From 03d99022dab1c9065fcad071c359e5b47b0d84f9 Mon Sep 17 00:00:00 2001 From: Andres Mejia Date: Fri, 29 Oct 2010 15:19:40 -0400 Subject: [PATCH] Imported Upstream version 0.4.5+svn2210 --- Changelog | 12 + INSTALLME | 2 +- Makefile | 78 +- applications/GPAX/GPAX.dsp | 346 +- applications/GPAX/GPAXPlugin.cpp | 87 +- applications/GPAX/GPAXPlugin.h | 1 + applications/GPAX/StdAfx.h | 8 +- applications/Makefile | 12 +- applications/generators/MPEG4/MPEG4Gen.dsp | 196 +- applications/generators/MPEG4/MPEG4Gen.dsw | 58 +- applications/generators/MPEG4/Makefile | 5 +- applications/generators/MPEG4/main.c | 66 +- applications/generators/MPEG4/templates10.txt | 53 + applications/generators/MPEG4/templates8.txt | 124 + applications/generators/MPEG4/templates9.txt | 68 + applications/generators/SVG/Makefile | 4 +- applications/generators/SVG/SVGGen.dsp | 252 +- applications/generators/SVG/SVGGen.dsw | 58 +- applications/generators/SVG/main.c | 6 +- applications/generators/X3D/Makefile | 5 +- applications/generators/X3D/X3DGen.dsp | 196 +- applications/generators/X3D/X3DGen.dsw | 58 +- applications/generators/X3D/main.c | 52 +- applications/m3u82mpd/main.c | 116 + applications/mp42avi/main.c | 10 +- applications/mp4box/Makefile | 20 +- applications/mp4box/filedump.c | 363 +- applications/mp4box/fileimport.c | 379 +- applications/mp4box/live.c | 775 + applications/mp4box/main.c | 917 +- applications/mp4client/Makefile | 28 +- applications/mp4client/extract.c | 78 +- applications/mp4client/main.c | 604 +- applications/osmo4_sym/osmo4_ui.cpp | 6 +- applications/osmo4_sym/osmo4_view.cpp | 13 +- applications/osmo4_w32/FileProps.cpp | 62 +- applications/osmo4_w32/MainFrm.cpp | 17 +- applications/osmo4_w32/Options.cpp | 8 +- applications/osmo4_w32/Osmo4.cpp | 191 +- applications/osmo4_w32/Osmo4.h | 3 +- applications/osmo4_w32/Osmo4.rc | 464 +- applications/osmo4_w32/Playlist.cpp | 28 +- applications/osmo4_w32/StdAfx.h | 4 + applications/osmo4_wce/MainFrm.cpp | 24 +- applications/osmo4_wce/Osmo4.cpp | 15 +- applications/osmo4_wce/Osmo4.h | 2 +- applications/osmo4_wce/StdAfx.h | 1 - applications/osmo4_wx/Makefile | 2 +- applications/osmo4_wx/Playlist.cpp | 16 +- applications/osmo4_wx/fileprops.cpp | 45 +- applications/osmo4_wx/osmo4.xpm | 2 +- applications/osmo4_wx/playlist.xpm | 14 +- applications/osmo4_wx/resource.h | 2 +- applications/osmo4_wx/toolbar.xpm | 22 +- applications/osmo4_wx/wxGPACControl.cpp | 2 +- applications/osmo4_wx/wxOsmo4.cpp | 194 +- applications/osmo4_wx/wxOsmo4.h | 27 +- applications/osmo4_wx/wxOsmo4.rc | 8 +- applications/osmophone/main.cpp | 583 +- applications/osmophone/newres.h | 2 +- applications/osmophone/openfile.cpp | 6 + applications/osmophone/osmophone.rc | 224 +- applications/osmophone/resource.h | 54 +- applications/osmozilla/osmozilla.cpp | 109 +- .../standalone2drender/standalone2drender.c | 172 - .../standalone2drender/standalone2drender.h | 16 - .../testapps/beng_test/BifsEngineTester.dsp | 103 - applications/testapps/beng_test/CmdLineTst.c | 89 - .../testapps/beng_test/rect-update.bt | 18 - applications/testapps/beng_test/rect.bt | 42 - applications/testapps/broadcaster/Makefile | 10 +- .../testapps/broadcaster/RTP_serv_generator.c | 451 +- .../testapps/broadcaster/RTP_serv_generator.h | 82 +- .../broadcaster/RTP_serv_packetizer.c | 191 +- .../broadcaster/RTP_serv_packetizer.h | 10 +- .../testapps/broadcaster/RTP_serv_sender.c | 61 +- .../testapps/broadcaster/RTP_serv_sender.h | 6 +- .../testapps/broadcaster/broadcaster.c | 502 +- .../testapps/broadcaster/broadcaster.dsp | 284 +- .../testapps/broadcaster/broadcaster.h | 29 +- .../broadcaster/broadcaster_config.cfg | 16 +- applications/testapps/broadcaster/debug.c | 24 + applications/testapps/broadcaster/debug.h | 18 + .../testapps/broadcaster/meteo_local.xmt | 1 + .../testapps/broadcaster/sdp_generator.c | 56 +- .../testapps/broadcaster/sdp_generator.h | 6 +- applications/testapps/dmbrs/dmbrs.dsp | 180 +- applications/testapps/largefile/largefile.dsp | 204 +- applications/testapps/largefile/largefile.dsw | 88 +- applications/testapps/largefile/main.c | 2 +- .../testapps/loadcompare/LoadCompare.dsp | 224 +- applications/testapps/loadcompare/Makefile | 2 +- .../testapps/loadcompare/loadcompare.c | 6 +- applications/testapps/mp42ts/Makefile | 1 - applications/testapps/mp42ts/main.c | 2184 +- applications/testapps/mp42ts/mp42ts.c | 823 - applications/testapps/mp42ts/mp42ts.dsp | 198 +- applications/testapps/mp42ts/mp42ts.h | 38 +- applications/testapps/mp42ts/mp42ts.vcproj | 231 + applications/testapps/mp4_streamer/Makefile | 64 - .../testapps/mp4_streamer/configuration.cfg | 31 - applications/testapps/mp4_streamer/main.c | 1175 - .../testapps/mp4_streamer/mp4_streamer.dsp | 102 - applications/testapps/mpedemux/main.c | 2 +- applications/testapps/mpedemux/mpedemux.dsp | 180 +- applications/testapps/mpeg2ts/mpeg2ts.dsp | 200 +- applications/testapps/svg2bifs/main.c | 22 +- applications/testapps/svg2bifs/svg2bifs.dsp | 180 +- applications/v4studio/V4FieldList.cpp | 10 +- applications/v4studio/V4SceneGraph.cpp | 6 +- applications/v4studio/V4Service.cpp | 16 +- bin/arm_ppc03_rel/install/gpac.inf | 8 +- bin/gcc/libgpac.so | Bin 4376700 -> 0 bytes bin/w32_rel/nsis_install/gpac_installer.nsi | 262 +- build/codeblocks/GPAX.cbp | 100 + build/codeblocks/Osmo4.cbp | 83 + build/codeblocks/aac_in.cbp | 62 + build/codeblocks/ac3_in.cbp | 64 + build/codeblocks/amr_dec.cbp | 496 + build/codeblocks/amr_float_dec.cbp | 159 + build/codeblocks/bifs_dec.cbp | 62 + build/codeblocks/ctx_load.cbp | 50 + build/codeblocks/demo_is.cbp | 50 + build/codeblocks/dummy_in.cbp | 50 + build/codeblocks/dx_hw.cbp | 86 + build/codeblocks/ffmpeg_in.cbp | 65 + build/codeblocks/ft_font.cbp | 55 + build/codeblocks/gdip_raster.cbp | 54 + build/codeblocks/gpac.workspace | 48 + build/codeblocks/gpac_js.cbp | 66 + build/codeblocks/img_in.cbp | 69 + build/codeblocks/ismacryp.cbp | 50 + build/codeblocks/isom_in.cbp | 60 + build/codeblocks/laser_dec.cbp | 50 + build/codeblocks/libgpac.cbp | 858 + build/codeblocks/mp3_in.cbp | 60 + build/codeblocks/mp4box.cbp | 84 + build/codeblocks/mp4client.cbp | 55 + build/codeblocks/mpegts_in.cbp | 50 + build/codeblocks/odf_dec.cbp | 50 + build/codeblocks/ogg.cbp | 70 + build/codeblocks/osmozilla.cbp | 72 + build/codeblocks/raw_out.cbp | 62 + build/codeblocks/rtp_in.cbp | 66 + build/codeblocks/saf_in.cbp | 50 + build/codeblocks/sdl_out.cbp | 61 + build/codeblocks/soft_raster.cbp | 71 + build/codeblocks/svg_in.cbp | 54 + build/codeblocks/timedtext.cbp | 53 + build/codeblocks/ui_rec.cbp | 53 + build/codeblocks/wav_out.cbp | 51 + build/codeblocks/wiiis.cbp | 55 + build/codeblocks/wxOsmo4.cbp | 65 + build/codeblocks/xvid_dec.cbp | 54 + build/msevc3/GPAC.VCW | 401 - build/msevc3/Osmo4.vcp | 281 - build/msevc3/aac_in.vcp | 140 - build/msevc3/amr_dec.vcp | 2411 -- build/msevc3/bifs_dec.vcp | 133 - build/msevc3/ctx_load.vcp | 135 - build/msevc3/dummy_in.vcp | 122 - build/msevc3/ft_font.vcp | 129 - build/msevc3/gapi.vcp | 134 - build/msevc3/img_in.vcp | 214 - build/msevc3/isom_in.vcp | 190 - build/msevc3/laser_dec.vcp | 147 - build/msevc3/libgpac.vcp | 3862 -- build/msevc3/libgpac_dll.vcp | 104 - build/msevc3/mp3_in.vcp | 137 - build/msevc3/odf_dec.vcp | 132 - build/msevc3/ogg.vcp | 198 - build/msevc3/rtp_in.vcp | 258 - build/msevc3/saf_in.vcp | 135 - build/msevc3/soft_raster.vcp | 218 - build/msevc3/svg_in.vcp | 145 - build/msevc3/timedtext.vcp | 155 - build/msevc3/wav_out.vcp | 118 - build/msevc3/xvid_dec.vcp | 462 - build/msevc4/GPAX.VCP | 12 +- build/msevc4/Osmo4.vcp | 34 +- build/msevc4/aac_in.vcp | 36 +- build/msevc4/ac3_in.vcp | 157 + build/msevc4/amr_dec.vcp | 27 +- build/msevc4/bifs_dec.vcp | 20 +- build/msevc4/ctx_load.vcp | 20 +- build/msevc4/dummy_in.vcp | 15 +- build/msevc4/ffmpeg_in.vcp | 118 +- build/msevc4/ft_font.vcp | 14 +- build/msevc4/gapi.vcp | 20 +- build/msevc4/gpac_js.vcp | 173 + build/msevc4/img_in.vcp | 49 +- build/msevc4/ismacryp.vcp | 27 +- build/msevc4/isom_in.vcp | 40 +- build/msevc4/laser_dec.vcp | 29 +- build/msevc4/libgpac.vcp | 1008 +- build/msevc4/libgpac_dll.vcp | 13 +- build/msevc4/mp3_in.vcp | 31 +- build/msevc4/odf_dec.vcp | 26 +- build/msevc4/osmophone.vcp | 29 +- build/msevc4/rtp_in.vcp | 65 +- build/msevc4/saf_in.vcp | 30 +- build/msevc4/soft_rast.vcp | 71 +- build/msevc4/svg_in.vcp | 34 +- build/msevc4/timedtext.vcp | 26 +- build/msevc4/wav_out.vcp | 20 +- build/msevc4/xvid_dec.vcp | 17 +- build/msvc6/GPAX.dsp | 172 - build/msvc6/Osmo4.dsp | 217 - build/msvc6/V4Studio.dsp | 505 - build/msvc6/aac_in.dsp | 105 - build/msvc6/ac3_in.dsp | 103 - build/msvc6/amr_dec.dsp | 982 - build/msvc6/amr_float_dec.dsp | 304 - build/msvc6/bifs_dec.dsp | 99 - build/msvc6/ctx_load.dsp | 99 - build/msvc6/dummy_in.dsp | 99 - build/msvc6/dx_hw.dsp | 143 - build/msvc6/ffmpeg_in.dsp | 113 - build/msvc6/ft_font.dsp | 105 - build/msvc6/gdip_raster.dsp | 115 - build/msvc6/gpac.dsw | 695 - build/msvc6/gpac_js.dsp | 113 - build/msvc6/img_in.dsp | 125 - build/msvc6/ismacryp.dsp | 100 - build/msvc6/isom_in.dsp | 116 - build/msvc6/laser_dec.dsp | 99 - build/msvc6/libgpac.dsp | 1404 - build/msvc6/libgpac_dll.dsp | 97 - build/msvc6/mp3_in.dsp | 103 - build/msvc6/mp42avi.dsp | 91 - build/msvc6/mp4box.dsp | 104 - build/msvc6/mp4client.dsp | 96 - build/msvc6/mpegts_in.dsp | 112 - build/msvc6/odf_dec.dsp | 99 - build/msvc6/ogg.dsp | 115 - build/msvc6/osmozilla.dsp | 150 - build/msvc6/raw_out.dsp | 99 - build/msvc6/rtp_in.dsp | 123 - build/msvc6/saf_in.dsp | 103 - build/msvc6/sdl_out.dsp | 116 - build/msvc6/soft_raster.dsp | 136 - build/msvc6/standalone2drender.dsp | 267 - build/msvc6/svg_in.dsp | 111 - build/msvc6/timedtext.dsp | 103 - build/msvc6/wav_out.dsp | 99 - build/msvc6/wxOsmo4.dsp | 156 - build/msvc6/xvid_dec.dsp | 101 - build/msvc8/GPAX.vcproj | 1416 +- build/msvc8/Osmo4.vcproj | 1904 +- build/msvc8/V4Studio.vcproj | 1844 +- build/msvc8/aac_in.vcproj | 1122 +- build/msvc8/ac3_in.vcproj | 690 +- build/msvc8/amr_dec.vcproj | 10778 +++-- build/msvc8/amr_float_dec.vcproj | 3014 +- build/msvc8/audio_filter.vcproj | 451 + build/msvc8/bifs_dec.vcproj | 1020 +- build/msvc8/ctx_load.vcproj | 1022 +- build/msvc8/demo_is.vcproj | 576 + build/msvc8/dummy_in.vcproj | 1020 +- build/msvc8/dx_hw.vcproj | 1474 +- build/msvc8/ffmpeg_in.vcproj | 1204 +- build/msvc8/ft_font.vcproj | 974 +- build/msvc8/gapi.vcproj | 262 + build/msvc8/gdip_raster.vcproj | 1279 +- build/msvc8/gpac.sln | 1137 +- build/msvc8/gpac_js.vcproj | 462 + build/msvc8/img_in.vcproj | 1371 +- build/msvc8/ismacryp.vcproj | 1021 +- build/msvc8/isom_in.vcproj | 1273 +- build/msvc8/laser_dec.vcproj | 1019 +- build/msvc8/libgpac.vcproj | 14343 +++---- build/msvc8/libgpac_dll.vcproj | 969 +- build/msvc8/m3u82mpd.vcproj | 421 + build/msvc8/m3u8_in.vcproj | 218 + build/msvc8/mp3_in.vcproj | 1115 +- build/msvc8/mp4box.vcproj | 1164 +- build/msvc8/mp4client.vcproj | 1069 +- build/msvc8/mpd_in.vcproj | 212 + build/msvc8/mpegts_in.vcproj | 1036 +- build/msvc8/odf_dec.vcproj | 1022 +- build/msvc8/ogg.vcproj | 1283 +- build/msvc8/opencv_is.vcproj | 577 + build/msvc8/opensvc.vcproj | 455 + build/msvc8/osmophone.vcproj | 586 + build/msvc8/osmozilla.vcproj | 1414 +- build/msvc8/platinum.vcproj | 465 + build/msvc8/raw_out.vcproj | 1021 +- build/msvc8/redirect_av.vcproj | 453 + build/msvc8/rtp_in.vcproj | 1429 +- build/msvc8/saf_in.vcproj | 1031 +- build/msvc8/sdl_out.vcproj | 1280 +- build/msvc8/soft_raster.vcproj | 1507 +- build/msvc8/svg_in.vcproj | 1050 +- build/msvc8/timedtext.vcproj | 1101 +- build/msvc8/ui_rec.vcproj | 576 + build/msvc8/validator.vcproj | 574 + build/msvc8/wav_out.vcproj | 1027 +- build/msvc8/widgetman.vcproj | 447 + build/msvc8/wiiis.vcproj | 578 + build/msvc8/wxOsmo4.vcproj | 776 +- build/msvc8/xvid_dec.vcproj | 1814 +- build/msvc9/GPAX.vcproj | 658 + build/msvc9/Osmo4.vcproj | 901 + build/msvc9/V4Studio.vcproj | 922 + build/msvc9/aac_in.vcproj | 508 + build/msvc9/ac3_in.vcproj | 431 + build/msvc9/amr_dec.vcproj | 5331 +++ build/msvc9/amr_float_dec.vcproj | 1449 + build/msvc9/audio_filter.vcproj | 460 + build/msvc9/bifs_dec.vcproj | 460 + build/msvc9/ctx_load.vcproj | 462 + build/msvc9/demo_is.vcproj | 576 + build/msvc9/dummy_in.vcproj | 460 + build/msvc9/dx_hw.vcproj | 682 + build/msvc9/ffmpeg_in.vcproj | 552 + build/msvc9/ft_font.vcproj | 436 + build/msvc9/gapi.vcproj | 273 + build/msvc9/gdip_raster.vcproj | 589 + build/msvc9/gpac.sln | 538 + build/msvc9/gpac_js.vcproj | 471 + build/msvc9/img_in.vcproj | 635 + build/msvc9/ismacryp.vcproj | 461 + build/msvc9/isom_in.vcproj | 587 + build/msvc9/laser_dec.vcproj | 459 + build/msvc9/libgpac.vcproj | 7131 +++ build/msvc9/libgpac_dll.vcproj | 439 + build/msvc9/mp3_in.vcproj | 507 + build/msvc9/mp4box.vcproj | 534 + build/msvc9/mp4client.vcproj | 483 + build/msvc9/mpegts_in.vcproj | 461 + build/msvc9/odf_dec.vcproj | 460 + build/msvc9/ogg.vcproj | 591 + build/msvc9/opencv_is.vcproj | 577 + build/msvc9/osmophone.vcproj | 595 + build/msvc9/osmozilla.vcproj | 657 + build/msvc9/platinum.vcproj | 474 + build/msvc9/raw_out.vcproj | 461 + build/msvc9/redirect_av.vcproj | 450 + build/msvc9/rtp_in.vcproj | 665 + build/msvc9/saf_in.vcproj | 466 + build/msvc9/sdl_out.vcproj | 589 + build/msvc9/soft_raster.vcproj | 703 + build/msvc9/svg_in.vcproj | 467 + build/msvc9/timedtext.vcproj | 501 + build/msvc9/ui_rec.vcproj | 576 + build/msvc9/wav_out.vcproj | 463 + build/msvc9/widgetman.vcproj | 456 + build/msvc9/wiiis.vcproj | 578 + build/msvc9/wxOsmo4.vcproj | 388 + build/msvc9/xvid_dec.vcproj | 1246 + build/symbian/libgpac.mmp | 5 +- build/symbian/libgpac_symbianU.def | 12 +- build/xcode/gpac.xcodeproj/project.pbxproj | 517 + config.h | 9 - configure | 890 +- doc/GPAC UPnP.doc | Bin 0 -> 74752 bytes doc/INSTALL.w32 | 2 +- doc/ISO 639-2 codes.txt | 969 +- doc/configuration.html | 51 +- doc/osmo4.ico | Bin 0 -> 15086 bytes extra_lib/include/faad/faad.h | 2 +- extra_lib/include/faad/neaacdec.h | 2 +- extra_lib/include/ffmpeg/avcodec.h | 2714 -- extra_lib/include/ffmpeg/avformat.h | 549 - extra_lib/include/ffmpeg/avio.h | 212 - extra_lib/include/ffmpeg/avutil.h | 137 - extra_lib/include/ffmpeg/common.h | 408 - extra_lib/include/ffmpeg/integer.h | 49 - extra_lib/include/ffmpeg/intfloat_readwrite.h | 39 - extra_lib/include/ffmpeg/log.h | 102 - extra_lib/include/ffmpeg/mathematics.h | 51 - extra_lib/include/ffmpeg/rational.h | 79 - extra_lib/include/js/jsautocfg.h | 2 + extra_lib/include/libavcodec/avcodec.h | 3714 ++ extra_lib/include/libavformat/avformat.h | 1238 + extra_lib/include/libavformat/avio.h | 408 + extra_lib/include/libavutil/avutil.h | 63 + extra_lib/include/libavutil/common.h | 319 + .../include/libavutil/intfloat_readwrite.h | 42 + extra_lib/include/libavutil/log.h | 116 + extra_lib/include/libavutil/mathematics.h | 74 + extra_lib/include/libavutil/mem.h | 104 + extra_lib/include/libavutil/pixfmt.h | 151 + extra_lib/include/libavutil/rational.h | 131 + extra_lib/include/libswscale/swscale.h | 263 + extra_lib/include/ogg/ogg.h | 2 +- extra_lib/include/ogg/os_types.h | 2 +- extra_lib/include/theora/theora.h | 2 +- extra_lib/include/vorbis/codec.h | 2 +- extra_lib/include/vorbis/vorbisenc.h | 2 +- extra_lib/include/vorbis/vorbisfile.h | 2 +- extra_lib/include/wiiuse.h | 653 + extra_lib/include/xvid/xvid.h | 2 +- extra_lib/include/zlib/zconf.h | 2 +- extra_lib/lib/arm_ppc02_rel/dummy | 0 extra_lib/lib/arm_ppc03_deb/dummy | 0 extra_lib/lib/arm_ppc03_rel/dummy | 0 extra_lib/lib/gcc/dummy | 0 extra_lib/lib/w32_deb/dummy | 0 extra_lib/lib/w32_rel/dummy | 0 gpac.spec | 2 +- gui/gui.bt | 42 + gui/gui.js | 2018 + gui/icons/applications-internet.svg | 622 + gui/icons/applications-multimedia.svg | 498 + gui/icons/applications-system.svg | 247 + gui/icons/audio-volume-high.svg | 643 + gui/icons/audio-volume-low.svg | 641 + gui/icons/audio-volume-medium.svg | 646 + gui/icons/audio-volume-muted.svg | 991 + gui/icons/audio-x-generic.svg | 180 + gui/icons/battery-caution.svg | 625 + gui/icons/camera-photo.svg | 681 + gui/icons/camera-video.svg | 1257 + gui/icons/dialog-error.svg | 316 + gui/icons/dialog-information.svg | 1145 + gui/icons/dialog-warning.svg | 359 + gui/icons/document-new.svg | 448 + gui/icons/document-print-preview.svg | 701 + gui/icons/document-print.svg | 530 + gui/icons/document-save-as.svg | 661 + gui/icons/document-save.svg | 617 + gui/icons/emblem-unreadable.svg | 357 + gui/icons/face-surprise.svg | 254 + gui/icons/folder.svg | 422 + gui/icons/go-bottom.svg | 225 + gui/icons/go-down.svg | 199 + gui/icons/go-first.svg | 203 + gui/icons/go-home.svg | 441 + gui/icons/go-jump.svg | 203 + gui/icons/go-last.svg | 203 + gui/icons/go-next.svg | 191 + gui/icons/go-previous.svg | 852 + gui/icons/go-top.svg | 972 + gui/icons/go-up.svg | 195 + gui/icons/image-missing.svg | 318 + gui/icons/left_arrow.svg | 374 + gui/icons/list-add.svg | 434 + gui/icons/list-remove.svg | 422 + gui/icons/media-eject.svg | 439 + gui/icons/media-playback-pause.svg | 630 + gui/icons/media-playback-start.svg | 308 + gui/icons/media-playback-stop.svg | 640 + gui/icons/media-record.svg | 326 + gui/icons/media-seek-backward.svg | 363 + gui/icons/media-seek-forward.svg | 370 + gui/icons/media-skip-backward.svg | 1014 + gui/icons/media-skip-forward.svg | 1002 + gui/icons/process-stop.svg | 334 + gui/icons/right_arrow.svg | 383 + gui/icons/tennis_ball.svg | 71 + gui/icons/tennis_black.svg | 50 + gui/icons/tennis_racket.svg | 64 + gui/icons/tennis_racket_color.svg | 68 + gui/icons/user-trash.svg | 487 + gui/icons/video-display.svg | 487 + gui/icons/video-x-generic.svg | 318 + gui/icons/view-fullscreen.svg | 520 + gui/iphone_wm_gui.js | 1364 + gui/iphone_wm_gui.svg | 547 + gui/mpegu-core.js | 1571 + gui/mpegu-wm.bt | 31 + gui/mpegu-wm.js | 1572 + gui/mpegu-wm.xmt | 69 + gui/tv_wm_gui.js | 485 + gui/tv_wm_gui.svg | 31 + include/gpac/avparse.h | 65 +- include/gpac/bifs.h | 13 +- include/gpac/bifsengine.h | 138 - include/gpac/bitstream.h | 12 +- include/gpac/color.h | 7 +- include/gpac/compositor.h | 1 + include/gpac/config_file.h | 7 +- include/gpac/configuration.h | 211 + include/gpac/constants.h | 197 +- include/gpac/crypt.h | 5 + include/gpac/download.h | 42 + include/gpac/dvb_mpe.h | 41 + include/gpac/esi.h | 11 +- include/gpac/events.h | 10 + include/gpac/filestreamer.h | 121 + include/gpac/ietf.h | 27 +- include/gpac/internal/avilib.h | 5 + include/gpac/internal/bifs_dev.h | 16 + include/gpac/internal/bifs_tables.h | 177 +- include/gpac/internal/compositor_dev.h | 200 +- include/gpac/internal/config_static.h | 89 - include/gpac/internal/crypt_dev.h | 7 +- include/gpac/internal/dvb_mpe_dev.h | 259 + include/gpac/internal/ietf_dev.h | 12 +- include/gpac/internal/isomedia_dev.h | 247 +- include/gpac/internal/laser_dev.h | 4 + include/gpac/internal/media_dev.h | 135 +- include/gpac/internal/mesh.h | 6 +- include/gpac/internal/ogg.h | 8 +- include/gpac/internal/reedsolomon.h | 78 + include/gpac/internal/scenegraph_dev.h | 494 +- include/gpac/internal/terminal_dev.h | 326 +- include/gpac/ismacryp.h | 23 +- include/gpac/iso639.h | 970 +- include/gpac/isomedia.h | 149 +- include/gpac/laser.h | 6 +- include/gpac/math.h | 17 - include/gpac/media_tools.h | 99 +- include/gpac/mediaobject.h | 4 +- include/gpac/module.h | 13 +- include/gpac/modules/audio_out.h | 58 +- include/gpac/modules/codec.h | 37 +- include/gpac/modules/font.h | 2 +- include/gpac/modules/ipmp.h | 2 +- include/gpac/modules/js_usr.h | 7 +- include/gpac/modules/raster2d.h | 24 +- include/gpac/modules/service.h | 33 +- include/gpac/modules/term_ext.h | 52 +- include/gpac/modules/video_out.h | 71 +- include/gpac/mpeg4_odf.h | 114 +- include/gpac/mpegts.h | 338 +- include/gpac/network.h | 13 +- include/gpac/nodes_mpeg4.h | 1542 +- include/gpac/nodes_svg.h | 42 +- include/gpac/nodes_x3d.h | 703 +- include/gpac/options.h | 26 +- include/gpac/path2d.h | 4 + include/gpac/rtp_streamer.h | 114 + include/gpac/scene_engine.h | 202 + include/gpac/scene_manager.h | 147 +- include/gpac/scenegraph.h | 111 +- include/gpac/scenegraph_svg.h | 36 +- include/gpac/scenegraph_vrml.h | 164 +- include/gpac/setup.h | 191 +- include/gpac/svg_types.h | 15 +- include/gpac/sync_layer.h | 3 + include/gpac/term_info.h | 14 +- include/gpac/terminal.h | 23 +- include/gpac/thread.h | 2 +- include/gpac/tools.h | 73 +- include/gpac/user.h | 23 +- include/gpac/xml.h | 2 +- modules/Makefile | 7 +- modules/aac_in/Makefile | 15 +- modules/aac_in/aac_in.c | 92 +- modules/aac_in/aac_in.def | 6 - modules/aac_in/faad_dec.c | 37 +- modules/ac3_in/Makefile | 14 +- modules/ac3_in/ac3_in.c | 76 +- modules/ac3_in/ac3_in.def | 6 - modules/ac3_in/liba52_dec.c | 4 +- modules/alsa/Makefile | 9 +- modules/alsa/alsa.c | 22 +- modules/amr_dec/Makefile | 10 +- modules/amr_dec/amr_dec.c | 20 +- modules/amr_dec/amr_dec.def | 6 - modules/amr_dec/amr_in.c | 64 +- modules/amr_dec/amr_nb/typedefs.h | 4 +- modules/amr_float_dec/Makefile | 12 +- modules/amr_float_dec/amr_float_dec.c | 27 +- modules/amr_float_dec/amr_float_dec.def | 6 - modules/amr_float_dec/amr_nb_ft/dummy | 0 modules/amr_float_dec/amr_wb_ft/dummy | 0 modules/audio_filter/Makefile | 53 + modules/audio_filter/audio_filter.c | 283 + modules/bifs_dec/Makefile | 14 +- modules/bifs_dec/bifs_dec.c | 43 +- modules/bifs_dec/bifs_dec.def | 6 - modules/ctx_load/Makefile | 15 +- modules/ctx_load/ctx_load.c | 161 +- modules/ctx_load/ctx_load.def | 6 - modules/demo_is/Makefile | 57 + modules/demo_is/demo-sensor.bt | 86 + modules/demo_is/demo_is.c | 102 + modules/directfb_out/Makefile | 58 + modules/directfb_out/directfb_out.c | 345 + modules/directfb_out/directfb_out.h | 51 + modules/dummy_in/Makefile | 14 +- modules/dummy_in/dummy_in.c | 81 +- modules/dummy_in/dummy_in.def | 6 - modules/dx_hw/Makefile | 4 +- modules/dx_hw/copy_pixels.c | 65 +- modules/dx_hw/dx_2d.c | 47 +- modules/dx_hw/dx_audio.c | 13 +- modules/dx_hw/dx_hw.def | 6 - modules/dx_hw/dx_hw.h | 58 +- modules/dx_hw/dx_hw.rc | 32 +- modules/dx_hw/dx_video.c | 277 +- modules/dx_hw/dx_window.c | 148 +- modules/dx_hw/resource.h | 6 +- modules/epoc_hw/epoc_aout.cpp | 12 +- modules/epoc_hw/epoc_codec.cpp | 24 +- modules/epoc_hw/epoc_vout.cpp | 25 +- modules/ffmpeg_in/Makefile | 25 +- modules/ffmpeg_in/ffmpeg_decode.c | 701 +- modules/ffmpeg_in/ffmpeg_demux.c | 139 +- modules/ffmpeg_in/ffmpeg_in.def | 6 - modules/ffmpeg_in/ffmpeg_in.h | 40 +- modules/ffmpeg_in/ffmpeg_load.c | 15 +- modules/ft_font/Makefile | 17 +- modules/ft_font/ft_font.c | 159 +- modules/ft_font/ft_font.def | 6 - modules/gapi/gapi.cpp | 505 +- modules/gapi/gapi.def | 6 - modules/gapi/gapi.h | 11 +- modules/gdip_raster/gdip_font.cpp | 25 +- modules/gdip_raster/gdip_grad.cpp | 6 +- modules/gdip_raster/gdip_priv.h | 4 +- modules/gdip_raster/gdip_rend.cpp | 24 +- modules/gdip_raster/gdip_rend.def | 6 - modules/gdip_raster/gdip_texture.cpp | 22 +- modules/gpac_js/Makefile | 17 +- modules/gpac_js/gpac_js.c | 359 +- modules/gpac_js/gpac_js.def | 6 - modules/img_in/Makefile | 19 +- modules/img_in/bmp_dec.c | 4 +- modules/img_in/img_dec.c | 35 +- modules/img_in/img_in.c | 27 +- modules/img_in/img_in.def | 6 - modules/img_in/jp2_dec.c | 14 +- modules/img_in/jpeg_dec.c | 4 +- modules/img_in/png_dec.c | 11 +- modules/ismacryp/Makefile | 15 +- modules/ismacryp/ismacryp.c | 28 +- modules/ismacryp/ismacryp.def | 6 - modules/isom_in/Makefile | 14 +- modules/isom_in/cache.c | 18 +- modules/isom_in/isom_in.def | 6 - modules/isom_in/isom_in.h | 16 +- modules/isom_in/load.c | 35 +- modules/isom_in/read.c | 19 +- modules/isom_in/read_ch.c | 73 +- modules/jack/Makefile | 11 +- modules/jack/jack.c | 34 +- modules/laser_dec/Makefile | 14 +- modules/laser_dec/laser_dec.c | 55 +- modules/laser_dec/laser_dec.def | 6 - modules/m3u8_in/Makefile | 73 + modules/m3u8_in/m3u8_in.c | 500 + modules/m3u8_in/m3u8_in.h | 40 + modules/m3u8_in/m3u8_in_load.c | 50 + modules/m3u8_in/m3u8_parser.c | 458 + modules/m3u8_in/m3u8_parser.h | 47 + modules/m3u8_in/playlist.c | 286 + modules/m3u8_in/playlist.h | 162 + modules/m3u8_in/test.c | 31 + modules/m3u8_in/tests/direct8.m3u8 | 3 + modules/m3u8_in/tests/relative_playlist.m3u8 | 3 + .../m3u8_in/tests/spec_encrypted_media.m3u8 | 18 + .../m3u8_in/tests/spec_multiple_files.m3u8 | 19 + .../m3u8_in/tests/spec_simple_playlist.m3u8 | 5 + .../tests/spec_sliding_window_playlist.m3u8 | 11 + .../m3u8_in/tests/spec_variant_playlist.m3u8 | 10 + modules/modules_export.cpp | 38 + modules/mp3_in/Makefile | 14 +- modules/mp3_in/mad_dec.c | 13 +- modules/mp3_in/mp3_in.c | 106 +- modules/mp3_in/mp3_in.def | 6 - modules/mpegts_in/Makefile | 15 +- modules/mpegts_in/mpegts_in.c | 417 +- modules/mpegts_in/mpegts_in.def | 6 - modules/odf_dec/Makefile | 14 +- modules/odf_dec/odf_dec.c | 41 +- modules/odf_dec/odf_dec.def | 6 - modules/ogg/Makefile | 12 +- modules/ogg/ogg.def | 6 - modules/ogg/ogg_in.c | 40 +- modules/ogg/ogg_load.c | 21 +- modules/ogg/theora_dec.c | 8 +- modules/ogg/vorbis_dec.c | 8 +- modules/opencv_is/Makefile | 59 + modules/opencv_is/demo-sensor.bt | 93 + .../haarcascade_frontalface_default.xml | 35712 ++++++++++++++++ modules/opencv_is/opencv_is.c | 219 + modules/opensvc_dec/Makefile | 59 + modules/opensvc_dec/opensvc_dec.c | 372 + modules/oss_audio/Makefile | 12 +- modules/oss_audio/oss.c | 37 +- modules/platinum/GPACFileMediaServer.cpp | 570 + modules/platinum/GPACFileMediaServer.h | 138 + modules/platinum/GPACMediaController.cpp | 323 + modules/platinum/GPACMediaController.h | 140 + modules/platinum/GPACMediaRenderer.cpp | 583 + modules/platinum/GPACMediaRenderer.h | 99 + modules/platinum/GPACPlatinum.cpp | 1547 + modules/platinum/GPACPlatinum.h | 146 + modules/platinum/GenericDevice.cpp | 930 + modules/platinum/GenericDevice.h | 203 + modules/platinum/Makefile | 70 + modules/platinum/SDK/ReadMe.txt | 25 + modules/platinum/SDK/include/Neptune.h | 84 + modules/platinum/SDK/include/NptArray.h | 522 + modules/platinum/SDK/include/NptBase64.h | 68 + .../platinum/SDK/include/NptBufferedStreams.h | 101 + modules/platinum/SDK/include/NptCommon.h | 169 + modules/platinum/SDK/include/NptConfig.h | 306 + modules/platinum/SDK/include/NptConsole.h | 55 + modules/platinum/SDK/include/NptConstants.h | 44 + modules/platinum/SDK/include/NptDataBuffer.h | 83 + modules/platinum/SDK/include/NptDebug.h | 56 + .../platinum/SDK/include/NptDefs.h | 0 modules/platinum/SDK/include/NptDynamicCast.h | 89 + .../SDK/include/NptDynamicLibraries.h | 84 + modules/platinum/SDK/include/NptFile.h | 203 + modules/platinum/SDK/include/NptHttp.h | 698 + modules/platinum/SDK/include/NptInterfaces.h | 115 + modules/platinum/SDK/include/NptList.h | 605 + modules/platinum/SDK/include/NptLogging.h | 512 + modules/platinum/SDK/include/NptMap.h | 330 + modules/platinum/SDK/include/NptMessaging.h | 176 + modules/platinum/SDK/include/NptNetwork.h | 228 + modules/platinum/SDK/include/NptQueue.h | 96 + modules/platinum/SDK/include/NptReferences.h | 146 + modules/platinum/SDK/include/NptResults.h | 160 + modules/platinum/SDK/include/NptRingBuffer.h | 84 + .../SDK/include/NptSelectableMessageQueue.h | 68 + modules/platinum/SDK/include/NptSerialPort.h | 119 + .../SDK/include/NptSimpleMessageQueue.h | 68 + modules/platinum/SDK/include/NptSockets.h | 335 + modules/platinum/SDK/include/NptStack.h | 72 + modules/platinum/SDK/include/NptStreams.h | 322 + modules/platinum/SDK/include/NptStrings.h | 339 + modules/platinum/SDK/include/NptSystem.h | 60 + modules/platinum/SDK/include/NptThreads.h | 283 + modules/platinum/SDK/include/NptTime.h | 150 + modules/platinum/SDK/include/NptTls.h | 161 + modules/platinum/SDK/include/NptTypes.h | 149 + modules/platinum/SDK/include/NptUri.h | 170 + modules/platinum/SDK/include/NptUtils.h | 219 + modules/platinum/SDK/include/NptVersion.h | 41 + modules/platinum/SDK/include/NptXml.h | 385 + modules/platinum/SDK/include/NptZip.h | 144 + modules/platinum/SDK/include/Platinum.h | 55 + modules/platinum/SDK/include/PltAction.h | 168 + modules/platinum/SDK/include/PltArgument.h | 142 + modules/platinum/SDK/include/PltConstants.h | 59 + modules/platinum/SDK/include/PltCtrlPoint.h | 203 + .../platinum/SDK/include/PltCtrlPointTask.h | 184 + .../platinum/SDK/include/PltDatagramStream.h | 99 + modules/platinum/SDK/include/PltDeviceData.h | 215 + modules/platinum/SDK/include/PltDeviceHost.h | 166 + modules/platinum/SDK/include/PltDidl.h | 130 + modules/platinum/SDK/include/PltDownloader.h | 91 + modules/platinum/SDK/include/PltEvent.h | 141 + .../platinum/SDK/include/PltFileMediaServer.h | 143 + modules/platinum/SDK/include/PltHttp.h | 135 + .../platinum/SDK/include/PltHttpClientTask.h | 158 + modules/platinum/SDK/include/PltHttpServer.h | 98 + .../SDK/include/PltHttpServerListener.h | 55 + .../platinum/SDK/include/PltHttpServerTask.h | 163 + modules/platinum/SDK/include/PltLeaks.h | 50 + .../platinum/SDK/include/PltMediaBrowser.h | 140 + .../SDK/include/PltMediaBrowserListener.h | 80 + modules/platinum/SDK/include/PltMediaCache.h | 75 + .../platinum/SDK/include/PltMediaConnect.h | 116 + .../platinum/SDK/include/PltMediaController.h | 338 + .../SDK/include/PltMediaControllerListener.h | 203 + modules/platinum/SDK/include/PltMediaItem.h | 326 + .../platinum/SDK/include/PltMediaPlaylist.h | 85 + .../platinum/SDK/include/PltMediaRenderer.h | 110 + modules/platinum/SDK/include/PltMediaServer.h | 131 + .../platinum/SDK/include/PltMetadataHandler.h | 90 + .../SDK/include/PltRingBufferStream.h | 113 + modules/platinum/SDK/include/PltService.h | 272 + modules/platinum/SDK/include/PltSsdp.h | 300 + .../platinum/SDK/include/PltSsdpListener.h | 65 + .../platinum/SDK/include/PltStateVariable.h | 144 + modules/platinum/SDK/include/PltStreamPump.h | 131 + modules/platinum/SDK/include/PltSvnVersion.h | 3 + .../SDK/include/PltSyncMediaBrowser.h | 168 + modules/platinum/SDK/include/PltTaskManager.h | 82 + modules/platinum/SDK/include/PltThreadTask.h | 108 + modules/platinum/SDK/include/PltTime.h | 57 + modules/platinum/SDK/include/PltUPnP.h | 92 + modules/platinum/SDK/include/PltUPnPHelper.h | 341 + modules/platinum/SDK/include/PltVersion.h | 48 + modules/platinum/SDK/include/PltXmlHelper.h | 299 + modules/pulseaudio/Makefile | 10 +- modules/pulseaudio/pulseaudio.c | 15 +- modules/raw_out/Makefile | 24 +- modules/raw_out/raw_out.def | 6 - modules/raw_out/raw_video.c | 32 +- modules/redirect_av/Makefile | 58 + modules/redirect_av/redirect_av.c | 232 + modules/rtp_in/Makefile | 14 +- modules/rtp_in/rtp_in.c | 111 +- modules/rtp_in/rtp_in.def | 6 - modules/rtp_in/rtp_in.h | 39 +- modules/rtp_in/rtp_session.c | 26 +- modules/rtp_in/rtp_signaling.c | 147 +- modules/rtp_in/rtp_stream.c | 97 +- modules/rtp_in/sdp_fetch.c | 31 +- modules/rtp_in/sdp_load.c | 206 +- modules/saf_in/Makefile | 14 +- modules/saf_in/saf_in.c | 48 +- modules/saf_in/saf_in.def | 6 - modules/sdl_out/Makefile | 20 +- modules/sdl_out/audio.c | 8 +- modules/sdl_out/sdl_out.c | 11 +- modules/sdl_out/sdl_out.def | 6 - modules/sdl_out/sdl_out.h | 16 +- modules/sdl_out/video.c | 488 +- modules/soft_raster/Makefile | 15 +- modules/soft_raster/ftgrays.c | 14 +- modules/soft_raster/rast_soft.def | 6 - modules/soft_raster/rast_soft.h | 16 +- modules/soft_raster/raster_565.c | 140 +- modules/soft_raster/raster_argb.c | 289 +- modules/soft_raster/raster_load.c | 12 +- modules/soft_raster/raster_rgb.c | 108 +- modules/soft_raster/stencil.c | 202 +- modules/soft_raster/surface.c | 57 +- modules/svg_in/Makefile | 16 +- modules/svg_in/svg_in.c | 78 +- modules/svg_in/svg_in.def | 6 - modules/timedtext/Makefile | 14 +- modules/timedtext/timedtext.def | 6 - modules/timedtext/timedtext_dec.c | 129 +- modules/timedtext/timedtext_in.c | 12 +- modules/ui_rec/Makefile | 62 + modules/ui_rec/readme.txt | 14 + modules/ui_rec/ui_rec.c | 249 + modules/wav_out/Makefile | 2 +- modules/wav_out/wav_out.c | 23 +- modules/wav_out/wav_out.def | 6 - modules/widgetman/Makefile | 75 + modules/widgetman/unzip.c | 1368 + modules/widgetman/unzip.h | 485 + modules/widgetman/wgt_load.c | 290 + modules/widgetman/wgt_load_base.js | 84 + modules/widgetman/widget.c | 416 + modules/widgetman/widgetman.c | 3510 ++ modules/widgetman/widgetman.h | 370 + modules/wiiis/Makefile | 60 + modules/wiiis/test_wii.bt | 251 + modules/wiiis/wiiis.c | 263 + modules/x11_out/Makefile | 31 +- modules/x11_out/x11_out.c | 191 +- modules/x11_out/x11_out.h | 9 +- modules/xvid_dec/Makefile | 17 +- modules/xvid_dec/xvid_dec.c | 31 +- modules/xvid_dec/xvid_dec.def | 6 - modules/xvid_dec/xvid_dec_wce.cpp | 21 +- modules/xvid_dec/xvid_wce/AUTHORS | 2 +- modules/xvid_dec/xvid_wce/TODO | 2 +- modules/xvid_dec/xvid_wce/bitstream.cpp | 2 +- modules/xvid_dec/xvid_wce/bitstream.h | 2 +- modules/xvid_dec/xvid_wce/decoder.cpp | 2 +- modules/xvid_dec/xvid_wce/decoder.h | 2 +- modules/xvid_dec/xvid_wce/font.cpp | 2 +- modules/xvid_dec/xvid_wce/global.h | 2 +- modules/xvid_dec/xvid_wce/gmc.cpp | 2 +- modules/xvid_dec/xvid_wce/gmc.h | 2 +- modules/xvid_dec/xvid_wce/idct.cpp | 2 +- modules/xvid_dec/xvid_wce/image.cpp | 2 +- modules/xvid_dec/xvid_wce/image.h | 2 +- modules/xvid_dec/xvid_wce/interpolate8x8.cpp | 2 +- modules/xvid_dec/xvid_wce/interpolate8x8.h | 2 +- modules/xvid_dec/xvid_wce/mbcoding.cpp | 2 +- modules/xvid_dec/xvid_wce/mbprediction.cpp | 2 +- modules/xvid_dec/xvid_wce/mbprediction.h | 2 +- modules/xvid_dec/xvid_wce/mem_align.cpp | 10 +- modules/xvid_dec/xvid_wce/mem_align.h | 2 +- modules/xvid_dec/xvid_wce/mem_transfer.cpp | 2 +- modules/xvid_dec/xvid_wce/mem_transfer.h | 2 +- modules/xvid_dec/xvid_wce/portab.h | 2 +- modules/xvid_dec/xvid_wce/quant.h | 2 +- modules/xvid_dec/xvid_wce/quant_h263.cpp | 2 +- modules/xvid_dec/xvid_wce/quant_matrix.cpp | 2 +- modules/xvid_dec/xvid_wce/quant_matrix.h | 2 +- modules/xvid_dec/xvid_wce/quant_mpeg.cpp | 2 +- modules/xvid_dec/xvid_wce/reduced.cpp | 2 +- modules/xvid_dec/xvid_wce/reduced.h | 2 +- modules/xvid_dec/xvid_wce/vlc_codes.h | 2 +- modules/xvid_dec/xvid_wce/xvid.cpp | 2 +- modules/xvid_dec/xvid_wce/xvid.h | 2 +- regression_tests/_mozilla_ie_simple.html | 4 +- .../bifs-2D-background-background2D-bind.bt | 71 - .../bifs-2D-background-background2D-image.bt | 97 - ...bifs-2D-background-background2D-layer2D.bt | 92 - .../bifs-2D-background-background2D-movie.bt | 94 - ...s-2D-background-background2D-url-change.bt | 105 - .../bifs-2D-interactivity-discsensor.bt | 129 - .../bifs-2D-interactivity-htk-sensor.bt | 175 - .../bifs-2D-interactivity-keysensor.bt | 810 - .../bifs-2D-interactivity-mousesensor.bt | 182 - .../bifs-2D-interactivity-nested-sensors.bt | 123 - .../bifs-2D-interactivity-planesensor2D.bt | 124 - ...bifs-2D-interactivity-proximitysensor2D.bt | 89 - .../bifs-2D-interactivity-stringsensor.bt | 153 - ...fs-2D-interactivity-touchsensor-4states.bt | 103 - ...s-2D-interactivity-touchsensor-hitpoint.bt | 91 - ...ivity-touchsensor-isactive-exposedfield.bt | 99 - ...s-2D-interactivity-touchsensor-isactive.bt | 98 - ...ifs-2D-interactivity-touchsensor-isover.bt | 59 - ...-2D-interactivity-touchsensor-move_over.bt | 268 - .../bifs-2D-painting-colortransform-alpha.bt | 101 - .../bifs-2D-painting-colortransform-bitmap.bt | 109 - .../bifs-2D-painting-colortransform-color.bt | 102 - .../bifs-2D-painting-lineproperties.bt | 168 - .../bifs-2D-painting-material2D.bt | 154 - .../bifs-2D-painting-xlineproperties-cap.bt | 211 - ...ting-xlineproperties-compositetexture2D.bt | 153 - .../bifs-2D-painting-xlineproperties-dash.bt | 142 - ...D-painting-xlineproperties-imagetexture.bt | 159 - .../bifs-2D-painting-xlineproperties-join.bt | 215 - ...painting-xlineproperties-lineargradient.bt | 122 - ...painting-xlineproperties-radialgradient.bt | 124 - ...fs-2D-painting-xlineproperties-scalable.bt | 123 - ...2D-painting-xlineproperties-transparent.bt | 176 - .../bifs-2D-positioning-clipper2D.bt | 316 - .../bifs-2D-positioning-form-align-center.bt | 162 - .../bifs-2D-positioning-form-align-horiz.bt | 129 - .../bifs-2D-positioning-form-align-vert.bt | 129 - .../bifs-2D-positioning-form-spread-horiz.bt | 182 - .../bifs-2D-positioning-form-spread-vert.bt | 170 - .../bifs-2D-positioning-layer2D.bt | 129 - .../bifs-2D-positioning-layer2d-in-layer2d.bt | 111 - ...-2D-positioning-layout-horiz-ltr-nowrap.bt | 403 - ...D-positioning-layout-horiz-ltr-wrap-btt.bt | 445 - ...D-positioning-layout-horiz-ltr-wrap-ttb.bt | 434 - ...-2D-positioning-layout-horiz-rtl-nowrap.bt | 415 - ...D-positioning-layout-horiz-rtl-wrap-btt.bt | 469 - ...D-positioning-layout-horiz-rtl-wrap-ttb.bt | 457 - .../bifs-2D-positioning-layout-horiz-text.bt | 84 - ...bifs-2D-positioning-layout-scroll-child.bt | 87 - .../bifs-2D-positioning-layout-scroll-full.bt | 344 - ...D-positioning-layout-scroll-modes-horiz.bt | 349 - ...2D-positioning-layout-scroll-modes-vert.bt | 350 - ...ifs-2D-positioning-layout-scroll-on-off.bt | 218 - ...s-2D-positioning-layout-vert-btt-nowrap.bt | 340 - ...2D-positioning-layout-vert-btt-wrap-ltr.bt | 372 - ...2D-positioning-layout-vert-btt-wrap-rtl.bt | 381 - ...s-2D-positioning-layout-vert-ttb-nowrap.bt | 331 - ...2D-positioning-layout-vert-ttb-wrap-ltr.bt | 363 - ...2D-positioning-layout-vert-ttb-wrap-rtl.bt | 372 - .../bifs-2D-positioning-orderedgroup.bt | 86 - .../bifs-2D-positioning-pathlayout.bt | 164 - .../bifs-2D-positioning-transform2D.bt | 133 - .../bifs-2D-positioning-transformmatrix2D.bt | 179 - regression_tests/bifs-2D-shapes-all.bt | 267 - .../bifs-2D-shapes-indexfaceset2D.bt | 123 - .../bifs-2D-shapes-indexlineset2D.bt | 100 - regression_tests/bifs-2D-shapes-pointset2D.bt | 56 - regression_tests/bifs-2D-shapes-xcurve2D.bt | 188 - ...texturing-compositetexture2D-background.bt | 116 - ...-2D-texturing-compositetexture2D-bitmap.bt | 89 - ...exturing-compositetexture2D-transparent.bt | 131 - .../bifs-2D-texturing-gradients-text.bt | 137 - ...bifs-2D-texturing-gradients-transparent.bt | 120 - .../bifs-2D-texturing-imagetexture-shapes.bt | 282 - ...bifs-2D-texturing-lineargradient-simple.bt | 75 - ...bifs-2D-texturing-lineargradient-spread.bt | 113 - .../bifs-2D-texturing-movietexture-shapes.bt | 285 - .../bifs-2D-texturing-pixeltexture.bt | 191 - ...bifs-2D-texturing-radialgradient-simple.bt | 94 - ...bifs-2D-texturing-radialgradient-spread.bt | 118 - ...bifs-2D-texturing-texturetransform-base.bt | 234 - ...-2D-texturing-texturetransform-interact.bt | 231 - ...ring-texturetransform-transformmatrix2D.bt | 242 - regression_tests/bifs-2D-viewport-complete.bt | 715 - regression_tests/bifs-2D-viewport-simple.bt | 88 - regression_tests/bifs-3D-background-images.bt | 87 - regression_tests/bifs-3D-background.bt | 56 - .../bifs-3D-interactivity-collision-proxy.bt | 80 - .../bifs-3D-interactivity-collision.bt | 79 - .../bifs-3D-interactivity-cylindersensor.bt | 90 - .../bifs-3D-interactivity-planesensor.bt | 93 - .../bifs-3D-interactivity-proximitysensor.bt | 80 - .../bifs-3D-interactivity-spheresensor.bt | 90 - .../bifs-3D-interactivity-visibilitysensor.bt | 100 - .../bifs-3D-lighting-directionalLight.bt | 63 - regression_tests/bifs-3D-lighting-fog.bt | 56 - .../bifs-3D-lighting-pointlight.bt | 71 - .../bifs-3D-lighting-spotlight.bt | 72 - ...-positioning-billboard-viewer-alignment.bt | 62 - .../bifs-3D-positioning-billboard.bt | 61 - .../bifs-3D-positioning-gravity.bt | 71 - .../bifs-3D-positioning-layer3D-views.bt | 160 - .../bifs-3D-positioning-layer3D.bt | 186 - regression_tests/bifs-3D-positioning-lod.bt | 63 - .../bifs-3D-positioning-transform.bt | 64 - .../bifs-3D-shapes-box-transparent.bt | 118 - regression_tests/bifs-3D-shapes-box.bt | 45 - regression_tests/bifs-3D-shapes-cone.bt | 58 - regression_tests/bifs-3D-shapes-cylinder.bt | 92 - .../bifs-3D-shapes-elevationgrid.bt | 74 - regression_tests/bifs-3D-shapes-extrusion.bt | 99 - .../bifs-3D-shapes-indexedfaceset.bt | 66 - .../bifs-3D-shapes-indexedlineset.bt | 99 - .../bifs-3D-shapes-nonlineardeformer.bt | 796 - regression_tests/bifs-3D-shapes-pointset.bt | 46 - .../bifs-3D-texturing-box-transparent.bt | 73 - .../bifs-3D-texturing-box-video.bt | 184 - regression_tests/bifs-3D-texturing-box.bt | 69 - ...-3D-texturing-compositetexture3D-bitmap.bt | 113 - ...ifs-3D-texturing-compositetexture3D-box.bt | 106 - .../bifs-3D-texturing-cone-transparent.bt | 68 - regression_tests/bifs-3D-texturing-cone.bt | 81 - .../bifs-3D-texturing-cylinder-transparent.bt | 93 - .../bifs-3D-texturing-cylinder.bt | 107 - .../bifs-3D-texturing-transform-box.bt | 85 - .../bifs-3D-texturing-transform-matrix-box.bt | 91 - regression_tests/bifs-3D-viewpoint-anim.bt | 84 - .../bifs-3D-viewpoint-bind-jump.bt | 114 - regression_tests/bifs-3D-viewpoint-bind.bt | 115 - .../bifs-3D-viewpoint-ortho-bind.bt | 114 - .../bifs-bitmap-image-meter-metrics.bt | 80 - .../bifs-bitmap-image-pixel-metrics.bt | 89 - .../bifs-bitmap-image-resizing.bt | 153 - .../bifs-bitmap-movie-materialkey.bt | 101 - regression_tests/bifs-bitmap-movie.bt | 84 - .../bifs-bitmap-video-resizing.bt | 152 - .../bifs-command-animated-osmo4logo.bt | 315 - regression_tests/bifs-command-delete-index.bt | 58 - regression_tests/bifs-command-delete-node.bt | 58 - regression_tests/bifs-command-delete-route.bt | 67 - regression_tests/bifs-command-global-qp.bt | 66 - regression_tests/bifs-command-insert-index.bt | 58 - regression_tests/bifs-command-insert-node.bt | 74 - .../bifs-command-insert-nodedef.bt | 64 - regression_tests/bifs-command-insert-route.bt | 67 - .../bifs-command-multiple-replace-field.bt | 66 - .../bifs-command-multiple-replace-index.bt | 62 - .../bifs-command-node-delete-ex.bt | 125 - regression_tests/bifs-command-proto-delete.bt | 93 - regression_tests/bifs-command-proto-insert.bt | 83 - .../bifs-command-protolist-delete.bt | 93 - .../bifs-command-quantification.bt | 186 - .../bifs-command-replace-field.bt | 67 - .../bifs-command-replace-index.bt | 58 - .../bifs-command-replace-node-null.bt | 65 - regression_tests/bifs-command-replace-node.bt | 67 - .../bifs-command-replace-route.bt | 67 - .../bifs-command-replace-scene-null.bt | 37 - .../bifs-command-replace-scene.bt | 76 - .../bifs-command-route-add-children.bt | 79 - .../bifs-command-route-children.bt | 79 - .../bifs-command-route-node-exposedfield.bt | 80 - regression_tests/bifs-command-route-node.bt | 76 - .../bifs-command-route-remove-children.bt | 93 - .../bifs-externproto-forestgump-lib.bt | 463 - .../bifs-externproto-forestgump.bt | 96 - .../bifs-externproto-mfurl-lib.bt | 52 - regression_tests/bifs-externproto-mfurl.bt | 69 - regression_tests/bifs-externproto-nood-lib.bt | 109 - regression_tests/bifs-externproto-nood.bt | 70 - .../bifs-externproto-simple-lib.bt | 90 - regression_tests/bifs-externproto-simple.bt | 81 - regression_tests/bifs-game-arrange.bt | 452 - regression_tests/bifs-game-breakout.bt | 1035 - regression_tests/bifs-game-bubble.bt | 433 - regression_tests/bifs-game-minesweeper.bt | 1538 - regression_tests/bifs-game-othello.bt | 2836 -- .../bifs-interpolation-colorinterpolator.bt | 63 - ...-interpolation-coordinateinterpolator2D.bt | 64 - .../bifs-interpolation-positionanimator.bt | 63 - .../bifs-interpolation-positionanimator2D.bt | 65 - ...rpolation-positioninterpolator-position.bt | 94 - ...interpolation-positioninterpolator-size.bt | 58 - ...olation-positioninterpolator2D-position.bt | 96 - ...terpolation-positioninterpolator2D-size.bt | 64 - .../bifs-interpolation-scalaranimator.bt | 66 - .../bifs-interpolation-scalarinterpolator.bt | 63 - .../bifs-interpolation-timesensor-enabled.bt | 82 - ...polation-timesensor-starttime_norestart.bt | 81 - ...erpolation-timesensor-starttime_restart.bt | 82 - .../bifs-interpolation-valuator-sftime.bt | 58 - .../bifs-linking-anchor-mp4-next.bt | 67 - .../bifs-linking-anchor-mp4-prev.bt | 67 - .../bifs-linking-anchor-viewpoint.bt | 92 - regression_tests/bifs-linking-anchor-www.bt | 67 - .../bifs-linking-animationstream.bt | 136 - .../bifs-linking-inline-direct-inline.bt | 75 - .../bifs-linking-inline-direct.bt | 51 - .../bifs-linking-inline-od-inline.bt | 76 - regression_tests/bifs-linking-inline-od.bt | 60 - .../bifs-linking-inline-rtsp-no-od.bt | 48 - regression_tests/bifs-linking-inline-rtsp.bt | 59 - .../bifs-linking-inline-segment-inline.bt | 74 - .../bifs-linking-inline-segment.bt | 41 - regression_tests/bifs-media-audiobuffer.bt | 203 - .../bifs-media-audioclip-urlchanged.bt | 145 - regression_tests/bifs-media-audioclip.bt | 133 - .../bifs-media-audiosource-mixing.bt | 194 - .../bifs-media-audiosource-urlchanged.bt | 146 - regression_tests/bifs-media-audiosource.bt | 133 - .../bifs-media-imagetexture-OD-reuse.bt | 89 - .../bifs-media-imagetexture-no-od.bt | 60 - .../bifs-media-imagetexture-object-scale.bt | 97 - .../bifs-media-imagetexture-transparent.bt | 275 - .../bifs-media-imagetexture-url-change.bt | 95 - .../bifs-media-movietexture-control.bt | 148 - .../bifs-media-movietexture-no-od.bt | 65 - .../bifs-media-movietexture-od-joinsession.bt | 93 - ...ifs-media-movietexture-od-leave-session.bt | 93 - .../bifs-media-movietexture-owns-OCR.bt | 75 - .../bifs-media-movietexture-shares-OCR.bt | 74 - .../bifs-media-movietexture-url-change.bt | 158 - .../bifs-media-sound-spatialize.bt | 77 - regression_tests/bifs-media-sound.bt | 77 - regression_tests/bifs-misc-UTF16-input.bt | 55 - regression_tests/bifs-misc-cyclic-graph.bt | 55 - .../bifs-misc-hc-proto-pathextrusion.bt | 103 - .../bifs-misc-hc-proto-planarextrusion.bt | 87 - .../bifs-misc-hc-proto-planeclipper.bt | 69 - ...ifs-misc-non-linear-parsing-conditional.bt | 69 - .../bifs-misc-non-linear-parsing-use.bt | 60 - ...-misc-srt-import-3gpp-control-share-ocr.bt | 64 - .../bifs-misc-srt-import-3gpp-control.bt | 64 - regression_tests/bifs-misc-srt-import-3gpp.bt | 64 - regression_tests/bifs-misc-srt-import.bt | 75 - regression_tests/bifs-od-remove-esd.bt | 78 - regression_tests/bifs-od-remove-od.bt | 78 - regression_tests/bifs-od-update-od.bt | 89 - regression_tests/bifs-proto-conditional.bt | 107 - regression_tests/bifs-proto-delete-def.bt | 91 - regression_tests/bifs-proto-delete-index.bt | 95 - regression_tests/bifs-proto-forestgump.bt | 478 - regression_tests/bifs-proto-mfurl.bt | 78 - regression_tests/bifs-proto-multiple.bt | 180 - regression_tests/bifs-proto-nested.bt | 132 - regression_tests/bifs-proto-route.bt | 110 - .../bifs-proto-sftime-protocode.bt | 99 - .../bifs-proto-sftime-protointerface.bt | 104 - regression_tests/bifs-proto-simple.bt | 88 - regression_tests/bifs-proto-use.bt | 93 - regression_tests/bifs-script-char-to-int.bt | 87 - regression_tests/bifs-script-child-create.bt | 61 - regression_tests/bifs-script-date.bt | 64 - regression_tests/bifs-script-event-out.bt | 85 - regression_tests/bifs-script-initialize.bt | 86 - regression_tests/bifs-script-load-url.bt | 67 - regression_tests/bifs-script-node-access.bt | 86 - regression_tests/bifs-script-node-create.bt | 80 - regression_tests/bifs-script-proto.bt | 223 - regression_tests/bifs-script-timestamp.bt | 67 - regression_tests/bifs-stream-text-switch.bt | 143 - regression_tests/bifs-text-align-horiz1.bt | 304 - regression_tests/bifs-text-align-horiz2.bt | 320 - regression_tests/bifs-text-align-horiz3.bt | 320 - regression_tests/bifs-text-align-horiz4.bt | 336 - regression_tests/bifs-text-align-vert1.bt | 200 - regression_tests/bifs-text-align-vert2.bt | 209 - regression_tests/bifs-text-align-vert3.bt | 209 - regression_tests/bifs-text-align-vert4.bt | 218 - regression_tests/bifs-text-glyph-advance.bt | 436 - regression_tests/bifs-text-length.bt | 230 - regression_tests/bifs-text-maxextend.bt | 176 - regression_tests/bifs-text-style.bt | 184 - regression_tests/bifs-text-unicode.bt | 55 - regression_tests/bifs-text-vrml-alignment.bt | 161 - .../bifs-timeline-mediacontrol-OCR.bt | 245 - .../bifs-timeline-mediacontrol-audio-speed.bt | 214 - .../bifs-timeline-mediacontrol-audio.bt | 352 - .../bifs-timeline-mediacontrol-complete.bt | 266 - ...bifs-timeline-mediacontrol-deactivation.bt | 105 - .../bifs-timeline-mediacontrol-inline-av.bt | 96 - ...s-timeline-mediacontrol-inline-segments.bt | 66 - .../bifs-timeline-mediacontrol-inline.bt | 231 - .../bifs-timeline-mediacontrol-rtsp.bt | 340 - .../bifs-timeline-mediacontrol-seg-inline.bt | 81 - .../bifs-timeline-mediacontrol-segments.bt | 154 - .../bifs-timeline-mediacontrol-video.bt | 248 - .../bifs-timeline-mediacontrol-videospeed.bt | 202 - ...ifs-timeline-mediasensor-segment-switch.bt | 226 - .../bifs-timeline-mediasensor-segment.bt | 215 - regression_tests/bifs-timeline-mediasensor.bt | 137 - .../bifs-2D-background-background2D-bind.bt | 71 + .../bifs-2D-background-background2D-image.bt | 97 + ...bifs-2D-background-background2D-layer2D.bt | 92 + .../bifs-2D-background-background2D-movie.bt | 94 + ...s-2D-background-background2D-url-change.bt | 105 + .../bifs/bifs-2D-interactivity-discsensor.bt | 129 + .../bifs/bifs-2D-interactivity-htk-sensor.bt | 175 + .../bifs/bifs-2D-interactivity-keysensor.bt | 810 + .../bifs/bifs-2D-interactivity-mousesensor.bt | 182 + .../bifs-2D-interactivity-nested-sensors.bt | 123 + .../bifs-2D-interactivity-planesensor2D.bt | 124 + ...bifs-2D-interactivity-proximitysensor2D.bt | 89 + .../bifs-2D-interactivity-stringsensor.bt | 153 + ...fs-2D-interactivity-touchsensor-4states.bt | 103 + ...s-2D-interactivity-touchsensor-hitpoint.bt | 91 + ...ivity-touchsensor-isactive-exposedfield.bt | 99 + ...s-2D-interactivity-touchsensor-isactive.bt | 98 + ...ifs-2D-interactivity-touchsensor-isover.bt | 59 + ...-2D-interactivity-touchsensor-move_over.bt | 268 + .../bifs-2D-painting-colortransform-alpha.bt | 101 + .../bifs-2D-painting-colortransform-bitmap.bt | 109 + .../bifs-2D-painting-colortransform-color.bt | 102 + .../bifs/bifs-2D-painting-lineproperties.bt | 168 + .../bifs/bifs-2D-painting-material2D.bt | 154 + .../bifs-2D-painting-xlineproperties-cap.bt | 211 + ...ting-xlineproperties-compositetexture2D.bt | 153 + .../bifs-2D-painting-xlineproperties-dash.bt | 142 + ...D-painting-xlineproperties-imagetexture.bt | 159 + .../bifs-2D-painting-xlineproperties-join.bt | 215 + ...painting-xlineproperties-lineargradient.bt | 122 + ...painting-xlineproperties-radialgradient.bt | 124 + ...fs-2D-painting-xlineproperties-scalable.bt | 123 + ...2D-painting-xlineproperties-transparent.bt | 176 + .../bifs/bifs-2D-positioning-clipper2D.bt | 316 + .../bifs-2D-positioning-form-align-center.bt | 162 + .../bifs-2D-positioning-form-align-horiz.bt | 129 + .../bifs-2D-positioning-form-align-vert.bt | 129 + .../bifs-2D-positioning-form-spread-horiz.bt | 182 + .../bifs-2D-positioning-form-spread-vert.bt | 170 + .../bifs/bifs-2D-positioning-layer2D.bt | 129 + .../bifs-2D-positioning-layer2d-in-layer2d.bt | 111 + ...-2D-positioning-layout-horiz-ltr-nowrap.bt | 403 + ...D-positioning-layout-horiz-ltr-wrap-btt.bt | 445 + ...D-positioning-layout-horiz-ltr-wrap-ttb.bt | 434 + ...-2D-positioning-layout-horiz-rtl-nowrap.bt | 415 + ...D-positioning-layout-horiz-rtl-wrap-btt.bt | 469 + ...D-positioning-layout-horiz-rtl-wrap-ttb.bt | 457 + .../bifs-2D-positioning-layout-horiz-text.bt | 84 + ...bifs-2D-positioning-layout-scroll-child.bt | 87 + .../bifs-2D-positioning-layout-scroll-full.bt | 344 + ...D-positioning-layout-scroll-modes-horiz.bt | 349 + ...2D-positioning-layout-scroll-modes-vert.bt | 350 + ...ifs-2D-positioning-layout-scroll-on-off.bt | 218 + ...s-2D-positioning-layout-vert-btt-nowrap.bt | 340 + ...2D-positioning-layout-vert-btt-wrap-ltr.bt | 372 + ...2D-positioning-layout-vert-btt-wrap-rtl.bt | 381 + ...s-2D-positioning-layout-vert-ttb-nowrap.bt | 331 + ...2D-positioning-layout-vert-ttb-wrap-ltr.bt | 363 + ...2D-positioning-layout-vert-ttb-wrap-rtl.bt | 372 + .../bifs/bifs-2D-positioning-orderedgroup.bt | 86 + ...bifs-2D-positioning-pathlayout-graphics.bt | 177 + .../bifs/bifs-2D-positioning-pathlayout.bt | 164 + .../bifs/bifs-2D-positioning-transform2D.bt | 133 + .../bifs-2D-positioning-transformmatrix2D.bt | 179 + regression_tests/bifs/bifs-2D-shapes-all.bt | 267 + .../bifs/bifs-2D-shapes-indexfaceset2D.bt | 123 + .../bifs/bifs-2D-shapes-indexlineset2D.bt | 100 + .../bifs/bifs-2D-shapes-pointset2D.bt | 56 + .../bifs/bifs-2D-shapes-xcurve2D.bt | 188 + ...texturing-compositetexture2D-background.bt | 117 + ...-2D-texturing-compositetexture2D-bitmap.bt | 89 + ...exturing-compositetexture2D-transparent.bt | 129 + .../bifs/bifs-2D-texturing-gradients-text.bt | 137 + ...bifs-2D-texturing-gradients-transparent.bt | 120 + .../bifs-2D-texturing-imagetexture-shapes.bt | 282 + ...bifs-2D-texturing-lineargradient-simple.bt | 75 + ...bifs-2D-texturing-lineargradient-spread.bt | 113 + .../bifs-2D-texturing-movietexture-shapes.bt | 285 + .../bifs/bifs-2D-texturing-pixeltexture.bt | 191 + ...bifs-2D-texturing-radialgradient-simple.bt | 94 + ...bifs-2D-texturing-radialgradient-spread.bt | 118 + ...bifs-2D-texturing-texturetransform-base.bt | 234 + ...-2D-texturing-texturetransform-interact.bt | 231 + ...ring-texturetransform-transformmatrix2D.bt | 242 + .../bifs/bifs-2D-viewport-complete.bt | 715 + .../bifs/bifs-2D-viewport-simple.bt | 88 + .../bifs/bifs-3D-background-images.bt | 87 + regression_tests/bifs/bifs-3D-background.bt | 56 + .../bifs-3D-interactivity-collision-proxy.bt | 80 + .../bifs/bifs-3D-interactivity-collision.bt | 79 + .../bifs-3D-interactivity-cylindersensor.bt | 90 + .../bifs/bifs-3D-interactivity-planesensor.bt | 93 + .../bifs-3D-interactivity-proximitysensor.bt | 80 + .../bifs-3D-interactivity-spheresensor.bt | 90 + .../bifs-3D-interactivity-visibilitysensor.bt | 100 + .../bifs/bifs-3D-lighting-directionalLight.bt | 63 + regression_tests/bifs/bifs-3D-lighting-fog.bt | 56 + .../bifs/bifs-3D-lighting-pointlight.bt | 71 + .../bifs/bifs-3D-lighting-spotlight.bt | 72 + ...-positioning-billboard-viewer-alignment.bt | 62 + .../bifs/bifs-3D-positioning-billboard.bt | 61 + .../bifs/bifs-3D-positioning-gravity.bt | 71 + .../bifs/bifs-3D-positioning-layer3D-views.bt | 160 + .../bifs/bifs-3D-positioning-layer3D.bt | 186 + .../bifs/bifs-3D-positioning-lod.bt | 63 + .../bifs/bifs-3D-positioning-transform.bt | 64 + .../bifs/bifs-3D-shapes-box-transparent.bt | 118 + regression_tests/bifs/bifs-3D-shapes-box.bt | 45 + regression_tests/bifs/bifs-3D-shapes-cone.bt | 58 + .../bifs/bifs-3D-shapes-cylinder.bt | 92 + .../bifs/bifs-3D-shapes-elevationgrid.bt | 74 + .../bifs/bifs-3D-shapes-extrusion.bt | 99 + .../bifs/bifs-3D-shapes-indexedfaceset.bt | 66 + .../bifs/bifs-3D-shapes-indexedlineset.bt | 99 + .../bifs/bifs-3D-shapes-nonlineardeformer.bt | 796 + .../bifs/bifs-3D-shapes-pointset.bt | 46 + .../bifs/bifs-3D-texturing-box-transparent.bt | 73 + .../bifs/bifs-3D-texturing-box-video.bt | 184 + .../bifs/bifs-3D-texturing-box.bt | 69 + ...-3D-texturing-compositetexture3D-bitmap.bt | 113 + ...ifs-3D-texturing-compositetexture3D-box.bt | 106 + .../bifs-3D-texturing-cone-transparent.bt | 68 + .../bifs/bifs-3D-texturing-cone.bt | 81 + .../bifs-3D-texturing-cylinder-transparent.bt | 93 + .../bifs/bifs-3D-texturing-cylinder.bt | 107 + .../bifs/bifs-3D-texturing-transform-box.bt | 85 + .../bifs-3D-texturing-transform-matrix-box.bt | 91 + .../bifs/bifs-3D-viewpoint-anim.bt | 84 + .../bifs/bifs-3D-viewpoint-bind-jump.bt | 114 + .../bifs/bifs-3D-viewpoint-bind.bt | 115 + .../bifs/bifs-3D-viewpoint-ortho-bind.bt | 114 + .../bifs/bifs-bitmap-image-meter-metrics.bt | 80 + .../bifs/bifs-bitmap-image-pixel-metrics.bt | 89 + .../bifs/bifs-bitmap-image-resizing.bt | 153 + .../bifs/bifs-bitmap-movie-materialkey.bt | 101 + regression_tests/bifs/bifs-bitmap-movie.bt | 84 + .../bifs/bifs-bitmap-video-resizing.bt | 152 + .../bifs/bifs-command-animated-osmo4logo.bt | 315 + .../bifs/bifs-command-delete-index.bt | 58 + .../bifs/bifs-command-delete-node.bt | 58 + .../bifs/bifs-command-delete-route.bt | 67 + .../bifs/bifs-command-global-qp.bt | 66 + .../bifs/bifs-command-insert-index.bt | 58 + .../bifs/bifs-command-insert-node.bt | 74 + .../bifs/bifs-command-insert-nodedef.bt | 64 + .../bifs/bifs-command-insert-route.bt | 67 + .../bifs-command-multiple-replace-field.bt | 66 + .../bifs-command-multiple-replace-index.bt | 62 + .../bifs/bifs-command-node-delete-ex.bt | 125 + .../bifs/bifs-command-proto-delete.bt | 93 + .../bifs/bifs-command-proto-insert.bt | 83 + .../bifs/bifs-command-protolist-delete.bt | 93 + .../bifs/bifs-command-quantification.bt | 186 + .../bifs/bifs-command-replace-field.bt | 67 + .../bifs/bifs-command-replace-index.bt | 58 + .../bifs/bifs-command-replace-node-null.bt | 65 + .../bifs/bifs-command-replace-node.bt | 67 + .../bifs/bifs-command-replace-route.bt | 67 + .../bifs/bifs-command-replace-scene-null.bt | 37 + .../bifs/bifs-command-replace-scene.bt | 76 + .../bifs/bifs-command-route-add-children.bt | 79 + .../bifs/bifs-command-route-children.bt | 79 + .../bifs-command-route-node-exposedfield.bt | 80 + .../bifs/bifs-command-route-node.bt | 76 + .../bifs-command-route-remove-children.bt | 93 + .../bifs/bifs-externproto-forestgump-lib.bt | 463 + .../bifs/bifs-externproto-forestgump.bt | 96 + .../bifs/bifs-externproto-mfurl-lib.bt | 52 + .../bifs/bifs-externproto-mfurl.bt | 69 + .../bifs/bifs-externproto-nood-lib.bt | 109 + .../bifs/bifs-externproto-nood.bt | 70 + .../bifs/bifs-externproto-simple-lib.bt | 90 + .../bifs/bifs-externproto-simple.bt | 81 + regression_tests/bifs/bifs-game-arrange.bt | 452 + regression_tests/bifs/bifs-game-breakout.bt | 1035 + regression_tests/bifs/bifs-game-bubble.bt | 433 + .../bifs/bifs-game-minesweeper.bt | 1538 + regression_tests/bifs/bifs-game-othello.bt | 2836 ++ .../bifs-interpolation-colorinterpolator.bt | 63 + ...-interpolation-coordinateinterpolator2D.bt | 64 + .../bifs-interpolation-positionanimator.bt | 63 + .../bifs-interpolation-positionanimator2D.bt | 65 + ...rpolation-positioninterpolator-position.bt | 94 + ...interpolation-positioninterpolator-size.bt | 58 + ...olation-positioninterpolator2D-position.bt | 96 + ...terpolation-positioninterpolator2D-size.bt | 64 + .../bifs/bifs-interpolation-scalaranimator.bt | 66 + .../bifs-interpolation-scalarinterpolator.bt | 63 + .../bifs-interpolation-timesensor-enabled.bt | 82 + ...polation-timesensor-starttime_norestart.bt | 81 + ...erpolation-timesensor-starttime_restart.bt | 82 + .../bifs-interpolation-valuator-sftime.bt | 58 + .../bifs/bifs-linking-anchor-mp4-next.bt | 67 + .../bifs/bifs-linking-anchor-mp4-prev.bt | 67 + .../bifs/bifs-linking-anchor-viewpoint.bt | 92 + .../bifs/bifs-linking-anchor-www.bt | 67 + .../bifs/bifs-linking-animationstream.bt | 135 + .../bifs/bifs-linking-inline-direct-inline.bt | 75 + .../bifs/bifs-linking-inline-direct.bt | 51 + .../bifs/bifs-linking-inline-od-inline.bt | 76 + .../bifs/bifs-linking-inline-od.bt | 60 + .../bifs/bifs-linking-inline-rtsp-no-od.bt | 48 + .../bifs/bifs-linking-inline-rtsp.bt | 59 + .../bifs-linking-inline-segment-inline.bt | 74 + .../bifs/bifs-linking-inline-segment.bt | 41 + .../bifs/bifs-media-audiobuffer.bt | 203 + .../bifs/bifs-media-audioclip-urlchanged.bt | 145 + regression_tests/bifs/bifs-media-audioclip.bt | 133 + .../bifs/bifs-media-audiosource-mixing.bt | 194 + .../bifs/bifs-media-audiosource-urlchanged.bt | 146 + .../bifs/bifs-media-audiosource.bt | 133 + .../bifs/bifs-media-imagetexture-OD-reuse.bt | 89 + .../bifs/bifs-media-imagetexture-no-od.bt | 60 + .../bifs-media-imagetexture-object-scale.bt | 97 + .../bifs-media-imagetexture-transparent.bt | 275 + .../bifs-media-imagetexture-url-change.bt | 95 + .../bifs/bifs-media-movietexture-control.bt | 148 + .../bifs/bifs-media-movietexture-no-od.bt | 65 + .../bifs-media-movietexture-od-joinsession.bt | 93 + ...ifs-media-movietexture-od-leave-session.bt | 93 + .../bifs/bifs-media-movietexture-owns-OCR.bt | 75 + .../bifs-media-movietexture-shares-OCR.bt | 74 + .../bifs-media-movietexture-url-change.bt | 158 + .../bifs/bifs-media-sound-spatialize.bt | 77 + regression_tests/bifs/bifs-media-sound.bt | 77 + .../bifs/bifs-misc-UTF16-input.bt | 55 + .../bifs/bifs-misc-cyclic-graph.bt | 55 + .../bifs/bifs-misc-hc-proto-pathextrusion.bt | 103 + .../bifs-misc-hc-proto-planarextrusion.bt | 87 + .../bifs/bifs-misc-hc-proto-planeclipper.bt | 69 + ...ifs-misc-non-linear-parsing-conditional.bt | 69 + .../bifs/bifs-misc-non-linear-parsing-use.bt | 60 + ...-misc-srt-import-3gpp-control-share-ocr.bt | 64 + .../bifs/bifs-misc-srt-import-3gpp-control.bt | 64 + .../bifs/bifs-misc-srt-import-3gpp.bt | 64 + regression_tests/bifs/bifs-misc-srt-import.bt | 75 + regression_tests/bifs/bifs-od-remove-esd.bt | 78 + regression_tests/bifs/bifs-od-remove-od.bt | 78 + regression_tests/bifs/bifs-od-update-od.bt | 89 + .../bifs/bifs-proto-conditional.bt | 107 + .../bifs/bifs-proto-delete-def.bt | 91 + .../bifs/bifs-proto-delete-index.bt | 95 + .../bifs/bifs-proto-forestgump.bt | 478 + regression_tests/bifs/bifs-proto-mfurl.bt | 78 + regression_tests/bifs/bifs-proto-multiple.bt | 180 + regression_tests/bifs/bifs-proto-nested.bt | 132 + regression_tests/bifs/bifs-proto-route.bt | 110 + .../bifs/bifs-proto-sftime-protocode.bt | 99 + .../bifs/bifs-proto-sftime-protointerface.bt | 104 + regression_tests/bifs/bifs-proto-simple.bt | 88 + regression_tests/bifs/bifs-proto-use.bt | 93 + .../bifs/bifs-script-char-to-int.bt | 87 + .../bifs/bifs-script-child-create.bt | 61 + regression_tests/bifs/bifs-script-date.bt | 64 + .../bifs/bifs-script-event-out.bt | 85 + .../bifs/bifs-script-initialize.bt | 86 + regression_tests/bifs/bifs-script-load-url.bt | 67 + .../bifs/bifs-script-node-access.bt | 86 + .../bifs/bifs-script-node-create.bt | 80 + regression_tests/bifs/bifs-script-proto.bt | 223 + .../bifs/bifs-script-timestamp.bt | 67 + .../bifs/bifs-stream-text-switch.bt | 143 + .../bifs/bifs-text-align-horiz1.bt | 304 + .../bifs/bifs-text-align-horiz2.bt | 320 + .../bifs/bifs-text-align-horiz3.bt | 320 + .../bifs/bifs-text-align-horiz4.bt | 336 + .../bifs/bifs-text-align-vert1.bt | 200 + .../bifs/bifs-text-align-vert2.bt | 209 + .../bifs/bifs-text-align-vert3.bt | 209 + .../bifs/bifs-text-align-vert4.bt | 218 + .../bifs/bifs-text-glyph-advance.bt | 436 + regression_tests/bifs/bifs-text-length.bt | 230 + regression_tests/bifs/bifs-text-maxextend.bt | 176 + regression_tests/bifs/bifs-text-style.bt | 184 + regression_tests/bifs/bifs-text-unicode.bt | 55 + .../bifs/bifs-text-vrml-alignment.bt | 161 + .../bifs/bifs-timeline-mediacontrol-OCR.bt | 245 + .../bifs-timeline-mediacontrol-audio-speed.bt | 214 + .../bifs/bifs-timeline-mediacontrol-audio.bt | 352 + .../bifs-timeline-mediacontrol-complete.bt | 266 + ...bifs-timeline-mediacontrol-deactivation.bt | 105 + .../bifs-timeline-mediacontrol-inline-av.bt | 96 + ...s-timeline-mediacontrol-inline-segments.bt | 66 + .../bifs/bifs-timeline-mediacontrol-inline.bt | 231 + .../bifs/bifs-timeline-mediacontrol-rtsp.bt | 340 + .../bifs-timeline-mediacontrol-seg-inline.bt | 81 + .../bifs-timeline-mediacontrol-segments.bt | 154 + .../bifs/bifs-timeline-mediacontrol-video.bt | 258 + .../bifs-timeline-mediacontrol-videospeed.bt | 202 + ...ifs-timeline-mediasensor-segment-switch.bt | 226 + .../bifs/bifs-timeline-mediasensor-segment.bt | 215 + .../bifs/bifs-timeline-mediasensor.bt | 137 + regression_tests/svg/all_syntaxes_1.1F2.svg | 498 + regression_tests/svg/createanim-by-script.svg | 73 + .../svg/createimage-by-script.svg | 16 + regression_tests/svg/utfscript.svg | 15 + regression_tests/utfscript.svg | 15 + regression_tests/x3d-2D-Arc2d.x3dv | 23 - regression_tests/x3d-2D-ArcClose2d.x3dv | 24 - regression_tests/x3d-2D-Disk2d.x3dv | 24 - regression_tests/x3d-2D-Polyline2d.x3dv | 23 - regression_tests/x3d-2D-Polypoint2d.x3dv | 23 - regression_tests/x3d-2D-TriangleSet2d.x3dv | 24 - .../x3d-3D-IndexedTriangleFanSet.x3dv | 28 - .../x3d-3D-IndexedTriangleSet.x3dv | 27 - .../x3d-3D-IndexedTriangleStripSet.x3dv | 28 - regression_tests/x3d-3D-LineSet.x3dv | 27 - regression_tests/x3d-3D-TriangleFanSet.x3dv | 28 - regression_tests/x3d-3D-TriangleSet.x3dv | 26 - regression_tests/x3d-3D-TriangleStripSet.x3dv | 28 - regression_tests/x3d-misc-ColorRGBA.x3dv | 42 - regression_tests/x3d-misc-HatchStyle.x3dv | 31 - regression_tests/x3d-misc-KeySensor.x3dv | 73 - regression_tests/x3d-misc-StringSensor.x3dv | 83 - regression_tests/x3d/x3d-2D-Arc2d.x3dv | 23 + regression_tests/x3d/x3d-2D-ArcClose2d.x3dv | 24 + regression_tests/x3d/x3d-2D-Disk2d.x3dv | 24 + regression_tests/x3d/x3d-2D-Polyline2d.x3dv | 23 + regression_tests/x3d/x3d-2D-Polypoint2d.x3dv | 23 + .../x3d/x3d-2D-TriangleSet2d.x3dv | 24 + .../x3d/x3d-3D-IndexedTriangleFanSet.x3dv | 28 + .../x3d/x3d-3D-IndexedTriangleSet.x3dv | 27 + .../x3d/x3d-3D-IndexedTriangleStripSet.x3dv | 28 + regression_tests/x3d/x3d-3D-LineSet.x3dv | 27 + .../x3d/x3d-3D-TriangleFanSet.x3dv | 28 + regression_tests/x3d/x3d-3D-TriangleSet.x3dv | 26 + .../x3d/x3d-3D-TriangleStripSet.x3dv | 28 + regression_tests/x3d/x3d-misc-ColorRGBA.x3dv | 42 + regression_tests/x3d/x3d-misc-HatchStyle.x3dv | 31 + regression_tests/x3d/x3d-misc-KeySensor.x3dv | 73 + .../x3d/x3d-misc-StringSensor.x3dv | 83 + src/Makefile | 76 +- src/bifs/arith_decoder.c | 48 +- src/bifs/bifs_codec.c | 74 +- src/bifs/bifs_node_tables.c | 313 +- src/bifs/com_dec.c | 215 +- src/bifs/com_enc.c | 92 +- src/bifs/conditional.c | 33 +- src/bifs/field_decode.c | 114 +- src/bifs/field_encode.c | 61 +- src/bifs/memory_decoder.c | 170 +- src/bifs/predictive_mffield.c | 2 + src/bifs/quant.h | 13 +- src/bifs/quantize.c | 3 + src/bifs/script.h | 4 + src/bifs/script_dec.c | 46 +- src/bifs/script_enc.c | 35 +- src/bifs/unquantize.c | 31 +- src/compositor/audio_input.c | 204 +- src/compositor/audio_mixer.c | 43 +- src/compositor/audio_render.c | 377 +- src/compositor/bindable.c | 120 +- src/compositor/camera.c | 2 +- src/compositor/compositor.c | 1048 +- src/compositor/compositor_2d.c | 469 +- src/compositor/compositor_3d.c | 105 +- src/compositor/compositor_node_init.c | 329 +- src/compositor/drawable.c | 168 +- src/compositor/drawable.h | 17 +- src/compositor/events.c | 565 +- src/compositor/font_engine.c | 101 +- src/compositor/gl_inc.h | 50 +- src/compositor/hardcoded_protos.c | 296 +- src/compositor/hc_flash_shape.c | 466 + src/compositor/mesh.c | 166 +- src/compositor/mesh_collide.c | 2 +- src/compositor/mesh_tesselate.c | 38 +- src/compositor/mpeg4_animstream.c | 10 +- src/compositor/mpeg4_audio.c | 23 +- src/compositor/mpeg4_background.c | 10 +- src/compositor/mpeg4_background2d.c | 48 +- src/compositor/mpeg4_bitmap.c | 10 +- src/compositor/mpeg4_composite.c | 358 +- src/compositor/mpeg4_form.c | 15 +- src/compositor/mpeg4_geometry_2d.c | 87 +- src/compositor/mpeg4_geometry_3d.c | 29 +- src/compositor/mpeg4_geometry_ifs2d.c | 15 +- src/compositor/mpeg4_geometry_ils2d.c | 34 +- src/compositor/mpeg4_gradients.c | 110 +- src/compositor/mpeg4_grouping.c | 120 +- src/compositor/mpeg4_grouping.h | 15 +- src/compositor/mpeg4_grouping_2d.c | 50 +- src/compositor/mpeg4_grouping_3d.c | 19 +- src/compositor/mpeg4_layer_2d.c | 103 +- src/compositor/mpeg4_layer_3d.c | 61 +- src/compositor/mpeg4_layout.c | 14 +- src/compositor/mpeg4_lighting.c | 8 +- src/compositor/mpeg4_path_layout.c | 9 +- src/compositor/mpeg4_sensors.c | 264 +- src/compositor/mpeg4_sound.c | 9 +- src/compositor/mpeg4_text.c | 112 +- src/compositor/mpeg4_textures.c | 182 +- src/compositor/mpeg4_timesensor.c | 13 +- src/compositor/mpeg4_viewport.c | 76 +- src/compositor/navigate.c | 18 +- src/compositor/nodes_stacks.h | 62 +- src/compositor/offscreen_cache.c | 62 +- src/compositor/offscreen_cache.h | 2 +- src/compositor/svg_base.c | 5 +- src/compositor/svg_filters.c | 425 + src/compositor/svg_font.c | 29 +- src/compositor/svg_geometry.c | 8 +- src/compositor/svg_grouping.c | 146 +- src/compositor/svg_media.c | 61 +- src/compositor/svg_paint_servers.c | 139 +- src/compositor/svg_text.c | 33 +- src/compositor/texturing.c | 38 +- src/compositor/texturing_gl.c | 156 +- src/compositor/visual_manager.c | 31 +- src/compositor/visual_manager.h | 18 +- src/compositor/visual_manager_2d.c | 385 +- src/compositor/visual_manager_2d.h | 36 +- src/compositor/visual_manager_2d_draw.c | 98 +- src/compositor/visual_manager_3d.c | 256 +- src/compositor/visual_manager_3d.h | 21 +- src/compositor/visual_manager_3d_gl.c | 97 +- src/compositor/x3d_geometry.c | 18 +- src/export.cpp | 1510 + src/ietf/rtcp.c | 41 +- src/ietf/rtp.c | 165 +- src/ietf/rtp_depacketizer.c | 159 +- src/ietf/rtp_packetizer.c | 50 +- src/ietf/rtp_pck_3gpp.c | 15 +- src/ietf/rtp_pck_mpeg12.c | 21 +- src/ietf/rtp_pck_mpeg4.c | 26 +- src/ietf/rtp_streamer.c | 735 + src/ietf/rtsp_command.c | 75 +- src/ietf/rtsp_common.c | 19 +- src/ietf/rtsp_response.c | 134 +- src/ietf/rtsp_session.c | 55 +- src/ietf/sdp.c | 162 +- src/isomedia/avc_ext.c | 239 +- src/isomedia/box_code_3gpp.c | 276 +- src/isomedia/box_code_apple.c | 47 +- src/isomedia/box_code_base.c | 1460 +- src/isomedia/box_code_isma.c | 119 +- src/isomedia/box_code_meta.c | 107 +- src/isomedia/box_dump.c | 869 +- src/isomedia/box_funcs.c | 141 +- src/isomedia/data_map.c | 75 +- src/isomedia/hint_track.c | 35 +- src/isomedia/hinting.c | 53 +- src/isomedia/isma_sample.c | 48 +- src/isomedia/isom_intern.c | 106 +- src/isomedia/isom_read.c | 364 +- src/isomedia/isom_store.c | 35 +- src/isomedia/isom_write.c | 338 +- src/isomedia/media.c | 56 +- src/isomedia/media_odf.c | 22 +- src/isomedia/meta.c | 60 +- src/isomedia/movie_fragments.c | 434 +- src/isomedia/sample_descs.c | 112 +- src/isomedia/stbl_read.c | 3 + src/isomedia/stbl_write.c | 195 +- src/isomedia/track.c | 64 +- src/isomedia/tx3g.c | 100 +- src/laser/lsr_dec.c | 756 +- src/laser/lsr_enc.c | 546 +- src/laser/lsr_tables.c | 4 +- src/libgpac.def | 1235 - src/libgpac_ce.def | 1207 - src/mcrypt/cbc.c | 16 +- src/mcrypt/cfb.c | 16 +- src/mcrypt/ctr.c | 15 +- src/mcrypt/des.c | 8 +- src/mcrypt/ecb.c | 5 +- src/mcrypt/g_crypt.c | 36 +- src/mcrypt/ncfb.c | 17 +- src/mcrypt/nofb.c | 17 +- src/mcrypt/ofb.c | 16 +- src/mcrypt/rijndael-128.c | 5 +- src/mcrypt/rijndael-192.c | 6 +- src/mcrypt/rijndael-256.c | 6 +- src/mcrypt/sha1.c | 2 +- src/mcrypt/stream.c | 5 +- src/mcrypt/tripledes.c | 9 +- src/media_tools/av_parsers.c | 1205 +- src/media_tools/avilib.c | 554 +- src/media_tools/dvb_mpe.c | 1246 + src/media_tools/filestreamer.c | 523 + src/media_tools/gpac_ogg.c | 42 +- src/media_tools/img.c | 133 +- src/media_tools/ismacryp.c | 41 +- src/media_tools/isom_hinter.c | 538 +- src/media_tools/isom_tools.c | 381 +- src/media_tools/m2ts_mux.c | 1501 + src/media_tools/media_export.c | 248 +- src/media_tools/media_import.c | 1818 +- src/media_tools/mpeg2_ps.c | 71 +- src/media_tools/mpeg2_ps.h | 9 +- src/media_tools/mpegts.c | 930 +- src/media_tools/reedsolomon.c | 569 + src/media_tools/saf.c | 26 +- src/media_tools/text_import.c | 133 +- src/media_tools/vobsub.c | 18 +- src/odf/desc_private.c | 316 +- src/odf/descriptors.c | 251 +- src/odf/ipmpx_code.c | 122 +- src/odf/ipmpx_dump.c | 13 +- src/odf/ipmpx_parse.c | 46 +- src/odf/oci_codec.c | 12 +- src/odf/odf_code.c | 1729 +- src/odf/odf_codec.c | 126 +- src/odf/odf_command.c | 51 +- src/odf/odf_dump.c | 17 +- src/odf/odf_parse.c | 118 +- src/odf/qos.c | 87 +- src/odf/slc.c | 6 +- src/scene_manager/encode_cbk.c | 503 - src/scene_manager/encode_isom.c | 291 +- src/scene_manager/loader_bt.c | 934 +- src/scene_manager/loader_isom.c | 61 +- src/scene_manager/loader_qt.c | 25 +- src/scene_manager/loader_svg.c | 419 +- src/scene_manager/loader_xmt.c | 476 +- src/scene_manager/scene_dump.c | 827 +- src/scene_manager/scene_engine.c | 1140 + src/scene_manager/scene_manager.c | 718 +- src/scene_manager/scene_stats.c | 44 +- src/scene_manager/swf_bifs.c | 94 +- src/scene_manager/swf_parse.c | 247 +- src/scene_manager/text_to_bifs.c | 41 +- src/scenegraph/base_scenegraph.c | 573 +- src/scenegraph/commands.c | 316 +- src/scenegraph/dom_events.c | 86 +- src/scenegraph/dom_smjs.c | 1262 +- src/scenegraph/mpeg4_animators.c | 24 +- src/scenegraph/mpeg4_nodes.c | 33468 +++++++++++---- src/scenegraph/mpeg4_valuator.c | 443 +- src/scenegraph/smil_anim.c | 2975 +- src/scenegraph/smil_timing.c | 24 +- src/scenegraph/svg_attributes.c | 2119 +- src/scenegraph/svg_properties.c | 78 +- src/scenegraph/svg_smjs.c | 724 +- src/scenegraph/svg_types.c | 94 +- src/scenegraph/vrml_interpolators.c | 127 +- src/scenegraph/vrml_proto.c | 239 +- src/scenegraph/vrml_route.c | 90 +- src/scenegraph/vrml_script.c | 38 +- src/scenegraph/vrml_smjs.c | 2148 +- src/scenegraph/vrml_tools.c | 828 +- src/scenegraph/x3d_nodes.c | 8742 +++- src/scenegraph/xbl_process.c | 16 +- src/scenegraph/xml_ns.c | 162 +- src/terminal/channel.c | 458 +- src/terminal/clock.c | 52 +- src/terminal/decoder.c | 279 +- src/terminal/inline.c | 1719 - src/terminal/input_sensor.c | 342 +- src/terminal/input_sensor.h | 23 +- src/terminal/media_control.c | 254 +- src/terminal/media_control.h | 40 +- src/terminal/media_manager.c | 63 +- src/terminal/media_memory.c | 55 +- src/terminal/media_memory.h | 17 +- src/terminal/media_object.c | 364 +- src/terminal/media_sensor.c | 22 +- src/terminal/mpeg4_inline.c | 715 + src/terminal/network_service.c | 153 +- src/terminal/object_browser.c | 36 +- src/terminal/object_manager.c | 509 +- src/terminal/scene.c | 1407 + src/terminal/svg_external.c | 58 +- src/terminal/term_node_init.c | 180 +- src/terminal/terminal.c | 885 +- src/utils/bitstream.c | 53 +- src/utils/color.c | 96 +- src/utils/configfile.c | 115 +- src/utils/dlmalloc.c | 5712 +++ src/utils/downloader.c | 602 +- src/utils/error.c | 808 +- src/utils/gzio.cpp | 13 +- src/utils/list.c | 56 +- src/utils/math.c | 1 + src/utils/module.c | 104 +- src/utils/module_wrap.h | 6 +- src/utils/os_divers.c | 274 +- src/utils/os_module.c | 34 +- src/utils/os_net.c | 263 +- src/utils/os_thread.c | 69 +- src/utils/path2d.c | 58 +- src/utils/path2d_stroker.c | 30 +- src/utils/symbian_net.cpp | 14 +- src/utils/symbian_os.cpp | 34 +- src/utils/uni_bidi.c | 28 +- src/utils/url.c | 140 +- src/utils/xml_parser.c | 319 +- src/utils/zutil.c | 28 +- src/utils/zutil.h | 8 +- 1753 files changed, 342082 insertions(+), 152589 deletions(-) create mode 100644 applications/generators/MPEG4/templates10.txt create mode 100644 applications/generators/MPEG4/templates8.txt create mode 100644 applications/generators/MPEG4/templates9.txt create mode 100644 applications/m3u82mpd/main.c create mode 100644 applications/mp4box/live.c delete mode 100644 applications/standalone2drender/standalone2drender.c delete mode 100644 applications/standalone2drender/standalone2drender.h delete mode 100644 applications/testapps/beng_test/BifsEngineTester.dsp delete mode 100644 applications/testapps/beng_test/CmdLineTst.c delete mode 100644 applications/testapps/beng_test/rect-update.bt delete mode 100644 applications/testapps/beng_test/rect.bt create mode 100644 applications/testapps/broadcaster/debug.c create mode 100644 applications/testapps/broadcaster/debug.h delete mode 100644 applications/testapps/mp42ts/mp42ts.c create mode 100644 applications/testapps/mp42ts/mp42ts.vcproj delete mode 100644 applications/testapps/mp4_streamer/Makefile delete mode 100644 applications/testapps/mp4_streamer/configuration.cfg delete mode 100644 applications/testapps/mp4_streamer/main.c delete mode 100644 applications/testapps/mp4_streamer/mp4_streamer.dsp delete mode 100755 bin/gcc/libgpac.so create mode 100644 build/codeblocks/GPAX.cbp create mode 100644 build/codeblocks/Osmo4.cbp create mode 100644 build/codeblocks/aac_in.cbp create mode 100644 build/codeblocks/ac3_in.cbp create mode 100644 build/codeblocks/amr_dec.cbp create mode 100644 build/codeblocks/amr_float_dec.cbp create mode 100644 build/codeblocks/bifs_dec.cbp create mode 100644 build/codeblocks/ctx_load.cbp create mode 100644 build/codeblocks/demo_is.cbp create mode 100644 build/codeblocks/dummy_in.cbp create mode 100644 build/codeblocks/dx_hw.cbp create mode 100644 build/codeblocks/ffmpeg_in.cbp create mode 100644 build/codeblocks/ft_font.cbp create mode 100644 build/codeblocks/gdip_raster.cbp create mode 100644 build/codeblocks/gpac.workspace create mode 100644 build/codeblocks/gpac_js.cbp create mode 100644 build/codeblocks/img_in.cbp create mode 100644 build/codeblocks/ismacryp.cbp create mode 100644 build/codeblocks/isom_in.cbp create mode 100644 build/codeblocks/laser_dec.cbp create mode 100644 build/codeblocks/libgpac.cbp create mode 100644 build/codeblocks/mp3_in.cbp create mode 100644 build/codeblocks/mp4box.cbp create mode 100644 build/codeblocks/mp4client.cbp create mode 100644 build/codeblocks/mpegts_in.cbp create mode 100644 build/codeblocks/odf_dec.cbp create mode 100644 build/codeblocks/ogg.cbp create mode 100644 build/codeblocks/osmozilla.cbp create mode 100644 build/codeblocks/raw_out.cbp create mode 100644 build/codeblocks/rtp_in.cbp create mode 100644 build/codeblocks/saf_in.cbp create mode 100644 build/codeblocks/sdl_out.cbp create mode 100644 build/codeblocks/soft_raster.cbp create mode 100644 build/codeblocks/svg_in.cbp create mode 100644 build/codeblocks/timedtext.cbp create mode 100644 build/codeblocks/ui_rec.cbp create mode 100644 build/codeblocks/wav_out.cbp create mode 100644 build/codeblocks/wiiis.cbp create mode 100644 build/codeblocks/wxOsmo4.cbp create mode 100644 build/codeblocks/xvid_dec.cbp delete mode 100644 build/msevc3/GPAC.VCW delete mode 100644 build/msevc3/Osmo4.vcp delete mode 100644 build/msevc3/aac_in.vcp delete mode 100644 build/msevc3/amr_dec.vcp delete mode 100644 build/msevc3/bifs_dec.vcp delete mode 100644 build/msevc3/ctx_load.vcp delete mode 100644 build/msevc3/dummy_in.vcp delete mode 100644 build/msevc3/ft_font.vcp delete mode 100644 build/msevc3/gapi.vcp delete mode 100644 build/msevc3/img_in.vcp delete mode 100644 build/msevc3/isom_in.vcp delete mode 100644 build/msevc3/laser_dec.vcp delete mode 100644 build/msevc3/libgpac.vcp delete mode 100644 build/msevc3/libgpac_dll.vcp delete mode 100644 build/msevc3/mp3_in.vcp delete mode 100644 build/msevc3/odf_dec.vcp delete mode 100644 build/msevc3/ogg.vcp delete mode 100644 build/msevc3/rtp_in.vcp delete mode 100644 build/msevc3/saf_in.vcp delete mode 100644 build/msevc3/soft_raster.vcp delete mode 100644 build/msevc3/svg_in.vcp delete mode 100644 build/msevc3/timedtext.vcp delete mode 100644 build/msevc3/wav_out.vcp delete mode 100644 build/msevc3/xvid_dec.vcp create mode 100644 build/msevc4/ac3_in.vcp create mode 100644 build/msevc4/gpac_js.vcp delete mode 100644 build/msvc6/GPAX.dsp delete mode 100644 build/msvc6/Osmo4.dsp delete mode 100644 build/msvc6/V4Studio.dsp delete mode 100644 build/msvc6/aac_in.dsp delete mode 100644 build/msvc6/ac3_in.dsp delete mode 100644 build/msvc6/amr_dec.dsp delete mode 100644 build/msvc6/amr_float_dec.dsp delete mode 100644 build/msvc6/bifs_dec.dsp delete mode 100644 build/msvc6/ctx_load.dsp delete mode 100644 build/msvc6/dummy_in.dsp delete mode 100644 build/msvc6/dx_hw.dsp delete mode 100644 build/msvc6/ffmpeg_in.dsp delete mode 100644 build/msvc6/ft_font.dsp delete mode 100644 build/msvc6/gdip_raster.dsp delete mode 100644 build/msvc6/gpac.dsw delete mode 100644 build/msvc6/gpac_js.dsp delete mode 100644 build/msvc6/img_in.dsp delete mode 100644 build/msvc6/ismacryp.dsp delete mode 100644 build/msvc6/isom_in.dsp delete mode 100644 build/msvc6/laser_dec.dsp delete mode 100644 build/msvc6/libgpac.dsp delete mode 100644 build/msvc6/libgpac_dll.dsp delete mode 100644 build/msvc6/mp3_in.dsp delete mode 100644 build/msvc6/mp42avi.dsp delete mode 100644 build/msvc6/mp4box.dsp delete mode 100644 build/msvc6/mp4client.dsp delete mode 100644 build/msvc6/mpegts_in.dsp delete mode 100644 build/msvc6/odf_dec.dsp delete mode 100644 build/msvc6/ogg.dsp delete mode 100644 build/msvc6/osmozilla.dsp delete mode 100644 build/msvc6/raw_out.dsp delete mode 100644 build/msvc6/rtp_in.dsp delete mode 100644 build/msvc6/saf_in.dsp delete mode 100644 build/msvc6/sdl_out.dsp delete mode 100644 build/msvc6/soft_raster.dsp delete mode 100644 build/msvc6/standalone2drender.dsp delete mode 100644 build/msvc6/svg_in.dsp delete mode 100644 build/msvc6/timedtext.dsp delete mode 100644 build/msvc6/wav_out.dsp delete mode 100644 build/msvc6/wxOsmo4.dsp delete mode 100644 build/msvc6/xvid_dec.dsp create mode 100644 build/msvc8/audio_filter.vcproj create mode 100644 build/msvc8/demo_is.vcproj create mode 100644 build/msvc8/gapi.vcproj create mode 100644 build/msvc8/gpac_js.vcproj create mode 100644 build/msvc8/m3u82mpd.vcproj create mode 100644 build/msvc8/m3u8_in.vcproj create mode 100644 build/msvc8/mpd_in.vcproj create mode 100644 build/msvc8/opencv_is.vcproj create mode 100644 build/msvc8/opensvc.vcproj create mode 100644 build/msvc8/osmophone.vcproj create mode 100644 build/msvc8/platinum.vcproj create mode 100644 build/msvc8/redirect_av.vcproj create mode 100644 build/msvc8/ui_rec.vcproj create mode 100644 build/msvc8/validator.vcproj create mode 100644 build/msvc8/widgetman.vcproj create mode 100644 build/msvc8/wiiis.vcproj create mode 100644 build/msvc9/GPAX.vcproj create mode 100644 build/msvc9/Osmo4.vcproj create mode 100644 build/msvc9/V4Studio.vcproj create mode 100644 build/msvc9/aac_in.vcproj create mode 100644 build/msvc9/ac3_in.vcproj create mode 100644 build/msvc9/amr_dec.vcproj create mode 100644 build/msvc9/amr_float_dec.vcproj create mode 100644 build/msvc9/audio_filter.vcproj create mode 100644 build/msvc9/bifs_dec.vcproj create mode 100644 build/msvc9/ctx_load.vcproj create mode 100644 build/msvc9/demo_is.vcproj create mode 100644 build/msvc9/dummy_in.vcproj create mode 100644 build/msvc9/dx_hw.vcproj create mode 100644 build/msvc9/ffmpeg_in.vcproj create mode 100644 build/msvc9/ft_font.vcproj create mode 100644 build/msvc9/gapi.vcproj create mode 100644 build/msvc9/gdip_raster.vcproj create mode 100644 build/msvc9/gpac.sln create mode 100644 build/msvc9/gpac_js.vcproj create mode 100644 build/msvc9/img_in.vcproj create mode 100644 build/msvc9/ismacryp.vcproj create mode 100644 build/msvc9/isom_in.vcproj create mode 100644 build/msvc9/laser_dec.vcproj create mode 100644 build/msvc9/libgpac.vcproj create mode 100644 build/msvc9/libgpac_dll.vcproj create mode 100644 build/msvc9/mp3_in.vcproj create mode 100644 build/msvc9/mp4box.vcproj create mode 100644 build/msvc9/mp4client.vcproj create mode 100644 build/msvc9/mpegts_in.vcproj create mode 100644 build/msvc9/odf_dec.vcproj create mode 100644 build/msvc9/ogg.vcproj create mode 100644 build/msvc9/opencv_is.vcproj create mode 100644 build/msvc9/osmophone.vcproj create mode 100644 build/msvc9/osmozilla.vcproj create mode 100644 build/msvc9/platinum.vcproj create mode 100644 build/msvc9/raw_out.vcproj create mode 100644 build/msvc9/redirect_av.vcproj create mode 100644 build/msvc9/rtp_in.vcproj create mode 100644 build/msvc9/saf_in.vcproj create mode 100644 build/msvc9/sdl_out.vcproj create mode 100644 build/msvc9/soft_raster.vcproj create mode 100644 build/msvc9/svg_in.vcproj create mode 100644 build/msvc9/timedtext.vcproj create mode 100644 build/msvc9/ui_rec.vcproj create mode 100644 build/msvc9/wav_out.vcproj create mode 100644 build/msvc9/widgetman.vcproj create mode 100644 build/msvc9/wiiis.vcproj create mode 100644 build/msvc9/wxOsmo4.vcproj create mode 100644 build/msvc9/xvid_dec.vcproj create mode 100644 build/xcode/gpac.xcodeproj/project.pbxproj delete mode 100644 config.h create mode 100644 doc/GPAC UPnP.doc create mode 100644 doc/osmo4.ico delete mode 100644 extra_lib/include/ffmpeg/avcodec.h delete mode 100644 extra_lib/include/ffmpeg/avformat.h delete mode 100644 extra_lib/include/ffmpeg/avio.h delete mode 100644 extra_lib/include/ffmpeg/avutil.h delete mode 100644 extra_lib/include/ffmpeg/common.h delete mode 100644 extra_lib/include/ffmpeg/integer.h delete mode 100644 extra_lib/include/ffmpeg/intfloat_readwrite.h delete mode 100644 extra_lib/include/ffmpeg/log.h delete mode 100644 extra_lib/include/ffmpeg/mathematics.h delete mode 100644 extra_lib/include/ffmpeg/rational.h create mode 100644 extra_lib/include/libavcodec/avcodec.h create mode 100644 extra_lib/include/libavformat/avformat.h create mode 100644 extra_lib/include/libavformat/avio.h create mode 100644 extra_lib/include/libavutil/avutil.h create mode 100644 extra_lib/include/libavutil/common.h create mode 100644 extra_lib/include/libavutil/intfloat_readwrite.h create mode 100644 extra_lib/include/libavutil/log.h create mode 100644 extra_lib/include/libavutil/mathematics.h create mode 100644 extra_lib/include/libavutil/mem.h create mode 100644 extra_lib/include/libavutil/pixfmt.h create mode 100644 extra_lib/include/libavutil/rational.h create mode 100644 extra_lib/include/libswscale/swscale.h create mode 100644 extra_lib/include/wiiuse.h delete mode 100644 extra_lib/lib/arm_ppc02_rel/dummy delete mode 100644 extra_lib/lib/arm_ppc03_deb/dummy delete mode 100644 extra_lib/lib/arm_ppc03_rel/dummy delete mode 100644 extra_lib/lib/gcc/dummy delete mode 100644 extra_lib/lib/w32_deb/dummy delete mode 100644 extra_lib/lib/w32_rel/dummy create mode 100644 gui/gui.bt create mode 100644 gui/gui.js create mode 100644 gui/icons/applications-internet.svg create mode 100644 gui/icons/applications-multimedia.svg create mode 100644 gui/icons/applications-system.svg create mode 100644 gui/icons/audio-volume-high.svg create mode 100644 gui/icons/audio-volume-low.svg create mode 100644 gui/icons/audio-volume-medium.svg create mode 100644 gui/icons/audio-volume-muted.svg create mode 100644 gui/icons/audio-x-generic.svg create mode 100644 gui/icons/battery-caution.svg create mode 100644 gui/icons/camera-photo.svg create mode 100644 gui/icons/camera-video.svg create mode 100644 gui/icons/dialog-error.svg create mode 100644 gui/icons/dialog-information.svg create mode 100644 gui/icons/dialog-warning.svg create mode 100644 gui/icons/document-new.svg create mode 100644 gui/icons/document-print-preview.svg create mode 100644 gui/icons/document-print.svg create mode 100644 gui/icons/document-save-as.svg create mode 100644 gui/icons/document-save.svg create mode 100644 gui/icons/emblem-unreadable.svg create mode 100644 gui/icons/face-surprise.svg create mode 100644 gui/icons/folder.svg create mode 100644 gui/icons/go-bottom.svg create mode 100644 gui/icons/go-down.svg create mode 100644 gui/icons/go-first.svg create mode 100644 gui/icons/go-home.svg create mode 100644 gui/icons/go-jump.svg create mode 100644 gui/icons/go-last.svg create mode 100644 gui/icons/go-next.svg create mode 100644 gui/icons/go-previous.svg create mode 100644 gui/icons/go-top.svg create mode 100644 gui/icons/go-up.svg create mode 100644 gui/icons/image-missing.svg create mode 100644 gui/icons/left_arrow.svg create mode 100644 gui/icons/list-add.svg create mode 100644 gui/icons/list-remove.svg create mode 100644 gui/icons/media-eject.svg create mode 100644 gui/icons/media-playback-pause.svg create mode 100644 gui/icons/media-playback-start.svg create mode 100644 gui/icons/media-playback-stop.svg create mode 100644 gui/icons/media-record.svg create mode 100644 gui/icons/media-seek-backward.svg create mode 100644 gui/icons/media-seek-forward.svg create mode 100644 gui/icons/media-skip-backward.svg create mode 100644 gui/icons/media-skip-forward.svg create mode 100644 gui/icons/process-stop.svg create mode 100644 gui/icons/right_arrow.svg create mode 100644 gui/icons/tennis_ball.svg create mode 100644 gui/icons/tennis_black.svg create mode 100644 gui/icons/tennis_racket.svg create mode 100644 gui/icons/tennis_racket_color.svg create mode 100644 gui/icons/user-trash.svg create mode 100644 gui/icons/video-display.svg create mode 100644 gui/icons/video-x-generic.svg create mode 100644 gui/icons/view-fullscreen.svg create mode 100644 gui/iphone_wm_gui.js create mode 100644 gui/iphone_wm_gui.svg create mode 100644 gui/mpegu-core.js create mode 100644 gui/mpegu-wm.bt create mode 100644 gui/mpegu-wm.js create mode 100644 gui/mpegu-wm.xmt create mode 100644 gui/tv_wm_gui.js create mode 100644 gui/tv_wm_gui.svg delete mode 100644 include/gpac/bifsengine.h create mode 100644 include/gpac/configuration.h create mode 100644 include/gpac/dvb_mpe.h create mode 100644 include/gpac/filestreamer.h delete mode 100644 include/gpac/internal/config_static.h create mode 100644 include/gpac/internal/dvb_mpe_dev.h create mode 100644 include/gpac/internal/reedsolomon.h create mode 100644 include/gpac/rtp_streamer.h create mode 100644 include/gpac/scene_engine.h delete mode 100644 modules/aac_in/aac_in.def delete mode 100644 modules/ac3_in/ac3_in.def delete mode 100644 modules/amr_dec/amr_dec.def delete mode 100644 modules/amr_float_dec/amr_float_dec.def delete mode 100644 modules/amr_float_dec/amr_nb_ft/dummy delete mode 100644 modules/amr_float_dec/amr_wb_ft/dummy create mode 100644 modules/audio_filter/Makefile create mode 100644 modules/audio_filter/audio_filter.c delete mode 100644 modules/bifs_dec/bifs_dec.def delete mode 100644 modules/ctx_load/ctx_load.def create mode 100644 modules/demo_is/Makefile create mode 100644 modules/demo_is/demo-sensor.bt create mode 100644 modules/demo_is/demo_is.c create mode 100644 modules/directfb_out/Makefile create mode 100755 modules/directfb_out/directfb_out.c create mode 100755 modules/directfb_out/directfb_out.h delete mode 100644 modules/dummy_in/dummy_in.def delete mode 100644 modules/dx_hw/dx_hw.def delete mode 100644 modules/ffmpeg_in/ffmpeg_in.def delete mode 100644 modules/ft_font/ft_font.def delete mode 100644 modules/gapi/gapi.def delete mode 100644 modules/gdip_raster/gdip_rend.def delete mode 100644 modules/gpac_js/gpac_js.def delete mode 100644 modules/img_in/img_in.def delete mode 100644 modules/ismacryp/ismacryp.def delete mode 100644 modules/isom_in/isom_in.def delete mode 100644 modules/laser_dec/laser_dec.def create mode 100644 modules/m3u8_in/Makefile create mode 100644 modules/m3u8_in/m3u8_in.c create mode 100644 modules/m3u8_in/m3u8_in.h create mode 100644 modules/m3u8_in/m3u8_in_load.c create mode 100644 modules/m3u8_in/m3u8_parser.c create mode 100644 modules/m3u8_in/m3u8_parser.h create mode 100644 modules/m3u8_in/playlist.c create mode 100644 modules/m3u8_in/playlist.h create mode 100644 modules/m3u8_in/test.c create mode 100644 modules/m3u8_in/tests/direct8.m3u8 create mode 100644 modules/m3u8_in/tests/relative_playlist.m3u8 create mode 100644 modules/m3u8_in/tests/spec_encrypted_media.m3u8 create mode 100644 modules/m3u8_in/tests/spec_multiple_files.m3u8 create mode 100644 modules/m3u8_in/tests/spec_simple_playlist.m3u8 create mode 100644 modules/m3u8_in/tests/spec_sliding_window_playlist.m3u8 create mode 100644 modules/m3u8_in/tests/spec_variant_playlist.m3u8 create mode 100644 modules/modules_export.cpp delete mode 100644 modules/mp3_in/mp3_in.def delete mode 100644 modules/mpegts_in/mpegts_in.def delete mode 100644 modules/odf_dec/odf_dec.def delete mode 100644 modules/ogg/ogg.def create mode 100644 modules/opencv_is/Makefile create mode 100644 modules/opencv_is/demo-sensor.bt create mode 100644 modules/opencv_is/haarcascade_frontalface_default.xml create mode 100644 modules/opencv_is/opencv_is.c create mode 100644 modules/opensvc_dec/Makefile create mode 100644 modules/opensvc_dec/opensvc_dec.c create mode 100644 modules/platinum/GPACFileMediaServer.cpp create mode 100644 modules/platinum/GPACFileMediaServer.h create mode 100644 modules/platinum/GPACMediaController.cpp create mode 100644 modules/platinum/GPACMediaController.h create mode 100644 modules/platinum/GPACMediaRenderer.cpp create mode 100644 modules/platinum/GPACMediaRenderer.h create mode 100644 modules/platinum/GPACPlatinum.cpp create mode 100644 modules/platinum/GPACPlatinum.h create mode 100644 modules/platinum/GenericDevice.cpp create mode 100644 modules/platinum/GenericDevice.h create mode 100644 modules/platinum/Makefile create mode 100644 modules/platinum/SDK/ReadMe.txt create mode 100644 modules/platinum/SDK/include/Neptune.h create mode 100644 modules/platinum/SDK/include/NptArray.h create mode 100644 modules/platinum/SDK/include/NptBase64.h create mode 100644 modules/platinum/SDK/include/NptBufferedStreams.h create mode 100644 modules/platinum/SDK/include/NptCommon.h create mode 100644 modules/platinum/SDK/include/NptConfig.h create mode 100644 modules/platinum/SDK/include/NptConsole.h create mode 100644 modules/platinum/SDK/include/NptConstants.h create mode 100644 modules/platinum/SDK/include/NptDataBuffer.h create mode 100644 modules/platinum/SDK/include/NptDebug.h rename extra_lib/lib/arm_ppc02_deb/dummy => modules/platinum/SDK/include/NptDefs.h (100%) create mode 100644 modules/platinum/SDK/include/NptDynamicCast.h create mode 100644 modules/platinum/SDK/include/NptDynamicLibraries.h create mode 100644 modules/platinum/SDK/include/NptFile.h create mode 100644 modules/platinum/SDK/include/NptHttp.h create mode 100644 modules/platinum/SDK/include/NptInterfaces.h create mode 100644 modules/platinum/SDK/include/NptList.h create mode 100644 modules/platinum/SDK/include/NptLogging.h create mode 100644 modules/platinum/SDK/include/NptMap.h create mode 100644 modules/platinum/SDK/include/NptMessaging.h create mode 100644 modules/platinum/SDK/include/NptNetwork.h create mode 100644 modules/platinum/SDK/include/NptQueue.h create mode 100644 modules/platinum/SDK/include/NptReferences.h create mode 100644 modules/platinum/SDK/include/NptResults.h create mode 100644 modules/platinum/SDK/include/NptRingBuffer.h create mode 100644 modules/platinum/SDK/include/NptSelectableMessageQueue.h create mode 100644 modules/platinum/SDK/include/NptSerialPort.h create mode 100644 modules/platinum/SDK/include/NptSimpleMessageQueue.h create mode 100644 modules/platinum/SDK/include/NptSockets.h create mode 100644 modules/platinum/SDK/include/NptStack.h create mode 100644 modules/platinum/SDK/include/NptStreams.h create mode 100644 modules/platinum/SDK/include/NptStrings.h create mode 100644 modules/platinum/SDK/include/NptSystem.h create mode 100644 modules/platinum/SDK/include/NptThreads.h create mode 100644 modules/platinum/SDK/include/NptTime.h create mode 100644 modules/platinum/SDK/include/NptTls.h create mode 100644 modules/platinum/SDK/include/NptTypes.h create mode 100644 modules/platinum/SDK/include/NptUri.h create mode 100644 modules/platinum/SDK/include/NptUtils.h create mode 100644 modules/platinum/SDK/include/NptVersion.h create mode 100644 modules/platinum/SDK/include/NptXml.h create mode 100644 modules/platinum/SDK/include/NptZip.h create mode 100644 modules/platinum/SDK/include/Platinum.h create mode 100644 modules/platinum/SDK/include/PltAction.h create mode 100644 modules/platinum/SDK/include/PltArgument.h create mode 100644 modules/platinum/SDK/include/PltConstants.h create mode 100644 modules/platinum/SDK/include/PltCtrlPoint.h create mode 100644 modules/platinum/SDK/include/PltCtrlPointTask.h create mode 100644 modules/platinum/SDK/include/PltDatagramStream.h create mode 100644 modules/platinum/SDK/include/PltDeviceData.h create mode 100644 modules/platinum/SDK/include/PltDeviceHost.h create mode 100644 modules/platinum/SDK/include/PltDidl.h create mode 100644 modules/platinum/SDK/include/PltDownloader.h create mode 100644 modules/platinum/SDK/include/PltEvent.h create mode 100644 modules/platinum/SDK/include/PltFileMediaServer.h create mode 100644 modules/platinum/SDK/include/PltHttp.h create mode 100644 modules/platinum/SDK/include/PltHttpClientTask.h create mode 100644 modules/platinum/SDK/include/PltHttpServer.h create mode 100644 modules/platinum/SDK/include/PltHttpServerListener.h create mode 100644 modules/platinum/SDK/include/PltHttpServerTask.h create mode 100644 modules/platinum/SDK/include/PltLeaks.h create mode 100644 modules/platinum/SDK/include/PltMediaBrowser.h create mode 100644 modules/platinum/SDK/include/PltMediaBrowserListener.h create mode 100644 modules/platinum/SDK/include/PltMediaCache.h create mode 100644 modules/platinum/SDK/include/PltMediaConnect.h create mode 100644 modules/platinum/SDK/include/PltMediaController.h create mode 100644 modules/platinum/SDK/include/PltMediaControllerListener.h create mode 100644 modules/platinum/SDK/include/PltMediaItem.h create mode 100644 modules/platinum/SDK/include/PltMediaPlaylist.h create mode 100644 modules/platinum/SDK/include/PltMediaRenderer.h create mode 100644 modules/platinum/SDK/include/PltMediaServer.h create mode 100644 modules/platinum/SDK/include/PltMetadataHandler.h create mode 100644 modules/platinum/SDK/include/PltRingBufferStream.h create mode 100644 modules/platinum/SDK/include/PltService.h create mode 100644 modules/platinum/SDK/include/PltSsdp.h create mode 100644 modules/platinum/SDK/include/PltSsdpListener.h create mode 100644 modules/platinum/SDK/include/PltStateVariable.h create mode 100644 modules/platinum/SDK/include/PltStreamPump.h create mode 100644 modules/platinum/SDK/include/PltSvnVersion.h create mode 100644 modules/platinum/SDK/include/PltSyncMediaBrowser.h create mode 100644 modules/platinum/SDK/include/PltTaskManager.h create mode 100644 modules/platinum/SDK/include/PltThreadTask.h create mode 100644 modules/platinum/SDK/include/PltTime.h create mode 100644 modules/platinum/SDK/include/PltUPnP.h create mode 100644 modules/platinum/SDK/include/PltUPnPHelper.h create mode 100644 modules/platinum/SDK/include/PltVersion.h create mode 100644 modules/platinum/SDK/include/PltXmlHelper.h delete mode 100644 modules/raw_out/raw_out.def create mode 100644 modules/redirect_av/Makefile create mode 100644 modules/redirect_av/redirect_av.c delete mode 100644 modules/rtp_in/rtp_in.def delete mode 100644 modules/saf_in/saf_in.def delete mode 100644 modules/sdl_out/sdl_out.def delete mode 100644 modules/soft_raster/rast_soft.def delete mode 100644 modules/svg_in/svg_in.def delete mode 100644 modules/timedtext/timedtext.def create mode 100644 modules/ui_rec/Makefile create mode 100644 modules/ui_rec/readme.txt create mode 100644 modules/ui_rec/ui_rec.c delete mode 100644 modules/wav_out/wav_out.def create mode 100644 modules/widgetman/Makefile create mode 100644 modules/widgetman/unzip.c create mode 100644 modules/widgetman/unzip.h create mode 100644 modules/widgetman/wgt_load.c create mode 100644 modules/widgetman/wgt_load_base.js create mode 100644 modules/widgetman/widget.c create mode 100644 modules/widgetman/widgetman.c create mode 100644 modules/widgetman/widgetman.h create mode 100644 modules/wiiis/Makefile create mode 100644 modules/wiiis/test_wii.bt create mode 100644 modules/wiiis/wiiis.c delete mode 100644 modules/xvid_dec/xvid_dec.def delete mode 100644 regression_tests/bifs-2D-background-background2D-bind.bt delete mode 100644 regression_tests/bifs-2D-background-background2D-image.bt delete mode 100644 regression_tests/bifs-2D-background-background2D-layer2D.bt delete mode 100644 regression_tests/bifs-2D-background-background2D-movie.bt delete mode 100644 regression_tests/bifs-2D-background-background2D-url-change.bt delete mode 100644 regression_tests/bifs-2D-interactivity-discsensor.bt delete mode 100644 regression_tests/bifs-2D-interactivity-htk-sensor.bt delete mode 100644 regression_tests/bifs-2D-interactivity-keysensor.bt delete mode 100644 regression_tests/bifs-2D-interactivity-mousesensor.bt delete mode 100644 regression_tests/bifs-2D-interactivity-nested-sensors.bt delete mode 100644 regression_tests/bifs-2D-interactivity-planesensor2D.bt delete mode 100644 regression_tests/bifs-2D-interactivity-proximitysensor2D.bt delete mode 100644 regression_tests/bifs-2D-interactivity-stringsensor.bt delete mode 100644 regression_tests/bifs-2D-interactivity-touchsensor-4states.bt delete mode 100644 regression_tests/bifs-2D-interactivity-touchsensor-hitpoint.bt delete mode 100644 regression_tests/bifs-2D-interactivity-touchsensor-isactive-exposedfield.bt delete mode 100644 regression_tests/bifs-2D-interactivity-touchsensor-isactive.bt delete mode 100644 regression_tests/bifs-2D-interactivity-touchsensor-isover.bt delete mode 100644 regression_tests/bifs-2D-interactivity-touchsensor-move_over.bt delete mode 100644 regression_tests/bifs-2D-painting-colortransform-alpha.bt delete mode 100644 regression_tests/bifs-2D-painting-colortransform-bitmap.bt delete mode 100644 regression_tests/bifs-2D-painting-colortransform-color.bt delete mode 100644 regression_tests/bifs-2D-painting-lineproperties.bt delete mode 100644 regression_tests/bifs-2D-painting-material2D.bt delete mode 100644 regression_tests/bifs-2D-painting-xlineproperties-cap.bt delete mode 100644 regression_tests/bifs-2D-painting-xlineproperties-compositetexture2D.bt delete mode 100644 regression_tests/bifs-2D-painting-xlineproperties-dash.bt delete mode 100644 regression_tests/bifs-2D-painting-xlineproperties-imagetexture.bt delete mode 100644 regression_tests/bifs-2D-painting-xlineproperties-join.bt delete mode 100644 regression_tests/bifs-2D-painting-xlineproperties-lineargradient.bt delete mode 100644 regression_tests/bifs-2D-painting-xlineproperties-radialgradient.bt delete mode 100644 regression_tests/bifs-2D-painting-xlineproperties-scalable.bt delete mode 100644 regression_tests/bifs-2D-painting-xlineproperties-transparent.bt delete mode 100644 regression_tests/bifs-2D-positioning-clipper2D.bt delete mode 100644 regression_tests/bifs-2D-positioning-form-align-center.bt delete mode 100644 regression_tests/bifs-2D-positioning-form-align-horiz.bt delete mode 100644 regression_tests/bifs-2D-positioning-form-align-vert.bt delete mode 100644 regression_tests/bifs-2D-positioning-form-spread-horiz.bt delete mode 100644 regression_tests/bifs-2D-positioning-form-spread-vert.bt delete mode 100644 regression_tests/bifs-2D-positioning-layer2D.bt delete mode 100644 regression_tests/bifs-2D-positioning-layer2d-in-layer2d.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-horiz-ltr-nowrap.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-horiz-ltr-wrap-btt.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-horiz-ltr-wrap-ttb.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-horiz-rtl-nowrap.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-horiz-rtl-wrap-btt.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-horiz-rtl-wrap-ttb.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-horiz-text.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-scroll-child.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-scroll-full.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-scroll-modes-horiz.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-scroll-modes-vert.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-scroll-on-off.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-vert-btt-nowrap.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-vert-btt-wrap-ltr.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-vert-btt-wrap-rtl.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-vert-ttb-nowrap.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-vert-ttb-wrap-ltr.bt delete mode 100644 regression_tests/bifs-2D-positioning-layout-vert-ttb-wrap-rtl.bt delete mode 100644 regression_tests/bifs-2D-positioning-orderedgroup.bt delete mode 100644 regression_tests/bifs-2D-positioning-pathlayout.bt delete mode 100644 regression_tests/bifs-2D-positioning-transform2D.bt delete mode 100644 regression_tests/bifs-2D-positioning-transformmatrix2D.bt delete mode 100644 regression_tests/bifs-2D-shapes-all.bt delete mode 100644 regression_tests/bifs-2D-shapes-indexfaceset2D.bt delete mode 100644 regression_tests/bifs-2D-shapes-indexlineset2D.bt delete mode 100644 regression_tests/bifs-2D-shapes-pointset2D.bt delete mode 100644 regression_tests/bifs-2D-shapes-xcurve2D.bt delete mode 100644 regression_tests/bifs-2D-texturing-compositetexture2D-background.bt delete mode 100644 regression_tests/bifs-2D-texturing-compositetexture2D-bitmap.bt delete mode 100644 regression_tests/bifs-2D-texturing-compositetexture2D-transparent.bt delete mode 100644 regression_tests/bifs-2D-texturing-gradients-text.bt delete mode 100644 regression_tests/bifs-2D-texturing-gradients-transparent.bt delete mode 100644 regression_tests/bifs-2D-texturing-imagetexture-shapes.bt delete mode 100644 regression_tests/bifs-2D-texturing-lineargradient-simple.bt delete mode 100644 regression_tests/bifs-2D-texturing-lineargradient-spread.bt delete mode 100644 regression_tests/bifs-2D-texturing-movietexture-shapes.bt delete mode 100644 regression_tests/bifs-2D-texturing-pixeltexture.bt delete mode 100644 regression_tests/bifs-2D-texturing-radialgradient-simple.bt delete mode 100644 regression_tests/bifs-2D-texturing-radialgradient-spread.bt delete mode 100644 regression_tests/bifs-2D-texturing-texturetransform-base.bt delete mode 100644 regression_tests/bifs-2D-texturing-texturetransform-interact.bt delete mode 100644 regression_tests/bifs-2D-texturing-texturetransform-transformmatrix2D.bt delete mode 100644 regression_tests/bifs-2D-viewport-complete.bt delete mode 100644 regression_tests/bifs-2D-viewport-simple.bt delete mode 100644 regression_tests/bifs-3D-background-images.bt delete mode 100644 regression_tests/bifs-3D-background.bt delete mode 100644 regression_tests/bifs-3D-interactivity-collision-proxy.bt delete mode 100644 regression_tests/bifs-3D-interactivity-collision.bt delete mode 100644 regression_tests/bifs-3D-interactivity-cylindersensor.bt delete mode 100644 regression_tests/bifs-3D-interactivity-planesensor.bt delete mode 100644 regression_tests/bifs-3D-interactivity-proximitysensor.bt delete mode 100644 regression_tests/bifs-3D-interactivity-spheresensor.bt delete mode 100644 regression_tests/bifs-3D-interactivity-visibilitysensor.bt delete mode 100644 regression_tests/bifs-3D-lighting-directionalLight.bt delete mode 100644 regression_tests/bifs-3D-lighting-fog.bt delete mode 100644 regression_tests/bifs-3D-lighting-pointlight.bt delete mode 100644 regression_tests/bifs-3D-lighting-spotlight.bt delete mode 100644 regression_tests/bifs-3D-positioning-billboard-viewer-alignment.bt delete mode 100644 regression_tests/bifs-3D-positioning-billboard.bt delete mode 100644 regression_tests/bifs-3D-positioning-gravity.bt delete mode 100644 regression_tests/bifs-3D-positioning-layer3D-views.bt delete mode 100644 regression_tests/bifs-3D-positioning-layer3D.bt delete mode 100644 regression_tests/bifs-3D-positioning-lod.bt delete mode 100644 regression_tests/bifs-3D-positioning-transform.bt delete mode 100644 regression_tests/bifs-3D-shapes-box-transparent.bt delete mode 100644 regression_tests/bifs-3D-shapes-box.bt delete mode 100644 regression_tests/bifs-3D-shapes-cone.bt delete mode 100644 regression_tests/bifs-3D-shapes-cylinder.bt delete mode 100644 regression_tests/bifs-3D-shapes-elevationgrid.bt delete mode 100644 regression_tests/bifs-3D-shapes-extrusion.bt delete mode 100644 regression_tests/bifs-3D-shapes-indexedfaceset.bt delete mode 100644 regression_tests/bifs-3D-shapes-indexedlineset.bt delete mode 100644 regression_tests/bifs-3D-shapes-nonlineardeformer.bt delete mode 100644 regression_tests/bifs-3D-shapes-pointset.bt delete mode 100644 regression_tests/bifs-3D-texturing-box-transparent.bt delete mode 100644 regression_tests/bifs-3D-texturing-box-video.bt delete mode 100644 regression_tests/bifs-3D-texturing-box.bt delete mode 100644 regression_tests/bifs-3D-texturing-compositetexture3D-bitmap.bt delete mode 100644 regression_tests/bifs-3D-texturing-compositetexture3D-box.bt delete mode 100644 regression_tests/bifs-3D-texturing-cone-transparent.bt delete mode 100644 regression_tests/bifs-3D-texturing-cone.bt delete mode 100644 regression_tests/bifs-3D-texturing-cylinder-transparent.bt delete mode 100644 regression_tests/bifs-3D-texturing-cylinder.bt delete mode 100644 regression_tests/bifs-3D-texturing-transform-box.bt delete mode 100644 regression_tests/bifs-3D-texturing-transform-matrix-box.bt delete mode 100644 regression_tests/bifs-3D-viewpoint-anim.bt delete mode 100644 regression_tests/bifs-3D-viewpoint-bind-jump.bt delete mode 100644 regression_tests/bifs-3D-viewpoint-bind.bt delete mode 100644 regression_tests/bifs-3D-viewpoint-ortho-bind.bt delete mode 100644 regression_tests/bifs-bitmap-image-meter-metrics.bt delete mode 100644 regression_tests/bifs-bitmap-image-pixel-metrics.bt delete mode 100644 regression_tests/bifs-bitmap-image-resizing.bt delete mode 100644 regression_tests/bifs-bitmap-movie-materialkey.bt delete mode 100644 regression_tests/bifs-bitmap-movie.bt delete mode 100644 regression_tests/bifs-bitmap-video-resizing.bt delete mode 100644 regression_tests/bifs-command-animated-osmo4logo.bt delete mode 100644 regression_tests/bifs-command-delete-index.bt delete mode 100644 regression_tests/bifs-command-delete-node.bt delete mode 100644 regression_tests/bifs-command-delete-route.bt delete mode 100644 regression_tests/bifs-command-global-qp.bt delete mode 100644 regression_tests/bifs-command-insert-index.bt delete mode 100644 regression_tests/bifs-command-insert-node.bt delete mode 100644 regression_tests/bifs-command-insert-nodedef.bt delete mode 100644 regression_tests/bifs-command-insert-route.bt delete mode 100644 regression_tests/bifs-command-multiple-replace-field.bt delete mode 100644 regression_tests/bifs-command-multiple-replace-index.bt delete mode 100644 regression_tests/bifs-command-node-delete-ex.bt delete mode 100644 regression_tests/bifs-command-proto-delete.bt delete mode 100644 regression_tests/bifs-command-proto-insert.bt delete mode 100644 regression_tests/bifs-command-protolist-delete.bt delete mode 100644 regression_tests/bifs-command-quantification.bt delete mode 100644 regression_tests/bifs-command-replace-field.bt delete mode 100644 regression_tests/bifs-command-replace-index.bt delete mode 100644 regression_tests/bifs-command-replace-node-null.bt delete mode 100644 regression_tests/bifs-command-replace-node.bt delete mode 100644 regression_tests/bifs-command-replace-route.bt delete mode 100644 regression_tests/bifs-command-replace-scene-null.bt delete mode 100644 regression_tests/bifs-command-replace-scene.bt delete mode 100644 regression_tests/bifs-command-route-add-children.bt delete mode 100644 regression_tests/bifs-command-route-children.bt delete mode 100644 regression_tests/bifs-command-route-node-exposedfield.bt delete mode 100644 regression_tests/bifs-command-route-node.bt delete mode 100644 regression_tests/bifs-command-route-remove-children.bt delete mode 100644 regression_tests/bifs-externproto-forestgump-lib.bt delete mode 100644 regression_tests/bifs-externproto-forestgump.bt delete mode 100644 regression_tests/bifs-externproto-mfurl-lib.bt delete mode 100644 regression_tests/bifs-externproto-mfurl.bt delete mode 100644 regression_tests/bifs-externproto-nood-lib.bt delete mode 100644 regression_tests/bifs-externproto-nood.bt delete mode 100644 regression_tests/bifs-externproto-simple-lib.bt delete mode 100644 regression_tests/bifs-externproto-simple.bt delete mode 100644 regression_tests/bifs-game-arrange.bt delete mode 100644 regression_tests/bifs-game-breakout.bt delete mode 100644 regression_tests/bifs-game-bubble.bt delete mode 100644 regression_tests/bifs-game-minesweeper.bt delete mode 100644 regression_tests/bifs-game-othello.bt delete mode 100644 regression_tests/bifs-interpolation-colorinterpolator.bt delete mode 100644 regression_tests/bifs-interpolation-coordinateinterpolator2D.bt delete mode 100644 regression_tests/bifs-interpolation-positionanimator.bt delete mode 100644 regression_tests/bifs-interpolation-positionanimator2D.bt delete mode 100644 regression_tests/bifs-interpolation-positioninterpolator-position.bt delete mode 100644 regression_tests/bifs-interpolation-positioninterpolator-size.bt delete mode 100644 regression_tests/bifs-interpolation-positioninterpolator2D-position.bt delete mode 100644 regression_tests/bifs-interpolation-positioninterpolator2D-size.bt delete mode 100644 regression_tests/bifs-interpolation-scalaranimator.bt delete mode 100644 regression_tests/bifs-interpolation-scalarinterpolator.bt delete mode 100644 regression_tests/bifs-interpolation-timesensor-enabled.bt delete mode 100644 regression_tests/bifs-interpolation-timesensor-starttime_norestart.bt delete mode 100644 regression_tests/bifs-interpolation-timesensor-starttime_restart.bt delete mode 100644 regression_tests/bifs-interpolation-valuator-sftime.bt delete mode 100644 regression_tests/bifs-linking-anchor-mp4-next.bt delete mode 100644 regression_tests/bifs-linking-anchor-mp4-prev.bt delete mode 100644 regression_tests/bifs-linking-anchor-viewpoint.bt delete mode 100644 regression_tests/bifs-linking-anchor-www.bt delete mode 100644 regression_tests/bifs-linking-animationstream.bt delete mode 100644 regression_tests/bifs-linking-inline-direct-inline.bt delete mode 100644 regression_tests/bifs-linking-inline-direct.bt delete mode 100644 regression_tests/bifs-linking-inline-od-inline.bt delete mode 100644 regression_tests/bifs-linking-inline-od.bt delete mode 100644 regression_tests/bifs-linking-inline-rtsp-no-od.bt delete mode 100644 regression_tests/bifs-linking-inline-rtsp.bt delete mode 100644 regression_tests/bifs-linking-inline-segment-inline.bt delete mode 100644 regression_tests/bifs-linking-inline-segment.bt delete mode 100644 regression_tests/bifs-media-audiobuffer.bt delete mode 100644 regression_tests/bifs-media-audioclip-urlchanged.bt delete mode 100644 regression_tests/bifs-media-audioclip.bt delete mode 100644 regression_tests/bifs-media-audiosource-mixing.bt delete mode 100644 regression_tests/bifs-media-audiosource-urlchanged.bt delete mode 100644 regression_tests/bifs-media-audiosource.bt delete mode 100644 regression_tests/bifs-media-imagetexture-OD-reuse.bt delete mode 100644 regression_tests/bifs-media-imagetexture-no-od.bt delete mode 100644 regression_tests/bifs-media-imagetexture-object-scale.bt delete mode 100644 regression_tests/bifs-media-imagetexture-transparent.bt delete mode 100644 regression_tests/bifs-media-imagetexture-url-change.bt delete mode 100644 regression_tests/bifs-media-movietexture-control.bt delete mode 100644 regression_tests/bifs-media-movietexture-no-od.bt delete mode 100644 regression_tests/bifs-media-movietexture-od-joinsession.bt delete mode 100644 regression_tests/bifs-media-movietexture-od-leave-session.bt delete mode 100644 regression_tests/bifs-media-movietexture-owns-OCR.bt delete mode 100644 regression_tests/bifs-media-movietexture-shares-OCR.bt delete mode 100644 regression_tests/bifs-media-movietexture-url-change.bt delete mode 100644 regression_tests/bifs-media-sound-spatialize.bt delete mode 100644 regression_tests/bifs-media-sound.bt delete mode 100644 regression_tests/bifs-misc-UTF16-input.bt delete mode 100644 regression_tests/bifs-misc-cyclic-graph.bt delete mode 100644 regression_tests/bifs-misc-hc-proto-pathextrusion.bt delete mode 100644 regression_tests/bifs-misc-hc-proto-planarextrusion.bt delete mode 100644 regression_tests/bifs-misc-hc-proto-planeclipper.bt delete mode 100644 regression_tests/bifs-misc-non-linear-parsing-conditional.bt delete mode 100644 regression_tests/bifs-misc-non-linear-parsing-use.bt delete mode 100644 regression_tests/bifs-misc-srt-import-3gpp-control-share-ocr.bt delete mode 100644 regression_tests/bifs-misc-srt-import-3gpp-control.bt delete mode 100644 regression_tests/bifs-misc-srt-import-3gpp.bt delete mode 100644 regression_tests/bifs-misc-srt-import.bt delete mode 100644 regression_tests/bifs-od-remove-esd.bt delete mode 100644 regression_tests/bifs-od-remove-od.bt delete mode 100644 regression_tests/bifs-od-update-od.bt delete mode 100644 regression_tests/bifs-proto-conditional.bt delete mode 100644 regression_tests/bifs-proto-delete-def.bt delete mode 100644 regression_tests/bifs-proto-delete-index.bt delete mode 100644 regression_tests/bifs-proto-forestgump.bt delete mode 100644 regression_tests/bifs-proto-mfurl.bt delete mode 100644 regression_tests/bifs-proto-multiple.bt delete mode 100644 regression_tests/bifs-proto-nested.bt delete mode 100644 regression_tests/bifs-proto-route.bt delete mode 100644 regression_tests/bifs-proto-sftime-protocode.bt delete mode 100644 regression_tests/bifs-proto-sftime-protointerface.bt delete mode 100644 regression_tests/bifs-proto-simple.bt delete mode 100644 regression_tests/bifs-proto-use.bt delete mode 100644 regression_tests/bifs-script-char-to-int.bt delete mode 100644 regression_tests/bifs-script-child-create.bt delete mode 100644 regression_tests/bifs-script-date.bt delete mode 100644 regression_tests/bifs-script-event-out.bt delete mode 100644 regression_tests/bifs-script-initialize.bt delete mode 100644 regression_tests/bifs-script-load-url.bt delete mode 100644 regression_tests/bifs-script-node-access.bt delete mode 100644 regression_tests/bifs-script-node-create.bt delete mode 100644 regression_tests/bifs-script-proto.bt delete mode 100644 regression_tests/bifs-script-timestamp.bt delete mode 100644 regression_tests/bifs-stream-text-switch.bt delete mode 100644 regression_tests/bifs-text-align-horiz1.bt delete mode 100644 regression_tests/bifs-text-align-horiz2.bt delete mode 100644 regression_tests/bifs-text-align-horiz3.bt delete mode 100644 regression_tests/bifs-text-align-horiz4.bt delete mode 100644 regression_tests/bifs-text-align-vert1.bt delete mode 100644 regression_tests/bifs-text-align-vert2.bt delete mode 100644 regression_tests/bifs-text-align-vert3.bt delete mode 100644 regression_tests/bifs-text-align-vert4.bt delete mode 100644 regression_tests/bifs-text-glyph-advance.bt delete mode 100644 regression_tests/bifs-text-length.bt delete mode 100644 regression_tests/bifs-text-maxextend.bt delete mode 100644 regression_tests/bifs-text-style.bt delete mode 100644 regression_tests/bifs-text-unicode.bt delete mode 100644 regression_tests/bifs-text-vrml-alignment.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-OCR.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-audio-speed.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-audio.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-complete.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-deactivation.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-inline-av.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-inline-segments.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-inline.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-rtsp.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-seg-inline.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-segments.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-video.bt delete mode 100644 regression_tests/bifs-timeline-mediacontrol-videospeed.bt delete mode 100644 regression_tests/bifs-timeline-mediasensor-segment-switch.bt delete mode 100644 regression_tests/bifs-timeline-mediasensor-segment.bt delete mode 100644 regression_tests/bifs-timeline-mediasensor.bt create mode 100644 regression_tests/bifs/bifs-2D-background-background2D-bind.bt create mode 100644 regression_tests/bifs/bifs-2D-background-background2D-image.bt create mode 100644 regression_tests/bifs/bifs-2D-background-background2D-layer2D.bt create mode 100644 regression_tests/bifs/bifs-2D-background-background2D-movie.bt create mode 100644 regression_tests/bifs/bifs-2D-background-background2D-url-change.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-discsensor.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-htk-sensor.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-keysensor.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-mousesensor.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-nested-sensors.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-planesensor2D.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-proximitysensor2D.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-stringsensor.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-touchsensor-4states.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-touchsensor-hitpoint.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-touchsensor-isactive-exposedfield.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-touchsensor-isactive.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-touchsensor-isover.bt create mode 100644 regression_tests/bifs/bifs-2D-interactivity-touchsensor-move_over.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-colortransform-alpha.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-colortransform-bitmap.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-colortransform-color.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-lineproperties.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-material2D.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-xlineproperties-cap.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-xlineproperties-compositetexture2D.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-xlineproperties-dash.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-xlineproperties-imagetexture.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-xlineproperties-join.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-xlineproperties-lineargradient.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-xlineproperties-radialgradient.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-xlineproperties-scalable.bt create mode 100644 regression_tests/bifs/bifs-2D-painting-xlineproperties-transparent.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-clipper2D.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-form-align-center.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-form-align-horiz.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-form-align-vert.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-form-spread-horiz.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-form-spread-vert.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layer2D.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layer2d-in-layer2d.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-nowrap.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-btt.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-ttb.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-nowrap.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-btt.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-ttb.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-horiz-text.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-scroll-child.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-scroll-full.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-scroll-modes-horiz.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-scroll-modes-vert.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-scroll-on-off.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-nowrap.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-wrap-ltr.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-wrap-rtl.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-nowrap.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-ltr.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-rtl.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-orderedgroup.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-pathlayout-graphics.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-pathlayout.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-transform2D.bt create mode 100644 regression_tests/bifs/bifs-2D-positioning-transformmatrix2D.bt create mode 100644 regression_tests/bifs/bifs-2D-shapes-all.bt create mode 100644 regression_tests/bifs/bifs-2D-shapes-indexfaceset2D.bt create mode 100644 regression_tests/bifs/bifs-2D-shapes-indexlineset2D.bt create mode 100644 regression_tests/bifs/bifs-2D-shapes-pointset2D.bt create mode 100644 regression_tests/bifs/bifs-2D-shapes-xcurve2D.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-compositetexture2D-background.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-compositetexture2D-bitmap.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-compositetexture2D-transparent.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-gradients-text.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-gradients-transparent.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-imagetexture-shapes.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-lineargradient-simple.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-lineargradient-spread.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-movietexture-shapes.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-pixeltexture.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-radialgradient-simple.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-radialgradient-spread.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-texturetransform-base.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-texturetransform-interact.bt create mode 100644 regression_tests/bifs/bifs-2D-texturing-texturetransform-transformmatrix2D.bt create mode 100644 regression_tests/bifs/bifs-2D-viewport-complete.bt create mode 100644 regression_tests/bifs/bifs-2D-viewport-simple.bt create mode 100644 regression_tests/bifs/bifs-3D-background-images.bt create mode 100644 regression_tests/bifs/bifs-3D-background.bt create mode 100644 regression_tests/bifs/bifs-3D-interactivity-collision-proxy.bt create mode 100644 regression_tests/bifs/bifs-3D-interactivity-collision.bt create mode 100644 regression_tests/bifs/bifs-3D-interactivity-cylindersensor.bt create mode 100644 regression_tests/bifs/bifs-3D-interactivity-planesensor.bt create mode 100644 regression_tests/bifs/bifs-3D-interactivity-proximitysensor.bt create mode 100644 regression_tests/bifs/bifs-3D-interactivity-spheresensor.bt create mode 100644 regression_tests/bifs/bifs-3D-interactivity-visibilitysensor.bt create mode 100644 regression_tests/bifs/bifs-3D-lighting-directionalLight.bt create mode 100644 regression_tests/bifs/bifs-3D-lighting-fog.bt create mode 100644 regression_tests/bifs/bifs-3D-lighting-pointlight.bt create mode 100644 regression_tests/bifs/bifs-3D-lighting-spotlight.bt create mode 100644 regression_tests/bifs/bifs-3D-positioning-billboard-viewer-alignment.bt create mode 100644 regression_tests/bifs/bifs-3D-positioning-billboard.bt create mode 100644 regression_tests/bifs/bifs-3D-positioning-gravity.bt create mode 100644 regression_tests/bifs/bifs-3D-positioning-layer3D-views.bt create mode 100644 regression_tests/bifs/bifs-3D-positioning-layer3D.bt create mode 100644 regression_tests/bifs/bifs-3D-positioning-lod.bt create mode 100644 regression_tests/bifs/bifs-3D-positioning-transform.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-box-transparent.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-box.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-cone.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-cylinder.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-elevationgrid.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-extrusion.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-indexedfaceset.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-indexedlineset.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-nonlineardeformer.bt create mode 100644 regression_tests/bifs/bifs-3D-shapes-pointset.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-box-transparent.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-box-video.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-box.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-compositetexture3D-bitmap.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-compositetexture3D-box.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-cone-transparent.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-cone.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-cylinder-transparent.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-cylinder.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-transform-box.bt create mode 100644 regression_tests/bifs/bifs-3D-texturing-transform-matrix-box.bt create mode 100644 regression_tests/bifs/bifs-3D-viewpoint-anim.bt create mode 100644 regression_tests/bifs/bifs-3D-viewpoint-bind-jump.bt create mode 100644 regression_tests/bifs/bifs-3D-viewpoint-bind.bt create mode 100644 regression_tests/bifs/bifs-3D-viewpoint-ortho-bind.bt create mode 100644 regression_tests/bifs/bifs-bitmap-image-meter-metrics.bt create mode 100644 regression_tests/bifs/bifs-bitmap-image-pixel-metrics.bt create mode 100644 regression_tests/bifs/bifs-bitmap-image-resizing.bt create mode 100644 regression_tests/bifs/bifs-bitmap-movie-materialkey.bt create mode 100644 regression_tests/bifs/bifs-bitmap-movie.bt create mode 100644 regression_tests/bifs/bifs-bitmap-video-resizing.bt create mode 100644 regression_tests/bifs/bifs-command-animated-osmo4logo.bt create mode 100644 regression_tests/bifs/bifs-command-delete-index.bt create mode 100644 regression_tests/bifs/bifs-command-delete-node.bt create mode 100644 regression_tests/bifs/bifs-command-delete-route.bt create mode 100644 regression_tests/bifs/bifs-command-global-qp.bt create mode 100644 regression_tests/bifs/bifs-command-insert-index.bt create mode 100644 regression_tests/bifs/bifs-command-insert-node.bt create mode 100644 regression_tests/bifs/bifs-command-insert-nodedef.bt create mode 100644 regression_tests/bifs/bifs-command-insert-route.bt create mode 100644 regression_tests/bifs/bifs-command-multiple-replace-field.bt create mode 100644 regression_tests/bifs/bifs-command-multiple-replace-index.bt create mode 100644 regression_tests/bifs/bifs-command-node-delete-ex.bt create mode 100644 regression_tests/bifs/bifs-command-proto-delete.bt create mode 100644 regression_tests/bifs/bifs-command-proto-insert.bt create mode 100644 regression_tests/bifs/bifs-command-protolist-delete.bt create mode 100644 regression_tests/bifs/bifs-command-quantification.bt create mode 100644 regression_tests/bifs/bifs-command-replace-field.bt create mode 100644 regression_tests/bifs/bifs-command-replace-index.bt create mode 100644 regression_tests/bifs/bifs-command-replace-node-null.bt create mode 100644 regression_tests/bifs/bifs-command-replace-node.bt create mode 100644 regression_tests/bifs/bifs-command-replace-route.bt create mode 100644 regression_tests/bifs/bifs-command-replace-scene-null.bt create mode 100644 regression_tests/bifs/bifs-command-replace-scene.bt create mode 100644 regression_tests/bifs/bifs-command-route-add-children.bt create mode 100644 regression_tests/bifs/bifs-command-route-children.bt create mode 100644 regression_tests/bifs/bifs-command-route-node-exposedfield.bt create mode 100644 regression_tests/bifs/bifs-command-route-node.bt create mode 100644 regression_tests/bifs/bifs-command-route-remove-children.bt create mode 100644 regression_tests/bifs/bifs-externproto-forestgump-lib.bt create mode 100644 regression_tests/bifs/bifs-externproto-forestgump.bt create mode 100644 regression_tests/bifs/bifs-externproto-mfurl-lib.bt create mode 100644 regression_tests/bifs/bifs-externproto-mfurl.bt create mode 100644 regression_tests/bifs/bifs-externproto-nood-lib.bt create mode 100644 regression_tests/bifs/bifs-externproto-nood.bt create mode 100644 regression_tests/bifs/bifs-externproto-simple-lib.bt create mode 100644 regression_tests/bifs/bifs-externproto-simple.bt create mode 100644 regression_tests/bifs/bifs-game-arrange.bt create mode 100644 regression_tests/bifs/bifs-game-breakout.bt create mode 100644 regression_tests/bifs/bifs-game-bubble.bt create mode 100644 regression_tests/bifs/bifs-game-minesweeper.bt create mode 100644 regression_tests/bifs/bifs-game-othello.bt create mode 100644 regression_tests/bifs/bifs-interpolation-colorinterpolator.bt create mode 100644 regression_tests/bifs/bifs-interpolation-coordinateinterpolator2D.bt create mode 100644 regression_tests/bifs/bifs-interpolation-positionanimator.bt create mode 100644 regression_tests/bifs/bifs-interpolation-positionanimator2D.bt create mode 100644 regression_tests/bifs/bifs-interpolation-positioninterpolator-position.bt create mode 100644 regression_tests/bifs/bifs-interpolation-positioninterpolator-size.bt create mode 100644 regression_tests/bifs/bifs-interpolation-positioninterpolator2D-position.bt create mode 100644 regression_tests/bifs/bifs-interpolation-positioninterpolator2D-size.bt create mode 100644 regression_tests/bifs/bifs-interpolation-scalaranimator.bt create mode 100644 regression_tests/bifs/bifs-interpolation-scalarinterpolator.bt create mode 100644 regression_tests/bifs/bifs-interpolation-timesensor-enabled.bt create mode 100644 regression_tests/bifs/bifs-interpolation-timesensor-starttime_norestart.bt create mode 100644 regression_tests/bifs/bifs-interpolation-timesensor-starttime_restart.bt create mode 100644 regression_tests/bifs/bifs-interpolation-valuator-sftime.bt create mode 100644 regression_tests/bifs/bifs-linking-anchor-mp4-next.bt create mode 100644 regression_tests/bifs/bifs-linking-anchor-mp4-prev.bt create mode 100644 regression_tests/bifs/bifs-linking-anchor-viewpoint.bt create mode 100644 regression_tests/bifs/bifs-linking-anchor-www.bt create mode 100644 regression_tests/bifs/bifs-linking-animationstream.bt create mode 100644 regression_tests/bifs/bifs-linking-inline-direct-inline.bt create mode 100644 regression_tests/bifs/bifs-linking-inline-direct.bt create mode 100644 regression_tests/bifs/bifs-linking-inline-od-inline.bt create mode 100644 regression_tests/bifs/bifs-linking-inline-od.bt create mode 100644 regression_tests/bifs/bifs-linking-inline-rtsp-no-od.bt create mode 100644 regression_tests/bifs/bifs-linking-inline-rtsp.bt create mode 100644 regression_tests/bifs/bifs-linking-inline-segment-inline.bt create mode 100644 regression_tests/bifs/bifs-linking-inline-segment.bt create mode 100644 regression_tests/bifs/bifs-media-audiobuffer.bt create mode 100644 regression_tests/bifs/bifs-media-audioclip-urlchanged.bt create mode 100644 regression_tests/bifs/bifs-media-audioclip.bt create mode 100644 regression_tests/bifs/bifs-media-audiosource-mixing.bt create mode 100644 regression_tests/bifs/bifs-media-audiosource-urlchanged.bt create mode 100644 regression_tests/bifs/bifs-media-audiosource.bt create mode 100644 regression_tests/bifs/bifs-media-imagetexture-OD-reuse.bt create mode 100644 regression_tests/bifs/bifs-media-imagetexture-no-od.bt create mode 100644 regression_tests/bifs/bifs-media-imagetexture-object-scale.bt create mode 100644 regression_tests/bifs/bifs-media-imagetexture-transparent.bt create mode 100644 regression_tests/bifs/bifs-media-imagetexture-url-change.bt create mode 100644 regression_tests/bifs/bifs-media-movietexture-control.bt create mode 100644 regression_tests/bifs/bifs-media-movietexture-no-od.bt create mode 100644 regression_tests/bifs/bifs-media-movietexture-od-joinsession.bt create mode 100644 regression_tests/bifs/bifs-media-movietexture-od-leave-session.bt create mode 100644 regression_tests/bifs/bifs-media-movietexture-owns-OCR.bt create mode 100644 regression_tests/bifs/bifs-media-movietexture-shares-OCR.bt create mode 100644 regression_tests/bifs/bifs-media-movietexture-url-change.bt create mode 100644 regression_tests/bifs/bifs-media-sound-spatialize.bt create mode 100644 regression_tests/bifs/bifs-media-sound.bt create mode 100644 regression_tests/bifs/bifs-misc-UTF16-input.bt create mode 100644 regression_tests/bifs/bifs-misc-cyclic-graph.bt create mode 100644 regression_tests/bifs/bifs-misc-hc-proto-pathextrusion.bt create mode 100644 regression_tests/bifs/bifs-misc-hc-proto-planarextrusion.bt create mode 100644 regression_tests/bifs/bifs-misc-hc-proto-planeclipper.bt create mode 100644 regression_tests/bifs/bifs-misc-non-linear-parsing-conditional.bt create mode 100644 regression_tests/bifs/bifs-misc-non-linear-parsing-use.bt create mode 100644 regression_tests/bifs/bifs-misc-srt-import-3gpp-control-share-ocr.bt create mode 100644 regression_tests/bifs/bifs-misc-srt-import-3gpp-control.bt create mode 100644 regression_tests/bifs/bifs-misc-srt-import-3gpp.bt create mode 100644 regression_tests/bifs/bifs-misc-srt-import.bt create mode 100644 regression_tests/bifs/bifs-od-remove-esd.bt create mode 100644 regression_tests/bifs/bifs-od-remove-od.bt create mode 100644 regression_tests/bifs/bifs-od-update-od.bt create mode 100644 regression_tests/bifs/bifs-proto-conditional.bt create mode 100644 regression_tests/bifs/bifs-proto-delete-def.bt create mode 100644 regression_tests/bifs/bifs-proto-delete-index.bt create mode 100644 regression_tests/bifs/bifs-proto-forestgump.bt create mode 100644 regression_tests/bifs/bifs-proto-mfurl.bt create mode 100644 regression_tests/bifs/bifs-proto-multiple.bt create mode 100644 regression_tests/bifs/bifs-proto-nested.bt create mode 100644 regression_tests/bifs/bifs-proto-route.bt create mode 100644 regression_tests/bifs/bifs-proto-sftime-protocode.bt create mode 100644 regression_tests/bifs/bifs-proto-sftime-protointerface.bt create mode 100644 regression_tests/bifs/bifs-proto-simple.bt create mode 100644 regression_tests/bifs/bifs-proto-use.bt create mode 100644 regression_tests/bifs/bifs-script-char-to-int.bt create mode 100644 regression_tests/bifs/bifs-script-child-create.bt create mode 100644 regression_tests/bifs/bifs-script-date.bt create mode 100644 regression_tests/bifs/bifs-script-event-out.bt create mode 100644 regression_tests/bifs/bifs-script-initialize.bt create mode 100644 regression_tests/bifs/bifs-script-load-url.bt create mode 100644 regression_tests/bifs/bifs-script-node-access.bt create mode 100644 regression_tests/bifs/bifs-script-node-create.bt create mode 100644 regression_tests/bifs/bifs-script-proto.bt create mode 100644 regression_tests/bifs/bifs-script-timestamp.bt create mode 100644 regression_tests/bifs/bifs-stream-text-switch.bt create mode 100644 regression_tests/bifs/bifs-text-align-horiz1.bt create mode 100644 regression_tests/bifs/bifs-text-align-horiz2.bt create mode 100644 regression_tests/bifs/bifs-text-align-horiz3.bt create mode 100644 regression_tests/bifs/bifs-text-align-horiz4.bt create mode 100644 regression_tests/bifs/bifs-text-align-vert1.bt create mode 100644 regression_tests/bifs/bifs-text-align-vert2.bt create mode 100644 regression_tests/bifs/bifs-text-align-vert3.bt create mode 100644 regression_tests/bifs/bifs-text-align-vert4.bt create mode 100644 regression_tests/bifs/bifs-text-glyph-advance.bt create mode 100644 regression_tests/bifs/bifs-text-length.bt create mode 100644 regression_tests/bifs/bifs-text-maxextend.bt create mode 100644 regression_tests/bifs/bifs-text-style.bt create mode 100644 regression_tests/bifs/bifs-text-unicode.bt create mode 100644 regression_tests/bifs/bifs-text-vrml-alignment.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-OCR.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-audio-speed.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-audio.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-complete.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-deactivation.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-inline-av.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-inline-segments.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-inline.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-rtsp.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-seg-inline.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-segments.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-video.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediacontrol-videospeed.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediasensor-segment-switch.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediasensor-segment.bt create mode 100644 regression_tests/bifs/bifs-timeline-mediasensor.bt create mode 100644 regression_tests/svg/all_syntaxes_1.1F2.svg create mode 100644 regression_tests/svg/createanim-by-script.svg create mode 100644 regression_tests/svg/createimage-by-script.svg create mode 100644 regression_tests/svg/utfscript.svg create mode 100644 regression_tests/utfscript.svg delete mode 100644 regression_tests/x3d-2D-Arc2d.x3dv delete mode 100644 regression_tests/x3d-2D-ArcClose2d.x3dv delete mode 100644 regression_tests/x3d-2D-Disk2d.x3dv delete mode 100644 regression_tests/x3d-2D-Polyline2d.x3dv delete mode 100644 regression_tests/x3d-2D-Polypoint2d.x3dv delete mode 100644 regression_tests/x3d-2D-TriangleSet2d.x3dv delete mode 100644 regression_tests/x3d-3D-IndexedTriangleFanSet.x3dv delete mode 100644 regression_tests/x3d-3D-IndexedTriangleSet.x3dv delete mode 100644 regression_tests/x3d-3D-IndexedTriangleStripSet.x3dv delete mode 100644 regression_tests/x3d-3D-LineSet.x3dv delete mode 100644 regression_tests/x3d-3D-TriangleFanSet.x3dv delete mode 100644 regression_tests/x3d-3D-TriangleSet.x3dv delete mode 100644 regression_tests/x3d-3D-TriangleStripSet.x3dv delete mode 100644 regression_tests/x3d-misc-ColorRGBA.x3dv delete mode 100644 regression_tests/x3d-misc-HatchStyle.x3dv delete mode 100644 regression_tests/x3d-misc-KeySensor.x3dv delete mode 100644 regression_tests/x3d-misc-StringSensor.x3dv create mode 100644 regression_tests/x3d/x3d-2D-Arc2d.x3dv create mode 100644 regression_tests/x3d/x3d-2D-ArcClose2d.x3dv create mode 100644 regression_tests/x3d/x3d-2D-Disk2d.x3dv create mode 100644 regression_tests/x3d/x3d-2D-Polyline2d.x3dv create mode 100644 regression_tests/x3d/x3d-2D-Polypoint2d.x3dv create mode 100644 regression_tests/x3d/x3d-2D-TriangleSet2d.x3dv create mode 100644 regression_tests/x3d/x3d-3D-IndexedTriangleFanSet.x3dv create mode 100644 regression_tests/x3d/x3d-3D-IndexedTriangleSet.x3dv create mode 100644 regression_tests/x3d/x3d-3D-IndexedTriangleStripSet.x3dv create mode 100644 regression_tests/x3d/x3d-3D-LineSet.x3dv create mode 100644 regression_tests/x3d/x3d-3D-TriangleFanSet.x3dv create mode 100644 regression_tests/x3d/x3d-3D-TriangleSet.x3dv create mode 100644 regression_tests/x3d/x3d-3D-TriangleStripSet.x3dv create mode 100644 regression_tests/x3d/x3d-misc-ColorRGBA.x3dv create mode 100644 regression_tests/x3d/x3d-misc-HatchStyle.x3dv create mode 100644 regression_tests/x3d/x3d-misc-KeySensor.x3dv create mode 100644 regression_tests/x3d/x3d-misc-StringSensor.x3dv create mode 100644 src/compositor/hc_flash_shape.c create mode 100644 src/compositor/svg_filters.c create mode 100644 src/export.cpp create mode 100644 src/ietf/rtp_streamer.c delete mode 100644 src/libgpac.def delete mode 100644 src/libgpac_ce.def create mode 100644 src/media_tools/dvb_mpe.c create mode 100644 src/media_tools/filestreamer.c create mode 100644 src/media_tools/m2ts_mux.c create mode 100644 src/media_tools/reedsolomon.c delete mode 100644 src/scene_manager/encode_cbk.c create mode 100644 src/scene_manager/scene_engine.c delete mode 100644 src/terminal/inline.c create mode 100644 src/terminal/mpeg4_inline.c create mode 100644 src/terminal/scene.c create mode 100644 src/utils/dlmalloc.c diff --git a/Changelog b/Changelog index 86d88b2..5506b0f 100644 --- a/Changelog +++ b/Changelog @@ -1,3 +1,15 @@ +27/08/09: + - Added overwrite of profile and level of AVC streams when adding tracks in mp4box(from ISOFF or .264). Use ":profile=X" and ":level=Z" when importing + - Fixed chapters and text tracks handling for iTunes. Using the -ipd option in MP4Box should fix all subtitles tracks. + When adding a track (including subtitle), it is now possible to override the track layout. For example: + MP4Box -add test.srt:layout=0x20x0x-1 test.mp4 + will set the track box to be max width of the file tracks, 20 pixels height, translated by 0 pixels left and aligned to the bottom (max height - 20) + To add a chapter track, you simply have to add ":chap" in the -add command. + - Added modular compilation of most libgpac features. See configure or include/gpac/configuration + - Fixed streaming interoperability with Live555 + - More fixed and speed improvement in VRML/BIFS scripting + - Added support for PBuffers on Win32/DirectX + 02/12/08: GPAC 0.4.5 - Support for AC3 in ISO Media, AC3 decoder (liba52) RTP hinting - Support for MediaAccessEvent (spec still under development ??) diff --git a/INSTALLME b/INSTALLME index 1bd5609..2dc4abd 100644 --- a/INSTALLME +++ b/INSTALLME @@ -11,7 +11,7 @@ are provided per library in the package. In case you have some of these libs already installed on your system, the detailed list of dependencies is * freetype2 from version 2.1.4 on. - * SpiderMonkey v1.7 (libjs from mozilla). Older versions should work + * SpiderMonkey v1.7 (libjs from mozilla). * libjpg version 6b * Libpng version 1.2.33 (older versions should work) * MAD version 0.15.1b (older versions should work) diff --git a/Makefile b/Makefile index 84ab8ae..ee078e4 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ distclean: $(MAKE) -C src distclean $(MAKE) -C applications distclean $(MAKE) -C modules distclean - rm -f config.mak + rm -f config.mak config.h dep: depend @@ -48,37 +48,26 @@ tar: ( tar zcvf ~/$(FILE).tar.gz ../gpac --exclude CVS --exclude bin --exclude lib --exclude Obj --exclude temp --exclude amr_nb --exclude amr_nb_ft --exclude amr_wb_ft --exclude *.mak --exclude *.o --exclude *.~*) install: - install -d "$(DESTDIR)$(prefix)" - install -d "$(DESTDIR)$(prefix)/bin" - install $(INSTFLAGS) -m 755 bin/gcc/MP4Box "$(DESTDIR)$(prefix)/bin" + $(INSTALL) -d "$(DESTDIR)$(prefix)" + $(INSTALL) -d "$(DESTDIR)$(prefix)/bin" + $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/MP4Box "$(DESTDIR)$(prefix)/bin" $(MAKE) -C applications install - install -d "$(DESTDIR)$(moddir)" - install bin/gcc/*.$(DYN_LIB_SUFFIX) "$(DESTDIR)$(moddir)" + $(INSTALL) -d "$(DESTDIR)$(moddir)" + $(INSTALL) bin/gcc/*.$(DYN_LIB_SUFFIX) "$(DESTDIR)$(moddir)" rm -f $(DESTDIR)$(moddir)/libgpac.$(DYN_LIB_SUFFIX) rm -f $(DESTDIR)$(moddir)/nposmozilla.$(DYN_LIB_SUFFIX) -ifeq ($(CONFIG_WIN32),yes) - install $(INSTFLAGS) -m 755 bin/gcc/libgpac.dll $(prefix)/$(libdir) -else -ifeq ($(DEBUGBUILD),no) - $(STRIP) bin/gcc/libgpac.$(DYN_LIB_SUFFIX) -endif -ifeq ($(CONFIG_DARWIN),yes) - install -m 755 bin/gcc/libgpac.$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac-$(VERSION).$(DYN_LIB_SUFFIX) - ln -sf libgpac-$(VERSION).$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(DYN_LIB_SUFFIX) -else - install $(INSTFLAGS) -m 755 bin/gcc/libgpac.$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac-$(VERSION).$(DYN_LIB_SUFFIX) - ln -sf libgpac-$(VERSION).$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(DYN_LIB_SUFFIX) - ldconfig || true -endif -endif - install -d "$(DESTDIR)$(mandir)" - install -d "$(DESTDIR)$(mandir)/man1" + $(MAKE) installdylib + $(INSTALL) -d "$(DESTDIR)$(mandir)" + $(INSTALL) -d "$(DESTDIR)$(mandir)/man1" if [ -d doc ] ; then \ - install -m 644 doc/man/mp4box.1 $(DESTDIR)$(mandir)/man1/ ; \ - install -m 644 doc/man/mp4client.1 $(DESTDIR)$(mandir)/man1/ ; \ - install -m 644 doc/man/gpac.1 $(DESTDIR)$(mandir)/man1/ ; \ - install -d "$(DESTDIR)$(prefix)/share/gpac" ; \ - install -m 644 doc/gpac.mp4 $(DESTDIR)$(prefix)/share/gpac/ ; \ + $(INSTALL) $(INSTFLAGS) -m 644 doc/man/mp4box.1 $(DESTDIR)$(mandir)/man1/ ; \ + $(INSTALL) $(INSTFLAGS) -m 644 doc/man/mp4client.1 $(DESTDIR)$(mandir)/man1/ ; \ + $(INSTALL) $(INSTFLAGS) -m 644 doc/man/gpac.1 $(DESTDIR)$(mandir)/man1/ ; \ + $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac" ; \ + $(INSTALL) $(INSTFLAGS) -m 644 doc/gpac.mp4 $(DESTDIR)$(prefix)/share/gpac/ ; \ + $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac/gui" ; \ + $(INSTALL) -d "$(DESTDIR)$(prefix)/share/gpac/gui/icons" ; \ + $(INSTALL) $(INSTFLAGS) -m 644 gui/icons/*.svg "$(DESTDIR)$(prefix)/share/gpac/gui/icons" ; \ fi uninstall: @@ -92,21 +81,40 @@ uninstall: rm -rf $(mandir)/man1/gpac.1 rm -rf $(prefix)/share/gpac +installdylib: +ifeq ($(CONFIG_WIN32),yes) + $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/libgpac.dll $(prefix)/$(libdir) +else +ifeq ($(DEBUGBUILD),no) + $(STRIP) bin/gcc/libgpac.$(DYN_LIB_SUFFIX) +endif +ifeq ($(CONFIG_DARWIN),yes) + $(INSTALL) -m 755 bin/gcc/libgpac.$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(VERSION).$(DYN_LIB_SUFFIX) + ln -sf libgpac.$(VERSION).$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(DYN_LIB_SUFFIX) +else + $(INSTALL) $(INSTFLAGS) -m 755 bin/gcc/libgpac.$(DYN_LIB_SUFFIX) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(DYN_LIB_SUFFIX).$(VERSION) + ln -sf libgpac.$(DYN_LIB_SUFFIX).$(VERSION) $(DESTDIR)$(prefix)/$(libdir)/libgpac.$(DYN_LIB_SUFFIX) +ifeq ($(DESTDIR)$(prefix),$(prefix)) + ldconfig || true +endif +endif +endif + install-lib: mkdir -p "$(DESTDIR)$(prefix)/include/gpac" - install -m 644 $(SRC_PATH)/include/gpac/*.h "$(DESTDIR)$(prefix)/include/gpac" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/include/gpac/*.h "$(DESTDIR)$(prefix)/include/gpac" mkdir -p "$(DESTDIR)$(prefix)/include/gpac/internal" - install -m 644 $(SRC_PATH)/include/gpac/internal/*.h "$(DESTDIR)$(prefix)/include/gpac/internal" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/include/gpac/internal/*.h "$(DESTDIR)$(prefix)/include/gpac/internal" mkdir -p "$(DESTDIR)$(prefix)/include/gpac/modules" - install -m 644 $(SRC_PATH)/include/gpac/modules/*.h "$(DESTDIR)$(prefix)/include/gpac/modules" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/include/gpac/modules/*.h "$(DESTDIR)$(prefix)/include/gpac/modules" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/config.h "$(DESTDIR)$(prefix)/include/gpac/configuration.h" ifeq ($(GPAC_ENST), yes) mkdir -p "$(DESTDIR)$(prefix)/include/gpac/enst" - install -m 644 $(SRC_PATH)/include/gpac/enst/*.h "$(DESTDIR)$(prefix)/include/gpac/enst" + $(INSTALL) $(INSTFLAGS) -m 644 $(SRC_PATH)/include/gpac/enst/*.h "$(DESTDIR)$(prefix)/include/gpac/enst" endif - mkdir -p "$(DESTDIR)$(prefix)/lib" - install -m 644 "./bin/gcc/libgpac_static.a" "$(DESTDIR)$(prefix)/lib" mkdir -p "$(DESTDIR)$(prefix)/$(libdir)" - install -m 644 "./bin/gcc/libgpac_static.a" "$(DESTDIR)$(prefix)/$(libdir)" + $(INSTALL) $(INSTFLAGS) -m 644 "./bin/gcc/libgpac_static.a" "$(DESTDIR)$(prefix)/$(libdir)" + $(MAKE) installdylib uninstall-lib: rm -rf "$(prefix)/include/gpac/internal" diff --git a/applications/GPAX/GPAX.dsp b/applications/GPAX/GPAX.dsp index 0b6fe26..ac3d1a3 100644 --- a/applications/GPAX/GPAX.dsp +++ b/applications/GPAX/GPAX.dsp @@ -1,173 +1,173 @@ -# Microsoft Developer Studio Project File - Name="GPAX" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=GPAX - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "GPAX.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "GPAX.mak" CFG="GPAX - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "GPAX - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "GPAX - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "GPAX - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/w32_deb" -# PROP Intermediate_Dir "obj/w32_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /Yu"stdafx.h" /FD /GZ /c -# ADD BASE RSC /l 0x804 /d "_DEBUG" -# ADD RSC /l 0x804 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 js32.lib zlib.lib winmm.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/w32_deb/GPAX.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" -# Begin Custom Build - Performing registration -OutDir=.\obj/w32_deb -TargetPath=\CVS\gpac\bin\w32_deb\GPAX.dll -InputPath=\CVS\gpac\bin\w32_deb\GPAX.dll -SOURCE="$(InputPath)" - -"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - regsvr32 /s /c "$(TargetPath)" - echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" - -# End Custom Build - -!ELSEIF "$(CFG)" == "GPAX - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "obj/w32_rel" -# PROP BASE Intermediate_Dir "obj/w32_rel" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/w32_rel" -# PROP Intermediate_Dir "obj/w32_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MD /W3 /Gm /ZI /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /Yu"stdafx.h" /FD /GZ /c -# SUBTRACT CPP /O -# ADD BASE RSC /l 0x804 /d "_DEBUG" -# ADD RSC /l 0x804 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 js32.lib zlib.lib winmm.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../gpac/extra_lib/lib/w32_deb" -# ADD LINK32 js32.lib zlib.lib winmm.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/w32_rel/GPAX.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_rel" -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=copy ..\..\bin\w32_rel\GPAX.dll "C:\Program Files\GPAC" -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "GPAX - Win32 Debug" -# Name "GPAX - Win32 Release" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\GPAX.cpp -# End Source File -# Begin Source File - -SOURCE=.\GPAX.def -# End Source File -# Begin Source File - -SOURCE=.\GPAX.idl -# ADD MTL /tlb ".\GPAX.tlb" /h "GPAX.h" /iid "GPAX_i.c" /Oicf -# End Source File -# Begin Source File - -SOURCE=.\GPAX.rc -# End Source File -# Begin Source File - -SOURCE=.\GPAXPlugin.cpp -# End Source File -# Begin Source File - -SOURCE=.\StdAfx.cpp -# ADD CPP /Yc"stdafx.h" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\GPAXPlugin.h -# End Source File -# Begin Source File - -SOURCE=.\Resource.h -# End Source File -# Begin Source File - -SOURCE=.\StdAfx.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=.\gpax.bmp -# End Source File -# Begin Source File - -SOURCE=.\GPAX.rgs -# End Source File -# Begin Source File - -SOURCE=.\GPAXProp.rgs -# End Source File -# End Group -# End Target -# End Project -# Section GPAX : {00000000-0000-0000-0000-800000800000} -# 1:21:IDS_DOCSTRINGGPAXProp:105 -# 1:12:IDD_GPAXPROP:107 -# 1:12:IDR_GPAXPROP:106 -# 1:20:IDS_HELPFILEGPAXProp:104 -# 1:17:IDS_TITLEGPAXProp:103 -# End Section +# Microsoft Developer Studio Project File - Name="GPAX" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=GPAX - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "GPAX.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GPAX.mak" CFG="GPAX - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GPAX - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "GPAX - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "GPAX - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "obj/w32_deb" +# PROP Intermediate_Dir "obj/w32_deb" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /Yu"stdafx.h" /FD /GZ /c +# ADD BASE RSC /l 0x804 /d "_DEBUG" +# ADD RSC /l 0x804 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 js32.lib zlib.lib winmm.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/w32_deb/GPAX.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" +# Begin Custom Build - Performing registration +OutDir=.\obj/w32_deb +TargetPath=\CVS\gpac\bin\w32_deb\GPAX.dll +InputPath=\CVS\gpac\bin\w32_deb\GPAX.dll +SOURCE="$(InputPath)" + +"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + regsvr32 /s /c "$(TargetPath)" + echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" + +# End Custom Build + +!ELSEIF "$(CFG)" == "GPAX - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "obj/w32_rel" +# PROP BASE Intermediate_Dir "obj/w32_rel" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "obj/w32_rel" +# PROP Intermediate_Dir "obj/w32_rel" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /Yu"stdafx.h" /FD /GZ /c +# ADD CPP /nologo /MD /W3 /Gm /ZI /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /Yu"stdafx.h" /FD /GZ /c +# SUBTRACT CPP /O +# ADD BASE RSC /l 0x804 /d "_DEBUG" +# ADD RSC /l 0x804 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 js32.lib zlib.lib winmm.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../gpac/extra_lib/lib/w32_deb" +# ADD LINK32 js32.lib zlib.lib winmm.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/w32_rel/GPAX.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_rel" +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Cmds=copy ..\..\bin\w32_rel\GPAX.dll "C:\Program Files\GPAC" +# End Special Build Tool + +!ENDIF + +# Begin Target + +# Name "GPAX - Win32 Debug" +# Name "GPAX - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\GPAX.cpp +# End Source File +# Begin Source File + +SOURCE=.\GPAX.def +# End Source File +# Begin Source File + +SOURCE=.\GPAX.idl +# ADD MTL /tlb ".\GPAX.tlb" /h "GPAX.h" /iid "GPAX_i.c" /Oicf +# End Source File +# Begin Source File + +SOURCE=.\GPAX.rc +# End Source File +# Begin Source File + +SOURCE=.\GPAXPlugin.cpp +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.cpp +# ADD CPP /Yc"stdafx.h" +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\GPAXPlugin.h +# End Source File +# Begin Source File + +SOURCE=.\Resource.h +# End Source File +# Begin Source File + +SOURCE=.\StdAfx.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\gpax.bmp +# End Source File +# Begin Source File + +SOURCE=.\GPAX.rgs +# End Source File +# Begin Source File + +SOURCE=.\GPAXProp.rgs +# End Source File +# End Group +# End Target +# End Project +# Section GPAX : {00000000-0000-0000-0000-800000800000} +# 1:21:IDS_DOCSTRINGGPAXProp:105 +# 1:12:IDD_GPAXPROP:107 +# 1:12:IDR_GPAXPROP:106 +# 1:20:IDS_HELPFILEGPAXProp:104 +# 1:17:IDS_TITLEGPAXProp:103 +# End Section diff --git a/applications/GPAX/GPAXPlugin.cpp b/applications/GPAX/GPAXPlugin.cpp index e32b66a..a72bf40 100644 --- a/applications/GPAX/GPAXPlugin.cpp +++ b/applications/GPAX/GPAXPlugin.cpp @@ -7,7 +7,7 @@ * * This file is part of GPAC / ActiveX control * - * GPAC is free software; you can redistribute it and/or modify + * GPAC is gf_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. @@ -28,8 +28,10 @@ #include "GPAXPlugin.h" #include #include +#include #ifndef _WIN32_WCE +#include #include #endif @@ -256,13 +258,44 @@ void CGPAXPlugin::LoadDATAUrl() } +// trap keys and forward on to the control +BOOL CGPAXPlugin::PreTranslateMessage(MSG* pMsg) +{ + switch (pMsg->message) + { + case WM_KEYDOWN: + case WM_KEYUP: + switch (pMsg->wParam) + { + case VK_UP: + case VK_DOWN: + case VK_LEFT: + case VK_RIGHT: + case VK_HOME: + case VK_END: + SendMessage (pMsg->message, pMsg->wParam, pMsg->lParam); + // Windowless controls won't be able to call SendMessage. + // Instead, just respond to the message here. + return TRUE; + } + break; + } + return FALSE; +// return COleControl::PreTranslateMessage(pMsg); +} + + + + +#define GPAC_REG_KEY HKEY_CURRENT_USER + //Create window message fuction. when the window is created, also initialize a instance of //GPAC player instance. LRESULT CGPAXPlugin::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if (m_term) return 0; - unsigned char config_path[GF_MAX_PATH]; + char config_path[GF_MAX_PATH], config_test_file[GF_MAX_PATH]; char *gpac_cfg; const char *str; @@ -271,27 +304,51 @@ LRESULT CGPAXPlugin::OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHa gpac_cfg = "GPAC.cfg"; -#if defined(_DEBUG) && !defined(_WIN32_WCE) - strcpy((char *) config_path, "D:\\cvs\\gpac\\bin\\w32_deb\\"); -#else //Here we retrieve GPAC config file in the install diractory, which is indicated in the //Registry HKEY hKey = NULL; DWORD dwSize; #ifdef _WIN32_WCE u16 w_path[1024]; - RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("GPAC"), 0, KEY_READ, &hKey); + RegOpenKeyEx(GPAC_REG_KEY, TEXT("Software\\GPAC"), 0, KEY_READ, &hKey); DWORD dwType = REG_SZ; dwSize = GF_MAX_PATH; - RegQueryValueEx(hKey, TEXT("InstallDir"), 0, &dwType, (LPBYTE) w_path, &dwSize); +#ifdef _DEBUG + if (RegQueryValueEx(hKey, TEXT("DebugDir"), 0, &dwType, (LPBYTE) w_path, &dwSize) != ERROR_SUCCESS) +#endif + RegQueryValueEx(hKey, TEXT("InstallDir"), 0, &dwType, (LPBYTE) w_path, &dwSize); CE_WideToChar(w_path, (char *)config_path); RegCloseKey(hKey); #else - RegOpenKeyEx(HKEY_CLASSES_ROOT, "GPAC", 0, KEY_READ, &hKey); - dwSize = GF_MAX_PATH; - RegQueryValueEx(hKey, "InstallDir", NULL, NULL, (unsigned char*) config_path, &dwSize); - RegCloseKey(hKey); + /*locate the key in current user, then in local machine*/ + if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\GPAC", 0, KEY_READ, &hKey) != ERROR_SUCCESS) + RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\GPAC", 0, KEY_READ, &hKey); + dwSize = GF_MAX_PATH; +#ifdef _DEBUG + if (RegQueryValueEx(hKey, "DebugDir", NULL, NULL,(unsigned char*) config_path, &dwSize) != ERROR_SUCCESS) #endif + RegQueryValueEx(hKey, "InstallDir", NULL, NULL,(unsigned char*) config_path, &dwSize); + RegCloseKey(hKey); + + /*do we have write access?*/ + strcpy(config_test_file, config_path); + assert(strlen(config_path)+strlen(gpac_cfg)+1 1000 #define STRICT + +#ifndef _WIN32_WCE + #ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0400 +#define _WIN32_WINNT 0x0501 #endif #define _ATL_APARTMENT_THREADED +#endif //_WIN32_WCE + + #include //You may derive a class from CComModule and use it if you want to override //something, but do not change the name of _Module diff --git a/applications/Makefile b/applications/Makefile index 14b93c0..45801ad 100644 --- a/applications/Makefile +++ b/applications/Makefile @@ -1,14 +1,12 @@ include ../config.mak -APPDIRS= mp4box mp4client testapps/mp4_streamer testapps/mp42ts -#APPDIRS= mp4client -ifeq ($(SRC_LOCAL_PATH), yes) -ifeq ($(TARGET_ARCH_ARMV4L), yes) -else -APPDIRS +=generators -endif +APPDIRS= mp4client + +ifeq ($(DISABLE_ISOFF), no) +APPDIRS += mp4box endif + V4STUDIODIR= INSTDIRS=mp4client ifeq ($(CONFIG_XUL),no) diff --git a/applications/generators/MPEG4/MPEG4Gen.dsp b/applications/generators/MPEG4/MPEG4Gen.dsp index 2339ae7..e5a7d9c 100644 --- a/applications/generators/MPEG4/MPEG4Gen.dsp +++ b/applications/generators/MPEG4/MPEG4Gen.dsp @@ -1,98 +1,98 @@ -# Microsoft Developer Studio Project File - Name="MPEG4Gen" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=MPEG4Gen - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "MPEG4Gen.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "MPEG4Gen.mak" CFG="MPEG4Gen - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "MPEG4Gen - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "MPEG4Gen - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "MPEG4Gen - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Obj/W32Rel" -# PROP Intermediate_Dir "Obj/W32Rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "MPEG4Gen - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Obj/W32Deb" -# PROP Intermediate_Dir "Obj/W32Deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "MPEG4Gen - Win32 Release" -# Name "MPEG4Gen - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\..\src\utils\list.c -# End Source File -# Begin Source File - -SOURCE=.\main.c -# End Source File -# End Group -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="MPEG4Gen" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=MPEG4Gen - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "MPEG4Gen.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "MPEG4Gen.mak" CFG="MPEG4Gen - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "MPEG4Gen - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "MPEG4Gen - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "MPEG4Gen - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Obj/W32Rel" +# PROP Intermediate_Dir "Obj/W32Rel" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "MPEG4Gen - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Obj/W32Deb" +# PROP Intermediate_Dir "Obj/W32Deb" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "MPEG4Gen - Win32 Release" +# Name "MPEG4Gen - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\utils\list.c +# End Source File +# Begin Source File + +SOURCE=.\main.c +# End Source File +# End Group +# End Target +# End Project diff --git a/applications/generators/MPEG4/MPEG4Gen.dsw b/applications/generators/MPEG4/MPEG4Gen.dsw index 15ce429..e3bd23b 100644 --- a/applications/generators/MPEG4/MPEG4Gen.dsw +++ b/applications/generators/MPEG4/MPEG4Gen.dsw @@ -1,29 +1,29 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "MPEG4Gen"=.\MPEG4Gen.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "MPEG4Gen"=.\MPEG4Gen.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/applications/generators/MPEG4/Makefile b/applications/generators/MPEG4/Makefile index 30405f9..3f38945 100644 --- a/applications/generators/MPEG4/Makefile +++ b/applications/generators/MPEG4/Makefile @@ -15,13 +15,12 @@ LDFLAGS+=-pg endif #common obj -OBJS= main.o ../../../src/utils/list.o ../../../src/utils/error.o +OBJS= main.o ifeq ($(CONFIG_WIN32),yes) EXE=.exe PROG=MPEG4Gen$(EXE) else -OBJS+=../../../src/utils/os_divers.o EXT= PROG=MPEG4Gen endif @@ -31,7 +30,7 @@ SRCS := $(OBJS:.o=.c) all: $(PROG) $(PROG): $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) $(EXTRALIBS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(EXTRALIBS) -L../../../bin/gcc -L../../../extra_lib/lib/gcc -lgpac %.o: %.c diff --git a/applications/generators/MPEG4/main.c b/applications/generators/MPEG4/main.c index 2b08f17..2dcac27 100644 --- a/applications/generators/MPEG4/main.c +++ b/applications/generators/MPEG4/main.c @@ -159,7 +159,7 @@ char *GetFixedPrintout(char *val) BField *BlankField() { - BField *n = malloc(sizeof(BField)); + BField *n = gf_malloc(sizeof(BField)); memset(n, 0, sizeof(BField)); return n; } @@ -167,7 +167,7 @@ BField *BlankField() BNode *BlankNode() { - BNode *n = malloc(sizeof(BNode)); + BNode *n = gf_malloc(sizeof(BNode)); memset(n, 0, sizeof(BNode)); n->NDT = gf_list_new(); n->Fields = gf_list_new(); @@ -194,7 +194,7 @@ void CheckInTable(char *token, GF_List *NDTs) p = gf_list_get(NDTs, i); if (!strcmp(p, token)) return; } - p = malloc(strlen(token)+1); + p = gf_malloc(strlen(token)+1); strcpy(p, token); gf_list_add(NDTs, p); } @@ -280,6 +280,8 @@ void WriteNodesFile(GF_List *BNodes, GF_List *NDTs, u32 NumVersions) f = BeginFile("nodes_mpeg4", 0); fprintf(f, "#include \n\n"); + fprintf(f, "#ifndef GPAC_DISABLE_VRML\n\n"); + //write all tags fprintf(f, "\n\nenum {\n"); @@ -318,8 +320,12 @@ void WriteNodesFile(GF_List *BNodes, GF_List *NDTs, u32 NumVersions) //write remaining fields //eventIn fields are handled as pointer to functions, called by the route manager if (!strcmp(bf->type, "eventIn")) { - fprintf(f, "\t%s %s;\t/*eventIn*/\n", bf->familly, bf->name); - fprintf(f, "\tvoid (*on_%s)(GF_Node *pThis);\t/*eventInHandler*/\n", bf->name); + if (strstr(bf->familly, "Node")) { + fprintf(f, "\tGF_Node *%s;\t/*eventIn*/\n",bf->name); + } else { + fprintf(f, "\t%s %s;\t/*eventIn*/\n", bf->familly, bf->name); + } + fprintf(f, "\tvoid (*on_%s)(GF_Node *pThis, struct _route *route);\t/*eventInHandler*/\n", bf->name); } else if (!strcmp(bf->type, "eventOut")) { //eventOut fields are handled as an opaque stack pointing to the route manager //this will be refined once the route is in place @@ -372,6 +378,7 @@ void WriteNodesFile(GF_List *BNodes, GF_List *NDTs, u32 NumVersions) } fprintf(f, "\tGF_BIFS_LAST_VERSION = GF_BIFS_V%d\n};\n\n", i); fprintf(f, "\n\n"); + fprintf(f, "#endif /*GPAC_DISABLE_VRML*/\n\n"); EndFile(f, "nodes_mpeg4", 0); @@ -703,7 +710,7 @@ void WriteNodeFields(FILE *f, BNode *n) fprintf(f, "\tcase %d:\n", i); - fprintf(f, "\t\tinfo->name = \"%s\";\n", bf->name); + fprintf(f, "\t\tinfo->name = \"%s\";\n", (bf->name[0]=='_') ? bf->name+1 : bf->name); //skip all eventIn if (!strcmp(bf->type, "eventIn")) { @@ -744,7 +751,7 @@ void WriteNodeFields(FILE *f, BNode *n) fprintf(f, "\nstatic s32 %s_get_field_index_by_name(char *name)\n{\n", n->name); for (i=0;iFields); i++) { bf = gf_list_get(n->Fields, i); - fprintf(f, "\tif (!strcmp(\"%s\", name)) return %d;\n", bf->name, i); + fprintf(f, "\tif (!strcmp(\"%s\", name)) return %d;\n", (bf->name[0]=='_') ? bf->name+1 : bf->name, i); } fprintf(f, "\treturn -1;\n\t}\n"); } @@ -803,6 +810,9 @@ void WriteNodeCode(GF_List *BNodes) fprintf(f, "#include \n\n"); fprintf(f, "\n#include \n"); + fprintf(f, "\n#ifndef GPAC_DISABLE_VRML\n"); + + for (k=0; kfamilly, "SFInt32")) { fprintf(f, "\tp->%s = %s;\n", bf->name, bf->def); } + //SFURL + else if (!strcmp(bf->familly, "SFURL")) { + if (strcmp(bf->def, "NULL")) + fprintf(f, "\tp->%s = %s;\n", bf->name, bf->def); + } //SFColor else if (!strcmp(bf->familly, "SFColor")) { CurrentLine = bf->def; @@ -1005,7 +1020,7 @@ void WriteNodeCode(GF_List *BNodes) } //SFString else if (!strcmp(bf->familly, "SFString")) { - fprintf(f, "\tp->%s.buffer = (char*)malloc(sizeof(char) * %d);\n", bf->name, strlen(bf->def)+1); + fprintf(f, "\tp->%s.buffer = (char*)gf_malloc(sizeof(char) * %d);\n", bf->name, strlen(bf->def)+1); fprintf(f, "\tstrcpy(p->%s.buffer, \"%s\");\n", bf->name, bf->def); } @@ -1018,7 +1033,7 @@ void WriteNodeCode(GF_List *BNodes) CurrentLine = bf->def; while (GetNextToken(token, " ,")) j++; j+=1; - fprintf(f, "\tp->%s.vals = (SFFloat*)malloc(sizeof(SFFloat)*%d);\n", bf->name, j); + fprintf(f, "\tp->%s.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*%d);\n", bf->name, j); fprintf(f, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -1036,7 +1051,7 @@ void WriteNodeCode(GF_List *BNodes) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(f, "\tp->%s.vals = (SFVec2f*)malloc(sizeof(SFVec2f)*%d);\n", bf->name, j); + fprintf(f, "\tp->%s.vals = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*%d);\n", bf->name, j); fprintf(f, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -1061,7 +1076,7 @@ void WriteNodeCode(GF_List *BNodes) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(f, "\tp->%s.vals = (SFVec3f *)malloc(sizeof(SFVec3f)*%d);\n", bf->name, j); + fprintf(f, "\tp->%s.vals = (SFVec3f *)gf_malloc(sizeof(SFVec3f)*%d);\n", bf->name, j); fprintf(f, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -1089,7 +1104,7 @@ void WriteNodeCode(GF_List *BNodes) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(f, "\tp->%s.vals = (GF_Vec4*)malloc(sizeof(GF_Vec4)*%d);\n", bf->name, j); + fprintf(f, "\tp->%s.vals = (GF_Vec4*)gf_malloc(sizeof(GF_Vec4)*%d);\n", bf->name, j); fprintf(f, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -1120,7 +1135,7 @@ void WriteNodeCode(GF_List *BNodes) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(f, "\tp->%s.vals = (SFInt32*)malloc(sizeof(SFInt32)*%d);\n", bf->name, j); + fprintf(f, "\tp->%s.vals = (SFInt32*)gf_malloc(sizeof(SFInt32)*%d);\n", bf->name, j); fprintf(f, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -1141,7 +1156,7 @@ void WriteNodeCode(GF_List *BNodes) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(f, "\tp->%s.vals = (SFColor*)malloc(sizeof(SFColor)*%d);\n", bf->name, j); + fprintf(f, "\tp->%s.vals = (SFColor*)gf_malloc(sizeof(SFColor)*%d);\n", bf->name, j); fprintf(f, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -1166,7 +1181,7 @@ void WriteNodeCode(GF_List *BNodes) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(f, "\tp->%s.vals = (char**)malloc(sizeof(SFString)*%d);\n", bf->name, j); + fprintf(f, "\tp->%s.vals = (char**)gf_malloc(sizeof(SFString)*%d);\n", bf->name, j); fprintf(f, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -1176,7 +1191,7 @@ void WriteNodeCode(GF_List *BNodes) store = CurrentLine; CurrentLine = token; GetNextToken(tok, " \""); - fprintf(f, "\tp->%s.vals[%d] = (char*)malloc(sizeof(char) * %d);\n", bf->name, j, strlen(tok)+1); + fprintf(f, "\tp->%s.vals[%d] = (char*)gf_malloc(sizeof(char) * %d);\n", bf->name, j, strlen(tok)+1); fprintf(f, "\tstrcpy(p->%s.vals[%d], \"%s\");\n", bf->name, j, tok); j+=1; CurrentLine = store; @@ -1188,7 +1203,7 @@ void WriteNodeCode(GF_List *BNodes) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(f, "\tp->%s.vals = (SFTime*)malloc(sizeof(SFTime)*%d);\n", bf->name, j); + fprintf(f, "\tp->%s.vals = (SFTime*)gf_malloc(sizeof(SFTime)*%d);\n", bf->name, j); fprintf(f, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -1310,6 +1325,7 @@ void WriteNodeCode(GF_List *BNodes) } fprintf(f, "\tdefault:\n\t\treturn -1;\n\t}\n}\n\n"); + fprintf(f, "\n#endif /*GPAC_DISABLE_VRML*/\n"); EndFile(f, "", 1); } @@ -1361,7 +1377,7 @@ void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs, u32 version) //update the NDT list CheckInTable(token, NDTs); - p = malloc(strlen(token)+1); + p = gf_malloc(strlen(token)+1); strcpy(p, token); gf_list_add(n->NDT, p); } @@ -1398,6 +1414,7 @@ void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs, u32 version) GetNextToken(f->name, " \t"); //fix for our own code :( if (!strcmp(f->name, "tag")) strcpy(f->name, "_tag"); + if (!strcmp(f->name, "auto")) strcpy(f->name, "_auto"); //has default skip_sep(" \t"); @@ -1611,7 +1628,10 @@ int main (int argc, char **argv) ndt_c = BeginFile("NDT", 1); fprintf(ndt_h, "#include \n\n"); + fprintf(ndt_h, "\n\n#ifndef GPAC_DISABLE_BIFS\n"); + fprintf(ndt_c, "\n\n#include \n"); + fprintf(ndt_c, "\n\n#ifndef GPAC_DISABLE_BIFS\n"); //prepare the encoding file fprintf(ndt_h, "\n\nu32 ALL_GetNodeType(const u32 *table, const u32 count, u32 NodeTag, u32 Version);\n\n"); @@ -1665,14 +1685,16 @@ int main (int argc, char **argv) } } fprintf(ndt_c, "\tdefault:\n\t\treturn 0;\n\t}\n}\n\n"); + fprintf(ndt_c, "\n\n#endif /*GPAC_DISABLE_BIFS*/\n\n"); + fprintf(ndt_h, "\n\n#endif /*GPAC_DISABLE_BIFS*/\n\n"); EndFile(ndt_h, "NDT", 0); EndFile(ndt_c, "", 1); //free NDTs while (gf_list_count(NDTs)) { char *tmp = gf_list_get(NDTs, 0); - free(tmp); + gf_free(tmp); gf_list_rem(NDTs, 0); } gf_list_del(NDTs); @@ -1682,17 +1704,17 @@ int main (int argc, char **argv) gf_list_rem(BNodes, 0); while (gf_list_count(n->NDT)) { char *tmp = gf_list_get(n->NDT, 0); - free(tmp); + gf_free(tmp); gf_list_rem(n->NDT, 0); } gf_list_del(n->NDT); while (gf_list_count(n->Fields)) { bf = gf_list_get(n->Fields, 0); - free(bf); + gf_free(bf); gf_list_rem(n->Fields, 0); } gf_list_del(n->Fields); - free(n); + gf_free(n); } gf_list_del(BNodes); diff --git a/applications/generators/MPEG4/templates10.txt b/applications/generators/MPEG4/templates10.txt new file mode 100644 index 0000000..70b3d0c --- /dev/null +++ b/applications/generators/MPEG4/templates10.txt @@ -0,0 +1,53 @@ +PROTO CacheTexture [#%NDT=SFWorldNode,SF2DNode,SF3DNode,SFTextureNode %COD=N +field SFInt32 objectTypeIndication 0 +field SFString decoderSpecificInfo "" +field SFString image "" +field SFString cacheURL "" +field MFURL cacheOD [] +field SFInt32 expirationDate 0 +field SFBool repeatS TRUE +field SFBool repeatT TRUE +]{} + +PROTO EnvironmentTest [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N +eventIn SFBool evaluate +exposedField SFBool enabled TRUE +exposedField SFInt32 parameter 0 +exposedField SFString compareValue "" +exposedField SFBool evaluateOnChange TRUE +eventOut SFBool valueLarger +eventOut SFBool valueEqual +eventOut SFBool valueSmaller +eventOut SFString parameterValue +] {} + + +PROTO KeyNavigator [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N +eventIn SFBool setFocus +exposedField SF3DNode sensor NULL +exposedField SF2DNode left NULL +exposedField SF2DNode right NULL +exposedField SF2DNode up NULL +exposedField SF2DNode down NULL +exposedField SF2DNode select NULL +exposedField SF2DNode quit NULL +exposedField SFFloat step 0 +eventOut SFBool focusSet +]{} + +PROTO SpacePartition [ #%NDT=SFWorldNode,SF3DNode %COD=N +eventIn MF3DNode addChildren +eventIn MF3DNode removeChildren +exposedField MF3DNode children [] +exposedField SFUrl SPStream NULL +]{} + +PROTO Storage [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N +eventIn SFBool forceSave +eventIn SFBool forceRestore +exposedField SFBool auto TRUE +field SFInt32 expireAfter 0 +field SFString name "" +field MFAttrRef storageList [] +]{} + diff --git a/applications/generators/MPEG4/templates8.txt b/applications/generators/MPEG4/templates8.txt new file mode 100644 index 0000000..93f2a87 --- /dev/null +++ b/applications/generators/MPEG4/templates8.txt @@ -0,0 +1,124 @@ +#-- Version 8 --# +# +# Beta for Symbolic Music Representation (SMR) +# +# templates for the BIFS nodes +# ============================= +# Notations I = Infinity +# %q=x Quantization method x +# 0 None +# 1 3D Position (SFVec3F) +# 2 2D Position (SFVec2F) +# 3 drawing Order +# 4 Color (SFColor) +# 5 Texture Coordinate +# 6 Angle (SFFloat 0-2PI) +# 7 Scale (SFVec2F or SFVec3F) +# 8 Interpolators keys +# 9 Normals +# 10 Rotations (SFRotation) +# 11 Object Size 3D (SFVec3F and SFFloat) +# 12 Object Size 2D +# 13 Linear Quantization (+ Nb Bits) +# 14 Index (of IndexedFaceSet,...) +# 15 SFVec4f +# 16 Reserved +# +# %a=y Animation method for fields that can be animated +# +## OO 081498 To match BIFS's update numbering +# 0 None +# 1 Position 3D +# 2 Position 2D +# 4 Color +# 6 Angle +# 7 Float +# 8 BoundFloat (intensities, transparencies,...) +# 9 Normal +# 10 Rotation +# 11 Size 3D +# 12 Size 2D +# 13 Integer +# 14 Reserved +## 0 3D Position +## 1 2D positon +## 2 Color (SFColor) +## 3 Angle (SFFloat 0-2pi) +## 4 Normals +## 5 Scale (SFVec2F) +## 6 Rotation (SFRotation) +## 7 Object Size or Scalar (SFFloat) +# +# %b=[min,max] bounds of value +# For each scalar or vectorial value, bounds may be specified. +# This will be used to check if user-specified values are out of bounds. In +# this case, bounds specified in the templates will be used (if not infinity). +# +# %NDT=Node Data Type +# For each node, one or several Node Data Types are assigned, specifying which node sub +# types the node belongs to. Moreover, each field of type SF/MF3DNode is re assigned +# a unique correct NodeDataType according to specify the allowed values of the field +# +# %COD Type of encoding +# N Normal Syntax : The node syntax follos the generic syntax for nodes +# S Special Syntax : The node has a specific syntax +# +# +# NCT => VRML type equivalence +# +# SF/MFxxxNode => SF/MFNode +# SF/MFURL => SF/MFString +# SF/MFCommandBuffer => SF/MFString +# SF/MFScript => SF/MFString +# +# +# Modification History +# ------------------------------------------------ +# October 9, 2006 [MBS] Added SMR nodes based on w8121 + +# +# Symbolic Music Representation (SMR) nodes +# + + +PROTO ScoreShape [ #%NDT=SFWorldNode,SF2DNode,SF3DNode %COD=N +exposedField SFMusicScoreNode score NULL +exposedField SFNode geometry NULL +]{} + + +PROTO MusicScore [ #%NDT=SFWorldNode,SFMusicScoreNode %COD=N +eventIn SFBool executeCommand +eventIn SFString gotoLabel +eventIn SFInt32 gotoMeasure +eventIn SFTime highlightTimePosition +eventIn SFVec3f mousePosition +exposedField MFString argumentsOnExecute [] +exposedField SFString commandOnExecute "" +exposedField SFInt32 firstVisibleMeasure 0 +exposedField SFBool hyperlinkEnable TRUE +exposedField SFBool loop FALSE +exposedField MFString partsLyrics [] +exposedField MFInt32 partsShown [] +exposedField SFTime scoreOffset 0.0 +exposedField SFVec2f size -1, -1 +exposedField SFFloat speed 1.0 #%b=(-I,+I) #%q=0 #%a=7 +exposedField SFTime startTime 0 #%b=(-I,+I) +exposedField SFTime stopTime 0 #%b=(-I,+I) +exposedField SFFloat transpose 0.0 +exposedField MFURL url [] +exposedField MFURL urlSA [] +exposedField SFString viewType "" +eventOut SFString activatedLink +eventOut MFString availableCommands +eventOut MFString availableLabels +eventOut MFString availableLyricLanguages +eventOut MFString availableViewTypes +eventOut SFBool isActive +eventOut SFVec3f highlightPosition +eventOut SFInt32 lastVisibleMeasure +eventOut SFInt32 numMeasures +eventOut MFString partNames +]{} + + diff --git a/applications/generators/MPEG4/templates9.txt b/applications/generators/MPEG4/templates9.txt new file mode 100644 index 0000000..465437b --- /dev/null +++ b/applications/generators/MPEG4/templates9.txt @@ -0,0 +1,68 @@ +PROTO FootPrintSetNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N +exposedField MFGeometryNode children [] +]{} + +PROTO FootPrintNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N + +exposedField SFInt32 index -1 #%b=[0,65535] +exposedField SFGeometryNode footprint NULL +]{} + +PROTO BuildingPartNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N + +exposedField SFInt32 index -1 #%b=[0,65535] +exposedField SFGeometryNode footprint NULL +exposedField SFInt32 buildingIndex -1 #%b=[0,65535] +exposedField SFFloat height 0 #%b=[0,I] +exposedField SFFloat altitude 0 #%b=[0,I] +exposedField MFGeometryNode alternativeGeometry [] +exposedField MFGeometryNode roofs [] +exposedField MFGeometryNode facades [] +]{} + + + +PROTO RoofNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N + +exposedField SFInt32 Type 0 #%b=[0,65535] +exposedField SFFloat Height 0.0 #%b=[0,I] +exposedField MFFloat SlopeAngle [0.0] #%b=[0,6.2831854] +exposedField SFFloat EaveProjection 0.0 +exposedField SFInt32 EdgeSupportIndex -1 #%b=[0,65535] +exposedField SFURL RoofTextureURL "" +exposedField SFBool IsGenericTexture TRUE +exposedField SFFloat TextureXScale 1.0 #%b=[0,I] +exposedField SFFloat TextureYScale 1.0 #%b=[0,I] +exposedField SFFloat TextureXPosition 0.0 #%b=[0,I] +exposedField SFFloat TextureYPosition 0.0 #%b=[0,I] +exposedField SFFloat TextureRotation 0.0 #%b=[0,I] +]{} + + + +PROTO FacadeNode [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N +exposedField SFFloat WidthRatio 1.0 #%b=[-I,I] +exposedField SFFloat XScale 1.0 #%b=[-I,I] +exposedField SFFloat YScale 1.0 #%b=[-I,I] +exposedField SFFloat XPosition 0.0 #%b=[-I,I] +exposedField SFFloat YPosition 0.0 #%b=[-I,I] +exposedField SFFloat XRepeatInterval 0.0 #%b=[-I,I] +exposedField SFFloat YRepeatInterval 0.0 #%b=[-I,I] +exposedField SFBool Repeat FALSE +exposedField SFURL FacadePrimitive "" +exposedField SFInt32 NbStories 0 #%b=[0,65535] +exposedField MFInt32 NbFacadeCellsByStorey 0 +exposedField MFFloat StoreyHeight 1.0 #%b=[0,I] +exposedField MFGeometryNode FacadeCellsArray [] +]{} + + +PROTO Shadow [#%NDT=SFWorldNode,SF3DNode,SFGeometryNode %COD=N +eventIn SF3DNode addChildren +eventIn SF3DNode removeChildren +exposedField MF3DNode children [] +exposedField SFBool enabled TRUE +exposedField SFBool cast TRUE +exposedField SFBool receive TRUE +exposedField SFFloat penumbra 0 #%b=[0,I] +]{} diff --git a/applications/generators/SVG/Makefile b/applications/generators/SVG/Makefile index a634751..e55a40c 100644 --- a/applications/generators/SVG/Makefile +++ b/applications/generators/SVG/Makefile @@ -15,7 +15,7 @@ LDFLAGS+=-pg endif #common obj -OBJS= html.o laser.o main.o v1.o v2.o v3.o ../../../src/utils/list.o ../../../src/utils/error.o +OBJS= html.o laser.o main.o v1.o v2.o v3.o CFLAGS+=-g LDFLAGS+=-g @@ -35,7 +35,7 @@ SRCS := $(OBJS:.o=.c) all: $(PROG) SVGGen$(EXE): $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) $(XML2_LFLAGS) $(EXTRALIBS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(XML2_LIBS) $(EXTRALIBS) -L../../../bin/gcc -L../../../extra_lib/lib/gcc -lgpac -lz %.o: %.c diff --git a/applications/generators/SVG/SVGGen.dsp b/applications/generators/SVG/SVGGen.dsp index 8d95fcb..c76b774 100644 --- a/applications/generators/SVG/SVGGen.dsp +++ b/applications/generators/SVG/SVGGen.dsp @@ -1,126 +1,126 @@ -# Microsoft Developer Studio Project File - Name="SVGGen" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=SVGGen - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "SVGGen.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "SVGGen.mak" CFG="SVGGen - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "SVGGen - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "SVGGen - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "SVGGen - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 libxml2.lib zlib.lib iconv.lib /nologo /subsystem:console /machine:I386 /libpath:"../../../extra_lib/lib/w32_release" - -!ELSEIF "$(CFG)" == "SVGGen - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 libxml2.lib zlib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "SVGGen - Win32 Release" -# Name "SVGGen - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\..\src\utils\error.c -# End Source File -# Begin Source File - -SOURCE=.\html.c -# End Source File -# Begin Source File - -SOURCE=.\laser.c -# End Source File -# Begin Source File - -SOURCE=..\..\..\src\utils\list.c -# End Source File -# Begin Source File - -SOURCE=.\main.c -# End Source File -# Begin Source File - -SOURCE=.\v1.c -# End Source File -# Begin Source File - -SOURCE=.\v2.c -# End Source File -# Begin Source File - -SOURCE=.\v3.c -# End Source File -# End Group -# Begin Source File - -SOURCE=.\svggen.h -# End Source File -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="SVGGen" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=SVGGen - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "SVGGen.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "SVGGen.mak" CFG="SVGGen - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "SVGGen - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "SVGGen - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "SVGGen - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 libxml2.lib zlib.lib iconv.lib /nologo /subsystem:console /machine:I386 /libpath:"../../../extra_lib/lib/w32_release" + +!ELSEIF "$(CFG)" == "SVGGen - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include/" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 libxml2.lib zlib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" + +!ENDIF + +# Begin Target + +# Name "SVGGen - Win32 Release" +# Name "SVGGen - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\utils\error.c +# End Source File +# Begin Source File + +SOURCE=.\html.c +# End Source File +# Begin Source File + +SOURCE=.\laser.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\src\utils\list.c +# End Source File +# Begin Source File + +SOURCE=.\main.c +# End Source File +# Begin Source File + +SOURCE=.\v1.c +# End Source File +# Begin Source File + +SOURCE=.\v2.c +# End Source File +# Begin Source File + +SOURCE=.\v3.c +# End Source File +# End Group +# Begin Source File + +SOURCE=.\svggen.h +# End Source File +# End Target +# End Project diff --git a/applications/generators/SVG/SVGGen.dsw b/applications/generators/SVG/SVGGen.dsw index 170c054..1b31b26 100644 --- a/applications/generators/SVG/SVGGen.dsw +++ b/applications/generators/SVG/SVGGen.dsw @@ -1,29 +1,29 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "SVGGen"=.\SVGGen.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "SVGGen"=.\SVGGen.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/applications/generators/SVG/main.c b/applications/generators/SVG/main.c index e448d93..fa51fa1 100644 --- a/applications/generators/SVG/main.c +++ b/applications/generators/SVG/main.c @@ -35,7 +35,7 @@ void deleteSVGGenAttribute(SVGGenAttribute **p) { xmlFree((*p)->svg_name); xmlFree((*p)->svg_type); - free(*p); + gf_free(*p); *p = NULL; } @@ -68,7 +68,7 @@ void deleteSVGGenElement(SVGGenElement **p) deleteSVGGenAttribute(&a); } gf_list_del((*p)->attributes); - free(*p); + gf_free(*p); *p = NULL; } @@ -631,7 +631,7 @@ SVGGenAttrGrp *getOneGlobalAttrGrp(xmlDocPtr doc, xmlXPathContextPtr xpathCtx, x return NULL; } attgrp = NewSVGGenAttrGrp(); - attgrp->name = strdup(name); + attgrp->name = gf_strdup(name); svgNameToImplementationName(attgrp->name, attgrp->imp_name); gf_list_add(globalAttrGrp, attgrp); diff --git a/applications/generators/X3D/Makefile b/applications/generators/X3D/Makefile index 224779c..4274cb5 100644 --- a/applications/generators/X3D/Makefile +++ b/applications/generators/X3D/Makefile @@ -15,13 +15,12 @@ LDFLAGS+=-pg endif #common obj -OBJS= main.o ../../../src/utils/list.o ../../../src/utils/error.o +OBJS= main.o ifeq ($(CONFIG_WIN32),yes) EXE=.exe PROG=X3DGen$(EXE) else -OBJS+=../../../src/utils/os_divers.o EXT= PROG=X3DGen endif @@ -31,7 +30,7 @@ SRCS := $(OBJS:.o=.c) all: $(PROG) $(PROG): $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) $(EXTRALIBS) + $(CC) $(LDFLAGS) -o $@ $(OBJS) $(EXTRALIBS) -L../../../bin/gcc -L../../../extra_lib/lib/gcc -lgpac %.o: %.c diff --git a/applications/generators/X3D/X3DGen.dsp b/applications/generators/X3D/X3DGen.dsp index b16b8dd..7afd243 100644 --- a/applications/generators/X3D/X3DGen.dsp +++ b/applications/generators/X3D/X3DGen.dsp @@ -1,98 +1,98 @@ -# Microsoft Developer Studio Project File - Name="X3DGen" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=X3DGen - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "X3DGen.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "X3DGen.mak" CFG="X3DGen - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "X3DGen - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "X3DGen - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "X3DGen - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "X3DGen - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Obj/W32Deb" -# PROP Intermediate_Dir "Obj/W32Deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "X3DGen - Win32 Release" -# Name "X3DGen - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\..\src\utils\list.c -# End Source File -# Begin Source File - -SOURCE=.\main.c -# End Source File -# End Group -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="X3DGen" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=X3DGen - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "X3DGen.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "X3DGen.mak" CFG="X3DGen - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "X3DGen - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "X3DGen - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "X3DGen - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "X3DGen - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Obj/W32Deb" +# PROP Intermediate_Dir "Obj/W32Deb" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "X3DGen - Win32 Release" +# Name "X3DGen - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\..\src\utils\list.c +# End Source File +# Begin Source File + +SOURCE=.\main.c +# End Source File +# End Group +# End Target +# End Project diff --git a/applications/generators/X3D/X3DGen.dsw b/applications/generators/X3D/X3DGen.dsw index 2c265c5..2aca071 100644 --- a/applications/generators/X3D/X3DGen.dsw +++ b/applications/generators/X3D/X3DGen.dsw @@ -1,29 +1,29 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "X3DGen"=.\X3DGen.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "X3DGen"=.\X3DGen.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/applications/generators/X3D/main.c b/applications/generators/X3D/main.c index 023876f..22954ae 100644 --- a/applications/generators/X3D/main.c +++ b/applications/generators/X3D/main.c @@ -126,7 +126,7 @@ u32 GetNextToken(char *token, char *sep) X3DField *BlankField() { - X3DField *n = malloc(sizeof(X3DField)); + X3DField *n = gf_malloc(sizeof(X3DField)); memset(n, 0, sizeof(X3DField)); return n; } @@ -134,7 +134,7 @@ X3DField *BlankField() X3DNode *BlankNode() { - X3DNode *n = malloc(sizeof(X3DNode)); + X3DNode *n = gf_malloc(sizeof(X3DNode)); memset(n, 0, sizeof(X3DNode)); n->NDT = gf_list_new(); n->Fields = gf_list_new(); @@ -161,7 +161,7 @@ void CheckInTable(char *token, GF_List *NDTs) p = gf_list_get(NDTs, i); if (!strcmp(p, token)) return; } - p = malloc(strlen(token)+1); + p = gf_malloc(strlen(token)+1); strcpy(p, token); gf_list_add(NDTs, p); } @@ -226,6 +226,7 @@ void WriteNodesFile(GF_List *BNodes, GF_List *NDTs) f = BeginFile(0); fprintf(f, "#include \n\n"); + fprintf(f, "#ifndef GPAC_DISABLE_X3D\n\n"); //write all tags fprintf(f, "\n\nenum {\n"); @@ -272,11 +273,12 @@ void WriteNodesFile(GF_List *BNodes, GF_List *NDTs) fprintf(f, "\t%s %s;\t/*%s*/\n", bf->familly, bf->name, bf->type); } if (!strcmp(bf->type, "eventIn")) - fprintf(f, "\tvoid (*on_%s)(GF_Node *pThis);\t/*eventInHandler*/\n", bf->name); + fprintf(f, "\tvoid (*on_%s)(GF_Node *pThis, struct _route *route);\t/*eventInHandler*/\n", bf->name); } fprintf(f, "} X_%s;\n\n\n", n->name); } + fprintf(f, "#endif /*GPAC_DISABLE_X3D*/\n\n"); EndFile(f, 0); } @@ -350,6 +352,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) fprintf(vrml_code, "\n#include \n"); fprintf(vrml_code, "\n#include \n"); fprintf(vrml_code, "\n/*for NDT tag definitions*/\n#include \n"); + fprintf(vrml_code, "#ifndef GPAC_DISABLE_X3D\n\n"); for (k=0; kfamilly, "SFString")) { - fprintf(vrml_code, "\tp->%s.buffer = (char*) malloc(sizeof(char) * %d);\n", bf->name, strlen(bf->def)+1); + fprintf(vrml_code, "\tp->%s.buffer = (char*) gf_malloc(sizeof(char) * %d);\n", bf->name, strlen(bf->def)+1); fprintf(vrml_code, "\tstrcpy(p->%s.buffer, \"%s\");\n", bf->name, bf->def); } @@ -575,7 +578,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, " ,")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (SFFloat *)malloc(sizeof(SFFloat)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (SFFloat *)gf_malloc(sizeof(SFFloat)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -593,7 +596,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, " ,")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (SFFloat*)malloc(sizeof(SFFloat)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -611,7 +614,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (SFVec2f*) malloc(sizeof(SFVec2f)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (SFVec2f*) gf_malloc(sizeof(SFVec2f)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -636,7 +639,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (SFVec2f*)malloc(sizeof(SFVec2f)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -661,7 +664,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (SFVec3f*)malloc(sizeof(SFVec3f)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (SFVec3f*)gf_malloc(sizeof(SFVec3f)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -689,7 +692,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (SFVec2f*)malloc(sizeof(SFVec3f)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (SFVec2f*)gf_malloc(sizeof(SFVec3f)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -717,7 +720,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (GF_Vec4*)malloc(sizeof(GF_Vec4)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (GF_Vec4*)gf_malloc(sizeof(GF_Vec4)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -748,7 +751,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (SFInt32*)malloc(sizeof(SFInt32)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (SFInt32*)gf_malloc(sizeof(SFInt32)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -769,7 +772,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (SFColor*)malloc(sizeof(SFColor)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (SFColor*)gf_malloc(sizeof(SFColor)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -794,7 +797,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (char**)malloc(sizeof(SFString)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (char**)gf_malloc(sizeof(SFString)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -804,7 +807,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) store = CurrentLine; CurrentLine = token; GetNextToken(tok, " \""); - fprintf(vrml_code, "\tp->%s.vals[%d] = (char*)malloc(sizeof(char) * %d);\n", bf->name, j, strlen(tok)+1); + fprintf(vrml_code, "\tp->%s.vals[%d] = (char*)gf_malloc(sizeof(char) * %d);\n", bf->name, j, strlen(tok)+1); fprintf(vrml_code, "\tstrcpy(p->%s.vals[%d], \"%s\");\n", bf->name, j, tok); j+=1; CurrentLine = store; @@ -816,7 +819,7 @@ void WriteNodeCode(GF_List *BNodes, FILE *vrml_code) CurrentLine = bf->def; while (GetNextToken(token, ",")) j++; j+=1; - fprintf(vrml_code, "\tp->%s.vals = (SFTime*)malloc(sizeof(SFTime)*%d);\n", bf->name, j); + fprintf(vrml_code, "\tp->%s.vals = (SFTime*)gf_malloc(sizeof(SFTime)*%d);\n", bf->name, j); fprintf(vrml_code, "\tp->%s.count = %d;\n", bf->name, j); j = 0; go = 1; @@ -1021,7 +1024,7 @@ void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs) //update the NDT list CheckInTable(token, NDTs); - p = malloc(strlen(token)+1); + p = gf_malloc(strlen(token)+1); strcpy(p, token); gf_list_add(n->NDT, p); } @@ -1101,7 +1104,7 @@ void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs) case 'a': printf("Corrupted X3D template file (quantization/animation not allowed)\n"); gf_list_del_item(n->Fields, f); - free(f); + gf_free(f); return; default: break; @@ -1110,7 +1113,7 @@ void ParseTemplateFile(FILE *nodes, GF_List *BNodes, GF_List *NDTs) /*we ignore these*/ if (!stricmp(f->name, "bboxCenter") || !stricmp(f->name, "bboxSize")) { gf_list_del_item(n->Fields, f); - free(f); + gf_free(f); } } } @@ -1234,13 +1237,14 @@ int main (int argc, char **argv) WriteNodeCode(XNodes, nodes); WriteNDT(nodes, XNodes, NDTs); + fprintf(nodes, "#endif /*GPAC_DISABLE_X3D*/\n\n"); EndFile(nodes, 1); //free NDTs while (gf_list_count(NDTs)) { char *tmp = gf_list_get(NDTs, 0); - free(tmp); + gf_free(tmp); gf_list_rem(NDTs, 0); } gf_list_del(NDTs); @@ -1254,17 +1258,17 @@ int main (int argc, char **argv) gf_list_rem(XNodes, 0); while (gf_list_count(n->NDT)) { char *tmp = gf_list_get(n->NDT, 0); - free(tmp); + gf_free(tmp); gf_list_rem(n->NDT, 0); } gf_list_del(n->NDT); while (gf_list_count(n->Fields)) { bf = gf_list_get(n->Fields, 0); - free(bf); + gf_free(bf); gf_list_rem(n->Fields, 0); } gf_list_del(n->Fields); - free(n); + gf_free(n); } gf_list_del(XNodes); diff --git a/applications/m3u82mpd/main.c b/applications/m3u82mpd/main.c new file mode 100644 index 0000000..c378f67 --- /dev/null +++ b/applications/m3u82mpd/main.c @@ -0,0 +1,116 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Telecom ParisTech 2010 - + * All rights reserved + * + * This file is part of GPAC / m3u82mpd application + * + * GPAC is gf_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 "../modules/m3u8_in/playlist.h" +#include "../modules/m3u8_in/m3u8_parser.h" +#include + +int main(int argc, char **argv) +{ + GF_Err e; + VariantPlaylist * pl = NULL; + char *url = argv[1]; + char *cache_m3u8_file; + u32 i, count; + FILE *fmpd; + Bool verbose = 0; + u32 update_interval = 0; + char *m3u8_local_name = "file.m3u8"; + Bool is_local = 0; + + gf_sys_init(0); + + gf_log_set_level(verbose ? GF_LOG_DEBUG : GF_LOG_INFO); + gf_log_set_tools(GF_LOG_NETWORK); + + while (1) { + + if (gf_url_is_local(url)) { + m3u8_local_name = url; + is_local = 1; + } else { + e = gf_dm_wget(url, m3u8_local_name); + if (e != GF_OK) return -1; + } + + e = parse_root_playlist(m3u8_local_name, &pl, "."); + if (e != GF_OK) return -1; + + fmpd = fopen(argv[2], "wt"); + + fprintf(fmpd, "\n"); + fprintf(fmpd, " \n"); + fprintf(fmpd, " Media Presentation Description for file %s\n", url); + fprintf(fmpd, " Generated by GPAC %s\n", GPAC_FULL_VERSION); + + fprintf(fmpd, " \n"); + fprintf(fmpd, " \n"); + + count = gf_list_count(pl->programs); + for (i=0; iprograms, i); + count2 = gf_list_count(prog->bitrates); + for (j = 0; jbitrates, j); + fprintf(stdout, "%d, %d, %s, %s, %d\n", pe->durationInfo, pe->bandwidth, pe->title, pe->url, pe->elementType); + if (pe->elementType == TYPE_PLAYLIST) { + u32 k, count3; + char *tmp; + char c; + char baseURL[GF_MAX_PATH]; + tmp = strrchr(url, '/'); + tmp++; + c = tmp[0]; + tmp[0] = 0; + strcpy(baseURL, url); + tmp[0] = c; + fprintf(fmpd, " \n"); + fprintf(fmpd, " \n", pe->durationInfo, baseURL); + count3 = gf_list_count(pe->element.playlist.elements); + update_interval = (count3 - 1) * pe->durationInfo * 1000; + for (k=0; kelement.playlist.elements, k); + if (k) fprintf(fmpd, " \n", elt->url); + else fprintf(fmpd, " \n", elt->url); + } + fprintf(fmpd, " \n"); + fprintf(fmpd, " \n"); + } else if (pe->elementType == TYPE_STREAM) { + fprintf(stdout, "Stream\n"); + } + } + } + fprintf(fmpd, " \n"); + fprintf(fmpd, ""); + fclose(fmpd); + variant_playlist_del(pl); + if (is_local) break; + gf_sleep(update_interval); + + } + + gf_sys_close(); + return 0; +} diff --git a/applications/mp42avi/main.c b/applications/mp42avi/main.c index fa75d56..de19cc4 100644 --- a/applications/mp42avi/main.c +++ b/applications/mp42avi/main.c @@ -496,11 +496,11 @@ void bifs3d_viewpoints_merger(GF_ISOFile *file, char *szConfigFile, u32 width, u err_exit: /* if (rendered_frames) { for (viewpoint_index = 1; viewpoint_index <= nb_viewpoints; viewpoint_index++) { - if (rendered_frames[viewpoint_index-1]) free(rendered_frames[viewpoint_index-1]); + if (rendered_frames[viewpoint_index-1]) gf_free(rendered_frames[viewpoint_index-1]); } - free(rendered_frames); + gf_free(rendered_frames); } - if (output_merged_frame) free(output_merged_frame); + if (output_merged_frame) gf_free(output_merged_frame); */ if (user.modules) gf_modules_del(user.modules); if (needs_raw) gf_cfg_set_key(user.config, "Video", "DriverName", old_driv); @@ -655,7 +655,7 @@ void bifs_to_vid(GF_ISOFile *file, char *szConfigFile, u32 width, u32 height, ch height = fb.height; if (avi_out) { AVI_set_video(avi_out, width, height, fps, comp); - conv_buf = malloc(sizeof(char) * width * height * 3); + conv_buf = gf_malloc(sizeof(char) * width * height * 3); } printf("Dumping at BIFS resolution %d x %d\n\n", width, height); gf_sc_release_screen_buffer(b2v.sr, &fb); @@ -713,7 +713,7 @@ void bifs_to_vid(GF_ISOFile *file, char *szConfigFile, u32 width, u32 height, ch err_exit: if (avi_out) AVI_close(avi_out); - if (conv_buf) free(conv_buf); + if (conv_buf) gf_free(conv_buf); if (user.modules) gf_modules_del(user.modules); if (needs_raw) gf_cfg_set_key(user.config, "Video", "DriverName", old_driv); gf_cfg_del(user.config); diff --git a/applications/mp4box/Makefile b/applications/mp4box/Makefile index d3c03fa..2cce51a 100644 --- a/applications/mp4box/Makefile +++ b/applications/mp4box/Makefile @@ -24,19 +24,29 @@ CFLAGS+=-DGPAC_DISABLE_SVG endif #common obj -OBJS= main.o filedump.o fileimport.o +OBJS= main.o filedump.o fileimport.o live.o + +LINKFLAGS=-L../../bin/gcc -L../../extra_lib/lib/gcc -LINKFLAGS=-L../../bin/gcc ifeq ($(CONFIG_WIN32),yes) EXE=.exe PROG=MP4Box$(EXE) -#LINKFLAGS+=-lgpac_static -lz $(EXTRALIBS) +ifeq ($(MP4BOX_STATIC),yes) +LINKFLAGS+=-lgpac_static -lz $(EXTRALIBS) +else LINKFLAGS+=-lgpac +endif + else + EXT= PROG=MP4Box -#LINKFLAGS+=-lgpac_static $(EXTRALIBS) $(GPAC_SH_FLAGS) -lz -LINKFLAGS+=-lgpac -lz $(OGL_LIBS) +ifeq ($(MP4BOX_STATIC),yes) +LINKFLAGS+=-lgpac_static $(EXTRALIBS) $(GPAC_SH_FLAGS) -lz +else +LINKFLAGS+=-lgpac +endif + endif diff --git a/applications/mp4box/filedump.c b/applications/mp4box/filedump.c index ce852cb..bd9df65 100644 --- a/applications/mp4box/filedump.c +++ b/applications/mp4box/filedump.c @@ -6,7 +6,7 @@ * * This file is part of GPAC / mp4box application * - * GPAC is free software; you can redistribute it and/or modify + * GPAC is gf_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. @@ -23,6 +23,13 @@ */ #include + +#ifdef GPAC_DISABLE_ISOM + +#error "Cannot compile MP4Box if GPAC is not built with ISO File Format support" + +#else + #include #include #include @@ -40,7 +47,7 @@ extern u32 get_file_type_by_ext(char *inName); void scene_coding_log(void *cbk, u32 log_level, u32 log_tool, const char *fmt, va_list vlist); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double force_fps, u32 frames_per_sample); #endif @@ -89,8 +96,6 @@ const char *GetLanguageCode(char *lang) return "und"; } -#ifndef GPAC_READ_ONLY - GF_Err dump_cover_art(GF_ISOFile *file, char *inName) { const char *tag; @@ -107,34 +112,40 @@ GF_Err dump_cover_art(GF_ISOFile *file, char *inName) } sprintf(szName, "%s.%s", inName, (tag_len>>31) ? "png" : "jpg"); - t = fopen(szName, "wb"); + t = gf_f64_open(szName, "wb"); fwrite(tag, tag_len & 0x7FFFFFFF, 1, t); fclose(t); return GF_OK; } +#ifndef GPAC_DISABLE_ISOM_WRITE + GF_Err set_cover_art(GF_ISOFile *file, char *inName) { GF_Err e; char *tag, *ext; FILE *t; u32 tag_len; - t = fopen(inName, "rb"); - fseek(t, 0, SEEK_END); - tag_len = ftell(t); - fseek(t, 0, SEEK_SET); - tag = malloc(sizeof(char) * tag_len); - fread(tag, tag_len, 1, t); + t = gf_f64_open(inName, "rb"); + gf_f64_seek(t, 0, SEEK_END); + tag_len = (u32) gf_f64_tell(t); + gf_f64_seek(t, 0, SEEK_SET); + tag = gf_malloc(sizeof(char) * tag_len); + tag_len = fread(tag, sizeof(char), tag_len, t); fclose(t); ext = strrchr(inName, '.'); if (!stricmp(ext, ".png")) tag_len |= 0x80000000; e = gf_isom_apple_set_tag(file, GF_ISOM_ITUNE_COVER_ART, tag, tag_len); - free(tag); + gf_free(tag); return e; } +#endif + +#ifndef GPAC_DISABLE_SCENE_DUMP + GF_Err dump_file_text(char *file, char *inName, u32 dump_mode, Bool do_log) { GF_Err e; @@ -185,7 +196,7 @@ GF_Err dump_file_text(char *file, char *inName, u32 dump_mode, Bool do_log) if (do_log) { char szLog[GF_MAX_PATH]; sprintf(szLog, "%s_dec.logs", inName); - logs = fopen(szLog, "wt"); + logs = gf_f64_open(szLog, "wt"); gf_log_set_tools(GF_LOG_CODING); gf_log_set_level(GF_LOG_DEBUG); @@ -216,6 +227,9 @@ GF_Err dump_file_text(char *file, char *inName, u32 dump_mode, Bool do_log) if (load.isom) gf_isom_delete(load.isom); return e; } +#endif + +#ifndef GPAC_DISABLE_SCENE_STATS static void dump_stats(FILE *dump, GF_SceneStatistics *stats) { @@ -230,6 +244,7 @@ static void dump_stats(FILE *dump, GF_SceneStatistics *stats) fprintf(dump, "\n", ptr->name); switch (ptr->tag) { +#ifndef GPAC_DISABLE_VRML case TAG_MPEG4_Bitmap: case TAG_MPEG4_Background2D: case TAG_MPEG4_Background: @@ -257,6 +272,7 @@ static void dump_stats(FILE *dump, GF_SceneStatistics *stats) draw_deleted += ptr->nb_del; draw_created += ptr->nb_created; break; +#endif /*GPAC_DISABLE_VRML*/ } fprintf(dump, "\n", ptr->nb_created, ptr->nb_used, ptr->nb_del); count += ptr->nb_created + ptr->nb_used; @@ -380,7 +396,7 @@ void dump_scene_stats(char *file, char *inName, u32 stat_level) if (inName) { strcpy(szBuf, inName); strcat(szBuf, "_stat.xml"); - dump = fopen(szBuf, "wt"); + dump = gf_f64_open(szBuf, "wt"); close = 1; } else { dump = stdout; @@ -464,9 +480,13 @@ exit: if (dump && close) fclose(dump); fprintf(stdout, "done\n"); } -#endif +#endif /*GPAC_DISABLE_SCENE_STATS*/ -void PrintFixed(Fixed val, Bool add_space) + + +#ifndef GPAC_DISABLE_VRML + +static void PrintFixed(Fixed val, Bool add_space) { if (add_space) fprintf(stdout, " "); if (val==FIX_MIN) fprintf(stdout, "-I"); @@ -474,7 +494,7 @@ void PrintFixed(Fixed val, Bool add_space) else fprintf(stdout, "%g", FIX2FLT(val)); } -void PrintNodeSFField(u32 type, void *far_ptr) +static void PrintNodeSFField(u32 type, void *far_ptr) { if (!far_ptr) return; switch (type) { @@ -518,35 +538,25 @@ void PrintNodeSFField(u32 type, void *far_ptr) break; } } - -static Bool node_in_table_by_tag(u32 tag, u32 NDTType) -{ - if (!tag) return 0; - if (tag==TAG_ProtoNode) return 1; - else if (tag<=GF_NODE_RANGE_LAST_MPEG4) { - u32 i; - - for (i=0;i\n"); if (inName) fclose(dump); } +#endif void dump_file_ts(GF_ISOFile *file, char *inName) { @@ -763,7 +798,7 @@ void dump_file_ts(GF_ISOFile *file, char *inName) if (inName) { strcpy(szBuf, inName); strcat(szBuf, "_ts.txt"); - dump = fopen(szBuf, "wt"); + dump = gf_f64_open(szBuf, "wt"); } else { dump = stdout; } @@ -779,11 +814,13 @@ void dump_file_ts(GF_ISOFile *file, char *inName) GF_ISOSample *samp = gf_isom_get_sample_info(file, i+1, j+1, NULL, NULL); dts = samp->DTS; cts = dts + (s32) samp->CTS_Offset; - gf_isom_sample_del(&samp); fprintf(dump, "Sample %d - DTS "LLD" - CTS "LLD"", j+1, LLD_CAST dts, LLD_CAST cts); + if (samp->IsRAP) fprintf(dump, " - RAP"); if (ctsdecoderConfig->streamType==GF_STREAM_VISUAL) { u32 w, h; w = h = 0; - if (esd->decoderConfig->objectTypeIndication==0x20) { + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { +#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"); w = dsi.width; h = dsi.height; - if (w && h) { - fprintf(stdout, "MPEG-4 Visual Size %d x %d - %s\n", dsi.width, dsi.height, 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(stdout, "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); } - } else if (esd->decoderConfig->objectTypeIndication==0x21) { - GF_AVCConfig *avccfg; +#else + gf_isom_get_visual_info(file, trackNum, 1, &w, &h); + fprintf(stdout, "MPEG-4 Visual Size %d x %d\n", w, h); +#endif + + } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_AVCConfig *avccfg, *svccfg; GF_AVCConfigSlot *slc; s32 par_n, par_d; +#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 - ", w, h); + fprintf(stdout, "AVC/H264 Video - Visual Size %d x %d", w, h); +#ifndef GPAC_DISABLE_AV_PARSERS avccfg = gf_isom_avc_config_get(file, trackNum, 1); - if (!avccfg) { + 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"); - } else { - fprintf(stdout, "Profile %s @ Level %g\n", gf_avc_get_profile_name(avccfg->AVCProfileIndication), ((Double)avccfg->AVCLevelIndication)/10.0 ); + } else if (avccfg) { + fprintf(stdout, " - Profile %s @ Level %g\n", gf_avc_get_profile_name(avccfg->AVCProfileIndication), ((Double)avccfg->AVCLevelIndication)/10.0 ); fprintf(stdout, "NAL Unit length bits: %d\n", 8*avccfg->nal_unit_size); - -#ifndef GPAC_READ_ONLY slc = gf_list_get(avccfg->sequenceParameterSets, 0); - gf_avc_get_sps_info(slc->data, slc->size, 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, "Pixel Aspect Ratio %d:%d - Indicated track size %d x %d\n", par_n, par_d, tw, th); + if (slc) { + gf_avc_get_sps_info(slc->data, slc->size, 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, "Pixel Aspect Ratio %d:%d - Indicated track size %d x %d\n", par_n, par_d, tw, th); + } } -#endif gf_odf_avc_cfg_del(avccfg); } + if (svccfg) { + fprintf(stdout, "\nSVC Profile %s @ Level %g\n", gf_avc_get_profile_name(svccfg->AVCProfileIndication), ((Double)svccfg->AVCLevelIndication)/10.0 ); + fprintf(stdout, "SVC NAL Unit length bits: %d\n", 8*svccfg->nal_unit_size); + slc = gf_list_get(svccfg->sequenceParameterSets, 0); + if (slc) { + gf_avc_get_sps_info(slc->data, slc->size, 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, "Pixel Aspect Ratio %d:%d - Indicated track size %d x %d\n", par_n, par_d, tw, th); + } + } + gf_odf_avc_cfg_del(svccfg); + } +#endif /*GPAC_DISABLE_AV_PARSERS*/ } /*OGG media*/ else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_MEDIA_OGG) { @@ -1100,29 +1203,38 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stdout, "Visual Size %d x %d\n", w, h); } } else if (esd->decoderConfig->streamType==GF_STREAM_AUDIO) { +#ifndef GPAC_DISABLE_AV_PARSERS GF_M4ADecSpecInfo a_cfg; GF_Err e; - u32 oti, is_mp2 = 0; + u32 oti; +#endif + u32 is_mp2 = 0; switch (esd->decoderConfig->objectTypeIndication) { - case 0x66: - case 0x67: - case 0x68: + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: is_mp2 = 1; - case 0x40: + case GPAC_OTI_AUDIO_AAC_MPEG4: +#ifndef GPAC_DISABLE_AV_PARSERS 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"); 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"); } +#else + fprintf(stdout, "MPEG-2/4 Audio - %d Channels - SampleRate %d\n", nb_ch, sr); +#endif break; - case 0x69: - case 0x6B: + 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); } else { +#ifndef GPAC_DISABLE_AV_PARSERS GF_ISOSample *samp = gf_isom_get_sample(file, trackNum, 1, &oti); 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"); @@ -1133,6 +1245,9 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) gf_mp3_layer(oti) ); gf_isom_sample_del(&samp); +#else + fprintf(stdout, "MPEG-1/2 Audio - %d Channels - SampleRate %d\n", nb_ch, sr); +#endif } break; /*OGG media*/ @@ -1147,9 +1262,9 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stdout, "Ogg/%s audio / GPAC Mux - Sample Rate %d - %d channel(s)\n", szName, sr, nb_ch); } break; - case 0xA0: fprintf(stdout, "EVRC Audio - Sample Rate 8000 - 1 channel\n"); break; - case 0xA1: fprintf(stdout, "SMV Audio - Sample Rate 8000 - 1 channel\n"); break; - case 0xE1: fprintf(stdout, "QCELP Audio - Sample Rate 8000 - 1 channel\n"); 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; /*packetVideo hack for EVRC...*/ case 0xD1: if (esd->decoderConfig->decoderSpecificInfo && (esd->decoderConfig->decoderSpecificInfo->dataLength==8) @@ -1168,7 +1283,7 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) fprintf(stdout, "\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==0x09) { + } 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"); @@ -1182,7 +1297,7 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) else fprintf(stdout, "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/1024, esd->decoderConfig->maxBitrate/1024); + 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); if (esd->dependsOnESID) fprintf(stdout, "\tDepends on stream %d for decoding\n", esd->dependsOnESID); else @@ -1259,7 +1374,18 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } 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); } else if (msub_type == GF_ISOM_SUBTYPE_AC3) { - fprintf(stdout, "\tAC3 stream - Sample Rate %d - %d channel(s) %d bits per samples\n", sr, nb_ch, (u32) bps); + u32 br = 0; + Bool lfe = 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; + gf_free(ac3); + } +#endif + fprintf(stdout, "\tAC3 stream - Sample Rate %d - %d%s channel(s) - bitrate %d\n", 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); } else if (msub_type == GF_ISOM_SUBTYPE_3GP_DIMS) { @@ -1288,19 +1414,31 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) } else { fprintf(stdout, "Streaming Hint Track (no refs)\n"); } +#ifndef GPAC_DISABLE_ISOM_HINTING refCount = gf_isom_get_payt_count(file, trackNum); for (i=0;ivendor_code), udesc->version, udesc->revision); if (udesc->extension_buf) { fprintf(stdout, "\tCodec configuration data size: %d bytes\n", udesc->extension_buf_size); - free(udesc->extension_buf); + gf_free(udesc->extension_buf); } - free(udesc); + gf_free(udesc); } else { fprintf(stdout, "Unknown track type\n"); } @@ -1330,16 +1468,20 @@ void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump) for (i=0; i= 1500) { - rate /= 1024; - max_rate /= 1024; + rate /= 1000; + max_rate /= 1000; fprintf(stdout, "\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); @@ -1442,7 +1584,12 @@ void DumpMovieInfo(GF_ISOFile *file) DumpMetaItem(file, 1, 0, "Root Meta"); if (!gf_isom_has_movie(file)) { - fprintf(stdout, "File has no movie (moov) - static data container\n"); + 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); + } else { + fprintf(stdout, "File has no movie (moov) - static data container\n"); + } return; } @@ -1548,6 +1695,11 @@ void DumpMovieInfo(GF_ISOFile *file) } } +#endif /*GPAC_DISABLE_ISOM*/ + + +#ifndef GPAC_DISABLE_MPEG2TS + typedef struct { /* when writing to file */ @@ -1664,19 +1816,20 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name) { char data[188]; GF_M2TS_Dump dumper; - u32 size, fsize, fdone; + u32 size; + u64 fsize, fdone; GF_M2TS_Demuxer *ts; - FILE *src = fopen(mpeg2ts_file, "rb"); + FILE *src = gf_f64_open(mpeg2ts_file, "rb"); ts = gf_m2ts_demux_new(); ts->on_event = on_m2ts_dump_event; memset(&dumper, 0, sizeof(GF_M2TS_Dump)); ts->user = &dumper; - fseek(src, 0, SEEK_END); - fsize = ftell(src); - fseek(src, 0, SEEK_SET); + gf_f64_seek(src, 0, SEEK_END); + fsize = gf_f64_tell(src); + gf_f64_seek(src, 0, SEEK_SET); fdone = 0; if (pes_out_name) { @@ -1685,11 +1838,11 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name) dumper.dump_pid = atoi(pid+1); pid[0] = 0; sprintf(dumper.dump, "%s_%d.media", pes_out_name, dumper.dump_pid); - dumper.pes_out = fopen(dumper.dump, "wb"); + dumper.pes_out = gf_f64_open(dumper.dump, "wb"); sprintf(dumper.nhml, "%s_%d.nhml", pes_out_name, dumper.dump_pid); - dumper.pes_out_nhml = fopen(dumper.nhml, "wt"); + dumper.pes_out_nhml = gf_f64_open(dumper.nhml, "wt"); sprintf(dumper.info, "%s_%d.info", pes_out_name, dumper.dump_pid); - dumper.pes_out_info = fopen(dumper.info, "wb"); + dumper.pes_out_info = gf_f64_open(dumper.info, "wb"); pid[0] = '#'; } } @@ -1724,3 +1877,7 @@ void dump_mpeg2_ts(char *mpeg2ts_file, char *pes_out_name) fclose(dumper.pes_out_info); } } + +#endif /*GPAC_DISABLE_MPEG2TS*/ + + diff --git a/applications/mp4box/fileimport.c b/applications/mp4box/fileimport.c index 86bc31a..220b330 100644 --- a/applications/mp4box/fileimport.c +++ b/applications/mp4box/fileimport.c @@ -6,7 +6,7 @@ * * This file is part of GPAC / mp4box application * - * GPAC is free software; you can redistribute it and/or modify + * GPAC is gf_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. @@ -30,10 +30,11 @@ #include -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE extern u32 swf_flags; extern Float swf_flatten_angle; +extern Bool keep_sys_tracks; const char *GetLanguageCode(char *lang); void scene_coding_log(void *cbk, u32 log_level, u32 log_tool, const char *fmt, va_list vlist); @@ -80,6 +81,8 @@ void convert_file_info(char *inName, u32 trackID) if (import.tk_info[i].lang) fprintf(stdout, " - 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].prog_num) { if (!import.nb_progs) { fprintf(stdout, " - Program %d", import.tk_info[i].prog_num); @@ -117,6 +120,7 @@ void convert_file_info(char *inName, u32 trackID) 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"); @@ -130,14 +134,15 @@ void convert_file_info(char *inName, u32 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; + u32 track_id, i, timescale, track, stype, profile, level; s32 par_d, par_n, prog_id, delay; - Bool do_audio, do_video, do_all, disable; - u32 group; + s32 tw, th, tx, ty; + Bool do_audio, do_video, do_all, disable, track_layout, chap_ref, is_chap, keep_handler; + u32 group, handler; const char *szLan; GF_Err e; GF_MediaImporter import; - char *ext, szName[1000], *handler_name; + char *ext, szName[1000], *fmt, *handler_name; memset(&import, 0, sizeof(GF_MediaImporter)); @@ -148,16 +153,25 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc return GF_BAD_PARAM; } + handler = 0; disable = 0; + chap_ref = 0; + is_chap = 0; + track_layout = 0; szLan = NULL; delay = 0; group = 0; + stype = 0; + profile = level = 0; + + tw = th = tx = ty = 0; par_d = par_n = -2; /*use ':' as separator, but beware DOS paths...*/ ext = strchr(szName, ':'); if (ext && ext[1]=='\\') ext = strchr(szName+2, ':'); handler_name = NULL; + fmt = NULL; while (ext) { char *ext2 = strchr(ext+1, ':'); if (ext2 && !strncmp(ext2, "://", 3)) ext2 = strchr(ext2+1, ':'); @@ -169,13 +183,26 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc else if (!strnicmp(ext+1, "delay=", 6)) delay = atoi(ext+7); else if (!strnicmp(ext+1, "fps=", 4)) { if (!strcmp(ext+5, "auto")) force_fps = 10000.0; + else if (strchr(ext+5, '-')) { + u32 ticks, dts_inc; + sscanf(ext+5, "%d-%d", &ticks, &dts_inc); + if (!dts_inc) dts_inc=1; + force_fps = ticks; + force_fps /= dts_inc; + } else force_fps = atof(ext+5); } + 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; else if (!stricmp(ext+1, "packed")) import_flags |= GF_IMPORT_FORCE_PACKED; else if (!stricmp(ext+1, "sbr")) import_flags |= GF_IMPORT_SBR_IMPLICIT; else if (!stricmp(ext+1, "sbrx")) import_flags |= GF_IMPORT_SBR_EXPLICIT; + else if (!stricmp(ext+1, "ovsbr")) import_flags |= GF_IMPORT_OVSBR; + else if (!stricmp(ext+1, "svc")) import_flags |= GF_IMPORT_SVC_EXPLICIT; + else if (!stricmp(ext+1, "nosvc")) import_flags |= GF_IMPORT_SVC_NONE; + else if (!stricmp(ext+1, "ps")) import_flags |= GF_IMPORT_PS_IMPLICIT; + else if (!stricmp(ext+1, "psx")) import_flags |= GF_IMPORT_PS_EXPLICIT; else if (!stricmp(ext+1, "mpeg4")) import_flags |= GF_IMPORT_FORCE_MPEG4; else if (!strnicmp(ext+1, "agg=", 4)) frames_per_sample = atoi(ext+5); else if (!strnicmp(ext+1, "dur=", 4)) import.duration = (u32) (atof(ext+5) * 1000); @@ -189,16 +216,29 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc sscanf(ext+5, "%d:%d", &par_n, &par_d); } } - else if (!strnicmp(ext+1, "name=", 5)) handler_name = strdup(ext+6); - else if (!strnicmp(ext+1, "font=", 5)) import.fontName = strdup(ext+6); + else if (!strnicmp(ext+1, "name=", 5)) handler_name = gf_strdup(ext+6); + 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 = strdup(ext+5); + 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, "disable", 7)) disable = 1; else if (!strnicmp(ext+1, "group=", 6)) { group = atoi(ext+7); if (!group) group = gf_isom_get_next_alternate_group_id(dest); } + else if (!strnicmp(ext+1, "hdlr=", 5)) + handler = GF_4CC(ext[6], ext[7], ext[8], ext[9]); + else if (!strnicmp(ext+1, "layout=", 7)) { + sscanf(ext+8, "%dx%dx%dx%d", &tw, &th, &tx, &ty); + track_layout = 1; + } + 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); + /*unrecognized, assume name has colon in it*/ else { @@ -226,6 +266,8 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc ext = strrchr(szName, '#'); if (ext) ext[0] = 0; + keep_handler = gf_isom_probe_file(szName); + import.in_name = szName; import.flags = GF_IMPORT_PROBE_ONLY; e = gf_media_import(&import); @@ -250,6 +292,39 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc } if (do_audio || do_video || track_id) do_all = 0; + if (track_layout || is_chap) { + u32 w, h, sw, sh, fw, fh, i; + w = h = sw = sh = fw = fh = 0; + chap_ref = 0; + for (i=0; i(u32)th) ? h-th : 0; + import.twidth = tw; + import.theight = th; + } + if (is_chap && chap_ref) import_flags |= GF_IMPORT_NO_TEXT_FLUSH; + } + + import.dest = dest; import.video_fps = force_fps; import.frames_per_sample = frames_per_sample; @@ -285,6 +360,33 @@ GF_Err import_file(GF_ISOFile *dest, char *inName, u32 import_flags, Double forc e = gf_media_change_par(import.dest, i+1, par_n, par_d); } if (handler_name) gf_isom_set_handler_name(import.dest, i+1, handler_name); + else if (!keep_handler) { + char szHName[1024]; + sprintf(szHName, "%s - Imported with GPAC %s", inName, GPAC_FULL_VERSION); + gf_isom_set_handler_name(import.dest, i+1, szHName); + } + if (handler) gf_isom_set_media_type(import.dest, i+1, handler); + if (disable) gf_isom_set_track_enabled(import.dest, i+1, 0); + + if (group) { + gf_isom_set_alternate_group_id(import.dest, i+1, group); + } + if (track_layout) { + gf_isom_set_track_layout_info(import.dest, i+1, tw<<16, th<<16, tx<<16, ty<<16, 0); + } + if (stype) + gf_isom_set_media_subtype(import.dest, i+1, 1, stype); + + if (is_chap && chap_ref) { + gf_isom_set_track_reference(import.dest, chap_ref, GF_4CC('c','h','a','p'), gf_isom_get_track_id(import.dest, i+1) ); + gf_isom_set_track_enabled(import.dest, i+1, 0); + } + + if (profile || level) + gf_media_change_pl(import.dest, i+1, profile, level); + + if (gf_isom_get_media_subtype(import.dest, i+1, 1)== GF_4CC( 'm', 'p', '4', 's' )) + keep_sys_tracks = 1; } } else { for (i=0; i=max_dur) { fprintf(stdout, "Input file (%f) shorter than requested split start offset (%f)\n", max_dur, chunk_start); - free(tks); + gf_free(tks); return GF_NOT_SUPPORTED; } if (max_dur<=split_dur) { fprintf(stdout, "Input file (%f) shorter than requested split duration (%f)\n", max_dur, split_dur); - free(tks); + 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"); - free(tks); + gf_free(tks); return GF_NOT_SUPPORTED; } } @@ -518,7 +645,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, 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); - free(tks); + gf_free(tks); return GF_NOT_SUPPORTED; } start = (Double) (s64) samp->DTS; @@ -886,7 +1013,7 @@ GF_Err split_isomedia_file(GF_ISOFile *mp4, Double split_dur, u32 split_size_kb, gf_set_progress("Splitting", nb_samp, nb_samp); err_exit: if (dest) gf_isom_delete(dest); - free(tks); + gf_free(tks); return e; } @@ -926,6 +1053,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou continue; case GF_ISOM_MEDIA_AUDIO: case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_SCENE: case GF_ISOM_MEDIA_OCR: @@ -968,6 +1096,7 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou case GF_ISOM_MEDIA_FLASH: continue; case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: case GF_ISOM_MEDIA_SCENE: use_ts_dur = 0; case GF_ISOM_MEDIA_AUDIO: @@ -985,8 +1114,9 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou tk_id = gf_isom_get_track_id(orig, i+1); dst_tk = gf_isom_get_track_by_id(dest, tk_id); if (dst_tk) { + u32 stype = gf_isom_get_media_subtype(dest, dst_tk, 1); /*we MUST have the same codec*/ - if (gf_isom_get_media_subtype(orig, i+1, 1) != gf_isom_get_media_subtype(dest, dst_tk, 1)) dst_tk = 0; + if (gf_isom_get_media_subtype(orig, i+1, 1) != stype) dst_tk = 0; /*we only support cat with the same number of sample descriptions*/ if (gf_isom_get_sample_description_count(orig, i+1) != gf_isom_get_sample_description_count(dest, dst_tk)) dst_tk = 0; /*if not forcing cat, check the media codec config is the same*/ @@ -998,6 +1128,34 @@ GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Dou gf_isom_get_visual_info(dest, dst_tk, 1, &w, &h); if ((ow!=w) || (oh!=h)) dst_tk = 0; } + + if (!dst_tk && ((stype == GF_ISOM_SUBTYPE_AVC_H264) || (stype == GF_ISOM_SUBTYPE_AVC2_H264)) ) { + GF_AVCConfig *avc_src, *avc_dst; + dst_tk = gf_isom_get_track_by_id(dest, tk_id); + + avc_src = gf_isom_avc_config_get(orig, i+1, 1); + avc_dst = gf_isom_avc_config_get(dest, dst_tk, 1); + + if (avc_src->nal_unit_size != avc_dst->nal_unit_size) dst_tk = 0; + else if (avc_src->AVCLevelIndication!=avc_dst->AVCLevelIndication) dst_tk = 0; + else if (avc_src->AVCProfileIndication!=avc_dst->AVCProfileIndication) dst_tk = 0; + else { + while (gf_list_count(avc_src->sequenceParameterSets)) { + GF_AVCConfigSlot *slc = gf_list_get(avc_src->sequenceParameterSets, 0); + gf_list_rem(avc_src->sequenceParameterSets, 0); + gf_list_add(avc_dst->sequenceParameterSets, slc); + } + + while (gf_list_count(avc_src->pictureParameterSets)) { + GF_AVCConfigSlot *slc = gf_list_get(avc_src->pictureParameterSets, 0); + gf_list_rem(avc_src->pictureParameterSets, 0); + 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) { @@ -1250,6 +1408,7 @@ GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Do } +#ifndef GPAC_DISABLE_SCENE_ENCODER /* MPEG-4 encoding */ @@ -1309,6 +1468,7 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log fprintf(stdout, "encoded using a %d.8 representation\n", opts->coord_bits - 8); } } +#ifndef GPAC_DISABLE_VRML /*BIFS*/ else if (stats->base_layer) { GF_AUContext *au; @@ -1346,10 +1506,11 @@ GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *log qp->scaleQuant = 1; } } +#endif } } - if (e) { + if (e<0) { fprintf(stdout, "Error loading file %s\n", gf_error_to_string(e)); goto err_exit; } else { @@ -1378,7 +1539,10 @@ err_exit: gf_sg_del(sg); return e; } +#endif /*GPAC_DISABLE_SCENE_ENCODER*/ + +#ifndef GPAC_DISABLE_BIFS_ENC /* MPEG-4 chunk encoding */ @@ -1485,10 +1649,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->nodeIDbitsmax_route_id); + if (!bcfg->routeIDbits) bcfg->routeIDbits = nbb; if (bcfg->routeIDbitsmax_proto_id); + if (!bcfg->protoIDbits) bcfg->protoIDbits=nbb; if (bcfg->protoIDbitsESID, au->commands, &data, &data_len); if (data) { sprintf(szName, "%s%02d.bifs", szRad, j); - f = fopen(szName, "wb"); + f = gf_f64_open(szName, "wb"); fwrite(data, data_len, 1, f); fclose(f); - free(data); + gf_free(data); } } } @@ -1529,6 +1698,7 @@ GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCa return e; } +#endif /*GPAC_DISABLE_BIFS_ENC*/ /** * @chunkFile BT chunk to be encoded @@ -1540,6 +1710,10 @@ 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) { +#ifdef GPAC_DISABLE_BIFS + fprintf(stdout, "BIFS is not supported in this build of GPAC\n"); + return GF_NOT_SUPPORTED; +#else GF_Err e; GF_SceneGraph *sg; GF_SceneManager *ctx; @@ -1562,7 +1736,7 @@ GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *ou } /* Step 2: make sure we have only ONE RAP for each stream*/ - e = gf_sm_make_random_access(ctx); + e = gf_sm_aggregate(ctx, 0); if (e) goto exit; /*Step 3: loading the chunk into the context*/ @@ -1592,7 +1766,7 @@ GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *ou char szF[GF_MAX_PATH], *ext; /*make random access for storage*/ - e = gf_sm_make_random_access(ctx); + e = gf_sm_aggregate(ctx, 0); if (e) goto exit; /*check if we dump to BT, XMT or encode to MP4*/ @@ -1624,6 +1798,7 @@ exit: gf_sg_del(sg); } return e; +#endif } #include @@ -1645,19 +1820,44 @@ void sax_node_start(void *sax_cbck, const char *node_name, const char *name_spac if (!strnicmp(att->value, "od:", 3)) continue; sprintf(szCheck, "%d", atoi(att->value)); if (!strcmp(szCheck, att->value)) continue; - gf_list_add(imports, strdup(att->value) ); + gf_list_add(imports, gf_strdup(att->value) ); } } -GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir) +typedef struct +{ + const char *root_file; + const char *dir; + GF_List *imports; +} WGTEnum; + +static Bool wgt_enum_files(void *cbck, char *file_name, char *file_path) +{ + WGTEnum *wgt = (WGTEnum *)cbck; + + if (!strcmp(wgt->root_file, file_path)) return 0; + /*remove CVS stuff*/ + if (strstr(file_path, ".#")) return 0; + gf_list_add(wgt->imports, gf_strdup(file_path) ); + return 0; +} +static Bool wgt_enum_dir(void *cbck, char *file_name, char *file_path) +{ + if (!stricmp(file_name, "cvs") || !stricmp(file_name, ".svn")) return 0; + gf_enum_directory(file_path, 0, wgt_enum_files, cbck, NULL); + return gf_enum_directory(file_path, 1, wgt_enum_dir, cbck, NULL); +} + +GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool make_wgt) { GF_ISOFile *file = NULL; GF_Err e; GF_SAXParser *sax; GF_List *imports; Bool ascii; + char root_dir[GF_MAX_PATH]; char *isom_src = NULL; - u32 i, count, mtype; + u32 i, count, mtype, skip_chars; char *type; type = gf_xml_get_root_type(file_name, &e); @@ -1665,14 +1865,46 @@ GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir) fprintf(stdout, "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); + gf_free(type); + return NULL; + } + gf_free(type); + type = gf_strdup("application/mw-manifest+xml"); + fcc = "mwgt"; + } imports = gf_list_new(); - sax = gf_xml_sax_new(sax_node_start, NULL, NULL, imports); - e = gf_xml_sax_parse_file(sax, file_name, NULL); - ascii = !gf_xml_sax_binary_file(sax); - gf_xml_sax_del(sax); - if (e<0) goto exit; - e = GF_OK; + + + root_dir[0] = 0; + if (make_wgt) { + WGTEnum wgt; + char *sep = strrchr(file_name, '\\'); + if (!sep) sep = strrchr(file_name, '/'); + if (sep) { + char c = sep[1]; + sep[1]=0; + strcpy(root_dir, file_name); + sep[1] = c; + } else { + strcpy(root_dir, "./"); + } + wgt.dir = root_dir; + wgt.root_file = file_name; + wgt.imports = imports; + gf_enum_directory(wgt.dir, 0, wgt_enum_files, &wgt, NULL); + gf_enum_directory(wgt.dir, 1, wgt_enum_dir, &wgt, NULL); + ascii = 1; + } else { + sax = gf_xml_sax_new(sax_node_start, NULL, NULL, imports); + e = gf_xml_sax_parse_file(sax, file_name, NULL); + ascii = !gf_xml_sax_binary_file(sax); + gf_xml_sax_del(sax); + if (e<0) goto exit; + e = GF_OK; + } if (fcc) { mtype = GF_4CC(fcc[0],fcc[1],fcc[2],fcc[3]); @@ -1690,31 +1922,35 @@ GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir) } - count = gf_list_count(imports); - for (i=0; i +#include +#include +#include +#include + +void PrintStreamerUsage() +{ + fprintf(stdout, "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" + "\n" + "-rtp enables streamer\n" + "-noloop disables looping when streaming\n" + "-mpeg4 forces MPEG-4 ES Generic for all RTP streams\n" + "-dst=IP IP destination (uni/multi-cast). Default: 127.0.0.1\n" + "-port=PORT output port of the first stream. Default: 7000\n" + "-mtu=MTU path MTU for RTP packets. Default is 1450 bytes\n" + "-ifce=IFCE IP address of the physical interface to use. Default: NULL (ANY)\n" + "-ttl=TTL time to live for multicast packets. Default: 1\n" + "-sdp=Name file name of the generated SDP. Default: \"session.sdp\"\n" + "\n" + ); +} + +int stream_file_rtp(int argc, char **argv) +{ + GF_ISOMRTPStreamer *file_streamer; + char *sdp_file = "session.sdp"; + char *ip_dest = "127.0.0.1"; + char *ifce_addr = NULL; + char *inName = NULL; + u16 port = 7000; + u32 ttl = 1; + Bool loop = 1, stream_rtp = 0; + Bool force_mpeg4 = 0; + u32 path_mtu = 1450; + u32 i; + + for (i = 1; i < (u32) argc ; i++) { + char *arg = argv[i]; + + if (arg[0] != '-') { + if (inName) { fprintf(stdout, "Error - 2 input names specified, please check usage\n"); return 1; } + inName = arg; + } + else if (!stricmp(arg, "-noloop")) loop = 0; + else if (!stricmp(arg, "-mpeg4")) force_mpeg4 = 1; + else if (!strnicmp(arg, "-port=", 6)) port = atoi(arg+6); + else if (!strnicmp(arg, "-mtu=", 5)) path_mtu = atoi(arg+5); + else if (!strnicmp(arg, "-dst=", 5)) ip_dest = arg+5; + else if (!strnicmp(arg, "-ttl=", 5)) ttl = atoi(arg+5); + else if (!strnicmp(arg, "-ifce=", 6)) ifce_addr = arg+6; + else if (!strnicmp(arg, "-sdp=", 5)) sdp_file = arg+5; + } + + if (!gf_isom_probe_file(inName)) { + fprintf(stdout, "File %s is not a valid ISO Media file and cannot be streamed\n", inName); + return 1; + } + + gf_sys_init(0); + + gf_log_set_tools(GF_LOG_RTP); + gf_log_set_level(GF_LOG_WARNING); //set to debug to have packet list + + 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"); + } else { + u32 check = 50; + fprintf(stdout, "Starting streaming %s to %s:%d\n", inName, ip_dest, port); + gf_isom_streamer_write_sdp(file_streamer, sdp_file); + + while (1) { + gf_isom_streamer_send_next_packet(file_streamer, 0, 0); + check--; + if (!check) { + if (gf_prompt_has_input()) { + char c = (char) gf_prompt_get_char(); + if (c=='q') break; + } + check = 50; + } + } + gf_isom_streamer_del(file_streamer); + } + gf_sys_close(); + return 0; +} + + +void PrintLiveUsage() +{ + fprintf(stdout, + + "Live scene encoder options:\n" + "-dst=IP destination IP - default: NULL\n" + "-port=PORT destination port - default: 7000\n" + "-mtu=MTU path MTU for RTP packets. Default is 1450 bytes\n" + "-ifce=IFCE IP address of the physical interface to use. Default: NULL(ANY)\n" + "-ttl=TTL time to live for multicast packets. Default: 1\n" + "-sdp=Name ouput SDP file - default: session.sdp\n" + "\n" + "-dims turns on DIMS mode for SVG input - default: off\n" + "-src=file source of updates - default: null\n" + "-rap=time duration in ms of base carousel - default: 0 (off)\n" + " you can specify the RAP period of a single ESID (not in DIMS):\n" + " -rap=ESID=X:time\n" + "\n" + "Runtime options:\n" + "q: quits\n" + "u: inputs some commands to be sent\n" + "U: same as u but signals the updates as critical\n" + "e: inputs some commands to be sent without being aggregated\n" + "E: same as e but signals the updates as critical\n" + "f: forces RAP sending\n" + "F: forces RAP regeneration and sending\n" + "p: dumps current scene\n" + "\n" + "GPAC version: " GPAC_FULL_VERSION "\n" + ""); +} +typedef struct +{ + GF_RTPStreamer *rtp; + Bool manual_rtcp; + u16 ESID; + + char *carousel_data; + u32 carousel_size, carousel_alloc; + u32 last_carousel_time; + u64 carousel_ts, time_at_carousel_store; + + u32 timescale, init_time; + u32 carousel_period, ts_delta; + u16 aggregate_on_stream; + Bool adjust_carousel_time, discard, aggregate, rap, critical, m2ts_vers_inc; +} RTPChannel; + +typedef struct +{ + GF_SceneEngine *seng; + Bool force_carousel, carousel_generation; + GF_List *streams; + u32 start_time; + Bool critical; +} LiveSession; + + +RTPChannel *next_carousel(LiveSession *sess, u32 *timeout) +{ + RTPChannel *to_send = NULL; + u32 i, time, count, now; + + if (!sess->start_time) sess->start_time = gf_sys_clock(); + now = gf_sys_clock() - sess->start_time; + + time = (u32) -1; + count = gf_list_count(sess->streams); + for (i=0; istreams, i); + if (!ch->carousel_period) continue; + if (!ch->carousel_size) continue; + + if (!ch->last_carousel_time) ch->last_carousel_time = now; + + if (ch->last_carousel_time + ch->carousel_period < time) { + to_send = ch; + time = ch->last_carousel_time + ch->carousel_period; + } + } + if (!to_send) { + if (timeout) *timeout = 0; + return NULL; + } + if (timeout) { + if (time>now) time-=now; + else time=0; + *timeout = time; + } + return to_send; +} + + +static void live_session_callback(void *calling_object, u16 ESID, char *data, u32 size, u64 ts) +{ + LiveSession *livesess = (LiveSession *) calling_object; + RTPChannel *rtpch; + u32 i=0; + + while ( (rtpch = gf_list_enum(livesess->streams, &i))) { + if (rtpch->ESID == ESID) { + + /*store carousel data*/ + if (livesess->carousel_generation && rtpch->carousel_period) { + if (rtpch->carousel_alloc < size) { + rtpch->carousel_data = gf_realloc(rtpch->carousel_data, size); + rtpch->carousel_alloc = size; + } + memcpy(rtpch->carousel_data, data, size); + 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); + } + /*send data*/ + else { + ts += rtpch->timescale*(gf_sys_clock()-rtpch->init_time + rtpch->ts_delta)/1000; + gf_rtp_streamer_send_au_with_sn(rtpch->rtp, data, size, ts, ts, rtpch->rap ? 1 : 0, (livesess->critical || rtpch->critical) ? 1 : 0 ); + fprintf(stdout, "Stream %d: Sending update at TS "LLD", %d bytes - RAP %d - critical %d\n", ESID, ts, size, rtpch->rap, (livesess->critical || rtpch->critical) ? 1 : 0); + rtpch->rap = rtpch->critical = 0; + + if (rtpch->manual_rtcp) gf_rtp_streamer_send_rtcp(rtpch->rtp, 0, 0); + } + return; + } + } +} + +static void live_session_send_carousel(LiveSession *livesess, RTPChannel *ch) +{ + u32 now = gf_sys_clock(); + u64 ts=0; + if (ch) { + if (ch->carousel_size) { + ts = ch->carousel_ts + ch->timescale * ( (ch->adjust_carousel_time ? gf_sys_clock() : ch->time_at_carousel_store) - ch->init_time + ch->ts_delta)/1000; + + 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); + + if (ch->manual_rtcp) { + ts = ch->carousel_ts + ch->timescale * ( gf_sys_clock() - ch->init_time + ch->ts_delta)/1000; + gf_rtp_streamer_send_rtcp(ch->rtp, 1, (u32) ts); + } + } + } else { + u32 i=0; + while (ch = gf_list_enum(livesess->streams, &i)) { + if (ch->carousel_size) { + if (ch->adjust_carousel_time) { + ts = ch->carousel_ts + ch->timescale*(gf_sys_clock()-ch->init_time + ch->ts_delta)/1000; + } else { + ts = ch->carousel_ts; + } + 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); + + if (ch->manual_rtcp) { + ts = ch->carousel_ts + ch->timescale*(gf_sys_clock()-ch->init_time + ch->ts_delta)/1000; + gf_rtp_streamer_send_rtcp(ch->rtp, 1, (u32) ts); + } + } + } + } +} + +static void live_session_setup(LiveSession *livesess, char *ip, u16 port, u32 path_mtu, u32 ttl, char *ifce_addr, char *sdp_name) +{ + RTPChannel *rtpch; + u32 count = gf_seng_get_stream_count(livesess->seng); + u32 i; + char *iod64 = gf_seng_get_base64_iod(livesess->seng); + char *sdp = gf_rtp_streamer_format_sdp_header("GPACSceneStreamer", ip, NULL, iod64); + if (iod64) gf_free(iod64); + + for (i=0; iseng, i, &ESID, &config, &config_len, &st, &oti, &ts); + + GF_SAFEALLOC(rtpch, RTPChannel); + rtpch->timescale = ts; + rtpch->init_time = gf_sys_clock(); + + switch (st) { + case GF_STREAM_OD: + case GF_STREAM_SCENE: + rtpch->rtp = gf_rtp_streamer_new_extended(st, oti, ts, ip, port, path_mtu, ttl, ifce_addr, + GP_RTP_PCK_SYSTEMS_CAROUSEL, (char *) config, config_len, + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4); + + if (rtpch->rtp) { + gf_rtp_streamer_disable_auto_rtcp(rtpch->rtp); + rtpch->manual_rtcp = 1; + } + break; + default: + rtpch->rtp = gf_rtp_streamer_new(st, oti, ts, ip, port, path_mtu, ttl, ifce_addr, GP_RTP_PCK_SIGNAL_RAP, (char *) config, config_len); + break; + } + rtpch->ESID = ESID; + rtpch->adjust_carousel_time = 1; + gf_list_add(livesess->streams, rtpch); + + gf_rtp_streamer_append_sdp(rtpch->rtp, ESID, (char *) config, config_len, NULL, &sdp); + + /*fetch initial config of the broadcast*/ + gf_seng_get_stream_carousel_info(livesess->seng, ESID, &rtpch->carousel_period, &rtpch->aggregate_on_stream); + + port += 2; + } + if (sdp) { + FILE *out = gf_f64_open(sdp_name, "wt"); + fprintf(out, "%s", sdp); + fclose(out); + gf_free(sdp); + } +} + +void live_session_shutdown(LiveSession *livesess) +{ + gf_seng_terminate(livesess->seng); + + if (livesess->streams) { + while (gf_list_count(livesess->streams)) { + RTPChannel *rtpch = gf_list_get(livesess->streams, 0); + gf_list_rem(livesess->streams, 0); + gf_rtp_streamer_del(rtpch->rtp); + if (rtpch->carousel_data) gf_free(rtpch->carousel_data); + gf_free(rtpch); + } + gf_list_del(livesess->streams); + } +} + + +static RTPChannel *set_broadcast_params(LiveSession *livesess, u16 esid, u32 period, u32 ts_delta, u16 aggregate_on_stream, Bool adjust_carousel_time, Bool force_rap, Bool aggregate_au, Bool discard_pending, Bool signal_rap, Bool signal_critical, Bool version_inc) +{ + RTPChannel *rtpch = NULL; + + /*locate our stream*/ + if (esid) { + u32 i=0; + while ( (rtpch = gf_list_enum(livesess->streams, &i))) { + if (rtpch->ESID == esid) break; + } + } + + /*TODO - set/reset the ESID for the parsers*/ + if (!rtpch) return NULL; + + /*TODO - if discard is set, abort current carousel*/ + if (discard_pending) { + } + + /*remember RAP flag*/ + rtpch->rap = signal_rap; + rtpch->critical = signal_critical; + rtpch->m2ts_vers_inc = version_inc; + + rtpch->ts_delta = ts_delta; + rtpch->aggregate = aggregate_au; + rtpch->adjust_carousel_time = adjust_carousel_time; + + /*change stream aggregation mode*/ + if ((aggregate_on_stream != (u16)-1) && (rtpch->aggregate_on_stream != aggregate_on_stream)) { + gf_seng_enable_aggregation(livesess->seng, esid, aggregate_on_stream); + rtpch->aggregate_on_stream = aggregate_on_stream; + } + /*change stream aggregation mode*/ + if ((period!=(u32)-1) && (rtpch->carousel_period != period)) { + rtpch->carousel_period = period; + rtpch->last_carousel_time = 0; + } + + if (force_rap) { + livesess->force_carousel = 1; + } + return rtpch; +} + +int live_session(int argc, char **argv) +{ + GF_Err e; + int i; + char *filename = NULL; + char *dst = NULL; + char *ifce_addr = NULL; + char *sdp_name = "session.sdp"; + u16 dst_port = 7000; + u32 load_type=0; + u32 check; + u32 ttl = 1; + u32 path_mtu = 1450; + s32 next_time; + u64 last_src_modif, mod_time; + char *src_name = NULL; + Bool run, has_carousel; + Bool udp = 0; + u16 sk_port=0; + GF_Socket *sk = NULL; + LiveSession livesess; + RTPChannel *ch; + char *update_buffer = NULL; + u32 update_buffer_size = 0; + u16 aggregate_on_stream; + Bool adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc; + Bool update_context; + u32 period, ts_delta; + u16 es_id; + + gf_sys_init(0); + + memset(&livesess, 0, sizeof(LiveSession)); + + gf_log_set_level(GF_LOG_INFO); + gf_log_set_tools(0xFFFFFFFF); + + for (i=1; iESID==id)) + ch->carousel_period = period; + } + has_carousel = 1; + } + } + + i=0; + while (ch = gf_list_enum(livesess.streams, &i)) { + if (ch->carousel_period) { + has_carousel = 1; + break; + } + } + update_context = 0; + livesess.carousel_generation = 1; + gf_seng_encode_context(livesess.seng, live_session_callback); + livesess.carousel_generation = 0; + + live_session_send_carousel(&livesess, NULL); + + check = 10; + run = 1; + while (run) { + check--; + if (!check) { + check = 10; + if (gf_prompt_has_input()) { + char c = gf_prompt_get_char(); + switch (c) { + case 'q': + run=0; + break; + case 'U': + livesess.critical = 1; + case 'u': + { + GF_Err e; + char szCom[8192]; + fprintf(stdout, "Enter command to send:\n"); + szCom[0] = 0; + scanf("%[^\t\n]", szCom); + /*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)); + e = gf_seng_aggregate_context(livesess.seng, 0); + livesess.critical = 0; + update_context = 1; + } + break; + case 'E': + livesess.critical = 1; + case 'e': + { + GF_Err e; + char szCom[8192]; + fprintf(stdout, "Enter command to send:\n"); + szCom[0] = 0; + scanf("%[^\t\n]", szCom); + /*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)); + livesess.critical = 0; + e = gf_seng_aggregate_context(livesess.seng, 0); + + } + break; + + case 'p': + { + char rad[GF_MAX_PATH]; + fprintf(stdout, "Enter output file name - \"std\" for stdout: "); + scanf("%s", rad); + e = gf_seng_save_context(livesess.seng, !strcmp(rad, "std") ? NULL : rad); + fprintf(stdout, "Dump done (%s)\n", gf_error_to_string(e)); + } + break; + case 'F': + update_context = 1; + case 'f': + livesess.force_carousel = 1; + break; + } + e = GF_OK; + } + } + + /*process updates from file source*/ + if (src_name) { + mod_time = gf_file_modification_time(src_name); + if (mod_time != last_src_modif) { + FILE *srcf; + char flag_buf[201], *flag; + fprintf(stdout, "Update file modified - processing\n"); + last_src_modif = mod_time; + + srcf = gf_f64_open(src_name, "rt"); + if (!srcf) continue; + + /*checks if we have a broadcast config*/ + fgets(flag_buf, 200, srcf); + fclose(srcf); + + aggregate_on_stream = (u16) -1; + adjust_carousel_time = force_rap = discard_pending = signal_rap = signal_critical = 0; + aggregate_au = version_inc = 1; + period = -1; + ts_delta = 0; + es_id = 0; + + /*find our keyword*/ + flag = strstr(flag_buf, "gpac_broadcast_config "); + if (flag) { + flag += strlen("gpac_broadcast_config "); + /*move to next word*/ + while (flag && (flag[0]==' ')) flag++; + + while (1) { + char *sep = strchr(flag, ' '); + if (sep) sep[0] = 0; + if (!strnicmp(flag, "esid=", 5)) es_id = atoi(flag+5); + else if (!strnicmp(flag, "period=", 7)) period = atoi(flag+7); + else if (!strnicmp(flag, "ts=", 3)) ts_delta = atoi(flag+3); + else if (!strnicmp(flag, "carousel=", 9)) aggregate_on_stream = atoi(flag+9); + else if (!strnicmp(flag, "restamp=", 8)) adjust_carousel_time = atoi(flag+8); + + else if (!strnicmp(flag, "discard=", 8)) discard_pending = atoi(flag+8); + else if (!strnicmp(flag, "aggregate=", 10)) aggregate_au = atoi(flag+10); + else if (!strnicmp(flag, "force_rap=", 10)) force_rap = atoi(flag+10); + else if (!strnicmp(flag, "rap=", 4)) signal_rap = atoi(flag+4); + else if (!strnicmp(flag, "critical=", 9)) signal_critical = atoi(flag+9); + else if (!strnicmp(flag, "vers_inc=", 9)) version_inc = atoi(flag+9); + if (sep) { + sep[0] = ' '; + flag = sep+1; + } else { + break; + } + } + + set_broadcast_params(&livesess, es_id, period, ts_delta, aggregate_on_stream, adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc); + } + + 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)); + e = gf_seng_aggregate_context(livesess.seng, 0); + + update_context = 1; + } + } + + /*process updates from socket source*/ + if (sk) { + char buffer[2049]; + u32 bytes_read; + Bool keep_receive; + u32 update_length; + u32 bytes_received; + + + e = gf_sk_receive(sk, buffer, 2048, 0, &bytes_read); + if (e == GF_OK) { + u32 hdr_length = 0; + u8 cmd_type = buffer[0]; + bytes_received = 0; + switch (cmd_type) { + case 0: + { + GF_BitStream *bs = gf_bs_new(buffer, bytes_read, GF_BITSTREAM_READ); + gf_bs_read_u8(bs); + es_id = gf_bs_read_u16(bs); + aggregate_on_stream = gf_bs_read_u16(bs); + if (aggregate_on_stream==0xFFFF) aggregate_on_stream = -1; + adjust_carousel_time = gf_bs_read_int(bs, 1); + force_rap = gf_bs_read_int(bs, 1); + aggregate_au = gf_bs_read_int(bs, 1); + discard_pending = gf_bs_read_int(bs, 1); + signal_rap = gf_bs_read_int(bs, 1); + signal_critical = gf_bs_read_int(bs, 1); + version_inc = gf_bs_read_int(bs, 1); + gf_bs_read_int(bs, 1); + period = gf_bs_read_u16(bs); + if (period==0xFFFF) period = -1; + ts_delta = gf_bs_read_u16(bs); + update_length = gf_bs_read_u32(bs); + hdr_length = 12; + gf_bs_del(bs); + } + + set_broadcast_params(&livesess, es_id, period, ts_delta, aggregate_on_stream, adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc); + break; + default: + update_length = 0; + break; + } + + if (update_buffer_size <= update_length) { + update_buffer = gf_realloc(update_buffer, update_length+1); + update_buffer_size = update_length+1; + } + if (update_length && (bytes_read>hdr_length) ) { + memcpy(update_buffer, buffer+hdr_length, bytes_read-hdr_length); + bytes_received = bytes_read-hdr_length; + } + while (bytes_received 20)) { + gf_sleep(20); + continue; + } + if (next_time) gf_sleep(next_time); + live_session_send_carousel(&livesess, ch); + } + +exit: + live_session_shutdown(&livesess); + if (update_buffer) gf_free(update_buffer); + if (sk) gf_sk_del(sk); + gf_sys_close(); + return e ? 1 : 0; +} + + diff --git a/applications/mp4box/main.c b/applications/mp4box/main.c index fe2d360..eddc1ac 100644 --- a/applications/mp4box/main.c +++ b/applications/mp4box/main.c @@ -6,7 +6,7 @@ * * This file is part of GPAC / mp4box application * - * GPAC is free software; you can redistribute it and/or modify + * GPAC is gf_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,49 +24,96 @@ #include + +#ifdef GPAC_DISABLE_ISOM + +#error "Cannot compile MP4Box if GPAC is not built with ISO File Format support" + +#else + #include /*RTP packetizer flags*/ #include #include +#include + +#include #define BUFFSIZE 8192 /*in fileimport.c*/ -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE void convert_file_info(char *inName, u32 trackID); 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, const char *tmpdir, char *outfile); 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); +#ifndef GPAC_DISABLE_SCENE_ENCODER GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *logs); GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *outputContext, const char *tmpdir); +#endif + + +GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir, Bool make_wgt); +#endif -GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir); GF_Err dump_cover_art(GF_ISOFile *file, char *inName); +GF_Err dump_chapters(GF_ISOFile *file, char *inName); u32 id3_get_genre_tag(const char *name); -#endif /*in filedump.c*/ -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_SCENE_DUMP GF_Err dump_file_text(char *file, char *inName, u32 dump_mode, Bool do_log); +#endif +#ifndef GPAC_DISABLE_SCENE_STATS void dump_scene_stats(char *file, char *inName, u32 stat_level); #endif void PrintNode(const char *name, u32 graph_type); void PrintBuiltInNodes(u32 graph_type); -void dump_file_mp4(GF_ISOFile *file, char *inName); + +#ifndef GPAC_DISABLE_ISOM_DUMP +void dump_isom_xml(GF_ISOFile *file, char *inName); +#endif + + +#ifndef GPAC_DISABLE_ISOM_HINTING +#ifndef GPAC_DISABLE_ISOM_DUMP void dump_file_rtp(GF_ISOFile *file, char *inName); +#endif +void DumpSDP(GF_ISOFile *file, char *inName); +#endif + void dump_file_ts(GF_ISOFile *file, char *inName); + +#ifndef GPAC_DISABLE_ISOM_DUMP void dump_file_ismacryp(GF_ISOFile *file, char *inName); void dump_timed_text_track(GF_ISOFile *file, u32 trackID, char *inName, Bool is_convert, u32 dump_type); -void DumpSDP(GF_ISOFile *file, char *inName); +#endif /*GPAC_DISABLE_ISOM_DUMP*/ + + void DumpTrackInfo(GF_ISOFile *file, u32 trackID, Bool full_dump); void DumpMovieInfo(GF_ISOFile *file); void PrintLanguages(); const char *GetLanguageCode(char *lang); + +#ifndef GPAC_DISABLE_MPEG2TS void dump_mpeg2_ts(char *mpeg2ts_in, char *pes_out_name); +#endif + + +#ifndef GPAC_DISABLE_STREAMING +void PrintStreamerUsage(); +int stream_file_rtp(int argc, char **argv); +#endif + +int live_session(int argc, char **argv); +void PrintLiveUsage(); Bool quiet = 0; +Bool dvbhdemux =0; +Bool keep_sys_tracks = 0; + /*some global vars for swf import :(*/ u32 swf_flags = 0; @@ -103,13 +150,9 @@ u32 nb_itunes_tags = sizeof(itags) / sizeof(itunes_tag); void PrintVersion() { fprintf(stdout, "MP4Box - GPAC version " GPAC_FULL_VERSION "\n" -#ifdef GPAC_FIXED_POINT - "GPAC compiled in fixed-point version\n" -#endif -#ifdef GPAC_READ_ONLY - "GPAC compiled in read-only version\n" -#endif - "GPAC Copyright: (c) Jean Le Feuvre 2000-2005\n\t\t(c) ENST 2005-200X\n"); + "GPAC Copyright: (c) Jean Le Feuvre 2000-2005\n\t\t(c) ENST 2005-200X\n" + "GPAC Configuration: " GPAC_CONFIGURATION "\n" + "Features: %s\n", gpac_features()); } void PrintGeneralUsage() @@ -120,11 +163,12 @@ void PrintGeneralUsage() " * Note 2: Performs drift checking accross tracks\n" " * Note 3: a value of 0 disables interleaving\n" " -old-inter time same as -inter but doesn't perform drift checking\n" - " -tight: performs tight interleaving (sample based) of the file\n" + " -tight performs tight interleaving (sample based) of the file\n" " * Note: reduces disk seek but increases file size\n" " -flat stores file with all media data first, non-interleaved\n" " -frag time_in_ms fragments file (track fragments of time_in_ms)\n" " * Note: Always disables interleaving\n" + " -ffspace size inserts free space before moof in fragmented files\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" @@ -143,17 +187,17 @@ void PrintGeneralUsage() " -rb ABCD removes given brand from file's alternate brand list\n" " -cprt string adds copyright string to movie\n" " -chap file adds chapter information contained in file\n" - " -rem trackID: removes track from file\n" - " -enable trackID: enables track\n" - " -disable trackID: disables track\n" - " -new: forces creation of a new destination file\n" - " -rem trackID: removes track from file\n" - " -lang [tkID=]LAN: sets track language. LAN is the ISO 639-2 code (eng, und)\n" - " -delay tkID=TIME: sets track start delay in ms.\n" - " -par tkID=PAR: sets visual track pixel aspect ratio (PAR=N:D or \"none\")\n" - " -name tkID=NAME: sets track handler name\n" + " -rem trackID removes track from file\n" + " -enable trackID enables track\n" + " -disable trackID disables track\n" + " -new forces creation of a new destination file\n" + " -rem trackID removes track from file\n" + " -lang [tkID=]LAN sets track language. LAN is the ISO 639-2 code (eng, und)\n" + " -delay tkID=TIME sets track start delay in ms.\n" + " -par tkID=PAR sets visual track pixel aspect ratio (PAR=N:D or \"none\")\n" + " -name tkID=NAME sets track handler name\n" " * NAME can indicate a UTF-8 file (\"file://file name\"\n" - " -itags tag1[:tag2]: sets iTunes tags to file - more info: MP4Box -tag-list.\n" + " -itags tag1[:tag2] sets iTunes tags to file - more info: MP4Box -tag-list.\n" " -split time_sec splits in files of time_sec max duration\n" " * Note: this removes all MPEG-4 Systems media\n" " -split-size size splits in files of max filesize kB.\n" @@ -229,54 +273,71 @@ void PrintImportUsage() { fprintf(stdout, "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" - " \"#pid=ID\": stream import from MPEG-2 TS\n" - " \":dur=D\": imports only the first D seconds\n" - " \":lang=LAN\": sets imported media language code\n" - " \":delay=delay_ms\": sets imported media initial delay in ms\n" - " \":par=PAR\": sets visual pixel aspect ratio (PAR=Num:Den)\n" - " \":name=NAME\": sets track handler name\n" - " \":disable\": imported track(s) will be disabled\n" - " \":group=G\": adds the track as part of the G alternate group.\n" - " * If G is 0, the first available GroupID will be picked.\n" - " \":fps=VAL\": same as -fps option\n" - " \":agg=VAL\": same as -agg option\n" - " \":par=VAL\": same as -par option\n" - " \":dref\": same as -dref option\n" - " \":nodrop\": same as -nodrop option\n" - " \":packed\": same as -packed option\n" - " \":sbr\": same as -sbr option\n" - " \":sbrx\": same as -sbrx option\n" - " \":mpeg4\": same as -mpeg4 option\n" - " \":font=name\": specifies font name for text import (default \"Serif\")\n" - " \":size=s\": specifies font size for text import (default 18)\n" + " \"#video\" \"#audio\" base import for most AV files\n" + " \"#trackID=ID\" track import for IsoMedia and other files\n" + " \"#pid=ID\" stream import from MPEG-2 TS\n" + " \":dur=D\" imports only the first D seconds\n" + " \":lang=LAN\" sets imported media language code\n" + " \":delay=delay_ms\" sets imported media initial delay in ms\n" + " \":par=PAR\" sets visual pixel aspect ratio (PAR=Num:Den)\n" + " \":name=NAME\" sets track handler name\n" + " \":ext=EXT\" overrides file extension when importing\n" + " \":hdlr=code\" sets track handler type to the given code point (4CC)\n" + " \":disable\" imported track(s) will be disabled\n" + " \":group=G\" adds the track as part of the G alternate group.\n" + " If G is 0, the first available GroupID will be picked.\n" + " \":fps=VAL\" same as -fps option\n" + " \":agg=VAL\" same as -agg option\n" + " \":par=VAL\" same as -par option\n" + " \":dref\" same as -dref option\n" + " \":nodrop\" same as -nodrop option\n" + " \":packed\" same as -packed option\n" + " \":sbr\" same as -sbr option\n" + " \":sbrx\" same as -sbrx option\n" + " \":ps\": same as -ps option\n" + " \":psx\": same as -psx option\n" + " \":ovsbr\": same as -ovsbr option\n" + " \":mpeg4\" same as -mpeg4 option\n" + " \":font=name\" specifies font name for text import (default \"Serif\")\n" + " \":size=s\" specifies font size for text import (default 18)\n" + " \":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" + " \":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" "\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" - " -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" - " -keep-all: keeps all existing tracks when using '-add'\n" - " * Note: only used when adding IsoMedia files\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" + " -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" + " -keep-all keeps all existing tracks when using '-add'\n" + " * Note: only used when adding IsoMedia files\n" "\n" "All the following options can be specified as default or for each track.\n" "When specified by track the syntax is \":opt\" or \":opt=val\".\n\n" - " -dref: keeps media data in original file\n" - " -no-drop: forces constant FPS when importing AVI video\n" - " -packed: * forces packed bitstream when importing raw ASP\n" - " -sbr: backward compatible signaling of AAC-SBR\n" - " -sbrx: non-backward compatible signaling of AAC-SBR\n" - " * Note: SBR AAC cannot be detected at import time\n" - " -fps FPS: forces frame rate for video and SUB subtitles import\n" - " * For raw H263 import, default FPS is 15\n" - " * For all other imports, default FPS is 25\n" - " -- THIS IS IGNORED FOR IsoMedia IMPORT --\n" - " -mpeg4: forces MPEG-4 sample descriptions when possible (3GPP2)\n" - " For AAC, forces MPEG-4 AAC signaling even if MPEG-2\n" - " -agg N: aggregates N audio frames in 1 sample (3GP media only)\n" - " * Note: Maximum value is 15 - Disabled by default\n" + " -dref keeps media data in original file\n" + " -no-drop forces constant FPS when importing AVI video\n" + " -packed forces packed bitstream when importing raw ASP\n" + " -sbr backward compatible signaling of AAC-SBR\n" + " -sbrx non-backward compatible signaling of AAC-SBR\n" + " -ps: backward compatible signaling of AAC-PS\n" + " -psx: non-backward compatible signaling of AAC-PS\n" + " -ovsbr: oversample SBR\n" + " * Note: SBR AAC, PS AAC and oversampled SBR cannot be detected at import time\n" + " -fps FPS forces frame rate for video and SUB subtitles import\n" + " FPS is either a number or expressed as timescale-increment\n" + " * For raw H263 import, default FPS is 15\n" + " * For all other imports, default FPS is 25\n" + " !! THIS IS IGNORED FOR IsoMedia IMPORT !!\n" + " -mpeg4 forces MPEG-4 sample descriptions when possible (3GPP2)\n" + " For AAC, forces MPEG-4 AAC signaling even if MPEG-2\n" + " -agg N aggregates N audio frames in 1 sample (3GP media only)\n" + " * Note: Maximum value is 15 - Disabled by default\n" "\n" ); } @@ -284,27 +345,27 @@ void PrintImportUsage() void PrintEncodeUsage() { fprintf(stdout, "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" + " -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" " * Note: cannot be used with -shadow\n" - " -shadow time_ms: forces BIFS sync shadow sample generation every time_ms.\n" + " -shadow time_ms forces BIFS sync shadow sample generation every time_ms.\n" " * Note: cannot be used with -sync\n" - " -log: generates scene codec log file if available\n" - " -ms file: specifies file for track importing\n" + " -log generates scene codec log file if available\n" + " -ms file specifies file for track importing\n" "\nChunk Processing\n" - " -ctx-in file: specifies initial context (MP4/BT/XMT)\n" + " -ctx-in file specifies initial context (MP4/BT/XMT)\n" " * Note: input file must be a commands-only file\n" - " -ctx-out file: specifies storage of updated context (MP4/BT/XMT)\n" + " -ctx-out file specifies storage of updated context (MP4/BT/XMT)\n" "\n" "LASeR Encoding options\n" - " -resolution res: resolution factor (-8 to 7, default 0)\n" + " -resolution res resolution factor (-8 to 7, default 0)\n" " all coords are multiplied by 2^res before truncation\n" - " -coord-bits bits: bits used for encoding truncated coordinates\n" + " -coord-bits bits bits used for encoding truncated coordinates\n" " (0 to 31, default 12)\n" - " -scale-bits bits: extra bits used for encoding truncated scales\n" + " -scale-bits bits extra bits used for encoding truncated scales\n" " (0 to 4, default 0)\n" - " -auto-quant res: resolution is given as if using -resolution\n" + " -auto-quant res resolution is given as if using -resolution\n" " but coord-bits and scale-bits are infered\n" ); } @@ -312,7 +373,7 @@ void PrintEncodeUsage() void PrintEncryptUsage() { fprintf(stdout, "ISMA Encryption/Decryption Options\n" - " -crypt drm_file: crypts a specific track using ISMA AES CTR 128\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" " -set-kms kms_uri changes KMS location for all tracks or a given one.\n" @@ -324,23 +385,23 @@ void PrintEncryptUsage() " File is a list of \"ISMACrypTrack\" elements\n" "\n" "ISMACrypTrack attributes are\n" - " TrackID: ID of track to en/decrypt\n" - " key: AES-128 key formatted (hex string \'0x\'+32 chars)\n" - " salt: CTR IV salt key (64 bits) (hex string \'0x\'+16 chars)\n" + " TrackID ID of track to en/decrypt\n" + " key AES-128 key formatted (hex string \'0x\'+32 chars)\n" + " salt CTR IV salt key (64 bits) (hex string \'0x\'+16 chars)\n" "\nEncryption only attributes:\n" - " Scheme_URI: URI of scheme used\n" - " KMS_URI: URI of key management system\n" + " Scheme_URI URI of scheme used\n" + " KMS_URI URI of key management system\n" " * Note: \'self\' writes key and salt in the file\n" - " selectiveType: selective encryption type - understood values are:\n" - " \"None\": all samples encrypted (default)\n" - " \"RAP\": only encrypts random access units\n" - " \"Non-RAP\": only encrypts non-random access units\n" - " \"Rand\": random selection is performed\n" - " \"X\": Encrypts every first sample out of X (uint)\n" - " \"RandX\": Encrypts one random sample out of X (uint)\n" + " selectiveType selective encryption type - understood values are:\n" + " \"None\" all samples encrypted (default)\n" + " \"RAP\" only encrypts random access units\n" + " \"Non-RAP\" only encrypts non-random access units\n" + " \"Rand\" random selection is performed\n" + " \"X\" Encrypts every first sample out of X (uint)\n" + " \"RandX\" Encrypts one random sample out of X (uint)\n" "\n" - " ipmpType: IPMP Signaling Type: None, IPMP, IPMPX\n" - " ipmpDescriptorID: IPMP_Descriptor ID to use if IPMP(X) is used\n" + " ipmpType IPMP Signaling Type: None, IPMP, IPMPX\n" + " ipmpDescriptorID IPMP_Descriptor ID to use if IPMP(X) is used\n" " * If not set MP4Box will generate one for you\n" "\n" ); @@ -349,111 +410,115 @@ void PrintEncryptUsage() void PrintHintUsage() { fprintf(stdout, "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" + " -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" - " -copy: copies media data to hint track rather than reference\n" + " -copy copies media data to hint track rather than reference\n" " * Note: speeds up server but takes much more space\n" - " -multi [maxptime]: enables frame concatenation in RTP packets if possible\n" - " maxptime: max packet duration in ms (optional, default 100ms)\n" - " -rate ck_rate: specifies rtp rate in Hz when no default for payload\n" + " -multi [maxptime] enables frame concatenation in RTP packets if possible\n" + " maxptime max packet duration in ms (optional, default 100ms)\n" + " -rate ck_rate specifies rtp rate in Hz when no default for payload\n" " * Note: default value is 90000 (MPEG rtp rates)\n" - " -mpeg4: forces MPEG-4 generic payload whenever possible\n" - " -latm: forces MPG4-LATM transport for AAC streams\n" - " -static: enables static RTP payload IDs whenever possible\n" + " -mpeg4 forces MPEG-4 generic payload whenever possible\n" + " -latm forces MPG4-LATM transport for AAC streams\n" + " -static enables static RTP payload IDs whenever possible\n" " * By default, dynamic payloads are always used\n" "\n" "MPEG-4 Generic Payload Options\n" - " -ocr: forces all streams to be synchronized\n" + " -ocr forces all streams to be synchronized\n" " * Most RTSP servers only support synchronized streams\n" - " -rap: signals random access points in RTP packets\n" - " -ts: signals AU Time Stamps in RTP packets\n" - " -size: signals AU size in RTP packets\n" - " -idx: signals AU sequence numbers in RTP packets\n" - " -iod: prevents systems tracks embedding in IOD\n" + " -rap signals random access points in RTP packets\n" + " -ts signals AU Time Stamps in RTP packets\n" + " -size signals AU size in RTP packets\n" + " -idx signals AU sequence numbers in RTP packets\n" + " -iod prevents systems tracks embedding in IOD\n" " * Note: shouldn't be used with -isma option\n" "\n" - " -add-sdp string: adds sdp string to (hint) track (\"-add-sdp tkID:string\")\n" - " or movie. This will take care of SDP lines ordering\n" - " -unhint: removes all hinting information.\n" + " -add-sdp string adds sdp string to (hint) track (\"-add-sdp tkID:string\")\n" + " or movie. This will take care of SDP lines ordering\n" + " -unhint removes all hinting information.\n" "\n"); } void PrintExtractUsage() { fprintf(stdout, "Extracting Options\n" - " -raw TrackID: extracts track in raw format when supported\n" - " -raws TrackID: extract each track sample to a file\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" - " -nhnt TrackID: extracts track in nhnt format\n" - " -nhml TrackID: extracts track in nhml format (XML nhnt).\n" + " -nhnt TrackID extracts track in nhnt format\n" + " -nhml TrackID extracts track in nhml format (XML nhnt).\n" " * Note: \"-nhml +TrackID\" for full dump\n" - " -single TrackID: extracts track to a new mp4 file\n" - " -avi TrackID: extracts visual track to an avi file\n" - " -qcp TrackID: same as \'-raw\' but defaults to QCP file for EVRC/SMV\n" - " -aviraw TK: extracts AVI track in raw format\n" - " $TK can be one of \"video\" \"audio\" \"audioN\"\n" - " -saf: remux file to SAF multiplex\n" + " -single TrackID extracts track to a new mp4 file\n" + " -avi TrackID extracts visual track to an avi file\n" + " -qcp TrackID same as \'-raw\' but defaults to QCP file for EVRC/SMV\n" + " -aviraw TK extracts AVI track in raw format\n" + " $TK can be one of \"video\" \"audio\" \"audioN\"\n" + " -saf remux file to SAF multiplex\n" + " -dvbhdemux demux DVB-H file into IP Datagrams\n" " * Note: can be used when encoding scene descriptions\n" + " -diod extracts file IOD in raw format when supported\n" "\n"); } void PrintDumpUsage() { fprintf(stdout, "Dumping Options\n" - " -std: dumps to stdout instead of file\n" + " -std dumps to stdout instead of file\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" - " -xmt: scene to XMT-A format - removes unknown MPEG4 nodes\n" - " -wrl: scene VRML format - removes unknown VRML nodes\n" - " -x3d: scene to X3D/XML format - removes unknown X3D nodes\n" - " -x3dv: scene to X3D/VRML format - removes unknown X3D nodes\n" - " -lsr: scene to LASeR format\n" - " -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" - " -sdp: dumps SDP description of hinted file\n" - " -dcr: ISMACryp samples structure to XML output\n" + " -bt scene to bt format - removes unknown MPEG4 nodes\n" + " -xmt scene to XMT-A format - removes unknown MPEG4 nodes\n" + " -wrl scene VRML format - removes unknown VRML nodes\n" + " -x3d scene to X3D/XML format - removes unknown X3D nodes\n" + " -x3dv scene to X3D/VRML format - removes unknown X3D nodes\n" + " -lsr scene to LASeR format\n" + " -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" + " -sdp dumps SDP description of hinted file\n" + " -dcr ISMACryp samples structure to XML output\n" + " -dump-cover Extracts cover art\n" + " -dump-chap Extracts chapter file\n" "\n" -#ifndef GPAC_READ_ONLY - " -ttxt: Converts input subtitle to GPAC TTXT format\n" +#ifndef GPAC_DISABLE_ISOM_WRITE + " -ttxt Converts input subtitle to GPAC TTXT format\n" #endif - " -ttxt TrackID: Dumps Text track to GPAC TTXT format\n" -#ifndef GPAC_READ_ONLY - " -srt: Converts input subtitle to SRT format\n" + " -ttxt TrackID Dumps Text track to GPAC TTXT format\n" +#ifndef GPAC_DISABLE_ISOM_WRITE + " -srt Converts input subtitle to SRT format\n" #endif - " -srt TrackID: Dumps Text track to SRT format\n" + " -srt TrackID Dumps Text track to SRT format\n" "\n" - " -stat: generates node/field statistics for scene\n" - " -stats: generates node/field statistics per MPEG-4 Access Unit\n" - " -statx: generates node/field statistics for scene after each AU\n" + " -stat generates node/field statistics for scene\n" + " -stats generates node/field statistics per MPEG-4 Access Unit\n" + " -statx generates node/field statistics for scene after each AU\n" "\n" - " -hash: generates SHA-1 Hash of the input file\n" + " -hash generates SHA-1 Hash of the input file\n" "\n"); } void PrintMetaUsage() { fprintf(stdout, "Meta handling Options\n" - " -set-meta args: sets given meta type - syntax: \"ABCD[:tk=ID]\"\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" " if ID is 0 use moov meta\n" " if ID is not 0 use track meta\n" - " -add-item args: adds resource to meta\n" + " -add-item args adds resource to meta\n" " * syntax: file_path + options (\':\' separated):\n" " tk=ID: meta adressing (file, moov, track)\n" " name=str: item name\n" " mime=mtype: item mime type\n" " encoding=enctype: item content-encoding type\n" " * file_path \"this\" or \"self\": item is the file itself\n" - " -rem-item args: removes resource from meta - syntax: item_ID[:tk=ID]\n" - " -set-primary args: sets item as primary for meta - syntax: item_ID[:tk=ID]\n" - " -set-xml args: sets meta XML data\n" + " -rem-item args removes resource from meta - syntax: item_ID[:tk=ID]\n" + " -set-primary args sets item as primary for meta - syntax: item_ID[:tk=ID]\n" + " -set-xml args sets meta XML data\n" " * syntax: xml_file_path[:tk=ID][:binary]\n" - " -rem-xml [tk=ID]: removes meta XML data\n" - " -dump-xml args: dumps meta XML to file - syntax file_path[:tk=ID]\n" - " -dump-item args: dumps item to file - syntax item_ID[:tk=ID][:path=fileName]\n" - " -package: packages input XML file into an ISO container\n" + " -rem-xml [tk=ID] removes meta XML data\n" + " -dump-xml args dumps meta XML to file - syntax file_path[:tk=ID]\n" + " -dump-item args dumps item to file - syntax item_ID[:tk=ID][:path=fileName]\n" + " -package packages input XML file into an ISO container\n" " * all media referenced except hyperlinks are added to file\n" "\n"); } @@ -466,17 +531,17 @@ void PrintSWFUsage() "MP4Box can import simple Macromedia Flash files (\".SWF\")\n" "You can specify a SWF input file with \'-bt\', \'xmt\' and \'-mp4\' options\n" "\n" - " -global: all SWF defines are placed in first scene replace\n" + " -global all SWF defines are placed in first scene replace\n" " * Note: By default SWF defines are sent when needed\n" - " -no-ctrl: uses a single stream for movie control and dictionary\n" + " -no-ctrl uses a single stream for movie control and dictionary\n" " * Note: this will disable ActionScript\n" - " -no-text: removes all SWF text\n" - " -no-font: removes all embedded SWF Fonts (terminal fonts used)\n" - " -no-line: removes all lines from SWF shapes\n" - " -no-grad: removes all gradients from swf shapes\n" - " -quad: uses quadratic bezier curves instead of cubic ones\n" - " -xlp: support for lines transparency and scalability\n" - " -flatten ang: complementary angle below which 2 lines are merged\n" + " -no-text removes all SWF text\n" + " -no-font removes all embedded SWF Fonts (terminal fonts used)\n" + " -no-line removes all lines from SWF shapes\n" + " -no-grad removes all gradients from swf shapes\n" + " -quad uses quadratic bezier curves instead of cubic ones\n" + " -xlp support for lines transparency and scalability\n" + " -flatten ang complementary angle below which 2 lines are merged\n" " * Note: angle \'0\' means no flattening\n" "\n" ); @@ -485,32 +550,29 @@ void PrintSWFUsage() void PrintUsage() { fprintf (stdout, "MP4Box [option] input [option]\n" -#ifndef GPAC_READ_ONLY - " -h general: general options help\n" - " -h hint: hinting options help\n" - " -h import: import options help\n" - " -h encode: encode options help\n" - " -h meta: meta handling options help\n" -#else - "READ-ONLY VERSION\n" -#endif - " -h extract: extraction options help\n" - " -h dump: dump options help\n" - " -h swf: Flash (SWF) options help\n" - " -h crypt: ISMA E&A options help\n" - " -h format: supported formats help\n" + " -h general general options help\n" + " -h hint hinting options help\n" + " -h import import options help\n" + " -h encode encode options help\n" + " -h meta meta handling options help\n" + " -h extract extraction options help\n" + " -h dump dump options help\n" + " -h swf Flash (SWF) options help\n" + " -h crypt ISMA E&A options help\n" + " -h format supported formats help\n" + " -h rtp streamer help\n" "\n" - " -nodes: lists supported MPEG4 nodes\n" - " -node NodeName: gets MPEG4 node syntax and QP info\n" - " -xnodes: lists supported X3D nodes\n" - " -xnode NodeName: gets X3D node syntax\n" - " -snodes: lists supported SVG nodes\n" - " -snode NodeName: gets SVG node syntax\n" - " -languages: lists supported ISO 639 languages\n" + " -nodes lists supported MPEG4 nodes\n" + " -node NodeName gets MPEG4 node syntax and QP info\n" + " -xnodes lists supported X3D nodes\n" + " -xnode NodeName gets X3D node syntax\n" + " -snodes lists supported SVG nodes\n" + " -snode NodeName gets SVG node syntax\n" + " -languages lists supported ISO 639 languages\n" "\n" - "-quiet: quiet mode\n" - " -v: verbose mode\n" - " -version: gets build version\n" + "-quiet quiet mode\n" + " -v verbose mode\n" + " -version gets build version\n" ); } @@ -523,7 +585,7 @@ void scene_coding_log(void *cbk, u32 log_level, u32 log_tool, const char *fmt, v fflush(logs); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_HINTING /* MP4 File Hinting @@ -681,7 +743,7 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32 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_AUTO_CAROUSEL) fprintf(stdout, "\tMPEG-4 Systems stream carousel enabled\n"); + if (flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) fprintf(stdout, "\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"); @@ -713,7 +775,9 @@ GF_Err HintFile(GF_ISOFile *file, u32 MTUSize, u32 max_ptime, u32 rtp_rate, u32 return GF_OK; } +#endif /*GPAC_DISABLE_ISOM_HINTING*/ +#ifndef GPAC_DISABLE_ISOM_WRITE static void check_media_profile(GF_ISOFile *file, u32 track) { @@ -725,11 +789,11 @@ static void check_media_profile(GF_ISOFile *file, u32 track) switch (esd->decoderConfig->streamType) { case 0x04: PL = gf_isom_get_pl_indication(file, GF_ISOM_PL_VISUAL); - if (esd->decoderConfig->objectTypeIndication==0x20) { + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { GF_M4VDecSpecInfo dsi; gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); if (dsi.VideoPL > PL) gf_isom_set_pl_indication(file, GF_ISOM_PL_VISUAL, dsi.VideoPL); - } else if (esd->decoderConfig->objectTypeIndication==0x21) { + } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) { gf_isom_set_pl_indication(file, GF_ISOM_PL_VISUAL, 0x15); } else if (!PL) { gf_isom_set_pl_indication(file, GF_ISOM_PL_VISUAL, 0xFE); @@ -738,7 +802,10 @@ static void check_media_profile(GF_ISOFile *file, u32 track) case 0x05: PL = gf_isom_get_pl_indication(file, GF_ISOM_PL_AUDIO); switch (esd->decoderConfig->objectTypeIndication) { - case 0x66: case 0x67: case 0x68: case 0x40: + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: + case GPAC_OTI_AUDIO_AAC_MPEG4: gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); if (dsi.audioPL > PL) gf_isom_set_pl_indication(file, GF_ISOM_PL_AUDIO, dsi.audioPL); break; @@ -749,7 +816,6 @@ static void check_media_profile(GF_ISOFile *file, u32 track) } gf_odf_desc_del((GF_Descriptor *) esd); } - void remove_systems_tracks(GF_ISOFile *file) { u32 i, count; @@ -767,6 +833,7 @@ void remove_systems_tracks(GF_ISOFile *file) case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_AUDIO: case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: gf_isom_remove_track_from_root_od(file, i+1); check_media_profile(file, i+1); break; @@ -814,15 +881,15 @@ void remove_systems_tracks(GF_ISOFile *file) u32 get_file_type_by_ext(char *inName) { u32 type = 0; - char *__ext = strrchr(inName, '.'); - if (__ext) { - char ext[20]; - if (!strcmp(__ext, ".gz")) __ext = strrchr(__ext-1, '.'); - strcpy(ext, __ext+1); - __ext = strchr(ext, '.'); - if (__ext) __ext[0] = 0; - - if (!stricmp(ext, "mp4") || !stricmp(ext, "3gp") || !stricmp(ext, "mov") || !stricmp(ext, "3g2")) type = 1; + char *ext = strrchr(inName, '.'); + if (ext) { + char *sep; + if (!strcmp(ext, ".gz")) ext = strrchr(ext-1, '.'); + ext+=1; + sep = strchr(ext, '.'); + if (sep) sep[0] = 0; + + if (!stricmp(ext, "mp4") || !stricmp(ext, "3gp") || !stricmp(ext, "mov") || !stricmp(ext, "3g2") || !stricmp(ext, "3gs")) type = 1; else if (!stricmp(ext, "bt") || !stricmp(ext, "wrl") || !stricmp(ext, "x3dv")) type = 2; else if (!stricmp(ext, "xmt") || !stricmp(ext, "x3d")) type = 3; else if (!stricmp(ext, "lsr") || !stricmp(ext, "saf")) type = 6; @@ -830,16 +897,22 @@ u32 get_file_type_by_ext(char *inName) else if (!stricmp(ext, "xsr")) type = 4; else if (!stricmp(ext, "xml")) type = 4; else if (!stricmp(ext, "swf")) type = 5; - else if (!stricmp(ext, "jp2")) return 0; + else if (!stricmp(ext, "jp2")) { + if (sep) sep[0] = '.'; + return 0; + } else type = 0; + + if (sep) sep[0] = '.'; } + /*try open file in read mode*/ if (!type && gf_isom_probe_file(inName)) type = 1; return type; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE static Bool can_convert_to_isma(GF_ISOFile *file) { u32 spec = gf_isom_guess_specification(file); @@ -848,7 +921,7 @@ static Bool can_convert_to_isma(GF_ISOFile *file) } #endif -static void progress_quiet(void *cbck, char *title, u32 done, u32 total) { } +static void progress_quiet(void *cbck, char *title, u64 done, u64 total) { } typedef struct @@ -883,7 +956,7 @@ typedef struct /*for SDP_EX, AddTrack and RemTrack*/ #define MAX_CUMUL_OPS 20 -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE static Bool parse_meta_args(MetaAction *meta, char *opts) { Bool ret = 0; @@ -1079,21 +1152,25 @@ int main(int argc, char **argv) { char outfile[5000]; GF_Err e; +#ifndef GPAC_DISABLE_SCENE_ENCODER GF_SMEncodeOptions opts; - Double InterleavingTime, split_duration, split_start, import_fps; +#endif + Double InterleavingTime, split_duration, split_start, import_fps, dash_duration; SDPLine sdp_lines[MAX_CUMUL_OPS]; MetaAction metas[MAX_CUMUL_OPS]; - char *szFilesToCat[MAX_CUMUL_OPS]; - char *szTracksToAdd[MAX_CUMUL_OPS]; TrackAction tracks[MAX_CUMUL_OPS]; TSELAction tsel_acts[MAX_CUMUL_OPS]; + u64 movie_time; u32 brand_add[MAX_CUMUL_OPS], brand_rem[MAX_CUMUL_OPS]; - u32 i, MTUSize, 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; - Bool HintIt, needSave, FullInter, Frag, HintInter, dump_std, dump_rtp, dump_mode, regular_iod, trackID, HintCopy, remove_sys_tracks, remove_hint, force_new, keep_sys_tracks, remove_root_od, import_subtitle; - 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, x3d_info, chunk_mode, dump_ts, do_saf, dump_m2ts, dump_cart, do_hash, verbose, force_cat; - char *inName, *outName, *arg, *mediaSource, *tmpdir, *input_ctx, *output_ctx, *drm_file, *avi2raw, *cprt, *chap_file, *pes_dump, *itunes_tags, *pack_file, *raw_cat; + u32 i, MTUSize, 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, frags_per_sidx; + Bool HintIt, needSave, FullInter, Frag, HintInter, dump_std, dump_rtp, dump_mode, regular_iod, trackID, HintCopy, 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, x3d_info, chunk_mode, dump_ts, do_saf, dump_m2ts, dump_cart, do_hash, verbose, force_cat, pack_wgt; + 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; GF_ISOFile *file; - + Bool stream_rtp=0; + Bool live_scene=0; + Bool dump_iod=0; + Bool seg_at_rap =0; if (argc < 2) { PrintUsage(); @@ -1105,19 +1182,26 @@ int main(int argc, char **argv) split_duration = 0.0; split_start = -1.0; InterleavingTime = 0.5; + dash_duration = 0.0; import_fps = 0; import_flags = 0; split_size = 0; + movie_time = 0; MTUSize = 1450; HintCopy = FullInter = HintInter = encode = do_log = old_interleave = do_saf = do_hash = verbose = 0; chunk_mode = dump_mode = Frag = force_ocr = remove_sys_tracks = agg_samples = remove_hint = keep_sys_tracks = remove_root_od = 0; - x3d_info = conv_type = HintIt = needSave = print_sdp = print_info = regular_iod = dump_std = open_edit = dump_isom = dump_rtp = dump_cr = dump_srt = dump_ttxt = force_new = dump_ts = dump_m2ts = dump_cart = import_subtitle = force_cat = 0; + x3d_info = 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; + frags_per_sidx = 1; track_dump_type = 0; ismaCrypt = 0; file = NULL; itunes_tags = pes_dump = NULL; + seg_name = NULL; + +#ifndef GPAC_DISABLE_SCENE_ENCODER memset(&opts, 0, sizeof(opts)); - +#endif + trackID = stat_level = hint_flags = 0; info_track_id = 0; do_flat = 0; @@ -1151,6 +1235,12 @@ int main(int argc, char **argv) info_track_id=0; } } + /*******************************************************************************/ + else if (!stricmp(arg, "-dvbhdemux")) { + dvbhdemux = 1; + } + /********************************************************************************/ +#ifndef GPAC_DISABLE_MEDIA_EXPORT else if (!stricmp(arg, "-raw")) { CHECK_NEXT_ARG track_dump_type = GF_EXPORT_NATIVE; @@ -1207,13 +1297,32 @@ int main(int argc, char **argv) trackID = atoi(argv[i+1]); i++; } +#endif /*GPAC_DISABLE_MEDIA_EXPORT*/ + +#ifndef GPAC_DISABLE_STREAMING + else if (!stricmp(arg, "-rtp")) { + stream_rtp = 1; + } +#endif + else if (!stricmp(arg, "-live")) { + live_scene = 1; + } + else if (!stricmp(arg, "-diod")) { + dump_iod = 1; + } +#ifndef GPAC_DISABLE_VRML else if (!stricmp(arg, "-node")) { CHECK_NEXT_ARG PrintNode(argv[i+1], 0); return (0); } else if (!stricmp(arg, "-xnode")) { CHECK_NEXT_ARG PrintNode(argv[i+1], 1); return (0); } - else if (!stricmp(arg, "-snode")) { CHECK_NEXT_ARG PrintNode(argv[i+1], 2); return (0); } else if (!stricmp(arg, "-nodes")) { PrintBuiltInNodes(0); return (0); } else if (!stricmp(arg, "-xnodes")) { PrintBuiltInNodes(1); return (0); } +#endif +#ifndef GPAC_DISABLE_SVG + else if (!stricmp(arg, "-snode")) { CHECK_NEXT_ARG PrintNode(argv[i+1], 2); return (0); } else if (!stricmp(arg, "-snodes")) { PrintBuiltInNodes(2); return (0); } else if (!stricmp(arg, "-std")) dump_std = 1; +#endif + +#if !defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_SCENE_DUMP) else if (!stricmp(arg, "-bt")) dump_mode = 1 + GF_SM_DUMP_BT; else if (!stricmp(arg, "-xmt")) dump_mode = 1 + GF_SM_DUMP_XMTA; else if (!stricmp(arg, "-wrl")) dump_mode = 1 + GF_SM_DUMP_VRML; @@ -1221,11 +1330,14 @@ int main(int argc, char **argv) else if (!stricmp(arg, "-x3d")) dump_mode = 1 + GF_SM_DUMP_X3D_XML; else if (!stricmp(arg, "-lsr")) dump_mode = 1 + GF_SM_DUMP_LASER; else if (!stricmp(arg, "-svg")) dump_mode = 1 + GF_SM_DUMP_SVG; +#endif /*defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_SCENE_DUMP)*/ + else if (!stricmp(arg, "-stat")) stat_level = 1; else if (!stricmp(arg, "-stats")) stat_level = 2; else if (!stricmp(arg, "-statx")) stat_level = 3; else if (!stricmp(arg, "-diso")) dump_isom = 1; else if (!stricmp(arg, "-dump-cover")) dump_cart = 1; + else if (!stricmp(arg, "-dump-chap")) dump_chap = 1; else if (!stricmp(arg, "-hash")) do_hash = 1; else if (!stricmp(arg, "-dmp4")) { @@ -1244,7 +1356,7 @@ int main(int argc, char **argv) } else { trackID = 0; } -#ifdef GPAC_READ_ONLY +#ifdef GPAC_DISABLE_ISOM_WRITE if (trackID) { fprintf(stdout, "Error: Read-Only version - subtitle conversion not available\n"); return 1; } #endif if (!stricmp(arg, "-ttxt")) dump_ttxt = 1; @@ -1258,7 +1370,7 @@ int main(int argc, char **argv) } } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*SWF importer options*/ else if (!stricmp(arg, "-global")) swf_flags |= GF_SM_SWF_STATIC_DICT; else if (!stricmp(arg, "-no-ctrl")) swf_flags &= ~GF_SM_SWF_SPLIT_TIMELINE; @@ -1302,8 +1414,22 @@ int main(int argc, char **argv) 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, "-frags-per-sidx")) { + CHECK_NEXT_ARG + frags_per_sidx = atoi(argv[i+1]); + i++; + } else if (!stricmp(arg, "-segment-name")) { + CHECK_NEXT_ARG + seg_name = argv[i+1]; + i++; } else if (!stricmp(arg, "-itags")) { CHECK_NEXT_ARG itunes_tags = argv[i+1]; i++; open_edit = 1; } +#ifndef GPAC_DISABLE_ISOM_HINTING else if (!stricmp(arg, "-hint")) { open_edit = 1; HintIt = 1; } else if (!stricmp(arg, "-unhint")) { open_edit = 1; remove_hint = 1; } else if (!stricmp(arg, "-copy")) HintCopy = 1; @@ -1313,7 +1439,10 @@ int main(int argc, char **argv) needSave = 1; } else if (!stricmp(arg, "-ocr")) force_ocr = 1; else if (!stricmp(arg, "-latm")) hint_flags |= GP_RTP_PCK_USE_LATM_AAC; - else if (!stricmp(arg, "-rap")) hint_flags |= GP_RTP_PCK_SIGNAL_RAP; + else if (!stricmp(arg, "-rap")) { + hint_flags |= GP_RTP_PCK_SIGNAL_RAP; + seg_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; @@ -1327,10 +1456,16 @@ int main(int argc, char **argv) else max_ptime=0; } } +#endif else if (!stricmp(arg, "-mpeg4")) { +#ifndef GPAC_DISABLE_ISOM_HINTING hint_flags |= GP_RTP_PCK_FORCE_MPEG4; +#endif +#ifndef GPAC_DISABLE_MEDIA_IMPORT import_flags |= GF_IMPORT_FORCE_MPEG4; +#endif } +#ifndef GPAC_DISABLE_ISOM_HINTING else if (!stricmp(arg, "-mtu")) { CHECK_NEXT_ARG MTUSize = atoi(argv[i+1]); i++; } else if (!stricmp(arg, "-cardur")) { CHECK_NEXT_ARG car_dur = atoi(argv[i+1]); i++; } else if (!stricmp(arg, "-rate")) { CHECK_NEXT_ARG rtp_rate = atoi(argv[i+1]); i++; } @@ -1360,11 +1495,15 @@ int main(int argc, char **argv) nb_sdp_ex++; i++; } +#endif /*GPAC_DISABLE_ISOM_HINTING*/ + else if (!stricmp(arg, "-single")) { +#ifndef GPAC_DISABLE_MEDIA_EXPORT CHECK_NEXT_ARG track_dump_type = GF_EXPORT_MP4; trackID = atoi(argv[i+1]); i++; +#endif } else if (!stricmp(arg, "-iod")) regular_iod = 1; else if (!stricmp(arg, "-flat")) do_flat = 1; @@ -1373,24 +1512,27 @@ int main(int argc, char **argv) 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 (nb_add>=MAX_CUMUL_OPS) { - fprintf(stdout, "Sorry - no more than %d add operations allowed\n", MAX_CUMUL_OPS); - return 1; - } - szTracksToAdd[nb_add] = argv[i+1]; nb_add++; i++; } else if (!stricmp(arg, "-cat")) { CHECK_NEXT_ARG - if (nb_cat>=MAX_CUMUL_OPS) { - fprintf(stdout, "Sorry - no more than %d cat operations allowed\n", MAX_CUMUL_OPS); - return 1; - } - szFilesToCat[nb_cat] = argv[i+1]; nb_cat++; i++; } + else if (!stricmp(arg, "-time")) { + struct tm time; + CHECK_NEXT_ARG + memset(&time, 0, sizeof(struct tm)); + sscanf(argv[i+1], "%d/%d/%d-%d:%d:%d", &time.tm_mday, &time.tm_mon, &time.tm_year, &time.tm_hour, &time.tm_min, &time.tm_sec); + time.tm_isdst=0; + time.tm_year -= 1900; + time.tm_mon -= 1; + open_edit = 1; + movie_time = 2082758400; + movie_time += mktime(&time); + i++; + } else if (!stricmp(arg, "-force-cat")) force_cat = 1; else if (!stricmp(arg, "-raw-cat")) { CHECK_NEXT_ARG @@ -1521,11 +1663,11 @@ int main(int argc, char **argv) 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(stdout, "Bad format for track name - expecting ID=name got %s\n", argv[i+1]); return 1; } tracks[nb_track_act].act_type = 5; - tracks[nb_track_act].hdl_name = ext+1; + tracks[nb_track_act].hdl_name = strchr(argv[i+1], '=') + 1; ext[0] = 0; tracks[nb_track_act].trackID = atoi(szTK); ext[0] = '='; @@ -1533,24 +1675,36 @@ int main(int argc, char **argv) nb_track_act++; i++; } +#ifndef GPAC_DISABLE_MEDIA_EXPORT else if (!stricmp(arg, "-dref")) import_flags |= GF_IMPORT_USE_DATAREF; else if (!stricmp(arg, "-no-drop") || !stricmp(arg, "-nodrop")) import_flags |= GF_IMPORT_NO_FRAME_DROP; else if (!stricmp(arg, "-packed")) import_flags |= GF_IMPORT_FORCE_PACKED; else if (!stricmp(arg, "-sbr")) import_flags |= GF_IMPORT_SBR_IMPLICIT; else if (!stricmp(arg, "-sbrx")) import_flags |= GF_IMPORT_SBR_EXPLICIT; + else if (!stricmp(arg, "-ps")) import_flags |= GF_IMPORT_PS_IMPLICIT; + else if (!stricmp(arg, "-psx")) import_flags |= GF_IMPORT_PS_EXPLICIT; + else if (!stricmp(arg, "-ovsbr")) import_flags |= GF_IMPORT_OVSBR; else if (!stricmp(arg, "-fps")) { CHECK_NEXT_ARG if (!strcmp(argv[i+1], "auto")) import_fps = 10000.0; - else import_fps = atof(argv[i+1]); + else if (strchr(argv[i+1], '-')) { + u32 ticks, dts_inc; + sscanf(argv[i+1], "%d-%d", &ticks, &dts_inc); + if (!dts_inc) dts_inc=1; + import_fps = ticks; + import_fps /= dts_inc; + } else import_fps = atof(argv[i+1]); i++; } else if (!stricmp(arg, "-agg")) { CHECK_NEXT_ARG agg_samples = atoi(argv[i+1]); i++; } - else if (!stricmp(arg, "-keep-sys") || !stricmp(arg, "-keepsys")) keep_sys_tracks = 1; else if (!stricmp(arg, "-keep-all") || !stricmp(arg, "-keepall")) import_flags |= GF_IMPORT_KEEP_ALL_TRACKS; +#endif /*GPAC_DISABLE_MEDIA_EXPORT*/ + else if (!stricmp(arg, "-keep-sys") || !stricmp(arg, "-keepsys")) keep_sys_tracks = 1; else if (!stricmp(arg, "-ms")) { CHECK_NEXT_ARG mediaSource = argv[i+1]; i++; } 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_SCENE_ENCODER else if (!stricmp(arg, "-def")) opts.flags |= GF_SM_ENCODE_USE_NAMES; else if (!stricmp(arg, "-sync")) { CHECK_NEXT_ARG @@ -1605,6 +1759,7 @@ int main(int argc, char **argv) input_ctx = argv[i+1]; i++; } +#endif /*GPAC_DISABLE_SCENE_ENCODER*/ else if (!strcmp(arg, "-crypt")) { CHECK_NEXT_ARG ismaCrypt = 1; @@ -1741,6 +1896,12 @@ int main(int argc, char **argv) pack_file = argv[i+1]; i++; } + else if (!stricmp(arg, "-mgt")) { + CHECK_NEXT_ARG + pack_file = argv[i+1]; + pack_wgt = 1; + i++; + } else if (!stricmp(arg, "-brand")) { char *b = argv[i+1]; @@ -1781,31 +1942,31 @@ int main(int argc, char **argv) } else if (!stricmp(arg, "-h")) { 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], "dump")) PrintDumpUsage(); - else if (!strcmp(argv[i+1], "swf")) PrintSWFUsage(); -#ifndef GPAC_READ_ONLY - else if (!strcmp(argv[i+1], "general")) PrintGeneralUsage(); - else if (!strcmp(argv[i+1], "hint")) PrintHintUsage(); else if (!strcmp(argv[i+1], "import")) PrintImportUsage(); else if (!strcmp(argv[i+1], "format")) PrintFormats(); + else if (!strcmp(argv[i+1], "hint")) PrintHintUsage(); else if (!strcmp(argv[i+1], "encode")) PrintEncodeUsage(); else if (!strcmp(argv[i+1], "crypt")) PrintEncryptUsage(); else if (!strcmp(argv[i+1], "meta")) PrintMetaUsage(); -#endif + else if (!strcmp(argv[i+1], "swf")) PrintSWFUsage(); + else if (!strcmp(argv[i+1], "rtp")) PrintStreamerUsage(); + else if (!strcmp(argv[i+1], "live")) PrintLiveUsage (); else if (!strcmp(argv[i+1], "all")) { -#ifndef GPAC_READ_ONLY PrintGeneralUsage(); - PrintHintUsage(); + PrintExtractUsage(); + PrintDumpUsage(); PrintImportUsage(); PrintFormats(); + PrintHintUsage(); PrintEncodeUsage(); PrintEncryptUsage(); PrintMetaUsage(); -#endif - PrintExtractUsage(); - PrintDumpUsage(); PrintSWFUsage(); + PrintStreamerUsage(); + PrintLiveUsage (); } else PrintUsage(); return 0; @@ -1817,7 +1978,7 @@ int main(int argc, char **argv) fprintf(stdout, "\t%s\t%s\n", itags[i].name, itags[i].comment); } return 0; - } else { + } else if (!live_scene && !stream_rtp) { fprintf(stdout, "Option %s unknown. Please check usage\n", arg); return 1; } @@ -1827,6 +1988,15 @@ int main(int argc, char **argv) return 1; } + if (live_scene) { + return live_session(argc, argv); + } +#ifndef GPAC_DISABLE_STREAMING + if (stream_rtp) { + return stream_file_rtp(argc, argv); + } +#endif /*GPAC_DISABLE_STREAMING*/ + if (raw_cat) { char chunk[4096]; FILE *fin, *fout; @@ -1863,7 +2033,7 @@ int main(int argc, char **argv) } /*init libgpac*/ - gf_sys_init(); + gf_sys_init(0); if (do_saf && !encode) { @@ -1874,12 +2044,15 @@ int main(int argc, char **argv) } } +#ifndef GPAC_DISABLE_SCENE_DUMP if (dump_mode == 1 + GF_SM_DUMP_SVG) { if (strstr(inName, ".srt") || strstr(inName, ".ttxt")) import_subtitle = 2; } +#endif + if (import_subtitle && !trackID) { -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_MEDIA_IMPORT GF_MediaImporter import; file = gf_isom_open("ttxt_convert", GF_ISOM_OPEN_WRITE, NULL); memset(&import, 0, sizeof(GF_MediaImporter)); @@ -1897,7 +2070,9 @@ int main(int argc, char **argv) while (outfile[strlen(outfile)-1] != '.') outfile[strlen(outfile)-1] = 0; outfile[strlen(outfile)-1] = 0; } +#ifndef GPAC_DISABLE_ISOM_DUMP dump_timed_text_track(file, gf_isom_get_track_id(file, 1), dump_std ? NULL : outfile, 1, (import_subtitle==2) ? 2 : dump_srt); +#endif gf_isom_delete(file); gf_delete_file("ttxt_convert"); if (e) { @@ -1906,17 +2081,18 @@ int main(int argc, char **argv) } return 0; #else - fprintf(stdout, "Error: read-only version\n"); + fprintf(stdout, "Feature not supported\n"); return 1; #endif } -#ifndef GPAC_READ_ONLY + +#if !defined(GPAC_DISABLE_MEDIA_IMPORT) && !defined(GPAC_DISABLE_ISOM_WRITE) if (nb_add) { u8 open_mode = GF_ISOM_OPEN_EDIT; if (force_new) { open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT; } else { - FILE *test = fopen(inName, "rb"); + FILE *test = gf_f64_open(inName, "rb"); if (!test) { open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT; if (!outName) outName = inName; @@ -1930,14 +2106,18 @@ int main(int argc, char **argv) fprintf(stdout, "Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) ); return 1; } - for (i=0; i0) ? 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, &file, &missing_bytes); + fprintf(stdout, "Truncated file - missing "LLD" bytes\n", missing_bytes); + } + if (!file) { if (open_edit && nb_meta_act) { file = gf_isom_open(inName, GF_ISOM_WRITE_EDIT, tmpdir); @@ -2071,22 +2265,46 @@ int main(int argc, char **argv) break; /*used for .saf / .lsr dump*/ case 6: +#ifndef GPAC_DISABLE_SCENE_DUMP if ((dump_mode==1+GF_SM_DUMP_LASER) || (dump_mode==1+GF_SM_DUMP_SVG)) { break; } +#endif default: if (!open_edit && file_exists && !gf_isom_probe_file(inName) && track_dump_type) { } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE else if (!open_edit && file_exists /* && !gf_isom_probe_file(inName) */ && !dump_mode) { + /*************************************************************************************************/ + if(dvbhdemux) + { + GF_MediaImporter import; + file = gf_isom_open("ttxt_convert", GF_ISOM_OPEN_WRITE, NULL); + memset(&import, 0, sizeof(GF_MediaImporter)); + import.dest = file; + import.in_name = inName; + 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)); + gf_isom_delete(file); + gf_delete_file("ttxt_convert"); + return 1; + } + } + if (dump_m2ts) { +#ifndef GPAC_DISABLE_MPEG2TS dump_mpeg2_ts(inName, pes_dump); +#endif } else { convert_file_info(inName, info_track_id); } return 0; } + + #endif else if (open_edit) { file = gf_isom_open(inName, GF_ISOM_WRITE_EDIT, tmpdir); @@ -2117,7 +2335,7 @@ int main(int argc, char **argv) outfile[strlen(outfile)-1] = 0; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_MEDIA_EXPORT if (track_dump_type & GF_EXPORT_AVI_NATIVE) { char szFile[1024]; GF_MediaExporter mdump; @@ -2147,22 +2365,36 @@ int main(int argc, char **argv) return 0; } +#endif /*GPAC_DISABLE_MEDIA_EXPORT*/ + +#ifndef GPAC_DISABLE_SCENE_DUMP if (dump_mode) { e = dump_file_text(inName, dump_std ? NULL : outfile, dump_mode-1, do_log); if (e) goto err_exit; } +#endif + +#ifndef GPAC_DISABLE_SCENE_STATS if (stat_level) dump_scene_stats(inName, dump_std ? NULL : outfile, stat_level); #endif + +#ifndef GPAC_DISABLE_ISOM_HINTING 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 (dump_isom) dump_file_mp4(file, dump_std ? NULL : outfile); - if (dump_rtp) dump_file_rtp(file, dump_std ? NULL : outfile); - if (dump_ts) dump_file_ts(file, dump_std ? NULL : outfile); +#ifndef GPAC_DISABLE_ISOM_DUMP + if (dump_isom) dump_isom_xml(file, dump_std ? NULL : outfile); if (dump_cr) dump_file_ismacryp(file, dump_std ? NULL : outfile); if ((dump_ttxt || dump_srt) && trackID) dump_timed_text_track(file, trackID, dump_std ? NULL : outfile, 0, dump_srt); +#ifndef GPAC_DISABLE_ISOM_HINTING + if (dump_rtp) dump_file_rtp(file, dump_std ? NULL : outfile); +#endif +#endif + + if (dump_ts) dump_file_ts(file, dump_std ? NULL : outfile); if (do_hash) { u8 hash[20]; e = gf_media_get_file_hash(inName, hash); @@ -2172,13 +2404,45 @@ int main(int argc, char **argv) fprintf(stdout, "\n"); } if (dump_cart) dump_cover_art(file, outfile); + if (dump_chap) dump_chapters(file, outfile); -#ifndef GPAC_READ_ONLY + if (dump_iod) { + GF_InitialObjectDescriptor *iod = (GF_InitialObjectDescriptor *)gf_isom_get_root_od(file); + if (!iod) { + fprintf(stdout, "File %s has no IOD", inName); + } else { + char szName[GF_MAX_PATH]; + FILE *iodf; + GF_BitStream *bs; + + sprintf(szName, "%s.iod", outfile); + iodf = gf_f64_open(szName, "wb"); + if (!iodf) { + fprintf(stdout, "Cannot open destination %s\n", szName); + } else { + char *desc; + u32 size; + bs = gf_bs_from_file(iodf, GF_BITSTREAM_WRITE); + if (gf_odf_desc_write((GF_Descriptor *)iod, &desc, &size)==GF_OK) { + fwrite(desc, 1, size, iodf); + gf_free(desc); + } else { + fprintf(stdout, "Error writing IOD\n", szName); + } + fclose(iodf); + } + } + } + +#ifndef GPAC_DISABLE_ISOM_WRITE if (split_duration || split_size) { split_isomedia_file(file, split_duration, split_size, inName, InterleavingTime, split_start, tmpdir, outName); /*never save file when splitting is desired*/ open_edit = 0; } +#endif + +#ifndef GPAC_DISABLE_MEDIA_EXPORT if (do_saf || track_dump_type) { char szFile[1024]; GF_MediaExporter mdump; @@ -2211,7 +2475,7 @@ int main(int argc, char **argv) if (meta->trackID) tk = gf_isom_get_track_by_id(file, meta->trackID); switch (meta->act_type) { -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE case 0: /*note: we don't handle file brand modification, this is an author stuff and cannot be guessed from meta type*/ e = gf_isom_set_meta_type(file, meta->root_meta, tk, meta->meta_4cc); @@ -2260,8 +2524,7 @@ int main(int argc, char **argv) return 0; } -#ifndef GPAC_READ_ONLY - +#ifndef GPAC_DISABLE_ISOM_WRITE for (i=0; i0) { + u32 tk, k; + for (k=0; k<(u32) count; k++) { + gf_isom_get_reference(file, j+1, GF_4CC('c','h','a','p'), k+1, &tk); + if (tk==i+1) { + is_chap = 1; + break; + } + } + if (is_chap) break; + } + if (is_chap) break; + } + /*this is a subtitle track*/ + if (!is_chap) + gf_isom_set_media_type(file, i+1, GF_ISOM_MEDIA_SUBT); + } + break; } } - gf_isom_set_brand_info(file, major_brand, 0); + gf_isom_set_brand_info(file, major_brand, 1); gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_MP42, 1); needSave = 1; } + +#ifndef GPAC_DISABLE_MCRYPT if (ismaCrypt) { if (ismaCrypt == 1) { if (!drm_file) { @@ -2400,6 +2697,7 @@ int main(int argc, char **argv) if (e) goto err_exit; needSave = 1; } +#endif /*GPAC_DISABLE_MCRYPT*/ } else if (outName) { strcpy(outfile, outName); } @@ -2536,18 +2834,18 @@ int main(int argc, char **argv) case GF_ISOM_ITUNE_COVER_ART: { char *d, *ext; - FILE *t = fopen(val, "rb"); - fseek(t, 0, SEEK_END); - tlen = ftell(t); - fseek(t, 0, SEEK_SET); - d = malloc(sizeof(char) * tlen); - fread(d, tlen, 1, t); + FILE *t = gf_f64_open(val, "rb"); + gf_f64_seek(t, 0, SEEK_END); + tlen = (u32) gf_f64_tell(t); + gf_f64_seek(t, 0, SEEK_SET); + d = gf_malloc(sizeof(char) * tlen); + tlen = fread(d, sizeof(char), tlen, t); fclose(t); ext = strrchr(val, '.'); if (!stricmp(ext, ".png")) tlen |= 0x80000000; e = gf_isom_apple_set_tag(file, GF_ISOM_ITUNE_COVER_ART, d, tlen); - free(d); + gf_free(d); } break; case GF_ISOM_ITUNE_TEMPO: @@ -2601,11 +2899,34 @@ int main(int argc, char **argv) } } - if (Frag) { + if (movie_time) { + gf_isom_set_creation_time(file, movie_time); + for (i=0; i #include -#ifndef GPAC_READ_ONLY - - #ifdef WIN32 #include #else @@ -89,9 +86,16 @@ static u32 put_pixel(FILE *fout, u32 type, u32 pf, char *ptr) case GF_PIXEL_BGR_32: case GF_PIXEL_RGBA: + //probably due to tinygl bug - verify +#ifndef GPAC_USE_TINYGL fputc(ptr[3], fout); fputc(ptr[2], fout); fputc(ptr[1], fout); +#else + fputc(ptr[2], fout); + fputc(ptr[1], fout); + fputc(ptr[0], fout); +#endif return 4; case GF_PIXEL_RGB_24: @@ -155,12 +159,12 @@ void write_bmp(GF_VideoSurface *fb, char *rad_name, u32 img_num) char *ptr, *prev; prev = strrchr(rad_name, '.'); - if (prev) prev[0] = '\0'; + //if (prev) prev[0] = '\0'; if (fb->pixel_format==GF_PIXEL_GREYSCALE) sprintf(str, "%s_%d_depth.bmp", rad_name, img_num); else sprintf(str, "%s_%d.bmp", rad_name, img_num); - fout = fopen(str, "wb"); + fout = gf_f64_open(str, "wb"); if (!fout) return; memset(&fh, 0, sizeof(fh)); @@ -175,7 +179,7 @@ void write_bmp(GF_VideoSurface *fb, char *rad_name, u32 img_num) if (fb->pixel_format==GF_PIXEL_GREYSCALE) fi.biBitCount = 24; else fi.biBitCount = 24; fi.biCompression = BI_RGB; - fi.biSizeImage = fb->pitch * fb->height; + fi.biSizeImage = fb->pitch_y * fb->height; /*NOT ALIGNED!!*/ fwrite(&fh.bfType, 2, 1, fout); @@ -185,15 +189,27 @@ void write_bmp(GF_VideoSurface *fb, char *rad_name, u32 img_num) fwrite(&fh.bfOffBits, 4, 1, fout); fwrite(&fi, 1, 40, fout); - +//#ifndef GPAC_USE_TINYGL for (j=fb->height; j>0; j--) { - ptr = fb->video_buffer + (j-1)*fb->pitch; + ptr = fb->video_buffer + (j-1)*fb->pitch_y; for (i=0;iwidth; i++) { u32 res = put_pixel(fout, 0, fb->pixel_format, ptr); assert(res); ptr += res; } } +//#else +#if 0 + for (j=0; jheight; j++) { + ptr = fb->video_buffer + j*fb->pitch; + for (i=0;iwidth; i++) { + u32 res = put_pixel(fout, 0, fb->pixel_format, ptr); + assert(res); + ptr += res; + } + } +#endif + fclose(fout); } @@ -208,7 +224,7 @@ void write_depthfile(GF_VideoSurface *fb, char *rad_name, u32 img_num) depth = (unsigned char *) fb->video_buffer; - fout = fopen("dump_depth", "wb"); + fout = gf_f64_open("dump_depth", "wb"); if (!fout) return; for (j=0; jheight; j++) { for (i=0;iwidth; i++) { @@ -234,14 +250,14 @@ void write_texture_file(GF_VideoSurface *fb, char *rad_name, u32 img_num, u32 du buf = (unsigned char *) fb->video_buffer; - if (dump_mode==6) fout = fopen("dump_rgbds", "wb"); - else if (dump_mode==9) fout = fopen("dump_rgbd", "wb"); + if (dump_mode==6) fout = gf_f64_open("dump_rgbds", "wb"); + else if (dump_mode==9) fout = gf_f64_open("dump_rgbd", "wb"); else return; if (!fout) return; for (j=0; jheight; j++) { for (i=0;iwidth*4; i++) { - val = fputc(buf[i+j*fb->pitch], fout); + val = fputc(buf[i+j*fb->pitch_y], fout); } } fclose(fout); @@ -264,12 +280,12 @@ void write_raw(GF_VideoSurface *fb, char *rad_name, u32 img_num) sprintf(str, "%s_%d.raw", rad_name, img_num); } - fout = fopen(str, "wb"); + fout = gf_f64_open(str, "wb"); if (!fout) return; for (j=0;jheight; j++) { - ptr = fb->video_buffer + j*fb->pitch; + ptr = fb->video_buffer + j*fb->pitch_y; for (i=0;iwidth; i++) { u32 res = put_pixel(fout, 0, fb->pixel_format, ptr); assert(res); @@ -281,7 +297,7 @@ void write_raw(GF_VideoSurface *fb, char *rad_name, u32 img_num) /* creates a .bmp format greyscale image of the byte depthbuffer and a binary with only the content of the depthbuffer */ -void dump_depth (GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, char *conv_buf, avi_t *avi_out) +void dump_depth (GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, char *conv_buf, void *avi_out) { GF_Err e; u32 i, k; @@ -300,7 +316,7 @@ void dump_depth (GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, char *dst, *src; u16 src_16; dst = conv_buf + k*fb.width*3; - src = fb.video_buffer + (fb.height-k-1) * fb.pitch; + src = fb.video_buffer + (fb.height-k-1) * fb.pitch_y; for (i=0;icompositor, &fb); } -void dump_frame(GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, char *conv_buf, avi_t *avi_out) +void dump_frame(GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, char *conv_buf, void *avi_out) { GF_Err e = GF_OK; u32 i, k, out_size; @@ -407,7 +425,7 @@ void dump_frame(GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, u16 src_16; if (dump_type==5 || dump_type==10) dst = conv_buf + k*fb.width*4; else dst = conv_buf + k*fb.width*3; - src = fb.video_buffer + (fb.height-k-1) * fb.pitch; + src = fb.video_buffer + (fb.height-k-1) * fb.pitch_y; switch (fb.pixel_format) { case GF_PIXEL_RGB_32: @@ -490,6 +508,7 @@ void dump_frame(GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, break; } } +#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"); @@ -497,6 +516,7 @@ void dump_frame(GF_Terminal *term, char *rad_name, u32 dump_type, u32 frameNum, if (AVI_write_frame(avi_out, conv_buf, out_size, 1) <0) printf("Error writing frame\n"); } +#endif break; case 2: write_bmp(&fb, rad_name, frameNum); @@ -550,8 +570,13 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa gf_term_set_size(term, width, height); gf_term_process_flush(term); } - +#ifndef GPAC_USE_TINYGL + printf("not tinygl\n"); e = gf_sc_get_screen_buffer(term->compositor, &fb, 0); +#else + printf("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)); return 0; @@ -582,6 +607,10 @@ 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"); + return 0; +#else u32 time, prev_time, nb_frames, dump_dur; char *conv_buf; avi_t *avi_out = NULL; @@ -622,8 +651,8 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa comp[0] = comp[1] = comp[2] = comp[3] = comp[4] = 0; AVI_set_video(avi_out, width, height, fps, comp); if (dump_mode==8) AVI_set_video(depth_avi_out, width, height, fps, comp); - if (dump_mode != 5 && dump_mode!=10) conv_buf = malloc(sizeof(char) * width * height * 3); - else conv_buf = malloc(sizeof(char) * width * height * 4); + if (dump_mode != 5 && dump_mode!=10) conv_buf = gf_malloc(sizeof(char) * width * height * 3); + else conv_buf = gf_malloc(sizeof(char) * width * height * 4); /*step to first frame*/ if (prev_time) gf_term_step_clocks(term, prev_time); @@ -650,8 +679,9 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa } AVI_close(avi_out); if (dump_mode==8) AVI_close(depth_avi_out); - free(conv_buf); + gf_free(conv_buf); fprintf(stdout, "AVI Extraction 100/100\n"); +#endif /*GPAC_DISABLE_AVILIB*/ } else { if (times[0]) gf_term_step_clocks(term, times[0]); @@ -672,5 +702,3 @@ Bool dump_file(char *url, u32 dump_mode, Double fps, u32 width, u32 height, Floa return 0; } -#endif - diff --git a/applications/mp4client/main.c b/applications/mp4client/main.c index e112724..ff4e448 100644 --- a/applications/mp4client/main.c +++ b/applications/mp4client/main.c @@ -28,6 +28,7 @@ #include #include #include +#include /*ISO 639 languages*/ #include @@ -35,21 +36,45 @@ #ifndef WIN32 #include #include + #else -/*for GetModuleFileName*/ -#include +#include /*for GetModuleFileName*/ +#include /*for _mkdir*/ +#include /*for getting user-dir*/ +#ifndef SHGFP_TYPE_CURRENT +#define SHGFP_TYPE_CURRENT 0 /*needed for MinGW*/ #endif +#ifdef _MSC_VER +/*get rid of console*/ +#if 0 +#pragma comment(linker,"/SUBSYSTEM:WINDOWS") +#pragma comment(linker,"/ENTRY:main") +#else +#pragma comment(linker,"/SUBSYSTEM:CONSOLE") +#endif + +#endif // _MSC_VER + +#endif //WIN32 + /*local prototypes*/ void PrintWorldInfo(GF_Terminal *term); void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number); -void PrintODList(GF_Terminal *term); +void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 indent, char *root_name); + void ViewODs(GF_Terminal *term, Bool show_timing); void PrintGPACConfig(); +static Bool restart = 0; +#if defined(__DARWIN__) || defined(__APPLE__) +static Bool not_threaded = 1; +#else static Bool not_threaded = 0; +#endif static Bool no_audio = 0; static Bool no_regulation = 0; +static Bool bench_mode = 0; Bool is_connected = 0; Bool startup_file = 0; GF_User user; @@ -57,6 +82,8 @@ GF_Terminal *term; u64 Duration; GF_Err last_error = GF_OK; +static Fixed bench_speed = FLT2FIX(20); + static Bool request_next_playlist_item = 0; static GF_Config *cfg_file; @@ -65,6 +92,7 @@ static Bool Run; static Bool CanSeek = 0; static u32 Volume=100; static char the_url[GF_MAX_PATH]; +static char pl_path[GF_MAX_PATH]; static Bool no_mime_check = 1; static Bool be_quiet = 0; static u32 log_time_start = 0; @@ -79,18 +107,17 @@ u32 init_h = 0; u32 last_x, last_y; Bool right_down = 0; -#ifndef GPAC_READ_ONLY void dump_frame(GF_Terminal *term, char *rad_path, u32 dump_type, u32 frameNum); Bool dump_file(char *the_url, u32 dump_mode, Double fps, u32 width, u32 height, Float scale, u32 *times, u32 nb_times); -#endif void PrintUsage() { fprintf(stdout, "Usage MP4Client [options] [filename]\n" "\t-c fileName: user-defined configuration file\n" "\t-rti fileName: logs run-time info (FPS, CPU, Mem usage) to file\n" - "\t-rtix fileName: same as -rti but driven by GPAC logs\n" + "\t-rtix fileName: same as -rti but driven by GPAC logs\n" "\t-quiet: removes script message, buffering and downloading status\n" + "\t-opt option: Overrides an option in the configuration file. String format is section:key=value\n" "\t-log-file file: sets output log file.\n" "\t-log-level lev: sets log level. Possible values are:\n" "\t \"error\" : logs only error messages\n" @@ -120,13 +147,20 @@ void PrintUsage() "\n" "\t-size WxH: specifies visual size (default: scene size)\n" "\t-scale s: scales the visual size (default: 1)\n" +#if defined(__DARWIN__) || defined(__APPLE__) + "\t-thread: enables thread usage for terminal and compositor \n" +#else "\t-no-thread: disables thread usage (except for audio)\n" +#endif "\t-no-audio: disables audio \n" "\t-no-wnd: uses windowless mode (Win32 only)\n" "\t-align vh: specifies v and h alignment for windowless mode\n" " possible v values: t(op), m(iddle), b(ottom)\n" " possible h values: l(eft), m(iddle), r(ight)\n" " default alignment is top-left\n" + " default alignment is top-left\n" + "\t-pause: pauses at first frame\n" + "\n" "Dumper Options:\n" "\t-bmp [times]: dumps given frames to bmp\n" "\t-raw [times]: dumps given frames to bmp\n" @@ -202,18 +236,51 @@ void PrintHelp() ); } - - GF_Config *create_default_config(char *file_path, char *file_name) { GF_Config *cfg; char szPath[GF_MAX_PATH]; + +#ifdef WIN32 + FILE *f; + Bool write_access = 0; + + /*following code is highly inspired by Osmo4*/ + /*do we have the write privileges on this dir ? if not, use user local data directory*/ + strcpy(szPath, file_path); + strcat(szPath, "GPAC.cfg"); + f = gf_f64_open(szPath, "wb"); + if (f != NULL) { + fclose(f); + write_access = 1; + } else { + write_access = 0; + } + strcpy(szPath, file_path); + + /*get GPAC.cfg path*/ + if (!write_access) { + char szPath2[GF_MAX_PATH]; + SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, file_path); + if (file_path[strlen((char *) file_path)-1] != '\\') strcat(file_path, "\\"); + strcat(file_path, "GPAC\\"); + /*create GPAC dir*/ + _mkdir(file_path); + strcpy(szPath2, file_path); + strcat(szPath2, "GPAC.cfg"); + f = gf_f64_open(szPath2, "wb"); + assert(f); + if (!f) return NULL; + fclose(f); + } +#else FILE *f; sprintf(szPath, "%s%c%s", file_path, GF_PATH_SEPARATOR, file_name); - f = fopen(szPath, "wt"); + f = gf_f64_open(szPath, "wt"); fprintf(stdout, "create %s: %s\n", szPath, (f==NULL) ? "Error" : "OK"); if (!f) return NULL; fclose(f); +#endif cfg = gf_cfg_new(file_path, file_name); if (!cfg) return NULL; @@ -222,7 +289,7 @@ GF_Config *create_default_config(char *file_path, char *file_name) fprintf(stdout, "Using module directory %s \n", GPAC_MODULES_PATH); strcpy(szPath, GPAC_MODULES_PATH); #elif defined(WIN32) - strcpy(szPath, file_path); + //szPath still contains the executable directory #else fprintf(stdout, "Please enter full path to GPAC modules directory:\n"); scanf("%s", szPath); @@ -274,8 +341,7 @@ GF_Config *create_default_config(char *file_path, char *file_name) #ifdef WIN32 gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "yes"); gf_cfg_set_key(cfg, "Video", "DriverName", "DirectX Video Output"); -#else -#ifdef __DARWIN__ +#elif defined(__DARWIN__) gf_cfg_set_key(cfg, "Video", "DriverName", "SDL Video Output"); /*SDL not so fast with scalable zoom*/ gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "no"); @@ -285,14 +351,11 @@ GF_Config *create_default_config(char *file_path, char *file_name) gf_cfg_set_key(cfg, "Compositor", "ScalableZoom", "yes"); gf_cfg_set_key(cfg, "Audio", "DriverName", "SDL Audio Output"); #endif -#endif + gf_cfg_set_key(cfg, "Video", "SwitchResolution", "no"); gf_cfg_set_key(cfg, "Network", "AutoReconfigUDP", "yes"); gf_cfg_set_key(cfg, "Network", "UDPTimeout", "10000"); gf_cfg_set_key(cfg, "Network", "BufferLength", "3000"); -#ifdef GPAC_TRISCOPE_MODE - gf_cfg_set_key(cfg, "Compositor", "OGLDepthBuffGain", "5"); -#endif /*store and reload*/ gf_cfg_del(cfg); @@ -324,17 +387,22 @@ static void UpdateRTInfo(const char *legend) return; if (display_rti) { - char szMsg[1024]; - GF_Event evt; - if (!rti.process_memory) rti.process_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail); if (!rti.gpac_memory) rti.gpac_memory = (u32) (memory_at_gpac_startup-rti.physical_memory_avail); - sprintf(szMsg, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB", - gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) ); - evt.type = GF_EVENT_SET_CAPTION; - evt.caption.caption = szMsg; - gf_term_user_event(term, &evt); + if (display_rti==2) { + fprintf(stdout, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB\r", + gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) ); + } else { + char szMsg[1024]; + GF_Event evt; + + sprintf(szMsg, "FPS %02.2f - CPU %02d (%02d) - Mem %d kB", + gf_term_get_framerate(term, 0), rti.total_cpu_usage, rti.process_cpu_usage, (u32) (rti.gpac_memory / 1024) ); + evt.type = GF_EVENT_SET_CAPTION; + evt.caption.caption = szMsg; + gf_term_user_event(term, &evt); + } } if (rti_logs) { fprintf(rti_logs, "% 8d\t% 8d\t% 8d\t% 4d\t% 8d\t%s", @@ -396,6 +464,16 @@ u32 get_sys_col(int idx) } #endif +void switch_bench() +{ + if (is_connected) { + bench_mode = !bench_mode; + display_rti = !display_rti; + ResetCaption(); + gf_term_set_speed(term, bench_mode ? bench_speed : FIX_ONE); + } +} + Bool GPAC_EventProc(void *ptr, GF_Event *evt) { if (!term) return 0; @@ -411,11 +489,14 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) const char *servName; if (!evt->message.service || !strcmp(evt->message.service, the_url)) { servName = "main service"; + } else if (!strnicmp(evt->message.service, "data:", 5)) { + servName = ""; } else { servName = evt->message.service; } if (!evt->message.message) return 0; if (evt->message.error==GF_SCRIPT_INFO) { + GF_LOG(GF_LOG_INFO, GF_LOG_SCRIPT, ("[Script] %s\n", evt->message.message)); fprintf(stdout, "%s\n", evt->message.message); } else if (evt->message.error) { if (!is_connected) last_error = evt->message.error; @@ -457,88 +538,93 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) if (right_down && (user.init_flags & GF_TERM_WINDOWLESS) ) { GF_Event move; move.move.x = evt->mouse.x - last_x; - move.move.y = evt->mouse.y - last_y; + move.move.y = last_y-evt->mouse.y; move.type = GF_EVENT_MOVE; move.move.relative = 1; gf_term_user_event(term, &move); } return 0; - /*we use CTRL and not ALT for keys, since windows shortcuts keypressed with ALT*/ - case GF_EVENT_KEYDOWN: - if ((evt->key.flags & GF_KEY_MOD_ALT)) { - switch (evt->key.key_code) { - case GF_KEY_LEFT: - if (Duration>=2000) { - s32 res = gf_term_get_time_in_ms(term) - (s32) (5*Duration/100); - if (res<0) res=0; - fprintf(stdout, "seeking to %.2f %% (", 100.0*(s64)res / (s64)Duration); - PrintTime(res); - fprintf(stdout, ")\n"); - gf_term_play_from_time(term, res, 0); - } - break; - case GF_KEY_RIGHT: - if (Duration>=2000) { - u32 res = gf_term_get_time_in_ms(term) + (s32) (5*Duration/100); - if (res>=Duration) res = 0; - fprintf(stdout, "seeking to %.2f %% (", 100.0*(s64)res / (s64)Duration); - PrintTime(res); - fprintf(stdout, ")\n"); - gf_term_play_from_time(term, res, 0); - } - break; - /*these 2 are likely not supported by most audio ouput modules*/ - case GF_KEY_UP: - if (Volume!=100) { Volume = MIN(Volume + 5, 100); gf_term_set_option(term, GF_OPT_AUDIO_VOLUME, Volume); } - break; - case GF_KEY_DOWN: - if (Volume) { Volume = (Volume > 5) ? (Volume-5) : 0; gf_term_set_option(term, GF_OPT_AUDIO_VOLUME, Volume); } - break; - case GF_KEY_PAGEDOWN: - if (Volume!=100) { Volume = MIN(Volume + 5, 100); gf_term_set_option(term, GF_OPT_AUDIO_VOLUME, Volume); } - break; - } - } else { - switch (evt->key.key_code) { - case GF_KEY_HOME: - gf_term_set_option(term, GF_OPT_NAVIGATION_TYPE, 1); - break; - case GF_KEY_ESCAPE: - gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN)); - break; - case GF_KEY_PAGEDOWN: - request_next_playlist_item = 1; - break; - } + case GF_EVENT_KEYUP: + switch (evt->key.key_code) { + case GF_KEY_SPACE: + if (evt->key.flags & GF_KEY_MOD_CTRL) switch_bench(); + break; } - - if (!(evt->key.flags & GF_KEY_MOD_CTRL)) return 0; + break; + case GF_EVENT_KEYDOWN: + gf_term_process_shortcut(term, evt); switch (evt->key.key_code) { + case GF_KEY_SPACE: + if (evt->key.flags & GF_KEY_MOD_CTRL) { + /*ignore key repeat*/ + if (!bench_mode) switch_bench(); + } + break; + case GF_KEY_PAGEDOWN: + case GF_KEY_MEDIANEXTTRACK: + request_next_playlist_item = 1; + break; + case GF_KEY_MEDIAPREVIOUSTRACK: + break; + case GF_KEY_ESCAPE: + gf_term_set_option(term, GF_OPT_FULLSCREEN, !gf_term_get_option(term, GF_OPT_FULLSCREEN)); + break; case GF_KEY_F: - fprintf(stdout, "Rendering rate: %f FPS\n", gf_term_get_framerate(term, 0)); + if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stdout, "Rendering rate: %f FPS\n", gf_term_get_framerate(term, 0)); break; case GF_KEY_T: - fprintf(stdout, "Scene Time: %f \n", gf_term_get_time_in_ms(term)/1000.0); + if (evt->key.flags & GF_KEY_MOD_CTRL) fprintf(stdout, "Scene Time: %f \n", gf_term_get_time_in_ms(term)/1000.0); break; case GF_KEY_D: - gf_term_set_option(term, GF_OPT_DIRECT_DRAW, !gf_term_get_option(term, GF_OPT_DIRECT_DRAW) ); + 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 ); + break; + case GF_KEY_4: + if (evt->key.flags & GF_KEY_MOD_CTRL) + gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); + break; + case GF_KEY_5: + if (evt->key.flags & GF_KEY_MOD_CTRL) + gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); + break; + case GF_KEY_6: + if (evt->key.flags & GF_KEY_MOD_CTRL) + gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); + break; + case GF_KEY_7: + if (evt->key.flags & GF_KEY_MOD_CTRL) + gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); break; - case GF_KEY_4: gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_4_3); break; - case GF_KEY_5: gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_16_9); break; - case GF_KEY_6: gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_FILL_SCREEN); break; - case GF_KEY_7: gf_term_set_option(term, GF_OPT_ASPECT_RATIO, GF_ASPECT_RATIO_KEEP); break; case GF_KEY_P: - 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); + 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"); + 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: - gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); + 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: "); + PrintTime(gf_term_get_time_in_ms(term)); + fprintf(stdout, "\n"); + } break; case GF_KEY_B: - if (is_connected) ViewODs(term, 1); + if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) + ViewODs(term, 1); break; case GF_KEY_M: - if (is_connected) ViewODs(term, 0); + if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) + ViewODs(term, 0); + break; + case GF_KEY_H: + if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) + gf_term_switch_quality(term, 1); + break; + case GF_KEY_L: + if ((evt->key.flags & GF_KEY_MOD_CTRL) && is_connected) + gf_term_switch_quality(term, 0); break; } break; @@ -557,6 +643,9 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) } ResetCaption(); break; + case GF_EVENT_EOS: + restart = 1; + break; case GF_EVENT_SIZE: if (user.init_flags & GF_TERM_WINDOWLESS) { GF_Event move; @@ -589,12 +678,6 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) break; case GF_EVENT_MIGRATE: { - const char *str = gf_cfg_get_key(cfg_file, "Network", "SessionMigration"); - if (!str || !strcmp(str, "no")) - gf_cfg_set_key(cfg_file, "Network", "SessionMigration", "yes"); - - fprintf(stdout, "Migrating session %s\n", the_url); - gf_term_disconnect(term); } break; case GF_EVENT_NAVIGATE_INFO: @@ -668,11 +751,12 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) GF_Config *loadconfigfile(char *filepath) { - GF_Config *cfg; + GF_Config *cfg = NULL; char *cfg_dir; char szPath[GF_MAX_PATH]; if (filepath) { + strcpy(szPath, filepath); cfg_dir = strrchr(szPath, '\\'); if (!cfg_dir) cfg_dir = strrchr(szPath, '/'); if (cfg_dir) { @@ -681,6 +765,9 @@ GF_Config *loadconfigfile(char *filepath) cfg = gf_cfg_new(cfg_dir, cfg_dir+1); cfg_dir[0] = c; if (cfg) goto success; + } else { + cfg = gf_cfg_new(".", filepath); + if (cfg) goto success; } } @@ -770,47 +857,6 @@ void set_navigation() if (e) fprintf(stdout, "Error setting mode: %s\n", gf_error_to_string(e)); } -static u32 parse_log_tools(char *val) -{ - char *sep; - u32 flags = 0; - while (val) { - sep = strchr(val, ':'); - if (sep) sep[0] = 0; - if (!stricmp(val, "core")) flags |= GF_LOG_CORE; - else if (!stricmp(val, "coding")) flags |= GF_LOG_CODING; - else if (!stricmp(val, "container")) flags |= GF_LOG_CONTAINER; - else if (!stricmp(val, "network")) flags |= GF_LOG_NETWORK; - else if (!stricmp(val, "rtp")) flags |= GF_LOG_RTP; - else if (!stricmp(val, "author")) flags |= GF_LOG_AUTHOR; - else if (!stricmp(val, "sync")) flags |= GF_LOG_SYNC; - else if (!stricmp(val, "codec")) flags |= GF_LOG_CODEC; - else if (!stricmp(val, "parser")) flags |= GF_LOG_PARSER; - else if (!stricmp(val, "media")) flags |= GF_LOG_MEDIA; - else if (!stricmp(val, "scene")) flags |= GF_LOG_SCENE; - else if (!stricmp(val, "script")) flags |= GF_LOG_SCRIPT; - else if (!stricmp(val, "interact")) flags |= GF_LOG_INTERACT; - else if (!stricmp(val, "smil")) flags |= GF_LOG_SMIL; - else if (!stricmp(val, "compose")) flags |= GF_LOG_COMPOSE; - else if (!stricmp(val, "mmio")) flags |= GF_LOG_MMIO; - else if (!stricmp(val, "none")) flags = 0; - else if (!stricmp(val, "all")) flags = 0xFFFFFFFF; - else if (!stricmp(val, "rti")) flags |= GF_LOG_RTI; - else if (!stricmp(val, "cache")) flags |= GF_LOG_CACHE; - if (!sep) break; - sep[0] = ':'; - val = sep+1; - } - return flags; -} -static u32 parse_log_level(char *val) -{ - if (!stricmp(val, "error")) return GF_LOG_ERROR; - if (!stricmp(val, "warning")) return GF_LOG_WARNING; - if (!stricmp(val, "info")) return GF_LOG_INFO; - if (!stricmp(val, "debug")) return GF_LOG_DEBUG; - return 0; -} static Bool get_time_list(char *arg, u32 *times, u32 *nb_times) { @@ -871,7 +917,7 @@ static void on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list static void init_rti_logs(char *rti_file, char *url, Bool use_rtix) { if (rti_logs) fclose(rti_logs); - rti_logs = fopen(rti_file, "wt"); + rti_logs = gf_f64_open(rti_file, "wt"); if (rti_logs) { fprintf(rti_logs, "!! GPAC RunTime Info "); if (url) fprintf(rti_logs, "for file %s", url); @@ -884,7 +930,7 @@ static void init_rti_logs(char *rti_file, char *url, Bool use_rtix) gf_log_set_level(GF_LOG_DEBUG); gf_log_set_tools(GF_LOG_RTI); - GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI] System state when enabling log")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI] System state when enabling log\n")); } else if (log_time_start) { log_time_start = gf_sys_clock(); } @@ -893,14 +939,19 @@ static void init_rti_logs(char *rti_file, char *url, Bool use_rtix) int main (int argc, char **argv) { + char c; const char *str; u32 i, times[100], nb_times, dump_mode; u32 simulation_time = 0; + Bool auto_exit = 0; + Bool logs_set = 0; Bool start_fs = 0; Bool use_rtix = 0; Bool rgbds_dump = 0; Bool rgbd_dump = 0; Bool depth_dump = 0; + Bool pause_at_first = 0; + Bool enable_mem_tracker = 0; Double fps = 25.0; Bool ret, fill_ar, visible; char *url_arg, *the_cfg, *rti_file; @@ -926,9 +977,12 @@ int main (int argc, char **argv) if (!strcmp(arg, "-c") || !strcmp(arg, "-cfg")) { the_cfg = argv[i+1]; i++; - break; } + else if (!strcmp(arg, "-mem-track")) enable_mem_tracker = 1; } + + gf_sys_init(enable_mem_tracker); + cfg_file = loadconfigfile(the_cfg); if (!cfg_file) { fprintf(stdout, "Error: Configuration File \"GPAC.cfg\" not found\n"); @@ -998,14 +1052,16 @@ int main (int argc, char **argv) } else if (!strcmp(arg, "-quiet")) { be_quiet = 1; } else if (!strcmp(arg, "-log-file") || !strcmp(arg, "-lf")) { - logfile = fopen(argv[i+1], "wt"); + logfile = gf_f64_open(argv[i+1], "wt"); gf_log_set_callback(logfile, on_gpac_log); i++; } else if (!strcmp(arg, "-log-level") || !strcmp(arg, "-ll")) { - gf_log_set_level(parse_log_level(argv[i+1])); + gf_log_set_level(gf_log_parse_level(argv[i+1])); + logs_set = 1; i++; } else if (!strcmp(arg, "-log-tools") || !strcmp(arg, "-lt")) { - gf_log_set_tools(parse_log_tools(argv[i+1])); + gf_log_set_tools(gf_log_parse_tools(argv[i+1])); + logs_set = 1; i++; } else if (!strcmp(arg, "-log-clock") || !strcmp(arg, "-lc")) { log_time_start = 1; @@ -1018,10 +1074,17 @@ int main (int argc, char **argv) i++; } else if (!strcmp(arg, "-no-wnd")) user.init_flags |= GF_TERM_WINDOWLESS; +#if defined(__DARWIN__) || defined(__APPLE__) + else if (!strcmp(arg, "-thread")) not_threaded = 0; +#else else if (!strcmp(arg, "-no-thread")) not_threaded = 1; +#endif else if (!strcmp(arg, "-no-audio")) no_audio = 1; else if (!strcmp(arg, "-no-regulation")) no_regulation = 1; else if (!strcmp(arg, "-fs")) start_fs = 1; + else if (!strcmp(arg, "-pause")) pause_at_first = 1; + else if (!strcmp(arg, "-exit")) auto_exit = 1; + else if (!strcmp(arg, "-mem-track")) enable_mem_tracker = 1; else if (!strcmp(arg, "-opt")) { char *sep, *sep2, szSec[1024], szKey[1024], szVal[1024]; sep = strchr(argv[i+1], ':'); @@ -1039,7 +1102,6 @@ int main (int argc, char **argv) gf_cfg_set_key(cfg_file, szSec, szKey, szVal[0] ? szVal : NULL); } } - gf_cfg_set_key(cfg_file, szSec, szKey, szVal); i++; } else if (!strncmp(arg, "-run-for=", 9)) simulation_time = atoi(arg+9); @@ -1055,15 +1117,19 @@ int main (int argc, char **argv) return 1; } if (dump_mode) rti_file = NULL; - gf_sys_init(); - + + if (!logs_set) { + gf_log_set_level(GF_LOG_ERROR); + gf_log_set_tools(0xFFFFFFFF); + } + gf_sys_get_rti(500, &rti, GF_RTI_SYSTEM_MEMORY_ONLY); memory_at_gpac_startup = rti.physical_memory_avail; if (rti_file) init_rti_logs(rti_file, url_arg, use_rtix); /*setup dumping options*/ if (dump_mode) { - user.init_flags |= GF_TERM_NO_AUDIO | GF_TERM_NO_VISUAL_THREAD | GF_TERM_NO_REGULATION /*| GF_TERM_INIT_HIDE*/; + user.init_flags |= GF_TERM_NO_AUDIO | GF_TERM_NO_THREAD | GF_TERM_NO_REGULATION /*| GF_TERM_INIT_HIDE*/; if (visible || dump_mode==8) user.init_flags |= GF_TERM_INIT_HIDE; } else { init_w = forced_width; @@ -1089,7 +1155,7 @@ int main (int argc, char **argv) user.EventProc = GPAC_EventProc; /*dummy in this case (global vars) but MUST be non-NULL*/ user.opaque = user.modules; - if (not_threaded) user.init_flags |= GF_TERM_NO_VISUAL_THREAD; + if (not_threaded) user.init_flags |= GF_TERM_NO_THREAD; if (no_audio) user.init_flags |= GF_TERM_NO_AUDIO; if (no_regulation) user.init_flags |= GF_TERM_NO_REGULATION; @@ -1116,10 +1182,10 @@ int main (int argc, char **argv) if (!strcmp(str, "Raw Video Output")) fprintf(stdout, "WARNING: using raw output video (memory only) - no display used\n"); /*check audio output*/ str = gf_cfg_get_key(cfg_file, "Audio", "DriverName"); - if (!strcmp(str, "No Audio Output Available")) fprintf(stdout, "WARNING: no audio output availble - make sure no other program is locking the sound card\n"); + if (!str || !strcmp(str, "No Audio Output Available")) fprintf(stdout, "WARNING: no audio output availble - 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; + no_mime_check = (str && !stricmp(str, "yes")) ? 1 : 0; } str = gf_cfg_get_key(cfg_file, "HTTPProxy", "Enabled"); @@ -1140,7 +1206,7 @@ int main (int argc, char **argv) Run = 1; ret = 1; -#ifndef GPAC_READ_ONLY + if (dump_mode) { if (!nb_times) { times[0] = 0; @@ -1149,7 +1215,6 @@ int main (int argc, char **argv) ret = dump_file(url_arg, dump_mode, fps, forced_width, forced_height, scale, times, nb_times); Run = 0; } else -#endif /*connect if requested*/ if (url_arg) { @@ -1158,17 +1223,19 @@ int main (int argc, char **argv) ext = strrchr(the_url, '.'); if (ext && (!stricmp(ext, ".m3u") || !stricmp(ext, ".pls"))) { fprintf(stdout, "Opening Playlist %s\n", the_url); - playlist = fopen(the_url, "rt"); + playlist = gf_f64_open(the_url, "rt"); if (playlist) { + strcpy(pl_path, the_url); fscanf(playlist, "%s", the_url); fprintf(stdout, "Opening URL %s\n", the_url); - gf_term_connect(term, the_url); + gf_term_connect_with_path(term, the_url, pl_path); } else { fprintf(stdout, "Hit 'h' for help\n\n"); } } else { fprintf(stdout, "Opening URL %s\n", the_url); - gf_term_connect(term, the_url); + if (pause_at_first) fprintf(stdout, "[Status: Paused]\n"); + gf_term_connect_from_time(term, the_url, 0, pause_at_first); } } else { fprintf(stdout, "Hit 'h' for help\n\n"); @@ -1179,18 +1246,15 @@ int main (int argc, char **argv) startup_file = 1; } } - /*reset session migration*/ - str = gf_cfg_get_key(cfg_file, "Network", "SessionMigration"); - if (str && !strcmp(str, "yes")) - gf_cfg_set_key(cfg_file, "Network", "SessionMigration", "no"); - if (start_fs) gf_term_set_option(term, GF_OPT_FULLSCREEN, 1); - while (Run) { - char c; - + while (Run) { /*we don't want getchar to block*/ if (!gf_prompt_has_input()) { + if (restart) { + restart = 0; + gf_term_play_from_time(term, 0, 0); + } if (request_next_playlist_item) { c = '\n'; request_next_playlist_item = 0; @@ -1199,6 +1263,9 @@ int main (int argc, char **argv) if (!use_rtix || display_rti) UpdateRTInfo(NULL); if (not_threaded) { gf_term_process_step(term); + if (auto_exit && gf_term_get_option(term, GF_OPT_IS_OVER)) { + Run = 0; + } } else { gf_sleep(rti_update_time_ms); } @@ -1215,12 +1282,10 @@ force_input: case 'q': Run = 0; break; + case 'X': + exit(0); + break; case 'Q': - str = gf_cfg_get_key(cfg_file, "Network", "SessionMigration"); - if (!str || !strcmp(str, "no")) - gf_cfg_set_key(cfg_file, "Network", "SessionMigration", "yes"); - fprintf(stdout, "Migrating session %s\n", the_url); - gf_term_disconnect(term); break; case 'o': startup_file = 0; @@ -1234,7 +1299,7 @@ force_input: gf_term_disconnect(term); fprintf(stdout, "Enter the absolute URL to the playlist\n"); scanf("%s", the_url); - playlist = fopen(the_url, "rt"); + playlist = gf_f64_open(the_url, "rt"); if (playlist) { fscanf(playlist, "%s", the_url); fprintf(stdout, "Opening URL %s\n", the_url); @@ -1251,7 +1316,7 @@ force_input: Run = 0; } else { fprintf(stdout, "Opening URL %s\n", the_url); - gf_term_connect(term, the_url); + gf_term_connect_with_path(term, the_url, pl_path); } } break; @@ -1329,12 +1394,13 @@ force_input: if (is_connected) PrintWorldInfo(term); break; case 'v': - if (is_connected) PrintODList(term); + if (is_connected) PrintODList(term, NULL, 0, 0, "Root"); break; case 'i': if (is_connected) { u32 ID; fprintf(stdout, "Enter OD ID (0 for main OD): "); + fflush(stdout); scanf("%d", &ID); ViewOD(term, ID, (u32)-1); } @@ -1343,6 +1409,7 @@ force_input: if (is_connected) { u32 num; fprintf(stdout, "Enter OD number (0 for main OD): "); + fflush(stdout); scanf("%d", &num); ViewOD(term, (u32)-1, num); } @@ -1368,19 +1435,39 @@ force_input: case 'd': if (is_connected) { - char file[GF_MAX_PATH], *sExt; + GF_ObjectManager *odm = NULL; + char radname[GF_MAX_PATH], *sExt; GF_Err e; + u32 i, count, odid; Bool xml_dump, std_out; + fprintf(stdout, "Enter Inline OD ID if any or 0"); + fflush(stdout); + radname[0] = 0; + scanf("%d", &odid); + if (odid) { + GF_ObjectManager *root_odm = gf_term_get_root_object(term); + if (!root_odm) break; + count = gf_term_get_object_count(term, root_odm); + for (i=0; iobjectDescriptorID==odid) break; + } + odm = NULL; + } + } fprintf(stdout, "Enter file radical name (+\'.x\' for XML dumping) - \"std\" for stdout: "); - scanf("%s", file); - sExt = strrchr(file, '.'); + fflush(stdout); + scanf("%s", radname); + sExt = strrchr(radname, '.'); xml_dump = 0; if (sExt) { if (!stricmp(sExt, ".x")) xml_dump = 1; sExt[0] = 0; } - std_out = strnicmp(file, "std", 3) ? 0 : 1; - e = gf_term_dump_scene(term, std_out ? NULL : file, xml_dump, 0, NULL); + 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)); } break; @@ -1425,7 +1512,7 @@ force_input: 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 stoped\n"); + fprintf(stdout, "Streaming Cache stopped\n"); } else { fprintf(stdout, "Streaming Cache not running\n"); } @@ -1434,6 +1521,11 @@ force_input: display_rti = !display_rti; ResetCaption(); break; + case 'F': + if (display_rti) display_rti = 0; + else display_rti = 2; + ResetCaption(); + break; case 'u': { @@ -1453,7 +1545,7 @@ force_input: char szLog[1024]; fprintf(stdout, "Enter new log level:\n"); scanf("%s", szLog); - gf_log_set_level(parse_log_level(szLog)); + gf_log_set_level(gf_log_parse_level(szLog)); } break; case 'T': @@ -1461,7 +1553,7 @@ force_input: char szLog[1024]; fprintf(stdout, "Enter new log tools:\n"); scanf("%s", szLog); - gf_log_set_tools(parse_log_tools(szLog)); + gf_log_set_tools(gf_log_parse_tools(szLog)); } break; case 'g': @@ -1484,6 +1576,41 @@ force_input: gf_term_set_option(term, GF_OPT_RELOAD_CONFIG, 1); break; + case 'B': + switch_bench(); + break; + + /*extract to PNG*/ + case 'Z': + { + GF_VideoSurface fb; + GF_Err e; + e = gf_term_get_screen_buffer(term, &fb); + if (e) { + fprintf(stdout, "Error dumping screen buffer %s\n", gf_error_to_string(e) ); + } else { + u32 dst_size = fb.width*fb.height*3; + char *dst=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) ); + } else { + FILE *png = gf_f64_open("dump.png", "wb"); + if (!png) { + fprintf(stdout, "Error writing file dump.png\n"); + } else { + fwrite(dst, dst_size, 1, png); + fclose(png); + fprintf(stdout, "Writing file dump.png\n"); + } + } + if (dst) free(dst); + gf_term_release_screen_buffer(term, &fb); + } + } + break; + case 'h': PrintHelp(); break; @@ -1500,13 +1627,24 @@ force_input: gf_term_del(term); fprintf(stdout, "OK\n"); - fprintf(stdout, "Unloading modules... "); + fprintf(stdout, "GPAC cleanup ...\n"); gf_modules_del(user.modules); - fprintf(stdout, "OK\n"); gf_cfg_del(cfg_file); + +#ifdef GPAC_MEMORY_TRACKING + if (enable_mem_tracker) { + gf_memory_print(); + fprintf(stdout, "print any key\n"); + while (!gf_prompt_has_input()) { + gf_sleep(100); + } + } +#endif + gf_sys_close(); if (rti_logs) fclose(rti_logs); if (logfile) fclose(logfile); + fprintf(stdout, "Bye\n"); return 0; } @@ -1532,33 +1670,73 @@ void PrintWorldInfo(GF_Terminal *term) gf_list_del(descs); } -void PrintODList(GF_Terminal *term) +void PrintODList(GF_Terminal *term, GF_ObjectManager *root_odm, u32 num, u32 indent, char *root_name) { - ODInfo odi; + GF_MediaInfo odi; u32 i, count; - GF_ObjectManager *odm, *root_odm = gf_term_get_root_object(term); + char szIndent[50]; + GF_ObjectManager *odm; + + if (!root_odm) { + fprintf(stdout, "Currently loaded objects:\n"); + root_odm = gf_term_get_root_object(term); + } if (!root_odm) return; if (gf_term_get_object_info(term, root_odm, &odi) != GF_OK) return; if (!odi.od) { fprintf(stdout, "Service not attached\n"); return; } - fprintf(stdout, "Currently loaded objects:\n"); - fprintf(stdout, "\tRootOD ID %d\n", odi.od->objectDescriptorID); + + for (i=0;iobjectDescriptorID); + } + + szIndent[indent]=' '; + szIndent[indent+1]=0; + indent++; count = gf_term_get_object_count(term, root_odm); for (i=0; iobjectDescriptorID, - (odi.od_type==GF_STREAM_VISUAL) ? "Video" : (odi.od_type==GF_STREAM_AUDIO) ? "Audio" : "Systems"); + num++; + if (gf_term_get_object_info(term, odm, &odi) == GF_OK) { + switch (gf_term_object_subscene_type(term, odm)) { + case 1: + PrintODList(term, odm, num, indent, "Root"); + break; + case 2: + PrintODList(term, odm, num, indent, "Inline Scene"); + break; + case 3: + PrintODList(term, odm, num, indent, "EXTERNPROTO Library"); + break; + default: + fprintf(stdout, "%s", szIndent); + fprintf(stdout, "#%d - ", num); + if (odi.media_url) { + fprintf(stdout, "%s", odi.media_url); + } else { + fprintf(stdout, "ID %d", odi.od->objectDescriptorID); + } + fprintf(stdout, " - %s\n", (odi.od_type==GF_STREAM_VISUAL) ? "Video" : (odi.od_type==GF_STREAM_AUDIO) ? "Audio" : "Systems"); + break; + } + } } } void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number) { - ODInfo odi; + GF_MediaInfo odi; u32 i, j, count, d_enum,id; GF_Err e; char code[5]; @@ -1676,17 +1854,19 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number) case GF_STREAM_VISUAL: fprintf(stdout, "\tVisual Stream - media type: "); switch (esd->decoderConfig->objectTypeIndication) { - case 0x20: fprintf(stdout, "MPEG-4\n"); break; - case 0x60: fprintf(stdout, "MPEG-2 Simple Profile\n"); break; - case 0x61: fprintf(stdout, "MPEG-2 Main Profile\n"); break; - case 0x62: fprintf(stdout, "MPEG-2 SNR Profile\n"); break; - case 0x63: fprintf(stdout, "MPEG-2 Spatial Profile\n"); break; - case 0x64: fprintf(stdout, "MPEG-2 High Profile\n"); break; - case 0x65: fprintf(stdout, "MPEG-2 422 Profile\n"); break; - case 0x6A: fprintf(stdout, "MPEG-1\n"); break; - case 0x6C: fprintf(stdout, "JPEG\n"); break; - case 0x6D: fprintf(stdout, "PNG\n"); break; - case 0x80: + case GPAC_OTI_VIDEO_MPEG4_PART2: fprintf(stdout, "MPEG-4\n"); break; + case GPAC_OTI_VIDEO_MPEG2_SIMPLE: fprintf(stdout, "MPEG-2 Simple Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_MAIN: fprintf(stdout, "MPEG-2 Main Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_SNR: fprintf(stdout, "MPEG-2 SNR Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_SPATIAL: fprintf(stdout, "MPEG-2 Spatial Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_HIGH: fprintf(stdout, "MPEG-2 High Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_422: fprintf(stdout, "MPEG-2 422 Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG1: fprintf(stdout, "MPEG-1\n"); break; + case GPAC_OTI_IMAGE_JPEG: fprintf(stdout, "JPEG\n"); break; + case GPAC_OTI_IMAGE_PNG: fprintf(stdout, "PNG\n"); break; + case GPAC_OTI_IMAGE_JPEG_2000: fprintf(stdout, "JPEG2000\n"); break; + + case GPAC_OTI_MEDIA_GENERIC: memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); code[4] = 0; fprintf(stdout, "GPAC Intern (%s)\n", code); @@ -1700,16 +1880,16 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number) case GF_STREAM_AUDIO: fprintf(stdout, "\tAudio Stream - media type: "); switch (esd->decoderConfig->objectTypeIndication) { - case 0x40: fprintf(stdout, "MPEG-4\n"); break; - case 0x66: fprintf(stdout, "MPEG-2 AAC Main Profile\n"); break; - case 0x67: fprintf(stdout, "MPEG-2 AAC LowComplexity Profile\n"); break; - case 0x68: fprintf(stdout, "MPEG-2 AAC Scalable Sampling Rate Profile\n"); break; - case 0x69: fprintf(stdout, "MPEG-2 Audio\n"); break; - case 0x6B: fprintf(stdout, "MPEG-1 Audio\n"); break; - case 0xA0: fprintf(stdout, "EVRC Audio\n"); break; - case 0xA1: fprintf(stdout, "SMV Audio\n"); break; - case 0xE1: fprintf(stdout, "QCELP Audio\n"); break; - case 0x80: + case GPAC_OTI_AUDIO_AAC_MPEG4: fprintf(stdout, "MPEG-4\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: fprintf(stdout, "MPEG-2 AAC Main Profile\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: fprintf(stdout, "MPEG-2 AAC LowComplexity Profile\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: fprintf(stdout, "MPEG-2 AAC Scalable Sampling Rate Profile\n"); break; + case GPAC_OTI_AUDIO_MPEG2_PART3: fprintf(stdout, "MPEG-2 Audio\n"); break; + case GPAC_OTI_AUDIO_MPEG1: fprintf(stdout, "MPEG-1 Audio\n"); break; + case GPAC_OTI_AUDIO_EVRC_VOICE: fprintf(stdout, "EVRC Audio\n"); break; + case GPAC_OTI_AUDIO_SMV_VOICE: fprintf(stdout, "SMV Audio\n"); break; + case GPAC_OTI_AUDIO_13K_VOICE: fprintf(stdout, "QCELP Audio\n"); break; + case GPAC_OTI_MEDIA_GENERIC: memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); code[4] = 0; fprintf(stdout, "GPAC Intern (%s)\n", code); @@ -1799,7 +1979,7 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number) } switch (odi.status) { - case 0: fprintf(stdout, "Stoped - "); break; + 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; @@ -1856,7 +2036,7 @@ void ViewOD(GF_Terminal *term, u32 OD_ID, u32 number) void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm) { - ODInfo odi; + GF_MediaInfo odi; if (!odm) return; if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return; @@ -1869,7 +2049,7 @@ void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm) switch (odi.status) { case 1: fprintf(stdout, "Playing - "); break; case 2: fprintf(stdout, "Paused - "); break; - default: fprintf(stdout, "Stoped - "); break; + default: fprintf(stdout, "Stopped - "); break; } if (odi.buffer>=0) fprintf(stdout, "Buffer: %d ms - ", odi.buffer); else fprintf(stdout, "Not buffering - "); @@ -1882,7 +2062,7 @@ void PrintODTiming(GF_Terminal *term, GF_ObjectManager *odm) void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm) { Float avg_dec_time; - ODInfo odi; + GF_MediaInfo odi; if (!odm) return; if (gf_term_get_object_info(term, odm, &odi) != GF_OK) return; @@ -1895,7 +2075,7 @@ void PrintODBuffer(GF_Terminal *term, GF_ObjectManager *odm) switch (odi.status) { case 1: fprintf(stdout, "Playing"); break; case 2: fprintf(stdout, "Paused"); break; - default: fprintf(stdout, "Stoped"); break; + default: fprintf(stdout, "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); diff --git a/applications/osmo4_sym/osmo4_ui.cpp b/applications/osmo4_sym/osmo4_ui.cpp index 5a51f3c..1b82c88 100644 --- a/applications/osmo4_sym/osmo4_ui.cpp +++ b/applications/osmo4_sym/osmo4_ui.cpp @@ -137,7 +137,7 @@ COsmo4AppUi::~COsmo4AppUi() } if (iAppView) delete iAppView; if (iPlaylist) delete iPlaylist; - if (m_title) free(m_title); + if (m_title) gf_free(m_title); m_title = NULL; } @@ -427,9 +427,9 @@ void COsmo4AppUi::SetTitleInfo(const char *title) void COsmo4AppUi::SetTitle(const char *title, int store_it) { if (store_it) { - if (m_title) free(m_title); + if (m_title) gf_free(m_title); m_title = NULL; - if (title) m_title = strdup(title); + if (title) m_title = gf_strdup(title); } SetTitleInfo(title ? title : m_title); } diff --git a/applications/osmo4_sym/osmo4_view.cpp b/applications/osmo4_sym/osmo4_view.cpp index 1acb350..e6064b6 100644 --- a/applications/osmo4_sym/osmo4_view.cpp +++ b/applications/osmo4_sym/osmo4_view.cpp @@ -347,13 +347,24 @@ void COsmo4AppView::ConstructL( const TRect& aRect ) if (!opt) first_launch = 2; if (first_launch) { + FILE *t; /*hardcode module directory*/ gf_cfg_set_key(m_user.config, "General", "ModulesDirectory", GPAC_MODULES_DIR); /*hardcode cache directory*/ gf_cfg_set_key(m_user.config, "General", "CacheDirectory", GPAC_CFG_DIR"cache"); gf_cfg_set_key(m_user.config, "Downloader", "CleanCache", "yes"); /*startup file*/ - gf_cfg_set_key(m_user.config, "General", "StartupFile", GPAC_CFG_DIR"gpac.mp4"); + t = fopen(GPAC_CFG_DIR"gui/gui.bt", "rt"); + if (t) { + fclose(t); + gf_cfg_set_key(m_user.config, "General", "StartupFile", GPAC_CFG_DIR"gui/gui.bt"); + } else { + t = fopen(GPAC_CFG_DIR"gpac.mp4", "rt"); + if (t) { + fclose(t); + gf_cfg_set_key(m_user.config, "General", "StartupFile", GPAC_CFG_DIR"gpac.mp4"); + } + } /*setup UDP traffic autodetect*/ gf_cfg_set_key(m_user.config, "Network", "AutoReconfigUDP", "yes"); gf_cfg_set_key(m_user.config, "Network", "UDPTimeout", "10000"); diff --git a/applications/osmo4_w32/FileProps.cpp b/applications/osmo4_w32/FileProps.cpp index bf913d8..a43c234 100644 --- a/applications/osmo4_w32/FileProps.cpp +++ b/applications/osmo4_w32/FileProps.cpp @@ -186,7 +186,7 @@ void CFileProps::SetGeneralInfo() { char info[10000]; char buf[1000]; - ODInfo odi; + GF_MediaInfo odi; GF_ObjectManager *odm; u32 h, m, s, i, j; @@ -359,24 +359,25 @@ void CFileProps::OnWorld() void CFileProps::OnViewsg() { - char szOutFile[GF_MAX_PATH]; + char szOutRadname[GF_MAX_PATH], *pFilename=NULL; Osmo4 *gpac = GetApp(); - strcpy(szOutFile, gpac->szAppPath); - strcat(szOutFile, "scene_dump"); + strcpy(szOutRadname, gpac->szUserPath); + strcat(szOutRadname, "scene_dump"); - GF_Err e = gf_term_dump_scene(gpac->m_term, (char *) szOutFile, gpac->m_ViewXMTA, 0, current_odm); + GF_Err e = gf_term_dump_scene(gpac->m_term, (char *) szOutRadname, &pFilename, gpac->m_ViewXMTA, 0, current_odm); if (e) { MessageBox(gf_error_to_string(e), "Error while dumping"); } else { - ShellExecute(NULL, "open", szOutFile, NULL, NULL, SW_SHOWNORMAL); + ShellExecute(NULL, "open", pFilename, NULL, NULL, SW_SHOWNORMAL); } + if (pFilename) gf_free(pFilename); } void CFileProps::SetDecoderInfo() { - ODInfo odi; + GF_MediaInfo odi; char buf[1000], info[2000]; u32 h, m, s; Osmo4 *gpac = GetApp(); @@ -448,7 +449,7 @@ void CFileProps::SetStreamsInfo() u32 i, count; char info[10000]; char buf[1000], code[5]; - ODInfo odi; + GF_MediaInfo odi; GF_ObjectManager *odm; Bool is_media; @@ -511,17 +512,18 @@ void CFileProps::SetStreamsInfo() is_media = 1; strcat(info, "Visual Stream - media type: "); switch (esd->decoderConfig->objectTypeIndication) { - case 0x20: strcat(info, "MPEG-4\r\n"); break; - case 0x60: strcat(info, "MPEG-2 Simple Profile\r\n"); break; - case 0x61: strcat(info, "MPEG-2 Main Profile\r\n"); break; - case 0x62: strcat(info, "MPEG-2 SNR Profile\r\n"); break; - case 0x63: strcat(info, "MPEG-2 Spatial Profile\r\n"); break; - case 0x64: strcat(info, "MPEG-2 High Profile\r\n"); break; - case 0x65: strcat(info, "MPEG-2 422 Profile\r\n"); break; - case 0x6A: strcat(info, "MPEG-1\r\n"); break; - case 0x6C: strcat(info, "JPEG\r\n"); break; - case 0x6D: strcat(info, "PNG\r\n"); break; - case 0x80: + case GPAC_OTI_VIDEO_MPEG4_PART2: strcat(info, "MPEG-4\r\n"); break; + case GPAC_OTI_VIDEO_MPEG2_SIMPLE: strcat(info, "MPEG-2 Simple Profile\r\n"); break; + case GPAC_OTI_VIDEO_MPEG2_MAIN: strcat(info, "MPEG-2 Main Profile\r\n"); break; + case GPAC_OTI_VIDEO_MPEG2_SNR: strcat(info, "MPEG-2 SNR Profile\r\n"); break; + case GPAC_OTI_VIDEO_MPEG2_SPATIAL: strcat(info, "MPEG-2 Spatial Profile\r\n"); break; + case GPAC_OTI_VIDEO_MPEG2_HIGH: strcat(info, "MPEG-2 High Profile\r\n"); break; + case GPAC_OTI_VIDEO_MPEG2_422: strcat(info, "MPEG-2 422 Profile\r\n"); break; + case GPAC_OTI_VIDEO_MPEG1: strcat(info, "MPEG-1\r\n"); break; + case GPAC_OTI_IMAGE_JPEG: strcat(info, "JPEG\r\n"); break; + case GPAC_OTI_IMAGE_PNG: strcat(info, "PNG\r\n"); break; + case GPAC_OTI_IMAGE_JPEG_2000: strcat(info, "JPEG2000\r\n"); break; + case GPAC_OTI_MEDIA_GENERIC: memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); code[4] = 0; sprintf(buf, "GPAC Intern (%s)\r\n", code); @@ -538,16 +540,16 @@ void CFileProps::SetStreamsInfo() is_media = 1; strcat(info, "Audio Stream - media type: "); switch (esd->decoderConfig->objectTypeIndication) { - case 0x40: strcat(info, "MPEG-4\r\n"); break; - case 0x66: strcat(info, "MPEG-2 AAC Main Profile\r\n"); break; - case 0x67: strcat(info, "MPEG-2 AAC LowComplexity Profile\r\n"); break; - case 0x68: strcat(info, "MPEG-2 AAC Scalable Sampling Rate Profile\r\n"); break; - case 0x69: strcat(info, "MPEG-2 Audio\r\n"); break; - case 0x6B: strcat(info, "MPEG-1 Audio\r\n"); break; - case 0xA0: strcat(info, "EVRC Audio\r\n"); break; - case 0xA1: strcat(info, "SMV Audio\r\n"); break; - case 0xE1: strcat(info, "QCELP Audio\r\n"); break; - case 0x80: + case GPAC_OTI_AUDIO_AAC_MPEG4: strcat(info, "MPEG-4\r\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: strcat(info, "MPEG-2 AAC Main Profile\r\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: strcat(info, "MPEG-2 AAC LowComplexity Profile\r\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: strcat(info, "MPEG-2 AAC Scalable Sampling Rate Profile\r\n"); break; + case GPAC_OTI_AUDIO_MPEG2_PART3: strcat(info, "MPEG-2 Audio\r\n"); break; + case GPAC_OTI_AUDIO_MPEG1: strcat(info, "MPEG-1 Audio\r\n"); break; + case GPAC_OTI_AUDIO_EVRC_VOICE: strcat(info, "EVRC Audio\r\n"); break; + case GPAC_OTI_AUDIO_SMV_VOICE: strcat(info, "SMV Audio\r\n"); break; + case GPAC_OTI_AUDIO_13K_VOICE: strcat(info, "QCELP Audio\r\n"); break; + case GPAC_OTI_MEDIA_GENERIC: memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); code[4] = 0; sprintf(buf, "GPAC Intern (%s)\r\n", code); @@ -637,7 +639,7 @@ void CFileProps::SetNetworkInfo() char buf[10000]; u32 id; NetStatCommand com; - ODInfo odi; + GF_MediaInfo odi; u32 d_enum, nb_streams; GF_Err e; GF_ObjectManager *odm; diff --git a/applications/osmo4_w32/MainFrm.cpp b/applications/osmo4_w32/MainFrm.cpp index f8134cd..9f01ec2 100644 --- a/applications/osmo4_w32/MainFrm.cpp +++ b/applications/osmo4_w32/MainFrm.cpp @@ -178,7 +178,7 @@ CMainFrame::CMainFrame() CMainFrame::~CMainFrame() { - if (m_chapters_start) free(m_chapters_start); + if (m_chapters_start) gf_free(m_chapters_start); if (m_pProps != NULL) m_pProps->DestroyWindow(); if (m_pOpt != NULL) m_pOpt->DestroyWindow(); if (m_pPlayList != NULL) delete m_pPlayList; @@ -460,7 +460,8 @@ LONG CMainFrame::OnSetSize(WPARAM wParam, LPARAM lParam) SetWindowPos(NULL, 0, 0, winRect.right, winRect.bottom, SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW); } else { /*just resize term*/ - gf_term_set_size(GetApp()->m_term, width, height); + //gf_term_set_size(GetApp()->m_term, width, height); + SetWindowPos(NULL, 0, 0, winRect.right, winRect.bottom, SWP_NOZORDER | SWP_NOMOVE | SWP_SHOWWINDOW); } return 0; } @@ -781,7 +782,7 @@ LONG CMainFrame::OnNavigate(WPARAM /*wParam*/, LPARAM /*lParam*/) if (str) { m_pPlayList->Truncate(); m_pPlayList->QueueURL(str); - free(str); + gf_free(str); m_pPlayList->RefreshList(); m_pPlayList->PlayNext(); return 0; @@ -950,7 +951,7 @@ void CMainFrame::BuildStreamList(Bool reset_only) for (u32 i=0; im_term, root_od, i); if (!odm) return; @@ -1088,7 +1089,7 @@ void CMainFrame::OnInitMenuPopup(CMenu* pPopupMenu, UINT ID, BOOL bSys) if (!odm) { pPopupMenu->EnableMenuItem(i, MF_DISABLED | MF_BYPOSITION); } else { - ODInfo info; + GF_MediaInfo info; gf_term_get_object_info(app->m_term, odm, &info); pPopupMenu->EnableMenuItem(i, MF_BYPOSITION); @@ -1393,7 +1394,7 @@ void CMainFrame::OnFileExit() void CMainFrame::BuildChapterList(Bool reset_only) { CMenu *pChaps; - ODInfo odi; + GF_MediaInfo odi; NetInfoCommand com; Osmo4 *app = GetApp(); @@ -1401,7 +1402,7 @@ void CMainFrame::BuildChapterList(Bool reset_only) pChaps = GetMenu()->GetSubMenu(2)->GetSubMenu(1); while (pChaps->GetMenuItemCount()) pChaps->DeleteMenu(0, MF_BYPOSITION); - if (m_chapters_start) free(m_chapters_start); + if (m_chapters_start) gf_free(m_chapters_start); m_chapters_start = NULL; m_num_chapters = 0; if (reset_only) return; @@ -1424,7 +1425,7 @@ void CMainFrame::BuildChapterList(Bool reset_only) } pChaps->AppendMenu(MF_ENABLED, ID_SETCHAP_FIRST + m_num_chapters, szLabel); - m_chapters_start = (Double *) realloc(m_chapters_start, sizeof(Double)*(m_num_chapters+1)); + m_chapters_start = (Double *) gf_realloc(m_chapters_start, sizeof(Double)*(m_num_chapters+1)); m_chapters_start[m_num_chapters] = seg->startTime; m_num_chapters++; } diff --git a/applications/osmo4_w32/Options.cpp b/applications/osmo4_w32/Options.cpp index 61b4d92..63d3d38 100644 --- a/applications/osmo4_w32/Options.cpp +++ b/applications/osmo4_w32/Options.cpp @@ -625,8 +625,8 @@ BOOL COptRender2D::OnInitDialog() Osmo4 *gpac = GetApp(); const char *sOpt; - sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "DirectDraw"); - if (sOpt && !stricmp(sOpt, "yes")) { + sOpt = gf_cfg_get_key(gpac->m_user.config, "Compositor", "DrawMode"); + if (sOpt && !stricmp(sOpt, "immediate")) { m_DirectRender.SetCheck(1); } else { m_DirectRender.SetCheck(0); @@ -667,7 +667,7 @@ void COptRender2D::SetYUV() void COptRender2D::SaveOptions() { Osmo4 *gpac = GetApp(); - gf_cfg_set_key(gpac->m_user.config, "Compositor", "DirectDraw", m_DirectRender.GetCheck() ? "yes" : "no"); + gf_cfg_set_key(gpac->m_user.config, "Compositor", "DrawMode", m_DirectRender.GetCheck() ? "immediate" : "defer"); gf_cfg_set_key(gpac->m_user.config, "Compositor", "ScalableZoom", m_Scalable.GetCheck() ? "yes" : "no"); gf_cfg_set_key(gpac->m_user.config, "Compositor", "DisableYUV", m_NoYUV.GetCheck() ? "yes" : "no"); @@ -1762,7 +1762,7 @@ void OptFiles::OnAssociate() unsigned char szApp[MAX_PATH]; unsigned char szIco[MAX_PATH]; - strcpy((char *) szApp, GetApp()->szAppPath); + strcpy((char *) szApp, GetApp()->szApplicationPath); strcpy((char *) szIco, (const char *) szApp); strcat((char *) szIco, "Osmo4.ico"); strcat((char *) szApp, "Osmo4.exe \"%L\""); diff --git a/applications/osmo4_w32/Osmo4.cpp b/applications/osmo4_w32/Osmo4.cpp index 0b39e19..a9c63a9 100644 --- a/applications/osmo4_w32/Osmo4.cpp +++ b/applications/osmo4_w32/Osmo4.cpp @@ -4,7 +4,7 @@ #include "stdafx.h" #include "Osmo4.h" #include - +#include #include "MainFrm.h" #include "OpenUrl.h" @@ -139,7 +139,7 @@ u32 get_sys_col(int idx) return res; } -static void Osmo4_progress_cbk(void *usr, char *title, u32 done, u32 total) +static void Osmo4_progress_cbk(void *usr, char *title, u64 done, u64 total) { if (!total) return; CMainFrame *pFrame = (CMainFrame *) ((Osmo4 *) usr)->m_pMainWnd; @@ -228,13 +228,17 @@ Bool Osmo4_EventProc(void *priv, GF_Event *evt) } break; /*don't resize on win32 msg notif*/ +#if 0 case GF_EVENT_SIZE: - if (gpac->m_term && !pFrame->m_bFullScreen && gpac->orig_width && (evt->size.width < W32_MIN_WIDTH) ) + if (/*gpac->m_term && !pFrame->m_bFullScreen && */gpac->orig_width && (evt->size.width < W32_MIN_WIDTH) ) pFrame->PostMessage(WM_SETSIZE, W32_MIN_WIDTH, (W32_MIN_WIDTH*gpac->orig_height) / gpac->orig_width); + else + pFrame->PostMessage(WM_SETSIZE, evt->size.width, evt->size.height); break; +#endif case GF_EVENT_CONNECT: - if (pFrame->m_bStartupFile) return 0; +// if (pFrame->m_bStartupFile) return 0; pFrame->BuildStreamList(1); if (evt->connect.is_connected) { @@ -259,57 +263,26 @@ Bool Osmo4_EventProc(void *priv, GF_Event *evt) break; case GF_EVENT_MIGRATE: { - const char *str = gf_cfg_get_key(gpac->m_user.config, "Network", "SessionMigration"); - if (!str || !strcmp(str, "no")) - gf_cfg_set_key(gpac->m_user.config, "Network", "SessionMigration", "yes"); - - gpac->m_navigate_url = ""; - pFrame->PostMessage(WM_NAVIGATE, NULL, NULL); } break; case GF_EVENT_KEYDOWN: - if (gpac->can_seek && evt->key.flags & GF_KEY_MOD_ALT) { - s32 res; - switch (evt->key.key_code) { - case GF_KEY_LEFT: - res = gf_term_get_time_in_ms(gpac->m_term) - 5*gpac->max_duration/100; - if (res<0) res=0; - gpac->PlayFromTime(res); - break; - case GF_KEY_RIGHT: - res = gf_term_get_time_in_ms(gpac->m_term) + 5*gpac->max_duration/100; - if ((u32) res>=gpac->max_duration) res = 0; - gpac->PlayFromTime(res); - break; - case GF_KEY_DOWN: - res = gf_term_get_time_in_ms(gpac->m_term) - 60000; - if (res<0) res=0; - gpac->PlayFromTime(res); - break; - case GF_KEY_UP: - res = gf_term_get_time_in_ms(gpac->m_term) + 60000; - if ((u32) res>=gpac->max_duration) res = 0; - gpac->PlayFromTime(res); - break; - } - } else if (evt->key.flags & GF_KEY_MOD_CTRL) { - switch (evt->key.key_code) { - case GF_KEY_LEFT: - pFrame->m_pPlayList->PlayPrev(); - break; - case GF_KEY_RIGHT: - pFrame->m_pPlayList->PlayNext(); - break; - } - } else { - switch (evt->key.key_code) { - case GF_KEY_HOME: - gf_term_set_option(gpac->m_term, GF_OPT_NAVIGATION_TYPE, 1); - break; - case GF_KEY_ESCAPE: - pFrame->PostMessage(WM_COMMAND, ID_VIEW_FULLSCREEN); - break; - } + gf_term_process_shortcut(gpac->m_term, evt); + /*update volume control*/ + pFrame->m_Sliders.SetVolume(); + + switch (evt->key.key_code) { + case GF_KEY_HOME: + gf_term_set_option(gpac->m_term, GF_OPT_NAVIGATION_TYPE, 1); + break; + case GF_KEY_ESCAPE: + pFrame->PostMessage(WM_COMMAND, ID_VIEW_FULLSCREEN); + break; + case GF_KEY_MEDIANEXTTRACK: + pFrame->m_pPlayList->PlayNext(); + break; + case GF_KEY_MEDIAPREVIOUSTRACK: + pFrame->m_pPlayList->PlayPrev(); + break; } break; case GF_EVENT_NAVIGATE: @@ -393,6 +366,9 @@ static void osmo4_do_log(void *cbk, u32 level, u32 tool, const char *fmt, va_lis BOOL Osmo4::InitInstance() { + char config_file[MAX_PATH]; + FILE *ft; + Bool write_access; CCommandLineInfo cmdInfo; m_logs = NULL; @@ -401,25 +377,57 @@ BOOL Osmo4::InitInstance() memset(&m_user, 0, sizeof(GF_User)); - strcpy((char *) szAppPath, AfxGetApp()->m_pszHelpFilePath); - while (szAppPath[strlen((char *) szAppPath)-1] != '\\') szAppPath[strlen((char *) szAppPath)-1] = 0; - if (szAppPath[strlen((char *) szAppPath)-1] != '\\') strcat(szAppPath, "\\"); + /*get Osmo4.exe path*/ + strcpy((char *) szApplicationPath, AfxGetApp()->m_pszHelpFilePath); + while (szApplicationPath[strlen((char *) szApplicationPath)-1] != '\\') szApplicationPath[strlen((char *) szApplicationPath)-1] = 0; + if (szApplicationPath[strlen((char *) szApplicationPath)-1] != '\\') strcat(szApplicationPath, "\\"); + + /*do we have the write privileges on this dir ? if no, use Documents and Settings*/ + strcpy(config_file, szApplicationPath); + strcat(config_file, "test.txt"); + ft = gf_f64_open(config_file, "wb"); + if (ft != NULL) { + fclose(ft); + gf_delete_file(config_file); + write_access = 1; + } else { + write_access = 0; + } + + /*get GPAC.cfg path*/ + if (write_access) { + strcat(szUserPath, szApplicationPath); + } else { + SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, szUserPath); + if (szUserPath[strlen((char *) szUserPath)-1] != '\\') strcat(szUserPath, "\\"); + strcat(szUserPath, "GPAC\\"); + /*create GPAC dir*/ + _mkdir(szUserPath); + } + + gf_sys_init(0); /*setup user*/ memset(&m_user, 0, sizeof(GF_User)); Bool first_launch = 0; /*init config and modules*/ - m_user.config = gf_cfg_new((const char *) szAppPath, "GPAC.cfg"); + m_user.config = gf_cfg_new((const char *) szUserPath, "GPAC.cfg"); if (!m_user.config) { first_launch = 1; /*create blank config file in the exe dir*/ - unsigned char config_file[MAX_PATH]; - strcpy((char *) config_file, (const char *) szAppPath); + char config_file[MAX_PATH]; + + strcpy(config_file, szUserPath); + /*create GPAC cache dir*/ + strcat(config_file, "cache"); + _mkdir(config_file); + + strcpy((char *) config_file, (const char *) szUserPath); strcat((char *) config_file, "GPAC.cfg"); - FILE *ft = fopen((const char *) config_file, "wt"); + ft = gf_f64_open((const char *) config_file, "wt"); fclose(ft); - m_user.config = gf_cfg_new((const char *) szAppPath, "GPAC.cfg"); + m_user.config = gf_cfg_new((const char *) szUserPath, "GPAC.cfg"); if (!m_user.config) { MessageBox(NULL, "GPAC Configuration file not found", "Fatal Error", MB_OK); m_pMainWnd->PostMessage(WM_CLOSE); @@ -460,7 +468,7 @@ BOOL Osmo4::InitInstance() strcat(static_szCmdLine, cmd); } else { strcat(static_szCmdLine, the_url); - free(the_url); + gf_free(the_url); } while ( (len = strlen(static_szCmdLine)) ) { char s = static_szCmdLine[len-1]; @@ -498,17 +506,18 @@ BOOL Osmo4::InitInstance() if (!m_user.modules) { const char *sOpt; /*inital launch*/ - m_user.modules = gf_modules_new(szAppPath, m_user.config); + m_user.modules = gf_modules_new(szApplicationPath, m_user.config); if (m_user.modules) { + FILE *t; unsigned char str_path[MAX_PATH]; - gf_cfg_set_key(m_user.config, "General", "ModulesDirectory", (const char *) szAppPath); + gf_cfg_set_key(m_user.config, "General", "ModulesDirectory", (const char *) szApplicationPath); sOpt = gf_cfg_get_key(m_user.config, "Compositor", "Raster2D"); if (!sOpt) gf_cfg_set_key(m_user.config, "Compositor", "Raster2D", "GPAC 2D Raster"); sOpt = gf_cfg_get_key(m_user.config, "General", "CacheDirectory"); if (!sOpt) { - sprintf((char *) str_path, "%scache", szAppPath); + sprintf((char *) str_path, "%scache", szUserPath); gf_cfg_set_key(m_user.config, "General", "CacheDirectory", (const char *) str_path); } /*setup UDP traffic autodetect*/ @@ -527,8 +536,16 @@ BOOL Osmo4::InitInstance() } } - sprintf((char *) str_path, "%sgpac.mp4", szAppPath); - gf_cfg_set_key(m_user.config, "General", "StartupFile", (const char *) str_path); + sprintf((char *) str_path, "%sgui/gui.bt", szApplicationPath); + t = gf_f64_open((char *) str_path, "rt"); + if (!t) { + sprintf((char *) str_path, "%sgpac.mp4", szApplicationPath); + t = gf_f64_open((char *) str_path, "rt"); + } + if (t) { + gf_cfg_set_key(m_user.config, "General", "StartupFile", (const char *) str_path); + fclose(t); + } } /*check audio config on windows, force config*/ @@ -538,14 +555,17 @@ BOOL Osmo4::InitInstance() gf_cfg_set_key(m_user.config, "Audio", "NumBuffers", "2"); gf_cfg_set_key(m_user.config, "Audio", "TotalDuration", "120"); } - /*check video config */ - sOpt = gf_cfg_get_key(m_user.config, "Video", "UseHardwareMemory"); - if (!sOpt) gf_cfg_set_key(m_user.config, "Video", "UseHardwareMemory", "yes"); /*by default use GDIplus, much faster than freetype on font loading*/ - gf_cfg_set_key(m_user.config, "FontEngine", "FontReader", "gdip_rend"); - - } + gf_cfg_set_key(m_user.config, "FontEngine", "FontReader", "gm_soft_raster"); + + /*set some shortcuts*/ + gf_cfg_set_key(m_user.config, "Shortcuts", "VolumeUp", "ctrl+Up"); + gf_cfg_set_key(m_user.config, "Shortcuts", "VolumeDown", "ctrl+Down"); + gf_cfg_set_key(m_user.config, "Shortcuts", "FastRewind", "ctrl+Left"); + gf_cfg_set_key(m_user.config, "Shortcuts", "FastForward", "ctrl+Right"); + gf_cfg_set_key(m_user.config, "Shortcuts", "Play", "ctrl+ "); + } if (! gf_modules_get_count(m_user.modules) ) { MessageBox(NULL, "No modules available - system cannot work", "Fatal Error", MB_OK); m_pMainWnd->PostMessage(WM_CLOSE); @@ -564,18 +584,13 @@ BOOL Osmo4::InitInstance() /*check video driver, if none or raw_out use dx_hw by default*/ str = gf_cfg_get_key(m_user.config, "Video", "DriverName"); if (!str || !stricmp(str, "raw_out")) { - gf_cfg_set_key(m_user.config, "Video", "DriverName", "dx_hw"); + gf_cfg_set_key(m_user.config, "Video", "DriverName", "DirectX Video Output"); } - /*reset session migration*/ - str = gf_cfg_get_key(m_user.config, "Network", "SessionMigration"); - if (str && !strcmp(str, "yes")) - gf_cfg_set_key(m_user.config, "Network", "SessionMigration", "no"); - /*check log file*/ str = gf_cfg_get_key(m_user.config, "General", "LogFile"); if (str) { - m_logs = fopen(str, "wt"); + m_logs = gf_f64_open(str, "wt"); gf_log_set_callback(m_logs, osmo4_do_log); } else m_logs = NULL; @@ -624,8 +639,6 @@ BOOL Osmo4::InitInstance() gf_log_set_tools(m_log_tools); } - gf_sys_init(); - m_user.opaque = this; m_user.os_window_handler = pFrame->m_pWndView->m_hWnd; m_user.EventProc = Osmo4_EventProc; @@ -663,7 +676,7 @@ BOOL Osmo4::InitInstance() pFrame->m_pPlayList->PlayNext(); } else { char sPL[MAX_PATH]; - strcpy((char *) sPL, szAppPath); + strcpy((char *) sPL, szUserPath); strcat(sPL, "gpac_pl.m3u"); pFrame->m_pPlayList->OpenPlayList(sPL); const char *sOpt = gf_cfg_get_key(GetApp()->m_user.config, "General", "PLEntry"); @@ -905,11 +918,11 @@ void Osmo4::OnOpenFile() /*looks like there's a bug here, main filter isn't used correctly while the others are*/ CFileDialog fd(TRUE,NULL,NULL, OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST , sFiles); fd.m_ofn.nMaxFile = 25000; - fd.m_ofn.lpstrFile = (char *) malloc(sizeof(char) * fd.m_ofn.nMaxFile); + fd.m_ofn.lpstrFile = (char *) gf_malloc(sizeof(char) * fd.m_ofn.nMaxFile); fd.m_ofn.lpstrFile[0] = 0; if (fd.DoModal()!=IDOK) { - free(fd.m_ofn.lpstrFile); + gf_free(fd.m_ofn.lpstrFile); return; } @@ -932,7 +945,7 @@ void Osmo4::OnOpenFile() CString file = fd.GetNextPathName(pos); pFrame->m_pPlayList->QueueURL(file); } - free(fd.m_ofn.lpstrFile); + gf_free(fd.m_ofn.lpstrFile); pFrame->m_pPlayList->RefreshList(); pFrame->m_pPlayList->PlayNext(); } @@ -978,12 +991,6 @@ void Osmo4::OnFileReload() void Osmo4::OnFileMigrate() { - const char *str = gf_cfg_get_key(m_user.config, "Network", "SessionMigration"); - if (!str || !strcmp(str, "no")) - gf_cfg_set_key(m_user.config, "Network", "SessionMigration", "yes"); - - m_navigate_url = ""; - m_pMainWnd->PostMessage(WM_NAVIGATE, NULL, NULL); } void Osmo4::OnConfigReload() @@ -1049,7 +1056,7 @@ void Osmo4::OnFileStop() void Osmo4::OnUpdateFileStop(CCmdUI* pCmdUI) { - pCmdUI->Enable(m_isopen); +// pCmdUI->Enable(m_isopen); } void Osmo4::OnSwitchRender() diff --git a/applications/osmo4_w32/Osmo4.h b/applications/osmo4_w32/Osmo4.h index a7a0583..cb53b1d 100644 --- a/applications/osmo4_w32/Osmo4.h +++ b/applications/osmo4_w32/Osmo4.h @@ -64,7 +64,8 @@ public: CString GetFileFilter(); - char szAppPath[GF_MAX_PATH]; + char szApplicationPath[GF_MAX_PATH]; + char szUserPath[GF_MAX_PATH]; FILE *m_logs; u32 m_log_level, m_log_tools; diff --git a/applications/osmo4_w32/Osmo4.rc b/applications/osmo4_w32/Osmo4.rc index a3247d1..1c65b6f 100644 --- a/applications/osmo4_w32/Osmo4.rc +++ b/applications/osmo4_w32/Osmo4.rc @@ -1,4 +1,4 @@ -//Microsoft Developer Studio generated resource script. +// Microsoft Visual C++ generated resource script. // #include "resource.h" @@ -13,7 +13,7 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources +// Anglais (États-Unis) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 @@ -26,7 +26,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Menu // -IDR_MAINFRAME MENU PRELOAD DISCARDABLE +IDR_MAINFRAME MENU BEGIN POPUP "&File" BEGIN @@ -142,22 +142,6 @@ END // Accelerator // -IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE -BEGIN - "I", ID_FILE_PROP, VIRTKEY, CONTROL, NOINVERT - "L", ID_VIEW_PL, VIRTKEY, CONTROL, NOINVERT - "M", ID_FILE_MIGRATE, VIRTKEY, CONTROL, NOINVERT - "O", ID_FILEOPEN, VIRTKEY, CONTROL, NOINVERT - "P", ID_FILE_PLAY, VIRTKEY, CONTROL, NOINVERT - "R", ID_FILE_RELOAD, VIRTKEY, CONTROL, NOINVERT - "S", ID_FILE_STEP, VIRTKEY, CONTROL, NOINVERT - "U", ID_OPEN_URL, VIRTKEY, CONTROL, NOINVERT - VK_NUMPAD1, ID_AR_KEEP, VIRTKEY, CONTROL, NOINVERT - VK_NUMPAD2, ID_AR_FILL, VIRTKEY, CONTROL, NOINVERT - VK_NUMPAD3, ID_AR_43, VIRTKEY, CONTROL, NOINVERT - VK_NUMPAD4, ID_AR_169, VIRTKEY, CONTROL, NOINVERT - VK_RETURN, ID_VIEW_FULLSCREEN, VIRTKEY, ALT, NOINVERT -END ///////////////////////////////////////////////////////////////////////////// @@ -166,44 +150,36 @@ END // IDD_ABOUTBOX DIALOGEX 0, 0, 209, 137 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_CLIENTEDGE CAPTION "Osmo4 / GPAC version X.X.X" FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN ICON IDR_MAINFRAME,IDC_STATIC,8,4,20,20 - CTEXT "Osmo4 Player - GPAC Multimedia Framework",IDC_STATIC,31, - 10,150,10,SS_NOPREFIX - CTEXT "(c) Jean Le Feuvre 2000-2005 - (c) ENST 2005-200X\nAll Rights Reserved", - IDC_STATIC,4,64,201,18 - CTEXT "This program is free software and may be distributed according to the terms of the GNU Lesser General Public License", - IDC_STATIC,4,26,200,18 - PUSHBUTTON "http://gpac.sourceforge.net",IDC_GOGPAC,43,47,121,13, - BS_FLAT,WS_EX_STATICEDGE + CTEXT "Osmo4 Player - GPAC Multimedia Framework",IDC_STATIC,31,10,150,10,SS_NOPREFIX + CTEXT "(c) Jean Le Feuvre 2000-2005 - (c) ENST 2005-200X\nAll Rights Reserved",IDC_STATIC,4,64,201,18 + CTEXT "This program is free software and may be distributed according to the terms of the GNU Lesser General Public License",IDC_STATIC,4,26,200,18 + PUSHBUTTON "http://gpac.sourceforge.net",IDC_GOGPAC,43,47,121,13,BS_FLAT,WS_EX_STATICEDGE GROUPBOX "With Many Thanks To:",IDC_STATIC,3,82,203,53 - CTEXT "The FreeType Project\nMozilla SpiderMonkey (JavaScript support)\n\nZLIB, the PNG Group, the I.J.G.\nFFMPEG, FAAD, XVID, MAD", - IDC_STATIC,9,92,189,41 + CTEXT "The FreeType Project\nMozilla SpiderMonkey (JavaScript support)\n\nZLIB, the PNG Group, the I.J.G.\nFFMPEG, FAAD, XVID, MAD",IDC_STATIC,9,92,189,41 END -IDD_PASSWD DIALOG DISCARDABLE 0, 0, 134, 71 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_PASSWD DIALOG 0, 0, 134, 71 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Enter user name and password" FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK",IDOK,4,56,50,12 PUSHBUTTON "Cancel",IDCANCEL,80,56,50,12 - LTEXT "Static__________________________",IDC_TXT_SITE,25,4,105, - 8 + LTEXT "Static__________________________",IDC_TXT_SITE,25,4,105,8 LTEXT "Login",IDC_STATIC,7,21,18,8 LTEXT "Password",IDC_STATIC,7,37,32,8 EDITTEXT IDC_EDIT_USER,47,18,55,14,ES_AUTOHSCROLL - EDITTEXT IDC_EDIT_PASSWORD,47,34,55,14,ES_PASSWORD | - ES_AUTOHSCROLL + EDITTEXT IDC_EDIT_PASSWORD,47,34,55,14,ES_PASSWORD | ES_AUTOHSCROLL LTEXT "Site",IDC_STATIC,7,4,13,8 END -#ifndef _MAC ///////////////////////////////////////////////////////////////////////////// // // Version @@ -226,18 +202,13 @@ BEGIN BEGIN BLOCK "040904b0" BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "\0" - VALUE "FileDescription", "Osmo4-GPAC\0" - VALUE "FileVersion", "0.4.5\0" - VALUE "InternalName", "Osmo4\0" - VALUE "LegalCopyright", "Copyright (C) 2005\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "Osmo4.EXE\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "Osmo4-GPAC\0" - VALUE "ProductVersion", "0.4.5\0" - VALUE "SpecialBuild", "\0" + VALUE "FileDescription", "Osmo4-GPAC" + VALUE "FileVersion", "0.4.5" + VALUE "InternalName", "Osmo4" + VALUE "LegalCopyright", "Copyright (C) 2005" + VALUE "OriginalFilename", "Osmo4.EXE" + VALUE "ProductName", "Osmo4-GPAC" + VALUE "ProductVersion", "0.4.5" END END BLOCK "VarFileInfo" @@ -246,8 +217,6 @@ BEGIN END END -#endif // !_MAC - ///////////////////////////////////////////////////////////////////////////// // @@ -255,7 +224,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE +GUIDELINES DESIGNINFO BEGIN IDD_ABOUTBOX, DIALOG BEGIN @@ -270,7 +239,7 @@ END // Toolbar // -IDR_MAINTOOLS TOOLBAR DISCARDABLE 16, 15 +IDR_MAINTOOLS TOOLBAR 16, 15 BEGIN BUTTON ID_FILEOPEN BUTTON ID_NAV_PREV @@ -291,25 +260,25 @@ END // Bitmap // -IDR_MAINTOOLS BITMAP DISCARDABLE "res\\maintool.bmp" +IDR_MAINTOOLS BITMAP "res\\maintool.bmp" ///////////////////////////////////////////////////////////////////////////// // // String Table // -STRINGTABLE PRELOAD DISCARDABLE +STRINGTABLE BEGIN IDR_MAINFRAME "Osmo4" END -STRINGTABLE PRELOAD DISCARDABLE +STRINGTABLE BEGIN AFX_IDS_APP_TITLE "Osmo4" AFX_IDS_IDLEMESSAGE "Ready" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN ID_FILE_EXIT "Quit the application; prompts to save documents\nExit" ID_H_ABOUT "Display program information, version number and copyright\nAbout" @@ -318,12 +287,12 @@ BEGIN ID_VIEW_ORIGINAL "restore Original Aspect of presentation" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN ID_VIEW_STATUS_BAR "Show or hide the status bar\nToggle StatusBar" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN AFX_IDS_SCSIZE "Change the window size" AFX_IDS_SCMOVE "Change the window position" @@ -334,13 +303,13 @@ BEGIN AFX_IDS_SCCLOSE "Close the active window and prompts to save the documents" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN AFX_IDS_SCRESTORE "Restore the window to normal size" AFX_IDS_SCTASKLIST "Activate Task List" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN ID_FILE_STOP "Stops current presentation" ID_SWITCH_RENDER "Switch between 2D and 3D renderers" @@ -350,7 +319,7 @@ BEGIN ID_HEADLIGHT "Turns headlight on/off" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN ID_CLEAR_NAV "Clears navigation history" ID_TIMER " " @@ -358,7 +327,7 @@ BEGIN ID_VIEW_PL "View navigation history as a playlist" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN ID_VIEW_FULLSCREEN "Move to Full Screen mode (Esc to exit)" ID_AR_KEEP "Keep Aspect Ratio of presentation" @@ -373,7 +342,7 @@ BEGIN ID_NAVIGATE_NONE "Disable navigation" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN ID_NAVIGATE_WALK "Turn walk navigation on" ID_AR_FILL "Ignores Aspect Ratio and always fill screen" @@ -382,7 +351,7 @@ BEGIN ID_NAV_RESET "Restore last viewpoint" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN ID_NAVIGATE_VR "QT-VR like navigation" ID_REC_ENABLE "Enable recording of streaming data" @@ -390,18 +359,18 @@ BEGIN ID_REC_ABORT "Stops recording and discard data" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN ID_FILE_COPY "Copy selected text to clipboard" ID_FILE_PASTE "Paste clipboard" END -#endif // English (U.S.) resources +#endif // Anglais (États-Unis) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -// French (France) resources +// Français (France) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) #ifdef _WIN32 @@ -414,348 +383,261 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH // Dialog // -IDD_OPENFILE DIALOG DISCARDABLE 0, 0, 301, 23 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_OPENFILE DIALOG 0, 0, 301, 23 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Select Location" FONT 8, "MS Sans Serif" BEGIN - COMBOBOX IDC_COMBOURL,3,5,273,67,CBS_DROPDOWN | CBS_AUTOHSCROLL | - CBS_SORT | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_COMBOURL,3,5,273,67,CBS_DROPDOWN | CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP DEFPUSHBUTTON "OK",IDC_BUTGO,279,5,19,13 END -IDD_OPTIONS DIALOG DISCARDABLE 0, 0, 174, 106 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_OPTIONS DIALOG 0, 0, 174, 106 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Osmo4 Options" FONT 8, "MS Sans Serif" BEGIN PUSHBUTTON "Apply",IDC_SAVEOPT,147,2,26,12 - COMBOBOX IDC_SELECT,42,2,99,173,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP + COMBOBOX IDC_SELECT,42,2,99,173,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Category",IDC_STATIC,7,4,29,8 END -IDD_OPT_GEN DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_GEN DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN - CONTROL "Loop At End",IDC_LOOP,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,4,4,55,10 - CONTROL "Look for subtitles",IDC_LOOKFORSUB,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,4,42,69,10 - CONTROL "Disable console messages",IDC_NO_CONSOLE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,4,17,99,10 - CONTROL "View Graph in XMT-A format",IDC_DUMP_XMT,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,4,30,105,10 - CONTROL "Single Instance",IDC_SINGLE_INSTANCE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,4,54,65,10 + CONTROL "Loop At End",IDC_LOOP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,4,55,10 + CONTROL "Look for subtitles",IDC_LOOKFORSUB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,42,69,10 + CONTROL "Disable console messages",IDC_NO_CONSOLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,17,99,10 + CONTROL "View Graph in XMT-A format",IDC_DUMP_XMT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,30,105,10 + CONTROL "Single Instance",IDC_SINGLE_INSTANCE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,54,65,10 END -IDD_OPT_RENDER DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_RENDER DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN LTEXT "Rendering Frame Rate",IDC_STATIC,5,4,72,8 - COMBOBOX IDC_BIFS_RATE,81,2,84,55,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - CONTROL "Fast Rendering",IDC_FAST_RENDER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,6,49,64,10 - CONTROL "Force Scene Size",IDC_FORCE_SIZE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,96,49,72,10 + COMBOBOX IDC_BIFS_RATE,81,2,84,55,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Fast Rendering",IDC_FAST_RENDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,49,64,10 + CONTROL "Force Scene Size",IDC_FORCE_SIZE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,96,49,72,10 LTEXT "Anti-Aliasing Level",IDC_STATIC,7,20,58,8 - COMBOBOX IDC_AA_LIST,81,17,84,46,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - CONTROL "Use 3D Renderer",IDC_USE_RENDER3D,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,6,63,71,10 + COMBOBOX IDC_AA_LIST,81,17,84,46,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Use 3D Renderer",IDC_USE_RENDER3D,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,63,71,10 LTEXT "2D Rasterizer",IDC_STATIC,7,35,44,8 - COMBOBOX IDC_GD_LIST,81,33,84,44,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - COMBOBOX IDC_DRAW_BOUNDS,109,60,56,44,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_GD_LIST,81,33,84,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_DRAW_BOUNDS,109,60,56,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Bounds",IDC_STATIC,82,64,25,8 END -IDD_OPT_AUDIO DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_CONTROL | WS_CHILD | WS_THICKFRAME +IDD_OPT_AUDIO DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_CONTROL | WS_CHILD | WS_THICKFRAME FONT 8, "MS Sans Serif" BEGIN - CONTROL "Spin1",IDC_SPIN_AUDIO,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ARROWKEYS,27,15,11,14 + CONTROL "Spin1",IDC_SPIN_AUDIO,"msctls_updown32",UDS_SETBUDDYINT | UDS_ARROWKEYS,27,15,11,14 EDITTEXT IDC_EDIT_AUDIO,5,15,19,14,ES_READONLY | ES_NUMBER - CONTROL "Force Audio Config",IDC_FORCE_AUDIO,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,6,3,73,10 + CONTROL "Force Audio Config",IDC_FORCE_AUDIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,3,73,10 LTEXT "buffers",IDC_STATIC,43,18,23,8 - CONTROL "Spin1",IDC_SPIN_FPS,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ARROWKEYS,104,15,11,14 + CONTROL "Spin1",IDC_SPIN_FPS,"msctls_updown32",UDS_SETBUDDYINT | UDS_ARROWKEYS,104,15,11,14 EDITTEXT IDC_AUDIO_FPS,77,15,24,14,ES_NUMBER LTEXT "Audio Driver",IDC_STATIC,7,63,40,8 - CONTROL "No Resynchronization",IDC_AUDIO_RESYNC,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,4,46,82,10 - COMBOBOX IDC_DRIVER_LIST,63,60,103,62,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP - CONTROL "Disable Notifications",IDC_AUDIO_NOTIFS,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,89,47,79,10 - CONTROL "Disable Multichannel",IDC_AUDIO_MULTICH,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,4,34,81,10 + CONTROL "No Resynchronization",IDC_AUDIO_RESYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,46,82,10 + COMBOBOX IDC_DRIVER_LIST,63,60,103,62,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Disable Notifications",IDC_AUDIO_NOTIFS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,89,47,79,10 + CONTROL "Disable Multichannel",IDC_AUDIO_MULTICH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,34,81,10 LTEXT "ms total length",IDC_STATIC,118,18,49,8 END -IDD_OPT_VIDEO DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_VIDEO DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN LTEXT "Video Driver",IDC_STATIC,6,7,40,8 - COMBOBOX IDC_VIDEO_LIST,55,5,111,44,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP + COMBOBOX IDC_VIDEO_LIST,55,5,111,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Change video resolution in fullscreen",IDC_SWITCH_RES, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,29,131,10 CONTROL "Use Hardware Video Memory in 2D mode",IDC_HWMEMORY, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,44,143,10 END -IDD_OPT_HTTP DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_HTTP DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN PUSHBUTTON "...",IDC_BROWSE_CACHE,57,4,109,12 - CONTROL "Clean cache at exit",IDC_CLEAN_CACHE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,3,19,77,10 - CONTROL "Always redownload incomplete cached files", - IDC_RESTART_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 3,30,153,10 + CONTROL "Clean cache at exit",IDC_CLEAN_CACHE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,19,77,10 + CONTROL "Always redownload incomplete cached files",IDC_RESTART_CACHE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,30,153,10 LTEXT "Cache Directory",IDC_STATIC,5,5,52,8 - CONTROL "XML progressive load",IDC_SAX_PROGRESSIVE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,3,42,84,10 - EDITTEXT IDC_SAX_DELAY,142,41,22,12,ES_CENTER | ES_AUTOHSCROLL | - ES_NUMBER + CONTROL "XML progressive load",IDC_SAX_PROGRESSIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,42,84,10 + EDITTEXT IDC_SAX_DELAY,142,41,22,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER LTEXT "TimeSlice (ms)",IDC_STATIC,91,43,46,8 EDITTEXT IDC_HTTP_PROXY,54,58,111,12,ES_AUTOHSCROLL - CONTROL "Use proxy",IDC_HTTP_USE_PROXY,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,3,59,47,10 + CONTROL "Use proxy",IDC_HTTP_USE_PROXY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,59,47,10 END -IDD_OPT_FONT DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_FONT DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN LTEXT "Font Engine",IDC_STATIC,6,11,39,8 - COMBOBOX IDC_FONT_LIST,60,8,105,44,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP + COMBOBOX IDC_FONT_LIST,60,8,105,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "...",IDC_BROWSE_FONT,2,40,164,12 LTEXT "System Font Directory",IDC_STATIC,46,29,70,8 - COMBOBOX IDC_TEXTURE_MODE,101,58,64,44,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_TEXTURE_MODE,101,58,64,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Text Texturing Mode",IDC_STATIC,7,60,69,8 END -IDD_OPT_SYSTEMS DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_SYSTEMS DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN - COMBOBOX IDC_LANG,75,4,92,58,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Prefered Language for stream selection",IDC_STATIC,3,3, - 61,17 + COMBOBOX IDC_LANG,75,4,92,58,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Prefered Language for stream selection",IDC_STATIC,3,3,61,17 LTEXT "Decoder Threading",IDC_STATIC,4,28,62,8 - COMBOBOX IDC_DEC_THREAD,75,25,92,57,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - CONTROL "Always draw late BIFS frames",IDC_BIFSDROP,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,3,43,109,10 - CONTROL "Force Single Timeline",IDC_FORCE_DURATION,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,3,58,83,10 + COMBOBOX IDC_DEC_THREAD,75,25,92,57,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "Always draw late BIFS frames",IDC_BIFSDROP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,43,109,10 + CONTROL "Force Single Timeline",IDC_FORCE_DURATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,58,83,10 END -IDD_OPT_STREAM DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_STREAM DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN LTEXT "Default Port",IDC_STATIC,6,6,40,8 - COMBOBOX IDC_PORT,52,3,113,61,CBS_DROPDOWNLIST | CBS_SORT | - WS_VSCROLL | WS_TABSTOP - CONTROL "RTP over RTSP",IDC_RTSP,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,4,19,68,10 - CONTROL "use RTP reordering",IDC_REORDER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,81,19,76,10 - LTEXT "milliseconds before control timeout",IDC_STATIC,38,34, - 108,8 - EDITTEXT IDC_TIMEOUT,3,32,30,12,ES_CENTER | ES_AUTOHSCROLL | - ES_NUMBER - LTEXT "milliseconds of Media Buffering ",IDC_STATIC,38,48,100, - 8 - EDITTEXT IDC_BUFFER,3,47,30,12,ES_CENTER | ES_AUTOHSCROLL | - ES_NUMBER - EDITTEXT IDC_REBUFFER_LEN,83,60,30,12,ES_CENTER | ES_AUTOHSCROLL | - ES_NUMBER - CONTROL "Rebuffer if less than",IDC_REBUFFER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,4,63,79,10 + COMBOBOX IDC_PORT,52,3,113,61,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP + CONTROL "RTP over RTSP",IDC_RTSP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,19,68,10 + CONTROL "use RTP reordering",IDC_REORDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,81,19,76,10 + LTEXT "milliseconds before control timeout",IDC_STATIC,38,34,108,8 + EDITTEXT IDC_TIMEOUT,3,32,30,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER + LTEXT "milliseconds of Media Buffering ",IDC_STATIC,38,48,100,8 + EDITTEXT IDC_BUFFER,3,47,30,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_REBUFFER_LEN,83,60,30,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER + CONTROL "Rebuffer if less than",IDC_REBUFFER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,4,63,79,10 LTEXT "milliseconds",IDC_STATIC,117,63,41,8 END IDD_PROPERTIES DIALOGEX 0, 0, 338, 150 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Presentation Properties" FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN - CONTROL "Tree1",IDC_ODTREE,"SysTreeView32",TVS_HASBUTTONS | - TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | - TVS_SHOWSELALWAYS | TVS_TRACKSELECT | TVS_SINGLEEXPAND | - WS_BORDER | WS_TABSTOP,2,2,120,114 - EDITTEXT IDC_ODINFO,123,17,213,130,ES_MULTILINE | ES_AUTOVSCROLL | - ES_AUTOHSCROLL | ES_NOHIDESEL | ES_OEMCONVERT | - ES_READONLY | WS_VSCROLL | WS_HSCROLL, - WS_EX_DLGMODALFRAME | WS_EX_STATICEDGE + CONTROL "Tree1",IDC_ODTREE,"SysTreeView32",TVS_HASBUTTONS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_SHOWSELALWAYS | TVS_TRACKSELECT | WS_BORDER | WS_TABSTOP | 0x400,2,2,120,114 + EDITTEXT IDC_ODINFO,123,17,213,130,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_NOHIDESEL | ES_OEMCONVERT | ES_READONLY | WS_VSCROLL | WS_HSCROLL,WS_EX_DLGMODALFRAME | WS_EX_STATICEDGE PUSHBUTTON "Get World Info",IDC_WORLD,2,118,119,13 PUSHBUTTON "View Scene Graph",IDC_VIEWSG,2,134,119,13 - CONTROL "Tab1",IDC_VIEWSEL,"SysTabControl32",TCS_BUTTONS,124,2, - 208,14 + CONTROL "Tab1",IDC_VIEWSEL,"SysTabControl32",TCS_BUTTONS,124,2,208,14 END -IDD_OPT_DECODER DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_DECODER DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN LTEXT "Prefered Audio Module",-1,46,5,69,8 - COMBOBOX IDC_AUDEC_LIST,26,17,111,56,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_AUDEC_LIST,26,17,111,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Prefered Video Module",-1,48,40,69,8 - COMBOBOX IDC_VIDEC_LIST,25,52,113,55,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_VIDEC_LIST,25,52,113,55,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END -IDD_OPT_RENDER2D DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | WS_CHILD +IDD_OPT_RENDER2D DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CHILD FONT 8, "MS Sans Serif" BEGIN - CONTROL "Disable YUV Hardware",IDC_YUV,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,5,54,89,10 + CONTROL "Disable YUV Hardware",IDC_YUV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,54,89,10 LTEXT "Static",IDC_FORMAT_YUV,97,57,67,8 - CONTROL "Direct Rendering",IDC_DIRECTRENDER,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,5,32,72,10 - CONTROL "Scalable Zoom",IDC_ZOOM_SCALABLE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,5,10,77,10 + CONTROL "Direct Rendering",IDC_DIRECTRENDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,32,72,10 + CONTROL "Scalable Zoom",IDC_ZOOM_SCALABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,10,77,10 END -IDD_OPT_RENDER3D DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | WS_CHILD +IDD_OPT_RENDER3D DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CHILD FONT 8, "MS Sans Serif" BEGIN - CONTROL "Use OpenGL Outlines",IDC_RASTER_OUTLINE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,5,2,84,10 + CONTROL "Use OpenGL Outlines",IDC_RASTER_OUTLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,2,84,10 CONTROL "Emulate power-of-two textures for video",IDC_EMUL_POW2, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,45,140,10 - CONTROL "Polygon Anti-Aliasing",IDC_DISABLE_POLY_AA,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,90,2,78,10 - CONTROL "Disable rectangular texture extensions", - IDC_DISABLE_TX_RECT,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,6,55,135,10 - CONTROL "Bitmap node uses direct pixel copy", - IDC_BITMAP_USE_PIXEL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,6,65,125,10 + CONTROL "Polygon Anti-Aliasing",IDC_DISABLE_POLY_AA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,90,2,78,10 + CONTROL "Disable rectangular texture extensions",IDC_DISABLE_TX_RECT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,55,135,10 + CONTROL "Bitmap node uses direct pixel copy",IDC_BITMAP_USE_PIXEL, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,65,125,10 LTEXT "Draw Normals",IDC_STATIC,4,17,45,8 - COMBOBOX IDC_DRAW_NORMALS,4,25,48,44,CBS_DROPDOWNLIST | - WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_DRAW_NORMALS,4,25,48,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Backface Cull",IDC_STATIC,57,17,55,8 - COMBOBOX IDC_BACK_CULL,57,25,47,44,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP + COMBOBOX IDC_BACK_CULL,57,25,47,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Draw Mode",IDC_STATIC,113,17,55,8 - COMBOBOX IDC_DRAW_MODE,111,25,53,44,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP + COMBOBOX IDC_DRAW_MODE,111,25,53,44,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP END -IDD_SLIDERS DIALOG DISCARDABLE 0, 0, 218, 18 -STYLE WS_CHILD +IDD_SLIDERS DIALOG 0, 0, 218, 18 +STYLE DS_SETFONT | WS_CHILD FONT 8, "MS Sans Serif" BEGIN - CONTROL "Slider1",ID_SLIDER,"msctls_trackbar32",TBS_BOTH | - TBS_NOTICKS | WS_TABSTOP,0,3,185,12 - CONTROL "Slider1",ID_AUDIO_VOL,"msctls_trackbar32",TBS_BOTH | - TBS_NOTICKS | WS_BORDER | WS_TABSTOP,187,3,30,13 + CONTROL "Slider1",ID_SLIDER,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,0,3,185,12 + CONTROL "Slider1",ID_AUDIO_VOL,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_BORDER | WS_TABSTOP,187,3,30,13 END IDD_NAVBAR DIALOGEX 0, 0, 279, 15 -STYLE WS_CHILD +STYLE DS_SETFONT | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN - COMBOBOX IDC_ADDRESS,29,1,130,196,CBS_DROPDOWN | CBS_AUTOHSCROLL | - WS_VSCROLL | WS_TABSTOP,WS_EX_ACCEPTFILES + COMBOBOX IDC_ADDRESS,29,1,130,196,CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_VSCROLL | WS_TABSTOP,WS_EX_ACCEPTFILES LTEXT "Address",IDC_DUMTXT,1,4,26,8 END IDD_PLAYLIST DIALOGEX 0, 0, 186, 54 -STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME +STYLE DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME EXSTYLE WS_EX_TOOLWINDOW CAPTION "Osmo4 Playlist" FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN - CONTROL "List4",IDC_FILELIST,"SysListView32",LVS_REPORT | - WS_BORDER | WS_TABSTOP,1,0,182,51 + CONTROL "List4",IDC_FILELIST,"SysListView32",LVS_REPORT | WS_BORDER | WS_TABSTOP,1,0,182,51 END -IDD_OPT_MCACHE DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_MCACHE DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN PUSHBUTTON "...",IDC_BROWSE_MCACHE,41,2,126,12 - CONTROL "Overwrite existing files",IDC_MCACHE_OVERWRITE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,3,18,85,10 - CONTROL "Use filename",IDC_MCACHE_USENAME,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,3,31,57,10 + CONTROL "Overwrite existing files",IDC_MCACHE_OVERWRITE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,18,85,10 + CONTROL "Use filename",IDC_MCACHE_USENAME,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,31,57,10 LTEXT "Record To",IDC_STATIC,4,4,35,8 - EDITTEXT IDC_BASEPRES,81,31,82,12,ES_CENTER | ES_AUTOHSCROLL | - ES_NUMBER + EDITTEXT IDC_BASEPRES,81,31,82,12,ES_CENTER | ES_AUTOHSCROLL | ES_NUMBER END -IDD_OPT_FILETYPES DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_FILETYPES DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN - COMBOBOX IDC_FILELIST,59,6,108,61,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP + COMBOBOX IDC_FILELIST,59,6,108,61,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Supported Files",IDC_STATIC,6,8,50,8 LTEXT "Extension",IDC_FILES_EXT,7,25,154,8 LTEXT "Mime Type",IDC_FILES_MIMES,7,37,156,8 - CONTROL "Associate with Osmo4",IDC_ASSOCIATE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,60,84,10 + CONTROL "Associate with Osmo4",IDC_ASSOCIATE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,60,84,10 LTEXT "Plugin",IDC_FILES_PLUG,8,49,154,8 END -IDD_OPT_LOGS DIALOG DISCARDABLE 0, 20, 169, 76 -STYLE DS_MODALFRAME | DS_CONTROL | WS_CHILD +IDD_OPT_LOGS DIALOG 0, 20, 169, 76 +STYLE DS_SETFONT | DS_MODALFRAME | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif" BEGIN LTEXT "Level",IDC_STATIC,6,7,18,8 - COMBOBOX IDC_LOG_LEVEL,30,4,64,74,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - CONTROL "core",IDC_TOOL_CORE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,3,23,30,10 - CONTROL "coding",IDC_TOOL_CODING,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,3,33,37,10 - CONTROL "container",IDC_TOOL_CONTAINER,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,3,43,45,10 - CONTROL "network",IDC_TOOL_NET,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,3,53,41,10 - CONTROL "rtp",IDC_TOOL_RTP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 3,63,24,10 - CONTROL "author",IDC_TOOL_AUTHOR,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,48,24,36,10 - CONTROL "sync",IDC_TOOL_SYNC,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,48,34,31,10 - CONTROL "codec",IDC_TOOL_CODEC,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,48,44,36,10 - CONTROL "parser",IDC_TOOL_PARSER,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,48,54,35,10 - CONTROL "media",IDC_TOOL_MEDIA,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,48,64,35,10 - CONTROL "scene",IDC_TOOL_SCENE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,86,24,35,10 - CONTROL "script",IDC_TOOL_SCRIPT,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,86,34,33,10 - CONTROL "compose",IDC_TOOL_COMPOSE,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,86,44,45,10 - CONTROL "render",IDC_TOOL_RENDER,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,86,54,36,10 - CONTROL "mmio",IDC_TOOL_MMIO,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,86,64,32,10 + COMBOBOX IDC_LOG_LEVEL,30,4,64,74,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + CONTROL "core",IDC_TOOL_CORE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,23,30,10 + CONTROL "coding",IDC_TOOL_CODING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,33,37,10 + CONTROL "container",IDC_TOOL_CONTAINER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,43,45,10 + CONTROL "network",IDC_TOOL_NET,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,53,41,10 + CONTROL "rtp",IDC_TOOL_RTP,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,3,63,24,10 + CONTROL "author",IDC_TOOL_AUTHOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,24,36,10 + CONTROL "sync",IDC_TOOL_SYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,34,31,10 + CONTROL "codec",IDC_TOOL_CODEC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,44,36,10 + CONTROL "parser",IDC_TOOL_PARSER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,54,35,10 + CONTROL "media",IDC_TOOL_MEDIA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,48,64,35,10 + CONTROL "scene",IDC_TOOL_SCENE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,24,35,10 + CONTROL "script",IDC_TOOL_SCRIPT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,34,33,10 + CONTROL "compose",IDC_TOOL_COMPOSE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,44,45,10 + CONTROL "render",IDC_TOOL_RENDER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,54,36,10 + CONTROL "mmio",IDC_TOOL_MMIO,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,86,64,32,10 END @@ -765,7 +647,7 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE +GUIDELINES DESIGNINFO BEGIN IDD_OPT_VIDEO, DIALOG BEGIN @@ -832,7 +714,7 @@ END // Toolbar // -IDR_PLAYLIST TOOLBAR DISCARDABLE 16, 15 +IDR_PLAYLIST TOOLBAR 16, 15 BEGIN BUTTON ID_PL_OPEN BUTTON ID_PL_SAVE @@ -849,7 +731,7 @@ END // Bitmap // -IDR_PLAYLIST BITMAP DISCARDABLE "res\\playlist.bmp" +IDR_PLAYLIST BITMAP "res\\playlist.bmp" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -857,18 +739,18 @@ IDR_PLAYLIST BITMAP DISCARDABLE "res\\playlist.bmp" // TEXTINCLUDE // -1 TEXTINCLUDE DISCARDABLE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE DISCARDABLE +2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END -3 TEXTINCLUDE DISCARDABLE +3 TEXTINCLUDE BEGIN "#define _AFX_NO_SPLITTER_RESOURCES\r\n" "#define _AFX_NO_OLE_RESOURCES\r\n" @@ -896,12 +778,12 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDR_MAINFRAME ICON DISCARDABLE "res\\osmo4.ico" -IDI_PLAY ICON DISCARDABLE "res\\play.ico" -IDI_STOP ICON DISCARDABLE "res\\stop.ico" -IDI_PAUSE ICON DISCARDABLE "res\\pause.ico" -IDI_MESSAGE ICON DISCARDABLE "res\\message.ico" -IDI_ERR ICON DISCARDABLE "res\\error.ico" +IDR_MAINFRAME ICON "..\\..\\doc\\osmo4.ico" +IDI_PLAY ICON "res\\play.ico" +IDI_STOP ICON "res\\stop.ico" +IDI_PAUSE ICON "res\\pause.ico" +IDI_MESSAGE ICON "res\\message.ico" +IDI_ERR ICON "res\\error.ico" ///////////////////////////////////////////////////////////////////////////// // @@ -969,7 +851,7 @@ BEGIN 0 END -#endif // French (France) resources +#endif // Français (France) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/applications/osmo4_w32/Playlist.cpp b/applications/osmo4_w32/Playlist.cpp index b2d648f..e06bfdd 100644 --- a/applications/osmo4_w32/Playlist.cpp +++ b/applications/osmo4_w32/Playlist.cpp @@ -18,26 +18,26 @@ static char THIS_FILE[] = __FILE__; PLEntry::PLEntry(CString url, char *path) { if (!path || strrchr(url, '\\') || strstr(url, "://")) { - m_url = strdup(url); + m_url = gf_strdup(url); } else { char szPath[MAX_PATH]; strcpy(szPath, path); strcat(szPath, url); - m_url = strdup(szPath); + m_url = gf_strdup(szPath); } char *str = (char *) strrchr(url, '\\'); if (!str) str = (char *) strrchr(url, '/'); if (str && strlen(str+1)) { - m_disp_name = strdup(str+1); + m_disp_name = gf_strdup(str+1); str = strrchr(m_disp_name, '.'); if (str) str[0] = 0; } else { str = (char *) strstr(url, "://"); if (str) { str += 3; - m_disp_name = strdup(str); + m_disp_name = gf_strdup(str); } else { - m_disp_name = strdup(url); + m_disp_name = gf_strdup(url); str = strrchr(m_disp_name, '.'); if (str) str[0] = 0; } @@ -50,8 +50,8 @@ PLEntry::PLEntry(CString url, char *path) PLEntry::~PLEntry() { - if (m_url) free(m_url); - if (m_disp_name) free(m_disp_name); + if (m_url) gf_free(m_url); + if (m_disp_name) gf_free(m_disp_name); } @@ -360,7 +360,7 @@ void Playlist::RefreshList() } - strcpy((char *) szPath, GetApp()->szAppPath); + strcpy((char *) szPath, GetApp()->szUserPath); strcat(szPath, "gpac_pl.m3u"); Save(szPath, 1); } @@ -372,7 +372,7 @@ void Playlist::OnPlAddFile() CFileDialog fd(TRUE,NULL,NULL, OFN_ALLOWMULTISELECT | OFN_HIDEREADONLY | OFN_FILEMUSTEXIST , sFiles); fd.m_ofn.nMaxFile = 25000; - fd.m_ofn.lpstrFile = (char *) malloc(sizeof(char) * fd.m_ofn.nMaxFile); + fd.m_ofn.lpstrFile = (char *) gf_malloc(sizeof(char) * fd.m_ofn.nMaxFile); fd.m_ofn.lpstrFile[0] = 0; if (fd.DoModal() == IDOK) { @@ -382,7 +382,7 @@ void Playlist::OnPlAddFile() QueueURL(fd.GetNextPathName(pos)); } } - free(fd.m_ofn.lpstrFile); + gf_free(fd.m_ofn.lpstrFile); m_all_dead_entries=-1; RefreshList(); } @@ -576,7 +576,7 @@ void Playlist::OnPlSave() void Playlist::Save(char *szPath, Bool save_m3u) { - FILE *out = fopen(szPath, "wt"); + FILE *out = gf_f64_open(szPath, "wt"); if (!save_m3u) fprintf(out, "[playlist]\nNumberOfEntries=%d\n", gf_list_count(m_entries)); @@ -621,7 +621,7 @@ void Playlist::OpenPlayList(CString fileName) if (sep) sep[1] = 0; else szPath[0] = 0; - pl = fopen(fileName, "rt"); + pl = gf_f64_open(fileName, "rt"); if (!pl) return; ple = NULL; load_m3u = 1; @@ -659,8 +659,8 @@ void Playlist::OpenPlayList(CString fileName) if (d>0) ple->m_duration = d; } else if (ple && !strnicmp(szLine, "Title", 5)) { char *st = strchr(szLine, '='); - free(ple->m_disp_name); - ple->m_disp_name = strdup(st + 6); + gf_free(ple->m_disp_name); + ple->m_disp_name = gf_strdup(st + 6); } } fclose(pl); diff --git a/applications/osmo4_w32/StdAfx.h b/applications/osmo4_w32/StdAfx.h index 2209b7e..914d5bf 100644 --- a/applications/osmo4_w32/StdAfx.h +++ b/applications/osmo4_w32/StdAfx.h @@ -6,6 +6,10 @@ #if !defined(AFX_STDAFX_H__1EEB44C5_1152_4872_8CA7_BD2994085EDC__INCLUDED_) #define AFX_STDAFX_H__1EEB44C5_1152_4872_8CA7_BD2994085EDC__INCLUDED_ +#ifndef WINVER +#define WINVER 0x0501 +#endif + #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 diff --git a/applications/osmo4_wce/MainFrm.cpp b/applications/osmo4_wce/MainFrm.cpp index 27a5621..9533161 100644 --- a/applications/osmo4_wce/MainFrm.cpp +++ b/applications/osmo4_wce/MainFrm.cpp @@ -1,7 +1,13 @@ // MainFrm.cpp : implementation of the CMainFrame class // +#ifdef _DEBUG +#include "stdafx.h" +#else #include "stdafx.h" +#undef _DEBUG +#endif + #include "Osmo4.h" #include @@ -190,7 +196,7 @@ void CMainFrame::SetPauseButton(Bool force_play_button) memset(&tb, 0, sizeof(tb)); tb.idCommand = ID_FILE_PAUSE; tb.fsStyle = TBSTYLE_BUTTON; - if (force_play_button || GetApp()->m_stoped || gf_term_get_option(GetApp()->m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) { + if (force_play_button || GetApp()->m_stopped || gf_term_get_option(GetApp()->m_term, GF_OPT_PLAY_STATE)==GF_STATE_PAUSED) { tb.iBitmap = 4; } else { tb.iBitmap = 1; @@ -257,7 +263,7 @@ void CMainFrame::UpdateTime() u32 now; COsmo4 *app = GetApp(); - if (!app->m_open || app->m_stoped) return; + if (!app->m_open || app->m_stopped) return; now = gf_term_get_time_in_ms(app->m_term); if (!now) return; @@ -398,7 +404,7 @@ LONG CMainFrame::Open(WPARAM wParam, LPARAM lParam) CloseURL(); char filename[5000]; CE_WideToChar((u16 *) (LPCTSTR) app->m_filename, filename); - app->m_stoped = 0; + app->m_stopped = 0; if (app->m_reconnect_time) { gf_term_connect_from_time(app->m_term, filename, app->m_reconnect_time, 0); @@ -424,9 +430,9 @@ LONG CMainFrame::OnNavigate(WPARAM /*wParam*/, LPARAM /*lParam*/) TCHAR w_to_url[MAX_PATH]; CE_WideToChar((u16 *) (LPCTSTR) app->m_filename, fileName); char *str = gf_url_concatenate(fileName, to_url); - if (!str) str = strdup(to_url); + if (!str) str = gf_strdup(to_url); CE_CharToWide(str, (u16 *)w_to_url); - free(str); + gf_free(str); app->m_filename = w_to_url; Open(0, 0); } else { @@ -457,10 +463,10 @@ LONG CMainFrame::OnNavigate(WPARAM /*wParam*/, LPARAM /*lParam*/) void CMainFrame::OnFilePause() { COsmo4 *app = GetApp(); - if (app->m_stoped) { + if (app->m_stopped) { char filename[5000]; CE_WideToChar((u16 *) (LPCTSTR) app->m_filename, filename); - app->m_stoped = 0; + app->m_stopped = 0; gf_term_connect(app->m_term, filename); app->SetBacklightState(1); @@ -475,14 +481,14 @@ void CMainFrame::OnFilePause() void CMainFrame::OnUpdateFilePause(CCmdUI* pCmdUI) { COsmo4 *app = GetApp(); - pCmdUI->Enable((app->m_open || app->m_stoped) ? TRUE : FALSE); + pCmdUI->Enable((app->m_open || app->m_stopped) ? TRUE : FALSE); } void CMainFrame::OnFileStop() { COsmo4 *app = GetApp(); if (!app->m_open) return; if (m_full_screen) OnViewFullscreen(); - app->m_stoped = 1; + app->m_stopped = 1; if (m_view_timing) KillTimer(PROGRESS_TIMER); gf_term_disconnect(app->m_term); m_progBar.SetPosition(0); diff --git a/applications/osmo4_wce/Osmo4.cpp b/applications/osmo4_wce/Osmo4.cpp index 5b02d14..0eea50b 100644 --- a/applications/osmo4_wce/Osmo4.cpp +++ b/applications/osmo4_wce/Osmo4.cpp @@ -254,6 +254,7 @@ BOOL COsmo4::InitInstance() if (!m_user.modules) { unsigned char str_path[MAX_PATH]; const char *sOpt; + FILE *t; /*inital launch*/ m_user.modules = gf_modules_new(config_path, m_user.config); if (m_user.modules) { @@ -296,8 +297,16 @@ BOOL COsmo4::InitInstance() /*by default use GDIplus, much faster than freetype on font loading*/ gf_cfg_set_key(m_user.config, "FontEngine", "FontReader", "ft_font"); - sprintf((char *) str_path, "%sgpac.mp4", config_path); - gf_cfg_set_key(m_user.config, "General", "StartupFile", (const char *) str_path); + sprintf((char *) str_path, "%sgui/gui.bt", config_path); + t = fopen(str_path, "rt"); + if (!t) { + sprintf((char *) str_path, "%sgpac.mp4", config_path); + t = fopen(str_path, "rt"); + } + if (t) { + gf_cfg_set_key(m_user.config, "General", "StartupFile", (const char *) str_path); + fclose(t); + } ::MessageBox(NULL, _T("Osmo4/GPAC Setup complete"), _T("Initial launch"), MB_OK); } @@ -339,7 +348,7 @@ BOOL COsmo4::InitInstance() m_pMainWnd->PostMessage(WM_QUIT); } - m_stoped = 0; + m_stopped = 0; m_open = 0; m_can_seek = 0; m_DoResume = 0; diff --git a/applications/osmo4_wce/Osmo4.h b/applications/osmo4_wce/Osmo4.h index 8c842d3..c063de6 100644 --- a/applications/osmo4_wce/Osmo4.h +++ b/applications/osmo4_wce/Osmo4.h @@ -58,7 +58,7 @@ public: u32 m_duration; CString m_navigate_url; - Bool m_Loop, m_fit_screen, m_can_seek, m_open, m_disable_backlight, m_stoped, m_no_mime_fetch; + Bool m_Loop, m_fit_screen, m_can_seek, m_open, m_disable_backlight, m_stopped, m_no_mime_fetch; void Pause(); u32 m_scene_width, m_scene_height, m_reconnect_time; diff --git a/applications/osmo4_wce/StdAfx.h b/applications/osmo4_wce/StdAfx.h index c78f502..93d8297 100644 --- a/applications/osmo4_wce/StdAfx.h +++ b/applications/osmo4_wce/StdAfx.h @@ -18,7 +18,6 @@ #error This project can not be built for H/PC Pro 2.11 or earlier platforms. #endif - #define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers #include // MFC core and standard components diff --git a/applications/osmo4_wx/Makefile b/applications/osmo4_wx/Makefile index a0841d7..a8fcd5c 100644 --- a/applications/osmo4_wx/Makefile +++ b/applications/osmo4_wx/Makefile @@ -41,7 +41,7 @@ SRCS := $(OBJS:.o=.cpp) all: $(PROG) Osmo4$(EXE): $(OBJS) - $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(WX_LFLAGS) -lz + $(CC) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(WX_LFLAGS) %.o: %.cpp $(CXX) $(CFLAGS) $(INSTALL_FLAGS) $(WX_CFLAGS) -c -o $@ $< diff --git a/applications/osmo4_wx/Playlist.cpp b/applications/osmo4_wx/Playlist.cpp index 6147702..7ed47a6 100644 --- a/applications/osmo4_wx/Playlist.cpp +++ b/applications/osmo4_wx/Playlist.cpp @@ -6,7 +6,7 @@ * * This file is part of GPAC / Osmo4 wxWidgets GUI * - * GPAC is free software; you can redistribute it and/or modify + * GPAC is gf_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. @@ -31,7 +31,7 @@ PLEntry::PLEntry(wxString url) { - m_url = strdup(url.mb_str(wxConvUTF8)); + m_url = gf_strdup(url.mb_str(wxConvUTF8)); Bool is_remote = 0;; wxCharBuffer the_url = (const char *) url.mb_str(wxConvUTF8); const char *_url = strstr(the_url, "://"); @@ -41,11 +41,11 @@ PLEntry::PLEntry(wxString url) char *str = (char*)strrchr(_url, '\\'); if (!str) str = (char*)strrchr(_url, '/'); if (str && strlen(str+1)) { - m_disp_name = strdup(str+1); + m_disp_name = gf_strdup(str+1); str = strrchr(m_disp_name, '.'); if (str) str[0] = 0; } else { - m_disp_name = strdup(_url); + m_disp_name = gf_strdup(_url); if (!is_remote) { str = strrchr(m_disp_name, '.'); if (str) str[0] = 0; @@ -59,8 +59,8 @@ PLEntry::PLEntry(wxString url) PLEntry::~PLEntry() { - if (m_url) free(m_url); - if (m_disp_name) free(m_disp_name); + if (m_url) gf_free(m_url); + if (m_disp_name) gf_free(m_disp_name); } @@ -551,8 +551,8 @@ void wxPlaylist::OpenPlaylist(wxString filename) if (d>0) ple->m_duration = d; } else if (ple && !strnicmp(szLine, "Title", 5)) { char *st = strchr(szLine, '='); - free(ple->m_disp_name); - ple->m_disp_name = strdup(st + 6); + gf_free(ple->m_disp_name); + ple->m_disp_name = gf_strdup(st + 6); } } fclose(pl); diff --git a/applications/osmo4_wx/fileprops.cpp b/applications/osmo4_wx/fileprops.cpp index 5645e82..4697d55 100644 --- a/applications/osmo4_wx/fileprops.cpp +++ b/applications/osmo4_wx/fileprops.cpp @@ -167,7 +167,7 @@ void wxFileProps::OnSelectInfo(wxCommandEvent & WXUNUSED(event) ) void wxFileProps::SetGeneralInfo() { wxString info; - ODInfo odi; + GF_MediaInfo odi; u32 h, m, s; u32 i, j; @@ -283,7 +283,7 @@ void wxFileProps::SetStreamsInfo() { u32 i, count; wxString info; - ODInfo odi; + GF_MediaInfo odi; char code[5]; info = wxT(""); @@ -327,16 +327,17 @@ void wxFileProps::SetStreamsInfo() case GF_STREAM_VISUAL: info += wxT("\tVisual Stream - media type: "); switch (esd->decoderConfig->objectTypeIndication) { - case 0x20: info += wxT("MPEG-4\n"); break; - case 0x60: info += wxT("MPEG-2 Simple Profile\n"); break; - case 0x61: info += wxT("MPEG-2 Main Profile\n"); break; - case 0x62: info += wxT("MPEG-2 SNR Profile\n"); break; - case 0x63: info += wxT("MPEG-2 Spatial Profile\n"); break; - case 0x64: info += wxT("MPEG-2 High Profile\n"); break; - case 0x65: info += wxT("MPEG-2 422 Profile\n"); break; - case 0x6A: info += wxT("MPEG-1\n"); break; - case 0x6C: info += wxT("JPEG\n"); break; - case 0x6D: info += wxT("PNG\n"); break; + case GPAC_OTI_VIDEO_MPEG4_PART2: info += wxT("MPEG-4\n"); break; + case GPAC_OTI_VIDEO_MPEG2_SIMPLE: info += wxT("MPEG-2 Simple Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_MAIN: info += wxT("MPEG-2 Main Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_SNR: info += wxT("MPEG-2 SNR Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_SPATIAL: info += wxT("MPEG-2 Spatial Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_HIGH: info += wxT("MPEG-2 High Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG2_422: info += wxT("MPEG-2 422 Profile\n"); break; + case GPAC_OTI_VIDEO_MPEG1: info += wxT("MPEG-1\n"); break; + case GPAC_OTI_IMAGE_JPEG: info += wxT("JPEG\n"); break; + case GPAC_OTI_IMAGE_PNG: info += wxT("PNG\n"); break; + case GPAC_OTI_IMAGE_JPEG_2000: info += wxT("JPEG2000\n"); break; case 0x80: memcpy(code, esd->decoderConfig->decoderSpecificInfo->data, 4); code[4] = 0; @@ -351,12 +352,12 @@ void wxFileProps::SetStreamsInfo() case GF_STREAM_AUDIO: info += wxT("\tAudio Stream - media type: "); switch (esd->decoderConfig->objectTypeIndication) { - case 0x40: info += wxT("MPEG-4\n"); break; - case 0x66: info += wxT("MPEG-2 AAC Main Profile\n"); break; - case 0x67: info += wxT("MPEG-2 AAC LowComplexity Profile\n"); break; - case 0x68: info += wxT("MPEG-2 AAC Scalable Sampling Rate Profile\n"); break; - case 0x69: info += wxT("MPEG-2 Audio\n"); break; - case 0x6B: info += wxT("MPEG-1 Audio\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG4: info += wxT("MPEG-4\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: info += wxT("MPEG-2 AAC Main Profile\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: info += wxT("MPEG-2 AAC LowComplexity Profile\n"); break; + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: info += wxT("MPEG-2 AAC Scalable Sampling Rate Profile\n"); break; + case GPAC_OTI_AUDIO_MPEG2_PART3: info += wxT("MPEG-2 Audio\n"); break; + case GPAC_OTI_AUDIO_MPEG1: info += wxT("MPEG-1 Audio\n"); break; case 0xA0: info += wxT("EVRC Audio\n"); break; case 0xA1: info += wxT("SMV Audio\n"); break; case 0xE1: info += wxT("QCELP Audio\n"); break; @@ -408,7 +409,7 @@ void wxFileProps::SetStreamsInfo() lan[2] = (esd->langDesc->langCode)&0xFF; lan[3] = 0; - if ((lan[0]=='u') && (lan[1]=='n') && (lan[2]=='d')) szLang = "Undetermined"; + if ((lan[0]=='u') && (lan[1]=='n') && (lan[2]=='d')) szLang = (char*) "Undetermined"; else { szLang = lan; while (GF_ISO639_Lang[i]) { @@ -430,7 +431,7 @@ void wxFileProps::SetStreamsInfo() void wxFileProps::SetDecoderInfo() { - ODInfo odi; + GF_MediaInfo odi; wxString info; u32 h, m, s; @@ -494,7 +495,7 @@ void wxFileProps::SetNetworkInfo() wxString info; u32 id; NetStatCommand com; - ODInfo odi; + GF_MediaInfo odi; u32 d_enum; GF_Err e; @@ -594,7 +595,7 @@ void wxFileProps::OnViewSG(wxCommandEvent &WXUNUSED(event)) } strcpy(szOutFile, out_file.GetFullName().mb_str(wxConvUTF8)); - GF_Err e = gf_term_dump_scene(m_pApp->m_term, szOutFile, dump_xmt, 0, m_current_odm); + GF_Err e = gf_term_dump_scene(m_pApp->m_term, szOutFile, NULL, dump_xmt, 0, m_current_odm); if (e) { wxMessageDialog dlg(this, wxString(gf_error_to_string(e), wxConvUTF8), wxT("Error while dumping"), wxOK); dlg.ShowModal(); diff --git a/applications/osmo4_wx/osmo4.xpm b/applications/osmo4_wx/osmo4.xpm index b1a4cd6..bec8e6a 100644 --- a/applications/osmo4_wx/osmo4.xpm +++ b/applications/osmo4_wx/osmo4.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char * osmo4[] = { +static const char * osmo4[] = { "32 32 266 2", " c None", ". c #990909", diff --git a/applications/osmo4_wx/playlist.xpm b/applications/osmo4_wx/playlist.xpm index 6ec3810..cfad2dc 100644 --- a/applications/osmo4_wx/playlist.xpm +++ b/applications/osmo4_wx/playlist.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char* pl_open[] = { +static const char* pl_open[] = { "16 16 5 1", " c #000000", "! c #808000", @@ -24,7 +24,7 @@ static char* pl_open[] = { "################"}; /* XPM */ -static char* pl_save[] = { +static const char* pl_save[] = { "16 16 3 1", " c #000000", "! c #808000", @@ -47,7 +47,7 @@ static char* pl_save[] = { "################"}; /* XPM */ -static char* pl_add[] = { +static const char* pl_add[] = { "16 16 2 1", " c #000000", "! c #C0C0C0", @@ -69,7 +69,7 @@ static char* pl_add[] = { "!!!!!!!!!!!!!!!!"}; /* XPM */ -static char* pl_rem[] = { +static const char* pl_rem[] = { "16 16 2 1", " c #000000", "! c #C0C0C0", @@ -91,7 +91,7 @@ static char* pl_rem[] = { "!!!!!!!!!!!!!!!!"}; /* XPM */ -static char* pl_up[] = { +static const char* pl_up[] = { "16 16 2 1", " c #000000", "! c #C0C0C0", @@ -113,7 +113,7 @@ static char* pl_up[] = { "!!!!!!!!!!!!!!!!"}; /* XPM */ -static char* pl_down[] = { +static const char* pl_down[] = { "16 16 2 1", " c #000000", "! c #C0C0C0", @@ -135,7 +135,7 @@ static char* pl_down[] = { "!!!!!!!!!!!!!!!!"}; /* XPM */ -static char* pl_sort[] = { +static const char* pl_sort[] = { "16 16 2 1", " c #000000", "! c #C0C0C0", diff --git a/applications/osmo4_wx/resource.h b/applications/osmo4_wx/resource.h index 2d49449..ace6dd4 100644 --- a/applications/osmo4_wx/resource.h +++ b/applications/osmo4_wx/resource.h @@ -2,7 +2,7 @@ // Microsoft Developer Studio generated include file. // Used by wxOsmo4.rc // -#define IDI_ICON1 101 +#define IDI_OSMO_ICON 101 // Next default values for new objects // diff --git a/applications/osmo4_wx/toolbar.xpm b/applications/osmo4_wx/toolbar.xpm index d9cdc79..887d59e 100644 --- a/applications/osmo4_wx/toolbar.xpm +++ b/applications/osmo4_wx/toolbar.xpm @@ -1,5 +1,5 @@ /* XPM */ -static char* tool_open_file[] = { +static const char* tool_open_file[] = { "16 16 2 1", " c #000000", "! c none", @@ -21,7 +21,7 @@ static char* tool_open_file[] = { "!!!!!!!!!!!!!!!!"}; /* XPM */ -static char* tool_prev[] = { +static const char* tool_prev[] = { "16 16 3 1", " c #000000", "! c none", @@ -44,7 +44,7 @@ static char* tool_prev[] = { "!!!!!!!!!!!!!!!!"}; /* XPM */ -static char* tool_next[] = { +static const char* tool_next[] = { "16 16 3 1", " c #000000", "! c none", @@ -67,7 +67,7 @@ static char* tool_next[] = { "!!!!!!!!!!!!!!!!"}; /* XPM */ -static char* tool_play[] = { +static const char* tool_play[] = { "16 16 2 1", " c #000000", "! c none", @@ -89,7 +89,7 @@ static char* tool_play[] = { "!!!!!!!!!!!!!!!!"}; /* XPM */ -static char* tool_pause[] = { +static const char* tool_pause[] = { "16 16 3 1", " c #000000", "! c #808080", @@ -113,7 +113,7 @@ static char* tool_pause[] = { /* XPM */ -static char* tool_step[] = { +static const char* tool_step[] = { "16 16 2 1", " c #000000", "! c none", @@ -136,7 +136,7 @@ static char* tool_step[] = { /* XPM */ -static char* tool_stop[] = { +static const char* tool_stop[] = { "16 16 2 1", " c #000000", "! c none", @@ -158,7 +158,7 @@ static char* tool_stop[] = { "!!!!!!!!!!!!!!!!"}; /* XPM */ -static char* tool_info[] = { +static const char* tool_info[] = { "16 16 3 1", " c #000000", "! c none", @@ -182,7 +182,7 @@ static char* tool_info[] = { /* XPM */ -static char* tool_config[] = { +static const char* tool_config[] = { "16 16 3 1", " c #000000", "! c #808080", @@ -205,7 +205,7 @@ static char* tool_config[] = { "################"}; /* XPM */ -static char* tool_sw_2d[] = { +static const char* tool_sw_2d[] = { "16 16 4 1", " c #FF0000", ". c #C0C0C0", @@ -229,7 +229,7 @@ static char* tool_sw_2d[] = { "................"}; /* XPM */ -static char* tool_sw_3d[] = { +static const char* tool_sw_3d[] = { "16 16 4 1", " c #FFFFFF", ". c #C0C0C0", diff --git a/applications/osmo4_wx/wxGPACControl.cpp b/applications/osmo4_wx/wxGPACControl.cpp index 59c788c..bbaa438 100644 --- a/applications/osmo4_wx/wxGPACControl.cpp +++ b/applications/osmo4_wx/wxGPACControl.cpp @@ -37,7 +37,7 @@ #define NUM_RATES 11 -static char *BIFSRates[11] = +static const char *BIFSRates[11] = { "5.0", "7.5", diff --git a/applications/osmo4_wx/wxOsmo4.cpp b/applications/osmo4_wx/wxOsmo4.cpp index 888f7d1..2c32ef9 100644 --- a/applications/osmo4_wx/wxOsmo4.cpp +++ b/applications/osmo4_wx/wxOsmo4.cpp @@ -6,21 +6,21 @@ * * This file is part of GPAC / Osmo4 wxWidgets GUI * - * GPAC is free software; you can redistribute it and/or modify + * GPAC is gf_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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * * - * */ @@ -158,7 +158,7 @@ u32 get_sys_col(int idx) } #endif -static void wxOsmo4_progress_cbk(void *usr, char *title, u32 done, u32 total) +static void wxOsmo4_progress_cbk(void *usr, char *title, u64 done, u64 total) { if (!total) return; wxOsmo4Frame *app = (wxOsmo4Frame *)usr; @@ -214,19 +214,21 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) } } +#if 0 /*log*/ - if (evt->message.error) + if (evt->message.error) ::wxLogMessage(wxString(evt->message.message, wxConvUTF8) + wxT(" (") + wxString(servName, wxConvUTF8) + wxT(") ") + wxString(gf_error_to_string(evt->message.error), wxConvUTF8) ); else ::wxLogMessage(wxString(evt->message.message, wxConvUTF8) + wxT(" (") + wxString(servName, wxConvUTF8) + wxT(")")); +#endif } break; case GF_EVENT_PROGRESS: { char *sTitle; - if (evt->progress.progress_type==0) sTitle = "Buffer"; - else if (evt->progress.progress_type==1) sTitle = "Download"; - else if (evt->progress.progress_type==2) sTitle = "Import"; + if (evt->progress.progress_type==0) sTitle = (char *)"Buffer"; + else if (evt->progress.progress_type==1) sTitle = (char *)"Download"; + else if (evt->progress.progress_type==2) sTitle = (char *)"Import"; gf_set_progress(sTitle, evt->progress.done, evt->progress.total); } break; @@ -270,7 +272,7 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) gf_term_set_option(app->m_term, GF_OPT_NAVIGATION_TYPE, 1); break; case GF_KEY_ESCAPE: - if (gf_term_get_option(app->m_term, GF_OPT_FULLSCREEN)) + if (gf_term_get_option(app->m_term, GF_OPT_FULLSCREEN)) gf_term_set_option(app->m_term, GF_OPT_FULLSCREEN, 0); break; default: @@ -382,7 +384,7 @@ bool wxOsmo4App::OnInit() wxFrame *frame = new wxOsmo4Frame(); frame->Show(TRUE); SetTopWindow(frame); - return true; + return true; } @@ -407,7 +409,7 @@ bool myDropfiles::OnDropFiles(wxCoord x, wxCoord y, const wxArrayString& filenam } } - for (u32 i=0; im_pPlayList->QueueURL(filenames.Item(i)); m_pMain->m_pPlayList->RefreshList(); @@ -635,7 +637,7 @@ Bool wxOsmo4Frame::LoadTerminal() gf_log_set_tools(m_log_tools); } - gf_sys_init(); + gf_sys_init(0); ::wxLogMessage(wxT("GPAC configuration file opened - looking for modules")); str = gf_cfg_get_key(m_user.config, "General", "ModulesDirectory"); @@ -660,7 +662,7 @@ Bool wxOsmo4Frame::LoadTerminal() m_user.modules = NULL; if ( dlg.ShowModal() != wxID_OK ) return false; str = dlg.GetPath().mb_str(wxConvUTF8); - + m_user.modules = gf_modules_new(str, m_user.config); if (!m_user.modules || !gf_modules_get_count(m_user.modules) ) { wxMessageDialog(NULL, wxT("Cannot find any modules for GPAC"), wxT("Init error"), wxOK); @@ -695,8 +697,8 @@ Bool wxOsmo4Frame::LoadTerminal() gf_cfg_set_key(m_user.config, "Audio", "TotalDuration", "120"); } + char str_path[GF_MAX_PATH]; #ifdef WIN32 - unsigned char str_path[MAX_PATH]; sOpt = gf_cfg_get_key(m_user.config, "Compositor", "Raster2D"); if (!sOpt) gf_cfg_set_key(m_user.config, "Compositor", "Raster2D", "gdip_rend"); sOpt = gf_cfg_get_key(m_user.config, "General", "CacheDirectory"); @@ -710,20 +712,29 @@ Bool wxOsmo4Frame::LoadTerminal() sOpt = gf_cfg_get_key(m_user.config, "General", "StartupFile"); if (!sOpt) { - sprintf((char *) str_path, "%sgpac.mp4", abs_gpac_path.mb_str(wxConvUTF8)); - gf_cfg_set_key(m_user.config, "General", "StartupFile", (const char *) str_path); + FILE *t; + sprintf((char *) str_path, "%sgui/gui.bt", abs_gpac_path.mb_str(wxConvUTF8)); + t = fopen(str_path, "rt"); + if (!t) { + sprintf((char *) str_path, "%sgpac.mp4", config_path); + t = fopen(str_path, "rt"); + } + if (t) { + gf_cfg_set_key(m_user.config, "General", "StartupFile", (const char *) str_path); + fclose(t); + } } #else #if defined(__DARWIN__) || defined(__APPLE__) wxDirDialog dlg3(NULL, wxT("Please specify a cache directory for GPAC")); dlg3.SetPath(wxT("/tmp")); - if ( dlg3.ShowModal() == wxID_OK ) + if ( dlg3.ShowModal() == wxID_OK ) gf_cfg_set_key(m_user.config, "General", "CacheDirectory", (const char *) dlg3.GetPath().mb_str(wxConvUTF8) ); wxDirDialog dlg2(NULL, wxT("Please locate a TrueType font repository on your system for text support")); dlg2.SetPath(wxT("/usr/share/fonts/truetype")); - if ( dlg2.ShowModal() == wxID_OK ) + if ( dlg2.ShowModal() == wxID_OK ) gf_cfg_set_key(m_user.config, "FontEngine", "FontDirectory", (const char *) dlg2.GetPath().mb_str(wxConvUTF8) ); gf_cfg_set_key(m_user.config, "Video", "DriverName", "SDL Video Output"); @@ -745,21 +756,28 @@ Bool wxOsmo4Frame::LoadTerminal() sOpt = gf_cfg_get_key(m_user.config, "General", "StartupFile"); if (!sOpt) { FILE *test; - test = fopen("/usr/local/share/gpac/gpac.mp4", "rb"); + strcpy(str_path, "/usr/local/share/gpac/gui/gui.bt"); + test = fopen(str_path, "rb"); + if (!test) { + strcpy(str_path, "/usr/local/share/gpac/gpac.mp4"); + test = fopen(str_path, "rb"); + } + if (!test) { + strcpy(str_path, "/usr/share/gpac/gui/gui.bt"); + test = fopen(str_path, "rb"); + } + if (!test) { + strcpy(str_path, "/usr/share/gpac/gpac.mp4"); + test = fopen(str_path, "rb"); + } if (test) { - gf_cfg_set_key(m_user.config, "General", "StartupFile", "/usr/local/share/gpac/gpac.mp4"); + gf_cfg_set_key(m_user.config, "General", "StartupFile", str_path); fclose(test); - } else { - test = fopen("/usr/share/gpac/gpac.mp4", "rb"); - if (test) { - gf_cfg_set_key(m_user.config, "General", "StartupFile", "/usr/share/gpac/gpac.mp4"); - fclose(test); - } - } + } } #endif - } + } if (! gf_modules_get_count(m_user.modules) ) { wxMessageDialog(NULL, wxT("No modules available - system cannot work"), wxT("Fatal Error"), wxOK).ShowModal(); gf_modules_del(m_user.modules); @@ -822,8 +840,8 @@ wxDEFAULT_FRAME_STYLE wxMenuBar *b = new wxMenuBar(); /*file*/ wxMenu *menu = new wxMenu(); - menu->Append(FILE_OPEN, wxT("&Open File\tCtrl+O"), wxT("Open local presentation")); - menu->Append(FILE_OPEN_URL, wxT("&Open URL\tCtrl+U"), wxT("Open remote presentation")); + menu->Append(GWX_FILE_OPEN, wxT("&Open File\tCtrl+O"), wxT("Open local presentation")); + menu->Append(GWX_FILE_OPEN_URL, wxT("&Open URL\tCtrl+U"), wxT("Open remote presentation")); menu->AppendSeparator(); menu->Append(FILE_PROPERTIES, wxT("&Properties\tCtrl+I"), wxT("Show presentation properties")); menu->Enable(FILE_PROPERTIES, 0); @@ -942,8 +960,8 @@ wxDEFAULT_FRAME_STYLE m_pConfig = new wxBitmap(tool_config); m_pSW2D = new wxBitmap(tool_sw_2d); m_pSW3D = new wxBitmap(tool_sw_3d); - - m_pToolBar->AddTool(FILE_OPEN, wxT(""), *m_pOpenFile, wxT("Open File")); + + m_pToolBar->AddTool(GWX_FILE_OPEN, wxT(""), *m_pOpenFile, wxT("Open File")); m_pToolBar->AddSeparator(); m_pPrevBut = new wxMenuButton(m_pToolBar, FILE_PREV, *m_pPrev); m_pPrevBut->SetToolTip(wxT("Previous Location")); @@ -1011,7 +1029,7 @@ wxDEFAULT_FRAME_STYLE sOpt = gf_cfg_get_key(m_user.config, "General", "LookForSubtitles"); m_lookforsubs = (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0; gf_term_set_option(m_term, GF_OPT_AUDIO_VOLUME, 100); - + ReloadURLs(); Raise(); m_pStatusbar->SetStatusText(wxT("Ready"), 2); @@ -1068,7 +1086,7 @@ wxOsmo4Frame::~wxOsmo4Frame() gf_sys_close(); if (m_user.config) gf_cfg_del(m_user.config); - if (m_chapters_start) free(m_chapters_start); + if (m_chapters_start) gf_free(m_chapters_start); if (m_pView) delete m_pView; //m_pToolBar->RemoveTool(FILE_PREV); @@ -1094,8 +1112,8 @@ wxOsmo4Frame::~wxOsmo4Frame() BEGIN_EVENT_TABLE(wxOsmo4Frame, wxFrame) EVT_CLOSE(wxOsmo4Frame::OnCloseApp) - EVT_MENU(FILE_OPEN, wxOsmo4Frame::OnFileOpen) - EVT_MENU(FILE_OPEN_URL, wxOsmo4Frame::OnFileOpenURL) + EVT_MENU(GWX_FILE_OPEN, wxOsmo4Frame::OnFileOpen) + EVT_MENU(GWX_FILE_OPEN_URL, wxOsmo4Frame::OnFileOpenURL) EVT_MENU(FILE_RELOAD_CONFIG, wxOsmo4Frame::OnFileReloadConfig) EVT_MENU(FILE_RELOAD, wxOsmo4Frame::OnFileReload) EVT_MENU(FILE_PROPERTIES, wxOsmo4Frame::OnFileProperties) @@ -1125,7 +1143,7 @@ BEGIN_EVENT_TABLE(wxOsmo4Frame, wxFrame) EVT_MENU(ID_MCACHE_ABORT, wxOsmo4Frame::OnCacheAbort) EVT_UPDATE_UI(ID_MCACHE_STOP, wxOsmo4Frame::OnUpdateCacheAbort) EVT_UPDATE_UI(ID_MCACHE_ABORT, wxOsmo4Frame::OnUpdateCacheAbort) - + EVT_MENU(APP_SHORTCUTS, wxOsmo4Frame::OnShortcuts) EVT_MENU(APP_NAV_KEYS, wxOsmo4Frame::OnNavInfo) @@ -1153,39 +1171,39 @@ BEGIN_EVENT_TABLE(wxOsmo4Frame, wxFrame) EVT_COMBOBOX(ID_ADDRESS, wxOsmo4Frame::OnURLSelect) EVT_MENU_RANGE(ID_SELSTREAM_0, ID_SELSTREAM_9, wxOsmo4Frame::OnStreamSel) - EVT_UPDATE_UI_RANGE(ID_SELSTREAM_0, ID_SELSTREAM_9, wxOsmo4Frame::OnUpdateStreamSel) + EVT_UPDATE_UI_RANGE(ID_SELSTREAM_0, ID_SELSTREAM_9, wxOsmo4Frame::OnUpdateStreamSel) EVT_MENU_RANGE(ID_SETCHAP_FIRST, ID_SETCHAP_LAST, wxOsmo4Frame::OnChapterSel) - EVT_UPDATE_UI_RANGE(ID_SETCHAP_FIRST, ID_SETCHAP_LAST, wxOsmo4Frame::OnUpdateChapterSel) + EVT_UPDATE_UI_RANGE(ID_SETCHAP_FIRST, ID_SETCHAP_LAST, wxOsmo4Frame::OnUpdateChapterSel) EVT_MENU_RANGE(ID_VIEWPOINT_FIRST, ID_VIEWPOINT_LAST, wxOsmo4Frame::OnViewport) - EVT_UPDATE_UI_RANGE(ID_VIEWPOINT_FIRST, ID_VIEWPOINT_LAST, wxOsmo4Frame::OnUpdateViewport) + EVT_UPDATE_UI_RANGE(ID_VIEWPOINT_FIRST, ID_VIEWPOINT_LAST, wxOsmo4Frame::OnUpdateViewport) EVT_MENU_RANGE(ID_NAVIGATE_NONE, ID_NAVIGATE_GAME, wxOsmo4Frame::OnNavigate) - EVT_UPDATE_UI_RANGE(ID_NAVIGATE_NONE, ID_NAVIGATE_GAME, wxOsmo4Frame::OnUpdateNavigation) + EVT_UPDATE_UI_RANGE(ID_NAVIGATE_NONE, ID_NAVIGATE_GAME, wxOsmo4Frame::OnUpdateNavigation) EVT_MENU(ID_NAVIGATE_RESET, wxOsmo4Frame::OnNavigateReset) EVT_MENU_RANGE(ID_COLLIDE_NONE, ID_COLLIDE_DISP, wxOsmo4Frame::OnCollide) - EVT_UPDATE_UI_RANGE(ID_COLLIDE_NONE, ID_COLLIDE_DISP, wxOsmo4Frame::OnUpdateCollide) + EVT_UPDATE_UI_RANGE(ID_COLLIDE_NONE, ID_COLLIDE_DISP, wxOsmo4Frame::OnUpdateCollide) EVT_MENU(ID_HEADLIGHT, wxOsmo4Frame::OnHeadlight) - EVT_UPDATE_UI(ID_HEADLIGHT, wxOsmo4Frame::OnUpdateHeadlight) + EVT_UPDATE_UI(ID_HEADLIGHT, wxOsmo4Frame::OnUpdateHeadlight) EVT_MENU(ID_GRAVITY, wxOsmo4Frame::OnGravity) - EVT_UPDATE_UI(ID_GRAVITY, wxOsmo4Frame::OnUpdateGravity) + EVT_UPDATE_UI(ID_GRAVITY, wxOsmo4Frame::OnUpdateGravity) EVT_UPDATE_UI(FILE_PROPERTIES, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(FILE_RELOAD, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(FILE_PLAY, wxOsmo4Frame::OnUpdatePlay) - EVT_UPDATE_UI(FILE_STOP, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(FILE_STEP, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(VIEW_ORIGINAL, wxOsmo4Frame::OnUpdateNeedsConnect) - EVT_UPDATE_UI(VIEW_FULLSCREEN, wxOsmo4Frame::OnUpdateFullScreen) + EVT_UPDATE_UI(FILE_RELOAD, wxOsmo4Frame::OnUpdateNeedsConnect) + EVT_UPDATE_UI(FILE_PLAY, wxOsmo4Frame::OnUpdatePlay) + EVT_UPDATE_UI(FILE_STOP, wxOsmo4Frame::OnUpdateNeedsConnect) + EVT_UPDATE_UI(FILE_STEP, wxOsmo4Frame::OnUpdateNeedsConnect) + EVT_UPDATE_UI(VIEW_ORIGINAL, wxOsmo4Frame::OnUpdateNeedsConnect) + EVT_UPDATE_UI(VIEW_FULLSCREEN, wxOsmo4Frame::OnUpdateFullScreen) EVT_UPDATE_UI(VIEW_AR_KEEP, wxOsmo4Frame::OnUpdateAR) EVT_UPDATE_UI(VIEW_AR_FILL, wxOsmo4Frame::OnUpdateAR) EVT_UPDATE_UI(VIEW_AR_169, wxOsmo4Frame::OnUpdateAR) EVT_UPDATE_UI(VIEW_AR_43, wxOsmo4Frame::OnUpdateAR) - EVT_SIZE(wxOsmo4Frame::OnSize) + EVT_SIZE(wxOsmo4Frame::OnSize) END_EVENT_TABLE() void wxOsmo4Frame::DoLayout(u32 v_width, u32 v_height) @@ -1279,7 +1297,7 @@ wxString wxOsmo4Frame::GetFileFilter() if (sFiles.Find(wxString(sDesc, wxConvUTF8) )>=0) continue; /*if same extensions for # mime types skip (don't polluate the file list)*/ if (sExts.Find(wxString(szKeyList, wxConvUTF8) )>=0) continue; - + sExts += wxString(szKeyList, wxConvUTF8); sExts += wxT(" "); sFiles += wxString(sDesc, wxConvUTF8); @@ -1325,7 +1343,7 @@ void wxOsmo4Frame::OnFileOpen(wxCommandEvent & WXUNUSED(event)) } else { m_pPlayList->Clear(); } - for (u32 i=0; iQueueURL(stra[i]); m_pPlayList->RefreshList(); @@ -1352,7 +1370,7 @@ void wxOsmo4Frame::OnFileProperties(wxCommandEvent & WXUNUSED(event)) void wxOsmo4Frame::OnFileReload(wxCommandEvent & WXUNUSED(event)) { - gf_term_disconnect(m_term); + gf_term_disconnect(m_term); m_connected = 0; DoConnect(); } @@ -1459,11 +1477,11 @@ void wxOsmo4Frame::OnUpdateAR(wxUpdateUIEvent &event) u32 val = gf_term_get_option(m_term, GF_OPT_ASPECT_RATIO); if ((event.GetId() == VIEW_AR_FILL) && (val==GF_ASPECT_RATIO_FILL_SCREEN)) event.Check(1); - else if ((event.GetId() == VIEW_AR_KEEP) && (val==GF_ASPECT_RATIO_KEEP)) + else if ((event.GetId() == VIEW_AR_KEEP) && (val==GF_ASPECT_RATIO_KEEP)) event.Check(1); - else if ((event.GetId() == VIEW_AR_169) && (val==GF_ASPECT_RATIO_16_9)) + else if ((event.GetId() == VIEW_AR_169) && (val==GF_ASPECT_RATIO_16_9)) event.Check(1); - else if ((event.GetId() == VIEW_AR_43) && (val==GF_ASPECT_RATIO_4_3)) + else if ((event.GetId() == VIEW_AR_43) && (val==GF_ASPECT_RATIO_4_3)) event.Check(1); else event.Check(0); } @@ -1486,12 +1504,12 @@ void wxOsmo4Frame::OnShortcuts(wxCommandEvent & WXUNUSED(event)) wxT("\n") wxT("Shortcuts with focus on video frame:\n") wxT("Seek +5% into presentation: Alt + right arrow\n") - wxT("Seek -5% into presentation: Alt + left arrow\n") + wxT("Seek -5% into presentation: Alt + left arrow\n") wxT("Seek +1min into presentation: Alt + up arrow\n") wxT("Seek -1min into presentation: Alt + down arrow\n") wxT("Next Playlist Entry: Ctrl + right arrow\n") wxT("Prev Playlist Entry: Ctrl + left arrow\n") - + , wxT("Shortcuts Available on Osmo4") , wxOK); @@ -1571,7 +1589,7 @@ AboutDlg::AboutDlg(wxWindow *parent) wxT("Osmo4 Player\n") wxT("GPAC Multimedia Framework\n") wxT("\n") - wxT("This program is free software and may\n") + wxT("This program is gf_free software and may\n") wxT("be distributed according to the terms\n") wxT("of the GNU Lesser General Public License\n") wxT("\n") @@ -1616,11 +1634,11 @@ void wxOsmo4Frame::OnGPACEvent(wxGPACEvent &event) m_pPlayList->Truncate(); m_pPlayList->QueueURL(wxString(str, wxConvUTF8)); m_pPlayList->RefreshList(); - free(str); + gf_free(str); m_pPlayList->PlayNext(); } return; - } + } cmd = get_pref_browser(m_user.config); cmd += wxT(" "); cmd += event.to_url; @@ -1682,7 +1700,7 @@ static wxString format_time(u32 duration, u32 timescale) void wxOsmo4Frame::SetStatus(wxString str) { - //m_pStatusbar->SetStatusText(str, 2); + //m_pStatusbar->SetStatusText(str, 2); m_LastStatusTime = gf_sys_clock(); } @@ -1694,7 +1712,7 @@ void wxOsmo4Frame::OnRTI(wxCommandEvent & event) if (!m_pTimer->IsRunning()) m_pTimer->Start(RTI_REFRESH_MS, 0); } else if (!m_connected && m_pTimer->IsRunning()) { m_LastStatusTime = 0; - m_pStatusbar->SetStatusText(wxT("Ready"), 2); + m_pStatusbar->SetStatusText(wxT("Ready"), 2); m_pTimer->Stop(); } } @@ -1707,7 +1725,7 @@ void wxOsmo4Frame::OnTimer(wxTimerEvent& WXUNUSED(event)) now = gf_sys_clock(); if (now > 1000+m_LastStatusTime) { m_LastStatusTime = 0; - m_pStatusbar->SetStatusText(wxT("Ready"), 2); + m_pStatusbar->SetStatusText(wxT("Ready"), 2); } } @@ -1716,10 +1734,10 @@ void wxOsmo4Frame::OnTimer(wxTimerEvent& WXUNUSED(event)) if (!gf_sys_get_rti(RTI_REFRESH_MS, &rti, 0)) return; if (rti.gpac_memory) rti.process_memory = rti.gpac_memory; - str = wxString::Format(wxT("CPU %02d (%02d) - Mem %d kB" ), + str = wxString::Format(wxT("CPU %02d (%02d) - Mem %d kB" ), rti.total_cpu_usage, rti.process_cpu_usage, rti.gpac_memory/1024); - m_pStatusbar->SetStatusText(str, 2); + m_pStatusbar->SetStatusText(str, 2); } if (!m_connected) return; @@ -1771,7 +1789,7 @@ void wxOsmo4Frame::OnTimer(wxTimerEvent& WXUNUSED(event)) } } -void wxOsmo4Frame::ConnectAcknowledged(Bool bOk) +void wxOsmo4Frame::ConnectAcknowledged(Bool bOk) { if (bOk) { m_pTimer->Start(RTI_REFRESH_MS, 0); @@ -1857,7 +1875,7 @@ void wxOsmo4Frame::OnSlide(wxScrollEvent &event) now *= m_duration; wxString str = format_time((u32) (now), 1000); m_pStatusbar->SetStatusText(str); - } + } else if (m_bGrabbed){ m_bGrabbed = 0; Double res = (Double) m_pProg->GetValue(); @@ -1947,7 +1965,7 @@ void wxOsmo4Frame::OnUpdateNavigation(wxUpdateUIEvent & event) else if (ID==ID_NAVIGATE_SLIDE) { event.Enable(enable); event.Check((mode==GF_NAVIGATE_SLIDE) ? 1 : 0); } if (type==GF_NAVIGATE_TYPE_2D) return; - event.Enable(enable); + event.Enable(enable); if (ID==ID_NAVIGATE_WALK) event.Check((mode==GF_NAVIGATE_WALK) ? 1 : 0); else if (ID==ID_NAVIGATE_FLY) event.Check((mode==GF_NAVIGATE_FLY) ? 1 : 0); else if (ID==ID_NAVIGATE_PAN) event.Check((mode==GF_NAVIGATE_PAN) ? 1 : 0); @@ -1970,7 +1988,7 @@ void wxOsmo4Frame::UpdateRenderSwitch() { const char *opt = gf_cfg_get_key(m_user.config, "Compositor", "ForceOpenGL"); m_pToolBar->RemoveTool(SWITCH_RENDER); - if (opt && !stricmp(opt, "yes")) + if (opt && !stricmp(opt, "yes")) m_pToolBar->InsertTool(12, SWITCH_RENDER, *m_pSW2D, wxNullBitmap, FALSE, NULL, wxT("2D Rasterizer")); else m_pToolBar->InsertTool(12, SWITCH_RENDER, *m_pSW3D, wxNullBitmap, FALSE, NULL, wxT("OpenGL Rendering")); @@ -2090,7 +2108,7 @@ void wxOsmo4Frame::ReloadURLs() } } -void wxOsmo4Frame::SelectionReady() +void wxOsmo4Frame::SelectionReady() { wxString urlVal = m_Address->GetValue(); if (urlVal.Find(wxT("://"))>0) { @@ -2231,7 +2249,7 @@ void wxOsmo4Frame::BuildStreamList(Bool reset_only) for (u32 i=0; iFindItemByPosition(0)->GetSubMenu(); - if (!info.owns_service) sprintf(szLabel, "Audio #%d", pMenu->GetMenuItemCount() + 1); + if (!info.owns_service) sprintf(szLabel, "Audio #%ld", pMenu->GetMenuItemCount() + 1); pMenu->AppendCheckItem(ID_SELSTREAM_0 +i, wxString(szLabel, wxConvUTF8)); break; case GF_STREAM_VISUAL: pMenu = sel_menu->FindItemByPosition(1)->GetSubMenu(); - if (!info.owns_service) sprintf(szLabel, "Video #%d", pMenu->GetMenuItemCount() + 1); + if (!info.owns_service) sprintf(szLabel, "Video #%ld", pMenu->GetMenuItemCount() + 1); pMenu->AppendCheckItem(ID_SELSTREAM_0 +i, wxString(szLabel, wxConvUTF8)); break; case GF_STREAM_TEXT: nb_subs ++; pMenu = sel_menu->FindItemByPosition(2)->GetSubMenu(); - if (!info.owns_service) sprintf(szLabel, "Subtitle #%d", pMenu->GetMenuItemCount() + 1); + if (!info.owns_service) sprintf(szLabel, "Subtitle #%ld", pMenu->GetMenuItemCount() + 1); pMenu->AppendCheckItem(ID_SELSTREAM_0 +i, wxString(szLabel, wxConvUTF8)); break; } @@ -2289,7 +2307,7 @@ void wxOsmo4Frame::OnUpdateStreamSel(wxUpdateUIEvent & event) GF_ObjectManager *odm = gf_term_get_object(m_term, root_od, ID); if (!odm) return; - ODInfo info; + GF_MediaInfo info; gf_term_get_object_info(m_term, odm, &info); event.Enable(1); event.Check(info.status ? 1 : 0); @@ -2364,14 +2382,14 @@ void wxOsmo4Frame::OnUpdateCacheEnable(wxUpdateUIEvent & event) switch (state) { case GF_MEDIA_CACHE_ENABLED: event.Enable(1); - event.SetText(wxT("Enabled")); + event.SetText(wxT("Enabled")); break; - case GF_MEDIA_CACHE_RUNNING: - event.SetText(wxT("Running")); + case GF_MEDIA_CACHE_RUNNING: + event.SetText(wxT("Running")); event.Enable(0); break; - case GF_MEDIA_CACHE_DISABLED: - event.SetText(wxT("Disabled")); + case GF_MEDIA_CACHE_DISABLED: + event.SetText(wxT("Disabled")); break; } } @@ -2386,13 +2404,13 @@ void wxOsmo4Frame::OnUpdateCacheAbort(wxUpdateUIEvent & event) void wxOsmo4Frame::BuildChapterList(Bool reset_only) { - ODInfo odi; + GF_MediaInfo odi; while (chap_menu->GetMenuItemCount()) { wxMenuItem* it = chap_menu->FindItemByPosition(0); chap_menu->Delete(it); } - if (m_chapters_start) free(m_chapters_start); + if (m_chapters_start) gf_free(m_chapters_start); m_chapters_start = NULL; m_num_chapters = 0; if (reset_only) return; @@ -2415,7 +2433,7 @@ void wxOsmo4Frame::BuildChapterList(Bool reset_only) } chap_menu->AppendCheckItem(ID_SETCHAP_FIRST + m_num_chapters, wxString(szLabel, wxConvUTF8)); - m_chapters_start = (Double *) realloc(m_chapters_start, sizeof(Double)*(m_num_chapters+1)); + m_chapters_start = (Double *) gf_realloc(m_chapters_start, sizeof(Double)*(m_num_chapters+1)); m_chapters_start[m_num_chapters] = seg->startTime; m_num_chapters++; } @@ -2428,7 +2446,7 @@ void wxOsmo4Frame::BuildChapterList(Bool reset_only) if (com.artist) { title.Append(wxString(com.artist, wxConvUTF8)); title += wxT(" "); } if (com.name) { title.Append(wxString(com.name, wxConvUTF8)); title += wxT(" "); } if (com.album) { title += wxT("("); title.Append(wxString(com.album, wxConvUTF8)); title += wxT(")"); } - + if (title.length()) SetTitle(title); } diff --git a/applications/osmo4_wx/wxOsmo4.h b/applications/osmo4_wx/wxOsmo4.h index 68c35f2..6c2b463 100644 --- a/applications/osmo4_wx/wxOsmo4.h +++ b/applications/osmo4_wx/wxOsmo4.h @@ -10,17 +10,17 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * * - * */ #ifndef _WXOSMO4_H @@ -73,10 +73,11 @@ private: #define MAX_VIEWPOINTS 50 -enum { - // Menu commands - FILE_OPEN = wxID_HIGHEST+1, - FILE_OPEN_URL, +// Menu commands +enum +{ + GWX_FILE_OPEN = wxID_HIGHEST, + GWX_FILE_OPEN_URL, FILE_RELOAD, FILE_RELOAD_CONFIG, FILE_PLAY, @@ -235,10 +236,10 @@ public: GF_Terminal *m_term; GF_User m_user; Bool m_connected, m_can_seek, m_console_off, m_loop, m_lookforsubs; - + void DoConnect(); - void ConnectAcknowledged(Bool bOk); + void ConnectAcknowledged(Bool bOk); void SetStatus(wxString str); void OnFilePlay(wxCommandEvent &event); @@ -258,7 +259,7 @@ public: u32 m_last_grab_time, m_last_grab_pos; wxWindow *m_pVisual; #endif - wxSlider *m_pProg; + wxSlider *m_pProg; wxPlaylist *m_pPlayList; void DoLayout(u32 v_width = 0, u32 v_height = 0); @@ -364,7 +365,7 @@ private: wxMenuButton *m_pPrevBut, *m_pNextBut; wxToolBar *m_pToolBar; wxMyComboBox *m_Address; - + wxMenu *vp_list; wxMenu *sel_menu; wxMenu *chap_menu; @@ -385,5 +386,5 @@ private: }; -#endif +#endif //_WXOSMO4_H diff --git a/applications/osmo4_wx/wxOsmo4.rc b/applications/osmo4_wx/wxOsmo4.rc index e7d6408..3e839b8 100644 --- a/applications/osmo4_wx/wxOsmo4.rc +++ b/applications/osmo4_wx/wxOsmo4.rc @@ -27,18 +27,18 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH // TEXTINCLUDE // -1 TEXTINCLUDE DISCARDABLE +1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END -2 TEXTINCLUDE DISCARDABLE +2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END -3 TEXTINCLUDE DISCARDABLE +3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" @@ -54,7 +54,7 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_ICON1 ICON DISCARDABLE "osmo4.ico" +IDI_OSMO_ICON ICON DISCARDABLE "../../doc/osmo4.ico" #endif // French (France) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/applications/osmophone/main.cpp b/applications/osmophone/main.cpp index 04ac480..147d70d 100644 --- a/applications/osmophone/main.cpp +++ b/applications/osmophone/main.cpp @@ -6,7 +6,7 @@ * * This file is part of GPAC / command-line client * - * GPAC is free software; you can redistribute it and/or modify + * GPAC is gf_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. @@ -28,14 +28,27 @@ /*for initial setup*/ #include +#include +#include + #include #include #include -#include -#include "resource.h" +#ifdef _WIN32_WCE +#include #include +#else + +#ifndef _T +#define _T(__a) (LPCSTR) __a +#endif + +#endif + +#include "resource.h" + #define WM_LOADTERM WM_USER + 1 #define STATE_TIMER_ID 20 #define STATE_TIMER_DUR 1000 @@ -50,8 +63,7 @@ void do_layout(Bool notif_size); static HWND g_hwnd = NULL; static HWND g_hwnd_disp = NULL; -static HWND g_hwnd_menu1 = NULL; -static HWND g_hwnd_menu2 = NULL; +static HWND g_hwnd_menu = NULL; static HWND g_hwnd_status = NULL; static HINSTANCE g_hinst = NULL; static Bool is_ppc = 0; @@ -74,6 +86,7 @@ static u32 screen_w = 0; static u32 screen_h = 0; static u32 menu_h = 0; static u32 caption_h = 0; +static u32 ratio_h = 1; static Bool backlight_off = 0; static u32 prev_batt_bl, prev_ac_bl; static Bool show_status = 1; @@ -83,23 +96,44 @@ static Bool loop = 0; static Bool full_screen = 0; static Bool force_2d_gl = 0; static Bool ctrl_mod_down = 0; -static Bool view_cpu = 0; -static Bool menu_switched = 0; +static Bool view_cpu = 1; static Bool use_low_fps = 0; static Bool use_svg_prog = 0; static Bool log_rti = 0; -static FILE *rti_file = NULL; +static FILE *log_file = NULL; static u32 rti_update_time_ms = 200; static u32 playlist_act = 0; + +void recompute_res(u32 sw, u32 sh ) +{ + caption_h = GetSystemMetrics(SM_CYCAPTION); + menu_h = GetSystemMetrics(SM_CYMENU)+2; + screen_w = GetSystemMetrics(SM_CXSCREEN); + screen_h = GetSystemMetrics(SM_CYSCREEN); + + ratio_h = sh / screen_h; + screen_w = sw; + screen_h = sh; + menu_h *= ratio_h; +// caption_h *= ratio_h; + disp_w = screen_w; + disp_h = screen_h - menu_h /*- caption_h*/; +} + + void set_status(char *state) { if (show_status && g_hwnd_status) { +#ifdef _WIN32_WCE TCHAR wstate[1024]; CE_CharToWide(state, (u16 *) wstate); SendMessage(g_hwnd_status, WM_SETTEXT, 0, (LPARAM) wstate); +#else + SendMessage(g_hwnd_status, WM_SETTEXT, 0, (LPARAM) state); +#endif last_state_time = GetTickCount(); } } @@ -111,7 +145,7 @@ void update_state_info() u32 time, m, s; if (!show_status) return; if (last_state_time) { - if (GetTickCount() > last_state_time + 1000) { + if (GetTickCount() > last_state_time + 200) { last_state_time = 0; reset_status = 1; } @@ -139,8 +173,8 @@ void update_state_info() } -static u32 prev_pos = 0; -void cbk_on_progress(void *_title, u32 done, u32 total) +static u64 prev_pos = 0; +void cbk_on_progress(void *_title, u64 done, u64 total) { #if 0 char szMsg[1024]; @@ -158,9 +192,12 @@ void set_full_screen() { full_screen = !full_screen; if (full_screen) { + show_status = 0; do_layout(0); gf_term_set_option(term, GF_OPT_FULLSCREEN, full_screen); } else { + const char *str = gf_cfg_get_key(user.config, "General", "ShowStatusBar"); + show_status = (str && !strcmp(str, "yes")) ? 1 : 0; gf_term_set_option(term, GF_OPT_FULLSCREEN, full_screen); do_layout(1); } @@ -169,45 +206,50 @@ void set_full_screen() static void on_gpac_rti_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list) { - GF_SystemRTInfo rti; - - if (lm != GF_LOG_RTI) return; + if (!log_file) return; - gf_sys_get_rti(rti_update_time_ms, &rti, 0); + if (lm & GF_LOG_RTI) { + GF_SystemRTInfo rti; + if (fmt) vfprintf(log_file, fmt, list); + + gf_sys_get_rti(rti_update_time_ms, &rti, 0); - fprintf(rti_file, "% 8d\t% 8d\t% 8d\t% 4d\t% 8d\t\t", - gf_sys_clock(), - gf_term_get_time_in_ms(term), - rti.total_cpu_usage, - (u32) gf_term_get_framerate(term, 0), - (u32) ( rti.gpac_memory / 1024) - ); - if (fmt) vfprintf(rti_file, fmt+6 /*[RTI] "*/, list); + fprintf(log_file, "% 8d\t% 8d\t% 8d\t% 4d\t% 8d\t\t", + gf_sys_clock(), + gf_term_get_time_in_ms(term), + rti.total_cpu_usage, + (u32) gf_term_get_framerate(term, 0), + (u32) ( rti.gpac_memory / 1024) + ); + } else if (fmt && (ll>=GF_LOG_INFO)) { + vfprintf(log_file, fmt, list); + } } - static void on_gpac_log(void *cbk, u32 ll, u32 lm, const char *fmt, va_list list) { - if (rti_file && fmt) vfprintf(rti_file, fmt, list); + if (fmt && log_file) vfprintf(log_file, fmt, list); } + static void setup_logs() { - if (rti_file) fclose(rti_file); - rti_file = NULL; + if (log_file) fclose(log_file); + log_file = NULL; gf_log_set_level(GF_LOG_ERROR); gf_log_set_tools(0); gf_log_set_callback(NULL, NULL); if (log_rti) { - rti_file = fopen("\\gpac_rti.txt", "a+t"); + log_file = gf_f64_open("\\gpac_logs.txt", "a+t"); - fprintf(rti_file, "!! GPAC RunTime Info for file %s !!\n", the_url); - fprintf(rti_file, "SysTime(ms)\tSceneTime(ms)\tCPU\tFPS\tMemory(kB)\tObservation\n"); + fprintf(log_file, "!! GPAC RunTime Info for file %s !!\n", the_url); + fprintf(log_file, "SysTime(ms)\tSceneTime(ms)\tCPU\tFPS\tMemory(kB)\tObservation\n"); gf_log_set_level(GF_LOG_DEBUG); - gf_log_set_tools(GF_LOG_RTI); - gf_log_set_callback(rti_file, on_gpac_rti_log); + gf_log_set_tools(GF_LOG_RTI|GF_LOG_SCRIPT); + gf_log_set_callback(log_file, on_gpac_rti_log); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI] System state when enabling log\n")); } else { u32 lt, ll; @@ -228,7 +270,7 @@ static void setup_logs() while (val) { sep = strchr(val, ':'); if (sep) sep[0] = 0; - if (!stricmp(val, "core")) lt |= GF_LOG_CODING; + if (!stricmp(val, "core")) lt |= GF_LOG_CORE; else if (!stricmp(val, "coding")) lt |= GF_LOG_CODING; else if (!stricmp(val, "container")) lt |= GF_LOG_CONTAINER; else if (!stricmp(val, "network")) lt |= GF_LOG_NETWORK; @@ -243,6 +285,7 @@ static void setup_logs() else if (!stricmp(val, "interact")) lt |= GF_LOG_INTERACT; else if (!stricmp(val, "compose")) lt |= GF_LOG_COMPOSE; else if (!stricmp(val, "mmio")) lt |= GF_LOG_MMIO; + else if (!stricmp(val, "rti")) lt |= GF_LOG_RTI; else if (!stricmp(val, "none")) ll = 0; else if (!stricmp(val, "all")) lt = 0xFFFFFFFF; if (!sep) break; @@ -251,8 +294,8 @@ static void setup_logs() } gf_log_set_tools(lt); } - if (ll && (rti_file = fopen("\\gpac_logs.txt", "wt"))) { - gf_log_set_callback(rti_file, on_gpac_log); + if (ll && (log_file = gf_f64_open("\\gpac_logs.txt", "a+t"))) { + gf_log_set_callback(log_file, on_gpac_log); } } @@ -311,7 +354,10 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) case GF_EVENT_MESSAGE: { if (!evt->message.message) return 0; - set_status((char *) evt->message.message); + if (evt->message.error==GF_SCRIPT_INFO) { + GF_LOG(GF_LOG_INFO, GF_LOG_SCRIPT, ("[Script] %s\n", evt->message.message)); + } + //set_status((char *) evt->message.message); } break; case GF_EVENT_PROGRESS: @@ -326,9 +372,17 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) case GF_EVENT_SIZE: break; + case GF_EVENT_RESOLUTION: + recompute_res(evt->size.width, evt->size.height); + do_layout(1); + break; + case GF_EVENT_SCENE_SIZE: do_layout(1); break; + case GF_EVENT_DBLCLICK: + set_full_screen(); + return 0; case GF_EVENT_CONNECT: if (evt->connect.is_connected) { is_connected = 1; @@ -341,7 +395,12 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) Duration = 0; } break; + case GF_EVENT_EOS: + if (Duration>2000) + gf_term_play_from_time(term, 0, 0); + break; case GF_EVENT_QUIT: + PostMessage(g_hwnd, WM_DESTROY, 0, 0); break; case GF_EVENT_KEYDOWN: switch (evt->key.key_code) { @@ -367,7 +426,9 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) gf_term_navigate_to(term, evt->navigate.to_url); return 1; } else { +#ifdef _WIN32_WCE u16 dst[1024]; +#endif SHELLEXECUTEINFO info; /* @@ -376,11 +437,15 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) */ memset(&info, 0, sizeof(SHELLEXECUTEINFO)); info.cbSize = sizeof(SHELLEXECUTEINFO); - info.lpVerb = L"open"; + info.lpVerb = _T("open"); info.fMask = SEE_MASK_NOCLOSEPROCESS; - info.lpFile = L"iexplore"; + info.lpFile = _T("iexplore"); +#ifdef _WIN32_WCE CE_CharToWide((char *) evt->navigate.to_url, dst); info.lpParameters = (LPCTSTR) dst; +#else + info.lpParameters = evt->navigate.to_url; +#endif info.nShow = SW_SHOWNORMAL; ShellExecuteEx(&info); } @@ -389,7 +454,7 @@ Bool GPAC_EventProc(void *ptr, GF_Event *evt) return 0; } -#define TERM_NOT_THREADED +//#define TERM_NOT_THREADED Bool LoadTerminal() { @@ -405,7 +470,7 @@ Bool LoadTerminal() user.opaque = user.modules; user.os_window_handler = g_hwnd_disp; #ifdef TERM_NOT_THREADED - user.init_flags = GF_TERM_NO_VISUAL_THREAD | GF_TERM_NO_REGULATION; + user.init_flags = GF_TERM_NO_THREAD | GF_TERM_NO_REGULATION; #endif term = gf_term_new(&user); @@ -416,6 +481,13 @@ Bool LoadTerminal() return 0; } +#ifdef _WIN32_WCE + screen_w = term->compositor->video_out->max_screen_width; + screen_h = term->compositor->video_out->max_screen_height; + disp_w = screen_w; + disp_h = screen_h - menu_h /*- caption_h*/; +#endif + #ifdef TERM_NOT_THREADED ::SetTimer(g_hwnd, GPAC_TIMER_ID, GPAC_TIMER_DUR, NULL); #endif @@ -436,26 +508,31 @@ void do_layout(Bool notif_size) w = screen_w; h = screen_h; ::ShowWindow(g_hwnd_status, SW_HIDE); - ::ShowWindow(g_hwnd_menu1, SW_HIDE); - ::ShowWindow(g_hwnd_menu2, SW_HIDE); +#ifdef _WIN32_WCE + ::ShowWindow(g_hwnd_menu, SW_HIDE); +#endif +#ifdef _WIN32_WCE SHFullScreen(g_hwnd, SHFS_HIDESIPBUTTON); +#endif ::MoveWindow(g_hwnd, 0, 0, screen_w, screen_h, 1); ::MoveWindow(g_hwnd_disp, 0, 0, screen_w, screen_h, 1); SetForegroundWindow(g_hwnd_disp); } else { - ::ShowWindow(g_hwnd_menu1, menu_switched ? SW_HIDE : SW_SHOW); - ::ShowWindow(g_hwnd_menu2, menu_switched ? SW_SHOW : SW_HIDE); +#ifdef _WIN32_WCE + ::ShowWindow(g_hwnd_menu, SW_SHOW); +#endif if (show_status) { ::MoveWindow(g_hwnd, 0, 0, disp_w, disp_h, 1); ::ShowWindow(g_hwnd_status, SW_SHOW); ::MoveWindow(g_hwnd_status, 0, 0, disp_w, caption_h, 1); ::MoveWindow(g_hwnd_disp, 0, caption_h, disp_w, disp_h - caption_h, 1); w = disp_w; - h = disp_h - caption_h; + h = disp_h - caption_h*ratio_h; } else { ::ShowWindow(g_hwnd_status, SW_HIDE); - ::MoveWindow(g_hwnd, 0, caption_h, disp_w, disp_h, 1); +// ::MoveWindow(g_hwnd, 0, caption_h, disp_w, disp_h, 1); + ::MoveWindow(g_hwnd, 0, 0, disp_w, disp_h, 1); ::MoveWindow(g_hwnd_disp, 0, 0, disp_w, disp_h, 1); w = disp_w; h = disp_h; @@ -467,12 +544,11 @@ void do_layout(Bool notif_size) void set_backlight_state(Bool disable) { +#ifdef _WIN32_WCE HKEY hKey = 0; DWORD dwSize; DWORD dwValue; HANDLE hBL; - - if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("ControlPanel\\Backlight"), 0, 0, &hKey ) != ERROR_SUCCESS) return; if (disable) { @@ -504,20 +580,21 @@ void set_backlight_state(Bool disable) SetEvent(hBL); CloseHandle(hBL); } +#endif } static Bool do_resume = 0; static Bool prev_backlight_state; -void freeze_display(Bool do_freeze) +void gf_freeze_display(Bool do_gf_freeze) { - if (do_freeze) { + if (do_gf_freeze) { prev_backlight_state = backlight_off; do_resume = 0; if (0 && is_connected && gf_term_get_option(term, GF_OPT_PLAY_STATE)==GF_STATE_PLAYING) { do_resume= 1; gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); } - /*freeze display*/ + /*gf_freeze display*/ gf_term_set_option(term, GF_OPT_FREEZE_DISPLAY, 1); set_backlight_state(0); @@ -535,6 +612,7 @@ void freeze_display(Bool do_freeze) static void show_taskbar(Bool show_it) { +#ifdef _WIN32_WCE HWND wnd; if (!is_ppc) return; @@ -547,13 +625,15 @@ static void show_taskbar(Bool show_it) ::ShowWindow(::FindWindow(_T("HHTaskbar"),NULL), SW_HIDE); SHFullScreen(wnd, SHFS_HIDESTARTICON | SHFS_HIDETASKBAR| SHFS_HIDESIPBUTTON); } +#endif } void refresh_recent_files() { +#ifdef _WIN32_WCE u32 count = gf_cfg_get_key_count(user.config, "RecentFiles"); - HMENU hMenu = (HMENU)SendMessage(g_hwnd_menu1, SHCMBM_GETSUBMENU, 0, ID_MENU_FILE); + HMENU hMenu = (HMENU)SendMessage(g_hwnd_menu, SHCMBM_GETSUBMENU, 0, ID_MENU_FILE); /*pos is hardcoded*/ hMenu = GetSubMenu(hMenu, 2); @@ -571,6 +651,7 @@ void refresh_recent_files() CE_CharToWide(name, (u16 *) txt); AppendMenu(hMenu, MF_STRING, IDM_OPEN_FILE1+i, txt); } +#endif } @@ -580,7 +661,7 @@ void open_file(HWND hwnd) char ext_list[4096]; strcpy(ext_list, ""); - freeze_display(1); + gf_freeze_display(1); u32 count = gf_cfg_get_key_count(user.config, "MimeTypes"); for (u32 i=0; i + +#ifdef _WIN32_WCE + #include #include @@ -397,3 +400,6 @@ Bool gf_file_dialog(HINSTANCE inst, HWND parent, char *url, const char *ext_list return 0; } + +#endif + diff --git a/applications/osmophone/osmophone.rc b/applications/osmophone/osmophone.rc index 47272df..4a0b80e 100644 --- a/applications/osmophone/osmophone.rc +++ b/applications/osmophone/osmophone.rc @@ -1,4 +1,4 @@ -//Microsoft eMbedded Visual C++ generated resource script. +// Microsoft Visual C++ generated resource script. // #include "resource.h" @@ -13,7 +13,7 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources +// Anglais (États-Unis) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 @@ -28,7 +28,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_ICON ICON DISCARDABLE "Osmo4.ico" +IDI_ICON ICON "../../doc/osmo4.ico" #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -36,18 +36,18 @@ IDI_ICON ICON DISCARDABLE "Osmo4.ico" // TEXTINCLUDE // -1 TEXTINCLUDE DISCARDABLE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE DISCARDABLE +2 TEXTINCLUDE BEGIN "#include ""newres.h""\r\n" "\0" END -3 TEXTINCLUDE DISCARDABLE +3 TEXTINCLUDE BEGIN "\r\n" "\0" @@ -58,41 +58,34 @@ END ///////////////////////////////////////////////////////////////////////////// // -// Data +// RCDATA // -IDM_MAIN_MENU1 SHMENUBAR DISCARDABLE +IDM_MAIN_MENU1 RCDATA BEGIN - IDM_MAIN_MENU1, 2, - I_IMAGENONE, ID_MENU_FILE, TBSTATE_ENABLED, - TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_FILE, 0, 0, - I_IMAGENONE, IDM_MENU_VIEW, TBSTATE_ENABLED, - TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_VIEW, 0, 1, + 0x0066, 0x0002, 0xfffe, 0x9c53, 0x0004, 0x0018, 0x9c55, 0x0000, 0x0000, + 0xfffe, 0x9c58, 0x0004, 0x0018, 0x9c59, 0x0000, 0x0001 END -IDR_ABOUT_MENU SHMENUBAR DISCARDABLE +IDR_ABOUT_MENU RCDATA BEGIN - IDR_ABOUT_MENU, 1, - I_IMAGENONE, IDM_ABOUT_OK, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE, IDS_CAP_OK, - 0, NOMENU, + 0x006b, 0x0001, 0xfffe, 0x9c77, 0x0004, 0x0010, 0x9c6c, 0x0000, 0xffff + END -IDM_MAIN_MENU2 SHMENUBAR DISCARDABLE +IDM_MAIN_MENU2 RCDATA BEGIN - IDM_MAIN_MENU2, 2, - I_IMAGENONE, ID_OPTION, TBSTATE_ENABLED, - TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_OPTION, 0, 0, - I_IMAGENONE, ID_MENUITEM40071, TBSTATE_ENABLED, - TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_MENUITEM40072, 0, 1, + 0x006c, 0x0002, 0xfffe, 0x9c83, 0x0004, 0x0018, 0x9c85, 0x0000, 0x0000, + 0xfffe, 0x9c87, 0x0004, 0x0018, 0x9c89, 0x0000, 0x0001 END ///////////////////////////////////////////////////////////////////////////// // -// Menubar +// Menu // -IDM_MAIN_MENU1 MENU DISCARDABLE +IDM_MAIN_MENU MENU BEGIN POPUP "File" BEGIN @@ -114,6 +107,41 @@ BEGIN MENUITEM "Pause", IDM_FILE_PAUSE MENUITEM "Copy/Paste", ID_FILE_CUT_PASTE MENUITEM SEPARATOR + POPUP "Logs" + BEGIN + POPUP "Level" + BEGIN + MENUITEM "None", ID_LOGLEVEL_NONE + MENUITEM "Error", ID_LOGLEVEL_ERROR + MENUITEM "Warning", ID_LOGLEVEL_WARNING + MENUITEM "Info", ID_LOGLEVEL_INFO + MENUITEM "Debug", ID_LOGLEVEL_DEBUG + END + POPUP "Tools" + BEGIN + MENUITEM "core", ID_TOOLS_CORE + MENUITEM "coding", ID_TOOLS_CODING + MENUITEM "container", ID_TOOLS_CONTAINER + MENUITEM "network", ID_TOOLS_NETWORK + MENUITEM "rtp", ID_TOOLS_RTP + MENUITEM "sync", ID_TOOLS_SYNC + MENUITEM "codec", ID_TOOLS_CODEC + MENUITEM "parser", ID_TOOLS_PARSER + MENUITEM "media", ID_TOOLS_MEDIA + MENUITEM "scene", ID_TOOLS_SCENE + MENUITEM "script", ID_TOOLS_SCRIPT + MENUITEM "interact", ID_TOOLS_INTERACT + MENUITEM "compose", ID_TOOLS_COMPOSE + MENUITEM "mmio", ID_TOOLS_MMIO + MENUITEM "rti", ID_TOOLS_RTI + MENUITEM SEPARATOR + MENUITEM "none", ID_TOOLS_NONE + MENUITEM "all", ID_TOOLS_ALL + END + MENUITEM "Reset", ID_LOGS_RESET + MENUITEM "Log CPU", IDM_FILE_LOG_RTI + END + MENUITEM SEPARATOR MENUITEM "Exit", IDM_ITEM_QUIT END POPUP "View" @@ -139,60 +167,57 @@ BEGIN END MENUITEM SEPARATOR MENUITEM "Fullscreen", IDM_VIEW_FS - POPUP "Aspect Ratio" + POPUP "Info" BEGIN - MENUITEM "Keep Original", IDM_VIEW_AR_NONE - MENUITEM "Fill Screen", IDM_VIEW_AR_FILL - MENUITEM "Ratio 4/3", IDM_VIEW_AR_4_3 - MENUITEM "Ratio 16/9", IDM_VIEW_AR_16_9 + MENUITEM "Status Bar", IDM_VIEW_STATUS + MENUITEM "CPU usage", IDM_VIEW_CPU END MENUITEM SEPARATOR - MENUITEM "Options", IDM_MENU_SWITCH + POPUP "Video" + BEGIN + MENUITEM "Direct FB", ID_VIDEO_DIRECTFB + MENUITEM "GAPI", ID_VIDEO_GAPI + MENUITEM "GDI", ID_VIDEO_GDI + MENUITEM SEPARATOR + MENUITEM "2D OpenGL", IDM_VIEW_FORCEGL + MENUITEM "Direct Draw", ID_VIDEO_DIRECTDRAW + MENUITEM "15.0 FPS", IDM_VIEW_LOW_RATE + POPUP "Aspect Ratio" + BEGIN + MENUITEM "Keep Original", IDM_VIEW_AR_NONE + MENUITEM "Fill Screen", IDM_VIEW_AR_FILL + MENUITEM "Ratio 4/3", IDM_VIEW_AR_4_3 + MENUITEM "Ratio 16/9", IDM_VIEW_AR_16_9 + END + END + POPUP "Options" + BEGIN + MENUITEM "Progressive SVG ", IDM_VIEW_SVG_LOAD + MENUITEM "Disable Playlist", IDS_CAP_DISABLE_PLAYLIST + END + MENUITEM "About", IDM_VIEW_ABOUT END END -IDR_ABOUT_MENU MENU DISCARDABLE +IDR_ABOUT_MENU MENU BEGIN MENUITEM "OK", IDM_ABOUT_OK END -IDM_MAIN_MENU2 MENU DISCARDABLE -BEGIN - POPUP "Options" - BEGIN - MENUITEM "15.0 FPS", IDM_VIEW_LOW_RATE - MENUITEM "Direct Draw", IDM_VIEW_DIRECT - MENUITEM SEPARATOR - MENUITEM "Status Bar", IDM_VIEW_STATUS - MENUITEM "CPU usage", IDM_VIEW_CPU - MENUITEM "Log RTI", IDM_FILE_LOG_RTI - MENUITEM SEPARATOR - MENUITEM "Close", IDM_MENU_SWITCH - END - POPUP "?" - BEGIN - MENUITEM "2D OpenGL", IDM_VIEW_FORCEGL - MENUITEM "Progressive SVG ", IDM_VIEW_SVG_LOAD - MENUITEM SEPARATOR - MENUITEM "Disable Playlist", IDS_CAP_DISABLE_PLAYLIST - MENUITEM "About", IDM_VIEW_ABOUT - END -END - ///////////////////////////////////////////////////////////////////////////// // // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CLASSNAME "Osmophone" IDS_WINDOWNAME "Osmo4" IDS_APPNAME "Osmophone.exe" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CAP_QUIT "Exit" IDS_CAP_FILE "File" @@ -200,33 +225,33 @@ BEGIN IDS_CAP_VIEW "View" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CAP_OK "OK" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CAP_NAVIGATE "Navigate" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CAP_OPTION "Options" IDS_CAP_MENUITEM40072 "?" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CAP_DISABLE_PLAYLIST "Copy/Paste" END -#endif // English (U.S.) resources +#endif // Anglais (États-Unis) resources ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// -// French (France) resources +// Français (France) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) #ifdef _WIN32 @@ -236,25 +261,22 @@ LANGUAGE LANG_FRENCH, SUBLANG_FRENCH ///////////////////////////////////////////////////////////////////////////// // -// Data +// RCDATA // -IDR_MENU_OPEN SHMENUBAR DISCARDABLE +IDR_MENU_OPEN RCDATA BEGIN - IDR_MENU_OPEN, 2, - I_IMAGENONE, IDM_OF_PL_ACT, TBSTATE_ENABLED, TBSTYLE_AUTOSIZE, - IDS_CAP_ADD, 0, NOMENU, - I_IMAGENONE, ID_OF_VIEW, TBSTATE_ENABLED, - TBSTYLE_DROPDOWN | TBSTYLE_AUTOSIZE, IDS_CAP_VIEW, 0, 1, + 0x006a, 0x0002, 0xfffe, 0x9c9b, 0x0004, 0x0010, 0x9c9f, 0x0000, 0xffff, + 0xfffe, 0x9c9a, 0x0004, 0x0018, 0x9c59, 0x0000, 0x0001 END ///////////////////////////////////////////////////////////////////////////// // -// Menubar +// Menu // -IDR_MENU_OPEN MENU DISCARDABLE +IDR_MENU_OPEN MENU BEGIN MENUITEM "Add", IDM_OF_PL_ACT POPUP "View" @@ -275,13 +297,13 @@ END // #ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO DISCARDABLE +GUIDELINES DESIGNINFO BEGIN IDD_APPABOUT, DIALOG BEGIN LEFTMARGIN, 1 - RIGHTMARGIN, 93 - BOTTOMMARGIN, 71 + RIGHTMARGIN, 113 + BOTTOMMARGIN, 74 END IDD_FILEDIALOG, DIALOG @@ -298,30 +320,26 @@ END // Dialog // -IDD_APPABOUT DIALOG DISCARDABLE 0, 0, 94, 74 -STYLE DS_SETFOREGROUND | WS_POPUP | WS_CAPTION +IDD_APPABOUT DIALOG 0, 0, 114, 77 +STYLE DS_SETFONT | DS_SETFOREGROUND | WS_POPUP | WS_CAPTION CAPTION "About Osmophone" FONT 8, "System" BEGIN - ICON IDI_ICON,IDC_STATIC,6,4,20,20 - LTEXT "Osmo4/GPAC\n""0.4.5"" (build ""33"")",IDC_STATIC,33, - 6,46,17 - CTEXT "Copyright (c) 2007 ENST\nAll Rights Reserved\n\nLicensed under LGPL", - IDC_STATIC,2,28,87,39 + ICON IDI_ICON,IDC_STATIC,1,0,16,16 + CTEXT "Osmo4/GPAC\n""0.4.5"" (build ""33"")",IDC_NAMECTRL,23,1,65,17 + CTEXT "Copyright (c) 2007 ENST\nAll Rights Reserved\nLicensed under LGPL",IDC_STATIC,2,44,111,33 END -IDD_FILEDIALOG DIALOG DISCARDABLE 0, 0, 104, 86 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +IDD_FILEDIALOG DIALOG 0, 0, 104, 86 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Select File" FONT 8, "System" BEGIN EDITTEXT IDC_DIRNAME,1,3,100,12,ES_AUTOHSCROLL | ES_READONLY - LISTBOX IDC_FILELIST,1,18,102,65,LBS_NOINTEGRALHEIGHT | - WS_VSCROLL | WS_TABSTOP + LISTBOX IDC_FILELIST,1,18,102,65,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP END -#ifndef _MAC ///////////////////////////////////////////////////////////////////////////// // // Version @@ -344,18 +362,14 @@ BEGIN BEGIN BLOCK "040c04b0" BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "ENST\0" - VALUE "FileDescription", "osmophone\0" - VALUE "FileVersion", "1, 0, 0, 1\0" - VALUE "InternalName", "osmophone\0" - VALUE "LegalCopyright", "Copyright © 2008\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "osmophone.exe\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "ENST GPAC\0" - VALUE "ProductVersion", "1, 0, 0, 1\0" - VALUE "SpecialBuild", "\0" + VALUE "CompanyName", "ENST" + VALUE "FileDescription", "osmophone" + VALUE "FileVersion", "1, 0, 0, 1" + VALUE "InternalName", "osmophone" + VALUE "LegalCopyright", "Copyright © 2008" + VALUE "OriginalFilename", "osmophone.exe" + VALUE "ProductName", "ENST GPAC" + VALUE "ProductVersion", "1, 0, 0, 1" END END BLOCK "VarFileInfo" @@ -364,37 +378,35 @@ BEGIN END END -#endif // !_MAC - ///////////////////////////////////////////////////////////////////////////// // // String Table // -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CAP_FILE "+" IDS_CAP_VIEW "View" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CAP_OK "OK" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CAP_SELECT "File" END -STRINGTABLE DISCARDABLE +STRINGTABLE BEGIN IDS_CAP_MENUITEM40092 "Add" IDS_CAP_ADD "Add" END -#endif // French (France) resources +#endif // Français (France) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/applications/osmophone/resource.h b/applications/osmophone/resource.h index 9744529..1b76c23 100644 --- a/applications/osmophone/resource.h +++ b/applications/osmophone/resource.h @@ -1,5 +1,5 @@ //{{NO_DEPENDENCIES}} -// Microsoft eMbedded Visual C++ generated include file. +// Microsoft Visual C++ generated include file. // Used by osmophone.rc // #define IDS_CLASSNAME 1 @@ -25,6 +25,7 @@ #define IDC_LIST1 1002 #define IDC_FILELIST 1002 #define IDC_LIST2 1003 +#define IDC_NAMECTRL 1004 #define IDM_FILE_EXIT 40002 #define IDM_HELP_ABOUT 40003 #define IDM_GRAB 40004 @@ -106,18 +107,63 @@ #define IDM_VIEW_CPU 40098 #define IDM_FILE_PAUSE 40099 #define IDM_VIEW_LOW_RATE 40100 -#define IDM_VIEW_DIRECT 40101 #define IDM_VIEW_SVG_LOAD 40102 #define IDS_CAP_DISABLE_PLAYLIST 40103 #define ID_FILE_CUT_PASTE 40104 +#define Fra 40105 +#define ID_VIDEO_DIRECTFB 40106 +#define ID_VIDEO_GAPI 40107 +#define ID_VIDEO_GDI 40108 +#define ID_VIDEO_DIRECTDRAW 40109 +#define ID_OPTIONS_TEST 40111 +#define ID_VIEW_INFO 40112 +#define ID_Menu 40113 +#define ID_OPTIONS_TEST40114 40114 +#define ID_OPTIONS_VIDEOOUT 40115 +#define ID_VIDEOOUT_FD 40116 +#define ID_OPTIONS_VIDEOOUT40117 40117 +#define ID_FILE_LOGS 40118 +#define ID_FILE_DS 40119 +#define ID_LOGS_ENABLED 40120 +#define ID_LOGS_LEVEL 40121 +#define ID_LEVEL_DEBUG 40122 +#define ID_LEVEL_WARNING 40123 +#define ID_LEVEL_INFO 40124 +#define ID_LEVEL_DEBUG40125 40125 +#define ID_LOGLEVEL_ERROR 40126 +#define ID_LOGLEVEL_WARNING 40127 +#define ID_LOGLEVEL_INFO 40128 +#define ID_LOGLEVEL_DEBUG 40129 +#define ID_LOGS_TOOLS 40130 +#define ID_LOGTOOL_CORE 40131 +#define ID_TOOLS_CODING 40132 +#define ID_TOOLS_CONTAINER 40133 +#define ID_TOOLS_NETWORK 40134 +#define ID_TOOLS_RTP 40135 +#define ID_TOOLS_SYNC 40136 +#define ID_TOOLS_CODEC 40137 +#define ID_TOOLS_PARSER 40138 +#define ID_TOOLS_MEDIA 40139 +#define ID_TOOLS_SCENE 40140 +#define ID_TOOLS_SCRIPT 40141 +#define ID_TOOLS_INTERACT 40142 +#define ID_TOOLS_COMPOSE 40143 +#define ID_TOOLS_MMIO 40144 +#define ID_TOOLS_RTI 40145 +#define ID_TOOLS_NONE 40146 +#define ID_TOOLS_ALL 40147 +#define ID_TOOLS_CORE 40148 +#define ID_LEVEL_NONE 40149 +#define ID_LOGLEVEL_NONE 40150 +#define ID_LOGS_RESET 40151 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 111 -#define _APS_NEXT_COMMAND_VALUE 40105 -#define _APS_NEXT_CONTROL_VALUE 1004 +#define _APS_NEXT_COMMAND_VALUE 40152 +#define _APS_NEXT_CONTROL_VALUE 1005 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/applications/osmozilla/osmozilla.cpp b/applications/osmozilla/osmozilla.cpp index 0046378..1eb47f8 100644 --- a/applications/osmozilla/osmozilla.cpp +++ b/applications/osmozilla/osmozilla.cpp @@ -40,10 +40,14 @@ #include #include #include - +#ifdef WIN32 +#include +#include +#endif #include "osmozilla.h" #include +#include nsIServiceManager *gServiceManager = NULL; @@ -93,7 +97,7 @@ nsIServiceManager *gServiceManager = NULL; char* NPP_GetMIMEDescription(void) { - return GPAC_PLUGIN_MIMETYPES; + return (char *) GPAC_PLUGIN_MIMETYPES; } ///////////////////////////////////// @@ -130,10 +134,10 @@ NPError NS_PluginGetValue(NPPVariable aVariable, void *aValue) NPError err = NPERR_NO_ERROR; switch (aVariable) { case NPPVpluginNameString: - *((char **)aValue) = "Osmozilla"; + *((char **)aValue) = (char *) "Osmozilla"; break; case NPPVpluginDescriptionString: - *((char **)aValue) = "GPAC Plugin " GPAC_FULL_VERSION " for Mozilla. For more information go to GPAC website"; + *((char **)aValue) = (char *) "GPAC Plugin " GPAC_FULL_VERSION " for Mozilla. For more information go to GPAC website"; break; default: err = NPERR_INVALID_PARAM; @@ -203,8 +207,8 @@ void nsOsmozillaInstance::SetOptions() m_bAutoStart = 0; else if (!stricmp(m_argn[i],"src") ) { - if (m_szURL) free(m_szURL); - m_szURL = strdup(m_argv[i]); + if (m_szURL) gf_free(m_szURL); + m_szURL = gf_strdup(m_argv[i]); } else if (!stricmp(m_argn[i],"use3d") && (!stricmp(m_argv[i], "true") || !stricmp(m_argv[i], "yes") ) ) { m_bUse3D = 1; @@ -227,19 +231,19 @@ void nsOsmozillaInstance::SetOptions() Bool absolute_url = 0; if (strstr(m_szURL, "://")) absolute_url = 1; else if (m_szURL[0] == '/') { - FILE *test = fopen(m_szURL, "rb"); + FILE *test = gf_f64_open(m_szURL, "rb"); if (test) { absolute_url = 1; fclose(test); } } - else if ((m_szURL[1] == ':') && (m_szURL[2] == '\\')) absolute_url = 1; + else if ((m_szURL[1] == ':') && ((m_szURL[2] == '\\') || (m_szURL[2] == '/'))) absolute_url = 1; if (!absolute_url) { char *url = m_szURL; m_szURL = NULL; NPN_GetURL(mInstance, url, NULL); - free(url); + gf_free(url); } } @@ -267,30 +271,53 @@ static void osmozilla_do_log(void *cbk, u32 level, u32 tool, const char *fmt, va NPBool nsOsmozillaInstance::init(NPWindow* aWindow) { - unsigned char config_path[GF_MAX_PATH]; + FILE *ft; + char config_path[GF_MAX_PATH], config_test_file[GF_MAX_PATH]; char *gpac_cfg; const char *str; if(aWindow == NULL) return FALSE; #ifdef XP_WIN - gpac_cfg = "GPAC.cfg"; -#ifdef _DEBUG -//#if 0 - strcpy((char *) config_path, "C:\\CVS\\gpac\\bin\\w32_deb"); -#else + gpac_cfg = (char *)"GPAC.cfg"; + HKEY hKey = NULL; DWORD dwSize; - RegOpenKeyEx(HKEY_CLASSES_ROOT, "GPAC", 0, KEY_READ, &hKey); + /*locate the key in current user, then in local machine*/ + if (RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\GPAC", 0, KEY_READ, &hKey) != ERROR_SUCCESS) + RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\GPAC", 0, KEY_READ, &hKey); dwSize = GF_MAX_PATH; - RegQueryValueEx(hKey, "InstallDir", NULL, NULL,(unsigned char*) config_path, &dwSize); - RegCloseKey(hKey); +#ifdef _DEBUG + if (RegQueryValueEx(hKey, "DebugDir", NULL, NULL,(unsigned char*) config_path, &dwSize) != ERROR_SUCCESS) #endif + RegQueryValueEx(hKey, "InstallDir", NULL, NULL,(unsigned char*) config_path, &dwSize); + RegCloseKey(hKey); + + /*do we have write access?*/ + strcpy(config_test_file, config_path); + if (config_path[strlen(config_path)-1] != '\\') + strcat(config_test_file, "\\"); + assert(strlen(config_path)+strlen(gpac_cfg)+1progress.done == evt->progress.total) { NPN_Status(mInstance, ""); } else { - char *szTitle = ""; - if (evt->progress.progress_type==0) szTitle = "Buffer "; - else if (evt->progress.progress_type==1) szTitle = "Download "; - else if (evt->progress.progress_type==2) szTitle = "Import "; + char *szTitle = (char *)""; + if (evt->progress.progress_type==0) szTitle = (char *)"Buffer "; + else if (evt->progress.progress_type==1) szTitle = (char *)"Download "; + else if (evt->progress.progress_type==2) szTitle = (char *)"Import "; sprintf(msg, "(GPAC) %s: %02.2f", szTitle, (100.0*evt->progress.done) / evt->progress.total); NPN_Status(mInstance, msg); } @@ -488,10 +515,10 @@ Bool nsOsmozillaInstance::EventProc(GF_Event *evt) case GF_KEY_HOME: gf_term_set_option(m_term, GF_OPT_NAVIGATION_TYPE, 1); break; - case GF_KEY_ESCAPE: +/* case GF_KEY_ESCAPE: gf_term_set_option(m_term, GF_OPT_FULLSCREEN, !gf_term_get_option(m_term, GF_OPT_FULLSCREEN)); break; - } +*/ } } break; case GF_EVENT_NAVIGATE_INFO: @@ -504,13 +531,13 @@ Bool nsOsmozillaInstance::EventProc(GF_Event *evt) return 1; } else { u32 i; - char *target = "_self"; + char *target = (char *)"_self"; for (i=0; inavigate.param_count; i++) { - if (!strcmp(evt->navigate.parameters[i], "_parent")) target = "_parent"; - else if (!strcmp(evt->navigate.parameters[i], "_blank")) target = "_blank"; - else if (!strcmp(evt->navigate.parameters[i], "_top")) target = "_top"; - else if (!strcmp(evt->navigate.parameters[i], "_new")) target = "_new"; + if (!strcmp(evt->navigate.parameters[i], "_parent")) target = (char *)"_parent"; + else if (!strcmp(evt->navigate.parameters[i], "_blank")) target = (char *)"_blank"; + else if (!strcmp(evt->navigate.parameters[i], "_top")) target = (char *)"_top"; + else if (!strcmp(evt->navigate.parameters[i], "_new")) target = (char *)"_new"; else if (!strnicmp(evt->navigate.parameters[i], "_target=", 8)) target = (char *) evt->navigate.parameters[i]+8; } NPN_GetURL(mInstance, evt->navigate.to_url, target); @@ -558,6 +585,7 @@ NPError nsOsmozillaInstance::SetWindow(NPWindow* aWindow) m_user.os_window_handler = aWindow->window; #endif +// m_user.init_flags = GF_TERM_DRAW_FRAME; m_prev_time = 0; m_url_changed = 0; @@ -566,7 +594,11 @@ NPError nsOsmozillaInstance::SetWindow(NPWindow* aWindow) gf_term_set_option(m_term, GF_OPT_ASPECT_RATIO, aspect_ratio); mInitialized = TRUE; - + +#ifdef XP_WIN + SetFocus((HWND)aWindow->window); +#endif + /*stream not ready*/ if (!m_szURL || !m_bAutoStart) return TRUE; @@ -580,8 +612,8 @@ NPError nsOsmozillaInstance::SetWindow(NPWindow* aWindow) NPError nsOsmozillaInstance::NewStream(NPMIMEType type, NPStream * stream, NPBool seekable, uint16 * stype) { - if (m_szURL) free(m_szURL); - m_szURL = strdup((const char *)stream->url); + if (m_szURL) gf_free(m_szURL); + m_szURL = gf_strdup((const char *)stream->url); /*connect from 0 and pause if not autoplay*/ if (m_bAutoStart) @@ -596,7 +628,7 @@ NPError nsOsmozillaInstance::DestroyStream(NPStream * stream, NPError reason) { if (0 && m_szURL) { gf_term_disconnect(m_term); - free(m_szURL); + gf_free(m_szURL); m_szURL = NULL; } return NPERR_NO_ERROR; @@ -695,7 +727,7 @@ void nsOsmozillaInstance::Print(NPPrint* printInfo) for (ysrc=0; ysrc void nsOsmozillaInstance::Update(const char *type, const char *commands) { if (m_term) { diff --git a/applications/standalone2drender/standalone2drender.c b/applications/standalone2drender/standalone2drender.c deleted file mode 100644 index e6870dd..0000000 --- a/applications/standalone2drender/standalone2drender.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * GPAC Multimedia Framework - * - * Authors: Cyril Concolato - * Copyright (c) 2005-200X ENST - * All rights reserved - * - * This file is part of GPAC / standalone 2D rendering lib (render2D + FT + RAW OUT + soft raster ) - * - * 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 "standalone2drender.h" -#include -#include -#include "render2d.h" -#include "stacks2d.h" -#include "visualsurface2d.h" -#include "ft_font.h" - -void SR_ResetFrameRate(GF_Compositor *); -GF_Raster2D *EVG_LoadRenderer(); -GF_VideoOutput *NewRawVideoOutput(); -GF_VisualRenderer *NewVisualRenderer(); -GF_Err R2D_GetSurfaceAccess(VisualSurface2D *surf); -void R2D_ReleaseSurfaceAccess(VisualSurface2D *surf); -Bool R2D_SupportsFormat(VisualSurface2D *surf, u32 pixel_format); -void R2D_DrawBitmap(VisualSurface2D *surf, struct _gf_sc_texture_handler *txh, GF_IRect *clip, GF_Rect *unclip, u8 alpha, u32 *col_key, GF_ColorMatrix *cmat); -GF_FontRaster *FT_Load(); -void FT_Delete(GF_FontRaster *); - -static GF_Err SA2DR_InitFontEngine(GF_FontRaster *dr) -{ - FTBuilder *ftpriv = (FTBuilder *)dr->priv; - - /*inits freetype*/ - if (FT_Init_FreeType(&ftpriv->library) ) return GF_IO_ERR; - - /*remove the final delimiter*/ -#if defined(WIN32) -#pragma message("using C:\\WINDOWS\\Fonts directory for fonts") - ftpriv->font_dir = strdup("C:\\WINDOWS\\Fonts"); -#else if defined(_WIN32_WCE) -#pragma message("using \\Windows directory for fonts") - ftpriv->font_dir = strdup("\\Windows"); -#endif - strcpy(ftpriv->font_serif,"Arial"); - strcpy(ftpriv->font_sans,"Times New Roman"); - strcpy(ftpriv->font_fixed,"Courier New"); - return GF_OK; -} - -static void SA2DR_SetFontEngine(GF_Compositor *sr) -{ - GF_FontRaster *ifce = FT_Load(); - - /*cannot init font engine*/ - if (SA2DR_InitFontEngine(ifce) != GF_OK) { - FT_Delete(ifce); - return; - } - sr->font_engine = ifce; -} - -static GF_Err SA2DR_LoadRenderer(GF_VisualRenderer *vr, GF_Compositor *compositor) -{ - Render2D *sr; - if (vr->user_priv) return GF_BAD_PARAM; - - sr = malloc(sizeof(Render2D)); - if (!sr) return GF_OUT_OF_MEM; - memset(sr, 0, sizeof(Render2D)); - - sr->compositor = compositor; - - sr->strike_bank = gf_list_new(); - sr->surfaces_2D = gf_list_new(); - - sr->top_effect = malloc(sizeof(RenderEffect2D)); - memset(sr->top_effect, 0, sizeof(RenderEffect2D)); - sr->top_effect->sensors = gf_list_new(); - sr->sensors = gf_list_new(); - - /*and create main surface*/ - sr->surface = NewVisualSurface2D(); - sr->surface->GetSurfaceAccess = R2D_GetSurfaceAccess; - sr->surface->ReleaseSurfaceAccess = R2D_ReleaseSurfaceAccess; - - sr->surface->DrawBitmap = R2D_DrawBitmap; - sr->surface->SupportsFormat = R2D_SupportsFormat; - sr->surface->render = sr; - gf_list_add(sr->surfaces_2D, sr->surface); - - sr->zoom = sr->scale_x = sr->scale_y = 1.0; - vr->user_priv = sr; - - /*load options*/ - //sr->top_effect->trav_flags |= TF_RENDER_DIRECT; - sr->scalable_zoom = 1; - sr->enable_yuv_hw = 0; - return GF_OK; -} - -GF_Compositor *SR_NewStandaloneRenderer() -{ - GF_Compositor *tmp; - GF_SAFEALLOC(tmp, GF_Compositor) - tmp->user, GF_User) - - tmp->visual_renderer = NewVisualRenderer(); - tmp->aspect_ratio = GF_ASPECT_RATIO_FILL_SCREEN; - - memset(&cfg, 0, sizeof(cfg)); - cfg.double_buffered = 1; - - tmp->video_out = NewRawVideoOutput(); - tmp->video_out->evt_cbk_hdl = tmp; - tmp->video_out->on_event = NULL; - - tmp->r2d = EVG_LoadRenderer(); - - /*and init*/ - if (SA2DR_LoadRenderer(tmp->visual_renderer, tmp) != GF_OK) { - tmp->video_out->Shutdown(tmp->video_out); - free(tmp); - return NULL; - } - - tmp->mx = gf_mx_new(""Renderer"); - tmp->textures = gf_list_new(); - tmp->frame_rate = 30.0; - tmp->frame_duration = 33; - tmp->time_nodes = gf_list_new(); - tmp->events = gf_list_new(); - tmp->ev_mx = gf_mx_new("Events"); - - SR_ResetFrameRate(tmp); - - /*set font engine if any*/ - SA2DR_SetFontEngine(tmp); - - tmp->extra_scenes = gf_list_new(); - tmp->interaction_level = GF_INTERACT_NORMAL | GF_INTERACT_INPUT_SENSOR; - tmp->antiAlias = GF_ANTIALIAS_FULL; - return tmp; -} - -void SR_DeleteStandaloneRenderer(GF_Compositor *tmp) -{ - tmp->visual_renderer->UnloadRenderer(tmp->visual_renderer); - free(tmp->visual_renderer); - DeleteVideoOutput(tmp->video_out); - EVG_ShutdownRenderer(tmp->r2d); - ft_shutdown_font_engine(tmp->font_engine); - FT_Delete(tmp->font_engine); - free(tmp->user); - free(tmp); -} - diff --git a/applications/standalone2drender/standalone2drender.h b/applications/standalone2drender/standalone2drender.h deleted file mode 100644 index a7c2b66..0000000 --- a/applications/standalone2drender/standalone2drender.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _STANDALONE2DRENDER_H -#define _STANDALONE2DRENDER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -GF_Compositor *SR_NewStandaloneRenderer(); - -#ifdef __cplusplus -} -#endif - -#endif //_STANDALONE2DRENDER_H \ No newline at end of file diff --git a/applications/testapps/beng_test/BifsEngineTester.dsp b/applications/testapps/beng_test/BifsEngineTester.dsp deleted file mode 100644 index 37329d7..0000000 --- a/applications/testapps/beng_test/BifsEngineTester.dsp +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="BifsEngineTester" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=BifsEngineTester - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "BifsEngineTester.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "BifsEngineTester.mak" CFG="BifsEngineTester - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "BifsEngineTester - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "BifsEngineTester - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "BifsEngineTester - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/BifsEngineTester.exe" - -!ELSEIF "$(CFG)" == "BifsEngineTester - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/BifsEngineTester.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "BifsEngineTester - Win32 Release" -# Name "BifsEngineTester - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\CmdLineTst.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/applications/testapps/beng_test/CmdLineTst.c b/applications/testapps/beng_test/CmdLineTst.c deleted file mode 100644 index bd94426..0000000 --- a/applications/testapps/beng_test/CmdLineTst.c +++ /dev/null @@ -1,89 +0,0 @@ -#include - -GF_Err SampleCallBack(void *calling_object, char *data, u32 size, u32 ts) -{ - fprintf(stdout, "Received at time %d, buffer %d bytes long.\n", ts, size); - return GF_OK; -} - -int main(int argc, char **argv) -{ - int i; - GF_BifsEngine *codec1 = NULL; - GF_BifsEngine * codec2 = NULL; - if (0) { - char *config; - u32 config_size; - char update[] = "\n AT \n 500 \n { \n REPLACE \n M.emissiveColor BY 1 0 0 } \n"; - - codec1 = gf_beng_init(NULL, argv[1]); - gf_beng_get_stream_config(codec1, &config, &config_size); - fprintf(stdout, "EncodedBifsConfig size is %d \n", config_size); - - gf_beng_encode_context(codec1, SampleCallBack); - gf_beng_save_context(codec1, "initial_context.mp4"); - gf_beng_encode_from_string(codec1, (char *) update, SampleCallBack); - gf_beng_save_context(codec1, "non_aggregated_context.mp4"); - gf_beng_aggregate_context(codec1); - gf_beng_save_context(codec1, "aggregated_context.mp4"); - gf_beng_terminate(codec1); - } else if (1) { - char *config; - u32 config_size; - char scene[] = "OrderedGroup {children [Background2D {backColor 1 1 1}Shape {appearance Appearance {material DEF M Material2D {emissiveColor 0 0 1 filled TRUE } } geometry Rectangle { size 100 75 } } ] }"; - char update[] = "\n AT \n 500 \n { \n REPLACE \n M.emissiveColor BY 1 0 0 \n REPLACE \n M.filled BY FALSE} \n"; - - codec1 = gf_beng_init_from_string(NULL, scene, 200, 200, 1); - gf_beng_get_stream_config(codec1, &config, &config_size); - fprintf(stdout, "EncodedBifsConfig size is %d \n", config_size); - - gf_beng_encode_context(codec1, SampleCallBack); - gf_beng_save_context(codec1, "initial_context.mp4"); - gf_beng_encode_from_string(codec1, (char *) update, SampleCallBack); - gf_beng_save_context(codec1, "non_aggregated_context.mp4"); - gf_beng_aggregate_context(codec1); - gf_beng_save_context(codec1, "aggregated_context.mp4"); - gf_beng_terminate(codec1); - } else { - - for (i = 0; i <10; i++) { - char context_rootname[] = "rect_context"; - char in_context[100], - bt_out_na_context[100], bt_out_agg_context[100], - mp4_out_na_context[100], mp4_out_agg_context[100]; - char update[1000];// = "REPLACE M.emissiveColor BY 1 1 0"; - char timed_update[1000]; - - sprintf(update, "REPLACE M.emissiveColor BY %f 0 0", i/10.0f); - - if (i != 0) { - sprintf(in_context, "na_%s_%i.bt", context_rootname, i); - } else { - strcpy(in_context, "rect.bt"); - } - - codec2 = gf_beng_init(NULL, in_context); - - sprintf(timed_update, "AT %i { %s }", 1000 + i, update); - - gf_beng_encode_from_string(codec2, timed_update, SampleCallBack); - - sprintf(mp4_out_na_context, "na_%s_%i.mp4", context_rootname, i+1); - sprintf(bt_out_na_context, "na_%s_%i.bt", context_rootname, i+1); - sprintf(mp4_out_agg_context, "agg_%s_%i.mp4", context_rootname, i+1); - sprintf(bt_out_agg_context, "agg_%s_%i.bt", context_rootname, i+1); - - gf_beng_save_context(codec2, mp4_out_na_context); - gf_beng_save_context(codec2, bt_out_na_context); - gf_beng_aggregate_context(codec2); - gf_beng_save_context(codec2, mp4_out_agg_context); - gf_beng_save_context(codec2, bt_out_agg_context); - - gf_beng_terminate(codec2); - } - fprintf(stdout, "Done.\n"); - } - return 0; -} - - diff --git a/applications/testapps/beng_test/rect-update.bt b/applications/testapps/beng_test/rect-update.bt deleted file mode 100644 index cae8ca4..0000000 --- a/applications/testapps/beng_test/rect-update.bt +++ /dev/null @@ -1,18 +0,0 @@ -AT 1000 { - REPLACE REC.size BY 50 50 -} -AT 2000 { - REPLACE M.emissiveColor BY 1 1 1 -} -AT 3000 { - REPLACE M.filled BY FALSE -} -AT 4000 { - REPLACE REC.size BY 30 20 -} -AT 5000 { - DELETE REC -} -AT 6000 { - DELETE M -} diff --git a/applications/testapps/beng_test/rect.bt b/applications/testapps/beng_test/rect.bt deleted file mode 100644 index 9058a32..0000000 --- a/applications/testapps/beng_test/rect.bt +++ /dev/null @@ -1,42 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - nodeIdBits 10 - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - Shape { - appearance Appearance { - material DEF M Material2D { - emissiveColor 0.5 0.6 0.4 - filled TRUE - } - } - geometry DEF REC Rectangle { - size 50 100 - } - } - ] -} diff --git a/applications/testapps/broadcaster/Makefile b/applications/testapps/broadcaster/Makefile index 0efdbe7..04082f0 100644 --- a/applications/testapps/broadcaster/Makefile +++ b/applications/testapps/broadcaster/Makefile @@ -19,16 +19,18 @@ LDFLAGS+=-pg endif #common obj -OBJS=RTP_serv_generator.o RTP_serv_packetizer.o RTP_serv_sender.o broadcaster.o sdp_generator.o +OBJS=RTP_serv_generator.o RTP_serv_packetizer.o RTP_serv_sender.o broadcaster.o sdp_generator.o debug.o + +LDFLAGS += -L../../../bin/gcc LIBS=-lgpac all: broadcaster -broadcaster: $(OBJS) - @$(CC) -o $(APPNAME) $(OBJS) $(LIBS) +broadcaster: $(OBJS) *.h + $(CC) -o $(APPNAME) $(OBJS) $(LIBS) $(LDFLAGS) .c.o: - @$(CC) -g -c $(CFLAGS) $*.c + $(CC) -Wall -g -c $(CFLAGS) $*.c clean: diff --git a/applications/testapps/broadcaster/RTP_serv_generator.c b/applications/testapps/broadcaster/RTP_serv_generator.c index 35f7271..a10292f 100644 --- a/applications/testapps/broadcaster/RTP_serv_generator.c +++ b/applications/testapps/broadcaster/RTP_serv_generator.c @@ -1,229 +1,286 @@ -/* - RTP Server - Projet MIX - Module de generation de l'horloge -*/ +#include +#include +#include #include "RTP_serv_generator.h" +#include "debug.h" -/*Inutile car plus de variables globales*/ -#define VERIFY_INITIALIZED if (!initialized) { printf("Error : SampleCallBack Called before initialization\n"); exit(255);} -int initialized = 0; // Il n'y a plus de variables globales donc ce flag est inutile. - -char in_context[100]; -char update[1000];// = "REPLACE M.emissiveColor BY 1 1 0"; -char timed_update[1000]; - -extern GF_Err SampleCallBack(void *calling_object, char *data, u32 size, u64 ts); - -PNC_CallbackData * PNC_Init_SceneGenerator(GF_RTPChannel * p_chan, GF_RTPHeader * p_hdr, char * default_scene, int socketPort) { - PNC_CallbackData * data = malloc(sizeof(PNC_CallbackData)); - int * i ; - - data->chan = p_chan; - data->hdr=p_hdr; - - /*Charger la scene initiale == le contexte*/ - data->codec= gf_beng_init(data, default_scene); - fprintf(stdout, "[carrousel] : command socket: listening on port %d\n", socketPort); - data->socket = gf_sk_new(GF_SOCK_TYPE_UDP); // on cree le socket UDP de commande - fprintf(stdout, "[carrousel] : socket bind: %d\n", gf_sk_bind(data->socket, NULL, socketPort, NULL, 0, 0)); - // fprintf(stdout, "[carrousel] : socket connect: %d\n", gf_sk_connect(data->socket, "127.0.0.1", socketPort, NULL)); - // fprintf(stdout, "[carrousel] : socket listen: %d\n", gf_sk_listen(data->socket, 1)); - fprintf(stdout, "[carrousel] : gf_sk_set_block_mode: %d\n", gf_sk_set_block_mode(data->socket,0)); - - data->extension = malloc(sizeof(PNC_CallbackExt)); - ((PNC_CallbackExt * )data->extension)->i = 0; - ((PNC_CallbackExt * )data->extension)->lastTS = 0; - i = & ((PNC_CallbackExt * )data->extension)->i; - - initialized = 1; // ici on est initialisé (flag) +/* Callback function called when encoding of BT is done */ +GF_Err SampleCallBack(void *calling_object, u16 ESID, char *au, u32 size, u64 ts) +{ + PNC_CallbackData *data = (PNC_CallbackData *)calling_object; + /* call the packetizer to create RTP packets */ + PNC_ProcessData(data, au, size, ts); + return GF_OK; +} + +GF_Err (*MySampleCallBack)(void *, u16, char *data, u32 size, u64 ts) = &SampleCallBack; + +PNC_CallbackData *PNC_Init_SceneGenerator(GF_RTPChannel *p_chan, GF_RTPHeader *p_hdr, char *default_scene, + u32 socketType, u16 socketPort, int debug) +{ + GF_Err e; + PNC_CallbackData *data = gf_malloc(sizeof(PNC_CallbackData)); + int *i; + data->chan = p_chan; + data->hdr = p_hdr; + data->debug = debug; + memset( (void*) (data->buffer), '\0', RECV_BUFFER_SIZE_FOR_COMMANDS); + data->bufferPosition = 0; + /* Loading the initial scene as the encoding context */ + data->codec = gf_seng_init((void*)data, default_scene); + if (!data->codec) { + fprintf(stderr, "Cannot create BIFS Engine from %s\n", default_scene); + gf_free(data); + return NULL; + } + data->server_socket = NULL; + data->socket = NULL; - return data; + if (socketType == GF_SOCK_TYPE_TCP) + { + data->server_socket = gf_sk_new(socketType); + e = gf_sk_bind(data->server_socket, NULL, (u16) socketPort, NULL, 0, 0); + if (e) + fprintf(stderr, "Failed to bind : %s\n", gf_error_to_string(e)); + e |= gf_sk_listen(data->server_socket, 1); + if (e) + fprintf(stderr, "Failed to listen : %s\n", gf_error_to_string(e)); + e |= gf_sk_set_block_mode(data->server_socket, 0); + if (e) + fprintf(stderr, "Failed to set block mode : %s\n", gf_error_to_string(e)); + e |= gf_sk_server_mode(data->server_socket, 0); + if (e) + fprintf(stderr, "Failed to set server mode : %s\n", gf_error_to_string(e)); + } else { + data->socket = gf_sk_new(socketType); + e = gf_sk_bind(data->socket, NULL, (u16) socketPort, NULL, 0, 0); + } + /* + char buffIp[1024]; + u16 port = 0; + u32 socket_type = 0; + e |= gf_sk_get_local_ip(data->socket, buffIp); + e |= gf_sk_get_local_info(data->socket, &port, &socket_type); + dprintf(DEBUG_RTP_serv_generator, "RTS_serv_generator %s:%d %s\n", + buffIp, port, socket_type==GF_SOCK_TYPE_UDP?"UDP":"TCP", e==GF_OK?"OK":"ERROR"); + */ + if (e) { + fprintf(stderr, "Cannot bind socket to port %d (%s)\n", socketPort, gf_error_to_string(e)); + if (data->socket) + gf_sk_del(data->socket); + if (data->server_socket) + gf_sk_del(data->server_socket); + gf_free(data); + return NULL; + } + data->extension = gf_malloc(sizeof(PNC_CallbackExt)); + ((PNC_CallbackExt * )data->extension)->i = 0; + ((PNC_CallbackExt * )data->extension)->lastTS = 0; + i = &((PNC_CallbackExt*)data->extension)->i; + return data; } -void PNC_SendInitScene(PNC_CallbackData * data){ - - // on peut gerer l'update de la scene par defaut. - /// TODO: Il va falloir gerer le mecanisme Carousel - data->RAP=1; //On demande que RAP soit positionné dans le SL - data->SAUN_inc=1; //On demande que SAUN soit incrementé car - //on ne pourra pas faire les prochaines mises a jour sans ... - fprintf(stdout, "[gpaclib] : "); - gf_beng_encode_context(data->codec, SampleCallBack); +void PNC_SendInitScene(PNC_CallbackData * data) +{ + data->RAP = 1; + data->SAUN_inc = 1; + gf_seng_encode_context(data->codec, MySampleCallBack); } -void PNC_Close_SceneGenerator(PNC_CallbackData * data) { - // terminer - if (data->extension) free(data->extension); - gf_beng_terminate(data->codec); +void PNC_Close_SceneGenerator(PNC_CallbackData * data) +{ + if (data->extension) gf_free(data->extension); + gf_seng_terminate(data->codec); gf_rtp_del(data->chan); PNC_ClosePacketizer(data); - free(data); + gf_free(data); } -/* fonction callcak appellee quand la compilation du BT est faite */ -GF_Err SampleCallBack(void *calling_object, char *au, u32 size, u64 ts) + +/** + * Finds the command directive if any + */ +static int findCommand(const char * buffer, int searchFrom) { - PNC_CallbackData * data ; - VERIFY_INITIALIZED; + char * sstr; + assert( buffer ); + assert( searchFrom >= 0); + /** We may have received #RTP_STREAM_ directive before the last update */ + if (searchFrom < 30){ + searchFrom = 0; + } else { + searchFrom-= 30; + } + sstr = strstr(&(buffer[searchFrom]), "#_RTP_STREAM_"); + if (sstr){ + return (sstr - buffer); + } + return -1; +} - data = (PNC_CallbackData *) calling_object; - - ///*the sample object*/ - ////typedef struct tagM4Sample - //{ - // /*data size*/ - // u32 dataLength; - // /*data with padding if requested*/ - // char *data; - // /*decoding time*/ - // u32 DTS; - // /*relative offset for composition if needed*/ - // u32 CTS_Offset; - // /*Random Access Point flag - 1 is regular RAP (read/write) , 2 is SyncShadow (read mode only)*/ - // u8 IsRAP; - //} M4Sample; - PNC_ProcessData(data, au, size, ts); // on passe la main au packetizer ... - - return GF_OK; +static GF_Err processSend(PNC_CallbackData * data, char * bsBuffer) +{ + GF_Err error; + assert( data ); + assert( bsBuffer ); + assert( data->codec ); + dprintf(DEBUG_RTP_serv_generator, "RTP STREAM SEND\n"); + gf_mx_p(data->carrousel_mutex); + error = gf_seng_encode_from_string(data->codec, 0, 0, bsBuffer, MySampleCallBack); + gf_mx_v(data->carrousel_mutex); + gf_free( bsBuffer ); + return error; } -GF_Err PNC_RAP(PNC_CallbackData * data) { - /// envoyer le RAP initial; +static GF_Err processRapReset(PNC_CallbackData * data, char * bsBuffer) +{ + GF_Err error; + dprintf(DEBUG_RTP_serv_generator, "RTP STREAM RAP RESET\n"); + gf_mx_p(data->carrousel_mutex); + data->RAP = 1; + data->RAPsent++; + data->SAUN_inc = 1; + error = gf_seng_aggregate_context(data->codec, 0); + if (error == GF_OK) + error = gf_seng_encode_context(data->codec, MySampleCallBack); + gf_mx_v(data->carrousel_mutex); + gf_free( bsBuffer ); + return error; +} + +static GF_Err processRap(PNC_CallbackData * data, char * bsBuffer) +{ + GF_Err error; + dprintf(DEBUG_RTP_serv_generator, "RTP STREAM RAP\n"); + gf_mx_p(data->carrousel_mutex); + data->SAUN_inc = 1; data->RAP = 1; - gf_beng_aggregate_context(data->codec); - gf_beng_encode_context(data->codec, SampleCallBack); - data->RAP = 0; - return GF_OK; + data->RAPsent++; + error = gf_seng_aggregate_context(data->codec, 0); + if (GF_OK == error) + error = gf_seng_encode_context(data->codec, MySampleCallBack); + gf_mx_v(data->carrousel_mutex); + gf_free( bsBuffer ); + return error; } -int PNC_int_isFinished(char * bsBuffer, u32 bsBufferSize) { - /* Fonction interne, sorte de parseur de directives - * Non exportée dans le .h */ - char * buff = malloc(sizeof(char)*bsBufferSize+5); - char * sstr; - int retour=(int)PNC_RET_RTP_STREAM_NOOP; - - *buff = 0; - - if (! buff) printf("ERREUR 1 %s %d \n", __FILE__, __LINE__); - if (! bsBuffer) printf("ERREUR 2 %s %d \n", __FILE__, __LINE__); - - memcpy(buff, bsBuffer, bsBufferSize); - buff[bsBufferSize]=0; - if ( *buff != '\0') - { - sstr = strstr(buff, "#_RTP_STREAM_"); // On cherche le prefixe des directives ... - - if (sstr) - { - //On en tient une ;) - sstr+=13; //On mange le prefixe - // printf("strStr $%s$ $%s$ %d\n",sstr ,PNC_STR_RTP_STREAM_RAP, strcmp(sstr, PNC_STR_RTP_STREAM_RAP) ); - if (strcmp(sstr, PNC_STR_RTP_STREAM_SEND_CRITICAL)==0) retour= (int)PNC_RET_RTP_STREAM_SEND_CRITICAL; - - if (strcmp(sstr, PNC_STR_RTP_STREAM_SEND)==0) retour= (int)PNC_RET_RTP_STREAM_SEND; - if (strcmp(sstr, PNC_STR_RTP_STREAM_RAP)==0) retour= (int)PNC_RET_RTP_STREAM_RAP; - if (strcmp(sstr, PNC_STR_RTP_STREAM_RAP_RESET)==0) retour= (int)PNC_RET_RTP_STREAM_RAP_RESET; - - free(buff); return retour; - } - } - free(buff); - return (int)PNC_RET_RTP_STREAM_NOOP; +static GF_Err processSendCritical(PNC_CallbackData * data, char * bsBuffer) +{ + GF_Err error; + dprintf(DEBUG_RTP_serv_generator, "RTP STREAM SEND CRITICAL\n"); + gf_mx_p(data->carrousel_mutex); + data->SAUN_inc = 1; + error = gf_seng_encode_from_string(data->codec, 0, 0, bsBuffer, MySampleCallBack); + gf_mx_v(data->carrousel_mutex); + gf_free( bsBuffer ); + return error; } -GF_Err PNC_processBIFSGenerator(PNC_CallbackData * data) { - unsigned char buffer[66000]; - u32 byteRead=0; - GF_BitStream * bs = gf_bs_new(NULL, 0,GF_BITSTREAM_WRITE); // dernier champ = mode ?!? no doc - unsigned char *bsBuffer; - // char bsCommande[66000]; - // struct timespec heure; - u32 bsSize=0; +/** + * Allocates a new buffer for output and copy everything in it; + * then copy off data from newStart to upToPosition. + */ +static char * eat_buffer_to_bs(char * data, int newStart, int upToPosition, int dataFullSize) +{ + char * newBuffer; + + /* Sanity checks */ + assert(data); + assert(newStart >= 0); + assert(upToPosition >= 0); + assert(dataFullSize > 0); + assert(newStart < upToPosition); + data[upToPosition] = '\0'; + newBuffer = NULL; + + /*new length + '\0'*/ + assert(dataFullSize >= upToPosition-newStart+2); + newBuffer = (char*)gf_malloc(dataFullSize); + memcpy(newBuffer, data, dataFullSize); + memcpy(data, newBuffer+newStart, upToPosition-newStart+1); + data[upToPosition-newStart+1]='\0'; + dprintf(DEBUG_RTP_serv_generator, "Generated : '%s'\n", newBuffer); + return newBuffer; +} + +GF_Err PNC_processBIFSGenerator(PNC_CallbackData * data) +{ + const int tmpBufferSize = 2048; + char *tmpBuffer = (char*)alloca(tmpBufferSize); + int byteRead=0; + + char *bsBuffer; int retour=0; GF_Err e; - /* ici, nous allons attendre (bloquant) sur le socket, et quand on recoit - * des données, on les range. quand on recoit un ordre, on l'execute sur les données. - */ - - while (!(retour = PNC_int_isFinished((char *) buffer, byteRead))) + + if (data->server_socket) + { + data->socket = NULL; + e = gf_sk_accept(data->server_socket, &(data->socket)); + if (e){ + return GF_OK; + } else { + dprintf(DEBUG_RTP_serv_generator, "New TCP client connected !\n"); + } + } + + do { - e = gf_sk_receive(data->socket, buffer, 66000, 0, & byteRead); - /* le receive semble pas bloquant alors que l'API l'annonce */ - switch (e) - { + if (data->socket == NULL) + return GF_OK; + e = gf_sk_receive(data->socket, tmpBuffer, tmpBufferSize, 0, & byteRead); + switch (e) { case GF_IP_NETWORK_EMPTY: - gf_bs_del(bs); - return GF_OK; + e = GF_OK; + break; case GF_OK: - break; + if (byteRead > 0){ + dprintf(DEBUG_RTP_serv_generator, "Received %d bytes\n", byteRead); + /* We copy data in buffer */ + memcpy( &(data->buffer[data->bufferPosition]), tmpBuffer, byteRead ); + data->buffer[data->bufferPosition + byteRead] = '\0'; + retour = findCommand( data->buffer, data->bufferPosition); + data->bufferPosition += byteRead; + if (retour >= 0){ + /** OK, it means we found a command ! */ + if (strncmp(&(data->buffer[retour+13]), + "SEND_CRITICAL", 13)==0){ + bsBuffer = eat_buffer_to_bs( data->buffer, retour, retour + 26, RECV_BUFFER_SIZE_FOR_COMMANDS); + data->bufferPosition = 0; + return processSendCritical(data, bsBuffer); + } + if (strncmp(&(data->buffer[retour+13]), "SEND", 4)==0){ + bsBuffer = eat_buffer_to_bs( data->buffer, retour, retour + 17, RECV_BUFFER_SIZE_FOR_COMMANDS); + data->bufferPosition = 0; + return processSend(data, bsBuffer); + } + if (strncmp(&(data->buffer[retour+13]), "RAP", 3)==0){ + bsBuffer = eat_buffer_to_bs( data->buffer, retour, retour + 16, RECV_BUFFER_SIZE_FOR_COMMANDS); + data->bufferPosition = 0; + return processRap(data, bsBuffer); + } + if (strncmp(&(data->buffer[retour+13]), "RAP_RESET", 9)==0){ + bsBuffer = eat_buffer_to_bs( data->buffer, retour, retour + 22, RECV_BUFFER_SIZE_FOR_COMMANDS); + data->bufferPosition = 0; + return processRapReset(data, bsBuffer); + } + /** If we are here, it means probably we did not received fully the command */ + break; + } + } + /* No bytes were received */ + break; default: - fprintf(stdout, "[carrousel] : erreur de socket : %d\n", e); - gf_bs_del(bs); + fprintf(stderr, "Socket error while receiving BIFS data %s\n", gf_error_to_string(e)); + if (data->socket != NULL){ + gf_sk_del(data->socket); + data->socket = NULL; + } return e; } - // if (byteRead > 0) printf("Octets recus: %d \n", byteRead); - gf_bs_write_data(bs, buffer, byteRead); - } - gf_bs_write_data(bs, (unsigned char *) "\0", 1); // on met le terminateur de chaine - gf_bs_get_content(bs, &bsBuffer, &bsSize); - //update=malloc(sizeof(char) * (bsSize + 20)); - //trash = clock_gettime(CLOCK_REALTIME, &heure); - //offset = heure.tv_sec*1000 + heure.tv_nsec/1000/1000; - //sprintf(update, "AT %d {%s}", offset, bsBuffer); - //printf("%f\n",(float)offset/1000.0); - /* les données sont pretes*/ - - // mutex - while(gf_mx_try_lock(data->carrousel_mutex) == 0) - { - gf_sleep(1); - } - - fprintf(stdout, "[carrousel] : received -> "); - switch (retour) - { - case PNC_RET_RTP_STREAM_SEND: - fprintf(stdout, "RTP STREAM SEND\n"); - /* on encode la chaine, qui est bien NULL Terminated */ - // sprintf(bsCommande, "AT 1{%s}", bsBuffer); - // fprintf(stdout, "COMMANDE : %s\n", bsCommande); - fprintf(stdout, "[gpaclib] : "); - e = gf_beng_encode_from_string(data->codec, (char *) bsBuffer, SampleCallBack); - fprintf(stdout, "beng result %d\n",e); - break; - - case PNC_RET_RTP_STREAM_SEND_CRITICAL: - fprintf(stdout, "RTP STREAM SEND CRITICAL\n"); - // sprintf(bsCommande, "AT 1{%s}", bsBuffer); - // fprintf(stdout, "COMMANDE : %s\n", bsCommande); - data->SAUN_inc=1; - fprintf(stdout, "[gpaclib] : "); - gf_beng_encode_from_string(data->codec, (char *) bsBuffer, SampleCallBack); - break; - - case PNC_RET_RTP_STREAM_RAP: - data->RAP=1; - data->RAPsent++; - fprintf(stdout, "RTP STREAM RAP\n"); - fprintf(stdout, "[gpaclib] : "); - gf_beng_aggregate_context(data->codec); - gf_beng_encode_context(data->codec, SampleCallBack); - break; - case PNC_RET_RTP_STREAM_RAP_RESET: - data->RAP=1; //On demande que RAP soit positionné dans le SL - data->RAPsent++; - fprintf(stdout, "RTP STREAM RAP\n"); - data->SAUN_inc=1; // On demande l'augmentation du SAUN - fprintf(stdout, "[gpaclib] : "); - gf_beng_aggregate_context(data->codec); - gf_beng_encode_context(data->codec, SampleCallBack); - break; - } - // unlocking mutex - gf_mx_v(data->carrousel_mutex); + } while (e == GF_OK); + return GF_OK; } diff --git a/applications/testapps/broadcaster/RTP_serv_generator.h b/applications/testapps/broadcaster/RTP_serv_generator.h index fd9777c..42dd43f 100644 --- a/applications/testapps/broadcaster/RTP_serv_generator.h +++ b/applications/testapps/broadcaster/RTP_serv_generator.h @@ -1,60 +1,66 @@ +#ifndef _RTP_SERV_GENERATOR_H_ +#define _RTP_SERV_GENERATOR_H_ #include -#if 0 -#include -#endif + #include -#include // Pour les sockets +#include // sockets #include #include +#include -#include "RTP_serv_packetizer.h" #include -#ifndef __RTP_SERV_CLOCK -#define __RTP_SERV_CLOCK +#define RECV_BUFFER_SIZE_FOR_COMMANDS 262144 -#define PNC_RET_RTP_STREAM_NOOP 0 -#define PNC_RET_RTP_STREAM_SEND 1 -#define PNC_RET_RTP_STREAM_SEND_CRITICAL 2 -#define PNC_RET_RTP_STREAM_RAP 3 -#define PNC_RET_RTP_STREAM_RAP_RESET 4 +/*callback type (allows reentrance)*/ +typedef struct tmp_PNC_CallbackData { + GF_RTPChannel *chan; + GF_RTPHeader *hdr; + char * formatedPacket; + int formatedPacketLength; + GP_RTPPacketizer *rtpBuilder; + GF_SceneEngine *codec; -#define PNC_STR_RTP_STREAM_SEND "SEND\n" -#define PNC_STR_RTP_STREAM_SEND_CRITICAL "SEND_CRITICAL\n" -#define PNC_STR_RTP_STREAM_RAP "RAP\n" -#define PNC_STR_RTP_STREAM_RAP_RESET "RAP_RESET\n" + /* socket on which updates are received */ + GF_Socket *socket; + GF_Socket *server_socket; + /* socket on which bitrate feedback is sent */ + GF_Socket *feedback_socket; -/*Le type passe pour le callback (permet la reentrance)*/ -typedef struct tmp_PNC_CallbackData { - GF_RTPChannel * chan; - GF_RTPHeader * hdr; - char * formatedPacket; - int formatedPacketLength; - GP_RTPPacketizer *rtpBuilder; - void * codec; - GF_Socket *socket; /// Socket pour recevoir les demandes de mise à jour. - GF_Socket *feedback_socket; // socket pour envoyer les données de retour débit à l'interface - void * extension; - int RAP; - int RAPsent; - int SAUN_inc; // On incremente le SequAUNumber de l'entete SL - GF_Mutex *carrousel_mutex; + void *extension; + + /* indication that the Access Unit is a RAP */ + int RAP; + /* RAP counter */ + int RAPsent; + /* indication that the Access Unit Sequence Number should be increased */ + int SAUN_inc; + + GF_Mutex *carrousel_mutex; + char buffer[RECV_BUFFER_SIZE_FOR_COMMANDS]; + int bufferPosition; + int debug; } PNC_CallbackData; + +#define RTP_SERV_GENERATOR_DEBUG 0x4 + typedef struct tmp_PNC_CallbackExt { - int i; - int lastTS; + int i; + int lastTS; } PNC_CallbackExt; -/*Les fonctions exportees*/ -extern GF_Err PNC_RAP(PNC_CallbackData * data); -extern PNC_CallbackData* PNC_Init_SceneGenerator(GF_RTPChannel * p_chan, GF_RTPHeader * p_hdr, char * default_scene, int socketPort); +/*exports*/ +extern GF_Err PNC_RAP(PNC_CallbackData *data); +extern PNC_CallbackData* PNC_Init_SceneGenerator(GF_RTPChannel *p_chan, GF_RTPHeader *p_hdr, char *default_scene, + u32 socketType, u16 socketPort, int debug); extern GF_Err PNC_processBIFSGenerator(PNC_CallbackData*); extern void PNC_Close_SceneGenerator(PNC_CallbackData*); extern void PNC_SendInitScene(PNC_CallbackData * data); - -#endif +#include "RTP_serv_packetizer.h" + +#endif \ No newline at end of file diff --git a/applications/testapps/broadcaster/RTP_serv_packetizer.c b/applications/testapps/broadcaster/RTP_serv_packetizer.c index eb93207..1e7f84b 100644 --- a/applications/testapps/broadcaster/RTP_serv_packetizer.c +++ b/applications/testapps/broadcaster/RTP_serv_packetizer.c @@ -1,147 +1,92 @@ -/* -RTP Server -Projet MIX - -Generation des paquets RTP -*/ - - -/* Ici on va prendre un buffer et le préparer pour l'envoyer, cad le passer - a RTPBuilder pour qu'il fasse les entetes, qu'il splitte - Ensuite on concatene l'entete avec le contenu et on envoie. - -*/ - - - #include "RTP_serv_packetizer.h" #include "RTP_serv_sender.h" +#include #include #include #include +#define MAX_PACKET_SIZE 2000 -void OnNewPacket(void *cbk, GF_RTPHeader *header){ - // +#include "debug.h" - // Ici on remet le packet courant à vide. - ((PNC_CallbackData *)cbk)->formatedPacketLength = 0; +void OnNewPacket(void *cbk, GF_RTPHeader *header) +{ + ((PNC_CallbackData *)cbk)->formatedPacketLength = 0; } -void OnPacketDone(void *cbk, GF_RTPHeader *header) { - // - printf("OK Paquet généré ->>>"); - //Ici on peut proceder à l'envoi du packet courant. - - - PNC_SendRTP(((PNC_CallbackData *)cbk), ((PNC_CallbackData *)cbk)->formatedPacket, ((PNC_CallbackData *)cbk)->formatedPacketLength); - ((PNC_CallbackData *)cbk)->formatedPacketLength = 0; - +void OnPacketDone(void *cbk, GF_RTPHeader *header) +{ + PNC_CallbackData *data = (PNC_CallbackData *)cbk; + dprintf(DEBUG_RTP_serv_packetizer, "RTP Packet done\n"); + PNC_SendRTP(data, ((PNC_CallbackData *)cbk)->formatedPacket, ((PNC_CallbackData *)cbk)->formatedPacketLength); + ((PNC_CallbackData *)cbk)->formatedPacketLength = 0; } -void OnData(void *cbk, char *data, u32 data_size, Bool is_head){ - - memcpy( ((PNC_CallbackData *)cbk)->formatedPacket+((PNC_CallbackData *)cbk)->formatedPacketLength, data, data_size); - ((PNC_CallbackData *)cbk)->formatedPacketLength+=data_size; - - // Ici on concatene ce qu'on vient de recevoir au packet courant. - +void OnData(void *cbk, char *data, u32 data_size, Bool is_head) +{ + memcpy(((PNC_CallbackData *)cbk)->formatedPacket+((PNC_CallbackData *)cbk)->formatedPacketLength, data, data_size); + ((PNC_CallbackData *)cbk)->formatedPacketLength += data_size; } -void PNC_InitPacketiser(PNC_CallbackData * data, char *sdp_fmt){ - - // char sdp_fmt[5000]; - GP_RTPPacketizer *p; - GF_SLConfig sl; - memset(&sl, 0, sizeof(sl)); - sl.useTimestampsFlag = 1; - sl.useRandomAccessPointFlag = 1; - sl.timestampResolution = 1000; - sl.AUSeqNumLength = 16; // Peut etre descendu a 7 pour gagner 1 octet ... - // PIPOCANAJA - - - p = gf_rtp_builder_new(GF_RTP_PAYT_MPEG4, - &sl, - GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_SIGNAL_AU_IDX, - data, - OnNewPacket, - OnPacketDone, - NULL, - OnData); - - // M4RTP_InitBuilder(p, 96, 1488, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, NULL); - gf_rtp_builder_init(p, 96, 1470, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, NULL); - - gf_rtp_builder_format_sdp(p, "mpeg4-generic", sdp_fmt, NULL, 0); - - // fprintf(stdout, "%s\n", sdp_fmt); - p->rtp_header.Version=2; - p->rtp_header.SSRC=rand();//RandomNumber identifiant la source - - data->hdr=& p->rtp_header; - data->rtpBuilder=p; - data->formatedPacket = malloc(2000); //buffer pour les paquets - data->formatedPacketLength = 0; +void PNC_InitPacketiser(PNC_CallbackData * data, char *sdp_fmt, unsigned short mtu_size) +{ + GP_RTPPacketizer *p; + GF_SLConfig sl; + memset(&sl, 0, sizeof(sl)); + sl.useTimestampsFlag = 1; + sl.useRandomAccessPointFlag = 1; + sl.timestampResolution = 1000; + sl.AUSeqNumLength = 16; + + p = gf_rtp_builder_new(GF_RTP_PAYT_MPEG4, + &sl, + GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_SIGNAL_AU_IDX, + data, + OnNewPacket, + OnPacketDone, + NULL, + OnData); + if (!p) { + fprintf(stderr, "Cannot create RTP builder \n"); + return; + } + + /* Mtu size - 20 = payload max size */ + mtu_size-=20; + gf_rtp_builder_init(p, 96, mtu_size, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, NULL); + gf_rtp_builder_format_sdp(p, "mpeg4-generic", sdp_fmt, NULL, 0); + p->rtp_header.Version=2; + p->rtp_header.SSRC=rand(); + data->hdr=& p->rtp_header; + data->rtpBuilder=p; + data->formatedPacket = gf_malloc(MAX_PACKET_SIZE); + data->formatedPacketLength = 0; } void PNC_ClosePacketizer(PNC_CallbackData *data) { - free(data->formatedPacket); + gf_free(data->formatedPacket); gf_rtp_builder_del(data->rtpBuilder); } -GF_Err PNC_ProcessData(PNC_CallbackData * data, char *au, u32 size, u64 ts) { - /* Prepare le paquet en mettant à jour le hdr qui contiendra le numero de sequence courant, - le timestamp correct ...*/ - /*PacketID represente le numero du paquet dans le cas d'une fragmentation en plusieurs paquet RTP - d'une data*/ - - // ici on met le timestamp pour que les modifications arrivent bien a etre affiches - data->hdr->TimeStamp = (u32) gf_sys_clock(); // ts; - - //Dans samp->IsRAP - // /*Random Access Point flag - 1 is regular RAP (read/write) , 2 is SyncShadow (read mode only)*/ - // u8 IsRAP; - - if (! data->rtpBuilder) { - printf(" data->rtpBuilder Null\n\n");exit(-1);} - - // ici on met le timestamp pour que les modifications arrivent bien a etre affiches - data->rtpBuilder->sl_header.compositionTimeStamp = (u32) gf_sys_clock(); // ts; - - data->rtpBuilder->sl_header.randomAccessPointFlag = data->RAP; - - if (data->SAUN_inc) // Si on a demandé d'incrémenter, on incrémente :) - data->rtpBuilder->sl_header.AU_sequenceNumber ++ ; - - data->RAP=0; - data->SAUN_inc=0; - - data->rtpBuilder->sl_header.paddingBits = 0; - - - gf_rtp_builder_process(data->rtpBuilder, au, size, 1, size, 0, 0); - -#if 0 - - while (remaining_length > RTP_packet_overflow) { - data->hdr->SequenceNumber++; - - PNC_SendRTP(data, current_data, RTP_packet_overflow); - - current_data += RTP_packet_overflow; - remaining_length -= RTP_packet_overflow; - } - -#endif - - - - // data->hdr->SequenceNumber++; - //PNC_SendRTP(data, current_data, remaining_length); - - return GF_OK; +GF_Err PNC_ProcessData(PNC_CallbackData * data, char *au, u32 size, u64 ts) +{ + assert( data ); + assert( au ); + /* We need to set a TS different every time */ + data->hdr->TimeStamp = (u32) gf_sys_clock(); + data->rtpBuilder->sl_header.compositionTimeStamp = (u32) gf_sys_clock(); + data->rtpBuilder->sl_header.randomAccessPointFlag = data->RAP; + if (data->SAUN_inc) data->rtpBuilder->sl_header.AU_sequenceNumber++; + + /* reset input data config */ + data->RAP=0; + data->SAUN_inc=0; + + data->rtpBuilder->sl_header.paddingBits = 0; + gf_rtp_builder_process(data->rtpBuilder, au, size, 1, size, 0, 0); + + return GF_OK; } diff --git a/applications/testapps/broadcaster/RTP_serv_packetizer.h b/applications/testapps/broadcaster/RTP_serv_packetizer.h index 5c9611a..9cec6ee 100644 --- a/applications/testapps/broadcaster/RTP_serv_packetizer.h +++ b/applications/testapps/broadcaster/RTP_serv_packetizer.h @@ -1,15 +1,13 @@ #ifndef __RTP_SERV_PACKETISER #define __RTP_SERV_PACKETISER - #include -#include "gpac/bifsengine.h" // Pour M4Sample +#include "gpac/scene_engine.h" // For M4Sample #include "RTP_serv_generator.h" -/*Les fonctions exportees*/ -void PNC_InitPacketiser(PNC_CallbackData * data, char *sdp_fmt); -GF_Err PNC_ProcessData(PNC_CallbackData * data, char *au, u32 size, u64 ts); +/*exports*/ +void PNC_InitPacketiser(PNC_CallbackData *data, char *sdp_fmt, unsigned short mtu_size); +GF_Err PNC_ProcessData(PNC_CallbackData *data, char *au, u32 size, u64 ts); void PNC_ClosePacketizer(PNC_CallbackData *data); - #endif diff --git a/applications/testapps/broadcaster/RTP_serv_sender.c b/applications/testapps/broadcaster/RTP_serv_sender.c index 2d7f2ce..bd379b9 100644 --- a/applications/testapps/broadcaster/RTP_serv_sender.c +++ b/applications/testapps/broadcaster/RTP_serv_sender.c @@ -1,14 +1,21 @@ #include "RTP_serv_sender.h" #include #include +#include "debug.h" -GF_Err PNC_InitRTP(GF_RTPChannel **chan, char * dest, int port){ +GF_Err PNC_InitRTP(GF_RTPChannel **chan, char *dest, int port, unsigned short mtu_size) +{ GF_Err res; GF_RTSPTransport tr; *chan = gf_rtp_new(); - printf("[carrousel] : RTP_SetupPorts=%d\n", gf_rtp_set_ports(*chan, 0)); + res = gf_rtp_set_ports(*chan, 0); + if (res) { + fprintf(stderr, "Cannot set RTP ports: %s\n", gf_error_to_string(res)); + gf_rtp_del(*chan); + return res; + } tr.destination = dest; tr.IsUnicast = gf_sk_is_multicast_address(dest) ? 0 : 1; @@ -18,49 +25,59 @@ GF_Err PNC_InitRTP(GF_RTPChannel **chan, char * dest, int port){ tr.source = "0.0.0.0"; tr.SSRC=rand(); - tr.port_first = port; - tr.port_last = port+1; + tr.port_first = port; + tr.port_last = port+1; if (tr.IsUnicast) { tr.client_port_first = port; - tr.client_port_last = port+1; + tr.client_port_last = port+1; } else { tr.source = dest; + tr.client_port_first = 0; + tr.client_port_last = 0; } + res = gf_rtp_setup_transport(*chan, &tr, dest); - printf("[carrousel] : RTP_SetupTransport=%d\n", res); - if (res !=0) return res; + if (res) { + fprintf(stderr, "Cannot setup RTP transport %s\n", gf_error_to_string(res)); + gf_rtp_del(*chan); + return res; + } - res = gf_rtp_initialize(*chan, 0, 1, 1500, 0, 0, NULL); - printf("[carrousel] : RTP_Initialize=%d\n", res); - if (res !=0) return res; + res = gf_rtp_initialize(*chan, 0, 1, mtu_size, 0, 0, NULL); + if (res) { + fprintf(stderr, "Cannot initialize RTP transport %s\n", gf_error_to_string(res)); + gf_rtp_del(*chan); + return res; + } return GF_OK; } -GF_Err PNC_SendRTP(PNC_CallbackData * data, char * payload, int payloadSize){ - GF_Err e; - unsigned char feedback_buffer[250]; // buffer pour envoyer le nombre de byte envoyé - +GF_Err PNC_SendRTP(PNC_CallbackData *data, char *payload, int payloadSize) +{ + GF_Err e; + unsigned char feedback_buffer[250]; + if (!data->hdr->TimeStamp) data->hdr->TimeStamp = ((PNC_CallbackExt * )data->extension)->lastTS; - + ((PNC_CallbackExt * )data->extension)->lastTS = data->hdr->TimeStamp; - e = gf_rtp_send_packet(data->chan, data->hdr, 0, 0, payload, payloadSize); + e = gf_rtp_send_packet(data->chan, data->hdr, payload, payloadSize, 0); + dprintf(DEBUG_RTP_serv_sender, "SendPacket : %d, TimeStamp RTP = %d, sz= %d\n", + e, data->hdr->TimeStamp, payloadSize); - fprintf(stdout, " SendPacket : %d, TimeStamp RTP = %d\n", e, data->hdr->TimeStamp); - // sending feedback bytes memset(feedback_buffer, 0, sizeof(feedback_buffer)); sprintf((char *) feedback_buffer, "DataSent=%d\nRAPsent=%d\n", payloadSize, data->RAPsent); - // fprintf(stdout, "DataSent=%d\nRAPsent=%d\n", payloadSize, data->RAPsent); e = gf_sk_send(data->feedback_socket, feedback_buffer, strlen((char *) feedback_buffer)); - fprintf(stdout, "[carrousel] : sent feedback data %d byte, return %d\n", payloadSize, e); + dprintf(DEBUG_RTP_serv_packetizer, "Sent feedback data %d byte, return %d\n", payloadSize, e); - return GF_OK; + return GF_OK; } -GF_Err PNC_CloseRTP(GF_RTPChannel *chan){ +GF_Err PNC_CloseRTP(GF_RTPChannel *chan) +{ gf_rtp_del(chan); return GF_OK; } diff --git a/applications/testapps/broadcaster/RTP_serv_sender.h b/applications/testapps/broadcaster/RTP_serv_sender.h index 381c755..f564c17 100644 --- a/applications/testapps/broadcaster/RTP_serv_sender.h +++ b/applications/testapps/broadcaster/RTP_serv_sender.h @@ -1,13 +1,13 @@ #ifndef __RTP_SERV_SENDER #define __RTP_SERV_SENDER -#include /// Pour GF_Err ... +#include /// For GF_Err ... #include "RTP_serv_generator.h" extern void test_RTP_serv_send(); -extern GF_Err PNC_InitRTP(GF_RTPChannel **chan, char * dest, int port); -extern GF_Err PNC_SendRTP(PNC_CallbackData * data, char * payload, int payloadSize); +extern GF_Err PNC_InitRTP(GF_RTPChannel **chan, char *dest, int port, unsigned short mtu_size); +extern GF_Err PNC_SendRTP(PNC_CallbackData *data, char *payload, int payloadSize); extern GF_Err PNC_CloseRTP(GF_RTPChannel *chan); diff --git a/applications/testapps/broadcaster/broadcaster.c b/applications/testapps/broadcaster/broadcaster.c index 7dd18ef..3b8349c 100644 --- a/applications/testapps/broadcaster/broadcaster.c +++ b/applications/testapps/broadcaster/broadcaster.c @@ -1,73 +1,103 @@ #include "broadcaster.h" +#include "debug.h" +static void printIncompatibleOptions() +{ + fprintf(stderr, "Options config file and tcp port are incompatible !\n"); +} -extern GF_Err SampleCallBack(void *calling_object, char *data, u32 size, u64 ts); +extern GF_Err SampleCallBack(void *, u16, char *data, u32 size, u64 ts); -/* fonction de gestion de la ligne de commande */ -void command_line_parsing(int* argc, char** argv, int* tcp_port, char *config_file, int *config_flag) +/** + * Returns a port from a char value, will return 0 if port is not valid + */ +static unsigned short port_from_string(const char * port_to_parse) { - int argument, counter; - char value[MAX_BUF]; - - // cas de tous parametres necessaires - if ((*argc) == 3) - { - /* parsing des parametres de la ligne de commande */ - argument=-1; - for(counter = 0; counter < ((*argc) - 2); counter = counter+2) - { - argument = server_command_line(argv[counter+1], argv[counter+2], value, argument); - if (argument == 0) (*tcp_port) = atoi(value); - // if (argument == 1) (*udp_port) = atoi(value); - if (argument == 2) - { - strcpy(config_file, value); - (*config_flag) = 1; - } - } - } - else - { - print_usage(); - exit(0); - } + unsigned long int v; + char * endptr = '\0'; + const char * value = port_to_parse; + if (value == NULL || value[0] == '\0'){ + fprintf(stderr, "Value for port cannot be empty"); + return 0; + } + v = strtoul(value, &endptr, 10); + if (*endptr != '\0' || v < 1 || v > 65535){ + fprintf(stderr, "Value %s is not a valid port, port must be between 1 and 65535 !\n", value); + return 0; + } + return (unsigned short) v; } -/* fonction pour la gestion de base de la ligne de commande */ -int server_command_line(char *arg_a, char *arg_b, char *value, int argument) +static int command_line_parsing(int argc, const char** argv, unsigned short * tcp_port, + char *config_file, int *config_flag, unsigned short * mtu_size, + int * debug, u32 * socketType_for_updates) { - char flag; - sscanf(arg_a, "-%c", &flag); - strcpy(value, arg_b); - switch (flag) - { - case 'p': - argument = 0; - break; - /* - case 'u': - argument = 1; - break; - */ - case 'f': - argument = 2; - break; - default: - print_usage(); - argument = -1; - break; + int counter = 1; + if (argc < 2 || argc%2 != 1) { + fprintf(stderr, "Incorrect number of arguments, must be multiple of 2 (Please specify at least -f or -p arguments) !\n"); + return -5; + } + + for(counter = 1; counter < (argc - 1); counter+=2) + { + const char * a = argv[counter]; + if (!strcmp("-p", a) || !strcmp("--port", a)) + { + if (*config_flag) + { + printIncompatibleOptions(); + return -2; + } + (*tcp_port) = port_from_string( argv[counter + 1] ); + if (!(*tcp_port)) return -3; + } + else if (!strcmp("-f", a) || !strcmp("--file", a)) + { + if (*tcp_port) { + printIncompatibleOptions(); + return -2; + } + strcpy(config_file, argv[counter+1]); + (*config_flag) = 1; + } + else if (!strcmp("-m", a) || !strcmp("--mtu", a)) + { + *mtu_size = atoi(argv[counter+1]); + if (!(mtu_size)) return -3; + } + else if (!strcmp("-d", a) || !strcmp("--debug", a)) + { + *debug = atoi(argv[counter+1]); + } + else if (!strcmp("-s", a) || !strcmp("--socket-type-for-updates", a)) + { + *socketType_for_updates = 0 == stricmp("TCP", argv[counter+1]); + } + else + { + fprintf(stderr, "Unknown parameter %s.", a); + return -2; + } } - return argument; + + if (!(*config_flag) && !(*tcp_port)) { + fprintf(stderr, "No config file or port specified !\n"); + return -6; + } + + return 0; } -/* gestion usage */ void print_usage(void) { - fprintf(stdout, "[broadcaster] usage : ./broadcaster [-p tcp_port] [-f fichier_config]\n"); - fprintf(stdout, "[broadcaster] usage : il faut specifier un fichier de configuration ou un port TCP pour l'interface GUI\n"); + fprintf(stdout, "BIFS Scene encoder and streamer (c) Telecom ParisTech 2009\n"); + fprintf(stdout, "USAGE: broadcaster [-p tcp_port] [-s TCP|UDP] [-f config_file_name] [-m mtu_size] -d [debug]\n"); + fprintf(stdout, "\tIndicate the location of the configuration file either with a TCP port number or a file name\n"); + fprintf(stdout, "\tmtu_size : the MTU size (default = 1492)\n"); + fprintf(stdout, "\t-s or --socket-type-for-updates : connection type for updates (UDP by default)\n"); + fprintf(stdout, "\tdebug: OR debug mask (broadcaster = 1, scene_generator=2, sdp_generator=4, ALL=31)\n"); } -/* fonction pour envoyer les messages RAP */ u32 RAP_send(void *par) { RAP_Input *input = par; @@ -75,33 +105,62 @@ u32 RAP_send(void *par) u32 *timer; input->status = 1; - while(input->status==1) { - // mutex avec le thread qui envoie les RAP pour l'envoi avec carrousel - while(gf_mx_try_lock(input->carrousel_mutex) == 0) - { - gf_sleep(1); - } - // locking - // gf_mx_p(input->carrousel_mutex); - // ici il faut integrer la fonction du carrousel pour envoyer RAP - /* envoi de RAP */ + while (input->status==1) { + gf_mx_p(input->carrousel_mutex); + timer = input->RAPtimer; data->RAPsent++; - fprintf(stdout, "[broadcaster] : RAP %d seconds\n", *(input->RAPtimer)); // *timer); - data->RAP=1; //On demande que RAP soit positionné dans le SL - fprintf(stdout, "[gpaclib] : "); - gf_beng_aggregate_context(data->codec); - gf_beng_encode_context(data->codec, SampleCallBack); - // unlocking + dprintf(DEBUG_broadcaster, "Sending RAP, will sleep for %d seconds\n", *timer); + data->RAP = 1; + gf_seng_aggregate_context(data->codec, 0); + gf_seng_encode_context(data->codec, SampleCallBack); + gf_mx_v(input->carrousel_mutex); - // gf_sleep(input->RAPtimer); - gf_sleep(*timer*1000); + gf_sleep((*timer)*1000); } input->status = 2; return GF_OK; } -/* gestion tcp pour interface gui */ +GF_Err parse_config(GF_Config *gf_config_file, CONF_Data *conf, int debug) +{ + conf->scene_init_file = gf_cfg_get_key(gf_config_file, MAIN_SECTION, SCENE_INIT); + if (!conf->scene_init_file) { + fprintf(stderr, "Cannot find initial scene from configuration file\n"); + return GF_IO_ERR; + } else { + dprintf(DEBUG_broadcaster, "Using initial scene: %s\n", conf->scene_init_file); + } + + conf->rap_timer = gf_cfg_get_key(gf_config_file, MAIN_SECTION, RAP_TIMER); + if (!conf->rap_timer) conf->rap_timer = "2"; + dprintf(DEBUG_broadcaster, "Using a RAP period of %s seconds\n", conf->rap_timer); + + conf->config_input_port = gf_cfg_get_key(gf_config_file, MAIN_SECTION, PORT_CONFIG); + if (!conf->config_input_port) conf->config_input_port = "5000"; + dprintf(DEBUG_broadcaster, "Using Configuration Port: %s\n", conf->config_input_port); + + conf->modif_input_port = gf_cfg_get_key(gf_config_file, MAIN_SECTION, PORT_MODIF); + if (!conf->modif_input_port) + conf->modif_input_port = "8000"; + dprintf(DEBUG_broadcaster, "Using Update Port: %s\n", conf->modif_input_port); + + conf->dest_ip = gf_cfg_get_key(gf_config_file, DEST_SECTION, DEST_ADDRESS); + if (!conf->dest_ip) + conf->dest_ip = "127.0.0.1"; + conf->dest_port = gf_cfg_get_key(gf_config_file, DEST_SECTION, PORT_OUTPUT); + if (!conf->dest_port) + conf->dest_port = "7000"; + dprintf(DEBUG_broadcaster, "Destination: %s:%s\n", conf->dest_ip, conf->dest_port); + + conf->feedback_ip = gf_cfg_get_key(gf_config_file, FEEDBACK_SECTION, IP_FEEDBACK); + if (!conf->feedback_ip) conf->feedback_ip = "127.0.0.1"; + conf->feedback_port = gf_cfg_get_key(gf_config_file, FEEDBACK_SECTION, PORT_FEEDBACK); + if (!conf->feedback_port) conf->feedback_port = "5757"; + dprintf(DEBUG_broadcaster, "Feedback host: %s:%s\n", conf->feedback_ip, conf->feedback_port); + return GF_OK; +} + u32 tcp_server(void *par) { TCP_Input *input = par; @@ -116,15 +175,17 @@ u32 tcp_server(void *par) GF_Socket *conn_socket; GF_Err e; + int debug = input->debug; input->status = 1; TCP_socket = gf_sk_new(GF_SOCK_TYPE_TCP); e = gf_sk_bind(TCP_socket, NULL, input->port, NULL, 0, 0); e = gf_sk_listen(TCP_socket, 1); - e = gf_sk_set_block_mode(TCP_socket, 0); + e = gf_sk_set_block_mode(TCP_socket, 1); e = gf_sk_server_mode(TCP_socket, 0); - while(input->status == 1) { + while(input->status == 1) + { memset(buffer, 0, sizeof(buffer)); e = gf_sk_accept(TCP_socket, &conn_socket); if (e == GF_OK) { @@ -133,25 +194,23 @@ u32 tcp_server(void *par) } switch (e) { - case GF_IP_NETWORK_EMPTY: - gf_sleep(33); - continue; - case GF_OK: - break; - default: - fprintf(stdout, "[broadcaster] : Error with TCP socket : %d\n", e); - exit(1); - break; + case GF_IP_NETWORK_EMPTY: + gf_sleep(33); + continue; + case GF_OK: + break; + default: + fprintf(stderr, "Error with TCP socket : %s\n", gf_error_to_string(e)); + exit(1); + break; } - if((*(input->config_flag)) == 0) { - + if((*(input->config_flag)) == 0) + { u32 num_retry; - - /* waiting for the configuration info */ fp = fopen("temp.cfg", "w+"); if (!fp) { - fprintf(stdout, "[broadcaster] : Error opening temp file for the configuration\n"); + fprintf(stderr, "Error opening temp file for the configuration\n"); exit(1); } ret = fwrite(buffer, 1, byte_read, fp); @@ -159,48 +218,38 @@ u32 tcp_server(void *par) /* parsing config info */ gf_config_file = gf_cfg_new(".", "temp.cfg"); - input->config->scene_init_file = gf_cfg_get_key(gf_config_file, MAIN_SECTION, SCENE_INIT); - input->config->rap_timer = gf_cfg_get_key(gf_config_file, MAIN_SECTION, RAP_TIMER); - input->config->config_input_port = gf_cfg_get_key(gf_config_file, MAIN_SECTION, PORT_CONFIG); - input->config->modif_input_port = gf_cfg_get_key(gf_config_file, MAIN_SECTION, PORT_MODIF); - - input->config->dest_ip = gf_cfg_get_key(gf_config_file, DEST_SECTION, DEST_ADDRESS); - input->config->dest_port = gf_cfg_get_key(gf_config_file, DEST_SECTION, PORT_OUTPUT); - - input->config->feedback_ip = gf_cfg_get_key(gf_config_file, FEEDBACK_SECTION, IP_FEEDBACK); - input->config->feedback_port = gf_cfg_get_key(gf_config_file, FEEDBACK_SECTION, PORT_FEEDBACK); - + if (!gf_config_file) { + fprintf(stderr, "Error opening the config file %s\n", gf_error_to_string(e)); + exit(-1); + } + parse_config(gf_config_file, input->config, debug); + /* Acknowledging the configuration */ gf_sk_send(conn_socket, "OK\n", 3); memset(temp, 0, sizeof(temp)); fp = fopen(input->config->scene_init_file, "w+"); if (!fp) { - fprintf(stdout, "[broadcaster] : Error opening temp file for the initial scene\n"); + fprintf(stderr, "Error opening temp file for reception of the initial scene\n"); exit(1); } num_retry=10; - while (1) { - + while (1) + { GF_Err e = gf_sk_receive(conn_socket, temp, sizeof(temp), 0, &byte_read); if (e == GF_OK) { fwrite(temp, 1, byte_read, fp); - } else if (e==GF_IP_NETWORK_EMPTY) { - num_retry--; - if (!num_retry) - break; - gf_sleep(1); - - } else - + } else { + fprintf(stderr, "Error receiving initial scene: %s\n", gf_error_to_string(e)); break; + } } fclose(fp); *(input->config_flag) = 1; @@ -208,7 +257,7 @@ u32 tcp_server(void *par) /* we only wait now for the config updates */ if ( (*(input->config_flag)) == 1) { ret = sscanf(buffer, "DelaiMax=%d\n", timer); - fprintf(stdout, "[broadcaster] : RAP timer changed, now : %d\n", *timer); + fprintf(stdout, "RAP timer changed, now : %d\n", *timer); } gf_sk_del(conn_socket); } @@ -220,145 +269,154 @@ u32 tcp_server(void *par) u8 get_a_char(); Bool has_input(); -int main (int argc, char** argv) +int main (const int argc, const char** argv) { GF_Err e; Bool run; - int tcp_port; - u32 config_flag; // pour savoir s'il faut lire la configuration du fichier ou de l'interface - char config_file[MAX_BUF]; - TCP_Input *tcp_conf; - RAP_Input *rap_conf; - CONF_Data *conf; - - /* parametres de configuration */ - GF_Config *gf_config_file; + /* location of the configuration file: 0 wait for config on a socket, 1 use the given file */ + u32 config_flag; + char config_file_name[MAX_BUF]; + + int dest_port; + unsigned short tcp_port = 0; + /* Should be fine on WIFI network */ + unsigned short mtu_size = 1492; + int debug = 0; + TCP_Input *tcp_conf = NULL; GF_Thread *tcp_thread; - GF_Thread *rap_thread; GF_Err th_err_tcp; + GF_Err th_err_rap; + RAP_Input *rap_conf; + GF_Thread *rap_thread; + + CONF_Data *conf; + GF_Config *gf_config_file; GF_Err res; GF_Socket *UDP_feedback_socket; + u32 socketType_for_updates; PNC_CallbackData * data; GF_RTPChannel * chan; - GF_RTPHeader hdr; - u32 timer; + GF_RTPHeader hdr; + u32 timer = -1; - GF_Mutex *carrousel_mutex; // objet en mutex + GF_Mutex *carrousel_mutex; char sdp_fmt[5000]; + tcp_thread = NULL; /* init gpac lib */ gf_sys_init(); + gf_log_set_level(GF_LOG_ERROR); + gf_log_set_tools(GF_LOG_NETWORK|GF_LOG_RTP|GF_LOG_SCENE|GF_LOG_PARSER|GF_LOG_AUTHOR|GF_LOG_CODING|GF_LOG_SCRIPT); - /* allocation structures */ - GF_SAFEALLOC(tcp_conf, TCP_Input) - GF_SAFEALLOC(rap_conf, RAP_Input) - GF_SAFEALLOC(conf, CONF_Data) + GF_SAFEALLOC(conf, CONF_Data); - /* gestion la ligne de commande */ tcp_port = config_flag = 0; - command_line_parsing(&argc, argv, &tcp_port, config_file, (int *) &config_flag); - // fprintf(stdout, "[broadcaster] : tcp:%d, udp:%d, config_flag:%d\n", tcp_port, udp_port, config_flag); - - /* controle si les deux parametres necessaires ont ete specifies */ - tcp_conf->config_flag = &config_flag; - + socketType_for_updates = GF_SOCK_TYPE_UDP; + if (command_line_parsing(argc, argv, &tcp_port, config_file_name, (int *) &config_flag, &mtu_size, &debug, &socketType_for_updates)){ + print_usage(); + return -1; + } + setDebugMode( debug ); gf_config_file = NULL; - - /* controle pour savoir ou il faut prendre la configuration */ - if(config_flag == 1) + if (config_flag == 1) { - /* ici il faut lire du fichier de configuration */ - gf_config_file = gf_cfg_new(NULL, config_file); - conf->scene_init_file = gf_cfg_get_key(gf_config_file, MAIN_SECTION, SCENE_INIT); - conf->rap_timer = gf_cfg_get_key(gf_config_file, MAIN_SECTION, RAP_TIMER); - conf->config_input_port = gf_cfg_get_key(gf_config_file, MAIN_SECTION, PORT_CONFIG); + char *cfg_path; + char *cfg_fname; + char *tmp; + + cfg_fname = config_file_name; + cfg_path = config_file_name; + tmp = strrchr(cfg_fname, GF_PATH_SEPARATOR); + if (tmp) { + cfg_fname = tmp+1; + tmp[0] = 0; + } else { + cfg_path = "."; + } + gf_config_file = gf_cfg_new(cfg_path, cfg_fname); + if (!gf_config_file) { + fprintf(stderr, "Cannot open config file %s\n", config_file_name); + return -1; + } else { + dprintf(DEBUG_broadcaster, "Using config file %s.\n", config_file_name); + } + if (parse_config(gf_config_file, conf, debug)) return -1; tcp_port = atoi(conf->config_input_port); - conf->modif_input_port = gf_cfg_get_key(gf_config_file, MAIN_SECTION, PORT_MODIF); - - conf->dest_ip = gf_cfg_get_key(gf_config_file, DEST_SECTION, DEST_ADDRESS); - conf->dest_port = gf_cfg_get_key(gf_config_file, DEST_SECTION, PORT_OUTPUT); - - conf->feedback_ip = gf_cfg_get_key(gf_config_file, FEEDBACK_SECTION, IP_FEEDBACK); - conf->feedback_port = gf_cfg_get_key(gf_config_file, FEEDBACK_SECTION, PORT_FEEDBACK); } - - // thread pour ecouter les données de l'interface tcp (et configuration si config_flag == 0) - - // il faut definir le poineur ici pour que apres tout ça marche bien - tcp_conf->RAPtimer = &timer; - tcp_conf->port = tcp_port; - tcp_conf->config = conf; // dans le cas ou on prend la configuration de l'interface ici on peut modifier les donnees - tcp_thread = gf_th_new("TCPInterface"); - th_err_tcp = gf_th_run(tcp_thread, tcp_server, tcp_conf); - - if(config_flag == 0) - fprintf(stdout, "[broadcast] : en attente de la configuration de l'interface...\n"); + else + { + GF_SAFEALLOC(tcp_conf, TCP_Input); + tcp_conf->config_flag = &config_flag; + tcp_conf->RAPtimer = &timer; + tcp_conf->port = tcp_port; + tcp_conf->config = conf; + tcp_thread = gf_th_new("TCPInterface"); + + /* Starting the thread which will write the received config in a temporary file */ + th_err_tcp = gf_th_run(tcp_thread, tcp_server, tcp_conf); + + fprintf(stdout, "Waiting for configuration on port %d...\n", tcp_conf->port); - // ici il faut attendre que les donnees arrivent de l'interface - while(config_flag == 0) - { - gf_sleep(1000); + while(config_flag == 0) { + gf_sleep(1000); + } + fprintf(stdout, "Configuration File received. Starting Streaming ...\n"); } - fprintf(stdout, "[broadcast] : configuration OK, init serveur\n"); - // setting the timer RAP - // cette partie change dans le cas ou on prend la configuratoin de l'interface timer = atoi(conf->rap_timer); - - // a ce point la nous avons la configuration du serveur - // initialisation carrousel - // Initialisation de la connexion - // ici il faut donner un adresse de broadcast - res = PNC_InitRTP(&chan, (char *)conf->dest_ip, atoi(conf->dest_port)); - if (res != 0) - { - printf("[carrousel] : erreur d'initialisation RTP -> M4Err = %d\n", res); + dest_port = atoi(conf->dest_port); + res = PNC_InitRTP(&chan, (char *)conf->dest_ip, dest_port, mtu_size); + if (res != 0) { + fprintf(stderr, "Cannot initialize RTP output (error: %d)\n", res); exit(1); } - - // objet mutex + carrousel_mutex = gf_mx_new("Carrousel"); - - // recupere l'objet data, necessaire pour toutes operations du carrousel - data = PNC_Init_SceneGenerator(chan, &hdr, (char *) conf->scene_init_file, atoi(conf->modif_input_port)); // la generation de scene - data->carrousel_mutex = carrousel_mutex; // ici on passe l'objet mutex à l'objet data + data = PNC_Init_SceneGenerator(chan, &hdr, (char *) conf->scene_init_file, + socketType_for_updates, (u16) atoi(conf->modif_input_port), debug); + if (!data) { + fprintf(stderr, "Cannot initialize Scene Generator\n"); + exit(1); + } + data->carrousel_mutex = carrousel_mutex; data->RAPsent = 1; - // preparation du socket pour envoyer le données de débit à l'interface UDP_feedback_socket = gf_sk_new(GF_SOCK_TYPE_UDP); - e = gf_sk_bind(UDP_feedback_socket, NULL, (u16) atoi(conf->feedback_port), (char *) conf->feedback_ip, (u16) atoi(conf->feedback_port), 0); - // fprintf(stdout, "[broadcaster] : bind udp for feedback : %d, port : %d\n", e, atoi(port_feedback)); - //e = gf_sk_connect(UDP_feedback_socket, (char *) conf->feedback_ip, (u16) atoi(conf->feedback_port, NULL)); - // fprintf(stdout, "[broadcaster] : connect udp feedback socket : %d, host : %s\n", e, ip_feedback); - gf_sk_set_block_mode(UDP_feedback_socket, 0); + e = gf_sk_bind(UDP_feedback_socket, NULL, (u16)atoi(conf->feedback_port), (char*)conf->feedback_ip, (u16)atoi(conf->feedback_port), 0); + if (e) { + fprintf(stderr, "Cannot bind socket for bitrate feedback information (%s)\n", gf_error_to_string(e)); + } else { + e = gf_sk_set_block_mode(UDP_feedback_socket, 1); + if (e) { + fprintf(stderr, "Cannot set feedback socket block mode (%s)\n", gf_error_to_string(e)); + } + } data->feedback_socket = UDP_feedback_socket; - PNC_InitPacketiser(data, sdp_fmt); // le packetiser, qui initialise le RTPBuilder, les headers, etc. - PNC_SendInitScene(data); // ici on envoie le RAP initial + PNC_InitPacketiser(data, sdp_fmt, mtu_size); + PNC_SendInitScene(data); - // ouvrir thread boucle pour envoi rap + GF_SAFEALLOC(rap_conf, RAP_Input); rap_conf->RAPtimer = &timer; - rap_conf->carrousel_mutex = carrousel_mutex; // ici on passe l'objet mutex + rap_conf->carrousel_mutex = carrousel_mutex; rap_conf->data = data; rap_thread = gf_th_new("RAPGenerator"); th_err_rap = gf_th_run(rap_thread, RAP_send, rap_conf); - // generation du fichier SDP - sdp_generator(data, conf->dest_ip, sdp_fmt); + sdp_generator(data, (char *)conf->dest_ip, sdp_fmt); - // udp boucle pour les données de modification run = 1; - while (run) { - - // cette fonction est modifié par rapport à la fonction du carrousel normale - // car elle integre le control sur la variable mutex pour envoyer en exclusion - // avec le thread des RAP + while (run) + { GF_Err e = PNC_processBIFSGenerator(data); - if (e) break; + if (e) { + fprintf(stderr, "Cannot Process BIFS data (%s)\n", gf_error_to_string(e)); + break; + } if (has_input()) { char c = get_a_char(); @@ -370,34 +428,35 @@ int main (int argc, char** argv) } gf_sleep(10); } + + /* waiting for termination of the RAP thread */ rap_conf->status = 0; while (rap_conf->status != 2) gf_sleep(0); + gf_free(rap_conf); + gf_th_del(rap_thread); - tcp_conf->status = 0; - while (tcp_conf->status != 2) - gf_sleep(0); + /* waiting for termination of the TCP listening thread */ + if (tcp_conf) { + tcp_conf->status = 0; + while (tcp_conf->status != 2) + gf_sleep(0); + gf_free(tcp_conf); + gf_th_del(tcp_thread); + } - /* nettoyage final */ PNC_Close_SceneGenerator(data); - free(tcp_conf); - free(rap_conf); - free(conf); - fprintf(stdout, "[broadcaster] : structures freed\n"); + gf_free(conf); if (gf_config_file) gf_cfg_del(gf_config_file); - gf_delete_file("temp.cfg"); - - gf_th_del(tcp_thread); - gf_th_del(rap_thread); gf_mx_del(carrousel_mutex); gf_sys_close(); return 0; } - /*seems OK under mingw also*/ + #ifdef WIN32 #include #include @@ -479,10 +538,11 @@ u8 get_a_char() close_keyboard(1); return ch; } - read(0,&ch,1); + int v = read(0,&ch,1); close_keyboard(1); + if (v == 0) + return 0; return ch; } #endif - diff --git a/applications/testapps/broadcaster/broadcaster.dsp b/applications/testapps/broadcaster/broadcaster.dsp index a0890b7..2edf9c5 100644 --- a/applications/testapps/broadcaster/broadcaster.dsp +++ b/applications/testapps/broadcaster/broadcaster.dsp @@ -1,138 +1,146 @@ -# Microsoft Developer Studio Project File - Name="broadcaster" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=broadcaster - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "broadcaster.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "broadcaster.mak" CFG="broadcaster - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "broadcaster - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "broadcaster - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "broadcaster - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "broadcaster - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 zlib.lib winmm.lib ws2_32.lib user32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/broadcaster.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "broadcaster - Win32 Release" -# Name "broadcaster - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\broadcaster.c -# End Source File -# Begin Source File - -SOURCE=.\RTP_serv_generator.c -# End Source File -# Begin Source File - -SOURCE=.\RTP_serv_packetizer.c -# End Source File -# Begin Source File - -SOURCE=.\RTP_serv_sender.c -# End Source File -# Begin Source File - -SOURCE=.\sdp_generator.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\broadcaster.h -# End Source File -# Begin Source File - -SOURCE=.\RTP_serv_generator.h -# End Source File -# Begin Source File - -SOURCE=.\RTP_serv_packetizer.h -# End Source File -# Begin Source File - -SOURCE=.\RTP_serv_sender.h -# End Source File -# Begin Source File - -SOURCE=.\sdp_generator.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="broadcaster" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=broadcaster - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "broadcaster.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "broadcaster.mak" CFG="broadcaster - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "broadcaster - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "broadcaster - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "broadcaster - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "broadcaster - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 zlib.lib winmm.lib ws2_32.lib user32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/broadcaster.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" + +!ENDIF + +# Begin Target + +# Name "broadcaster - Win32 Release" +# Name "broadcaster - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\broadcaster.c +# End Source File +# Begin Source File + +SOURCE=.\debug.c +# End Source File +# Begin Source File + +SOURCE=.\RTP_serv_generator.c +# End Source File +# Begin Source File + +SOURCE=.\RTP_serv_packetizer.c +# End Source File +# Begin Source File + +SOURCE=.\RTP_serv_sender.c +# End Source File +# Begin Source File + +SOURCE=.\sdp_generator.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\broadcaster.h +# End Source File +# Begin Source File + +SOURCE=.\debug.h +# End Source File +# Begin Source File + +SOURCE=.\RTP_serv_generator.h +# End Source File +# Begin Source File + +SOURCE=.\RTP_serv_packetizer.h +# End Source File +# Begin Source File + +SOURCE=.\RTP_serv_sender.h +# End Source File +# Begin Source File + +SOURCE=.\sdp_generator.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/applications/testapps/broadcaster/broadcaster.h b/applications/testapps/broadcaster/broadcaster.h index d999d10..8bb17d4 100644 --- a/applications/testapps/broadcaster/broadcaster.h +++ b/applications/testapps/broadcaster/broadcaster.h @@ -3,8 +3,8 @@ #include #include -/* includes pour gpac library*/ -#include +/* includes for gpac library */ +#include #include #include #include @@ -15,21 +15,21 @@ #include #include -/* include pour carrousel BIFS */ -/* pour les envois RTP */ +/* includes for BIFS carousel */ +/* RTP sends */ #include "RTP_serv_sender.h" -/* pour la mise en paquets */ +/* packetization */ #include "RTP_serv_packetizer.h" -/* le module applicatif */ +/* applicative module */ #include "RTP_serv_generator.h" -/* include pour SDP generation */ +/* for SDP generation */ #include "sdp_generator.h" /* definitions */ #define MAX_BUF 4096 -/* données de configuration */ +/* configuration data*/ #define MAIN_SECTION "Broadcaster" #define SCENE_INIT "InitialScene" #define RAP_TIMER "RAPPeriod" @@ -44,7 +44,7 @@ #define IP_FEEDBACK "IP" #define PORT_FEEDBACK "Port" -/* structure pour les données de configuration du serveur */ +/* data struct on the server side */ typedef struct config_data { const char *rap_timer; @@ -61,12 +61,13 @@ typedef struct config_data typedef struct tcp_input { - u16 port; // port sur laquelle ouvrir le serveur - u32 *config_flag; // pour savoir si le serveur tcp doit attendre donnees de configuration - // GF_Socket *socket; // socket tcp pour l'interface + u16 port; // server port + u32 *config_flag; // indicates whether the tcp server waits for configuration data + // GF_Socket *socket; // socket tcp for the GUI interface u32 *RAPtimer; CONF_Data *config; u32 status; + int debug; } TCP_Input; typedef struct rap_input @@ -77,8 +78,8 @@ typedef struct rap_input u32 status; } RAP_Input; -void command_line_parsing(int* argc, char** argv, int *tcp_port, char *config_file, int *config_flag); -int server_command_line(char *arg_a, char *arg_b, char *value, int argument); +/*void command_line_parsing(int* argc, const char** argv, int *tcp_port, const char *config_file, int *config_flag); +int server_command_line(char *arg_a, char *arg_b, char *value, int argument);*/ u32 tcp_server(void *par); u32 RAP_send(void *par); void print_usage(void); diff --git a/applications/testapps/broadcaster/broadcaster_config.cfg b/applications/testapps/broadcaster/broadcaster_config.cfg index c132771..50c802d 100644 --- a/applications/testapps/broadcaster/broadcaster_config.cfg +++ b/applications/testapps/broadcaster/broadcaster_config.cfg @@ -1,14 +1,16 @@ [Broadcaster] -InitialScene=meteo_local.xmt +InitialScene=/var/www/initial.bt RAPPeriod=2 -ConfigPort=5000 -SceneUpdatePort=8000 +ConfigPort=5500 +SceneUpdatePort=8100 [Destination] #IP=233.64.133.10 -IP=137.194.232.99 -Port=7000 +#IP=137.194.232.99 +IP=127.0.0.1 +Port=7100 [Feedback] -IP=137.194.232.99 -Port=5757 +#IP=137.194.232.99 +IP=127.0.0.1 +Port=5758 diff --git a/applications/testapps/broadcaster/debug.c b/applications/testapps/broadcaster/debug.c new file mode 100644 index 0000000..a2a28aa --- /dev/null +++ b/applications/testapps/broadcaster/debug.c @@ -0,0 +1,24 @@ +#include "debug.h" +#include +#include + +static int _broadcaster_debug = 0; + +void setDebugMode(int mode) +{ + _broadcaster_debug = mode; +} + +int getDebugMode() +{ + return _broadcaster_debug; +} + +void dprintf(debugMode debug, const char *msg, ...) +{ + va_list ap; + va_start( ap, msg ); + if ((debug & _broadcaster_debug) == debug) + vfprintf(stderr, msg, ap); + va_end(ap); +} diff --git a/applications/testapps/broadcaster/debug.h b/applications/testapps/broadcaster/debug.h new file mode 100644 index 0000000..4b4da6e --- /dev/null +++ b/applications/testapps/broadcaster/debug.h @@ -0,0 +1,18 @@ +#ifndef _BROADCASTER_DEBUG_H +#define _BROADCASTER_DEBUG_H + +typedef enum _debugMode { + DEBUG_broadcaster = 1, + DEBUG_RTP_serv_generator = 2, + DEBUG_RTP_serv_packetizer =4, + DEBUG_RTP_serv_sender = 8, + DEBUG_sdp_generator = 16 +} debugMode; + +void setDebugMode(int mode); + +int getDebugMode(); + +void dprintf(debugMode debug, const char *msg, ...); + +#endif diff --git a/applications/testapps/broadcaster/meteo_local.xmt b/applications/testapps/broadcaster/meteo_local.xmt index 1feaa3a..7749589 100644 --- a/applications/testapps/broadcaster/meteo_local.xmt +++ b/applications/testapps/broadcaster/meteo_local.xmt @@ -390,3 +390,4 @@ + diff --git a/applications/testapps/broadcaster/sdp_generator.c b/applications/testapps/broadcaster/sdp_generator.c index 01066bc..0cd7f89 100644 --- a/applications/testapps/broadcaster/sdp_generator.c +++ b/applications/testapps/broadcaster/sdp_generator.c @@ -1,9 +1,10 @@ #include "sdp_generator.h" +#include "debug.h" -int sdp_generator(PNC_CallbackData * data, char *ip_dest, char *sdp_fmt) +int sdp_generator(PNC_CallbackData *data, char *ip_dest, char *sdp_fmt) { - GF_BifsEngine *codec; - GF_ESD *esd; + GF_SceneEngine *codec; + GF_ESD *esd = NULL; u32 size,size64; char *buffer; char buf64[5000]; @@ -13,22 +14,18 @@ int sdp_generator(PNC_CallbackData * data, char *ip_dest, char *sdp_fmt) u16 port; u32 socket_type; - // fonctions necessaires pour recuperer les informations necessaires a la construction du fichier gf_sk_get_local_info(data->chan->rtp, &port, &socket_type); - // fprintf(stdout, "%s --------- %d\n", ip_adresse, port); fp = fopen("broadcaster.sdp", "w+"); - if(fp == NULL) - { - fprintf(stdout, "[broadcaster] : erreur, probleme a ouvrir file temp pour scene initiale\n"); + if(fp == NULL) { + fprintf(stderr, "Cannot open SDP file broadcaster.sdp\n"); exit(1); } - // ecriture du fichier SDP + ret = fwrite("v=0\n", 1, 4, fp); - sprintf(temp, "o=GpacBroadcaster 3326096807 1117107880000 IN IP%d %s\n", gf_net_is_ipv6(ip_dest) ? 6 : 4, ip_dest); ret = fwrite(temp, 1, strlen(temp), fp); - + ret = fwrite("s=MPEG4Broadcaster\n", 1, 19, fp); sprintf(temp, "c=IN IP%d %s\n", gf_net_is_ipv6(ip_dest) ? 6 : 4, ip_dest); @@ -36,36 +33,35 @@ int sdp_generator(PNC_CallbackData * data, char *ip_dest, char *sdp_fmt) ret = fwrite("t=0 0\n", 1, 6, fp); - // GF_BIFSEngine - codec = (GF_BifsEngine *) data->codec; - buffer = NULL; - size = 0; - gf_odf_desc_write((GF_Descriptor *) codec->ctx->root_od, &buffer, &size); - esd = gf_list_get(codec->ctx->root_od->ESDescriptors, 0); + codec = (GF_SceneEngine *) data->codec; + if (codec) { + buffer = NULL; + size = 0; + gf_odf_desc_write((GF_Descriptor *) codec->ctx->root_od, &buffer, &size); + esd = gf_list_get(codec->ctx->root_od->ESDescriptors, 0); - //encode in Base64 the iod - size64 = gf_base64_encode((unsigned char *) buffer, size, (unsigned char *) buf64, 2000); - // size64 = gf_base64_encode(buffer, size, buf64, 2000); - buf64[size64] = 0; - free(buffer); + size64 = gf_base64_encode((unsigned char *) buffer, size, (unsigned char *) buf64, 2000); + buf64[size64] = 0; + free(buffer); - // fprintf(stdout, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"\n", buf64); - sprintf(temp, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"\n", buf64); - ret = fwrite(temp, 1, strlen(temp), fp); + sprintf(temp, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"\n", buf64); + ret = fwrite(temp, 1, strlen(temp), fp); + } sprintf(temp, "m=application %d RTP/AVP 96\n", port); ret = fwrite(temp, 1, strlen(temp), fp); ret = fwrite("a=rtpmap:96 mpeg4-generic/1000\n", 1, 31, fp); - sprintf(temp, "a=mpeg4-esid:%d\n", esd->ESID); - ret = fwrite(temp, 1, strlen(temp), fp); + if (esd) { + sprintf(temp, "a=mpeg4-esid:%d\n", esd->ESID); + ret = fwrite(temp, 1, strlen(temp), fp); + } - // fprintf(stdout, "%s\n", sdp_fmt); sprintf(temp, "%s\n", sdp_fmt); ret = fwrite(temp, 1, strlen(temp), fp); - + fflush(fp); fclose(fp); - fprintf(stdout, "[sdp generator] : fichier SDP generater in broadcaster.sdp\n"); + dprintf(DEBUG_sdp_generator, "SDP file generated in broadcaster.sdp\n"); return GF_OK; } diff --git a/applications/testapps/broadcaster/sdp_generator.h b/applications/testapps/broadcaster/sdp_generator.h index 9ce41fd..7742591 100644 --- a/applications/testapps/broadcaster/sdp_generator.h +++ b/applications/testapps/broadcaster/sdp_generator.h @@ -2,12 +2,12 @@ #include #include #include -#include +#include #include #include #include "RTP_serv_generator.h" -/* definitions des structures */ +/* structure definitions */ struct __tag_bifs_engine { GF_SceneGraph *sg; @@ -26,4 +26,4 @@ struct __tag_bifs_engine u32 encoded_bifs_config_size; }; -int sdp_generator(PNC_CallbackData * data, char *ip_dest, char *sdp_fmt); +int sdp_generator(PNC_CallbackData *data, char *ip_dest, char *sdp_fmt); diff --git a/applications/testapps/dmbrs/dmbrs.dsp b/applications/testapps/dmbrs/dmbrs.dsp index 8ae463f..a94c742 100644 --- a/applications/testapps/dmbrs/dmbrs.dsp +++ b/applications/testapps/dmbrs/dmbrs.dsp @@ -1,90 +1,90 @@ -# Microsoft Developer Studio Project File - Name="dmbrs" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=dmbrs - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "dmbrs.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "dmbrs.mak" CFG="dmbrs - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "dmbrs - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "dmbrs - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "dmbrs - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 zlib.lib winmm.lib /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/dmbrs.exe" /libpath:"../../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "dmbrs - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 zlib.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/dmbrs.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "dmbrs - Win32 Release" -# Name "dmbrs - Win32 Debug" -# Begin Source File - -SOURCE=.\main.c -# End Source File -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="dmbrs" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=dmbrs - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "dmbrs.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "dmbrs.mak" CFG="dmbrs - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "dmbrs - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "dmbrs - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "dmbrs - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 zlib.lib winmm.lib /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/dmbrs.exe" /libpath:"../../../extra_lib/lib/w32_rel" + +!ELSEIF "$(CFG)" == "dmbrs - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 zlib.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/dmbrs.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" + +!ENDIF + +# Begin Target + +# Name "dmbrs - Win32 Release" +# Name "dmbrs - Win32 Debug" +# Begin Source File + +SOURCE=.\main.c +# End Source File +# End Target +# End Project diff --git a/applications/testapps/largefile/largefile.dsp b/applications/testapps/largefile/largefile.dsp index e6b0c21..3a568ad 100644 --- a/applications/testapps/largefile/largefile.dsp +++ b/applications/testapps/largefile/largefile.dsp @@ -1,102 +1,102 @@ -# Microsoft Developer Studio Project File - Name="largefile" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=largefile - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "largefile.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "largefile.mak" CFG="largefile - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "largefile - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "largefile - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "largefile - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 winmm.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "largefile - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "largefile - Win32 Release" -# Name "largefile - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\main.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="largefile" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=largefile - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "largefile.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "largefile.mak" CFG="largefile - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "largefile - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "largefile - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "largefile - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 winmm.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "largefile - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "largefile - Win32 Release" +# Name "largefile - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\main.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/applications/testapps/largefile/largefile.dsw b/applications/testapps/largefile/largefile.dsw index 12e531a..d1ebaae 100644 --- a/applications/testapps/largefile/largefile.dsw +++ b/applications/testapps/largefile/largefile.dsw @@ -1,44 +1,44 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "largefile"=.\largefile.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac - End Project Dependency -}}} - -############################################################################### - -Project: "libgpac"=..\..\..\build\msvc6\libgpac.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "largefile"=.\largefile.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name libgpac + End Project Dependency +}}} + +############################################################################### + +Project: "libgpac"=..\..\..\build\msvc6\libgpac.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/applications/testapps/largefile/main.c b/applications/testapps/largefile/main.c index 8337f36..80ed26b 100644 --- a/applications/testapps/largefile/main.c +++ b/applications/testapps/largefile/main.c @@ -53,7 +53,7 @@ int main(int argc, char **argv) samp = gf_isom_sample_new(); samp->dataLength = 1024*1024; - samp->data = malloc(sizeof(char)*samp->dataLength); + samp->data = gf_malloc(sizeof(char)*samp->dataLength); memset(samp->data, 0, sizeof(char)*samp->dataLength); for (i=0; i -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=LoadCompare - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "LoadCompare.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "LoadCompare.mak" CFG="LoadCompare - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "LoadCompare - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "LoadCompare - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "LoadCompare - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "LoadCompare___Win32_Release" -# PROP BASE Intermediate_Dir "LoadCompare___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/loadcompare_rel" -# PROP Intermediate_Dir "obj/loadcompare_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /I "../../../extra_lib/include/zlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 zlib.lib winmm.lib libxml2.lib /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/LoadCompare.exe" /libpath:"../../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "LoadCompare - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "LoadCompare___Win32_Debug" -# PROP BASE Intermediate_Dir "LoadCompare___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/loadcompare_deb" -# PROP Intermediate_Dir "obj/loadcompare_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../extra_lib/include/zlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 zlib.lib winmm.lib libxml2.lib /nologo /subsystem:console /pdb:"obj/loadcompare_deb//LoadCompare.pdb" /debug /machine:I386 /out:"../../../bin/w32_deb/LoadCompare.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "LoadCompare - Win32 Release" -# Name "LoadCompare - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\loadcompare.c -# End Source File -# Begin Source File - -SOURCE=..\..\..\modules\svg_loader\lsr_parser.c -# End Source File -# Begin Source File - -SOURCE=..\..\..\modules\svg_loader\svg_parser.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="LoadCompare" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=LoadCompare - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "LoadCompare.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "LoadCompare.mak" CFG="LoadCompare - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "LoadCompare - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "LoadCompare - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "LoadCompare - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "LoadCompare___Win32_Release" +# PROP BASE Intermediate_Dir "LoadCompare___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "obj/loadcompare_rel" +# PROP Intermediate_Dir "obj/loadcompare_rel" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /I "../../../extra_lib/include/zlib" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 zlib.lib winmm.lib libxml2.lib /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/LoadCompare.exe" /libpath:"../../../extra_lib/lib/w32_rel" + +!ELSEIF "$(CFG)" == "LoadCompare - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "LoadCompare___Win32_Debug" +# PROP BASE Intermediate_Dir "LoadCompare___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "obj/loadcompare_deb" +# PROP Intermediate_Dir "obj/loadcompare_deb" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /I "../../../extra_lib/include/zlib" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 zlib.lib winmm.lib libxml2.lib /nologo /subsystem:console /pdb:"obj/loadcompare_deb//LoadCompare.pdb" /debug /machine:I386 /out:"../../../bin/w32_deb/LoadCompare.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "LoadCompare - Win32 Release" +# Name "LoadCompare - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\loadcompare.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\modules\svg_loader\lsr_parser.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\modules\svg_loader\svg_parser.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/applications/testapps/loadcompare/Makefile b/applications/testapps/loadcompare/Makefile index 11184a9..7f45d93 100644 --- a/applications/testapps/loadcompare/Makefile +++ b/applications/testapps/loadcompare/Makefile @@ -29,7 +29,7 @@ else EXT= PROG=LoadCompare #LINKFLAGS+=-lgpac_static $(EXTRALIBS) $(GPAC_SH_FLAGS) -lz -LINKFLAGS+=-lgpac -lz $(XML2_LFLAGS) +LINKFLAGS+=-lgpac -lz $(XML2_LIBS) endif diff --git a/applications/testapps/loadcompare/loadcompare.c b/applications/testapps/loadcompare/loadcompare.c index 35e9d8a..896cf98 100644 --- a/applications/testapps/loadcompare/loadcompare.c +++ b/applications/testapps/loadcompare/loadcompare.c @@ -584,7 +584,7 @@ Bool loadcompare_one(void *cbck, char *item_name, char *item_path) if (!lc->spread_repeat) { print_load_data(lc, ld); - free(ld); + gf_free(ld); } return 0; } @@ -664,7 +664,7 @@ int main(int argc, char **argv) loadcompare_one(&lc, tmp+1, in); ld = gf_list_get(lc.data, 0); print_load_data(&lc, ld); - free(ld); + gf_free(ld); } else { if (lc.spread_repeat) { for (lc.repeat_index = 0; lc.repeat_index < lc.nbloads; lc.repeat_index ++) { @@ -678,7 +678,7 @@ int main(int argc, char **argv) for (i=0; i #include +#include #include -#include "mp42ts.h" - -void usage() -{ - fprintf(stderr, "usage: mp42ts [options] dst\n" - "With options being: \n" - "-prog=FILE specifies an input file used for a TS service\n" - " * currently only supports ISO files and SDP files\n" - " * option can be used several times, once for each program\n" - "-rate=R specifies target rate in kbits/sec of the multiplex\n" - " If not set, transport stream will be of variable bitrate\n" - "-mpeg4 forces usage of MPEG-4 signaling (use of IOD and SL Config)\n" - "\n" - "dst can be a file, an RTP or a UDP destination (unicast/multicast)\n" - ); -} - -static GFINLINE void m2ts_dump_time(M2TS_Time *time, char *name) -{ - fprintf(stdout, "%s: %d%03d\n", name, time->sec, time->nanosec/1000000); -} -static GFINLINE Bool m2ts_time_less(M2TS_Time *a, M2TS_Time *b) { - if (a->sec>b->sec) return 0; - if (a->sec==b->sec) return (a->nanosecnanosec) ? 1 : 0; - return 1; -} -static GFINLINE Bool m2ts_time_less_or_equal(M2TS_Time *a, M2TS_Time *b) { - if (a->sec>b->sec) return 0; - if (a->sec==b->sec) return (a->nanosec>b->nanosec) ? 0 : 1; - return 1; -} - -static GFINLINE void m2ts_time_inc(M2TS_Time *time, u32 delta_inc_num, u32 delta_inc_den) -{ - u64 n_sec; - u32 sec; - - /*couldn't compute bitrate - we need to have more info*/ - if (!delta_inc_den) return; - - sec = delta_inc_num / delta_inc_den; - - if (sec) { - time->sec += sec; - sec *= delta_inc_den; - delta_inc_num = delta_inc_num % sec; - } - /*move to nanosec - 0x3B9ACA00 = 1000*1000*1000 */ - n_sec = delta_inc_num; - n_sec *= 0x3B9ACA00; - n_sec /= delta_inc_den; - time->nanosec += (u32) n_sec; - while (time->nanosec >= 0x3B9ACA00) { - time->nanosec -= 0x3B9ACA00; - time->sec ++; - } -} - -/************************************ - * Section-related functions - ************************************/ -void m2ts_mux_table_update(M2TS_Mux_Stream *stream, u8 table_id, u16 table_id_extension, - u8 *table_payload, u32 table_payload_length, - Bool use_syntax_indicator, Bool private_indicator, - Bool use_checksum) -{ - u32 overhead_size; - u32 offset; - u32 section_number, nb_sections; - M2TS_Mux_Table *table, *prev_table; - u32 maxSectionLength; - M2TS_Mux_Section *section, *prev_sec; - GF_BitStream *bs; - - /* check if there is already a table with that id */ - prev_table = NULL; - table = stream->tables; - while (table) { - if (table->table_id == table_id) { - /* if yes, we need to flush the table and increase the version number */ - M2TS_Mux_Section *sec = table->section; - while (sec) { - M2TS_Mux_Section *sec2 = sec->next; - free(sec->data); - free(sec); - sec = sec2; - } - table->version_number = (table->version_number + 1)%0x1F; - break; - } - prev_table = table; - table = table->next; - } - - if (!table) { - /* if no, the table is created */ - GF_SAFEALLOC(table, M2TS_Mux_Table); - table->table_id = table_id; - if (prev_table) prev_table->next = table; - else stream->tables = table; - } - - if (!table_payload_length) return; - - switch (table_id) { - case GF_M2TS_TABLE_ID_PMT: - case GF_M2TS_TABLE_ID_PAT: - case GF_M2TS_TABLE_ID_SDT_ACTUAL: - case GF_M2TS_TABLE_ID_SDT_OTHER: - case GF_M2TS_TABLE_ID_BAT: - maxSectionLength = 1024; - break; - case GF_M2TS_TABLE_ID_MPEG4_BIFS: - case GF_M2TS_TABLE_ID_MPEG4_OD: - maxSectionLength = 4096; - break; - default: - fprintf(stderr, "Cannot create sections for table with id %d\n", table_id); - return; - } - - overhead_size = SECTION_HEADER_LENGTH; - if (use_syntax_indicator) overhead_size += SECTION_ADDITIONAL_HEADER_LENGTH + CRC_LENGTH; - - section_number = 0; - nb_sections = 1; - while (nb_sections*(maxSectionLength - overhead_size) 1) - fprintf(stdout,"Warning: last section number for PMT shall be 0 !!\n"); - break; - default: - break; - } - - prev_sec = NULL; - offset = 0; - while (offset < table_payload_length) { - u32 remain; - GF_SAFEALLOC(section, M2TS_Mux_Section); - - remain = table_payload_length - offset; - if (remain > maxSectionLength - overhead_size) { - section->length = maxSectionLength; - } else { - section->length = remain + overhead_size; - } - - bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); - - /* first header (not included in section length */ - gf_bs_write_int(bs, table_id, 8); - gf_bs_write_int(bs, use_syntax_indicator, 1); - gf_bs_write_int(bs, private_indicator, 1); - gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */ - gf_bs_write_int(bs, section->length - SECTION_HEADER_LENGTH, 12); - - if (use_syntax_indicator) { - /* second header */ - gf_bs_write_int(bs, table_id_extension, 16); - gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */ - gf_bs_write_int(bs, table->version_number, 5); - gf_bs_write_int(bs, 1, 1); /* current_next_indicator = 1: we don't send version in advance */ - gf_bs_write_int(bs, section_number, 8); - section_number++; - gf_bs_write_int(bs, nb_sections-1, 8); - } - - gf_bs_write_data(bs, table_payload + offset, section->length - overhead_size); - offset += section->length - overhead_size; - - if (use_syntax_indicator) { - /* place holder for CRC */ - gf_bs_write_u32(bs, 0); - } - - gf_bs_get_content(bs, (char**) §ion->data, §ion->length); - gf_bs_del(bs); - - if (use_syntax_indicator) { - u32 CRC; - CRC = gf_crc_32(section->data,section->length-CRC_LENGTH); - section->data[section->length-4] = (CRC >> 24) & 0xFF; - section->data[section->length-3] = (CRC >> 16) & 0xFF; - section->data[section->length-2] = (CRC >> 8) & 0xFF; - section->data[section->length-1] = CRC & 0xFF; - } - - if (prev_sec) prev_sec->next = section; - else table->section = section; - prev_sec = section; - } - stream->current_table = stream->tables; - stream->current_section = stream->current_table->section; - stream->current_section_offset = 0; -} - -void m2ts_mux_table_update_mpeg4(M2TS_Mux_Stream *stream, u8 table_id, u16 table_id_extension, - u8 *table_payload, u32 table_payload_length, - Bool use_syntax_indicator, Bool private_indicator, - Bool use_checksum) -{ - GF_SLHeader hdr; - u32 overhead_size; - u32 offset, sl_size; - u32 section_number, nb_sections; - M2TS_Mux_Table *table, *prev_table; - /*max section length for MPEG-4 BIFS and OD*/ - u32 maxSectionLength = 4096; - M2TS_Mux_Section *section, *prev_sec; - GF_BitStream *bs; - - /* check if there is already a table with that id */ - prev_table = NULL; - table = stream->tables; - while (table) { - if (table->table_id == table_id) { - /* if yes, we need to flush the table and increase the version number */ - M2TS_Mux_Section *sec = table->section; - while (sec) { - M2TS_Mux_Section *sec2 = sec->next; - free(sec->data); - free(sec); - sec = sec2; - } - table->version_number = (table->version_number + 1)%0x1F; - break; - } - prev_table = table; - table = table->next; - } - - if (!table) { - /* if no, the table is created */ - GF_SAFEALLOC(table, M2TS_Mux_Table); - table->table_id = table_id; - if (prev_table) prev_table->next = table; - else stream->tables = table; - } - - if (!table_payload_length) return; - - overhead_size = SECTION_HEADER_LENGTH; - if (use_syntax_indicator) overhead_size += SECTION_ADDITIONAL_HEADER_LENGTH + CRC_LENGTH; - - section_number = 0; - nb_sections = 1; - hdr = stream->sl_header; - sl_size = gf_sl_get_header_size(&stream->ifce->sl_config, &hdr); - /*SL-packetized data doesn't fit in one section, we must repacketize*/ - if (sl_size + table_payload_length > maxSectionLength - overhead_size) { - nb_sections = 0; - offset = 0; - hdr.accessUnitEndFlag = 0; - while (offsetifce->sl_config, &hdr); - /*remove start flag*/ - hdr.accessUnitStartFlag = 0; - /*fill each section but beware of last packet*/ - offset += maxSectionLength - overhead_size - sl_size; - nb_sections++; - } - } - prev_sec = NULL; - offset = 0; - hdr = stream->sl_header; - while (offset < table_payload_length) { - u32 remain; - char *slhdr; - u32 slhdr_size; - GF_SAFEALLOC(section, M2TS_Mux_Section); - - hdr.accessUnitEndFlag = (section_number+1==nb_sections) ? stream->sl_header.accessUnitEndFlag : 0; - gf_sl_packetize(&stream->ifce->sl_config, &hdr, NULL, 0, &slhdr, &slhdr_size); - hdr.accessUnitStartFlag = 0; - - remain = table_payload_length - offset; - if (remain > maxSectionLength - overhead_size - slhdr_size) { - section->length = maxSectionLength; - } else { - section->length = remain + overhead_size + slhdr_size; - } - sl_size = section->length - overhead_size - slhdr_size; - - bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); - - /* first header (not included in section length */ - gf_bs_write_int(bs, table_id, 8); - gf_bs_write_int(bs, use_syntax_indicator, 1); - gf_bs_write_int(bs, private_indicator, 1); - gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */ - gf_bs_write_int(bs, section->length - SECTION_HEADER_LENGTH, 12); - - if (use_syntax_indicator) { - /* second header */ - gf_bs_write_int(bs, table_id_extension, 16); - gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */ - gf_bs_write_int(bs, table->version_number, 5); - gf_bs_write_int(bs, 1, 1); /* current_next_indicator = 1: we don't send version in advance */ - gf_bs_write_int(bs, section_number, 8); - section_number++; - gf_bs_write_int(bs, nb_sections-1, 8); - } - - /*write sl header*/ - gf_bs_write_data(bs, slhdr, slhdr_size); - free(slhdr); - /*write sl data*/ - gf_bs_write_data(bs, table_payload + offset, sl_size); - offset += sl_size; - - if (use_syntax_indicator) { - /* place holder for CRC */ - gf_bs_write_u32(bs, 0); - } - - gf_bs_get_content(bs, (char**) §ion->data, §ion->length); - gf_bs_del(bs); - - if (use_syntax_indicator) { - u32 CRC; - CRC = gf_crc_32(section->data,section->length-CRC_LENGTH); - section->data[section->length-4] = (CRC >> 24) & 0xFF; - section->data[section->length-3] = (CRC >> 16) & 0xFF; - section->data[section->length-2] = (CRC >> 8) & 0xFF; - section->data[section->length-1] = CRC & 0xFF; - } - - if (prev_sec) prev_sec->next = section; - else table->section = section; - prev_sec = section; - } - stream->current_table = stream->tables; - stream->current_section = stream->current_table->section; - stream->current_section_offset = 0; -} - -void m2ts_mux_table_update_bitrate(M2TS_Mux *mux, M2TS_Mux_Stream *stream) -{ - M2TS_Mux_Table *table; - - /*update PMT*/ - if (stream->table_needs_update) - stream->process(mux, stream); - - stream->bit_rate = 0; - table = stream->tables; - while (table) { - M2TS_Mux_Section *section = table->section; - while (section) { - stream->bit_rate += section->length; - section = section->next; - } - table = table->next; - } - stream->bit_rate *= 8; - if (!stream->refresh_rate_ms) stream->refresh_rate_ms = 500; - stream->bit_rate *= 1000; - stream->bit_rate /= stream->refresh_rate_ms; -} - -/* length of adaptation_field_length; */ -#define ADAPTATION_LENGTH_LENGTH 1 -/* discontinuty flag, random access flag ... */ -#define ADAPTATION_FLAGS_LENGTH 1 -/* length of encoded pcr */ -#define PCR_LENGTH 6 - -static u32 m2ts_add_adaptation(GF_BitStream *bs, - Bool has_pcr, u64 time, - Bool is_rap, - u32 padding_length) -{ - u32 adaptation_length; - - adaptation_length = ADAPTATION_FLAGS_LENGTH + (has_pcr?PCR_LENGTH:0) + padding_length; - - gf_bs_write_int(bs, adaptation_length, 8); - gf_bs_write_int(bs, 0, 1); // discontinuity indicator - gf_bs_write_int(bs, is_rap, 1); // random access indicator - gf_bs_write_int(bs, 0, 1); // es priority indicator - gf_bs_write_int(bs, has_pcr, 1); // PCR_flag - gf_bs_write_int(bs, 0, 1); // OPCR flag - gf_bs_write_int(bs, 0, 1); // splicing point flag - gf_bs_write_int(bs, 0, 1); // transport private data flag - gf_bs_write_int(bs, 0, 1); // adaptation field extension flag - if (has_pcr) { - u64 PCR_base, PCR_ext; - PCR_base = time; - gf_bs_write_long_int(bs, PCR_base, 33); - gf_bs_write_int(bs, 0, 6); // reserved - PCR_ext = 0; - gf_bs_write_long_int(bs, PCR_ext, 9); - } - while (padding_length) { - gf_bs_write_u8(bs, 0xff); // stuffing byte - padding_length--; - } - - return adaptation_length + ADAPTATION_LENGTH_LENGTH; -} - -void m2ts_mux_table_get_next_packet(M2TS_Mux_Stream *stream, u8 *packet) -{ - GF_BitStream *bs; - M2TS_Mux_Table *table; - M2TS_Mux_Section *section; - u32 payload_length, padding_length; - u8 adaptation_field_control; - - table = stream->current_table; - assert(table); - - section = stream->current_section; - assert(section); - - bs = gf_bs_new(packet, 188, GF_BITSTREAM_WRITE); - - gf_bs_write_int(bs, 0x47, 8); // sync - gf_bs_write_int(bs, 0, 1); // error indicator - if (stream->current_section_offset == 0) { - gf_bs_write_int(bs, 1, 1); // payload start indicator - } else { - /* No section concatenation yet!!!*/ - gf_bs_write_int(bs, 0, 1); // payload start indicator - } - - if (!stream->current_section_offset) payload_length = 183; - else payload_length = 184; - - if (section->length - stream->current_section_offset >= payload_length) { - padding_length = 0; - adaptation_field_control = M2TS_ADAPTATION_NONE; - } else { - /* in all the following cases, we write an adaptation field */ - adaptation_field_control = M2TS_ADAPTATION_AND_PAYLOAD; - /* we need at least 2 bytes for adaptation field headers (no pcr) */ - payload_length -= 2; - if (section->length - stream->current_section_offset >= payload_length) { - padding_length = 0; - } else { - padding_length = payload_length - section->length + stream->current_section_offset; - payload_length -= padding_length; - } - } - assert(payload_length + stream->current_section_offset <= section->length); - - gf_bs_write_int(bs, 0, 1); /*priority indicator*/ - gf_bs_write_int(bs, stream->pid, 13); /*pid*/ - gf_bs_write_int(bs, 0, 2); /*scrambling indicator*/ - gf_bs_write_int(bs, adaptation_field_control, 2); /*we do not use adaptation field for sections */ - gf_bs_write_int(bs, stream->continuity_counter, 4); /*continuity counter*/ - if (stream->continuity_counter < 15) stream->continuity_counter++; - else stream->continuity_counter=0; - - if (adaptation_field_control != M2TS_ADAPTATION_NONE) - m2ts_add_adaptation(bs, 0, 0, 0, padding_length); - - /*pointer field*/ - if (!stream->current_section_offset) { - /* no concatenations of sections in ts packets, so start address is 0 */ - gf_bs_write_u8(bs, 0); - } - gf_bs_del(bs); - - memcpy(packet+188-payload_length, section->data + stream->current_section_offset, payload_length); - stream->current_section_offset += payload_length; - - //m2ts_time_inc(stream->time, 1504/*188*8*/, muxer->bit_rate); - - if (stream->current_section_offset == section->length) { - stream->current_section_offset = 0; - stream->current_section = stream->current_section->next; - if (!stream->current_section) { - stream->current_table = stream->current_table->next; - /*carousel table*/ - if (!stream->current_table && stream->refresh_rate_ms) { - stream->current_table = stream->tables; - /*update ES time*/ - m2ts_time_inc(&stream->time, stream->refresh_rate_ms, 1000); - } - if (stream->current_table) stream->current_section = stream->current_table->section; - } - } - -} - - - -Bool m2ts_stream_process_pat(M2TS_Mux *muxer, M2TS_Mux_Stream *stream) -{ - if (stream->table_needs_update) { /* generate table payload */ - M2TS_Mux_Program *prog; - GF_BitStream *bs; - u8 *payload; - u32 size; - - bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - prog = muxer->programs; - while (prog) { - gf_bs_write_u16(bs, prog->number); - gf_bs_write_int(bs, 0x7, 3); /*reserved*/ - gf_bs_write_int(bs, prog->pmt->pid, 13); /*reserved*/ - prog = prog->next; - } - gf_bs_get_content(bs, (char**)&payload, &size); - gf_bs_del(bs); - m2ts_mux_table_update(stream, GF_M2TS_TABLE_ID_PAT, muxer->ts_id, payload, size, 1, 0, 0); - stream->table_needs_update = 0; - free(payload); - } - return 1; -} - -Bool m2ts_stream_process_pmt(M2TS_Mux *muxer, M2TS_Mux_Stream *stream) -{ - if (stream->table_needs_update) { /* generate table payload */ - M2TS_Mux_Stream *es; - u8 *payload; - u32 length; - GF_BitStream *bs; - - bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); - gf_bs_write_int(bs, 0x7, 3); // reserved - gf_bs_write_int(bs, stream->program->pcr->pid, 13); - gf_bs_write_int(bs, 0xF, 4); // reserved - - if (!stream->program->iod) { - gf_bs_write_int(bs, 0, 12); // program info length =0 - } else { - u32 len; - GF_BitStream *bs_iod; - char *iod_data; - u32 iod_data_len; - - bs_iod = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); - gf_odf_write_descriptor(bs_iod, stream->program->iod); - gf_bs_get_content(bs_iod, &iod_data, &iod_data_len); - gf_bs_del(bs_iod); - - len = iod_data_len + 4; - gf_bs_write_int(bs, len, 12); // program info length - - gf_bs_write_int(bs, GF_M2TS_MPEG4_IOD_DESCRIPTOR, 8); - len = iod_data_len + 2; - gf_bs_write_int(bs, len, 8); - - /* Scope_of_IOD_label : - 0x10 iod unique a l'intérieur de programme - 0x11 iod unoque dans le flux ts */ - gf_bs_write_int(bs, 2, 8); - - gf_bs_write_int(bs, 2, 8); // IOD_label - - gf_bs_write_data(bs, iod_data, iod_data_len); - free(iod_data); - } - es = stream->program->streams; - while (es) { - gf_bs_write_int(bs, es->mpeg2_stream_type, 8); - gf_bs_write_int(bs, 0x7, 3); // reserved - gf_bs_write_int(bs, es->pid, 13); - gf_bs_write_int(bs, 0xF, 4); // reserved - - /* Second Loop Descriptor */ - if (stream->program->iod) { - gf_bs_write_int(bs, 4, 12); // ES info length = 4 :only SL Descriptor - gf_bs_write_int(bs, GF_M2TS_MPEG4_SL_DESCRIPTOR, 8); - gf_bs_write_int(bs, 2, 8); - gf_bs_write_int(bs, es->ifce->stream_id, 16); // mpeg4_esid - } else { - gf_bs_write_int(bs, 0, 12); - } - es = es->next; - } - - gf_bs_get_content(bs, (char**)&payload, &length); - gf_bs_del(bs); - - m2ts_mux_table_update(stream, GF_M2TS_TABLE_ID_PMT, stream->program->number, payload, length, 1, 0, 0); - stream->table_needs_update = 0; - free(payload); - } - return 1; -} - -Bool m2ts_stream_process_stream(M2TS_Mux *muxer, M2TS_Mux_Stream *stream) -{ - if (stream->mpeg2_stream_type==GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { - /*section not completely sent yet*/ - if (stream->current_section) return 1; - } - else if (stream->pck_offset < stream->pck.data_len) { - /*PES packet not completely sent yet*/ - return 1; - } - - /*PULL mode*/ - if (stream->ifce->caps & GF_ESI_AU_PULL_CAP) { - if (stream->pck.data_len) { - /*discard packet data if we use SL over PES*/ - if (stream->mpeg2_stream_type==GF_M2TS_SYSTEMS_MPEG4_PES) free(stream->pck.data); - /*release data*/ - stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_RELEASE, NULL); - } - stream->pck_offset = 0; - stream->pck.data_len = 0; - - /*EOS*/ - if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) return 0; - stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_PULL, &stream->pck); - } else { - M2TS_Packet *pck; - /*flush input pipe*/ - stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_FLUSH, NULL); - gf_mx_p(stream->mx); - /*discard first packet*/ - if (stream->pck_offset) { - assert(stream->pck_first); - pck = stream->pck_first; - stream->pck_first = pck->next; - free(pck->data); - free(pck); - } - stream->pck_offset = 0; - stream->pck.data_len = 0; - - /*fill pck*/ - pck = stream->pck_first; - if (!pck) { - gf_mx_v(stream->mx); - return 0; - } - stream->pck.cts = pck->cts; - stream->pck.data = pck->data; - stream->pck.data_len = pck->data_len; - stream->pck.dts = pck->dts; - stream->pck.flags = pck->flags; - gf_mx_v(stream->mx); - } - if (!(stream->pck.flags & GF_ESI_DATA_HAS_DTS)) - stream->pck.dts = stream->pck.cts; - - /*!! watchout !!*/ - if (stream->ts_scale) { - stream->pck.cts = (u64) (stream->ts_scale * (s64) stream->pck.cts); - stream->pck.dts = (u64) (stream->ts_scale * (s64) stream->pck.dts); - } - - /*SL-encapsultaion*/ - switch (stream->mpeg2_stream_type) { - case GF_M2TS_SYSTEMS_MPEG4_SECTIONS: - /*update SL config*/ - stream->sl_header.accessUnitStartFlag = (stream->pck.flags & GF_ESI_DATA_AU_START) ? 1 : 0; - stream->sl_header.accessUnitEndFlag = (stream->pck.flags & GF_ESI_DATA_AU_END) ? 1 : 0; - stream->sl_header.accessUnitLength += stream->pck.data_len; - stream->sl_header.randomAccessPointFlag = (stream->pck.flags & GF_ESI_DATA_AU_RAP) ? 1: 0; - stream->sl_header.compositionTimeStampFlag = (stream->pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0; - stream->sl_header.compositionTimeStamp = stream->pck.cts; - stream->sl_header.decodingTimeStampFlag = (stream->pck.flags & GF_ESI_DATA_HAS_DTS) ? 1: 0; - stream->sl_header.decodingTimeStamp = stream->pck.dts; - - m2ts_mux_table_update_mpeg4(stream, stream->table_id, muxer->ts_id, stream->pck.data, stream->pck.data_len, 1, 0, 0); - break; - case GF_M2TS_SYSTEMS_MPEG4_PES: - { - char *src_data; - u32 src_data_len; - - /*update SL config*/ - stream->sl_header.accessUnitStartFlag = (stream->pck.flags & GF_ESI_DATA_AU_START) ? 1 : 0; - stream->sl_header.accessUnitEndFlag = (stream->pck.flags & GF_ESI_DATA_AU_END) ? 1 : 0; - stream->sl_header.accessUnitLength += stream->pck.data_len; - stream->sl_header.randomAccessPointFlag = (stream->pck.flags & GF_ESI_DATA_AU_RAP) ? 1: 0; - stream->sl_header.compositionTimeStampFlag = (stream->pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0; - stream->sl_header.compositionTimeStamp = stream->pck.cts; - stream->sl_header.decodingTimeStampFlag = (stream->pck.flags & GF_ESI_DATA_HAS_DTS) ? 1: 0; - stream->sl_header.decodingTimeStamp = stream->pck.dts; - - src_data = stream->pck.data; - src_data_len = stream->pck.data_len; - stream->pck.data_len = 0; - stream->pck.data = NULL; - - gf_sl_packetize(&stream->ifce->sl_config, &stream->sl_header, src_data, src_data_len, &stream->pck.data, &stream->pck.data_len); - - /*discard src data*/ - if (!(stream->ifce->caps & GF_ESI_AU_PULL_CAP)) { - free(src_data); - stream->pck_first->data = stream->pck.data; - stream->pck_first->data_len = stream->pck.data_len; - } - } - break; - } - - - /*initializing the PCR*/ - if (!stream->program->pcr_init) { - if (stream==stream->program->pcr) { - stream->program->pcr_init_ts_time = muxer->time; - stream->program->pcr_init_time = stream->pck.dts; - stream->program->pcr_init = 1; - } else { - /*don't send until PCR is initialized*/ - return 0; - } - } - - /*move to current time in TS unit*/ - stream->time = stream->program->pcr_init_ts_time; - m2ts_time_inc(&stream->time, (u32) (stream->pck.dts - stream->program->pcr_init_time), 90000); - - /*compute bitrate if needed*/ - if (!stream->bit_rate) { - if (!stream->last_br_time) { - stream->last_br_time = stream->pck.dts + 1; - stream->bytes_since_last_time = stream->pck.data_len; - } else { - if (stream->pck.dts - stream->last_br_time - 1 >= 90000) { - u64 r = 8*stream->bytes_since_last_time; - r*=90000; - stream->bit_rate = (u32) (r / (stream->pck.dts - stream->last_br_time - 1)); - stream->program->mux->needs_reconfig = 1; - } else { - stream->bytes_since_last_time += stream->pck.data_len; - } - } - } - return 1; -} - -static u32 m2ts_stream_get_pes_header_length(M2TS_Mux_Stream *stream) -{ - u32 hdr_len; - /*not the AU start*/ - if (stream->pck_offset || !(stream->pck.flags & GF_ESI_DATA_AU_START) ) return 0; - hdr_len = 9; - if (stream->pck.flags & GF_ESI_DATA_HAS_CTS) hdr_len += 5; - if (stream->pck.flags & GF_ESI_DATA_HAS_DTS) hdr_len += 5; - return hdr_len; -} - -u32 m2ts_stream_add_pes_header(GF_BitStream *bs, M2TS_Mux_Stream *stream) -{ - u32 pes_len; - Bool use_pts, use_dts; - - gf_bs_write_int(bs, 0x1, 24);//packet start code - gf_bs_write_u8(bs, stream->mpeg2_stream_id);// stream id - - use_pts = (stream->pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0; - use_dts = (stream->pck.flags & GF_ESI_DATA_HAS_DTS) ? 1 : 0; - - pes_len = stream->pck.data_len + 3; // 3 = header size - if (use_pts) pes_len += 5; - if (use_dts) pes_len += 5; - gf_bs_write_int(bs, pes_len, 16); // pes packet length - - 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, 0x0, 1); // copyright - gf_bs_write_int(bs, 0x0, 1); // original or copy - - gf_bs_write_int(bs, use_pts, 1); - gf_bs_write_int(bs, use_dts, 1); - gf_bs_write_int(bs, 0x0, 6); //6 flags = 0 (ESCR, ES_rate, DSM_trick, additional_copy, PES_CRC, PES_extension) - - gf_bs_write_int(bs, use_dts*5+use_pts*5, 8); - - if (use_pts) { - u64 t; - gf_bs_write_int(bs, use_dts ? 0x3 : 0x2, 4); // reserved '0011' || '0010' - t = ((stream->pck.cts >> 30) & 0x7); - gf_bs_write_long_int(bs, t, 3); - gf_bs_write_int(bs, 1, 1); // marker bit - t = ((stream->pck.cts >> 15) & 0x7fff); - gf_bs_write_long_int(bs, t, 15); - gf_bs_write_int(bs, 1, 1); // marker bit - t = stream->pck.cts & 0x7fff; - gf_bs_write_long_int(bs, t, 15); - gf_bs_write_int(bs, 1, 1); // marker bit - } - - if (use_dts) { - u64 t; - gf_bs_write_int(bs, 0x1, 4); // reserved '0001' - t = ((stream->pck.dts >> 30) & 0x7); - gf_bs_write_long_int(bs, t, 3); - gf_bs_write_int(bs, 1, 1); // marker bit - t = ((stream->pck.dts >> 15) & 0x7fff); - gf_bs_write_long_int(bs, t, 15); - gf_bs_write_int(bs, 1, 1); // marker bit - t = stream->pck.dts & 0x7fff; - gf_bs_write_long_int(bs, t, 15); - gf_bs_write_int(bs, 1, 1); // marker bit - } - return pes_len+4; // 4 = start code + stream_id -} - -void m2ts_mux_pes_get_next_packet(M2TS_Mux_Stream *stream, u8 *packet) -{ - GF_BitStream *bs; - Bool is_rap, needs_pcr; - u32 remain, adaptation_field_control, payload_length, padding_length, hdr_len; - - assert(stream->pid); - bs = gf_bs_new(packet, 188, GF_BITSTREAM_WRITE); - - hdr_len = m2ts_stream_get_pes_header_length(stream); - remain = stream->pck.data_len - stream->pck_offset; - - needs_pcr = (hdr_len && (stream==stream->program->pcr) ) ? 1 : 0; - adaptation_field_control = M2TS_ADAPTATION_NONE; - payload_length = 184 - hdr_len; - padding_length = 0; - - if (needs_pcr) { - adaptation_field_control = M2TS_ADAPTATION_AND_PAYLOAD; - /*AF headers + PCR*/ - payload_length -= 8; - } else if (remain<184) { - /*AF headers*/ - payload_length -= 2; - adaptation_field_control = M2TS_ADAPTATION_AND_PAYLOAD; - } - if (remain>=payload_length) { - padding_length = 0; - } else { - padding_length = payload_length - remain; - payload_length -= padding_length; - } - - gf_bs_write_int(bs, 0x47, 8); // sync byte - gf_bs_write_int(bs, 0, 1); // error indicator - gf_bs_write_int(bs, hdr_len ? 1 : 0, 1); // start ind - gf_bs_write_int(bs, 0, 1); // transport priority - gf_bs_write_int(bs, stream->pid, 13); // pid - gf_bs_write_int(bs, 0, 2); // scrambling - gf_bs_write_int(bs, adaptation_field_control, 2); // we do not use adaptation field for sections - gf_bs_write_int(bs, stream->continuity_counter, 4); // continuity counter - if (stream->continuity_counter < 15) stream->continuity_counter++; - else stream->continuity_counter=0; - - is_rap = (hdr_len && (stream->pck.flags & GF_ESI_DATA_AU_RAP) ) ? 1 : 0; - - if (adaptation_field_control != M2TS_ADAPTATION_NONE) { - /*FIXME - WE NEED A REAL PCR, NOT THE DTS*/ - m2ts_add_adaptation(bs, needs_pcr, stream->pck.dts, is_rap, padding_length); - } - - /*FIXME - we need proper packetization here in case we're not fed with full AUs*/ - if (hdr_len) m2ts_stream_add_pes_header(bs, stream); - - gf_bs_del(bs); - - memcpy(packet+188-payload_length, stream->pck.data + stream->pck_offset, payload_length); - stream->pck_offset += payload_length; - - assert(stream->pck_offset <= stream->pck.data_len); - m2ts_time_inc(&stream->time, payload_length, stream->bit_rate); -} - - -M2TS_Mux_Stream *m2ts_stream_new(u32 pid) { - M2TS_Mux_Stream *stream; - - GF_SAFEALLOC(stream, M2TS_Mux_Stream); - stream->pid = pid; - stream->process = m2ts_stream_process_stream; - - return stream; -} - -GF_Err m2ts_output_ctrl(GF_ESInterface *_self, u32 ctrl_type, void *param) -{ - GF_ESIPacket *esi_pck; - M2TS_Packet *pck; - M2TS_Mux_Stream *stream = (M2TS_Mux_Stream *)_self->output_udta; - switch (ctrl_type) { - case GF_ESI_OUTPUT_DATA_DISPATCH: - GF_SAFEALLOC(pck, M2TS_Packet); - esi_pck = (GF_ESIPacket *)param; - pck->data_len = esi_pck->data_len; - pck->data = malloc(sizeof(char)*pck->data_len); - memcpy(pck->data, esi_pck->data, pck->data_len); - pck->flags = esi_pck->flags; - pck->cts = esi_pck->cts; - pck->dts = esi_pck->dts; - gf_mx_p(stream->mx); - if (!stream->pck_first) { - stream->pck_first = stream->pck_last = pck; - } else { - stream->pck_last->next = pck; - stream->pck_last = pck; - } - gf_mx_v(stream->mx); - break; - } - return GF_OK; -} - - - -M2TS_Mux_Stream *m2ts_program_stream_add(M2TS_Mux_Program *program, struct __elementary_stream_ifce *ifce, u32 pid, Bool is_pcr) -{ - M2TS_Mux_Stream *stream, *st; - - stream = m2ts_stream_new(pid); - stream->ifce = ifce; - stream->pid = pid; - stream->program = program; - if (is_pcr) program->pcr = stream; - if (program->streams) { - st = program->streams; - while (st->next) st = st->next; - st->next = stream; - } else { - program->streams = stream; - } - if (program->pmt) program->pmt->table_needs_update = 1; - stream->bit_rate = ifce->bit_rate; - - switch (ifce->stream_type) { - case GF_STREAM_VISUAL: - /*just pick first valid stream_id in visual range*/ - stream->mpeg2_stream_id = 0xE0; - switch (ifce->object_type_indication) { - case 0x20: - stream->mpeg2_stream_type = GF_M2TS_VIDEO_MPEG4; - break; - case 0x21: - stream->mpeg2_stream_type = GF_M2TS_VIDEO_H264; - break; - case 0x6A: - stream->mpeg2_stream_type = GF_M2TS_VIDEO_MPEG1; - break; - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: - stream->mpeg2_stream_type = GF_M2TS_VIDEO_MPEG2; - break; - /*JPEG/PNG carried in MPEG-4 PES*/ - case 0x6C: - case 0x6D: - stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES; - stream->mpeg2_stream_id = 0xFA; - break; - default: - break; - } - break; - case GF_STREAM_AUDIO: - switch (ifce->object_type_indication) { - case 0x6B: - stream->mpeg2_stream_type = GF_M2TS_AUDIO_MPEG1; - break; - case 0x69: - stream->mpeg2_stream_type = GF_M2TS_AUDIO_MPEG2; - break; - case 0x40: - stream->mpeg2_stream_type = GF_M2TS_AUDIO_AAC; - break; - } - /*just pick first valid stream_id in audio range*/ - stream->mpeg2_stream_id = 0xC0; - break; - case GF_STREAM_SCENE: - case GF_STREAM_OD: - stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_SECTIONS; - stream->mpeg2_stream_id = 0xFA; - stream->table_id = (ifce->stream_type==GF_STREAM_OD) ? GF_M2TS_TABLE_ID_MPEG4_OD : GF_M2TS_TABLE_ID_MPEG4_BIFS; - break; - } - - /*override signaling for all streams except BIFS/OD, to use MPEG-4 PES*/ - if (program->mux->mpeg4_signaling) { - if (stream->mpeg2_stream_type != GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { - stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES; - stream->mpeg2_stream_id = 0xFA;/*ISO/IEC14496-1_SL-packetized_stream*/ - } - } - - stream->ifce->output_ctrl = m2ts_output_ctrl; - stream->ifce->output_udta = stream; - stream->mx = gf_mx_new("M2TS PID"); - if (ifce->timescale != 90000) stream->ts_scale = 90000.0 / ifce->timescale; - return stream; -} - -#define M2TS_PSI_REFRESH_RATE 200 - -M2TS_Mux_Program *m2ts_mux_program_add(M2TS_Mux *muxer, u32 program_number, u32 pmt_pid) -{ - M2TS_Mux_Program *program; - - GF_SAFEALLOC(program, M2TS_Mux_Program); - program->mux = muxer; - program->number = program_number; - if (muxer->programs) { - M2TS_Mux_Program *p = muxer->programs; - while (p->next) p = p->next; - p->next = program; - } else { - muxer->programs = program; - } - program->pmt = m2ts_stream_new(pmt_pid); - program->pmt->program = program; - muxer->pat->table_needs_update = 1; - program->pmt->process = m2ts_stream_process_pmt; - program->pmt->refresh_rate_ms = M2TS_PSI_REFRESH_RATE; - return program; -} - -M2TS_Mux *m2ts_mux_new(u32 mux_rate, Bool real_time) -{ - GF_BitStream *bs; - M2TS_Mux *muxer; - GF_SAFEALLOC(muxer, M2TS_Mux); - muxer->pat = m2ts_stream_new(GF_M2TS_PID_PAT); - muxer->pat->process = m2ts_stream_process_pat; - muxer->pat->refresh_rate_ms = M2TS_PSI_REFRESH_RATE; - muxer->real_time = real_time; - muxer->bit_rate = mux_rate; - if (mux_rate) muxer->fixed_rate = 1; - - /*format NULL packet*/ - bs = gf_bs_new(muxer->null_pck, 188, GF_BITSTREAM_WRITE); - gf_bs_write_int(bs, 0x47, 8); - gf_bs_write_int(bs, 0, 1); - gf_bs_write_int(bs, 0, 1); - gf_bs_write_int(bs, 0, 1); - gf_bs_write_int(bs, 0x1FFF, 13); - gf_bs_write_int(bs, 0, 2); - gf_bs_write_int(bs, 1, 2); - gf_bs_write_int(bs, 0, 4); - gf_bs_del(bs); - return muxer; -} - -void m2ts_mux_stream_del(M2TS_Mux_Stream *st) -{ - while (st->tables) { - M2TS_Mux_Table *tab = st->tables->next; - while (st->tables->section) { - M2TS_Mux_Section *sec = st->tables->section->next; - free(st->tables->section->data); - free(st->tables->section); - st->tables->section = sec; - } - free(st->tables); - st->tables = tab; - } - while (st->pck_first) { - M2TS_Packet *pck = st->pck_first; - st->pck_first = pck->next; - free(pck->data); - free(pck); - } - if (st->mx) gf_mx_del(st->mx); - free(st); -} - -void m2ts_mux_program_del(M2TS_Mux_Program *prog) -{ - while (prog->streams) { - M2TS_Mux_Stream *st = prog->streams->next; - m2ts_mux_stream_del(prog->streams); - prog->streams = st; - } - m2ts_mux_stream_del(prog->pmt); - free(prog); -} - -void m2ts_mux_del(M2TS_Mux *mux) -{ - while (mux->programs) { - M2TS_Mux_Program *p = mux->programs->next; - m2ts_mux_program_del(mux->programs); - mux->programs = p; - } - m2ts_mux_stream_del(mux->pat); - free(mux); -} - -void m2ts_mux_update_config(M2TS_Mux *mux, Bool reset_time) -{ - M2TS_Mux_Program *prog; - - if (!mux->fixed_rate) { - mux->bit_rate = 0; - - /*get PAT bitrate*/ - m2ts_mux_table_update_bitrate(mux, mux->pat); - mux->bit_rate += mux->pat->bit_rate; - } - - prog = mux->programs; - while (prog) { - M2TS_Mux_Stream *stream = prog->streams; - while (stream) { - /*!! WATCHOUT - this is raw bitrate without PES header overhead !!*/ - if (!mux->fixed_rate) { - mux->bit_rate += stream->bit_rate; - /*update PCR every 100ms - we need at least 8 bytes without padding*/ - if (stream == prog->pcr) mux->bit_rate += 8*8*10; - } - - /*reset mux time*/ - if (reset_time) stream->time.sec = stream->time.nanosec = 0; - stream = stream->next; - } - /*get PMT bitrate*/ - if (!mux->fixed_rate) { - m2ts_mux_table_update_bitrate(mux, prog->pmt); - mux->bit_rate += prog->pmt->bit_rate; - } - prog = prog->next; - } - /*reset mux time*/ - if (reset_time) { - mux->time.sec = mux->time.nanosec = 0; - mux->init_sys_time = 0; - } -} - -u32 gf_m2ts_get_sys_clock(M2TS_Mux *muxer) -{ - return gf_sys_clock() - muxer->init_sys_time; -} -u32 gf_m2ts_get_ts_clock(M2TS_Mux *muxer) -{ - u32 now, init; - init = muxer->init_ts_time.sec*1000 + muxer->init_ts_time.nanosec/1000000; - now = muxer->time.sec*1000 + muxer->time.nanosec/1000000; - return now-init; -} - - -const char *m2ts_mux_process(M2TS_Mux *muxer, u32 *status) -{ - M2TS_Mux_Program *program; - M2TS_Mux_Stream *stream, *stream_to_process; - M2TS_Time time; - u32 now, nb_streams, nb_streams_done; - char *ret; - Bool res; - - nb_streams = nb_streams_done = 0; - *status = GF_M2TS_STATE_IDLE; - - now = gf_sys_clock(); - - if (muxer->real_time) { - if (!muxer->init_sys_time) { - muxer->init_sys_time = now; - muxer->init_ts_time = muxer->time; - } else { - u32 diff = now - muxer->init_sys_time; - M2TS_Time now = muxer->init_ts_time; - m2ts_time_inc(&now, diff, 1000); +#include +#include - if (m2ts_time_less(&now, &muxer->time)) - return NULL; - } - } - stream_to_process = NULL; - time = muxer->time; +#define MP42TS_PRINT_FREQ 634 /*refresh printed info every CLOCK_REFRESH ms*/ - if (muxer->needs_reconfig) { - m2ts_mux_update_config(muxer, 0); - muxer->needs_reconfig = 0; - } - res = muxer->pat->process(muxer, muxer->pat); - if (res && m2ts_time_less_or_equal(&muxer->pat->time, &time) ) { - time = muxer->pat->time; - stream_to_process = muxer->pat; - /*force sending the PAT regardless of other streams*/ - goto send_pck; - } +static GFINLINE void usage() +{ + fprintf(stderr, "usage: mp42ts {rate {prog}*} [mpeg4-carousel] [mpeg4] [time] [src] dst\n" + "\n" + "-rate=R specifies target rate in kbps of the multiplex\n" + " If not set, transport stream will be of variable bitrate\n" + "-prog=filename specifies an input file used for a TS service\n" + " * currently only supports ISO files and SDP files\n" + " * option can be used several times, once for each program\n" + "-mpeg4-carousel=n carousel period in ms\n" + "-mpeg4 forces usage of MPEG-4 signaling (use of IOD and SL Config)\n" + "-time=n request the program to stop after n ms\n" + "-src=filename update file: must be either an .sdp or a .bt file\n" + "\n" + "dst can be either a file, an RTP or a UDP destination (unicast/multicast)\n" + ); +} - program = muxer->programs; - while (program) { - res = program->pmt->process(muxer, program->pmt); - if (res && m2ts_time_less(&program->pmt->time, &time) ) { - time = program->pmt->time; - stream_to_process = program->pmt; - /*force sending the PMT regardless of other streams*/ - goto send_pck; - } - stream = program->streams; - while (stream) { - nb_streams ++; - res = stream->process(muxer, stream); - if (res) { - if (m2ts_time_less(&stream->time, &time)) { - time = stream->time; - stream_to_process = stream; - } - } else { - if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) nb_streams_done ++; - } - stream = stream->next; - } - program = program->next; - } -send_pck: - ret = NULL; - if (!stream_to_process) { - if (nb_streams && (nb_streams==nb_streams_done)) { - *status = GF_M2TS_STATE_EOS; - } else { - *status = GF_M2TS_STATE_PADDING; - } - /* padding packets ?? */ - if (muxer->fixed_rate) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Inserting empty packet at %d:%d\n", time.sec, time.nanosec)); - ret = muxer->null_pck; - muxer->tot_pad_sent++; - } - /*we still need to increase the mux time, even though we're not fixed-rate*/ - else { - m2ts_time_inc(&muxer->time, 1504/*188*8*/, muxer->bit_rate); - } - } else { - if (stream_to_process->tables) { - m2ts_mux_table_get_next_packet(stream_to_process, muxer->dst_pck); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Sending table packet from PID %d at %d:%d\n", stream_to_process->pid, time.sec, time.nanosec)); - } else { - m2ts_mux_pes_get_next_packet(stream_to_process, muxer->dst_pck); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Sending PES packet from PID %d at %d:%d\n", stream_to_process->pid, time.sec, time.nanosec)); - } - ret = muxer->dst_pck; - *status = GF_M2TS_STATE_DATA; - } - if (ret) { - muxer->tot_pck_sent++; - /*increment time*/ - m2ts_time_inc(&muxer->time, 1504/*188*8*/, muxer->bit_rate); - - if (muxer->real_time) { - muxer->pck_sent++; - if (now - muxer->last_br_time > 500) { - u64 size = 8*188*muxer->pck_sent*1000; - muxer->avg_br = (u32) (size/(now - muxer->last_br_time)); - muxer->last_br_time = now; - muxer->pck_sent=0; - } - } - } - return ret; -} + +#define MAX_MUX_SRC_PROG 100 +typedef struct +{ + GF_ISOFile *mp4; + u32 nb_streams, pcr_idx; + GF_ESInterface streams[40]; + GF_Descriptor *iod; + GF_SceneEngine *seng; + GF_Thread *th; + char *src_name; + u32 rate; + Bool repeat; +} M2TSProgram; typedef struct { @@ -1294,9 +74,34 @@ typedef struct u32 track, sample_number, sample_count; GF_ISOSample *sample; /*refresh rate for images*/ - u32 refresh_rate_ms, nb_repeat_last; + u32 image_repeat_ms, nb_repeat_last; + void *dsi; + u32 dsi_size; + u32 nalu_size; + void *dsi_and_rap; + Bool loop; + u64 ts_offset; } GF_ESIMP4; +typedef struct +{ + u32 carousel_period, ts_delta; + u16 aggregate_on_stream; + Bool adjust_carousel_time; + Bool discard; + Bool rap; + Bool critical; + Bool vers_inc; +} GF_ESIStream; + +/*output types*/ +enum +{ + GF_MP42TS_FILE_OUTPUT, /*open mpeg2ts file*/ + GF_MP42TS_UDP_OUTPUT, /*open udp socket*/ + GF_MP42TS_RTP_OUTPUT, /*open rtp socket*/ +}; + static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) { GF_ESIMP4 *priv = (GF_ESIMP4 *)ifce->input_udta; @@ -1304,47 +109,103 @@ static GF_Err mp4_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) switch (act_type) { case GF_ESI_INPUT_DATA_FLUSH: - return GF_OK; - case GF_ESI_INPUT_DATA_PULL: { - GF_ESIPacket *pck = (GF_ESIPacket *)param; - if (!priv->sample) { + GF_ESIPacket pck; + if (!priv->sample) priv->sample = gf_isom_get_sample(priv->mp4, priv->track, priv->sample_number+1, NULL); - } + if (!priv->sample) return GF_IO_ERR; - pck->data_len = priv->sample->dataLength; - pck->data = priv->sample->data; - pck->flags = GF_ESI_DATA_AU_START | GF_ESI_DATA_AU_END | GF_ESI_DATA_HAS_CTS; - pck->cts = priv->sample->DTS; - + + pck.flags = 0; + pck.flags = GF_ESI_DATA_AU_START | GF_ESI_DATA_HAS_CTS; + if (priv->sample->IsRAP) pck.flags |= GF_ESI_DATA_AU_RAP; + pck.cts = priv->sample->DTS + priv->ts_offset; + if (priv->nb_repeat_last) { - pck->cts += priv->nb_repeat_last*ifce->timescale * priv->refresh_rate_ms / 1000; + pck.cts += priv->nb_repeat_last*ifce->timescale * priv->image_repeat_ms / 1000; } if (priv->sample->CTS_Offset) { - pck->dts = pck->cts; - pck->cts += priv->sample->CTS_Offset; - pck->flags |= GF_ESI_DATA_HAS_DTS; + pck.dts = pck.cts; + pck.cts += priv->sample->CTS_Offset; + pck.flags |= GF_ESI_DATA_HAS_DTS; } - if (priv->sample->IsRAP) pck->flags |= GF_ESI_DATA_AU_RAP; - } - return GF_OK; - case GF_ESI_INPUT_DATA_RELEASE: - if (priv->sample) { - gf_isom_sample_del(&priv->sample); - priv->sample_number++; - if (priv->sample_number==priv->sample_count) { - if (priv->refresh_rate_ms) { - priv->nb_repeat_last++; - priv->sample_number--; - } else { - ifce->caps |= GF_ESI_STREAM_IS_OVER; + + if (priv->sample->IsRAP && priv->dsi) { + pck.data = priv->dsi; + pck.data_len = priv->dsi_size; + ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); + pck.flags = 0; + } + if (priv->nalu_size) { + u32 remain = priv->sample->dataLength; + char *ptr = priv->sample->data; + u32 v, size; + char sc[4]; + sc[0] = sc[1] = sc[2] = 0; sc[3] = 1; + + while (remain) { + size = 0; + v = priv->nalu_size; + while (v) { + size |= (u8) *ptr; + ptr++; + remain--; + v-=1; + if (v) size<<=8; } + remain -= size; + + pck.data = sc; + pck.data_len = 4; + ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); + pck.flags &= ~GF_ESI_DATA_AU_START; + + if (!remain) pck.flags |= GF_ESI_DATA_AU_END; + + pck.data = ptr; + pck.data_len = size; + ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); + ptr += size; + } + + } else { + pck.flags |= GF_ESI_DATA_AU_END; + pck.data = priv->sample->data; + pck.data_len = priv->sample->dataLength; + ifce->output_ctrl(ifce, GF_ESI_OUTPUT_DATA_DISPATCH, &pck); + } + + gf_isom_sample_del(&priv->sample); + priv->sample_number++; + if (priv->sample_number==priv->sample_count) { + if (priv->loop) { + Double scale; + u64 duration; + /*increment ts offset*/ + scale = gf_isom_get_media_timescale(priv->mp4, priv->track); + scale /= gf_isom_get_timescale(priv->mp4); + duration = (u64) (gf_isom_get_duration(priv->mp4) * scale); + priv->ts_offset += duration; + priv->sample_number = 0; + } + else if (priv->image_repeat_ms) { + priv->nb_repeat_last++; + priv->sample_number--; + } else { + ifce->caps |= GF_ESI_STREAM_IS_OVER; } } + } return GF_OK; + case GF_ESI_INPUT_DESTROY: - free(priv); + if (priv->dsi) gf_free(priv->dsi); + if (ifce->decoder_config) { + gf_free(ifce->decoder_config); + ifce->decoder_config = NULL; + } + gf_free(priv); ifce->input_udta = NULL; return GF_OK; default: @@ -1357,20 +218,58 @@ static void fill_isom_es_ifce(GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_n GF_ESIMP4 *priv; char _lan[4]; GF_DecoderConfig *dcd; - u64 avg_rate; + u64 avg_rate, duration; GF_SAFEALLOC(priv, GF_ESIMP4); priv->mp4 = mp4; priv->track = track_num; + priv->loop = 1; priv->sample_count = gf_isom_get_sample_count(mp4, track_num); memset(ifce, 0, sizeof(GF_ESInterface)); - ifce->caps = GF_ESI_AU_PULL_CAP; ifce->stream_id = gf_isom_get_track_id(mp4, track_num); dcd = gf_isom_get_decoder_config(mp4, track_num, 1); ifce->stream_type = dcd->streamType; ifce->object_type_indication = dcd->objectTypeIndication; + if (dcd->decoderSpecificInfo && dcd->decoderSpecificInfo->dataLength) { + switch (dcd->objectTypeIndication) { + case GPAC_OTI_AUDIO_AAC_MPEG4: + 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); + break; + case GPAC_OTI_VIDEO_MPEG4_PART2: + priv->dsi = gf_malloc(sizeof(char)*dcd->decoderSpecificInfo->dataLength); + priv->dsi_size = dcd->decoderSpecificInfo->dataLength; + memcpy(priv->dsi, dcd->decoderSpecificInfo->data, dcd->decoderSpecificInfo->dataLength); + break; + case GPAC_OTI_VIDEO_AVC: + { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_AVCConfigSlot *slc; + u32 i; + GF_BitStream *bs; + GF_AVCConfig *avccfg = gf_isom_avc_config_get(mp4, track_num, 1); + priv->nalu_size = avccfg->nal_unit_size; + bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + for (i=0; isequenceParameterSets);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; ipictureParameterSets);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 **) &priv->dsi, &priv->dsi_size); + gf_bs_del(bs); +#endif + } + break; + } + } gf_odf_desc_del((GF_Descriptor *)dcd); gf_isom_get_media_language(mp4, track_num, _lan); ifce->lang = GF_4CC(_lan[0],_lan[1],_lan[2],' '); @@ -1379,17 +278,11 @@ static void fill_isom_es_ifce(GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_n ifce->duration = gf_isom_get_media_timescale(mp4, track_num); avg_rate = gf_isom_get_media_data_size(mp4, track_num); avg_rate *= ifce->timescale * 8; - avg_rate /= gf_isom_get_media_duration(mp4, track_num); + if (duration=gf_isom_get_media_duration(mp4, track_num)) + avg_rate /= duration; if (gf_isom_has_time_offset(mp4, track_num)) ifce->caps |= GF_ESI_SIGNAL_DTS; - /*turn on image repeat*/ - switch (ifce->object_type_indication) { - case 0x6C: - case 0x6D: - //priv->refresh_rate_ms = 500; - break; - } ifce->bit_rate = (u32) avg_rate; ifce->duration = (Double) (s64) gf_isom_get_media_duration(mp4, track_num); ifce->duration /= ifce->timescale; @@ -1398,6 +291,18 @@ static void fill_isom_es_ifce(GF_ESInterface *ifce, GF_ISOFile *mp4, u32 track_n ifce->input_udta = priv; } + +static GF_Err seng_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) +{ + if (act_type==GF_ESI_INPUT_DESTROY) { + //TODO: free my data + ifce->input_udta = NULL; + return GF_OK; + } + + return GF_OK; +} + typedef struct { /*RTP channel*/ @@ -1409,6 +314,12 @@ typedef struct GF_ESIPacket pck; GF_ESInterface *ifce; + + Bool cat_dsi; + void *dsi_and_rap; + + Bool use_carousel; + u32 au_sn; } GF_ESIRTP; static GF_Err rtp_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) @@ -1435,20 +346,274 @@ static GF_Err rtp_input_ctrl(GF_ESInterface *ifce, u32 act_type, void *param) 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); + 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); - free(rtp); + gf_free(rtp); ifce->input_udta = NULL; return GF_OK; } return GF_OK; } +static GF_Err SampleCallBack(void *calling_object, u16 ESID, char *data, u32 size, u64 ts) +{ + u32 i=0; + //fprintf(stdout, "update: ESID=%d - size=%d - ts="LLD"\n", ESID, size, ts); + if (calling_object) { + M2TSProgram *prog = (M2TSProgram *)calling_object; + while (inb_streams){ + if (prog->streams[i].output_ctrl==NULL) { + fprintf(stdout, "MULTIPLEX NOT YET CREATED\n"); + return GF_OK; + } + if (prog->streams[i].stream_id == ESID) { + GF_ESIStream *priv = (GF_ESIStream *)prog->streams[i].input_udta; + GF_ESIPacket pck; + memset(&pck, 0, sizeof(GF_ESIPacket)); + pck.data = data; + pck.data_len = size; + pck.flags |= GF_ESI_DATA_HAS_CTS; + pck.flags |= GF_ESI_DATA_AU_START; + pck.flags |= GF_ESI_DATA_AU_END; + if (priv->rap) + pck.flags |= GF_ESI_DATA_AU_RAP; + if (prog->repeat || !priv->vers_inc) { + pck.flags |= GF_ESI_DATA_REPEAT; + fprintf(stdout, "RAP carousel from scene engine sent: ESID=%d - size=%d - ts="LLD"\n", ESID, size, ts); + } else { + fprintf(stdout, "Update from scene engine sent: ESID=%d - size=%d - ts="LLD"\n", ESID, size, ts); + } + prog->streams[i].output_ctrl(&prog->streams[i], GF_ESI_OUTPUT_DATA_DISPATCH, &pck); + return GF_OK; + } + i++; + } + } + return GF_OK; +} + + +static volatile Bool run = 1; + +static void set_broadcast_params(M2TSProgram *prog, u16 esid, u32 period, u32 ts_delta, u16 aggregate_on_stream, Bool adjust_carousel_time, Bool force_rap, Bool aggregate_au, Bool discard_pending, Bool signal_rap, Bool signal_critical, Bool version_inc) +{ + u32 i=0; + GF_ESIStream *priv=NULL; + GF_ESInterface *esi=NULL; + + /*locate our stream*/ + if (esid) { + while (inb_streams) { + if (prog->streams[i].stream_id == esid){ + priv = (GF_ESIStream *)prog->streams[i].input_udta; + esi = &prog->streams[i]; + break; + } + else{ + i++; + } + } + /*TODO: stream not found*/ + } + + /*TODO - set/reset the ESID for the parsers*/ + if (!priv) return NULL; + + /*TODO - if discard is set, abort current carousel*/ + if (discard_pending) { + } + + /*remember RAP flag*/ + priv->rap = signal_rap; + priv->critical = signal_critical; + priv->vers_inc = version_inc; + + priv->ts_delta = ts_delta; + priv->adjust_carousel_time = adjust_carousel_time; + + /*change stream aggregation mode*/ + if ((aggregate_on_stream != (u16)-1) && (priv->aggregate_on_stream != aggregate_on_stream)) { + gf_seng_enable_aggregation(prog->seng, esid, aggregate_on_stream); + priv->aggregate_on_stream = aggregate_on_stream; + } + /*change stream aggregation mode*/ + if (priv->aggregate_on_stream==esi->stream_id) { + if (priv->aggregate_on_stream && (period!=(u32)-1) && (esi->repeat_rate != period)) { + esi->repeat_rate = period; + } + } else { + esi->repeat_rate = 0; + } + + return priv; +} + +static Bool seng_output(void *param) +{ + GF_Err e; + u64 last_src_modif, mod_time; + Bool has_carousel=0; + M2TSProgram *prog = (M2TSProgram *)param; + GF_SceneEngine *seng = prog->seng; + Bool update_context=0; + u32 i=0; + Bool force_rap, adjust_carousel_time, discard_pending, signal_rap, signal_critical, version_inc, aggregate_au; + u32 period, ts_delta; + u16 es_id, aggregate_on_stream; + + if (prog->rate){ + has_carousel = 1; + } + gf_sleep(2000); /*TODO: events instead? What are we waiting for?*/ + gf_seng_encode_context(seng, SampleCallBack); + + last_src_modif = prog->src_name ? gf_file_modification_time(prog->src_name) : 0; + + while (run) { + if (!gf_prompt_has_input()) { + if (prog->src_name) { + mod_time = gf_file_modification_time(prog->src_name); + if (mod_time != last_src_modif) { + FILE *srcf; + char flag_buf[201], *flag; + fprintf(stdout, "Update file modified - processing\n"); + last_src_modif = mod_time; + + srcf = fopen(prog->src_name, "rt"); + if (!srcf) continue; + + /*checks if we have a broadcast config*/ + fgets(flag_buf, 200, srcf); + fclose(srcf); + + aggregate_au = force_rap = adjust_carousel_time = discard_pending = signal_rap = signal_critical = 0; + version_inc = 1; + period = -1; + aggregate_on_stream = -1; + ts_delta = 0; + es_id = 0; + + /*find our keyword*/ + flag = strstr(flag_buf, "gpac_broadcast_config "); + if (flag) { + flag += strlen("gpac_broadcast_config "); + /*move to next word*/ + while (flag && (flag[0]==' ')) flag++; + + while (1) { + char *sep = strchr(flag, ' '); + if (sep) sep[0] = 0; + if (!strnicmp(flag, "esid=", 5)) { + /*ESID on which the update is applied*/ + es_id = atoi(flag+5); + } else if (!strnicmp(flag, "period=", 7)) { + /*TODO: target period carousel for ESID ??? (ESID/carousel)*/ + period = atoi(flag+7); + } else if (!strnicmp(flag, "ts=", 3)) { + /*TODO: */ + ts_delta = atoi(flag+3); + } else if (!strnicmp(flag, "carousel=", 9)) { + /*TODO: why? => sends the update on carousel id specified by this argument*/ + aggregate_on_stream = atoi(flag+9); + } else if (!strnicmp(flag, "restamp=", 8)) { + /*CTS is updated when carouselled*/ + adjust_carousel_time = atoi(flag+8); + } else if (!strnicmp(flag, "discard=", 8)) { + /*when we receive several updates during a single carousel period, this attribute specifies whether the current update discard pending ones*/ + discard_pending = atoi(flag+8); + } else if (!strnicmp(flag, "aggregate=", 10)) { + /*Boolean*/ + aggregate_au = atoi(flag+10); + } else if (!strnicmp(flag, "force_rap=", 10)) { + /*TODO: */ + force_rap = atoi(flag+10); + } else if (!strnicmp(flag, "rap=", 4)) { + /*TODO: */ + signal_rap = atoi(flag+4); + } else if (!strnicmp(flag, "critical=", 9)) { + /*TODO: */ + signal_critical = atoi(flag+9); + } else if (!strnicmp(flag, "vers_inc=", 9)) { + /*Boolean to increment m2ts section version number*/ + version_inc = atoi(flag+9); + } + if (sep) { + sep[0] = ' '; + flag = sep+1; + } else { + break; + } + } + + set_broadcast_params(prog, es_id, period, ts_delta, aggregate_on_stream, adjust_carousel_time, force_rap, aggregate_au, discard_pending, signal_rap, signal_critical, version_inc); + } + + e = gf_seng_encode_from_file(seng, es_id, aggregate_au ? 0 : 1, prog->src_name, SampleCallBack); + if (e) + fprintf(stdout, "Processing command failed: %s\n", gf_error_to_string(e)); + else + gf_seng_aggregate_context(seng, 0); + + update_context=1; + + + + } + } + if (update_context) { + prog->repeat = 1; + e = gf_seng_encode_context(seng, SampleCallBack ); + prog->repeat = 0; + } + + gf_sleep(10); + } else { /*gf_prompt_has_input()*/ + char c = gf_prompt_get_char(); + switch (c) { + case 'u': + { + GF_Err e; + char szCom[8192]; + fprintf(stdout, "Enter command to send:\n"); + fflush(stdin); + szCom[0] = 0; + scanf("%[^\t\n]", szCom); + prog->repeat = 0; + e = gf_seng_encode_from_string(seng, 0, 0, szCom, SampleCallBack); + prog->repeat = 1; + if (e) fprintf(stdout, "Processing command failed: %s\n", gf_error_to_string(e)); + update_context=1; + } + break; + case 'p': + { + char rad[GF_MAX_PATH]; + fprintf(stdout, "Enter output file name - \"std\" for stdout: "); + scanf("%s", rad); + e = gf_seng_save_context(seng, !strcmp(rad, "std") ? NULL : rad); + fprintf(stdout, "Dump done (%s)\n", gf_error_to_string(e)); + } + break; + case 'q': + { + run = 0; + } + } + e = GF_OK; + } + } + + + return e ? 1 : 0; +} + + static void rtp_sl_packet_cbk(void *udta, char *payload, u32 size, GF_SLHeader *hdr, GF_Err e) { GF_ESIRTP *rtp = (GF_ESIRTP*)udta; @@ -1462,10 +627,26 @@ static void rtp_sl_packet_cbk(void *udta, char *payload, u32 size, GF_SLHeader * 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); } -void fill_rtp_es_ifce(GF_ESInterface *ifce, GF_SDPMedia *media, GF_SDPInfo *sdp) +static void fill_rtp_es_ifce(GF_ESInterface *ifce, GF_SDPMedia *media, GF_SDPInfo *sdp) { u32 i; GF_Err e; @@ -1524,6 +705,17 @@ void fill_rtp_es_ifce(GF_ESInterface *ifce, GF_SDPMedia *media, GF_SDPInfo *sdp) 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; @@ -1538,24 +730,39 @@ void fill_rtp_es_ifce(GF_ESInterface *ifce, GF_SDPMedia *media, GF_SDPInfo *sdp) fprintf(stdout, "RTP interface initialized\n"); } -#define MAX_MUX_SRC_PROG 100 -typedef struct +void fill_seng_es_ifce(GF_ESInterface *ifce, u32 i, GF_SceneEngine *seng, u32 period) { - GF_ISOFile *mp4; - u32 nb_streams, pcr_idx; - GF_ESInterface streams[40]; - GF_Descriptor *iod; -} M2TSProgram; + GF_Err e=GF_OK; + char *config_buffer; + u32 len; + GF_ESIStream *stream; + + memset(ifce, 0, sizeof(GF_ESInterface)); + gf_seng_get_stream_config(seng, i, &ifce->stream_id, &config_buffer, &len, &ifce->stream_type, &ifce->object_type_indication, &ifce->timescale); + + ifce->repeat_rate = period; + GF_SAFEALLOC(stream, GF_ESIStream); + stream->rap = 1; + ifce->input_udta = stream; + + //fprintf(stdout, "Caroussel period: %d\n", period); +// e = gf_seng_set_carousel_time(seng, ifce->stream_id, period); + if (e) { + fprintf(stdout, "Cannot set carousel time on stream %d to %d: %s\n", ifce->stream_id, period, gf_error_to_string(e)); + } + ifce->input_ctrl = seng_input_ctrl; + +} -Bool open_program(M2TSProgram *prog, const char *src) +static Bool open_program(M2TSProgram *prog, const char *src, u32 carousel_rate, Bool *force_mpeg4, const char *update) { GF_SDPInfo *sdp; u32 i; GF_Err e; - + memset(prog, 0, sizeof(M2TSProgram)); - /* Open ISO file */ + /*open ISO file*/ if (gf_isom_probe_file(src)) { u32 nb_tracks; u32 first_audio = 0; @@ -1568,6 +775,22 @@ Bool open_program(M2TSProgram *prog, const char *src) if (gf_isom_get_media_type(prog->mp4, i+1) == GF_ISOM_MEDIA_HINT) continue; fill_isom_es_ifce(&prog->streams[i], prog->mp4, i+1); + switch(prog->streams[i].stream_type) { + case GF_STREAM_OD: + case GF_STREAM_SCENE: + *force_mpeg4 = 1; + prog->streams[i].repeat_rate = carousel_rate; + break; + case GF_STREAM_VISUAL: + /*turn on image repeat*/ + switch (prog->streams[i].object_type_indication) { + case GPAC_OTI_IMAGE_JPEG: + case GPAC_OTI_IMAGE_PNG: + ((GF_ESIMP4 *)prog->streams[i].input_udta)->image_repeat_ms = carousel_rate; + break; + } + break; + } prog->nb_streams++; /*get first visual stream as PCR*/ if (!prog->pcr_idx && @@ -1578,26 +801,22 @@ Bool open_program(M2TSProgram *prog, const char *src) if (!first_audio && (gf_isom_get_media_type(prog->mp4, i+1) == GF_ISOM_MEDIA_AUDIO) ) { first_audio = i+1; } - prog->streams[i].sl_config.timestampResolution = 90000; //prog->streams[i].timescale; - prog->streams[i].sl_config.useRandomAccessPointFlag = 1; - prog->streams[i].sl_config.useAccessUnitStartFlag = 1; - prog->streams[i].sl_config.useAccessUnitEndFlag = 1; - prog->streams[i].sl_config.useTimestampsFlag = 1; - prog->streams[i].sl_config.timestampLength = 33; - prog->streams[i].sl_config.tag = GF_ODF_SLC_TAG; - gf_isom_set_extraction_slc(prog->mp4, i+1, 1, &prog->streams[i].sl_config); } - /* WARNING: the returned IOD may be different from the one actually in the file - because it rewrites the SL config according to SL extraction settings. */ - prog->iod = gf_isom_get_root_od(prog->mp4); /*if no visual PCR found, use first audio*/ if (!prog->pcr_idx) prog->pcr_idx = first_audio; - if (prog->pcr_idx) prog->pcr_idx-=1; + if (prog->pcr_idx) { + GF_ESIMP4 *priv; + prog->pcr_idx-=1; + priv = prog->streams[prog->pcr_idx].input_udta; + gf_isom_set_default_sync_track(prog->mp4, priv->track); + } + prog->iod = gf_isom_get_root_od(prog->mp4); return 1; } /*open SDP file*/ if (strstr(src, ".sdp")) { + GF_X_Attribute *att; char *sdp_buf; u32 sdp_size; FILE *_sdp = fopen(src, "rt"); @@ -1608,54 +827,218 @@ Bool open_program(M2TSProgram *prog, const char *src) fseek(_sdp, 0, SEEK_END); sdp_size = ftell(_sdp); fseek(_sdp, 0, SEEK_SET); - sdp_buf = (char*)malloc(sizeof(char)*sdp_size); + sdp_buf = (char*)gf_malloc(sizeof(char)*sdp_size); memset(sdp_buf, 0, sizeof(char)*sdp_size); fread(sdp_buf, sdp_size, 1, _sdp); fclose(_sdp); sdp = gf_sdp_info_new(); e = gf_sdp_info_parse(sdp, sdp_buf, sdp_size); - free(sdp_buf); + gf_free(sdp_buf); if (e) { fprintf(stderr, "Error opening %s : %s\n", src, gf_error_to_string(e)); gf_sdp_info_del(sdp); return 0; } + + i=0; + while ((att = (GF_X_Attribute*)gf_list_enum(sdp->Attributes, &i))) { + char buf[2000]; + u32 size; + char *buf64; + u32 size64; + char *iod_str; + if (strcmp(att->Name, "mpeg4-iod") ) continue; + iod_str = att->Value + 1; + if (strnicmp(iod_str, "data:application/mpeg4-iod;base64", strlen("data:application/mpeg4-iod;base64"))) continue; + + buf64 = strstr(iod_str, ","); + if (!buf64) break; + buf64 += 1; + size64 = strlen(buf64) - 1; + size = gf_base64_decode(buf64, size64, buf, 2000); + + gf_odf_desc_read(buf, size, &prog->iod); + break; + } + prog->nb_streams = gf_list_count(sdp->media_desc); for (i=0; inb_streams; i++) { GF_SDPMedia *media = gf_list_get(sdp->media_desc, i); fill_rtp_es_ifce(&prog->streams[i], media, sdp); + switch(prog->streams[i].stream_type) { + case GF_STREAM_OD: + case GF_STREAM_SCENE: + *force_mpeg4 = 1; + prog->streams[i].repeat_rate = carousel_rate; + break; + } if (!prog->pcr_idx && (prog->streams[i].stream_type == GF_STREAM_VISUAL)) { prog->pcr_idx = i+1; } } + if (prog->pcr_idx) prog->pcr_idx-=1; gf_sdp_info_del(sdp); + return 2; + } + else if (strstr(src, ".bt")) //open .bt file + { + u32 load_type=0; + prog->seng = gf_seng_init(prog, src, load_type, NULL, (load_type == GF_SM_LOAD_DIMS) ? 1 : 0); + + if (!prog->seng) { + fprintf(stdout, "Cannot create scene engine\n"); + exit(0); + } + else{ + fprintf(stdout, "Scene engine created.\n"); + } + + prog->iod = gf_seng_get_iod(prog->seng); + + prog->nb_streams = gf_seng_get_stream_count(prog->seng); + prog->rate = carousel_rate; + *force_mpeg4 = 1; + + for (i=0; inb_streams; i++) { + fill_seng_es_ifce(&prog->streams[i], i, prog->seng, prog->rate); + //fprintf(stdout, "Fill interface\n"); + if (!prog->pcr_idx && (prog->streams[i].stream_type == GF_STREAM_VISUAL)) { + prog->pcr_idx = i+1; + } + } + if (!prog->pcr_idx) prog->pcr_idx=1; + prog->pcr_idx-=1; + prog->th = gf_th_new("Carousel"); + prog->src_name = update; + gf_th_run(prog->th, seng_output, prog); + return 1; } else { fprintf(stderr, "Error opening %s - not a supported input media, skipping.\n", src); return 0; } } +/*parse MP42TS arguments*/ +static GFINLINE GF_Err parse_args(int argc, char **argv, u32 *mux_rate, u32 *carrousel_rate, M2TSProgram *progs, u32 *nb_progs, Bool *mpeg4_signaling, char **src_name, Bool *real_time, u32 *run_time, u32 *output_type, char **ts_out, u16 *port) +{ + Bool rate_found=0, mpeg4_carousel_found=0, prog_found=0, mpeg4_found=0, time_found=0, src_found=0, dst_found=0; + char *prog_name; + u32 res; + s32 i; + for (i=1; impeg4_signaling = mpeg4_signaling; - /* Open mpeg2ts file*/ switch(output_type) { - case 0: + case GF_MP42TS_FILE_OUTPUT: ts_file = fopen(ts_out, "wb"); if (!ts_file ) { fprintf(stderr, "Error opening %s\n", ts_out); goto exit; } break; - case 1: + case GF_MP42TS_UDP_OUTPUT: ts_udp = gf_sk_new(GF_SOCK_TYPE_UDP); if (gf_sk_is_multicast_address((char *)ts_out)) { e = gf_sk_setup_multicast(ts_udp, (char *)ts_out, port, 0, 0, NULL); @@ -1744,11 +1095,11 @@ FILE *ts_file; e = gf_sk_bind(ts_udp, NULL, port, (char *)ts_out, port, GF_SOCK_REUSE_PORT); } if (e) { - fprintf(stdout, "Error inhitializing UDP socket: %s\n", gf_error_to_string(e)); + fprintf(stdout, "Error initializing UDP socket: %s\n", gf_error_to_string(e)); goto exit; } break; - case 2: + case GF_MP42TS_RTP_OUTPUT: ts_rtp = gf_rtp_new(); gf_rtp_set_ports(ts_rtp, port); tr.IsUnicast = gf_sk_is_multicast_address((char *)ts_out) ? 0 : 1; @@ -1783,49 +1134,56 @@ FILE *ts_file; hdr.Marker = 0; break; } - - cur_pid = 100; + + + /****************************************/ + /* declare all streams to the muxer */ + /****************************************/ + cur_pid = 100; /*PIDs start from 100*/ for (i=0; impeg4_signaling) program->iod = progs[i].iod; for (j=0; j=GF_M2TS_STATE_PADDING) break; } break; - case 1: - while ((ts_pck = m2ts_mux_process(muxer, &status)) != NULL) { + case GF_MP42TS_UDP_OUTPUT: + while ((ts_pck = gf_m2ts_mux_process(muxer, &status)) != NULL) { e = gf_sk_send(ts_udp, (char*)ts_pck, 188); if (e) fprintf(stdout, "Error %s sending UDP packet\n", gf_error_to_string(e)); if (status>=GF_M2TS_STATE_PADDING) break; } break; - case 2: - while ((ts_pck = m2ts_mux_process(muxer, &status)) != NULL) { + case GF_MP42TS_RTP_OUTPUT: + while ((ts_pck = gf_m2ts_mux_process(muxer, &status)) != NULL) { hdr.SequenceNumber++; /*muxer clock at 90k*/ ts = muxer->time.sec*90000 + muxer->time.nanosec*9/100000; /*FIXME - better discontinuity check*/ hdr.Marker = (ts < hdr.TimeStamp) ? 1 : 0; hdr.TimeStamp = ts; - e = gf_rtp_send_packet(ts_rtp, &hdr, 0, 0, (char*)ts_pck, 188); + e = gf_rtp_send_packet(ts_rtp, &hdr, (char*)ts_pck, 188, 0); if (e) fprintf(stdout, "Error %s sending RTP packet\n", gf_error_to_string(e)); if (status>=GF_M2TS_STATE_PADDING) break; @@ -1833,29 +1191,36 @@ FILE *ts_file; break; } if (real_time) { - /*abort*/ - if (gf_prompt_has_input()) { - char c = gf_prompt_get_char(); - if (c == 'q') break; + /*refresh every MP42TS_PRINT_FREQ ms*/ + u32 now=gf_sys_clock(); + if (now/MP42TS_PRINT_FREQ != last_print_time/MP42TS_PRINT_FREQ) { + last_print_time = now; + fprintf(stdout, "M2TS: time %d - TS time %d - avg bitrate %d\r", gf_m2ts_get_sys_clock(muxer), gf_m2ts_get_ts_clock(muxer), muxer->avg_br); } - fprintf(stdout, "M2TS: time %d - TS time %d - avg bitrate %d\r", gf_m2ts_get_sys_clock(muxer), gf_m2ts_get_ts_clock(muxer), muxer->avg_br); - } else if (run_time) { + } + + /*cpu load regulation*/ + gf_sleep(1); + + if (run_time) { if (gf_m2ts_get_ts_clock(muxer) > run_time) { - fprintf(stdout, "Stoping multiplex at %d ms (requested runtime %d ms)\n", gf_m2ts_get_ts_clock(muxer), run_time); + fprintf(stdout, "Stopping multiplex at %d ms (requested runtime %d ms)\n", gf_m2ts_get_ts_clock(muxer), run_time); break; } - } else if (status==GF_M2TS_STATE_EOS) { + } + if (status==GF_M2TS_STATE_EOS) { break; } } exit: + run = 0; if (ts_file) fclose(ts_file); if (ts_udp) gf_sk_del(ts_udp); if (ts_rtp) gf_rtp_del(ts_rtp); - if (ts_out) free(ts_out); - m2ts_mux_del(muxer); + if (ts_out) gf_free(ts_out); + if (muxer) gf_m2ts_mux_del(muxer); for (i=0; i -#include -#include -#include -#include "mp42ts.h" - -#if 0 -/************************************************************ - * SL-Packetized Stream related functions - ************************************************************/ -void config_sample_hdr(M2TS_mux_stream *stream) -{ - GF_SAFEALLOC(stream->SLHeader, GF_SLHeader); - if (stream->sample){ - stream->SLHeader->accessUnitStartFlag = 1; - stream->SLHeader->accessUnitEndFlag = 1; - stream->SLHeader->accessUnitLength = stream->sample->dataLength; - stream->SLHeader->randomAccessPointFlag = stream->sample->IsRAP; - stream->SLHeader->compositionTimeStampFlag = 1; - stream->SLHeader->compositionTimeStamp = (stream->sample->CTS_Offset+stream->sample->DTS)*90000/1000; - stream->SLHeader->decodingTimeStampFlag = 1; - stream->SLHeader->decodingTimeStamp = stream->sample->DTS*90000/1000; - printf("SL Header: DTS "LLD", CTS "LLD"\n", stream->SLHeader->decodingTimeStamp, stream->SLHeader->compositionTimeStamp); - } -} - -void SLpacket_in_pes(M2TS_mux_stream *stream, char *Packet, u32 Size) -{ - config_sample_hdr(stream); - gf_sl_packetize(stream->SLConfig, stream->SLHeader, stream->sample->data, stream->sample->dataLength, &stream->sl_packet, &stream->sl_packet_len); -} - -GF_List *CreateTSPacketsFromSLPacket(M2TS_mux_stream *stream, char *SLPacket, u32 SL_Size) -{ - u8 table_id; - u16 table_id_extension; - MP42TS_Buffer *B; - GF_List *sections, *ts_packet; - - if (stream->MP4_type == GF_ISOM_MEDIA_SCENE){ - table_id = GF_M2TS_TABLE_ID_MPEG4_BIFS; - }else if (stream->MP4_type == GF_ISOM_MEDIA_OD){ - table_id = GF_M2TS_TABLE_ID_MPEG4_OD; - } - table_id_extension = 0; - - GF_SAFEALLOC(B, MP42TS_Buffer); - B->length = SL_Size; - B->data = SLPacket; - sections = CreateSections(B, table_id, table_id_extension, stream->SL_section_version_number); - B = EncodeSections(sections); - ts_packet = CreateTSPacketsFromSections(B, stream->mpeg2_es_pid, &stream->continuity_counter); - - free(B); - stream->SL_section_version_number ++; - if (stream->SL_section_version_number > 32) stream->SL_section_version_number = 0; - - return ts_packet; -} - -MP42TS_Buffer *get_iod(GF_BitStream *bs) -{ - GF_Err e; - GF_InitialObjectDescriptor *iod; - u32 DescSize =0; - GF_BitStream *bs_out; - MP42TS_Buffer *B; - iod = (GF_InitialObjectDescriptor *)gf_odf_new_iod(); - - e = gf_odf_read_iod(bs, iod, DescSize); - - bs_out = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); - e = gf_odf_write_iod(bs_out, iod); - - GF_SAFEALLOC(B, MP42TS_Buffer); - B->data = malloc(DescSize); - gf_bs_get_content(bs_out, &B->data, &B->length); - gf_bs_del(bs); - - return B; -} - -/********************************************************************************** - * PSI related functions - **********************************************************************************/ - -/*************************** PMT *****************************/ -void InitializePMT(GF_M2TS_Program *program) -{ - u32 i; - - program->pcr_pid = 0; - for (i = 0; istreams); i++) { - M2TS_mux_stream *stream = (M2TS_mux_stream *)gf_list_get(program->streams, i); - if (stream->MP2_type == GF_M2TS_VIDEO_MPEG2) { - program->pcr_pid = stream->mpeg2_es_pid; - } else if (!program->pcr_pid) { - program->pcr_pid = stream->mpeg2_es_pid; - } - } -} - -MP42TS_Buffer *EncodePMT(GF_M2TS_Program *program, MP42TS_Buffer *iod) -{ - u32 i; - MP42TS_Buffer *B; - return B; -} - -void CreateTSPacketsForPMTs(M2TS_muxer *muxer) -{ - u32 i, j, nb_progs; - GF_M2TS_Program *program; - M2TS_mux_stream *stream; - MP42TS_Buffer *B; - GF_List *sections; - Bool use_iod = 0; - MP42TS_Buffer *B_iod; - - muxer->pmt_ts_packet = gf_list_new(); - nb_progs = gf_list_count(muxer->pat_table); - for (i= 0; ipat_table,i); - program->streams = gf_list_new(); - - for (j = 0; j < gf_list_count(muxer->streams); j++) { - stream = gf_list_get(muxer->streams, j); - stream->mpeg2_es_pid = 100*(i+1)+10*(j+1); - gf_list_add(program->streams, stream); - } - - InitializePMT(program); - - if (use_iod) { - GF_ObjectDescriptor *iod; - GF_BitStream *bs_iod; - - /* iod */ - iod = (GF_ObjectDescriptor *)gf_isom_get_root_od(muxer->mp4_in); - /* Mise à jour des SLConfigDescriptor à la façon MPEG-2 (timestamp_length = 33 ...) */ - if (iod->tag == GF_ODF_OD_TAG || iod->tag == GF_ODF_IOD_TAG) { - GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)iod; - u32 i, count = gf_list_count(od->ESDescriptors); - for (i = 0; i < count; i++ ){ - GF_ESD * esd = gf_list_get(od->ESDescriptors, i); - esd->slConfig->AUDuration = 0; - esd->slConfig->AULength = 0; - esd->slConfig->AUSeqNumLength = 0; - esd->slConfig->CUDuration = 0; - esd->slConfig->degradationPriorityLength = 0; - esd->slConfig->durationFlag = 0; - esd->slConfig->hasRandomAccessUnitsOnlyFlag = 0; - esd->slConfig->instantBitrateLength = 32; - esd->slConfig->OCRLength = 0; - esd->slConfig->OCRResolution = 90000; - esd->slConfig->packetSeqNumLength = 0; - esd->slConfig->predefined = 0; - esd->slConfig->startCTS = 0; - esd->slConfig->startDTS = 0; - esd->slConfig->timeScale = 0; - esd->slConfig->timestampLength = 33; - esd->slConfig->timestampResolution = 90000; - esd->slConfig->useAccessUnitEndFlag = 1; - esd->slConfig->useAccessUnitStartFlag = 1; - esd->slConfig->useIdleFlag = 1; - esd->slConfig->usePaddingFlag = 0; - esd->slConfig->useRandomAccessPointFlag = 0; - esd->slConfig->useTimestampsFlag = 1; - } - } - bs_iod = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); - - gf_odf_write_od(bs_iod, iod); - gf_odf_desc_del((GF_Descriptor *)iod); - - GF_SAFEALLOC(B_iod, MP42TS_Buffer); - gf_bs_get_content(bs_iod, &B_iod->data, &B_iod->length); - gf_bs_del(bs_iod); - } - - B = EncodePMT(program, (use_iod ? B_iod: NULL)); - sections = CreateSections(B, GF_M2TS_TABLE_ID_PMT, program->number, 1); - B = EncodeSections(sections); - gf_list_add(muxer->pmt_ts_packet, CreateTSPacketsFromSections(B, program->pmt_pid, NULL)); - } -} - - -/*************************** SDT *****************************/ -MP42TS_Buffer *encodeSDT(GF_List *prog_list, char *provider_name, u32 provider_name_lenth, char *service_name, u32 service_name_lenth) -{ - u32 i, j, k, CRC; - GF_M2TS_Program *program; - MP42TS_Buffer *B; - u16 desc_lenth; - u32 nb_program = gf_list_count(prog_list); - GF_SAFEALLOC(B, MP42TS_Buffer); - B->length = nb_program * (10 + service_name_lenth + provider_name_lenth) + 7; // un seul descripteur: service desc 0x48 - B->data = malloc(B->length); - - B->data[0] = 0; // original_network_id (2 byte) - B->data[1] = 0x1; - B->data[2] = 0; // reserved - // program loop - for (k= 0; k < gf_list_count(prog_list); k++){ - program = gf_list_get(prog_list,k); - B->data[3 + k*(10 + provider_name_lenth + service_name_lenth)] = (program->number >> 8) & 0xff; // service_id - B->data[4 + k*(10 + provider_name_lenth + service_name_lenth)] = program->number & 0xff; // service_id - B->data[5 + k*(10 + provider_name_lenth + service_name_lenth)] = 0; // EIT - - desc_lenth = provider_name_lenth + service_name_lenth + 5; // desc_loop_lenth - B->data[6 + k*(10 + provider_name_lenth + service_name_lenth)] = ((desc_lenth >> 8) & 0xf) | 0x80; // dscriptor loop length : 1 desc // 0x4 status = running - B->data[7 + k*(10 + provider_name_lenth + service_name_lenth)] = desc_lenth & 0xff;// dscriptor loop length - // descriptor loop - B->data[8 + k*(10 + provider_name_lenth + service_name_lenth)] = 0x48; // desct tag - B->data[9 + k*(10 + provider_name_lenth + service_name_lenth)] = service_name_lenth + provider_name_lenth + 3; // desc_lenth - B->data[10 + k*(10 + provider_name_lenth + service_name_lenth)] = 0x1; // srvice type : 0x1 = digital TV - B->data[11 + k*(10 + provider_name_lenth + service_name_lenth)] = provider_name_lenth; - for (i = 0; i < provider_name_lenth; i++){ - B->data[12 + i + k*(10 + provider_name_lenth + service_name_lenth)] = provider_name[i]; - } - B->data[12 + i + k*(10 + provider_name_lenth + service_name_lenth)] = service_name_lenth; - for (j = 0; j < service_name_lenth; j++){ - B->data[13+i+j + k*(10 + provider_name_lenth + service_name_lenth)] = service_name[j]; - } - // descriptor loop end - } - // crc // - CRC = gf_crc_32(B->data,B->length-4); - B->data[B->length-4] = (CRC >> 24) & 0xFF; - B->data[B->length-3] = (CRC >> 16) & 0xFF; - B->data[B->length-2] = (CRC >> 8) & 0xFF; - B->data[B->length-1] = CRC & 0xFF; - - return B; -} - -void CreateTSPacketsForSDT(M2TS_muxer *muxer, char *provider_name, char *service_name) -{ - MP42TS_Buffer *B; - GF_List *sections; - B = encodeSDT(muxer->pat_table, provider_name, 4, service_name, 8); - sections = CreateSections(B, GF_M2TS_TABLE_ID_SDT_ACTUAL, 1, 1); - B = EncodeSections(sections); - muxer->sdt_ts_packet = CreateTSPacketsFromSections(B, 0x11, NULL); -} - - -/************************************************************************************* - * PES related functions - ************************************************************************************/ -void add_pes_header(GF_BitStream *bs, M2TS_mux_stream *stream) -{ - u32 pes_len; - u32 pes_header_data_length; - Bool use_pts, use_dts; - - use_pts = 1; - use_dts = 1; - pes_header_data_length = 10; - - if (stream->muxer->log_level == LOG_PES) fprintf(stdout, "PID %d - Starting PES for AU %d - DTS "LLD" - PTS "LLD" - RAP %d\n", stream->mpeg2_es_pid, stream->sample_number, stream->sample->DTS, stream->sample->DTS+stream->sample->CTS_Offset, stream->sample->IsRAP); - gf_bs_write_int(bs, 0x1, 24);//packet start code - gf_bs_write_int(bs, stream->mpeg2_pes_streamid, 8);// stream id - - pes_len = stream->sample->dataLength + 13; // 13 = header size (including PTS/DTS) - gf_bs_write_int(bs, pes_len, 16); // pes packet length - - 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, 0x0, 1); // copyright - gf_bs_write_int(bs, 0x0, 1); // original or copy - - gf_bs_write_int(bs, use_pts, 1); - gf_bs_write_int(bs, use_dts, 1); - gf_bs_write_int(bs, 0x0, 6); //6 flags = 0 (ESCR, ES_rate, DSM_trick, additional_copy, PES_CRC, PES_extension) - - gf_bs_write_int(bs, pes_header_data_length, 8); - - if (use_pts && use_dts){ - u64 cts, dts, t; - - cts = stream->sample->DTS + stream->sample->CTS_Offset; - - gf_bs_write_int(bs, 0x2, 4); // reserved '0010' - t = ((cts >> 30) & 0x7); - gf_bs_write_long_int(bs, t, 3); - gf_bs_write_int(bs, 1, 1); // marker bit - t = ((cts >> 15) & 0x7fff); - gf_bs_write_long_int(bs, t, 15); - gf_bs_write_int(bs, 1, 1); // marker bit - t = cts & 0x7fff; - gf_bs_write_long_int(bs, t, 15); - gf_bs_write_int(bs, 1, 1); // marker bit - - dts = stream->sample->DTS; - - gf_bs_write_int(bs, 0x1, 4); // reserved '0001' - t = ((dts >> 30) & 0x7); - gf_bs_write_long_int(bs, t, 3); - gf_bs_write_int(bs, 1, 1); // marker bit - t = ((dts >> 15) & 0x7fff); - gf_bs_write_long_int(bs, t, 15); - gf_bs_write_int(bs, 1, 1); // marker bit - t = dts & 0x7fff; - gf_bs_write_long_int(bs, t, 15); - gf_bs_write_int(bs, 1, 1); // marker bit - } - -} - -u8 *encode_ts(M2TS_muxer *muxer, M2TS_mux_stream *stream) -{ - GF_BitStream *bs; - u8 *ts_data; - u32 ts_data_len; - - /* length of the header from start of pes header to start of payload (including PTS/DTS) */ - u32 pes_header_length = 19; - u32 remain; - Bool PUSI; - u32 adaptation_length; - u32 payload_length; - Bool is_rap; - - bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); - - if (stream->nb_bytes_written == 0){ - PUSI = 1; - } else { - PUSI = 0; - } - - gf_bs_write_int(bs, 0x47, 8); // sync byte - gf_bs_write_int(bs, 0, 1); // error indicator - gf_bs_write_int(bs, PUSI, 1); // start ind - gf_bs_write_int(bs, 0, 1); // transport priority - gf_bs_write_int(bs, stream->mpeg2_es_pid, 13); // pid - gf_bs_write_int(bs, 0, 2); // scrambling - - remain = stream->sample->dataLength + pes_header_length*PUSI - stream->nb_bytes_written; - - if (stream->MP2_type == GF_M2TS_VIDEO_MPEG2 && stream->sample->IsRAP) is_rap=1; - else is_rap = 0; - - adaptation_length = add_adaptation(bs, &stream->continuity_counter, - stream->PCR, - stream->stream_time, - is_rap, - remain); - - payload_length = 184 - adaptation_length; - - if (PUSI){ - u32 pes_payload_length; - - add_pes_header(bs, stream); - pes_payload_length = payload_length - pes_header_length; - gf_bs_write_data(bs, stream->sample->data, pes_payload_length); - stream->nb_bytes_written += pes_payload_length; -// fprintf(stdout, "TS payload length %d - total %d\n", pes_payload_length, stream->nb_bytes_written); - } else { - gf_bs_write_data(bs, stream->sample->data+stream->nb_bytes_written, payload_length); - stream->nb_bytes_written += payload_length; -// fprintf(stdout, "TS payload length %d - total %d \n", payload_length, stream->nb_bytes_written); - } - gf_bs_get_content(bs, &ts_data, &ts_data_len); - gf_bs_del(bs); - return ts_data; -} - -void create_one_ts(M2TS_muxer *muxer, M2TS_mux_stream *stream) -{ - u8 *data; - - if (!stream->sample || stream->nb_bytes_written >= stream->sample->dataLength){ - u32 tmp; - /* TODO free sample ? */ - stream->sample = NULL; - stream->sample_number ++; - stream->sample = gf_isom_get_sample(muxer->mp4_in, stream->track_number, stream->sample_number, &tmp); - if (stream->sample) stream->stream_time = stream->sample->DTS; - stream->nb_bytes_written = 0; - } - - if (stream->sample) { - data = encode_ts(muxer, stream); - fwrite(data, 1, 188, muxer->ts_out); - //fwrite(data+4, 1, 184, stream->pes_out); - } -} - -void get_mux_stream_sample(GF_ISOFile *mp4_in, M2TS_mux_stream *stream); - -void initialize_muxer(M2TS_muxer *muxer) -{ - M2TS_mux_stream *stream; - u32 i, nb_track; - - muxer->muxer_time = 0; - muxer->streams = gf_list_new(); - muxer->pmt_ts_packet = gf_list_new(); - - nb_track = gf_isom_get_track_count(muxer->mp4_in); - for (i=1; i<=nb_track; i++) { - char out[500]; - GF_SAFEALLOC(stream, M2TS_mux_stream); - stream->muxer = muxer; - stream->track_number = i; - stream->mpeg4_es_id = gf_isom_get_track_id(muxer->mp4_in, i); - stream->MP4_type = gf_isom_get_media_type(muxer->mp4_in, i); - stream->nb_samples = gf_isom_get_sample_count(muxer->mp4_in, i); - if (0) { - sprintf(out, "out%i.pes", i); - stream->pes_out = fopen(out, "wb"); - } - - switch (stream->MP4_type) { - case GF_ISOM_MEDIA_VISUAL: - if (muxer->use_sl) { - stream->MP2_type = GF_M2TS_SYSTEMS_MPEG4_PES; - } else { - stream->MP2_type = GF_M2TS_VIDEO_MPEG2; - } - stream->mpeg2_pes_streamid = 0xE0 + i; - break; - case GF_ISOM_MEDIA_AUDIO: - if (muxer->use_sl) { - stream->MP2_type = GF_M2TS_SYSTEMS_MPEG4_PES; - } else { - stream->MP2_type = GF_M2TS_AUDIO_MPEG2; - } - stream->mpeg2_pes_streamid = 0xC0 + i; - break; - case GF_ISOM_MEDIA_OD: - stream->MP2_type = GF_M2TS_SYSTEMS_MPEG4_SECTIONS; - break; - case GF_ISOM_MEDIA_SCENE: - stream->MP2_type = GF_M2TS_SYSTEMS_MPEG4_SECTIONS; - break; - default: - fprintf(stderr, "Track type %d not supported in MPEG-2\n", stream->MP4_type); - } - - if (stream->MP2_type == GF_M2TS_SYSTEMS_MPEG4_PES || - stream->MP2_type == GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { - stream->SLConfig = (GF_SLConfig *)gf_odf_desc_new(GF_ODF_SLC_TAG); - stream->SLConfig->AUDuration = 0; - stream->SLConfig->AULength = 0; - stream->SLConfig->AUSeqNumLength = 0; - stream->SLConfig->CUDuration = 0; - stream->SLConfig->degradationPriorityLength = 0; - stream->SLConfig->durationFlag = 0; - stream->SLConfig->hasRandomAccessUnitsOnlyFlag = 0; - stream->SLConfig->instantBitrateLength = 32; - stream->SLConfig->OCRLength = 0; - stream->SLConfig->OCRResolution = 90000; - stream->SLConfig->packetSeqNumLength = 0; - stream->SLConfig->predefined = 0; - stream->SLConfig->startCTS = 0; - stream->SLConfig->startDTS = 0; - stream->SLConfig->timeScale = 0; - stream->SLConfig->timestampLength = 33; - stream->SLConfig->timestampResolution = 90000; - stream->SLConfig->useAccessUnitEndFlag = 1; - stream->SLConfig->useAccessUnitStartFlag = 1; - stream->SLConfig->useIdleFlag = 1; - stream->SLConfig->usePaddingFlag = 0; - stream->SLConfig->useRandomAccessPointFlag = 0; - stream->SLConfig->useTimestampsFlag = 1; - } - if (stream->MP2_type == GF_M2TS_SYSTEMS_MPEG4_PES){ - stream->SL_in_pes = 1; - } else if (stream->MP2_type == GF_M2TS_SYSTEMS_MPEG4_SECTIONS){ - stream->SL_in_section = 1; - stream->sl_section_ts_packets = gf_list_new(); - } - gf_list_add(muxer->streams, stream); - } -} - -/********************************************************************************* - * Muxer general functions - ********************************************************************************/ -M2TS_mux_stream *get_current_stream(M2TS_muxer *muxer) -{ - M2TS_mux_stream *stream; - M2TS_mux_stream *res; - u32 i, count; - u64 inf_time = 0xffffffffffffffff; - - count = gf_list_count(muxer->streams); - for(i = 0; i < count; i++) { - stream = gf_list_get(muxer->streams, i); - if (stream->stream_time < inf_time) { - res = stream; - inf_time = stream->stream_time; - } - } - - if (res->sample_number > res->nb_samples) muxer->end = 1; - return stream; -} - -M2TS_mux_stream *compare_muxer_time_with_stream_time(M2TS_muxer *muxer) -{ - M2TS_mux_stream *stream; - u32 i, k, count; - u64 inf_time = 0xffffffffffffffff; - u32 stream_with_inf_time = 0; - - k=0; - count = gf_list_count(muxer->streams); - for(i = 0; i < count; i++) { - stream = gf_list_get(muxer->streams, i); - if (stream->sample) { - if (stream->stream_time < inf_time) { - inf_time = stream->stream_time; - stream_with_inf_time = i; - } - } else { - u32 SI_index = (u32)(muxer->TS_Rate * muxer->SI_interval / 188); - if (stream->SL_in_section && stream->repeat_section && - muxer->insert_SI == SI_index){ - // par exemple pour qu'une image soit retransmise - stream->nb_bytes_written = 0; - update_muxer(muxer, muxer->mp4_in, stream); - } - k++; - } - } - - if (k == i) muxer->end = 1; - stream = gf_list_get(muxer->streams, stream_with_inf_time); - muxer->muxer_time = stream->stream_time; - return stream; -} - -void M2TS_OnEvent_muxer(M2TS_muxer *muxer, u32 evt_type, void *par) -{ - M2TS_mux_stream *stream; - - switch (evt_type) { - case GF_M2TS_EVT_PAT: - { - u8 *data; - u32 i, count; - count = gf_list_count(muxer->pat_ts_packet); - for (i = 0; i < count; i++) { - data = gf_list_get(muxer->pat_ts_packet, i); - fwrite(data, 1, 188, muxer->ts_out); - } - } - break; - - case GF_M2TS_EVT_SDT: - { - u8 *data; - u32 i, count; - count = gf_list_count(muxer->sdt_ts_packet); - for (i = 0; i < count; i++) { - data = gf_list_get(muxer->sdt_ts_packet, i); - fwrite(data, 1, 188, muxer->ts_out); - } - } - break; - - case GF_M2TS_EVT_PMT: - { - u32 i, j, count1, count2; - u8 *data; - GF_List *ts_packet; - - count1 = gf_list_count(muxer->pmt_ts_packet); - for (i = 0; i < count1; i++) { - ts_packet = gf_list_get(muxer->pmt_ts_packet, i); - count2 = gf_list_count(ts_packet); - for (j = 0; jts_out); - } - } - muxer->insert_SI = 0; - } - break; - - case GF_M2TS_EVT_ES: - stream = get_current_stream(muxer); //compare_muxer_time_with_stream_time(muxer); - if (muxer->end) return; - create_one_ts(muxer, stream); - break; - -/* - case GF_M2TS_EVT_SL_SECTION: - - stream = par; - if (!stream->sl_packet && stream->sample){ - // AU ---> SL : 1 sample = 1paquet SL - if (stream->SL_in_section){ - static u32 writeSL = 1; - u32 count; - // créer une section ou plus pour ce paquet SL => list de paquet TS - printf("sample number %d: DTS "LLD", CTS Offset %d\n", stream->sample_number, stream->sample->DTS, stream->sample->CTS_Offset); - - config_sample_hdr(stream); - gf_sl_packetize(stream->SLConfig, stream->SLHeader, stream->sample->data, stream->sample->dataLength, &stream->sl_packet, &stream->sl_packet_len); - - - writeSL++; - stream->sl_section_ts_packets = CreateTSPacketsFromSLPacket(stream, stream->sl_packet, stream->sl_packet_len); - - count = gf_list_count(stream->sl_section_ts_packets); - printf("sl_packet_length %d ,nb ts packet %d \n", stream->sl_packet_len, count); - - }else if (stream->SL_in_pes && (stream->nb_bytes_written == 0)){ - config_sample_hdr(stream); - gf_sl_packetize(stream->SLConfig, stream->SLHeader, stream->sample->data, stream->sample->dataLength, &stream->sample->data, &stream->sample->dataLength); - - } - - } - if (stream->SL_in_section && stream->sl_packet){ - - unsigned char *data; - static nb_ts_sec = 0; - data = gf_list_get(stream->sl_section_ts_packets, 0); - fwrite(data, 1, 188, muxer->ts_out); - nb_ts_sec ++; - gf_list_rem(stream->sl_section_ts_packets, 0); - - - if (gf_list_count(stream->sl_section_ts_packets) == 0){ - - printf("nb ts write %d\n\n", nb_ts_sec); - nb_ts_sec = 0; - - stream->sl_packet = NULL; - stream->sl_packet_len = 0; - stream->nb_bytes_written = 0; - stream->sample->dataLength = 0; - free(stream->sample->data); - update_muxer(muxer, muxer->mp4_in, stream); - } - - }else if (stream->SL_in_pes && stream->sample->data){ - - create_one_ts(muxer, stream); - if (stream->nb_bytes_written == 0){ - stream->sl_packet = NULL; - stream->sl_packet_len = 0; - } - } - - - break; - - case GF_M2TS_EVT_DEMUX_DATA: - { - GF_BitStream *mp2_bs; - u32 pid_found = 0; - u64 pos, has_data; - mp2_bs = par; - - has_data = gf_bs_available(mp2_bs); - while (has_data > 0) { - u32 i = 0; - unsigned char *data; - u32 data_size = 188; - data = malloc(data_size); - // read one ts packet - gf_bs_read_data(mp2_bs, data, data_size); - has_data = gf_bs_available(mp2_bs); - pos = gf_bs_get_position(mp2_bs); - if (data[0] != 0x47){ - u32 k = 0; - i++; - printf("Sync byte error %d\r", i); - while (data[0] != 0x47 && has_data){ - data = &data[1]; - data[187] = gf_bs_read_u8(mp2_bs); - k++; - } - }else{ - - // gf_m2ts_process_data(ts, data, data_size); - m2ts_write_ts_packet(muxer, data, &pid_found); - } - pos = gf_bs_get_position(mp2_bs); - if (pid_found == 1) break; - } - } - break;*/ - } -} - - -/*Events used by the MPEGTS muxer*/ -enum -{ - GF_M2TS_EVT_PAT = 0, - GF_M2TS_EVT_PMT, - GF_M2TS_EVT_SDT, - GF_M2TS_EVT_ES, - GF_M2TS_EVT_SL_SECTION, - /* Data from demuxer */ - GF_M2TS_EVT_DEMUX_DATA, -}; - -typedef struct -{ - u8 *data; - u32 length; -} MP42TS_Buffer; - -typedef struct M2TS_mux_stream -{ - u32 track_number; - u32 mpeg2_es_pid; - u32 mpeg2_pes_streamid; - u32 mpeg4_es_id; - - GF_ISOSample *sample; - u32 sample_number; - u32 nb_samples; - u32 nb_bytes_written; - u32 continuity_counter; - - GF_List *packets; - - - GF_SLConfig *SLConfig; - GF_SLHeader *SLHeader; - Bool SL_in_pes; - u8 *sl_packet; - u32 sl_packet_len; - Bool SL_in_section; - Bool repeat_section; - u32 SL_section_version_number; - GF_List *sl_section_ts_packets; - - GF_M2TS_PES *PES; - - u8 is_time_initialized; - u64 stream_time; - - u32 MP2_type; - u32 MP4_type; - - FILE *pes_out; - - Bool PCR; - - struct M2TS_muxer *muxer; -} M2TS_mux_stream; - -typedef struct M2TS_muxer -{ - u32 TS_Rate; // bps - float PAT_interval; // s - float PMT_interval; // s - float SI_interval; //s - - u32 send_pat, send_pmt; - - /* ~ PCR */ - u64 muxer_time; - - /* M2TS_mux_stream List*/ - GF_List *streams; - - GF_List *pat_table; /* List of GF_M2TS_Program */ - - GF_List *pat_ts_packet; /* List of Encoded TS packets corresponding to PAT */ - GF_List *sdt_ts_packet; /* List of Encoded TS packets corresponding to SDT */ - GF_List *pmt_ts_packet; /* List of List of Encoded TS packets corresponding to each PMT */ - - /*user callback - MUST NOT BE NULL*/ - void (*on_event)(struct M2TS_muxer *muxer, u32 evt_type, void *par); - /*private user data*/ - void *user; - - GF_ISOFile *mp4_in; - FILE *ts_out; - - u32 insert_SI; - Bool end; - - Bool use_sl; - - u32 log_level; -} M2TS_muxer; - -typedef struct -{ - u32 *pid; - u32 length; -} M2TS_pid_list; -#endif diff --git a/applications/testapps/mp42ts/mp42ts.dsp b/applications/testapps/mp42ts/mp42ts.dsp index 50df482..61f3b4b 100644 --- a/applications/testapps/mp42ts/mp42ts.dsp +++ b/applications/testapps/mp42ts/mp42ts.dsp @@ -1,99 +1,99 @@ -# Microsoft Developer Studio Project File - Name="mp42ts" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=mp42ts - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mp42ts.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mp42ts.mak" CFG="mp42ts - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mp42ts - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "mp42ts - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mp42ts - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/mp42ts.exe" /libpath:"../../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "mp42ts - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/mp42ts.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" -# SUBTRACT LINK32 /nodefaultlib - -!ENDIF - -# Begin Target - -# Name "mp42ts - Win32 Release" -# Name "mp42ts - Win32 Debug" -# Begin Source File - -SOURCE=.\main.c -# End Source File -# Begin Source File - -SOURCE=.\mp42ts.c -# End Source File -# Begin Source File - -SOURCE=.\mp42ts.h -# End Source File -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="mp42ts" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=mp42ts - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mp42ts.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mp42ts.mak" CFG="mp42ts - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mp42ts - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "mp42ts - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mp42ts - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/mp42ts.exe" /libpath:"../../../extra_lib/lib/w32_rel" + +!ELSEIF "$(CFG)" == "mp42ts - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/mp42ts.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" +# SUBTRACT LINK32 /nodefaultlib + +!ENDIF + +# Begin Target + +# Name "mp42ts - Win32 Release" +# Name "mp42ts - Win32 Debug" +# Begin Source File + +SOURCE=.\main.c +# End Source File +# Begin Source File + +SOURCE=.\mp42ts.c +# End Source File +# Begin Source File + +SOURCE=.\mp42ts.h +# End Source File +# End Target +# End Project diff --git a/applications/testapps/mp42ts/mp42ts.h b/applications/testapps/mp42ts/mp42ts.h index 18085d2..5ed59a1 100644 --- a/applications/testapps/mp42ts/mp42ts.h +++ b/applications/testapps/mp42ts/mp42ts.h @@ -83,6 +83,10 @@ typedef struct __m2ts_mux_stream { /*multiplexer time - NOT THE PCR*/ M2TS_Time time; + + /* MPEG-4 SL Config */ + GF_SLConfig sl_config; + /*table tools*/ M2TS_Mux_Table *tables; /*total table sizes for bitrate estimation (PMT/PAT/...)*/ @@ -103,12 +107,16 @@ typedef struct __m2ts_mux_stream { GF_ESIPacket pck; u32 pck_offset; + Bool force_new; struct __elementary_stream_ifce *ifce; Double ts_scale; + u64 initial_ts; /*packet fifo*/ M2TS_Packet *pck_first, *pck_last; + /*packet reassembler (PES packets are most of the time full frames)*/ + M2TS_Packet *pck_reassembler; GF_Mutex *mx; /*avg bitrate compute*/ u64 last_br_time; @@ -118,6 +126,8 @@ typedef struct __m2ts_mux_stream { u8 table_id; GF_SLHeader sl_header; //GF_SLConfig sl_config; + + u32 last_aac_time; } M2TS_Mux_Stream; @@ -133,10 +143,11 @@ struct __m2ts_mux_program { /*pointer to PCR stream*/ M2TS_Mux_Stream *pcr; - Bool pcr_init; /*TS time at pcr init*/ - M2TS_Time pcr_init_ts_time; - u64 pcr_init_time; + M2TS_Time ts_time_at_pcr_init; + u64 pcr_init_time, num_pck_at_pcr_init; + u64 last_pcr; + u32 last_sys_clock; GF_Descriptor *iod; }; @@ -148,8 +159,13 @@ struct __m2ts_mux { u16 ts_id; Bool needs_reconfig; + + /* used to indicate that the input data is pushed to the muxer (i.e. not read from a file) + or that the output data is sent on sockets (not written to a file) */ Bool real_time; - /*if set bit-rate won't be re-estimated*/ + + /* indicates if the multiplexer shall target a fix bit rate (monitoring timing and produce padding packets) + or if the output stream will contain only input data*/ Bool fixed_rate; /*output bit-rate in bit/sec*/ @@ -157,12 +173,18 @@ struct __m2ts_mux { char dst_pck[188], null_pck[188]; - /*multiplexer time in micro-sec*/ - M2TS_Time time, init_ts_time; - u32 init_sys_time; + /*multiplexer time, incremented each time a packet is sent + used to monitor the sending of muxer related data (PAT, ...) */ + M2TS_Time time; + + /* Time of the muxer when the first call to process is made (first packet sent?) */ + M2TS_Time init_ts_time; + + /* System time when the muxer is started */ + u32 init_sys_time; Bool eos_found; - u32 pck_sent, last_br_time, avg_br; + u32 pck_sent_over_br_window, last_br_time, avg_br; u64 tot_pck_sent, tot_pad_sent; Bool mpeg4_signaling; diff --git a/applications/testapps/mp42ts/mp42ts.vcproj b/applications/testapps/mp42ts/mp42ts.vcproj new file mode 100644 index 0000000..e425096 --- /dev/null +++ b/applications/testapps/mp42ts/mp42ts.vcproj @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/applications/testapps/mp4_streamer/Makefile b/applications/testapps/mp4_streamer/Makefile deleted file mode 100644 index 2628096..0000000 --- a/applications/testapps/mp4_streamer/Makefile +++ /dev/null @@ -1,64 +0,0 @@ -include ../../../config.mak - -vpath %.c $(SRC_PATH)/applications/testapps/mp4_streamer - -CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include - -ifeq ($(DEBUGBUILD), yes) -CFLAGS+=-g -LDFLAGS+=-g -endif - -ifeq ($(GPROFBUILD), yes) -CFLAGS+=-pg -LDFLAGS+=-pg -endif - -#common obj -OBJS= main.o - -LINKFLAGS=-L../../../bin/gcc -ifeq ($(CONFIG_WIN32),yes) -EXE=.exe -PROG=mp4_streamer$(EXE) -#LINKFLAGS+=-lgpac_static -lz $(EXTRALIBS) -LINKFLAGS+=-lgpac -else -EXT= -PROG=mp4_streamer -#LINKFLAGS+=-lgpac_static $(EXTRALIBS) $(GPAC_SH_FLAGS) -lz $(OGL_LIBS) -LINKFLAGS+=-lgpac $(OGL_LIBS) -endif - - -SRCS := $(OBJS:.o=.c) - -all: $(PROG) - -$(PROG): $(OBJS) - $(CC) $(LDFLAGS) -o ../../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) - - -%.o: %.c - $(CC) $(CFLAGS) -c -o $@ $< - - -clean: - rm -f $(OBJS) ../../../bin/gcc/$(PROG) - -dep: depend - -depend: - rm -f .depend - $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend - -distclean: clean - rm -f Makefile.bak .depend - - - -# include dependency files if they exist -# -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/applications/testapps/mp4_streamer/configuration.cfg b/applications/testapps/mp4_streamer/configuration.cfg deleted file mode 100644 index 1e5b8da..0000000 --- a/applications/testapps/mp4_streamer/configuration.cfg +++ /dev/null @@ -1,31 +0,0 @@ -#---------------------------------------------------------------------- -# Configuration File of the mp4 streamer -#---------------------------------------------------------------------- -# Usage: time in ms, bit rate in kbps, port numbers must be even -#---------------------------------------------------------------------- -[GLOBAL] -nbSession=2 -burst_mode=yes -off_duration=500 -burst_duration=500 -burst_bitrate=8000 - -#an IPV4 multicast address -IP_dest=233.64.133.10 -#IPV4 loopback (localhost) -#IP_dest=127.0.0.1 -#IPV6 multicast loopback -#IP_dest=FF01::1 - -#IPV6 loopback -#IP_dest=::1 - -[SESSION1] -port=7000 -file=tnt.mp4 -looping=1 - -[SESSION2] -port=7002 -file=av.mp4 -looping=1 diff --git a/applications/testapps/mp4_streamer/main.c b/applications/testapps/mp4_streamer/main.c deleted file mode 100644 index 63a31a8..0000000 --- a/applications/testapps/mp4_streamer/main.c +++ /dev/null @@ -1,1175 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Cyril Concolato / Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / mp4 simple streamer application - * - * 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 -#include -#include -#include - -GP_RTPPacketizer *gf_rtp_packetizer_create_and_init_from_file(GF_ISOFile *file, - u32 TrackNum, - void *cbk_obj, - void (*OnNewPacket)(void *cbk, GF_RTPHeader *header), - void (*OnPacketDone)(void *cbk, GF_RTPHeader *header), - void (*OnDataReference)(void *cbk, u32 payload_size, u32 offset_from_orig), - void (*OnData)(void *cbk, char *data, u32 data_size, Bool is_head), - u32 Path_MTU, - u32 max_ptime, - u32 default_rtp_rate, - u32 flags, - u8 PayloadID, - Bool copy_media, - u32 InterleaveGroupID, - u8 InterleaveGroupPriority); -void gf_hinter_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, GF_ISOFile *file, u32 track); - -//------------------------------------------------------------ -// Define -//------------------------------------------------------------ -#define PATHFILE "." -#define RTP_HEADER_SIZE 12 // in bytes (octets) -#define BASE_PAYT 96 - -//------------------------------------------------------------ -// Typedef -//------------------------------------------------------------ -enum -{ - LOG_NONE = 0, - LOG_BURST, - LOG_AU, - LOG_PACKET, -}; - -typedef struct -{ - u32 log_level; - u32 path_mtu; - struct __tag_rtp_session *session; - u8 payt; - - Bool burst_mode; - - /*burst mode configuration*/ - u32 burstDuration; - u32 burstBitRate; - u32 burstSize; - u32 offDuration; - u32 averageBitRate; - u32 cycleDuration; - u32 nbBurstSent; -} Streamer; - -typedef struct __tag_rtp_pck -{ - struct __tag_rtp_pck *next; - - GF_RTPHeader header; - char *payload; - u32 payload_len; -} RTP_Packet; - -typedef struct __tag_rtp_stream -{ - struct __tag_rtp_stream *next; - - u32 current_au; - u32 nb_aus; - - u32 port; - GF_RTPChannel *channel; - GP_RTPPacketizer *packetizer; - - GF_ISOSample *au; // the AU - u32 track; - u32 sample_duration; - u32 sample_desc_index; - /*normalized DTS in micro-sec*/ - u64 microsec_dts; - - /* The previous packet which could not be sent in previous burst*/ - RTP_Packet *pck_queue; - /* The current packet being formed */ - RTP_Packet packet; - u32 ts_offset, microsec_ts_offset; - u32 next_ts; - - Double ts_scale, microsec_ts_scale; - Bool process_burst; - /*NALU size for H264/AVC*/ - u32 avc_nalu_size; - - struct __tag_rtp_session *session; -} RTP_Stream; - - -typedef struct __tag_rtp_session -{ - struct __tag_rtp_session *next; - - u32 id; - u32 minBurstSize; // max size to fill the burst with the media bitRate - u32 looping; // 1: play the media in a loop, 0 play once - char *filename; - GF_ISOFile *mp4File; - u32 nbBurstSent; // pour cette session - u32 timelineOrigin; // time when the first burts was sent. this time <=> (CTS=0) - u32 nextBurstTime; - u32 dataLengthInBurst; // total bytes filled in current burst - s32 drift; - Bool force_mpeg4_generic; - - /*list of streams in session*/ - RTP_Stream *stream; - - /*to sync looping sessions with tracks of # length*/ - u32 duration; - - Streamer *streamer; -} RTP_Session; - - -static void rtp_flush_channel(RTP_Stream *rtp) -{ - u32 currentPacketSize; - RTP_Packet *pck = rtp->pck_queue; - while (pck) { - RTP_Packet *tmp = pck; - - gf_rtp_send_packet(rtp->channel, &pck->header, 0, 0, pck->payload, pck->payload_len); - currentPacketSize = (pck->payload_len + RTP_HEADER_SIZE); - rtp->session->dataLengthInBurst+= currentPacketSize; - if (rtp->session->streamer->log_level == LOG_PACKET) fprintf(stdout, " RTP SN %u - TS %u - M %u - Size %u\n", pck->header.SequenceNumber, pck->header.TimeStamp, pck->header.Marker, currentPacketSize); - - pck = pck->next; - free(tmp->payload); - free(tmp); - } - rtp->pck_queue = NULL; -} - - -/* - * callback functions, called by the RTP packetiser - */ - -/* - * The RTP packetizer is starting a new RTP packet and is giving the header - */ -static void burst_on_pck_new(void *cbk, GF_RTPHeader *header) -{ - RTP_Stream *rtp = cbk; - if (!header) return; - memcpy(&rtp->packet.header, header, sizeof(GF_RTPHeader)); -} /* OnNewPacket */ - -/* - * The RTP packetiser is done with the current RTP packet - * the header may have changed since the beginning of the packet (OnNewPacket) - * - */ -static void burst_on_pck_done(void *cbk, GF_RTPHeader *header) -{ - GF_Err e; - s64 burst_time, rtp_ts; - RTP_Stream *rtp = cbk; - u32 currentPacketSize; // in bits - - - currentPacketSize = (rtp->packet.payload_len + RTP_HEADER_SIZE); - burst_time = (s64) rtp->packetizer->sl_config.timestampResolution * (rtp->session->nextBurstTime + rtp->session->streamer->cycleDuration); - rtp_ts = (s64) rtp->next_ts*1000; - - if (rtp->session->dataLengthInBurst + currentPacketSize < rtp->session->streamer->burstSize - && (burst_time - rtp_ts > 0) ) { - - e = gf_rtp_send_packet(rtp->channel, header, 0, 0, rtp->packet.payload, rtp->packet.payload_len); - if (e) - fprintf(stdout, "Error %s sending RTP packet\n", gf_error_to_string(e)); - rtp->session->dataLengthInBurst += currentPacketSize; - free(rtp->packet.payload); - rtp->packet.payload = NULL; - rtp->packet.payload_len = 0; - - if (rtp->session->streamer->log_level == LOG_PACKET) fprintf(stdout, " RTP SN %u - TS %u - M %u - Size %u\n", rtp->packet.header.SequenceNumber, rtp->packet.header.TimeStamp, rtp->packet.header.Marker, currentPacketSize); - - } else { - RTP_Packet *pck; - if (rtp->session->dataLengthInBurst + currentPacketSize > rtp->session->streamer->burstSize) { - if (rtp->session->streamer->log_level >= LOG_BURST) - fprintf(stdout, " Packet (TS %u) delayed due to buffer overflow\n", rtp->next_ts); - } else { - if (rtp->session->streamer->log_level==LOG_PACKET) - fprintf(stdout, " Packet (TS %u) delayed to avoid drift\n", rtp->next_ts); - } - - GF_SAFEALLOC(pck, RTP_Packet); - memcpy(&pck->header, header, sizeof(GF_RTPHeader)); - pck->payload = rtp->packet.payload; - pck->payload_len = rtp->packet.payload_len; - rtp->packet.payload = NULL; - rtp->packet.payload_len = 0; - rtp->process_burst = 0; - if (rtp->pck_queue) { - RTP_Packet *first = rtp->pck_queue; - while (first->next) first = first->next; - first->next = pck; - } else { - rtp->pck_queue = pck; - } - } - -} /* OnPacketdone */ - -/* - * The RTP packetiser has added data to the current RTP packet - */ -static void on_pck_data(void *cbk, char *data, u32 data_size, Bool is_head) -{ - RTP_Stream *rtp = cbk; - if (!data ||!data_size) return; - - if (!rtp->packet.payload_len) { - rtp->packet.payload = malloc(data_size); - memcpy(rtp->packet.payload, data, data_size); - rtp->packet.payload_len = data_size; - } else { - rtp->packet.payload = realloc(rtp->packet.payload, rtp->packet.payload_len + data_size); - if (!is_head) { - memcpy(rtp->packet.payload+rtp->packet.payload_len, data, data_size); - } else { - memmove(rtp->packet.payload+data_size, rtp->packet.payload, rtp->packet.payload_len); - memcpy(rtp->packet.payload, data, data_size); - } - rtp->packet.payload_len += data_size; - } - -} /* OnData */ - -/* - * The RTP packetizer is starting a new RTP packet and is giving the header - */ -static void on_pck_new(void *cbk, GF_RTPHeader *header) -{ - RTP_Stream *rtp = cbk; - if (!header) return; - memcpy(&rtp->packet.header, header, sizeof(GF_RTPHeader)); -} - -/* - * The RTP packetiser is done with the current RTP packet - * the header may have changed since the beginning of the packet (OnNewPacket) - * - */ -static void on_pck_done(void *cbk, GF_RTPHeader *header) -{ - RTP_Stream *rtp = cbk; - GF_Err e = gf_rtp_send_packet(rtp->channel, header, 0, 0, rtp->packet.payload, rtp->packet.payload_len); - if (e) - fprintf(stdout, "Error %s sending RTP packet\n", gf_error_to_string(e)); - free(rtp->packet.payload); - - if (rtp->session->streamer->log_level == LOG_PACKET) - fprintf(stdout, " RTP SN %u - TS %u - M %u - Size %u\n", rtp->packet.header.SequenceNumber, rtp->packet.header.TimeStamp, rtp->packet.header.Marker, rtp->packet.payload_len + RTP_HEADER_SIZE); - - rtp->packet.payload = NULL; - rtp->packet.payload_len = 0; -} - - -GF_Err rtp_init_packetizer(RTP_Stream *rtp, char *dest_ip) -{ - u32 flags = 0; - - if (rtp->session->force_mpeg4_generic) flags = GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_FORCE_MPEG4; - - if (rtp->session->streamer->burst_mode) { - rtp->packetizer = gf_rtp_packetizer_create_and_init_from_file(rtp->session->mp4File, rtp->track, rtp, - burst_on_pck_new, burst_on_pck_done, NULL, on_pck_data, - rtp->session->streamer->path_mtu, 0, 0, flags, - rtp->session->streamer->payt, 0, 0, 0); - } else { - rtp->packetizer = gf_rtp_packetizer_create_and_init_from_file(rtp->session->mp4File, rtp->track, rtp, - on_pck_new, on_pck_done, NULL, on_pck_data, - rtp->session->streamer->path_mtu, 0, 0, flags, - rtp->session->streamer->payt, 0, 0, 0); - } - - rtp->session->streamer->payt++; - - rtp->ts_scale = rtp->packetizer->sl_config.timestampResolution; - rtp->ts_scale /= gf_isom_get_media_timescale(rtp->session->mp4File, rtp->track); - - rtp->microsec_ts_scale = 1000000; - rtp->microsec_ts_scale /= gf_isom_get_media_timescale(rtp->session->mp4File, rtp->track); - return GF_OK; -} - -GF_Err rtp_setup_sdp(RTP_Session *session, char *dest_ip) -{ - RTP_Stream *rtp; - FILE *sdp_out; - char filename[30]; - char mediaName[30], payloadName[30]; - char sdpLine[20000]; - - sprintf(filename, "session%d.sdp", session->id); - sdp_out = fopen(filename, "wt"); - if (!sdp_out) return GF_IO_ERR; - - sprintf(sdpLine, "v=0"); - fprintf(sdp_out, "%s\n", sdpLine); - sprintf(sdpLine, "o=MP4Streamer 3357474383 1148485440000 IN IP%d %s", gf_net_is_ipv6(dest_ip) ? 6 : 4, dest_ip); - fprintf(sdp_out, "%s\n", sdpLine); - sprintf(sdpLine, "s=livesession"); - fprintf(sdp_out, "%s\n", sdpLine); - sprintf(sdpLine, "i=This is an MP4 time-sliced Streaming demo"); - fprintf(sdp_out, "%s\n", sdpLine); - sprintf(sdpLine, "u=http://gpac.sourceforge.net"); - fprintf(sdp_out, "%s\n", sdpLine); - sprintf(sdpLine, "e=admin@"); - fprintf(sdp_out, "%s\n", sdpLine); - sprintf(sdpLine, "c=IN IP%d %s", gf_net_is_ipv6(dest_ip) ? 6 : 4, dest_ip); - fprintf(sdp_out, "%s\n", sdpLine); - sprintf(sdpLine, "t=0 0"); - fprintf(sdp_out, "%s\n", sdpLine); - sprintf(sdpLine, "a=x-copyright: Streamed with GPAC (C)2000-200X - http://gpac.sourceforge.net\n"); - fprintf(sdp_out, "%s\n", sdpLine); - - rtp = session->stream; - while (rtp) { - - gf_rtp_builder_get_payload_name(rtp->packetizer, payloadName, mediaName); - - sprintf(sdpLine, "m=%s %d RTP/%s %d", mediaName, rtp->port, rtp->packetizer->slMap.IV_length ? "SAVP" : "AVP", rtp->packetizer->PayloadType); - fprintf(sdp_out, "%s\n", sdpLine); - sprintf(sdpLine, "a=rtpmap:%d %s/%d", rtp->packetizer->PayloadType, payloadName, rtp->packetizer->sl_config.timestampResolution); - fprintf(sdp_out, "%s\n", sdpLine); - - if (gf_isom_get_media_type(rtp->session->mp4File, rtp->track) == GF_ISOM_MEDIA_VISUAL) { - u32 w, h; - w = h = 0; - gf_isom_get_visual_info(rtp->session->mp4File, rtp->track, 1, &w, &h); - if (rtp->packetizer->rtp_payt == GF_RTP_PAYT_H263) { - sprintf(sdpLine, "a=cliprect:0,0,%d,%d", h, w); - } - /*extensions for some mobile phones*/ - sprintf(sdpLine, "a=framesize:%d %d-%d", rtp->packetizer->PayloadType, w, h); - } - /*AMR*/ - if ((rtp->packetizer->rtp_payt == GF_RTP_PAYT_AMR) || (rtp->packetizer->rtp_payt == GF_RTP_PAYT_AMR_WB)) { - sprintf(sdpLine, "a=fmtp:%d octet-align", rtp->packetizer->PayloadType); - fprintf(sdp_out, "%s\n", sdpLine); - } - /*Text*/ - else if (rtp->packetizer->rtp_payt == GF_RTP_PAYT_3GPP_TEXT) { - gf_hinter_format_ttxt_sdp(rtp->packetizer, payloadName, sdpLine, rtp->session->mp4File, rtp->track); - fprintf(sdp_out, "%s\n", sdpLine); - } - /*EVRC/SMV in non header-free mode*/ - else if ((rtp->packetizer->rtp_payt == GF_RTP_PAYT_EVRC_SMV) && (rtp->packetizer->auh_size>1)) { - sprintf(sdpLine, "a=fmtp:%d maxptime=%d", rtp->packetizer->PayloadType, rtp->packetizer->auh_size*20); - fprintf(sdp_out, "%s\n", sdpLine); - } - /*H264/AVC*/ - else if (rtp->packetizer->rtp_payt == GF_RTP_PAYT_H264_AVC) { - GF_AVCConfig *avcc = gf_isom_avc_config_get(rtp->session->mp4File, rtp->track, 1); - sprintf(sdpLine, "a=fmtp:%d profile-level-id=%02X%02X%02X; packetization-mode=1", rtp->packetizer->PayloadType, avcc->AVCProfileIndication, avcc->profile_compatibility, avcc->AVCLevelIndication); - if (gf_list_count(avcc->pictureParameterSets) || gf_list_count(avcc->sequenceParameterSets)) { - u32 i, count, b64s; - char b64[200]; - strcat(sdpLine, "; sprop-parameter-sets="); - count = gf_list_count(avcc->sequenceParameterSets); - for (i=0; isequenceParameterSets, i); - b64s = gf_base64_encode(sl->data, sl->size, b64, 200); - b64[b64s]=0; - strcat(sdpLine, b64); - if (i+1pictureParameterSets); - for (i=0; ipictureParameterSets, i); - b64s = gf_base64_encode(sl->data, sl->size, b64, 200); - b64[b64s]=0; - strcat(sdpLine, b64); - if (i+1avc_nalu_size = avcc->nal_unit_size; - gf_odf_avc_cfg_del(avcc); - } - /*MPEG-4 decoder config*/ - else if (rtp->packetizer->rtp_payt==GF_RTP_PAYT_MPEG4) { - GF_DecoderConfig *dcd; - dcd = gf_isom_get_decoder_config(rtp->session->mp4File, rtp->track, 1); - - if (dcd && dcd->decoderSpecificInfo && dcd->decoderSpecificInfo->data) { - gf_rtp_builder_format_sdp(rtp->packetizer, payloadName, sdpLine, dcd->decoderSpecificInfo->data, dcd->decoderSpecificInfo->dataLength); - } else { - gf_rtp_builder_format_sdp(rtp->packetizer, payloadName, sdpLine, NULL, 0); - } - if (dcd) gf_odf_desc_del((GF_Descriptor *)dcd); - - if (rtp->packetizer->slMap.IV_length) { - const char *kms; - gf_isom_get_ismacryp_info(rtp->session->mp4File, rtp->track, 1, NULL, NULL, NULL, NULL, &kms, NULL, NULL, NULL); - if (!strnicmp(kms, "(key)", 5) || !strnicmp(kms, "(ipmp)", 6) || !strnicmp(kms, "(uri)", 5)) { - strcat(sdpLine, "; ISMACrypKey="); - } else { - strcat(sdpLine, "; ISMACrypKey=(uri)"); - } - strcat(sdpLine, kms); - } - - fprintf(sdp_out, "%s\n", sdpLine); - } - /*MPEG-4 Audio LATM*/ - else if (rtp->packetizer->rtp_payt==GF_RTP_PAYT_LATM) { - GF_DecoderConfig *dcd; - GF_BitStream *bs; - char *config_bytes; - u32 config_size; - - /* form config string */ - bs = gf_bs_new(NULL, 32, GF_BITSTREAM_WRITE); - gf_bs_write_int(bs, 0, 1); /* AudioMuxVersion */ - gf_bs_write_int(bs, 1, 1); /* all streams same time */ - gf_bs_write_int(bs, 0, 6); /* numSubFrames */ - gf_bs_write_int(bs, 0, 4); /* numPrograms */ - gf_bs_write_int(bs, 0, 3); /* numLayer */ - - /* audio-specific config */ - dcd = gf_isom_get_decoder_config(rtp->session->mp4File, rtp->track, 1); - if (dcd) { - gf_bs_write_data(bs, dcd->decoderSpecificInfo->data, dcd->decoderSpecificInfo->dataLength); - gf_odf_desc_del((GF_Descriptor *)dcd); - } - - /* other data */ - gf_bs_write_int(bs, 0, 3); /* frameLengthType */ - gf_bs_write_int(bs, 0xff, 8); /* latmBufferFullness */ - gf_bs_write_int(bs, 0, 1); /* otherDataPresent */ - gf_bs_write_int(bs, 0, 1); /* crcCheckPresent */ - gf_bs_get_content(bs, &config_bytes, &config_size); - gf_bs_del(bs); - - gf_rtp_builder_format_sdp(rtp->packetizer, payloadName, sdpLine, config_bytes, config_size); - fprintf(sdp_out, "%s\n", sdpLine); - free(config_bytes); - } - rtp = rtp->next; - } - fprintf(sdp_out, "\n"); - - fclose(sdp_out); - - return GF_OK; -} /* rtp_init_packetizer */ - -GF_Err rtp_init_channel(RTP_Stream *rtp, u32 path_mtu, char * dest, int port) -{ - GF_RTSPTransport tr; - GF_Err res; - - rtp->channel = gf_rtp_new(); - gf_rtp_set_ports(rtp->channel, 0); - - tr.IsUnicast = gf_sk_is_multicast_address(dest) ? 0 : 1; - tr.Profile="RTP/AVP"; - tr.destination = dest; - tr.source = "0.0.0.0"; - tr.IsRecord = 0; - tr.Append = 0; - tr.SSRC = rand(); - - tr.port_first = port; - tr.port_last = port+1; - if (tr.IsUnicast) { - tr.client_port_first = port; - tr.client_port_last = port+1; - } else { - tr.source = dest; - } - - res = gf_rtp_setup_transport(rtp->channel, &tr, dest); - if (res !=0) { - fprintf(stdout, "Cannot setup RTP transport info\n"); - return res; - } - - res = gf_rtp_initialize(rtp->channel, 0, 1, 1500, 0, 0, NULL); - if (res !=0) { - fprintf(stdout, "Cannot initialize RTP sockets\n"); - return res; - } - - return GF_OK; -} /* rtp_init_channel */ - -// --------------------------------------------------------------------------------------------------- - -/* - * paquetization of a burst - * process the AUs till the burst size is reached. - * - */ - -void burst_process_session(RTP_Session *session) -{ - RTP_Stream *rtp, *to_send; - Bool first = 1; - u32 time; - - time = gf_sys_clock(); - if (!session->timelineOrigin) session->timelineOrigin = time; - - - rtp = session->stream; - while (rtp) { - rtp->process_burst = 1; - rtp = rtp->next; - } - - rtp = NULL; - while (1) { - u64 min_ts = (u64) -1; - to_send = NULL; - - /*for each stream, locate next time*/ - rtp = session->stream; - while (rtp) { - /*channel is no longer active in current burst*/ - if (!rtp->process_burst) { - rtp = rtp->next; - continue; - } - /*flush prev stream if needed*/ - rtp_flush_channel(rtp); - - /*load next AU*/ - if (!rtp->au) { - if (rtp->current_au >= rtp->nb_aus) { - if (!session->looping) { - rtp->process_burst = 0; - rtp = rtp->next; - continue; - } - rtp->process_burst = 1; - rtp->ts_offset = rtp->next_ts; - rtp->microsec_ts_offset = (u32) (rtp->next_ts*(1000000.0/rtp->packetizer->sl_config.timestampResolution)) + session->timelineOrigin; - rtp->current_au = 0; - } - if (rtp->current_au + 1==rtp->nb_aus) { - rtp->current_au = rtp->current_au; - } - - rtp->au = gf_isom_get_sample(session->mp4File, rtp->track, rtp->current_au + 1, &rtp->sample_desc_index); - rtp->current_au ++; - if (rtp->au) { - u64 ts; - rtp->sample_duration = gf_isom_get_sample_duration(session->mp4File, rtp->track, rtp->current_au); - rtp->sample_duration = (u32)(rtp->sample_duration*rtp->ts_scale); - - rtp->microsec_dts = (u64) (rtp->microsec_ts_scale * (s64) (rtp->au->DTS)) + rtp->microsec_ts_offset + session->timelineOrigin; - ts = (u64) (rtp->ts_scale * (s64) (rtp->au->DTS)); - - rtp->packetizer->sl_header.decodingTimeStamp = ts + rtp->ts_offset; - - ts = (u64) (rtp->ts_scale * (s64) (rtp->au->DTS+rtp->au->CTS_Offset)); - rtp->packetizer->sl_header.compositionTimeStamp = ts + rtp->ts_offset; - - rtp->packetizer->sl_header.randomAccessPointFlag = rtp->au->IsRAP; - } - } - if (rtp->au) { - if (min_ts > rtp->microsec_dts) { - min_ts = rtp->microsec_dts; - to_send = rtp; - } - } - rtp = rtp->next; - } - - /*burst is full or no packet to write due to timing*/ - if (!to_send) break; - - rtp = to_send; - /*compute drift*/ - if (first) { - first = 0; - session->drift = (s32) ((s64)(time - session->timelineOrigin) - ((s64) rtp->next_ts*1000/rtp->packetizer->sl_config.timestampResolution)); - if (session->streamer->log_level >= LOG_BURST) fprintf(stdout, "Time %u - Burst %u - Session %u (Time %u) - TS %d - Drift %d ms\n", time, session->streamer->nbBurstSent, session->id, time - session->timelineOrigin, rtp->next_ts, session->drift); - else { - fprintf(stdout, "Time %u - Burst %u - Session %u (Time %u) - TS %d - Drift %d ms\r", time, session->streamer->nbBurstSent, session->id, time - session->timelineOrigin, rtp->next_ts, session->drift); - fflush(stdout); - } - - } - - if (session->streamer->log_level >= LOG_AU) fprintf(stdout, "Sess %d - stream %d - Processing AU %d - DTS "LLD" - CTS "LLD"\n", session->id, rtp->track, rtp->current_au, rtp->packetizer->sl_header.decodingTimeStamp, rtp->packetizer->sl_header.compositionTimeStamp); - - /*unpack nal units*/ - if (rtp->avc_nalu_size) { - u32 v, size; - u32 remain = rtp->au->dataLength; - char *ptr = rtp->au->data; - - rtp->packetizer->sl_header.accessUnitStartFlag = 1; - rtp->packetizer->sl_header.accessUnitEndFlag = 0; - while (remain) { - size = 0; - v = rtp->avc_nalu_size; - while (v) { - size |= (u8) *ptr; - ptr++; - remain--; - v-=1; - if (v) size<<=8; - } - remain -= size; - rtp->packetizer->sl_header.accessUnitEndFlag = remain ? 0 : 1; - gf_rtp_builder_process(rtp->packetizer, ptr, size, (u8) !remain, rtp->au->dataLength, rtp->sample_duration, (u8) rtp->sample_desc_index ); - ptr += size; - rtp->packetizer->sl_header.accessUnitStartFlag = 0; - } - } else { - gf_rtp_builder_process(rtp->packetizer, rtp->au->data, rtp->au->dataLength, (u8) 1, rtp->au->dataLength, rtp->sample_duration, (u8) rtp->sample_desc_index); - } - - rtp->next_ts = (u32)(rtp->packetizer->sl_header.decodingTimeStamp + rtp->sample_duration); - /*OK delete sample*/ - gf_isom_sample_del(&rtp->au); - } - - if (session->streamer->log_level >= LOG_BURST) - fprintf(stdout, " Actual Burst Size %d bytes - Actual Bit Rate %d kbps\n", session->dataLengthInBurst, 8*session->dataLengthInBurst/(session->streamer->burstDuration+session->streamer->offDuration)); - session->nbBurstSent++; - session->streamer->nbBurstSent++; - -} - - -void process_sessions(Streamer *streamer) -{ - RTP_Session *session; - RTP_Stream *rtp, *to_send; - u32 time; - s32 diff; - u64 min_ts; - - time = gf_sys_clock(); - /*browse all sessions and locate most mature stream*/ - to_send = NULL; - min_ts = (u64) -1; - session = streamer->session; - while (session) { - /*init session timeline - all sessions are sync'ed for packet scheduling purposes*/ - if (!session->timelineOrigin) session->timelineOrigin = time*1000; - rtp = session->stream; - while (rtp) { - /*load next AU*/ - if (!rtp->au) { - if (rtp->current_au >= rtp->nb_aus) { - Double scale; - if (!rtp->session->looping) { - rtp = rtp->next; - continue; - } - /*increment ts offset*/ - scale = rtp->packetizer->sl_config.timestampResolution/1000.0; - rtp->ts_offset += (u32) (session->duration * scale); - rtp->microsec_ts_offset = (u32) (rtp->ts_offset*(1000000.0/rtp->packetizer->sl_config.timestampResolution)) + session->timelineOrigin; - rtp->current_au = 0; - } - if (rtp->current_au + 1==rtp->nb_aus) { - rtp->current_au = rtp->current_au; - } - - rtp->au = gf_isom_get_sample(rtp->session->mp4File, rtp->track, rtp->current_au + 1, &rtp->sample_desc_index); - rtp->current_au ++; - if (rtp->au) { - u64 ts; - rtp->sample_duration = gf_isom_get_sample_duration(rtp->session->mp4File, rtp->track, rtp->current_au); - rtp->sample_duration = (u32)(rtp->sample_duration*rtp->ts_scale); - - rtp->microsec_dts = (u64) (rtp->microsec_ts_scale * (s64) (rtp->au->DTS)) + rtp->microsec_ts_offset + session->timelineOrigin; - - ts = (u64) (rtp->ts_scale * (s64) (rtp->au->DTS)); - rtp->packetizer->sl_header.decodingTimeStamp = ts + rtp->ts_offset; - - ts = (u64) (rtp->ts_scale * (s64) (rtp->au->DTS+rtp->au->CTS_Offset)); - rtp->packetizer->sl_header.compositionTimeStamp = ts + rtp->ts_offset; - - rtp->packetizer->sl_header.randomAccessPointFlag = rtp->au->IsRAP; - } - } - - /*check timing*/ - if (rtp->au) { - if (min_ts > rtp->microsec_dts) { - min_ts = rtp->microsec_dts; - to_send = rtp; - } - } - - rtp = rtp->next; - } - session = session->next; - } - - /*no input data ...*/ - if( !to_send) return; - min_ts /= 1000; - - /*sleep until TS is mature*/ - while (1) { - diff = (u32) (min_ts) - gf_sys_clock(); - if (diff > 2) { - //fprintf(stdout, "RTP session %d stream %d - sleeping %d ms\n", to_send->session->id, to_send->track, diff); - gf_sleep(1); - } else { - if (diff<0) fprintf(stdout, "WARNING: RTP session %d stream %d - sending packet %d ms too late\n", to_send->session->id, to_send->track, -diff); - break; - } - } - - /*send packets*/ - - /*unpack nal units*/ - if (to_send->avc_nalu_size) { - u32 v, size; - u32 remain = to_send->au->dataLength; - char *ptr = to_send->au->data; - - to_send->packetizer->sl_header.accessUnitStartFlag = 1; - to_send->packetizer->sl_header.accessUnitEndFlag = 0; - while (remain) { - size = 0; - v = to_send->avc_nalu_size; - while (v) { - size |= (u8) *ptr; - ptr++; - remain--; - v-=1; - if (v) size<<=8; - } - remain -= size; - to_send->packetizer->sl_header.accessUnitEndFlag = remain ? 0 : 1; - gf_rtp_builder_process(to_send->packetizer, ptr, size, (u8) !remain, to_send->au->dataLength, to_send->sample_duration, (u8) to_send->sample_desc_index ); - ptr += size; - to_send->packetizer->sl_header.accessUnitStartFlag = 0; - } - } else { - gf_rtp_builder_process(to_send->packetizer, to_send->au->data, to_send->au->dataLength, (u8) 1, to_send->au->dataLength, to_send->sample_duration, (u8) to_send->sample_desc_index); - } - /*delete sample*/ - gf_isom_sample_del(&to_send->au); - -} - - - -// --------------------------------------------------------------------------------------------------- - - -u16 check_next_port(Streamer *streamer, u16 first_port) -{ - RTP_Session *session = streamer->session; - while (session) { - RTP_Stream *rtp = session->stream; - while (rtp) { - if (rtp->port==first_port) { - return check_next_port(streamer, (u16) (first_port+2) ); - } - rtp = rtp->next; - } - session = session->next; - } - return first_port; -} - -/* - * configuration: - * retrieves the parameters from the configuration file - * - */ - -GF_Err configuration(Streamer *streamer, char *cfg_file, char *src_file, char *ip_dest, u16 port, Bool loop, Bool force_mpeg4) -{ - GF_Err e = GF_OK; - RTP_Session *session, *last_sess; - u32 nb_sessions; - const char *opt = NULL; - const char *dest_ip; - GF_Config *configFile = NULL; - u32 i, j; - - if (cfg_file) { - fprintf(stdout, "Configuration file: %s \n", cfg_file); - - configFile = gf_cfg_new(PATHFILE, cfg_file); - if (!configFile) { - fprintf(stderr, "ERROR: could not open the file\n"); - return GF_IO_ERR; - } - - opt = gf_cfg_get_key(configFile, "GLOBAL", "nbSession"); - nb_sessions = opt ? atoi(opt) : 0; - fprintf(stdout, " Number of sessions: %u \n", nb_sessions); - - opt = gf_cfg_get_key(configFile, "GLOBAL", "IP_dest"); - dest_ip = opt ? opt : "127.0.0.1"; - fprintf(stdout, " Destination IP: %s \n", dest_ip); - - - opt = gf_cfg_get_key(configFile, "GLOBAL", "path_mtu"); - if (opt) streamer->path_mtu = atoi(opt); - if (!streamer->path_mtu) streamer->path_mtu = 1450; - fprintf(stdout, " Path MTU: %u bytes \n", streamer->path_mtu); - - /*configure burst mode*/ - opt = gf_cfg_get_key(configFile, "GLOBAL", "burst_mode"); - streamer->burst_mode = (opt && !strcmp(opt, "yes")) ? 1 : 0; - if (streamer->burst_mode) { - opt = gf_cfg_get_key(configFile, "GLOBAL", "off_duration"); - streamer->offDuration = opt ? atoi(opt) : 0; - fprintf(stdout, " Offtime duration: %u ms \n", streamer->offDuration); - - opt = gf_cfg_get_key(configFile, "GLOBAL", "burst_duration"); - streamer->burstDuration = opt ? atoi(opt) : 1000; - fprintf(stdout, " Burst duration: %u ms \n", streamer->burstDuration); - - opt = gf_cfg_get_key(configFile, "GLOBAL", "burst_bitrate"); - streamer->burstBitRate = opt ? atoi(opt) : 500; - fprintf(stdout, " Burst bit rate: %u kbps \n", streamer->burstBitRate); - - streamer->burstSize = streamer->burstBitRate*1024*streamer->burstDuration/1000/8; - streamer->averageBitRate = (streamer->burstDuration * streamer->burstBitRate)/(streamer->offDuration + streamer->burstDuration); - - fprintf(stdout, " Burst mode enabled - burst size: %d bytes - average bit rate %d kbps\n", streamer->burstSize, streamer->averageBitRate); - } - } else { - fprintf(stdout, " Path MTU: %u bytes \n", streamer->path_mtu); - dest_ip = ip_dest; - fprintf(stdout, " Destination IP: %s Port %d\n", dest_ip, port); - nb_sessions = 1; - } - - streamer->payt = BASE_PAYT; - - last_sess = NULL; - for(i=0; inext = session; - } else { - streamer->session = session; - } - last_sess = session; - - session->streamer = streamer; - session->id = i+1; - session->mp4File = file; - - if (cfg_file) { - opt = gf_cfg_get_key(configFile, sessionName, "port"); - first_port = opt ? atoi(opt) : 7000+4*i; - - opt = gf_cfg_get_key(configFile, sessionName, "looping"); - session->looping = opt ? atoi(opt) : 1; - - opt = gf_cfg_get_key(configFile, sessionName, "force_mpeg4-generic"); - session->force_mpeg4_generic = opt ? atoi(opt) : 0; - - opt = gf_cfg_get_key(configFile, sessionName, "path_mtu"); - sess_path_mtu = opt ? atoi(opt) : 0; - if (!opt) sess_path_mtu = streamer->path_mtu; - - opt = gf_cfg_get_key(configFile, sessionName, "IP_dest"); - sess_dest_ip = (char *) (opt ? opt : dest_ip); - } else { - sess_path_mtu = streamer->path_mtu; - sess_dest_ip = (char *) dest_ip; - session->looping = loop; - session->force_mpeg4_generic = force_mpeg4; - first_port = port; - } - - sess_data_size = 0; - prev_stream = NULL; - nb_tracks = gf_isom_get_track_count(session->mp4File); - for (j=0;jmp4File, j+1)) { - case GF_ISOM_MEDIA_VISUAL: - case GF_ISOM_MEDIA_AUDIO: - case GF_ISOM_MEDIA_TEXT: - case GF_ISOM_MEDIA_OD: - case GF_ISOM_MEDIA_SCENE: - break; - default: - continue; - } - - GF_SAFEALLOC(rtp, RTP_Stream); - if (prev_stream) prev_stream->next = rtp; - else session->stream = rtp; - prev_stream = rtp; - - rtp->session = session; - rtp->track = j+1; - - rtp->nb_aus = gf_isom_get_sample_count(session->mp4File, rtp->track); - mediaTimescale = gf_isom_get_media_timescale(session->mp4File, rtp->track); - mediaDuration = (u32)(gf_isom_get_media_duration(session->mp4File, rtp->track)*1000/mediaTimescale); // ms - mediaSize = (u32)gf_isom_get_media_data_size(session->mp4File, rtp->track); - - sess_data_size += mediaSize; - if (mediaDuration > session->duration) session->duration = mediaDuration; - - rtp->port = check_next_port(streamer, first_port); - first_port = rtp->port+2; - - e = rtp_init_channel(rtp, sess_path_mtu+12, sess_dest_ip, rtp->port); - if (e) { - fprintf(stderr, "Could not initialize RTP Channel: %s\n", gf_error_to_string(e)); - goto exit; - } - e = rtp_init_packetizer(rtp, sess_dest_ip); - if (e) { - fprintf(stderr, "Could not initialize Packetizer: %s\n", gf_error_to_string(e)); - goto exit; - } - } - rtp_setup_sdp(session, sess_dest_ip); - - if (streamer->burst_mode) { - session->minBurstSize = (sess_data_size * (streamer->burstDuration + streamer->offDuration)) / session->duration; // bps * ms ==> bits - fprintf(stdout, "Session %u: %d ms - avg bitrate %d kbps - Min Burst Size %d bytes\n", session->id, session->duration, sess_data_size/session->duration, session->minBurstSize); - } - } - - /*configure burst*/ - if (streamer->burst_mode) { - streamer->cycleDuration = 0; - session = streamer->session; - while (session) { - session->nextBurstTime = streamer->cycleDuration; - streamer->cycleDuration += streamer->burstDuration; - session = session->next; - } - streamer->cycleDuration += streamer->offDuration; - } - - fprintf(stdout, "\n"); - -exit: - if (cfg_file) gf_cfg_del(configFile); - return e; -} /* configuration */ - -// --------------------------------------------------------------------------------------------------- - - -void usage() -{ - fprintf(stdout, "Usage: MP4Streamer [options] file\n" - "with options being one fo the following:\n" - "-cfg: file is a configuration file for all sessions\n" - "\n" - "Options used for simple streaming:\n" - "-port=NUM: port to use. Default is 7000\n" - "-mtu=NUM: network path MTU to use. Default is 1450\n" - "-dst=ADD: destination IP address. Default is 127.0.0.1\n" - "-mpeg4: forces usage of mpeg4-generic payload format. Default is off\n" - "-noloop: disables session looping. Default is off\n" - ); -} - -Bool check_exit() -{ - if (gf_prompt_has_input()) { - char c; - c = (char) gf_prompt_get_char(); - if (c=='q') return 1; - } - return 0; -} - -int main(int argc, char **argv) -{ - Streamer streamer; /* Streamer metadata (from cfg file) */ - char *cfg = NULL; - RTP_Session *session; - u32 i; - s32 sleepDuration; - u32 time; - char *ip_dest = "127.0.0.1"; - u16 port = 7000; - Bool loop = 1; - Bool force_mpeg4 = 0; - char *file_name = NULL; - - - if (argc < 2) { - usage(argv[0]); - return 0; - } - - gf_log_set_tools(0xFFFFFFFF); - gf_log_set_level(GF_LOG_ERROR); - - memset(&streamer, 0, sizeof(Streamer)); - streamer.log_level = LOG_BURST; - streamer.path_mtu = 1450; - - for (i=1; i<(u32) argc; i++) { - char *arg = argv[i]; - if (arg[0]=='-') { - if (!stricmp(arg, "-q") || !stricmp(arg, "--quiet")) streamer.log_level = LOG_NONE; - else if (!strnicmp(arg, "-v=", 3)) { - if (!stricmp(arg+3, "au")) streamer.log_level = LOG_AU; - else if (!stricmp(arg+3, "rtp")) streamer.log_level = LOG_PACKET; - } - else if (!strnicmp(arg, "-cfg=", 5)) cfg = arg+5; - else if (!strnicmp(arg, "-port=", 6)) port = atoi(arg+6); - else if (!strnicmp(arg, "-mtu=", 5)) streamer.path_mtu = atoi(arg+5); - else if (!strnicmp(arg, "-dst=", 5)) ip_dest = arg+5; - else if (!stricmp(arg, "-noloop")) loop = 0; - else if (!stricmp(arg, "-mpeg4")) force_mpeg4 = 1; - } else { - file_name = arg; - } - } - - if (!cfg && !file_name) { - usage(argv[0]); - return 0; - } - - fprintf(stdout, "Time-sliced MP4 Streamer - (c) ENST 2006-200X\n"); - fprintf(stdout, "Developed within the Multimedia group\n"); - fprintf(stdout, "with the help of the following students: \n"); - fprintf(stdout, " MIX 2006: Anh-Vu BUI and Xiangfeng LIU \n"); - fprintf(stdout, "\n"); - - if (!cfg) fprintf(stdout, "Configuring streaming of file %s to %s:%d - loop %s\n", file_name, ip_dest, port, loop?"enabled":"disabled"); - /* - * Initialization - * - */ - gf_sys_init(); - if (configuration(&streamer, cfg, file_name, ip_dest, port, loop, force_mpeg4) != GF_OK) { - goto err_exit; - } - - if (streamer.burst_mode) { - session = streamer.session; - while (1) { - burst_process_session(session); - session->dataLengthInBurst = 0; - session->nextBurstTime += streamer.cycleDuration; - session = session->next; - if (!session) session = streamer.session; - - time = gf_sys_clock(); - sleepDuration = session->nextBurstTime - (time - session->timelineOrigin); - if (sleepDuration > 0) { - gf_sleep(sleepDuration); - } - - if (check_exit()) break; - } - } else { - while (1) { - process_sessions(&streamer); - if (check_exit()) break; - } - } - -err_exit: - /* - * Desallocation - * - */ - session = streamer.session; - while (session) { - RTP_Session *_s = session; - RTP_Stream *rtp = session->stream; - while (rtp) { - RTP_Stream *tmp = rtp; - rtp_flush_channel(rtp); - if (rtp->au) gf_isom_sample_del(&rtp->au); - if (rtp->channel) gf_rtp_del(rtp->channel); - if (rtp->packetizer) gf_rtp_builder_del(rtp->packetizer); - if (rtp->packet.payload) free(rtp->packet.payload); - rtp = rtp->next; - free(tmp); - } - if (session->mp4File) gf_isom_close(session->mp4File); - session = session->next; - free(_s); - } - gf_sys_close(); - fprintf(stdout, "done\n"); - return GF_OK; - -} /* end main */ - diff --git a/applications/testapps/mp4_streamer/mp4_streamer.dsp b/applications/testapps/mp4_streamer/mp4_streamer.dsp deleted file mode 100644 index 4a05bb3..0000000 --- a/applications/testapps/mp4_streamer/mp4_streamer.dsp +++ /dev/null @@ -1,102 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mp4_streamer" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=mp4_streamer - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mp4_streamer.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mp4_streamer.mak" CFG="mp4_streamer - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mp4_streamer - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "mp4_streamer - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mp4_streamer - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/mp4_streamer.exe" /libpath:"../../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "mp4_streamer - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/mp4_streamer.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "mp4_streamer - Win32 Release" -# Name "mp4_streamer - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\main.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/applications/testapps/mpedemux/main.c b/applications/testapps/mpedemux/main.c index b606e91..f176754 100644 --- a/applications/testapps/mpedemux/main.c +++ b/applications/testapps/mpedemux/main.c @@ -100,6 +100,6 @@ int main(int argc, char **argv) } gf_m2ts_demux_del(mpedemux->ts_demux); - free(mpedemux); + gf_free(mpedemux); return GF_OK; } diff --git a/applications/testapps/mpedemux/mpedemux.dsp b/applications/testapps/mpedemux/mpedemux.dsp index 5aae5e6..b4f3317 100644 --- a/applications/testapps/mpedemux/mpedemux.dsp +++ b/applications/testapps/mpedemux/mpedemux.dsp @@ -1,90 +1,90 @@ -# Microsoft Developer Studio Project File - Name="mpedemux" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=mpedemux - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mpedemux.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mpedemux.mak" CFG="mpedemux - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mpedemux - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "mpedemux - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mpedemux - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 zlib.lib winmm.lib ws2_32.lib js32.lib /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/mpedemux.exe" /libpath:"../../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "mpedemux - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 zlib.lib winmm.lib ws2_32.lib js32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/mpedemux.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "mpedemux - Win32 Release" -# Name "mpedemux - Win32 Debug" -# Begin Source File - -SOURCE=.\main.c -# End Source File -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="mpedemux" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=mpedemux - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mpedemux.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mpedemux.mak" CFG="mpedemux - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mpedemux - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "mpedemux - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mpedemux - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 zlib.lib winmm.lib ws2_32.lib js32.lib /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/mpedemux.exe" /libpath:"../../../extra_lib/lib/w32_rel" + +!ELSEIF "$(CFG)" == "mpedemux - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 zlib.lib winmm.lib ws2_32.lib js32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/mpedemux.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" + +!ENDIF + +# Begin Target + +# Name "mpedemux - Win32 Release" +# Name "mpedemux - Win32 Debug" +# Begin Source File + +SOURCE=.\main.c +# End Source File +# End Target +# End Project diff --git a/applications/testapps/mpeg2ts/mpeg2ts.dsp b/applications/testapps/mpeg2ts/mpeg2ts.dsp index 656390f..37052e4 100644 --- a/applications/testapps/mpeg2ts/mpeg2ts.dsp +++ b/applications/testapps/mpeg2ts/mpeg2ts.dsp @@ -1,100 +1,100 @@ -# Microsoft Developer Studio Project File - Name="mpeg2ts" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=mpeg2ts - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mpeg2ts.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mpeg2ts.mak" CFG="mpeg2ts - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mpeg2ts - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "mpeg2ts - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mpeg2ts - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == "mpeg2ts - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 zlib.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "mpeg2ts - Win32 Release" -# Name "mpeg2ts - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\main.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="mpeg2ts" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=mpeg2ts - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mpeg2ts.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mpeg2ts.mak" CFG="mpeg2ts - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mpeg2ts - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "mpeg2ts - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mpeg2ts - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "mpeg2ts - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 zlib.lib winmm.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "mpeg2ts - Win32 Release" +# Name "mpeg2ts - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\main.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/applications/testapps/svg2bifs/main.c b/applications/testapps/svg2bifs/main.c index c97ef07..ef3a048 100644 --- a/applications/testapps/svg2bifs/main.c +++ b/applications/testapps/svg2bifs/main.c @@ -313,15 +313,15 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na gf_svg_parse_element_id((GF_Node *)elt, att->value, 0); id_string = att->value; } else if (anim && !stricmp(att->name, "to")) { - anim->to = strdup(att->value); + anim->to = gf_strdup(att->value); } else if (anim && !stricmp(att->name, "from")) { - anim->from = strdup(att->value); + anim->from = gf_strdup(att->value); } else if (anim && !stricmp(att->name, "by")) { - anim->by = strdup(att->value); + anim->by = gf_strdup(att->value); } else if (anim && !stricmp(att->name, "values")) { - anim->values = strdup(att->value); + anim->values = gf_strdup(att->value); } else if (anim && (tag == TAG_SVG_animateTransform) && !stricmp(att->name, "type")) { - anim->type = strdup(att->value); + anim->type = gf_strdup(att->value); } else { GF_FieldInfo info; if (gf_node_get_field_by_name((GF_Node *)elt, att->name, &info)==GF_OK) { @@ -339,7 +339,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na memset(&converter->all_atts, 0, sizeof(SVGAllAttributes)); gf_svg_flatten_attributes(elt, &converter->all_atts); - backup_props = malloc(sizeof(SVGPropertiesPointers)); + backup_props = gf_malloc(sizeof(SVGPropertiesPointers)); memcpy(backup_props, &converter->svg_props, sizeof(SVGPropertiesPointers)); gf_node_set_private((GF_Node *)elt, backup_props); @@ -700,7 +700,7 @@ static void svg2bifs_node_start(void *sax_cbck, const char *name, const char *na text->fontStyle = (GF_Node *)fs; gf_sg_vrml_mf_alloc(&fs->family, GF_SG_VRML_MFSTRING, 1); - fs->family.vals[0] = strdup(converter->svg_props.font_family->value); + fs->family.vals[0] = gf_strdup(converter->svg_props.font_family->value); fs->size = converter->svg_props.font_size->value; shape->appearance = create_appearance(&converter->svg_props, converter->bifs_sg); @@ -981,7 +981,7 @@ static void svg2bifs_node_end(void *sax_cbck, const char *name, const char *name SVGPropertiesPointers *backup_props = gf_node_get_private(converter->svg_parent); memcpy(&converter->svg_props, backup_props, sizeof(SVGPropertiesPointers)); -// free(backup_props); +// gf_free(backup_props); gf_node_set_private(converter->svg_parent, NULL); if (!(gf_node_get_tag(converter->svg_parent) == TAG_SVG_animateTransform)) @@ -1001,7 +1001,7 @@ static void svg2bifs_text_content(void *sax_cbck, const char *text_content, Bool if (converter->bifs_text_node) { M_Text *text = (M_Text *)converter->bifs_text_node; gf_sg_vrml_mf_alloc(&text->string, GF_SG_VRML_MFSTRING, 1); - text->string.vals[0] = strdup(text_content); + text->string.vals[0] = gf_strdup(text_content); } } @@ -1042,5 +1042,5 @@ int main(int argc, char **argv) gf_xml_sax_del(converter->sax_parser); - free(converter); -} \ No newline at end of file + gf_free(converter); +} diff --git a/applications/testapps/svg2bifs/svg2bifs.dsp b/applications/testapps/svg2bifs/svg2bifs.dsp index 066739a..335a2ce 100644 --- a/applications/testapps/svg2bifs/svg2bifs.dsp +++ b/applications/testapps/svg2bifs/svg2bifs.dsp @@ -1,90 +1,90 @@ -# Microsoft Developer Studio Project File - Name="svg2bifs" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=svg2bifs - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "svg2bifs.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "svg2bifs.mak" CFG="svg2bifs - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "svg2bifs - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "svg2bifs - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "svg2bifs - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/svg2bifs.exe" /libpath:"../../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "svg2bifs - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/svg2bifs.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "svg2bifs - Win32 Release" -# Name "svg2bifs - Win32 Debug" -# Begin Source File - -SOURCE=.\main.c -# End Source File -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="svg2bifs" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=svg2bifs - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "svg2bifs.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "svg2bifs.mak" CFG="svg2bifs - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "svg2bifs - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "svg2bifs - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "svg2bifs - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"../../../bin/w32_rel/svg2bifs.exe" /libpath:"../../../extra_lib/lib/w32_rel" + +!ELSEIF "$(CFG)" == "svg2bifs - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"../../../bin/w32_deb/svg2bifs.exe" /pdbtype:sept /libpath:"../../../extra_lib/lib/w32_deb" + +!ENDIF + +# Begin Target + +# Name "svg2bifs - Win32 Release" +# Name "svg2bifs - Win32 Debug" +# Begin Source File + +SOURCE=.\main.c +# End Source File +# End Target +# End Project diff --git a/applications/v4studio/V4FieldList.cpp b/applications/v4studio/V4FieldList.cpp index 952d953..f6b1e50 100644 --- a/applications/v4studio/V4FieldList.cpp +++ b/applications/v4studio/V4FieldList.cpp @@ -147,8 +147,8 @@ void V4FieldList::SetFieldValue(GF_FieldInfo f, wxString *value, int pos) else *((SFBool *)ptr) = 0; break; case GF_SG_VRML_SFSTRING: - if (((SFString *)ptr)->buffer) free(((SFString *)ptr)->buffer); - ((SFString *)ptr)->buffer = strdup(value->c_str()); + if (((SFString *)ptr)->buffer) gf_free(((SFString *)ptr)->buffer); + ((SFString *)ptr)->buffer = gf_strdup(value->c_str()); break; default: break; @@ -437,8 +437,8 @@ void V4FieldList::OnCellLeftDClick(wxGridEvent &evt) wxFontData retData = fd.GetFontData(); wxFont font = retData.GetChosenFont(); wxString name = font.GetFaceName(); - if (((SFString *)ptr)->buffer) free(((SFString *)ptr)->buffer); - ((SFString *)ptr)->buffer = strdup(name.c_str()); + if (((SFString *)ptr)->buffer) gf_free(((SFString *)ptr)->buffer); + ((SFString *)ptr)->buffer = gf_strdup(name.c_str()); } else { return; } @@ -449,4 +449,4 @@ void V4FieldList::OnCellLeftDClick(wxGridEvent &evt) } V4StudioFrame *parent = (V4StudioFrame *)this->GetParent(); parent->Update(); -} \ No newline at end of file +} diff --git a/applications/v4studio/V4SceneGraph.cpp b/applications/v4studio/V4SceneGraph.cpp index 03dd1fd..05558ac 100644 --- a/applications/v4studio/V4SceneGraph.cpp +++ b/applications/v4studio/V4SceneGraph.cpp @@ -22,7 +22,7 @@ V4SceneGraph::~V4SceneGraph() { // TODO : pquoi fallait il commenter cette ligne ? //if (m_pSm) gf_sm_del(m_pSm); - if (m_pOriginal_mp4) free(m_pOriginal_mp4); + if (m_pOriginal_mp4) gf_free(m_pOriginal_mp4); if (m_pService) delete m_pService; } @@ -74,7 +74,7 @@ void V4SceneGraph::LoadNew() gf_sg_del(m_pSg); m_pSg = NULL; } - if (m_pOriginal_mp4) free(m_pOriginal_mp4); + if (m_pOriginal_mp4) gf_free(m_pOriginal_mp4); m_pOriginal_mp4 = NULL; m_pIs = gf_is_new(NULL); @@ -129,7 +129,7 @@ void V4SceneGraph::LoadFile(const char *path) m_term->root_scene = m_pIs; // TODO : what's the use of this ? - if (m_pOriginal_mp4) free(m_pOriginal_mp4); + if (m_pOriginal_mp4) gf_free(m_pOriginal_mp4); m_pOriginal_mp4 = NULL; /* Loading of a file (BT, MP4 ...) and modification of the SceneManager */ diff --git a/applications/v4studio/V4Service.cpp b/applications/v4studio/V4Service.cpp index 823e9ee..d46c911 100644 --- a/applications/v4studio/V4Service.cpp +++ b/applications/v4studio/V4Service.cpp @@ -24,7 +24,7 @@ Bool V4Service::V4_RemoveChannel(V4Service *v4service, LPNETCHANNEL ch) V4Channel *v4c = (V4Channel *)gf_list_get(v4service->channels, i); if (v4c->ch && v4c->ch==ch) { gf_list_rem(v4service->channels, i); - free(v4c); + gf_free(v4c); return 1; } } @@ -71,7 +71,7 @@ static GF_Descriptor *V4_GetServiceDesc(GF_InputService *plug, u32 expect_type, esd->decoderConfig->objectTypeIndication = 0x01; //V4_PRIVATE_SCENE_OTI; if (v4service->GetPath()) { esd->decoderConfig->decoderSpecificInfo->dataLength = strlen(v4service->GetPath()) + 1; - esd->decoderConfig->decoderSpecificInfo->data = strdup(v4service->GetPath()); + esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(v4service->GetPath()); } gf_list_add(iod->ESDescriptors, esd); return (GF_Descriptor *)iod; @@ -86,7 +86,7 @@ static GF_Err V4_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, con if (!ESID) { gf_term_on_connect(v4serv->GetService(), channel, GF_STREAM_NOT_FOUND); } else { - V4Channel *v4c = (V4Channel *)malloc(sizeof(V4Channel)); + V4Channel *v4c = (V4Channel *)gf_malloc(sizeof(V4Channel)); memset(v4c, 0, sizeof(V4Channel)); v4c->ch = channel; v4c->ESID = ESID; @@ -174,7 +174,7 @@ static Bool V4_CanHandleURLInService(GF_InputService *plug, const char *url) V4Service::V4Service(const char *path) { - m_pNetClient = (GF_InputService *)malloc(sizeof(GF_InputService)); + m_pNetClient = (GF_InputService *)gf_malloc(sizeof(GF_InputService)); m_pNetClient->priv = this; m_pNetClient->CanHandleURL = V4_CanHandleURL; @@ -194,12 +194,12 @@ V4Service::V4Service(const char *path) m_pNetClient->CanHandleURLInService = V4_CanHandleURLInService; channels = gf_list_new(); - if (path) m_path = strdup(path); + if (path) m_path = gf_strdup(path); } V4Service::~V4Service() { - if (m_path) free(m_path); + if (m_path) gf_free(m_path); gf_list_del(channels); - free(m_pNetClient); -} \ No newline at end of file + gf_free(m_pNetClient); +} diff --git a/bin/arm_ppc03_rel/install/gpac.inf b/bin/arm_ppc03_rel/install/gpac.inf index b4fa5a0..81b6545 100644 --- a/bin/arm_ppc03_rel/install/gpac.inf +++ b/bin/arm_ppc03_rel/install/gpac.inf @@ -28,7 +28,7 @@ CESelfRegister=GPAX.dll [SourceDisksFiles] libgpac.dll = 1 %ExeName% = 1 -Osmo4.exe = 1 +;Osmo4.exe = 1 GPAX.dll = 1 gpac.mp4 = 3 @@ -67,7 +67,7 @@ gm_xvid_dec.dll = 1 ;ENST Proprietary modules -gm_upnp.dll = 1 +;gm_upnp.dll = 1 ;================================================== @@ -92,7 +92,7 @@ DefaultDestDir = 0, %InstallDir% [Exefiles] "%ExeName%" -"Osmo4.exe" +;"Osmo4.exe" "gpac.mp4" "gm_aac_in.dll" "gm_amr_dec.dll" @@ -117,7 +117,7 @@ DefaultDestDir = 0, %InstallDir% "gm_xvid_dec.dll" ;"gm_ogg_xiph.dll" -"gm_upnp.dll" +;"gm_upnp.dll" [GPACReg] ;GPAC cfg file location diff --git a/bin/gcc/libgpac.so b/bin/gcc/libgpac.so deleted file mode 100755 index 64634a20a33a91ae2a37262612fd82fc31dfc766..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4376700 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

neUk?inOo2g=zI(tC#NA0?CCkWJr_ZC!iSKTpO) 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

CLM0&j*|JZRR#s|d6sOI zLBYJ2$WB=`j(5-TG(}cPmkGSbgwUO`QoE9U4*m$kHA`aGu3 zt)s0nD1*CMmOakxutD$t=SJ=#8U6%!=q8#g8?y9XHVsD?YXA2-SEg;|_Rpau(titg zhD^-mZk6F%x$B;xL3y-H20h1}B`fl|oeF58tdQX^@SZPQWzdVfXKbfcvZj#R^Cjw5 zL=$DJOxdB&$@o{eLw8cAVj3emW%z5n7s>F~x$AaQw>M~_tdLG`@*X8iWT&j#!{=FL zv|0M^<*t%0Z*!-}8tM5C?`hIyA9uVglMdy)*T~R!xpSpM1$VeCk)8*5uX>L<9i&mR zOvW7Iy+n4(#P{`i>GT12hAjG!yHhqC<@T@Ed$LYC9OFGpHb|cu-qU1_%t9Axe}8`| z2Y<|6CY?U#ZkC>P-2NwMgADzGd%%}8QBFR|oiCTybJxh7UvYQJ=C8SZ8fec(8Y4r$ z;m(p(r?_3d)qAo?4)~7uL^=6;?tEF%%+(pu*gS%NeUF1%bb(gsP|E8Y* z&O!hKlQ4dr(8rdc=9(ZjT5gLL=h zJyDj)K{x9z%SLc_%1}S6ZF0;kwGE6yG^9=vP_2F&U==ulWvoF_qmg%$O`Fjm%g4Xlbtd&oX>M*d<3`u z6k2gNb(l)SWvi8#nH9}lC$GDgyJ9viilMEtGnPB*J{lKC zn;)Q_@ibAo&Et-jG4r|aN5^S@or4nSJ~{Xy?ix8{A@>rwUv^96{Vv%ghb8HKxnK5p znD^x}^bu~CMKmp$?p#b`me4&ZbjnityL@38ce@N)&b>~4EN@!Ddvz+EyOMq(r>x@s zQ0`0Pp1qoWEZ02B{kz=1hWq8U^qO?~r0nq+_oMQ6d1@W+(HZnZ`N(?iZ)Du#+|xHu z&y6%u9+S?Qyx%KZpWyc2M3-gJDw(#KyGDBEa37Q&TeusZrY^ZOMOMl1ZF-(Z!)1}o ze}VUA>A#&jO;*XMoxJBur&qZfUZbI}(<0fhkNc%^TDxD*KcMY0sET`?Ty~iIXF2;r z?zAKH19{a^?gV*Mx_!iZqI_Q#9pgQwhQ1`rYPmaQ>u20mC#gd{4VSsnvyt~i*&w67 z;k`_D%9L+;ZtuL;-kas4=sxYeI{7gAPuo>8W*~Qk3`ZAg z&wr3X*K)U_^R#;jdQLM29jBRse$x#4A8nQS=sE4)Eb~3JrH>bPimZ?hH}W1Xb7h0{ zL>Fpb_j`1kW&%1)(`PtMlm33(t7Nsjb|mlfWQqJu-a3lU*U1Js*q`@@<$n3E+=R~4 zz8@b;_tE-xWQn{WgU0ardRZeEpa)Ip)$O!QKo@Ge3SFofj1JVyk!^Awx=_0xM-OVc zq6alk%MkRSwq1_WMD(DxcgbROp|%szg_?8Fg_>WX3pM@FgPP9hLCr3igD%u|Zy(x( zF4Xp6bfIQ3x=^zTU8w1eF4QbU7i#u$r;hmVi{g$h)XYH-YBow=bfLCO(1n^O(S@3u z(S@3?q6;-=p$jz+pbIr4(S@3|=s``#muMckP}|YyK+POkE$5*NwR%AnLB4V&GV<;0W@$lEti>r+#igi z9^>gcdE-Rx99bTr_omRoY4mFu9nJkqEDgAirpij$CByFL^H=B74<4kW5^4G)G;T3< zP0@WB&0C>+DovFQ(r+d2nX+RQ_wv$L5Pp3{tz zWLYh<`|#c*m!Rjg?^m^SMaOA7L6%EL{P#fZz7bug*&;*GciPTI*J(D% zK=hopb7YhBL*Hrlbab8O3HdC#PTL(a5`Cxb8R$99V%a65(R1Q1J7l#d?|$ez?Rf&a zPP0Qsdh2ttOGe+sd#Q9B#vLcirLzz339?eU`tqJEtEI=yyr;@q={=nHbXhNb(RbSS zHxGTMxe;BbSuefOb=ppqvG;Lj-cLi&bK3Jl>5QJ!cDZz(%Uu~y9p}^11=Kr%7R#`Q zxNBwDLheG@A;S`R&y#I3BuRJKA_E`hJ>U_VBb%fj`cC_Pd!XmU|6W-uz0r5ty&ioh zo}=qDTVx>mPTT3|J5AR$v{0s^>$H1^9D%OWcA@k@&uKeVcF0I{opwJaOVM}Qjz-UE zmP+T1+{w}zU8g(F=-H9_TvF!!iVYr|kn?G;9bhmO1DpzE~lh>p{I zS+>a#bewk2kxeoVU8mh&kzVLJZCA_4$=vla4qc}`Z;{F9I&F8zz34k_2cYXT`-js! znH#~~B>m8J+I#6T2wkV`OnCr(r|q%mIdPYc)409RaoT-`ES4QI2VJKJBI&J64 zFm#=^56ePyowhq<7`jf|h0+^cr|lnQ2)a(&Z_7CJoVLrQBf3u8C*&^lowohZb>cng zhK|#AoGg}YvSB`-dpt-Z(RJGUeLtb+(RJExL(ge?eMZyedi0%k&qCK}9+PjO@3cJ~ zeW&S-zSF!G|2r&F$zr&5h_g&02Jw=D#u(J*Vxx^8cg<`cAv2qU$uPboXWCAe(daa7zmGoCbbf(GpwqNnfIib~lHTYvZ6~4AG<%@SG{?ygrQ0#y zH=xtB=V#GrniJ7yn&)H{`b^t7=rhfq&}W**ooE93Oxvr`XPWNlGtIbhv_(cw;65i) z(P!Fwj-m7b`b^s%=rc{%2wH$X({?&~Ofv@^rr9E+(PP>!M~`Vnqr)`IWHkCq+m*6Q zCZof&`#zaChkJ+oQ9cmIdkgwZd%p{Pra1$BruomK)Nd_KmVxLp?Rlnj&E_sdpK14W zbeX0rx=hmp9j2KeOJ%>UyeFf}wC8QI8hxg1=WpnG^qIETq0hv7=rc_ZbeZO9>4iSi z_6+oyW-|Ir(+^#ynJQgJakrt*w0j%+OfwRFrnwY-rWuDm)67AaX*y4%JJ4s^K94@r zEJUAaUPPa1)}qTauS1t=i8 zVp)Jb)3yitOfw8UrkN?LWhDAcyXTvmHIA8HgU!T#g>o^hJ+p zMxwtoGi9YLMUQFsTJ)Hv2RcmiIr$2DOxyM7G0mrbr+MfxZAYTVG#@~RX+AHL(PP?f zLyu|ZpvN>r&|{i$=rK(X^qA)F=rPR;=rPR}^q6KbdQ3ALJ*HWT9@F$dhiN+APW{kh z+O9>9X%?f$G`-Mcnt|vs%|`T?W-WS5vp+gavtGub$F!Y*9@89z4%6(8?$S(^CuJcz zOuIYcztd?}OK)_Sw)140OhA8W_j(zP4%2oM`b#qz-KAOkpXe`bN20$p>(O7DZRjt} z5cHR3Bl=4-485h9E*GJB~1!=V3I= zhvvv88STq^tqi-FyHW-Y=Ps4rBe)Bts~>lQ3>e8BJBrrIFn{h!85qD_D!oT@r^@g# z+<7u)EO)U?3gkX4vv1*UlF_$v`vlQc85GQ&DZ|Hc=gFAy+{H5VHty}RY$CT$D6Nt~ zlek@OrvZ~`tvqxGw{sYcmW8tGPTrT^MGwi;aP9-rF@n2JdQ8!lK~uTYWv%px5c`oO)f~_u9bcdaW7gz{ZeSPELqCkA@i1Tx5&Wd z+?ldo4qL%{oGg`2D|ye5KC8Hkq{pM&$+CJ4cL;h*`{%t}`lWLhOOMC6^Q7}S?o8Pw zt21~HSx?KQ-{aiH(qjX6o^;;GohiFyY9{Y(GT{mCCKlKQ9BfaVPAcrLylU+%3h_?=_k#tEKbn zyvNB>*&z#e^LefGc!N7xwn?W_-uKEb*|~@J!nbIP9J-G?RaQ&aa^9bnO>)+|`Z}^r z2JYuQT~0Sl@vQE$yp_A~91Z-L`u#$SWypDM$2OWNXZ))7 zf1{g2sZo|n;=cz6Dr#>r2+xJ&<~#odA~|NK1GfzIeo zTYJ#to;2E#7RuNwxwpzNC+<8M)0=y*^zOqwq909{wbJ8i-UA2F)6(@??tyMJL6%EL zciy9AvFwmx*YkOvY>|P3c+Zse()$M9Q)RVu_24~0mP^O~@g6OUWrqwK%;$NsMFx8E zo+<04w-@iJvRb;{$a{h;mySbtkCrEfa@P;11tVyS4D{p9kxkNXB=4EBUN(*5-P@lQ zO4k7H$kEhs4DFDSW4YU;^DW$QvQ~QB%6qabmySWaN6TV)MX>JjsB|62dy||no;yc2 zNxuoar-smK>3SRYr_y60cb@bP)#qfj^q$1~;oGVEWST5%Wv?*a>txuS+Jm<9yz` z9@OU+&}!+LpwG$Xhq(O~(oETq#2xT3EtWouxl?7m^jN}swG2t&&XG4P<$gfc%SkKr zo^(ysmX0gA(`AQDUd8*o)wEPPKFaO0hWf6hPU$rCF&e*)I%d#lc~O4)IPdNoXu^MP zB3bRMmh(a&-3 zkoEc8-UT#M*2{z!crTZZFLFoA{O#P0vbm5u_$3-xL^Gx14(=S;DAQiyJ!U5zT1=Np z*VnicWTl+V9_75hEL&vUyS$f5w+ikASuH~j@ZRtq^*TtCWvxs-#Cx@Lt>n&lpEgSG54a0u z<%isEN9dnNX=JtDlWo%D81KchLx$Dxo+n#m@p0ZS$dHe@Yo+Js+!tj?9e4N%+Ad?i z;12kbX3BXdxy$9&dhQl^_$zMLuW6^8)WGf4NK<9ZH{8Xt=@hr$w|Y-j%7E{9&y@4N z=PsA^&D_jJ%G!P`3TI-Fa`3e%EuS%4*sD2HwMDj;xnApu4nh zFF`IC%)LvtdvX`wNZVw{5bh?~I+Q!mo4$GzjUGmeWrqy(N=TE;4px&ctvMiTfGHeW=rv}nWnHS96B-f(9w6E_sLGR0I86Cp= z*oib<*2+1z^Ik05WZ-1p!|tRxvR-=JrLQMzrE56vak5mVMerUzg`T{ddQ7DWvQ!pF z^1f&qEtf;1xRYh2^q$3gtt^h_Zj*uca@WtMl`+&Ymb%_Y7s>QE?yd)DNIcDyW9M)3%PS-z4S=rJwbNKuq3@N>!tU@yywZ7N4R|!(XGk!@M4;Z z{?h(_Ii5n3(OuehT}CUV^K$NJSt#4&?JM}aC6%V5yR@&xvWp)PF+pgWZ|RS zuIMi9^YyZFEq7o#EtTHrE$zKR>AH^lqD;-;Zjm|bxw~Zgvx z4x6~A%DgP@CYiUHyG4fN=(!Bp!rg)X(!T$Gxim*M$pzc=JdY;GO1bX^-n(SvcJ4gc zB$IdYUM{^~<^J7fs(a}|x2g>uVbJ^zrV%Df}oP15@)ccyHS zfgkBEzmW%y>Fd?dN?B9O?fMyY_?$MLq#pG&L6*u1jl5^d4!P(X-fN`mDemlVsdE#J zmc?@8_q-oEO&x!rxo2pTENtO!lYu{Rm&yw=rIq(eIrbOs^XF-DJ1v$cf9Ll2gC@wx z4sP#Gy)Q#9aYuI1JJ4I&--kJ}O>RbiY4;lRmu5o`T8!?}_CQBkiT=`d7 zz0qIVo`mkwY?ZzK=Ki$Xb(in=_n>>KG{vT7*zi#O3ezBEamkh6#Len1}f=bjrtGe*;2XyB{d~Seem0-`+=DbWk-q*2 z-L#laOwoNA{a}Uesq|&pVAG~9vXfR8(}flEXcb-h8{H*OOZRr( zXUJ@MSYDKkfAPH@iSC#GI{PNks+DwW7JX?eed0O#ryTt}cal7s&+St{3uLog{sQmw zUZ&s5T|2njq~n|1QDd*a{QbJGjMk&Ow0}N&C0SQzHlw>VzeRUxPC{>K{v~74S=xS6 z_Bz4+C3;J{2cx$%56cL2mbSOc3)1l`-UHBC+VhRFJ9I^i{8?FS0cAAP0W=gD%}3%w=oG8Da~?E>l3&3Y@_XV6`mZ(czkbELhlq+8`VdFNHU zzbG%r2q)fm$cr+v7w^Bxu-@DS@`5by!}~yVmiGO5QMSntbe49{mQ8X5x=XuPptm&p zqqj7Z`}WDR;t+g|7`&DH;j&eHY?>5IP7_F7ph zy>8(Bq9$9 z?~oVejN!cRlHEse--YhdzMtQqyEIGCTbdVT1bR!`1u`4mrR`n!(`D!_Z6B7w=q+vk zBqyP}w0$a`-hl4XcFh8MPXhf=E_;akqFl0&yH>g$zA9!ZBJT5kIR?QTiQJaouzq9 zMxd{>y+huFzS8z;`G>4WZ)x}S=q$}sGI%3*fgFa;(wL?yWMt zC-4v`2jFF`>&xv=xUi4mcmiAuXK6H_M8NH?5zeR6pK7roS?1#?M zY?DdoEp4}W(HTQ%gM1aer9J<47@ds1(squlm$B$8?Y>o>l-a|1ua^zzE$uyT^p<7< zI!p7CboA$LLT_pJB=nYM6*^1P5q+f@Df46*I!n8E$Pjdvww=*gnguceou%yyaxnTz z+skDy^p&=E$Uo#{^p}lvOY;pGfZoz} z0J=(ZmHb2wisJnMI!k-rAAO~nBoE7_=q&BtCTq}H+V((SX)cu?OILK2_&V}Cxe0xx z-J7Hz`byhfvL2nK?O61c=4ly(p3-)@td`F6dGC}V4|1DO4~{D8uXR6m&j%4 zD{b$PXVF>Oeh_`7c|jgVXKA|>ouxSsouwIp&e9AT|9xhgwWmSEbYA;&{>+lqO&yTp|dnY&{>+Fp|dn! zLT72dj=s{o5`Cq)Nd6x>OWRA(SDMG(Z%R2?e4jThOMPr_CsfB-iXf9 ztU+gKeu2)?+=b54d>Ngkxdff1*@Di}oOF<`Mqg?BkbDcBrR_23EX^2nm1e$dkg@12 z?OuSc(mWx1p|7+ZD=X1i+Kxn5X+9+n%MK_1%lAp>EA9Euaws}W+w0L;ny%<9%{cUx z<`41&I!oI>qq8&v&{dizWH0oUwkOGG^p&=skxA$*Z4XChX-+{;X|9%g}h#D(hu6I!n8^ptCf6 z(N~(U$UW#RZFl>gzJbot_Iv0o%|vvT<|F7U&7E>9I!oIZ(OH@W=q$~}=q$}7be3iy zI!p8Fe`yywOWPOFS(^O@(L8jPw!cSbX--FHY0gGxY38G|H2Y7XpP{p~eJeUk^KNvO zW_R?J=2JpENyQehG z?Oy0A&Aa83vKXDE-Rsd=np@FXnx}i+df8HMy8kBXJ&Y#!&~n+`mwUCmAd_z9{j`i7 z&V52gjNm>jgZ;R(W#mZiv{CeeO!DVGEn@??PsoVT+y(NHG2G>H%~R^f0T13aR=T`XH2H;viS~f zzc89A4@LU^ z78IUZYcGfozffuk(3^JTCi} z@ZP?ghQ2{_rB5mM3F)zi+wCn{DZ7_(hwq~W@|+AV=Y5~-k}KZj{jhZ2&mAobKR?c7VH`vva9GWd7y zUGkz_(aC$I^t{NOc8Lc3P1nozF76Zm(&}zOmw!GFb)YM{(>^_EhD>$ju9AzcP6JTBeu;XO$nkiBN|9xHdri!x#spBKn;GB}#|Y}qJ%@8x~9 zJTBd5^PVK9#&PG#Ch0ww_hflc_IZH!_41sIi0Az!`K!Eb9`9S^cXH%>-n|yk0(njb zC-9yvuUN<(D-X!N5Az-^kISixdEX^Fxjc z8uwOtL1w4*8dS@euFlWN;<-zV~UDjQD{2 zusr)A_nk-R;A*;59+v$-;(gLFdR)4rhqS++ljH&Eh%VCZ$EEAX-1FoGIpK5O-RtNa zx!?qM|1W5Qoc$$tvD|c$yI$_E=XU&xo|S=LbGtRrdGfAC?mU_H4R^KdI>jCNt=^O0 z%h})YUMx3#&s{G&nz=(x(@goy1@7-p>IbF6q^i_b%DzO72;*OTOHT_w%x-H+Q=X?ZdrUo|GPa zc^~FXSIN!jBkk{-vvS@w+@1sJ0{ND#M;~eLdtOJE$tu~`jrT+D)bV;6DW8`u(&Gj` ze@K?f|C8gRdY zXt`AQsj|9BcFi{-3&ycf#6`PvKUiUisr;~wI6Tu2jSsqBy;iF}?ZJ(BdkER~%y z>|s7HmuZi1hcBZ0lj-Tj^m+7=_T%wu3f+c2()Rde^ats;oI6!kN#_;3&zF7BL)zze z%0a8Rx5++f+<(g#S91?|lpc}e(M8(V`CFb@%YA=3{ZihIF4EpRBFC@ecF&-B(s4a^ zsT}e+caeN*19#j;S}c2Ja!-|c(sL8D2MVgN2Ak9d5L^}85JriA| zJ--1xqu@&7ZLy9J&pBimus8-<5yK>z?6#g*=7#BfE8belz{N?dr?> z>X+>IN!q=-kNv(xbM!3x{eR}jSX$KEejlIh-&Wf14>Mm(qi;M)f61nO@O7OWx_v2! z=WriGH);1*Z=wZN{V(sZ!!-8yftPo~tm`i86itKV`*P}R-m_!q{8;*oJTA}4>+j?9 zyX6nb++!Bg^>Swl_jhvG7VcxR-0}L$->-VXkq6|D^6F&1KTamdTzOFbB%_w_{XMch zg?r{wS}tcU<9=7VE$2Qc|F?pByPT5B{if`6OO4Q4U+pT`31Y%DrBm zkzs3ie_i%o%l(B6Oy_Qp;~wMQF8`IA*71H$PR-yxFP~n|ea+)^l1z~=%g^M$(r*Lb zpCg}=@5ys=*+#y1Qif!57s=0MwJAb*rsJMsN-GC}6bgYqYN zQ*XXMp)Y+`x;b+nlR5pkf0eth=DzA0S|r=#Z3B4k7)V#R(m~hKtuo*`?lk$nyuyw5 zDKb}nC2w%&^ZBw`4!xfDkL1EZ-0?Ti_oTlE_k{n^6N9OPCmkiz(fi*lGZ-;b3C<QdW)SZkK}txqID8gXN3zW9bvb z=Lzzd{7c3J^Z6#(B5xeWd!&3zekUi5=kp@@r<^%~_Y!$!2zRUuoXCB3C|xRxu z`M4ZCkoRr!sPu8={RcTB)H)mcb|1Uf{{7cnG@ITQPiHTr4U6d&+4QpG^`}YK(@p+#_ITn71bx6@nipgqFq?IpDB z4I1<&J@N^ytfi-$=-mHVk7M88_`x*8m%cunZoh^097o4z(uJ$+*8%pqX=~`$kJ0A6 zBQM{pUb5fkZO^;EOvB}K2e^CV_ix+tj~SRr?_8s*HT(7?_0(_q^I?Q_TD8q z=OlMzz3yMpHyh~rQ#5gn=jG4!Tuaw)rBgqkCGz((+=E-FSF&}8_U)ZtLNk}rJ!|Ob zb#yVhM0>9vxK)p=PnOfcCul=6y(qW+$UU}|djCvs zK2M+gmCpTx`gG99zvx?i?dLW7@jvWN8-~%9qv%q9Iy-6$zd)~O z-s@&R-|)_>J?33Z+gj3UT36!*dK-*gzp02`^zv>KWCG9BlL4NaT~osAG^xy zlhmEu;Dhe4P7k-9WO=UK|@nb@9AwnF|(huI(}*}{CK zU~jsK9xj7=Q9IbAEIi}@v+1G=$PX*R-__yk8ZduNxV1if+5nn0gg(0eU!HINmT*QZ zSgJi-Nl()a{-{^b_v3P06@4Er8Xtk5&%nud;TqcZA@V?dzb^Bi7K6vkV19j{F7^7m z;m-(Y5ebXx>yeDFqU%c|$JxOM2bfP^uVkJBeO(hde=S&%hU@E@%$r~$|1XRCXpe%( z6KN>DOEYMnLYOy=jxCJrO+)EjYEuN`b*Ts4N?*_%dbcR%f1rblA={X79eS%cat0k> zj$FzDHlR1?OWMK`;{&N5ji4FS*b4I;=w!NvKA@Sjq&4Py(ga%D2KC6^@GJGGAg_n= z`)^wjhB-nPJ&%$4Nj*Oihq=M~Jz)twKaqNXo}Y+Q?Bw-P%%pAg{6zA~itr%)+7djO~20&yDo%t=s`L>5cPF>9wYN^>wRQZ-RCT3K7#Y( z;BFd0W7^Aki_W8U_54P1H)^EkH`%pUihNhNDbiTXVRWma;~!SeEs2aDPoWxfV3511HvnuBYI-voMra zyoMZ2?XDxYqHpM)o2Xx*Z|Imis2jvUxBGDP0~kqXK1AL@BWa^V)Ki|qz0aZ53wS9R zzM`X2kO!wihnH{@^?i%ncYvJV%I|Xrji;6aQ4gSX{zINY=M6&MN9PPi-ZTXI4uuCi z;EQ31>iZ!XZxjS8zk-jl;E6BL{Ttj)zkWxydoS;UQU;6eda*=QFcRqRF zC6BY_0_+q4Ur`h7dnw~X8_4&FV#l8F+EDm)Aw07f4qOiZhQjc0xc4kv?kxS$WSz-f z;dt#&CwYbTZxbJD|2FY;0Q7hY|7t%qtxu5mg<|MS`FunyY9^m!h)=@dk(cnxd${zF z^kI_mHG%MQFl-b8!;iwD;cyuZJ%b!eXJ16#MTbNod(j~`ndy%hLYSxB}aV2Ee2C!x$IFzn$g&am7bVN4n1ed$R!}K2A(I53ldbqx0-t*bf07f)~ z7aGC9#;{W}c(ys*&<3_|2g5tU1lqMT^0h9|uNz#_2O1236$Zf$^y>^{$CC!m3I4z{4fW8r|uzgz9oOp z_MC)`Q|0_Z^1GKXSU>lYd`>^-5>u?@{k~}00G^73;j`rZsMJ%R!)qht{iNh>BjI!! zMx!%O&!n*y@_td~J37K4qu_W?m`3aDMD9aNzC!++3(Nn84Q%9d8(D7v{m~t{_jWke z7yj{w4*Oy9acFb`R;DpkTet)hL9 z&LF;y~(FV9K0vZ_A$vdu1QTU)ZtZfU2SAi?&-6D1K z=8rOkDQ2)v5{#kOpCWfRl=B&R{&kGtVEWerxw`{w`4cwQem*ikVxpY?i1RMN)7N0a z9a!fP43A@-Iy^`A&)*>L__BK5Btu;LH+I0qJLF8yrexRaxx?KEh$ z4(9HLwOh*hm(25S150;@t7(?|@6=JVRQ*S1sZ8 z-Y$9dMtZ%t%$pYu$KQp{dOe}k6C1!sdY#}n1B2sweW2*6pIiQt|4(bm`Jni@7W_kN z>-nP8yU?7=HS%)HtFZrdxLVhHZD5cd2iqsXAU#i%`t)b8@pE{A)=x#wr59cz_j?1a z)1Z4gw0aK>e!yQp;qh$P@)wMz-E)u==+Inb^Zdp0p4Ts0wGi?(`d?w>Z**-DDk0ldhS%xDD#%tL53)3!l?P^^j-vghhJ60P5Ns`8}QIj%?Kj zM$&P;x|NZff5`l-GO(f}jIRz&YrxtQ;YNCiMovb3b&$OO zmURsEyhLnDXVTcisP8!f!{~eJt>-UtT>X=9IZdMV^n6CfSL%6;=pG3V(H!cg=QT23 z?J{geZ_>$EP*0k?6+Isk=hD0M`2*Bz>v@rkFVyoPFzC)dIx+G0I&Upkqt zpgZZ&4VV{2*ZUxE-wEw@Lnj*Ihy3vX+;totItfSX`I`J3rh2|6j=c^a(<*x2CiU8J zaB(6$nF^iL;D`^fqMnz@{9)NJNYBS4Pw6b@Sz?ndFq%f~lk*y>5AcIV{;&)kM-BI* zK8!|DpCHtG9){ECCR*wU>H&0r2y%;~F#b4v69)I6gyG>ZhFYFNZbHM(BKw_#kIusd z5wPX3_eG7i3o$nwYrnl+17}V?BgSQ{R=MSO7BaT0Y-)Z?coz&$QvJZVnOXZ;6RL`5`dCsQ&{~#ZrbqwS@SjOuZ!D+^DHLX?z zc?R8Virk|pd{hj&n8A0nzd5pD3D}NCSt3ughR^ADT2#;H<@vm$w{4L>m4vNJ@wn2k zb6J?L96Uum%Ol^Y09`6V2S+%q5}aEZUZy>&An&2$Y9ODdRyC1p(j3~;33V4|xStlT zhkS%Su8%ye0enXvHAGHo1YH`#oi1=|6S%)A$D6}N)Q2XuLj7fH7}XYrwS(h2!>3(f zeYu{(&|I#sQ$q|4T(*nf3=C@SfIWRg7XyRC2Vj=3*hW4t+6AL^-Uj(zKM2Mihk+;H zu#>RU8ECLmG%+w3tn=2iL$OJu|ACFFgj z)azTo@s_Zg9lS@U>-B~*&q(h}Cr+jn^!g9UnQ5?de~Y}FqTjDbeLDE_x2$qlGUZ|LtO(w_dNVFn%3uv;`i}`_0MY9*KoH)H@FO25lLSyn=?) zkJLE<<5Osnd^UOO`kC40nMp?#M}AWRMp?k$^sy!KAuHI{n)B#KYFQTbU$l97oBeuiDV94)mmt=)k(D zKcMaFA&;c%>LV|232+##4)x{q1+9A?^}j{r`!M-A{Y+smGx&-gDS=$e5-zfW&28Z^+N~t= zS=y=;axkq`8aaTLD}$Wt1U>4&YxSVDURNd0>k_Tk06CiW?uLB57aZLi*60sy2EsSZ%u@aC&5d!!DQrk+Hwl=W7=dY@+s=&i@Y!#9*cr^XeN!jhWbxh z<~nl0hp<~ByhZ(!kUKtur|5v^$Tw*77s&p}uu=+~NxQx0d>WUD{P83F?-O*$g8pA% zzpwB*&H0YJCmW8+g{}U7?q0I?cI7Ytzl=09|!D znb(faE{eQpEW9)h&d}@4W!_8rS+56|?6wp}OJXZ`iPb|z;U{nKB6UbKZzbsH`7P7gzhWRaq2_I=yh#UAAbqP(;=6UM?}Fp zw9HlHG&=Yi@&WQw`Zodj$TK+U1$^ov=Uei81KYzl z^iv1qimvcyPng^XM*Ro(jfL^Fj$Rip>t#=YL#IKnnJ|P#A4E3L>)K`hqd*uH4BzQ> z?ouDD*SCwE_4;;k+zIHS*SAY%1iY)cq%7sUNVwPdLt4 z-uFv=O92?6*HcS=qt{c5#R|iQMc~Wga6k!o)0&onIW)o^`Lga~k#!QzahzJ~`JdG5 z>G_|yoVL~TKgkXBJWm{P7p|h|dVVMMj)~AI9X|K~vuT{3SIN8ySlhE)JxmJhxCR$^1yO%MkUz1 zGF(#~2Gxae_2I$>@JD0X1o}3GKFy$Ab9kR7wm^Q>5`Jg}o3w$~=+^eg@zkaR@?g4) zKBc8QVmzW7+}9fh_J@^+!q`!8$t+k?`y9yc?W|rOC>l0!%JbM%*#0EUKfpP!K5Q%u z)b9;t{+E5QUcK6Rd5mYHJTvFPWffiWa6w|i3fZyqg;mBh~z&Lv54s!M*xHuM`eFkehhZSEyuN3%&R(Xm1=?^qCl=ngM_`~V% zBFOKHLi6YF2Hp7r`7J$LT)tP3Cp_eHcgZEkz&A_f`WML^!r)-N9!7G?8#vHV z-X}Fbdng*la!p9kK{Cl{W4#-6I{0t{& z!LeVU(N}0+NZvQd-871-uvoszgwNWyd?o%q$X$U=hYjP zZIEXfz5kFL*Orc>BO*~>OT%bKeSNVvFgT^3TZzf~`Xa8^*A;PdDBMZQ>FbQt&GdCf zw4uFepR=eBIS-xmbx7vj)yMfF*BkAHZT7)_dqe}-M@_HNk~&Z7U1;e*}$JfTM6Ly+%!sq27YdrN#C0JUK2!Kc5qC>GKwU>f>1&7$oZR6K(Z%ca?!bbv4ew zAe`=qKwfqk+FpTe^m9C!_xBF`9M7BpPbR{h3G(_X^EM^J+i&6Y_wXuhp`QoJyso-G zS@ih~1Aahb{hUzhhiNPQyioEi-3KNno54!@IxV@NzD|pAdcC}urQcJF;rhBQI_vAU zIFtI&6Z8fxp|9IA&mkL*r;nS->!#FS(;VvD67}=0@aqA1?e-@q8G9U_3e#3wGTYo5B{O|^mA5O|DRr`E*2dQ4d%k)H2VM96ZP(kV523lQiUH$JBNv@&LM}9?PjAso8G3Db5QrBkMLkGt?Y@q4=p?oxjCImuhG);FB(A)cewt)Nm2%c60>2Nt0|(=6I%4aRTMx@(dBsmVGXPyOjn>aiZ< zS80b0$f4AHBeDlQLv1#pKAXnV9-C3WMyMC2Fx1<37}A8`q_&w8wVT&rlN| z27?GX%ao3hNw)aVKCzC~R^P_6>)% zPQf_(`80CiIhc7K#$JH)BjATfXnzS7ybQDHoh!)xQSkItIA8an%k!_60W0bGwB%Xz zmY!EjPNxQ$$j-DM-AD)LVmyN;{6@ZVPtLbxogCWcKJqSF=mGK|dVv0>-5+B7HZAlB zxjo%UKhg$|F+PC$(OCM6T0gUK2h=tJ^`SI~ z=F+-}7+*tw(Sb>*2hiu#_9^Pa=r;P8zNbZ=VO~wzj*g_>^ad^R9P|6olQfIAdV%pp zG?M1hk;xdpK+RK-N7Eo`nu>Zqx|cqr8Px10=2fQs=n@)5O0%m0Q)t1?n0Hz~x0CfByTUnc@L4x#J`pz5KDIK? zZzfEn$)3o`^I_&P7_l81`oM$`SnwzuN_T}K7YT!7QeeeY_=GNdiQMrO?3)e)zQB23 zVXyD7e-5<#4cq3EeXR2QeU0GC{BWlB1<~Ix-B}QMjs+}V8ivt*cF4YE;qmscV@KG? z4Q6zQMS4Joe$aXVd^-}Z8wI~mqcO;9ec@%APV?_Ty&P>yM^hhql0KukwE9jQ-+>ON zi|8(Tg=W#ByKr1p+M6z;$7wPxyc_eI(OJ}&o~K`Fg*}-6ADu(D(i8L%{Xr}3#c><_ z;aBRlAKBsn+#LXS20_Eauo10y8+rddSo#4h{sqp-fnQAI^J@9~Vr~X+=yfNOz3ao4 zF3`6LJmv;3>i%e%XXgP=41?*T;D)hq@B}zyBHW>U+T^%bbmJW4i3?!JB6v_gXP0>w z>9JkNRtIPZ+;kjPxCEC|`+vyB1?6*eS?3bns-MeCc5e!&YkwTc8}##eajkwXFP7Kq zIK+!PVJ+<=EqO70bP(BE`{_u%o%V$mm+0sDV$V}B?G~JJ7p6RbfAu;9nP+YRJ?JHR zwIu3MrQzr@@M|TQUJZ_I1$*oF1hU>_>f0UJwFg`<8E&E})P4%;#`B>Et+D{Qw(dKZ zbq{#Kp3C6BKj3{^tMc^&7H|T`U|#%f%tP({;39BI>R*g|VIhcx5yJ|zjWkC`kju?Kt1Rkw0jTTsoe)=x{h9_ zCq804`V;*88OCP8qF-P;>P@fEKeWzQ%o|O2Q^#+p7yJ%W=%63S+vsiD{wM0LInbL% z((klpF2+aFAM}N%d|xJi{`T`=>G`lO^`g6I*@YNiL|f?hY;t^0dWk-wQ?_9I82w0V zZAE<&Jw`v$TH82IkI|3Rc{|7HF?wPb>ThZ7-N*;%O+RFFf7tdQEF1v618ET49}H7Z z!VTfj>=ZOP1G}At_BUa3I*A^mFKDr7&ZCp)G5V3#x`la@=wAAQ7Q2mcH@c8sqy~5R zICLSsO#l9WJO=X?)62BjU9L~p(|fe|J&x0j^d2pCALHHWdU}r*d%)xAMtYGNKg75@ z4WM;1QMda6U9;ii!t%YY{C#{&?M;!}7lR@6u^F;gad^NS4lV&(TfmK$%vSIaHMd6I zO!M0y52I1Eo-OKSO2Vo13N6DtNJ2iycXfkcr2=xs#jSgsx`VH#j!g=%!b!vk8A!^+ec{%N& z-{;Gp?<#7k-{(u7Mpx487O1yt0|Q*4nH!us3~r?nG+_kl#YV!cvCwKV97*R+Lr$Iv zr_O?rv*C(4@G_k<7ukIt44~iX=lQ6QSOB{(f*npe>CHB6*)z9JX=2KW7ie`)i7$P4LSD&J7% zt>4ZN-YNpqsjVq;cY38La#S%m)eN4Xi_MX3O28&IaHu_esMnjw&$G}OKA;A*k+W&p zI>?cAVL($@z8RcHt=b|_rx%AHJ9xk(noqB1k;k1xgK0Otu0`r|X(Y{=jk?iX*k}t3 z+6q4$f`fzL@?cp0B6PU~{q=eoSwB&)mk}R6hUN9T8OfvR<2dAvdL50_3+Qz;qM=?# zBM#E*XT%s^Mk8X3>XC)dk}o%Q+}acN-~tJm2`4m5?=^?Do0 z&5OZL#o;##xY!bASwTlfIJFL}-3*3zgs*9zPRK`lz~UaT?=ToJ9G)BrTaSkK=!5ad ze<9Ra9u3Sih~6bVIP|Cf0IxTdJ6kJg9$V-1-Vr!-1-XkPJ=7n z!cyt*L?+y8Cf7yD@5ibHJXQ+2mw|QcUTOK~B2d(PE$@IDlvVUi2)CD?pg-u-H zKzfosrp0<-+?EE=+w==f=!tp7d%=!$4h^Cy)V4R~4W)iGh1$AfygS`UFVoMoN*~PY zM_1AlG=&!L%X!p~CQ#dc9H)LXg%dcB`yclt{E7E5lWefPy@JE8L~7=H@dpN50!V_NGB z>gQ>(v&e3AAw5Q4Q2TS7M?>ge+Vld(_tI(+$O~zqNaW&CT!-$ZpJ}bD7@tCq(G+Tb zjmOjV^d6mm6XT!mz_KxLGCfX>@1ov~UZQ31p+1COp-%Tv-$cLDh(y%?(VNea%l(1} z>6skl3c0Z1Z#af7{)2phTK`4vMH6XvRm}TRjmKAqYiq!rHDN|!xeisHXR6)@N^H;qHtGPE&;S}u zKhbiXFmDr$qVxVkecM!+M*q!0KDH1VFM?uV(s((7x*W|d$HEm;M5OjT&2{kmn|5c;te@|oIjV?+3z zy0=BnqCIs#l^k!{6@D8Dokqd7)SVvue|-YRLp@=Qg)n>x?6eLJ@PkF3!xy^mNFJ}@ zTe!KjT>mTinqChqcGP`CVr_5u;2wOb_p6ZlyI9yY3pV}=S1Gzp} z>T8W)fL>=T`7#aG>y0H}qw(dCqbk7-)nHe>4~5L@-2%FIV%F=ErM|ZxyfPGS7y+AX zf);xHvdr6j0#=NIyY&7NQZKF7HH)EoU9)(b-g$-mnvT@_OUSro1=y9IsEFLJCG0X1 zj-}ORAbWViMYOdy@=)sKhrEN%JA=H5n%qHN5d)p|dTV(;m+0At$P@MYYpHLgb@e)I zokv6TdThy&dOfx{P_Mfd-|6+%V#jZA8!h_-c?jJ>6KTnx81GLbvym--!GSctpw6f%(EKo5`-n?DUlsT$2)1|!zv+E9WZdEtY^eLlBv;jaWa8NTvcF2aXA7O}V376^ zm-@A;@K+r;vp#Gv5YC$hH*SN;fgIQVBXazJD{$^#SaP6TH!k&1I%gR!Q*fQ#kE8oSY25&>bI{snI9o`ahuiPiT?@cbdp`{qp=i7ldY}(2g4G zem5Bpr0H~|6YBfh!e2dLMlYDF`_1IIYJK29>P64dR9bit=DE^k^aUNM`w(Qk9@_6y z+)qDI*QuzlpAN4q;rykrj~CobE9!k?WSzlu$_nI-JK%#|&~G;!_7ui`gLXzvdB;yI z0&Ppc{jK0D-6tXI_tkw8;)PMrat`!e2uB@*U5?WeaG>@PmE#IMfPY@VOKEVv?zfO} zJKb*~#^`9;!f4vD8uB6W) z_tA6oG5tVIN@6_++Jw5($#fMxrTZG?=Q%M7ewYTA`@rlYaK=$s=r&CG22HiEs2sn# zAj~NOT}`zzG)7MbHe;pRS2}j<7 ztLQ!&@D%lE`jwhJLwy9@OjBsV=NKE#q$AZ4Ef}Bn33`XusJ?Yuus6V4$Xy+-Y zFQ!N6P3k%m<8$a%YPAIQUUUgPuo?AZ)I1E?KOBZ%fw9!>G4kYRaD6JYe+g~hz+!38 zt&sGUmA@aQi@|x;uxL4GTb@>cZk3@)6?n%9?r8~q+rYF{(0L2oyBpf?fgyWgS%3H{ z2>OJ;t;eCs3HY5B4Mk3*Uue*I)V(jj&(~o67-)DO4x~?M&j+X*J%l6Z@JGnIXyxa~ zT~c7_47lbq-0%n58`jVJeI7Q3YwTe_9cW$;+SP|8nn05laA9}&aW35J37gM@FX)2# z$Tb(hdoi$3d|FRsc;Q(9rf??FKH}X;%HW2yFIM{tW z9N`5AuY~ri;JsbYZ8vNm4ExfAP~=i)VEMCf5Iu4Mxq1XVLfs>g6QW_-9aujGmdxKU z@8=sxpVK=gs5=#e?M@oGTU~-H>Gz3^ z^442C364yLzfv0K)k9yyp>JR+t(u1HMjO6G-bo9kBRBp4yMBbGpWqz&kVbt*-TW(T z@(ntFhrT~yjRG!t&&#YJj4lLsS;7$x(54Bj-2$e!f*o7K74#K-(hl{jUa-V!7(j1O z%QdLCq#kq|O`>PlVxGx57`z!eZ-FOhZ69QFU)YjHoxjE_->i5<*J~`_Z|QnsHQoOyPNq%2 zB0r(Ny6;oQkJH-b=6Si2_KB1FDF-;XcZs~bi5|RwY!v~=(H*q#CDiND2713hS#R`J zIFAmvfgE=Wy55F+^}a+hf6ZfP@&x)P!gyLZ3Aw{-I9vC1%5nbZt@5032^z*&=jEgB zws}U;FSL9g)J^-ta}^89OLLbGcn z^Ku|fu23p3x7R*wGOzDE*rAU|r?of%N-n7P4HT>CeFH^@;;XX}0HB$pinyXpO0CFk1^+QpG(QOq2Aw4{8S0ntO~(}I`P9&xY-+8Er+Sv zw^qh&wEv8%_tO?ju7Udk;aPg`HS*36u+Ud{=sPSG>XdhUsk(BWDeEkt|FnONW5%&{eM^TdhK5zPSbt`VgPNc|NlxZ zr2qelU9@k3c%HiJI#1vz7C07v~Q5OL+_U^2GKM0292d}X%W4zt<1Nj z2WcqXtbGk+e1k1qq_1z1e>%e3+TTF(aqVv)UOxjL(O^Df58xXk=~-ov}O+GHKkqXe(KmzUJvDQ>(Mr}Cmq=umd5k7TO0& zawoc4`#nf5Rv1>IH?;4A)SuB@I$8TbNZpfq({Or;rqV)1F~2NrPRG(kbT18~AE;3= z9ABQ+rmLwRy+rTPqGmX*0&Puu&~@|xjiL`}(c(Owwx&JkI(mRc(TB9CIgh8UX%D)N z9-vY5AvNfZP25hqF&<)Ows-z@_0cHVDpD?xAu#c zdi!wbejR$#eY)>m#@D@tCh0JO{`UcSJoThY>DrGN52a&skk|cz3v}PRtekLVj3atq^EY17-t8)$_zP3olDo!5PF~He~aTv(N*+4&80=sF|RbOPMgp! zbRZp1=g~EE7d=8RQ2TdSzrXIQm*20q-Un68qJOE`7u3tpA@uf7)TjM|k8@z*T-ca4 z{ewJ!9{!8$`VUSsu*rMeGWlR%-PbG6V-%f9t#n_n)P3m>-FK_cTld|H&2-(mqZyX2<>UpEgt3<=~JWsOoY-l_WZrA;|Qa4?|`V!dE8`jl*xiY@|AbdsZ1|YAZ zTj@i3^$5nZsfq6Em34x2Kd*R+Ry~H?gbt=lXzAk^_oPed9h!6l;~De^4ZVrFp`MS* z;|+ZSkJ4wlFIehhGhn@Ua6HY)MV@XT=dCiYuI~F4Z_>KOkf+ht^dBvv`+jBqEugr_;4-FQ;Vzlf+iI1Gz`Ns(~(Wq9x^ zw7m`kZozPRiMEJA{l{Hc<37wZkk2FJ`4}3)7x`fY?I$mF7v0w@Mw`R@C7`zj+(jek zZJI*!TVh@bT7~weWNGj)HntY2j=bf(LfA>W_{yph|}<@5$EupHybYv8!GaKk!i=L3^=z&CWc zKk~{0(1#wPZG%wnMhDR`bQWDgH_)9lh@PZZXbg>~$@CrlLjO?XU_6f)`joz-`43~< zf;!TMv=bdjC(=c96FopfX^kUTx3KOfmp`X?-A^ti)6cZJ-d{oLb*Z85Gnahl4ty2| z$0oq`NpRG2xHb(wdkd{I;JObm_9MKJ3*XWYx{qBR=ce9=Ky20!_M~IzLb{b6rk80P z&7_8nu#PRQMcdK=bP8QgchlE&R%5KQgs!5Fy1!nY?^petRP4|m#^^qK$uYXmUfk^l zZ_xz$mVW#H_zuiFru*#WxN9_tex?NuW4sKlLp##JbOv2b{pe{LLtoNtTI>kcuSi{J zcRGsBr<-XIy-4HfS85i5b*s}3bU0l^chNKSG0mjLN3o6@y+Ci%M4C#=9mD)8bOv2S zSJ2=v%xifL?xfSAk&E1dC23>Yg^r?)?qFVtd(d4!7neWJ5p)_|L=Tt1_&IuoX3+h1 z7!RfA=x>_e9^=#LQo51)(l0cJRw#?(>d;oSI~_tN(FJr3ZCwt>_n`f07(Gu-9WbvN zZAtsk33Ms-rN`(snnXX-0_Cx88Cr*Sq=V@Ux|;gY(=>)=&}>?u0@g1^=g|tl&X7ExgXxkpP(!LZj&%Gy{*%zMb5AzRzB`3n_v=RM233V&&VxEx`qDI{uZ)cyf^$z8!ks)Usn1J$hesktm+JZG=nF#?}dy{Y6U~J|AplH z+V?`tq92DKzw?As_d|~ZaBBeUq?8 z45{aPMD_k9lACEi3~?@Ps(mmdPo=@MqV~a%`b7Gh{+ERMCVG`-(_rn3A;Y#lvB=@JAXomL1kh+8R!O(HKiKc2l45^pYJ{V#Tx{A)wJ{VF@q~_WWL-GoGP5WX< zZmj(<#HqBg_P@|fgJ~*_(Y_cm{#yHDh^E>PL(HO8weN-Gku-p&(vsT$LdM;w7d=Z` zX186wC zLNn+OYPAW+JJR~posOVWsW%OvVe~qUrQfOHW~^U_PM}NZ1{y-Y({|bqM1I~x?W-ZC z(LUN=L-Jy}hWgTJ=P=}THD3F}zXPP7kQMYq#iG>#T}%H!!jYW0jiCv8XF>0G*;hR_)LhW@6#pJTlV zbO${|W9dt3`~ve!P)AyywxjNJB%MjU={6cbPtof%mcF6isZ}x_zdUV9$I@9efQHdn z`jQ%_@aLfQX=^%?PNRG2Bl?RLNX0shX?r@CuB6-OEgDCSU-Eg-#wBLs0Pjra(+mL)x`)r60w6BI(QTu9$&1o+> zm=5cV@h|irZPf+!X*85J>Wcaj8b&`+8|~X6kJp=e((iPd_VbYOV4B|@*^Jhr$NQoF zfPNW(oI|Y!BKM_3=uY~LR{sz4E>3}#Q{f1@oyO6>+9yPw-^J;iul+(K@1|zjH$-w6 z?dyqLbs>DX41TAE-pE$8G3`j*>3kYYPg7&;3t@Hp5qnBvY z0L&Xp=g<{&J3T;64`F@{dYay)zo>H{<~5^J=mOeX`;5r*b2|dZNpHP$Ms9VzUFOhF+e-U|{O<&*{?JFYrR6gk^Azr7k^bK_|#Q17D zw;*yLZC?m^CyktzO)TA1+B`rgPoly7Eej#$)8oERKhDbip1V+-^ zw1D;vk#V2qFtr^W4S&<2~HWjjnKXza{R_0FkSnD zNdA}$O$?+@gya_5Cq#TfHy9!N(0?>CKkCwwZDhtGuq!nOs8eFuZQH5+Sfy@^9eTo0t=f;Uj(T~o5OVN>mk`n`+A65 z>%w3fN=w&6y#n>3Yv@V3y94Hh(sT4R&7}FX|A#zYn)a~}ztX}3kgaHSdT=!A5%ea# zPiv3Cco>bO*XiD|7!Rgb=@a^j8ji!fqO=07Mf*?>x|2GN$8pZIJ?%k9(`ht`zN7^v z;COR7fR3c|=yJN72GU3xO<&Lqnnl}B#N+g!qvVwF(0rh&Af_8F0NCec~+ z7(GpIXrB?8S3vuWi0$b!?I$96ruGvNn|FkR=r|hTin@&(?4$icWd7G_@Go7b{XwMu zLHmPXm2<>PlzP z4RjB^M3d<^I?)#Ejc|bB+CM}d*To5DIzvzGCnELSy0BP1SfDXn+zwtI3afg+MzjNc zNE5V=h^!Yn9*&s=m(YvTk?+!H^b<9lhw&NOcSP1{?*(6K-x0}%>!FVij0l07Pr%OM za2!2<3OR||pW{4gcLn*xZ8$R)-iU)Q^#027xEl+|{s7Ub2+W|nZIGkv;qW#vh|X$@ zJfatzMtkY~5oNt`)8SN47(EYmS^%qh!Jo@uqcw2E4rm?#JL&zFWxa-azh&{T-e*}2 zgW+`B1>_2MVI}RiBJ-Yqhjk2Pe}m*`8lnAFBtNBFiz5HBfM$N+w@3p6_tNy7K_?X&Q7K z`3lXth+Om%d=mw~QKPHKb*KydkG8yl@x3=;5IuYsdA{~{k)L-NwSI+csC`|eZt@m> zqqVfZi`0Xu_a|g~?e`+}liKe^teOJ@sbwy58R|k;&`kP`miUeNwdgFmjUJ?-wDBLz z_oS=nA!_^=g@jXeKYy&tG}z#N8KKsQU+pL)=JG?31A#=L3`;X&%u z2>JdYcvJh*$m661b6yDicM>LFhP`jXm=7?XCR5X|s24PpeL%9FEghxzHWPU07A015>(6w|Q{jnX#<@14sXpAp%JWZz4cc8w6-q-u& z%Ht-{mvo#T>NDv^f8<{W;C}&dKi#B#hh&|R+IL7SbQo69`|e7vNA0yQkmNcvOZx&z zHogJRYTqBpF|@t*{gK=y6TbfnbEx4r?C)lGi{Es&3gS>teTrvjwPJz?s!5xcW!+o%~_5+f~ZLIx()Dtk5W`!Y- zJ_+Zag(1}U0&;i+^oxYIXaappe^6uXHzbc|L3>|8u6`3H-hyRr!yx*SdfY+XpU!@Q z{4fsIOoXY=VAm9QHx=%A$#J^;74nfZI5i!H(-QBHKYfPlwf~Vke>3fWB>wvW_x^>K z>3y1%&pB`29W%J64D4DR_N8O#47!|dq6g?PdYRs#&uKdSN&nGeHSl=W)R8u(&*>Lh zv?k`4r_E?jI*~4=duSNFOJCBTw1D}swQ*yiyomv!mG2KA-(xWtj-l0h}gJx5cVpz|bI?{Ty4edz>&@07p z+yk0SKhi(c)Ex6l(`vLa?MVC5QFJCOCvTCyb8t4m$!Xu5>@xnSN}?Y||@$8|b9wF2Ix^Hw7NqXo1-m&~69cH)WQn+06j<3Xsiv!f7AD+ zk!RS!ie+IN8d@E>W(`=pCTvv~9@c(f@_T6R0f*8(OOQk81$vvdT8i;*bO0SqGuL1| zhk67fkEKiLetL(tI)ZuK>2w+rhI)gOFe?_?#=&ybjn1SCs5iYr)9GhwACGm~QCI3t zhf;64m7b4!n`t<`L~V^QzY_H`LH=k4Ygxlb zCE;Rw7*P(MEe{7f!m%{8GUw6N+UHFEK8&pnXV6et7L5>=ppCsOur*Z0Zw;d?XkSKMGfBzcpDumv+@Y zYLeq<-5bbV@4>g)H%-P@YQHqmQTwEc4e8k@$XgR&rKj*U-I|PC?d>Gm^luB7^?=5Upygs1PWvuF{ziS4A~)1NYVz|e^M?I4 zLzh5!;52+rztA(<7fp^^9SM)no|loQ(2CK>=Ee>3=AWTY=pF5gChNSmg$^ZQTp2jU z4lbb2Xc{f7{nO<5!j90x9ex-Le~*HD#=tA%;U{Xc1bH~!?u|TVEezTRdj!FWG~Z$5 z;?$8^hoOF#-aCn0O#7+H^K>`|ooP$j{58QezwsD~5kw`ncyt0wF3ss}@xz=2Jnb0_%I8%|yhKLx|7+HXyckJ3JCV!O+5 z$hby%c?&&GQ|X3J7{5@Zao)V%SKw?q@)hzrI{r2CSM9$hkCUl=*TnhSZ%w>ITcjgT zryJ-8Ixhp`0os>Mj`P>PY~tll@T>M=lU(Hs4A*{alDBDp8qr4kv59kOpZqR)`I#9^ zw}7=A;l%pzb#s_WkGDn6ZU>w9g7E`jpCRz{=1{75TrLms95)8zTAqm_J-htd7? z8huO0AH%#p+FwnM-$9dU!BEs2(Fl5>Xp_A8MIE6NofK?lVCZUMF#TYuJXh(y8ObFQ z;hB%HNfp_jAoWc;zj8hUbM4C}`kaPm(~9Ti&vfQn^5a}&8h zG<--4+(I_deY$eoFY2ZHbtT`RDKsn>bx+;rD&ww>(5ou6s|n{ffcYE3#q>AzY=rt( zYSsd|R6A(d0lLx6^ad^55#!CNWhdk;>e3l`5)Gq!^*+DyybX09tZ1zJTt#;}&=c8u z5&X3n)>;DpxX9mIng2)cmn%LolfS>BrS2aR*A|xReZ{k8@G;GzX2nsjNxRUobOjBd zS7|EErB>!xCq}P3lgDeL*PV$yJHy2^j6VB+y$i-4(cg4vSJW$6%Jng_PWub;y{Y&s zM!r`RZS?y_v8CSkK^#d}Xn!=x4@<+=wPD4&u(W8h{Si=2fU?Mfue*Q8(z#c}^1LcstYQsHsU`#`}yD7}k?dADTe*Ydyz8Nl^ZjMw-oOGnKWmRBX0K$KmM9$Nx7o7QJQ=V+miPx1S8&`ad3UwUxJLfEMSk5XOYz@#%&&P=PP!*EvQHK2BWzUmsX`uA z4ga3QN45k1KS0jP{|8_p{<{yWwU%A_%Y#GY^xxzS8*i9$kp0`{9-(?`d(#dbr}_Z) z_rceR!@fT7_sw$H7FlY$Tx-ABqB~SyZlmv1ZfytK+WS<$ZP)*;94AKNZ~w9}-l;y* z{x3xN;|Ce>ql|BR+q@C+|0-U0x$PK9c~YQE$i6`suNzzTjU!L9j}Yn^**^%*O(G*F zmHSf3ZUbbWfp)ok$o{3cuFz}Q!``#y*awH>A#&#jS&n^ZP_Jv3*(Tpq?`YRXND?-0 zmz@<+d6_+Jui4;88vn;uh^$=K-nK97hnO0V5GcpknYL7V)r)76N9>Nw%Cob`lUZfe zY%+Zg*}A%1XcN~^Ze$nKR9<7Rbyi-`Ro=Hj|5L7K_p$E|e*YG*&kk%lLcW-)=U1LSP>(ZTCPV;>#3VToMNJ~GI?R?Cs>Cxd)`rwqrw zGRQscEcTZ{{*nDA$LnDa}|*#?R0yso$8%_k#~B@ z?(8Fg>kG0^0GwgxZdcyBL(XKM0F2)}E?cn=0CJ2|vLN5rAXhmfU)peIl~3|{e~j1U zbNw*b{=nz;k(by=eEuH!mHlSh@_BpId)Pzvf=$fl<}qHYmfX`<1`m|e_}ndl^qG8YE5A`*^iKW| zDo+LAxn6v|bP;6Ch|Y23s}so|RF0HN7Pd3_+&f;kR7rWRj?CIfM*dM& z7$(Dyk{uSxcZ*~)KIe|t`DiCBQ9f_;ELE;(huL0y9v;^f+AIIy^Y6$Zd>$Ik=lccN zm(L-?BQ|v>x+4Q57^V#9{tNm@X#y4+}6*tP; ze2x#_SH+t0m`zYidAv0XE%@9UoMz+j z`8MR8>t*8&vPWb*XNG#_sIrZ%5KZ~#=(2JQ**T^h8CQ0VCm*GjjT*^ywqIlAg01E1 z!!qd+ng6IsN*XzmW0pZqJcD@W=EXOU8#g@vb%VeqL^5+$DjJ;uB@cBZ#?ruI` z2&-+C%MQx{N9D?6vJ{^y#JmhAWtOwD0iQ2Kz4gCxmECnqxyV!5=$Y(gAH7x%eIt|b zxk9|o?XPkRp94e=wmqXLU$Yzdd>_W6^7%ekjnDPLkz8Maqm#fCeGG#{jDwiz8 z=lw80e0lj>Wf`xA{JX9k)l^=yiTQcqxb9;&nYO2_(@VbUEhqJrQToa01LgKXa>X!t zX1M%di;hxGHC9dFOYK<$;V6O-i@;GCVAP`08&8%^CUf#RK-6d2 z@I{pS+h=8!+m@5Twn|0ijm>4e7P7ki+5Y;Y>K9wf4Q*uGcJg074~VZ{oX`Eivo;Ho9CLSC)$>`zDizlFRaZ4hz@i zOC=ZDOEzj6)ql1V_&gTo*W~k8@Rq&TTzOlQmArw6|sDXYyY@Uxn9u z&gXSt#kH~upU*+Qvr(q!^Et@%Y(_qxgFMp)+w@yi&&lU?Fy8;L{Lk(^qI`rTJ$?|+I1LHSry`##*_&f&crT82MOnXkg=jY!dU*>ZZa0{Q0fbsdf z0vu$&+v)MJE{^&d+lkL3AW!2uJFiP2>+*9)kfZQ91vuFrw=eRlzHpelwN4JZE^FVA zFZlcct}nyq2jDY4Hvqfv`2e_`>*%lp*UjNruA9R-TsMaSQ)Ip+a;SZ@Tlw;SIrE(S za77llF6TXv30}&6ALVa6*N@k)5L1qfC3`29$&<^8sbrU&GGjjZtIb$cd3hN*y^8!$ zO(v`%>ok$~n#oCgegI$pi`~*f`H{`Y=Ls-g$!_NJ1jrHj9081P8`|fCR4+C{wizui z*>vNT6Z1I$T))C*;Q4;!LNjDXyN&1eQQy8wW?w58*&OSXJKHrj$9dQ78av{$>W6Hk zE6RVplYu;6kFU2YM84s9dE{t`u>S#*+rc&`&&i|yJ*5m^O#WF@?&u|t*~HV8gKeP& z%F7nY^Y+XlGqK1!Q6?CW00EYDVys~XF{o6FlaYYXKcTFRoW zWvzDdbw?S%&n3pMr^qOIc8W942czEaFPW6*f{}Av&KG74d)jv9IZli}uw8jh6Zx!- z&Cj*v>+w7$tjhD3a2(HH!VzU;f1blc9>{Z;up!Ss!ZJMn$jtMPutJEeovc7ue#7&K zs6Wjtv+z73a$(yyyK?TbGVd(ec!`X?ROVSG|64BS^SmKmr^lbN&`lZTmi%x>rn@UU z$1WH)e>C^caos|D(9VjddT3@jF}qBaQ!Xze$CZ;)%gZa3WwR=BB+uvZ^$*F(M`Z4! zGC4or6yvFRJ`WbUDLdSi3+z67+or##@$L4i{bGkc(D*i<^TX@*c`iS`lsj|cydCN% z^2j;`W$s_)oMCbo&+qa38!Pwnd;#*y3NlwcxxK0E#dCTXKV%b3Rc`XToMDgfd;;d> z;Q0htY`#2WLnJ+RBPm=U9t&37Y^f%LuJA5@`+6yu}IkX+VnDU204M}1aaMB zyUPatt$N2``4i7aU|ym7^0x8 z{&jIK0OP~#I6KYGwM*Y0{Imy0>uiSzA78vhpcNJGISwiLwk_r0C zl>OweRdT^*nLjGlVevY1Tg$)O$=6)3Mm<|RtQ*2g?Ar!&{vdM~kTdLjJGPAHSCe(^ zsCvo~>dT%DWSNGtza3`B*+T5shOb-7?wG6mj_Zo3H|BaG{K|Ddn4Nu_-~hYZreyyn z)SKC#?0cJ?eVs7g!}hns>^M8kUbT1Z6Z^(~w&l*~b*tLCwy9ldH`pEafDJsW>l50P zc0*#U=i&RE#C1iunthkxbDN!gmyo|!#Cjk6h3kE=8rR)8FE7@^;HQ&VpMo#At_9n$ zp9n1bK~}d{KPeAk-wljkh$DL(lw+UDsdkQCZ2z*UxekTvv)Tf-w4MA)pQ4*{t;dS5IP#YVY<)O=&aO)2TIYZUOnajl9xLcAPCg{w*UNl!3NH1+0_c z>!)cdx7*o2Dkp0t2eaP<<}J0W>=Um4pdRmt=i49bpsT9idm-a5w$9Nn2i|uzp^(n9AJiFAcwg>GATbb{N@p=pF z*H6lq_*^vVRoBR7cCp=IgY8B8(7v%>ZIrcoov${*I_3Iy@Mh)7b_d^Y;_L4nDc3&0 z`#t3R4`sV(ct3{xKbtO%a@x%DNiG?I@AEM4E#K$CK09Q+eKPt%8UC1DbjrS#EA6ZI z%3op?2z#BCsbp$?E;L?u=pp&WwmR%=FYGE9Hm}}pdBMKq`ygE3$_9aQBG2z)UgI>f)nwUis+_h`*4Qo&osijit`^rt`Yyxq94hj5 zn}VPBh+LBAP+^lUvLMf$A`i3$dMS^#`|Kxs;#Z9yA0RIbm-qSp0Iw5qi7fk74vmES zf7BcBeFKbMS+3zZPUH_fzX?k4mWe70EtWqmm-SZ289Wz>c~_F*J|7NCF4Lxv*X&!{HIwS? z`5YMLZ_Flh<(3ul$dy%P`f4)fAlc8}7^b|OpM!(fdAUN~T_xl593blFbIA1NWU9LI zL33G+??W)}x!pWkxy=~)Wvom(-cFQFC(DRaWR0nE_I? zEeqs9o-f4rlac2M`F-(obzlUZBZPm%!22LrJ+Um7R35M+>npbyAP?JtJTHjrLhUM^ z8$=$@^MY`lJ!g~hoFMA`>{9#2&g6MPjF;IV8NkN7xLNl)Kx5wq0e_7uYK8lyCnm8}yYe_`VF^*FC#^fb!;nGS(!S)0SJJJjmX* z!5dYt$M5KJ26OZL8|C>o%JXlq$|w2L7x|v&;84HC_j9mCB-xAooEU+zslA;2ZnrZy3D&$wy+iW{tx3#?dpBX zLwSx1^-kyHq>FMf&t;(=%yU*Sehj=Xgwxnh9qwlzb=Kp_**0Gylcpr%RdmFR8@=!Z_hVnT(eu45n+x)O{ zt0VH34aajfc-@S)pj~U1|EuwrcjbwDGCuni0F zUbBUH?gsVOx#ZZ~@>?ERw+h}*V>}A`+rpq(a``+tX`y_}b1oR)a!n@VITz&I1!UBM zGCiNOL_Oje`6e>nmm`Nnl`nXH1v%iJOmkm0IDz-$sK@8~cDVPxjQUxYv{l06{WQk! z+wMGXf}AnE{LFrr$Yol{V?Vq8Ke?fsEZI|@>LrKtmhJn>IQ``OU**2RvgK%5eT?j2 zf0&@$Z?YV1&(BcKIa3a@LuV;}oGm-dk=^IYhKuBSyLqwlkfrjA{d====w8`ASbnrA z*}oINANTIc5IgRX^3*3X_H+AIz73H#Kgd=eWr9y~bf|pKexG>##}Q?*NOG+G!?umA z`X+nSPKcuVb^FF{jjDR2Xfm0-WphSXy_}62L%E^tWZUpO5Wc?&eC`%L;<^Zoz~^mY zN_!@s@bNvNQ=Q$pDl~keAut65|;z$&vOr*KJTg_)_+dk98R2ISFJI_M1d*Y`fT{NmLJ)RBp64 z?EU1b4^1Jjr;)2O$QoJYk9p+O{PMExP*iz+DY>(>3@#&2mz76@MdIhluvEk-;~P_lPO2Y<`ZO_NwVB+dG3LX#Xgq!y20OV1gtM17mFfS#E?zm z$hGn02^%4?avA&7R!psW)N~&2DsK*yxt7WnE974Gt;E;8VXJLc?zu&dvy-+e*F7y$ zpOr0d$sM*W&(GlX;<8U8tju*XxQ6RwutaLP(55M>+@r3X+DvBVxfjfT@S{xBL4N#M zZsqwGjIZN*8VtwtE^yZ@d1R4{uu{fjzd?*I4VDQG$s#t@VdY`A9@pV8KN8Qqz~Nk1 zgS~m)1Sa5l5!fd@*1KQ~p7VfTcy0q$;kgZ%th(%IOZHS=J6skUA?tBH4fE@!$Qx$H zA7sqZGErHXx10>Jr|o~XXOPDGm6s z24cMoId&|0#y;RW9qMVgE(iD7XhF)?cFGl8pTl^0uFt` zuab$@$)GLr$xb56Js%PWF319&VGd&jWHbJI!uk-v`v^ucOlgMby;4+2i+dNDl9 zeh=`eEz7kSTwco!Gwt^=md8`!^u>wN;lZ|773W#w%3sZO_}+w)CGG?{8<=jW)+BjgMO| zkF)OszV6Nc|IooV0MScx_7T3Q+7 z2f559O0OJ}L3YV0XWA6Gl?&yOXY$L=1!U!d@@QF^B1p!nASZDj0^jE^b>(vIM<7pR zKM7c9*Otnf%Vf0W zGVvN2XRTbxeiN7`V;n>fKl5e3$rl$g&`M7gnbP- zFqMqL{u0OyZT|Mk!R#}E`s?0uGW$#*f3bDgX9D>Q`%J*8>@xv7vd;vJ&;AmyB==EZ zboQ5kh1pL6j$%Ivm?@?eWoGxiAkNFb+XzX&+VzOuitZv^Vu`pI=BXeIZc)!**$hY3%cW@&4@d z0L!t@1Ki3!5Adno%Ka{8yOsN1%=QWQzmPMq{{#HUz7McG`#!)B+l1#Ekw>$?18l{< z4lpkJI>4^BNetz{1hO&vJ7D~sUC%xb$e~H(@?^3u`#GSVk9{2A#8UEyI`W9^Qdjwl zjbBfB3i~|Zy4mdW0Mj;-P1)xGc~2ABm;D@&6SR`Y?9$fC_qxj_gJkr9$a3t@fcn|f&g|2G+@F0K;4t=QfRC@qZO`Nt8{v&|vbVCxJK4^b`A_*& zIP9<;#a!2AO255d>B^?p^(&;3!<53p|p z47D}cKLWY(U|DmB{GUBJRQW9TRWUCT`%Lh4>|^$sK#n~^F5*5baxwOsfQ8s+0(P|f zrYHx@l5^+C2>e`Y%v<({EW21XT`nJNl+8EEfXyBpkq5J{1pM(o zInCz#raXZCB{1HT{Uu=e=yGK&*_C}JP>&m5u1zjK@^h(CZ^=Frut*WP!Nz7^3Do=A zE4D5BOrU;|eI{TQ_LYF^?dX=u)7fVN^;hgO0oS&bL)m8nIfQ*CU_`BOkFJ*gt~vxz7z7vOfg;V0*Ja1oC&=f#<}Le_T0J`c!sj?2Go@{`JI?Hl%cz`WG#^8lN#mx(sXv39Mk&Atwp z7h{_&Zdb6s1L|4W&jCKSxw+4cJe}vt;XUqi!vZN~6!vpK{-3RWKsh@5IiTLzF0(z^ z*8%nB?B@WpT$bzE*8zC|_ru`@+nD_vkVn|O?XdriTH}-Gf_yhY&c8H1nOul|BIfwlkkSnrZ z1KgHM&dez*=aUO1`MGX+S+P`!c{k?Ik;ieHc)`$0B_kk?6-hC)ShGC1>~FTy8u7fGVHs6yv@dB zzXjxKcDzk-TJ_?#nT>hg^X+)smi-v;I!o<+d*q$!&)JUw<9m4SA711>F)YYF46vqc z$$equel}hz<*YVCG35{bL zyV+j>cK#+m zM#~kJqa={OvcCex^YoUX!{qn{vMu{6V7vwUD!_H@rvSg%KiE$JxhDH4z~6VvhI?cr z_D4WHi2V^@J3GX#d8GPDyPu!ahk0GU$!Xs$`y`-#lYJ84O!i5j@#R7GLqLwo{a;u; zpUlC22*|gBWHk0eKt5sfvi|{c!c86U_MR)ih{aV;UP1=4F9m-8 zsx-9vIKLRDQR6mMgboe-Dfo_*1soBnR-^3F_UB%U3*qg1m$0 zP2d}zGlA{c4+QpMKM?rH?qwek2zO$v-2L$tm*{eLqg1njM zSYR;EvA~!-zXAu?Cp(lA@pHLQKfrS=uocg-z!08WflDvSt2Xi_i6X+_60$X`B+wbE|0K32xJ(PdiJ@%a4&T~n)z9{>X!0In#N%kc{{$?AzQXXS(^YhIx9_NkB zV2j$C_Bx+~#Jqj%Ujl2#kt^*Un>?=SRqct zuHtzheE5ndb;lzt3|3Fy=Cug8S>po$R07M@NpweRSB-e&c>R@_O#4!_nMN zhq<|*4l{Ef9nRzaIV{foayZ>4=6*SHTYKML=l(hB`MF;Xm)eN@+y&$Y+$V?exlax| z+6eso1mvvjZvsbh-x+4-elz@?`^&Hv_m^Q#?jytAHUXdaLtepsWjK)g%J3=oli}~& zPllzqpA2tvKN*hVJ~F&)`*S}TIbwbp%Kc>I*4#&io9#&MCnLAxelq8C-xs#E*X=g$ z%c9<$`?2u34Qi=;?njTek}J7CiFx(7F9}O=Uk|>r!?~}AoQ3;&uoL&U;9c%h!Oh&K zfjr`y8<4Bsp!i+;v&z;64S$dxyy3 z++RSB$$bRa(+=Q10djP%=fh5Ro{h-$ebk%SBV5-<4&u5#%+7Uv_#@ZPVHK{Q!{S^& zhre>&9PYE%xo(b}g#DLcAlJ=daodUO=Eym@P7Y_B(bp02^+@$M#f?WTCOS%39 zD=m=wZ33=mq5g*JSTJy_-1khz;PVZr=i>SjOwDyA*g6pFCU7Iyk6;(B1Hp-0_knlq zORo1Im*lz*jK%dC*uwtK^%>-KiLrhGW3qoFW#33xjq4fkx!uoo4dg0Z*MQAp;(aL0 z%=g>yC%)f?jrcwrHsSkh7{vFrFeTsDGV^^cyu$aRFitjEobU6H6R>|H$NBya{>t}v zuomCn!HDdK2vhKV46MfYF>oH=x4>q6zXGrG{R$k&`(PNJ_qlKs?`z>1-p|6typM%X z?FHVSA~)xKBs^%F@_rKeIPV+bNZv2P{JcMeDR`d;tJ$-55byg?kF+m#K=^Sn0`l_n z3*i~w|G_c5?}O>s=L62+xpY{I_kS=3KYtL`u#fjCC*+J`=9A%h}%p`6fSa4_@Nu>cRUwcMV7KJ`;B3d1^R@=YnBro&$yp zc|Qq1*a|%Vi~OhUzE*i7&+DR|p7)#ZW;t0WNG|7nC+Z~+%JgUC>IBKc>Z$lSV;B!) zzde}54%w(Y(ay7(j;Vf)_m`O8g7=m1yv@V=N#u<-0q-l3tEZEVY#ZCfF6aFv=H=jh zB^+*N@;oMTO5SI}%r;sg+#ez@=KUs2!q2mUzwmw%M*Jkl^1cuGl6}s;ddRWa&klCC zFKkElwL^WLP0e$C$Om|S4@TjAARKRFHB-*Pb9ShQ+Cw~Nhy2Kv=XpEijy(4UNANxo zPU8I`EX4amxY-`%{UCB9-Veg;JpTiu@_Bn$g7-~uncWKoAQ1Ojtr7h>^!@|?y$l3 zlD%X9vlo8X>rCZ+8(#OJePh>G$9)j$XKTxTypKcf$mfe;ftK>6UBvr4)DPN3?DK}4 z#pbsed4Grcbi36C+x+Ychw;1%i`%P_vvraPkCfcI&rZ?_qu$b)Q>w90F<$h^D{#CQ|io%e&tt$9BP+wy)89@{NX?3d>b$&iz> z6Ymc(uO<6~!&@KZYg;Zh?gLSenqKDR{UP$*BQhuN50Pg+kcW9+h#dKq416PR=fXNO z>aT1#_JKo=Z`0ZiBUK;Xv2fV<1zY(q<)~aY#dTL~TlRTI-fZ{T$$ZJ= z>? zCsY1n^W@4C_Iju69hQ7tB9zV+2ws9-v&jVZ^B-4(R<0r}W_PKp;EA#yjejT;# zP5aQ+;{G+p-`Q~N>yMn>*0l||zs=u|V)(g%p|xbq+VY+~Uq|`iaye>+9Kb)nbx{NM zhmRX(v

EFs_7%>4HX^_^2?h`q|+2h{V*gTApB8Ti+M>vz*3qgT)<7bI3OTDpYKf*E}%5s6A;jV<_H%s&i=&L zL%#edPMG&?e)d&FeTe;){mglt9sWvrwXN|^xtZN-GeH~#TTg{f|`#{u#?VVG~E6>Q&_vE&E zc%OxNN9xP@4df;ppU($lypat!shsnyJYZ}8qr7!v!m#-bH_HR;>xk<|uzw@Gz|Uoe zcOoPTGi4l^q_JGwL`G~Xf3nAH{uZjQ?=JK9kS&hMQJ>`t_D{#x+4oI0`7Vb9Bo3>m z4<|cU#rrtSi&IU0Or6F5~-6)a#y=t?icp{Cj|U z(eUzlMA;{joMc-jQO=rFR+UU+nU>3nc8XnO zH`oLAAG>aauKU}bvrp`28|_ccOKP*&BDS*aZztMC_PiarS+6sXpL2lUrv}{bgX<5- z1GWr5{{Zzmc4GpplOQKbD4W{biIi(4mK$uWB+9?o;dZ_)#Qvsuy_4*33Zt=~DePwV z+431xkH9{s7(Zb{ZEp5GMSZD#WQ%4|eS*DcBV|>+fNf`I*n{>x`>5h|>*bWc+k3f` z6R^K3#xK~$?6Zp8x~BY>`;*91*^d<7VBb;r{*=7-pPbD8qo@~S|52EQeMjLs+mroA zk?YQv85YX^Ht`GP>^8_wx{P%oTz8hwHNwPP7lI=)VBH6#0lkL?gJtZ<#S$eq1|P>vo9s;dD)i| z?)aZ<%;%;!pU*eJGd9(Hf_ zAl89ky;w3Z>;QH70dOED@Aje8C-xahCWFGbjKIFa`VL!Sd{f z2eZYN_3UjvkAZr|cz}KMVB*p; z3j5w6?_}RQ_y_ya!76-y0q$l$I@Y6Mod;%!Ay2SB9C9%C=iol}hl4Y-$+hhNhTNcz zOjcKRuP@IulP`wI(d^HL`8Rk@ALeIYHhB7ltjTlw$lX55+@EBYP#MVmK8!DoAooX- z<0H#nv1L8>Ys0+e?9T@8CXx4lkUg@>Du2lK3+0w|@|&HwUO5ZT_v3ZuZIp$N%W5|2 z3FV}AzrAcvUC?-r%ktAT8SA>tYJ==gH&kD1U)$0*Rj+L~-BnIkD|guUSBd@G@O?h( zB=dK7wt0>#NBAxy=g1p2zaY;&`xBFqod_xZrB;tHDL= zp9D{HKMiJNe|?yM=eOW+o1Xh@$OUa9`;OnW$Lzkvu zU|R0yz)?Jh14kB@J4(w8Wn_Q;e~R%2+^2v|xjzB-^WT3sX1|V44`a6tt z6aW6esr>f^p65C@%(Oz5*d~`9l+zB&NJr$WTe8?~S*8Ygg4oL5f+&$_so`s=EyvM$gGQH&13T3Nm-if+qiz|H+hri2$1LS`~ZAuf8sd; zSe5cr+v2;iL_@|#V^K8mRKPl$g%;Ev?-Ln=9SsH{=DK-l<^LGtEcIcSJX zJ5=tqt$tGuH%zAdS}^STk|$#0Y+^vb>XS0&DS57Jys&zReY8+H&LY{!1}stDeMt5^ zA}^niQT~zD?AmL}tFOzT82I~!ufO;y?l0kiTll$xF>cFdcjb}?GRIT7yfyaIFz;47 zS?DKO-}bY`x~RUcn>=BE&W)c}Tz|?Y&8r-@p#0f3E~GrAn0#W>mQcR(Mi$M4pL4w4 zyXE-#hO@Kh4Rcy9*`t80P*A2SB&*szc4!UNJD0_JCSGS1|9tWV1eD{S3mj^vTvmSl zul#gVM!79Z*nW2XJ=NRXm$U8bhsr-ak};pilh0($?{c2KZ?gx)3HyF}+TAu{IMu7! zd3JRq)oVwV!{f@6HbFe)W_GE4Zu7_2_yD`KxbjbLy`Sy#g zQ(E=EZ1^(DP3%S+rL60Aqm5Ed^@jE@8$QT&yTX34b;@geh5cfyRZ#tRd*5Dfse0BQ z@AzCjp~E#8JoJT>Rs(_yY*++XUj};WYop7mL0WJ`G^g* z1(&Jb)&6O}Z&AH$?zmw;U+?$IX!~Tu{W7V|eL%Uq-S)R~j)StSU1MVftDe=4J*)hO zJ^GLG4SV^Va`p4FwGFoIFR0$%uDPiEw~cUBIk_!%O}VaZbY1y>cK;3Ki?+-i1vM;|Vr~6M9w%hF~ z+vKapyV@F|%ERm|oA;aQ742giYM+FQ7xwe;pIs4Ad51k0NBNO$oLae?jgUq;p-r1j zxrjZVL-~QNm{+-(ZBtHp3;UYl-{Bc+Wv~sk8`i0wZM__0KiLc$RBvR*+oLwbX5OfI z&Fy4+)PAy=H+i0|xJP-gZMfIjUa?EL?}1;(mi;o~ZJF7Yc%b~zK6|7*=dt|piM(hl zKUF^b1oy9a-6`B(fQyddJ{BfAF5{h)Nlwe&XXNs;@(%aoFuy}2nV9S9$n}%SKiU5e z`IHT@DO0On-d?tm(x{%p*0%%gGJDE~*pzAgdbYEjVfWYvHt+|{FJPP75q6EeXhUs= zbh@s(?PcfNL-vJDm|pWs*mib;-C}RpNEtLghplf1+GX~X4Y4UR>bml_vz=l0*atQ+ zljaw&&Fu)g#$L3cHbZ7zSKaoq^X(z~!Y0h3`6X;SJHc+TH*BP=nxDhgw*&1md&-8` zl-YD$dHai_OkQsAscElAY&$!_Zn5?I`gQCwd&-8`l>IcXyzOjf*gf`v z4g6K}3)tp%gk57V+EAOJzpkrpd)fK+kbPkj4$%A(ww;||x7Zst(m>76Ve8w0c9}h8 zU)ltN{B>+QJHc+TH*BQA{yMh49cY)?Q#Qn=9HQ&W+s<}|-D4lvz@eI7z&5ud>>7K~ zhT06j>ALE+mz{49*%vn9FwHMv+t~?ri@jkZ4cGh}w!R%`m)TP`#HJjf>&n~Cc81+! zAK1W=nqR;+wZ1iQuFu#v`SehypT4z$bc zDH~!_j@5PLZD%{f?y(PS;5f}MV4K?!c8xt}Lu|_N{yMg^oniOb2R3kmzm9EgN7yy? zq7AhfChEHCwwIl657`$s;Uvv3VcXdWc8k4cBTd%)9JaZgVE5P;HsKV%zU^#h*h4nN zW|*q^_3c2r%$~9#Hsv(UFK;{B8Fr6-U<0RXegWIuPOw|-4I62O=I5~W?LfQCp0Xh} z?gb6g6csRiWUN+5$|LL=d(np43?aVGcC_Q{gAW=H{3zGh zi#F7z`=s$8oAax3e;YnjIh_r%KiP41ojq$~f75l1?XPyO-EFVgq5)X1$NQe9c7UC4 z_u5-FAe`o>wPkG^JKVmvZLt}{*B@b*+ava|jU7Sra@&TsuU%wc+cFU~f2`eLuh{Q4 zV6;;^%jd z-Nomhkh^nVfzHG}7o0ms{<}z~-YgSm#=Zi^&+zk3;rv~4=x$klk1V!VF0uXgDIc_@ z_baD7ARGKG^B<9Ej>#WS$+33K8RehP%2oD{tI8?3FM{uDtj+sSInpEfvn}yNd9+>g zOgZ&)&wnZF+6A`#E7cRm!8sOuorU%)KVKEOQ)+pzBc6*werz|F#<>*a2bW~A9N1?; zUYASG&MV88kcXPc_PRS)HPdpsP@(_lOnKi?DfPA{kPoDK5iDzacbS+TxsZ>x4x zjy_$En=cP}w%M%_jHRS2jg<)hpR{c1%yz zpYZcWaeaZMvg|PI10%l~DYJ}{@5f=^4E6IoM+1vZlmD|3_&JZLm$WNwRQ3Z!z4J_Y z%$DHu_^9`_YwQF28=uq1cnd*1Fnq4AHl`bp(s_NtA2O7;3@z4<%#y8Em_R-?Mqv@xavRJ(RRJP zVgpKOUS?a%_O%P`QTy5^DXHs9+n?-YyWQTlQA=rlZrjKXv47gLHe6NBPixEARyIXV zjX(TRCTJzg*zR_*J!d1d*1YWYMsMZc2FW4A*A+R=8sP0BuW`1=`LRc5a#``OpU3x|zQnIW&ul1b*u%$bXYjmNr( z^8?#r29&hh?NeLjipKlfcKqB8%um-9_apFD0{s6C%OsMolE?@}VR^Wi++AGW z7$ein!2j=jAeIqPaLEf^(D=Lq$ zXZYvM`D5kSV)*k$PCia9_vOz8>MQM)2Fly{bAtLO zo9Soeuk4GD`a=G^z<+H4{@ft{V$-C-&jWHTyCto1l&tb!8!wx3aXZ+)vPbxHhu5jc zpF23j-r~<6a*Q%E1%D2ad-3NGh6KrD<>e0*<PpEu_<3E zSFq{dD6g?MZH;%T&$O4`E02tVpKHASa-QdbU6RQK_O$(Gb0*h#3p>&7wGC=&{HSfw zO?jf-YhT(_-8Ejr4zg?QO&hC+=9RQv>;ik*Ht4B&BW;6z%I!zXnf9>#U^9-qOqD+!S=Sx?Ijy|oaPm@?d?o^*nY4X$NTHsk#?(nXcJBF*SEcGjftucvTN;4 z`)!uSxBe+3t(1Li#=n$9Z0IWGfve@%HS)0Sv|jnMZN5SIfi1sLd7(XRzu6C4HQr*o ze7Hm2*(o=_l$YT*ok(nJ#AmwSbcoGtzo;^iFU2+#J`XD`akjK63((m?I*i+ipDS54>r+M)eG7N zwzr*Wx7thggH1He*V_iRx1DLX+DrC>O*Gxt+Xl9`ooTn)OZJ0JG(*=X;dwp$`XBP| z$oVoHwxe@0v3vZqGBs{f{9`$g5BNCYx~;Wieh&Mb}JTk2X=RNymle}&civs zzrLUI+&i;7yR)-(=MMC<*CCuNGuZ17d78{_uS4Vrx!qoe$e*N_z3!0z%73>r&z6z$ zy8I@+cd(z^F51Ulk62HPy&mCrdp*LO_PT<_t;|Alr~)#hh_y;G!S z&PnIl^-)o;+Z*GCVBa11JrJ&vc_W$Y$-#1iyesGJX1~sR={GrjAM;1qDT;ZW{3`Pv zVBO^)ttFcsVs<-B8_FlL+!59%%4q3#l=WrO2sdBiHwwi7g#?m`(0$-D^p)$t|<4) z-?HIlwl9z=t}suM8Lu)okYnT-x%L{{YhS0EZqS=@_D$ydGXE{+hH|3ZC*Mk++w50S zhRT`pnEWDr@34Q643#*QBi;+6W#Gjh{w)?ds0Z-@tLLgM916d?r5qPkK8uFOw(bJGs)XuZs2j zlwOIL6C|d^WZERm&t*9qE#S?OWts>70`F!t#r(=FNH+nK%t|klZD`eOPZKW2HxW*4xNa z@{6pIf$dXeDZ6eho{zS2f-IYf^?`D!ye%D>+5TJB%EJ7wTqx6LWqp;rAyZ{%ygReJ}ckIyA4>sZP#Nyh4I{tX@(}WvRp4~HD!IU+$X0tV?9d# z_`l6rFWG{YZAk~on=)-H*5}GQvQcZ+7s%von0L$HvPWCii?^eLkH%$Ii?%y$K`KXxjXCq?~A)LeB7Dy`(37BC~lhCr?9r`_QfF=*0|lekOV{3muu27Wbt`v(qHGXr4Uua9%ny zAB~b@^E1~dKx_NcD{?>~=8(d4m+VoL`9U#yHGl?{r2AxwQp_7J0@FzpyZpUYF#nY-7d zS!z-5+B9z+8eW&ysz<*ypko@+O^xWv#&k(jdPM$}Yn!qD)vjZV$E{jR8q|s|mM`Us zHmpaqr3u>6&h6=ej&x8bTBtL9)>Vemf4WhRf9V*xN_Otg`aSta_8iFiGwCvjdCy>) zZwRd}PYq@E8%9SBrx`}jZzE}r(KJH(j%D5~^NeS%Ay3Ni39PS~M1#Yq=VZEGW}eDC zUG9`Mr?c)on?98Z<}jC;OCx2?h0NPzfkn)rGE9aqQ9t=X&Rfd5=Q7%JIejKwRxnRq zO*5{gRb;Fju#WZCo9GC+Ojg^>`Xu>Q9^J}%nQgR<94{+xXMKij5y`xI7d;~r?`Ezi zi|u7@B8SMIGG-s!Zy%xSj?!@_lx513%+b-b(s`Qn0!@8`4wmU}GXJ_oeQwjFcj$+^ zG}nDv@c|tn8$4!C@s!q<*PpBZEA^M}-!Wf$Pd`eJ56mh4qtTzJ?-$xydVgci^^*q4 z&T{TA)_d6h!#E!Fcu9xY|HH^%<_l`G?l)N!QqTLTvB6F?5$)K9>2ATs~e|W|_cTRz9A_oP9cdKZ7Ql zN&RH(O6H;wv_c|`tHbTb+PqmXhs~D-YuS8Ra6lru+~&m}rPDh0^Ou=6FxQuxH!?5VMqh5H zK09b7*-Mt&&H4-3Zx3^hy)@oFT3&|A%~7o1lHqnec06vb2WT&WA7%;}QS z!Saesos9K(?zEi@m$j3#K3#@;Fz5E9hvil;=3CM=1#@9JNpA3FJ$-80Gz}dtd-^ah zklyK-%cQ3#Wbq8lb28E;nP~gWbiaHilV)K(Wmei+ewTl;v0g4a-6*r?U=GMh)8wK* zbJI+D=s)tOT$Gpf`uXS(*`^@#H(An;xl~~~LtdA^W!55WuOa`Hi{)>bwJ7_ol4*)D zSCpZ$RB_hlNv8nj88W&A^Rbe&P9Qxa3zTARBj5c$muCH-Y*LOnX?faC_N>6XP&!v+ zel1f~Vjd`O%ly??-xfmO$UfDX=gXNjnA_B({c6!g@{F8WoAtfYQHME?TrH#JS2>_A z`z@2_AoqNU|CQnNp7=i*HXDrbc<`nyH;uW|Q`KdZjn6~BS%YcQ>G&Rt z{5uIgN5Li2=vy1Vhdjx~-NBb$bi0jzL|&7UF0^rw$bmL44?eF%uh=*^4$-^Q=N#^-1s8@GbI{0DuN1OKxlXUa$06sF??X}6lRXdQaB5p``%tJ^p@EPrb^ z9le*9v2m2BU${VT+c+5HjW+HD_O|gZaHx%Qfn(k9KR;||<167Z8EWI@kXOjxvb~L; zL;Zm)nT5G-P8uO=*|<9NYii@?U{@PI2m2SG>Fs)ZJj z=(pa^w}1s~JRQ7Wi(acsee2Of_36?!v`ar4W8*PSIXNExvT+JdjtQl3o)f&)gbr^- zod(j8gJ`*tbhk`U-hLNzax|Q8zmqsQex$L__fC#BY3cD?bWv^^kcZ~UOK;1T1(=-+ z(v0%CjFBGxY=0q_6k=XmnD(e+-xHi1I~vf3vfBjaNt0-=ZFE5a?1$(d;)4AE=Gj1l zHq#U*iXM5q}>nE{fBAMll0+bI`K9=aF_OZMB_c7-g3n&=0|eLTjm|| zlKk?H^&ubV{_nKk51K26&PSNw1sf<=~NzkqM#j=Fffk*~_oR?H)1 zR8p)5?d5Ge&IcFAOxfg*Ph4Ik&yB|ZhxTs0@IN#>c^>~e!19;q!7KEcoOqS_rp$et zxxbuqkJ)jbz9@_PkM(t*MRP~d$+ENkuYvYIb7?8NzAJKDXKW8#EaST{mzMKgnJ>%J z1DFpCq@@PazN6_~nRqPoQ8{@W^ZY4v>^C|g47Q4>+ zAer|zv-cCa@eiG7uMe!Rp${!{gs!vw8}<9Pf5TN*@%)u=b?o`>7iYA*^@F+HPa5ok z^Gne0k1Ujcxp_hw@f_>f7Tg$;EG3|0WNFc*dBH zV*QsU(QkIWL*!)pXptxyb$}+kO#9jOGth6qUHbbT&G(QVm(?FLPmu@YLwUyLdBu7v z+B~mt(Q6v`hE}loUQsV;*X4kzKha!Y=r=jruH%jN$2K1KjmT}L>u4$W-y(jrH0$9eAX^Lcvg0v&OY zCb0Pr(Ed=)v3UfLr`bFKFq6#>0Jq3-HZK5jUOUepZng9I;S4*UAKv&)H`#f?$OE#` z`*LV;<~_1=Y3BE3X!^4Bx^yYWyt_7iDwFhM?kbi7`(~ zbYlxzdH~HekcQcKC9Jo%jXSdYnHa}ocqj?Y;Z9?+({X+@B8Xe-rM`pJlH1i)ituWqK(C=JPy0th>Q-kUI|gl`Nw(5uJL$CD z^zeTA=@Q*~lV-n7H@~J?{-c+^(^%Q<2Xoz@^kOQ!@8Wi|+I-P)gADa$-YO4dV?JMq zPAo$URiiUx)?ntQa=Y{jVZEH3An(YT&Db8(oaSjk_q3wXt*KjETE9K**@3R;L=W5b z`>~j$A|AHGdiCyO&IruBRBL~GWzmX;XFei$oz2o6?BbF=aL<=RLw~|tq%yhh6 z-xdA-+Vxmr6T6-&Tp@kzdaB6tWtN-FDR0q>-)QCU^pHH@gzphp&La_>mzd5-NqgG& z8nnmDN=M1ezRV--dkNb2$@2F71i7zFV&7AchsxZIn4inmO_+O5qqP^)4tr<|`=1HR zFTP64-=n{(;d3DBy{pq#$7$gb_?(7%#j^B-?AaXO15sbrg1%}=W5!Y6FgjYco6P({ zE}6<)z|Ql>dZx(-)0tP!qRD1c_c^qm{2-^yW&Q6wnsEWmzlfe)Ml-LZ3#8jB=HBaQ zs`Yf|23m9@y}yah-9oo)ryF+DqkHI$y|kRoSAgyLu%8ATqQwu>rSjSt=51$brE~Ob zV*D?H<-4Y$XVcN_el)*b#{})qU(?tRbn92z)2>T`_L=fTQv5!Q>|xg#flK8pIWsxy z={)F2>E_8iQ-*pmf06T2Fgx4zbFto{GSHiOY&u#x1AQ+?Wn%7W*DJwtvkOtz;`C5? zdcOi~ZSyUlU(ZGKu8bea94yD${{!fELQc5GoZWu+M}6>Lx-mY!XCP0r-<{zB`#lzx zDoZEX?~=$9?Dt3OSDF5jC#oG1%q^2}!Gde~FHD{jNl2&d-^L3?>@=Yjn zw}0rQ@${Hn9LC%@9=@OB{&}RNi-T$D5c;h;ZBUb*Zb(!2q>X#ij|1q42{d3PT`cd; zVLq^wzF$W3ucUS5zjCF#C1d2`2=-61k)GT}Z|zn-NKc=lpJa~H%w6Ra`CQ&R!}dPs z=tg;7W{+mQ?0Gs%p1#OD{U+Uii@uga{O~&m9^bZw=vdjQJ@Z<5T;}V*dR1AxBl7`y zPuA$f`k{Yl+HQ1>d?gcgXFXyd?Y)q?E~U?9o@LCFq@#Fa2oOd$z~%Abk=|J6xcZFVWa5 zw8eEAag%1aO>aGGoBubm6V>FP?q{oe%4Jrhyy#5CBG zo{%e2GPm%iZ&J~;X=vMYbZ&Zjv<)5Ih3*?fod(nLa-=*Worb7g_Lq^;W3<*ck-AQz zt7MBX=7DnYWaho{TsU*yX|%H(Ih{Fn4$VK0KA%rhE~G={d3k>w>m%0FTU+U?oiuwS zJ-wSg+CvBJrSJFCyvJxCc}dnj&iYdsa)SByS?Y6+Hn>Cw$n~=F71qDV!dIEE-=ndz z(0%3>a*8}4BOb9m>oa=(IW1w=^~V0S&7EclqMPJUyKV~FzsdY|{S@Q_al33rt6hf}9^OtXq{8o8$n)pZ*$e1Txoi=0?Zve7QkrWSbzV-_%Fu$i z&NkM!M}F{Q4)muP3)4_JrzrDN*{?YBG1;*M^A1@hka?zjS&BKAT_+s3TeCbpRgvDc z>xHA9t1?X=L__7fVCKLO`pB*aj{akF(1W>Y<87)REE?CI?+~3K-`RD-vD`bmE;t-q z0`r8x!*-o!SaUS}J)UN>>olXjq9cCihE2QCZ7u+!-9JyOS+z$s0fo{j0IPPD^d>Kh?f(-7Hc4fEpz`27Xz+Zu}BTVT9a z_&o%!=|`tO!tV#jza01;3N<`~xHG`f%{2y??>egQ&|;`ZyzAN2t4IqDL0d!S?z={gJ(HV3@sLpqIT);HFa8 ze_@4Rc;4WgiFjUM>gNG*E_z3w+4a>?-~E9){-Y14$nVzV!kF@?q{AT7t2S|?Eu?b%k}cK zd?pLp`OCPS-g1WAE^kW@JHHwI0_8LrDc{OscD^(E&6P)GN;}^f^^MZS&UZ%cE1$_0 zcD^&}$7SGg=2bG~3Fa~Ks|>aCp0V6r8FGp_N@hFFyimH>`OfG+SU!`@?7U~xAIQXZ z-ZOF=IaxlEZqaP-E8okBb{;gAOMZdQl1>+yYsw#Tik9H>01Q952_)v+{$?a)bS=%L&ryChLXdayw5M>y4I9cbP}Zjq;IfbC2zlN{~7H)~{>$>0>~H5!qkdBs{ExYod?Yj5 zdDQ5)Pd=6YpIDEOS7lv0uNwWg$>jDwh24()Ei-&&y|ug|Q+{JT*?0Ot{*irtu)avn z`^9`sCj8A@M9!D{q(=^0mxm=bdBw zC(5hxlPvDT_5<>!OqQ1QTrxn`maXLgIYBOyTjgnaOMaB`(sBK1WG-1w)|Q>+069%A zlY8W8`AC*e&-G82Zg$?h?MJeQyqJ;oikWFQIaeN$&$F<-S5~^jmmZg0voY_LALT^* z9~8IyGzYz%lX~Z(59Nsb%+CwZpn|lc93wwSFZ*8=>un?_R$yKy%U5KMSBd({GIEtX zD__f?%IyCni2joEsxjY?b%UAx>^yVakH&JCTqr-t;dcHx`Yn}*q*o2ryVRl+W%t_5 zbL4(`TZYtOyT6@Rj`cbu57O-x_&{ydytt zU_FtYhmH28vX`u2=VhZ_%+AY(;qvMh=8rPe&d)}>o1K>pbIFzRfOOf;_AIio>@C;H zlQLF%?c{RXWwA)+m$J?-=C*czH*UYBo!^U%?LL?$}PoKUWVBD@5r6y7I{X-yTtYk((5wwc3JES^M5k2oi~s5 z)s|gl-D|9Wmi?|X=e$9u%LqG<9?LhqMIXzfc3wT|bMDX&^6FjY_cHVz^8|TOzLuHq zv%Rz|_JH|6xzx_b$L+X3qI2X|dHpf#747_d^y_Zt=fhFY=^gp@1+(i*I$AE1FQwBf zwg<=tvchZDi@l-Yvd>%QDbnp7b1vCKPLzk`eR=&o`)B=+j+D)8UI1*zzjDJT<}0$# zXXa_LqRkh8{$1r;IrA&)f#2v;Sr;wh0O}T^0pxrYetz`2KAooj5y=~qB z+kh+LQGa^3eZt3f51`r!s9y){D#TGE5$ow`Cu1_Ma;^%U9BoitQz2Z8=FUmv^Nj zHTz$e@8tG0te=qqHV*@~x0akEH_2x*MmD$k8qj}fdb--?Z9uMI^ESXP(mylvMw!{> zb3l7J*;UrC`5jPiBV%Pso9_Yjd2*vnla2L!a*oXhfqtPm=<%HNh|Ldy`tjWKSsvnA1wXip;_CjdZER`nt-rp3PH&$LE;LQ%`nh{*=i(v%ab;Jt9}xydt=tM`XTk z%+=)f?#vfuf*#DivZ?GZQ}$xJUvFAT4wExvw0tVh^kM&xeQDu;X&srQA9GND8Yb7t zrUO{7J&?|n+ho^4tj`-v@5*0t`w-UG*t{orJf2FIVa!crkj;aF_Ez$#{4LXuWP4#5 zC9lZJquAbDI*(@VEoYBm-Y8$lD&ee8mTzR2sjR=Vah14V(bH-3nKauhdQGmJ&3st4 zn8Q3srkl&$QVy3x=d*rr0sSL;EM)#7-4`)ek^60&C+=7168i5_T6;O2DYwa6D_AeM znkHRCSIGTqnXB78Dp+s1P4tuOx|zAX&6k4qbla%QcG^S!*~vV57xmjsQ|zVJ<^Fx@ zcZBYe^^P)+lf#cOXFX0E$jS1MY-jVO;C`K#pJbTLn}Yf}8GWAl#RYosBAs)IUbswG zU!lWn+$@%NT&Ef2SK0Um>t$}ygYvda^ni6=IsOsz3hDEh`Io%)g!zkfdCr_k&X?6* zvYzM_^_7=pz&qCK$!&7$d)BvopjYGp4SLR|rXdRj8Cv)OoG>_~r zXV|A6P7Wrm!p<5zm!QRblnO1Ko+riNzm^fIZ39pc}h@U zWb>22Te8Dh=7;j)Ip$)~H1|c?K~}bTNw9oZdFTrBV>!*{DM9;v>9BFj$k}Aw>&&}l z7Msrm?XBg0dDX@_qn^j+F@cqB9uqiCM#`Bsj|u9ppU`^GXz~~IvTXH|xzQ`SNp80J zOtAdVH}vaUI_Mo;{eeD{k^iaRM_S_(Jt-ZZng5g7zcAMQ+u#Qs^ppO! z`B6}B`kQW%y&M>ag!*+S+RVm%BfGlLYBo;_@|7gi+l`j7c~DSqCtZ^>AC=x7%-wAK zIQo5&mu%h=l3AtcS@){>&5P9@)m`Bf)zA*gPVzz0DT_ z@5&gN*5(aC-7}CrviU%eUCYpv73h7L+QyNg{bLX`)17%H{F9ZFm z+B_L>QZ~9yo|fg`VcgZ?M2@_llRM(wNbZ;po%&#W&KLUiFKwF~_NNdpy{Gg z#??0*q(7^B$K^V9UMl*3u0_4-(53C^?A3JbZaS+O#*v}_s$TSCFwXx(K2@DgTS(mx zQ-2Sfhl%!MGOs6db$K}@^Qbg5p%3jR56hsmtOwp^&B$)N65c)>?RA&y7{pD(TUAoj@ zziBn;A^Ab3t;71iUGcpf_d7**nHc9kA%9tl^WtIT8rpOn?QZ8qq5fNzDari39Gz31 zwy8*0%a&D`k4v`@=AqSTY;Bs^uFHz`SF!7N!6l8UM-#eP)^5r?NgkJfWr=2N?<+UR zC;!iO9v9aCM5eX#xsV&myVA?f??OFTj+4HvSZ^w4$g|RI2-`=?fbq;FC(uE1pFC#g zi{W-2+WBCx$_yH0=Yb(_w)4K=X*=%=R-8}U*?C{c4`la+%y}2no6>DLbD9;jv7HZw z<*L~EU~rGj6~WxX&I?0*fxII#+IeEAyV`kSu<=&fd>8$0=ZB#lVCRRy6n1_X>?fDm zd1A=!`)Sz&^x;AJ%FYu*dy^w{nVt8AeC;7UksR-L$fZ5$z|=G{J$1M9tx=#x034<|S8T#9H!J+be zPv#!I>8tbf$VEE0LBY8G!42sInY=M`uTZ+HJ6+v}{^&<9O{F2{=>&O3mbJ$f_h*Lu zE-PMSea>CF;{o;jNVj~VSwGW?e`vgTesSx2P?-AK^M&=dm%HR|+0vdjv@ew({_kSe z{g=>X^1jTql=Xq~m`uEk^;&Xy2fJ4a{d{0ozZp{at12z04EGVO%=upOY7jvyKOSB9nPCcl?^%;ndB^F=iF^ zFY_cm&%l?iY2tj44&&jG&o;yJ19$#I|DL8T|I%r4k34DXz3A*X9p59)bs4UJle+rx4X~(wy|Bt)i{=g&lc@ehBOsiy}rL(C$JB@FjC(*C2JS21HX1%;zR|AhT`kj=; z6XARjT2`1Ap6Kjo1X*L$v~psX&t$Z>L|JS^|a-!kj?5m!dQX{ZF>?V~ zMYfdvWVl={56T&qyM$(pjG946<;&GMvtAiqoZrCe_gSw=RL-Q_sBMDCIo zx-DLDC=D!iN`)c}S4b5!t4|tv{9Hfn9 z7MqU=_2;sieGf(+D;LX1d0sx3=}NGF^^$aq&Fh5aOWOBnnBL}bg4-+80`@%`d5*kh z-=C4o+xKNSTt1YsGF>&cmyliMD7ipxmuKY@`CEF~_i@}#9(hd0$TIf*9PRDpD4E^9 zhofFrc9g^99JyIW%bzm4eP74&A#y}5W|!JDy(}VU${6{teb2}8v*ZqWPCk|K>#|=K zSx&Z+!(=^woM(ykt(1QPm?Hz}6bH_~M0+j|+FzzBiSb&fFP6vTJ^4+#2eMyISxL5$ z!{kD_M{X{~<=mR!cMRN4VHqOZ$uPN89+OXHj7-s#>j{+gWT>1V7s;J6T0WD`&A6U) zGEg>?qvc9@Og@#)&AGg<43y2}V7XA9kZ+|+3of5Q7L&E)KXRg6Esx1ZGFGN-$@LYN z^<^&^E;q>2^0|!Pipyt`rDPM?PtKHE<$3u=CTz|1WRvA(OZiLsw_(2%GFE!GWj#FWWoF3-X0b@h{u| zl{aOHeyrD#!{i)!OlI%TeiP&ySz`d}TjVMEQPv&E_Hpu+3?9V#M(IA7xu?7;8xCQ; zyId&$%GN{KK0q#)&cj&mAWzAh!&$E_w@dF4toN6ZGWAH-3(CfFx4bI>x+UrE+D$O754}11IUBHPKqa;DrMkIB38eSEHOnj76A?@QOD ztPhuuWyNHyFOjchtZeAc_C4~V^i0lrFL_kHmGM2;o?Diajbyl7Esw~bGKD9XFCeSQ z_HwvfAS2}^S=5Wmcai60!W62@BeH2q)(^_e-pr-tVi_r)$ik`Euc_QCugTvs+=u<% z%Nl8!JIJZ>gG`W)?S68pJR!@cXZvXROE$~E`c%1Io{%4;Yex2KFE7X!(vgYnEo5KW zC^PHVuKe3nIJdo3*-@5ArI?KWu!bWU&yR^*{`%5E+5D$`PhC(Cdkj+U0#*nrDp-Q=ayCE z3He$UEy#Wy&*`LejlBHw=IY`cyTV;(xT&|lO zD>q9=VYX+KWn@D+TrQB?1+SDWBp}hXE{S&m0oMvFF>}H(`A%&+sl5wvfBT1FO0{-?G%^2`!G+E zE95?TMZS^o`?7ypSx5%UgwxobdM|dYvGtfI*!TwY+a=G-kJ8u1J)qsSA5 zQ2r+~*!T(51LSbIPhOUvWWFZsUsZOJVe*W8CjD)^1=b%bBjiJw*2Y_)y@8x8kICQC zvpM_u%OKfV4ws8$l)NRqTX6Yeves5C7H1BD8PsWdC9+d#&9Ps!=N=G8*w6dsND7VWq@{#-@y%KZz{4z*BmA_^G zB<#0dCQQbhRhE{0<#*}q!G0NK3E5N5@M8Nq>6Sw4m7`_xl&sg3J7hs`)~m=Ca+-{i zA7s^3>_15^k%#3qIoZbf;Bh`CV`O0)=Y#rw`9ea@!&13-YbZmIUK^&@X>dT3HrzXKo@>*t~M+7g~T0m)`@JQsOt;wlw8-~u{#m%`4!tMG#V{B6LodsfHeLq($J#g< z*rXfn*^5q+18m$3+EewXS#2Iy5K}^n3V_ewP^@GY80evgZ@l!{lapLcWrYr|g$imXOV5NgKC=+x=|gbYP&3 z$ALp+d>dzj93tDv={C*=^#?MWjjKWKB-hIrS<}YXpgltVmZfc64eE!bvyG!ct|BMO z3o^Bhr$KvbxkkQ``E7g++Iz|v>ARZs5ZOmAl$l0hoDG%>leb1Q#~VXmT__UQp6?>9 zBtzwfORRs9iytu0b}t&YTss@TgZ2Mw<8@%uT(s~p%#(@yMfx6R9+RnfT>a_;y7B|9 z`I)BpLMzC&a+F*lkIE-9{#P!SRaTH~j}gEy%{{>bo+pDILPJfx{9!^%x%|KL=KVOcAZ7!TGH39r-)ox z&XJ|;x{9_Q={X(03nLen+mhh>7V=fOA^_hTkgv&7cKt)-PSPtgK1U&!lFf25XUs(p z=cX@Z%lym<3ebG^{R7LFx9cauy+!B~St5|Ri=1GetI=_=HvGGqF&w}S2)ccPq^A1M|i{@KUjA+jom}b*yD(Lb9;q<6&FLH0&-jNumoEX~+JqplycAY!qgLZv8*zz`gagVmK^Mg>2Z|C>G3b9yE zr^Jp$$1n~8<~d0>o~4JZ{kE%P;3hn7u&uSjuIK0}YaizBIO4$V_fGC;W#jhXU>gSn zOK+g$+1g5wef|>NlKs{j7) zg8DAm?kw|jnK_#ISz&yxK)+7 zwm&1s?x#2H^@kjNhW@eFA@Y9PpW&>d*k9rAGxVbE$H;@u(I2)SBkwFqi`jmRT&Oht zuOi)5jpnue7wxXL-@?}a*Y;cFaQUz8x5%sI4%>f`ui5?!=h*%Wt9j7@w*Mkmvi%n( zw*42*mc?y9Moy5HZnpgvIl`{z0AJdE3v=533I|8h4|2Tiuc)t;_a893+Wv|9a5>xd zQ{)iaPvMs@^t0`!$N@iSLN`3W$o@%br0t)`H*EieEp7jVpKbqy54~w|+y9W;$p@pE z$J>60`ZC)OVS;hAK{$Oen{KfE4(*q1JUpCk`yH%j*B^i-9%FxlUw>migKeBW98P)S zJI2`SAAYvS4~{C0{&0z{7y7!OUj=uEcPg~QiFTZT{W8&6CD9K#!0s0;VEtD+IU1kF zeg+rXaS;wEhvyfLuI+lSYTmSbFWfKG*A1Y~w*I7v95rlvV7H7kac26xm|tAIpdAO$?rHt&Cv&v2*C%{t zj}tsw{x#eek+HK5*a+y6-=F-X0&+zigrfZ2iOB9JlOs1EcJ90`u7Y zfgZ)t4_3GP1D_{D|Hht<6}9ns3ht>x$J_fba$|cRhGpE*&&kt~#Dh+CLLE78Sz50= zja)!IeK9T%?SpK&)$ttxc77%dmk(@t7?=H{E-!e~bwl|fNmf2+#xKBn6**Pjl5Pdr?&3$cOJ{%Peev-<0FO%=J3nhNX2rJmNjQH#{&#}6 z4$$O>X_b>S@hN)tCLMK`hTNz9Qe%By$sBhw(bJP~+&~^VnYt{efvf3z``n54qSil! ziz8JoI^X&s-mW zx_l9RC41R*!qD&2ZCZ2)jzh=;X3&ZDxe|G8Ct5k~ebB|>f50!Ue&QgFJVdXbqP^_A z7~iCh3)OI3fhp|#BIvO9XZYBD=Yr?&(gyZ>6Y?56Zo)e<*Ba)YGRHP%UwfZJzx)&Y zcJUY4z)6WY=S!Am$_yaxR`jxL%)J3XdZ)?xfH`i1wvxMNsx zF@C>=yFcK1IWSK%ynn;OE$E&pG`p=o7T-JNepz@t>shAKWr^^(qhEmC4vetdfuk4WUkyB_Xqv!hvW9)5&K*LBZF}}`5cZ!AvAM!`l2muIe^{` zqXj3^z;N12E|%xyhFfee|CH8#MqkK^FPP`c0mt#aj{6a|7TXE$*!IGZjkLlh8rU7% zk9v2x*&YYvm$sd-XE$soTs98d2P=-Jt7Z8K%oF7inS3Jac_z_2a%dRyZ8>x*^JRJ5 z9v$CuMBSLyhh)b9Z;^Mo#aMLiSZ`Nnb^lG5Yu^jJ;5xO%cH z*j}`^vF9B+C82)yd?SyLKQk~l&r0WHr~Wx;rCfAbURpjMU6P-cC_r0%qE)}r)P3>z z;&v_;#OG0%+>h3ibLCx`$)D}*nrBu*wF-!Gj#4pv+u3CzTx=4UH)0%6_-;kqK{ ziePTGmi}5t8?UF{8|dLp^kP3e4!9qGF42w!@p&2fvK+7-7%V6G`I z%Pc2Z?=C}aJ4ZPjQ{{w-*iVt)$Ru|Q#pTTL@wlPhM7GR`#}9eEydy7VW<7Hj+D{&r z8?&-Lw+C+bF^<#M>53b4x7_ZD*ALoXr>A8z&=zvIjLgIORoNvk^LQB{bLV5dstmW| z7S_MS9zQtIjz6$-A8aRF*q8RT*9-Dg`N8h@Qp}g*g7v{#Y3S3eG?g#iTo}KLqWyur z&S8wbzF|9e`d?RiVl?%)<2>3=p2L0!g9qYvuDd(3h5E(Wvj@F$g|5F!pC|T@YxmDU zlVzpbmJPZ~x|W+6{W*7mZ4R?M8cWVr)08=tk$&q-C4X39ada!SupV zT6YGWF5~6F_Fz37rDtB|fAZ04WvJ^24~NrOcSpFrPiJ*;^q2utI~;3g(dujPJRuL0 zn`AtD-$6Z}Y%D$2vtCj5k!$5$>9&FWLgixlQhM9_7}h_)-pAku`ADYN%zCwMcz;8? zM;*U7vwPt2M1B&E?Sspw(roLnJswVu_VVXm=KJ93AM9t_ z2P@n5!TJtt2Mo9C$HBMlXqI^RJdE6GAhrkYx=&Zw_8~7Fi0y!vZ2RD;$uxs)4|3Oa zG}9*fdmDYboetVfr`dL+f3XVKUKlOwR$_i2GgM)&Dht`;g#OQOQ8#Q1@+j3=L7u{ zY@rGF;rUpWz~Lj;+J1%XY>zjLmGL_;yLY4)WUEfh3vSc4wtr!{oVFjqarSt^Vz%9I zp1t1TNxOgWw=8e>6S=26+Kjn+bDF9pjkf!_0N1;SqLXER`&^3pmxP7loN1q@k(b)> z7Dme&N6@c)5=T6Hoxzun=&v`l(s#OEM$0oXthf40w^a0uTfXsFY&X_(X*~6rK-;aM z9meBvK>Gk0CL^b?ep$YkiK^oMqJND>c-&y=v2@4;I$$c@I-P!)Nt?~0C+5;0YiSbO z-?5%-a^ptkL-MvvmJiPl`fZVm^D}?4_dC@6?eie~SMHUuvb=pBMEh8IMkXu7dL21i z-j*5c^B|UMBO~Nn`K}n-lNP7tcYwSn3z4h{tT;o$bu6|iA z%fLM27@qIgq>h?)+=A`pAURELx9?>M;SZr z!u56?S(wMJ9}An>bz|WbyIw5ZUYxG5>%$_Cvg^Xal6D5t#dkn>H(^9Y;0MZcd(9mC|`(w=d-P&ryK*gG!I z*h`Nu!0#LAe?^Y$i2H%;)|m##urACmKVtp&lR1i)!unucTR#l)@Q?GKLA0zL*HG_n z$1%903Z6&U%+?1FkD-y{=@EOLP;Y0)D|lip9c0HN_wh3V?y@qjJtbqeEs!u@ei z?g*^v8D}q)Y)>H+Q_h!E&Co(044C-PKX1IF^Iee;{{A>PYvC7PIX_zGKJv z`>u|jcASSF$KdgYdn4$axb1Xx#Kdic}RS${Ke3M*GeQw4fb_ zk)OqFr>kR^9cPgv?KlUW188D<|3^L*x81IeCw5#yc2AD&flKXs$I&E?s|o0gM0B4U zb@HNx?RyFOMW&|?)! zApa+S+WkX*mYB9mLO;vecE8b{z=M5spuNpUgTeL zsSooSAHHo&UF>y^ zT-09Y(9b@n!SePw4eqtiX>g1k@8EUYF8IifdvLZL58&Cnxc@M~K8L|!vZ);>kgv+t zMVS}b=N;5{+3^zgx9x-@?RWuC+2B1d#(x}+*?ZO2X2$Jy};7V*IG1=bHn zdxOM|j`E$&r-l4iCg06GZ>U#X-Pz{NLVK<#eBXpi`}o8;xd_HnAy3bM|3hG=esupn zy0sX-&sqO|G{tHfEQ{`7zPFPewQ&aM|D+2In@tbQp+8p9KYQsX8()C_uPge+`Drxm z*1|t7-};H?6YZ^j)2B)BI3T}IN{64q{)IgEG|d-HJ zI-F>aV@Eef$q<^QCQW5I*2&>h9Xcg;q_@X6gS%sjnFyc%GkM3EsuZ>#d3G;atpT2YjfzM^= z_f5{ZkN*LYZ^#Qzn5%uDKNDj=Kzsd+)H&EcF5jz5H|)Xwi}rMT=?l5;Ec20b^l~)z zPg{?D?uQM#;CKO7%kGB*;_}nywAf2JPR@JJyyP>j=v*SM|0OSax-^ZMLGR9_IkJ_E z>vzuf!#qxoytd!L&GLpFUy!@n{s&jueg`+$eg_-aeh0m5KZ9N6QQ5=xE7UK_7~6l4 zv)O(FAJ~2aFW7zqZ`*zY%iI0}x7q#zy={Mi4{U#dVYa_OU)x_`FWX<>8QWiAHQQfc zYTG|x0oy-dHhcczMtlC@KU3)^xz6?j)bHB!51m`mmG=B2Kb6<*`A4o$)<4eGmFZ6T zt{QWj5IR^+l&>4&dB*awvXedU$X)FDhI{2md)|@1*z*pn+4BwO%eD5rBX6+h9oDet z9sZA|y9}#h>!ScZAc%wtm|%BdH+EdRyRa~>h27oVdTp=W-Hn0WirtAASM1hzE!O}2 z^n2ExIOojlnY|~^L#}stjq4r8<@$!t&0wx~5&(3dbok(!$%w+_6w4WIbC8G$KiA^ z^sUTy0Q$N(YoE%zQS#T2z}WKS!)2pX+>f|8{mh^=%F8p!h3T+>bdCzRj=WS5_ zp(*y?@UL$2&p~`nMO=T%kM9Sw9YSvAI6fJW;Wz#cIGVo$-sO0(&0F)Gm78C}F@0g& zpUve9NAq{W?=f;#VvLXM_CaPig7VUilgtm>2V86V`768lVS7M%27h^q<4?o(^iqy{ zC0oCdx#D9vVR+_*@N#j1G5*J(e6h~WFDn#~8~A%tqhHD2155GuKzIHQ zxQ)L9CgAUYEBHI$-F9+2{|6em=_TC%4(mk99iL^;7rDah{#AL5dE}3BjJd(Vds{G{ z>#lOLr~Kn31NnO~yaRs+^y2S;#aN%SqTciVb~u2!rLU7K5Z@CPVY>!j)xmOv9ogQ% zz!x$v>q#pQ=aQM1?K!f~McJ$a=7YSP`%xIh=dfX|oR}}1;)(ACyS?*wT-wET`qB|z z&Ja4%-5E`n_&Aej@&wLI+R5E%;fem`HWz0%-5b~0>J4#k!tXM$rH|9Fyd3@X@LRQ!ySq9!>&uygWzl+Yj<@sX0=_@I6M*jzx6Q-vg+~`k&v1NiWbcL;f3=JA zJR8P?tLn%;4^R)0dp(n>8)3X3fr%)|NI494?xhWMlXf+<3fM|e8#`F|xah}qrW zDNc)fJ8L)|Y{*>L-#I};J)GD49|Y*13hNJsm~~QMKFG_=Y?GCXvzZy4NGHrz#k8=+~5;F z*9hx1$MD+NF6oH4&c8I!%^A&p9?X*t)4?}6<-%Grw7={-P~J2Ty}^7jepj}G@E|`2 zKKmqH_`D?YZhlVOIL+pM!V~)#~C#CN>>Bs+d!SD@yo&#?A zPwwIWuOR!hz~>b9cAC)#9!|2pa@2Tvdy?EXS^hOe22YhP)8tEY$SUk#F`o>p<)pRJ zWt}{5KzbaK5#h4g5&7|$oPI(+Jt?PLki{>`U03AF8?xYCS^vKDcp^id%4ZI)Z{mB6 zjUz|!{f)?LtI5yR<@lO%wOOgIa+#_Kr?#EEi;oMNHH`s;iE85)&=lX&fC&;blbq=5C?zpvt1rs>k z_sh7)WZ@@CV#^D6$99C_Gp@>08?d~PI~|naTu;bZ4$HO?(wFN6uET>GBx4Aqp-ot75y)fPk`Oi#wb(X9>M`m3h=kJ!O&dZoO zSWcM!TvHj{Le6b1Pw+S%!%qyA-T6O6$bS6aALx=q_DLcA(#T5bWmYa%+$(*Ye#Cj% zKJv2}+)sJIP+4!B?A!p$8RPFYy<4IDhr2U^)4?koA5P@>u<215&uBG^#;l_%)5=0=PeG7oo@39dF`Ss$K?><FIaJ)JWhWZY_4&d8?*%7aTWJ#xJq7$0^kB)^)y z3Mmu5_W;T)eEzQ%<(8 zAk!4bc|DBZshZqbM?N1U+YOPPBV_WCGO|q3*y;Q$$l;ab<7>gOs6J((ehmmEFY9-8EdYU?bk_<^>X1hnRth+ds1$VhvkXsD<+fe1LQS7oR33! znN+grIeE{l&gaN6yb{mj!L-+9vwB$m$al?@&6L|Vm)D2NR3qflk@CnmIefhIxh)$$ zkgLs_@0DMBVSV9qa`HYQc!$gRhKuu{BbG1x%KZ~u^cnjTc%mzo7tGsJ9`7ro`pYo` zWN{wfV7wvcW!K+w>mT_~CM-7$FStqG*(+nrI5+ag4j-Q#%Ms%x&mmWvMT3+h&Cs06 zPeNt!HgYEGJEm{J`!QkGU9z{iXt(m*J+cuZcFz&a@Ygu{ZQVGlJCvxAC*s-lfEkF`YtP&iGC<| z{wZ7hlIecSY`nh?pI_PRV2&}fm(lPAqva-E@5T7uGvqAZ|BW2Q>-aE7eAzR({MJ}z z<9&JKZx<~SC`{!TQ+l#Ql2?l zzBQvJD5sqvSIw3Q=ExNDWU@ta*a}%`rOdNRmNWaAfnBh@K5%u$nV-$jFqL02OLSFU zXC~{We6)uw(o=3TbM#VPVV*WC^j3L=gxD|ObDx{*eq+CjT#)_R?XFHE9*4l)<`?#F zkstGT1TN(92pr1e5txO?Au#iFnVbDy+Ta3_N~-hg{IVf?s*u z1~2fq4Ho9{8k}G@uc7?O463Dk#;jFa`HShw<2FpcY>0eij^=R*%3XO}0*CUr1fJn> z8=S`DHh7-LDRACAd5_0w$OU(w%3x9nraxvKp9y{!31 z{&7Kn4fBa&KMt04lXK(B@*eV_xg(zP?qsqpk7F>M!{Zp(C0K4OD+`pD-A2gm=JV0Y zqsGXmX7RDg2{xd;#rztXgUsdT71P6CF&IdUyk4G=NIzP|LCEQMt|6_SrLZ@PXcru`2el|z+R(aw+a)IgAS9!kq(Ol6_<-z^sI`g|(Wq``}nYjll&oyJr?}JqS z_h5O#956)rwmEsIa*tthpP6~M@;_$a2;~9hO|#fYm5(!TnmI#+w|sHGjNK^$C=N~ zj#E{B(=0Mgd7^pS44$s?`Q~?X{0x=9Hw(>D-e+c>ZPS_Y{!t!p-Zrz(QTaggteI`D zO>e$33(Qmb4D*#)WxmQ+nSl$G`$x7vYX7W|a9nCXl@M@K>GriU*4=`_=Ro2>grq?=~pLxd2zFy^H zqUF;I$zr$fd>3U`^Qf8UlFDb87tIWpRo>TpXBNC-^D&Q@*{`a6s(IQh6RGmi<~1|L zHI=tC|20!yS9ypz$IN&`&P0rUbM<9n8VD=ruRz?Z)pB& zMwz)^X?PcNyP52@%3GM%%))O}KFj=SR{c-q5oV&d%6-kk8*#n}?cL#}I9`D{mdX8Q z`Q^&vx}Y7#@E2?+)8c&1KpCeQwkzaC=2`QT=@p{k&CD6*Q}dk}x4FhEYECi3&BQG< ze4x43d~K#`so}-Vrsg*DrJ1;u#w%uyF;AP<%}-{7)*63?dCW{6s`9dCO|!ij-bTYC z&1mzp8K)0%r9p8cA9S)vxhm+ zmShzOz1hoLWqMuk)aM%`n+>xRvvI2g+NIl#@rvXJgE{vdO&IeUxB z+ijKYx5?#Z+3m`Q%v*bun;w@@P4Rm$-_Pa-?x&Dzaz6w+nK#TN-2b3Fqq&g#8|04M zpTPd+IMa>$2b3o=TXVZazF@vI<8pgLc@i@jw;$xpW?8egd6wG;hL>jjhc(USW*2k1 zxx_5U?E>SMH`kcE&79m`Fub@~)qG}tG~;l)!Fc{=9M*egGo3loT*G>f;k(Tf<~8%1 z8IScC;|($kvi>2LH|v_eqEud$^%BG1{@>TiAKu76o;Z%g@J>l&juvuFA31ZN?7T{j z;{6*KzvmYj#N$w8ch+~9*vw#-H|v_+%%SEI^Md)wOm$fE3o?tDRm@K2Y;(PN&-`Fk zKBD=Angh)V<~;Mb`O=JYRMQnRhnVxtTc+PJjhD#`F$bAv&D*A1gvL*9W-$wyf0^~n zzs(}YHC+dDsd?CpG@qF7O_vjz&eu$1<~LiJz0Hm05%ZFn=A`D+&}?T$norF4rpqaf z-^l!Fra!Inyk=>$l{wbjW5zwB@iUo2%oXNCGvKVot8KP4yP8AH$>u`ykr{AK)0Z;a zn!U`C=3?`@`P1}1ujzx#I%Yd_fO*PH!{aJ!FHOy^=JU?zKcc+M02ywM<#le9e=%=w zQyy|q);uJ$`J&&6@uvC7o904)<>HCtdA^qpJ92_aDQ4jpcrxS4AGp>*erN8`*KDmCus-{*iag1@o299hP5tUKP`~55sv( z*efZnJHYHsW&WPBXK(4o`@%4MT|!*{h3Nxjs)4u;i9DU}F@za;-VNS1!+G5ixdyK{ z!iQ!bUT;M9;`K(j$lU)5nPD@2UzmgCeqK&7n#Ie>JebqD zIEB~`g1Ps~{s-k-cYJ@8Z{hV5_;C!rC#=iq*5bURS@%7LBX?rIYN3y_gY$z2_Q}e; z9}4;4Njd+NOvmjH<+sfK`%wRpv+({kPS5QG_BxE^0&{Q2?|?IR%6z-z0Ah%yQHZ(BSz&0}dXpH|No>R|!%6=Pi0rt~iLwbfPyBI{v&K_g_Ni`)~X%m_Gx)KU|$vUJH`*N6Hq_s3#cyFaHk$w#$O~!%Cdb zg*Z+c_G?G_JEhHd?9U=MG560xuJ7igm@NmIZ~gH5QT}rSmM8qSQHJD1y+EFpOMaV= z&qF@EKn~a?OYW0-AIK?Y;_u3d-EiLmri)ic{u>Y5IdU>j`N&V+@RudCNv|Mzi`NS< zehjYsJhWWRFg z0r|vyx4Llb`1RJvGP{Fg^I6vaa=2fD^&U<%YqOpsk77NCYxrCh+`xJcAM-vYScdf) zE;ci=ej|U6gL)0$)s{y#p*=(1&3X>E@xCP(&3X(SUeAKXSdZbJQ*t8fGxA;5XV{bV z8D3?5hPzpx;Z4?Oc!KpAUSWNP8(E)WqCC>Kj;w4BGxwU&rYoOk#dPoa{4Gq~Nrst= z&HHA)&Klm@oM9d{-zF;vTHO9np1ztaYrf_7i1J?C4q-xW zhj6o5i`yacZ*wuXN95An9$^V?hj4?LZ;5hUZkH%O%k2^t<@N}#n0dHeBLCoa3IFBx z2orKUgp19DCzZFSMEys3Q*M`V4Yx}eH-{{0b};9er_FC>Ha>rh>3VScg)_|8W_fPM zD335da(hPZ$n6)F?j#>``$hiB?H8`$_6tWWkju;*+>TMc&1}6_`8T&~ln>$d41b&d z#bA3zPXA8UFh`i1%*UqxdyQAt9G|>M?DTuhXfq%{<+-_^!2GXZKjBi^*V)AV!=U(1 zf`4R~dDkpGU**0_Wt=s#+VLc@(+x7C6DEz#HT-3x02#I#?JVYh!OXz@5b_7}C-+Cl z1#`=iv$4NH4l|dUvlgrTmYMCSa-U-|!wGqp`z=hL@u4ii=cSNie#^IiN@!^2BWS zVbKcm7WbRTeK*N}Hp>%RWm4YHfZ@@+kAd>O1sKftEWr8Zw@dkB^RX*3lKWW<508}5 z=7(#_x30@Jw`7ak@`d^Bu5!8ivgiZ(&qH~D`)$tuiQNB9`h1sH<6!@U;c4AuDDPWE zo@svJ{vCOTw@m0GHzkqJ&3(MT7328?${2G2GRmc9!c5BbO2}qS;(7wk9T2J@+h@*h8W zFQtr|O3pPS(km}yyMgKZvfY4ND#_|qWEV4ARprL!JadB?VFuOKct^~r#>#H3rGIDn zw2MsKQZ`mJ+fRJ{+7Nk$_mv}mY%53oEq9p7J1Ea$JB#rO50#U7|2gtj(}nFX zvfn8Aat<2B%82NN6xq;FnbC?UvKW4T18s4&jOy5M7GPjtXO;tX-ne=QS_qUc| zq4I%QwVm=}bHCZBgUUB`lnpw`?&cBmt~sZ(h959nbWt89n8Dt$zCdtHV^bxp4~?d-Y0W%|Bva59gbAv27rlr&b?<1&v~m+$4p@D%msezR!<d48=t!~PTI_ubreU->xuDJWm@R<5dx<$`>K z^$R{_{ekYSWa_c<>lvBovdsBJjx$$v!G0CfHS8_>nBjetzxI_`rpUm#GTp{Rj_U`! zuVb?uT?@+t`3#pMtk2~KKbf<+{E%~V`N7j>D3>Ghz@{=|Yk6rdmIuoH7R%rN%12A& z@ilVh7TI>IJg{4O?v<|lWaxgG@POQFRywF0?~vST)(KZ${$5V}Bz@V>#rMkmpFC%V zSHp5ed1G+nA%x1N{GDl=nF!KcAJ0n+3;~r&}dEt&<(L$PMOtt}_Q5nhiwIH|2 zBz<^27r7#zmx06h95jsnBJc5eX5_KI<)g;fE|A}u;e3u6dBj#3v`xO?dtgw0jqibh zmtV=v-l!MI0|R8)Suz)|523so&qKijW@7&DIC2VJCxThnuZE%QN5eA}(f@>(M#-7{ zA8h1(CDBg68Kq>8(sDo1 z%l9SZ?UJ%WB^g*%_G=-(nB{oB4D)m2`7hYQoa~!FHvcpeRaef`Sr#%on#a1RJZP+3 zW0vK4D$F-=3fU)>^ym2|lovC@%p}=VUcZg(X0}?c{1?v$VY&wg%N!xwpO#z9 z;e3vlpMPFvfAI5F+4a60{y^3bC=@&Vw%M5H5iow~6taiekmnCjzQBy(`FiB0JdXf}@%#ZS z$@2tomFdajeB{CAYaYKN_n9ZJ@ccP)=yEykg6wfo=DQ>xnL95l54a+y+>+yO+ju;V z$Ncu*lMU}nPd*Qf@{?vjl(KuY9L?u}G5qlx8S+-9`XFbSoj)pjI_SS({BQAOMNc`| zTx8D7rt;J|)f8JI}6=l{f`d;!l_z?e?5`ag1jPtn-&-G9mRW_GrV*W)_e1W=`^cad?+1fj*e`>>*`C6??4QBLyblVN;QNAL zOFrib19`s({LbI84DWG?!uN#L-$-|UPvlYjo-luZd14#phkVnF+^+oG{D;>wFg%L) z=T3;@_-{!bYc+GR8Ic}Rw}1F#9U=&`b*{2%?Q&aEq))SPt5m9!85#n2X5Jc z&pqVjd>@V93y1Rl8rYBTH-ZWHej~V@&&$GyiSn)4X0q~AK0k}$JEqBp(`D35*^>7g zVfZ@pyXnv8Yf(Od{S3H__mRN@i)6ROviDG|2b6aiDZh@De&c01-nWF|^C!vke4h~V z6uw6YmY6Mnn-lq7A(UU8Cy&jSm-+q{lqXs$dz$r@DVJL=ubQVHD;J5DUtgJgpCRV+ z&=vg{SfiDkKS);Q`!i9VGdcPxFkVVoHm!V`P2MXiJC>5YO3NW-jNHP{eTVmo+-GW^#itHy?_b-kuj_f$T9!QJgf)E z)67|{56EtnqsL33-C`3CEe)Un;*eXT4M2=!^X!#><#ZdJU5uN62+!W$%CF zt*x^0cG+u(thQ5rFunFGzc=R{Q1&_`i-*h1hh@?u@`ZWmsPffgR=xxKXME2rJLP2a zl=+PHk;7RJVc!|@GV2}kNAoWCW5}af&)_W9FPMh)3MS+G%%JZQxs&w=xhCrk?815j zck;buun_ABtjziVubAUmFOYMxUchgx7w|9E3s{x)0v7*)^$T6OT_%j@%;b3#7|G** zScu2}a2(&00R!2d!#-TEaH-jY>lHcqE9v%8j{7MOaXZKG^gNFOJ2aCI%*G+gcU#E9 zE#B**1Y zb07O}C=cNIHkgIy%iuDz3)d%dk3aGv`(?*#CtSk!uEVe^(*LT=7AdFkeQy|^ zobP#qvrJ#U=M8y^=}}aQ3@$XL)6WY_}tDX5};H;w;KH%(>Z>znL?Flz*FDaw;D;3*=JHl~3L? zzvNfWUQkvww-r&oX(nes72mIl8NhxFavd{U3FRnrZb=)T{aTDykNsNMoc&t(H~Y1) zOnKSW%ur2vw%MY(a(6R9E#+C}q}s~E>dH#>ESp&yD)((9KbUEFz7d~)-3;XOBFJ-0 zzh=t4%rAVeH-=|zA#=5smCd&8lqZmf7n zITn2W%U&{+&$A%s>SM#%UqIeqhO*y)9Ebe|c$)nNm}#=i!F~hs$NMrHuTLO%`zZUm zqP<1VlUD9wzY}>C`~B6XYh6?MLi36ld|l-~ZpcA5rR!}O$@d0g z{vHG68s5i@JTf27Bf|WAuQ-n%Hujj+}<~Ux@M^4G>_;9m%lGpK()AKq${N-IR z);d0No#`51dF%W_vBR_QxC!GoHIuRb%;|X?#d7weVZ8OSF#FTUEzK#sE`$8U^xC1^ zp3j${e73oR$6?43?1#fKJPv~uc^n4k^L?4H3g4Fr8wBEi3}D+r@(-V{neXSc{)F}% zW-W~UIV^n-`&YPa4)#|tnENrfmi@yCF3#{nGAa8N$h)4PeTSFKBM#21Am8A7z~CId zHyG|eD|elfjVs~vP<|pzj_Dzjt&`CkW!PrPzvm{r z*OcEA_Fz92o;@!c-N)}m9`it+d@664QKri?l^10{7vq03M}1SCWiB-@n~UpVd0_lu zTpsY$H<|Od4CiqL%G>Zb0uJGOncz3RKMk(sa)Z6N+~8a;H`txa4KC$-)8J0NHx2gX zd(+_Y&vJNqEHC5%73EkiU*x0R~A73<#TEz?lJnc(=A`EFAiT)$ z2e)uOa5v`zr*l4V1?K}3JeN&5ALPm0|IhGpda(Y%qfrE~gHXE`3iJXT0PZ+>{Cp=|7VgD03Is2V(Is2RNv>BKEP2^&xUkT+g>|dh1 z2>X|?Ec=(R8vB>90sEIQH~W>a5c`AhZ!;HU{!X`ESl@7MZ#nCgEXeH?! zd%up4b2s*W9Umtj>p99-oB3kz-|=y(mBZ(u+>_fM4CnaO{hi?)4<O8W z`_U*b$$m4OV0L7G89C;b{KWn;@(?b6Sc%u+in%)vc%BaqmAI^^#JE^x(@hXcD9G`6VGqu$NdLCBrL_I*>T}N)niR}itYHrzt&%q=A;d}Ps{5NvbJFE}nUwpn2mRKY^@V*h`r2oop zW)ePcjPn2ZJQHkpQf_j=c}e8uypIHK=Kny#f_LQ8yD}f2PeS>_-}3DrS=j~a5#=+@ z-`$i4@qQ4LZ{m7}U4P0~W?gQVD33DBr^Wg}-jG%9E5ke8c50a|(~oP~P)jxr5g|k!!Gi+y{xXKak^7>)aCzMB}(D- zXP6Gpr(?X*<}mZH>F|6yhnvI9!=}UY>l|(lGcWOcJIZ}|z8%K!d^^m;^X;(h*Fv#& z{was?{5r}Ho6ZO2Ex%=Hf7};=;WJoI-nlq`Z%z{HICG78%6wtQ+oJKZnjbDJkGUf6 zM#`(a9}@Ge#rq+lYh%jAp98`0Df>~s;6J>d9qu#Tc^~gj{J${IufsPy?uDtieZgDi*mKIsxqYGh z54SJq=8NwEvzSfIt!AW|*-ztDGe??R%#!{Z-pX8RMwkt_9piJ3*Ot@k$Z&4QC_lpO z7ydA7b2~=f&+~;aC{#8xCzx^DsJxIl#!TE+<#o*s=6~jAo>#%-sgYoXkY36maYhJ7$3~$8k170^@_+dLiZpZBfw&!{~?CF$Z zKMhuWhV~fFG7q_|dgMi5Y3Sg{VAlTiMQZ+9|g(7x4ezFn#)HIp!hOEAkI>Gw+KPRemwkep7B_X8EDq-JI>9-e5kD%@1*u^SjA0<|Xq; zT$S(gkV`6He}L%=u)hRbR+hKS%Ip`Ryg1t_cxJDRw@(f!h5Cu|GBxEg)3cUxM>Ena zTwCS;&MOo<-3|61Fnx{%vN8J+$QOc8-{GsPMPp5IO;)`w2i}nDZ^}EjWX?OX*j@SR zzD)5@dOnf$Udqwt4)ekP%U@~uY18Ai@?YjibI3cDzxgB&e3nIi$YQ^xZ=&GX-*GdE z9GpyU2#}*v%U@|_@-nhS6&b&(d~a5*p**aXOj=JiH2c(7PSshyF{^|r7wRs@n5lax zpD@FED(4(4pG=j@X3OpKZ1@7XlE)iZUm4fQBo|~C)BTq6O!LBsW$6ZzLu zx#*e9@LV2zA(KSQjjv>;H&*^mR(~%$eUPEwWRCCh&2KsIkIdqV^G*2vljF!I?(&m| z{1H!H^O6I7WN3VOFQLrpCwKYF8i{1d#4=YBnK`N4WmZqFJj{F-puC>f7x2C6rjUtJ z$z$f7)XEWQY`nDcFx!Eie$G3dH-*Wv1;o0R{d458yeH$m7c=@P_ERV?&ixoHn+MxH>>B%?vUpD8OTn?Z z8b7~*hjW|nAA^Z&%H}+ehkVtnQAasRJ6Yd+%l}cqc-8p7bnwbMS?9g%@lpEof66fY z6`wDH!@ru}WZCa>(hqs?myGY=_hbB-734ggmqTvO|D}VgYsfzQe>&vEJiiAI)|a2m zYy2NZl&_sGi_Me`c^x0+#pcMGydHpje3$IBSLWR(;~te0&D|x@9%1}f=JHa?4$mi| z{4xK(5%z2(y&KD|ypDkKdd=jamhu(vqeOY@E;1%ecH;E~lqVV@_p$$qoFRow%l<3! zBeQHi<#*=a?7w38AM+f~gCV~){n;-=KF#a2um}6M@U=Oti}FS@gx6^?JR|$Pu)4Y4 ztUN&F3(Q;Nl~YZS{dk;)>HampvK~fxJ7ah~3(n#B5SWbH56tbLKES`~$oHXg8^15g z^RiuqRr{b_gmL-*YcMy@7r-_H<&67s$N+2)D32K|?@yK^*WtJcJ)+ehwNFDGn}NjJ-OTjZ9VGO-KVRm^{SL0PS#eAGlfX)Yi0ygkN?=6(XE z;c~g@>V$K-z~LMYTXVm$+SmDH)~=4_f}EzV+*(gwHvgo>c7)*xvdXX=vS=PzFRwgT zQl67&@McpS=M{B#QijOV<_hza zS+%)_cQuEbOU%orM+=RY*$gu$oBPd`Ep5D3a;~|~JYZ&Ot>J~u%H}Tfni*w&GrdDK z-9$5}jdESy_mAIOx1DTj?lGgyi1r%($xQjT@(}YnpBun@K6a7$!{iS0i!2~<$HTko{aC|g~QBACzOAizIA8NUBqTwgVtn7&-EDDTPj0JC%X z!*k{ct_S2YTn}&>mnTfg$rU2 zMgBhc$Slt1FOX}PEzQg3N&Zd@e_`h1?`h@flrSrqFU*C=WAlnG^W?Q6A3U3y<;r)9`}%+pNmvfbx}Q7cLLv zm*yw466*`fx0-XfoRD9eU(BRjJ}BQ|hMO_w4|6o@2gbW;J~2O-zs=mNKNv6A?9Ao) z$lDoWPBRag_sqfE4`I9(T;8y|xroabxjdIIOx#gsHXE3Kn`6y+=4tbe`Q7yCr1_*a zL(Hz`aC3>d&5SUwn;BV;@x2O}mCPpQM)R^coBIunAI|**yli^09w3)9XPA4<0M-u- zFUa}W)-%tD1XY& zhx7UQFg^FT@C@5G*pT}hIMDppJZ7F?J;d;vW-ym4@^jWJIEKpwy7GI&uB-=ern%d^ zV{T%7!0>JSo=JS2^ZcIhfmwuhad$TJd&6e@-taotKkUHo1-F`uxm=KkbN=wO*^KiU z7}xp9`M_a715{=yv1_5^t|zaRX>`VRZEp2G*MM=(9>4=i9-FdLa2 z%|Yf@^A+nkrt86a4mX*L|5IMib{6IL*v`VP{C#je>nA*DUNj$>A53@FUyRqp?8o*5 zc{bY%n1}lbIEC-qf0=jXD4m7kJJablT-T=S;yH`xeLrV8z3uL-r5D|t&2+t+ zvy+x}bN0uUdpbvGC)_Vi`z3JBQ?EGARqF2L+@kwEoCmakyYq~0@OEC&w(*^Jv}8Qz z3!UKM{GwgmoH!exZyd*yj`VX9Qm=SU5<1!4NkPltc@A0}_vzCg@tvGBwVRWl?(uVq z#tz4Q7&Mu`^A~-I>+p2Ehf|wQb9WljrQS{mou1GMr72yV4m7TZ)0I|2yF_1Me@e^X z{0Y5;`xj||pEH?yc{(%cZ!c#a-H!K@(@32zH zyDW!Zk)DyV`E_~C47;K1a!dZcBRkxasqf1&kK~jn**#jWb#T2E-=iu2rx|{5mo?(b z=jmnf401;uxv0MU)<_06mTUODIp%Y~9LM`hkr$dZcwZ=TTho>2E0I&0gZaD=^4ZOD z4euL8&cO4GFxVW^K>5jDS@Vh9_EZ+*eLfifBi}y*&v(XsPp}G~+kw4!A0ZrL4&nWT z$kWVmysr>>zBz;U7b34Pe`Lh@9^_n&i^O`ViTv11HVl=Yr^qBnSIiK0*nQ}VbM~d-}nsFSo-^_g961>jmH{mV*pE*3k z_hG>#doZ1wud{a_EaEuB!li!z>Id@Z!kJ@jSu0ztgSTdnwclYm=cr7d63ZFm*U2LL z^p^K8;Cdd)a~;Ec_qaQ=m*aEc)~MvMu67BC^G zc6rDw6r{Y$+{E*H7_WRj*(kq^G*j~WG=|?SCJPmpbIppSl{c7S4V0VlJy4i#f2eHS zMqW2P+bUP+AZK-!y}HVv?pEGYZs=|0edHwbty#XW$`_hGeEt%jpLd|_J4kjOBImD= z3;7;1j8~7>tKr5YGKTlZA+O{4XjqHy--O-FXQspV9HBg|86Kvb=yLwp@;H1CCx!>y zlc5h}XTC=h32jvI4Ua+D-=7w{6C~?37n6` z=TtnG#Bu$c(7E0U-w)0@iu2nr4c|NV)yr9Z81)W5I)dK~(|5yru3(y)7$0^uoAEt^ z$e+!Lb(H;@%2Vdn5aqlrWa9R+t2z4&J|FYhb3q=zC<{E6#m(xb-&>U*iIEGx%4@&n zy0}=bnBPwGuvs#m$~V@Q7aPltt!2hgxxI~C^tWu?N#5xp6Y)Kfn7_*)=|56FnkP3b zkiQnoRsYJSE9CrDa`1Y2dV@@LL7w1y4l(~te9s|l!S_$X+1=%yp7N7@ARCx}5?Z;hbiJ3v zam|MF2z>4Vp5lAx;ML;t6yFzzyoK+DgHK*y{4svcPjm2p%JnW{|AX=nUtC{-oBiY$ zGs0iFO(K~wiL5*i?Jvep%=;eU?;mJa;N@t{_e5ML?5$jV2*Z&Fy+U5(;mnC`2R)qq z!_n>|AN_&y5FCeB#qWSub7TH+aZ~&bSS%lY2YkB{zXNXAExVqOF(>8hbJF4SDi|;Q zWx3Uyd{wz&q&$C1Cc7gC@V*{Q*ZQqo$md;x7 z-(606{>1M)ivL&JgWm_Qti$q#U)IYaXXSjZ2bA|Jjo%NWo61bQPYHQpOF6!id_7#Q z;PZtTo@}I?ngq)W`9NWL=7>BNA;0oDL=6Ai6~7P0=Y5GV3GYjUUHSY1EXC`=umPXP zhI{#(HQdks8l0H~>mRnwE;pM&eC`D0tIQ<4{~mdidDk4w`x;Tcrm*~Jh894wW zCK&Iz8N>b|@^|(Np&R>u@J>0|pqlJwdRJF|S5wxiCEuDAdH*1$?`)Rg{e#Fk>dV%A zP6hctvrc2>L``H?-d~8}wav}E&k*@VOPRWztYjwS^ngmFvdHm%RT6({1=D$A6anzsS3$EAIosc>RCK zYCq)!-WP=O+b+0|1_tteAQhiT9Zx|1?WKP)_hh zCi*V_{wag_oIl2o%i~x0b%pfhdx?>=n&UPouL+kGPs@(xWHa2H%J&#!`igvyF?>-0 z?K5=ceV#Br-**Zp^Z6C{$E?lwiz2&}k-zx=JIJs3dqGwztrQ?JTTs z4lrx7-9>p(w!5%bL+LbD0I$MzT2Wcv$$vHgWlUdd%Ka;FQnGnAtP8*4T5gc-#46~lX*2hB8m z4+qMhv)zUD+3vzSY+CKKBVj8=&67rM$luK8loW?#lXn?#j*GImhSn zU`C$jgzjgs-N4uEZ^9IL0%M(45cLtc5$h!!%>6xl$$ljKxLrPDKN9&X&jZ4xtf#Oh z+c&r<5X%G3%`97Iku6y-QGU)W#`=i7&UEGT$;j(@zaTu#dJ0$ac^7z!^%8bweT1o5 zA7R$gG9T+Da&gv6n5ewG$NGnSk)DTjwfo9FTwll;xqhG@*AJ}7 z^#adxy})U8u$L2pa6!`wIP)eC3znseZY*8M-=d9t@yK+01Bk~J#GW#LOk?e=Sdpu5r zgM+bN;bgYM@Zf8?{<9p$=k!pXlF!k?1EmYa8dO%MEhigRkPC;(6Kvlw{;fecu7{0> z$e+Wd_ekl_^Sx2HPTN3!=W;xO>nl&B+fZz8$c`KOe{ekefv_Uqn+L8&5nMU z{<^30f%iwlGiNX#Scmru!!5k;7vALkyYMTM(KA$he^saoq6jtQ>5n;Glknc%E-fVW|`x23lnyFeU_cM=} zUaeG~mi-fqf2xh#(q2yaTgG&-@=o$_7dfn}{MAi1? z%K~#`g}JijJXvDC{9|5OpuBFO{JKi+-zHyemp6CFar?~ua^OL^;E>!CZo?1Den(`T z2zks*ds(@X+3~9K=j$@h3GA=1K8~B+Pb#l4vz=1DWez*7JnfA1Jue?#uzX3DzAOW- z$am(ctIE@^$wt>@r5iHqP5Ht+d`r2=Z8_1r^HMqNmCX7^uIFVlS_V@UlHLhknS&8pQ zK>0W?*~ME%CY0aJxI9mZ@kX01d7cuv3eQu*m*y~@r$ly=$|otLe;PSFoh;7w2jgYS zE`OTyawsPcGIPmBX20CZS@OzR`DMz2@+RMJf%)bvCN~t9=gi3^l((7R&E0%&Gp4&& zN=~XO18PX0#xlr^F_Sk@xfjnHV*2&VM9%l=v9>MC+5+c6A}Y$sovQQU8#yla0s%6x0O4Y1+nP_z6%m3QO*4bzt%DyOcL z56pzCm20n&t;|eom8bK)sF;4KIct~lYSVA8ayqm8Y31(b_A|=gP49cyE-=3kGt$g| zU*(Os+;X73;Qkr<43-u6eUY1*$2eY~3*M(IT~o<0b8a@}qeW#LE-#E9!sP-#aQ?6a z=MM{VzYiCTkdMa7(o<#5X)>7mV~n@0{9RL0*c+;-QA7d zf?^jocDG`;D0a6Z*xmWFyIZkavFkmL=e&P?Kj*o3W_M?2@5IjRqQ1(O8=SbF-U+AG zBk0UXT5%Kgvhf)GLu@>TD{VZ6Fo*q)4s5%V#@|f~?V;)R(o?dcjoawo z)y8cYVB$Y%gj1 zf8ZS3|AG7LxEf~pOTBIX1UX)OS}_^LA7B5gAG6o>&2c`<#95hB*Pw&#d87SxZ+gU@ zFY+pTp74b%X8X6u)k5h?xpyw}&c!r=y$>#7$+(S~=LOQMvSkzIL-Ij0=3?z=8+pR^>+m?6I?}tH=&UYuLojXDoi6K1 zGxnmnhta9>fb9=qeg#(3R<@sjoM$(EX8T>p$*B`vW z8jh7&>~oDg&yH{4Uw0Zm27P76HK>0`MLkl}0rI9inU?iLc6@^V-s!1tMw%xxeP-hW z+Kbxw0EgtF$E2T~*F}Ak+-k=s$Z2f90v3_?ZT|xKugqfm8OVOJi5-U^7br`+m!oNF z&?53qGiKN3>erUek>zatO@!;QIXUjQ@Mc@gMl=R@ETxx~(kASbZ% zA+W#vb%%M6jVGwjxA6n6wQ&O0wQ<6JSWj#XflkM`c-dm>3&zwVE zmXG9w0&Jfv%N1mwRRZBFs7E75P|>FUs~g^0{ZSf6Fsk4vNJ* zRxXyQyjagEtH~?!v7G45e)D8`ALhF9yY!6BdW763Z_DN%+1^P;OXm~op>ml#D62)Y zy|Hxp%p6zdmOJGM+3gGa4V4+cG8d3{?DK>5uBYwC!o;>d6~yOK2H5(89LLrhcuWqq z^#!?rtsn5ETx#nFawA(0ps&6E@VFde?>llqd!OMexy;^Yuq@XYd zV9N!jvE>1;$c(l;kax%qwp^^AEf082PPXNOT+x;X{4VF&azV~(%LCq%vuwE_*RbUQ z-E4Wl-Lji47v$WwJW{zhhh!gHF334;dBDeVo-G&Ty0$!^r!5b7K=!ref}G2i2aJ;Q zZMh)Vv*iI}+46t~Wj|Xk$hmEKz{fJLEf3@)vY#y%>u1XYK9LJ-xggiKraHn8Ody={5H!*YPVe&oEiyx=pr zz?K{GD0^LPJ)Gk9y5I-7#$F$C3wvEKvAr&MR)*N?LM~yi3x1TV?e!t&u1IIt{8#!q zRc*e|vH8LsGT7#ioXO@3@5oS_KXNsjFLbf_!tJuC%^x`-mZR$#e2-)2M_~!e4IC$q z?H|HFGT8PLk%L3%C)-a%cE-}E@$|w(x@;;vIgQSqPJf2dG+}h{Y#KR-Cbr{e%=i8p znsXC^;>&A4yZVOKl93oF_AT{yyy8{q^yzY7Q2`CZs40ZnMveyMy zST5%{ElSc4TTn;-W%WoL9~Y-Rz8-R%ZT5b`E%v^_A@=@Qw)GJO2^P6O@!HRPC0 z>2$k~4f($O)||Pg-FJrigBZA93l_Kg#$e<~x_KUbWcP)k?!SPxTS>pz{a~mcSWVNe zpPJh- zhC7(Y+4)8EUwDst)&r*-w;Z^X?XzUYWz1#d9(hgnvGohjFpep-W{2% zbf&+%(4^hyiSG15PdfV&9cR;5bDVFoXdv_M=JdO)(TUl|=8OI*gXtZcKk~U=^oKk< zjya!g|IuDYc9XHTuwLBu3(#I;I}Mf}_A7_dK?d4&LCC#iM?3$8 zT;vki)D=R!S`9Q>Ghw%j7m%U9APiv66Yw1d1LTiSVX%y*{U2M)*C z`DggC9hOI5S0|`F?O~s<`}lvS+PLlzhSsIEcHsI$r7yaV-I;S=l|L27v z$g4e^7&#O<4$eOghuIzH<_KDKl(hX-)X$Bkx5v-}w!ez{dfQ)x zXKj6gzioYje{6k%%XZUwwqJ=n+14Al!PXmi!}crT_Jef7A-c{U?=b!+=`qG(_$CXK3;g*?$d>R@6lOypDyz4#F#%^(2!2E`)QFE%WfT*hjpZ@ zcjfTzI0DNdVLVRI)oM(i{+jqrW0V> zVOYC8?PK?mBj>+Qv+melB9E~9!J$uVI@az7N8VufgTu*o|2NDrfF88_ zy^;6Y{oQbcZO>s&+n&SpwmpaU?0#>U-|q8<1#SBdo7;9BHn8nDjM_jG+IAbcs@;DL zpUJ+qeMTNsAIlN0wEL=Iw7swJw7oCzr@b%mmn~;lJ5|wt4zbVM9sKXG=@-Wdv(Fuz zZu=`Rk*!y-W@FmL+DpZDCfa@uye_L+f8^)3e*n{3f4J4QucLgOU3MNFHnH>Q@O?Lo zGjN3cUlNRG|Ca>Y*#9NLO!j|CFrocV61*Wh+y5mYAC*myFvmJYKVG19?K*Iq?k+8| zw(!4vr&O_j=B-3)+i~zr$7wx-PLO$4GWV4u)-o5`N#8GrmE$^9R?uv#=&99os~wl2 z{mD66=sfkX`Gw+lJ1)=*mQT4k&uo7tiM!L#?%#m@`_YPaUlHr-!q=G=6UcR*s+bpI&h>Kji8Dm>&8B;(8aD zrwKhbj&}YJ)8~opxSgUe?0F-fuzKbA&Q=d>Uto3@ysz+YQ%nbadeS5|-9en6!+9OE z$7$rGv7LHn;C2_s2j|tzE|%-#c-)SM;ULSo@w-T7EBro_9S^}>mJh~rPTTP#{EX%6 zQq|XaatHOh7?+>XC(r4u7qs^e8vc`J{!6Rd{SugNmRund-9vj0{64Jd;^Qne$9g*1 z9>Ai$&P20!Oy{z>4xcZxApST0A&lee3@~@%e*n$Rv7AMw3x40p9E0DQi|@QP2gP-Mo6Ef&pGPpn%SmZ|iRTnF$Kn6p%)}l}JM(Znr?(jv*STy~ z!S6tsqdlEBW;p)G_%ST)<5aZeQU}-B%Caw+f61QPQv7R=d5YdIgY^mhGu!{jz#Dbb z|8wvi`c1AqiuDZb+mBJtYt)IN6g21ByZc-d)KPWntX&&9k*9?i|%w;#qeOutIrlwS5b;iwP2L&K$WmpQ!*YL0Oq z{btIpBbevQsdt#WWWhLxev?+xLaXV;7#N39FCC-sKmT~qo?EEDC$^Jl5B8y*K4CqG zis{TTAGkU3qTvnvF1pzi{}*iDiQ&w!-%I@F>Qu1b%e;*B(0=zXvAgr?2OJvPIaC#& zPnc>geUKQh3ppSgE$)ryhukfIE|BdyF<&1|Ka8W%)9Ko|w1&MNOz-PW+pj6|FQ1Hq z{ZrIO|H1Rfi~ZS}czjsB7QGjV@do+SUixt#jXX%bAK>?x(4K!V##cCWH`WLE$o?M; z&gq2r6-LU;TbT>WuG^RgN$+%cz36{UjPBnV84$ako4w^=NU10NAPKedvuFP2OFp2&C6g*ap z7B5b-B|yI*7bkN@+B6C3$dlwz87(s=WqSh|B758Qg_y3x8XC2qh998U?Rprr_q6L^ z;I#TQgPos4-ZzS-wExjT-f!n@+J@d>+y2#eg!npsv37tQZKCOqxLH*QoY&T#wyU!nP zu>0y^f!}oDV!Tht9nFvm+eUOtnx?Y>a7_x(=K|E3>e;&r1w+13wO*d8aZ zhx245{DkGUfi}v7<$;{0H0=~f+t_yOIR5`to-voWIVsoCf^tMEyx*vwu1l|2zoVW` zw9IJzkZZ`-R$q+Y4Yr)m%^3<^{(3sw*W>dIOW}Gv^MSS3_HjJc!xZ>^D|^3TJp11+ zc-`vt@xS0^q_0!PUQa6@XIfYEgJBWKlYE@_v+%rN-Y^<#Hq9Yx%1m=uKW)>M_j1Zc z(hp`AA6!oc3&e8LY=!S}U8lJV*J-?@ZgzhET^wgDbjj-DtdI?MGxv~3tbPywV`v#Z zu)GAnFKZe8wp`A~`Oh*;Zq9adp2#BRuz2{5UYf=%?Cq44jm9eH+Qd@kV@IV6yIYHRwdFWr?3+bQ&WC9mGX<41Tp-|hNWxY9ni zFqv&{;9|Qk53aTATVZ9}?!w^K^tDYN0tCVSfT`lwGyNvGTO`N*H*(vmj6+&FHv^QN%1T^|fnltMe4ZTIED^MSOR zeb0~%*VWkfcW`wJ>ehaI}Z$3KBJ{R(BCpsH1j@L^9%Fcukssx^PR^2Ntgbj z6Kr{4{vm(qbKAc_{^Cl1+xO_mx9od#nAw*em+j&+Uy~1Pe+>N!+j4^$+EWj^?PqwKUZhJov(md?fwZk-CoZ@Pv@eXYp>^kr*n2N)^k`g7UsVl_uZRa;y6|8 zx)fO4UT1>1&Mg_cJo5t^|55+llOC|&pFw_Nzb^vYTK~N99e2Av^`NVh*4EFto=)F7 zcs?-Hwj*nCeNG*E+kW>HIp-eQ*9D(rR*hc5?q|fa52-77vN59G)=b8Im zpye*oRF~Y(+^`UgyFj{LQjXQ?^8AnS^P<d8Lk6$b9PpsEh^EkWwCuhJ**;qng;djZqDtRbX!{39{=xc zzgG;iWuS-T+)T{9?06CFceBx|+36;k&5lFRK36Wy$6O>otyX}ZkiK@jg8rvV&}=2? zL|MEn^J2Nb8gu6AG`u!#?(x?a+;;?V)-vx}=Zled%!dSQhQa z`ZVbbU>-e?HXBN(+V2$ObuF>qC$`sj7~6UH*3K8exVAha@Vh2eX$E^=kbQC?7sl`G znoZ(3Giq0C~_A-5?F;0n)W(NS6-xpuF|D9={fs81oLsT??d40 z`}9+6yx+*}hS9bw>D|>d;Tl?X2OW5x`r7xQnC``O>eR&ggj~a)ezxrb@+KSa;pL9B zdso_KG~H|CIoj_{r9-CCr#7CWUUCine2;oPp;KPd=k`0i==Uc%#$9+fH9ek|eo0Sf z+vmGmTqjXcY`2@aJDsNI`=>`JO*fMU+j)l0@tt7%e8Xh+xp?d2ys^)DxtPwj8Za?_ zch5fW@N^Ztet6vKi{m<}tq#kUM;%_a{ea0{j(aQE2=}Q4(5Nq)+7NLCl#4)9bR|5az@~=@*+%tJqF2yKf9G$MLIct=P`q zNV;w>y|jY6aXR|#`9WP`;PZ(bQNQ>LoN!R~eOyxla)%h@O)<4`aH)9?s_~7*}8sJKqa0G@xl4(mAqM0CSo~bXa4WE08Xf zjhZkgKZ5z!i|1TFM~@}L^Fw~vkxrhB?@y2~6u|jxSS1;rFT7a~%NZWMO{>~`4&is^ z&(pAkm>&6Ka+<3H-C*-WJ=*36UsuHZU<~`cKREm;oqhuI$%_9`wCiHwKFe3}`?CMh zmuF}UKeVGhO8%5FsLw&ek;O2V>gwu#4S?3Bz;JJvKk&#&&!Pui5nQ;zdk<({Z}opug^8 zJSiUEDg1yYjiU8rGOK^Wc}ZEw>d4*X6+0dr=r|d?>EYNgkE`?aKP+E()Yd21r%bVb zZm{FdB#v|4&P&7HcHJnPVE3av!1bi|z9o<8thM(W{}35u#B~ZjzoVmWxu-!OID|cY&~lk!}(+P;lb88&*pmH%c*SRS4qclv*S~^ zy&YYSy32ca=bp6}a&gw#=c2IVJSvLsC1H>AG`an5H}c1Cw5NmDg*-40%|8X-Pa;ov zgx3e(*?e|-;`?#5!}C^$-#qcUVVO>7_s97Mdq3ggTy(6xpU6e*JT;8;LVvi-`loes zf;-b1cK*-9%_-!T_MfHQ>9FkdVs3iBD_zl@ddyDuum8#UH1Tped@J=hK(~itT)_Mz zHqcI2=#Q)PRT3;0w0}xPla-{UExo!h&km*?deDTuXuomP zZwjp(MuS$-%d*ls=C14M^+@`4BVD_NZrVyOZj;+-(}Q&REn46<9e0oZeN4+l(KYhy zbLLAg=!SQ6%6nS#FCFHMaTd$%U>uq{13fAmWMcl5g9cWnbF0(OL9|7CI;cC{-b3y3 z-azJNgXo{ZG-n81HJZi`rR8Lzxy(!Dx0TFEH`Bhd_!j1TyXcGEwA>!*c7(<`O8?4J zXPJv#q5+?2nEd{gIrJ|*Ef>Yd{uGwmN0~B!Ij79rkvUaoT6H*WJA#JIr156a@!RPS z>6ad#Ys|myPkP2akH}Hc_*_HJ*!Vocd^XO)W4-YCOX}r}FNfdXhF2@lbUX3+K#t!V z?W^KCEp5BiCAQOS44jSeUQUy)6If3!^UL${`Xsi$lOB_qf32iRR?$4tPqvW#WRJ`2 zH%=~*udcH0c8#Wxy4_&=(3><&M#$ZFHT^vr`w7i1>&ReP;2GQN z%Ine0`9IT9a;tRt!g?B6S@w~OWa_W%=O=s1QNLN=FWvtz*Drv*LK_lj0GGSxp^7emb=+{!tkdgAOj5~n+>d3BghTJ1>%CEBJKu$MWu92r@ z@L9G`k(um&)$n|}%11JV{m&ZeBV`x+zcu7p_CISd=4D!0_K+>?|JTs|O!l__UqcSD z|6ha8Wy2fHD{s;)w`gsd@D6i-Syh%aJobV0 zLZ9e&Sv8vZl5GEld4c@>m3icM>hgnTmVPqq7wZRP%-_tr|4{G0w3a*}tJ?qK;e8n; z56G-8tVc<2SLTt@!;QIzJS)4pv%Wy?lY#bsdw86)GFD9Hbuy0!b0;r4U1sxPZY4{_ zX727wm&(d|NV^NDD|#I$}A8X~=tGW*Nr@;~`nE>6yV8B@?j zsc1lIdLj*dFa6Rocb5m`b6F%E+gr++GL8LDA(mqmIa?l-zvR>m?6*^Xm1#4w-c8Pt z&t%+8Y~O4Ddx*zL?@vd|$Ff8K>!I?M^tJy-#B}-Xe}>>edA=#LXEWNiIX%~sW^F}l z$k8%yYt|dd5P4Q6Y{&MZvZs769byr?U^D1XQ*!K|0C>!k6z zI`^PcWu@NCetqfB{&ejCdP!Cq$Q&%U$R~qXZ$Fr39YUK(XDD+e`(0~1{$criIP<{~ zG(!j-zK2%YOB>7Ha)LZ0Z_6zQ*ni+b>V1f2lD7^sr#?c1P?{A0|w|D(?w z{2v{j|2r2t#FfT&qZ4HocjlHcXl@T$Tb7B%d|h7jV*V-nc{BG*PJL6*W*KO&jP!dp z>XV1gk?Zp^kIheG7oa$Tant+cco@8q$*Ts*LB)dZ2t6 zz?`@dohQ>YX8sgN|1_mpo6*(H>97{`s~pyndBOl1Ay3Lra`+;)&z2GLxLm)5?e`zi zuhRE1a~4@f2FPwQO8$}wqc~lNdzydi?=pEL2J?IA8Iw7)^pox7>sV~}@uIb4M;Rh3 zWnp_uIY@@d>z&vhvop;qYsdz3SnnbmZe;Eyr_1pF*AwFW0X~=0Wu!bMpGYSW`_)ZG zyU4L}vD_`MN+&t{my`jrr;MGK?V046Lb#3{&u64}hJVhJo8_3;tS^$=Wr8@Y=a4@O zF_$b%8_KS7t87(-?E~ZtxlTTo4U4j0cR5k6lKbTy87-3)<8<}p40%d+F2(j)GJ9#} zO7ci;=G*e4^sd8t4q08k3SvEedzxLI>Bd~OJ8dOr_F%pu|H#xmSuZVn$tf~(FSeJJ zfwEz5)UW z4jIVy#qzLxBAr2OuOJW0*D}^%wr7;*i$uN0PK9E0U)`^@?Ls@SUb9XseZtk4%-*|Xj*6+sLS&ovkW!c$mZ!CMtPvm)znbm+C;&A zmlb4Nc~DjlWWP3YkX#_Q$}=)b{*nosaQd9GqHH32$_a9r+$}H3m(sN<=a*dOmmh|) z?me8Qm(}G+IZtkuo+I@9q`&MXXUZ+|vfMbA)8&~*tI2k9xD1y!WX$>Oze8S>uVmT< zZ1>+sO#YDZPqBY?SzbQ!!1sul&vzNulR2wQm4~^ItSQ^c!7@~??#%uX_Wdj7dtBa= zUu24|Y%eKK%g6GkOkm&NVm<}sgGtQJWSUgwmDOZhIar3t2zg3Al0W1|7kp2M#|v?z zKJIkSdU{E|kUrt8XOIaZnX}7sGFXn0i{vgj_$alKpea`|^iObc*eHWpx=ON5}=T$wOS1 zfY;wkHhslBST2!|Ws=uyuO!>Z(Q=)<{f7Pi$|P@@^GHAWO1iycdj?ruzWu~{yl7fX z?)=PrK|Ytx7uIvjj9-~A%NXC7v&#V4Urv&n+Do6MY@ z?TcjM9L!T>%$&?a*G%+EYjevx+zuck*m8*8j@8#hHCe&^Iz;N#=>A>1x@nEc07Av>bEH^7M$j zBhOb*dqvt$E|R4xu^uE7_%YX!|H;Z#SWi=xmXXb>F)xrEsxz0bK|9GA@{e?>%l1sN zwcJ^c_1yL8D%qd`^I=)KA#+-P>MsKWn3u?yjhJgSrlaM4`6rO|^v$SubDCTJkqcU| z{zqnS$=pG9ZOuHe4gF%*nPI(8-H!UnzVdT>*5h`dS!D&;Tn>;+E507?ee<}?!kJPjMJ03ku2SdIY=Ju%Ur7;jgrCr znY{+krZTBrkBa3OI+(^8LdVEIvhPsV-^!q2%=e`KaOQKe<_P9c8D}K(82Lx`9mV=v z85F{NPx_B$J|`=WVcstbk7bUKna43Nl8MJNPmwVvFb|bq2~ljLTVF=@vJ7$eq5C9v;k@J!v)h z$%{FOH~k{7_%NrAO)JYWGD5zUiQ}-JzZ@#}%crtcT=rWoAIMbkSPzu*zoGCBL zb(z>+J2PD+6K7%WE^o`HSy}IxjjoW%vokl4N90>sB?sFl%X>0cPS(4~RWeg9)|<+} zyv!qIxD3w6`cpYEKl5gJOQtTsdYHT>dlzJVfjlU~3bDRl7B0-(T#k{q|6eb`_K9+8 zDdumovEAQ*&&Q?m)T;u`FGouMO018Or7JU!mx=wDvsIxRl7s2-A@t8s`f(UdKAc{WyGAfi7)kHRv7?yxhtNEu>A^8H?^wD^ZW_!tpmlcA5P4I^+0FU`8G8?N4cSM|m5KMUy{z1`pE>OTT2TfcWOg}3v&qAUnNuC1 zHRMD&^(gBxj?rAQjoc>Ro?v^>f3)B!+EmUx&Aes|uEW0*%PBmTM#=Jae+25?h59jvsllTqq0L_57%hlRqml`!%MAy3mYv zT^ah7lK!%rY(J3gTj$VEa>QKbP4bS6mKo=VAYeP+?YcKsXLC&}j*aX%gM zE>~P{22aXjZp>BXNqJK?a%cNNyIu{`rA$F{$^|l9x~F7&LYXBkb7wh7UXf9!fP50?Jp@ckEZknAhR$V}teK57{?ZnWHO-;*Jqk_o+- zH+s_}azQ8NNO@Rp8LEEr?l9&z(izSiS7wj}WM%0uJIVoal3XAs&gJ}8$?*%B7t2bu z@qHCu&%_3FnSJksyjkwF@p5w8@4XY#A`uyGUplSp?z=7jQvKXai*w4jZz=-*Lh z9f;2}@)Ega67vz6U@~(C*-UnoL*y*^Q#P=17V~W@7uk4<>}BIAY_*Iole^?l8!yq` zcmtgx7s&|O*v38d>nI1v3^v}OUO-lm^<{M%-_U+RK9KLFvx)81x6>xFz)R+1vbv3j zm`{8UjAJmJOqiZIqbw*Z%4-?fzRIo_#&k0pQ13=Gh0I{%Cfck1UmG`(d&&`V@M6|K z$>mF!&#$MCp((FIuLzaTYnh9B`Sr)D=3UA;wL#PnP3td_`U- z3)^^#94^zXX3i(e$(FLa94@EHC32hmAYImQe(_{2*<8+-hvjwI-^O)3uOv2(+w+&l zZ9GT*CIf8TM(!#z`Z5=k)nrSVBrV%3+jwsCksda#BPW)XZ5&4qkX!9K2jpR~=oA^l z#&Oh>$_a9zykz4!+IQJF3(w2^HlEu2>e2o-t|AxzNJssmH*9=G{j7rL3=&A7w2Y|ImM;Okm@nO>g58EdP$y zm80ctS@J#G=gXh6iS4gp`u(!{N9Og?`xA3#d0O6*IilGFFuvgN zF3S?G%++LL*+KS``{gU?;>PKk$N}=4jFw(@zXu*KgZwFz*?k|Vx0a{vJ`d!)HcrDb zvXy`dU;oVlHRu6!RyH&C&;;SjocxR%U{wv6Q@ruv&o{;Px{MtvbP*1XUL^;qdXwb z$-6R3W11K{m8oSe`Bl!(&VKc4(@t`Lyef0lWxIbpdO^OF?)6zuEep$9GP7;J zv0R(Wu5z(I>!$mzX2+ozY<}x>vujJwrI8H*p4f2~@ZO2cj zZ+F+aEMI_h6#OxvC#caZ&LLff9BKHj$HaFHx#+jZpAwmpZpH;wmnBZzI+zJ{6l(0GJEWzNn{pTM%I=sWUamI-&}5x$K`#Qc^~@~lM#0O zhUYWNj@#e@xmR|w{R`9w*nR~}IG1LT#pf~C`M^KemcgZh9m|sn%v+VpA+GpBv7d$E-+3^>0 zl%2nVu8V02+rL0QxrO$&;~nI#&*(Yn_ndi&^nJk`B#+Asc6@~Cx5?YGgdH!T-bv1t z|H)|EKS6s(7rYXMrjhmRy zL%G?;MdWri{+TxZ!3jPzEFC>jgmx%KAIMv!m>1Z6mzXZS-A@VU$;VVKsi{5C++OgD_lHw)_8(@5+?Jn48FX@}`_( z_vNAgdKug9!$baK_t(KMc0U}PJ(0$lhx=HNv&zp)nfouJG3-7uv@ep4?fx+2Ve4sQ zyI%@6}nf5ztu>W2f zY}fB2Z?)_9VQ#yAA1=4!aOiKx;c&4XheJ<0?uJEWJz2=En@4?|9goAPGPqs`&TCCe zb*IPedLGm_X2thQFyBOM-;&31mfCSOoIIU2wfZ(x88cX|mVSGeRYx{Aq zi_C8ObI396JQ;jy+YeZ*C|y~cRMKjryya-WDs)f{I;S(nJDc9_=Y?79{#>|d z0qqta;~Mf`nI<9gOF1ejbB+|WKq@+0rcK8@M&51B{BaD8If>S``~U2D*!_F3Rb3j; zkXEq!(NI4v)On zk6~6Dk6|1;E`e+8`yyD_j!WPUFY0FZO(FYKqgO-d_tEsHgK-M&>1BkCRPyd!LF;~h-9j)vHA1#;s@wBTb}?i($DKS8$k{%$lP2HogG&mN(HcD@q* zrrZB2!fp>}5eL6>h+NM8R}rrC!S5Pcw)=VDwZ}B-C7opV$)LW=?uUV%zvzwj7*CO( zWyE+2r=Fo7&(f=3>Af?>|FwT8gx`HezuiUX3L9q=x;xEm{Dt%FI0$C7;~*I07L9e6 z7JW*`*?5Zf!_R56H*}?qtEi{@Ni*5+_#r1Kg7FHjv~d*)fQ_fn&(4p+ z={BCi!FJpQugMexndjJeh7~f!^{r(gDZQ~Jqk_6)dJZa+)oMGb*^tW*bcCqmW zo{}4Fyg^R#jxMtC1^K9rFYvdGFYvmJFL14mEAXd{D{!Fg*TQ(VzY2qFe-)Os{Z+Wp z#u=E=_DA6lJ5LYm*|-8dY&?N~Y&?M@Z9fg>N`TKTTq8HxIDp*FKKHPJecs_)+y8-I zY`+ISvin5gU;Es`*>;~LTwtF+Si;Wl!$x*rBOGq~Kd_eV|G*vgIfIA)&{nQk?~y;s z+V=aY$fxZ-J~-?Xz4n`Su>Atm$JqUCaEh(h@S5Fc25Z=TUhsNHtiQ0A?GM1+w*JDA z=V-XCpN(TV?QH#ox2DjtQ|VPZen$O)oqvbnr|Etbq^d zhqZ0JhYfALhZ}8w0xq`oANtt-1Pqg7?Q?(}-}Wcq5BaAB^T1ZLdRtn^_9xKqm+eo$ z%=Y<#OYHLlXWIS*oM8JC(0w%hWBV1zN%GQ8wqJqV+CFFSyzO7W=C*$UQ#Hl@0xV?v z8StR(XTT!1e*v${+P0s8ywvtHU>n=NfG(M6HQT>HPGS2Ou+~+&=q9~)hkCxJLGq04 zf1v++``p`fNoh}c(Z&JPE99rMY<~o~{6V_H#s}mMHa@`KHZH(Ra;J?C$Z2eRfSYW; z1dg`-61d973;0-`v2g=Ah6_Ib@R5xhFoW%vz)d!OKsVbTfg^4FfF*4FfYWUJfbDJk zfIDscfQ4-T1m?7H1iISyc`%)gBQQ`dmp`PhjW1}=T!O~5{T1XgWoer7^kY?evO4vw zMQ_>u3;Hj%{TEoz_Fv#+8>isGh4j@TnqV<4WaAdvH_L&xKZ86~W=h1o%f>a-b0w!? za;JP~`#orHosxF7@elcubV<$J)W$>956J7Xc3al>2GJ{H>6Xbfz>Xs^-D2A>f|Kge z81}ma$ir=a2)?v&73R17B6!ZmSLkK;$y?p_i(rFDwQr_BZNCWhZZ;0Xm2#`yr;fbB z#${N+#%1_=B0XpONyzJMKMA(9@fwb^@ftR^@ft?kcn$N{qCf1sDRP-Hw5JTU<4V+P z+HoW7W5lDZ`)7gA-4U5M{WBFavUMFMVt~ihe0&9$8K{kV)FGUv^nsE|=Hk z4BH-Kek)|{p3ME^kzUO2WN2^Z1M*oP<_vvlfE*?tjbQzY^cu;WTIQ33ZPCo=v%^_QvlGdGqa>4rOgXq{~6=La(PC+ zm&ppUy}S&P-(>1SY=0tO7GYjflzNq3@pQXKRHImD$Dwaa&)!~m-)-H zK2M&O0ToyuE5l^5imZprLY0{3`q4Ggr#f>+86dyaVBM!CO(QeZV%{x})n@)AgX%C( zlFQ{*nW8S+N6KCDf_x}T)MLL|V`*QxP5zZ-#DT{uaJjj$PU)0$>s9=PS)%1q9^1v`C4Y)&GwK}bfJuOnz@Wz zAkUv=eb+fU^*oJ`SuSe2OSFYNaGCj>486kq@hW|HjYeLl-EPoqw`raSw3du`$h`Uy zJubUNF;9{0pE8e;xt}xFenI!jp)Z-IzNQD{J2~bp>)qec-0x}64|KA;7tK8QGadPr zE|x{UF;|wuWTY(no$amVl}@&a|NPla1vhxl}Ic%KpiMse3m%RYu4)Jy`!O z>-S{dDC72GZYTH1ti4$uA}9A{K01irlJBK6nDr5MT?byzY`H-mk!`oK-OqkE8~p-h zS2ObU4ADllz-X>4Whw_8;h|PXEWl32}wv{dHycgy-P)@Y-U&v(&;QS8UY3GOFM_Jp> z6Crny_w9TU@@MH?hB<}IC;enIIaJP;JLFmUSbmqW?0gg+Cygv18_N*6_y6^B?B7+6 zkn81H8705Ul6Jlek5fZ7mEC2CTp@Q#uS%RQyBu%d^I<-VR-Q)tfMV^umrAIZ+FG!BI^LCj3N;%oSe?(p;cgk}zN=D1rHQ7IvtSRTnWAe3K zCxiJ0)}>u!ntIInWF@(K66PG)-w*;MY8?o;$QGSgJ%qOyz3H;wgbvY8wv zH_Ow~V>E$NmAbyBsaA%YyUS@4Sq;fH{pUChN)0GDOan+vF*EU%D>j{3^&svYQ+)7s#FR zqWmCz7jZsWWhogbUrU$8?3YmHm$hUUnQaOCm6ic=u8fq2Ck%9V1jylvM*U|floN$q`bxb)q^_7<{_oG6#d9rCPvEc0yD{N;BUXB+G3 z{zubYhF7h1TL4a}Qg3m0mqT%v;_mM5?i^eS9NgWZxI@tvm*VaecXut^F~2eHulE^q ztz=u0on)_M%i8il1nX0F(N(hkUgptqzT6^@OSgUOmtOvr3HG!8Q5K72{(GDzK0yn} zDssS0)+fs__vv--ldUt-*0?wm*orjR|Y&}dj?rVe*eyT%^$R#94u$Z3P0I? zK|YbcWbiMxkCV&fUU^p5|IL1PMRc4NK094IHswQ|2aFCWS;a-2Kovr5MEV9qK_$hxwxoFJFUUGl69u=|?3E$&oX`;_RA_O%Pw+)+#pZM*D|^(r++V9n=vPpS!7XJUAB^aqJam-l6?44A;_(#Qg`we+9F_S7=JtRUOT zFgaIlljr0^nQ$`amrc6QU`{V<$hmTjJSanFvVV6uU>5UAnS3^LQQ1TemJ{VdxkH|j zujOwUJcskkE9=NMa&qsS98*d4#$ziLQH_0fu zd^PLWAI1*i`*$+N z2JYf~GRb&9moXm(^rho3_mrdMQF%wcm(C&fPb>?|Hgb@hDtF1J^1DoQ znDZ$o8_51LT<(_FrN&0Y4Ib1H37gw_1k5zQdI$CK9Z7v7MDKcC}$}94fbhdK( z3UaL6A)iRMZR}T2){$XyrF~WoVZXAntGpw>%7lCM_;Rc~AwSEE``E9H>@Qc!Yx1+q zw4eR!$T4!Id?bS+*{`x(DBYu2Pb~||O9xnwdyp28BW2-3thbjV<$QTTK9>Q9**}vk zA?wOva^D%lpJdJ`i^^KE zgB&U|oM!)WvdLNIF>;d}a*p+5^0AzBk@bD@qfBv$^%`=dTq9#Ivpx3}+FXv58{{SV zSEjwn{$u1ex$_$9uVnCb=E5@T4d#Jzm3$_>ZnC|ooG*XL&|7SODLrm8r zid-VM$rJLf{3HiI?gO#Tk@my|G@s4WvFZ-`^l+tjeIHNeB|^gWkFd>c9CInsoX7p%Cw(2pJK9s z>>)>fW_!CYbdgN|mHA(}SniTHpO(Us*XuE|aI_7n#a~{p-p}a=na}kEN$4`=^)v zWH&F?6Wcg{yzb6V=@9Arj5)6yEmQtxy^_3h9^?EmeV+?7T;90IJns^XkjpMJyI!Fe zWuB|dF4t&l8FHO@hHQC*`JkM3llhZ8bc^|`{BWDO_8r<+&XLPvSa-cgFUmaknG-#r zC1pSP-~;P_Ww%evTfflJU+FWu4i@jvPwDraIfcw6OUrt)kNi)rmV4z{d0)PlY3#ZS zJYHQnN`CptdhK6y$8Y-K|BYp?@rPcQF@KrkI)(o?-;6RwM!T^7Lne&FoLAP9hg?}7 z;YJtAlcrHRMpaRi2SK6R}^(B(#e>BwdoSoOQzbrq?Vf9&GFRL|R9xX!}GFOvf@>gTl%Qc}FWS6GQ=VZBN%wJ{3=FH); zSqtWlYV%v<}>O8se+%s+s6lPolld8sTth&e*G|Cc#N zb{x#SLQWXM{73d1%KTQg8>Z>y>EXN{z&HIGU;gMaCujL3}gN5Sh{o^eIY%@ zGZ&Z5*e>WU7nMkk*sHt z6Xgl{NbZYbzuX6C8@WLS9%g;}5&BHVJ<44CB)xi;<~c_@o~J{v(CsqlDsv9m><05h zc}%Xk$@(ps^EPw8J2YB8kx_S9kGe;fKcK(l$VbfHk7=tXbe}Bvl)1g^`HXqwb9!5L zd&T_nHNEwo27aXDc2>FZMHQxzdMjbgw6k=OyFP`Q9|p zhx+@{8FGLhb4P#LHh|8Q-(~th)*H&va)*2-+r?wQdhzMGgfuuYT`BKM-z2OTm0jdk znII|K56W)In0HIB2nf(XIXjv)?>n-F~c|jJ+%J#Z)n%pQ~NVjb4S5qF6_oaV! zw!e_>Ihf1Iaq^J7FZ<Pi40rFdZtCRsa?l{{+;DBSz;;c$5zo4;WV=>D$C0z^2=KGbJkHG znLwtN+2k$xTz-|V>p6X(Oewd^L-M@5BVWjG^4bQ@=e~R?zsQEK**;Ucyu>PB zxFw{+`qNMH*$n16cK=fJTO~d1KBmaQa*o}n)Upe%CxNZxQ+MWtcKr$JKm6(A0Gd9K zx~8IK*7mzH z{MUXjhGBAFEOSIM{2q*Ylx&!sxsB{D2gxyVs$3w$~H@zBlVLY&-KUuJhp>U2gYJ zLY`{(aexbCnbyq5Y+CSyd3jeRvFq(nPhs05*i}xE3#7Ykr_dfGQ^*9i-9o*W zd}rG&?w!H^lNcnC$#61MP*0XS1y;)@~W)8j?*`n zo#jY5SIt6V%09Lg14Q`b)hcYLy^$YbQwqC)X^0=*6$lGkW zhnwyCRG4lTZIA$;JMuA^BO&v4nKTh|n0zX0*ma?pE`JglQjB($xr;N;v-Jc0#@{L{p zhkk4AdOujvuFr#M?0P&nLOzhC?0P)Zm&uxT{Ty;fyDkpav+La8A-fI@rm^eHpqpJ^ z2ItEia+_U`g?gA>Uj_fzbyTqGD!B;Phak6?DeZbCy7L-`}o>fq(6K7uYD4-jLpZncLX) zDQFLuCtaC;$}{fFb?o{N^vh@0aloZ^-3Huh*ImG<9CVvqr+}Pu61`gy`(emwM$>&` z=(owV=M>t=?t6xQRc*TipW1c@HoQj5+@kv*(GHJkw-2<=C;G{@OPFqg?JvPvF4#W7 z#Wvm!eoR73*nPy1yUE_RKZSf%ev?rtSf8DS_DV|wZT|-Sk8h#Jw$eA-=-?xCQ(sN6V45%IoHtWwX}!*ev9^f_B$agYxf0%+3fc%n5kUh|M~n7U18hR(%#M; z>2KRtDC5zi}8Rqv*y8AN^mIv&<2xxZ;q}}B< zc~oAPRf5@XlDsYR#$!Eud^$`Xk~icJ`yR#Pb;(BO$qjP9JR{R&XTRn-sIPs0V){h# za0%umCFw4CUA~inrP!WLehy{!Elm^3I%SyyD$;nie~QP;APdM)SyeWdo#ZOHMedWw zhsekec7zcR@7E6`p-R+4pP3)xxrlOyCr zIY%y+8|7|!M4pp3qvb-mQTFN2{(lEi zciTV0^hsrYS;F>nP_HUC%FNN&k3oI&8JflR^O5t)5^|s%Ewk8uKl)9z`)a^nwx0t% zZ2ukx$s)3x94M38{txPr<)|SoW2su&Ck^OD| z3H`6zc@Q|t&S${W@~W(9=P6M4w*7n9N%ofuyk^R$_r|3gk-$K$Y#o&STG+tJwG_mQEQ!Y;1WiUJLGrk=9 z`Z&2)zz2cO^_8^pj%5GKpLbG^!!+kiyie#iPgWj{=Yf1J9Mjbaa04xPH-j_q&nFo2$0d{>Y+J_CK)ouMnj+XI8F@KdaZGRc< zRmRb$c3u;C^;BAJ9<6QH-=Y3^6h1##$L=Q#bJ+3@zn`G{Y`+@0zFpS>{cQgldfM_2 z18n(+|GcOD<(6N}joh&uqWz0}ZTrQ@D{Ma)F1P()cxoGcXycEO>)oMs?$X^hUJ~_l zHm(sCUW?_**VU;g``hw-%*A`~h6X>P9Ujv(pJ|rA^pk`8kzu~mU1=RRI!Zik5!@ls?(Wrn+#~l`mZ*0P-mK^8};o^v&!9a?O4|H*!>OheE!<~4dLpE^qJj{ z5P9G}(XjeeJZ(S)<=;E9;_xU)#%otxM<0+UC z|AS%v@N~wQ2k<{jW(GIsw)rKF<8c~p^KnAVqCrj*^R1^d)*O!ez`d~S;?#W!J@9{= zujqm|@LC+FqHVX~L7CRJ&&YLTb33nu+`{hH5C6*cc76%@RZVP9VSsHskSBX76s>fn6a{=m<6ybcT6b_OOmOuzf!b4Gsu70-9En^W2TuN-cb zH)P{n_B7CMyzL+t$$$t$z7c>F4*pTad$l9&=;=o5B|4) z5zXxZH^y<&ET?lk;ZHZ`K{#EP8-~YmrsbuV^T0^_f7U#jz7X7t|0^?V;(r*6(r=b~ z1UT6%)9B6ABZ}524C8q@0b6Jn%XM)6+A*74I#~JMEd^H<;I%Vzo zB=>YGSih7(&gkuMfuFO^w&$-soZ%7l#&J4v0oDW5%h~=2d}aNP#c_OX|7Asx6Kdwb z|5=)Sy`9W^VFrIEyS*<3Je|U_-67;;9?rFB`t%5#?cuDl$AP8K(A-C%dyq5g1ni9E z)9P@}d6*2#&jotWEa>SpN{01gqNmf*Jnik2NdfQS^GpRdcsil!U}xn+Pe zJ`;TD>paX3uLU`SbI_ggs$88D_5ChRpWLvii_@_rjEUoP{}0a6W{b5!-AD8LDPLDcxUd`e-?+WAi0bZ(3Kes~t zhKrNe_LJe*Jouh~z3u+RaHid_7+$dZ62p~tzhSu1&ey~A_WvXBs2pzlnaGiLd;ueD ze-oy&-*4bI`LiT*Q~P}c^(nGo5$0gK?;h%VlVHCOuCn{Kz-M;;6Be=U8{A?0aqxs} zWBYT+1LgFY%v0<>3#bpV;~3~+$1QNQOl13U$bNQy6b`igI5<)6uS*wGtT)Kz1qX<&3oY1s7+-a@1id`=1DT-Yij$Qu)W)x!hyZU+}>H&d_c4KL*J0?f(j3x*c@v zYg+0ny;>fRhxQ+5Xmfj9TN{T~3l zdxrYi{o|1fRG_abQ+GT5K)w7_`q%C+j+}lIri&lsc-rfN!>m87VfA@&oH6#gpsyV_ z!P!=S>ErA@k^6r(x9K_tIIq9Zz19!8vmH-C7dt+JBkgzwF1F(oxX`A%gMM(Zy?(g&KKj7~m$4m$_Xmai&$c#R6uFQ6&qXR< zr+PU&Kj>MWhRD_SdQpETm)q+`ZnBh4u<2_DJDqHM4!2mI4S!CtmJ!gaPh-3oF7^CQFdwj4C~cS_oFaMZ*3W_7s# z9P$qjr_*`*)XrNVU%F0P*?9}(kufy)BRbB`TcEzn&QHL_7m!KX?li={uaH|e#Or}y z?D_Zibt>EY1G6+lJ3M3C&oDQq<$L}~{!yF}Bq(W}z>zv3yQ>BLI zeVjRFNq;9G4XoqqbWaN}`a9**!!q8^0duCiQ^2O{qF%=x!OKR#La1L^*=7o2-^Dr3@3bv+oWDhw}u9W-brABz%g8t4|8QYk-Q4{*e>NowJ zr@d%GtIvqz?6!tqFfLwBk=x}x>1yYN(Jzy%E_=%*@`!xb zj{SR>v0hG!JNP`|BDq=m_eOhRd~eB86OqSZJk)g9+uey?N)yh2SA3j&%V>Vf&HS9r zmSH{13Gu(jmSMdmu$`-u&ZdX`{+Ioo>ek-Q-`Ql@!T&H?hI6dnL;QcT>4x8TmSg*q z%grgUiXKCbGZyDJkf>~mgX9=F)jS^LT#1Cg9Vfm0KMH(kxsZ#K+cFH@jN@3i=@9A< zy_{r+Y4vEB*Td;=#^AWf%oWFpG9SlrYT5Sxn6I-@E;x_u?cr3pLsLJXc^}e`kLaf- z^v8Ev{Rh2w6&A<;6x;vbz*F*({3tza{%D^iH^~$7zWgDB@3Mb3Sw=RM{p1w6Mjn#4 z9#btfjLynirCZIob+|If$!k{habDZw!zHijdHGjXw0^gJoQ9@5 z#(kPI@Vk`R*v&a^-t%*Q$-Fn2v)SkK#@{Jn9>(3oa=BjaD#iW><*G`|o8(9NONLfvdu2IYE|68Lu)Us~FIULWYMNfokPBtI z8f@<__sS#EyC&P?$&{^_bII1SuUs!9@~A`I2!`+d`Aa4C*%|98pwJYSwc3I|H^rCm%J+9$+$tBPx4?qo_ic; zNdkI45quEG*^!u*NlIr)&rHlkWHT)9)<3W?%_+Oco${=7E5d%AJab^E)3( ztCXihE6|vV^tVil<=6UGkWpA(E#HyXuzXtnEK65qZdjcTkh^4)W~|3=PV31@Ns+hv zI=|A=r}p}h$6|Y924Xv6#>Mu)+-&oM(_7MFcK)EUuk%l8c*f5;pAJ^{aX!gs8JG)Y zq-nF!OEPJ8<^X#Xu&gRoD$VqCi|Ei}`O=d8AxH}i^b;Dei@8dqX_PM}h z_Wr}%Hb3Z(?SgsJ`or1Q|8-o)H#02c>x7s!Je_)Gu%GjYL0Sq+S%*A9N;vt z_r0i>Q`z2kc*R~n{AsV}B97;6xq@j;R~%=^KDL}8SGU)D-`(kM`uaIj%&%_FX0r|U z4@<*hK~9!AUKjJtCWbq-)f5y?A<7qQFSw_h}GUtElC&Oj$39J{N zNWade_2$qEa%ed7xz#jkCym*qx{ZU!^ZX-o?qzN!C(9`LR;Jv?e%0hqxk<)I|NZP& zTy~R-)nq<)*}BIY$Idx|`mz_ZibyI!aF+qg9WqT}D1+j(DVYd;c+AxJ>w*xtF{v z%e_!P`BP4R$-3Vwn&TafkiPGk`^jrE{|DA*%ZwkH!{k$0?i1_b(&IC8J9%6t`oem- z%=rB5^+=B_%>HPGO++xce<`b_TohTRC z@`n1hZuFWhU&yT|(_8YmU8j%wUR&;9JzL(|1Ui?^e7LTCD2xek9+>F^oky|w{Tvn? zfn3Agxhy}8Vm@NyLr^dJ7xRV3Q)0gj7AQ}f)~ET~)AKPj-xIp&DUEtYuRf<;U(rRc z>4Ud4#RuyCk)D$6J~OxbBEQn6-{}1BH2eoW@>A`<>C3oyKk&TQ+I5WZaT?kuEpxGtX#F zkF=oaThVTEcU$Jf?dWiMLpEv8dX5hCtc>W$T%#*3*pm*BH|5k`tk3ODz5CF%@{ugt zm-YMdzkbYXhtSMJ=?$5GIP-P6Y6P>_NLoP-kcCIFUSl-vD9?m3r$0>F$eHr83^~H~ zY4VEnI?8$<86#^QW4+-C8Y4rand_gTQS#$y<_u@)KIwjrd890Sp82rcew8`fHG2QL z@=f|kF1gJ-GKOw^NaH`FKV`ZX%x_;(|5vo%J38z=o&AAs|46rfrhC597T@UE?=<00 z`bE0`W={Nv=5{b173*s`H=53!-u0sO;?k#bT`=>!1hicunmZ}2m5eS=PRFIBty9y^ zY3Q7^^hriKIx|g?m8Q&3Hx;54iqb?SX;0a{3G_yU`~5Ju#7z)*mxu!f4iU4dJG*XdxS9` z8b`0n`rDYh%CU04EN1)Lm|qPWF9>5=(4jV75V`6pygqBU>&jrdNA$f+{g^q&8`@G1 zmuuy!Q7=}S4w_8QgwtJX=mU9gEpyy; zG;lr5EK?j{PH~*>JVRf|ofnt~UZTY>)2;H4ta*?1i?YxI=9{)Y65$HC{1`c#?3)=%WtvV*Os$lX2Y2suNpk}f`Kx9fkf}EV)t6t-yNW zigc;`)Qq`UbK0dRohUO7VqO_W56GHhnLAIX%VZO~&I#{FSGiX1mFX9<{hiFen0dTR zY}*@5pU&1_SV;C<$vjG?S;hR1{CH` zUD-`elHu~0jFGW&@;A<>@pszh2kj+a%CtXOkCf--3+eWY?V07^_}Jd!^E@egC15@% z0~0d$kjWA;ca^ykGtZSyQs&7rcXHG<09?*1=g|cHZ0l$+g~_CewP(`vOZo$ z%RRPVhyKq8(D$<9Am%!9tXwFIk7N7T=d@{ZybqX9aa*5ZiF9<_KlHK8o{PCwZW<#$ z=3%~*m%7;XhM3RdV${pF1IS(E$kxnn+ELf`G?jF>&kz0g+2;a3%i!P4xn#Hp-cPi* z>PVM&qrKkacX-tEe4u+gF+Lr+!buuB1>?+-56z~n=h7?lX{klD=qB1z=Gw~q_#}N8 zO;_Kb1#i-jTeS9Tn)w|~@`YacL5n#UkB;Y&E)IPkmln-L2gvc+m~&^R1#{BZ|IpQW z=p}im6m#tgv|$}ONB&!nIkXX-EUz_YF4T%vlxaINSLsUAcc=f!CHq@6~qg(pX;R9%e;WScy8^b(p3QaMUCRsqw zE~Xnd(zLs1!+mt`8T$7s_5Vs6J2+2)=f5(LhP0#Q`_kI~(lTK**3N67e^m#+E5Vc< z=)KPLSywu+8{I4mc4zJ?BV@l%tiO^&J~OYAtA8^W|3fF_$M`cmZlAeyeRGWeLB3?; zf#95Y7`F-s#;0$R(n%TUip;cp2+fv<*3M7;XVc_!>0Fs-J@d6K^zByqdnettmwq@v z1CP=l(X`N6TJahkd!1eg!0&K)zK5D(dQ`{>rgbhd5hv*11eb+O%o zZuRIVUu>t4*SKT(glRnK1uwePwgafw^rkm*(0#Vvqdv`+fA~E{+V#uGC%@3Vc3nR5 zq7b^JDqYiw=IKRS4xtTZ(rT+|kDYXQB)xrsdVQleT(Nv%{v86SmpeXZtwRg8qBGml z-S$0%_Nw-Hk6oRt_B{&2Wht8vawYrTgAMF^4kpfr&kMen8*TkWu59Zgbo&SI7wlli zpVfn$i+0=xo7nyWjO~v70_bLSmtbdyoezOGVrVHl{zu-E437ubb)h#G(W7=8iu%nJ zbcG#vA{Vgvb#!r>*zp*AX7hzUcH9I1wfVxCcHRKKw)w*)J!p{aCnJBe`9nY3ABMMW z{;-P8|5t#Mw znVLqXp@%ck&ROU!J5E8rW(BE#5t@4;O>fU1?Y_2O57XN7hZ9`z{NY=B9q@u3pFakR9d9My$7NN^jbE z6FjdRwto&Q%cios93hv>t@4HRwEcKYUr5%MwV@AcK!|hmxt0nGQ`dwp*~FBk=^Wk66zJ_&^ofl zYUcfR9trIypA*EHn;P~sL!A6%iY<&mq*SL9RqL2kUp_O>@@pNI70BYMxym*8;|f23JuDcSN1 z>z@L#y+^;eK{S=jCo9W|GNT>u+v`b5XUVOpn9JGq)M&40-{)_!oY?q@1GtZ&yf5AC z_i@x4%O&B=?`-@8>Ywd=E?i>c2;g%Wc#yfEY$3qRyJWy&_A4T% z$bHi52-~yE8ghwz^@QyKPicaj*dE|{7m+RHSh-f7mT7Dp1NuLaKDn4fWNq13KKTFk z5caDr`^u^{Sf6O)95CNcooS*jw6q*7SIeu?(|(`EbRi>XU72Jeb1~UcdfM;T=$}cJ zm%A3S-hL51AfHK}#jO7$>&szswe(xUeix5p`-sQ+F#+2RSYsk>ELTgvNvyAwhwZ#M z`hSx%H!|0>?H}sDchCYm=>s{+wufkskY2l)qvgK6%*poAnJ;OjH*}4h@Rs?D9QccQ zvpd#9%)f0uI!#Wo?F#B4sj)u6)^f7kDR0PlY1q$yGM2xIah(jZsB9$zZ2dxe^EEWf zR=U8(ji4T2<3wP4IZ`f?yX9s1R>nQX=~BxAvWXljm&k82?Qu@mP7aYv}cyt^_&3YueMsXCP0ME972zQ9hTIY}^L=2iv#}m_wG4jpcaxQ#P`39q8Xvj+19? zeM7y0jqiY$ZT*2SWx{UE#bpE8OP;s&3;jRHceef@drYR8iER!wgbfr&VJ;UP{vh@cZkukRZAjjK4w``;xZ9PIgnXNalp8P5o+xmn0 zMVa2#ALNJfuB}JN#cVyY>21A%JLG&@Z;)N=_hdNE)*l#U>kk}i>kV8dSKIo7T-MeP z*k3M}$K-Q4z}6r1D`v+#qrIF*@_ z?DmuO2nS2E6)2GsaX>^0^HJ$mo-KP}u z_gp~B%Ly{nzVFcfQ7*CXIb@ghwAf<2?k3(&`(<>9eO|~_UC<8a$b@l}WdT>_)v~@D z^L1I(UHxTW59V+gD<^rfp2Leq%0zLMWwA8OV`W%6=Jx4n*NpV8?4Ol6Q+2vmy4vT1 z*Oj{#{brvNa(I0@ry;H1iALJzg!VFhX~YQnbUZEhA5CbV2m1Y#*Jd(joJ&jCxH+`f zv;79RM|NDwoNyTpx6cLbqc+e_GQ$?;l1uRUtaNqWtf0kq(AC~(N4={Ly(@qFGA|0C zRRh&8h~@~UXJw*z%ul3WeCDPyM*?O)`+oyG-VhmU?>BPQY--O=i{+qiippYiQVDuJ zlolvU-&dgDTG3f;=#I8D(zaK4oY)SueMfrMJ|BDhezd;b_ZPXyFuGpm8Oa=OpBvgU zPN0)y#0=(sv*~gB{Ln9jt!J?5a=KbJ-N<}dHr~X1Ycox>jpo`xA1=k`^)K$vVe1=o z?DK1*hH znQJZcaCt$dUdMV5d05U2xA)z}dED9BaUQlS{ciQVzRp3*@KiTi*!EM~;=WKVkzr(a z+S=;n0-RsA{|bw5psnrvA@bGTG@YGCM4n;GIm}s+=CJQ!Y`*KDFfy z{bsvkKLc(Hq&IE91396cuYjxUeqyk{9rwbe_WWjeJGt!n!Z3O8U*w0TM!4YpM?JSI zofJTK2htw#Xt$ztSxM?wimtcUH!Y5H#y)?T&&Gkl-1d54R~zpIqwVpauZ?Sh|Hi@e zFlR8`9G{-E`89KQ&SL-21^%`9!LIgu0NiEM!zDI7%S4dz zAV0R>Yv7RS^nx9)jrDg9*zyin*z17pZTW&AOT^@3xk+_cn+-vu#gL78V$kjCM z8hXL*Ux)V0b{}GRLawv>*&#pMPTTLG-(>rp%m-wm2<9pBnJlr3_42#vU)g>SbEds? zth^_8?PI<9etJS?iqv#b^t!BmK>cL>gUsg-(SHupDe|2h_aDYF;B`jGDR#ec(dS z$8n)cYyh?oFfxv_$SmOM?6&n1##(-f`*q{E&!t6xQ_jYT!RGQ`+0@!o;r{rR;VyYe zPO|nD?oOl`>g8;=af|SI68gsKP2C;WkI1m0?H4o-aJ+3l9j2CbWT@@8qaMfh*I{B= zOm35xGO_)+^vlfLOJ0(>v#>s0ew4McvVKU`YQWq}UHcHSqsZ z_B%CPVB^MMK+{x?OF1v6oP96Btv~U;z+d+JFbrr;SKBy3B+_Z94J-&638eLumcwj9E~iRlr0eB`wDdkhS-?=4u} zo)7$L&mWG%`{r`o)w$ChCh~PkWBBzAuo6**FNe&pT*&I@^56*{{r9bn_WQ14;mW2{})wQ(}Yz2q?) zFN1tf4zh7G$aCaF8{dT--^S6v5E*FWX^?Zt8nUE~uR*1E@{kdybJYi%4Ea^5ktxs4-3F1?Jlmbun4 zSCo0$VVny3J@`VSztS4t=wJES4dYnQFRP6cf+=jA5UefB*?1x3!LqxJ8$wjB;eJ7L z;0rJ3>1KG;-wE0Q>$*6_cVj+ZU7Yi;>AW}8{Vk1tPyIg7C9=y$<|*=x3{Q&f7v?u8 z1wCJpHmpZqG@=_@({?s40R0o&^(gSiIhx}<9WM)y#Op+R(0*)RV4GUl9>9q*UR~xe z*>oiHE4g$f^Nm$Bb}Q|)jeakU^$zn3E<*>6pb;bKDe3l-xw`!GiaFnFy4AhF|K@XT zFW#U3+?`(g=tWs!KXZia9LfAf1|48dagZiHL|4i*hnZ)~pd-v9G_!Xs9gAjxztly?itPfoJPoUFPOW(q(fg(FIyk6{PdJLZM{U^Bm3FnHMuPju9G+UPg^;)(SQ?Oo#1@!qtf4=wCV6Z+Ev0W@6p3uNva zkEXWuAM<-snpP`AJC~)m%F%ii=vVolZ7(pLYh`+}3VmIbMpUEas?%#Sq6TxpTC{j= z>QRS=$-TDy!Te7&rk+h{`DS!%bDF6IeI{48WUkkWdfN62^LZ-AwqefHmOhg|?0t7} zoU+|ehp$&*|H%xeDK^mro9UY!bka^*Y`5G)zeLd?2kD!`wC_>n6ZGmyI^-;^drs{a z>7+|E$5nb(4!Oac?P4J3td`n~B z(M7*#*WYx^A6nDF^&WWNQn}J$ZZz6m^|-XAH!YByjz~$}RN3IQENB&%J>*+eR1dq+25B-Dq0$6b(B~C!V9F&(k6o=_wh0nYqUm z`t&Bvew%)KNf)|c+&`Yj_PF$iFWurt>m;VTl2Df-^t&t-%KWJ;{bJjrnfP7I1?vl} znw~DV`!OKDZ%>=W!*LmMiO%#-I_w`H-)%zcPse@&a_u>E;s)x!h1R=7Z{Mbq@6z;N zX=)ej7hw8-lG2eWXp@vQLutCAA{|zrj%Y}CHJ2@DtuFL>H=1=U9W9ehWF9%2PFY6} ztf$E~(JWhNMcaSD^ZT`(y6&XuBIGW5-NAkd`aK#&mye^fe_=l!_2ahR4&T}SI!tW) z<*=0PkHb#39}Z{u(3G+GeDb?H8|?jrC9l$fR^RI9^tbD;VB#0_-7osv+WQANE`MoA z9DI(*-{c%u=9*dQTl>7xUemVMu!~&Kl{r-pT2vN)&pbUYmIw5IVao?x+JRQ@NGI6x zf_nKbv{+g!FUa}Q(>M9)r-F2kjUPvQ|E9EMGdidR9W#zDoPpPgesS%%7tYy8-R!zD zIh+M>$L-4=!iUX3HzuYuoY) zBR9#-^sX(ps86xw70%f~ciD1_yvvqbnE43(d6Ay8>%LHL|DK-yPLuzoYvN#eMte_h zI>(%=hKB)d)wc4<#<_N0pj(a6Cxcr=|jhK`v*2hOL_8);v= z-V5{lZ2v0*BTv%Mt8~>Jdg2S6^PQ%%>%h=IHkcOeM6bx}otgc5(mO+`?{FG4f_jdk zjc3xRowQX1&13659;dKf*9Bu@X^^e|R=4AH*xI%OaH4Go;7;2Pz!=*Oz=+*Aj)lIF zG}4Z5k^kCtSFqG^I^hH@d6ll0Ep9No{lWI&q>t0l)*txUwkz1-T})Y+})98w&fN%p)I%2!UtFWNysJbJSE&J2iblUvU8f2xBV&Pld|P`<{}qpyohnS(>&iL;J|Fa=sjD$7Se0O*XOPGvw~_ zsoYwg^^SJDhW5d7igdT*H`L?Hbn>7)W5;!9zir2L@UI=$!DDt@2d~ISvaTK9q25OJ zmQQ4K4YvE#q<(h%hyK}RcR5BbkVj-qJ5EIZ88U$#CnC?1E9EYEO5T;PwQk8l1?f~MY^hDjL+w00{sZ74c7-c-Xp^Ne`5SmIw2@=XOZi z9U3OlG#&m&pf}NC0*QmoT59t$!yrzBpB6(qw2uVe!qunFT;gpa0 z)dGyS2c$V&;*(DF3Hl?^$sTd%Q#UfsjQ1?YGlewX%XqL~e*UGtWqimjsThyO_v~mf zj})MZ+|r(Avq~@e!Y;$;1@vd21?+N=Ucz_NXg6Gs`1_AMQi6uiuA1f#$S67j-&v%M zF&{l^k)QM;;V`*FvwP$@J?@m)1)#?($!Pv?DMB9wq{8pmFYReF z^cSNyopO}U!25eT-XU-4H;*JK2p9VBJrURx?WpJlr?jP6z0!kb!v3T0aGcSmAvs5@ z2jw;G?v(Fz3fhseeE)Ju8QQ}tt!aP1bff2OGVQkkSwx50X9=}-N%eds z^;j70r;vXL%fsW6)V1JQ{0|kauI6(#;v!7%WR=5=VV>HE8~bG?y%;Xv=y`|Ks{6-{yMoU^`9j)b-?X;X%4$v$On@B3*g zuO#mUm*V{!z3;^LvEdxMG@~|re`=sQnQ<+<%%M-vj)A_!a_Px{+@kLT@`z6INz&f1 zlugpnuXbrd$6KW>{bG@sbcRnB(fbZLPe=OY2F(|cs(oN$^h+|e;xpf1rbA;VdIRlK zX2|w}r0H;78w}GpG43O*>XuSN zU>&FIr_EiGWGEaIl3sK-%8`!7_#nezjsV6xf&~I{ln%mo2ZzIxewjy4;Cof{Xh1TJ zfbG4~jYc|T5X~7O<7iEb%%Xi=5=A?pU)S&0E&FK>pPZuAopOz~4VQ=X6yAH&5pI!@ zungWq(5h&^Mhp2Q1zjAFEOfV93emg~QjX5S`1jOemzJ~vzVA!-dSwVb8!ZHIP0G+{`3(EV;1LMu6C0!@njMK5^eCv|wmJsOU+NNgG}T+U5WOE7M3l`6DK znAE40f-;UC@XIV3?U!XViC^yh)+*7o3+mG`Faq@oErst1&~kohObcLqPa4E`)@i>8 zc|hN~#XlCl@ri$&8lUlL+$S01GaYd%#Vhut&R6AvXgqw+VhUV^=XLrdC^e?Sh88(N6NXEgX)r#%pG}M7y(#S!E(NB;3~1L# z%VJ!N8PJF4LpstT%V-9>{719dB==0X$07Y_9G6U>m3=aY7P3neZR3;8biG6N)5rK8 zCmkD*YqV8J9@2HV->2a&`Tje$iE|d>KWq|{&hkhS+R85(=y8warkO)hivH!0TC}W9 zn$pH@iKJWc-ikH|lL>TjB{v=Jl4A6*O)Ak1C_h>P>+?Gu@1^Kme8-Ajx5*T`5$$H_UXQG% z({TSuS2@K!PkqdIbwJ+I#V+|t8{+%PbJRtP)KrYER>?+(+oe4fw=ANc(4LL1$NLCc z66gP1Sl%PqXkxzr=jyavY+b#V{^Ut zW87z&#V%FoHkZ_=P4L`Ezj);Wt?!VJ^ko>H!QdQ^F1=_AeD|If zL4PFr55}LMn~L^PjQ^3jzRDMg#&`Hl{C$gSVv{V%N=5IgtlI=6&q zNh|uLL8nvl(Qf$u9^L1Y^>m?MuF)O%t|FapL)`$Apq`+MEz*N-aLF|K(J80sOI$~3 zS+u{UP3*`EGub5xy^7OJH1w zcxlTBNk`i_Bp03Rm1=ZdxHP0=Ly~kUyls&kv|&)PE`x{h9bEb-LW0ZTB)@c|H6x_) zI`ul^-4Rka3U+bIb-FM@(yo9X!|>gA_=jJP(<*L>w-WZWNGtl-Avmq z0^g^kOTwfF-DZ=4^gq9hqE|5v&m?>(JoWy zDU7p6FNevmP3lR;eegbxzP8D2`ra!s)<9c863|0oQk8bKOFf!6C?jdx2$@8$yX6o~ z;*e9cH~Q<*)_w_J3tc|((x{Ncq7@=!CVhhM3ejG8e@=bq4@J}Bd7Q^dkD#QZ&G4N+ zItJxSJA~uA?eG$wN2wo{L9@1<0?)Q4w-z{ZntDsb)&%)$ynmr&r=zjqjNUe5R zKud+>I2~@4|7iPgiMIi^3rGQ43jaq@Z%7)`6jtd=BXIqr&M-MdQ=9LD@x{2IUIP?3TNc&Iv$$mr{Te3Q=uPy`q`AW6CXMNlhcr`!I5)#s9?41z zxTOl6it*iPDyMX#u8{Pnha57CZVr>h^a#F(P0!;yZnTV79?-VkK3!}}Omg7I41@6eIBFZ-R(FRkf7pLC&Cv{RTIrVX9)jQQai#?5VVjYi`AC#`OikF=XpWH)>i z6gQ3ZNlY3W^%Z?=kus|7grVPnz8VA>vy>OjF3UfVR zZLSCWi|N%Pq!kT>B#P5vXU2yxjwbDk@#X0{uWYBg(Vm8;w#hrX&nhYQ!M`k$iGB!5 zZaM__=k&BguJlHE!fuTBxFnh$3YU*`KK9#wcmm@@(o%NGLx%>XE-e`@Bk66NhxA#v zT%u87Vm$!ohl!tVwn<#t)FQ=bS(g;xeuNbmZ}Lcb#;_LSc{XWuNR62W+l_c2(=%YZ z>4pet)CT$CTE_3Ja*_5xJx_a~y%o(AE;9!qAG94rJSR+&(~1~BhsO6wSvu7%&junN ztj>64P&(5kxL={iP(DZ0&5T?6C0a16fpO=sAoBKJFN!Q%psVR|o*Ors8mY^J-zWiS1K z@l@#pt30MTJ!0j0mkJj@?c$aUG%xNaslzR`XflTkpe60Hf`-E76kQ!5SEv*3U5~=j z;gW*pcSt+U6P(0$O|bDM zwKdx{F@1}1s~Y>9y6m31;-xy_t9m^i+D%}-6da!#u3MpgVgDh-DP3qU1BY|{%VYd? z<5}YnZV%GaPQdoS``j-0q&<#5ShaWImihjRHPf{G)4Y!rRdcbw9)VV{{H>1=u z6V#3q)z4?u(cB))*Y=5e_KUiU+k^D2f2k*ns7))Va~i1Qxt++jYKwY@+lzSMKWecP zYSWi$FJ(36QCNSTJg6hOVYBbAdm|twy)ojK-*AQ3t$oY2YPXiA#?u+-P z^dsJn-h}7EWb`dK5Br1H37DdQx}%u-ud#4(jfeJDM^->NBmY_Bmxox+T(>-Ur`~!5 zqrFo0iCX=s+UJ>?_AyNElQx_VXL369Jy(l!`UJmhV15{SsdnZ6D2PXPRnv4+T^wf; z=>@*3t=L}?acZ_}gg4l(5f*H!PXDMrHs)YIN=$#w|AS!CaCMaNm{sHET(2A; z4fuO7VIs^AD>qVq84IxAA<|ENQs?n^5I6a%-skoX!uz-X)a) z%SNkHqtwZ3)R}A#i0SVA>bX;DFZR|r2Ro?g z+0GUD@+8Ing}E}K{9uwS>iG+5+JDt=uhhhBr-^+1f2!|&*lxrJlc@dDsYMH#xTzY| zLCxArt=vbQI#I1YUG1=5eY8zIdO$71^2P5Qy{Ou6sdrg#AU%@x2Fwsb`NC&x#|WS7 zQdhJ6BI0dF)c9<_h3n%_9j&}t96XN9U6DttsZ52R?NTkusVR{jM#EPop(u1_ef3rL9Osh?GOXy zjr=*-o)w-lo@KjM#I}y=8MbRh{IkCrK2ZHKNUg;7ftbFE?E+!Nt?KFB*e{6FvmGjI zW^8jz;|&+pB5$zY!XqTZTlKwh%6pBcd@z1g$9z%`e^xJjQ4f4m<9vk^ENF`XTiGPh zcQ_&-8(!nO3XeE(9-X&KBA5Ctj#@OX+QKM7#53{#kFf>M&kW%*_>;Qev%0W3&PSxz zZK<9$mYt;WmdR=|8_rkcOTpiJgK+|Re#5k_)bBjc5x-6V?|P+oLiGsS7X(A{lI2`FhN~)GxK%Db-knNVfzHcIgPbvXgp}1I;uG4 z!}KpD)Pfb&JXO_Xb<{I?k-xH2Dn+S1R;WWcuEnsBOfk;lbrTy7vorCTVBVJKF+w#c-2@dJ(i2E>*ws_(lGlE7hGF)FzwE z^am&pOyB-cz0w)!Grf|d3p{9%o-99Dp5+I#Sa80>xtv}oLV8E5GmU2wARp4l@jQZy zc^?PEd7oIxE3+JkVND(f$MHXZ4|oLS*h{_3dIzzul^V_TQUMX}kAM9V(^#1~eFy+LYyt_&Mtv_}B0DPWT_KlE!see<8i! zCAG*Ebs3kFCqk^;k8muP181bKWz3F58e$kKwSRU{l zuS+mvOl%*V#OY(vZkNvma3t@8VIy9z;8Kng0&9I%v;0u&tib&k(p#-j`#i&Pj-y|p zv2A($KH@t(zu=x{>Q_!rhIZM{;TE*38;|`8r_RRj!K1t`E%(T`M@WaglOi3);qev^ z{d-$2Qy!171CK|T?gz@_f648K`Th%Wh8jke zFXBQhUs#Us#o%q0FPyVjZOd{-Jm`(Ojpse$x;NE~ELX(cc^<%YJP%+OKEK1XJpSQ= z1L`BLe{Huc;Q0%CXHYFJSko&b>A`@+bi;fWxy<{lzr!Sw_gT>W2aLk^5EH2P_}*oL zU4-{vPc4#!76_C4bd^OK(P6kBqw^zV1-)XCqcnb)JfY9g-aLu=B&oV5t-6%=ADCX9 z_iykp^X0~Q%zS_Qq*XFC1%2y~tIQAQGCyoHQcalx=8KSHe4c|NQz2gBmWh+Gzu-@v zhj0x0)xt09)mdREXTEP^ujO6tT_T+RJsH{Hc z^f=*?h0B5Uxg7X|`CyROC3uC`JLu+qS{D!-_tO^i&&>?8IpjU-UD$>7EwpA=;~5jN z-bH!>j?)gSvEGI4I6X6-r#Ky+W&Hw&@;w7w%X$Fr;&}@nGr!X>E0`ZP-h})xiq}IJ zc1Z1dSgp@`5$Uyf9>7bipI~{1`rWCXa;eQ&Z((}=Kh#~uYOGh0zA?F4C8e5|&oM|( zmqs0Ae8qYV>3{M13C9{!X4kltu}5)@Gw{4azUZTB@qg4hm(-<~)t8UdTRi`e|Hdb^ z=r?sfuTw~$kyzbioSIhS;#t&D1x&scYMf5$!rtmE)}vU?VxHfy#2|Gq-}@oXF-4s) zPmRA+owZp_$oJaFcZ=@<;d^7Pa~co$s76|F{A2o#pt`xU+IonZYk?Yjg<6sC1(Dyv z_k!^JQq&`G9>13e4;t^X{zP2qth$@WOKz9cWq)Nv?Z^20&|MmK_DV06YxHUjz&MLTI$T&YR!H)zL37yc%r|?Nd~If zjKz#CjWM~L>=ClixZb$ic+z;s_?*i}{%%}89ATVcj52OFe&_o2vP$`nY97Ad|KXPS z4b-;A%1t$HY;1QM{Zx^!F6&tsoAoQq%=DPW+IJL$Z^<3up3o;ROB;?91PQ zx%oRV3%3V0;QcK;&iSW#q%5}sc4?$GY@+Tqer~R@zlA!`n5UJ-w~br*yI9U3{vK@F z0OO^=BR8&0IFj3qxGc*RmOqc*hY7gcflg`2d~hf8!7W^0SeN->Cca09<@i1pF1(~h^SwIa zmRwF1q;om&9G3%6ayhUgmjgR-ei+U9;l0ah7Vba9Q@EVrHhE&4#qC9$g~tnA&h3L; z`2G~0o`&VaQoJ98_ajkWFm)GoWLLF954C?U^&-bVM814O)l#wW`-rE9&|e$gU_JTD zDeHQxvAe=kI3D_{j$UwKKu&UcPP7N=15;Wg))2TCtK`Y??hc2|r3|hh`QFIpGN7Jq@IYw&+g5wr`U=>w96PDcAA+6nEF>860xqM@L)q)}+!NUNeBA5H3&8T6`0 zqNo$^Vd-G>ub|P`UK;SoQ~Cn^VQ4zHIMc$`Apk*#hDHs#dw;uVwj|% z+t3f5X2Sm+G*(E4(2i&qPycnw5<1NvYB4Mc;obvPcG5e zPI*Xuc&?)R@%tHI+K|MgyWEn3enNXPnkOj5XdRbSqqFe)Gz#@D?S$>8!||PCnhNa@ z=|i+Trt@8Ln`ZFJOIp+_Kj?9<_%gy%R!K+`qJJ@65Fz<#GOv`U|9IqYn!+RP=mgv^ z&<}X-p%H$WOUpQ94UG(!J+!G`PSYw8a+|vR@{*P;R}9E9`VHf}7go12z8NM*X-Ah_p$XBx zj0VtNpXLvVJq!G9m)P_i`uEd*cwbGgyQBn7;FTJ*jz^l)Qx@q)CwgTVy>7=iS#Ub~ zxzVt2*-BGj9DDi_?aXOS^y8z=@ZAU+!zcEvur&HN(!ODmlqLztUSk0|)FTz>KQ^gP zfBB?6E$x(k^nJLDqm@E3j~21WTDs6BXJ|e252Amd{Sxiwl0W0&z6~Z~IZnlW6J3OU zj5Ha>37|Lp(ykCZjef7jbVU)*w907Xx&a!$9;n*yV%$MYZ*WiTYn*M|Vf5VB>1mCb zqcvXoN}U=P>xbnOPpIZfs-DTFj>xV~%%Q&E`V@9a|G(A63$Yx;$rq`cjM*1!e9<_0 ziN-OOs)LuQ;mg%S#-dRgcV3~sGj?97@x@hYytQhKBkC37yK@>(KCiC6piaA_e!QYy zys1{brKY;0R$#eed-gt6Gd)-9v)q{eQa%1g?eb2I@j%mmovr;LwRC( zGn{I2w|YB{dNY~YFuD58*o6Cq<<0#9pBg`wLpwmklWMC|iedj0a>|e5YOxvkeZ&uE ztJ~+Q#pbCqAE>{K-hVYtZp`#h<3q-hk2UW0L_KJ{X?$(8u^jQc@r{{{H-cDyq<=SV zPoioa!_o?Ahw-Md}|*)%Hej zJ;V*sK8wdU9LIV9MjTbw@H|Bv@2#52Sk$=6c*yv#@uShj^BeQeHXb+LGQKi~z1Mto zjh&5?jmwOWSRY_{-;Lc_A0Unu!tn_UuwD&?B%-N$p}AVMg_?rL1E!B+zNYy8JkMXa zbDjEy+mE#QF^LJ>&TX|KW88Zsv6cK4m=z+pvCvPM-I0P$qR9&u_#td49tkJilRk z)`Kt;>p%F;n6@nHKg69`Zl~R1y^igG-d2dOIwenQwQn0WMLYGcC2ED{$d7!-jsF_^ z@Opvt_OGzVUp4F|HvUw&;R5I$YKme;CVjNBRt_3^gVjqwyG?SN&b`Xo70zd4u@+4J;3q z8;3YcKsFogJpT}z3Tk*Jp@pxRoj1ILVj|;?UcwE3qJT71> z9v9HZ;{xvFaR68FIDlukpW$}yXE=iU8MYLZ8@#<3>k%C$9p~Wv4%}7~=`acR+atSt z=6Kf&F&_AN%m+UiKU~sy&lR=IHFcIT^18+)Z>V{1s-uiG?r2=&o;uj*zOQjpW8jg- z`HhE-DW7P1b>kyrzZaUm%9t%$YnFn&sXX~ zW0LP0Klq{M{HZ3gV*g?OD=zhJ0`+GiHA7;xj&X!>tFcu|o!&6LdaIoJUwJimMfG?! z^?407FUQNq@5U(tV~6BV8VZw|bemtg(+?h*PTN{!8$IfjtMm}Y8K(8|{kNj9l3o6! zNBvTh=5^!$2e>96)9Ive*+$0%QTB6--n!~ zp5%FqI4|So=oiZC1x$EXy~yVV#4n9S`P_iG#WS^^afWfD@h$I@k#Fh?b)E6J(ZTy> zOiyJjWE}LLrl;id2&NY_24kSy5bvFX^wBQ4%;yZdPpU6c9~ql1*4Va0Jz^}rRO2nn z)SS!J55}%h8ZTX;rd(-aqiwaumH3>2-!0B^f+^3dM~o*gnD~;JepR*cxdQoz8q4tc z0&!QCGknDRU|5~y#(aFfU^>eMX5{k$Ji_M#Sc%UEa6no$W;!)vMl~htPfVY~>mqEx z>mmG;&u#D;uZu8cc{Pg935cz{Z>VpVLt9`Ei{#*b&mNTO+^_H+*AIT+`oT!!8 zjKurRM`{COq;a5elJSo5moe~I=SynLW*lc+XWVZ*Z%p(==PPKeWNc(C#B#-YwJ`QD zUgGxj3CKs|3m%tT#e$Y&xjdq&5;TrTurnQ~&gqHP)V-NgnmDDuaAth-x zlp8(ck>PZiTb9$OxUSNKXh%Y4xx}#-)^JK{8Xx1Z(|q_2IPGnf;k0RlET?5d@(*2M zl_#{HT^##h`Upu)ZQ)Xq-n2*yI^QD0Y58zjPJ=G_hxR}}IJy$+zaIwdlA5kVJ51^g zNDEpyB*SUPpe(01eew^@8X-^UU5hvlz-rhZw2ECy(qcYoK`;AcI2{l!N9jk8L>z=| z@t&V%!uzE|usp^&ISfaKqn{h}xMeQAihd0=C$6t_rd{sPfq36`46b&{P5Kz)GaQG9 zT#|_v#5fkWVDWG%NAGx~Ev*ocF|@2hR{x%k|FdaEt7N|o>xIi&fl7AzMgTN0}!lBgLI z!s~bsokAUvR&7R~_@!SNn8qQ)SPx~zcShU7C0?o1PW{1nrCS1wVLRg><5XjmahLIo z@u9J8d!2uVajo&F@s{ze(b+-sr!bB+ZZaM+UN?R)1|oI7yvCZw9>&qedB$zVXU0HB zoj4KaZX9l$YusnNWQ^ZMms8l- z*4W=T%eck(z!=t5=Zj@bW2|WGU>swdZ`^47WlY^oms8Bx$9UHG!07I-`H~y!8OIwB z8GSu8Ukc+bW3;hoPn~{e7<_J%UBgxDD0T8^waYm5&zWkv8E^vnH9SDO9(ZyO;vZJ& zlQ2{QA?OK?u_)TA*ntR%ZLAUMI3?tF_&>3z*5(Y-H`q=9OIwD8X|pZMZtF))X9ve zid<$4TMkgyBi*tW|Nqh~;c}Y!dWgjA1(S&spf5x!QI|*qnn9#B-7fN!4i))IJ7T`x zaG}U9<2B=8+EZjQjTTu#>x*>Y`eYJWL4SyRqCSz>ec@%1G&G$>%FyKKCrqD+RO_$K zVmv}*SU+{2F~sRe-@@s5&ApK6@P;uXr}OnUk$Y0k)HIW~-bsuBCIsWIJ`a_;^p9eC2bAwfcrz%`b{rQl{wTzM`lRz{n8+>_$Ee*g z9)x9Axb&yRB4iky=aWC!-@t}~VSfO)r(Q_a*iY?qGta|}^u>{DOuS34b4@3P%0@(sDHUSa!T z#3R_wAGVx;^^CB~iB;+p#(B_QWVJeQBAnupGxT4#?0cfVt%>C$&eKM1!0&G5uu7xJ z@Vr$rOoivrPJ&iKf7o?uT(-BGfbkPqj_?`NVPU4%vWa7+nvv~%5%;~R=J>8QWB&rA zNA^?;vz;#D7_-!t^VN!6-uNKK=~EA`Q9T>g9h@HJk}R{}a-Y1R|5_yFQFYl{HSj}y z#(D{W9gP`AxSzFHWM`j&e2wmS8p+Tf{L@|l|No4U`2`7vK^hx&x=un})_ zsUz7A8}UoFzlL#me83JR)#Tg{h)2~|3pP*}@OVM`QXU7e!V5LQV3rU1>#{!xe8b}a z)@6SL*moY*>o1X!^P$Hg%XwV%^vKz5YPHkq>R0Nja4Z+oKk>MR9nz||Sl&VOd*yyE z?UgTVUk4Mj9UuI!k(z?XE8^*g)i-z59_$Z@^t;Q|=RAH9Z#{(dgw5D)5MJMe@XT;`GOd*EXH zkFgJKuu9^C>RiSR?b7>znm-qQ7xA{{>h6i^tC9F!r1xS!AQ-(L`3qot56)L5ApN<# z_2Kf^_~#*wEr->W#%IRzM>Kuu3H6gP;qU2wIl+EI>;3Z3c#X#?;{SMj!pTR~Y;50; zIPU}X$Q$+DM>P)H^<#R^#8`jWiS77d=K^ZRCTh|4YOWsYU>@hlcaHZNu;o1U_B!>` zR(0oob=*lc);qP+4|RSJ<%RigG*M6VPzQ`sUvu0JOn(rC;}Q;K`+GQ!<8;8jY%dLa zv%E&wWz$JDlIJ<%NbWDVu9BLtnmVekYU6&y^d_u#;6$D`@MAx$A6zqB&BgtS_$z-W zr&VsT-|Ya5YsvirbMtp$>htOq#y@N_g!K>n!rzC5FCx8UKu*x(_)f(owayha;xb(C zmIeutA8uy++AiHVJt@Y2zo+hC?89+-6?VZm?6fETw=xEJ9Yy>Hub;5cHJBz`JghI^ zch(ay`2cJmtjg;b{KWjXeX^4EEc~1G?ud}2x}&~-t?uFUejWPOVGD(g)+;}Pu^OL&ovl_wc0;a!6rv6t<&A@se>5X_E!Fb)& z?Tgi@Qw0%io6|*uMq-WV+oWZ@;SL zc^!Kll#IN7!49~dS^Pm6NO#+0B+V9(i8O6MX2Gy+5mNcPTJ%4d&?kp~srk8|GNZhB zU4Tn6se8G7h%d38fXP`;z)t_D6ECVG@2e|VUts!0))(;gSM_ZoYzN|PY1HNU)zL*& zXG!&LWA$=dwKvE4!F&x^f57&vKVV_jAF$6F^&;yJ#BcYhtyzB{{_m|?mh}hX<{bA2 zu4nxL7qI?-eMhK?Sbrei%6>d>C+iW|i1i4xvL1oiSdYNJS#Dp@Kb0nSNW3@juuBRV zlk)xraX*$PT+jL!?pcfZVH@U)cFQQ^ak|kVm3SP&;bF)R&$Awaxp*H56Z853$GtcwnuggV%UQBvoLuJwZKfZ$0*E?^vNHPf2~b2@csc_W&H<_@qPw2=6o=J zOEqv%U0NLTBRz2&H3P@DL0su0mY3WkN4GQ_-DXnaT4R4{(Y4 zs`q$bm(nZwtEl4!shKvay?3c+d43{aRWIVsXrJwe18njurkWt0nlBDKhxgU&zX~(( zyn!AE)(hIX99V8K_CLJBeyH#~=euu}&5hNKoQ~MR`=`-vvGY8HX}BC1?ZI+jW`1`N zwl-cccH{g=|IX#ZqFhc4n^d4BJTipdvdUaKD?+x=SorQ89T<`#+@6g-shvPQ%lJf? zBw)WgIG_C?lcSv|k7wxQeHC27^@l#z4=~Albyf+?hqxL0!NHB}ZwvSHJc2*Dyh|?W z!~5$!=pVq}tsjul^eV=yrxQKm<8|(XT~5)D;nIfnd|tmSNTzn+^Bm%v+0>b_@Vkg- zbVa$r9D~#yoNuO0Zqj`g8I=@H3(3e&xIVyqpVb{qciH7Qm!Bw1c5(TzBexS?N)B7Q z{RiyM^9+_=pk`jLw%?{+JgJ7gS5yB~zw-VH^Mx(L zdc({s)J0p>mE2!QPtN__AxsJwYa6>5XB%yQYrf>h!o~*1?#A)PLo638H#wiLVPWH9 zV<+B!F`eZM2N<^-ZyJ9Z6R_SwzSg(YWW4W39NAJGYy6kxhV*uTyjF=ET`16#)YRf-fir9UE|X^uwJu#vVrw9ypab!c8T?= z`Vg@tt4&JgMZ6>+zy4BZaysI+Os{N}CC1fs9NOD6ADjg(uAnr^hu9yG3C2MMHQr}T z{Y>Myyq`k8gfG>_gXXYa(g zRXi>VewcBpnl%#XcU_X1pMgZMizXj98g!E!QT9PEC`2aEH(h1Hl|58q>$ z2H#_R))}yZO*-vSKP`p~xSv4Wf$5i>GThjo(_cnN=&YLa9BhF0Ewm=yTk?2R@3Qmo8@cM!2PmI4}YV3=nUNOds zt8rChRD3g^G5H@FS1^7^sB!y5>ON!PG#Xpes>L#?(Z(2AG#+m(pH<^gMsGHaBaMIN z)c9{><=h&#%A=MkpeE;Y8MZTLG4-Y~PbrPhlv9t?RNK^6mvj7NmTObh(pr6GY|uvI zeC^bh#xcfo#_z`D?KNMs4radYYB%FiV|WiuPtW(!`2Bu-PJ(m!oDB~d-|+qwan}** zcRmLpo;+I3Iz}xzP91K%XY}y-6Ztb3pG?p=lJ^TpKR8AGG*fLlOTA?D@H|1jtGq9R z-50BtrD}0w!(|%pG2SpvTCV9yqtu4RVaB7zOe=JHEn}568ZTX|?%kxW=5rXNZY znDe}*S2H%cVDdj#ml~VA(D;#Y${US$yj6F7P&a&1dwfIQ9>-(r@`l_b~ssTRVU^!=osQHGe-}!z6>8E%<1K*BQyG>Jj^1TPr4;X)N zd=tdw*Q({VtDy_1CzIOc!wi%kw9Zp2@;F9(kk2t!d@|vh`jN*w;TR{T8`BYA3#bQ!YLOVKueX}9uR5IP8S+)YqdlQ{s z7^gdZvV-*l+|PXNg3|9_^}$2+9Iv0t@ZCsy#3>7sAU|xDPIXjL6R^HTdIi>tur;>} z&e^6;i&o3=`4Q>y@jPPr?vU)!Snh1}r!{Wk^CRLCeBT8Z8GrKn`yala%IgjM)I^>4 z73odwa@U3!_WOqT3;K)yfUEGGQ2G|%=lKbJ_+FJ2`CvCEY>n}29;gLeaF<2KJyiel zzy^2^#_MkZi>&5#7nV(+S`(>$V*=y6q?&%4`L{SFocW>0n829Pn9uk+Ir5zdNEseS zFmYKmdu#RhBenQr^^a6=fLl^>Kfvm&Ut!`5aGgsoWrl4XGVxEQ<2xe5alF8Z%hg>> zcZW$!ro-(_hZmVX3hy$Bljl!atL!cfOQ9VBwc-1bWndAJ3v{5!lp1QW^6&)4 zy{HH;;yXXpR7X`<5ARWq;y8l6I4(Gh&2dLyMUFcHJa9pMen)jM(+lAHhrBOa2C{HZ!7|+M|_#R(R^>41vxNw=l^?}v6UA-~RM^`nH z@rE$T#~6-bT+S{v8N(>X1wzt^F+9O|UO>h&hPk=@g8miM;+9|h-DMGyxR1K07xbck z4`Voc5KM=D>%(BD2x%}JHt|dGQ)=hu>HuB`k)E2**>D!GNAMA^H*g-yGi8LdmCm#CWbXENVyKRKL#9`m_9GWRBY<`CO$wQV(wSA)3gOT=5ykK>g(2L+7cgOb{Kd48z9K>0<92m{{@}a-lcQqmJ%N+PF(|foS{o8)Rwqf#_ zZpL>*d0z%s+A)7Uuf%t#2Wbn`2Xu!=qUlAHpA)9QI8!vCO(xNPXs_&o4x3DL!x|PT z=z+6vU8g(3q#p0v;6pE5;FRvmF`g3~=trD7C`BXSPqYu``_L+Qe-RVj^T;v!5dEBD z!4)p~OuKnyZfv*^-zTCcd=ljHhvGZmw1QXC)WY)NiwuZkp?_y)7!&=KZm7li{{`Z^ zWnrXSy7GUG>)|qn_6rIw&=|KPAQs*q!q~mk_k2%J1{GV-7xwTrYje3&zt4JTq?*qUA{5}92Iza8u7VsCuRX-V-5i%Ji2QucZ)T zm?<%0cSsuTQ+FDR9?Gvvecf0H2gTI98{UsA+YixhsPzDWriM@XTx>N?}33>xn@ zKFOr<>+EX$9BO~#eB(ajUE?of;+&elb8dBVUUhLkb#MV=A+=f&b*%BIadA;i?^0Y{ zV;oRI`#kwdT$KY(s-qDLmiDT z8{ZlS*46Zd#=XWN>>rKgJvRo~Pa5${W9j-D_cvB+tnpRjpG`C_-dyctoM~*-LeqP; zQqLQowbnRo8+A}yb+s{OdyR8PsymDoJ8FE?SgNze!;EXXXl&*9aoCQ`-PEbZeLXZz z*;75*SFO=ceQaDmK;uCJ)pUc@L&p8XG)_KTU20r3PUF=})jliL#cR~J#)4}#-fRq8 zr*Y;D>U!fJn>8+IbZpT$t?|+}jf-qoPaDVV)cCydm9hUWO)qpr-EZ9ekH&qDsq>7s z;~Ez+MxE5yeoAd}T3u{BZp?pH)2CllcNqI$(m3liHNg$F!5wwTU3J%M^+hf?H(XqQ zsx#SNA91yI>LBAR9xq5w-An!2M?Eq^{cLoMG5L&n$7(!fq8d3#O*mOSG)+w~UA4_n z7Z@+i(YW4X^_4NSLSxr{^{}zfIgO_p&l>Zxe6aqRZmDZn4v1&nR||9dqAnExd489a;pQ3d&yNC*xAqQ%JvKOtwtpu;pqlV<+PU<40rsD9v}8#~+sS z#Q4*g;Jl`1H|{Qpcq;xUZ;$H$9L4(YSx^pCQe*LaLhKx_*5iIaJeKZzM)0*~}$JqTB`-hyXYKfxQEKFTfgIUOco{aDi`&x{jUuOZIP;}TBqs5bAW ze(a%sy`|o52A^5wenzY(oIg&@)dK0?@qa&k=9LUNneLTdtUoJwqACR`pnBb-+ON`w;d1BsF17JkKD1%rxrgwCaki>Z@LA$5CqT z0G@A~!OMRy_<#`KZu)c=3yQ*z?{vwXmTaDXSt;6#b>FLL-4UJVM zXxx*>4W=J9elV`(afI|=M$2@K+ZsR$#pV zI~%7OA8@^q-jC}CcN-J&xJA6aKfDkjEk~=HcB|#Cs>yi%VtVbtFeaW)uc$qE-XJbC z0uHfAG>;FsiS;?G#d-tIo2B06{zTlG`xEx&euP)KA7KaXM>ubRns%4E&sdV{h3Rk3 zs*kxIh?}r{VVfsvvXM|wpK$$QS*|}EH4cUaCB)x@g*iVwc3a)U>&?yxSwB@R#`Q*A zk?Rd}a=l;{-Y>vc#$DSqE_hn?a{E^NkF>jt&LZjBN57NYaSsH7ySuv$1Q~pAXK>db zgF^@qLU4B-+}$M%!QI^nE`wYC*Ok3_pXa>moORAxhY$R+tE#K3yQ{tLZa0}}`g6Jv z&o|Go9>jmL9X%XUbg?>ppSqgUgLG#u*Mkn}yi5I^acUnq&wdJ%bGgFC=6G`p%eD29 zfUvAu%zH)1;kU(Lt%2d4j9-Mc}(xl?t!s*by+{(BkQDU|Q^ zP>nKobJ(0}VMFyrCw1RY)pdkgqVQBj50s1Gd!1nww!1Oja?Jf%YH#WAQmyhz{q#mH#QcVMk7^^d z3vOmyAK$5Xt6t&sAwE_Y`Eb^I#4!$upNjFqJ6qJrUywe>Usll{-jebw{OK)wIpN_TVqEOb)@+_>-p&}(dHj?G`@?;`ruO52Y0g` zc;8&e`Vf~1Rzr59e6W{9nMY1*yte@Ik=~}Pny#7}x)=H1JZ0W4%s-g_3gQewvMD|C zVZRJ&uZ(JJX0;;A-EqP9J`uw)EC<`N94weg9cNzUa7b@?9m9D#r0WN@$w&3jXSK91 z$|3)Qnbu$9qk(FZ#A+W-FUsvUN2k=dS6VeS$A|ogtm^MM)Eqh0duChC7nJK>RCOw) zPBC3LzmPwyoVu^78hH!t-RCY>X(wlSZyvj^@f&l(SB;aqV>pyc#pMQPvtHxP9{QD5Z&g?8)liGPL%Hd=f6IQ7 z9N!<}aIkv-^5NJZH7}Px;+kBKU;*|+=*r~|@0%g{G(J#BUBczk!bt{jy@FNU)Ja@E zh|_whTeyB97A}9dnZtzzN@iEYl*7R$<~t6LIDqBh_-`oR9LFs`;DSJzNYCIpxgZ~2 zXL)#+R2vsMs++aMH z#dgCf?4R%@rz^j&4B&7uD33aU?Q`JyUe5p1zOt9=IUJou&6Nx$#r;IK59VRJ;K>|n z-x6w#^6Jn0aBraOF09t#`iD3>=Np_+Rozhx`s4mA*T?qw{RX$+b6sS!d6fMRafd4E zD#n`w@%}RS9`8kr#Bm60{X<>Ge)b8!>#eQkU_Rmr%!jV*e_!w(AoFTX#I>9yq?VeC z`@MqhQi^`X_blmVyuX@e$99d@b;w}q?2u^M-$yRd@xBtp{VIIK__Bu_c!KoXX*6z5~BYfoCv%k+7GS92*Z$y2z6W>hmS))Mb_)rERbF7tWZ4(CjRWw4*v zs(xp@+)oPecL}inbhr%dVhl6Qg2`|k!{_p0iG(;n8t}S9vH;o7_%)uZn5)*li*&?8 znGgMDBYi)9-@91N$8^MXn7$mpf8cO1ANw72rv>p|=Y?t##$#~b$Na){#JSl&;hY7q zjjITcQ{cJ-Y6t#q=Yv1KZ%4i4F5TcQ`B%V^4tcRk&9)jI#QL@to`amuN_Y?LCfEVz zal7FN+~=eZ{3Ycc*vnHg?^mxJR$bWNkzSSK&*dX)52;=;aDt1JWjXkg&s)F~$Ka$O z@jj(yI02jbNsn`I7~b#r2u8X|l_kX!{Ip8_%=E=U(*Knj;)MQ!*q_^r&v@^HS+N+7 z?-9F{S9_c5D{FkS1C|5wr*%|IPFD-gRr73AJszvop0j>W*=-j6g!s=u@o_?Zc|9eC zn|dLe8kGi)!|xxqquuaKPQ)90WI?;43BFv6bi}uqo+wDpw?R5Aofqd*uzP;BWk`M;+?dAP2f8q;14<@$y6vRuF52(wZbjSrb=7Ha&G^9AK{ z?Nc9`a}R3V;ITTE?eX)HH@~UXxLgpYDFT=KORJ*l@zQDlmmks_mQ#!8Ks|^ZEVlvQ z+2nGB580n#OKvxw;CtTOPQVf7h2J$!TTT7T+|pO$P3)g2?>0hRU>;&WMf!R6Pv|p2 z-8fG@@{gLc5ZZ$3#SJ*=K2n&a(Tes%rE0AC%K-%`b*WDp2$Z$h4~#lrFI2%59br& zDV1OuD00JCyFz^CT@5DbsFLP~XDDz)}xHR6(b;k|n4gZgL~w)YsW!8p}1Q|+)) zJzWLk*@54+n*G=w#M^@~Jd97Ire?oIe4f)C;E=EN)R76>JBO^;fPAFa;QGG9T`tvx zqwzbfTI#hra6*s_;(7o*TdQZ;9}sWl{DPPML_N@#&t>(;eKnSYeGjXyoR5gzo~yZ8 z?z}U;I|oO&NGQw0{_J0HxF5>F%*E89CDel@)#lUG_svoMwU<0@sa8+eUb)INvpxHJ zE1WmqQ(t^k53;>TZ`}>?UaXJY{>}`NVLjk?Ja05e-Ou=ur@Ze;ao*lrZO{|LBmNPl z`W3-)L0oT*`pjH88rLO}-aib(Wx;oOhpI{Xz(60VYqt3nbAOEV>YTrqT*R**EafHV zMypMt)J)^l6Kv-eKS?(P-V2m6=2ULy5VuZ^`d~nLwYb^FoMC=6(^k-Ob$(yTlj^-uE^mvD6e=O5zjQ`B+HAA;k*78njb+oTrddh3ke-O;T0UOf9Z z9Le^>T07M=yVZ3M)uWHp2^?-}pgiJ!7{2*Ky%w%6V7`w-25|b|^mFP8?$4X!dIaYS z3>ym%dP^EEZ#am)c9*v&)t!vbyU2a|%?-cPRLh)Fzp|b{KdCStHpF`Y*dHF_yQG|c zSe*M!7{T$w=gj|s?=??_+uS9N>9C9o`ZKKIP#1WrU8<@cajHux^mCM}Sw-D@xtZGxucf7t2Vu-R(Y*v{-J(!!TAyDPvWMY_fUWHSIY&f?Q^TgKdLVS zaX$dVHA9Dcxrxiz)tnAeQKLnb*WkSxW-ves;kUHr!_8mSuJ-%J#*K}-BW`f zsX>ob-#GQE+3~5yrJk#YUZ_s5)XcBdif_~k@6>aj)SExm2xr{a!1SgYrgq?c4#Xd4 zsO->w9Z!uovA|GgOyf0=N z^u%=!I@?u(r>mt**I633XDlwV-|RO-S29a5-PKC^!s>!-dwm4 z#{smMpRA@|yu_2oH*0X7ZuXq7ary=7AT!lAjX!dJp?t4cb(<5~jd)KbwbTvu#Z9&N zEj8|^`YB$m&GSJFH^&^s@z3#*z8lqr=2eat>18=Sn3mfIxc<7@-5d2Gt{JGtWl$4m zRwvh14{$q%a%GlcxJkaU{*ZbtMy=23Li&8}=b;PFFX8TO>O}7M5x3^?4eZZ)ra8$V z4hKiFUC`l$eAtHjdl<&!YZ$Uu&AwlK%=(c2WEqBA<{|%Zdf|!v>aO!@;o&HU^jv)~ zzhDL4Z-fW`M!pN47donTx}pvkf$~VdW$yWe{*QR_a^#2m%5&P#U)HZtV>n+C2d{wh zab5Bsb&D(NLA=z>bXPBUsEIkBkbllsO&XwPETon#qBi0256ZdMP!DrIg18sQ_Y=>x zb38DFfdFaF|*~<^vea+vFzt4 zcf%}OSmWmAO|v8WC(0FL|AZTP-Uy?3-U!!}RbQKqavBfh_7eHCcVfCzdB}cq%Px%{ zbGw7|lATZvzTc;IVn0XR?UTCXiyF)Nkp7AN?j+t@u~&6$M>^tUW^U7&`Ll4GW%gt` z;?d?jbK5?Y8{j7gp;LJmImY;(0J+F`t*?aexDxK?dIl5UQ!hPKZ?gOtes2Kf+xW_B z#{2m_0GQWR`f+`LJNeuNJU>LOmKMiHh_~?iGtAWn>mlu_uI2Fs;zL|dy7|geZs%b; z&Nq0D+jY2v+hKU(Fw&2BOP+Oz;XrN&N8>vKjnNO`>p#`DeBJ`_hT3Z2a&0 z=@=faZpO^W|X^Umb`=Ixxr0l(dqck@CUSW0KPl(NiFsj&U1)=Jlx?TtDP}E z*qi%n7|QD>umraoa5;~|VF0%qune~oa5T3Qun_AxhVKgrhJ)U$4>o3faJDPzfm2uy z9L(cIIFiSQ@I8mS<1gK~{en|n)b1P(@lu`-z~dZ0ta(u#&>X`f{)6?wMywD1&U!B5 z_lV|L)`$25bPB=mwb>t<`O8D|H1~J0zVgsq>Vf!Fprqh-1a3F8u>T-lWG3Zy1@STN z4bqlvgi0?8#0{2~l)iJcbAD)L$ zpC?hzB~!B|R}bXJ@<6$B$ai|_D_fACUI<_Hz2uOgv5xeYt-@{mo7P&KhUtbql0dG54C&dEAWjR14G%=H^8j zyDnCX?^HAIR%3a5h2dV9#U5)sB2HatKH>cOFmVN^j}Z81XC@Y1RaO^O4Y|YHr#c+kcuJ-y8o+?a6ot_Lp1^ zE^bnc^YgKb45F>QPq6jhYAEM>JM5qKst>xt?09~oJIsLRA83g{N!<$$b(2wjVI>b)(;vQYl|^j- zDtCE9`}j%I(Q1-#*vVTSxMRJ7o0xvwQ&NtBr|^67{c7f8YPv{REJz}LsKdEF&GMAh z+;751jBDe&JzT$F67!Dv!JM@~^Sf_Uhnq9Z)tfZ^xY?KMXJ%}l�{?!2Y<8Fkc<8 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

@5sL3k^*CDFBFVp!jA+qjmj;No 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℘G08+5aJtW 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

wHNvg;MWnJ)Q!qU@z{Zw{J&sLu zw`6F&*d2Y4^g|suwja3{Aim$0zbILc<^S#QN4RkuzW7{^yCZfYDp@b{QZm2J!zKEBFVXONA)v(NqCNuAqgHP-@E!aOfCP> zR&t8*Ds8`T{W;y$=fN~^2erlBwtA}V&C3x6a0{Mfrf>^g6kWPR>l7<1QI$BH4zNVI z)`3N^cXLE7Zq-g`*^%&gw4#Mb*OykY(G={e@hwtFjNiTH>_rN~@h@1U_#2xi|5b|= zKr!aOoSw1%;?EZ;Y=V3LV3)U48-IKyg>#4Wa!GoJ% zXZhc&@JCVkoUgXa?+Py!7Ay!aRj(Q``|>kw=z=D{$@RW64+~Fl^E3D>JRZ#3(YBEt z2<2n+#O67kSJpsldY-v|;iUT)O}hW1N%ylS-M=_}pBgXgW9Xx29lJizFQpwzGp>qg z@D;CSJZM=(AC3rI^uW$DwC|7ccY|Q}vQ+N#+s(8jBUVUQlMXe>ofE#bMJFGE7N>@n z5X;(rUtRsD^7m#sezN*W&Wv-~xUEX>j>Rp>6Rr0sf2@RiZCX)c7kAK?(_bnHiYv!@ zT}nF~?bSr;vJV7xDDTnDHNgpJ@h7@B3s(lyIgOU0ieSbXMCmJWI`+U~83n$~Cd_L* ze3#I!N|A6gee8Zv(draC`?gq#grPGe|KX;@oQgSZmlhS7{QiXH)_ycxrL8rl7;chd`e9%Y4~|4;G_}bJbq1 zhh4M7wXO0@iU{zseJ?dXnIEq&&jK$oN94zwJDv{iA7~982%FCBea5?^x4z^4HNWIl zxQYzmyj}gM4kr?4mzk{Hg$2BdU1OFGkSQg_wtSUrC)yugqE#^~gdTRbJaC|+tHsNk zX8)12!g3(K~zbrU1zxjk5IZT+Y-5q;YmlpIqy5>}EjXJ!cHt4~~rj}?2 zD_A~zFavZK^dB7jN|=+d8J#K7#sNv{+Wzp;xg)!Xw}bIhLy^h0m@-E4Dp zA=w?VPqR^P71-?Ex$v^6Ut8ClvU0(~CG;)F5r&!I0Z#Y&w~n3z1DpWZwlbKn6zU{g zzjQ8*pswVzhcXO*0al@}3f1T81ST@90Oev0Ag?Lii#P`0@6k=rURuX(5>FqWrwyV( zC81{!vm71`q`P3d)noLAwFed-knUKKsYFb{2kkU<+1tgs$OCgIT&>d%UWoY_T-lo+ zZx{=kIvyOT4ITvZgb}}8{cmV67_UB}5X83d!(?b`zmNF}-!f6(@c<qW#Qzjhv^ zj6(!t&u_B+$cGVI`6|?aueCCwaatGx7UGt49IlfmL|>-{_IuGq1~bsT^E5jmY9a%v*RbCf>@Ug!UT@S2wzuh{u) zv+?_9*d*jXzO%l@KOw(xC#fDt!P4=-;6cWo$RQ?n+y_5AR{x$7zBa!IX9ObW^Y;|MQGKipxu6KT9He%2dcB**9S67SQ74 zkmm_s6tFG+2b?hYZho|RRM3;-&Um~2CLsV;dg1W=wb(Zhmn<3xX>hi4H9F?R9>Tfi zbctCkjCcP{k? z)QoQU;^#m6SBT1MbaX8cbklpR*!+miiNW29IkBGhkB?7#{T1~7EznfpbJ=oU=%La_yOY z#{U^|Bor~#eLz!&qJ{Czs{HuvTDM&a!il~l)WbG z#ET|psyTPmP!qJB-$t6(F$eniz)R{Px49fZeQ;1ZSWxy`0)zTmgaz&lzi1qjrBkoq zscdJXIo#9odNLm_grmX(DiYy^CgMpTd|i-niiuMO=2wBGYIcl&#DI|IQw3*kj8HHi zaXv8-{Zwq0B)@-f@Q;?v3aE`c9|S=Tjq}u^&fq#~sGr}aWL;aaGbM|P!+QsRnp%35 zH%!arI;48d>TBNXzrfb@;A@AEC^nVzP>x91%)K`3UDeJG7r!oiBX-hec8zzgGOANY zya`J(XhPoHKxt{DyM~Vt!9L*MPd}_b@qW1C3EHe}R-&kj$LP1uGX7spG5(+HnUu`j zS#JDBI;q?pL>W~-2@d~!95@8`dWB(CShI+&1q1#|2Cp>D8N2GA@!09s(mVZzMd!Wp z-R~UBU1lU^j5xzP7bBS|Y}9ts>wcagBHl^h#7tQ}6zKqqU$dc>lipVViA8K$81U~J zylT3|pPj38%fwpaKV)qux#zW4CjMydba$TP@zrFZfs z8vi18;0z#Nc?AU{#a#AA5;EAJXHaHAV(L68EKatp;iAw>Uk)!_r%MY8Dj6uXzP=$8xu@n|;2~ zATBP5DT;z~j^*ETv{cQR3E++q3P@M?Eaw7RK*W9{@%~Rz6m&thY4v>^Z-N}X1qVwz z*+1K#q?m+l$379W$q%G`>y@oq9qSGS_pX^%*K+ErdfSfPG)QXy=Ab25RUc+Txyp&a z#^6NOknj?i{MuFyctf&(ja>VS>#?rQGN*j4dBaSFU|Qqo9#o?Caa6BTJ8+ovMW)os z!)M{A(&wNwr@677tg&Vr?z4P?E8$0QPUiVpzMsn%v9K_QiqiZhwH46O`>Og{Fz}JV z8RE491(#1Rfm-%a9hcSo6h;=4Xx^POH4DS8QR#ZLzT)=eafltA)Np{omj9Oq7TcF% zeh=)YMZ}4U(kmS7u&cu1XYxR|BR#x3A+Ib2BMn~fDKg;}SzT){aIVzrgfhU%m_}*D# z+uTgOFzi$)I2MkEs=U+1TCLwH?01nqJJvDWSIsrG*|lTvaOX`_ zj7?Fn$_ZLoDFY7}(X#mot*mq`L`1JrQlCHY!S_!-i-;q`5fTj13R8Dt

8-kpiZt@jzy8DbUPHNXH=ol#|y*lh)x9FOy-}}|v zgV5p9fS#}A1T;7P+)UaV?fQ@W;mn%mqzl-|Pe9I7$~?17G$!FwG4h%>hRzYlsE{tD z=ymbq&QBAZzym8oH6v8Re3^f0AqHYaaamlxp<BJM!u zkH|?zG)DG-dvj1ffO5p*F`Q)$PrKaW{I3^lkh_au~)%C&kaVOpc#lmM}vH#b@JxMvwR73qe8}`J5KS3T-_4 zfh=|{&kpO6`>H|h|1Z=(i2R>BEiaUDv6e+~T?FeGwgjI?v{Jag!z)}VTm#}WhJR;J z?b+^QoYaKmzE^&&(YIsZ_?Vr~l>v?&prr^P%hZwl$SMf1ry=;n;ookM@&W- zoI9yX&oETZ&ElD53rWlow(HO*1W<~wf(Ppj5>dzw2>bmhc_F*)HbS9ec$!lsTs}Lz zNby%7a)XGCTZ8O3c1)+FvtLv8$0_YOvHb&UgEMq38Z8-SkHOisG!F_wmEBik1)uV6XwCF@S6z`qr7edi-nQl7))|bFXlxI*4djs~qCt zx`Qi&r3ki5&f)iTr43(-XuD*7uyh4Kui@d9{LbU|3Zk!=saFL{-;;{N3YNYjd~;`b znF6y+I$>6<7v*X62kR}HCCPUF1kr3d_9E))v-Q)D`Z@nO`>BlPOIyPw=Lbt?tIu?@ zjo%CSeL3R|2wz{)$uX~^OWvqi3l8VU&yR75av!AJJbtg?_ch^?kBcq!fIK$9kH-aV zfNR6c^q^{hwr}WpjAu?Xp3gE526wuxrj)-8@LOy1s#=>HUZw}ttywVXlEzUYrPkqE z;X5RATrKqqbR{zuhoTZsySTCRGS&Nh3f}sB3tj|J9G#c^Bw_9te`v2LV>!H3`$--h z!t$K^S(QLlq4&qNe}G%{IwwA|RTy22?bgUbW{MW?s)%{>W2i+mDDCf?(tbKSz$u>o zKHFfQCdYy#6;=9MH4KxtkY~}yKx#H|AqP%jr-fp$q4IE$v(_jS86oE(XU4}aI=bI~ z*eGgr)IfBeDXts&yQiQu{+nT5Zye1&6?uH(AixXT2$J2;2NtS*1v@}4Y(rR3#I{-U z(#$x&?ZSjEb8YSO!1}}ZWFMJl9Uuehlzkwth=QnS>IpSN8@8QL@~Wk^ijA)E?0_y_ zNG9}c^UP-C_Rcb3wZ9PU@g~&$`3nkG3!4Qubi^25bV=-MudAZsZ?WfdDkgzs)8_6yIEn zJHVuxHuLKkx(5ogX|9fyR6PpVh?S-7(%@%g<#p8?jT8ez0 zbI9UICuON;npb!M-Vqx#UIN9f;&uNX9p-}F|iKM3`a$ngr^0d|RyP0+mDX!-HNs z(b=2{3HD1IvvgXn^;uz!@I@EA>p~{l@BAksL~$_UZ?)5b@e9z?ypi`(uN^N^>gNji zz#@OhFCyuDj~aDwTLy_e*nzQB5z6vWXAhOW#p|))2;gv;!x~-8n?`60FHU3}x9vc& ziVm>d1W?pbNkld6{6C|2)_!TBIuq$hiLhz!OY`_%t!qCB{na??`1J~ZsR=kTbfn%J zxs5X4mBXv_1+~@#mOd(F0Eh~>>~V_wL{B=hhgKt0KWg4`IXzCNW?E=}vec+HbZGew zeag5*SrwpX<2#nBYS+*=X|WWN;5q0yM87PH_;&$XlwZHp$a_sdg`edQz7Gn)YF8p4 z85D{BhM)C~qmep6cSFw))nZIj0c0_E`aPiO(Mbtupp)RjEEd!wa@_S2F|a*cHgCrL zxuxt9oY}L@9~@fu!#aN^e_cNQ+)8Li>}GQ$p|33p%8DWg+}6GF4F>;c2cq^wj(c|? z)!xlULbo%rIrvds?r!HWw4F}dN1JDL{K(6{L)hO3Km1J;7(d#-zv#B~MQMi7s)0~V z-0n6;OYxojz|)k)7}hxs^=UK-Y+)Nu;6^!Exu3yG8n^J8yZe{G)3Bd^=01t>4$^I~s^2D*BYvSQdecEzFiv?O7 zTKAh8{~GNR?cW!Ea*iMm%s+{Q!A7q=Yz7@|J~cceyg0E@fONLDwZ-c#2hOO;bT`am z_n2~b?GESD@$jm~@ZyG!2fgd0z6>_7;I2QBtF!Mt1+iVMbJZ}m~%Ht@?Ph{<7z0Yf)I!GyxI`zTGtMm&{;yjjtD83ERKR(xHDs6ho4FDo^+0`>acn zM;OQ}{dg0IfW?UE*Sa%gsPsemtWs-_er&KxSffcpvH`~!Nr4ktn9l|g+nW-}NyvAJ z{O#nGG^+WWOeKjGDK)Pkx5_z1b{oZGlAY6uhw5lGs%|j}{>1#YHpS0L$~58}9oCtc zXHy1}+=C{1ARH>`jN~Dgzft1au^q%7P!Hec{2Cku=JSi{_vuOHT=k@WG6U)GpJh!j zkD5bFiS`V=|DU~t(4V`a$9qMil7X$x+*r|$P0xvn_01msR%q< z{5N62ic^F{yQIU~MYBJ+I_JM}(d=vZX+O3^`9!0uiJTU1F|$32<$o2lw9{0gljOnj z-uNma%ioI-Da}vP@F1B@jYp?8iI$q&=|T^R@u_ht?VrXR5i@2=p5X7}t?)Lg zT*q!&xD1-$|DhQr(#EYF!QDSMddEs`B8N=*>*MKr7BZ^ZgQ;vY>%k!oO( z3PE?b_~%CQzM+&4*QogEct0JJHp)kXlWQg^IFsTL+NO%HrG>XTkIlQ-lu?@_7gGsJ zV>1wq88dG7aM5Mn1wQbtrnI6-FY0n+RMUuwmnX}tt#QGX%PPH-`#3%!IuFt5Yud;O zQIejS%&ObnBoI7{zF~f@M&E?(i|#{HOTv@IrR6)bG%Bib=D!i#8(+Ik$@qARvj%5U|1<96hI7!PW5 zua3I3Y;MPo2TvSmvYl`f!NZEVU));W-0=g#c$KEQwS2pqH{y+<>~_L2^XSUSw7+Uj zuy!un5HLa^2(rAQ7|JQ)(d4f}B}evTJt{D03jJIAws3D+#@0t7D~DEYCt_>O!X~e9 z5`xOYS-F2o`woJl4je36P8QUL`ut&h2PRQ)@(VzTGzEncsiw-z1{}h)R`M zRLy}RqkWGmO*W@z)*^MW=a9qF*aQrqYdF%DwARI?mgI-Cb4hGebTR^`U`G4yCQgv| z#!BP#GQlo=NQ7onN#aNQ6!j`2iW4;=fkZl$2w-|6cu+^MF=L1jGB#mgoWBRb1VFUW znhp0`Gt|imjKIND?cNX3^cYv_jFGq`$@U6E?)a|o2Hv1~6GB{K^g(p??SK7Fedo&fNX*ZJo zq2Y3v)Ec%#NQR{)~W-dS%jSh=j9Zat?ImnaWQtS1rGYPTLZcNo?IS-vt}U z6{vqvnicq+yEmLM((%q1-L#dA?Qp5RY+!L^4_TD6i*Jg##l>!0A;oT!pVe$?3rGHN z8NcHzF&n)>{I!L=4Qa=;$tf|tD*rsv&o9Dpg`S)HK5xETrr*}Xa$+Z@{-^AbD_{P* zW9X^Lmn^sXPmC^LzS7gU)xUN$CthRXNqsad4KE%%v*N!!?o^VAedXBj?^nJ5PY1lh zM#>8Q-g<4l9R9s_(AvG7qc!|{ZGUz5k_Q!+5{aBqH>FF66db4RT!F+_WKqig`@O$v z(GJlGuAj2MPtq%G6`ior5C2{}I{i7`dY#le{QIk~UcFN7`lma%44yUo`wQQ2@nz(* z<^9Srizk)+;2bNS?B^x#?eDem*Z&#mp7_2b|A>b5o}A5(KSAB^dHfBPDq21z2AWy`>ygox;Kga_gVBEIH)`hC&s~&>|svgTb&8g{-zj(zguBr1T6aBxA70Y$i?sZ z_eA^NHb!_Codatd=zy#L1-FOJ|D22Q%Y8a3cl|N=`F#4j3w@0ELukWu_g8_J>hKks zmciEzAJN`B|INckv{BDr;=(eWe!{!RujpSxrZBE^p9_2E(EswEx&HDM@qgIEPj-=* zxz|R}{!|pE9PjAs>3(xI+R^8YycwkUwz4#qE{xEFmZ&Fp9aPiJWA8$PXGvQ-X)o;c z-TkS@;FI!+VLFaQ2@|%*4 zjU1J;ywSdLJ7_F539N*4GVM>&?LQfdd3(p!fq86jGSNPg`RSYjf;%SIy)t20BiI|L z=%w8KF4~Z~(QB>dG=FjXp_S}R&3Og+m+d>Ra1Ep_ZZR4$bX#X~y^}ZU)FgwM+h&yP zgtEOy<(DzuMc3r6h5RXQa}o4l4c<*IIkIm-|32Z}KK;jYp?cmf3JN<`r6>Tn*4*RCwFpw-2vHOuHQxdE7|uzB85~uR2pD3!LHiG=+LVD zFz(dAJRvkC5yml{E@pwU75bZ==PABdScW!fS%yE`ho8cWW6Kwmx+qT+kI7tPZl+>E zeLTPJP{#WlJix_tF`jh?>Ep}Q#=8Anwc6FAT%E$z%CYjX`gaPyz+giuBJC8_))mh! zlRCkU-MwXYuwZ&*vuc}vM#tj=ryesYxt}SLr!k7{fj{kaJ(il==-|B36qX8oxAw09 zzlJ_}R*nCn{3ly8XN-|n6EAJbm5>H{CjZ@VHjKM@Z868;w9;Ja8cseY2}snEwG zp`Ms2vfXC)bGQ2$cR$XV z;oeA{7RoN-HNar6u!x@9^|cW`;c~G@LTTZzS2)q`ZH?S8KK!)SjjzP2g$Jl<_=v*7 zvFcOE`s1ztl*%6w@pRvxgDn&MUw^+n7nya>PvN~)TQ>`GUw8Ffr-YPY zb|d7Xo3varWX(M=v+p3=J^2u)$_yp1+dLz?9aG{A%=kTb+mmsgY<}l!-g_RoRc4ZQ zurL>V*1Ef5vy$|X3t+(pEEMDP9(m5h#SK7y@kNo`!CzLV?M?CS9IU;Dl0#tqnX6B9GaHo@uHo0-Tgm=OQrv%X6f(n)0#Q| zeZx;{ru=v0vl}h1W$E3nUm|iUS6Uw5Z_7+VvBG>_rQj+$R-5nNe6;jpedETN=hV*f z1oM*JoGDGOJWu#F5q-9E0>14c_?3VjdFNUA_RCOJ9N#{RD;v)dZ7A>x1?F1!gD)CB zqMZfa$Pgve{ysMz8SH`k@DXhcKwfw^?XxMs8(F~%(NBk;rMJiB6n;;+v)s-OZ$yqa zQRk@Kd3L)e6VK~Q-FKqo2ESA7{iDhII`>|(Gze9bhN-uyw^n|;g6PE1k!k*bW+kRU zQF~jly3>F1ZO-Vy=XCeXEE%K1b$hf&Sox1wC7addnSI;6Ld(c*iXE45DY z7js`(*CvOzkB^mZrY`j}mY-JBsH=On`r#F%#|<6%qom${;Xa=okKsB^3`VyOk4oQD zr*k{xBFgTp%kHS_+h3R6r)|jEpb~j%bzXIz^W4{K9|j?_>c4h`h(qr+Wq$A zejoRn7xyfGgOlri`8(_P(2-m0-ha1)`{2ihj{K>{YiDBTvpeE`%3qw%?oRsI!#y6N znLXRx_XAj1W=eALd4b;jcE*vI0tby3A%&E%Lrh}(!b7_acRnu)%K z_PxqbqC?U{J+RylABaT@*#N1AVzJdr0m6xM+f@20!MTKL=nN)u2z08I3*uJPI$0gJ%?%Ex#WykyNb|8!`?=|| zqyWzDC(nb~&&e$3MEr9|B^h4E4s)0~DiT|*+c3cCp#$QQIYC!j@a8$em2I)*nSlJn za2`zL?y;s)#`J)^wpTNlbWf7kQM*C0ywKrEc-idm&28b8bL60+3t;k+w)na&Adc0Z z2g~A45$(JJvx0&!80EegIVB0_zEJ^3j9-xUhN#ie+@bQ-VRzd^cQc7>ol(}=uVQPK zWWEIHFuT5cz#ni3%z;Kq(3^~dyJBZ6rAa`}RdaHsaQ7;vqy?D^Vw?FS{cZT*2eG3m z-kg1qH-7#%Kn)N1$W2^0zk9LENnbr=(L?el)JZ}e(MQn~6i05MtlBJ&+?rh7mR#K) zUD1n?ja++$uOVg?N4_3C4{z4h^Q{FsCp}DdO_o!t7cOgdFfvYMZeHVjxGD1lAK=GymCPXPqE#GiyLMxhI>Ck58acM`H$4XF>Yd7LIX-@Fd{BCxCBFzg)l4! zAQDn#^oyaQ(QZ=%1syES+eWHPL|KUrf>>NSyjf*qk{OI_*4>SF^H*Q0r0S1;-IuLx zh8E$C8b+0S&MRCe07oB$H(P;9=%6#c#>Uti)l@jDrh?vvfYY~g%?fjPFTI}efLD;H z5Z-KszNtdx4~>1d281b&?BUK`?b8+i!cmQ4bmRbk6~U-3@VQ1wNJOLccl5^iEuIPX ziZsPh5$E2l3eWncDhm$HKpS|JPxHU88T`!f(`sjMeeiH#g^D9_i{(#)4^<&*Ug6)< zgO6r4nft227dzbw>@*1H4I?uS9XoC|R9!zN7Wza z0B>X_V@w2HzT^+kG0OD(*7e(;_= zv8A1w&rzZH%+Z_FZs8@&K#Z%W*T;CiUYVuCQFU#m;igwm7*kyEGztnFtdkS;I9eyo z4OO^qa$`i18pGvHb&H!$y`)))pztOWWRQQF61q65kk|3n$wk!jvk<(g<2E!BnMK&(aybDb)EH1)e}56;~}qbDJ_c> z-4KzYPm2_(P;n$~to&K?*V}$cLLhOv5#yp1UCB8t_(b~-b_~?7eo=U;?T%8arAKq^ zRh}vFH|#@UUEG;qpq^uzQXlv~41QO*&+iB=_o{M3;pHVn!%QHf_ZXc1+}cC|P~E5&{R^7AU330ll8VO=y+kvRp!y zQH2$KBF=wM?q(b@Es6bG+9y_#cDoZ9IA(jtluz7!xs7?36Cz^l>G*~Ay~77@XR>it z5mtn&vt`4`$Fx)~MeM#M=)bi%@^Nm351b%T%ocRT8RMVNAh_SAn<&43OhK|k?%@W$ zf~y5e&(H+CJNrNH1lg4xZ|lr` z&xL|EgwqY`Y^sTHF6_HuX5SbgT9@-l&ljA?xw2zf*T79&E7#U;)&)lTuAuMJ90%|P zRA?PpaCv>ub3?FhDCirr&1vF?>xOU#d_oSfsPYa2fmiqjENNw)p_e>H6<%B)<~|)} zH+Xma_NhlkTTf^2Uhal4JH}xeyS+PdJ4ySW9n)bGj|C&E_#n8^=kK|rx<2b>T@$0W z;on&s!9z3dk208CKD(qXJz;hz1kGY0zN>Y?vKI1^^$blcZqDSbKbca%r-af13Swg) z<%iQ;wbz#L>+Ss54!nwV?Twr#VWfY^?M8_)m(6)jb*PBOFa-;=82XMdp@zL~%o>(S z>Llu6b_^Erj^FbJ7f#=;9sLE;XHo(|_!jWJh0A74)8livVE#suF5hf$x1tV{v>)uF?M-e`2ik!(ocBr0Phdy!!`&z!D zZ-{~KA1h{!P{+DOh3bDgQ=?Np`fiE9AW`fQKAX%6HfnZ@*$w((Pu1xrw`30}u^-eS zd%(N?CcY9WO~H+_ zeGwHnDqJS^J{T2+4zH>Ywx2tqcW2$GH+AmIo7d`P|E;IGD%kY=BktTeF2)bSQI+uS zxTtxw`E=QkR&{J2{NT`cKFQM>ukZ@fZmg;7#;5*T^>hBxMj7aCvlEPN_wKk+H3T;* z{c<>}zfb+Op4iz%Bg^dFoA~Qp_Yib_uxY`~dgfifgFA!wh_M)G`D}1yBKw(4{`H&? zp~H1Tdo|ks8#fv^KH~5q;4FoKJQ`ds98GhSDF)xIna`9$E~0(`*Lsei ziv=*)=UXH8Ss^-wkm`cR*kV`EIU;6Pb^HrPyxEo~oui+P;i#w-wMig!lJ{1x@I^jy zoNOr-MRsZCGtD80_Gg((ToXB|7`unJC1lR%fo6$`(?pe|ki^L9 zmCZx+t8~6VQXx|v*@Ay5V&JDUrN{B`SmOxJwbp#aAk)ESKV!dQk|}jyDrWjA!lmgXInQ+B%7A*4AJT z{i*WwfzS`kxR*d*ATLl=?XV?+ivSN9J#ttO&EQdZo48iDa{QIY!rbO?i7l8f>r}W`7N<#CQ$C+WCRf;$Nkq@!s0)#0DrwME9O>x zLF!_Ff7;kFaNqOaKMwiU<8hFL1afFueZ9h~S#&%oX17rSjxGNw*)sOkt!gGufuVF- z?jR^o4EFBf`PaVN$JcCm6RuRC9*5%IjYVv9MJ7DC<9lmfG1@G5nfX823ApZdraH{s zmf4w^H*2kuQ0KQabbN2{7s`l|-IhVlqEC3JiS%#vu9u6xq?7fGk5z21*xB%Bj=Y99 z_z{0dDHCX-IF@L6Yz;4CV>;U%{UzaRJ969C{O{3)--MjT%Lk7!0{e>A%+uk_V7r69 z81zdyt!%V@7MWWoGWlXXUk>iJlsMSFZJ+D*@*V#dckcsUS6SuzCvBubB0GhEsZ@-b z(IQn_V6>qH(}a^$Fc@G0l`#kk9T-7tyH8t@U~A5Sp4nz5*MS+GQ7>MZk(ptX8L@y= zDQ(RuTD8=Q#TF@AnI2DPtiUY@Ubvs{diT5cJ|{t#-@WsDp5Kp$r#buI`)9rDUH{*; z5P?s7$45V8^hs;Twz`&|Jd^&%W`Ez{ z3>)A)bJP0rS>Lt&Q)>FI<>$tp&Y92LZPPEFO>MHq=`+dNW?!$^OgKoCIkc+Rwo|pn zsx)S{pIIb7!>obR+r`rih(-r(@b+AWDxTjbUSs(g%%3;=cM=?xxt>G`gi>?XwFkQp z*wNEsqaHaFhYBek1cdkV6+jMBx0k!~4;MH!{4suEC&@Ybf}O?r9Gttog^XKQUIPxz zh9*EjnqAumkdHB^q`G(hU~oet4Y4XljYyiE*0X0l=JH)!AWQ=|K(cW*ZK-_EQ9Mw9 zeUv*8XMp9H5w;%u9y*T3+&U+E@FTfd#dGAabh*cdLeq)!C>l9H`V#xhNd=vL1H7HS zvPeN*6A?qkiyh$rls5$q0gxI1R5O+=_|eFTjFCfYKRIhUp$py}RmR4<}nC-}{tsI*(EQzXhk)(N`8uwh&~v5r`Z>%H4~E0SWZ}6QC>p zMxaaEQZz?`UO#q?I`m@sr4CSfJB|~pY~xc0&xDDk$oFzhZeqXQzmT>~Jl8+5Xhx!( zwq@}OfI-C5wxI(<5`eliR?vP9AcI?3RlZSSccAqe?3*@49rUc^| zN%vRKJq3Nazx%*{d(;m~p-9m=9i;U4=_fyoMV(E$OCx*9a z1v0wNZ43%0tADcWD(&}AoxSTu6(>#WmxWtgZL{#+Xk?>D6b(K<%)rHhA-sMY>VEi{ z|Lb;i4~5aKSI0pc_!lvY)3X5Jdj~?grPCRHpt@F_Fn=AH@4NVS?BvQ1#Gno95Xr%} zO2k&Sa%@52dr$!@$rcn94+fvEh@encs`4RS*TQj^E@}Dl}#vLThkY@N?N3X$96x^@T+!#d%ht{tB1TK#~A`>L$ci~TF^lv8ErLp=L z@u1$)zfT0v8T>KS?BHsWrQhYYkT0O#*bey9-5C_cmzn7N!xOpx-r#Vd$)K!GYHjI3 zQCT!_wA{lV7I^&Bp--QhTQ5`0O#4KJHB<*x>4nOZN`WSv5oTyDkWQTdYP)`1*+IGd z4R@6C+FOk|Z;r$qk=V~9VF^|w|5lJ7`T=E7o{bw?u|GcVVuS>LSggy z^#8N@=l`4@I5{j^odJ5Uydmpn4t?5ToQHuW`i_V#o3v1tzD`+CWY5d*T|Y#M*In>` z=l;O=5!_g?mSg*{01y;^0K`mIv8)x)wcHM8cpKUUa**d|J!_8l3=BwCzW5_371k#5 zQxDuE6erE1 z^yS`I)LiLzFG?wyY-S+^ivqOGn$s#htq1Q&v!Vuo3o@0Qu3(?b{ZZM*cw#-#$Cq7) zqT_;VXhUfkkoT##cU<0In%zu!M#=Z1{bJ(Z2K|4HR_Z6RQIW3+i~^YSYUld0wNZWL!_Mgdj2hq*-49W&k?-1v`(ff+tL;rKAb zi~C4jF+39h!H=m-!(l=srsQTgUhS)uvppw#xk7gGesaVkpU8`&Tdyk}G8r4Z)rv@Z z9Tim)EVT?LWo9^$zc&lVnkC5J!uM#{eDcCBDa|&M3E4P%k}u;Ab4bbv;>`a(LtX z-SeM7Og-BJm&setkT(iJB^{qUyzK-c&vRQ{-;F<=`5WzuXN_jAOuAA9Q~9=@<;?@X z+vP`awr+!MS=X`Vev0msN=7uG{+XrTidWheOCU9YlfP|-)?Vlo|I18{Sxe}Af=yV1 z@=*>CVZ3$f@O?rXHpTawxSWjd;kSkBX&zT5@G((0CIGH8hZNUus$7)P8IVT8pUH>u z3hUa0!_2h_hw*hK=NeAFi$gh*?=si+U3^`+0aJA>IKCF4G8P<{@)JAHQ4%wUw<=?Z z#KyqRJqx8Xqlf`(+Ono)yxbS7m+{-oTFS;)RuFa^hFF>B}U$nGWD@ta7kyM)MT%Z0b_Y2}gR`^AYzn+}fL zOkY9qIMGl7sfTye630^hcJ_B^__npzi*y{&YeqND&k_OZ;L^I0cFafS!-dG#zA>yf zL_#`Uw0h(4Z8K>ci#*141E+ltfe8v%$$yaQN?_FM{MSkQsj<&(=l><&0Gny(HVGoV zbEXeA9lHd({~e`)J1gya=r`ae9`qaV0o~5+Ix4p#Kccb0h!-Qi>?#d5k;kj@kM`Bp zT8M~-QhGCYhn6%x@MoJ?)Ra6TP0^C(#-TfA4iH`72xd^|5ZG#-+z}1mdD6g+S;M<3 z*Kw>w%jXRx!+dy$c~3w=cp<6+ih{=sH`!K3HafCP!J`@lC}>1AgRnYF@4u0_gP;T2 z@?t_~<$R-QL;#08iH=Bqu3wwvuvHCfnh~-C%Nnl;^U?!t)M#gka7DSh^`n>P zKSaF#6_LW+{Nw!R7k@I=J*>jWUuQ z_0%o(PZ&-`C#uHdlri`VxYCMVhGdPC=w2?fR4lhGD14rKr3t-c`!ywT@{|1~Q=>Z$ zD$QC%+MLyk78ySZKZGkopG*N>gd0yb^4q)-rg8&gThtV`FM5Ue8Hx9Ywj(<|b6^?* zNoh-!pug>=t8(ktzp`5!I6s$+iWNi;G|=<*-_mTl7VMwOPheD;BTqiRK0_y~=8+_L zxYOLRI&ifx*RrztZsp(_9w)8T;T{fN9g6FH`uB#uX**9vmM_4aOp^cI;jzjPwd#n& zi{~|lul}aKUpB7f5t@(x4p)tRxu|LN{`K#hMH-DqY`@lwC!C4$u9oOIJkE{8`@`bD zI91$v$K#{3Rne2Y&n+d&bW#Y}+Dj`P$M)m2-u85STa)uar_WW7dsYGvAJ2MsJYT_! zB3V{X`Gm9=qfd$7K0TLalVvx(D!5B!Zd*xhbSCgzdx`}SX?-lkP1dlgP5XBr6Z z8tk$9doR}C#v49e;4s|k2jlk;kilq!LvNAbF zu>JV!+n*jzdjLu@xpgb?cBFw*bup8M*FCGaT$*3?if`%{km^ah8G706+vscBcc7PL zg*Lm@=1bI{q!QdbTOttG&o7hDvO^S5;Rz`v*i62NOl3^;QA-a}mH4vcO3H7+j7v+d zCLq~tJZ z_w4wcX6*NuC4F)3Q1H0R_Sr();eS}SSZS5OV+(tzOV-mmdTHzPB*w92XTW5IA)k-7 zdG$Brdc35SO7GQQy8SFvBloNFr#L2UdDz$qZxUZ#^>#bXd6Ilh7^||nb$<3#O#NQ# z=U3y=g{rDd`9HbE9%3g`IL*xL-z5(#Nz;+kWh-GPx>eF?J#3^2r$iFllK*m~Tzn+w zR*Krr_!E<{tQgxAp9DpVZX-3@Qs=EHkv8Z8ms5Lmq?OR6(S5&rh01(pkOKZEL5I$$ z`+)De&69m9MR3552^_6+b}<&Ih=f9}xJmKPm_blCLb`_^78HcRC5Kj`kvTB>zG>2TeU*(0^otDJQ$N2>FN@j^TfKYL!Nu{PPiLabGlASK$z|)cRpaM{HvuchTAb)$moG zb(VU`@jn_Dij2vs$9Gp$h1g!wk12ONr!Z*tJk&kYA8Y5GC6u77MlRlleL+iBuWYWf5>ew?RfPB;WxwS`Gv&|nXSpVjzl zP?o|VByas7sT9Il!HwtBf+dOyTdYtd_CBSnfnv5Ptz2nv0cdeLA<%aXwR1JE^eh?U zXkuBZ=M)03Rj1R9H-)#dXbRqLzwZfig7vD41n2yDQ^EMO6vk^*Mf)@d;CE#J44=wo zYy(aPziK6>KaY)<>*4hSrBaMBR~1A5g;qV3(kDQv9DaQ=kY-pGt+2<6D25BIW+MX= zGWb%BE|DV}=l(0&Fk_Oc@JhRA=c2tdcs1bZH&Eu<*!~L~1TQ+h>hgJcdo6^(Y`eAW zggR%7$wvw>PRAlcBI0h27DHl*S39#I|0aYk?+D^JcJ*9#2qnQSYg2I7j%7@0XkUK5 zfykflmbM6$&3xIF+nb*tvjEzl(ml~oG`x?!aWjlVNpbdrrwwEQC_chp-eUs$co!@< z6E;RPAL-b`TWnm2V)*tDj-eVg)Wa`;!0bcHl2s9g9&(3D$ryA@%vZKFb`2j2Zg@AX zp-z*?GI?M5f+v7KCv+cHlFU9b2;&wnojW_F57d0T{}}m#*CYU{w27nUs7OZyJS3L=J=xaBus4GY$VSL!&iI_Tl_JZhrN18fuS@ z0gm&c!M3g^!edHLkSVEam?$9~SuZ_Q{b4k4AYP$`l(&1V@+MJo$roaPJGv%HPZ)hz zSuSm^ZUOV6S8C1PqqoRCJ+0EiFH|qla;F?fb{W`{E)cR2exp z6>co=G+b2&Numqpuoe$^=1Ydx-Z|O@)eXt~ChgXgSItdBss?F{mR{pqN}iw#t3jU! zkO_N!XrQqqzfxY4q;orwm!u25-DI?r>ZSp5ZOPBJPiqLIm&=fsdW9#Cm`snnG}1cy z>qe6(BuLbW6SOuF{;NGzOxffYJi|rG8?UdY6OTWJKa(G_abINPHoBh$f5PC&3+%fZ zTwp+Z?G!*;;D83W>g3K;UQXfn|0Di$wBtWBjQ`{#N;MT@I)a)u&`vFw*GB!zS>S|# zmHU@FSXIu3fY`%)z+PUy^0MV_FZVAuW<@Gte!!@7fa*l?@mhT}T~AK6D5>Ttwrk&I ze4O*9NUGB7!#6p_<8_{v@FaueP0F>e_eQr;-<1oeFFc;q_mh%Pi|@x7-ZMt&qqlC898&pbaUF}I<8Rw)q7{5l4Ub$C<*o`vD22B2c6LE$#8KnBV9q&vPu6w={HZ#(z&gdp$O)SO|UmEja! zoR9qy2Dk3H<(K`*@}Tfh>-QrcUSWCYsHkfF3Mn;?>Zh`k2sg24=33-$jY9^M)h9L_ z;VZHWe!iGrX~1}|24|0M(#gz>b=>+ojt_k=m4BHUZb6|(`(tSf9SJ7cd3U!@G*EjR zaLv{uHvu(TxxB8iprCA2FJ}($TgrE3)Qgvx1HGkl_;)c|X}oJX-C$nDQzuVYNukUL zJG2s4v@y3&y1Pef+^^ECpcIs;`aVVd~eP2fj)c3wPl`b^(S)RBI9#RcU`_qfUI$)Af!W?`=T!bMpW-Fp= z2;dlXL%341RGUZm??{1B_gPG!ayl<$^chE=6hI#9G&`rTPu6y=bB-?}Z^&kW`Z&W> zyXrPmE5j!o5v@kcXH(K*KlYY)uRHTvvi*z)g>k|A-1hPjx-R#bw-^)8bz~}nmgPr( z+ZerO)t^S!Hd(&cu1E79)WO92S6$S#=u_cS)jwKy<|)^PD@h1!>Fg0|!R0IoRmGN5o#8))~meGuI=FPF5=HnLjVs zYry>1(fMbUD7&?zqBDvP&%8dj=y&!iGu8xk_EzjHxIsitqEJwr#xJ32%S#jm-a`nU z7J@Jr{RxWy;GxyV0Ub>L%9W>M-7&+ewurtGLZSN03w(Ag9k9sA`6N495*?cqUC!^I z(C^sFq~!Ab*n<;Wf=<>XpCYDtQ2Ko-A$E}io#e7bDU4XRI{Y^o6q6BknMHSF`IPsn z_a^WgJ-9TbM=2D;OB@8xP9UiGP9Qk)QV>)gm<$B-Z!}y3dRvL;U=N<^I>{1^DeU1t zm8mPYwfenSkC5GN!V3w*hmeCE+&2pD-3rQ(+M051;WO&-^;$i$k{azB+L-?Vg{4$w znX;-s@D;DWiJgPHX_Y-Iw|pT0v%uF)ptLof7SPrup#T^r{OUv_JCg91^e$t5Et|GA z!B=l@s{Ajp2CWzJ%+|^BOr~Wo+R%=jGq|(n{GP$ml)zYCJkI3BBP1_|sT_wKSfl58 zWI}9ImKZ=iNP(8p1r%qM>^PNtZ}j*X6-C+^cABvG7E>}hC*fRDuiFaiHIYh5cO1iw%dln!6 zg0(-x3P2Zs#LuW#8U0dKqIa(A+{~@WAJO2Y!0gYWZaNP~YkQp=6i!sH46*Oh=)$S{ z#7tZHs5*Kvkm)cKaOvqN^_~W3It?^;^}I=-DeX{EWqA2m@7ccZW#!(FKuyZMga}*L z1ft|$!TG=?c*hr6H%uwH)9uz^o?8P9n!Q&?y=!XcyvEJ>Is-U!UVf?Q>}ND;%{wUE z$WPzDgZLVhpx-<1>zMayIgw+D#tF?==+0rU|G!Ls2?uhJfRK8;d^PbB{*t~}|5v@_ zhk%Ipk;G!XY=YACvj%u+KQ7DV@am z+Mm?+aar8g0%XKRVW6K5&WvUPF=fc2L>h}8C>}67U zi@f(3YUwCwEo!lur)xMP?NR@w(M6NDRll}!<+tFZ>T7SK5H7?+(f8I z)HA7m_g5xiGP~Gl$M5ZKUggjDu-v=oWp@-;4HEgxz}e!fJe+?4DwKM|mxA;E5rNRG z>IekOSxX>n;c5s3D7WTPoj$)wT9~5&C2ifrcq*#9CcNbLFVc0DKjNcuZ}_sIb_gh2 z3`eEI1sSFR9mGeqa8H6qN7p#c02dSzVQ?xTqdBL z7Mm5maY#eB+5Vj-w6vdN<1ak_{PR!mc>U&eKVQp#;UiCPUb_~bljRj@*g5(IeK39g zo|Ei*G$MMR|3dXdO~3TS`kP++6wi_M7mn%0V05|m><@ztH=UsojJ>z9u(R~g$A8R^ zV8flSvQZuSgG~%^bkkanJnQWpqd&iI(}5#O4~=fyw7%dQT<=<_{>@nL3{5ke)3Y>j z_fu?FF^5AmC1?Olg9d++6J}m$(sSKcGx76M**3#i(MA-ydOXlRdxt?K0cM;E(kqL8 z9Tb#$w24H_pX2WoOrXTws36+eUqinq+`osME9JDrUl7# zlDatSwhGfs`ZxJ^!T~LVO>|z=!uWkc|L!C2e6cu!;M~|Le?MBhNF=MfZS9)IY2x&-KB5G#*ylI^k$LgvXz|?YkE6w5 z=H9w!@tW%WZf41OW7Yp*egrcR)xeI)5K|leX;c_}$ysg*|3KlX*w+*jv1R;TXa;eu zzvHI66Px9tp{H=mtL9Por*4`{+%$g>^<<}cU)0k*wn8&K+Hb7#5e6rVi1|x18)IpV znG>OaYongbR9zjeu@!5go;B5bqMi(7g5n1l+t`Y^@WkpDC;4|2fa8Qz+3N)q>0bGx zGZ7x(<0Ks{POG7)ueg4a42$6>4f=As5%tY%u8Y9FO+2^*WEsmp4PaX}tpvaXH<|#N z81nKrtQ~o}A-`6b@**#1j203W73^T&yg7}(sGPw~WWXyiu4z9R1%*^u5;&U9qHlW4 zyP|poF}fu2G#AZ(;llZc*~R4Z!eJ6mob>sm$T!PFau7MT9>g^}7pPyI^{T}&C0sl- z^CvRqaq#re>PJe?9{EIg)aXR>=ua9(Uual;mN)#&WPf@JFnwjyv7gY{GM|#XHUu{R z6O37ydm8tz@%AK9NEu`X)6bfQA;?oNm(`qSqdw7CVtSNzeTXa6^ zYMVT^-R%o|+QT*#u~m=^1{W76BfCSKnJTMqlVC+Q8VZn4;e+hTZOw0pa$6;4d=rja zrgVeI#4u@Jw%M~v*(5HChYKPLW~q{Ck)`D8pgI+(aIT6&$wTFuV?_LZ|;N_}t3@_%1W z>sq;sucJn5ERoi>zF%8f6*n25Z`J=L*ka+p{_qV^{t(Cto*eQ3CmPECth@tePok5q z2Xqr$eZEu%ET7pF{PpJfdlqbta<>OJZK-}I`gp6<2J!z&qdv)RyH`sok?~2S_y0WD z*i_Eg7o#;*q7om;4t{E)PNuYMDxL=T+4;XO4~Dn1NXZ6Dd-_iUlamP!n83vjGEWBG zUvCC_0-fNt+vG{;k>Udh(VRlU*phEG*=ls_Jgdzvz9X^(dWVl=ANzUqF^q@{^Q{UL zZAB28zjKfuP8vG@k>MQ|x}SSTc5qSRa8s|Wx)+smPYJ0h%~_on^W{gcLVS9B@4ybk zr^iiv+W+u1`yUC*7t(3r~bMLB0=KD zD-qk=w07jthWtsfi4}?<=}E$ zy#Cc?F+7MilaVa5wBa9n5~onKnunfLyyy#H+dszjlttOC$NjNt&*P)IDjgN^a0MqAM94L@6C?zD6`PZ-Yfv zT_XdC|BBp0j{l$|q_;5xcOzrH$fKUjK|CgtJCyIse4An7EF%CEJNC;4*go|Dyn1wG zn+xY3-TI!?zJW|P|8Qn#gd~Detj`-Ae31M~Pm-;S{--aU=i6LAy(@o+ynq_-yosiH z4VInrrC^Z6xp>CGVAuD|%3N{MDY;4olXyav3c^OrKY`p-wm?rJ!+Ch~U05>|i~`AZ zaf>jBqig9-Otf?k153Enw{y_!LhSCzNzpAz$_Ac_;oPWE+t6fr`N8+tIHgr(dglK5DDRGHMoL;{Pz?7VE zSNPLtNn6A;6#=uat1*1T*m+IySxi+bjB>jOw_bTC2|pgh?nxwX{y?d#dMo~3#%V`| z-VrUQ)=v0#eAe0&P6}qK2^#LAn*wdMRr1bHo>TWvaIN6#`7aukSa4J6s zr{nWZ&Yl6?d`1FAt-49`n-L0RMaUmBS)hn6CVV%1z0)dTxjOl*7EIja6TXzY2>fyT z!CO;+P}fk~>aULeDwaQpuQLibmOm(d>%^ukQ0FdW*CGcU^v>w?n5&3*Odas3y&o>m zop}Fsw~jRxC0O`35Ia4wh1H9yZhgUaqrdE@Wml|-L%3;WA_M&Ji`5_T{Ezx_=Z`xJFv0%xIf&!# zDK=B~)$!_WUcM&u5;PzL3VissL?(n#P8_^>?I$rXzVmQD=QZZbh00ok|9(^~@*CaT zhq5xAkK6vXozwcoxHA*raBOGgZU0Q6i8KE@OC+?6bzJ_wxW-8Q+yOrZ{gen1 z5^cw8eO@)n9aIO}RJDLkaEZV|de)AM8-%u&TzUHp#vxD^CDiK3+M?9JC@!-vC@6@~ z=1iSi{T%8T8{W?#TbR2YKoAL;!qG~WgbE|$r~!bb_AM^Xj`%Z3j?y8K>&clh>in&I z`89os=*$agP`q5OL;C>{CpBp8fNMp@gDH(6^fB?G&pJ!fgy2jU02yjICvNct>9a!z zaA}^-BZBmM2;pGnyhQXh zD9F($+4sx*^|GXbGt z@9KL<_}tQ1FK}iyZP)Pj)juVp9m2ya6-nk~t(QXzL?%?JB@++q&fjYd63CKW%Y>xl z4y;S8oDF5f4Eya;JrH zMg8-FZ#T7z4Q5*5DAwv<)&VYVzzbc@2{Vy>-`XW-=x_`x@uf1Lxyvn5j{&W4%p0QE9>fwhIdqpM6cjD;{6N8Jib02xOUzAny58yS5c;;7?rw5#x?hJ{ z#wby<1(L{qofLneCSz}gLR)@M2V!<6C?+F{J6tw-pQo}hnt9Rez6O=bzndKB?L3ut zgRT<5rrQ7Bfgvb53ac;}M`4fRSE765p>9F(WNwM5tZ5TreS(jK4uY@XeD(4xKjaCm znB}3s$_P)r1QX#3#D>vB`i=LNlaE1ISJi-2U;@(Bd$!&^hyVpF~58*Y`dz zFWNb^hn$E41g`#IxDqFfYnHl0xx1xqlI)Uy?Zg-dmsn`?jraxUufw{mrvU)wHpZiq zC03w`Tixi=jv_c7&|SY7aZPyaaDtTjiLu!kEJWQrX|UpC2#<+-K)#J_{&7aG(6Dh# zaH57{&}1C$c2>Q(9WDM(fjjgOqLhF^xwUa2#RJ}6>gfbFItY;7na!Ovw>!CIdOEm+ z@|}4HMSx~aJK#U36AvwV3!<;t5NtF8T^FZNZz zY&XUm9(trrR@|c^ zP~0kTZ6nZ^iUS$ChXt~D3XJwpMwIa1G3QG;=iI&s38%pNis9z3kMl`g7%9j0cz8XV zTdQx_bPp865@UvMjxOkodRj_HlzZCXnDFCH5Xx_2uE-^|yj}XmGbIWL+91UK&1jXF z?rcy;Zq7ek{ckaSzDM+#W%YR~=zaOe!(}m_>osy3^(JYyDwpVW+BN=RIvf$p;vzEf zNjx}~(G?FHEP}$%7-_Jf&t`lK51dTb%r9nb*c%kStJx@fq4B$*@GRFQ63$bW9bpVw zdP!$=4o6{wg4965NLb91=Wpuj%Fkll6=mMwZ`Y!A@%M5H$wR-{u2(-k)^xMr=|P3^ zWvLG5GNw|c zn^pvW9FJ0ca6GY}O}P1ce5(4qAT{u(CnLuR{27UrTF4?vNvAn&fD8CbvN^znl5A;- zr`R8JVqawbnP7wQe$aB3LrXGpfs)|~Zcw&9ljb+nB4tSRu@+4WmxFj#Fze>rlX4V& zkgiL=DUhHb(poKPSvb%FoCn)RpCzdAliXwR-WDxUdWn%1mawhzby{Nmbh&691=P9J z>g|Z}bH(GOLxoNGw=kcN0mxc(7I?39_-hDPIae38>kYZVBc^k)wu5ZBPn*2lY$r%2 zE8g-~w&L~Mi_OIl{sYu;>$Y~}$%de~jQ%vW8@{PoG~JxFPtq|tF|0(?%1*>Dn9v_6 zEpALNa49y8cja2bBT7wwK^-05pk`awj@7@Eh=$`9hzvA6$w4yX= zv#N=~HY>cUzw7uwG^3ej{(#@^l)?#W1_9_cG9HQn?Ih+`yz63JgN*#K=Ii~l3B676 z2{{s6n)+N&Jsx>s-dPCdOMJG#qZ6}CFkG?xLw?_C9rMQ`lYhhZopmp|_4gT`3^-Tg zwQn&Y+5Dmzu~+LszM)wDPladmmuIw$MV*e3r*9zN-{|bv8f2Ckr|)=m8Q9JQDU?sb zT#Iwff!!)QE9d$5s6upZw}TzYKL-v31=SsLN|@YLP6_)qzkm?)v$4P@gJKKOMgo&F zbKTAxSx}i4mikq|yz|`~qJ3FC80{g-AC$VSSYuXLqOa=(DSUqzhh>t_QXk^y*Pp8f zcD25l9P|3;=__`Rwat_}e{mBhxz5A&uY&4FWkunk{YY0F|4mQ20exwPU!t-3;y32! zArJx^PAnly7GI)6;H0csj$viLRUq6Ko!wk|BFgPOl`?iORGaQkhe{!|m$#q~?vv-{4m_z{BZq<;t;QyO zqc!2UVsy0)OAi#N4PdgQm}%Kv4dc$G2q62ZdW(}!gr7IN{myr?*S(1T7!*GY(zw;N zy;;*uER?62aw<7Gk**WgTO_IHu7+fl42pXZVB>z>2s7G|j0aEC3a?h~txP%dTbW@uteerf?4{uj63#WTL zzUB7&pAz`}UDez|q}8*;3zg&yP9ZoeCKW+8VapZTKg@KQo40;elJdF92 zMbpP|^z}9YtanDegnndp5Jrs{MBfB$B$W2Hgm)`!+_e<1i^(hLyR@{y=(Ra=tLsyF z#PSn>X|jtknE~0PST-3?6d%mX8!;3!*6Z`Aev?VzAT(@BWS=ecmCRDJ?Y z4Z10N6>ioqcD~;jDrif#5l386~ z5bH82YQ^y@0j(B^Oum{jo~rug@u^~@#-Jxco|RW$;fH%$JPN-yPA^10HxaJ-=b~3D z!^^L5bO#s&g%u3Mfaxv8eeIQlj4ob4k3Wt_kwij=wn=kIZW<|iwj^^(13Tow874J3 zwX3yM1KTXhZF@A_SsK_>8r~WdR1ir@S8#*UeM<2PivN>es!oa`igNF^K#ov(#}b9A zTl5CEmclKAf+`PEYL@h~Bq%Fb{W|Afp1+53l(Wc((!6kZ2XI+6pQ2Y!Om95)Jh2e` zl6&J2&i&q0XMpGUM>zk^ujZ%iqG##Gw;1%lcpwnMT`|c`O|qj{5_M#;Z=kbI&6hYBrjm z5grD1d**I(t{zurX_Riic>FI>Y@u)qqZ9~|8Q%s2d{Oy!L831?`S$;F`3@D+aY2Wz zdFt{I|6e0WlhB2A(Ms}03#VFVORNFHk^%sdVQOW7SDhf^>BGxB&-|ax{~DiX#(1?y z=b2lhvlV}|ox=ujsPDiSY7RJC;vjDzOgNMf36s1-6-g8Gp8bR{YbcVy776du@8q`}%RQlGv_V+6iOi^$zs4KHjX%M-Fv?D= ze1M)}dR?DiD7BBWq{pzN)8h2!ael;ld!mu;n4f?@6XEgfhhyTXyd}hl&0e^)eO0UM zeTF%)$q#Nv!sPHHS6vzYGU_{xK^CltNRRmjv|^Sk!sDf~cg4;K3w7g=U}jY{Mbn4; zJ4SR<52~J@#gy%K@=mg8g5sM6dH;Y2IyUm84wPj#eP{4Az%%I`6&KCCqchCzodiHZ zQHQ6Kcj{;HMIK5n!xC$zQBx89rl zN;CXz1}-reiBHk{2Z&uEn0JjWY`5~-Tc}j&P|c1TSIA2p%gY~SO;vZ9+;9PLms*lD z;zbmM~n5?52qT{$%hI3PlLX24}hH=9Nnuxe@9nw|pIkDoqfF^EZ>`SiLbGwt?8HbUXLri%t5Em~`b6 z{1bmiS1=rZpbw}Dx-{XbobAom8LOd|Gv9evc>H}ud0u%ejV2y4a#>v?rHSgd>gA6l zR0oB~C{JR{z<`t$m}Pn-UzE3cFb3}R>+*TC+vk^Q256uP*#48#arOrCKM}=j6)DWMS z8)np_-MD0H&uv=O9_9Cqo!1zRY+JbKhWxK&5P6XMs}B?&2ya5ISeOI83e`9XaX+^y zlTl9ccy1RhYXz3^M(M%%J125KY=}PAR(<0*g*1Lh2`iksr5z{pPsMD3lep;g*-n=>Tdq~t=KW5K1Sk;)(PD%jbg zK{`ns2+E+P1mHs3SW$FEYOMCITQ`mzuV`c5mdud9zFy1d!6k~ulFDv=xnY^|z@0Z* zRfhRimEmL)E)qVCUH$cDo{{k)8)Gj#Hfs?zAH-TA8V{DRyPiKMdiPw%@l1|xCAh^| z(eEB>`OY&UctZ!Lzn7!I#K>MO5KgxT8iw0GyqIF4!@Fma`@E4u zMd2qo1TefSD6FIj(T&FFqV|Os%?|T~!IhhK2sGT$LD={2Xd3Nrm(wI3K{spDUh40# zJ48qCH^7;ddUokNyG?*UIef9RQ z{x;6-XsIu1ulzA1b_?@j@;n*d%(^;T>jB|aP?fWebn(m4=(qDr1~B7te(B{!5?zS; zO`MZ|HM&SbLQLcW%TIz7Aj-B6-?ee{sQWCgoK#QU-9yX)4BJ=RbWr>|fmC`@%r|r- z2^+TV5|T*hu|;*42G2t7){2M|#j%QtO30XLDZkhlB1Z2+*+RazG?pfYp=?1F{UMIOp3G zxj;t8Jt5+!G1Bm4)4JwsUCe$*QvOK`Gx7WK&q<2(OBC*QE5JfLWebrkQO!#0-1}4P z)qk`V3BT+C9wT`jzMZskE~H{ zm;a6pqo*=S`&)3`cf+lso|b5-4rYDG1!v7Lx&Ol1wp(JUf~gh1#HTK7EB}}@X4dBg z4=#DI;@q4LzU#<8gN^@&he36Diut z;i!y<<>!f)^EyTY-yx{X_D4{7pN7X$xpwi5GZNRQ`VVeULLBm1DF+(gX+qq{OsMh} zF7e03`h5aO;pXRgwe*2bki;dHQ;>h$&yBb8n+M2yD`__<+`%=i=sZ_U?y1AnQNp#q z1kDXLkF1IvaxbSRviD8s%=&DCqDnC!bc|g<2wKa+!Fj8ut3rwtW3jOESxHxMx|p4~q&9k&~}-50?`v z|(bPugpxp_wqaXunXPRq1zTH=bPC5Z!i%_;l1Jv{CUON1+C%i(d6v2PXp(Jhavszt(Xrf(*rDgTnDi94c=gm6uV_vlACJH4Lbr$~PH%eKZ{`+U z=l=2PJJR)Z?Ie0vww>f=+D>xI+Ho0VGV5h*MJy*>GN5*)+*PYqm>2G9+H!X4=mLm@ zz<8MqV5X3TXk|_!VRbGioHnx zcg6l_32E{J##xv1&0yL2&Ic{M*ZH8e3-Wy5I9k%>)r@WS`|yNB-(<#~oenwOHbE zj|F4M`hbb3x3%2sq^urdE_X@E<1MiUJ7Tb5=Gtdl*%HsjTVh-E?!-(nu+PY( ziM-f}_j%Y$1PH%Cuh9oYz>`Jl+LGVt`5H^*g|75N=(mhG31s|E0e;=Bm1}qeJPco* zgs-Vv8ZbBi5r?kwFFJHBX_0H=>S;50|-f|J$VWBk>J9A5G~-AB3~+iQ~9d%RHAY6EnV zA1fvmP_$_wF=j4e7&H}%#a|J6`go)`SF)zXx7ap6j$Z=Hc$j&xF|yoY*?0dT`|g~~ zyW@+g%uAe(XH8y{BmnHBKr@fTOf}E$wL^C^8I?? zlAoQ&&n)<{59py&+s<sDb!kbl+LeF^+fec6B4tB+ zg(WKe0jVc)oXOg*r%^kJnw3r@3Lgv#Z&T0mqqRgUnoCr_UJ8P4k|iU@0f|J)bFLZM zJV0BfDrz}Wt(Vpq#IVuR1EPnD^^D}OL9W(MH)@@I*jMU7U)=9^($xB*zIz?tITgm7 z6uJFcL+&{hroQjT1gYG{`MIs9<~JRc-^%&VV8bB~t%ThxVrg4xXgf@BsCBfbxpDOT zmU@l(VQXryg*9wi&2m23gcBBu^GwoXaUr7Z~c zXF~E|zpbNW$Qd1MN$i4xU;gzP?UX8SX-mBScBeT^l6->bxvoCuW8;3h$(Bm=T$wZjyUIC*S~W*Q2n2V~SB~TTiu~b$ybCO5m5`5ZrO_bZqAxP$I zKmtVt9qBq|i{BOlBinxd76kxI;|XTn7lT%1jXJ;6^h2YcOQzh9%7yCo<5&3Q_M`N> zItC*89u%(Qfgis^*^Bk+2ToHoiAvYRoAuNBi5Vr&8Af3|h%d#%EX$tFx$j@2H-`>t z-w9taVhL_-`k8Fh<>32)m&SMH<8k=@V?#iljDK-_|B~K`yGU`&3}(9job-fh_2mLB{tL|me9o|i`E|8jg)k~-rzHY3YXviz*dRouml1WAg^6xzzj zb6(`;ms%RtZ`peQ?1}lC)?aX9^`C35Utj$~e69C6B3vEIT)z%+ zLkAN$zsq_;Dv~Tj$w(`Pvs1)>%#rb)5INI(M756Mdl%Ih@JsqvP<#cyP}LBmW&r{I zBnh3ko5T*vr6yuk*23zwps-OtT?qNVXjonuSUKBrs00O_$3Tn2#eTG>gH9*pUb z1RY;pcdOUO@!IL+VS=RY?Wq*O9L_{sim~e^&hH(gw$q$q5^BgK_m&?XLSihR)~N{b zIk2kqsMJbPHX8?i^B-YBskd^hk?%M$;n4C|-H5H&ZB{-s(){ZsaJ!;8%KT@%5m@?Dcn%3OHqW~Kz|6IdxA77GW@ z%x`~@ip^=h9I?Fc?~G({06jx8QZkvy`)My-6DtawL-J>$o!s$q`kJ70rpQxmUz5*3 z&~i+V#*_cx?+%`9unswUsYjNd4Iz@dVhzGXD@`MII$&dx^(0RO8wag~Z!v&$8n~N5 z()TL1OF}bWX5x2XCp`S1cD-*G7RcZYwV)EyT>9R0sNTtI21`Z)PzD5O4^XoZbA-2w@#ya-T574wAEygcgBBm20*MQ*&O9$Z~3EX-4ON61f z$#8FRzEVx4towG?a7l$jN_ zT)t4SGW7HW{XBP$VkPdiG0x^~fGD^i6qpdwov4-;8@&wsgRpIt-n4bCyk0}V@2q&m zpqS?>MgoTceQj}iFcJKrz2gf9+k;VAxGi1S(B6eZ2g9nCnFc(rtD);9`q(FYv0~?V ziFVd9C9f=TzovOo=>g`gpDxpdVwdY^RWWJag%q6lEPg1_JTc z43i0zax58<4pdcm>P6f138ZIpc$>}`?+IU_-HS_W;l=d@!&tlVDD61wojj0F=u&6N!|Hfj=Afs0>>a!%!_(9rH9 zcjO-#%RS9d^L68Ouo}xEOpLA9+6CQ!#@nxpF+UB8pP_l1qpe3!RJ9#V_D<)=cM$^V z5cB_T@1=r@1SuIXBOqn&%pYx>W^`*ORU8=)n-*qNWecr+Zo1@w z=I}jhpKA*LggY+k1rB@&1n25G{Q!d9ES<7QUsBt>Te%E~-_Vr22Uq7n*F> zlJ@++NT$%b(S_(L`AE%*IPSRMXSiK%0AZE?z`~m?pys=f>QW=O(qk+}e{oew9x+M8 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

t(ZL|?b~H|>hF`U=k(qSOOK^uc3k<10UHuY{ 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

    ?pdsH`S*7^laTQl7G!s7!N96CZgQ}^27pMf0 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%0A4dVC)P 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�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
    c5QxB2HQ zJ~t)??MUPCnHrV2KO<{vbn#JSOZHjJ>&3-ygVAvtMeyK-O$e81>?+OI7h8kB=H~kdt&3Ju8vL$q zw8?1n1C1VKD(UT>6mp{4PwE~KNpBbTcnJj_>5j`89v5B@#g>9%QT4% z+cF(y`N48nP@yktQ4)1e>fD=q9;?CW%+CiR0%T7l*@W%$pF`N%3INVf3&7$EhSyH2 z-Vyb8!5OAfdNLJ_TmehsuCDqDNb2vR0s;_I=7SE*#KWEx&RSSo($Rn81GT}&7KV@X zXqMKm6&ttaF?XDUv8_G-&0w2f4V;m-rgv78drXJHHvwYq%mieEDZDc9W}P^;^S8Oz z6d`UR3~*Xp20*wnnwRxkN4w2kt08t<`@q{$%oi_&~IJb#^T z)>$Wh6E525a!G@usiA&$Kg6%@DzDYrAzXF6{z{9fEqqO+v%9wVrZmnN%ujcI8mOoj z@n2hH)vctFG;9yFm`zoC5ss0Needt89krJusm)~4KqWQwbY4*KawM?Ju%kbl)-;9nRU z35q8nDPbj2Q`&i~bj?(aS(L{Q$u$%IR@*8Pp!p|&iHf|Ul$ssudybdfmyA1pg3tB( zIQlcOdRo9UY|Ky?7W*x^k4T+;w(#kxjrc)D7uv${SbU~9z{$er@WdjziGFzq6UB!* z5{r}W&pZ(rkwThup+4KQPE8!(CVNtRB$9lkugyqT7bLN*$TJai@az*BrE(h+cbnR` zliH)0d^0$KI>N-E3&t1r|3*7Xw^JIlzp#|xK~S9T@mY=4^&);ZpS->g-PG2ZbcrL_> zW)nG!3Ur=`bBsD>@8xo5+EWQo5LQ#G;buz-!NVG_$eX;6L}lL{5{cf zJ#FurvU5?&nY0JUHhsDG?t%};shV~!T5Zw$7OkP*z7+s*bm5DHs0#!BWjFMZ>;U zLdotP?T+6}Pi&{Xd&0i4N^d$KeffYD+yUK;Ne<{?v?z2#``Yd`)Z9u#aCbWAphctM zRGhc3Znmo++L%!^=pQK;uw_I5pvBIa8wiY9V|8PTBt1eW4bhMl^VC+G#cT-ybT6Km z$!t*}``T3CF^~?}{9EtdOS{&DYRELkmxmg}5B4>6ps3F>{`g~+RnXnBs*lH{i7PvQ zK%5nQoZtEwoQh?Vq2_%9xbcgn=nfvh&dg8ZXuepmEa&!0Kkg{by8na%hNlyMjV6Knb(L)6$z(Hx=ac= z{tBEI$mh1WSu=ct4&N5{GmZrNeOyw_{l%7V1t0A!c2GKRG@_z+FM(sEjpSQ`2m8*@ zh((u~({>^Is*2JmeaIRAvxuge+0VVcxq1uZHWkx=DP>U(MpO%LBHT%HbYpu^lHbXd zh5f&yf5P%$#U~k3{83Wfc$obg$7&G&OnIoC4RkafqvS|k73Tbfpn!W_vO7w8yi9CR z>jJ@p3#W)LA!?^@pYx0$)@d&LZg6-)48=Jv{k^)%Rn@MUcr*E&KFJO*K&n}#j)Z~RMAy^`-FM`|@4d{C!kuEgz zp!iKaDppWON~v>pu`!NC_j95_b%1bH>e0}JSnYO&mv$KWOsRC40u@hG+aoays=wI| z35w$bXH0u3Gx3yO_$*utcH$L{8kFM)R4=ghgzw}D!}n|fjP^v5<`L!}gVniiXDcWk zPhEwNH8;mc@?i4@EZ}E22pSW(vT!42dpp@scojp!FUaQmgiOc3uC$dTqbuP(@zIkW z>*fJ*6zV%F-k{oTeS=ek+|g41aw;L7)N%1QlJ;RPP2qOzEB~Sd;c+WgHe1+?8Myvf zwqTzK9(z50j<3nQ?s7Atpd?eq`x)61e~;5Iu6$x84oZJTq4<-o-n7Scy^(gl!Ft}^ z9RHjXA%j@@;w?Ij0Y1wRvMb&IQ$UZmIP0bNs>=8A$9y+vkF8%dY^(hQYaJ;ch_!48 z3IS4_jekgk18+44#iN9ubHMoXC#oh~8^{R-JAa|txqR?V-bHivib3B7F%-?- znGmA^^dW1!7T$_Us~=yQ5OvM=SYp!=K9RP4P!d-l;=S^m^9pqaZY$BT(;AZA18zs7 zDU;w#!__R2$JTc$p1@$t8cKkuAHiFF&%{*PWBE`eRXY|m(qxJ+E67&v3Q_Z=ZSmCM zrAA_0#0R!gI0NdS7A3{o9TZcXP#PHc5INAZCdI!3`Hag*4AjrIDDC35_)(@3>3wzXio;uRnb>lG)K@8;+yVmvJAHVwZkwrH2*KMO(S zrJPI8?CYavsCZe~r`;@NGQZ7rzGC+>kf1dV&ZG-ThAX-tIquGe?s*!}1q;H`REmcy zr}Gyb&QDLYRtbl%)yGQd)BII!Nsz5@?L-p7k{s?5{4dXW&1QL67ZoG$e@p5-woaWH z%1tWIzu)|+Wtos!;(kfTFux{RzD^IRS%U7C#;D|+7H);TS4}mB4=4c6&P4+e_tDKb zFMR$`?gRUK36j6n=$+s%tsueM#uJ~!lKQ)Ir3@&NJ>MqB%lB$%iGQ(KJtBjx$Vlq>brJs6aV&hTHc(!ZL~|@X~#jf|Juy-!A;Wd3FXce2J2w2P9f=J zG~tYS;rR<#yGb^pVsori8?nq%vS>~8W4@FP>TcocM6r>YyquT+t+W7Zzovib{tV-~ zl!Y6CmI*hqB^=6=>*CH;vjvNiV6k&mKY#s{BT74Vmh9`o@nd(E^o{WT(hX6-YbKoe z+L}%Dxpj5=oPvmYea>dYi^*ikSn%t`?T768?6igiR+rLoU}bXz0R1eLE+O5av*tw0 zF*ifD%Cs3Hy`&8Y%Vo-#t`bSCBYpay9VKpZ;IZtZTD6pI>>_TIft{lj}6`r?yF*A7jv;`6}2I(Fyw1V4^+ zzy4kK%Zy7VHQTm;+JAWWc}bha+W}?L;IFr@+y3-U*G_PgHo0m|e|_=k)Tl7vZr#a! zl8!Hd2{EB+n=r;HAsf1tB2{u_3NeeJ68!6;u)H|#SLz2 zX=h^98g?n?T>{GX?Q5^305B&$m7XjhVYnrlk zR1@7esj^&$P#6w;At-)dLeEgO(l?2;+A>|L%b<`D>~8sj+u3BAsRN*;!q_(uUrToU zk*t%tGPAyq=ov{jx%1L>Q=qS1dwH2;I(pFq;y5}7A-|)_tm&dBLax$XvnIRxT?nro zWkGOwOGz_p7Z_v=AQpzrq>2sH6JGr9!q5BPt1+>|<~YgI>CD`v@kcXea@}eCsGh}# zn8ByEKfV2_m!1Ie+zftE-yHck{EfdEn&S4O>t%GFz>T7OS;{8|{YldyB5mPrepfN(_m7nB}Tjn1%kvQlLsW#OWsvWxjm!PxY8mwV2B%Uy%620KHE zW?8)o_xW(8~g9@yiUiRwWk`C-eL?px5bO3G@HPv`TKZ(2)U$}_SwBVr%QG~Wtv&` ztW%~hx97~FB0|`6{b5a8z*c}HUP`HQS0kZhQK}W?eh=p6iSZjG4?5CjOvgqynXD!@ zEGrmorzZD4cD}s$WM`XU8#mQMI?;*qPlSth>t>smm%M~Z*V((9T8No1Q|z4AGTq?* z$3&IVDO@warrWPU@jIkp3Zf6^UA#*sE^zE2oAKaN)%jO)Fm#E z*g;<;5V-5Cp;N(y>)l|Jks95GK}Es4=j@KVhShvZea$rsEBwvdSJ@v%&Mfuz&~)Fj zucNNpY+YV*W#TbDm+Vzw-4Kxu}sj*<= zIJbpJ$7=Lr=OOH{^2zLQ0dDTu9q(&p@peOt7H2_<>BP2Q?QMmJ=`kd8M#MeB(Cw!qF3Q$l^ zrz6#pq3tcM$-w92EEZ$H+N3r!spDL#8qK8Ic>@xG#8OQ5QF#AEA;#7W{o5N9OirRiytOL)#wzXmhTIMHF9k^C)u_baXl(eP5j5nF66V| zdv2PSaNRqudZb35n2HKr+Nj5mb!g||VIKY7?5wtOeh=D_imR9Zp=ugB_lLbt2Bq(- zOc#bf_5m%7bLs0!ne(KXzpU9)$WIM^4phazlBBrEz0YX3!ky1XPniFt@l!d4X5fO; z;ui+aIyb*dr)n66Y#=Gi&p*vwP2b;*=C*z5OWd9Ql6h_I*#4OvFE8D^{WC9NT8(-) z|JBpV@#asJWFiKbT6;8?sLZ+keIm#D!o6=n=sutu(P3> zxU1V}elQUN7uB=sJH1=wFn@h#-+-S*b4_isbLTxB(bags2E`|Z9GIWG9D(Qs9G(FrKpVB>yr{=;s4!Lb(BjkJ5CfB~&iRa_)aRD~83mL0w*alXDeUR0 z-X=I%t%{rVFB$l&KlVYh$l7^fN;E}n5nz7uV<^cgVtiz-{DFci!~Q0My|+|)y43aP zhH(&ZrN6#{Nd($@%&RY7O3i+w&-)ywJ=kx zX2yTzvg?~pWS8roc-_}C0bBJ-o(66>-QO=dpY}GDnt@M$bb*g2EvLbTQYyi)G zOqwkq`(&h-QQBDoQ{<`MYxU9^jWxtisT<&n_b>8z6BK2F8VPs6nDU#;9_ z)HqT(V4E0IidnLbCy}3ZbJFd}2kEwI)D-)U1OxYMb&zXigSn9wz#-Cd=@|ZON zKx}Vz$kkg8z=r=|G=`(eret&sUdRpctu#Zuty>fJqzxyvljx`^d&=hd#GjDo()v7Y z=hpd4d;c==H}-Hwg=R>y;o8>y%|H~=d|dM(I$pp-Btg%aMlD1$)IUy%s`&hjn&bGmp9JDK90Xq-5ikc+ z8D-jyc$yg8Vhhb_{JN*P(AD0^QqYqrdf(yE4YtjFHvyUt z25t*se+!4G!+!jm@YNu_eN#hY*w6WszIPA^@8+I~JiYVgp40d_;pU#x`8o0Co-_Cv zcXQ9AaC70wwyQ-Ya-$1RPYUNwh;Hog!U~&sdR<>+2qhd)7d^n4D5yJ~p;{*L zq?zKkM3IXdK7 zAmY!HE!#5=DB0O-*;S7hxs-PO!fg&1y~{TYTfs^tMl&~?d%{jeqgsX7zJ1Zh{~=wP z9-qpkJrwXC%PaM!BB!ZHx^k7{*1u5*BSU%Zp2YL3{D8uYdS6sm(WX&`(H_SB;0pY_ zoE%<}m1USJN#&YH(Ac?3 zvmV@}dlHsy6sFj!+3=z^rKi?SX;2*CopoP=0S*^5p$UNeN`sr_aZTd$Nb|NB#$fa2 znz7;39dca<2t4EyNO%c(v^Z6A2ZxROkF;~-pVE#^Z_YIL~bP6{o3X(ax?($$5b7zvg5B)iOSf1IA2G>oJ(N-8xBZc1EdM!lwDuc-M2uDq8IZc#XqR&lQjEsY2TW^Y?!Wn zQFep5ypnhm7`*FlXiM)0Re$ZU*)iNglkJekb3lJAL5G^gLMnj%L|_ibYSCyMnx+!- zsSU9tO4Gd`1&USCe;KQrBl;I6~BIw&WM zHO0py-XqbZi%hTgtd(227Uten>5(4RzSo8+T>rE5ATs-HioE`N?sR8QdY>b}HWx4FP;M@Ar-37x z;d6(kB-Z$*Y!nJR7E-N6EtBIz*%LSJjnI zJE10~xh95P4H1-1u?jkp3V!pnyT5hLR&Iu>vu*SMUUf~NH6p74V;{iSXTW%4`)A&G zdFk%$pV=4n?iM7%o{4qz+`O-AY%}pNsie}=-|^qZgy9+Hc-Ojy3qsm@d=O;Pr z={HuIVaVrR&K#YV3}kgurCmf@8%Q+waw%uN7SSFJ00IO1(fs;Pg^eBJ*M(F5J(kI- zaLUVuXR$UNc6MM_8}GSn{8=KBU$#o4OSTn>tL) z?-Ag?N`|x|^_Yq}hgB5oaIN)ICE9M{p5rOb=0@g)k7)9$h4lN^Rb%p9k&m_%UTv!0 z>#)>;u~k+4k)c|RcBO~f+i@Rv^d|K^GTM5Gl@E5Mk4rO+J%Xbd-RIN--Hor1*oHsY ze(*RrtlyEy?~&a-S%+j<>xSF{X**77W@I09%ca!m6mC)Rpi1~*bw`?DRCr*CmDQch zYjP-Za0GqR#i!6%=zW$t68%c5m{izYqP)340pxGJo{L)eZFwK%RDPZ2np+Y0F;b#k zH~wXNIaS~7T58kwG=S}z%vG23!E0d5 zX6b77G4MnnRp=>oR$EDRS&TN&$(+$41m?g;@+O`H^;#BFw^BN>iJ@K>S&K90`2E z3SFuCCxg%^33v*Af~0{kzJw~=6vvZz6k8EL5>>t|s!XJc#(6az$$o!r*!TWn-{Z`8 z$%CQ7FPcJ|$oLG6N&Em<3-QCv@gybL3lfG#J~9=HFUR zIlXrT#os`Mm0oST!$EE*i(4+H1mbu~?`=WxA{dy)oK?lyjIofVO4Dmio3u*PD8t@unVmoxvEE< zn{chFM~79lnOk11s%KnP&k#X-Z|54=yeaO<|B#8DeQ+54JK5RF*bF2XUBw^rG%VU_L8Elzl6)SK*cb7W_D zWmmVcJfGnek9yCVN^Sz-Nz-*pJr?B-*?k2hlz4U(FmBLHCp7-GLhow?rF^Y({_bGK zhb0S$$plzBxm4M1n=SM{!}n)8=Wh;H+yuH8de`xNU1#scV8#3F{eHgR-#LFxu;Ljt z(R(-F@9ylqCs=Wfz2DCF+dJpq5v({)?;Edj4nB+P?O}@md%PY(OYC);MJ-`lEu=_0 z3t5@LCy-qD{kWj`MSD0A%(sW5;p0K^m-c*2B6ot~VW4v1_wDKXzuNcX)A!HY``GmT z!VGM(+f+*r=rjAdb}r9uBHmPLWlGM)Tcjla70w`r<|xgPov_qSO4%|Pn%IUfO3bF} z)rnpU6FVvT81-Q)!DLg~;*2)Qy*Ag{?&4R4m8IL6$a3j6{%*3rbHef+yo9Un)L&tA z(_@TP_&an#a}xIkt;Z#f8TmSqXpDWFPHJ?L0|q(p2@!gOm69xR^R}M%^tGR3H1AU4u0N70zmjKLMDmK7f{VNQJlo zv^i5&PM7Jl#iyza!RVkgE8$>2xF4!*szPhFrJb0QRgSdJ?@0SeL3+E@^?4%WEUaa z*WS+Zr!8v9{mj?wtOkj{>4^11=hc67^(FPYIGh4l zwm;`Y*S8a8_NU~Jb)<&hWSIChy3LKOjVdVWxTqV$%L({m`8rdMA+2t7Jj?ore8;}r zuB~Zvg!@F)Gux9g>lV(TxH!5*fvP3vV=^0-3VUklxu1}ZFA=aiUW$!uQyDWt^?vl$ zjqNVxi$XfX-@SgZ5F5L0uP;_%OXXe{fkfA9EWO88HxR}d?w-nKGYtqtSuDrcgZsA@ zuYljEo7i0z^}h6Xyhby+d^cIZk;^UM#O%7;Sd5!fS^o=@7*B`KC@cHLZH`(-84`0w z+6QAZ3q1SFZ0lm|ZV2(SPFqOw)@s75O_eReferAa4TL>oYhto`xWU6b*!Ey_4<2l9 zBwAta*8^`Ik&6f3IxP3vz*~n7=3W|jYq}B6=HS6?<#`u0hVys32Gf4C8L@?^3PJH! zE$o-5yV4Lm=!vuc7 zrxy+Qf6~z8b%Rz(UAD0I(RyfBa`SOLWP{&qr~Eic;>x(mK0-MRJp0UX;l2r32^2px<(!56@Qw1njpB<_MKrR7>wj; z*%04AH3IDgDxIB>+)gF`#c*`ClCYBoJEWv69~@q}E7?7KuB@b%XYrV%&Hmw)yOQ&U zS7;@fXB=$ZDy{jG!z<72Jb*!nT2^UY2A8O35ebH#sl{Tj;xEZ_W)njiTzpL7_l+m4 zEA0A1Vcj99@A0L4B8eK5`k#e$&7@M9$8iWa{xEqC;?K)Td5dpZ+g$Jx&)GekQ$n3F z5A!$UlopWjGJ&@cHzQ?*gVpyXdP6M@7jZjzmj4i}Sj6BKm30}I_8(@d@uvl(m$Zgl z6G5XH{^LKxFPuC?i&e;ZZ5kL6QHWE=7?534+O37W6@)15siB9BCuN8-QXphdU8G|* z%j*hBF?4>rZ%<_?k{VB0hLF^91v5?oYn^7vWX&qKFe8KAu>v|e01eY`CJILgAl#jH zP{p)cS-VI8Af1&EJM1%o^T>ABNh(^iF>tFA)VIKqZ`y)ny&Xwm-gg)b?jw5H~jUIM&P= zdW$*n6{;`1bu4ji?BTfFgu+`#n_LWve?w9TM7Xtp{5``q5lwpuie)mf`xm~hV_O5f zfRBe1{?M3P;sFC;GZd*7?#V!#%4%3C zzNOuA*VIribH_+5?gjgq^~I_c=5y{m)NiM7Yps>pZ}<8iRPkc2x7_`^!v0|K@eatg zW5+!TE`%iQ5F~jbR&mac&~aR`44Sh&lTp$WBI{VgcD_$`5O@}02#rsy!OmHs!0`({jNGW{he-Ksp@ z=+f?f!RXw1Y?F10zsRgBR2YWJHpRK)D?Ri0ZW;8OqLjs(Dt$pZh-XAKpBG~fUqGxg z#zf?JWXmYi?)}O1oi5n@$U$+jQ+Qeg z(-FW#E4q0ClGW{pXOlVXnHTFsy5lPudj4!ZJu6-^civRc#l!h~#Fq(%jO#@2F62|l z@jaY&)`jyi9tx328<^U_9lv_ED5)PZCyMt#bO43h*0eQte1!j_UGd^I{-F31N_h84 z6L99t{3&LRV8b5DwGTSlm|c6JQKYLbt~RYLi>ydEipxws(UvT?!Ub*N)LK@uTD&Uj9o5D{t+8PP&L!eBw`~<&(J9LR1>BN5Wcw_UNK45`LG=;jDS_ zH~G!TkIa38+=)iG(>dBt1@97whul~v=bhFlyXe_!d<#*V_*n zyOawH*+0oFmZ-NfYvQ}j#2-L6|pWAD6Kwx+BzogFPw6~Mbc z?E%jEQ=720Y@Hjf{k}D#O814`S5=Ra+}_vI#vLy@W>36wz#Yv>tKb6G!o31L(39d^ z`yz~|&t_a8#-ORGh>CwpvK4-v9!Rc!$IBTP-xW2sj$@?f@`B>^$x3l}96P4xD}H+7 zxgPH|V#AfI{D|!Y1@WuWghWm}sv)@9Il}oPI15;Ic7md=nXvnd8JkY(NTirWm*#mh z38UZLFLI(k{xhj8;3hDa(aUgu*5zqW&V;~|3A>-JE1P*X)fj`clGl=I*W+{Kiz;3F zS`4pnSXX?f*0i+|Rc2kKKGFB@s|ImhdI0D>X zN#VYlOvB2}K6tqeX}ME004{~@cs$;Qb9pw7@!0zQ3g*^=-_T-ubyBI}qge+2Q|j}C z=oi?gC&d3ubxvP2*I>B_GAffn{Ej%4ZTp9YM)2=8`#38q0#~IX66}6wtaE=5aE7nc zG7$GVJBM0-8BqDneDX=UiagDqX$I~6l%9TUnE9_(dd{P)yv6KC6U0BS=T(c9z6F+$ z_#N>I-=M9Gi6Q@isBd8{U&?hz^?j}MnJcgC%B{|iCOf38KLJY2i(IJT3-WqRrsIBK zbvfX9T_b$R6!XKWE0({Dd8{V)>$=RIANE~FyXyR8hmGNe&X=z}vU(12()Wkv|GxMv zh>_i&%X~+D2mCvqs3YAS=-iOsSg14(Rv&co$Y;+Syo&l3F#TsoeOHM(ib@z|?N*K24ZsUb*kJBdC^h@XQyJeLM0oj0+bQdz=l9UItSKN_vE z*iF(V=ycT6;UOG;h~nWTZIwQ^_jYMpcpO!TUt3vC4xt)zhdz8LNm5}Hk(MHCG!iQL zYFvSNZRNz-r8<3lLakixv`WL-pUqvtk?Ctc`IVbAE>g7WEOKY=rA$$-@WK@q|K1Lh!vDW zyNCY{soMx`#h@J@;^`&#v=ih^mWt9@QmYJU@;nKQbx7m)u|2n~!y8ow-ejpg|D12o z>uq<@tR3<;jBQ&>*s)a4+0pa#&#X+uBV zknQP=qxC8$#ak4?PUA|v3hzfySRbuFb}ypu^5V(%gtQ#Yy;ns>kae&5;%*#R@+TNw zNy+H@^f0;>tF6&B-+dp^vVI6i6Yd~B*5T@N{2^P9FH&Fn`OK?voQ$Jy?JQ^pR2e`< zeY0zorskKZFZG3l4ofE*wxmfJIi#;0_7x6ESY><6NU2sPprzKp<-8sfEtsbr>r=zJ{vn0FF2ykg%q+;0-fmkf%2Z()Slob6{bel?@HFdsp2 zcD>#qv1(O({#bNMHpY_R>rwAIBaDulka1cgze%(;)&O{`KH*{gK!y5v@;5%T3fA-l@xo>sl4yE$yeZofp zgMMPSOi{f0D){2%*>s(sNzBH6Ub!HN8(_`iUHq2HW+dK=VI_Y;^{)mgqpCGShGn)A zyr4XP8%6~k>#A2!$!RJ>>dcsb9OH~>G`0OnEgExop#_I;T9vp!EN&S1$SL9e+{w}W z%~AK&fUQG?(vEKMI&-+qhaIs>huw1*Zm2$Y;Qm%&&w|>0z2BECiZC+dQ|azop zp}dDD68?w^?|euioGd1LnBN$lmE$fn-C~CCn7hRqKba>V|36nucUR&@i<`sz=HGss zdmouf6a%{LI}%a8uetiTx0hev%GKQ1x8^^?5bAv?n#`n~Azm6$rW>FJAfQ^Uui=LH zGeFNFW^KP}*`5VVdiIFca6|*^18t$aQM-|?T-q!SqYfv?5|#Fn5TYpQ=GbzGu+N*&c_!Gy<&VknlYVN({g_4X5S7knC7r)`;6(^ zck5*L#}|EFTSfo)#Je|R4P&Qj*m+uvdpIU&RUudzbI5ER)l#H$cOqb=LD!RODbaEJ(rnZ5~~XK$mJ5dmx+G0 z*eK~fgZ5=eHo8{{$evP0_ccH#L836F2%@S*gXgzdGn0Yj5*7ro7eURoSV zLOjnR5~qkJI#ua*z~sjDmdOp3?$*KP$qg`qHTX?^q|)6nFh;5E>zee_cA346oy1Rg z!MLy+_A!-PIum^Ep8^GPnnG%2t8HK={(b3z=0pyWU+1yJKc?E;cBlAcY{9;B-WQo? zt^wB(1W$N>bToIomW8)y9Af|ZV|B~te(6q|(Vo&U2R#$0wyoSVj-S>ti*3MFCJ-Rd z$}TnLjte&j_w|hDzZgwx;jN~{@RtcxJnsMq*VcN&+Qe>>V65#Q-;KQg1QS5Nbo;2Z zI^QqVnarM>wOXB4v~DP-`K9!){XBpE8Ot}9QqBe1ZvRcwm=J?=h-q^UFpRuQBR9Dn z-Oze4-w-|YLojU7Qz4zmWM4rr#?7>9jSIo?}g6!so}gpA&v-;uj} zq%zt8`2tE{^Z0&>F#^oAdrwWAjO@p0O7Z{5bkX{=q(2!yN3$5XhU6zML%{KWBHI1X zT)9ty(QdhTyrxc5?glN7h_oi;Mb1Hd7_6e6E-G2= zDoIKzX1B#7L7s8mVO;9Z3vpMv#|pE+PIL=sfQoDSBHtH9-L1iW-7V{PkMabP`EK=f zWa}fqNpwytPPXT;d)LM50LO9i8HsNI&eK8;p@-e6E`Kv z=k;X#8q*{vKfS-X)(quE=_yy&p6PIDOhh=zp`DZRzcdcWl0V~UT^k?rxLMvHsZ>Md z@wjaqsAi>L-?X4Ou(k8@jPD{Uu=|%M0b-jwTa=v-mv1FS$L*M`%RWENeGGfrEfY}^ zH7A5goq3ObTBYMwdYp9cnZQd!I10d2dL*N;31+ThuA9Fkz6RS1X}4pYMmKy-u{FIa z!>6!kkfuS+fGS<7vS_V;m716Nia9U)+Ft)E)i9HJT>Y!Kd*U9wtJeiUW3REjCdHM5+#0mAbw5@3|R5h0HU_^KVUCh;NU3n$}&q(?f z{$kD3dRv3ixo{2gbt;PPM|iH@;rJKz8vazjmk?r&UL5_sjqTX)m@VBqXk0(VCnJD% z`Z8@){%4-B@So}TQ^`mbNh@G(2Tc4ALm~B*A!eBckA?4iNuy9ukFIpXV@=mXF@Bz zPYQ)9y_?<7R`;{R{p`^X=PsWVS*qf+GB~Fx3nEM=f=Dk!v5)evh4XjG&Tt#a(X?pE zxaebC72XlP9^Cg6oV|kkHglF|{jO2+ANv+6S=76=^GOi&x>4bry;1M(PVy{&ln;zf zRckz5Ony+BMdGylYr*ofc)+i8@#tvQghPAxtpDYxLht6ra4vBdtw^%TTkh$fyrt4C zfznWTqPg%^$F;vt+V4Vs!%XzyWKV zp~@c~&FF}@68)NS;S<4q&xf3O?U^0i_gpg0|6m|Cv~9_yMVtakhLxY#nSU+!K8BO{ zOf#ypCxmk}s@jOEA9Vc4B_`fvS6I)H|ID+G3ZPikTZ7_O&8yq$9vKST!lhf8ahp5N zf;}6}*%Q7VF4|>Pb3^dbtvbVIekww#t(`s1?p}EL^DdvG@vstlU6kL`mir&(<574O z7o{flVM#5#FjUypoOy1^Jhx?@J2KB*JO>XZg$JfLQpvI__9%E!Vd);d;lkY(ak+-P zxLK3ZuLLVo^WvgsIu~u`Y7EVtR&zB{>P?A+`K_Uh8!(Q9jB>9)c|mjM6QD>?e4fn; z65{XiYX}2&FM3j#2HrS44^}+EN9qF-bM`prT3aQ7=y8uLpFlZM^zRW!E7pPE!Q5xV z*Aw(hnLa(ZPB6~nTcDpCww;k2vsEVD*swS#|LfiXtnpS z?BVgfJc8-1XP@t^5^s|z%)d`oistd@-3ScUQ07vrHqZTx{qX0 zTX^xr=mC|%L|(clX{=IOmprZic~kX04hq5FTnI5%3SxTthwnqDbt+hXtEdzc2kW{T z?~K}DCWf3t7obMwe;k#qZ|BYomVZYutk*=n!QWzc*D0m7FKpr0$9Vyi`Q2pemD$TZ%FRX7a{BG>EzbP2THr8-*#Z{_yrSMo5o3GJwVXfXE zp<|B{WxbIi`^Mxc;V*0TBMNR($)t`V?7YfZ)CjZ~i7M-9bHU7U^%-d6m)* z9@Gp0g_EbSB)8_sI;rV2PvVv8dwJ2Vkp%;&Wp))vA`l&?@!4?YljIA_4YXP*J>zR! zb+bxKkGHx()}XLf?QsV0-AQvArJ8$+*@z5OvbBARUGQj?Dyo!<{8eA0mFo2SSLr=k zrOpQTS^wmV@IR3lk->lRQ_%yeG+L{_jq8H@Y>4G?7d37wmt^Tpf*okR_4w$*CQNSS zTZ6}sDQswp*4|E;u>DIEQZqE5K9t+r)+`$s7zkI|g#L1r{jOiDx0BYtHRe=%59gI{ zEv#?sEDL5!?u^O_vJ}=Tp^;m*uWgGKOdui;eRYXgKL0@-U;7$4IxSyt(+VIFtY{pq z0Vy4@eKDE(eUG11s-8c5=8?xM)zhM#Xc9SS5v{$YPwP`m1G5j}QS^vv1 zoh$F8T)0wmy?AE$Ja*lc!j1L2S{x=p?5EnaG+N>JKS7YEwL7eg0M5M=uz*fOel7_U zJ1_)(M6>YbtF#bqrmpvI?zH5fbR7q;T_-Eu=g~J9k!tHKs~_CliFaJI%H{)xI4-!a zzk{h&??kP?MA={5gpO$B9e!0z(2+`EK+lbS_!@Pm1H#IU6mBROCu)q!Z&+jZtFaYJ zaCs#_#W?BdDMJO$oe$Xe<-62Zv{QK})T~*9YAM`+<>Be5q43K_8F@YLZmvEUbxjP7 zNyXnI68H99j+e)0ap72WjAN{(YbHDwQ5%%LsgLD*=#-+hue7W>E89JuSX)7kQm|Y%7h?52 zu-q&@L`KS5qI^wktt@8sSdE88hWZKjI`sj=`1_1`X`-H|Q{`0x?c}GzRku?#TD4i= zZa=0xeN?#edOhE7cH7{w=0FgRRw*&KZ&UDC`{9w53EQLp58Uh9@tI)pU{n%cFVDZV zytZA86P%O>3UboSFrML7O1g+dkQFDN3Vw%s!`C?vLWsqE_{Lg5nQ-N;)RjM8_yM0N z{O&L=XQGjxRLPS2Rb-i15S!4HWO?>m;!<$GqYK7qnTGpdif-elq{{f#=DvXfEBRJ< zqVdg5K)k`HvnpKb)1`FybWWw{GGNQ!mPyAzILD`VWYRl=;-C5Su1tCt!CG8;xVOk1 zK+CMB1LO#b&AxzEh`BcRNzXws1}n9)`B1X5DUzC5+3fJUD^c0t-|OLzRwnqLcL4lb zGVtHTSp^o$d)<0h@LxFyu)@+U2f+Uy$?D;6nal+L?5;{_fV_-?h(WnywCpWzP?s%P za}%vpWqf3<4D46)vEV+Y@ZS&YZ_B19@ZS&Y2eRo2{PzRmwe&Z+J%V};Khr^ew7#gyzvE#r_>uyB7xuS!dMZw`_qO!? zV#{CSCvEy(61W>9`{^{g4VL$FtN^tBN!6CENqIOAA?D+=_~!Vg5%T1x8lNq%G)-is z$Q$|X6w8@ka{ThKV<2Uxi^v64>d61S9ui-Nz#tslD1ysvUcdXK#?3#$2y<)v9VMfT zI#zvk8?i+eOo%VHRQ1~UTr!T4_}nLy(-g`|*Le;nOyrvA4~my-UFlSyqmVM}TOo3d z@3DOqE|aw5xJxG?#ePNM$do1>U@HJCr@En8Cw$Ve#-VcStf2S`++{F$ys@wzZA}tA zocYy$=(y8V!6iS7yQzR>jWu1F;ds)b$F= zLDI$w^*4TlA!p{%eS-%dQ{RVIs)S#Zejp+IvEMSDrC4v;qKhVI6%X?isZ(F-{#Gfi zCbv>5r9H`$O^uS771IS$BRU4{0cj%QwJZ3ImP@GVewN$~9`6(pLksculv{N8CXTlEsdiJ8+25!v%h6Y9DT(UJB$Kvg)1MW%_Wa@u2e^^`#{0E2Cl0sozCX5 z{7TKOWehD_{4wYuTB{P_T9vOp>0s)Qv!sTH`00J*G)*l0vf+T!;92JV4PTr_!OF?h z3Fx9M`badl=D(|-o>$|GtTJiWY#dB3mrZ7F39V2vPgdShSM!(ar|DHquVH_9lTB}n zs$;L(y}k7xL=71Lc0q9-7@F{pOL#2o@ACYiv=<5H7(vv&BBig!-dh`?`)8#Ig2j@K zQS*v$=E_?O_JT&KG>5Z`4|9CuKZN-!Z`ObfUn@YF#@01r98R>7J#j2_;=m|(bb2J> z#FTgRWJ1&AWZ$G_}jaDj2or_P_XuzF|aepIrqn0Muw8S5y zoHKD%y2pvqL9CY4q{$UDb84ND>C@jH%QZLuk= zW|I@9zgwMwT@lLt>Is$7+jQA#ez{WGpF9_?Z$*ZDhh%!oGVt>)_>WFCee^h{=B<<7 zG%G@3|G?5i)(kNC!u~Jbc*vSBQsCxM&?vmNu&J5J==@mAl4lCm2AD5|?zER{?-Fok zun9jyoAB^6`^MIwJp?O0B*Ji4JX+@xzsL9+RT{H?vR1G%Wp(PsBPrFEPj;j z=a~)kk)G=3%prP7U-ffkIEL{RDosge&uLjwseU6e3!osi^Va~<6n2?r%#LvZ-Xm=_ z;LED=YdTn32ObebBq+&8s(PXJg7~zOm(J$|x9biG^JsEr&~~~laUPzm|$WO3t}c zcfcT<$BQiNgH}+y@Ale~RHID571!0JZSQ~6F{KfRBX0R69de`oC#vmyJ!!u-?v$RA zxpWIEjs2(t#-96Mb>p_B7al{=DjT=*J73G%xC`+p@bLWz2WYytb(G;z+NAO)WE_8s zMX=<_@#G)0dq{;Zi`w4*+i;aIDt@P^c@7oTh*5C%e!?SQ<>9d=G36Mw#b{`_0xs<+7~)XI~`?w zs^Z8fLXo%hWqRAv9}{YaxyQa3u=?bfj27f6;YIrUe%Idn+;h_el=;m+^O=4i_ndw9 z%i3$Nz4qE`uf5hiF{C@`xBBt*?5sH$G1<6TO}BAx5!S&c+sjyc713=wP-I`!grjXnC&su5X@&`M{}1<9**e)P?e2fU zoBg|Jwuaja|6-{C%Uq4Rig)R5Q_Z0jvHeS92j~JYtcrK@JtEd~wG;B9ijM?GcP&TkZ>X9^9!!=jn>}>+re}!tBg8EJm z5e8-He$+wm1Ny2q3#7G2z>@wOEEAZ5knz@TcVC0ooo&t|dpw+j?1AkDMqAIki2Yts z{0@s7blY~{trm+-lt}Bu2mR16tfE4!9DQ;=D&su4|aYO#fw1$Ul{>4qA)Bp z6zQhAb`p#*#(7OR;tB^HtLk|INOZ0Wdy%d7aN?5y@Yor6@-UTG9JLNp`{zbs z2^U~=Nf_>z;ZN0aAg)`V21<=-gfX;YhfcqC#7eyF^iCA1D7^oqEx+iHr!mF~&Uu#= zv>x>kj>k&iD~@{0s=O8gJ`BfUzr5{RuLKSZRK?L}40Hn36xK23N27FW>nGl+4gxmy zcylGRMc=d72iD=!g-l0Z@}w1Q=_@1SA2^0Sja!e=qvYsYM<+(B;8-`tievU!un;!I zJM;Jz0<&WZQ=i~d_%7=nGks*_kzhTyaqN+0+|@H%gd;SE*W=JNEC8p#-kfP@Ri9$|xMe9tl^VLN3kI@pd6s-1Zi}?4&=1YFRQg zqRl}sBG8n5P6Ip|;K52Rwt9L9M6}Ks)=vTgb2y6=)p``CR|}@{pzRxMC02bc8WE6W z46CtPhH_+B>J;E8eKuN?pf})9AaV^)s+4t%k~#C0bP626s(}O7 zG6=-Q=w|_ld)O@2L5*zGT6>U|RWM^SVmih=-k#)(?NQ!(DQZ(8L z?$N*2zFW$1AGKThS~U#kq$Azk&M3|Yz9kek@I9{IQ~*dkG55|%h^))VdP}-(T(Jn> z75Xf!_tYcYi~d>2ovu84YyG*Uf5JBk1FedkK|~48mnM4S6Bz_4#+~V>?~P*Wqw=x+z>w;gjh*cF@AFK(gb*l6w@}5wR<4YhVsc}uYkla z1wn`RAe_{BqtG`<>QE>f{a?~F=?Oi7&rdZjkTA^A`ys2)uUyk)ii8+fl>PvobXV@0 zJTCcr+bhEty5v3yF76n5w4a^K7Pe*kiDPF=_rv=dtDb|tO2!~z;VYE8ee{0C!g4fM zF6xyfONcgKk9sv@eeJB0*$PyuJGPSQU>B>o%(&rk9z0UAyL_3gq zrOp=l;nyQnJ5mS#;iYH?PZ_C$tB_@c-UN4HD3)+Nmc=mw=r9t*$q)@r?D!aXmz^&i z=mt^O_FxF1yR$N{^uy9qA}=je4V!PV>YbJ*;GqZeL-KDK(+&1u=$1qQP{MUXav)&? z3KsbFFTe)5X$L(q9%OhwE=eIi^f%xR{Y|1(=ymB0GpJtbPAt{4{%2t96IU zbUjJqe`w%Y{qEgSY0FJ2E?1NIwL5fqGNbbiY%+*0$hSt{FuY&w#r^t2&%shKi!w@aj3UA9ES zoqQhgZv|3a&h`@)ghlYfYOm;B)4`>JEP|i3^R}tJD4#oI`u&f(-%k2(&|%mbO0Ff{ zBgW$!PQO>!l@0W(_aWU&n>8Ms)DM7`CEZTfd6*~~7lg-2HS%3(S-*cr@)-?DNYA8G z`nPhr_?+O;!@~|&;Fa4OA z2TRO6Xg2d;z8>@BV>;dXCkpAm$>ulo{|(%Y0e%LQP7m>9_<)n9OADOOP0-(i#dw8- zIg8hjzK>Y?p1}+g0;-KrFZyTh|Gi!@SkI+x*f8w1Amk`sDXF$373Va7t zWsjT976UvH%Dea;t6pojM;bp~viMGoj8ftoOD_<_F6mBWis>)7L*q$CkNruJKSbtj zdM_wNEwXkA0V4|`A4X5pt!$8%bPpU-i#T6{zvg!!y1-8b{|qOH`Y!`Qf(oh01>$sY44B7)=Z+ zX>f!(!`x;jqK2O^4c!X&B{C|irH(2E@*^2+%_pbY@!pSd#5`)LN2Vp+avCJe>=mSw zHXjzgt2ey3PJ~<>mw-_RM;OlYYli63Y14q`|)p*-Q+KJk}Mx)0Tm&P>Du=~3d$!g^=)6QIl}2t7+Lv+L3~Q32Pb zE6{#)UHSyy!*wY!#mEi+V;KF+xAgN7(^Q8JN8(!uwsSopI6#PDnUWYY@ z_)Yf8b|(BVoM}XnT=-T%vPt7S7^&S|iH5LhQx)F@12~b^>(#V3659hVGJ;RFs8W7| z=W%XwkPhhbMfGjAimEyK>NEVQI&Gkojst#t zl3aSL^IY;Nh6{1&G98!DJeTMG*``^3e4l@PgCF1RUtjOXcly`Y`SB<6A05Q46hGdZ z-{Z#*@Xyx#z9ZZG>ydqHzV(3L(c|~zpUL0c<6l2J-`bmxKjB|L$M4wUcWkh5!E>VD zbUSW6EW}|qV$6WO;sUeur)iEpC((8bDxT-9H(aJ2gom=(^i9w-C)-p5X!3xMZSKxD z%|=UrHQzLcEycI^@ePLrxV_R*K-DX~Kajt9tABk>eviO3MS$z^+X3iQ3z>Um3|F<^ zgcl}F9-)6Wxo=A9;gRF<<`@)ZSsX_A&6E7!`+E+*@T7$x!kZls($Ihy*qCclu)zzw*Xhdy9Biu#J!4I4mYxh!cQ%+ieS8%ZuFt|k&9^7bH zjD^t$49(T~7yR*kym55ZWPeh%zmYm#eOqW z_vKsf^*eCa{1DK|vEsOjJ%%>N$!2JT>~Gr1zsA1$PfCPZkIQy zW5C~(kT)s)JAc!1d6RO1zv*sy+sSe}{Y{K z>2GS_+a8tSZ$88F{-#;-%+mg*+49V?{-!y2CIx4hLDLvNlg9K+=s)t356`cxPb720%Q*(SGW~j5_>Cq^DE-$q1$h+ z%)exp-t^aouyV+vMQgpCTk&TWb6^GQ_V*sa&sx9Fn_uN&O>R&5dmxvzulD0>DV^Yr zPH5xZ=yE03X|p)btFFKsVz~hk1a8U7YW>F_qQTC~vDkpOc$qEocdh*G z#9x^F@=Trj2b{;l!0bKr!K4{KggLuogv1eZ(v*z>OE&(H$aHHdYsFXl9S`~Ol;80% zmhpTu&x-S>a~=2FcS7tj^JceQ0{7WvuUD^g^lFmXNqpN?HaG{@$V5&-r^`6j*i%4C z=zJQiLRXjO!i3Z^fK9Ss`#=tX0ahfB#J4eGy6%t00}6%Jp=#SfTbV!pC_!(YgyBJr z`Kv0CqfqJGSE>KWW=c5pBr<`-l0@(;>d~w|dgb7ofDVFgHhu`AZ}w+(B0@m2sgZ}t z{zk?F_v1DG#;Nj9nZKDD9>_5Mp8U;_sr&LbS3tBeI6OprK(6uAQb7m#5{xyE`e~`B zW3r!SJxGNYF4R(kx*&oJoN>x*hW$Z4f)bL@qb?8`zi2thaJe)g_2RuMT~D~AIm#?I z_rl$dN;fdEW2bI5fAazO|H;O83gEjn2>F}y*ajG|`w#+IwLf6UMSuJ;4o8~#Am;u~i@BL`*i8BHqle)pd6Sc2JTkxi ze!u;JTzoT$ozi~%{@R0npMo^rajzfWoLzB0TkrPc58yJI-I146W!6y}P=U zt^|?TrAaUTkkX-3;&8*g6P1GucH;-*z7Id}LH8hARPl%KgRy-WKXz<6dMe8iR_i#t z7(K7Gmp!uhZ$A(YiA39t4u#!mbX9^E9LBi!TH@D$fIbNb;2|J@=RqMt!U1pyhb6+^ zkO&VHh%k=~7EmF=^g;qEbVv~I26?3AbV#UB2H_^jp%Kq5LRQMKLBlL`MRSTOO1H@? zk)fHW9l8Zl12b!o3s!3|Y#odl9*=D{=D85vX1@b;w}nI#WVC(^IN;tD^maf2nH{|f zJ3vkAaFqpoliEr37UNMg3$4=uI4FA~_z5t{&2OKFO*4EP$9sb=q?&zP7SX*8_g8qd z(;6G@qbMO`-(#>_gx2`|1)Rn=8xoE`V2}{s5e+m0CvVJ1S{Zd zjlnF{eN=4liqCiPtGYz}(E~qc@|Nc}ymfKWXsOTt?>;2>i|YNB+4gz19-yzYnv2Ae zYuaw7YZs<-?f$v7``dn11NWDubFb0AM_$vbXt>>7I>9Idx{jfOt!Ss@$R79V*cku5 zK0N1J>P>T9eDxR2F1pcx@l(1^IC3IEj8YC^SrAU zV6Y~smMQqDQY};Q12=NB@Kdf@^p?714lf9SbV?2BRARU_MDZw&XAVHob@d? zak91CBG3oai}IXCa_0ma=vj&Gt{ zRPMQ%2bz-jBNVLrSWWguiw>)&j2<5`2^HKDvlJYmhzup zPIXDwYI(j}>V#}ifrX4*0bDE(_=<@cOGrzCRiP3rnk~!oaZHjvzvb>caziK3^&o2V zyB@+{)B&!vGyeh>^nB|Bcm;PNuL8G(0tpY3pgBPORe0pmh@YZmQ6p+Arg#x`f?5oL z=2tv`m!OACK%ZNNL?LB!GD850&_?k8g!z;O5cs^`f@<-O5ioei2pGI$1Uhv-;GM`5 zSOs1=*kp_j@riF34qh`P5~D@Sbjx#}C)bQAc4SB-)IDWnu;P#u zcKhquD}Rso6v@F~-^nbLY07*!DqB$@ki{qCr%H)vQ%%38GQyMagOTMZVr0o-tc?F4KI1Py&1HzYn-bIy%ik<|5%70FpkCesZcF9;ipoy+=3slm^S=?5zWI7EW;N>>4hJ= zO3Bagxl7cs$k0`elz}zmmy7DM$-KI{UR~Ef#;HS`IPdEzLs742s>YmJT0lkwrA?PF?_DyC4(V^XI0Uhd?vqFminpTBW7CstEK{>C|=)limh z-KpAlQ?zRBh0{h#Zg3F^l#;IDsjfzbwuy@f{Nqh68d|Iobi*lY1cOjNglj6;m=tEh zA#VcljsQ}alg*_dX?>FnqK?orVlp5a3UpYlrA7$6b8MpZ@HJENGa5coU*fNL%Xu{Z z7X63C-}G;L^H(d5`M15rV~Uw|IDOaraMsFtqJ)>wht5wP%dON@5AvG8_33aPif{ae z_&*0%cQ6c&1jC*v*Qu&t`$%i?Vdp2jK?=6^jXqS5SbR81`Nko66wVuF5B2HT2q!M* zVeG*5@DB3wD^H>?9!cSP`)cA?&0Ad$Ti=7;^T{TVo7an*24AT|^j;a4e>$J$__OY* z_g4ptf)aw75TJe&0=W;YvId>bJ{Xc6yXnYpA=X;uYu}3NvtIiXxXa*SU)@&cweM67_1q1_ck6Y|y_;Q#?^7<7KHS>7DS0@c+|}}s zSMI&?a7ek`c*x=ykMbrf>C>{C9HoS2P?YTt0zKSnoI;MU$?5vGy!ZPpF)gGciOape zH{Vj~KXZ5h+xK50jp6__9G@@aHs|=xxONj9P!5s#g=D3(q0FRudIX)QnV_80b^Rc2H4D{-J!Y|<;+6Y_zsySFCBIk6;rFSL{=gkS- zw-)f@sChULJ zJU)r&t@puuc69slIseR&mj+g|e|LV{LV@sa!U@9j=#_&*EHC>!h%lH*JezjkI)CX| z!-I$|EjdyBvwkqkZsoF3@F;Jru-$>@b*%&s(3L2c9f9l#2+Nck!g>m{s9d^)%yh~7 z37p!uAXu6io*ubXCYB&JfIx2MD(hh zM9tthx^{XO6gKu`8+RE!kMU}w_vBQ(K%Pi1#xJ>(65ipZSL0o|Jo~~o6cq|+o5E0K z>pJl*yN(7LUOL5m^eV!;&X6@@=o}YeIIM=hR0x_-52xvS)l0Jga-_!3M%GBKf0tbD zTc>&H1^D8n`5g|k0FG*^$_l)8Qp$m$5wJn@>3U=pO%!N%I~$-w#H(mK zlGD2Hyd;;Ng?BbQAoEn?ZQy)89|z9S?|2hx9Y9ArP3yw0NM*^O*6`=n$hhbxSjFg&|8c#@Fdgj!IGk&_|HHBKgQ!Rt_uV7%dz4hRV8 zJz!*U%E{PWo#M$yJ+RM&>7bj~2T?=erX^P;Sa%}_$H=svy;eLn+E<;&MIM_X#*R+< zb|fK~h>Sd3KI7K?wWYer1yW%J-1AmydU2P>#yaUWqyS95QYK zvdkA#-`+xfUyRmwh`oW&84I8}2+;N27S^|hlOda}W9vB1rWlN~ZD`j}PEX6UeB+2g z0fuZ;nKVL;-+*VYu@nk0c>s6f`m7ojQk`=HT8D@-7CCi`Z@jL@Swkc}EQ08u`M#n6 zv7s_u{&9TA=HY(yR>0!s0W%9tV+-+Nr0Ok%k|c{f^go*>V_dyd9Y(OkonaxtU`5gR=bfe{Y)hS0% z;gxz2TtQx=yw?DG6bDR$A0FBBrEB%Yozp(yZEv}Ce?-%u$(TVwsrl8bZqssLc zO;v)PX)V=>FQLjAQf1|GF-M^dg4= z_Uu3q$xo%Fmu5tCHm?O5)jHfu=9>E{=I`PZ&;FhKO|FF#Lr@nEhd^BL=&G6^a&E@$ zN)KxBrV1~Q zzd(TqcMlBQ22P^7kZ7jJ-RO+%UgYBhPxqr)%$48`06l<%1AyNw=1K@;1;CrdT&Y>i zm72v|2`9<`7V1Gj3f&|ih2a?>h20q-g&7qfh0zos)u*2=)#iM35za$}{1;92(H(4M!50gL^)j)YF5Y*;jN-idk4~z{bjk_s>$%VA!+)AGu&|Xv4trWJ zaFE9g0)tiLpQKy8ft(vM1^`$R^lQ86|9nWLwd3JB+cGP=Xx2MS7>M+kGa=oZ)83C&yN9PaY|T~$!7&LZzJ&;ynyAG z_|fMQy6Z;!^3|!tfjvUYf0bAWaS&Xh*LAEsi8J-8BXXIO-hgiFUUTFNy$;5sy$C*n z8N`oXU){k;`u-Pu^O+UY?9XIqos^So0^ThAN8+ ztksCpwE)vciBTQ-_?P8vAO7YtTxR(X0>TX{LrG9A;7$|vKVl*_!LOKLHXMKW|} zCKY_2`*)4+6xq`f?N8xC97(V%`f{V}bFfgG4L-WV6AfA93XKq2{tK=_HQ0Yh_2MVt z6G#x^sX{+uBHhbJJhy+=`eisBnY28v`_VR!E;0TAlMW&ong6%&7@XiFd|2*}nf|uL zaxxHX-D^LVYgou9jniC1wY;qFlO!@*95^9~E_zdV1FagNz*q}?X0qLhxkGhMYBTaU zT^wI`=;Nkccy&dpJ9MdiPxHpE8QumNe)A$8ZSk#SU^(z%F=c;)o7fkm8+}diMUA&2 z|0Xg#S}t}{l_+4w$J@~zoTkf%ErTmtFr;PaIvh`JVvjBTav94^MgoYxLairFsz!>l zr{@}DQbMOSmmP1YD^I>3sqDe<9_f-`Uw6U?{JtJff+y%q<2N9`ZLUD1>%v+fpiOU! z!3*~52$}I}FWvQtMQ=|25{BR(!AECM{?xu1XM7w$B+hY%8i6k-JspU`y+UtT|55N{ zIQ6V+Sjdl>P>7~rh-Eb$73j2M6gt)Y!Zu9LW0}+q)u7&^^P`R#&e!7?jt8W>lHe{j zB=bk><2 zVJ>qB@9h|P{&9eTAX;yF2wO!j4fb3B?Sq#w-YD(?zLyfDsV^s&ABcC5!9>^ka}*gf z5_A;hc^F{hr9uEL-X<|vOqhgq!1Pz2JnB=(j#qGz^HOyCld2_bUQ57gK@2y-KM7}_ zbbAMxKG71%GjPh1Zs`{~g{pAkxI%|iMmy98B!B`ra@KY|2sv>uabVyn%}-hcq3oaJ zGYB0xG>U&qx&Pu0y>ICm`o5+{$dYax#@sYd^oy0KYoK4bQ$R|XMtMl-s-eN^8Fl)= zZspeC`#_J@3nA(wnAkcV5)AxE!{u@s4s6CGdVG+>jjsdWgdAu#{hX9%D7P16#6@N{ zGTRjwhXKeR@c#6u`Kjf%`Hy!VMSgfGL8%D)K|$6+~l7<82&p-Bl(8C}9A&V_3n&W=lP;&4;IDZ&4HTk%fle}~Zk}h(wzbcvW8vZQ19P=LV z?~*uGm%$Nfx=IRRZ(S}AupO-6!xil9nOVsv?JyYLiRYBm=t+$MZ>m~(puoSQJ;$ce zeFE)*3+7ykVE7LqdMNSn$#Z+~H&OuHjNW44=Sk(yp@D0fJQcnAqv-zFWcet;^%qpom zX+Lm#xF1--Jsta3C^r$aVU%*que1AzqnPEx$}yVgDCOG1a^A`9QO!L{xtg%tMYbH~ z6ZpHgW98u87zJ%JavDy_xx6mMP-4;1qtoKG|R z4Nv-b&ZV4zbO`C=S><<`=}&aoFA7icJvQw#0jqys^Lq=f*U)fRYpi z4z-4Bx!dL!}0chO1Qko35B=K>veaJo&HmTtvl(Yc%^{uBcDKNp+kO~WDZQ|iAm@jcD;rk zD27fVj2xo^c7A~RYxld46NM0S7?w`ZnK(EMi$&um&$ih!%Zi`oo~DQ98z!fn}K&ZIgoYkrM`FDJ^M~ z;&By$7l?vM=#IJ;wsImC@R)OMm1+L~n1EyweaDwZ;TwkFV$}!0Jy36{rp!VMJQlRo zbUUdQG&mCfQ8JWU9|LOP1%Le3PdfF2W9n8GSUz|v3Ws%Z9y_Uj8l^szs|m~9i%ipn z1f29&0nf_4V=?bNp;)mN21I2$vGK)k>D@pbA^dxQf?6K5T#@Z*eu((Q$U~J}WXC5v zGSq7DUZoy=6VHf|nf^FTBW;naUsL2~jbC&?)Xp+*aE&AaPxAYDmnuzaNupD&-SSr(^~d z%DJ~4L%{E2kWQxUf=SZS+F{>m#f7Mg$%oO<2{;#kqyU5eLV;!fVt~;X<9Kj{L%9)v zYN+k$)^&%Up^6aeTrdJefZ*mRjK_glbK+XquZMsw+mVyJ?1gEuM+tJ!<@io$csapw zkf;A4vveJ4U1i}Dqm%JpF1}Cy^zvsEfa~2AJK>d}5@clUJx_w)cGSIb>K~%OKCeOC zaZ!i1R}MiW5cT$}KaV#fyMDR=@O&pk`2AM$T;Mc;1Xx(_z7GI#-0yPE8Fdw@k?=%3xxlBQX zE1YyiD|uM!OHVo8P#H`9y}G&%8;@^!`P%)jzLaek0|Ih>+)@XPuOR^ACsnXf7##O$ z67^UdH>W3IKHyMM1A;^|w!0Kt0QNt``OLR6LrKHJ6z1Mr;Zv56^vM_Z{ zHO-=NviZb?IG>I8-~~sX4_}CbTilqMg}W~C2QS2luH2QY!nxChIJUyM)2!-A;IEZz zN_E9p(=6VGkL_NGB0sKMZw54!#3Rzh-N5Hqk@5*uzN5P30{TI4m>oBFffmneFj7F z!{3?}38WU^7vwm0LL20<&*Lo@Kgy2g;(h#4`VIoDFS~m1N(0R6u=w^7ELnUjgCC-h zj0~3D?!^6EiAt)Z<3NNSGa$ha_Y}0&i|TibJ~ZrsY@1zCfJXPn*!Pn7q$PIdW-WK! zRXHa4KIKw(1$u4ZNxMOii%*H)=-qAcHW!B|O=Tzm|JUSEdVi$tuPqb<-;2;C`~xS} zvtI-tN{a#v61EhLFwgNreF5#6(Zgz*Og=6~%8Aq5oz>X<3;a=eRNL=0l#>;Q+vl@v zcXG0!#wUCu<>lPl2|NDf+=O`&VsYo;&6YBG8;sHAa(q&2Sa3-$)@GaW;zJ{C;F)bq zkF6=&KIF+RACs$8*MU!C_ERbqJb2p~2yOodw(Gif#mbAc7gARDoP=M{$I*W>_3>re zi!v0`pM@R;gL!QfIZwAy}zG5wG?1b~6-7)#DH^ zpC($G;pdR4$5l};sO#-KJX0qfqAELd*E^V?tYCs7WnEAo%RDnBl@m{RpELBycK<4 zKbzk_R`{;Ri_2ud6G6%EttTdfQu}VlYkdWiUjm8Bmmu4pGkz-5hhCx)9M2!(Q^ay2-~`e1KP}Ub zk51|{s8(aPG-$=Moxernm8l{GUtwW6_d5yiTucI5bL#JwmXOa|-vfH~`}14Mk;mV_ zzrj)F#C+5ETK@!c1XV~Yo(Y>|CSbqx*Z34x*?kmnAKwlw${8%tiYRMv8;x4sy<;%O z@>wE!+IfyUhpfK`LX>H53*R5&yQaIXeBWGne~9nhh5Q@%-l^ZGt>26{?a$nkXJX3E z`QWq2g>xFxrMLb;mYdCT^Gl(?|B}k^Pz*D7?KYTN(m_a~1DyFZP@?wVnYap%V`1l; z>PE)Yp5%L0t|+I~wxK_4jKMcV{IOQ1LNa4;(nI=Y^})Z<_C(VwxXvEDxi7vIV&*Y! zLoqC(F2VQj^IaB*a!_Z)lGyNgP>;cHTTaw~fJOM`1QXn9gepAvLM)#s*<#OL3C)Col5Dz- z6`_HDTLHP$@J=%4@j5>#L%y>aD-RLkinnQQd*ZyTdpm}j)0mZSdv-=43Ng|?{C0(% z)PqzkRAJlb6*{T8FnVQ&h7Cvh zQ#6J(A{+U;jL7w))r4SJLV#}*qRW$`YIg9JcUOy?YkP7a&RXsmy_UC+73R59F%GQa zYwx-W6eiM~VI=go|IrGG#3)UEceDzr&T&%z3|X3R+Ms}=!8eUcM9KzySS{PD0bUlTm?s@^uXvn zOPtqP_rH?w>0CbM=I-Pfoy*7GLB9T1=qvZDo>)q-ioVgRc*kD2ly6zZAKrZxT-sR0 z8}GgfuCA=2Y~d&@_?Y1arCC@*gXj^7a)S(lavl zsbLlIusP>a9I!0t>bI}RH5FYytfF5?MU*paMK_LC(K}=3VcqT0JKlX2lv#+ERqwuv zou-O4@4kxNr~>PD;ZUh?=m7&0cW3$aH)y{A1l0_s-o)4wq8&q!ZLqJBg`21i8j%9K z81C9~4HYaDY@^k#$f>9&)&zK?>vA8m=rJZ&3C_j#qMP|XGA!S2$w#7+eBYyN%zW`x z2m}&Y=Q|}Ihg$NL+xnixj4I?y&e5DqV6KHoC~`LI`$;1n8`_e=FV`yp)~fzZr;lu?dhJEQV^eqx`OMjo)8c_r4gatkx82So z+hG!yXt(|eY_w%De?e4b?=|mbSlGZ`kCuq9Fi!Dn2LUhJKm_OHx`BzL}Enz-2gZVmAK zYA_R6VZs!h@K!Jd2}`<>B=ay)t<&EKs9kXt3zY_C;q#b)CQ&*)7BJ=q2M8z$iCMQx zs|*ckc;6e_l?vLJc9g;$Mt1hoov)2sribbmeOpe4S4a#Y6b5<-VOk=VO!)Qk*Gs6l zj^Gqls`qp4wR^=bmBA$84NrzxDRHk9f&CCqQA$-q|XbNn2;dj3gaRM+vQ6q;x(gGvESdWd4(Se9#; z-19>OR7Gs>EHkKUXk-uCpqd}FQ4~AXN%L4i!=aWV*o~9oU0AlbIlAT)R43eiU5ain z%h*rM9UZ80C$*k+&lY9DQa-jVAPIkgk6Z5ry4YL?-!^pe4O)k*`L;U6H)t4U@~!O_ z7PI^D_Ez-(hdM!e>8*SM3BdgZOfQ}Oq(RSiPtG}T8TEUp*Iq^y)NJ4qCb>QL z06yx<)wd$a+!z(L^JbVJ4R~EcHo@znVVAD1i&kCcvA>XE5Rdj|fWAVOYq$jsVK(5CuYo?`rq-g^a+Tl)Ke`(Pc7`c|Z51^bsz7o!54lkO5 zD@x}3WE`zRPb>qPo3*N*AQ^8uzss$9n6LO}*KhQD?N(x>}DdN@uKr^uL9Bv@REjcO-x=>En!ziy*@TO`;$}SD^%;rpeEpg>ePIoz5 zl}~c+XDryT<^vC)R}Chf_gSlmfo-NSeGgG=zJl8UKly0{cc!m1D{$baM{9j;h-6zu zrRI8WKaNW4Fws##Xh>=MTM3wxhv_lh_FK=EvT6Z4CwvKzmIT#g6@pRvC$Zz%QpS(C zOJGyT(QZdpC&h@IwFe~*rshtxXDDRU5D0flT=#A`Q;IX(_9JXxV}_x5py3R3VBnKD z7qug&$-PD3m!1pMUA%2&7`Vto8+1q2OyZ2EhQkNd@}J1yQynf^MJKf%D;!LdcEvke zbMe&YN+7VtSAU;tLHu6yNA#d-0;`@M3;qF_*{5UpK;A(y%T^yeijQIAxKGB6(N%6( z=dD~}?R}_6e{(B3hf64>5T;V6U>hGfjIvYG>AFoml%{*MT=8Md?P<+bi3@BFBj` z;2NtMR@c@*CLK`MCUQ+vSRq31@&~HuiF)ll(Y7$xlwjJxT9x5y5{__&OG)94s}S8L zt>f%g#dg2?N?<2fr?9|NEPyb*T;?EL$bBv8q*>ew35d|_vZ%h^1{Wha+48`4Gv>Yy zH!3>)aamy&%<~q^vKbeKjcEV`G!I0kFWYsJM95bYM0JJ>pVrf}ySdClE+F!>z&v>p zbpTEYkyC#;6h8HZPbsiu{S~~`JXMEvEw**piIS03*0M0U)yG19hO1=6bCHui6BRr6 zFmRdiUu41_a8ZqBOwmrv7x=}8(R%j8-vg)2>!nVKq@b@>54*W5 zqaohi+7D;x@G^^HaE72Z9Yt|w)(#SIi@3n~Rvd%U^F(4IPag((R61>kmtlU`xMce9 z%YQjJf8vvx04tg*D2g+)G}17`tL*RzJ)dLWJ~|Prl{<8klX(UGQfJg2JU+9s%1J9O zg$U%fKT$S)J*S70dXyR9K;a(c4* zV|R=rY>l(^>mXkTReVrJ4OVlJA>-}UOg#ZIlFBi#q+BKxRxAxtyhs4|uOO#j2Ey%n zJgakz4YP+A{TUCm&D$l{`Wu#b>8m*1 ztS9pX{-S>qRHmK-AmpGjJz=V_=u98p^-*Q81UoBTAGSgCX6FmVBCyX(!5~<;bI&-e z4%WAp9El235fjxkGzBt3Rp?EuAoPH;xAuJocBK&AZvYipN(<(NdW=FPD@UmW71o3{ zHw&3bdcz)Q*frU6@d-9_1(VOhe(+X%(0z*Cgi>Qia3ep{?*}#&c$_YD>7*~lb8sQ| zv+X^#C&2d0(HRjfNMkI_&aK3+-39MTUyd;$h7lihH#RWqBq1B8!eGSGt0JWpVycdL z@BRLJ0T;}j4rz^m2$TQz+6*H>xA&=d|H{2+<;1qW@`>A3{OGp6(uv!>_2d~r3F_;7 zQabFUXcNTYT#R4mkyGj+bz%!rBHkvQ%s=Cip7Ne-#Ao3J&ZB8Q(}$+GckzGJfY*Zv z1@jCaKk59Bs z$+@B^!+XT?!Zi9GleFm(cI9dXLgl7PoyEIYD!Yr=iCu+G~TQ&9XS8AMarQ<&T*;7pQ4yB)Q$ z5BMT|z}*#Gm5^>AelYX9z4)ZAE$4Jm?mp(jr9ZsE;#@! zi$y{$Rt@Suzkmqu7@)-W(8&Y$*={9=M3BX@x~~<=tzeyCUdk=kPw2n2!@j$dbQ&x; zH5P6m77~r7Q>fQTGZKvMwTw0-28<#>JJD7Xd>(_K?OV)<1eYL%`(2GkegBb&%sdKG zw%Fmh9j~TDa6|%>&%n(V;6|QCz<0DLfcQSh&T*7SR_UH$ALVzW7^9}{)sjMHeiRA@uYvRUv^su~;U z;ka?O7eA^R=XkJQZG`KkL1-!3%Cfj0Nv4hqr5Gacb^y(x6KaupHdO{GEhxe5KG9p- zc)tZa@!t14^tbwk2n`0c?614C-dyT3`cdPL>_GtVrq{mOc?6a&ttt30_Tu+KeqG(} zs{d7{K2z$g*q~Od_8Ve;iQiD>H(+Abt1rdWM9$@<6g80_hR(7O_9QPjE&;X2B+pS@ zQ!y59-#Afq)PN3X#{_49;-}TU5=9wIWs~E!iNLxVj-S-r22Ub)sfJlPgo(OOCN+H1 z!bxoxXFGlVG%jT8IQl^A-EiaaTz^}(tW?Fde4!g|Le4% z9c2WLXTWn-zs0xMd#A^{zjCVT=)Uk7)!Kcbui7_cW9LkduXVo8b5tzvU;Aea6g&i> z)vxX4qd2Z&<;ZJ8LwKzRy!Jj$t4=SO_Ye%g_zv6T+%q2aIO!88diWrOvOQk=QSC>} z-=oJ_`@}+xQr@^FIr2KH&~9Y!oZzH(qmudB*Yc60hu**!c(X-_j$4p^_?L*&v?mwu zNAuhS?Uj1yffnv=S@^ri1P65o8%t~VA9)#>S9}K-oW3K@vN!v;Z9a(THMf07wchWw z4q9J52x>UKa}ie4Jvtaj*IZP>Ug^qp#79>CJaNLx%TW1CZ&UTLQLA1p7#^H1m|c3B z4&dgs4|=^SyBriet@YT_abD{&4*Z8fSPGAj3n%fh{pgt9X;Scx)AZ0>h%iBes=YrO zJ9V0P8{-F7!w<()E1b|H(iHp@!?O$2$7ep>DejWH08jQ&M5w_t1x>FtONct7bQ2O_vBx2ynliO<3BUzne@T0Y^&W9Jb+iM zd-1gw9#eE_x8cHF!DC3%^<5L8-#vzYsi7wQni~MYG2~Y5ni(WG^!ITW`(@lMTCMKu z!{hX}S&sV?Xxc*P#a}YtRF);Yud{?gD2e+(Hzf-ct=;e|h+q zUVDFVjY*zp{GWs?tJ+0X)rJqd*X!Ye&nm~BOhaSJ4x1zihQ0$*I3COMD9UA&jeyX>jW zHU;~W19~ZY0zX>dA(tMj8pP*{6bM^Vt@q|;E+#d?8LF&idJz6RydE7Duk>RICVI`7 zU<;nQYmZ}Za4V6j*E!7K#+JE>{*|wNqIUjgAfKdXwHXelIXZxCo>Q=eBR9mK2HytksrbZctUyy$TE18w5j_Qwv+lUGMRgZvbkS_ zcfc1bsTwAu8p{yKVU^(N;gAJ?g96=3BK1vgKjx&rgjTwP+wnJj5c1qIJOB~y&nYB< z5AuGOYE6Ob%`9~n$9~0G`6*IjLxXl8DeL$w6R3Cg9B^9IFo*b=jwz(sUizT%0SS-s z?W;XpiYg{!C-q6>b>A49SYEhFrdHgm1*wrnLkKG}8cD5%o7{~ zm0%tl{5feJOmUbHE&C?)jQ@g1F!n&xR6Lt}&?BGr81H=HAo5qx($Z5U&aDp6UnD|c zz{@4}>Tq$13rg^B2|A%G!G3WiI4G_JkI|JNCdVpbk;s^cb^(XCoq;7_C2<}}p-JSL zpCZe1w}FKoxG3KJ+-+;siu{Euz)2qfQ>8;gh?wp7(hn$F!>uvSH(=PP3bOE82s{Yf zGUue*sw0JaTSSIhfjBG`gn%ylis#}1q)0&!lA$vv#ejk%(Gw8V202sm2Q*e7ItU}~ zcWnu-!(349m1-_lG{}M&i?g6KT}S4exLVDnk@xJ!iSOVLM%w!p(GqYMZQIAOJ4ayz zLPo=D!-l_wOzsA?7h^ruvZ0qDV_mA3>gc!IDknQ!39{0Mm%tl4{`BhPFyo?c7L;wPKn2=&Yd8) zX^?%kCSX0bP__b)@^cNmWB>tbtNNx8=6)a|aRe6?-JWp&gEuuBK{%Y$&yhJ7??H)@ zr&$j4%a6$()i!zCZ(}O<32uC5eImx4&#X^iD=~y{Vn=%yeU?itjx9_t%VY9r`ehd;xR4n zLicLHf+tJY4(P7sb=MAsUBkYw8gr1-jw^*#CWEA|s8-iZ#kld*2B_k)ScWGmHA;C| z0Y%DjyPk^lzXkb= zt=G75ToP~XaaOg<{CtAE2IS_X-;Z}o2O9q}$YK7!#`l3|xe!M0%hefAQeamw?YeR* zY2qN^nOVa5BzrZ}`l^B7NPnG2 zu01=2`}t04EIQzRdTP141Fn4M%((dCi{~aTbh_w^Wd^1H#3YgTyS~T-$PzQP+_1^W zXRT#wCfRBFTq5Grb+yN{D~_s}lZcR~fe_~r%&ESC_nLW$F?4s0QM2o&eQA=D*@O%r zQ4%N=1~P3(po2o7$Gl_P`eNf|GW=_SrN;+B*N@5WC-D>1rmmf;S}Cwqpe{{NSQZ%B z(MKU%{wPCnLtyYw)<5nTt&g1a9pJ>l^B88`58&fmVj;EPyr&28ZHczK!*~R=K*R5h znLvS)5+AI@%d)#>TztvJbAiW~kzodfEsfvwol-tHh#vq!G$2qEKm}1#pDo~K5oCrD zgmgSXUuNIS{fqwq&}gqVgS#y!wSkY^nxTCsO;5b=|L8JtCQ=Q&sV_5uLY`^=budum zyB^6XXZhhI%@4&0vbJa1bBQyc1Qd2?#`B-Z2XS5$?;}2ODfCwuPt2#Qs;9S>;V>B( zZyRmE)O;KxCuY?i94O^c{|z-u7kGJkM&mfbeYD{W7{ER^-X|HRt4q?ylYh_C!9Jc2 zT4=x`g%5Aj+4;Rl@v2WwS5(4ld-ky&=?h1s1K{Vfc z)3}+67<`q8Mypz@5Fc2zBf{5OC-qShappn%MPx6Pc}N}(sm#Oj(5EsK+DWXL4Sawf ziaa^=A>q({!l93nLysYeRU!+6NXHTV7J(gC51b+KZGP!L1NFmRgz<_`X13>;?U{jz zGH#OIT<5Rno&+!JH}iLozy1Nq<*&aVzv3_tXZagx z1Zr{Qi;HAm9GUC5+Pk~)6Iraw8xuTBTGaA8yoSTLg5CcPzNzL}+4-}w9UHJ+7Cvyl zEL59?4?Lh6%PICXR$yxfu}=ts5d^Vh*v+2L$dtsfjXG3**gx#!Js%+b$P50qJOV9m z%kPjVC`%_E_VX_cjK{oyGK!(0IY>HOQ8{ zopiPB$gk5qM{tVOghUSBz$tnhpYhj|Ryc&DA`T&m2>4x3^78lQgoN-|68voeFUVgs zo|IekcxE^0u{FaI%kpB0EbLXo6anXhB0I zhD?KFl-a~FZdME?I8F?Z6_Ws22${86LS`XA7D8qrKo&w~AwU*FW+6ZpLS`XAR+R+E zs+Is*2$=$@AM@S(UHBo(sXe+Ch^(B`J7n5o`W(< zJPblJ8AikPJ065@Jbbe5lM#MhHB}*8pl#fkTI=zNMu_azQFz{a=efFpb5V=X%fM5H z|GGPoRNUGF%H7S@A^>c`J%(XPfGN);8|Q%`;lcDC7LK>ognELMBLSdv>(p`RK4ZT2 zh_~xv`FZ7_@K4;K6kl06fdhqbAVV+QqnL;G81uX#X|@^0g|5$K~IT^i68;K zyJ$vG9U?lm!9XnzIEEyeqE;_ z-1cJZ)fb=pof#^@m1$mAwfiEe3`Y|}Jl@bnQVZWnD!OfwiHz;|egqnW4lhl!b7SYU zk=RsgY5*y9LYLu-E+sm7eEX{RQ=t%<95zn+J>RG4I9;i|us4Bv9kz&Oc_CDADTwvf=gj&;}AyQDQL>AOD5gs9eMPQvWzja-DUTc`m zP}!r7*JMwij}+i-5a2oY{7Kk$`ncckq^KLv$GuVJU_(42Ft;EFl?ch{KBaq6$hl`P z{`&noLx{c9cBFbrX4zivaY0*z+=2@M0oF&&XWoY9Sx{d*kn=h{qXDA-CdQZoz!Lg#51am^W$Bw ziU&te2ru}b7@TbE)7$#T7SpwpxeQ-4QD-ZjLpf}wHIqXE<{|2a@XMS_;gCT1Youb~`uV;78mavm|J(C8-5Fae zIVZBh;UH0uprKB@>nDE)ObB1}_d+5PNDu8f65x1DfTcYtPE1av_^qW3y#&DR;>k9e z5+7_U&Im8}8s~Y9vkY=v8ZTlo2CK{~S)0Kybv3BOuB#>#Aoq1Pbm7UFe3!PBb~# z@~;I6Oe@SA8dKWnC?j-(Ynou+NhdL;dV!BlY$5_fiMGP!WF&-yeaO_K8ni13q6g>o zE`hfSU5N?Y^3fMkIJ~gB!WSIksZ0+7o?^&32ikGT8T7L+W*#<0BrCL|J(Ff-dC{Vk zj+>J6j{Wh6M!FJm#h8ZDRR=&CBj?}Hd&F_zCB-QNiTLyc!?y80r?0XPP6}#Uv)YT2J ztv^LwHw#)oIH8Wl5I6W92erkv{>s%NyU1{$;OU)DQdY;oDyIlWw-hagCPIwFWYA{` zHIn2!B2__fsQ;7GbtR|&IBuaLSy+mcZ;jz?E%qIvQHCZPPAZFBm|=*pNiK%SU{_-| zEu862z5huxh@t`Pr2$`5M}@zUx^L+SzF^ZVx^S}(p-x0T4TR@_c~d?idPQqsWFg53 z9PE7X6vzVh@7RL_dix!a!T}PGhExjxKx~F?AlvUaN}wlcog6~_A`mWZnEg0}_db5A z3Xl3%B3)Z0!dB&|AnFv0U1+_rE6lGJK7~5tefiboUlw0kL{Y-npw0+#{rLUR3<}fl zq7xcF{!sY-7SXvU-+B}aZM>UQilYv{{V3D={PsT0gY%~!g-kRT-wxS?K1O5R3oKTm z!3r>(Dr_+4RZsHws+L(tp1~(-Sb+ktlOucZQiiAKkO%Z~%5@$j+W7$1A_`zX2Hwz@ zzks+3cu%~CSO79YDhhsvCZg5xV+1k5I(+xh&4>Iw+6)oT_lwb?XrVeU5AGm9^pDqh zx#33vV}};&dq^;=dZh~qC=7lQ-E-~gq(Aq+xoX zlA~mAgn=7+%fS$bMOwIj8!4<0nZX3@VvU{0usz4Fcqg_E;j8 zQ`{6q9sI)Xj-T)kJPIo1Fls=zlKl$LaZ{WrvM+fM`NY`iJ{EBM@K+eKzI&zP;I*m8 zDKZ)HBHX8dY>$;T;=kU!wW?+h9iIQ(igN`)j?A(E^|bMGx#nGG-Ua zXgwD^_j`^aN7VZ%nR=qqTON*3ACoac(h=O8o}>jZrT76hs5SaMn1)7yCvM@Q>(gA@ z(bop{L4PKqXwi4GbvyD}@G9q~Sr6p?8Zoe~NQS)(OjV{q?9&<`NV7(~{UAO?@59Ue zVs7Ql9GPm_8GbouInu&}hYLEc#P|&L6UZmiXdrj8JuWP9JIb_+KAurgl(M^CcW9cv zF(Uh+rSoUd{uO$2@my1p+Jj@NKIDemvwp$WEpiZ)yzTl1crdU9QCcgCjyLE^p{%kbl*xW$=q zv4)%QlB=QGkn!8T7H&{P42ETYbW$s(eRt^e#2xO?6!;?@Dg%E?KA_EJ(x z0}A6MRgfxUa$aR+a`}Z6l#7?9AQDk9gF%#$%^-ixhsS|yVGRXm0RypV2=7>!VZe51W{friGfQbRFtbdWH6WOH zZ`UFI=bOOkLI5PV#2#-u%vz~`)c$qcoiVQ$cZs!rK;+q1v}S-Vl2r3N+%b&A7xP{< zW&ij??|e7_+qZAui6!n;vC>>~1)p=xlc=%S)m&AwtN8|7{T`*A42%SlVmf;PWg*L&C>n81C|VIN@<|HAw* z*Kty3!(D5koYVCN0Eo2ZWPToF0y>?;z6!wI5OW?GR}a0yOL#w=ufdJo>p(*QI z!+8x?ct69}@33AJ@*0?M*eAR^?|Kl-h<)v(VuG;zAJl{WsfjUzdD2;jgTXOq2f7WI z5yEii1~}i6*55#0wtc<88`{U%_KWJh05zygCt5*;i3`xguBNk3QJEC`(*Q>smHMmO zgXc-G9TIpF6FckB%@dvN2!^2|?aojf+j`q zSsN!+t!1?%RU_Gsz?5d<_E9V8-_}=&3*TpA7|b}^K~BF9Y8UJyF^R_d8&?A^q6PWf zo`M??;9`uQ=Eq>r=sz=SHF|?TB7x^wop)7$I2Hmcsws3tG~+^0Yoc<-NAcsN7J;^B zRN;~LDt?D@ASs1Fz(xsARY=q1;5mE{crYL%f-*A}@Yb*BIcQg;Tb8?Kf_yy|Kv+lF zpD_x8KA^`N2j4h=#^1;*)&>;@GC$2U>5N80;=`s(_2|uEUpnQa|2HyOK4bhKk`KgS z63lu9xrM&^u=lUlqhWCS)k68&o?sIDc-TL*_t2i;bbQfzokyBtq&}XzllE=`zK78s z=;Z%b@&kF&Tfk_vb>wa6PE*}AvEWZ)YEHgrPVDbtFhM7M0sczAf{Ty?{7Ri+dNcDc zpGh;{VJ6MgGb!K&wEx_8{-Y?P<#t;v$noyU!ym##1Ah)C^1c!;+?xAPUiu++q^S}< zN@SwQyPZr}cs~Z_nQf}r)l>lwTg=N`FxrvD9OZ0QM3-R`;N^NIwV|QlQsn1&w3Zf4 z2-`LS>e9~GG%YpiNdj9jVH63RR~FhYs)JD2AWJ7fp-bz!2F7*cT(LRUxty$}7Pn1; z^9UB`NO*AOV@QIfpv-zOdGC$<>14yTG@TfM`~K?5ttjsQNVxAcbt)~d{pwWbkzasR zPfLBHfh!(XHn2jjhQYrN8T!PW%S>Twwk_S#s4Qm0rqo$%Wz`%sf(t)EKPtynwDdl- zBm+1q{{cHLWU#}g*;V+qk^X6keX=T82B!~dR636gA!0Y0Qt7pl18yX-ghpkIR{;8gX`s;`kJwcD`dAp@8%cX1E3zZ>j!m;+dTmbV|>S;Sdd12iX zw@=&)mgk)rG{C`a6q`kB3#fzPor@QoqBqQ#@p4T?X;eZV-;5dyXydp=(e@RCw#P7e zPME9HPUdHLBle0gSHP8(6aMoN0=AohA7HuZ-Q(}ob}*R_W4VX8dYa)Y0_pE1mbp1= zr9WB?yC(6Gr&5t1V@EqUAM6}v#CjF(7rf|+G`y1F*C0icFHNHQ%iCgnctSrg*5bPM zB%v$FB9p8yqHmuZF@A+-pXNFWxqpRGRP!rq55g4xOvXNvc;7nMcfl_o56BZQWM|iF z(`&D({^UIr?XG8*)9!jEZuyn+HeZIPVc3403ZIGJzrEx{EK$0|y)rh2ueih=OH5d@ z^2%7r*j&?8WQ0&`Mem3B#u)bD{iYeb|LLUm;e#9zIH_&S(_WfwDwn9Ml$EffGXe&w zSvQ4R=rRyt=}GQ)!;7<%x*tW|znT0N!muGDt^>ldUgsYx*9P?U41p~c{2w3@d+f4* z|B`s}DxC~@mwWE++wmT&{vLj00l@P-)GN=xSI%pimzen2dyqsoxY_1~!o!;8SrCKw zfn16^iO6zdN#|ZMc}%cKgaf_)Vf=7E0p6bA941+|s~G`?n$N`lXO&>{$ZcY-Ii~lJ zWoQp*DOam_l*tk1eO=iXCo1gf=QUSzQ?Qa*^z8ugCu7fG+@TqXkIrZUn*<_|#T}|Q z^9B14yw~C~)FitrkbRV8bTNO$%ap$2FLTPrkNLM9JJ>Pk-}bUf%R`F)Aqtp1DxSERdSautS@mB?P!ej;|@(t)VM>RPAuyD$~fLjbW)S0y&%93 z-jBRy_QyZgzZ#C(6TvwB-P_ImQN-K|5Yy_yQCp;*fp6+^xVd}|cB>^;j!S$P0h?~D z1UgA0n(Gax6g||vz{mtM3_+HA0m?lXTH~|>w`w@ZJMTfQV6}MvYpaqb*jav8|*@Zd$3qmJ+B)fO#|a=>QIcH-Jbq>Ag4U>EUWb3aAtr z?KmC(JnLAXDrov=dI38#5mE28rBdsTAJpMCaT zd+oK>UVH7e*NS3_m){3H2i!mgiyPK7biI7<`d7HF}u@7 znqaLDA?J_9T6eO#;np+I6U!E67OUi{gt zsd-Jkm>u;ZqSw?1fh6c?LZ)AU5e$jiGvN;O-PV0N$N1KEb3n6YZTD%x;#R`i2aD(U zgy??XJgD)FqM3PqH;1RFVPVXfe)p{K|FHOhN(RrH{JI&zh#LB{<1savfiTPVzrab38g~W=WhNTVRe6qgg<>%JKrqJ^I$f@+GGHpz^so}=#(zgnx9=%>TU-TJT<*^Zn9h<H~qv}gIf2qK`HcvEKhO7~p7QrQQm=9*-Fyd{9^~#e1o9omS=pohxv3BO zm(<$_@*f*+2LX0x{>$fbC#|fe#dbneg}n?04&g;xp-Aem6^$Q4Z4<>>A!z6>=}*DqtfO^8Q$bJZ?PewUNNa2gxqBr=R%GO$qF^y}sGWvB`5IdDhX2-XE(OE^NVMz~`TL@1;3% zKGbTD$1YWva@@+<7#OW~bZQJp@Vi$<$8t&w3gQRo^R&(9@Y4@;*Uj#Y z`?S1NLD53N;@lWvHetqGcY}BT#}oLa)H%Ue68HXdL?i8-ch&Nx(=A`R%gdJM1L#>e97m>%XH2B;DzbG-#JuQ}^`|6` zVOJK|!Ho$8(vAc&dyds45h1=T&zwHxlqqZ1zqXECNHAT=o4z75^6~j$kcVW?t|ue5 z<{3_jNV-<&17!**75PIdMER4nO~=RTf3ka_h_S9g=~_HLxUMc390W-xcO=sLf38FJ zJbV!)ZWj`5&GNzz5QLeO}gAqk;-WK)ZKiJw9=e{8iLmBa@TwV{4$*q+gAjE z;Ajj^G{M3Y8wo3^05>Fv#?V5{ZRYVS5qN-S)%1TmJvP%{+!DN&lRiX)u6<`qpQ2G4d>Z_MJ!~|@ zEkVC#I*+w~o{-3^VmUx)lT}(REJF+71kn3NgSW}OQ7b6R4OIH_xMf6THQLwxof9R8 z`yULTCFR7kFdk0tM{hu6ysh$^Kv^KlkW^Jc9GJ;(A16Ob`cQd#tJqI=`cb8RW96BP zW0KubsiPhDM2Q0MSnxZX+ysCG{4Y*NEc%jW}*(mO6>NT7Kt7ZISfAh%EHtw%q z3~K!)jgwhTuqQ?ntfG2qN{_VN@5kD1wLX0ba_-`lTCpyx^X~r`vKz&^|CC9KA8Niy zsdu$CL}Z6vt8gHx*$@psZ%n^CQD<4rP*{oeG%fY|xnrxJ$xl~|n3J|S)9!Q|5r?M* z4V6=v5fhpr;8M$i9rr?4Ae@m~^8!g^Q+vkRI0SxrZlT@9?EUsV$R(N+)@qJC&C=qg(HX}*rhY9-Ri zjrIPuRGR8Dp?}HThbLb-dec126V80_nqZ(Iy{$I5q`7V8^=-L%Izw4A{W^qyL$Sl* z-Z>Mb9x2Y)_tfM+Tl~O;7Cw(-E_LI;j=|1_Wc*Xg3$dHc9zAuzP^HwF60IebC1l}RH38h-x-W7S^tKdxC(Lrh*-XhbCdiK1c=TC-jLu&A<0tH_5UWKt z8p`GxFMBEPymc4xH?|%fs(Swhd;jY4``CKq4ew_Vj}5a24eE9H zPoTNlxOK%%ebFwX(WRp+w|7y!Yk5$m{pRgEflk300hXkHe^fb4$!TsQRdW;}^wc$UO zgQ-`=GVp8=QIdiC!=pHbIMwSI68%HWV>MPV&g2(0f|oRgCySt`izV19h=jN#HY0j7 zGeR`r<@K4Z2X20WSyGhN_*GrhZuH3+5K}Q$ikfe4e3(~rYuZ7Z0a4j-o z5?PD%m@E=v=M!pLb2G%N)xw%VyEy2quW@FkxM(i9>DwnW1b*_KVBj7y8uo5dWF(hh zR1$E2IQJ!qAq`UxBfVou3GEUZqf`U4CASz$pum{D^QM!7fpKNZ`~_ez;94x#0p41$i{8_wLuCSqg-d3qnBFyM212Hjslk zk>|{!$58x`hR{*`^}2-b8{SRF1A52C^9e7A29t%t6U9D~I24GS zN0tYoA8aGkL4i1VeFuokhb$4b#5!V-+=MG?@@wo~nZmRgdvcK6f+>CSWck_VoufMA zn7eo(t79~X_AbABVL(b$3_ef}ac@cPiMD~@VZ@j$8L`FlHSf@l@DlL>m%&m_G4#JX z+TU;-u;AKR1k@G^FIL>;mLQ2cLH{dq$%hQ@2yA&$p^!$^~yMRbSWR@ya{-j+J0%FL)KWST)T zKUg|PD^LXj@mHWC1KoUo`5a0RCc7bgxuz`Q*mO4+E@%R=#S;{Kg8XXj4aHUDJmP_Z zPv}8oaaE%pv^PNrt5mpvd+@5}@UNK>BR==m9bkH9Jc_*!Y{ig#o?^WaZ&;zvV|}j$ zROFIdjd+gL_r|Iu<376Xt&^mS^}U@{@3pM<*4wr2I^S-S4PnpCCwu* zSQ5U&MXHEV!jqrKgd)LVAuQq-3+#jb*bEj7Ukx~LQ1YSF-&Sy6ZeeN+KbO%4N$IbL1j5 za=vN!TCpsSdBZ7TY_Ux;`Ni(6(c;%lL;c*f_zlxIJc68|zm4{;rk#hi?i=~@MO*a! z7X+PMxfKij#S4S}ozgRrxd;hlE^-x_%jAU2MbGSzalf9fYLMLQj^#353x@-aPX74X za*HkTpej`FP4OtF1`Pj%`lu}EMMjWPiV1wb(1p&+5`pmQ;7DslW-bzpQYxPS8Kupa zCr!rSu;){SCb`{g&vZ)tLkm1;e<$qk0sFh3zv>-7T2V9K$fH|h;U?PN-9CBVlB783 zV&N;8z*3S(zszJ4!V=o3bcsV?DVJ7l5Jorw6I8_0WWNELDK(=JN8#3Zmu-r8R+QpN zUE=3u5+zdV{$SL`65UtP=&-iPZnRC8GA}olC~HK;oWKu8uC?L!vd>bE;FsUea6gUa z(Tb3c1i=&pBjTU(_ageZNCnl?>HJ7+=cdJX1|v6G?PY^<-kzxH{78y-?n*GYD?z4z zv0*WmH-izF8Kvn8?ii(5@F`V()_ARfnCn_GE!VgLb)q~T*08+wB3Kewa$@-w&a*^ zwR3*6=ONKfpMXp5R$W?OnE5B8?I)Z^b3F%L+pI`oZ!spU<`}_|ONBAteW@j%N>{e; zW$)2btz7qF7GISJj5?v7dgW2z#KXkPVUVDAZ*U|qWr}9 zBKcg``AVT1bwxCf0D{_=-wch2e0}4Z-16E8ggf+51%zahW`98>J@FO!92|^Dj}iD&^PsCz?m$o5-8LVev#6vN7DmaraKQ_ zu84o@W%q+uI6z+qcZf~M6RlJM9Jz!`{2!*nTE7Rsqe`X;$N9+g0WIL}m+TTiZhysK z)0qa*oOQywdyZY^nzJ-i^UR*4=ZXmh>8$8w~~>r|wj#ykpUbKjBmz3nD=B zg%x_zXmxpYBQD=dI+gw58!5b+eQ4uxr@q0jxo*oSZ>@mBRxV0o8-pEo0Z|0sA0V2t z=qnM!$SAlBpN#Y|Cyb#!jTB5Djg*n)>U_=3&`CRQ^Y)cN4P;rGR!J!1m+|(C_oQH#(3^V3sb^n8;=>V8nf9^%-9Vy@hBt zs+9D6$|ss%V-7H4hf~!19|h}> zsGEwSKCy+^UK>}D>mgSX6O$O72J0-Ac=AwXwJYm(q3yULZp!rT?|F2!U%x!C7U}f@ z8^-J2F%_Q%z1TT0nLHM;dRZE#chrTy#V{I!9K+=Ar~r`91tT?BV+JDvH`i4&&2^ON zwPH05_JS1#@Z>GW_ zf5jVlBj2Tuyvobm4AwL+dc!jz>-3THB0eI&DsR$9mPPmdo6y#jr!14>`QeWGgj*+( zSC@N|!SXuzg2tfsQPsCPz3_|{FY`}oXQDR!8}u&UKX&QF;1`_cZxJKyYOm83RQ=G63&tG&!yfhfky$W4a2tK$3Y zEfjUQF+67eT;N-ua6dUY*L~E<9Dmn2c$3=9mFs%PH1!83%Uo&7`h8404rJGh7~=Fd z)W_OTYf6Xr<9hLVj(R~Zj0Agl3#{8-dJP8lUZ?tR)ot8M zKc{J@1LfF6f;9+i@Z0ZWtaqI+xm2wwSPj)^4Fv`de*d&gAYS%LATwnyyiqm7C&~&czg1hmm1mXFP-*$xfP`xug_Xu2 zynzP_15slU4_$@-Mup#j^lBWup>2U`0)61kJT&{S^l$%1_(&s0dJcIRThT=uFXvZktdyMinMuSWGKTZ7)q-(&K2;`?ToLTe)O z7_h(sPOG--z<_q0z03!>8ajF|FnVh)v+K7-@Nx>6%7%`9;okg?Yi|N_kZE;`!@$0R>8V)UNYXi zLST_*cEbmG4i|h<5mstbBbl*On%x-KAS)DmnK9~i=x#H!o|jPs|J(*4J5Jz2^2r$Q z!`7Fv)R`5ycMCtqeCt&!eSK|U^;e99N+s`!2g)_+Ta!XNQ0SbIRpJIkYoD0DH(X0E zLitxaJ$Qo>xQ2@U;O<>UJ|%&7x+m7OmbfMMJX~MHm#Jg6QCc3ai~U_D&InjD!Pvwf zvD?s^c2RsZ?novB5I}?B%5rdi484I4UU&45M_-yh8}ics$x0Uk2TWc~ z#@=|WjcBoCBJ^s!i!^@T@H${xbP~iG$xZnsv5p%Sw=L=@KmVM2KJpx2E|R7Zm0!d2 zMGMOJm+E~(`CfY0YVy}cA!-hpkR4rg8r7%5T=oG5vzq-|L{3aX&+=hlQ37;l`S`M9 z_AccSM+Z{-nj(xy&xwcC%?0XLYIM;_v@n`lizElXsX@a5{W{;3kH$SlsU7ZidBXA* zpF)FypHJFuY6JUebESrrx+IEJF|SqIeO613^~FW4B|~65q8dDH=9I>Ltp6)AHlnN4 zYnB<7r~Bj`5j^Q5Z}mowQh)l$TWoyNuLqUsBd131z0B#{Gd?3H&d~E|rRUGtM~Tw? zQP78C72jLlI;}Z^kt*tn7{Z-74UBd$ZycHUl3|*&7}-wXb02YBA)4dDw}^GXGs`IE zgT)flMh~fX3_UN(x$Z4P&r3#o!_PnuL(j+Zx&O@kh$I}HF!~FBMLUcSwo(atGlQ;w zNNtlAKt28xf|jS#bwN| zOG^A2tiMN8hkZA@Q)RUm*x&E?JiC`ybg60R`BMddM)_rio_~j3Yog6(l?hzrk4)@@x5wj|`7Llk2W#XbM7tIZNY<|R0x9rJ38o=A+eu4{1q$3`ujQsh){~{m&uZ#YgG3A%!v|LCI zy_w%dAL36mUZ+#=4>kfq!kznYuwIYDW}a13NX*H;(L;Dnj2D|x zyvzpf7ilL7r*9~H&sL{!cRUheC0+xZrrZ9G(bylHURZy$^|z&s=Z7@o>7W1LZaw|1N?Rm^{E!OhpGfsn;DieEW{KBBR~NeO#S_4Q z(YDUFcfnAlEMm6Vm6|u#_&`zsHQ4;TD$4{pS@*T=LkF!g{JTg>!fMXTjsSytfy>pW zts~Eh6-lalHzp_Pn|@aQqNqmz7!$F-LCiRP%oF9zWKJHDBb3UeZ{yNneJSgO} zJ?mwB?s6LraaW=I=lTczXTJGrRsqSuIu;kTuNX`3KRrFR%ui+l!z=W@Ajk@TVjt~J z1P&MLRq?LufAF_9pH;oKTtlI@{h~+(R{yMXVDs&6T;#^M6D(JKt0i58UM(lgW*r%Z z2kO2{tEGL^cnKHWE7W2{JJkUcPa5FFOdb=fEH!cJ;G7e%DN+qsWU{L^n(*zOcD zMZVwiv#V0j*jjej4{Qw7ckR3chW+rbxHNvFI{&G;kH$0fy-z~V3RDpoc6<)Y*F^$k z;al1Z8Ig)w zpQ{MvnVm^7^u8iLs4ZSL%8&gp z_cl$(^XgVTFk7MFJ1d(h-~A1bV*vvm$l3*|EG|)d#CykfF#NFQFs+V>7OIMEI@5fc zy~)+9`H%YC`C|F@MQ$kZve1;wN(T`Krz>y%P;v62@5($(KAOg@j6Ek5E0T&q@88lU zFv8~vqsMZj5fN(tNpr_0|JlY_^BM$JlHS^?h#1<&JD)S3mAaVD{aw@3(m@xbWw7?` z+QsXMcE!_Xw2oy$FiNT5Gb(%5BejqE?k(BBa*a!K^{3|Qmul*XSIR+J#dD4CU_Yu< z((Gt4NDG~r2Gb=4Yrmy>UG25s(x=fTcmWCe)xB=g7Rkg@6ML09%xUt59bN<8HeaLj zy8b_}^mn)%kDzJ&JkW~XC541-OI&%69V;PkWkvnCePT`CZxPDmf2#MD?c*Vk=iIp_ z%X{ZjInEt4aFR9fz)Lm|^_vDx4e+9T-kKO^;7UzICGdL5s%nX#E2%iJhNMJ%k(u5Mm+Nhae1UxZ6y{|zb%vLeQqGusMY z_B(u)>;AoOqkVjl^zWzn`B#iRGyXa&5Pn+4kwa70x5LYxE5=ZLhUw#)RDC;KeJT)I znpNs^)TXVS<34GF)(2?Tk)Z2A`pIb~Rw8~*KPXy_Yu*)JBq-hb&fu83UZ9;+y+#yK zz5hO~Qck4pRa|dAlr_iIn_Ds!KB=)r{a-@=jRcPCOu7W66$tIwV*Nq+ki|3;ZE@^WH%%EP{H{KEP=B@EQG8IEK&0~q zpDfT0Q7`o@xLws2vubWv_Aq~I74pq=kG3Bczb#jjg=(;bUhfpq*^KieQu zHam^eGW~3$J!$4|Fg%-v{j8Kk{M<0(Wl0;lg_%V`yz5V1~%DDQ#scc1cMpe;LA)g)NJBrjyw>sUL zD~ccgBfjv4U&h~sCtw%Q?+oU7_UpKGbzQyH;Ev`xo?STY`m+X~!((EM2Ni2VD>bxJ6yt2^#_zd9z>Moot~}aC3LO9HtdB-J z8q^5u_f7YWK(y%3)*Fy4FJ~FrO_4`MeuzrFj7-h0H$hHMtSfPZWdmn$L7kU1KZK7Z zUgf#uH2Z6DeDuN=--?7EkVw1U zQY)1fHLAYR$xD*ydQoRYtPu)1 zIHlTWh?#~z$Y1>nFA~Wi-;2XtJaQBhAI;7D z3mqw!P1{$Ii9z4X0o`%8y@{B}#Ensa30@&;DmHgQAZqY#*SHDNyO&aTEX{-4ZRobS z8YbRl_82d7CPmOc>O~`Js-%lV_HgsscY42#y2|~xpq&am*(NaStvj8+#bE&*u}>U` z=~*bkTc@-OuCIUl~5Ub?3YYyw(v=%j@t&{zUcLa5~W0$ogYIzgs;nvsriv_oGf=x#7+m zgBf&g;w=d$H)BsBq6}FtCZ58LEXHHGS>g{FhGQDx*LIhWqm$m4PyS%Zm1+Zfak*n| zb_jn7etA*e@8-%#2{$wb z)?l#Cmf<>gM{~gj>xi8y#%%e1dP=at)9`%b?(Jq29NH-iML`;c*Swnk$n(DXxb0S<02@f>d0>F{azg6m*m-@hd!uXE3p1FsE zHAkx2@v|>5CSFFJpSy>cl^8|ix+_bXm@`;d2OR^=jj!~7k3qU^gH<)`QrWnCkLb-#;{i6TI+BPHc%?-mEZ<{vP3{f zbw^iLx()l==8m=f4!5&(zLu55>vpw0s3vasl7lvTIQWdJ4lw&s!)NTT4ST9PqK)Ix z5*3ceSPur8jx*vkxne)enawp;Y(jhxS;^s~uGu6SwL zN7B!}Honie_pdA6zti5A{SlUMkKYI3>aD)aQYwee3|o;B!9F+|g-FM#5{{Vt&k4S; z$(6s=qyhWA|A?qU24ug$Z#)v>ZSg|DGk-`W!$B^^PoFl1WWv9edi31~E82H<`D-7c zCMTOre(-rselRAOn6u=03x%dX)=?A^CU9W2jJE{CQP z_P!bi7tHX6Gqeh=E5u-lyV!=p#V8916$8DE|Jiv8`bcRqNs^u(JmbC5TF zo~2R$KeEQct3CDCqt{=aKJpjzE43PrZGQ0uVre+96=y>YuL+3bz0XZa5`stNk*pkh9X?YX_sX*Dnrkp92JL-2yJ~<9s5~|DnhY4Za>0#r<&N zEF9g3$L#VP4oq~`MHSreeOJNZ?X{`zNZFu>JCZs481;gIQukq{Tl2$eR{ypN^OJXw zdy?pjt~nPAZ_AtX8m(3&DSs1YXyIs3`h`C{4nc(%^SC0JIhV1$rJ16HXyK@?qBEEl z&p}*ce%gQif;A}$q)r>!se+Y$!8ZR)OZ_XFO}s5m^dPq$R1^(GJHta6@(o6A=G)x8 zvgqad?omjVkwKpL$&JBC#x6DmBU&u^$**yU&Mr1{_`)u>1b1l2{Ua_wl9>^S8sV>( zC5;$p{`!S>QSYx8<&!$YU*BaHjsE(jcG2Xoe~(=>`|Fq6MT@^)3m(!F`0H2M#VmjQ zWp**!Uw@@t%<*$ZV%FiVgS^?3^A%?hN^gpP8yZ3uF8CMP0XA`tjHipc|(#n4+L zdpKb)2v89vHuTo~qaOXB(AlEs;de*(ovr&O<8(J`BtwdwbBY_9=t{A3UU5US`sCa? zH}aAmAY;*ROx}jt;)9>Ob&I)B+6MQ(C@#TzExd#2@W7t-+55JorWN-GZj~xy0z8nI zL)5yW3CDQ;4bC9&*z}IZv3GCL<{y#pUkbqFc+n;Ti#~GQxy9sT>cHLC z%~4d2f_oP&Pp_N3?+J_iaosuL)dJSmLk`NxrWoE*K1G8c{I0Br1-;B(;~l}dr@gVT ztg&ErI)@$9leUl5d6v!)tQ(#=SFYhwEU?@>dFj;@6I+AMg~hDU2+N#60EWaI#kQ&l z;FWoh;Vu4P@}%MqA~C%033~F|;s)Vw-*5Ik8|nlLcow{qXDe<<)PvVl^{2t!&(vS{ zJZ&^n8>|<(w3*cd{RNR9zWW8qJvRn>+MCt4uM0*u;NfezRC`6V%%YBj=VV;Stxu_l zv-7Y3;7tO0ZU~ai5Mt>dwovdLBkKb}u7xlBp?c&DdqMf3M$KUS^M@MrsGr02^DVTm zmz8&{e<+S?V#4NxC|Hp(QqBd(2;3WsSQJgT?h%{X{-|uTLFZCXT_3k?kM0#5!6&7* z1h>mx91P1+oPF58{YrlQ;lJQ7iTL=NAC8rd^s@Q}q+jt#S5;u*&L6s(LP391@zYDW zD1N$2-weHnzl!YPe{-!s7-%F^TAUs)D+9E*?qB$;SVj{>4hhx^pyKCRRaZ}Aaj^wR zEPZgBeelUCKA2@6M9FSqrV+;9Lt)|bLF?(THv0V$7YND8@9MxsEZ%~l%Eg-P*=OdO zJ|bDo*vda@J zPl#u*Gf+GOqC_Zi7|{xBxYd_o%?%Qb!!{-8<^CLJEm`bD5!kG#rPgyDCoJ^snh|V1 zh$!F=Q4zDk&^99{!o4sttRRn4y}zPfQ^E?uCpG#j8iVCc{)#3AGhEReEN}5wv}g`k z(HbnD<*%3(ET8SKm>m$}W5pcF{T1^h^hrF2#3z1)+rm0>f)VB&`Wx6RMC!l5W+8uh zU0|~if%pTPh5Y51zcmZ_%UL077V?)j1vU%$%bNq6h5Y3$fz3kx^47p+A%FR-z-A#r zjRZCeDR7O=LjLl3fz3ib;h@%EYZWdGABWf7I5-Bz{{2&ne?}B-31Z?m!aCqIc7zYt zFqV#~@`JIBAl$-mBISriWwCEUx!@uAO7~}R9}U9DWl*Vq$147Y-=%fw6FRTtc9Y$V z>E~<$HO(S=v=T+&$F zuB)~C9+rIOYIIL~)4qoTJF7zWyuRD;#*&g@4~oR)>ANN0-Yib_?r&$QY9KfqW+mH# z#S7Eh7y8L9Mx#(FF*l%8XcS6?Mxj(AK zP-w{ANX1$!6X6KTEaa>&cCI6zyoV=9#(VPFn<*v0(mNIw`v(2KjgxOMIbTc;7Ls@I zh*ClCJ^1RiUBa~Uc2%9c=LEhw&(B`T&$j*3BDyf;gD4(B0(>+Ude*|T!p2>x8O6k? zs(SB2qK4wwt?!D7At5t)SK$=JG-3z}$-$!K_PpC0`KU@HN9R6T_`q$N4EhR%a#+UU zzX5#hu>GCL-MXM|Dg-Q`E&$H76a)V!{*Si(>$J%fbrk!?gC$K!Rrox>*_>!(I$MZ{ zO7KINFi~QYP~O!_Xwlt>IH^YxJm^OdDW{qFafve!^QVT-&~`L$K3+g%rFSLTt^h-J z()hg#-F|m5F}Ikgb()a!ru-QCN_g3;fV7YVCF9|0E-iR2^Ij>AnUMy*aBT#i2yDnA zjw54Sa;r#1p->*MP$*+^m&6^RgZc0wLZK9sw-n#soOw7k7pEW~JzMA_=X5d?=_c1J zA__q+3pIuR-9(a>2rtvfleJTtM|s~0*QkC1o2O1U!mFr)aOYq@DSS^^l`Y||tCczgtJbUT-CzE0yMT7UYLn3{gkLuZ&Pw)WB9JA2=Pr8CpjG6Z+ zdESzCM|lvO+jayI8Z!oKw}#FM^uCR`o-L-aM*6R-DA%()Fb{@cy*Pye&Lt6QUm*K<4 zzX~626Nq)se}^=^jD<2as*y!j(E}nn4SMfHnSg^Ki)Fz&IqtMQM3`&j;0Cc|FeDoc)Q^vO)1xDMyzgQ>^Id$;(fijO^qH8M5?62a{k#?g`qrfaN^ex7Vl zPW1!w*VM#wFt~W0w&$*u$m9I?08w5Zlj<#Z)0>3%6qCfaQ@}eY^^CcXUI>kj z|9m#fvbq8)E|Kqg$DJVPnC*AW3X-!Zmq?#qpE#VHT}KX>p7Hd%>!%UHf`F+0k~-$7 z7>PdflUwVaqRC^R8Sk&G_7a1>7O{&?Oawg#5keO+2$3CQU_6(Q*Af=Ay5JKDD9Ilv zDA+cs2ObU*clMt=`RB;*;3Ph~biv~IoEP!clbRZWfxUkH{IH{1*0LC+i*{QUO> z?Ms2$GhL{AX$)VW2nk;1YAs|2#?$YuuM4l_+Rg75&u3EjP!)E!(d1_dzCl&jkTL?+ z#tt=;uWKKy8qC>K$j zc7vQBxJ10Rymy3wzEc9k(x`)WzhfcEB1%U3MC-OErU?qC%K!ejPkih}FJ6Afapj>o ze{uUueDY=2o1j*qO~fv&c4!}bIaX@rVS>wsqpSgTg#W^%F$MohpCvw7u&PT_rtA{d z0TKnV2*j^t2}x*+OPUM+TcLJaY)n`MUDn#nZ4*c z%Idq~lBU9v7OlUlzHFvs`AdlaYm&97ipPz;$Y(KV_L)H#e-Hs*)l`?vld!0E*y}Xo z!~=SKDMY@Nib~6_O}wni4s(}Y+B^+txr&*@Zek)X1x~Z|B(h74WC(}0mvngCzz~l*m$eiKQM<5JgJ&g-NF&o9^F(kX zswC^1EvtvFOnd@KW2>BCO z9uDQof_#qW+soMecAZI%fupVyr1r*0I;8d8l37~T?Jc}_cCqiE)7k$NI+A)&VL{8D z!8322CX(2|LWI?0@(7L!@|x=EJUP&ZFnbo zHnYoXups7ocg`Iv?uQsOR$4M?LWn5mfn0K@QBHEJs3m40zOiA}x=?mk8|36z{5p8A z!VL$Fb3q1(u1#IKr=zhz6@6QoIotZScq6}J^n%{8;3lQwdMj5<%*Kzo#N!6?j@s$A za7##)i>II7v9?PSH|!0Pgz31yUV?(V*rHSOfw{ZV7R)Gx?-!{WYUO|3*L=+C`c3g8I!;8=mDwklfg&50tMO9PC+)?L`|m zS1i<2D4X5mMVCLcSWJ8id=$cB@=mkXUteGByK^!=7x{Rhz#_T#F1H^staH`q?^q%} za3?wKW$!LNtbQ8y`cDpjNdes#(e*YXjmvg>hllJQK2DLgg|&BqmWj`e^w>{iZpS*S zjJ?LFr6gpGBq(kQ@EFAk*X*V8!UsmdCxWdYP7Sk0=a3hC_J$X z4W5#Bfg%ebhy6YpH?UIpP4N*dGmbv8ZvfMP%t-eZMD$)p-kyc+47{_+M|$w$hPjV| zdDQVM7Dnp$!%~`c&Imp93&G+hDeLalzDLx~Wbp^I!_rAxCEl=3^gRAEZJ6B208n6G z7_N``1`FYmR_G+QgTw)#11xZjFd+nBBOac_7mSk_0daI;EaxHq@YkqKSnAy9_uUDK z_iYQ`ARbeB`0}>!d5Rcc!f%#8i|y6U_dxJ3V=gkKylUCSZbb>Z+GwfpHt0m$R^CcZ zmVFUAyTra(M!_YHKRK3_3bAV;&a0o`XGI#bNS<1m#^auliy`%v$}*S}moMbusnrk5 z5O>9wmZi8c%2FKn-`0bd*=FkiS~xL5nQfc=f!*m}*ZKo{gMr-^xWC>fnsV>>wtt_- zbD}>C?8m)YEJ={wUHN1|q`mDoGktQekv`)JlBGro#>JW1o5nT;GO|Cj%f0#J0qCn# zW(?mhBxCZB9{S0Npc6#)w^`!T)VZXlHwEA6AG~NGPkmd@ZZFe{ZE$c*+mZ36yfif{D;+}ZLFomzt>Oq2M+js6Yl-(_TIJiZ?3I>J+7_C;9dg|>llZ=@d%A+ohRe7vlYAQi5v<511Vg3fs$F-1f{f?uz+HAp$2>(S*+lka_jZ{F6ZIe@;+~`Et?*-uVuAOBTb$>eeWmnYl z_L)X-^cQIK@1aK#fap3fVE)@@h%(F+!60B;O^?k&6f=Es)yfsq8CP0dF~f1y%oWVT zRTEe4i$<BskoE|foe)PiTpm!&{6-+>m!U9 zI~6-}hrhflln-(+VD~pACVvIuO4<$v;JPXD30nN?vO&{el6eLVI?}{S^6KFoP9Bn$ zfH;*{a|BMS=sJeSf2F^yD_FJ^QGZ%`C!XT(kMd!?4`7@^-MJL_C!cWhBK4K>3wAGs z09H=^mFg?4*}6++kN6QTdsPpsJY$j4afkDr8aF&%OEpma-&Ne^yO*j!Itt=s`l8dX zw0a(>L)v^Oih=)E?l*B0zs#R;6B6F9gtMfv)n3%S1gxQ|RvPMdC>!!Kw8AGxmp6!q zf5Ba}Ok6!0lT|+Tvg4LwhSxv+F2&DNlHc#=mo&-(R%ssdmozA1_Ckf2s#-c3L=+Z8 z)&``5mCKC)5K48x*)Z;i-D}NW2AtZ0dCs<{u{nexQXvV=E4svU{zN+KE_q$F$zb;<%i4u zQs&=$7r1%BPp)MHs3*hHUM@VBn!V(mEQj%0M>=%|7cNxrc5yG7SeKHyTHWzWSw$6Gg> zzmYo6yRFf?8TPKG^v*pV{uk=4sAAnw?up-}r>6H$PG`T*0o2^;6nPsDl<^k2S{&Hr z-JjegFL;)B*X-QWH&(o67pp3#!>5n5Tt7Q~q@B|3l)k=Y(I7wE>F4^>7uCW*uXuFM zqeI)}f#~;cEc9$GM&y%EZfc>_i?&d%dsDk=i|gJrsJp1{hvz&zw9V@7*;LWZ>=^bQ zZ=C{MmKHvG9V5%P*XfGacLo=Cu^Y&s<6*wBZE3rgd79Vk42lk7UZPOG!-P`MjS^R_ zvUPVwsbPZ4Nr0fL-ctIG(#NZ6_OMjs@-DdlGWzBixs%{JT{x*grAJd9$8uiIE9~R; zk@$jJ6tJ~?&jLFV1l2WG-HAo-@-lgKiWj{b0mxt8uIrvnx?b9)Yy1Y18)Z7}SQ<6e z{+`7hOD>FWq|I3c?TPf#d3L(Ro+Q5pAV-(4qM1DBsiRhiK;PNreWSA^rnPU^jYr0~ zp@Ub;m*UAlclZDTaRyOCKm<(3dw3~FKZ!fduWZ&Xj$<1a3sT1GW_H}`!E$k!Hh#Lu(HqIDwn;AnQl1CKl;DR-EquPck6mAlbj;=_> zE_H%hed+z0zvJkwgA@sR?y2a?t(oW%JxzY?C{83%m6w$y^NgTP9o62lY=cvj*zCR@eTjEd z)Lh+8z+zSX?iR0<*rMuAIMeVPQ>HJYg~p}qu;CN@;|axWk(@S>UEa@TC<{M`oeoFt z)_&Xx%l~SD`5dr2e}fl^%wO>-ZWUw|)Bh@^%B9d@RnE%_k@6OMH;ccK#EH&Y4ZmHF zNeP2Q}xsC!Xs=5u4dS1N^is6)%V2-=e0Tf9M2ywhX272-y;v&mUeL*o3=C$hqdl` zq}Y`78u-}sDlfC?$W&(V%e%r)@nW=kum}KgA5UXAg@WS4;W!g{2_@l1?tr_5UG=jE zAgpKlB3z6zFJh3`s9@;3!WIF&*Hf2`u=*dcy$ z(7S)hjIyK6YO0xerw*%|<4UmpW@>8d9mI14!p>c>(C^z6!S7sKP%Xq2@%mneTC59^ zKeU(mHvq*iP44o~Qc^*bA5^6^Q4nQUjXZdO<&H7$J{ey*a`X7lKtxXNS}63d=5zc# ztZJ>de>U-d>_`;x5`>=Q*FZ{5aEa{$+q~GjiCs*#;FTq4oLN$K0<5s?RmfwB>_O~O z?5FDq6o)S##-A4dUhFYA_x9Z;Pt;B`v5yuz%~E-bmpM%Lqfu(VjHxP^9$7K*xI&>? z3pLmVJe=xfE$_>^Z}ABX>g<P15C(x8znf75C?p_W(EJbC2J<8O_hRbWOfF zT7M>j#JT3HG%ABs-<@eZqbR$e6BnW%ibDGD2@-2?BGO{uAFbZe;uUN~V7j`6ft1ZJ zE5|C#;#a)KU$WH4C#7>f!k?Fs*XONm7WxE#kpj;86Hxt7{w(y88=exb(#3X zbQ&$|CQmdtrHyXNVQOKTk6$791=CXiDL<((X`D#szMc4t(Y*W}%~%xyfev~+5ZH8N zX(3o|1rWFuL2Wtavls~M$+_MwG5xvS^Gre5A$=e(E@DcC_Sn+oOIE~g5xis`cWf~w zD$M?sdpjyc;iv`{#EQaGwalSFBelM09q6TBUd?_!TVWh&c`G7=0k#2cF7(_I4Q1gP znXfgVYpetmOR7Xx)oci(=~z+*wv^;UMQR&3mlVs)m1~QT(?^yn&yVfHuv!KZo4zBo ztWJMoMos^jY2#viontm0>Bi6#n5PhI#a5q=p5glfzHq!8+9_dVQ&L&v1WT~UkUdzU zeMxiiNjD9xAM-x9{iJcCR*PdzK806PMEevaTsgGWi^dH=sYfq@@=&MJjh=+C)c+EH zwHA6J$`5PH`w*p3sUFwO3l6QswS(f9#i#(Q*IsAy~W|uU3nEAuYETWKhA-hltR2N+oc}aTFDHRq2l3v3ISr4l|dkW-mUT!S?iTMhS&Vn+0o@qC@BAOl;+#0{Q zEhM)*hl9M#LFOv&zGTC9G)Lft_=~2qb^zx|MXo0}ojP{b4!?j`-M0M=CvEfY%b&G< z+Y@ys{m_4JMSbDlY1Xv~w!FSgADpjDeE;mScj)-hL30I2{durblUZhz1~K5UpWNo% z*L{YG3=JFG$m${c$m$xl$=GsK8L}##cX(YPY9?bpm}vet#St}sNmo=pm7a17{4bG< zHr}YGPNTn~i!>#X-pS!9%#r=);P3)Sm>p31O1}Jh7z4#h7Rr)4mli+MVw;-4SsJX zxb-fk8ozfCs1Q>ntCZAt*EJ<3M6o+bQn7)A@uHI*Yx_QzjdPDhNs02walTVsi5#@W8y@}s7jY$rc@?*T9Ss0v|@{!8p3syf$uz_(KtUiJzBWa^DokMa@i zNN8b~iXBhd)KSHeC$GRv2T8no3GP;-7&X7`!2cxJIu>UYP`l1&HVRxhla@{-+%2Wg zdVw!pN1fY1%52q?&j!-uO#OB2vF}-j^MS#d;;MR1q6_j8IEDiN&ED(uBsL#t3!|oQ zy_{?ug#zS8^xKKgOLQ9^ME@099LB|;O(wJ&i1(z-KIO)3EHkz?`FSsU0+@5-^gQ(+ zJCM~i+2N0E3PP~>vNl!YQPP`9 ze@99!`+A=SeOfAAB1#gWMhJIPPDba1DLy56S=Tauk0jKDCT6N6zHqcWe+y!cj;rBfW zA(kII9KDAk8qL@1mI8*j$fg(Ea5sFAt~wMLlNZe+yF$-TLHXXg5A!$H^TUSHcxT33 z{a*G4WDG=MQk5j|4gNSZ=N4GreWsx;_s5O0aBPa{&$q=6@3owok{I15O-6wkRP1r0 zhtd`AzDNCS?j)w0;K$FglO9a-n$4{}-z6@I-?(|+T8id+IW^4;-%NF*j@=0Ka|}zZ zQ%_lcYq6+TWm)Y1*2%1ikhsUONE$sxlK&%PVDs;bigPccgWx(hAYI5jrcueqxnqm# zF@9PC95dAP63wnmo|;`*sEBmYDN0jMN!Z3D25~V9*Aa)||t1DCUAdINm zOJB#-oH?Hn2_HoN`9tu3mNNeX@J}VtO6(H#-T`M8ifvkmd1oFFpz6#{;neb!pREJW+chUYIoUdN- zKLg~H_;&z*une$wEWjmtxl{n>6a!rRLYL?6F{!dE`8g>=+3T@ogo`x>(R=%~BFLq% zPh3Qvm&7stosoV^#D6}WQpbJ2>OAf{jzz*(Q-1I^UQAJbGXPFm{tjMDQGOwGKV|th z@Z!Hc0iB0b`fpeAmXe%~^?y7QVI0G{-^qeo3reT>mv&Wy-p#STX_IDs_&0>ripHT_ z&&JAndN-Q3ra81+PjVyLgPU3GMffsC>bQEoR#^`_7*oLWwPWB(F(Aj)gA-c0U%mHC z166>jJU~`VUPFFf*o+r! z;*_=p<46C~{vSa%rnS@sm64WW#PlD+x@SjG1w2OU7<%1R2$F;5Fw`uYodq|cKg!s_ znV-Lp<-qg70_N1X0zca9W3&HPHqT5Bx_PwZ4}*gZ=7kmbA$XZDfrz%>_P;#*92c%! z+b;KuFX472o97(S3`~}Wz~z%y|G&gvdS?S}K9~3H0D{Gd@J8lYCd#rs%IHDSX&iJH zPJUSP=>Nm<)ycHfYbwWAk!b2mqh;%;kIQp>&uH-43Xc{fhyQb%AQ;PNoVFepj|Trx z4tv(eLz++4kKcDL`5b8@5xG)U;Uhlpq4@BOvCMQ4HE8may`cZy2ng*mYl-A`nOm-V zDmPG&{Wiv2{1L@xqzCrSWS?LPJ6&8V_P4@#O}w0_8m&Jmz(#=U;JWZA0X;%%#SXQ{Y!U|PpaKaZ=b(&){u z^h2f6+G3;hEH695m5$+Mz2M5aSPg3Z0QL{cz6sw_t}6P*O4*eiFV(wMC3^PaPoDj{ zE_=69o+P9-IJ0t(7>zNinmSbZFhiXSHq%F@NBr((KWuGn#yha1#UF0eilC#_ zAJ)!O&@sy&Znlfr{&0(3%<+fis~U97^M_~I#e9Ewwp}drhv(QuyFWb7F1q~T`F63? zA702sD33;yBf;ej1Zvc1XnshQH-r4k*|^vm%b)a-d8t-!XpU(e#RXdj{U4aU9g(K)?n;TJChcQYxmDBQ^pOT;mLXiE!56gX`aVJFAJHnt zC3ip~5P(D=0Es}Trxjtt=Fw7@!tUGFM1Il;v6a;0G)7 zJH+%r+(hHuzW4z=@*&%{fIirp_zv`;yo?>ybdp(P_cJ28>3>r&BRfX9%oljBEr<%- zOr9h=q|s_MuV3#@=a`RmT4&*#uR9b>&kZ~fa|PXUlwOD^z5jdZfw7tWQ1{L$h!hDtZcm=%c-lMPsplM^xY;+=PvzL{e~8hxWd z>OH7jjHFU#lfj6n-YGuOK}==vQVojR81D<=N#$jK&4b8n6oZ!ekt>AMG>be8pc3}l z#V&Gw0ATur{py(1do~ZEi9Qt7*?N$VVtq;X;m3GkwFDP8_%p24_?vECRp>+MgG&{o zZlEqo@w+e@!5$6<Jkt+6%>$KjTx)$-<_GGNyB+>H5-MeGyDOQ>{VGveuHqAN^ zq#Ti~*D*fz+z29i9=1~$evJ`08Tq?AdEVJn0exk48oi}P5SjqqWdxy#sng0| zKkaX!PY9n(o>6a53&nq_HwK-J{FFSCVw$V!A#$xg_pv5ytQ38f*vxrd2}Rbw$#JJ& z#kFs$jr6S_)p8u(qvzp#hbGtgQ$fFj*A12GEEal56?u_odW z_EkC?!_#=Hcz(z5hg70tSw!Lm!OHo# z;cwfY@GqKEAFN!+PeZV>ou9^FWfwn9xvm-7=1k-)Fk?)uX{)VPN5LcS=Xf=j{y%D` zwu*>ME<~VC{>tGSj|vkZoFULu)7j1sM~AxjsWgVh4KaPi4aG}~vc)uNb8;R0M6{FM z@k)iT>AEK+4(3#hqsTJGlJK)1ImD=(;AMZpRnWViIk0oS_Oo%Y?5LBB1-@uVkLAWM zxsTz-&+21GHC+|0RdT&ryUu-ZHj!G(AIuBi&kgWTfzt3Bykh)^4$2{J$|==lGq7p3 zJ7+Oij@OEl_XyMC6YGDolTVJ@HqJ!vuhfc5^XKG5G+y$Wxd(EsL<1_ZncG_!JIom1DD?lcanPfPBc`5D2Y%FZFRKW) zLC$;yPSbm|^PyNfABwf}p;$W~ina5hSUVqzwez7^J0FU*^PyNfABwf}A=A!3N|TYi zm%egoL%zeQ=tgBAxV-NNKyGhH;WJ~A!1P3<6IVETCI$Wt-pGG4<|y#1M~~Ov6Q)O3 zf0ehWHR2Pdy_2-VXb++$E2^I5jeLm_)Y>4Lr;b}6C}}S10|#yNDR|G^!gCj2PP6Ny zE>RIDa(S%R*Vt>JKZnCvX*Ce!7V-$6YoivIRjSgJDvDUw7`@MFy0iCHU&!2q3I*hO z;}!KZZ;60(C3)@IanbJb*)D34;5*BOUR_MAJ5xp*M~UTE>mKG*C~^o8_q>tvjEv~q z!D^B7+N`iQtaO68#D)G(i%BS9N)J~o`n%-5L-cg^<*R|cNdcEO* z0xk+4@xyU3Yn&gj{nOYK0ZNdTi{|5IaKOK)Nk93nCUI6x3Tbp8*Vt5?mg{PIy1)sN z-NlYX;mU*pXm!*TuEc?7H(;_rVqY8y$;bL}Fc)l%?SQfa>o`stgh;PZA+i4yMSL=B z=Cu`Wn9_vN*qTr76#zoTEPhLM28Jk@n3ElGfj6l@C9bG_J~l6+>Fv$8BjDJGrJXrs zB0PoD2IfSM&mD%W4Z@DR5UxUg2L1T?&Lwt}RK&ckF{}mCRNR$fQ|U^prxbPF63lFS z291pRjgJ+}p~2~KPKk(b#+p|n*|>w@gH8Qk9RG&Qv0GU@@dj1kD4ZVeQt{a4XT z?_Ay6evv4+Fj59OgX=feYC!#qY7_jD1F5!-UkHLjmbEOGH@YZpx%%(^lRq<8@xMFtTl)3>jt#R&he=r zC)`c%+3416YAW1=EOqnaG4&-GGjH8_{Eh0nFj1TqIfyIok=1!IM=bV=wc7&5va1dI za~(fe0Z_Tx>cgufsmIx|R(!ulVrTpG3Mq2Wk)Nd%c*K=?OYJ6d&u5qOjEkBZ2xJ)A z3dbVH789S=y1J$~R(RqZ_oVCseAA57tl}e+iQ*%iYyTx@%h5w_cunyK5xhh6;_*Gi z1Mqkb;Kj)q7QeO_#im`bL4e$FJ6JN1(qA{gT*%sO`^mnfxR~3Xm>xxE7Agg%i;_H8RR!Y!*^(SoLr8K7cXOuu(n=7QlROoD~Q z@_rR=%dmMd`B1KBfAOMLf?Y4}?nE`YA7qm!!k2vQYR-DdB_QL7(=$Xxo>oDm zy}VC9TScT70Yd{{cVLs8GEM@wy@Bay!O4N_0nxXZgBg68F0nBwU0`uIgg{k_GkQ)eOyO z6+Pbv{!MbYv~L7W>)T5Yo+$*4xE3x5E~-OdQrks!2u$kgssjRQdcCOrOW>K^cedvv z2KW${VgPsUB>TeejQ&^h)O_+E5?MQSA|h_6+9`w(+iZ;=zna===%y&!2wh6ri&1zK z_&2DHHMX#$tYnrRmRK)BS$H|y*2J;4Vchowg5;T>?R$3HFQ)q@8JtuJ|5msuI-#@g z34en|XWQTEZ-T;45Kvyj{ER&hr2|KVT(+0!e04jkYK}9jQ=F^IC!f|8rV0#fmsKpD zN=tfeDLi(zj&QfLvxD4-^Iozg$pQ%1+vqcqc5EX-ZTJ^HtL-OUvXy$8&Eggc7&Bu& z-jO=3`s^IL8m7cW?NX8Wee*ZZjXh=$VknTKZznS4X{rf7@WKmh z#6*Yxa|7&F9;9^~X|3ZN|BnokdT48t0}*8E?(VY{#Izzgud}DKnR@(w$wd6!Kci*Q z?L2B$xfp!wsy`Tad{_V9(m-wh7pxpuG0iFRa|SU2&rGtq-!nqNO)`Kxp`nOR@ zZU1*M(@%jq=K>CDcJ+Uja%cB{#>#=Zr9x6NwmmD7l~8wj33ay35Ti<{8{bk!9rtyV zH0?DSCL1GZZ0sm>%)!v%cgzFBeg}#;=v`>&Z8!9Gg)@cFWBl#ie)kJ(c+1wsVDwJJ zRwIpt^5DjDL7J}Le~5EJJY?$s{wb&uk;`I_8YkW zeu0vDsc-;6|AFtnpf6v~jUFmIfF8Ddgom0g^>ADCaH$@?E_%2#dU$nZ$vhA3Z2h6@ z->Paht8PuiRAbR0gZ>Gj0n1#HUCqjU?&uEN>qM!Oy%X$#j(ruZ_g0m5{W%zbAB?xX z^_4a8JzMNPE8XgEUaaMy|3&K&>!_|+W9Sz+gWmw0{<=_;Q{@h>*&mzyK4S)`>mqs` zbM21QpK_%7WjyhJ{=2W{I};)u%IuHJF}S$yszkc^s`>@Zwd2K_ zT>Z>qEpcaY7D0zxjQS|=5j;s2*Xi;=@sX>Tftzc$7tUr)h~O#wC5ywy3V*4o9^LG* z9EY452|yqp6NIdOkSKc%eQ<%ymrx`MT*M)p6z9!F>yqEeW;{X&=T;u|yNUx}E}l@& z3Fu;SXW?NTy|R!18;jR${CVFOi`RVFyPu!rL&P;GKk4~mp=Y<<-%1Gr7haVZZJyp; zx2yf-HQs%_x2|3KvbC!k*DgQPUd^w1wfs!?RCQxLdMCk zU3F@6ao{inao7mr>Ebm{@98^KyykH6k)Zcb;RoBEXevKKc{o&fM5ms%mmc!yr0x44 zo9H|4x9zVxX}f>XE1J?Xz`~XCKT-ckRFXKI7?4+OcXs%0JgW%RhU>QeaBO;02`gt3 zB$8m3oEL^Bi-c4A0Yx4OmE^8UzbM70;h3HnFNyzu{E`6F*P*| zKYAothQ@-c-~SJ>@S>yE!rY zt|Inb$+Ubsp5}egJ|^hfHbKXtyN(?KncVellm^AUHa$r~cH}TczTSGW&%eDn(V0{+w5nblR|s!V4NB=7~izP=>BGueU7}xp62AA4S`F~ zezVwhk^_RtBs|lTq?7oPoziB4@4zD|qN4eW8o^LOb_(bw$WBFj2?cxsTw&{`c|!2$ z_()@Wz?W`4^x&0MLgcpgl(+hIKpe0y(OVl>h;`_#{=UZHQc31tD|oa6*fX9E?ny`8 z&*75Kxs@D>cAU7xt=nin3-F@o3rD_%q-Hq>siNIc2WaUz=bf=mud!gic;ws4_sIXp z=%32|8l!)5?_GK1h*mLGfw%bG$1$+UEN8Ztk^u4EAC72!Q10 zCbttOX_?k9d28=vps3q6^ zFa*8WySw<>S@OaVZ$YA=!+WFSxVYaD{V3|*dgM4`i!|dk8f}i;;a>tzCq0{ubFgFQ zn@?P9?LQI~yNFjE^d7*SnXoc`CwhxWuM;*2I}x_p?5JlvEf(a4MKGqZAIX;%ttrLP zO~KuyVq9%4c8ySVbhVKAl2oyagmkndoqMwWhDC7&y~X0MoD_fZYI*R#JtZ-GPveRp zmmT6r|F&8-aSR6!-3MEgL@js=Jf>1TCV*!T?Yuj-5x2S&EHNo3J7bwjg=aO(58x*zS0({121V^H8 zD)$vZj}KDb2=5=+bpkxw)b1n%=Fz9EFqu(!F^>AvTXA4f8yn!eTv=h;y&5M z21}+?7u#G_?4hb+i5w}&6Q+axeo7~qw=>^RenuXv83|EzyKC3xOd9=`y=gh z(w`r2e~wQUtBT11K~gOFkLiUiH>lgC#qyqz&(_Dwb4U)t`hk=bUY@@sn=7 zAdrN&lb5eD&SuSweq3PFW_~8y7skE^t4oYB2(ISufPd8wg^_m`c7N^l?vimAGdCJ; zZ?-2X%_!m`QHAZ(hTEr&O?R$pCm+9GQpj-|Gu*yVuL(E6H#>nw0P5X5sVD(c>ZJj6-F_~*^Z}3*jpD-KQ;BD+y;XC3D4pLjBS&62$qeQdT%sAPqM!rjWJ=I6)o-5~bWHQxrv)9;{r2e?=KJj}IzoumO2;g73pN{*6?_Hx zxX0yWK>Pfps}D-8eEzN)?|n}C`zl}^x&_i2pMJ~Wf_%50KXh_CQ+3AArx{_tU#fOL ztkGz{l7)Il?)|CSsFy@ql?j~FJoW>qr^S-x?*h*GaEBpb0od&)Pc&T5f;GPE%hO3>bOeYIbo0cwL#MUY6>26IzVqBC@J zrdxOBpfXND>@9i_U*Ie(^WV@6>8au724R%fO(s*1u_b>!8NKTk}d9;SYzM0HE@ty5hT@ z<4eVNodz2e-*pDJ>+CuRW3>;HUcAi1v1?@=bSq23J6!BmWp#&adnA_v4srkGr2`_;@y31w#bAGxh8Rv*-$O$$!~V%_N@fiC1z*{)v~J zm5yhuoP(ldgbXCZ8*BHYkeVd<5l*IH+;`Qpu7d$hz98d$31qDOHUpX)6d+FW)*ksK z5dEOWIC|F1Wulv>MmJB3Zmy4RZj5ej!aII+a|XA-ilq?Rw6jb6H-;QFalb%K$p24% zm0GMF?8pnMEf}z0t2wxKO5he>cp9h(Zk_7N`i1B8xO|#>#UD7O$NTI3!9BXUw!sf~ z>*k&&KMFq3=nuR{Pq$`*Kcp$DiLJFiAIm0H-s_BDS{WpL2NFBWp31?(0n9S+PCi){!zm{adRWzanb=^@ZP2k9XadFR(* z4q`?G@^f@((?6Pf5|Lsen0K%ZOXW->(7eM~Ik3iJJ5jABy2FCLD_~0!vf6L_CITYY zfwr0V{0jEjr_sOH!JeR6DA<645p6&f72C!XO@j?9LM1Ag5_C@uY#`ev-E$?@G0Dps z;fR+t_Q9Y=5S>Z`gZ+a~Idd-#t~$#`=MBTA$4yd{w`o&|sl2s8A*S-y3bfBr-kKr1 z{dkp!E4 z&gJicM@1OZfg8!gjJwIf2&)llDxe^aTL_o&0`V)>L39^BSySA5 zbSGz(i%)UcTTESUhn6$Nr+^Q$Ynt6a){f%5%TqeYystRFSwHEcJB#xhEgdoZMsLlp z)1tP48YaeDeaU33P&r*Ym&OO7)(*b#8k5{RkaH;a5lRIEYJM)ikTOlV{EhCi*j;XO zmj`HbE%tHl=?-_f(_P-J>#kKvKm)iUmr4)4UUJOFL5p*^Njq9BCP!T?=_JE(aci&#`7n&&?X0D3r!p1ML z1u)irIIo$~G(X&X_4_lTg>zGGR`GB5r#oMBz+C#NP+&C;TPtXYnbCG~4GL;Y^lV+h z0MJ?%6;|;^oxzk}n5wr6;`)L?m8~0e5I2*QFf}_EP-2+c<@)K{2osH%A-} zD7W?penHQ{%4ue^H--CtVJiWdV70zow(R{M2ineo_riv@%ZXSf zLOi%o2{DW}CNMsB^dDAX+TG&D{jaIgwcAdI2mST5yY`fy-(>Ayos9c`O8Z;X{!rKx z`|`@T|3C!h!f^8=6$`Chm2v;Z>7@N`*$*1FT-4BZrPudcYIJC8|H8G`TVY%KmD)E~ z)|JWe%i45`Bs;2?OKEi{qZLaJCGS6HxziIYw-}5wk@^I~ak;tJQ9M@`*_|o3Z_#PL z{Y>d}0-xu#-zfcrVwL*Fv-4O4SDh|BJ?gs`mp@xEwLp78vgDlVyqipQ@(1o%*;2)6+|eoZ((6V1+q3vXnX z&TfDtGcej;yz@q#IMJ^C_qA*PJy^eZ*Ur}6cI`+G(D5CRtYTuj_F&L@G%Gf)8NF+l zO>xzRz1sH3mT%DVCp!H>*g|zAzknV~y!lW(TIA$^kwak7piZj}=a0wf-s5>C$ne3A z8#*{}h6?`a+;9d#0Tv0LmdX1w1&M*9PwNHmara>MOylH+Dk|Hiaq{|=ceW8j5ZY7~ zG*vlkUTt8Ppe1O#$Xl(zk~y1vTuG~FF0YwyYBd3;xAupcVv~q!5I##+ZENQB4G|S2 z=$aa^S@rt7eZ1{%kra3C?wwp{;*kd+>287dSEs50@BdqD}vRr0FvA0QBLU7E?_Uf|Af znws{8el_?F1^xQ@dHhC&>AL?~lotpPhOw|k9ogmgZ{->lWO-5y4NeLf?n~EFcUeAq z8xJwdO)$tRuKRj2y!CG@XTvd5y)oR&>f5Z*@UURBXs`b@e_$JJD24)Q_PB0$o7eEO z?^Rk}09)Kw%&VxFGCTj$+M$*b{t(n8_YIojL? zO)<~lqL;r&UK2)}I`Pc?-k_k_&~ZT<+jMI|9rJR(B68sN2?Y&$@b>y(P~#h>t_u1! z;BMQXElutB-NvQwVf8iPq~*s3zPh1Ug3m5}h9~%HjvMk}afH{`6C_dmGR*8OnA!Ws zV`ghqz+hWURm{vge%T$S_s9iH%+^^E#O*Ocu%$^v<9LhcpuRMjDU9-c{1yl9DUulY=keneJ2#PRC z>m+Z@AF-Yg!17cZY6%CnkV^rqpQDgx}ut(BzPPQT{A4M)7Qbz(K z_K?fgi@dcrut-b$;gdOfB+wqbmm*PWX7P@h&qecQrn#Qsn&Ns|oD0l~^p&tK0M9ro z%c2czRM7C2o-bVpM2>1n0&;W8M!r=rQn1Blu;~_F>BAHc`o&L+=lh_fUXrVNefvCa z^S7x7JyY47x7B&M$CNgpv@rF5>ER1?NRK3`Z4_dHpx1K^!Unz6FI`$V?{cifA?=4r zGSWU`H<0#Yb^~cYZa0wjlXe4XKV>(N_UG&d(tcVuj-V*9u5X9dvG3w{K7QA%+EJ716bRI^FH*P zZ?2?b5!kTr+=g3$;rxCIi#QMG_r!OSzvQ&z|&G_1k=`r4mB?coz?Nrl?SwEmN7W4sJ@dUE%e8T*bmW^&*z#Q2h=>SP9jywz)5pUzt>wMD>k!F1mDv5s_*+SqDMK;1|>&Kamp zRW<&j$_1$%QXq1cS6iS4u4%4~d#9V8lCf8!A*>Z+7N37#+Pf7|`%x4c#%ymXHBL!5iD|{Ik>F zl!wVIcff$NgM5ZhayNCx^HgCn{b1g!M;R$PZzFAHIQ726fxTN^8~tfMo_lMiIS6$( zJjV;g4>H=#SheGpPX%{C3+U6p||4Xf{x2BgK$Z&3%gEt*ODI$CYEkcB^phbxA74`=a zzQX<>!pG7O5x(ml)da-2scpMHZAas{R}GYgE-Ut?F64N7b{rQ1v`6R6U;yRWIN|)eE_duKLzd zRV%RSsH)pYb{`Sg_nRyzyag%_l~`VZyTV+8Ai4YE5Dw zDGBzRvSbGcyTwb^>E@o`{RJEV`>0M9h6TGfE0>R^(C zrqZkQnyKGg3yZn;)_y@smjT^}gENI}ob8K=NhMGENv%K7q}+R3yfsIK*v*0`>{nqE z-T3_yspf`T{2voo5rh!6?=P03Tk9iY5VjxCZ9_!dzxIQ=ZH(#;pKx|rT=x~1?pK*_ z$|&n#^aaj)uuB@@U=5~O+#S=8jI(|^A+Hl#C+5KCHDAf?YH70$daK`J-Csy&C5^j7 z;!PWj=;C6t{FQg6itkM6cw48uA4Q8BiA&5Q(G6^Z~3R9_66`5 zw=Rg<7wWn&YQIs}8&7;h?9_zJ%Cu1~JV=}TTc(#Di^Q00=81;EHW-4WJ)`5IS^PH; z6{r++5JylOZ_YX}6Pv}XNHE`l_0MeX{f=oN*fU;ZA$65+%jW=t4^D6Wu|JqG2>%2v z39g$GrVcqfEfX&Nc>GE`NUw{|aDvbZy4$5raevP-lgncZj2VAeHkpF=-FA})brU5#$=q8sY% z*w;vOONP^4T$){(=$594=&b#_HEMLqHG9oGjY&K?mUY(TyymMKWH&j=PbQ~n)Z~1Y z)-yToJY+IIGppuD_to?BaZ?0D=6})BH9rcmSTs1$|I*BJ51tAasm#|MnA#a1Vu#wY>8s)`quopMEGSTAZ(!U(k^1Xvs@onH3 z^04vNu-+Y9OMO+24(823=D3v$rXo^eSsFN7X=R+9%vJtt--2?l{}R8_vVMg{AT8_T zEHAF9NAygDNG`S<%XTm6^4Ut;RF?jdRUbIP(|=OKu0k5@t$#Vc)eSp!u7=sEAV=($ z8avVwT^!E4dL!0=rD%x=E;2{misYgf)@@^S5qtwmrjE4n4^ve{?8BYu|1|btw2s(x z;^B=~@At2(vViSKEMPl0T~zPCwaLe|A{1?|?F~?&LGmE!u={hHOK*^n*v=^+_d=F+ zFThYa7Bg)7ED_AosxMH`o$DAB#Dtk`aId1?j+Kj#-jrUCus$$m))|(BnbmPQ+b<+1 zp-OL3IpanWWA5vxM%Pb^uCI@-Z;Y;QimuQ2bEf#%1J6M~dmmpc&3u~AVs9f<y`(nGtuMrKI>i<1ao#yW`h)7~2UapsV2Oad3eh zZ7zLZ>IJ*46dnh$yTY$k%?U0^t_8zapvXduA}h$rTcZvnXwu4+(d2_er8iinQDs95 z4$*ydsPy@9zhiU@T3Ik+SWTq7HPf)@Nxoy{s=uS~S_#3^yXEgFq}a$4z|8dFrS=X zy-z`^@o})Sf$*?ByO+Ht*>vSjzjE0x#wX7M4)`GA>E4=ux_4@B_kGSAgTo`;yZ!DV z3Jhm=tKOvCvZB9okH2z%vWFb*XcAA2qGvd}T?N?=;*M!g!bZON%x?` z<}*AJc@h^2ho9gjB$F7xNVC#&00hU$aP4)Dv**#fa%;e;aa?f)mzlwPy6rll!~lzF zukQ`yB8tXm&yI|rY0%9@8ToW9-<3V507-;9jdnaa`)m&?NYY37P{BjScrH4k?7`yR zm;9*O|3y}r|QmE)RWJBKRP=Q=p+%~^PQ zmdhTlZ_RG?)?92oWoSJ|Pw|zq^4rCis@0VSX>`gCKvs_I_?IS?mnYGndp83bT*heH z2th0uBrpFAc_-4bUU9EZmLo&n;kL;p!!0}NFiII*W)53o&m1K=pN7wu|241g_h8q8 z?)@~n6ZZz*RroRRQt_g!^7$Po^|ei&PBS&gp|&CkZg_5wJO6Ed2opoAsmfw6o=9Eqk05Byy3g9aMb&*A-TH-V}I> zDY%)yH=&-IaTij&>m+xXfYprXg4)oc>vYKaOLg{Bc}n^hHiI z>^4qZ`ESUQa^VgBQf8wPvK636mqDZ+=Jlysu5X%{o(F`V!zpKLnDozmAGpK{^E^aW;r&jUVlo#|}Xx z?^oeZ@JD^P2sbbXbZ#3y7wkXYQE$I{e{$MeXCo*zSBCEtKF?9_2cKZ}$CbS1-j=y2 zKJJb47w{&wUD5~T~fdt?7jiV7$``3i*=1#{O%F2Z<8uo zd3eV2c(*<=YeTe`6@YL_Qo>x3WlX9_8u}psjsd0NwJRQvc=lg zuA-M)sY>wZojqK7gPRx5#f)W<}Y}+A{Aw@iDh9&fx*0`aSfqmG??- z;fqzia&FK%G+#OR&f&;>ou184&M$CRUYGKdbN+QXj<1~Rby@M1^Iy9zo$s7@UEZp7 z86}Q$_Q`dQInI#@hg=C7i(q(k+=KTT7lzWye~Z=VhUTnMajWgb$Ip4L|07z*Fw7PH z$^7RmP;@;)^2EpELOYvYiSX0eJj}L;CEX{LOSuoGFm&|!B)foY(aCP| zi^W>4zky#EiW!F--Lp-ft@D?`+rT(0-Pu^8 z#K6yn8txWWM+!5C)?FOCecxx|8sSL7#>+V!Ra*}2En&lhS`(Z@R5RlS{cjpbdp@dm zIs{DS!8r3h)`xdj^7eva0Bce^t7V1%m!~v1|?1cy)rxjPfMTQT!s9dc`3ZWXSk=%?VbKcD@@a zptt@Os=>DnzoobHBmZOB!}uN7u2uX%8KQdcc>iznJqJhS{!m@^c<~$fg5uj5b?h7+ z5?whDIQ>;gb_LRh8=L~4bshCaR~UT0@J+rz4a|ZYw(8+3e{t3njU1?jPw_VjXo*X< zf5o4dI@B%Dit0JR@N-`2V3UK6UDt2uf9@oln}*a3^Z6h=TY2U09oIi-?&N#q z%y06DiID3NZuO?~hgiQw?col4eJ?ctKf{iZtqFY3Fk4CRP)EJHIBeAsW2^nc9nF?L z+IdXJwBe5NuvLe{R&yU`7CROWcZ|VSCakErX1K$U7A$L{*jE1P`AhRB6xAHAJjNvx z_KcLrwFSP~g_;ya?Kybj7Z|UDMM6~I*I=@|d%0D-=3$yEg(Kb{fQy4=AwYJ7@n!?I z1Bs#yj>+{jox6(i59t=UPOMfpYHzXYuuUa5MKHdmw7MZN@({YYOSJkT8tlNoWeOhs zbH^tkA-08WE7QzLW*piUGc{7*G||{b{u;D+)NpFhkY6LWlH!A6GK1#YxwzJJ#8qp_ zQN3IA*JUu5C?cs8Lwi`)DL&jRNwBjdESc^vVLR-I=X*pGjCdl?nOw8XfT8rP1H7~7 z-7JV*6+DHV%~8)ugQipGrF0`Niqc&)Z~;n(Hxvz@h|-8CdiJEQ$16*YL2TwP0~H)S zxG_q#{AFYF1s__qRH$)JN-v|faZ8^%SLt!St=3xI$4AvYOHRwnr)fkL68Nz>r47m# zzt1(z!X2HTd%NcRcyzmP5){F|o%uc~dcfyypYGqze2*BjG^;${Ak5?*#Bw>#w!OxS%4p^95`De!jLmmntmR#W6~3^?g(Xmi)r zXvrD-1!=Rv!Tah)Vf*8UzX7afSlmUkXL{!TkE0rpB;v1VzqplcF+IS{MkGP|v1*Bn%4D0K?#x1gJxBeHzdg zGD4DlhFjrUc9z?dVF|7Xu2Yfbpl2vZ{TS3Dp#c&>dmW<=0?mM^JI=7+gkf=sQ1!M9 z-kdCDyK9*YTmD^d7`7q|1FwjJb!|_!kZSwddEia(@{RV{sBXp~4vVpZg6_?D+~I|C z^Cy*C&*7U;W$lqXf2))PsaB`A*@gO5KN<7Y}QRpVN)P-6etlXj# z;D5uo2VFx+e*#zrI_3ye*VfQhZV}JFgJrrky1pfP2MhE-^p5F5&hMC_Q^Sd2 zN%wY~m{sZ3+*9m@ zYVIj*CkX(90M%SGjOiGThtgaWE;j z3#7SGjyUgq!RYdSXFOKS9&YX39d+;b)@E^Jt5gcyFd^2_eL62~?tU|NfhV?4j zPyr1Wht+2bVIn)(mK#Fo^w99!W<8JIvJ!^r0vNsR)57T6&V|vpB^W)s`O@s8mu4T~ zz$&CpNPPy^X!6-e{csghmsovryb`w0m-{JW!hUfVe@EM+8SL{7JE}rk+EW=xw#s|Hd93pQhKt>3+VxFcBp>4 zL-pziFE>~_#SOD)IAcmuRmaLAb;508l;p6xn3HwI*Xw0oa-5!4oM=bSCK;kRDn(7z z!$VZ|b7A*w6+C{SjyZ~*{~WX#^et_L_VrcNkPauq%GaHN&cdl!4d`}ZOSE_zULr*F z*YKV&;fNL6A1$69ErujKRGv@fMx0-*)dN3ErO zsCBi^ewH=C&q(PHnXz|oFe1Uw#v&RGa*UTHkTqef8ZJ)25N`zp8RM=YOcNP{FCs4R zvqk5`@=R<$0v(uvbx{>1*ppBKqXR|I@O@0_ec*jZqU7<|#4);7XaFB?1Ox>$?Ps`P z!FoD(LM+ZWb6&k03)syW`%-Q+CXp}*wxQhPS>!8-0VF}S(l`O61N!bwb!<6Bu70{^ z8Z$%8PzTqOCf>%LZDpEK#j91rmvN8%kb@Ye_JLqTA{^K)!tJ<$-J%wRsHH!moZ}

    nK$9lQ!?t~9G(Aql` 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

    imA)|YRtKOKLh7I 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 LA z{+uhncP8vSP_F*>=fkPNoy~nx-y7lNm`1ZozMpZ}T-9tQW$k6q55Ni5Q$e}ja@d#W zZ@dN0+~D~`|76RP250jd^P4Tt`qh1YEkC0@(BCc1$_q?KIQWj=tdsg50>`k2`H$3R zIGkEj$QL^IJWhk-tRF^7{U^fCm312b?Q%HtkLUk!4IFCMr2dX~!fvwji-&}B-!IOK zfn$u1?)>~!TmErxe|LrCpP&7GV?KftoafV1>h~p_CVt}#;UBF0#jZM^Yw>yR_uEMM zj&SfFN8`o!hU3?H{*#Bn&L+>lVI&-2eRz>v|9s1jdhyt&!fvwncRidqi}TPW|3m*z z{tO)Xx{OEW1++^RcQ{Y72^PLDscY5)TB5)l0j`5QJIyk(e+Waa!7xtY|r|ZFo;q=>` z)qiV=l`r)Csn%F#^}+Hu`}<$m{6~BCHNV2)RW-VwweO}}d(O#@55(<)gFXD}KU5D# zo-J4Z#AevJ*VBIthNG;92g&b^fJ5zy)gEEIE&pQ&ozG3R%z1;AlK*B~{$DTt?L0U> zyHelBIBe7U?E8a0687PL?C!U{ZRO18Pn7F@V9U?+&g=Oc4!;-B_1JdUNqX&N59W;} zJp0;WI7s|=cf78K6UTbzyBrM1zwqJ_4T1x$J^j{1IE}yVV^W_h;mn7Q?zi3!$2P!J z+m62rZTXgsdVbvVmKpC3mh$hw!4u2O$ueI^!_mC;<8CQi~ACZ3o$65cn`h%a~4Ep42WV~#XCjY`R^OSHk zoUE!*`<6ps-+MjG5pul{9Q&=o93lFlv*0-UvAORx_Q6)3=T9;fPO(3;IeY&FW(I67 z=R6?!y}57_e;0SYbUz$y)vWW=#c=vezqv+!{|%deN;mTc9n{|MM{xX-N^`Kte}cm| zm#e+oF4!FHX#9eGzJ@nfn0Zp40?QKuX0&`S%HhO@V)GIWZm)j?oczv7Rqc_m!*v-s^Ch`0Lln@2`bJr}Q+Fq`!Uz$9DSF zp6hQo`fb2$lKfq^kpJQKo;@@iY1PBLgo4ICpCjSadDUu#erC3E zKYy2)O)_6EhT|Qp)SjaU9A!2#UVg7H9N5-qqH_JAutU78-2Nl+G2q1TN87A3AU+s_Ik$r z3`dxcdp8qEx;|3Tl-{+tiw&UeZz&k3kKR3A7VZ?E&Uqu?;-+q(0Q6D&XL zH{E4C84bs<&pS`9KORoyjhE+J9vsl~Qm(b-;{oFr{rP|4L|%NGMR4#{;#bS{o`((k z^n-*~TPAhLvN0QBANoaqmJ7^wI5f0Oftp0sjj|hFdW1_{b;%VXq&%le`D2lHvg5dDea;8@3Q%^r@UYCCoR|4sJ+TYn}3mK zZ}kHl-dt+ll>YIT-|iFWBB`>E%KW!2a0t4IS)2@_EAs30nX2I`_B@~E1FG>{N6`4Kk-~$ zeZ!A%GFqzpDSO~B{$cKVrQ~~fTd65vu(Iu011GQa>Hb7t*mrQ1#)~=@cGwTNMt*NB zoO%L%vb-Oc!m-b5%(-$uGp&4Cd!0Yr4o6R`(D>ZlbjQFaKTyLf=&;Gi5|M%Mble?&Y!V=iGy@%N$*LxR^yvcsC z-2YdW$5onhzc-q9rGK4l zt+qX79t8 zX`jB9iI;MS{QhuT{!2&gvnIgKW^cT{0CtmYzv*y_^WS$!`P<puoZcX;QQ zt%T#8FLtry{}xUz_u?n+goBY%^MSlyEq>wptcRKY=f-!~xv)sjm*@irKl1#0j)6nW zZw{CIAvnPJwMclpmCy0kFXzLtdm2qZ`rmXb$G-7Q$$twRWq#aA_(3>Ge5KjKPg?o) zeXvQ*)$dg}wzl5p9F{V^xG3*-_%a#wH~?OzX}fQ(`aVO@7)Qfw^o_Y zq&^8a#(dbl-g4M!?rN@+`}r6SR#xfwzTL`)I_7uz{dPNOzm;Bp^ux|%zxhkv*CXN7 zXC2hPasuoo+eR1J{9DUaAAY6fk3IXZS+@K`mF6(H-h4PfywZX4`w7@g^6UI$Jsds3 zvp@gbmOsSv-`fgj`UiBs_*d9hggvNS&+O#)|8;ac>;z}fms}?DzE=K9gDI8z9Bbvh z8)ZBt9snGi=Z)`Y!D-efJicsyxDvL>mu1d_g9FcVe_6)f5sohGtoq$I;TZjQu*l!D zj6KfL!W-Zq{-?R?6_{V)5c<3UB0u0)_@P3xRGw!iIM%v1XISOxQxDrz${+T591cfj zH0k_njFtcGoyQP?edqekgXFdS`vy3SKeqe6#BF{__Il3>=k~{#+Q4n|&Z9}gN#ePW zBCoyP9ypSxpXu-$*W-PQio6OAcB?eEXX{&luQ=s7kAvlAw)}~3EYIJ5k}c2oty1Jy zSb3iR)C@R^J-6Gw_rdY~0_tD?q|J|ixN9Hsy3L>WJxkgAhZUPu(!O88p*K8z_YZLR zThBg!7wj8YWX_cS)9QEn$E#j`9~}J%`>ocw`>C_?$p`Cv=1@2_t)J@0M#3@de>TYd zod-L8s`P&T11FyL&MUhfP7>esQE9(894CHkNXjpP!`pnus#WasSZU?&6zY0qJ)CIK zU-hF~Z2s;6Ge+|N1pE4TH-~r2mEY$N+Jo5Mt=V#ICNyA>VsCnvH$or9>d3QdWLr% z(Ka}BL^84q&&RQ@3EI4(# zWBQZL_W#@9*cGK_h&=Dd;b5LU$P2KqwO`{etcIh1_{=)F{(9KC$$P)QfW!E+4iWhd zoBu^`f9M}L_H(`YRqB7xZYn~`wJ-imaCBKeji1vGj<52Y^QFGSVJ9!X{#iEvL7X?j z0^Huut#F9_Fjqgm08V{XsqsahferCJUHkqd9BbKM_lHw9f2&3lrcU;Ho8dV7U&jgm zXywCe)&Kn;IQ^Yp_0=8!=K43|uPOCyuuM8KTi%#KaAJQ)^wl@!FxxlQ2oiX0|li$KY;;p;- zvR|y6^9Y(G|Gs;v&wRg`Amdpf9Qx5a&!amWqrGh3u=O8k<)?f4+7Rq;9>bj?9}n9! zD$B&@vU2Xv)o0Ft)9lyf*3Z~GNd7&N|328q{oA&+zxNcJs_3la@%wP{>ds~jKV#)P z;Ap%=_Y3wjym+J)+4457*uKQ?@1XkO9&mWy&f32Yg(J%=Of;LnfO+t~COy4K*JG!` z$>+-TysH1ep_#Sj8Oi@&IB|VI^`(!)4)H>c68YleL#20qw>-BIn@BHLuIKlVR9S?@W@yaIiql_=(;RyQT zYWck=99|tz{qB8maF<`t4|&$|HO1ypd4HC{sfi8RA2z`8rA0a({|qM|_0A{y3l3l2 zr23YUeYxI|-g>(nc3udm{x4uTZ@zm79Jv;KgVc989RIM{^ppEJ!{$$SGRsAN8Js45 z%4+%ET@R-?KXk9iAF$<#-*mCG=ZiK!-y?TD_7-eDt~1MJeEitvuMX(*{sE3W?3im= zAld%+mz9qx*6%~R{q{A!enqNp>SFmZuRUtuV6ca2#|vf4H^JfQ?EgxAhQh7$)<>tp zHa(cFKl4V*oWE9=RPqetblC_^PkPr2To(3+bH!9!J#~Rq0``C9#4P+XH=MulK&#u**ZY& zUvGuYwdJbcxd)EDKS1|iUawVxdZI~%<7 z<;TK7_P=_|^)81~Sa-~Cn`^H*w)~%+bv#`FC#Kb?ee@DIN<5MVDZdOh_j>x}wQz|2 zrZYso5zeswI#YNn96sCY4}0O{;3ED0`u3-OocEg3PZyYS*d{)A+5X#K_;TS8oaTJh zxmhkS7r;^WL@tQeq6KE zF9c`GdK!0rbFP(-^Q%627Hre-Y<`wDa3b%0c?3@5-;ry-0`oi^N_0~DqW9t0sw#7v zjL*MXIrdatv)3yy2ehI7;b!&cD2GGn1Kj@C6OOUIao?AIaH6b_sg&|V;2`n4&k+v8 zKI|*P!V%bc#IsMk*5)7TH?Dm}3{G=?*9^)3C>&c_rq_D~j<@mR555K4l$-yfI)x)| z_{~xBJ^WPUHjf<-zk?I4E44jZ9RNSu#SF>Hu~&nWCwudaYB+{HeXYoQ!GZPVsxKS> zr)G39A$i`zU?2A3e15Xe|13E9wqN(tF0=BZE6gtqP7e~=6B)5HGfu|s#E!_yJP0&G7Cayg%>y8VJ<~$i556D^zktk0mXLTt zX#6skWg$ibhzDK<$$qeefbaYMe_i&D9jAvQovc`wy{`ZI*MDD8AM=lx{^xd!U;Ja% z|1bP3*8A&!Df+*E2kGMOyTxDh`*$Dd-~S&HJ#>QfAO7T*<9m(ok^cFQf4ca;9A1V< zFaBP_FE!G?{#)NI{!<^{k6DiQUhTa8Z1Gw7>`1$KdUw(i+j?e$UV>$k_^9y}F z(m%gQ?+yGfNdNjjzFYh;@BjZs`p0*@s2}_%anOG9R}i1U`~Ov>7eDzd`rG^&q<1oV zzqd&L`d|1~jMrTu{qukRv&heWLi&&Yxo;J}t^NF&;@@WZXt($SAMbA>{k#9zuSELz zw~_vhzy3=Rzx++47r&Y8+kOw}AOCL&o_-(czwsZW_sRbu(%*yrHt-++#6OMkt$sQ3 z<3ES={^zS3S`L2)mhb;d;f2sJ-y?li9kB^f+ z@e|U;@BQ=feT07x=|6n?i_u^6KSui3|EWJKeDe!<_3AG&4gZRuU;nR>{&r@M^tX`S z$>P`jPb~ktzY_h;{{ZP9|GVEVehvtq`0*bg{kw?w@W*|;KlgK3Z{Y8_r@w>r;=lMT z#>aWVG~$IndHD~J{@!2y<>+sGjr6zwk3SLb(|e?g@BHcF_Z*-9TS)J~o-NQ%e-7!( z^KVE0vEM}cZ~XZbPvS2z{omldRSb~h{clk(!cRL--+_ye}MG2|AjwM{9P~q893tpA^e%cefC|XfB&<8 zF`l=79qFGS{@gEl{m+r!`76H|?IHh7mjA7PIr<-biS&>E&aW1K*4OXfM|$zk{>kER z`uhJizXyL5=&j#D`ts>J(O>-UG5uS>r(XXbBK?#9=v(nT{LC+)efSfE@BbvyfBP?g ztN4F>eBVX-CmBEbuOYnye$MXSpDj+2{*Ax%t5H5)jA!H3E&hBqEQZTfy;|Si;%8YN zU%$U9-=6oc%Mz)RM(X>=SqC z6g@uD2wJQNrBHL1=ok4B^7?zXHS%DZY+ju(%Iol~V|PDQ zxVc-Fd73R?kg-LUBR#E_cU7Z{Ru1}T=AhA(;k~2`?T!IA)2DK< zSWKSFR%^am!};uXe0Pfzhs`;uCjDx-8qa6NX#Q!&p;g>8v@@EPHIMeXu7I@WF>AG6 zl()gCMul)yb=hv5L zrnAr89%SKN=WMsPcUVjZt9vZkta@5~cJK;bgIzWEU+i_Cmi^w#Ed{S$yeJlEdzZ+K zV_)BlhovwfllA%rcz-;qyx@Ke++NkI?(Sdi?{<9T?PHgg^M|nY>{B>+G^p>3TV4z- zEpO&afJb?U)4Z9>bFrFt_kDn=Z!}XqE#}Kr%3l)O13Gw%~s`Ic`n>g#!)b3C7ohsf&w`e46Nmm7k**>Hw~1+F%~ zoK{%18TM{H8<#iZ5s3@_qqQC40<8-iB4mEJdRxA!Rsg@%9C-8kc~KSX6$y~>Y*j61 zgGuo;os^3KR))uOgyV-pLa1NjjB;OD&g|J7@PJz5!DRe3u1eIxwd>iu{+Y#!D?lp` z->RBzS?FEJGrh94nt!gGYBuUzr-R)k>+=axkkWq)0eg02OZ4SnYPQ zuJ1Lf&L;PJxNP(pnyf+lfDFM5w$#N-1+nfY>`2#U?!DT76>ELtboO2yzR1@&&4}~M z)~36gS1?oId{I|B2#R7gUXkeABuhXmrD>{mceNc{q@CaI;mYYQ*m$qV{8d$PFVc*252xAjw&l$TH&%$2rw)ks^>yw zbvb`1mcw~5L9$rzPwMd1E;@|K-Gf6U0j@^h0c=6kk2JaZe$ZnX{^4mPE$j*4GD5c~ z$a+}Ks=MW2p<99n6c}O*1ir%1fxjvc<$|J7b*qa@36Zf~TiNTqfTi)4l7ntq4d3i{ z-!dq{6}F|dE!1VNcZd_#{mtQvm)#}1J={Q@-|X(Z?1s%AO18{&cV};FNpH&tdN0w> zXuMoK^C03B*4^XjkxcCzY46~bFoEyZ0Ho6+@mcjmxK?hScU3JWgJE@YdiD;xzNN{% z{cTIx1Lm;d4)4d45k_207uDTbAZbP>gqr0E zh=S$(xwt&qJt_Ou>TJnDg66wCY9w(5o%1{{=0wu5R@X|reD$iQ#yO1ggZRwitMy>C z9IQa2Jb?JC3!_*3_k21X%tjn>SgG}FS>1ur0!b0(SB|Q%entOHc}%A7Y+Ox7$M=KT zUFFl~I5rIk z&CBU_zMNhRaKfLms_bR3e6t*k#(uNbY9xP(-{ZHc+*#6M? z@pw7RcI5T^DHV}dj2n=$vB22dY?&@9tnq8eW&ksxUF_GYx&|$<22Bt$-(e#MlYAbn zqL}Jii#H{Z_`=k79-M*0#^W|i8KD(XAoHlCc-m+}DyDOyjBCurNTvp3rwOFkOlgj}Ge;8Fl zSYePqsGegh=d%g$PL|Zp5XzdEqrbSXGQby3$ohRf7(Reu1ET26jO|}TM%Y?cU(!t| z3B%1=3|X-~pyj9W6l89z(N=!e1hyL7I0R?jZ=(qKp&PUy=>Uo(()t27AjC`o$O8cM zNqoiJ&70v2f`af(e=%RR5T#bPH3xxj3kw|qQ(9qsFJz~B^VvvPAEN895beFlu>3J`byg9# zU`>fl`1JL7HO(%8*W=0LW2KAdHMD42aB}w z+91fb2I)8{>lhbG9H@g?I?Rodn0PmM9N%e)8%X0~{x}Yh8tVo;oP%mM{I25otp?b- zGA(bu2I`3QnyCB?w@oavn*p2A7q61#5AU-*d%q+d<5L1261mqX2h>!fW=DQAIR1%E zH!qBAu5U@$&AB%-V?AaOK@tm9x4^73JI<8&3KfOvMay^|PDbH!s{UJM{YtJ#7H1%#nov%-xmqah{dy%-)XH`QwGD}eueOzU z;>4{yjkL(bZ;1#`S9h|3i;3iV;??haQj{{ z6JdpFS(aBif!@`r`%o#%@=6_oq)@q|$Uh3=sQe%&p_Nw(@}AIKNPBTh#uRF`vb}PL zye53mQRE+K;rs>&wevi$79~8PPR#HMyp&AN6l$a#uhNFLxZ@iI@dGe2l%a$s!;*$$ zD2i|kT4-~-q0L;-5!=l(y<*0UhH6=sS8CpC*-md1_y^>^LUa5b+R24Oq5M40^okh< z&U$O+dR6CxLTjG%LadzgoS{7BgswUSnQ`o4%NmOxI+kFxQ4%`o5O9T$#C*njN`<0a zeh_QqnO-rl<*oDF$_|wy-I|XyThwkmgbHC;4dGfGS0mS}9?ir&hB}_~!d##cYUFud z4diDO>%?tnWO~Ksg^^8YqrgAt+RF?dZz=YV-_x8SFuGy*jZCkYQOlmQL0E^+MH`9A z^_qe7CMg^$1*XEQ1fC-llaltLL}rIV=OVm3357y=Xv`}lNQk|M5rsa)YlP1mat&`I zqtipR#0GhtFr`o-bi!$S6;3M@i}~?w0p*7vwaaaMeJB2jilUO@WA}oNbBtyk0d+~B@ zBZV`eLXd=bc^q&k_Z9WxP&<_Rrh4h72qDyKYgNN&HUvT8gBCnDMmL5uH`HsuY8*yO z=nyI=2=kgPAPV(Tqj58m!ZlRVN&+CWPSdD-7rd-J`_M!JEUzd?h^>IUYUv?DdqEr) z8pm+xnhIp2&2#YQd3)U9YA`z+PcR~wu4}ke;n~;oJDNOf zWW#yw&Z-M+&`X8%b(U>E3l?`|`v?8%t2Hc&t)+LMB#N$rOL!%WVNcXq7#GIPEZYr) znQV6DQ*0E(uDS}_UA60UTbSya9YrH0btZ+ zE85$6@v7S>y|;6)wPe3{V2}#qr4@aZ)K4v=vzVHGN!VSQnXN3ltQs5~_F#?+FG4zC zPGRlNbo%(Yz}hv^kJWJRww<%v%)$2`VL}EA zi2^_0(d7}wobZFo8`hG^Dmhr%7C1=n7c%}uMgP@5leiXlaSbyJI+kiksCx7S8)6Ix zosZ_LLQUlzCie9?*n_I=gAGDWXA z<$^(9c>^gni#34%6MjI8ONe{@d_J-jTg?M5mK}J$&bGD~NLXb#ba`S@&F)tBo|vvD zD>xoJdvYcNSGxFE6Yzpq(X2ZZSFl-vSCrU@tpAVP%hmv}13m!!GLJI0!UXo*ex;!x zJ0A*?jiDf&4+Y8Lat^NuYX)u*99Ew<++JfGeg*_^{5_t@4@`g<`(ptU_}Un?=lzfA%rVio8#=G-*K;$A*tMCX+q#*>>!q1vd)>?fKs7TkgXTW?_1>)2 zH7}@WVMLlKg(Z#N8HL z5d;CiD#toy0U%N`%sk}a>r-Oj^Vya@_u-Fladt%9oG%2vdk5ukP41Xukx1Ap)bz*lhCBU5}NvgVK zIB%*stfQCDonMPe?JRNeOlMh=5&o3oElUB#Mdydn9;37LdcNq)4+6l>!luZpyNWP> zXVHd?>YHjsF0r#xRPc0`UR0|Aow+*;LCH^?Ab?j+XB7Z#lWXj(1yBGFaW|fImVQo| z!1fYYLM-Tfwd|~7hsZoEwx1={>aUl#Xs4qYS4x7rkX?2kaywlAowB=jRd9}rZ>kTq znQMZ#wHUx?YnKhR)z(%>RXEseZK(;ATdQSK%&m3ITj8fn&Bv2a#n$G+(w_}x-?W;c z+8?RTPurReDektltsn0YRRzu6fW{>59#yyytC8HV#ZM^qK*)W7rWBs+u;>TXwuB$) zGlb%dj{tT7DKusz4G18TYs{Ffr#E0-vz)0EWqHnm&io9Sp)bZugo*&q3y*R(fao)b z!NMLG1tE+i>rxf0oAkk8XhC1#OB)+O!%E0!*_&jcrzdknZ+V352Z3l}Zu6U432IVl z=yf`F&v!+bLHrFwI7qc>tncj3)@Oxlkn7CS+E_y)&yURAk@-UlQ~~N8gefU})h5q} zLPpLh!LAJ!HW{PzoeyM%+2FBU&B4x@%ZWa!U>_lmeDIp({Q$0*Xch`=725RS{;kyX zX?G-89@5ukhP_VNk;r8~su)P%m;nOc{O8kGHSATaCw&3}IZR3WPSC8YJF+7_9FOea zncSYiG!=>R0T;tA)xdd%@vlX;Es8h|^<7y=2XH0K^!MY=}k6&MYr z&dQn2>&G!++a}n7asd}phxh!u1r61jEx{DKk>OwEt$XaIJc}KU&`&!L%pw=G(IV@% z_gI9m)-s!i%#1@r{$V{4k6u zA1i%78-ur%$*bTuP6Sxy8sJEWb%uK>Y96@(ZdaToIP1nFXWYy{ZMxK}VMKwdo>yRp z6ptc(#D)NrXqoL3EShZ$p!z_tn&EIwJca`qyR-s0($m?sbLC#{A{I=nkB$&+f-u}& zc@GcDG%7cTCiK+p68>_(C%^B_St%6G&2x9VDx^>#Uqm>z(BssX84HGG$rjo&fZ8V$ zAv}avSkDZ9g=W0Ufna>{O*QeFaJzM9q?CQPOhZUf7Vdyr z;P)5@*S+Nj2o}Q`^CbH$%A55K6FSE#+W^;4wT-Sx*1tv|lV&tVdPl(c@q|VGyKC)`LIRIZrRjF_qy% z1JicO z>gi)C9T}VMUwkZ2KVBXGQCf#&vumgKUqF0}rj9PIN(+Rl5qi!Suk*~#@AnX&DomP2 z2R%k}nl1*tT^xBIYF@sN;?9N+_PXV@`-h0}haj$?!oOtb6StMqnyjAYV0{k9?eh? zY-><5QlLoDR5F+@NgbsO(BIR}?haoaijZQ}``yERU&i?Hv&bXFj*U4yOy2W=(%{XK z{btr+xW{e3*gxtIsI{fKPOL;49zhrys%a}51KMl0wOVZn4R`ozSJBScCM)?oy0-t| z<>4!+cE{kD5mpR0Bx9Q0jBi2BAi-c~U0?NfUT%r=2sJn~CYRijW5wXy_PyfCq8lL_ z3sy#$$t3$9dkvAlOVV4pF3fJ_HpTj_LfMJF!|cjdK|?6tD!T?Mg1DpWvmgR*eQ|-E zWq`u2Pnu=Bjd_L{HFLx4o4H91@^NdyUZeHUPBS-{#@Se#Wnnzc+^pyQ&JLQnp^;{8 z*2qC;BhB2ez3Dd;mLpy}>$=kVpBYu*iUY(o`@(Tq^0Qqf}wICfhr9`Nboj&PB^9shAY-fFNIC8U6iJi`IIh|4ymf7UOL zMk62@2sMDRl!67(mLcvyX&Yp$+Jo*nzQiz2uX#H@@Lz_8J*w+DVoN?PKm^kEWj)J= zGcAu`+q- zJUyk?}^O6uxG>x&-@RabTRyZ*|w%$IUhw4_<9@YLqldQNcLPh~k4`-&4k<8c1+! zPcEssE3PU914goYZ+B<}z>iJ3#q}X4Z_B7Tp$wrv(W+A5<{9Pq;&Q({x;!t>-b(}y3IS==62^p#F0D^LF%UaG?S`v8&;nwV zQRAy&HCdF)-TE^yGdwuppUe4(F?fA1A@LYj2z@<}I9+-M%?GEe)~eMjFaG)EiDKUN~8LG|VMUEHKg+V-u zw4@-q&Mz-6e^g$q8K3NE4c-d-<|>XWY|Q_U8VDy2VgR^uH2|0}ct5-IGtg%Q;ZqZz zch2wtlJMemHu~l|2*P}V193tq-C}HUu#1qrp^|<8Hnwz$HMLQS1H`J#A$|xn9za09 zkqwt;t=EU^vzLzHLMiVL`yKcJrt(>zU=ui=&M~~$!<4i*M?qiMU2h+O^}9gp#r{sW zIm!$2a9Gfv(!DR1&x+%u@l$tKds{-Xg1YTC2ztqDq-)eK4_w?v*vJE^IJWc{gL6CkW%geT3{C=Hr}0lR^7BmLOg) zGbzca^Qya>RlV(As{~gPB`MH<@^-p|%5{3f&c(`1_kDx_HAd$b;{+sx?0O&;t+NJR z2T)^_&~#HjuXZktbZHAJ8`g3%fs(a-=D( z*NB<`#Q~g@Vl{JF0{&P&$GqYF8aFpv96!xw41eu~kOYHEgb5}z6%gm+{zI@Y3?hCx zA3>hdZc@n8WK4J9dP`V{W9-vG{h&WDU&D5D2p#SG0sJTm$r+dWNH0g+1JM&PP5BiR zSWC^*+EY?yzvb-=SIBh0c+#jR5x)hXwsG=e;`Ju3uoJlVdfn24m%C8*31tU!wDbPO zQTh5D)YAFI(VNpErH?+Gz;-Q5pIZV5S@l1jpPV+zKl;sO!Syk4-1hdn1UT0)5H4)_ zzFh3uivJJ-Cld(0`2c}LuV4nnI7})bd5%(cD?-l=ffL%E-D7tk?u#NabY@lj;TfDd z-sm9RaNMMhg0Gy+aHqSgS_h)4M}-omjdxPc^puSs<6UvGC0qR7_jY^mDoZNba0_7Oo_syrCQF2=*pFcKU* zVgdjrPA%DB&}*dT2>7tLQ;g%?azXUv@)O~rl4#1Gt{{;i^|$>%=wlP78xY%RRa?HO z&;)~81FHe;j820soW2HHll~8;6G15Nf_9FnUBnUXE})dL2!m>Iy4W*xX+z&At?o?r z^bM7WV>Qb{V%Z2`*ji=WtpU7F@`C!My3%$$f*z_7RkU*B_gHYrzl7s?D6CmxsjagQi96wBiP1AOiknWqTZyG9lkZ z)+Hr`A&#@j3tX}w9dH~Ouij9S_vax-ymkJYfb*(8LP3gtDp%0=A+U3Urm-=tC?T=8wv>;Xu zgIP>dUTD|H&W(7S^MwFx1OkSExzdXQMD>{3jXzd!gQF@I!&$9clmsmSx1xFkf5Znn zOz8j{h)+Cg*e%qvJgC}n%Nd{2HT&J2!!25m-QG)RJ$yvGGcZ&WPP{)kHrX?PX+Mm| zD}Loe|0)jD3!bJd!C#?XIo2q(bfpIhOfw-pu9To`qMlD+;sX*0)<6$iWCcKUd=+Bl zY82dzN&!He_EJ(u1~iT<$^F>_B6WV6;q)*@WtpZnG;MZbtROQi_=XwYR14_N#|eCb zE1KV{ZJ}IHFxHdEL4HUv1wXV5K55joLB0LMy#v+T+|cxOed~u&Sy62iTc76T9FHdF zBN8T!qqX7W8)SQ+9IBOU2ZQWn6@A1*30|ZLZsTcyu8HcN;;REpv1{^pw*dr8XUYB^ zy+?MCZdIx-Bsk^mT_{O@&+XA3%D51x}t7!%# z^ktA?RdDAC=Yr2#oe633S04~CsVsfPkC=%F#o&KyvSh1wgrM*P(ft?qMg8g400!Oh zH}{ev8%d&=F`fsTK_qUM6<}0Bp>Pk!4>)xH7Cfvq2~`6xZ=sV=2+a<%jb;vc4!BI# z4DIc=@jV{PV;)Z|RdQH-vQ+jYSK7}=)JSn?hd$8Yfsi5^P4Y~#3g0j#uWLO z@=M@-<(R{qX58Iy@8A$%fIX< z!F-WUmXW(wOZ?J2{ML&vOrb6@q|SY8Eb8o89PmWyOU93+1qB&u!;N?9=jjc&_Sg`h z8Kzb8ms2$!2_qL$6;3GZCb}bT=A#2O#78ty3lnr}matq>gR!|A@K)F zpT?u!QYVDLAP)ku(1(QhaYq_$a92}BZ#mn{ymIF#AkM=XZH&)WN9RYY^9g6$cf!}5 z_DmMjy&I1AdQf3=lk9X;K%ihU-H&4786&7EIR=UbIAX(A%1Jb*N;>;{`Qq>;(Oct# zHKho*bzuqwK6w{$-~?8ayw6Q53#6zFuV^@Nunr$OabeigFIMtqmJx<$_|)A>kFM`0b zo(7#hWR^N60u~4KFii%?4jWQBlgl}L3cvAU+}nq>!xP3prB570G(&gViOnzOuo4WE zCmtmQ5@K$k1eB0Q-t10+d98x-e##iOIfy}W*e&_PdugD^D6xVG0d@eEQ#bZ-3cAe_ zx3`7c8Ni&l8r2pNjdW4S*0mT@Mt*MAqQA`m@4Xy-=mg##o;ljWJ?|Yt+6Ph4kf7Uz zCtev@Nu;vMk*=1VYGh$PBx8i}A>MNZ_-bd%gJ`cX*eze+EjS%vdiD5AwB1ePZRb!i$V0m;f-1$b zsP1qu3kK{yk1eCX^=_+H-r$K;)Wv*_VI0rQhBCFO=d5u!JDb9mLvHA8C4lJ~X>VtD zi-;d3*xT-JUTk}$Z|88^bpknQ_v-g{_O>YDU<(BWfAm%j0uz1qmX}~Q6`ve8PNJ)~moK2LY<*=%%D!n8 zanUdnsFd0tv81*r8O<@^uA0JcWaM+0BD^%=xO*_*<2nmo!UVIc0C5KPy#$mV3fX|?uVy*dEd1c}1@ znT8&?ninv!_OD!^Y5sRN5O7w(HJEjLQ5+g4&7|k6s%K%{1FXE^t-HX)_79r}Wx^6r#)ZV0ju|Pl_bcCG6ujbI+-%twzTd@ibPJwVwj| z#Vi`tKzCH(`6WCY7_;T!?Q!vN)z^H_78FA{7~DXRfgvgr&t+`{Fx+-&B*JJ!Y$FF zISt${vMZXh-*$Tqm{14dS42NXxTvb64q za6a1u5pupkShP5j%^r78iW4BwGz3&fUgx^w4R0I^s?jhn;&;q6wy2B(dUWFb*Tf?x zl(zZ->+@8^-?+Ant}w>b-1oP24Yn?QXxo%!5RMwHq`IwrqJ3gE?lUBdTlg1ik4nEg zaPn#K$T$N21L|przxie#nXSy$<6E z@&R7j26+~aqem2EW@tBTSj?~xAu$FP2y8SD(Ya67w}1_rQ)1)I5H zZOS`5FW4v=PwHkGvempn^P$HWH3VligR+HP#pYV55V?DzsdD6R~b;rkh?A}{}vNv~;5gH#0h z7I3iGVt)^Jy$mUQ?oO$8koRt&fNt$&^IL$r57p(tynMi!2I(+49!vxu9odhtbDs2L-59OswTA4u z`M5nRUzbp8V?LoEJ>!R=`wlzh*ME0{4Sa*k$TS=uO`sC9F9Uu+4y(1(&CkL_`)oY{ zAyctuQhxv}!`@89dbrrgxAC8Xf6CAt1WZVgW)l54Ux23(S;u^QK|qC08wxBZw4|%` zLa;2xVJ!HnX8RUa_}y97Z$86r#Md{rkcyL$lP zU{>FTWkblao1MYY;*;B$hNVOdK5*AGnRH@56f}dA6^PI@=Hu=g^DOROQ!m2paTj z#fyk6aQVzykcweSV%yv0PnI!Xf}cR;*4JO_YpxjEw)+jYk5!{A!oMJvx6JBkFfAL6 zdV;n6r|LX+FVo)ct5*dr;xyWF2n7!3*R`at_Myk4>eOAX@UzzoF}4)<3x3@ma?8Si zQRafi_>IIb>*ZKy@NV+FxKC9|=F>2)RDtSaMeUAHS!$wHEjBCBLGw$MF<>Cu-z-YQ zB3ft<3CNgTbuL5?Y@rF70}tYpjDzMS+3XQddq3Z~nmJWNCKZm&s+&0#L^2D8gTg|_ zkB54FxtRy4DCAmHbyMKuLNv?pt{R!_sgdEMY~*?8jXdkSk;SfMGlkF~>QNc_5TfWZ zOkvC7_8_+994K3G`m-_d`qLPiD^&?C0r`PDXw-tqP`+AVg28poXw(wcD1HoOhAQJ4 z03UP0=d&hR;wGhA3Vfj=zyvLjyBH%%zoTpC$y{$IYJGqAFwn+a16|brcqIq zv|%K_QXQt$O-;wqe6l|1AeF-OqjeKaDVx1At_&$EwI!7Ra+L9DJYsY^f{MiYmbTTj zXlz-v#$GD_hNdZ^8F6(eD4dUrr2xnBaSmxk*Cp9I*oUEpRU;>QN6qQ#iPQ@$04a)t zZT#c7hI=RcdV{H~XNWd6*u~Prk)c`9_|VQ?5w?1Fv$lv`^sjcwcGBI-+l1aqx;tG} zDKBgmCmBy!_e^2)uoqhMsTkw!twn~{L4wQS0QI%_5n3m2v3Nxo#%&rXMriC_13EgV zzBOs7LOd^x(RL+OwasBHR?0E%X*}h@^6fViFZN?J|1|TTKqo8z2~KVNwPJ&3^uVj16tKIISZ!M~)&hl3TN*%x@Ga39 zyA0_|kP{NXfhjXSY-}nm0FA|9E^ken7TC1z?2WI$XhA7~4QYSZF4+9C&}TDqd4)*;@HV9_QW62pbSqBYcgTSdWm)HDbS6*3oj9r675DK$2FKFxkO5P4<=U zYpEP_6TAiQiHLp^c)BZh6Mqu7$!9Y_Mq~b&R=T`Z*!He2V=~HFWLP9`!WeXdcY)x%Gnkg}7 zy6jUs;daYLP0KTAF+mfs8WEZ}0Rc?b+s!lBHJo@5g@i4bS$1NTogL`UQ-4-9-NIQB z3=-%~)1K+$WQ{-;H@91`77%ydeuxfAA}jR@lM*Q?N;n#)To}9}z%d*?w8OKk#ME^( ztYPg0DnmY3y#?j&?1K|bjjJjwe{lbIWy0yv*4Oq(wJjoasx6DONT7AD?k-($TVJg3 z3Kf8RTNs&LMw(5Z;2us1D(8pg`N`GkS^18T*xBh$50^{&Xaf-1^T=A=)*v|J)S!$O zvh-l~EEY7?kV$e%8e<^Cht2`_4sg@5I;2ku$0!?Cvf)`TB6PDfZ}%(-z@0zj_03j7 z9xiDlBHpEC@5nQxU`l!%Fc=h2eZ-2Er(=e|Y1!#>jO2l!?S-#wP-0VCLy%WldkYfI z8fTxo7fKqcQ)xnG-CMQ41EaR|fzXhhqbzp`+O+%g9h{P^qH~q+jj7C=6|?6N1@nAh zJ&mq`V2Sr^%&96btCSKijCD1Cy_D}04ycFNx3TH6ba6}=PHGIEl(k>OuV7NS1V1$o zFA7lI7e=RM)ydl*Q;m_TlH|>j&ZMVu5ZQS#Vy0$E$t|+FijtC-L+>@1ya{YpsyWCi zx$q*(F@7`EHr_I&?cAjY&a+PyI5X8W{wAgU%j^Tu(WwHW9D)H!Y04N<%0IuDOY5BS zNiJlHxm4i7o|IvHdrH#_0v78zPR`ex4QKsJT#`Nx@}-mm))eG2{Y(+#zY{0z^tO2s zz)K@PBNL#hrLJcU00=sxbbyuUY0r-FgDgpt%28$~ZIV@wq>R;$_ib#oMZu_AgMd*^ zlYX&Eo8*h-H>j7C1I$1Ez{dU%8!BmDdNwlE{!&UZg^l z-@YW2sd*ZPKZX{`aFj}*xPGL_K1PETezjmpai@59#|mkh!T2D%(bOi8AgpOgro%Kk zHqyN2Y^;zj!*80$D^?4HT%i4I{1F7{)Y>S@=n@QF2R1d9!9&Vyk!k86Yb8}oB#i2W zrNVU*!kK$iDGr__c3dO#y^V9qu4uK?qB@kTQa6vm$C9AX`ocP=#`AuzNH`npw=gD3MrTt zA)|_s08$FdI7Ep{Uj$j&RW(SMoN0pbOdhW_0WS?BWzba2*R>3;4${0~kKO;_F!0?^{zdpNx z!_3LAy*s)%KQ8V^lchz^qgA}#D&myrivcef1YSfuW=Zrwv>`~hYz|;{ia^s>Akg#; z9Z_gwQzN*SC>h+USJ(YZSa*N|1zKPT?PEm!8q2Rnt^uR*a`lXR5#%k~kT0aYlp?=e zdTe8JaT{YtVG|1Ge~usuaD-J@8+m_mO0K>`3vyG<9BGgFl*O^yC~o0sP=D`xZ{D82 zJ}!4Z+bM3bzIpmWu6iG&!0KC!>*zT5IK3ai9T4&67=7=;9(%2>JhClfywqX&7K?#Z zCmFybMHP%?a?LSfkc($@y-3&Vq4{yFZS zU4(U3tVFmGj2B~(R=^1Z+xO`sR^pMEgfeMzZ;kid%Oa` z3WC}_>G1Sdan@DaQX#{z*m=#&j^4$4)8PJ{uVA7h*XAQ(J41YVVp zh`)*vtA``-XcyPZ2tTd|kkpDlB3DjA5^dPxY2~wp;E6=jKP;UB+`hCeDUgT=orm<6+?j z-b0mTC-;Yp&W$}QZlQZjdt^r)XOwrXJ`s{{z%S_sA+UQ)S<`mWo;t!_3czi^z!{va zSRF3aP4zV%Pb@yiA3hd?AhwgelM8wnImn>0ZXc~{WAj3^M~;dyCCpott!vOYz2y)F zJ*$yTwMOd(VTfZ-Tlc+N)T>Ht%)Q85n z09r|Wp{Br!z{4QKCgVpg08)7aMAr2;C4n7zjg2gf>|1hpsK}A)Oe`390NSkyj7)^! zCZ{lTL=7Aoc!569(F7p_qH`pazPW=TywsqpSluQ}x1(diD6!RGhVzOku{myy#SEN( z+AWS*DD;gNEN$F&i?Eux=`;6!&yEnbvQqHr2y`k9hY{n*w;IVNHT5%umWb}wb z#3z>uhy`u~X3?QFx)bMvlgBfMcnU)+?3<^l1~lyGH7o{4U$5$~)!t~_zmAAp%qi#Y zCM|4!7WAP5#PtOKWffU_RqT{!uS-Vs=JIj4E+QetBwk zfG9_i43wx%d;mxdD+ZU*?NNgpYmhnII0T!aWgTgW8<bM|7P7(Co6 zqm(i;iwk1q?$!@>*9T@hgkZYBFF2DpnbOG&_?9_g3Z6U^f2c8roh3xsoyqDxLR}s3 zY=wRlxWQih3}u9)?_-X;JBT9VI43{J(+Y=<3(EK;Ms4}fIPbyw349Ve!eR?1Gyudq zLxeeroQ&FwLBcN?&*qemj0xYp#;`BEEEi~O zySWmXq09ag+A_?=sag~jeg&UV!x@b3gA+T&dqmDgM7bjBW2rcwV#){_02(?IDg3{m zUul+t{RS6NhbmuH8cE@WYF^A6JWP0%Ccry-GNBbs!U)h@QBV*ZFDdtI<{FxWeJBO3 z#8|O-#*OcPR>OySjhOhY>p{ySs>V#KIo!A*T%W2Z#?eOrJQ@SR#*ty{!bB9} zUrd8D5Qtc#RSe+)GEf(i;lObNNnBu*6TL<_5mFq&I!x%|xdoRIP%p8u8+uzI1h9CV zFjcslT)U6hC3SbnY{)l+qz^|1_bnsRjo1Y6U~vJc$xmGusF4L2nnB; zj}lrJW8NmBe!M9)EpfhCqH>oabtCQt>@S`aJtic4jzu~%<1SPqlH-Am{8!EUOO0>9 zmd=!!@UsVgD&7rY(>*Av?a+7xCVr~hp+GpWI$Uk+!)Rvi2R3zBwB36G#U+N)HxN@N zbw@L=5XNo;?nSw}1PeoRJ};amlN+&VvcqKva+rx>uJO z$3o z#TzQ18z^qb*OexkI!U+S7qOp$x(!IvsRlk&$has^*yGGJHi;y#&bB+uR+}Op$v@~- zQw}gKt){sEJIn3PsF}!q;`-$Y*cc0;-esfxqw*p!f*7LX2OpHch?X}HK%ldn{l&u4 zqKl|dv2RViB`#N|!pVpWUWURjVWK9r(XAZW7nw3$y?K4aN;tNVsmL>dscATrIuN*Q zSK}2>C^#Z}sRodAfg{7%=HiJMgKRONncjo9P+C4t;KPSSb!$KN6{l}ph^>3ZOLfaiq?H{yKA>KA+} z!n7LkL!S8kg5W!tWPC1^#!)(C^fEyosN9z*U^X^RBr+U}07MKdVWrs$U>h8d-@xxU zAV}X??ZRlNZHO3uxV{+^-&5GYZm^PkM$iIiNw&nNz~SBoMgSmj`ZPqiSe`q7_u#bw zB4nEl-VH4|yfgLkY2e>m69OBGRZ%KLvw#j;SUdg#Xx-5wz+BiAj^X01~<7Uu{&b{zh zO0~+TorcPFR}2}YeLp76ru_e2kd8J)3C0vn4? zFK zCCjuATu-8GNn8O8Z}slQrHOt7n(7~db7xOxf?X&v!=*$eDi7UAvHN&qHE=09!kCTi zNV^c;)zEh8l*ve5$K2dE!a51AGbVzF4p*|)P zX^aaw#N)qYBmwkc_+0@tK;~|sLndzUI>LI6YDYKAb)&u;Y1MqRi5A!Vv zu9IX){-_0F8*;9Z`m$a2PbP0+WAugjU65FUco1YQjRDOv;cjv{UmVGrfsF`~b@`zN zgwz|@gy0W^X5%BHU?e2Q6-dZ%{pX)bUI4f> zV1c^8qCnCIa3?p~Khrg-`~36%N7lscYfvmnq(JtPcXE2!6_E-YdJwy&_h zjNpwG|g;R~g?K00Un(P@GNr6F$~)lce$dj%Dz9<$JyJZnlh-rIW{~Z=w6FA(>@YeEo@?xadgm8;1~zO zP=d5~>*G~n-ghU#bem1@LM8xYL-mr>u1S-oHP_r)LZxsg5rwh|sWn~fWh_i&BKbK8 zL_B?i8Ix=UX#(8%AXyK-=+U_PZR8tiV%!HF+XiDLo5;l`Q3is-Ra{gENFsej zb|fr7l33%mh)TB)=b)TDQl!u%?=f{=Txf^iKt3Y1Vr^&Kv zYecE@sTe$r5$)eT;~FIBOG5n?w8---3WH(wjH|UT6ozJUVF#sGv~2R`4M$SCVlkqmU*9t}x%?W&KkZrU8nxBG6<1T`zQtO?{{0KyjTx@nZ9mXbfS954aev^F* zFeVBD!Z0>a2RD`c=Z9^T4aMZ1|FZ=`sN$3+x9n{x(-XB=qR zxd2{^_!hEux9MnIkKuCUaDa?W@M2H1vPrTH>{`r)OKT!tt42VjqI%Rl>vB~IA>g@j zdae+4OmG1%n~Ot?05;yN0}Pjn5Y#1Ga%tF5M3I!T**l)GeYQe0;C?!OVmLx<#2x4a z2y0yH9H>r1P|+ktQ=)O7#;Q@d6gWO#Bp@pWaXgqE4G|5rmS!<7zd@kG0S+j%SiH=LP?nJM zobgd=f2zlcLw<_07y|NfO3c!dWntQpwE~GRl_C%%tmuyz{_z9>FP{U5g070@IpG<| z#)-ZAnnG@S?n`G$yK9lS;Tfd6o4`dD08oZOk^8{lUt5ep5vWdxVn8>PFKN#tU2+ar zO9f@Xt<3X;!_yX86e*b6tRM;+4|K}YNMh`B3K&3rh``RSSoJ0Pi6Ygw=+56moP;aG z*N@Wx=7T0FPD5m8*k^(vcLpFhG&>+;-G~$EQDjPGtR6(DI^Y!oAyGu3{dy`TrHV{i z&if2kIP~f!Ob+%e|C~djrB&5x*fU&pnU=460+Mxyu zY_NH~vtk4z%GWb_X{5=yInl;Wk3qxRUr-NbObTJS(& z0L)P#3^9ctzCjFsTc~r$^I!<+9t`KC2HkK9dI?EW`hk=SD3kp;rNSKysK6x*OMC1a z%QhNI28H(}^msQjfr)UNk&lH(q+W%RY}1F2#WrI zMrn?W_K1? zeI(W{rLDl&Fahi^tG|3tFe>_%E- zoFakIBoK)6z=h|u$rehf;h`p{V4TEs>d=@<^VKECwmc8+#{8Yt`19H1m;BaZ9E zfdb11N;HF~B&il*CO*mVk}lFrXBY3RV7(v4%{6Ni$$6Ps7~&OCfEvgS=!_6Nl%j80 z8e;k0t*19m1OvC*Buvo4Nr1uweI_10wCc2hg~7AAyz4Z1fluKRCwr+7)=i1p;@G6vRS!&1E%aJYx#oY`H zWx%)bFw^#qV^Uy1DpxsFhfGOr!V2PqeO2_|lyFB~+}lQva;TRy0IEN6Ix?dRhtNel z1TEnX;HDo@YI>Pam%|SQxw!HMQ%rP%I1#c#!c;&Do2jn_#$PY6N`dkYOHUHin7g24 zi9`YP)UwpI$uD8$9fpQ0i^HPC5L$9M2?&WaSv)=102ToEJ;lTZ7#~27$b1c&K^hGb zPuMh0A+9>r8{-(8@trJO%~!#?Nh{(4D-A`a?%9QI$Jx%iuIwPRMT_xj2FaW>!;!3& z$6_>+ELJ%NQQMYG81YiKWYux3c8LDM&WMb4STw_^z<++=gU-;< zd8h?+DobjeLZi8oNDoMw;@xE>(~u;**@?$kqIVt;Y2FL%S|SK@RE@)qNX{-M#@GYG z)2xU>TNsbDu*maZ#`0Jx7HFVU*aQiS8<>j(x+21NlwI-}Yl0eT2SUx9FuLib&^YSO zZ6QZfne;~1j4Xc=#Ww}JT8Ai2!RVMlqQyvE5D3_?jUB~HT$7tQUX;*|ipSL59Bra- zT}PuRX`y(#YFq(#art;^l9Z2aVTG}#5HpL$#kRvlSKA)7T|utHb>n)Aw56qqM1X7~ zlo%Tq?5Pd)tY?6EK16I+tWdFlE)r7cT(jcRn_5B=2ae5oc|5}uD1!OuVQS;!%#8u9 zCHa`pYFUyOqCFV(Q2id*_lByAAx)l$yK)zhT}}itVLVJ{$lQ%|G1+0q~(2GwhWqrNTkL zfTAe~Xg#O5xCq4bx#x#?!2pnS#DH8lBcn`4MIosC2Vj6DvusS0)E!6+bF)Byk#|6E z2m-)0!OG_NpBI!iA_B7ZfRLfuu#KT?238b-+0?=Y@t>LT5-Z5~g-a7|H*-I8t+GCSWp8zWCwp-znwVM@hL%3=&v4KhP$8G26xR(K2!zff#ijh;? zX%XtIvb^K7urSskg3Js>z+_N?$~`kcx8vi=Y<}s+SF9o$5di`q<3U4Q4HuVyO%qP$ z{lv9*i)Hc`4Dy6;o)y*sI$|gS+C}6 z2)v=NhE+pzQouR&6qffo11zGA2OP7KlnHPN;SGHN{Eb>J3N{W0C(7n&M`13FeocNI zZTAAtZ1&acAuRn6x;kp&kR>?5ZgHI?CN+4$t^}#qY6%3XgBXv8Xp`bK6wQ?2_Rp>% zfq#!!zizTD=^0pR%8(E@7QIL@bH4)GUak3BsZrpCcJ4qsx1K^KDU?qEKIwi8VYzC$ zS6-WqWuIOeXch8aBl)8wmER2Smo3V|E|K7&K^D#@$u_723iOVFqFwJQAdHLsz?2?a zt*Sy0&*8SC9dI>k*Mdxf&*ugV9g&}CPO$~68ZsiD7rE{bdo)9>2fP6Z(tE`NIx zGxM0hb(|~=h$KfQT*|ol_lp67Nf3w71mEnmWXGqgJ3s&@>X?EQ36&6u97iRZxJ~E4 z=#|lzN$G&X=F!)hbx9&|ZP3_w@+u8q2V%xJdyvFjKeXMO4i_BY&Vch6&s--*?mV5-ObJ zCd1ap`5fNEO#5VwSFMIPSz-xJ1fzs6UN8s^&)e3APfSW#c5wu$mK!F20dgL?UB4ML z2@9J-X-`nZ+R1s~mm^wj?0nyL~kXzOxZ!j>^9 z1G(}>!x{B2y<<49>`zLK$t~95dvY zwqOnpTtL5yO%G{4a=Nq)V2qsNupp&?{bSHRMPZ(q(@Lf(HM`wb>8^9P$i*5D=7oLJ zEI~~`H$-|{_Z3uYO)`wg06qYK2wE>Ky+*BfYE#n7dzV8xe30|(1#hJ!Dz3qWeLE9Db8Zypc`!+V$+Ul%$zbChs-RoCAzEV?T2?V;TY4fJjI?v7>An;T2{Zg z5^6IWgyAAs^I<+(c&rBJMgpG?M1a`PU3^EuVV~F$qctyrE1ti;qz>d+-PKLxBnGCt zT%WE!EyE3$O+aXl_%f2q+<owhkoiNi}Rx{rCWmrW9U7@@oR@Tek9} zi)*nT)M>q=cpLa0`*>p8gyw})AWTEsH85Dd!MH>P>7b(cXstmM$OOCt3Xy`20!|@G zJ3~*|lsFrrV>v3uTNxq>8ZvZ%k!DZs6;5ApNDwl@NO`nzQv;xvqagW~lcZs*ua^}) zFAK%+FjO7YcJzfU&v1Ngrwse>GuO>yZD&ijmam8>Lr4d5lOn^;EV8GUuh8 zIo;67_(?_b#XU%FY?N7EvzsJ^<95Hh0Kk%Y>zkcGRM2u(Tq=GNR1sW!?E=lGA#%?_ z()Nfoj92wwKq3e^G!xOeUfbO%0ucjn7T&Z-WauzlwoahyilCAZTC&CbQ%<6_9kV0x zD4HDttGYV2mHQkMG78DnF5pH@F2gBuP1AMBl?fu4$P(BMBT=X;&v0?b%f0`AxaV)# zjKIbvi@sw~WB?GP?A4AMa5C^=%|kC0#r51ZSvt0MGANh>M(~gfluV(AoVeCOh-xb7 z$c&=RSBQ)E0a4w-aL|%0Ngk!^os8jSVz5k`KD#Qw&W3xKB19AI&Fgb6l$sPy zvDd;eC7`!U3t||a16;#83l)VjO&I1B16BbxQSl4}sgsf0W|oT+1nV2=kF_vT0vVoZ z9#kIl2N3jpr{I;_w|%5nR{sNrVz>R4xIFHA%X zDY!2^j}aG(#$1NgbbkbNh`Y&UqHbwRY+**WI2KOG;R#sm9tuoEfngkrX+`JmQQ!*R zU?ij=XN%`h1B%~61PF3b$OQQ!M%2dljOuDfmGAEPBKVCN$3Nd@I1MNSwD<_Kr;?Isoc~k{RIJrXTZzh zN}Pyw4R$WsGy(QW0Xja^SqMfSyar7K$K!yGsT~S>cOf)g46J5GHgvB_3_tA>ZlnBD z1QV})*R3XwA(?3s1Ngy^X&Aa}#24t2r3dKOPzd`Z0PJ~S$&>-1yf$$T!Dqre%})2U z1a!ny;QOS}a-A@|mN2pWI5K?F`E9zcr6Lm)%2v^Eo}muo9$X{_=-`&dgOINF* z3v)Q6pe6AI=kNmN6GTMy9&&j=$WGAxc&hBy#PG3ibed5CbHp;-nhqu~$M zD56@*2;LpN{Qxl@L*#H>A)26dl95r_=ekn~wUm2g;Y{%fDA;s%;FAe@gyG`~dE6Qz zM=k9T;1Bm6j{(?7NKS#0b^h3}E0+>AUKiKVW#hblPwRPslbW>nQ(8kXbAdX*O)-VL zq#Y)y8}{3ZB8@|ex*!2Jng+*6LKl^bT9O=^vvKN*ol*4U2g)5oqn8#&A=U$uMi}&r z;l4>IaD4zYO-;ilY#0z|ChVekpf9~qKw$Vh=N-7)K!Q~?IWnog;R-1w)!`KHK|RpW z57K3@O)_#12ZnQm#13j1k_`}kIp3C~X?W>aSH>1g=pi@&vZ-T9AFcHnVzr=;$gfH!ZO-$(vE@!r4kN&rv!URDEeb7?hLDB`?P#Jb;mrq`0~DVw zwu8MRM4veJ=0}aXy6jl@(|pNrn=X;#{`x5Ug`5?_BLK&3=*^xMBBy3 z{vMyxMr7e%AZ4Y)F!Q{#}qOK{?hr~sk_G_5qp=QLnD zF^MarSdZ}<2R7izU|<}M)-5C11a^cQDCmj4Jkq}!u9Wi`2CBNxrin+)M~I{@Er?DZ z7KwOeqqu(mgYtS_o?gct$u7Sfthg48lqU0Z9;S?}GW5}=t8!={7XVoY?88lEj44r# z}Vx$8&n8`10 zQRvHQo96k3CWZIOW#ywV{K&y;-BU=lV9y71*e%nBe+WN`WJ>0WgKVPzsE?C)OJe~{tMg(^oAUMOtg>f~?|K~038kee8qas8iZQ$r~# zVokY9&iDD1M6j2VRX}uhy?Kr0^|6DUIpsz(99txh)_8;uWCn^UlyTw>=oq0Ngv@BME?CJa85gh` zB|{r(SWLN8LZ+bQDFS_64C;phu(XWoYT3LGm&3hXlhzlyflw?Eet&Wn0*q6huii=L z`i+qmo@kwRd7K8L4N&Z^Ft0+h4SP{7*^rM>vW}5O{7#}-hbiOVb@Tyhh;kJ}W1@8c zDGh#&F_wrI>x5epB2q5S%+)N5m#j$ASb44+Ipt2trDH34jz`tyOutks6=N zDke(^gi}Ev0V6SFk<7t^UDo}54!}<5hS&!Z zdPy3xAFMq{*ZXFb zDE<<>$G|f;cNkd+i25ZTFR+b*Vi|jgF6*LiI`6cBDP}E~nc8ZeIP#S^isUbS98o0a zM&x4xfRJZ$ev{_R>;gVqnN}+!yG#THx(o8T>H&Bttzz`&H24HuFxr#zu*UiD1T1)l z0TL*P0ggFpy99vj&Rn?G=S$OoAsS$#f_@UvnLxyQ01mUb;=1Ugj|DRQ1e>(lnjD*9 zP_E0QHBnSOsU7MaET%}5w$WfIg!hCj3JP7ha19we4zdN?4?db4l&lsU1cN{m9EV-P zkAv|<25`ogI^k+6-x=sRdygO-8?tn_20p^HCEm;hm|>C7Oj_|Bliv^*$75nwIC2#5 zz%E8fc|zN?fTF+x_rjemA#ylS$8EYb*D%2%X3xkzp(Tvo+<~wOG)V>%yB>Ma1rojZ z#`$3^fMn!Qn8Qh4F%@huVnIHGDE}5 zEbIixUW{7c(M$~ESAftmn;Co+g(ci_KgrTLNZ|lzx%AL@0zkQeV7LWDwJns1bvI*1 ztdf-T@;Q#{41Fp)#FA-z7_8J|HKQpKd>YUj@OzZ&gu_cuJBM;~7cN&>F4%hFnva3t zCU0@wo{zACd@x*#&a=T5*n!#lmWWk>DM~>@r;s;@CYXDKoKzFHlhN9XfTkfDFJyTT zXom722y>Vmvh)L)oB-ExaOJ3IXpSm>QRfv~%XEh#i!TFNPiLFyGNy z2UUf1iHll133hqzbe~4T!O|K_+r^cYeOlZXcIZL_@(w|ypb#2Vxq(=bzmZvkT`L?V ziO177`+bpkN%=(C!g#i}Q|(M7^8gQ87mwOar-T^bTU1{N?==`e@(rZ|E$d<=l>`N5 z`(iOQs4%x-XECyMUAYF4^i;U8uv*mBVXa&kC!j_a*M=C2!!rowk+Dj~YDCy4m4T*p z^?`Ah^PY&V^&0x!0Es}+Y{7Wf;^WoDTihoQ7#~CNjL=P52Tcfrfr7)B{vf(Q%xn?M zctKplWV;G#YIQGEE{Z*^pSD zhL3MUAbDSf*InW;eMP?5ltIf1L73Pa3C*@x8uf*LfW5itAbXt`{EXn zO0YQ`OB^w`GE?jSeMr=rg=D)Qk zutYmI{BAJ>U8hN7;iIB^xJrB}sSz&i*&iJ6l2?)0AgUYPkbdJ)ODWp*T=GP=r+`!N zVam4!l!btuo`o*bWL5RqNs9~Xn&pvsPoeJY7U%2}+QQlG%h>@*eE+}Vq8Q+~*vGTYet!1d>P??3Ot& z*s~xDe}SjWife zQigdUq~L^ILyoSEl)fyimhBRR4eEx6D&4|h&0Pwir8jCG;uj7ofdVl;d0<_Feq?~; zmsECAAcM*w=~mTXlt@OsKY@j!H}#2c(&3vsm|XX-XNEr*pggJ6(+=nXlL%UK8o zk2oz35`w_`8cMJCv*H#O=i+zhKF2AC___EtiAu~xpw3JiY&gQn!rY(l9_}@~ZPIC$ zrjZy8HjoT-0tE>KRQw~1kwg`;p)MUpkWbB9To5zeUCG05d`#V z3`=MCmhj<7%3_j^G(es;sz8!sqTBMJfNe@|6b#Em@Bzcnmy2jQgpi%Wo>b2Yk)_Pf zMQDIfb~7Kr(1N;E`L`RvO=&#PvM?^0A`obZ4ry`ffq@i9mTFx`L%N_rAVW95DKC@& ziN}IUF!W3y6r91%M(l{s+Mzyjd7|p4Z8Qj)c4NntckT3$qXyGe=g^Olx(V-!)1A-xh^lNr23A1qZ5zXvh zOT!W892k8j|Q2v$!)^{-a5<#_DzsJg%k>(<4tb8t~J!Hp82VsT76rsV>*v(>UNor32;u*!_U5<0m}tj;S< z_6#EV(8xoOu|O{f8$omq?U>t4i-8xI$x$_|B@UGz){Or;!BIW$8_IH66Ff?Q7~neB zJWDDqpB>8G=s_*lZAWd~QkviqFmRPj#Dv;18)Uui37xKHX?3^j}kg_{HC2;qO8 zQ5kG%W6^*!N_N}QctZCF3Iuo#m`1{q;I@I8~fl{UL3KKvl z83{@##hVKtcXigH%A9-*b{x~UMRH05ALndwxS8y#=2T!~0~OeQf?0b~3vQ%^xLkpr zV)qEnsDrQ|M@iy@W-`p3MPxI%G)L^0>oobs(t`n#IOZG zlaBdqKGFq)OsHx7mFUD8JR{`GcS;R202yu@8J^t`DdjERUeY%mX@sBlkGU)N5qdqcFUrqV9*_ zqO9hPM8`eAf#@GyY5`?%+k&oAEEk5QS95Sc^l~Sey$QsI{D7tpTn>=P1q_ai#!DYyzlU?2YMp&STWC+Fow7_re2UVT-<+H_*g;UuYKdOeTS>} znqk}G`eMMKVx=+?z^cCOi%2t_q16JLrQ#<9BnJ`9_{~v>WpfXgUY4&Hki*3iq#}=# zHSD8rZV&KYY&3ykC}Xt`kUXcU0uH`NAwvLQ0YIIY>{4TifFt?|gcC6cu4B_~r!^c){1CuZ@cjdC`nISm5b~z_TY~JwqmbkdV|AWJE+o)&RYg=Tno}AXLa{ z(;fogNy?Wy6CoinQ?Jj73Aypdi6Q;}`a09*IFBP+;}=axl+hy;rnV|IidP)+h+`fk&ivFPE77HlfH;*(Mc-`ETLjjbWf7L<7+tiLo<4Bm{ z2mAnjbkCSBLZO=C-CLiwKtah#e7Vh9TjTGl;Wc9A-GXdidjd zbyg=QTfrFm5sbC*IpkL~XNlHky%6urpillwj?xf!iNJ&67e-?^aL8X4ljOKoHJ>rU zsvW;MbM%&iHtmzK$LIHx5IqvBrL#{8x+0YoR;I3!E#ii{PnCfEfA%V-n# zAs~jX_G|tsHx^dN_IcgdR@(s!l$;8!!F7&&%Z7)W+BB@No8OFyXfZ=M7;&v>OZH3= zj?MNE{3bVbUMTn36UVLPTz9*X2+$geH58AelAMegAEHdt3aVF!>7|%_EIv9`Wmy64 zG+WvCUU#d4g=h`!V8Q~T3j=*??!voNlLLgbx3q>~cs!D-4Hu+eTu$?l(`BKWVMcQmQc5|1dxMjYUzcvRP@3ZnWG0Ec2zH5AYiTw!#p-qcU}cb1;iH~q72)L`C16;maUec0(( z;?D$kg-be84awJ<){SJieW4NLo7QH$Z5@$LaQgzo3Le7Lu9iBbA!4j_h5`@Vo;?P# z&g32m(l}|}*Q}-S&Cq}7j_7xuaKk|jholk%`i0ms%&(K%UZ-%FFIRu$#`Vo4W}*4E zPzjxV>4@EaYnzD-JC`uAVYKZQztuYKrPI4UlFx=ch_dK@bhV69@Ub%Y_PSH1odN?{ zj9~qUk4mF?@(7uX_eNXelf(w9zQS|4!*aUV{oT#C3q>@Q(bd*U2N^7oDc|VU)+;E` zk6kv|kH2uI5eSNLcwYE ziA?=f(sGE9TD|y@1cU2Z3y%;dTL}_NMfv)q;o#v;xI~gQ=?|txDQWjcQ?SSQ5Y$PH z6WhN$eFPdizJ@V&6i|Jn+mzcQ@LKCewR*9iB-mMwcVfFuPlLS%m_TL764*)wSv2T4{;cZ_c~^RxMmhn~0wGmw4s zjLs`q2Y4btlu9k-aAnHzHw;%>12uMi@&amYZej5n@UN;o zWR=+YD;b}$H91%IiR?+aAg67CL;m)u^eFwjGfyr+UbU0BEs9wQJPYrZG+f*|0>?Qr zkZP}o(89PdyUwgx=4_}KgNPtU)a0R~kNFO)U@L{3FRu%c%CTyp6RrSEU2Qcqkyyhty?CQhd zCk)0#M}7r)0yOP~`~>zLHFC$?+-)0>&E8XuL1fpP2t_?K>TT$+$&fG`cVy;Zqu{nT2MbeJe6A~fja!nV3; zn)6%;tZ(9?P&uHLI4udwq_Nbi&!{v#c(OrxZD}v%)#bxr-s)mYtp_I85;B5pED%AR z6(W>LoyH3mh-20>*e{+NtgMGPV(no(K6spaRN`Pv-Q_vcCsIBMTtA-E5^-h{39eD? z@`5*O>8`!>?DRxkG}dTbln)^ZqorSB} zh@#_a5s07kq5UMT?X()6N2#UO3hV#z zg&GUAjW%d1aJljyi2}`>yzrVfTufZpLa>yXXgoLk0A7Dwo^X^@qSw#~8vl+Cheg#YB#UnMd zTb(kIB*`s{_tRwBETLS4Tr7+4>zuz3w(Flkzs&;E(RPp8S1w5yaaf>YIY?C})An~M z&iOY=4jl)LC~WZ*k54cZK-0(LKTgg+ywxK8B-!f6-yc=U%tvuP%ekvQ!~UwaqZ&Fx zh+enn^SB(;*wtV5R~B>lR&R-l9Wge`fbgG}Yws4PH#Z{>S$9y1w@&?@V$=h4{NBS~ z58m~vtb&c6%v(jIk6zz@0aliks)2&?O8<0rf2c_l+Nse=5Z4se8I$DWayLX3-*?8W z!O_FEP;5?V5)ti9G2~31#F={TBU8FjjY4PzpDxa*6qrUpYzVb{$KsE;($wYMe>rb0 zq1D>V;=(=QuBfI0n}KRe_xT zm%gD7rAdd9R2fYAGa3JPcYZq3=j2zl`^C}`sh{8DXq+fZ(^E}x(matI_0@1(aMId; zqqWWCRZgRS-Ydp!Pf^3?<6gNsqwCqdD}Pa2b5Mq)J2@iuXE%D1b(bnZ8Q-ed^lOe| zBlJkcbk}iT_>N*1$awy#kI$7{(!(1+)U|>)^gJdJGW=4J8BEeq$LrJIZf?I{ou7R< zf9FDORTjR&Uep*%zekiOLTFFF*DfKfuwlMd473LB{B|(KKXduhaxhhxG=>swjA>w< z{i^2bGBsG^zM6gzu~s6w>MD0hO=b)5iO)hSlg_j8U36b*R#62Ds|l=nYwJ2@6Wu*T zkA^#H35#$Fo_W2$r%C;)rINS#58a~p;g`KPZ;xL6#}9g5{7hur-b-qNH+USHGv4P? z7vR={F90mX$iII0V6NC#sRe)3{*u$zUtLydKC8)+dYKi9#Yu6P?wlbGJaAK^@3~;G zYlUHUDFB7iUa%aEbf&aLMyZs?$^~F2)0P_n(Sl&)sMY4=YW!+P3gqG4Vr`wR#a0@l86pT z<^QJ9<4ejH+X0LKE2F}v=_Wn@ol=RaZRl~42d_m)v|$w>ScjywVW`0s?byH-F{mAs z5RnmIqXUi1%ROyU>B7NW^&CeH<8R%GK3U;*K z5nq^(TmQv(QyV9Dx!9@Umy3Ww1Id`d&>F+`OP8^1uZ(fB=vw(SzCZ2NNLF>e!;I>M zJ`~f=^7!et8PK4BS6H7%Wl0(~B7k8Bm{ipE1p*4mWxAkif9IT(kDwDu6yK-pl$#{R zWlc#0H@!MT^LTrGqJf8$Gs4{A00HCcOy7g#qD3o3GNLaIHu{D7(zfAcP5p&Br;%y` zuX&u6G@a8iZ>VBn@ za2SkVmCKo=)ZEjwJjm+Yc0|shz18w-$iRaP9xSKS$q21sfvC1q8+50)Y_@$5*(V6FzLBfHAL@J zOy@V7^Ox0IKx0c`EIoOg^CNC@JK>G@=0>;L3WGL|ell?fpY|DQE2zC2$aU`%N;jj0 zm&ACmV!aKkpr^?XQbmfI?Qh)uuRjVTg4;;Uv9C|JH@~2zkMDQS1sifAm2TmSrUqWc z@E`)!HC!O|z=PZb#m!0g8?L6-?vr{@2buDyeS2WPU>7?Np7S{{#*ST=avH7Dy;MRT zM>)`a{6K&Q)u%}9Sf^(?hErX?SwABEr({vbpTb41qrKz7+s&6Q?A;ziYq9@b8CmFAiOKet!M@ zG9H{t+lC|XbmtG$uKVSD|Mh340p_~#E*hIwWqH3bQC5ckr`ZKDf!5$QrpxLzRA|S_ z#Ujr|x2Ky`n|96jrPN?-*MrXa@}#6v%p^b7aFjKcnj~+mNktJ{;~E5dHQhie1s z60~PY0x#;S-akP5zFuLMvyHJ+EsEQj=YUH^%P&u$ndjlEO{v-}qxv4*!0d4G38$-> zqsXXh074FaW5$x4J5`b1*8bQ_PYNWQ?)-fz+{InlJNWqeEgrbu1Bvjb&UGhMe1h%= zf}-nSfWdqna0wHXwbe_ze8Y<~>{jNzzwAHgAHrtzi~hsne%UwilC}V~80e9do<)}0 z8NMV<1KX_%PUzT|b9hc{<2hRQ;9%SG-cy>js`X7$1V-J{YpI2K7YmW?Zk>UeEJ9|R zh~I-`YPyO%UBz3^B(!<;4T?8ogeQ;udXG9gKl@R;Fmv3{-eVA2w|{vN zY=DKW!}T2J+1!mA4633HpG@G7kd#B20_}E0#VjM$Kpd8qu>0rbD6nAY*|zK&-oJHz!`f(j9^8=NzE|5ZN#lk*R=s6?C0NhOBf?RtJ(hMz?cl zt`GJB_^RmUj%vUx&j(gZfDlO=i6f~MM9=CK?R=cfj<#ho4#{#kupJuPtHcIdNG{_Y zKc^nbX%nW&WRR1l44Aq7du@9L#NG9{+!&L}iwWC?PS+PS`2J+@gRuVPD|uh-il{QT zI;EkTodNlTJG(nkPB)+{pOwr{z!lfGltsiG%BS!l53ET>af~3yx|SM1PtX7NdfLE3 zepIe_04y>i9@yj~8-Nb_E1sLv(Jg_WNke#SF0C`asr^l7(y)5 zrH-tn!`ru-$(;{zU6X|3c*Xp3;1BDj8Xk8dQ<>H~kJA6#G@f@0ae;KMYol{X+$DQ3 z5Aw&9N@oSihxos!=H1KY4xj{5=cp)O+HkPz5j@gxJD$xW-+yK!bXYac`Uq&V zF+hzBW;`Z%gGue@sv!XQi2YqT`tubNdk=fNpG9L6Y%?anWtTu7Juym>EF$htVxS)DS{HGbZgerdj6BwT z2!gCNPtXvp2?u;TzIvL@kB;K|gHN|^Vf zXx1v(RIg)G;Ada8l5IHD3yv_AiQldxkHabHG>;$E=Zp#;v)Q(wu0QmtI?tM*_AzrgkoYiWg{mq(U*J5gyyG9AyLnay z(ehi`?u}VFjp}m!B#29`?8ZcjAs88|upF_)x0_U?%V*|bP;#mI)@L?ty3t8z@X`Is z@A2}*)Ap6GcC9fA_7fD3#nO9_P4wGQT|8M28WkJRNc=WnRndB*AjeUfsHjFu86SY1a>#{n@X;QRdyCcUJ7VnIdHWFaT|2n>VcK~)hdO$X|S9nYwUSmQvBaiPxR1>) z>~`nP0;Ro;nOF8tr;yh3+sDfbD=+7b6eDxNz49#jh76GvZPOkX(kV_bPWr$^B+-!p z2SoZD`IivcGg;8>t>CUAR7sawM zML2RN2%yZ=}j32P^jGFpIir@GTO04_bw zMy|Z*ksQ2{M_~hEvZjXC#b{!995_&GO&orErDE3u>sfYgX-JWp`~yrUN}qbYq4de$ zSv$)2F>b|=&|+GCGGf(+l0wNrO#S`8sb9-Oa2>2ZZm**Nt;7FxrAiHrdZ7ZM+mLmH>EOP z#)$_CV zH>Id_1jQRwL2-7apnIb7^kB@4Vmj9OA=UI<)6?VGCjZeEx@BEk~N+ zRo7L{SNyO8$o*xju7{ptF=knjaQbHjpo3_G@5L4_`@goHvalIBXph#P*pWH`9i*yO zuAg*CnhvDXK2R=-CVcqZLqf#%HP&Av$^KbbLA8>8f%smZs}(mdFidypmc#j;;%1Yf z!m~r`3r4hR9Rnkw#q$`GBZtX*Wq>e=Z`GMBfmcTQ9H}HJ4P1J{EL@gisE8J8W331K zULzyETAj`6m7A(pLbYw4t8>5_^al2_MK&a$bCDlGNaqg)J9Oux-e;8cA97gGf3)r%{%e~uPXc&% zefRi>l5TvtJy_g40Qg64Hr8!u_$o#js*P#9!Q`&4n_u7VG4_%F-IY_VM-_VpPX-?1 zvxLIVu`3k4{D$C+^hB+-ig0U0YNmg*OSx1V+hr^aZB9VT3(!Ea@u{iRkRP(mUzy4y z^OZuCVl(@%DCNa{En6shx>Kin?zQ~>x*Et8fLI7r!nNM5>buMQ7lNkkfi@abDE>Sl zRz6p3*47gbUuUU%UEN4*76Rgcu|BcvPqJNBaMs1aPyjJ#kI}*kX3~=vWvjo~D(iDy zF<+N6AQn6shulRxQo+^UuK$`<;Bw;0Lj88#Cj5q$rlHk5>_`v3ys@`lOMr3I306fW zO*B2q=FX+6j(|lSnFk zQyWD5hLmDiF|}lZ^X=Fzu%CkOx6TN%r_@8IWK#)_XD{yF0sa8qM%OX-BcJt9nh)~s z0MVU;aSu%rF=}ieCGh$e&zu$8xlCQ)hH3ZZ3U1s(9WeCdTLE7#y!<5>nEX0N57q4{ zf=;dOCmgvW;_DPLz`_rHtwKzS_EZ)*;}3zG_=2K3&k?H`Nk zjK26Qc1R;S6j(?@#v5aVGrY?bXS7YS7aw2${pe5cUhf~h`G1G+4r=cRg%h5V{Y2A$ zUB_Q9+uDdO>htevGoCp{J{?_|IvhE;b=?SmvicLPyZdDQEIQFtvhU)|TUcW`32MEk zjchUJOL-a(W8=nvNpbsR}%*ORu zxWolh#4qoJ;9|ZG%&56xV$@tq!*)Amsh&*&^`ZHum{yMy25<1YXDNMpQt5M_iUfu$ zG`VlWE`z*hlcH=iH(TniaCt#cgy61$oKeSZ=AvF6@9xYpNZXZCNBaJ7W$|kC@3LBf zRTlMr)tC7oo7rk^*{3W_M+hPg{|4H|1IC^3>$R?Ml?RaFV;#aj|ag4L~-zHkk^W+yn}fNW2uL zMNRx_yEo_hN%=;hycD00w-rQ(BwZ5i-%;EaAw0dKWvD1_B^QWownuoa7f?-Bh|t!- zhM*MvJ53{Qt*JE-Mctg}aBsl|_#brG{oQ5!z5%XDjaYj@3q48*tjadZquFK42g=TL zV9VEZtbiO~^wmqYI>9kH2CCvzR04zf#8q)UuW`$6ngDF?wq z8A4~{F%m^7kZ7iWKN9RWrn-b=S}iKv{?2{>xm*NesU-t|$@SKMTK07$d{EHn)RL+^ zsbG%G7hS(4Ilgr%LgYS8AO3=(d)I|=s;}O%D@3B{1!3jk>!0wdm3X@?5{M-GhpB{l zygEN8-X~fHTF;JixjDndF#YpWe!FritL2hv1uInQ_m-lS7@{;y;R=VExjw5PTu z4A}fVMb76^TjRXnB8wnmBgf|{bN&g7OQhl9u_~7r%Pv<4>06t_71#Zc3WJsF3Q4I1 zU)`rgd7@sKuB4LN!yTD#m-XqpPSJUn{p^(1pwN{(Qn(6tb1L;byBACVv9x*luJadi z!6-{soQu})wRFyThL=2^TTRvPDlb&@!?O>ErrON)j&5z+1Q}cLp@WsBq4g)hFm;gu z1rM>kxA(_a8>P4$Fz9EUnYMI)o*E)My_tk3`hpU0Ppvj*_{bl@giEdg{gUFZp$z+a zKIoE2%c-j(kStFEH$TP?Wbc$3jPW35$+!~|1N^g*B3aQFi5FWuA)-T@Mc;k9<|-kb zTc1|T>P?*32{dT*uCoO#JyI9$t4sY>KR~SpAVReU+gk;cxO&JefMIBOrFpj$j~JA9 zdc$`>%uEKSqh)Q2!Rh5axx!~3V}2hyZJOFW)5+r|iE7`F0E;8HIwGvtNivtLNfXX3 zY>Yj$V;qVC%^DnZKN~jmQr=e|iImQF2eg+sVj5Lgu1>ljNYd$aYQR&o(zM%AbN6sE z;Y9#Jt~+Nr za~RL>BJ<&q@+Osmdgx-MH$-!{zmdM5zHrP}@se;@glm`rPxh*lU{^4;3_@apq$An> zyBb?%9n$RI6>d*A?(Wwi**!72=EYdvtYR}Cqs%%aBa_YOZPekbyI`ADf)ah@3=@2S+KsPj1Dh!yqTAQMg78HrwR)U|1-BCafDAny2 zrN*(rTb01NJI0QpcRl#EbRR+PoIwtBrIqa-?Cl_Mc5YxJlD#`e*E4WcNaL*!13f&n zR6OY!l7pP}>(?LUZDfsGLSdE^n@eN&FkrLdgNh_6CsmCV`hmZdBiqZ65ESgftuq=!pcQe)c#C6m7m z5vIxu?+YZvNj|Vj72s%uMr-to3YG2G&}*Dww>}|9z}B5^bDBybVz=$HQxWj7A~Wu) znna3EB}vScV|qDuImOqGlv9Ze_~J-1)zen=o^ey}9pQ0_ZJCE{|gSk|Y{msRa9rH$CLpx7Oc|ozNZsjwJ*Z}{x>R9!*Zm)MV@g+q* z{R6Fm<?nx%>lhe@w*T*UnfVbyHW%-ZEK)mX#?ID$_QXHgOnKMNT!6zgRj{@*U zV_GQQp@*wITSUYVlC%g!WKo{X(SS%wWO-PPT-Sfub&QG^2^+$#O4XA5sQUG^`;g^4 z;-Gd#+4GnwKCFQmchrd)QrtR2#N?y!I_Elk^6F%YVYC~=J9+-bIJZcy{xD$(kVExo ztaPkQjt<047#Z@ZRLt@Hhq{of6Anv;r3SI8+|TaFu+bAkIcCfYYqa++Uf1_>#19N> z7Db1nqEZ}OfUb|nFn=wadZLBXnfc4nyPMO`jnKG}vy9mgin`0Vg=J!0T7>b_p||JX zbYS|MmbOw;eEj~3u8+4ICPF2*vpNY%a}qE9M!)Qs`0jPI6F^?V_mSwa!`h;yavf2T z;Rf&9*`d7K$_Wvk(*>(Z2He`h#!Ni9JTi2(T%*N`T-ymd)bGpXbkcMq9Q1D-{))LKnF0n47KbB{ zn)tW#mW!ibZ$9I)(3}5SrFe=3+?OHpHg~Bqfg4VubKa1)~s2FJ1 z?|n^=eJ;^gb{G|_81+RFK&+w8k1Fv|hqz6faQ$g5o81 zO*?Lqr)JqC>o3Tb`5SHR7Ak$#DY^E^L*Swnc;Z6jD?W)Z{X{& zZCOizb=QY>+3S+{3N$gRj@7a@xYp$WDf3dypx0dhiD@7t^YqW&7GEQPv*?jsrH?H! zey+reei&+rT$)U~p66FD!-{N@1`_Sl5RqadhO*)%*B9t;v98X6{SyK?twVV)UULgd z7#j;=R>a1R9+zaaB%dquxr9PmG@aL4_k=}suEmHfUPo@89nB6{P zlmVk(%uhZjkC1P*ol^K?@`1-1O8|L>Y3N~qQ>bII(3fIjaRUfjh|O4tUkEgPKuS4zvb(${Px4Jh!b@UF|9a)i}vV&ft-<-*KO`qcj&= zQM*4bnc`i;>bsqFN_ve)@)mXG-l9qf*nYU0AB&GzXW1*&hywK;pvaW;#zV{P6H&3H zYIjbqsB_M8$fnsXF|14CTzenklq#=z5k<#}Hzkb@H}xN*9A#hAa&~pD{4$4zM`PpHQ7 zz5A)Un^aUAIB?bM(apjA5MO(QvDPE`u~N<>nyPmGF>jguKD8|g)Z@~)>_p%8`pubc zQOX=#W<>9TNZ2y!Ek2GO?)6Ek_X8-F1AF%Kcx&#_(-hSNW$w;JpRwdw^Lyx|cu){% zW~u}6vsEh{L)1GkTB=DWq(XPkPd~nYulW-~bo?I9t!ED~v23~DpoLE9lGYqd2qABe zmecKX@iVrw<*p9scgu^JOrrVZ505f4tBGUvOUb|L{bB9nYn=LHRPE&>?OC4}uiPwG z8cf%qv0@-5B+MBkT&X&a_*)t;=3`airbu0RfR$u&UX;kyLb^cr`VznhAx!A-a??u7 z0}Qrzpo}b!xO%Hu0cNi8JZTA+RhJs5`4cr{gx}#KEi44APX#*cs0Y~pinHN>lm#V! zL$BkmUEN%J2RV~eOS>0w0-ot5=v54`l=NmLgZ?I^ z%@+dbM1$)&v!q`Bz8nLZ3gD?JxNrX0Qv66FJhfetU)Kz9K-kTKm~wxMX-=|?Xtx@d zJd4G_fO>l5SU|L5=5ghtI}*?`xGwhbHKCc;Ufz9UFb*tvdFOP8h+qy^HJdYsu6y_1 zJQViZ$;9gxZORw)Q%jV-+`fokQ)K#fdrz})`8rj3Mzp$-47U1b`8Tgt`4=}?;_Zmk zY?$L~#&>_C%kkm*o3gIQ(RAC+oH$r;nmIWDK2!y#_*Vd?XW_<|tG~I|_9ts(*}z5P zB^S<48x|oaT2`9Y)W@BV6fzy&<}y%`(EBkSE`~$KyA!nB6-i;52E9P#)p)q{cw9os z+U!qjBeXG|ZP<*?`+9XG%b>(4j;@CyQnB3if=jtu$`9>)rv!t|==9c*PM|=Ap_x~=5c+<0qwO>@S9#R#?9cNKvd3-|JrkrQ= z#;oXVAV7tn&a?6q#d%J+jf{bDLd1Aff0mzoPKXU#klHKXJ zXF9Fu!5t(?VAE~X8Tr@DX6*JamnT&xWk&}++efWak%eiOq<|g{kC<$59E!V7)bVY2 zzCi#;XvIiouODl_gkCPsQHMTKwl(BoRB`LOd_E{9+6R4bJ!e~p*>Crv@%_saEjxbH z+S){k_ReeKUtM8sr=_hS@9dP_YTB%KBv;yq7xJKMk(8<_*VE(9EK*vw0_wDQ)iQ_n zDMm`{O>r{&Q~s~r6+rfhvfSLk3^5&Am+YXAR*WS-CU1&W5R;OXF~FtIb!Doe_-i$4 zQZi>9I2;75y|?$Wx5)Et0__vpnwBq@)FY4gcB=3ou45mc7ByZ|KsC%!>8z(m4qE4k zdjjo#{6GKehw%e>Mcu%#rX22xA~2VBMvfEowkQeR^i?vGOVk* z7HJ095YI%mT(aXi0zTjF%A@WQDASRZ;CaFmAhws3xLz(U|H|w|`7Wb10MVgm5i_az zHGg%^?$8k7*tK+)1C|q>?n#4fL%vQ2$rG4^Rt{sQPr05QyqU`F?>fNZEW8g)jvrDx{H;#aps<4IuN6a+nIsV zxyg;wNa|9N7vyl~Bu&21+@tpoc?p1Cg@WyZ$W(gDcsoPJS_A3pSSl{XM1vsBm3RU zPbQmSHgICS#1r%=XeVH*{&eNGUE*!jAhitcf9{P*NX)P1;Zp;Mv*gD{3+OWi@ZN77 z_kS}>!dGfXIS_a#5y^Cb7pjucHoiFvKdkq$ZRrI)P-QsAV*ZVpm=5Cmd16^>bKgbi z{}LmoZGSXv3|@sBscgYAsN;n%I$cB01t(gw+_%PN=n4^$N1>&DAaW@Z%Is}@Qn>|1 zfIP>@{!Dv`{2kej%hdQ0a_M?QxxuHxtiRndN5x#H!Ss4#hNo6q{Ea^fF07X>BgFJi z$z_;+QHS-pQJkSLHogpmtXg;i9CkH~Ed$i@ayfu$hVMFBeQ&D_9S+fIlkg3SZK4YC zlk%0svq!%|U$k`{UdwDU5Xvkt!byW|-QW=Y!JVxc)zRFmjmI4i$y`<4==CrxzBqLE z)-0*P0vU8yn#oLE*~Ic-RwXuYkprOE35-;Y2ITqZxlGBwDwbAGkI>osA-v|F2r^T_ z_Rs0dC9ixOILZZ9?c)+)o+%br(IY2hWuy(wybIjrut|TGFYCJb@x7&RzJG2f(P@i8 z?2bZj@S2f5o10NIZFZD45z^}U#hA&<<0~e+8GBXXvpxp0)*8(9@CO%1Dd=*Pvl>)F zRi6mh-2EyzXu^Q3(q&=UI31n<<72hsVlInxN~~_k!_y9KBkYWuM8zpj|0FJ0+j{5| zKXQYoTwq;iZo);8Rgnly{4<{+cv5W`8XBlaA8E(pD$UWm;m!PWMzjNuQCO=#W!Vp) z&MNU*kZbtLWf=gc$tNDX$M^JabT&O*LyOd<_Z4WoBUk_ALe@(1|NX67;nxv2g_cy# z+#`Beh__iPZwSLf?gnWIil0&*Zbb*U4!T@2D*S+9Tze0@@lf{b-aQ@;mCd4@u(P{I z|Fr1x7fTdmdch^&uT4k&*eB+b&%5|Dnz8cVM?e4mGky&UUWd(}2=Spc<#b%h^(7+} zvI|XA@PBRVjWO=vg3*3=*ox*v7{|8P6i@o!zNR4oo6(Ap5?*dAY5sY+HH+NNE^idHhYi5sGSd`5*4{ zIH=CrmU&fBY?vq#YeThtU>?E48|ChvZPX11dWFCy1E(T~%-Y+p03*S!kbYu=up4E1 z&F0!vPpmO-Y&N%i?#dp%$EJKmMaMu+eB<T9^TB^(Ch#&8p%0 z{8~-x(*^y(vEv)iHLjjGDEMNGC6fh>r%qrc)w0cm*;nfRMn`tsh7$U|sZU}Bj*&`- zfp2Yk4VBJ=eK8#vg0@Wut`vJ#*}ff#``;0mRxQ>8E`bzkVr6d{6764jneq)ht`!P8 zQo@EZ4HfAX*pITrk3iqr)HQWdG`JIZ-(x}s(=lASaqx7~)f-Cf`3bBi z*%BvE9Q8d2YZ%VwD0p)dQieq*vgms`J%rk8mGL}<`IjIwgDFuW_fG)7Hjn&6WVn6> zY9LD8(HSI1K$@M;Cu=UViu5_t)Z_2z5RI_z8dH-^rV``P3vf+VsRy5q{5gW|&g_|D3V3ZucM{I*nhwBXu|*}N;dtwFbCnbg%^XT89qr$fhK>8m zc_6J?Ik%hoGA~am-l5gbz zGbwr$GgUpN{-vd6jjb=`vyyaHIh;Urm}-2we;5w^YPj`*&*am6 zpiTeVmv|xqf*$NQyj(;;so>_crqYUqP_H`4XAB@hhC=rK%RN4!jx*rN1Z7OSAUCk!@F$0L8942$$%?Nj!e zlM=10J_kY_g_4O}ZCK?Q#yyS@)&j+fRv+^Ibwr~{UX&=#JK^pq@4Gsqav4`ArUg(W(?hcUm%T&ot@0}%QMW*tWM zRD;$EFsD9@N&4t1#|+q#J&7~_pPwJNr1dSO^8Y3BQJ^LsC?_80+iu5ly@uqc&7^*? zVKy;%8Ip(jZg9P2o?e?trx3aR{KsUeXe7k%sML=(Ad`nXHbb=D&}f+Q ziRi5j=2dfHpgh+5`S|;rz4w$!*uBUX%_PF z^%a*;)NhvCF`jERR;~dK)>qqJm_6LC5F+HvQr-wWA(w=R>nV60h8YY!XeIWV)gs*eLoZDdvE zn53%VNLerd>+Aj8K`ZUVTaqHvS$4$e7gZvDS{L~?Pl`hNS-g>^ z5XO!HNm};6Y|QP7Dxa-v>9}?PBK<*0hX&!gg5^aJWFrRa(p=t0Txb+9ElVC$V<$m2 z?eXh9H_e{^t_;D@UM=Ds-SmC4x#imdFLjgt!SU5Hg@Jd42ar@5qBnRKa=$*GvtA~F zIKvs|(=fBX)9j!fRu+U2C`u*oShprhYA1?0(6j76n6B*{wT=R)q7X;R z*<>B@B8A@vp4I!8Ct5b%9zTA<7pkLr-t(A~962KuJZ{c2>OGkW)NAgd6}Q)Vzm^F7 zu?8~hAoNcSR&>+DZtToo_sYuXf&P)H^u&M|Wd%K7PRfTrx9Qbm%7OMY&Hte)wokCw zp;FA{&gn~H=V~m`&j~v0Z;cAxA)|(7&~BB&<;(4_+I#c6z50x6kSUOxcgy#ZLbbkR z6$NOz@7d+1jhFBUvkjY$0&a!iHEwubaE9=u!`okX|2o^=Ys8T(SOP;mE@%yPS&}ba zQD!18qd!O~1Ug^<24GkZwiSHeFBhdYb6n_lbYtBl;nEO<7x+AEZN0nVO`g!*JAbFw z(%>flh?9JvMT)apy%*CekJ`)fD)r(B-rD6eUQzB)tv@YVZFuIFv{~FWF14VPkEgs> z#(8~dZoP{vigMa?We5tCq=K0lBTV_HPJLslm{WYSUN3g-nKqLn=Ot_Z!%zvZMi=p`a{u+dn;xd3<26TRxzpkg@lWMpRL#1t8T0d!jm6XKc3Su;wvGkpmF0K|E z@B^!?9vOovIonB&PSX{PQ|M@Cc8u?}=d8nX*M@3-xI`y2tQ1tO`_G9SJ zTFHa_=8$&|kJVeZYCB1i_@FOjf;q# zb{>b_wI1K?jr|Mu^Am0KJJcc)y33q6J9TWvdq_bJepGJel?O3rj*Yn2WT{L$P{Wyc zpw6O*-_^UrMd1{a)7&=C^5Y~Rn-^1?@@vLbC~V$?R@1$1O6eXDCJ>!sXSoo~P|EXx zC4FHZ=b?hdonHt7J$$DWeR=m)^RJ^>MY#@H=QJ)1umfzW74i({5)^fVG(W*130|+f zh>11qWV^B=*P>{Q;5?rSSFg8}jJ`Xu`#5Vqee@Q|MC>?)==Bk*0GhyQzZmqYE?#trdZ}tru_~j9U-b)*_KPiJQIcK9{vyI0>Y6&qR$L zHR0Jj;>Hyj*qCyr?3rXl*YWJh>pefyB_pu^R9_I(F_?_@>C?%jD)dAT3#5MBAw=rQ z76q$2S@nenf<1xcJ72D)*0;pKD_8V-ekEVv=J6O4)^LelIt)jhLJz}r+x(7eyXn^tr4#)gr1s+3>3mjp_2KcbRg}JMb*nboMWSlUjuz4eQe76_$QPc$Ubs-3 z%tmVEwCqaVPbWv^Sx|ix3YGvUBpWqXV&%kS(h?gT4#PI9o*PfNJDBQN;GWF06=y1* z-;!(XL1Y#B%y-d%vT|}XC0dd(F(j5$0sLkC*t0n$IO1KfB2Ux(b=SN=?I@u7+xZ%! z{GLY4FSM(XScjOrnR*N@f;fq{1drJa8Qf`>RE8#;h>e#+uv+5>RqDsG4L3Y~zwav) zWSy3)*1MOaMl0-NhtTnLHHA;kJ9i@YS(P>Tw}-SBfQZA!(Fk;u_oex^H2>J0frd91 zc>JVXWD{Nm-SD4=WV=wck-=&?`v~c;E`@*^gTrg~aD2b!_REeGvj{+W!0FcwkI=r5 zpYLnBhxXoZRbT=Lq>+3n8hJK{H=N6HaMz0DS%v?H{HaLm;rqmmC?MObgl; z#J~Wc>+!>Cf7;LeHWr4y?A-I!ME5SKyxPCL!+|2nq3;cwVs@Pa1}3BEw^H3IL(`?B z$J7cWcr{JFy)g6Y&Bvgf8}Y8kptZj;jVz9@ka^*ufGq7$^gTw2HwG)P$elOGL_8Wy z`0m~bMT?YHug5^tqT+*HJG{Dq`2`q94u=&vrOKjURT17l5pbF8cSm;4MC4AYw3@j4 zfj0FCablM2WhmhKmlT>-;S+C1tH*O-z52>YgTCP=LwJL+AdXX8+L;~{xC;Vh8VP?M z>e*QYeFu<1Dn$x9jrSZ8#YjG)59g0=;*{mR`aA#H2eQX6uvRK^iGQUCJ%#j_Uq|}O zx~WgiPN>lndIX!$NY(shJmTlCK? zMOREkiQ_om_QQ1QZh08wRvaTJUhnGQ$Snpah}1L=a8shG^pwmYt<@08PYD7Y{|;|)bIxHPVP6xhPW19N~*|g zhTWL!ZmfiShxtaHZ6yC2l+_wk^D|N$u9U7ek9Rkes-K-(U>$FG?=htXBP^&0jwk$5 zPh9+@xUvRqntaj3<-S;-Z!CUeRKV7BX3kLGHPcsyNhtc*uLi zN7C;3{(||{p_4!ATU5i~`lt^_j~)7W1Ln8d#f^43EkM;evK8^dbfw}*2@zT20y(oJ z1vgof|Erb`q*B{2f(e`dIi7$R*wIB91X1mwQVOK4bhq?tweY_G`%v{u28e*u)tTx9 zCd0AeP7c;upig}UAtJ5rCT&Iib|TcIl~M6Ds?4IK?vhCg4(dRM3c2Ldw?Mo9q~w&B`^+o^dk-5Z3p~>aSfb2 zO#Q7ZKCoT<2A{zoi|z5997x|s9<5ox0_heWhsb>ex<#w^;qVCu{djfjHZome7VP#(s^NXXAlHM)JoK7)gy%Yi)I?v{uv%J3QV17@Uru zW_#($U1h}gD%QHZ#w41S)QuQ})45Pe6po<$&VssA%@QdU&wJeZTH;VmF)?Nd{7v7x;-8UcGkb(D7CTdOxnKk{m4^kePy!9Ss1sPAwZIV1Zoa{wRlYKnuViY1%l*%_V9VcF(#sn0Opyr+l#ze*uxs3a?5yWH(zX@X*$ ztb#-r9y4{fnq$P6Q#sbqCZ;EV%+E%r_6Cj|O&B-PQ`Z@4vjWVjGnR%{_!r)R z06hOvB^|)50!4U`#8pU!*vHiKnoTy~^1|Kc`-)%ek=3v5e#0mFp+Y(Jh-hnu^CLRj zT%=?tx~*Sj?q_Sh5{R(?RdDCJn?vGv`TOTWZa&sHj)B;4ZTE8)^&y};9WztMmQ)Iy zL=iTkg`uHm_4@d?YKhNS!R7is zPD{gcSwaT^bkC?>GlOF6!wl%cnpoJ@qk?UHiQkD_mKQY^=45vcUZwSBdJ?F&8fg_A4JS1 z8-jsu`W^pJpH$`OrUiD)V0py;j^4Tsv*VvzYf?p2M$DQoRx5v(O!ciSkP1OkpfQkp z%KM`GSwnn)M_eptWxcGf0fB7jhjck8K~Whz;9-LfVh&1w$RAQbASdM$ytTLcT>F4d zTSJI(LaDN+dK){_gETrJ2X+<@!;JVD1#^CHMrRWS%ooKu-1F2$KYMX{eG_3}=%czZ zQ`gD=L=m$DtxFuMnl=7ua%xSLLKQGM=%TXIq6?=s zVP_e7JFB8V3MsG>H*I({9!*+0WZ{4f2TZFl3R~J+$eG00m1R|FI2xTyaP2UMY0DI; z)Cr0CpMTTYiK2ctInEmm|?Qk++j2T6a@xhUJP zcV6P>jSA9P4?78HoKg70z=KLHFD0K@ZMn_7o|uFYA2$2?llmJ>of`bt<0U+9S4@GR zZeAkUg*R)*3s0)j1Dj22!@x`4r{Ja9ur-Tb*o9OE&lG-$uI&fMJ;t{f=~BE`bxN4{ zD*&k5S1}VG>lIhU+pL)8ok zz!U5mx0yO7rhIpE_UlF5V|`a_1N%mIm(>vmFceio&#mBMT-yE9G6oEV1BhY9=@jd1 zST!EvQx$pSigpI~&6c;}0%|~rONQ_{`tJ8wYvEm_a-^d#Jd)gKlCN!!Ap`=`kag`V zHAO*K<5p~|3yl0%Y95LPrA=4mW7oK5plSm$8rBB<#9ZN%*9DPhohIFWhm^IKqsU8N zufSdOBaxt%3|9{+)|`Du)KGFHKFO3D-+Yz5QpXRk*7+M$?bsVme7JC%V}cZ~?S*tS7~@yzU40fA znjk!JI69S8(L#LSGE1Tebgm-lidg#J(@YH5(P5i=I%%oWaiAnFGTsW?LSp9A^i&`=G(jY!&)x$H&DKq}iF^))S^hid8 z<1TlBVP{w3@8qvHK=gML#9YOmT^@46PHhNi6-^W)AlX?hxE|a7%#moa&*jWvuLzl0gA`l zhAr;Znme%O<&huGA2s4n?mD<*B|P9$ZNsLiwTuoRE_r6Jv?lYyhsiEx!X1^6bK}Ef zq7Y@q&hOtQRnTPk#Bi!N$;HZpWaa^URiIeGRkCw$pE*PFbqXEny-NQqVCJ^2qBHQ@ zd8Se!H!o&UU<&#h8Z7oLAV0~c`V$8JGsIr&aQJ`};H{9gm(=KYsNsNG;sb}R{y0%YA~z&%#Fcf5)ay9{Vyz@h zBxsz$-=B3J@`9LCWeUbv%)7g9cA>gD%G6>-w0L<`R1s3d!I^lWAsVxxMRvy57Oj05 z32EKCShLQa6!TFWpGo`D8O@+!y;;QPzn9i1R54$#mRQ{G^^&mJpixp7YcroO1cNIs#6R5k~lBorR9sr-tDdP&B z-F_#nayF$;q9(BU;R(==(%@ZCdITXLU_aqRv$$8Aq-XmCH~`wwiux8H-f-hEwm!5g z#((Eh`lAB%CxL&^vrG!9YhOvHU+ON#tuL)!Qic}G+ZiFWAo)Ni%Um@_TIg!!6?yD4 zC}ba4^p{+rP=$ejbetoP3Xn3C&OAa#D0;PF0>43&%hKC!3E4A5pnCan6q=oalLa$^ z$v82Grp-)XzfMI8_vg{cch(%HsTgO_)vt$U{tGOq8ItG^^>_dMR_AtrVBN#N{i#YuXm-0O|@7a zZAwZBEhHMP!M z>6MabZBPkJTaIbPTG`!el%DqA>NSa7{Lhe)h>%VTXx)*zj%GIhO=r$ z4(UZIcFYcnc0X4gprHzKohnQJqCp`;VF{u2lQw<+R$%hx3nI}f#kx=+s|9rUNbww* z6lnH9HTggPbjB&GUvtBI((c!f{8-RhLb@2{i=fl3U5Au7*aQ z5Vn5n)YFx;y6D|m)Ae{k31SWaM9%p_QMvMky(LA|DuAnhn;=U-C0x8DY%M~Nt2tl8S7|;19{6D$JERwGRL!~nQm6aYm&Fg}(>OPM+`00>OJ*28g^piGRF;Bz z6eK&;aPf*_Q+ePa_l;8GpKNr0_veWA>G@V~5SO}sHdm+Qg`}fHKwGyDm zJjefCYxRND%E9>)hpZCi0gAYM+<=Im*ppRmnUaYCkt=T}a2J~Gs|3Lg(>s764Qm~p zDW*r*mGd3<1Y%gx(5V>q9C)*)v6+z4CcmhvOMUX6V!gl+;t4X(VjAaCvd>E8HH)ReVKjDeZ<}=AJ`CjX>-P!jk?>$<)~a$ zh4l^GQBT>gVa#^HUD`^6z@UyeVayJ*s!+m#k%J<+Sr}I0_^!bk3llcI4`{2#o)wMt zlnH^CnVlY+mpejbJ$c$cK(DnePRV8loAVXBqOidOpWp{mZ&pVErnd%y;6r1rnu%O` zafHDJMYs%2i?Exk^9PbAl?>t-mfG<>Gg=$bH7D%7f)=p1D=U#pZh{bNxX^MEa)fL5(#Qo8j-{ ze{%NbK0iTJ^A!jTN5HA51*iwEcDjr8+q*UeAJ5CSN%gT6S3*(j_k0+sF(h1hIa%5b zXh(9+XpNnHrQri5Z19!KM^rfpkpK*gbxO69HZXOENBQ5g#Ak18+js0$Hv{ z-vygN!dO0kM1gn9gQZ`eMKD};L#C5U0k1WDmG67BR69XlYZT~;o{o$iN95TY&UV{l zg9g!4h6_4iHQx{WnKFiH{I)s%e3O-GRO?L-u_={n%j9>3)u%ijl$jJ*$rC}p4juuf^f5Hi|XA#+} t*eckSO61a{AlF`Umc5S<356!==us2=FgldmmwWRIy8niW#Jj2q`TwW4$+iFh diff --git a/bin/w32_rel/nsis_install/gpac_installer.nsi b/bin/w32_rel/nsis_install/gpac_installer.nsi index 1122e56..961e0c1 100644 --- a/bin/w32_rel/nsis_install/gpac_installer.nsi +++ b/bin/w32_rel/nsis_install/gpac_installer.nsi @@ -2,21 +2,24 @@ BGGradient XPStyle on WindowIcon on -Icon "..\Osmo4.ico" -UninstallIcon "..\Osmo4.ico" +Icon "..\..\..\..\doc\osmo4.ico" +UninstallIcon "..\..\..\..\doc\osmo4.ico" -!define GPAC_VERSION 0.4.5 -!define /date RELDATE "%Y%m%d" +!define GPAC_VERSION 0.4.6 +!define /date RELDATE "%Y%m%d_%H%M" + +!define GPAC_ROOT ..\..\..\.. Name "GPAC Framework ${GPAC_VERSION}" OutFile "GPAC.Framework.Setup-${RELDATE}.exe" -InstallDir $PROGRAMFILES\GPAC -InstallDirRegKey HKLM SOFTWARE\GPAC "Install_Dir" + +InstallDir "$PROGRAMFILES\GPAC" +InstallDirRegKey HKCU "SOFTWARE\GPAC" "InstallDir" LicenseText "GPAC Licence" -LicenseData "..\..\..\COPYING" +LicenseData "${GPAC_ROOT}\COPYING" DirText "This will install the GPAC Framework on your computer. Choose a directory" @@ -25,6 +28,103 @@ InstType Normal ComponentText "This will install the GPAC Framework on your computer. Select which optional things you want installed." + +Function FctWriteRegStrAuth + ;local var + Push $0 + Push $R0 + Push $R1 + Push $R2 + Push $R3 + ;pop function arguments + Exch 5 + Pop $R3 + Exch 5 + Pop $R2 + Exch 5 + Pop $R1 + Exch 5 + Pop $R0 + + ;test if calling HKCR + StrCmp $R0 "HKCR" +1 +3 + WriteRegStr HKCR $R1 $R2 $R3 + goto lbl_end + + #has current user admin privileges? + userInfo::getAccountType + Pop $0 + StrCmp $0 "Admin" lbl_admin lbl_not_admin + + lbl_admin: + WriteRegStr HKLM $R1 $R2 $R3 + goto lbl_end + + lbl_not_admin: + WriteRegStr HKCU $R1 $R2 $R3 + + lbl_end: + Pop $R3 + Pop $R2 + Pop $R1 + Pop $R0 + Pop $0 +FunctionEnd + +!macro WriteRegStrAuth HKREG SUBREG ENTRY VALUESTR + Push "${HKREG}" + Push "${SUBREG}" + Push "${ENTRY}" + Push "${VALUESTR}" + Call FctWriteRegStrAuth +!macroend + +!define WriteRegStrAuth "!insertmacro WriteRegStrAuth" + + +Function un.FctDeleteRegKeyAuth + ;local var + Push $0 + Push $R0 + Push $R1 + ;pop function arguments + Exch 3 + Pop $R1 + Exch 3 + Pop $R0 + + ;test if calling HKCR + StrCmp $R0 "HKCR" +1 +3 + DeleteRegKey HKCR $R1 + goto lbl_end + + #has current user admin privileges? + userInfo::getAccountType + Pop $0 + StrCmp $0 "Admin" lbl_admin lbl_not_admin + + lbl_admin: + DeleteRegKey HKLM $R1 + goto lbl_end + + lbl_not_admin: + DeleteRegKey HKCU $R1 + + lbl_end: + Pop $0 + Pop $R1 + Pop $R0 +FunctionEnd + +!macro DeleteRegKeyAuth HKREG SUBREG + Push "${HKREG}" + Push "${SUBREG}" + Call un.FctDeleteRegKeyAuth +!macroend + +!define DeleteRegKeyAuth "!insertmacro DeleteRegKeyAuth" + + Function InsertGDIPLUS Push $R0 Push $R1 @@ -73,28 +173,28 @@ Section "Osmo4/GPAC Player" SectionIn RO SetOutPath $INSTDIR - File /oname=ReadMe.txt "..\..\..\README" - File /oname=License.txt "..\..\..\COPYING" - File /oname=Changelog.txt "..\..\..\Changelog" - File "..\..\..\doc\configuration.html" - File "..\..\..\doc\gpac.mp4" + File /oname=ReadMe.txt "${GPAC_ROOT}\README" + File /oname=License.txt "${GPAC_ROOT}\COPYING" + File /oname=Changelog.txt "${GPAC_ROOT}\Changelog" + File "${GPAC_ROOT}\doc\configuration.html" + File "${GPAC_ROOT}\doc\gpac.mp4" File "..\Osmo4.exe" - File "..\Osmo4.ico" + File "..\..\..\..\doc\osmo4.ico" File "..\libgpac.dll" File "..\gm_dummy_in.dll" File "..\gm_dx_hw.dll" File "..\js32.dll" + File "..\gm_gpac_js.dll" ;create default cache SetOutPath $INSTDIR\cache SetOutPath $INSTDIR - - - WriteRegStr HKLM SOFTWARE\GPAC "Install_Dir" "$INSTDIR" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Osmo4" "DisplayName" "Osmo4/GPAC (remove only)" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Osmo4" "UninstallString" '"$INSTDIR\uninstall.exe"' + + ${WriteRegStrAuth} HKCU "SOFTWARE\GPAC" "InstallDir" "$INSTDIR" + ${WriteRegStrAuth} HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Osmo4" "DisplayName" "Osmo4/GPAC (remove only)" + ${WriteRegStrAuth} HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Osmo4" "UninstallString" "$INSTDIR\uninstall.exe" WriteUninstaller "uninstall.exe" SectionEnd @@ -153,9 +253,10 @@ SectionEnd Section "FFMPEG Reader and Decoder" SectionIn 1 File "..\gm_ffmpeg_in.dll" - File "..\avcodec-51.dll" - File "..\avformat-51.dll" - File "..\avutil-49.dll" + File "..\avcodec-52.dll" + File "..\avformat-52.dll" + File "..\avutil-50.dll" + File "..\swscale-0.dll" SectionEnd Section "XviD Video Decoder" @@ -163,10 +264,10 @@ Section "XviD Video Decoder" File "..\gm_xvid_dec.dll" SectionEnd -Section "3GPP AMR NB & WB Speech Decoder" - SectionIn 1 - File "..\gm_amr_float_dec.dll" -SectionEnd +;Section "3GPP AMR NB & WB Speech Decoder" +; SectionIn 1 +; File "..\gm_amr_float_dec.dll" +;SectionEnd Section "Subtitle & TimedText Support" SectionIn 1 @@ -193,6 +294,7 @@ Section "Progressive SVG Support" File "..\gm_svg_in.dll" SectionEnd + Section "GDI+ Rasterizer" SectionIn 1 call InsertGDIPLUS @@ -215,9 +317,18 @@ SectionEnd Section "Xiph Ogg Reader - Vorbis and Theora Decoders" SectionIn 1 - File "..\gm_ogg_xiph.dll" + File "..\gm_ogg.dll" SectionEnd +;Section "UPnP Support" +; SectionIn 1 +; File "..\gm_platinum.dll" +;SectionEnd + +;Section "Widget Manager" +; SectionIn 1 +; File "..\gm_widgetman.dll" +;SectionEnd SubSectionEnd @@ -225,6 +336,11 @@ SubSection "Osmo4 Shortcuts" Section "Add Start Menu Shortcuts" SectionIn 1 + #has current user admin privileges? + userInfo::getAccountType + Pop $0 + StrCmp $0 "Admin" +1 +2 + SetShellVarContext all CreateDirectory "$SMPROGRAMS\Osmo4" CreateShortCut "$SMPROGRAMS\Osmo4\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0 CreateShortCut "$SMPROGRAMS\Osmo4\Osmo4.lnk" "$INSTDIR\Osmo4.exe" "" "$INSTDIR\Osmo4.exe" 0 @@ -250,10 +366,9 @@ SectionEnd Section "Make Osmo4 the default MPEG-4 Player" SectionIn 1 ;write file association - WriteRegStr HKCR GPAC\mp4\DefaultIcon "" "$INSTDIR\Osmo4.ico, 0" - WriteRegStr HKCR GPAC\mp4\Shell\open\command "" '$INSTDIR\Osmo4.exe "%L" ' - WriteRegStr HKCR .mp4 "" "GPAC\mp4" - + ${WriteRegStrAuth} HKCR GPAC\mp4\DefaultIcon "" "$INSTDIR\Osmo4.ico, 0" + ${WriteRegStrAuth} HKCR GPAC\mp4\Shell\open\command "" "$INSTDIR\Osmo4.exe %L" + ${WriteRegStrAuth} HKCR .mp4 "" "GPAC\mp4" !system 'shell32.dll::SHChangeNotify(i, i, i, i) v (${SHCNE_ASSOCCHANGED}, ${SHCNF_IDLIST}, 0, 0)' SectionEnd @@ -261,18 +376,18 @@ SectionEnd Section "Associate 3GPP files (3GP) with Osmo4" SectionIn 1 ;write file association - WriteRegStr HKCR GPAC\3gp\DefaultIcon "" "$INSTDIR\Osmo4.ico, 0" - WriteRegStr HKCR GPAC\3gp\Shell\open\command "" '$INSTDIR\Osmo4.exe "%L" ' - WriteRegStr HKCR .3gp "" "GPAC\3gp" + ${WriteRegStrAuth} HKCR GPAC\3gp\DefaultIcon "" "$INSTDIR\Osmo4.ico, 0" + ${WriteRegStrAuth} HKCR GPAC\3gp\Shell\open\command "" "$INSTDIR\Osmo4.exe %L" + ${WriteRegStrAuth} HKCR .3gp "" "GPAC\3gp" !system 'shell32.dll::SHChangeNotify(i, i, i, i) v (${SHCNE_ASSOCCHANGED}, ${SHCNF_IDLIST}, 0, 0)' SectionEnd Section "Associate 3GPP2 files (3G2) with Osmo4" SectionIn 1 ;write file association - WriteRegStr HKCR GPAC\3g2\DefaultIcon "" "$INSTDIR\Osmo4.ico, 0" - WriteRegStr HKCR GPAC\3g2\Shell\open\command "" '$INSTDIR\Osmo4.exe "%L" ' - WriteRegStr HKCR .3g2 "" "GPAC\3g2" + ${WriteRegStrAuth} HKCR GPAC\3g2\DefaultIcon "" "$INSTDIR\Osmo4.ico, 0" + ${WriteRegStrAuth} HKCR GPAC\3g2\Shell\open\command "" "$INSTDIR\Osmo4.exe %L" + ${WriteRegStrAuth} HKCR .3g2 "" "GPAC\3g2" !system 'shell32.dll::SHChangeNotify(i, i, i, i) v (${SHCNE_ASSOCCHANGED}, ${SHCNF_IDLIST}, 0, 0)' SectionEnd @@ -293,19 +408,16 @@ SectionEnd Section "Osmozilla (GPAC Plugin for Mozilla)" SectionIn 1 - SetOutPath $INSTDIR\mozilla + SetOutPath $INSTDIR File "..\nposmozilla.dll" File "..\nposmozilla.xpt" - WriteRegStr HKCR GPAC "InstallDir" "$INSTDIR" - WriteRegStr HKLM "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "Path" "$INSTDIR\mozilla\nposmozilla.dll" - WriteRegStr HKLM "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "XPTPath" "$INSTDIR\mozilla\nposmozilla.xpt" - WriteRegStr HKLM "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "Version" "${GPAC_VERSION}" - WriteRegStr HKLM "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "Vendor" "GPAC" - WriteRegStr HKLM "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "Description" "GPAC plugin" - WriteRegStr HKLM "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "ProductName" "Osmozilla" - - + ${WriteRegStrAuth} HKCU "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "Path" "$INSTDIR\nposmozilla.dll" + ${WriteRegStrAuth} HKCU "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "XPTPath" "$INSTDIR\nposmozilla.xpt" + ${WriteRegStrAuth} HKCU "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "Version" "${GPAC_VERSION}" + ${WriteRegStrAuth} HKCU "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "Vendor" "GPAC" + ${WriteRegStrAuth} HKCU "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "Description" "GPAC plugin" + ${WriteRegStrAuth} HKCU "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" "ProductName" "Osmozilla" SectionEnd @@ -313,7 +425,6 @@ Section "GPAX (GPAC ActiveX Control)" SectionIn 1 SetOutPath $INSTDIR File "..\GPAX.dll" - WriteRegStr HKCR GPAC "InstallDir" "$INSTDIR" RegDLL "$INSTDIR\GPAX.dll" SectionEnd @@ -325,11 +436,11 @@ Section "MP4Client (GPAC Command-line client/grabber)" SectionEnd -; Function .onInstSuccess +Function .onInstSuccess ; MessageBox MB_YESNO "GPAC Framework installation complete. Do you want to launch the Osmo4 player?" IDNO NoLaunch -; Exec $INSTDIR\Osmo4.exe +; Exec $INSTDIR\Osmo4.exe ; NoLaunch: -; FunctionEnd +FunctionEnd @@ -342,27 +453,39 @@ UninstallText "This will uninstall OSMO4/GPAC from your computer. Hit next to co ; special uninstall section. Section "Uninstall" ; remove registry keys - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Osmo4" - DeleteRegKey HKLM SOFTWARE\GPAC - DeleteRegKey HKCR mp4file\DefaultIcon - DeleteRegKey HKCR mp4file\shell - DeleteRegKey HKCR .mp4 - DeleteRegKey HKCR btfile\shell - DeleteRegKey HKCR .bt + ${DeleteRegKeyAuth} HKCU "Software\Microsoft\Windows\CurrentVersion\Uninstall\Osmo4" + ${DeleteRegKeyAuth} HKCU "SOFTWARE\GPAC" + ${DeleteRegKeyAuth} HKCU "SOFTWARE\MozillaPlugins\@gpac/osmozilla,version=1.0" + ${DeleteRegKeyAuth} HKCR GPAC\mp4\DefaultIcon + ${DeleteRegKeyAuth} HKCR GPAC\mp4\shell\open\command + ${DeleteRegKeyAuth} HKCR GPAC\mp4 + ${DeleteRegKeyAuth} HKCR .mp4 + ${DeleteRegKeyAuth} HKCR GPAC\3gp\DefaultIcon + ${DeleteRegKeyAuth} HKCR GPAC\3gp\shell\open\command + ${DeleteRegKeyAuth} HKCR GPAC\3gp + ${DeleteRegKeyAuth} HKCR .3gp + ${DeleteRegKeyAuth} HKCR GPAC\3g2\DefaultIcon + ${DeleteRegKeyAuth} HKCR GPAC\3g2\shell\open\command + ${DeleteRegKeyAuth} HKCR GPAC\3g2 + ${DeleteRegKeyAuth} HKCR .3g2 + ${DeleteRegKeyAuth} HKCR GPAC Delete $INSTDIR\cache\*.* RMDir "$INSTDIR\cache" - Delete $INSTDIR\mozilla\*.* - RMDir "$INSTDIR\mozilla" Delete $INSTDIR\*.* RMDir "$INSTDIR" + UnRegDLL "$INSTDIR\GPAX.dll" + Push $INSTDIR + Call un.RemoveFromPath + #has current user admin privileges? + userInfo::getAccountType + Pop $0 + StrCmp $0 "Admin" +1 +2 + SetShellVarContext all Delete "$SMPROGRAMS\Osmo4\*.*" RMDir "$SMPROGRAMS\Osmo4" Delete "$QUICKLAUNCH\Osmo4.lnk" Delete "$DESKTOP\Osmo4.lnk" - UnRegDLL "$INSTDIR\GPAX.dll" - Push $INSTDIR - Call un.RemoveFromPath SectionEnd @@ -431,7 +554,16 @@ Function AddToPath StrCpy $0 "$1;$0" AddToPath_NTdoIt: WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $0 - SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 + + ReadRegStr $1 HKCU "Environment" "PATH" + StrCpy $2 $1 1 -1 # copy last char + StrCmp $2 ";" 0 +2 # if last char == ; + StrCpy $1 $1 -1 # remove last char + StrCmp $1 "" AddToPath_NTdoIt2 + StrCpy $0 "$1;$0" + AddToPath_NTdoIt2: + WriteRegExpandStr HKCU "Environment" "PATH" $0 + SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 AddToPath_done: Pop $3 @@ -491,7 +623,7 @@ Function un.RemoveFromPath Goto unRemoveFromPath_done unRemoveFromPath_NT: - ReadRegStr $1 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" + ReadRegStr $1 HKCU "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" StrCpy $5 $1 1 -1 # copy last char StrCmp $5 ";" +2 # if last char != ; StrCpy $1 "$1;" # append ; @@ -513,7 +645,7 @@ Function un.RemoveFromPath StrCmp $5 ";" 0 +2 # if last char == ; StrCpy $3 $3 -1 # remove last char - WriteRegExpandStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3 + WriteRegExpandStr HKCU "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "PATH" $3 SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000 unRemoveFromPath_done: diff --git a/build/codeblocks/GPAX.cbp b/build/codeblocks/GPAX.cbp new file mode 100644 index 0000000..71e7fd9 --- /dev/null +++ b/build/codeblocks/GPAX.cbp @@ -0,0 +1,100 @@ + + + + + + diff --git a/build/codeblocks/Osmo4.cbp b/build/codeblocks/Osmo4.cbp new file mode 100644 index 0000000..222b554 --- /dev/null +++ b/build/codeblocks/Osmo4.cbp @@ -0,0 +1,83 @@ + + + + + + diff --git a/build/codeblocks/aac_in.cbp b/build/codeblocks/aac_in.cbp new file mode 100644 index 0000000..979c646 --- /dev/null +++ b/build/codeblocks/aac_in.cbp @@ -0,0 +1,62 @@ + + + + + + diff --git a/build/codeblocks/ac3_in.cbp b/build/codeblocks/ac3_in.cbp new file mode 100644 index 0000000..06ca507 --- /dev/null +++ b/build/codeblocks/ac3_in.cbp @@ -0,0 +1,64 @@ + + + + + + diff --git a/build/codeblocks/amr_dec.cbp b/build/codeblocks/amr_dec.cbp new file mode 100644 index 0000000..fdf59e4 --- /dev/null +++ b/build/codeblocks/amr_dec.cbp @@ -0,0 +1,496 @@ + + + + + + diff --git a/build/codeblocks/amr_float_dec.cbp b/build/codeblocks/amr_float_dec.cbp new file mode 100644 index 0000000..f5e7fcb --- /dev/null +++ b/build/codeblocks/amr_float_dec.cbp @@ -0,0 +1,159 @@ + + + + + + diff --git a/build/codeblocks/bifs_dec.cbp b/build/codeblocks/bifs_dec.cbp new file mode 100644 index 0000000..e11039e --- /dev/null +++ b/build/codeblocks/bifs_dec.cbp @@ -0,0 +1,62 @@ + + + + + + diff --git a/build/codeblocks/ctx_load.cbp b/build/codeblocks/ctx_load.cbp new file mode 100644 index 0000000..d24c3b6 --- /dev/null +++ b/build/codeblocks/ctx_load.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/build/codeblocks/demo_is.cbp b/build/codeblocks/demo_is.cbp new file mode 100644 index 0000000..3962b53 --- /dev/null +++ b/build/codeblocks/demo_is.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/build/codeblocks/dummy_in.cbp b/build/codeblocks/dummy_in.cbp new file mode 100644 index 0000000..ccbf67f --- /dev/null +++ b/build/codeblocks/dummy_in.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/build/codeblocks/dx_hw.cbp b/build/codeblocks/dx_hw.cbp new file mode 100644 index 0000000..6cf29e8 --- /dev/null +++ b/build/codeblocks/dx_hw.cbp @@ -0,0 +1,86 @@ + + + + + + diff --git a/build/codeblocks/ffmpeg_in.cbp b/build/codeblocks/ffmpeg_in.cbp new file mode 100644 index 0000000..e8a824b --- /dev/null +++ b/build/codeblocks/ffmpeg_in.cbp @@ -0,0 +1,65 @@ + + + + + + diff --git a/build/codeblocks/ft_font.cbp b/build/codeblocks/ft_font.cbp new file mode 100644 index 0000000..5b2148a --- /dev/null +++ b/build/codeblocks/ft_font.cbp @@ -0,0 +1,55 @@ + + + + + + diff --git a/build/codeblocks/gdip_raster.cbp b/build/codeblocks/gdip_raster.cbp new file mode 100644 index 0000000..77e4ada --- /dev/null +++ b/build/codeblocks/gdip_raster.cbp @@ -0,0 +1,54 @@ + + + + + + diff --git a/build/codeblocks/gpac.workspace b/build/codeblocks/gpac.workspace new file mode 100644 index 0000000..b9de249 --- /dev/null +++ b/build/codeblocks/gpac.workspace @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/codeblocks/gpac_js.cbp b/build/codeblocks/gpac_js.cbp new file mode 100644 index 0000000..c62181d --- /dev/null +++ b/build/codeblocks/gpac_js.cbp @@ -0,0 +1,66 @@ + + + + + + diff --git a/build/codeblocks/img_in.cbp b/build/codeblocks/img_in.cbp new file mode 100644 index 0000000..b0445a7 --- /dev/null +++ b/build/codeblocks/img_in.cbp @@ -0,0 +1,69 @@ + + + + + + diff --git a/build/codeblocks/ismacryp.cbp b/build/codeblocks/ismacryp.cbp new file mode 100644 index 0000000..1eebb4f --- /dev/null +++ b/build/codeblocks/ismacryp.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/build/codeblocks/isom_in.cbp b/build/codeblocks/isom_in.cbp new file mode 100644 index 0000000..1f2c81e --- /dev/null +++ b/build/codeblocks/isom_in.cbp @@ -0,0 +1,60 @@ + + + + + + diff --git a/build/codeblocks/laser_dec.cbp b/build/codeblocks/laser_dec.cbp new file mode 100644 index 0000000..d7719cc --- /dev/null +++ b/build/codeblocks/laser_dec.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/build/codeblocks/libgpac.cbp b/build/codeblocks/libgpac.cbp new file mode 100644 index 0000000..cf02575 --- /dev/null +++ b/build/codeblocks/libgpac.cbp @@ -0,0 +1,858 @@ + + + + + + diff --git a/build/codeblocks/mp3_in.cbp b/build/codeblocks/mp3_in.cbp new file mode 100644 index 0000000..1284d24 --- /dev/null +++ b/build/codeblocks/mp3_in.cbp @@ -0,0 +1,60 @@ + + + + + + diff --git a/build/codeblocks/mp4box.cbp b/build/codeblocks/mp4box.cbp new file mode 100644 index 0000000..b7775ea --- /dev/null +++ b/build/codeblocks/mp4box.cbp @@ -0,0 +1,84 @@ + + + + + + diff --git a/build/codeblocks/mp4client.cbp b/build/codeblocks/mp4client.cbp new file mode 100644 index 0000000..e5a6276 --- /dev/null +++ b/build/codeblocks/mp4client.cbp @@ -0,0 +1,55 @@ + + + + + + diff --git a/build/codeblocks/mpegts_in.cbp b/build/codeblocks/mpegts_in.cbp new file mode 100644 index 0000000..f743a15 --- /dev/null +++ b/build/codeblocks/mpegts_in.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/build/codeblocks/odf_dec.cbp b/build/codeblocks/odf_dec.cbp new file mode 100644 index 0000000..9017141 --- /dev/null +++ b/build/codeblocks/odf_dec.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/build/codeblocks/ogg.cbp b/build/codeblocks/ogg.cbp new file mode 100644 index 0000000..09691d1 --- /dev/null +++ b/build/codeblocks/ogg.cbp @@ -0,0 +1,70 @@ + + + + + + diff --git a/build/codeblocks/osmozilla.cbp b/build/codeblocks/osmozilla.cbp new file mode 100644 index 0000000..b97057a --- /dev/null +++ b/build/codeblocks/osmozilla.cbp @@ -0,0 +1,72 @@ + + + + + + diff --git a/build/codeblocks/raw_out.cbp b/build/codeblocks/raw_out.cbp new file mode 100644 index 0000000..e7db51d --- /dev/null +++ b/build/codeblocks/raw_out.cbp @@ -0,0 +1,62 @@ + + + + + + diff --git a/build/codeblocks/rtp_in.cbp b/build/codeblocks/rtp_in.cbp new file mode 100644 index 0000000..4f2c1c1 --- /dev/null +++ b/build/codeblocks/rtp_in.cbp @@ -0,0 +1,66 @@ + + + + + + diff --git a/build/codeblocks/saf_in.cbp b/build/codeblocks/saf_in.cbp new file mode 100644 index 0000000..f239de1 --- /dev/null +++ b/build/codeblocks/saf_in.cbp @@ -0,0 +1,50 @@ + + + + + + diff --git a/build/codeblocks/sdl_out.cbp b/build/codeblocks/sdl_out.cbp new file mode 100644 index 0000000..c4451a0 --- /dev/null +++ b/build/codeblocks/sdl_out.cbp @@ -0,0 +1,61 @@ + + + + + + diff --git a/build/codeblocks/soft_raster.cbp b/build/codeblocks/soft_raster.cbp new file mode 100644 index 0000000..243d7d7 --- /dev/null +++ b/build/codeblocks/soft_raster.cbp @@ -0,0 +1,71 @@ + + + + + + diff --git a/build/codeblocks/svg_in.cbp b/build/codeblocks/svg_in.cbp new file mode 100644 index 0000000..2c5e359 --- /dev/null +++ b/build/codeblocks/svg_in.cbp @@ -0,0 +1,54 @@ + + + + + + diff --git a/build/codeblocks/timedtext.cbp b/build/codeblocks/timedtext.cbp new file mode 100644 index 0000000..10acad7 --- /dev/null +++ b/build/codeblocks/timedtext.cbp @@ -0,0 +1,53 @@ + + + + + + diff --git a/build/codeblocks/ui_rec.cbp b/build/codeblocks/ui_rec.cbp new file mode 100644 index 0000000..9aea29f --- /dev/null +++ b/build/codeblocks/ui_rec.cbp @@ -0,0 +1,53 @@ + + + + + + diff --git a/build/codeblocks/wav_out.cbp b/build/codeblocks/wav_out.cbp new file mode 100644 index 0000000..6dcb394 --- /dev/null +++ b/build/codeblocks/wav_out.cbp @@ -0,0 +1,51 @@ + + + + + + diff --git a/build/codeblocks/wiiis.cbp b/build/codeblocks/wiiis.cbp new file mode 100644 index 0000000..63d0fcc --- /dev/null +++ b/build/codeblocks/wiiis.cbp @@ -0,0 +1,55 @@ + + + + + + diff --git a/build/codeblocks/wxOsmo4.cbp b/build/codeblocks/wxOsmo4.cbp new file mode 100644 index 0000000..b0f368d --- /dev/null +++ b/build/codeblocks/wxOsmo4.cbp @@ -0,0 +1,65 @@ + + + + + + diff --git a/build/codeblocks/xvid_dec.cbp b/build/codeblocks/xvid_dec.cbp new file mode 100644 index 0000000..02379dd --- /dev/null +++ b/build/codeblocks/xvid_dec.cbp @@ -0,0 +1,54 @@ + + + + + + diff --git a/build/msevc3/GPAC.VCW b/build/msevc3/GPAC.VCW deleted file mode 100644 index 271722c..0000000 --- a/build/msevc3/GPAC.VCW +++ /dev/null @@ -1,401 +0,0 @@ -Microsoft eMbedded Visual Tools Workspace File, Format Version 3.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "Osmo4"=.\Osmo4.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "aac_in"=.\aac_in.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "amr_dec"=.\amr_dec.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "bifs_dec"=.\bifs_dec.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ctx_load"=.\ctx_load.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "dummy_in"=.\dummy_in.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ft_font"=.\ft_font.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "gapi"=.\gapi.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "img_in"=.\img_in.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "isom_in"=.\isom_in.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "laser_dec"=.\laser_dec.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "libgpac"=.\libgpac.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "libgpac_dll"=.\libgpac_dll.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac - End Project Dependency -}}} - -############################################################################### - -Project: "mp3_in"=.\mp3_in.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "odf_dec"=.\odf_dec.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ogg"=.\ogg.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "render2d"=.\render2d.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "render3d"=.\render3d.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "rtp_in"=.\rtp_in.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "saf_in"=.\saf_in.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "soft_raster"=.\soft_raster.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "svg_in"=.\svg_in.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "svg_loader"=.\svg_loader.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "timedtext"=.\timedtext.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "wav_out"=.\wav_out.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "xvid_dec"=.\xvid_dec.vcp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/build/msevc3/Osmo4.vcp b/build/msevc3/Osmo4.vcp deleted file mode 100644 index 402ee94..0000000 --- a/build/msevc3/Osmo4.vcp +++ /dev/null @@ -1,281 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="Osmo4" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Application" 0x8501 - -CFG=Osmo4 - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Osmo4.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Osmo4.vcn" CFG="Osmo4 - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Osmo4 - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Application") -!MESSAGE "Osmo4 - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Osmo4 - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 2 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 2 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/osmo4_rel" -# PROP Intermediate_Dir "obj/osmo4_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "_AFXDLL" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "_AFXDLL" /r -# ADD BASE CPP /nologo /W3 /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_AFXDLL" /Yu"stdafx.h" /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_AFXDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 gx.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/Osmo4.exe" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "Osmo4 - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 2 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 2 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/osmo4_deb" -# PROP Intermediate_Dir "obj/osmo4_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "_AFXDLL" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "_AFXDLL" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_AFXDLL" /Yu"stdafx.h" /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include" /D "DEBUG" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "UNICODE" /D "_UNICODE" /D "_AFXDLL" /FR /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 gx.lib /nologo /base:"0x00010000" /stack:0x10000,0x1000 /entry:"wWinMainCRTStartup" /debug /out:"../../bin/arm_ppc02_deb/Osmo4.exe" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "Osmo4 - Win32 (WCE ARM) Release" -# Name "Osmo4 - Win32 (WCE ARM) Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\applications\osmo4_wce\MainFrm.cpp -DEP_CPP_MAINF=\ - "..\..\Applications\Osmo4_wce\MainFrm.h"\ - "..\..\Applications\Osmo4_wce\Osmo4.h"\ - "..\..\Applications\Osmo4_wce\ProgressBar.h"\ - "..\..\Applications\Osmo4_wce\StdAfx.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\options.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -NODEP_CPP_MAINF=\ - ".\x.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wce\OpenDlg.cpp -DEP_CPP_OPEND=\ - "..\..\Applications\Osmo4_wce\OpenDlg.h"\ - "..\..\Applications\Osmo4_wce\Osmo4.h"\ - "..\..\Applications\Osmo4_wce\StdAfx.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wce\Options.cpp -DEP_CPP_OPTIO=\ - "..\..\Applications\Osmo4_wce\Options.h"\ - "..\..\Applications\Osmo4_wce\Osmo4.h"\ - "..\..\Applications\Osmo4_wce\StdAfx.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\audio_out.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\font.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\options.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -NODEP_CPP_OPTIO=\ - ".\x.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wce\Osmo4.cpp -DEP_CPP_OSMO4=\ - "..\..\Applications\Osmo4_wce\MainFrm.h"\ - "..\..\Applications\Osmo4_wce\OpenDlg.h"\ - "..\..\Applications\Osmo4_wce\Options.h"\ - "..\..\Applications\Osmo4_wce\Osmo4.h"\ - "..\..\Applications\Osmo4_wce\ProgressBar.h"\ - "..\..\Applications\Osmo4_wce\StdAfx.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\options.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -NODEP_CPP_OSMO4=\ - ".\x.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wce\Osmo4.rc -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wce\ProgressBar.cpp -DEP_CPP_PROGR=\ - "..\..\Applications\Osmo4_wce\Osmo4.h"\ - "..\..\Applications\Osmo4_wce\ProgressBar.h"\ - "..\..\Applications\Osmo4_wce\StdAfx.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wce\StdAfx.cpp -DEP_CPP_STDAF=\ - "..\..\Applications\Osmo4_wce\StdAfx.h"\ - -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\Applications\Osmo4_wce\MainFrm.h -# End Source File -# Begin Source File - -SOURCE=..\..\Applications\Osmo4_wce\newres.h -# End Source File -# Begin Source File - -SOURCE=..\..\Applications\Osmo4_wce\OpenDlg.h -# End Source File -# Begin Source File - -SOURCE=..\..\Applications\Osmo4_wce\Options.h -# End Source File -# Begin Source File - -SOURCE=..\..\Applications\Osmo4_wce\Osmo4.h -# End Source File -# Begin Source File - -SOURCE=..\..\Applications\Osmo4_wce\ProgressBar.h -# End Source File -# Begin Source File - -SOURCE=..\..\Applications\Osmo4_wce\Resource.h -# End Source File -# Begin Source File - -SOURCE=..\..\Applications\Osmo4_wce\StdAfx.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=..\..\applications\osmo4_wce\res\Cmdbar.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wce\res\Osmo4.ico -# End Source File -# End Group -# End Target -# End Project diff --git a/build/msevc3/aac_in.vcp b/build/msevc3/aac_in.vcp deleted file mode 100644 index d83f089..0000000 --- a/build/msevc3/aac_in.vcp +++ /dev/null @@ -1,140 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="aac_in" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=aac_in - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "aac_in.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "aac_in.vcn" CFG="aac_in - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "aac_in - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "aac_in - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "aac_in - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/aac_in_rel" -# PROP Intermediate_Dir "obj/aac_in_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "AAC_IN_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /I "../../extra_lib/include/faad" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAC_HAS_FAAD" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 libfaad2.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_aac_in.dll" /libpath:"../../extra_lib/lib/arm_ppc02_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "aac_in - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/aac_in_deb" -# PROP Intermediate_Dir "obj/aac_in_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "AAC_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/faad" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GPAC_HAS_FAAD" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 libfaad2.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_aac_in.dll" /libpath:"../../extra_lib/lib/arm_ppc02_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "aac_in - Win32 (WCE ARM) Release" -# Name "aac_in - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\aac_in\aac_in.c -DEP_CPP_AAC_I=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\aac_in\aac_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\aac_in\faad_dec.c -DEP_CPP_FAAD_=\ - "..\..\extra_lib\include\faad\faad.h"\ - "..\..\extra_lib\include\faad\neaacdec.h"\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# End Target -# End Project diff --git a/build/msevc3/amr_dec.vcp b/build/msevc3/amr_dec.vcp deleted file mode 100644 index 022ff38..0000000 --- a/build/msevc3/amr_dec.vcp +++ /dev/null @@ -1,2411 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="amr_dec" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=amr_dec - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "amr_dec.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "amr_dec.vcn" CFG="amr_dec - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "amr_dec - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "amr_dec - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "amr_dec - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/amr_dec_rel" -# PROP Intermediate_Dir "obj/amr_dec_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "AMR_DEC_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "__MSDOS__" /D "MMS_IO" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_amr_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "amr_dec - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/amr_dec_deb" -# PROP Intermediate_Dir "obj/amr_dec_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "AMR_DEC_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "__MSDOS__" /D "MMS_IO" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_amr_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "amr_dec - Win32 (WCE ARM) Release" -# Name "amr_dec - Win32 (WCE ARM) Debug" -# Begin Group "amr_nb" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\a_refl.c -DEP_CPP_A_REF=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\a_refl.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\a_refl.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\agc.c -DEP_CPP_AGC_C=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\agc.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\agc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\autocorr.c -DEP_CPP_AUTOC=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\autocorr.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\autocorr.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\az_lsp.c -DEP_CPP_AZ_LS=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\az_lsp.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\grid.tab"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\az_lsp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\b_cn_cod.c -DEP_CPP_B_CN_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\b_cn_cod.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\window.tab"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\b_cn_cod.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\basic_op.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\basicop2.c -DEP_CPP_BASIC=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\bgnscd.c -DEP_CPP_BGNSC=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\bgnscd.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gmed_n.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\sqrt_l.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\bgnscd.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\bits2prm.c -DEP_CPP_BITS2=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\bitno.tab"\ - "..\..\modules\amr_dec\amr_nb\bits2prm.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\bits2prm.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c1035pf.c -DEP_CPP_C1035=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c1035pf.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cor_h.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gray.tab"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\s10_8pf.h"\ - "..\..\modules\amr_dec\amr_nb\set_sign.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c1035pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c2_11pf.c -DEP_CPP_C2_11=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c2_11pf.h"\ - "..\..\modules\amr_dec\amr_nb\c2_11pf.tab"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cor_h.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\set_sign.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c2_11pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c2_9pf.c -DEP_CPP_C2_9P=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c2_9pf.h"\ - "..\..\modules\amr_dec\amr_nb\c2_9pf.tab"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cor_h.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\set_sign.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c2_9pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c3_14pf.c -DEP_CPP_C3_14=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c3_14pf.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cor_h.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\set_sign.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c3_14pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c4_17pf.c -DEP_CPP_C4_17=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c4_17pf.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cor_h.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gray.tab"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\set_sign.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c4_17pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c8_31pf.c -DEP_CPP_C8_31=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c8_31pf.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cor_h.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\s10_8pf.h"\ - "..\..\modules\amr_dec\amr_nb\set_sign.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c8_31pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c_g_aver.c -DEP_CPP_C_G_A=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c_g_aver.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c_g_aver.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\calc_cor.c -DEP_CPP_CALC_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\calc_cor.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\calc_cor.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\calc_en.c -DEP_CPP_CALC_E=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\calc_en.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\calc_en.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cbsearch.c -DEP_CPP_CBSEA=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c1035pf.h"\ - "..\..\modules\amr_dec\amr_nb\c2_11pf.h"\ - "..\..\modules\amr_dec\amr_nb\c2_9pf.h"\ - "..\..\modules\amr_dec\amr_nb\c3_14pf.h"\ - "..\..\modules\amr_dec\amr_nb\c4_17pf.h"\ - "..\..\modules\amr_dec\amr_nb\c8_31pf.h"\ - "..\..\modules\amr_dec\amr_nb\cbsearch.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cbsearch.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cl_ltp.c -DEP_CPP_CL_LT=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cl_ltp.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\convolve.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\enc_lag3.h"\ - "..\..\modules\amr_dec\amr_nb\enc_lag6.h"\ - "..\..\modules\amr_dec\amr_nb\g_pitch.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pitch_fr.h"\ - "..\..\modules\amr_dec\amr_nb\pred_lt.h"\ - "..\..\modules\amr_dec\amr_nb\q_gain_p.h"\ - "..\..\modules\amr_dec\amr_nb\ton_stab.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cl_ltp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cnst.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cnst_vad.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cod_amr.c -DEP_CPP_COD_A=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cbsearch.h"\ - "..\..\modules\amr_dec\amr_nb\cl_ltp.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cnst_vad.h"\ - "..\..\modules\amr_dec\amr_nb\cod_amr.h"\ - "..\..\modules\amr_dec\amr_nb\convolve.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_enc.h"\ - "..\..\modules\amr_dec\amr_nb\g_adapt.h"\ - "..\..\modules\amr_dec\amr_nb\gain_q.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\levinson.h"\ - "..\..\modules\amr_dec\amr_nb\lpc.h"\ - "..\..\modules\amr_dec\amr_nb\lsp.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\ol_ltp.h"\ - "..\..\modules\amr_dec\amr_nb\p_ol_wgh.h"\ - "..\..\modules\amr_dec\amr_nb\pitch_fr.h"\ - "..\..\modules\amr_dec\amr_nb\pre_big.h"\ - "..\..\modules\amr_dec\amr_nb\pred_lt.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\qua_gain.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\spreproc.h"\ - "..\..\modules\amr_dec\amr_nb\spstproc.h"\ - "..\..\modules\amr_dec\amr_nb\ton_stab.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\vad.h"\ - "..\..\modules\amr_dec\amr_nb\vad1.h"\ - "..\..\modules\amr_dec\amr_nb\vad2.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cod_amr.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\convolve.c -DEP_CPP_CONVO=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\convolve.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\convolve.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\copy.c -DEP_CPP_COPY_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\copy.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cor_h.c -DEP_CPP_COR_H=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cor_h.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cor_h.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\count.c -DEP_CPP_COUNT=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\count.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d1035pf.c -DEP_CPP_D1035=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d1035pf.h"\ - "..\..\modules\amr_dec\amr_nb\gray.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d1035pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d2_11pf.c -DEP_CPP_D2_11=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d2_11pf.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d2_11pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d2_9pf.c -DEP_CPP_D2_9P=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c2_9pf.tab"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d2_9pf.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d2_9pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d3_14pf.c -DEP_CPP_D3_14=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d3_14pf.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d3_14pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d4_17pf.c -DEP_CPP_D4_17=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d4_17pf.h"\ - "..\..\modules\amr_dec\amr_nb\gray.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d4_17pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d8_31pf.c -DEP_CPP_D8_31=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d8_31pf.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d8_31pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_gain_c.c -DEP_CPP_D_GAI=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d_gain_c.h"\ - "..\..\modules\amr_dec\amr_nb\gains.tab"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_gain_c.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_gain_p.c -DEP_CPP_D_GAIN=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d_gain_p.h"\ - "..\..\modules\amr_dec\amr_nb\gains.tab"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_gain_p.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_homing.c -DEP_CPP_D_HOM=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\bitno.tab"\ - "..\..\modules\amr_dec\amr_nb\bits2prm.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\d_homing.h"\ - "..\..\modules\amr_dec\amr_nb\d_homing.tab"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_homing.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_plsf.c -DEP_CPP_D_PLS=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf_5.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_plsf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_plsf_3.c -DEP_CPP_D_PLSF=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf_3.tab"\ - "..\..\modules\amr_dec\amr_nb\reorder.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_plsf_5.c -DEP_CPP_D_PLSF_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf_5.tab"\ - "..\..\modules\amr_dec\amr_nb\reorder.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_amr.c -DEP_CPP_DEC_A=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\agc.h"\ - "..\..\modules\amr_dec\amr_nb\b_cn_cod.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\bgnscd.h"\ - "..\..\modules\amr_dec\amr_nb\bitno.tab"\ - "..\..\modules\amr_dec\amr_nb\c_g_aver.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d1035pf.h"\ - "..\..\modules\amr_dec\amr_nb\d2_11pf.h"\ - "..\..\modules\amr_dec\amr_nb\d2_9pf.h"\ - "..\..\modules\amr_dec\amr_nb\d3_14pf.h"\ - "..\..\modules\amr_dec\amr_nb\d4_17pf.h"\ - "..\..\modules\amr_dec\amr_nb\d8_31pf.h"\ - "..\..\modules\amr_dec\amr_nb\d_gain_c.h"\ - "..\..\modules\amr_dec\amr_nb\d_gain_p.h"\ - "..\..\modules\amr_dec\amr_nb\d_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\dec_amr.h"\ - "..\..\modules\amr_dec\amr_nb\dec_gain.h"\ - "..\..\modules\amr_dec\amr_nb\dec_lag3.h"\ - "..\..\modules\amr_dec\amr_nb\dec_lag6.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_dec.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_enc.h"\ - "..\..\modules\amr_dec\amr_nb\ec_gains.h"\ - "..\..\modules\amr_dec\amr_nb\ex_ctrl.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\int_lpc.h"\ - "..\..\modules\amr_dec\amr_nb\int_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\lsp.tab"\ - "..\..\modules\amr_dec\amr_nb\lsp_avg.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\ph_disp.h"\ - "..\..\modules\amr_dec\amr_nb\pred_lt.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\sqrt_l.h"\ - "..\..\modules\amr_dec\amr_nb\syn_filt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_amr.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_gain.c -DEP_CPP_DEC_G=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\dec_gain.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.h"\ - "..\..\modules\amr_dec\amr_nb\qgain475.tab"\ - "..\..\modules\amr_dec\amr_nb\qua_gain.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_gain.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_lag3.c -DEP_CPP_DEC_L=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\dec_lag3.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_lag3.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_lag6.c -DEP_CPP_DEC_LA=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\dec_lag6.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_lag6.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dtx_dec.c -DEP_CPP_DTX_D=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\a_refl.h"\ - "..\..\modules\amr_dec\amr_nb\b_cn_cod.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\c_g_aver.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_dec.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_enc.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\lsp.tab"\ - "..\..\modules\amr_dec\amr_nb\lsp_az.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf_5.tab"\ - "..\..\modules\amr_dec\amr_nb\reorder.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\syn_filt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dtx_dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dtx_enc.c -DEP_CPP_DTX_E=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_enc.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\lsp.tab"\ - "..\..\modules\amr_dec\amr_nb\lsp_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\reorder.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dtx_enc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\e_homing.c -DEP_CPP_E_HOM=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\e_homing.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\e_homing.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ec_gains.c -DEP_CPP_EC_GA=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\ec_gains.h"\ - "..\..\modules\amr_dec\amr_nb\gains.tab"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\gmed_n.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ec_gains.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\enc_lag3.c -DEP_CPP_ENC_L=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\enc_lag3.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\enc_lag3.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\enc_lag6.c -DEP_CPP_ENC_LA=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\enc_lag6.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\enc_lag6.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ex_ctrl.c -DEP_CPP_EX_CT=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\ex_ctrl.h"\ - "..\..\modules\amr_dec\amr_nb\gmed_n.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\sqrt_l.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ex_ctrl.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\frame.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_adapt.c -DEP_CPP_G_ADA=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\g_adapt.h"\ - "..\..\modules\amr_dec\amr_nb\gmed_n.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_adapt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_code.c -DEP_CPP_G_COD=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\g_code.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_code.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_pitch.c -DEP_CPP_G_PIT=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\g_pitch.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_pitch.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gain_q.c -DEP_CPP_GAIN_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\calc_en.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\g_adapt.h"\ - "..\..\modules\amr_dec\amr_nb\g_code.h"\ - "..\..\modules\amr_dec\amr_nb\gain_q.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\q_gain_c.h"\ - "..\..\modules\amr_dec\amr_nb\qgain475.h"\ - "..\..\modules\amr_dec\amr_nb\qgain795.h"\ - "..\..\modules\amr_dec\amr_nb\qua_gain.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gain_q.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gc_pred.c -DEP_CPP_GC_PR=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gc_pred.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gmed_n.c -DEP_CPP_GMED_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gmed_n.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gmed_n.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\hp_max.c -DEP_CPP_HP_MA=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\hp_max.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\hp_max.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\int_lpc.c -DEP_CPP_INT_L=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\int_lpc.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_az.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\int_lpc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\int_lsf.c -DEP_CPP_INT_LS=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\int_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\int_lsf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\inter_36.c -DEP_CPP_INTER=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\inter_36.h"\ - "..\..\modules\amr_dec\amr_nb\inter_36.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\inter_36.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\inv_sqrt.c -DEP_CPP_INV_S=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\inv_sqrt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lag_wind.c -DEP_CPP_LAG_W=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\lag_wind.h"\ - "..\..\modules\amr_dec\amr_nb\lag_wind.tab"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lag_wind.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\levinson.c -DEP_CPP_LEVIN=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\levinson.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\levinson.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lflg_upd.c -DEP_CPP_LFLG_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\vad2.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\log2.c -DEP_CPP_LOG2_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\log2.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\log2.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lpc.c -DEP_CPP_LPC_C=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\autocorr.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\lag_wind.h"\ - "..\..\modules\amr_dec\amr_nb\levinson.h"\ - "..\..\modules\amr_dec\amr_nb\lpc.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\window.tab"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lpc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsfwt.c -DEP_CPP_LSFWT=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\lsfwt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsfwt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp.c -DEP_CPP_LSP_C=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\az_lsp.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\int_lpc.h"\ - "..\..\modules\amr_dec\amr_nb\lsp.h"\ - "..\..\modules\amr_dec\amr_nb\lsp.tab"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_avg.c -DEP_CPP_LSP_A=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_avg.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf_5.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_avg.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_az.c -DEP_CPP_LSP_AZ=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_az.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_az.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_lsf.c -DEP_CPP_LSP_L=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_lsf.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_lsf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\mac_32.c -DEP_CPP_MAC_3=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mac_32.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\mac_32.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\mode.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\n_proc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\n_proc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ol_ltp.c -DEP_CPP_OL_LT=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cnst_vad.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\ol_ltp.h"\ - "..\..\modules\amr_dec\amr_nb\p_ol_wgh.h"\ - "..\..\modules\amr_dec\amr_nb\pitch_ol.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\vad.h"\ - "..\..\modules\amr_dec\amr_nb\vad1.h"\ - "..\..\modules\amr_dec\amr_nb\vad2.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ol_ltp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\oper_32b.c -DEP_CPP_OPER_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\oper_32b.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\p_ol_wgh.c -DEP_CPP_P_OL_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\calc_cor.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cnst_vad.h"\ - "..\..\modules\amr_dec\amr_nb\corrwght.tab"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gmed_n.h"\ - "..\..\modules\amr_dec\amr_nb\hp_max.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\p_ol_wgh.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\vad.h"\ - "..\..\modules\amr_dec\amr_nb\vad1.h"\ - "..\..\modules\amr_dec\amr_nb\vad2.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\p_ol_wgh.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ph_disp.c -DEP_CPP_PH_DI=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\ph_disp.h"\ - "..\..\modules\amr_dec\amr_nb\ph_disp.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ph_disp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pitch_fr.c -DEP_CPP_PITCH=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\convolve.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\enc_lag3.h"\ - "..\..\modules\amr_dec\amr_nb\enc_lag6.h"\ - "..\..\modules\amr_dec\amr_nb\inter_36.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pitch_fr.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pitch_fr.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pitch_ol.c -DEP_CPP_PITCH_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\calc_cor.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cnst_vad.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\hp_max.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pitch_ol.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\vad.h"\ - "..\..\modules\amr_dec\amr_nb\vad1.h"\ - "..\..\modules\amr_dec\amr_nb\vad2.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pitch_ol.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\post_pro.c -DEP_CPP_POST_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\post_pro.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\post_pro.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pow2.c -DEP_CPP_POW2_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pow2.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pre_big.c -DEP_CPP_PRE_B=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pre_big.h"\ - "..\..\modules\amr_dec\amr_nb\residu.h"\ - "..\..\modules\amr_dec\amr_nb\syn_filt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\weight_a.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pre_big.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pre_proc.c -DEP_CPP_PRE_P=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pre_proc.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pre_proc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pred_lt.c -DEP_CPP_PRED_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\pred_lt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pred_lt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\preemph.c -DEP_CPP_PREEM=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\preemph.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\preemph.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\prm2bits.c -DEP_CPP_PRM2B=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\bitno.tab"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\prm2bits.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\prm2bits.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pstfilt.c -DEP_CPP_PSTFI=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\agc.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\preemph.h"\ - "..\..\modules\amr_dec\amr_nb\pstfilt.h"\ - "..\..\modules\amr_dec\amr_nb\residu.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\syn_filt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\weight_a.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pstfilt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_gain_c.c -DEP_CPP_Q_GAI=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gains.tab"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.h"\ - "..\..\modules\amr_dec\amr_nb\q_gain_c.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_gain_c.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_gain_p.c -DEP_CPP_Q_GAIN=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gains.tab"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\q_gain_p.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_gain_p.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_plsf.c -DEP_CPP_Q_PLS=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_plsf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_plsf_3.c -DEP_CPP_Q_PLSF=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\lsfwt.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf_3.tab"\ - "..\..\modules\amr_dec\amr_nb\reorder.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_plsf_5.c -DEP_CPP_Q_PLSF_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\lsfwt.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_lsf.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf_5.tab"\ - "..\..\modules\amr_dec\amr_nb\reorder.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qgain475.c -DEP_CPP_QGAIN=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\mac_32.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.h"\ - "..\..\modules\amr_dec\amr_nb\qgain475.h"\ - "..\..\modules\amr_dec\amr_nb\qgain475.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qgain475.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qgain795.c -DEP_CPP_QGAIN7=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\calc_en.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\g_adapt.h"\ - "..\..\modules\amr_dec\amr_nb\gains.tab"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\mac_32.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.h"\ - "..\..\modules\amr_dec\amr_nb\q_gain_p.h"\ - "..\..\modules\amr_dec\amr_nb\qgain795.h"\ - "..\..\modules\amr_dec\amr_nb\sqrt_l.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qgain795.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qua_gain.c -DEP_CPP_QUA_G=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.h"\ - "..\..\modules\amr_dec\amr_nb\qua_gain.h"\ - "..\..\modules\amr_dec\amr_nb\qua_gain.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qua_gain.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\r_fft.c -DEP_CPP_R_FFT=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\vad2.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\reorder.c -DEP_CPP_REORD=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\reorder.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\reorder.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\residu.c -DEP_CPP_RESID=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\residu.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\residu.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\s10_8pf.c -DEP_CPP_S10_8=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\s10_8pf.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\s10_8pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\set_sign.c -DEP_CPP_SET_S=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\inv_sqrt.h"\ - "..\..\modules\amr_dec\amr_nb\set_sign.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\set_sign.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\set_zero.c -DEP_CPP_SET_Z=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\set_zero.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sid_sync.c -DEP_CPP_SID_S=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\sid_sync.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sid_sync.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sp_dec.c -DEP_CPP_SP_DE=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\agc.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\bgnscd.h"\ - "..\..\modules\amr_dec\amr_nb\bitno.tab"\ - "..\..\modules\amr_dec\amr_nb\bits2prm.h"\ - "..\..\modules\amr_dec\amr_nb\c_g_aver.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\d_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\dec_amr.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_dec.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_enc.h"\ - "..\..\modules\amr_dec\amr_nb\ec_gains.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_avg.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\ph_disp.h"\ - "..\..\modules\amr_dec\amr_nb\post_pro.h"\ - "..\..\modules\amr_dec\amr_nb\preemph.h"\ - "..\..\modules\amr_dec\amr_nb\pstfilt.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\sp_dec.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sp_dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sp_enc.c -DEP_CPP_SP_EN=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\bitno.tab"\ - "..\..\modules\amr_dec\amr_nb\cl_ltp.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\cnst_vad.h"\ - "..\..\modules\amr_dec\amr_nb\cod_amr.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_enc.h"\ - "..\..\modules\amr_dec\amr_nb\g_adapt.h"\ - "..\..\modules\amr_dec\amr_nb\gain_q.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\levinson.h"\ - "..\..\modules\amr_dec\amr_nb\lpc.h"\ - "..\..\modules\amr_dec\amr_nb\lsp.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\p_ol_wgh.h"\ - "..\..\modules\amr_dec\amr_nb\pitch_fr.h"\ - "..\..\modules\amr_dec\amr_nb\pre_proc.h"\ - "..\..\modules\amr_dec\amr_nb\prm2bits.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\sp_enc.h"\ - "..\..\modules\amr_dec\amr_nb\ton_stab.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\vad.h"\ - "..\..\modules\amr_dec\amr_nb\vad1.h"\ - "..\..\modules\amr_dec\amr_nb\vad2.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sp_enc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\spreproc.c -DEP_CPP_SPREP=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\residu.h"\ - "..\..\modules\amr_dec\amr_nb\spreproc.h"\ - "..\..\modules\amr_dec\amr_nb\syn_filt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\weight_a.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\spreproc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\spstproc.c -DEP_CPP_SPSTP=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\spstproc.h"\ - "..\..\modules\amr_dec\amr_nb\syn_filt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\spstproc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sqrt_l.c -DEP_CPP_SQRT_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\sqrt_l.h"\ - "..\..\modules\amr_dec\amr_nb\sqrt_l.tab"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sqrt_l.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\strfunc.c -DEP_CPP_STRFU=\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\strfunc.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\strfunc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\syn_filt.c -DEP_CPP_SYN_F=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\syn_filt.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\syn_filt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ton_stab.c -DEP_CPP_TON_S=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\copy.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\set_zero.h"\ - "..\..\modules\amr_dec\amr_nb\ton_stab.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ton_stab.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\typedef.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\typedefs.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad1.c -DEP_CPP_VAD1_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst_vad.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\vad.h"\ - "..\..\modules\amr_dec\amr_nb\vad1.h"\ - "..\..\modules\amr_dec\amr_nb\vad2.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad1.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad2.c -DEP_CPP_VAD2_=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\log2.h"\ - "..\..\modules\amr_dec\amr_nb\oper_32b.h"\ - "..\..\modules\amr_dec\amr_nb\pow2.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\vad2.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad2.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vadname.c -DEP_CPP_VADNA=\ - "..\..\modules\amr_dec\amr_nb\vadname.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vadname.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\weight_a.c -DEP_CPP_WEIGH=\ - "..\..\include\gpac\setup.h"\ - "..\..\modules\amr_dec\amr_nb\basic_op.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\count.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - "..\..\modules\amr_dec\amr_nb\weight_a.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\weight_a.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_dec.c -DEP_CPP_AMR_D=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\amr_dec\amr_nb\agc.h"\ - "..\..\modules\amr_dec\amr_nb\bgnscd.h"\ - "..\..\modules\amr_dec\amr_nb\c_g_aver.h"\ - "..\..\modules\amr_dec\amr_nb\cnst.h"\ - "..\..\modules\amr_dec\amr_nb\d_homing.h"\ - "..\..\modules\amr_dec\amr_nb\d_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\dec_amr.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_dec.h"\ - "..\..\modules\amr_dec\amr_nb\dtx_enc.h"\ - "..\..\modules\amr_dec\amr_nb\ec_gains.h"\ - "..\..\modules\amr_dec\amr_nb\gc_pred.h"\ - "..\..\modules\amr_dec\amr_nb\lsp_avg.h"\ - "..\..\modules\amr_dec\amr_nb\mode.h"\ - "..\..\modules\amr_dec\amr_nb\ph_disp.h"\ - "..\..\modules\amr_dec\amr_nb\post_pro.h"\ - "..\..\modules\amr_dec\amr_nb\preemph.h"\ - "..\..\modules\amr_dec\amr_nb\pstfilt.h"\ - "..\..\modules\amr_dec\amr_nb\q_plsf.h"\ - "..\..\modules\amr_dec\amr_nb\sp_dec.h"\ - "..\..\modules\amr_dec\amr_nb\typedef.h"\ - "..\..\modules\amr_dec\amr_nb\typedefs.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_dec.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_in.c -DEP_CPP_AMR_I=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# End Target -# End Project diff --git a/build/msevc3/bifs_dec.vcp b/build/msevc3/bifs_dec.vcp deleted file mode 100644 index 6686062..0000000 --- a/build/msevc3/bifs_dec.vcp +++ /dev/null @@ -1,133 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="bifs_dec" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=bifs_dec - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "bifs_dec.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "bifs_dec.vcn" CFG="bifs_dec - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "bifs_dec - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "bifs_dec - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "bifs_dec - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/bifs_dec_rel" -# PROP Intermediate_Dir "obj/bifs_dec_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "BIFS_DEC_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_bifs_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "bifs_dec - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/bifs_dec_deb" -# PROP Intermediate_Dir "obj/bifs_dec_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "BIFS_DEC_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_bifs_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "bifs_dec - Win32 (WCE ARM) Release" -# Name "bifs_dec - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\bifs_dec\bifs_dec.c -DEP_CPP_BIFS_=\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\bifs_dec\bifs_dec.def -# End Source File -# End Target -# End Project diff --git a/build/msevc3/ctx_load.vcp b/build/msevc3/ctx_load.vcp deleted file mode 100644 index 4057d46..0000000 --- a/build/msevc3/ctx_load.vcp +++ /dev/null @@ -1,135 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="ctx_load" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=ctx_load - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ctx_load.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ctx_load.vcn" CFG="ctx_load - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ctx_load - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "ctx_load - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ctx_load - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/ctx_load_rel" -# PROP Intermediate_Dir "obj/ctx_load_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "CTX_LOAD_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_ctx_load.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "ctx_load - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/ctx_load_deb" -# PROP Intermediate_Dir "obj/ctx_load_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "CTX_LOAD_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_ctx_load.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "ctx_load - Win32 (WCE ARM) Release" -# Name "ctx_load - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\ctx_load\ctx_load.c -DEP_CPP_CTX_L=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scene_manager.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ctx_load\ctx_load.def -# End Source File -# End Target -# End Project diff --git a/build/msevc3/dummy_in.vcp b/build/msevc3/dummy_in.vcp deleted file mode 100644 index 11d09ba..0000000 --- a/build/msevc3/dummy_in.vcp +++ /dev/null @@ -1,122 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="dummy_in" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=dummy_in - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "dummy_in.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "dummy_in.vcn" CFG="dummy_in - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "dummy_in - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "dummy_in - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "dummy_in - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/dum_in_rel" -# PROP Intermediate_Dir "obj/dum_in_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "DUMMY_IN_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_dummy_in.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "dummy_in - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/dum_in_deb" -# PROP Intermediate_Dir "obj/dum_in_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "DUMMY_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_dummy_in.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "dummy_in - Win32 (WCE ARM) Release" -# Name "dummy_in - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\dummy_in\dummy_in.c -DEP_CPP_DUMMY=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dummy_in\dummy_in.def -# End Source File -# End Target -# End Project diff --git a/build/msevc3/ft_font.vcp b/build/msevc3/ft_font.vcp deleted file mode 100644 index b248ec4..0000000 --- a/build/msevc3/ft_font.vcp +++ /dev/null @@ -1,129 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="ft_font" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=ft_font - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ft_font.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ft_font.vcn" CFG="ft_font - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ft_font - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "ft_font - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ft_font - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/freetype_rel" -# PROP Intermediate_Dir "obj/freetype_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "FT_FONT_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /I "../../extra_lib/include/freetype" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 freetype.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_ft_font.dll" /libpath:"../../extra_lib/lib/arm_ppc02_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "ft_font - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/freetype_deb" -# PROP Intermediate_Dir "obj/freetype_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "FT_FONT_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/freetype" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 freetype.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_ft_font.dll" /libpath:"../../extra_lib/lib/arm_ppc02_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "ft_font - Win32 (WCE ARM) Release" -# Name "ft_font - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\ft_font\ft_font.c -DEP_CPP_FT_FO=\ - "..\..\extra_lib\include\freetype\freetype\config\ftheader.h"\ - "..\..\extra_lib\include\freetype\ft2build.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\font.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - "..\..\modules\ft_font\ft_font.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ft_font\ft_font.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ft_font\ft_font.h -# End Source File -# End Target -# End Project diff --git a/build/msevc3/gapi.vcp b/build/msevc3/gapi.vcp deleted file mode 100644 index 0d95280..0000000 --- a/build/msevc3/gapi.vcp +++ /dev/null @@ -1,134 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="gapi" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=gapi - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "gapi.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "gapi.vcn" CFG="gapi - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "gapi - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "gapi - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gapi - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/gapi_rel" -# PROP Intermediate_Dir "obj/gapi_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /I "../../extra_lib/include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 gx.lib commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 gx.lib libGLES_CM.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /out:"../../bin/arm_ppc02_rel/gm_gapi.dll" /libpath:"../../extra_lib/lib/arm_ppc02_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "gapi - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/gapi_deb" -# PROP Intermediate_Dir "obj/gapi_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 gx.lib commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 gx.lib libGLES_CM.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_gapi.dll" /libpath:"../../extra_lib/lib/arm_ppc02_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# SUBTRACT LINK32 /pdb:none - -!ENDIF - -# Begin Target - -# Name "gapi - Win32 (WCE ARM) Release" -# Name "gapi - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\gapi\gapi.cpp -DEP_CPP_GAPI_=\ - "..\..\extra_lib\include\GLES\egl.h"\ - "..\..\extra_lib\include\GLES\gl.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\events.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\gapi\gapi.h"\ - {$(INCLUDE)}"aygshell.h"\ - {$(INCLUDE)}"gx.h"\ - {$(INCLUDE)}"sipapi.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\gapi\gapi.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\gapi\gapi.h -# End Source File -# End Target -# End Project diff --git a/build/msevc3/img_in.vcp b/build/msevc3/img_in.vcp deleted file mode 100644 index cdaf67b..0000000 --- a/build/msevc3/img_in.vcp +++ /dev/null @@ -1,214 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="img_in" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=img_in - Win32 (WCE ARM) Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "img_in.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "img_in.vcn" CFG="img_in - Win32 (WCE ARM) Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "img_in - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "img_in - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "img_in - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/img_in_rel" -# PROP Intermediate_Dir "obj/img_in_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "IMG_IN_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /I "../../extra_lib/include/png" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/jpeg" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAC_HAS_PNG" /D "GPAC_HAS_JPEG" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 libpng.lib zlib.lib libjpeg.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_img_in.dll" /libpath:"../../extra_lib/lib/arm_ppc02_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "img_in - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/img_in_deb" -# PROP Intermediate_Dir "obj/img_in_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "IMG_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/png" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/jpeg" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GPAC_HAS_PNG" /D "GPAC_HAS_JPEG" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 libpng.lib zlib.lib libjpeg.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_img_in.dll" /libpath:"../../extra_lib/lib/arm_ppc02_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "img_in - Win32 (WCE ARM) Release" -# Name "img_in - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\img_in\bmp_dec.c -DEP_CPP_BMP_D=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\img_in\img_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\img_dec.c -DEP_CPP_IMG_D=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\img_in\img_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\img_in.c -DEP_CPP_IMG_I=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\img_in\img_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\img_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\img_in.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\jpeg_dec.c -DEP_CPP_JPEG_=\ - "..\..\extra_lib\include\jpeg\jconfig.h"\ - "..\..\extra_lib\include\jpeg\jmorecfg.h"\ - "..\..\extra_lib\include\jpeg\jpeglib.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\img_in\img_in.h"\ - -NODEP_CPP_JPEG_=\ - "..\..\extra_lib\include\jpeg\jerror.h"\ - "..\..\extra_lib\include\jpeg\jpegint.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\png_dec.c -DEP_CPP_PNG_D=\ - "..\..\extra_lib\include\png\png.h"\ - "..\..\extra_lib\include\png\pngconf.h"\ - "..\..\extra_lib\include\zlib\zconf.h"\ - "..\..\extra_lib\include\zlib\zlib.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\img_in\img_in.h"\ - -NODEP_CPP_PNG_D=\ - "..\..\extra_lib\include\png\alloc.h"\ - -# End Source File -# End Target -# End Project diff --git a/build/msevc3/isom_in.vcp b/build/msevc3/isom_in.vcp deleted file mode 100644 index 43972db..0000000 --- a/build/msevc3/isom_in.vcp +++ /dev/null @@ -1,190 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="isom_in" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=isom_in - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "isom_in.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "isom_in.vcn" CFG="isom_in - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "isom_in - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "isom_in - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "isom_in - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/isom_in_rel" -# PROP Intermediate_Dir "obj/isom_in_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "isom_in_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_isom_in.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "isom_in - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/isom_in_deb" -# PROP Intermediate_Dir "obj/isom_in_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "isom_in_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_isom_in.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "isom_in - Win32 (WCE ARM) Release" -# Name "isom_in - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\isom_in\cache.c -DEP_CPP_CACHE=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\isom_in\isom_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\isom_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\isom_in.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\load.c -DEP_CPP_LOAD_=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\isom_in\isom_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\read.c -DEP_CPP_READ_=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\isom_in\isom_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\read_ch.c -DEP_CPP_READ_C=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\isom_in\isom_in.h"\ - -# End Source File -# End Target -# End Project diff --git a/build/msevc3/laser_dec.vcp b/build/msevc3/laser_dec.vcp deleted file mode 100644 index 0bc122b..0000000 --- a/build/msevc3/laser_dec.vcp +++ /dev/null @@ -1,147 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="laser_dec" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=laser_dec - Win32 (WCE ARM) Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "laser_dec.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "laser_dec.vcn" CFG="laser_dec - Win32 (WCE ARM) Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "laser_dec - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "laser_dec - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "laser_dec - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/laser_dec_rel" -# PROP Intermediate_Dir "obj/laser_dec_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /GX- /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "LASER_DEC_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /GX- /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /YX /Oxs /M$(CECrtMT) /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_laser_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "laser_dec - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/laser_dec_deb" -# PROP Intermediate_Dir "obj/laser_dec_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /GX- /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "LASER_DEC_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /GX- /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /YX /M$(CECrtMTDebug) /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_laser_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "laser_dec - Win32 (WCE ARM) Release" -# Name "laser_dec - Win32 (WCE ARM) Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\modules\laser_dec\laser_dec.c -DEP_CPP_LASER=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\laser.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\laser_dec\laser_dec.def -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/msevc3/libgpac.vcp b/build/msevc3/libgpac.vcp deleted file mode 100644 index a5f7f90..0000000 --- a/build/msevc3/libgpac.vcp +++ /dev/null @@ -1,3862 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="libgpac" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Static Library" 0x8504 - -CFG=libgpac - Win32 (WCE ARM) Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "libgpac.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "libgpac.vcn" CFG="libgpac - Win32 (WCE ARM) Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libgpac - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Static Library") -!MESSAGE "libgpac - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe - -!IF "$(CFG)" == "libgpac - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/libgpac_rel" -# PROP Intermediate_Dir "obj/libgpac_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "NDEBUG" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/js" /D "NDEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /D "GPAC_HAS_SPIDERMONKEY" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX /Yc /Yu -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo - -!ELSEIF "$(CFG)" == "libgpac - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/libgpac_deb" -# PROP Intermediate_Dir "obj/libgpac_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/js" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /D "GPAC_HAS_SPIDERMONKEY" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX /Yc /Yu -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo - -!ENDIF - -# Begin Target - -# Name "libgpac - Win32 (WCE ARM) Release" -# Name "libgpac - Win32 (WCE ARM) Debug" -# Begin Group "utils" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\utils\base_encoding.c -DEP_CPP_BASE_=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\bitstream.c -DEP_CPP_BITST=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\color.c -DEP_CPP_COLOR=\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\configfile.c -DEP_CPP_CONFI=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\downloader.c -DEP_CPP_DOWNL=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\token.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\error.c -DEP_CPP_ERROR=\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\list.c -DEP_CPP_LIST_=\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\math.c -DEP_CPP_MATH_=\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\setup.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\module.c -DEP_CPP_MODUL=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\utils\module_wrap.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\module_wrap.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\os_divers.c -DEP_CPP_OS_DI=\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\os_module.c -DEP_CPP_OS_MO=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\utils\module_wrap.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\os_net.c -DEP_CPP_OS_NE=\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\os_thread.c -DEP_CPP_OS_TH=\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\path2d.c -DEP_CPP_PATH2=\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\path2d_stroker.c -DEP_CPP_PATH2D=\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\token.c -DEP_CPP_TOKEN=\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\token.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\url.c -DEP_CPP_URL_C=\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\utf.c -DEP_CPP_UTF_C=\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\xml_parser.c -DEP_CPP_XML_P=\ - "..\..\extra_lib\include\zlib\zconf.h"\ - "..\..\extra_lib\include\zlib\zlib.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - "..\..\include\gpac\xml.h"\ - -# End Source File -# End Group -# Begin Group "odf" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\odf\desc_private.c -DEP_CPP_DESC_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\descriptors.c -DEP_CPP_DESCR=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\ipmpx_code.c -DEP_CPP_IPMPX=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\ipmpx_dump.c -DEP_CPP_IPMPX_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\ipmpx_parse.c -DEP_CPP_IPMPX_P=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\oci_codec.c -DEP_CPP_OCI_C=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_code.c -DEP_CPP_ODF_C=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_codec.c -DEP_CPP_ODF_CO=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_command.c -DEP_CPP_ODF_COM=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\odf_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_dump.c -DEP_CPP_ODF_D=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_parse.c -DEP_CPP_ODF_P=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\token.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\qos.c -DEP_CPP_QOS_C=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\slc.c -DEP_CPP_SLC_C=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# End Group -# Begin Group "bifs" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\bifs\arith_decoder.c -DEP_CPP_ARITH=\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\quant.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\bifs_codec.c -DEP_CPP_BIFS_=\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\bifs_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\bifs_node_tables.c -DEP_CPP_BIFS_N=\ - "..\..\include\gpac\internal\bifs_tables.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\bifs_tables.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\com_dec.c -DEP_CPP_COM_D=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\quant.h"\ - -NODEP_CPP_COM_D=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\com_enc.c -DEP_CPP_COM_E=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\quant.h"\ - -NODEP_CPP_COM_E=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\conditional.c -DEP_CPP_CONDI=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_CONDI=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\field_decode.c -DEP_CPP_FIELD=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\quant.h"\ - "..\..\src\bifs\script.h"\ - -NODEP_CPP_FIELD=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\field_encode.c -DEP_CPP_FIELD_=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\bifs_tables.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\quant.h"\ - "..\..\src\bifs\script.h"\ - -NODEP_CPP_FIELD_=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\memory_decoder.c -DEP_CPP_MEMOR=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\quant.h"\ - -NODEP_CPP_MEMOR=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\predictive_mffield.c -DEP_CPP_PREDI=\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\quant.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\quant.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\quantize.c -DEP_CPP_QUANT=\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\quant.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\script.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\script_dec.c -DEP_CPP_SCRIP=\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\script.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\script_enc.c -DEP_CPP_SCRIPT=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\script.h"\ - -NODEP_CPP_SCRIPT=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\unquantize.c -DEP_CPP_UNQUA=\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\bifs\quant.h"\ - -# End Source File -# End Group -# Begin Group "isomedia" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\isomedia\avc_ext.c -DEP_CPP_AVC_E=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_3gpp.c -DEP_CPP_BOX_C=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_apple.c -DEP_CPP_BOX_CO=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_base.c -DEP_CPP_BOX_COD=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_isma.c -DEP_CPP_BOX_CODE=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_meta.c -DEP_CPP_BOX_CODE_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_dump.c -DEP_CPP_BOX_D=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_funcs.c -DEP_CPP_BOX_F=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\data_map.c -DEP_CPP_DATA_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\hint_track.c -DEP_CPP_HINT_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\hinting.c -DEP_CPP_HINTI=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isma_sample.c -DEP_CPP_ISMA_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isom_intern.c -DEP_CPP_ISOM_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isom_read.c -DEP_CPP_ISOM_R=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isom_store.c -DEP_CPP_ISOM_S=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isom_write.c -DEP_CPP_ISOM_W=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\isomedia_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\media.c -DEP_CPP_MEDIA=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\media_odf.c -DEP_CPP_MEDIA_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\meta.c -DEP_CPP_META_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\movie_fragments.c -DEP_CPP_MOVIE=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\sample_descs.c -DEP_CPP_SAMPL=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\stbl_read.c -DEP_CPP_STBL_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\stbl_write.c -DEP_CPP_STBL_W=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\track.c -DEP_CPP_TRACK=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\tx3g.c -DEP_CPP_TX3G_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# End Group -# Begin Group "ietf" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\include\gpac\internal\ietf_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtcp.c -DEP_CPP_RTCP_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp.c -DEP_CPP_RTP_C=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp_packetizer.c -DEP_CPP_RTP_P=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp_pck_3gpp.c -DEP_CPP_RTP_PC=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp_pck_mpeg12.c -DEP_CPP_RTP_PCK=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp_pck_mpeg4.c -DEP_CPP_RTP_PCK_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtsp_command.c -DEP_CPP_RTSP_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\token.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtsp_common.c -DEP_CPP_RTSP_C=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\token.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtsp_response.c -DEP_CPP_RTSP_R=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\token.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtsp_session.c -DEP_CPP_RTSP_S=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\ietf_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\sdp.c -DEP_CPP_SDP_C=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\token.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# End Group -# Begin Group "scenegraph" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\scenegraph\base_scenegraph.c -DEP_CPP_BASE_S=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_BASE_S=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\commands.c -DEP_CPP_COMMA=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_COMMA=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\dom_events.c -DEP_CPP_DOM_E=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_DOM_E=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\mpeg4_animators.c -DEP_CPP_MPEG4=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_MPEG4=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\mpeg4_nodes.c -DEP_CPP_MPEG4_=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_MPEG4_=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\mpeg4_valuator.c -DEP_CPP_MPEG4_V=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_MPEG4_V=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\scenegraph_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\smil_anim.c -DEP_CPP_SMIL_=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_SMIL_=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\smil_timing.c -DEP_CPP_SMIL_T=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_SMIL_T=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_attributes.c -DEP_CPP_SVG_A=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_SVG_A=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_nodes.c -DEP_CPP_SVG_N=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_SVG_N=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_properties.c -DEP_CPP_SVG_P=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_SVG_P=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_smjs.c -DEP_CPP_SVG_S=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_SVG_S=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_tools.c -DEP_CPP_SVG_T=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_SVG_T=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_types.c -DEP_CPP_SVG_TY=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_SVG_TY=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_interpolators.c -DEP_CPP_VRML_=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_VRML_=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_proto.c -DEP_CPP_VRML_P=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_VRML_P=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_route.c -DEP_CPP_VRML_R=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_VRML_R=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_script.c -DEP_CPP_VRML_S=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_VRML_S=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_smjs.c -DEP_CPP_VRML_SM=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_VRML_SM=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_tools.c -DEP_CPP_VRML_T=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_VRML_T=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\x3d_nodes.c -DEP_CPP_X3D_N=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_X3D_N=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# End Group -# Begin Group "media_tools" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\media_tools\av_parsers.c -DEP_CPP_AV_PA=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\media_dev.h"\ - "..\..\include\gpac\internal\ogg.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\avilib.c -DEP_CPP_AVILI=\ - "..\..\include\gpac\internal\avilib.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\avilib.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\gpac_ogg.c -DEP_CPP_GPAC_=\ - "..\..\include\gpac\internal\ogg.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\ismacryp.c -DEP_CPP_ISMAC=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\ismacryp.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\xml.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\ismacryp.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\isom_hinter.c -DEP_CPP_ISOM_H=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\isom_tools.c -DEP_CPP_ISOM_T=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\media_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\media_export.c -DEP_CPP_MEDIA_E=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\avilib.h"\ - "..\..\include\gpac\internal\media_dev.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\internal\ogg.h"\ - "..\..\include\gpac\internal\vobsub.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\mpegts.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\media_import.c -DEP_CPP_MEDIA_I=\ - "..\..\extra_lib\include\zlib\zconf.h"\ - "..\..\extra_lib\include\zlib\zlib.h"\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\avilib.h"\ - "..\..\include\gpac\internal\media_dev.h"\ - "..\..\include\gpac\internal\odf_dev.h"\ - "..\..\include\gpac\internal\ogg.h"\ - "..\..\include\gpac\internal\vobsub.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\mpegts.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\xml.h"\ - "..\..\src\media_tools\mpeg2_ps.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\mpeg2_ps.c -DEP_CPP_MPEG2=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\src\media_tools\mpeg2_ps.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\mpeg2_ps.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\ogg.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\text_import.c -DEP_CPP_TEXT_=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\media_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\token.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - "..\..\include\gpac\xml.h"\ - -# End Source File -# End Group -# Begin Group "scene_manager" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\scene_manager\encode_cbk.c -DEP_CPP_ENCOD=\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bifsengine.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scene_manager.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\encode_isom.c -DEP_CPP_ENCODE=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\laser.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.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\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_ENCODE=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_bt.c -DEP_CPP_LOADE=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\extra_lib\include\zlib\zconf.h"\ - "..\..\extra_lib\include\zlib\zlib.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.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\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\include\gpac\utf.h"\ - -NODEP_CPP_LOADE=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_isom.c -DEP_CPP_LOADER=\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\laser.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.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\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_qt.c -DEP_CPP_LOADER_=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\media_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scene_manager.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_svg.c -DEP_CPP_LOADER_S=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.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\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - "..\..\include\gpac\xml.h"\ - -NODEP_CPP_LOADER_S=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_xmt.c -DEP_CPP_LOADER_X=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.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\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - "..\..\include\gpac\xml.h"\ - "..\..\src\bifs\quant.h"\ - -NODEP_CPP_LOADER_X=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\scene_dump.c -DEP_CPP_SCENE=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.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\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - "..\..\src\bifs\quant.h"\ - -NODEP_CPP_SCENE=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\scene_manager.c -DEP_CPP_SCENE_=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bifs.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.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\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\xml.h"\ - -NODEP_CPP_SCENE_=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\scene_stats.c -DEP_CPP_SCENE_S=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\path2d.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\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_SCENE_S=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\swf_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\swf_parse.c -DEP_CPP_SWF_P=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\swf_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scene_manager.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\swf_shape.c -DEP_CPP_SWF_S=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\swf_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scene_manager.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\text_to_bifs.c -DEP_CPP_TEXT_T=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\media_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\scene_manager.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\utf.h"\ - "..\..\include\gpac\xml.h"\ - -# End Source File -# End Group -# Begin Group "mcrypt" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\mcrypt\cbc.c -DEP_CPP_CBC_C=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\cfb.c -DEP_CPP_CFB_C=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\crypt_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\ctr.c -DEP_CPP_CTR_C=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\des.c -DEP_CPP_DES_C=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\ecb.c -DEP_CPP_ECB_C=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\g_crypt.c -DEP_CPP_G_CRY=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\ncfb.c -DEP_CPP_NCFB_=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\nofb.c -DEP_CPP_NOFB_=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\ofb.c -DEP_CPP_OFB_C=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE="..\..\src\mcrypt\rijndael-128.c" -DEP_CPP_RIJND=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE="..\..\src\mcrypt\rijndael-192.c" -DEP_CPP_RIJNDA=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE="..\..\src\mcrypt\rijndael-256.c" -DEP_CPP_RIJNDAE=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\stream.c -DEP_CPP_STREA=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\tripledes.c -DEP_CPP_TRIPL=\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\crypt_dev.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# End Group -# Begin Group "terminal" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\terminal\channel.c -DEP_CPP_CHANN=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\ismacryp.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\media_memory.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\clock.c -DEP_CPP_CLOCK=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\decoder.c -DEP_CPP_DECOD=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.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\raster2d.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\input_sensor.h"\ - "..\..\src\terminal\media_control.h"\ - "..\..\src\terminal\media_memory.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\inline.c -DEP_CPP_INLIN=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\media_control.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\input_sensor.c -DEP_CPP_INPUT=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\include\gpac\utf.h"\ - "..\..\src\terminal\input_sensor.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\input_sensor.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_control.c -DEP_CPP_MEDIA_C=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\media_control.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_control.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_manager.c -DEP_CPP_MEDIA_M=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\media_memory.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_memory.c -DEP_CPP_MEDIA_ME=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\media_control.h"\ - "..\..\src\terminal\media_memory.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_memory.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_object.c -DEP_CPP_MEDIA_O=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\media_control.h"\ - "..\..\src\terminal\media_memory.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_sensor.c -DEP_CPP_MEDIA_S=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\media_control.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\network_service.c -DEP_CPP_NETWO=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\object_browser.c -DEP_CPP_OBJEC=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.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\sync_layer.h"\ - "..\..\include\gpac\term_info.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\media_memory.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\object_manager.c -DEP_CPP_OBJECT=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\input_sensor.h"\ - "..\..\src\terminal\media_control.h"\ - "..\..\src\terminal\media_memory.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\svg_external.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\term_node_init.c -DEP_CPP_TERM_=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\terminal\input_sensor.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\terminal.c -DEP_CPP_TERMI=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.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\raster2d.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\options.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scene_manager.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\terminal_dev.h -# End Source File -# End Group -# Begin Group "renderer" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\renderer\audio_input.c -DEP_CPP_AUDIO=\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\audio_out.h"\ - "..\..\include\gpac\modules\font.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\renderer\audio_mixer.c -DEP_CPP_AUDIO_=\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\audio_out.h"\ - "..\..\include\gpac\modules\font.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\renderer\audio_render.c -DEP_CPP_AUDIO_R=\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\audio_out.h"\ - "..\..\include\gpac\modules\font.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\renderer\audio_stacks.c -DEP_CPP_AUDIO_S=\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\audio_out.h"\ - "..\..\include\gpac\modules\font.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\renderer\common_stacks.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\renderer\base_textures.c -DEP_CPP_BASE_T=\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\audio_out.h"\ - "..\..\include\gpac\modules\font.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\renderer\common_stacks.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\renderer\common_stacks.c -DEP_CPP_COMMO=\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\audio_out.h"\ - "..\..\include\gpac\modules\font.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\src\renderer\common_stacks.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\renderer\common_stacks.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\renderer\renderer.c -DEP_CPP_RENDE=\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\audio_out.h"\ - "..\..\include\gpac\modules\font.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\options.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\renderer_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\renderer\texturing.c -DEP_CPP_TEXTU=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\renderer_dev.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.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\raster2d.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\modules\video_out.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\options.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\renderer.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# End Group -# Begin Group "laser" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\include\gpac\internal\laser_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\laser\lsr_dec.c -DEP_CPP_LSR_D=\ - "..\..\extra_lib\include\js\jsapi.h"\ - "..\..\extra_lib\include\js\jsautocfg.h"\ - "..\..\extra_lib\include\js\jscompat.h"\ - "..\..\extra_lib\include\js\jscpucfg.h"\ - "..\..\extra_lib\include\js\jslong.h"\ - "..\..\extra_lib\include\js\jsosdep.h"\ - "..\..\extra_lib\include\js\jsotypes.h"\ - "..\..\extra_lib\include\js\jspubtd.h"\ - "..\..\extra_lib\include\js\jstypes.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\laser_dev.h"\ - "..\..\include\gpac\internal\scenegraph_dev.h"\ - "..\..\include\gpac\laser.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -NODEP_CPP_LSR_D=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\laser\lsr_enc.c -DEP_CPP_LSR_E=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\laser_dev.h"\ - "..\..\include\gpac\laser.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\laser\lsr_tables.c -DEP_CPP_LSR_T=\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\nodes_svg.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_svg.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# End Group -# Begin Group "include" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\include\gpac\modules\audio_out.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\avparse.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\base_coding.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\bifs.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\bifsengine.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\bitstream.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\codec.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\config.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\constants.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\crypt.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\download.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\font.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\ietf.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\isomedia.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\list.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\math.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\media_tools.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\mediaobject.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\module.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\mpeg4_odf.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\network.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\nodes_mpeg4.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\nodes_svg.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\nodes_x3d.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\options.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\path2d.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\raster2d.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\renderer.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\scene_manager.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\scenegraph.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\scenegraph_svg.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\scenegraph_vrml.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\service.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\setup.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\terminal.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\thread.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\token.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\tools.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\user.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\utf.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\video_out.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\xml.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\yuv.h -# End Source File -# End Group -# End Target -# End Project diff --git a/build/msevc3/libgpac_dll.vcp b/build/msevc3/libgpac_dll.vcp deleted file mode 100644 index 8478959..0000000 --- a/build/msevc3/libgpac_dll.vcp +++ /dev/null @@ -1,104 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="libgpac_dll" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=libgpac_dll - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "libgpac_dll.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "libgpac_dll.vcn" CFG="libgpac_dll - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libgpac_dll - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "libgpac_dll - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "libgpac_dll - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/libgpac_dll_deb" -# PROP Intermediate_Dir "obj/libgpac_dll_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "LIBGPAC_DLL_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "LIBGPAC_DLL_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 zlib.lib js.lib winsock.lib toolhelp.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /out:"../../bin/arm_ppc02_deb/libgpac.dll" /libpath:"../../extra_lib/lib/arm_ppc02_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "libgpac_dll - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/libgpac_dll_rel" -# PROP Intermediate_Dir "obj/libgpac_dll_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /YX /Oxs /M$(CECrtMT) /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 zlib.lib js.lib winsock.lib toolhelp.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /out:"../../bin/arm_ppc02_rel/libgpac.dll" /libpath:"../../extra_lib/lib/arm_ppc02_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "libgpac_dll - Win32 (WCE ARM) Debug" -# Name "libgpac_dll - Win32 (WCE ARM) Release" -# Begin Source File - -SOURCE=..\..\src\libgpac_ce.def -# End Source File -# End Target -# End Project diff --git a/build/msevc3/mp3_in.vcp b/build/msevc3/mp3_in.vcp deleted file mode 100644 index 0b11f2f..0000000 --- a/build/msevc3/mp3_in.vcp +++ /dev/null @@ -1,137 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="mp3_in" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=mp3_in - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mp3_in.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mp3_in.vcn" CFG="mp3_in - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mp3_in - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "mp3_in - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mp3_in - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/mp3_in_rel" -# PROP Intermediate_Dir "obj/mp3_in_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "MP3_IN_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /I "../../extra_lib/include/mad" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAC_HAS_MAD" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 libmad.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_mp3_in.dll" /libpath:"../../extra_lib/lib/arm_ppc02_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "mp3_in - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/mp3_in_deb" -# PROP Intermediate_Dir "obj/mp3_in_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "MP3_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/mad" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GPAC_HAS_MAD" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 libmad.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_mp3_in.dll" /libpath:"../../extra_lib/lib/arm_ppc02_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "mp3_in - Win32 (WCE ARM) Release" -# Name "mp3_in - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\mp3_in\mad_dec.c -DEP_CPP_MAD_D=\ - "..\..\extra_lib\include\mad\mad.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\mp3_in\mp3_in.c -DEP_CPP_MP3_I=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\mp3_in\mp3_in.def -# End Source File -# End Target -# End Project diff --git a/build/msevc3/odf_dec.vcp b/build/msevc3/odf_dec.vcp deleted file mode 100644 index 8e3b2a6..0000000 --- a/build/msevc3/odf_dec.vcp +++ /dev/null @@ -1,132 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="odf_dec" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=odf_dec - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "odf_dec.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "odf_dec.vcn" CFG="odf_dec - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "odf_dec - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "odf_dec - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "odf_dec - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/odf_dec_rel" -# PROP Intermediate_Dir "obj/odf_dec_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "odf_dec_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_odf_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "odf_dec - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/odf_dec_deb" -# PROP Intermediate_Dir "obj/odf_dec_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "odf_dec_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_odf_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "odf_dec - Win32 (WCE ARM) Release" -# Name "odf_dec - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\odf_dec\odf_dec.c -DEP_CPP_ODF_D=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\odf_dec\odf_dec.def -# End Source File -# End Target -# End Project diff --git a/build/msevc3/ogg.vcp b/build/msevc3/ogg.vcp deleted file mode 100644 index 1164623..0000000 --- a/build/msevc3/ogg.vcp +++ /dev/null @@ -1,198 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="ogg" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=ogg - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ogg.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ogg.vcn" CFG="ogg - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ogg - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "ogg - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ogg - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/ogg_in_rel" -# PROP Intermediate_Dir "obj/ogg_in_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "OGG_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /I "../../extra_lib/include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAC_HAS_VORBIS" /D "GPAC_HAS_THEORA" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 ogg_static.lib vorbis_static.lib theora_static.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_ogg_xiph.dll" /libpath:"../../extra_lib/lib/arm_ppc02_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "ogg - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/ogg_in_deb" -# PROP Intermediate_Dir "obj/ogg_in_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "OGG_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GPAC_HAS_VORBIS" /D "GPAC_HAS_THEORA" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 ogg_static.lib vorbis_static.lib theora_static.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_ogg_xiph.dll" /libpath:"../../extra_lib/lib/arm_ppc02_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "ogg - Win32 (WCE ARM) Release" -# Name "ogg - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\ogg\ogg.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\ogg_in.c -DEP_CPP_OGG_I=\ - "..\..\extra_lib\include\ogg\ogg.h"\ - "..\..\extra_lib\include\ogg\os_types.h"\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\ogg\ogg_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\ogg_in.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\ogg_load.c -DEP_CPP_OGG_L=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\ogg\ogg_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\theora_dec.c -DEP_CPP_THEOR=\ - "..\..\extra_lib\include\ogg\ogg.h"\ - "..\..\extra_lib\include\ogg\os_types.h"\ - "..\..\extra_lib\include\theora\theora.h"\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\ogg\ogg_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\vorbis_dec.c -DEP_CPP_VORBI=\ - "..\..\extra_lib\include\ogg\ogg.h"\ - "..\..\extra_lib\include\ogg\os_types.h"\ - "..\..\extra_lib\include\vorbis\codec.h"\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\ogg\ogg_in.h"\ - -# End Source File -# End Target -# End Project diff --git a/build/msevc3/rtp_in.vcp b/build/msevc3/rtp_in.vcp deleted file mode 100644 index a6af2c9..0000000 --- a/build/msevc3/rtp_in.vcp +++ /dev/null @@ -1,258 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="rtp_in" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=rtp_in - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "rtp_in.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "rtp_in.vcn" CFG="rtp_in - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "rtp_in - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "rtp_in - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "rtp_in - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/rtp_in_rel" -# PROP Intermediate_Dir "obj/rtp_in_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "RTP_IN_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_rtp_in.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "rtp_in - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/rtp_in_deb" -# PROP Intermediate_Dir "obj/rtp_in_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "RTP_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_rtp_in.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "rtp_in - Win32 (WCE ARM) Release" -# Name "rtp_in - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_in.c -DEP_CPP_RTP_I=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\rtp_in\rtp_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_in.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_payloads.c -DEP_CPP_RTP_P=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\rtp_in\rtp_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_session.c -DEP_CPP_RTP_S=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\rtp_in\rtp_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_signaling.c -DEP_CPP_RTP_SI=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\rtp_in\rtp_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_stream.c -DEP_CPP_RTP_ST=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\rtp_in\rtp_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\sdp_fetch.c -DEP_CPP_SDP_F=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\rtp_in\rtp_in.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\sdp_load.c -DEP_CPP_SDP_L=\ - "..\..\include\gpac\base_coding.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\network.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\rtp_in\rtp_in.h"\ - -# End Source File -# End Target -# End Project diff --git a/build/msevc3/saf_in.vcp b/build/msevc3/saf_in.vcp deleted file mode 100644 index d59edbb..0000000 --- a/build/msevc3/saf_in.vcp +++ /dev/null @@ -1,135 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="saf_in" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=saf_in - Win32 (WCE ARM) Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "saf_in.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "saf_in.vcn" CFG="saf_in - Win32 (WCE ARM) Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "saf_in - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "saf_in - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "saf_in - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/saf_in_rel" -# PROP Intermediate_Dir "obj/saf_in_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /GX- /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "SAF_IN_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /GX- /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "SAF_IN_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_saf_in.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "saf_in - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/saf_in_deb" -# PROP Intermediate_Dir "obj/saf_in_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /GX- /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "SAF_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /GX- /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "SAF_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_saf_in.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "saf_in - Win32 (WCE ARM) Release" -# Name "saf_in - Win32 (WCE ARM) Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\modules\saf_in\saf_in.c -DEP_CPP_SAF_I=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\saf_in\saf_in.def -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/msevc3/soft_raster.vcp b/build/msevc3/soft_raster.vcp deleted file mode 100644 index c31c47b..0000000 --- a/build/msevc3/soft_raster.vcp +++ /dev/null @@ -1,218 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="soft_raster" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=soft_raster - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "soft_raster.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "soft_raster.vcn" CFG="soft_raster - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "soft_raster - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "soft_raster - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "soft_raster - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/soft_rast_rel" -# PROP Intermediate_Dir "obj/soft_rast_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "soft_raster_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_soft_raster.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "soft_raster - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/soft_rast_deb" -# PROP Intermediate_Dir "obj/soft_rast_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "soft_raster_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_soft_raster.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "soft_raster - Win32 (WCE ARM) Release" -# Name "soft_raster - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\soft_raster\ftgrays.c -DEP_CPP_FTGRA=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\soft_raster\rast_soft.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\rast_soft.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\rast_soft.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_565.c -DEP_CPP_RASTE=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\soft_raster\rast_soft.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_argb.c -DEP_CPP_RASTER=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\soft_raster\rast_soft.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_load.c -DEP_CPP_RASTER_=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\soft_raster\rast_soft.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_rgb.c -DEP_CPP_RASTER_R=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\soft_raster\rast_soft.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\stencil.c -DEP_CPP_STENC=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\soft_raster\rast_soft.h"\ - -NODEP_CPP_STENC=\ - "..\..\include\gpac\yuv.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\surface.c -DEP_CPP_SURFA=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\raster2d.h"\ - "..\..\include\gpac\path2d.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\soft_raster\rast_soft.h"\ - -# End Source File -# End Target -# End Project diff --git a/build/msevc3/svg_in.vcp b/build/msevc3/svg_in.vcp deleted file mode 100644 index 4dda385..0000000 --- a/build/msevc3/svg_in.vcp +++ /dev/null @@ -1,145 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="svg_in" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=svg_in - Win32 (WCE ARM) Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "svg_in.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "svg_in.vcn" CFG="svg_in - Win32 (WCE ARM) Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "svg_in - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "svg_in - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "svg_in - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/svg_in_rel" -# PROP Intermediate_Dir "obj/svg_in_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "SVG_IN_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /I "../../include" /I "../../extra_lib/include/zlib" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "SVG_IN_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 zlib.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_svg_in.dll" /libpath:"../../extra_lib/lib/arm_ppc02_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "svg_in - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/svg_in_deb" -# PROP Intermediate_Dir "obj/svg_in_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "SVG_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/zlib" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "SVG_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 zlib.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_svg_in.dll" /libpath:"../../extra_lib/lib/arm_ppc02_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "svg_in - Win32 (WCE ARM) Release" -# Name "svg_in - Win32 (WCE ARM) Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\modules\svg_in\svg_in.c -DEP_CPP_SVG_I=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\scene_manager.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\svg_in\svg_in.def -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/msevc3/timedtext.vcp b/build/msevc3/timedtext.vcp deleted file mode 100644 index 3bdaf2a..0000000 --- a/build/msevc3/timedtext.vcp +++ /dev/null @@ -1,155 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="timedtext" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=timedtext - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "timedtext.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "timedtext.vcn" CFG="timedtext - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "timedtext - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "timedtext - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "timedtext - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/ttxt_rel" -# PROP Intermediate_Dir "obj/ttxt_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "TIMEDTEXT_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_timedtext.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "timedtext - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/ttxt_deb" -# PROP Intermediate_Dir "obj/ttxt_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "TIMEDTEXT_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_timedtext.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "timedtext - Win32 (WCE ARM) Release" -# Name "timedtext - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\timedtext\timedtext.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\timedtext\timedtext_dec.c -DEP_CPP_TIMED=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\isomedia_dev.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ - "..\..\include\gpac\utf.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\timedtext\timedtext_in.c -DEP_CPP_TIMEDT=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\isomedia.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\media_tools.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# End Target -# End Project diff --git a/build/msevc3/wav_out.vcp b/build/msevc3/wav_out.vcp deleted file mode 100644 index 866fee0..0000000 --- a/build/msevc3/wav_out.vcp +++ /dev/null @@ -1,118 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="wav_out" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=wav_out - Win32 (WCE ARM) Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "wav_out.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "wav_out.vcn" CFG="wav_out - Win32 (WCE ARM) Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "wav_out - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "wav_out - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "wav_out - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/wav_out_rel" -# PROP Intermediate_Dir "obj/wav_out_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "wav_out_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x100000,0x10000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_wav_out.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "wav_out - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/wav_out_deb" -# PROP Intermediate_Dir "obj/wav_out_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "wav_out_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_wav_out.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "wav_out - Win32 (WCE ARM) Release" -# Name "wav_out - Win32 (WCE ARM) Debug" -# Begin Source File - -SOURCE=..\..\modules\wav_out\wav_out.c -DEP_CPP_WAV_O=\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\audio_out.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\wav_out\wav_out.def -# End Source File -# End Target -# End Project diff --git a/build/msevc3/xvid_dec.vcp b/build/msevc3/xvid_dec.vcp deleted file mode 100644 index 0b495a2..0000000 --- a/build/msevc3/xvid_dec.vcp +++ /dev/null @@ -1,462 +0,0 @@ -# Microsoft eMbedded Visual Tools Project File - Name="xvid_dec" - Package Owner=<4> -# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (WCE ARM) Dynamic-Link Library" 0x8502 - -CFG=xvid_dec - Win32 (WCE ARM) Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "xvid_dec.vcn". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "xvid_dec.vcn" CFG="xvid_dec - Win32 (WCE ARM) Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "xvid_dec - Win32 (WCE ARM) Release" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE "xvid_dec - Win32 (WCE ARM) Debug" (based on "Win32 (WCE ARM) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -# PROP ATL_Project 2 -CPP=clarm.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "xvid_dec - Win32 (WCE ARM) Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ARMRel" -# PROP BASE Intermediate_Dir "ARMRel" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/xvid_dec_rel" -# PROP Intermediate_Dir "obj/xvid_dec_rel" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "NDEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "XVID_DEC_EXPORTS" /YX /Oxs /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /O2 /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /Oxs /M$(CECrtMT) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_rel/gm_xvid_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ELSEIF "$(CFG)" == "xvid_dec - Win32 (WCE ARM) Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ARMDbg" -# PROP BASE Intermediate_Dir "ARMDbg" -# PROP BASE CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/xvid_dec_deb" -# PROP Intermediate_Dir "obj/xvid_dec_deb" -# PROP CPU_ID "{D6518FFC-710F-11D3-99F2-00105A0DF099}" -# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "UNICODE" /d "_UNICODE" /d "DEBUG" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /r -# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "XVID_DEC_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc02_deb/gm_xvid_dec.dll" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM - -!ENDIF - -# Begin Target - -# Name "xvid_dec - Win32 (WCE ARM) Release" -# Name "xvid_dec - Win32 (WCE ARM) Debug" -# Begin Group "xvid_wce" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\bitstream.cpp -DEP_CPP_BITST=\ - "..\..\modules\xvid_dec\xvid_wce\bitstream.h"\ - "..\..\modules\xvid_dec\xvid_wce\decoder.h"\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\image.h"\ - "..\..\modules\xvid_dec\xvid_wce\interpolate8x8.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_transfer.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\quant_matrix.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\vlc_codes.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\bitstream.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\CodecAPI.cpp -DEP_CPP_CODEC=\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\decoder.cpp -DEP_CPP_DECOD=\ - "..\..\modules\xvid_dec\xvid_wce\decoder.h"\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\gmc.h"\ - "..\..\modules\xvid_dec\xvid_wce\image.h"\ - "..\..\modules\xvid_dec\xvid_wce\interpolate8x8.h"\ - "..\..\modules\xvid_dec\xvid_wce\mbprediction.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_align.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_transfer.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\quant.h"\ - "..\..\modules\xvid_dec\xvid_wce\quant_matrix.h"\ - "..\..\modules\xvid_dec\xvid_wce\reduced.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\vlc_codes.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\decoder.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\font.cpp -DEP_CPP_FONT_=\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\image.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\global.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\gmc.cpp -DEP_CPP_GMC_C=\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\gmc.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\gmc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\idct.cpp -DEP_CPP_IDCT_=\ - "..\..\modules\xvid_dec\xvid_wce\decoder.h"\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\image.h"\ - "..\..\modules\xvid_dec\xvid_wce\interpolate8x8.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_transfer.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\vlc_codes.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\image.cpp -DEP_CPP_IMAGE=\ - "..\..\modules\xvid_dec\xvid_wce\decoder.h"\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\image.h"\ - "..\..\modules\xvid_dec\xvid_wce\interpolate8x8.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_align.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_transfer.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\reduced.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\vlc_codes.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\image.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\interpolate8x8.cpp -DEP_CPP_INTER=\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\interpolate8x8.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_transfer.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\interpolate8x8.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\mbcoding.cpp -DEP_CPP_MBCOD=\ - "..\..\modules\xvid_dec\xvid_wce\bitstream.h"\ - "..\..\modules\xvid_dec\xvid_wce\decoder.h"\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\image.h"\ - "..\..\modules\xvid_dec\xvid_wce\interpolate8x8.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_transfer.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\vlc_codes.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\mbprediction.cpp -DEP_CPP_MBPRE=\ - "..\..\modules\xvid_dec\xvid_wce\decoder.h"\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\image.h"\ - "..\..\modules\xvid_dec\xvid_wce\interpolate8x8.h"\ - "..\..\modules\xvid_dec\xvid_wce\mbprediction.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_transfer.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\vlc_codes.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\mbprediction.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\mem_align.cpp -DEP_CPP_MEM_A=\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_align.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\mem_align.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\mem_transfer.cpp -DEP_CPP_MEM_T=\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_transfer.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\mem_transfer.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\portab.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\qpel.inl -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\qpel_tab.cpp -DEP_CPP_QPEL_=\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\qpel.inl"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\quant.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\quant_h263.cpp -DEP_CPP_QUANT=\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\quant.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\quant_matrix.cpp -DEP_CPP_QUANT_=\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\quant_matrix.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\quant_matrix.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\quant_mpeg.cpp -DEP_CPP_QUANT_M=\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\quant.h"\ - "..\..\modules\xvid_dec\xvid_wce\quant_matrix.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\reduced.cpp -DEP_CPP_REDUC=\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\reduced.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\reduced.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\Rules.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\vlc_codes.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\xvid.cpp -DEP_CPP_XVID_=\ - "..\..\modules\xvid_dec\xvid_wce\decoder.h"\ - "..\..\modules\xvid_dec\xvid_wce\global.h"\ - "..\..\modules\xvid_dec\xvid_wce\image.h"\ - "..\..\modules\xvid_dec\xvid_wce\interpolate8x8.h"\ - "..\..\modules\xvid_dec\xvid_wce\mem_transfer.h"\ - "..\..\modules\xvid_dec\xvid_wce\portab.h"\ - "..\..\modules\xvid_dec\xvid_wce\quant.h"\ - "..\..\modules\xvid_dec\xvid_wce\reduced.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\vlc_codes.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\xvid.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_wce\xvid_ppc.asm - -!IF "$(CFG)" == "xvid_dec - Win32 (WCE ARM) Release" - -# Begin Custom Build -IntDir=.\obj/xvid_dec_rel -InputPath=..\..\modules\xvid_dec\xvid_wce\xvid_ppc.asm -InputName=xvid_ppc - -"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - armasm -CPU StrongARM1 -o $(IntDir)\$(InputName).obj $(InputPath) - -# End Custom Build - -!ELSEIF "$(CFG)" == "xvid_dec - Win32 (WCE ARM) Debug" - -# Begin Custom Build -IntDir=.\obj/xvid_dec_deb -InputPath=..\..\modules\xvid_dec\xvid_wce\xvid_ppc.asm -InputName=xvid_ppc - -"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - armasm -CPU StrongARM1 -o $(IntDir)\$(InputName).obj $(InputPath) - -# End Custom Build - -!ENDIF - -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_dec.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_dec_wce.cpp -DEP_CPP_XVID_D=\ - "..\..\include\gpac\avparse.h"\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ - "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ - -# End Source File -# End Target -# End Project diff --git a/build/msevc4/GPAX.VCP b/build/msevc4/GPAX.VCP index 3fc489f..98b0646 100644 --- a/build/msevc4/GPAX.VCP +++ b/build/msevc4/GPAX.VCP @@ -50,7 +50,7 @@ RSC=rc.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAX_EXPORTS" /YX /O2 /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /Oxt /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "_ATL_STATIC_REGISTRY" /YX /M$(CECrtMT) /c +# ADD CPP /nologo /W3 /Oxt /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "_ATL_STATIC_REGISTRY" /YX /M$(CECrtMT) /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 BSC32=bscmake.exe @@ -109,7 +109,6 @@ DEP_CPP_GPAX_=\ "..\..\applications\GPAX\GPAXPlugin.h"\ "..\..\applications\GPAX\StdAfx.h"\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\math.h"\ @@ -119,7 +118,10 @@ DEP_CPP_GPAX_=\ "..\..\include\gpac\terminal.h"\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ - {$(INCLUDE)}"guiddef.h"\ + +NODEP_CPP_GPAX_=\ + "..\..\include\gpac\config.h"\ + ".\uiddef.h"\ # End Source File # Begin Source File @@ -151,7 +153,6 @@ DEP_CPP_GPAXP=\ "..\..\applications\GPAX\GPAXPlugin.h"\ "..\..\applications\GPAX\StdAfx.h"\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\math.h"\ @@ -164,6 +165,9 @@ DEP_CPP_GPAXP=\ "..\..\include\gpac\user.h"\ "..\..\include\gpac\utf.h"\ +NODEP_CPP_GPAXP=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File diff --git a/build/msevc4/Osmo4.vcp b/build/msevc4/Osmo4.vcp index 656e4b4..72a1be4 100644 --- a/build/msevc4/Osmo4.vcp +++ b/build/msevc4/Osmo4.vcp @@ -110,7 +110,8 @@ DEP_CPP_MAINF=\ "..\..\applications\osmo4_wce\ProgressBar.h"\ "..\..\applications\osmo4_wce\StdAfx.h"\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\math.h"\ @@ -123,6 +124,9 @@ DEP_CPP_MAINF=\ "..\..\include\gpac\user.h"\ {$(INCLUDE)}"gx.h"\ +NODEP_CPP_MAINF=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -132,7 +136,8 @@ DEP_CPP_OPEND=\ "..\..\applications\osmo4_wce\Osmo4.h"\ "..\..\applications\osmo4_wce\StdAfx.h"\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\math.h"\ @@ -142,6 +147,9 @@ DEP_CPP_OPEND=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ +NODEP_CPP_OPEND=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -150,24 +158,32 @@ DEP_CPP_OPTIO=\ "..\..\applications\osmo4_wce\Options.h"\ "..\..\applications\osmo4_wce\Osmo4.h"\ "..\..\applications\osmo4_wce\StdAfx.h"\ + "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\iso639.h"\ + "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\audio_out.h"\ "..\..\include\gpac\modules\codec.h"\ "..\..\include\gpac\modules\font.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\options.h"\ "..\..\include\gpac\path2d.h"\ "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\terminal.h"\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ {$(INCLUDE)}"gx.h"\ +NODEP_CPP_OPTIO=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -181,7 +197,8 @@ DEP_CPP_OSMO4=\ "..\..\applications\osmo4_wce\StdAfx.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ @@ -198,6 +215,9 @@ DEP_CPP_OSMO4=\ "..\..\include\gpac\user.h"\ {$(INCLUDE)}"gx.h"\ +NODEP_CPP_OSMO4=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -211,7 +231,8 @@ DEP_CPP_PROGR=\ "..\..\applications\osmo4_wce\ProgressBar.h"\ "..\..\applications\osmo4_wce\StdAfx.h"\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\math.h"\ @@ -221,6 +242,9 @@ DEP_CPP_PROGR=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ +NODEP_CPP_PROGR=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File diff --git a/build/msevc4/aac_in.vcp b/build/msevc4/aac_in.vcp index 56b45a1..378b6b5 100644 --- a/build/msevc4/aac_in.vcp +++ b/build/msevc4/aac_in.vcp @@ -104,7 +104,8 @@ SOURCE=..\..\modules\aac_in\aac_in.c DEP_CPP_AAC_I=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\list.h"\ @@ -116,14 +117,43 @@ DEP_CPP_AAC_I=\ "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ +NODEP_CPP_AAC_I=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File -SOURCE=..\..\modules\aac_in\aac_in.def +SOURCE=..\..\modules\aac_in\faad_dec.c +DEP_CPP_FAAD_=\ + "..\..\extra_lib\include\faad\faad.h"\ + "..\..\extra_lib\include\faad\neaacdec.h"\ + "..\..\include\gpac\avparse.h"\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\module.h"\ + "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\tools.h"\ + +NODEP_CPP_FAAD_=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File -SOURCE=..\..\modules\aac_in\faad_dec.c +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/ac3_in.vcp b/build/msevc4/ac3_in.vcp new file mode 100644 index 0000000..637cacd --- /dev/null +++ b/build/msevc4/ac3_in.vcp @@ -0,0 +1,157 @@ +# Microsoft eMbedded Visual Tools Project File - Name="ac3_in" - Package Owner=<4> +# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (WCE ARMV4) Dynamic-Link Library" 0xa302 + +CFG=ac3_in - Win32 (WCE ARMV4) Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "ac3_in.vcn". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "ac3_in.vcn" CFG="ac3_in - Win32 (WCE ARMV4) Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "ac3_in - Win32 (WCE ARMV4) Release" (based on "Win32 (WCE ARMV4) Dynamic-Link Library") +!MESSAGE "ac3_in - Win32 (WCE ARMV4) Debug" (based on "Win32 (WCE ARMV4) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +# PROP ATL_Project 2 +CPP=clarm.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "ac3_in - Win32 (WCE ARMV4) Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ARMV4Rel" +# PROP BASE Intermediate_Dir "ARMV4Rel" +# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}" +# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "obj/ac3_in_rel" +# PROP Intermediate_Dir "obj/ac3_in_rel" +# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}" +# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r +# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r +# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "AC3_IN_EXPORTS" /YX /O2 /M$(CECrtMT) /c +# ADD CPP /nologo /W3 /I "../../include" /I "../../extra_lib/include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAC_HAS_LIBA52" /YX /O2 /M$(CECrtMT) /c +# SUBTRACT CPP /u +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM +# ADD LINK32 liba52.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc03_rel/gm_ac3_in.dll" /libpath:"../../extra_lib/lib/arm_ppc03_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM + +!ELSEIF "$(CFG)" == "ac3_in - Win32 (WCE ARMV4) Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "ARMV4Dbg" +# PROP BASE Intermediate_Dir "ARMV4Dbg" +# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}" +# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "obj/ac3_in_deb" +# PROP Intermediate_Dir "obj/ac3_in_deb" +# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}" +# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r +# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r +# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "AC3_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c +# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GPAC_HAS_LIBA52" /YX /M$(CECrtMTDebug) /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM +# ADD LINK32 liba52.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc03_deb/gm_ac3_in.dll" /libpath:"../../extra_lib/lib/arm_ppc03_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM + +!ENDIF + +# Begin Target + +# Name "ac3_in - Win32 (WCE ARMV4) Release" +# Name "ac3_in - Win32 (WCE ARMV4) Debug" +# Begin Source File + +SOURCE=..\..\modules\ac3_in\ac3_in.c +DEP_CPP_AC3_I=\ + "..\..\include\gpac\avparse.h"\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\download.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\module.h"\ + "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\tools.h"\ + +NODEP_CPP_AC3_I=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\modules\ac3_in\liba52_dec.c +DEP_CPP_LIBA5=\ + "..\..\extra_lib\include\a52dec\a52.h"\ + "..\..\extra_lib\include\a52dec\mm_accel.h"\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\module.h"\ + "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\tools.h"\ + +NODEP_CPP_LIBA5=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# End Target +# End Project diff --git a/build/msevc4/amr_dec.vcp b/build/msevc4/amr_dec.vcp index 52ac844..36380dd 100644 --- a/build/msevc4/amr_dec.vcp +++ b/build/msevc4/amr_dec.vcp @@ -2244,7 +2244,8 @@ SOURCE=..\..\modules\amr_dec\amr_nb\weight_a.h SOURCE=..\..\modules\amr_dec\amr_dec.c DEP_CPP_AMR_D=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\list.h"\ @@ -2277,17 +2278,17 @@ DEP_CPP_AMR_D=\ "..\..\modules\amr_dec\amr_nb\typedef.h"\ "..\..\modules\amr_dec\amr_nb\typedefs.h"\ -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_dec.def +NODEP_CPP_AMR_D=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File SOURCE=..\..\modules\amr_dec\amr_in.c DEP_CPP_AMR_I=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\isomedia.h"\ @@ -2300,6 +2301,20 @@ DEP_CPP_AMR_I=\ "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ +NODEP_CPP_AMR_I=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/bifs_dec.vcp b/build/msevc4/bifs_dec.vcp index 1ab3bba..2291169 100644 --- a/build/msevc4/bifs_dec.vcp +++ b/build/msevc4/bifs_dec.vcp @@ -104,17 +104,21 @@ SOURCE=..\..\modules\bifs_dec\bifs_dec.c DEP_CPP_BIFS_=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\color.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ "..\..\include\gpac\download.h"\ + "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\mediaobject.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\modules\ipmp.h"\ "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\modules\term_ext.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ "..\..\include\gpac\scenegraph.h"\ @@ -126,10 +130,20 @@ DEP_CPP_BIFS_=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ +NODEP_CPP_BIFS_=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File -SOURCE=..\..\modules\bifs_dec\bifs_dec.def +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/ctx_load.vcp b/build/msevc4/ctx_load.vcp index 55c7725..e30eb11 100644 --- a/build/msevc4/ctx_load.vcp +++ b/build/msevc4/ctx_load.vcp @@ -103,10 +103,12 @@ LINK32=link.exe SOURCE=..\..\modules\ctx_load\ctx_load.c DEP_CPP_CTX_L=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\color.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ "..\..\include\gpac\download.h"\ + "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -114,7 +116,9 @@ DEP_CPP_CTX_L=\ "..\..\include\gpac\mediaobject.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\modules\ipmp.h"\ "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\modules\term_ext.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\network.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ @@ -128,10 +132,20 @@ DEP_CPP_CTX_L=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ +NODEP_CPP_CTX_L=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File -SOURCE=..\..\modules\ctx_load\ctx_load.def +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/dummy_in.vcp b/build/msevc4/dummy_in.vcp index 51e841d..c59abd4 100644 --- a/build/msevc4/dummy_in.vcp +++ b/build/msevc4/dummy_in.vcp @@ -103,7 +103,8 @@ LINK32=link.exe SOURCE=..\..\modules\dummy_in\dummy_in.c DEP_CPP_DUMMY=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\list.h"\ @@ -115,10 +116,20 @@ DEP_CPP_DUMMY=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\xml.h"\ +NODEP_CPP_DUMMY=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File -SOURCE=..\..\modules\dummy_in\dummy_in.def +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/ffmpeg_in.vcp b/build/msevc4/ffmpeg_in.vcp index b20f0e3..8ef6e6b 100644 --- a/build/msevc4/ffmpeg_in.vcp +++ b/build/msevc4/ffmpeg_in.vcp @@ -50,8 +50,8 @@ RSC=rc.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "FFMPEG_IN_EXPORTS" /YX /O2 /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /I "../../include" /I "../../extra_lib/include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "FFMPEG_IN_EXPORTS" /M$(CECrtMT) /c -# SUBTRACT CPP /O /YX +# ADD CPP /nologo /W3 /Oxt /I "../../include" /I "../../extra_lib/include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "CONFIG_WIN32" /D "CONFIG_MSVC" /D "EMULATE_INTTYPES" /M$(CECrtMT) /c +# SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 BSC32=bscmake.exe @@ -59,7 +59,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 ffmpeg.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc03_rel/gm_ffmpeg_in.dll" /libpath:"../../extra_lib/lib/arm_ppc03_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM +# ADD LINK32 avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc03_rel/gm_ffmpeg_in.dll" /libpath:"../../extra_lib/lib/arm_ppc03_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM !ELSEIF "$(CFG)" == "ffmpeg_in - Win32 (WCE ARMV4) Debug" @@ -81,7 +81,7 @@ LINK32=link.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "FFMPEG_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c +# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "CONFIG_WIN32" /D "CONFIG_MSVC" /D "EMULATE_INTTYPES" /M$(CECrtMTDebug) /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 @@ -90,7 +90,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM -# ADD LINK32 ffmpeg.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc03_deb/gm_ffmpeg_in.dll" /libpath:"../../extra_lib/lib/arm_ppc03_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM +# ADD LINK32 avcodec-52.lib avformat-52.lib avutil-50.lib swscale-0.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /out:"../../bin/arm_ppc03_deb/gm_ffmpeg_in.dll" /libpath:"../../extra_lib/lib/arm_ppc03_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM !ENDIF @@ -102,23 +102,24 @@ LINK32=link.exe SOURCE=..\..\modules\ffmpeg_in\ffmpeg_decode.c DEP_CPP_FFMPE=\ - "..\..\extra_lib\include\ffmpeg\avcodec.h"\ - "..\..\extra_lib\include\ffmpeg\avformat.h"\ - "..\..\extra_lib\include\ffmpeg\avio.h"\ - "..\..\extra_lib\include\ffmpeg\avutil.h"\ - "..\..\extra_lib\include\ffmpeg\common.h"\ - "..\..\extra_lib\include\ffmpeg\integer.h"\ - "..\..\extra_lib\include\ffmpeg\intfloat_readwrite.h"\ - "..\..\extra_lib\include\ffmpeg\log.h"\ - "..\..\extra_lib\include\ffmpeg\mathematics.h"\ - "..\..\extra_lib\include\ffmpeg\rational.h"\ + "..\..\extra_lib\include\libavcodec\avcodec.h"\ + "..\..\extra_lib\include\libavformat\avformat.h"\ + "..\..\extra_lib\include\libavformat\avio.h"\ + "..\..\extra_lib\include\libavutil\avutil.h"\ + "..\..\extra_lib\include\libavutil\common.h"\ + "..\..\extra_lib\include\libavutil\intfloat_readwrite.h"\ + "..\..\extra_lib\include\libavutil\log.h"\ + "..\..\extra_lib\include\libavutil\mathematics.h"\ + "..\..\extra_lib\include\libavutil\mem.h"\ + "..\..\extra_lib\include\libavutil\pixfmt.h"\ + "..\..\extra_lib\include\libavutil\rational.h"\ + "..\..\extra_lib\include\libswscale\swscale.h"\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -131,10 +132,8 @@ DEP_CPP_FFMPE=\ "..\..\modules\ffmpeg_in\ffmpeg_in.h"\ NODEP_CPP_FFMPE=\ - "..\..\extra_lib\include\ffmpeg\berrno.h"\ - "..\..\extra_lib\include\ffmpeg\config.h"\ - "..\..\extra_lib\include\ffmpeg\internal.h"\ - "..\..\extra_lib\include\ffmpeg\os_support.h"\ + "..\..\extra_lib\include\libavutil\config.h"\ + "..\..\extra_lib\include\libavutil\internal.h"\ "..\..\include\gpac\config.h"\ # End Source File @@ -142,22 +141,23 @@ NODEP_CPP_FFMPE=\ SOURCE=..\..\modules\ffmpeg_in\ffmpeg_demux.c DEP_CPP_FFMPEG=\ - "..\..\extra_lib\include\ffmpeg\avcodec.h"\ - "..\..\extra_lib\include\ffmpeg\avformat.h"\ - "..\..\extra_lib\include\ffmpeg\avio.h"\ - "..\..\extra_lib\include\ffmpeg\avutil.h"\ - "..\..\extra_lib\include\ffmpeg\common.h"\ - "..\..\extra_lib\include\ffmpeg\integer.h"\ - "..\..\extra_lib\include\ffmpeg\intfloat_readwrite.h"\ - "..\..\extra_lib\include\ffmpeg\log.h"\ - "..\..\extra_lib\include\ffmpeg\mathematics.h"\ - "..\..\extra_lib\include\ffmpeg\rational.h"\ + "..\..\extra_lib\include\libavcodec\avcodec.h"\ + "..\..\extra_lib\include\libavformat\avformat.h"\ + "..\..\extra_lib\include\libavformat\avio.h"\ + "..\..\extra_lib\include\libavutil\avutil.h"\ + "..\..\extra_lib\include\libavutil\common.h"\ + "..\..\extra_lib\include\libavutil\intfloat_readwrite.h"\ + "..\..\extra_lib\include\libavutil\log.h"\ + "..\..\extra_lib\include\libavutil\mathematics.h"\ + "..\..\extra_lib\include\libavutil\mem.h"\ + "..\..\extra_lib\include\libavutil\pixfmt.h"\ + "..\..\extra_lib\include\libavutil\rational.h"\ + "..\..\extra_lib\include\libswscale\swscale.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -170,41 +170,36 @@ DEP_CPP_FFMPEG=\ "..\..\modules\ffmpeg_in\ffmpeg_in.h"\ NODEP_CPP_FFMPEG=\ - "..\..\extra_lib\include\ffmpeg\berrno.h"\ - "..\..\extra_lib\include\ffmpeg\config.h"\ - "..\..\extra_lib\include\ffmpeg\internal.h"\ - "..\..\extra_lib\include\ffmpeg\os_support.h"\ + "..\..\extra_lib\include\libavutil\config.h"\ + "..\..\extra_lib\include\libavutil\internal.h"\ "..\..\include\gpac\config.h"\ # End Source File # Begin Source File -SOURCE=..\..\modules\ffmpeg_in\ffmpeg_in.def -# End Source File -# Begin Source File - SOURCE=..\..\modules\ffmpeg_in\ffmpeg_in.h # End Source File # Begin Source File SOURCE=..\..\modules\ffmpeg_in\ffmpeg_load.c DEP_CPP_FFMPEG_=\ - "..\..\extra_lib\include\ffmpeg\avcodec.h"\ - "..\..\extra_lib\include\ffmpeg\avformat.h"\ - "..\..\extra_lib\include\ffmpeg\avio.h"\ - "..\..\extra_lib\include\ffmpeg\avutil.h"\ - "..\..\extra_lib\include\ffmpeg\common.h"\ - "..\..\extra_lib\include\ffmpeg\integer.h"\ - "..\..\extra_lib\include\ffmpeg\intfloat_readwrite.h"\ - "..\..\extra_lib\include\ffmpeg\log.h"\ - "..\..\extra_lib\include\ffmpeg\mathematics.h"\ - "..\..\extra_lib\include\ffmpeg\rational.h"\ + "..\..\extra_lib\include\libavcodec\avcodec.h"\ + "..\..\extra_lib\include\libavformat\avformat.h"\ + "..\..\extra_lib\include\libavformat\avio.h"\ + "..\..\extra_lib\include\libavutil\avutil.h"\ + "..\..\extra_lib\include\libavutil\common.h"\ + "..\..\extra_lib\include\libavutil\intfloat_readwrite.h"\ + "..\..\extra_lib\include\libavutil\log.h"\ + "..\..\extra_lib\include\libavutil\mathematics.h"\ + "..\..\extra_lib\include\libavutil\mem.h"\ + "..\..\extra_lib\include\libavutil\pixfmt.h"\ + "..\..\extra_lib\include\libavutil\rational.h"\ + "..\..\extra_lib\include\libswscale\swscale.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -217,10 +212,19 @@ DEP_CPP_FFMPEG_=\ "..\..\modules\ffmpeg_in\ffmpeg_in.h"\ NODEP_CPP_FFMPEG_=\ - "..\..\extra_lib\include\ffmpeg\berrno.h"\ - "..\..\extra_lib\include\ffmpeg\config.h"\ - "..\..\extra_lib\include\ffmpeg\internal.h"\ - "..\..\extra_lib\include\ffmpeg\os_support.h"\ + "..\..\extra_lib\include\libavutil\config.h"\ + "..\..\extra_lib\include\libavutil\internal.h"\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ "..\..\include\gpac\config.h"\ # End Source File diff --git a/build/msevc4/ft_font.vcp b/build/msevc4/ft_font.vcp index 44bbf74..a6419ab 100644 --- a/build/msevc4/ft_font.vcp +++ b/build/msevc4/ft_font.vcp @@ -105,10 +105,9 @@ DEP_CPP_FT_FO=\ "..\..\extra_lib\include\freetype\freetype\config\ftheader.h"\ "..\..\extra_lib\include\freetype\ft2build.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ @@ -125,11 +124,18 @@ NODEP_CPP_FT_FO=\ # End Source File # Begin Source File -SOURCE=..\..\modules\ft_font\ft_font.def +SOURCE=..\..\modules\ft_font\ft_font.h # End Source File # Begin Source File -SOURCE=..\..\modules\ft_font\ft_font.h +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/gapi.vcp b/build/msevc4/gapi.vcp index 230326e..28895ca 100644 --- a/build/msevc4/gapi.vcp +++ b/build/msevc4/gapi.vcp @@ -50,7 +50,7 @@ RSC=rc.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GAPI_EXPORTS" /YX /O2 /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /Oxt /I "../../include" /I "../../extra_lib/include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAC_HAVE_CONFIG_H" /M$(CECrtMT) /c +# ADD CPP /nologo /W3 /Oxt /I "../../include" /I "../../extra_lib/include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /M$(CECrtMT) /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 @@ -81,7 +81,7 @@ LINK32=link.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GAPI_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GPAC_HAVE_CONFIG_H" /FR /M$(CECrtMTDebug) /c +# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /FR /M$(CECrtMTDebug) /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 @@ -106,10 +106,9 @@ DEP_CPP_GAPI_=\ "..\..\extra_lib\include\GLES\gl.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ @@ -125,16 +124,23 @@ DEP_CPP_GAPI_=\ NODEP_CPP_GAPI_=\ "..\..\include\gpac\config.h"\ - "C:\Program Files\Windows CE Tools\wce420\POCKET PC 2003\Include\ARMV4\vibrate.h"\ + "C:\Program Files\WindowsCE\wce420\POCKET PC 2003\Include\ARMV4\vibrate.h"\ # End Source File # Begin Source File -SOURCE=..\..\modules\gapi\gapi.def +SOURCE=..\..\modules\gapi\gapi.h # End Source File # Begin Source File -SOURCE=..\..\modules\gapi\gapi.h +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/gpac_js.vcp b/build/msevc4/gpac_js.vcp new file mode 100644 index 0000000..328179a --- /dev/null +++ b/build/msevc4/gpac_js.vcp @@ -0,0 +1,173 @@ +# Microsoft eMbedded Visual Tools Project File - Name="gpac_js" - Package Owner=<4> +# Microsoft eMbedded Visual Tools Generated Build File, Format Version 6.02 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (WCE ARMV4) Dynamic-Link Library" 0xa302 + +CFG=gpac_js - Win32 (WCE ARMV4) Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gpac_js.vcn". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gpac_js.vcn" CFG="gpac_js - Win32 (WCE ARMV4) Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gpac_js - Win32 (WCE ARMV4) Release" (based on "Win32 (WCE ARMV4) Dynamic-Link Library") +!MESSAGE "gpac_js - Win32 (WCE ARMV4) Debug" (based on "Win32 (WCE ARMV4) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +# PROP ATL_Project 2 +CPP=clarm.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gpac_js - Win32 (WCE ARMV4) Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "ARMV4Rel" +# PROP BASE Intermediate_Dir "ARMV4Rel" +# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}" +# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "obj/gjs_rel" +# PROP Intermediate_Dir "obj/gjs_rel" +# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}" +# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r +# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r +# ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAC_JS_EXPORTS" /YX /O2 /M$(CECrtMT) /c +# ADD CPP /nologo /W3 /I "../../include" /I "../../extra_lib/include/js" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "XP_PC" /O2 /M$(CECrtMT) /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM +# ADD LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /out:"../../bin/arm_ppc03_rel/gm_gpac_js.dll" /libpath:"../../extra_lib/lib/arm_ppc03_rel" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM + +!ELSEIF "$(CFG)" == "gpac_js - Win32 (WCE ARMV4) Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "ARMV4Dbg" +# PROP BASE Intermediate_Dir "ARMV4Dbg" +# PROP BASE CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}" +# PROP BASE Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "obj/gjs_deb" +# PROP Intermediate_Dir "obj/gjs_deb" +# PROP CPU_ID "{ECBEA43D-CD7B-4852-AD55-D4227B5D624B}" +# PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r +# ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r +# ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GPAC_JS_EXPORTS" /YX /M$(CECrtMTDebug) /c +# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/js" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "XP_PC" /M$(CECrtMTDebug) /c +# SUBTRACT CPP /YX +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /nodefaultlib:"$(CENoDefaultLib)" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM +# ADD LINK32 commctrl.lib coredll.lib /nologo /base:"0x00100000" /stack:0x10000,0x1000 /entry:"_DllMainCRTStartup" /dll /debug /out:"../../bin/arm_ppc03_deb/gm_gpac_js.dll" /libpath:"../../extra_lib/lib/arm_ppc03_deb" /subsystem:$(CESubsystem) /align:"4096" /MACHINE:ARM + +!ENDIF + +# Begin Target + +# Name "gpac_js - Win32 (WCE ARMV4) Release" +# Name "gpac_js - Win32 (WCE ARMV4) Debug" +# Begin Source File + +SOURCE=..\..\modules\gpac_js\gpac_js.c +DEP_CPP_GPAC_=\ + "..\..\extra_lib\include\js\jsapi.h"\ + "..\..\extra_lib\include\js\jsautocfg.h"\ + "..\..\extra_lib\include\js\jscompat.h"\ + "..\..\extra_lib\include\js\jscpucfg.h"\ + "..\..\extra_lib\include\js\jslong.h"\ + "..\..\extra_lib\include\js\jsosdep.h"\ + "..\..\extra_lib\include\js\jsotypes.h"\ + "..\..\extra_lib\include\js\jsproto.tbl"\ + "..\..\extra_lib\include\js\jspubtd.h"\ + "..\..\extra_lib\include\js\jstypes.h"\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\color.h"\ + "..\..\include\gpac\compositor.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\download.h"\ + "..\..\include\gpac\events.h"\ + "..\..\include\gpac\internal\camera.h"\ + "..\..\include\gpac\internal\compositor_dev.h"\ + "..\..\include\gpac\internal\mesh.h"\ + "..\..\include\gpac\internal\scenegraph_dev.h"\ + "..\..\include\gpac\internal\terminal_dev.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\math.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\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\network.h"\ + "..\..\include\gpac\nodes_svg.h"\ + "..\..\include\gpac\path2d.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\terminal.h"\ + "..\..\include\gpac\thread.h"\ + "..\..\include\gpac\tools.h"\ + "..\..\include\gpac\user.h"\ + "..\..\include\gpac\xml.h"\ + +NODEP_CPP_GPAC_=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# End Target +# End Project diff --git a/build/msevc4/img_in.vcp b/build/msevc4/img_in.vcp index c21616e..f405c0e 100644 --- a/build/msevc4/img_in.vcp +++ b/build/msevc4/img_in.vcp @@ -50,7 +50,7 @@ RSC=rc.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "IMG_IN_EXPORTS" /YX /O2 /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /Oxt /I "../../include" /I "../../extra_lib/include/openjpeg" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAC_HAS_JPEG" /D "GPAC_HAS_PNG" /D "GPAC_HAS_JP2" /D "OPJ_STATIC" /M$(CECrtMT) /c +# ADD CPP /nologo /W3 /Oxt /I "../../include" /I "../../extra_lib/include/openjpeg" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "GPAC_HAS_JP2" /D "OPJ_STATIC" /M$(CECrtMT) /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 @@ -81,7 +81,7 @@ LINK32=link.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "IMG_IN_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/png" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/jpeg" /I "../../extra_lib/include/openjpeg" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GPAC_HAS_JPEG" /D "GPAC_HAS_PNG" /D "GPAC_HAS_JP2" /D "OPJ_STATIC" /FR /M$(CECrtMTDebug) /c +# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/png" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/jpeg" /I "../../extra_lib/include/openjpeg" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "GPAC_HAS_JP2" /D "OPJ_STATIC" /FR /M$(CECrtMTDebug) /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 @@ -104,9 +104,9 @@ SOURCE=..\..\modules\img_in\bmp_dec.c DEP_CPP_BMP_D=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -117,6 +117,9 @@ DEP_CPP_BMP_D=\ "..\..\include\gpac\tools.h"\ "..\..\modules\img_in\img_in.h"\ +NODEP_CPP_BMP_D=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -124,9 +127,9 @@ SOURCE=..\..\modules\img_in\img_dec.c DEP_CPP_IMG_D=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -137,6 +140,9 @@ DEP_CPP_IMG_D=\ "..\..\include\gpac\tools.h"\ "..\..\modules\img_in\img_in.h"\ +NODEP_CPP_IMG_D=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -145,9 +151,9 @@ DEP_CPP_IMG_I=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -158,10 +164,9 @@ DEP_CPP_IMG_I=\ "..\..\include\gpac\tools.h"\ "..\..\modules\img_in\img_in.h"\ -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\img_in.def +NODEP_CPP_IMG_I=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -174,9 +179,9 @@ DEP_CPP_JP2_D=\ "..\..\extra_lib\include\openjpeg\openjpeg.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -187,6 +192,9 @@ DEP_CPP_JP2_D=\ "..\..\include\gpac\tools.h"\ "..\..\modules\img_in\img_in.h"\ +NODEP_CPP_JP2_D=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -195,9 +203,9 @@ DEP_CPP_JPEG_=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -208,6 +216,20 @@ DEP_CPP_JPEG_=\ "..\..\include\gpac\tools.h"\ "..\..\modules\img_in\img_in.h"\ +NODEP_CPP_JPEG_=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -216,9 +238,9 @@ DEP_CPP_PNG_D=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -229,6 +251,9 @@ DEP_CPP_PNG_D=\ "..\..\include\gpac\tools.h"\ "..\..\modules\img_in\img_in.h"\ +NODEP_CPP_PNG_D=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/ismacryp.vcp b/build/msevc4/ismacryp.vcp index 16ddaab..05e923e 100644 --- a/build/msevc4/ismacryp.vcp +++ b/build/msevc4/ismacryp.vcp @@ -96,9 +96,6 @@ LINK32=link.exe # Name "ismacryp - Win32 (WCE ARMV4) Release" # Name "ismacryp - Win32 (WCE ARMV4) Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\..\modules\ismacryp\ismacryp.c @@ -107,11 +104,11 @@ DEP_CPP_ISMAC=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\crypt.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\ismacryp.h"\ "..\..\include\gpac\isomedia.h"\ @@ -122,6 +119,7 @@ DEP_CPP_ISMAC=\ "..\..\include\gpac\modules\codec.h"\ "..\..\include\gpac\modules\ipmp.h"\ "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\modules\term_ext.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\scenegraph.h"\ "..\..\include\gpac\scenegraph_vrml.h"\ @@ -132,19 +130,20 @@ DEP_CPP_ISMAC=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ +NODEP_CPP_ISMAC=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File -SOURCE=..\..\modules\ismacryp\ismacryp.def +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group # End Target # End Project diff --git a/build/msevc4/isom_in.vcp b/build/msevc4/isom_in.vcp index fdc2d4b..ecc0449 100644 --- a/build/msevc4/isom_in.vcp +++ b/build/msevc4/isom_in.vcp @@ -104,7 +104,8 @@ SOURCE=..\..\modules\isom_in\cache.c DEP_CPP_CACHE=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\isomedia.h"\ @@ -118,10 +119,9 @@ DEP_CPP_CACHE=\ "..\..\include\gpac\tools.h"\ "..\..\modules\isom_in\isom_in.h"\ -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\isom_in.def +NODEP_CPP_CACHE=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -133,7 +133,8 @@ SOURCE=..\..\modules\isom_in\load.c DEP_CPP_LOAD_=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\isomedia.h"\ @@ -147,6 +148,20 @@ DEP_CPP_LOAD_=\ "..\..\include\gpac\tools.h"\ "..\..\modules\isom_in\isom_in.h"\ +NODEP_CPP_LOAD_=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -154,9 +169,11 @@ SOURCE=..\..\modules\isom_in\read.c DEP_CPP_READ_=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ + "..\..\include\gpac\ismacryp.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\media_tools.h"\ @@ -168,6 +185,9 @@ DEP_CPP_READ_=\ "..\..\include\gpac\tools.h"\ "..\..\modules\isom_in\isom_in.h"\ +NODEP_CPP_READ_=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -175,7 +195,8 @@ SOURCE=..\..\modules\isom_in\read_ch.c DEP_CPP_READ_C=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\isomedia.h"\ @@ -189,6 +210,9 @@ DEP_CPP_READ_C=\ "..\..\include\gpac\tools.h"\ "..\..\modules\isom_in\isom_in.h"\ +NODEP_CPP_READ_C=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/laser_dec.vcp b/build/msevc4/laser_dec.vcp index 79423ec..d034fb4 100644 --- a/build/msevc4/laser_dec.vcp +++ b/build/msevc4/laser_dec.vcp @@ -96,9 +96,6 @@ LINK32=link.exe # Name "laser_dec - Win32 (WCE ARMV4) Release" # Name "laser_dec - Win32 (WCE ARMV4) Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\..\modules\laser_dec\laser_dec.c @@ -106,10 +103,10 @@ DEP_CPP_LASER=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\laser.h"\ "..\..\include\gpac\list.h"\ @@ -119,8 +116,9 @@ DEP_CPP_LASER=\ "..\..\include\gpac\modules\codec.h"\ "..\..\include\gpac\modules\ipmp.h"\ "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\modules\term_ext.h"\ "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_svg_da.h"\ + "..\..\include\gpac\nodes_svg.h"\ "..\..\include\gpac\path2d.h"\ "..\..\include\gpac\scenegraph.h"\ "..\..\include\gpac\scenegraph_svg.h"\ @@ -133,19 +131,20 @@ DEP_CPP_LASER=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ +NODEP_CPP_LASER=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File -SOURCE=..\..\modules\laser_dec\laser_dec.def +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group # End Target # End Project diff --git a/build/msevc4/libgpac.vcp b/build/msevc4/libgpac.vcp index 499b85e..35f9ace 100644 --- a/build/msevc4/libgpac.vcp +++ b/build/msevc4/libgpac.vcp @@ -45,7 +45,7 @@ CPP=clarm.exe # PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "NDEBUG" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /YX /O2 /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /Oxt /I "../../include" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/js" /I "../../extra_lib/include" /I "../../extra_lib/include/jpeg" /I "../../extra_lib/include/png" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "NDEBUG" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /D "GPAC_HAVE_CONFIG_H" /M$(CECrtMT) /c +# ADD CPP /nologo /W3 /Oxt /I "../../include" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/js" /I "../../extra_lib/include" /I "../../extra_lib/include/jpeg" /I "../../extra_lib/include/png" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "NDEBUG" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /M$(CECrtMT) /c # SUBTRACT CPP /YX LIB32=link.exe -lib # ADD BASE LIB32 /nologo @@ -71,7 +71,7 @@ BSC32=bscmake.exe # PROP Platform_ID "{8A9A2F80-6887-11D3-842E-005004848CBA}" # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/js" /I "../../extra_lib/include" /I "../../extra_lib/include/jpeg" /I "../../extra_lib/include/png" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /D "GPAC_HAVE_CONFIG_H" /FR /M$(CECrtMTDebug) /c +# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/js" /I "../../extra_lib/include" /I "../../extra_lib/include/jpeg" /I "../../extra_lib/include/png" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_LIB" /FR /M$(CECrtMTDebug) /c # SUBTRACT CPP /YX LIB32=link.exe -lib # ADD BASE LIB32 /nologo @@ -94,9 +94,8 @@ BSC32=bscmake.exe SOURCE=..\..\src\utils\base_encoding.c DEP_CPP_BASE_=\ "..\..\include\gpac\base_coding.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -109,8 +108,7 @@ NODEP_CPP_BASE_=\ SOURCE=..\..\src\utils\bitstream.c DEP_CPP_BITST=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -124,10 +122,9 @@ SOURCE=..\..\src\utils\color.c DEP_CPP_COLOR=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\setup.h"\ @@ -143,8 +140,7 @@ NODEP_CPP_COLOR=\ SOURCE=..\..\src\utils\configfile.c DEP_CPP_CONFI=\ "..\..\include\gpac\config_file.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\setup.h"\ @@ -160,10 +156,9 @@ SOURCE=..\..\src\utils\downloader.c DEP_CPP_DOWNL=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\network.h"\ @@ -180,8 +175,7 @@ NODEP_CPP_DOWNL=\ SOURCE=..\..\src\utils\error.c DEP_CPP_ERROR=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -193,8 +187,7 @@ NODEP_CPP_ERROR=\ SOURCE=..\..\src\utils\list.c DEP_CPP_LIST_=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -207,8 +200,7 @@ NODEP_CPP_LIST_=\ SOURCE=..\..\src\utils\math.c DEP_CPP_MATH_=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\setup.h"\ @@ -221,8 +213,7 @@ NODEP_CPP_MATH_=\ SOURCE=..\..\src\utils\module.c DEP_CPP_MODUL=\ "..\..\include\gpac\config_file.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\setup.h"\ @@ -241,8 +232,7 @@ SOURCE=..\..\src\utils\module_wrap.h SOURCE=..\..\src\utils\os_divers.c DEP_CPP_OS_DI=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -255,8 +245,7 @@ NODEP_CPP_OS_DI=\ SOURCE=..\..\src\utils\os_module.c DEP_CPP_OS_MO=\ "..\..\include\gpac\config_file.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\setup.h"\ @@ -271,8 +260,7 @@ NODEP_CPP_OS_MO=\ SOURCE=..\..\src\utils\os_net.c DEP_CPP_OS_NE=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\network.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -285,8 +273,7 @@ NODEP_CPP_OS_NE=\ SOURCE=..\..\src\utils\os_thread.c DEP_CPP_OS_TH=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\thread.h"\ @@ -300,9 +287,8 @@ NODEP_CPP_OS_TH=\ SOURCE=..\..\src\utils\path2d.c DEP_CPP_PATH2=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\path2d.h"\ "..\..\include\gpac\setup.h"\ @@ -316,9 +302,8 @@ NODEP_CPP_PATH2=\ SOURCE=..\..\src\utils\path2d_stroker.c DEP_CPP_PATH2D=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\path2d.h"\ "..\..\include\gpac\setup.h"\ @@ -332,8 +317,7 @@ NODEP_CPP_PATH2D=\ SOURCE=..\..\src\utils\token.c DEP_CPP_TOKEN=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\token.h"\ "..\..\include\gpac\tools.h"\ @@ -346,8 +330,7 @@ NODEP_CPP_TOKEN=\ SOURCE=..\..\src\utils\uni_bidi.c DEP_CPP_UNI_B=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\utf.h"\ @@ -360,8 +343,7 @@ NODEP_CPP_UNI_B=\ SOURCE=..\..\src\utils\url.c DEP_CPP_URL_C=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\network.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -374,8 +356,7 @@ NODEP_CPP_URL_C=\ SOURCE=..\..\src\utils\utf.c DEP_CPP_UTF_C=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\utf.h"\ @@ -390,8 +371,7 @@ SOURCE=..\..\src\utils\xml_parser.c DEP_CPP_XML_P=\ "..\..\extra_lib\include\zlib\zconf.h"\ "..\..\extra_lib\include\zlib\zlib.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -411,8 +391,7 @@ NODEP_CPP_XML_P=\ SOURCE=..\..\src\odf\desc_private.c DEP_CPP_DESC_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -429,9 +408,8 @@ NODEP_CPP_DESC_=\ SOURCE=..\..\src\odf\descriptors.c DEP_CPP_DESCR=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\isomedia.h"\ @@ -450,8 +428,7 @@ NODEP_CPP_DESCR=\ SOURCE=..\..\src\odf\ipmpx_code.c DEP_CPP_IPMPX=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -465,11 +442,10 @@ NODEP_CPP_IPMPX=\ # End Source File # Begin Source File -SOURCE=..\..\src\odf\ipmpx_parse.c +SOURCE=..\..\src\odf\ipmpx_dump.c DEP_CPP_IPMPX_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -483,11 +459,27 @@ NODEP_CPP_IPMPX_=\ # End Source File # Begin Source File +SOURCE=..\..\src\odf\ipmpx_parse.c +DEP_CPP_IPMPX_P=\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\internal\odf_dev.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\tools.h"\ + +NODEP_CPP_IPMPX_P=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\src\odf\oci_codec.c DEP_CPP_OCI_C=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -504,8 +496,7 @@ NODEP_CPP_OCI_C=\ SOURCE=..\..\src\odf\odf_code.c DEP_CPP_ODF_C=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -523,8 +514,7 @@ NODEP_CPP_ODF_C=\ SOURCE=..\..\src\odf\odf_codec.c DEP_CPP_ODF_CO=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -541,8 +531,7 @@ NODEP_CPP_ODF_CO=\ SOURCE=..\..\src\odf\odf_command.c DEP_CPP_ODF_COM=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -560,13 +549,33 @@ SOURCE=..\..\include\gpac\internal\odf_dev.h # End Source File # Begin Source File +SOURCE=..\..\src\odf\odf_dump.c +DEP_CPP_ODF_D=\ + "..\..\include\gpac\avparse.h"\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\internal\odf_dev.h"\ + "..\..\include\gpac\isomedia.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\media_tools.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\tools.h"\ + +NODEP_CPP_ODF_D=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\src\odf\odf_parse.c DEP_CPP_ODF_P=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -586,8 +595,7 @@ NODEP_CPP_ODF_P=\ SOURCE=..\..\src\odf\qos.c DEP_CPP_QOS_C=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -604,8 +612,7 @@ NODEP_CPP_QOS_C=\ SOURCE=..\..\src\odf\slc.c DEP_CPP_SLC_C=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -628,11 +635,10 @@ DEP_CPP_ARITH=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -662,11 +668,10 @@ DEP_CPP_BIFS_=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -674,6 +679,7 @@ DEP_CPP_BIFS_=\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\network.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ + "..\..\include\gpac\nodes_x3d.h"\ "..\..\include\gpac\path2d.h"\ "..\..\include\gpac\scenegraph.h"\ "..\..\include\gpac\scenegraph_svg.h"\ @@ -696,9 +702,8 @@ SOURCE=..\..\include\gpac\internal\bifs_dev.h SOURCE=..\..\src\bifs\bifs_node_tables.c DEP_CPP_BIFS_N=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\bifs_tables.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ @@ -722,11 +727,10 @@ DEP_CPP_COM_D=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -756,11 +760,10 @@ DEP_CPP_COM_E=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -790,11 +793,10 @@ DEP_CPP_CONDI=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -823,11 +825,10 @@ DEP_CPP_FIELD=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -858,12 +859,11 @@ DEP_CPP_FIELD_=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ "..\..\include\gpac\internal\bifs_tables.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -894,11 +894,10 @@ DEP_CPP_MEMOR=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -928,11 +927,10 @@ DEP_CPP_PREDI=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -966,11 +964,10 @@ DEP_CPP_QUANT=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -1004,11 +1001,10 @@ DEP_CPP_SCRIP=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -1038,11 +1034,10 @@ DEP_CPP_SCRIPT=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -1072,11 +1067,10 @@ DEP_CPP_UNQUA=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -1108,9 +1102,8 @@ NODEP_CPP_UNQUA=\ SOURCE=..\..\src\isomedia\avc_ext.c DEP_CPP_AVC_E=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1128,8 +1121,7 @@ NODEP_CPP_AVC_E=\ SOURCE=..\..\src\isomedia\box_code_3gpp.c DEP_CPP_BOX_C=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1147,8 +1139,7 @@ NODEP_CPP_BOX_C=\ SOURCE=..\..\src\isomedia\box_code_apple.c DEP_CPP_BOX_CO=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1166,8 +1157,7 @@ NODEP_CPP_BOX_CO=\ SOURCE=..\..\src\isomedia\box_code_base.c DEP_CPP_BOX_COD=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1185,8 +1175,7 @@ NODEP_CPP_BOX_COD=\ SOURCE=..\..\src\isomedia\box_code_isma.c DEP_CPP_BOX_CODE=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1204,8 +1193,7 @@ NODEP_CPP_BOX_CODE=\ SOURCE=..\..\src\isomedia\box_code_meta.c DEP_CPP_BOX_CODE_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1220,11 +1208,29 @@ NODEP_CPP_BOX_CODE_=\ # End Source File # Begin Source File +SOURCE=..\..\src\isomedia\box_dump.c +DEP_CPP_BOX_D=\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\internal\isomedia_dev.h"\ + "..\..\include\gpac\isomedia.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\tools.h"\ + "..\..\include\gpac\utf.h"\ + +NODEP_CPP_BOX_D=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\src\isomedia\box_funcs.c DEP_CPP_BOX_F=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1242,8 +1248,7 @@ NODEP_CPP_BOX_F=\ SOURCE=..\..\src\isomedia\data_map.c DEP_CPP_DATA_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1262,8 +1267,7 @@ NODEP_CPP_DATA_=\ SOURCE=..\..\src\isomedia\hint_track.c DEP_CPP_HINT_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1281,8 +1285,7 @@ NODEP_CPP_HINT_=\ SOURCE=..\..\src\isomedia\hinting.c DEP_CPP_HINTI=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1300,8 +1303,7 @@ NODEP_CPP_HINTI=\ SOURCE=..\..\src\isomedia\isma_sample.c DEP_CPP_ISMA_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1319,8 +1321,7 @@ NODEP_CPP_ISMA_=\ SOURCE=..\..\src\isomedia\isom_intern.c DEP_CPP_ISOM_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1339,8 +1340,7 @@ NODEP_CPP_ISOM_=\ SOURCE=..\..\src\isomedia\isom_read.c DEP_CPP_ISOM_R=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1358,8 +1358,7 @@ NODEP_CPP_ISOM_R=\ SOURCE=..\..\src\isomedia\isom_store.c DEP_CPP_ISOM_S=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1377,8 +1376,7 @@ NODEP_CPP_ISOM_S=\ SOURCE=..\..\src\isomedia\isom_write.c DEP_CPP_ISOM_W=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1400,8 +1398,7 @@ SOURCE=..\..\include\gpac\internal\isomedia_dev.h SOURCE=..\..\src\isomedia\media.c DEP_CPP_MEDIA=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1419,8 +1416,7 @@ NODEP_CPP_MEDIA=\ SOURCE=..\..\src\isomedia\media_odf.c DEP_CPP_MEDIA_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1438,8 +1434,7 @@ NODEP_CPP_MEDIA_=\ SOURCE=..\..\src\isomedia\meta.c DEP_CPP_META_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1457,8 +1452,7 @@ NODEP_CPP_META_=\ SOURCE=..\..\src\isomedia\movie_fragments.c DEP_CPP_MOVIE=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1476,8 +1470,7 @@ NODEP_CPP_MOVIE=\ SOURCE=..\..\src\isomedia\sample_descs.c DEP_CPP_SAMPL=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1495,8 +1488,7 @@ NODEP_CPP_SAMPL=\ SOURCE=..\..\src\isomedia\stbl_read.c DEP_CPP_STBL_=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1514,8 +1506,7 @@ NODEP_CPP_STBL_=\ SOURCE=..\..\src\isomedia\stbl_write.c DEP_CPP_STBL_W=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1533,8 +1524,7 @@ NODEP_CPP_STBL_W=\ SOURCE=..\..\src\isomedia\track.c DEP_CPP_TRACK=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1552,9 +1542,8 @@ NODEP_CPP_TRACK=\ SOURCE=..\..\src\isomedia\tx3g.c DEP_CPP_TX3G_=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -1580,9 +1569,8 @@ SOURCE=..\..\include\gpac\internal\ietf_dev.h SOURCE=..\..\src\ietf\rtcp.c DEP_CPP_RTCP_=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ @@ -1600,9 +1588,8 @@ NODEP_CPP_RTCP_=\ SOURCE=..\..\src\ietf\rtp.c DEP_CPP_RTP_C=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ @@ -1622,11 +1609,10 @@ DEP_CPP_RTP_D=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\esi.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\mpeg4_odf.h"\ @@ -1645,10 +1631,9 @@ NODEP_CPP_RTP_D=\ SOURCE=..\..\src\ietf\rtp_packetizer.c DEP_CPP_RTP_P=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -1667,10 +1652,9 @@ NODEP_CPP_RTP_P=\ SOURCE=..\..\src\ietf\rtp_pck_3gpp.c DEP_CPP_RTP_PC=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ @@ -1687,11 +1671,11 @@ NODEP_CPP_RTP_PC=\ SOURCE=..\..\src\ietf\rtp_pck_mpeg12.c DEP_CPP_RTP_PCK=\ + "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ @@ -1709,10 +1693,9 @@ NODEP_CPP_RTP_PCK=\ SOURCE=..\..\src\ietf\rtp_pck_mpeg4.c DEP_CPP_RTP_PCK_=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ @@ -1730,9 +1713,8 @@ NODEP_CPP_RTP_PCK_=\ SOURCE=..\..\src\ietf\rtsp_command.c DEP_CPP_RTSP_=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ @@ -1751,9 +1733,8 @@ NODEP_CPP_RTSP_=\ SOURCE=..\..\src\ietf\rtsp_common.c DEP_CPP_RTSP_C=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ @@ -1772,9 +1753,8 @@ NODEP_CPP_RTSP_C=\ SOURCE=..\..\src\ietf\rtsp_response.c DEP_CPP_RTSP_R=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ @@ -1794,9 +1774,8 @@ SOURCE=..\..\src\ietf\rtsp_session.c DEP_CPP_RTSP_S=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ @@ -1814,9 +1793,8 @@ NODEP_CPP_RTSP_S=\ SOURCE=..\..\src\ietf\sdp.c DEP_CPP_SDP_C=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\network.h"\ "..\..\include\gpac\setup.h"\ @@ -1837,11 +1815,10 @@ NODEP_CPP_SDP_C=\ SOURCE=..\..\src\scenegraph\base_scenegraph.c DEP_CPP_BASE_S=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -1868,10 +1845,9 @@ SOURCE=..\..\src\scenegraph\commands.c DEP_CPP_COMMA=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\laser_dev.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\laser.h"\ @@ -1900,11 +1876,10 @@ NODEP_CPP_COMMA=\ SOURCE=..\..\src\scenegraph\dom_events.c DEP_CPP_DOM_E=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -1935,14 +1910,14 @@ DEP_CPP_DOM_S=\ "..\..\extra_lib\include\js\jslong.h"\ "..\..\extra_lib\include\js\jsosdep.h"\ "..\..\extra_lib\include\js\jsotypes.h"\ + "..\..\extra_lib\include\js\jsproto.tbl"\ "..\..\extra_lib\include\js\jspubtd.h"\ "..\..\extra_lib\include\js\jstypes.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -1960,8 +1935,6 @@ DEP_CPP_DOM_S=\ "..\..\include\gpac\xml.h"\ NODEP_CPP_DOM_S=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ "..\..\include\gpac\config.h"\ # End Source File @@ -1970,10 +1943,9 @@ NODEP_CPP_DOM_S=\ SOURCE=..\..\src\scenegraph\mpeg4_animators.c DEP_CPP_MPEG4=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -1997,10 +1969,9 @@ NODEP_CPP_MPEG4=\ SOURCE=..\..\src\scenegraph\mpeg4_nodes.c DEP_CPP_MPEG4_=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2024,10 +1995,9 @@ NODEP_CPP_MPEG4_=\ SOURCE=..\..\src\scenegraph\mpeg4_valuator.c DEP_CPP_MPEG4_V=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2055,10 +2025,9 @@ SOURCE=..\..\include\gpac\internal\scenegraph_dev.h SOURCE=..\..\src\scenegraph\smil_anim.c DEP_CPP_SMIL_=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2082,11 +2051,10 @@ NODEP_CPP_SMIL_=\ SOURCE=..\..\src\scenegraph\smil_timing.c DEP_CPP_SMIL_T=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2111,16 +2079,16 @@ SOURCE=..\..\src\scenegraph\svg_attributes.c DEP_CPP_SVG_A=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\network.h"\ + "..\..\include\gpac\nodes_svg.h"\ "..\..\include\gpac\path2d.h"\ "..\..\include\gpac\scenegraph.h"\ "..\..\include\gpac\scenegraph_svg.h"\ @@ -2138,10 +2106,9 @@ NODEP_CPP_SVG_A=\ SOURCE=..\..\src\scenegraph\svg_properties.c DEP_CPP_SVG_P=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2171,14 +2138,14 @@ DEP_CPP_SVG_S=\ "..\..\extra_lib\include\js\jslong.h"\ "..\..\extra_lib\include\js\jsosdep.h"\ "..\..\extra_lib\include\js\jsotypes.h"\ + "..\..\extra_lib\include\js\jsproto.tbl"\ "..\..\extra_lib\include\js\jspubtd.h"\ "..\..\extra_lib\include\js\jstypes.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2194,8 +2161,6 @@ DEP_CPP_SVG_S=\ "..\..\include\gpac\tools.h"\ NODEP_CPP_SVG_S=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ "..\..\include\gpac\config.h"\ # End Source File @@ -2204,10 +2169,9 @@ NODEP_CPP_SVG_S=\ SOURCE=..\..\src\scenegraph\svg_types.c DEP_CPP_SVG_T=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2231,10 +2195,9 @@ NODEP_CPP_SVG_T=\ SOURCE=..\..\src\scenegraph\vrml_interpolators.c DEP_CPP_VRML_=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2259,10 +2222,9 @@ NODEP_CPP_VRML_=\ SOURCE=..\..\src\scenegraph\vrml_proto.c DEP_CPP_VRML_P=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2287,10 +2249,9 @@ NODEP_CPP_VRML_P=\ SOURCE=..\..\src\scenegraph\vrml_route.c DEP_CPP_VRML_R=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2315,10 +2276,9 @@ NODEP_CPP_VRML_R=\ SOURCE=..\..\src\scenegraph\vrml_script.c DEP_CPP_VRML_S=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2349,16 +2309,16 @@ DEP_CPP_VRML_SM=\ "..\..\extra_lib\include\js\jslong.h"\ "..\..\extra_lib\include\js\jsosdep.h"\ "..\..\extra_lib\include\js\jsotypes.h"\ + "..\..\extra_lib\include\js\jsproto.tbl"\ "..\..\extra_lib\include\js\jspubtd.h"\ "..\..\extra_lib\include\js\jstypes.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -2369,6 +2329,7 @@ DEP_CPP_VRML_SM=\ "..\..\include\gpac\modules\ipmp.h"\ "..\..\include\gpac\modules\js_usr.h"\ "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\modules\term_ext.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\network.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ @@ -2387,8 +2348,6 @@ DEP_CPP_VRML_SM=\ "..\..\include\gpac\user.h"\ NODEP_CPP_VRML_SM=\ - "..\..\extra_lib\include\js\jsstddef.h"\ - "..\..\extra_lib\include\js\platform.h"\ "..\..\include\gpac\config.h"\ # End Source File @@ -2396,15 +2355,18 @@ NODEP_CPP_VRML_SM=\ SOURCE=..\..\src\scenegraph\vrml_tools.c DEP_CPP_VRML_T=\ + "..\..\include\gpac\bifs.h"\ + "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\internal\bifs_dev.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\network.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ "..\..\include\gpac\nodes_x3d.h"\ @@ -2414,6 +2376,8 @@ DEP_CPP_VRML_T=\ "..\..\include\gpac\scenegraph_vrml.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\svg_types.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\thread.h"\ "..\..\include\gpac\tools.h"\ NODEP_CPP_VRML_T=\ @@ -2425,10 +2389,9 @@ NODEP_CPP_VRML_T=\ SOURCE=..\..\src\scenegraph\x3d_nodes.c DEP_CPP_X3D_N=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2454,10 +2417,9 @@ SOURCE=..\..\src\scenegraph\xbl_process.c DEP_CPP_XBL_P=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -2488,10 +2450,9 @@ SOURCE=..\..\src\scenegraph\xml_ns.c DEP_CPP_XML_N=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2520,9 +2481,9 @@ SOURCE=..\..\src\media_tools\av_parsers.c DEP_CPP_AV_PA=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\ietf.h"\ "..\..\include\gpac\internal\media_dev.h"\ "..\..\include\gpac\internal\ogg.h"\ "..\..\include\gpac\isomedia.h"\ @@ -2530,6 +2491,7 @@ DEP_CPP_AV_PA=\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\media_tools.h"\ "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\network.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ @@ -2542,9 +2504,8 @@ NODEP_CPP_AV_PA=\ SOURCE=..\..\src\media_tools\avilib.c DEP_CPP_AVILI=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\avilib.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -2558,10 +2519,36 @@ SOURCE=..\..\include\gpac\internal\avilib.h # End Source File # Begin Source File +SOURCE=..\..\src\media_tools\filestreamer.c +DEP_CPP_FILES=\ + "..\..\include\gpac\avparse.h"\ + "..\..\include\gpac\base_coding.h"\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\filestreamer.h"\ + "..\..\include\gpac\ietf.h"\ + "..\..\include\gpac\internal\media_dev.h"\ + "..\..\include\gpac\isomedia.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\math.h"\ + "..\..\include\gpac\media_tools.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\network.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\tools.h"\ + +NODEP_CPP_FILES=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\src\media_tools\gpac_ogg.c DEP_CPP_GPAC_=\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\ogg.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -2583,14 +2570,15 @@ DEP_CPP_IMG_C=\ "..\..\extra_lib\include\zlib\zlib.h"\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\ietf.h"\ "..\..\include\gpac\internal\media_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\media_tools.h"\ "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\network.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ @@ -2598,7 +2586,8 @@ DEP_CPP_IMG_C=\ NODEP_CPP_IMG_C=\ "..\..\extra_lib\include\jpeg\jerror.h"\ "..\..\extra_lib\include\jpeg\jpegint.h"\ - "..\..\extra_lib\include\png\alloc.h"\ + "..\..\extra_lib\include\png\config.h"\ + "..\..\extra_lib\include\png\pngusr.h"\ "..\..\include\gpac\config.h"\ # End Source File @@ -2608,10 +2597,9 @@ SOURCE=..\..\src\media_tools\ismacryp.c DEP_CPP_ISMAC=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\ismacryp.h"\ "..\..\include\gpac\isomedia.h"\ @@ -2633,10 +2621,10 @@ DEP_CPP_ISOM_H=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\ietf.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\internal\media_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2657,9 +2645,8 @@ SOURCE=..\..\src\media_tools\isom_tools.c DEP_CPP_ISOM_T=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\media_tools.h"\ @@ -2680,12 +2667,14 @@ SOURCE=..\..\include\gpac\internal\media_dev.h SOURCE=..\..\src\media_tools\media_export.c DEP_CPP_MEDIA_E=\ + "..\..\extra_lib\include\zlib\zconf.h"\ + "..\..\extra_lib\include\zlib\zlib.h"\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\ietf.h"\ "..\..\include\gpac\internal\avilib.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\media_dev.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\internal\ogg.h"\ @@ -2695,6 +2684,7 @@ DEP_CPP_MEDIA_E=\ "..\..\include\gpac\media_tools.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\mpegts.h"\ + "..\..\include\gpac\network.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ @@ -2711,10 +2701,10 @@ DEP_CPP_MEDIA_I=\ "..\..\extra_lib\include\zlib\zlib.h"\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\ietf.h"\ "..\..\include\gpac\internal\avilib.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\media_dev.h"\ "..\..\include\gpac\internal\odf_dev.h"\ "..\..\include\gpac\internal\ogg.h"\ @@ -2724,6 +2714,7 @@ DEP_CPP_MEDIA_I=\ "..\..\include\gpac\media_tools.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\mpegts.h"\ + "..\..\include\gpac\network.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ @@ -2740,8 +2731,7 @@ SOURCE=..\..\src\media_tools\mpeg2_ps.c DEP_CPP_MPEG2=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ "..\..\src\media_tools\mpeg2_ps.h"\ @@ -2756,19 +2746,69 @@ SOURCE=..\..\src\media_tools\mpeg2_ps.h # End Source File # Begin Source File +SOURCE=..\..\src\media_tools\mpegts.c +DEP_CPP_MPEGT=\ + "..\..\include\gpac\avparse.h"\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\ietf.h"\ + "..\..\include\gpac\internal\media_dev.h"\ + "..\..\include\gpac\internal\odf_dev.h"\ + "..\..\include\gpac\isomedia.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\math.h"\ + "..\..\include\gpac\media_tools.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\mpegts.h"\ + "..\..\include\gpac\network.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\tools.h"\ + +NODEP_CPP_MPEGT=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\src\media_tools\saf.c +DEP_CPP_SAF_C=\ + "..\..\include\gpac\avparse.h"\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\ietf.h"\ + "..\..\include\gpac\internal\media_dev.h"\ + "..\..\include\gpac\isomedia.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\media_tools.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\network.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\thread.h"\ + "..\..\include\gpac\tools.h"\ + +NODEP_CPP_SAF_C=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\src\media_tools\text_import.c DEP_CPP_TEXT_=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\ietf.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\internal\media_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\media_tools.h"\ "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\network.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\token.h"\ @@ -2782,6 +2822,20 @@ NODEP_CPP_TEXT_=\ # End Source File # Begin Source File +SOURCE=..\..\src\media_tools\vobsub.c +DEP_CPP_VOBSU=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\internal\vobsub.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\tools.h"\ + +NODEP_CPP_VOBSU=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\include\gpac\internal\vobsub.h # End Source File # End Group @@ -2795,9 +2849,8 @@ DEP_CPP_ENCOD=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bifsengine.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -2822,10 +2875,9 @@ DEP_CPP_ENCODE=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\laser.h"\ @@ -2860,12 +2912,11 @@ DEP_CPP_LOADE=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -2898,9 +2949,8 @@ SOURCE=..\..\src\scene_manager\loader_isom.c DEP_CPP_LOADER=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\laser.h"\ "..\..\include\gpac\list.h"\ @@ -2928,15 +2978,16 @@ SOURCE=..\..\src\scene_manager\loader_qt.c DEP_CPP_LOADER_=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\ietf.h"\ "..\..\include\gpac\internal\media_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\media_tools.h"\ "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\network.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ "..\..\include\gpac\scene_manager.h"\ "..\..\include\gpac\scenegraph.h"\ @@ -2954,19 +3005,24 @@ NODEP_CPP_LOADER_=\ SOURCE=..\..\src\scene_manager\loader_svg.c DEP_CPP_LOADER_S=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\laser_dev.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ + "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\laser.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ + "..\..\include\gpac\mediaobject.h"\ "..\..\include\gpac\module.h"\ + "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\modules\ipmp.h"\ + "..\..\include\gpac\modules\service.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\network.h"\ "..\..\include\gpac\nodes_svg.h"\ @@ -2978,7 +3034,10 @@ DEP_CPP_LOADER_S=\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\svg_types.h"\ "..\..\include\gpac\sync_layer.h"\ + "..\..\include\gpac\terminal.h"\ + "..\..\include\gpac\thread.h"\ "..\..\include\gpac\tools.h"\ + "..\..\include\gpac\user.h"\ "..\..\include\gpac\utf.h"\ "..\..\include\gpac\xml.h"\ @@ -2993,11 +3052,10 @@ DEP_CPP_LOADER_X=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -3032,12 +3090,11 @@ DEP_CPP_SCENE=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\bifs_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -3073,10 +3130,9 @@ DEP_CPP_SCENE_=\ "..\..\include\gpac\bifs.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -3107,10 +3163,9 @@ SOURCE=..\..\src\scene_manager\scene_stats.c DEP_CPP_SCENE_S=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -3139,10 +3194,9 @@ DEP_CPP_SWF_B=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\internal\swf_dev.h"\ "..\..\include\gpac\isomedia.h"\ @@ -3181,9 +3235,8 @@ DEP_CPP_SWF_P=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\swf_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -3207,15 +3260,16 @@ SOURCE=..\..\src\scene_manager\text_to_bifs.c DEP_CPP_TEXT_T=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\ietf.h"\ "..\..\include\gpac\internal\media_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\media_tools.h"\ "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\network.h"\ "..\..\include\gpac\scene_manager.h"\ "..\..\include\gpac\scenegraph.h"\ "..\..\include\gpac\scenegraph_vrml.h"\ @@ -3237,9 +3291,8 @@ NODEP_CPP_TEXT_T=\ SOURCE=..\..\src\mcrypt\cbc.c DEP_CPP_CBC_C=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3252,9 +3305,8 @@ NODEP_CPP_CBC_C=\ SOURCE=..\..\src\mcrypt\cfb.c DEP_CPP_CFB_C=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3271,9 +3323,8 @@ SOURCE=..\..\include\gpac\internal\crypt_dev.h SOURCE=..\..\src\mcrypt\ctr.c DEP_CPP_CTR_C=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3286,9 +3337,8 @@ NODEP_CPP_CTR_C=\ SOURCE=..\..\src\mcrypt\des.c DEP_CPP_DES_C=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3301,9 +3351,8 @@ NODEP_CPP_DES_C=\ SOURCE=..\..\src\mcrypt\ecb.c DEP_CPP_ECB_C=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3316,9 +3365,8 @@ NODEP_CPP_ECB_C=\ SOURCE=..\..\src\mcrypt\g_crypt.c DEP_CPP_G_CRY=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3331,9 +3379,8 @@ NODEP_CPP_G_CRY=\ SOURCE=..\..\src\mcrypt\ncfb.c DEP_CPP_NCFB_=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3346,9 +3393,8 @@ NODEP_CPP_NCFB_=\ SOURCE=..\..\src\mcrypt\nofb.c DEP_CPP_NOFB_=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3361,9 +3407,8 @@ NODEP_CPP_NOFB_=\ SOURCE=..\..\src\mcrypt\ofb.c DEP_CPP_OFB_C=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3376,9 +3421,8 @@ NODEP_CPP_OFB_C=\ SOURCE="..\..\src\mcrypt\rijndael-128.c" DEP_CPP_RIJND=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3391,9 +3435,8 @@ NODEP_CPP_RIJND=\ SOURCE="..\..\src\mcrypt\rijndael-192.c" DEP_CPP_RIJNDA=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3406,9 +3449,8 @@ NODEP_CPP_RIJNDA=\ SOURCE="..\..\src\mcrypt\rijndael-256.c" DEP_CPP_RIJNDAE=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3421,9 +3463,8 @@ NODEP_CPP_RIJNDAE=\ SOURCE=..\..\src\mcrypt\sha1.c DEP_CPP_SHA1_=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3435,9 +3476,8 @@ NODEP_CPP_SHA1_=\ SOURCE=..\..\src\mcrypt\stream.c DEP_CPP_STREA=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3450,9 +3490,8 @@ NODEP_CPP_STREA=\ SOURCE=..\..\src\mcrypt\tripledes.c DEP_CPP_TRIPL=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\crypt.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\crypt_dev.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ @@ -3473,13 +3512,12 @@ DEP_CPP_CHANN=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -3520,11 +3558,10 @@ DEP_CPP_CLOCK=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -3555,13 +3592,12 @@ DEP_CPP_DECOD=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -3598,25 +3634,31 @@ NODEP_CPP_DECOD=\ # End Source File # Begin Source File -SOURCE=..\..\src\terminal\inline.c -DEP_CPP_INLIN=\ +SOURCE=..\..\src\terminal\input_sensor.c +DEP_CPP_INPUT=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\internal\camera.h"\ + "..\..\include\gpac\internal\compositor_dev.h"\ + "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.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\ipmp.h"\ + "..\..\include\gpac\modules\raster2d.h"\ "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\modules\video_out.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ "..\..\include\gpac\nodes_x3d.h"\ @@ -3631,44 +3673,6 @@ DEP_CPP_INLIN=\ "..\..\include\gpac\thread.h"\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ - "..\..\src\terminal\media_control.h"\ - -NODEP_CPP_INLIN=\ - "..\..\include\gpac\config.h"\ - -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\input_sensor.c -DEP_CPP_INPUT=\ - "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\color.h"\ - "..\..\include\gpac\compositor.h"\ - "..\..\include\gpac\config_file.h"\ - "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\download.h"\ - "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ - "..\..\include\gpac\internal\terminal_dev.h"\ - "..\..\include\gpac\list.h"\ - "..\..\include\gpac\math.h"\ - "..\..\include\gpac\mediaobject.h"\ - "..\..\include\gpac\module.h"\ - "..\..\include\gpac\modules\codec.h"\ - "..\..\include\gpac\modules\ipmp.h"\ - "..\..\include\gpac\modules\service.h"\ - "..\..\include\gpac\mpeg4_odf.h"\ - "..\..\include\gpac\nodes_mpeg4.h"\ - "..\..\include\gpac\nodes_x3d.h"\ - "..\..\include\gpac\scenegraph.h"\ - "..\..\include\gpac\scenegraph_vrml.h"\ - "..\..\include\gpac\setup.h"\ - "..\..\include\gpac\sync_layer.h"\ - "..\..\include\gpac\terminal.h"\ - "..\..\include\gpac\thread.h"\ - "..\..\include\gpac\tools.h"\ - "..\..\include\gpac\user.h"\ "..\..\include\gpac\utf.h"\ "..\..\src\terminal\input_sensor.h"\ @@ -3687,11 +3691,10 @@ DEP_CPP_MEDIA_C=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -3728,13 +3731,12 @@ DEP_CPP_MEDIA_M=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -3773,11 +3775,10 @@ DEP_CPP_MEDIA_ME=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -3815,13 +3816,12 @@ DEP_CPP_MEDIA_O=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ @@ -3866,11 +3866,10 @@ DEP_CPP_MEDIA_S=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -3897,16 +3896,56 @@ NODEP_CPP_MEDIA_S=\ # End Source File # Begin Source File +SOURCE=..\..\src\terminal\mpeg4_inline.c +DEP_CPP_MPEG4_I=\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\color.h"\ + "..\..\include\gpac\compositor.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\download.h"\ + "..\..\include\gpac\events.h"\ + "..\..\include\gpac\internal\terminal_dev.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\math.h"\ + "..\..\include\gpac\mediaobject.h"\ + "..\..\include\gpac\module.h"\ + "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\modules\ipmp.h"\ + "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\network.h"\ + "..\..\include\gpac\nodes_mpeg4.h"\ + "..\..\include\gpac\nodes_x3d.h"\ + "..\..\include\gpac\path2d.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\terminal.h"\ + "..\..\include\gpac\thread.h"\ + "..\..\include\gpac\tools.h"\ + "..\..\include\gpac\user.h"\ + "..\..\src\terminal\media_control.h"\ + +NODEP_CPP_MPEG4_I=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\src\terminal\network_service.c DEP_CPP_NETWO=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -3937,11 +3976,10 @@ DEP_CPP_OBJEC=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\isomedia.h"\ "..\..\include\gpac\list.h"\ @@ -3980,11 +4018,10 @@ DEP_CPP_OBJECT=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4013,17 +4050,57 @@ NODEP_CPP_OBJECT=\ # End Source File # Begin Source File +SOURCE=..\..\src\terminal\scene.c +DEP_CPP_SCENE_C=\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\color.h"\ + "..\..\include\gpac\compositor.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\download.h"\ + "..\..\include\gpac\events.h"\ + "..\..\include\gpac\internal\terminal_dev.h"\ + "..\..\include\gpac\list.h"\ + "..\..\include\gpac\math.h"\ + "..\..\include\gpac\mediaobject.h"\ + "..\..\include\gpac\module.h"\ + "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\modules\ipmp.h"\ + "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ + "..\..\include\gpac\network.h"\ + "..\..\include\gpac\nodes_mpeg4.h"\ + "..\..\include\gpac\nodes_x3d.h"\ + "..\..\include\gpac\path2d.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\terminal.h"\ + "..\..\include\gpac\thread.h"\ + "..\..\include\gpac\tools.h"\ + "..\..\include\gpac\user.h"\ + "..\..\src\terminal\media_control.h"\ + +NODEP_CPP_SCENE_C=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\src\terminal\svg_external.c DEP_CPP_SVG_E=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -4060,13 +4137,12 @@ DEP_CPP_TERM_=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -4084,6 +4160,7 @@ DEP_CPP_TERM_=\ "..\..\include\gpac\nodes_mpeg4.h"\ "..\..\include\gpac\nodes_svg.h"\ "..\..\include\gpac\nodes_x3d.h"\ + "..\..\include\gpac\options.h"\ "..\..\include\gpac\path2d.h"\ "..\..\include\gpac\scenegraph.h"\ "..\..\include\gpac\scenegraph_svg.h"\ @@ -4109,13 +4186,12 @@ DEP_CPP_TERMI=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ @@ -4148,6 +4224,7 @@ DEP_CPP_TERMI=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ "..\..\include\gpac\xml.h"\ + "..\..\src\terminal\media_memory.h"\ NODEP_CPP_TERMI=\ "..\..\include\gpac\config.h"\ @@ -4171,11 +4248,10 @@ SOURCE=..\..\src\laser\lsr_dec.c DEP_CPP_LSR_D=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\laser_dev.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\laser.h"\ @@ -4204,11 +4280,10 @@ SOURCE=..\..\src\laser\lsr_enc.c DEP_CPP_LSR_E=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\laser_dev.h"\ "..\..\include\gpac\internal\scenegraph_dev.h"\ "..\..\include\gpac\laser.h"\ @@ -4236,9 +4311,8 @@ NODEP_CPP_LSR_E=\ SOURCE=..\..\src\laser\lsr_tables.c DEP_CPP_LSR_T=\ "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\laser_dev.h"\ "..\..\include\gpac\laser.h"\ "..\..\include\gpac\list.h"\ @@ -4268,12 +4342,11 @@ DEP_CPP_AUDIO=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4304,12 +4377,11 @@ DEP_CPP_AUDIO_=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4340,12 +4412,11 @@ DEP_CPP_AUDIO_R=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4376,12 +4447,11 @@ DEP_CPP_BINDA=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4414,9 +4484,8 @@ NODEP_CPP_BINDA=\ SOURCE=..\..\src\compositor\camera.c DEP_CPP_CAMER=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\internal\camera.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\options.h"\ @@ -4445,13 +4514,12 @@ DEP_CPP_COMPO=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -4491,6 +4559,7 @@ DEP_CPP_COMPO=\ NODEP_CPP_COMPO=\ "..\..\include\gpac\config.h"\ + "..\..\src\compositor\chrono.h"\ "..\..\src\src\compositor\triscope_renoir\triscope_renoir.h"\ # End Source File @@ -4501,12 +4570,11 @@ DEP_CPP_COMPOS=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4544,16 +4612,14 @@ NODEP_CPP_COMPOS=\ SOURCE=..\..\src\compositor\compositor_3d.c DEP_CPP_COMPOSI=\ - "..\..\..\TinyGL\include\GL\oscontext.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4598,12 +4664,11 @@ DEP_CPP_COMPOSIT=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4639,12 +4704,11 @@ DEP_CPP_DRAWA=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4688,13 +4752,12 @@ DEP_CPP_EVENT=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -4743,12 +4806,11 @@ DEP_CPP_FONT_=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4793,12 +4855,11 @@ DEP_CPP_HARDC=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4836,13 +4897,11 @@ NODEP_CPP_HARDC=\ SOURCE=..\..\src\compositor\mesh.c DEP_CPP_MESH_=\ - "..\..\..\TinyGL\include\GL\gl.h"\ "..\..\extra_lib\include\GLES\egl.h"\ "..\..\extra_lib\include\GLES\gl.h"\ "..\..\include\gpac\color.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4867,9 +4926,8 @@ SOURCE=..\..\include\gpac\internal\mesh.h SOURCE=..\..\src\compositor\mesh_collide.c DEP_CPP_MESH_C=\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4887,13 +4945,11 @@ NODEP_CPP_MESH_C=\ SOURCE=..\..\src\compositor\mesh_tesselate.c DEP_CPP_MESH_T=\ - "..\..\..\TinyGL\include\GL\gl.h"\ "..\..\extra_lib\include\GLES\egl.h"\ "..\..\extra_lib\include\GLES\gl.h"\ "..\..\include\gpac\color.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4915,12 +4971,11 @@ DEP_CPP_MPEG4_A=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4956,12 +5011,11 @@ DEP_CPP_MPEG4_AU=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -4997,12 +5051,11 @@ DEP_CPP_MPEG4_B=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5042,12 +5095,11 @@ DEP_CPP_MPEG4_BA=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5088,12 +5140,11 @@ DEP_CPP_MPEG4_BI=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5130,16 +5181,14 @@ NODEP_CPP_MPEG4_BI=\ SOURCE=..\..\src\compositor\mpeg4_composite.c DEP_CPP_MPEG4_C=\ - "..\..\..\TinyGL\include\GL\oscontext.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5179,12 +5228,11 @@ DEP_CPP_MPEG4_F=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5224,12 +5272,11 @@ DEP_CPP_MPEG4_G=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5268,12 +5315,11 @@ DEP_CPP_MPEG4_GE=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5313,12 +5359,11 @@ DEP_CPP_MPEG4_GEO=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5357,12 +5402,11 @@ DEP_CPP_MPEG4_GEOM=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5401,12 +5445,11 @@ DEP_CPP_MPEG4_GR=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5443,12 +5486,11 @@ DEP_CPP_MPEG4_GRO=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5492,12 +5534,11 @@ DEP_CPP_MPEG4_GROU=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5537,12 +5578,11 @@ DEP_CPP_MPEG4_GROUP=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5582,12 +5622,11 @@ DEP_CPP_MPEG4_L=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5624,16 +5663,14 @@ NODEP_CPP_MPEG4_L=\ SOURCE=..\..\src\compositor\mpeg4_layer_3d.c DEP_CPP_MPEG4_LA=\ - "..\..\..\TinyGL\include\GL\oscontext.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5674,12 +5711,11 @@ DEP_CPP_MPEG4_LAY=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5719,12 +5755,11 @@ DEP_CPP_MPEG4_LI=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5763,12 +5798,11 @@ DEP_CPP_MPEG4_P=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5809,13 +5843,12 @@ DEP_CPP_MPEG4_S=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -5862,12 +5895,11 @@ DEP_CPP_MPEG4_SO=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5906,12 +5938,11 @@ DEP_CPP_MPEG4_T=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5954,12 +5985,11 @@ DEP_CPP_MPEG4_TE=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -5993,12 +6023,11 @@ DEP_CPP_MPEG4_TI=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6035,13 +6064,12 @@ DEP_CPP_MPEG4_VI=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -6088,12 +6116,11 @@ DEP_CPP_NAVIG=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6137,12 +6164,11 @@ DEP_CPP_OFFSC=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6184,12 +6210,11 @@ DEP_CPP_SVG_B=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6228,12 +6253,11 @@ DEP_CPP_SVG_F=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6273,12 +6297,11 @@ DEP_CPP_SVG_G=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6318,13 +6341,12 @@ DEP_CPP_SVG_GR=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -6372,12 +6394,11 @@ DEP_CPP_SVG_M=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6416,12 +6437,11 @@ DEP_CPP_SVG_PA=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6461,12 +6481,11 @@ DEP_CPP_SVG_TE=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6507,13 +6526,12 @@ DEP_CPP_TEXTU=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ @@ -6560,18 +6578,16 @@ SOURCE=..\..\src\compositor\texturing.h SOURCE=..\..\src\compositor\texturing_gl.c DEP_CPP_TEXTUR=\ - "..\..\..\TinyGL\include\GL\gl.h"\ "..\..\extra_lib\include\GLES\egl.h"\ "..\..\extra_lib\include\GLES\gl.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6612,12 +6628,11 @@ DEP_CPP_VISUA=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6628,6 +6643,8 @@ DEP_CPP_VISUA=\ "..\..\include\gpac\modules\raster2d.h"\ "..\..\include\gpac\modules\video_out.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ + "..\..\include\gpac\nodes_svg.h"\ + "..\..\include\gpac\nodes_x3d.h"\ "..\..\include\gpac\path2d.h"\ "..\..\include\gpac\scenegraph.h"\ "..\..\include\gpac\scenegraph_svg.h"\ @@ -6638,6 +6655,7 @@ DEP_CPP_VISUA=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ "..\..\src\compositor\drawable.h"\ + "..\..\src\compositor\nodes_stacks.h"\ "..\..\src\compositor\visual_manager.h"\ "..\..\src\compositor\visual_manager_2d.h"\ "..\..\src\compositor\visual_manager_3d.h"\ @@ -6657,12 +6675,11 @@ DEP_CPP_VISUAL=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6705,12 +6722,11 @@ DEP_CPP_VISUAL_=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6751,12 +6767,11 @@ DEP_CPP_VISUAL_M=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6798,18 +6813,16 @@ SOURCE=..\..\src\compositor\visual_manager_3d.h SOURCE=..\..\src\compositor\visual_manager_3d_gl.c DEP_CPP_VISUAL_MA=\ - "..\..\..\TinyGL\include\GL\gl.h"\ "..\..\extra_lib\include\GLES\egl.h"\ "..\..\extra_lib\include\GLES\gl.h"\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6846,12 +6859,11 @@ DEP_CPP_X3D_G=\ "..\..\include\gpac\color.h"\ "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\camera.h"\ "..\..\include\gpac\internal\compositor_dev.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\internal\mesh.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ @@ -6921,15 +6933,11 @@ SOURCE=..\..\include\gpac\compositor.h # End Source File # Begin Source File -SOURCE=..\..\include\gpac\config.h -# End Source File -# Begin Source File - SOURCE=..\..\include\gpac\config_file.h # End Source File # Begin Source File -SOURCE=..\..\include\gpac\internal\config_static.h +SOURCE=..\..\include\gpac\configuration.h # End Source File # Begin Source File diff --git a/build/msevc4/libgpac_dll.vcp b/build/msevc4/libgpac_dll.vcp index eb4ffc4..ba93a91 100644 --- a/build/msevc4/libgpac_dll.vcp +++ b/build/msevc4/libgpac_dll.vcp @@ -50,7 +50,7 @@ RSC=rc.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "LIBGPAC_DLL_EXPORTS" /YX /O2 /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /Oxt /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /M$(CECrtMT) /c +# ADD CPP /nologo /W3 /Oxt /I "../../include" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /M$(CECrtMT) /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 @@ -81,7 +81,7 @@ LINK32=link.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "DEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /D "LIBGPAC_DLL_EXPORTS" /YX /M$(CECrtMTDebug) /c -# ADD CPP /nologo /W3 /Zi /Od /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c +# ADD CPP /nologo /W3 /Zi /Od /I "../../include" /D "DEBUG" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "_USRDLL" /M$(CECrtMTDebug) /c # SUBTRACT CPP /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /o "NUL" /win32 @@ -100,7 +100,14 @@ LINK32=link.exe # Name "libgpac_dll - Win32 (WCE ARMV4) Debug" # Begin Source File -SOURCE=..\..\src\libgpac_ce.def +SOURCE=..\..\src\export.cpp +DEP_CPP_EXPOR=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_EXPOR=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/mp3_in.vcp b/build/msevc4/mp3_in.vcp index 827c504..9241eed 100644 --- a/build/msevc4/mp3_in.vcp +++ b/build/msevc4/mp3_in.vcp @@ -103,13 +103,32 @@ LINK32=link.exe SOURCE=..\..\modules\mp3_in\mad_dec.c DEP_CPP_MAD_D=\ "..\..\extra_lib\include\mad\mad.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\bitstream.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ + "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ +NODEP_CPP_MAD_D=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -117,7 +136,8 @@ SOURCE=..\..\modules\mp3_in\mp3_in.c DEP_CPP_MP3_I=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\list.h"\ @@ -129,10 +149,9 @@ DEP_CPP_MP3_I=\ "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ -# End Source File -# Begin Source File - -SOURCE=..\..\modules\mp3_in\mp3_in.def +NODEP_CPP_MP3_I=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/odf_dec.vcp b/build/msevc4/odf_dec.vcp index 65b852f..623bf3a 100644 --- a/build/msevc4/odf_dec.vcp +++ b/build/msevc4/odf_dec.vcp @@ -100,20 +100,35 @@ LINK32=link.exe # Name "odf_dec - Win32 (WCE ARMV4) Debug" # Begin Source File +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\modules\odf_dec\odf_dec.c DEP_CPP_ODF_D=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\color.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ "..\..\include\gpac\download.h"\ + "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\mediaobject.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\modules\ipmp.h"\ "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\modules\term_ext.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\scenegraph.h"\ "..\..\include\gpac\scenegraph_vrml.h"\ @@ -124,10 +139,9 @@ DEP_CPP_ODF_D=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ -# End Source File -# Begin Source File - -SOURCE=..\..\modules\odf_dec\odf_dec.def +NODEP_CPP_ODF_D=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/osmophone.vcp b/build/msevc4/osmophone.vcp index 7f0e9b1..9a26e59 100644 --- a/build/msevc4/osmophone.vcp +++ b/build/msevc4/osmophone.vcp @@ -105,21 +105,39 @@ SOURCE=..\..\applications\osmophone\main.cpp DEP_CPP_MAIN_=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ + "..\..\include\gpac\compositor.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\internal\camera.h"\ + "..\..\include\gpac\internal\compositor_dev.h"\ + "..\..\include\gpac\internal\mesh.h"\ + "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\math.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\ipmp.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\options.h"\ + "..\..\include\gpac\path2d.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\terminal.h"\ + "..\..\include\gpac\thread.h"\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ {$(INCLUDE)}"aygshell.h"\ @@ -129,7 +147,7 @@ DEP_CPP_MAIN_=\ NODEP_CPP_MAIN_=\ "..\..\include\gpac\config.h"\ - "C:\Program Files\Windows CE Tools\wce420\POCKET PC 2003\Include\ARMV4\vibrate.h"\ + "C:\Program Files\WindowsCE\wce420\POCKET PC 2003\Include\ARMV4\vibrate.h"\ # End Source File # Begin Source File @@ -137,8 +155,7 @@ NODEP_CPP_MAIN_=\ SOURCE=..\..\applications\osmophone\openfile.cpp DEP_CPP_OPENF=\ "..\..\include\gpac\config_file.h"\ - "..\..\include\gpac\internal\config.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ {$(INCLUDE)}"aygshell.h"\ @@ -147,7 +164,7 @@ DEP_CPP_OPENF=\ NODEP_CPP_OPENF=\ "..\..\include\gpac\config.h"\ - "C:\Program Files\Windows CE Tools\wce420\POCKET PC 2003\Include\ARMV4\vibrate.h"\ + "C:\Program Files\WindowsCE\wce420\POCKET PC 2003\Include\ARMV4\vibrate.h"\ # End Source File # Begin Source File diff --git a/build/msevc4/rtp_in.vcp b/build/msevc4/rtp_in.vcp index 7adc46b..d542fc7 100644 --- a/build/msevc4/rtp_in.vcp +++ b/build/msevc4/rtp_in.vcp @@ -98,16 +98,25 @@ LINK32=link.exe # Name "rtp_in - Win32 (WCE ARMV4) Release" # Name "rtp_in - Win32 (WCE ARMV4) Debug" -# Begin Group "Source Files" +# Begin Source File -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + +# End Source File # Begin Source File SOURCE=..\..\modules\rtp_in\rtp_in.c DEP_CPP_RTP_I=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\ietf.h"\ @@ -122,10 +131,13 @@ DEP_CPP_RTP_I=\ "..\..\include\gpac\tools.h"\ "..\..\modules\rtp_in\rtp_in.h"\ +NODEP_CPP_RTP_I=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File -SOURCE=..\..\modules\rtp_in\rtp_in.def +SOURCE=..\..\modules\rtp_in\rtp_in.h # End Source File # Begin Source File @@ -133,7 +145,8 @@ SOURCE=..\..\modules\rtp_in\rtp_session.c DEP_CPP_RTP_S=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\ietf.h"\ @@ -148,6 +161,9 @@ DEP_CPP_RTP_S=\ "..\..\include\gpac\tools.h"\ "..\..\modules\rtp_in\rtp_in.h"\ +NODEP_CPP_RTP_S=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -155,7 +171,8 @@ SOURCE=..\..\modules\rtp_in\rtp_signaling.c DEP_CPP_RTP_SI=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\ietf.h"\ @@ -170,6 +187,9 @@ DEP_CPP_RTP_SI=\ "..\..\include\gpac\tools.h"\ "..\..\modules\rtp_in\rtp_in.h"\ +NODEP_CPP_RTP_SI=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -177,10 +197,12 @@ SOURCE=..\..\modules\rtp_in\rtp_stream.c DEP_CPP_RTP_ST=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\ietf.h"\ + "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\service.h"\ @@ -192,6 +214,9 @@ DEP_CPP_RTP_ST=\ "..\..\include\gpac\tools.h"\ "..\..\modules\rtp_in\rtp_in.h"\ +NODEP_CPP_RTP_ST=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -199,7 +224,8 @@ SOURCE=..\..\modules\rtp_in\sdp_fetch.c DEP_CPP_SDP_F=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\ietf.h"\ @@ -214,6 +240,9 @@ DEP_CPP_SDP_F=\ "..\..\include\gpac\tools.h"\ "..\..\modules\rtp_in\rtp_in.h"\ +NODEP_CPP_SDP_F=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -221,10 +250,12 @@ SOURCE=..\..\modules\rtp_in\sdp_load.c DEP_CPP_SDP_L=\ "..\..\include\gpac\base_coding.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\ietf.h"\ + "..\..\include\gpac\internal\ietf_dev.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\service.h"\ @@ -236,19 +267,9 @@ DEP_CPP_SDP_L=\ "..\..\include\gpac\tools.h"\ "..\..\modules\rtp_in\rtp_in.h"\ +NODEP_CPP_SDP_L=\ + "..\..\include\gpac\config.h"\ + # End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_in.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group # End Target # End Project diff --git a/build/msevc4/saf_in.vcp b/build/msevc4/saf_in.vcp index 7f6d370..2c1a291 100644 --- a/build/msevc4/saf_in.vcp +++ b/build/msevc4/saf_in.vcp @@ -96,18 +96,26 @@ LINK32=link.exe # Name "saf_in - Win32 (WCE ARMV4) Release" # Name "saf_in - Win32 (WCE ARMV4) Debug" -# Begin Group "Source Files" +# Begin Source File -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + +# End Source File # Begin Source File SOURCE=..\..\modules\saf_in\saf_in.c DEP_CPP_SAF_I=\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ @@ -118,19 +126,9 @@ DEP_CPP_SAF_I=\ "..\..\include\gpac\thread.h"\ "..\..\include\gpac\tools.h"\ +NODEP_CPP_SAF_I=\ + "..\..\include\gpac\config.h"\ + # End Source File -# Begin Source File - -SOURCE=..\..\modules\saf_in\saf_in.def -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group # End Target # End Project diff --git a/build/msevc4/soft_rast.vcp b/build/msevc4/soft_rast.vcp index 4aa25b1..9ce44e6 100644 --- a/build/msevc4/soft_rast.vcp +++ b/build/msevc4/soft_rast.vcp @@ -98,15 +98,13 @@ LINK32=link.exe # Name "soft_rast - Win32 (WCE ARMV4) Release" # Name "soft_rast - Win32 (WCE ARMV4) Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\..\modules\soft_raster\ftgrays.c DEP_CPP_FTGRA=\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ @@ -116,17 +114,32 @@ DEP_CPP_FTGRA=\ "..\..\include\gpac\tools.h"\ "..\..\modules\soft_raster\rast_soft.h"\ +NODEP_CPP_FTGRA=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File -SOURCE=..\..\modules\soft_raster\rast_soft.def +SOURCE=..\..\modules\soft_raster\rast_soft.h # End Source File # Begin Source File SOURCE=..\..\modules\soft_raster\raster_565.c DEP_CPP_RASTE=\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ @@ -136,13 +149,17 @@ DEP_CPP_RASTE=\ "..\..\include\gpac\tools.h"\ "..\..\modules\soft_raster\rast_soft.h"\ +NODEP_CPP_RASTE=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File SOURCE=..\..\modules\soft_raster\raster_argb.c DEP_CPP_RASTER=\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ @@ -152,13 +169,17 @@ DEP_CPP_RASTER=\ "..\..\include\gpac\tools.h"\ "..\..\modules\soft_raster\rast_soft.h"\ +NODEP_CPP_RASTER=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File SOURCE=..\..\modules\soft_raster\raster_load.c DEP_CPP_RASTER_=\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ @@ -168,13 +189,17 @@ DEP_CPP_RASTER_=\ "..\..\include\gpac\tools.h"\ "..\..\modules\soft_raster\rast_soft.h"\ +NODEP_CPP_RASTER_=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File SOURCE=..\..\modules\soft_raster\raster_rgb.c DEP_CPP_RASTER_R=\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ @@ -184,13 +209,17 @@ DEP_CPP_RASTER_R=\ "..\..\include\gpac\tools.h"\ "..\..\modules\soft_raster\rast_soft.h"\ +NODEP_CPP_RASTER_R=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File SOURCE=..\..\modules\soft_raster\stencil.c DEP_CPP_STENC=\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ @@ -200,13 +229,17 @@ DEP_CPP_STENC=\ "..\..\include\gpac\tools.h"\ "..\..\modules\soft_raster\rast_soft.h"\ +NODEP_CPP_STENC=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File SOURCE=..\..\modules\soft_raster\surface.c DEP_CPP_SURFA=\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\math.h"\ "..\..\include\gpac\module.h"\ @@ -216,19 +249,9 @@ DEP_CPP_SURFA=\ "..\..\include\gpac\tools.h"\ "..\..\modules\soft_raster\rast_soft.h"\ +NODEP_CPP_SURFA=\ + "..\..\include\gpac\config.h"\ + # End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\modules\soft_raster\rast_soft.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group # End Target # End Project diff --git a/build/msevc4/svg_in.vcp b/build/msevc4/svg_in.vcp index ac6d461..5763820 100644 --- a/build/msevc4/svg_in.vcp +++ b/build/msevc4/svg_in.vcp @@ -50,7 +50,7 @@ RSC=rc.exe # ADD BASE RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD RSC /l 0x409 /d UNDER_CE=$(CEVersion) /d _WIN32_WCE=$(CEVersion) /d "NDEBUG" /d "UNICODE" /d "_UNICODE" /d "$(CePlatform)" /d "ARM" /d "_ARM_" /d "ARMV4" /r # ADD BASE CPP /nologo /W3 /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "SVG_IN_EXPORTS" /YX /O2 /M$(CECrtMT) /c -# ADD CPP /nologo /W3 /Oxt /I "../../include" /I "../../extra_lib/include/zlib" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "SVG_IN_EXPORTS" /YX /M$(CECrtMT) /c +# ADD CPP /nologo /W3 /Oxt /I "../../include" /I "../../extra_lib/include/zlib" /D _WIN32_WCE=$(CEVersion) /D "$(CePlatform)" /D "ARM" /D "_ARM_" /D "ARMV4" /D UNDER_CE=$(CEVersion) /D "UNICODE" /D "_UNICODE" /D "NDEBUG" /D "_USRDLL" /D "SVG_IN_EXPORTS" /YX /M$(CECrtMT) /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /o "NUL" /win32 BSC32=bscmake.exe @@ -96,9 +96,17 @@ LINK32=link.exe # Name "svg_in - Win32 (WCE ARMV4) Release" # Name "svg_in - Win32 (WCE ARMV4) Debug" -# Begin Group "Source Files" +# Begin Source File -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + +# End Source File # Begin Source File SOURCE=..\..\modules\svg_in\svg_in.c @@ -107,7 +115,8 @@ DEP_CPP_SVG_I=\ "..\..\extra_lib\include\zlib\zlib.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\color.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\events.h"\ @@ -120,6 +129,7 @@ DEP_CPP_SVG_I=\ "..\..\include\gpac\modules\codec.h"\ "..\..\include\gpac\modules\ipmp.h"\ "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\modules\term_ext.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\scene_manager.h"\ "..\..\include\gpac\scenegraph.h"\ @@ -131,19 +141,9 @@ DEP_CPP_SVG_I=\ "..\..\include\gpac\tools.h"\ "..\..\include\gpac\user.h"\ +NODEP_CPP_SVG_I=\ + "..\..\include\gpac\config.h"\ + # End Source File -# Begin Source File - -SOURCE=..\..\modules\svg_in\svg_in.def -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group # End Target # End Project diff --git a/build/msevc4/timedtext.vcp b/build/msevc4/timedtext.vcp index 42c49e3..781acb9 100644 --- a/build/msevc4/timedtext.vcp +++ b/build/msevc4/timedtext.vcp @@ -100,17 +100,26 @@ LINK32=link.exe # Name "timedtext - Win32 (WCE ARMV4) Debug" # Begin Source File -SOURCE=..\..\modules\timedtext\timedtext.def +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File SOURCE=..\..\modules\timedtext\timedtext_dec.c DEP_CPP_TIMED=\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\color.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\crypt.h"\ "..\..\include\gpac\download.h"\ + "..\..\include\gpac\events.h"\ "..\..\include\gpac\internal\isomedia_dev.h"\ "..\..\include\gpac\internal\terminal_dev.h"\ "..\..\include\gpac\isomedia.h"\ @@ -119,7 +128,9 @@ DEP_CPP_TIMED=\ "..\..\include\gpac\mediaobject.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\modules\ipmp.h"\ "..\..\include\gpac\modules\service.h"\ + "..\..\include\gpac\modules\term_ext.h"\ "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\nodes_mpeg4.h"\ "..\..\include\gpac\scenegraph.h"\ @@ -132,6 +143,9 @@ DEP_CPP_TIMED=\ "..\..\include\gpac\user.h"\ "..\..\include\gpac\utf.h"\ +NODEP_CPP_TIMED=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -139,7 +153,8 @@ SOURCE=..\..\modules\timedtext\timedtext_in.c DEP_CPP_TIMEDT=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ - "..\..\include\gpac\config.h"\ + "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ "..\..\include\gpac\download.h"\ "..\..\include\gpac\isomedia.h"\ @@ -153,6 +168,9 @@ DEP_CPP_TIMEDT=\ "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ +NODEP_CPP_TIMEDT=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/wav_out.vcp b/build/msevc4/wav_out.vcp index 43214c9..8b13f3c 100644 --- a/build/msevc4/wav_out.vcp +++ b/build/msevc4/wav_out.vcp @@ -100,20 +100,30 @@ LINK32=link.exe # Name "wav_out - Win32 (WCE ARMV4) Debug" # Begin Source File +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + +# End Source File +# Begin Source File + SOURCE=..\..\modules\wav_out\wav_out.c DEP_CPP_WAV_O=\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config_static.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\audio_out.h"\ "..\..\include\gpac\setup.h"\ "..\..\include\gpac\tools.h"\ -# End Source File -# Begin Source File - -SOURCE=..\..\modules\wav_out\wav_out.def +NODEP_CPP_WAV_O=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msevc4/xvid_dec.vcp b/build/msevc4/xvid_dec.vcp index 83e7430..f8944d6 100644 --- a/build/msevc4/xvid_dec.vcp +++ b/build/msevc4/xvid_dec.vcp @@ -439,7 +439,14 @@ InputName=xvid_ppc # End Group # Begin Source File -SOURCE=..\..\modules\xvid_dec\xvid_dec.def +SOURCE=..\..\modules\modules_export.cpp +DEP_CPP_MODUL=\ + "..\..\include\gpac\configuration.h"\ + "..\..\include\gpac\setup.h"\ + +NODEP_CPP_MODUL=\ + "..\..\include\gpac\config.h"\ + # End Source File # Begin Source File @@ -448,15 +455,21 @@ DEP_CPP_XVID_D=\ "..\..\include\gpac\avparse.h"\ "..\..\include\gpac\bitstream.h"\ "..\..\include\gpac\config_file.h"\ + "..\..\include\gpac\configuration.h"\ "..\..\include\gpac\constants.h"\ - "..\..\include\gpac\internal\config_static.h"\ + "..\..\include\gpac\list.h"\ "..\..\include\gpac\module.h"\ "..\..\include\gpac\modules\codec.h"\ + "..\..\include\gpac\mpeg4_odf.h"\ "..\..\include\gpac\setup.h"\ + "..\..\include\gpac\sync_layer.h"\ "..\..\include\gpac\tools.h"\ "..\..\modules\xvid_dec\xvid_wce\Rules.h"\ "..\..\modules\xvid_dec\xvid_wce\xvid.h"\ +NODEP_CPP_XVID_D=\ + "..\..\include\gpac\config.h"\ + # End Source File # End Target # End Project diff --git a/build/msvc6/GPAX.dsp b/build/msvc6/GPAX.dsp deleted file mode 100644 index 7b4231e..0000000 --- a/build/msvc6/GPAX.dsp +++ /dev/null @@ -1,172 +0,0 @@ -# Microsoft Developer Studio Project File - Name="GPAX" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=GPAX - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "GPAX.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "GPAX.mak" CFG="GPAX - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "GPAX - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "GPAX - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "GPAX - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/w32_deb" -# PROP Intermediate_Dir "obj/w32_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /FD /GZ /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE RSC /l 0x804 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 js32.lib zlib.lib winmm.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/w32_deb/GPAX.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" -# Begin Custom Build - Performing registration -OutDir=.\obj/w32_deb -TargetPath=\CVS\gpac\bin\w32_deb\GPAX.dll -InputPath=\CVS\gpac\bin\w32_deb\GPAX.dll -SOURCE="$(InputPath)" - -"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - regsvr32 /s /c "$(TargetPath)" - echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" - -# End Custom Build - -!ELSEIF "$(CFG)" == "GPAX - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "obj/w32_rel" -# PROP BASE Intermediate_Dir "obj/w32_rel" -# PROP BASE Ignore_Export_Lib 0 -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/w32_rel" -# PROP Intermediate_Dir "obj/w32_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MD /W3 /Gm /ZI /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /FD /GZ /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE RSC /l 0x804 /d "_DEBUG" -# ADD RSC /l 0x804 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 js32.lib zlib.lib winmm.lib ws2_32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept /libpath:"../gpac/extra_lib/lib/w32_deb" -# ADD LINK32 /nologo /subsystem:windows /dll /debug /machine:I386 /out:"../../bin/w32_rel/GPAX.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_rel" -# Begin Custom Build - Performing registration -OutDir=.\obj/w32_rel -TargetPath=\CVS\gpac\bin\w32_rel\GPAX.dll -InputPath=\CVS\gpac\bin\w32_rel\GPAX.dll -SOURCE="$(InputPath)" - -"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" - regsvr32 /s /c "$(TargetPath)" - echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg" - -# End Custom Build -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=copy ..\..\bin\w32_rel\GPAX.dll "C:\Program Files\GPAC" -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "GPAX - Win32 Debug" -# Name "GPAX - Win32 Release" -# Begin Source File - -SOURCE=..\..\applications\GPAX\gpax.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\GPAX.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\GPAX.def -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\GPAX.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\GPAX.idl -# ADD MTL /tlb ".\GPAX.tlb" -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\GPAX.rc -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\GPAX.rgs -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\GPAXPlugin.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\GPAXPlugin.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\resource.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\StdAfx.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\GPAX\StdAfx.h -# End Source File -# End Target -# End Project -# Section GPAX : {00000000-0000-0000-0000-800000800000} -# 1:21:IDS_DOCSTRINGGPAXProp:105 -# 1:12:IDD_GPAXPROP:107 -# 1:12:IDR_GPAXPROP:106 -# 1:20:IDS_HELPFILEGPAXProp:104 -# 1:17:IDS_TITLEGPAXProp:103 -# End Section diff --git a/build/msvc6/Osmo4.dsp b/build/msvc6/Osmo4.dsp deleted file mode 100644 index 9968288..0000000 --- a/build/msvc6/Osmo4.dsp +++ /dev/null @@ -1,217 +0,0 @@ -# Microsoft Developer Studio Project File - Name="Osmo4" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=Osmo4 - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "Osmo4.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "Osmo4.mak" CFG="Osmo4 - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Osmo4 - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "Osmo4 - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Osmo4 - Win32 Release" - -# PROP BASE Use_MFC 6 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 6 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/osmo4_w32_rel" -# PROP Intermediate_Dir "obj/osmo4_w32_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FD /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" /d "_AFXDLL" -# ADD RSC /l 0x40c /d "NDEBUG" /d "_AFXDLL" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386 -# ADD LINK32 /nologo /stack:0x800000 /subsystem:windows /machine:I386 /out:"../../bin/w32_rel/Osmo4.exe" - -!ELSEIF "$(CFG)" == "Osmo4 - Win32 Debug" - -# PROP BASE Use_MFC 6 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 6 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/osmo4_w32_deb" -# PROP Intermediate_Dir "obj/osmo4_w32_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" /d "_AFXDLL" -# ADD RSC /l 0x40c /d "_DEBUG" /d "_AFXDLL" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /subsystem:windows /debug /machine:I386 /out:"../../bin/w32_deb/Osmo4.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "Osmo4 - Win32 Release" -# Name "Osmo4 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\AddressBar.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\FileProps.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\MainFrm.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\OpenUrl.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Options.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Osmo4.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Osmo4.rc -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Playlist.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Sliders.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\StdAfx.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\AddressBar.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\FileProps.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\MainFrm.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\OpenUrl.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Options.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Osmo4.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Playlist.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Resource.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\Sliders.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\StdAfx.h -# End Source File -# End Group -# Begin Group "res" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\res\error.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\res\maintool.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\res\message.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\res\osmo4.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\res\pause.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\res\play.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\res\playlist.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_w32\res\stop.ico -# End Source File -# End Group -# End Target -# End Project diff --git a/build/msvc6/V4Studio.dsp b/build/msvc6/V4Studio.dsp deleted file mode 100644 index 51dcc02..0000000 --- a/build/msvc6/V4Studio.dsp +++ /dev/null @@ -1,505 +0,0 @@ -# Microsoft Developer Studio Project File - Name="V4Studio" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=V4Studio - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "V4Studio.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "V4Studio.mak" CFG="V4Studio - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "V4Studio - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "V4Studio - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "V4Studio - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/v4studio_rel" -# PROP Intermediate_Dir "obj/v4studio_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WXDEBUG__" /D WXDEBUG=1 /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /i "E:\MesProjets\wxWindows\include" /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 wxbase26.lib wxmsw26_core.lib wxmsw26_adv.lib ws2_32.lib shell32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib ole32.lib uuid.lib odbc32.lib odbccp32.lib comctl32.lib rpcrt4.lib winmm.lib /nologo /subsystem:windows /machine:I386 /out:"../../bin/w32_rel/V4Studio.exe" -# SUBTRACT LINK32 /map - -!ELSEIF "$(CFG)" == "V4Studio - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/v4studio_deb" -# PROP Intermediate_Dir "obj/v4studio_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../M4Systems/SceneGraph" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "__WINDOWS__" /D "__WXMSW__" /D "__WXDEBUG__" /D WXDEBUG=1 /D "__WIN95__" /D "__WIN32__" /D WINVER=0x0400 /D "STRICT" /FR /FD /GZ /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /fo"rc\V4Studio.res" /i "C:\Projets\wxWindows\include" /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 /machine:IX86 -# ADD LINK32 wxbase26d.lib wxmsw26d_core.lib wxmsw26d_adv.lib comctl32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib rpcrt4.lib /nologo /subsystem:windows /debug /machine:I386 /out:"../../bin/w32_deb/V4Studio.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "V4Studio - Win32 Release" -# Name "V4Studio - Win32 Debug" -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\appearance.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\blank.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\bullseye.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\cdrom.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\circle.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\close.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\colortransform.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\computer.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\copy.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\cross.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\cut.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\delete.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\drive.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\file1.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\floppy.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\folder1.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\folder2.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\fs.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\group.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\hand.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\ifs2d.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\ils2d.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\image.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\layer2d.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\lg.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\lineproperties.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\magnif1.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\material2d.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\movie.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\new.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\noentry.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\open.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\orderedgroup.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\paste.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\paste_use.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\pbrush.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\pencil.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\pntleft.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\pntright.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\preview.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\print.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\query.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\RCa01312 -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\rect.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\redo.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\removble.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\resource_orig.xrc -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\rg.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\rightarr.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\roller.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\save.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\shape.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\sound.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\t2d.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\text.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\tm2d.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\undo.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\v4.bmp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\v4.ico -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\V4Studio.rc - -!IF "$(CFG)" == "V4Studio - Win32 Release" - -!ELSEIF "$(CFG)" == "V4Studio - Win32 Debug" - -# ADD BASE RSC /l 0x40c /i "\CVS\gpac\applications\v4studio\rc" /i "\gpac2\applications\v4studio\rc" -# SUBTRACT BASE RSC /i "C:\Projets\wxWindows\include" -# ADD RSC /l 0x40c /i "\CVS\gpac\applications\v4studio\rc" /i "\gpac2\applications\v4studio\rc" -# SUBTRACT RSC /i "C:\Projets\wxWindows\include" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\wx\msw\watch1.cur -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\rc\xlineproperties.bmp -# End Source File -# End Group -# Begin Group "UI" - -# PROP Default_Filter "" -# Begin Group "TimeLine" - -# PROP Default_Filter "*.h" -# Begin Source File - -SOURCE=..\..\applications\v4studio\safe_include.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLine.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLine.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLineCase.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLineCase.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLineElt.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLineElt.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLineHdr.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLineHdr.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLineLine.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4TimeLine\V4TimeLineLine.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4CommandPanel.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4CommandPanel.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4FieldList.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4FieldList.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4StudioFrame.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4StudioFrame.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4StudioTree.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4StudioTree.h -# End Source File -# End Group -# Begin Group "SceneManagment" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4Node.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4Node.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4NodePool.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4NodePool.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4NodePools.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4NodePools.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4SceneManager.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4SceneManager.h -# End Source File -# End Group -# Begin Group "GPACTerminal" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4Service.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4Service.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\wxGPACPanel.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\wxGPACPanel.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4StudioApp.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\v4studio\V4StudioApp.h -# End Source File -# End Target -# End Project diff --git a/build/msvc6/aac_in.dsp b/build/msvc6/aac_in.dsp deleted file mode 100644 index 2b5dba6..0000000 --- a/build/msvc6/aac_in.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="aac_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=aac_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "aac_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "aac_in.mak" CFG="aac_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "aac_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "aac_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "aac_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/aac_in_rel" -# PROP Intermediate_Dir "obj/aac_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AAC_IN_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include/faad" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_FAAD" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 libfaad.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_aac_in.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "aac_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/aac_in_deb" -# PROP Intermediate_Dir "obj/aac_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AAC_IN_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include/faad" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_FAAD" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 libfaad.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_aac_in.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "aac_in - Win32 Release" -# Name "aac_in - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\aac_in\aac_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\aac_in\aac_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\aac_in\faad_dec.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/ac3_in.dsp b/build/msvc6/ac3_in.dsp deleted file mode 100644 index 3c62863..0000000 --- a/build/msvc6/ac3_in.dsp +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="ac3_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=ac3_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ac3_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ac3_in.mak" CFG="ac3_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ac3_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "ac3_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ac3_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AC3_IN_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_LIBA52" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 liba52.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_ac3_in.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "ac3_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AC3_IN_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_LIBA52" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 liba52.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_ac3_in.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "ac3_in - Win32 Release" -# Name "ac3_in - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\ac3_in\ac3_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ac3_in\ac3_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ac3_in\liba52_dec.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/amr_dec.dsp b/build/msvc6/amr_dec.dsp deleted file mode 100644 index 51809cb..0000000 --- a/build/msvc6/amr_dec.dsp +++ /dev/null @@ -1,982 +0,0 @@ -# Microsoft Developer Studio Project File - Name="amr_dec" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=amr_dec - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "amr_dec.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "amr_dec.mak" CFG="amr_dec - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "amr_dec - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "amr_dec - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "amr_dec - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/amr_dec_rel" -# PROP Intermediate_Dir "obj/amr_dec_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amr_dec_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMS_IO" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /stack:0x800000 /dll /machine:I386 /out:"../../bin/w32_rel/gm_amr_dec.dll" -# SUBTRACT LINK32 /verbose /profile /incremental:yes /debug /nodefaultlib - -!ELSEIF "$(CFG)" == "amr_dec - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/amr_dec_deb" -# PROP Intermediate_Dir "obj/amr_dec_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "amr_dec_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MMS_IO" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_amr_dec.dll" -# SUBTRACT LINK32 /verbose /profile /pdb:none /incremental:no - -!ENDIF - -# Begin Target - -# Name "amr_dec - Win32 Release" -# Name "amr_dec - Win32 Debug" -# Begin Group "amr_nb_dec" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\a_refl.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\a_refl.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\agc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\agc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\autocorr.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\autocorr.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\az_lsp.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\az_lsp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\b_cn_cod.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\b_cn_cod.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\basic_op.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\basicop2.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\bgnscd.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\bgnscd.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\bits2prm.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\bits2prm.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c1035pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c1035pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c2_11pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c2_11pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c2_9pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c2_9pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c3_14pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c3_14pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c4_17pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c4_17pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c8_31pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c8_31pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c_g_aver.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\c_g_aver.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\calc_cor.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\calc_cor.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\calc_en.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\calc_en.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cbsearch.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cbsearch.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cl_ltp.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cl_ltp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cnst.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cnst_vad.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cod_amr.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cod_amr.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\convolve.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\convolve.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\copy.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\copy.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cor_h.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\cor_h.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\count.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\count.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d1035pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d1035pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d2_11pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d2_11pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d2_9pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d2_9pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d3_14pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d3_14pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d4_17pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d4_17pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d8_31pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d8_31pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_gain_c.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_gain_c.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_gain_p.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_gain_p.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_homing.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_homing.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_plsf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_plsf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_plsf_3.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\d_plsf_5.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_amr.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_amr.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_gain.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_gain.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_lag3.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_lag3.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_lag6.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dec_lag6.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dtx_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dtx_dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dtx_enc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\dtx_enc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ec_gains.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\enc_lag6.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ex_ctrl.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ex_ctrl.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\frame.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_adapt.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_adapt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_code.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_code.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_pitch.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\g_pitch.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gain_q.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gain_q.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gc_pred.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gc_pred.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gmed_n.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\gmed_n.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\hp_max.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\hp_max.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\int_lpc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\int_lpc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\int_lsf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\int_lsf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\inter_36.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\inter_36.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\inv_sqrt.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\inv_sqrt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lag_wind.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lag_wind.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\levinson.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\levinson.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lflg_upd.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\log2.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\log2.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lpc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lpc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsfwt.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsfwt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_avg.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_avg.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_az.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_az.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_lsf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\lsp_lsf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\mac_32.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\mac_32.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\mode.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\n_proc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\n_proc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ol_ltp.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ol_ltp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\oper_32b.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\oper_32b.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\p_ol_wgh.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\p_ol_wgh.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ph_disp.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ph_disp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pitch_fr.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pitch_fr.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pitch_ol.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pitch_ol.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\post_pro.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\post_pro.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pow2.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pow2.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pre_big.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pre_big.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pre_proc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pre_proc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pred_lt.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pred_lt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\preemph.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\preemph.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\prm2bits.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\prm2bits.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pstfilt.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\pstfilt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_gain_c.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_gain_c.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_gain_p.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_gain_p.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_plsf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_plsf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_plsf_3.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\q_plsf_5.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qgain475.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qgain475.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qgain795.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qgain795.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qua_gain.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\qua_gain.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\r_fft.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\reorder.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\reorder.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\residu.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\residu.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\s10_8pf.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\s10_8pf.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\set_sign.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\set_sign.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\set_zero.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\set_zero.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sid_sync.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sid_sync.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sp_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sp_dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sp_enc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sp_enc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\spreproc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\spreproc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\spstproc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\spstproc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sqrt_l.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\sqrt_l.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\strfunc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\strfunc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\syn_filt.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\syn_filt.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ton_stab.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\ton_stab.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\typedef.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\typedefs.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad1.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad1.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad2.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vad2.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vadname.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\vadname.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\weight_a.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\weight_a.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_dec.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_nb\enc_lag3.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/amr_float_dec.dsp b/build/msvc6/amr_float_dec.dsp deleted file mode 100644 index 67a2164..0000000 --- a/build/msvc6/amr_float_dec.dsp +++ /dev/null @@ -1,304 +0,0 @@ -# Microsoft Developer Studio Project File - Name="amr_float_dec" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=amr_float_dec - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "amr_float_dec.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "amr_float_dec.mak" CFG="amr_float_dec - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "amr_float_dec - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "amr_float_dec - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "amr_float_dec - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/amr_float_dec_rel" -# PROP Intermediate_Dir "obj/amr_float_dec_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AMR_FLOAT_DEC_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_AMR_FT" /D "GPAC_HAS_AMR_FT_WB" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_amr_float_dec.dll" - -!ELSEIF "$(CFG)" == "amr_float_dec - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/amr_float_dec_deb" -# PROP Intermediate_Dir "obj/amr_float_dec_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "AMR_FLOAT_DEC_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_AMR_FT" /D "GPAC_HAS_AMR_FT_WB" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_amr_float_dec.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "amr_float_dec - Win32 Release" -# Name "amr_float_dec - Win32 Debug" -# Begin Group "amr_nb_ft" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\interf_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\interf_dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\interf_enc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\interf_enc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\interf_rom.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\rom_dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\rom_enc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\sp_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\sp_dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\sp_enc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\sp_enc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_nb_ft\typedef.h -# End Source File -# End Group -# Begin Group "amr_wb_ft" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_acelp.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_acelp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_dtx.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_dtx.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_gain.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_gain.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_if.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_if.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_lpc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_lpc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_main.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_main.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_rom.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_util.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\dec_util.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_acelp.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_acelp.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_dtx.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_dtx.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_gain.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_gain.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_if.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_if.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_lpc.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_lpc.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_main.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_main.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_rom.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_util.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\enc_util.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\if_rom.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\if_rom.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\typedef.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_wb_ft\typedefs.h -# End Source File -# End Group -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_float_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_float_dec\amr_float_dec.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\amr_dec\amr_in.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/bifs_dec.dsp b/build/msvc6/bifs_dec.dsp deleted file mode 100644 index eb0a7e7..0000000 --- a/build/msvc6/bifs_dec.dsp +++ /dev/null @@ -1,99 +0,0 @@ -# Microsoft Developer Studio Project File - Name="bifs_dec" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=bifs_dec - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "bifs_dec.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "bifs_dec.mak" CFG="bifs_dec - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "bifs_dec - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "bifs_dec - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "bifs_dec - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/bifs_dec_rel" -# PROP Intermediate_Dir "obj/bifs_dec_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BIFS_DEC_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_bifs_dec.dll" - -!ELSEIF "$(CFG)" == "bifs_dec - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/bifs_dec_deb" -# PROP Intermediate_Dir "obj/bifs_dec_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BIFS_DEC_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_bifs_dec.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "bifs_dec - Win32 Release" -# Name "bifs_dec - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\bifs_dec\bifs_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\bifs_dec\bifs_dec.def -# End Source File -# End Target -# End Project diff --git a/build/msvc6/ctx_load.dsp b/build/msvc6/ctx_load.dsp deleted file mode 100644 index ee240f4..0000000 --- a/build/msvc6/ctx_load.dsp +++ /dev/null @@ -1,99 +0,0 @@ -# Microsoft Developer Studio Project File - Name="ctx_load" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=ctx_load - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ctx_load.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ctx_load.mak" CFG="ctx_load - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ctx_load - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "ctx_load - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ctx_load - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/ctx_load_rel" -# PROP Intermediate_Dir "obj/ctx_load_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTX_LOAD_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_ctx_load.dll" - -!ELSEIF "$(CFG)" == "ctx_load - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/ctx_load_deb" -# PROP Intermediate_Dir "obj/ctx_load_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CTX_LOAD_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_ctx_load.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "ctx_load - Win32 Release" -# Name "ctx_load - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\ctx_load\ctx_load.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ctx_load\ctx_load.def -# End Source File -# End Target -# End Project diff --git a/build/msvc6/dummy_in.dsp b/build/msvc6/dummy_in.dsp deleted file mode 100644 index 28386a1..0000000 --- a/build/msvc6/dummy_in.dsp +++ /dev/null @@ -1,99 +0,0 @@ -# Microsoft Developer Studio Project File - Name="dummy_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=dummy_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "dummy_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "dummy_in.mak" CFG="dummy_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "dummy_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "dummy_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "dummy_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/dymmy_in_rel" -# PROP Intermediate_Dir "obj/dymmy_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "dummy_in_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_dummy_in.dll" - -!ELSEIF "$(CFG)" == "dummy_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/dymmy_in_deb" -# PROP Intermediate_Dir "obj/dymmy_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "dummy_in_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_dummy_in.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "dummy_in - Win32 Release" -# Name "dummy_in - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\dummy_in\dummy_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dummy_in\dummy_in.def -# End Source File -# End Target -# End Project diff --git a/build/msvc6/dx_hw.dsp b/build/msvc6/dx_hw.dsp deleted file mode 100644 index 4741dc6..0000000 --- a/build/msvc6/dx_hw.dsp +++ /dev/null @@ -1,143 +0,0 @@ -# Microsoft Developer Studio Project File - Name="dx_hw" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=dx_hw - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "dx_hw.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "dx_hw.mak" CFG="dx_hw - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "dx_hw - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "dx_hw - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "dx_hw - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/dx_hw_rel" -# PROP Intermediate_Dir "obj/dx_hw_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DX_HW_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAVE_CONFIG_H" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 opengl32.lib glu32.lib dsound.lib dxguid.lib ddraw.lib ole32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_dx_hw.dll" - -!ELSEIF "$(CFG)" == "dx_hw - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/dx_hw_deb" -# PROP Intermediate_Dir "obj/dx_hw_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DX_HW_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAVE_CONFIG_H" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 msimg32.lib opengl32.lib dsound.lib dxguid.lib ddraw.lib ole32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_dx_hw.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "dx_hw - Win32 Release" -# Name "dx_hw - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\dx_hw\collide.cur -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\res\collide.cur -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\copy_pixels.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\dx_2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\dx_audio.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\dx_hw.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\dx_hw.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\dx_hw.rc -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\dx_video.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\dx_window.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\hand.cur -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\res\hand.cur -# End Source File -# Begin Source File - -SOURCE=..\..\modules\dx_hw\resource.h -# End Source File -# End Target -# End Project diff --git a/build/msvc6/ffmpeg_in.dsp b/build/msvc6/ffmpeg_in.dsp deleted file mode 100644 index a05c3be..0000000 --- a/build/msvc6/ffmpeg_in.dsp +++ /dev/null @@ -1,113 +0,0 @@ -# Microsoft Developer Studio Project File - Name="ffmpeg_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=ffmpeg_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ffmpeg_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ffmpeg_in.mak" CFG="ffmpeg_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ffmpeg_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "ffmpeg_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ffmpeg_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/ffmpeg_in_rel" -# PROP Intermediate_Dir "obj/ffmpeg_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FFMPEG_IN_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include/" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 avcodec-51.lib avformat-51.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_ffmpeg_in.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "ffmpeg_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/ffmpeg_in_deb" -# PROP Intermediate_Dir "obj/ffmpeg_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FFMPEG_IN_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 avcodec-51.lib avformat-51.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_ffmpeg_in.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" -# SUBTRACT LINK32 /incremental:no /nodefaultlib - -!ENDIF - -# Begin Target - -# Name "ffmpeg_in - Win32 Release" -# Name "ffmpeg_in - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\ffmpeg_in\ffmpeg_decode.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ffmpeg_in\ffmpeg_demux.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ffmpeg_in\ffmpeg_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ffmpeg_in\ffmpeg_in.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ffmpeg_in\ffmpeg_load.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/ft_font.dsp b/build/msvc6/ft_font.dsp deleted file mode 100644 index 2df9bbe..0000000 --- a/build/msvc6/ft_font.dsp +++ /dev/null @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="ft_font" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=ft_font - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ft_font.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ft_font.mak" CFG="ft_font - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ft_font - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "ft_font - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ft_font - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/ft_font_rel" -# PROP Intermediate_Dir "obj/ft_font_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FT_FONT_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include/freetype" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 freetype.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_ft_font.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "ft_font - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/ft_font_deb" -# PROP Intermediate_Dir "obj/ft_font_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FT_FONT_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include/freetype" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 freetype.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_ft_font.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "ft_font - Win32 Release" -# Name "ft_font - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\ft_font\ft_font.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ft_font\ft_font.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ft_font\ft_font.h -# End Source File -# End Target -# End Project diff --git a/build/msvc6/gdip_raster.dsp b/build/msvc6/gdip_raster.dsp deleted file mode 100644 index 54d3da2..0000000 --- a/build/msvc6/gdip_raster.dsp +++ /dev/null @@ -1,115 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gdip_raster" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=gdip_raster - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "gdip_raster.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "gdip_raster.mak" CFG="gdip_raster - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "gdip_raster - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "gdip_raster - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gdip_raster - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/gdip_rel" -# PROP Intermediate_Dir "obj/gdip_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDIP_REND_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 gdiplus.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_gdip_raster.dll" - -!ELSEIF "$(CFG)" == "gdip_raster - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/gdip_deb" -# PROP Intermediate_Dir "obj/gdip_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GDIP_REND_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 gdiplus.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_gdip_raster.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "gdip_raster - Win32 Release" -# Name "gdip_raster - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\gdip_raster\gdip_font.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\modules\gdip_raster\gdip_grad.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\modules\gdip_raster\gdip_priv.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\gdip_raster\gdip_rend.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\modules\gdip_raster\gdip_rend.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\gdip_raster\gdip_texture.cpp -# End Source File -# End Target -# End Project diff --git a/build/msvc6/gpac.dsw b/build/msvc6/gpac.dsw deleted file mode 100644 index 88c4dc9..0000000 --- a/build/msvc6/gpac.dsw +++ /dev/null @@ -1,695 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "GPAX"=.\GPAX.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "Osmo4"=.\Osmo4.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency - Begin Project Dependency - Project_Dep_Name aac_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name bifs_dec - End Project Dependency - Begin Project Dependency - Project_Dep_Name ctx_load - End Project Dependency - Begin Project Dependency - Project_Dep_Name dummy_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name dx_hw - End Project Dependency - Begin Project Dependency - Project_Dep_Name ft_font - End Project Dependency - Begin Project Dependency - Project_Dep_Name gdip_raster - End Project Dependency - Begin Project Dependency - Project_Dep_Name img_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name isom_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name mp3_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name odf_dec - End Project Dependency - Begin Project Dependency - Project_Dep_Name rtp_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name soft_raster - End Project Dependency - Begin Project Dependency - Project_Dep_Name wav_out - End Project Dependency - Begin Project Dependency - Project_Dep_Name xvid_dec - End Project Dependency - Begin Project Dependency - Project_Dep_Name svg_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name mpegts_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name saf_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name timedtext - End Project Dependency - Begin Project Dependency - Project_Dep_Name ffmpeg_in - End Project Dependency - Begin Project Dependency - Project_Dep_Name ismacryp - End Project Dependency - Begin Project Dependency - Project_Dep_Name laser_dec - End Project Dependency -}}} - -############################################################################### - -Project: "aac_in"=.\aac_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ac3_in"=.\ac3_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "amr_dec"=.\amr_dec.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "amr_float_dec"=.\amr_float_dec.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "bifs_dec"=.\bifs_dec.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "broadcaster"=..\..\applications\testapps\broadcaster\broadcaster.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ctx_load"=.\ctx_load.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "dummy_in"=.\dummy_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "dx_hw"=.\dx_hw.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ffmpeg_in"=.\ffmpeg_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ft_font"=.\ft_font.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "gdip_raster"=.\gdip_raster.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "gpac_js"=.\gpac_js.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "img_in"=.\img_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ismacryp"=.\ismacryp.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "isom_in"=.\isom_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "laser_dec"=.\laser_dec.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "libgpac"=.\libgpac.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "libgpac_dll"=.\libgpac_dll.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac - End Project Dependency -}}} - -############################################################################### - -Project: "mp3_in"=.\mp3_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "mp42ts"=..\..\applications\testapps\mp42ts\mp42ts.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "mp4_streamer"=..\..\applications\testapps\mp4_streamer\mp4_streamer.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "mp4box"=.\mp4box.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac - End Project Dependency -}}} - -############################################################################### - -Project: "mp4client"=.\mp4client.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "mpegts_in"=.\mpegts_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "odf_dec"=.\odf_dec.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "ogg"=.\ogg.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "osmozilla"=.\osmozilla.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "raw_out"=.\raw_out.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "rtp_in"=.\rtp_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "saf_in"=.\saf_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "sdl_out"=.\sdl_out.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "soft_raster"=.\soft_raster.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "svg2bifs"=..\..\applications\testapps\svg2bifs\svg2bifs.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac - End Project Dependency -}}} - -############################################################################### - -Project: "svg_in"=.\svg_in.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "timedtext"=.\timedtext.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "wav_out"=.\wav_out.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "wxOsmo4"=.\wxOsmo4.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Project: "xvid_dec"=.\xvid_dec.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name libgpac_dll - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff --git a/build/msvc6/gpac_js.dsp b/build/msvc6/gpac_js.dsp deleted file mode 100644 index 47778d0..0000000 --- a/build/msvc6/gpac_js.dsp +++ /dev/null @@ -1,113 +0,0 @@ -# Microsoft Developer Studio Project File - Name="gpac_js" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=gpac_js - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "gpac_js.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "gpac_js.mak" CFG="gpac_js - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "gpac_js - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "gpac_js - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "gpac_js - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "gpac_js___Win32_Release" -# PROP BASE Intermediate_Dir "gpac_js___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/gpac_js_rel" -# PROP Intermediate_Dir "obj/gpac_js_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_JS_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include/js" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_SPIDERMONKEY" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_gpac_js.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "gpac_js - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "gpac_js___Win32_Debug" -# PROP BASE Intermediate_Dir "gpac_js___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/gpac_js_deb" -# PROP Intermediate_Dir "obj/gpac_js_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_JS_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include/js" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_SPIDERMONKEY" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_gpac_js.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "gpac_js - Win32 Release" -# Name "gpac_js - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\modules\gpac_js\gpac_js.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\gpac_js\gpac_js.def -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/msvc6/img_in.dsp b/build/msvc6/img_in.dsp deleted file mode 100644 index 2a4799e..0000000 --- a/build/msvc6/img_in.dsp +++ /dev/null @@ -1,125 +0,0 @@ -# Microsoft Developer Studio Project File - Name="img_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=img_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "img_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "img_in.mak" CFG="img_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "img_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "img_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "img_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/img_in_rel" -# PROP Intermediate_Dir "obj/img_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IMG_IN_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include/openjpeg" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_JP2" /D "OPJ_STATIC" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 LibOpenJPEG.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_img_in.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "img_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/img_in_deb" -# PROP Intermediate_Dir "obj/img_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "IMG_IN_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include/openjpeg" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_JP2" /D "OPJ_STATIC" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 LibOpenJPEGd.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_img_in.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "img_in - Win32 Release" -# Name "img_in - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\img_in\bmp_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\img_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\img_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\img_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\img_in.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\jp2_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\jpeg_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\img_in\png_dec.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/ismacryp.dsp b/build/msvc6/ismacryp.dsp deleted file mode 100644 index fbc91d4..0000000 --- a/build/msvc6/ismacryp.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# Microsoft Developer Studio Project File - Name="ismacryp" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=ismacryp - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ismacryp.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ismacryp.mak" CFG="ismacryp - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ismacryp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "ismacryp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ismacryp - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "ismacryp___Win32_Release" -# PROP BASE Intermediate_Dir "ismacryp___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/ismacryp_rel" -# PROP Intermediate_Dir "obj/ismacryp_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISMACRYP_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_ismacryp.dll" - -!ELSEIF "$(CFG)" == "ismacryp - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "ismacryp___Win32_Debug" -# PROP BASE Intermediate_Dir "ismacryp___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/ismacryp_deb" -# PROP Intermediate_Dir "obj/ismacryp_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ISMACRYP_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_ismacryp.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "ismacryp - Win32 Release" -# Name "ismacryp - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\ismacryp\ismacryp.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ismacryp\ismacryp.def -# End Source File -# End Target -# End Project diff --git a/build/msvc6/isom_in.dsp b/build/msvc6/isom_in.dsp deleted file mode 100644 index d367b82..0000000 --- a/build/msvc6/isom_in.dsp +++ /dev/null @@ -1,116 +0,0 @@ -# Microsoft Developer Studio Project File - Name="isom_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=isom_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "isom_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "isom_in.mak" CFG="isom_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "isom_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "isom_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "isom_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/isom_in_rel" -# PROP Intermediate_Dir "obj/isom_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MP4_IO_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# SUBTRACT CPP /Fr -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_isom_in.dll" - -!ELSEIF "$(CFG)" == "isom_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/isom_in_deb" -# PROP Intermediate_Dir "obj/isom_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MP4_IO_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_LIBA52" /FR /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_isom_in.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "isom_in - Win32 Release" -# Name "isom_in - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\isom_in\cache.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\isom_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\isom_in.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\load.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\read.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\isom_in\read_ch.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/laser_dec.dsp b/build/msvc6/laser_dec.dsp deleted file mode 100644 index 23c1505..0000000 --- a/build/msvc6/laser_dec.dsp +++ /dev/null @@ -1,99 +0,0 @@ -# Microsoft Developer Studio Project File - Name="laser_dec" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=laser_dec - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "laser_dec.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "laser_dec.mak" CFG="laser_dec - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "laser_dec - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "laser_dec - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "laser_dec - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/laser_dec_rel" -# PROP Intermediate_Dir "obj/laser_dec_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LASER_DEC_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_laser_dec.dll" - -!ELSEIF "$(CFG)" == "laser_dec - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/laser_dec_deb" -# PROP Intermediate_Dir "obj/laser_dec_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LASER_DEC_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_laser_dec.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "laser_dec - Win32 Release" -# Name "laser_dec - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\laser_dec\laser_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\laser_dec\laser_dec.def -# End Source File -# End Target -# End Project diff --git a/build/msvc6/libgpac.dsp b/build/msvc6/libgpac.dsp deleted file mode 100644 index 7b98bc1..0000000 --- a/build/msvc6/libgpac.dsp +++ /dev/null @@ -1,1404 +0,0 @@ -# Microsoft Developer Studio Project File - Name="libgpac" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=libgpac - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "libgpac.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "libgpac.mak" CFG="libgpac - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libgpac - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "libgpac - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "libgpac - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/libgpac_rel" -# PROP Intermediate_Dir "obj/libgpac_rel" -# PROP Target_Dir "" -MTL=midl.exe -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O1 /I "../../include" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/js" /I "../../extra_lib/include/jpeg" /I "../../extra_lib/include/png" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "GPAC_HAVE_CONFIG_H" /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"../../bin/w32_rel/libgpac_static.lib" - -!ELSEIF "$(CFG)" == "libgpac - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/libgpac_deb" -# PROP Intermediate_Dir "obj/libgpac_deb" -# PROP Target_Dir "" -MTL=midl.exe -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /GX /ZI /Od /I "../../include" /I "../../extra_lib/include/zlib" /I "../../extra_lib/include/js" /I "../../extra_lib/include/jpeg" /I "../../extra_lib/include/png" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "GPAC_HAVE_CONFIG_H" /FD /GZ /c -# SUBTRACT CPP /Fr /YX -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"../../bin/w32_deb/libgpac_static.lib" - -!ENDIF - -# Begin Target - -# Name "libgpac - Win32 Release" -# Name "libgpac - Win32 Debug" -# Begin Group "utils" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\utils\base_encoding.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\bitstream.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\color.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\configfile.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\downloader.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\error.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\list.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\math.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\module.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\module_wrap.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\os_divers.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\os_module.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\os_net.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\os_thread.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\path2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\path2d_stroker.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\token.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\uni_bidi.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\url.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\utf.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\utils\xml_parser.c -# End Source File -# End Group -# Begin Group "odf" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\odf\desc_private.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\descriptors.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\ipmpx_code.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\ipmpx_dump.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\ipmpx_parse.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\oci_codec.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_code.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_codec.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_command.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\odf_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_dump.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\odf_parse.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\qos.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\odf\slc.c -# End Source File -# End Group -# Begin Group "bifs" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\bifs\arith_decoder.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\bifs_codec.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\bifs_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\bifs_node_tables.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\bifs_tables.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\com_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\com_enc.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\conditional.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\field_decode.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\field_encode.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\memory_decoder.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\predictive_mffield.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\quant.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\quantize.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\script.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\script_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\script_enc.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\bifs\unquantize.c -# End Source File -# End Group -# Begin Group "isomedia" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\isomedia\avc_ext.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_3gpp.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_apple.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_base.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_isma.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_code_meta.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_dump.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\box_funcs.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\data_map.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\hint_track.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\hinting.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isma_sample.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isom_intern.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isom_read.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isom_store.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\isom_write.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\isomedia_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\media.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\media_odf.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\meta.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\movie_fragments.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\sample_descs.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\stbl_read.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\stbl_write.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\track.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\isomedia\tx3g.c -# End Source File -# End Group -# Begin Group "ietf" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\include\gpac\internal\ietf_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtcp.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp_depacketizer.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp_packetizer.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp_pck_3gpp.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp_pck_mpeg12.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtp_pck_mpeg4.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtsp_command.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtsp_common.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtsp_response.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\rtsp_session.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\ietf\sdp.c -# End Source File -# End Group -# Begin Group "scenegraph" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\scenegraph\base_scenegraph.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\commands.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\dom_events.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\dom_smjs.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\mpeg4_animators.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\mpeg4_nodes.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\mpeg4_valuator.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\scenegraph_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\smil_anim.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\smil_timing.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_attributes.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_properties.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_smjs.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\svg_types.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_interpolators.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_proto.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_route.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_script.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_smjs.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\vrml_tools.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\x3d_nodes.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\xbl_process.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scenegraph\xml_ns.c -# End Source File -# End Group -# Begin Group "media_tools" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\media_tools\av_parsers.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\avilib.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\avilib.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\gpac_ogg.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\img.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\ismacryp.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\isom_hinter.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\isom_tools.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\media_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\media_export.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\media_import.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\mpeg2_ps.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\mpeg2_ps.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\mpegts.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\ogg.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\saf.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\text_import.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\media_tools\vobsub.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\vobsub.h -# End Source File -# End Group -# Begin Group "scene_manager" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\scene_manager\encode_cbk.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\encode_isom.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_bt.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_isom.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_qt.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_svg.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\loader_xmt.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\scene_dump.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\scene_manager.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\scene_stats.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\swf_bifs.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\swf_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\swf_parse.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\scene_manager\text_to_bifs.c -# End Source File -# End Group -# Begin Group "mcrypt" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\mcrypt\cbc.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\cfb.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\crypt_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\ctr.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\des.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\ecb.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\g_crypt.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\ncfb.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\nofb.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\ofb.c -# End Source File -# Begin Source File - -SOURCE="..\..\src\mcrypt\rijndael-128.c" -# End Source File -# Begin Source File - -SOURCE="..\..\src\mcrypt\rijndael-192.c" -# End Source File -# Begin Source File - -SOURCE="..\..\src\mcrypt\rijndael-256.c" -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\sha1.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\stream.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\mcrypt\tripledes.c -# End Source File -# End Group -# Begin Group "terminal" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\terminal\channel.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\clock.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\decoder.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\inline.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\input_sensor.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\input_sensor.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_control.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_control.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_manager.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_memory.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_memory.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_object.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\media_sensor.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\network_service.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\object_browser.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\object_manager.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\svg_external.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\term_node_init.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\terminal\terminal.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\terminal_dev.h -# End Source File -# End Group -# Begin Group "compositor" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\src\compositor\audio_input.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\audio_mixer.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\audio_render.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\bindable.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\camera.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\camera.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\compositor.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\compositor_2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\compositor_3d.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\compositor_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\compositor_node_init.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\drawable.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\drawable.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\events.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\font_engine.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\gl_inc.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\hardcoded_protos.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mesh.c -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\mesh.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mesh_collide.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mesh_tesselate.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_animstream.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_audio.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_background.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_background2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_bitmap.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_composite.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_form.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_geometry_2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_geometry_3d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_geometry_ifs2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_geometry_ils2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_gradients.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_grouping.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_grouping.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_grouping_2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_grouping_3d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_layer_2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_layer_3d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_layout.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_lighting.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_path_layout.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_sensors.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_sound.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_text.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_textures.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_timesensor.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\mpeg4_viewport.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\navigate.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\nodes_stacks.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\offscreen_cache.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\offscreen_cache.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\svg_base.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\svg_font.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\svg_geometry.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\svg_grouping.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\svg_media.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\svg_paint_servers.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\svg_text.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\texturing.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\texturing.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\texturing_gl.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\visual_manager.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\visual_manager.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\visual_manager_2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\visual_manager_2d.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\visual_manager_2d_draw.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\visual_manager_3d.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\visual_manager_3d.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\visual_manager_3d_gl.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\compositor\x3d_geometry.c -# End Source File -# End Group -# Begin Group "laser" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\include\gpac\internal\laser_dev.h -# End Source File -# Begin Source File - -SOURCE=..\..\src\laser\lsr_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\laser\lsr_enc.c -# End Source File -# Begin Source File - -SOURCE=..\..\src\laser\lsr_tables.c -# End Source File -# End Group -# Begin Group "include" - -# PROP Default_Filter "" -# Begin Source File - -SOURCE=..\..\include\gpac\modules\audio_out.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\avparse.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\base_coding.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\bifs.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\bifsengine.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\bitstream.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\codec.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\color.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\compositor.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\config_file.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\internal\config_static.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\constants.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\crypt.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\download.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\esi.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\events.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\font.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\ietf.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\ipmp.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\ismacryp.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\isomedia.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\js_usr.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\laser.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\list.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\math.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\media_tools.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\mediaobject.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\module.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\mpeg4_odf.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\mpegts.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\network.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\nodes_mpeg4.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\nodes_svg.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\nodes_x3d.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\nodes_xbl.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\options.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\path2d.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\raster2d.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\scene_manager.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\scenegraph.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\scenegraph_svg.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\scenegraph_vrml.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\service.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\setup.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\svg_types.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\sync_layer.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\term_ext.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\term_info.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\terminal.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\thread.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\token.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\tools.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\user.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\utf.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\modules\video_out.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\xml.h -# End Source File -# Begin Source File - -SOURCE=..\..\include\gpac\yuv.h -# End Source File -# End Group -# End Target -# End Project diff --git a/build/msvc6/libgpac_dll.dsp b/build/msvc6/libgpac_dll.dsp deleted file mode 100644 index c5d9b52..0000000 --- a/build/msvc6/libgpac_dll.dsp +++ /dev/null @@ -1,97 +0,0 @@ -# Microsoft Developer Studio Project File - Name="libgpac_dll" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=libgpac_dll - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "libgpac_dll.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "libgpac_dll.mak" CFG="libgpac_dll - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "libgpac_dll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "libgpac_dll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "libgpac_dll - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "libgpac_dll___Win32_Release" -# PROP BASE Intermediate_Dir "libgpac_dll___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/libgpac_dll_rel" -# PROP Intermediate_Dir "obj/libgpac_dll_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGPAC_DLL_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/libgpac.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "libgpac_dll - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "libgpac_dll___Win32_Debug" -# PROP BASE Intermediate_Dir "libgpac_dll___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/libgpac_dll_deb" -# PROP Intermediate_Dir "obj/libgpac_dll_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBGPAC_DLL_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/libgpac.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "libgpac_dll - Win32 Release" -# Name "libgpac_dll - Win32 Debug" -# Begin Source File - -SOURCE=..\..\src\libgpac.def -# End Source File -# End Target -# End Project diff --git a/build/msvc6/mp3_in.dsp b/build/msvc6/mp3_in.dsp deleted file mode 100644 index 4c5bd36..0000000 --- a/build/msvc6/mp3_in.dsp +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mp3_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=mp3_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mp3_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mp3_in.mak" CFG="mp3_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mp3_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mp3_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mp3_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/mp3_in_rel" -# PROP Intermediate_Dir "obj/mp3_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MP3_IN_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include/mad" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_MAD" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 libmad.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_mp3_in.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "mp3_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/mp3_in_deb" -# PROP Intermediate_Dir "obj/mp3_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MP3_IN_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include/mad" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_MAD" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 libmad.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_mp3_in.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "mp3_in - Win32 Release" -# Name "mp3_in - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\mp3_in\mad_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\mp3_in\mp3_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\mp3_in\mp3_in.def -# End Source File -# End Target -# End Project diff --git a/build/msvc6/mp42avi.dsp b/build/msvc6/mp42avi.dsp deleted file mode 100644 index ee41683..0000000 --- a/build/msvc6/mp42avi.dsp +++ /dev/null @@ -1,91 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mp42avi" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=mp42avi - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mp42avi.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mp42avi.mak" CFG="mp42avi - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mp42avi - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "mp42avi - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mp42avi - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/mp42avi_rel" -# PROP Intermediate_Dir "obj/mp42avi_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"../../bin/w32_rel/MP42Avi.exe" -# SUBTRACT LINK32 /profile /pdb:none /incremental:yes /map /debug /nodefaultlib /force - -!ELSEIF "$(CFG)" == "mp42avi - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/mp42avi_deb" -# PROP Intermediate_Dir "obj/mp42avi_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /subsystem:console /profile /map /debug /machine:I386 /out:"../../bin/w32_deb/MP42Avi.exe" - -!ENDIF - -# Begin Target - -# Name "mp42avi - Win32 Release" -# Name "mp42avi - Win32 Debug" -# Begin Source File - -SOURCE=..\..\applications\mp42avi\main.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/mp4box.dsp b/build/msvc6/mp4box.dsp deleted file mode 100644 index b7a0ae7..0000000 --- a/build/msvc6/mp4box.dsp +++ /dev/null @@ -1,104 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mp4box" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=mp4box - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mp4box.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mp4box.mak" CFG="mp4box - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mp4box - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "mp4box - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mp4box - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/mp4box_rel" -# PROP Intermediate_Dir "obj/mp4box_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O1 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 /nologo /subsystem:console /machine:I386 /out:"../../bin/w32_rel/MP4Box.exe" /libpath:"../../extra_lib/lib/w32_rel" -# SUBTRACT LINK32 /map -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=copy ..\..\bin\w32_rel\MP4Box.exe "C:\Program Files\GPAC" -# End Special Build Tool - -!ELSEIF "$(CFG)" == "mp4box - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/mp4box_deb" -# PROP Intermediate_Dir "obj/mp4box_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/w32_deb/MP4Box.exe" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "mp4box - Win32 Release" -# Name "mp4box - Win32 Debug" -# Begin Source File - -SOURCE=..\..\applications\mp4box\filedump.c -# End Source File -# Begin Source File - -SOURCE=..\..\applications\mp4box\fileimport.c -# End Source File -# Begin Source File - -SOURCE=..\..\applications\mp4box\main.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/mp4client.dsp b/build/msvc6/mp4client.dsp deleted file mode 100644 index 27fcd75..0000000 --- a/build/msvc6/mp4client.dsp +++ /dev/null @@ -1,96 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mp4client" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG=mp4client - Win32 Release -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mp4client.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mp4client.mak" CFG="mp4client - Win32 Release" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mp4client - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "mp4client - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mp4client - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/mp4client_rel" -# PROP Intermediate_Dir "obj/mp4client_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 User32.lib /nologo /subsystem:console /machine:I386 /out:"../../bin/w32_rel/MP4Client.exe" - -!ELSEIF "$(CFG)" == "mp4client - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/mp4client_deb" -# PROP Intermediate_Dir "obj/mp4client_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Ot /I "../../include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 User32.lib /nologo /subsystem:console /debug /machine:I386 /out:"../../bin/w32_deb/MP4Client.exe" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "mp4client - Win32 Release" -# Name "mp4client - Win32 Debug" -# Begin Source File - -SOURCE=..\..\applications\mp4client\extract.c -# End Source File -# Begin Source File - -SOURCE=..\..\applications\mp4client\main.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/mpegts_in.dsp b/build/msvc6/mpegts_in.dsp deleted file mode 100644 index 25ff656..0000000 --- a/build/msvc6/mpegts_in.dsp +++ /dev/null @@ -1,112 +0,0 @@ -# Microsoft Developer Studio Project File - Name="mpegts_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=mpegts_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mpegts_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mpegts_in.mak" CFG="mpegts_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mpegts_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "mpegts_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mpegts_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "mpegts_in___Win32_Release" -# PROP BASE Intermediate_Dir "mpegts_in___Win32_Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/mpegts_in_rel" -# PROP Intermediate_Dir "obj/mpegts_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MPEGTS_IN_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_mpegts_in.dll" - -!ELSEIF "$(CFG)" == "mpegts_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "mpegts_in___Win32_Debug" -# PROP BASE Intermediate_Dir "mpegts_in___Win32_Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/mpegts_in_deb" -# PROP Intermediate_Dir "obj/mpegts_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MPEGTS_IN_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_mpegts_in.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "mpegts_in - Win32 Release" -# Name "mpegts_in - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\modules\mpegts_in\mpegts_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\mpegts_in\mpegts_in.def -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/msvc6/odf_dec.dsp b/build/msvc6/odf_dec.dsp deleted file mode 100644 index 1cdeaf5..0000000 --- a/build/msvc6/odf_dec.dsp +++ /dev/null @@ -1,99 +0,0 @@ -# Microsoft Developer Studio Project File - Name="odf_dec" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=odf_dec - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "odf_dec.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "odf_dec.mak" CFG="odf_dec - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "odf_dec - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "odf_dec - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "odf_dec - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/odf_dec_rel" -# PROP Intermediate_Dir "obj/odf_dec_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OD_DEC_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_odf_dec.dll" - -!ELSEIF "$(CFG)" == "odf_dec - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/odf_dec_deb" -# PROP Intermediate_Dir "obj/odf_dec_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OD_DEC_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_odf_dec.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "odf_dec - Win32 Release" -# Name "odf_dec - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\odf_dec\odf_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\odf_dec\odf_dec.def -# End Source File -# End Target -# End Project diff --git a/build/msvc6/ogg.dsp b/build/msvc6/ogg.dsp deleted file mode 100644 index 4a418f8..0000000 --- a/build/msvc6/ogg.dsp +++ /dev/null @@ -1,115 +0,0 @@ -# Microsoft Developer Studio Project File - Name="ogg" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=ogg - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "ogg.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ogg.mak" CFG="ogg - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "ogg - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "ogg - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "ogg - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/ogg_rel" -# PROP Intermediate_Dir "obj/ogg_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OGG_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_VORBIS" /D "GPAC_HAS_THEORA" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 ogg_static.lib vorbis_static.lib theora_static.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_ogg_xiph.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "ogg - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/ogg_deb" -# PROP Intermediate_Dir "obj/ogg_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OGG_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "GPAC_HAS_VORBIS" /D "GPAC_HAS_THEORA" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 vorbis_static.lib theora_static.lib ogg_static.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_ogg_xiph.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "ogg - Win32 Release" -# Name "ogg - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\ogg\ogg.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\ogg_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\ogg_in.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\ogg_load.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\theora_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ogg\vorbis_dec.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/osmozilla.dsp b/build/msvc6/osmozilla.dsp deleted file mode 100644 index f1df122..0000000 --- a/build/msvc6/osmozilla.dsp +++ /dev/null @@ -1,150 +0,0 @@ -# Microsoft Developer Studio Project File - Name="osmozilla" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=osmozilla - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "osmozilla.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "osmozilla.mak" CFG="osmozilla - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "osmozilla - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "osmozilla - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "osmozilla - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/osmozilla_rel" -# PROP Intermediate_Dir "obj/osmozilla_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OSMOZILLA_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\include" /I "..\..\extra_lib\include\gecko-sdk\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NPBASIC_EXPORTS" /D "MOZILLA_STRICT_API" /D "XP_WIN" /D "_X86_" /D "XPCOM_GLUE" /D WINVER=0x0400 /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 advapi32.lib user32.lib gdi32.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/nposmozilla.dll" -# SUBTRACT LINK32 /map -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=copy ..\..\applications\osmozilla\nsIOsmozilla.xpt_w32 ..\..\bin\w32_rel\nposmozilla.xpt copy ..\..\bin\w32_rel\nposmozilla.dll "C:\Program Files\GPAC\mozilla" copy ..\..\bin\w32_rel\nposmozilla.xpt "C:\Program Files\GPAC\mozilla" -# End Special Build Tool - -!ELSEIF "$(CFG)" == "osmozilla - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/osmozilla_deb" -# PROP Intermediate_Dir "obj/osmozilla_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OSMOZILLA_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "..\..\include" /I "..\..\extra_lib\include\gecko-sdk\include" /D "WIN32" /D "XP_WIN32" /D "XP_WIN" /D "_X86_" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "NPBASIC_EXPORTS" /D "MOZILLA_STRICT_API" /D "XPCOM_GLUE" /FR /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 advapi32.lib user32.lib gdi32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/nposmozilla.dll" /pdbtype:sept -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=copy ..\..\bin\w32_deb\nposmozilla.dll "C:\Program Files\GPAC\mozilla" -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "osmozilla - Win32 Release" -# Name "osmozilla - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\applications\osmozilla\np_entry.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmozilla\npn_gate.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmozilla\npp_gate.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmozilla\osmozilla.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmozilla\osmozilla.def -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmozilla\osmozilla.rc -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\applications\osmozilla\npplat.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmozilla\nsIOsmozilla.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmozilla\osmozilla.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/msvc6/raw_out.dsp b/build/msvc6/raw_out.dsp deleted file mode 100644 index d3b1d42..0000000 --- a/build/msvc6/raw_out.dsp +++ /dev/null @@ -1,99 +0,0 @@ -# Microsoft Developer Studio Project File - Name="raw_out" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=raw_out - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "raw_out.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "raw_out.mak" CFG="raw_out - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "raw_out - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "raw_out - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "raw_out - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/raw_out_rel" -# PROP Intermediate_Dir "obj/raw_out_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAW_OUT_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_raw_out.dll" - -!ELSEIF "$(CFG)" == "raw_out - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/raw_out_deb" -# PROP Intermediate_Dir "obj/raw_out_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RAW_OUT_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_raw_out.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "raw_out - Win32 Release" -# Name "raw_out - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\raw_out\raw_out.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\raw_out\raw_video.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/rtp_in.dsp b/build/msvc6/rtp_in.dsp deleted file mode 100644 index bb8c50f..0000000 --- a/build/msvc6/rtp_in.dsp +++ /dev/null @@ -1,123 +0,0 @@ -# Microsoft Developer Studio Project File - Name="rtp_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=rtp_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "rtp_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "rtp_in.mak" CFG="rtp_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "rtp_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "rtp_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "rtp_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/rtp_in_rel" -# PROP Intermediate_Dir "obj/rtp_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RTP_IN_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_rtp_in.dll" - -!ELSEIF "$(CFG)" == "rtp_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/rtp_in_deb" -# PROP Intermediate_Dir "obj/rtp_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "RTP_IN_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_rtp_in.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "rtp_in - Win32 Release" -# Name "rtp_in - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_in.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_in.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_session.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_signaling.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\rtp_stream.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\sdp_fetch.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\rtp_in\sdp_load.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/saf_in.dsp b/build/msvc6/saf_in.dsp deleted file mode 100644 index e612a6c..0000000 --- a/build/msvc6/saf_in.dsp +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="saf_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=saf_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "saf_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "saf_in.mak" CFG="saf_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "saf_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "saf_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "saf_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/saf_in_rel" -# PROP Intermediate_Dir "obj/saf_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAF_IN_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_saf_in.dll" - -!ELSEIF "$(CFG)" == "saf_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/saf_in_deb" -# PROP Intermediate_Dir "obj/saf_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SAF_IN_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_saf_in.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "saf_in - Win32 Release" -# Name "saf_in - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\modules\saf_in\saf_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\saf_in\saf_in.def -# End Source File -# End Group -# End Target -# End Project diff --git a/build/msvc6/sdl_out.dsp b/build/msvc6/sdl_out.dsp deleted file mode 100644 index 8ef584a..0000000 --- a/build/msvc6/sdl_out.dsp +++ /dev/null @@ -1,116 +0,0 @@ -# Microsoft Developer Studio Project File - Name="sdl_out" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=sdl_out - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "sdl_out.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "sdl_out.mak" CFG="sdl_out - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "sdl_out - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "sdl_out - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "sdl_out - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/sdl_out_rel" -# PROP Intermediate_Dir "obj/sdl_out_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SDL_OUT_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 SDL.lib user32.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_sdl_out.dll" - -!ELSEIF "$(CFG)" == "sdl_out - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/sdl_out_deb" -# PROP Intermediate_Dir "obj/sdl_out_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SDL_OUT_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 SDL.lib user32.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_sdl_out.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "sdl_out - Win32 Release" -# Name "sdl_out - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\sdl_out\audio.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\sdl_out\cursors.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\sdl_out\sdl_out.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\sdl_out\sdl_out.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\sdl_out\sdl_out.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\sdl_out\video.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/soft_raster.dsp b/build/msvc6/soft_raster.dsp deleted file mode 100644 index 5872056..0000000 --- a/build/msvc6/soft_raster.dsp +++ /dev/null @@ -1,136 +0,0 @@ -# Microsoft Developer Studio Project File - Name="soft_raster" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=soft_raster - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "soft_raster.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "soft_raster.mak" CFG="soft_raster - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "soft_raster - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "soft_raster - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "soft_raster - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/soft_raster_rel" -# PROP Intermediate_Dir "obj/soft_raster_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_soft_raster.dll" - -!ELSEIF "$(CFG)" == "soft_raster - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/soft_raster_deb" -# PROP Intermediate_Dir "obj/soft_raster_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_soft_raster.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "soft_raster - Win32 Release" -# Name "soft_raster - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\soft_raster\ftgrays.c - -!IF "$(CFG)" == "soft_raster - Win32 Release" - -!ELSEIF "$(CFG)" == "soft_raster - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\rast_soft.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\rast_soft.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_565.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_argb.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_load.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_rgb.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\stencil.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\surface.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/standalone2drender.dsp b/build/msvc6/standalone2drender.dsp deleted file mode 100644 index ec9cf4f..0000000 --- a/build/msvc6/standalone2drender.dsp +++ /dev/null @@ -1,267 +0,0 @@ -# Microsoft Developer Studio Project File - Name="standalone2drender" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=standalone2drender - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "standalone2drender.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "standalone2drender.mak" CFG="standalone2drender - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "standalone2drender - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "standalone2drender - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "standalone2drender - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/sar2d_rel" -# PROP Intermediate_Dir "obj/sar2d_rel" -# PROP Target_Dir "" -F90=df.exe -MTL=midl.exe -LINK32=link.exe -lib -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include/freetype" /I "../../modules/m4_rend" /I "../../modules/render2d" /I "../../modules/ft_font" /I "../../modules/raw_out" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /D "GPAC_STANDALONE_RENDER_2D" /D "DANAE" /FR /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"../../bin/w32_rel/gpac_sar2d.lib" - -!ELSEIF "$(CFG)" == "standalone2drender - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/sar2d_deb" -# PROP Intermediate_Dir "obj/sar2d_deb" -# PROP Target_Dir "" -F90=df.exe -MTL=midl.exe -LINK32=link.exe -lib -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include/freetype" /I "../../modules/m4_rend" /I "../../modules/render2d" /I "../../modules/ft_font" /I "../../modules/raw_out" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /D "GPAC_STANDALONE_RENDER_2D" /D "DANAE" /FR /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo /out:"../../bin/w32_deb/gpac_sar2d.lib" - -!ENDIF - -# Begin Target - -# Name "standalone2drender - Win32 Release" -# Name "standalone2drender - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\modules\render2d\background2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\drawable.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\form.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\ft_font\ft_font.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\ftgrays.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\geometry_stacks.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\grouping.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\grouping_stacks.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\ifs2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\ils2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\layout.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\path_layout.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_565.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_argb.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_load.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\raster_rgb.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\raw_out\raw_video.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\render2d.c - -!IF "$(CFG)" == "standalone2drender - Win32 Release" - -# ADD CPP /FAcs - -!ELSEIF "$(CFG)" == "standalone2drender - Win32 Debug" - -!ENDIF - -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\render2d_nodes.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\sensor_stacks.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\sound.c -# End Source File -# Begin Source File - -SOURCE=..\..\applications\standalone2drender\standalone2drender.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\stencil.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\surface.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\svg_base.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\svg_media.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\svg_stacks.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\svg_text.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\text.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\texture_stacks.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\viewport.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\visualsurface2d.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\visualsurface2d_draw.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\modules\render2d\drawable.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\grouping.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\soft_raster\rast_soft.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\render2d.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\stacks2d.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\svg\svg_stacks.h -# End Source File -# Begin Source File - -SOURCE=..\..\modules\render2d\visualsurface2d.h -# End Source File -# End Group -# End Target -# End Project diff --git a/build/msvc6/svg_in.dsp b/build/msvc6/svg_in.dsp deleted file mode 100644 index 12b757e..0000000 --- a/build/msvc6/svg_in.dsp +++ /dev/null @@ -1,111 +0,0 @@ -# Microsoft Developer Studio Project File - Name="svg_in" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=svg_in - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "svg_in.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "svg_in.mak" CFG="svg_in - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "svg_in - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "svg_in - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "svg_in - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/svg_in_rel" -# PROP Intermediate_Dir "obj/svg_in_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SVG_IN_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include/zlib" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 zlib.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_svg_in.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "svg_in - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/svg_in_deb" -# PROP Intermediate_Dir "obj/svg_in_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SVG_IN_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include/zlib" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 zlib.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_svg_in.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "svg_in - Win32 Release" -# Name "svg_in - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\modules\svg_in\svg_in.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\svg_in\svg_in.def -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff --git a/build/msvc6/timedtext.dsp b/build/msvc6/timedtext.dsp deleted file mode 100644 index 5e35033..0000000 --- a/build/msvc6/timedtext.dsp +++ /dev/null @@ -1,103 +0,0 @@ -# Microsoft Developer Studio Project File - Name="timedtext" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=timedtext - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "timedtext.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "timedtext.mak" CFG="timedtext - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "timedtext - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "timedtext - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "timedtext - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/ttxt_rel" -# PROP Intermediate_Dir "obj/ttxt_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TIMEDTEXT_DEC_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_timedtext.dll" - -!ELSEIF "$(CFG)" == "timedtext - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/ttxt_deb" -# PROP Intermediate_Dir "obj/ttxt_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TIMEDTEXT_DEC_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_timedtext.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "timedtext - Win32 Release" -# Name "timedtext - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\timedtext\timedtext.def -# End Source File -# Begin Source File - -SOURCE=..\..\modules\timedtext\timedtext_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\timedtext\timedtext_in.c -# End Source File -# End Target -# End Project diff --git a/build/msvc6/wav_out.dsp b/build/msvc6/wav_out.dsp deleted file mode 100644 index 9ddec56..0000000 --- a/build/msvc6/wav_out.dsp +++ /dev/null @@ -1,99 +0,0 @@ -# Microsoft Developer Studio Project File - Name="wav_out" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=wav_out - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "wav_out.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "wav_out.mak" CFG="wav_out - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "wav_out - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "wav_out - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "wav_out - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/wav_out_rel" -# PROP Intermediate_Dir "obj/wav_out_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WAV_AUDIO_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 winmm.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_wav_out.dll" - -!ELSEIF "$(CFG)" == "wav_out - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/wav_out_deb" -# PROP Intermediate_Dir "obj/wav_out_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "WAV_AUDIO_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 winmm.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_wav_out.dll" /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "wav_out - Win32 Release" -# Name "wav_out - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\wav_out\wav_out.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\wav_out\wav_out.def -# End Source File -# End Target -# End Project diff --git a/build/msvc6/wxOsmo4.dsp b/build/msvc6/wxOsmo4.dsp deleted file mode 100644 index 3128357..0000000 --- a/build/msvc6/wxOsmo4.dsp +++ /dev/null @@ -1,156 +0,0 @@ -# Microsoft Developer Studio Project File - Name="wxOsmo4" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Application" 0x0101 - -CFG=wxOsmo4 - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "wxOsmo4.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "wxOsmo4.mak" CFG="wxOsmo4 - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "wxOsmo4 - Win32 Release" (based on "Win32 (x86) Application") -!MESSAGE "wxOsmo4 - Win32 Debug" (based on "Win32 (x86) Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "wxOsmo4 - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/osmo4_wx_rel" -# PROP Intermediate_Dir "obj/osmo4_wx_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 -# ADD LINK32 wxbase26.lib wxmsw26_core.lib comctl32.lib ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib rpcrt4.lib /nologo /subsystem:windows /machine:I386 /out:"../../bin/w32_rel/wxOsmo4.exe" - -!ELSEIF "$(CFG)" == "wxOsmo4 - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/osmo4_wx_deb" -# PROP Intermediate_Dir "obj/osmo4_wx_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept -# ADD LINK32 wxbase26d.lib wxmsw26d_core.lib comctl32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib rpcrt4.lib /nologo /subsystem:windows /debug /machine:I386 /out:"../../bin/w32_deb/wxOsmo4.exe" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "wxOsmo4 - Win32 Release" -# Name "wxOsmo4 - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\fileprops.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\menubtn.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\Playlist.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\wxGPACControl.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\wxOsmo4.cpp -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\wxOsmo4.rc -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\fileprops.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\menubtn.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\Playlist.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\resource.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\wxGPACControl.h -# End Source File -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\wxOsmo4.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=..\..\applications\osmo4_wx\osmo4.ico -# End Source File -# End Group -# End Target -# End Project diff --git a/build/msvc6/xvid_dec.dsp b/build/msvc6/xvid_dec.dsp deleted file mode 100644 index 863c985..0000000 --- a/build/msvc6/xvid_dec.dsp +++ /dev/null @@ -1,101 +0,0 @@ -# Microsoft Developer Studio Project File - Name="xvid_dec" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=xvid_dec - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "xvid_dec.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "xvid_dec.mak" CFG="xvid_dec - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "xvid_dec - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "xvid_dec - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "xvid_dec - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "obj/xvid_dec_rel" -# PROP Intermediate_Dir "obj/xvid_dec_rel" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XVID_DEC_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /O2 /I "../../include" /I "../../extra_lib/include/xvid" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 libxvidcore.lib /nologo /dll /machine:I386 /out:"../../bin/w32_rel/gm_xvid_dec.dll" /libpath:"../../extra_lib/lib/w32_rel" - -!ELSEIF "$(CFG)" == "xvid_dec - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "obj/xvid_dec_deb" -# PROP Intermediate_Dir "obj/xvid_dec_deb" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XVID_DEC_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../../include" /I "../../extra_lib/include/xvid" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FD /GZ /c -# SUBTRACT CPP /YX -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 libxvidcore.lib /nologo /dll /debug /machine:I386 /out:"../../bin/w32_deb/gm_xvid_dec.dll" /pdbtype:sept /libpath:"../../extra_lib/lib/w32_deb" - -!ENDIF - -# Begin Target - -# Name "xvid_dec - Win32 Release" -# Name "xvid_dec - Win32 Debug" -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_dec.c -# End Source File -# Begin Source File - -SOURCE=..\..\modules\xvid_dec\xvid_dec.def -# End Source File -# End Target -# End Project diff --git a/build/msvc8/GPAX.vcproj b/build/msvc8/GPAX.vcproj index 9651193..06d75b3 100644 --- a/build/msvc8/GPAX.vcproj +++ b/build/msvc8/GPAX.vcproj @@ -1,767 +1,649 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/Osmo4.vcproj b/build/msvc8/Osmo4.vcproj index 10910be..18e143e 100644 --- a/build/msvc8/Osmo4.vcproj +++ b/build/msvc8/Osmo4.vcproj @@ -1,1012 +1,892 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/V4Studio.vcproj b/build/msvc8/V4Studio.vcproj index 3db5ff4..5594bd3 100644 --- a/build/msvc8/V4Studio.vcproj +++ b/build/msvc8/V4Studio.vcproj @@ -1,922 +1,922 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/aac_in.vcproj b/build/msvc8/aac_in.vcproj index c0e8707..0e3897b 100644 --- a/build/msvc8/aac_in.vcproj +++ b/build/msvc8/aac_in.vcproj @@ -1,623 +1,499 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/ac3_in.vcproj b/build/msvc8/ac3_in.vcproj index eff70ae..38f421e 100644 --- a/build/msvc8/ac3_in.vcproj +++ b/build/msvc8/ac3_in.vcproj @@ -1,268 +1,422 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/amr_dec.vcproj b/build/msvc8/amr_dec.vcproj index 9c50fac..8b7515b 100644 --- a/build/msvc8/amr_dec.vcproj +++ b/build/msvc8/amr_dec.vcproj @@ -1,5447 +1,5331 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/amr_float_dec.vcproj b/build/msvc8/amr_float_dec.vcproj index c3c306b..5c33410 100644 --- a/build/msvc8/amr_float_dec.vcproj +++ b/build/msvc8/amr_float_dec.vcproj @@ -1,1565 +1,1449 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/audio_filter.vcproj b/build/msvc8/audio_filter.vcproj new file mode 100644 index 0000000..d413236 --- /dev/null +++ b/build/msvc8/audio_filter.vcproj @@ -0,0 +1,451 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/bifs_dec.vcproj b/build/msvc8/bifs_dec.vcproj index c2df3ae..6475a5a 100644 --- a/build/msvc8/bifs_dec.vcproj +++ b/build/msvc8/bifs_dec.vcproj @@ -1,569 +1,451 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/ctx_load.vcproj b/build/msvc8/ctx_load.vcproj index 06dd17b..cf563ab 100644 --- a/build/msvc8/ctx_load.vcproj +++ b/build/msvc8/ctx_load.vcproj @@ -1,569 +1,453 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/demo_is.vcproj b/build/msvc8/demo_is.vcproj new file mode 100644 index 0000000..2b3b2fc --- /dev/null +++ b/build/msvc8/demo_is.vcproj @@ -0,0 +1,576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/dummy_in.vcproj b/build/msvc8/dummy_in.vcproj index d0d5bcc..fe87c10 100644 --- a/build/msvc8/dummy_in.vcproj +++ b/build/msvc8/dummy_in.vcproj @@ -1,569 +1,451 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/dx_hw.vcproj b/build/msvc8/dx_hw.vcproj index 1176b6d..ce7d078 100644 --- a/build/msvc8/dx_hw.vcproj +++ b/build/msvc8/dx_hw.vcproj @@ -1,801 +1,673 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/ffmpeg_in.vcproj b/build/msvc8/ffmpeg_in.vcproj index 5a0761b..d8491be 100644 --- a/build/msvc8/ffmpeg_in.vcproj +++ b/build/msvc8/ffmpeg_in.vcproj @@ -1,661 +1,543 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/ft_font.vcproj b/build/msvc8/ft_font.vcproj index 56b5c94..cb8a321 100644 --- a/build/msvc8/ft_font.vcproj +++ b/build/msvc8/ft_font.vcproj @@ -1,547 +1,427 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/gapi.vcproj b/build/msvc8/gapi.vcproj new file mode 100644 index 0000000..f9cd18a --- /dev/null +++ b/build/msvc8/gapi.vcproj @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/gdip_raster.vcproj b/build/msvc8/gdip_raster.vcproj index 33fa10e..7ef1e56 100644 --- a/build/msvc8/gdip_raster.vcproj +++ b/build/msvc8/gdip_raster.vcproj @@ -1,699 +1,580 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/gpac.sln b/build/msvc8/gpac.sln index bc7ca77..aeb807f 100644 --- a/build/msvc8/gpac.sln +++ b/build/msvc8/gpac.sln @@ -1,346 +1,791 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPAX", "GPAX.vcproj", "{72486240-A124-496E-A67A-E76FEC7E99BE}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Osmo4", "Osmo4.vcproj", "{C79C2D73-06E9-4622-92CE-F166B1B51792}" - ProjectSection(ProjectDependencies) = postProject - {A86E6EF8-3683-4AD0-8878-7A0D51326088} = {A86E6EF8-3683-4AD0-8878-7A0D51326088} - {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60} = {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60} - {464697D2-BA44-446F-8223-1EB3969ED1A8} = {464697D2-BA44-446F-8223-1EB3969ED1A8} - {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B} = {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B} - {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D} = {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D} - {5D3983BF-143F-49C3-9284-89778282AEFE} = {5D3983BF-143F-49C3-9284-89778282AEFE} - {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45} = {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45} - {879E26B2-48DB-47B3-B82F-893696286E6F} = {879E26B2-48DB-47B3-B82F-893696286E6F} - {402A8794-B724-44A3-B608-84B600ECA387} = {402A8794-B724-44A3-B608-84B600ECA387} - {073E2381-4FDE-4C4D-A117-C489EB17C48B} = {073E2381-4FDE-4C4D-A117-C489EB17C48B} - {1F7CD37F-DC9A-4AC7-881B-36B263A644C7} = {1F7CD37F-DC9A-4AC7-881B-36B263A644C7} - {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E} = {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E} - {FC8F1F56-078E-470D-B252-68EDDE88AA9D} = {FC8F1F56-078E-470D-B252-68EDDE88AA9D} - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - {E2DBD151-9523-4E1A-9478-F3F825668F6E} = {E2DBD151-9523-4E1A-9478-F3F825668F6E} - {CAA5A551-006A-4119-8115-FB14692E719F} = {CAA5A551-006A-4119-8115-FB14692E719F} - {01183543-B182-4E32-9FD6-FC15C847316C} = {01183543-B182-4E32-9FD6-FC15C847316C} - {BAE0C03A-56E0-4D37-89F5-62DD03BFC013} = {BAE0C03A-56E0-4D37-89F5-62DD03BFC013} - {B38E812D-9823-48E7-BE5F-BF09B0AD4165} = {B38E812D-9823-48E7-BE5F-BF09B0AD4165} - {042D3628-67F3-4B5C-8BC0-CD9AFA416974} = {042D3628-67F3-4B5C-8BC0-CD9AFA416974} - {71071F01-C813-4384-BE38-0F4020BCC0EE} = {71071F01-C813-4384-BE38-0F4020BCC0EE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aac_in", "aac_in.vcproj", "{1F7CD37F-DC9A-4AC7-881B-36B263A644C7}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amr_dec", "amr_dec.vcproj", "{5ED5A1C8-DB34-4089-8E53-EFB225754D02}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amr_float_dec", "amr_float_dec.vcproj", "{5D3983BF-143F-49C3-9284-89778282AEFE}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bifs_dec", "bifs_dec.vcproj", "{73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ctx_load", "ctx_load.vcproj", "{BAE0C03A-56E0-4D37-89F5-62DD03BFC013}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy_in", "dummy_in.vcproj", "{073E2381-4FDE-4C4D-A117-C489EB17C48B}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dx_hw", "dx_hw.vcproj", "{B64736BD-9245-4F40-961D-EB9822265764}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ffmpeg_in", "ffmpeg_in.vcproj", "{9FECAB79-BC70-4EEA-A23B-B64159F904B3}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ft_font", "ft_font.vcproj", "{042D3628-67F3-4B5C-8BC0-CD9AFA416974}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gdip_raster", "gdip_raster.vcproj", "{CAA5A551-006A-4119-8115-FB14692E719F}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "img_in", "img_in.vcproj", "{9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isom_in", "isom_in.vcproj", "{FC8F1F56-078E-470D-B252-68EDDE88AA9D}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "laser_dec", "laser_dec.vcproj", "{879E26B2-48DB-47B3-B82F-893696286E6F}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgpac", "libgpac.vcproj", "{233014D5-F6E5-419D-8757-FA9CE7337088}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgpac_dll", "libgpac_dll.vcproj", "{D3540754-E0CF-4604-AC11-82DE9BD4D814}" - ProjectSection(ProjectDependencies) = postProject - {233014D5-F6E5-419D-8757-FA9CE7337088} = {233014D5-F6E5-419D-8757-FA9CE7337088} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp3_in", "mp3_in.vcproj", "{4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4box", "mp4box.vcproj", "{48E2C7C6-52EB-46FB-8722-00A62F46F497}" - ProjectSection(ProjectDependencies) = postProject - {233014D5-F6E5-419D-8757-FA9CE7337088} = {233014D5-F6E5-419D-8757-FA9CE7337088} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4client", "mp4client.vcproj", "{A35D99BF-D72D-4F56-99A1-97249B22BCE2}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpegts_in", "mpegts_in.vcproj", "{B38E812D-9823-48E7-BE5F-BF09B0AD4165}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odf_dec", "odf_dec.vcproj", "{A86E6EF8-3683-4AD0-8878-7A0D51326088}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ogg", "ogg.vcproj", "{3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osmozilla", "osmozilla.vcproj", "{A0288B75-0D95-4106-A3A7-779A891E8FEF}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raw_out", "raw_out.vcproj", "{8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rtp_in", "rtp_in.vcproj", "{E2DBD151-9523-4E1A-9478-F3F825668F6E}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "saf_in", "saf_in.vcproj", "{2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_out", "sdl_out.vcproj", "{F346A9A7-CF8D-4409-8776-1D4244F96EF8}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soft_raster", "soft_raster.vcproj", "{71071F01-C813-4384-BE38-0F4020BCC0EE}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "svg_in", "svg_in.vcproj", "{402A8794-B724-44A3-B608-84B600ECA387}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "timedtext", "timedtext.vcproj", "{464697D2-BA44-446F-8223-1EB3969ED1A8}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wav_out", "wav_out.vcproj", "{01183543-B182-4E32-9FD6-FC15C847316C}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xvid_dec", "xvid_dec.vcproj", "{4258687D-4905-46A6-9407-08F4F8A81CC0}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ismacryp", "ismacryp.vcproj", "{E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ac3_in", "ac3_in.vcproj", "{1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}" - ProjectSection(ProjectDependencies) = postProject - {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.ActiveCfg = Debug|Win32 - {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.Build.0 = Debug|Win32 - {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.ActiveCfg = Release|Win32 - {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.Build.0 = Release|Win32 - {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Win32.ActiveCfg = Debug|Win32 - {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Win32.Build.0 = Debug|Win32 - {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Win32.ActiveCfg = Release|Win32 - {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Win32.Build.0 = Release|Win32 - {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Win32.ActiveCfg = Debug|Win32 - {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Win32.Build.0 = Debug|Win32 - {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Win32.ActiveCfg = Release|Win32 - {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Win32.Build.0 = Release|Win32 - {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Win32.ActiveCfg = Debug|Win32 - {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Debug|Win32.Build.0 = Debug|Win32 - {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Win32.ActiveCfg = Release|Win32 - {5ED5A1C8-DB34-4089-8E53-EFB225754D02}.Release|Win32.Build.0 = Release|Win32 - {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Win32.ActiveCfg = Debug|Win32 - {5D3983BF-143F-49C3-9284-89778282AEFE}.Debug|Win32.Build.0 = Debug|Win32 - {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Win32.ActiveCfg = Release|Win32 - {5D3983BF-143F-49C3-9284-89778282AEFE}.Release|Win32.Build.0 = Release|Win32 - {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Win32.ActiveCfg = Debug|Win32 - {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Win32.Build.0 = Debug|Win32 - {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Win32.ActiveCfg = Release|Win32 - {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Win32.Build.0 = Release|Win32 - {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Win32.ActiveCfg = Debug|Win32 - {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Win32.Build.0 = Debug|Win32 - {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Win32.ActiveCfg = Release|Win32 - {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Win32.Build.0 = Release|Win32 - {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Win32.ActiveCfg = Debug|Win32 - {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Win32.Build.0 = Debug|Win32 - {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Win32.ActiveCfg = Release|Win32 - {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Win32.Build.0 = Release|Win32 - {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Win32.ActiveCfg = Debug|Win32 - {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Win32.Build.0 = Debug|Win32 - {B64736BD-9245-4F40-961D-EB9822265764}.Release|Win32.ActiveCfg = Release|Win32 - {B64736BD-9245-4F40-961D-EB9822265764}.Release|Win32.Build.0 = Release|Win32 - {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Win32.ActiveCfg = Debug|Win32 - {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Win32.Build.0 = Debug|Win32 - {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Win32.ActiveCfg = Release|Win32 - {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Win32.Build.0 = Release|Win32 - {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Win32.ActiveCfg = Debug|Win32 - {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Win32.Build.0 = Debug|Win32 - {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Win32.ActiveCfg = Release|Win32 - {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Win32.Build.0 = Release|Win32 - {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Win32.ActiveCfg = Debug|Win32 - {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Win32.Build.0 = Debug|Win32 - {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Win32.ActiveCfg = Release|Win32 - {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Win32.Build.0 = Release|Win32 - {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Win32.ActiveCfg = Debug|Win32 - {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Win32.Build.0 = Debug|Win32 - {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Win32.ActiveCfg = Release|Win32 - {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Win32.Build.0 = Release|Win32 - {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Win32.ActiveCfg = Debug|Win32 - {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Win32.Build.0 = Debug|Win32 - {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Win32.ActiveCfg = Release|Win32 - {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Win32.Build.0 = Release|Win32 - {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Win32.ActiveCfg = Debug|Win32 - {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Win32.Build.0 = Debug|Win32 - {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Win32.ActiveCfg = Release|Win32 - {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Win32.Build.0 = Release|Win32 - {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Win32.ActiveCfg = Debug|Win32 - {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Win32.Build.0 = Debug|Win32 - {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Win32.ActiveCfg = Release|Win32 - {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Win32.Build.0 = Release|Win32 - {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Win32.ActiveCfg = Debug|Win32 - {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Win32.Build.0 = Debug|Win32 - {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Win32.ActiveCfg = Release|Win32 - {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Win32.Build.0 = Release|Win32 - {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Win32.ActiveCfg = Debug|Win32 - {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Win32.Build.0 = Debug|Win32 - {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Win32.ActiveCfg = Release|Win32 - {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Win32.Build.0 = Release|Win32 - {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Win32.ActiveCfg = Debug|Win32 - {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Win32.Build.0 = Debug|Win32 - {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Win32.ActiveCfg = Release|Win32 - {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Win32.Build.0 = Release|Win32 - {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.ActiveCfg = Debug|Win32 - {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.Build.0 = Debug|Win32 - {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.ActiveCfg = Release|Win32 - {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.Build.0 = Release|Win32 - {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Win32.ActiveCfg = Debug|Win32 - {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Win32.Build.0 = Debug|Win32 - {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Win32.ActiveCfg = Release|Win32 - {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Win32.Build.0 = Release|Win32 - {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Win32.ActiveCfg = Debug|Win32 - {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Win32.Build.0 = Debug|Win32 - {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Win32.ActiveCfg = Release|Win32 - {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Win32.Build.0 = Release|Win32 - {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Win32.ActiveCfg = Debug|Win32 - {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Win32.Build.0 = Debug|Win32 - {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Win32.ActiveCfg = Release|Win32 - {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Win32.Build.0 = Release|Win32 - {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Win32.ActiveCfg = Debug|Win32 - {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Win32.Build.0 = Debug|Win32 - {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Win32.ActiveCfg = Release|Win32 - {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Win32.Build.0 = Release|Win32 - {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Win32.ActiveCfg = Debug|Win32 - {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Win32.Build.0 = Debug|Win32 - {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Win32.ActiveCfg = Release|Win32 - {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Win32.Build.0 = Release|Win32 - {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Win32.ActiveCfg = Debug|Win32 - {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Win32.Build.0 = Debug|Win32 - {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Win32.ActiveCfg = Release|Win32 - {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Win32.Build.0 = Release|Win32 - {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Win32.ActiveCfg = Debug|Win32 - {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Win32.Build.0 = Debug|Win32 - {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Win32.ActiveCfg = Release|Win32 - {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Win32.Build.0 = Release|Win32 - {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Win32.ActiveCfg = Debug|Win32 - {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Win32.Build.0 = Debug|Win32 - {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Win32.ActiveCfg = Release|Win32 - {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Win32.Build.0 = Release|Win32 - {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Win32.ActiveCfg = Debug|Win32 - {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Win32.Build.0 = Debug|Win32 - {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Win32.ActiveCfg = Release|Win32 - {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Win32.Build.0 = Release|Win32 - {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Win32.ActiveCfg = Debug|Win32 - {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Win32.Build.0 = Debug|Win32 - {402A8794-B724-44A3-B608-84B600ECA387}.Release|Win32.ActiveCfg = Release|Win32 - {402A8794-B724-44A3-B608-84B600ECA387}.Release|Win32.Build.0 = Release|Win32 - {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Win32.ActiveCfg = Debug|Win32 - {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Win32.Build.0 = Debug|Win32 - {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Win32.ActiveCfg = Release|Win32 - {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Win32.Build.0 = Release|Win32 - {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Win32.ActiveCfg = Debug|Win32 - {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Win32.Build.0 = Debug|Win32 - {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Win32.ActiveCfg = Release|Win32 - {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Win32.Build.0 = Release|Win32 - {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Win32.ActiveCfg = Debug|Win32 - {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Win32.Build.0 = Debug|Win32 - {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Win32.ActiveCfg = Release|Win32 - {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Win32.Build.0 = Release|Win32 - {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Win32.ActiveCfg = Debug|Win32 - {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Win32.Build.0 = Debug|Win32 - {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Win32.ActiveCfg = Release|Win32 - {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Win32.Build.0 = Release|Win32 - {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Win32.ActiveCfg = Debug|Win32 - {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Win32.Build.0 = Debug|Win32 - {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Win32.ActiveCfg = Release|Win32 - {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPAX", "GPAX.vcproj", "{72486240-A124-496E-A67A-E76FEC7E99BE}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Osmo4", "Osmo4.vcproj", "{C79C2D73-06E9-4622-92CE-F166B1B51792}" + ProjectSection(ProjectDependencies) = postProject + {71071F01-C813-4384-BE38-0F4020BCC0EE} = {71071F01-C813-4384-BE38-0F4020BCC0EE} + {042D3628-67F3-4B5C-8BC0-CD9AFA416974} = {042D3628-67F3-4B5C-8BC0-CD9AFA416974} + {B38E812D-9823-48E7-BE5F-BF09B0AD4165} = {B38E812D-9823-48E7-BE5F-BF09B0AD4165} + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013} = {BAE0C03A-56E0-4D37-89F5-62DD03BFC013} + {01183543-B182-4E32-9FD6-FC15C847316C} = {01183543-B182-4E32-9FD6-FC15C847316C} + {CAA5A551-006A-4119-8115-FB14692E719F} = {CAA5A551-006A-4119-8115-FB14692E719F} + {E2DBD151-9523-4E1A-9478-F3F825668F6E} = {E2DBD151-9523-4E1A-9478-F3F825668F6E} + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + {FC8F1F56-078E-470D-B252-68EDDE88AA9D} = {FC8F1F56-078E-470D-B252-68EDDE88AA9D} + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E} = {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E} + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7} = {1F7CD37F-DC9A-4AC7-881B-36B263A644C7} + {073E2381-4FDE-4C4D-A117-C489EB17C48B} = {073E2381-4FDE-4C4D-A117-C489EB17C48B} + {402A8794-B724-44A3-B608-84B600ECA387} = {402A8794-B724-44A3-B608-84B600ECA387} + {879E26B2-48DB-47B3-B82F-893696286E6F} = {879E26B2-48DB-47B3-B82F-893696286E6F} + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45} = {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45} + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D} = {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D} + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B} = {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B} + {464697D2-BA44-446F-8223-1EB3969ED1A8} = {464697D2-BA44-446F-8223-1EB3969ED1A8} + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60} = {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60} + {A86E6EF8-3683-4AD0-8878-7A0D51326088} = {A86E6EF8-3683-4AD0-8878-7A0D51326088} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aac_in", "aac_in.vcproj", "{1F7CD37F-DC9A-4AC7-881B-36B263A644C7}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bifs_dec", "bifs_dec.vcproj", "{73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ctx_load", "ctx_load.vcproj", "{BAE0C03A-56E0-4D37-89F5-62DD03BFC013}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy_in", "dummy_in.vcproj", "{073E2381-4FDE-4C4D-A117-C489EB17C48B}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dx_hw", "dx_hw.vcproj", "{B64736BD-9245-4F40-961D-EB9822265764}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ffmpeg_in", "ffmpeg_in.vcproj", "{9FECAB79-BC70-4EEA-A23B-B64159F904B3}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ft_font", "ft_font.vcproj", "{042D3628-67F3-4B5C-8BC0-CD9AFA416974}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gdip_raster", "gdip_raster.vcproj", "{CAA5A551-006A-4119-8115-FB14692E719F}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "img_in", "img_in.vcproj", "{9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isom_in", "isom_in.vcproj", "{FC8F1F56-078E-470D-B252-68EDDE88AA9D}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "laser_dec", "laser_dec.vcproj", "{879E26B2-48DB-47B3-B82F-893696286E6F}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgpac", "libgpac.vcproj", "{233014D5-F6E5-419D-8757-FA9CE7337088}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgpac_dll", "libgpac_dll.vcproj", "{D3540754-E0CF-4604-AC11-82DE9BD4D814}" + ProjectSection(ProjectDependencies) = postProject + {233014D5-F6E5-419D-8757-FA9CE7337088} = {233014D5-F6E5-419D-8757-FA9CE7337088} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp3_in", "mp3_in.vcproj", "{4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4box", "mp4box.vcproj", "{48E2C7C6-52EB-46FB-8722-00A62F46F497}" + ProjectSection(ProjectDependencies) = postProject + {233014D5-F6E5-419D-8757-FA9CE7337088} = {233014D5-F6E5-419D-8757-FA9CE7337088} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4client", "mp4client.vcproj", "{A35D99BF-D72D-4F56-99A1-97249B22BCE2}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpegts_in", "mpegts_in.vcproj", "{B38E812D-9823-48E7-BE5F-BF09B0AD4165}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odf_dec", "odf_dec.vcproj", "{A86E6EF8-3683-4AD0-8878-7A0D51326088}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ogg", "ogg.vcproj", "{3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osmozilla", "osmozilla.vcproj", "{A0288B75-0D95-4106-A3A7-779A891E8FEF}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raw_out", "raw_out.vcproj", "{8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rtp_in", "rtp_in.vcproj", "{E2DBD151-9523-4E1A-9478-F3F825668F6E}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "saf_in", "saf_in.vcproj", "{2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_out", "sdl_out.vcproj", "{F346A9A7-CF8D-4409-8776-1D4244F96EF8}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soft_raster", "soft_raster.vcproj", "{71071F01-C813-4384-BE38-0F4020BCC0EE}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "svg_in", "svg_in.vcproj", "{402A8794-B724-44A3-B608-84B600ECA387}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "timedtext", "timedtext.vcproj", "{464697D2-BA44-446F-8223-1EB3969ED1A8}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wav_out", "wav_out.vcproj", "{01183543-B182-4E32-9FD6-FC15C847316C}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xvid_dec", "xvid_dec.vcproj", "{4258687D-4905-46A6-9407-08F4F8A81CC0}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ismacryp", "ismacryp.vcproj", "{E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ac3_in", "ac3_in.vcproj", "{1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gapi", "gapi.vcproj", "{F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osmophone", "osmophone.vcproj", "{CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpac_js", "gpac_js.vcproj", "{27F7FDF4-479B-47B5-BFEA-12E9EA41F663}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_filter", "audio_filter.vcproj", "{C993119B-29B1-49C8-8EA3-A9ABF633164E}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "platinum", "platinum.vcproj", "{694C765F-DFD6-467E-A813-B3F887E822D4}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "widgetman", "widgetman.vcproj", "{07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "redirect_av", "redirect_av.vcproj", "{073E2281-4FDE-4C4D-A217-C489DB17C48C}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Mixed Platforms = Debug|Mixed Platforms + Debug|Smartphone 2003 (ARMV4) = Debug|Smartphone 2003 (ARMV4) + Debug|Win32 = Debug|Win32 + Release|Mixed Platforms = Release|Mixed Platforms + Release|Smartphone 2003 (ARMV4) = Release|Smartphone 2003 (ARMV4) + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.ActiveCfg = Debug|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.Build.0 = Debug|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.ActiveCfg = Release|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.Build.0 = Release|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Win32.ActiveCfg = Debug|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Win32.Build.0 = Debug|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Win32.ActiveCfg = Release|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Win32.Build.0 = Release|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Win32.ActiveCfg = Debug|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Win32.Build.0 = Debug|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Win32.ActiveCfg = Release|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Win32.Build.0 = Release|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Win32.ActiveCfg = Debug|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Win32.Build.0 = Debug|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Win32.ActiveCfg = Release|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Win32.Build.0 = Release|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Win32.ActiveCfg = Debug|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Win32.Build.0 = Debug|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Win32.ActiveCfg = Release|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Win32.Build.0 = Release|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Win32.ActiveCfg = Debug|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Win32.Build.0 = Debug|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Win32.ActiveCfg = Release|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Win32.Build.0 = Release|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Win32.ActiveCfg = Debug|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Win32.Build.0 = Debug|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Win32.ActiveCfg = Release|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Win32.Build.0 = Release|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Win32.ActiveCfg = Debug|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Win32.Build.0 = Debug|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Win32.ActiveCfg = Release|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Win32.Build.0 = Release|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Win32.ActiveCfg = Debug|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Win32.Build.0 = Debug|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Win32.ActiveCfg = Release|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Win32.Build.0 = Release|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Win32.ActiveCfg = Debug|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Win32.Build.0 = Debug|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Win32.ActiveCfg = Release|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Win32.Build.0 = Release|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Win32.ActiveCfg = Debug|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Win32.Build.0 = Debug|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Win32.ActiveCfg = Release|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Win32.Build.0 = Release|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Win32.ActiveCfg = Debug|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Win32.Build.0 = Debug|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Win32.ActiveCfg = Release|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Win32.Build.0 = Release|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Win32.ActiveCfg = Debug|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Win32.Build.0 = Debug|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Win32.ActiveCfg = Release|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Win32.Build.0 = Release|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Win32.ActiveCfg = Debug|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Win32.Build.0 = Debug|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Win32.ActiveCfg = Release|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Win32.Build.0 = Release|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Win32.ActiveCfg = Debug|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Win32.Build.0 = Debug|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Win32.ActiveCfg = Release|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Win32.Build.0 = Release|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Win32.ActiveCfg = Debug|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Win32.Build.0 = Debug|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Win32.ActiveCfg = Release|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Win32.Build.0 = Release|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Win32.ActiveCfg = Debug|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Win32.Build.0 = Debug|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Win32.ActiveCfg = Release|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Win32.Build.0 = Release|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.ActiveCfg = Debug|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.Build.0 = Debug|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.ActiveCfg = Release|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.Build.0 = Release|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Win32.ActiveCfg = Debug|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Win32.Build.0 = Debug|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Win32.ActiveCfg = Release|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Win32.Build.0 = Release|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Win32.ActiveCfg = Debug|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Win32.Build.0 = Debug|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Win32.ActiveCfg = Release|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Win32.Build.0 = Release|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Win32.ActiveCfg = Debug|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Win32.Build.0 = Debug|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Win32.ActiveCfg = Release|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Win32.Build.0 = Release|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Win32.ActiveCfg = Debug|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Win32.Build.0 = Debug|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Win32.ActiveCfg = Release|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Win32.Build.0 = Release|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Win32.ActiveCfg = Debug|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Win32.Build.0 = Debug|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Win32.ActiveCfg = Release|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Win32.Build.0 = Release|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Win32.ActiveCfg = Debug|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Win32.Build.0 = Debug|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Win32.ActiveCfg = Release|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Win32.Build.0 = Release|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Win32.ActiveCfg = Debug|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Win32.Build.0 = Debug|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Win32.ActiveCfg = Release|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Win32.Build.0 = Release|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Win32.Build.0 = Debug|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Win32.ActiveCfg = Release|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Win32.Build.0 = Release|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Win32.Build.0 = Debug|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Win32.ActiveCfg = Release|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Win32.Build.0 = Release|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Win32.ActiveCfg = Debug|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Win32.Build.0 = Debug|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Win32.ActiveCfg = Release|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Win32.Build.0 = Release|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Win32.ActiveCfg = Debug|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Win32.Build.0 = Debug|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Win32.ActiveCfg = Release|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Win32.Build.0 = Release|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Win32.ActiveCfg = Debug|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Win32.Build.0 = Debug|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Win32.ActiveCfg = Release|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Win32.Build.0 = Release|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Win32.ActiveCfg = Debug|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Win32.Build.0 = Debug|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Win32.ActiveCfg = Release|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Win32.Build.0 = Release|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Win32.ActiveCfg = Debug|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Win32.Build.0 = Debug|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Win32.ActiveCfg = Release|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Win32.Build.0 = Release|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Win32.ActiveCfg = Debug|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Win32.Build.0 = Debug|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Win32.ActiveCfg = Release|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Win32.Build.0 = Release|Win32 + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Mixed Platforms.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Mixed Platforms.Build.0 = Debug|Pocket PC 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Win32.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Mixed Platforms.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Mixed Platforms.Build.0 = Release|Pocket PC 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Win32.ActiveCfg = Debug|Win32 + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Mixed Platforms.Build.0 = Release|Win32 + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Win32.ActiveCfg = Release|Win32 + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Win32.Build.0 = Release|Win32 + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Win32.ActiveCfg = Debug|Win32 + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Win32.Build.0 = Debug|Win32 + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Win32.ActiveCfg = Release|Win32 + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Win32.Build.0 = Release|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Win32.ActiveCfg = Debug|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Win32.Build.0 = Debug|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Win32.ActiveCfg = Release|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Win32.Build.0 = Release|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Win32.ActiveCfg = Debug|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Win32.Build.0 = Debug|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Win32.ActiveCfg = Release|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Win32.Build.0 = Release|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Win32.ActiveCfg = Debug|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Win32.Build.0 = Debug|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Win32.ActiveCfg = Release|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Win32.Build.0 = Release|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Debug|Mixed Platforms.Build.0 = Debug|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Debug|Win32.ActiveCfg = Debug|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Debug|Win32.Build.0 = Debug|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Release|Mixed Platforms.ActiveCfg = Release|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Release|Mixed Platforms.Build.0 = Release|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Release|Win32.ActiveCfg = Release|Win32 + {D08849E2-C077-4360-A70C-7B858A486EA4}.Release|Win32.Build.0 = Release|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Mixed Platforms.ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Mixed Platforms.Build.0 = Debug|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Mixed Platforms.Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Win32.ActiveCfg = Debug|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Win32.Build.0 = Debug|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Mixed Platforms.ActiveCfg = Release|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Mixed Platforms.Build.0 = Release|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Mixed Platforms.Deploy.0 = Release|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Win32.ActiveCfg = Release|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/build/msvc8/gpac_js.vcproj b/build/msvc8/gpac_js.vcproj new file mode 100644 index 0000000..b8cae4d --- /dev/null +++ b/build/msvc8/gpac_js.vcproj @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/img_in.vcproj b/build/msvc8/img_in.vcproj index a3032e5..167561e 100644 --- a/build/msvc8/img_in.vcproj +++ b/build/msvc8/img_in.vcproj @@ -1,745 +1,626 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/ismacryp.vcproj b/build/msvc8/ismacryp.vcproj index 14ba581..d24bd95 100644 --- a/build/msvc8/ismacryp.vcproj +++ b/build/msvc8/ismacryp.vcproj @@ -1,569 +1,452 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/isom_in.vcproj b/build/msvc8/isom_in.vcproj index 70bc06f..aa31fe0 100644 --- a/build/msvc8/isom_in.vcproj +++ b/build/msvc8/isom_in.vcproj @@ -1,695 +1,578 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/laser_dec.vcproj b/build/msvc8/laser_dec.vcproj index c494869..ced1d7a 100644 --- a/build/msvc8/laser_dec.vcproj +++ b/build/msvc8/laser_dec.vcproj @@ -1,569 +1,450 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/libgpac.vcproj b/build/msvc8/libgpac.vcproj index 0a27efa..1f61fb9 100644 --- a/build/msvc8/libgpac.vcproj +++ b/build/msvc8/libgpac.vcproj @@ -1,7219 +1,7124 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/libgpac_dll.vcproj b/build/msvc8/libgpac_dll.vcproj index 540b085..b8d4fbc 100644 --- a/build/msvc8/libgpac_dll.vcproj +++ b/build/msvc8/libgpac_dll.vcproj @@ -1,539 +1,430 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/m3u82mpd.vcproj b/build/msvc8/m3u82mpd.vcproj new file mode 100644 index 0000000..2944b33 --- /dev/null +++ b/build/msvc8/m3u82mpd.vcproj @@ -0,0 +1,421 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/m3u8_in.vcproj b/build/msvc8/m3u8_in.vcproj new file mode 100644 index 0000000..4dd9f3a --- /dev/null +++ b/build/msvc8/m3u8_in.vcproj @@ -0,0 +1,218 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/mp3_in.vcproj b/build/msvc8/mp3_in.vcproj index 80719dc..22bff34 100644 --- a/build/msvc8/mp3_in.vcproj +++ b/build/msvc8/mp3_in.vcproj @@ -1,617 +1,498 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/mp4box.vcproj b/build/msvc8/mp4box.vcproj index d6bbbbc..109c9a3 100644 --- a/build/msvc8/mp4box.vcproj +++ b/build/msvc8/mp4box.vcproj @@ -1,639 +1,525 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/mp4client.vcproj b/build/msvc8/mp4client.vcproj index a6d2239..e210b94 100644 --- a/build/msvc8/mp4client.vcproj +++ b/build/msvc8/mp4client.vcproj @@ -1,595 +1,474 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/mpd_in.vcproj b/build/msvc8/mpd_in.vcproj new file mode 100644 index 0000000..5ad1d92 --- /dev/null +++ b/build/msvc8/mpd_in.vcproj @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/mpegts_in.vcproj b/build/msvc8/mpegts_in.vcproj index 8f2ec4f..bf67bf8 100644 --- a/build/msvc8/mpegts_in.vcproj +++ b/build/msvc8/mpegts_in.vcproj @@ -1,584 +1,452 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/odf_dec.vcproj b/build/msvc8/odf_dec.vcproj index 808017b..4af4c5a 100644 --- a/build/msvc8/odf_dec.vcproj +++ b/build/msvc8/odf_dec.vcproj @@ -1,571 +1,451 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/ogg.vcproj b/build/msvc8/ogg.vcproj index 5eb6cd2..a7beb25 100644 --- a/build/msvc8/ogg.vcproj +++ b/build/msvc8/ogg.vcproj @@ -1,701 +1,582 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/opencv_is.vcproj b/build/msvc8/opencv_is.vcproj new file mode 100644 index 0000000..b2c0642 --- /dev/null +++ b/build/msvc8/opencv_is.vcproj @@ -0,0 +1,577 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/opensvc.vcproj b/build/msvc8/opensvc.vcproj new file mode 100644 index 0000000..3ffe1a4 --- /dev/null +++ b/build/msvc8/opensvc.vcproj @@ -0,0 +1,455 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/osmophone.vcproj b/build/msvc8/osmophone.vcproj new file mode 100644 index 0000000..8b648a3 --- /dev/null +++ b/build/msvc8/osmophone.vcproj @@ -0,0 +1,586 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/osmozilla.vcproj b/build/msvc8/osmozilla.vcproj index ed9b0b6..dbaebd7 100644 --- a/build/msvc8/osmozilla.vcproj +++ b/build/msvc8/osmozilla.vcproj @@ -1,766 +1,648 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/platinum.vcproj b/build/msvc8/platinum.vcproj new file mode 100644 index 0000000..e6e5f28 --- /dev/null +++ b/build/msvc8/platinum.vcproj @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/raw_out.vcproj b/build/msvc8/raw_out.vcproj index bf72878..9ac78e4 100644 --- a/build/msvc8/raw_out.vcproj +++ b/build/msvc8/raw_out.vcproj @@ -1,569 +1,452 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/redirect_av.vcproj b/build/msvc8/redirect_av.vcproj new file mode 100644 index 0000000..84aafc2 --- /dev/null +++ b/build/msvc8/redirect_av.vcproj @@ -0,0 +1,453 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/rtp_in.vcproj b/build/msvc8/rtp_in.vcproj index 2809ce9..e424b89 100644 --- a/build/msvc8/rtp_in.vcproj +++ b/build/msvc8/rtp_in.vcproj @@ -1,773 +1,656 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/saf_in.vcproj b/build/msvc8/saf_in.vcproj index 8067cb7..b95a1b8 100644 --- a/build/msvc8/saf_in.vcproj +++ b/build/msvc8/saf_in.vcproj @@ -1,574 +1,457 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/sdl_out.vcproj b/build/msvc8/sdl_out.vcproj index e2571c2..dbf4605 100644 --- a/build/msvc8/sdl_out.vcproj +++ b/build/msvc8/sdl_out.vcproj @@ -1,700 +1,580 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/soft_raster.vcproj b/build/msvc8/soft_raster.vcproj index 008a684..0389eff 100644 --- a/build/msvc8/soft_raster.vcproj +++ b/build/msvc8/soft_raster.vcproj @@ -1,813 +1,694 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/svg_in.vcproj b/build/msvc8/svg_in.vcproj index 22ec71e..5d25d90 100644 --- a/build/msvc8/svg_in.vcproj +++ b/build/msvc8/svg_in.vcproj @@ -1,592 +1,458 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/timedtext.vcproj b/build/msvc8/timedtext.vcproj index 5f44f77..7f19b5e 100644 --- a/build/msvc8/timedtext.vcproj +++ b/build/msvc8/timedtext.vcproj @@ -1,609 +1,492 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/ui_rec.vcproj b/build/msvc8/ui_rec.vcproj new file mode 100644 index 0000000..2812055 --- /dev/null +++ b/build/msvc8/ui_rec.vcproj @@ -0,0 +1,576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/validator.vcproj b/build/msvc8/validator.vcproj new file mode 100644 index 0000000..d06fb9c --- /dev/null +++ b/build/msvc8/validator.vcproj @@ -0,0 +1,574 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/wav_out.vcproj b/build/msvc8/wav_out.vcproj index 13573be..1f93af7 100644 --- a/build/msvc8/wav_out.vcproj +++ b/build/msvc8/wav_out.vcproj @@ -1,573 +1,454 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/widgetman.vcproj b/build/msvc8/widgetman.vcproj new file mode 100644 index 0000000..820ed3a --- /dev/null +++ b/build/msvc8/widgetman.vcproj @@ -0,0 +1,447 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/wiiis.vcproj b/build/msvc8/wiiis.vcproj new file mode 100644 index 0000000..b6c0193 --- /dev/null +++ b/build/msvc8/wiiis.vcproj @@ -0,0 +1,578 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/wxOsmo4.vcproj b/build/msvc8/wxOsmo4.vcproj index 64ce65b..dbe64f2 100644 --- a/build/msvc8/wxOsmo4.vcproj +++ b/build/msvc8/wxOsmo4.vcproj @@ -1,388 +1,388 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc8/xvid_dec.vcproj b/build/msvc8/xvid_dec.vcproj index cb9a9ad..e0e9bc1 100644 --- a/build/msvc8/xvid_dec.vcproj +++ b/build/msvc8/xvid_dec.vcproj @@ -1,577 +1,1237 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/GPAX.vcproj b/build/msvc9/GPAX.vcproj new file mode 100644 index 0000000..8c82577 --- /dev/null +++ b/build/msvc9/GPAX.vcproj @@ -0,0 +1,658 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/Osmo4.vcproj b/build/msvc9/Osmo4.vcproj new file mode 100644 index 0000000..3aa291a --- /dev/null +++ b/build/msvc9/Osmo4.vcproj @@ -0,0 +1,901 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/V4Studio.vcproj b/build/msvc9/V4Studio.vcproj new file mode 100644 index 0000000..5594bd3 --- /dev/null +++ b/build/msvc9/V4Studio.vcproj @@ -0,0 +1,922 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/aac_in.vcproj b/build/msvc9/aac_in.vcproj new file mode 100644 index 0000000..8796c3a --- /dev/null +++ b/build/msvc9/aac_in.vcproj @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/ac3_in.vcproj b/build/msvc9/ac3_in.vcproj new file mode 100644 index 0000000..1cc809c --- /dev/null +++ b/build/msvc9/ac3_in.vcproj @@ -0,0 +1,431 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/amr_dec.vcproj b/build/msvc9/amr_dec.vcproj new file mode 100644 index 0000000..8b7515b --- /dev/null +++ b/build/msvc9/amr_dec.vcproj @@ -0,0 +1,5331 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/amr_float_dec.vcproj b/build/msvc9/amr_float_dec.vcproj new file mode 100644 index 0000000..5c33410 --- /dev/null +++ b/build/msvc9/amr_float_dec.vcproj @@ -0,0 +1,1449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/audio_filter.vcproj b/build/msvc9/audio_filter.vcproj new file mode 100644 index 0000000..80eede9 --- /dev/null +++ b/build/msvc9/audio_filter.vcproj @@ -0,0 +1,460 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/bifs_dec.vcproj b/build/msvc9/bifs_dec.vcproj new file mode 100644 index 0000000..af0f677 --- /dev/null +++ b/build/msvc9/bifs_dec.vcproj @@ -0,0 +1,460 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/ctx_load.vcproj b/build/msvc9/ctx_load.vcproj new file mode 100644 index 0000000..77fcda8 --- /dev/null +++ b/build/msvc9/ctx_load.vcproj @@ -0,0 +1,462 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/demo_is.vcproj b/build/msvc9/demo_is.vcproj new file mode 100644 index 0000000..2b3b2fc --- /dev/null +++ b/build/msvc9/demo_is.vcproj @@ -0,0 +1,576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/dummy_in.vcproj b/build/msvc9/dummy_in.vcproj new file mode 100644 index 0000000..411fb04 --- /dev/null +++ b/build/msvc9/dummy_in.vcproj @@ -0,0 +1,460 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/dx_hw.vcproj b/build/msvc9/dx_hw.vcproj new file mode 100644 index 0000000..c2bf331 --- /dev/null +++ b/build/msvc9/dx_hw.vcproj @@ -0,0 +1,682 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/ffmpeg_in.vcproj b/build/msvc9/ffmpeg_in.vcproj new file mode 100644 index 0000000..e64e014 --- /dev/null +++ b/build/msvc9/ffmpeg_in.vcproj @@ -0,0 +1,552 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/ft_font.vcproj b/build/msvc9/ft_font.vcproj new file mode 100644 index 0000000..740f083 --- /dev/null +++ b/build/msvc9/ft_font.vcproj @@ -0,0 +1,436 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/gapi.vcproj b/build/msvc9/gapi.vcproj new file mode 100644 index 0000000..d065f38 --- /dev/null +++ b/build/msvc9/gapi.vcproj @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/gdip_raster.vcproj b/build/msvc9/gdip_raster.vcproj new file mode 100644 index 0000000..92f09f1 --- /dev/null +++ b/build/msvc9/gdip_raster.vcproj @@ -0,0 +1,589 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/gpac.sln b/build/msvc9/gpac.sln new file mode 100644 index 0000000..9ad6c59 --- /dev/null +++ b/build/msvc9/gpac.sln @@ -0,0 +1,538 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GPAX", "GPAX.vcproj", "{72486240-A124-496E-A67A-E76FEC7E99BE}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Osmo4", "Osmo4.vcproj", "{C79C2D73-06E9-4622-92CE-F166B1B51792}" + ProjectSection(ProjectDependencies) = postProject + {71071F01-C813-4384-BE38-0F4020BCC0EE} = {71071F01-C813-4384-BE38-0F4020BCC0EE} + {042D3628-67F3-4B5C-8BC0-CD9AFA416974} = {042D3628-67F3-4B5C-8BC0-CD9AFA416974} + {B38E812D-9823-48E7-BE5F-BF09B0AD4165} = {B38E812D-9823-48E7-BE5F-BF09B0AD4165} + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013} = {BAE0C03A-56E0-4D37-89F5-62DD03BFC013} + {01183543-B182-4E32-9FD6-FC15C847316C} = {01183543-B182-4E32-9FD6-FC15C847316C} + {CAA5A551-006A-4119-8115-FB14692E719F} = {CAA5A551-006A-4119-8115-FB14692E719F} + {E2DBD151-9523-4E1A-9478-F3F825668F6E} = {E2DBD151-9523-4E1A-9478-F3F825668F6E} + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + {FC8F1F56-078E-470D-B252-68EDDE88AA9D} = {FC8F1F56-078E-470D-B252-68EDDE88AA9D} + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E} = {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E} + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7} = {1F7CD37F-DC9A-4AC7-881B-36B263A644C7} + {073E2381-4FDE-4C4D-A117-C489EB17C48B} = {073E2381-4FDE-4C4D-A117-C489EB17C48B} + {402A8794-B724-44A3-B608-84B600ECA387} = {402A8794-B724-44A3-B608-84B600ECA387} + {879E26B2-48DB-47B3-B82F-893696286E6F} = {879E26B2-48DB-47B3-B82F-893696286E6F} + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45} = {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45} + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D} = {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D} + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B} = {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B} + {464697D2-BA44-446F-8223-1EB3969ED1A8} = {464697D2-BA44-446F-8223-1EB3969ED1A8} + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60} = {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60} + {A86E6EF8-3683-4AD0-8878-7A0D51326088} = {A86E6EF8-3683-4AD0-8878-7A0D51326088} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aac_in", "aac_in.vcproj", "{1F7CD37F-DC9A-4AC7-881B-36B263A644C7}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bifs_dec", "bifs_dec.vcproj", "{73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ctx_load", "ctx_load.vcproj", "{BAE0C03A-56E0-4D37-89F5-62DD03BFC013}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dummy_in", "dummy_in.vcproj", "{073E2381-4FDE-4C4D-A117-C489EB17C48B}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dx_hw", "dx_hw.vcproj", "{B64736BD-9245-4F40-961D-EB9822265764}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ffmpeg_in", "ffmpeg_in.vcproj", "{9FECAB79-BC70-4EEA-A23B-B64159F904B3}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ft_font", "ft_font.vcproj", "{042D3628-67F3-4B5C-8BC0-CD9AFA416974}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gdip_raster", "gdip_raster.vcproj", "{CAA5A551-006A-4119-8115-FB14692E719F}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "img_in", "img_in.vcproj", "{9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isom_in", "isom_in.vcproj", "{FC8F1F56-078E-470D-B252-68EDDE88AA9D}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "laser_dec", "laser_dec.vcproj", "{879E26B2-48DB-47B3-B82F-893696286E6F}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgpac", "libgpac.vcproj", "{233014D5-F6E5-419D-8757-FA9CE7337088}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libgpac_dll", "libgpac_dll.vcproj", "{D3540754-E0CF-4604-AC11-82DE9BD4D814}" + ProjectSection(ProjectDependencies) = postProject + {233014D5-F6E5-419D-8757-FA9CE7337088} = {233014D5-F6E5-419D-8757-FA9CE7337088} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp3_in", "mp3_in.vcproj", "{4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4box", "mp4box.vcproj", "{48E2C7C6-52EB-46FB-8722-00A62F46F497}" + ProjectSection(ProjectDependencies) = postProject + {233014D5-F6E5-419D-8757-FA9CE7337088} = {233014D5-F6E5-419D-8757-FA9CE7337088} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mp4client", "mp4client.vcproj", "{A35D99BF-D72D-4F56-99A1-97249B22BCE2}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpegts_in", "mpegts_in.vcproj", "{B38E812D-9823-48E7-BE5F-BF09B0AD4165}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odf_dec", "odf_dec.vcproj", "{A86E6EF8-3683-4AD0-8878-7A0D51326088}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ogg", "ogg.vcproj", "{3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osmozilla", "osmozilla.vcproj", "{A0288B75-0D95-4106-A3A7-779A891E8FEF}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raw_out", "raw_out.vcproj", "{8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rtp_in", "rtp_in.vcproj", "{E2DBD151-9523-4E1A-9478-F3F825668F6E}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "saf_in", "saf_in.vcproj", "{2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdl_out", "sdl_out.vcproj", "{F346A9A7-CF8D-4409-8776-1D4244F96EF8}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soft_raster", "soft_raster.vcproj", "{71071F01-C813-4384-BE38-0F4020BCC0EE}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "svg_in", "svg_in.vcproj", "{402A8794-B724-44A3-B608-84B600ECA387}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "timedtext", "timedtext.vcproj", "{464697D2-BA44-446F-8223-1EB3969ED1A8}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wav_out", "wav_out.vcproj", "{01183543-B182-4E32-9FD6-FC15C847316C}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xvid_dec", "xvid_dec.vcproj", "{4258687D-4905-46A6-9407-08F4F8A81CC0}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ismacryp", "ismacryp.vcproj", "{E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ac3_in", "ac3_in.vcproj", "{1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gapi", "gapi.vcproj", "{F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "osmophone", "osmophone.vcproj", "{CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpac_js", "gpac_js.vcproj", "{27F7FDF4-479B-47B5-BFEA-12E9EA41F663}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "audio_filter", "audio_filter.vcproj", "{C993119B-29B1-49C8-8EA3-A9ABF633164E}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "platinum", "platinum.vcproj", "{694C765F-DFD6-467E-A813-B3F887E822D4}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "widgetman", "widgetman.vcproj", "{07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "redirect_av", "redirect_av.vcproj", "{073E2281-4FDE-4C4D-A217-C489DB17C48C}" + ProjectSection(ProjectDependencies) = postProject + {D3540754-E0CF-4604-AC11-82DE9BD4D814} = {D3540754-E0CF-4604-AC11-82DE9BD4D814} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Smartphone 2003 (ARMV4) = Debug|Smartphone 2003 (ARMV4) + Debug|Win32 = Debug|Win32 + Release|Smartphone 2003 (ARMV4) = Release|Smartphone 2003 (ARMV4) + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.ActiveCfg = Debug|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Debug|Win32.Build.0 = Debug|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.ActiveCfg = Release|Win32 + {72486240-A124-496E-A67A-E76FEC7E99BE}.Release|Win32.Build.0 = Release|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Win32.ActiveCfg = Debug|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Debug|Win32.Build.0 = Debug|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Win32.ActiveCfg = Release|Win32 + {C79C2D73-06E9-4622-92CE-F166B1B51792}.Release|Win32.Build.0 = Release|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Win32.ActiveCfg = Debug|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Debug|Win32.Build.0 = Debug|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Win32.ActiveCfg = Release|Win32 + {1F7CD37F-DC9A-4AC7-881B-36B263A644C7}.Release|Win32.Build.0 = Release|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Win32.ActiveCfg = Debug|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Debug|Win32.Build.0 = Debug|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Win32.ActiveCfg = Release|Win32 + {73CF10D0-DEC8-4D4B-AAB8-45864694CB8B}.Release|Win32.Build.0 = Release|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Win32.ActiveCfg = Debug|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Debug|Win32.Build.0 = Debug|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Win32.ActiveCfg = Release|Win32 + {BAE0C03A-56E0-4D37-89F5-62DD03BFC013}.Release|Win32.Build.0 = Release|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Win32.ActiveCfg = Debug|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Debug|Win32.Build.0 = Debug|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Win32.ActiveCfg = Release|Win32 + {073E2381-4FDE-4C4D-A117-C489EB17C48B}.Release|Win32.Build.0 = Release|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Win32.ActiveCfg = Debug|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Debug|Win32.Build.0 = Debug|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Win32.ActiveCfg = Release|Win32 + {B64736BD-9245-4F40-961D-EB9822265764}.Release|Win32.Build.0 = Release|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Win32.ActiveCfg = Debug|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Debug|Win32.Build.0 = Debug|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Win32.ActiveCfg = Release|Win32 + {9FECAB79-BC70-4EEA-A23B-B64159F904B3}.Release|Win32.Build.0 = Release|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Win32.ActiveCfg = Debug|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Debug|Win32.Build.0 = Debug|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Win32.ActiveCfg = Release|Win32 + {042D3628-67F3-4B5C-8BC0-CD9AFA416974}.Release|Win32.Build.0 = Release|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Win32.ActiveCfg = Debug|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Debug|Win32.Build.0 = Debug|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Win32.ActiveCfg = Release|Win32 + {CAA5A551-006A-4119-8115-FB14692E719F}.Release|Win32.Build.0 = Release|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Win32.ActiveCfg = Debug|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Debug|Win32.Build.0 = Debug|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Win32.ActiveCfg = Release|Win32 + {9F0660BC-4582-4D4E-BA83-E2BE5F6BDD45}.Release|Win32.Build.0 = Release|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Win32.ActiveCfg = Debug|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Debug|Win32.Build.0 = Debug|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Win32.ActiveCfg = Release|Win32 + {FC8F1F56-078E-470D-B252-68EDDE88AA9D}.Release|Win32.Build.0 = Release|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Win32.ActiveCfg = Debug|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Debug|Win32.Build.0 = Debug|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Win32.ActiveCfg = Release|Win32 + {879E26B2-48DB-47B3-B82F-893696286E6F}.Release|Win32.Build.0 = Release|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Win32.ActiveCfg = Debug|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Debug|Win32.Build.0 = Debug|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Win32.ActiveCfg = Release|Win32 + {233014D5-F6E5-419D-8757-FA9CE7337088}.Release|Win32.Build.0 = Release|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Win32.ActiveCfg = Debug|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Debug|Win32.Build.0 = Debug|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Win32.ActiveCfg = Release|Win32 + {D3540754-E0CF-4604-AC11-82DE9BD4D814}.Release|Win32.Build.0 = Release|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Win32.ActiveCfg = Debug|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Debug|Win32.Build.0 = Debug|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Win32.ActiveCfg = Release|Win32 + {4AC7F65D-0DC0-49F9-8B96-AD05F11FF38E}.Release|Win32.Build.0 = Release|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Win32.ActiveCfg = Debug|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Debug|Win32.Build.0 = Debug|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Win32.ActiveCfg = Release|Win32 + {48E2C7C6-52EB-46FB-8722-00A62F46F497}.Release|Win32.Build.0 = Release|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.ActiveCfg = Debug|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Debug|Win32.Build.0 = Debug|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.ActiveCfg = Release|Win32 + {A35D99BF-D72D-4F56-99A1-97249B22BCE2}.Release|Win32.Build.0 = Release|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Win32.ActiveCfg = Debug|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Debug|Win32.Build.0 = Debug|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Win32.ActiveCfg = Release|Win32 + {B38E812D-9823-48E7-BE5F-BF09B0AD4165}.Release|Win32.Build.0 = Release|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Win32.ActiveCfg = Debug|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Debug|Win32.Build.0 = Debug|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Win32.ActiveCfg = Release|Win32 + {A86E6EF8-3683-4AD0-8878-7A0D51326088}.Release|Win32.Build.0 = Release|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Win32.ActiveCfg = Debug|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Debug|Win32.Build.0 = Debug|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Win32.ActiveCfg = Release|Win32 + {3B4108E4-C8FD-4D82-AF4A-F928CCF36A60}.Release|Win32.Build.0 = Release|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Win32.ActiveCfg = Debug|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Debug|Win32.Build.0 = Debug|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Win32.ActiveCfg = Release|Win32 + {A0288B75-0D95-4106-A3A7-779A891E8FEF}.Release|Win32.Build.0 = Release|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Win32.ActiveCfg = Debug|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Debug|Win32.Build.0 = Debug|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Win32.ActiveCfg = Release|Win32 + {8162BADA-2FB6-4A71-B998-ABAFAF28E5A8}.Release|Win32.Build.0 = Release|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Win32.ActiveCfg = Debug|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Debug|Win32.Build.0 = Debug|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Win32.ActiveCfg = Release|Win32 + {E2DBD151-9523-4E1A-9478-F3F825668F6E}.Release|Win32.Build.0 = Release|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Win32.ActiveCfg = Debug|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Debug|Win32.Build.0 = Debug|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Win32.ActiveCfg = Release|Win32 + {2B6AB6CD-E7D0-4706-BB4A-DDD7AE1A510D}.Release|Win32.Build.0 = Release|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Win32.ActiveCfg = Debug|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Debug|Win32.Build.0 = Debug|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Win32.ActiveCfg = Release|Win32 + {F346A9A7-CF8D-4409-8776-1D4244F96EF8}.Release|Win32.Build.0 = Release|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Win32.ActiveCfg = Debug|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Debug|Win32.Build.0 = Debug|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Win32.ActiveCfg = Release|Win32 + {71071F01-C813-4384-BE38-0F4020BCC0EE}.Release|Win32.Build.0 = Release|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Win32.ActiveCfg = Debug|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Debug|Win32.Build.0 = Debug|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Win32.ActiveCfg = Release|Win32 + {402A8794-B724-44A3-B608-84B600ECA387}.Release|Win32.Build.0 = Release|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Win32.ActiveCfg = Debug|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Debug|Win32.Build.0 = Debug|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Win32.ActiveCfg = Release|Win32 + {464697D2-BA44-446F-8223-1EB3969ED1A8}.Release|Win32.Build.0 = Release|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Win32.ActiveCfg = Debug|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Debug|Win32.Build.0 = Debug|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Win32.ActiveCfg = Release|Win32 + {01183543-B182-4E32-9FD6-FC15C847316C}.Release|Win32.Build.0 = Release|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Win32.ActiveCfg = Debug|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Debug|Win32.Build.0 = Debug|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Win32.ActiveCfg = Release|Win32 + {4258687D-4905-46A6-9407-08F4F8A81CC0}.Release|Win32.Build.0 = Release|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Win32.ActiveCfg = Debug|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Debug|Win32.Build.0 = Debug|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Win32.ActiveCfg = Release|Win32 + {E08DA5C2-9D97-4CD3-BB13-6FD6BA4458D6}.Release|Win32.Build.0 = Release|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Win32.ActiveCfg = Debug|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Debug|Win32.Build.0 = Debug|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Win32.ActiveCfg = Release|Win32 + {1DE72B1E-0DD6-4AFD-95E9-D23ACAB31812}.Release|Win32.Build.0 = Release|Win32 + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Debug|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {F9AF60FE-C2F2-4D94-9667-E4FCC6FAA466}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Debug|Win32.ActiveCfg = Debug|Pocket PC 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) + {CAA7EF3E-C7F4-4F8A-9E17-9A06DEF9E717}.Release|Win32.ActiveCfg = Release|Pocket PC 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Win32.ActiveCfg = Debug|Win32 + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Debug|Win32.Build.0 = Debug|Win32 + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Win32.ActiveCfg = Release|Win32 + {27F7FDF4-479B-47B5-BFEA-12E9EA41F663}.Release|Win32.Build.0 = Release|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Win32.ActiveCfg = Debug|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Debug|Win32.Build.0 = Debug|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Win32.ActiveCfg = Release|Win32 + {C993119B-29B1-49C8-8EA3-A9ABF633164E}.Release|Win32.Build.0 = Release|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Win32.ActiveCfg = Debug|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Debug|Win32.Build.0 = Debug|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Win32.ActiveCfg = Release|Win32 + {694C765F-DFD6-467E-A813-B3F887E822D4}.Release|Win32.Build.0 = Release|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Smartphone 2003 (ARMV4).Build.0 = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Smartphone 2003 (ARMV4).Deploy.0 = Debug|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Win32.ActiveCfg = Debug|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Debug|Win32.Build.0 = Debug|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Smartphone 2003 (ARMV4).Build.0 = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Smartphone 2003 (ARMV4).Deploy.0 = Release|Smartphone 2003 (ARMV4) + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Win32.ActiveCfg = Release|Win32 + {07D6FB42-0F4F-487A-BCBA-EC4BBF5CB160}.Release|Win32.Build.0 = Release|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Smartphone 2003 (ARMV4).ActiveCfg = Debug|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Win32.ActiveCfg = Debug|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Debug|Win32.Build.0 = Debug|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Smartphone 2003 (ARMV4).ActiveCfg = Release|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Win32.ActiveCfg = Release|Win32 + {073E2281-4FDE-4C4D-A217-C489DB17C48C}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/build/msvc9/gpac_js.vcproj b/build/msvc9/gpac_js.vcproj new file mode 100644 index 0000000..7462a48 --- /dev/null +++ b/build/msvc9/gpac_js.vcproj @@ -0,0 +1,471 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/img_in.vcproj b/build/msvc9/img_in.vcproj new file mode 100644 index 0000000..212b393 --- /dev/null +++ b/build/msvc9/img_in.vcproj @@ -0,0 +1,635 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/ismacryp.vcproj b/build/msvc9/ismacryp.vcproj new file mode 100644 index 0000000..48b287c --- /dev/null +++ b/build/msvc9/ismacryp.vcproj @@ -0,0 +1,461 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/isom_in.vcproj b/build/msvc9/isom_in.vcproj new file mode 100644 index 0000000..d481ef9 --- /dev/null +++ b/build/msvc9/isom_in.vcproj @@ -0,0 +1,587 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/laser_dec.vcproj b/build/msvc9/laser_dec.vcproj new file mode 100644 index 0000000..09b65e2 --- /dev/null +++ b/build/msvc9/laser_dec.vcproj @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/libgpac.vcproj b/build/msvc9/libgpac.vcproj new file mode 100644 index 0000000..233676f --- /dev/null +++ b/build/msvc9/libgpac.vcproj @@ -0,0 +1,7131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/libgpac_dll.vcproj b/build/msvc9/libgpac_dll.vcproj new file mode 100644 index 0000000..b1843b9 --- /dev/null +++ b/build/msvc9/libgpac_dll.vcproj @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/mp3_in.vcproj b/build/msvc9/mp3_in.vcproj new file mode 100644 index 0000000..c675ac6 --- /dev/null +++ b/build/msvc9/mp3_in.vcproj @@ -0,0 +1,507 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/mp4box.vcproj b/build/msvc9/mp4box.vcproj new file mode 100644 index 0000000..085572b --- /dev/null +++ b/build/msvc9/mp4box.vcproj @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/mp4client.vcproj b/build/msvc9/mp4client.vcproj new file mode 100644 index 0000000..3543660 --- /dev/null +++ b/build/msvc9/mp4client.vcproj @@ -0,0 +1,483 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/mpegts_in.vcproj b/build/msvc9/mpegts_in.vcproj new file mode 100644 index 0000000..0003d8c --- /dev/null +++ b/build/msvc9/mpegts_in.vcproj @@ -0,0 +1,461 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/odf_dec.vcproj b/build/msvc9/odf_dec.vcproj new file mode 100644 index 0000000..0ed0e70 --- /dev/null +++ b/build/msvc9/odf_dec.vcproj @@ -0,0 +1,460 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/ogg.vcproj b/build/msvc9/ogg.vcproj new file mode 100644 index 0000000..36df595 --- /dev/null +++ b/build/msvc9/ogg.vcproj @@ -0,0 +1,591 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/opencv_is.vcproj b/build/msvc9/opencv_is.vcproj new file mode 100644 index 0000000..b2c0642 --- /dev/null +++ b/build/msvc9/opencv_is.vcproj @@ -0,0 +1,577 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/osmophone.vcproj b/build/msvc9/osmophone.vcproj new file mode 100644 index 0000000..b4a6780 --- /dev/null +++ b/build/msvc9/osmophone.vcproj @@ -0,0 +1,595 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/osmozilla.vcproj b/build/msvc9/osmozilla.vcproj new file mode 100644 index 0000000..0010628 --- /dev/null +++ b/build/msvc9/osmozilla.vcproj @@ -0,0 +1,657 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/platinum.vcproj b/build/msvc9/platinum.vcproj new file mode 100644 index 0000000..c1c4a05 --- /dev/null +++ b/build/msvc9/platinum.vcproj @@ -0,0 +1,474 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/raw_out.vcproj b/build/msvc9/raw_out.vcproj new file mode 100644 index 0000000..1a43d23 --- /dev/null +++ b/build/msvc9/raw_out.vcproj @@ -0,0 +1,461 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/redirect_av.vcproj b/build/msvc9/redirect_av.vcproj new file mode 100644 index 0000000..6c543f1 --- /dev/null +++ b/build/msvc9/redirect_av.vcproj @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/rtp_in.vcproj b/build/msvc9/rtp_in.vcproj new file mode 100644 index 0000000..1305c92 --- /dev/null +++ b/build/msvc9/rtp_in.vcproj @@ -0,0 +1,665 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/saf_in.vcproj b/build/msvc9/saf_in.vcproj new file mode 100644 index 0000000..6cec8ed --- /dev/null +++ b/build/msvc9/saf_in.vcproj @@ -0,0 +1,466 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/sdl_out.vcproj b/build/msvc9/sdl_out.vcproj new file mode 100644 index 0000000..5c814bf --- /dev/null +++ b/build/msvc9/sdl_out.vcproj @@ -0,0 +1,589 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/soft_raster.vcproj b/build/msvc9/soft_raster.vcproj new file mode 100644 index 0000000..6ed438e --- /dev/null +++ b/build/msvc9/soft_raster.vcproj @@ -0,0 +1,703 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/svg_in.vcproj b/build/msvc9/svg_in.vcproj new file mode 100644 index 0000000..826c9e2 --- /dev/null +++ b/build/msvc9/svg_in.vcproj @@ -0,0 +1,467 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/timedtext.vcproj b/build/msvc9/timedtext.vcproj new file mode 100644 index 0000000..fc4cc4e --- /dev/null +++ b/build/msvc9/timedtext.vcproj @@ -0,0 +1,501 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/ui_rec.vcproj b/build/msvc9/ui_rec.vcproj new file mode 100644 index 0000000..d28f1ea --- /dev/null +++ b/build/msvc9/ui_rec.vcproj @@ -0,0 +1,576 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/wav_out.vcproj b/build/msvc9/wav_out.vcproj new file mode 100644 index 0000000..dc1d5e5 --- /dev/null +++ b/build/msvc9/wav_out.vcproj @@ -0,0 +1,463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/widgetman.vcproj b/build/msvc9/widgetman.vcproj new file mode 100644 index 0000000..4034d69 --- /dev/null +++ b/build/msvc9/widgetman.vcproj @@ -0,0 +1,456 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/wiiis.vcproj b/build/msvc9/wiiis.vcproj new file mode 100644 index 0000000..b6c0193 --- /dev/null +++ b/build/msvc9/wiiis.vcproj @@ -0,0 +1,578 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/wxOsmo4.vcproj b/build/msvc9/wxOsmo4.vcproj new file mode 100644 index 0000000..dbe64f2 --- /dev/null +++ b/build/msvc9/wxOsmo4.vcproj @@ -0,0 +1,388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/msvc9/xvid_dec.vcproj b/build/msvc9/xvid_dec.vcproj new file mode 100644 index 0000000..220d672 --- /dev/null +++ b/build/msvc9/xvid_dec.vcproj @@ -0,0 +1,1246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/symbian/libgpac.mmp b/build/symbian/libgpac.mmp index 64c9af2..3e6e881 100644 --- a/build/symbian/libgpac.mmp +++ b/build/symbian/libgpac.mmp @@ -228,18 +228,19 @@ SOURCE channel.c SOURCE clock.c SOURCE decoder.c SOURCE term_node_init.c -SOURCE inline.c SOURCE input_sensor.c SOURCE media_control.c SOURCE media_manager.c SOURCE media_memory.c SOURCE media_object.c SOURCE media_sensor.c +SOURCE mpeg4_inline.c SOURCE network_service.c SOURCE object_browser.c SOURCE object_manager.c -SOURCE terminal.c +SOURCE scene.c SOURCE svg_external.c +SOURCE terminal.c //compositor SOURCEPATH ..\..\src\compositor diff --git a/build/symbian/libgpac_symbianU.def b/build/symbian/libgpac_symbianU.def index 3bd8506..2f8769b 100644 --- a/build/symbian/libgpac_symbianU.def +++ b/build/symbian/libgpac_symbianU.def @@ -151,13 +151,13 @@ EXPORTS gf_inline_default_scene_viewpoint @ 150 NONAME gf_inline_disconnect @ 151 NONAME gf_inline_find_odm @ 152 NONAME - gf_inline_force_scene_size @ 153 NONAME + gf_scene_force_size @ 153 NONAME gf_inline_get_proto_lib @ 154 NONAME - gf_inline_get_time @ 155 NONAME - gf_inline_process_anchor @ 156 NONAME - gf_inline_register_extra_graph @ 157 NONAME - gf_inline_set_duration @ 158 NONAME - gf_inline_setup_object @ 159 NONAME + gf_scene_get_time @ 155 NONAME + gf_scene_process_anchor @ 156 NONAME + gf_scene_register_extra_graph @ 157 NONAME + gf_scene_set_duration @ 158 NONAME + gf_scene_setup_object @ 159 NONAME gf_invfix @ 160 NONAME gf_ismacryp_crypt_file @ 161 NONAME gf_ismacryp_decrypt_file @ 162 NONAME diff --git a/build/xcode/gpac.xcodeproj/project.pbxproj b/build/xcode/gpac.xcodeproj/project.pbxproj new file mode 100644 index 0000000..fd6a492 --- /dev/null +++ b/build/xcode/gpac.xcodeproj/project.pbxproj @@ -0,0 +1,517 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXAggregateTarget section */ + 717BB3A71152558600A39D3D /* modules */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 717BB3B0115255B900A39D3D /* Build configuration list for PBXAggregateTarget "modules" */; + buildPhases = ( + ); + dependencies = ( + ); + name = modules; + productName = modules; + }; + 717BB66C11525AA200A39D3D /* all */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 717BB67511525AD100A39D3D /* Build configuration list for PBXAggregateTarget "all" */; + buildPhases = ( + ); + dependencies = ( + 71D7E31411577931003DF497 /* PBXTargetDependency */, + 71D7E30811525E2E003DF497 /* PBXTargetDependency */, + 717BB67011525AAA00A39D3D /* PBXTargetDependency */, + 717BB67411525AB200A39D3D /* PBXTargetDependency */, + ); + name = all; + productName = all; + }; + 71D7E310115778E1003DF497 /* configure */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 71D7E312115778FF003DF497 /* Build configuration list for PBXAggregateTarget "configure" */; + buildPhases = ( + ); + dependencies = ( + ); + name = configure; + productName = configure; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXContainerItemProxy section */ + 717BB66F11525AAA00A39D3D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 717BAE39115238D100A39D3D; + remoteInfo = libgpac; + }; + 717BB67311525AB200A39D3D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 717BB3A71152558600A39D3D; + remoteInfo = modules; + }; + 71D7E30711525E2E003DF497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 71D7E30411525E11003DF497; + remoteInfo = applications; + }; + 71D7E31311577931003DF497 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 71D7E310115778E1003DF497; + remoteInfo = configure; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 717BB27B1152533800A39D3D /* bifs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = bifs; path = ../../src/bifs; sourceTree = SOURCE_ROOT; }; + 717BB27C1152533800A39D3D /* compositor */ = {isa = PBXFileReference; lastKnownFileType = folder; name = compositor; path = ../../src/compositor; sourceTree = SOURCE_ROOT; }; + 717BB2831152533800A39D3D /* dir_info */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = dir_info; path = ../../src/dir_info; sourceTree = SOURCE_ROOT; }; + 717BB2841152533800A39D3D /* export.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = export.cpp; path = ../../src/export.cpp; sourceTree = SOURCE_ROOT; }; + 717BB2851152533800A39D3D /* ietf */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ietf; path = ../../src/ietf; sourceTree = SOURCE_ROOT; }; + 717BB2861152533800A39D3D /* isomedia */ = {isa = PBXFileReference; lastKnownFileType = folder; name = isomedia; path = ../../src/isomedia; sourceTree = SOURCE_ROOT; }; + 717BB2871152533800A39D3D /* laser */ = {isa = PBXFileReference; lastKnownFileType = folder; name = laser; path = ../../src/laser; sourceTree = SOURCE_ROOT; }; + 717BB2881152533800A39D3D /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../../src/Makefile; sourceTree = SOURCE_ROOT; }; + 717BB2891152533800A39D3D /* mcrypt */ = {isa = PBXFileReference; lastKnownFileType = folder; name = mcrypt; path = ../../src/mcrypt; sourceTree = SOURCE_ROOT; }; + 717BB28A1152533800A39D3D /* media_tools */ = {isa = PBXFileReference; lastKnownFileType = folder; name = media_tools; path = ../../src/media_tools; sourceTree = SOURCE_ROOT; }; + 717BB28B1152533800A39D3D /* odf */ = {isa = PBXFileReference; lastKnownFileType = folder; name = odf; path = ../../src/odf; sourceTree = SOURCE_ROOT; }; + 717BB28C1152533800A39D3D /* scene_manager */ = {isa = PBXFileReference; lastKnownFileType = folder; name = scene_manager; path = ../../src/scene_manager; sourceTree = SOURCE_ROOT; }; + 717BB28D1152533800A39D3D /* scenegraph */ = {isa = PBXFileReference; lastKnownFileType = folder; name = scenegraph; path = ../../src/scenegraph; sourceTree = SOURCE_ROOT; }; + 717BB28E1152533800A39D3D /* terminal */ = {isa = PBXFileReference; lastKnownFileType = folder; name = terminal; path = ../../src/terminal; sourceTree = SOURCE_ROOT; }; + 717BB28F1152533800A39D3D /* utils */ = {isa = PBXFileReference; lastKnownFileType = folder; name = utils; path = ../../src/utils; sourceTree = SOURCE_ROOT; }; + 717BB3B3115256CD00A39D3D /* aac_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = aac_in; path = ../../modules/aac_in; sourceTree = SOURCE_ROOT; }; + 717BB3B8115256CD00A39D3D /* ac3_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ac3_in; path = ../../modules/ac3_in; sourceTree = SOURCE_ROOT; }; + 717BB3BD115256CD00A39D3D /* alsa */ = {isa = PBXFileReference; lastKnownFileType = folder; name = alsa; path = ../../modules/alsa; sourceTree = SOURCE_ROOT; }; + 717BB3C1115256CD00A39D3D /* amr_dec */ = {isa = PBXFileReference; lastKnownFileType = folder; name = amr_dec; path = ../../modules/amr_dec; sourceTree = SOURCE_ROOT; }; + 717BB3C9115256CD00A39D3D /* amr_float_dec */ = {isa = PBXFileReference; lastKnownFileType = folder; name = amr_float_dec; path = ../../modules/amr_float_dec; sourceTree = SOURCE_ROOT; }; + 717BB3D3115256CD00A39D3D /* audio_filter */ = {isa = PBXFileReference; lastKnownFileType = folder; name = audio_filter; path = ../../modules/audio_filter; sourceTree = SOURCE_ROOT; }; + 717BB3D7115256CD00A39D3D /* bifs_dec */ = {isa = PBXFileReference; lastKnownFileType = folder; name = bifs_dec; path = ../../modules/bifs_dec; sourceTree = SOURCE_ROOT; }; + 717BB3DB115256CD00A39D3D /* ctx_load */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ctx_load; path = ../../modules/ctx_load; sourceTree = SOURCE_ROOT; }; + 717BB3E5115256CD00A39D3D /* demo_is */ = {isa = PBXFileReference; lastKnownFileType = folder; name = demo_is; path = ../../modules/demo_is; sourceTree = SOURCE_ROOT; }; + 717BB3EA115256CD00A39D3D /* dummy_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dummy_in; path = ../../modules/dummy_in; sourceTree = SOURCE_ROOT; }; + 717BB3EE115256CD00A39D3D /* dx_hw */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dx_hw; path = ../../modules/dx_hw; sourceTree = SOURCE_ROOT; }; + 717BB3FB115256CD00A39D3D /* epoc_hw */ = {isa = PBXFileReference; lastKnownFileType = folder; name = epoc_hw; path = ../../modules/epoc_hw; sourceTree = SOURCE_ROOT; }; + 717BB400115256CD00A39D3D /* ffmpeg_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ffmpeg_in; path = ../../modules/ffmpeg_in; sourceTree = SOURCE_ROOT; }; + 717BB407115256CD00A39D3D /* ft_font */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ft_font; path = ../../modules/ft_font; sourceTree = SOURCE_ROOT; }; + 717BB40C115256CD00A39D3D /* gapi */ = {isa = PBXFileReference; lastKnownFileType = folder; name = gapi; path = ../../modules/gapi; sourceTree = SOURCE_ROOT; }; + 717BB410115256CD00A39D3D /* gdip_raster */ = {isa = PBXFileReference; lastKnownFileType = folder; name = gdip_raster; path = ../../modules/gdip_raster; sourceTree = SOURCE_ROOT; }; + 717BB417115256CD00A39D3D /* gpac_js */ = {isa = PBXFileReference; lastKnownFileType = folder; name = gpac_js; path = ../../modules/gpac_js; sourceTree = SOURCE_ROOT; }; + 717BB41B115256CD00A39D3D /* img_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = img_in; path = ../../modules/img_in; sourceTree = SOURCE_ROOT; }; + 717BB425115256CD00A39D3D /* ismacryp */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ismacryp; path = ../../modules/ismacryp; sourceTree = SOURCE_ROOT; }; + 717BB429115256CD00A39D3D /* isom_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = isom_in; path = ../../modules/isom_in; sourceTree = SOURCE_ROOT; }; + 717BB431115256CD00A39D3D /* jack */ = {isa = PBXFileReference; lastKnownFileType = folder; name = jack; path = ../../modules/jack; sourceTree = SOURCE_ROOT; }; + 717BB435115256CD00A39D3D /* laser_dec */ = {isa = PBXFileReference; lastKnownFileType = folder; name = laser_dec; path = ../../modules/laser_dec; sourceTree = SOURCE_ROOT; }; + 717BB439115256CD00A39D3D /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../../modules/Makefile; sourceTree = SOURCE_ROOT; }; + 717BB43A115256CD00A39D3D /* modules_export.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = modules_export.cpp; path = ../../modules/modules_export.cpp; sourceTree = SOURCE_ROOT; }; + 717BB43B115256CD00A39D3D /* mp3_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = mp3_in; path = ../../modules/mp3_in; sourceTree = SOURCE_ROOT; }; + 717BB440115256CD00A39D3D /* mpegts_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = mpegts_in; path = ../../modules/mpegts_in; sourceTree = SOURCE_ROOT; }; + 717BB444115256CD00A39D3D /* odf_dec */ = {isa = PBXFileReference; lastKnownFileType = folder; name = odf_dec; path = ../../modules/odf_dec; sourceTree = SOURCE_ROOT; }; + 717BB448115256CD00A39D3D /* ogg */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ogg; path = ../../modules/ogg; sourceTree = SOURCE_ROOT; }; + 717BB450115256CD00A39D3D /* opencv_is */ = {isa = PBXFileReference; lastKnownFileType = folder; name = opencv_is; path = ../../modules/opencv_is; sourceTree = SOURCE_ROOT; }; + 717BB456115256CD00A39D3D /* oss_audio */ = {isa = PBXFileReference; lastKnownFileType = folder; name = oss_audio; path = ../../modules/oss_audio; sourceTree = SOURCE_ROOT; }; + 717BB45A115256CD00A39D3D /* pulseaudio */ = {isa = PBXFileReference; lastKnownFileType = folder; name = pulseaudio; path = ../../modules/pulseaudio; sourceTree = SOURCE_ROOT; }; + 717BB45E115256CD00A39D3D /* raw_out */ = {isa = PBXFileReference; lastKnownFileType = folder; name = raw_out; path = ../../modules/raw_out; sourceTree = SOURCE_ROOT; }; + 717BB462115256CD00A39D3D /* rtp_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = rtp_in; path = ../../modules/rtp_in; sourceTree = SOURCE_ROOT; }; + 717BB46C115256CD00A39D3D /* saf_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = saf_in; path = ../../modules/saf_in; sourceTree = SOURCE_ROOT; }; + 717BB470115256CD00A39D3D /* sdl_out */ = {isa = PBXFileReference; lastKnownFileType = folder; name = sdl_out; path = ../../modules/sdl_out; sourceTree = SOURCE_ROOT; }; + 717BB479115256CD00A39D3D /* soft_raster */ = {isa = PBXFileReference; lastKnownFileType = folder; name = soft_raster; path = ../../modules/soft_raster; sourceTree = SOURCE_ROOT; }; + 717BB484115256CD00A39D3D /* svg_in */ = {isa = PBXFileReference; lastKnownFileType = folder; name = svg_in; path = ../../modules/svg_in; sourceTree = SOURCE_ROOT; }; + 717BB488115256CD00A39D3D /* timedtext */ = {isa = PBXFileReference; lastKnownFileType = folder; name = timedtext; path = ../../modules/timedtext; sourceTree = SOURCE_ROOT; }; + 717BB48D115256CD00A39D3D /* ui_rec */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ui_rec; path = ../../modules/ui_rec; sourceTree = SOURCE_ROOT; }; + 717BB492115256CD00A39D3D /* wav_out */ = {isa = PBXFileReference; lastKnownFileType = folder; name = wav_out; path = ../../modules/wav_out; sourceTree = SOURCE_ROOT; }; + 717BB496115256CD00A39D3D /* wiiis */ = {isa = PBXFileReference; lastKnownFileType = folder; name = wiiis; path = ../../modules/wiiis; sourceTree = SOURCE_ROOT; }; + 717BB49B115256CD00A39D3D /* x11_out */ = {isa = PBXFileReference; lastKnownFileType = folder; name = x11_out; path = ../../modules/x11_out; sourceTree = SOURCE_ROOT; }; + 717BB4A0115256CD00A39D3D /* xvid_dec */ = {isa = PBXFileReference; lastKnownFileType = folder; name = xvid_dec; path = ../../modules/xvid_dec; sourceTree = SOURCE_ROOT; }; + 717BB4DA115259C000A39D3D /* generators */ = {isa = PBXFileReference; lastKnownFileType = folder; name = generators; path = ../../applications/generators; sourceTree = SOURCE_ROOT; }; + 717BB527115259C000A39D3D /* GPAX */ = {isa = PBXFileReference; lastKnownFileType = folder; name = GPAX; path = ../../applications/GPAX; sourceTree = SOURCE_ROOT; }; + 717BB53B115259C000A39D3D /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = ../../applications/Makefile; sourceTree = SOURCE_ROOT; }; + 717BB53C115259C000A39D3D /* mp4box */ = {isa = PBXFileReference; lastKnownFileType = folder; name = mp4box; path = ../../applications/mp4box; sourceTree = SOURCE_ROOT; }; + 717BB543115259C000A39D3D /* mp4client */ = {isa = PBXFileReference; lastKnownFileType = folder; name = mp4client; path = ../../applications/mp4client; sourceTree = SOURCE_ROOT; }; + 717BB548115259C000A39D3D /* mp42avi */ = {isa = PBXFileReference; lastKnownFileType = folder; name = mp42avi; path = ../../applications/mp42avi; sourceTree = SOURCE_ROOT; }; + 717BB54C115259C000A39D3D /* osmo4_sym */ = {isa = PBXFileReference; lastKnownFileType = folder; name = osmo4_sym; path = ../../applications/osmo4_sym; sourceTree = SOURCE_ROOT; }; + 717BB564115259C000A39D3D /* osmo4_w32 */ = {isa = PBXFileReference; lastKnownFileType = folder; name = osmo4_w32; path = ../../applications/osmo4_w32; sourceTree = SOURCE_ROOT; }; + 717BB585115259C000A39D3D /* osmo4_wce */ = {isa = PBXFileReference; lastKnownFileType = folder; name = osmo4_wce; path = ../../applications/osmo4_wce; sourceTree = SOURCE_ROOT; }; + 717BB59B115259C000A39D3D /* osmo4_wx */ = {isa = PBXFileReference; lastKnownFileType = folder; name = osmo4_wx; path = ../../applications/osmo4_wx; sourceTree = SOURCE_ROOT; }; + 717BB5B1115259C000A39D3D /* osmophone */ = {isa = PBXFileReference; lastKnownFileType = folder; name = osmophone; path = ../../applications/osmophone; sourceTree = SOURCE_ROOT; }; + 717BB5B9115259C000A39D3D /* osmozilla */ = {isa = PBXFileReference; lastKnownFileType = folder; name = osmozilla; path = ../../applications/osmozilla; sourceTree = SOURCE_ROOT; }; + 717BB5CB115259C000A39D3D /* testapps */ = {isa = PBXFileReference; lastKnownFileType = folder; name = testapps; path = ../../applications/testapps; sourceTree = SOURCE_ROOT; }; + 717BB60F115259C000A39D3D /* v4studio */ = {isa = PBXFileReference; lastKnownFileType = folder; name = v4studio; path = ../../applications/v4studio; sourceTree = SOURCE_ROOT; }; +/* End PBXFileReference section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* gpac */ = { + isa = PBXGroup; + children = ( + 717BB4D9115259A000A39D3D /* applications */, + 717BB3B2115256A600A39D3D /* modules */, + 717BB27A1152530E00A39D3D /* libgpac */, + ); + name = gpac; + sourceTree = ""; + }; + 717BB27A1152530E00A39D3D /* libgpac */ = { + isa = PBXGroup; + children = ( + 717BB27B1152533800A39D3D /* bifs */, + 717BB27C1152533800A39D3D /* compositor */, + 717BB2831152533800A39D3D /* dir_info */, + 717BB2841152533800A39D3D /* export.cpp */, + 717BB2851152533800A39D3D /* ietf */, + 717BB2861152533800A39D3D /* isomedia */, + 717BB2871152533800A39D3D /* laser */, + 717BB2881152533800A39D3D /* Makefile */, + 717BB2891152533800A39D3D /* mcrypt */, + 717BB28A1152533800A39D3D /* media_tools */, + 717BB28B1152533800A39D3D /* odf */, + 717BB28C1152533800A39D3D /* scene_manager */, + 717BB28D1152533800A39D3D /* scenegraph */, + 717BB28E1152533800A39D3D /* terminal */, + 717BB28F1152533800A39D3D /* utils */, + ); + name = libgpac; + sourceTree = ""; + }; + 717BB3B2115256A600A39D3D /* modules */ = { + isa = PBXGroup; + children = ( + 717BB3B3115256CD00A39D3D /* aac_in */, + 717BB3B8115256CD00A39D3D /* ac3_in */, + 717BB3BD115256CD00A39D3D /* alsa */, + 717BB3C1115256CD00A39D3D /* amr_dec */, + 717BB3C9115256CD00A39D3D /* amr_float_dec */, + 717BB3D3115256CD00A39D3D /* audio_filter */, + 717BB3D7115256CD00A39D3D /* bifs_dec */, + 717BB3DB115256CD00A39D3D /* ctx_load */, + 717BB3E5115256CD00A39D3D /* demo_is */, + 717BB3EA115256CD00A39D3D /* dummy_in */, + 717BB3EE115256CD00A39D3D /* dx_hw */, + 717BB3FB115256CD00A39D3D /* epoc_hw */, + 717BB400115256CD00A39D3D /* ffmpeg_in */, + 717BB407115256CD00A39D3D /* ft_font */, + 717BB40C115256CD00A39D3D /* gapi */, + 717BB410115256CD00A39D3D /* gdip_raster */, + 717BB417115256CD00A39D3D /* gpac_js */, + 717BB41B115256CD00A39D3D /* img_in */, + 717BB425115256CD00A39D3D /* ismacryp */, + 717BB429115256CD00A39D3D /* isom_in */, + 717BB431115256CD00A39D3D /* jack */, + 717BB435115256CD00A39D3D /* laser_dec */, + 717BB439115256CD00A39D3D /* Makefile */, + 717BB43A115256CD00A39D3D /* modules_export.cpp */, + 717BB43B115256CD00A39D3D /* mp3_in */, + 717BB440115256CD00A39D3D /* mpegts_in */, + 717BB444115256CD00A39D3D /* odf_dec */, + 717BB448115256CD00A39D3D /* ogg */, + 717BB450115256CD00A39D3D /* opencv_is */, + 717BB456115256CD00A39D3D /* oss_audio */, + 717BB45A115256CD00A39D3D /* pulseaudio */, + 717BB45E115256CD00A39D3D /* raw_out */, + 717BB462115256CD00A39D3D /* rtp_in */, + 717BB46C115256CD00A39D3D /* saf_in */, + 717BB470115256CD00A39D3D /* sdl_out */, + 717BB479115256CD00A39D3D /* soft_raster */, + 717BB484115256CD00A39D3D /* svg_in */, + 717BB488115256CD00A39D3D /* timedtext */, + 717BB48D115256CD00A39D3D /* ui_rec */, + 717BB492115256CD00A39D3D /* wav_out */, + 717BB496115256CD00A39D3D /* wiiis */, + 717BB49B115256CD00A39D3D /* x11_out */, + 717BB4A0115256CD00A39D3D /* xvid_dec */, + ); + name = modules; + sourceTree = ""; + }; + 717BB4D9115259A000A39D3D /* applications */ = { + isa = PBXGroup; + children = ( + 717BB4DA115259C000A39D3D /* generators */, + 717BB527115259C000A39D3D /* GPAX */, + 717BB53B115259C000A39D3D /* Makefile */, + 717BB53C115259C000A39D3D /* mp4box */, + 717BB543115259C000A39D3D /* mp4client */, + 717BB548115259C000A39D3D /* mp42avi */, + 717BB54C115259C000A39D3D /* osmo4_sym */, + 717BB564115259C000A39D3D /* osmo4_w32 */, + 717BB585115259C000A39D3D /* osmo4_wce */, + 717BB59B115259C000A39D3D /* osmo4_wx */, + 717BB5B1115259C000A39D3D /* osmophone */, + 717BB5B9115259C000A39D3D /* osmozilla */, + 717BB5CB115259C000A39D3D /* testapps */, + 717BB60F115259C000A39D3D /* v4studio */, + ); + name = applications; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + 717BAE39115238D100A39D3D /* libgpac */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = 717BAE3E115238D800A39D3D /* Build configuration list for PBXLegacyTarget "libgpac" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + buildWorkingDirectory = $SOURCE_ROOT/../../src; + dependencies = ( + ); + name = libgpac; + passBuildSettingsInEnvironment = 1; + productName = libgpac; + }; + 717BB4D11152588A00A39D3D /* MP4Client */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = 717BB4D6115258CE00A39D3D /* Build configuration list for PBXLegacyTarget "MP4Client" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + buildWorkingDirectory = $SOURCE_ROOT/../../applications/mp4client; + dependencies = ( + ); + name = MP4Client; + passBuildSettingsInEnvironment = 1; + productName = MP4Client; + }; + 717BB66611525A4D00A39D3D /* MP4Box */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = 717BB66B11525A8700A39D3D /* Build configuration list for PBXLegacyTarget "MP4Box" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + buildWorkingDirectory = $SOURCE_ROOT/../../applications/mp4box; + dependencies = ( + ); + name = MP4Box; + passBuildSettingsInEnvironment = 1; + productName = MP4Box; + }; + 71D7E30411525E11003DF497 /* applications */ = { + isa = PBXLegacyTarget; + buildArgumentsString = configure; + buildConfigurationList = 71D7E30911525E4C003DF497 /* Build configuration list for PBXLegacyTarget "applications" */; + buildPhases = ( + ); + buildToolPath = /bin/bash; + buildWorkingDirectory = $SOURCE_ROOT/../../; + dependencies = ( + ); + name = applications; + passBuildSettingsInEnvironment = 1; + productName = applications; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "gpac" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 08FB7794FE84155DC02AAC07 /* gpac */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 717BB66C11525AA200A39D3D /* all */, + 71D7E310115778E1003DF497 /* configure */, + 71D7E30411525E11003DF497 /* applications */, + 717BAE39115238D100A39D3D /* libgpac */, + 717BB3A71152558600A39D3D /* modules */, + 717BB4D11152588A00A39D3D /* MP4Client */, + 717BB66611525A4D00A39D3D /* MP4Box */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXTargetDependency section */ + 717BB67011525AAA00A39D3D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 717BAE39115238D100A39D3D /* libgpac */; + targetProxy = 717BB66F11525AAA00A39D3D /* PBXContainerItemProxy */; + }; + 717BB67411525AB200A39D3D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 717BB3A71152558600A39D3D /* modules */; + targetProxy = 717BB67311525AB200A39D3D /* PBXContainerItemProxy */; + }; + 71D7E30811525E2E003DF497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 71D7E30411525E11003DF497 /* applications */; + targetProxy = 71D7E30711525E2E003DF497 /* PBXContainerItemProxy */; + }; + 71D7E31411577931003DF497 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 71D7E310115778E1003DF497 /* configure */; + targetProxy = 71D7E31311577931003DF497 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1DEB928B08733DD80010E9CD /* Makefile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.5; + }; + name = Makefile; + }; + 717BAE3B115238D100A39D3D /* Makefile */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = libgpac; + ZERO_LINK = NO; + }; + name = Makefile; + }; + 717BB3A91152558600A39D3D /* Makefile */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = modules; + ZERO_LINK = NO; + }; + name = Makefile; + }; + 717BB4D31152588A00A39D3D /* Makefile */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = MP4Client; + ZERO_LINK = NO; + }; + name = Makefile; + }; + 717BB66811525A4D00A39D3D /* Makefile */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = MP4Box; + ZERO_LINK = NO; + }; + name = Makefile; + }; + 717BB66E11525AA200A39D3D /* Makefile */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = all; + ZERO_LINK = NO; + }; + name = Makefile; + }; + 71D7E30611525E12003DF497 /* Makefile */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + PRODUCT_NAME = applications; + ZERO_LINK = NO; + }; + name = Makefile; + }; + 71D7E311115778E1003DF497 /* Makefile */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = configure; + }; + name = Makefile; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "gpac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB928B08733DD80010E9CD /* Makefile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Makefile; + }; + 717BAE3E115238D800A39D3D /* Build configuration list for PBXLegacyTarget "libgpac" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 717BAE3B115238D100A39D3D /* Makefile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Makefile; + }; + 717BB3B0115255B900A39D3D /* Build configuration list for PBXAggregateTarget "modules" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 717BB3A91152558600A39D3D /* Makefile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Makefile; + }; + 717BB4D6115258CE00A39D3D /* Build configuration list for PBXLegacyTarget "MP4Client" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 717BB4D31152588A00A39D3D /* Makefile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Makefile; + }; + 717BB66B11525A8700A39D3D /* Build configuration list for PBXLegacyTarget "MP4Box" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 717BB66811525A4D00A39D3D /* Makefile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Makefile; + }; + 717BB67511525AD100A39D3D /* Build configuration list for PBXAggregateTarget "all" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 717BB66E11525AA200A39D3D /* Makefile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Makefile; + }; + 71D7E30911525E4C003DF497 /* Build configuration list for PBXLegacyTarget "applications" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 71D7E30611525E12003DF497 /* Makefile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Makefile; + }; + 71D7E312115778FF003DF497 /* Build configuration list for PBXAggregateTarget "configure" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 71D7E311115778E1003DF497 /* Makefile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Makefile; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/config.h b/config.h deleted file mode 100644 index 6fc2775..0000000 --- a/config.h +++ /dev/null @@ -1,9 +0,0 @@ -/* Automatically generated by configure */ -#ifndef GF_CONFIG_H -#define GF_CONFIG_H -#define GPAC_CONFIG_LINUX -#define GPAC_HAS_SPIDERMONKEY -#define GPAC_HAS_JPEG -#define GPAC_HAS_PNG -#define GPAC_HAS_IPV6 -#endif diff --git a/configure b/configure index 3dce906..0417295 100755 --- a/configure +++ b/configure @@ -12,6 +12,15 @@ else TMPDIR1="/tmp" fi +#thanks to ffmpeg for this +for v in "$@"; do + r="${v#*=}" + l="${v%$r}" + test "$r" = "${r#* }" || r="'$r'" + GPAC_CONFIGURATION="${GPAC_CONFIGURATION# } ${l}${r}" +done + + TMPC="${TMPDIR1}/gpac-conf-${RANDOM}-$$-${RANDOM}.c" TMPH="${TMPDIR1}/gpac-conf-${RANDOM}-$$-${RANDOM}.h" TMPCPP="${TMPDIR1}/gpac-conf-${RANDOM}-$$-${RANDOM}.cpp" @@ -28,10 +37,14 @@ dxsdk_path="" moz_path="local" cc_orig="gcc" cc="${cc_orig}" +cpp_orig="g++" +cpp="${cpp_orig}" ar="ar" ranlib="ranlib" make="make" strip="strip" +install="${INSTALL:=install}" +instflags="${INSTFLAGS:=-p}" cpu=`uname -m` debuginfo="no" sdl_path="" @@ -44,8 +57,6 @@ libdir="lib" #GPAC module config js_flags="XP_UNIX" js_lib="-ljs" -iso_fragments="yes" -make_readonly="no" has_mingw_directx="no" has_js="no" has_ft="no" @@ -69,12 +80,11 @@ has_jack="no" has_x11="no" has_x11_shm="no" has_x11_xv="no" -disable_svg="no" no_gcc_opt="no" use_fixed_point="no" use_memory_tracking="no" +use_std_alloc="no" has_opengl="no" -disable_opengl="no" has_tinygl="no" enable_tinygl="no" has_ssl="no" @@ -82,12 +92,48 @@ has_ipv6="no" has_dvb4linux="no" has_xmlrpc="no" has_openjpeg="no" +has_libxml2="no" gprof_build="no" -PIC_CFLAGS="" +static_build="no" want_pic="no" has_joystick="no" has_xul="no" enable_joystick="no" +static_mp4box="no" +disable_3d="no" +disable_svg="no" +disable_vrml="no" +disable_x3d="no" +disable_od="no" +disable_bifs="no" +disable_bifs_enc="no" +disable_laser="no" +disable_beng="no" +disable_qtvr="no" +disable_avi="no" +disable_m2ps="no" +disable_m2ts="no" +disable_m2ts_mux="no" +disable_ogg="no" +disable_parsers="no" +disable_import="no" +disable_export="no" +disable_swf="no" +disable_scene_stats="no" +disable_scene_dump="no" +disable_scene_encode="no" +disable_loader_isoff="no" +disable_loader_bt="no" +disable_loader_xmt="no" +disable_od_dump="no" +disable_mcrypt="no" +disable_isoff="no" +disable_isoff_write="no" +disable_isoff_frag="no" +disable_isoff_hint="no" +disable_isoff_frag="no" +disable_streaming="no" +enable_depth_compositor="no" enable_renoir="no" win32="no" @@ -96,13 +142,13 @@ cygwin="no" linux="no" freebsd="no" darwin="no" +sunos="no" alt_macosx_dir="" Mac_Applications="" extralibs="-lm" bigendian="no" SHFLAGS=-shared need_inet_aton="no" -LDFLAGS="$LDFLAGS -Wl --warn-common" CFLAGS="" CPPFLAGS="" GPAC_SH_FLAGS=-lpthread @@ -128,7 +174,8 @@ echo " --mandir=DIR man documentation in DIR [PREFIX/man]" echo "" echo " --source-path=PATH path of source code [$source_path]" echo " --cross_prefix=PREFIX use PREFIX for compile tools [$cross_prefix]" -echo " --cc=CC use C compiler CC [$cc]" +echo " --cc =CC use C compiler CC [$cc]" +echo " --cpp=CPP use C++ compiler CPP [$cpp]" echo " --make=MAKE use specified make [$make]" echo " --extra-cflags=ECFLAGS add ECFLAGS to CFLAGS [$CFLAGS]" echo " --extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS [$LDFLAGS]" @@ -145,28 +192,60 @@ echo " --enable-debug produce debug version" echo " --enable-gprof enable profiling" echo " --enable-pic enable Position Independant Code for shared objects" echo " --strip enable strip" +echo " --std-allocator uses standard lib memory allocator" echo " --track-memory enable tracking of all memory allocated by gpac" -echo " --disable-fragments disable movie fragments in ISO media support" echo " --disable-opt disable GCC optimizations" echo " --disable-ipv6 disable IPV6 support" echo " --disable-wx disable wxWidgets support" echo " --disable-oss-audio disable OSS audio" echo " --disable-x11-shm disable X11 shared memory support" echo " --disable-x11-xv disable X11 Xvideo support" -echo " --disable-fragments disable movie fragments in ISO media support" -echo " --enable-readonly force ISO media to be read-only" -echo " --disable-svg disable SVG support" -echo " --enable-fixed-point enable fixed-point math (THIS MODIFIES GPAC MATH.H HEADER)" +echo " --enable-fixed-point enable fixed-point math" echo " --force-fixed-point force fixed-point math without changing gpac math.h header" -echo " --disable-opengl disable OpenGL support" echo " --enable-tinygl enable TinyGL support" echo " --enable-joystick enable joystick support" -echo " --enable-renoir enable renoir 3D support" echo " --disable-ssl disable OpenSSL support" echo " --enable-amr-nb-fixed enable AMR NB fixed-point decoder" echo " --enable-amr-nb enable AMR NB library" echo " --enable-amr-wb enable AMR WB library" echo " --enable-amr enable both AMR NB and WB libraries" +echo " --static-mp4box configure for static linking of MP4Box." +echo " --enable-depth enables depth handling in the compositor" + +echo "" +echo "Configuration options for libgpac - all options can be enabled with --enable-optname" +echo " --disable-all disables all features in libgpac" +echo " --disable-3d disable 3D rendering" +echo " --disable-svg disable SVG" +echo " --disable-vrml disable MPEG-4/VRML/X3D" +echo " --disable-x3d disable X3D only" +echo " --disable-odf disable full support of MPEG-4 OD Framework" +echo " --disable-bifs disable BIFS coder" +echo " --disable-laser disable LASeR coder" +echo " --disable-beng disable scene encoder engine" +echo " --disable-qtvr disable import of Cubic QTVR files" +echo " --disable-avi disable AVI" +echo " --disable-ogg disable OGG" +echo " --disable-m2ps disable MPEG2 PS" +echo " --disable-m2ts disable MPEG2 TS" +echo " --disable-m2ts-mux disable MPEG2 TS Multiplexer" +echo " --disable-parsers disable AV parsers" +echo " --disable-import disable media importers" +echo " --disable-export disable media exporters" +echo " --disable-swf disable SWF import" +echo " --disable-scene-stats disable scene graph statistics" +echo " --disable-scene-dump disable scene graph dump" +echo " --disable-od-dump disable OD dump" +echo " --disable-mcrypt disable mcrypt" +echo " --disable-scene-encode disable BIFS & LASeR to ISO File Format encoding" +echo " --disable-loader-isoff disable scene loading from ISO File Format" +echo " --disable-loader-bt disable scene loading from ISO File Format" +echo " --disable-loader-xmt disable scene loading from ISO File Format" +echo " --disable-isoff disable ISO File Format" +echo " --disable-isoff-write disable ISO File Format edit/write" +echo " --disable-isoff-hint disable ISO File Format hinting" +echo " --disable-isoff-frag disable fragments in ISO File Format" +echo " --disable-streaming disable RTP/RTSP/SDP" echo "" echo "Extra libraries configuration. You can turn a libray off or force using the local version in gpac/extra_lib/" echo " --use-js=OPT force SpiderMonkey ECMAScript OPT=[no,local]" @@ -218,13 +297,19 @@ case "$cpu" in x86_64|amd64) cpu="x86" is_64="yes" - canon_arch="`cc -dumpmachine | sed -e 's,\([^-]*\)-.*,\1,'`" + case `uname -s` in + SunOS) + canon_arch=`isainfo -n` + ;; + *) + canon_arch="`$cc -dumpmachine | sed -e 's,\([^-]*\)-.*,\1,'`" + ;; + esac + if [ x"$canon_arch" = x"x86_64" -o x"$canon_arch" = x"amd64" ]; then if [ -z "`echo $CFLAGS | grep -- -m32`" ]; then cpu="x86_64" - libdir="lib64" - #that's a bit crude... - PIC_CFLAGS="-fPIC -DPIC" + libdir="lib64" want_pic="yes" fi fi @@ -235,6 +320,10 @@ case "$cpu" in alpha) cpu="alpha" ;; + ppc64) + cpu="powerpc" + libdir="lib64" + ;; "Power Macintosh"|ppc) cpu="powerpc" ;; @@ -244,6 +333,14 @@ case "$cpu" in sh4|sh4a|sh) cpu="sh4" ;; + sun4u|sun4v) + cpu="sparc" + if [ -z "`echo $CFLAGS | grep -- -m32`" ]; then + is_64="yes" + PIC_CFLAGS="-fPIC -DPIC" + want_pic="yes" + fi + ;; *) cpu="unknown" ;; @@ -309,7 +406,16 @@ fi ;; SunOS) make="gmake" -LDFLAGS="" +LDFLAGS="${opt#--extra-ldflags=}" +instflags="" +if test "$is_64" = "yes"; then + if test "$cpu" = "x86_64"; then + libdir=lib/amd64 + elif test "$cpu" = "sparc"; then + libdir=lib/sparcv9 + fi +fi +sunos="yes" need_inet_aton="yes" extralibs="$extralibs -lsocket -lnsl" ;; @@ -379,6 +485,7 @@ win32="yes" Linux) js_flags="-DXP_UNIX -I/usr/include/js" +LDFLAGS="$LDFLAGS -Wl,--warn-common" #OSS_LDFLAGS="-laoss" linux="yes" case "$cpu" in @@ -459,49 +566,141 @@ fi #look for spidermonkey JS support -cat > $TMPC << EOF -#include -int main( void ) { return 0; } +#spidermonkey test for new API +if test "$has_js" = "no" ; then + + cat > $TMPCPP << EOF + #include + int main( void ) { JSContext *cx; jsval *rp; return JS_AddValueRoot(cx, rp); } EOF -#regular spidermonkey -if $cc -o $TMPO $TMPC $js_flags -ljs 2> /dev/null ; then -js_inc="/usr/include" -has_js="system" -elif test "$alt_macosx_dir" != "" ; then - if cc -o $TMPO $TMPC -DXP_UNIX -I$alt_macosx_dir/include/js -L$alt_macosx_dir/lib -ljs 2> /dev/null ; then - has_js="system" - js_flags="-DXP_UNIX -I$alt_macosx_dir/include/js" - js_lib="-L$alt_macosx_dir/lib -ljs" - js_inc="$alt_macosx_dir/include/js" + #try local + js_inc="$local_inc/js" + js_flags="-DXP_UNIX -I$local_inc/js" + if $cpp -o $TMPO $TMPCPP $js_flags -L$local_lib -ljs -lpthread 2> /dev/null ; then + has_js="local" + #dc added + 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` + if $cpp -o $TMPO $TMPCPP $js_flags $js_lib_pkg -lpthread 2> /dev/null ; then + has_js="system" + js_lib=`pkg-config --libs mozilla-js` + fi +fi + +if test "$has_js" = "no" ; then + #try prefix (DC) + js_inc="$prefix/include/js" + js_flags="-DXP_UNIX -I$prefix/include/js" + if $cpp -o $TMPO $TMPCPP $js_flags -L$prefix/lib -ljs -lpthread 2> /dev/null ; then + has_js="prefix" + #dc added end + else + if $cpp -o $TMPO $TMPCPP $js_flags -ljs -lpthread 2> /dev/null ; then + js_inc="/usr/include" + has_js="system" + elif $cpp -o $TMPO $TMPCPP -DXP_UNIX -I$alt_macosx_dir/include/js -L$alt_macosx_dir/lib -ljs -lpthread 2> /dev/null ; then + has_js="system" + js_flags="-DXP_UNIX -I$alt_macosx_dir/include/js" + js_lib="-L$alt_macosx_dir/lib -ljs" + js_inc="$alt_macosx_dir/include/js" + else + #debian spidermonkey (smjs) + js_flags="-DXP_UNIX -I/usr/include/smjs" + js_inc="/usr/include/smjs" + if $cpp -o $TMPO $TMPCPP $js_flags -lsmjs -lpthread 2> /dev/null ; then + has_js="system" + js_lib="-lsmjs" + else + #debian spidermonkey (mozjs) + js_flags="-DXP_UNIX -I/usr/include/mozjs" + js_inc="/usr/include/mozjs" + if $cpp -o $TMPO $TMPCPP $js_flags -lmozjs -lpthread 2> /dev/null ; then + has_js="system" + js_lib="-lmozjs" + fi + fi + fi + fi fi -else -#debian spidermonkey (smjs) -js_flags="-DXP_UNIX -I/usr/include/smjs" -js_inc="/usr/include/smjs" -if $cc -o $TMPO $TMPC $js_flags -lsmjs 2> /dev/null ; then -has_js="system" -js_lib="-lsmjs" -else -#debian spidermonkey (mozjs) -js_flags="-DXP_UNIX -I/usr/include/mozjs" -js_inc="/usr/include/mozjs" -if $cc -o $TMPO $TMPC $js_flags -lmozjs 2> /dev/null ; then -has_js="system" -js_lib="-lmozjs" -else -#try local -js_inc="$local_inc/js" -js_flags="-DXP_UNIX -I$local_inc/js" -if $cc -o $TMPO $TMPC $js_flags -L$local_lib -ljs 2> /dev/null ; then -has_js="local" fi fi + +if test "$has_js" != "no" ; then +js_flags="-DSPIDERMONKEY_NEW_API $js_flags" +echo "SpiderMonkey new API detected" # (version > 1.8.0rc1) fi + +#spidermonkey test for regular API +if test "$has_js" = "no" ; then + + cat > $TMPC << EOF + #include + int main( void ) { return 0; } +EOF + + #try local + js_inc="$local_inc/js" + js_flags="-DXP_UNIX -I$local_inc/js" + if $cc -o $TMPO $TMPC $js_flags -L$local_lib -ljs 2> /dev/null ; then + has_js="local" + #dc added + else + #try prefix (DC) + js_inc="$prefix/include/js" + js_flags="-DXP_UNIX -I$prefix/include/js" + if $cc -o $TMPO $TMPC $js_flags -L$prefix/lib -ljs 2> /dev/null ; then + has_js="prefix" + #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` + if $cc -o $TMPO $TMPC $js_flags $js_lib_pkg -lpthread 2> /dev/null ; then + has_js="system" + js_lib=`pkg-config --libs mozilla-js` + fi + fi + if test "$has_js" = "no" ; then + if $cc -o $TMPO $TMPC $js_flags -ljs 2> /dev/null ; then + js_inc="/usr/include" + has_js="system" + elif $cc -o $TMPO $TMPC -DXP_UNIX -I$alt_macosx_dir/include/js -L$alt_macosx_dir/lib -ljs 2> /dev/null ; then + has_js="system" + js_flags="-DXP_UNIX -I$alt_macosx_dir/include/js" + js_lib="-L$alt_macosx_dir/lib -ljs" + js_inc="$alt_macosx_dir/include/js" + else + #debian spidermonkey (smjs) + js_flags="-DXP_UNIX -I/usr/include/smjs" + js_inc="/usr/include/smjs" + if $cc -o $TMPO $TMPC $js_flags -lsmjs 2> /dev/null ; then + has_js="system" + js_lib="-lsmjs" + else + #debian spidermonkey (mozjs) + js_flags="-DXP_UNIX -I/usr/include/mozjs" + js_inc="/usr/include/mozjs" + if $cc -o $TMPO $TMPC $js_flags -lmozjs 2> /dev/null ; then + has_js="system" + js_lib="-lmozjs" + fi + fi + fi + fi + fi + fi + fi + if test "$has_js" != "no" ; then +if test "$linux" = "yes" ; then +if test "$cpu" != "sh4"; then #WARNING: there is a bug in MOZJS packages, the MOZILLA_1_8_BRANCH macro is not signaled, there is no way of knowing #if the lib has been compiled with or without the macro. We currently just decide that if the macro is present @@ -513,6 +712,11 @@ echo "If you have troubles with scripts in GPAC, disable this macro and recompil fi fi +fi +fi + +#fi + #end JS test @@ -525,20 +729,17 @@ cat > $TMPC << EOF #include FT_OUTLINE_H int main( void ) { return 0; } EOF -echo $cross_prefix if test "$cross_prefix" != "" ; then - if test "`which $prefix/bin/freetype-config`" != ""; then - ft_cflags="`$prefix/bin/freetype-config --cflags`" - ft_lflags="`$prefix/bin/freetype-config --libs`" - if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null ; then + ft_cflags="-I$prefix/include " + ft_lflags="-L$prefix/lib -lfreetype" + if $cc -o $TMPO $TMPC $ft_cflags $ft_lflags 2> /dev/null ; then has_ft="system" - else + else 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 has_ft="local" fi - fi fi else if test "`which freetype-config`" != ""; then @@ -599,6 +800,18 @@ if test "$cross_prefix" != "" ; then has_jpeg="local" fi fi + else + jpeg_cflags="-I$prefix/include" + jpeg_lflags="-L$prefix/lib -ljpeg" + if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then + has_jpeg="system" + else + jpeg_cflags="-I$local_inc/jpeg" + jpeg_lflags="-L$local_lib -ljpeg" + if $cc -o $TMPO $TMPC $jpeg_cflags $jpeg_lflags 2> /dev/null ; then + has_jpeg="local" + fi + fi fi else if $cc -o $TMPO $TMPC -ljpeg 2> /dev/null ; then @@ -638,8 +851,8 @@ EOF if test "$cross_prefix" != "" ; then png_cflags="-I$prefix/include" png_lflags="-L$prefix/lib -lpng -lz" - echo $png_cflags - echo $png_lflags + #-nostdlib prevents from searching standard compiler libraries + #if $cc -o $TMPO $TMPC -nostdlib $png_cflags $png_lflags 2> /dev/null ; then if $cc -o $TMPO $TMPC $png_cflags $png_lflags 2> /dev/null ; then has_png="system" else @@ -702,14 +915,22 @@ cat > $TMPC << EOF int main( void ) { return 0; } EOF -if $cc -o $TMPO $TMPC -lxvidcore 2> /dev/null ; then -has_xvid="system" -elif test "$alt_macosx_dir" != "" ; then - if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lxvidcore 2> /dev/null ; then - has_xvid="system" - fi -elif $cc -o $TMPO $TMPC -I$local_inc/xvid -L$local_lib -lxvidcore 2> /dev/null ; then -has_xvid="local" +if test "$cross_prefix" != "" ; then + if $cc -o $TMPO $TMPC -I$prefix/include -L$prefix/lib -lxvidcore 2> /dev/null ; then + has_xvid="system" + elif $cc -o $TMPO $TMPC -I$local_inc/xvid -L$local_lib -lxvidcore 2> /dev/null ; then + has_xvid="local" + fi +else + if $cc -o $TMPO $TMPC -lxvidcore 2> /dev/null ; then + has_xvid="system" + elif test "$alt_macosx_dir" != "" ; then + if $cc -o $TMPO $TMPC -I$alt_macosx_dir/include -L$alt_macosx_dir/lib -lxvidcore 2> /dev/null ; then + has_xvid="system" + fi + elif $cc -o $TMPO $TMPC -I$local_inc/xvid -L$local_lib -lxvidcore 2> /dev/null ; then + has_xvid="local" + fi fi #look for FAAD support @@ -730,24 +951,41 @@ fi #look for FFMPEG support + +if pkg-config --exists libavcodec libavformat libswscale 2> /dev/null ; then + + ffmpeg_cflags=`pkg-config --cflags libavcodec libavformat libswscale` + ffmpeg_lflags=`pkg-config --libs libavcodec libavformat libswscale` + has_ffmpeg="system" + +else + +cat > $TMPC << EOF +#include +int main( void ) { return 0; } +EOF + +if $cc -o $TMPO $TMPC 2> /dev/null ; then +old_ffmpeg_inc="no" +else + +old_ffmpeg_inc="yes" + cat > $TMPC << EOF -#include #include int main( void ) { return 0; } EOF +fi + + if test "$cross_prefix" != "" ; then - echo "HELLO" - echo "HELLO" - echo "HELLO" if $cc -o $TMPO $TMPC -I$prefix/include -L$prefix/lib -lz -lavcodec -lavformat -lavutil 2> /dev/null ; then - echo "HELLO" - echo "HELLO" - echo "HELLO" has_ffmpeg="system" else if $cc -o $TMPO $TMPC -I$local_inc -L$local_lib -lz -lavcodec -lavformat 2> /dev/null ; then has_ffmpeg="local" + echo OK fi fi else @@ -762,6 +1000,8 @@ else fi fi +fi + #look for vorbis support cat > $TMPC << EOF #include @@ -860,7 +1100,7 @@ fi has_wx="no" wx_too_old="no" -if test "`which wx-config`" != "" ; then +if type wx-config >/dev/null 2>&1; then wx_version=`wx-config --version | sed 's/[^0-9]//g'` @@ -901,6 +1141,16 @@ fi fi #end wx test +# If svg isn't disabled +if test "$disable_svg" != "yes"; then +# Then we check libxm2 presence via pkg-config + if pkg-config libxml-2.0 --exists > /dev/null 2>&1 ; then + libxml2_cflags=`pkg-config libxml-2.0 --cflags` + libxml2_lib_flags=`pkg-config libxml-2.0 --libs` + has_libxml2="yes" + fi +fi + # look for IPv6 cat > $TMPC << EOF @@ -913,7 +1163,7 @@ int main( void ) { struct ipv6_mreq mreq6; getaddrinfo(0,0,0,0); getnameinfo(0,0,0,0,0,0,0); - IN6_IS_ADDR_MULTICAST(0); + IN6_IS_ADDR_MULTICAST( (struct in6_addr *) 0); } EOF @@ -977,7 +1227,6 @@ if $cc -o $TMPE $TMPC > /dev/null 2>&1 ; then has_jack="yes" fi - for opt do case "$opt" in --sdl-cfg=*) sdl_path=`echo $opt | cut -d '=' -f 2`; sdl_local="yes" @@ -1012,7 +1261,9 @@ for opt do ;; --enable-gprof) gprof_build="yes"; ;; - --enable-pic) PIC_CFLAGS="-fPIC -DPIC"; want_pic="yes"; + --enable-static-bin) static_build="yes"; + ;; + --enable-pic) want_pic="yes"; ;; --disable-opt) no_gcc_opt="yes" ;; @@ -1020,32 +1271,28 @@ for opt do ;; --disable-wx) has_wx="no" ;; - --disable-fragments) iso_fragments="no" - ;; - --enable-readonly) make_readonly="yes" - ;; --disable-oss-audio) has_oss_audio="no" ;; --disable-x11-shm) has_x11_shm="no" ;; --disable-x11-xv) has_x11_xv="no" ;; - --disable-svg) disable_svg="yes" - ;; --enable-fixed-point) use_fixed_point="yes" ;; - --force-fixed-point) use_fixed_point="forced" - ;; --strip) INSTFLAGS="-s $INSTFLAGS" ;; - --track-memory) use_memory_tracking="yes" + --std-allocator) use_std_alloc="yes" ;; - --disable-opengl) disable_opengl="yes" + --track-memory) use_memory_tracking="yes" ;; --enable-tinygl) enable_tinygl="yes" ;; --disable-ssl) has_ssl="no" ;; + --enable-depth) enable_depth_compositor="yes" + ;; + --static-mp4box) static_mp4box="yes" + ;; --use-faad=*) has_faad=${opt#--use-faad=} ;; --use-js=*) has_js=${opt#--use-js=} @@ -1088,10 +1335,142 @@ has_png=$tmp_has_png ;; --enable-joystick) enable_joystick="yes" ;; - --enable-renoir) enable_renoir="yes" - ;; --enable-pulseaudio=*) has_pulseaudio="yes" ;; + + --disable-all) has_pulseaudio="yes"; disable_3d="yes"; disable_svg="yes"; disable_vrml="yes"; disable_od="yes"; disable_bifs="yes"; disable_bifs_enc="yes"; disable_laser="yes"; disable_beng="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_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" + ;; + + --disable-3d) disable_3d="yes" + ;; + --enable-3d) disable_3d="no" + ;; + --disable-svg) disable_svg="yes" + ;; + --enable-svg) disable_svg="no" + ;; + --disable-vrml) disable_vrml="yes" + ;; + --enable-vrml) disable_vrml="no" + ;; + --disable-x3d) disable_x3d="yes" + ;; + --enable-x3d) disable_x3d="no" + ;; + --disable-odf) disable_od="yes" + ;; + --enable-odf) disable_od="no" + ;; + --disable-bifs) disable_bifs="yes" + ;; + --enable-bifs) disable_bifs="no" + ;; + --disable-bifs-enc) disable_bifs_enc="yes" + ;; + --enable-bifs-enc) disable_bifs_enc="no" + ;; + --disable-laser) disable_laser="yes" + ;; + --enable-laser) disable_laser="no" + ;; + --disable-beng) disable_beng="yes" + ;; + --enable-beng) disable_beng="no" + ;; + --disable-qtvr) disable_qtvr="yes" + ;; + --enable-qtvr) disable_qtvr="no" + ;; + --disable-avi) disable_avi="yes" + ;; + --enable-avi) disable_avi="no" + ;; + --disable-ogg) disable_ogg="yes" + ;; + --enable-ogg) disable_ogg="no" + ;; + --disable-m2ps) disable_m2ps="yes" + ;; + --enable-m2ps) disable_m2ps="no" + ;; + --disable-m2ts) disable_m2ts="yes" + ;; + --enable-m2ts) disable_m2ts="no" + ;; + --disable-m2ts-mux) disable_m2ts_mux="yes" + ;; + --enable-m2ts-mux) disable_m2ts_mux="no" + ;; + --disable-parsers) disable_parsers="yes" + ;; + --enable-parsers) disable_parsers="no" + ;; + --disable-import) disable_import="yes" + ;; + --enable-import) disable_import="no" + ;; + --disable-export) disable_export="yes" + ;; + --enable-export) disable_export="no" + ;; + --disable-swf) disable_swf="yes" + ;; + --enable-swf) disable_swf="no" + ;; + --disable-scene-stats) disable_scene_stats="yes" + ;; + --enable-scene-stats) disable_scene_stats="no" + ;; + --disable-scene-dump) disable_scene_dump="yes" + ;; + --enable-scene-dump) disable_scene_dump="no" + ;; + --disable-scene-encode) disable_scene_encode="yes" + ;; + --enable-scene-encode) disable_scene_encode="no" + ;; + --disable-loader-isoff) disable_loader_isoff="yes" + ;; + --enable-loader-isoff) disable_loader_isoff="no" + ;; + --disable-loader-bt) disable_loader_bt="yes" + ;; + --enable-loader-bt) disable_loader_bt="no" + ;; + --disable-loader-xmt) disable_loader_xmt="yes" + ;; + --enable-loader-xmt) disable_loader_xmt="no" + ;; + --disable-od-dump) disable_od_dump="yes" + ;; + --enable-od-dump) disable_od_dump="no" + ;; + --disable-mcrypt) disable_mcrypt="yes" + ;; + --enable-mcrypt) disable_mcrypt="no" + ;; + --disable-isoff) disable_isoff="yes" + ;; + --enable-isoff) disable_isoff="no" + ;; + --disable-isoff-write) disable_isoff_write="yes" + ;; + --enable-isoff-write) disable_isoff_write="no" + ;; + --disable-isoff-hint) disable_isoff_hint="yes" + ;; + --enable-isoff-hint) disable_isoff_hint="no" + ;; + --disable-isoff-frag) disable_isoff_frag="yes" + ;; + --enable-isoff-frag) disable_isoff_frag="no" + ;; + --disable-streaming) disable_streaming="yes" + ;; + --enable-streaming) disable_streaming="no" + ;; + + esac done @@ -1099,20 +1478,30 @@ done LINK3D="" INCL3D="" +DarwinGL="no" +if test "$darwin" = "yes" ; then +cat > $TMPC << EOF +#include +#include +int main( void ) { glEnable(GL_NORMALIZE); return 0; } +EOF +else cat > $TMPC << EOF #include #include -int main( void ) { return 0; } +int main( void ) { glEnable(GL_NORMALIZE); return 0; } EOF +fi -if test "$disable_opengl" = "no" ; then +if test "$disable_3d" = "no" ; then if test "$win32" = "yes" ; then LINK3D="-lopengl32 -lglu32" elif test "$darwin" = "yes" ; then - LINK3D="-lgl -lglu" + LINK3D="-framework OpenGL -framework GLUT" + DarwinGL="yes" else - LINK3D="-lGL -lglut" + LINK3D="-lGL -lGLU -lX11" fi if $cc -o $TMPO $TMPC $LINK3D 2> /dev/null ; then has_opengl="yes" @@ -1134,11 +1523,11 @@ EOF # has_tinygl="system" # LINK3D="-lTinyGL" if test "$enable_tinygl" = "yes" ;then - if $cc -o $TMPO $TMPC -I${source_path}/../../TinyGL/include -L${source_path}/../../TinyGL/lib/$target_bin_dir -lTinyGL 2> /dev/null ; then + if $cc -o $TMPO $TMPC -I${source_path}/../tiny-gl/include -L${source_path}/../tiny-gl/lib/$target_bin_dir -lTinyGL 2> /dev/null ; then has_tinygl="yes" has_opengl="yes" - LINK3D="-L${source_path}/../../TinyGL/lib/$target_bin_dir -lTinyGL" - INCL3D="-I${source_path}/../../TinyGL/include" + LINK3D="-L${source_path}/../tiny-gl/lib/$target_bin_dir -lTinyGL" + INCL3D="-I${source_path}/../tiny-gl/include" fi fi @@ -1243,7 +1632,7 @@ sdl_config="$sdl_path/sdl-config" sdl_static="yes" fi -if test "`which $sdl_config`" != ""; then +if type $sdl_config >/dev/null 2>&1; then cat > $TMPC << EOF #include @@ -1301,12 +1690,37 @@ if test x"$mandir" = x""; then mandir="${prefix}/man" fi +if test "$static_mp4box" = "yes"; then +has_opengl="no" +has_ssl="no" +has_js="no" +has_jpeg="no" +has_png="no" +fi + +if test "$cpu" = "sh4"; then +viren_dir="`ls $source_path/modules | grep viren_out`" +if test "$viren_dir" = "viren_out"; then +enable_depth_compositor="yes" +enable_renoir="yes" +fi +fi + +#prepare for config.h writing +TMPH="${TMPDIR1}/gpac-conf-${RANDOM}-$$-${RANDOM}.h" +echo "/* Automatically generated by configure */" > $TMPH +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` echo "" echo "** System Configuration" echo "Install prefix: $prefix" echo "Source path: $source_path" -echo "C compiler: $cc" +echo "C compiler: $cc" +echo "C++ compiler: $cpp" echo "make: $make" echo "CPU: $cpu" echo "Big Endian: $bigendian" @@ -1317,23 +1731,150 @@ echo "" echo "** GPAC $version Core Configuration **" echo "debug version: $debuginfo" echo "GProf enabled: $gprof_build" +echo "Static build enabled: $static_build" echo "Memory tracking enabled: $use_memory_tracking" -echo "read-only version: $make_readonly" +echo "Use standard memory allocator: $use_std_alloc" echo "fixed-point version: $use_fixed_point" echo "IPV6 Support: $has_ipv6" -echo "IsoMedia MovieFragments support: $iso_fragments" -echo "SVG Support disabled: $disable_svg" + + +if test "$disable_svg" = "yes" ; then +echo "SVG disabled" +echo "#define GPAC_DISABLE_SVG" >> $TMPH +fi +if test "$disable_vrml" = "yes" ; then +echo "MPEG-4/VRML/X3D disabled" +echo "#define GPAC_DISABLE_VRML" >> $TMPH +fi +if test "$disable_x3d" = "yes" ; then +echo "X3D disabled" +echo "#define GPAC_DISABLE_X3D" >> $TMPH +fi +if test "$disable_od" = "yes" ; then +echo "OD Full support disabled" +echo "#define GPAC_MINIMAL_ODF" >> $TMPH +fi +if test "$disable_bifs" = "yes" ; then +echo "BIFS coder disabled" +echo "#define GPAC_DISABLE_BIFS" >> $TMPH +fi +if test "$disable_bifs_enc" = "yes" ; then +echo "BIFS encoder disabled" +echo "#define GPAC_DISABLE_BIFS_ENC" >> $TMPH +fi +if test "$disable_laser" = "yes" ; then +echo "LASeR coder disabled" +echo "#define GPAC_DISABLE_LASER" >> $TMPH +fi +if test "$disable_beng" = "yes" ; then +echo "Scene encoder engine disabled" +echo "#define GPAC_DISABLE_SENG" >> $TMPH +fi +if test "$disable_qtvr" = "yes" ; then +echo "Cubic QTVR import disabled" +echo "#define GPAC_DISABLE_QTVR" >> $TMPH +fi +if test "$disable_avi" = "yes" ; then +echo "AVI disabled" +echo "#define GPAC_DISABLE_AVILIB" >> $TMPH +fi +if test "$disable_ogg" = "yes" ; then +echo "OGG disabled" +echo "#define GPAC_DISABLE_OGG" >> $TMPH +fi +if test "$disable_m2ps" = "yes" ; then +echo "MPEG-2 PS disabled" +echo "#define GPAC_DISABLE_MPEG2PS" >> $TMPH +fi +if test "$disable_m2ts" = "yes" ; then +echo "MPEG-2 TS disabled" +echo "#define GPAC_DISABLE_MPEG2TS" >> $TMPH +fi +if test "$disable_m2ts_mux" = "yes" ; then +echo "MPEG-2 TS Multiplexer disabled" +echo "#define GPAC_DISABLE_MPEG2TS_MUX" >> $TMPH +fi +if test "$disable_parsers" = "yes" ; then +echo "AV Parsers disabled" +echo "#define GPAC_DISABLE_AV_PARSERS" >> $TMPH +fi +if test "$disable_import" = "yes" ; then +echo "Media importers disabled" +echo "#define GPAC_DISABLE_MEDIA_IMPORT" >> $TMPH +fi +if test "$disable_export" = "yes" ; then +echo "Media exmporters disabled" +echo "#define GPAC_DISABLE_MEDIA_EXPORT" >> $TMPH +fi +if test "$disable_swf" = "yes" ; then +echo "SWF import disabled" +echo "#define GPAC_DISABLE_SWF_IMPORT" >> $TMPH +fi +if test "$disable_scene_stats" = "yes" ; then +echo "Scene statistics disabled" +echo "#define GPAC_DISABLE_SCENE_STATS" >> $TMPH +fi +if test "$disable_scene_dump" = "yes" ; then +echo "Scene dump disabled" +echo "#define GPAC_DISABLE_SCENE_DUMP" >> $TMPH +fi +if test "$disable_scene_encode" = "yes" ; then +echo "Scene encoder to ISO FF disabled" +echo "#define GPAC_DISABLE_SCENE_ENCODER" >> $TMPH +fi +if test "$disable_loader_isoff" = "yes" ; then +echo "Scene loader from ISO FF disabled" +echo "#define GPAC_DISABLE_LOADER_ISOM" >> $TMPH +fi +if test "$disable_loader_bt" = "yes" ; then +echo "BT/WRL Scene loader disabled" +echo "#define GPAC_DISABLE_LOADER_BT" >> $TMPH +fi +if test "$disable_loader_xmt" = "yes" ; then +echo "XMT/X3D Scene loader disabled" +echo "#define GPAC_DISABLE_LOADER_XMT" >> $TMPH +fi +if test "$disable_od_dump" = "yes" ; then +echo "OD dump disabled" +echo "#define GPAC_DISABLE_OD_DUMP" >> $TMPH +fi +if test "$disable_mcrypt" = "yes" ; then +echo "MCrypt disabled" +echo "#define GPAC_DISABLE_MCRYPT" >> $TMPH +fi +if test "$disable_isoff" = "yes" ; then +echo "ISO File Format disabled" +echo "#define GPAC_DISABLE_ISOM" >> $TMPH +fi +if test "$disable_isoff_write" = "yes" ; then +echo "ISO File Format write disabled" +echo "#define GPAC_DISABLE_ISOM_WRITE" >> $TMPH +fi +if test "$disable_isoff_hint" = "yes" ; then +echo "ISO File Format hinting disabled" +echo "#define GPAC_DISABLE_ISOM_HINTING" >> $TMPH +fi +if test "$disable_isoff_frag" = "yes" ; then +echo "ISO File Format fragments disabled" +echo "#define GPAC_DISABLE_ISOM_FRAGMENTS" >> $TMPH +fi +if test "$disable_streaming" = "yes" ; then +echo "RTP/RTSP/SDP streaming disabled" +echo "#define GPAC_DISABLE_STREAMING" >> $TMPH +fi + +if test "$enable_depth_compositor" = "yes" ; then +echo "Depth Compositor enabled" +echo "#define GF_SR_USE_DEPTH" >> $TMPH +fi + echo "" echo "** Detected libraries **" echo "zlib: $has_zlib" if test "$win32" != "yes" ; then -if test "$has_oss_audio" = "no"; then -echo "OSS Audio: no" -else -echo "OSS Audio: yes" -fi +echo "OSS Audio: $has_oss_audio" echo "ALSA Audio: $has_alsa" echo "Jack Audio: $has_jack" echo "PulseAudio Audio: $has_pulseaudio" @@ -1351,9 +1892,6 @@ echo "OpenSSL support: $has_ssl" echo "Mozilla XUL/GECKO support: $has_xul" -echo "Joystick support: $has_joystick" -echo "Renoir enabled: $enable_renoir" - if test "$win32" = "yes" ; then echo "DirectX Support: $has_mingw_directx" fi @@ -1394,6 +1932,10 @@ echo "Xiph Theora: $has_theora" fi echo "A52 (AC3): $has_a52" +if test "$enable_renoir" = "yes" ; then +echo "Renoir enabled - make sure the driver libraries are present in modules/viren_out directory" +fi + echo "" if test "$has_amr_nb_fixed" = "yes" ; then echo "*** AMR NB FIXED-POINT NOTICE ***" @@ -1440,29 +1982,20 @@ fi fi -#overwrite fixed-point in math.h -if test "$use_fixed_point" = "yes"; then -if grep "#define GPAC_NO_FIXED_POINT" $source_path/include/gpac/math.h > /dev/null 2>&1 ; then -sed -e 's/#define GPAC_NO_FIXED_POINT/#define GPAC_FIXED_POINT/' $source_path/include/gpac/math.h >$TMPH -cp -f $TMPH $source_path/include/gpac/math.h -fi -elif test "$use_fixed_point" = "forced"; then -CFLAGS="$CFLAGS -DGPAC_FIXED_POINT" -else -if grep "#define GPAC_FIXED_POINT" $source_path/include/gpac/math.h > /dev/null 2>&1 ; then -sed -e 's/#define GPAC_FIXED_POINT/#define GPAC_NO_FIXED_POINT/' $source_path/include/gpac/math.h >$TMPH -cp -f $TMPH $source_path/include/gpac/math.h -fi +if test "$want_pic" = "yes" ; then +CFLAGS="$CFLAGS -fPIC -DPIC" +CPPFLAGS="$CPPFLAGS -fPIC -DPIC" fi -TMPH="${TMPDIR1}/gpac-conf-${RANDOM}-$$-${RANDOM}.h" +ldir=`pwd` +CFLAGS="$CFLAGS -DGPAC_HAVE_CONFIG_H -I$ldir" +CPPFLAGS="$CPPFLAGS -DGPAC_HAVE_CONFIG_H -I$ldir" + echo "Creating config.mak" echo "# Automatically generated by configure - do not modify" > config.mak -echo "/* Automatically generated by configure */" > $TMPH -echo "#ifndef GF_CONFIG_H" >> $TMPH -echo "#define GF_CONFIG_H" >> $TMPH +echo "GPAC_CONFIGURATION=$GPAC_CONFIGURATION" >> config.mak echo "prefix=$prefix" >> config.mak echo "DESTDIR=$DESTDIR" >> config.mak @@ -1475,10 +2008,10 @@ echo "CC=$cc" >> config.mak echo "AR=$ar" >> config.mak echo "RANLIB=$ranlib" >> config.mak echo "STRIP=$strip" >> config.mak +echo "INSTALL=$install" >> config.mak +echo "INSTFLAGS=$instflags" >> config.mak echo "OPTFLAGS=$CFLAGS" >> config.mak echo "CPPFLAGS=$CPPFLAGS" >> config.mak -echo "PIC_CFLAGS=$PIC_CFLAGS" >> config.mak -echo "WANT_PIC=$want_pic" >> config.mak echo "LDFLAGS=$LDFLAGS" >> config.mak echo "SHFLAGS=$SHFLAGS" >> config.mak echo "libdir=$libdir" >> config.mak @@ -1512,6 +2045,17 @@ fi echo "EXTRALIBS=$extralibs" >> config.mak echo "VERSION=$version" >>config.mak +if test "$use_fixed_point" = "yes"; then +echo "#define GPAC_FIXED_POINT" >> $TMPH +fi + +if test "$use_memory_tracking" = "yes"; then +echo "#define GPAC_MEMORY_TRACKING" >> $TMPH +elif test "$use_std_alloc" = "yes"; then +echo "#define GPAC_STD_ALLOCATOR" >> $TMPH +fi + + if test "$win32" = "yes" ; then echo "CONFIG_WIN32=yes" >> config.mak echo "CONFIG_OS=CONFIG_WIN32" >> config.mak @@ -1528,7 +2072,14 @@ elif test "$darwin" = "yes" ; then echo "CONFIG_DARWIN=yes" >> config.mak echo "CONFIG_OS=CONFIG_DARWIN" >> config.mak echo "#define GPAC_CONFIG_DARWIN" >> $TMPH + if test "$DarwinGL" = "yes" ; then + echo "#define CONFIG_DARWIN_GL" >> $TMPH + fi echo "mac_apps=$Mac_Applications" >> config.mak +elif test "$sunos" = "yes" ; then + echo "CONFIG_SUNOS=yes" >> config.mak + echo "CONFIG_OS=CONFIG_SUNOS" >> config.mak + echo "#define GPAC_CONFIG_SUNOS" >> $TMPH else echo "CONFIG_OS=CONFIG_GEN" >> config.mak echo "#define GPAC_CONFIG_GENERIC" >> $TMPH @@ -1573,20 +2124,27 @@ echo "CONFIG_OGG=$has_ogg" >> config.mak echo "CONFIG_VORBIS=$has_vorbis" >> config.mak echo "CONFIG_THEORA=$has_theora" >> config.mak echo "CONFIG_FFMPEG=$has_ffmpeg" >> config.mak +echo "CONFIG_FFMPEG_OLD=$old_ffmpeg_inc" >> config.mak + echo "CONFIG_OSS_AUDIO=$has_oss_audio" >> config.mak echo "CONFIG_ALSA=$has_alsa" >> config.mak echo "CONFIG_JACK=$has_jack" >> config.mak echo "CONFIG_A52=$has_a52" >> config.mak echo "DISABLE_SVG=$disable_svg" >> config.mak +echo "HAS_LIBXML2=$has_libxml2" >> config.mak +if test "$has_libxml2" = "yes"; then + echo "XML2_CFLAGS=$libxml2_cflags" >> config.mak + echo "XML2_LIBS=$libxml2_lib_flags" >> config.mak +fi + + echo "GPAC_USE_TINYGL=$has_tinygl" >> config.mak echo "OGL_INCLS=$INCL3D" >> config.mak -if test "$disable_svg" = "yes" ; then -echo "#define GPAC_DISABLE_SVG" >> $TMPH -fi + +echo "DISABLE_ISOFF=$disable_isoff" >> config.mak + echo "HAS_OPENGL=$has_opengl" >> config.mak -echo "ENABLE_JOYSTICK=$has_joystick" >> config.mak -echo "TRISCOPE_MODE=$enable_renoir" >> config.mak if test "$has_opengl" = "yes" ; then echo "OGL_LIBS=$LINK3D" >> config.mak @@ -1598,6 +2156,8 @@ if test "$has_tinygl" = "yes" ; then echo "#define GPAC_USE_TINYGL" >> $TMPH fi +echo "ENABLE_JOYSTICK=$has_joystick" >> config.mak + echo "HAS_OPENSSL=$has_ssl" >> config.mak if test "$has_ssl" = "yes" ; then echo "SSL_LIBS=$LINK_SSL" >> config.mak @@ -1620,15 +2180,7 @@ echo "CONFIG_AMR_NB_FT=$has_amr_nb" >> config.mak echo "CONFIG_AMR_WB_FT=$has_amr_wb" >> config.mak echo "DEBUGBUILD=$debuginfo" >> config.mak echo "GPROFBUILD=$gprof_build" >> config.mak - -echo "GPACREADONLY=$make_readonly" >> config.mak -if test "$make_readonly" = "yes" ; then - echo "#define GPAC_READ_ONLY" >> $TMPH -fi -echo "ISOFRAGMENTS=$iso_fragments" >> config.mak -if test "$iso_fragments" = "no" ; then - echo "#define GPAC_ISOM_NO_FRAGMENTS" >> $TMPH -fi +echo "STATICBUILD=$static_build" >> config.mak echo "CONFIG_IPV6=$has_ipv6" >> config.mak if test "$has_ipv6" = "yes" ; then @@ -1666,6 +2218,7 @@ echo "OSS_LDFLAGS=$OSS_LDFLAGS" >> config.mak fi echo "CONFIG_X11=$has_x11" >> config.mak + if test "$has_x11_shm" = "yes"; then echo "USE_X11_SHM=$has_x11_shm" >> config.mak fi @@ -1680,19 +2233,9 @@ echo "X11_LIB_PATH=$X11_PATH/lib" >> config.mak fi echo "X11_INC_PATH=$X11_PATH/include" >> config.mak -#overwrite memory tracking in setup.h -if test "$use_memory_tracking" = "yes"; then -if grep "#define GPAC_MEMORY_TRACKING 0" $source_path/include/gpac/setup.h > /dev/null 2>&1 ; then -sed -e 's/#define GPAC_MEMORY_TRACKING 0/#define GPAC_MEMORY_TRACKING 1/' $source_path/include/gpac/setup.h >$TMPH -cp -f $TMPH $source_path/include/gpac/setup.h -fi -else -if grep "#define GPAC_MEMORY_TRACKING 1" $source_path/include/gpac/setup.h > /dev/null 2>&1 ; then -sed -e 's/#define GPAC_MEMORY_TRACKING 1/#define GPAC_MEMORY_TRACKING 0/' $source_path/include/gpac/setup.h >$TMPH -cp -f $TMPH $source_path/include/gpac/setup.h -fi -fi +echo "MP4BOX_STATIC=$static_mp4box" >> config.mak +echo "RENOIR_ENABLE=$enable_renoir" >> config.mak GPAC_ENST_INC=no GPAC_ENST=no @@ -1707,7 +2250,7 @@ int main( void ) { } EOF -if $cc -o $TMPE $TMPC -liconv > /dev/null 2>&1 ; then +if $cc -o $TMPE $TMPC -L$local_lib -liconv > /dev/null 2>&1 ; then GPAC_ENST=yes echo "LIBGPAC_ENST=`cd src; ls enst/*.c | sed -e 's/\.c/.o/' | tr -s '\r\n' ' ' ; cd ..`" >> config.mak else @@ -1724,10 +2267,6 @@ if test "$source_path_used" = "yes" ; then echo "Creating compilation tree image" SRC_DIRS="src src/utils src/isomedia src/ietf src/odf src/bifs src/scenegraph src/terminal src/mcrypt src/media_tools src/scene_manager src/compositor src/laser" - - if test "$enable_renoir" = "yes" ; then - SRC_DIRS+=" src/compositor/triscope_renoir" - fi APP_DIRS="applications/mp4box applications/mp4client applications/mp4box applications/osmozilla applications/osmo4_wx applications/testapps/mp4_streamer applications/testapps/mp42ts" @@ -1736,12 +2275,6 @@ if test "$source_path_used" = "yes" ; then done ln -sf $source_path/Makefile Makefile ln -sf $source_path/src/Makefile src/Makefile - ln -sf $source_path/src/libgpac.def src/libgpac.def - - #if test "$enable_renoir" = "yes" ; then - #should be done according to target - #cp $source_path/src/compositor/triscope_renoir/*.a src/compositor/triscope_renoir - #fi mkdir -p applications ln -sf $source_path/applications/Makefile applications/Makefile @@ -1752,19 +2285,20 @@ if test "$source_path_used" = "yes" ; then ln -sf $source_path/$dir/Makefile $dir/Makefile done - MOD_DIRS="modules modules/aac_in modules/ac3_in modules/alsa modules/amr_dec modules/amr_float_dec modules/bifs_dec modules/ctx_load modules/dummy_in modules/dx_hw modules/ffmpeg_in modules/ft_font modules/gpac_js modules/img_in modules/ismacryp modules/isom_in modules/jack modules/laser_dec modules/mp3_in modules/mpegts_in modules/odf_dec modules/ogg modules/oss_audio modules/pulseaudio modules/raw_out modules/rtp_in modules/saf_in modules/sdl_out modules/soft_raster modules/svg_in modules/timedtext modules/wav_out modules/x11_out modules/xvid_dec" + cur_dir="`pwd`" + cd $source_path/ + MOD_DIRS="`ls -d modules/*/`" + cd $cur_dir + + mkdir -p modules + ln -sf $source_path/modules/Makefile modules/Makefile + for dir in $MOD_DIRS ; do + if ls $source_path/$dir/Makefile > /dev/null 2>&1; then mkdir -p $dir ln -sf $source_path/$dir/Makefile $dir/Makefile - cd $source_path/$dir - if ls *.def > /dev/null 2>&1; then - def_file="`ls *.def`" - cd $cur_dir - ln -sf $source_path/$dir/$def_file $dir/$def_file - else - cd $cur_dir - fi + fi done if test "$has_mingw_directx" = "yes"; then ln -sf $source_path/modules/dx_hw/hand.cur modules/dx_hw/hand.cur @@ -1792,7 +2326,7 @@ else echo "config.h is unchanged" fi -rm -f $TMPO $TMPC $TMPS $TMPCPP $TMPH +rm -f $TMPO $TMPC $TMPE $TMPS $TMPCPP $TMPH if [ ! -d "./bin" ]; then mkdir ./bin diff --git a/doc/GPAC UPnP.doc b/doc/GPAC UPnP.doc new file mode 100644 index 0000000000000000000000000000000000000000..61f915baccb46ff8c051f299d58684adb88e6035 GIT binary patch literal 74752 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

      Ow;hPq!mH3U9$O*bF=1IMk>` zKY`isIW)sNmDicJh0d@9R)Bb@4$my?|1Xl6>-i$9@87uI|4e4#NM%Ian36r-@3A|(bBo=j zhOEo?N&f84?FuS1y!RhRD+Ve4XZ1S>kwI#`dBha(uSbZUN8oFTEM(>pS%^F$3;E{}dfjU| z8fjk3(Ma+*8tH#6Vb{HurA5tpEGNI$t^(h< zS;|%5Tnl`i!RCL?0xOX|_s|&sH8(Xe$TUldLAW7_LH@3cJW-^kjtmMh(i&SWk5VDG zjE~h^-BKasQ7U8rVW002N_5G?mrt0Hfxgx9*%*4u_`F&^8$-!wW9R_FzI^hS`Is&% zbqdpF4rY#8UhDGQGJg0K)$LuEhrHJ189>;VS6*9QhWko8kzYPDFWJ%Zdk<&kQ9ZJwr!tJSqY zgfCmYt_up@GJfM9YF$-VdqKeggnjuI3Yf3q`WkhPDD2BztMhE!_{Lh^!wb_6vvK1a zTk@8nUX!)RNZM7}LFz1d8*Z^L|69xgwEV@B8gN;yd%Gg!FE0Lo%f7l7xo-aAHj94A zRME_w9hu5m!!qr&hGmLq4a;=W8kT1ivwrNFoS7-%B0Qp2Ftjw3g+Tj76i;Tc{vpH& zgCNLm|L=^&@*B02-YD9C9OP32K4xi6zP-4scRuAVSEM2@g_T$Rt1pA)2Sw%g{^Wal z@`L3s=V_!AaNnsMzOR!aKL;#7Y9qfDA#VqipC2AmXrv;)Ie5J97^U`r@rt}mTK(Zu zzHRrD`x&KP_o<5f1djZ^l)S)J-X+?u$)}3^XubT9YL{}`lwXGKROH*5p1Y4J@`_#g zy$Sir19^$<{^5VB^_J&H<>sb*#6D%lgp3YSmlf2dg{Z5+a#Y>dw=v__jSMz?QAs{P z9u$lrsXQi#a`xnFi-WV5N6Wt0p?k_tA*0$!=sIS)Pgu5UqMagi;iiW?!tB$+isLAUu*Snz5)3JD`C7pFDN`uuxa9q$`eBw zEq}TzBSft#D1Sh?kkC#qkUw&vW{7^8C^0nZKDz~3i0T= ze2v?qICy|vzC7KQzZuF<^xJivvwA_cjf0TXK^xi%Vq6Pi?+P-Q7ev>^DbYVyF@9Jm zBWP}=0gq0Y^~>*F6C)Q*&8yV7efigQI3|l%(vRi*M39tIKupd|koH&rQt&zugSrL8 zcpe4u%PxU500X8XK38S7Ql&a<#S^-Vt@tgZK<54HK=R%S*7?1x9kl7vy$2h0ek{v!GEbI;JK4$-k~VKHsFuT_fZOs^KXT-U^t9`he7J`2-{KcC_DzEVGN7~IX|B51o#&` z4ijM#JOOh4iq2#`EXRc0&wpIT|>q-3MFe^{0)|7-PWO!=W?C)X~YtToJf zWSkt*%MVf?f=$MjcEt{hrTuH4B8;9|$=ctXrWU*WcYSW8e4}j9-CP@PZNdLr`$0%Q zB)`^w{B5`RV6DAz8OgkM+L7(Uj*cdcYVjuP`l^fAxw}07NCLHQ$$qqvI=Zp)Ym;T- MtK@$Evs&Q)0UwTE>;M1& literal 0 HcmV?d00001 diff --git a/doc/INSTALL.w32 b/doc/INSTALL.w32 index 464f870..0b2b589 100644 --- a/doc/INSTALL.w32 +++ b/doc/INSTALL.w32 @@ -103,7 +103,7 @@ II GPAC compilation Note that if you have only installed libogg you can also remove the "ogg" project from the workspace, it won't be any usefull. * sdl_out: - GPAC can use SDL library for audio (all clients) and video (MP4Client andwxOsmo4) output. + GPAC can use SDL library for audio (all clients) and video (MP4Client and wxOsmo4) output. You will need to get SDL 1.2 for windows. Get it at http://www.libsdl.org/download-1.2.php. You need the DEVELOPMENT LIBRARY SDL-devel-1.2.7-VC6.zip Unpack and setup your path or VisualC++ for SDL include and lib directories (you may need to restart VisualC++) You will need to modify your VC settings to look for libxml headers and library directories. diff --git a/doc/ISO 639-2 codes.txt b/doc/ISO 639-2 codes.txt index e3b3665..54f255f 100644 --- a/doc/ISO 639-2 codes.txt +++ b/doc/ISO 639-2 codes.txt @@ -1,484 +1,487 @@ -"Abkhazian","abk", "ab" -"Achinese","ace", "" -"Acoli","ach", "" -"Adangme","ada", "" -"Adygei","ady", "" -"Adyghe","ady", "" -"Afar","aar", "aa" -"Afrihili","afh", "" -"Afrikaans","afr", "af" -"Afro-Asiatic (Other)","afa", "" -"Akan","aka", "" -"Akkadian","akk", "" -"Albanian","alb/sqi", "sq" -"Aleut","ale", "" -"Algonquian languages","alg", "" -"Altaic (Other)","tut", "" -"Amharic","amh", "am" -"Apache languages","apa", "" -"Arabic","ara", "ar" -"Aragonese","arg", "" -"Aramaic","arc", "" -"Arapaho","arp", "" -"Araucanian","arn", "" -"Arawak","arw", "" -"Armenian","arm/hye", "hy" -"Artificial (Other)","art", "" -"Assamese","asmAsturian","ast", "as" -"Athapascan languages","ath", "" -"Australian languages","aus", "" -"Austronesian (Other)","map", "" -"Avaric","ava", "" -"Avestan","ave", "" -"Awadhi","awa", "" -"Aymara","aym", "ay" -"Azerbaijani","aze", "az" -"Bable","ast", "" -"Balinese","ban", "" -"Baltic (Other)","bat", "" -"Baluchi","bal", "" -"Bambara","bam", "" -"Bamileke languages","bai", "" -"Banda","bad", "" -"Bantu (Other)","bnt", "" -"Basa","bas", "" -"Bashkir","bak", "ba" -"Basque","baq/eus", "eu" -"Batak (Indonesia)","btk", "" -"Beja","bej", "" -"Belarusian","bel", "be" -"Bemba","bem", "" -"Bengali","ben", "bn" -"Berber (Other)","ber", "" -"Bhojpuri","bho", "" -"Bihari","bih", "bh" -"Bikol","bik", "" -"Bini","bin", "" -"Bislama","bis", "bi" -"Bokmål, Norwegian","nob", "" -"Bosnian","bos", "" -"Braj","bra", "" -"Breton","bre", "br" -"Buginese","bug", "" -"Bulgarian","bul", "bg" -"Buriat","bua", "" -"Burmese","bur/mya", "my" -"Caddo","cad", "" -"Carib","car", "" -"Castilian","spa", "" -"Catalan","cat", "ca" -"Caucasian (Other)","cau", "" -"Cebuano","ceb", "" -"Celtic (Other)","cel", "" -"Central American Indian (Other)","cai", "" -"Chagatai","chg", "" -"Chamic languages","cmc", "" -"Chamorro","cha", "" -"Chechen","che", "" -"Cherokee","chr" , "" -"Chewa","nya", "" -"Cheyenne","chy", "" -"Chibcha","chb", "" -"Chichewa","nya", "" -"Chinese","chi/zho", "zh" -"Chinook jargon","chn", "" -"Chipewyan","chp", "" -"Choctaw","cho", "" -"Chuang","zha", "" -"Church Slavic (Slavonic)","chu", "" -"Chuukese","chk", "" -"Chuvash","chv", "" -"Coptic","cop", "" -"Cornish","cor", "" -"Corsican","cos", "co" -"Cree","cre" , "" -"Creek","mus" , "" -"Creoles and pidgins(Other)","crp", "" -"Creoles and pidgins, English-based (Other)","cpe", "" -"Creoles and pidgins, French-based (Other)","cpf", "" -"Creoles and pidgins, Portuguese-based (Other)","cpp", "" -"Crimean Tatar","crh", "" -"Crimean Turkish","crh", "" -"Croatian","scr/hrv", "hr" -"Cushitic (Other)","cus", "" -"Czech","cze/ces", "cs" -"Dakota","dak", "" -"Danish","dan", "da" -"Dargwa","dar", "" -"Dayak","day", "" -"Delaware","del", "" -"Dinka","din", "" -"Divehi","div" , "" -"Dogri","doi", "" -"Dogrib","dgr" , "" -"Dravidian (Other)","dra", "" -"Duala","dua", "" -"Dutch","dut/nld", "nl" -"Dutch, Middle (ca. 1050-1350)","dum", "" -"Dyula","dyu", "" -"Dzongkha","dzo", "dz" -"Efik","efi", "" -"Egyptian (Ancient)","egy", "" -"Ekajuk","eka", "" -"Elamite","elx", "" -"English","eng", "en" -"English, Middle (1100-1500)","enm", "" -"English, Old (ca.450-1100)","ang", "" -"Erzya","myv", "" -"Esperanto","epo", "eo" -"Estonian","est", "et" -"Ewe","ewe", "" -"Ewondo","ewo", "" -"Fang","fan", "" -"Fanti","fat" , "" -"Faroese","fao", "fo" -"Fijian","fij", "fj" -"Finnish","fin", "fi" -"Finno-Ugrian (Other)","fiu", "" -"Fon","fon", "" -"French","fre/fra", "fr" -"French, Middle (ca.1400-1600)","frm", "" -"French, Old (842-ca.1400)","fro", "" -"Frisian","fry", "fy" -"Friulian","fur" , "" -"Fulah","ful", "" -"Ga","gaa", "" -"Gaelic","gla", "" -"Gallegan","glg", "gl" -"Ganda","lug", "" -"Gayo","gay", "" -"Gbaya","gba" , "" -"Geez","gez", "" -"Georgian","geo/kat", "ka" -"German","ger/deu", "de" -"German, Low","nds" , "" -"German, Middle High (ca.1050-1500)","gmh", "" -"German, Old High (ca.750-1050)","goh", "" -"Germanic (Other)","gem", "" -"Gikuyu","kik", "" -"Gilbertese","gil", "" -"Gondi","gon", "" -"Gorontalo","gor", "" -"Gothic","got", "" -"Grebo","grb", "" -"Greek, Ancient (to 1453)","grc", "" -"Greek, Modern (1453-)","gre/ell", "el" -"Guarani","grn", "gn" -"Gujarati","guj", "gu" -"Gwich´in","gwi", "" -"Haida","hai", "" -"Haitian","hat", "" -"Haitian Creole","hat", "" -"Hausa","hau", "ha" -"Hawaiian","haw", "" -"Hebrew","heb", "he" -"Herero","her", "" -"Hiligaynon","hil", "" -"Himachali","him", "" -"Hindi","hin", "hi" -"Hiri Motu","hmo", "" -"Hittite","hit", "" -"Hmong","hmn", "" -"Hungarian","hun", "hu" -"Hupa","hup", "" -"Iban","iba", "" -"Icelandic","ice/isl", "is" -"Ido","ido", "" -"Igbo","ibo" , "" -"Ijo","ijo", "" -"Iloko","ilo", "" -"Inari Sami","smn", "" -"Indic (Other)","inc", "" -"Indo-European (Other)","ine", "" -"Indonesian","ind", "id" -"Ingush","inh", "" -"Interlingua (International Auxiliary Language Association)","ina", "ia" -"Interlingue","ile", "" -"Inuktitut","iku", "iu" -"Inupiaq","ipk", "ik" -"Iranian (Other)","ira", "" -"Irish","gle", "ga" -"Irish, Middle (900-1200)","mga", "" -"Irish, Old (to 900)","sga", "" -"Iroquoian languages","iro", "" -"Italian","ita", "it" -"Japanese","jpn", "ja" -"Javanese","jav", "jv" -"Judeo-Arabic","jrb", "" -"Judeo-Persian","jpr", "" -"Kabardian","kbd", "" -"Kabyle","kab", "" -"Kachin","kac", "" -"Kalaallisut","kal", "kl" -"Kalmyk","xal", "" -"Kamba","kam", "" -"Kannada","kan", "kn" -"Kanuri","kau", "" -"Karachay-Balkar","krc", "" -"Kara-Kalpak","kaa", "" -"Karen","kar", "" -"Kashmiri","kas", "ks" -"Kashubian","csb", "" -"Kawi","kaw", "" -"Kazakh","kaz", "kk" -"Khasi","kha", "" -"Khmer","khm", "km" -"Khoisan (Other)","khi", "" -"Khotanese","kho", "" -"Kikuyu","kik", "" -"Kimbundu","kmb", "" -"Kinyarwanda","kin", "rw" -"Kirghiz","kir", "ky" -"Komi","kom", "" -"Kongo","kon" , "" -"Konkani","kok" , "" -"Korean","kor", "ko" -"Kosraean","kos" , "" -"Kpelle","kpe" , "" -"Kru","kro" , "" -"Kuanyama","kua", "" -"Kumyk","kum" , "" -"Kurdish","kur", "ku" -"Kurukh","kru" , "" -"Kutenai","kut", "" -"Kwanyama","kua", "" -"Ladino","lad" , "" -"Lahnda","lah" , "" -"Lamba","lam" , "" -"Lao","lao", "lo" -"Latin","lat", "la" -"Latvian","lav", "lv" -"Letzeburgesch","ltz", "" -"Lezghian (lezLimburgan - limLimburger - limlimburgish)","lim", "" -"Lingala","lin", "ln" -"Lithuanian","lit", "lt" -"Low German","nds", "" -"Low Saxon","nds", "" -"Lozi","loz" , "" -"Luba-Katanga","lub" , "" -"Luba-Lulua","lua" , "" -"Luiseno","lui", "" -"Lule Sami","smj", "" -"Lunda","lun" , "" -"Luo (Kenya and Tanzania)","luo", "" -"Luxembourgish","ltz", "" -"Lushai","lus" , "" -"Macedonian","mac/mkd", "mk" -"Madurese","mad" , "" -"Magahi","mag" , "" -"Maithili","mai", "" -"Makasar","mak", "" -"Malagasy","mlg", "mg" -"Malay","may/msa", "ms" -"Malayalam","mal", "" -"Maltese","mlt", "ml" -"Manchu","mnc", "" -"Mandar","mdr", "" -"Mandingo","man", "" -"Manipuri","mni" , "" -"Manobo languages","mno" , "" -"Manx","glv", "" -"Maori","mao/mri", "mi" -"Marathi","mar", "mr" -"Mari","chm" , "" -"Marshallese","mah", "" -"Marwari","mwr" , "" -"Masai","mas" , "" -"Mayan languages","myn" , "" -"Mende","men" , "" -"Micmac","mic" , "" -"Minangkabau","min" , "" -"Miscellaneous languages","mis" , "" -"Mohawk","moh" , "" -"Moksha","mdf", "" -"Moldavian","mol", "mo" -"Mon-Khmer (Other)","mkh" , "" -"Mongo","lol" , "" -"Mongolian","mon", "mn" -"Mossi","mos" , "" -"Multiple languages","mul" , "" -"Munda languages","mun" , "" -"Nahuatl","nah" , "" -"Nauru","nau", "na" -"Navaho","nav", "" -"Navajo","nav", "" -"Ndebele, North","nde", "" -"Ndebele, South","nbl", "" -"Ndonga, ndoNeapolitan","nap", "" -"Nepali","nep", "ne" -"Newari","new" , "" -"Nias","nia" , "" -"Niger-Kordofanian (Other)","nic", "" -"Nilo-Saharan (Other)","ssa" , "" -"Niuean","niu" , "" -"Nogai","nog", "" -"Norse, Old","non", "" -"North American Indian (Other)","nai" , "" -"Northern Sami","sme", "" -"North Ndebele","nde", "" -"Norwegian","nor", "no" -"Norwegian Bokmål","nob", "" -"Norwegian Nynorsk","nno", "" -"Nubian languages","nub" , "" -"Nyamwezi","nym" , "" -"Nyanja","nya", "" -"Nyankole","nyn", "" -"Nynorsk, Norwegian","nno" , "" -"Nyoro","nyo" , "" -"Nzima","nzi" , "" -"Occitan (post 1500)","oci", "oc" -"Ojibwa","oji" , "" -"Old Bulgarian","chu", "" -"Old Church Slavonic","chu", "" -"Old Slavonic","chu", "" -"Oriya","ori", "or" -"Oromo","orm", "om" -"Osage","osa", "" -"Ossetian - Ossetic","oss", "" -"Otomian languages","oto", "" -"Pahlavi","pal" , "" -"Palauan","pau", "" -"Pali","pli", "" -"Pampanga","pam", "" -"Pangasinan","pag", "" -"Panjabi","pan", "pa" -"Papiamento","pap" , "" -"Papuan (Other)","paa" , "" -"Persian","per/fas", "fa" -"Persian, Old (ca.600-400)","peo" , "" -"Philippine (Other)","phi" , "" -"Phoenician","phn" , "" -"Pohnpeian","pon" , "" -"Polish","pol", "pl" -"Portuguese","por", "pt" -"Prakrit languages","pra", "" -"Provençal","oci", "" -"Provençal, Old (to 1500)","pro" , "" -"Pushto","pus", "ps" -"Quechua","que", "qu" -"Raeto-Romance","roh", "rm" -"Rajasthani","raj", "" -"Rapanui","rap", "" -"Rarotongan","rar", "" -"Romance (Other)","roa", "" -"Romanian","rum/ron", "ro" -"Romany","rom" , "" -"Rundi","run", "rn" -"Russian","rus", "ru" -"Salishan languages","sal" , "" -"Samaritan Aramaic","sam" , "" -"Sami languages (Other)","smi" , "" -"Samoan","smo", "sm" -"Sandawe","sad" , "" -"Sango","sag", "sg" -"Sanskrit","san", "sa" -"Santali","sat", "" -"Sardinian","srd", "" -"Sasak","sas" , "" -"Saxon, Low","nds", "" -"Scots","sco", "" -"Scottish Gaelic","gla" , "" -"Selkup","sel" , "" -"Semitic (Other)","sem" , "" -"Serbian","srp", "sr" -"Serbo-Croatian", "scr", "sh" -"Serer","srr" , "" -"Shan","shn" , "" -"Shona","sna", "sn" -"Sichuan Yi","iii", "" -"Sidamo","sid" , "" -"Sign languages","sgn" , "" -"Siksika","bla" , "" -"Sindhi","snd", "sd" -"Sinhalese","sin", "si" -"Sino-Tibetan (Other)","sit", "" -"Siouan languages","sio", "" -"Skolt Sami","sms" , "" -"Slave (Athapascan)","den" , "" -"Slavic (Other)","sla" , "" -"Slovak","slo", "sk" -"Slovenian","slv", "sl" -"Sogdian","sog" , "" -"Somali","som", "so" -"Songhai","son" , "" -"Soninke","snk" , "" -"Sorbian languages","wen" , "" -"Sotho, Northern","nso" , "" -"Sotho, Southern","sot", "st" -"South American Indian (Other)","sai" , "" -"Southern Sami","sma", "" -"South Ndebele","nbl", "" -"Spanish","spa", "es" -"Sukuma","suk", "" -"Sumerian","sux" , "" -"Sundanese","sun", "su" -"Susu","sus" , "" -"Swahili","swa", "sw" -"Swati","ssw", "ss" -"Swedish","swe", "sv" -"Syriac","syr", "" -"Tagalog","tgl", "tl" -"Tahitian","tah", "" -"Tai (Other)","tai" , "" -"Tajik","tgk", "tg" -"Tamashek","tmh" , "" -"Tamil","tam", "ta" -"Tatar","tat", "tt" -"Telugu","tel", "te" -"Tereno","ter" , "" -"Tetum","tet" , "" -"Thai","tha", "th" -"Tibetan","tib", "bo" -"Tigre","tig" , "" -"Tigrinya","tir", "ti" -"Timne","tem" , "" -"Tiv","tiv" , "" -"Tlingit","tli" , "" -"Tok Pisin","tpi" , "" -"Tokelau","tkl" , "" -"Tonga (Nyasa)","tog" , "to" -"Tonga (Tonga Islands)","ton", "" -"Tsimshian","tsi" , "" -"Tsonga","tso", "ts" -"Tswana","tsn", "tn" -"Tumbuka","tum" , "" -"Tupi languages","tup", "" -"Turkish","tur", "tr" -"Turkish, Ottoman (1500-1928)","ota" , "" -"Turkmen","tuk", "tk" -"Tuvalu","tvl", "" -"Tuvinian","tyv" , "" -"Twi","twi", "tw" -"Udmurt (udmUgaritic)","uga" , "" -"Uighur","uig", "ug" -"Ukrainian","ukr", "uk" -"Umbundu","umb" , "" -"Undetermined","und", "" -"Urdu","urd", "ur" -"Uzbek","uzb", "uz" -"Vai","vai", "" -"Venda","ven" , "" -"Vietnamese","vie", "vi" -"Volapük","vol", "vo" -"Votic","vot", "" -"Wakashan languages","wak" , "" -"Walamo","wal" , "" -"Walloon","wln", "" -"Waray","war", "" -"Washo","was" , "" -"Welsh","wel", "cy" -"Wolof","wol", "wo" -"Xhosa","xho", "xh" -"Yakut","sah" , "" -"Yao","yao" , "" -"Yapese","yap", "" -"Yiddish","yid", "yi" -"Yoruba","yor", "yo" -"Yupik languages","ypk" , "" -"Zande","znd" , "" -"Zapotec","zap" , "" -"Zenaga","zen" , "" -"Zhuang","zha", "za" -"Zulu","zul", "zu" -"Zuni","zun", "" +Codes used in GPAC are according to ISO/IEC 639-2/T as of GPAC 0.4.6-DEV internal rev. 6 + "Abkhazian","abk","ab", + "Achinese","ace","", + "Acoli","ach","", + "Adangme","ada","", + "Adyghe; Adygei","ady","", + "Afar","aar","aa", + "Afrihili","afh","", + "Afrikaans","afr","af", + "Afro-Asiatic languages","afa","", + "Ainu","ain","", + "Akan","aka","ak", + "Akkadian","akk","", + "Albanian","sqi","sq", + "Aleut","ale","", + "Algonquian languages","alg","", + "Altaic languages","tut","", + "Amharic","amh","am", + "Angika","anp","", + "Apache languages","apa","", + "Arabic","ara","ar", + "Aragonese","arg","an", + "Arapaho","arp","", + "Arawak","arw","", + "Armenian","hye","hy", + "Aromanian; Arumanian; Macedo-Romanian","rup","", + "Artificial languages","art","", + "Assamese","asm","as", + "Asturian; Bable; Leonese; Asturleonese","ast","", + "Athapascan languages","ath","", + "Australian languages","aus","", + "Austronesian languages","map","", + "Avaric","ava","av", + "Avestan","ave","ae", + "Awadhi","awa","", + "Aymara","aym","ay", + "Azerbaijani","aze","az", + "Balinese","ban","", + "Baltic languages","bat","", + "Baluchi","bal","", + "Bambara","bam","bm", + "Bamileke languages","bai","", + "Banda languages","bad","", + "Bantu languages","bnt","", + "Basa","bas","", + "Bashkir","bak","ba", + "Basque","eus","eu", + "Batak languages","btk","", + "Beja; Bedawiyet","bej","", + "Belarusian","bel","be", + "Bemba","bem","", + "Bengali","ben","bn", + "Berber languages","ber","", + "Bhojpuri","bho","", + "Bihari languages","bih","bh", + "Bikol","bik","", + "Bini; Edo","bin","", + "Bislama","bis","bi", + "Blin; Bilin","byn","", + "Blissymbols; Blissymbolics; Bliss","zbl","", + "BokmÃ¥l, Norwegian; Norwegian BokmÃ¥l","nob","nb", + "Bosnian","bos","bs", + "Braj","bra","", + "Breton","bre","br", + "Buginese","bug","", + "Bulgarian","bul","bg", + "Buriat","bua","", + "Burmese","mya","my", + "Caddo","cad","", + "Catalan; Valencian","cat","ca", + "Caucasian languages","cau","", + "Cebuano","ceb","", + "Celtic languages","cel","", + "Central American Indian languages","cai","", + "Central Khmer","khm","km", + "Chagatai","chg","", + "Chamic languages","cmc","", + "Chamorro","cha","ch", + "Chechen","che","ce", + "Cherokee","chr","", + "Cheyenne","chy","", + "Chibcha","chb","", + "Chichewa; Chewa; Nyanja","nya","ny", + "Chinese","zho","zh", + "Chinook jargon","chn","", + "Chipewyan; Dene Suline","chp","", + "Choctaw","cho","", + "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic","chu","cu", + "Chuukese","chk","", + "Chuvash","chv","cv", + "Classical Newari; Old Newari; Classical Nepal Bhasa","nwc","", + "Classical Syriac","syc","", + "Coptic","cop","", + "Cornish","cor","kw", + "Corsican","cos","co", + "Cree","cre","cr", + "Creek","mus","", + "Creoles and pidgins","crp","", + "Creoles and pidgins, English based","cpe","", + "Creoles and pidgins, French-based","cpf","", + "Creoles and pidgins, Portuguese-based","cpp","", + "Crimean Tatar; Crimean Turkish","crh","", + "Croatian","hrv","hr", + "Cushitic languages","cus","", + "Czech","ces","cs", + "Dakota","dak","", + "Danish","dan","da", + "Dargwa","dar","", + "Delaware","del","", + "Dinka","din","", + "Divehi; Dhivehi; Maldivian","div","dv", + "Dogri","doi","", + "Dogrib","dgr","", + "Dravidian languages","dra","", + "Duala","dua","", + "Dutch, Middle (ca.1050-1350)","dum","", + "Dutch; Flemish","nld","nl", + "Dyula","dyu","", + "Dzongkha","dzo","dz", + "Eastern Frisian","frs","", + "Efik","efi","", + "Egyptian (Ancient)","egy","", + "Ekajuk","eka","", + "Elamite","elx","", + "English","eng","en", + "English, Middle (1100-1500)","enm","", + "English, Old (ca.450-1100)","ang","", + "Erzya","myv","", + "Esperanto","epo","eo", + "Estonian","est","et", + "Ewe","ewe","ee", + "Ewondo","ewo","", + "Fang","fan","", + "Fanti","fat","", + "Faroese","fao","fo", + "Fijian","fij","fj", + "Filipino; Pilipino","fil","", + "Finnish","fin","fi", + "Finno-Ugrian languages","fiu","", + "Fon","fon","", + "French","fra","fr", + "French, Middle (ca.1400-1600)","frm","", + "French, Old (842-ca.1400)","fro","", + "Friulian","fur","", + "Fulah","ful","ff", + "Ga","gaa","", + "Gaelic; Scottish Gaelic","gla","gd", + "Galibi Carib","car","", + "Galician","glg","gl", + "Ganda","lug","lg", + "Gayo","gay","", + "Gbaya","gba","", + "Geez","gez","", + "Georgian","kat","ka", + "German","deu","de", + "German, Middle High (ca.1050-1500)","gmh","", + "German, Old High (ca.750-1050)","goh","", + "Germanic languages","gem","", + "Gilbertese","gil","", + "Gondi","gon","", + "Gorontalo","gor","", + "Gothic","got","", + "Grebo","grb","", + "Greek, Ancient (to 1453)","grc","", + "Greek, Modern (1453-)","ell","el", + "Guarani","grn","gn", + "Gujarati","guj","gu", + "Gwich'in","gwi","", + "Haida","hai","", + "Haitian; Haitian Creole","hat","ht", + "Hausa","hau","ha", + "Hawaiian","haw","", + "Hebrew","heb","he", + "Herero","her","hz", + "Hiligaynon","hil","", + "Himachali languages; Western Pahari languages","him","", + "Hindi","hin","hi", + "Hiri Motu","hmo","ho", + "Hittite","hit","", + "Hmong; Mong","hmn","", + "Hungarian","hun","hu", + "Hupa","hup","", + "Iban","iba","", + "Icelandic","isl","is", + "Ido","ido","io", + "Igbo","ibo","ig", + "Ijo languages","ijo","", + "Iloko","ilo","", + "Inari Sami","smn","", + "Indic languages","inc","", + "Indo-European languages","ine","", + "Indonesian","ind","id", + "Ingush","inh","", + "Interlingua (International Auxiliary Language Association)","ina","ia", + "Interlingue; Occidental","ile","ie", + "Inuktitut","iku","iu", + "Inupiaq","ipk","ik", + "Iranian languages","ira","", + "Irish","gle","ga", + "Irish, Middle (900-1200)","mga","", + "Irish, Old (to 900)","sga","", + "Iroquoian languages","iro","", + "Italian","ita","it", + "Japanese","jpn","ja", + "Javanese","jav","jv", + "Judeo-Arabic","jrb","", + "Judeo-Persian","jpr","", + "Kabardian","kbd","", + "Kabyle","kab","", + "Kachin; Jingpho","kac","", + "Kalaallisut; Greenlandic","kal","kl", + "Kalmyk; Oirat","xal","", + "Kamba","kam","", + "Kannada","kan","kn", + "Kanuri","kau","kr", + "Kara-Kalpak","kaa","", + "Karachay-Balkar","krc","", + "Karelian","krl","", + "Karen languages","kar","", + "Kashmiri","kas","ks", + "Kashubian","csb","", + "Kawi","kaw","", + "Kazakh","kaz","kk", + "Khasi","kha","", + "Khoisan languages","khi","", + "Khotanese; Sakan","kho","", + "Kikuyu; Gikuyu","kik","ki", + "Kimbundu","kmb","", + "Kinyarwanda","kin","rw", + "Kirghiz; Kyrgyz","kir","ky", + "Klingon; tlhIngan-Hol","tlh","", + "Komi","kom","kv", + "Kongo","kon","kg", + "Konkani","kok","", + "Korean","kor","ko", + "Kosraean","kos","", + "Kpelle","kpe","", + "Kru languages","kro","", + "Kuanyama; Kwanyama","kua","kj", + "Kumyk","kum","", + "Kurdish","kur","ku", + "Kurukh","kru","", + "Kutenai","kut","", + "Ladino","lad","", + "Lahnda","lah","", + "Lamba","lam","", + "Land Dayak languages","day","", + "Lao","lao","lo", + "Latin","lat","la", + "Latvian","lav","lv", + "Lezghian","lez","", + "Limburgan; Limburger; Limburgish","lim","li", + "Lingala","lin","ln", + "Lithuanian","lit","lt", + "Lojban","jbo","", + "Low German; Low Saxon; German, Low; Saxon, Low","nds","", + "Lower Sorbian","dsb","", + "Lozi","loz","", + "Luba-Katanga","lub","lu", + "Luba-Lulua","lua","", + "Luiseno","lui","", + "Lule Sami","smj","", + "Lunda","lun","", + "Luo (Kenya and Tanzania)","luo","", + "Lushai","lus","", + "Luxembourgish; Letzeburgesch","ltz","lb", + "Macedonian","mkd","mk", + "Madurese","mad","", + "Magahi","mag","", + "Maithili","mai","", + "Makasar","mak","", + "Malagasy","mlg","mg", + "Malay","msa","ms", + "Malayalam","mal","ml", + "Maltese","mlt","mt", + "Manchu","mnc","", + "Mandar","mdr","", + "Mandingo","man","", + "Manipuri","mni","", + "Manobo languages","mno","", + "Manx","glv","gv", + "Maori","mri","mi", + "Mapudungun; Mapuche","arn","", + "Marathi","mar","mr", + "Mari","chm","", + "Marshallese","mah","mh", + "Marwari","mwr","", + "Masai","mas","", + "Mayan languages","myn","", + "Mende","men","", + "Mi'kmaq; Micmac","mic","", + "Minangkabau","min","", + "Mirandese","mwl","", + "Mohawk","moh","", + "Moksha","mdf","", + "Mon-Khmer languages","mkh","", + "Mongo","lol","", + "Mongolian","mon","mn", + "Mossi","mos","", + "Multiple languages","mul","", + "Munda languages","mun","", + "N'Ko","nqo","", + "Nahuatl languages","nah","", + "Nauru","nau","na", + "Navajo; Navaho","nav","nv", + "Ndebele, North; North Ndebele","nde","nd", + "Ndebele, South; South Ndebele","nbl","nr", + "Ndonga","ndo","ng", + "Neapolitan","nap","", + "Nepal Bhasa; Newari","new","", + "Nepali","nep","ne", + "Nias","nia","", + "Niger-Kordofanian languages","nic","", + "Nilo-Saharan languages","ssa","", + "Niuean","niu","", + "No linguistic content; Not applicable","zxx","", + "Nogai","nog","", + "Norse, Old","non","", + "North American Indian languages","nai","", + "Northern Frisian","frr","", + "Northern Sami","sme","se", + "Norwegian","nor","no", + "Norwegian Nynorsk; Nynorsk, Norwegian","nno","nn", + "Nubian languages","nub","", + "Nyamwezi","nym","", + "Nyankole","nyn","", + "Nyoro","nyo","", + "Nzima","nzi","", + "Occitan (post 1500)","oci","oc", + "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)","arc","", + "Ojibwa","oji","oj", + "Oriya","ori","or", + "Oromo","orm","om", + "Osage","osa","", + "Ossetian; Ossetic","oss","os", + "Otomian languages","oto","", + "Pahlavi","pal","", + "Palauan","pau","", + "Pali","pli","pi", + "Pampanga; Kapampangan","pam","", + "Pangasinan","pag","", + "Panjabi; Punjabi","pan","pa", + "Papiamento","pap","", + "Papuan languages","paa","", + "Pedi; Sepedi; Northern Sotho","nso","", + "Persian","fas","fa", + "Persian, Old (ca.600-400 B.C.)","peo","", + "Philippine languages","phi","", + "Phoenician","phn","", + "Pohnpeian","pon","", + "Polish","pol","pl", + "Portuguese","por","pt", + "Prakrit languages","pra","", + "Provençal, Old (to 1500);Occitan, Old (to 1500)","pro","", + "Pushto; Pashto","pus","ps", + "Quechua","que","qu", + "Rajasthani","raj","", + "Rapanui","rap","", + "Rarotongan; Cook Islands Maori","rar","", + "Reserved for local use","qaa-qtz","", + "Romance languages","roa","", + "Romanian; Moldavian; Moldovan","ron","ro", + "Romansh","roh","rm", + "Romany","rom","", + "Rundi","run","rn", + "Russian","rus","ru", + "Salishan languages","sal","", + "Samaritan Aramaic","sam","", + "Sami languages","smi","", + "Samoan","smo","sm", + "Sandawe","sad","", + "Sango","sag","sg", + "Sanskrit","san","sa", + "Santali","sat","", + "Sardinian","srd","sc", + "Sasak","sas","", + "Scots","sco","", + "Selkup","sel","", + "Semitic languages","sem","", + "Serbian","srp","sr", + "Serer","srr","", + "Shan","shn","", + "Shona","sna","sn", + "Sichuan Yi; Nuosu","iii","ii", + "Sicilian","scn","", + "Sidamo","sid","", + "Sign Languages","sgn","", + "Siksika","bla","", + "Sindhi","snd","sd", + "Sinhala; Sinhalese","sin","si", + "Sino-Tibetan languages","sit","", + "Siouan languages","sio","", + "Skolt Sami","sms","", + "Slave (Athapascan)","den","", + "Slavic languages","sla","", + "Slovak","slk","sk", + "Slovenian","slv","sl", + "Sogdian","sog","", + "Somali","som","so", + "Songhai languages","son","", + "Soninke","snk","", + "Sorbian languages","wen","", + "Sotho, Southern","sot","st", + "South American Indian languages","sai","", + "Southern Altai","alt","", + "Southern Sami","sma","", + "Spanish; Castilian","spa","es", + "Sranan Tongo","srn","", + "Sukuma","suk","", + "Sumerian","sux","", + "Sundanese","sun","su", + "Susu","sus","", + "Swahili","swa","sw", + "Swati","ssw","ss", + "Swedish","swe","sv", + "Swiss German; Alemannic; Alsatian","gsw","", + "Syriac","syr","", + "Tagalog","tgl","tl", + "Tahitian","tah","ty", + "Tai languages","tai","", + "Tajik","tgk","tg", + "Tamashek","tmh","", + "Tamil","tam","ta", + "Tatar","tat","tt", + "Telugu","tel","te", + "Tereno","ter","", + "Tetum","tet","", + "Thai","tha","th", + "Tibetan","bod","bo", + "Tigre","tig","", + "Tigrinya","tir","ti", + "Timne","tem","", + "Tiv","tiv","", + "Tlingit","tli","", + "Tok Pisin","tpi","", + "Tokelau","tkl","", + "Tonga (Nyasa)","tog","", + "Tonga (Tonga Islands)","ton","to", + "Tsimshian","tsi","", + "Tsonga","tso","ts", + "Tswana","tsn","tn", + "Tumbuka","tum","", + "Tupi languages","tup","", + "Turkish","tur","tr", + "Turkish, Ottoman (1500-1928)","ota","", + "Turkmen","tuk","tk", + "Tuvalu","tvl","", + "Tuvinian","tyv","", + "Twi","twi","tw", + "Udmurt","udm","", + "Ugaritic","uga","", + "Uighur; Uyghur","uig","ug", + "Ukrainian","ukr","uk", + "Umbundu","umb","", + "Uncoded languages","mis","", + "Undetermined","und","", + "Upper Sorbian","hsb","", + "Urdu","urd","ur", + "Uzbek","uzb","uz", + "Vai","vai","", + "Venda","ven","ve", + "Vietnamese","vie","vi", + "Volapük","vol","vo", + "Votic","vot","", + "Wakashan languages","wak","", + "Walloon","wln","wa", + "Waray","war","", + "Washo","was","", + "Welsh","cym","cy", + "Western Frisian","fry","fy", + "Wolaitta; Wolaytta","wal","", + "Wolof","wol","wo", + "Xhosa","xho","xh", + "Yakut","sah","", + "Yao","yao","", + "Yapese","yap","", + "Yiddish","yid","yi", + "Yoruba","yor","yo", + "Yupik languages","ypk","", + "Zande languages","znd","", + "Zapotec","zap","", + "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki","zza","", + "Zenaga","zen","", + "Zhuang; Chuang","zha","za", + "Zulu","zul","zu", + "Zuni","zun","", diff --git a/doc/configuration.html b/doc/configuration.html index edea454..0ca904b 100644 --- a/doc/configuration.html +++ b/doc/configuration.html @@ -10,7 +10,7 @@
      GPAC Configuration file documentation
      Version 0.4.5

      -Last Modified $Date: 2008/12/02 18:04:42 $ +Last Modified $Date: 2010-04-09 16:44:04 $



      @@ -41,6 +41,7 @@ The config file is based on the win32 .ini file model, thus is ordered by sectio
      ISOReader DVB ALSA +Shortcuts



      @@ -224,6 +225,11 @@ handling and "Multi" means that each decoder runs in its own thread.

      Specifies the priority of the decoders (priority is applied to decoder thread(s) regardless of threading mode).

      +ResyncLateClock [value: unsigned integer] +

      +Specifies the threshold after which late clocks are resynchronized to timestamps for OCR streams. By default, no threashold (0) is used and clocks are never resynchronized. This allows to +resync clocks to the media owning the clock when the decoding is really too slow, and should only be used for debugging purposes. +

      NoVisualThread [value: "yes" "no"]

      Specifies whether the visual rendering is done in the main codec manager or in a dedicated thread. @@ -292,6 +298,12 @@ Specifies whether scalable zoom should be used or not. When scalable zoom is ena DisableYUV [value: "yes" "no"]

      Disables YUV hardware support (YUV hardware support may not be available for the current video output module).

      + + +ForceOpenGL [value: "yes" "no"] +

      +Specifies that 2D rendering will be performed by OpenGL rather than raster 2D. This will involve polygon tesselation which may not be supported on all platforms.

      + RasterOutlines [value: "yes" "no"]

      Specifies that outlining shall be done through OpenGL pen width rather than vectorial outlining.

      @@ -374,6 +386,9 @@ Default audio volume used when launching GPAC.

      Pan [value: integer (0-100)]

      Default audio stereo balance used when launching GPAC - 0 for full left, 100 for full right, 50 for balanced.

      +Filter [value: string] +

      +Defines a set of audio filters. Audio filters are declared as a list of strings separated with ";;". The exact syntax of the string is filter specific.

      @@ -641,10 +656,42 @@ Specifies the ALSA device to use. Default device is "hw:0,0".

      The "StreamingText" section of the config file holds all configuration options for the 3GPP/MPEG-4 Streaming Text decoder.

      UseTexturing [value: "yes" "no"]

      -Specifies whether the text shall be drawn using an intermediate texture or not.

      +Specifies whether the text shall be drawn using an intermediate texture or not.<OutlineText [value: "yes" "no"] +

      +Specifies whether the text shall be drawn with a black thin outline or not.

      + + +

      + + +Section "Shortcuts" Back to top +

      The "Shortcuts" section of the config file holds all shortcuts in GPAC. You can define a shorcut for an action as:
      +'action'='keyname' or 'action'='ctrl+keyname' or 'action'='alt+keyname' or "='action'='ctrl+alt+keyname'
      +Shift is not supported as a key modifier, and case is insensitive. +Currently defined actions are as follows:

      +Play or Pause
      +Stop
      +Step
      +Exit
      +Mute
      +VolumeUp
      +VolumeDown
      +JumpForward
      +JumpBackward
      +JumpStart
      +JumpEnd
      +FastForward
      +FineForward
      +SlowForward
      +FastRewind
      +FineRewind
      +SlowRewind
      +Next
      +Previous


      + diff --git a/doc/osmo4.ico b/doc/osmo4.ico new file mode 100644 index 0000000000000000000000000000000000000000..5f4841e34759e924fdb89bb224ce9542128d7483 GIT binary patch literal 15086 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 /* size_t */ -#endif - -#define AV_STRINGIFY(s) AV_TOSTRING(s) -#define AV_TOSTRING(s) #s - -#define LIBAVCODEC_VERSION_INT ((51<<16)+(32<<8)+0) -#define LIBAVCODEC_VERSION 51.32.0 -#define LIBAVCODEC_BUILD LIBAVCODEC_VERSION_INT - -#define LIBAVCODEC_IDENT "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION) - -#define AV_NOPTS_VALUE INT64_C(0x8000000000000000) -#define AV_TIME_BASE 1000000 -#ifdef CONFIG_MSVC -static AVRational AV_TIME_BASE_Q_HACK() { AVRational r; r.num=1; r.den=AV_TIME_BASE; return r;} -#define AV_TIME_BASE_Q AV_TIME_BASE_Q_HACK() -#else -#define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} -#endif - -enum CodecID { - CODEC_ID_NONE, - CODEC_ID_MPEG1VIDEO, - CODEC_ID_MPEG2VIDEO, /* prefered ID for MPEG Video 1 or 2 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, - - /* 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, - - /* 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, - - /* 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, - - CODEC_ID_MP2= 0x15000, - CODEC_ID_MP3, /* prefered ID for MPEG Audio layer 1, 2 or3 decoding */ - CODEC_ID_AAC, -#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) - CODEC_ID_MPEG4AAC, -#endif - 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, - 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, - - /* subtitle codecs */ - CODEC_ID_DVD_SUBTITLE= 0x17000, - CODEC_ID_DVB_SUBTITLE, - - CODEC_ID_MPEG2TS= 0x20000, /* _FAKE_ codec to indicate a raw MPEG2 transport - stream (only used by libavformat) */ -}; - -/* CODEC_ID_MP3LAME is absolete */ -#define CODEC_ID_MP3LAME CODEC_ID_MP3 - -enum CodecType { - CODEC_TYPE_UNKNOWN = -1, - CODEC_TYPE_VIDEO, - CODEC_TYPE_AUDIO, - CODEC_TYPE_DATA, - CODEC_TYPE_SUBTITLE, -}; - -/* currently unused, may be used if 24/32 bits samples ever supported */ -/* all in native endian */ -enum SampleFormat { - SAMPLE_FMT_NONE = -1, - SAMPLE_FMT_U8, ///< unsigned 8 bits - SAMPLE_FMT_S16, ///< signed 16 bits - SAMPLE_FMT_S24, ///< signed 24 bits - SAMPLE_FMT_S32, ///< signed 32 bits - SAMPLE_FMT_FLT, ///< float -}; - -/* in bytes */ -#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio - -/** - * 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
      - * 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 - -/** - * minimum encoding buffer size. - * used to avoid some checks during header writing - */ -#define FF_MIN_BUFFER_SIZE 16384 - -/* motion estimation type, EPZS by default */ -enum Motion_Est_ID { - ME_ZERO = 1, - ME_FULL, - ME_LOG, - ME_PHODS, - ME_EPZS, - ME_X1, - ME_HEX, - ME_UMH, - ME_ITER, -}; - -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 -}; - -typedef struct RcOverride{ - int start_frame; - int end_frame; - int qscale; // if this is 0 then quality_factor will be used instead - float quality_factor; -} RcOverride; - -#define FF_MAX_B_FRAMES 16 - -/* encoding support - these flags can be passed in AVCodecContext.flags before initing - Note: not everything is supported yet. -*/ - -#define CODEC_FLAG_QSCALE 0x0002 ///< use fixed qscale -#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / Advanced prediction for H263 -#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 -/* parent program gurantees that the input for b-frame containing streams is not written to - for at least s->max_b_frames+1 frames, if this is not set than the input will be copied */ -#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 -#define CODEC_FLAG_TRUNCATED 0x00010000 /** input bitstream might be truncated at a random location instead - of only at frame boundaries */ -#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_TRELLIS_QUANT 0x00200000 ///< use trellis quantization -#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_H263P_AIC 0x01000000 ///< H263 Advanced intra coding / MPEG4 AC prediction (remove this) -#define CODEC_FLAG_AC_PRED 0x01000000 ///< H263 Advanced intra coding / MPEG4 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 ///< H263 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 ((int)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_SKIP_RD 0x00004000 ///< RD optimal MB level residual skiping - -/* Unsupported options : - * Syntax Arithmetic coding (SAC) - * Reference Picture Selection - * Independant Segment Decoding */ -/* /Fx */ -/* codec capabilities */ - -#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 - */ -#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 non zero delay and needs to be feeded with NULL at the end to get the delayed data. - * if this is not set, the codec is guranteed to never be feeded with NULL data - */ -#define CODEC_CAP_DELAY 0x0020 -/** - * Codec can be fed a final frame with a smaller size. - * This can be used to prevent truncation of the last audio samples. - */ -#define CODEC_CAP_SMALL_LAST_FRAME 0x0040 - -//the following defines may change, don't expect compatibility if you use them -#define MB_TYPE_INTRA4x4 0x0001 -#define MB_TYPE_INTRA16x16 0x0002 //FIXME h264 specific -#define MB_TYPE_INTRA_PCM 0x0004 //FIXME h264 specific -#define MB_TYPE_16x16 0x0008 -#define MB_TYPE_16x8 0x0010 -#define MB_TYPE_8x16 0x0020 -#define MB_TYPE_8x8 0x0040 -#define MB_TYPE_INTERLACED 0x0080 -#define MB_TYPE_DIRECT2 0x0100 //FIXME -#define MB_TYPE_ACPRED 0x0200 -#define MB_TYPE_GMC 0x0400 -#define MB_TYPE_SKIP 0x0800 -#define MB_TYPE_P0L0 0x1000 -#define MB_TYPE_P1L0 0x2000 -#define MB_TYPE_P0L1 0x4000 -#define MB_TYPE_P1L1 0x8000 -#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) -#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) -#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) -#define MB_TYPE_QUANT 0x00010000 -#define MB_TYPE_CBP 0x00020000 -//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) - -/** - * Pan Scan area. - * this specifies the area which should be displayed. Note there may be multiple such areas for one frame - */ -typedef struct AVPanScan{ - /** - * id. - * - encoding: set by user. - * - decoding: set by lavc - */ - int id; - - /** - * width and height in 1/16 pel - * - encoding: set by user. - * - decoding: set by lavc - */ - int width; - int height; - - /** - * position of the top left corner in 1/16 pel for up to 3 fields/frames. - * - encoding: set by user. - * - decoding: set by lavc - */ - 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 lavc unless the default get/release_buffer() is used\ - * - encoding: \ - * - decoding: \ - */\ - uint8_t *base[4];\ - /**\ - * 1 -> keyframe, 0-> not\ - * - encoding: set by lavc\ - * - decoding: set by lavc\ - */\ - int key_frame;\ -\ - /**\ - * picture type of the frame, see ?_TYPE below.\ - * - encoding: set by lavc for coded_picture (and set by user for input)\ - * - decoding: set by lavc\ - */\ - 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 lavc\ - */\ - int64_t pts;\ -\ - /**\ - * picture number in bitstream order.\ - * - encoding: set by\ - * - decoding: set by lavc\ - */\ - int coded_picture_number;\ - /**\ - * picture number in display order.\ - * - encoding: set by\ - * - decoding: set by lavc\ - */\ - int display_picture_number;\ -\ - /**\ - * quality (between 1 (good) and FF_LAMBDA_MAX (bad)) \ - * - encoding: set by lavc for coded_picture (and set by user for input)\ - * - decoding: set by lavc\ - */\ - 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\ - * - encoding: unused\ - * - decoding: set by lavc (before get_buffer() call))\ - */\ - int reference;\ -\ - /**\ - * QP table\ - * - encoding: unused\ - * - decoding: set by lavc\ - */\ - int8_t *qscale_table;\ - /**\ - * QP store stride\ - * - encoding: unused\ - * - decoding: set by lavc\ - */\ - int qstride;\ -\ - /**\ - * mbskip_table[mb]>=1 if MB didnt change\ - * stride= mb_width = (width+15)>>4\ - * - encoding: unused\ - * - decoding: set by lavc\ - */\ - 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 lavc\ - */\ - int16_t (*motion_val[2])[2];\ -\ - /**\ - * Macroblock type table\ - * mb_type_base + mb_width + 2\ - * - encoding: set by user\ - * - decoding: set by lavc\ - */\ - 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 lavc\ - */\ - uint8_t motion_subsample_log2;\ -\ - /**\ - * for some private data of the user\ - * - encoding: unused\ - * - decoding: set by user\ - */\ - void *opaque;\ -\ - /**\ - * error\ - * - encoding: set by lavc if flags&CODEC_FLAG_PSNR\ - * - decoding: unused\ - */\ - uint64_t error[4];\ -\ - /**\ - * type of the buffer (to keep track of who has to dealloc data[*])\ - * - encoding: set by the one who allocs it\ - * - decoding: set by the one who allocs it\ - * Note: user allocated (direct rendering) & internal buffers can not coexist currently\ - */\ - int type;\ - \ - /**\ - * when decoding, this signal how much the picture must be delayed.\ - * extra_delay = repeat_pict / (2*fps)\ - * - encoding: unused\ - * - decoding: set by lavc\ - */\ - int repeat_pict;\ - \ - /**\ - * \ - */\ - int qscale_type;\ - \ - /**\ - * The content of the picture is interlaced.\ - * - encoding: set by user\ - * - decoding: set by lavc (default 0)\ - */\ - int interlaced_frame;\ - \ - /**\ - * if the content is interlaced, is top field displayed first.\ - * - encoding: set by user\ - * - decoding: set by lavc\ - */\ - int top_field_first;\ - \ - /**\ - * Pan scan.\ - * - encoding: set by user\ - * - decoding: set by lavc\ - */\ - AVPanScan *pan_scan;\ - \ - /**\ - * tell user application that palette has changed from previous frame.\ - * - encoding: ??? (no palette-enabled encoder yet)\ - * - decoding: set by lavc (default 0)\ - */\ - int palette_has_changed;\ - \ - /**\ - * Codec suggestion on buffer type if != 0\ - * - encoding: unused\ - * - decoding: set by lavc (before get_buffer() call))\ - */\ - int buffer_hints;\ -\ - /**\ - * DCT coeffitients\ - * - encoding: unused\ - * - decoding: set by lavc\ - */\ - short *dct_coeff;\ -\ - /**\ - * Motion referece frame index\ - * - encoding: set by user\ - * - decoding: set by lavc\ - */\ - int8_t *ref_index[2]; - -#define FF_QSCALE_TYPE_MPEG1 0 -#define FF_QSCALE_TYPE_MPEG2 1 -#define FF_QSCALE_TYPE_H264 2 - -#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 dealloc 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 dealloc 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 -#define FF_SP_TYPE 6 - -#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) - -/** - * Audio Video Frame. - */ -typedef struct AVFrame { - FF_COMMON_FRAME -} AVFrame; - -#define DEFAULT_FRAME_RATE_BASE 1001000 - -/** - * main external api structure. - */ -typedef struct AVCodecContext { - /** - * Info on struct for av_log - * - set by avcodec_alloc_context - */ - AVClass *av_class; - /** - * the average bitrate. - * - encoding: set by user. unused for constant quantizer encoding - * - decoding: set by lavc. 0 or some bitrate if this info is available in the stream - */ - int bit_rate; - - /** - * 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 - */ - int bit_rate_tolerance; - - /** - * CODEC_FLAG_*. - * - encoding: set by user. - * - decoding: set by user. - */ - int flags; - - /** - * some codecs needs additionnal format info. It is stored here - * - encoding: set by user. - * - decoding: set by lavc. (FIXME is this ok?) - */ - int sub_id; - - /** - * 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) [7, 8 are x264 specific, 9 is snow specific] - * - encoding: MUST be set by user. - * - decoding: unused - */ - int me_method; - - /** - * some codecs need / can use extra-data 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 - * then extradata_size to avoid prolems if its read with the bitstream reader - * the bytewise contents of extradata must not depend on the architecture or cpu endianness - * - encoding: set/allocated/freed by lavc. - * - decoding: set/allocated/freed by user. - */ - uint8_t *extradata; - int extradata_size; - - /** - * 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 lavc. - */ - AVRational time_base; - - /* video only */ - /** - * picture width / height. - * - encoding: MUST be set by user. - * - decoding: set by lavc. - * Note, for compatibility its possible to set this instead of - * coded_width/height before decoding - */ - int width, height; - -#define FF_ASPECT_EXTENDED 15 - - /** - * the number of pictures in a group of pitures, or 0 for intra_only. - * - encoding: set by user. - * - decoding: unused - */ - int gop_size; - - /** - * pixel format, see PIX_FMT_xxx. - * - encoding: set by user. - * - decoding: set by lavc. - */ - enum PixelFormat pix_fmt; - - /** - * Frame rate emulation. If not zero lower layer (i.e. format handler) - * has to read frames at native frame rate. - * - encoding: set by user. - * - decoding: unused. - */ - int rate_emu; - - /** - * if non NULL, 'draw_horiz_band' is called by the libavcodec - * decoder to draw an horizontal band. It improve cache usage. Not - * all codecs can do that. You must check the codec capabilities - * before - * - 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 - */ - 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 sec - int channels; - - /** - * audio sample format. - * - encoding: set by user. - * - decoding: set by lavc. - */ - enum SampleFormat sample_fmt; ///< sample format, currenly unused - - /* the following data should not be initialized */ - /** - * samples per packet. initialized when calling 'init' - */ - int frame_size; - int frame_number; ///< audio or video frame number - int real_pict_num; ///< returns the real picture number of previous encoded frame - - /** - * number of frames the decoded output will be delayed relative to - * the encoded input. - * - encoding: set by lavc. - * - decoding: unused - */ - int delay; - - /* - 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 qmin; - - /** - * maximum quantizer. - * - encoding: set by user. - * - decoding: unused - */ - int qmax; - - /** - * maximum quantizer difference between frames. - * - encoding: set by user. - * - decoding: unused - */ - int max_qdiff; - - /** - * 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 - */ - int max_b_frames; - - /** - * qscale factor between ip and b frames. - * - encoding: set by user. - * - decoding: unused - */ - float b_quant_factor; - - /** obsolete FIXME remove */ - int rc_strategy; -#define FF_RC_STRATEGY_XVID 1 - - int b_frame_strategy; - - /** - * hurry up amount. - * deprecated in favor of skip_idct and skip_frame - * - encoding: unused - * - decoding: set by user. 1-> skip b frames, 2-> skip idct/dequant too, 5-> skip everything except header - */ - int hurry_up; - - struct AVCodec *codec; - - void *priv_data; - - /* unused, FIXME remove*/ - int rtp_mode; - - int rtp_payload_size; /* The size of the RTP payload: the coder will */ - /* do it's 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 transmited RTP payload */ - - - /* The RTP callback: This function is called */ - /* every time the encoder has a packet to send */ - /* 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; - - /** - * number of bits used for the previously encoded frame. - * - encoding: set by lavc - * - decoding: unused - */ - int frame_bits; - - /** - * private data of the user, can be used to carry app specific stuff. - * - encoding: set by user - * - decoding: set by user - */ - void *opaque; - - char codec_name[32]; - enum CodecType codec_type; /* see CODEC_TYPE_xxx */ - enum CodecID codec_id; /* see CODEC_ID_xxx */ - - /** - * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). - * this is used to workaround some encoder bugs - * - encoding: set by user, if not then the default based on codec_id will be used - * - decoding: set by user, will be converted to upper case by lavc during init - */ - unsigned int codec_tag; - - /** - * workaround 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 ///< workaround various bugs in microsofts broken decoders -//#define FF_BUG_FAKE_SCALABILITY 16 //autodetection should work 100% - - /** - * luma single coeff elimination threshold. - * - encoding: set by user - * - decoding: unused - */ - int luma_elim_threshold; - - /** - * chroma single coeff elimination threshold. - * - encoding: set by user - * - decoding: unused - */ - int chroma_elim_threshold; - - /** - * strictly follow the std (MPEG4, ...). - * - encoding: set by user - * - decoding: unused - */ - 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 non standarized experimental things - - /** - * qscale offset 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 - */ - float b_quant_offset; - - /** - * error resilience higher values will detect more errors but may missdetect - * some more or less valid parts as errors. - * - encoding: unused - * - decoding: set by user - */ - int error_resilience; -#define FF_ER_CAREFUL 1 -#define FF_ER_COMPLIANT 2 -#define FF_ER_AGGRESSIVE 3 -#define FF_ER_VERY_AGGRESSIVE 4 - - /** - * 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 lavc - * 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 - * - encoding: unused - * - decoding: set by lavc, user can override - */ - int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic); - - /** - * called to release buffers which where allocated with get_buffer. - * a released buffer can be reused in get_buffer() - * pic.data[*] must be set to NULL - * - encoding: unused - * - decoding: set by lavc, user can override - */ - void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); - - /** - * if 1 the stream has a 1 frame delay during decoding. - * - encoding: set by lavc - * - decoding: set by lavc - */ - int has_b_frames; - - /** - * number of bytes per packet if constant and known or 0 - * used by some WAV based audio codecs - */ - int block_align; - - 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. */ - - /** - * 0-> h263 quant 1-> mpeg quant. - * - encoding: set by user. - * - decoding: unused - */ - int mpeg_quant; - - /** - * pass1 encoding statistics output buffer. - * - encoding: set by lavc - * - decoding: unused - */ - char *stats_out; - - /** - * pass2 encoding statistics input buffer. - * concatenated stuff from stats_out of pass1 should be placed here - * - encoding: allocated/set/freed by user - * - decoding: unused - */ - char *stats_in; - - /** - * 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 - */ - float rc_qsquish; - - float rc_qmod_amp; - int rc_qmod_freq; - - /** - * ratecontrol override, see RcOverride. - * - encoding: allocated/set/freed by user. - * - decoding: unused - */ - RcOverride *rc_override; - int rc_override_count; - - /** - * rate control equation. - * - encoding: set by user - * - decoding: unused - */ - char *rc_eq; - - /** - * maximum bitrate. - * - encoding: set by user. - * - decoding: unused - */ - int rc_max_rate; - - /** - * minimum bitrate. - * - encoding: set by user. - * - decoding: unused - */ - int rc_min_rate; - - /** - * decoder bitstream buffer size. - * - encoding: set by user. - * - decoding: unused - */ - int rc_buffer_size; - float rc_buffer_aggressivity; - - /** - * 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 - */ - float i_quant_factor; - - /** - * qscale offset between p and i frames. - * - encoding: set by user. - * - decoding: unused - */ - float i_quant_offset; - - /** - * initial complexity for pass1 ratecontrol. - * - encoding: set by user. - * - decoding: unused - */ - float rc_initial_cplx; - - /** - * 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 - - /** - * 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; - - - /* for binary compatibility */ - int unused; - - /** - * idct algorithm, see FF_IDCT_* below. - * - encoding: set by user - * - decoding: set by user - */ - 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 - - /** - * slice count. - * - encoding: set by lavc - * - decoding: set by user (or 0) - */ - int slice_count; - /** - * slice offsets in the frame in bytes. - * - encoding: set/allocated by lavc - * - decoding: set/allocated by user (or NULL) - */ - int *slice_offset; - - /** - * error concealment flags. - * - encoding: unused - * - decoding: set by user - */ - int error_concealment; -#define FF_EC_GUESS_MVS 1 -#define FF_EC_DEBLOCK 2 - - /** - * dsp_mask could be add used to disable unwanted CPU features - * CPU features (i.e. MMX, SSE. ...) - * - * with FORCE flag you may instead enable given CPU features - * (Dangerous: usable in case of misdetection, improper usage however will - * result into program crash) - */ - unsigned dsp_mask; -#define FF_MM_FORCE 0x80000000 /* force usage of selected flags (OR) */ - /* lower 16 bits - CPU features */ -#ifdef HAVE_MMX -#define FF_MM_MMX 0x0001 /* standard MMX */ -#define FF_MM_3DNOW 0x0004 /* AMD 3DNOW */ -#define FF_MM_MMXEXT 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 */ -#endif /* HAVE_MMX */ -#ifdef HAVE_IWMMXT -#define FF_MM_IWMMXT 0x0100 /* XScale IWMMXT */ -#endif /* HAVE_IWMMXT */ - - /** - * bits per sample/pixel from the demuxer (needed for huffyuv). - * - encoding: set by lavc - * - decoding: set by user - */ - int bits_per_sample; - - /** - * 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 - - /** - * sample aspect ratio (0 if unknown). - * numerator and denominator must be relative prime and smaller then 256 for some video standards - * - encoding: set by user. - * - decoding: set by lavc. - */ - AVRational sample_aspect_ratio; - - /** - * the picture in the bitstream. - * - encoding: set by lavc - * - decoding: set by lavc - */ - AVFrame *coded_frame; - - /** - * debug. - * - encoding: set by user. - * - decoding: set by user. - */ - 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 - - /** - * debug. - * - encoding: set by user. - * - decoding: set by user. - */ - 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 - - /** - * error. - * - encoding: set by lavc if flags&CODEC_FLAG_PSNR - * - decoding: unused - */ - uint64_t error[4]; - - /** - * minimum MB quantizer. - * - encoding: unused - * - decoding: unused - */ - int mb_qmin; - - /** - * maximum MB quantizer. - * - encoding: unused - * - decoding: unused - */ - int mb_qmax; - - /** - * motion estimation compare function. - * - encoding: set by user. - * - decoding: unused - */ - int me_cmp; - /** - * subpixel motion estimation compare function. - * - encoding: set by user. - * - decoding: unused - */ - int me_sub_cmp; - /** - * macroblock compare function (not supported yet). - * - encoding: set by user. - * - decoding: unused - */ - int mb_cmp; - /** - * interlaced dct compare 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; - - /** - * pre pass for motion estimation. - * - encoding: set by user. - * - decoding: unused - */ - int pre_me; - - /** - * motion estimation pre pass compare function. - * - encoding: set by user. - * - decoding: unused - */ - int me_pre_cmp; - - /** - * ME pre pass diamond size & shape. - * - encoding: set by user. - * - decoding: unused - */ - int pre_dia_size; - - /** - * subpel ME quality. - * - encoding: set by user. - * - decoding: unused - */ - int me_subpel_quality; - - /** - * callback to negotiate the pixelFormat. - * @param fmt is the list of formats which are supported by the codec, - * its terminated by -1 as 0 is a valid format, the formats are ordered by quality - * the first is allways the native one - * @return the choosen format - * - encoding: unused - * - decoding: set by user, if not set then the native format will always be choosen - */ - enum PixelFormat (*get_format)(struct AVCodecContext *s, const enum PixelFormat * fmt); - - /** - * DTG active format information (additionnal aspect ratio - * information only used in DVB MPEG2 transport streams). 0 if - * not set. - * - * - encoding: unused. - * - decoding: set by decoder - */ - int dtg_active_format; -#define FF_DTG_AFD_SAME 8 -#define FF_DTG_AFD_4_3 9 -#define FF_DTG_AFD_16_9 10 -#define FF_DTG_AFD_14_9 11 -#define FF_DTG_AFD_4_3_SP_14_9 13 -#define FF_DTG_AFD_16_9_SP_14_9 14 -#define FF_DTG_AFD_SP_4_3 15 - - /** - * Maximum motion estimation search range in subpel units. - * if 0 then no limit - * - * - encoding: set by user. - * - decoding: unused. - */ - int me_range; - - /** - * intra quantizer bias. - * - encoding: set by user. - * - decoding: unused - */ - int intra_quant_bias; -#define FF_DEFAULT_QUANT_BIAS 999999 - - /** - * inter quantizer bias. - * - encoding: set by user. - * - decoding: unused - */ - int inter_quant_bias; - - /** - * color table ID. - * - encoding: unused. - * - decoding: which clrtable should be used for 8bit RGB images - * table have to be stored somewhere FIXME - */ - int color_table_id; - - /** - * internal_buffer count. - * Don't touch, used by lavc default_get_buffer() - */ - int internal_buffer_count; - - /** - * internal_buffers. - * Don't touch, used by lavc default_get_buffer() - */ - void *internal_buffer; - -#define FF_LAMBDA_SHIFT 7 -#define FF_LAMBDA_SCALE (1< ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). - * this is used to workaround some encoder bugs - * - encoding: unused - * - decoding: set by user, will be converted to upper case by lavc during init - */ - unsigned int stream_codec_tag; - - /** - * scene change detection threshold. - * 0 is default, larger means fewer detected scene changes - * - encoding: set by user. - * - decoding: unused - */ - int scenechange_threshold; - - /** - * minimum lagrange multipler - * - encoding: set by user. - * - decoding: unused - */ - int lmin; - - /** - * maximum lagrange multipler - * - encoding: set by user. - * - decoding: unused - */ - int lmax; - - /** - * Palette control structure - * - encoding: ??? (no palette-enabled encoder yet) - * - decoding: set by user. - */ - struct AVPaletteControl *palctrl; - - /** - * noise reduction strength - * - encoding: set by user. - * - decoding: unused - */ - int noise_reduction; - - /** - * called at the beginning of a frame to get cr buffer for it. - * buffer type (size, hints) must be the same. lavc won't check it. - * lavc 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(). - * - encoding: unused - * - decoding: set by lavc, user can override - */ - int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); - - /** - * number of bits which should be loaded into the rc buffer before decoding starts - * - encoding: set by user. - * - decoding: unused - */ - int rc_initial_buffer_occupancy; - - /** - * - * - encoding: set by user. - * - decoding: unused - */ - int inter_threshold; - - /** - * CODEC_FLAG2_*. - * - encoding: set by user. - * - decoding: set by user. - */ - int flags2; - - /** - * simulates errors in the bitstream to test error concealment. - * - encoding: set by user. - * - decoding: unused. - */ - int error_rate; - - /** - * MP3 antialias algorithm, see FF_AA_* below. - * - encoding: unused - * - decoding: set by user - */ - 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 - /** - * Quantizer noise shaping. - * - encoding: set by user - * - decoding: unused - */ - int quantizer_noise_shaping; - - /** - * Thread count. - * is used to decide how many independant tasks should be passed to execute() - * - encoding: set by user - * - decoding: set by user - */ - int thread_count; - - /** - * the codec may call this to execute several independant 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 lavc, user can override - * - decoding: set by lavc, user can override - */ - int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), 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; - - /** - * Motion estimation threshold. under which no motion estimation is - * performed, but instead the user specified motion vectors are used - * - * - encoding: set by user - * - decoding: unused - */ - int me_threshold; - - /** - * Macroblock threshold. under which the user specified macroblock types will be used - * - encoding: set by user - * - decoding: unused - */ - int mb_threshold; - - /** - * precision of the intra dc coefficient - 8. - * - encoding: set by user - * - decoding: unused - */ - int intra_dc_precision; - - /** - * noise vs. sse weight for the nsse comparsion function. - * - encoding: set by user - * - decoding: unused - */ - int nsse_weight; - - /** - * number of macroblock rows at the top which are skipped. - * - encoding: unused - * - decoding: set by user - */ - int skip_top; - - /** - * number of macroblock rows at the bottom which are skipped. - * - encoding: unused - * - decoding: set by user - */ - int skip_bottom; - - /** - * profile - * - encoding: set by user - * - decoding: set by lavc - */ - int profile; -#define FF_PROFILE_UNKNOWN -99 - - /** - * level - * - encoding: set by user - * - decoding: set by lavc - */ - int level; -#define FF_LEVEL_UNKNOWN -99 - - /** - * low resolution decoding. 1-> 1/2 size, 2->1/4 size - * - encoding: unused - * - decoding: set by user - */ - int lowres; - - /** - * bitsream 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 - */ - int coded_width, coded_height; - - /** - * frame skip threshold - * - encoding: set by user - * - decoding: unused - */ - int frame_skip_threshold; - - /** - * frame skip factor - * - encoding: set by user - * - decoding: unused - */ - int frame_skip_factor; - - /** - * frame skip exponent - * - encoding: set by user - * - decoding: unused - */ - int frame_skip_exp; - - /** - * frame skip comparission function - * - encoding: set by user. - * - decoding: unused - */ - int frame_skip_cmp; - - /** - * border processing masking. raises the quantizer for mbs on the borders - * of the picture. - * - encoding: set by user - * - decoding: unused - */ - float border_masking; - - /** - * minimum MB lagrange multipler. - * - encoding: set by user. - * - decoding: unused - */ - int mb_lmin; - - /** - * maximum MB lagrange multipler. - * - encoding: set by user. - * - decoding: unused - */ - int mb_lmax; - - /** - * - * - encoding: set by user. - * - decoding: unused - */ - int me_penalty_compensation; - - /** - * - * - 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; - - /** - * - * - encoding: set by user. - * - decoding: unused - */ - int bidir_refine; - - /** - * - * - encoding: set by user. - * - decoding: unused - */ - int brd_scale; - - /** - * constant rate factor - quality-based VBR - values ~correspond to qps - * - encoding: set by user. - * - decoding: unused - */ - float crf; - - /** - * constant quantization parameter rate control method - * - encoding: set by user. - * - decoding: unused - */ - int cqp; - - /** - * minimum gop size - * - encoding: set by user. - * - decoding: unused - */ - int keyint_min; - - /** - * number of reference frames - * - encoding: set by user. - * - decoding: unused - */ - int refs; - - /** - * chroma qp offset from luma - * - encoding: set by user. - * - decoding: unused - */ - int chromaoffset; - - /** - * influences how often b-frames are used - * - encoding: set by user. - * - decoding: unused - */ - int bframebias; - - /** - * trellis RD quantization - * - encoding: set by user. - * - decoding: unused - */ - int trellis; - - /** - * reduce fluctuations in qp (before curve compression) - * - encoding: set by user. - * - decoding: unused - */ - float complexityblur; - - /** - * in-loop deblocking filter alphac0 parameter - * alpha is in the range -6...6 - * - encoding: set by user. - * - decoding: unused - */ - int deblockalpha; - - /** - * in-loop deblocking filter beta parameter - * beta is in the range -6...6 - * - encoding: set by user. - * - decoding: unused - */ - int deblockbeta; - - /** - * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4 - * - encoding: set by user. - * - decoding: unused - */ - int partitions; -#define X264_PART_I4X4 0x001 /* Analyse i4x4 */ -#define X264_PART_I8X8 0x002 /* Analyse i8x8 (requires 8x8 transform) */ -#define X264_PART_P8X8 0x010 /* Analyse p16x8, p8x16 and p8x8 */ -#define X264_PART_P4X4 0x020 /* Analyse p8x4, p4x8, p4x4 */ -#define X264_PART_B8X8 0x100 /* Analyse b16x8, b8x16 and b8x8 */ - - /** - * direct mv prediction mode - 0 (none), 1 (spatial), 2 (temporal) - * - encoding: set by user. - * - decoding: unused - */ - int directpred; - - /** - * audio cutoff bandwidth (0 means "automatic") . Currently used only by FAAC - * - encoding: set by user. - * - decoding: unused - */ - int cutoff; - - /** - * multiplied by qscale for each frame and added to scene_change_score - * - encoding: set by user. - * - decoding: unused - */ - int scenechange_factor; - - /** - * - * note: value depends upon the compare functin used for fullpel ME - * - encoding: set by user. - * - decoding: unused - */ - int mv0_threshold; - - /** - * adjusts sensitivity of b_frame_strategy 1 - * - encoding: set by user. - * - decoding: unused - */ - int b_sensitivity; - - /** - * - encoding: set by user. - * - decoding: unused - */ - int compression_level; -#define FF_COMPRESSION_DEFAULT -1 - - /** - * sets whether to use LPC mode - used by FLAC encoder - * - encoding: set by user. - * - decoding: unused. - */ - int use_lpc; - - /** - * LPC coefficient precision - used by FLAC encoder - * - encoding: set by user. - * - decoding: unused. - */ - int lpc_coeff_precision; - - /** - * - encoding: set by user. - * - decoding: unused. - */ - int min_prediction_order; - - /** - * - encoding: set by user. - * - decoding: unused. - */ - int max_prediction_order; - - /** - * search method for selecting prediction order - * - encoding: set by user. - * - decoding: unused. - */ - int prediction_order_method; - - /** - * - encoding: set by user. - * - decoding: unused. - */ - int min_partition_order; - - /** - * - encoding: set by user. - * - decoding: unused. - */ - int max_partition_order; - - /** - * GOP timecode frame start number, in non drop frame format - * - encoding: set by user. - * - decoding: unused. - */ - int64_t timecode_frame_start; -} AVCodecContext; - -/** - * AVCodec. - */ -typedef struct AVCodec { - 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, - uint8_t *buf, int buf_size); - int capabilities; - struct AVCodec *next; - 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 terminanted by -1 -} AVCodec; - -/** - * 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 -} AVPicture; - -/** - * AVPaletteControl - * This structure defines a method for communicating palette changes - * between and demuxer and a decoder. - * this is totally broken, palette changes should be sent as AVPackets - */ -#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 a 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; - -typedef struct AVSubtitleRect { - uint16_t x; - uint16_t y; - uint16_t w; - uint16_t h; - uint16_t nb_colors; - int linesize; - uint32_t *rgba_palette; - uint8_t *bitmap; -} AVSubtitleRect; - -typedef struct AVSubtitle { - uint16_t format; /* 0 = graphics */ - uint32_t start_display_time; /* relative to packet pts, in ms */ - uint32_t end_display_time; /* relative to packet pts, in ms */ - uint32_t num_rects; - AVSubtitleRect *rects; -} AVSubtitle; - -extern AVCodec ac3_encoder; -extern AVCodec amr_nb_encoder; -extern AVCodec amr_wb_encoder; -extern AVCodec asv1_encoder; -extern AVCodec asv2_encoder; -extern AVCodec bmp_encoder; -extern AVCodec dvvideo_encoder; -extern AVCodec faac_encoder; -extern AVCodec ffv1_encoder; -extern AVCodec ffvhuff_encoder; -extern AVCodec flac_encoder; -extern AVCodec flashsv_encoder; -extern AVCodec flv_encoder; -extern AVCodec gif_encoder; -extern AVCodec h261_encoder; -extern AVCodec h263_encoder; -extern AVCodec h263p_encoder; -extern AVCodec h264_encoder; -extern AVCodec huffyuv_encoder; -extern AVCodec jpegls_encoder; -extern AVCodec libgsm_encoder; -extern AVCodec libtheora_encoder; -extern AVCodec ljpeg_encoder; -extern AVCodec mdec_encoder; -extern AVCodec mjpeg_encoder; -extern AVCodec mp2_encoder; -extern AVCodec mp3lame_encoder; -extern AVCodec mpeg1video_encoder; -extern AVCodec mpeg2video_encoder; -extern AVCodec mpeg4_encoder; -extern AVCodec msmpeg4v1_encoder; -extern AVCodec msmpeg4v2_encoder; -extern AVCodec msmpeg4v3_encoder; -extern AVCodec oggvorbis_encoder; -extern AVCodec pam_encoder; -extern AVCodec pbm_encoder; -extern AVCodec pgm_encoder; -extern AVCodec pgmyuv_encoder; -extern AVCodec png_encoder; -extern AVCodec ppm_encoder; -extern AVCodec rv10_encoder; -extern AVCodec rv20_encoder; -extern AVCodec snow_encoder; -extern AVCodec sonic_encoder; -extern AVCodec sonic_ls_encoder; -extern AVCodec svq1_encoder; -extern AVCodec vcr1_encoder; -extern AVCodec vorbis_encoder; -extern AVCodec wmav1_encoder; -extern AVCodec wmav2_encoder; -extern AVCodec wmv1_encoder; -extern AVCodec wmv2_encoder; -extern AVCodec x264_encoder; -extern AVCodec xvid_encoder; -extern AVCodec zlib_encoder; -extern AVCodec zmbv_encoder; - -extern AVCodec aac_decoder; -extern AVCodec aasc_decoder; -extern AVCodec alac_decoder; -extern AVCodec amr_nb_decoder; -extern AVCodec amr_wb_decoder; -extern AVCodec asv1_decoder; -extern AVCodec asv2_decoder; -extern AVCodec avs_decoder; -extern AVCodec bmp_decoder; -extern AVCodec cavs_decoder; -extern AVCodec cinepak_decoder; -extern AVCodec cljr_decoder; -extern AVCodec cook_decoder; -extern AVCodec cscd_decoder; -extern AVCodec cyuv_decoder; -extern AVCodec dsicinaudio_decoder; -extern AVCodec dsicinvideo_decoder; -extern AVCodec dvvideo_decoder; -extern AVCodec eightbps_decoder; -extern AVCodec ffv1_decoder; -extern AVCodec ffvhuff_decoder; -extern AVCodec flac_decoder; -extern AVCodec flashsv_decoder; -extern AVCodec flic_decoder; -extern AVCodec flv_decoder; -extern AVCodec fourxm_decoder; -extern AVCodec fraps_decoder; -extern AVCodec gif_decoder; -extern AVCodec h261_decoder; -extern AVCodec h263_decoder; -extern AVCodec h263i_decoder; -extern AVCodec h264_decoder; -extern AVCodec huffyuv_decoder; -extern AVCodec idcin_decoder; -extern AVCodec imc_decoder; -extern AVCodec indeo2_decoder; -extern AVCodec indeo3_decoder; -extern AVCodec interplay_dpcm_decoder; -extern AVCodec interplay_video_decoder; -extern AVCodec kmvc_decoder; -extern AVCodec libgsm_decoder; -extern AVCodec loco_decoder; -extern AVCodec mace3_decoder; -extern AVCodec mace6_decoder; -extern AVCodec mdec_decoder; -extern AVCodec mjpeg_decoder; -extern AVCodec mjpegb_decoder; -extern AVCodec mmvideo_decoder; -extern AVCodec mp2_decoder; -extern AVCodec mp3_decoder; -extern AVCodec mp3adu_decoder; -extern AVCodec mp3on4_decoder; -extern AVCodec mpc7_decoder; -extern AVCodec mpeg1video_decoder; -extern AVCodec mpeg2video_decoder; -extern AVCodec mpeg4_decoder; -extern AVCodec mpeg4aac_decoder; -extern AVCodec mpeg_xvmc_decoder; -extern AVCodec mpegvideo_decoder; -extern AVCodec msmpeg4v1_decoder; -extern AVCodec msmpeg4v2_decoder; -extern AVCodec msmpeg4v3_decoder; -extern AVCodec msrle_decoder; -extern AVCodec msvideo1_decoder; -extern AVCodec mszh_decoder; -extern AVCodec nuv_decoder; -extern AVCodec oggvorbis_decoder; -extern AVCodec png_decoder; -extern AVCodec qdm2_decoder; -extern AVCodec qdraw_decoder; -extern AVCodec qpeg_decoder; -extern AVCodec qtrle_decoder; -extern AVCodec ra_144_decoder; -extern AVCodec ra_288_decoder; -extern AVCodec roq_decoder; -extern AVCodec roq_dpcm_decoder; -extern AVCodec rpza_decoder; -extern AVCodec rv10_decoder; -extern AVCodec rv20_decoder; -extern AVCodec rv30_decoder; -extern AVCodec rv40_decoder; -extern AVCodec shorten_decoder; -extern AVCodec smackaud_decoder; -extern AVCodec smacker_decoder; -extern AVCodec smc_decoder; -extern AVCodec snow_decoder; -extern AVCodec sol_dpcm_decoder; -extern AVCodec sonic_decoder; -extern AVCodec sp5x_decoder; -extern AVCodec svq1_decoder; -extern AVCodec svq3_decoder; -extern AVCodec targa_decoder; -extern AVCodec theora_decoder; -extern AVCodec tiertexseqvideo_decoder; -extern AVCodec tiff_decoder; -extern AVCodec truemotion1_decoder; -extern AVCodec truemotion2_decoder; -extern AVCodec truespeech_decoder; -extern AVCodec tscc_decoder; -extern AVCodec tta_decoder; -extern AVCodec ulti_decoder; -extern AVCodec vc1_decoder; -extern AVCodec vcr1_decoder; -extern AVCodec vmdaudio_decoder; -extern AVCodec vmdvideo_decoder; -extern AVCodec vmnc_decoder; -extern AVCodec vorbis_decoder; -extern AVCodec vp3_decoder; -extern AVCodec vp5_decoder; -extern AVCodec vp6_decoder; -extern AVCodec vp6f_decoder; -extern AVCodec vqa_decoder; -extern AVCodec wavpack_decoder; -extern AVCodec wmav1_decoder; -extern AVCodec wmav2_decoder; -extern AVCodec wmv1_decoder; -extern AVCodec wmv2_decoder; -extern AVCodec wmv3_decoder; -extern AVCodec wnv1_decoder; -extern AVCodec ws_snd1_decoder; -extern AVCodec xan_dpcm_decoder; -extern AVCodec xan_wc3_decoder; -extern AVCodec xl_decoder; -extern AVCodec zlib_decoder; -extern AVCodec zmbv_decoder; - -/* pcm codecs */ -#define PCM_CODEC(id, name) \ -extern AVCodec name ## _decoder; \ -extern AVCodec name ## _encoder - -PCM_CODEC(CODEC_ID_PCM_ALAW, pcm_alaw); -PCM_CODEC(CODEC_ID_PCM_MULAW, pcm_mulaw); -PCM_CODEC(CODEC_ID_PCM_S8, pcm_s8); -PCM_CODEC(CODEC_ID_PCM_S16BE, pcm_s16be); -PCM_CODEC(CODEC_ID_PCM_S16LE, pcm_s16le); -PCM_CODEC(CODEC_ID_PCM_S24BE, pcm_s24be); -PCM_CODEC(CODEC_ID_PCM_S24DAUD, pcm_s24daud); -PCM_CODEC(CODEC_ID_PCM_S24LE, pcm_s24le); -PCM_CODEC(CODEC_ID_PCM_S32BE, pcm_s32be); -PCM_CODEC(CODEC_ID_PCM_S32LE, pcm_s32le); -PCM_CODEC(CODEC_ID_PCM_U8, pcm_u8); -PCM_CODEC(CODEC_ID_PCM_U16BE, pcm_u16be); -PCM_CODEC(CODEC_ID_PCM_U16LE, pcm_u16le); -PCM_CODEC(CODEC_ID_PCM_U24BE, pcm_u24be); -PCM_CODEC(CODEC_ID_PCM_U24LE, pcm_u24le); -PCM_CODEC(CODEC_ID_PCM_U32BE, pcm_u32be); -PCM_CODEC(CODEC_ID_PCM_U32LE, pcm_u32le); - -/* adpcm codecs */ - -PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm); -PCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx); -PCM_CODEC(CODEC_ID_ADPCM_CT, adpcm_ct); -PCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea); -PCM_CODEC(CODEC_ID_ADPCM_G726, adpcm_g726); -PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); -PCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); -PCM_CODEC(CODEC_ID_ADPCM_IMA_QT, adpcm_ima_qt); -PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav); -PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws); -PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms); -PCM_CODEC(CODEC_ID_ADPCM_SBPRO_2, adpcm_sbpro_2); -PCM_CODEC(CODEC_ID_ADPCM_SBPRO_3, adpcm_sbpro_3); -PCM_CODEC(CODEC_ID_ADPCM_SBPRO_4, adpcm_sbpro_4); -PCM_CODEC(CODEC_ID_ADPCM_SMJPEG, adpcm_ima_smjpeg); -PCM_CODEC(CODEC_ID_ADPCM_SWF, adpcm_swf); -PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa); -PCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); - -#undef PCM_CODEC - -/* dummy raw video codec */ -extern AVCodec rawvideo_decoder; -extern AVCodec rawvideo_encoder; - -/* the following codecs use external GPL libs */ -extern AVCodec ac3_decoder; -extern AVCodec dts_decoder; - -/* subtitles */ -extern AVCodec dvbsub_decoder; -extern AVCodec dvbsub_encoder; -extern AVCodec dvdsub_decoder; -extern AVCodec dvdsub_encoder; - -/* resample.c */ - -struct ReSampleContext; -struct AVResampleContext; - -typedef struct ReSampleContext ReSampleContext; - -ReSampleContext *audio_resample_init(int output_channels, int input_channels, - int output_rate, int input_rate); -int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); -void audio_resample_close(ReSampleContext *s); - -struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff); -int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); -void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); -void av_resample_close(struct AVResampleContext *c); - -/* YUV420 format is assumed ! */ - -struct ImgReSampleContext; - -typedef struct ImgReSampleContext ImgReSampleContext; - -ImgReSampleContext *img_resample_init(int output_width, int output_height, - int input_width, int input_height); - -ImgReSampleContext *img_resample_full_init(int owidth, int oheight, - int iwidth, int iheight, - int topBand, int bottomBand, - int leftBand, int rightBand, - int padtop, int padbottom, - int padleft, int padright); - - -void img_resample(ImgReSampleContext *s, - AVPicture *output, const AVPicture *input); - -void img_resample_close(ImgReSampleContext *s); - -/** - * Allocate memory for a picture. Call avpicture_free to free it. - * - * @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 0 if successful, -1 if not. - */ -int avpicture_alloc(AVPicture *picture, int pix_fmt, int width, int height); - -/* Free a picture previously allocated by avpicture_alloc. */ -void avpicture_free(AVPicture *picture); - -int avpicture_fill(AVPicture *picture, uint8_t *ptr, - int pix_fmt, int width, int height); -int avpicture_layout(const AVPicture* src, int pix_fmt, int width, int height, - unsigned char *dest, int dest_size); -int avpicture_get_size(int pix_fmt, int width, int height); -void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift); -const char *avcodec_get_pix_fmt_name(int pix_fmt); -void avcodec_set_dimensions(AVCodecContext *s, int width, int height); -enum PixelFormat avcodec_get_pix_fmt(const char* name); -unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat p); - -#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) */ - -int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt, - int has_alpha); -int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt, - int has_alpha, int *loss_ptr); - -#define FF_ALPHA_TRANSP 0x0001 /* image has some totally transparent pixels */ -#define FF_ALPHA_SEMI_TRANSP 0x0002 /* image has some transparent pixels */ -int img_get_alpha_info(const AVPicture *src, - int pix_fmt, int width, int height); - -/* convert among pixel formats */ -int img_convert(AVPicture *dst, int dst_pix_fmt, - const AVPicture *src, int pix_fmt, - int width, int height); - -/* deinterlace a picture */ -int avpicture_deinterlace(AVPicture *dst, const AVPicture *src, - int pix_fmt, int width, int height); - -/* external high level API */ - -extern AVCodec *first_avcodec; - -/* returns LIBAVCODEC_VERSION_INT constant */ -unsigned avcodec_version(void); -/* returns LIBAVCODEC_BUILD constant */ -unsigned avcodec_build(void); -void avcodec_init(void); - -void register_avcodec(AVCodec *format); -AVCodec *avcodec_find_encoder(enum CodecID id); -AVCodec *avcodec_find_encoder_by_name(const char *name); -AVCodec *avcodec_find_decoder(enum CodecID id); -AVCodec *avcodec_find_decoder_by_name(const char *name); -void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); - -void avcodec_get_context_defaults(AVCodecContext *s); -AVCodecContext *avcodec_alloc_context(void); -void avcodec_get_frame_defaults(AVFrame *pic); -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); -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 avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void **arg, int *ret, int count); -//FIXME func typedef - -/** - * opens / inits the AVCodecContext. - * not thread save! - */ -int avcodec_open(AVCodecContext *avctx, AVCodec *codec); - - -attribute_deprecated int avcodec_decode_audio(AVCodecContext *avctx, int16_t *samples, - int *frame_size_ptr, - uint8_t *buf, int buf_size); -/** - * Decode an audio frame. - * - * @param avctx the codec context. - * @param samples output buffer, 16 byte aligned - * @param frame_size_ptr the output buffer size in bytes (you MUST set this to the allocated size before calling avcodec_decode_audio2()), zero if no frame could be compressed - * @param buf input buffer, 16 byte aligned - * @param buf_size the input buffer size - * @return 0 if successful, -1 if not. - */ -int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, - int *frame_size_ptr, - uint8_t *buf, int buf_size); -int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, - int *got_picture_ptr, - uint8_t *buf, int buf_size); -int avcodec_decode_subtitle(AVCodecContext *avctx, AVSubtitle *sub, - int *got_sub_ptr, - const uint8_t *buf, int buf_size); -int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, - int *data_size_ptr, - uint8_t *buf, int buf_size); -int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, - const short *samples); -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); - -int avcodec_close(AVCodecContext *avctx); - -void avcodec_register_all(void); - -void avcodec_flush_buffers(AVCodecContext *avctx); - -void avcodec_default_free_buffers(AVCodecContext *s); - -/* misc usefull functions */ - -/** - * returns a single letter to describe the picture type - */ -char av_get_pict_type_char(int pict_type); - -/** - * returns codec bits per sample - */ -int av_get_bits_per_sample(enum CodecID codec_id); - -/* 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 last_frame_offset; /* offset of the last frame */ - /* video info */ - int pict_type; /* XXX: put it back in AVCodecContext */ - 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 -} 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, - 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; - -extern AVCodecParser *av_first_parser; - -void av_register_codec_parser(AVCodecParser *parser); -AVCodecParserContext *av_parser_init(int codec_id); -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); -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); - -extern AVCodecParser aac_parser; -extern AVCodecParser ac3_parser; -extern AVCodecParser cavsvideo_parser; -extern AVCodecParser dvbsub_parser; -extern AVCodecParser dvdsub_parser; -extern AVCodecParser h261_parser; -extern AVCodecParser h263_parser; -extern AVCodecParser h264_parser; -extern AVCodecParser mjpeg_parser; -extern AVCodecParser mpeg4video_parser; -extern AVCodecParser mpegaudio_parser; -extern AVCodecParser mpegvideo_parser; -extern AVCodecParser pnm_parser; -extern AVCodecParser vc1_parser; - - -typedef struct AVBitStreamFilterContext { - void *priv_data; - struct AVBitStreamFilter *filter; - AVCodecParserContext *parser; - struct AVBitStreamFilterContext *next; -} AVBitStreamFilterContext; - - -typedef struct AVBitStreamFilter { - const char *name; - int priv_data_size; - int (*filter)(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe); - struct AVBitStreamFilter *next; -} AVBitStreamFilter; - -extern AVBitStreamFilter *av_first_bitstream_filter; - -void av_register_bitstream_filter(AVBitStreamFilter *bsf); -AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); -int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, - AVCodecContext *avctx, const char *args, - uint8_t **poutbuf, int *poutbuf_size, - const uint8_t *buf, int buf_size, int keyframe); -void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); - -extern AVBitStreamFilter dump_extradata_bsf; -extern AVBitStreamFilter remove_extradata_bsf; -extern AVBitStreamFilter noise_bsf; -extern AVBitStreamFilter mp3_header_compress_bsf; -extern AVBitStreamFilter mp3_header_decompress_bsf; -extern AVBitStreamFilter mjpega_dump_header_bsf; - - -/* memory */ -void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); -/* for static data only */ -/* call av_free_static to release all staticaly allocated tables */ -void av_free_static(void); -void *av_mallocz_static(unsigned int size); -void *av_realloc_static(void *ptr, unsigned int size); - -void img_copy(AVPicture *dst, const AVPicture *src, - int pix_fmt, int width, int height); - -int img_crop(AVPicture *dst, const AVPicture *src, - int pix_fmt, int top_band, int left_band); - -int img_pad(AVPicture *dst, const AVPicture *src, int height, int width, int pix_fmt, - int padtop, int padbottom, int padleft, int padright, int *color); - -extern unsigned int av_xiphlacing(unsigned char *s, unsigned int v); - -#ifdef __cplusplus -} -#endif - -#endif /* AVCODEC_H */ diff --git a/extra_lib/include/ffmpeg/avformat.h b/extra_lib/include/ffmpeg/avformat.h deleted file mode 100644 index 38099d4..0000000 --- a/extra_lib/include/ffmpeg/avformat.h +++ /dev/null @@ -1,549 +0,0 @@ -/* - * copyright (c) 2001 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 AVFORMAT_H -#define AVFORMAT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define LIBAVFORMAT_VERSION_INT ((51<<16)+(8<<8)+0) -#define LIBAVFORMAT_VERSION 51.8.0 -#define LIBAVFORMAT_BUILD LIBAVFORMAT_VERSION_INT - -#define LIBAVFORMAT_IDENT "Lavf" AV_STRINGIFY(LIBAVFORMAT_VERSION) - -#include -#include /* FILE */ -#include "avcodec.h" - -#include "avio.h" - -/* packet functions */ - -typedef struct AVPacket { - int64_t pts; ///< presentation time stamp in time_base units - int64_t dts; ///< decompression time stamp in time_base units - uint8_t *data; - int size; - int stream_index; - int flags; - int duration; ///< presentation duration in time_base units (0 if not available) - void (*destruct)(struct AVPacket *); - void *priv; - int64_t pos; ///< byte position in stream, -1 if unknown -} AVPacket; -#define PKT_FLAG_KEY 0x0001 - -void av_destruct_packet_nofree(AVPacket *pkt); -void av_destruct_packet(AVPacket *pkt); - -/* initialize optional fields of a packet */ -static inline void av_init_packet(AVPacket *pkt) -{ - pkt->pts = AV_NOPTS_VALUE; - pkt->dts = AV_NOPTS_VALUE; - pkt->pos = -1; - pkt->duration = 0; - pkt->flags = 0; - pkt->stream_index = 0; - pkt->destruct= av_destruct_packet_nofree; -} - -int av_new_packet(AVPacket *pkt, int size); -int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size); -int av_dup_packet(AVPacket *pkt); - -/** - * Free a packet - * - * @param pkt packet to free - */ -static inline void av_free_packet(AVPacket *pkt) -{ - if (pkt && pkt->destruct) { - pkt->destruct(pkt); - } -} - -/*************************************************/ -/* fractional numbers for exact pts handling */ - -/* the exact value of the fractional number is: 'val + num / den'. num - is assumed to be such as 0 <= num < den */ -typedef struct AVFrac { - int64_t val, num, den; -} AVFrac attribute_deprecated; - -/*************************************************/ -/* input/output formats */ - -struct AVCodecTag; - -struct AVFormatContext; - -/* this structure contains the data a format has to probe a file */ -typedef struct AVProbeData { - const char *filename; - unsigned char *buf; - int buf_size; -} AVProbeData; - -#define AVPROBE_SCORE_MAX 100 ///< max score, half of that is used for file extension based detection - -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 *device; /* video, audio or DV device */ - const char *standard; /* tv standard, NTSC, PAL, SECAM */ - int mpeg2ts_raw:1; /* force raw MPEG2 transport stream output, if possible */ - int mpeg2ts_compute_pcr:1; /* compute exact PCR for each transport - stream packet (only meaningful if - mpeg2ts_raw is TRUE */ - int initial_pause:1; /* do not begin to play the stream - immediately (RTSP only) */ - int prealloced_context:1; - enum CodecID video_codec_id; - enum CodecID audio_codec_id; -} AVFormatParameters; - -//! demuxer will use url_fopen, 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 */ -#define AVFMT_RAWPICTURE 0x0020 /* format wants AVPicture structure for - raw picture data */ -#define AVFMT_GLOBALHEADER 0x0040 /* format wants global header */ -#define AVFMT_NOTIMESTAMPS 0x0080 /* format doesnt need / has any timestamps */ -#define AVFMT_GENERIC_INDEX 0x0100 /* use generic index building code */ - -typedef struct AVOutputFormat { - const char *name; - const char *long_name; - const char *mime_type; - const char *extensions; /* comma separated 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 */ - 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 CODEC_ID_NONE terminated - */ - const struct AVCodecTag **codec_tag; - - /* private fields */ - struct AVOutputFormat *next; -} AVOutputFormat; - -typedef struct AVInputFormat { - const char *name; - const char *long_name; - /* 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 parsing by this format */ - int (*read_probe)(AVProbeData *); - /* read the format header and initialize the AVFormatContext - structure. Return 0 if OK. 'ap' if non NULL contains - additionnal paramters. 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. */ - int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); - /* close the stream. The AVFormatContext and AVStreams are not - freed by this function */ - int (*read_close)(struct AVFormatContext *); - /** - * seek to a given timestamp relative to the frames in - * stream component stream_index - * @param stream_index must not be -1 - * @param flags selects which direction should be preferred if no exact - * match is available - */ - int (*read_seek)(struct AVFormatContext *, - int stream_index, int64_t timestamp, int flags); - /** - * gets the next timestamp in AV_TIME_BASE units. - */ - 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) */ - int (*read_play)(struct AVFormatContext *); - - /* pause playing - only meaningful if using a network based format - (RTSP) */ - int (*read_pause)(struct AVFormatContext *); - - const struct AVCodecTag **codec_tag; - - /* private fields */ - struct AVInputFormat *next; -} AVInputFormat; - -typedef struct AVIndexEntry { - int64_t pos; - int64_t timestamp; -#define AVINDEX_KEYFRAME 0x0001 - int flags:2; - int size:30; //yeah trying to keep the size of this small to reduce memory requirements (its 24 vs 32 byte due to possible 8byte align) - int min_distance; /* min distance between this and the previous keyframe, used to avoid unneeded searching */ -} AVIndexEntry; - -typedef struct AVStream { - int index; /* stream index in AVFormatContext */ - int id; /* format specific stream id */ - AVCodecContext *codec; /* codec context */ - /** - * real base frame rate of the stream. - * this is the lowest framerate with which all timestamps can be - * represented accurately (its the least common multiple of all - * framerates in the stream), Note, this value is just a guess! - * for example if the timebase is 1/90000 and all frames have either - * approximately 3600 or 1800 timer ticks then r_frame_rate will be 50/1 - */ - AVRational r_frame_rate; - void *priv_data; - /* internal data used in av_find_stream_info() */ - int64_t codec_info_duration; - int codec_info_nb_frames; - /* encoding: PTS generation when outputing stream */ - AVFrac pts; - - /** - * 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. - */ - AVRational time_base; - int pts_wrap_bits; /* number of bits in pts (used for wrapping control) */ - /* ffmpeg.c private use */ - int stream_copy; /* if TRUE, just copy stream */ - enum AVDiscard discard; ///< selects which packets can be discarded at will and dont 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 thats the right place, for it */ - float quality; - /* decoding: position of the first frame of the component, in - AV_TIME_BASE fractional seconds. */ - int64_t start_time; - /* decoding: duration of the stream, in AV_TIME_BASE fractional - seconds. */ - int64_t duration; - - char language[4]; /* ISO 639 3-letter language code (empty string if undefined) */ - - /* av_read_frame() support */ - int need_parsing; ///< 1->full parsing needed, 2->only parse headers dont repack - 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 - -#define MAX_REORDER_DELAY 4 - int64_t pts_buffer[MAX_REORDER_DELAY+1]; -} AVStream; - -#define AVFMTCTX_NOHEADER 0x0001 /* signal that no header is present - (streams are added dynamically) */ - -#define MAX_STREAMS 20 - -/* format I/O context */ -typedef struct AVFormatContext { - const AVClass *av_class; /* set by av_alloc_format_context */ - /* can only be iformat or oformat, not both at the same time */ - struct AVInputFormat *iformat; - struct AVOutputFormat *oformat; - 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; - 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 */ - - 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. */ - 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; - const uint8_t *cur_ptr; - int cur_len; - AVPacket cur_pkt; - - /* av_seek_frame() support */ - int64_t data_offset; /* offset of the first packet */ - int index_built; - - int mux_rate; - int packet_size; - int preload; - 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 pts if missing even if it requires parsing future frames -#define AVFMT_FLAG_IGNIDX 0x0002 ///< ignore index - - int loop_input; - /* decoding: size of data to probe; encoding unused */ - unsigned int probesize; - - /** - * maximum duration in AV_TIME_BASE units over which the input should be analyzed in av_find_stream_info() - */ - int max_analyze_duration; -} AVFormatContext; - -typedef struct AVPacketList { - AVPacket pkt; - struct AVPacketList *next; -} AVPacketList; - -extern AVInputFormat *first_iformat; -extern AVOutputFormat *first_oformat; - -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); -enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, - const char *filename, const char *mime_type, enum CodecType type); - -void av_hex_dump(FILE *f, uint8_t *buf, int size); -void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); - -void av_register_all(void); - -/* codec tag <-> codec id */ -enum CodecID av_codec_get_id(const struct AVCodecTag **tags, unsigned int tag); -unsigned int av_codec_get_tag(const struct AVCodecTag **tags, enum CodecID id); - -/* media file input */ -AVInputFormat *av_find_input_format(const char *short_name); -AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); -int av_open_input_stream(AVFormatContext **ic_ptr, - ByteIOContext *pb, const char *filename, - AVInputFormat *fmt, AVFormatParameters *ap); -int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, - AVInputFormat *fmt, - int buf_size, - AVFormatParameters *ap); -/* no av_open for output, so applications will need this: */ -AVFormatContext *av_alloc_format_context(void); - -#define AVERROR_UNKNOWN (-1) /* unknown error */ -#define AVERROR_IO (-2) /* i/o error */ -#define AVERROR_NUMEXPECTED (-3) /* number syntax expected in filename */ -#define AVERROR_INVALIDDATA (-4) /* invalid data found */ -#define AVERROR_NOMEM (-5) /* not enough memory */ -#define AVERROR_NOFMT (-6) /* unknown format */ -#define AVERROR_NOTSUPP (-7) /* operation not supported */ - -int av_find_stream_info(AVFormatContext *ic); -int av_read_packet(AVFormatContext *s, AVPacket *pkt); -int av_read_frame(AVFormatContext *s, AVPacket *pkt); -int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags); -int av_read_play(AVFormatContext *s); -int av_read_pause(AVFormatContext *s); -void av_close_input_file(AVFormatContext *s); -AVStream *av_new_stream(AVFormatContext *s, int id); -void av_set_pts_info(AVStream *s, int pts_wrap_bits, - int pts_num, int pts_den); - -#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); -int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); -int av_add_index_entry(AVStream *st, - int64_t pos, int64_t timestamp, int size, int distance, int flags); -int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags); -void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); -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); -int av_write_header(AVFormatContext *s); -int av_write_frame(AVFormatContext *s, AVPacket *pkt); -int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); -int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush); - -int av_write_trailer(AVFormatContext *s); - -void dump_format(AVFormatContext *ic, - int index, - const char *url, - int is_output); -int parse_image_size(int *width_ptr, int *height_ptr, const char *str); -int parse_frame_rate(int *frame_rate, int *frame_rate_base, const char *arg); -int64_t parse_date(const char *datestr, int duration); - -int64_t av_gettime(void); - -/* ffm specific for ffserver */ -#define FFM_PACKET_SIZE 4096 -offset_t ffm_read_write_index(int fd); -void ffm_write_write_index(int fd, offset_t pos); -void ffm_set_write_index(AVFormatContext *s, offset_t pos, offset_t file_size); - -int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); - -int av_get_frame_filename(char *buf, int buf_size, - const char *path, int number); -int av_filename_number_test(const char *filename); - -/* grab specific */ -int video_grab_init(void); -int audio_init(void); - -/* DV1394 */ -int dv1394_init(void); -int dc1394_init(void); - -#ifdef HAVE_AV_CONFIG_H - -#include "os_support.h" - -int strstart(const char *str, const char *val, const char **ptr); -int stristart(const char *str, const char *val, const char **ptr); -void pstrcpy(char *buf, int buf_size, const char *str); -char *pstrcat(char *buf, int buf_size, const char *s); - -void __dynarray_add(unsigned long **tab_ptr, int *nb_ptr, unsigned long elem); - -#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 */\ - __dynarray_add((unsigned long **)_tab, nb_ptr, (unsigned long)_elem);\ -} while(0) -#else -#define dynarray_add(tab, nb_ptr, elem)\ -do {\ - __dynarray_add((unsigned long **)(tab), nb_ptr, (unsigned long)(elem));\ -} while(0) -#endif - -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); - -struct in_addr; -int resolve_host(struct in_addr *sin_addr, const char *hostname); - -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); - -int match_ext(const char *filename, const char *extensions); - -#endif /* HAVE_AV_CONFIG_H */ - -#ifdef __cplusplus -} -#endif - -#endif /* AVFORMAT_H */ - diff --git a/extra_lib/include/ffmpeg/avio.h b/extra_lib/include/ffmpeg/avio.h deleted file mode 100644 index f44d526..0000000 --- a/extra_lib/include/ffmpeg/avio.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * unbuffered io for ffmpeg system - * copyright (c) 2001 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 AVIO_H -#define AVIO_H - -/* output byte stream handling */ - -typedef int64_t offset_t; - -/* unbuffered I/O */ - -struct URLContext { - 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; -#if LIBAVFORMAT_VERSION_INT >= (52<<16) - char *filename; /* specified filename */ -#else - char filename[1]; /* specified filename */ -#endif -}; - -typedef struct URLContext 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(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); -offset_t url_seek(URLContext *h, offset_t pos, int whence); -int url_close(URLContext *h); -int url_exist(const char *filename); -offset_t url_filesize(URLContext *h); -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. -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); - -/** - * passing this as the "whence" parameter to a seek function causes it to - * return the filesize without seeking anywhere, supporting this is optional - * if its not supprted 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); - offset_t (*url_seek)(URLContext *h, offset_t pos, int whence); - int (*url_close)(URLContext *h); - struct URLProtocol *next; -} URLProtocol; - -extern URLProtocol *first_protocol; -extern URLInterruptCB *url_interrupt_cb; - -int register_protocol(URLProtocol *protocol); - -typedef struct { - unsigned char *buffer; - int buffer_size; - unsigned char *buf_ptr, *buf_end; - void *opaque; - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); - offset_t (*seek)(void *opaque, offset_t offset, int whence); - offset_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; - 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 -} ByteIOContext; - -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), - offset_t (*seek)(void *opaque, offset_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 put_strz(ByteIOContext *s, const char *buf); - -offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence); -void url_fskip(ByteIOContext *s, offset_t offset); -offset_t url_ftell(ByteIOContext *s); -offset_t url_fsize(ByteIOContext *s); -int url_feof(ByteIOContext *s); -int url_ferror(ByteIOContext *s); - -#define URL_EOF (-1) -int url_fgetc(ByteIOContext *s); -#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 -char *url_fgets(ByteIOContext *s, char *buf, int buf_size); - -void put_flush_packet(ByteIOContext *s); - -int get_buffer(ByteIOContext *s, unsigned char *buf, int size); -int get_partial_buffer(ByteIOContext *s, unsigned char *buf, int size); -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); - -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); - -static inline int url_is_streamed(ByteIOContext *s) -{ - return s->is_streamed; -} - -int url_fdopen(ByteIOContext *s, URLContext *h); -int url_setbufsize(ByteIOContext *s, int buf_size); -int url_fopen(ByteIOContext *s, const char *filename, int flags); -int url_fclose(ByteIOContext *s); -URLContext *url_fileno(ByteIOContext *s); -int url_fget_max_packet_size(ByteIOContext *s); - -int url_open_buf(ByteIOContext *s, uint8_t *buf, int buf_size, int flags); -int url_close_buf(ByteIOContext *s); - -int url_open_dyn_buf(ByteIOContext *s); -int url_open_dyn_packet_buf(ByteIOContext *s, int max_packet_size); -int url_close_dyn_buf(ByteIOContext *s, uint8_t **pbuffer); - -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); - -/* file.c */ -extern URLProtocol file_protocol; -extern URLProtocol pipe_protocol; - -/* udp.c */ -extern URLProtocol udp_protocol; -int udp_set_remote_url(URLContext *h, const char *uri); -int udp_get_local_port(URLContext *h); -int udp_get_file_handle(URLContext *h); - -/* tcp.c */ -extern URLProtocol tcp_protocol; - -/* http.c */ -extern URLProtocol http_protocol; - -#endif - diff --git a/extra_lib/include/ffmpeg/avutil.h b/extra_lib/include/ffmpeg/avutil.h deleted file mode 100644 index d85755c..0000000 --- a/extra_lib/include/ffmpeg/avutil.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * copyright (c) 2006 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_H -#define AVUTIL_H - -/** - * @file avutil.h - * external api header. - */ - - -#ifdef __cplusplus -extern "C" { -#endif - -#define AV_STRINGIFY(s) AV_TOSTRING(s) -#define AV_TOSTRING(s) #s - -#define LIBAVUTIL_VERSION_INT ((49<<16)+(3<<8)+0) -#define LIBAVUTIL_VERSION 49.3.0 -#define LIBAVUTIL_BUILD LIBAVUTIL_VERSION_INT - -#define LIBAVUTIL_IDENT "Lavu" AV_STRINGIFY(LIBAVUTIL_VERSION) - - -#include "common.h" -#include "mathematics.h" -#include "rational.h" -#include "integer.h" -#include "intfloat_readwrite.h" -#include "log.h" - -/** - * Pixel format. Notes: - * - * PIX_FMT_RGB32 is handled in an endian-specific manner. A 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. - * - * 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] and, is 1024 bytes long (256 4-byte entries) and is - * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is - * also endian-specific). Note also that the individual RGB palette - * components stored in AVFrame.data[1] should be in the range 0..255. - * 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. - */ -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_RGB32, ///< Packed RGB 8:8:8, 32bpp, (msb)8A 8R 8G 8B(lsb), in cpu endianness - 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_RGB565, ///< Packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), in cpu endianness - PIX_FMT_RGB555, ///< Packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), in cpu endianness most significant bit to 0 - PIX_FMT_GRAY8, ///< Y , 8bpp - PIX_FMT_MONOWHITE, ///< Y , 1bpp, 1 is white - PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black - 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(xvmc_render.h) - 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_BGR32, ///< Packed RGB 8:8:8, 32bpp, (msb)8A 8B 8G 8R(lsb), in cpu endianness - PIX_FMT_BGR565, ///< Packed RGB 5:6:5, 16bpp, (msb) 5B 6G 5R(lsb), in cpu endianness - PIX_FMT_BGR555, ///< Packed RGB 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), in cpu endianness most significant bit to 1 - 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)2R 3G 3B(lsb) - PIX_FMT_RGB4_BYTE, ///< Packed RGB 1:2:1, 8bpp, (msb)2R 3G 3B(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_RGB32_1, ///< Packed RGB 8:8:8, 32bpp, (msb)8R 8G 8B 8A(lsb), in cpu endianness - PIX_FMT_BGR32_1, ///< Packed RGB 8:8:8, 32bpp, (msb)8B 8G 8R 8A(lsb), in cpu endianness - - PIX_FMT_GRAY16BE, ///< Y , 16bpp, big-endian - PIX_FMT_GRAY16LE, ///< Y , 16bpp, 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 -}; - -#ifdef WORDS_BIGENDIAN -#define PIX_FMT_RGBA PIX_FMT_RGB32_1 -#define PIX_FMT_BGRA PIX_FMT_BGR32_1 -#define PIX_FMT_ARGB PIX_FMT_RGB32 -#define PIX_FMT_ABGR PIX_FMT_BGR32 -#define PIX_FMT_GRAY16 PIX_FMT_GRAY16BE -#else -#define PIX_FMT_RGBA PIX_FMT_BGR32 -#define PIX_FMT_BGRA PIX_FMT_RGB32 -#define PIX_FMT_ARGB PIX_FMT_BGR32_1 -#define PIX_FMT_ABGR PIX_FMT_RGB32_1 -#define PIX_FMT_GRAY16 PIX_FMT_GRAY16LE -#endif - -#if LIBAVUTIL_VERSION_INT < (50<<16) -#define PIX_FMT_UYVY411 PIX_FMT_UYYVYY411 -#define PIX_FMT_RGBA32 PIX_FMT_RGB32 -#define PIX_FMT_YUV422 PIX_FMT_YUYV422 -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* AVUTIL_H */ diff --git a/extra_lib/include/ffmpeg/common.h b/extra_lib/include/ffmpeg/common.h deleted file mode 100644 index d75bb5f..0000000 --- a/extra_lib/include/ffmpeg/common.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * copyright (c) 2006 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 - */ - -/** - * @file common.h - * common internal and external api header. - */ - -#ifndef COMMON_H -#define COMMON_H - -#if (defined(WIN32) || defined(_WIN32_WCE) ) && !defined(__MINGW32__) && !defined(__CYGWIN__) -# define CONFIG_MSVC -#endif - -/*THIS CONFIG IS FOR WINCE ONLY!!*/ -#ifdef CONFIG_MSVC -#define CONFIG_WIN32 -#define EMULATE_INTTYPES -#define CONFIG_ALIGN -#define inline __inline - -#ifdef _WIN32_WCE -#define perror(n) -#endif - -#elif defined(__SYMBIAN32__) -#define EMULATE_INTTYPES -#endif - -#ifdef HAVE_AV_CONFIG_H -/* only include the following when compiling package */ -# include "config.h" - -# include -# include -# include -# include -# include -# ifndef _WIN32_WCE -# ifndef __BEOS__ -# include -# else -# include "berrno.h" -# endif -# endif -# include -#endif /* HAVE_AV_CONFIG_H */ - -#ifndef EMULATE_INTTYPES -# include -#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 av_always_inline -#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) -# define av_always_inline __attribute__((always_inline)) inline -#else -# define av_always_inline inline -#endif -#endif - -#ifdef HAVE_AV_CONFIG_H -# include "internal.h" -#endif /* HAVE_AV_CONFIG_H */ - -#ifndef attribute_deprecated -#if defined(__GNUC__) && (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ > 0) -# define attribute_deprecated __attribute__((deprecated)) -#else -# define attribute_deprecated -#endif -#endif - -#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 - -//rounded divison & 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 FFABS(a) ((a) >= 0 ? (a) : (-(a))) -#define FFSIGN(a) ((a) > 0 ? 1 : -1) - -#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) -#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) - -#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) - -/* misc math functions */ -extern const uint8_t ff_log2_tab[256]; - -static inline int av_log2(unsigned int v) -{ - int n; - - n = 0; - if (v & 0xffff0000) { - v >>= 16; - n += 16; - } - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} - -static inline int av_log2_16bit(unsigned int v) -{ - int n; - - n = 0; - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += ff_log2_tab[v]; - - return n; -} - -/* median of 3 */ -static inline int mid_pred(int a, int b, int c) -{ -#ifdef HAVE_CMOV - int i=b; - asm volatile( - "cmp %2, %1 \n\t" - "cmovg %1, %0 \n\t" - "cmovg %2, %1 \n\t" - "cmp %3, %1 \n\t" - "cmovl %3, %1 \n\t" - "cmp %1, %0 \n\t" - "cmovg %1, %0 \n\t" - :"+&r"(i), "+&r"(a) - :"r"(b), "r"(c) - ); - return i; -#elif 0 - int t= (a-b)&((a-b)>>31); - a-=t; - b+=t; - b-= (b-c)&((b-c)>>31); - b+= (a-b)&((a-b)>>31); - - return b; -#else - if(a>b){ - if(c>b){ - if(c>a) b=a; - else b=c; - } - }else{ - if(b>c){ - if(c>a) b=c; - else b=a; - } - } - return b; -#endif -} - -/** - * 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 int clip(int a, int amin, int amax) -{ - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -/** - * clip a signed integer value into the 0-255 range - * @param a value to clip - * @return clipped value - */ -static inline uint8_t clip_uint8(int a) -{ - if (a&(~255)) return (-a)>>31; - else return a; -} - -/* math */ -int64_t ff_gcd(int64_t a, int64_t b); - -/** - * converts fourcc string to int - */ -static inline int ff_get_fourcc(const char *s){ -#ifdef HAVE_AV_CONFIG_H - assert( strlen(s)==4 ); -#endif - - return (s[0]) + (s[1]<<8) + (s[2]<<16) + (s[3]<<24); -} - -#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. - */ -#define GET_UTF8(val, GET_BYTE, ERROR)\ - val= GET_BYTE;\ - {\ - int ones= 7 - av_log2(val ^ 255);\ - if(ones==1)\ - ERROR\ - val&= 127>>ones;\ - while(--ones > 0){\ - int tmp= GET_BYTE - 128;\ - if(tmp>>6)\ - ERROR\ - val= (val<<6) + tmp;\ - }\ - } - -/*! - * \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 - * a ucs4 encoded unicode character that is to be converted to utf-8. If - * val is given as a function it's executed only once. - * \param tmp is a temporary variable and should be of type uint8_t. It - * represents an intermediate value during conversion that is to be - * outputted by PUT_BYTE. - * \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 - * 7 times in the general case, depending on the length of the converted - * unicode character. - */ -#define PUT_UTF8(val, tmp, PUT_BYTE)\ - {\ - int bytes, shift;\ - uint32_t in = val;\ - if (in < 0x80) {\ - tmp = in;\ - PUT_BYTE\ - } else {\ - bytes = (av_log2(in) + 4) / 5;\ - shift = (bytes - 1) * 6;\ - tmp = (256 - (256 >> bytes)) | (in >> shift);\ - PUT_BYTE\ - while (shift >= 6) {\ - shift -= 6;\ - tmp = 0x80 | ((in >> shift) & 0x3f);\ - PUT_BYTE\ - }\ - }\ - } - -#if defined(ARCH_X86) || defined(ARCH_POWERPC) -#if defined(ARCH_X86_64) -static inline uint64_t read_time(void) -{ - uint64_t a, d; - asm volatile( "rdtsc\n\t" - : "=a" (a), "=d" (d) - ); - return (d << 32) | (a & 0xffffffff); -} -#elif defined(ARCH_X86_32) -static inline long long read_time(void) -{ - long long l; - asm volatile( "rdtsc\n\t" - : "=A" (l) - ); - return l; -} -#else //FIXME check ppc64 -static inline uint64_t read_time(void) -{ - uint32_t tbu, tbl, temp; - - /* from section 2.2.1 of the 32-bit PowerPC PEM */ - __asm__ __volatile__( - "1:\n" - "mftbu %2\n" - "mftb %0\n" - "mftbu %1\n" - "cmpw %2,%1\n" - "bne 1b\n" - : "=r"(tbl), "=r"(tbu), "=r"(temp) - : - : "cc"); - - return (((uint64_t)tbu)<<32) | (uint64_t)tbl; -} -#endif - -#define START_TIMER \ -uint64_t tend;\ -uint64_t tstart= read_time();\ - -#define STOP_TIMER(id) \ -tend= read_time();\ -{\ - static uint64_t tsum=0;\ - static int tcount=0;\ - static int tskip_count=0;\ - if(tcount<2 || tend - tstart < 8*tsum/tcount){\ - tsum+= tend - tstart;\ - tcount++;\ - }else\ - tskip_count++;\ - if(((tcount+tskip_count)&(tcount+tskip_count-1))==0){\ - av_log(NULL, AV_LOG_DEBUG, "%"PRIu64" dezicycles in %s, %d runs, %d skips\n", tsum*10/tcount, id, tcount, tskip_count);\ - }\ -} -#else -#define START_TIMER -#define STOP_TIMER(id) {} -#endif - -/* memory */ - -#ifdef __GNUC__ - #define DECLARE_ALIGNED(n,t,v) t v __attribute__ ((aligned (n))) -#else - #define DECLARE_ALIGNED(n,t,v) __declspec(align(n)) t v -#endif - -/* memory */ -void *av_malloc(unsigned int size); -void *av_realloc(void *ptr, unsigned int size); -void av_free(void *ptr); - -void *av_mallocz(unsigned int size); -char *av_strdup(const char *s); -void av_freep(void *ptr); - -#ifndef restrict -# define restrict -#endif - -#if defined(CONFIG_MSVC) || defined(__SYMBIAN32__) -typedef int64_t int_fast64_t; -typedef uint64_t uint_fast64_t; -typedef int32_t int_fast32_t; -typedef uint32_t uint_fast32_t; -typedef int16_t int_fast16_t; -typedef uint16_t uint_fast16_t; -typedef int8_t int_fast8_t; -typedef uint8_t uint_fast8_t; -#endif - -#endif /* COMMON_H */ - diff --git a/extra_lib/include/ffmpeg/integer.h b/extra_lib/include/ffmpeg/integer.h deleted file mode 100644 index a50ad9b..0000000 --- a/extra_lib/include/ffmpeg/integer.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * arbitrary precision integers - * Copyright (c) 2004 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 - * - */ - -/** - * @file integer.h - * arbitrary precision integers - * @author Michael Niedermayer - */ - -#ifndef INTEGER_H -#define INTEGER_H - -#define AV_INTEGER_SIZE 8 - -typedef struct AVInteger{ - uint16_t v[AV_INTEGER_SIZE]; -} AVInteger; - -AVInteger av_add_i(AVInteger a, AVInteger b); -AVInteger av_sub_i(AVInteger a, AVInteger b); -int av_log2_i(AVInteger a); -AVInteger av_mul_i(AVInteger a, AVInteger b); -int av_cmp_i(AVInteger a, AVInteger b); -AVInteger av_shr_i(AVInteger a, int s); -AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b); -AVInteger av_div_i(AVInteger a, AVInteger b); -AVInteger av_int2i(int64_t a); -int64_t av_i2int(AVInteger a); - -#endif // INTEGER_H diff --git a/extra_lib/include/ffmpeg/intfloat_readwrite.h b/extra_lib/include/ffmpeg/intfloat_readwrite.h deleted file mode 100644 index c535b64..0000000 --- a/extra_lib/include/ffmpeg/intfloat_readwrite.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * copyright (c) 2005 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 INTFLOAT_READWRITE_H -#define INTFLOAT_READWRITE_H - -#include "common.h" - -/* IEEE 80 bits extended float */ -typedef struct AVExtFloat { - uint8_t exponent[2]; - uint8_t mantissa[8]; -} AVExtFloat; - -double av_int2dbl(int64_t v); -float av_int2flt(int32_t v); -double av_ext2dbl(const AVExtFloat ext); -int64_t av_dbl2int(double d); -int32_t av_flt2int(float d); -AVExtFloat av_dbl2ext(double d); - -#endif /* INTFLOAT_READWRITE_H */ diff --git a/extra_lib/include/ffmpeg/log.h b/extra_lib/include/ffmpeg/log.h deleted file mode 100644 index 56ca012..0000000 --- a/extra_lib/include/ffmpeg/log.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * copyright (c) 2006 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 LOG_H -#define LOG_H - -#include - -/** - * Used by av_log - */ -typedef struct AVCLASS AVClass; -struct AVCLASS { - const char* class_name; - const char* (*item_name)(void*); /* actually passing a pointer to an AVCodecContext - or AVFormatContext, which begin with an AVClass. - Needed because av_log is in libavcodec and has no visibility - of AVIn/OutputFormat */ - const struct AVOption *option; -}; - -/* av_log API */ - -#if LIBAVUTIL_VERSION_INT < (50<<16) -#define AV_LOG_QUIET -1 -#define AV_LOG_FATAL 0 -#define AV_LOG_ERROR 0 -#define AV_LOG_WARNING 1 -#define AV_LOG_INFO 1 -#define AV_LOG_VERBOSE 1 -#define AV_LOG_DEBUG 2 -#else -#define AV_LOG_QUIET -8 - -/** - * something went really wrong and we will crash now - */ -#define AV_LOG_PANIC 0 - -/** - * something went wrong and recovery is not possible - * like no header in a format which depends on it or a combination - * of parameters which are not allowed - */ -#define AV_LOG_FATAL 8 - -/** - * something went wrong and cannot losslessly be recovered - * but not all future data is affected - */ -#define AV_LOG_ERROR 16 - -/** - * something somehow does not look correct / something which may or may not - * lead to some problems like use of -vstrict -2 - */ -#define AV_LOG_WARNING 24 - -#define AV_LOG_INFO 32 -#define AV_LOG_VERBOSE 40 - -/** - * stuff which is only useful for libav* developers - */ -#define AV_LOG_DEBUG 48 -#endif -extern int av_log_level; - -#ifdef __GNUC__ -extern void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); -#else -extern void av_log(void*, int level, const char *fmt, ...); -#endif - -#if LIBAVUTIL_VERSION_INT < (50<<16) -extern void av_vlog(void*, int level, const char *fmt, va_list); -extern int av_log_get_level(void); -extern void av_log_set_level(int); -extern void av_log_set_callback(void (*)(void*, int, const char*, va_list)); -extern void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); -#else -extern void (*av_vlog)(void*, int, const char*, va_list); -#endif - -#endif /* LOG_H */ diff --git a/extra_lib/include/ffmpeg/mathematics.h b/extra_lib/include/ffmpeg/mathematics.h deleted file mode 100644 index 0b74b25..0000000 --- a/extra_lib/include/ffmpeg/mathematics.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * copyright (c) 2005 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 MATHEMATICS_H -#define MATHEMATICS_H - -#include "rational.h" - -enum AVRounding { - AV_ROUND_ZERO = 0, ///< round toward zero - AV_ROUND_INF = 1, ///< round away from zero - AV_ROUND_DOWN = 2, ///< round toward -infinity - AV_ROUND_UP = 3, ///< round toward +infinity - AV_ROUND_NEAR_INF = 5, ///< round to nearest and halfway cases away from zero -}; - -/** - * rescale a 64bit 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); - -/** - * rescale a 64bit 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); - -/** - * rescale a 64bit integer by 2 rational numbers. - */ -int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq); - -#endif /* MATHEMATICS_H */ diff --git a/extra_lib/include/ffmpeg/rational.h b/extra_lib/include/ffmpeg/rational.h deleted file mode 100644 index 1bbfd13..0000000 --- a/extra_lib/include/ffmpeg/rational.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Rational numbers - * Copyright (c) 2003 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 - * - */ - -/** - * @file rational.h - * Rational numbers. - * @author Michael Niedermayer - */ - -#ifndef RATIONAL_H -#define RATIONAL_H - -/** - * Rational number num/den. - */ -typedef struct AVRational{ - int num; ///< numerator - int den; ///< denominator -} AVRational; - -static inline AVRational _AVRational(int num,int den) -{ - AVRational r; - r.num = num; - r.den = den; - return r; -} - -/** - * returns 0 if a==b, 1 if a>b and -1 if a>63)|1; - else return 0; -} - -/** - * converts the given AVRational to a double. - */ -static inline double av_q2d(AVRational a){ - return a.num / (double) a.den; -} - -/** - * reduce a fraction. - * this is usefull for framerate calculations - * @param max the maximum allowed for dst_nom & dst_den - * @return 1 if exact, 0 otherwise - */ -int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max); - -AVRational av_mul_q(AVRational b, AVRational c); -AVRational av_div_q(AVRational b, AVRational c); -AVRational av_add_q(AVRational b, AVRational c); -AVRational av_sub_q(AVRational b, AVRational c); -AVRational av_d2q(double d, int max); - -#endif // RATIONAL_H diff --git a/extra_lib/include/js/jsautocfg.h b/extra_lib/include/js/jsautocfg.h index a7f5d6b..7dccf19 100644 --- a/extra_lib/include/js/jsautocfg.h +++ b/extra_lib/include/js/jsautocfg.h @@ -47,4 +47,6 @@ #define JS_BYTES_PER_DWORD_LOG2 3L #define JS_WORDS_PER_DWORD_LOG2 1L +#define JS_STACK_GROWTH_DIRECTION (-1) + #endif /* js_cpucfg___ */ diff --git a/extra_lib/include/libavcodec/avcodec.h b/extra_lib/include/libavcodec/avcodec.h new file mode 100644 index 0000000..682c522 --- /dev/null +++ b/extra_lib/include/libavcodec/avcodec.h @@ -0,0 +1,3714 @@ +/* + * copyright (c) 2001 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 AVCODEC_AVCODEC_H +#define AVCODEC_AVCODEC_H + +/** + * @file libavcodec/avcodec.h + * external API header + */ + +#ifndef _WIN32_WCE +#include +#endif +#include "libavutil/avutil.h" + +#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) + +#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. + * 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. + * There may be slight deviations from the principle due to implementation + * details. + * + * 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. + */ +enum CodecID { + 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, + + /* 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, + + /* 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, + + /* 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_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, + + /* 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, + + /* other specific kind of codecs (generally used for attachments) */ + CODEC_ID_TTF= 0x18000, + + 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) */ +}; + +enum CodecType { + CODEC_TYPE_UNKNOWN = -1, + CODEC_TYPE_VIDEO, + CODEC_TYPE_AUDIO, + CODEC_TYPE_DATA, + CODEC_TYPE_SUBTITLE, + CODEC_TYPE_ATTACHMENT, + CODEC_TYPE_NB +}; + +/** + * all in native-endian format + */ +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 +}; + +/* 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) + +/* in bytes */ +#define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio + +/** + * 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.
      + * 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 + +/** + * minimum encoding buffer size + * Used to avoid some checks during header writing. + */ +#define FF_MIN_BUFFER_SIZE 16384 + + +/** + * motion estimation type. + */ +enum Motion_Est_ID { + ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed + ME_FULL, + ME_LOG, + ME_PHODS, + ME_EPZS, ///< enhanced predictive zonal search + ME_X1, ///< reserved for experiments + ME_HEX, ///< hexagon based search + ME_UMH, ///< uneven multi-hexagon search + ME_ITER, ///< iterative search + ME_TESA, ///< transformed exhaustive search algorithm +}; + +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 +}; + +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 +}; + +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 +}; + +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 +}; + +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 +}; + +/** + * X X 3 4 X X are luma samples, + * 1 2 1-6 are possible chroma positions + * 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 +}; + +typedef struct RcOverride{ + int start_frame; + int end_frame; + int qscale; // If this is 0 then quality_factor will be used instead. + float quality_factor; +} RcOverride; + +#define FF_MAX_B_FRAMES 16 + +/* encoding support + These flags can be passed in AVCodecContext.flags before initialization. + Note: Not everything is supported yet. +*/ + +#define CODEC_FLAG_QSCALE 0x0002 ///< Use fixed qscale. +#define CODEC_FLAG_4MV 0x0004 ///< 4 MV per MB allowed / advanced prediction for H.263. +#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 + * this is not set the input will be copied. + */ +#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. +#define CODEC_FLAG_TRUNCATED 0x00010000 /** Input bitstream might be truncated at a random + location instead of only at frame boundaries. */ +#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_SKIP_RD 0x00004000 ///< RD optimal MB level residual skipping +#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 + +/* Unsupported options : + * Syntax Arithmetic coding (SAC) + * Reference Picture Selection + * Independent Segment Decoding */ +/* /Fx */ +/* codec capabilities */ + +#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 + */ +#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. + */ +#define CODEC_CAP_DELAY 0x0020 +/** + * Codec can be fed a final frame with a smaller size. + * This can be used to prevent truncation of the last audio samples. + */ +#define CODEC_CAP_SMALL_LAST_FRAME 0x0040 +/** + * Codec can export data for HW decoding (VDPAU). + */ +#define CODEC_CAP_HWACCEL_VDPAU 0x0080 + +//The following defines may change, don't expect compatibility if you use them. +#define MB_TYPE_INTRA4x4 0x0001 +#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific +#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific +#define MB_TYPE_16x16 0x0008 +#define MB_TYPE_16x8 0x0010 +#define MB_TYPE_8x16 0x0020 +#define MB_TYPE_8x8 0x0040 +#define MB_TYPE_INTERLACED 0x0080 +#define MB_TYPE_DIRECT2 0x0100 //FIXME +#define MB_TYPE_ACPRED 0x0200 +#define MB_TYPE_GMC 0x0400 +#define MB_TYPE_SKIP 0x0800 +#define MB_TYPE_P0L0 0x1000 +#define MB_TYPE_P1L0 0x2000 +#define MB_TYPE_P0L1 0x4000 +#define MB_TYPE_P1L1 0x8000 +#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0) +#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1) +#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1) +#define MB_TYPE_QUANT 0x00010000 +#define MB_TYPE_CBP 0x00020000 +//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...) + +/** + * Pan Scan area. + * This specifies the area which should be displayed. + * Note there may be multiple such areas for one frame. + */ +typedef struct AVPanScan{ + /** + * id + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int id; + + /** + * width and height in 1/16 pel + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int width; + int height; + + /** + * position of the top left corner in 1/16 pel for up to 3 fields/frames + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + 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_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). + +typedef struct AVPacket { + /** + * Presentation timestamp in AVStream->time_base units; the time at which + * the decompressed packet will be presented to the user. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + * pts MUST be larger or equal to dts as presentation cannot happen before + * decompression, unless one wants to view hex dumps. Some formats misuse + * the terms dts and pts/cts to mean something different. Such timestamps + * must be converted to true pts/dts before they are stored in AVPacket. + */ + int64_t pts; + /** + * Decompression timestamp in AVStream->time_base units; the time at which + * the packet is decompressed. + * Can be AV_NOPTS_VALUE if it is not stored in the file. + */ + int64_t dts; + uint8_t *data; + int size; + int stream_index; + int flags; + /** + * Duration of this packet in AVStream->time_base units, 0 if unknown. + * Equals next_pts - this_pts in presentation order. + */ + int duration; + void (*destruct)(struct AVPacket *); + void *priv; + int64_t pos; ///< byte position in stream, -1 if unknown + + /** + * Time difference in AVStream->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 packet. + * + * 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; +} AVPacket; +#define PKT_FLAG_KEY 0x0001 + +/** + * 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*. + */ +typedef struct AVFrame { + FF_COMMON_FRAME +} AVFrame; + +/** + * 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 + */ + const AVClass *av_class; + /** + * 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. + */ + int bit_rate; + + /** + * 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 + */ + int bit_rate_tolerance; + + /** + * CODEC_FLAG_*. + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags; + + /** + * 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. + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. (FIXME: Is this OK?) + */ + int sub_id; + + /** + * 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 + */ + int me_method; + + /** + * 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. + */ + uint8_t *extradata; + int extradata_size; + + /** + * 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. + */ + AVRational time_base; + + /* video only */ + /** + * 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. + */ + int width, height; + +#define FF_ASPECT_EXTENDED 15 + + /** + * the number of pictures in a group of pictures, or 0 for intra_only + * - encoding: Set by user. + * - decoding: unused + */ + int gop_size; + + /** + * Pixel format, see PIX_FMT_xxx. + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum PixelFormat pix_fmt; + + /** + * 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 + */ + int rate_emu; + + /** + * 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. + * - 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 + */ + 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 + + /** + * audio sample format + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + enum SampleFormat sample_fmt; ///< sample format, currently unused + + /* The following data should not be initialized. */ + /** + * Samples per packet, initialized when calling 'init'. + */ + int frame_size; + int frame_number; ///< audio or video frame number + int real_pict_num; ///< Returns the real picture number of previous encoded frame. + + /** + * Number of frames the decoded output will be delayed relative to + * the encoded input. + * - encoding: Set by libavcodec. + * - decoding: unused + */ + int delay; + + /* - 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 qmin; + + /** + * maximum quantizer + * - encoding: Set by user. + * - decoding: unused + */ + int qmax; + + /** + * maximum quantizer difference between frames + * - encoding: Set by user. + * - decoding: unused + */ + int max_qdiff; + + /** + * 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 + */ + int max_b_frames; + + /** + * 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 + */ + float b_quant_factor; + + /** obsolete FIXME remove */ + int rc_strategy; +#define FF_RC_STRATEGY_XVID 1 + + int b_frame_strategy; + + /** + * hurry up amount + * - 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. + */ + 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; + + /** + * number of bits used for the previously encoded frame + * - encoding: Set by libavcodec. + * - decoding: unused + */ + int frame_bits; + + /** + * Private data of the user, can be used to carry app specific stuff. + * - encoding: Set by user. + * - decoding: Set by user. + */ + void *opaque; + + char codec_name[32]; + enum CodecType codec_type; /* see CODEC_TYPE_xxx */ + enum CodecID codec_id; /* see CODEC_ID_xxx */ + + /** + * 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. + */ + unsigned int codec_tag; + + /** + * 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_FAKE_SCALABILITY 16 //Autodetection should work 100%. + + /** + * luma single coefficient elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ + int luma_elim_threshold; + + /** + * chroma single coeff elimination threshold + * - encoding: Set by user. + * - decoding: unused + */ + int chroma_elim_threshold; + + /** + * 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) + */ + 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. + + /** + * qscale offset between IP and B-frames + * - encoding: Set by user. + * - decoding: unused + */ + float b_quant_offset; + + /** + * Error recognization; 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; +#define FF_ER_CAREFUL 1 +#define FF_ER_COMPLIANT 2 +#define FF_ER_AGGRESSIVE 3 +#define FF_ER_VERY_AGGRESSIVE 4 + + /** + * 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. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ + 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. + * - encoding: unused + * - decoding: Set by libavcodec., user can override. + */ + void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * 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 has_b_frames; + + /** + * number of bytes per packet if constant and known or 0 + * Used by some WAV based audio codecs. + */ + int block_align; + + 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. */ + + /** + * 0-> h263 quant 1-> mpeg quant + * - encoding: Set by user. + * - decoding: unused + */ + int mpeg_quant; + + /** + * pass1 encoding statistics output buffer + * - encoding: Set by libavcodec. + * - decoding: unused + */ + char *stats_out; + + /** + * pass2 encoding statistics input buffer + * Concatenated stuff from stats_out of pass1 should be placed here. + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + char *stats_in; + + /** + * 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 + */ + float rc_qsquish; + + float rc_qmod_amp; + int rc_qmod_freq; + + /** + * ratecontrol override, see RcOverride + * - encoding: Allocated/set/freed by user. + * - decoding: unused + */ + RcOverride *rc_override; + int rc_override_count; + + /** + * rate control equation + * - encoding: Set by user + * - decoding: unused + */ + const char *rc_eq; + + /** + * maximum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int rc_max_rate; + + /** + * minimum bitrate + * - encoding: Set by user. + * - decoding: unused + */ + int rc_min_rate; + + /** + * decoder bitstream buffer size + * - encoding: Set by user. + * - decoding: unused + */ + int rc_buffer_size; + float rc_buffer_aggressivity; + + /** + * 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 + */ + float i_quant_factor; + + /** + * qscale offset between P and I-frames + * - encoding: Set by user. + * - decoding: unused + */ + float i_quant_offset; + + /** + * initial complexity for pass1 ratecontrol + * - encoding: Set by user. + * - decoding: unused + */ + float rc_initial_cplx; + + /** + * 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 + + /** + * 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; + + /** + * IDCT algorithm, see FF_IDCT_* below. + * - encoding: Set by user. + * - decoding: Set by user. + */ + 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 + + /** + * slice count + * - 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). + */ + int *slice_offset; + + /** + * error concealment flags + * - encoding: unused + * - decoding: Set by user. + */ + int error_concealment; +#define FF_EC_GUESS_MVS 1 +#define FF_EC_DEBLOCK 2 + + /** + * 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.) + */ + 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 + + /** + * bits per sample/pixel from the demuxer (needed for huffyuv). + * - encoding: Set by libavcodec. + * - decoding: Set by user. + */ + int bits_per_coded_sample; + + /** + * 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 + + /** + * 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; + + /** + * the picture in the bitstream + * - encoding: Set by libavcodec. + * - decoding: Set by libavcodec. + */ + AVFrame *coded_frame; + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + 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 + + /** + * debug + * - encoding: Set by user. + * - decoding: Set by user. + */ + 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 + + /** + * error + * - encoding: Set by libavcodec if flags&CODEC_FLAG_PSNR. + * - decoding: unused + */ + uint64_t error[4]; + + /** + * minimum MB quantizer + * - encoding: unused + * - decoding: unused + */ + int mb_qmin; + + /** + * maximum MB quantizer + * - encoding: unused + * - decoding: unused + */ + int mb_qmax; + + /** + * 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 + */ + int pre_me; + + /** + * motion estimation prepass comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int me_pre_cmp; + + /** + * ME prepass diamond size & shape + * - encoding: Set by user. + * - decoding: unused + */ + int pre_dia_size; + + /** + * subpel ME quality + * - encoding: Set by user. + * - decoding: unused + */ + 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) + * 0 if not set. + * + * - encoding: unused + * - decoding: Set by decoder. + */ + int dtg_active_format; +#define FF_DTG_AFD_SAME 8 +#define FF_DTG_AFD_4_3 9 +#define FF_DTG_AFD_16_9 10 +#define FF_DTG_AFD_14_9 11 +#define FF_DTG_AFD_4_3_SP_14_9 13 +#define FF_DTG_AFD_16_9_SP_14_9 14 +#define FF_DTG_AFD_SP_4_3 15 + + /** + * maximum motion estimation search range in subpel units + * If 0 then no limit. + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_range; + + /** + * intra quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + int intra_quant_bias; +#define FF_DEFAULT_QUANT_BIAS 999999 + + /** + * inter quantizer bias + * - encoding: Set by user. + * - decoding: unused + */ + int inter_quant_bias; + + /** + * 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< ('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. + * - encoding: Set by user. + * - decoding: unused + */ + int scenechange_threshold; + + /** + * minimum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int lmin; + + /** + * maximum Lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int lmax; + + /** + * palette control structure + * - encoding: ??? (no palette-enabled encoder yet) + * - decoding: Set by user. + */ + struct AVPaletteControl *palctrl; + + /** + * noise reduction strength + * - encoding: Set by user. + * - decoding: unused + */ + int noise_reduction; + + /** + * 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(). + * - encoding: unused + * - decoding: Set by libavcodec., user can override + */ + int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic); + + /** + * Number of bits which should be loaded into the rc buffer before decoding starts. + * - encoding: Set by user. + * - decoding: unused + */ + int rc_initial_buffer_occupancy; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int inter_threshold; + + /** + * CODEC_FLAG2_* + * - encoding: Set by user. + * - decoding: Set by user. + */ + int flags2; + + /** + * Simulates errors in the bitstream to test error concealment. + * - encoding: Set by user. + * - decoding: unused + */ + int error_rate; + + /** + * MP3 antialias algorithm, see FF_AA_* below. + * - encoding: unused + * - decoding: Set by user. + */ + 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 + /** + * quantizer noise shaping + * - encoding: Set by user. + * - decoding: unused + */ + int quantizer_noise_shaping; + + /** + * 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; + + /** + * 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); + + /** + * thread opaque + * Can be used by execute() to store some per AVCodecContext stuff. + * - encoding: set by execute() + * - decoding: set by execute() + */ + void *thread_opaque; + + /** + * 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 me_threshold; + + /** + * Macroblock threshold below which the user specified macroblock types will be used. + * - encoding: Set by user. + * - decoding: unused + */ + int mb_threshold; + + /** + * precision of the intra DC coefficient - 8 + * - encoding: Set by user. + * - decoding: unused + */ + int intra_dc_precision; + + /** + * noise vs. sse weight for the nsse comparsion function + * - encoding: Set by user. + * - decoding: unused + */ + int nsse_weight; + + /** + * Number of macroblock rows at the top which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_top; + + /** + * Number of macroblock rows at the bottom which are skipped. + * - encoding: unused + * - decoding: Set by user. + */ + int skip_bottom; + + /** + * profile + * - 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 + + /** + * level + * - encoding: Set by user. + * - decoding: Set by libavcodec. + */ + int level; +#define FF_LEVEL_UNKNOWN -99 + + /** + * low resolution decoding, 1-> 1/2 size, 2->1/4 size + * - encoding: unused + * - decoding: Set by user. + */ + int lowres; + + /** + * 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. + */ + int coded_width, coded_height; + + /** + * frame skip threshold + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_threshold; + + /** + * frame skip factor + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_factor; + + /** + * frame skip exponent + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_exp; + + /** + * frame skip comparison function + * - encoding: Set by user. + * - decoding: unused + */ + int frame_skip_cmp; + + /** + * Border processing masking, raises the quantizer for mbs on the borders + * of the picture. + * - encoding: Set by user. + * - decoding: unused + */ + float border_masking; + + /** + * minimum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmin; + + /** + * maximum MB lagrange multipler + * - encoding: Set by user. + * - decoding: unused + */ + int mb_lmax; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int me_penalty_compensation; + + /** + * + * - 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; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int bidir_refine; + + /** + * + * - encoding: Set by user. + * - decoding: unused + */ + int brd_scale; + + /** + * constant rate factor - quality-based VBR - values ~correspond to qps + * - encoding: Set by user. + * - decoding: unused + */ + float crf; + + /** + * constant quantization parameter rate control method + * - encoding: Set by user. + * - decoding: unused + */ + int cqp; + + /** + * minimum GOP size + * - encoding: Set by user. + * - decoding: unused + */ + int keyint_min; + + /** + * number of reference frames + * - encoding: Set by user. + * - decoding: Set by lavc. + */ + int refs; + + /** + * chroma qp offset from luma + * - encoding: Set by user. + * - decoding: unused + */ + int chromaoffset; + + /** + * Influences how often B-frames are used. + * - encoding: Set by user. + * - decoding: unused + */ + int bframebias; + + /** + * trellis RD quantization + * - encoding: Set by user. + * - decoding: unused + */ + int trellis; + + /** + * Reduce fluctuations in qp (before curve compression). + * - encoding: Set by user. + * - decoding: unused + */ + float complexityblur; + + /** + * in-loop deblocking filter alphac0 parameter + * alpha is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + int deblockalpha; + + /** + * in-loop deblocking filter beta parameter + * beta is in the range -6...6 + * - encoding: Set by user. + * - decoding: unused + */ + int deblockbeta; + + /** + * macroblock subpartition sizes to consider - p8x8, p4x4, b8x8, i8x8, i4x4 + * - encoding: Set by user. + * - 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 */ + + /** + * direct MV prediction mode - 0 (none), 1 (spatial), 2 (temporal), 3 (auto) + * - encoding: Set by user. + * - decoding: unused + */ + int directpred; + + /** + * Audio cutoff bandwidth (0 means "automatic") + * - encoding: Set by user. + * - decoding: unused + */ + int cutoff; + + /** + * Multiplied by qscale for each frame and added to scene_change_score. + * - encoding: Set by user. + * - decoding: unused + */ + int scenechange_factor; + + /** + * + * Note: Value depends upon the compare function used for fullpel ME. + * - encoding: Set by user. + * - decoding: unused + */ + int mv0_threshold; + + /** + * Adjusts sensitivity of b_frame_strategy 1. + * - encoding: Set by user. + * - decoding: unused + */ + int b_sensitivity; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int compression_level; +#define FF_COMPRESSION_DEFAULT -1 + + /** + * Sets whether to use LPC mode - used by FLAC encoder. + * - encoding: Set by user. + * - decoding: unused + */ + int use_lpc; + + /** + * LPC coefficient precision - used by FLAC encoder + * - encoding: Set by user. + * - decoding: unused + */ + int lpc_coeff_precision; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int min_prediction_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int max_prediction_order; + + /** + * search method for selecting prediction order + * - encoding: Set by user. + * - decoding: unused + */ + int prediction_order_method; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int min_partition_order; + + /** + * - encoding: Set by user. + * - decoding: unused + */ + int max_partition_order; + + /** + * GOP timecode frame start number, in non drop frame format + * - encoding: Set by user. + * - decoding: unused + */ + int64_t timecode_frame_start; + +#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. + */ + int request_channels; +#endif + + /** + * Percentage of dynamic range compression to be applied by the decoder. + * The default value is 1.0, corresponding to full compression. + * - encoding: unused + * - decoding: Set by user. + */ + float drc_scale; + + /** + * opaque 64bit number (generally a PTS) that will be reordered and + * output in AVFrame.reordered_opaque + * - encoding: unused + * - decoding: Set by user. + */ + int64_t reordered_opaque; + + /** + * 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. + */ + int bits_per_raw_sample; + + /** + * Audio channel layout. + * - encoding: set by user. + * - decoding: set by libavcodec. + */ + int64_t channel_layout; + + /** + * Request decoder to use this channel layout if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + */ + int64_t request_channel_layout; + + /** + * Ratecontrol attempt to use, at maximum, 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, times the amount needed to prevent a vbv overflow. + * - encoding: Set by user. + * - decoding: unused. + */ + float rc_min_vbv_overflow_use; + + /** + * Hardware accelerator in use + * - encoding: unused. + * - decoding: Set by libavcodec + */ + 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 + * provided by the user. In that case, this holds display-dependent + * data FFmpeg cannot instantiate itself. Please refer to the + * FFmpeg HW accelerator documentation to know how to fill this + * is. e.g. for VA API, this is a struct vaapi_context. + * - encoding: unused + * - decoding: Set by user + */ + void *hwaccel_context; + + /** + * Chromaticity coordinates of the source primaries. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorPrimaries color_primaries; + + /** + * Color Transfer Characteristic. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorSpace colorspace; + + /** + * MPEG vs JPEG YUV range. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVColorRange color_range; + + /** + * This defines the location of chroma samples. + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + enum AVChromaLocation chroma_sample_location; +} AVCodecContext; + +/** + * 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; + 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); + /** + * Codec capabilities. + * see CODEC_CAP_* + */ + int capabilities; + struct AVCodec *next; + /** + * 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; + +/** + * AVHWAccel. + */ +typedef struct AVHWAccel { + /** + * Name of the hardware accelerated codec. + * The name is globally unique among encoders and among decoders (but an + * encoder and a decoder can share the same name). + */ + const char *name; + + /** + * Type of codec implemented by the hardware accelerator. + * + * See CODEC_TYPE_xxx + */ + enum CodecType type; + + /** + * Codec implemented by the hardware accelerator. + * + * See CODEC_ID_xxx + */ + enum CodecID id; + + /** + * Supported pixel format. + * + * Only hardware accelerated formats are supported here. + */ + enum PixelFormat pix_fmt; + + /** + * Hardware accelerated codec capabilities. + * see FF_HWACCEL_CODEC_CAP_* + */ + int capabilities; + + struct AVHWAccel *next; + + /** + * Called at the beginning of each frame or field picture. + * + * 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. + * Otherwise, this means the whole frame is available at this point. + * + * @param avctx the codec context + * @param buf the frame data buffer base + * @param buf_size the size of the frame in bytes + * @return zero if successful, a negative value otherwise + */ + int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Callback for each slice. + * + * Meaningful slice information (codec specific) is guaranteed to + * be parsed at this point. This function is mandatory. + * + * @param avctx the codec context + * @param buf the slice data buffer base + * @param buf_size the size of the slice in bytes + * @return zero if successful, a negative value otherwise + */ + int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size); + + /** + * Called at the end of each frame or field picture. + * + * The whole picture is parsed at this point and can now be sent + * to the hardware accelerator. This function is mandatory. + * + * @param avctx the codec context + * @return zero if successful, a negative value otherwise + */ + int (*end_frame)(AVCodecContext *avctx); + + /** + * Size of HW accelerator private data. + * + * Private data is allocated with av_mallocz() before + * AVCodecContext.get_buffer() and deallocated after + * AVCodecContext.release_buffer(). + */ + int priv_data_size; +} AVHWAccel; + +/** + * 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 +} 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, + + SUBTITLE_BITMAP, ///< A bitmap, pict will be set + + /** + * Plain text, the text field must be set by the decoder and is + * authoritative. ass and pict fields may contain approximations. + */ + SUBTITLE_TEXT, + + /** + * Formatted text, the ass field must be set by the decoder and is + * authoritative. pict and text fields may contain approximations. + */ + SUBTITLE_ASS, +}; + +typedef struct AVSubtitleRect { + int x; ///< top left corner of pict, undefined when pict is not set + int y; ///< top left corner of pict, undefined when pict is not set + int w; ///< width of pict, undefined when pict is not set + int h; ///< height of pict, undefined when pict is not set + int nb_colors; ///< number of colors in pict, undefined when pict is not set + + /** + * data+linesize for the bitmap of this subtitle. + * can be set for text/ass as well once they where rendered + */ + AVPicture pict; + enum AVSubtitleType type; + + char *text; ///< 0 terminated plain UTF-8 text + + /** + * 0 terminated ASS/SSA compatible event line. + * The pressentation of this is unaffected by the other values in this + * struct. + */ + char *ass; +} AVSubtitleRect; + +typedef struct AVSubtitle { + uint16_t format; /* 0 = graphics */ + uint32_t start_display_time; /* relative to packet pts, in ms */ + uint32_t end_display_time; /* relative to packet pts, in ms */ + unsigned num_rects; + AVSubtitleRect **rects; +} AVSubtitle; + +/* packet functions */ + +/** + * @deprecated use NULL instead + */ +attribute_deprecated void av_destruct_packet_nofree(AVPacket *pkt); + +/** + * Default packet destructor. + */ +void av_destruct_packet(AVPacket *pkt); + +/** + * Initialize optional fields of a packet with default values. + * + * @param pkt packet + */ +void av_init_packet(AVPacket *pkt); + +/** + * 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 + */ +int av_new_packet(AVPacket *pkt, int size); + +/** + * Reduce packet size, correctly zeroing padding + * + * @param pkt packet + * @param size new size + */ +void av_shrink_packet(AVPacket *pkt, int size); + +/** + * @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); + +/** + * Free a packet. + * + * @param pkt packet to free + */ +void av_free_packet(AVPacket *pkt); + +/* resample.c */ + +struct ReSampleContext; +struct AVResampleContext; + +typedef struct ReSampleContext ReSampleContext; + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * @deprecated Use av_audio_resample_init() instead. + */ +attribute_deprecated ReSampleContext *audio_resample_init(int output_channels, int input_channels, + int output_rate, int input_rate); +#endif +/** + * Initializes 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 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 + */ +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 audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples); +void audio_resample_close(ReSampleContext *s); + + +/** + * 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 + */ +int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx); + + +/** + * 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 + * + * example: av_resample_compensate(c, 10, 500) + * here instead of 510 samples only 500 samples would be output + * + * 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 av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance); +void av_resample_close(struct AVResampleContext *c); + +/** + * Allocate memory for a picture. Call avpicture_free to free it. + * + * @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 + */ +int avpicture_alloc(AVPicture *picture, enum PixelFormat pix_fmt, int width, int height); + +/** + * Free a picture previously allocated by avpicture_alloc(). + * + * @param picture the AVPicture to be freed + */ +void avpicture_free(AVPicture *picture); + +/** + * 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. + * + * @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 + */ +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); + +/** + * 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); + +/** + * Returns the pixel format corresponding to the name \p name. + * + * 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". + * + * Finally if no pixel format has been found, returns \c PIX_FMT_NONE. + */ +enum PixelFormat avcodec_get_pix_fmt(const char* name); +unsigned int avcodec_pix_fmt_to_codec_tag(enum PixelFormat p); + +#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) */ + +/** + * 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. + * + * @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. + */ +int avcodec_get_pix_fmt_loss(enum PixelFormat dst_pix_fmt, enum PixelFormat src_pix_fmt, + int has_alpha); + +/** + * 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. + * + * @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[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. + */ +enum PixelFormat avcodec_find_best_pix_fmt(int64_t pix_fmt_mask, enum PixelFormat src_pix_fmt, + int has_alpha, int *loss_ptr); + + +/** + * Print in buf the string corresponding to the pixel format with + * number pix_fmt, or an header if pix_fmt is negative. + * + * @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. + */ +void avcodec_pix_fmt_string (char *buf, int buf_size, enum PixelFormat pix_fmt); + +#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 + */ +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 */ + +/** + * 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. + */ +AVCodec *av_codec_next(AVCodec *c); + +/** + * Returns the LIBAVCODEC_VERSION_INT constant. + */ +unsigned avcodec_version(void); + +/** + * Initializes libavcodec. + * + * @warning This function \e must be called before any other libavcodec + * function. + */ +void avcodec_init(void); + +#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() + */ +void avcodec_register(AVCodec *codec); + +/** + * Finds a registered encoder with a matching codec ID. + * + * @param id CodecID of the requested encoder + * @return An encoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_encoder(enum CodecID id); + +/** + * Finds 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); + +/** + * Finds a registered decoder with a matching codec ID. + * + * @param id CodecID of the requested decoder + * @return A decoder if one was found, NULL otherwise. + */ +AVCodec *avcodec_find_decoder(enum CodecID id); + +/** + * Finds 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); +void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode); + +/** + * Sets the fields of the given AVCodecContext to default values. + * + * @param s The AVCodecContext of which the fields should be set to default values. + */ +void avcodec_get_context_defaults(AVCodecContext *s); + +/** 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); + +/** + * 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 + */ +AVCodecContext *avcodec_alloc_context(void); + +/** 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); + +/** + * 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(). + * + * @return An AVFrame filled with default values or NULL on failure. + * @see avcodec_get_frame_defaults + */ +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. + * + * @param[in] w Width of the picture. + * @param[in] h Height of the picture. + * @return Zero if valid, a negative value if invalid. + */ +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 + +/** + * 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 + */ +int avcodec_open(AVCodecContext *avctx, AVCodec *codec); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Decodes an audio frame from \p buf into \p samples. + * Wrapper function which calls avcodec_decode_audio3. + * + * @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. + */ +attribute_deprecated int avcodec_decode_audio2(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + const uint8_t *buf, int buf_size); +#endif + +/** + * 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(). + * + * @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 avpkt->data should be set to 0 to ensure that + * no overreading happens for damaged MPEG streams. + * + * @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. + * + * @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. + */ +int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples, + int *frame_size_ptr, + AVPacket *avpkt); + +#if LIBAVCODEC_VERSION_MAJOR < 53 +/** + * Decodes a video frame from \p buf into \p picture. + * Wrapper function which calls avcodec_decode_video2. + * + * @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. + */ +attribute_deprecated int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + const uint8_t *buf, int buf_size); +#endif + +/** + * 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. + * + * @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. + * + * @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. + * + * @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. + */ +int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, + int *got_picture_ptr, + AVPacket *avpkt); + +#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); +#endif + +/** + * 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); + +/** + * Encodes an audio frame from \p samples into \p 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. + */ +int avcodec_encode_audio(AVCodecContext *avctx, uint8_t *buf, int buf_size, + const short *samples); + +/** + * 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. + */ +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); + +int avcodec_close(AVCodecContext *avctx); + +/** + * 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 + */ +void avcodec_register_all(void); + +/** + * Flush buffers, should be called when seeking or when switching to a different stream. + */ +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. + * + * @param[in] pict_type the picture type + * @return A single character representing the picture type. + */ +char av_get_pict_type_char(int pict_type); + +/** + * 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. + */ +int av_get_bits_per_sample(enum CodecID codec_id); + +/** + * Returns sample format bits per sample. + * + * @param[in] sample_fmt the sample format + * @return Number of bits per sample or zero if unknown for the given sample format. + */ +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 + +/** + * 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); + + +typedef struct AVBitStreamFilterContext { + void *priv_data; + struct AVBitStreamFilter *filter; + AVCodecParserContext *parser; + struct AVBitStreamFilterContext *next; +} AVBitStreamFilterContext; + + +typedef struct AVBitStreamFilter { + const char *name; + int priv_data_size; + int (*filter)(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); + void (*close)(AVBitStreamFilterContext *bsfc); + struct AVBitStreamFilter *next; +} AVBitStreamFilter; + +void av_register_bitstream_filter(AVBitStreamFilter *bsf); +AVBitStreamFilterContext *av_bitstream_filter_init(const char *name); +int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc, + AVCodecContext *avctx, const char *args, + uint8_t **poutbuf, int *poutbuf_size, + const uint8_t *buf, int buf_size, int keyframe); +void av_bitstream_filter_close(AVBitStreamFilterContext *bsf); + +AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f); + +/* memory */ + +/** + * Reallocates the given block if it is not large enough, otherwise it + * does nothing. + * + * @see av_realloc + */ +void *av_fast_realloc(void *ptr, unsigned int *size, unsigned int min_size); + +/** + * Allocates 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 + * handling to avoid memleaks is necessary. + * + * @param ptr pointer to pointer to already allocated buffer, overwritten with pointer to new buffer + * @param size size of the buffer *ptr points to + * @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); + +/** + * Copy image 'src' to 'dst'. + */ +void av_picture_copy(AVPicture *dst, const AVPicture *src, + enum PixelFormat pix_fmt, int width, int height); + +/** + * Crop image top and left side. + */ +int av_picture_crop(AVPicture *dst, const AVPicture *src, + enum PixelFormat pix_fmt, int top_band, int left_band); + +/** + * Pad image. + */ +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 + * x 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 + */ +int av_parse_video_frame_size(int *width_ptr, int *height_ptr, const char *str); + +/** + * 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 + * /, 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 + */ +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. */ + +/** + * Registers the hardware accelerator \p hwaccel. + */ +void av_register_hwaccel(AVHWAccel *hwaccel); + +/** + * If hwaccel is NULL, returns the first registered hardware accelerator, + * if hwaccel is non-NULL, returns the next registered hardware accelerator + * after hwaccel, or NULL if hwaccel is the last one. + */ +AVHWAccel *av_hwaccel_next(AVHWAccel *hwaccel); + +#endif /* AVCODEC_AVCODEC_H */ diff --git a/extra_lib/include/libavformat/avformat.h b/extra_lib/include/libavformat/avformat.h new file mode 100644 index 0000000..8732b56 --- /dev/null +++ b/extra_lib/include/libavformat/avformat.h @@ -0,0 +1,1238 @@ +/* + * copyright (c) 2001 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 AVFORMAT_AVFORMAT_H +#define AVFORMAT_AVFORMAT_H + +#define LIBAVFORMAT_VERSION_MAJOR 52 +#define LIBAVFORMAT_VERSION_MINOR 32 +#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) + +/** + * Returns the LIBAVFORMAT_VERSION_INT constant. + */ +unsigned avformat_version(void); + +#include +#include /* FILE */ +#include "libavcodec/avcodec.h" + +#include "avio.h" + +struct AVFormatContext; + + +/* + * Public Metadata API. + * The metadata API allows libavformat to export metadata tags to a client + * application using a sequence of key/value pairs. + * Important concepts to keep in mind: + * 1. 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 + * 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. + */ +void av_metadata_free(AVMetadata **m); + + +/* packet functions */ + + +/** + * 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); + + +/*************************************************/ +/* fractional numbers for exact pts handling */ + +/** + * The exact value of the fractional number is: 'val + num / den'. + * num is assumed to be 0 <= num < den. + */ +typedef struct AVFrac { + int64_t val, num, den; +} AVFrac; + +/*************************************************/ +/* input/output formats */ + +struct AVCodecTag; + +/** This structure contains the data a format has to probe a file. */ +typedef struct AVProbeData { + const char *filename; + unsigned char *buf; + int buf_size; +} AVProbeData; + +#define AVPROBE_SCORE_MAX 100 ///< maximum score, half of that is used for file-extension-based detection +#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. +#define AVFMT_NOFILE 0x0001 +#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */ +#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ +#define AVFMT_RAWPICTURE 0x0020 /**< Format wants AVPicture structure for + raw picture data. */ +#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_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */ + +typedef struct AVOutputFormat { + const char *name; + /** + * Descriptive name for the format, 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 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 */ + 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. + */ + const struct AVCodecTag * const *codec_tag; + + enum CodecID subtitle_codec; /**< default subtitle codec */ + + const AVMetadataConv *metadata_conv; + + /* private fields */ + struct AVOutputFormat *next; +} AVOutputFormat; + +typedef struct AVInputFormat { + const char *name; + /** + * Descriptive name for the format, 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; + /** 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 */ + int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); + /** 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. + * @param stream_index Must not be -1. + * @param flags Selects which direction should be preferred if no exact + * match is available. + * @return >= 0 on success (but not necessarily the new offset) + */ + 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. + * @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). */ + int (*read_play)(struct AVFormatContext *); + + /** 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 + * can be presented successfully will be closest to ts and within min/max_ts. + * 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 */ +}; + +typedef struct AVIndexEntry { + int64_t pos; + int64_t timestamp; +#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). + int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */ +} AVIndexEntry; + +#define AV_DISPOSITION_DEFAULT 0x0001 +#define AV_DISPOSITION_DUB 0x0002 +#define AV_DISPOSITION_ORIGINAL 0x0004 +#define AV_DISPOSITION_COMMENT 0x0008 +#define AV_DISPOSITION_LYRICS 0x0010 +#define AV_DISPOSITION_KARAOKE 0x0020 + +/** + * Stream 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(AVStream) must not be used outside libav*. + */ +typedef struct AVStream { + int index; /**< stream index in AVFormatContext */ + int id; /**< format-specific stream ID */ + AVCodecContext *codec; /**< codec context */ + /** + * Real base framerate of the stream. + * This is the lowest framerate with which all timestamps can be + * represented accurately (it is the least common multiple of all + * framerates in the stream). Note, this value is just a guess! + * For example, if the time base is 1/90000 and all frames have either + * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. + */ + AVRational r_frame_rate; + void *priv_data; + + /* internal data used in av_find_stream_info() */ + int64_t first_dts; + /** 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. + */ + 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. + * 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). + * @note The ASF header does NOT contain a correct start_time the ASF + * 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 + * a bitrate, this value will be estimated from bitrate and file size. + */ + 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]; + + /** + * sample aspect ratio (0 if unknown) + * - encoding: Set by user. + * - decoding: Set by libavformat. + */ + AVRational sample_aspect_ratio; + + AVMetadata *metadata; + + /* av_read_frame() support */ + const uint8_t *cur_ptr; + int cur_len; + AVPacket cur_pkt; + + // Timestamp generation support: + /** + * Timestamp corresponding to the last dts sync point. + * + * Initialized when AVCodecParserContext.dts_sync_point >= 0 and + * a DTS is received from the underlying container. Otherwise set to + * AV_NOPTS_VALUE by default. + */ + int64_t reference_dts; +} AVStream; + +#define AV_PROGRAM_RUNNING 1 + +/** + * 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(AVProgram) must not be used outside libav*. + */ +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; +} AVProgram; + +#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present + (streams are added dynamically) */ + +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; +} AVChapter; + +#define MAX_STREAMS 20 + +/** + * 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*. + */ +typedef struct AVFormatContext { + const AVClass *av_class; /**< Set by avformat_alloc_context. */ + /* Can only be iformat or oformat, not both at the same time. */ + struct AVInputFormat *iformat; + struct AVOutputFormat *oformat; + 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 + + 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. */ + 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 + + /* av_seek_frame() support */ + int64_t data_offset; /** offset of the first packet */ + int index_built; + + int mux_rate; + int packet_size; + int preload; + 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. + + int loop_input; + /** 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(). + */ + int max_analyze_duration; + + const uint8_t *key; + int keylen; + + unsigned int nb_programs; + AVProgram **programs; + + /** + * Forced video codec_id. + * Demuxing: Set by user. + */ + enum CodecID video_codec_id; + /** + * Forced audio codec_id. + * Demuxing: Set by user. + */ + enum CodecID audio_codec_id; + /** + * Forced subtitle codec_id. + * Demuxing: Set by user. + */ + enum CodecID subtitle_codec_id; + + /** + * Maximum amount of memory in bytes to use for the index of each stream. + * If the index exceeds this size, entries will be discarded as + * needed to maintain a smaller size. This can lead to slower or less + * accurate seeking (depends on demuxer). + * Demuxers for which a full in-memory index is mandatory will ignore + * this. + * muxing : unused + * demuxing: set by user + */ + unsigned int max_index_size; + + /** + * Maximum amount of memory in bytes to use for buffering frames + * obtained from realtime capture devices. + */ + unsigned int max_picture_buffer; + + unsigned int nb_chapters; + AVChapter **chapters; + + /** + * Flags to enable debugging. + */ + int debug; +#define FF_FDEBUG_TS 0x0001 + + /** + * Raw packets from the demuxer, prior to parsing and decoding. + * This buffer is used for buffering packets until the codec can + * be identified, as parsing cannot be done without knowing the + * codec. + */ + struct AVPacketList *raw_packet_buffer; + struct AVPacketList *raw_packet_buffer_end; + + struct AVPacketList *packet_buffer_end; + + AVMetadata *metadata; +} AVFormatContext; + +typedef struct AVPacketList { + AVPacket pkt; + struct AVPacketList *next; +} AVPacketList; + +#if LIBAVFORMAT_VERSION_INT < (53<<16) +extern AVInputFormat *first_iformat; +extern AVOutputFormat *first_oformat; +#endif + +/** + * If f is NULL, returns the first registered input format, + * if f is non-NULL, returns the next registered input format after f + * or NULL if f is the last one. + */ +AVInputFormat *av_iformat_next(AVInputFormat *f); + +/** + * If f is NULL, returns the first registered output format, + * if f is non-NULL, returns the next registered output format after f + * or NULL if f is the last one. + */ +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. + */ +enum CodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, + const char *filename, const char *mime_type, + enum CodecType type); + +/** + * 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_dump, av_pkt_dump_log + */ +void av_hex_dump(FILE *f, 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_dump, av_pkt_dump_log + */ +void av_hex_dump_log(void *avcl, int level, 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. + */ +void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); + +/** + * 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. + */ +void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload); + +/** + * 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); + +/** 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); + +/* media file input */ + +/** + * Finds AVInputFormat based on the short name of the input format. + */ +AVInputFormat *av_find_input_format(const char *short_name); + +/** + * Guess file format. + * + * @param is_opened Whether the file is already opened; determines whether + * demuxers with or without AVFMT_NOFILE are probed. + */ +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]. + */ +int av_open_input_stream(AVFormatContext **ic_ptr, + ByteIOContext *pb, const char *filename, + AVInputFormat *fmt, AVFormatParameters *ap); + +/** + * Open a media file as input. The codecs are not opened. Only the file + * header (if present) is read. + * + * @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 + */ +int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, + AVInputFormat *fmt, + int buf_size, + AVFormatParameters *ap); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** + * @deprecated Use avformat_alloc_context() instead. + */ +attribute_deprecated AVFormatContext *av_alloc_format_context(void); +#endif + +/** + * Allocate an AVFormatContext. + * Can be freed with av_free() but do not forget to free everything you + * explicitly allocated as well! + */ +AVFormatContext *avformat_alloc_context(void); + +/** + * 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 + * @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. + */ +int av_find_stream_info(AVFormatContext *ic); + +/** + * Read a transport packet from a media file. + * + * This function is obsolete and should never be used. + * Use av_read_frame() instead. + * + * @param s media file handle + * @param pkt is filled + * @return 0 if OK, AVERROR_xxx on error + */ +int av_read_packet(AVFormatContext *s, AVPacket *pkt); + +/** + * Return the next frame of a stream. + * + * The returned packet is valid + * until the next av_read_frame() or until av_close_input_file() and + * must be freed with av_free_packet. For video, the packet contains + * exactly one frame. For audio, it contains an integer number of + * frames if each frame has a known fixed size (e.g. PCM or ADPCM + * data). If the audio frames have a variable size (e.g. MPEG audio), + * then it contains one frame. + * + * pkt->pts, pkt->dts and pkt->duration are always set to correct + * values in AVStream.time_base units (and guessed if the format cannot + * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format + * has B-frames, so it is better to rely on pkt->dts if you do not + * decompress the payload. + * + * @return 0 if OK, < 0 on error or end of file + */ +int av_read_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Seek to the keyframe at timestamp. + * 'timestamp' in 'stream_index'. + * @param stream_index If stream_index is (-1), a default + * stream is selected, and timestamp is automatically converted + * from AV_TIME_BASE units to the stream specific time_base. + * @param timestamp Timestamp in AVStream.time_base units + * or, if no stream is specified, in AV_TIME_BASE units. + * @param flags flags which select direction and seeking mode + * @return >= 0 on success + */ +int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, + int flags); + +/** + * Seek to timestamp ts. + * Seeking will be done so that the point from which all active streams + * can be presented successfully will be closest to ts and within min/max_ts. + * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. + * + * If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and + * are the file position (this may not be supported by all demuxers). + * If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames + * in the stream with stream_index (this may not be supported by all demuxers). + * Otherwise all timestamps are in units of the stream selected by stream_index + * or if stream_index is -1, in AV_TIME_BASE units. + * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as + * keyframes (this may not be supported by all demuxers). + * + * @param stream_index index of the stream which is used as time base reference + * @param min_ts smallest acceptable timestamp + * @param ts target timestamp + * @param max_ts largest acceptable timestamp + * @param flags flags + * @returns >=0 on success, error code otherwise + * + * @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! + */ +int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); + +/** + * Start playing a network-based stream (e.g. RTSP stream) at the + * current position. + */ +int av_read_play(AVFormatContext *s); + +/** + * Pause a network-based stream (e.g. RTSP stream). + * + * Use av_read_play() to resume it. + */ +int av_read_pause(AVFormatContext *s); + +/** + * Free a AVFormatContext allocated by av_open_input_stream. + * @param s context to free + */ +void av_close_input_stream(AVFormatContext *s); + +/** + * Close a media file (but not its codecs). + * + * @param s media file handle + */ +void av_close_input_file(AVFormatContext *s); + +/** + * Add a new stream to a media file. + * + * Can only be called in the read_header() function. If the flag + * AVFMTCTX_NOHEADER is in the format context, then new streams + * can be added in read_packet too. + * + * @param s media file handle + * @param id file-format-dependent stream ID + */ +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); + +/** + * 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) + */ +void av_set_pts_info(AVStream *s, int pts_wrap_bits, + int pts_num, int pts_den); + +#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); + +/** + * 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. + */ +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. + * + * @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. + * + * 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. + * + * @param s media file handle + * @return 0 if OK, AVERROR_xxx on error + */ +int av_write_header(AVFormatContext *s); + +/** + * Write a packet to an output media file. + * + * The packet shall contain one audio or video frame. + * The packet must be correctly interleaved according to the container + * specification, if not then av_interleaved_write_frame must be used. + * + * @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 + */ +int av_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * Writes 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 + * call av_write_frame() instead as it is slightly faster. It is also important + * to keep in mind that completely non-interleaved input will need huge amounts + * of memory to interleave with this, so it is preferable to interleave at the + * 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 + */ +int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); + +/** + * 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 + */ +int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, + AVPacket *pkt, int flush); + +/** + * @brief 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. + * + * @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); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** + * Parses width and height out of string str. + * @deprecated Use av_parse_video_frame_size instead. + */ +attribute_deprecated int parse_image_size(int *width_ptr, int *height_ptr, + const char *str); + +/** + * Converts framerate from a string to a fraction. + * @deprecated Use av_parse_video_frame_rate instead. + */ +attribute_deprecated int parse_frame_rate(int *frame_rate, int *frame_rate_base, + const char *arg); +#endif + +/** + * Parses \p 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 \p 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 \p datestr cannot be + * successfully parsed. + * @param duration Flag which tells how to interpret \p datestr, if + * not zero \p datestr is interpreted as a duration, otherwise as a + * date. + */ +int64_t parse_date(const char *datestr, int duration); + +/** Gets the current time in microseconds. */ +int64_t av_gettime(void); + +/* 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. + * + * syntax: '?tag1=val1&tag2=val2...'. Little URL decoding is done. + * Return 1 if found. + */ +int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info); + +/** + * Returns in 'buf' the path with '%d' replaced by a number. + * + * Also handles the '%0nd' format where 'n' is the total number + * of digits and '%%'. + * + * @param buf destination buffer + * @param buf_size destination buffer size + * @param path numbered sequence string + * @param number frame number + * @return 0 if OK, -1 on format error + */ +int av_get_frame_filename(char *buf, int buf_size, + const char *path, int number); + +/** + * Check whether filename actually is a numbered sequence generator. + * + * @param filename possible numbered sequence string + * @return 1 if a valid numbered sequence string, 0 otherwise + */ +int av_filename_number_test(const char *filename); + +/** + * Generate an SDP for an RTP session. + * + * @param ac array of AVFormatContexts describing the RTP streams. If the + * array is composed by only one context, such context can contain + * multiple AVStreams (one AVStream per RTP stream). Otherwise, + * 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 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); + +#ifdef HAVE_AV_CONFIG_H + +void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem); + +#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 + +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); + +struct in_addr; +int resolve_host(struct in_addr *sin_addr, const char *hostname); + +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); + +int match_ext(const char *filename, const char *extensions); + +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* AVFORMAT_AVFORMAT_H */ diff --git a/extra_lib/include/libavformat/avio.h b/extra_lib/include/libavformat/avio.h new file mode 100644 index 0000000..5794fd6 --- /dev/null +++ b/extra_lib/include/libavformat/avio.h @@ -0,0 +1,408 @@ +/* + * copyright (c) 2001 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 AVFORMAT_AVIO_H +#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. + */ + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +#include "libavutil/common.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*. + */ +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 */ +}; + +typedef struct URLContext 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; + +#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); + +#if LIBAVFORMAT_VERSION_MAJOR < 53 +/** + * @deprecated Use av_register_protocol() instead. + */ +attribute_deprecated int register_protocol(URLProtocol *protocol); +#endif + +int av_register_protocol(URLProtocol *protocol); + +/** + * 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*. + */ +typedef struct { + unsigned char *buffer; + int buffer_size; + unsigned char *buf_ptr, *buf_end; + 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); + 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; + 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 (*read_pause)(void *opaque, int pause); + int64_t (*read_seek)(void *opaque, int stream_index, + int64_t timestamp, int flags); +} ByteIOContext; + +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( + 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)); + +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 put_strz(ByteIOContext *s, const char *buf); + +/** + * fseek() equivalent for ByteIOContext. + * @return new position or AVERROR. + */ +int64_t url_fseek(ByteIOContext *s, int64_t offset, int whence); + +/** + * Skip given number of bytes forward. + * @param offset number of bytes + */ +void url_fskip(ByteIOContext *s, int64_t offset); + +/** + * ftell() equivalent for ByteIOContext. + * @return position or AVERROR. + */ +int64_t url_ftell(ByteIOContext *s); + +/** + * Gets the filesize. + * @return filesize or AVERROR + */ +int64_t url_fsize(ByteIOContext *s); + +/** + * feof() equivalent for ByteIOContext. + * @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); + +/** @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); + + +/** + * Reads size bytes from ByteIOContext into buf. + * @returns number of bytes read or AVERROR + */ +int get_buffer(ByteIOContext *s, unsigned char *buf, int size); + +/** + * 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 + */ +int get_partial_buffer(ByteIOContext *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); + +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); + +uint64_t ff_get_v(ByteIOContext *bc); + +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); + +/** @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); + +/** @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); + +/** + * 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. + * + * @param s buffered file handle + * @return maximum packet size in bytes + */ +int url_fget_max_packet_size(ByteIOContext *s); + +int url_open_buf(ByteIOContext **s, uint8_t *buf, int buf_size, int flags); + +/** return the written or read size */ +int url_close_buf(ByteIOContext *s); + +/** + * Open a write only memory stream. + * + * @param s new IO context + * @return zero if no error. + */ +int url_open_dyn_buf(ByteIOContext **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. + * + * @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); + +/** + * Return the written size and a pointer to the buffer. The buffer + * must be freed with av_free(). + * @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 + +#endif /* AVFORMAT_AVIO_H */ diff --git a/extra_lib/include/libavutil/avutil.h b/extra_lib/include/libavutil/avutil.h new file mode 100644 index 0000000..fac1f5e --- /dev/null +++ b/extra_lib/include/libavutil/avutil.h @@ -0,0 +1,63 @@ +/* + * copyright (c) 2006 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_AVUTIL_H +#define AVUTIL_AVUTIL_H + +/** + * @file libavutil/avutil.h + * external API header + */ + + +#define AV_STRINGIFY(s) AV_TOSTRING(s) +#define AV_TOSTRING(s) #s + +#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) + +#define LIBAVUTIL_VERSION_MAJOR 50 +#define LIBAVUTIL_VERSION_MINOR 3 +#define LIBAVUTIL_VERSION_MICRO 0 + +#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) + +/** + * Returns the LIBAVUTIL_VERSION_INT constant. + */ +unsigned avutil_version(void); + +#include "common.h" +#include "mathematics.h" +#include "rational.h" +#include "intfloat_readwrite.h" +#include "log.h" +#include "pixfmt.h" + +#endif /* AVUTIL_AVUTIL_H */ diff --git a/extra_lib/include/libavutil/common.h b/extra_lib/include/libavutil/common.h new file mode 100644 index 0000000..609864f --- /dev/null +++ b/extra_lib/include/libavutil/common.h @@ -0,0 +1,319 @@ +/* + * copyright (c) 2006 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 + */ + +/** + * @file libavutil/common.h + * common internal and external API header + */ + +#ifndef AVUTIL_COMMON_H +#define AVUTIL_COMMON_H + +#include +#ifndef _WIN32_WCE +#include +#else +#define inline __inline +#endif +#include +#include +#include +#include +#include + +#if !defined(EMULATE_INTTYPES) +# include +#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 + +#ifndef attribute_deprecated +#if AV_GCC_VERSION_AT_LEAST(3,1) +# define attribute_deprecated __attribute__((deprecated)) +#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 +#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 FFABS(a) ((a) >= 0 ? (a) : (-(a))) +#define FFSIGN(a) ((a) > 0 ? 1 : -1) + +#define FFMAX(a,b) ((a) > (b) ? (a) : (b)) +#define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) +#define FFMIN(a,b) ((a) > (b) ? (b) : (a)) +#define FFMIN3(a,b,c) FFMIN(FFMIN(a,b),c) + +#define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0) +#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) + +/* misc math functions */ +extern const uint8_t ff_log2_tab[256]; + +static inline av_const int av_log2(unsigned int v) +{ + int n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +static inline av_const int av_log2_16bit(unsigned int v) +{ + int n = 0; + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += ff_log2_tab[v]; + + return n; +} + +/** + * Clips 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) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +/** + * Clips 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) +{ + if (a&(~255)) return (-a)>>31; + else return a; +} + +/** + * Clips a signed integer value into the -32768,32767 range. + * @param a value to clip + * @return clipped value + */ +static inline av_const int16_t av_clip_int16(int a) +{ + if ((a+32768) & ~65535) return (a>>31) ^ 32767; + else return a; +} + +/** + * Clips 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) +{ + 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. + */ +#define GET_UTF8(val, GET_BYTE, ERROR)\ + val= GET_BYTE;\ + {\ + int ones= 7 - av_log2(val ^ 255);\ + if(ones==1)\ + ERROR\ + val&= 127>>ones;\ + while(--ones > 0){\ + int tmp= GET_BYTE - 128;\ + if(tmp>>6)\ + ERROR\ + val= (val<<6) + tmp;\ + }\ + } + +/*! + * \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 + * 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 + * 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. + * 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 + * 7 times in the general case, depending on the length of the converted + * Unicode character. + */ +#define PUT_UTF8(val, tmp, PUT_BYTE)\ + {\ + int bytes, shift;\ + uint32_t in = val;\ + if (in < 0x80) {\ + tmp = in;\ + PUT_BYTE\ + } else {\ + bytes = (av_log2(in) + 4) / 5;\ + shift = (bytes - 1) * 6;\ + tmp = (256 - (256 >> bytes)) | (in >> shift);\ + PUT_BYTE\ + while (shift >= 6) {\ + shift -= 6;\ + tmp = 0x80 | ((in >> shift) & 0x3f);\ + PUT_BYTE\ + }\ + }\ + } + +#include "mem.h" + +#ifdef HAVE_AV_CONFIG_H +# include "config.h" +# include "internal.h" +#endif /* HAVE_AV_CONFIG_H */ + +#endif /* AVUTIL_COMMON_H */ diff --git a/extra_lib/include/libavutil/intfloat_readwrite.h b/extra_lib/include/libavutil/intfloat_readwrite.h new file mode 100644 index 0000000..88c6f69 --- /dev/null +++ b/extra_lib/include/libavutil/intfloat_readwrite.h @@ -0,0 +1,42 @@ +/* + * copyright (c) 2005 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_INTFLOAT_READWRITE_H +#define AVUTIL_INTFLOAT_READWRITE_H + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif +#include "common.h" + +/* IEEE 80 bits extended float */ +typedef struct AVExtFloat { + uint8_t exponent[2]; + 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; + +#endif /* AVUTIL_INTFLOAT_READWRITE_H */ diff --git a/extra_lib/include/libavutil/log.h b/extra_lib/include/libavutil/log.h new file mode 100644 index 0000000..1206a2f --- /dev/null +++ b/extra_lib/include/libavutil/log.h @@ -0,0 +1,116 @@ +/* + * copyright (c) 2006 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_LOG_H +#define AVUTIL_LOG_H + +#include +#include "avutil.h" + +/** + * Describes 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 { + /** + * The name of the class; usually it is the same name as the + * context structure type to which the AVClass is associated. + */ + const char* class_name; + + /** + * A pointer to a function which returns the name of a context + * instance \p ctx associated with the class. + */ + const char* (*item_name)(void* ctx); + + /** + * a pointer to the first option specified in the class if any or NULL + * + * @see av_set_default_options() + */ + const struct AVOption *option; +}; + +/* av_log API */ + +#define AV_LOG_QUIET -8 + +/** + * Something went really wrong and we will crash now. + */ +#define AV_LOG_PANIC 0 + +/** + * Something went wrong and recovery is not possible. + * For example, no header was found for a format which depends + * on headers or an illegal combination of parameters is used. + */ +#define AV_LOG_FATAL 8 + +/** + * Something went wrong and cannot losslessly be recovered. + * However, not all future data is affected. + */ +#define AV_LOG_ERROR 16 + +/** + * Something somehow does not look correct. This may or may not + * lead to problems. An example would be the use of '-vstrict -2'. + */ +#define AV_LOG_WARNING 24 + +#define AV_LOG_INFO 32 +#define AV_LOG_VERBOSE 40 + +/** + * Stuff which is only useful for libav* developers. + */ +#define AV_LOG_DEBUG 48 + +/** + * Sends 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. + * + * @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 fmt The format string (printf-compatible) that specifies how + * 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_vlog(void*, 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); + +#endif /* AVUTIL_LOG_H */ diff --git a/extra_lib/include/libavutil/mathematics.h b/extra_lib/include/libavutil/mathematics.h new file mode 100644 index 0000000..f437404 --- /dev/null +++ b/extra_lib/include/libavutil/mathematics.h @@ -0,0 +1,74 @@ +/* + * copyright (c) 2005 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_MATHEMATICS_H +#define AVUTIL_MATHEMATICS_H + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif +#include +#include "common.h" +#include "rational.h" + +#ifndef M_E +#define M_E 2.7182818284590452354 /* e */ +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#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 + +enum AVRounding { + AV_ROUND_ZERO = 0, ///< Round toward zero. + AV_ROUND_INF = 1, ///< Round away from zero. + AV_ROUND_DOWN = 2, ///< Round toward -infinity. + AV_ROUND_UP = 3, ///< Round toward +infinity. + AV_ROUND_NEAR_INF = 5, ///< Round to nearest and halfway cases away from zero. +}; + +int64_t av_const av_gcd(int64_t a, int64_t b); + +/** + * Rescales 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. + * 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. + */ +int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq) av_const; + +#endif /* AVUTIL_MATHEMATICS_H */ diff --git a/extra_lib/include/libavutil/mem.h b/extra_lib/include/libavutil/mem.h new file mode 100644 index 0000000..e50553a --- /dev/null +++ b/extra_lib/include/libavutil/mem.h @@ -0,0 +1,104 @@ +/* + * copyright (c) 2006 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 + */ + +/** + * @file libavutil/mem.h + * memory handling functions + */ + +#ifndef AVUTIL_MEM_H +#define AVUTIL_MEM_H + +#include "common.h" + +#if AV_GCC_VERSION_AT_LEAST(3,1) + #define av_malloc_attrib __attribute__((__malloc__)) +#else + #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))) +#else + #define av_alloc_size(n) +#endif + +/** + * Allocates a block of \p 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); + +/** + * 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. + * @param ptr Pointer to a memory block already allocated with + * av_malloc(z)() or av_realloc() or NULL. + * @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); + +/** + * Frees 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. + * @note It is recommended that you use av_freep() instead. + * @see av_freep() + */ +void av_free(void *ptr); + +/** + * Allocates a block of \p size bytes with alignment suitable for all + * memory accesses (including vectors if available on the CPU) and + * zeroes 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); + +/** + * Duplicates the string \p 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. + */ +char *av_strdup(const char *s) av_malloc_attrib; + +/** + * Frees 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. + * @see av_free() + */ +void av_freep(void *ptr); + +#endif /* AVUTIL_MEM_H */ diff --git a/extra_lib/include/libavutil/pixfmt.h b/extra_lib/include/libavutil/pixfmt.h new file mode 100644 index 0000000..4995a4d --- /dev/null +++ b/extra_lib/include/libavutil/pixfmt.h @@ -0,0 +1,151 @@ +/* + * copyright (c) 2006 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_PIXFMT_H +#define AVUTIL_PIXFMT_H + +/** + * @file libavutil/pixfmt.h + * 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. + */ + +/** + * Pixel format. Notes: + * + * 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. + * + * 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 + * formatted the same as in PIX_FMT_RGB32 described above (i.e., it is + * also endian-specific). Note also that the individual RGB palette + * components stored in AVFrame.data[1] should be in the range 0..255. + * 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. + * + * 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. + */ +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 +}; + +#ifdef WORDS_BIGENDIAN +# define PIX_FMT_NE(be, le) PIX_FMT_##be +#else +# define PIX_FMT_NE(be, le) 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) + +#endif /* AVUTIL_PIXFMT_H */ diff --git a/extra_lib/include/libavutil/rational.h b/extra_lib/include/libavutil/rational.h new file mode 100644 index 0000000..048202b --- /dev/null +++ b/extra_lib/include/libavutil/rational.h @@ -0,0 +1,131 @@ +/* + * rational numbers + * Copyright (c) 2003 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 + */ + +/** + * @file libavutil/rational.h + * rational numbers + * @author Michael Niedermayer + */ + +#ifndef AVUTIL_RATIONAL_H +#define AVUTIL_RATIONAL_H + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif +#include "common.h" + +/** + * rational number numerator/denominator + */ +typedef struct AVRational{ + int num; ///< numerator + int den; ///< denominator +} AVRational; + +/** + * Compares two rationals. + * @param a first rational + * @param b second rational + * @return 0 if a==b, 1 if a>b and -1 if a>63)|1; + else return 0; +} + +/** + * Converts rational to double. + * @param a rational to convert + * @return (double) a + */ +static inline double av_q2d(AVRational a){ + return a.num / (double) a.den; +} + +/** + * Reduces a fraction. + * This is useful for framerate calculations. + * @param dst_num destination numerator + * @param dst_den destination denominator + * @param num source numerator + * @param den source denominator + * @param max the maximum allowed for dst_num & dst_den + * @return 1 if exact, 0 otherwise + */ +int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max); + +/** + * Multiplies two rationals. + * @param b first rational + * @param c second rational + * @return b*c + */ +AVRational av_mul_q(AVRational b, AVRational c) av_const; + +/** + * Divides one rational by another. + * @param b first rational + * @param c second rational + * @return b/c + */ +AVRational av_div_q(AVRational b, AVRational c) av_const; + +/** + * Adds two rationals. + * @param b first rational + * @param c second rational + * @return b+c + */ +AVRational av_add_q(AVRational b, AVRational c) av_const; + +/** + * Subtracts one rational from another. + * @param b first rational + * @param c second rational + * @return b-c + */ +AVRational av_sub_q(AVRational b, AVRational c) av_const; + +/** + * Converts a double precision floating point number to a rational. + * @param d double to convert + * @param max the maximum allowed numerator and denominator + * @return (AVRational) d + */ +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. + */ +int av_nearer_q(AVRational q, AVRational q1, AVRational q2); + +/** + * Finds the nearest value in \p q_list to \p 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/libswscale/swscale.h b/extra_lib/include/libswscale/swscale.h new file mode 100644 index 0000000..f5856c3 --- /dev/null +++ b/extra_lib/include/libswscale/swscale.h @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2001-2003 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 SWSCALE_SWSCALE_H +#define SWSCALE_SWSCALE_H + +/** + * @file libswscale/swscale.h + * @brief + * external api for the swscale stuff + */ + +#include "libavutil/avutil.h" + +#define LIBSWSCALE_VERSION_MAJOR 0 +#define LIBSWSCALE_VERSION_MINOR 7 +#define LIBSWSCALE_VERSION_MICRO 1 + +#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) + +/** + * Returns the LIBSWSCALE_VERSION_INT constant. + */ +unsigned swscale_version(void); + +/* values for the flags, the stuff on the command line is different */ +#define SWS_FAST_BILINEAR 1 +#define SWS_BILINEAR 2 +#define SWS_BICUBIC 4 +#define SWS_X 8 +#define SWS_POINT 0x10 +#define SWS_AREA 0x20 +#define SWS_BICUBLIN 0x40 +#define SWS_GAUSS 0x80 +#define SWS_SINC 0x100 +#define SWS_LANCZOS 0x200 +#define SWS_SPLINE 0x400 + +#define SWS_SRC_V_CHR_DROP_MASK 0x30000 +#define SWS_SRC_V_CHR_DROP_SHIFT 16 + +#define SWS_PARAM_DEFAULT 123456 + +#define SWS_PRINT_INFO 0x1000 + +//the following 3 flags are not completely implemented +//internal chrominace subsampling info +#define SWS_FULL_CHR_H_INT 0x2000 +//input subsampling info +#define SWS_FULL_CHR_H_INP 0x4000 +#define SWS_DIRECT_BGR 0x8000 +#define SWS_ACCURATE_RND 0x40000 +#define SWS_BITEXACT 0x80000 + +#define SWS_CPU_CAPS_MMX 0x80000000 +#define SWS_CPU_CAPS_MMX2 0x20000000 +#define SWS_CPU_CAPS_3DNOW 0x40000000 +#define SWS_CPU_CAPS_ALTIVEC 0x10000000 +#define SWS_CPU_CAPS_BFIN 0x01000000 + +#define SWS_MAX_REDUCE_CUTOFF 0.002 + +#define SWS_CS_ITU709 1 +#define SWS_CS_FCC 4 +#define SWS_CS_ITU601 5 +#define SWS_CS_ITU624 5 +#define SWS_CS_SMPTE170M 5 +#define SWS_CS_SMPTE240M 7 +#define SWS_CS_DEFAULT 5 + + + +// when used for filters they must have an odd number of elements +// coeffs cannot be shared between vectors +typedef struct { + double *coeff; ///< pointer to the list of coefficients + int length; ///< number of coefficients in the vector +} SwsVector; + +// vectors can be shared +typedef struct { + SwsVector *lumH; + SwsVector *lumV; + SwsVector *chrH; + SwsVector *chrV; +} SwsFilter; + +struct SwsContext; + +void sws_freeContext(struct SwsContext *swsContext); + +/** + * Allocates and returns a SwsContext. You need it to perform + * scaling/conversion operations using sws_scale(). + * + * @param srcW the width of the source image + * @param srcH the height of the source image + * @param srcFormat the source image format + * @param dstW the width of the destination image + * @param dstH the height of the destination image + * @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 + */ +struct SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, + int dstW, int dstH, enum PixelFormat dstFormat, + int flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, const double *param); + +/** + * 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 + * rows in an image. + * + * @param context the scaling context previously created with + * sws_getContext() + * @param srcSlice the array containing the pointers to the planes of + * the source slice + * @param srcStride the array containing the strides for each plane of + * the source image + * @param srcSliceY the position in the source image of the slice to + * process, that is the number (counted starting from + * zero) in the image of the first row of the slice + * @param srcSliceH the height of the source slice, that is the number + * of rows in the slice + * @param dst the array containing the pointers to the planes of + * the destination image + * @param dstStride the array containing the strides for each plane of + * 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 + +/** + * @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 + * @return -1 if not supported + */ +int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], + int srcRange, const int table[4], int dstRange, + int brightness, int contrast, int saturation); + +/** + * @return -1 if not supported + */ +int sws_getColorspaceDetails(struct SwsContext *c, int **inv_table, + int *srcRange, int **table, int *dstRange, + int *brightness, int *contrast, int *saturation); + +/** + * Returns 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. + */ +SwsVector *sws_getConstVec(double c, int length); + +/** + * Allocates and returns 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. + */ +void sws_scaleVec(SwsVector *a, double scalar); + +/** + * Scales all the coefficients of \p a so that their sum equals \p + * height." + */ +void sws_normalizeVec(SwsVector *a, double height); +void sws_convVec(SwsVector *a, SwsVector *b); +void sws_addVec(SwsVector *a, SwsVector *b); +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. + */ +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. + */ +void sws_printVec2(SwsVector *a, AVClass *log_ctx, int log_level); + +void sws_freeVec(SwsVector *a); + +SwsFilter *sws_getDefaultFilter(float lumaGBlur, float chromaGBlur, + float lumaSharpen, float chromaSharpen, + float chromaHShift, float chromaVShift, + int verbose); +void sws_freeFilter(SwsFilter *filter); + +/** + * Checks if \p context can be reused, otherwise reallocates a new + * one. + * + * If \p 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 + * the new parameters. + * + * Be warned that \p srcFilter and \p 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 flags, SwsFilter *srcFilter, + SwsFilter *dstFilter, const double *param); + +#endif /* SWSCALE_SWSCALE_H */ diff --git a/extra_lib/include/ogg/ogg.h b/extra_lib/include/ogg/ogg.h index 48bbfb1..4a714e5 100644 --- a/extra_lib/include/ogg/ogg.h +++ b/extra_lib/include/ogg/ogg.h @@ -11,7 +11,7 @@ ******************************************************************** function: toplevel libogg include - last mod: $Id: ogg.h,v 1.2 2008/12/02 18:04:43 jeanlf Exp $ + last mod: $Id: ogg.h,v 1.2 2008-12-02 18:04:43 jeanlf Exp $ ********************************************************************/ #ifndef _OGG_H diff --git a/extra_lib/include/ogg/os_types.h b/extra_lib/include/ogg/os_types.h index 604d853..ee30903 100644 --- a/extra_lib/include/ogg/os_types.h +++ b/extra_lib/include/ogg/os_types.h @@ -11,7 +11,7 @@ ******************************************************************** function: #ifdef jail to whip a few platforms into the UNIX ideal. - last mod: $Id: os_types.h,v 1.2 2008/12/02 18:04:43 jeanlf Exp $ + last mod: $Id: os_types.h,v 1.2 2008-12-02 18:04:43 jeanlf Exp $ ********************************************************************/ #ifndef _OS_TYPES_H diff --git a/extra_lib/include/theora/theora.h b/extra_lib/include/theora/theora.h index d99c95b..5429d10 100644 --- a/extra_lib/include/theora/theora.h +++ b/extra_lib/include/theora/theora.h @@ -11,7 +11,7 @@ ******************************************************************** function: - last mod: $Id: theora.h,v 1.2 2008/12/02 18:04:43 jeanlf Exp $ + last mod: $Id: theora.h,v 1.2 2008-12-02 18:04:43 jeanlf Exp $ ********************************************************************/ diff --git a/extra_lib/include/vorbis/codec.h b/extra_lib/include/vorbis/codec.h index 0357bef..535bb43 100644 --- a/extra_lib/include/vorbis/codec.h +++ b/extra_lib/include/vorbis/codec.h @@ -11,7 +11,7 @@ ******************************************************************** function: libvorbis codec headers - last mod: $Id: codec.h,v 1.2 2008/12/02 18:04:43 jeanlf Exp $ + last mod: $Id: codec.h,v 1.2 2008-12-02 18:04:43 jeanlf Exp $ ********************************************************************/ diff --git a/extra_lib/include/vorbis/vorbisenc.h b/extra_lib/include/vorbis/vorbisenc.h index 48afcc5..21308bf 100644 --- a/extra_lib/include/vorbis/vorbisenc.h +++ b/extra_lib/include/vorbis/vorbisenc.h @@ -11,7 +11,7 @@ ******************************************************************** function: vorbis encode-engine setup - last mod: $Id: vorbisenc.h,v 1.2 2008/12/02 18:04:43 jeanlf Exp $ + last mod: $Id: vorbisenc.h,v 1.2 2008-12-02 18:04:43 jeanlf Exp $ ********************************************************************/ diff --git a/extra_lib/include/vorbis/vorbisfile.h b/extra_lib/include/vorbis/vorbisfile.h index 5453c23..9abe89e 100644 --- a/extra_lib/include/vorbis/vorbisfile.h +++ b/extra_lib/include/vorbis/vorbisfile.h @@ -11,7 +11,7 @@ ******************************************************************** function: stdio-based convenience library for opening/seeking/decoding - last mod: $Id: vorbisfile.h,v 1.2 2008/12/02 18:04:43 jeanlf Exp $ + last mod: $Id: vorbisfile.h,v 1.2 2008-12-02 18:04:43 jeanlf Exp $ ********************************************************************/ diff --git a/extra_lib/include/wiiuse.h b/extra_lib/include/wiiuse.h new file mode 100644 index 0000000..78c5125 --- /dev/null +++ b/extra_lib/include/wiiuse.h @@ -0,0 +1,653 @@ +/* + * wiiuse + * + * Written By: + * Michael Laforest < para > + * Email: < thepara (--AT--) g m a i l [--DOT--] com > + * + * Copyright 2006-2007 + * + * This file is part of wiiuse. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * $Header: /home/bouqueau/Works/smb_moscovie/gpac/extra_lib/include/wiiuse.h,v 1.1 2009-05-20 17:11:40 jeanlf Exp $ + * + */ + +/** + * @file + * + * @brief API header file. + * + * If this file is included from inside the wiiuse source + * and not from a third party program, then wiimote_internal.h + * is also included which extends this file. + */ + +#ifndef WIIUSE_H_INCLUDED +#define WIIUSE_H_INCLUDED + +#ifdef _WIN32 + /* windows */ + #include +#else + /* nix */ + #include +#endif + +#ifdef WIIUSE_INTERNAL_H_INCLUDED + #define WCONST +#else + #define WCONST const +#endif + +/* led bit masks */ +#define WIIMOTE_LED_NONE 0x00 +#define WIIMOTE_LED_1 0x10 +#define WIIMOTE_LED_2 0x20 +#define WIIMOTE_LED_3 0x40 +#define WIIMOTE_LED_4 0x80 + +/* button codes */ +#define WIIMOTE_BUTTON_TWO 0x0001 +#define WIIMOTE_BUTTON_ONE 0x0002 +#define WIIMOTE_BUTTON_B 0x0004 +#define WIIMOTE_BUTTON_A 0x0008 +#define WIIMOTE_BUTTON_MINUS 0x0010 +#define WIIMOTE_BUTTON_ZACCEL_BIT6 0x0020 +#define WIIMOTE_BUTTON_ZACCEL_BIT7 0x0040 +#define WIIMOTE_BUTTON_HOME 0x0080 +#define WIIMOTE_BUTTON_LEFT 0x0100 +#define WIIMOTE_BUTTON_RIGHT 0x0200 +#define WIIMOTE_BUTTON_DOWN 0x0400 +#define WIIMOTE_BUTTON_UP 0x0800 +#define WIIMOTE_BUTTON_PLUS 0x1000 +#define WIIMOTE_BUTTON_ZACCEL_BIT4 0x2000 +#define WIIMOTE_BUTTON_ZACCEL_BIT5 0x4000 +#define WIIMOTE_BUTTON_UNKNOWN 0x8000 +#define WIIMOTE_BUTTON_ALL 0x1F9F + +/* nunchul button codes */ +#define NUNCHUK_BUTTON_Z 0x01 +#define NUNCHUK_BUTTON_C 0x02 +#define NUNCHUK_BUTTON_ALL 0x03 + +/* classic controller button codes */ +#define CLASSIC_CTRL_BUTTON_UP 0x0001 +#define CLASSIC_CTRL_BUTTON_LEFT 0x0002 +#define CLASSIC_CTRL_BUTTON_ZR 0x0004 +#define CLASSIC_CTRL_BUTTON_X 0x0008 +#define CLASSIC_CTRL_BUTTON_A 0x0010 +#define CLASSIC_CTRL_BUTTON_Y 0x0020 +#define CLASSIC_CTRL_BUTTON_B 0x0040 +#define CLASSIC_CTRL_BUTTON_ZL 0x0080 +#define CLASSIC_CTRL_BUTTON_FULL_R 0x0200 +#define CLASSIC_CTRL_BUTTON_PLUS 0x0400 +#define CLASSIC_CTRL_BUTTON_HOME 0x0800 +#define CLASSIC_CTRL_BUTTON_MINUS 0x1000 +#define CLASSIC_CTRL_BUTTON_FULL_L 0x2000 +#define CLASSIC_CTRL_BUTTON_DOWN 0x4000 +#define CLASSIC_CTRL_BUTTON_RIGHT 0x8000 +#define CLASSIC_CTRL_BUTTON_ALL 0xFEFF + +/* guitar hero 3 button codes */ +#define GUITAR_HERO_3_BUTTON_STRUM_UP 0x0001 +#define GUITAR_HERO_3_BUTTON_YELLOW 0x0008 +#define GUITAR_HERO_3_BUTTON_GREEN 0x0010 +#define GUITAR_HERO_3_BUTTON_BLUE 0x0020 +#define GUITAR_HERO_3_BUTTON_RED 0x0040 +#define GUITAR_HERO_3_BUTTON_ORANGE 0x0080 +#define GUITAR_HERO_3_BUTTON_PLUS 0x0400 +#define GUITAR_HERO_3_BUTTON_MINUS 0x1000 +#define GUITAR_HERO_3_BUTTON_STRUM_DOWN 0x4000 +#define GUITAR_HERO_3_BUTTON_ALL 0xFEFF + + +/* wiimote option flags */ +#define WIIUSE_SMOOTHING 0x01 +#define WIIUSE_CONTINUOUS 0x02 +#define WIIUSE_ORIENT_THRESH 0x04 +#define WIIUSE_INIT_FLAGS (WIIUSE_SMOOTHING | WIIUSE_ORIENT_THRESH) + +#define WIIUSE_ORIENT_PRECISION 100.0f + +/* expansion codes */ +#define EXP_NONE 0 +#define EXP_NUNCHUK 1 +#define EXP_CLASSIC 2 +#define EXP_GUITAR_HERO_3 3 + +/* IR correction types */ +typedef enum ir_position_t { + WIIUSE_IR_ABOVE, + WIIUSE_IR_BELOW +} ir_position_t; + +/** + * @brief Check if a button is pressed. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is pressed, 0 if not. + */ +#define IS_PRESSED(dev, button) ((dev->btns & button) == button) + +/** + * @brief Check if a button is being held. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is held, 0 if not. + */ +#define IS_HELD(dev, button) ((dev->btns_held & button) == button) + +/** + * @brief Check if a button is released on this event. \n\n + * This does not mean the button is not pressed, it means \n + * this button was just now released. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is released, 0 if not. + * + */ +#define IS_RELEASED(dev, button) ((dev->btns_released & button) == button) + +/** + * @brief Check if a button has just been pressed this event. + * @param dev Pointer to a wiimote_t or expansion structure. + * @param button The button you are interested in. + * @return 1 if the button is pressed, 0 if not. + */ +#define IS_JUST_PRESSED(dev, button) (IS_PRESSED(dev, button) && !IS_HELD(dev, button)) + +/** + * @brief Return the IR sensitivity level. + * @param wm Pointer to a wiimote_t structure. + * @param lvl [out] Pointer to an int that will hold the level setting. + * If no level is set 'lvl' will be set to 0. + */ +#define WIIUSE_GET_IR_SENSITIVITY(dev, lvl) \ + do { \ + if ((wm->state & 0x0200) == 0x0200) *lvl = 1; \ + else if ((wm->state & 0x0400) == 0x0400) *lvl = 2; \ + else if ((wm->state & 0x0800) == 0x0800) *lvl = 3; \ + else if ((wm->state & 0x1000) == 0x1000) *lvl = 4; \ + else if ((wm->state & 0x2000) == 0x2000) *lvl = 5; \ + else *lvl = 0; \ + } while (0) + +#define WIIUSE_USING_ACC(wm) ((wm->state & 0x020) == 0x020) +#define WIIUSE_USING_EXP(wm) ((wm->state & 0x040) == 0x040) +#define WIIUSE_USING_IR(wm) ((wm->state & 0x080) == 0x080) +#define WIIUSE_USING_SPEAKER(wm) ((wm->state & 0x100) == 0x100) + +#define WIIUSE_IS_LED_SET(wm, num) ((wm->leds & WIIMOTE_LED_##num) == WIIMOTE_LED_##num) + +/* + * Largest known payload is 21 bytes. + * Add 2 for the prefix and round up to a power of 2. + */ +#define MAX_PAYLOAD 32 + +/* + * This is left over from an old hack, but it may actually + * be a useful feature to keep so it wasn't removed. + */ +#ifdef WIN32 + #define WIIMOTE_DEFAULT_TIMEOUT 10 + #define WIIMOTE_EXP_TIMEOUT 10 +#endif + +typedef unsigned char byte; +typedef char sbyte; + +struct wiimote_t; +struct vec3b_t; +struct orient_t; +struct gforce_t; + + +/** + * @brief Callback that handles a read event. + * + * @param wm Pointer to a wiimote_t structure. + * @param data Pointer to the filled data block. + * @param len Length in bytes of the data block. + * + * @see wiiuse_init() + * + * A registered function of this type is called automatically by the wiiuse + * library when the wiimote has returned the full data requested by a previous + * call to wiiuse_read_data(). + */ +typedef void (*wiiuse_read_cb)(struct wiimote_t* wm, byte* data, unsigned short len); + + +/** + * @struct read_req_t + * @brief Data read request structure. + */ +struct read_req_t { + wiiuse_read_cb cb; /**< read data callback */ + byte* buf; /**< buffer where read data is written */ + unsigned int addr; /**< the offset that the read started at */ + unsigned short size; /**< the length of the data read */ + unsigned short wait; /**< num bytes still needed to finish read */ + byte dirty; /**< set to 1 if not using callback and needs to be cleaned up */ + + struct read_req_t* next; /**< next read request in the queue */ +}; + + +/** + * @struct vec2b_t + * @brief Unsigned x,y byte vector. + */ +typedef struct vec2b_t { + byte x, y; +} vec2b_t; + + +/** + * @struct vec3b_t + * @brief Unsigned x,y,z byte vector. + */ +typedef struct vec3b_t { + byte x, y, z; +} vec3b_t; + + +/** + * @struct vec3f_t + * @brief Signed x,y,z float struct. + */ +typedef struct vec3f_t { + float x, y, z; +} vec3f_t; + + +/** + * @struct orient_t + * @brief Orientation struct. + * + * Yaw, pitch, and roll range from -180 to 180 degrees. + */ +typedef struct orient_t { + float roll; /**< roll, this may be smoothed if enabled */ + float pitch; /**< pitch, this may be smoothed if enabled */ + float yaw; + + float a_roll; /**< absolute roll, unsmoothed */ + float a_pitch; /**< absolute pitch, unsmoothed */ +} orient_t; + + +/** + * @struct gforce_t + * @brief Gravity force struct. + */ +typedef struct gforce_t { + float x, y, z; +} gforce_t; + + +/** + * @struct accel_t + * @brief Accelerometer struct. For any device with an accelerometer. + */ +typedef struct accel_t { + struct vec3b_t cal_zero; /**< zero calibration */ + struct vec3b_t cal_g; /**< 1g difference around 0cal */ + + float st_roll; /**< last smoothed roll value */ + float st_pitch; /**< last smoothed roll pitch */ + float st_alpha; /**< alpha value for smoothing [0-1] */ +} accel_t; + + +/** + * @struct ir_dot_t + * @brief A single IR source. + */ +typedef struct ir_dot_t { + byte visible; /**< if the IR source is visible */ + + unsigned int x; /**< interpolated X coordinate */ + unsigned int y; /**< interpolated Y coordinate */ + + short rx; /**< raw X coordinate (0-1023) */ + short ry; /**< raw Y coordinate (0-767) */ + + byte order; /**< increasing order by x-axis value */ + + byte size; /**< size of the IR dot (0-15) */ +} ir_dot_t; + + +/** + * @enum aspect_t + * @brief Screen aspect ratio. + */ +typedef enum aspect_t { + WIIUSE_ASPECT_4_3, + WIIUSE_ASPECT_16_9 +} aspect_t; + + +/** + * @struct ir_t + * @brief IR struct. Hold all data related to the IR tracking. + */ +typedef struct ir_t { + struct ir_dot_t dot[4]; /**< IR dots */ + byte num_dots; /**< number of dots at this time */ + + enum aspect_t aspect; /**< aspect ratio of the screen */ + + enum ir_position_t pos; /**< IR sensor bar position */ + + unsigned int vres[2]; /**< IR virtual screen resolution */ + int offset[2]; /**< IR XY correction offset */ + int state; /**< keeps track of the IR state */ + + int ax; /**< absolute X coordinate */ + int ay; /**< absolute Y coordinate */ + + int x; /**< calculated X coordinate */ + int y; /**< calculated Y coordinate */ + + float distance; /**< pixel distance between first 2 dots*/ + float z; /**< calculated distance */ +} ir_t; + + +/** + * @struct joystick_t + * @brief Joystick calibration structure. + * + * The angle \a ang is relative to the positive y-axis into quadrant I + * and ranges from 0 to 360 degrees. So if the joystick is held straight + * upwards then angle is 0 degrees. If it is held to the right it is 90, + * down is 180, and left is 270. + * + * The magnitude \a mag is the distance from the center to where the + * joystick is being held. The magnitude ranges from 0 to 1. + * If the joystick is only slightly tilted from the center the magnitude + * will be low, but if it is closer to the outter edge the value will + * be higher. + */ +typedef struct joystick_t { + struct vec2b_t max; /**< maximum joystick values */ + struct vec2b_t min; /**< minimum joystick values */ + struct vec2b_t center; /**< center joystick values */ + + float ang; /**< angle the joystick is being held */ + float mag; /**< magnitude of the joystick (range 0-1) */ +} joystick_t; + + +/** + * @struct nunchuk_t + * @brief Nunchuk expansion device. + */ +typedef struct nunchuk_t { + struct accel_t accel_calib; /**< nunchuk accelerometer calibration */ + struct joystick_t js; /**< joystick calibration */ + + int* flags; /**< options flag (points to wiimote_t.flags) */ + + byte btns; /**< what buttons have just been pressed */ + byte btns_held; /**< what buttons are being held down */ + byte btns_released; /**< what buttons were just released this */ + + float orient_threshold; /**< threshold for orient to generate an event */ + int accel_threshold; /**< threshold for accel to generate an event */ + + struct vec3b_t accel; /**< current raw acceleration data */ + struct orient_t orient; /**< current orientation on each axis */ + struct gforce_t gforce; /**< current gravity forces on each axis */ +} nunchuk_t; + + +/** + * @struct classic_ctrl_t + * @brief Classic controller expansion device. + */ +typedef struct classic_ctrl_t { + short btns; /**< what buttons have just been pressed */ + short btns_held; /**< what buttons are being held down */ + short btns_released; /**< what buttons were just released this */ + + float r_shoulder; /**< right shoulder button (range 0-1) */ + float l_shoulder; /**< left shoulder button (range 0-1) */ + + struct joystick_t ljs; /**< left joystick calibration */ + struct joystick_t rjs; /**< right joystick calibration */ +} classic_ctrl_t; + + +/** + * @struct guitar_hero_3_t + * @brief Guitar Hero 3 expansion device. + */ +typedef struct guitar_hero_3_t { + short btns; /**< what buttons have just been pressed */ + short btns_held; /**< what buttons are being held down */ + short btns_released; /**< what buttons were just released this */ + + float whammy_bar; /**< whammy bar (range 0-1) */ + + struct joystick_t js; /**< joystick calibration */ +} guitar_hero_3_t; + + +/** + * @struct expansion_t + * @brief Generic expansion device plugged into wiimote. + */ +typedef struct expansion_t { + int type; /**< type of expansion attached */ + + union { + struct nunchuk_t nunchuk; + struct classic_ctrl_t classic; + struct guitar_hero_3_t gh3; + }; +} expansion_t; + + +/** + * @enum win32_bt_stack_t + * @brief Available bluetooth stacks for Windows. + */ +typedef enum win_bt_stack_t { + WIIUSE_STACK_UNKNOWN, + WIIUSE_STACK_MS, + WIIUSE_STACK_BLUESOLEIL +} win_bt_stack_t; + + +/** + * @struct wiimote_state_t + * @brief Significant data from the previous event. + */ +typedef struct wiimote_state_t { + /* expansion_t */ + float exp_ljs_ang; + float exp_rjs_ang; + float exp_ljs_mag; + float exp_rjs_mag; + unsigned short exp_btns; + struct orient_t exp_orient; + struct vec3b_t exp_accel; + float exp_r_shoulder; + float exp_l_shoulder; + + /* ir_t */ + int ir_ax; + int ir_ay; + float ir_distance; + + struct orient_t orient; + unsigned short btns; + + struct vec3b_t accel; +} wiimote_state_t; + + +/** + * @enum WIIUSE_EVENT_TYPE + * @brief Events that wiiuse can generate from a poll. + */ +typedef enum WIIUSE_EVENT_TYPE { + WIIUSE_NONE = 0, + WIIUSE_EVENT, + WIIUSE_STATUS, + WIIUSE_CONNECT, + WIIUSE_DISCONNECT, + WIIUSE_UNEXPECTED_DISCONNECT, + WIIUSE_READ_DATA, + WIIUSE_NUNCHUK_INSERTED, + WIIUSE_NUNCHUK_REMOVED, + WIIUSE_CLASSIC_CTRL_INSERTED, + WIIUSE_CLASSIC_CTRL_REMOVED, + WIIUSE_GUITAR_HERO_3_CTRL_INSERTED, + WIIUSE_GUITAR_HERO_3_CTRL_REMOVED +} WIIUSE_EVENT_TYPE; + +/** + * @struct wiimote_t + * @brief Wiimote structure. + */ +typedef struct wiimote_t { + WCONST int unid; /**< user specified id */ + + #ifndef WIN32 + WCONST bdaddr_t bdaddr; /**< bt address */ + WCONST char bdaddr_str[18]; /**< readable bt address */ + WCONST int out_sock; /**< output socket */ + WCONST int in_sock; /**< input socket */ + #else + WCONST HANDLE dev_handle; /**< HID handle */ + WCONST OVERLAPPED hid_overlap; /**< overlap handle */ + WCONST enum win_bt_stack_t stack; /**< type of bluetooth stack to use */ + WCONST int timeout; /**< read timeout */ + WCONST byte normal_timeout; /**< normal timeout */ + WCONST byte exp_timeout; /**< timeout for expansion handshake */ + #endif + + WCONST int state; /**< various state flags */ + WCONST byte leds; /**< currently lit leds */ + WCONST float battery_level; /**< battery level */ + + WCONST int flags; /**< options flag */ + + WCONST byte handshake_state; /**< the state of the connection handshake */ + + WCONST struct read_req_t* read_req; /**< list of data read requests */ + WCONST struct accel_t accel_calib; /**< wiimote accelerometer calibration */ + WCONST struct expansion_t exp; /**< wiimote expansion device */ + + WCONST struct vec3b_t accel; /**< current raw acceleration data */ + WCONST struct orient_t orient; /**< current orientation on each axis */ + WCONST struct gforce_t gforce; /**< current gravity forces on each axis */ + + WCONST struct ir_t ir; /**< IR data */ + + WCONST unsigned short btns; /**< what buttons have just been pressed */ + WCONST unsigned short btns_held; /**< what buttons are being held down */ + WCONST unsigned short btns_released; /**< what buttons were just released this */ + + WCONST float orient_threshold; /**< threshold for orient to generate an event */ + WCONST int accel_threshold; /**< threshold for accel to generate an event */ + + WCONST struct wiimote_state_t lstate; /**< last saved state */ + + WCONST WIIUSE_EVENT_TYPE event; /**< type of event that occured */ + WCONST byte event_buf[MAX_PAYLOAD]; /**< event buffer */ +} wiimote; + + +/***************************************** + * + * Include API specific stuff + * + *****************************************/ + +#ifdef _WIN32 + #define WIIUSE_EXPORT_DECL __declspec(dllexport) + #define WIIUSE_IMPORT_DECL __declspec(dllimport) +#else + #define WIIUSE_EXPORT_DECL + #define WIIUSE_IMPORT_DECL +#endif + +#ifdef WIIUSE_COMPILE_LIB + #define WIIUSE_EXPORT WIIUSE_EXPORT_DECL +#else + #define WIIUSE_EXPORT WIIUSE_IMPORT_DECL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* wiiuse.c */ +WIIUSE_EXPORT extern const char* wiiuse_version(); + +WIIUSE_EXPORT extern struct wiimote_t** wiiuse_init(int wiimotes); +WIIUSE_EXPORT extern void wiiuse_disconnected(struct wiimote_t* wm); +WIIUSE_EXPORT extern void wiiuse_cleanup(struct wiimote_t** wm, int wiimotes); +WIIUSE_EXPORT extern void wiiuse_rumble(struct wiimote_t* wm, int status); +WIIUSE_EXPORT extern void wiiuse_toggle_rumble(struct wiimote_t* wm); +WIIUSE_EXPORT extern void wiiuse_set_leds(struct wiimote_t* wm, int leds); +WIIUSE_EXPORT extern void wiiuse_motion_sensing(struct wiimote_t* wm, int status); +WIIUSE_EXPORT extern int wiiuse_read_data(struct wiimote_t* wm, byte* buffer, unsigned int offset, unsigned short len); +WIIUSE_EXPORT extern int wiiuse_write_data(struct wiimote_t* wm, unsigned int addr, byte* data, byte len); +WIIUSE_EXPORT extern void wiiuse_status(struct wiimote_t* wm); +WIIUSE_EXPORT extern struct wiimote_t* wiiuse_get_by_id(struct wiimote_t** wm, int wiimotes, int unid); +WIIUSE_EXPORT extern int wiiuse_set_flags(struct wiimote_t* wm, int enable, int disable); +WIIUSE_EXPORT extern float wiiuse_set_smooth_alpha(struct wiimote_t* wm, float alpha); +WIIUSE_EXPORT extern void wiiuse_set_bluetooth_stack(struct wiimote_t** wm, int wiimotes, enum win_bt_stack_t type); +WIIUSE_EXPORT extern void wiiuse_set_orient_threshold(struct wiimote_t* wm, float threshold); +WIIUSE_EXPORT extern void wiiuse_resync(struct wiimote_t* wm); +WIIUSE_EXPORT extern void wiiuse_set_timeout(struct wiimote_t** wm, int wiimotes, byte normal_timeout, byte exp_timeout); +WIIUSE_EXPORT extern void wiiuse_set_accel_threshold(struct wiimote_t* wm, int threshold); + +/* connect.c */ +WIIUSE_EXPORT extern int wiiuse_find(struct wiimote_t** wm, int max_wiimotes, int timeout); +WIIUSE_EXPORT extern int wiiuse_connect(struct wiimote_t** wm, int wiimotes); +WIIUSE_EXPORT extern void wiiuse_disconnect(struct wiimote_t* wm); + +/* events.c */ +WIIUSE_EXPORT extern int wiiuse_poll(struct wiimote_t** wm, int wiimotes); + +/* ir.c */ +WIIUSE_EXPORT extern void wiiuse_set_ir(struct wiimote_t* wm, int status); +WIIUSE_EXPORT extern void wiiuse_set_ir_vres(struct wiimote_t* wm, unsigned int x, unsigned int y); +WIIUSE_EXPORT extern void wiiuse_set_ir_position(struct wiimote_t* wm, enum ir_position_t pos); +WIIUSE_EXPORT extern void wiiuse_set_aspect_ratio(struct wiimote_t* wm, enum aspect_t aspect); +WIIUSE_EXPORT extern void wiiuse_set_ir_sensitivity(struct wiimote_t* wm, int level); + +/* nunchuk.c */ +WIIUSE_EXPORT extern void wiiuse_set_nunchuk_orient_threshold(struct wiimote_t* wm, float threshold); +WIIUSE_EXPORT extern void wiiuse_set_nunchuk_accel_threshold(struct wiimote_t* wm, int threshold); + + +#ifdef __cplusplus +} +#endif + + +#endif /* WIIUSE_H_INCLUDED */ + diff --git a/extra_lib/include/xvid/xvid.h b/extra_lib/include/xvid/xvid.h index 2c7d25d..a33f339 100644 --- a/extra_lib/include/xvid/xvid.h +++ b/extra_lib/include/xvid/xvid.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: xvid.h,v 1.2 2008/12/02 18:04:43 jeanlf Exp $ + * $Id: xvid.h,v 1.2 2008-12-02 18:04:43 jeanlf Exp $ * ****************************************************************************/ diff --git a/extra_lib/include/zlib/zconf.h b/extra_lib/include/zlib/zconf.h index 19892af..dc25590 100644 --- a/extra_lib/include/zlib/zconf.h +++ b/extra_lib/include/zlib/zconf.h @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zconf.h,v 1.2 2008/12/02 18:04:43 jeanlf Exp $ */ +/* @(#) $Id: zconf.h,v 1.2 2008-12-02 18:04:43 jeanlf Exp $ */ #ifndef ZCONF_H #define ZCONF_H diff --git a/extra_lib/lib/arm_ppc02_rel/dummy b/extra_lib/lib/arm_ppc02_rel/dummy deleted file mode 100644 index e69de29..0000000 diff --git a/extra_lib/lib/arm_ppc03_deb/dummy b/extra_lib/lib/arm_ppc03_deb/dummy deleted file mode 100644 index e69de29..0000000 diff --git a/extra_lib/lib/arm_ppc03_rel/dummy b/extra_lib/lib/arm_ppc03_rel/dummy deleted file mode 100644 index e69de29..0000000 diff --git a/extra_lib/lib/gcc/dummy b/extra_lib/lib/gcc/dummy deleted file mode 100644 index e69de29..0000000 diff --git a/extra_lib/lib/w32_deb/dummy b/extra_lib/lib/w32_deb/dummy deleted file mode 100644 index e69de29..0000000 diff --git a/extra_lib/lib/w32_rel/dummy b/extra_lib/lib/w32_rel/dummy deleted file mode 100644 index e69de29..0000000 diff --git a/gpac.spec b/gpac.spec index 892e841..7d98972 100644 --- a/gpac.spec +++ b/gpac.spec @@ -1,4 +1,4 @@ -# $Id: gpac.spec,v 1.5 2008/12/02 18:04:42 jeanlf Exp $ +# $Id: gpac.spec,v 1.5 2008-12-02 18:04:42 jeanlf Exp $ Summary: GPAC is a multimedia framework covering MPEG-4, VRML/X3D and SVG. Name: gpac Version: 0.4.5 diff --git a/gui/gui.bt b/gui/gui.bt new file mode 100644 index 0000000..719f7cd --- /dev/null +++ b/gui/gui.bt @@ -0,0 +1,42 @@ +####################################################################################### +# Hardcoded PROTO node which displays object without taking into account user transforms +####################################################################################### +EXTERNPROTO Untransform [ + exposedField MFNode children [] +] +[ "urn:inet:gpac:builtin:Untransform"] + + + +####################################################################################### +# Main Scene +####################################################################################### + +DEF GPAC_UI OrderedGroup { + children [ + Background2D { backColor 1 1 1} + + DEF MovieControl MediaControl { + loop TRUE + } + DEF Movie Transform2D { + children [ + Inline { url ""} + ] + } + + DEF UI_ROOT Untransform { + children [ + ] + } + + DEF GUIScript Script { + field SFNode root USE GPAC_UI + field SFNode ui_root USE UI_ROOT + field SFNode movie USE Movie + field SFNode movie_ctrl USE MovieControl + + url "gui.js" + } + ] +} diff --git a/gui/gui.js b/gui/gui.js new file mode 100644 index 0000000..b9aa6b6 --- /dev/null +++ b/gui/gui.js @@ -0,0 +1,2018 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Authors: +// Jean Le Feuvre, Telecom ParisTech +// Jean-Claude Dufourd, Telecom ParisTech +// +///////////////////////////////////////////////////////////////////////////////// + + +function new_extension() +{ + var obj = new Object(); + obj.type = 'extension'; + return obj; +} + +//Initialize the main UI script +function initialize() { + //var icon; + var i, count, wid; + + gpac.caption = 'Osmo4'; + + display_width = parseInt( gpac.getOption('General', 'LastWidth') ); + display_height = parseInt( gpac.getOption('General', 'LastHeight') ); + + if (!gpac.fullscreen && display_width && display_height) { + gpac.set_size(display_width, display_height); + } else { + display_width = gpac.get_screen_width(); + display_height = gpac.get_screen_height(); + } + + //request event listeners on the window - GPAC specific extensions !!! + root.addEventListener('resize', on_resize, 0); + root.addEventListener('zoom', on_zoom, 0); + root.addEventListener('scroll', on_scroll, 0); + + widget_default_size = 200; + scene_width = 0; + + icon_size = 48; + dock_height = 48; + info_height = 32; + toggle_bar_height = 16; + screen_dpi = gpac.get_horizontal_dpi(); + + widget_remote_candidate = null; + controlled_renderer = null; + has_upnp = eval("(typeof(UPnP) != 'undefined');"); + if (has_upnp) { + UPnP.onMediaRendererAdd = onMediaRendererAdd; + UPnP.onMediaConnect = onMediaConnect; + UPnP.onMediaStop = onMediaStop; + UPnP.onMediaPause = onMediaPause; + UPnP.onMediaPlay = onMediaPlay; + UPnP.onMigrate = OnMediaMigrate; + UPnP.BindRenderer(); + upnp_renders = null; + } + + /*setup dock*/ + widget_ui_visible = false; + + /*widget subtree*/ + widget_display = new SFNode('Transform2D'); + ui_root.children[0] = widget_display; + + /*widget manager page*/ + widget_ui = new SFNode('Layer2D'); + ui_root.children[1] = widget_ui; + + /*all other UI elements subtree*/ + dlg_display = new SFNode('Transform2D'); + ui_root.children[2] = dlg_display; + + infobar = text_label('', 'MIDDLE'); + ui_root.children[3] = infobar; + + /*our dock*/ + dock = new SFNode('Transform2D'); + ui_root.children[4] = dock; + + + nb_widgets_on_screen = 0; + first_visible_widget = 0; + setup_icons(); + + /*init the widget manager*/ + Browser.loadScript('mpegu-core.js', true); + log_level = l_inf; + widget_manager_init(); + + if (typeof(WidgetManager) != 'undefined') { + WidgetManager.on_widget_remove = widget_remove; + WidgetManager.on_widget_add = widget_insert; + WidgetManager.coreOutSetSize = widget_request_size; + WidgetManager.coreOutShow = widget_request_show; + WidgetManager.coreOutHide = widget_request_hide; + WidgetManager.coreOutRequestActivate = widget_request_activate; + WidgetManager.coreOutRequestDeactivate = widget_request_deactivate; + WidgetManager.coreOutShowNotification = widget_request_notification; + WidgetManager.coreOutPlaceComponent = widget_place_component; + WidgetManager.coreOutGetAttention = widget_request_attention; + + WidgetManager.coreOutInstallWidget = widget_request_install; + WidgetManager.coreOutMigrateComponent = widget_migrate_component; + WidgetManager.coreOutRequestMigrationTargets = widget_migration_targets; + WidgetManager.coreOutActivateTemporaryWidget = widget_activate_temporary_widget; + + /*restore our widgets*/ + widgets_init(); + } + + + /*init all extensions*/ + var list = gpac.enum_directory('extensions', '*', 0); + for (i=0; i=hw) || (2*ry>=hh)) rx = ry = 6; + + temp = this.geometry.point.point; + temp[0] = new SFVec2f(hw-rx, hh); + temp[1] = new SFVec2f(hw, hh);/*bezier ctrl point*/ + temp[2] = new SFVec2f(hw, hh-ry); + temp[3] = new SFVec2f(hw, -hh+ry); + temp[4] = new SFVec2f(hw, -hh);/*bezier control point*/ + temp[5] = new SFVec2f(hw-rx, -hh); + temp[6] = new SFVec2f(-hw+rx, -hh); + temp[7] = new SFVec2f(-hw, -hh);/*bezier control point*/ + temp[8] = new SFVec2f(-hw, -hh+ry); + temp[9] = new SFVec2f(-hw, hh-ry); + temp[10] = new SFVec2f(-hw, hh);/*bezier control point*/ + temp[11] = new SFVec2f(-hw+rx, hh); + } + obj.set_color = function(r, g, b) { + this.appearance.material.emissiveColor.r = r; + this.appearance.material.emissiveColor.g = g; + this.appearance.material.emissiveColor.b = b; + } + return obj; +} + +function icon_button(url, label, no_back) +{ + var obj = new SFNode('Transform2D'); + obj.visible = true; + obj.children[0] = new SFNode('Transform2D'); + obj.children[0].scale.x = 0; + obj.children[0].children[0] = rectangle(); + + obj.children[1] = new SFNode('Layer2D'); + obj.children[1].size.x = icon_size; + obj.children[1].size.y = icon_size; + obj.children[1].children[0] = new SFNode('Inline'); + obj.children[1].children[0].url[0] = url; + + obj.touch = new SFNode('TouchSensor'); + obj.children[1].children[1] = obj.touch; + obj.button_click = NULL; + obj.down = false; + obj.over = false; + obj.on_active = function(value) { + if (value) { + this.down = true; + } else { + if (this.down && this.over && this.button_click) this.button_click(); + this.down = false; + } + }; + obj.button_over = on_icon_over; + obj.on_over = function(value) { + this.over = value; + if (!no_back) + this.children[0].scale.x = value ? 1 : 0; + if (this.button_over) this.button_over(value); + }; + Browser.addRoute(obj.touch, 'isOver', obj, obj.on_over); + Browser.addRoute(obj.touch, 'isActive', obj, obj.on_active); + obj.label = label; + obj.hide = function() { this.scale.x = this.scale.y = 0; this.visible = false; }; + obj.show = function() { this.scale.x = this.scale.y = 1; this.visible = true; }; + obj.set_size = function(x, y) { + this.children[0].children[0].set_size(x, y); + this.children[1].size.x = x; + this.children[1].size.y = y; + }; + return obj; +} + +function text_label(label, justify) +{ + var obj = new SFNode('Transform2D'); + obj.children[0] = new SFNode('Shape'); + obj.children[0].appearance = new SFNode('Appearance'); + obj.children[0].appearance.material = new SFNode('Material2D'); + obj.children[0].appearance.material.filled = TRUE; + obj.children[0].appearance.material.emissiveColor = new SFColor(0, 0, 0); + obj.children[0].geometry = new SFNode('Text'); + obj.children[0].geometry.string[0] = label; + obj.children[0].geometry.fontStyle = new SFNode('FontStyle'); + obj.children[0].geometry.fontStyle.justify[0] = justify; + obj.children[0].geometry.fontStyle.justify[1] = 'MIDDLE'; + obj.children[0].geometry.fontStyle.size = 20; + obj.set_label = function(value) { + this.children[0].geometry.string[0] = value; + } + return obj; +} + + +function text_rect(label) +{ + var obj = new SFNode('Transform2D'); + obj.children[0] = rectangle(); + obj.children[0].set_color(0.7, 0.7, 0.8); + + obj.children[1] = new SFNode('Shape'); + obj.children[1].appearance = new SFNode('Appearance'); + obj.children[1].appearance.material = new SFNode('Material2D'); + obj.children[1].appearance.material.filled = TRUE; + obj.children[1].appearance.material.emissiveColor = new SFColor(0, 0, 0); + obj.children[1].geometry = new SFNode('Text'); + obj.children[1].geometry.string[0] = label; + obj.children[1].geometry.fontStyle = new SFNode('FontStyle'); + obj.children[1].geometry.fontStyle.justify[0] = 'MIDDLE'; + obj.children[1].geometry.fontStyle.justify[1] = 'MIDDLE'; + obj.children[1].geometry.fontStyle.size = 20; + obj.children[2] = new SFNode('TouchSensor'); + + obj.set_size = function(w, h) { + this.children[0].set_size(w, h); + }; + + + obj.over = false; + obj.on_over = function(value) { + this.children[0].set_color(0.7, value ? 0.5 : 0.7, 0.8); + this.over = value; + }; + Browser.addRoute(obj.children[2], 'isOver', obj, obj.on_over); + + obj.down = false; + obj.button_click = null; + obj.on_active = function(value) { + if (value) { + this.down = true; + } else { + if (this.down && this.over && this.button_click) this.button_click(); + this.down = false; + } + }; + Browser.addRoute(obj.children[2], 'isActive', obj, obj.on_active); + + return obj; +} + +function new_slider(vertical) +{ + var obj = new SFNode('Transform2D'); + obj.children[0] = new SFNode('Shape'); + obj.children[0].appearance = new SFNode('Appearance'); + obj.children[0].appearance.material = new SFNode('Material2D'); + obj.children[0].appearance.material.filled = TRUE; + obj.children[0].appearance.texture = new SFNode('LinearGradient'); + obj.children[0].appearance.texture.endPoint.x = vertical ? 1 : 0; + obj.children[0].appearance.texture.endPoint.y = vertical ? 0 : 1; + obj.children[0].appearance.texture.key[0] = 0; + obj.children[0].appearance.texture.key[1] = 0.5; + obj.children[0].appearance.texture.key[2] = 1; + obj.children[0].appearance.texture.keyValue[0] = new SFColor(0.4, 0.4, 0.6); + obj.children[0].appearance.texture.keyValue[1] = new SFColor(0.4, 0.4, 1); + obj.children[0].appearance.texture.keyValue[2] = new SFColor(0.4, 0.4, 0.6); + obj.children[0].geometry = new SFNode('Rectangle'); + + obj.children[1] = new SFNode('Transform2D'); + obj.children[1].children[0] = new SFNode('Shape'); + obj.children[1].children[0].appearance = new SFNode('Appearance'); + obj.children[1].children[0].appearance.material = new SFNode('Material2D'); + obj.children[1].children[0].appearance.material.filled = TRUE; + obj.children[1].children[0].appearance.material.emissiveColor = new SFColor(0, 0, 1); + obj.children[1].children[0].geometry = new SFNode('Circle'); + + obj.on_slide = function(value) { } + obj.children[2] = new SFNode('PlaneSensor2D'); + obj.set_translation = function(value) { + this.frac = 0.5 + (vertical ? value.y/this.height : value.x/this.width); + this.children[1].translation = value; + this.on_slide(this.min + (this.max-this.min) * this.frac); + } + Browser.addRoute(obj.children[2], 'translation_changed', obj, obj.set_translation); + + + obj.set_value = function(value) { + value -= this.min; + if (value<0) value = 0; + else if (value>this.max-this.min) value = this.max-this.min; + if (this.max==this.min) value = 0; + else value /= (this.max-this.min); + + value -= 0.5; + value *= (vertical ? this.height : this.width); + + if (vertical) { + this.children[1].translation.y = value; + this.children[2].offset.y = value; + } else { + this.children[1].translation.x = value; + this.children[2].offset.x = value; + } + } + + obj.radius = 10; + obj.vertical = vertical; + obj.set_size = function(w, h) { + var rad; + this.children[0].geometry.size.x = w; + this.children[0].geometry.size.y = h; + rad = vertical ? w : h; + rad/=1.33; + this.children[1].children[0].geometry.radius = rad; + this.children[2].maxPosition.x = this.vertical ? 0 : w/2; + this.children[2].maxPosition.y = this.vertical ? h/2 : 0; + this.children[2].minPosition.x = this.vertical ? 0 : -w/2; + this.children[2].minPosition.y = this.vertical ? -h/2 : 0; + this.width = w; + this.height = h; + } + obj.min = 0; + obj.max = 100; + + obj.set_size(vertical ? 10 : 200, vertical ? 200 : 10); + return obj; +} + +function new_radio_button(label) +{ + var obj = new SFNode('Transform2D'); + obj.children[0] = new SFNode('Shape'); + obj.children[0].appearance = new SFNode('Appearance'); + obj.children[0].appearance.material = new SFNode('Material2D'); + obj.children[0].appearance.material.filled = TRUE; + obj.children[0].appearance.material.emissiveColor = new SFColor(1, 1, 1); + obj.children[0].appearance.material.lineProps = new SFNode('LineProperties'); + obj.children[0].appearance.material.lineProps.lineColor = new SFColor(0, 0, 0); + obj.children[0].appearance.material.lineProps.width = 1; + obj.children[0].geometry = new SFNode('Circle'); + + obj.children[1] = new SFNode('Shape'); + obj.children[1].appearance = new SFNode('Appearance'); + obj.children[1].appearance.material = new SFNode('Material2D'); + obj.children[1].appearance.material.filled = TRUE; + obj.children[1].appearance.material.emissiveColor = new SFColor(0, 0, 0); + obj.children[1].appearance.material.transparency = 1; + obj.children[1].geometry = new SFNode('Circle'); + + obj.children[2] = text_label(label, 'BEGIN'); + + obj.children[3] = new SFNode ('TouchSensor'); + + obj.on = false; + obj.on_select = function(value) {} + obj.on_active = function(value) { + if (!value) return; + this.on = !this.on; + this.children[1].appearance.material.transparency = this.on ? 0 : 1; + this.on_select(this.on); + } + Browser.addRoute(obj.children[3], 'isActive', obj, obj.on_active); + + obj.enable = function(value) { + this.on = value; + this.children[1].appearance.material.transparency = this.on ? 0 : 1; + } + + obj.set_width = function(w, h) { + var rad = w0) { + info.children[i++] = text_label(txt.substring(0, idx), 'BEGIN'); + txt = txt.substring(idx+1, txt.length); + } else { + info.children[i++] = text_label(txt, 'BEGIN'); + break; + } + } + + info_dlg.ifce_idx = info_dlg.children.length; + info = text_rect('Interfaces (count: ' + wid.num_interfaces + ' - bound: ' + wid.num_bound_interfaces+')', 'BEGIN'); + info_dlg.children[info_dlg.ifce_idx] = info; + info.visible = false; + info.button_click = function() { + this.visible = !this.visible; + layout(); + } + i=3; + for (j=0; jdisplay_width) { + start_x = (icon_size-display_width)/2; + } else { + start_x = (icon_size-tot_len)/2; + } + /*translate / size all items in the dock*/ + for (i=0;i0) { + first_visible_widget += nb_wid; + } + + if (first_visible_widget) widget_ui.prev.show(); + else widget_ui.prev.hide(); + + if (first_visible_widget+nb_wid < count) widget_ui.next.show(); + else widget_ui.next.hide(); + + for (i=0; i= count) { + break; + } + wid = widget_ui.children[i +first_visible_widget+widget_ui.nb_tools]; + wid.show(); + wid.set_size(icon_size, icon_size); + wid.translation.x = start_x; + wid.translation.y = start_y; + start_x += icon_size + spread_x; + if (start_x + icon_size / 2 >= display_width/2) { + start_x = (icon_size-display_width)/2 + spread_x/2; + start_y -= icon_size; + } + nb_widgets_on_screen = i+1; + if (start_y - icon_size < (dock_height-display_height)/2) { + i++; + break; + } + } +} + +//performs layout on all contents +function layout() { + var i, list, start_x; + + gpac.setOption('General', 'LastWidth', ''+display_width); + gpac.setOption('General', 'LastHeight', ''+display_height); + + if (dlg_display.children.length) { + widget_display.scale.x = 0; + widget_ui_visible = false; + } + //layout all icons in the dock + dock_layout(); + widget_ui_layout(0); + + if (dlg_display.children.length) { + list = dlg_display.children; + for (i=0; i 0) { + break; + } + } + return icon; +} + +//initialize GPAC widget manager and load all widgets +function widgets_init() { + + count = WidgetManager.num_widgets; + for (i=0; i 1 && args[1] != null) { + alert('Migrating component to ' + UPnP.GetMediaRenderer(parseInt(args[1])).Name); + WidgetManager.migrate_widget(UPnP.GetMediaRenderer(parseInt(args[1])), comp); + widget_close(comp); + } else { + widget_remote_candidate = wid; + on_upnpopen(false, false); + } + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.migrateComponentMessage, ifce.get_message("migrateComponent"), wid, 1); // send return code 1 = success + } +} + +function widget_migration_targets(wid, args) +{ + var count = UPnP.MediaRenderersCount, codes = new Array(), names = new Array(), descriptions = new Array(), i; + + for (i = 0; i < count; i++) { + var render = UPnP.GetMediaRenderer(i); + codes.push(""+i); + names.push(render.Name); + descriptions.push(render.HostName +" "+ render.UUID); + } + i = null; + var ifce_count = wid.num_interfaces, j; + for (j = 0; j < ifce_count; j++) { + var ifce = wid.get_interface(j); + if (ifce.type == "urn:mpeg:mpegu:schema:widgets:core:out:2010") { + i = ifce; + break; + } + } + if (i != null) { + wmjs_core_out_invoke_reply(coreOut.requestMigrationTargetsMessage, i.get_message("requestMigrationTargets"), + wid, codes, names, descriptions); + } +} + + +// +// implementation of core:out activate temporary widget +// +function widget_activate_temporary_widget(wid, args) { + var w = WidgetManager.open(args[0], null); + if (w != null) widget_launch(w); + var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010"); + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.activateTemporaryWidgetMessage, ifce.get_message("activateTemporaryWidget"), + wid, (w != null ? 1 : 0)); // send return code 1 = success + } +} + + + +function insert_widget_icon(new_wid, no_layout) { + var icon; + icon = icon_button(widget_get_icon(new_wid), new_wid.name, 0); + icon.tooltip = new_wid.name; + new_wid.in_panel = true; + new_wid.visible = false; + new_wid.icon_dock = icon; + icon.button_click = on_widget_launch; + icon.widget = new_wid; + widget_ui.addChildren[0] = new_wid.icon_dock; + if (!no_layout) layout(); +} + +function scan_directory(dir) +{ + var i, j, count, list, new_wid, uri; + list = gpac.enum_directory(dir, '.xml;.wgt;.mgt', 0); + for (i=0; i this.list.length) this.first = this.list.length - this.nb_items; + } + if (this.first) this.children[1].show(); + if (this.first+this.nb_items < this.list.length) this.children[2].show(); + + for (i=0; i=this.list.length) break; + item = text_rect(this.list[i+this.first].name); + item.path = this.list[i+this.first].path; + item.name = this.list[i+this.first].name; + item.directory = this.list[i+this.first].directory; + item.filebrowse = this; + if (this.upnp_mode) { + item.is_server = this.list[i+this.first].is_server; + item.resource_uri = this.list[i+this.first].resource_uri; + item.button_click = function() { + if (this.directory) { + if (this.is_server) { + this.filebrowse.server_uuid = this.path; + } else { + this.filebrowse.directory = this.path; + } + this.filebrowse.browse(false); + } else { + dlg_display.children.length = 0; + if (this.filebrowse.on_browse) { + this.filebrowse.on_browse(this.resource_uri, null); + } + } + }; + } else { + item.button_click = function() { + if (this.directory) { + this.filebrowse.directory = this.path + this.name; + this.filebrowse.browse(false); + } else { + dlg_display.children.length = 0; + if (this.filebrowse.on_browse) { + this.filebrowse.on_browse(this.path + this.name, this.filebrowse.directory); + } + } + }; + } + this.children[this.nb_tools+i] = item; + } + this.set_size(this.width, this.height); + } + + + filebrowse.set_size = function(w, h) { + var i, x, y, isize, nbi; + isize = 24; + if (w>display_width - isize) w = display_width - isize; + + this.width = w; + this.height = h; + + i = 1; + while ((i+1)*isize <= h - isize) i++; + + if (i != this.nb_items) { + this.nb_items = i; + this.layout(0); + return; + } + x = -w/2 + isize/2; + y = h/2 - isize/2; + + for (i=0;ii+1) { + this.children[i].set_size(isize, isize); + } + this.children[i].translation.x = x; + this.children[i].translation.y = y; + x += isize; + } + y-=isize; + while (ithis.nb_items) count = this.nb_items-1; + + item = text_rect('Close'); + item.button_click = function() { + dlg_display.children.length = 0; + upnp_renders=null; + widget_display.scale.x = 1; + infobar.set_label(''); + } + this.children[this.children.length] = item; + + if (!remote_only) { + str = (controlled_renderer==null) ? '+ ' : ''; + str += 'Local Renderer'; + item = text_rect(str); + item.button_click = function() { + dlg_display.children.length = 0; + upnp_renders=null; + widget_display.scale.x = 1; + infobar.set_label(''); + controlled_renderer = null; + } + this.children[this.children.length] = item; + } + + for (i=0; i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Internet Category + + + Jakub Steiner + + + + + Tuomas Kuosmanen + + + + http://jimmac.musichall.cz + + + internet + tools + applications + category + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/applications-multimedia.svg b/gui/icons/applications-multimedia.svg new file mode 100644 index 0000000..abbf80a --- /dev/null +++ b/gui/icons/applications-multimedia.svg @@ -0,0 +1,498 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Multimedia Category + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + video + multimedia + category + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/applications-system.svg b/gui/icons/applications-system.svg new file mode 100644 index 0000000..9d76774 --- /dev/null +++ b/gui/icons/applications-system.svg @@ -0,0 +1,247 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + System Applications + + + Jakub Steiner + + + http://jimmac.musichall.cz/ + + + system + applications + group + category + admin + root + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/audio-volume-high.svg b/gui/icons/audio-volume-high.svg new file mode 100644 index 0000000..c8b4202 --- /dev/null +++ b/gui/icons/audio-volume-high.svg @@ -0,0 +1,643 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Volume - High + + + Jakub Steiner + + + + + Lapo Calamandrei + + + + + + http://www.tango-project.org + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/audio-volume-low.svg b/gui/icons/audio-volume-low.svg new file mode 100644 index 0000000..f29437c --- /dev/null +++ b/gui/icons/audio-volume-low.svg @@ -0,0 +1,641 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Volume - Low + + + Jakub Steiner + + + + + Lapo Calamandrei + + + + + + http://www.tango-project.org + + + + + volume + sound + level + low + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/audio-volume-medium.svg b/gui/icons/audio-volume-medium.svg new file mode 100644 index 0000000..e9bcb65 --- /dev/null +++ b/gui/icons/audio-volume-medium.svg @@ -0,0 +1,646 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Volume - Medium + + + Jakub Steiner + + + + + Lapo Calamandrei + + + + + + http://www.tango-project.org + + + + + volume + sound + level + medium + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/audio-volume-muted.svg b/gui/icons/audio-volume-muted.svg new file mode 100644 index 0000000..3e8d570 --- /dev/null +++ b/gui/icons/audio-volume-muted.svg @@ -0,0 +1,991 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Volume - Muted + + + Jakub Steiner + + + + + Lapo Calamandrei + + + + + + http://www.tango-project.org + + + + + volume + sound + level + none + mute + muted + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/audio-x-generic.svg b/gui/icons/audio-x-generic.svg new file mode 100644 index 0000000..239d001 --- /dev/null +++ b/gui/icons/audio-x-generic.svg @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Generic Audio + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/battery-caution.svg b/gui/icons/battery-caution.svg new file mode 100644 index 0000000..4eaa58f --- /dev/null +++ b/gui/icons/battery-caution.svg @@ -0,0 +1,625 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Battery - Caution + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + battery + apm + acpi + power management + caution + + + + + + Garrett LeSage + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/camera-photo.svg b/gui/icons/camera-photo.svg new file mode 100644 index 0000000..25435e0 --- /dev/null +++ b/gui/icons/camera-photo.svg @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + Photo Camera + + + camera + photo + SLR + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/camera-video.svg b/gui/icons/camera-video.svg new file mode 100644 index 0000000..28259eb --- /dev/null +++ b/gui/icons/camera-video.svg @@ -0,0 +1,1257 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Camera / Video + + + Jakub Steiner + + + http://jimmac.musichall.cz/ + + + camera + camcorder + video + cam + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/dialog-error.svg b/gui/icons/dialog-error.svg new file mode 100644 index 0000000..602fa79 --- /dev/null +++ b/gui/icons/dialog-error.svg @@ -0,0 +1,316 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Rodney Dawes + + + + + Jakub Steiner, Garrett LeSage + + + + Dialog Error + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/dialog-information.svg b/gui/icons/dialog-information.svg new file mode 100644 index 0000000..1e957cc --- /dev/null +++ b/gui/icons/dialog-information.svg @@ -0,0 +1,1145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Info + + + Jakub Steiner + + + + + dialog + info + + + http://jimmac.musichall.cz + + + + Garrett LeSage + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/dialog-warning.svg b/gui/icons/dialog-warning.svg new file mode 100644 index 0000000..51f7ff3 --- /dev/null +++ b/gui/icons/dialog-warning.svg @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Dialog Warning + 2005-10-14 + + + Andreas Nilsson + + + + + Jakub Steiner, Garrett LeSage + + + + + dialog + warning + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/document-new.svg b/gui/icons/document-new.svg new file mode 100644 index 0000000..1bfdb16 --- /dev/null +++ b/gui/icons/document-new.svg @@ -0,0 +1,448 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + New Document + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/document-print-preview.svg b/gui/icons/document-print-preview.svg new file mode 100644 index 0000000..9698d5e --- /dev/null +++ b/gui/icons/document-print-preview.svg @@ -0,0 +1,701 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Print Preview + + + Jakub Steiner + + + + http://jimmac.musichall.cz + + + printer + local + laser + bubblejet + inkjet + print + output + cups + lpd + preview + + + + + Corey Woodworth + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/document-print.svg b/gui/icons/document-print.svg new file mode 100644 index 0000000..bb3d43d --- /dev/null +++ b/gui/icons/document-print.svg @@ -0,0 +1,530 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Print Document + + + Jakub Steiner + + + + http://jimmac.musichall.cz + + + document + lpr + print + local + laser + bubblejet + inkjet + print + output + cups + lpd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/document-save-as.svg b/gui/icons/document-save-as.svg new file mode 100644 index 0000000..09fa340 --- /dev/null +++ b/gui/icons/document-save-as.svg @@ -0,0 +1,661 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Save As + + + Jakub Steiner + + + + + hdd + hard drive + save as + io + store + + + + + http://jimmac.musichall.cz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/document-save.svg b/gui/icons/document-save.svg new file mode 100644 index 0000000..6be29c4 --- /dev/null +++ b/gui/icons/document-save.svg @@ -0,0 +1,617 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Save + + + Jakub Steiner + + + + + hdd + hard drive + save + io + store + + + + + http://jimmac.musichall.cz + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/emblem-unreadable.svg b/gui/icons/emblem-unreadable.svg new file mode 100644 index 0000000..82a4a4f --- /dev/null +++ b/gui/icons/emblem-unreadable.svg @@ -0,0 +1,357 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Unreadable + + + emblem + access + denied + unreadable + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/face-surprise.svg b/gui/icons/face-surprise.svg new file mode 100644 index 0000000..b40a301 --- /dev/null +++ b/gui/icons/face-surprise.svg @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Face - Shocked + + + emoticon + emote + smiley + stare + shocked + :O + + + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/folder.svg b/gui/icons/folder.svg new file mode 100644 index 0000000..2027f56 --- /dev/null +++ b/gui/icons/folder.svg @@ -0,0 +1,422 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Folder Icon + + + + Jakub Steiner + + + + http://jimmac.musichall.cz + + + folder + directory + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/go-bottom.svg b/gui/icons/go-bottom.svg new file mode 100644 index 0000000..fe87dc3 --- /dev/null +++ b/gui/icons/go-bottom.svg @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go to Bottom + + + go + bottom + + + + + Andreas Nilsson + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/go-down.svg b/gui/icons/go-down.svg new file mode 100644 index 0000000..18dadc4 --- /dev/null +++ b/gui/icons/go-down.svg @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Down + + + go + lower + down + arrow + pointer + > + + + + + Andreas Nilsson + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/go-first.svg b/gui/icons/go-first.svg new file mode 100644 index 0000000..e79e0e1 --- /dev/null +++ b/gui/icons/go-first.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Previous + + + go + previous + left + arrow + pointer + < + + + + + Andreas Nilsson + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/go-home.svg b/gui/icons/go-home.svg new file mode 100644 index 0000000..3520b51 --- /dev/null +++ b/gui/icons/go-home.svg @@ -0,0 +1,441 @@ + +image/svg+xmlGo HomeJakub Steinerhttp://jimmac.musichall.czhomereturngodefaultuserdirectoryTuomas Kuosmanen + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gui/icons/go-jump.svg b/gui/icons/go-jump.svg new file mode 100644 index 0000000..3e0517f --- /dev/null +++ b/gui/icons/go-jump.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Jump + + + go + jump + seek + arrow + pointer + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/go-last.svg b/gui/icons/go-last.svg new file mode 100644 index 0000000..e2331cb --- /dev/null +++ b/gui/icons/go-last.svg @@ -0,0 +1,203 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Next + + + go + next + right + arrow + pointer + > + + + + + Andreas Nilsson + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/go-next.svg b/gui/icons/go-next.svg new file mode 100644 index 0000000..989bff5 --- /dev/null +++ b/gui/icons/go-next.svg @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Next + + + go + next + right + arrow + pointer + > + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/go-previous.svg b/gui/icons/go-previous.svg new file mode 100644 index 0000000..f1eb977 --- /dev/null +++ b/gui/icons/go-previous.svg @@ -0,0 +1,852 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Previous + + + go + previous + left + arrow + pointer + < + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/go-top.svg b/gui/icons/go-top.svg new file mode 100644 index 0000000..a25edbb --- /dev/null +++ b/gui/icons/go-top.svg @@ -0,0 +1,972 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Top + + + go + highest + top + arrow + pointer + > + + + + + Andreas Nilsson + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/go-up.svg b/gui/icons/go-up.svg new file mode 100644 index 0000000..0e3d01d --- /dev/null +++ b/gui/icons/go-up.svg @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Go Up + + + go + higher + up + arrow + pointer + > + + + + + Andreas Nilsson + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/image-missing.svg b/gui/icons/image-missing.svg new file mode 100644 index 0000000..e585fd8 --- /dev/null +++ b/gui/icons/image-missing.svg @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Broken Image + + + image + picture + photo + missing + broken + 404 + + + + + Garrett LeSage + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/left_arrow.svg b/gui/icons/left_arrow.svg new file mode 100644 index 0000000..75f49f1 --- /dev/null +++ b/gui/icons/left_arrow.svg @@ -0,0 +1,374 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Seek Backward + + + Lapo Calamandrei + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/list-add.svg b/gui/icons/list-add.svg new file mode 100644 index 0000000..a514a01 --- /dev/null +++ b/gui/icons/list-add.svg @@ -0,0 +1,434 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Add + 2006-01-04 + + + Andreas Nilsson + + + http://tango-project.org + + + add + plus + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/list-remove.svg b/gui/icons/list-remove.svg new file mode 100644 index 0000000..67da191 --- /dev/null +++ b/gui/icons/list-remove.svg @@ -0,0 +1,422 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Remove + 2006-01-04 + + + Andreas Nilsson + + + http://tango-project.org + + + remove + delete + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/media-eject.svg b/gui/icons/media-eject.svg new file mode 100644 index 0000000..eb76b24 --- /dev/null +++ b/gui/icons/media-eject.svg @@ -0,0 +1,439 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Playback Start + + + Jakub Steiner + + + + + + media + eject + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/media-playback-pause.svg b/gui/icons/media-playback-pause.svg new file mode 100644 index 0000000..56e1d6b --- /dev/null +++ b/gui/icons/media-playback-pause.svg @@ -0,0 +1,630 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Playback Pause + + + Lapo Calamandrei + + + + + + media + pause + playback + video + music + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/media-playback-start.svg b/gui/icons/media-playback-start.svg new file mode 100644 index 0000000..09195da --- /dev/null +++ b/gui/icons/media-playback-start.svg @@ -0,0 +1,308 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Playback Start + + + Lapo Calamandrei + + + + + + play + media + music + video + player + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/media-playback-stop.svg b/gui/icons/media-playback-stop.svg new file mode 100644 index 0000000..70cb229 --- /dev/null +++ b/gui/icons/media-playback-stop.svg @@ -0,0 +1,640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Playback Pause + + + Lapo Calamandrei + + + + + + media + stop + playback + video + music + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/media-record.svg b/gui/icons/media-record.svg new file mode 100644 index 0000000..d71e455 --- /dev/null +++ b/gui/icons/media-record.svg @@ -0,0 +1,326 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Record + + + Lapo Calamandrei + + + + + + media + player + record + music + sound + video + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/media-seek-backward.svg b/gui/icons/media-seek-backward.svg new file mode 100644 index 0000000..04e9f68 --- /dev/null +++ b/gui/icons/media-seek-backward.svg @@ -0,0 +1,363 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Seek Backward + + + Lapo Calamandrei + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/media-seek-forward.svg b/gui/icons/media-seek-forward.svg new file mode 100644 index 0000000..197db29 --- /dev/null +++ b/gui/icons/media-seek-forward.svg @@ -0,0 +1,370 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Seek Forward + + + Lapo Calamandrei + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/media-skip-backward.svg b/gui/icons/media-skip-backward.svg new file mode 100644 index 0000000..7e84148 --- /dev/null +++ b/gui/icons/media-skip-backward.svg @@ -0,0 +1,1014 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Skip Backward + + + Lapo Calamandrei + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/media-skip-forward.svg b/gui/icons/media-skip-forward.svg new file mode 100644 index 0000000..137d948 --- /dev/null +++ b/gui/icons/media-skip-forward.svg @@ -0,0 +1,1002 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Skip Forward + + + Lapo Calamandrei + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/process-stop.svg b/gui/icons/process-stop.svg new file mode 100644 index 0000000..72b78f0 --- /dev/null +++ b/gui/icons/process-stop.svg @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Stop + 2005-10-16 + + + Andreas Nilsson + + + + + stop + halt + error + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/right_arrow.svg b/gui/icons/right_arrow.svg new file mode 100644 index 0000000..b1b9fe9 --- /dev/null +++ b/gui/icons/right_arrow.svg @@ -0,0 +1,383 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Media Seek Forward + + + Lapo Calamandrei + + + + + + Jakub Steiner + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/tennis_ball.svg b/gui/icons/tennis_ball.svg new file mode 100644 index 0000000..e68f1cf --- /dev/null +++ b/gui/icons/tennis_ball.svg @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/tennis_black.svg b/gui/icons/tennis_black.svg new file mode 100644 index 0000000..66d156b --- /dev/null +++ b/gui/icons/tennis_black.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + image/svg+xml + + Other map symbols + + + Mohamed Ibrahim + + + + + Public Domain + + + + + clker.com + + + + + other map symbols + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gui/icons/tennis_racket.svg b/gui/icons/tennis_racket.svg new file mode 100644 index 0000000..dc242a5 --- /dev/null +++ b/gui/icons/tennis_racket.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/gui/icons/tennis_racket_color.svg b/gui/icons/tennis_racket_color.svg new file mode 100644 index 0000000..7cde756 --- /dev/null +++ b/gui/icons/tennis_racket_color.svg @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/user-trash.svg b/gui/icons/user-trash.svg new file mode 100644 index 0000000..9943ebb --- /dev/null +++ b/gui/icons/user-trash.svg @@ -0,0 +1,487 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Trash Empty + 2003-02-04 + + + Jakub Steiner + + + + + trash + delete + deleted files + waste + recycle + bin + empty + + + + + Novell, Inc. + + + + + + Garrett LeSage + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/video-display.svg b/gui/icons/video-display.svg new file mode 100644 index 0000000..97ea133 --- /dev/null +++ b/gui/icons/video-display.svg @@ -0,0 +1,487 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + Video Display + + + + Jakub Steiner + + + + + video + display + monitor + LCD + CRT + + + + http://jimmac.musichall.cz/ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/video-x-generic.svg b/gui/icons/video-x-generic.svg new file mode 100644 index 0000000..d575550 --- /dev/null +++ b/gui/icons/video-x-generic.svg @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + Generic Video + + + video + audio + multimedia + movie + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/icons/view-fullscreen.svg b/gui/icons/view-fullscreen.svg new file mode 100644 index 0000000..2d61d91 --- /dev/null +++ b/gui/icons/view-fullscreen.svg @@ -0,0 +1,520 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + Jakub Steiner + + + http://jimmac.musichall.cz + + View Fullscreen + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/gui/iphone_wm_gui.js b/gui/iphone_wm_gui.js new file mode 100644 index 0000000..e3ea4d9 --- /dev/null +++ b/gui/iphone_wm_gui.js @@ -0,0 +1,1364 @@ +// to make sure the initialization fis done only once +var init = true; + +// constant +var xlinkns = 'http://www.w3.org/1999/xlink'; +var evns = 'http://www.w3.org/2001/xml-events'; + +// state of the widget manager: displays homepage (value=home) or executes widget (value="exec") +var state = 'home'; + +// convenience variables for SVG elements +var homepage, arrows, icons, widgetContainer, root, homebar, execbar; + +// where is the index into pages of icons on the home page +var where = 0, maxwhere = 0, whereW = 0; + +// array of activated widgets +var activatedWidgets = new Array(); +var numActivatedWidgets = 0; + +// variables for flexible layout +// variables for flexible layout +var totalWidth, totalHeight, iconNbHoriz, iconNbVert, iconsPerPage; + +//previous size +var previousWidth = 0, previousHeight = 0; + +// to differentiate between install icon and scan dir for icons +var isThisAScan; + +// preferred icon type +var preferredIconType = '.svg'; + +function setPreferredSize() { + var display_width = parseInt(gpac.getOption('Widgets', 'LastWMWidth')); + var display_height = parseInt(gpac.getOption('Widgets', 'LastWMHeight')); + if (display_width && display_height) { + gpac.set_size(display_width, display_height); + } +} + +// adapt layout to the size of the screen +function adaptLayoutToSize() { + if (l_deb < log_level) alert("[UI] adaptLayoutToSize"); + var tmpObject, tmpObj2; + // get size to adapt to + totalWidth = root.viewport.width; + totalHeight = root.viewport.height; + if (totalWidth == 0) totalWidth = 160; + if (totalHeight == 0) totalHeight = 280; + while (totalWidth < 160 || totalHeight < 280) { + totalWidth *= 4; + totalHeight *= 4; + } + // min size is 160 by 280 + if (totalWidth < 160) totalWidth = 160; + if (totalHeight < 280) totalHeight = 280; + // round to lower multiple of 80 + totalWidth -= totalWidth % 80; + var iconHeight = totalHeight - 120; + iconHeight -= iconHeight % 80; + // how many lines and columns of icons + iconNbHoriz = totalWidth / 80; + iconNbVert = iconHeight / 80; + totalHeight = iconHeight + 120; + // 120 is upper bar (60) + lower bar (60) + iconsPerPage = iconNbHoriz * iconNbVert; + // fix svg viewbox + document.getElementById("svg").setAttribute("viewBox", "0 0 " + totalWidth + " " + totalHeight); + // fix odd line + tmpObj2 = document.getElementById("odd"); + var i, already = tmpObj2.getElementsByTagName("use").length; + //alert("odd line "+already+" "+iconNbHoriz); + for (i = already; i < iconNbHoriz; i++) { + tmpObject = document.createElement("use"); + tmpObject.setAttribute("x", i * 80); + tmpObject.setAttributeNS(xlinkns, "href", (((i % 2) == 0) ? "#lightRect" : "#darkRect" )); + tmpObj2.appendChild(tmpObject); + } + // fix even line + tmpObj2 = document.getElementById("even"); + already = tmpObj2.getElementsByTagName("use").length; + //alert("even line "+already+" "+iconNbHoriz); + for (i = already; i < iconNbHoriz; i++) { + tmpObject = document.createElement("use"); + tmpObject.setAttribute("x", i * 80); + tmpObject.setAttributeNS(xlinkns, "href", (((i % 2) == 0) ? "#darkRect" : "#lightRect" )); + tmpObj2.appendChild(tmpObject); + } + // fix frame (black with rounded corners) + tmpObject = document.getElementById("frame"); + tmpObject.setAttribute("width", totalWidth); + tmpObject.setAttribute("height", totalHeight); + tmpObject = document.getElementById("frame2"); + tmpObject.setAttribute("width", totalWidth); + tmpObject.setAttribute("height", totalHeight); + // fix screen (white) + tmpObject = document.getElementById("screen"); + tmpObject.setAttribute("width", totalWidth); + tmpObject.setAttribute("height", totalHeight - 120); + // fix grid back (gray) + tmpObject = document.getElementById("gridback"); + tmpObject.setAttribute("width", totalWidth); + tmpObject.setAttribute("height", totalHeight - 120); + // fix icon background grid + tmpObject = document.getElementById("grid"); + already = tmpObject.getElementsByTagName("use").length; + for (i = already; i < iconNbVert; i++) { + tmpObj2 = document.createElement("use"); + tmpObj2.setAttribute("y", i * 80); + tmpObj2.setAttributeNS(xlinkns, "href", (((i % 2) == 0) ? "#odd" : "#even" )); + tmpObject.appendChild(tmpObj2); + } + // if there are already too many lines, remove the extra ones otherwise they are rendered on top of the lower + // part of the decoration + if (already > iconNbVert) { + while (already-- > iconNbVert) tmpObject.removeChild(tmpObject.lastChild); + } + // fix commands (lower bar) + document.getElementById("commands").setAttribute("transform", "translate(0, " + (totalHeight - 60) + ")"); + document.getElementById("homeButton").setAttribute("transform", "translate(" + (totalWidth / 2) + ", 30)"); + document.getElementById("right").setAttribute("transform", "translate(" + (totalWidth - 50) + ", 10)"); + document.getElementById("rightW").setAttribute("transform", "translate(" + (totalWidth - 50) + ", 10)"); + // fix the cuts (white rects left and right because we have no clipping) + tmpObject = document.getElementById("leftCut"); + tmpObject.setAttribute("width", totalWidth); + tmpObject.setAttribute("height", totalHeight); + tmpObject.setAttribute("x", -1 - totalWidth); + tmpObject = document.getElementById("rightCut"); + tmpObject.setAttribute("width", totalWidth); + tmpObject.setAttribute("height", totalHeight); + tmpObject.setAttribute("x", 1 + totalWidth); + // respace executing widgets if any + tmpObject = widgetContainer.getElementsByTagName("g"); + for (i = 0; i < tmpObject.length; i++) { + var gg = tmpObject.item(i); + gg.setAttribute("transform", "translate(" + (totalWidth * (i - 1)) + ", 0)"); + if (gg.firstElementChild != null) { + gg.firstElementChild.setAttribute("width", totalWidth); + gg.firstElementChild.setAttribute("height", totalHeight - 120); + } + } +} + +// +// widget close on click at "Kill" button +// +function on_kill_widget() { + if (state == 'exec') { + widget_close(activatedWidgets[whereW]); + } +} + +// +// when deleting an executing widgets, all executing widgets to its right are moved to the left +// +function recurseMoveAfterDelete(target) { + if (target != null && target.nextElementSibling != null) { + var v = target.nextElementSibling; + recurseMoveAfterDelete(v); + v.setAttribute("transform", target.getAttribute("transform")); + } +} + +// +// click on home button to switch from icons to executing widgets +// +function home_button(evt) { + if (l_deb < log_level) alert("[UI] home_button"); + if (state != 'home') { + state = 'home'; + widgetContainer.setAttribute('display', 'none'); + homepage.setAttribute('display', 'inline'); + homebar.setAttribute('display', 'inline'); + execbar.setAttribute('display', 'none'); + arrows.setAttribute('display', 'inline'); + arrowsW.setAttribute('display', 'none'); + widgetAddList.setAttribute('display', 'none'); + } else { + state = 'exec'; + widgetContainer.setAttribute('display', 'inline'); + homepage.setAttribute('display', 'none'); + homebar.setAttribute('display', 'none'); + execbar.setAttribute('display', 'inline'); + arrows.setAttribute('display', 'none'); + arrowsW.setAttribute('display', 'inline'); + widgetAddList.setAttribute('display', 'none'); + } +} + +// constants +var adjustFrom = "0,0"; +var animDue = true; + +// +// after each change of icon page, this function adjusts the visibility of arrows in the lower bar +// +function adjustwhere(animDue) { + if (l_deb < log_level) alert("[UI] adjust " + where + " 0 " + maxwhere); + document.getElementById("left").setAttribute("display", ((where > 0) ? "inline" : "none")); + document.getElementById("right").setAttribute("display", ((where < maxwhere) ? "inline" : "none")); + if (!animDue) { + icons.setAttribute("transform", 'translate(' + (-80 * iconNbHoriz * where) + ',0)'); + } else { + var aw = document.createElement("animateTransform"); + aw.setAttribute("attributeName", "transform"); + aw.setAttribute("type", "translate"); + //alert('time '+document.documentElement.getCurrentTime()); + aw.setAttribute("begin", document.documentElement.getCurrentTime()); + aw.setAttribute("dur", "1s"); + aw.setAttribute("fill", "freeze"); + aw.setAttributeNS(xlinkns, "href", "#icons"); + aw.setAttribute("from", adjustFrom); + aw.setAttribute("to", (-80 * iconNbHoriz * where) + ",0"); + document.documentElement.appendChild(aw); + } + adjustFrom = (-80 * iconNbHoriz * where) + ",0"; +} + +// +// action of the left button on the lower bar +// +function left_button() { + if (l_deb < log_level) alert("[UI] left button " + where + " 0"); + if (where > 0) { + where--; + adjustwhere(true); + } +} + +// +// action of the right button of the lower bar +// +function right_button() { + if (l_deb < log_level) alert("[UI] right button " + where + " " + maxwhere); + if (where < maxwhere) { + where++; + adjustwhere(true); + } +} + +var adjustFromW = "0,0"; +var oldwhereW = -1; + +// +// after each change of icon page, this function adjusts the visibility of arrows in the lower bar +// +function adjustWhereWidgets(animDue) { + if (oldwhereW != whereW) { + // hide oldwhereW + if (oldwhereW >= 0 && activatedWidgets[oldwhereW] != null) WidgetManager.corein_message(activatedWidgets[oldwhereW], "hide"); + } + if (l_deb < log_level) alert("[UI] adjustW " + whereW + " 0 " + (numActivatedWidgets - 1)); + document.getElementById("leftW").setAttribute("display", ((whereW > 0) ? "inline" : "none")); + document.getElementById("rightW").setAttribute("display", ((whereW < (numActivatedWidgets - 1)) ? "inline" : "none")); + if (!animDue) { + widgetContainer.setAttribute("transform", "translate(" + (-totalWidth * whereW) + ",0)"); + } else { + var aw = document.createElement("animateTransform"); + aw.setAttribute("attributeName", "transform"); + aw.setAttribute("type", "translate"); + aw.setAttribute("begin", document.documentElement.getCurrentTime()); + aw.setAttribute("dur", "1s"); + aw.setAttribute("fill", "freeze"); + aw.setAttributeNS(xlinkns, "href", "#widget"); + aw.setAttribute("from", adjustFromW); + aw.setAttribute("to", (-totalWidth * whereW) + ",0"); + document.documentElement.appendChild(aw); + } + adjustFromW = (-totalWidth * whereW) + ",0"; + document.getElementById("widgetName").textContent = + (whereW >= 0 && activatedWidgets[whereW] != null ? activatedWidgets[whereW].shortName : '-'); + if (oldwhereW != whereW) { + // show whereW + if (whereW >= 0 && activatedWidgets[whereW] != null) WidgetManager.corein_message(activatedWidgets[whereW], "show"); + oldwhereW = whereW; + } +} + +// +// action of the left button on the lower bar +// +function left_buttonW() { + if (l_deb < log_level) alert("[UI] left button " + whereW); + if (whereW > 0) { + whereW--; + adjustWhereWidgets(animDue); + } +} + +// +// action of the right button of the lower bar +// +function right_buttonW() { + if (l_deb < log_level) alert("[UI] right button " + whereW + " " + (numActivatedWidgets - 1)); + if (whereW < (numActivatedWidgets - 1)) { + whereW++; + adjustWhereWidgets(animDue); + } +} + +// +// action of each icon, starting the matching widget +// +function activating_widget(w) { + if (l_deb < log_level) alert("[UI] activating widget: " + w.name); + if (widget_add(w)) { + state = 'exec'; + widgetContainer.setAttribute('display', 'inline'); + homepage.setAttribute('display', 'none'); + homebar.setAttribute('display', 'none'); + execbar.setAttribute('display', 'inline'); + arrows.setAttribute('display', 'none'); + arrowsW.setAttribute('display', 'inline'); + widgetAddList.setAttribute('display', 'none'); + } +} + +function widget_activated_and_bound(wid) { + WidgetManager.corein_message(wid, "activate"); +} + +// +// main initialization function +// init variables, then init the widget manager C code, then inits UPnP +// +function initialize() { + if (l_deb < log_level) alert("[UI] initialize"); + init = false; + setPreferredSize(); + root = document.documentElement; + homepage = document.getElementById('homepage'); + homebar = document.getElementById('homebar'); + execbar = document.getElementById('execbar'); + arrows = document.getElementById('arrows'); + arrowsW = document.getElementById('arrowsW'); + icons = document.getElementById('icons'); + widgetContainer = document.getElementById('widget'); + widgetAddList = document.getElementById('widgetAddList'); + /* Setup the GPAC Widget Manager - this will also scan the available widgets */ + log_level = l_inf; + widget_manager_init(); + WidgetManager.on_widget_remove = widget_remove; + WidgetManager.on_widget_add = widget_add; + /* register the callback to be notified of incoming widgets */ + has_upnp = (typeof UPnP != 'undefined'); + if (has_upnp) { + /* setting the callback to allow other devices to push their widgets */ + UPnP.onMediaConnect = onMediaConnect; + /* Tell GPAC that the calls to the main Renderer (like open, ...) must be forwared to this scene */ + UPnP.BindRenderer(); + } + WidgetManager.coreOutShow = coreOutShowImplementation; + WidgetManager.coreOutGetAttention = coreOutGetAttentionImplementation; + WidgetManager.coreOutHide = coreOutHideImplementation; + WidgetManager.coreOutRequestDeactivate = coreOutRequestDeactivateImplementation; + WidgetManager.coreOutInstallWidget = coreOutInstallWidgetImplementation; + WidgetManager.coreOutActivateTemporaryWidget = coreOutActivateTemporaryWidgetImplementation; + WidgetManager.coreOutMigrateComponent = coreOutMigrateComponentImplementation; + WidgetManager.coreOutRequestMigrationTargets = coreOutRequestMigrationTargetsImplementation; +} + +// +// implementation of core:out install widget +// +function coreOutInstallWidgetImplementation(wid, args) { + var w = widgetInstall(args[0], true, false); + var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010"); + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.installWidgetMessage, ifce.get_message("installWidget"), + wid, (w != null ? 1 : 0)); // send return code 1 = success + } +} + +// +// implementation of core:out activate temporary widget +// +function coreOutActivateTemporaryWidgetImplementation(wid, args) { + var w = widgetInstall(args[0], true, true); + if (w != null) activating_widget(w); + var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010"); + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.activateTemporaryWidgetMessage, ifce.get_message("activateTemporaryWidget"), + wid, (w != null ? 1 : 0)); // send return code 1 = success + } +} + +// +// implementation of core:out migrate component +// +function coreOutMigrateComponentImplementation(wid, args) { + //alert("coreOutMigrateComponent "+wid.name+" "+args.length); + var comp = wid.get_component(args[0], true); + var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010"); + if (comp==null) { + log(l_err, 'Component '+args[0]+' cannot be found in widget '+wid.name); + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.migrateComponentMessage, ifce.get_message("migrateComponent"), wid, 0); + } + return; + } + if (args.length > 1 && args[1] != null) { + WidgetManager.migrate_widget(UPnP.GetMediaRenderer(parseInt(args[1])), comp); + widget_close(comp); + } else { + upnp_renders = selector_window(comp); + upnp_renders.on_select = function(item, wid) { + upnp_renders.unregister(root); + upnp_renders = null; + if (item == -1) return; + if (comp != null) { + alert("upnp_renders.on_select("+item+","+comp.name+")"); + WidgetManager.migrate_widget(UPnP.GetMediaRenderer(item), comp); + widget_close(comp); + } + }; + upnp_renders.register(root); + } + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.migrateComponentMessage, ifce.get_message("migrateComponent"), wid, 1); // send return code 1 = success + } +} + +// +// implementation of core:out request migration targets +// +function coreOutRequestMigrationTargetsImplementation(wid, args) { + var count = UPnP.MediaRenderersCount, codes = new Array(), names = new Array(), descriptions = new Array(), i; + for (i = 0; i < count; i++) { + var render = UPnP.GetMediaRenderer(i); + codes.push(""+i); + names.push(render.Name); + descriptions.push(render.HostName +" "+ render.UUID); + } + i = null; + var ifce_count = wid.num_interfaces, j; + for (j = 0; j < ifce_count; j++) { + var ifce = wid.get_interface(j); + if (ifce.type == "urn:mpeg:mpegu:schema:widgets:core:out:2010") { + i = ifce; + break; + } + } + if (i != null) { + wmjs_core_out_invoke_reply(coreOut.requestMigrationTargetsMessage, i.get_message("requestMigrationTargets"), + wid, codes, names, descriptions); + } +} + +// +// implementation of core:out Show message +// this is a request by the widget to be shown +// +function coreOutShowImplementation(wid, args) { + //alert("core:out show "+wid.name); + var target = widgetContainer.firstElementChild; + var i; + for (i = 0; i < numActivatedWidgets; i++) { + //alert("is it "+activatedWidgets[i].name); + if (activatedWidgets[i] == wid) break; + target = target.nextElementSibling; + } + // here, i is the index of the current widget + //alert(" "+i+" "+numActivatedWidgets); + if (i < numActivatedWidgets) { + whereW = i; + adjustWhereWidgets(false); + } + var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010"); + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.showMessage, ifce.get_message("show"), wid, 1); // send return code 1 = success + } +} + +// +// implementation of core:out GetAttention message +// this is a request by the widget to be shown and some special signal is given +// +function coreOutGetAttentionImplementation(wid, args) { + //alert("core:out getAttention "+wid.name); + var target = widgetContainer.firstElementChild; + var i; + for (i = 0; i < numActivatedWidgets; i++) { + //alert("is it "+activatedWidgets[i].name); + if (activatedWidgets[i] == wid) break; + target = target.nextElementSibling; + } + // here, i is the index of the current widget + //alert(" "+i+" "+numActivatedWidgets); + if (i < numActivatedWidgets) { + whereW = i; + adjustWhereWidgets(false); + } + document.getElementById("getAttention").beginElement(); + var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010"); + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.getAttentionMessage, ifce.get_message("getAttention"), wid, 1); // send return code 1 = success + } +} + +// +// implementation of core:out hide message +// this is a request by the widget to be hidden (some other widget (if any) is shown) +// +function coreOutHideImplementation(wid, args) { + //alert("core:out hide "+wid.name); + var target = widgetContainer.firstElementChild; + var i; + for (i = 0; i < numActivatedWidgets; i++) { + //alert("is it "+activatedWidgets[i].name); + if (activatedWidgets[i] == wid) break; + target = target.nextElementSibling; + } + // here, i is the index of the current widget + //alert("hide "+i+" "+numActivatedWidgets); + if (i < numActivatedWidgets) { + if (whereW > 0) whereW--; + else if (whereW < numActivatedWidgets - 1) whereW++; + else return; + adjustWhereWidgets(false); + } + var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010"); + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.hideMessage, ifce.get_message("hide"), wid, 1); // send return code 1 = success + } +} + +// +// implementation of core:out requestDeactivate message +// this is a request by the widget to be stopped +// +function coreOutRequestDeactivateImplementation(wid, args) { + //alert("core:out hide "+wid.name); + var target = widgetContainer.firstElementChild; + var i; + for (i = 0; i < numActivatedWidgets; i++) { + //alert("is it "+activatedWidgets[i].name); + if (activatedWidgets[i] == wid) break; + target = target.nextElementSibling; + } + // here, i is the index of the current widget + //alert("hide "+i+" "+numActivatedWidgets); + if (i < numActivatedWidgets) { + widget_close(activatedWidgets[i]); + } + var ifce = getInterfaceByType(wid, "urn:mpeg:mpegu:schema:widgets:core:out:2010"); + if (ifce != null) { + wmjs_core_out_invoke_reply(coreOut.requestDeactivateMessage, ifce.get_message("requestDeactivate"), wid, 1); // send return code 1 = success + } +} + +var testCyrilsExtension = false; + +// +// WM callback for when a component is activated by its parent +// +function widget_add(w) { + if (!w.activated) { + if (testCyrilsExtension) { + var anima = document.createElement("animation"); + anima.setAttributeNS('http://gpac.sourceforge.net/svg-extensions', 'use-as-primary', 'false'); + widget_launch(w, anima); + } else { + if (sameFileIgnoringSVGView(w.icon, w.main)) { + // same file in icon and main + } else { + widget_launch(w, document.createElement("animation")); + } + } + return true; + } else if (w.multipleInstances) { + var newwid = WidgetManager.open(w.manifest, null); + widget_launch(newwid, document.createElement("animation")); + return true; + } + return false; +} + +function sameFileIgnoringSVGView(name1, name2) { + if (name1 == name2) return true; + if (name1 == null) return false; + var i1 = name1.indexOf("#"); + var i2 = name2.indexOf("#"); + if (i1 < 0) i1 = name1.length; + else i1--; + if (i2 < 0) i2 = name2.length; + else i2--; + return name1.substring(0, i1) == name2.substring(0, i2); +} + +// +// recompute the number of widgets loaded currently +// +function getNbWidgets() { + var i, nbWidgets = 0; + for (i = 0; i < WidgetManager.num_widgets; i++) { + var w = WidgetManager.get(i); + if (w != null && w.loaded) nbWidgets++; + } + return nbWidgets; +} + +// +// just resize the window and viewport, and initialize the first time this is called +// +function resize() { + if (init) initialize(); + if (root.viewport.width == previousWidth && root.viewport.height == previousHeight) return; + if (l_deb < log_level) alert("[UI] start initialize() w:" + root.viewport.width + " h:" + root.viewport.height); + adaptLayoutToSize(); + // start by filling the "home page" with known icons + where = 0; + var nbWidgets = getNbWidgets(); + maxwhere = ((nbWidgets - 1) - ((nbWidgets - 1) % iconsPerPage)) / iconsPerPage; + var wid; + var iconIterator = document.getElementById("icons").firstElementChild; + var position = 0; + for (i = 1; i <= WidgetManager.num_widgets; i++) { + wid = WidgetManager.get(i - 1); + // alert("build:"+wid.main+" "+wid.loaded); + if (wid.loaded) { + insert_icon(wid, position, i - 1, iconIterator); + WidgetManager.corein_message(wid, 'setSize', 'width', totalWidth, 'height', totalHeight-120, 'dpi', 96); + position++; + if (iconIterator != null) iconIterator = iconIterator.nextElementSibling; + } + } + adjustwhere(false); + adjustWhereWidgets(false); + previousWidth = root.viewport.width; + previousHeight = root.viewport.height; + gpac.setOption("Widgets", "LastWMWidth", '' + previousWidth); + gpac.setOption("Widgets", "LastWMHeight", '' + previousHeight); +} + +// +// function inserting an icon on the home page +// +function insert_icon(widget, position, widgetIndex, previousIcon) { + if (l_deb < log_level) alert("[UI] insert_icon: " + widget.shortName + " " + position + " " + widgetIndex + " WMnw:" + WidgetManager.num_widgets); + widget.loaded = true; + if (l_deb < log_level) alert("[UI] widget name: " + widget.name); + var icon = null, original = null; + for (var i = 0; i < widget.icons.length; i++) { + // default to the first icon even if not of the preferred type + if (i == 0) { + icon = widget.icons[0].relocated_src; + //original = widget.icons[0].original; + // alert("choosing default icon " + icon); + } + // check for preferred type + if (widget.icons[i].relocated_src.indexOf(preferredIconType) > 0) { + icon = widget.icons[i].relocated_src; + //original = widget.icons[i].original; + break; + } + } + //alert(""); + //alert("content of widget:"); + //alert("main " + widget.main); + //alert("icon " + icon); + //alert("original " + original); + //alert(""); + //icon = restoreFragmentOnURL(icon, original); + var shortName = widget.shortName; + if (typeof shortName == 'undefined') shortName = widget.name.substring(0, 9); + createIconSVGdecoration(previousIcon, widget, (((position % iconNbHoriz) * 80) + ((80 * (position - (position % iconsPerPage))) / iconNbVert)), + ((((position % iconsPerPage) - (position % iconNbHoriz)) / iconNbHoriz) * 80), "icons", icon, + shortName, widgetIndex); +} + +function restoreFragmentOnURL(iconUrl, original) { + var l = original.indexOf('#'); + if (l >= 0) { + return iconUrl + original.substring(l); + } + return iconUrl; +} + +// constant +var corein = "urn:mpeg:mpegu:schema:widgets:core:in:2010"; + +// +// commodity method to empty a list of children +// +function removeAllChildren(o) { + if (o != null && o.hasChildNodes()) { + while (o.childNodes.length >= 1) { + o.removeChild(o.firstChild); + } + } +} + +// +// create the home page icon with all its behaviours +// +function createIconSVGdecoration(previousIcon, widget, x, y, fatherId, iconUrl, name, widIndex) { + var g, g2; + if (l_inf < log_level) alert("[UI] createIconSVGdecoration " + iconUrl + " " + x + " " + y); + if (previousIcon != null) { + g = previousIcon; + } else { + g = document.createElement("g"); + document.getElementById(fatherId).appendChild(g); + } + g.setAttribute("transform", 'translate(' + x + ',' + y + ')'); + if (previousIcon != null) { + g2 = g.firstElementChild; + } else { + g2 = document.createElement("g"); + g2.setAttribute("transform", 'translate(15,10)'); + g.appendChild(g2); + } + if (iconUrl == null || iconUrl == "") iconUrl = "icons/face-surprise.svg"; + // + // process differently cases where widget.icon == widget.main + // + var container; + if (!testCyrilsExtension && sameFileIgnoringSVGView(iconUrl, widget.main) && widget.main.indexOf('.svg') >= 0) { + // see if the animation already exists + container = document.getElementById(name); + if (container == null) { + // if the animation does not exist yet, create it + container = media('animation', iconUrl, 50, 50); + // store the animation in the main defs + document.getElementById("mainDefs").appendChild(container); + container.setAttribute('id', name); + } + if (previousIcon == null) { + // put the container in a use + var use = document.createElement("use"); + use.setAttribute('id', 'iconContainer' + name); + use.setAttributeNS(xlinkns, 'href', '#' + name); + g2.appendChild(use); + } + } else { + if (previousIcon == null) { + container = appropriateElementForMedia(iconUrl, 50, 50); + container.setAttribute('id', name); + g2.appendChild(container); + } + } + if (previousIcon == null) { + g2 = document.createElement("g"); + g2.setAttribute("transform", 'translate(40,70)'); + g.appendChild(g2); + var anim = text(name, 'white', 0, 0, 14, 'Arial Unicode MS'); + anim.setAttribute("text-anchor", "middle"); + anim.setAttribute("display-align", "center"); + g2.appendChild(anim); + var rect = invisible_rect(80, 80); + g.appendChild(rect); + rect.addEventListener("click", csi(widget), false); + } +} + +function csi(widget) { + return function(evt) { activating_widget(widget);}; +} + +// +// widget closing action (WM callback) +// +function widget_close(wid) { + if (wid == null) return; + if (l_inf <= log_level) alert('[UI] widget_close:' + wid.name); + // maybe inform the widget that it is going to be deactivated + WidgetManager.corein_message(wid, "deactivate"); + var target = widgetContainer.firstElementChild; + var i; + for (i = 0; i < numActivatedWidgets; i++) { + if (activatedWidgets[i] == wid) break; + target = target.nextElementSibling; + } + if (target != null) { + // move next widgets back one slot + recurseMoveAfterDelete(target); + // stop the subscene + if (target.firstElementChild != null) target.firstElementChild.setAttributeNS(xlinkns, "href", ""); + // end trying + widgetContainer.removeChild(target); + } + wid.deactivate(); + wid.activated = false; + activatedWidgets.splice(i, 1); + numActivatedWidgets--; + whereW = (whereW >= i ? (whereW > 0 ? whereW - 1 : 0) : whereW); + adjustWhereWidgets(false); + // if no more widgets, go back to the icons + if (numActivatedWidgets == 0) { + state = 'home'; + widgetContainer.setAttribute('display', 'none'); + homepage.setAttribute('display', 'inline'); + homebar.setAttribute('display', 'inline'); + execbar.setAttribute('display', 'none'); + arrows.setAttribute('display', 'inline'); + arrowsW.setAttribute('display', 'none'); + widgetAddList.setAttribute('display', 'none'); + } + if (!wid.permanent) WidgetManager.unload(wid, false); +} + +// +// widget unloading action (WM callback) +// +function widget_remove(wid) { + if (l_deb <= log_level) alert('[UI] widget_remove:' + wid.name); + widget_close(wid); + WidgetManager.unload(wid, false); +} + +// +// widget launcher action +// +function widget_launch(wid, scene_container) { + if (l_inf <= log_level) alert('[UI] widget_launch:' + wid.name); + var tmp = document.createElement("g"); + tmp.setAttribute("transform", "translate(" + (totalWidth * numActivatedWidgets) + ", 0)"); + widgetContainer.appendChild(tmp); + var icon = null; + alert("wid: "+wid.name+"|"+wid.shortName); + if (typeof wid.shortName != 'undefined') { + var container = document.getElementById(wid.shortName); + if (container != null) icon = container.getAttributeNS(xlinkns, 'href'); + } + if (icon != null && + !testCyrilsExtension && + sameFileIgnoringSVGView(icon, wid.main) && + endsWith(wid.main, '.svg')) { + // get the animation with id=shortName stored in mainDefs + scene_container = document.getElementById(wid.shortName); + // get the original use on it, used in the icon + var iconContainer = document.getElementById('iconContainer' + wid.shortName); + // create a new use + var use = document.createElement('use'); + // point to the animation + use.setAttributeNS(xlinkns, 'href', '#' + wid.shortName); + // resize the animation + scene_container.setAttribute("width", totalWidth); + scene_container.setAttribute("height", totalHeight - 120); + // resize the original use //TODO fix the aspect ratio conservation + var m, t = Math.abs(totalHeight - 120 - totalWidth) / 2; + if (totalWidth > totalHeight - 120) { + m = 50 / (totalHeight - 120); + iconContainer.setAttribute('transform', 'scale(' + m + ',' + m + ') translate(' + (-t) + ',0)'); + } else { + m = 50 / totalWidth; + iconContainer.setAttribute('transform', 'scale(' + m + ',' + m + ') translate(0,' + (-t) + ') '); + } + // add the new use as widget execution container + tmp.appendChild(use); + wid.activate(scene_container); + } else { + scene_container.setAttribute("width", totalWidth); + scene_container.setAttribute("height", totalHeight - 120); + tmp.appendChild(scene_container); + scene_container.setAttributeNS(xlinkns, 'href', wid.main); + wid.activate(scene_container); + } + wid.activated = true; + activatedWidgets.splice(numActivatedWidgets, 0, wid); + whereW = numActivatedWidgets; + numActivatedWidgets++; + adjustWhereWidgets(false); + wid.load_component = widget_load_component; + wid.permanent = true; + wid.on_load = function () { + WidgetManager.corein_message(this, 'setSize', 'width', totalWidth, 'height', totalHeight-120, 'dpi', 96); + }; + // + if (log_level > l_inf) { + var i = 0; + alert(">>>>>>>>>>>>> "+wid.name+" interfaces:"); + for (;i < wid.num_interfaces; i++) { + alert(""+wid.get_interface(i).type); + } + } + // +} + +// +// widget load component (WM callback) +// +function widget_load_component(comp, is_unload) { + if (l_deb <= log_level) alert('[UI] widget_load_component:' + comp.name); + if (is_unload) { + widget_close(comp); + comp.parent = null; + } else { + widget_add(comp); + comp.permanent = false; + comp.parent = this; + } +} + +var upnp_renders; + +// +// widget remoting function +// +function on_widget_remote() { + if (UPnP.MediaRenderersCount && numActivatedWidgets > 0) { + upnp_renders = selector_window(activatedWidgets[whereW]); + upnp_renders.on_select = function(item, wid) { + upnp_renders.unregister(root); + upnp_renders = null; + if (item == -1) return; + if (wid != null) { + alert("upnp_renders.on_select("+item+","+wid.name+")"); + WidgetManager.migrate_widget(UPnP.GetMediaRenderer(item), wid); + widget_close(wid); + } + }; + upnp_renders.register(root); + } +} + +// +// creates the menu of available targets for pushing a widget elsewhere +// +function selector_window(widget) { + var i, count, render; + var selector = document.createElement('g'), obj, child; + selector.setAttribute('transform', 'translate(10,10)'); + count = UPnP.MediaRenderersCount; + selector.appendChild(rect(0, 0, 300, 20 * (count + 1), 'white', 'black')); + for (i = 0; i < count; i++) { + render = UPnP.GetMediaRenderer(i); + obj = text(render.Name, 'black', 5, 17 + (20 * i), 15, 'sans-serif'); + obj.setAttribute('id', "selector" + i); + selector.appendChild(obj); + obj.addEventListener('mouseover', sw1("selector"+i), false); + obj.addEventListener('mouseout', sw2("selector"+i), false); + obj.addEventListener('click', sw3(i, widget), false); + } + obj = text('Cancel', 'rgb(0,0,120)', 55, 17 + (20 * i), 15, 'sans-serif'); + obj.setAttribute('id', "cancel"); + selector.appendChild(obj); + obj.addEventListener('mouseover', function(evt) { document.getElementById("cancel").setAttribute("fill", "red"); }, false); + obj.addEventListener('mouseout', function(evt) { document.getElementById("cancel").setAttribute("fill", "black"); }, false); + obj.addEventListener('click', function(evt) { upnp_renders.on_select(-1, null); }, false); + selector.register = function(disp) { + disp.appendChild(this); + }; + selector.unregister = function(disp) { + disp.removeChild(this); + }; + return selector; +} + +function sw1(s) { + return function(evt) { document.getElementById(s).setAttribute("fill", "blue"); }; +} + +function sw2(s) { + return function(evt) { document.getElementById(s).setAttribute("fill", "black"); }; +} + +function sw3(si, widget) { + return function(evt) { upnp_renders.on_select(si, widget); }; +} + +// +// when a widget is pushed to here, install the widget and execute it +// +function onMediaConnect(url, src_ip) { + if (l_inf <= log_level) alert('[UI] onMediaConnect :\"' + url + '\"'); + if (WidgetManager.probe(url)) { + var w = WidgetManager.open(url, src_ip); + if (w == null) return; + state = 'exec'; + widgetContainer.setAttribute('display', 'inline'); + homepage.setAttribute('display', 'none'); + homebar.setAttribute('display', 'none'); + execbar.setAttribute('display', 'inline'); + arrows.setAttribute('display', 'none'); + arrowsW.setAttribute('display', 'inline'); + widgetAddList.setAttribute('display', 'none'); + var nbWidgets = getNbWidgets(); + widget_add(w); + adjustWhereWidgets(false); + w.permanent = false; + } +} + +// +// file list vars +// +var flstart = 0, fllist, maxFileNames = 14; + +// +// create a file menu in the main screen, allowing to navigate directories and choose widget config files +// +function on_widget_add_menu() { + state = 'list'; + widgetContainer.setAttribute('display', 'none'); + homepage.setAttribute('display', 'none'); + homebar.setAttribute('display', 'none'); + execbar.setAttribute('display', 'inline'); + arrows.setAttribute('display', 'none'); + arrowsW.setAttribute('display', 'none'); + widgetAddList.setAttribute('display', 'inline'); + maxFileNames = Math.round(((iconNbVert * 80) / 25) - 1.4); + isThisAScan = false; + refillWidgetAddList(false); +} + +// +// create a file menu in the main screen, allowing to navigate directories and choose a directory to scan for widgets +// and load all their icons +// +function on_dir_scan() { + state = 'list'; + widgetContainer.setAttribute('display', 'none'); + homepage.setAttribute('display', 'none'); + homebar.setAttribute('display', 'none'); + execbar.setAttribute('display', 'inline'); + arrows.setAttribute('display', 'none'); + arrowsW.setAttribute('display', 'none'); + widgetAddList.setAttribute('display', 'inline'); + maxFileNames = Math.round(((iconNbVert * 80) / 25) - 1.4); + isThisAScan = true; + refillWidgetAddList(true); +} + +// +// remove all installed icons +// +function on_clean_up() { + var i; + //if (l_inf <= log_level) alert('[UI] unloading ' + WidgetManager.num_widgets + ' widgets'); + for (i = WidgetManager.num_widgets - 1; i >= 0; i--) { + var w = WidgetManager.get(i); + if (w.loaded) { + alert("unloading " + w.name); + w.loaded = false; + WidgetManager.unload(w, false); + } + } + where = 0; + maxwhere = 0; + removeAllChildren(document.getElementById("icons")); + adjustwhere(false); +} + +// +// install, but do not launch, the widget whose config.xml has been chosen, and return to the home page +// +function widgetInstall(uri, manual, temporary) { + var wid, j, count = WidgetManager.num_widgets, nbWidgets = getNbWidgets(); + for (j = 0; j < count; j++) { + wid = WidgetManager.get(j); + if (wid.url == uri) { + if (wid.loaded) break; + if (temporary) wid.permanent = false; + else insert_icon(wid, nbWidgets, nbWidgets); + } + } + if (j == count) { + wid = WidgetManager.open(uri, null); + if (wid != null) { + if (temporary) wid.permanent = false; + else insert_icon(wid, nbWidgets, nbWidgets); + } + } + if (manual) return wid; + state = 'home'; + widgetContainer.setAttribute('display', 'none'); + homepage.setAttribute('display', 'inline'); + homebar.setAttribute('display', 'inline'); + execbar.setAttribute('display', 'none'); + arrows.setAttribute('display', 'inline'); + arrowsW.setAttribute('display', 'none'); + removeAllChildren(widgetAddList); + maxwhere = ((nbWidgets - 1) - ((nbWidgets - 1) % iconsPerPage)) / iconsPerPage; + where = maxwhere; + adjustwhere(false); + return wid; +} + +// +// clean up file list space and refill it +// +function refillWidgetAddList(flag) { + removeAllChildren(widgetAddList); + fllist = null; + flstart = 0; + fllist = gpac.enum_directory(gpac.last_working_directory, "", false); + fillWidgetAddList(flag); +} + +// +// go to parent directory +// +function flUpDir(evt) { + var s = gpac.last_working_directory; + if (l_inf <= log_level) alert("[UI] lwd:" + gpac.last_working_directory); + var index = s.lastIndexOf("\\"); + if (index != -1) { + gpac.last_working_directory = s.substring(0, index); + refillWidgetAddList(isThisAScan); + } else { + index = s.lastIndexOf("/"); + if (index != -1) { + gpac.last_working_directory = s.substring(0, index); + refillWidgetAddList(isThisAScan); + } else { + gpac.last_working_directory = "/"; + refillWidgetAddList(isThisAScan); + } + } +} + +// +// go to a named directory +// +function flGoTo(newDir) { + //alert("goto "+newDir); + var s = gpac.last_working_directory; + if (s == "/") { + gpac.last_working_directory = newDir; + } else { + var c = s.charAt(s.length - 1); + if (c != '\\' && c != '/') s += "/"; + gpac.last_working_directory = s + newDir; + } + //alert(gpac.last_working_directory); + refillWidgetAddList(isThisAScan); +} + +// +// if the directory contains more files that can be shown, show previous page of file names +// +function flPrevFiles(evt) { + if (flstart == 0) return; + flstart -= maxFileNames; + if (flstart < 0) flstart = 0; + removeAllChildren(widgetAddList); + fillWidgetAddList(isThisAScan); +} + +// +// if the directory contains more files that can be shown, show next page of file names +// +function flNextFiles(evt) { + if (flstart + maxFileNames < fllist.length) { + flstart += maxFileNames; + removeAllChildren(widgetAddList); + fillWidgetAddList(isThisAScan); + } +} + +// +// scan the current directory recursively for widgets, clean up and return to home page +// +function flScanDir(evt) { + scan_directory(gpac.last_working_directory); + state = 'home'; + var nbWidgets = getNbWidgets(); + widgetContainer.setAttribute('display', 'none'); + homepage.setAttribute('display', 'inline'); + homebar.setAttribute('display', 'inline'); + execbar.setAttribute('display', 'none'); + arrows.setAttribute('display', 'inline'); + arrowsW.setAttribute('display', 'none'); + removeAllChildren(widgetAddList); + maxwhere = ((nbWidgets - 1) - ((nbWidgets - 1) % iconsPerPage)) / iconsPerPage; + where = maxwhere; + adjustwhere(false); +} + +// +// scanning +// +function scan_directory(dir) { + var ii, j, count, list, w, uri, loadedWidgets = 0; + list = gpac.enum_directory(dir, '.xml;.wgt', 0); + for (ii = 0; ii < list.length; ii++) { + uri = list[ii].path + list[ii].name; + if (list[ii].directory) { + scan_directory(uri); + } else { + count = WidgetManager.num_widgets; + for (j = 0; j < count; j++) { + var wid = WidgetManager.get(j); + if (wid.loaded) loadedWidgets++; + if (wid.url == uri) { + if (wid.loaded) break; + insert_icon(wid, getNbWidgets(), j); + break; + } + } + if (j == count) { + w = WidgetManager.open(uri, null); + if (w != null) { + insert_icon(w, loadedWidgets, WidgetManager.num_widgets - 1); + } + } + } + } +} + +// +// create the up, prev, next button, show current directory and as many file names as possible +// the file names are active: clicking on a directory name goes to that directory +// clicking on a file tries to load that file as a widget +// +function fillWidgetAddList(flag) { + if (flag) { + widgetAddList.appendChild(use("cartoucheflag")); + document.getElementById("dirflag").textContent = gpac.last_working_directory; + } else { + widgetAddList.appendChild(use("cartouche")); + document.getElementById("dir").textContent = gpac.last_working_directory; + } + // next lines are file names + var obj; + for (i = 0; i < (fllist.length - flstart) && i < maxFileNames; i++) { + obj = use("fileMenuElement" + i); + obj.setAttribute('transform', 'translate(0,' + (25 * (i + 1)) + ')'); + widgetAddList.appendChild(obj); + document.getElementById("fileMenuElement" + i + "u").setAttributeNS(xlinkns, 'href', "#" + (fllist[i + flstart].directory ? 'folder' : 'new')); + document.getElementById("fileMenuElement" + i + "t").textContent = fllist[i + flstart].name; + if (obj.listener != null) obj.removeEventListener("click", obj.listener); + if (fllist[i + flstart].directory) { + obj.listener = createGoto(escaping(fllist[i + flstart].name)); + obj.addEventListener("click", obj.listener, false); + } else if (isWidgetFileName(fllist[i + flstart].name)) { + obj.listener = createWidgetInstall(escaping(gpac.last_working_directory + '/' + fllist[i + flstart].name)); + obj.addEventListener("click", obj.listener, false); + } + } +} + +function createGoto(s) { + return function () { + flGoTo(s); + }; +} + +function createWidgetInstall(s) { + return function () { + widgetInstall(s, false, false); + }; +} + +// // // // // // // // // // // // // // // +// function library +// // // // // // // // // // // // // // // + +function isWidgetFileName(s) { + if (endsWith(s, 'config.xml')) return true; + if (endsWith(s, '.wgt')) return true; + return false; +} + +// +// replace globally \ with / in a string +// +function escaping(s) { + s = s.replace(/\\/g, '/'); + return s; +} + +// +// create rect +// +function rect(x, y, w, h, fill, stroke, id) { + var child = document.createElement('rect'); + if (id != null) { + child.setAttribute('id', id); + } + child.setAttribute('x', x); + child.setAttribute('y', y); + child.setAttribute('width', w); + child.setAttribute('height', h); + child.setAttribute('fill', fill); + child.setAttribute('stroke', stroke); + return child; +} + +// +// create text +// +function text(content, fill, x, y, size, family) { + var child = document.createElement('text'); + child.setAttribute('fill', fill); + child.textContent = content; + child.setAttribute('x', x); + child.setAttribute('y', y); + child.setAttribute('font-size', size); + child.setAttribute('font-family', family); + return child; +} + +// +// create invisible rect getting all events +// +function invisible_rect(w, h) { + var child = document.createElement('rect'); + child.setAttribute('width', w); + child.setAttribute('height', h); + child.setAttribute('fill', 'none'); + child.setAttribute('stroke', 'none'); + child.setAttribute('pointer-events', 'all'); + return child; +} + +// +// create animation +// +function media(etype, uri, w, h) { + var child = document.createElement(etype); + child.setAttributeNS(xlinkns, 'href', uri); + child.setAttribute('width', w); + child.setAttribute('height', h); + if (etype == 'animation') { + child.setAttributeNS('http://gpac.sourceforge.net/svg-extensions', 'use-as-primary', 'false'); + } + return child; +} + +// +// create use +// +function use(uri) { + var child = document.createElement('use'); + child.setAttributeNS(xlinkns, 'href', '#' + uri); + return child; +} + +// +// create appropriate element for media reference by the given uri +// +function appropriateElementForMedia(uri, w, h) { + if (uri.indexOf('#') != -1) { + return media('animation', uri, w, h); + } + if (endsWith(uri, '.svg')) { + return media('animation', uri, w, h); + } + if (endsWith(uri, '.bt')) { + return media('animation', uri, w, h); + } + if (endsWith(uri, '.png')) { + return media('image', uri, w, h); + } + if (endsWith(uri, '.jpg')) { + return media('image', uri, w, h); + } + if (endsWith(uri, '.gif')) { + return media('image', uri, w, h); + } + if (l_war <= log_level) alert("[UI] WARNING: bad suffix for an icon URI: " + uri); + return media('image', uri, w, h); +} + +// +// substitute for the useful predefined function endsWith +// +function endsWith(s1, s2) { + return s1.toLowerCase().substring(s1.length - s2.length) == s2; +} + diff --git a/gui/iphone_wm_gui.svg b/gui/iphone_wm_gui.svg new file mode 100644 index 0000000..80df4a5 --- /dev/null +++ b/gui/iphone_wm_gui.svg @@ -0,0 +1,547 @@ + + + + + + + + + + + + + + + + + + + + + + + + + flUpDir(); + + + + + + flPrevFiles(); + + + + + + flNextFiles(); + + + + + + + + + + + flUpDir(); + + + + + + flPrevFiles(); + + + + + + flNextFiles(); + + + + + + flScanDir(); + + + + + + + + + + + document.getElementById("fileMenuElement0r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement0r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement1r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement1r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement2r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement2r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement3r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement3r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement4r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement4r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement5r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement5r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement6r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement6r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement7r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement7r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement8r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement8r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement9r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement9r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement10r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement10r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement11r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement11r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement12r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement12r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement13r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement13r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement14r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement14r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement15r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement15r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement16r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement16r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement17r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement17r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement18r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement18r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement19r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement19r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement20r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement20r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement21r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement21r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement22r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement22r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement23r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement23r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement24r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement24r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement25r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement25r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement26r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement26r").setAttribute("fill", "rgb(245,245,245)"); + + + + + + document.getElementById("fileMenuElement27r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement27r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement28r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement28r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement29r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement29r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement30r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement30r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement31r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement31r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement32r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement32r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement33r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement33r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement34r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement34r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement35r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement35r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement36r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement36r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement37r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement37r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement38r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement38r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement39r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement39r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement40r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement40r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement41r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement41r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement42r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement42r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement43r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement43r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement44r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement44r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement45r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement45r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement46r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement46r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement47r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement47r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement48r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement48r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + document.getElementById("fileMenuElement49r").setAttribute("fill", "black"); + document.getElementById("fileMenuElement49r").setAttribute("fill", "rgb(245,245,245)"); + ; + + + + + + + + Push + on_widget_remote(); + + + + KillW + on_kill_widget(); + + widgetName + + + + + Add + on_widget_add_menu(); + + + + Reset + on_clean_up(); + + + + Scan + on_dir_scan(); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + home_button(evt); + + + + + + left_button(); + + + + + right_button(); + + + + + + + left_buttonW(); + + + + + right_buttonW(); + + + + + + + + + resize(); + + diff --git a/gui/mpegu-core.js b/gui/mpegu-core.js new file mode 100644 index 0000000..97a5e07 --- /dev/null +++ b/gui/mpegu-core.js @@ -0,0 +1,1571 @@ +//This software module was originally developed by TelecomParisTech in the +//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard. +// +//This software module is an implementation of a part of one or +//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets +//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets +//(ISO/IEC 23007-1) free license to this software module or modifications +//thereof for use in hardware or software products claiming conformance to +//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software +//module in hardware or software products are advised that its use may +//infringe existing patents. +//The original developer of this software module and his/her company, the +//subsequent editors and their companies, and ISO/IEC have no liability +//for use of this software module or modifications thereof in an implementation. +//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming +//products. +//Telecom ParisTech retains full right to use the code for his/her own purpose, +//assign or donate the code to a third party and to inhibit third parties from +//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products. +// +//This copyright notice must be included in all copies or derivative works. +// +//Copyright (c) 2009. +// +///////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// +// +// Authors: +// Jean Le Feuvre, Telecom ParisTech +// Jean-Claude Dufourd, Telecom ParisTech +// +///////////////////////////////////////////////////////////////////////////////// + + + +/* + The widget manager in MPEG-U reference software is implemented in 2 parts: + - a native GPAC module called gm_widgetman implementing + * W3C widget loading (download, unzip, manifest parsing) + * W3C Widget APIs + * MPEG Widgets interfaces, messages and parameters listing + + - a script module (this file) implementing + * MPEG Widget interface binding with UPnP services (UPnP is implemented in another module) + * MPEG Widget interface binding with other local widgets + * MPEG Widget discovery through UPnP devices announcement. The discovery is done by setting the device presentationURL to the widget URL + + + A typical user of the widget manager will therefore see the following interfaces: + +interface WidgetManager { + readonly unsigned integer num_widgets; + string last_widget_dir; + + Widget open(string url, string source_ip); + void bind(Widget wid); + Widget get(unsigned int idx); + void unload(Widget wid); + void migrate_widget(upnp_renderer, widget); + void corein_message(widget, msg_name, arg1name, arg1val, ....); + + //callback functions for the GUI to be notifed of widgets added / removed when UPnP devices are appearing/disappearing + void on_widget_add(widget); + void on_widget_remove(widget); + + //callback functions for core:out + void coreOutSetSize(wid, args); + void coreOutShow(wid, args); + void coreOutHide(wid, args); + void coreOutRequestActivate(wid, args); + void coreOutRequestDeactivate(wid, args); + void coreOutShowNotification(wid, args); + void coreOutPlaceComponent(wid, args); + void coreOutGetAttention(wid, args); + + } + + +interface Widget { + //exported meta-data from MPEG-U Manifest + readonly string mainEncoding; + readonly string mainMimeType; + readonly integer defaultWidth; + readonly integer defaultHeight; + + readonly Array icons; + readonly Array features; + readonly Array preferences; + + + readonly string identifier; + readonly string name; + readonly string shortName; + readonly string authorName; + readonly string authorEmail; + readonly string authorHref; + readonly string description; + readonly string viewmodes; + readonly string licence; + readonly string licenceHref; + readonly string version; + readonly string uuid; + readonly boolean discardable; + readonly boolean multipleInstances; + + //widget-manager specific data + readonly string manifest; + readonly string main; + readonly string localizedSrc; + readonly Array components; //array of widget objects used as component + boolean permanent; + readonly boolean is_component; + readonly Widget parent; + readonly boolean activated; + readonly string section; + readonly integer num_section; + readonly integer num_interfaces; + readonly integer num_bound_interfaces; + readonly integer num_components; + + + device = local UPnP device created in order to publish interfaces of this widget as upnp services + originating_device = the device who sent the widget, either through migration or device discovery (presentationURL) + originating_device_ip = the IP of the device who sent the widget + + + + void activate(Element node_with_ref_to_main); + void deactivate(); + } + +interface Icon { + readonly string src; + readonly string relocated_src; + readonly integer width; + readonly integer height; +} + +interface Preference { + readonly string name; + readonly string value; + readonly boolean readonly; +} + +interface Features { + readonly string name; + readonly boolean required; + readonly Array params +} + +interface FeatureParam { + readonly string name; + readonly string value; +} + */ + +/*log function*/ +function log(lev, str) { + if (lev <= log_level) alert('[WM] ' + str); +} + +/*log levels*/ +l_err = 0; +l_war = 1; +l_inf = 2; +l_deb = 3; + +/*default log level*/ +log_level = l_err; + +/*initializes the widget manager*/ +function widget_manager_init() { + log(l_inf, 'Initializing MPEG-U Widgets'); + /*if UPnP is enabled, override the deviceAdd callback*/ + WidgetManager.upnp = false; + if (typeof(UPnP) != 'undefined') { + WidgetManager.upnp = true; + log(l_inf, 'Enabling Widget UPnP Discovery') + UPnP.onDeviceAdd = wmjs_on_device_add; + } + WidgetManager.migrate_widget = wmjs_migrate_widget; + WidgetManager.probe = wmjs_probe_widget; + WidgetManager.open = wmjs_open_widget; + WidgetManager.bind = wmjs_bind_widget; + + WidgetManager.on_widget_add = wmjs_on_widget_add; + WidgetManager.on_widget_remove = wmjs_on_widget_remove; + + WidgetManager.check_bindings = wmjs_bind_widgets; + WidgetManager.unbind_widget = wmjs_unbind_widget; + WidgetManager.corein_message = wmjs_corein_message; + WidgetManager.initialize(); + log(l_inf, 'MPEG-U Widgets successfully initialized'); + initCore(); +} + +function wmjs_on_widget_add(widget) {} + +function wmjs_on_widget_remove(widget) {} + +function wmjs_migrate_widget(render, widget) { + if (WidgetManager.upnp) { + var url, ctx, ctx_uri, uri; + url = widget.url; + ctx = widget.get_context(); + uri = UPnP.ShareResource(url, render.HostName); + + if (ctx != "") { + if ((uri.indexOf('?') < 0) && (uri.indexOf('%3f') < 0) && (uri.indexOf('%3F') < 0)) { + ctx_uri = uri + '?mpeg-u-context'; + } else { + ctx_uri = uri + '&mpeg-u-context'; + } + UPnP.ShareVirtualResource(ctx_uri, ctx, "application/mpegu-context", true); + log(l_inf, 'Migrating widget ' + url + ' to renderer ' + render.Name + ' as resource ' + uri); + log(l_inf, 'Migration Context ' + ctx); + log(l_inf, 'Migration Context URI ' + ctx_uri); + } + render.Open(uri); + } +} + +function wmjs_probe_widget(url) { + if ((url.lastIndexOf('.wgt') >= 0) || (url.lastIndexOf('.mgt') >= 0) || (url.lastIndexOf('.xml') >= 0)) return 1; + return 0; +} + + +function wmjs_open_widget(url, src_ip) { + log(l_deb, "wmjs_open_widget"); + var wid = WidgetManager.load(url); + if (wid == null) { + log(l_err, 'File ' + url + ' is not a valid widget'); + return null; + } + wid.device = null; + wid.originating_device = null; + wid.originating_device_ip = null; + if (src_ip) { + wid.permanent = false; + wid.originating_device_ip = src_ip; + log(l_inf, 'Widget received - ip ' + wid.originating_device_ip); + } else { + wid.permanent = true; + wid.originating_device_ip = null; + } + return wid; +} + +/*performs an unbind check on all widgets*/ +function wmjs_unbind_widget(widget) { + var i, count, wid, ifce_count, j; + log(l_inf, 'wmjs_unbind_widget ' + widget.name); + + if (WidgetManager.upnp && widget.device) { + UPnP.DeleteDevice(widget.device); + widget.device = null; + } + + count = WidgetManager.num_widgets; + ifce_count = widget.num_interfaces; + for (i = 0; i < count; i++) { + wid = WidgetManager.get(i); + if (!wid) continue; + if (wid == widget) continue; + if (!wid.activated) continue; + + for (j = 0; j < ifce_count; j++) { + var an_ifce = widget.get_interface(j); + wid.unbind_interface(an_ifce, widget); + } + } + wmjs_bind_widgets(); +} + + +/*performs a bind check on all widgets*/ +function wmjs_bind_widgets() { + log(l_deb, 'wmjs_bind_widgets'); + var i, wid, count; + count = WidgetManager.num_widgets; + for (i = 0; i < count; i++) { + wid = WidgetManager.get(i); + if (!wid) continue; + if (!wid.activated) continue; + WidgetManager.bind(wid); + } +} + + +/*performs a bind on the given widget*/ +function wmjs_bind_widget(wid) { + var i, j, ifce_count, device, service, msg, do_bind; + + if (!wid.activated) { + log(l_inf, 'widget not activated - cannot bind'); + return; + } + ifce_count = wid.num_interfaces; + + log(l_inf, 'Binding widget ' + wid.name + ' - Nb Interfaces ' + ifce_count); + + /*browse all interfaces and locate services*/ + for (i = 0; i < ifce_count; i++) { + var ifce = wid.get_interface(i); + log(l_inf, 'Binding interface ' + ifce.type); + + /*look for a core:* service for this interface and setup*/ + if (wmjs_bind_interface_to_core_service(wid, ifce)) { + continue; + } + /*if our widget is already bound to this widget, skip it*/ + if (!ifce.multipleBinding && wid.is_interface_bound(ifce)) { + log(l_deb, 'Widget ' + wid.name + ' interface ' + ifce.type + ' already bound'); + continue; + } + /*if the widget is the provider of the service, create the service*/ + if (ifce.serviceProvider) { + log(l_inf, 'widget is a service provider'); + if (WidgetManager.upnp) wmjs_create_upnp_service(wid, ifce); + continue; + } + /*look for a UPnP service for this interface and setup*/ + if (WidgetManager.upnp && wmjs_bind_interface_to_upnp(wid, ifce)) { + continue; + } + /*look for a local service for this interface*/ + if (wmjs_bind_interface_to_local(wid, ifce)) { + continue; + } + /*no service found*/ + log(l_inf, 'Cannot find service for widget ' + wid.name + ' interface ' + ifce.type); + } +} + +/*called when a new UPnP device has been added or removed in the network*/ +function wmjs_on_device_add(device, is_add) { + log(l_deb, 'wmjs_on_device_add'); + if (!is_add) { + log(l_inf, 'Device Removed ' + device.Name); + wmjs_unbind_upnp_device(device); + if (device.widget != null) { + log(l_inf, 'Widget Removed ' + device.widget.name); + WidgetManager.on_widget_remove(device.widget); + device.widget.originating_device = null; + device.widget = null; + } + WidgetManager.check_bindings(); + return; + } + log(l_inf, 'Device Added ' + device.Name + ' URL ' + device.PresentationURL); + WidgetManager.check_bindings(); + /*look for a presentation url - if not given or not identifying a widget, don't do anything*/ + var url = device.PresentationURL; + if (!url || (url == '')) return; + if (! WidgetManager.probe(url)) return; + /*OK load the widget*/ + var widget = WidgetManager.load(url); + widget.newBorn = true; + if (widget == null) { + log(l_err, 'File ' + url + ' is not a valid widget'); + return; + } + widget.originating_device = device; + device.widget = widget; + /*indicate our widget is not to be stored*/ + widget.permanent = false; + WidgetManager.on_widget_add(widget); +} + + +/* + LOCAL INTERFACE BINDING ROUTINES + + In this implementation, widgets-to-widget communication in the same widget manager are called "local" communications. + The implementation do not rely on any service description for that and directly matches the widgets interfaces + */ + +function wmjs_output_trigger_callback_local(msg_out, wid_src, msg_in, wid_dst) { + log(l_deb, "wmjs_output_trigger_callback_local"); + return function(value) { + log(l_deb, "wmjs_output_trigger_callback_local/function " + value + " '" + wid_src.name + "'" + wid_dst.name + "'"); + var param_count = msg_out.num_params; + var args = new Array(); + var is_script = 0; + var ai = 0, i; + if (msg_in.has_script_input) is_script = 1; + log(l_inf, 'Invoking Widget(' + wid_src.name + ').' + msg_out.name); + for (i = 0; i < param_count; i++) { + var param = msg_out.get_param(i); + if (param.is_input) continue; + + if (is_script) { + args[ai] = wid_src.get_param_value(param); + ai++; + } else { + wid_dst.set_input(msg_in.get_param(param.name), wid_src.get_param_value(param)); + } + } + log(l_inf, 'Calling Widget(' + wid_dst.name + ').' + msg_in.name); + + if (msg_in.has_input_action) { + wid_dst.call_input_action(msg_in); + } else if (is_script) { + wid_dst.call_input_script(msg_in, args); + } + }; +} + + +function wmjs_interface_invoke_callback_local(wid_dst, ifce_dst, is_reply) { + log(l_deb, "wmjs_interface_invoke_callback_local '" + wid_dst.name + "' '" + ifce_dst.type + "' - reply " + is_reply); + return function() { + var j, i, ai, param_count, msgHandler, msg_src, msg_dst, is_script; + var args = new Array(); + is_script = 0; + msgHandler = arguments[0]; + /*get msg from source interface (this object)*/ + msg_src = this.get_message(msgHandler.msgName); + // JCD: take into account message repetition, if any + for (j = 0; j < ifce_dest.num_messages; j++) { + msg_dst = ifce_dest.get_message(j); + if (msg_dst.name == msgHandler.nsgName) { + log(l_deb, (is_reply ? 'invokeReply ' : 'invoke ') + msg_src.name + ' on ' + wid_dst.name + '.' + msg_dst.name); + if (msg_dst.has_script_input) is_script = 1; + param_count = msg_src.num_params; + ai = 1; + for (i = 0; i < param_count; i++) { + var param = msg_dst.get_param(i); + if (! param.is_input) continue; + if (is_script) { + args[ai - 1] = arguments[ai]; + } else { + wid_dst.set_input(param, arguments[ai]); + } + ai++; + } + if (msg_dst.has_input_action) { + wid_dst.call_input_action(msg_dst); + } else if (is_script) { + wid_dst.call_input_script(msg_dst, args); + } + } + } + }; +} + +/* + END OF LOCAL INTERFACE BINDING ROUTINES + */ + + +function wmjs_bind_interface_to_local(wid, ifce) { + log(l_deb, "wmjs_bind_interface_to_local '" + wid.name + "' " + ifce.type); + var i, count, count2, j, a_ifce, a_msg, par, a_par, k, nb_ok, ret, set_bind, a_wid; + count = WidgetManager.num_widgets; + ret = false; + // this is the main loop to try to bind a widget to any other + for (i = 0; i < count; i++) { + a_wid = WidgetManager.get(i); + if (!a_wid) continue; + if (a_wid == wid) continue; + if (!a_wid.activated) continue; + count2 = a_wid.num_interfaces; + // now that we know this is a valid widget and not the same as wid + // loop on all its interfaces to find one of the right type + for (j = 0; j < count2; j++) { + a_ifce = a_wid.get_interface(j); + if (a_ifce.type == ifce.type) break; + } + if (j == count2) continue; + + /*if our widget is already bound to this widget (multiple binding==true) or to any widget (multiple binding==false), skip it*/ + if (wid.is_interface_bound(ifce, ifce.multipleBinding ? a_wid : null)) { + log(l_inf, 'Widget ' + wid.name + ' interface ' + ifce.type + ' is already bound'); + continue; + } + /*if our widget is already bound to this widget (multiple binding==true) or to any widget (multiple binding==false), skip it*/ + if (a_wid.is_interface_bound(a_ifce, a_ifce.multipleBinding ? wid : null)) { + log(l_inf, 'Widget ' + a_wid.name + ' interface ' + a_ifce.type + ' is already bound'); + continue; + } + + set_bind = 0; + // we have found an interface of the right type in the other widget + log(l_inf, 'Checking local widget ' + a_wid.name + ' for interface ' + ifce.type); + // loop on the messages to check if they match + for (j = 0; j < ifce.num_messages; j++) { + var msg = ifce.get_message(j), l; + //if (msg.is_input) continue; // JCD: remove test + // does the other interface have this message + // JCD: remove next line and take repetition of messages into account + // a_msg = a_ifce.get_message(msg.name); + for (l = 0; l < a_ifce.num_messages; l++) { + a_msg = a_ifce.get_message(l); + alert(msg.name+" "+a_msg.name); + if (a_msg.name == msg.name) { + // the messages have matching names, check direction + if (msg.is_input == a_msg.is_input) { + log(l_inf, 'Local widget message for ' + msg.name + ' is not in direction ' + (msg.is_input ? 'output' : 'input')); + continue; + } + // the messages have matching names and directions, check params + if (msg.num_params != a_msg.num_params) { + log(l_war, 'Local widget message ' + msg.name + ' does not have the same number of parameters'); + continue; + } + /*check all params*/ + nb_ok = 0; + for (k = 0; k < msg.num_params; k++) { + par = msg.get_param(k); + a_par = a_msg.get_param(par.name); + if (a_par != null && par.is_input != a_par.is_input) nb_ok ++; + } + if (nb_ok != msg.num_params) { + log(l_war, 'Local widget message ' + msg.name + ' does not have the same input/output parameters'); + continue; + } + set_bind ++; + // the messages match + log(l_inf, 'Binding ' + wid.name + '.' + msg.name + ' to ' + a_wid.name + '.' + a_msg.name); + /*OK let's bind this action: we only need to assign the output trigger, the input action will be called from the other widget*/ + if (msg.has_output_trigger) { + wid.bind_output_trigger(msg, wmjs_output_trigger_callback_local(msg, wid, a_msg, a_wid), a_wid); + } + /*OK let's bind this action: we only need to assign the output trigger, the input action will be called from the other widget*/ + if (a_msg.has_output_trigger) { + a_wid.bind_output_trigger(a_msg, wmjs_output_trigger_callback_local(a_msg, a_wid, msg, wid), wid); + } + } + } + } + if (!set_bind) continue; + + /*create callback for programmatic action triggers*/ + ifce.invoke = wmjs_interface_invoke_callback_local(a_wid, a_ifce, 0); + ifce.invokeReply = wmjs_interface_invoke_callback_local(a_wid, a_ifce, 1); + /*create callback for programmatic action triggers*/ + a_ifce.invoke = wmjs_interface_invoke_callback_local(wid, ifce, 0); + a_ifce.invokeReply = wmjs_interface_invoke_callback_local(wid, ifce, 1); + a_wid.bind_interface(a_ifce, wid, 'localhost'); + wid.bind_interface(ifce, a_wid, 'localhost'); + ret = true; + } + return ret; +} + + +/* + INTERFACE BINDING TO UPNP SERVICES ROUTINES + + This implemntation supports binding interfaces to existing UPnP services + */ + +/*create a listener function for input parameters*/ +function wmjs_upnp_action_listener(widget, par, msg) { + log(l_deb, "wmjs_upnp_action_listener '" + widget.name + "' " + (par != null ? par.name : 'noPar') + " " + (msg != null ? msg.name : 'noMsg')); + return function(value) { + log(l_deb, "wmjs_upnp_action_listener/function '" + widget.name + "' " + (par != null ? par.name : 'noPar') + " " + + (msg != null ? msg.name : 'noMsg') + " " + value); + if (par != null) widget.set_input(par, value); + if (msg != null) widget.call_input_action(msg); + } +} + +/*create a listener function for input parameters*/ +function wmjs_upnp_action_listener_script(widget, msg) { + log(l_deb, 'wmjs_upnp_action_listener_script'); + return function() { + var i, count, act, par, rval, msgHandler, args; + act = arguments[0]; + log(l_deb, 'wmjs_upnp_action_listener_script/function:nb args ' + arguments.length); + msgHandler = arguments[1]; + log(l_deb, 'wmjs_upnp_action_listener_script/function:msgh ' + msgHandler); + args = new Array(); + count = msg.num_params; + for (i = 0; i < count; i++) { + par = msg.get_param(i); + if (!par.is_input) continue; + rval = act.GetArgumentValue(par.name); + if (par.script_type == 'number') { + args.push(parseInt(rval)); + } else if (par.script_type == 'boolean') { + args.push(rval == 'true'); + } else { + args.push(rval); + } + } + msgHandler.onInvokeReply(args); + } +} + + +/**/ +function wmjs_output_trigger_callback_upnp(service, widget, msg) { + log(l_deb, 'wmjs_output_trigger_callback_upnp'); + return function(value) { + log(l_deb, 'wmjs_output_trigger_callback_upnp/function ' + value); + var i, pi, param_count = msg.num_params; + var args = new Array(); + pi = 0; + for (i = 0; i < param_count; i++) { + var param = msg.get_param(i); + if (param.is_input) continue; + args[pi] = param.name; + args[pi + 1] = widget.get_param_value(param); + pi += 2; + } + log(l_inf, 'Calling UPnP Action ' + msg.name + " " + param_count); + service.CallAction(msg.name, args); + }; +} + + +/*create the action callback*/ +function wmjs_message_setup_upnp(widget, service, msg) { + log(l_deb, 'wmjs_message_setup_upnp ' + msg.name); + /*first let's browse all the message params*/ + var rad, i, param_count, has_script_input; + has_script_input = false; + param_count = msg.num_params; + for (i = 0; i < param_count; i++) { + var param = msg.get_param(i); + /*interface not valid for this service*/ + if (!service.HasAction(msg.name, param.name)) { + if (!param.is_input) { + log(l_war, 'Output param ' + param.name + ' not found in action - cannot bind action'); + return false; + } + continue; + } + /*this is a service -> widget param */ + if (param.is_input) { + if (msg.has_input_action) { + service.SetActionListener(msg.name, wmjs_upnp_action_listener(widget, param, null), param.name); + } else { + has_script_input = true; + // todo: pas vrai d'apres JCD + } + } + /*this is a widget -> service param , used in callback function*/ + } + /*assign the output trigger*/ + if (msg.has_output_trigger) { + var fun_name = 'call_' + msg.name; + widget[fun_name] = wmjs_output_trigger_callback_upnp(service, widget, msg); + widget.bind_output_trigger(msg, widget[fun_name], service); + } + /*assign the input action*/ + if (msg.has_input_action) { + service.SetActionListener(msg.name, wmjs_upnp_action_listener(widget, null, msg)); + } else if (has_script_input) { + service.SetActionListener(msg.name, wmjs_upnp_action_listener_script(widget, msg), true); + } + return true; +} + + +function wmjs_interface_invoke_callback_upnp(service) { + log(l_deb, 'wmjs_interface_invoke_callback_upnp'); + return function() { + log(l_deb, 'wmjs_interface_invoke_callback_upnp/function'); + var args = new Array(); + var i, pi, ai, param_count, msg, ifce_msg; + + msg = arguments[0]; + ifce_msg = this.get_message(msg.msgName); + param_count = ifce_msg.num_params; + log(l_inf, 'UPnP invoke action ' + ifce_msg.name + ' - ' + msg.msgName); + + pi = 0; + ai = 1; + for (i = 0; i < param_count; i++) { + var param = ifce_msg.get_param(i); + if (param.is_input) continue; + + args[pi] = param.name; + args[pi + 1] = arguments[ai]; + pi += 2; + ai++; + } + service.CallAction(msg.msgName, args, msg); + }; +} + + +function wmjs_bind_interface_to_upnp(wid, ifce) { + log(l_deb, "wmjs_bind_interface_to_upnp"); + var do_bind, is_upnp = false; + var service = null; + + if (wid.originating_device) { + service = wid.originating_device.FindService(ifce.type); + } else if (wid.originating_device_ip) { + service = UPnP.FindService(wid.originating_device_ip, ifce.type); + } else { + var j, dev_count = UPnP.DevicesCount; + log(l_deb, 'wmjs_bind_interface_to_upnp nb ' + dev_count); + for (j = 0; j < dev_count; j++) { + device = UPnP.GetDevice(j); + log(l_deb, "wmjs_bind_interface_to_upnp " + device.Name + ' - type: ' + ifce.type); + /*do we have a UPnP service with the same interface type ?*/ + service = device.FindService(ifce.type); + + /*our widget is not bound to this service*/ + if (service) { + if (!wid.is_interface_bound(ifce, service)) break; + service = null; + is_upnp = true; + } + } + } + if (!service) return is_upnp; + + /*our widget is already bound to this service*/ + if (wid.is_interface_bound(ifce, service)) { + log(l_inf, 'Found UPnP Service for interface ' + ifce.type); + return true; + } + + log(l_inf, 'Found UPnP Service for interface ' + ifce.type); + do_bind = 0; + for (j = 0; j < ifce.num_messages; j++) { + var msg = ifce.get_message(j); + /*if we have a state variable in the service with the same name as the pin, bind it*/ + if (service.HasStateVariable(msg.name)) { + var param = msg.get_param(0); + if (param && (param.name == msg.name)) { + /*set listeners for declarative action triggers*/ + log(l_deb, 'Found UPnP state variable for message ' + msg.name); + service.SetStateVariableListener(wmjs_upnp_action_listener(wid, param, msg), param.name); + do_bind = 1; + } + } + /*if we have an action in the service with the same name as the pin, bind it*/ + else if (service.HasAction(msg.name)) { + /*set listeners for declarative action triggers*/ + log(l_deb, 'Found UPnP action for message ' + msg.name); + wmjs_message_setup_upnp(wid, service, msg); + do_bind = 1; + } + /*NOTE: UPnP actions are only messageOut, messageIn are UPnP events and don't have output paramaters. We therefore never need to setup + the invokeReply callback for interfaces matching UPnP services. !! This is not true for UPnP services created to publish an interface, eg serviceProvider="true".*/ + } + if (do_bind) { + /*create callback for programmatic action triggers*/ + log(l_inf, 'Binding widget ' + wid.name + ' interface ' + ifce.type + ' to host ' + service.Hostname); + ifce.invoke = wmjs_interface_invoke_callback_upnp(service); + /*bind interface*/ + wid.bind_interface(ifce, service, service.Hostname); + } + return true; +} + +function wmjs_unbind_upnp_device(device) +{ + var i, count, j, ifce_count; + count = WidgetManager.num_widgets; + + for (i = 0; i < count; i++) { + wid = WidgetManager.get(i); + if (!wid) continue; + if (!wid.activated) continue; + + ifce_count = wid.num_interfaces; + for (j = 0; j < ifce_count; j++) { + var ifce = wid.get_interface(j); + /*do we have a UPnP service with the same interface type ?*/ + var service = device.FindService(ifce.type); + if (!service) continue; + + /*unbind this interface*/ + if (wid.is_interface_bound(ifce, service)) { + wid.unbind_interface(ifce, service); + } + } + } +} + + +/* + END OF INTERFACE BINDING TO UPNP SERVICES ROUTINES + */ + + + +/* + INTERFACE PUBLISHING AS UPNP SERVICES ROUTINES + + This implementation supports publishing a widget interface in the network as a UPnP service. This is done + by generating on the fly a new device associated with a widget, and one UPnP service per widget interface. + The UPnP service description (SCPD) is generated on the fly from the interface description + */ + + +var header = '10'; +var middler = ''; +var footer = ''; + +function wmjs_make_interface_scpd(widget, ifce) { + log(l_deb, "wmjs_make_interface_scpd"); + var variables = '', actions = '', vars, j, msg, k, param, numstatevar = 0; + /*do actions*/ + for (j = 0; j < ifce.num_messages; j++) { + msg = ifce.get_message(j); + actions += '' + msg.name + ''; + for (k = 0; k < msg.num_params; k++) { + param = msg.get_param(k); + actions += '' + param.name + '' + (param.is_input ? 'in' : 'out'); + actions += 'v' + numstatevar + ''; + numstatevar++; + } + actions += ''; + } + /*do variables*/ + for (k = 0; k < numstatevar; k++) { + variables += 'v' + k + 'string'; + } + return header + actions + middler + variables + footer; +} + +/* generic processing of any action from outside */ +function wmjs_widget_upnp_process_action(action) { + log(l_deb, 'wmjs_widget_upnp_process_action Action ' + action.Name + ' invoked on ' + action.Service.ifce.type); + var i, ai, args, msg, has_output = false; + /* find the message matching the action in the interface */ + msg = null; + for (i = 0; i < action.Service.ifce.num_messages; i++) { + msg = action.Service.ifce.get_message(i); + if (msg.name == action.Name) break; + msg = null; + } + if (msg == null) { + log(l_inf, 'wmjs_widget_upnp_process_action Action not found: ' + action.Name + ' invoked on ' + action.Service.name); + return; + } + args = new Array(); + ai = 0; + /*assign action for any async callback from the scene (cf wmjs_upnp_action_response)*/ + action.Service.action = action; + /* for each param in the found message */ + for (i = 0; i < msg.num_params; i++) { + var param = msg.get_param(i); + /* only process input params */ + if (!param.is_input) { + has_output = true; + continue; + } + if (msg.has_script_input) { + /* input param is scripted, store argument value in args array */ + args[ai] = action.GetArgument(param.name); + } else { + /* input param is not scripted but declarative, store argument value directly in scene tree */ + this.widget.set_input(param, action.GetArgument(param.name)); + } + ai++; + } + if (msg.has_input_action) { + /* message is not scripted, call input action */ + this.widget.call_input_action(msg); + } else if (msg.has_script_input) { + /* message is scripted, call the script function specified in inputAction */ + this.widget.call_input_script(msg, args); + } + if (!has_output) { + log(l_inf, 'wmjs_widget_upnp_process_action sending empty reply'); + action.SendReply(); + action.Service.action = null; + } +} + + +function wmjs_upnp_event_sender(service, widget, msg) { + return function(value) { + log(l_deb, 'wmjs_upnp_event_sender/function ' + service.ifce.type + " " + widget.name + " " + msg.name); + var i, pi, param_count = msg.num_params; + var args = new Array(); + pi = 0; + for (i = 0; i < param_count; i++) { + var param = msg.get_param(i); + if (param.is_input) continue; + args[pi] = param.name; + args[pi + 1] = widget.get_param_value(param); + pi += 2; + } + log(l_inf, 'sending UPnP event ' + msg.name); + service.CallAction(msg.name, args); + }; +} + +function wmjs_upnp_action_response(service, widget, msg) { + return function(value) { + if (service.action == null) { + // TODO this code avoids the bug that this function is called twice: find out why it is called twice! + log(l_inf, 'wmjs_upnp_action_response/function DUPL(return) ' + service.ifce.type + " '" + widget.name + "' " + msg.name); + return; + } + var i, pi, param_count = msg.num_params; + var args = new Array(); + pi = 0; + for (i = 0; i < param_count; i++) { + var param = msg.get_param(i); + if (param.is_input) continue; + args[pi] = param.name; + args[pi + 1] = widget.get_param_value(param); + pi += 2; + } + log(l_inf, 'UPnP sending reply on action ' + service.action + ': ' + service.ifce.type + " '" + widget.name + "' " + msg.name); + service.action.SendReply(args); + service.action = null; + }; +} + + +function wmjs_upnp_action_response_script(service) { + return function() { + if (service.action == null) { + // this code avoids the bug that this function is called twice: find out why it is called twice! + return; + } + var i, pi, ai, param_count; + var args = new Array(); + var msgHandler = arguments[0]; + var msg = service.ifce.get_message(msgHandler.msgName); + + pi = 0; + ai = 1; + for (i = 0; i < param_count; i++) { + var param = msg.get_param(i); + if (param.is_input) continue; + args[pi] = param.name; + args[pi + 1] = arguments[ai]; + pi += 2; + ai++; + } + log(l_inf, 'UPnP sending reply on action ' + service.action); + service.action.SendReply(args); + service.action = null; + }; +} + +function wmjs_create_upnp_service(widget, ifce) { + var i, service, scpd, start_device = 0; + + log(l_deb, 'widget device : ' + widget.device); + if (!widget.device) { + //log(l_inf,'creating device'); + /* at least one interface is a provider, so create a device */ + var name = widget.name.replace(new RegExp(' ', 'g'), '_'); + widget.device = UPnP.CreateDevice("urn:mpeg:mpeg-u:widget:provider:" + name + ":1", name); + /* remember the widget in the device */ + widget.device.widget = widget; + widget.device.enabled = 1; + start_device = 1; + /* implement the response to a external call (messageOut of another widget) */ + widget.device.OnAction = wmjs_widget_upnp_process_action; + } + + /*service has already been created*/ + if (typeof(ifce.started) != 'undefined') return; + + log(l_inf, 'wmjs_create_upnp_service'); + scpd = wmjs_make_interface_scpd(widget, ifce); + log(l_inf, 'Service scpd ' + scpd); + service = widget.device.SetupService(name, ifce.type, ifce.type + ".001", scpd); + service.ifce = ifce; + + /* for each message in a provider interface */ + for (i = 0; i < ifce.num_messages; i++) { + msg = ifce.get_message(i); + /* if there is an output_trigger, a reply may be triggered after a call */ + if (msg.has_output_trigger) { + if (msg.is_input) { + /* output in an input message => this is a reply */ + var fun_name1 = 'respond_' + msg.name; + widget[fun_name1] = wmjs_upnp_action_response(service, widget, msg); + widget.bind_output_trigger(msg, widget[fun_name1], service); + } else { + /* output in an output message => this is an event */ + var fun_name2 = 'send_event_' + msg.name; + widget[fun_name2] = wmjs_upnp_event_sender(service, widget, msg); + widget.bind_output_trigger(msg, widget[fun_name2], service); + } + } + /*if message is input, a reply may be sent*/ + else if (msg.is_input) { + var j, has_out; + has_out = 0; + for (j = 0; j < msg.num_params; j++) { + var param = msg.get_param(j); + if (param.is_input) continue; + has_out = 1; + break; + } + if (has_out) { + ifce.invokeReply = wmjs_upnp_action_response_script(service); + } + } + } + ifce.started = true; + + if (start_device) { + //log(l_inf,"device start"); + widget.device.Start(); + } +} + + +/* + END OF INTERFACE PUBLISHING AS UPNP SERVICES ROUTINES + */ + +/********************************************************* + Start of implementation of core:in and core:out interfaces + *********************************************************/ + +var coreIn, coreOut; + +// +// function defining messages for the core:* interfaces implemented by the WM +// +function defineMessage(name, direction, executeFunction, params1, params2) { + var msg = new Object(); + msg.name = name; + msg.is_input = !direction; // the standard defines the point of view of the widget, not that of the WM + msg.num_params = 0; + // the executeFunction is the function implemented by widman.js and + // which passes the buck to a function of the widget manager, if there is one + if (executeFunction != null) msg.execute = executeFunction; + // in a messageOut, params1 contains outputs and params2 contains inputs + // in a messageIn, params1 contains inputs and params2 contains outputs + if (direction) { + if (params1 != null) { + msg.paramsOut = params1; + msg.num_params += params1.length; + } + if (params2 != null) { + msg.paramsIn = params2; + msg.num_params += params2.length; + } + } else { + if (params1 != null) { + msg.paramsIn = params1; + msg.num_params += params1.length; + } + if (params2 != null) { + msg.paramsOut = params2; + msg.num_params += params2.length; + } + } + //alert("Message defined: "+msg.name+' '+msg.num_params+' '+msg.is_input+' '+ + // (msg.paramsIn != null ? msg.paramsIn.length : 0)+' '+ + // (msg.paramsOut != null ? msg.paramsOut.length : 0)); + return msg; +} + +// +// function defining the parameter lists for messages +// the direction of a parameter is implicit in its position in the paramsIn or paramsOut of a message +// +function defineParams() { + var params = new Array(); + var i = 0; + for (; i < arguments.length; i++) { + params[i] = arguments[i]; + } + return params; +} + +// +// get message by name in a core interface (core:in or core:out +// +function getMessage(core, s) { + var i = 0; + for (; i < core.length; i++) { + if (core[i].name == s) return core[i]; + } + return null; +} + +// +// get a parameter from a message by name +// +function hasParam(msg, name) { + var i = 0; + if (msg.paramsIn) { + for (i = 0; i < msg.paramsIn.length; i++) { + if (msg.paramsIn[i] == name) return true; + } + } + if (msg.paramsOut) { + for (i = 0; i < msg.paramsOut.length; i++) { + if (msg.paramsOut[i] == name) return true; + } + } + return false; +} + +// +// get a parameter from a message by index +// +function getParam(msg, i) { + if (!msg.is_input) { + if (msg.paramsIn) { + if (i < msg.paramsIn.length) { + return msg.paramsIn[i]; + } else { + i -= msg.paramsIn.length; + } + } + if (msg.paramsOut) { + if (i < msg.paramsOut.length) { + return msg.paramsOut[i]; + } + } + } else { + if (msg.paramsOut) { + if (i < msg.paramsOut.length) { + return msg.paramsOut[i]; + } else { + i -= msg.paramsOut.length; + } + } + if (msg.paramsIn) { + if (i < msg.paramsIn.length) { + return msg.paramsIn[i]; + } + } + } + return null; +} + +// +// get a parameter from a message by index +// +function getInputParam(msg, i) { + if (!msg.is_input) { + if (msg.paramsIn) { + if (i < msg.paramsIn.length) { + return msg.paramsIn[i]; + } else { + return null; + } + } + } else { + if (msg.paramsOut) { + if (i < msg.paramsOut.length) { + return null; + } else { + i -= msg.paramsOut.length; + } + } + if (msg.paramsIn) { + if (i < msg.paramsIn.length) { + return msg.paramsIn[i]; + } + } + } + return null; +} + +// +// reconstruct the direction of a parameter of a message by its position +// +function paramDirection(msg, name) { + var i = 0; + if (msg.paramsIn) { + for (i = 0; i < msg.paramsIn.length; i++) { + if (msg.paramsIn[i] == name) return true; + } + } + if (msg.paramsOut) { + for (i = 0; i < msg.paramsOut.length; i++) { + if (msg.paramsOut[i] == name) return false; + } + } + return false; +} + +function initCore() { + /* + Methods implementing messageIn of the core interfaces + In these methods, this is the message and args is the list of arguments of the message + widman.js, as the common part of all widget managers, does not implement these methods directly + but passes the buck to specific WM implementations. + In specific WM implementation, an initializer function should contain + WidgetManager.coreOutSetSize = function (...) {...}; + or similar. + */ + WidgetManager.coreOutSetSize = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.setSize" + argsString); + }; + + WidgetManager.coreOutShow = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.show" + argsString); + }; + + WidgetManager.coreOutHide = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.hide" + argsString); + }; + + WidgetManager.coreOutRequestActivate = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.requestActivate" + argsString); + }; + + WidgetManager.coreOutRequestDeactivate = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.requestDeactivate" + argsString); + }; + + WidgetManager.coreOutShowNotification = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.showNotification" + argsString); + }; + + WidgetManager.coreOutPlaceComponent = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.placeComponent" + argsString); + }; + + WidgetManager.coreOutGetAttention = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.getAttention" + argsString); + }; + WidgetManager.coreOutInstallWidget = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.installWidget" + argsString); + }; + WidgetManager.coreOutMigrateComponent = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.migrateComponent" + argsString); + }; + WidgetManager.coreOutRequestMigrationTargets = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.requestMigrationTargets" + argsString); + }; + WidgetManager.coreOutActivateTemporaryWidget = function(wid, args) { + var i = 0, argsString = ""; + for (; i < args.length; i++) argsString += " " + args[i]; + log(l_deb, "*** defCoreOutImpl.activateTemporaryWidget" + argsString); + }; + /* + Define the core:* interfaces that the widget manager implements and provides to widgets + The structure of messages is simplified. + messageIn have first an array of paramsIn, then an array of paramsOut for a reply + messageOut have first an array of paramsOut, then an array of paramsIn for reply + Because of this simplification, getParam and defineMessage are dependent on the direction of the message + The direction of a parameter is implicit in the fact that it is stored in paramsIn or paramsOut of the message + */ + coreIn = new Array(); + coreOut = new Array(); + coreIn[0] = defineMessage("setSize", true, null, defineParams("width", "height", "dpi")); + coreIn.setSizeMessage = coreIn[0]; + coreIn[1] = defineMessage("show", true, null); + coreIn.showMessage = coreIn[1]; + coreIn[2] = defineMessage("hide", true, null); + coreIn.hideMessage = coreIn[2]; + coreIn[3] = defineMessage("activate", true, null); + coreIn.activateMessage = coreIn[3]; + coreIn[4] = defineMessage("deactivate", true, null); + coreIn.deactivateMessage = coreIn[4]; + coreIn.type = "urn:mpeg:mpegu:schema:widgets:core:in:2010"; + coreOut[0] = defineMessage("setSize", false, coreOutSetSize, defineParams("width", "height")); + coreOut.setSizeMessage = coreOut[0]; + coreOut[1] = defineMessage("show", false, coreOutShow); + coreOut.showMessage = coreOut[1]; + coreOut[2] = defineMessage("hide", false, coreOutHide); + coreOut.hideMessage = coreOut[2]; + coreOut[3] = defineMessage("requestActivate", false, coreOutRequestActivate, null, + defineParams("returnCode")); + coreOut.requestActivateMessage = coreOut[3]; + coreOut[4] = defineMessage("requestDeactivate", false, coreOutRequestDeactivate, null, + defineParams("returnCode")); + coreOut.requestDeactivateMessage = coreOut[4]; + coreOut[5] = defineMessage("showNotification", false, coreOutShowNotification, + defineParams("message"), defineParams("returnCode")); + coreOut.showNotificationMessage = coreOut[5]; + coreOut[6] = defineMessage("placeComponent", false, coreOutPlaceComponent, + defineParams("componentID", "x", "y", "w", "h", "z-index", "transparency"), + defineParams("returnCode")); + coreOut.placeComponentMessage = coreOut[6]; + coreOut[7] = defineMessage("getAttention", false, coreOutGetAttention, + null, defineParams("returnCode")); + coreOut.getAttentionMessage = coreOut[7]; + coreOut[8] = defineMessage("installWidget", false, coreOutInstallWidget, + defineParams("url"), defineParams("returnCode")); + coreOut.installWidgetMessage = coreOut[8]; + coreOut[9] = defineMessage("migrateComponent", false, coreOutMigrateComponent, + defineParams("componentId", "targetCode"), defineParams("returnCode")); + coreOut.migrateComponentMessage = coreOut[9]; + coreOut[10] = defineMessage("requestMigrationTargets", false, coreOutRequestMigrationTargets, + null, defineParams("targetCodes", "targetNames", "targetDescriptions")); + coreOut.requestMigrationTargetsMessage = coreOut[10]; + coreOut[11] = defineMessage("activateTemporaryWidget", false, coreOutActivateTemporaryWidget, + defineParams("url"), defineParams("returnCode")); + coreOut.activateTemporaryWidget = coreOut[11]; + coreOut.type = "urn:mpeg:mpegu:schema:widgets:core:out:2010"; +} + +function coreOutRequestMigrationTargets(wid, args) { + WidgetManager.coreOutRequestMigrationTargets(wid, args); +} + +function coreOutSetSize(wid, args) { + WidgetManager.coreOutSetSize(wid, args); +} + +function coreOutShow(wid, args) { + WidgetManager.coreOutShow(wid, args); +} + +function coreOutHide(wid, args) { + WidgetManager.coreOutHide(wid, args); +} + +function coreOutRequestActivate(wid, args) { + WidgetManager.coreOutRequestActivate(wid, args); +} + +function coreOutRequestDeactivate(wid, args) { + WidgetManager.coreOutRequestDeactivate(wid, args); +} + +function coreOutShowNotification(wid, args) { + WidgetManager.coreOutShowNotification(wid, args); +} + +function coreOutPlaceComponent(wid, args) { + WidgetManager.coreOutPlaceComponent(wid, args); +} + +function coreOutGetAttention(wid, args) { + WidgetManager.coreOutGetAttention(wid, args); +} + +function coreOutInstallWidget(wid, args) { + WidgetManager.coreOutInstallWidget(wid, args); +} + +function coreOutActivateTemporaryWidget(wid, args) { + WidgetManager.coreOutActivateTemporaryWidget(wid, args); +} + +function coreOutMigrateComponent(wid, args) { + WidgetManager.coreOutMigrateComponent(wid, args); +} + +/* + Methods of binding and callback of core:* interfaces + */ +function wmjs_interface_invoke_callback_core(wid_src, ifce_dst, is_reply) { + log(l_inf, "wmjs_interface_invoke_callback_core '" + ifce_dst.type + "' - reply " + is_reply); + return function() { + var i, ai = 0, param_count, msgHandler, msg_src, msg_dst; + var args = new Array(); + msgHandler = arguments[0]; + /*get msg from source interface (this object)*/ + msg_src = this.get_message(msgHandler.msgName); + msg_dst = getMessage(ifce_dst, msgHandler.msgName); + //var argstring = ""; + //for (i = 0; i < msg_dst.num_params; i++) argstring += " "+getParam(msg_dst, i); + //log(l_inf, argstring); + //log(l_inf, (is_reply ? 'invokeReply ' : 'invoke ') + msg_src.name + ' on core.' + msg_dst.name + " nbpar:"+msg_src.num_params); + param_count = msg_src.num_params; + for (i = 0; i < param_count; i++) { + var param = getInputParam(msg_dst, i); + if (param == null) continue; + args[ai] = arguments[ai+1]; + ai++; + } + log(l_inf, (is_reply ? 'invokeReply ' : 'invoke ') + msg_src.name + ' on core.' + msg_dst.name + " nb:"+ai); + // call the method that implements the core:* message + msg_dst.execute(wid_src, args); + }; +} + +// function invokeReply for a reply from within a coreOut message +function wmjs_core_out_invoke_reply() { + var i, ai, param_count, is_script, msg_src, msg_dst, wid_dst; + var args = new Array(); + is_script = 0; + msg_src = arguments[0]; + msg_dst = arguments[1]; + wid_dst = arguments[2]; + log(l_inf, 'coreOut/invokeReply ' + msg_src.name + ' on core.' + msg_dst.name + ' to ' +wid_dst.name+ " nb:"+ai); + if (msg_dst.has_script_input) is_script = 1; + param_count = msg_src.num_params; + ai = 3; + for (i = 0; i < param_count; i++) { + var param = msg_dst.get_param(i); + if (! param.is_input) continue; + if (is_script) { + args[ai - 3] = arguments[ai]; + } else { + wid_dst.set_input(param, arguments[ai]); + } + ai++; + } + if (msg_dst.has_input_action) { + wid_dst.call_input_action(msg_dst); + } else if (is_script) { + wid_dst.call_input_script(msg_dst, args); + } +} + +// get an interface by type in WidgetManager, since getInterfaceHandlersByType is not accessible +function getInterfaceByType(widget, type) { + for (var i = 0; i < widget.num_interfaces; i++) { + var ifce = widget.get_interface(i); + if (ifce.type == type) return ifce; + } + return null; +} + +function wmjs_bind_interface_to_core_service(wid, ifce) { + if (ifce.type == "urn:mpeg:mpegu:schema:widgets:core:in:2010") { + // core:in + return wmjs_bind_interface_to_core_service1(wid, ifce, coreIn); + } else if (ifce.type == "urn:mpeg:mpegu:schema:widgets:core:out:2010") { + // core:out + return wmjs_bind_interface_to_core_service1(wid, ifce, coreOut); + } + // not an interface to core services + return false; +} + +function wmjs_bind_interface_to_core_service1(wid, ifce, core) { + // loop on the messages to check if they match + log(l_inf, 'Bind interface to core service ' + wid.name + " " + ifce.type); + var set_bind = 0, nb_ok, j, k, a_msg; + for (j = 0; j < ifce.num_messages; j++) { + var msg = ifce.get_message(j); + // does the other interface have this message + a_msg = getMessage(core, msg.name); + if (!a_msg) { + // no, it does not have this message, so leave + log(l_inf, 'No core message for ' + msg.name); + continue; + } + // the messages have matching names, check direction + if (msg.is_input == a_msg.is_input) { + log(l_inf, 'core message for ' + msg.name + ' is not in direction ' + (msg.is_input ? 'output' : 'input')); + continue; + } + // the messages have matching names and directions, check params + if (msg.num_params != a_msg.num_params) { + log(l_war, 'core message ' + msg.name + ' does not have the same number of parameters ' + + msg.num_params + ' ' + a_msg.num_params); + var paramstring = ""; + for (k = 0; k < msg.num_params; k++) { + par = msg.get_param(k); + paramstring += " " + par.name; + } + log(l_deb, paramstring); + continue; + } + /*check all params*/ + nb_ok = 0; + for (k = 0; k < msg.num_params; k++) { + par = msg.get_param(k); + //log(l_inf, " "+par.name+" "+hasParam(a_msg, par.name)+" "+par.is_input+" "+paramDirection(a_msg, par.name)); + if (hasParam(a_msg, par.name) != null && par.is_input != paramDirection(a_msg, par.name)) nb_ok ++; + } + if (nb_ok != msg.num_params) { + log(l_war, 'core message ' + msg.name + ' does not have the same input/output parameters '+nb_ok+" "+msg.num_params); + continue; + } + set_bind ++; + // the messages match + log(l_inf, 'Binding ' + wid.name + '.' + msg.name + ' to core.' + a_msg.name); + /*OK let's bind this action: we only need to assign the output trigger, the input + action will be called from the other widget*/ + if (msg.has_output_trigger) { + wid.bind_output_trigger(msg, wmjs_output_trigger_callback_core(msg, wid, a_msg), WidgetManager); + } + } + if (!set_bind) return false; + /*create callback for programmatic action triggers*/ + ifce.invoke = wmjs_interface_invoke_callback_core(wid, core, 0); + // ifce.invokeReply = wmjs_interface_invoke_callback_core(wid, core, 1); + wid.bind_interface(ifce, null, 'localhost'); + return true; +} + +function wmjs_output_trigger_callback_core(msg_out, wid_src, msg_in) { + log(l_deb, "wmjs_output_trigger_callback_core"); + return function() { + log(l_deb, "wmjs_output_trigger_callback_core/function '" + wid_src.name + "'"); + var param_count = msg_out.num_params; + var args = new Array(); + var ai = 0, i; + log(l_inf, 'Invoking Widget(' + wid_src.name + ').' + msg_out.name); + for (i = 0; i < param_count; i++) { + var param = msg_out.get_param(i); + if (param.is_input) continue; + args[ai] = wid_src.get_param_value(param); + ai++; + } + msg_in.execute(wid_src, args); + }; +} + + +// +// send a core:in message with no parameter +// +function wmjs_corein_message() +{ + if (arguments.length < 2) return; + var widget = arguments[0]; + var message = arguments[1]; + + for (var i=0; i=hw) || (2*ry>=hh)) rx = ry = 6; + + temp = this.geometry.point.point; + temp[0] = new SFVec2f(hw-rx, hh); + temp[1] = new SFVec2f(hw, hh);/*bezier ctrl point*/ + temp[2] = new SFVec2f(hw, hh-ry); + temp[3] = new SFVec2f(hw, -hh+ry); + temp[4] = new SFVec2f(hw, -hh);/*bezier control point*/ + temp[5] = new SFVec2f(hw-rx, -hh); + temp[6] = new SFVec2f(-hw+rx, -hh); + temp[7] = new SFVec2f(-hw, -hh);/*bezier control point*/ + temp[8] = new SFVec2f(-hw, -hh+ry); + temp[9] = new SFVec2f(-hw, hh-ry); + temp[10] = new SFVec2f(-hw, hh);/*bezier control point*/ + temp[11] = new SFVec2f(-hw+rx, hh); + } + obj.set_color = function(r, g, b) { + this.appearance.material.emissiveColor.r = r; + this.appearance.material.emissiveColor.g = g; + this.appearance.material.emissiveColor.b = b; + } + return obj; +} + +function icon_button(url, label, no_back) +{ + var obj = new SFNode('Transform2D'); + obj.children[0] = new SFNode('Transform2D'); + obj.children[0].scale.x = 0; + obj.children[0].children[0] = rectangle(); + + obj.children[1] = new SFNode('Layer2D'); + obj.children[1].size.x = icon_size; + obj.children[1].size.y = icon_size; + obj.children[1].children[0] = new SFNode('Inline'); + obj.children[1].children[0].url[0] = url; + + obj.touch = new SFNode('TouchSensor'); + obj.children[1].children[1] = obj.touch; + obj.button_click = NULL; + obj.down = false; + obj.over = false; + obj.on_active = function(value) { + if (value) { + this.down = true; + } else { + if (this.down && this.over && this.button_click) this.button_click(); + this.down = false; + } + }; + obj.button_over = on_icon_over; + obj.on_over = function(value) { + this.over = value; + if (!no_back) + this.children[0].scale.x = value ? 1 : 0; + if (this.button_over) this.button_over(value); + }; + Browser.addRoute(obj.touch, 'isOver', obj, obj.on_over); + Browser.addRoute(obj.touch, 'isActive', obj, obj.on_active); + obj.label = label; + obj.hide = function() { this.scale.x = this.scale.y = 0;}; + obj.show = function() { this.scale.x = this.scale.y = 1;}; + obj.set_size = function(x, y) { + this.children[0].children[0].set_size(x, y); + this.children[1].size.x = x; + this.children[1].size.y = y; + }; + return obj; +} + +function text_label(label, justify) +{ + var obj = new SFNode('Transform2D'); + obj.children[0] = new SFNode('Shape'); + obj.children[0].appearance = new SFNode('Appearance'); + obj.children[0].appearance.material = new SFNode('Material2D'); + obj.children[0].appearance.material.filled = TRUE; + obj.children[0].appearance.material.emissiveColor = new SFColor(0, 0, 0); + obj.children[0].geometry = new SFNode('Text'); + obj.children[0].geometry.string[0] = label; + obj.children[0].geometry.fontStyle = new SFNode('FontStyle'); + obj.children[0].geometry.fontStyle.justify[0] = justify; + obj.children[0].geometry.fontStyle.justify[1] = 'MIDDLE'; + obj.children[0].geometry.fontStyle.size = 20; + obj.set_label = function(value) { + this.children[0].geometry.string[0] = value; + } + return obj; +} + + +function text_rect(label) +{ + var obj = new SFNode('Transform2D'); + obj.children[0] = rectangle(); + obj.children[0].set_color(0.7, 0.7, 0.8); + + obj.children[1] = new SFNode('Shape'); + obj.children[1].appearance = new SFNode('Appearance'); + obj.children[1].appearance.material = new SFNode('Material2D'); + obj.children[1].appearance.material.filled = TRUE; + obj.children[1].appearance.material.emissiveColor = new SFColor(0, 0, 0); + obj.children[1].geometry = new SFNode('Text'); + obj.children[1].geometry.string[0] = label; + obj.children[1].geometry.fontStyle = new SFNode('FontStyle'); + obj.children[1].geometry.fontStyle.justify[0] = 'MIDDLE'; + obj.children[1].geometry.fontStyle.justify[1] = 'MIDDLE'; + obj.children[1].geometry.fontStyle.size = 20; + obj.children[2] = new SFNode('TouchSensor'); + + obj.set_size = function(w, h) { + this.children[0].set_size(w, h); + }; + + + obj.over = false; + obj.on_over = function(value) { + this.children[0].set_color(0.7, value ? 0.5 : 0.7, 0.8); + this.over = value; + }; + Browser.addRoute(obj.children[2], 'isOver', obj, obj.on_over); + + obj.down = false; + obj.button_click = null; + obj.on_active = function(value) { + if (value) { + this.down = true; + } else { + if (this.down && this.over && this.button_click) this.button_click(); + this.down = false; + } + }; + Browser.addRoute(obj.children[2], 'isActive', obj, obj.on_active); + + return obj; +} + +function new_widget_control(widget) +{ + var obj = new SFNode('Transform2D'); + + obj.children[0] = new SFNode('Transform2D'); + + obj.children[0].children[0] = rectangle(); + + obj.children[0].children[1] = new SFNode('TouchSensor'); + + + obj.component_bound=false; + obj.show_ctrl = true; + obj.onClick = function(value) { + if (!value) return; + this.show_ctrl = !this.show_ctrl; + if (this.show_ctrl) { + var i, comps, idx; + this.children[0].children[0].appearance.material.transparency = 0; + this.children[1].scale.x = 1; + this.children[3].scale.x = 1; + + for (i=0; i0) { + info.children[i++] = text_label(txt.substring(0, idx), 'BEGIN'); + txt = txt.substring(idx+1, txt.length); + } else { + info.children[i++] = text_label(txt, 'BEGIN'); + break; + } + } + + info_dlg.ifce_idx = info_dlg.children.length; + info = text_rect('Interfaces (count: ' + wid.num_interfaces + ' - bound: ' + wid.num_bound_interfaces+')', 'BEGIN'); + info_dlg.children[info_dlg.ifce_idx] = info; + info.visible = false; + info.button_click = function() { + this.visible = !this.visible; + layout(); + } + i=3; + for (j=0; jdisplay_width) { + start_x = (icon_size-display_width)/2; + } else { + start_x = (icon_size-tot_len)/2; + } + /*translate / size all items in the dock*/ + for (i=0;i0) { + first_visible_widget += nb_wid; + } + + for (i=0; i= count) { + break; + } + wid = widget_screen.children[i +first_visible_widget]; + wid.show(); + wid.set_size(icon_size, icon_size); + wid.translation.x = start_x; + wid.translation.y = start_y; + start_x += icon_size + spread_x; + if (start_x + icon_size / 2 >= display_width/2) { + start_x = (icon_size-display_width)/2 + spread_x/2; + start_y -= icon_size; + } + nb_widgets_on_screen = i+1; + if (start_y - icon_size < (dock_height-display_height)/2) { + i++; + break; + } + } +} + +//performs layout on all contents +function layout() { + var i, list, start_x; + + gpac.setOption('Widgets', 'LastWMWidth', ''+display_width); + gpac.setOption('Widgets', 'LastWMHeight', ''+display_height); + + + if (WidgetManager.num_widgets) { + dock.children[0].show(); + } else { + dock.children[0].hide(); + } + if (dlg_display.children.length) { + widget_display.scale.x = 0; + widget_screen_visible = false; + } + //layout all icons in the dock + dock_layout(); + widget_screen_layout(0); + + if (dlg_display.children.length) { + list = dlg_display.children; + for (i=0; i 0) { + break; + } + } + return icon; +} + +//initialize GPAC widget manager and load all widgets +function widgets_init() { + + count = WidgetManager.num_widgets; + for (i=0; i l_inf) { + var i = 0; + alert(">>>>>>>>>>>>> "+wid.name+" interfaces:"); + for (;i < wid.num_interfaces; i++) { + alert(""+wid.get_interface(i).type); + } + } + // +} + + +//core out install widget implementation JCD +function widget_install_widget(widget, args) +{ + var uri = args[0], j; + var count = WidgetManager.num_widgets; + for (j=0; j 1 && args[1] != null) { + var render = UPnP.GetMediaRenderer(parseInt(args[1])); + WidgetManager.migrate_widget(render, widget_remote_candidate); + widget_close(widget_remote_candidate, 0); + widget_remote_candidate = null; + } else { + on_upnpopen(); + } + } +} + +// core out request migration targets JCD +function widget_request_migration_targets(wid, args) +{ + var count = UPnP.MediaRenderersCount, codes = new Array(), names = new Array(), descriptions = new Array(), i; + for (i = 0; i < count; i++) { + var render = UPnP.GetMediaRenderer(i); + codes.push(""+i); + names.push(render.Name); + descriptions.push(render.HostName +" "+ render.UUID); + } + i = null; + var ifce_count = wid.num_interfaces, j; + for (j = 0; j < ifce_count; j++) { + var ifce = wid.get_interface(j); + if (ifce.type == "urn:mpeg:mpegu:schema:widgets:core:out:2010") { + i = ifce; + break; + } + } + if (i != null) { + wmjs_core_out_invoke_reply(coreOut.requestMigrationTargetsMessage, i.get_message("requestMigrationTargets"), + wid, codes, names, descriptions); + } + +} + +function widget_request_size(widget, args) +{ + if (args.length==2) { + w = (typeof args[0] == 'string') ? parseInt(args[0]) : args[0]; + h = (typeof args[1] == 'string') ? parseInt(args[1]) : args[1]; + widget.widget_control.set_size(w, h); + } +} + +function widget_request_show(widget, args) +{ + widget.widget_control.show(); +} + +function widget_request_hide(widget, args) +{ + widget.widget_control.hide(); +} + +function widget_request_activate(widget, args) +{ + if (!widget.visible) + widget_launch(widget); +} + +function widget_request_deactivate(widget, args) +{ + if (widget.visible) + widget_close(widget, 0); +} + +function widget_request_attention(widget, args) +{ + if (widget.visible) { + widget_display.removeChildren[0] = widget.widget_control; + widget_display.addChildren[0] = widget.widget_control; + widget.widget_control.flash(); + } +} + +function widget_request_notification(widget, args) +{ + var notif = text_rect(''); + notif.children[1].geometry.string[0] = 'Notification from widget'; + notif.children[1].geometry.string[1] = ' '+widget.name; + notif.children[1].geometry.string[2] = ' '; + notif.children[1].geometry.string[3] = args[0]; + dlg_display.children[0] = notif; + notif.set_size(320, 240); + notif.button_click = function() { + dlg_display.removeChildren[0] = this; + } +} + +function widget_place_component(widget, args) +{ + var comp = widget.get_component(args[0]); + + if (comp==null) { + log(l_err, 'Component '+args[0]+' cannot be found in widget '+widget.name); + return; + } + comp.widget_control.place_x = args[1]; + comp.widget_control.place_y = args[2]; + comp.widget_control.place_w = args[3]; + comp.widget_control.place_h = args[4]; + comp.widget_control.place_z = args[5]; + comp.widget_control.component_bound = true; + widget.widget_control.refresh_layout(false, comp); +} + + + +function insert_widget_icon(new_wid, no_layout) { + var icon; + icon = icon_button(widget_get_icon(new_wid), new_wid.name, 0); + icon.tooltip = new_wid.name; + new_wid.in_panel = true; + new_wid.visible = false; + new_wid.icon_dock = icon; + icon.button_click = on_widget_launch; + icon.widget = new_wid; + widget_screen.addChildren[0] = new_wid.icon_dock; + if (!no_layout) layout(); +} + +function scan_directory(dir) +{ + var i, j, count, list, new_wid, uri; + list = gpac.enum_directory(dir, '.xml;.wgt;.mgt', 0); + for (i=0; i this.list.length) this.first = this.list.length - this.nb_items; + } + if (this.first) this.children[1].show(); + if (this.first+this.nb_items < this.list.length) this.children[2].show(); + + for (i=0; i=this.list.length) break; + item = text_rect(this.list[i+this.first].name); + item.path = this.list[i+this.first].path; + item.name = this.list[i+this.first].name; + item.directory = this.list[i+this.first].directory; + item.filebrowse = this; + item.button_click = function() { + if (this.directory) { + this.filebrowse.directory = this.path + this.name; + this.filebrowse.browse(false); + } else { + var value = this.path + this.name; + dlg_display.children.length = 0; + widget_display.scale.x = 1; + widget_screen_visible = true; + layout(); + + var new_wid = WidgetManager.open(value, null); + if (new_wid==null) return; + + WidgetManager.last_widget_dir = this.filebrowse.directory; + insert_widget_icon(new_wid, 0); + } + } + this.children[this.nb_tools+i] = item; + } + this.set_size(this.width, this.height); + } + + + filebrowse.set_size = function(w, h) { + var i, x, y, isize, nbi; + isize = 24; + if (w>display_width - isize) w = display_width - isize; + + this.width = w; + this.height = h; + + i = 1; + while ((i+1)*isize <= h - isize) i++; + + if (i != this.nb_items) { + this.nb_items = i; + this.layout(0); + return; + } + x = -w/2 + isize/2; + y = h/2 - isize/2; + + for (i=0;ii+1) { + this.children[i].set_size(isize, isize); + } + this.children[i].translation.x = x; + this.children[i].translation.y = y; + x += isize; + } + y-=isize; + while (ithis.nb_items) count = this.nb_items-1; + + item = text_rect('Close'); + item.button_click = function() { + dlg_display.children.length = 0; + upnp_renders=null; + widget_display.scale.x = 1; + infobar.set_label(''); + } + this.children[this.children.length] = item; + + for (i=0; i + + + +
      +
      + + + + + + + + + + + + + + + + + + + + + +
      diff --git a/gui/tv_wm_gui.js b/gui/tv_wm_gui.js new file mode 100644 index 0000000..15bfe6e --- /dev/null +++ b/gui/tv_wm_gui.js @@ -0,0 +1,485 @@ +var movie1 = "../widgets/media/local_video/movies/Clovis Cornillac.mp4"; +var movie2 = "../widgets/media/local_video/movies/Airheads2001_edit.mp4"; +var movie3 = "../widgets/media/local_video/movies/CH Video - Alberto Alessi.mp4"; +var movie4 = "../widgets/media/local_video/movies/Crossing2001_edit.mp4"; +var movie5 = "../widgets/media/local_video/movies/EnemyAtT2001_512kb.mp4"; +var movie6 = "../widgets/media/local_video/movies/KAMI2001_512kb.mp4"; +var movie7 = "../widgets/media/local_video/movies/PipeDrea2001_512kb.mp4"; +var movie8 = "../widgets/media/local_video/movies/LAUTRETE2001_512kb.mp4"; +var movie9 = "../widgets/media/local_video/movies/Unexpect2001_512kb.mp4"; +var movie0 = "../widgets/media/local_video/movies/Animatrix_The_Second_Renaissance_l.mp4"; + +var xlinkns = 'http://www.w3.org/1999/xlink'; + +/* override the print function to use SVG alert */ +print = alert; + +/******************************************************************************* + *Global elements referenced in this script + ******************************************************************************/ + +/* Root of the SVG document presenting the widgets, the dock ...*/ +var root; +/* The dock element presents the widget icons or simplified representations */ +var dock; +/* The movie element presents the media content, widgets are added on top of it */ +var movie; +/* The widget_display element contains the full representation of all activated widgets, it is on top of the movie element */ +var widget_display; +/* The display element contains things to be displayed on top of the widgets */ +var display; + + +function create_icon(url, short_name) { + var icon_g; + icon_g = document.createElement('g'); + icon_g.short_name = short_name; + + var back_rect; + back_rect = document.createElement('rect'); + back_rect.setAttribute('fill', 'url(#inactiveGradient)'); + back_rect.setAttribute('rx', 5); + back_rect.setAttribute('stroke', 'black'); + back_rect.setAttribute('stroke-width', 1); + icon_g.appendChild(back_rect); + + var icon; + icon = document.createElement('animation'); + icon.setAttributeNS(xlinkns ,'href', url); + icon_g.appendChild(icon); + + var text; + text = document.createElement('textArea'); + text.setAttribute('fill', 'white'); + text.textContent = short_name; + icon_g.appendChild(text); + + return icon_g; +} + +function set_icon_active(icon, value) { + var back_rect; + back_rect = icon.firstElementChild; + if (!value) back_rect.setAttribute('fill', 'url(#inactiveGradient)'); + else back_rect.setAttribute('fill', 'url(#activeGradient)'); +} + +function set_icon_visible(icon, value) { + if (value) icon.setAttribute('display', 'inline'); + else icon.setAttribute('display', 'none'); +} + +function set_icon_position(icon, x, y) { + icon.setAttribute('transform', 'translate('+x+','+y+')'); +} + +function set_icon_size(icon, w, h) { + var back_rect = icon.firstElementChild; + back_rect.setAttribute('width', w); + back_rect.setAttribute('height', h); + + var anim = back_rect.nextElementSibling; + anim.setAttribute('x', 5*w/8); + anim.setAttribute('y', -10); + anim.setAttribute('width', 1.2*h); + anim.setAttribute('height', 1.2*h); + + var tA = anim.nextElementSibling; + tA.setAttribute('x', icon_spacing); + tA.setAttribute('y', 5); + tA.setAttribute('height', h); + if (w > 100) { + tA.setAttribute('font-size', h/3); + tA.setAttribute('width', w/1.8); + } else { + tA.setAttribute('font-size', h/5); + tA.setAttribute('width', 4*w/8); + } +} + +function add_widget_to_dock(wid) { + var wid_icon_url = null; + var icon; + var preferredIconType = '.svg'; + for (var i = 0; i < wid.icons.length; i++) { + wid_icon_url = wid.icons[i].relocated_src; + if (wid.icons[i].relocated_src.indexOf(preferredIconType) > 0) { + break; + } + } + if (wid_icon_url == null) wid_icon_url = 'icons\\applications-system.svg'; + //alert(wid_icon_url); + icon = create_icon(wid_icon_url, wid.name); + icon.widget = wid; + set_icon_visible(icon, false); + dock.appendChild(icon); + wid.icon_dock = icon; +} + + +function resize() { + /*dummy values, assign upon window resize event*/ + alert('Size:'+root.viewport.width+'x'+root.viewport.height); + display_width = root.viewport.width;//gpac.get_screen_width(); + display_height = root.viewport.height;//gpac.get_screen_height(); + + nb_icon_max = 4; + if (display_width > 800) { + out_spacing = 30; + icon_spacing = 10; + } else { + out_spacing = 10; + icon_spacing = 4; + } + dock_width = display_width; + icon_width = (dock_width-((nb_icon_max-1)*icon_spacing+2*out_spacing))/nb_icon_max; + + dock_height = display_height/10; + icon_height = dock_height+4; + + movie.setAttribute('width', display_width); + if (is_dock_visible) { + movie.setAttribute('height', display_height - dock_height); + } else { + movie.setAttribute('height', display_height); + } + + dock.setAttribute('transform', 'translate(0, '+(display_height-dock_height)+')'); + + var dock_back = dock.firstElementChild.firstElementChild; + dock_back.setAttribute('x', 0); + dock_back.setAttribute('y', 0); + dock_back.setAttribute('height', dock_height); + dock_back.setAttribute('width', dock_width); + + var left_arrow = dock_back.nextElementSibling; + left_arrow.setAttribute('x', 0); + left_arrow.setAttribute('y', 0); + left_arrow.setAttribute('height', dock_height - 5); + left_arrow.setAttribute('width', out_spacing); + + var right_arrow = left_arrow.nextElementSibling; + right_arrow.setAttribute('x', dock_width-out_spacing); + right_arrow.setAttribute('y', 0); + right_arrow.setAttribute('height', dock_height-5); + right_arrow.setAttribute('width', out_spacing); + + dock_layout(); + alert('ok'); +} + +/******************************************************************************* + * Global Initialization function, called when the SVG document is loaded + * Initializes global variables (elements) + * Finds the available widgets and add them to the dock + ******************************************************************************/ +function initialize() { + /* root of the SVG document presenting the widgets, the dock ...*/ + root = document.documentElement; + + /* The dock presents the widget icons or simplified representations */ + dock = document.getElementById('dock'); + + /* The movie element presents the media content, widgets are added on top of it */ + movie = document.getElementById('movie'); + + /* The widget display element contains the full representation of all activated widgets, it is on top of the movie_inline element */ + widget_display = document.getElementById('widget_display'); + + /* The display element contains things to be displayed on top of the widgets */ + display = document.getElementById('display'); + + is_dock_visible = false; + if (!is_dock_visible) dock.setAttribute('display', 'none'); + + activate = new Array(); + selected_widget_index = 0; + first_displayed_widget_index = 0; + nb_widgets_visible = 0; + current_widget_pos = 0; + next_widget_pos = 0; + vertical_spacing = 10; + vertical_offset = 0; + + /* if the WidgetManager object is not defined (this is a GPAC extension), we define a dummy one to enable debugging in Opera for example */ + if (typeof WidgetManager == 'undefined') { + WidgetManager = new Object; + WidgetManager.initialize = function () {} + WidgetManager.num_widgets = 8; + WidgetManager.get = function(i) { + var wid = new Object; + if (i < 2) { + wid.icon = 'widgets/clock/appointment-new.svg'; + wid.main = 'widgets/clock/appointment-new.svg'; + wid.name = 'Clock'; + wid.visible = false; + wid.x = 0; + wid.y = 0; + wid.width = 100; + wid.height = 100; + } else { + wid.icon = 'icons/audio-volume-high.svg'; + wid.main = 'icons/audio-volume-high.svg'; + wid.name = 'Music'; + wid.visible = false; + wid.x = 0; + wid.y = 0; + wid.width = 100; + wid.height = 100; + } + return wid; + } + WidgetManager.unload = function (wid) {} + } + + /* Setup the GPAC Widget Manager - this will also scan the available widgets */ + widget_manager_init(); + + /* scan all the widgets from the widget manager, create an iconic view, set its size, add it to the dock element but make it invisible */ + var i; + nb_widgets = WidgetManager.num_widgets; + for (i=0; i= (first_displayed_widget_index+nb_icon_max)) { + set_icon_visible(child, false); + alert('setting child '+i+' invisible'+(i == selected_widget_index ? '*' :' ')+ ' '+child.getAttribute('transform')); + } else { + var offset_x = start_x + (i-first_displayed_widget_index)*(icon_width+icon_spacing); + set_icon_visible(child, true); + if (i == selected_widget_index) set_icon_active(child, true); + else set_icon_active(child, false); + set_icon_size(child, icon_width, icon_height); + set_icon_position(child, offset_x, dock_height-icon_height); +// alert('setting child '+i+' visible'+(i == selected_widget_index ? '*' :' ')+ ' '+child.getAttribute('transform')); + } + child = child.nextElementSibling; + i++; + } +} + +function focusNextWidget() { + alert('next'); + if (selected_widget_index < nb_widgets - 1) selected_widget_index++; + if (selected_widget_index > first_displayed_widget_index + nb_icon_max -1 && first_displayed_widget_index + nb_icon_max < nb_widgets) first_displayed_widget_index++; + dock_layout(); +} + +function focusPrevWidget() { + alert('prev'); + if (selected_widget_index > 0) selected_widget_index--; + if (first_displayed_widget_index > selected_widget_index && first_displayed_widget_index > 0) first_displayed_widget_index--; + + dock_layout(); +} + +function on_key_up(evt) { + alert(evt.keyIdentifier + ' released '+evt.keyCode); + if (evt.keyIdentifier == 'Right' || evt.keyCode == 39) { + focusNextWidget(); + } else if (evt.keyIdentifier == 'Left' || evt.keyCode == 37) { + focusPrevWidget(); + } else if (evt.keyIdentifier == 'Up') { + vertical_offset += root.viewport.width / 3; + widget_display.setAttribute('transform', 'translate(0,'+vertical_offset+')'); + } else if (evt.keyIdentifier == 'Down') { + vertical_offset -= root.viewport.width / 3; + widget_display.setAttribute('transform', 'translate(0,'+vertical_offset+')'); + } else if (evt.keyIdentifier == 'Enter') { + if (is_dock_visible) { + if (activate[selected_widget_index]) { + widget_launch(WidgetManager.get(selected_widget_index), widget_display); + activate[selected_widget_index] = false; + nb_widgets_visible++; + if (nb_widgets_visible == 1) { + } + } else { + widget_close(WidgetManager.get(selected_widget_index)); + activate[selected_widget_index] = true; + nb_widgets_visible--; + if (nb_widgets_visible == 0) { + + } + } + } + } else if (evt.keyIdentifier == 'F1') { + dock_toggle_visible(); + } else if (evt.keyIdentifier == 'U+0030') { + movie.setAttributeNS(xlinkns, 'href', movie0); + } else if (evt.keyIdentifier == 'U+0031') { + movie.setAttributeNS(xlinkns, 'href', movie1); + } else if (evt.keyIdentifier == 'U+0032') { + movie.setAttributeNS(xlinkns, 'href', movie2); + } else if (evt.keyIdentifier == 'U+0033') { + movie.setAttributeNS(xlinkns, 'href', movie3); + } else if (evt.keyIdentifier == 'U+0034') { + movie.setAttributeNS(xlinkns, 'href', movie4); + } else if (evt.keyIdentifier == 'U+0035') { + movie.setAttributeNS(xlinkns, 'href', movie5); + } else if (evt.keyIdentifier == 'U+0036') { + movie.setAttributeNS(xlinkns, 'href', movie6); + } else if (evt.keyIdentifier == 'U+0037') { + movie.setAttributeNS(xlinkns, 'href', movie7); + } else if (evt.keyIdentifier == 'U+0038') { + movie.setAttributeNS(xlinkns, 'href', movie8); + } else if (evt.keyIdentifier == 'U+0039') { + movie.setAttributeNS(xlinkns, 'href', movie9); + } +} + +function widget_close(widget) { + alert('widget_close:'+widget.name); + if (typeof widget.deactivate != 'undefined') { + widget.deactivate(); + } else { + wid.visible = false; + } + next_widget_pos -= widget.height + vertical_spacing; + widget.scene_container.removeChild(widget.widget_control); + /*force disconnect of main resource - we do this because we are not sure when the widget_control will be destroyed due to JS GC*/ + widget.widget_control.firstElementChild.setAttributeNS(xlinkns, 'href', ''); + //widget.widget_control.firstElementChild.removeAttributeNS(xlinkns, 'href'); +} + +/* todo ...*/ +function widget_remove(wid) +{ + WidgetManager.unload(wid); +} + +/* Function that starts to present the Widget Full representation */ +function widget_launch(wid, scene_container) { + alert('widget_launch:'+wid.name); + + var widg_ctrl, anim; + + //assign default size to the widget + wid.width = root.viewport.width / 3; + wid.height = root.viewport.width / 3; + + var w = wid.width; + var h = wid.height; + alert('w '+w + ' h '+h); + + widg_ctrl = document.createElement('g'); + widg_ctrl.wid = wid; +// widg_ctrl.setAttribute('transform', 'translate('+(nb_widgets_visible>=2?600:0)+','+400*nb_widgets_visible+')'); +// var y = (nb_widgets_visible%2)*310; +// var x = ((nb_widgets_visible - nb_widgets_visible%2)/2*310); + var x = 0; + var y = next_widget_pos; + next_widget_pos += h+vertical_spacing; + + alert('x:'+x+', y:' +y); + widg_ctrl.setAttribute('transform', 'translate('+x+','+y+')'); + + anim = document.createElement('animation'); + anim.setAttributeNS(xlinkns, 'href', wid.main); + anim.setAttribute('width', w); + anim.setAttribute('height', h); + anim.setAttribute('preserveAspectRatio', 'xMidYMid'); + + widg_ctrl.appendChild(anim); + + wid.widget_control = widg_ctrl; + wid.scene_container = scene_container; + /*this will setup the scene graph for the widget in order to filter input and output communication pins*/ + wid.on_load = function() { + alert('wid.on_load:'+this.name); + WidgetManager.bind(this); + } + wid.activate(anim); + scene_container.appendChild(widg_ctrl); +} + +function dock_toggle_visible() { + if (is_dock_visible) { + dock.setAttribute('display', 'none'); + movie.setAttribute('height', display_height); + is_dock_visible = false; + } else { + dock.setAttribute('display', 'inline'); + is_dock_visible = true; + movie.setAttribute('height', display_height - dock_height); + } +} + + +function onMediaConnect(url, src_ip) +{ + alert('onMediaConnect :\"'+url+'\"'); + + if (WidgetManager.probe(url) ) { + var new_wid = WidgetManager.open(url, src_ip); + if (new_wid==null) return; + + add_widget_to_dock(new_wid); + for (var i = nb_widgets; i < WidgetManager.num_widgets; i++) { + activate[i] = true; + } + nb_widgets = WidgetManager.num_widgets; + dock_layout(); + } else { + alert('invalid widget extension'); + /* TODO if this is not a widget url, we should probably change the movie being played */ + } +} + +function onMediaStop() +{ + alert('Media Stop'); + movie.endElement(); +} +function onMediaPause() +{ + alert('Media pause'); + movie.pauseElement(); +} +function onMediaPlay() +{ + alert('Media Play'); + movie.resumeElement(); +} diff --git a/gui/tv_wm_gui.svg b/gui/tv_wm_gui.svg new file mode 100644 index 0000000..bc834b6 --- /dev/null +++ b/gui/tv_wm_gui.svg @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + initialize(); + resize(); + diff --git a/include/gpac/avparse.h b/include/gpac/avparse.h index 530882c..5b08a75 100644 --- a/include/gpac/avparse.h +++ b/include/gpac/avparse.h @@ -53,20 +53,20 @@ typedef struct typedef struct __tag_m4v_parser GF_M4VParser; -GF_M4VParser *gf_m4v_parser_new(char *data, u32 data_size, Bool mpeg12video); +#ifndef GPAC_DISABLE_AV_PARSERS + +GF_M4VParser *gf_m4v_parser_new(char *data, u64 data_size, Bool mpeg12video); GF_M4VParser *gf_m4v_parser_bs_new(GF_BitStream *bs, Bool mpeg12video); void gf_m4v_parser_del(GF_M4VParser *m4v); GF_Err gf_m4v_parse_config(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi); /*get a frame (can contain GOP). The parser ALWAYS resync on the next object in the bitstream thus you can seek the bitstream to copy the payload without re-seeking it */ -GF_Err gf_m4v_parse_frame(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u32 *size, u32 *start, Bool *is_coded); +GF_Err gf_m4v_parse_frame(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded); /*returns current object start in bitstream*/ -u32 gf_m4v_get_object_start(GF_M4VParser *m4v); +u64 gf_m4v_get_object_start(GF_M4VParser *m4v); /*returns 1 if current object is a valid MPEG-4 Visual object*/ Bool gf_m4v_is_valid_object_type(GF_M4VParser *m4v); -/*returns readable description of profile*/ -const char *gf_m4v_get_profile_name(u8 video_pl); /*decodes DSI*/ GF_Err gf_m4v_get_config(char *rawdsi, u32 rawdsi_size, GF_M4VDecSpecInfo *dsi); /*rewrites PL code in DSI*/ @@ -74,6 +74,19 @@ void gf_m4v_rewrite_pl(char **io_dsi, u32 *io_dsi_len, u8 PL); /*rewrites PAR code in DSI. Negative values will remove the par*/ GF_Err gf_m4v_rewrite_par(char **o_data, u32 *o_dataLen, s32 par_n, s32 par_d); +#endif /*GPAC_DISABLE_AV_PARSERS*/ + +/*returns readable description of profile*/ +const char *gf_m4v_get_profile_name(u8 video_pl); + +#ifndef GPAC_DISABLE_AV_PARSERS +s32 gf_mv12_next_start_code(unsigned char *pbuffer, u32 buflen, u32 *optr, u32 *scode); +s32 gf_mv12_next_slice_start(unsigned char *pbuffer, u32 startoffset, u32 buflen, u32 *slice_offset); + +#endif /* GPAC_DISABLE_AV_PARSERS*/ + +#ifndef GPAC_DISABLE_AV_PARSERS + /*MP3 tools*/ u8 gf_mp3_num_channels(u32 hdr); u16 gf_mp3_sampling_rate(u32 hdr); @@ -81,12 +94,19 @@ u16 gf_mp3_window_size(u32 hdr); u16 gf_mp3_bit_rate(u32 hdr); u8 gf_mp3_object_type_indication(u32 hdr); u8 gf_mp3_layer(u32 hdr); -u8 gf_mp3_version(u32 hdr); -const char *gf_mp3_version_name(u32 hdr); u16 gf_mp3_frame_size(u32 hdr); u32 gf_mp3_get_next_header(FILE* in); u32 gf_mp3_get_next_header_mem(char *buffer, u32 size, u32 *pos); +#endif /*GPAC_DISABLE_AV_PARSERS*/ + +u8 gf_mp3_version(u32 hdr); +const char *gf_mp3_version_name(u32 hdr); + + + +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined (GPAC_DISABLE_OGG) + /*vorbis tools*/ typedef struct { @@ -107,6 +127,8 @@ Bool gf_vorbis_parse_header(GF_VorbisParser *vp, char *data, u32 data_len); in this frame*/ u32 gf_vorbis_check_frame(GF_VorbisParser *vp, char *data, u32 data_length); +#endif /*!defined(GPAC_DISABLE_AV_PARSERS) && !defined (GPAC_DISABLE_OGG)*/ + enum { @@ -135,14 +157,16 @@ enum GF_M4A_ER_HILN = 26, GF_M4A_ER_PARAMETRIC = 27, GF_M4A_SSC = 28, - //GF_M4A_PS = 29, + GF_M4A_AAC_PS = 29, GF_M4A_LAYER1 = 32, GF_M4A_LAYER2 = 33, GF_M4A_LAYER3 = 34, GF_M4A_DST = 35, - GF_M4A_ALS = 36, + GF_M4A_ALS = 36 }; +#ifndef GPAC_DISABLE_AV_PARSERS + static const u32 GF_M4ASampleRates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, @@ -157,6 +181,8 @@ typedef struct /*SBR*/ Bool has_sbr; u32 sbr_object_type, sbr_sr, sbr_sr_index; + /*PS*/ + Bool has_ps; /*PL indication*/ u8 audioPL; } GF_M4ADecSpecInfo; @@ -164,12 +190,19 @@ typedef struct GF_Err gf_m4a_get_config(char *dsi, u32 dsi_size, GF_M4ADecSpecInfo *cfg); /*gets audioPL for given cfg*/ u32 gf_m4a_get_profile(GF_M4ADecSpecInfo *cfg); -const char *gf_m4a_object_type_name(u32 objectType); -const char *gf_m4a_get_profile_name(u8 audio_pl); GF_Err gf_m4a_write_config(GF_M4ADecSpecInfo *cfg, char **dsi, u32 *dsi_size); +GF_Err gf_m4a_write_config_bs(GF_BitStream *bs, GF_M4ADecSpecInfo *cfg); GF_Err gf_m4a_parse_config(GF_BitStream *bs, GF_M4ADecSpecInfo *cfg, Bool size_known); +#endif /*GPAC_DISABLE_AV_PARSERS*/ + +const char *gf_m4a_object_type_name(u32 objectType); +const char *gf_m4a_get_profile_name(u8 audio_pl); + +#ifndef GPAC_DISABLE_AV_PARSERS + + typedef struct { u32 bitrate; @@ -182,12 +215,15 @@ typedef struct Bool gf_ac3_parser(u8 *buffer, u32 buffer_size, u32 *pos, GF_AC3Header *out_hdr, Bool full_parse); Bool gf_ac3_parser_bs(GF_BitStream *bs, GF_AC3Header *hdr, Bool full_parse); - +u32 gf_ac3_get_channels(u32 acmod); +u32 gf_ac3_get_bitrate(u32 brcode); GF_Err gf_avc_get_sps_info(char *sps, u32 sps_size, u32 *width, u32 *height, s32 *par_n, s32 *par_d); - const char *gf_avc_get_profile_name(u8 video_prof); +#endif /*GPAC_DISABLE_AV_PARSERS*/ + + /*gets image size (bs must contain the whole image) @OTI: image type (JPEG=0x6C, PNG=0x6D) @@ -197,7 +233,8 @@ void gf_img_parse(GF_BitStream *bs, u8 *OTI, u32 *mtype, u32 *width, u32 *height GF_Err gf_img_jpeg_dec(char *jpg, u32 jpg_size, u32 *width, u32 *height, u32 *pixel_format, char *dst, u32 *dst_size, u32 dst_nb_comp); GF_Err gf_img_png_dec(char *png, u32 png_size, u32 *width, u32 *height, u32 *pixel_format, char *dst, u32 *dst_size); -GF_Err gf_img_png_enc(char *data, u32 width, u32 height, u32 pixel_format, char *dst, u32 *dst_size); +GF_Err gf_img_png_file_dec(char *png_file, u32 *width, u32 *height, u32 *pixel_format, char **dst, u32 *dst_size); +GF_Err gf_img_png_enc(char *data, u32 width, u32 height, s32 stride, u32 pixel_format, char *dst, u32 *dst_size); #ifdef __cplusplus } diff --git a/include/gpac/bifs.h b/include/gpac/bifs.h index f818295..fac6640 100644 --- a/include/gpac/bifs.h +++ b/include/gpac/bifs.h @@ -34,6 +34,9 @@ extern "C" { /*for BIFSConfig*/ #include +#ifndef GPAC_DISABLE_BIFS + + typedef struct __tag_bifs_dec GF_BifsDecoder; /*BIFS decoder constructor - @@ -42,6 +45,9 @@ typedef struct __tag_bifs_dec GF_BifsDecoder; GF_BifsDecoder *gf_bifs_decoder_new(GF_SceneGraph *scenegraph, Bool command_dec); void gf_bifs_decoder_del(GF_BifsDecoder *codec); +/*assigns extraction path for BIFS decoder - default is current directory*/ +void gf_bifs_decoder_set_extraction_path(GF_BifsDecoder *codec, const char *path, const char *serviceURL); + /*sets the scene time. Scene time is the real clock of the bifs stream in secs*/ void gf_bifs_decoder_set_time_offset(GF_BifsDecoder *codec, Double ts); @@ -64,6 +70,7 @@ GF_Err gf_bifs_decode_au(GF_BifsDecoder *codec, u16 ESID, char *data, u32 data_l GF_Err gf_bifs_decode_command_list(GF_BifsDecoder *codec, u16 ESID, char *data, u32 data_length, GF_List *com_list); +#ifndef GPAC_DISABLE_BIFS_ENC /*BIFS encoding*/ typedef struct __tag_bifs_enc GF_BifsEncoder; @@ -85,11 +92,13 @@ u8 gf_bifs_encoder_get_version(GF_BifsEncoder *codec, u16 ESID); /*Encodes current graph as a scene replace*/ GF_Err gf_bifs_encoder_get_rap(GF_BifsEncoder *codec, char **out_data, u32 *out_data_length); +#endif /*GPAC_DISABLE_BIFS_ENC*/ + +#endif /*GPAC_DISABLE_BIFS*/ + #ifdef __cplusplus } #endif - - #endif /*_GF_BIFS_H_*/ diff --git a/include/gpac/bifsengine.h b/include/gpac/bifsengine.h deleted file mode 100644 index 69e1769..0000000 --- a/include/gpac/bifsengine.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * GPAC Multimedia Framework - * - * Authors: Cyril Concolato - Jean le Feuvre - * Copyright (c) 2005-200X ENST - * 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. - * - */ - - -#ifndef _GF_BIFSENGINE_H_ -#define _GF_BIFSENGINE_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -#ifndef GPAC_READ_ONLY - -typedef struct __tag_bifs_engine GF_BifsEngine; - -/** - * @calling_object is the calling object on which call back will be called - * @inputContext is the name of a scene file (bt, xmt or mp4) to initialize the coding context - * - * must be called only one time (by process calling the DLL) before other calls - */ -GF_BifsEngine *gf_beng_init(void *calling_object, char *inputContext); - -/** - * @calling_object is the calling object on which call back will be called - * @inputContext is an UTF-8 scene description (with or without IOD) in BT or XMT-A format - * @width, @height: width and height of scene if no IOD is given in the context. - * @usePixelMetrics: metrics system used in the scene, if no IOD is given in the context. - * - * must be called only one time (by process calling the DLL) before other calls - */ -GF_BifsEngine *gf_beng_init_from_string(void *calling_object, char *inputContext, u32 width, u32 height, Bool usePixelMetrics); - - -/** - * @calling_object is the calling object on which call back will be called - * @ctx is an already loaded scene manager - * - * must be called only one time (by process calling the DLL) before other calls - */ -GF_BifsEngine *gf_beng_init_from_context(void *calling_object, GF_SceneManager *ctx); - -/** - * @beng, pointer to the GF_BifsEngine returned by BENC_Init - * @config: pointer to the encoded BIFS config (memory is not allocated) - * @config_len: length of the buffer - * - * must be called after BENC_Init - */ -void gf_beng_get_stream_config(GF_BifsEngine *beng, char **config, u32 *config_len); - -/** - * Encodes the AU context which is not encoded when calling BENC_EncodeAUFromString/File - * Should be called after Aggregate. - * - * @beng, pointer to the GF_BifsEngine returned by BENC_Init - * @AUCallback, pointer on a callback function to get the result of the coding the AU using the current context - * - */ -GF_Err gf_beng_encode_context(GF_BifsEngine *beng, GF_Err (*AUCallback)(void *, char *data, u32 size, u64 ts)); - -/** - * @beng, pointer to the GF_BifsEngine returned by BENC_Init - * @auFile, name of a file containing a description for an access unit (BT or XMT) - * @AUCallback, pointer on a callback function to get the result of the coding the AU using the current context - * - */ -GF_Err gf_beng_encode_from_file(GF_BifsEngine *beng, char *auFile, GF_Err (*AUCallback)(void *, char *data, u32 size, u64 ts)); - -/** - * @beng, pointer to the GF_BifsEngine returned by BENC_Init - * @auString, a char string to encode (must one or several complete nodes in BT - * @AUCallback, pointer on a callback function to get the result of the coding the AU using the current context - * - */ -GF_Err gf_beng_encode_from_string(GF_BifsEngine *beng, char *auString, GF_Err (*AUCallback)(void *, char *data, u32 size, u64 ts)); - -/** - * @beng, pointer to the GF_BifsEngine returned by BENC_Init - * @ctxFileName, name of the file to save the current state of the BIFS scene to - * - * save the current context of the beng. - * if you want to save an aggregate context, use BENC_AggregateCurrentContext before - * - */ -GF_Err gf_beng_save_context(GF_BifsEngine *beng, char *ctxFileName); - -/** - * @beng, pointer to the GF_BifsEngine returned by BENC_Init - * - * aggregates the current context of the beng, creates a scene replace - * - */ -GF_Err gf_beng_aggregate_context(GF_BifsEngine *beng); - -/** - * @beng, pointer to the GF_BifsEngine returned by BENC_Init - * - * release the memory used by this beng, no more call on the beng should happen after this - * - */ -void gf_beng_terminate(GF_BifsEngine *beng); - - -#endif - - -#ifdef __cplusplus -} -#endif // __cplusplus - - -#endif /*_GF_BIFSENGINE_H_*/ - diff --git a/include/gpac/bitstream.h b/include/gpac/bitstream.h index 22ac172..290dd0d 100644 --- a/include/gpac/bitstream.h +++ b/include/gpac/bitstream.h @@ -50,7 +50,7 @@ extern "C" { enum { GF_BITSTREAM_READ = 0, - GF_BITSTREAM_WRITE, + GF_BITSTREAM_WRITE }; typedef struct __tag_bitstream GF_BitStream; @@ -267,7 +267,7 @@ void gf_bs_write_double(GF_BitStream *bs, Double value); * \param data the data to write * \param nbBytes number of data bytes to write */ -u32 gf_bs_write_data(GF_BitStream *bs, char *data, u32 nbBytes); +u32 gf_bs_write_data(GF_BitStream *bs, const char *data, u32 nbBytes); /*! * \brief align char writing @@ -389,6 +389,14 @@ void gf_bs_skip_bytes(GF_BitStream *bs, u64 nbBytes); */ GF_Err gf_bs_seek(GF_BitStream *bs, u64 offset); +/*! + *\brief bitstream truncation + * + *Truncates the bitstream at the current position + *\param bs the target bitstream + */ +void gf_bs_truncate(GF_BitStream *bs); + /*! *\brief bit peeking * diff --git a/include/gpac/color.h b/include/gpac/color.h index 9c864eb..2f5817b 100644 --- a/include/gpac/color.h +++ b/include/gpac/color.h @@ -54,9 +54,12 @@ typedef struct u32 width; /*!Height of the video framebuffer */ u32 height; + /*!Horizontal pitch of the video framebuffer (number of bytes to skip to go to next (right) pixel in the buffer). May be + negative for some framebuffers (embedded devices). 0 means linear frame buffer (pitch_x==bytes per pixel)*/ + s32 pitch_x; /*!Vertical pitch of the video framebuffer (number of bytes to skip to go down one line in the buffer). May be negative for some framebuffers (embedded devices)*/ - s32 pitch; + s32 pitch_y; /*!Pixel format of the video framebuffer*/ u32 pixel_format; /*!pointer to the begining of the video memory (top-left corner)*/ @@ -223,7 +226,7 @@ typedef struct /*!\brief not done yet * */ -GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *dst_wnd, GF_Window *src_wnd, s32 dst_x_pitch, u8 alpha, Bool flip, GF_ColorKey *colorKey, GF_ColorMatrix * cmat); +GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *dst_wnd, GF_Window *src_wnd, u8 alpha, Bool flip, GF_ColorKey *colorKey, GF_ColorMatrix * cmat); diff --git a/include/gpac/compositor.h b/include/gpac/compositor.h index e6dca34..5799a45 100644 --- a/include/gpac/compositor.h +++ b/include/gpac/compositor.h @@ -155,6 +155,7 @@ GF_Compositor *gf_sc_get_compositor(GF_Node *node); Bool gf_sc_script_action(GF_Compositor *sr, u32 type, GF_Node *n, GF_JSAPIParam *param); +void gf_sc_reload_audio_filters(GF_Compositor *compositor); #ifdef __cplusplus } diff --git a/include/gpac/config_file.h b/include/gpac/config_file.h index 17d7f13..7b80967 100644 --- a/include/gpac/config_file.h +++ b/include/gpac/config_file.h @@ -153,7 +153,12 @@ GF_Err gf_cfg_insert_key(GF_Config *cfgFile, const char *secName, const char *ke */ void gf_cfg_del_section(GF_Config *cfgFile, const char *secName); -/*! @} */ +/*get a sub key (separator is ':') in a given key in a given section. Returns an error if the key does not exist + *\param cfgFile the target configuration file + *\param secName the target section + *\param keyName the name of the target key + *\param sub_index the 0-based index position of the sub key*/ +const char *gf_cfg_get_sub_key(GF_Config *iniFile, const char *secName, const char *keyName,u32 sub_index); #ifdef __cplusplus diff --git a/include/gpac/configuration.h b/include/gpac/configuration.h new file mode 100644 index 0000000..00cdc56 --- /dev/null +++ b/include/gpac/configuration.h @@ -0,0 +1,211 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2008 - + * 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_CONFIG_H_ +#define _GF_CONFIG_H_ + +#define GPAC_CONFIGURATION "(static configuration file)" + +/*this file defines all common macros for libgpac compilation*/ + +/*except for symbian32 which uses .mmp directives ... */ +#if defined(WIN32) || defined(_WIN32_WCE) + +/*enables GPAC fixed point*/ +//#define GPAC_FIXED_POINT + +/*automatic tracking is disabled by default, causes too many problems when reusing parts of gpac*/ +#if 0 +/*enables GPAC memory tracking*/ +#if defined(DEBUG) || defined(_DEBUG) +#define GPAC_MEMORY_TRACKING +#endif +#endif + +/*platform is big endian*/ +//#define GPAC_BIG_ENDIAN + +/*SSL enabled*/ +//#define GPAC_HAS_SSL + +/*spidermonkey enabled*/ +#define GPAC_HAS_SPIDERMONKEY + +/*libjpeg enabled*/ +#define GPAC_HAS_JPEG + +/*pnj enabled*/ +#define GPAC_HAS_PNG + +/*IPv6 enabled - for win32, this is evaluated at compile time, !! do not uncomment !!*/ +//#define GPAC_HAS_IPV6 + +/*3D compositor disabled*/ +//#define GPAC_DISABLE_3D + +/*use TinyGL instead of OpenGL*/ +//#define GPAC_USE_TINYGL + +/*use OpenGL ES instead of OpenGL*/ +//#define GPAC_USE_OGL_ES + + +#if defined(_WIN32_WCE) + +#ifndef GPAC_FIXED_POINT +#define GPAC_FIXED_POINT +#endif + +/*use intel fixed-point*/ +//#define GPAC_USE_IGPP +/*use intel fixed-point with high precision*/ +//#define GPAC_USE_IGPP_HP + +#if defined(GPAC_USE_IGPP) && defined(GPAC_USE_IGPP_HP) +#error "Only one of GPAC_USE_IGPP and GPAC_USE_IGPP_HP can be defined" +#endif + +#if !defined(GPAC_DISABLE_3D) && !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_OGL_ES) +#define GPAC_USE_OGL_ES +#endif + +#endif /*_WIN32_WCE*/ + + + +#endif /*defined(WIN32) || defined(_WIN32_WCE)*/ + + +#if defined(__SYMBIAN32__) + +#ifndef GPAC_FIXED_POINT +#define GPAC_FIXED_POINT +#endif + +#endif + +#if defined(_WIN32_WCE) +/*comment this line if you don't have a GLU32 version for Windows Mobile*/ +//#define GPAC_HAS_GLU +#elif defined(WIN32) +#define GPAC_HAS_GLU +#endif + + +/*disables SVG scene graph*/ +//#define GPAC_DISABLE_SVG + +/*disables VRML/BIFS scene graphs*/ +//#define GPAC_DISABLE_VRML + +/*disables X3D scene graphs*/ +//#define GPAC_DISABLE_X3D + +/*disables MPEG-4 OD Framework - this only minimalize the set of OD features used, however all cannot be removed*/ +//#define GPAC_MINIMAL_ODF + +/*disables BIFS coding*/ +//#define GPAC_DISABLE_BIFS + +/*disables LASeR coder*/ +//#define GPAC_DISABLE_LASER + +/*disables BIFS Engine support - TODO - merge DIMS and LASeR into BENG and rename it*/ +//#define GPAC_DISABLE_SENG + +/*disables Cubic QTVR importing*/ +//#define GPAC_DISABLE_QTVR + +/*disables AVILib support*/ +//#define GPAC_DISABLE_AVILIB + +/*disables OGG support*/ +//#define GPAC_DISABLE_OGG + +/*disables MPEG2 PS support*/ +//#define GPAC_DISABLE_MPEG2PS + +/*disables MPEG2 TS demux support*/ +//#define GPAC_DISABLE_MPEG2TS + +/*disables MPEG2 TS Mux support*/ +//#define GPAC_DISABLE_MPEG2TS_MUX + +/*disables all media import functions*/ +//#define GPAC_DISABLE_MEDIA_IMPORT + +/*disable all AV parsing functions*/ +//#define GPAC_DISABLE_AV_PARSERS + +/*disables all media export functions*/ +//#define GPAC_DISABLE_MEDIA_EXPORT + +/*disables SWF importer*/ +//#define GPAC_DISABLE_SWF_IMPORT + +/*disables all media export functions*/ +//#define GPAC_DISABLE_SCENE_STATS + +/*disables scene -> MP4 encoder*/ +//#define GPAC_DISABLE_SCENE_ENCODER + +/*disables ISOM -> scene decoder*/ +//#define GPAC_DISABLE_LOADER_ISOM + +/*disables BT/WRL/X3DV -> scene decoder*/ +//#define GPAC_DISABLE_LOADER_BT + +/*disables XMTA/X3D -> scene decoder*/ +//#define GPAC_DISABLE_LOADER_XMT + +/*disables mcrypt*/ +//#define GPAC_DISABLE_MCRYPT + +/*disables all ISO FF*/ +//#define GPAC_DISABLE_ISOM + +/*disables ISO FF hint tracks*/ +//#define GPAC_DISABLE_ISOM_HINTING + +/*disables ISO FF writing*/ +//#define GPAC_DISABLE_ISOM_WRITE + +/*disables ISO FF fragments*/ +//#define GPAC_DISABLE_ISOM_FRAGMENTS + +/*disables scene graph textual dump*/ +//#define GPAC_DISABLE_SCENE_DUMP + +/*disables OD graph textual dump*/ +//#define GPAC_DISABLE_OD_DUMP + +/*disables OD graph textual dump*/ +//#define GPAC_DISABLE_ISOM_DUMP + +/*disables IETF RTP/SDP/RTSP*/ +//#define GPAC_DISABLE_STREAMING + +#endif /*_GF_CONFIG_H_*/ + diff --git a/include/gpac/constants.h b/include/gpac/constants.h index 54cad88..f543b32 100644 --- a/include/gpac/constants.h +++ b/include/gpac/constants.h @@ -102,6 +102,9 @@ enum *the objectTypeIndication currently in use for these streams are documented below\n */ GF_STREAM_PRIVATE_SCENE = 0x20, + + /*used internally to signal the the OTI carries a 4CC code, typically media subtype (stsd entry in file format)*/ + GF_STREAM_4CC = 0xF0 }; @@ -127,9 +130,12 @@ enum /*!service descriptor expected is of TEXT type (3GPP/MPEG4)*/ GF_MEDIA_OBJECT_TEXT, /*!service descriptor expected is of UserInteraction type (MPEG-4 InputSensor)*/ - GF_MEDIA_OBJECT_INTERACT, + GF_MEDIA_OBJECT_INTERACT }; +/*! All Media Objects inserted through URLs and not MPEG-4 OD Framework use this ODID*/ +#define GF_MEDIA_EXTERNAL_ID 1050 + /*! * \brief Pixel Formats @@ -166,6 +172,12 @@ typedef enum /*!32 bit RGBA (openGL like)*/ GF_PIXEL_RGBA = GF_4CC('R','G','B', 'A'), + /*!RGB24 + depth plane*/ + GF_PIXEL_RGBD = GF_4CC('R', 'G', 'B', 'D'), + + /*!RGB24 + depth plane (7 power bits) + shape mask*/ + GF_PIXEL_RGBDS = GF_4CC('3', 'C', 'D', 'S'), + /*!YUV packed format*/ GF_PIXEL_YUY2 = GF_4CC('Y','U','Y','2'), /*!YUV packed format*/ @@ -189,16 +201,12 @@ typedef enum GF_PIXEL_IYUV = GF_4CC('I','Y','U','V'), /*!YUV planar format*/ GF_PIXEL_I420 = GF_4CC('I','4','2','0'), - - /*used in triscope mode and dumping rgbds textures in non-triscope mode*/ - GF_PIXEL_RGBDS = GF_4CC('3', 'C', 'D', 'S'), - - /*used for dumping rgbds textures in non-triscope mode*/ - GF_PIXEL_RGBD = GF_4CC('R', 'G', 'B', 'D'), /*!YV12 + Alpha plane*/ - GF_PIXEL_YUVA = GF_4CC('Y', 'U', 'V', 'A') + GF_PIXEL_YUVA = GF_4CC('Y', 'U', 'V', 'A'), + /*!YV12 + Depth plane*/ + GF_PIXEL_YUVD = GF_4CC('Y', 'U', 'V', 'D') } GF_PixelFormat; @@ -213,32 +221,68 @@ enum { /*!OTI for BIFS v1*/ GPAC_OTI_SCENE_BIFS = 0x01, + /*!OTI for OD v1*/ + GPAC_OTI_OD_V1 = 0x01, /*!OTI for BIFS v2*/ GPAC_OTI_SCENE_BIFS_V2 = 0x02, + /*!OTI for OD v2*/ + GPAC_OTI_OD_V2 = 0x02, /*!OTI for BIFS InputSensor streams*/ GPAC_OTI_SCENE_INTERACT = 0x03, - /*!OTI forLASeR streams*/ + /*!OTI for AFX streams with extended BIFS config*/ + GPAC_OTI_SCENE_BIFS_EXTENDED = 0x04, + /*!OTI for AFX streams with extended AFXConfig*/ + GPAC_OTI_SCENE_AFX = 0x05, + /*!OTI for Font data streams */ + GPAC_OTI_FONT = 0x06, + /*!OTI for synthesized texture streams */ + GPAC_OTI_SCENE_SYNTHESIZED_TEXTURE = 0x07, + /*!OTI for streaming text streams */ + GPAC_OTI_TEXT_MPEG4 = 0x08, + /*!OTI for LASeR streams*/ GPAC_OTI_SCENE_LASER = 0x09, - /*!OTI for dummy streams (dsi = file name) using the generci context loader (BIFS/VRML/SWF/...) - GPAC internal*/ - GPAC_OTI_PRIVATE_SCENE_GENERIC = 0xC0, - /*!OTI for SVG dummy stream (dsi = file name) - GPAC internal*/ - GPAC_OTI_PRIVATE_SCENE_SVG = 0xC1, - /*!OTI for LASeR/SAF+XML dummy stream (dsi = file name) - GPAC internal*/ - GPAC_OTI_PRIVATE_SCENE_LASER = 0xC2, - /*!OTI for XBL dummy streams (dsi = file name) - GPAC internal*/ - GPAC_OTI_PRIVATE_SCENE_XBL = 0xC3, - /*!OTI for EPG dummy streams (dsi = null) - GPAC internal*/ - GPAC_OTI_PRIVATE_SCENE_EPG = 0xC4, - - /*!OTI for streaming SVG - GPAC internal*/ - GPAC_OTI_SCENE_SVG = 0xD0, - /*!OTI for streaming SVG + gz - GPAC internal*/ - GPAC_OTI_SCENE_SVG_GZ = 0xD1, - /*!OTI for DIMS (dsi = 3GPP DIMS configuration) - GPAC internal*/ - GPAC_OTI_SCENE_DIMS = 0xD2, -}; - + /*!OTI for MPEG-4 Video Part 2 streams*/ + GPAC_OTI_VIDEO_MPEG4_PART2 = 0x20, + /*!OTI for MPEG-4 Video Part 10 (H.264 | AVC ) streams*/ + GPAC_OTI_VIDEO_AVC = 0x21, + /*!OTI for AVC Parameter sets streams*/ + GPAC_OTI_VIDEO_AVC_PS = 0x22, + /*!OTI for MPEG-4 AAC streams*/ + GPAC_OTI_AUDIO_AAC_MPEG4 = 0x40, + + /*!OTI for MPEG-2 Visual Simple Profile streams*/ + GPAC_OTI_VIDEO_MPEG2_SIMPLE = 0x60, + /*!OTI for MPEG-2 Visual Main Profile streams*/ + GPAC_OTI_VIDEO_MPEG2_MAIN = 0x61, + /*!OTI for MPEG-2 Visual SNR Profile streams*/ + GPAC_OTI_VIDEO_MPEG2_SNR = 0x62, + /*!OTI for MPEG-2 Visual SNR Profile streams*/ + GPAC_OTI_VIDEO_MPEG2_SPATIAL = 0x63, + /*!OTI for MPEG-2 Visual SNR Profile streams*/ + GPAC_OTI_VIDEO_MPEG2_HIGH = 0x64, + /*!OTI for MPEG-2 Visual SNR Profile streams*/ + GPAC_OTI_VIDEO_MPEG2_422 = 0x65, + + + /*!OTI for MPEG-2 AAC Main Profile streams*/ + GPAC_OTI_AUDIO_AAC_MPEG2_MP = 0x66, + /*!OTI for MPEG-2 AAC Low Complexity Profile streams*/ + GPAC_OTI_AUDIO_AAC_MPEG2_LCP = 0x67, + /*!OTI for MPEG-2 AAC Scaleable Sampling Rate Profile streams*/ + GPAC_OTI_AUDIO_AAC_MPEG2_SSRP = 0x68, + /*!OTI for MPEG-2 Audio Part 3 streams*/ + GPAC_OTI_AUDIO_MPEG2_PART3 = 0x69, + /*!OTI for MPEG-1 Video streams*/ + GPAC_OTI_VIDEO_MPEG1 = 0x6A, + /*!OTI for MPEG-1 Audio streams*/ + GPAC_OTI_AUDIO_MPEG1 = 0x6B, + /*!OTI for JPEG streams*/ + GPAC_OTI_IMAGE_JPEG = 0x6C, + /*!OTI for PNG streams*/ + GPAC_OTI_IMAGE_PNG = 0x6D, + /*!OTI for JPEG-2000 streams*/ + GPAC_OTI_IMAGE_JPEG_2000 = 0x6E, /*! * \brief Extra ObjectTypeIndication @@ -265,8 +309,7 @@ enum * char *data: per-codec extensions till end of DSI bitstream \endcode */ -#define GPAC_OTI_MEDIA_GENERIC 0x80 - + GPAC_OTI_MEDIA_GENERIC = 0x80, /*! * \brief FFMPEG ObjectTypeIndication * @@ -277,8 +320,52 @@ enum * char *data: codec extensions till end of DSI bitstream \endcode */ -#define GPAC_OTI_MEDIA_FFMPEG 0x81 + GPAC_OTI_MEDIA_FFMPEG = 0x81, + + /*!OTI for EVRC Voice streams*/ + GPAC_OTI_AUDIO_EVRC_VOICE = 0xA0, + /*!OTI for SMV Voice streams*/ + GPAC_OTI_AUDIO_SMV_VOICE = 0xA1, + /*!OTI for 3GPP2 CMF streams*/ + GPAC_OTI_3GPP2_CMF = 0xA2, + /*!OTI for SMPTE VC-1 Video streams*/ + GPAC_OTI_VIDEO_SMPTE_VC1 = 0xA3, + /*!OTI for Dirac Video streams*/ + GPAC_OTI_VIDEO_DIRAC = 0xA4, + /*!OTI for AC-3 audio streams*/ + GPAC_OTI_AUDIO_AC3 = 0xA5, + /*!OTI for enhanced AC-3 audio streams*/ + GPAC_OTI_AUDIO_AC3_ENHANCED = 0xA6, + /*!OTI for DRA audio streams*/ + GPAC_OTI_AUDIO_DRA = 0xA7, + /*!OTI for ITU G719 audio streams*/ + GPAC_OTI_AUDIO_ITU_G719 = 0xA8, + /*!OTI for DTS Coherent Acoustics audio streams*/ + GPAC_OTI_AUDIO_DTS_CA = 0xA9, + /*!OTI for DTS-HD High Resolution audio streams*/ + GPAC_OTI_AUDIO_DTS_HD_HR = 0xAA, + /*!OTI for DTS-HD Master audio streams*/ + GPAC_OTI_AUDIO_DTS_HD_MASTER = 0xAB, + + /*!OTI for dummy streams (dsi = file name) using the generic context loader (BIFS/VRML/SWF/...) - GPAC internal*/ + GPAC_OTI_PRIVATE_SCENE_GENERIC = 0xC0, + /*!OTI for SVG dummy stream (dsi = file name) - GPAC internal*/ + GPAC_OTI_PRIVATE_SCENE_SVG = 0xC1, + /*!OTI for LASeR/SAF+XML dummy stream (dsi = file name) - GPAC internal*/ + GPAC_OTI_PRIVATE_SCENE_LASER = 0xC2, + /*!OTI for XBL dummy streams (dsi = file name) - GPAC internal*/ + GPAC_OTI_PRIVATE_SCENE_XBL = 0xC3, + /*!OTI for EPG dummy streams (dsi = null) - GPAC internal*/ + GPAC_OTI_PRIVATE_SCENE_EPG = 0xC4, + /*!OTI for WGT dummy streams (dsi = null) - GPAC internal*/ + GPAC_OTI_PRIVATE_SCENE_WGT = 0xC5, + /*!OTI for streaming SVG - GPAC internal*/ + GPAC_OTI_SCENE_SVG = 0xD0, + /*!OTI for streaming SVG + gz - GPAC internal*/ + GPAC_OTI_SCENE_SVG_GZ = 0xD1, + /*!OTI for DIMS (dsi = 3GPP DIMS configuration) - GPAC internal*/ + GPAC_OTI_SCENE_DIMS = 0xD2, /*! * \brief OGG ObjectTypeIndication @@ -292,7 +379,15 @@ enum dsi_size -= packet_size; }\endcode */ -#define GPAC_OTI_MEDIA_OGG 0xDD + GPAC_OTI_MEDIA_OGG = 0xDD, + GPAC_OTI_MEDIA_THEORA = 0xDF, + + GPAC_OTI_MEDIA_SUBPIC = 0xE0, + + /*!OTI for 13K Voice / QCELP audio streams*/ + GPAC_OTI_AUDIO_13K_VOICE = 0xE1 + +}; @@ -355,18 +450,29 @@ enum */ /*AVC NAL unit types*/ -#define GF_AVC_NALU_NON_IDR_SLICE 0x1 -#define GF_AVC_NALU_DP_A_SLICE 0x2 -#define GF_AVC_NALU_DP_B_SLICE 0x3 -#define GF_AVC_NALU_DP_C_SLICE 0x4 -#define GF_AVC_NALU_IDR_SLICE 0x5 -#define GF_AVC_NALU_SEI 0x6 -#define GF_AVC_NALU_SEQ_PARAM 0x7 -#define GF_AVC_NALU_PIC_PARAM 0x8 -#define GF_AVC_NALU_ACCESS_UNIT 0x9 -#define GF_AVC_NALU_END_OF_SEQ 0xa -#define GF_AVC_NALU_END_OF_STREAM 0xb -#define GF_AVC_NALU_FILLER_DATA 0xc +#define GF_AVC_NALU_NON_IDR_SLICE 1 +#define GF_AVC_NALU_DP_A_SLICE 2 +#define GF_AVC_NALU_DP_B_SLICE 3 +#define GF_AVC_NALU_DP_C_SLICE 4 +#define GF_AVC_NALU_IDR_SLICE 5 +#define GF_AVC_NALU_SEI 6 +#define GF_AVC_NALU_SEQ_PARAM 7 +#define GF_AVC_NALU_PIC_PARAM 8 +#define GF_AVC_NALU_ACCESS_UNIT 9 +#define GF_AVC_NALU_END_OF_SEQ 10 +#define GF_AVC_NALU_END_OF_STREAM 11 +#define GF_AVC_NALU_FILLER_DATA 12 +#define GF_AVC_NALU_SEQ_PARAM_EXT 13 + +#define GF_AVC_NALU_SVC_PREFIX_NALU 14 +#define GF_AVC_NALU_SVC_SUBSEQ_PARAM 15 +#define GF_AVC_NALU_SLICE_AUX 19 + +#define GF_AVC_NALU_SVC_SLICE 0x14 + +/*#define GF_SVC_NALU_SLICE 0x14 +#define GF_SVC_NALU_NAL_EXT_PARAM 14 +#define GF_SVC_NALU_SEQ_EXT_PARAM 15*/ #define GF_AVC_TYPE_P 0 #define GF_AVC_TYPE_B 1 @@ -389,6 +495,9 @@ static const u32 GF_AMR_FRAME_SIZE[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, static const u32 GF_AMR_WB_FRAME_SIZE[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, 5, 0, 0, 0, 0, 0 }; +/*out-of-band sample desc (128 and 255 reserved in RFC)*/ +#define GF_RTP_TX3G_SIDX_OFFSET 129 + /*! \endcond */ diff --git a/include/gpac/crypt.h b/include/gpac/crypt.h index 20cb825..8e297ee 100644 --- a/include/gpac/crypt.h +++ b/include/gpac/crypt.h @@ -56,6 +56,9 @@ extern "C" { #include +#ifndef GPAC_DISABLE_MCRYPT + + /*max number of possible key sizes for all supported modes*/ #define MAX_KEY_SIZES 4 @@ -150,6 +153,7 @@ u32 gf_crypt_str_module_get_algo_block_size(const char *algorithm); u32 gf_crypt_str_module_get_algo_key_size(const char *algorithm); u32 gf_crypt_str_get_algo_supported_key_sizes(const char *algorithm, int *keys); +#endif /*GPAC_DISABLE_MCRYPT*/ /*SHA1 from Christophe Devine*/ @@ -182,6 +186,7 @@ void gf_sha1_csum(u8 *buf, u32 buflen, u8 digest[20]); */ void gf_sha1_hmac(u8 *key, u32 keylen, u8 *buf, u32 buflen, u8 digest[20]); + #ifdef __cplusplus } #endif diff --git a/include/gpac/download.h b/include/gpac/download.h index 89ccf6e..b005b9b 100644 --- a/include/gpac/download.h +++ b/include/gpac/download.h @@ -132,6 +132,12 @@ enum GF_NETIO_SESSION_NOT_THREADED = 1, /*!session has no cache: data will be sent to the user if threaded mode (live streams like radios & co)*/ GF_NETIO_SESSION_NOT_CACHED = 1<<1, + /*! ignores any data already in the cache*/ + GF_NETIO_SESSION_FORCE_RESTART = 1<<2, + /*! reuses any data already in the cache and appends the new data*/ + GF_NETIO_SESSION_REUSE_APPEND = 1<<3, + /*! forces cache to be saved on disk - this is temporary until we cleanup cache management*/ + GF_NETIO_SESSION_KEEP_CACHE = 1<<4 }; @@ -266,6 +272,42 @@ const char *gf_dm_sess_get_cache_name(GF_DownloadSession * sess); GF_Err gf_dm_sess_get_stats(GF_DownloadSession * sess, const char **server, const char **path, u32 *total_size, u32 *bytes_done, u32 *bytes_per_sec, u32 *net_status); +/*! + *\brief fetch session object + * + *Fetch the session object (process all headers and data transfer). This is only usable if the session is not threaded + *\param sess the download session + *\return the last error in the session or 0 if none*/ +GF_Err gf_dm_sess_process(GF_DownloadSession * sess); + +/*! + *\brief Get session resource url + * + *Returns the original resource URL associated with the session + *\param sess the download session + *\return the associated URL*/ +const char *gf_dm_sess_get_resource_name(GF_DownloadSession *dnload); + +/*! + *\brief Set session request range + * + *Sets the session range request + *\param sess the download session + *\param start start range of the request + *\param end end range of the request + *\return error code if any + */ +GF_Err gf_dm_sess_set_range(GF_DownloadSession *sess, u32 start, u32 end); + +/*! + *\brief Reset session + * + *Resets the session for new processing of the same url + *\param sess the download session + *\return error code if any + */ +GF_Err gf_dm_sess_reset(GF_DownloadSession *sess); + /*! @} */ #ifdef __cplusplus diff --git a/include/gpac/dvb_mpe.h b/include/gpac/dvb_mpe.h new file mode 100644 index 0000000..6a6305c --- /dev/null +++ b/include/gpac/dvb_mpe.h @@ -0,0 +1,41 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Walid B.H - Jean Le Feuvre + * Copyright (c)2006-200X ENST - 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 + * 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. + * + * 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 gf_free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#ifndef _GF_DVB_MPE_H_ +#define _GF_DVB_MPE_H_ + +#include +#include + +typedef struct tag_m2ts_section_mpe GF_M2TS_SECTION_MPE; +typedef struct _sock_entry GF_SOCK_ENTRY; + +void gf_dvb_mpe_init(GF_M2TS_Demuxer *ts); +void gf_dvb_mpe_shutdown(GF_M2TS_Demuxer *ts); +GF_M2TS_ES *gf_dvb_mpe_section_new(); +void gf_dvb_mpe_section_del(GF_M2TS_ES *es); +void gf_m2ts_print_mpe_info(GF_M2TS_Demuxer *ts); + +#endif //_GF_DVB_MPE_H_ diff --git a/include/gpac/esi.h b/include/gpac/esi.h index 3e49933..d942c46 100644 --- a/include/gpac/esi.h +++ b/include/gpac/esi.h @@ -71,7 +71,9 @@ enum GF_ESI_DATA_AU_RAP = 1<<2, GF_ESI_DATA_HAS_CTS = 1<<3, GF_ESI_DATA_HAS_DTS = 1<<4, - GF_ESI_DATA_ENCRYPTED = 1<<5, + GF_ESI_DATA_REPEAT = 1<<5, + GF_ESI_DATA_CRITICAL = 1<<6, + GF_ESI_DATA_ENCRYPTED = 1<<7, }; typedef struct __data_packet_ifce @@ -120,8 +122,6 @@ typedef struct __elementary_stream_ifce /*MPEG-4 ST/OTIs*/ u8 stream_type; u8 object_type_indication; - /* MPEG-4 SL Config */ - GF_SLConfig sl_config; /*stream 4CC for non-mpeg codecs, 0 otherwise (stream is identified through StreamType/ObjectType)*/ u32 fourcc; /*packed 3-char language code (4CC with last byte ' ')*/ @@ -132,6 +132,11 @@ typedef struct __elementary_stream_ifce Double duration; /*average bit rate in bit/sec - 0 if unknown*/ u32 bit_rate; + /*repeat rate in ms for carrouseling - 0 if no repeat*/ + u32 repeat_rate; + + char *decoder_config; + u32 decoder_config_size; struct __esi_video_info info_video; struct __esi_audio_info info_audio; diff --git a/include/gpac/events.h b/include/gpac/events.h index df62203..ad6ef47 100644 --- a/include/gpac/events.h +++ b/include/gpac/events.h @@ -145,6 +145,14 @@ enum { /*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. @@ -178,6 +186,7 @@ enum { /*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*/ @@ -189,6 +198,7 @@ enum { GF_EVENT_MIGRATE, /*indicates a session migration request*/ GF_EVENT_DISCONNECT, /*indicates the current url should be disconnected*/ GF_EVENT_SYS_COLORS, /*queries the list of system colors*/ + GF_EVENT_RESOLUTION, /*indicates the screen resolution has changed*/ }; /*GPAC/DOM3 key codes*/ diff --git a/include/gpac/filestreamer.h b/include/gpac/filestreamer.h new file mode 100644 index 0000000..a400851 --- /dev/null +++ b/include/gpac/filestreamer.h @@ -0,0 +1,121 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2008- + * All rights reserved + * + * This file is part of GPAC / media tools sub-project + * + * GPAC is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GPAC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _GF_ISOMRTPStreamer_H_ +#define _GF_ISOMRTPStreamer_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \file + * \brief RTP file streamer functions. + */ + +/*! + * \addtogroup media_grp FileStreamer + * \ingroup media_grp + * \brief FileStreamer object + * + * This section documents the list object of the GPAC framework. + * @{ + */ + +#include + + +typedef struct __isom_rtp_streamer GF_ISOMRTPStreamer; + +/*! + * \brief ISO File RTP Streamer list constructor + * + * Constructs a new ISO file RTP streamer + *\param file_name source file name to stream. Hint tracks will be ignored, all media tracks will be streamed + *\param ip_dest destination IP address (V4 or V6, unicast or multicast) + *\param port destination port + *\param loop whether streaming stops at the end of all tracks or not. If not, RTP TS will continuously be incremented + *\param force_mpeg4 forces usage of MPEG-4 generic (RFC3640) for all streams + *\param path_mtu maximum RTP packet payload size allowed + *\param ttl multicast time to live + *\param ifce_addr IP of the local interface to use (may be NULL) + *\return new list object + */ +GF_ISOMRTPStreamer *gf_isom_streamer_new(const char *file_name, const char *ip_dest, u16 port, Bool loop, Bool force_mpeg4, u32 path_mtu, u32 ttl, char *ifce_addr); + +/*! + * \brief RTP file streamer destructor + * + * Destructs an RTP file streamer + * \param ptr object to destruct + */ +void gf_isom_streamer_del(GF_ISOMRTPStreamer *streamer); + +/*! + * \brief writes the SDP file + * + * Writes the SDP file asscoiated with the streaming session + * \param streamer RTP streamer object + * \param sdpfilename SDP file name to create + */ +GF_Err gf_isom_streamer_write_sdp(GF_ISOMRTPStreamer *streamer, char*sdpfilename); + +/*! + * \brief gets the SDP file + * + * Gets the SDP asscoiated with all media in the streaming session (only media parts are returned) + * \param streamer RTP streamer object + * \param out_sdp_buffer location to the SDP buffer to allocate and fill + */ +GF_Err gf_isom_streamer_get_sdp(GF_ISOMRTPStreamer *streamer, char **out_sdp_buffer); + + +/*! + * \brief sends RTP packet + * + * Sends the next RTP packet in the current file, potentially waiting for the TS to be mature. If the last packet is sent and looping is disabled, this will return GF_EOS. + * \param streamer RTP streamer object + * \param send_ahead_delay delay in milliseconds for packet sending. A packet is sent if (packet.timestamp + send_ahead_delay) is greate than the current time. + * \param max_sleep_time indicates that if the streamer has to wait more than max_sleep_time before sending the packet, it should return and send it later. + */ +GF_Err gf_isom_streamer_send_next_packet(GF_ISOMRTPStreamer *streamer, s32 send_ahead_delay, s32 max_sleep_time); + +/*! + * \brief resets RTP sender + * + * Reset the RTP streams to the beginning of the media file + * \param streamer RTP streamer object + * \param is_loop indicates whether the RTP timelines shall continue from the end of the file or shall restart from 0 + */ +void gf_isom_streamer_reset(GF_ISOMRTPStreamer *streamer, Bool is_loop); + +/*! @} */ + +#ifdef __cplusplus +} +#endif + + +#endif /*_GF_ISOMRTPStreamer_H_*/ + diff --git a/include/gpac/ietf.h b/include/gpac/ietf.h index 2d6d778..8e449a9 100644 --- a/include/gpac/ietf.h +++ b/include/gpac/ietf.h @@ -32,6 +32,9 @@ extern "C" { #endif #include + +#ifndef GPAC_DISABLE_STREAMING + #include #include #include @@ -537,7 +540,7 @@ void gf_rtp_del(GF_RTPChannel *ch); /*you configure a server channel through the transport structure, with the same info as a client channel, the client_port_* info designing the REMOTE client and port_* designing your server channel*/ -GF_Err gf_rtp_setup_transport(GF_RTPChannel *ch, GF_RTSPTransport *trans_info, char *remote_address); +GF_Err gf_rtp_setup_transport(GF_RTPChannel *ch, GF_RTSPTransport *trans_info, const char *remote_address); /*auto-setup of rtp/rtcp transport ports - only effective in unicast, non interleaved cases. for multicast port setup MUST be done through the above gf_rtp_setup_transport function @@ -598,7 +601,7 @@ u32 gf_rtp_read_rtcp(GF_RTPChannel *ch, char *buffer, u32 buffer_size); GF_Err gf_rtp_decode_rtp(GF_RTPChannel *ch, char *pck, u32 pck_size, GF_RTPHeader *rtp_hdr, u32 *PayloadStart); /*decodes an RTCP packet and update timing info, send RR too*/ -GF_Err gf_rtp_decode_rtcp(GF_RTPChannel *ch, char *pck, u32 pck_size); +GF_Err gf_rtp_decode_rtcp(GF_RTPChannel *ch, char *pck, u32 pck_size, Bool *has_sr); /*computes and send Receiver report. If the channel is a TCP channel, you must specify the callback function. NOTE: many RTP implementation do NOT process RTCP info received on TCP... @@ -614,8 +617,9 @@ GF_Err gf_rtp_send_bye(GF_RTPChannel *ch, void *rtsp_cbk); -/*send RTP packet*/ -GF_Err gf_rtp_send_packet(GF_RTPChannel *ch, GF_RTPHeader *rtp_hdr, char *extra_header, u32 extra_header_size, char *pck, u32 pck_size); +/*send RTP packet. In fast_send mode, user passes a pck pointer with 12 bytes available BEFORE pck to +write the header in place*/ +GF_Err gf_rtp_send_packet(GF_RTPChannel *ch, GF_RTPHeader *rtp_hdr, char *pck, u32 pck_size, Bool fast_send); enum { @@ -997,7 +1001,7 @@ enum /*MPEG-4 generic transport option*/ /*if flag set, RAP flag is signaled in RTP payload*/ GP_RTP_PCK_SIGNAL_RAP = (1<<4), - /*if flag set, AU indexes are signaled in RTP payload*/ + /*if flag set, AU indexes are signaled in RTP payload - only usable for AU interleaving (eg audio)*/ GP_RTP_PCK_SIGNAL_AU_IDX = (1<<5), /*if flag set, AU size is signaled in RTP payload*/ GP_RTP_PCK_SIGNAL_SIZE = (1<<6), @@ -1005,7 +1009,7 @@ enum GP_RTP_PCK_SIGNAL_TS = (1<<7), /*setup payload for carouseling of systems streams*/ - GP_RTP_PCK_AUTO_CAROUSEL = (1<<8), + GP_RTP_PCK_SYSTEMS_CAROUSEL = (1<<8), /*use LATM payload for AAC-LC*/ GP_RTP_PCK_USE_LATM_AAC = (1<<9), @@ -1017,6 +1021,9 @@ enum /*signals that each sample will have its own key indicator - ignored in non-multi modes if not set and key indicator changes, a new RTP packet will be forced*/ GP_RTP_PCK_KEY_IDX_PER_AU = (1<<11), + + /*is zip compression used in DIMS unit ?*/ + GP_RTP_DIMS_COMPRESSED = (1<<12), }; @@ -1155,8 +1162,8 @@ struct __tag_rtp_packetizer typedef struct __tag_rtp_packetizer GP_RTPPacketizer; /*creates a new builder - @hintType: hint media type, one of the above - @flags: hint flags (cf above) + @rtp_payt: rtp payload format, one of the above GF_RTP_PAYT_* + @flags: packetizer flags, one of the above GP_RTP_PCK_* @slc: user-given SL config to use. If none specified, default RFC config is used @cbk_obj: callback object passed back in functions @OnNewPacket: callback function starting new RTP packet @@ -1172,7 +1179,7 @@ typedef struct __tag_rtp_packetizer GP_RTPPacketizer; @is_head: signal the data added MUST be inserted at the begining of the payload. Otherwise data is concatenated as received */ -GP_RTPPacketizer *gf_rtp_builder_new(u32 hintType, +GP_RTPPacketizer *gf_rtp_builder_new(u32 rtp_payt, GF_SLConfig *slc, u32 flags, void *cbk_obj, @@ -1311,6 +1318,8 @@ void gf_rtp_depacketizer_process(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, cha void gf_rtp_depacketizer_get_slconfig(GF_RTPDepacketizer *rtp, GF_SLConfig *sl); +#endif /*GPAC_DISABLE_STREAMING*/ + #ifdef __cplusplus } #endif diff --git a/include/gpac/internal/avilib.h b/include/gpac/internal/avilib.h index 08ac5be..7697cc3 100644 --- a/include/gpac/internal/avilib.h +++ b/include/gpac/internal/avilib.h @@ -30,6 +30,8 @@ #include +#ifndef GPAC_DISABLE_AVILIB + #define AVI_MAX_TRACKS 8 typedef struct @@ -431,4 +433,7 @@ struct AVIStreamHeader { long dwSampleSize; }; +#endif /*GPAC_DISABLE_AVILIB*/ + #endif /*_GF_AVILIB_H_*/ + diff --git a/include/gpac/internal/bifs_dev.h b/include/gpac/internal/bifs_dev.h index 6af7710..b7e897d 100644 --- a/include/gpac/internal/bifs_dev.h +++ b/include/gpac/internal/bifs_dev.h @@ -33,6 +33,11 @@ #include #include +#ifndef GPAC_DISABLE_BIFS + +/*defined to support BIFS predictive MF fields*/ +//#define GPAC_ENABLE_BIFS_PMF + typedef struct { /*node this mask is for*/ GF_Node *node; @@ -121,6 +126,9 @@ struct __tag_bifs_dec Bool ignore_size; Bool is_com_dec; Double cts_offset; + + char *extraction_path; + char *service_url; }; @@ -151,6 +159,8 @@ void gf_bifs_check_field_change(GF_Node *node, GF_FieldInfo *field); GF_Err gf_bifs_flush_command_list(GF_BifsDecoder *codec); +#ifndef GPAC_DISABLE_BIFS_ENC + struct __tag_bifs_enc { GF_Err LastError; @@ -199,6 +209,8 @@ GF_Node *gf_bifs_enc_find_node(GF_BifsEncoder *codec, u32 nodeID); GF_Route *gf_bifs_enc_is_field_ised(GF_BifsEncoder *codec, GF_Node *node, u32 fieldIndex); +#endif /*GPAC_DISABLE_BIFS_ENC*/ + /*get field QP and anim info*/ Bool gf_bifs_get_aq_info(GF_Node *Node, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits); @@ -219,5 +231,9 @@ u32 gf_bifs_get_ndt_bits(u32 NDT_Tag, u32 Version); /*return absolute node tag given its type in the NDT and the NDT version number*/ u32 gf_bifs_ndt_get_node_type(u32 NDT_Tag, u32 NodeType, u32 Version); + +#endif /*GPAC_DISABLE_BIFS*/ + #endif //_GF_BIFS_DEV_H_ + diff --git a/include/gpac/internal/bifs_tables.h b/include/gpac/internal/bifs_tables.h index 59449f5..c36268f 100644 --- a/include/gpac/internal/bifs_tables.h +++ b/include/gpac/internal/bifs_tables.h @@ -24,9 +24,9 @@ /* - DO NOT MOFIFY - File generated on GMT Thu Aug 07 11:43:26 2008 + DO NOT MOFIFY - File generated on GMT Mon Jan 18 12:27:12 2010 - BY MPEG4Gen for GPAC Version 0.4.5-DEV + BY MPEG4Gen for GPAC Version 0.4.6-DEV */ #ifndef _NDT_H @@ -36,6 +36,9 @@ +#ifndef GPAC_DISABLE_BIFS + + u32 ALL_GetNodeType(const u32 *table, const u32 count, u32 NodeTag, u32 Version); @@ -652,10 +655,180 @@ u32 NDT_V6_GetNodeType(u32 NDT_Tag, u32 NodeTag); + +/* NDT BIFS Version 7 */ + +#define SFWorldNode_V7_NUMBITS 4 +#define SFWorldNode_V7_Count 11 + +static const u32 SFWorldNode_V7_TypeToTag[11] = { + TAG_MPEG4_AdvancedAudioBuffer, TAG_MPEG4_AudioChannelConfig, TAG_MPEG4_DepthImageV2, TAG_MPEG4_MorphShape, TAG_MPEG4_MultiTexture, TAG_MPEG4_PointTextureV2, TAG_MPEG4_SBVCAnimationV2, TAG_MPEG4_SimpleTextureV2, TAG_MPEG4_SurroundingSound, TAG_MPEG4_Transform3DAudio, TAG_MPEG4_WideSound +}; + +#define SF3DNode_V7_NUMBITS 3 +#define SF3DNode_V7_Count 6 + +static const u32 SF3DNode_V7_TypeToTag[6] = { + TAG_MPEG4_DepthImageV2, TAG_MPEG4_MorphShape, TAG_MPEG4_SBVCAnimationV2, TAG_MPEG4_SurroundingSound, TAG_MPEG4_Transform3DAudio, TAG_MPEG4_WideSound +}; + +#define SF2DNode_V7_NUMBITS 2 +#define SF2DNode_V7_Count 3 + +static const u32 SF2DNode_V7_TypeToTag[3] = { + TAG_MPEG4_MorphShape, TAG_MPEG4_SBVCAnimationV2, TAG_MPEG4_Transform3DAudio +}; + +#define SFAudioNode_V7_NUMBITS 2 +#define SFAudioNode_V7_Count 2 + +static const u32 SFAudioNode_V7_TypeToTag[2] = { + TAG_MPEG4_AdvancedAudioBuffer, TAG_MPEG4_AudioChannelConfig +}; + +#define SFTextureNode_V7_NUMBITS 1 +#define SFTextureNode_V7_Count 1 + +static const u32 SFTextureNode_V7_TypeToTag[1] = { + TAG_MPEG4_MultiTexture +}; + +#define SFDepthImageNode_V7_NUMBITS 1 +#define SFDepthImageNode_V7_Count 1 + +static const u32 SFDepthImageNode_V7_TypeToTag[1] = { + TAG_MPEG4_DepthImageV2 +}; + +#define SFDepthTextureNode_V7_NUMBITS 2 +#define SFDepthTextureNode_V7_Count 2 + +static const u32 SFDepthTextureNode_V7_TypeToTag[2] = { + TAG_MPEG4_PointTextureV2, TAG_MPEG4_SimpleTextureV2 +}; + + +u32 NDT_V7_GetNumBits(u32 NDT_Tag); +u32 NDT_V7_GetNodeTag(u32 Context_NDT_Tag, u32 NodeType); +u32 NDT_V7_GetNodeType(u32 NDT_Tag, u32 NodeTag); + + + + +/* NDT BIFS Version 8 */ + +#define SFWorldNode_V8_NUMBITS 2 +#define SFWorldNode_V8_Count 2 + +static const u32 SFWorldNode_V8_TypeToTag[2] = { + TAG_MPEG4_ScoreShape, TAG_MPEG4_MusicScore +}; + +#define SF3DNode_V8_NUMBITS 1 +#define SF3DNode_V8_Count 1 + +static const u32 SF3DNode_V8_TypeToTag[1] = { + TAG_MPEG4_ScoreShape +}; + +#define SF2DNode_V8_NUMBITS 1 +#define SF2DNode_V8_Count 1 + +static const u32 SF2DNode_V8_TypeToTag[1] = { + TAG_MPEG4_ScoreShape +}; + +#define SFMusicScoreNode_V8_NUMBITS 1 +#define SFMusicScoreNode_V8_Count 1 + +static const u32 SFMusicScoreNode_V8_TypeToTag[1] = { + TAG_MPEG4_MusicScore +}; + + +u32 NDT_V8_GetNumBits(u32 NDT_Tag); +u32 NDT_V8_GetNodeTag(u32 Context_NDT_Tag, u32 NodeType); +u32 NDT_V8_GetNodeType(u32 NDT_Tag, u32 NodeTag); + + + + +/* NDT BIFS Version 9 */ + +#define SFWorldNode_V9_NUMBITS 3 +#define SFWorldNode_V9_Count 6 + +static const u32 SFWorldNode_V9_TypeToTag[6] = { + TAG_MPEG4_FootPrintSetNode, TAG_MPEG4_FootPrintNode, TAG_MPEG4_BuildingPartNode, TAG_MPEG4_RoofNode, TAG_MPEG4_FacadeNode, TAG_MPEG4_Shadow +}; + +#define SF3DNode_V9_NUMBITS 3 +#define SF3DNode_V9_Count 6 + +static const u32 SF3DNode_V9_TypeToTag[6] = { + TAG_MPEG4_FootPrintSetNode, TAG_MPEG4_FootPrintNode, TAG_MPEG4_BuildingPartNode, TAG_MPEG4_RoofNode, TAG_MPEG4_FacadeNode, TAG_MPEG4_Shadow +}; + +#define SFGeometryNode_V9_NUMBITS 3 +#define SFGeometryNode_V9_Count 6 + +static const u32 SFGeometryNode_V9_TypeToTag[6] = { + TAG_MPEG4_FootPrintSetNode, TAG_MPEG4_FootPrintNode, TAG_MPEG4_BuildingPartNode, TAG_MPEG4_RoofNode, TAG_MPEG4_FacadeNode, TAG_MPEG4_Shadow +}; + + +u32 NDT_V9_GetNumBits(u32 NDT_Tag); +u32 NDT_V9_GetNodeTag(u32 Context_NDT_Tag, u32 NodeType); +u32 NDT_V9_GetNodeType(u32 NDT_Tag, u32 NodeTag); + + + + +/* NDT BIFS Version 10 */ + +#define SFWorldNode_V10_NUMBITS 3 +#define SFWorldNode_V10_Count 5 + +static const u32 SFWorldNode_V10_TypeToTag[5] = { + TAG_MPEG4_CacheTexture, TAG_MPEG4_EnvironmentTest, TAG_MPEG4_KeyNavigator, TAG_MPEG4_SpacePartition, TAG_MPEG4_Storage +}; + +#define SF3DNode_V10_NUMBITS 3 +#define SF3DNode_V10_Count 5 + +static const u32 SF3DNode_V10_TypeToTag[5] = { + TAG_MPEG4_CacheTexture, TAG_MPEG4_EnvironmentTest, TAG_MPEG4_KeyNavigator, TAG_MPEG4_SpacePartition, TAG_MPEG4_Storage +}; + +#define SF2DNode_V10_NUMBITS 3 +#define SF2DNode_V10_Count 4 + +static const u32 SF2DNode_V10_TypeToTag[4] = { + TAG_MPEG4_CacheTexture, TAG_MPEG4_EnvironmentTest, TAG_MPEG4_KeyNavigator, TAG_MPEG4_Storage +}; + +#define SFTextureNode_V10_NUMBITS 1 +#define SFTextureNode_V10_Count 1 + +static const u32 SFTextureNode_V10_TypeToTag[1] = { + TAG_MPEG4_CacheTexture +}; + + +u32 NDT_V10_GetNumBits(u32 NDT_Tag); +u32 NDT_V10_GetNodeTag(u32 Context_NDT_Tag, u32 NodeType); +u32 NDT_V10_GetNodeType(u32 NDT_Tag, u32 NodeTag); + + + u32 NDT_GetChildTable(u32 NodeTag); +#endif /*GPAC_DISABLE_BIFS*/ + + + #endif /*_NDT_H*/ diff --git a/include/gpac/internal/compositor_dev.h b/include/gpac/internal/compositor_dev.h index 311c2b3..21dd540 100644 --- a/include/gpac/internal/compositor_dev.h +++ b/include/gpac/internal/compositor_dev.h @@ -53,10 +53,16 @@ /*use 2D caching for groups*/ //#define GF_SR_USE_VIDEO_CACHE +//#define GPAC_USE_TINYGL + +/*depth-enabled version for autostereoscopic displays */ +#define GF_SR_USE_DEPTH /*FPS computed on this number of frame*/ #define GF_SR_FPS_COMPUTE_SIZE 30 + + enum { GF_SR_CFG_OVERRIDE_SIZE = 1, @@ -103,8 +109,17 @@ typedef struct #endif +#if !defined(GPAC_DISABLE_3D) && !defined(GPAC_USE_TINYGL) +# define OPENGL_RASTER +#else +# ifdef OPENGL_RASTER +# undef OPENGL_RASTER +# endif +#endif + #define DOUBLECLICK_TIME_MS 250 + enum { /*no text selection*/ @@ -117,6 +132,13 @@ enum GF_SC_TSEL_RELEASED, }; +enum +{ + GF_SC_DRAW_NONE, + GF_SC_DRAW_FRAME, + GF_SC_DRAW_FLUSH, +}; + struct __tag_compositor { /*the main user*/ @@ -131,6 +153,9 @@ struct __tag_compositor /*2D rasterizer*/ GF_Raster2D *rasterizer; + /*all textures (texture handlers)*/ + GF_List *video_listeners; + /*visual rendering thread if used*/ GF_Thread *VisualThread; /*0: not init, 1: running, 2: exit requested, 3: done*/ @@ -144,6 +169,8 @@ struct __tag_compositor /*extra scene graphs (OSD, etc), always registered in draw order. That's the module responsability to draw them*/ GF_List *extra_scenes; + + u32 inherit_type_3d; /*all time nodes registered*/ GF_List *time_nodes; @@ -183,9 +210,11 @@ struct __tag_compositor Bool fullscreen; /*!! paused will not stop display (this enables pausing a VRML world and still examining it)*/ Bool paused, step_mode; - Bool draw_next_frame; + u32 frame_draw_type; + u32 force_next_frame_redraw; /*freeze_display prevents any screen updates - needed when output driver uses direct video memory access*/ Bool is_hidden, freeze_display; + Bool debug_defer; /*current frame number*/ u32 frame_number; @@ -199,11 +228,15 @@ struct __tag_compositor GF_FontManager *font_manager; /*set whenever a new font has been received*/ Bool reset_fonts; + s32 fonts_pending; /*options*/ u32 aspect_ratio, antiAlias, texture_text_mode; Bool high_speed, stress_mode; Bool force_opengl_2d; +#ifdef OPENGL_RASTER + Bool opengl_raster; +#endif /*key modif*/ u32 key_states; @@ -272,6 +305,12 @@ struct __tag_compositor /*indicates a sensor is currently active*/ Bool grabbed_sensor; + /*current keynav node if any*/ + GF_Node *keynav_node; + + /*current keynav node if any*/ + GF_List *env_tests; + /*hardware handle for 2D screen access - currently only used with win32 (HDC) */ void *hw_context; /*indicates whether HW is locked*/ @@ -282,6 +321,7 @@ struct __tag_compositor Bool video_memory; /*indicate if overlays were prezsent in the previous frame*/ Bool last_had_overlays; + GF_RasterCallback raster_callbacks; /*options*/ Bool scalable_zoom; @@ -294,6 +334,8 @@ struct __tag_compositor /*set if content doesn't allow navigation*/ Bool navigation_disabled; + u32 rotate_mode; + /*user mouse navigation state: 0: not active 1: pre-active phase: mouse has been clicked and waiting for mouse move to confirm. This allows @@ -327,7 +369,7 @@ struct __tag_compositor /*picked node*/ GF_Node *hit_node; /*appearance at hit point - used for composite texture*/ - GF_Node *hit_appear; + GF_Node *hit_appear, *prev_hit_appear; /*parent use stack - SVG only*/ GF_List *hit_use_stack, *prev_hit_use_stack; /*picked node uses DOM event or VRML events ?*/ @@ -435,12 +477,10 @@ struct __tag_compositor GF_List *cached_groups_queue; #endif - /*used for -depth dump*/ - Fixed OGLDepthGain; /*gain applied to OpenGL depth buffer, a float [0..1])*/ - Fixed OGLDepthOffset; /*offset applied to OpenGL depth buffer*/ - -#ifdef GPAC_TRISCOPE_MODE - void *RenoirHandler; +#ifdef GF_SR_USE_DEPTH + Bool auto_calibration; + /*display depth in pixels - if -1, it is the height of the display area*/ + s32 display_depth; #endif }; @@ -477,21 +517,23 @@ enum /*Set durin a composition cycle. If not set at the end of the cycle, the hardware binding is released*/ GF_SR_TEXTURE_USED = (1<<4), + + /*texture is SVG (needs special treatment in OpenGL)*/ + GF_SR_TEXTURE_SVG = (1<<5), }; typedef struct _gf_sc_texture_handler { GF_Node *owner; GF_Compositor *compositor; - /*low-level texture object - this is not exposed out of libgpac*/ + /*low-level texture object for internal rasterizer and OpenGL - this is not exposed out of libgpac*/ struct __texture_wrapper *tx_io; /*media stream*/ GF_MediaObject *stream; /*texture is open (for DEF/USE)*/ Bool is_open; - /*this is needed in case the Url is changed - note that media nodes cannot point to different - URLs (when they could in VRML), the MF is only holding media segment descriptions*/ - MFURL current_url; + /*this is needed in case the Url is changed*/ +// MFURL current_url; /*to override by each texture node*/ void (*update_texture_fcnt)(struct _gf_sc_texture_handler *txh); /*needs_release if a visual frame is grabbed (not used by modules)*/ @@ -517,20 +559,17 @@ typedef struct _gf_sc_texture_handler /*image data for natural media*/ char *data; u32 width, height, stride, pixelformat, pixel_ar; + +#ifndef GPAC_DISABLE_VRML /*if set texture has been transformed by MatteTexture -> disable blit*/ Bool has_cmat; /*matteTexture parent if any*/ GF_Node *matteTexture; - - -#ifdef GPAC_TRISCOPE_MODE - - void *RenoirObject; - #endif - - + + /*user data for video output module, if needed*/ + void *vout_udta; } GF_TextureHandler; /*setup texturing object*/ @@ -623,6 +662,7 @@ typedef struct _group_cache_candidate GF_CacheCandidate; #define MAX_USER_CLIP_PLANES 4 + /*the traversing context: set_up at top-level and passed through SFNode_Render. Each node is responsible for restoring the context state before returning*/ struct _traversing_state @@ -638,7 +678,7 @@ struct _traversing_state /*current traversing mode*/ u32 traversing_mode; /*for 2D drawing, indicates objects are to be drawn as soon as traversed, at each frame*/ - Bool direct_draw; + Bool immediate_draw; /*current subtree is part of a switched-off subtree (needed for audio)*/ Bool switched_off; /*set by the traversed subtree to indicate no cull shall be performed*/ @@ -660,9 +700,12 @@ struct _traversing_state /*the one and only visual manager currently being traversed*/ GF_VisualManager *visual; +#ifndef GPAC_DISABLE_VRML /*current background and viewport stacks*/ GF_List *backgrounds; GF_List *viewpoints; +#endif + /*current transformation from top-level*/ GF_Matrix2D transform; @@ -697,6 +740,7 @@ struct _traversing_state Bool ignore_strike; GF_List *use_stack; + /* Styling Property and others for SVG context */ #ifndef GPAC_DISABLE_SVG SVG_Number *parent_use_opacity; @@ -737,6 +781,7 @@ struct _traversing_state /*world ray for picking - in 2D, orig is 2D mouse pos and direction is -z*/ GF_Ray ray; + s32 pick_x, pick_y; /*we have 2 clippers, one for regular clipping (layout, form if clipping) which is maintained in world coord system and one for layer2D which is maintained in parent coord system (cf layer rendering). The layer clipper @@ -749,6 +794,7 @@ struct _traversing_state /*set when traversing a cached group during offscreen bitmap construction.*/ Bool in_group_cache; + Bool in_svg_filter; #ifndef GPAC_DISABLE_3D /*the current camera*/ @@ -757,10 +803,12 @@ struct _traversing_state /*current object (model) transformation from top-level, view is NOT included*/ GF_Matrix model_matrix; +#ifndef GPAC_DISABLE_VRML /*fog bind stack*/ - GF_List *fogs; /*holds fogs info*/ + GF_List *fogs; /*navigation bind stack*/ GF_List *navigations; +#endif /*when drawing, signals the mesh is transparent (enables blending)*/ Bool mesh_is_transparent; @@ -793,8 +841,10 @@ struct _traversing_state #endif - /*depth z-axis info for 2D scenes in triscope mode*/ - Fixed depth; +#ifdef GF_SR_USE_DEPTH + Fixed depth_gain, depth_offset; +#endif + #ifdef GF_SR_USE_VIDEO_CACHE /*set to 1 if cache evaluation can be skipped - this is only set when there is not enough memory @@ -841,7 +891,7 @@ void gf_mixer_add_input(GF_AudioMixer *am, GF_AudioInterface *src); void gf_mixer_remove_input(GF_AudioMixer *am, GF_AudioInterface *src); void gf_mixer_lock(GF_AudioMixer *am, Bool lockIt); /*mix inputs in buffer, return number of bytes written to output*/ -u32 gf_mixer_get_output(GF_AudioMixer *am, void *buffer, u32 buffer_size); +u32 gf_mixer_get_output(GF_AudioMixer *am, void *buffer, u32 buffer_size, u32 delay_ms); /*reconfig all sources if needed - returns TRUE if main audio config changed NOTE: this is called at each gf_mixer_get_output by the mixer. To call externally for audio hardware reconfiguration only*/ @@ -857,6 +907,35 @@ u32 gf_mixer_get_block_align(GF_AudioMixer *am); Bool gf_mixer_must_reconfig(GF_AudioMixer *am); Bool gf_mixer_empty(GF_AudioMixer *am); + +struct _audiofilterentry +{ + struct _audiofilterentry *next; + u32 in_block_size; + char *in_block; + u32 nb_bytes; + u32 delay_ms; + Bool enable, in_place; + GF_AudioFilter *filter; +}; + +typedef struct +{ + Bool enable_filters; + struct _audiofilterentry *filters; + /*filter processing takes place in a temp buffer since we don't know how many + samples a filter will output, and may ned to cache the output between 2 fill_buffer calls*/ + char *tmp_block1, *tmp_block2; + u32 min_block_size, max_block_size, delay_ms; + +} GF_AudioFilterChain; + +GF_Err gf_afc_load(GF_AudioFilterChain *afc, GF_User *user, char *filterstring); +GF_Err gf_afc_setup(GF_AudioFilterChain *afc, u32 bps, u32 sr, u32 chan, u32 ch_cfg, u32 *ch_out, u32 *ch_cfg_out); +u32 gf_afc_process(GF_AudioFilterChain *afc, u32 nb_bytes); +void gf_afc_unload(GF_AudioFilterChain *afc); +void gf_afc_reset(GF_AudioFilterChain *afc); + /*the audio renderer*/ typedef struct _audio_render { @@ -877,12 +956,16 @@ typedef struct _audio_render /*client*/ GF_User *user; + GF_List *audio_listeners; /*audio thread if output not self-threaded*/ GF_Thread *th; - /*thread state: 0: not intit, 1: running, 2: waiting for stop, 3: done*/ + /*thread state: 0: not init, 1: running, 2: waiting for stop, 3: done*/ u32 audio_th_state; - u32 audio_delay, volume, pan; + u32 audio_delay, volume, pan, mute; + + GF_AudioFilterChain filter_chain; + u32 nb_filled, nb_used; } GF_AudioRenderer; /*creates audio renderer*/ @@ -898,6 +981,9 @@ void gf_sc_ar_control(GF_AudioRenderer *ar, u32 CtrlType); /*set volume and pan*/ void gf_sc_ar_set_volume(GF_AudioRenderer *ar, u32 Volume); void gf_sc_ar_set_pan(GF_AudioRenderer *ar, u32 Balance); +/*mute/unmute audio*/ +void gf_sc_ar_mute(GF_AudioRenderer *ar, Bool mute); + /*set audio priority*/ void gf_sc_ar_set_priority(GF_AudioRenderer *ar, u32 priority); /*gets time in msec - this is the only clock used by the whole ESM system - depends on the audio driver*/ @@ -924,6 +1010,8 @@ typedef struct _soundinterface GF_Node *owner; } GF_SoundInterface; +typedef struct __audiofilteritem GF_AudioFilterItem; + /*audio common to AudioClip and AudioSource*/ typedef struct { @@ -936,15 +1024,17 @@ typedef struct Fixed speed, intensity; Bool stream_finished; Bool need_release; - MFURL url; u32 is_open; Bool is_muted; Bool register_with_renderer, register_with_parent; GF_SoundInterface *snd; + GF_AudioFilterItem *filter; } GF_AudioInput; /*setup interface with audio renderer - overwrite any functions needed after setup EXCEPT callback object*/ void gf_sc_audio_setup(GF_AudioInput *ai, GF_Compositor *sr, GF_Node *node); +/*unregister interface from renderer/mixer and stops source - deleteing the interface is the caller responsability*/ +void gf_sc_audio_predestroy(GF_AudioInput *ai); /*open audio object*/ GF_Err gf_sc_audio_open(GF_AudioInput *ai, MFURL *url, Double clipBegin, Double clipEnd); /*closes audio object*/ @@ -981,12 +1071,12 @@ GF_Err compositor_2d_set_aspect_ratio(GF_Compositor *sr); void compositor_2d_set_user_transform(GF_Compositor *sr, Fixed zoom, Fixed tx, Fixed ty, Bool is_resize) ; GF_Err compositor_2d_get_video_access(GF_VisualManager *surf); void compositor_2d_release_video_access(GF_VisualManager *surf); -Bool compositor_2d_draw_bitmap(GF_VisualManager *visual, GF_TraverseState *tr_state, struct _drawable_context *ctx, GF_ColorKey *col_key); +void compositor_2d_init_callbacks(GF_Compositor *compositor); GF_Rect compositor_2d_update_clipper(GF_TraverseState *tr_state, GF_Rect this_clip, Bool *need_restore, GF_Rect *original, Bool for_layer); Bool compositor_get_2d_plane_intersection(GF_Ray *ray, SFVec3f *res); -void compositor_send_resize_event(GF_Compositor *compositor, Fixed old_z, Fixed old_tx, Fixed old_ty, Bool is_resize); +void compositor_send_resize_event(GF_Compositor *compositor, GF_SceneGraph *subscene, Fixed old_z, Fixed old_tx, Fixed old_ty, Bool is_resize); void compositor_set_cache_memory(GF_Compositor *compositor, u32 memory); /*checks whether the background node is transparent or not*/ @@ -1011,6 +1101,7 @@ void gf_sc_load_opengl_extensions(GF_Compositor *sr); Bool gf_sc_exec_event(GF_Compositor *sr, GF_Event *evt); void gf_sc_get_nodes_bounds(GF_Node *self, GF_ChildNodeItem *children, GF_TraverseState *tr_state, s32 *child_idx); +Bool gf_sc_exec_event_vrml(GF_Compositor *compositor, GF_Event *ev); void gf_sc_visual_register(GF_Compositor *sr, GF_VisualManager *surf); void gf_sc_visual_unregister(GF_Compositor *sr, GF_VisualManager *surf); @@ -1024,6 +1115,12 @@ void compositor_set_ar_scale(GF_Compositor *sr, Fixed scaleX, Fixed scaleY); /*reset focus if node being deleted has the focus - must be called for each focusable node (internally called for 2D & 3D drawable nodes)*/ void gf_sc_check_focus_upon_destroy(GF_Node *n); +void gf_sc_key_navigator_del(GF_Compositor *sr, GF_Node *n); +void gf_sc_change_key_navigator(GF_Compositor *sr, GF_Node *n); +GF_Node *gf_scene_get_keynav(GF_SceneGraph *sg, GF_Node *sensor); +const char *gf_scene_get_service_url(GF_SceneGraph *sg); +Bool gf_scene_lock(GF_SceneGraph *sg, Bool do_lock); + #ifndef GPAC_DISABLE_SVG void compositor_svg_build_gradient_texture(GF_TextureHandler *txh); @@ -1151,5 +1248,48 @@ void gf_font_spans_get_selection(GF_Node *node, GF_List *spans, GF_TraverseState GF_Font *gf_compositor_svg_set_font(GF_FontManager *fm, char *a_font, u32 styles, Bool check_only); + +u32 gf_sc_focus_switch_ring(GF_Compositor *compositor, Bool move_prev); + +Bool compositor_handle_navigation(GF_Compositor *compositor, GF_Event *ev); + +void gf_sc_next_frame_state(GF_Compositor *compositor, u32 state); + + +#ifdef GPAC_USE_TINYGL +void gf_get_tinygl_depth(GF_TextureHandler *txh); +#endif + + + +typedef struct +{ + void *udta; + /*called when new video frame is ready to be flushed on screen. time is the terminal global clock in ms*/ + void (*on_video_frame)(void *udta, u32 time); + /*called when video output has been resized*/ + void (*on_video_reconfig)(void *udta, u32 width, u32 height); +} GF_VideoListener; + +GF_Err gf_sc_add_video_listener(GF_Compositor *compositor, GF_VideoListener *vl); +GF_Err gf_sc_remove_video_listener(GF_Compositor *compositor, GF_VideoListener *vl); + +typedef struct +{ + void *udta; + /*called when audio frame is ready to be sent to the sound card. + @buffer, @buffer_size: audio buffer + @time: the terminal global clock in ms + @delay: Due to sound card latencies, audio is sent to the sound card delay milliseconds earlier than + its associated video. + */ + void (*on_audio_frame)(void *udta, char *buffer, u32 buffer_size, u32 time, u32 delay); + /*called when audio output has been reconfigured*/ + void (*on_audio_reconfig)(void *udta, u32 samplerate, u32 bits_per_sample, u32 nb_channel, u32 channel_cfg); +} GF_AudioListener; + +GF_Err gf_sc_add_audio_listener(GF_Compositor *compositor, GF_AudioListener *al); +GF_Err gf_sc_remove_audio_listener(GF_Compositor *compositor, GF_AudioListener *al); + #endif /*_COMPOSITOR_DEV_H_*/ diff --git a/include/gpac/internal/config_static.h b/include/gpac/internal/config_static.h deleted file mode 100644 index 2dcd660..0000000 --- a/include/gpac/internal/config_static.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * Copyright (c) ENST 2008 - - * 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_CONFIG_H_ -#define _GF_CONFIG_H_ - -/*this file defines all common macros for libgpac compilation*/ - -/*platform is big endian*/ -//#define GPAC_BIG_ENDIAN - -/*SSL enabled*/ -//#define GPAC_HAS_SSL - -/*spidermonkey enabled*/ -#define GPAC_HAS_SPIDERMONKEY - -/*libjpeg enabled*/ -#define GPAC_HAS_JPEG - -/*pnj enabled*/ -#define GPAC_HAS_PNG - -/*IPv6 enabled - for win32, this is evaluated at compile time, !! do not uncomment !!*/ -//#define GPAC_HAS_IPV6 - -/*SVG disabled*/ -//#define GPAC_DISABLE_SVG - -/*3D compositor disabled*/ -//#define GPAC_DISABLE_3D - -/*use TinyGL instead of OpenGL*/ -//#define GPAC_USE_TINYGL - -/*use OpenGL ES instead of OpenGL*/ -//#define GPAC_USE_OGL_ES - - -#if defined(_WIN32_WCE) - -/*use intel fixed-point*/ -//#define GPAC_USE_IGPP -/*use intel fixed-point with high precision*/ -//#define GPAC_USE_IGPP_HP - -#if defined(GPAC_USE_IGPP) && defined(GPAC_USE_IGPP_HP) -#error "Only one of GPAC_USE_IGPP and GPAC_USE_IGPP_HP can be defined" -#endif - - -#if !defined(GPAC_DISABLE_3D) && !defined(GPAC_USE_TINYGL) && !defined(GPAC_USE_OGL_ES) -#define GPAC_USE_OGL_ES -#endif - -#endif - - -#if !defined(GPAC_USE_OGL_ES) && !defined(GPAC_USE_TINYGL) -#define GPAC_HAS_GLU -#endif - - - -#endif /*_GF_CONFIG_H_*/ - diff --git a/include/gpac/internal/crypt_dev.h b/include/gpac/internal/crypt_dev.h index 79d6c25..9244b1e 100644 --- a/include/gpac/internal/crypt_dev.h +++ b/include/gpac/internal/crypt_dev.h @@ -31,14 +31,12 @@ extern "C" { #include +#ifndef GPAC_DISABLE_MCRYPT + /*the samllest version of the lib: only AES-128-CTR supported*/ #define GPAC_CRYPT_ISMA_ONLY -#if !defined(GPAC_CRYPT_ISMA_ONLY) && defined(GPAC_READ_ONLY) -#define GPAC_CRYPT_ISMA_ONLY -#endif - typedef void (*mcryptfunc)(void*,void*); typedef GF_Err (*mcrypt_setkeystream)(void *, const void *, int, const void *, int); typedef GF_Err (*mcrypt_setkeyblock) (void *, const void *, int); @@ -149,6 +147,7 @@ void memxor(unsigned char *o1, unsigned char *o2, int length) #define Bzero(x, y) memset(x, 0, y) +#endif /*GPAC_DISABLE_MCRYPT*/ #ifdef __cplusplus } diff --git a/include/gpac/internal/dvb_mpe_dev.h b/include/gpac/internal/dvb_mpe_dev.h new file mode 100644 index 0000000..8435227 --- /dev/null +++ b/include/gpac/internal/dvb_mpe_dev.h @@ -0,0 +1,259 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Walid B.H - Jean Le Feuvre + * Copyright (c)2006-200X ENST - 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 + * 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. + * + * 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 gf_free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#ifndef _GF_DVB_MPE_DEV_H_ +#define _GF_DVB_MPE_DEV_H_ + +#include +#include + + +/*INT object*/ +typedef struct +{ + u32 id; + u32 processing_order; + u32 number_of_descriptor; + GF_List * descriptors; + +} GF_M2TS_INT; + +typedef struct +{ + u32 tag; + u32 length; + u32 network_id; + u32 original_network_id; + u32 ts_id; + u32 service_id; + u32 component_tag; + +}GF_M2TS_LOC_DSCPTR_IP_STREAM; + +typedef struct descriptor_TimeSliceFec +{ + Bool time_slicing; + u8 mpe_fec; + u8 frame_size; + u8 max_burst_duration; + u8 max_average_rate; + u8 time_slice_fec_id; + u8 * id_selector; +}GF_M2TS_DesTimeSliceFec; + +typedef struct +{ + u16 network_id; + u16 original_network_id; + u16 transport_stream_id; + u16 service_id; + u8 component_tag; +}GF_M2TS_DesLocation; + +typedef struct { + u8 type; /* 0 = target_IP_descriptor, 1 = target_IP_address_descriptor */ + u32 address_mask; + u8 address[4]; + u8 slash_mask; + u32 rx_port[10]; /* list of the adress port */ +} GF_M2TS_IP_Target; + +typedef struct +{ + GF_List *targets; /* list of IP destination for the IP streams in the platform */ + u32 PID; + Bool stream_info_gathered; + + /* location descriptor only valid for the associated targets */ + GF_M2TS_DesLocation location; + + GF_M2TS_DesTimeSliceFec time_slice_fec; +} GF_M2TS_IP_Stream; + + +/*IP_Platform object*/ +typedef struct __gf_dvb_mpe_ip_platform +{ +/* remaining from INT, to be delete */ + u32 id; + u32 processing_order; + u32 number_of_descriptor; + + u8 *name; /* platform name */ + u8 *provider_name; /* platform provider name */ + + /* location descriptor valid for the whole platform */ + GF_M2TS_DesLocation *location; + + GF_List * ip_streams; + Bool all_info_gathered; + GF_List *socket_struct; + +} GF_M2TS_IP_PLATFORM; + +typedef struct +{ + char *data; /* Data */ + u32 u32_version; /* IP version */ + u32 u32_hdr_length; /* header length by piece of 4 bytes */ + u32 u32_total_length; /* the length of the datagram (hdr+payload) in bytes */ + u32 u32_payload_size; /* the length of the payload */ + u32 u32_id_nb; /* the number of the paquet, in case of frag */ + u32 u32_flag; /* if 010 unfrag packet, 100 fragmented packet, check the id_nb to know the packet number. + 0 is the last one */ + u32 u32_frag_offset; /* The offset position of this packet compare to the first packet. unit : 8 bytes */ + u32 u32_TTL; /* (Time To Live) when = 0 , the packet is ignored and error message */ + u32 u32_protocol; /* TCP = 6, UDP = 17, ICMP = 1 */ + u32 u32_crc; + u8 u8_tx_adr[4]; /* source adress */ + u8 u8_rx_adr[4]; /* destination adress */ + u32 u32_size_option; /* size of the option before payload */ + u32 u32_padding; /* = 1 if where read padding columns */ + u32 u32_sum; + + /* UDP */ + u32 u32_tx_udp_port; /* source port */ + u32 u32_rx_udp_port; /* destination port */ + u32 u32_udp_data_size; + u32 u32_udp_chksm; + GF_Socket *sock; /* socket of the */ + +}GF_M2TS_IP_Packet; + + + + +#define MPE_ADT_COLS 191 +#define MPE_RS_COLS NPAR + +typedef struct mpe_error_holes +{ + u32 offset; + u32 length; + +}MPE_Error_Holes; + +typedef struct mpe_fec_frame +{ + u32 rows; + u32 col_adt ; + u32 col_rs ; + u8 *p_adt; /* pointer to the application data table*/ + u8 *p_rs; /* pointer to the RS data table*/ + u32 *p_error_adt; + u32 *p_error_rs ; + + u32 capacity_total; + u32 current_offset_adt ; + u32 current_offset_rs; + u32 initialized ; + u8 ADT_done; + u32 PID; + GF_List *mpe_holes; + //u32 erasures [] p_erasures; /*pointer to the error indicators*/ +} MPE_FEC_FRAME; + + +/* Get INT table */ +void gf_m2ts_process_int(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ip_table, unsigned char *data, u32 data_size, u32 table_id); + +void section_DSMCC_INT(GF_M2TS_IP_PLATFORM* ip_platform, u8 *data, u32 data_size); + +u32 platform_descriptorDSMCC_INT_UNT (GF_M2TS_IP_PLATFORM* ip_platform,u8 *data); +u32 dsmcc_pto_platform_descriptor_loop (GF_M2TS_IP_PLATFORM* ip_platform,u8 *data); + +u32 descriptorDSMCC_INT_UNT (GF_M2TS_IP_Stream *ip_str,u8 *data); +void descriptorDSMCC_target_IP_address ( GF_M2TS_IP_Stream *ip_str, u8 *data); +u32 dsmcc_pto_descriptor_loop (GF_M2TS_IP_Stream *ip_str, u8 *data); +void descriptorTime_slice_fec_identifier(GF_M2TS_IP_Stream *ip_str, u8 *data); +void gf_m2ts_target_ip( GF_M2TS_IP_Stream* ip_str, u8 *data); +void descriptorLocation(GF_M2TS_IP_Stream *ip_str , u8 *data); + + +void gf_ip_platform_descriptor(GF_M2TS_IP_PLATFORM* ip_platform, u8 *data); +void gf_ip_platform_provider_descriptor(GF_M2TS_IP_PLATFORM* ip_platform,u8 *data); +void gf_m2ts_ip_platform_init(GF_M2TS_IP_PLATFORM * ip_platform); + +u32 gf_m2ts_ipdatagram_reader(u8 *datagram, GF_M2TS_IP_Packet *ip_packet, u32 offset); +void gf_m2ts_process_ipdatagram(MPE_FEC_FRAME *mff,GF_M2TS_Demuxer *ts); +Bool gf_m2ts_compare_ip(u8 rx_ip_adress[4], u8 ip_adress_bootstrap[4]); + +struct _sock_entry +{ + u32 ipv4_addr; + u16 port; + GF_Socket *sock; + Bool bind_failure; +}; +struct tag_m2ts_section_mpe +{ + ABSTRACT_ES + GF_M2TS_SectionFilter *sec; + + /* if this stream is an MPE section stream, we need: + - a direct access to the timeslice fec descriptor + - an MPE FEC Frame Structure to process RS code */ + GF_M2TS_IP_Stream *ip_platform; + MPE_FEC_FRAME *mff; + +}; + + +void gf_m2ts_process_mpe(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_MPE *mpe, unsigned char *data, u32 data_size, u8 table_id); +void gf_m2ts_gather_ipdatagram_information(MPE_FEC_FRAME *mff,GF_M2TS_Demuxer *ts); + +void socket_simu(GF_M2TS_IP_Packet *ip_packet, GF_M2TS_Demuxer *ts); + + +/* allocate the necessary memory space*/ +u32 init_frame(MPE_FEC_FRAME * mff, u32 rows); + +void getRowFromADT(MPE_FEC_FRAME * mff,u32 index, u8 * adt_row); +void getRowFromRS(MPE_FEC_FRAME * mff,u32 index, u8 * rs_row); +void setRowRS(MPE_FEC_FRAME * mff,u32 index, u8 * p_rs); + +/*return the number of errors and the position of the error in the row*/ +void getErrorPositions(MPE_FEC_FRAME * mff, u32 row, u32 * errPositions); + +void setColRS( MPE_FEC_FRAME * mff, u32 offset, u8 * pds, u32 length ); +void getColRS(MPE_FEC_FRAME * mff, u32 offset, u8 * pds, u32 length); +void setIpDatagram(MPE_FEC_FRAME * mff,u32 offset, u8 * dgram, u32 length ); + +void setErrorIndicator(u32 * data , u32 offset1, u32 length ); +void resetMFF(MPE_FEC_FRAME * mff) ; +u32 getErrasurePositions( MPE_FEC_FRAME *mff , u32 row, u32 *errasures); + +void decode_fec(MPE_FEC_FRAME * mff); + + +// Descriptor tag space/scope... +typedef enum { + MPEG, DVB_SI, + DSMCC_STREAM, DSMCC_CAROUSEL, DSMCC_INT_UNT, MHP_AIT, TVA_RNT +} DTAG_SCOPE; + +void descriptor_PRIVATE (u8 *b, DTAG_SCOPE tag_scope, GF_List * descriptors ); + +#endif //_GF_DVB_MPE_DEV_H_ diff --git a/include/gpac/internal/ietf_dev.h b/include/gpac/internal/ietf_dev.h index 41ebf66..3542ef1 100644 --- a/include/gpac/internal/ietf_dev.h +++ b/include/gpac/internal/ietf_dev.h @@ -26,6 +26,9 @@ #define _GF_IETF_DEV_H_ #include + +#ifndef GPAC_DISABLE_STREAMING + #include /* @@ -130,6 +133,7 @@ struct __tag_rtp_channel u32 last_pck_ntp_sec, last_pck_ntp_frac; u32 num_pck_sent, num_payload_bytes; + Bool no_auto_rtcp; /*RTCP info*/ char *s_name, *s_email, *s_location, *s_phone, *s_tool, *s_note, *s_priv; // s8 first_rtp_pck; @@ -138,6 +142,8 @@ struct __tag_rtp_channel u32 SenderSSRC; u32 last_pck_sn; + /*indicates if a packet loss is detected between current and previous packet*/ + Bool packet_loss; char *CName; @@ -179,7 +185,7 @@ void gf_rtp_get_next_report_time(GF_RTPChannel *ch); if (str) { \ if (strlen((const char *) str)+pos >= buf_size) { \ buf_size += RTSP_WRITE_STEPALLOC; \ - buf = (char *) realloc(buf, buf_size); \ + buf = (char *) gf_realloc(buf, buf_size); \ } \ strcpy(buf+pos, (const char *) str); \ pos += strlen((const char *) str); \ @@ -312,7 +318,9 @@ GF_Err gf_rtsp_http_tunnel_start(GF_RTSPSession *sess, char *UserAgent); GF_Err gp_rtp_builder_do_mpeg4(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); GF_Err gp_rtp_builder_do_h263(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); GF_Err gp_rtp_builder_do_amr(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); +#ifndef GPAC_DISABLE_AV_PARSERS GF_Err gp_rtp_builder_do_mpeg12_video(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); +#endif GF_Err gp_rtp_builder_do_mpeg12_audio(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize, u32 duration, u8 descIndex); GF_Err gp_rtp_builder_do_avc(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); @@ -323,5 +331,7 @@ GF_Err gp_rtp_builder_do_dims(GP_RTPPacketizer *builder, char *data, u32 data_si GF_Err gp_rtp_builder_do_ac3(GP_RTPPacketizer *builder, char *data, u32 data_size, u8 IsAUEnd, u32 FullAUSize); +#endif /*GPAC_DISABLE_STREAMING*/ + #endif /*_GF_IETF_DEV_H_*/ diff --git a/include/gpac/internal/isomedia_dev.h b/include/gpac/internal/isomedia_dev.h index bb38ee9..d738e53 100644 --- a/include/gpac/internal/isomedia_dev.h +++ b/include/gpac/internal/isomedia_dev.h @@ -31,6 +31,8 @@ extern "C" { #include +#ifndef GPAC_DISABLE_ISOM + //the default size is 64, cause we need to handle large boxes... #define GF_ISOM_BOX \ @@ -131,7 +133,7 @@ enum GF_ISOM_BOX_TYPE_PDIN = GF_4CC( 'p', 'd', 'i', 'n' ), GF_ISOM_BOX_TYPE_SDTP = GF_4CC( 's', 'd', 't', 'p' ), -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS /*Movie Fragments*/ GF_ISOM_BOX_TYPE_MVEX = GF_4CC( 'm', 'v', 'e', 'x' ), GF_ISOM_BOX_TYPE_MEHD = GF_4CC( 'm', 'e', 'h', 'd' ), @@ -161,8 +163,15 @@ enum GF_ISOM_BOX_TYPE_AVCC = GF_4CC( 'a', 'v', 'c', 'C' ), GF_ISOM_BOX_TYPE_BTRT = GF_4CC( 'b', 't', 'r', 't' ), GF_ISOM_BOX_TYPE_M4DS = GF_4CC( 'm', '4', 'd', 's' ), - GF_ISOM_BOX_TYPE_AVC1 = GF_4CC( 'a', 'v', 'c', '1' ), GF_ISOM_BOX_TYPE_PASP = GF_4CC( 'p', 'a', 's', 'p' ), + GF_ISOM_BOX_TYPE_AVC1 = GF_4CC( 'a', 'v', 'c', '1' ), + GF_ISOM_BOX_TYPE_AVC2 = GF_4CC( 'a', 'v', 'c', '2' ), + GF_ISOM_BOX_TYPE_SVCC = GF_4CC( 's', 'v', 'c', 'C' ), + GF_ISOM_BOX_TYPE_SVC1 = GF_4CC( 's', 'v', 'c', '1' ), + + /*LASeR extension*/ + GF_ISOM_BOX_TYPE_LSRC = GF_4CC( 'l', 's', 'r', 'C' ), + GF_ISOM_BOX_TYPE_LSR1 = GF_4CC( 'l', 's', 'r', '1' ), /*3GPP extensions*/ GF_ISOM_BOX_TYPE_DAMR = GF_4CC( 'd', 'a', 'm', 'r' ), @@ -172,6 +181,12 @@ enum GF_ISOM_BOX_TYPE_DSMV = GF_4CC( 'd', 's', 'm', 'v' ), GF_ISOM_BOX_TYPE_TSEL = GF_4CC( 't', 's', 'e', 'l' ), + /* 3GPP Adaptive Streaming extensions */ + GF_ISOM_BOX_TYPE_STYP = GF_4CC( 's', 't', 'y', 'p' ), + GF_ISOM_BOX_TYPE_TFAD = GF_4CC( 't', 'f', 'a', 'd' ), + GF_ISOM_BOX_TYPE_TFMA = GF_4CC( 't', 'f', 'm', 'a' ), + GF_ISOM_BOX_TYPE_SIDX = GF_4CC( 's', 'i', 'd', 'x' ), + /*3GPP text / MPEG-4 StreamingText*/ GF_ISOM_BOX_TYPE_FTAB = GF_4CC( 'f', 't', 'a', 'b' ), GF_ISOM_BOX_TYPE_TX3G = GF_4CC( 't', 'x', '3', 'g' ), @@ -271,6 +286,7 @@ enum GF_ISOM_HANDLER_TYPE_MDIR = GF_4CC( 'm', 'd', 'i', 'r' ), GF_ISOM_BOX_TYPE_CHAP = GF_4CC( 'c', 'h', 'a', 'p' ), + GF_ISOM_BOX_TYPE_TEXT = GF_4CC( 't', 'e', 'x', 't' ), /*OMA (P)DCF boxes*/ GF_ISOM_BOX_TYPE_OHDR = GF_4CC( 'o', 'h', 'd', 'r' ), @@ -402,7 +418,7 @@ typedef struct GF_MovieHeaderBox *mvhd; GF_ObjectDescriptorBox *iods; GF_UserDataBox *udta; -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS struct __tag_mvex_box *mvex; #endif /*meta box if any*/ @@ -461,6 +477,11 @@ typedef struct char *name; /*private for editing*/ Bool is_unpacked; + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + u64 dts_at_seg_start; + u32 sample_count_at_seg_start; +#endif } GF_TrackBox; typedef struct @@ -584,7 +605,7 @@ typedef struct GF_SttsEntry *entries; u32 nb_entries, alloc_size; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*cache for WRITE*/ u32 w_currentSampleNum; u64 w_LastDTS; @@ -609,7 +630,7 @@ typedef struct GF_DttsEntry *entries; u32 nb_entries, alloc_size; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE u32 w_LastSampleNumber; /*force one sample per entry*/ Bool unpack_mode; @@ -631,7 +652,7 @@ typedef struct { GF_ISOM_FULL_BOX GF_List *entryList; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*Cache for write*/ GF_StsfEntry *w_currentEntry; u32 w_currentEntryIndex; @@ -670,7 +691,21 @@ typedef struct GF_ESD *desc; } GF_ESDBox; -/*for all MPEG4 media except audio and video*/ +typedef struct +{ + GF_ISOM_BOX + u32 bufferSizeDB; + u32 maxBitrate; + u32 avgBitrate; +} GF_MPEG4BitRateBox; + +typedef struct +{ + GF_ISOM_BOX + GF_List *descriptors; +} GF_MPEG4ExtensionDescriptorsBox; + +/*for most MPEG4 media */ typedef struct { GF_ISOM_SAMPLE_ENTRY_FIELDS @@ -679,6 +714,28 @@ typedef struct GF_SLConfig *slc; } GF_MPEGSampleEntryBox; +typedef struct +{ + GF_ISOM_BOX + char *hdr; + u32 hdr_size; +} GF_LASERConfigurationBox; + + +typedef struct +{ + GF_ISOM_SAMPLE_ENTRY_FIELDS + + GF_LASERConfigurationBox *lsr_config; + GF_MPEG4BitRateBox *bitrate; + GF_MPEG4ExtensionDescriptorsBox *descr; + + /*used for hinting when extracting the OD stream...*/ + GF_SLConfig *slc; +} GF_LASeRSampleEntryBox; + +GF_Err LSR_UpdateESD(GF_LASeRSampleEntryBox *lsr, GF_ESD *esd); + typedef struct { GF_ISOM_BOX @@ -710,25 +767,11 @@ typedef struct void gf_isom_video_sample_entry_init(GF_VisualSampleEntryBox *ent); GF_Err gf_isom_video_sample_entry_read(GF_VisualSampleEntryBox *ptr, GF_BitStream *bs); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE void gf_isom_video_sample_entry_write(GF_VisualSampleEntryBox *ent, GF_BitStream *bs); void gf_isom_video_sample_entry_size(GF_VisualSampleEntryBox *ent); #endif -typedef struct -{ - GF_ISOM_BOX - u32 bufferSizeDB; - u32 maxBitrate; - u32 avgBitrate; -} GF_MPEG4BitRateBox; - -typedef struct -{ - GF_ISOM_BOX - GF_List *descriptors; -} GF_MPEG4ExtensionDescriptorsBox; - typedef struct { GF_ISOM_BOX @@ -744,6 +787,7 @@ typedef struct /*avc extensions - we merged with regular 'mp4v' box to handle isma E&A signaling of AVC*/ GF_AVCConfigurationBox *avc_config; + GF_AVCConfigurationBox *svc_config; GF_MPEG4BitRateBox *bitrate; /*ext descriptors*/ GF_MPEG4ExtensionDescriptorsBox *descr; @@ -787,7 +831,7 @@ typedef struct void gf_isom_audio_sample_entry_init(GF_AudioSampleEntryBox *ptr); GF_Err gf_isom_audio_sample_entry_read(GF_AudioSampleEntryBox *ptr, GF_BitStream *bs); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE void gf_isom_audio_sample_entry_write(GF_AudioSampleEntryBox *ptr, GF_BitStream *bs); void gf_isom_audio_sample_entry_size(GF_AudioSampleEntryBox *ptr); #endif @@ -1097,6 +1141,22 @@ typedef struct GF_BoxRecord default_box; GF_StyleRecord default_style; GF_FontTableBox *font_table; +} GF_Tx3gSampleEntryBox; + +/*Apple specific*/ +typedef struct +{ + GF_ISOM_SAMPLE_ENTRY_FIELDS \ + u32 displayFlags; + u32 textJustification; + char background_color[6], foreground_color[6]; + GF_BoxRecord default_box; + u16 fontNumber; + u16 fontFace; + char reserved1[8]; + u8 reserved2; + u16 reserved3; + char *textName; /*font name*/ } GF_TextSampleEntryBox; typedef struct @@ -1198,7 +1258,7 @@ typedef struct { u64 extent_offset; u64 extent_length; -#ifndef GPAC_READ_OLNLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*for storage only*/ u64 original_extent_offset; #endif @@ -1209,7 +1269,7 @@ typedef struct u16 item_ID; u16 data_reference_index; u64 base_offset; -#ifndef GPAC_READ_OLNLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*for storage only*/ u64 original_base_offset; #endif @@ -1333,7 +1393,7 @@ typedef struct __tag_meta_box -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS /*V2 boxes - Movie Fragments*/ @@ -1378,6 +1438,10 @@ typedef struct GF_MovieFragmentHeaderBox *mfhd; GF_List *TrackList; GF_ISOFile *mov; + /*offset in the file of moof or mdat (whichever comes first) for this fragment*/ + u64 fragment_offset; + u32 mdat_size; + char *mdat; } GF_MovieFragmentBox; @@ -1413,8 +1477,10 @@ typedef struct GF_List *TrackRuns; /*keep a pointer to default flags*/ GF_TrackExtendsBox *trex; + GF_SampleDependencyTypeBox *sdtp; /*when data caching is on*/ u32 DataCache; + GF_Box *tfad; } GF_TrackFragmentBox; /*FLAGS for TRUN : specify what is written in the SampleTable of TRUN*/ @@ -1450,7 +1516,16 @@ typedef struct u32 CTS_Offset; } GF_TrunEntry; -#endif +typedef struct +{ + GF_ISOM_BOX + u32 majorBrand; + u32 minorVersion; + u32 altCount; + u32 *altBrand; +} GF_SegmentTypeBox; + +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ /*RTP Hint Track Sample Entry*/ @@ -1730,7 +1805,28 @@ typedef struct __oma_kms_box GF_OMADRMAUFormatBox *fmt; } GF_OMADRMKMSBox; +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS +typedef struct +{ + Bool reference_type; + u32 reference_offset; + u32 subsegment_duration; + Bool contains_RAP; + u32 RAP_delta_time; +} GF_SIDXReference; + +typedef struct __sidx_box +{ + GF_ISOM_FULL_BOX + + u32 reference_track_ID; + u32 nb_track_times; + GF_SIDXTrackTimes *tracks_times; + u32 nb_refs; + GF_SIDXReference *refs; +} GF_SegmentIndexBox; +#endif /* Data Map (media storage) stuff @@ -1775,7 +1871,7 @@ typedef struct GF_ISOM_BASE_DATA_HANDLER FILE *stream; Bool last_acces_was_read; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE char *temp_file; #endif } GF_FileDataMap; @@ -1785,9 +1881,9 @@ typedef struct { GF_ISOM_BASE_DATA_HANDLER char *name; - u32 file_size; + u64 file_size; char *byte_map; - u32 byte_pos; + u64 byte_pos; } GF_FileMappingDataMap; GF_Err gf_isom_datamap_new(const char *location, const char *parentPath, u8 mode, GF_DataMap **outDataMap); @@ -1801,7 +1897,7 @@ GF_DataMap *gf_isom_fdm_new(const char *sPath, u8 mode); void gf_isom_fdm_del(GF_FileDataMap *ptr); u32 gf_isom_fdm_get_data(GF_FileDataMap *ptr, char *buffer, u32 bufferLength, u64 fileOffset); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_DataMap *gf_isom_fdm_new_temp(const char *sTempPath); #endif @@ -1810,7 +1906,7 @@ GF_DataMap *gf_isom_fmo_new(const char *sPath, u8 mode); void gf_isom_fmo_del(GF_FileMappingDataMap *ptr); u32 gf_isom_fmo_get_data(GF_FileMappingDataMap *ptr, char *buffer, u32 bufferLength, u64 fileOffset); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE u64 gf_isom_datamap_get_offset(GF_DataMap *map); GF_Err gf_isom_datamap_add_data(GF_DataMap *ptr, char *data, u32 dataSize); #endif @@ -1821,9 +1917,9 @@ GF_Err gf_isom_datamap_add_data(GF_DataMap *ptr, char *data, u32 dataSize); /*time def for MP4/QT/MJ2K files*/ -#define GF_ISOM_MAC_TIME_OFFSET 2082758400/*208284480 */ +#define GF_ISOM_MAC_TIME_OFFSET 2082844800 -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS #define GF_ISOM_FORMAT_FRAG_FLAGS(pad, sync, deg) ( ( (pad) << 17) | ( ( !(sync) ) << 16) | (deg) ); #define GF_ISOM_GET_FRAG_PAD(flag) ( (flag) >> 17) & 0x7 #define GF_ISOM_GET_FRAG_SYNC(flag) ( ! ( ( (flag) >> 16) & 0x1)) @@ -1849,7 +1945,7 @@ struct __tag_isom { the moov*/ GF_DataMap *movieFileMap; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*the final file name*/ char *finalName; /*the file where we store edited samples (for READ_WRITE and WRITE mode only)*/ @@ -1876,13 +1972,17 @@ struct __tag_isom { /*meta box if any*/ GF_MetaBox *meta; -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS u32 FragmentsFlags, NextMoofNumber; /*active fragment*/ GF_MovieFragmentBox *moof; /*in WRITE mode, this is the current MDAT where data is written*/ /*in READ mode this is the last valid file position before a gf_isom_box_read failed*/ u64 current_top_box_start; + u64 segment_start; + + GF_List *moof_list; + Bool use_segments, moof_first; #endif /*this contains ALL the root boxes excepts fragments*/ @@ -1961,7 +2061,7 @@ GF_Err gf_isom_rewrite_text_sample(GF_ISOSample *samp, u32 sampleDescriptionInde GF_UserDataMap *udta_getEntry(GF_UserDataBox *ptr, u32 box_type, bin128 *uuid); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err FlushCaptureMode(GF_ISOFile *movie); GF_Err CanAccessMovie(GF_ISOFile *movie, u32 Mode); @@ -2019,11 +2119,11 @@ GF_Err stbl_RemovePaddingBits(GF_SampleTableBox *stbl, u32 SampleNumber); GF_Err stbl_RemoveSampleFragments(GF_SampleTableBox *stbl, u32 sampleNumber); GF_Err stbl_RemoveRedundant(GF_SampleTableBox *stbl, u32 SampleNumber); -#ifndef GPAC_ISOM_NO_FRAGMENTS -GF_Err StoreFragment(GF_ISOFile *movie); +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS +GF_Err gf_isom_close_fragments(GF_ISOFile *movie); #endif -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Err GetNextMediaTime(GF_TrackBox *trak, u64 movieTime, u64 *OutMovieTime); @@ -2057,6 +2157,8 @@ void AVC_RewriteESDescriptor(GF_MPEGVisualSampleEntryBox *avc); GF_Err reftype_AddRefTrack(GF_TrackReferenceTypeBox *ref, u32 trackID, u16 *outRefIndex); +#ifndef GPAC_DISABLE_ISOM_HINTING + /* Hinting stuff */ @@ -2154,6 +2256,7 @@ GF_Err gf_isom_hint_sample_read(GF_HintSample *ptr, GF_BitStream *bs, u32 sample GF_Err gf_isom_hint_sample_write(GF_HintSample *ptr, GF_BitStream *bs); u32 gf_isom_hint_sample_size(GF_HintSample *ptr); + /***************************************************** Hint Packets (generic packet for future protocol support) *****************************************************/ @@ -2206,6 +2309,8 @@ GF_Err gf_isom_hint_rtp_offset(GF_RTPPacket *ptr, u32 offset, u32 HintSampleNumb u32 gf_isom_hint_rtp_length(GF_RTPPacket *ptr); +#endif + struct _3gpp_text_sample { @@ -2484,6 +2589,7 @@ GF_Err void_Read(GF_Box *s, GF_BitStream *bs); GF_Err stsf_Read(GF_Box *s, GF_BitStream *bs); GF_Err pdin_Read(GF_Box *s, GF_BitStream *bs); +#ifndef GPAC_DISABLE_ISOM_HINTING GF_Box *hinf_New(); GF_Box *trpy_New(); @@ -2615,6 +2721,8 @@ GF_Err hnti_Size(GF_Box *s); GF_Err sdp_Size(GF_Box *s); GF_Err rtpo_Size(GF_Box *s); +#endif + GF_Box *ftyp_New(); void ftyp_del(GF_Box *s); @@ -2637,7 +2745,7 @@ void gppc_del(GF_Box *s); GF_Err gppa_Read(GF_Box *s, GF_BitStream *bs); GF_Err gppv_Read(GF_Box *s, GF_BitStream *bs); GF_Err gppc_Read(GF_Box *s, GF_BitStream *bs); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gppa_Write(GF_Box *s, GF_BitStream *bs); GF_Err gppv_Write(GF_Box *s, GF_BitStream *bs); GF_Err gppc_Write(GF_Box *s, GF_BitStream *bs); @@ -2647,7 +2755,7 @@ GF_Err gppc_Size(GF_Box *s); #endif -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS GF_Box *mvex_New(); GF_Box *trex_New(); GF_Box *moof_New(); @@ -2655,6 +2763,7 @@ GF_Box *mfhd_New(); GF_Box *traf_New(); GF_Box *tfhd_New(); GF_Box *trun_New(); +GF_Box *styp_New(); void mvex_del(GF_Box *s); void trex_del(GF_Box *s); @@ -2663,6 +2772,7 @@ void mfhd_del(GF_Box *s); void traf_del(GF_Box *s); void tfhd_del(GF_Box *s); void trun_del(GF_Box *s); +void styp_del(GF_Box *s); GF_Err mvex_Read(GF_Box *s, GF_BitStream *bs); GF_Err trex_Read(GF_Box *s, GF_BitStream *bs); @@ -2671,6 +2781,7 @@ GF_Err mfhd_Read(GF_Box *s, GF_BitStream *bs); GF_Err traf_Read(GF_Box *s, GF_BitStream *bs); GF_Err tfhd_Read(GF_Box *s, GF_BitStream *bs); GF_Err trun_Read(GF_Box *s, GF_BitStream *bs); +GF_Err styp_Read(GF_Box *s, GF_BitStream *bs); GF_Err mvex_Write(GF_Box *s, GF_BitStream *bs); GF_Err trex_Write(GF_Box *s, GF_BitStream *bs); @@ -2679,6 +2790,7 @@ GF_Err mfhd_Write(GF_Box *s, GF_BitStream *bs); GF_Err traf_Write(GF_Box *s, GF_BitStream *bs); GF_Err tfhd_Write(GF_Box *s, GF_BitStream *bs); GF_Err trun_Write(GF_Box *s, GF_BitStream *bs); +GF_Err styp_Write(GF_Box *s, GF_BitStream *bs); GF_Err mvex_Size(GF_Box *s); GF_Err trex_Size(GF_Box *s); @@ -2687,6 +2799,7 @@ GF_Err mfhd_Size(GF_Box *s); GF_Err traf_Size(GF_Box *s); GF_Err tfhd_Size(GF_Box *s); GF_Err trun_Size(GF_Box *s); +GF_Err styp_Size(GF_Box *s); GF_Box *mehd_New(); @@ -2705,6 +2818,8 @@ GF_Err avcc_Write(GF_Box *s, GF_BitStream *bs); GF_Err avcc_Size(GF_Box *s); GF_Box *avc1_New(); +GF_Box *avc2_New(); +GF_Box *svc1_New(); GF_Box *m4ds_New(); void m4ds_del(GF_Box *s); @@ -2722,6 +2837,7 @@ GF_Err btrt_Size(GF_Box *s); /*3GPP streaming text*/ GF_Box *ftab_New(); GF_Box *tx3g_New(); +GF_Box *text_New(); GF_Box *styl_New(); GF_Box *hlit_New(); GF_Box *hclr_New(); @@ -2734,6 +2850,7 @@ GF_Box *twrp_New(); void ftab_del(GF_Box *s); void tx3g_del(GF_Box *s); +void text_del(GF_Box *s); void styl_del(GF_Box *s); void hlit_del(GF_Box *s); void hclr_del(GF_Box *s); @@ -2746,6 +2863,7 @@ void twrp_del(GF_Box *s); GF_Err ftab_Read(GF_Box *s, GF_BitStream *bs); GF_Err tx3g_Read(GF_Box *s, GF_BitStream *bs); +GF_Err text_Read(GF_Box *s, GF_BitStream *bs); GF_Err styl_Read(GF_Box *s, GF_BitStream *bs); GF_Err hlit_Read(GF_Box *s, GF_BitStream *bs); GF_Err hclr_Read(GF_Box *s, GF_BitStream *bs); @@ -2756,9 +2874,10 @@ GF_Err tbox_Read(GF_Box *s, GF_BitStream *bs); GF_Err blnk_Read(GF_Box *s, GF_BitStream *bs); GF_Err twrp_Read(GF_Box *s, GF_BitStream *bs); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ftab_Write(GF_Box *s, GF_BitStream *bs); GF_Err tx3g_Write(GF_Box *s, GF_BitStream *bs); +GF_Err text_Write(GF_Box *s, GF_BitStream *bs); GF_Err styl_Write(GF_Box *s, GF_BitStream *bs); GF_Err hlit_Write(GF_Box *s, GF_BitStream *bs); GF_Err hclr_Write(GF_Box *s, GF_BitStream *bs); @@ -2771,6 +2890,7 @@ GF_Err twrp_Write(GF_Box *s, GF_BitStream *bs); GF_Err ftab_Size(GF_Box *s); GF_Err tx3g_Size(GF_Box *s); +GF_Err text_Size(GF_Box *s); GF_Err styl_Size(GF_Box *s); GF_Err hlit_Size(GF_Box *s); GF_Err hclr_Size(GF_Box *s); @@ -2826,7 +2946,7 @@ GF_Err frma_Read(GF_Box *s, GF_BitStream *bs); GF_Err schm_Read(GF_Box *s, GF_BitStream *bs); GF_Err schi_Read(GF_Box *s, GF_BitStream *bs); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err meta_Write(GF_Box *s, GF_BitStream *bs); GF_Err xml_Write(GF_Box *s, GF_BitStream *bs); GF_Err bxml_Write(GF_Box *s, GF_BitStream *bs); @@ -2864,7 +2984,7 @@ void iKMS_del(GF_Box *s); void iSFM_del(GF_Box *s); GF_Err iKMS_Read(GF_Box *s, GF_BitStream *bs); GF_Err iSFM_Read(GF_Box *s, GF_BitStream *bs); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err iKMS_Write(GF_Box *s, GF_BitStream *bs); GF_Err iSFM_Write(GF_Box *s, GF_BitStream *bs); GF_Err iKMS_Size(GF_Box *s); @@ -2881,7 +3001,7 @@ GF_Err data_Read(GF_Box *s, GF_BitStream *bs); GF_Box *ilst_New(); GF_Box *ListItem_New(u32 type); GF_Box *data_New(); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ilst_Write(GF_Box *s, GF_BitStream *bs); GF_Err ListItem_Write(GF_Box *s, GF_BitStream *bs); GF_Err data_Write(GF_Box *s, GF_BitStream *bs); @@ -2975,7 +3095,7 @@ GF_Err rtpo_dump(GF_Box *a, FILE * trace); -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS GF_Err mvex_dump(GF_Box *a, FILE * trace); GF_Err mehd_dump(GF_Box *a, FILE * trace); GF_Err trex_dump(GF_Box *a, FILE * trace); @@ -2984,6 +3104,7 @@ GF_Err mfhd_dump(GF_Box *a, FILE * trace); GF_Err traf_dump(GF_Box *a, FILE * trace); GF_Err tfhd_dump(GF_Box *a, FILE * trace); GF_Err trun_dump(GF_Box *a, FILE * trace); +GF_Err styp_dump(GF_Box *a, FILE * trace); #endif GF_Err avcc_dump(GF_Box *a, FILE * trace); @@ -2993,6 +3114,7 @@ GF_Err btrt_dump(GF_Box *a, FILE * trace); GF_Err ftab_dump(GF_Box *a, FILE * trace); GF_Err tx3g_dump(GF_Box *a, FILE * trace); +GF_Err text_dump(GF_Box *a, FILE * trace); GF_Err styl_dump(GF_Box *a, FILE * trace); GF_Err hlit_dump(GF_Box *a, FILE * trace); GF_Err hclr_dump(GF_Box *a, FILE * trace); @@ -3026,12 +3148,15 @@ GF_Err ilst_dump(GF_Box *a, FILE * trace); GF_Err ListItem_dump(GF_Box *a, FILE * trace); GF_Err data_dump(GF_Box *a, FILE * trace); +GF_Err lsrc_dump(GF_Box *a, FILE * trace); +GF_Err lsr1_dump(GF_Box *a, FILE * trace); + /*Apple extensions*/ GF_MetaBox *gf_isom_apple_get_meta_extensions(GF_ISOFile *mov); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_MetaBox *gf_isom_apple_create_meta_extensions(GF_ISOFile *mov); -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /*OMA extensions*/ GF_Box *ohdr_New(); @@ -3132,6 +3257,30 @@ GF_Err dac3_Write(GF_Box *s, GF_BitStream *bs); GF_Err dac3_Size(GF_Box *s); GF_Err dac3_dump(GF_Box *a, FILE * trace); +GF_Box *lsrc_New(); +void lsrc_del(GF_Box *s); +GF_Err lsrc_Read(GF_Box *s, GF_BitStream *bs); +GF_Err lsrc_Write(GF_Box *s, GF_BitStream *bs); +GF_Err lsrc_Size(GF_Box *s); +GF_Err lsrc_dump(GF_Box *a, FILE * trace); + +GF_Box *lsr1_New(); +void lsr1_del(GF_Box *s); +GF_Err lsr1_Read(GF_Box *s, GF_BitStream *bs); +GF_Err lsr1_Write(GF_Box *s, GF_BitStream *bs); +GF_Err lsr1_Size(GF_Box *s); +GF_Err lsr1_dump(GF_Box *a, FILE * trace); + +GF_Box *sidx_New(); +void sidx_del(GF_Box *s); +GF_Err sidx_Read(GF_Box *s, GF_BitStream *bs); +GF_Err sidx_Write(GF_Box *s, GF_BitStream *bs); +GF_Err sidx_Size(GF_Box *s); +GF_Err sidx_dump(GF_Box *a, FILE * trace); + + +#endif /*GPAC_DISABLE_ISOM*/ + #ifdef __cplusplus } #endif diff --git a/include/gpac/internal/laser_dev.h b/include/gpac/internal/laser_dev.h index ddb8e7e..83ed903 100644 --- a/include/gpac/internal/laser_dev.h +++ b/include/gpac/internal/laser_dev.h @@ -29,6 +29,8 @@ #include +#ifndef GPAC_DISABLE_LASER + /*per_stream config support*/ typedef struct { @@ -333,5 +335,7 @@ enum LSR_AMD1_EXT_updateSource, }; +#endif /*GPAC_DISABLE_LASER*/ + #endif diff --git a/include/gpac/internal/media_dev.h b/include/gpac/internal/media_dev.h index cebcf4d..7f7987d 100644 --- a/include/gpac/internal/media_dev.h +++ b/include/gpac/internal/media_dev.h @@ -27,8 +27,18 @@ #define _GF_MEDIA_DEV_H_ #include +#include +#ifndef GPAC_DISABLE_ISOM +void gf_media_get_sample_average_infos(GF_ISOFile *file, u32 Track, u32 *avgSize, u32 *MaxSize, u32 *TimeDelta, u32 *maxCTSDelta, u32 *const_duration, u32 *bandwidth); +#endif + + +#ifndef GPAC_DISABLE_MEDIA_IMPORT GF_Err gf_import_message(GF_MediaImporter *import, GF_Err e, char *format, ...); +#endif /*GPAC_DISABLE_MEDIA_IMPORT*/ + +#ifndef GPAC_DISABLE_AV_PARSERS /*returns 0 if not a start code, or size of start code (3 or 4 bytes). If start code, bitstream is positionned AFTER start code*/ @@ -37,45 +47,84 @@ u32 AVC_IsStartCode(GF_BitStream *bs); u32 AVC_NextStartCode(GF_BitStream *bs); /*returns NAL unit type - bitstream must be sync'ed!!*/ u8 AVC_NALUType(GF_BitStream *bs); -/*slice NALU*/ -Bool AVC_NALUIsSlice(u8 type); +Bool SVC_NALUIsSlice(u8 type); + + +enum +{ + /*SPS has been parsed*/ + AVC_SPS_PARSED = 1, + /*SPS has been declared to the upper layer*/ + AVC_SPS_DECLARED = 1<<1, + /*SUB-SPS has been parsed*/ + AVC_SUBSPS_PARSED = 1<<2, + /*SUB-SPS has been declared to the upper layer*/ + AVC_SUBSPS_DECLARED = 1<<3, +}; + +typedef struct +{ + u8 cpb_removal_delay_length_minus1; + u8 dpb_output_delay_length_minus1; + /*to be eventually completed by other hrd members*/ +} AVC_HRD; + +typedef struct +{ + s32 timing_info_present_flag; + u32 num_units_in_tick; + u32 time_scale; + s32 fixed_frame_rate_flag; + u32 par_num, par_den; + + Bool nal_hrd_parameters_present_flag; + Bool vcl_hrd_parameters_present_flag; + AVC_HRD hrd; + + Bool pic_struct_present_flag; + /*to be eventually completed by other vui members*/ +} AVC_VUI; typedef struct { - s32 profile_idc; - s32 level_idc; - s32 prof_compat; - s32 log2_max_frame_num; - u32 poc_type, poc_cycle_length; - s32 log2_max_poc_lsb; - s32 delta_pic_order_always_zero_flag; + s32 profile_idc; + s32 level_idc; + s32 prof_compat; + s32 log2_max_frame_num; + u32 poc_type, poc_cycle_length; + s32 log2_max_poc_lsb; + s32 delta_pic_order_always_zero_flag; s32 offset_for_non_ref_pic, offset_for_top_to_bottom_field; Bool frame_mbs_only_flag; - s16 offset_for_ref_frame[256]; - - s32 timing_info_present_flag; - u32 num_units_in_tick; - u32 time_scale; - s32 fixed_frame_rate_flag; + s16 offset_for_ref_frame[256]; u32 width, height; - u32 par_num, par_den; + + AVC_VUI vui; + /*used to discard repeated SPSs - 0: not parsed, 1 parsed, 2 sent*/ - u32 status; + u32 state; } AVC_SPS; typedef struct { - s32 sps_id; - s32 pic_order_present; /* pic_order_present_flag*/ - s32 redundant_pic_cnt_present; /* redundant_pic_cnt_present_flag */ - int slice_group_count; /* num_slice_groups_minus1 + 1*/ + s32 id; /* used to compare pps when storing SVC PSS */ + s32 sps_id; + s32 pic_order_present; /* pic_order_present_flag*/ + s32 redundant_pic_cnt_present; /* redundant_pic_cnt_present_flag */ + u32 slice_group_count; /* num_slice_groups_minus1 + 1*/ /*used to discard repeated SPSs - 0: not parsed, 1 parsed, 2 sent*/ u32 status; } AVC_PPS; +typedef struct +{ + s32 temporal_id; + s32 idr_pic_flag; +} SVC_NALUHeader; + typedef struct { u8 nal_ref_idc, nal_unit_type, field_pic_flag, bottom_field_flag; @@ -90,6 +139,7 @@ typedef struct AVC_SPS *sps; AVC_PPS *pps; + SVC_NALUHeader NalHeader; } AVCSliceInfo; @@ -102,27 +152,36 @@ typedef struct u8 valid; } AVCSeiRecoveryPoint; +typedef struct +{ + u8 pic_struct; + /*to be eventually completed by other pic_timing members*/ +} AVCSeiPicTiming; typedef struct { AVCSeiRecoveryPoint recovery_point; + AVCSeiPicTiming pic_timing; /*to be eventually completed by other sei*/ - } AVCSei; typedef struct { - AVC_SPS sps[32]; + AVC_SPS sps[32]; /* range allowed in the spec is 0..31 */ + s8 sps_active_idx; /*currently active sps; must be initalized to -1 in order to discard not yet decodable SEIs*/ + AVC_PPS pps[255]; AVCSliceInfo s_info; AVCSei sei; + + Bool is_svc; } AVCState; /*return sps ID or -1 if error*/ -s32 AVC_ReadSeqInfo(GF_BitStream *bs, AVCState *avc, u32 *vui_flag_pos); +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(GF_BitStream *bs, AVCState *avc); +s32 AVC_ReadPictParamSet(char *pps_data, u32 pps_size, AVCState *avc); /*is slice a RAP*/ Bool AVC_SliceIsIDR(AVCState *avc); /*parses NALU, updates avc state and returns: @@ -132,10 +191,14 @@ Bool AVC_SliceIsIDR(AVCState *avc); */ s32 AVC_ParseNALU(GF_BitStream *bs, u32 nal_hdr, AVCState *avc); /*remove SEI messages not allowed in MP4*/ +/*nota: 'buffer' remains unmodified but cannot be set const*/ u32 AVC_ReformatSEI_NALU(char *buffer, u32 nal_size, AVCState *avc); +#ifndef GPAC_DISABLE_ISOM GF_Err AVC_ChangePAR(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d); +#endif +#endif /*GPAC_DISABLE_AV_PARSERS*/ typedef struct { @@ -144,5 +207,27 @@ typedef struct } QCPRateTable; +#if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_STREAMING) + +GP_RTPPacketizer *gf_rtp_packetizer_create_and_init_from_file(GF_ISOFile *file, + u32 TrackNum, + void *cbk_obj, + void (*OnNewPacket)(void *cbk, GF_RTPHeader *header), + void (*OnPacketDone)(void *cbk, GF_RTPHeader *header), + void (*OnDataReference)(void *cbk, u32 payload_size, u32 offset_from_orig), + void (*OnData)(void *cbk, char *data, u32 data_size, Bool is_head), + u32 Path_MTU, + u32 max_ptime, + u32 default_rtp_rate, + u32 flags, + u8 PayloadID, + Bool copy_media, + u32 InterleaveGroupID, + u8 InterleaveGroupPriority); + +void gf_media_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, GF_ISOFile *file, u32 track); + +#endif + #endif /*_GF_MEDIA_DEV_H_*/ diff --git a/include/gpac/internal/mesh.h b/include/gpac/internal/mesh.h index 57fba27..e8e6b4d 100644 --- a/include/gpac/internal/mesh.h +++ b/include/gpac/internal/mesh.h @@ -179,7 +179,7 @@ void mesh_generate_tex_coords(GF_Mesh *mesh, GF_Node *__texCoords); void mesh_new_unit_bbox(GF_Mesh *mesh); /*insert base primitives - low res indicates less subdivision steps for circles (cone, cylinder, ellipse, sphere)*/ -void mesh_new_rectangle(GF_Mesh *mesh, SFVec2f size); +void mesh_new_rectangle(GF_Mesh *mesh, SFVec2f size, SFVec2f *orig, Bool flip); void mesh_new_ellipse(GF_Mesh *mesh, Fixed a_dia, Fixed b_dia, Bool low_res); void mesh_new_box(GF_Mesh *mesh, SFVec3f size); void mesh_new_cylinder(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, Bool side, Bool top, Bool low_res); @@ -264,14 +264,14 @@ indices are ignored. partially implemented on ogl-ES*/ void TesselateFaceMesh(GF_Mesh *mesh, GF_Mesh *face); -#ifndef GPAC_USE_OGL_ES +#ifdef GPAC_HAS_GLU /*converts 2D path into a polygon - these are only partially implemented when using oglES for_outline: 0, regular odd/even windining rule with texCoords 1, zero-non-zero windining rule without texCoords 2, zero-non-zero windining rule with texCoords */ -void TesselatePath(GF_Mesh *mesh, GF_Path *path, u32 outline_style); +void gf_mesh_tesselate_path(GF_Mesh *mesh, GF_Path *path, u32 outline_style); /*appends given face (and tesselate if needed) to the mesh. Only vertices are used in the face indices are ignored. diff --git a/include/gpac/internal/ogg.h b/include/gpac/internal/ogg.h index 867de04..36aa3b8 100644 --- a/include/gpac/internal/ogg.h +++ b/include/gpac/internal/ogg.h @@ -23,6 +23,10 @@ #ifndef _GF_OGG_H_ #define _GF_OGG_H_ +#include + +#ifndef GPAC_DISABLE_OGG + /*DON'T CLASH WITH OFFICIAL OGG IF ALREADY INCLUDED*/ #ifndef _OGG_H @@ -30,8 +34,6 @@ extern "C" { #endif -#include - typedef struct { s32 endbyte; s32 endbit; @@ -205,5 +207,7 @@ void ogg_packet_clear(ogg_packet *op); #endif /*_OGG_H*/ +#endif /*GPAC_DISABLE_OGG*/ + #endif /*_GF_OGG_H_*/ diff --git a/include/gpac/internal/reedsolomon.h b/include/gpac/internal/reedsolomon.h new file mode 100644 index 0000000..1923f47 --- /dev/null +++ b/include/gpac/internal/reedsolomon.h @@ -0,0 +1,78 @@ +/* Reed Solomon Coding for glyphs + * + * (c) Henry Minsky (hqm@ua.com), Universal Access Inc. (1991-1996) + * + * + */ + +/**************************************************************** + + Below is NPAR, the only compile-time parameter you should have to + modify. + + It is the number of parity bytes which will be appended to + your data to create a codeword. + + Note that the maximum codeword size is 255, so the + sum of your message length plus parity should be less than + or equal to this maximum limit. + + In practice, you will get slooow error correction and decoding + if you use more than a reasonably small number of parity bytes. + (say, 10 or 20) + + ****************************************************************/ +#ifndef _ECC_H_ +#define _ECC_H_ +#define NPAR 64 + +/****************************************************************/ + +#define TRUE 1 +#define FALSE 0 + +typedef unsigned long BIT32; +typedef unsigned short BIT16; + +/* **************************************************************** */ + +/* Maximum degree of various polynomials. */ +#define MAXDEG (NPAR*2) + +/*************************************/ +/* Encoder parity bytes */ +extern int pBytes[MAXDEG]; + +/* Decoder syndrome bytes */ +extern int synBytes[MAXDEG]; + +/* print debugging info */ +extern int DEBUG; + +/* Reed Solomon encode/decode routines */ +void initialize_ecc (void); +int check_syndrome (void); +void decode_data (unsigned char data[], int nbytes); +void encode_data (unsigned char msg[], int nbytes, unsigned char dst[]); + + +/* galois arithmetic tables */ +extern int gexp[]; +extern int glog[]; + +void init_galois_tables (void); +int ginv(int elt); +int gmult(int a, int b); + + +/* Error location routines */ +int correct_errors_erasures (unsigned char codeword[], int csize,int nerasures, int erasures[]); + +/* polynomial arithmetic */ +void add_polys(int dst[], int src[]) ; +void scale_poly(int k, int poly[]); +void mult_polys(int dst[], int p1[], int p2[]); + +void copy_poly(int dst[], int src[]); +void zero_poly(int poly[]); +#endif //_ECC_H_ diff --git a/include/gpac/internal/scenegraph_dev.h b/include/gpac/internal/scenegraph_dev.h index 54d88a0..1a3e087 100644 --- a/include/gpac/internal/scenegraph_dev.h +++ b/include/gpac/internal/scenegraph_dev.h @@ -23,7 +23,6 @@ */ - #ifndef _GF_SCENEGRAPH_DEV_H_ #define _GF_SCENEGRAPH_DEV_H_ @@ -38,6 +37,11 @@ #include +#ifdef __cplusplus +extern "C" { +#endif + + #ifdef GPAC_HAS_SPIDERMONKEY /*WIN32 and WinCE config (no configure script)*/ @@ -89,6 +93,12 @@ struct _node_interactive_ext THIS IS DYNAMICALLY CREATED*/ GF_List *routes; +#ifdef GPAC_HAS_SPIDERMONKEY + /*JS bindings if any - THIS IS DYNAMICALLY CREATED + This speeds up field modif notification (script bindings are listed here)*/ + struct _node_js_binding *js_binding; +#endif + #ifndef GPAC_DISABLE_SVG /*event listeners - THIS IS DYNAMICALLY CREATED*/ GF_DOMEventTarget *dom_evt; @@ -149,34 +159,12 @@ struct __tag_scene_graph /*all DEF nodes (explicit)*/ NodeIDedItem *id_node, *id_node_last; - /*all routes available*/ - GF_List *Routes; - - /*all routes available*/ - GF_List *exported_nodes; - - /*when a proto is instanciated it creates its own scene graph. BIFS/VRML specify that the namespace is the same - (eg cannot reuse a NodeID or route name/ID), but this could be done differently by some other stds - if NULL this is the main scenegraph*/ - struct _proto_instance *pOwningProto; - - /*all first-level protos of the graph (the only ones that can be instanciated in this graph)*/ - GF_List *protos; - /*all first-level protos of the graph not currently registered - memory handling of graph only*/ - GF_List *unregistered_protos; - /*pointer to the root node*/ GF_Node *RootNode; - /*routes to be activated (cascade model). This is used at the top-level graph only (eg - proto routes use that too, ecept ISed fields). It is the app responsability to - correctly connect or browse scene graphs connected through Inline*/ - GF_List *routes_to_activate; - - /*since events may trigger deletion of objects we use a 2 step delete*/ - GF_List *routes_to_destroy; + /*nodes exported from this scene graph*/ + GF_List *exported_nodes; - u32 simulation_tick; /*user private data*/ void *userpriv; @@ -187,7 +175,7 @@ struct __tag_scene_graph /*real scene time callback*/ Double (*GetSceneTime)(void *userpriv); - GF_SceneGraph *(*GetExternProtoLib)(void *userpriv, MFURL *lib_url); + /*parent scene if any*/ struct __tag_scene_graph *parent_scene; @@ -206,28 +194,61 @@ struct __tag_scene_graph /*script loader*/ void (*script_load)(GF_Node *node); /*callback to JS upon node modif*/ - void (*on_node_modified)(struct __tag_scene_graph *sg, GF_Node *node, GF_FieldInfo *info); + void (*on_node_modified)(struct __tag_scene_graph *sg, GF_Node *node, GF_FieldInfo *info, GF_Node *script); + +#ifdef GF_SELF_REPLACE_ENABLE + /*to detect replace scene from within conditionals*/ + Bool graph_has_been_reset; +#endif - u32 max_defined_route_id; /*namespaces list. This list is used while parsing/dumping the tree to store the hierarchy of xmlns attributes in subtrees. It is a stack of GF_XMLNS structures pushed/popped at each element*/ GF_List *ns; -#ifdef GF_SELF_REPLACE_ENABLE - /*to detect replace scene from within conditionals*/ - Bool graph_has_been_reset; -#endif + /*temp storage for name conversions*/ + char szNameBuffer[100]; + +#ifndef GPAC_DISABLE_VRML + + /*all routes available*/ + GF_List *Routes; + + /*when a proto is instanciated it creates its own scene graph. BIFS/VRML specify that the namespace is the same + (eg cannot reuse a NodeID or route name/ID), but this could be done differently by some other stds + if NULL this is the main scenegraph*/ + struct _proto_instance *pOwningProto; + + /*all first-level protos of the graph (the only ones that can be instanciated in this graph)*/ + GF_List *protos; + /*all first-level protos of the graph not currently registered - memory handling of graph only*/ + GF_List *unregistered_protos; + + /*routes to be activated (cascade model). This is used at the top-level graph only (eg + proto routes use that too, ecept ISed fields). It is the app responsability to + correctly connect or browse scene graphs connected through Inline*/ + GF_List *routes_to_activate; + + /*since events may trigger deletion of objects we use a 2 step delete*/ + GF_List *routes_to_destroy; + + u32 simulation_tick; + + GF_SceneGraph *(*GetExternProtoLib)(void *userpriv, MFURL *lib_url); + + u32 max_defined_route_id; + /*global qp used in BIFS coding*/ GF_Node *global_qp; +#endif + +#ifndef GPAC_DISABLE_SVG /*use stack as used in the dom_fire_event - this is only valid during an event fire, and may be NULL*/ GF_List *use_stack; + Bool abort_bubbling; - /*temp storage for name conversions*/ - char szNameBuffer[100]; -#ifndef GPAC_DISABLE_SVG GF_DOMEventTarget dom_evt; u32 nb_evts_focus; u32 nb_evts_mouse; @@ -286,6 +307,23 @@ void *gf_node_get_name_address(GF_Node*node); void gf_node_changed_internal(GF_Node *node, GF_FieldInfo *field, Bool notify_scripts); +void gf_node_dirty_parent_graph(GF_Node *node); + + +/*BASE node (GF_Node) destructor*/ +void gf_node_free(GF_Node *node); + +/*node destructor dispatcher: redirects destruction for each graph type: VRML/MPEG4, X3D, SVG...)*/ +void gf_node_del(GF_Node *node); + +/*creates an undefined GF_Node - for parsing only*/ +GF_Node *gf_sg_new_base_node(); + + +void gf_sg_lock_javascript(Bool LockIt); + +#ifndef GPAC_DISABLE_VRML + struct _route { u8 is_setup; @@ -295,23 +333,23 @@ struct _route u32 ID; char *name; + /*scope of this route*/ + GF_SceneGraph *graph; + u32 lastActivateTime; + GF_Node *FromNode; GF_FieldInfo FromField; GF_Node *ToNode; GF_FieldInfo ToField; - - /*scope of this route*/ - GF_SceneGraph *graph; - u32 lastActivateTime; }; void gf_sg_route_unqueue(GF_SceneGraph *sg, GF_Route *r); /*returns TRUE if route modified destination node*/ Bool gf_sg_route_activate(GF_Route *r); void gf_sg_route_queue(GF_SceneGraph *pSG, GF_Route *r); - void gf_sg_destroy_routes(GF_SceneGraph *sg); +void gf_sg_route_setup(GF_Route *r); /*MPEG4 def*/ @@ -325,6 +363,7 @@ const char *gf_sg_mpeg4_node_get_class_name(u32 NodeTag); Bool gf_sg_mpeg4_node_get_aq_info(GF_Node *node, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits); s32 gf_sg_mpeg4_node_get_field_index_by_name(GF_Node *node, char *name); +#ifndef GPAC_DISABLE_X3D /*X3D def*/ GF_Node *gf_sg_x3d_node_new(u32 NodeTag); GF_Err gf_sg_x3d_node_get_field(GF_Node *node, GF_FieldInfo *field); @@ -332,9 +371,11 @@ u32 gf_sg_x3d_node_get_field_count(GF_Node *node); void gf_sg_x3d_node_del(GF_Node *node); const char *gf_sg_x3d_node_get_class_name(u32 NodeTag); s32 gf_sg_x3d_node_get_field_index_by_name(GF_Node *node, char *name); - Bool gf_x3d_get_node_type(u32 NDT_Tag, u32 NodeTag); +#endif + +/*VRML/X3D types*/ void gf_sg_mfint32_del(MFInt32 par); void gf_sg_mffloat_del(MFFloat par); void gf_sg_mfdouble_del(MFDouble par); @@ -358,8 +399,173 @@ void gf_sg_sfurl_del(SFURL url); Bool gf_sg_vrml_node_init(GF_Node *node); Bool gf_sg_vrml_node_changed(GF_Node *node, GF_FieldInfo *field); +char *gf_node_vrml_dump_attribute(GF_Node *n, GF_FieldInfo *info); + +// +// MF Fields tools +// WARNING: MF / SF Nodes CANNOT USE THESE FUNCTIONS +// + +//return the size (in bytes) of fixed fields (buffers are handled as a char ptr , 1 byte) +u32 gf_sg_vrml_get_sf_size(u32 FieldType); + +/*returns field type from its name*/ +u32 gf_sg_field_type_by_name(char *fieldType); + +/*clones the command in another graph - needed for uncompressed conditional in protos +if force_clone is not set and the target graph is the same as the command graph, nodes are just registered +with the new commands rather than cloned*/ +GF_Command *gf_sg_vrml_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool force_clone); + + +/* + Proto node + +*/ + +/*field interface to codec. This is used to do the node decoding, index translation +and all QP/BIFS Anim parsing. */ +struct _protofield +{ + u8 EventType; + u8 FieldType; + /*if UseName, otherwise fieldN*/ + char *FieldName; + + /*default field value*/ + void *def_value; + + GF_Node *def_sfnode_value; + GF_ChildNodeItem *def_mfnode_value; + + /*coding indexes*/ + u32 IN_index, OUT_index, DEF_index, ALL_index; + + /*Quantization*/ + u32 QP_Type, hasMinMax; + void *qp_min_value, *qp_max_value; + /*this is for QP=13 only*/ + u32 NumBits; + + /*Animation*/ + u32 Anim_Type; + + void *userpriv; + void (*OnDelete)(void *ptr); +}; + +GF_ProtoFieldInterface *gf_sg_proto_new_field_interface(u32 FieldType); + +/*set QP and anim info for a proto field (BIFS allows for that in proto coding)*/ +GF_Err gf_bifs_proto_field_set_aq_info(GF_ProtoFieldInterface *field, u32 QP_Type, u32 hasMinMax, u32 QPSFType, void *qp_min_value, void *qp_max_value, u32 QP13_NumBits); + +/*proto field instance. since it is useless to duplicate all coding info, names and the like +we seperate proto declaration and proto instanciation*/ +typedef struct +{ + u8 EventType; + u8 FieldType; + u8 has_been_accessed; + void *field_pointer; +} GF_ProtoField; + + +struct _proto +{ + /*1 - Prototype interface*/ + u32 ID; + char *Name; + GF_List *proto_fields; + + /*pointer to parent scene graph*/ + struct __tag_scene_graph *parent_graph; + /*pointer to proto scene graph*/ + struct __tag_scene_graph *sub_graph; + + /*2 - proto implementation as declared in the bitstream*/ + GF_List *node_code; + + /*num fields*/ + u32 NumIn, NumOut, NumDef, NumDyn; + + void *userpriv; + void (*OnDelete)(void *ptr); + + /*URL of extern proto lib (if none, URL is empty)*/ + MFURL ExternProto; + + /*list of instances*/ + GF_List *instances; +}; + +/*proto field API*/ +u32 gf_sg_proto_get_num_fields(GF_Node *node, u8 code_mode); +GF_Err gf_sg_proto_get_field(GF_Proto *proto, GF_Node *node, GF_FieldInfo *field); + +enum +{ + GF_SG_PROTO_LOADED = 1, + GF_SG_PROTO_IS_GROUPING = 2, +}; + +typedef struct _proto_instance +{ + /*this is a node*/ + BASE_NODE + + /*Prototype interface for coding and field addressing*/ + GF_Proto *proto_interface; + + /*proto implementation at run-time (aka the state of the nodes may differ accross + different instances of the proto)*/ + GF_List *fields; + + /*a proto doesn't have one root SFnode but a collection of nodes for implementation*/ + GF_List *node_code; + + /*node for proto rendering, first of all declared nodes*/ + GF_Node *RenderingNode; + + /*in case the PROTO is destroyed*/ + char *proto_name; + + /*scripts are loaded once all IS routes are activated and node code is loaded*/ + GF_List *scripts_to_load; + + u32 flags; +} GF_ProtoInstance; + +/*destroy proto*/ +void gf_sg_proto_del_instance(GF_ProtoInstance *inst); +GF_Err gf_sg_proto_get_field_index(GF_ProtoInstance *proto, u32 index, u32 code_mode, u32 *all_index); +Bool gf_sg_proto_get_aq_info(GF_Node *Node, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits); +GF_Err gf_sg_proto_get_field_ind_static(GF_Node *Node, u32 inField, u8 IndexMode, u32 *allField); +GF_Node *gf_sg_proto_create_node(GF_SceneGraph *scene, GF_Proto *proto, GF_ProtoInstance *from_inst); +void gf_sg_proto_instanciate(GF_ProtoInstance *proto_node); + +/*get tag of first node in proto code - used for validation only*/ +u32 gf_sg_proto_get_root_tag(GF_Proto *proto); + + +/*to call when a proto field has been modified (at creation or through commands, modifications through events +are handled internally). +node can be the proto instance or a node from the proto code +this will call NodeChanged if needed, forward to proto/node or trigger any route if needed*/ +void gf_sg_proto_propagate_event(GF_Node *node, u32 fieldIndex, GF_Node *from_node); + +s32 gf_sg_proto_get_field_index_by_name(GF_Proto *proto, GF_Node *node, char *name); + +GF_Node *gf_vrml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *cloned_parent, char *inst_id_suffix); + +#endif /*GPAC_DISABLE_VRML*/ + + +/*specialized node unregister for Memory Commands - checks if the node(s) used in the command have been destroyed +during the reset. If so don't attempt to unregister the node*/ +GF_Err gf_node_try_destroy(GF_SceneGraph *sg, GF_Node *pNode, GF_Node *parentNode); + #ifndef GPAC_DISABLE_SVG @@ -642,163 +848,6 @@ void gf_smil_timing_resume(GF_Node *node); #endif -// -// MF Fields tools -// WARNING: MF / SF Nodes CANNOT USE THESE FUNCTIONS -// - -//return the size (in bytes) of fixed fields (buffers are handled as a char ptr , 1 byte) -u32 gf_sg_vrml_get_sf_size(u32 FieldType); - - -/*BASE node (GF_Node) destructor*/ -void gf_node_free(GF_Node *node); - -/*node destructor dispatcher: redirects destruction for each graph type: VRML/MPEG4, X3D, SVG...)*/ -void gf_node_del(GF_Node *node); - -/*creates an undefined GF_Node - for parsing only*/ -GF_Node *gf_sg_new_base_node(); - -/*returns field type from its name*/ -u32 gf_sg_field_type_by_name(char *fieldType); - - - -/* - Proto node - -*/ - -/*field interface to codec. This is used to do the node decoding, index translation -and all QP/BIFS Anim parsing. */ -struct _protofield -{ - u8 EventType; - u8 FieldType; - /*if UseName, otherwise fieldN*/ - char *FieldName; - - /*default field value*/ - void *def_value; - - GF_Node *def_sfnode_value; - GF_ChildNodeItem *def_mfnode_value; - - /*coding indexes*/ - u32 IN_index, OUT_index, DEF_index, ALL_index; - - /*Quantization*/ - u32 QP_Type, hasMinMax; - void *qp_min_value, *qp_max_value; - /*this is for QP=13 only*/ - u32 NumBits; - - /*Animation*/ - u32 Anim_Type; - - void *userpriv; - void (*OnDelete)(void *ptr); -}; - -GF_ProtoFieldInterface *gf_sg_proto_new_field_interface(u32 FieldType); - -/*set QP and anim info for a proto field (BIFS allows for that in proto coding)*/ -GF_Err gf_bifs_proto_field_set_aq_info(GF_ProtoFieldInterface *field, u32 QP_Type, u32 hasMinMax, u32 QPSFType, void *qp_min_value, void *qp_max_value, u32 QP13_NumBits); - -/*proto field instance. since it is useless to duplicate all coding info, names and the like -we seperate proto declaration and proto instanciation*/ -typedef struct -{ - u8 EventType; - u8 FieldType; - u8 has_been_accessed; - void *field_pointer; -} GF_ProtoField; - - -struct _proto -{ - /*1 - Prototype interface*/ - u32 ID; - char *Name; - GF_List *proto_fields; - - /*pointer to parent scene graph*/ - struct __tag_scene_graph *parent_graph; - /*pointer to proto scene graph*/ - struct __tag_scene_graph *sub_graph; - - /*2 - proto implementation as declared in the bitstream*/ - GF_List *node_code; - - /*num fields*/ - u32 NumIn, NumOut, NumDef, NumDyn; - - void *userpriv; - void (*OnDelete)(void *ptr); - - /*URL of extern proto lib (if none, URL is empty)*/ - MFURL ExternProto; - - /*list of instances*/ - GF_List *instances; -}; - -/*proto field API*/ -u32 gf_sg_proto_get_num_fields(GF_Node *node, u8 code_mode); -GF_Err gf_sg_proto_get_field(GF_Proto *proto, GF_Node *node, GF_FieldInfo *field); - - -typedef struct _proto_instance -{ - /*this is a node*/ - BASE_NODE - - /*Prototype interface for coding and field addressing*/ - GF_Proto *proto_interface; - - /*proto implementation at run-time (aka the state of the nodes may differ accross - different instances of the proto)*/ - GF_List *fields; - - /*a proto doesn't have one root SFnode but a collection of nodes for implementation*/ - GF_List *node_code; - - /*node for proto rendering, first of all declared nodes*/ - GF_Node *RenderingNode; - - /*in case the PROTO is destroyed*/ - char *proto_name; - - /*scripts are loaded once all IS routes are activated and node code is loaded*/ - GF_List *scripts_to_load; - - Bool is_loaded; -} GF_ProtoInstance; - -/*destroy proto*/ -void gf_sg_proto_del_instance(GF_ProtoInstance *inst); -GF_Err gf_sg_proto_get_field_index(GF_ProtoInstance *proto, u32 index, u32 code_mode, u32 *all_index); -Bool gf_sg_proto_get_aq_info(GF_Node *Node, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits); -GF_Err gf_sg_proto_get_field_ind_static(GF_Node *Node, u32 inField, u8 IndexMode, u32 *allField); -GF_Node *gf_sg_proto_create_node(GF_SceneGraph *scene, GF_Proto *proto, GF_ProtoInstance *from_inst); -void gf_sg_proto_instanciate(GF_ProtoInstance *proto_node); - -/*get tag of first node in proto code - used for validation only*/ -u32 gf_sg_proto_get_root_tag(GF_Proto *proto); - - -/*to call when a proto field has been modified (at creation or through commands, modifications through events -are handled internally). -node can be the proto instance or a node from the proto code -this will call NodeChanged if needed, forward to proto/node or trigger any route if needed*/ -void gf_sg_proto_check_field_change(GF_Node *node, u32 fieldIndex); - -s32 gf_sg_proto_get_field_index_by_name(GF_Proto *proto, GF_Node *node, char *name); - -GF_Node *gf_vrml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *cloned_parent, char *inst_id_suffix); - /* Script node @@ -827,6 +876,7 @@ typedef struct void (*JS_EventIn)(GF_Node *node, GF_FieldInfo *in_field); Bool is_loaded; + } GF_ScriptPriv; /*setup script stack*/ @@ -876,19 +926,20 @@ struct _scriptfield the_class.resolve = JS_ResolveStub; \ the_class.convert = JS_ConvertStub; \ the_class.finalize = fin; \ - the_class.hasInstance = js_has_instance; - -typedef struct -{ - GF_Node *node; - GF_DownloadSession *sess; -} JSFileDownload; + the_class.hasInstance = my_js_has_instance; struct JSContext *gf_sg_ecmascript_new(GF_SceneGraph *sg); void gf_sg_ecmascript_del(struct JSContext *); +GF_Node *gf_sg_js_get_node(struct JSContext *c, struct JSObject *obj); + void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script); +Bool gf_js_add_root(struct JSContext *cx, void *rp); +Bool gf_js_add_named_root(struct JSContext *cx, void *rp, const char *name); +Bool gf_js_remove_root(struct JSContext *cx, void *rp); +void gf_js_vrml_flush_event_out(GF_Node *node, GF_ScriptPriv *priv); + typedef struct { GF_FieldInfo field; @@ -898,17 +949,27 @@ typedef struct /*JS list for MFFields or NULL*/ struct JSObject *js_list; - /*when creating SFnode from inside the script, the node is stored here untill attached to an object*/ - GF_Node *temp_node; + /*pointer to the SFNode if this is an SFNode or MFNode[i] field */ + GF_Node *node; + /*when creating MFnode from inside the script, the node list is stored here untill attached to an object*/ GF_ChildNodeItem *temp_list; /*when not owned by a node*/ void *field_ptr; - - Bool reevaluate; + + /*cpontext in which the field was created*/ + struct JSContext *js_ctx; + Bool is_rooted; } GF_JSField; + +struct _node_js_binding +{ + void *node; /*GF_JSField for VRML, JSObject otherwise*/ + GF_List *fields; +}; + + #ifndef GPAC_DISABLE_SVG -void JSScript_LoadSVG(GF_Node *node); typedef struct __tag_svg_script_ctx { @@ -921,6 +982,9 @@ typedef struct __tag_svg_script_ctx struct JSObject *global; /*global event object - used to update the associated DOMEvent (JS private stack) when dispatching events*/ struct JSObject *event; + + Bool in_script; + Bool force_gc; } GF_SVGJS; #endif /*GPAC_DISABLE_SVG*/ @@ -932,6 +996,8 @@ void dom_js_load(GF_SceneGraph *scene, struct JSContext *c, struct JSObject *glo /*unloads the DOM core support (to be called upon destruction only, once the JSContext has been destroyed to releases all resources used by DOM JS)*/ void dom_js_unload(); +/*unloads DOM core before the JSContext is being destroyed */ +void dom_js_pre_destroy(struct JSContext *c, GF_SceneGraph *sg, GF_Node *script_or_handler_node); /*defines a new global object "document" of type Document*/ void dom_js_define_document(struct JSContext *c, struct JSObject *global, GF_SceneGraph *doc); @@ -1006,9 +1072,10 @@ GF_Err gf_node_deactivate(GF_Node *node); /*post a listener to be added - this is only used by LASeR:activate and DOM.addEventListener. This is to ensure that when a node is processing an event creating a new listener on this node, this listener will not be triggered*/ -void gf_dom_listener_post_add(GF_Node *obs, GF_Node *listener); +void gf_sg_listener_post_add(GF_Node *obs, GF_Node *listener); /*process all pending add_listener request*/ void gf_dom_listener_process_add(GF_SceneGraph *sg); +void gf_dom_listener_reset_defered(GF_SceneGraph *sg); void gf_node_delete_attributes(GF_Node *node); @@ -1029,5 +1096,10 @@ GF_Err gf_dom_listener_del(GF_Node *listener, GF_DOMEventTarget *target); GF_DOMHandler *gf_dom_listener_build_ex(GF_Node *node, u32 event_type, u32 event_parameter, GF_Node *handler, GF_Node **out_listener); + +#ifdef __cplusplus +} +#endif + #endif /*_GF_SCENEGRAPH_DEV_H_*/ diff --git a/include/gpac/internal/terminal_dev.h b/include/gpac/internal/terminal_dev.h index 1559aa6..4ae35a3 100644 --- a/include/gpac/internal/terminal_dev.h +++ b/include/gpac/internal/terminal_dev.h @@ -38,8 +38,9 @@ extern "C" { #include #include #include +#include -typedef struct _inline_scene GF_InlineScene; +typedef struct _scene GF_Scene; typedef struct _media_manager GF_MediaManager; typedef struct _object_clock GF_Clock; typedef struct _es_channel GF_Channel; @@ -73,7 +74,7 @@ struct _net_service /*opens service - performs URL concatenation if parent service specified*/ -GF_ClientService *gf_term_service_new(GF_Terminal *term, GF_ObjectManager *owner, const char *url, GF_ClientService *parent_service, GF_Err *ret_code); +GF_ClientService *gf_term_service_new(GF_Terminal *term, GF_ObjectManager *owner, const char *url, const char *parent_url, GF_Err *ret_code); /*destroy service*/ void gf_term_service_del(GF_ClientService *nets); @@ -92,33 +93,44 @@ GF_Err gf_term_service_cache_close(GF_ClientService *ns, Bool no_save); this is mainly designed for movie dumping in MP4Client*/ GF_Err gf_term_step_clocks(GF_Terminal * term, u32 ms_diff); -void gf_term_sample_clocks(GF_Terminal *term); +u32 gf_term_sample_clocks(GF_Terminal *term); + +u32 gf_term_check_end_of_scene(GF_Terminal *term, Bool skip_interactions); /* - Inline scene stuff + GF_Scene object. This is the structure handling all scene management, mainly: + - list of resources (media objects) used + - scene time management + - reload/seek + - Dynamic scene (without a scene description)* + Each scene registers itself as the private data of its associated scene graph. + + The scene object is also used by Inline nodes and all media resources of type "scene", eg , */ -struct _inline_scene +struct _scene { /*root OD of the subscene, ALWAYS namespace of the parent scene*/ struct _od_manager *root_od; /*scene codec: top level decoder decoding/generating the scene - can be BIFS, VRML parser, etc*/ struct _generic_codec *scene_codec; - /*OD codec - specific to MPEG-4, only present at the inline level (media ressources are always scoped here)*/ + /*OD codec - specific to MPEG-4*/ struct _generic_codec *od_codec; - /*struct _od_managers used, namespace of this scene. The chain does not have the root_od - it only contains OD sent through OD UPDATE in the OD stream(s) attached - to this scene. Remote ODs are not added, only there parents are*/ - GF_List *ODlist; - /*list of MOs (links between OD and nodes)*/ - GF_List *media_objects; - /*list of externproto libraries*/ - GF_List *extern_protos; - /*list of nodes using this inline*/ - GF_List *inline_nodes; + /*mutex for scene access*/ + GF_Mutex *mx; + + /*all sub resources of this scene (eg, list of GF_ObjectManager), namespace of this scene. This includes + both external resources (urls) and ODs sent in MPEG-4 systems*/ + GF_List *resources; + + /*list of GF_MediaObject - these are the links betwwen scene nodes (URL, xlink:href) and media resources. + We need this link because of MPEG-4 Systems, where an OD (media resource) can be removed or replaced by the server + without the scene being modified*/ + GF_List *scene_objects; + /*list of extra scene graphs (text streams, generic OSDs, ...)*/ GF_List *extra_scenes; - /*inline scene graph*/ + /*scene graph*/ GF_SceneGraph *graph; /*graph state - if not attached, no traversing of inline 0: not attached @@ -126,94 +138,135 @@ struct _inline_scene 2: temp graph attached. The temp graph is generated when waiting for the first scene AU to be processed */ u32 graph_attached; - /*togles inline restart - needed because the restart may be triggered from inside the scene or from - parent scene, hence 2 render passes must be used - special value 2 means scene URL changes (for anchor navigation*/ - u32 needs_restart; + + + /*current simulation time of the compositor*/ + Double simulation_time; + + /*set to 1 when single time-line presentation with only static resources (ONE OD AU is detected or no media removal/adding possible) + This allows preventing OD/BIFS streams shutdown/startup when seeking.*/ + Bool static_media_ressources; + + + /*callback to call to dispatch SVG MediaEvent - this is a pointer to function only because of linking issues + with static libgpac (avoids depending on SpiderMonkey and OpenGL32 if not needed)*/ + void (*on_media_event)(GF_Scene *scene, u32 type); + /*duration of inline scene*/ u64 duration; - /*if not 0, all objects in the scene will run on this clock. Needed in GPAC when clock references do not - respect object graph (eg IOD depending on external stream for clock)*/ - u16 force_sub_clock_id; - /*world info node or title node*/ + + /*WorldInfo node or node*/ void *world_info; + /*current IRI fragment if any*/ + char *fragment_uri; + + /*secondary resource scene - this is specific to SVG: a secondary resource scene is <use> or <fonturi>, and all resources + identified in a secondary resource must be checked for existence and created in the primary resource*/ + Bool secondary_resource; + + /*needed by some apps in GPAC which manipulate the scene tree in different locations as the resources*/ + char *redirect_xml_base; + + + /*FIXME - Dynamic scenes are only supported through VRML/BIFS nodes, we should add support for SVG scene graph + generation if needed*/ Bool is_dynamic_scene; /*clock for dynamic scene - current assumption is that all selected streams are synchronized in the dyn scene*/ GF_Clock *dyn_ck; /*URLs of current video, audio and subs (we can't store objects since they may be destroyed when seeking)*/ - SFURL visual_url, audio_url, text_url; - /*set to 1 when single time-line presentation with ONE OD AU is detected - the goal is to prevent - OD shutdown/startup when seeking. This will also remove unneeded net traffic for AddChannel/RemoveChannel - like RTSP TEARDOWN/SETUP*/ - Bool static_media_ressources; + SFURL visual_url, audio_url, text_url, dims_url; - /*current simulation time of the compositor*/ - Double simulation_time; +#ifndef GPAC_DISABLE_VRML + /*list of externproto libraries*/ + GF_List *extern_protos; - /*current IRI fragment if any*/ - char *fragment_uri; + /*togles inline restart - needed because the restart may be triggered from inside the scene or from + parent scene, hence 2 render passes must be used + special value 2 means scene URL changes (for anchor navigation*/ + u32 needs_restart; - /*secondary resource scene*/ - Bool secondary_resource; + /*URL of the current parent Inline node, only set during traversal*/ + MFURL *current_url; - char *redirect_xml_base; + + /*list of M_Storage nodes active*/ + GF_List *storages; + + /*list of M_KeyNavigator nodes*/ + GF_List *keynavigators; +#endif }; -GF_InlineScene *gf_inline_new(GF_InlineScene *parentScene); -void gf_inline_del(GF_InlineScene *is); -struct _od_manager *gf_inline_find_odm(GF_InlineScene *is, u16 OD_ID); -void gf_inline_disconnect(GF_InlineScene *is, Bool for_shutdown); -void gf_inline_remove_object(GF_InlineScene *is, GF_ObjectManager *odm, Bool for_shutdown); +GF_Scene *gf_scene_new(GF_Scene *parentScene); +void gf_scene_del(GF_Scene *scene); +struct _od_manager *gf_scene_find_odm(GF_Scene *scene, u16 OD_ID); +void gf_scene_disconnect(GF_Scene *scene, Bool for_shutdown); +void gf_scene_remove_object(GF_Scene *scene, GF_ObjectManager *odm, Bool for_shutdown); /*browse all (media) channels and send buffering info to the app*/ -void gf_inline_buffering_info(GF_InlineScene *is); -void gf_inline_attach_to_compositor(GF_InlineScene *is); -struct _mediaobj *gf_inline_get_media_object(GF_InlineScene *is, MFURL *url, u32 obj_type_hint, Bool lock_timelines); -struct _mediaobj *gf_inline_get_media_object_ex(GF_InlineScene *is, MFURL *url, u32 obj_type_hint, Bool lock_timelines, struct _mediaobj *sync_ref, Bool always_load_new, GF_Node *node_ptr); -void gf_inline_setup_object(GF_InlineScene *is, GF_ObjectManager *odm); -/*restarts inline scene - care has to be taken not to remove the scene while it is traversed*/ -void gf_inline_restart(GF_InlineScene *is); +void gf_scene_buffering_info(GF_Scene *scene); +void gf_scene_attach_to_compositor(GF_Scene *scene); +struct _mediaobj *gf_scene_get_media_object(GF_Scene *scene, MFURL *url, u32 obj_type_hint, Bool lock_timelines); +struct _mediaobj *gf_scene_get_media_object_ex(GF_Scene *scene, MFURL *url, u32 obj_type_hint, Bool lock_timelines, struct _mediaobj *sync_ref, Bool force_new_if_not_attached, GF_Node *node_ptr); +void gf_scene_setup_object(GF_Scene *scene, GF_ObjectManager *odm); /*updates scene duration based on settings*/ -void gf_inline_set_duration(GF_InlineScene *is); +void gf_scene_set_duration(GF_Scene *scene); /*locate media object by ODID (non dynamic ODs) or URL (dynamic ODs)*/ -struct _mediaobj *gf_inline_find_object(GF_InlineScene *is, u16 ODID, char *url); +struct _mediaobj *gf_scene_find_object(GF_Scene *scene, u16 ODID, char *url); /*returns scene time in sec - exact meaning of time depends on standard used*/ -Double gf_inline_get_time(void *_is); -/*returns true if the given node DEF name is the url target view (eg blabla#myview)*/ -Bool gf_inline_default_scene_viewpoint(GF_Node *node); +Double gf_scene_get_time(void *_is); /*register extra scene graph for on-screen display*/ -void gf_inline_register_extra_graph(GF_InlineScene *is, GF_SceneGraph *extra_scene, Bool do_remove); +void gf_scene_register_extra_graph(GF_Scene *scene, GF_SceneGraph *extra_scene, Bool do_remove); /*forces scene size info (without changing pixel metrics) - this may be needed by modules using extra graphs (like timedtext)*/ -void gf_inline_force_scene_size(GF_InlineScene *is, u32 width, u32 height); +void gf_scene_force_size(GF_Scene *scene, u32 width, u32 height); /*regenerate a scene graph based on available objects - can only be called for dynamic OD streams*/ -void gf_inline_regenerate(GF_InlineScene *is); +void gf_scene_regenerate(GF_Scene *scene); /*selects given ODM for dynamic scenes*/ -void gf_inline_select_object(GF_InlineScene *is, GF_ObjectManager *odm); +void gf_scene_select_object(GF_Scene *scene, GF_ObjectManager *odm); /*restarts dynamic scene from given time: scene graph is not reseted, objects are just restarted instead of closed and reopened. If a media control is present on inline, from_time is overriden by MC range*/ -void gf_inline_restart_dynamic(GF_InlineScene *is, u64 from_time); -/*owner inline node has been modified*/ -void gf_inline_on_modified(GF_Node *node); -/*returns scene graph associated with an externProto lib - exported for VRML/X3D loaded*/ -GF_SceneGraph *gf_inline_get_proto_lib(void *_is, MFURL *lib_url); +void gf_scene_restart_dynamic(GF_Scene *scene, u64 from_time); /*exported for compositor: handles filtering of "self" parameter indicating anchor only acts on container inline scene not root one. Returns 1 if handled (cf user.h, navigate event)*/ -Bool gf_inline_process_anchor(GF_Node *caller, GF_Event *evt); +Bool gf_scene_process_anchor(GF_Node *caller, GF_Event *evt); +void gf_scene_force_size_to_video(GF_Scene *scene, GF_MediaObject *mo); +void gf_scene_sample_time(GF_Scene *scene); + +Bool gf_scene_check_clocks(GF_ClientService *ns, GF_Scene *scene); + +void gf_scene_notify_event(GF_Scene *scene, u32 event_type, GF_Node *n, void *dom_evt); + + +GF_Node *gf_scene_get_subscene_root(GF_Node *inline_node); + +#ifndef GPAC_DISABLE_VRML + /*extern proto fetcher*/ -GF_SceneGraph *gf_inline_get_proto_lib(void *SceneCallback, MFURL *lib_url); -void gf_inline_force_scene_size_video(GF_InlineScene *is, GF_MediaObject *mo); -void gf_inline_sample_time(GF_InlineScene *is); +typedef struct +{ + MFURL *url; + GF_MediaObject *mo; +} GF_ProtoLink; + +/*returns true if the given node DEF name is the url target view (eg blabla#myview)*/ +Bool gf_inline_is_default_viewpoint(GF_Node *node); + +GF_SceneGraph *gf_inline_get_proto_lib(void *_is, MFURL *lib_url); +Bool gf_inline_is_protolib_object(GF_Scene *scene, GF_ObjectManager *odm); + +/*restarts inline scene - care has to be taken not to remove the scene while it is traversed*/ +void gf_inline_restart(GF_Scene *scene); + +#endif + /*compares object URL with another URL - ONLY USE THIS WITH DYNAMIC ODs*/ -Bool gf_mo_is_same_url(GF_MediaObject *obj, MFURL *inline_url); +Bool gf_mo_is_same_url(GF_MediaObject *obj, MFURL *an_url, Bool *keep_fragment, u32 obj_hint_type); void gf_mo_update_caps(GF_MediaObject *mo); -GF_Node *gf_inline_get_subscene_root(GF_Node *inline_node); -GF_Node *gf_inline_get_parent_node(GF_Node *node, u32 idx); - -const char *gf_inline_get_fragment_uri(GF_Node *node); -void gf_inline_set_fragment_uri(GF_Node *node, const char *uri); +const char *gf_scene_get_fragment_uri(GF_Node *node); +void gf_scene_set_fragment_uri(GF_Node *node, const char *uri); enum { @@ -232,10 +285,42 @@ enum GF_TERM_SINGLE_THREAD = 1<<2, GF_TERM_MULTI_THREAD = 1<<3, GF_TERM_SYSDEC_RESYNC = 1<<4, - GF_TERM_SINGLE_CLOCK = 1<<5, - GF_TERM_DRAW_FRAME = 1<<6 + GF_TERM_SINGLE_CLOCK = 1<<5 +}; + +/*URI relocators are used for containers like zip or ISO FF with file items. The relocator +is in charge of translating the URI, potentially extracting the associated resource and sending +back the new (local or not) URI. Only the interface is defined, URI translators are free to derive from them + +relocate a URI - if NULL is returned, this relocator is not concerned with the URI +otherwise returns the translated URI +*/ + +#define GF_TERM_URI_RELOCATOR \ + Bool (*relocate_uri)(void *__self, const char *parent_uri, const char *uri, char *out_relocated_uri, char *out_localized_uri); \ + +typedef struct __gf_uri_relocator GF_URIRelocator; + +struct __gf_uri_relocator +{ + GF_TERM_URI_RELOCATOR }; +typedef struct +{ + GF_TERM_URI_RELOCATOR + GF_Terminal *term; + char *szAbsRelocatedPath; +} GF_TermLocales; + +#define MAX_SHORTCUTS 200 + +typedef struct +{ + u8 code; + u8 mods; + u8 action; +} GF_Shortcut; struct _tag_terminal @@ -249,7 +334,7 @@ struct _tag_terminal /*file downloader*/ GF_DownloadManager *downloader; /*top level scene*/ - GF_InlineScene *root_scene; + GF_Scene *root_scene; /*Media manager*/ GF_List *codecs; @@ -298,8 +383,19 @@ struct _tag_terminal /*root node of the user prefs*/ GF_SceneGraph *dcci_doc; - GF_List *extensions; - GF_List *unthreaded_extensions; + GF_List *extensions; /*list of all extensions*/ + GF_List *unthreaded_extensions; /*list of extensions to call at each frame*/ + GF_List *event_filters; /*list of extensions filtering events*/ + GF_Mutex *evt_mx; + + /*static URI relocator for locales*/ + GF_TermLocales locales; + + GF_List *uri_relocators; /*list of GF_URIRelocator*/ + + GF_Shortcut shortcuts[MAX_SHORTCUTS]; + Fixed speed_ratio; + }; @@ -313,11 +409,15 @@ void gf_term_stop_codec(GF_Codec *codec); void gf_term_set_threading(GF_Terminal *term, u32 mode); void gf_term_set_priority(GF_Terminal *term, s32 Priority); +void gf_term_register_event_filter(GF_Terminal *term, GF_TermExt *filter); +void gf_term_unregister_event_filter(GF_Terminal *term, GF_TermExt *filter); + +Bool gf_term_forward_event(GF_Terminal *term, GF_Event *evt, Bool consumed); /*error report function*/ void gf_term_message(GF_Terminal *app, const char *service, const char *message, GF_Err error); /*creates service for given OD / URL*/ -void gf_term_connect_object(GF_Terminal *app, GF_ObjectManager *odm, char *serviceURL, GF_ClientService *ParentService); +void gf_term_connect_object(GF_Terminal *app, GF_ObjectManager *odm, char *serviceURL, char *parent_url); /*creates service for given channel / URL*/ GF_Err gf_term_connect_remote_channel(GF_Terminal *app, GF_Channel *ch, char *URL); @@ -349,6 +449,7 @@ For these nodes, the traverse effect passed will be NULL.*/ void gf_term_queue_node_traverse(GF_Terminal *term, GF_Node *node); void gf_term_unqueue_node_traverse(GF_Terminal *term, GF_Node *node); +Bool gf_term_lock_codec(GF_Codec *codec, Bool lock); /*clock*/ @@ -380,7 +481,7 @@ hasOCR indicates whether the stream being attached carries object clock referenc @clocks: list of clocks in ES namespace (service) @is: inline scene to solve clock dependencies */ -GF_Clock *gf_clock_attach(GF_List *clocks, GF_InlineScene *is, u16 OCR_ES_ID, u16 ES_ID, s32 hasOCR); +GF_Clock *gf_clock_attach(GF_List *clocks, GF_Scene *scene, u16 OCR_ES_ID, u16 ES_ID, s32 hasOCR); /*reset clock (only called by channel owning clock)*/ void gf_clock_reset(GF_Clock *ck); /*stops clock (only called for scene clock)*/ @@ -424,11 +525,16 @@ enum GF_ESM_ES_UNAVAILABLE }; +enum +{ + GF_ESM_CAROUSEL_NONE = 0, + GF_ESM_CAROUSEL_MPEG4, + GF_ESM_CAROUSEL_MPEG2, +}; + /*data channel (elementary stream)*/ struct _es_channel { - /*security check on channel*/ - u32 chan_id; /*service this channel belongs to*/ GF_ClientService *service; /*stream descriptor*/ @@ -464,6 +570,8 @@ struct _es_channel /* SL reassembler */ /*current AU TSs*/ u32 DTS, CTS; + /*special case for carousels in the past*/ + u32 CTS_past_offset; /*AU and Packet seq num info*/ u32 au_sn, pck_sn; u32 max_au_sn, max_pck_sn; @@ -483,6 +591,7 @@ struct _es_channel Bool first_au_fetched; /* used in Carousel, to skip packets until the end of AU */ + u8 carousel_type; Bool skip_carousel_au; /* TimeStamp to Media Time mapping*/ @@ -518,8 +627,12 @@ struct _es_channel GF_IPMPTool *ipmp_tool; Bool is_protected; + u32 resync_drift; + /*TSs as received from network - these are used for cache storage*/ u64 net_dts, net_cts; + + Bool no_timestamps; }; /*creates a new channel for this stream*/ @@ -543,10 +656,10 @@ void gf_es_drop_au(GF_Channel *ch); /*performs final setup upon connection confirm*/ void gf_es_on_connect(GF_Channel *ch); /*reconfigure SL for this channel*/ -void gf_es_reconfig_sl(GF_Channel *ch, GF_SLConfig *slc); +void gf_es_reconfig_sl(GF_Channel *ch, GF_SLConfig *slc, Bool use_m2ts_sections); /*hack for streaming: whenever a time map (media time <-> TS time) event is received on the channel reset decoding buffer this is needed because all server tested resend packets on already running channel*/ -void gf_es_map_time(GF_Channel *ch, Bool reset); +void gf_es_reset_buffers(GF_Channel *ch); /*dummy channels are used by scene decoders which don't use ESM but load directly the scene graph themselves these channels are ALWAYS pulling ones, and this function will init the channel clock if needed*/ void gf_es_init_dummy(GF_Channel *ch); @@ -566,7 +679,7 @@ enum handling of the CB. For video, the output is kept alive, For audio, the output is reseted (don't want audio loop ;)*/ GF_ESM_CODEC_EOS = 2, - /*pause: the decoder is stoped but the CB is kept intact + /*pause: the decoder is stopped but the CB is kept intact THIS IS NOT USED AS A CODEC STATUS, but only for signaling that the CB shouldn't be reseted - the real status of a "paused" decoder is STOP*/ GF_ESM_CODEC_PAUSE = 3, @@ -609,6 +722,8 @@ struct _generic_codec u32 last_unit_dts; /*last processed CTS on base layer - seeking detection*/ u32 last_unit_cts; + /*SHA signature for the last processed unit. Only for images (Capacity==1)*/ + u8 last_unit_signature[20]; /*in case the codec performs temporal re-ordering itself*/ Bool is_reordering; u32 prev_au_size; @@ -619,8 +734,10 @@ struct _generic_codec u32 last_stat_start, cur_bit_size; u32 avg_bit_rate, max_bit_rate; u32 total_dec_time, nb_dec_frames, max_dec_time; - /*number of droped frames*/ + /*number of frames dropped at the presentation*/ u32 nb_droped; + /*we detect if the same image is sent again and again to the decoder (using last_unit_signature)*/ + u32 nb_repeted_frames; /*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*/ @@ -642,10 +759,6 @@ GF_Codec *gf_codec_use_codec(GF_Codec *codec, GF_ObjectManager *odm); /*OD manager*/ - -/*all inserted ODs have this ODID*/ -#define GF_ESM_DYNAMIC_OD_ID 1050 - enum { /*flag set if object cannot be time-controloed*/ @@ -660,6 +773,11 @@ enum GF_ODM_INLINE_PROFILES = (1<<5), /*flag set if object declared by network service, not from OD stream*/ GF_ODM_NOT_IN_OD_STREAM = (1<<6), + /*flag set if object is an entry point of the network service*/ + GF_ODM_SERVICE_ENTRY = (1<<7), + + /*flag set if object has been started before any start request from the scene*/ + GF_ODM_PREFETCH = (1<<8), /*dynamic flags*/ @@ -675,6 +793,13 @@ enum GF_ODM_STATE_BLOCKED, }; +enum +{ + GF_ODM_ACTION_PLAY, + GF_ODM_ACTION_STOP, + GF_ODM_ACTION_DELETE, +}; + struct _od_manager { /*pointer to terminal*/ @@ -682,15 +807,17 @@ struct _od_manager /*the service used by this ODM. If the service private data is this ODM, then the service was created for this ODM*/ GF_ClientService *net_service; /*parent scene or NULL for root scene*/ - struct _inline_scene *parentscene; + GF_Scene *parentscene; /*channels associated with this object (media channels, OCR, IPMP, OCI, etc)*/ GF_List *channels; /*sub scene for inline/animation or NULL */ - struct _inline_scene *subscene; + GF_Scene *subscene; /*object codec (media or BIFS for AnimationStream) attached if any*/ struct _generic_codec *codec; +#ifndef GPAC_MINIMAL_ODF /*OCI codec attached if any*/ struct _generic_codec *oci_codec; +#endif /*OCR codec attached if any*/ struct _generic_codec *ocr_codec; @@ -721,12 +848,16 @@ struct _od_manager */ u64 media_start_time, media_stop_time; + u32 action_type; + +#ifndef GPAC_DISABLE_VRML /*the one and only media control currently attached to this object*/ struct _media_control *media_ctrl; /*the list of media control controling the object*/ GF_List *mc_stack; /*the media sensor(s) attached to this object*/ GF_List *ms_stack; +#endif }; @@ -749,15 +880,13 @@ void gf_odm_set_duration(GF_ObjectManager *odm, GF_Channel *, u64 stream_duratio /*signals end of stream on channels*/ void gf_odm_on_eos(GF_ObjectManager *odm, GF_Channel *); /*start Object streams and queue object for network PLAY*/ -void gf_odm_start(GF_ObjectManager *odm); +void gf_odm_start(GF_ObjectManager *odm, Bool was_in_media_queue); /*stop OD streams*/ void gf_odm_stop(GF_ObjectManager *odm, Bool force_close); /*send PLAY request to network - needed to properly handle multiplexed inputs ONLY called by service handler (media manager thread)*/ void gf_odm_play(GF_ObjectManager *odm); -/*returns 1 if this is a segment switch, 0 otherwise - takes care of object restart if segment switch*/ -Bool gf_odm_check_segment_switch(GF_ObjectManager *odm); /*pause object (mediaControl use only)*/ void gf_odm_pause(GF_ObjectManager *odm); /*resume object (mediaControl use only)*/ @@ -775,6 +904,7 @@ GF_Segment *gf_odm_find_segment(GF_ObjectManager *odm, char *descName); /*locks ODM with destruction check - returns 0 if object manager is not attached to object*/ Bool gf_odm_lock_mo(struct _mediaobj *mo); +void gf_odm_signal_eos(GF_ObjectManager *odm); /*GF_MediaObject: link between real object manager and scene. although there is a one-to-one mapping between a MediaObject and an ObjectManager, we have to keep them seperated in order to handle OD remove commands which destroy @@ -836,10 +966,14 @@ GF_Err gf_odm_post_es_setup(struct _es_channel *ch, struct _generic_codec *dec, */ void gf_term_attach_service(GF_Terminal *term, GF_InputService *service_hdl); + +Bool gf_term_send_event(GF_Terminal *term, GF_Event *evt); + /*media access events */ void gf_term_service_media_event(GF_ObjectManager *odm, u32 event_type); -u32 URL_GetODID(MFURL *url); +/*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); #ifdef __cplusplus } diff --git a/include/gpac/ismacryp.h b/include/gpac/ismacryp.h index caf57da..270b299 100644 --- a/include/gpac/ismacryp.h +++ b/include/gpac/ismacryp.h @@ -32,6 +32,15 @@ extern "C" { #include <gpac/isomedia.h> +/*loads key and salt from a LOCAL gpac-DRM file (cf MP4Box doc)*/ +GF_Err gf_ismacryp_gpac_get_info(u32 stream_id, char *drm_file, char *key, char *salt); + +/*loads key and salt for MPEG4IP protected files*/ +Bool gf_ismacryp_mpeg4ip_get_info(char *kms_uri, char *key, char *salt); + +/*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]); + enum { /*no selective encryption*/ @@ -80,11 +89,13 @@ typedef struct } GF_TrackCryptInfo; +#if !defined(GPAC_DISABLE_MCRYPT) && !defined(GPAC_DISABLE_ISOM_WRITE) + /*encrypts track - logs, progress: info callbacks, NULL for stdout*/ -GF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (*progress)(void *cbk, u32 done, u32 total), void *cbk); +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*/ -GF_Err gf_ismacryp_decrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (*progress)(void *cbk, u32 done, u32 total), void *cbk); +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). @@ -98,14 +109,8 @@ GF_Err gf_ismacryp_decrypt_file(GF_ISOFile *mp4file, const char *drm_file); */ GF_Err gf_ismacryp_crypt_file(GF_ISOFile *mp4file, const char *drm_file); -/*loads key and salt from a LOCAL gpac-DRM file (cf MP4Box doc)*/ -GF_Err gf_ismacryp_gpac_get_info(u32 stream_id, char *drm_file, char *key, char *salt); - -/*loads key and salt for MPEG4IP protected files*/ -Bool gf_ismacryp_mpeg4ip_get_info(char *kms_uri, char *key, char *salt); +#endif /*!defined(GPAC_DISABLE_MCRYPT) && !defined(GPAC_DISABLE_ISOM_WRITE)*/ -/*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]); #ifdef __cplusplus } diff --git a/include/gpac/iso639.h b/include/gpac/iso639.h index 5ea68b2..72cbdba 100644 --- a/include/gpac/iso639.h +++ b/include/gpac/iso639.h @@ -28,494 +28,496 @@ /*ISO 639 code names - first string is readable english name of the language - - second string is 3-char code of language as per ISO/IEC 639-2 + - second string is 3-char code of language as per ISO/IEC 639-2/T - third string is 2-char code of language as per ISO/IEC 639-1, and may be empty */ static const char *GF_ISO639_Lang[] = { - "Abkhazian","abk", "ab", - "Achinese","ace", "", - "Acoli","ach", "", - "Adangme","ada", "", - "Adygei","ady", "", - "Adyghe","ady", "", - "Afar","aar", "aa", - "Afrihili","afh", "", - "Afrikaans","afr", "af", - "Afro-Asiatic (Other)","afa", "", - "Akan","aka", "", - "Akkadian","akk", "", - "Albanian","alb/sqi", "sq", - "Aleut","ale", "", - "Algonquian languages","alg", "", - "Altaic (Other)","tut", "", - "Amharic","amh", "am", - "Apache languages","apa", "", - "Arabic","ara", "ar", - "Aragonese","arg", "", - "Aramaic","arc", "", - "Arapaho","arp", "", - "Araucanian","arn", "", - "Arawak","arw", "", - "Armenian","arm/hye", "hy", - "Artificial (Other)","art", "", - "Assamese","ast", "as", - "Athapascan languages","ath", "", - "Australian languages","aus", "", - "Austronesian (Other)","map", "", - "Avaric","ava", "", - "Avestan","ave", "", - "Awadhi","awa", "", - "Aymara","aym", "ay", - "Azerbaijani","aze", "az", - "Bable","ast", "", - "Balinese","ban", "", - "Baltic (Other)","bat", "", - "Baluchi","bal", "", - "Bambara","bam", "", - "Bamileke languages","bai", "", - "Banda","bad", "", - "Bantu (Other)","bnt", "", - "Basa","bas", "", - "Bashkir","bak", "ba", - "Basque","baq/eus", "eu", - "Batak (Indonesia)","btk", "", - "Beja","bej", "", - "Belarusian","bel", "be", - "Bemba","bem", "", - "Bengali","ben", "bn", - "Berber (Other)","ber", "", - "Bhojpuri","bho", "", - "Bihari","bih", "bh", - "Bikol","bik", "", - "Bini","bin", "", - "Bislama","bis", "bi", - "BokmÃ¥l, Norwegian","nob", "", - "Bosnian","bos", "", - "Braj","bra", "", - "Breton","bre", "br", - "Buginese","bug", "", - "Bulgarian","bul", "bg", - "Buriat","bua", "", - "Burmese","bur/mya", "my", - "Caddo","cad", "", - "Carib","car", "", - "Castilian","spa", "", - "Catalan","cat", "ca", - "Caucasian (Other)","cau", "", - "Cebuano","ceb", "", - "Celtic (Other)","cel", "", - "Central American Indian (Other)","cai", "", - "Chagatai","chg", "", - "Chamic languages","cmc", "", - "Chamorro","cha", "", - "Chechen","che", "", - "Cherokee","chr" , "", - "Chewa","nya", "", - "Cheyenne","chy", "", - "Chibcha","chb", "", - "Chichewa","nya", "", - "Chinese","chi/zho", "zh", - "Chinook jargon","chn", "", - "Chipewyan","chp", "", - "Choctaw","cho", "", - "Chuang","zha", "", - "Church Slavic (Slavonic)","chu", "", - "Chuukese","chk", "", - "Chuvash","chv", "", - "Coptic","cop", "", - "Cornish","cor", "", - "Corsican","cos", "co", - "Cree","cre" , "", - "Creek","mus" , "", - "Creoles and pidgins(Other)","crp", "", - "Creoles and pidgins, English-based (Other)","cpe", "", - "Creoles and pidgins, French-based (Other)","cpf", "", - "Creoles and pidgins, Portuguese-based (Other)","cpp", "", - "Crimean Tatar","crh", "", - "Crimean Turkish","crh", "", - "Croatian","scr/hrv", "hr", - "Cushitic (Other)","cus", "", - "Czech","cze/ces", "cs", - "Dakota","dak", "", - "Danish","dan", "da", - "Dargwa","dar", "", - "Dayak","day", "", - "Delaware","del", "", - "Dinka","din", "", - "Divehi","div" , "", - "Dogri","doi", "", - "Dogrib","dgr" , "", - "Dravidian (Other)","dra", "", - "Duala","dua", "", - "Dutch","dut/nld", "nl", - "Dutch, Middle (ca. 1050-1350)","dum", "", - "Dyula","dyu", "", - "Dzongkha","dzo", "dz", - "Efik","efi", "", - "Egyptian (Ancient)","egy", "", - "Ekajuk","eka", "", - "Elamite","elx", "", - "English","eng", "en", - "English, Middle (1100-1500)","enm", "", - "English, Old (ca.450-1100)","ang", "", - "Erzya","myv", "", - "Esperanto","epo", "eo", - "Estonian","est", "et", - "Ewe","ewe", "", - "Ewondo","ewo", "", - "Fang","fan", "", - "Fanti","fat" , "", - "Faroese","fao", "fo", - "Fijian","fij", "fj", - "Finnish","fin", "fi", - "Finno-Ugrian (Other)","fiu", "", - "Fon","fon", "", - "French","fre/fra", "fr", - "French, Middle (ca.1400-1600)","frm", "", - "French, Old (842-ca.1400)","fro", "", - "Frisian","fry", "fy", - "Friulian","fur" , "", - "Fulah","ful", "", - "Ga","gaa", "", - "Gaelic","gla", "", - "Gallegan","glg", "gl", - "Ganda","lug", "", - "Gayo","gay", "", - "Gbaya","gba" , "", - "Geez","gez", "", - "Georgian","geo/kat", "ka", - "German","ger/deu", "de", - "German, Low","nds" , "", - "German, Middle High (ca.1050-1500)","gmh", "", - "German, Old High (ca.750-1050)","goh", "", - "Germanic (Other)","gem", "", - "Gikuyu","kik", "", - "Gilbertese","gil", "", - "Gondi","gon", "", - "Gorontalo","gor", "", - "Gothic","got", "", - "Grebo","grb", "", - "Greek, Ancient (to 1453)","grc", "", - "Greek, Modern (1453-)","gre/ell", "el", - "Guarani","grn", "gn", - "Gujarati","guj", "gu", - "Gwich´in","gwi", "", - "Haida","hai", "", - "Haitian","hat", "", - "Haitian Creole","hat", "", - "Hausa","hau", "ha", - "Hawaiian","haw", "", - "Hebrew","heb", "he", - "Herero","her", "", - "Hiligaynon","hil", "", - "Himachali","him", "", - "Hindi","hin", "hi", - "Hiri Motu","hmo", "", - "Hittite","hit", "", - "Hmong","hmn", "", - "Hungarian","hun", "hu", - "Hupa","hup", "", - "Iban","iba", "", - "Icelandic","ice/isl", "is", - "Ido","ido", "", - "Igbo","ibo" , "", - "Ijo","ijo", "", - "Iloko","ilo", "", - "Inari Sami","smn", "", - "Indic (Other)","inc", "", - "Indo-European (Other)","ine", "", - "Indonesian","ind", "id", - "Ingush","inh", "", - "Interlingua (International Auxiliary Language Association)","ina", "ia", - "Interlingue","ile", "", - "Inuktitut","iku", "iu", - "Inupiaq","ipk", "ik", - "Iranian (Other)","ira", "", - "Irish","gle", "ga", - "Irish, Middle (900-1200)","mga", "", - "Irish, Old (to 900)","sga", "", - "Iroquoian languages","iro", "", - "Italian","ita", "it", - "Japanese","jpn", "ja", - "Javanese","jav", "jv", - "Judeo-Arabic","jrb", "", - "Judeo-Persian","jpr", "", - "Kabardian","kbd", "", - "Kabyle","kab", "", - "Kachin","kac", "", - "Kalaallisut","kal", "kl", - "Kalmyk","xal", "", - "Kamba","kam", "", - "Kannada","kan", "kn", - "Kanuri","kau", "", - "Karachay-Balkar","krc", "", - "Kara-Kalpak","kaa", "", - "Karen","kar", "", - "Kashmiri","kas", "ks", - "Kashubian","csb", "", - "Kawi","kaw", "", - "Kazakh","kaz", "kk", - "Khasi","kha", "", - "Khmer","khm", "km", - "Khoisan (Other)","khi", "", - "Khotanese","kho", "", - "Kikuyu","kik", "", - "Kimbundu","kmb", "", - "Kinyarwanda","kin", "rw", - "Kirghiz","kir", "ky", - "Komi","kom", "", - "Kongo","kon" , "", - "Konkani","kok" , "", - "Korean","kor", "ko", - "Kosraean","kos" , "", - "Kpelle","kpe" , "", - "Kru","kro" , "", - "Kuanyama","kua", "", - "Kumyk","kum" , "", - "Kurdish","kur", "ku", - "Kurukh","kru" , "", - "Kutenai","kut", "", - "Kwanyama","kua", "", - "Ladino","lad" , "", - "Lahnda","lah" , "", - "Lamba","lam" , "", - "Lao","lao", "lo", - "Latin","lat", "la", - "Latvian","lav", "lv", - "Letzeburgesch","ltz", "", - "Lezghian (lezLimburgan - limLimburger - limlimburgish)","lim", "", - "Lingala","lin", "ln", - "Lithuanian","lit", "lt", - "Low German","nds", "", - "Low Saxon","nds", "", - "Lozi","loz" , "", - "Luba-Katanga","lub" , "", - "Luba-Lulua","lua" , "", - "Luiseno","lui", "", - "Lule Sami","smj", "", - "Lunda","lun" , "", - "Luo (Kenya and Tanzania)","luo", "", - "Luxembourgish","ltz", "", - "Lushai","lus" , "", - "Macedonian","mac/mkd", "mk", - "Madurese","mad" , "", - "Magahi","mag" , "", - "Maithili","mai", "", - "Makasar","mak", "", - "Malagasy","mlg", "mg", - "Malay","may/msa", "ms", - "Malayalam","mal", "", - "Maltese","mlt", "ml", - "Manchu","mnc", "", - "Mandar","mdr", "", - "Mandingo","man", "", - "Manipuri","mni" , "", - "Manobo languages","mno" , "", - "Manx","glv", "", - "Maori","mao/mri", "mi", - "Marathi","mar", "mr", - "Mari","chm" , "", - "Marshallese","mah", "", - "Marwari","mwr" , "", - "Masai","mas" , "", - "Mayan languages","myn" , "", - "Mende","men" , "", - "Micmac","mic" , "", - "Minangkabau","min" , "", - "Miscellaneous languages","mis" , "", - "Mohawk","moh" , "", - "Moksha","mdf", "", - "Moldavian","mol", "mo", - "Mon-Khmer (Other)","mkh" , "", - "Mongo","lol" , "", - "Mongolian","mon", "mn", - "Mossi","mos" , "", - "Multiple languages","mul" , "", - "Munda languages","mun" , "", - "Nahuatl","nah" , "", - "Nauru","nau", "na", - "Navaho","nav", "", - "Navajo","nav", "", - "Ndebele, North","nde", "", - "Ndebele, South","nbl", "", - "Ndonga, ndoNeapolitan","nap", "", - "Nepali","nep", "ne", - "Newari","new" , "", - "Nias","nia" , "", - "Niger-Kordofanian (Other)","nic", "", - "Nilo-Saharan (Other)","ssa" , "", - "Niuean","niu" , "", - "Nogai","nog", "", - "Norse, Old","non", "", - "North American Indian (Other)","nai" , "", - "Northern Sami","sme", "", - "North Ndebele","nde", "", - "Norwegian","nor", "no", - "Norwegian BokmÃ¥l","nob", "", - "Norwegian Nynorsk","nno", "", - "Nubian languages","nub" , "", - "Nyamwezi","nym" , "", - "Nyanja","nya", "", - "Nyankole","nyn", "", - "Nynorsk, Norwegian","nno" , "", - "Nyoro","nyo" , "", - "Nzima","nzi" , "", - "Occitan (post 1500)","oci", "oc", - "Ojibwa","oji" , "", - "Old Bulgarian","chu", "", - "Old Church Slavonic","chu", "", - "Old Slavonic","chu", "", - "Oriya","ori", "or", - "Oromo","orm", "om", - "Osage","osa", "", - "Ossetian - Ossetic","oss", "", - "Otomian languages","oto", "", - "Pahlavi","pal" , "", - "Palauan","pau", "", - "Pali","pli", "", - "Pampanga","pam", "", - "Pangasinan","pag", "", - "Panjabi","pan", "pa", - "Papiamento","pap" , "", - "Papuan (Other)","paa" , "", - "Persian","per/fas", "fa", - "Persian, Old (ca.600-400)","peo" , "", - "Philippine (Other)","phi" , "", - "Phoenician","phn" , "", - "Pohnpeian","pon" , "", - "Polish","pol", "pl", - "Portuguese","por", "pt", - "Prakrit languages","pra", "", - "Provençal","oci", "", - "Provençal, Old (to 1500)","pro" , "", - "Pushto","pus", "ps", - "Quechua","que", "qu", - "Raeto-Romance","roh", "rm", - "Rajasthani","raj", "", - "Rapanui","rap", "", - "Rarotongan","rar", "", - "Romance (Other)","roa", "", - "Romanian","rum/ron", "ro", - "Romany","rom" , "", - "Rundi","run", "rn", - "Russian","rus", "ru", - "Salishan languages","sal" , "", - "Samaritan Aramaic","sam" , "", - "Sami languages (Other)","smi" , "", - "Samoan","smo", "sm", - "Sandawe","sad" , "", - "Sango","sag", "sg", - "Sanskrit","san", "sa", - "Santali","sat", "", - "Sardinian","srd", "", - "Sasak","sas" , "", - "Saxon, Low","nds", "", - "Scots","sco", "", - "Scottish Gaelic","gla" , "", - "Selkup","sel" , "", - "Semitic (Other)","sem" , "", - "Serbian","srp", "sr", - "Serbo-Croatian", "scr", "sh", - "Serer","srr" , "", - "Shan","shn" , "", - "Shona","sna", "sn", - "Sichuan Yi","iii", "", - "Sidamo","sid" , "", - "Sign languages","sgn" , "", - "Siksika","bla" , "", - "Sindhi","snd", "sd", - "Sinhalese","sin", "si", - "Sino-Tibetan (Other)","sit", "", - "Siouan languages","sio", "", - "Skolt Sami","sms" , "", - "Slave (Athapascan)","den" , "", - "Slavic (Other)","sla" , "", - "Slovak","slo", "sk", - "Slovenian","slv", "sl", - "Sogdian","sog" , "", - "Somali","som", "so", - "Songhai","son" , "", - "Soninke","snk" , "", - "Sorbian languages","wen" , "", - "Sotho, Northern","nso" , "", - "Sotho, Southern","sot", "st", - "South American Indian (Other)","sai" , "", - "Southern Sami","sma", "", - "South Ndebele","nbl", "", - "Spanish","spa", "es", - "Sukuma","suk", "", - "Sumerian","sux" , "", - "Sundanese","sun", "su", - "Susu","sus" , "", - "Swahili","swa", "sw", - "Swati","ssw", "ss", - "Swedish","swe", "sv", - "Syriac","syr", "", - "Tagalog","tgl", "tl", - "Tahitian","tah", "", - "Tai (Other)","tai" , "", - "Tajik","tgk", "tg", - "Tamashek","tmh" , "", - "Tamil","tam", "ta", - "Tatar","tat", "tt", - "Telugu","tel", "te", - "Tereno","ter" , "", - "Tetum","tet" , "", - "Thai","tha", "th", - "Tibetan","tib", "bo", - "Tigre","tig" , "", - "Tigrinya","tir", "ti", - "Timne","tem" , "", - "Tiv","tiv" , "", - "Tlingit","tli" , "", - "Tok Pisin","tpi" , "", - "Tokelau","tkl" , "", - "Tonga (Nyasa)","tog" , "to", - "Tonga (Tonga Islands)","ton", "", - "Tsimshian","tsi" , "", - "Tsonga","tso", "ts", - "Tswana","tsn", "tn", - "Tumbuka","tum" , "", - "Tupi languages","tup", "", - "Turkish","tur", "tr", - "Turkish, Ottoman (1500-1928)","ota" , "", - "Turkmen","tuk", "tk", - "Tuvalu","tvl", "", - "Tuvinian","tyv" , "", - "Twi","twi", "tw", - "Udmurt (udmUgaritic)","uga" , "", - "Uighur","uig", "ug", - "Ukrainian","ukr", "uk", - "Umbundu","umb" , "", - "Undetermined","und", "", - "Urdu","urd", "ur", - "Uzbek","uzb", "uz", - "Vai","vai", "", - "Venda","ven" , "", - "Vietnamese","vie", "vi", - "Volapük","vol", "vo", - "Votic","vot", "", - "Wakashan languages","wak" , "", - "Walamo","wal" , "", - "Walloon","wln", "", - "Waray","war", "", - "Washo","was" , "", - "Welsh","wel", "cy", - "Wolof","wol", "wo", - "Xhosa","xho", "xh", - "Yakut","sah" , "", - "Yao","yao" , "", - "Yapese","yap", "", - "Yiddish","yid", "yi", - "Yoruba","yor", "yo", - "Yupik languages","ypk" , "", - "Zande","znd" , "", - "Zapotec","zap" , "", - "Zenaga","zen" , "", - "Zhuang","zha", "za", - "Zulu","zul", "zu", - "Zuni","zun", "", + "Abkhazian","abk","ab", + "Achinese","ace","", + "Acoli","ach","", + "Adangme","ada","", + "Adyghe; Adygei","ady","", + "Afar","aar","aa", + "Afrihili","afh","", + "Afrikaans","afr","af", + "Afro-Asiatic languages","afa","", + "Ainu","ain","", + "Akan","aka","ak", + "Akkadian","akk","", + "Albanian","sqi","sq", + "Aleut","ale","", + "Algonquian languages","alg","", + "Altaic languages","tut","", + "Amharic","amh","am", + "Angika","anp","", + "Apache languages","apa","", + "Arabic","ara","ar", + "Aragonese","arg","an", + "Arapaho","arp","", + "Arawak","arw","", + "Armenian","hye","hy", + "Aromanian; Arumanian; Macedo-Romanian","rup","", + "Artificial languages","art","", + "Assamese","asm","as", + "Asturian; Bable; Leonese; Asturleonese","ast","", + "Athapascan languages","ath","", + "Australian languages","aus","", + "Austronesian languages","map","", + "Avaric","ava","av", + "Avestan","ave","ae", + "Awadhi","awa","", + "Aymara","aym","ay", + "Azerbaijani","aze","az", + "Balinese","ban","", + "Baltic languages","bat","", + "Baluchi","bal","", + "Bambara","bam","bm", + "Bamileke languages","bai","", + "Banda languages","bad","", + "Bantu languages","bnt","", + "Basa","bas","", + "Bashkir","bak","ba", + "Basque","eus","eu", + "Batak languages","btk","", + "Beja; Bedawiyet","bej","", + "Belarusian","bel","be", + "Bemba","bem","", + "Bengali","ben","bn", + "Berber languages","ber","", + "Bhojpuri","bho","", + "Bihari languages","bih","bh", + "Bikol","bik","", + "Bini; Edo","bin","", + "Bislama","bis","bi", + "Blin; Bilin","byn","", + "Blissymbols; Blissymbolics; Bliss","zbl","", + "BokmÃ¥l, Norwegian; Norwegian BokmÃ¥l","nob","nb", + "Bosnian","bos","bs", + "Braj","bra","", + "Breton","bre","br", + "Buginese","bug","", + "Bulgarian","bul","bg", + "Buriat","bua","", + "Burmese","mya","my", + "Caddo","cad","", + "Catalan; Valencian","cat","ca", + "Caucasian languages","cau","", + "Cebuano","ceb","", + "Celtic languages","cel","", + "Central American Indian languages","cai","", + "Central Khmer","khm","km", + "Chagatai","chg","", + "Chamic languages","cmc","", + "Chamorro","cha","ch", + "Chechen","che","ce", + "Cherokee","chr","", + "Cheyenne","chy","", + "Chibcha","chb","", + "Chichewa; Chewa; Nyanja","nya","ny", + "Chinese","zho","zh", + "Chinook jargon","chn","", + "Chipewyan; Dene Suline","chp","", + "Choctaw","cho","", + "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic","chu","cu", + "Chuukese","chk","", + "Chuvash","chv","cv", + "Classical Newari; Old Newari; Classical Nepal Bhasa","nwc","", + "Classical Syriac","syc","", + "Coptic","cop","", + "Cornish","cor","kw", + "Corsican","cos","co", + "Cree","cre","cr", + "Creek","mus","", + "Creoles and pidgins","crp","", + "Creoles and pidgins, English based","cpe","", + "Creoles and pidgins, French-based","cpf","", + "Creoles and pidgins, Portuguese-based","cpp","", + "Crimean Tatar; Crimean Turkish","crh","", + "Croatian","hrv","hr", + "Cushitic languages","cus","", + "Czech","ces","cs", + "Dakota","dak","", + "Danish","dan","da", + "Dargwa","dar","", + "Delaware","del","", + "Dinka","din","", + "Divehi; Dhivehi; Maldivian","div","dv", + "Dogri","doi","", + "Dogrib","dgr","", + "Dravidian languages","dra","", + "Duala","dua","", + "Dutch, Middle (ca.1050-1350)","dum","", + "Dutch; Flemish","nld","nl", + "Dyula","dyu","", + "Dzongkha","dzo","dz", + "Eastern Frisian","frs","", + "Efik","efi","", + "Egyptian (Ancient)","egy","", + "Ekajuk","eka","", + "Elamite","elx","", + "English","eng","en", + "English, Middle (1100-1500)","enm","", + "English, Old (ca.450-1100)","ang","", + "Erzya","myv","", + "Esperanto","epo","eo", + "Estonian","est","et", + "Ewe","ewe","ee", + "Ewondo","ewo","", + "Fang","fan","", + "Fanti","fat","", + "Faroese","fao","fo", + "Fijian","fij","fj", + "Filipino; Pilipino","fil","", + "Finnish","fin","fi", + "Finno-Ugrian languages","fiu","", + "Fon","fon","", + "French","fra","fr", + "French, Middle (ca.1400-1600)","frm","", + "French, Old (842-ca.1400)","fro","", + "Friulian","fur","", + "Fulah","ful","ff", + "Ga","gaa","", + "Gaelic; Scottish Gaelic","gla","gd", + "Galibi Carib","car","", + "Galician","glg","gl", + "Ganda","lug","lg", + "Gayo","gay","", + "Gbaya","gba","", + "Geez","gez","", + "Georgian","kat","ka", + "German","deu","de", + "German, Middle High (ca.1050-1500)","gmh","", + "German, Old High (ca.750-1050)","goh","", + "Germanic languages","gem","", + "Gilbertese","gil","", + "Gondi","gon","", + "Gorontalo","gor","", + "Gothic","got","", + "Grebo","grb","", + "Greek, Ancient (to 1453)","grc","", + "Greek, Modern (1453-)","ell","el", + "Guarani","grn","gn", + "Gujarati","guj","gu", + "Gwich'in","gwi","", + "Haida","hai","", + "Haitian; Haitian Creole","hat","ht", + "Hausa","hau","ha", + "Hawaiian","haw","", + "Hebrew","heb","he", + "Herero","her","hz", + "Hiligaynon","hil","", + "Himachali languages; Western Pahari languages","him","", + "Hindi","hin","hi", + "Hiri Motu","hmo","ho", + "Hittite","hit","", + "Hmong; Mong","hmn","", + "Hungarian","hun","hu", + "Hupa","hup","", + "Iban","iba","", + "Icelandic","isl","is", + "Ido","ido","io", + "Igbo","ibo","ig", + "Ijo languages","ijo","", + "Iloko","ilo","", + "Inari Sami","smn","", + "Indic languages","inc","", + "Indo-European languages","ine","", + "Indonesian","ind","id", + "Ingush","inh","", + "Interlingua (International Auxiliary Language Association)","ina","ia", + "Interlingue; Occidental","ile","ie", + "Inuktitut","iku","iu", + "Inupiaq","ipk","ik", + "Iranian languages","ira","", + "Irish","gle","ga", + "Irish, Middle (900-1200)","mga","", + "Irish, Old (to 900)","sga","", + "Iroquoian languages","iro","", + "Italian","ita","it", + "Japanese","jpn","ja", + "Javanese","jav","jv", + "Judeo-Arabic","jrb","", + "Judeo-Persian","jpr","", + "Kabardian","kbd","", + "Kabyle","kab","", + "Kachin; Jingpho","kac","", + "Kalaallisut; Greenlandic","kal","kl", + "Kalmyk; Oirat","xal","", + "Kamba","kam","", + "Kannada","kan","kn", + "Kanuri","kau","kr", + "Kara-Kalpak","kaa","", + "Karachay-Balkar","krc","", + "Karelian","krl","", + "Karen languages","kar","", + "Kashmiri","kas","ks", + "Kashubian","csb","", + "Kawi","kaw","", + "Kazakh","kaz","kk", + "Khasi","kha","", + "Khoisan languages","khi","", + "Khotanese; Sakan","kho","", + "Kikuyu; Gikuyu","kik","ki", + "Kimbundu","kmb","", + "Kinyarwanda","kin","rw", + "Kirghiz; Kyrgyz","kir","ky", + "Klingon; tlhIngan-Hol","tlh","", + "Komi","kom","kv", + "Kongo","kon","kg", + "Konkani","kok","", + "Korean","kor","ko", + "Kosraean","kos","", + "Kpelle","kpe","", + "Kru languages","kro","", + "Kuanyama; Kwanyama","kua","kj", + "Kumyk","kum","", + "Kurdish","kur","ku", + "Kurukh","kru","", + "Kutenai","kut","", + "Ladino","lad","", + "Lahnda","lah","", + "Lamba","lam","", + "Land Dayak languages","day","", + "Lao","lao","lo", + "Latin","lat","la", + "Latvian","lav","lv", + "Lezghian","lez","", + "Limburgan; Limburger; Limburgish","lim","li", + "Lingala","lin","ln", + "Lithuanian","lit","lt", + "Lojban","jbo","", + "Low German; Low Saxon; German, Low; Saxon, Low","nds","", + "Lower Sorbian","dsb","", + "Lozi","loz","", + "Luba-Katanga","lub","lu", + "Luba-Lulua","lua","", + "Luiseno","lui","", + "Lule Sami","smj","", + "Lunda","lun","", + "Luo (Kenya and Tanzania)","luo","", + "Lushai","lus","", + "Luxembourgish; Letzeburgesch","ltz","lb", + "Macedonian","mkd","mk", + "Madurese","mad","", + "Magahi","mag","", + "Maithili","mai","", + "Makasar","mak","", + "Malagasy","mlg","mg", + "Malay","msa","ms", + "Malayalam","mal","ml", + "Maltese","mlt","mt", + "Manchu","mnc","", + "Mandar","mdr","", + "Mandingo","man","", + "Manipuri","mni","", + "Manobo languages","mno","", + "Manx","glv","gv", + "Maori","mri","mi", + "Mapudungun; Mapuche","arn","", + "Marathi","mar","mr", + "Mari","chm","", + "Marshallese","mah","mh", + "Marwari","mwr","", + "Masai","mas","", + "Mayan languages","myn","", + "Mende","men","", + "Mi'kmaq; Micmac","mic","", + "Minangkabau","min","", + "Mirandese","mwl","", + "Mohawk","moh","", + "Moksha","mdf","", + "Mon-Khmer languages","mkh","", + "Mongo","lol","", + "Mongolian","mon","mn", + "Mossi","mos","", + "Multiple languages","mul","", + "Munda languages","mun","", + "N'Ko","nqo","", + "Nahuatl languages","nah","", + "Nauru","nau","na", + "Navajo; Navaho","nav","nv", + "Ndebele, North; North Ndebele","nde","nd", + "Ndebele, South; South Ndebele","nbl","nr", + "Ndonga","ndo","ng", + "Neapolitan","nap","", + "Nepal Bhasa; Newari","new","", + "Nepali","nep","ne", + "Nias","nia","", + "Niger-Kordofanian languages","nic","", + "Nilo-Saharan languages","ssa","", + "Niuean","niu","", + "No linguistic content; Not applicable","zxx","", + "Nogai","nog","", + "Norse, Old","non","", + "North American Indian languages","nai","", + "Northern Frisian","frr","", + "Northern Sami","sme","se", + "Norwegian","nor","no", + "Norwegian Nynorsk; Nynorsk, Norwegian","nno","nn", + "Nubian languages","nub","", + "Nyamwezi","nym","", + "Nyankole","nyn","", + "Nyoro","nyo","", + "Nzima","nzi","", + "Occitan (post 1500)","oci","oc", + "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)","arc","", + "Ojibwa","oji","oj", + "Oriya","ori","or", + "Oromo","orm","om", + "Osage","osa","", + "Ossetian; Ossetic","oss","os", + "Otomian languages","oto","", + "Pahlavi","pal","", + "Palauan","pau","", + "Pali","pli","pi", + "Pampanga; Kapampangan","pam","", + "Pangasinan","pag","", + "Panjabi; Punjabi","pan","pa", + "Papiamento","pap","", + "Papuan languages","paa","", + "Pedi; Sepedi; Northern Sotho","nso","", + "Persian","fas","fa", + "Persian, Old (ca.600-400 B.C.)","peo","", + "Philippine languages","phi","", + "Phoenician","phn","", + "Pohnpeian","pon","", + "Polish","pol","pl", + "Portuguese","por","pt", + "Prakrit languages","pra","", + "Provençal, Old (to 1500);Occitan, Old (to 1500)","pro","", + "Pushto; Pashto","pus","ps", + "Quechua","que","qu", + "Rajasthani","raj","", + "Rapanui","rap","", + "Rarotongan; Cook Islands Maori","rar","", + "Reserved for local use","qaa-qtz","", + "Romance languages","roa","", + "Romanian; Moldavian; Moldovan","ron","ro", + "Romansh","roh","rm", + "Romany","rom","", + "Rundi","run","rn", + "Russian","rus","ru", + "Salishan languages","sal","", + "Samaritan Aramaic","sam","", + "Sami languages","smi","", + "Samoan","smo","sm", + "Sandawe","sad","", + "Sango","sag","sg", + "Sanskrit","san","sa", + "Santali","sat","", + "Sardinian","srd","sc", + "Sasak","sas","", + "Scots","sco","", + "Selkup","sel","", + "Semitic languages","sem","", + "Serbian","srp","sr", + "Serer","srr","", + "Shan","shn","", + "Shona","sna","sn", + "Sichuan Yi; Nuosu","iii","ii", + "Sicilian","scn","", + "Sidamo","sid","", + "Sign Languages","sgn","", + "Siksika","bla","", + "Sindhi","snd","sd", + "Sinhala; Sinhalese","sin","si", + "Sino-Tibetan languages","sit","", + "Siouan languages","sio","", + "Skolt Sami","sms","", + "Slave (Athapascan)","den","", + "Slavic languages","sla","", + "Slovak","slk","sk", + "Slovenian","slv","sl", + "Sogdian","sog","", + "Somali","som","so", + "Songhai languages","son","", + "Soninke","snk","", + "Sorbian languages","wen","", + "Sotho, Southern","sot","st", + "South American Indian languages","sai","", + "Southern Altai","alt","", + "Southern Sami","sma","", + "Spanish; Castilian","spa","es", + "Sranan Tongo","srn","", + "Sukuma","suk","", + "Sumerian","sux","", + "Sundanese","sun","su", + "Susu","sus","", + "Swahili","swa","sw", + "Swati","ssw","ss", + "Swedish","swe","sv", + "Swiss German; Alemannic; Alsatian","gsw","", + "Syriac","syr","", + "Tagalog","tgl","tl", + "Tahitian","tah","ty", + "Tai languages","tai","", + "Tajik","tgk","tg", + "Tamashek","tmh","", + "Tamil","tam","ta", + "Tatar","tat","tt", + "Telugu","tel","te", + "Tereno","ter","", + "Tetum","tet","", + "Thai","tha","th", + "Tibetan","bod","bo", + "Tigre","tig","", + "Tigrinya","tir","ti", + "Timne","tem","", + "Tiv","tiv","", + "Tlingit","tli","", + "Tok Pisin","tpi","", + "Tokelau","tkl","", + "Tonga (Nyasa)","tog","", + "Tonga (Tonga Islands)","ton","to", + "Tsimshian","tsi","", + "Tsonga","tso","ts", + "Tswana","tsn","tn", + "Tumbuka","tum","", + "Tupi languages","tup","", + "Turkish","tur","tr", + "Turkish, Ottoman (1500-1928)","ota","", + "Turkmen","tuk","tk", + "Tuvalu","tvl","", + "Tuvinian","tyv","", + "Twi","twi","tw", + "Udmurt","udm","", + "Ugaritic","uga","", + "Uighur; Uyghur","uig","ug", + "Ukrainian","ukr","uk", + "Umbundu","umb","", + "Uncoded languages","mis","", + "Undetermined","und","", + "Upper Sorbian","hsb","", + "Urdu","urd","ur", + "Uzbek","uzb","uz", + "Vai","vai","", + "Venda","ven","ve", + "Vietnamese","vie","vi", + "Volapük","vol","vo", + "Votic","vot","", + "Wakashan languages","wak","", + "Walloon","wln","wa", + "Waray","war","", + "Washo","was","", + "Welsh","cym","cy", + "Western Frisian","fry","fy", + "Wolaitta; Wolaytta","wal","", + "Wolof","wol","wo", + "Xhosa","xho","xh", + "Yakut","sah","", + "Yao","yao","", + "Yapese","yap","", + "Yiddish","yid","yi", + "Yoruba","yor","yo", + "Yupik languages","ypk","", + "Zande languages","znd","", + "Zapotec","zap","", + "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki","zza","", + "Zenaga","zen","", + "Zhuang; Chuang","zha","za", + "Zulu","zul","zu", + "Zuni","zun","", NULL }; diff --git a/include/gpac/isomedia.h b/include/gpac/isomedia.h index 06c8610..64dd632 100644 --- a/include/gpac/isomedia.h +++ b/include/gpac/isomedia.h @@ -32,9 +32,11 @@ extern "C" { #endif +#include <gpac/tools.h> -#include <gpac/mpeg4_odf.h> +#ifndef GPAC_DISABLE_ISOM +#include <gpac/mpeg4_odf.h> /*the isomedia file*/ typedef struct __tag_isom GF_ISOFile; @@ -158,6 +160,8 @@ 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' ), + /*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' ), /*MPEG-4 media types*/ @@ -197,6 +201,8 @@ enum /*AVC/H264 media type - not listed as an MPEG-4 type, ALTHOUGH this library automatically remaps GF_AVCConfig to MPEG-4 ESD*/ GF_ISOM_SUBTYPE_AVC_H264 = GF_4CC( 'a', 'v', 'c', '1' ), + GF_ISOM_SUBTYPE_AVC2_H264 = GF_4CC( 'a', 'v', 'c', '2' ), + GF_ISOM_SUBTYPE_SVC_H264 = GF_4CC( 's', 'v', 'c', '1' ), /*3GPP(2) extension subtypes*/ GF_ISOM_SUBTYPE_3GP_H263 = GF_4CC( 's', '2', '6', '3' ), @@ -210,6 +216,8 @@ enum GF_ISOM_SUBTYPE_3GP_DIMS = GF_4CC( 'd', 'i', 'm', 's' ), GF_ISOM_SUBTYPE_AC3 = GF_4CC( 'a', 'c', '-', '3' ), + + GF_ISOM_SUBTYPE_LSR1 = GF_4CC( 'l', 's', 'r', '1' ), }; @@ -354,6 +362,9 @@ GF_Err gf_isom_refresh_fragmented(GF_ISOFile *the_file, u64 *MissingBytes); the base IsoMedia structure without "moov" container*/ Bool gf_isom_has_movie(GF_ISOFile *file); +/* check if the file has a top styp box and returns the brand and version of the first styp found */ +Bool gf_isom_has_segment(GF_ISOFile *file, u32 *brand, u32 *version); + /******************************************************************** READING API FUNCTIONS ********************************************************************/ @@ -621,6 +632,9 @@ GF_Err gf_isom_get_audio_info(GF_ISOFile *the_file, u32 trackNumber, u32 StreamD /*returns track visual info - all coord values are expressed as 16.16 fixed point floats*/ GF_Err gf_isom_get_track_layout_info(GF_ISOFile *the_file, u32 trackNumber, u32 *width, u32 *height, s32 *translation_x, s32 *translation_y, s16 *layer); +/*returns track matrix info - all coord values are expressed as 16.16 fixed point floats*/ +GF_Err gf_isom_get_track_matrix(GF_ISOFile *the_file, u32 trackNumber, u32 matrix[9]); + /*returns width and height of the given visual sample desc - error if not a visual track*/ GF_Err gf_isom_get_pixel_aspect_ratio(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex, u32 *hSpacing, u32 *vSpacing); @@ -707,7 +721,7 @@ Bool gf_isom_is_single_av(GF_ISOFile *file); u32 gf_isom_guess_specification(GF_ISOFile *file); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /******************************************************************** @@ -729,6 +743,11 @@ GF_Err gf_isom_remove_track(GF_ISOFile *the_file, u32 trackNumber); /*sets the enable flag of a track*/ GF_Err gf_isom_set_track_enabled(GF_ISOFile *the_file, u32 trackNumber, u8 enableTrack); +/*sets creationTime and modificationTime of the movie to the specified date*/ +GF_Err gf_isom_set_creation_time(GF_ISOFile *movie, u64 time); +/*sets creationTime and modificationTime of the track to the specified date*/ +GF_Err gf_isom_set_track_creation_time(GF_ISOFile *movie,u32 trackNumber, u64 time); + /*changes the trackID - all track references present in the file are updated returns error if trackID is already in used in the file*/ GF_Err gf_isom_set_track_id(GF_ISOFile *the_file, u32 trackNumber, u32 trackID); @@ -809,6 +828,11 @@ GF_Err gf_isom_set_copyright(GF_ISOFile *the_file, const char *threeCharCode, ch /*deletes copyright (1-based indexes)*/ GF_Err gf_isom_remove_copyright(GF_ISOFile *the_file, u32 index); +/*changes the handler type of the media*/ +GF_Err gf_isom_set_media_type(GF_ISOFile *movie, u32 trackNumber, u32 new_type); + +/*changes the type of the sampleDescriptionBox - USE AT YOUR OWN RISK, the file may not be understood afterwards*/ +GF_Err gf_isom_set_media_subtype(GF_ISOFile *movie, u32 trackNumber, u32 sampleDescriptionIndex, u32 new_type); GF_Err gf_isom_set_alternate_group_id(GF_ISOFile *movie, u32 trackNumber, u32 groupId); @@ -910,6 +934,9 @@ GF_Err gf_isom_set_visual_info(GF_ISOFile *the_file, u32 trackNumber, u32 Stream all coord values are expressed as 16.16 fixed point floats*/ GF_Err gf_isom_set_track_layout_info(GF_ISOFile *the_file, u32 trackNumber, u32 width, u32 height, s32 translation_x, s32 translation_y, s16 layer); +/*sets track matrix - all coordinates are expressed as 16.16 floating points*/ +GF_Err gf_isom_set_track_matrix(GF_ISOFile *the_file, u32 trackNumber, u32 matrix[9]); + GF_Err gf_isom_set_pixel_aspect_ratio(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex, u32 hSpacing, u32 vSpacing); /*set SR & nbChans for audio description*/ @@ -1015,6 +1042,10 @@ GF_Err gf_isom_clone_pl_indications(GF_ISOFile *orig, GF_ISOFile *dest); /*clones root OD from input to output file, without copying root OD track references*/ GF_Err gf_isom_clone_root_od(GF_ISOFile *input, GF_ISOFile *output); +/*clones the entire movie file to destination. Tracks can be cloned if clone_tracks is set, in which case hint tracks can be +kept if keep_hint_tracks is set*/ +GF_Err gf_isom_clone_movie(GF_ISOFile *orig_file, GF_ISOFile *dest_file, Bool clone_tracks, Bool keep_hint_tracks); + /*returns true if same set of sample description in both tracks - this does include self-contained checking and reserved flags. The specific media cfg (DSI & co) is not analysed, only a brutal memory comparaison is done*/ @@ -1022,6 +1053,15 @@ Bool gf_isom_is_same_sample_description(GF_ISOFile *f1, u32 tk1, GF_ISOFile *f2, GF_Err gf_isom_set_JPEG2000(GF_ISOFile *mov, Bool set_on); +/*releases current movie segment - this closes the associated file IO object. +If reset_tables is set, sample information for all tracks setup as segment are destroyed. This allows keeping the memory +footprint low when playing segments. Note however that seeking in the file is then no longer possible*/ +GF_Err gf_isom_release_segment(GF_ISOFile *movie, Bool reset_tables); +/*opens a new segment file. Access to samples in previous segments is no longer possible*/ +GF_Err gf_isom_open_segment(GF_ISOFile *movie, const char *fileName); + +#ifndef GPAC_DISBALE_ISOM_FRAGMENTS + /* Movie Fragments Writing API Movie Fragments is a feature of ISO media files for fragmentation @@ -1072,11 +1112,23 @@ GF_Err gf_isom_setup_track_fragment(GF_ISOFile *the_file, u32 TrackID, u16 DefaultDegradationPriority); /*flushes data to disk and prepare movie fragmentation*/ -GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *the_file); +GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *the_file, Bool use_segments); -/*starts a new movie fragment*/ -GF_Err gf_isom_start_fragment(GF_ISOFile *the_file); +/*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); +/*starts a new segment in the file. If SegName is given, the output will be written in the SegName file*/ +GF_Err gf_isom_start_segment(GF_ISOFile *movie, char *SegName); + +typedef struct +{ + u32 track_ID; + u64 decoding_time; +} GF_SIDXTrackTimes; + +/*closes current segment*/ +GF_Err gf_isom_close_segment(GF_ISOFile *movie, u32 fragments_per_sidx, u32 referenceTrackID, GF_SIDXTrackTimes *tracks_times, u32 nb_times, Bool daisy_chain_sidx); enum { @@ -1123,6 +1175,7 @@ GF_Err gf_isom_fragment_add_sample(GF_ISOFile *the_file, u32 TrackID, GF_ISOSamp CANNOT be used with OD tracks*/ GF_Err gf_isom_fragment_append_data(GF_ISOFile *the_file, u32 TrackID, char *data, u32 data_size, u8 PaddingBits); +#endif /*GPAC_DISBALE_ISOM_FRAGMENTS*/ /****************************************************************** @@ -1186,6 +1239,8 @@ enum GF_ISOM_HINT_RTP = GF_4CC('r', 't', 'p', ' '), }; +#ifndef GPAC_DISABLE_ISOM_HINTING + /*Setup the resources based on the hint format This function MUST be called after creating a new hint track and before @@ -1315,23 +1370,37 @@ GF_Err gf_isom_sdp_add_line(GF_ISOFile *the_file, const char *text); /*remove all SDP info at the movie level*/ GF_Err gf_isom_sdp_clean(GF_ISOFile *the_file); -#endif /*GPAC_READ_ONLY*/ +#endif /*GPAC_DISABLE_ISOM_HINTING*/ -/*Get SDP info at the movie level*/ -GF_Err gf_isom_sdp_get(GF_ISOFile *the_file, const char **sdp, u32 *length); -/*Get SDP info at the track level*/ -GF_Err gf_isom_sdp_track_get(GF_ISOFile *the_file, u32 trackNumber, const char **sdp, u32 *length); -u32 gf_isom_get_payt_count(GF_ISOFile *the_file, u32 trackNumber); -const char *gf_isom_get_payt_info(GF_ISOFile *the_file, u32 trackNumber, u32 index, u32 *payID); +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#ifndef GPAC_DISABLE_ISOM_DUMP /*dumps file structures into XML trace file */ GF_Err gf_isom_dump(GF_ISOFile *file, FILE *trace); + +#endif /*GPAC_DISABLE_ISOM_DUMP*/ + + +#ifndef GPAC_DISABLE_ISOM_HINTING + +#ifndef GPAC_DISABLE_ISOM_DUMP /*dumps RTP hint samples structure into XML trace file @trackNumber, @SampleNum: hint track and hint sample number @trace: output */ GF_Err gf_isom_dump_hint_sample(GF_ISOFile *the_file, u32 trackNumber, u32 SampleNum, FILE * trace); +#endif + +/*Get SDP info at the movie level*/ +GF_Err gf_isom_sdp_get(GF_ISOFile *the_file, const char **sdp, u32 *length); +/*Get SDP info at the track level*/ +GF_Err gf_isom_sdp_track_get(GF_ISOFile *the_file, u32 trackNumber, const char **sdp, u32 *length); + +u32 gf_isom_get_payt_count(GF_ISOFile *the_file, u32 trackNumber); +const char *gf_isom_get_payt_info(GF_ISOFile *the_file, u32 trackNumber, u32 index, u32 *payID); + @@ -1362,6 +1431,9 @@ as the hint sample timestamp + ts_offset, some packets may need to be sent earli */ GF_Err gf_isom_next_hint_packet(GF_ISOFile *the_file, u32 trackNumber, char **pck_data, u32 *pck_size, Bool *disposable, Bool *repeated, u32 *trans_ts, u32 *sample_num); +#endif /*GPAC_DISABLE_ISOM_HINTING*/ + + /* 3GPP specific extensions @@ -1393,24 +1465,28 @@ typedef struct /*return the 3GP config for this tream description, NULL if not a 3GPP track*/ GF_3GPConfig *gf_isom_3gp_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*create the track config*/ GF_Err gf_isom_3gp_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_3GPConfig *config, char *URLname, char *URNname, u32 *outDescriptionIndex); /*update the track config - subtypes shall NOT differ*/ GF_Err gf_isom_3gp_config_update(GF_ISOFile *the_file, u32 trackNumber, GF_3GPConfig *config, u32 DescriptionIndex); -#endif /*GPAC_READ_ONLY*/ +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /*AVC/H264 extensions - GF_AVCConfig is defined in mpeg4_odf.h*/ /*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*/ +GF_AVCConfig *gf_isom_svc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex); -#ifndef GPAC_READ_ONLY +#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); /*updates AVC config*/ GF_Err gf_isom_avc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg); -#endif +/*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); +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /* @@ -1424,10 +1500,13 @@ GF_Err gf_isom_avc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 Desc and ESD will be emulated for text tracks.*/ GF_Err gf_isom_text_set_streaming_mode(GF_ISOFile *the_file, Bool do_convert); + +#ifndef GPAC_DISABLE_ISOM_DUMP /*exports text track to given format @dump_type: 0 for TTXT, 1 for srt, 2 for SVG */ GF_Err gf_isom_text_dump(GF_ISOFile *the_file, u32 track, FILE *dump, u32 dump_type); +#endif /*returns encoded TX3G box (text sample description for 3GPP text streams) as needed by RTP or other standards: @sidx: 1-based stream description index @@ -1452,7 +1531,7 @@ GF_TextSample *gf_isom_new_text_sample(); /*destroy text sample handle*/ void gf_isom_delete_text_sample(GF_TextSample *tx_samp); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*Create a new TextSampleDescription in the file. The URL and URN are used to describe external media, this will create a data reference for the media @@ -1518,7 +1597,7 @@ 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); -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /***************************************************** ISMACryp Samples @@ -1589,7 +1668,7 @@ GF_Err gf_isom_get_omadrm_info(GF_ISOFile *the_file, u32 trackNumber, u32 sample 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); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*removes ISMACryp protection info (does not perform decryption :)*/ GF_Err gf_isom_remove_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex); @@ -1609,11 +1688,13 @@ GF_Err gf_isom_set_oma_protection(GF_ISOFile *the_file, u32 trackNumber, u32 des 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); -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ +#ifndef GPAC_DISABLE_ISOM_DUMP /*xml dumpers*/ GF_Err gf_isom_dump_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, FILE * trace); GF_Err gf_isom_dump_ismacryp_sample(GF_ISOFile *the_file, u32 trackNumber, u32 SampleNum, FILE *trace); +#endif /******************************************************************** @@ -1676,7 +1757,7 @@ GF_Err gf_isom_extract_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num /*retirves primary item ID, 0 if none found (primary can also be stored through meta XML)*/ u32 gf_isom_get_meta_primary_item_id(GF_ISOFile *file, Bool root_meta, u32 track_num); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*sets meta type (four char int, eg "mp21", ... Creates a meta box if none found @@ -1706,7 +1787,7 @@ GF_Err gf_isom_remove_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, /*sets the given item as the primary one. You SHALL NOT use this if the meta has a valid XML data*/ GF_Err gf_isom_set_meta_primary_item(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 item_num); -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /******************************************************************** @@ -1715,10 +1796,10 @@ GF_Err gf_isom_set_meta_primary_item(GF_ISOFile *file, Bool root_meta, u32 track GF_Err gf_isom_get_timed_meta_data_info(GF_ISOFile *file, u32 track, u32 sampleDescription, Bool *is_xml, const char **mime_or_namespace, const char **content_encoding, const char **schema_loc); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*create a new timed metat data sample description for this track*/ GF_Err gf_isom_timed_meta_data_config_new(GF_ISOFile *movie, u32 trackNumber, Bool is_xml, char *mime_or_namespace, char *content_encoding, char *schema_loc, char *URLname, char *URNname, u32 *outDescriptionIndex); -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /******************************************************************** @@ -1755,7 +1836,7 @@ and the data_len to the genre ID returns GF_URL_ERROR if no tag is present in the file */ GF_Err gf_isom_apple_get_tag(GF_ISOFile *mov, u32 tag, const char **data, u32 *data_len); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*set the given tag info. If data and data_len are 0, removes the given tag For 'genre', data may be NULL in which case the genre ID taken from the data_len parameter */ @@ -1763,7 +1844,7 @@ GF_Err gf_isom_apple_set_tag(GF_ISOFile *mov, u32 tag, const char *data, u32 dat /*sets compatibility tag on AVC tracks (needed by iPod to play files... hurray for standards)*/ GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber); -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /*3GPP Alternate Group API - (c) 2007 ENST & ResonateMP4*/ @@ -1783,7 +1864,7 @@ criteriaListSize: number of criteria items in returned list */ const u32 *gf_isom_get_track_switch_parameter(GF_ISOFile *movie, u32 trackNumber, u32 group_index, u32 *switchGroupID, u32 *criteriaListSize); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*sets a new (switch) group for this track trackNumber: track trackRefGroup: number of a track belonging to the same alternate group. If 0, a new alternate group will be created for this track @@ -1801,7 +1882,7 @@ GF_Err gf_isom_reset_track_switch_parameter(GF_ISOFile *movie, u32 trackNumber, /*resets ALL track switch group information in the entire movie*/ GF_Err gf_isom_reset_switch_parameters(GF_ISOFile *movie); -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ typedef struct @@ -1818,10 +1899,10 @@ typedef struct } GF_DIMSDescription; GF_Err gf_isom_get_dims_description(GF_ISOFile *movie, u32 trackNumber, u32 descriptionIndex, GF_DIMSDescription *desc); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_new_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DIMSDescription *desc, char *URLname, char *URNname, u32 *outDescriptionIndex); GF_Err gf_isom_update_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DIMSDescription *desc, char *URLname, char *URNname, u32 DescriptionIndex); -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -1837,10 +1918,14 @@ typedef struct u8 brcode; } GF_AC3Config; -#ifndef GPAC_READ_ONLY +GF_AC3Config *gf_isom_ac3_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex); + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_ac3_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AC3Config *cfg, char *URLname, char *URNname, u32 *outDescriptionIndex); -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#endif /*GPAC_DISABLE_ISOM*/ #ifdef __cplusplus } diff --git a/include/gpac/laser.h b/include/gpac/laser.h index 800da28..f52f157 100644 --- a/include/gpac/laser.h +++ b/include/gpac/laser.h @@ -32,11 +32,11 @@ extern "C" { #include <gpac/nodes_svg.h> +#ifndef GPAC_DISABLE_LASER + /*for LASeRConfig*/ #include <gpac/mpeg4_odf.h> -#ifndef GPAC_DISABLE_SVG - typedef struct __tag_laser_codec GF_LASeRCodec; @@ -78,7 +78,7 @@ GF_Err gf_laser_encoder_get_config(GF_LASeRCodec *codec, u16 ESID, char **out_da GF_Err gf_laser_encoder_get_rap(GF_LASeRCodec *codec, char **out_data, u32 *out_data_length); -#endif +#endif /*GPAC_DISABLE_LASER*/ #ifdef __cplusplus } diff --git a/include/gpac/math.h b/include/gpac/math.h index 36dad51..6316945 100644 --- a/include/gpac/math.h +++ b/include/gpac/math.h @@ -41,23 +41,6 @@ extern "C" { #include <math.h> #endif -/*! - \cond DUMMY_DOXY_SECTION -*/ - -#ifndef GPAC_FIXED_POINT -/*note: - to turn fp on, change to GPAC_FIXED_POINT - to turn fp off, change to GPAC_NO_FIXED_POINT - this is needed by configure+sed to modify this file directly -*/ -#define GPAC_NO_FIXED_POINT -#endif - -/*! - \endcond -*/ - /*! *\addtogroup math_grp math diff --git a/include/gpac/media_tools.h b/include/gpac/media_tools.h index eb4cc6e..c65f9a4 100644 --- a/include/gpac/media_tools.h +++ b/include/gpac/media_tools.h @@ -33,6 +33,16 @@ extern "C" { #include <gpac/isomedia.h> #include <gpac/avparse.h> + +#ifndef GPAC_DISABLE_ISOM +/*creates (if needed) a GF_ESD for the given track - THIS IS RESERVED for local playback +only, since the OTI used when emulated is not standard...*/ +GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track); +#endif + + +#ifndef GPAC_DISABLE_MEDIA_IMPORT + /* track importers @@ -65,7 +75,22 @@ enum GF_IMPORT_KEEP_ALL_TRACKS = 1<<7, /*uses compact size in .MOV/.IsoMedia files*/ GF_IMPORT_USE_COMPACT_SIZE = 1<<8, + /*don't add a final empty sample when importing text tracks from srt*/ + GF_IMPORT_NO_TEXT_FLUSH = 1<<9, + /*for SVC video: forces explicit SVC signaling */ + GF_IMPORT_SVC_EXPLICIT = 1<<10, + /*for SVC video: removes all SVC extensions*/ + GF_IMPORT_SVC_NONE = 1<<11, + + /*for AAC audio: forces PS mode with implicit signaling (backward compatible)*/ + GF_IMPORT_PS_IMPLICIT = 1<<12, + /*for AAC audio: forces PS mode with explicit signaling (non-backward compatible). + Will override GF_IMPORT_PS_IMPLICIT flag when set*/ + GF_IMPORT_PS_EXPLICIT = 1<<13, + /* oversampled SBR */ + GF_IMPORT_OVSBR = 1<<14, + /*when set, only updates tracks info and return*/ GF_IMPORT_PROBE_ONLY = 1<<20, /*only set when probing, signals several frames per sample possible*/ @@ -74,6 +99,8 @@ enum GF_IMPORT_OVERRIDE_FPS = 1<<22, /*only set when probing, signals duration not usable*/ GF_IMPORT_NO_DURATION = 1<<23, + /*when set IP packets found in MPE sections will be sent to the local network */ + GF_IMPORT_MPE_DEMUX = 1<<24, /*when set by user during import, will abort*/ GF_IMPORT_DO_ABORT = 1<<31 }; @@ -103,6 +130,8 @@ struct __track_import_info struct __track_audio_info audio_info; u32 lang; + /*for MPEG4 on MPEG-2 TS: mpeg4 ES-ID*/ + u32 mpeg4_es_id; /*for MPEG2 TS: program number*/ u16 prog_num; }; @@ -146,6 +175,8 @@ typedef struct __track_import u32 frames_per_sample; /*track ID of imported media in destination file*/ u32 final_trackID; + /*optional format indication for media source (used in IM1)*/ + char *force_ext; /*for MP4 import only*/ GF_ISOFile *orig; @@ -153,6 +184,10 @@ typedef struct __track_import /*for text import*/ u32 fontSize; char *fontName; + u32 twidth, theight; + + /*Initial offset of the first AU to import*/ + Double initial_time_offset; /*number of tracks after probing - may be set to 0, in which case no track selection can be performed. It may also be inaccurate if probing doesn't @@ -170,6 +205,41 @@ typedef struct __track_import GF_Err gf_media_import(GF_MediaImporter *importer); + +/*adds chapter info contained in file - import_fps is optional (most formats don't use it), defaults to 25*/ +GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import_fps); + + +/*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, char *output_file, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, u32 fragments_per_sidx, Bool daisy_chain_sidx); + +/*make the file ISMA compliant: creates ISMA BIFS / OD tracks if needed, and update audio/video IDs +the file should not contain more than one audio and one video track +@keepImage: if set, generates system info if image is found - only used for image imports +*/ +GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, Bool no_ocr); + +/*make the file 3GP compliant && sets profile +*/ +GF_Err gf_media_make_3gpp(GF_ISOFile *mp4file); + +/*make the file playable on a PSP +*/ +GF_Err gf_media_make_psp(GF_ISOFile *mp4file); + +/*changes pixel aspect ratio for visual tracks if supported. Negative values remove any PAR info*/ +GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den); + +/*changes the profile (if not 0) and level (if not 0) indication of the media - only AVC/H264 supported for now*/ +GF_Err gf_media_change_pl(GF_ISOFile *file, u32 track, u32 profile, u32 level); + +#endif /*GPAC_DISABLE_MEDIA_IMPORT*/ + + + +#ifndef GPAC_DISABLE_MEDIA_EXPORT + enum { /*track dumper types are formatted as flags for conveniency for @@ -225,8 +295,10 @@ typedef struct __track_exporter /*if error returns same value as error signaled in message*/ GF_Err gf_media_export(GF_MediaExporter *dump); +#endif /*GPAC_DISABLE_MEDIA_EXPORT*/ +#ifndef GPAC_DISABLE_ISOM_HINTING /* RTP IsoMedia file hinting */ @@ -278,33 +350,8 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, u32 IOD_Profile, u32 bandwidth); signal data mime-type (OD, BIFS or any) */ Bool gf_hinter_can_embbed_data(char *data, u32 data_size, u32 streamType); -/*save file as fragmented movie*/ -GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double MaxFragmentDuration); - -/*adds chapter info contained in file - import_fps is optional (most formats don't use it), defaults to 25*/ -GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import_fps); - -/*make the file ISMA compliant: creates ISMA BIFS / OD tracks if needed, and update audio/video IDs -the file should not contain more than one audio and one video track -@keepImage: if set, generates system info if image is found - only used for image imports -*/ -GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, Bool no_ocr); - -/*make the file 3GP compliant && sets profile -*/ -GF_Err gf_media_make_3gpp(GF_ISOFile *mp4file); - -/*make the file playable on a PSP -*/ -GF_Err gf_media_make_psp(GF_ISOFile *mp4file); - -/*creates (if needed) a GF_ESD for the given track - THIS IS RESERVED for local playback -only, since the OTI used when emulated is not standard...*/ -GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track); - -/*changes pixel aspect ratio for visual tracks if supported. Negative values remove any PAR info*/ -GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den); +#endif /*GPAC_DISABLE_ISOM_HINTING*/ /*SAF Multiplexer object. The multiplexer supports concurencial (multi-threaded) access*/ diff --git a/include/gpac/mediaobject.h b/include/gpac/mediaobject.h index 4d1e25e..4ee91e5 100644 --- a/include/gpac/mediaobject.h +++ b/include/gpac/mediaobject.h @@ -51,7 +51,7 @@ typedef struct _mediaobj GF_MediaObject; /*locate media object related to the given node - url designes the object to find - returns NULL if URL cannot be handled - note that until the mediaObject.isInit member is true, the media object is not valid (and could actually never be) */ -GF_MediaObject *gf_mo_register(GF_Node *node, MFURL *url, Bool lock_timelines); +GF_MediaObject *gf_mo_register(GF_Node *node, MFURL *url, Bool lock_timelines, Bool force_new_res); /*unregister the node from the media object*/ void gf_mo_unregister(GF_Node *node, GF_MediaObject *mo); @@ -117,6 +117,8 @@ Bool gf_mo_get_visual_info(GF_MediaObject *mo, u32 *width, u32 *height, u32 *str Bool gf_mo_get_audio_info(GF_MediaObject *mo, u32 *sample_rate, u32 *bits_per_sample, u32 *num_channels, u32 *channel_config); +Fixed gf_mo_get_current_speed(GF_MediaObject *mo); + /*checks if the service associated withthis object has an audio stream*/ Bool gf_mo_has_audio(GF_MediaObject *mo); diff --git a/include/gpac/module.h b/include/gpac/module.h index 594b02f..6418403 100644 --- a/include/gpac/module.h +++ b/include/gpac/module.h @@ -43,9 +43,9 @@ extern "C" { *A module is a dynamic/shared library providing one or several interfaces to the GPAC framework. *A module cannot provide several interfaces of the same type. Each module must export the following functions: \code - * Bool QueryInterface(u32 interface_type); + * u32 *QueryInterfaces(u32 interface_type); \endcode - * This function is used to query supported interfaces. It returns non zero if the module handles this interface type, 0 otherwise.\n + * This function is used to query supported interfaces. It returns a zero-terminated array of supported interface types.\n \code GF_BaseInterface *LoadInterface(u32 interface_type); \endcode @@ -163,6 +163,15 @@ u32 gf_modules_get_count(GF_ModuleManager *pm); */ const char *gf_modules_get_file_name(GF_ModuleManager *pm, u32 index); +/*! + *\brief get module file name + * + *Gets a module shared library file name based on its index + *\param ifce the module instance to query + *\return the name of the shared library module + */ +const char *gf_module_get_file_name(GF_BaseInterface *ifce); + /*! *\brief loads an interface * diff --git a/include/gpac/modules/audio_out.h b/include/gpac/modules/audio_out.h index c1ea6ee..94bbf8d 100644 --- a/include/gpac/modules/audio_out.h +++ b/include/gpac/modules/audio_out.h @@ -47,7 +47,7 @@ extern "C" { */ /*interface name and version for audio output*/ -#define GF_AUDIO_OUTPUT_INTERFACE GF_4CC('G','A','O', 0x03) +#define GF_AUDIO_OUTPUT_INTERFACE GF_4CC('G','A','O', '1') /*interface returned on query interface*/ typedef struct _audiooutput @@ -123,6 +123,62 @@ typedef struct _audiooutput } GF_AudioOutput; +/* + Audio hardware output module +*/ + +/*interface name and version for audio output*/ +#define GF_AUDIO_FILTER_INTERFACE GF_4CC('G','A','F', '1') + +/*interface returned on query interface*/ +typedef struct _tag_audio_filter GF_AudioFilter; + +struct _tag_audio_filter +{ + /* interface declaration*/ + GF_DECL_MODULE_INTERFACE + + /*sets the current filter. The filterstring is opaque to libgpac and is taken as given + in the GPAC configuration file, where filters are listed as a ';;' seperated list in the "Filter" key of + the [Audio] section. + @returns: 1 is this module can handle the filterstring, 0 otherwise. + */ + Bool (*SetFilter)(GF_AudioFilter *af, char *filterstring); + /*configures the filter: + @samplerate: samplerate of data - this cannot be modified by a filter + @bits_per_sample: sample format (8 or 16 bit signed PCM data) of data - this cannot be modified by a filter + @input_channel_number: number of input channels + @input_channel_layout: channel layout of input data - cf <gpac/constants.h> + @output_channel_number: number of ouput channels + @output_channel_layout: channel layout of output data - cf <gpac/constants.h> + &output_block_size_in_samples: size in blocks of the data to be sent to this filter. + If 0, data will not be reframed and blocks of any number of samples will be processed + @delay_ms: delay in ms introduced by this filter + @inplace_processing_capable: if set to 1, this filter is capable of processing data inplace, in which case + the same buffer is passed for in_data and out_data in the process call + */ + GF_Err (*Configure)(GF_AudioFilter *af, u32 samplerate, u32 bits_per_sample, u32 input_channel_number, u32 input_channel_layout, u32 *output_channel_number, u32 *output_channel_layout, u32 *output_block_size_in_samples, u32 *delay_ms, Bool *inplace_processing_capable); + /*process a chunk of audio data. + @in_data: input sample buffer + @in_data_size: input sample buffer size. If block len was set in the configure stage, there will be block len sample + @out_data: output sample buffer - if inplace was set in the configure stage, same as in_data. + NOTE: Outputing more samples that input ones may crash the system, the buffer only contains space for + the same amount of samples (including channels added/removed by the filter) + @out_data_size: data size written to output. Usually 0 or in_data_size. + */ + GF_Err (*Process)(GF_AudioFilter *af, void *in_data, u32 in_data_size, void *out_data, u32 *out_data_size); + + /*gets an option from the filter - currently not implemented */ + const char *(*GetOption)(GF_AudioFilter *af, char *option); + /*sets an option to the filter - currently not implemented */ + Bool (*SetOption)(GF_AudioFilter *af, char *option, char *value); + + /*Indicates the filter should be reset (audio stop or seek )*/ + void (*Reset)(GF_AudioFilter *af); + + /*private user data for the module*/ + void *udta; +}; #ifdef __cplusplus } diff --git a/include/gpac/modules/codec.h b/include/gpac/modules/codec.h index 26c3181..7759924 100644 --- a/include/gpac/modules/codec.h +++ b/include/gpac/modules/codec.h @@ -116,8 +116,14 @@ enum GF_CODEC_SHOW_SCENE, /*This is only called on scene decoders, GetCap only. If the decoder may continue modifying the scene once the last AU is received, it must set cap.valueINT to 1 (typically, text stream decoder will hold the scene for a given duration - after the last AU). Otherwise the decoder will be stoped and ask to remove any extra scene being displayed*/ + after the last AU). Otherwise the decoder will be stopped and ask to remove any extra scene being displayed*/ GF_CODEC_MEDIA_NOT_OVER, + + /*switches up or down media quality for scalable coding*/ + GF_CODEC_MEDIA_SWITCH_QUALITY, + + /*special cap indicating the codec should abort processing as soon as possible because it is about to be destroyed*/ + GF_CODEC_ABORT }; @@ -162,7 +168,7 @@ typedef struct _basedecoder } GF_BaseDecoder; /*interface name and version for media decoder */ -#define GF_MEDIA_DECODER_INTERFACE GF_4CC('G', 'M', 'D', 0x02) +#define GF_MEDIA_DECODER_INTERFACE GF_4CC('G', 'M', 'D', '1') /*the media module interface. A media module MUST be implemented in synchronous mode as time and resources management is done by the terminal*/ @@ -187,10 +193,10 @@ typedef struct _mediadecoder -typedef struct _inline_scene *LPINLINESCENE; +typedef struct _scene *LPSCENE; /*interface name and version for scene decoder */ -#define GF_SCENE_DECODER_INTERFACE GF_4CC('G', 'S', 'D', 0x02) +#define GF_SCENE_DECODER_INTERFACE GF_4CC('G', 'S', 'D', '1') typedef struct _scenedecoder { @@ -204,7 +210,7 @@ typedef struct _scenedecoder or a re-entrant call, cf below) This is called once upon creation of the decoder (several times if re-entrant) */ - GF_Err (*AttachScene)(struct _scenedecoder *, LPINLINESCENE is, Bool is_scene_root); + GF_Err (*AttachScene)(struct _scenedecoder *, LPSCENE scene, Bool is_scene_root); /*releases scene. If the decoder manages nodes / resources in the scene, THESE MUST BE DESTROYED. May be NULL if decoder doesn't manage nodes but only create them (like BIFS, OD) and doesn't have to be instructed the scene is about to be resumed @@ -223,6 +229,27 @@ typedef struct _scenedecoder } GF_SceneDecoder; + + +/*interface name and version for scene decoder */ +#define GF_INPUT_DEVICE_INTERFACE GF_4CC('G', 'I', 'D', '1') + +typedef struct __input_device +{ + /* interface declaration*/ + GF_DECL_MODULE_INTERFACE + + Bool (*RegisterDevice)(struct __input_device *, const char *urn, GF_BitStream *dsi, void (*AddField)(struct __input_device *_this, u32 fieldType, const char *name)); + void (*Start)(struct __input_device *); + void (*Stop)(struct __input_device *); + + void *udta; + + /*this is set upon loading and shall not be modified*/ + GF_BaseDecoder *input_decoder; + void (*DispatchFrame)(struct __input_device *, u8 *data, u32 data_len); +} GF_InputSensorDevice; + #ifdef __cplusplus } #endif diff --git a/include/gpac/modules/font.h b/include/gpac/modules/font.h index e466f11..1b8e40d 100644 --- a/include/gpac/modules/font.h +++ b/include/gpac/modules/font.h @@ -86,7 +86,7 @@ enum #define GF_FONT_WEIGHT_MASK 0xFFFFFC00 /*interface name and version for font engine*/ -#define GF_FONT_READER_INTERFACE GF_4CC('G','F','T', 0x01) +#define GF_FONT_READER_INTERFACE GF_4CC('G','F','T', '1') typedef struct _font_reader diff --git a/include/gpac/modules/ipmp.h b/include/gpac/modules/ipmp.h index 0e0930d..0b561db 100644 --- a/include/gpac/modules/ipmp.h +++ b/include/gpac/modules/ipmp.h @@ -104,7 +104,7 @@ typedef struct } GF_IPMPEvent; /*interface name and version for IPMP tools*/ -#define GF_IPMP_TOOL_INTERFACE GF_4CC('G','I','P', 0x01) +#define GF_IPMP_TOOL_INTERFACE GF_4CC('G','I','P', '1') typedef struct _ipmp_tool GF_IPMPTool; diff --git a/include/gpac/modules/js_usr.h b/include/gpac/modules/js_usr.h index 36390c9..4d92f4b 100644 --- a/include/gpac/modules/js_usr.h +++ b/include/gpac/modules/js_usr.h @@ -34,10 +34,13 @@ extern "C" { #include <gpac/scenegraph.h> /*interface name and version for JavaScript User Extensions*/ -#define GF_JS_USER_EXT_INTERFACE GF_4CC('G','J','S', 0x01) +#define GF_JS_USER_EXT_INTERFACE GF_4CC('G','J','S', '1') typedef struct _js_usr_ext GF_JSUserExtension; +typedef struct JSContext GF_JSContext; +typedef struct JSObject GF_JSObject; + struct _js_usr_ext { /* interface declaration*/ @@ -51,7 +54,7 @@ struct _js_usr_ext global: JavaScript global object for the context unload: if true, the extension should be unloaded from the JavaScript context (called upon destroy). Otherwise it should be loaded */ - void (*load)(GF_JSUserExtension *jsext, GF_SceneGraph *doc, struct JSContext *jsctx, struct JSObject *global, Bool unload); + void (*load)(GF_JSUserExtension *jsext, GF_SceneGraph *doc, GF_JSContext *jsctx, GF_JSObject *global, Bool unload); /*module private*/ void *udta; }; diff --git a/include/gpac/modules/raster2d.h b/include/gpac/modules/raster2d.h index 088d063..9fd1702 100644 --- a/include/gpac/modules/raster2d.h +++ b/include/gpac/modules/raster2d.h @@ -89,11 +89,11 @@ typedef enum /* rasterizer antialiasing depending on the graphics engine*/ typedef enum { - /*raster should use fastest mode possible (eg, no antialiasing)*/ + /*raster shall use no antialiasing */ GF_RASTER_HIGH_SPEED, /*raster should use fast mode and good quality if possible*/ GF_RASTER_MID, - /*raster should use antialiasing*/ + /*raster should use full antialiasing*/ GF_RASTER_HIGH_QUALITY } GF_RasterLevel; @@ -106,13 +106,20 @@ typedef enum alpha is computed by the lib @alpha: blending amount (0->0xFF) for the pixels */ + +typedef void (*raster_cbk_fill_run_alpha) (void *, u32, u32, u32, GF_Color, u8); +typedef void (*raster_cbk_fill_run_no_alpha) (void *, u32, u32, u32, GF_Color); +typedef void (*raster_cbk_fill_rect)(void *cbk, u32 x, u32 y, u32 width, u32 height, GF_Color color); + typedef struct { void *cbk; /*fills line pixels without any blending operation*/ - void (*fill_run_no_alpha)(void *cbk, u32 x, u32 y, u32 run_h_len, GF_Color color); - /*fills line pixels without blending operation - alpha combines both fill color and anti-aliasing blending*/ - void (*fill_run_alpha)(void *cbk, u32 x, u32 y, u32 run_h_len, GF_Color color, u32 alpha); + raster_cbk_fill_run_no_alpha fill_run_no_alpha; + /* fills line pixels with blending operation - alpha combines both fill color and anti-aliasing blending */ + raster_cbk_fill_run_alpha fill_run_alpha; + /*fills rectangle*/ + raster_cbk_fill_rect fill_rect; } GF_RasterCallback; @@ -124,7 +131,7 @@ typedef void *GF_STENCIL; typedef void *GF_SURFACE; /*interface name and version for raster2D*/ -#define GF_RASTER_2D_INTERFACE GF_4CC('G','R','2', 0x02) +#define GF_RASTER_2D_INTERFACE GF_4CC('G','R','2', '2') /*graphics driver*/ typedef struct _raster2d_interface @@ -209,10 +216,11 @@ typedef struct _raster2d_interface /* attach surface object to memory buffer if supported @pixels: texture data @width, @height: texture size - @stride: texture horizontal pitch (bytes to skip to get to next row) + @pitch_x: texture horizontal pitch (bytes to skip to get to next pixel). O means linear frame buffer (eg pitch_x==bytes per pixel) + @pitch_y: texture vertical pitch (bytes to skip to get to next line) @pixelFormat: texture pixel format */ - GF_Err (*surface_attach_to_buffer) (GF_SURFACE _this, char *pixels, u32 width, u32 height, u32 stride, GF_PixelFormat pixelFormat); + GF_Err (*surface_attach_to_buffer) (GF_SURFACE _this, char *pixels, u32 width, u32 height, s32 pitch_x, s32 pitch_y, GF_PixelFormat pixelFormat); GF_Err (*surface_attach_to_callbacks) (GF_SURFACE _this, GF_RasterCallback *callbacks, u32 width, u32 height); diff --git a/include/gpac/modules/service.h b/include/gpac/modules/service.h index 6c9c346..6f63cce 100644 --- a/include/gpac/modules/service.h +++ b/include/gpac/modules/service.h @@ -91,6 +91,11 @@ enum GF_NET_SERVICE_INFO, /*checks if there is an audio stream in the service - term->net only*/ GF_NET_SERVICE_HAS_AUDIO, + /*instructs the service to get the migration info - term->net only*/ + GF_NET_SERVICE_MIGRATION_INFO, + + /*When using DASH or playlists, query the next file to concatenate to thecurrent one net->proxy only*/ + GF_NET_SERVICE_QUERY_NEXT, }; /*channel command for all commands that don't need params: @@ -135,6 +140,8 @@ typedef struct u32 sync_id; /*audio frame duration and sample rate if any - this is needed by some RTP payload*/ u32 frame_duration, sample_rate; + /*do we use MPEG-2 section for SL packets ? this field is not coded*/ + Bool use_m2ts_sections; } GF_NetComConfig; /*GF_NET_CHAN_BUFFER, GF_NET_CHAN_BUFFER_QUERY*/ @@ -279,6 +286,24 @@ typedef struct char *base_url; } GF_NetComHasAudio; +/*GF_NET_SERVICE_MIGRATION_INFO*/ +typedef struct +{ + u32 command_type; + + /*out: migration data, allocated and freed by the plugin*/ + char *data; + u32 data_len; +} GF_NetComMigration; + +/*GF_NET_SERVICE_QUERY_NEXT*/ +typedef struct +{ + u32 command_type; + /*out: next url to play after current one*/ + const char *next_url; +} GF_NetURLQuery; + typedef union __netcommand { u32 command_type; @@ -296,6 +321,8 @@ typedef union __netcommand GF_NetComInfo info; GF_NetComPixelAR par; GF_NetComHasAudio audio; + GF_NetComMigration migrate; + GF_NetURLQuery url_query; } GF_NetworkCommand; /* @@ -303,7 +330,7 @@ typedef union __netcommand */ /*interface name and version for input service*/ -#define GF_NET_CLIENT_INTERFACE GF_4CC('G', 'I', 'S', 0x01) +#define GF_NET_CLIENT_INTERFACE GF_4CC('G', 'I', 'S', '1') typedef struct _netinterface { @@ -380,6 +407,10 @@ typedef struct _netinterface /*private*/ void *priv; + +/*proxy stuff*/ + GF_Err (*query_proxy)(struct _netinterface *, GF_NetworkCommand *param); + void *proxy_udta; } GF_InputService; /*callback functions - these can be linked with non-LGPL modules*/ diff --git a/include/gpac/modules/term_ext.h b/include/gpac/modules/term_ext.h index b77f7d3..ae18349 100644 --- a/include/gpac/modules/term_ext.h +++ b/include/gpac/modules/term_ext.h @@ -33,26 +33,60 @@ extern "C" { #include <gpac/terminal.h> /*interface name and version for Terminal Extensions services*/ -#define GF_TERM_EXT_INTERFACE GF_4CC('G','T','E', 0x01) +#define GF_TERM_EXT_INTERFACE GF_4CC('G','T','E', '1') typedef struct _term_ext GF_TermExt; +typedef struct { + void *scenegraph; + void *ctx; + void *global; + Bool unload; +} GF_TermExtJS; + enum { - /*start terminal extension. If 0 is returned, the module will be unloaded*/ + /*start terminal extension. If 0 is returned, the module will be unloaded + associated param: GF_Terminal *term + @return: 1 if OK, 0 otherwise (in which case the extensions will be removed without calling stop) + */ GF_TERM_EXT_START = 1, - /*stop terminal extension*/ + /*stop terminal extension + associated param: NULL + @return: ignored + */ GF_TERM_EXT_STOP, - /*process extension - the GF_TERM_EXT_CAP_NOT_THREADED capability MUST be set*/ + + /*process extension - only called GF_TERM_EXTENSION_NOT_THREADED capability is set + associated param: NULL + @return: ignored + */ GF_TERM_EXT_PROCESS, + + /*filter event - only called if the GF_TERM_EXTENSION_FILTER_EVENT capability is set + associated param: GF_Event *evt + @return: 1 if the event must be discarded, 0 otherwise + */ + GF_TERM_EXT_EVENT, + + /*load/unload js bindings of this extension + associated param: GF_TermExtJS *jsext + @return: ignored + */ + GF_TERM_EXT_JSBIND, }; enum { /*signal the extension is to be called on regular basis (once per simulation tick). This MUST be set during the GF_TERM_EXT_START command and cannot be changed at run-time*/ - GF_TERM_EXT_CAP_NOT_THREADED = 1<<1, + GF_TERM_EXTENSION_NOT_THREADED = 1<<1, + + /*extension wants to filter events*/ + GF_TERM_EXTENSION_FILTER_EVENT = 1<<2, + + GF_TERM_EXTENSION_JS = 1<<3, }; @@ -64,17 +98,19 @@ struct _term_ext /*caps of the module*/ u32 caps; - /*load JS extension + /*terminal extension proc termext: pointer to the module - term: pointer to GPAC terminal + action: action type of this call + param: associated param of the call */ - Bool (*process)(GF_TermExt *termext, GF_Terminal *term, u32 action); + Bool (*process)(GF_TermExt *termext, u32 action, void *param); /*module private*/ void *udta; }; + #ifdef __cplusplus } #endif diff --git a/include/gpac/modules/video_out.h b/include/gpac/modules/video_out.h index 4f97110..bbf65cc 100644 --- a/include/gpac/modules/video_out.h +++ b/include/gpac/modules/video_out.h @@ -51,27 +51,42 @@ extern "C" { enum { + /*HW supports RGB->backbuffer blitting*/ + GF_VIDEO_HW_HAS_RGB = (1<<1), + /*HW supports RGBA->backbuffer blitting*/ + GF_VIDEO_HW_HAS_RGBA = (1<<2), /*HW supports YUV->backbuffer blitting*/ - GF_VIDEO_HW_HAS_YUV = (1<<1), - /*HW supports keying*/ - GF_VIDEO_HW_HAS_COLOR_KEY = (1<<2), - /*HW supports 90 degres rotation of display in 2D mode (Mobile Phones & PDAs)*/ - GF_VIDEO_HW_CAN_ROTATE = (1<<3), + GF_VIDEO_HW_HAS_YUV = (1<<3), + /*HW supports YUV overlays*/ + GF_VIDEO_HW_HAS_YUV_OVERLAY = (1<<4), /*HW supports OpenGL rendering. Whether this is OpenGL or OpenGL-ES depends on compilation settings and cannot be changed at runtime*/ - GF_VIDEO_HW_OPENGL = (1<<4), + GF_VIDEO_HW_OPENGL = (1<<5), /*HW supports OpenGL offscreen rendering. Whether this is OpenGL or OpenGL-ES depends on compilation settings and cannot be changed at runtime*/ - GF_VIDEO_HW_OPENGL_OFFSCREEN = (1<<5), + GF_VIDEO_HW_OPENGL_OFFSCREEN = (1<<6), /*HW supports OpenGL offscreen rendering with alpha. Whether this is OpenGL or OpenGL-ES depends on compilation settings and cannot be changed at runtime*/ - GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA = (1<<6), - /*HW supports YUV overlays*/ - GF_VIDEO_HW_HAS_YUV_OVERLAY = (1<<7), + GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA = (1<<7), + + /*HW supports line blitting*/ + GF_VIDEO_HW_HAS_LINE_BLIT = (1<<15), + /*HW supports locking a surface by device context (Win32 only)*/ + GF_VIDEO_HW_HAS_HWND_HDC = (1<<16), + /*HW only supports direct rendering mode*/ + GF_VIDEO_HW_DIRECT_ONLY = (1<<17), }; +typedef struct +{ + GF_IRect *list; + u32 count; +} GF_DirtyRectangles; + +typedef struct _gf_sc_texture_handler GF_TextureH; + /*interface name and version for video output*/ -#define GF_VIDEO_OUTPUT_INTERFACE GF_4CC('G','V','O',0x04) +#define GF_VIDEO_OUTPUT_INTERFACE GF_4CC('G','V','O','1') /* video output interface @@ -158,6 +173,29 @@ typedef struct _video_out */ GF_Err (*Blit)(struct _video_out *vout, GF_VideoSurface *video_src, GF_Window *src_wnd, GF_Window *dst_wnd, u32 overlay_type); + /*optional + blits the texture as a bitmap with the specified transform cliped with the given cliper, with alpha and + color keying (NULL if no keying) + */ + Bool (*BlitTexture)(struct _video_out *vout, GF_TextureH *texture, GF_Matrix2D *transform, GF_IRect *clip, u8 alpha, GF_ColorKey *col_key, Fixed depth_offset, Fixed depth_gain); + /*optional + releases any HW resource used by the texture object due to a call to BlitTexture. This is called when + the object is about to be destroyed or is no longer visible on screen + */ + void (*ReleaseTexture)(struct _video_out *vout, GF_TextureH *texture); + + /*optional + flushes only the listed rectangles + */ + void (*FlushRectangles)(struct _video_out *vout, GF_DirtyRectangles *rectangles); + + /*ignored if GF_VIDEO_HW_HAS_LINE_BLIT is not set*/ + void (*DrawHLine)(struct _video_out *vout, u32 x, u32 y, u32 length, GF_Color color); + void (*DrawHLineAlpha)(struct _video_out *vout, u32 x, u32 y, u32 length, GF_Color color, u8 alpha); + void (*DrawRectangle)(struct _video_out *vout, u32 x, u32 y, u32 width, u32 height, GF_Color color); + + + /*set of above HW flags*/ u32 hw_caps; /*main pixel format of video board (informative only)*/ @@ -166,12 +204,17 @@ typedef struct _video_out u32 yuv_pixel_format; /*maximum resolution of the screen*/ u32 max_screen_width, max_screen_height; + /* dpi of the screen*/ + u32 dpi_x, dpi_y; /*overlay color key used by the hardware bliter - if not set, only top-level overlay can be used*/ u32 overlay_color_key; -#ifdef ENABLE_JOYSTICK - u32 centered_mode; -#endif + + /*for auto-stereoscopic output*/ + /*maximum pixel disparity*/ + u32 disparity; + /*nominal display viewing distance in pixels*/ + Fixed view_distance; /*driver private*/ void *opaque; diff --git a/include/gpac/mpeg4_odf.h b/include/gpac/mpeg4_odf.h index d98bf71..5773294 100644 --- a/include/gpac/mpeg4_odf.h +++ b/include/gpac/mpeg4_odf.h @@ -112,7 +112,7 @@ enum /*descriptor for aucilary video data*/ - GF_ODF_AUX_VIDEO_DATA = GF_ODF_EXT_BEGIN_TAG + 1, + GF_ODF_AUX_VIDEO_DATA = GF_ODF_EXT_BEGIN_TAG + 1 }; @@ -293,7 +293,7 @@ enum /*control point between CB and render*/ IPMP_CP_CM = 3, /*control point in BIFS tree (???)*/ - IPMP_CP_BIFS = 4, + IPMP_CP_BIFS = 4 /*the rest is reserved or forbidden(0xFF)*/ }; @@ -345,8 +345,8 @@ typedef struct /* Elementary Mask of Bifs Config - parsing only */ typedef struct { BASE_DESCRIPTOR - u32 node_id; // referenced nodeID - char *node_name; // referenced node name + u32 node_id; /* referenced nodeID */ + char *node_name; /* referenced node name */ } GF_ElementaryMask; /*BIFSConfig - parsing only, STORED IN ESD:DCD:DSI*/ @@ -415,7 +415,7 @@ enum GF_TXT_SCROLL_DIRECTION = 0x00000180, GF_TXT_KARAOKE = 0x00000800, GF_TXT_VERTICAL = 0x00020000, - GF_TXT_FILL_REGION = 0x00040000, + GF_TXT_FILL_REGION = 0x00040000 }; typedef struct @@ -497,6 +497,10 @@ typedef struct { /*indicates input file shall be destryed - used during SWF import*/ Bool delete_file; + + /*carousel configuration*/ + u32 carousel_period_plus_one; + u16 aggregate_on_esid; } GF_MuxInfo; typedef struct @@ -800,6 +804,8 @@ typedef struct { u16 size; char *data; + /* used of AVC/SVC detection */ + s32 id; } GF_AVCConfigSlot; typedef struct @@ -812,6 +818,9 @@ typedef struct GF_List *sequenceParameterSets; GF_List *pictureParameterSets; + + /*for SVC*/ + u8 complete_representation; } GF_AVCConfig; @@ -942,13 +951,18 @@ typedef struct tagODCoDec GF_List *CommandList; } GF_ODCodec; + /*construction / destruction*/ GF_ODCodec *gf_odf_codec_new(); void gf_odf_codec_del(GF_ODCodec *codec); /* add a command to the codec command list. */ GF_Err gf_odf_codec_add_com(GF_ODCodec *codec, GF_ODCom *command); -/*encode the current coimmand list - once called the commands are destroyed*/ -GF_Err gf_odf_codec_encode(GF_ODCodec *codec, Bool delete_content); +/*encode the current command list - once called the commands are removed or destroyed depending on @cleanup_type: + 0: commands are removed from the list but not destroyed + 1: commands are removed from the list and destroyed + 2: commands are kept in the list and not destroyed +if delete_content is set*/ +GF_Err gf_odf_codec_encode(GF_ODCodec *codec, u32 cleanup_type); /*get the encoded AU. user is responsible of allocated space*/ GF_Err gf_odf_codec_get_au(GF_ODCodec *codec, char **outAU, u32 *au_length); /* set the encoded AU to the codec*/ @@ -980,6 +994,32 @@ GF_Err gf_odf_com_del(GF_ODCom **com); GF_Descriptor *gf_odf_desc_new(u8 tag); void gf_odf_desc_del(GF_Descriptor *desc); +/*this is a helper for building a preformatted GF_ESD with decoderConfig, decoderSpecificInfo with no data and +SLConfig descriptor with predefined*/ +GF_ESD *gf_odf_desc_esd_new(u32 sl_predefined); + +/*special function for authoring - convert DSI to BIFSConfig*/ +GF_BIFSConfig *gf_odf_get_bifs_config(GF_DefaultDescriptor *dsi, u8 oti); +/*special function for authoring - convert DSI to LASERConfig*/ +GF_Err gf_odf_get_laser_config(GF_DefaultDescriptor *dsi, GF_LASERConfig *cfg); +/*sepcial function for authoring - convert DSI to TextConfig*/ +GF_Err gf_odf_get_text_config(GF_DefaultDescriptor *dsi, u8 oti, GF_TextConfig *cfg); +/*special function for authoring - convert DSI to UIConfig*/ +GF_Err gf_odf_get_ui_config(GF_DefaultDescriptor *dsi, GF_UIConfig *cfg); +/*converts UIConfig to dsi - does not destroy input descr but does create output one*/ +GF_Err gf_odf_encode_ui_config(GF_UIConfig *cfg, GF_DefaultDescriptor **out_dsi); + +/*simple constructor/destructor*/ +GF_AVCConfig *gf_odf_avc_cfg_new(); +void gf_odf_avc_cfg_del(GF_AVCConfig *cfg); +/*gets GF_AVCConfig from MPEG-4 DSI*/ +GF_AVCConfig *gf_odf_avc_cfg_read(char *dsi, u32 dsi_size); +/*writes GF_AVCConfig as MPEG-4 DSI*/ +GF_Err gf_odf_avc_cfg_write(GF_AVCConfig *cfg, char **outData, u32 *outSize); + +/*destroy the descriptors in a list but not the list*/ +GF_Err gf_odf_desc_list_del(GF_List *descList); + /*use this function to decode a standalone descriptor the raw descriptor MUST be formatted with tag and size field!!! a new desc is created and you must delete it when done*/ @@ -997,7 +1037,6 @@ u32 gf_odf_desc_size(GF_Descriptor *desc); /*this is usefull to duplicate on the fly a descriptor*/ GF_Err gf_odf_desc_copy(GF_Descriptor *inDesc, GF_Descriptor **outDesc); - /*This functions handles internally what desc can be added to another desc and adds it. NO DUPLICATION of the descriptor, so once a desc is added to its parent, destroying the parent WILL DESTROY @@ -1005,10 +1044,6 @@ this descriptor*/ GF_Err gf_odf_desc_add_desc(GF_Descriptor *parentDesc, GF_Descriptor *newDesc); -/*this is a helper for building a preformatted GF_ESD with decoderConfig, decoderSpecificInfo with no data and -SLConfig descriptor with predefined*/ -GF_ESD *gf_odf_desc_esd_new(u32 sl_predefined); - /*Since IPMP V2, we introduce a new set of functions to read / write a list of descriptors that have no containers (a bit like an OD command, but for descriptors) @@ -1025,32 +1060,13 @@ you must pass (outEncList != NULL && *outEncList == NULL)*/ GF_Err gf_odf_desc_list_write(GF_List *descList, char **outEncList, u32 *outSize); /*returns size of encoded desc list*/ GF_Err gf_odf_desc_list_size(GF_List *descList, u32 *outSize); -/*destroy the descriptors in a list but not the list*/ -GF_Err gf_odf_desc_list_del(GF_List *descList); /*retuns NULL if unknown, otherwise value*/ const char *gf_odf_stream_type_name(u32 streamType); u32 gf_odf_stream_type_by_name(const char *streamType); -/*special function for authoring - convert DSI to BIFSConfig*/ -GF_BIFSConfig *gf_odf_get_bifs_config(GF_DefaultDescriptor *dsi, u8 oti); -/*special function for authoring - convert DSI to LASERConfig*/ -GF_Err gf_odf_get_laser_config(GF_DefaultDescriptor *dsi, GF_LASERConfig *cfg); -/*sepcial function for authoring - convert DSI to TextConfig*/ -GF_Err gf_odf_get_text_config(GF_DefaultDescriptor *dsi, u8 oti, GF_TextConfig *cfg); -/*special function for authoring - convert DSI to UIConfig*/ -GF_Err gf_odf_get_ui_config(GF_DefaultDescriptor *dsi, GF_UIConfig *cfg); -/*converts UIConfig to dsi - does not destroy input descr but does create output one*/ -GF_Err gf_odf_encode_ui_config(GF_UIConfig *cfg, GF_DefaultDescriptor **out_dsi); - -/*simple constructor/destructor*/ -GF_AVCConfig *gf_odf_avc_cfg_new(); -void gf_odf_avc_cfg_del(GF_AVCConfig *cfg); -/*gets GF_AVCConfig from MPEG-4 DSI*/ -GF_AVCConfig *gf_odf_avc_cfg_read(char *dsi, u32 dsi_size); -/*writes GF_AVCConfig as MPEG-4 DSI*/ -GF_Err gf_odf_avc_cfg_write(GF_AVCConfig *cfg, char **outData, u32 *outSize); +#ifndef GPAC_MINIMAL_ODF /************************************************************ @@ -1122,6 +1138,8 @@ you MUST delete events */ OCIEvent *gf_oci_codec_get_event(OCICodec *codec); +#ifndef GPAC_DISABLE_OD_DUMP + /*OD dump tools*/ GF_Err gf_odf_dump_au(char *data, u32 dataLength, FILE *trace, u32 indent, Bool XMTDump); GF_Err gf_odf_dump_com(void *p, FILE *trace, u32 indent, Bool XMTDump); @@ -1132,10 +1150,15 @@ GF_Err gf_odf_dump_com_list(GF_List *commandList, FILE *trace, u32 indent, Bool GF_Err gf_oci_dump_event(OCIEvent *ev, FILE *trace, u32 indent, Bool XMTDump); GF_Err gf_oci_dump_au(u8 version, char *au, u32 au_length, FILE *trace, u32 indent, Bool XMTDump); +#endif /*GPAC_DISABLE_OD_DUMP*/ + + +#endif /*GPAC_MINIMAL_ODF*/ /*OD parsing tools (XMT/BT)*/ /*returns desc tag based on name*/ u32 gf_odf_get_tag_by_name(char *descName); + /*field type for OD/QoS/IPMPX/etc*/ enum { @@ -1152,12 +1175,14 @@ enum /*IPMP ByteArray type*/ GF_ODF_FT_IPMPX_BA = 5, /*IPMP ByteArray list type*/ - GF_ODF_FT_IPMPX_BA_LIST = 6, + GF_ODF_FT_IPMPX_BA_LIST = 6 }; u32 gf_odf_get_field_type(GF_Descriptor *desc, char *fieldName); + /*set non-descriptor field value - value string shall be presented without ' or " characters*/ GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val); +#ifndef GPAC_MINIMAL_ODF @@ -1184,7 +1209,7 @@ enum { GF_IPMPX_AUTH_Forbidden_Tag = 0x00, GF_IPMPX_AUTH_AlgorithmDescr_Tag = 0x01, - GF_IPMPX_AUTH_KeyDescr_Tag = 0x02, + GF_IPMPX_AUTH_KeyDescr_Tag = 0x02 }; typedef struct @@ -1248,7 +1273,7 @@ enum GF_IPMPX_KEY_DESCRIPTOR_TAG = 0xA4, GF_IPMPX_PARAM_DESCRIPTOR_ITEM_TAG = 0xA5, GF_IPMPX_SEL_ENC_BUFFER_TAG = 0xA6, - GF_IPMPX_SEL_ENC_FIELD_TAG = 0xA7, + GF_IPMPX_SEL_ENC_FIELD_TAG = 0xA7 }; typedef char GF_IPMPX_Date[5]; @@ -1381,7 +1406,7 @@ typedef struct typedef struct { GF_IPMPX_DATA_BASE - u8 scope; + u8 scope; u16 IPMP_DescriptorIDEx; } GF_IPMPX_GetToolContext; @@ -1389,9 +1414,9 @@ typedef struct typedef struct { GF_IPMPX_DATA_BASE - u16 OD_ID; + u16 OD_ID; u16 ESD_ID; - u32 IPMP_ToolContextID; + u32 IPMP_ToolContextID; } GF_IPMPX_GetToolContextResponse; /*GF_IPMPX_LISTEN_Types*/ @@ -1401,7 +1426,7 @@ enum GF_IPMPX_LISTEN_CONNECTIONFAILED = 0x01, GF_IPMPX_LISTEN_DISCONNECTED = 0x02, GF_IPMPX_LISTEN_DISCONNECTIONFAILED = 0x03, - GF_IPMPX_LISTEN_WATERMARKDETECTED = 0x04, + GF_IPMPX_LISTEN_WATERMARKDETECTED = 0x04 }; typedef struct @@ -1513,7 +1538,7 @@ enum GF_IPMPX_SE_COMP_VIDEO_GOB = 0x04, /*0x05-2F ISO Reserved for video*/ GF_IPMPX_SE_COMP_AAC_DF = 0x30, - GF_IPMPX_SE_COMP_AAC_NONE = 0x31, + GF_IPMPX_SE_COMP_AAC_NONE = 0x31 /* 0x32 - 0x5F ISO Reserved for audio 0x60 - 0xCF ISO Reserved @@ -1529,7 +1554,7 @@ enum GF_IPMPX_SE_SYNC_VIDEO_VOP = 0x01, GF_IPMPX_SE_SYNC_VIDEO_GOV = 0x02, /*0x03-2F ISO Reserved for video,*/ - GF_IPMPX_SE_SYNC_AAC_DF = 0x30, + GF_IPMPX_SE_SYNC_AAC_DF = 0x30 /*0x31 - 0x5F ISO Reserved for audio 0x60 - 0xCF ISO Reserved 0xD0 - 0xFE User Defined @@ -1549,7 +1574,7 @@ enum /*0x06-2F ISO Reserved for video*/ GF_IPMPX_SE_FID_AAC_SIGN = 0x30, GF_IPMPX_SE_FID_AAC_CODEWORDS = 0x31, - GF_IPMPX_SE_FID_AAC_SCALE = 0x32, + GF_IPMPX_SE_FID_AAC_SCALE = 0x32 /*0x32 - 0x5F ISO Reserved for audio 0x60 - 0xCF ISO Reserved 0xD0 - 0xFE User Defined @@ -1580,7 +1605,7 @@ enum GF_IPMPX_WM_INSERT = 0, GF_IPMPX_WM_EXTRACT = 1, GF_IPMPX_WM_REMARK = 2, - GF_IPMPX_WM_DETECT_COMPRESSION = 3, + GF_IPMPX_WM_DETECT_COMPRESSION = 3 }; /*used for both audio and video WM init*/ @@ -1629,7 +1654,7 @@ enum { GF_IPMPX_WM_COMPRESSION = 0, GF_IPMPX_WM_NO_COMPRESSION = 1, - GF_IPMPX_WM_COMPRESSION_UNKNOWN = 2, + GF_IPMPX_WM_COMPRESSION_UNKNOWN = 2 }; typedef struct @@ -1689,6 +1714,7 @@ GF_Err gf_ipmpx_set_byte_array(GF_IPMPX_Data *p, char *field, char *str); GF_Err gf_ipmpx_dump_data(GF_IPMPX_Data *_p, FILE *trace, u32 indent, Bool XMTDump); +#endif /*GPAC_MINIMAL_ODF*/ #ifdef __cplusplus } diff --git a/include/gpac/mpegts.h b/include/gpac/mpegts.h index d508634..c5d081d 100644 --- a/include/gpac/mpegts.h +++ b/include/gpac/mpegts.h @@ -27,15 +27,26 @@ #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> 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; + /*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 + /*MPEG-2 TS Media types*/ enum { @@ -45,6 +56,14 @@ enum GF_M2TS_AUDIO_MPEG2 = 0x04, GF_M2TS_PRIVATE_SECTION = 0x05, GF_M2TS_PRIVATE_DATA = 0x06, + GF_M2TS_MHEG = 0x07, + GF_M2TS_13818_1_DSMCC = 0x08, + GF_M2TS_H222_1 = 0x09, + GF_M2TS_13818_6_ANNEX_A = 0x0A, + GF_M2TS_13818_6_ANNEX_B = 0x0B, + GF_M2TS_13818_6_ANNEX_C = 0x0C, + GF_M2TS_13818_6_ANNEX_D = 0x0D, + GF_M2TS_13818_1_AUXILIARY = 0x0E, GF_M2TS_AUDIO_AAC = 0x0F, GF_M2TS_VIDEO_MPEG4 = 0x10, GF_M2TS_AUDIO_LATM_AAC = 0x11, @@ -56,7 +75,15 @@ enum GF_M2TS_AUDIO_AC3 = 0x81, GF_M2TS_AUDIO_DTS = 0x8A, + GF_M2TS_MPE_SECTIONS = 0x90, GF_M2TS_SUBTITLE_DVB = 0x100, + + /*internal use*/ + GF_M2TS_AUDIO_EC3 = 0x150, + GF_M2TS_VIDEO_VC1 = 0x151, + GF_M2TS_DVB_TELETEXT = 0x152, + GF_M2TS_DVB_VBI = 0x153, + GF_M2TS_DVB_SUBTITLE = 0x154, }; /*returns readable name for given stream type*/ const char *gf_m2ts_get_stream_name(u32 streamType); @@ -141,6 +168,8 @@ enum #endif /* A generic event message for EIT, TDT, TOT etc */ GF_M2TS_EVT_DVB_GENERAL, + /* MPE / MPE-FEC frame extraction and IP datagrams decryptation */ + GF_M2TS_EVT_DVB_MPE, }; enum @@ -164,7 +193,8 @@ typedef struct __m2ts_demux_table { struct __m2ts_demux_table *next; - Bool is_init; + u8 is_init; + u8 is_repeat; /*table id*/ u8 table_id; @@ -194,8 +224,6 @@ typedef struct GF_M2TS_SectionFilter u16 length; /*number of bytes received from current section*/ u16 received; - /*error indiator when reaggregating sections*/ - u8 had_error; /*section->table aggregator*/ GF_M2TS_Table *table; @@ -242,12 +270,16 @@ enum GF_M2TS_ES_IS_SL = 1<<2, /*ES is an mpeg-4 Object Descriptor SL-packetized stream*/ GF_M2TS_ES_IS_MPEG4_OD = 1<<3, + /*ES is a DVB MPE stream*/ + GF_M2TS_ES_IS_MPE = 1<<4, /*all flags above this mask are used by importers & co*/ GF_M2TS_ES_STATIC_FLAGS_MASK = 0x0000FFFF, + /*always send sections regardless of their version_number*/ + GF_M2TS_ES_SEND_REPEATED_SECTIONS = 1<<16, /*Flag used by importers*/ - GF_M2TS_ES_FIRST_DTS = 1<<20, + GF_M2TS_ES_FIRST_DTS = 1<<17, }; /*Abstract Section/PES stream object, only used for type casting*/ @@ -257,6 +289,8 @@ enum u32 pid; \ u32 stream_type; \ u32 mpeg4_es_id; \ + GF_SLConfig *slcfg; \ + s16 component_tag; \ void *user; \ u64 first_dts; @@ -265,21 +299,23 @@ struct tag_m2ts_es ABSTRACT_ES }; -/*INT object*/ -typedef struct + +typedef struct { - u32 id; -} GF_M2TS_INT; + u8 id; + u16 pck_len; + u8 data_alignment; + u64 PTS, DTS; + u8 hdr_data_len; +} GF_M2TS_PESHeader; struct tag_m2ts_section_es { ABSTRACT_ES GF_M2TS_SectionFilter *sec; - - /* MPE Frame object, MPE-FEC related data */ - GF_M2TS_INT *ip_mac_not_table; }; + /*******************************************************************************/ typedef struct tag_m2ts_dvb_sub { @@ -301,6 +337,8 @@ typedef struct tag_m2ts_dvb_teletext typedef struct tag_m2ts_pes { ABSTRACT_ES + /*continuity counter check*/ + s16 cc; u32 lang; /*object info*/ @@ -311,12 +349,16 @@ typedef struct tag_m2ts_pes /*mpegts lib private - do not touch :)*/ /*PES re-assembler*/ unsigned char *data; - u32 data_len, pes_len; + /*amount of bytes received in the current PES packet (NOT INCLUDING ANY PENDING BYTES)*/ + u32 data_len; + /*size of the PES packet being recevied*/ + u32 pes_len; Bool rap; u64 PTS, DTS; /*PES reframer - if NULL, pes processing is skiped*/ u32 frame_state; + /*returns the number of bytes consummed from the input data buffer*/ void (*reframe)(struct tag_m2ts_demux *ts, struct tag_m2ts_pes *pes, u64 DTS, u64 CTS, unsigned char *data, u32 data_len); /*LATM stuff - should be moved out of mpegts*/ unsigned char *buf; @@ -382,16 +424,15 @@ typedef struct { /*EIT information objects*/ typedef struct { - u32 year, month, day, time; + time_t unix_time; - /* local time offset descriptor data */ + /* local time offset descriptor data (unused ...) */ char country_code[3]; u8 country_region_id; - u8 local_time_offset_polarity; - u16 local_time_offset; - /*time_of_change*/ - u32 toc_year, toc_month, toc_day, toc_time; - u16 next_time_offset; + s32 local_time_offset_seconds; + time_t unix_next_toc; + s32 next_time_offset_seconds; + } GF_M2TS_DateTime_Event; typedef struct { @@ -405,8 +446,9 @@ typedef struct { typedef struct { u16 event_id; - GF_M2TS_DateTime_Event start; - u32 duration; + time_t unix_start; + time_t unix_duration; + u8 running_status; u8 free_CA_mode; GF_List *short_events; @@ -424,9 +466,6 @@ typedef struct GF_List *events; } GF_M2TS_EIT; -void gf_m2ts_decode_mjd_date(u32 date, u32 *year, u32 *month, u32 *day); - - /*MPEG-2 TS packet*/ typedef struct { @@ -443,6 +482,7 @@ typedef struct { char *data; u32 data_len; + u8 version_number; /*parent stream */ GF_M2TS_ES *stream; } GF_M2TS_SL_PCK; @@ -466,38 +506,48 @@ struct tag_m2ts_demux /*default transport PID filters*/ GF_M2TS_SectionFilter *pat, *nit, *sdt, *eit, *tdt_tot_st; - /* Structure to hold all the INT tables if the TS contains IP streams */ - GF_List *ip_mac_not_tables; - Bool has_4on2; /* analyser */ FILE *pes_out; -}; + Bool dvb_h_demux; + /*user callback - MUST NOT BE NULL*/ + void (*on_mpe_event)(struct tag_m2ts_demux *ts, u32 evt_type, void *par); + /* Structure to hold all the INT tables if the TS contains IP streams */ + struct __gf_dvb_mpe_ip_platform *ip_platform; +}; GF_M2TS_Demuxer *gf_m2ts_demux_new(); void gf_m2ts_demux_del(GF_M2TS_Demuxer *ts); void gf_m2ts_reset_parsers(GF_M2TS_Demuxer *ts); +GF_ESD *gf_m2ts_get_esd(GF_M2TS_ES *es); GF_Err gf_m2ts_set_pes_framing(GF_M2TS_PES *pes, u32 mode); GF_Err gf_m2ts_process_data(GF_M2TS_Demuxer *ts, char *data, u32 data_size); + + 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_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, /* ... */ @@ -540,12 +590,18 @@ enum /* ... */ 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, }; @@ -590,7 +646,10 @@ enum { 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 - 0x4d reserved */ + /* 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 */ @@ -615,12 +674,6 @@ enum { /* 0xff reserved */ }; -enum { - M2TS_ADAPTATION_RESERVED = 0, - M2TS_ADAPTATION_NONE = 1, - M2TS_ADAPTATION_ONLY = 2, - M2TS_ADAPTATION_AND_PAYLOAD = 3, -}; #define SECTION_HEADER_LENGTH 3 /* header till the last bit of the section_length field */ @@ -669,13 +722,196 @@ typedef struct */ } GF_M2TS_AdaptationField; -typedef struct + + +void gf_m2ts_print_info(GF_M2TS_Demuxer *ts); + +#ifndef GPAC_DISABLE_MPEG2TS_MUX + +/* + MPEG-2 TS Multiplexer +*/ + +enum { + GF_M2TS_ADAPTATION_RESERVED = 0, + GF_M2TS_ADAPTATION_NONE = 1, + GF_M2TS_ADAPTATION_ONLY = 2, + GF_M2TS_ADAPTATION_AND_PAYLOAD = 3, +}; + + + +typedef struct __m2ts_mux_program GF_M2TS_Mux_Program; +typedef struct __m2ts_mux GF_M2TS_Mux; + +typedef struct __m2ts_section { + struct __m2ts_section *next; + u8 *data; + u32 length; +} GF_M2TS_Mux_Section; + +typedef struct __m2ts_table { + struct __m2ts_table *next; + u8 table_id; + u8 version_number; + struct __m2ts_section *section; +} GF_M2TS_Mux_Table; + +typedef struct { - u8 id; - u16 pck_len; - u8 data_alignment; - u64 PTS, DTS; - u8 hdr_data_len; -} GF_M2TS_PESHeader; + u32 sec; + u32 nanosec; +} GF_M2TS_Time; + + +typedef struct __m2ts_mux_pck +{ + struct __m2ts_mux_pck *next; + char *data; + u32 data_len; + u32 flags; + u64 cts, dts; +} GF_M2TS_Packet; + + +typedef struct __m2ts_mux_stream { + struct __m2ts_mux_stream *next; + + u32 pid; + u8 continuity_counter; + struct __m2ts_mux_program *program; + + /*average stream bit-rate in bit/sec*/ + u32 bit_rate; + + /*multiplexer time - NOT THE PCR*/ + GF_M2TS_Time time; + + /*table tools*/ + GF_M2TS_Mux_Table *tables; + /*total table sizes for bitrate estimation (PMT/PAT/...)*/ + u32 total_table_size; + /* used for on-the-fly packetization of sections */ + GF_M2TS_Mux_Table *current_table; + GF_M2TS_Mux_Section *current_section; + u32 current_section_offset; + u32 refresh_rate_ms; + Bool table_needs_update; + + Bool (*process)(struct __m2ts_mux *muxer, struct __m2ts_mux_stream *stream); + + /*PES tools*/ + void *pes_packetizer; + u32 mpeg2_stream_type; + u32 mpeg2_stream_id; + + GF_ESIPacket pck; + u32 pck_offset; + Bool force_new; + + struct __elementary_stream_ifce *ifce; + Double ts_scale; + u64 initial_ts; + + /*packet fifo*/ + GF_M2TS_Packet *pck_first, *pck_last; + /*packet reassembler (PES packets are most of the time full frames)*/ + GF_M2TS_Packet *pck_reassembler; + GF_Mutex *mx; + /*avg bitrate compute*/ + u64 last_br_time; + u32 bytes_since_last_time; + + /*MPEG-4 over MPEG-2*/ + u8 table_id; + GF_SLHeader sl_header; + /* MPEG-4 SL Config */ + GF_SLConfig sl_config; + + u32 last_aac_time; +} GF_M2TS_Mux_Stream; + + +struct __m2ts_mux_program { + struct __m2ts_mux_program *next; + + struct __m2ts_mux *mux; + u16 number; + /*all streams but PMT*/ + GF_M2TS_Mux_Stream *streams; + /*PMT*/ + GF_M2TS_Mux_Stream *pmt; + /*pointer to PCR stream*/ + GF_M2TS_Mux_Stream *pcr; + + /*TS time at pcr init*/ + GF_M2TS_Time ts_time_at_pcr_init; + u64 pcr_init_time, num_pck_at_pcr_init; + u64 last_pcr; + u32 last_sys_clock; + + GF_Descriptor *iod; +}; + +struct __m2ts_mux { + GF_M2TS_Mux_Program *programs; + GF_M2TS_Mux_Stream *pat; + + u16 ts_id; + + Bool needs_reconfig; + + /* used to indicate that the input data is pushed to the muxer (i.e. not read from a file) + or that the output data is sent on sockets (not written to a file) */ + Bool real_time; + + /* indicates if the multiplexer shall target a fix bit rate (monitoring timing and produce padding packets) + or if the output stream will contain only input data*/ + Bool fixed_rate; + + /*output bit-rate in bit/sec*/ + u32 bit_rate; + + char dst_pck[188], null_pck[188]; + + /*multiplexer time, incremented each time a packet is sent + used to monitor the sending of muxer related data (PAT, ...) */ + GF_M2TS_Time time; + + /* Time of the muxer when the first call to process is made (first packet sent?) */ + GF_M2TS_Time init_ts_time; + + /* System time when the muxer is started */ + u32 init_sys_time; + + Bool eos_found; + u32 pck_sent_over_br_window, last_br_time, avg_br; + u64 tot_pck_sent, tot_pad_sent; + + Bool mpeg4_signaling; +}; + + +enum +{ + GF_M2TS_STATE_IDLE, + GF_M2TS_STATE_DATA, + GF_M2TS_STATE_PADDING, + GF_M2TS_STATE_EOS, +}; + +GF_M2TS_Mux *gf_m2ts_mux_new(u32 mux_rate, Bool real_time); +void gf_m2ts_mux_del(GF_M2TS_Mux *mux); +GF_M2TS_Mux_Program *gf_m2ts_mux_program_add(GF_M2TS_Mux *muxer, u32 program_number, u32 pmt_pid); +GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, GF_ESInterface *ifce, u32 pid, Bool is_pcr); +void gf_m2ts_mux_update_config(GF_M2TS_Mux *mux, Bool reset_time); +const char *gf_m2ts_mux_process(GF_M2TS_Mux *muxer, u32 *status); +u32 gf_m2ts_get_sys_clock(GF_M2TS_Mux *muxer); +u32 gf_m2ts_get_ts_clock(GF_M2TS_Mux *muxer); + + +#endif /*GPAC_DISABLE_MPEG2TS_MUX*/ + +#endif /*GPAC_DISABLE_MPEG2TS*/ #endif //_GF_MPEG_TS_H_ diff --git a/include/gpac/network.h b/include/gpac/network.h index 0e2bb23..e8e6249 100644 --- a/include/gpac/network.h +++ b/include/gpac/network.h @@ -77,6 +77,15 @@ char *gf_url_get_absolute_path(const char *pathName, const char *parentPath); */ char *gf_url_concatenate(const char *parentName, const char *pathName); +/*! + *\brief URL encodin + * + *Encodes URL by replacing special characters with their % encodings. + *\param path URL of the service + *\return encoded path name , or NULL if bad paths are provided. + \note the returned string must be freed by user + */ +char *gf_url_percent_encode(const char *path); /*! *\brief URL to file system @@ -317,7 +326,7 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_ip_add, u16 multi_port *\param multi_ip_add the multicast IP address to test *\return 1 if the address is a multicast one, 0 otherwise */ -u32 gf_sk_is_multicast_address(char *multi_ip_add); +u32 gf_sk_is_multicast_address(const char *multi_ip_add); /*! *\brief send data with wait delay @@ -378,7 +387,7 @@ Bool gf_net_is_ipv6(char *address); * * The gf_net_mobileip_ctrl_cbk type is the type for the callback of the \ref gf_net_set_mobileip_callback function. By default no mobileip is used * \param cbck Opaque user data. - * \param start boolean indicating wether the MobileIP subsystem should be started or stoped. + * \param start boolean indicating wether the MobileIP subsystem should be started or stopped. * \return Error code if needed. * */ diff --git a/include/gpac/nodes_mpeg4.h b/include/gpac/nodes_mpeg4.h index 7433f23..99e101a 100644 --- a/include/gpac/nodes_mpeg4.h +++ b/include/gpac/nodes_mpeg4.h @@ -24,9 +24,9 @@ /* - DO NOT MOFIFY - File generated on GMT Thu Aug 07 11:43:26 2008 + DO NOT MOFIFY - File generated on GMT Mon Jan 18 12:27:12 2010 - BY MPEG4Gen for GPAC Version 0.4.5-DEV + BY MPEG4Gen for GPAC Version 0.4.6-DEV */ #ifndef _nodes_mpeg4_H @@ -38,6 +38,8 @@ extern "C" { #include <gpac/scenegraph_vrml.h> +#ifndef GPAC_DISABLE_VRML + enum { @@ -212,6 +214,30 @@ enum { TAG_MPEG4_XCurve2D, TAG_MPEG4_XFontStyle, TAG_MPEG4_XLineProperties, + TAG_MPEG4_AdvancedAudioBuffer, + TAG_MPEG4_AudioChannelConfig, + TAG_MPEG4_DepthImageV2, + TAG_MPEG4_MorphShape, + TAG_MPEG4_MultiTexture, + TAG_MPEG4_PointTextureV2, + TAG_MPEG4_SBVCAnimationV2, + TAG_MPEG4_SimpleTextureV2, + TAG_MPEG4_SurroundingSound, + TAG_MPEG4_Transform3DAudio, + TAG_MPEG4_WideSound, + TAG_MPEG4_ScoreShape, + TAG_MPEG4_MusicScore, + TAG_MPEG4_FootPrintSetNode, + TAG_MPEG4_FootPrintNode, + TAG_MPEG4_BuildingPartNode, + TAG_MPEG4_RoofNode, + TAG_MPEG4_FacadeNode, + TAG_MPEG4_Shadow, + TAG_MPEG4_CacheTexture, + TAG_MPEG4_EnvironmentTest, + TAG_MPEG4_KeyNavigator, + TAG_MPEG4_SpacePartition, + TAG_MPEG4_Storage, TAG_LastImplementedMPEG4 }; @@ -223,7 +249,7 @@ typedef struct _tagAnchor MFString parameter; /*exposedField*/ MFURL url; /*exposedField*/ SFBool activate; /*eventIn*/ - void (*on_activate)(GF_Node *pThis); /*eventInHandler*/ + void (*on_activate)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ } M_Anchor; @@ -340,7 +366,7 @@ typedef struct _tagBackground { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat groundAngle; /*exposedField*/ MFColor groundColor; /*exposedField*/ MFURL backUrl; /*exposedField*/ @@ -359,7 +385,7 @@ typedef struct _tagBackground2D { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFColor backColor; /*exposedField*/ MFURL url; /*exposedField*/ SFBool isBound; /*eventOut*/ @@ -416,7 +442,7 @@ typedef struct _tagColorInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFColor keyValue; /*exposedField*/ SFColor value_changed; /*eventOut*/ @@ -454,9 +480,9 @@ typedef struct _tagConditional { BASE_NODE SFBool activate; /*eventIn*/ - void (*on_activate)(GF_Node *pThis); /*eventInHandler*/ + void (*on_activate)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool reverseActivate; /*eventIn*/ - void (*on_reverseActivate)(GF_Node *pThis); /*eventInHandler*/ + void (*on_reverseActivate)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFCommandBuffer buffer; /*exposedField*/ SFBool isActive; /*eventOut*/ } M_Conditional; @@ -490,7 +516,7 @@ typedef struct _tagCoordinateInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec3f keyValue; /*exposedField*/ MFVec3f value_changed; /*eventOut*/ @@ -501,7 +527,7 @@ typedef struct _tagCoordinateInterpolator2D { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec2f keyValue; /*exposedField*/ MFVec2f value_changed; /*eventOut*/ @@ -572,7 +598,7 @@ typedef struct _tagElevationGrid { BASE_NODE MFFloat set_height; /*eventIn*/ - void (*on_set_height)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_height)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *normal; /*exposedField*/ GF_Node *texCoord; /*exposedField*/ @@ -589,17 +615,29 @@ typedef struct _tagElevationGrid } M_ElevationGrid; +typedef struct _tagExpression +{ + BASE_NODE + SFInt32 expression_select1; /*exposedField*/ + SFInt32 expression_intensity1; /*exposedField*/ + SFInt32 expression_select2; /*exposedField*/ + SFInt32 expression_intensity2; /*exposedField*/ + SFBool init_face; /*exposedField*/ + SFBool expression_def; /*exposedField*/ +} M_Expression; + + typedef struct _tagExtrusion { BASE_NODE MFVec2f set_crossSection; /*eventIn*/ - void (*on_set_crossSection)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_crossSection)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFRotation set_orientation; /*eventIn*/ - void (*on_set_orientation)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_orientation)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFVec2f set_scale; /*eventIn*/ - void (*on_set_scale)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_scale)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFVec3f set_spine; /*eventIn*/ - void (*on_set_spine)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_spine)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool beginCap; /*field*/ SFBool ccw; /*field*/ SFBool convex; /*field*/ @@ -613,6 +651,148 @@ typedef struct _tagExtrusion } M_Extrusion; +typedef struct _tagFace +{ + BASE_NODE + GF_Node *fap; /*exposedField*/ + GF_Node *fdp; /*exposedField*/ + GF_Node *fit; /*exposedField*/ + GF_Node *ttsSource; /*exposedField*/ + GF_ChildNodeItem *renderedFace; /*exposedField*/ +} M_Face; + + +typedef struct _tagFaceDefMesh +{ + BASE_NODE + GF_Node *faceSceneGraphNode; /*field*/ + MFInt32 intervalBorders; /*field*/ + MFInt32 coordIndex; /*field*/ + MFVec3f displacements; /*field*/ +} M_FaceDefMesh; + + +typedef struct _tagFaceDefTables +{ + BASE_NODE + SFInt32 fapID; /*field*/ + SFInt32 highLevelSelect; /*field*/ + GF_ChildNodeItem *faceDefMesh; /*exposedField*/ + GF_ChildNodeItem *faceDefTransform; /*exposedField*/ +} M_FaceDefTables; + + +typedef struct _tagFaceDefTransform +{ + BASE_NODE + GF_Node *faceSceneGraphNode; /*field*/ + SFInt32 fieldId; /*field*/ + SFRotation rotationDef; /*field*/ + SFVec3f scaleDef; /*field*/ + SFVec3f translationDef; /*field*/ +} M_FaceDefTransform; + + +typedef struct _tagFAP +{ + BASE_NODE + GF_Node *viseme; /*exposedField*/ + GF_Node *expression; /*exposedField*/ + SFInt32 open_jaw; /*exposedField*/ + SFInt32 lower_t_midlip; /*exposedField*/ + SFInt32 raise_b_midlip; /*exposedField*/ + SFInt32 stretch_l_corner; /*exposedField*/ + SFInt32 stretch_r_corner; /*exposedField*/ + SFInt32 lower_t_lip_lm; /*exposedField*/ + SFInt32 lower_t_lip_rm; /*exposedField*/ + SFInt32 lower_b_lip_lm; /*exposedField*/ + SFInt32 lower_b_lip_rm; /*exposedField*/ + SFInt32 raise_l_cornerlip; /*exposedField*/ + SFInt32 raise_r_cornerlip; /*exposedField*/ + SFInt32 thrust_jaw; /*exposedField*/ + SFInt32 shift_jaw; /*exposedField*/ + SFInt32 push_b_lip; /*exposedField*/ + SFInt32 push_t_lip; /*exposedField*/ + SFInt32 depress_chin; /*exposedField*/ + SFInt32 close_t_l_eyelid; /*exposedField*/ + SFInt32 close_t_r_eyelid; /*exposedField*/ + SFInt32 close_b_l_eyelid; /*exposedField*/ + SFInt32 close_b_r_eyelid; /*exposedField*/ + SFInt32 yaw_l_eyeball; /*exposedField*/ + SFInt32 yaw_r_eyeball; /*exposedField*/ + SFInt32 pitch_l_eyeball; /*exposedField*/ + SFInt32 pitch_r_eyeball; /*exposedField*/ + SFInt32 thrust_l_eyeball; /*exposedField*/ + SFInt32 thrust_r_eyeball; /*exposedField*/ + SFInt32 dilate_l_pupil; /*exposedField*/ + SFInt32 dilate_r_pupil; /*exposedField*/ + SFInt32 raise_l_i_eyebrow; /*exposedField*/ + SFInt32 raise_r_i_eyebrow; /*exposedField*/ + SFInt32 raise_l_m_eyebrow; /*exposedField*/ + SFInt32 raise_r_m_eyebrow; /*exposedField*/ + SFInt32 raise_l_o_eyebrow; /*exposedField*/ + SFInt32 raise_r_o_eyebrow; /*exposedField*/ + SFInt32 squeeze_l_eyebrow; /*exposedField*/ + SFInt32 squeeze_r_eyebrow; /*exposedField*/ + SFInt32 puff_l_cheek; /*exposedField*/ + SFInt32 puff_r_cheek; /*exposedField*/ + SFInt32 lift_l_cheek; /*exposedField*/ + SFInt32 lift_r_cheek; /*exposedField*/ + SFInt32 shift_tongue_tip; /*exposedField*/ + SFInt32 raise_tongue_tip; /*exposedField*/ + SFInt32 thrust_tongue_tip; /*exposedField*/ + SFInt32 raise_tongue; /*exposedField*/ + SFInt32 tongue_roll; /*exposedField*/ + SFInt32 head_pitch; /*exposedField*/ + SFInt32 head_yaw; /*exposedField*/ + SFInt32 head_roll; /*exposedField*/ + SFInt32 lower_t_midlip_o; /*exposedField*/ + SFInt32 raise_b_midlip_o; /*exposedField*/ + SFInt32 stretch_l_cornerlip; /*exposedField*/ + SFInt32 stretch_r_cornerlip; /*exposedField*/ + SFInt32 lower_t_lip_lm_o; /*exposedField*/ + SFInt32 lower_t_lip_rm_o; /*exposedField*/ + SFInt32 raise_b_lip_lm_o; /*exposedField*/ + SFInt32 raise_b_lip_rm_o; /*exposedField*/ + SFInt32 raise_l_cornerlip_o; /*exposedField*/ + SFInt32 raise_r_cornerlip_o; /*exposedField*/ + SFInt32 stretch_l_nose; /*exposedField*/ + SFInt32 stretch_r_nose; /*exposedField*/ + SFInt32 raise_nose; /*exposedField*/ + SFInt32 bend_nose; /*exposedField*/ + SFInt32 raise_l_ear; /*exposedField*/ + SFInt32 raise_r_ear; /*exposedField*/ + SFInt32 pull_l_ear; /*exposedField*/ + SFInt32 pull_r_ear; /*exposedField*/ +} M_FAP; + + +typedef struct _tagFDP +{ + BASE_NODE + GF_Node *featurePointsCoord; /*exposedField*/ + GF_Node *textureCoord; /*exposedField*/ + GF_ChildNodeItem *faceDefTables; /*exposedField*/ + GF_ChildNodeItem *faceSceneGraph; /*exposedField*/ + SFBool useOrthoTexture; /*field*/ +} M_FDP; + + +typedef struct _tagFIT +{ + BASE_NODE + MFInt32 FAPs; /*exposedField*/ + MFInt32 Graph; /*exposedField*/ + MFInt32 numeratorExp; /*exposedField*/ + MFInt32 denominatorExp; /*exposedField*/ + MFInt32 numeratorImpulse; /*exposedField*/ + MFInt32 numeratorTerms; /*exposedField*/ + MFInt32 denominatorTerms; /*exposedField*/ + MFFloat numeratorCoefs; /*exposedField*/ + MFFloat denominatorCoefs; /*exposedField*/ +} M_FIT; + + typedef struct _tagFog { BASE_NODE @@ -620,7 +800,7 @@ typedef struct _tagFog SFString fogType; /*exposedField*/ SFFloat visibilityRange; /*exposedField*/ SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool isBound; /*eventOut*/ } M_Fog; @@ -671,13 +851,13 @@ typedef struct _tagIndexedFaceSet { BASE_NODE MFInt32 set_colorIndex; /*eventIn*/ - void (*on_set_colorIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_coordIndex; /*eventIn*/ - void (*on_set_coordIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_coordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_normalIndex; /*eventIn*/ - void (*on_set_normalIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_normalIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_texCoordIndex; /*eventIn*/ - void (*on_set_texCoordIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_texCoordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *coord; /*exposedField*/ GF_Node *normal; /*exposedField*/ @@ -699,11 +879,11 @@ typedef struct _tagIndexedFaceSet2D { BASE_NODE MFInt32 set_colorIndex; /*eventIn*/ - void (*on_set_colorIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_coordIndex; /*eventIn*/ - void (*on_set_coordIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_coordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_texCoordIndex; /*eventIn*/ - void (*on_set_texCoordIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_texCoordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *coord; /*exposedField*/ GF_Node *texCoord; /*exposedField*/ @@ -719,9 +899,9 @@ typedef struct _tagIndexedLineSet { BASE_NODE MFInt32 set_colorIndex; /*eventIn*/ - void (*on_set_colorIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_coordIndex; /*eventIn*/ - void (*on_set_coordIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_coordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *coord; /*exposedField*/ MFInt32 colorIndex; /*field*/ @@ -734,9 +914,9 @@ typedef struct _tagIndexedLineSet2D { BASE_NODE MFInt32 set_colorIndex; /*eventIn*/ - void (*on_set_colorIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_coordIndex; /*eventIn*/ - void (*on_set_coordIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_coordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *coord; /*exposedField*/ MFInt32 colorIndex; /*field*/ @@ -815,7 +995,7 @@ typedef struct _tagListeningPoint { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool jump; /*exposedField*/ SFRotation orientation; /*exposedField*/ SFVec3f position; /*exposedField*/ @@ -866,7 +1046,7 @@ typedef struct _tagNavigationInfo { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat avatarSize; /*exposedField*/ SFBool headlight; /*exposedField*/ SFFloat speed; /*exposedField*/ @@ -887,7 +1067,7 @@ typedef struct _tagNormalInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec3f keyValue; /*exposedField*/ MFVec3f value_changed; /*eventOut*/ @@ -906,7 +1086,7 @@ typedef struct _tagOrientationInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFRotation keyValue; /*exposedField*/ SFRotation value_changed; /*eventOut*/ @@ -983,7 +1163,7 @@ typedef struct _tagPositionInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec3f keyValue; /*exposedField*/ SFVec3f value_changed; /*eventOut*/ @@ -994,7 +1174,7 @@ typedef struct _tagPositionInterpolator2D { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec2f keyValue; /*exposedField*/ SFVec2f value_changed; /*eventOut*/ @@ -1086,7 +1266,7 @@ typedef struct _tagScalarInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFFloat keyValue; /*exposedField*/ SFFloat value_changed; /*eventOut*/ @@ -1183,7 +1363,7 @@ typedef struct _tagTermCap { BASE_NODE SFTime evaluate; /*eventIn*/ - void (*on_evaluate)(GF_Node *pThis); /*eventInHandler*/ + void (*on_evaluate)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFInt32 capability; /*exposedField*/ SFInt32 value; /*eventOut*/ } M_TermCap; @@ -1272,37 +1452,37 @@ typedef struct _tagValuator { BASE_NODE SFBool inSFBool; /*eventIn*/ - void (*on_inSFBool)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inSFBool)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFColor inSFColor; /*eventIn*/ - void (*on_inSFColor)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inSFColor)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFColor inMFColor; /*eventIn*/ - void (*on_inMFColor)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inMFColor)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFFloat inSFFloat; /*eventIn*/ - void (*on_inSFFloat)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inSFFloat)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat inMFFloat; /*eventIn*/ - void (*on_inMFFloat)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inMFFloat)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFInt32 inSFInt32; /*eventIn*/ - void (*on_inSFInt32)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inSFInt32)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 inMFInt32; /*eventIn*/ - void (*on_inMFInt32)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inMFInt32)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFRotation inSFRotation; /*eventIn*/ - void (*on_inSFRotation)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inSFRotation)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFRotation inMFRotation; /*eventIn*/ - void (*on_inMFRotation)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inMFRotation)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFString inSFString; /*eventIn*/ - void (*on_inSFString)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inSFString)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFString inMFString; /*eventIn*/ - void (*on_inMFString)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inMFString)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFTime inSFTime; /*eventIn*/ - void (*on_inSFTime)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inSFTime)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFVec2f inSFVec2f; /*eventIn*/ - void (*on_inSFVec2f)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inSFVec2f)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFVec2f inMFVec2f; /*eventIn*/ - void (*on_inMFVec2f)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inMFVec2f)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFVec3f inSFVec3f; /*eventIn*/ - void (*on_inSFVec3f)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inSFVec3f)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFVec3f inMFVec3f; /*eventIn*/ - void (*on_inMFVec3f)(GF_Node *pThis); /*eventInHandler*/ + void (*on_inMFVec3f)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool outSFBool; /*eventOut*/ SFColor outSFColor; /*eventOut*/ MFColor outMFColor; /*eventOut*/ @@ -1335,7 +1515,7 @@ typedef struct _tagViewpoint { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFFloat fieldOfView; /*exposedField*/ SFBool jump; /*exposedField*/ SFRotation orientation; /*exposedField*/ @@ -1358,6 +1538,16 @@ typedef struct _tagVisibilitySensor } M_VisibilitySensor; +typedef struct _tagViseme +{ + BASE_NODE + SFInt32 viseme_select1; /*exposedField*/ + SFInt32 viseme_select2; /*exposedField*/ + SFInt32 viseme_blend; /*exposedField*/ + SFBool viseme_def; /*exposedField*/ +} M_Viseme; + + typedef struct _tagWorldInfo { BASE_NODE @@ -1407,6 +1597,347 @@ typedef struct _tagApplicationWindow } M_ApplicationWindow; +typedef struct _tagBAP +{ + BASE_NODE + SFInt32 sacroiliac_tilt; /*exposedField*/ + SFInt32 sacroiliac_torsion; /*exposedField*/ + SFInt32 sacroiliac_roll; /*exposedField*/ + SFInt32 l_hip_flexion; /*exposedField*/ + SFInt32 r_hip_flexion; /*exposedField*/ + SFInt32 l_hip_abduct; /*exposedField*/ + SFInt32 r_hip_abduct; /*exposedField*/ + SFInt32 l_hip_twisting; /*exposedField*/ + SFInt32 r_hip_twisting; /*exposedField*/ + SFInt32 l_knee_flexion; /*exposedField*/ + SFInt32 r_knee_flexion; /*exposedField*/ + SFInt32 l_knee_twisting; /*exposedField*/ + SFInt32 r_knee_twisting; /*exposedField*/ + SFInt32 l_ankle_flexion; /*exposedField*/ + SFInt32 r_ankle_flexion; /*exposedField*/ + SFInt32 l_ankle_twisting; /*exposedField*/ + SFInt32 r_ankle_twisting; /*exposedField*/ + SFInt32 l_subtalar_flexion; /*exposedField*/ + SFInt32 r_subtalar_flexion; /*exposedField*/ + SFInt32 l_midtarsal_flexion; /*exposedField*/ + SFInt32 r_midtarsal_flexion; /*exposedField*/ + SFInt32 l_metatarsal_flexion; /*exposedField*/ + SFInt32 r_metatarsal_flexion; /*exposedField*/ + SFInt32 l_sternoclavicular_abduct; /*exposedField*/ + SFInt32 r_sternoclavicular_abduct; /*exposedField*/ + SFInt32 l_sternoclavicular_rotate; /*exposedField*/ + SFInt32 r_sternoclavicular_rotate; /*exposedField*/ + SFInt32 l_acromioclavicular_abduct; /*exposedField*/ + SFInt32 r_acromioclavicular_abduct; /*exposedField*/ + SFInt32 l_acromioclavicular_rotate; /*exposedField*/ + SFInt32 r_acromioclavicular_rotate; /*exposedField*/ + SFInt32 l_shoulder_flexion; /*exposedField*/ + SFInt32 r_shoulder_flexion; /*exposedField*/ + SFInt32 l_shoulder_abduct; /*exposedField*/ + SFInt32 r_shoulder_abduct; /*exposedField*/ + SFInt32 l_shoulder_twisting; /*exposedField*/ + SFInt32 r_shoulder_twisting; /*exposedField*/ + SFInt32 l_elbow_flexion; /*exposedField*/ + SFInt32 r_elbow_flexion; /*exposedField*/ + SFInt32 l_elbow_twisting; /*exposedField*/ + SFInt32 r_elbow_twisting; /*exposedField*/ + SFInt32 l_wrist_flexion; /*exposedField*/ + SFInt32 r_wrist_flexion; /*exposedField*/ + SFInt32 l_wrist_pivot; /*exposedField*/ + SFInt32 r_wrist_pivot; /*exposedField*/ + SFInt32 l_wrist_twisting; /*exposedField*/ + SFInt32 r_wrist_twisting; /*exposedField*/ + SFInt32 skullbase_roll; /*exposedField*/ + SFInt32 skullbase_torsion; /*exposedField*/ + SFInt32 skullbase_tilt; /*exposedField*/ + SFInt32 vc1roll; /*exposedField*/ + SFInt32 vc1torsion; /*exposedField*/ + SFInt32 vc1tilt; /*exposedField*/ + SFInt32 vc2roll; /*exposedField*/ + SFInt32 vc2torsion; /*exposedField*/ + SFInt32 vc2tilt; /*exposedField*/ + SFInt32 vc3roll; /*exposedField*/ + SFInt32 vc3torsion; /*exposedField*/ + SFInt32 vc3tilt; /*exposedField*/ + SFInt32 vc4roll; /*exposedField*/ + SFInt32 vc4torsion; /*exposedField*/ + SFInt32 vc4tilt; /*exposedField*/ + SFInt32 vc5roll; /*exposedField*/ + SFInt32 vc5torsion; /*exposedField*/ + SFInt32 vc5tilt; /*exposedField*/ + SFInt32 vc6roll; /*exposedField*/ + SFInt32 vc6torsion; /*exposedField*/ + SFInt32 vc6tilt; /*exposedField*/ + SFInt32 vc7roll; /*exposedField*/ + SFInt32 vc7torsion; /*exposedField*/ + SFInt32 vc7tilt; /*exposedField*/ + SFInt32 vt1roll; /*exposedField*/ + SFInt32 vt1torsion; /*exposedField*/ + SFInt32 vt1tilt; /*exposedField*/ + SFInt32 vt2roll; /*exposedField*/ + SFInt32 vt2torsion; /*exposedField*/ + SFInt32 vt2tilt; /*exposedField*/ + SFInt32 vt3roll; /*exposedField*/ + SFInt32 vt3torsion; /*exposedField*/ + SFInt32 vt3tilt; /*exposedField*/ + SFInt32 vt4roll; /*exposedField*/ + SFInt32 vt4torsion; /*exposedField*/ + SFInt32 vt4tilt; /*exposedField*/ + SFInt32 vt5roll; /*exposedField*/ + SFInt32 vt5torsion; /*exposedField*/ + SFInt32 vt5tilt; /*exposedField*/ + SFInt32 vt6roll; /*exposedField*/ + SFInt32 vt6torsion; /*exposedField*/ + SFInt32 vt6tilt; /*exposedField*/ + SFInt32 vt7roll; /*exposedField*/ + SFInt32 vt7torsion; /*exposedField*/ + SFInt32 vt7tilt; /*exposedField*/ + SFInt32 vt8roll; /*exposedField*/ + SFInt32 vt8torsion; /*exposedField*/ + SFInt32 vt8tilt; /*exposedField*/ + SFInt32 vt9roll; /*exposedField*/ + SFInt32 vt9torsion; /*exposedField*/ + SFInt32 vt9tilt; /*exposedField*/ + SFInt32 vt10roll; /*exposedField*/ + SFInt32 vt10torsion; /*exposedField*/ + SFInt32 vt10tilt; /*exposedField*/ + SFInt32 vt11roll; /*exposedField*/ + SFInt32 vt11torsion; /*exposedField*/ + SFInt32 vt11tilt; /*exposedField*/ + SFInt32 vt12roll; /*exposedField*/ + SFInt32 vt12torsion; /*exposedField*/ + SFInt32 vt12tilt; /*exposedField*/ + SFInt32 vl1roll; /*exposedField*/ + SFInt32 vl1torsion; /*exposedField*/ + SFInt32 vl1tilt; /*exposedField*/ + SFInt32 vl2roll; /*exposedField*/ + SFInt32 vl2torsion; /*exposedField*/ + SFInt32 vl2tilt; /*exposedField*/ + SFInt32 vl3roll; /*exposedField*/ + SFInt32 vl3torsion; /*exposedField*/ + SFInt32 vl3tilt; /*exposedField*/ + SFInt32 vl4roll; /*exposedField*/ + SFInt32 vl4torsion; /*exposedField*/ + SFInt32 vl4tilt; /*exposedField*/ + SFInt32 vl5roll; /*exposedField*/ + SFInt32 vl5torsion; /*exposedField*/ + SFInt32 vl5tilt; /*exposedField*/ + SFInt32 l_pinky0_flexion; /*exposedField*/ + SFInt32 r_pinky0_flexion; /*exposedField*/ + SFInt32 l_pinky1_flexion; /*exposedField*/ + SFInt32 r_pinky1_flexion; /*exposedField*/ + SFInt32 l_pinky1_pivot; /*exposedField*/ + SFInt32 r_pinky1_pivot; /*exposedField*/ + SFInt32 l_pinky1_twisting; /*exposedField*/ + SFInt32 r_pinky1_twisting; /*exposedField*/ + SFInt32 l_pinky2_flexion; /*exposedField*/ + SFInt32 r_pinky2_flexion; /*exposedField*/ + SFInt32 l_pinky3_flexion; /*exposedField*/ + SFInt32 r_pinky3_flexion; /*exposedField*/ + SFInt32 l_ring0_flexion; /*exposedField*/ + SFInt32 r_ring0_flexion; /*exposedField*/ + SFInt32 l_ring1_flexion; /*exposedField*/ + SFInt32 r_ring1_flexion; /*exposedField*/ + SFInt32 l_ring1_pivot; /*exposedField*/ + SFInt32 r_ring1_pivot; /*exposedField*/ + SFInt32 l_ring1_twisting; /*exposedField*/ + SFInt32 r_ring1_twisting; /*exposedField*/ + SFInt32 l_ring2_flexion; /*exposedField*/ + SFInt32 r_ring2_flexion; /*exposedField*/ + SFInt32 l_ring3_flexion; /*exposedField*/ + SFInt32 r_ring3_flexion; /*exposedField*/ + SFInt32 l_middle0_flexion; /*exposedField*/ + SFInt32 r_middle0_flexion; /*exposedField*/ + SFInt32 l_middle1_flexion; /*exposedField*/ + SFInt32 r_middle1_flexion; /*exposedField*/ + SFInt32 l_middle1_pivot; /*exposedField*/ + SFInt32 r_middle1_pivot; /*exposedField*/ + SFInt32 l_middle1_twisting; /*exposedField*/ + SFInt32 r_middle1_twisting; /*exposedField*/ + SFInt32 l_middle2_flexion; /*exposedField*/ + SFInt32 r_middle2_flexion; /*exposedField*/ + SFInt32 l_middle3_flexion; /*exposedField*/ + SFInt32 r_middle3_flexion; /*exposedField*/ + SFInt32 l_index0_flexion; /*exposedField*/ + SFInt32 r_index0_flexion; /*exposedField*/ + SFInt32 l_index1_flexion; /*exposedField*/ + SFInt32 r_index1_flexion; /*exposedField*/ + SFInt32 l_index1_pivot; /*exposedField*/ + SFInt32 r_index1_pivot; /*exposedField*/ + SFInt32 l_index1_twisting; /*exposedField*/ + SFInt32 r_index1_twisting; /*exposedField*/ + SFInt32 l_index2_flexion; /*exposedField*/ + SFInt32 r_index2_flexion; /*exposedField*/ + SFInt32 l_index3_flexion; /*exposedField*/ + SFInt32 r_index3_flexion; /*exposedField*/ + SFInt32 l_thumb1_flexion; /*exposedField*/ + SFInt32 r_thumb1_flexion; /*exposedField*/ + SFInt32 l_thumb1_pivot; /*exposedField*/ + SFInt32 r_thumb1_pivot; /*exposedField*/ + SFInt32 l_thumb1_twisting; /*exposedField*/ + SFInt32 r_thumb1_twisting; /*exposedField*/ + SFInt32 l_thumb2_flexion; /*exposedField*/ + SFInt32 r_thumb2_flexion; /*exposedField*/ + SFInt32 l_thumb3_flexion; /*exposedField*/ + SFInt32 r_thumb3_flexion; /*exposedField*/ + SFInt32 HumanoidRoot_tr_vertical; /*exposedField*/ + SFInt32 HumanoidRoot_tr_lateral; /*exposedField*/ + SFInt32 HumanoidRoot_tr_frontal; /*exposedField*/ + SFInt32 HumanoidRoot_rt_body_turn; /*exposedField*/ + SFInt32 HumanoidRoot_rt_body_roll; /*exposedField*/ + SFInt32 HumanoidRoot_rt_body_tilt; /*exposedField*/ + SFInt32 extensionBap187; /*exposedField*/ + SFInt32 extensionBap188; /*exposedField*/ + SFInt32 extensionBap189; /*exposedField*/ + SFInt32 extensionBap190; /*exposedField*/ + SFInt32 extensionBap191; /*exposedField*/ + SFInt32 extensionBap192; /*exposedField*/ + SFInt32 extensionBap193; /*exposedField*/ + SFInt32 extensionBap194; /*exposedField*/ + SFInt32 extensionBap195; /*exposedField*/ + SFInt32 extensionBap196; /*exposedField*/ + SFInt32 extensionBap197; /*exposedField*/ + SFInt32 extensionBap198; /*exposedField*/ + SFInt32 extensionBap199; /*exposedField*/ + SFInt32 extensionBap200; /*exposedField*/ + SFInt32 extensionBap201; /*exposedField*/ + SFInt32 extensionBap202; /*exposedField*/ + SFInt32 extensionBap203; /*exposedField*/ + SFInt32 extensionBap204; /*exposedField*/ + SFInt32 extensionBap205; /*exposedField*/ + SFInt32 extensionBap206; /*exposedField*/ + SFInt32 extensionBap207; /*exposedField*/ + SFInt32 extensionBap208; /*exposedField*/ + SFInt32 extensionBap209; /*exposedField*/ + SFInt32 extensionBap210; /*exposedField*/ + SFInt32 extensionBap211; /*exposedField*/ + SFInt32 extensionBap212; /*exposedField*/ + SFInt32 extensionBap213; /*exposedField*/ + SFInt32 extensionBap214; /*exposedField*/ + SFInt32 extensionBap215; /*exposedField*/ + SFInt32 extensionBap216; /*exposedField*/ + SFInt32 extensionBap217; /*exposedField*/ + SFInt32 extensionBap218; /*exposedField*/ + SFInt32 extensionBap219; /*exposedField*/ + SFInt32 extensionBap220; /*exposedField*/ + SFInt32 extensionBap221; /*exposedField*/ + SFInt32 extensionBap222; /*exposedField*/ + SFInt32 extensionBap223; /*exposedField*/ + SFInt32 extensionBap224; /*exposedField*/ + SFInt32 extensionBap225; /*exposedField*/ + SFInt32 extensionBap226; /*exposedField*/ + SFInt32 extensionBap227; /*exposedField*/ + SFInt32 extensionBap228; /*exposedField*/ + SFInt32 extensionBap229; /*exposedField*/ + SFInt32 extensionBap230; /*exposedField*/ + SFInt32 extensionBap231; /*exposedField*/ + SFInt32 extensionBap232; /*exposedField*/ + SFInt32 extensionBap233; /*exposedField*/ + SFInt32 extensionBap234; /*exposedField*/ + SFInt32 extensionBap235; /*exposedField*/ + SFInt32 extensionBap236; /*exposedField*/ + SFInt32 extensionBap237; /*exposedField*/ + SFInt32 extensionBap238; /*exposedField*/ + SFInt32 extensionBap239; /*exposedField*/ + SFInt32 extensionBap240; /*exposedField*/ + SFInt32 extensionBap241; /*exposedField*/ + SFInt32 extensionBap242; /*exposedField*/ + SFInt32 extensionBap243; /*exposedField*/ + SFInt32 extensionBap244; /*exposedField*/ + SFInt32 extensionBap245; /*exposedField*/ + SFInt32 extensionBap246; /*exposedField*/ + SFInt32 extensionBap247; /*exposedField*/ + SFInt32 extensionBap248; /*exposedField*/ + SFInt32 extensionBap249; /*exposedField*/ + SFInt32 extensionBap250; /*exposedField*/ + SFInt32 extensionBap251; /*exposedField*/ + SFInt32 extensionBap252; /*exposedField*/ + SFInt32 extensionBap253; /*exposedField*/ + SFInt32 extensionBap254; /*exposedField*/ + SFInt32 extensionBap255; /*exposedField*/ + SFInt32 extensionBap256; /*exposedField*/ + SFInt32 extensionBap257; /*exposedField*/ + SFInt32 extensionBap258; /*exposedField*/ + SFInt32 extensionBap259; /*exposedField*/ + SFInt32 extensionBap260; /*exposedField*/ + SFInt32 extensionBap261; /*exposedField*/ + SFInt32 extensionBap262; /*exposedField*/ + SFInt32 extensionBap263; /*exposedField*/ + SFInt32 extensionBap264; /*exposedField*/ + SFInt32 extensionBap265; /*exposedField*/ + SFInt32 extensionBap266; /*exposedField*/ + SFInt32 extensionBap267; /*exposedField*/ + SFInt32 extensionBap268; /*exposedField*/ + SFInt32 extensionBap269; /*exposedField*/ + SFInt32 extensionBap270; /*exposedField*/ + SFInt32 extensionBap271; /*exposedField*/ + SFInt32 extensionBap272; /*exposedField*/ + SFInt32 extensionBap273; /*exposedField*/ + SFInt32 extensionBap274; /*exposedField*/ + SFInt32 extensionBap275; /*exposedField*/ + SFInt32 extensionBap276; /*exposedField*/ + SFInt32 extensionBap277; /*exposedField*/ + SFInt32 extensionBap278; /*exposedField*/ + SFInt32 extensionBap279; /*exposedField*/ + SFInt32 extensionBap280; /*exposedField*/ + SFInt32 extensionBap281; /*exposedField*/ + SFInt32 extensionBap282; /*exposedField*/ + SFInt32 extensionBap283; /*exposedField*/ + SFInt32 extensionBap284; /*exposedField*/ + SFInt32 extensionBap285; /*exposedField*/ + SFInt32 extensionBap286; /*exposedField*/ + SFInt32 extensionBap287; /*exposedField*/ + SFInt32 extensionBap288; /*exposedField*/ + SFInt32 extensionBap289; /*exposedField*/ + SFInt32 extensionBap290; /*exposedField*/ + SFInt32 extensionBap291; /*exposedField*/ + SFInt32 extensionBap292; /*exposedField*/ + SFInt32 extensionBap293; /*exposedField*/ + SFInt32 extensionBap294; /*exposedField*/ + SFInt32 extensionBap295; /*exposedField*/ + SFInt32 extensionBap296; /*exposedField*/ +} M_BAP; + + +typedef struct _tagBDP +{ + BASE_NODE + GF_ChildNodeItem *bodyDefTables; /*exposedField*/ + GF_ChildNodeItem *bodySceneGraph; /*exposedField*/ +} M_BDP; + + +typedef struct _tagBody +{ + BASE_NODE + GF_Node *bdp; /*exposedField*/ + GF_Node *bap; /*exposedField*/ + GF_ChildNodeItem *renderedBody; /*exposedField*/ +} M_Body; + + +typedef struct _tagBodyDefTable +{ + BASE_NODE + SFString bodySceneGraphNodeName; /*exposedField*/ + MFInt32 bapIDs; /*exposedField*/ + MFInt32 vertexIds; /*exposedField*/ + MFInt32 bapCombinations; /*exposedField*/ + MFVec3f displacements; /*exposedField*/ + SFInt32 numInterpolateKeys; /*exposedField*/ +} M_BodyDefTable; + + +typedef struct _tagBodySegmentConnectionHint +{ + BASE_NODE + SFString firstSegmentNodeName; /*exposedField*/ + SFString secondSegmentNodeName; /*exposedField*/ + MFInt32 firstVertexIdList; /*exposedField*/ + MFInt32 secondVertexIdList; /*exposedField*/ +} M_BodySegmentConnectionHint; + + typedef struct _tagDirectiveSound { BASE_NODE @@ -1430,7 +1961,7 @@ typedef struct _tagHierarchical3DMesh { BASE_NODE SFInt32 triangleBudget; /*eventIn*/ - void (*on_triangleBudget)(GF_Node *pThis); /*eventInHandler*/ + void (*on_triangleBudget)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFFloat level; /*exposedField*/ MFURL url; /*field*/ SFBool doneLoading; /*eventOut*/ @@ -1508,7 +2039,7 @@ typedef struct _tagServerCommand { BASE_NODE SFBool trigger; /*eventIn*/ - void (*on_trigger)(GF_Node *pThis); /*eventInHandler*/ + void (*on_trigger)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool enable; /*exposedField*/ MFURL url; /*exposedField*/ SFString command; /*exposedField*/ @@ -1577,17 +2108,158 @@ typedef struct _tagMediaSensor } M_MediaSensor; +typedef struct _tagBitWrapper +{ + BASE_NODE + GF_Node *node; /*field*/ + SFInt32 type; /*field*/ + MFURL url; /*field*/ + SFString buffer; /*field*/ +} M_BitWrapper; + + typedef struct _tagCoordinateInterpolator4D { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec4f keyValue; /*exposedField*/ MFVec4f value_changed; /*eventOut*/ } M_CoordinateInterpolator4D; +typedef struct _tagDepthImage +{ + BASE_NODE + GF_Node *diTexture; /*field*/ + SFFloat farPlane; /*field*/ + SFVec2f fieldOfView; /*field*/ + SFFloat nearPlane; /*field*/ + SFRotation orientation; /*field*/ + SFBool orthographic; /*field*/ + SFVec3f position; /*field*/ +} M_DepthImage; + + +typedef struct _tagFFD +{ + BASE_NODE + VRML_CHILDREN + MFVec4f controlPoint; /*exposedField*/ + SFInt32 uDimension; /*field*/ + MFFloat uKnot; /*field*/ + SFInt32 uOrder; /*field*/ + SFInt32 vDimension; /*field*/ + MFFloat vKnot; /*field*/ + SFInt32 vOrder; /*field*/ + SFInt32 wDimension; /*field*/ + MFFloat wKnot; /*field*/ + SFInt32 wOrder; /*field*/ +} M_FFD; + + +typedef struct _tagImplicit +{ + BASE_NODE + SFVec3f bboxSize; /*exposedField*/ + MFFloat c; /*exposedField*/ + MFInt32 densities; /*exposedField*/ + SFBool dual; /*exposedField*/ + SFBool solid; /*exposedField*/ +} M_Implicit; + + +typedef struct _tagXXLFM_Appearance +{ + BASE_NODE + GF_Node *blendList; /*exposedField*/ + GF_ChildNodeItem *lightMapList; /*exposedField*/ + GF_ChildNodeItem *tileList; /*exposedField*/ + GF_Node *vertexFrameList; /*exposedField*/ +} M_XXLFM_Appearance; + + +typedef struct _tagXXLFM_BlendList +{ + BASE_NODE + MFInt32 blendMode; /*exposedField*/ + MFInt32 lightMapIndex; /*exposedField*/ +} M_XXLFM_BlendList; + + +typedef struct _tagXXLFM_FrameList +{ + BASE_NODE + MFInt32 index; /*exposedField*/ + MFVec3f frame; /*exposedField*/ +} M_XXLFM_FrameList; + + +typedef struct _tagXXLFM_LightMap +{ + BASE_NODE + SFVec3f biasRGB; /*exposedField*/ + SFInt32 priorityLevel; /*exposedField*/ + SFVec3f scaleRGB; /*exposedField*/ + GF_Node *surfaceMapList; /*exposedField*/ + GF_Node *viewMapList; /*exposedField*/ +} M_XXLFM_LightMap; + + +typedef struct _tagXXLFM_SurfaceMapList +{ + BASE_NODE + MFInt32 tileIndex; /*exposedField*/ + GF_Node *triangleCoordinate; /*exposedField*/ + MFInt32 triangleIndex; /*exposedField*/ + MFInt32 viewMapIndex; /*exposedField*/ +} M_XXLFM_SurfaceMapList; + + +typedef struct _tagXXLFM_ViewMapList +{ + BASE_NODE + GF_Node *textureOrigin; /*exposedField*/ + GF_Node *textureSize; /*exposedField*/ + MFInt32 tileIndex; /*exposedField*/ + MFInt32 vertexIndex; /*exposedField*/ +} M_XXLFM_ViewMapList; + + +typedef struct _tagMeshGrid +{ + BASE_NODE + MFInt32 set_colorIndex; /*eventIn*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_coordIndex; /*eventIn*/ + void (*on_set_coordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_normalIndex; /*eventIn*/ + void (*on_set_normalIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_texCoordIndex; /*eventIn*/ + void (*on_set_texCoordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *color; /*exposedField*/ + GF_Node *coord; /*exposedField*/ + SFInt32 displayLevel; /*exposedField*/ + SFInt32 filterType; /*exposedField*/ + GF_Node *gridCoord; /*exposedField*/ + SFInt32 hierarchicalLevel; /*exposedField*/ + MFInt32 nLevels; /*exposedField*/ + GF_Node *normal; /*exposedField*/ + MFInt32 nSlices; /*exposedField*/ + GF_Node *texCoord; /*exposedField*/ + MFFloat vertexOffset; /*exposedField*/ + MFInt32 vertexLink; /*exposedField*/ + MFInt32 colorIndex; /*field*/ + MFInt32 coordIndex; /*field*/ + MFInt32 normalIndex; /*field*/ + SFBool solid; /*field*/ + MFInt32 texCoordIndex; /*field*/ + SFBool isLoading; /*eventOut*/ + MFInt32 nVertices; /*eventOut*/ +} M_MeshGrid; + + typedef struct _tagNonLinearDeformer { BASE_NODE @@ -1599,11 +2271,147 @@ typedef struct _tagNonLinearDeformer } M_NonLinearDeformer; +typedef struct _tagNurbsCurve +{ + BASE_NODE + MFInt32 set_colorIndex; /*eventIn*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *color; /*exposedField*/ + MFVec4f controlPoint; /*exposedField*/ + SFInt32 tessellation; /*exposedField*/ + MFInt32 colorIndex; /*field*/ + SFBool colorPerVertex; /*field*/ + MFFloat knot; /*field*/ + SFInt32 order; /*field*/ +} M_NurbsCurve; + + +typedef struct _tagNurbsCurve2D +{ + BASE_NODE + MFInt32 set_colorIndex; /*eventIn*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *color; /*exposedField*/ + MFVec3f controlPoint; /*exposedField*/ + SFInt32 tessellation; /*exposedField*/ + MFInt32 colorIndex; /*field*/ + SFBool colorPerVertex; /*field*/ + MFFloat knot; /*field*/ + SFInt32 order; /*field*/ +} M_NurbsCurve2D; + + +typedef struct _tagNurbsSurface +{ + BASE_NODE + MFInt32 set_colorIndex; /*eventIn*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_texColorIndex; /*eventIn*/ + void (*on_set_texColorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *color; /*exposedField*/ + MFVec4f controlPoint; /*exposedField*/ + GF_Node *texCoord; /*exposedField*/ + SFInt32 uTessellation; /*exposedField*/ + SFInt32 vTessellation; /*exposedField*/ + SFBool ccw; /*field*/ + MFInt32 colorIndex; /*field*/ + SFBool colorPerVertex; /*field*/ + SFBool solid; /*field*/ + MFInt32 texColorIndex; /*field*/ + SFInt32 uDimension; /*field*/ + MFFloat uKnot; /*field*/ + SFInt32 uOrder; /*field*/ + SFInt32 vDimension; /*field*/ + MFFloat vKnot; /*field*/ + SFInt32 vOrder; /*field*/ +} M_NurbsSurface; + + +typedef struct _tagOctreeImage +{ + BASE_NODE + GF_ChildNodeItem *images; /*field*/ + MFInt32 octree; /*field*/ + SFInt32 octreeResolution; /*field*/ + MFInt32 voxelImageIndex; /*field*/ +} M_OctreeImage; + + +typedef struct _tagXXParticles +{ + BASE_NODE + SFFloat creationRate; /*exposedField*/ + SFFloat creationRateVariation; /*exposedField*/ + SFFloat emitAlpha; /*exposedField*/ + SFColor emitColor; /*exposedField*/ + SFColor emitColorVariation; /*exposedField*/ + SFVec3f emitterPosition; /*exposedField*/ + SFVec3f emitVelocity; /*exposedField*/ + SFVec3f emitVelocityVariation; /*exposedField*/ + SFBool enabled; /*exposedField*/ + SFFloat fadeAlpha; /*exposedField*/ + SFColor fadeColor; /*exposedField*/ + SFFloat fadeRate; /*exposedField*/ + SFVec3f force; /*exposedField*/ + GF_ChildNodeItem *influences; /*exposedField*/ + GF_Node *init; /*exposedField*/ + SFTime maxLifeTime; /*exposedField*/ + SFFloat maxLifeTimeVariation; /*exposedField*/ + SFInt32 maxParticles; /*exposedField*/ + SFFloat minRange; /*exposedField*/ + SFFloat maxRange; /*exposedField*/ + GF_Node *primitive; /*exposedField*/ + SFInt32 primitiveType; /*exposedField*/ + SFFloat particleRadius; /*exposedField*/ + SFFloat particleRadiusRate; /*exposedField*/ + SFFloat particleRadiusVariation; /*exposedField*/ +} M_XXParticles; + + +typedef struct _tagXXParticleInitBox +{ + BASE_NODE + SFFloat falloff; /*exposedField*/ + SFVec3f size; /*exposedField*/ +} M_XXParticleInitBox; + + +typedef struct _tagXXPlanarObstacle +{ + BASE_NODE + SFVec3f distance; /*exposedField*/ + SFVec3f normal; /*exposedField*/ + SFFloat reflection; /*exposedField*/ + SFFloat absorption; /*exposedField*/ +} M_XXPlanarObstacle; + + +typedef struct _tagXXPointAttractor +{ + BASE_NODE + SFFloat innerRadius; /*exposedField*/ + SFFloat outerRadius; /*exposedField*/ + SFVec3f position; /*exposedField*/ + SFFloat rate; /*exposedField*/ +} M_XXPointAttractor; + + +typedef struct _tagPointTexture +{ + BASE_NODE + MFColor color; /*field*/ + MFInt32 depth; /*field*/ + SFInt32 depthNbBits; /*field*/ + SFInt32 height; /*field*/ + SFInt32 width; /*field*/ +} M_PointTexture; + + typedef struct _tagPositionAnimator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFVec2f fromTo; /*exposedField*/ MFFloat key; /*exposedField*/ MFRotation keyOrientation; /*exposedField*/ @@ -1623,7 +2431,7 @@ typedef struct _tagPositionAnimator2D { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFVec2f fromTo; /*exposedField*/ MFFloat key; /*exposedField*/ SFInt32 keyOrientation; /*exposedField*/ @@ -1643,18 +2451,153 @@ typedef struct _tagPositionInterpolator4D { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec4f keyValue; /*exposedField*/ SFVec4f value_changed; /*eventOut*/ } M_PositionInterpolator4D; +typedef struct _tagProceduralTexture +{ + BASE_NODE + SFBool aSmooth; /*exposedField*/ + MFVec2f aWarpmap; /*exposedField*/ + MFFloat aWeights; /*exposedField*/ + SFBool bSmooth; /*exposedField*/ + MFVec2f bWarpmap; /*exposedField*/ + MFFloat bWeights; /*exposedField*/ + SFInt32 cellWidth; /*exposedField*/ + SFInt32 cellHeight; /*exposedField*/ + MFColor color; /*exposedField*/ + SFFloat distortion; /*exposedField*/ + SFInt32 height; /*exposedField*/ + SFInt32 roughness; /*exposedField*/ + SFInt32 seed; /*exposedField*/ + SFInt32 type; /*exposedField*/ + SFBool xSmooth; /*exposedField*/ + MFVec2f xWarpmap; /*exposedField*/ + SFBool ySmooth; /*exposedField*/ + MFVec2f yWarpmap; /*exposedField*/ + SFInt32 width; /*exposedField*/ + SFImage image_changed; /*eventOut*/ +} M_ProceduralTexture; + + +typedef struct _tagQuadric +{ + BASE_NODE + SFVec3f bboxSize; /*exposedField*/ + MFInt32 densities; /*exposedField*/ + SFBool dual; /*exposedField*/ + SFVec4f P0; /*exposedField*/ + SFVec4f P1; /*exposedField*/ + SFVec4f P2; /*exposedField*/ + SFVec4f P3; /*exposedField*/ + SFVec4f P4; /*exposedField*/ + SFVec4f P5; /*exposedField*/ + SFBool solid; /*exposedField*/ +} M_Quadric; + + +typedef struct _tagSBBone +{ + BASE_NODE + VRML_CHILDREN + SFInt32 boneID; /*exposedField*/ + SFVec3f center; /*exposedField*/ + SFVec3f endpoint; /*exposedField*/ + SFInt32 falloff; /*exposedField*/ + SFInt32 ikChainPosition; /*exposedField*/ + MFFloat ikPitchLimit; /*exposedField*/ + MFFloat ikRollLimit; /*exposedField*/ + MFFloat ikTxLimit; /*exposedField*/ + MFFloat ikTyLimit; /*exposedField*/ + MFFloat ikTzLimit; /*exposedField*/ + MFFloat ikYawLimit; /*exposedField*/ + SFRotation rotation; /*exposedField*/ + SFInt32 rotationOrder; /*exposedField*/ + SFVec3f scale; /*exposedField*/ + SFRotation scaleOrientation; /*exposedField*/ + MFFloat sectionInner; /*exposedField*/ + MFFloat sectionOuter; /*exposedField*/ + MFFloat sectionPosition; /*exposedField*/ + MFInt32 skinCoordIndex; /*exposedField*/ + MFFloat skinCoordWeight; /*exposedField*/ + SFVec3f translation; /*exposedField*/ +} M_SBBone; + + +typedef struct _tagSBMuscle +{ + BASE_NODE + SFInt32 falloff; /*exposedField*/ + GF_Node *muscleCurve; /*exposedField*/ + SFInt32 muscleID; /*exposedField*/ + SFInt32 radius; /*exposedField*/ + MFInt32 skinCoordIndex; /*exposedField*/ + MFFloat skinCoordWeight; /*exposedField*/ +} M_SBMuscle; + + +typedef struct _tagSBSegment +{ + BASE_NODE + VRML_CHILDREN + SFVec3f centerOfMass; /*exposedField*/ + SFFloat mass; /*exposedField*/ + MFVec3f momentsOfInertia; /*exposedField*/ + SFString name; /*exposedField*/ +} M_SBSegment; + + +typedef struct _tagSBSite +{ + BASE_NODE + VRML_CHILDREN + SFVec3f center; /*exposedField*/ + SFString name; /*exposedField*/ + SFRotation rotation; /*exposedField*/ + SFVec3f scale; /*exposedField*/ + SFRotation scaleOrientation; /*exposedField*/ + SFVec3f translation; /*exposedField*/ +} M_SBSite; + + +typedef struct _tagSBSkinnedModel +{ + BASE_NODE + GF_ChildNodeItem *bones; /*exposedField*/ + SFVec3f center; /*exposedField*/ + GF_ChildNodeItem *muscles; /*exposedField*/ + SFString name; /*exposedField*/ + SFRotation rotation; /*exposedField*/ + GF_ChildNodeItem *segments; /*exposedField*/ + SFVec3f scale; /*exposedField*/ + SFRotation scaleOrientation; /*exposedField*/ + GF_ChildNodeItem *sites; /*exposedField*/ + GF_ChildNodeItem *skeleton; /*exposedField*/ + GF_ChildNodeItem *skin; /*exposedField*/ + GF_Node *skinCoord; /*exposedField*/ + GF_Node *skinNormal; /*exposedField*/ + SFVec3f translation; /*exposedField*/ + GF_Node *weighsComputationSkinCoord; /*exposedField*/ +} M_SBSkinnedModel; + + +typedef struct _tagSBVCAnimation +{ + BASE_NODE + MFURL url; /*exposedField*/ + GF_ChildNodeItem *virtualCharacters; /*exposedField*/ +} M_SBVCAnimation; + + typedef struct _tagScalarAnimator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFVec2f fromTo; /*exposedField*/ MFFloat key; /*exposedField*/ SFInt32 keyType; /*exposedField*/ @@ -1668,6 +2611,85 @@ typedef struct _tagScalarAnimator } M_ScalarAnimator; +typedef struct _tagSimpleTexture +{ + BASE_NODE + GF_Node *depth; /*field*/ + GF_Node *texture; /*field*/ +} M_SimpleTexture; + + +typedef struct _tagSolidRep +{ + BASE_NODE + SFVec3f bboxSize; /*exposedField*/ + MFInt32 densityList; /*exposedField*/ + GF_Node *solidTree; /*exposedField*/ +} M_SolidRep; + + +typedef struct _tagSubdivisionSurface +{ + BASE_NODE + MFInt32 set_colorIndex; /*eventIn*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_coordIndex; /*eventIn*/ + void (*on_set_coordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_cornerVertexIndex; /*eventIn*/ + void (*on_set_cornerVertexIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_creaseEdgeIndex; /*eventIn*/ + void (*on_set_creaseEdgeIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_creaseVertexIndex; /*eventIn*/ + void (*on_set_creaseVertexIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_dartVertexIndex; /*eventIn*/ + void (*on_set_dartVertexIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFInt32 set_texCoordIndex; /*eventIn*/ + void (*on_set_texCoordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *color; /*exposedField*/ + GF_Node *coord; /*exposedField*/ + GF_Node *texCoord; /*exposedField*/ + GF_ChildNodeItem *sectors; /*exposedField*/ + SFInt32 subdivisionLevel; /*exposedField*/ + SFInt32 subdivisionType; /*exposedField*/ + SFInt32 subdivisionSubType; /*exposedField*/ + MFInt32 invisibleEdgeIndex; /*field*/ + SFBool ccw; /*field*/ + MFInt32 colorIndex; /*field*/ + SFBool colorPerVertex; /*field*/ + SFBool convex; /*field*/ + MFInt32 coordIndex; /*field*/ + MFInt32 cornerVertexIndex; /*field*/ + MFInt32 creaseEdgeIndex; /*field*/ + MFInt32 creaseVertexIndex; /*field*/ + MFInt32 dartVertexIndex; /*field*/ + SFBool solid; /*field*/ + MFInt32 texCoordIndex; /*field*/ +} M_SubdivisionSurface; + + +typedef struct _tagSubdivSurfaceSector +{ + BASE_NODE + SFFloat flatness; /*exposedField*/ + SFVec3f normal; /*exposedField*/ + SFFloat normalTension; /*exposedField*/ + SFInt32 _tag; /*exposedField*/ + SFFloat theta; /*exposedField*/ + SFInt32 faceIndex; /*field*/ + SFInt32 vertexIndex; /*field*/ +} M_SubdivSurfaceSector; + + +typedef struct _tagWaveletSubdivisionSurface +{ + BASE_NODE + GF_Node *baseMesh; /*exposedField*/ + SFFloat fieldOfView; /*exposedField*/ + SFFloat frequency; /*exposedField*/ + SFInt32 quality; /*exposedField*/ +} M_WaveletSubdivisionSurface; + + typedef struct _tagClipper2D { BASE_NODE @@ -1754,6 +2776,23 @@ typedef struct _tagRadialGradient } M_RadialGradient; +typedef struct _tagSynthesizedTexture +{ + BASE_NODE + MFVec3f translation; /*exposedField*/ + MFRotation rotation; /*exposedField*/ + SFInt32 pixelWidth; /*exposedField*/ + SFInt32 pixelHeight; /*exposedField*/ + SFBool loop; /*exposedField*/ + SFFloat speed; /*exposedField*/ + SFTime startTime; /*exposedField*/ + SFTime stopTime; /*exposedField*/ + MFURL url; /*exposedField*/ + SFTime duration_changed; /*eventOut*/ + SFBool isActive; /*eventOut*/ +} M_SynthesizedTexture; + + typedef struct _tagTransformMatrix2D { BASE_NODE @@ -1771,7 +2810,7 @@ typedef struct _tagViewport { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFVec2f position; /*exposedField*/ SFVec2f size; /*exposedField*/ SFFloat orientation; /*exposedField*/ @@ -1834,6 +2873,376 @@ typedef struct _tagXLineProperties } M_XLineProperties; +typedef struct _tagAdvancedAudioBuffer +{ + BASE_NODE + VRML_CHILDREN + SFBool loop; /*exposedField*/ + SFFloat pitch; /*exposedField*/ + SFTime startTime; /*exposedField*/ + SFTime stopTime; /*exposedField*/ + SFTime startLoadTime; /*exposedField*/ + SFTime stopLoadTime; /*exposedField*/ + SFInt32 loadMode; /*exposedField*/ + SFInt32 numAccumulatedBlocks; /*exposedField*/ + SFInt32 deleteBlock; /*exposedField*/ + SFInt32 playBlock; /*exposedField*/ + SFFloat length; /*exposedField*/ + SFInt32 numChan; /*field*/ + MFInt32 phaseGroup; /*field*/ + SFTime duration_changed; /*eventOut*/ + SFBool isActive; /*eventOut*/ +} M_AdvancedAudioBuffer; + + +typedef struct _tagAudioChannelConfig +{ + BASE_NODE + VRML_CHILDREN + SFInt32 generalChannelFormat; /*exposedField*/ + SFInt32 fixedPreset; /*exposedField*/ + SFInt32 fixedPresetSubset; /*exposedField*/ + SFInt32 fixedPresetAddInf; /*exposedField*/ + MFInt32 channelCoordinateSystems; /*exposedField*/ + MFFloat channelSoundLocation; /*exposedField*/ + MFInt32 channelDirectionalPattern; /*exposedField*/ + MFVec3f channelDirection; /*exposedField*/ + SFInt32 ambResolution2D; /*exposedField*/ + SFInt32 ambResolution3D; /*exposedField*/ + SFInt32 ambEncodingConvention; /*exposedField*/ + SFFloat ambNfcReferenceDistance; /*exposedField*/ + SFFloat ambSoundSpeed; /*exposedField*/ + SFInt32 ambArrangementRule; /*exposedField*/ + SFInt32 ambRecombinationPreset; /*exposedField*/ + MFInt32 ambComponentIndex; /*exposedField*/ + MFFloat ambBackwardMatrix; /*exposedField*/ + MFInt32 ambSoundfieldResolution; /*exposedField*/ + SFInt32 numChannel; /*field*/ +} M_AudioChannelConfig; + + +typedef struct _tagDepthImageV2 +{ + BASE_NODE + GF_Node *diTexture; /*field*/ + SFFloat farPlane; /*field*/ + SFVec2f fieldOfView; /*field*/ + SFFloat nearPlane; /*field*/ + SFRotation orientation; /*field*/ + SFBool orthographic; /*field*/ + SFVec3f position; /*field*/ + SFVec2f splatMinMax; /*field*/ +} M_DepthImageV2; + + +typedef struct _tagMorphShape +{ + BASE_NODE + GF_Node *baseShape; /*exposedField*/ + SFInt32 morphID; /*exposedField*/ + GF_ChildNodeItem *targetShapes; /*exposedField*/ + MFFloat weights; /*exposedField*/ +} M_MorphShape; + + +typedef struct _tagMultiTexture +{ + BASE_NODE + SFFloat alpha; /*exposedField*/ + SFColor color; /*exposedField*/ + MFInt32 function; /*exposedField*/ + MFInt32 mode; /*exposedField*/ + MFInt32 source; /*exposedField*/ + GF_ChildNodeItem *texture; /*exposedField*/ + MFVec3f cameraVector; /*exposedField*/ + SFBool transparent; /*exposedField*/ +} M_MultiTexture; + + +typedef struct _tagPointTextureV2 +{ + BASE_NODE + MFColor color; /*field*/ + MFInt32 depth; /*field*/ + SFInt32 depthNbBits; /*field*/ + SFInt32 height; /*field*/ + GF_Node *normal; /*field*/ + MFVec3f splatU; /*field*/ + MFVec3f splatV; /*field*/ + SFInt32 width; /*field*/ +} M_PointTextureV2; + + +typedef struct _tagSBVCAnimationV2 +{ + BASE_NODE + MFInt32 activeUrlIndex; /*exposedField*/ + SFBool loop; /*exposedField*/ + SFFloat speed; /*exposedField*/ + SFTime startTime; /*exposedField*/ + SFTime stopTime; /*exposedField*/ + SFFloat transitionTime; /*exposedField*/ + MFURL url; /*exposedField*/ + GF_ChildNodeItem *virtualCharacters; /*exposedField*/ + SFTime duration_changed; /*eventOut*/ + SFBool isActive; /*eventOut*/ +} M_SBVCAnimationV2; + + +typedef struct _tagSimpleTextureV2 +{ + BASE_NODE + GF_Node *depth; /*field*/ + GF_Node *normal; /*field*/ + GF_Node *splatU; /*field*/ + GF_Node *splatV; /*field*/ + GF_Node *texture; /*field*/ +} M_SimpleTextureV2; + + +typedef struct _tagSurroundingSound +{ + BASE_NODE + GF_Node *source; /*exposedField*/ + SFFloat intensity; /*exposedField*/ + SFFloat distance; /*exposedField*/ + SFVec3f location; /*exposedField*/ + SFFloat distortionFactor; /*exposedField*/ + SFRotation orientation; /*exposedField*/ + SFBool isTransformable; /*exposedField*/ +} M_SurroundingSound; + + +typedef struct _tagTransform3DAudio +{ + BASE_NODE + VRML_CHILDREN + SFFloat thirdCenterCoordinate; /*exposedField*/ + SFVec3f rotationVector; /*exposedField*/ + SFFloat thirdScaleCoordinate; /*exposedField*/ + SFVec3f scaleOrientationVector; /*exposedField*/ + SFFloat thirdTranslationCoordinate; /*exposedField*/ + SFRotation coordinateTransform; /*exposedField*/ +} M_Transform3DAudio; + + +typedef struct _tagWideSound +{ + BASE_NODE + GF_Node *source; /*exposedField*/ + SFFloat intensity; /*exposedField*/ + SFVec3f location; /*exposedField*/ + SFBool spatialize; /*exposedField*/ + GF_Node *perceptualParameters; /*exposedField*/ + SFBool roomEffect; /*exposedField*/ + SFInt32 shape; /*exposedField*/ + MFFloat size; /*exposedField*/ + SFVec3f direction; /*exposedField*/ + SFFloat density; /*exposedField*/ + SFInt32 diffuseSelect; /*exposedField*/ + SFFloat decorrStrength; /*exposedField*/ + SFFloat speedOfSound; /*field*/ + SFFloat distance; /*field*/ + SFBool useAirabs; /*field*/ +} M_WideSound; + + +typedef struct _tagScoreShape +{ + BASE_NODE + GF_Node *score; /*exposedField*/ + GF_Node *geometry; /*exposedField*/ +} M_ScoreShape; + + +typedef struct _tagMusicScore +{ + BASE_NODE + SFBool executeCommand; /*eventIn*/ + void (*on_executeCommand)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFString gotoLabel; /*eventIn*/ + void (*on_gotoLabel)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFInt32 gotoMeasure; /*eventIn*/ + void (*on_gotoMeasure)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFTime highlightTimePosition; /*eventIn*/ + void (*on_highlightTimePosition)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFVec3f mousePosition; /*eventIn*/ + void (*on_mousePosition)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFString argumentsOnExecute; /*exposedField*/ + SFString commandOnExecute; /*exposedField*/ + SFInt32 firstVisibleMeasure; /*exposedField*/ + SFBool hyperlinkEnable; /*exposedField*/ + SFBool loop; /*exposedField*/ + MFString partsLyrics; /*exposedField*/ + MFInt32 partsShown; /*exposedField*/ + SFTime scoreOffset; /*exposedField*/ + SFVec2f size; /*exposedField*/ + SFFloat speed; /*exposedField*/ + SFTime startTime; /*exposedField*/ + SFTime stopTime; /*exposedField*/ + SFFloat transpose; /*exposedField*/ + MFURL url; /*exposedField*/ + MFURL urlSA; /*exposedField*/ + SFString viewType; /*exposedField*/ + SFString activatedLink; /*eventOut*/ + MFString availableCommands; /*eventOut*/ + MFString availableLabels; /*eventOut*/ + MFString availableLyricLanguages; /*eventOut*/ + MFString availableViewTypes; /*eventOut*/ + SFBool isActive; /*eventOut*/ + SFVec3f highlightPosition; /*eventOut*/ + SFInt32 lastVisibleMeasure; /*eventOut*/ + SFInt32 numMeasures; /*eventOut*/ + MFString partNames; /*eventOut*/ +} M_MusicScore; + + +typedef struct _tagFootPrintSetNode +{ + BASE_NODE + VRML_CHILDREN +} M_FootPrintSetNode; + + +typedef struct _tagFootPrintNode +{ + BASE_NODE + SFInt32 index; /*exposedField*/ + GF_Node *footprint; /*exposedField*/ +} M_FootPrintNode; + + +typedef struct _tagBuildingPartNode +{ + BASE_NODE + SFInt32 index; /*exposedField*/ + GF_Node *footprint; /*exposedField*/ + SFInt32 buildingIndex; /*exposedField*/ + SFFloat height; /*exposedField*/ + SFFloat altitude; /*exposedField*/ + GF_ChildNodeItem *alternativeGeometry; /*exposedField*/ + GF_ChildNodeItem *roofs; /*exposedField*/ + GF_ChildNodeItem *facades; /*exposedField*/ +} M_BuildingPartNode; + + +typedef struct _tagRoofNode +{ + BASE_NODE + SFInt32 Type; /*exposedField*/ + SFFloat Height; /*exposedField*/ + MFFloat SlopeAngle; /*exposedField*/ + SFFloat EaveProjection; /*exposedField*/ + SFInt32 EdgeSupportIndex; /*exposedField*/ + SFURL RoofTextureURL; /*exposedField*/ + SFBool IsGenericTexture; /*exposedField*/ + SFFloat TextureXScale; /*exposedField*/ + SFFloat TextureYScale; /*exposedField*/ + SFFloat TextureXPosition; /*exposedField*/ + SFFloat TextureYPosition; /*exposedField*/ + SFFloat TextureRotation; /*exposedField*/ +} M_RoofNode; + + +typedef struct _tagFacadeNode +{ + BASE_NODE + SFFloat WidthRatio; /*exposedField*/ + SFFloat XScale; /*exposedField*/ + SFFloat YScale; /*exposedField*/ + SFFloat XPosition; /*exposedField*/ + SFFloat YPosition; /*exposedField*/ + SFFloat XRepeatInterval; /*exposedField*/ + SFFloat YRepeatInterval; /*exposedField*/ + SFBool Repeat; /*exposedField*/ + SFURL FacadePrimitive; /*exposedField*/ + SFInt32 NbStories; /*exposedField*/ + MFInt32 NbFacadeCellsByStorey; /*exposedField*/ + MFFloat StoreyHeight; /*exposedField*/ + GF_ChildNodeItem *FacadeCellsArray; /*exposedField*/ +} M_FacadeNode; + + +typedef struct _tagShadow +{ + BASE_NODE + VRML_CHILDREN + SFBool enabled; /*exposedField*/ + SFBool cast; /*exposedField*/ + SFBool receive; /*exposedField*/ + SFFloat penumbra; /*exposedField*/ +} M_Shadow; + + +typedef struct _tagCacheTexture +{ + BASE_NODE + SFInt32 objectTypeIndication; /*field*/ + SFString decoderSpecificInfo; /*field*/ + SFString image; /*field*/ + SFString cacheURL; /*field*/ + MFURL cacheOD; /*field*/ + SFInt32 expirationDate; /*field*/ + SFBool repeatS; /*field*/ + SFBool repeatT; /*field*/ +} M_CacheTexture; + + +typedef struct _tagEnvironmentTest +{ + BASE_NODE + SFBool evaluate; /*eventIn*/ + void (*on_evaluate)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFBool enabled; /*exposedField*/ + SFInt32 parameter; /*exposedField*/ + SFString compareValue; /*exposedField*/ + SFBool evaluateOnChange; /*exposedField*/ + SFBool valueLarger; /*eventOut*/ + SFBool valueEqual; /*eventOut*/ + SFBool valueSmaller; /*eventOut*/ + SFString parameterValue; /*eventOut*/ +} M_EnvironmentTest; + + +typedef struct _tagKeyNavigator +{ + BASE_NODE + SFBool setFocus; /*eventIn*/ + void (*on_setFocus)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *sensor; /*exposedField*/ + GF_Node *left; /*exposedField*/ + GF_Node *right; /*exposedField*/ + GF_Node *up; /*exposedField*/ + GF_Node *down; /*exposedField*/ + GF_Node *select; /*exposedField*/ + GF_Node *quit; /*exposedField*/ + SFFloat step; /*exposedField*/ + SFBool focusSet; /*eventOut*/ +} M_KeyNavigator; + + +typedef struct _tagSpacePartition +{ + BASE_NODE + VRML_CHILDREN + SFURL SPStream; /*exposedField*/ +} M_SpacePartition; + + +typedef struct _tagStorage +{ + BASE_NODE + SFBool forceSave; /*eventIn*/ + void (*on_forceSave)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFBool forceRestore; /*eventIn*/ + void (*on_forceRestore)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFBool _auto; /*exposedField*/ + SFInt32 expireAfter; /*field*/ + SFString name; /*field*/ + MFAttrRef storageList; /*field*/ +} M_Storage; + + /*NodeDataType tags*/ enum { NDT_SFWorldNode = 1, @@ -1888,11 +3297,12 @@ enum { NDT_SFSBSegmentNode, NDT_SFSBSiteNode, NDT_SFBaseMeshNode, - NDT_SFSubdivSurfaceSectorNode + NDT_SFSubdivSurfaceSectorNode, + NDT_SFMusicScoreNode }; /*All BIFS versions handled*/ -#define GF_BIFS_NUM_VERSION 6 +#define GF_BIFS_NUM_VERSION 10 enum { GF_BIFS_V1 = 1, @@ -1901,11 +3311,17 @@ enum { GF_BIFS_V4, GF_BIFS_V5, GF_BIFS_V6, - GF_BIFS_LAST_VERSION = GF_BIFS_V6 + GF_BIFS_V7, + GF_BIFS_V8, + GF_BIFS_V9, + GF_BIFS_V10, + GF_BIFS_LAST_VERSION = GF_BIFS_V10 }; +#endif /*GPAC_DISABLE_VRML*/ + #ifdef __cplusplus } #endif diff --git a/include/gpac/nodes_svg.h b/include/gpac/nodes_svg.h index 4c146f0..e51785a 100644 --- a/include/gpac/nodes_svg.h +++ b/include/gpac/nodes_svg.h @@ -80,6 +80,30 @@ enum { TAG_SVG_use, TAG_SVG_video, + TAG_SVG_filter, + TAG_SVG_feDistantLight, + TAG_SVG_fePointLight, + TAG_SVG_feSpotLight, + TAG_SVG_feBlend, + TAG_SVG_feColorMatrix, + TAG_SVG_feComponentTransfer, + TAG_SVG_feFuncR, + TAG_SVG_feFuncG, + TAG_SVG_feFuncB, + TAG_SVG_feFuncA, + TAG_SVG_feComposite, + TAG_SVG_feConvolveMatrix, + TAG_SVG_feDiffuseLighting, + TAG_SVG_feDisplacementMap, + TAG_SVG_feFlood, + TAG_SVG_feGaussianBlur, + TAG_SVG_feImage, + TAG_SVG_feMerge, + TAG_SVG_feMorphology, + TAG_SVG_feOffset, + TAG_SVG_feSpecularLighting, + TAG_SVG_feTile, + TAG_SVG_feTurbulence, TAG_LSR_conditional, TAG_LSR_cursorManager, @@ -91,7 +115,7 @@ enum { TAG_SVG_UndefinedElement }; -/* Definition of SVG 3 attribute internal tags - 200 defined */ +/* Definition of SVG attribute internal tags - 200 defined */ /* TAG names are made of "TAG_SVG_ATT_" + SVG attribute name (with - replaced by _) */ enum { TAG_SVG_ATT_id = TAG_SVG_ATT_RANGE_FIRST, @@ -116,6 +140,7 @@ enum { TAG_SVG_ATT_stroke_opacity, TAG_SVG_ATT_fill, TAG_SVG_ATT_fill_rule, + TAG_SVG_ATT_filter, TAG_SVG_ATT_stroke, TAG_SVG_ATT_stroke_dasharray, TAG_SVG_ATT_stroke_dashoffset, @@ -241,6 +266,7 @@ enum { TAG_SVG_ATT_y1, TAG_SVG_ATT_x2, TAG_SVG_ATT_y2, + TAG_SVG_ATT_filterUnits, TAG_SVG_ATT_gradientUnits, TAG_SVG_ATT_spreadMethod, TAG_SVG_ATT_gradientTransform, @@ -275,8 +301,16 @@ enum { TAG_SVG_ATT_overlay, TAG_SVG_ATT_fullscreen, TAG_SVG_ATT_motionTransform, + + TAG_SVG_ATT_filter_transfer_type, + TAG_SVG_ATT_filter_table_values, + TAG_SVG_ATT_filter_intercept, + TAG_SVG_ATT_filter_amplitude, + TAG_SVG_ATT_filter_exponent + }; + struct _all_atts { XML_Space *xml_space; XMLRI *xml_base; @@ -320,6 +354,7 @@ struct _all_atts { SVG_Number *stroke_opacity; SVG_Paint *fill; SVG_FillRule *fill_rule; + SVG_Paint *filter; SVG_Paint *stroke; SVG_StrokeDashArray *stroke_dasharray; SVG_Length *stroke_dashoffset; @@ -447,6 +482,7 @@ struct _all_atts { SVG_Coordinate *x2; SVG_Coordinate *y2; SVG_GradientUnit *gradientUnits; + SVG_GradientUnit *filterUnits; SVG_SpreadMethod *spreadMethod; SVG_Transform *gradientTransform; SVG_Number *pathLength; @@ -480,6 +516,10 @@ struct _all_atts { SVG_Overlay *overlay; SVG_Boolean *fullscreen; SVG_Motion *motionTransform; + + SVG_Boolean *gpac_useAsPrimary; + SVG_Number *gpac_depthOffset; + SVG_Number *gpac_depthGain; }; #ifdef __cplusplus } diff --git a/include/gpac/nodes_x3d.h b/include/gpac/nodes_x3d.h index 22f6ba6..e81579c 100644 --- a/include/gpac/nodes_x3d.h +++ b/include/gpac/nodes_x3d.h @@ -24,9 +24,9 @@ /* - DO NOT MOFIFY - File generated on GMT Thu Aug 07 11:44:22 2008 + DO NOT MOFIFY - File generated on GMT Fri Jul 31 16:39:50 2009 - BY X3DGen for GPAC Version 0.4.5-DEV + BY X3DGen for GPAC Version 0.4.6-DEV */ #ifndef _GF_X3D_NODES_H @@ -38,6 +38,8 @@ extern "C" { #include <gpac/scenegraph_vrml.h> +#ifndef GPAC_DISABLE_X3D + enum { @@ -239,7 +241,7 @@ typedef struct _tagX3DBackground { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat groundAngle; /*exposedField*/ MFColor groundColor; /*exposedField*/ MFURL backUrl; /*exposedField*/ @@ -269,7 +271,7 @@ typedef struct _tagX3DBooleanFilter { BASE_NODE SFBool set_boolean; /*eventIn*/ - void (*on_set_boolean)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_boolean)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool inputFalse; /*eventOut*/ SFBool inputNegate; /*eventOut*/ SFBool inputTrue; /*eventOut*/ @@ -281,11 +283,11 @@ typedef struct _tagX3DBooleanSequencer { BASE_NODE SFBool next; /*eventIn*/ - void (*on_next)(GF_Node *pThis); /*eventInHandler*/ + void (*on_next)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool previous; /*eventIn*/ - void (*on_previous)(GF_Node *pThis); /*eventInHandler*/ + void (*on_previous)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFBool keyValue; /*exposedField*/ SFBool value_changed; /*eventOut*/ @@ -297,7 +299,7 @@ typedef struct _tagX3DBooleanToggle { BASE_NODE SFBool set_boolean; /*eventIn*/ - void (*on_set_boolean)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_boolean)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool toggle; /*exposedField*/ GF_Node *metadata; /*exposedField*/ } X_BooleanToggle; @@ -307,7 +309,7 @@ typedef struct _tagX3DBooleanTrigger { BASE_NODE SFTime set_triggerTime; /*eventIn*/ - void (*on_set_triggerTime)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_triggerTime)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool triggerTrue; /*eventOut*/ GF_Node *metadata; /*exposedField*/ } X_BooleanTrigger; @@ -353,7 +355,7 @@ typedef struct _tagX3DColorInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFColor keyValue; /*exposedField*/ SFColor value_changed; /*eventOut*/ @@ -424,7 +426,7 @@ typedef struct _tagX3DCoordinateInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec3f keyValue; /*exposedField*/ MFVec3f value_changed; /*eventOut*/ @@ -436,7 +438,7 @@ typedef struct _tagX3DCoordinateInterpolator2D { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec2f keyValue; /*exposedField*/ MFVec2f value_changed; /*eventOut*/ @@ -499,7 +501,7 @@ typedef struct _tagX3DElevationGrid { BASE_NODE MFFloat set_height; /*eventIn*/ - void (*on_set_height)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_height)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *normal; /*exposedField*/ GF_Node *texCoord; /*exposedField*/ @@ -517,17 +519,115 @@ typedef struct _tagX3DElevationGrid } X_ElevationGrid; +typedef struct _tagX3DEspduTransform +{ + BASE_NODE + VRML_CHILDREN + SFFloat set_articulationParameterValue0; /*eventIn*/ + void (*on_set_articulationParameterValue0)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFFloat set_articulationParameterValue1; /*eventIn*/ + void (*on_set_articulationParameterValue1)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFFloat set_articulationParameterValue2; /*eventIn*/ + void (*on_set_articulationParameterValue2)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFFloat set_articulationParameterValue3; /*eventIn*/ + void (*on_set_articulationParameterValue3)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFFloat set_articulationParameterValue4; /*eventIn*/ + void (*on_set_articulationParameterValue4)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFFloat set_articulationParameterValue5; /*eventIn*/ + void (*on_set_articulationParameterValue5)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFFloat set_articulationParameterValue6; /*eventIn*/ + void (*on_set_articulationParameterValue6)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFFloat set_articulationParameterValue7; /*eventIn*/ + void (*on_set_articulationParameterValue7)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFString address; /*exposedField*/ + SFInt32 applicationID; /*exposedField*/ + SFInt32 articulationParameterCount; /*exposedField*/ + MFInt32 articulationParameterDesignatorArray; /*exposedField*/ + MFInt32 articulationParameterChangeIndicatorArray; /*exposedField*/ + MFInt32 articulationParameterIdPartAttachedToArray; /*exposedField*/ + MFInt32 articulationParameterTypeArray; /*exposedField*/ + MFFloat articulationParameterArray; /*exposedField*/ + SFVec3f center; /*exposedField*/ + SFInt32 collisionType; /*exposedField*/ + SFInt32 deadReckoning; /*exposedField*/ + SFVec3f detonationLocation; /*exposedField*/ + SFVec3f detonationRelativeLocation; /*exposedField*/ + SFInt32 detonationResult; /*exposedField*/ + SFInt32 entityCategory; /*exposedField*/ + SFInt32 entityCountry; /*exposedField*/ + SFInt32 entityDomain; /*exposedField*/ + SFInt32 entityExtra; /*exposedField*/ + SFInt32 entityID; /*exposedField*/ + SFInt32 entityKind; /*exposedField*/ + SFInt32 entitySpecific; /*exposedField*/ + SFInt32 entitySubCategory; /*exposedField*/ + SFInt32 eventApplicationID; /*exposedField*/ + SFInt32 eventEntityID; /*exposedField*/ + SFInt32 eventNumber; /*exposedField*/ + SFInt32 eventSiteID; /*exposedField*/ + SFBool fired1; /*exposedField*/ + SFBool fired2; /*exposedField*/ + SFInt32 fireMissionIndex; /*exposedField*/ + SFFloat firingRange; /*exposedField*/ + SFInt32 firingRate; /*exposedField*/ + SFInt32 forceID; /*exposedField*/ + SFInt32 fuse; /*exposedField*/ + SFVec3f linearVelocity; /*exposedField*/ + SFVec3f linearAcceleration; /*exposedField*/ + SFString marking; /*exposedField*/ + SFString multicastRelayHost; /*exposedField*/ + SFInt32 multicastRelayPort; /*exposedField*/ + SFInt32 munitionApplicationID; /*exposedField*/ + SFVec3f munitionEndPoint; /*exposedField*/ + SFInt32 munitionEntityID; /*exposedField*/ + SFInt32 munitionQuantity; /*exposedField*/ + SFInt32 munitionSiteID; /*exposedField*/ + SFVec3f munitionStartPoint; /*exposedField*/ + SFString networkMode; /*exposedField*/ + SFInt32 port; /*exposedField*/ + SFTime readInterval; /*exposedField*/ + SFRotation rotation; /*exposedField*/ + SFVec3f scale; /*exposedField*/ + SFRotation scaleOrientation; /*exposedField*/ + SFInt32 siteID; /*exposedField*/ + SFVec3f translation; /*exposedField*/ + SFInt32 warhead; /*exposedField*/ + SFTime writeInterval; /*exposedField*/ + SFBool rtpHeaderExpected; /*field*/ + SFFloat articulationParameterValue0_changed; /*eventOut*/ + SFFloat articulationParameterValue1_changed; /*eventOut*/ + SFFloat articulationParameterValue2_changed; /*eventOut*/ + SFFloat articulationParameterValue3_changed; /*eventOut*/ + SFFloat articulationParameterValue4_changed; /*eventOut*/ + SFFloat articulationParameterValue5_changed; /*eventOut*/ + SFFloat articulationParameterValue6_changed; /*eventOut*/ + SFFloat articulationParameterValue7_changed; /*eventOut*/ + SFTime collideTime; /*eventOut*/ + SFTime detonateTime; /*eventOut*/ + SFTime firedTime; /*eventOut*/ + SFBool isActive; /*eventOut*/ + SFBool isCollided; /*eventOut*/ + SFBool isDetonated; /*eventOut*/ + SFBool isNetworkReader; /*eventOut*/ + SFBool isNetworkWriter; /*eventOut*/ + SFBool isRtpHeaderHeard; /*eventOut*/ + SFBool isStandAlone; /*eventOut*/ + SFTime timestamp; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_EspduTransform; + + typedef struct _tagX3DExtrusion { BASE_NODE MFVec2f set_crossSection; /*eventIn*/ - void (*on_set_crossSection)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_crossSection)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFRotation set_orientation; /*eventIn*/ - void (*on_set_orientation)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_orientation)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFVec2f set_scale; /*eventIn*/ - void (*on_set_scale)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_scale)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFVec3f set_spine; /*eventIn*/ - void (*on_set_spine)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_spine)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool beginCap; /*field*/ SFBool ccw; /*field*/ SFBool convex; /*field*/ @@ -559,7 +659,7 @@ typedef struct _tagX3DFog SFString fogType; /*exposedField*/ SFFloat visibilityRange; /*exposedField*/ SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool isBound; /*eventOut*/ GF_Node *metadata; /*exposedField*/ SFTime bindTime; /*eventOut*/ @@ -582,6 +682,148 @@ typedef struct _tagX3DFontStyle } X_FontStyle; +typedef struct _tagX3DGeoCoordinate +{ + BASE_NODE + MFVec3d point; /*exposedField*/ + GF_Node *geoOrigin; /*field*/ + MFString geoSystem; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_GeoCoordinate; + + +typedef struct _tagX3DGeoElevationGrid +{ + BASE_NODE + MFDouble set_height; /*eventIn*/ + void (*on_set_height)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *color; /*exposedField*/ + GF_Node *normal; /*exposedField*/ + GF_Node *texCoord; /*exposedField*/ + SFFloat yScale; /*exposedField*/ + SFBool ccw; /*field*/ + SFBool colorPerVertex; /*field*/ + SFFloat creaseAngle; /*field*/ + SFString geoGridOrigin; /*field*/ + GF_Node *geoOrigin; /*field*/ + MFString geoSystem; /*field*/ + MFDouble height; /*field*/ + SFBool normalPerVertex; /*field*/ + SFBool solid; /*field*/ + SFInt32 xDimension; /*field*/ + SFDouble xSpacing; /*field*/ + SFInt32 zDimension; /*field*/ + SFDouble zSpacing; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_GeoElevationGrid; + + +typedef struct _tagX3DGeoLocation +{ + BASE_NODE + VRML_CHILDREN + SFVec3d geoCoords; /*exposedField*/ + GF_Node *geoOrigin; /*field*/ + MFString geoSystem; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_GeoLocation; + + +typedef struct _tagX3DGeoLOD +{ + BASE_NODE + SFVec3d center; /*field*/ + MFURL child1Url; /*field*/ + MFURL child2Url; /*field*/ + MFURL child3Url; /*field*/ + MFURL child4Url; /*field*/ + GF_Node *geoOrigin; /*field*/ + MFString geoSystem; /*field*/ + SFFloat range; /*field*/ + MFURL rootUrl; /*field*/ + GF_ChildNodeItem *rootNode; /*field*/ + GF_ChildNodeItem *children; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_GeoLOD; + + +typedef struct _tagX3DGeoMetadata +{ + BASE_NODE + GF_ChildNodeItem *data; /*exposedField*/ + MFString summary; /*exposedField*/ + MFURL url; /*exposedField*/ + GF_Node *metadata; /*exposedField*/ +} X_GeoMetadata; + + +typedef struct _tagX3DGeoOrigin +{ + BASE_NODE + SFVec3d geoCoords; /*exposedField*/ + MFString geoSystem; /*exposedField*/ + SFBool rotateYUp; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_GeoOrigin; + + +typedef struct _tagX3DGeoPositionInterpolator +{ + BASE_NODE + SFFloat set_fraction; /*eventIn*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + MFFloat key; /*exposedField*/ + MFVec3d keyValue; /*exposedField*/ + GF_Node *geoOrigin; /*field*/ + MFString geoSystem; /*field*/ + SFVec3d geovalue_changed; /*eventOut*/ + SFVec3f value_changed; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_GeoPositionInterpolator; + + +typedef struct _tagX3DGeoTouchSensor +{ + BASE_NODE + SFBool enabled; /*exposedField*/ + GF_Node *geoOrigin; /*field*/ + MFString geoSystem; /*field*/ + SFVec3f hitNormal_changed; /*eventOut*/ + SFVec3f hitPoint_changed; /*eventOut*/ + SFVec2f hitTexCoord_changed; /*eventOut*/ + SFVec3d hitGeoCoord_changed; /*eventOut*/ + SFBool isActive; /*eventOut*/ + SFBool isOver; /*eventOut*/ + SFTime touchTime; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_GeoTouchSensor; + + +typedef struct _tagX3DGeoViewpoint +{ + BASE_NODE + SFBool set_bind; /*eventIn*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFString set_orientation; /*eventIn*/ + void (*on_set_orientation)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFString set_position; /*eventIn*/ + void (*on_set_position)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + SFString description; /*exposedField*/ + SFFloat fieldOfView; /*exposedField*/ + SFBool headlight; /*exposedField*/ + SFBool jump; /*exposedField*/ + MFString navType; /*exposedField*/ + SFTime bindTime; /*eventOut*/ + SFBool isBound; /*eventOut*/ + GF_Node *geoOrigin; /*field*/ + MFString geoSystem; /*field*/ + SFRotation orientation; /*field*/ + SFVec3d position; /*field*/ + SFFloat speedFactor; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_GeoViewpoint; + + typedef struct _tagX3DGroup { BASE_NODE @@ -590,6 +832,89 @@ typedef struct _tagX3DGroup } X_Group; +typedef struct _tagX3DHAnimDisplacer +{ + BASE_NODE + MFInt32 coordIndex; /*exposedField*/ + MFVec3f displacements; /*exposedField*/ + SFString name; /*exposedField*/ + SFFloat weight; /*exposedField*/ + GF_Node *metadata; /*exposedField*/ +} X_HAnimDisplacer; + + +typedef struct _tagX3DHAnimHumanoid +{ + BASE_NODE + SFVec3f center; /*exposedField*/ + MFString info; /*exposedField*/ + GF_ChildNodeItem *joints; /*exposedField*/ + SFString name; /*exposedField*/ + SFRotation rotation; /*exposedField*/ + SFVec3f scale; /*exposedField*/ + SFRotation scaleOrientation; /*exposedField*/ + GF_ChildNodeItem *segments; /*exposedField*/ + GF_ChildNodeItem *sites; /*exposedField*/ + GF_ChildNodeItem *skeleton; /*exposedField*/ + GF_ChildNodeItem *skin; /*exposedField*/ + GF_Node *skinCoord; /*exposedField*/ + GF_Node *skinNormal; /*exposedField*/ + SFVec3f translation; /*exposedField*/ + SFString version; /*exposedField*/ + GF_ChildNodeItem *viewpoints; /*exposedField*/ + GF_Node *metadata; /*exposedField*/ +} X_HAnimHumanoid; + + +typedef struct _tagX3DHAnimJoint +{ + BASE_NODE + VRML_CHILDREN + SFVec3f center; /*exposedField*/ + GF_ChildNodeItem *displacers; /*exposedField*/ + SFRotation limitOrientation; /*exposedField*/ + MFFloat llimit; /*exposedField*/ + SFString name; /*exposedField*/ + SFRotation rotation; /*exposedField*/ + SFVec3f scale; /*exposedField*/ + SFRotation scaleOrientation; /*exposedField*/ + MFInt32 skinCoordIndex; /*exposedField*/ + MFFloat skinCoordWeight; /*exposedField*/ + MFFloat stiffness; /*exposedField*/ + SFVec3f translation; /*exposedField*/ + MFFloat ulimit; /*exposedField*/ + GF_Node *metadata; /*exposedField*/ +} X_HAnimJoint; + + +typedef struct _tagX3DHAnimSegment +{ + BASE_NODE + VRML_CHILDREN + SFVec3f centerOfMass; /*exposedField*/ + GF_Node *coord; /*exposedField*/ + GF_ChildNodeItem *displacers; /*exposedField*/ + SFFloat mass; /*exposedField*/ + MFFloat momentsOfInertia; /*exposedField*/ + SFString name; /*exposedField*/ + GF_Node *metadata; /*exposedField*/ +} X_HAnimSegment; + + +typedef struct _tagX3DHAnimSite +{ + BASE_NODE + VRML_CHILDREN + SFVec3f center; /*exposedField*/ + SFString name; /*exposedField*/ + SFRotation rotation; /*exposedField*/ + SFVec3f scale; /*exposedField*/ + SFRotation scaleOrientation; /*exposedField*/ + SFVec3f translation; /*exposedField*/ + GF_Node *metadata; /*exposedField*/ +} X_HAnimSite; + + typedef struct _tagX3DImageTexture { BASE_NODE @@ -604,13 +929,13 @@ typedef struct _tagX3DIndexedFaceSet { BASE_NODE MFInt32 set_colorIndex; /*eventIn*/ - void (*on_set_colorIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_coordIndex; /*eventIn*/ - void (*on_set_coordIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_coordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_normalIndex; /*eventIn*/ - void (*on_set_normalIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_normalIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_texCoordIndex; /*eventIn*/ - void (*on_set_texCoordIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_texCoordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *coord; /*exposedField*/ GF_Node *normal; /*exposedField*/ @@ -633,9 +958,9 @@ typedef struct _tagX3DIndexedLineSet { BASE_NODE MFInt32 set_colorIndex; /*eventIn*/ - void (*on_set_colorIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_colorIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFInt32 set_coordIndex; /*eventIn*/ - void (*on_set_coordIndex)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_coordIndex)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *coord; /*exposedField*/ MFInt32 colorIndex; /*field*/ @@ -649,7 +974,7 @@ typedef struct _tagX3DIndexedTriangleFanSet { BASE_NODE MFInt32 set_index; /*eventIn*/ - void (*on_set_index)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_index)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *coord; /*exposedField*/ GF_Node *normal; /*exposedField*/ @@ -667,7 +992,7 @@ typedef struct _tagX3DIndexedTriangleSet { BASE_NODE MFInt32 set_index; /*eventIn*/ - void (*on_set_index)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_index)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *coord; /*exposedField*/ GF_Node *normal; /*exposedField*/ @@ -685,7 +1010,7 @@ typedef struct _tagX3DIndexedTriangleStripSet { BASE_NODE MFInt32 set_index; /*eventIn*/ - void (*on_set_index)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_index)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ GF_Node *color; /*exposedField*/ GF_Node *coord; /*exposedField*/ SFFloat creaseAngle; /*exposedField*/ @@ -712,11 +1037,11 @@ typedef struct _tagX3DIntegerSequencer { BASE_NODE SFBool next; /*eventIn*/ - void (*on_next)(GF_Node *pThis); /*eventInHandler*/ + void (*on_next)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFBool previous; /*eventIn*/ - void (*on_previous)(GF_Node *pThis); /*eventInHandler*/ + void (*on_previous)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFInt32 keyValue; /*exposedField*/ SFInt32 value_changed; /*eventOut*/ @@ -728,7 +1053,7 @@ typedef struct _tagX3DIntegerTrigger { BASE_NODE SFBool set_boolean; /*eventIn*/ - void (*on_set_boolean)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_boolean)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFInt32 integerKey; /*exposedField*/ SFInt32 triggerValue; /*eventOut*/ GF_Node *metadata; /*exposedField*/ @@ -771,6 +1096,20 @@ typedef struct _tagX3DLineSet } X_LineSet; +typedef struct _tagX3DLoadSensor +{ + BASE_NODE + SFBool enabled; /*exposedField*/ + SFTime timeOut; /*exposedField*/ + GF_ChildNodeItem *watchList; /*exposedField*/ + SFBool isActive; /*eventOut*/ + SFBool isLoaded; /*eventOut*/ + SFTime loadTime; /*eventOut*/ + SFFloat progress; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_LoadSensor; + + typedef struct _tagX3DLOD { BASE_NODE @@ -897,7 +1236,7 @@ typedef struct _tagX3DNavigationInfo { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat avatarSize; /*exposedField*/ SFBool headlight; /*exposedField*/ SFFloat speed; /*exposedField*/ @@ -922,7 +1261,7 @@ typedef struct _tagX3DNormalInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec3f keyValue; /*exposedField*/ MFVec3f value_changed; /*eventOut*/ @@ -930,11 +1269,181 @@ typedef struct _tagX3DNormalInterpolator } X_NormalInterpolator; +typedef struct _tagX3DNurbsCurve +{ + BASE_NODE + MFVec3f controlPoint; /*exposedField*/ + SFInt32 tessellation; /*exposedField*/ + MFDouble weight; /*exposedField*/ + SFBool closed; /*field*/ + MFFloat knot; /*field*/ + SFInt32 order; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsCurve; + + +typedef struct _tagX3DNurbsCurve2D +{ + BASE_NODE + MFVec2f controlPoint; /*exposedField*/ + SFInt32 tessellation; /*exposedField*/ + MFFloat weight; /*exposedField*/ + MFFloat knot; /*field*/ + SFInt32 order; /*field*/ + SFBool closed; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsCurve2D; + + +typedef struct _tagX3DNurbsOrientationInterpolator +{ + BASE_NODE + SFFloat set_fraction; /*eventIn*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *controlPoints; /*exposedField*/ + MFDouble knot; /*exposedField*/ + SFInt32 order; /*exposedField*/ + MFDouble weight; /*exposedField*/ + SFRotation value_changed; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsOrientationInterpolator; + + +typedef struct _tagX3DNurbsPatchSurface +{ + BASE_NODE + GF_Node *controlPoint; /*exposedField*/ + GF_Node *texCoord; /*exposedField*/ + SFInt32 uTessellation; /*exposedField*/ + SFInt32 vTessellation; /*exposedField*/ + MFDouble weight; /*exposedField*/ + SFBool solid; /*field*/ + SFBool uClosed; /*field*/ + SFInt32 uDimension; /*field*/ + MFDouble uKnot; /*field*/ + SFInt32 uOrder; /*field*/ + SFBool vClosed; /*field*/ + SFInt32 vDimension; /*field*/ + MFDouble vKnot; /*field*/ + SFInt32 vOrder; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsPatchSurface; + + +typedef struct _tagX3DNurbsPositionInterpolator +{ + BASE_NODE + SFFloat set_fraction; /*eventIn*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *controlPoints; /*exposedField*/ + MFDouble knot; /*exposedField*/ + SFInt32 order; /*exposedField*/ + MFDouble weight; /*exposedField*/ + SFVec3f value_changed; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsPositionInterpolator; + + +typedef struct _tagX3DNurbsSet +{ + BASE_NODE + GF_ChildNodeItem *addGeometry; /*eventIn*/ + void (*on_addGeometry)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_ChildNodeItem *removeGeometry; /*eventIn*/ + void (*on_removeGeometry)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_ChildNodeItem *geometry; /*exposedField*/ + SFFloat tessellationScale; /*exposedField*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsSet; + + +typedef struct _tagX3DNurbsSurfaceInterpolator +{ + BASE_NODE + SFVec2f set_fraction; /*eventIn*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_Node *controlPoints; /*exposedField*/ + MFDouble weight; /*exposedField*/ + SFVec3f position_changed; /*eventOut*/ + SFVec3f normal_changed; /*eventOut*/ + SFInt32 uDimension; /*field*/ + MFDouble uKnot; /*field*/ + SFInt32 uOrder; /*field*/ + SFInt32 vDimension; /*field*/ + MFDouble vKnot; /*field*/ + SFInt32 vOrder; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsSurfaceInterpolator; + + +typedef struct _tagX3DNurbsSweptSurface +{ + BASE_NODE + GF_Node *crossSectionCurve; /*exposedField*/ + GF_Node *trajectoryCurve; /*exposedField*/ + SFBool ccw; /*field*/ + SFBool solid; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsSweptSurface; + + +typedef struct _tagX3DNurbsSwungSurface +{ + BASE_NODE + GF_Node *profileCurve; /*exposedField*/ + GF_Node *trajectoryCurve; /*exposedField*/ + SFBool ccw; /*field*/ + SFBool solid; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsSwungSurface; + + +typedef struct _tagX3DNurbsTextureCoordinate +{ + BASE_NODE + MFVec2f controlPoint; /*exposedField*/ + MFFloat weight; /*exposedField*/ + SFInt32 uDimension; /*field*/ + MFDouble uKnot; /*field*/ + SFInt32 uOrder; /*field*/ + SFInt32 vDimension; /*field*/ + MFDouble vKnot; /*field*/ + SFInt32 vOrder; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsTextureCoordinate; + + +typedef struct _tagX3DNurbsTrimmedSurface +{ + BASE_NODE + GF_ChildNodeItem *addTrimmingContour; /*eventIn*/ + void (*on_addTrimmingContour)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_ChildNodeItem *removeTrimmingContour; /*eventIn*/ + void (*on_removeTrimmingContour)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ + GF_ChildNodeItem *trimmingContour; /*exposedField*/ + GF_Node *controlPoint; /*exposedField*/ + GF_Node *texCoord; /*exposedField*/ + SFInt32 uTessellation; /*exposedField*/ + SFInt32 vTessellation; /*exposedField*/ + MFDouble weight; /*exposedField*/ + SFBool solid; /*field*/ + SFBool uClosed; /*field*/ + SFInt32 uDimension; /*field*/ + MFDouble uKnot; /*field*/ + SFInt32 uOrder; /*field*/ + SFBool vClosed; /*field*/ + SFInt32 vDimension; /*field*/ + MFDouble vKnot; /*field*/ + SFInt32 vOrder; /*field*/ + GF_Node *metadata; /*exposedField*/ +} X_NurbsTrimmedSurface; + + typedef struct _tagX3DOrientationInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFRotation keyValue; /*exposedField*/ SFRotation value_changed; /*eventOut*/ @@ -1012,7 +1521,7 @@ typedef struct _tagX3DPositionInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec3f keyValue; /*exposedField*/ SFVec3f value_changed; /*eventOut*/ @@ -1024,7 +1533,7 @@ typedef struct _tagX3DPositionInterpolator2D { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFVec2f keyValue; /*exposedField*/ SFVec2f value_changed; /*eventOut*/ @@ -1048,6 +1557,38 @@ typedef struct _tagX3DProximitySensor } X_ProximitySensor; +typedef struct _tagX3DReceiverPdu +{ + BASE_NODE + SFString address; /*exposedField*/ + SFInt32 applicationID; /*exposedField*/ + SFInt32 entityID; /*exposedField*/ + SFString multicastRelayHost; /*exposedField*/ + SFInt32 multicastRelayPort; /*exposedField*/ + SFString networkMode; /*exposedField*/ + SFInt32 port; /*exposedField*/ + SFInt32 radioID; /*exposedField*/ + SFFloat readInterval; /*exposedField*/ + SFFloat receivedPower; /*exposedField*/ + SFInt32 receiverState; /*exposedField*/ + SFBool rtpHeaderExpected; /*exposedField*/ + SFInt32 siteID; /*exposedField*/ + SFInt32 transmitterApplicationID; /*exposedField*/ + SFInt32 transmitterEntityID; /*exposedField*/ + SFInt32 transmitterRadioID; /*exposedField*/ + SFInt32 transmitterSiteID; /*exposedField*/ + SFInt32 whichGeometry; /*exposedField*/ + SFFloat writeInterval; /*exposedField*/ + SFBool isActive; /*eventOut*/ + SFBool isNetworkReader; /*eventOut*/ + SFBool isNetworkWriter; /*eventOut*/ + SFBool isRtpHeaderHeard; /*eventOut*/ + SFBool isStandAlone; /*eventOut*/ + SFTime timestamp; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_ReceiverPdu; + + typedef struct _tagX3DRectangle2D { BASE_NODE @@ -1060,7 +1601,7 @@ typedef struct _tagX3DScalarInterpolator { BASE_NODE SFFloat set_fraction; /*eventIn*/ - void (*on_set_fraction)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_fraction)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat key; /*exposedField*/ MFFloat keyValue; /*exposedField*/ SFFloat value_changed; /*eventOut*/ @@ -1087,6 +1628,38 @@ typedef struct _tagX3DShape } X_Shape; +typedef struct _tagX3DSignalPdu +{ + BASE_NODE + SFString address; /*exposedField*/ + SFInt32 applicationID; /*exposedField*/ + MFInt32 data; /*exposedField*/ + SFInt32 dataLength; /*exposedField*/ + SFInt32 encodingScheme; /*exposedField*/ + SFInt32 entityID; /*exposedField*/ + SFString multicastRelayHost; /*exposedField*/ + SFInt32 multicastRelayPort; /*exposedField*/ + SFString networkMode; /*exposedField*/ + SFInt32 port; /*exposedField*/ + SFInt32 radioID; /*exposedField*/ + SFFloat readInterval; /*exposedField*/ + SFBool rtpHeaderExpected; /*exposedField*/ + SFInt32 sampleRate; /*exposedField*/ + SFInt32 samples; /*exposedField*/ + SFInt32 siteID; /*exposedField*/ + SFInt32 tdlType; /*exposedField*/ + SFInt32 whichGeometry; /*exposedField*/ + SFFloat writeInterval; /*exposedField*/ + SFBool isActive; /*eventOut*/ + SFBool isNetworkReader; /*eventOut*/ + SFBool isNetworkWriter; /*eventOut*/ + SFBool isRtpHeaderHeard; /*eventOut*/ + SFBool isStandAlone; /*eventOut*/ + SFTime timestamp; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_SignalPdu; + + typedef struct _tagX3DSound { BASE_NODE @@ -1188,7 +1761,7 @@ typedef struct _tagX3DTextureBackground { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ MFFloat groundAngle; /*exposedField*/ MFColor groundColor; /*exposedField*/ GF_Node *backTexture; /*exposedField*/ @@ -1258,7 +1831,7 @@ typedef struct _tagX3DTimeTrigger { BASE_NODE SFBool set_boolean; /*eventIn*/ - void (*on_set_boolean)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_boolean)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFTime triggerTime; /*eventOut*/ GF_Node *metadata; /*exposedField*/ } X_TimeTrigger; @@ -1292,6 +1865,54 @@ typedef struct _tagX3DTransform } X_Transform; +typedef struct _tagX3DTransmitterPdu +{ + BASE_NODE + SFString address; /*exposedField*/ + SFVec3f antennaLocation; /*exposedField*/ + SFInt32 antennaPatternLength; /*exposedField*/ + SFInt32 antennaPatternType; /*exposedField*/ + SFInt32 applicationID; /*exposedField*/ + SFInt32 cryptoKeyID; /*exposedField*/ + SFInt32 cryptoSystem; /*exposedField*/ + SFInt32 entityID; /*exposedField*/ + SFInt32 frequency; /*exposedField*/ + SFInt32 inputSource; /*exposedField*/ + SFInt32 lengthOfModulationParameters; /*exposedField*/ + SFInt32 modulationTypeDetail; /*exposedField*/ + SFInt32 modulationTypeMajor; /*exposedField*/ + SFInt32 modulationTypeSpreadSpectrum; /*exposedField*/ + SFInt32 modulationTypeSystem; /*exposedField*/ + SFString multicastRelayHost; /*exposedField*/ + SFInt32 multicastRelayPort; /*exposedField*/ + SFString networkMode; /*exposedField*/ + SFInt32 port; /*exposedField*/ + SFFloat power; /*exposedField*/ + SFInt32 radioEntityTypeCategory; /*exposedField*/ + SFInt32 radioEntityTypeCountry; /*exposedField*/ + SFInt32 radioEntityTypeDomain; /*exposedField*/ + SFInt32 radioEntityTypeKind; /*exposedField*/ + SFInt32 radioEntityTypeNomenclature; /*exposedField*/ + SFInt32 radioEntityTypeNomenclatureVersion; /*exposedField*/ + SFInt32 radioID; /*exposedField*/ + SFFloat readInterval; /*exposedField*/ + SFVec3f relativeAntennaLocation; /*exposedField*/ + SFBool rtpHeaderExpected; /*exposedField*/ + SFInt32 siteID; /*exposedField*/ + SFFloat transmitFrequencyBandwidth; /*exposedField*/ + SFInt32 transmitState; /*exposedField*/ + SFInt32 whichGeometry; /*exposedField*/ + SFFloat writeInterval; /*exposedField*/ + SFBool isActive; /*eventOut*/ + SFBool isNetworkReader; /*eventOut*/ + SFBool isNetworkWriter; /*eventOut*/ + SFBool isRtpHeaderHeard; /*eventOut*/ + SFBool isStandAlone; /*eventOut*/ + SFTime timestamp; /*eventOut*/ + GF_Node *metadata; /*exposedField*/ +} X_TransmitterPdu; + + typedef struct _tagX3DTriangleFanSet { BASE_NODE @@ -1351,7 +1972,7 @@ typedef struct _tagX3DViewpoint { BASE_NODE SFBool set_bind; /*eventIn*/ - void (*on_set_bind)(GF_Node *pThis); /*eventInHandler*/ + void (*on_set_bind)(GF_Node *pThis, struct _route *route); /*eventInHandler*/ SFFloat fieldOfView; /*exposedField*/ SFBool jump; /*exposedField*/ SFRotation orientation; /*exposedField*/ @@ -1386,6 +2007,8 @@ typedef struct _tagX3DWorldInfo } X_WorldInfo; +#endif /*GPAC_DISABLE_X3D*/ + #ifdef __cplusplus } #endif diff --git a/include/gpac/options.h b/include/gpac/options.h index 67da71f..bf0ecb9 100644 --- a/include/gpac/options.h +++ b/include/gpac/options.h @@ -176,6 +176,13 @@ enum GF_BACK_CULL_ALPHA, /*backface culling enabled alos for transparent meshes*/ }; +enum +{ + GF_DRAW_MODE_DEFER=0, + GF_DRAW_MODE_DEFER_DEBUG, + GF_DRAW_MODE_IMMEDIATE, +}; + /*high-level options*/ enum { @@ -195,6 +202,8 @@ enum GF_OPT_AUDIO_VOLUME, /*set / get audio pan (value is pan between 0 (all left) and 100(all right) )*/ GF_OPT_AUDIO_PAN, + /*set / get audio mute*/ + GF_OPT_AUDIO_MUTE, /*get javascript flag (no set, depends on compil) - value: boolean, true if JS enabled in build*/ GF_OPT_HAS_JAVASCRIPT, /*get selectable stream flag (no set) - value: boolean, true if audio/video/subtitle stream selection is @@ -207,11 +216,11 @@ enum /*set freeze display on/off / get freeze state freeze_display prevents any screen updates needed when output driver uses direct video memory access*/ GF_OPT_FREEZE_DISPLAY, - /*get isOver flag: if true the file can be restarted, otherwise it should not - this is used to check is there are several timelines, timesensors or interactions, in which case - the file could be running for an undetermined period. - Note that nothing prevents the user app to restart such a file*/ + /*Returns 1 if file playback is considered as done (all streams finished, no active time sensors + and no user interactions in the scene)*/ GF_OPT_IS_FINISHED, + /*Returns 1 if file timeline is considered as done (all streams finished, no active time sensors)*/ + GF_OPT_IS_OVER, /*set/get aspect ratio (value: one of AspectRatio enum) */ GF_OPT_ASPECT_RATIO, /*send a redraw message (SetOption only): all graphics info (display list, vectorial path) is @@ -239,10 +248,13 @@ enum /*get/set OpenGL force mode - returns error if OpenGL is not supported*/ GF_OPT_USE_OPENGL, - /*set/get direct draw flag. In direct draw, the screen is entirely redrawn at each frame - value: boolean + /*set/get draw mode. + In immediate mode, the screen is entirely redrawn at each frame + In defer mode, only the changed ares are redrawn + In defer-debug mode, unchanged areas are erased and changed ares are redrawn + value: enum */ - GF_OPT_DIRECT_DRAW, + GF_OPT_DRAW_MODE, /*set/get scalable zoom (value: boolean)*/ GF_OPT_SCALABLE_ZOOM, /*set/get YUV acceleration (value: boolean) */ diff --git a/include/gpac/path2d.h b/include/gpac/path2d.h index e96d2e3..a27fa1b 100644 --- a/include/gpac/path2d.h +++ b/include/gpac/path2d.h @@ -556,10 +556,14 @@ enum */ typedef struct { + /*begining of the structure is casted in MFFloat in BIFS, DO NOT CHANGE ORDER*/ + /*! Number of dashes in the pattern*/ u32 num_dash; /*! Value of the pattern dashes. Unit depends on the dash type*/ Fixed *dashes; + /*! SVG/CSS unit for the dashes */ + u8 *dash_units; } GF_DashSettings; /*!\brief Pen properties diff --git a/include/gpac/rtp_streamer.h b/include/gpac/rtp_streamer.h new file mode 100644 index 0000000..bda1a1b --- /dev/null +++ b/include/gpac/rtp_streamer.h @@ -0,0 +1,114 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2008- + * All rights reserved + * + * This file is part of GPAC / media tools sub-project + * + * GPAC is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * GPAC is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef _GF_RTPSTREAMER_H_ +#define _GF_RTPSTREAMER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * \file <gpac/rtp_streamer.h> + * \brief RTP streamer functions (packetizer and RTP socket). + */ + +/*! + * \addtogroup media_grp RTPStreamer + * \ingroup media_grp + * \brief RTPStreamer object + * + * This section documents the RTP streamer object of the GPAC framework. + * @{ + */ + +#include <gpac/ietf.h> +#include <gpac/isomedia.h> + +#ifndef GPAC_DISABLE_STREAMING + +typedef struct __rtp_streamer GF_RTPStreamer; + +/*! + * \brief RTP Streamer constructor + * + * Constructs a new RTP file streamer + *\param ifce_addr IP of the local interface to use (may be NULL) + *\return new object + */ + +GF_RTPStreamer *gf_rtp_streamer_new(u32 streamType, u32 oti, u32 timeScale, + const char *ip_dest, u16 port, u32 MTU, u8 TTL, const char *ifce_addr, + u32 flags, char *dsi, u32 dsi_len); + + +GF_RTPStreamer *gf_rtp_streamer_new_extended(u32 streamType, u32 oti, u32 timeScale, + const char *ip_dest, u16 port, u32 MTU, u8 TTL, const char *ifce_addr, + u32 flags, char *dsi, u32 dsi_len, + u32 PayloadType, u32 sample_rate, u32 nb_ch, + Bool is_crypted, u32 IV_length, u32 KI_length, + u32 MinSize, u32 MaxSize, u32 avgTS, u32 maxDTSDelta, u32 const_dur, u32 bandwidth, u32 max_ptime, + u32 au_sn_len); + +/*! + * \brief RTP file streamer destructor + * + * Destructs an RTP file streamer + * \param ptr object to destruct + */ +void gf_rtp_streamer_del(GF_RTPStreamer *streamer); + +/*! + * \brief gets the SDP file + * + * Gets the SDP asscoiated with all media in the streaming session (only media parts are returned) + * \param streamer RTP streamer object + * \param out_sdp_buffer location to the SDP buffer to allocate and fill + */ +GF_Err gf_rtp_streamer_append_sdp(GF_RTPStreamer *rtp, u16 ESID, char *dsi, u32 dsi_len, char *KMS_URI, char **out_sdp_buffer); + +GF_Err gf_rtp_streamer_append_sdp_extended(GF_RTPStreamer *rtp, u16 ESID, char *dsi, u32 dsi_len, GF_ISOFile *isofile, u32 isotrack, char *KMS_URI, u32 width, u32 height, char **out_sdp_buffer) ; + +GF_Err gf_rtp_streamer_send_au(GF_RTPStreamer *rtp, char *data, u32 size, u64 cts, u64 dts, Bool is_rap); + +GF_Err gf_rtp_streamer_send_au_with_sn(GF_RTPStreamer *rtp, char *data, u32 size, u64 cts, u64 dts, Bool is_rap, Bool inc_au_sn); + +GF_Err gf_rtp_streamer_send_data(GF_RTPStreamer *rtp, char *data, u32 size, u32 fullsize, u64 cts, u64 dts, Bool is_rap, Bool au_start, Bool au_end, u32 au_sn, u32 sampleDuration, u32 sampleDescIndex); + +char *gf_rtp_streamer_format_sdp_header(char *app_name, char *ip_dest, char *session_name, char *iod64); + +void gf_rtp_streamer_disable_auto_rtcp(GF_RTPStreamer *streamer); + +GF_Err gf_rtp_streamer_send_rtcp(GF_RTPStreamer *streamer, Bool force_ts, u32 rtp_ts); + +/*! @} */ + +#ifdef __cplusplus +} +#endif + +#endif //GPAC_DISABLE_STREAMING + +#endif /*_GF_RTPSTREAMER_H_*/ + diff --git a/include/gpac/scene_engine.h b/include/gpac/scene_engine.h new file mode 100644 index 0000000..4b0dd45 --- /dev/null +++ b/include/gpac/scene_engine.h @@ -0,0 +1,202 @@ +/* + * GPAC Multimedia Framework + * + * Authors: Cyril Concolato - Jean le Feuvre + * Copyright (c) 2005-200X ENST + * 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_SCENEENGINE_H_ +#define _GF_SCENEENGINE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <gpac/scene_manager.h> + +#ifndef GPAC_DISABLE_SENG + +typedef struct __tag_scene_engine GF_SceneEngine; + + +typedef void (*gf_seng_callback)(void *udta, u16 ESID, char *data, u32 size, u64 ts); + +/** + * @calling_object is the calling object on which call back will be called + * @inputContext is the name of a scene file (bt, xmt or mp4) to initialize the coding context + * @load_type is the prefered loader type for the content (e.g. SVG vs DIMS) + * @dump_path is the path where scenes are dumped + * @embed_resources indicates if images and scripts should be encoded inlined with the content + * + * must be called only one time (by process calling the DLL) before other calls + */ +GF_SceneEngine *gf_seng_init(void *calling_object, char *inputContext, u32 load_type, char *dump_path, Bool embed_resources); + +/** + * @calling_object is the calling object on which call back will be called + * @inputContext is an UTF-8 scene description (with or without IOD) in BT or XMT-A format + * @load_type is the prefered loader type for the content (e.g. SVG vs DIMS) + * @width, @height: width and height of scene if no IOD is given in the context. + * @usePixelMetrics: metrics system used in the scene, if no IOD is given in the context. + * @dump_path is the path where scenes are dumped + * + * must be called only one time (by process calling the DLL) before other calls + */ +GF_SceneEngine *gf_seng_init_from_string(void *calling_object, char *inputContext, u32 load_type, u32 width, u32 height, Bool usePixelMetrics, char *dump_path); + + +/** + * @calling_object is the calling object on which call back will be called + * @ctx is an already loaded scene manager + * @dump_path is the path where scenes are dumped + * + * must be called only one time (by process calling the DLL) before other calls + */ +GF_SceneEngine *gf_seng_init_from_context(void *calling_object, GF_SceneManager *ctx, char *dump_path); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * + * must be called after gf_seng_init() + */ +u32 gf_seng_get_stream_count(GF_SceneEngine *seng); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * @ESID, ID of the stream + * @carousel_period: pointer to store the carousel_period + * @aggregate_on_es_id: pointer to store the target carousel stream ID + * + * must be called after gf_seng_init() + */ +GF_Err gf_seng_get_stream_carousel_info(GF_SceneEngine *seng, u16 ESID, u32 *carousel_period, u16 *aggregate_on_es_id); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * @idx: stream index + * @ESID: pointer to the stream ID + * @config: pointer to the encoded BIFS config (memory is not allocated) + * @config_len: length of the buffer + * @streamType: pointer to get stream type + * @objectType: pointer to get object type + * @timeScale: pointer to get time scale + * + * must be called after gf_seng_init() + */ +GF_Err gf_seng_get_stream_config(GF_SceneEngine *seng, u32 idx, u16 *ESID, const char **config, u32 *config_len, u32 *streamType, u32 *objectType, u32 *timeScale); + +/** + * Encodes the AU context which is not encoded when calling BENC_EncodeAUFromString/File + * Should be called after Aggregate. + * + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * @AUCallback, pointer on a callback function to get the result of the coding the AU using the current context + * + */ +GF_Err gf_seng_encode_context(GF_SceneEngine *seng, gf_seng_callback callback); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * @ESID, target streams when no indication is present in the file (eg, no atES_ID ) + * @auFile, name of a file containing a description for an access unit (BT or XMT) + * @AUCallback, pointer on a callback function to get the result of the coding the AU using the current context + * + */ +GF_Err gf_seng_encode_from_file(GF_SceneEngine *seng, u16 ESID, Bool disable_aggregation, char *auFile, gf_seng_callback callback); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * @ESID, target streams when no indication is present in the file (eg, no atES_ID ) + * @auString, a char string to encode (must one or several complete nodes in BT + * @AUCallback, pointer on a callback function to get the result of the coding the AU using the current context + * + */ +GF_Err gf_seng_encode_from_string(GF_SceneEngine *seng, u16 ESID, Bool disable_aggregation, char *auString, gf_seng_callback callback); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * @ESID, indicates the stream to which these commands apply (0 if first scene stream) + * @commans, the list of commands to encode + * @AUCallback, pointer on a callback function to get the result of the coding the AU using the current context + * + */ +GF_Err gf_seng_encode_from_commands(GF_SceneEngine *codec, u16 ESID, Bool disable_aggregation, u32 time, GF_List *commands, gf_seng_callback callback); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * @ctxFileName, name of the file to save the current state of the BIFS scene to + * + * save the current context of the seng. + * if you want to save an aggregate context, use BENC_AggregateCurrentContext before + * + */ +GF_Err gf_seng_save_context(GF_SceneEngine *seng, char *ctxFileName); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * @ESID, stream ID + * @onESID: set stream aggragation on to the specified stream, or off if onESID is 0 + * + * marks the stream as carrying its own "rap" in the first AU of the stream + */ +GF_Err gf_seng_enable_aggregation(GF_SceneEngine *codec, u16 ESID, u16 onESID); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * + * aggregates the current context of the seng, creates a scene replace + * if @ESID is specified, only aggregate commands for this stream + */ +GF_Err gf_seng_aggregate_context(GF_SceneEngine *seng, u16 ESID); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * + * release the memory used by this seng, no more call on the seng should happen after this + * + */ +void gf_seng_terminate(GF_SceneEngine *seng); + +/** + * @seng, pointer to the GF_SceneEngine returned by gf_seng_init() + * @buf64, pointer to a buffer that will be allocated and will contain the base64 encoded version of the binary IOD + * @buf64, pointer to the size of the buffer + * + * encodes the IOD for this BIFS Engine into Base64 + * + */ +char *gf_seng_get_base64_iod(GF_SceneEngine *seng); + +GF_Descriptor *gf_seng_get_iod(GF_SceneEngine *seng); + +GF_Err gf_seng_dump_rap_on(GF_SceneEngine *seng, Bool dump_rap); + +#endif /*GPAC_DISABLE_SENG*/ + + +#ifdef __cplusplus +} +#endif // __cplusplus + + +#endif /*_GF_SCENEENGINE_H_*/ + diff --git a/include/gpac/scene_manager.h b/include/gpac/scene_manager.h index 8769a9a..e0635b4 100644 --- a/include/gpac/scene_manager.h +++ b/include/gpac/scene_manager.h @@ -31,6 +31,7 @@ extern "C" { #endif #include <gpac/isomedia.h> +#include <gpac/mpeg4_odf.h> #include <gpac/scenegraph_vrml.h> /* @@ -42,6 +43,18 @@ extern "C" { always belong to the desired NDT*/ Bool gf_node_in_table(GF_Node *node, u32 NDTType); +enum +{ + /*AU is RAP - random access indication - may be overriden by encoder*/ + GF_SM_AU_RAP = 1, + /*AU will not be aggregated (only used by scene engine)*/ + GF_SM_AU_NOT_AGGREGATED = 1<<1, + /*AU has been modified (only used by scene engine)*/ + GF_SM_AU_MODIFIED = 1<<2, + /*AU is a carousel (only used by scene engine)*/ + GF_SM_AU_CAROUSEL = 1<<3 +}; + /*generic systems access unit context*/ typedef struct { @@ -49,11 +62,11 @@ typedef struct u64 timing; /*timing in sec - used if timing isn't set*/ Double timing_sec; - /*random access indication - may be overriden by encoder*/ - Bool is_rap; /*opaque command list per stream type*/ GF_List *commands; + u32 flags; + /*pointer to owner stream*/ struct _stream_context *owner; } GF_AUContext; @@ -63,6 +76,9 @@ typedef struct _stream_context { /*ESID of stream, or 0 if unknown in which case it is automatically updated at encode stage*/ u16 ESID; + /*stream name if any (XMT), NULL otherwise*/ + char *name; + /*stream type - used as a hint, the encoder(s) may override it*/ u8 streamType; u8 objectType; @@ -74,6 +90,14 @@ typedef struct _stream_context u64 last_au_time; /*set if stream is part of root OD (playback only)*/ Bool in_root_od; + /*number of previous AUs (used in live scene encoder only)*/ + u32 current_au_count; + char *dec_cfg; + u32 dec_cfg_len; + + u16 aggregate_on_esid; + u32 carousel_period; + Bool disable_aggregation; } GF_StreamContext; /*generic presentation context*/ @@ -114,15 +138,18 @@ GF_StreamContext *gf_sm_stream_find(GF_SceneManager *ctx, u16 ES_ID); /*create a new AU context in the given stream context*/ GF_AUContext *gf_sm_stream_au_new(GF_StreamContext *stream, u64 timing, Double time_ms, Bool isRap); +GF_MuxInfo *gf_sm_get_mux_info(GF_ESD *src); + /*reset the context: - purge all access units on all streams - destroy root OD */ void gf_sm_reset(GF_SceneManager *ctx); -/*applies all commands in all streams (only BIFS for now): the context manager will only have one command per -stream, this command being a random access*/ -GF_Err gf_sm_make_random_access(GF_SceneManager *ctx); +/*applies all commands in all streams (only BIFS for now): the context manager will only have maximum one AU per +stream, this AU being a random access for the stream +if @ESID is set, aggregation is only performed on the given stream*/ +GF_Err gf_sm_aggregate(GF_SceneManager *ctx, u16 ESID); /*translates SRT/SUB (TTXT not supported) source into BIFS command stream source @src: GF_ESD of new stream (MUST be created before to store TS resolution) @@ -175,6 +202,8 @@ enum /* in this mode, each root svg tag will be interpreted as a REPLACE SCENE */ GF_SM_LOAD_CONTEXT_STREAMING = 1<<3, + /*indicates that external resources in the content should be embedded as if possible*/ + GF_SM_LOAD_EMBEDS_RES = 1<<4, }; /*loader type, usually detected based on file ext*/ @@ -185,7 +214,7 @@ enum GF_SM_LOAD_X3DV, /*X3D VRML loader*/ GF_SM_LOAD_XMTA, /*XMT-A loader*/ GF_SM_LOAD_X3D, /*X3D XML loader*/ - GF_SM_LOAD_SVG_DA, /*SVG loader with dynamic allocation of attributes */ + GF_SM_LOAD_SVG, /*SVG loader*/ GF_SM_LOAD_XSR, /*LASeR+XML loader*/ GF_SM_LOAD_DIMS, /*DIMS LASeR+XML loader*/ GF_SM_LOAD_SWF, /*SWF->MPEG-4 converter*/ @@ -194,20 +223,27 @@ enum GF_SM_LOAD_XBL }; -typedef struct +typedef struct __scene_loader GF_SceneLoader; + +struct __scene_loader { + /*loader type, one of the above value. If not set, detected based on file extension*/ + u32 type; + /*scene graph worked on - may be NULL if ctx is present*/ GF_SceneGraph *scene_graph; - struct _inline_scene *is; + struct _scene *is; /*context manager to load (MUST BE RESETED BEFORE if needed) - may be NULL for loaders not using commands, in which case the graph will be directly updated*/ GF_SceneManager *ctx; /*file to import except IsoMedia files*/ const char *fileName; +#ifndef GPAC_DISABLE_ISOM /*IsoMedia file to import (we need to be able to load from an opened file for scene stats)*/ GF_ISOFile *isom; +#endif /*swf import flags*/ u32 swf_import_flags; /*swf flatten limit: angle limit below which 2 lines are considered as aligned, @@ -220,11 +256,15 @@ typedef struct /*loader flags*/ u32 flags; + u16 force_es_id; + /*private to loader*/ void *loader_priv; - /*loader type, one of the above value. If not set, detected based on file extension*/ - u32 type; -} GF_SceneLoader; + GF_Err (*process)(GF_SceneLoader *loader); + void (*done)(GF_SceneLoader *loader); + GF_Err (*parse_string)(GF_SceneLoader *loader, char *str); + GF_Err (*suspend)(GF_SceneLoader *loader, Bool suspend); +}; /*initializes the context loader - this will load any IOD and the first frame of the main scene*/ GF_Err gf_sm_load_init(GF_SceneLoader *load); @@ -232,6 +272,8 @@ GF_Err gf_sm_load_init(GF_SceneLoader *load); GF_Err gf_sm_load_run(GF_SceneLoader *load); /*terminates the context loader*/ void gf_sm_load_done(GF_SceneLoader *load); +/*suspends/resume context loading*/ +GF_Err gf_sm_load_suspend(GF_SceneLoader *load, Bool suspend); /*parses memory scene (any textural format) into the context !! THE LOADER TYPE MUST BE ASSIGNED (BT/WRL/XMT/X3D/SVG only) !! @@ -242,41 +284,7 @@ to clean ressources (needed for SAX progressive loading) */ GF_Err gf_sm_load_string(GF_SceneLoader *load, char *str, Bool clean_at_end); - -/*scene dump mode*/ -enum -{ - /*BT*/ - GF_SM_DUMP_BT = 0, - /*XMT-A*/ - GF_SM_DUMP_XMTA, - /*VRML Text (WRL)*/ - GF_SM_DUMP_VRML, - /*X3D Text (x3dv)*/ - GF_SM_DUMP_X3D_VRML, - /*X3D XML*/ - GF_SM_DUMP_X3D_XML, - /*LASeR XML*/ - GF_SM_DUMP_LASER, - /*SVG dump (only dumps svg root of the first LASeR unit*/ - GF_SM_DUMP_SVG, - /*blind XML dump*/ - GF_SM_DUMP_XML, - /*automatic selection of MPEG4 vs X3D, text mode*/ - GF_SM_DUMP_AUTO_TXT, - /*automatic selection of MPEG4 vs X3D, xml mode*/ - GF_SM_DUMP_AUTO_XML, -}; - -#ifndef GPAC_READ_ONLY - -/*dumps scene context to BT or XMT -@rad_name: file name & loc without extension - if NULL dump will happen in stdout -@dump_mode: one of the above*/ -GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode); - -#endif - +#ifndef GPAC_DISABLE_SCENE_ENCODER /*encoding flags*/ enum @@ -316,8 +324,44 @@ if @log is set, generates BIFS encoder log file */ GF_Err gf_sm_encode_to_file(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEncodeOptions *opt); +#endif /*GPAC_DISABLE_SCENE_ENCODER*/ + + /*Dumping tools*/ +#ifndef GPAC_DISABLE_SCENE_DUMP + +/*scene dump mode*/ +enum +{ + /*BT*/ + GF_SM_DUMP_BT = 0, + /*XMT-A*/ + GF_SM_DUMP_XMTA, + /*VRML Text (WRL)*/ + GF_SM_DUMP_VRML, + /*X3D Text (x3dv)*/ + GF_SM_DUMP_X3D_VRML, + /*X3D XML*/ + GF_SM_DUMP_X3D_XML, + /*LASeR XML*/ + GF_SM_DUMP_LASER, + /*SVG dump (only dumps svg root of the first LASeR unit*/ + GF_SM_DUMP_SVG, + /*blind XML dump*/ + GF_SM_DUMP_XML, + /*automatic selection of MPEG4 vs X3D, text mode*/ + GF_SM_DUMP_AUTO_TXT, + /*automatic selection of MPEG4 vs X3D, xml mode*/ + GF_SM_DUMP_AUTO_XML, +}; + +/*dumps scene context to BT or XMT +@rad_name: file name & loc without extension - if NULL dump will happen in stdout +@dump_mode: one of the above*/ +GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode); + typedef struct _scenedump GF_SceneDumper; + /*create a scene dumper @graph: scene graph being dumped @rad_name: file radical (NULL for stdout) - if not NULL MUST BE GF_MAX_PATH length @@ -328,6 +372,11 @@ returns NULL if can't create a file GF_SceneDumper *gf_sm_dumper_new(GF_SceneGraph *graph, char *rad_name, char indent_char, Bool XMLDump); void gf_sm_dumper_del(GF_SceneDumper *bd); +/*gets a pointer to the filename (rad+ext) of the dumped file +returns null if no file has been dumped +*/ +char *gf_sm_dump_get_name(GF_SceneDumper *bd); + /*dumps commands list @indent: indent to use @skip_replace_scene_header: if set and dumping in BT mode, the initial REPLACE SCENE header is skipped @@ -340,8 +389,9 @@ GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 inde */ GF_Err gf_sm_dump_graph(GF_SceneDumper *sdump, Bool skip_proto, Bool skip_routes); +#endif /*GPAC_DISABLE_SCENE_DUMP*/ -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_SCENE_STATS /*stat object - to refine :)*/ @@ -362,6 +412,7 @@ typedef struct typedef struct _scenestat { GF_List *node_stats; + GF_List *proto_stats; /*ranges of all SFVec2fs for points only (MFVec2fs)*/ @@ -417,7 +468,7 @@ GF_Err gf_sm_stats_for_scene(GF_StatManager *stat, GF_SceneManager *sm); /*produces stat report for the given command*/ GF_Err gf_sm_stats_for_command(GF_StatManager *stat, GF_Command *com); -#endif +#endif /*GPAC_DISABLE_SCENE_STATS*/ #ifdef __cplusplus diff --git a/include/gpac/scenegraph.h b/include/gpac/scenegraph.h index d4e7742..e63d46e 100644 --- a/include/gpac/scenegraph.h +++ b/include/gpac/scenegraph.h @@ -1,3 +1,4 @@ + /* * GPAC - Multimedia Framework C SDK * @@ -212,10 +213,13 @@ u32 gf_node_get_num_instances(GF_Node *node); /*calls node traverse callback routine on this node*/ void gf_node_traverse(GF_Node *node, void *udta); -/*allows a node to be re-rendered - by default a node in its render phase will never be rendered a second time. -Use this function to enable a second render for this node - this must be called while node is being rendered*/ +/*allows a node to be re-rendered - by default a node in its render phase will never be retraversed a second time. +Use this function to enable a second traverse for this node while traversing the node*/ void gf_node_allow_cyclic_traverse(GF_Node *node); +/*sets the cyclic travers flag - returns 0 if flag was already set*/ +Bool gf_node_set_cyclic_traverse_flag(GF_Node *node, Bool on); + /*blindly calls traverse callback on all children nodes */ void gf_node_traverse_children(GF_Node *node, void *renderStack); /*returns number of parent for this node (parent are kept regardless of DEF state)*/ @@ -224,6 +228,8 @@ u32 gf_node_get_parent_count(GF_Node *node); idx is 0-based parent index*/ GF_Node *gf_node_get_parent(GF_Node *node, u32 idx); +/*returns 1 if target node is in the subtree below the node, 0 otherwise*/ +Bool gf_node_parent_of(GF_Node *node, GF_Node *target); enum { @@ -246,7 +252,7 @@ enum /*SVG-specific flags due to mix of geometry and appearance & co attributes*/ /*SVG geometry changed is the same as base flag*/ GF_SG_SVG_GEOMETRY_DIRTY = GF_SG_NODE_DIRTY, - GF_SG_SVG_COLOR_DIRTY = GF_SG_VRML_BINDABLE_DIRTY, + GF_SG_SVG_COLOR_DIRTY = 1<<2, GF_SG_SVG_DISPLAYALIGN_DIRTY = 1<<3, GF_SG_SVG_FILL_DIRTY = 1<<4, GF_SG_SVG_FILLOPACITY_DIRTY = 1<<5, @@ -310,6 +316,8 @@ In case an implementation does not use this: content) otherwise the app is guaranteed to crash. */ +typedef struct _route GF_Route; + /*other fieldTypes may be ignored by implmentation not using VRML/MPEG4 native types*/ typedef struct @@ -327,7 +335,7 @@ typedef struct /*event type*/ u32 eventType; /*eventin handler if any*/ - void (*on_event_in)(GF_Node *pNode); + void (*on_event_in)(GF_Node *pNode, GF_Route *from_route); } GF_FieldInfo; /*returns number of field for this node*/ @@ -453,7 +461,13 @@ enum typedef struct { - const char *url; + /*for GF_JSAPI_OP_RESOLVE_URI, + set by caller to the URI to resolve. + If NULL, the return URI is the unresolved parent scene one. + Otherwise, the input URL will be reolved to its local name (eg for ZIP/... packages) + upon return, ALLOCATED by the callee and must be freed by the caller + */ + char *url; const char **params; u32 nb_params; } GF_JSAPIURI; @@ -495,8 +509,8 @@ enum { /*!push message from script engine.*/ GF_JSAPI_OP_MESSAGE, - /*!get scene URI.*/ - GF_JSAPI_OP_GET_SCENE_URI, + /*!resolves a given URI.*/ + GF_JSAPI_OP_RESOLVE_URI, /*!get current user agent scale.*/ GF_JSAPI_OP_GET_SCALE, /*!set current user agent scale.*/ @@ -547,9 +561,6 @@ enum GF_JSAPI_OP_GET_SUBSCENE, /*!resolves relative Xlink based on xml:base*/ GF_JSAPI_OP_RESOLVE_XLINK, - /*!evaluates if the given IRI is available for playback (returns 1) or not. If the IRI is - NULL, this evaluates whether the scene is ready for composition (canvas setup) or not.*/ - GF_JSAPI_OP_EVAL_IRI, /*!gets GPAC terminal*/ GF_JSAPI_OP_GET_TERM, @@ -558,6 +569,9 @@ enum GF_JSAPI_OP_PAUSE_SVG, /*!resumes an SVG ELEMENT*/ GF_JSAPI_OP_RESUME_SVG, + /*!gets the DPI*/ + GF_JSAPI_OP_GET_DPI_X, + GF_JSAPI_OP_GET_DPI_Y, }; /* interface to various get/set options: @@ -578,6 +592,8 @@ void gf_sg_script_load(GF_Node *script); Bool gf_sg_has_scripting(); +char *gf_node_dump_attribute(GF_Node *elt, GF_FieldInfo *info); + /* scene graph command tools used for BIFS and LASeR @@ -591,8 +607,12 @@ Bool gf_sg_has_scripting(); */ enum { + GF_SG_RESERVED = 0, + +#ifndef GPAC_DISABLE_VRML + /*BIFS commands*/ - GF_SG_SCENE_REPLACE = 0, + GF_SG_SCENE_REPLACE, GF_SG_NODE_REPLACE, GF_SG_FIELD_REPLACE, GF_SG_INDEXED_REPLACE, @@ -614,9 +634,9 @@ enum GF_SG_NODE_DELETE_EX, /*BIFS*/ - GF_SG_FIELD_REPLACE_OP, - GF_SG_INDEXED_REPLACE_OP, + GF_SG_XREPLACE, +#endif GF_SG_LAST_BIFS_COMMAND, @@ -682,51 +702,54 @@ typedef struct /*for authoring purposes - must be cleaned by user*/ Bool unresolved; char *unres_name; - - /*scene replace command: - root node is stored in com->node - protos are stored in com->new_proto_list - routes are stored as RouteInsert in the same frame - BIFS only - */ - Bool use_names; + + + union { + /*scene replace command: + root node is stored in com->node + protos are stored in com->new_proto_list + routes are stored as RouteInsert in the same frame + BIFS only + */ + Bool use_names; + u32 RouteID; + s32 ChildNodeTag; + }; /*proto list to insert - BIFS only*/ GF_List *new_proto_list; /*proto ID list to delete - BIFS only*/ u32 *del_proto_list; - u32 del_proto_list_size; - - - /*route insert, replace and delete (BIFS only) - fromNodeID is also used to identify operandElementId in LASeR Add/Replace + union { + u32 del_proto_list_size; + u32 child_field; + }; - OR - sendEvent - */ -// union { - u32 RouteID; - u32 send_event_name; -// }; -// union { + union { char *def_name; char *send_event_string; -// }; -// union { + }; + union { + //route insertion - fromNodeID is also used to identify operandElementId in LASeR Add/Replace u32 fromNodeID; s32 send_event_integer; -// }; - u32 fromFieldIndex; + }; + union { + u32 fromFieldIndex; + u32 send_event_name; + }; -// union { + union { u32 toNodeID; s32 send_event_x; -// }; -// union { + }; + union { u32 toFieldIndex; s32 send_event_y; -// }; + }; Bool aggregated; + /*some commands need to never be applied; for instance when building an aggregate carrousel*/ + Bool never_apply; } GF_Command; @@ -742,10 +765,6 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *inScene, GF_Command *com, Double time_ GF_Err gf_sg_command_apply_list(GF_SceneGraph *graph, GF_List *comList, Double time_offset); /*returns new commandFieldInfo structure and registers it with command*/ GF_CommandField *gf_sg_command_field_new(GF_Command *com); -/*clones the command in another graph - needed for uncompressed conditional in protos -if force_clone is not set and the target graph is the same as the command graph, nodes are just registered -with the new commands rather than cloned*/ -GF_Command *gf_sg_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool force_clone); #ifdef __cplusplus } diff --git a/include/gpac/scenegraph_svg.h b/include/gpac/scenegraph_svg.h index 2d5d534..e80dfbd 100644 --- a/include/gpac/scenegraph_svg.h +++ b/include/gpac/scenegraph_svg.h @@ -32,6 +32,7 @@ extern "C" { #include <gpac/scenegraph.h> #include <gpac/svg_types.h> + /******************************************************************************* * * DOM base scene graph @@ -113,6 +114,10 @@ enum TAG_XBL_ATT_command, TAG_XBL_ATT_preventdefault, TAG_XBL_ATT_src, + + TAG_GSVG_ATT_useAsPrimary, + TAG_GSVG_ATT_depthOffset, + TAG_GSVG_ATT_depthGain, }; @@ -154,12 +159,10 @@ typedef struct __dom_full_node u32 ns; } GF_DOMFullNode; - - enum { - /*no NS specified, it will be evaluated from attribute/node name*/ - GF_XMLNS_NONE, + /*XMLNS is undefined*/ + GF_XMLNS_UNDEFINED = 0, GF_XMLNS_XML, GF_XMLNS_XLINK, @@ -168,9 +171,14 @@ enum GF_XMLNS_SVG, GF_XMLNS_XBL, + GF_XMLNS_SVG_GPAC_EXTENSION, + /*any other namespace uses the CRC32 of the namespace as an identifier*/ }; +/*returns the built-in XMLNS id for this namespace if known, otherwise returns GF_XMLNS_UNDEFINED*/ +u32 gf_xml_get_namespace_id(char *name); + GF_Err gf_sg_add_namespace(GF_SceneGraph *sg, char *name, char *qname); GF_Err gf_sg_remove_namespace(GF_SceneGraph *sg, char *name, char *qname); u32 gf_sg_get_namespace_code(GF_SceneGraph *sg, char *qname); @@ -205,6 +213,12 @@ typedef struct /*creates a new text node, assign string (does NOT duplicate it) and register node with parent if desired*/ GF_DOMText *gf_dom_add_text_node(GF_Node *parent, char *text_data); +/*replace text content of node by the specified string - if string is NULL, only resets the children of the node*/ +void gf_dom_set_textContent(GF_Node *n, char *text); + +/*flatten text content of the node and returns the result - result shall be free'ed by the caller*/ +char *gf_dom_flatten_textContent(GF_Node *n); + /*creates a new text node - this DOES NOT register the node at all*/ GF_DOMText *gf_dom_new_text_node(GF_SceneGraph *sg); @@ -240,6 +254,7 @@ enum GF_DOM_EVENT_PHASE_AT_TARGET = 2, GF_DOM_EVENT_PHASE_BUBBLE = 3, + GF_DOM_EVENT_CANCEL_MASK = 0xE0, /*special phase indicating the event has been canceled*/ GF_DOM_EVENT_PHASE_CANCEL = 1<<5, /*special phase indicating the event has been canceled immediately*/ @@ -265,7 +280,7 @@ typedef struct u32 ptr_type; } GF_DOMEventTarget; -GF_Err gf_dom_listener_add(GF_Node *listener, GF_DOMEventTarget *evt_target); +GF_Err gf_sg_listener_add(GF_Node *listener, GF_DOMEventTarget *evt_target); typedef struct @@ -323,6 +338,9 @@ typedef struct /*number of listeners triggered by the event*/ u32 consumed; + + /*for GF_EVENT_ATTR_MODIFIED*/ + GF_FieldInfo *attr; } GF_DOM_Event; /*fires event on the specified node @@ -356,7 +374,7 @@ typedef struct __xml_ev_handler /*target EventListener object (this) */ void *evt_listen_obj; /*function value for spidermonkey - we cannot use JS_CallFunction since it does not work on closures - we use 64 bits to store the value for portability safety */ + we use 64 bits to store the value for portability safety*/ u64 js_fun_val; /*compiled function for the case were CallFunction is needed*/ void *js_fun; @@ -543,8 +561,8 @@ char *gf_svg_attribute_type_to_string(u32 att_type); GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_content, u8 anim_value_type); void gf_svg_parse_style(GF_Node *n, char *style); -GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue); -GF_Err gf_svg_dump_attribute_indexed(GF_Node *elt, GF_FieldInfo *info, char *attValue); +char *gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info); +char *gf_svg_dump_attribute_indexed(GF_Node *elt, GF_FieldInfo *info); void gf_svg_path_build(GF_Path *path, GF_List *commands, GF_List *points); @@ -557,7 +575,7 @@ u32 gf_svg_get_system_paint_server_type(const char *name); Bool gf_smil_notify_timed_elements(GF_SceneGraph *sg); void gf_smil_timing_insert_clock(GF_Node *elt, Bool is_end, Double clock); -void gf_svg_parse_transformlist(GF_Matrix2D *mat, char *attribute_content); +Bool gf_svg_parse_transformlist(GF_Matrix2D *mat, char *attribute_content); typedef struct _smil_timing_rti SMIL_Timing_RTI; diff --git a/include/gpac/scenegraph_vrml.h b/include/gpac/scenegraph_vrml.h index c6edb49..fe99993 100644 --- a/include/gpac/scenegraph_vrml.h +++ b/include/gpac/scenegraph_vrml.h @@ -163,6 +163,10 @@ typedef struct { unsigned char* script_text; } SFScript; +typedef struct { + GF_Node *node; + u32 fieldIndex; +} SFAttrRef; /* MF Types */ @@ -243,6 +247,11 @@ typedef struct { SFScript *vals; } MFScript; +typedef struct { + u32 count; + SFAttrRef* vals; +} MFAttrRef; + SFColorRGBA gf_sg_sfcolor_to_rgba(SFColor val); @@ -287,9 +296,13 @@ enum GF_SG_VRML_MFNODE, GF_SG_VRML_MFVEC4F, + GF_SG_VRML_SFATTRREF = 45, + GF_SG_VRML_MFATTRREF = 46, + /*used types in GPAC but not defined in the MPEG4 spec*/ GF_SG_VRML_MFURL, GF_SG_VRML_MFSCRIPT, + GF_SG_VRML_MFCOMMANDBUFFER, /*used types in X3D*/ GF_SG_VRML_MFDOUBLE, @@ -297,59 +310,59 @@ enum GF_SG_VRML_MFVEC2D, GF_SG_VRML_MFVEC3D, + /*special event only used in routes for binding eventOut/exposedFields to script functions. + A route with ToField.FieldType set to this value holds a pointer to a function object. + */ + GF_SG_VRML_SCRIPT_FUNCTION, + + GF_SG_VRML_UNKNOWN }; -const char *gf_sg_vrml_get_field_type_by_name(u32 FieldType); -/* -allocates a new field and gets it back. - NOTE: - GF_SG_VRML_MFNODE will return a pointer to a GF_List structure (eg GF_List *) - GF_SG_VRML_SFNODE will return NULL -*/ -void *gf_sg_vrml_field_pointer_new(u32 FieldType); -/*deletes a field pointer (including SF an,d MF nodes)*/ -void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType); - Bool gf_sg_vrml_is_sf_field(u32 FieldType); /*translates MF/SF to SF type*/ u32 gf_sg_vrml_get_sf_type(u32 FieldType); -/* - MFField manipulation - MFNode cannot use these, use the GF_List functions instead - or the Node_* insertion functions - FieldType shall always be given when manipulating MFFields -*/ /*Insert (+alloc) a slot in the MFField with a specified position for insertion and sets the ptr to the newly created slot @InsertAt is the 0-based index for the new slot */ GF_Err gf_sg_vrml_mf_insert(void *mf, u32 FieldType, void **new_ptr, u32 InsertAt); -/*adds at the end and gets the ptr*/ -GF_Err gf_sg_vrml_mf_append(void *mf, u32 FieldType, void **new_ptr); -/*remove the desired item*/ -GF_Err gf_sg_vrml_mf_remove(void *mf, u32 FieldType, u32 RemoveFrom); -/*alloc a fixed array*/ -GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems); -/*get the item in the array*/ -GF_Err gf_sg_vrml_mf_get_item(void *mf, u32 FieldType, void **new_ptr, u32 ItemPos); /*remove all items of the MFField*/ GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType); -/*clones a field content EXCEPT SF/MFNode. Pointers to field shall be used -@dest, @orig: pointers to field -@FieldType: type of the field +/*exported for URL handling in compositor*/ +void gf_sg_mfurl_del(MFURL url); +void gf_sg_vrml_copy_mfurl(MFURL *dst, MFURL *src); +/*exported for 3D camera in compositor*/ +SFRotation gf_sg_sfrotation_interpolate(SFRotation kv1, SFRotation kv2, Fixed fraction); + +/*adds a new node to the "children" field +position is the 0-BASED index in the list of children, -1 means end of list (append) +DOES NOT CHECK CHILD/PARENT type compatibility */ -void gf_sg_vrml_field_copy(void *dest, void *orig, u32 FieldType); +GF_Err gf_node_insert_child(GF_Node *parent, GF_Node *new_child, s32 Position); +/*removes an existing node from the "children" field*/ +GF_Err gf_node_remove_child(GF_Node *parent, GF_Node *toremove_child); +/*remove and replace given child by specified node. If node is NULL, only delete target node +position is the 0-BASED index in the list of children, -1 means end of list (append) +DOES NOT CHECK CHILD/PARENT type compatibility +*/ +GF_Err gf_node_replace_child(GF_Node *node, GF_ChildNodeItem **container, s32 pos, GF_Node *newNode); -/*indicates whether 2 fields of same type EXCEPT SF/MFNode are equal -@dest, @orig: pointers to field -@FieldType: type of the field +/*set proto loader - callback is the same as simulation time callback + GetExternProtoLib is a pointer to the proto lib loader - this callback shall return the LPSCENEGRAPH +of the extern proto lib if found and loaded, NULL if not found and GF_SG_INTERNAL_PROTO for internal +hardcoded protos (extensions of MPEG-4 scene graph used for module deveopment) */ -Bool gf_sg_vrml_field_equal(void *dest, void *orig, u32 FieldType); +#define GF_SG_INTERNAL_PROTO (GF_SceneGraph *) 0xFFFFFFFF + + +#ifndef GPAC_DISABLE_VRML + @@ -372,9 +385,9 @@ children: list of children SFNodes #define VRML_CHILDREN \ CHILDREN \ GF_ChildNodeItem *addChildren; \ - void (*on_addChildren)(GF_Node *pNode); \ + void (*on_addChildren)(GF_Node *pNode, struct _route *route); \ GF_ChildNodeItem *removeChildren; \ - void (*on_removeChildren)(GF_Node *pNode); \ + void (*on_removeChildren)(GF_Node *pNode, struct _route *route); \ typedef struct { @@ -386,16 +399,54 @@ void gf_sg_vrml_parent_setup(GF_Node *pNode); void gf_sg_vrml_parent_destroy(GF_Node *pNode); -/*set proto loader - callback is the same as simulation time callback - GetExternProtoLib is a pointer to the proto lib loader - this callback shall return the LPSCENEGRAPH -of the extern proto lib if found and loaded, NULL if not found and GF_SG_INTERNAL_PROTO for internal -hardcoded protos (extensions of MPEG-4 scene graph used for module deveopment) +Bool gf_node_in_table_by_tag(u32 tag, u32 NDTType); + + +const char *gf_sg_vrml_get_field_type_by_name(u32 FieldType); + + +/* +allocates a new field and gets it back. + NOTE: + GF_SG_VRML_MFNODE will return a pointer to a GF_List structure (eg GF_List *) + GF_SG_VRML_SFNODE will return NULL */ -#define GF_SG_INTERNAL_PROTO (GF_SceneGraph *) 0xFFFFFFFF +void *gf_sg_vrml_field_pointer_new(u32 FieldType); +/*deletes a field pointer (including SF an,d MF nodes)*/ +void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType); + + +/*adds at the end and gets the ptr*/ +GF_Err gf_sg_vrml_mf_append(void *mf, u32 FieldType, void **new_ptr); +/*remove the desired item*/ +GF_Err gf_sg_vrml_mf_remove(void *mf, u32 FieldType, u32 RemoveFrom); +/*alloc a fixed array*/ +GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems); +/*get the item in the array*/ +GF_Err gf_sg_vrml_mf_get_item(void *mf, u32 FieldType, void **new_ptr, u32 ItemPos); + +/*copies a field content EXCEPT SF/MFNode. Pointers to field shall be used +@dest, @orig: pointers to field +@FieldType: type of the field +*/ +void gf_sg_vrml_field_copy(void *dest, void *orig, u32 FieldType); + +/*clones a field content EXCEPT SF/MFNode. Pointers to field shall be used +@dest, @orig: pointers to field +@FieldType: type of the field +@inScene: target scene graph for SFCommandBuffers cloning +*/ +void gf_sg_vrml_field_clone(void *dest, void *orig, u32 FieldType, GF_SceneGraph *inScene); + +/*indicates whether 2 fields of same type EXCEPT SF/MFNode are equal +@dest, @orig: pointers to field +@FieldType: type of the field +*/ +Bool gf_sg_vrml_field_equal(void *dest, void *orig, u32 FieldType); + /*GF_Route manip: routes are used to pass events between nodes. Event handling is managed by the scene graph however only the nodes overloading the EventIn handler associated with the event will process the eventIn*/ -typedef struct _route GF_Route; /*creates a new route: @fromNode: @fromField: address of the eventOut field triggering the route @@ -583,24 +634,6 @@ void gf_sg_set_proto_loader(GF_SceneGraph *scene, GF_SceneGraph *(*GetExternProt /*get a pointer to the MF URL field for externProto info - DO NOT TOUCH THIS FIELD*/ MFURL *gf_sg_proto_get_extern_url(GF_Proto *proto); -SFRotation gf_sg_sfrotation_interpolate(SFRotation kv1, SFRotation kv2, Fixed fraction); - - - - -/*adds a new node to the "children" field -position is the 0-BASED index in the list of children, -1 means end of list (append) -DOES NOT CHECK CHILD/PARENT type compatibility -*/ -GF_Err gf_node_insert_child(GF_Node *parent, GF_Node *new_child, s32 Position); -/*removes an existing node from the "children" field*/ -GF_Err gf_node_remove_child(GF_Node *parent, GF_Node *toremove_child); -/*remove and replace given child by specified node. If node is NULL, only delete target node -position is the 0-BASED index in the list of children, -1 means end of list (append) -DOES NOT CHECK CHILD/PARENT type compatibility -*/ -GF_Err gf_node_replace_child(GF_Node *node, GF_ChildNodeItem **container, s32 pos, GF_Node *newNode); - /*signals eventOut has been set. FieldIndex/eventName identify the eventOut field. Routes are automatically triggered when the event is signaled*/ void gf_node_event_out(GF_Node *node, u32 FieldIndex); @@ -609,10 +642,21 @@ void gf_node_event_out_str(GF_Node *node, const char *eventName); /*exported for parsers*/ u32 gf_node_mpeg4_type_by_class_name(const char *node_name); + +#ifndef GPAC_DISABLE_X3D u32 gf_node_x3d_type_by_class_name(const char *node_name); +#endif + + +#endif /*GPAC_DISABLE_VRML*/ + + +/*returns 1 if proto is a hardcoded proto acting as a grouping node*/ +Bool gf_node_proto_is_grouping(GF_Node *node); + +/*tags a hardcoded proto as being a grouping node*/ +GF_Err gf_node_proto_set_grouping(GF_Node *node); -/*exported for URL handling in compositor*/ -void gf_sg_mfurl_del(MFURL url); #ifdef __cplusplus } diff --git a/include/gpac/setup.h b/include/gpac/setup.h index cf07b73..201dc2c 100644 --- a/include/gpac/setup.h +++ b/include/gpac/setup.h @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -29,19 +29,17 @@ extern "C" { #endif - -/*WIN32 and WinCE config*/ -#if defined(WIN32) || defined(_WIN32_WCE) - +/*This is to handle cases where config.h is generated at the root of the gpac build tree (./configure) +This is only needed when building libgpac and modules when libgpac is not installed*/ #ifdef GPAC_HAVE_CONFIG_H - -#if defined(__GNUC__) -#include <gpac/internal/config.h> +# include "config.h" #else -#include <gpac/internal/config_static.h> +# include <gpac/configuration.h> #endif -#endif + +/*WIN32 and WinCE config*/ +#if defined(WIN32) || defined(_WIN32_WCE) /*common win32 parts*/ #include <stdio.h> @@ -69,16 +67,6 @@ typedef char s8; /*WINCE config*/ #if defined(_WIN32_WCE) -/*winCE read-only (smaller)*/ -#ifndef GPAC_READ_ONLY -#define GPAC_READ_ONLY -#endif - -/*winCE always fixed-point*/ -#ifndef GPAC_FIXED_POINT -#define GPAC_FIXED_POINT -#endif - /*win32 assert*/ #ifndef assert @@ -102,6 +90,8 @@ void CE_CharToWide(char *str, unsigned short *w_str); #define stricmp _stricmp #define strnicmp _strnicmp #define strupr _strupr +#define mkdir _mkdir + #ifndef _PTRDIFF_T_DEFINED typedef int ptrdiff_t; @@ -125,8 +115,9 @@ typedef unsigned int size_t; #define strupr _strupr #define strlwr _strlwr -//#define GPAC_DISABLE_LOG - +/* +#define GPAC_DISABLE_LOG +*/ #else /*END WINCE*/ /*WIN32 not-WinCE*/ @@ -163,22 +154,19 @@ typedef unsigned int size_t; typedef unsigned __int64 u64; typedef __int64 s64; -#else +#else /*FIXME - we don't have 64bit support here we should get rid of all 64bits divisions*/ -//typedef unsigned long long u64; -//typedef long long s64; +/* +typedef unsigned long long u64; +typedef long long s64; +*/ typedef unsigned int u64; typedef signed int s64; #endif /*symbian 8*/ -/*SYMBIAN always fixed-point*/ -#ifndef GPAC_FIXED_POINT -#define GPAC_FIXED_POINT -#endif - typedef unsigned int u32; typedef unsigned short u16; @@ -221,15 +209,10 @@ char * my_str_lwr(char *str); /*end SYMBIAN config*/ -#else +#else /*UNIX likes*/ -#ifdef GPAC_HAVE_CONFIG_H -#include "config.h" -#endif - - /*force large file support*/ #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 @@ -325,40 +308,59 @@ typedef u8 bin128[16]; typedef u32 Bool; #endif + /*GPAC memory tracking*/ -#define GPAC_MEMORY_TRACKING 0 +#if defined(GPAC_MEMORY_TRACKING) + +void *gf_mem_malloc(size_t size, char *filename, int line); +void *gf_mem_calloc(size_t num, size_t size_of, char *filename, int line); +void *gf_mem_realloc(void *ptr, size_t size, char *filename, int line); +void gf_mem_free(void *ptr, char *filename, int line); +char *gf_mem_strdup(const char *str, char *filename, int line); +void gf_memory_print(void); /*prints the state of current allocations*/ -#if GPAC_MEMORY_TRACKING -void *gf_malloc(size_t size); -void *gf_realloc(void *ptr, size_t size); -void gf_free(void *ptr); -char *gf_strdup(const char *str); +#define gf_free(ptr) gf_mem_free(ptr, __FILE__, __LINE__) +#define gf_malloc(size) gf_mem_malloc(size, __FILE__, __LINE__) +#define gf_calloc(num, size_of) gf_mem_calloc(num, size_of, __FILE__, __LINE__) +#define gf_strdup(s) gf_mem_strdup(s, __FILE__, __LINE__) +#define gf_realloc(ptr1, ptr2) gf_mem_realloc(ptr1, ptr2, __FILE__, __LINE__) + +#else -#undef malloc -#define malloc gf_malloc -#undef realloc -#define realloc gf_realloc -#undef free -#define free gf_free -#undef strdup -#define strdup gf_strdup +#define gf_malloc malloc +#define gf_calloc calloc +#define gf_realloc realloc +#define gf_free free +#define gf_strdup strdup #endif + + /*end GPAC memory tracking*/ -#if defined (WIN32) && !defined(__GNUC__) +#if (defined (WIN32) || defined (_WIN32_WCE)) && !defined(__GNUC__) #define LLD "%I64d" #define LLU "%I64u" +#define LLX "%I64x" #define LLD_CAST #define LLU_CAST #elif defined (__SYMBIAN32__) #define LLD "%d" #define LLU "%u" +#define LLX "%x" #define LLD_CAST (u32) #define LLU_CAST (s32) #else +#ifdef _LP64 /*Unix 64 bits*/ +#define LLD "%ld" +#define LLU "%lu" +#define LLX "%lx" +#else /*Unix 32 bits*/ #define LLD "%lld" #define LLU "%llu" +#define LLX "%llx" +#endif + #define LLD_CAST #define LLU_CAST #endif @@ -366,7 +368,88 @@ char *gf_strdup(const char *str); #ifndef GF_EXPORT /*use def files for windows or let compiler decide*/ -#define GF_EXPORT +#define GF_EXPORT +#endif + + + + +/*safety checks on macros*/ + +#ifdef GPAC_DISABLE_VRML +# ifndef GPAC_DISABLE_BIFS +# define GPAC_DISABLE_BIFS +# endif +# ifndef GPAC_DISABLE_QTVR +# define GPAC_DISABLE_QTVR +# endif +# ifndef GPAC_DISABLE_X3D +# define GPAC_DISABLE_X3D +# endif +# ifndef GPAC_DISABLE_LOADER_BT +# define GPAC_DISABLE_LOADER_BT +# endif +# ifndef GPAC_DISABLE_LOADER_XMT +# define GPAC_DISABLE_LOADER_XMT +# endif +#endif + +#ifdef GPAC_DISABLE_SVG +# ifndef GPAC_DISABLE_LASER +# define GPAC_DISABLE_LASER +# endif +#endif + + +#ifdef GPAC_DISABLE_AV_PARSERS +# ifndef GPAC_DISABLE_MPEG2PS +# define GPAC_DISABLE_MPEG2PS +# endif +#endif + +#ifdef GPAC_DISABLE_ISOM +# ifndef GPAC_DISABLE_ISOM_WRITE +# define GPAC_DISABLE_ISOM_WRITE +# endif +# ifndef GPAC_DISABLE_ISOM_HINTING +# define GPAC_DISABLE_ISOM_HINTING +# endif +# ifndef GPAC_DISABLE_ISOM_FRAGMENTS +# define GPAC_DISABLE_ISOM_FRAGMENTS +# endif +# ifndef GPAC_DISABLE_SCENE_ENCODER +# define GPAC_DISABLE_SCENE_ENCODER +# endif +# ifndef GPAC_DISABLE_ISOM_DUMP +# define GPAC_DISABLE_ISOM_DUMP +# endif +#endif + +#ifdef GPAC_DISABLE_ISOM_WRITE +# ifndef GPAC_DISABLE_MEDIA_IMPORT +# define GPAC_DISABLE_MEDIA_IMPORT +# endif +#endif + +#ifdef GPAC_DISABLE_STREAMING +# ifndef GPAC_DISABLE_ISOM_HINTING +# define GPAC_DISABLE_ISOM_HINTING +# endif +#endif + +#ifdef GPAC_DISABLE_BIFS +# ifndef GPAC_DISABLE_BIFS_ENC +# define GPAC_DISABLE_BIFS_ENC +# endif +#endif + +#if defined(GPAC_DISABLE_BIFS_ENC) && defined(GPAC_DISABLE_LASER) +# ifndef GPAC_DISABLE_LOADER_ISOM +# define GPAC_DISABLE_LOADER_ISOM +# endif +# ifndef GPAC_DISABLE_SENG +# define GPAC_DISABLE_SENG +# endif #endif diff --git a/include/gpac/svg_types.h b/include/gpac/svg_types.h index b830cd7..43f8ae4 100644 --- a/include/gpac/svg_types.h +++ b/include/gpac/svg_types.h @@ -86,6 +86,7 @@ enum { SVG_SpreadMethod_datatype, SVG_TextAlign_datatype, SVG_Focusable_datatype, + SVG_Filter_TransferType_datatype, SMIL_SyncBehavior_datatype, SMIL_SyncTolerance_datatype, SMIL_AttributeType_datatype, @@ -611,11 +612,12 @@ enum { typedef struct { u32 count; Fixed* vals; -} Array; + u8 *units; +} UnitArray; typedef struct { u8 type; - Array array; + UnitArray array; } SVG_StrokeDashArray; enum { @@ -853,6 +855,15 @@ enum { }; typedef u8 SVG_Focusable; +enum +{ + SVG_FILTER_TRANSFER_IDENTITY, + SVG_FILTER_TRANSFER_TABLE, + SVG_FILTER_TRANSFER_DISCRETE, + SVG_FILTER_TRANSFER_LINEAR, + SVG_FILTER_TRANSFER_GAMMA +}; +typedef u8 SVG_Filter_TransferType; enum { SVG_SPREAD_PAD = 0, diff --git a/include/gpac/sync_layer.h b/include/gpac/sync_layer.h index 13ed64f..628eca8 100644 --- a/include/gpac/sync_layer.h +++ b/include/gpac/sync_layer.h @@ -106,6 +106,9 @@ typedef struct /*ISMACryp extensions*/ u8 isma_encrypted; u64 isma_BSO; + /*version_number are pushed from m2ts sections to the mpeg4sl layer so as to handle mpeg4 stream dependencies*/ + u8 m2ts_version_number_plus_one; + u8 m2ts_pcr; } GF_SLHeader; diff --git a/include/gpac/term_info.h b/include/gpac/term_info.h index 278a331..8d75a04 100644 --- a/include/gpac/term_info.h +++ b/include/gpac/term_info.h @@ -61,7 +61,7 @@ typedef struct GF_ObjectDescriptor *od; Double duration; Double current_time; - /*0: stoped, 1: playing, 2: paused, 3: not setup, 4; setup failed.*/ + /*0: stopped, 1: playing, 2: paused, 3: not setup, 4; setup failed.*/ u32 status; /*if set, the PL flags are valid*/ Bool has_profiles; @@ -109,10 +109,13 @@ typedef struct u32 protection; u32 lang; -} ODInfo; -/*fills the ODInfo structure describing the OD manager*/ -GF_Err gf_term_get_object_info(GF_Terminal *term, GF_ObjectManager *odm, ODInfo *info); + /*name of media if not defined in OD framework*/ + const char *media_url; +} GF_MediaInfo; + +/*fills the GF_MediaInfo structure describing the OD manager*/ +GF_Err gf_term_get_object_info(GF_Terminal *term, GF_ObjectManager *odm, GF_MediaInfo *info); /*gets current downloads info for the service - only use if ODM owns thesrevice, returns 0 otherwise. @d_enum: in/out current enum - shall start to 0, incremented at each call. fct returns 0 if no more downloads @@ -143,11 +146,12 @@ const char *gf_term_get_world_info(GF_Terminal *term, GF_ObjectManager *scene_od /*dumps scene graph in specified file, in BT or XMT format @rad_name: file radical (NULL for stdout) - if not NULL MUST BE GF_MAX_PATH length +@filename [out]: if not null, returns the complete filename (rad + ext); MUST BE FREED BY THE CALLER if @skip_proto is set proto declarations are not dumped If @odm is or points to an inlined OD the inlined scene is dumped If @odm is NULL the main scene is dumped */ -GF_Err gf_term_dump_scene(GF_Terminal *term, char *rad_name, Bool xml_dump, Bool skip_proto, GF_ObjectManager *odm); +GF_Err gf_term_dump_scene(GF_Terminal *term, char *rad_name, char **filename, Bool xml_dump, Bool skip_proto, GF_ObjectManager *odm); #ifdef __cplusplus diff --git a/include/gpac/terminal.h b/include/gpac/terminal.h index 8a673cc..f93c88d 100644 --- a/include/gpac/terminal.h +++ b/include/gpac/terminal.h @@ -39,6 +39,8 @@ GF_Terminal *gf_term_new(GF_User *user); returns GF_IO_ERR if client couldn't be shutdown normally*/ GF_Err gf_term_del(GF_Terminal *term); +/* Browses all registered relocators (ZIP-based, ISOFF-based or file-system-based to relocate a URL based on the user locale */ +Bool gf_term_relocate_url(GF_Terminal *term, const char *service_url, const char *parent_url, char *relocated_url, char *localized_url); /*connects to a URL*/ void gf_term_connect(GF_Terminal *term, const char *URL); /*disconnects the url*/ @@ -47,16 +49,21 @@ void gf_term_disconnect(GF_Terminal *term); This is the only safe way of restarting/jumping a presentation from inside the EventProc where doing a disconnect/connect could deadlock if toURL is NULL, uses the current URL*/ void gf_term_navigate_to(GF_Terminal *term, const char *toURL); -/*restarts url from given time (in ms). Return value: +/*restarts url from given time (in ms). +@pause_at_first_frame: if 1, pauses at the first frame. If 2, pauses at the first frame only if the terminal is in paused state. +Return value: 0: service is not connected yet 1: service has no seeking capabilities 2: service has been seeked */ -u32 gf_term_play_from_time(GF_Terminal *term, u64 from_time, Bool pause_at_first_frame); +u32 gf_term_play_from_time(GF_Terminal *term, u64 from_time, u32 pause_at_first_frame); /*connect URL and seek right away - only needed when reloading the complete player (avoids waiting for connection and post a seek..)*/ void gf_term_connect_from_time(GF_Terminal *term, const char *URL, u64 time_in_ms, Bool pause_at_first_frame); +/*same as gf_term_connect but specifies a parent path*/ +void gf_term_connect_with_path(GF_Terminal *term, const char *URL, const char *parent_URL); + /*returns current framerate if @absoluteFPS is set, the return value is the absolute framerate, eg NbFrameCount/NbTimeSpent regardless of whether a frame has been drawn or not, which means the FPS returned can be much greater than the target rendering @@ -81,7 +88,7 @@ GF_Err gf_term_set_viewpoint(GF_Terminal *term, u32 viewpoint_idx, const char *v GF_Err gf_term_add_object(GF_Terminal *term, const char *url, Bool auto_play); -/*set/set option - most of the terminal cfg is done through options, please refer to user.h for details*/ +/*set/set option - most of the terminal cfg is done through options, please refer to options.h for details*/ GF_Err gf_term_set_option(GF_Terminal *term, u32 opt_type, u32 opt_value); u32 gf_term_get_option(GF_Terminal *term, u32 opt_type); @@ -94,6 +101,11 @@ GF_Err gf_term_set_simulation_frame_rate(GF_Terminal * term, Double frame_rate); /*gets simulation frame rate*/ Double gf_term_get_simulation_frame_rate(GF_Terminal *term); +/*process shortcuts*/ +void gf_term_process_shortcut(GF_Terminal *term, GF_Event *ev); + +void gf_term_set_speed(GF_Terminal *term, Fixed speed); + /*sends a set of scene commands (BT, XMT, X3D, LASeR+XML) to the scene type indicates the language used - accepted values are "model/x3d+xml" or "x3d": commands is an X3D+XML scene @@ -172,6 +184,11 @@ GF_Err gf_term_release_screen_buffer(GF_Terminal *term, GF_VideoSurface *framebu /*ObjectManager used by both terminal and object browser (term_info.h)*/ typedef struct _od_manager GF_ObjectManager; +/*switches quality up or down - can be called several time in the same direction +this will call all decoders to adjust their quality levels +VERY BASIC INTERFACE*/ +void gf_term_switch_quality(GF_Terminal *term, Bool up); + #ifdef __cplusplus } #endif diff --git a/include/gpac/thread.h b/include/gpac/thread.h index 083f57b..d9b1ccb 100644 --- a/include/gpac/thread.h +++ b/include/gpac/thread.h @@ -185,7 +185,7 @@ void gf_mx_del(GF_Mutex *mx); /* *\brief mutex locking * - *Locks the mutex object, making sure that another thread locking this mutex cannot exectute until the mutex is unlocked. + *Locks the mutex object, making sure that another thread locking this mutex cannot execute until the mutex is unlocked. *\param mx the mutex object *\return 1 if success, 0 if error locking the mutex (which should never happen) */ diff --git a/include/gpac/tools.h b/include/gpac/tools.h index 80da566..bb192f2 100644 --- a/include/gpac/tools.h +++ b/include/gpac/tools.h @@ -58,10 +58,10 @@ extern "C" { * Macro giving GPAC version expressed as a printable string */ /*KEEP SPACE SEPARATORS FOR MAKE / GREP (SEE MAIN MAKEFILE)!!!, and NO SPACE in GPAC_VERSION for proper install*/ -#define GPAC_VERSION "0.4.5" +#define GPAC_VERSION "0.4.6-DEV" -#define GPAC_BUILD_NUMBER "33" -#define GPAC_FULL_VERSION GPAC_VERSION" (build "GPAC_BUILD_NUMBER")" +#define GPAC_INTERNAL_REV "8" +#define GPAC_FULL_VERSION GPAC_VERSION" (internal rev. "GPAC_INTERNAL_REV")" /*! * \brief GPAC Version @@ -69,7 +69,7 @@ extern "C" { * * Macro giving GPAC version expressed as an integer, where version X.Y.Z is coded as 0x00XXYYZZ */ -#define GPAC_VERSION_INT 0x00000405 +#define GPAC_VERSION_INT 0x00000406 /*! * \brief Memory allocation @@ -77,7 +77,7 @@ extern "C" { * * Macro allocating memory and zero-ing it */ -#define GF_SAFEALLOC(__ptr, __struct) { __ptr = (__struct *) malloc(sizeof(__struct)); if (__ptr) memset((void *) __ptr, 0, sizeof(__struct)); } +#define GF_SAFEALLOC(__ptr, __struct) { __ptr = (__struct *) gf_malloc(sizeof(__struct)); if (__ptr) memset((void *) __ptr, 0, sizeof(__struct)); } /*! * \brief 4CC Formatting @@ -86,6 +86,15 @@ extern "C" { * Macro formating a 4-character code (or 4CC) "abcd" as 0xAABBCCDD */ #define GF_4CC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d)) + + +/*! + * \brief GPAC feature list + * + * returns the list of features enabled/disabled in this GPAC build. +*/ +const char *gpac_features(); + /*! * \brief 4CC Printing * @@ -97,8 +106,8 @@ const char *gf_4cc_to_str(u32 type); * \brief large file opening * * Opens a large file (>4GB) - * \param file_name Same semantics as fopen - * \param mode Same semantics as fopen + * \param file_name Same semantics as gf_f64_open + * \param mode Same semantics as gf_f64_open * \return stream handle of the file object * \note You only need to call this function if you're suspecting the file to be a large one (usually only media files), otherwise use regular stdio. */ @@ -116,9 +125,9 @@ u64 gf_f64_tell(FILE *f); * \brief large file seeking * * Seeks the current read/write position in a large file - * \param f Same semantics as fseek - * \param pos Same semantics as fseek - * \param whence Same semantics as fseek + * \param f Same semantics as gf_f64_seek + * \param pos Same semantics as gf_f64_seek + * \param whence Same semantics as gf_f64_seek * \return new position in the file * \note You only need to call this function if you're suspecting the file to be a large one (usually only media files), otherwise use regular stdio. */ @@ -225,7 +234,7 @@ typedef enum /*! Authentication with the remote host has failed*/ GF_AUTHENTICATION_FAILURE = -50, /*! Script not ready for playback */ - GF_SCRIPT_NOT_READY = -51, + GF_SCRIPT_NOT_READY = -51 } GF_Err; /*! @@ -259,7 +268,7 @@ enum /*! Log message is informational (state, etc..)*/ GF_LOG_INFO, /*! Log message is a debug info*/ - GF_LOG_DEBUG, + GF_LOG_DEBUG }; /*! @@ -316,6 +325,12 @@ enum GF_LOG_RTI = 1<<16, /*! Log for SMIL timing and animation*/ GF_LOG_SMIL = 1<<17, + /*! Log for memory tracker*/ + GF_LOG_MEMORY = 1<<18, + /*! Log for audio compositor*/ + GF_LOG_AUDIO = 1<<19, + /*! generic Log for modules*/ + GF_LOG_MODULE = 1<<20 }; @@ -376,6 +391,9 @@ void gf_log_lt(u32 ll, u32 lt); u32 gf_log_get_level(); u32 gf_log_get_tools(); +u32 gf_log_parse_level(const char *val); +u32 gf_log_parse_tools(const char *val); + #ifdef GPAC_DISABLE_LOG #define GF_LOG(_ll, _lm, __args) #else @@ -449,8 +467,18 @@ GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item * \param fileName absolute name of the file or name relative to the current working directory. */ void gf_delete_file(char *fileName); + /*! - * \brief File Deletion + * \brief File Move + * + * Moves or renames a file or directory. + * \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(char *fileName, char *newFileName); + +/*! + * \brief Temporary File Creation * * Creates a new temporary file in binary mode * \return stream handle to the new file ressoucre @@ -458,6 +486,15 @@ void gf_delete_file(char *fileName); FILE *gf_temp_file_new(); +/*! + * \brief File Modification Time + * + * Returns the modification time of the given file. The exact meaning of this value is system dependent + * \param filename file to check + * \return modification time of the file + */ +u64 gf_file_modification_time(const char *filename); + /*! * \brief Progress formatting * @@ -466,7 +503,7 @@ FILE *gf_temp_file_new(); * \param done Current amount performed of the action. * \param total Total amount of the action. */ -void gf_set_progress(char *title, u32 done, u32 total); +void gf_set_progress(char *title, u64 done, u64 total); /*! * \brief Progress Callback @@ -478,7 +515,7 @@ void gf_set_progress(char *title, u32 done, u32 total); * \param total Total amount of the action. * */ -typedef void (*gf_on_progress_cbk)(void *cbck, char *title, u32 done, u32 total); +typedef void (*gf_on_progress_cbk)(void *cbck, char *title, u64 done, u64 total); /*! * \brief Progress overwriting @@ -535,7 +572,7 @@ void gf_prompt_set_echo_off(Bool echo_off); * function before calling any other GPAC functions, since on some systems (like winCE) it may result in a better memory usage estimation. * \note This can be called several times but only the first call will result in system setup. */ -void gf_sys_init(); +void gf_sys_init(Bool enable_memory_tracker); /*! * \brief System closing * @@ -622,7 +659,7 @@ enum Fetching the entire ocess allocated memory can have a large impact on performances*/ GF_RTI_PROCESS_MEMORY = 1<<1, /*!Indicates that only system memory should be fetched. When set, all refreshing info is ignored*/ - GF_RTI_SYSTEM_MEMORY_ONLY = 1<<2, + GF_RTI_SYSTEM_MEMORY_ONLY = 1<<2 }; /*! @@ -639,7 +676,7 @@ enum Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags); -Bool gf_sys_get_battery_state(Bool *onBattery, u32 *onCharge, u32 *level); +Bool gf_sys_get_battery_state(Bool *onBattery, u32 *onCharge, u32 *level, u32 *batteryLifeTime, u32 *batteryFullLifeTime); /*! @} */ diff --git a/include/gpac/user.h b/include/gpac/user.h index bf13ac6..53f49be 100644 --- a/include/gpac/user.h +++ b/include/gpac/user.h @@ -52,13 +52,15 @@ enum * rendering is done after media decoding * the user is responsible for updating the terminal */ - GF_TERM_NO_VISUAL_THREAD = 1<<2, + GF_TERM_NO_THREAD = 1<<2, /*disables frame-rate regulation (used when dumping content)*/ GF_TERM_NO_REGULATION = 1<<3, /*lets the main user handle window events (neede for browser plugins)*/ GF_TERM_NO_WINDOWPROC_OVERRIDE = 1<<4, /*works in windowless mode - experimental, only supported on Win32*/ - GF_TERM_WINDOWLESS = 1<<5 + GF_TERM_WINDOWLESS = 1<<5, + /*works with no visual thread fr the composition - compositor is driven by the media manager*/ + GF_TERM_DRAW_FRAME = 1<<6 }; /*user object for all callbacks*/ @@ -86,23 +88,6 @@ typedef struct } GF_User; -/*macro for event forwarding*/ -#define GF_USER_SENDEVENT(_user, _evt) (_user->EventProc ? _user->EventProc(_user->opaque, _evt) : 0) - -/*macro for message event format/send*/ -#define GF_USER_MESSAGE(_user, _serv, _msg, _e) \ - { \ - GF_Event evt; \ - if (_user->EventProc) { \ - evt.type = GF_EVENT_MESSAGE; \ - evt.message.service = _serv; \ - evt.message.message = _msg; \ - evt.message.error = _e; \ - _user->EventProc(_user->opaque, &evt); \ - } \ - } - - #ifdef __cplusplus } #endif diff --git a/include/gpac/xml.h b/include/gpac/xml.h index 0d5b917..040549f 100644 --- a/include/gpac/xml.h +++ b/include/gpac/xml.h @@ -90,7 +90,7 @@ typedef void (*gf_xml_sax_node_start)(void *sax_cbck, const char *node_name, con typedef void (*gf_xml_sax_node_end)(void *sax_cbck, const char *node_name, const char *name_space); typedef void (*gf_xml_sax_text_content)(void *sax_cbck, const char *content, Bool is_cdata); -typedef void (*gf_xml_sax_progress)(void *cbck, u32 done, u32 tot); +typedef void (*gf_xml_sax_progress)(void *cbck, u64 done, u64 tot); /*creates new sax parser - all callbacks are optionals*/ GF_SAXParser *gf_xml_sax_new(gf_xml_sax_node_start on_node_start, diff --git a/modules/Makefile b/modules/Makefile index fc7419a..3019e57 100644 --- a/modules/Makefile +++ b/modules/Makefile @@ -1,7 +1,7 @@ include ../config.mak #all OS and lib independent -PLUGDIRS=aac_in ac3_in bifs_dec ctx_load dummy_in soft_raster mp3_in isom_in odf_dec rtp_in raw_out timedtext img_in svg_in saf_in mpegts_in ismacryp +PLUGDIRS=aac_in ac3_in audio_filter bifs_dec ctx_load dummy_in soft_raster mp3_in isom_in odf_dec rtp_in timedtext img_in svg_in saf_in mpegts_in ismacryp widgetman redirect_av ifeq ($(DISABLE_SVG), no) PLUGDIRS+=laser_dec svg_in @@ -68,6 +68,11 @@ else PLUGDIRS+=gpac_js endif + +ifeq ($(RENOIR_ENABLE),yes) +PLUGDIRS+=viren_out +endif + #w32 plugins ifeq ($(CONFIG_WIN32),yes) PLUGDIRS+=wav_out diff --git a/modules/aac_in/Makefile b/modules/aac_in/Makefile index 535391e..bd9e58c 100644 --- a/modules/aac_in/Makefile +++ b/modules/aac_in/Makefile @@ -34,21 +34,18 @@ endif LIB=gm_aac_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols aac_in.def -endif - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) +#LDFLAGS+=-export-symbols aac_in.def endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) -L../../bin/gcc -lgpac $(EXTRALIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_aac_in-static.so $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) +endif %.o: %.c diff --git a/modules/aac_in/aac_in.c b/modules/aac_in/aac_in.c index ca91b86..6872562 100644 --- a/modules/aac_in/aac_in.c +++ b/modules/aac_in/aac_in.c @@ -27,6 +27,8 @@ #include <gpac/avparse.h> #include <gpac/constants.h> +#ifndef GPAC_DISABLE_AV_PARSERS + typedef struct { GF_ClientService *service; @@ -71,6 +73,7 @@ static Bool AAC_CanHandleURL(GF_InputService *plug, const char *url) { char *sExt; sExt = strrchr(url, '.'); + if (!strnicmp(url, "rtsp://", 7)) return 0; if (!sExt) return 0; if (gf_term_check_extension(plug, "audio/x-m4a", "aac", "MPEG-4 AAC Music", sExt)) return 1; if (gf_term_check_extension(plug, "audio/aac", "aac", "MPEG-4 AAC Music", sExt)) return 1; @@ -119,6 +122,10 @@ static GF_ESD *AAC_GetESD(AACReader *read) gf_bs_write_int(dsi, 1, 1); gf_bs_write_int(dsi, sbr_sr_idx, 4); + /* always signal implicit PS in case it's used ??? */ + gf_bs_write_int(dsi, 0x548, 11); + gf_bs_write_int(dsi, 1, 1); + gf_bs_align(dsi); gf_bs_get_content(dsi, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(dsi); @@ -138,9 +145,10 @@ static void AAC_SetupObject(AACReader *read) static Bool ADTS_SyncFrame(GF_BitStream *bs, Bool is_complete, ADTSHeader *hdr) { - u32 val, pos, start_pos; + u32 val; + u64 start_pos, pos; - start_pos = (u32) gf_bs_get_position(bs); + start_pos = gf_bs_get_position(bs); while (gf_bs_available(bs)) { val = gf_bs_read_u8(bs); if (val!=0xFF) continue; @@ -152,7 +160,7 @@ static Bool ADTS_SyncFrame(GF_BitStream *bs, Bool is_complete, ADTSHeader *hdr) hdr->is_mp2 = gf_bs_read_int(bs, 1); gf_bs_read_int(bs, 2); hdr->no_crc = gf_bs_read_int(bs, 1); - pos = (u32) gf_bs_get_position(bs) - 2; + pos = gf_bs_get_position(bs) - 2; hdr->profile = 1 + gf_bs_read_int(bs, 2); hdr->sr_idx = gf_bs_read_int(bs, 4); @@ -210,7 +218,7 @@ static Bool AAC_ConfigureFromFile(AACReader *read) read->nb_ch = hdr.nb_ch; read->prof = hdr.profile; read->sr_idx = hdr.sr_idx; - read->oti = hdr.is_mp2 ? read->prof+0x66 : 0x40; + read->oti = hdr.is_mp2 ? read->prof+GPAC_OTI_AUDIO_AAC_MPEG2_MP : GPAC_OTI_AUDIO_AAC_MPEG4; read->sample_rate = GF_M4ASampleRates[read->sr_idx]; read->duration = 0; @@ -224,7 +232,7 @@ static Bool AAC_ConfigureFromFile(AACReader *read) } } gf_bs_del(bs); - fseek(read->stream, 0, SEEK_SET); + gf_f64_seek(read->stream, 0, SEEK_SET); return 1; } @@ -249,7 +257,7 @@ static void AAC_OnLiveData(AACReader *read, char *data, u32 data_size) GF_BitStream *bs; ADTSHeader hdr; - read->data = realloc(read->data, sizeof(char)*(read->data_size+data_size) ); + read->data = gf_realloc(read->data, sizeof(char)*(read->data_size+data_size) ); memcpy(read->data + read->data_size, data, sizeof(char)*data_size); read->data_size += data_size; @@ -262,7 +270,7 @@ static void AAC_OnLiveData(AACReader *read, char *data, u32 data_size) read->nb_ch = hdr.nb_ch; read->prof = hdr.profile; read->sr_idx = hdr.sr_idx; - read->oti = hdr.is_mp2 ? read->prof+0x66-1 : 0x40; + read->oti = hdr.is_mp2 ? read->prof+GPAC_OTI_AUDIO_AAC_MPEG2_MP-1 : GPAC_OTI_AUDIO_AAC_MPEG4; read->sample_rate = GF_M4ASampleRates[read->sr_idx]; read->is_live = 1; memset(&read->sl_hdr, 0, sizeof(GF_SLHeader)); @@ -293,9 +301,9 @@ static void AAC_OnLiveData(AACReader *read, char *data, u32 data_size) if (pos) { char *d; read->data_size -= pos; - d = malloc(sizeof(char) * read->data_size); + d = gf_malloc(sizeof(char) * read->data_size); memcpy(d, read->data + pos, sizeof(char) * read->data_size); - free(read->data); + gf_free(read->data); read->data = d; } AAC_RegulateDataRate(read); @@ -319,17 +327,17 @@ void AAC_NetIO(void *cbk, GF_NETIO_Parameter *param) } } else if (param->msg_type==GF_NETIO_PARSE_HEADER) { if (!strcmp(param->name, "icy-name")) { - if (read->icy_name) free(read->icy_name); - read->icy_name = strdup(param->value); + if (read->icy_name) gf_free(read->icy_name); + read->icy_name = gf_strdup(param->value); } if (!strcmp(param->name, "icy-genre")) { - if (read->icy_genre) free(read->icy_genre); - read->icy_genre = strdup(param->value); + if (read->icy_genre) gf_free(read->icy_genre); + read->icy_genre = gf_strdup(param->value); } if (!strcmp(param->name, "icy-meta")) { GF_NetworkCommand com; char *meta; - if (read->icy_track_name) free(read->icy_track_name); + if (read->icy_track_name) gf_free(read->icy_track_name); read->icy_track_name = NULL; meta = param->value; while (meta && meta[0]) { @@ -337,7 +345,7 @@ void AAC_NetIO(void *cbk, GF_NETIO_Parameter *param) if (sep) sep[0] = 0; if (!strnicmp(meta, "StreamTitle=", 12)) { - read->icy_track_name = strdup(meta+12); + read->icy_track_name = gf_strdup(meta+12); } if (!sep) break; sep[0] = ';'; @@ -370,7 +378,7 @@ void AAC_NetIO(void *cbk, GF_NETIO_Parameter *param) szCache = gf_dm_sess_get_cache_name(read->dnload); if (!szCache) e = GF_IO_ERR; else { - read->stream = fopen((char *) szCache, "rb"); + read->stream = gf_f64_open((char *) szCache, "rb"); if (!read->stream) e = GF_SERVICE_ERROR; else { /*if full file at once (in cache) parse duration*/ @@ -437,7 +445,7 @@ static GF_Err AAC_ConnectService(GF_InputService *plug, GF_ClientService *serv, } reply = GF_OK; - read->stream = fopen(szURL, "rb"); + read->stream = gf_f64_open(szURL, "rb"); if (!read->stream) { reply = GF_URL_ERROR; } else if (!AAC_ConfigureFromFile(read)) { @@ -458,7 +466,7 @@ static GF_Err AAC_CloseService(GF_InputService *plug) if (read->dnload) gf_term_download_del(read->dnload); read->dnload = NULL; - if (read->data) free(read->data); + if (read->data) gf_free(read->data); read->data = NULL; gf_term_on_disconnect(read->service, NULL, GF_OK); return GF_OK; @@ -520,7 +528,7 @@ static GF_Err AAC_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) GF_Err e = GF_STREAM_NOT_FOUND; if (read->ch == channel) { read->ch = NULL; - if (read->data) free(read->data); + if (read->data) gf_free(read->data); read->data = NULL; e = GF_OK; } @@ -568,7 +576,7 @@ static GF_Err AAC_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) read->start_range = com->play.start_range; read->end_range = com->play.end_range; read->current_time = 0; - if (read->stream) fseek(read->stream, 0, SEEK_SET); + if (read->stream) gf_f64_seek(read->stream, 0, SEEK_SET); if (read->ch == com->base.on_channel) { read->done = 0; @@ -596,7 +604,8 @@ static GF_Err AAC_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) static GF_Err AAC_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) { - u32 pos, start_from; + u64 pos; + u32 start_from; Bool sync; GF_BitStream *bs; ADTSHeader hdr; @@ -628,7 +637,7 @@ static GF_Err AAC_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, cha *is_new_data = 1; fetch_next: - pos = ftell(read->stream); + pos = gf_f64_tell(read->stream); sync = ADTS_SyncFrame(bs, !read->is_remote, &hdr); if (!sync) { gf_bs_del(bs); @@ -636,7 +645,7 @@ fetch_next: *out_reception_status = GF_EOS; read->done = 1; } else { - fseek(read->stream, pos, SEEK_SET); + gf_f64_seek(read->stream, pos, SEEK_SET); *out_reception_status = GF_OK; } return GF_OK; @@ -663,7 +672,7 @@ fetch_next: read->sl_hdr.compositionTimeStamp = read->current_time; - read->data = malloc(sizeof(char) * (read->data_size+read->pad_bytes)); + read->data = gf_malloc(sizeof(char) * (read->data_size+read->pad_bytes)); gf_bs_read_data(bs, read->data, read->data_size); if (read->pad_bytes) memset(read->data + read->data_size, 0, sizeof(char) * read->pad_bytes); gf_bs_del(bs); @@ -680,7 +689,7 @@ static GF_Err AAC_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) if (read->ch == channel) { if (!read->data) return GF_BAD_PARAM; - free(read->data); + gf_free(read->data); read->data = NULL; read->current_time += read->nb_samp; return GF_OK; @@ -691,7 +700,7 @@ static GF_Err AAC_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) GF_InputService *AAC_Load() { AACReader *reader; - GF_InputService *plug = malloc(sizeof(GF_InputService)); + GF_InputService *plug = gf_malloc(sizeof(GF_InputService)); memset(plug, 0, sizeof(GF_InputService)); GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC AAC Reader", "gpac distribution") @@ -706,7 +715,7 @@ GF_InputService *AAC_Load() plug->ChannelGetSLP = AAC_ChannelGetSLP; plug->ChannelReleaseSLP = AAC_ChannelReleaseSLP; - reader = malloc(sizeof(AACReader)); + reader = gf_malloc(sizeof(AACReader)); memset(reader, 0, sizeof(AACReader)); plug->priv = reader; return plug; @@ -716,18 +725,27 @@ void AAC_Delete(void *ifce) { GF_InputService *plug = (GF_InputService *) ifce; AACReader *read = plug->priv; - free(read); - free(plug); + gf_free(read); + gf_free(plug); } +#endif + + GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_NET_CLIENT_INTERFACE) return 1; -#ifdef GPAC_HAS_FAAD - if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1; -#endif - return 0; + static u32 si [] = { + #ifndef GPAC_DISABLE_AV_PARSERS + GF_NET_CLIENT_INTERFACE, + #endif + #ifdef GPAC_HAS_FAAD + GF_MEDIA_DECODER_INTERFACE, + #endif + 0 + }; + + return si; } #ifdef GPAC_HAS_FAAD @@ -738,7 +756,9 @@ void DeleteFAADDec(GF_BaseDecoder *ifcg); GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { +#ifndef GPAC_DISABLE_AV_PARSERS if (InterfaceType == GF_NET_CLIENT_INTERFACE) return (GF_BaseInterface *)AAC_Load(); +#endif #ifdef GPAC_HAS_FAAD if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)NewFAADDec(); #endif @@ -754,8 +774,10 @@ void ShutdownInterface(GF_BaseInterface *ifce) DeleteFAADDec((GF_BaseDecoder *)ifce); break; #endif +#ifndef GPAC_DISABLE_AV_PARSERS case GF_NET_CLIENT_INTERFACE: AAC_Delete(ifce); break; +#endif } } diff --git a/modules/aac_in/aac_in.def b/modules/aac_in/aac_in.def deleted file mode 100644 index 39f84e3..0000000 --- a/modules/aac_in/aac_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_aac_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/aac_in/faad_dec.c b/modules/aac_in/faad_dec.c index 51f1a7d..9eada49 100644 --- a/modules/aac_in/faad_dec.c +++ b/modules/aac_in/faad_dec.c @@ -49,8 +49,10 @@ typedef struct static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) { +#ifndef GPAC_DISABLE_AV_PARSERS GF_Err e; GF_M4ADecSpecInfo a_cfg; +#endif FAADCTX(); if (ctx->ES_ID && ctx->ES_ID!=esd->ESID) return GF_NOT_SUPPORTED; @@ -65,10 +67,14 @@ static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) return GF_IO_ERR; } +#ifndef GPAC_DISABLE_AV_PARSERS e = gf_m4a_get_config((unsigned char *) esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg); if (e) return e; - if ( (s8) faacDecInit2(ctx->codec, (unsigned char *) esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, (u32 *) &ctx->sample_rate, (u8 *) &ctx->num_channels) < 0) +#endif + + if ( (s8) faacDecInit2(ctx->codec, (unsigned char *) esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, (unsigned long *) &ctx->sample_rate, (u8 *) &ctx->num_channels) < 0) { +#ifndef GPAC_DISABLE_AV_PARSERS s8 res; char *dsi; u32 dsi_len; @@ -78,6 +84,7 @@ static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) case GF_M4A_AAC_SSR: case GF_M4A_AAC_LTP: case GF_M4A_AAC_SBR: + case GF_M4A_AAC_PS: GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error initializing stream %d\n", esd->ESID)); return GF_NOT_SUPPORTED; default: @@ -88,15 +95,19 @@ static GF_Err FAAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) a_cfg.nb_chan = 1; gf_m4a_write_config(&a_cfg, &dsi, &dsi_len); - res = faacDecInit2(ctx->codec, (unsigned char *) dsi, dsi_len, (u32 *) &ctx->sample_rate, (u8 *) &ctx->num_channels); - free(dsi); - if (res < 0) { + res = faacDecInit2(ctx->codec, (unsigned char *) dsi, dsi_len, (unsigned long *) &ctx->sample_rate, (u8 *) &ctx->num_channels); + gf_free(dsi); + if (res < 0) +#endif + { GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[FAAD] Error initializing stream %d\n", esd->ESID)); return GF_NOT_SUPPORTED; } } +#ifndef GPAC_DISABLE_AV_PARSERS ctx->is_sbr = a_cfg.has_sbr; +#endif ctx->num_samples = 1024; ctx->out_size = 2 * ctx->num_samples * ctx->num_channels; ctx->ES_ID = esd->ESID; @@ -215,7 +226,7 @@ static GF_Err FAAD_ProcessData(GF_MediaDecoder *ifcg, /*if late or seeking don't decode*/ switch (mmlevel) { case GF_CODEC_LEVEL_SEEK: - case GF_CODEC_LEVEL_DROP: +// case GF_CODEC_LEVEL_DROP: *outBufferLength = 0; return GF_OK; default: @@ -306,17 +317,19 @@ static const char *FAAD_GetCodecName(GF_BaseDecoder *ifcg) static Bool FAAD_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, u32 ObjectType, char *decSpecInfo, u32 decSpecInfoSize, u32 PL) { +#ifndef GPAC_DISABLE_AV_PARSERS GF_M4ADecSpecInfo a_cfg; +#endif /*audio decs*/ if (StreamType != GF_STREAM_AUDIO) return 0; switch (ObjectType) { /*MPEG2 aac*/ - case 0x66: - case 0x67: - case 0x68: + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: /*MPEG4 aac*/ - case 0x40: + case GPAC_OTI_AUDIO_AAC_MPEG4: break; /*cap query*/ case 0: @@ -325,9 +338,11 @@ static Bool FAAD_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, u32 Object return 0; } if (!decSpecInfoSize || !decSpecInfo) return 0; +#ifndef GPAC_DISABLE_AV_PARSERS if (gf_m4a_get_config((unsigned char *) decSpecInfo, decSpecInfoSize, &a_cfg) != GF_OK) return 0; /*BSAC not supported*/ if (a_cfg.base_object_type == GF_M4A_ER_BSAC) return 0; +#endif return 1; } @@ -358,8 +373,8 @@ void DeleteFAADDec(GF_BaseDecoder *ifcg) { FAADCTX(); if (ctx->codec) faacDecClose(ctx->codec); - free(ctx); - free(ifcg); + gf_free(ctx); + gf_free(ifcg); } diff --git a/modules/ac3_in/Makefile b/modules/ac3_in/Makefile index 2ca5f88..6dbf7b0 100644 --- a/modules/ac3_in/Makefile +++ b/modules/ac3_in/Makefile @@ -27,28 +27,22 @@ CFLAGS+=-DGPAC_HAS_LIBA52 #local faad lib ifeq ($(CONFIG_FAAD), local) EXTRALIBS+=-L../../extra_lib/lib/gcc -CFLAGS+= -I$(LOCAL_INC_PATH)/a52 +CFLAGS+= -I$(LOCAL_INC_PATH) endif EXTRALIBS+= -la52 endif LIB=gm_ac3_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols ac3_in.def -endif - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) +#LDFLAGS+=-export-symbols ac3_in.def endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) -L../../bin/gcc -lgpac $(EXTRALIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) %.o: %.c diff --git a/modules/ac3_in/ac3_in.c b/modules/ac3_in/ac3_in.c index 08bddb8..0aeee52 100644 --- a/modules/ac3_in/ac3_in.c +++ b/modules/ac3_in/ac3_in.c @@ -27,6 +27,8 @@ #include <gpac/avparse.h> #include <gpac/constants.h> +#ifndef GPAC_DISABLE_AV_PARSERS + typedef struct { GF_ClientService *service; @@ -130,7 +132,7 @@ static Bool AC3_ConfigureFromFile(AC3Reader *read) } } gf_bs_del(bs); - fseek(read->stream, 0, SEEK_SET); + gf_f64_seek(read->stream, 0, SEEK_SET); return 1; } @@ -150,12 +152,12 @@ static void AC3_RegulateDataRate(AC3Reader *read) static void AC3_OnLiveData(AC3Reader *read, char *data, u32 data_size) { - u32 pos; + u64 pos; Bool sync; GF_BitStream *bs; GF_AC3Header hdr; - read->data = realloc(read->data, sizeof(char)*(read->data_size+data_size) ); + read->data = gf_realloc(read->data, sizeof(char)*(read->data_size+data_size) ); memcpy(read->data + read->data_size, data, sizeof(char)*data_size); read->data_size += data_size; @@ -180,7 +182,7 @@ static void AC3_OnLiveData(AC3Reader *read, char *data, u32 data_size) bs = gf_bs_new(read->data, read->data_size, GF_BITSTREAM_READ); hdr.framesize = pos = 0; while (gf_ac3_parser_bs(bs, &hdr, 0)) { - pos = (u32) gf_bs_get_position(bs); + pos = gf_bs_get_position(bs); read->sl_hdr.accessUnitStartFlag = 1; read->sl_hdr.accessUnitEndFlag = 1; read->sl_hdr.AU_sequenceNumber++; @@ -190,15 +192,15 @@ static void AC3_OnLiveData(AC3Reader *read, char *data, u32 data_size) gf_bs_skip_bytes(bs, hdr.framesize); } - pos = (u32) gf_bs_get_position(bs); + pos = gf_bs_get_position(bs); gf_bs_del(bs); if (pos) { char *d; read->data_size -= pos; - d = malloc(sizeof(char) * read->data_size); + d = gf_malloc(sizeof(char) * read->data_size); memcpy(d, read->data + pos, sizeof(char) * read->data_size); - free(read->data); + gf_free(read->data); read->data = d; } AC3_RegulateDataRate(read); @@ -222,17 +224,17 @@ void AC3_NetIO(void *cbk, GF_NETIO_Parameter *param) } } else if (param->msg_type==GF_NETIO_PARSE_HEADER) { if (!strcmp(param->name, "icy-name")) { - if (read->icy_name) free(read->icy_name); - read->icy_name = strdup(param->value); + if (read->icy_name) gf_free(read->icy_name); + read->icy_name = gf_strdup(param->value); } if (!strcmp(param->name, "icy-genre")) { - if (read->icy_genre) free(read->icy_genre); - read->icy_genre = strdup(param->value); + if (read->icy_genre) gf_free(read->icy_genre); + read->icy_genre = gf_strdup(param->value); } if (!strcmp(param->name, "icy-meta")) { GF_NetworkCommand com; char *meta; - if (read->icy_track_name) free(read->icy_track_name); + if (read->icy_track_name) gf_free(read->icy_track_name); read->icy_track_name = NULL; meta = param->value; while (meta && meta[0]) { @@ -240,7 +242,7 @@ void AC3_NetIO(void *cbk, GF_NETIO_Parameter *param) if (sep) sep[0] = 0; if (!strnicmp(meta, "StreamTitle=", 12)) { - read->icy_track_name = strdup(meta+12); + read->icy_track_name = gf_strdup(meta+12); } if (!sep) break; sep[0] = ';'; @@ -273,7 +275,7 @@ void AC3_NetIO(void *cbk, GF_NETIO_Parameter *param) szCache = gf_dm_sess_get_cache_name(read->dnload); if (!szCache) e = GF_IO_ERR; else { - read->stream = fopen((char *) szCache, "rb"); + read->stream = gf_f64_open((char *) szCache, "rb"); if (!read->stream) e = GF_SERVICE_ERROR; else { /*if full file at once (in cache) parse duration*/ @@ -340,7 +342,7 @@ static GF_Err AC3_ConnectService(GF_InputService *plug, GF_ClientService *serv, } reply = GF_OK; - read->stream = fopen(szURL, "rb"); + read->stream = gf_f64_open(szURL, "rb"); if (!read->stream) { reply = GF_URL_ERROR; } else if (!AC3_ConfigureFromFile(read)) { @@ -361,7 +363,7 @@ static GF_Err AC3_CloseService(GF_InputService *plug) if (read->dnload) gf_term_download_del(read->dnload); read->dnload = NULL; - if (read->data) free(read->data); + if (read->data) gf_free(read->data); read->data = NULL; gf_term_on_disconnect(read->service, NULL, GF_OK); return GF_OK; @@ -423,7 +425,7 @@ static GF_Err AC3_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) GF_Err e = GF_STREAM_NOT_FOUND; if (read->ch == channel) { read->ch = NULL; - if (read->data) free(read->data); + if (read->data) gf_free(read->data); read->data = NULL; e = GF_OK; } @@ -471,7 +473,7 @@ static GF_Err AC3_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) read->start_range = com->play.start_range; read->end_range = com->play.end_range; read->current_time = 0; - if (read->stream) fseek(read->stream, 0, SEEK_SET); + if (read->stream) gf_f64_seek(read->stream, 0, SEEK_SET); if (read->ch == com->base.on_channel) { read->done = 0; @@ -499,7 +501,7 @@ static GF_Err AC3_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) static GF_Err AC3_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) { - u32 pos, start_from; + u64 pos, start_from; Bool sync; GF_BitStream *bs; GF_AC3Header hdr; @@ -531,7 +533,7 @@ static GF_Err AC3_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, cha *is_new_data = 1; fetch_next: - pos = ftell(read->stream); + pos = gf_f64_tell(read->stream); sync = gf_ac3_parser_bs(bs, &hdr, 0); if (!sync) { gf_bs_del(bs); @@ -539,7 +541,7 @@ fetch_next: *out_reception_status = GF_EOS; read->done = 1; } else { - fseek(read->stream, pos, SEEK_SET); + gf_f64_seek(read->stream, pos, SEEK_SET); *out_reception_status = GF_OK; } return GF_OK; @@ -566,7 +568,7 @@ fetch_next: read->sl_hdr.compositionTimeStamp = read->current_time; - read->data = malloc(sizeof(char) * (read->data_size+read->pad_bytes)); + read->data = gf_malloc(sizeof(char) * (read->data_size+read->pad_bytes)); gf_bs_read_data(bs, read->data, read->data_size); if (read->pad_bytes) memset(read->data + read->data_size, 0, sizeof(char) * read->pad_bytes); gf_bs_del(bs); @@ -583,7 +585,7 @@ static GF_Err AC3_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) if (read->ch == channel) { if (!read->data) return GF_BAD_PARAM; - free(read->data); + gf_free(read->data); read->data = NULL; read->current_time += read->nb_samp; return GF_OK; @@ -594,7 +596,7 @@ static GF_Err AC3_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) GF_InputService *AC3_Load() { AC3Reader *reader; - GF_InputService *plug = malloc(sizeof(GF_InputService)); + GF_InputService *plug = gf_malloc(sizeof(GF_InputService)); memset(plug, 0, sizeof(GF_InputService)); GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC AC3 Reader", "gpac distribution") @@ -609,7 +611,7 @@ GF_InputService *AC3_Load() plug->ChannelGetSLP = AC3_ChannelGetSLP; plug->ChannelReleaseSLP = AC3_ChannelReleaseSLP; - reader = malloc(sizeof(AC3Reader)); + reader = gf_malloc(sizeof(AC3Reader)); memset(reader, 0, sizeof(AC3Reader)); plug->priv = reader; return plug; @@ -619,29 +621,39 @@ void AC3_Delete(void *ifce) { GF_InputService *plug = (GF_InputService *) ifce; AC3Reader *read = plug->priv; - free(read); - free(plug); + gf_free(read); + gf_free(plug); } +#endif /*GPAC_DISABLE_AV_PARSERS*/ + #ifdef GPAC_HAS_LIBA52 GF_BaseDecoder *NewAC3Dec(); void DeleteAC3Dec(GF_BaseDecoder *ifcg); #endif GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_NET_CLIENT_INTERFACE) return 1; +static u32 si [] = { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_NET_CLIENT_INTERFACE, +#endif #ifdef GPAC_HAS_LIBA52 - if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1; + GF_MEDIA_DECODER_INTERFACE, #endif - return 0; + 0 +}; + + return si; } GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { +#ifndef GPAC_DISABLE_AV_PARSERS if (InterfaceType == GF_NET_CLIENT_INTERFACE) return (GF_BaseInterface *)AC3_Load(); +#endif #ifdef GPAC_HAS_LIBA52 if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)NewAC3Dec(); #endif @@ -657,8 +669,10 @@ void ShutdownInterface(GF_BaseInterface *ifce) DeleteAC3Dec((GF_BaseDecoder *)ifce); break; #endif +#ifndef GPAC_DISABLE_AV_PARSERS case GF_NET_CLIENT_INTERFACE: AC3_Delete(ifce); break; +#endif } } diff --git a/modules/ac3_in/ac3_in.def b/modules/ac3_in/ac3_in.def deleted file mode 100644 index cba0550..0000000 --- a/modules/ac3_in/ac3_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_ac3_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/ac3_in/liba52_dec.c b/modules/ac3_in/liba52_dec.c index 7d356f9..ce4bd4b 100644 --- a/modules/ac3_in/liba52_dec.c +++ b/modules/ac3_in/liba52_dec.c @@ -331,8 +331,8 @@ void DeleteAC3Dec(GF_BaseDecoder *ifcg) { A52CTX(); if (ctx->codec) a52_free(ctx->codec); - free(ctx); - free(ifcg); + gf_free(ctx); + gf_free(ifcg); } diff --git a/modules/alsa/Makefile b/modules/alsa/Makefile index 665579a..6d8d931 100644 --- a/modules/alsa/Makefile +++ b/modules/alsa/Makefile @@ -22,16 +22,11 @@ SRCS := $(OBJS:.o=.c) LIB=gm_alsa.$(DYN_LIB_SUFFIX) -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac -lasound +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -lasound %.o: %.c diff --git a/modules/alsa/alsa.c b/modules/alsa/alsa.c index 70221e2..b7ba4be 100644 --- a/modules/alsa/alsa.c +++ b/modules/alsa/alsa.c @@ -75,7 +75,7 @@ static void ALSA_Shutdown(GF_AudioOutput*dr) snd_pcm_close(ctx->playback_handle); ctx->playback_handle = NULL; } - if (ctx->wav_buf) free(ctx->wav_buf); + if (ctx->wav_buf) gf_free(ctx->wav_buf); ctx->wav_buf = NULL; } @@ -94,7 +94,7 @@ static GF_Err ALSA_ConfigureOutput(GF_AudioOutput*dr, u32 *SampleRate, u32 *NbCh snd_pcm_close(ctx->playback_handle); ctx->playback_handle = NULL; } - if (ctx->wav_buf) free(ctx->wav_buf); + if (ctx->wav_buf) gf_free(ctx->wav_buf); ctx->wav_buf = NULL; err = snd_pcm_open(&ctx->playback_handle, ctx->dev_name, SND_PCM_STREAM_PLAYBACK, 0/*SND_PCM_NONBLOCK*/); @@ -191,7 +191,7 @@ static GF_Err ALSA_ConfigureOutput(GF_AudioOutput*dr, u32 *SampleRate, u32 *NbCh ctx->delay = (ctx->buf_size*1000) / (sr*ctx->block_align); /*allocate a single buffer*/ - ctx->wav_buf = malloc(ctx->buf_size*sizeof(char)); + ctx->wav_buf = gf_malloc(ctx->buf_size*sizeof(char)); if(!ctx->wav_buf) return GF_OUT_OF_MEM; memset(ctx->wav_buf, 0, ctx->buf_size*sizeof(char)); GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[ALSA] Setup %d ch @ %d hz - %d periods of %d us - total buffer size %d - overall delay %d ms\n", ctx->nb_ch, sr, nb_bufs, period_time, ctx->buf_size, ctx->delay)); @@ -319,7 +319,7 @@ void *NewALSAOutput() GF_SAFEALLOC(driv, GF_AudioOutput); if(!driv) { - free(ctx); + gf_free(ctx); return NULL; } driv->opaque = ctx; @@ -341,8 +341,8 @@ void DeleteALSAOutput(void *ifce) { GF_AudioOutput*dr = (GF_AudioOutput*) ifce; ALSAContext *ctx = (ALSAContext *)dr->opaque; - free(ctx); - free(dr); + gf_free(ctx); + gf_free(dr); } @@ -350,11 +350,13 @@ void DeleteALSAOutput(void *ifce) * ******************************************************************** * interface */ -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) - return 1; - return 0; + static u32 si [] = { + GF_AUDIO_OUTPUT_INTERFACE, + 0 + }; + return si; } GF_BaseInterface *LoadInterface(u32 InterfaceType) diff --git a/modules/amr_dec/Makefile b/modules/amr_dec/Makefile index e6121bc..54fd517 100644 --- a/modules/amr_dec/Makefile +++ b/modules/amr_dec/Makefile @@ -47,20 +47,14 @@ SRCS := $(OBJS:.o=.c) LIB=gm_amr_dec.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols amr_dec.def -endif - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) +#LDFLAGS+=-export-symbols amr_dec.def endif all: $(LIB) $(LIB): $(OBJS) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac %.o: %.c diff --git a/modules/amr_dec/amr_dec.c b/modules/amr_dec/amr_dec.c index 4881a63..78ac04d 100644 --- a/modules/amr_dec/amr_dec.c +++ b/modules/amr_dec/amr_dec.c @@ -250,7 +250,7 @@ GF_MediaDecoder *NewAMRDecoder() AMRDec *dec; GF_MediaDecoder *ifce; GF_SAFEALLOC(ifce , GF_MediaDecoder); - dec = malloc(sizeof(AMRDec)); + dec = gf_malloc(sizeof(AMRDec)); memset(dec, 0, sizeof(AMRDec)); ifce->privateStack = dec; ifce->CanHandleStream = AMR_CanHandleStream; @@ -271,17 +271,19 @@ GF_MediaDecoder *NewAMRDecoder() void DeleteAMRDecoder(GF_BaseDecoder *ifcg) { AMRCTX(); - free(ctx); - free(ifcg); + gf_free(ctx); + gf_free(ifcg); } -Bool QueryInterface(u32 InterfaceType) +GF_EXPORT +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_MEDIA_DECODER_INTERFACE: return 1; - case GF_NET_CLIENT_INTERFACE: return 1; - default: return 0; - } + static u32 si [] = { + GF_NET_CLIENT_INTERFACE, + GF_MEDIA_DECODER_INTERFACE, + 0 + }; + return si; } GF_InputService *NewAESReader(); diff --git a/modules/amr_dec/amr_dec.def b/modules/amr_dec/amr_dec.def deleted file mode 100644 index a8a336a..0000000 --- a/modules/amr_dec/amr_dec.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_amr_dec.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/amr_dec/amr_in.c b/modules/amr_dec/amr_in.c index 07516f2..b9625b0 100644 --- a/modules/amr_dec/amr_in.c +++ b/modules/amr_dec/amr_in.c @@ -27,6 +27,15 @@ #include <gpac/constants.h> #include <gpac/isomedia.h> + +enum +{ + TYPE_AMR = 0, + TYPE_AMR_WB, + TYPE_EVRC, + TYPE_SMV, +}; + typedef struct { GF_ClientService *service; @@ -69,20 +78,20 @@ static GF_ESD *AMR_GetESD(AMR_Reader *read) esd->slConfig->useAccessUnitEndFlag = esd->slConfig->useAccessUnitStartFlag = 0; esd->slConfig->hasRandomAccessUnitsOnlyFlag = 1; - if ((read->mtype==GF_ISOM_SUBTYPE_3GP_AMR) || (read->mtype==GF_ISOM_SUBTYPE_3GP_AMR_WB)) { + if ((read->mtype==TYPE_AMR) || (read->mtype==TYPE_AMR_WB)) { esd->decoderConfig->objectTypeIndication = GPAC_OTI_MEDIA_GENERIC; dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(dsi, read->mtype); - gf_bs_write_u32(dsi, (read->mtype==GF_ISOM_SUBTYPE_3GP_AMR) ? 8000 : 16000); + gf_bs_write_u32(dsi, (read->mtype==TYPE_AMR) ? 8000 : 16000); gf_bs_write_u16(dsi, 1); - gf_bs_write_u16(dsi, (read->mtype==GF_ISOM_SUBTYPE_3GP_AMR) ? 160 : 320); + gf_bs_write_u16(dsi, (read->mtype==TYPE_AMR) ? 160 : 320); gf_bs_write_u8(dsi, 16); gf_bs_write_u8(dsi, 1); gf_bs_get_content(dsi, & esd->decoderConfig->decoderSpecificInfo->data, & esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(dsi); } - else if (read->mtype==GF_ISOM_SUBTYPE_3GP_EVRC) esd->decoderConfig->objectTypeIndication = 0xA0; - else if (read->mtype==GF_ISOM_SUBTYPE_3GP_SMV) esd->decoderConfig->objectTypeIndication = 0xA1; + else if (read->mtype==TYPE_EVRC) esd->decoderConfig->objectTypeIndication = 0xA0; + else if (read->mtype==TYPE_SMV) esd->decoderConfig->objectTypeIndication = 0xA1; return esd; } @@ -130,19 +139,19 @@ static Bool AMR_ConfigureFromFile(AMR_Reader *read) if (!strnicmp(magic, "#!AMR\n", 6)) { fseek(read->stream, 6, SEEK_SET); - read->mtype = GF_ISOM_SUBTYPE_3GP_AMR; + read->mtype = TYPE_AMR; } else if (!strnicmp(magic, "#!EVRC\n", 7)) { fseek(read->stream, 7, SEEK_SET); read->start_offset = 7; - read->mtype = GF_ISOM_SUBTYPE_3GP_EVRC; + read->mtype = TYPE_EVRC; } else if (!strnicmp(magic, "#!SMV\n", 6)) { fseek(read->stream, 6, SEEK_SET); - read->mtype = GF_ISOM_SUBTYPE_3GP_SMV; + read->mtype = TYPE_SMV; } else if (!strnicmp(magic, "#!AMR-WB\n", 9)) { - read->mtype = GF_ISOM_SUBTYPE_3GP_AMR_WB; + read->mtype = TYPE_AMR_WB; read->start_offset = 9; read->sample_rate = 16000; read->block_size = 320; @@ -160,10 +169,10 @@ static Bool AMR_ConfigureFromFile(AMR_Reader *read) while (!feof(read->stream)) { u8 ft = fgetc(read->stream); switch (read->mtype) { - case GF_ISOM_SUBTYPE_3GP_AMR: - case GF_ISOM_SUBTYPE_3GP_AMR_WB: + case TYPE_AMR: + case TYPE_AMR_WB: ft = (ft >> 3) & 0x0F; - size = (read->mtype==GF_ISOM_SUBTYPE_3GP_AMR_WB) ? GF_AMR_WB_FRAME_SIZE[ft] : GF_AMR_FRAME_SIZE[ft]; + size = (read->mtype==TYPE_AMR_WB) ? GF_AMR_WB_FRAME_SIZE[ft] : GF_AMR_FRAME_SIZE[ft]; break; default: for (i=0; i<GF_SMV_EVRC_RATE_TO_SIZE_NB; i++) { @@ -302,7 +311,7 @@ static GF_Err AMR_CloseService(GF_InputService *plug) if (read->dnload) gf_term_download_del(read->dnload); read->dnload = NULL; - if (read->data) free(read->data); + if (read->data) gf_free(read->data); read->data = NULL; gf_term_on_disconnect(read->service, NULL, GF_OK); return GF_OK; @@ -362,7 +371,7 @@ static GF_Err AMR_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) GF_Err e = GF_STREAM_NOT_FOUND; if (read->ch == channel) { read->ch = NULL; - if (read->data) free(read->data); + if (read->data) gf_free(read->data); read->data = NULL; e = GF_OK; } @@ -453,11 +462,11 @@ fetch_next: toc = fgetc(read->stream); switch (read->mtype) { - case GF_ISOM_SUBTYPE_3GP_AMR: + case TYPE_AMR: ft = (toc >> 3) & 0x0F; read->data_size = GF_AMR_FRAME_SIZE[ft]; break; - case GF_ISOM_SUBTYPE_3GP_AMR_WB: + case TYPE_AMR_WB: ft = (toc >> 3) & 0x0F; read->data_size = GF_AMR_WB_FRAME_SIZE[ft]; break; @@ -485,7 +494,7 @@ fetch_next: read->data_size++; read->sl_hdr.compositionTimeStamp = read->current_time; - read->data = malloc(sizeof(char) * (read->data_size+read->pad_bytes)); + read->data = gf_malloc(sizeof(char) * (read->data_size+read->pad_bytes)); read->data[0] = toc; if (read->data_size>1) fread(read->data + 1, read->data_size-1, 1, read->stream); if (read->pad_bytes) memset(read->data + read->data_size, 0, sizeof(char) * read->pad_bytes); @@ -502,7 +511,7 @@ static GF_Err AMR_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) if (read->ch == channel) { if (!read->data) return GF_BAD_PARAM; - free(read->data); + gf_free(read->data); read->data = NULL; read->current_time += read->block_size; return GF_OK; @@ -513,7 +522,7 @@ static GF_Err AMR_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) GF_InputService *NewAESReader() { AMR_Reader *reader; - GF_InputService *plug = malloc(sizeof(GF_InputService)); + GF_InputService *plug = gf_malloc(sizeof(GF_InputService)); memset(plug, 0, sizeof(GF_InputService)); GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC AMR/EVRC/SMV Reader", "gpac distribution") @@ -528,7 +537,7 @@ GF_InputService *NewAESReader() plug->ChannelGetSLP = AMR_ChannelGetSLP; plug->ChannelReleaseSLP = AMR_ChannelReleaseSLP; - reader = malloc(sizeof(AMR_Reader)); + reader = gf_malloc(sizeof(AMR_Reader)); memset(reader, 0, sizeof(AMR_Reader)); plug->priv = reader; return plug; @@ -538,19 +547,20 @@ void DeleteAESReader(void *ifce) { GF_InputService *plug = (GF_InputService *) ifce; AMR_Reader *read = plug->priv; - free(read); - free(plug); + gf_free(read); + gf_free(plug); } #ifdef GPAC_AMR_IN_STANDALONE GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_NET_CLIENT_INTERFACE: return 1; - default: return 0; - } + static u32 si [] = { + GF_NET_CLIENT_INTERFACE, + 0 + }; + return si; } GF_EXPORT diff --git a/modules/amr_dec/amr_nb/typedefs.h b/modules/amr_dec/amr_nb/typedefs.h index 63b0bfd..0777505 100644 --- a/modules/amr_dec/amr_nb/typedefs.h +++ b/modules/amr_dec/amr_nb/typedefs.h @@ -177,11 +177,11 @@ typedef struct { #define PC #define PLATFORM "PC" #define LSBFIRST -#else -#elif defined(WIN32) +#elif defined(WIN32) || defined(_WIN32_WCE) #define PC #define PLATFORM "PC" #define LSBFIRST +#else #error "can't determine architecture; adapt typedefs.h to your platform" #endif diff --git a/modules/amr_float_dec/Makefile b/modules/amr_float_dec/Makefile index 48f8476..74074bd 100644 --- a/modules/amr_float_dec/Makefile +++ b/modules/amr_float_dec/Makefile @@ -38,20 +38,14 @@ SRCS := $(OBJS:.o=.c) LIB=gm_amr_float_dec.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols amr_float_dec.def -endif - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) +#LDFLAGS+=-export-symbols amr_float_dec.def endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac %.o: %.c diff --git a/modules/amr_float_dec/amr_float_dec.c b/modules/amr_float_dec/amr_float_dec.c index fe4574a..816d454 100644 --- a/modules/amr_float_dec/amr_float_dec.c +++ b/modules/amr_float_dec/amr_float_dec.c @@ -63,7 +63,7 @@ static GF_Err AMR_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) GF_BitStream *bs; u32 packed; AMRFTCTX(); - if (esd->decoderConfig || !esd->decoderConfig->decoderSpecificInfo) return GF_NOT_SUPPORTED; + if (esd->dependsOnESID || !esd->decoderConfig->decoderSpecificInfo) return GF_NOT_SUPPORTED; /*AMRWB dec is another module*/ if (!strnicmp(esd->decoderConfig->decoderSpecificInfo->data, "sawb", 4)) ctx->is_amr_wb = 1; @@ -73,9 +73,9 @@ static GF_Err AMR_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); gf_bs_read_u32(bs); + gf_bs_read_u32(bs); + ctx->num_channels = gf_bs_read_u16(bs); gf_bs_read_u16(bs); - gf_bs_read_u16(bs); - ctx->num_channels = gf_bs_read_u8(bs); gf_bs_read_u8(bs); packed = gf_bs_read_u8(bs); gf_bs_del(bs); @@ -263,7 +263,7 @@ GF_MediaDecoder *NewAMRFTDecoder() AMRFTDec *dec; GF_MediaDecoder *ifce; GF_SAFEALLOC(ifce , GF_MediaDecoder); - dec = malloc(sizeof(AMRFTDec)); + dec = gf_malloc(sizeof(AMRFTDec)); memset(dec, 0, sizeof(AMRFTDec)); ifce->privateStack = dec; ifce->CanHandleStream = AMR_CanHandleStream; @@ -284,22 +284,23 @@ GF_MediaDecoder *NewAMRFTDecoder() void DeleteAMRFTDecoder(GF_BaseDecoder *ifcg) { AMRFTCTX(); - free(ctx); - free(ifcg); + gf_free(ctx); + gf_free(ifcg); } /*re-include AMR reader (we coul make it an independant module...)*/ GF_InputService *NewAESReader(); void DeleteAESReader(void *ifce); -Bool QueryInterface(u32 InterfaceType) +GF_EXPORT +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_MEDIA_DECODER_INTERFACE: return 1; - case GF_NET_CLIENT_INTERFACE: return 1; - default: - return 0; - } + static u32 si [] = { + GF_NET_CLIENT_INTERFACE, + GF_MEDIA_DECODER_INTERFACE, + 0 + }; + return si; } GF_BaseInterface *LoadInterface(u32 InterfaceType) diff --git a/modules/amr_float_dec/amr_float_dec.def b/modules/amr_float_dec/amr_float_dec.def deleted file mode 100644 index b6049f5..0000000 --- a/modules/amr_float_dec/amr_float_dec.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_amr_float_dec.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/amr_float_dec/amr_nb_ft/dummy b/modules/amr_float_dec/amr_nb_ft/dummy deleted file mode 100644 index e69de29..0000000 diff --git a/modules/amr_float_dec/amr_wb_ft/dummy b/modules/amr_float_dec/amr_wb_ft/dummy deleted file mode 100644 index e69de29..0000000 diff --git a/modules/audio_filter/Makefile b/modules/audio_filter/Makefile new file mode 100644 index 0000000..27f34ce --- /dev/null +++ b/modules/audio_filter/Makefile @@ -0,0 +1,53 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/audio_filter + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +#common obj +OBJS= audio_filter.o + +SRCS := $(OBJS:.o=.c) + +LIB=gm_audio_filter.$(DYN_LIB_SUFFIX) + +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) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif + diff --git a/modules/audio_filter/audio_filter.c b/modules/audio_filter/audio_filter.c new file mode 100644 index 0000000..b68034a --- /dev/null +++ b/modules/audio_filter/audio_filter.c @@ -0,0 +1,283 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Telecom ParisTech 20010- + * All rights reserved + * + * Authors: Jean Le Feuvre + * + * This file is part of GPAC / sample audio filter 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/modules/audio_out.h> +#include <gpac/math.h> + +#ifndef PI +#define PI GF_PI +#endif + +typedef struct +{ + u32 type; + Bool inplace; + u32 sample_block_size; + + /*distorsion param*/ + Double gain, clip, volume; + + /*delai param*/ + char *delai_buffer, *block_buffer; + u32 delai_ms, delai_buffer_size, block_size, nb_bytes; + Double feedback; +} FilterContext; + +static GF_Err ProcessDistorsion(GF_AudioFilter *af, void *in_block, u32 in_block_size, void *out_block, u32 *out_block_size) +{ + u32 i, count; + register Double temp; + Double gain, clip, volume; + FilterContext *ctx = af->udta; + + gain=ctx->gain / 100.0; + clip=ctx->clip * 32768.0 / 100.0; + volume=ctx->volume / 100.0; + count = in_block_size>>1; + for(i=0; i<count; i++) { + temp = (Double) ((s16 *) in_block)[i]; + temp = temp * gain; + + if (temp > clip) temp = clip; + else if (temp < -clip) temp = -clip; + temp = temp*volume; + + if (temp > 32767.0) temp = 32767.0; + else if (temp < -32768.0) temp = -32768.0; + ((s16 *) out_block)[i] = (s16) temp; + } + *out_block_size = in_block_size; + return GF_OK; +} + +static GF_Err ProcessIdentity(GF_AudioFilter *af, void *in_block, u32 in_block_size, void *out_block, u32 *out_block_size) +{ + FilterContext *ctx = af->udta; + if (!ctx->inplace) + memcpy(out_block, in_block, in_block_size); + + *out_block_size = in_block_size; + return GF_OK; +} + +static GF_Err ProcessDelai(GF_AudioFilter *af, void *in_block, u32 in_block_size, void *out_block, u32 *out_block_size) +{ + s16 *in, *delay, *out; + u32 i; + register Double temp; + Double ratio, vol; + FilterContext *ctx = af->udta; + assert(ctx->block_size==in_block_size); + + /*fill delai buffer*/ + if (ctx->nb_bytes<ctx->delai_buffer_size) { + memcpy(ctx->delai_buffer + ctx->nb_bytes, in_block, in_block_size); + ctx->nb_bytes += in_block_size; + memcpy(out_block, in_block, in_block_size); + *out_block_size = in_block_size; + return GF_OK; + } + memcpy(ctx->block_buffer, ctx->delai_buffer, ctx->block_size); + memmove(ctx->delai_buffer, ctx->delai_buffer + ctx->block_size, (ctx->delai_buffer_size-ctx->block_size) ); + + vol = ctx->volume / 100; + ratio = ctx->feedback/100; + delay = (s16 *) ctx->block_buffer; + in = (s16 *) in_block; + out = (s16 *) out_block; + for (i=0; i<ctx->block_size/2; i++) { + temp = (1-ratio)*in[i] + ratio*delay[i]; + temp = temp*vol; + out[i] = (s16) temp; + } + memcpy(ctx->delai_buffer + ctx->nb_bytes - in_block_size, out_block, in_block_size); + + *out_block_size = ctx->block_size; + return GF_OK; +} + + +static GF_Err Configure(GF_AudioFilter *af, u32 in_sr, u32 in_bps, u32 in_nb_ch, u32 in_ch_cfg, u32 *out_nb_ch, u32 *out_ch_cfg, u32 *out_block_len_in_samples, u32 *delay_ms, Bool *inplace) +{ + FilterContext *ctx = af->udta; + + *inplace = ctx->inplace; + *delay_ms = 0; + *out_nb_ch = in_nb_ch; + *out_ch_cfg = in_ch_cfg; + + switch (ctx->type) { + case 2: + ctx->block_size = ctx->sample_block_size * in_nb_ch * in_bps / 8; + ctx->delai_buffer_size = in_nb_ch * in_bps * ctx->delai_ms * in_sr / 1000 / 8; + ctx->delai_buffer_size /= ctx->block_size; + ctx->delai_buffer_size *= ctx->block_size; + + if (ctx->delai_buffer) gf_free(ctx->delai_buffer); + ctx->delai_buffer = gf_malloc(sizeof(char)*ctx->delai_buffer_size); + memset(ctx->delai_buffer, 0, sizeof(char)*ctx->delai_buffer_size); + + if (ctx->block_buffer) gf_free(ctx->block_buffer); + ctx->block_buffer = gf_malloc(sizeof(char)*ctx->block_size); + memset(ctx->block_buffer, 0, sizeof(char)*ctx->block_size); + break; + } + + *out_block_len_in_samples = ctx->sample_block_size; + return GF_OK; +} + +static Bool SetFilter(GF_AudioFilter *af, char *filter) +{ + char *opts; + FilterContext *ctx = af->udta; + if (!filter) return 0; + + opts = strchr(filter, '@'); + if (opts) opts[0] = 0; + + ctx->sample_block_size = 0; + ctx->inplace = 1; + ctx->volume = 100.0; + + if (!stricmp(filter, "identity")) { + af->Process = ProcessIdentity; + ctx->type = 0; + } + else if (!stricmp(filter, "distorsion")) { + ctx->gain=50.0; + ctx->clip=100.0; + af->Process = ProcessDistorsion; + ctx->type = 1; + } + else if (!stricmp(filter, "delai")) { + ctx->delai_ms = 100; + ctx->feedback = 50; + af->Process = ProcessDelai; + ctx->type = 2; + ctx->sample_block_size = 120; + } else { + if (opts) opts[0] = '@'; + return 0; + } + if (opts) { + opts[0] = '@'; + opts++; + + while (1) { + char *sep = strchr(opts, ';'); + if (sep) sep[0] = 0; + + if (!strnicmp(opts, "blocksize=", 10)) ctx->sample_block_size = atoi(opts+10); + else if (!stricmp(opts, "noinplace")) ctx->inplace = 0; + else if (!strnicmp(opts, "gain=", 5)) ctx->gain = atof(opts+5); + else if (!strnicmp(opts, "clip=", 5)) ctx->clip = atof(opts+5); + else if (!strnicmp(opts, "volume=", 7)) ctx->volume = atof(opts+7); + else if (!strnicmp(opts, "delai=", 6)) ctx->delai_ms = atoi(opts+6); + else if (!strnicmp(opts, "feedback=", 9)) { + ctx->feedback = atof(opts+9); + if (ctx->feedback>100) ctx->feedback=100; + } + + if (!sep) break; + sep[0] = ';'; + opts = sep+1; + } + } + + return 1; +} + + +static Bool SetOption(GF_AudioFilter *af, char *option, char *value) +{ + return 1; +} +static void Reset(GF_AudioFilter *af) +{ +} + + +void *NewAudioFilter() +{ + FilterContext *ctx; + GF_AudioFilter *mod; + GF_SAFEALLOC(ctx, FilterContext); + if(!ctx) return NULL; + + GF_SAFEALLOC(mod, GF_AudioFilter); + if(!mod) { + gf_free(ctx); + return NULL; + } + mod->udta = ctx; + mod->SetFilter = SetFilter; + mod->Configure = Configure; + mod->Process = ProcessIdentity; + mod->SetOption = SetOption; + mod->Reset = Reset; + + GF_REGISTER_MODULE_INTERFACE(mod, GF_AUDIO_FILTER_INTERFACE, "Sample Audio Filter", "gpac distribution"); + return mod; +} + +void DeleteAudioFilter(void *ifce) +{ + GF_AudioFilter *dr = (GF_AudioFilter*) ifce; + FilterContext *ctx = (FilterContext *)dr->udta; + + if (ctx->delai_buffer) gf_free(ctx->delai_buffer); + gf_free(ctx); + gf_free(dr); +} + + +/* + * ******************************************************************** + * interface + */ +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_AUDIO_FILTER_INTERFACE, + 0 + }; + return si; +} + +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + if (InterfaceType == GF_AUDIO_FILTER_INTERFACE) + return NewAudioFilter(); + return NULL; +} + +void ShutdownInterface(GF_BaseInterface *ifce) +{ + if (ifce->InterfaceType==GF_AUDIO_FILTER_INTERFACE) + DeleteAudioFilter((GF_AudioFilter*)ifce); +} diff --git a/modules/bifs_dec/Makefile b/modules/bifs_dec/Makefile index 2f639f8..ae04b1f 100644 --- a/modules/bifs_dec/Makefile +++ b/modules/bifs_dec/Makefile @@ -21,20 +21,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_bifs_dec.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols bifs_dec.def +#LDFLAGS+=-export-symbols bifs_dec.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_bifs_dec-static.so $(OBJS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/bifs_dec/bifs_dec.c b/modules/bifs_dec/bifs_dec.c index e5a3ce9..7dce2b0 100644 --- a/modules/bifs_dec/bifs_dec.c +++ b/modules/bifs_dec/bifs_dec.c @@ -26,9 +26,11 @@ #include <gpac/bifs.h> #include <gpac/constants.h> +#ifndef GPAC_DISABLE_BIFS + typedef struct { - GF_InlineScene *pScene; + GF_Scene *pScene; GF_Terminal *app; GF_BifsDecoder *codec; u32 PL, nb_streams; @@ -47,7 +49,7 @@ static GF_Err BIFS_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapabilit return GF_OK; } -GF_Err BIFS_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder) +GF_Err BIFS_AttachScene(GF_SceneDecoder *plug, GF_Scene *scene, Bool is_scene_decoder) { BIFSPriv *priv = (BIFSPriv *)plug->privateStack; if (priv->codec) return GF_BAD_PARAM; @@ -55,6 +57,7 @@ GF_Err BIFS_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_sc priv->app = scene->root_od->term; priv->codec = gf_bifs_decoder_new(scene->graph, 0); + gf_bifs_decoder_set_extraction_path(priv->codec, (char *) gf_modules_get_option((GF_BaseInterface *)plug, "General", "CacheDirectory"), scene->root_od->net_service->url); /*ignore all size info on anim streams*/ if (!is_scene_decoder) gf_bifs_decoder_ignore_size_info(priv->codec); return GF_OK; @@ -93,13 +96,17 @@ static GF_Err BIFS_DetachStream(GF_BaseDecoder *plug, u16 ES_ID) static GF_Err BIFS_ProcessData(GF_SceneDecoder*plug, char *inBuffer, u32 inBufferLength, u16 ES_ID, u32 AU_time, u32 mmlevel) { + Double ts_offset; + s32 time; GF_Err e = GF_OK; BIFSPriv *priv = (BIFSPriv *)plug->privateStack; - e = gf_bifs_decode_au(priv->codec, ES_ID, inBuffer, inBufferLength, ((Double)AU_time)/1000.0); + time = (s32) AU_time; + ts_offset = ((Double)time)/1000.0; + e = gf_bifs_decode_au(priv->codec, ES_ID, inBuffer, inBufferLength, ts_offset); /*if scene not attached do it*/ - gf_inline_attach_to_compositor(priv->pScene); + gf_scene_attach_to_compositor(priv->pScene); return e; } @@ -128,8 +135,8 @@ void DeleteBIFSDec(GF_BaseDecoder *plug) BIFSPriv *priv = (BIFSPriv *)plug->privateStack; /*in case something went wrong*/ if (priv->codec) gf_bifs_decoder_del(priv->codec); - free(priv); - free(plug); + gf_free(priv); + gf_free(plug); } GF_BaseDecoder *NewBIFSDec() @@ -154,23 +161,30 @@ GF_BaseDecoder *NewBIFSDec() return (GF_BaseDecoder *) tmp; } + +#endif /*GPAC_DISABLE_BIFS*/ + + GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_SCENE_DECODER_INTERFACE: - return 1; - default: - return 0; - } + static u32 si [] = { +#ifndef GPAC_DISABLE_BIFS + GF_SCENE_DECODER_INTERFACE, +#endif + 0 + }; + return si; } GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { switch (InterfaceType) { +#ifndef GPAC_DISABLE_BIFS case GF_SCENE_DECODER_INTERFACE: return (GF_BaseInterface *)NewBIFSDec(); +#endif default: return NULL; } @@ -180,8 +194,11 @@ GF_EXPORT void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_BIFS case GF_SCENE_DECODER_INTERFACE: DeleteBIFSDec((GF_BaseDecoder *)ifce); break; +#endif } } + diff --git a/modules/bifs_dec/bifs_dec.def b/modules/bifs_dec/bifs_dec.def deleted file mode 100644 index 3b239e6..0000000 --- a/modules/bifs_dec/bifs_dec.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_bifs_dec.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/ctx_load/Makefile b/modules/ctx_load/Makefile index cfce40b..860a091 100644 --- a/modules/ctx_load/Makefile +++ b/modules/ctx_load/Makefile @@ -21,21 +21,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_ctx_load.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols ctx_load.def -endif - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) +#LDFLAGS+=-export-symbols ctx_load.def endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ctx_load-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/ctx_load/ctx_load.c b/modules/ctx_load/ctx_load.c index 807d0cb..cb250c7 100644 --- a/modules/ctx_load/ctx_load.c +++ b/modules/ctx_load/ctx_load.c @@ -28,19 +28,21 @@ #include <gpac/network.h> #include <gpac/nodes_mpeg4.h> +#ifndef GPAC_DISABLE_VRML typedef struct { - GF_InlineScene *inline_scene; + GF_Scene *scene; GF_Terminal *app; GF_SceneManager *ctx; GF_SceneLoader load; char *file_name; - u32 file_size; + u64 file_size; u32 load_flags; u32 nb_streams; u32 base_stream_id; - u32 last_check_time, last_check_size; + u32 last_check_time; + u64 last_check_size; /*mp3 import from flash*/ GF_List *files_to_delete; /*progressive loading support for XMT X3D*/ @@ -61,20 +63,20 @@ static GF_Err CTXLoad_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapabi return GF_OK; } -static void ODS_SetupOD(GF_InlineScene *is, GF_ObjectDescriptor *od) +static void ODS_SetupOD(GF_Scene *scene, GF_ObjectDescriptor *od) { GF_ObjectManager *odm; - odm = gf_inline_find_odm(is, od->objectDescriptorID); + odm = gf_scene_find_odm(scene, od->objectDescriptorID); /*remove the old OD*/ if (odm) gf_odm_disconnect(odm, 1); odm = gf_odm_new(); odm->OD = od; - odm->term = is->root_od->term; - odm->parentscene = is; - gf_list_add(is->ODlist, odm); + odm->term = scene->root_od->term; + odm->parentscene = scene; + gf_list_add(scene->resources, odm); /*locate service owner*/ - gf_odm_setup_object(odm, is->root_od->net_service); + gf_odm_setup_object(odm, scene->root_od->net_service); } @@ -82,30 +84,50 @@ static void CTXLoad_Reset(CTXLoadPriv *priv) { if (priv->ctx) gf_sm_del(priv->ctx); priv->ctx = NULL; - gf_sg_reset(priv->inline_scene->graph); + gf_sg_reset(priv->scene->graph); if (priv->load_flags != 3) priv->load_flags = 0; while (gf_list_count(priv->files_to_delete)) { char *fileName = (char*)gf_list_get(priv->files_to_delete, 0); gf_list_rem(priv->files_to_delete, 0); gf_delete_file(fileName); - free(fileName); + gf_free(fileName); } } -void CTXLoad_OnActivate(GF_Node *node) +static void CTXLoad_ExecuteConditional(M_Conditional *c, GF_Scene *scene) { - GF_InlineScene *is = (GF_InlineScene *) gf_node_get_private(node); + GF_List *clist = c->buffer.commandList; + c->buffer.commandList = NULL; + + gf_sg_command_apply_list(gf_node_get_graph((GF_Node*)c), clist, gf_scene_get_time(scene)); + + if (c->buffer.commandList != NULL) { + while (gf_list_count(clist)) { + GF_Command *sub_com = (GF_Command *)gf_list_get(clist, 0); + gf_sg_command_del(sub_com); + gf_list_rem(clist, 0); + } + gf_list_del(clist); + } else { + c->buffer.commandList = clist; + } +} + +static void CTXLoad_OnActivate(GF_Node *node, GF_Route *route) +{ + GF_Scene *scene = (GF_Scene *) gf_node_get_private(node); M_Conditional*c = (M_Conditional*)node; /*always apply in parent graph to handle protos correctly*/ - if (c->activate) gf_sg_command_apply_list(gf_node_get_graph(node), c->buffer.commandList, gf_inline_get_time(is)); + if (c->activate) CTXLoad_ExecuteConditional(c, scene); } -void CTXLoad_OnReverseActivate(GF_Node *node) + +static void CTXLoad_OnReverseActivate(GF_Node *node, GF_Route *route) { - GF_InlineScene *is = (GF_InlineScene *) gf_node_get_private(node); + GF_Scene *scene = (GF_Scene *) gf_node_get_private(node); M_Conditional*c = (M_Conditional*)node; /*always apply in parent graph to handle protos correctly*/ if (!c->reverseActivate) - gf_sg_command_apply_list(gf_node_get_graph(node), c->buffer.commandList, gf_inline_get_time(is)); + CTXLoad_ExecuteConditional(c, scene); } void CTXLoad_NodeCallback(void *cbk, u32 type, GF_Node *node, void *param) @@ -122,15 +144,16 @@ void CTXLoad_NodeCallback(void *cbk, u32 type, GF_Node *node, void *param) static Bool CTXLoad_CheckDownload(CTXLoadPriv *priv) { - u32 size; + u64 size; FILE *f; u32 now = gf_sys_clock(); if (!priv->file_size && (now - priv->last_check_time < 1000) ) return 0; - f = fopen(priv->file_name, "rt"); - fseek(f, 0, SEEK_END); - size = ftell(f); + f = gf_f64_open(priv->file_name, "rt"); + if (!f) return 0; + gf_f64_seek(f, 0, SEEK_END); + size = gf_f64_tell(f); fclose(f); /*we MUST have a complete file for now ...*/ @@ -150,11 +173,11 @@ static GF_Err CTXLoad_Setup(GF_BaseDecoder *plug) CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack; if (!priv->file_name) return GF_BAD_PARAM; - priv->ctx = gf_sm_new(priv->inline_scene->graph); + priv->ctx = gf_sm_new(priv->scene->graph); memset(&priv->load, 0, sizeof(GF_SceneLoader)); priv->load.ctx = priv->ctx; - priv->load.is = priv->inline_scene; - priv->load.scene_graph = priv->inline_scene->graph; + priv->load.is = priv->scene; + priv->load.scene_graph = priv->scene->graph; priv->load.fileName = priv->file_name; priv->load.flags = GF_SM_LOAD_FOR_PLAYBACK; priv->load.localPath = gf_modules_get_option((GF_BaseInterface *)plug, "General", "CacheDirectory"); @@ -189,7 +212,7 @@ static GF_Err CTXLoad_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) priv->file_size = gf_bs_read_u32(bs); gf_bs_del(bs); size = esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32); - priv->file_name = (char *) malloc(sizeof(char)*(1 + size) ); + priv->file_name = (char *) gf_malloc(sizeof(char)*(1 + size) ); memcpy(priv->file_name, esd->decoderConfig->decoderSpecificInfo->data + sizeof(u32), sizeof(char)*(esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32)) ); priv->file_name[size] = 0; priv->nb_streams = 1; @@ -226,12 +249,12 @@ static GF_Err CTXLoad_DetachStream(GF_BaseDecoder *plug, u16 ES_ID) return GF_OK; } -static GF_Err CTXLoad_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder) +static GF_Err CTXLoad_AttachScene(GF_SceneDecoder *plug, GF_Scene *scene, Bool is_scene_decoder) { CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack; if (priv->ctx) return GF_BAD_PARAM; - priv->inline_scene = scene; + priv->scene = scene; priv->app = scene->root_od->term; gf_sg_set_node_callback(scene->graph, CTXLoad_NodeCallback); @@ -290,8 +313,8 @@ static void CTXLoad_CheckStreams(CTXLoadPriv *priv ) if (au && sc->in_root_od && (au->timing>max_dur)) max_dur = (u32) (au->timing * 1000 / sc->timeScale); } if (max_dur) { - priv->inline_scene->root_od->duration = max_dur; - gf_inline_set_duration(priv->inline_scene); + priv->scene->root_od->duration = max_dur; + gf_scene_set_duration(priv->scene); } } @@ -325,7 +348,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB gf_sm_load_done(&priv->load); priv->file_pos = 0; /*this will call detach scene*/ - gf_inline_disconnect(priv->inline_scene, 1); + gf_scene_disconnect(priv->scene, 0); return CTXLoad_Setup((GF_BaseDecoder *)plug); } i=0; @@ -347,14 +370,14 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB u32 entry_time; char file_buf[4096+1]; if (!priv->src) { - priv->src = fopen(priv->file_name, "rb"); + priv->src = gf_f64_open(priv->file_name, "rb"); if (!priv->src) return GF_URL_ERROR; priv->file_pos = 0; } priv->load.type = GF_SM_LOAD_XMTA; e = GF_OK; entry_time = gf_sys_clock(); - fseek(priv->src, priv->file_pos, SEEK_SET); + gf_f64_seek(priv->src, priv->file_pos, SEEK_SET); while (1) { u32 diff, nb_read; nb_read = fread(file_buf, 1, 4096, priv->src); @@ -376,9 +399,9 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB diff = gf_sys_clock() - entry_time; if (diff > priv->sax_max_duration) break; } - if (!priv->inline_scene->graph_attached) { - gf_sg_set_scene_size_info(priv->inline_scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics); - gf_inline_attach_to_compositor(priv->inline_scene); + if (!priv->scene->graph_attached) { + gf_sg_set_scene_size_info(priv->scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics); + gf_scene_attach_to_compositor(priv->scene); CTXLoad_CheckStreams(priv); } @@ -392,11 +415,11 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB e = gf_sm_load_init(&priv->load); if (!e) { CTXLoad_CheckStreams(priv); - gf_sg_set_scene_size_info(priv->inline_scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics); + gf_sg_set_scene_size_info(priv->scene->graph, priv->ctx->scene_width, priv->ctx->scene_height, priv->ctx->is_pixel_metrics); /*VRML, override base clock*/ if ((priv->load.type==GF_SM_LOAD_VRML) || (priv->load.type==GF_SM_LOAD_X3DV) || (priv->load.type==GF_SM_LOAD_X3D)) { /*override clock callback*/ - gf_sg_set_scene_time_callback(priv->inline_scene->graph, CTXLoad_GetVRMLTime); + gf_sg_set_scene_time_callback(priv->scene->graph, CTXLoad_GetVRMLTime); } } } @@ -407,7 +430,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB gf_sm_load_done(&priv->load); } - if (e) { + if (e<0) { gf_sm_load_done(&priv->load); gf_sm_del(priv->ctx); priv->ctx = NULL; @@ -419,7 +442,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB if (priv->load_flags==2) { CTXLoad_CheckStreams(priv); if (!gf_list_count(priv->ctx->streams)) { - gf_inline_attach_to_compositor(priv->inline_scene); + gf_scene_attach_to_compositor(priv->scene); } } } @@ -453,7 +476,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB if (au_time > stream_time) break; - if (au->is_rap) last_rap = j-1; + if (au->flags & GF_SM_AU_RAP) last_rap = j-1; } j = last_rap; } @@ -472,7 +495,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB j--; gf_list_rem(sc->AUs, j); gf_list_del(au->commands); - free(au); + gf_free(au); } continue; } @@ -487,7 +510,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB /*apply the commands*/ k=0; while ((com = (GF_Command *)gf_list_enum(au->commands, &k))) { - e = gf_sg_command_apply(priv->inline_scene->graph, com, 0); + e = gf_sg_command_apply(priv->scene->graph, com, 0); if (e) break; /*remove commands on base layer*/ if (can_delete_com) { @@ -517,7 +540,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB esd = (GF_ESD*)gf_list_get(od->ESDescriptors, 0); if (!esd) { if (od->URLString) { - ODS_SetupOD(priv->inline_scene, od); + ODS_SetupOD(priv->scene, od); } else { gf_odf_desc_del((GF_Descriptor *) od); } @@ -546,12 +569,12 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB /*set ST to private scene to get sure the stream will be redirected to us*/ esd->decoderConfig->streamType = GF_STREAM_PRIVATE_SCENE; esd->dependsOnESID = priv->base_stream_id; - ODS_SetupOD(priv->inline_scene, od); + ODS_SetupOD(priv->scene, od); } else if (esd->decoderConfig->streamType==GF_STREAM_INTERACT) { GF_UIConfig *cfg = (GF_UIConfig *) esd->decoderConfig->decoderSpecificInfo; gf_odf_encode_ui_config(cfg, &esd->decoderConfig->decoderSpecificInfo); gf_odf_desc_del((GF_Descriptor *) cfg); - ODS_SetupOD(priv->inline_scene, od); + ODS_SetupOD(priv->scene, od); } else { gf_odf_desc_del((GF_Descriptor *) od); } @@ -559,7 +582,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB } /*text import*/ if (mux->textNode) { -#ifdef GPAC_READ_ONLY +#ifdef GPAC_DISABLE_MEDIA_IMPORT gf_odf_desc_del((GF_Descriptor *) od); continue; #else @@ -572,14 +595,14 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB /*set ST to private scene and dependency to base to get sure the stream will be redirected to us*/ esd->decoderConfig->streamType = GF_STREAM_PRIVATE_SCENE; esd->dependsOnESID = priv->base_stream_id; - ODS_SetupOD(priv->inline_scene, od); + ODS_SetupOD(priv->scene, od); continue; #endif } /*soundstreams are a bit of a pain, they may be declared before any data gets written*/ if (mux->delete_file) { - FILE *t = fopen(mux->file_name, "rb"); + FILE *t = gf_f64_open(mux->file_name, "rb"); if (!t) { keep_com = 1; gf_list_insert(odU->objectDescriptors, od, 0); @@ -588,16 +611,16 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB fclose(t); } /*remap to remote URL*/ - remote = strdup(mux->file_name); + remote = gf_strdup(mux->file_name); k = od->objectDescriptorID; /*if files were created we'll have to clean up (swf import)*/ - if (mux->delete_file) gf_list_add(priv->files_to_delete, strdup(remote)); + if (mux->delete_file) gf_list_add(priv->files_to_delete, gf_strdup(remote)); gf_odf_desc_del((GF_Descriptor *) od); od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); od->URLString = remote; od->objectDescriptorID = k; - ODS_SetupOD(priv->inline_scene, od); + ODS_SetupOD(priv->scene, od); } if (keep_com) break; } @@ -606,7 +629,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB { GF_ODRemove *odR = (GF_ODRemove*)com; for (k=0; k<odR->NbODs; k++) { - GF_ObjectManager *odm = gf_inline_find_odm(priv->inline_scene, odR->OD_ID[k]); + GF_ObjectManager *odm = gf_scene_find_odm(priv->scene, odR->OD_ID[k]); if (odm) gf_odm_disconnect(odm, 1); } } @@ -626,8 +649,8 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB } sc->last_au_time = au_time + 1; /*attach graph to renderer*/ - if (!priv->inline_scene->graph_attached) - gf_inline_attach_to_compositor(priv->inline_scene); + if (!priv->scene->graph_attached) + gf_scene_attach_to_compositor(priv->scene); if (e) return e; /*for root streams remove completed AUs (no longer needed)*/ @@ -635,7 +658,7 @@ static GF_Err CTXLoad_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inB j--; gf_list_rem(sc->AUs, j); gf_list_del(au->commands); - free(au); + gf_free(au); } } } @@ -685,11 +708,11 @@ Bool CTXLoad_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, u32 ObjectTyp void DeleteContextLoader(GF_BaseDecoder *plug) { CTXLoadPriv *priv = (CTXLoadPriv *)plug->privateStack; - if (priv->file_name) free(priv->file_name); + if (priv->file_name) gf_free(priv->file_name); assert(!priv->ctx); gf_list_del(priv->files_to_delete); - free(priv); - free(plug); + gf_free(priv); + gf_free(plug); } GF_BaseDecoder *NewContextLoader() @@ -715,23 +738,27 @@ GF_BaseDecoder *NewContextLoader() return (GF_BaseDecoder*)tmp; } +#endif + GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_SCENE_DECODER_INTERFACE: - return 1; - default: - return 0; - } +static u32 si [] = { +#ifndef GPAC_DISABLE_VRML + GF_SCENE_DECODER_INTERFACE, +#endif + 0}; + return si; } GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { switch (InterfaceType) { +#ifndef GPAC_DISABLE_VRML case GF_SCENE_DECODER_INTERFACE: return (GF_BaseInterface *)NewContextLoader(); +#endif default: return NULL; } @@ -741,8 +768,12 @@ GF_EXPORT void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_VRML case GF_SCENE_DECODER_INTERFACE: DeleteContextLoader((GF_BaseDecoder *)ifce); break; +#endif } } + + diff --git a/modules/ctx_load/ctx_load.def b/modules/ctx_load/ctx_load.def deleted file mode 100644 index 98f3ac7..0000000 --- a/modules/ctx_load/ctx_load.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_ctx_load.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/demo_is/Makefile b/modules/demo_is/Makefile new file mode 100644 index 0000000..1c8b4a1 --- /dev/null +++ b/modules/demo_is/Makefile @@ -0,0 +1,57 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/demo_is + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +#common obj +OBJS= demo_is.o + +SRCS := $(OBJS:.o=.c) + +LIB=gm_demo_is.$(DYN_LIB_SUFFIX) +ifeq ($(CONFIG_WIN32),yes) +#LDFLAGS+=-export-symbols demo_is.def +endif + + +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) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/demo_is/demo-sensor.bt b/modules/demo_is/demo-sensor.bt new file mode 100644 index 0000000..73f5683 --- /dev/null +++ b/modules/demo_is/demo-sensor.bt @@ -0,0 +1,86 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of a demo InputSensor" "" "GPAC Regression Tests" "$Date: 2009-05-20 15:59:18 $ - $Revision: 1.1 $" "(C) 2009 ENST"] + title "InputSensor Test - Demo device" + } + Transform2D { + translation 0 90 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TEXT Text { + string ["DemoSensor", ""] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 30 + } + } + } + ] + } + InputSensor { + url [od:10] + buffer { + REPLACE TEXT.string[1] BY "" + } + } + ] +} + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 5 + decConfigDescr DecoderConfigDescriptor { + streamType 10 + decSpecificInfo UIConfig { + deviceName "DemoSensor" + } + } + } + ] + } + ] +} + diff --git a/modules/demo_is/demo_is.c b/modules/demo_is/demo_is.c new file mode 100644 index 0000000..06e4209 --- /dev/null +++ b/modules/demo_is/demo_is.c @@ -0,0 +1,102 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * This file is part of GPAC / Dummy input 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/modules/codec.h> +#include <gpac/scenegraph_vrml.h> + +static Bool DEV_RegisterDevice(struct __input_device *ifce, const char *urn, GF_BitStream *dsi, void (*AddField)(struct __input_device *_this, u32 fieldType, const char *name)) +{ + if (strcmp(urn, "DemoSensor")) return 0; + + AddField(ifce, GF_SG_VRML_SFSTRING, "content"); + + return 1; +} + +static void DEV_Start(struct __input_device *ifce) +{ + GF_BitStream *bs; + char *buf, *szWord; + u32 len, val, i, buf_size; + + szWord = "Hello InputSensor!"; + + bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + /*HTK sensor buffer format: SFString - SFInt32 - SFFloat*/ + gf_bs_write_int(bs, 1, 1); + len = strlen(szWord); + val = gf_get_bit_size(len); + gf_bs_write_int(bs, val, 5); + gf_bs_write_int(bs, len, val); + for (i=0; i<len; i++) gf_bs_write_int(bs, szWord[i], 8); + + gf_bs_align(bs); + gf_bs_get_content(bs, &buf, &buf_size); + gf_bs_del(bs); + + ifce->DispatchFrame(ifce, buf, buf_size); + gf_free(buf); +} + +static void DEV_Stop(struct __input_device *ifce) +{ +} + + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_INPUT_DEVICE_INTERFACE, + 0 + }; + return si; +} + +GF_EXPORT +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + GF_InputSensorDevice *plug; + if (InterfaceType != GF_INPUT_DEVICE_INTERFACE) return NULL; + + GF_SAFEALLOC(plug, GF_InputSensorDevice); + GF_REGISTER_MODULE_INTERFACE(plug, GF_INPUT_DEVICE_INTERFACE, "GPAC Demo InputSensor", "gpac distribution") + + plug->RegisterDevice = DEV_RegisterDevice; + plug->Start = DEV_Start; + plug->Stop = DEV_Stop; + + return (GF_BaseInterface *)plug; +} + +GF_EXPORT +void ShutdownInterface(GF_BaseInterface *bi) +{ + GF_InputSensorDevice *ifcn = (GF_InputSensorDevice*)bi; + if (ifcn->InterfaceType==GF_INPUT_DEVICE_INTERFACE) { + gf_free(bi); + } +} diff --git a/modules/directfb_out/Makefile b/modules/directfb_out/Makefile new file mode 100644 index 0000000..74ad100 --- /dev/null +++ b/modules/directfb_out/Makefile @@ -0,0 +1,58 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/directfb_out + +CFLAGS= $(OPTFLAGS) +CFLAGS+=-I$(SRC_PATH)/include -I$(DIRECTFB_INC_PATH) +LDFLAGS+=-ldirectfb-1.4 -lfusion-1.4 -ldirect-1.4 + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + + + + +#common obj +OBJS=directfb_out.o + +SRCS := $(OBJS:.o=.c) + +LIB=gm_directfb_out.$(DYN_LIB_SUFFIX) + + +all: $(LIB) + + +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -L../../bin/gcc -lgpac -o ../../bin/gcc/$@ $(OBJS) + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +clean: + rm -f $(OBJS) ../../bin/gcc/$(LIB) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/directfb_out/directfb_out.c b/modules/directfb_out/directfb_out.c new file mode 100755 index 0000000..8691a6b --- /dev/null +++ b/modules/directfb_out/directfb_out.c @@ -0,0 +1,345 @@ +#include "directfb_out.h" + +#define DirectFBVID() DirectFBVidCtx *ctx = (DirectFBVidCtx *)driv->opaque +// this was supposed to contain argc and argv from main !!!!! +int argc; +char **argv = {"toto"}; + +u32 DirectFBVid_TranslatePixelFormatToGPAC(u32 dfbpf) +{ + switch (dfbpf) { + case DSPF_RGB16: return GF_PIXEL_RGB_565; + case DSPF_RGB555: return GF_PIXEL_RGB_555; + case DSPF_RGB24: return GF_PIXEL_RGB_24; + case DSPF_RGB32: return GF_PIXEL_RGB_32; + case DSPF_ARGB: return GF_PIXEL_ARGB; +// case DSPF_YUY2: return GF_PIXEL_YUY2; +// case DSPF_YV12: return GF_PIXEL_YV12; +// case DSPF_I420: return GF_PIXEL_YV12; + default: return 0; + } +} + +u32 DirectFBVid_TranslatePixelFormatFromGPAC(u32 dfbpf) +{ + switch (dfbpf) { + case GF_PIXEL_RGB_565: return DSPF_RGB16; + case GF_PIXEL_RGB_555 : return DSPF_RGB555; + case GF_PIXEL_RGB_24 : return DSPF_RGB24; + case GF_PIXEL_RGB_32 : return DSPF_RGB32; + case GF_PIXEL_ARGB: return DSPF_ARGB; + case GF_PIXEL_YUY2 : return DSPF_YUY2; + case GF_PIXEL_YV12 : return DSPF_YV12; + default: return 0; + } +} + +GF_Err DirectFBVid_Setup(GF_VideoOutput *driv, void *os_handle, void *os_display, u32 init_flags) +{ + DFBResult err; + DFBSurfaceDescription dsc; + DFBSurfacePixelFormat dfbpf; + DFBAccelerationMask mask; + + DirectFBVID(); + ctx->is_init = 0; + argc=0; + DFBCHECK(DirectFBInit(&argc, & (argv) )); + + DirectFBSetOption ("bg-none", NULL); + DirectFBSetOption ("no-init-layer", NULL); + + /* create the super interface */ + DFBCHECK(DirectFBCreate( &(ctx->dfb) )); + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] Initialization\n")); + + /* create an input buffer for key events */ +// DFBCHECK(ctx->dfb->CreateInputEventBuffer( ctx->dfb, DICAPS_KEYS, DFB_FALSE, &key_events )); + + /* Set the cooperative level */ + err = ctx->dfb->SetCooperativeLevel( ctx->dfb, DFSCL_FULLSCREEN ); + if (err) + DirectFBError( "Failed to set cooperative level", err ); + + /* Get the primary surface, i.e. the surface of the primary layer. */ + dsc.flags = DSDESC_CAPS; + dsc.caps = DSCAPS_PRIMARY | DSCAPS_DOUBLE; + + if (ctx->use_systems_memory) + dsc.caps |= DSCAPS_SYSTEMONLY; + + DFBCHECK(ctx->dfb->CreateSurface( ctx->dfb, &dsc, &(ctx->primary) )); + + ctx->primary->GetPixelFormat( ctx->primary, &dfbpf ); + ctx->pixel_format = DirectFBVid_TranslatePixelFormatToGPAC(dfbpf); + ctx->primary->GetSize( ctx->primary, &(ctx->width), &(ctx->height) ); + ctx->primary->Clear( ctx->primary, 0, 0, 0, 0xFF); + + ctx->primary->GetAccelerationMask( ctx->primary, NULL, &mask ); + if (mask & DFXL_DRAWLINE ) // DrawLine() is accelerated. + accel_drawline = 1; + if (mask & DFXL_FILLRECTANGLE) // FillRectangle() is accelerated. + accel_fillrect = 1; + + printf("accel_drawline=%d\n",accel_drawline); + printf("accel_fillrect=%d\n",accel_fillrect); + + ctx->is_init = 1; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] Initialization success\n")); + return GF_OK; +} + +static void DirectFBVid_Shutdown(GF_VideoOutput *driv) +{ + DirectFBVID(); + if (!ctx->is_init) return; + ctx->primary->Release( ctx->primary ); +// ctx->key_events->Release( ctx->key_events ); + ctx->dfb->Release( ctx->dfb ); + ctx->is_init = 0; +} + +static GF_Err DirectFBVid_Flush(GF_VideoOutput *driv, GF_Window *dest) +{ + + DirectFBVID(); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] Flipping backbuffer\n")); + ctx->primary->Flip( ctx->primary, NULL, DSFLIP_ONSYNC ); +} + + +GF_Err DirectFBVid_SetFullScreen(GF_VideoOutput *driv, u32 bFullScreenOn, u32 *screen_width, u32 *screen_height) +{ + DFBResult err; + DirectFBVID(); + + *screen_width = ctx->width; + *screen_height = ctx->height; + + return GF_OK; +} + +#if 0 +Bool DirectFBVid_ProcessMessageQueue(DirectFBVidCtx *ctx, GF_VideoOutput *driv) +{ + DFBInputEvent ev; + u32 err; + + while (ctx->key_events->GetEvent( ctx->key_events, DFB_EVENT(&ev) ) == DFB_OK) + { + if (ev.type == DIET_KEYPRESS) + { + switch (ev.key_symbol) + { + case DIKS_ESCAPE: + case DIKS_SMALL_Q: + case DIKS_CAPITAL_Q: + case DIKS_BACK: + case DIKS_STOP: + DirectFBVid_Shutdown(driv); + exit( 42 ); + break; + default: + break; + } + } + } + return 1; +} +#endif + +static GF_Err DirectFBVid_ProcessEvent(GF_VideoOutput *driv, GF_Event *evt) +{ + DirectFBVID(); + if (!evt) { + //DirectFBVid_ProcessMessageQueue(ctx, driv); + return GF_OK; + } + switch (evt->type) { + case GF_EVENT_SIZE: + if ((ctx->width !=evt->size.width) || (ctx->height != evt->size.height)) { + GF_Event gpac_evt; + gpac_evt.type = GF_EVENT_SIZE; + gpac_evt.size.width = ctx->width; + gpac_evt.size.height = ctx->height; + driv->on_event(driv->evt_cbk_hdl, &gpac_evt); + } + return GF_OK; + + case GF_EVENT_VIDEO_SETUP: + if (evt->setup.opengl_mode) return GF_NOT_SUPPORTED; + + if ((ctx->width !=evt->setup.width) || (ctx->height != evt->setup.height)) { + GF_Event gpac_evt; + gpac_evt.type = GF_EVENT_SIZE; + gpac_evt.size.width = ctx->width; + gpac_evt.size.height = ctx->height; + driv->on_event(driv->evt_cbk_hdl, &gpac_evt); + } + return GF_OK; + default: + return GF_OK; + } +} + +static GF_Err DirectFBVid_LockBackBuffer(GF_VideoOutput *driv, GF_VideoSurface *video_info, u32 do_lock) +{ + DFBResult ret; + u32 pitch; + void *buf; + u32 width, height; + DFBSurfacePixelFormat format; + + DirectFBVID(); + if (!ctx->primary) return GF_BAD_PARAM; + if (do_lock) + { + if (!video_info) return GF_BAD_PARAM; + ret = ctx->primary->Lock(ctx->primary, DSLF_READ | DSLF_WRITE, &buf, &pitch); + if (ret != DFB_OK) return GF_IO_ERR; + + video_info->width = ctx->width; + video_info->height = ctx->height; + video_info->pitch_x = 0; + video_info->pitch_y = pitch; + video_info->video_buffer = buf; + video_info->pixel_format = ctx->pixel_format; + video_info->is_hardware_memory = !ctx->use_systems_memory; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DirectFB] backbuffer locked\n")); + } else { + ctx->primary->Unlock(ctx->primary); + } + return GF_OK; + +} + +static GF_Err DirectFBVid_Blit(GF_VideoOutput *driv, GF_VideoSurface *video_src, GF_Window *src_wnd, GF_Window *dst_wnd, u32 overlay_type) +{ + DirectFBVID(); + if (overlay_type == 0) return GF_OK; + else return GF_NOT_SUPPORTED; + //return GF_OK; +} + +static void DirectFBVid_DrawHLine(GF_VideoOutput *driv, u32 x, u32 y, u32 length, GF_Color color) +{ + DirectFBVID(); + u8 r, g, b; + + SET_DRAWING_FLAGS( DSDRAW_NOFX ); + + r = GF_COL_R(color); + g = GF_COL_G(color); + b = GF_COL_B(color); + + ctx->primary->SetColor(ctx->primary, r, g, b, 0xFF); // no alpha + ctx->primary->DrawLine(ctx->primary, x, y, x+length, y); + +} + +static void DirectFBVid_DrawHLineAlpha(GF_VideoOutput *driv, u32 x, u32 y, u32 length, GF_Color color, u8 alpha) +{ + DirectFBVID(); + u8 r, g, b; + + + SET_DRAWING_FLAGS( DSDRAW_BLEND ); // use alpha + + r = GF_COL_R(color); + g = GF_COL_G(color); + b = GF_COL_B(color); + + ctx->primary->SetColor(ctx->primary, r, g, b, alpha); + ctx->primary->DrawLine(ctx->primary, x, y, x+length, y); + +} + +static void DirectFBVid_DrawRectangle(GF_VideoOutput *driv, u32 x, u32 y, u32 width, u32 height, GF_Color color) +{ + DirectFBVID(); + + u8 r, g, b, a; + + r = GF_COL_R(color); + g = GF_COL_G(color); + b = GF_COL_B(color); + a = GF_COL_A(color); + + SET_DRAWING_FLAGS( DSDRAW_NOFX ); + + ctx->primary->SetColor(ctx->primary, r, g, b, a); + ctx->primary->FillRectangle(ctx->primary, x, y, width, height); + //ctx->primary->Blit( ctx->primary, ctx->primary, NULL, x, y ); +} + +void *DirectFBNewVideo() +{ + DirectFBVidCtx *ctx; + GF_VideoOutput *driv; + + driv = gf_malloc(sizeof(GF_VideoOutput)); + memset(driv, 0, sizeof(GF_VideoOutput)); + GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "DirectFB Video Output", "gpac distribution"); + + ctx = gf_malloc(sizeof(DirectFBVidCtx)); + memset(ctx, 0, sizeof(DirectFBVidCtx)); + + /* GF_VideoOutput */ + driv->opaque = ctx; + driv->Setup = DirectFBVid_Setup; + driv->Shutdown = DirectFBVid_Shutdown; + driv->Flush = DirectFBVid_Flush; + driv->SetFullScreen = DirectFBVid_SetFullScreen; + driv->ProcessEvent = DirectFBVid_ProcessEvent; + driv->LockBackBuffer = DirectFBVid_LockBackBuffer; + driv->LockOSContext = NULL; + driv->Blit = DirectFBVid_Blit; + driv->hw_caps |= GF_VIDEO_HW_HAS_RGB | GF_VIDEO_HW_HAS_RGBA | GF_VIDEO_HW_HAS_YUV | GF_VIDEO_HW_HAS_LINE_BLIT; + + if (driv->hw_caps & GF_VIDEO_HW_HAS_LINE_BLIT) + { + driv->DrawHLine = DirectFBVid_DrawHLine; + driv->DrawHLineAlpha = DirectFBVid_DrawHLineAlpha; + driv->DrawRectangle = DirectFBVid_DrawRectangle; + } + + return driv; +} + +void DirectFBDeleteVideo(void *ifce) +{ + GF_VideoOutput *driv = (GF_VideoOutput *)ifce; + DirectFBVID(); + gf_free(ctx); + gf_free(driv); +} + + +/*interface query*/ +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + 0 + }; + return si; +} + +/*interface create*/ +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return DirectFBNewVideo(); + return NULL; +} + +/*interface destroy*/ +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { + case GF_VIDEO_OUTPUT_INTERFACE: + DirectFBDeleteVideo(ifce); + break; + } +} diff --git a/modules/directfb_out/directfb_out.h b/modules/directfb_out/directfb_out.h new file mode 100755 index 0000000..bb10e83 --- /dev/null +++ b/modules/directfb_out/directfb_out.h @@ -0,0 +1,51 @@ +#ifndef _DIRECTFB_OUT_H_ +#define _DIRECTFB_OUT_H_ + + +#include <gpac/modules/video_out.h> + +/* DirectFB */ +#define __DIRECT__STDTYPES__ //prevent u8, s8, ... definitions by directFB as we have them in GPAC +#include <directfb.h> +#include <directfb_strings.h> +#include <directfb_util.h> +#include <direct/util.h> + +static int do_xor = 0; +static int accel_drawline = 0; +static int accel_fillrect = 0; + +/* macro for a safe call to DirectFB functions */ +#define DFBCHECK(x...) \ + do { \ + err = x; \ + if (err != DFB_OK) { \ + fprintf( stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ + DirectFBErrorFatal( #x, err ); \ + } \ + } while (0) + +#define SET_DRAWING_FLAGS( flags ) \ + ctx->primary->SetDrawingFlags( ctx->primary, (flags) | (do_xor ? DSDRAW_XOR : 0) ) + + +typedef struct +{ + /* the super interface */ + IDirectFB *dfb; + /* the primary surface */ + IDirectFBSurface *primary; + + /* screen width, height */ + u32 width, height, pixel_format; + Bool use_systems_memory, disable_acceleration, disable_aa, is_init; + + /* Input interfaces: event buffer */ +// IDirectFBEventBuffer *key_events; + +} DirectFBVidCtx; + +void *DirectFBNewVideo(); +void DirectFBDeleteVideo(void *ifce); + +#endif diff --git a/modules/dummy_in/Makefile b/modules/dummy_in/Makefile index 5be8f45..4e19719 100644 --- a/modules/dummy_in/Makefile +++ b/modules/dummy_in/Makefile @@ -21,20 +21,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_dummy_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols dummy_in.def +#LDFLAGS+=-export-symbols dummy_in.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_dummy_in-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/dummy_in/dummy_in.c b/modules/dummy_in/dummy_in.c index 9a07559..f5b36aa 100644 --- a/modules/dummy_in/dummy_in.c +++ b/modules/dummy_in/dummy_in.c @@ -40,7 +40,7 @@ typedef struct { /*the service we're responsible for*/ GF_ClientService *service; - char szURL[2048]; + char *url; u32 oti; GF_List *channels; @@ -66,7 +66,7 @@ Bool DC_RemoveChannel(DCReader *read, LPNETCHANNEL ch) while ((dc = (DummyChannel *)gf_list_enum(read->channels, &i))) { if (dc->ch && dc->ch==ch) { gf_list_rem(read->channels, i-1); - free(dc); + gf_free(dc); return 1; } } @@ -77,23 +77,32 @@ Bool DC_CanHandleURL(GF_InputService *plug, const char *url) { char *sExt = strrchr(url, '.'); if (sExt) { + Bool ok; + char *cgi_par; if (!strnicmp(sExt, ".gz", 3)) sExt = strrchr(sExt, '.'); if (!strnicmp(url, "rtsp://", 7)) return 0; + cgi_par = strchr(sExt, '?'); + if (cgi_par) cgi_par[0] = 0; /*the mpeg-4 mime types for bt/xmt are NOT registered at all :)*/ - if (gf_term_check_extension(plug, "application/x-bt", "bt bt.gz btz", "MPEG-4 Text (BT)", sExt)) return 1; - if (gf_term_check_extension(plug, "application/x-xmt", "xmt xmt.gz xmtz", "MPEG-4 Text (XMT)", sExt)) return 1; - //if (gf_term_check_extension(plug, "application/x-xmta", "xmta xmta.gz xmtaz", "MPEG-4 Text (XMT)", sExt)) return 1; + ok = gf_term_check_extension(plug, "application/x-bt", "bt bt.gz btz", "MPEG-4 Text (BT)", sExt); + if (!ok) ok = gf_term_check_extension(plug, "application/x-xmt", "xmt xmt.gz xmtz", "MPEG-4 Text (XMT)", sExt);; + //if (!ok) ok = gf_term_check_extension(plug, "application/x-xmta", "xmta xmta.gz xmtaz", "MPEG-4 Text (XMT)", sExt); /*but all these ones are*/ - if (gf_term_check_extension(plug, "model/vrml", "wrl wrl.gz", "VRML World", sExt)) return 1; - if (gf_term_check_extension(plug, "x-model/x-vrml", "wrl wrl.gz", "VRML World", sExt)) return 1; - if (gf_term_check_extension(plug, "model/x3d+vrml", "x3dv x3dv.gz x3dvz", "X3D/VRML World", sExt)) return 1; - if (gf_term_check_extension(plug, "model/x3d+xml", "x3d x3d.gz x3dz", "X3D/XML World", sExt)) return 1; - if (gf_term_check_extension(plug, "application/x-shockwave-flash", "swf", "Macromedia Flash Movie", sExt)) return 1; - if (gf_term_check_extension(plug, "image/svg+xml", "svg svg.gz svgz", "SVG Document", sExt)) return 1; - if (gf_term_check_extension(plug, "image/x-svgm", "svgm", "SVGM Document", sExt)) return 1; - if (gf_term_check_extension(plug, "application/x-LASeR+xml", "xsr", "LASeR Document", sExt)) return 1; + if (!ok) ok = gf_term_check_extension(plug, "model/vrml", "wrl wrl.gz", "VRML World", sExt); + if (!ok) ok = gf_term_check_extension(plug, "x-model/x-vrml", "wrl wrl.gz", "VRML World", sExt); + if (!ok) ok = gf_term_check_extension(plug, "model/x3d+vrml", "x3dv x3dv.gz x3dvz", "X3D/VRML World", sExt); + if (!ok) ok = gf_term_check_extension(plug, "model/x3d+xml", "x3d x3d.gz x3dz", "X3D/XML World", sExt); + if (!ok) ok = gf_term_check_extension(plug, "application/x-shockwave-flash", "swf", "Macromedia Flash Movie", sExt); + if (!ok) ok = gf_term_check_extension(plug, "image/svg+xml", "svg svg.gz svgz", "SVG Document", sExt); + if (!ok) ok = gf_term_check_extension(plug, "image/x-svgm", "svgm", "SVGM Document", sExt); + if (!ok) ok = gf_term_check_extension(plug, "application/x-LASeR+xml", "xsr", "LASeR Document", sExt); + if (!ok) ok = gf_term_check_extension(plug, "application/widget", "wgt", "W3C Widget Package", sExt); + if (!ok) ok = gf_term_check_extension(plug, "application/x-mpegu-widget", "mgt", "MPEG-U Widget Package", sExt); + + if (cgi_par) cgi_par[0] = '?'; + if (ok) return 1; } if (!strnicmp(url, "file://", 7) || !strstr(url, "://")) { @@ -105,7 +114,8 @@ Bool DC_CanHandleURL(GF_InputService *plug, const char *url) else if (!strcmp(rtype, "X3D")) handled = 1; else if (!strcmp(rtype, "svg")) handled = 1; else if (!strcmp(rtype, "bindings")) handled = 1; - free(rtype); + else if (!strcmp(rtype, "widget")) handled = 1; + gf_free(rtype); return handled; } } @@ -133,6 +143,8 @@ void DC_NetIO(void *cbk, GF_NETIO_Parameter *param) if (strstr(param->value, "image/svg+xml")) read->oti = GPAC_OTI_PRIVATE_SCENE_SVG; if (strstr(param->value, "image/x-svgm")) read->oti = GPAC_OTI_PRIVATE_SCENE_SVG; if (strstr(param->value, "application/x-LASeR+xml")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; + if (strstr(param->value, "application/widget")) read->oti = GPAC_OTI_PRIVATE_SCENE_WGT; + if (strstr(param->value, "application/x-mpegu-widget")) read->oti = GPAC_OTI_PRIVATE_SCENE_WGT; } return; } else if (!e && (param->msg_type!=GF_NETIO_DATA_EXCHANGE)) return; @@ -168,21 +180,21 @@ GF_Err DC_ConnectService(GF_InputService *plug, GF_ClientService *serv, const ch if (read->dnload) gf_term_download_del(read->dnload); read->dnload = NULL; - strcpy(read->szURL, url); - ext = strchr(read->szURL, '#'); + read->url = gf_strdup(url); + ext = strchr(read->url, '#'); if (ext) { char *anext; ext[0] = 0; - anext = strrchr(read->szURL, '.'); + anext = strrchr(read->url, '.'); ext[0] = '#'; ext = anext; } else { - ext = strrchr(read->szURL, '.'); + ext = strrchr(read->url, '.'); } if (ext && !stricmp(ext, ".gz")) { char *anext; ext[0] = 0; - anext = strrchr(read->szURL, '.'); + anext = strrchr(read->url, '.'); ext[0] = '.'; ext = anext; } @@ -215,6 +227,8 @@ GF_Err DC_ConnectService(GF_InputService *plug, GF_ClientService *serv, const ch read->oti = GPAC_OTI_PRIVATE_SCENE_LASER; else if (!stricmp(ext, "xbl")) read->oti = GPAC_OTI_PRIVATE_SCENE_XBL; + else if (!stricmp(ext, "wgt") || !stricmp(ext, "mgt")) + read->oti = GPAC_OTI_PRIVATE_SCENE_WGT; if (cgi_par) cgi_par[0] = '?'; } @@ -227,7 +241,8 @@ GF_Err DC_ConnectService(GF_InputService *plug, GF_ClientService *serv, const ch else if (!strcmp(rtype, "XMT-A")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; else if (!strcmp(rtype, "X3D")) read->oti = GPAC_OTI_PRIVATE_SCENE_GENERIC; else if (!strcmp(rtype, "bindings")) read->oti = GPAC_OTI_PRIVATE_SCENE_XBL; - free(rtype); + else if (!strcmp(rtype, "widget")) read->oti = GPAC_OTI_PRIVATE_SCENE_WGT; + gf_free(rtype); } } @@ -236,11 +251,11 @@ GF_Err DC_ConnectService(GF_InputService *plug, GF_ClientService *serv, const ch url += 7; } else if (strstr(url, "://")) { - DC_DownloadFile(plug, read->szURL); + DC_DownloadFile(plug, read->url); return GF_OK; } - test = fopen(read->szURL, "rt"); + test = gf_f64_open(read->url, "rt"); if (!test) { gf_term_on_connect(serv, NULL, GF_URL_ERROR); return GF_OK; @@ -288,11 +303,11 @@ static GF_Descriptor *DC_GetServiceDesc(GF_InputService *plug, u32 expect_type, uri = (char *) gf_dm_sess_get_cache_name(read->dnload); gf_dm_sess_get_stats(read->dnload, NULL, NULL, &size, NULL, NULL, NULL); } else { - FILE *f = fopen(read->szURL, "rt"); - fseek(f, 0, SEEK_END); - size = ftell(f); + FILE *f = gf_f64_open(read->url, "rt"); + gf_f64_seek(f, 0, SEEK_END); + size = (u32) gf_f64_tell(f); fclose(f); - uri = read->szURL; + uri = read->url; } bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, size); @@ -399,10 +414,13 @@ Bool DC_CanHandleURLInService(GF_InputService *plug, const char *url) } GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType==GF_NET_CLIENT_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_NET_CLIENT_INTERFACE, + 0 + }; + return si; } GF_EXPORT @@ -439,7 +457,8 @@ void ShutdownInterface(GF_BaseInterface *bi) DCReader *read = (DCReader*)ifcn->priv; assert(!gf_list_count(read->channels)); gf_list_del(read->channels); - free(read); - free(bi); + if( read->url) gf_free(read->url); + gf_free(read); + gf_free(bi); } } diff --git a/modules/dummy_in/dummy_in.def b/modules/dummy_in/dummy_in.def deleted file mode 100644 index 835b3b1..0000000 --- a/modules/dummy_in/dummy_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_dummy_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/dx_hw/Makefile b/modules/dx_hw/Makefile index 36e7005..f744883 100644 --- a/modules/dx_hw/Makefile +++ b/modules/dx_hw/Makefile @@ -3,7 +3,7 @@ include ../../config.mak vpath %.c $(SRC_PATH)/modules/dx_hw #DIRECTSOUND_VERSION is needed for GCC compil.. -CFLAGS= $(OPTFLAGS) -w -I$(SRC_PATH)/include -DGPAC_HAVE_CONFIG_H -DDIRECTSOUND_VERSION=0x0500 +CFLAGS= $(OPTFLAGS) -w -I$(SRC_PATH)/include -DDIRECTSOUND_VERSION=0x0500 ifeq ($(DEBUGBUILD), yes) CFLAGS+=-g @@ -31,7 +31,7 @@ SRCS := $(OBJS:.o=.c) LIB=gm_dx_hw.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols dx_hw.def +#LDFLAGS+=-export-symbols dx_hw.def endif all: $(LIB) diff --git a/modules/dx_hw/copy_pixels.c b/modules/dx_hw/copy_pixels.c index 9422709..2da0eb0 100644 --- a/modules/dx_hw/copy_pixels.c +++ b/modules/dx_hw/copy_pixels.c @@ -89,23 +89,26 @@ static void VR_write_yv12_to_yuv(GF_VideoSurface *vs, unsigned char *src, u32 s pU = src + src_stride * src_height; pV = src + 5*src_stride * src_height/4; + pY = pY + src_stride * src_wnd->y + src_wnd->x; - pU = pU + (src_stride * src_wnd->y / 2 + src_wnd->x) / 2; - pV = pV + (src_stride * src_wnd->y / 2 + src_wnd->x) / 2; + /*because of U and V downsampling by 2x2, working with odd Y offset will lead to a half-line shift between Y and UV components. We + therefore force an even Y offset for U and V planes.*/ + pU = pU + (src_stride * (src_wnd->y / 2) + src_wnd->x) / 2; + pV = pV + (src_stride * (src_wnd->y / 2) + src_wnd->x) / 2; if (is_planar_yuv(vs->pixel_format)) { /*complete source copy*/ - if ( (vs->pitch == (s32) src_stride) && (src_wnd->w == src_width) && (src_wnd->h == src_height)) { + if ( (vs->pitch_y == (s32) src_stride) && (src_wnd->w == src_width) && (src_wnd->h == src_height)) { assert(!src_wnd->x); assert(!src_wnd->y); memcpy(vs->video_buffer, pY, sizeof(unsigned char)*src_width*src_height); if (vs->pixel_format == GF_PIXEL_YV12) { - memcpy(vs->video_buffer + vs->pitch * vs->height, pV, sizeof(unsigned char)*src_width*src_height/4); - memcpy(vs->video_buffer + 5 * vs->pitch * vs->height/4, pU, sizeof(unsigned char)*src_width*src_height/4); + memcpy(vs->video_buffer + vs->pitch_y * vs->height, pV, sizeof(unsigned char)*src_width*src_height/4); + memcpy(vs->video_buffer + 5 * vs->pitch_y * vs->height/4, pU, sizeof(unsigned char)*src_width*src_height/4); } else { - memcpy(vs->video_buffer + vs->pitch * vs->height, pU, sizeof(unsigned char)*src_width*src_height/4); - memcpy(vs->video_buffer + 5 * vs->pitch * vs->height/4, pV, sizeof(unsigned char)*src_width*src_height/4); + memcpy(vs->video_buffer + vs->pitch_y * vs->height, pU, sizeof(unsigned char)*src_width*src_height/4); + memcpy(vs->video_buffer + 5 * vs->pitch_y * vs->height/4, pV, sizeof(unsigned char)*src_width*src_height/4); } } else { u32 i; @@ -115,31 +118,31 @@ static void VR_write_yv12_to_yuv(GF_VideoSurface *vs, unsigned char *src, u32 s dst = vs->video_buffer; src2 = (vs->pixel_format != GF_PIXEL_YV12) ? pU : pV; - dst2 = vs->video_buffer + vs->pitch * vs->height; + dst2 = vs->video_buffer + vs->pitch_y * vs->height; src3 = (vs->pixel_format != GF_PIXEL_YV12) ? pV : pU; - dst3 = vs->video_buffer + 5*vs->pitch * vs->height/4; + dst3 = vs->video_buffer + 5*vs->pitch_y * vs->height/4; for (i=0; i<src_wnd->h; i++) { memcpy(dst, src, src_wnd->w); src += src_stride; - dst += vs->pitch; + dst += vs->pitch_y; if (i<src_wnd->h/2) { memcpy(dst2, src2, src_wnd->w/2); src2 += src_stride/2; - dst2 += vs->pitch/2; + dst2 += vs->pitch_y/2; memcpy(dst3, src3, src_wnd->w/2); src3 += src_stride/2; - dst3 += vs->pitch/2; + dst3 += vs->pitch_y/2; } } } - } else if (vs->pixel_format==GF_PIXEL_UYVY) { + } else if (get_yuv_base(vs->pixel_format)==GF_PIXEL_UYVY) { u32 i, j; unsigned char *dst, *y, *u, *v; for (i=0; i<src_wnd->h; i++) { y = pY + i*src_stride; u = pU + (i/2) * src_stride/2; v = pV + (i/2) * src_stride/2; - dst = vs->video_buffer + i*vs->pitch; + dst = vs->video_buffer + i*vs->pitch_y; for (j=0; j<src_wnd->w/2;j++) { *dst = *u; @@ -156,14 +159,14 @@ static void VR_write_yv12_to_yuv(GF_VideoSurface *vs, unsigned char *src, u32 s y++; } } - } else if (vs->pixel_format==GF_PIXEL_YUY2) { + } else if (get_yuv_base(vs->pixel_format)==GF_PIXEL_YUY2) { u32 i, j; unsigned char *dst, *y, *u, *v; for (i=0; i<src_wnd->h; i++) { y = pY + i*src_stride; u = pU + (i/2) * src_stride/2; v = pV + (i/2) * src_stride/2; - dst = vs->video_buffer + i*vs->pitch; + dst = vs->video_buffer + i*vs->pitch_y; for (j=0; j<src_wnd->w/2;j++) { *dst = *y; @@ -187,7 +190,7 @@ static void VR_write_yv12_to_yuv(GF_VideoSurface *vs, unsigned char *src, u32 s y = pY + i*src_stride; u = pU + (i/2) * src_stride/2; v = pV + (i/2) * src_stride/2; - dst = vs->video_buffer + i*vs->pitch; + dst = vs->video_buffer + i*vs->pitch_y; for (j=0; j<src_wnd->w/2;j++) { *dst = *y; @@ -236,7 +239,7 @@ void rgb_to_24(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_ if (src_pf==vs->pixel_format) { for (i=0; i<src_wnd->h; i++) { - memcpy(vs->video_buffer + i*vs->pitch, src, sizeof(unsigned char) * BPP * src_wnd->w); + memcpy(vs->video_buffer + i*vs->pitch_y, src, sizeof(unsigned char) * BPP * src_wnd->w); src += src_stride; } return; @@ -256,13 +259,13 @@ void rgb_to_555(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src if (src_pf==vs->pixel_format) { for (i=0; i<src_wnd->h; i++) { - memcpy(vs->video_buffer + i*vs->pitch, src, sizeof(unsigned char) * BPP * src_wnd->w); + memcpy(vs->video_buffer + i*vs->pitch_y, src, sizeof(unsigned char) * BPP * src_wnd->w); } return; } /*nope get all pixels*/ for (i=0; i<src_wnd->h; i++) { - dst = vs->video_buffer + i*vs->pitch; + dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { switch (src_pf) { @@ -290,13 +293,13 @@ void rgb_to_565(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src if (src_pf==vs->pixel_format) { for (i=0; i<src_wnd->h; i++) { - memcpy(vs->video_buffer + i*vs->pitch, src, sizeof(unsigned char) * BPP * src_wnd->w); + memcpy(vs->video_buffer + i*vs->pitch_y, src, sizeof(unsigned char) * BPP * src_wnd->w); } return; } /*nope get all pixels*/ for (i=0; i<src_wnd->h; i++) { - dst = vs->video_buffer + i*vs->pitch; + dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { switch (src_pf) { @@ -325,7 +328,7 @@ void rgb_to_32(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_ if (src_pf==vs->pixel_format) { for (i=0; i<src_wnd->h; i++) { - memcpy(vs->video_buffer + i*vs->pitch, src, sizeof(unsigned char) * BPP * src_wnd->w); + memcpy(vs->video_buffer + i*vs->pitch_y, src, sizeof(unsigned char) * BPP * src_wnd->w); } return; } @@ -333,7 +336,7 @@ void rgb_to_32(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_ isBGR = vs->pixel_format==GF_PIXEL_BGR_32; if (isBGR) { for (i=0; i<src_wnd->h; i++) { - dst = vs->video_buffer + i*vs->pitch; + dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { switch (src_pf) { @@ -354,7 +357,7 @@ void rgb_to_32(GF_VideoSurface *vs, unsigned char *src, u32 src_stride, u32 src_ } } else { for (i=0; i<src_wnd->h; i++) { - dst = vs->video_buffer + i*vs->pitch; + dst = vs->video_buffer + i*vs->pitch_y; cur = src + i*src_stride; for (j=0; j<src_wnd->w; j++) { switch (src_pf) { @@ -382,25 +385,25 @@ void dx_copy_pixels(GF_VideoSurface *dst_s, const GF_VideoSurface *src_s, const if (get_yuv_base(src_s->pixel_format)==GF_PIXEL_YV12) { if (format_is_yuv(dst_s->pixel_format)) { /*generic YV planar to YUV (planar or not) */ - VR_write_yv12_to_yuv(dst_s, src_s->video_buffer, src_s->pitch, src_s->pixel_format, src_s->width, src_s->height, src_wnd); + VR_write_yv12_to_yuv(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->pixel_format, src_s->width, src_s->height, src_wnd); } else { - gf_stretch_bits(dst_s, (GF_VideoSurface*) src_s, NULL, (GF_Window *)src_wnd, 0, 0xFF, 0, NULL, NULL); + gf_stretch_bits(dst_s, (GF_VideoSurface*) src_s, NULL, (GF_Window *)src_wnd, 0xFF, 0, NULL, NULL); } } else { switch (dst_s->pixel_format) { case GF_PIXEL_RGB_555: - rgb_to_555(dst_s, src_s->video_buffer, src_s->pitch, src_s->width, src_s->height, src_s->pixel_format, src_wnd); + rgb_to_555(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->width, src_s->height, src_s->pixel_format, src_wnd); break; case GF_PIXEL_RGB_565: - rgb_to_565(dst_s, src_s->video_buffer, src_s->pitch, src_s->width, src_s->height, src_s->pixel_format, src_wnd); + rgb_to_565(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->width, src_s->height, src_s->pixel_format, src_wnd); break; case GF_PIXEL_RGB_24: case GF_PIXEL_BGR_24: - rgb_to_24(dst_s, src_s->video_buffer, src_s->pitch, src_s->width, src_s->height, src_s->pixel_format, src_wnd); + rgb_to_24(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->width, src_s->height, src_s->pixel_format, src_wnd); break; case GF_PIXEL_RGB_32: case GF_PIXEL_BGR_32: - rgb_to_32(dst_s, src_s->video_buffer, src_s->pitch, src_s->width, src_s->height, src_s->pixel_format, src_wnd); + rgb_to_32(dst_s, src_s->video_buffer, src_s->pitch_y, src_s->width, src_s->height, src_s->pixel_format, src_wnd); break; } } diff --git a/modules/dx_hw/dx_2d.c b/modules/dx_hw/dx_2d.c index dbbeb55..0ef7b65 100644 --- a/modules/dx_hw/dx_2d.c +++ b/modules/dx_hw/dx_2d.c @@ -159,6 +159,9 @@ GF_Err CreateBackBuffer(GF_VideoOutput *dr, u32 Width, u32 Height, Bool use_syst dd->systems_memory = 1; } } + if (dd->systems_memory) dr->hw_caps &= ~GF_VIDEO_HW_HAS_RGB; + else dr->hw_caps |= GF_VIDEO_HW_HAS_RGB; + ddsd.dwWidth = Width; ddsd.dwHeight = Height; @@ -355,7 +358,8 @@ static GF_Err DD_LockSurface(DDContext *dd, GF_VideoSurface *vi, void *surface) vi->video_buffer = desc.lpSurface; vi->width = desc.dwWidth; vi->height = desc.dwHeight; - vi->pitch = desc.lPitch; + vi->pitch_x = 0; + vi->pitch_y = desc.lPitch; vi->is_hardware_memory = dd->systems_memory ? 0 : 1; return GF_OK; } @@ -436,6 +440,7 @@ static GF_Err DD_BlitSurface(DDContext *dd, DDSurface *src, GF_Window *src_wnd, if (key) flags |= DDBLT_KEYSRC; hr = IDirectDrawSurface_Blt(dd->pBack, dst_wnd ? &r_dst : NULL, src->pSurface, src_wnd ? &r_src : NULL, flags, NULL); } + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX Out] Hardware blit result: %s\n", gf_error_to_string(FAILED(hr) ? GF_IO_ERR : GF_OK ) )); return FAILED(hr) ? GF_IO_ERR : GF_OK; } @@ -449,8 +454,14 @@ static DDSurface *DD_GetSurface(GF_VideoOutput *dr, u32 width, u32 height, u32 p HRESULT hr; DDCONTEXT; + if (!dd->pDD) return NULL; + /*yuv format*/ if (pixelformat_yuv(pixel_format)) { + /*some drivers give broken result if YUV surface dimensions are not even*/ + while (width%2) width++; + while (height%2) height++; + if (dr->yuv_pixel_format) { DDSurface *yuvp = &dd->yuv_pool; @@ -526,6 +537,10 @@ static GF_Err DD_Blit(GF_VideoOutput *dr, GF_VideoSurface *video_src, GF_Window DDSurface *pool; DDCONTEXT; + if (!video_src) { + if (overlay_type && dd->yuv_pool.pSurface) IDirectDrawSurface2_UpdateOverlay(dd->yuv_pool.pSurface, NULL, dd->pPrimary, NULL, DDOVER_HIDE, NULL); + return GF_OK; + } if (src_wnd) { w = src_wnd->w; h = src_wnd->h; @@ -534,6 +549,8 @@ static GF_Err DD_Blit(GF_VideoOutput *dr, GF_VideoSurface *video_src, GF_Window h = video_src->height; } /*get RGB or YUV pool surface*/ + //if (video_src->pixel_format==GF_PIXEL_YUVD) return GF_NOT_SUPPORTED; + if (video_src->pixel_format==GF_PIXEL_YUVD) video_src->pixel_format=GF_PIXEL_YV12; pool = DD_GetSurface(dr, w, h, video_src->pixel_format); if (!pool) return GF_IO_ERR; @@ -563,6 +580,10 @@ static GF_Err DD_Blit(GF_VideoOutput *dr, GF_VideoSurface *video_src, GF_Window dst.y = pt.y; MAKERECT(dst_rc, (&dst)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX] Blit surface to dest %d x %d - overlay type %s\n", dst.w, dst.h, + (overlay_type==0)? "none" : ((overlay_type==1) ? "Top-Level" : "ColorKey") + )); + #if 1 if (overlay_type==1) { hr = IDirectDrawSurface2_UpdateOverlay(pool->pSurface, &src_rc, dd->pPrimary, &dst_rc, DDOVER_SHOW, NULL); @@ -640,6 +661,7 @@ static GFINLINE Bool is_yuv_planar(u32 format) void DD_InitYUV(GF_VideoOutput *dr) { u32 w, h, j, i, num_yuv; + Bool force_yv12=0; DWORD numCodes; DWORD formats[30]; DWORD *codes; @@ -658,12 +680,12 @@ void DD_InitYUV(GF_VideoOutput *dr) #ifdef USE_DX_3 IDirectDraw_GetFourCCCodes(dd->pDD, &numCodes, NULL); if (!numCodes) return; - codes = (DWORD *)malloc(numCodes*sizeof(DWORD)); + codes = (DWORD *)gf_malloc(numCodes*sizeof(DWORD)); IDirectDraw_GetFourCCCodes(dd->pDD, &numCodes, codes); #else IDirectDraw7_GetFourCCCodes(dd->pDD, &numCodes, NULL); if (!numCodes) return; - codes = (DWORD *)malloc(numCodes*sizeof(DWORD)); + codes = (DWORD *)gf_malloc(numCodes*sizeof(DWORD)); IDirectDraw7_GetFourCCCodes(dd->pDD, &numCodes, codes); #endif @@ -672,7 +694,7 @@ void DD_InitYUV(GF_VideoOutput *dr) formats[num_yuv] = is_yuv_supported(codes[i]); if (formats[num_yuv]) num_yuv++; } - free(codes); + gf_free(codes); /*too bad*/ if (!num_yuv) { dr->hw_caps &= ~(GF_VIDEO_HW_HAS_YUV | GF_VIDEO_HW_HAS_YUV_OVERLAY); @@ -702,6 +724,8 @@ void DD_InitYUV(GF_VideoOutput *dr) goto rem_fmt; } now = gf_sys_clock() - now; + if (formats[i]== GF_PIXEL_YV12) + force_yv12=1; if (!checkPacked) { if (now<min_planar) { @@ -734,6 +758,9 @@ rem_fmt: SAFE_DD_RELEASE(dd->yuv_pool.pSurface); memset(&dd->yuv_pool, 0, sizeof(DDSurface)); } + opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "UseHardwareMemory"); + if (opt && !strcmp(opt, "never")) num_yuv = 0; + /*too bad*/ if (!num_yuv) { dr->hw_caps &= ~(GF_VIDEO_HW_HAS_YUV | GF_VIDEO_HW_HAS_YUV_OVERLAY); @@ -742,13 +769,14 @@ rem_fmt: return; } - if (best_planar && (min_planar < min_packed )) { + if (best_planar && (min_planar <= min_packed )) { dr->yuv_pixel_format = best_planar; } else { min_planar = min_packed; dr->yuv_pixel_format = best_packed; } - dr->yuv_pixel_format = GF_PIXEL_YV12; + if (force_yv12) + dr->yuv_pixel_format = GF_PIXEL_YV12; GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[DX Out] Picked YUV format %s - drawn in %d ms\n", gf_4cc_to_str(dr->yuv_pixel_format), min_planar)); dr->hw_caps |= GF_VIDEO_HW_HAS_YUV_OVERLAY; @@ -761,7 +789,8 @@ rem_fmt: gf_modules_set_option((GF_BaseInterface *)dr, "Video", "EnableOffscreenYUV", "yes"); } if (!strcmp(opt, "yes")) dr->hw_caps |= GF_VIDEO_HW_HAS_YUV; - + + /*get YUV overlay key*/ opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "OverlayColorKey"); /*no set is the default*/ @@ -780,7 +809,9 @@ rem_fmt: GF_Err DD_SetBackBufferSize(GF_VideoOutput *dr, u32 width, u32 height, Bool use_system_memory) { DDCONTEXT; +#ifndef GPAC_DISABLE_3D if (dd->output_3d_type) return GF_BAD_PARAM; +#endif if (!dd->ddraw_init) return InitDirectDraw(dr, width, height); return CreateBackBuffer(dr, width, height, use_system_memory); } @@ -788,7 +819,7 @@ GF_Err DD_SetBackBufferSize(GF_VideoOutput *dr, u32 width, u32 height, Bool use_ void DD_SetupDDraw(GF_VideoOutput *driv) { - driv->hw_caps |= GF_VIDEO_HW_HAS_COLOR_KEY; + driv->hw_caps |= GF_VIDEO_HW_HAS_RGB; driv->Blit = DD_Blit; driv->LockBackBuffer = DD_LockBackBuffer; driv->LockOSContext = LockOSContext; diff --git a/modules/dx_hw/dx_audio.c b/modules/dx_hw/dx_audio.c index 7565ffe..6396be6 100644 --- a/modules/dx_hw/dx_audio.c +++ b/modules/dx_hw/dx_audio.c @@ -372,8 +372,9 @@ static void DS_SetVolume(GF_AudioOutput *dr, u32 Volume) { LONG Vol; DSCONTEXT(); - if (Volume > 100) Volume = 100; - Vol = DSBVOLUME_MIN/2 + Volume * (DSBVOLUME_MAX-DSBVOLUME_MIN/2) / 100; + if (Volume > 100) Volume = DSBVOLUME_MAX; + else if(Volume == 0) Vol = DSBVOLUME_MIN; + else Vol = DSBVOLUME_MIN/2 + Volume * (DSBVOLUME_MAX-DSBVOLUME_MIN/2) / 100; IDirectSoundBuffer_SetVolume(ctx->pOutput, Vol); } @@ -419,10 +420,10 @@ void *NewAudioOutput() if( FAILED( hr = CoInitialize(NULL) ) ) return NULL; - ctx = malloc(sizeof(DSContext)); + ctx = gf_malloc(sizeof(DSContext)); memset(ctx, 0, sizeof(DSContext)); - driv = malloc(sizeof(GF_AudioOutput)); + driv = gf_malloc(sizeof(GF_AudioOutput)); memset(driv, 0, sizeof(GF_AudioOutput)); GF_REGISTER_MODULE_INTERFACE(driv, GF_AUDIO_OUTPUT_INTERFACE, "DirectSound Audio Output", "gpac distribution"); @@ -449,8 +450,8 @@ void DeleteAudioOutput(void *ifce) GF_AudioOutput *dr = (GF_AudioOutput *)ifce; DSCONTEXT(); - free(ctx); - free(ifce); + gf_free(ctx); + gf_free(ifce); CoUninitialize(); } diff --git a/modules/dx_hw/dx_hw.def b/modules/dx_hw/dx_hw.def deleted file mode 100644 index 56d452a..0000000 --- a/modules/dx_hw/dx_hw.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_dx_hw.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/dx_hw/dx_hw.h b/modules/dx_hw/dx_hw.h index b0ce10a..cc8693f 100644 --- a/modules/dx_hw/dx_hw.h +++ b/modules/dx_hw/dx_hw.h @@ -10,22 +10,25 @@ * 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. - * + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * */ #ifndef _DXHW_H #define _DXHW_H +#if defined(__GNUC__) && !defined(DIRECTSOUND_VERSION) +#define DIRECTSOUND_VERSION 0x0500 +#endif /*driver interfaces*/ #include <gpac/modules/audio_out.h> @@ -34,7 +37,12 @@ #include <gpac/constants.h> #include <gpac/thread.h> + +/* #include <windows.h> +*/ +#include <ddraw.h> + #include <mmsystem.h> #include <dsound.h> @@ -42,7 +50,13 @@ #include <vfw.h> #endif -#include <ddraw.h> +#ifdef _WIN32_WCE +# ifndef SWP_ASYNCWINDOWPOS +# define SWP_ASYNCWINDOWPOS 0 +# endif +#endif + + #ifdef GPAC_USE_OGL_ES #include "GLES/egl.h" @@ -66,6 +80,13 @@ typedef struct u32 width, height, format, pitch; } DDSurface; + +#if defined(GPAC_USE_TINYGL) +# ifndef GPAC_DISABLE_3D +# define GPAC_DISABLE_3D +# endif +#endif + typedef struct { HWND os_hwnd, fs_hwnd, cur_hwnd, parent_wnd; @@ -98,8 +119,8 @@ typedef struct /*HW surfaces for blitting+stretch*/ DDSurface rgb_pool, yuv_pool; - - /*if we own the window*/ + + /*if we run in threaded mode*/ GF_Thread *th; u32 th_state; @@ -112,6 +133,8 @@ typedef struct u32 cursor_type; /*gl*/ +#ifndef GPAC_DISABLE_3D + #ifdef GPAC_USE_OGL_ES NativeDisplayType gl_HDC; EGLDisplay egldpy; @@ -119,14 +142,18 @@ typedef struct EGLConfig eglconfig; EGLContext eglctx; #else - HDC gl_HDC; - HGLRC gl_HRC; + HDC gl_HDC, pb_HDC; + HGLRC gl_HRC, pb_HRC; + void *pbuffer; + Bool glext_init; #endif u32 output_3d_type; - HWND gl_hwnd; - Bool has_focus; + HWND gl_hwnd, bound_hwnd; Bool gl_double_buffer; +#endif + + Bool has_focus; DWORD orig_wnd_proc; u32 last_mouse_move, timer, cursor_type_backup; @@ -155,7 +182,10 @@ void dx_copy_pixels(GF_VideoSurface *dst_s, const GF_VideoSurface *src_s, const /*this is REALLY ugly, to pass the HWND to DSound when we create the window in this module*/ HWND DD_GetGlobalHWND(); -GF_Err DD_SetupOpenGL(GF_VideoOutput *dr); +#ifndef GPAC_DISABLE_3D +GF_Err DD_SetupOpenGL(GF_VideoOutput *dr, u32 offscreen_width, u32 offscreen_height); +#endif + #ifdef USE_DX_3 #define SAFE_DD_RELEASE(p) { if(p) { IDirectDraw_Release(p); (p)=NULL; } } @@ -170,4 +200,6 @@ void DeleteAudioOutput(void *); #define SAFE_DS_RELEASE(p) { if(p) { IDirectSound_Release(p); (p)=NULL; } } -#endif +LRESULT APIENTRY DD_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam); + +#endif diff --git a/modules/dx_hw/dx_hw.rc b/modules/dx_hw/dx_hw.rc index 3ef7ebf..919aa04 100644 --- a/modules/dx_hw/dx_hw.rc +++ b/modules/dx_hw/dx_hw.rc @@ -1,4 +1,4 @@ -//Microsoft Developer Studio generated resource script. +// Microsoft Visual C++ generated resource script. // #include "resource.h" @@ -7,14 +7,19 @@ // // Generated from the TEXTINCLUDE 2 resource. // +#include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// French (France) resources +// Français (France) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -22,17 +27,13 @@ // TEXTINCLUDE // -1 TEXTINCLUDE DISCARDABLE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE DISCARDABLE -BEGIN - -END -3 TEXTINCLUDE DISCARDABLE +3 TEXTINCLUDE BEGIN "\r\n" "\0" @@ -46,9 +47,18 @@ END // Cursor // -IDC_HAND_PTR CURSOR DISCARDABLE "hand.cur" -IDC_COLLIDE CURSOR DISCARDABLE "collide.cur" -#endif // French (France) resources +IDC_HAND_PTR CURSOR "hand.cur" +IDC_COLLIDE CURSOR "collide.cur" + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_OSMO_ICON ICON "..\\..\\doc\\osmo4.ico" +#endif // Français (France) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/modules/dx_hw/dx_video.c b/modules/dx_hw/dx_video.c index 25b421c..aad36cc 100644 --- a/modules/dx_hw/dx_video.c +++ b/modules/dx_hw/dx_video.c @@ -37,16 +37,121 @@ #define DDCONTEXT DDContext *dd = (DDContext *)dr->opaque; + + +#ifndef GPAC_DISABLE_3D + +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_BLUE_BITS_ARB 0x2019 + +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_TEXTURE_RGB_ARB 0x2075 + +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 + +typedef Bool (APIENTRY *CHOOSEPFFORMATARB)(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +static CHOOSEPFFORMATARB wglChoosePixelFormatARB = NULL; + +typedef void *(APIENTRY *CREATEPBUFFERARB)(HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +static CREATEPBUFFERARB wglCreatePbufferARB = NULL; + +typedef void (APIENTRY *DESTROYBUFFERARB)(void *pb); +static DESTROYBUFFERARB wglDestroyPbufferARB = NULL; + +typedef HDC (APIENTRY *GETPBUFFERDCARB)(void *pb); +static GETPBUFFERDCARB wglGetPbufferDCARB = NULL; + +typedef HDC (APIENTRY *RELEASEPBUFFERDCARB)(void *pb, HDC dc); +static RELEASEPBUFFERDCARB wglReleasePbufferDCARB = NULL; + +static void dd_init_gl_offscreen(GF_VideoOutput *driv) +{ + const char *opt; + DDContext *dd = driv->opaque; + + opt = gf_modules_get_option((GF_BaseInterface *)driv, "Video", "GLOffscreenMode"); + +#ifndef _WIN32_WCE + + wglCreatePbufferARB = (CREATEPBUFFERARB) wglGetProcAddress("wglCreatePbufferARB"); + if (opt && strcmp(opt, "PBuffer")) wglCreatePbufferARB = NULL; + + if (wglCreatePbufferARB) { + wglChoosePixelFormatARB = (CHOOSEPFFORMATARB) wglGetProcAddress("wglChoosePixelFormatARB"); + wglDestroyPbufferARB = (DESTROYBUFFERARB) wglGetProcAddress("wglDestroyPbufferARB"); + wglGetPbufferDCARB = (GETPBUFFERDCARB ) wglGetProcAddress("wglGetPbufferDCARB"); + wglReleasePbufferDCARB = (RELEASEPBUFFERDCARB ) wglGetProcAddress("wglReleasePbufferDCARB"); + + GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[DX] Using PBuffer for OpenGL Offscreen Rendering\n")); + driv->hw_caps |= GF_VIDEO_HW_OPENGL_OFFSCREEN | GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA; + + if (!opt) gf_modules_set_option((GF_BaseInterface *)driv, "Video", "GLOffscreenMode", "PBuffer"); + } else +#endif + { + u32 gl_type = 1; + HINSTANCE hInst; + +#ifndef _WIN32_WCE + hInst = GetModuleHandle("gm_dx_hw.dll"); +#else + hInst = GetModuleHandle(_T("gm_dx_hw.dll")); +#endif + opt = gf_modules_get_option((GF_BaseInterface *)driv, "Video", "GLOffscreenMode"); + if (opt) { + if (!strcmp(opt, "Window")) gl_type = 1; + else if (!strcmp(opt, "VisibleWindow")) gl_type = 2; + else gl_type = 0; + } else { + gf_modules_set_option((GF_BaseInterface *)driv, "Video", "GLOffscreenMode", "Window"); + } + + if (gl_type) { +#ifdef _WIN32_WCE + dd->gl_hwnd = CreateWindow(_T("GPAC DirectDraw Output"), _T("GPAC OpenGL Offscreen"), WS_POPUP, 0, 0, 120, 100, NULL, NULL, hInst, NULL); +#else + dd->gl_hwnd = CreateWindow("GPAC DirectDraw Output", "GPAC OpenGL Offscreen", WS_POPUP, 0, 0, 120, 100, NULL, NULL, hInst, NULL); +#endif + if (!dd->gl_hwnd) + return; + + ShowWindow(dd->gl_hwnd, (gl_type == 2) ? SW_SHOW : SW_HIDE); + GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[DX] Using %s window for OpenGL Offscreen Rendering\n", (gl_type == 2) ? "Visible" : "Hidden")); + driv->hw_caps |= GF_VIDEO_HW_OPENGL_OFFSCREEN | GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA; + } + } + +} +#endif + + static void RestoreWindow(DDContext *dd) { if (!dd->NeedRestore) return; - dd->NeedRestore = 0; + +#ifndef GPAC_DISABLE_3D if (dd->output_3d_type==1) { #ifndef _WIN32_WCE ChangeDisplaySettings(NULL,0); #endif - } else { + } else +#endif + + { #ifdef USE_DX_3 IDirectDraw_SetCooperativeLevel(dd->pDD, dd->cur_hwnd, DDSCL_NORMAL); #else @@ -62,7 +167,7 @@ static void RestoreWindow(DDContext *dd) void DestroyObjectsEx(DDContext *dd, Bool only_3d) { if (!only_3d) { - RestoreWindow(dd); +// RestoreWindow(dd); SAFE_DD_RELEASE(dd->rgb_pool.pSurface); memset(&dd->rgb_pool, 0, sizeof(DDSurface)); @@ -74,6 +179,10 @@ void DestroyObjectsEx(DDContext *dd, Bool only_3d) SAFE_DD_RELEASE(dd->pDD); dd->ddraw_init = 0; +#ifdef GPAC_DISABLE_3D + } +#else + /*do not destroy associated GL context*/ if (dd->output_3d_type==2) return; } @@ -91,16 +200,35 @@ void DestroyObjectsEx(DDContext *dd, Bool only_3d) dd->egldpy = NULL; } #elif !defined(_WIN32_WCE) + + if (dd->pb_HRC) { + wglMakeCurrent(dd->pb_HDC, NULL); + wglDeleteContext(dd->pb_HRC); + dd->pb_HRC = NULL; + } + if (dd->pb_HDC) { +// wglReleasePbufferDCARB(dd->pbuffer, dd->pb_HDC); + ReleaseDC(dd->bound_hwnd, dd->pb_HDC); + dd->pb_HDC = NULL; + } + if (dd->pbuffer) { + wglDestroyPbufferARB(dd->pbuffer); + dd->pbuffer = NULL; + } + if (dd->gl_HRC) { - wglMakeCurrent(dd->gl_HDC, NULL); + //wglMakeCurrent(NULL, NULL); wglDeleteContext(dd->gl_HRC); dd->gl_HRC = NULL; } if (dd->gl_HDC) { - ReleaseDC(dd->cur_hwnd, dd->gl_HDC); + ReleaseDC(dd->bound_hwnd, dd->gl_HDC); dd->gl_HDC = NULL; } #endif + + +#endif } void DestroyObjects(DDContext *dd) @@ -108,7 +236,9 @@ void DestroyObjects(DDContext *dd) DestroyObjectsEx(dd, 0); } -GF_Err DD_SetupOpenGL(GF_VideoOutput *dr) +#ifndef GPAC_DISABLE_3D + +GF_Err DD_SetupOpenGL(GF_VideoOutput *dr, u32 offscreen_width, u32 offscreen_height) { const char *sOpt; GF_Event evt; @@ -160,28 +290,28 @@ GF_Err DD_SetupOpenGL(GF_VideoOutput *dr) } #elif !defined(_WIN32_WCE) PIXELFORMATDESCRIPTOR pfd; - s32 pixelformat; + s32 pixelformat; + u32 i; /*already setup*/ -// if (dd->gl_HRC) return GF_OK; DestroyObjectsEx(dd, (dd->output_3d_type==1) ? 0 : 1); - if (dd->output_3d_type==2) { - dd->gl_HDC = GetDC(dd->gl_hwnd); - } else { - dd->gl_HDC = GetDC(dd->cur_hwnd); - } + dd->bound_hwnd = (dd->gl_hwnd && (dd->output_3d_type==2)) ? dd->gl_hwnd : dd->cur_hwnd; + dd->gl_HDC = GetDC(dd->bound_hwnd ); + if (!dd->gl_HDC) return GF_IO_ERR; memset(&pfd, 0, sizeof(pfd)); pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; - if (dd->gl_double_buffer) + pfd.dwFlags = PFD_SUPPORT_OPENGL; + if (dd->bound_hwnd != dd->fs_hwnd) pfd.dwFlags |= PFD_DRAW_TO_WINDOW; + + if (dd->gl_double_buffer ) { pfd.dwFlags |= PFD_DOUBLEBUFFER; - else { + } else { sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "UseGLDoubleBuffering"); - if (sOpt && !strcmp(sOpt, "yes")) pfd.dwFlags |= PFD_DOUBLEBUFFER; + if (!sOpt || !strcmp(sOpt, "yes")) pfd.dwFlags |= PFD_DOUBLEBUFFER; } pfd.dwLayerMask = PFD_MAIN_PLANE; @@ -192,12 +322,69 @@ GF_Err DD_SetupOpenGL(GF_VideoOutput *dr) /*we need alpha support for composite textures...*/ pfd.cAlphaBits = 8; if ( (pixelformat = ChoosePixelFormat(dd->gl_HDC, &pfd)) == FALSE ) return GF_IO_ERR; - if (SetPixelFormat(dd->gl_HDC, pixelformat, &pfd) == FALSE) + + if (SetPixelFormat(dd->gl_HDC, pixelformat, &pfd) == FALSE) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DX GL] Cannot select pixel format: error %d- disabling GL\n", GetLastError() )); return GF_IO_ERR; + } + dd->gl_HRC = wglCreateContext(dd->gl_HDC); if (!dd->gl_HRC) return GF_IO_ERR; - if (!wglMakeCurrent(dd->gl_HDC, dd->gl_HRC)) return GF_IO_ERR; + + if (!dd->glext_init) { + dd->glext_init=1; + wglMakeCurrent(dd->gl_HDC, dd->gl_HRC); + dd_init_gl_offscreen(dr); + return DD_SetupOpenGL(dr, offscreen_width, offscreen_height); + } + + + if ((dd->output_3d_type!=2) || dd->gl_hwnd) { + if (!wglMakeCurrent(dd->gl_HDC, dd->gl_HRC)) return GF_IO_ERR; + } else if (wglCreatePbufferARB) { + const int pbufferAttributes [50] = { + WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB, + WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB, + 0 + }; + u32 pformats[20]; + u32 nbformats=0; + int hdcAttributes[] = { + WGL_SUPPORT_OPENGL_ARB, TRUE, + WGL_DRAW_TO_PBUFFER_ARB, TRUE, + WGL_RED_BITS_ARB, 8, + WGL_GREEN_BITS_ARB, 8, + WGL_BLUE_BITS_ARB, 8, +/* + WGL_DEPTH_BITS_ARB, 16, + WGL_BIND_TO_TEXTURE_RGBA_ARB, TRUE, + WGL_COLOR_BITS_ARB,24, + WGL_DEPTH_BITS_ARB, 0, + WGL_STENCIL_BITS_ARB,0, +*/ 0 + }; + wglChoosePixelFormatARB(dd->gl_HDC, hdcAttributes, NULL, 20, pformats, &nbformats); + // Create the PBuffer + for (i=0; i<nbformats; i++) { + dd->pbuffer = wglCreatePbufferARB(dd->gl_HDC, pformats[i], offscreen_width, offscreen_height, pbufferAttributes); + if (dd->pbuffer) break; + } + if (!dd->pbuffer) return GF_IO_ERR; + + dd->pb_HDC = wglGetPbufferDCARB(dd->pbuffer); + dd->pb_HRC = wglCreateContext(dd->pb_HDC); + if (!wglMakeCurrent(dd->pb_HDC, dd->pb_HRC)) return GF_IO_ERR; + + + } #endif + + /*special care for Firefox: XUL and OpenGL do not go well together, there is a stack overflow in WM_PAINT + for our plugin window - avoid this by overriding the WindowProc once OpenGL is setup!!*/ + if ((dd->bound_hwnd==dd->os_hwnd) && dd->orig_wnd_proc) + SetWindowLong(dd->os_hwnd, GWL_WNDPROC, (DWORD) DD_WindowProc); + + if (dd->output_3d_type==1) { evt.type = GF_EVENT_VIDEO_SETUP; evt.setup.opengl_mode = 1; @@ -206,6 +393,7 @@ GF_Err DD_SetupOpenGL(GF_VideoOutput *dr) return GF_OK; } +#endif @@ -215,13 +403,22 @@ GF_Err DD_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, u32 init_ DDCONTEXT dd->os_hwnd = (HWND) os_handle; - //if (init_flags & (GF_TERM_NO_VISUAL_THREAD | GF_TERM_NO_REGULATION) ) dd->systems_memory = 2; DD_SetupWindow(dr, init_flags); /*fatal error*/ if (!dd->os_hwnd) return GF_IO_ERR; dd->cur_hwnd = dd->os_hwnd; + { + HDC hdc; + hdc = GetDC(dd->os_hwnd); + dr->dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); + dr->dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(dd->os_hwnd, hdc); + } + +#ifndef GPAC_DISABLE_3D dd->output_3d_type = 0; +#endif GetWindowRect(dd->cur_hwnd, &rc); return InitDirectDraw(dr, rc.right - rc.left, rc.bottom - rc.top); } @@ -231,7 +428,9 @@ static void DD_Shutdown(GF_VideoOutput *dr) DDCONTEXT /*force destroy of opengl*/ +#ifndef GPAC_DISABLE_3D if (dd->output_3d_type) dd->output_3d_type = 1; +#endif DestroyObjects(dd); DD_ShutdownWindow(dr); @@ -263,14 +462,17 @@ static GF_Err DD_SetFullScreen(GF_VideoOutput *dr, Bool bOn, u32 *outWidth, u32 sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "MaxResolution"); if (sOpt) sscanf(sOpt, "%dx%d", &MaxWidth, &MaxHeight); + if (dd->NeedRestore) RestoreWindow(dd); /*destroy all objects*/ DestroyObjects(dd); + if (dd->timer) KillTimer(dd->cur_hwnd, dd->timer); dd->timer = 0; ShowWindow(dd->cur_hwnd, SW_HIDE); dd->cur_hwnd = dd->fullscreen ? dd->fs_hwnd : dd->os_hwnd; ShowWindow(dd->cur_hwnd, SW_SHOW); +#ifndef GPAC_DISABLE_3D if (dd->output_3d_type==1) { DEVMODE settings; e = GF_OK; @@ -299,9 +501,11 @@ static GF_Err DD_SetFullScreen(GF_VideoOutput *dr, Bool bOn, u32 *outWidth, u32 dd->fs_store_width = dd->fs_width; dd->fs_store_height = dd->fs_height; } - if (!e) e = DD_SetupOpenGL(dr); + if (!e) e = DD_SetupOpenGL(dr, 0, 0); - } else { + } else +#endif + { e = InitDirectDraw(dr, dd->width, dd->height); } @@ -327,6 +531,11 @@ GF_Err DD_Flush(GF_VideoOutput *dr, GF_Window *dest) DDCONTEXT; if (!dd) return GF_BAD_PARAM; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX] FLushing video output\n")); + +#ifndef GPAC_DISABLE_3D + if (dd->output_3d_type==1) { #ifdef GPAC_USE_OGL_ES if (dd->surface) eglSwapBuffers(dd->egldpy, dd->surface); @@ -335,6 +544,8 @@ GF_Err DD_Flush(GF_VideoOutput *dr, GF_Window *dest) #endif return GF_OK; } +#endif + if (!dd->ddraw_init) return GF_BAD_PARAM; @@ -433,11 +644,11 @@ GF_Err GetDisplayMode(DDContext *dd) static void *NewDXVideoOutput() { DDContext *pCtx; - GF_VideoOutput *driv = (GF_VideoOutput *) malloc(sizeof(GF_VideoOutput)); + GF_VideoOutput *driv = (GF_VideoOutput *) gf_malloc(sizeof(GF_VideoOutput)); memset(driv, 0, sizeof(GF_VideoOutput)); GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "DirectX Video Output", "gpac distribution"); - pCtx = malloc(sizeof(DDContext)); + pCtx = gf_malloc(sizeof(DDContext)); memset(pCtx, 0, sizeof(DDContext)); driv->opaque = pCtx; driv->Flush = DD_Flush; @@ -448,7 +659,7 @@ static void *NewDXVideoOutput() driv->max_screen_width = GetSystemMetrics(SM_CXSCREEN); driv->max_screen_height = GetSystemMetrics(SM_CYSCREEN); - driv->hw_caps = GF_VIDEO_HW_OPENGL | GF_VIDEO_HW_OPENGL_OFFSCREEN | GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA; + driv->hw_caps = GF_VIDEO_HW_OPENGL | GF_VIDEO_HW_OPENGL_OFFSCREEN | GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA | GF_VIDEO_HW_HAS_HWND_HDC; DD_SetupDDraw(driv); @@ -459,16 +670,20 @@ static void DeleteVideoOutput(void *ifce) { GF_VideoOutput *driv = (GF_VideoOutput *) ifce; DDContext *dd = (DDContext *)driv->opaque; - free(dd); - free(driv); + gf_free(dd); + gf_free(driv); } /*interface query*/ -Bool QueryInterface(u32 InterfaceType) +GF_EXPORT +const u32 *QueryInterfaces() { - if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return 1; - if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + GF_AUDIO_OUTPUT_INTERFACE, + 0 + }; + return si; } /*interface create*/ GF_BaseInterface *LoadInterface(u32 InterfaceType) diff --git a/modules/dx_hw/dx_window.c b/modules/dx_hw/dx_window.c index 31f7024..e8113fb 100644 --- a/modules/dx_hw/dx_window.c +++ b/modules/dx_hw/dx_window.c @@ -94,6 +94,8 @@ static void w32_translate_key(u32 wParam, u32 lParam, GF_EventKey *evt) case VK_INSERT: evt->key_code = GF_KEY_INSERT; break; case VK_DELETE: evt->key_code = GF_KEY_DEL; break; case VK_HELP: evt->key_code = GF_KEY_HELP; break; + case VK_OEM_PLUS: evt->key_code = GF_KEY_PLUS; break; + case VK_OEM_MINUS: evt->key_code = GF_KEY_PLUS; break; #ifndef _WIN32_WCE case VK_NONCONVERT: evt->key_code = GF_KEY_NONCONVERT; break; @@ -317,12 +319,12 @@ void release_mouse(DDContext *ctx, HWND hWnd, GF_VideoOutput *vout) LRESULT APIENTRY DD_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam) { - Bool ret = 0; + Bool ret = 1; GF_Event evt; DDContext *ctx; GF_VideoOutput *vout = (GF_VideoOutput *) GetWindowLong(hWnd, GWL_USERDATA); - if (!vout) return DefWindowProc (hWnd, msg, wParam, lParam); + if (!vout) return DefWindowProc(hWnd, msg, wParam, lParam); ctx = (DDContext *)vout->opaque; switch (msg) { @@ -331,18 +333,18 @@ LRESULT APIENTRY DD_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam) evt.type = GF_EVENT_SIZE; evt.size.width = LOWORD(lParam); evt.size.height = HIWORD(lParam); - ret = vout->on_event(vout->evt_cbk_hdl, &evt); + vout->on_event(vout->evt_cbk_hdl, &evt); break; case WM_MOVE: evt.type = GF_EVENT_MOVE; evt.move.x = LOWORD(lParam); evt.move.y = HIWORD(lParam); - ret = vout->on_event(vout->evt_cbk_hdl, &evt); + vout->on_event(vout->evt_cbk_hdl, &evt); break; case WM_CLOSE: if (hWnd==ctx->os_hwnd) { evt.type = GF_EVENT_QUIT; - ret = vout->on_event(vout->evt_cbk_hdl, &evt); + vout->on_event(vout->evt_cbk_hdl, &evt); } break; case WM_DESTROY: @@ -355,29 +357,50 @@ LRESULT APIENTRY DD_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam) } break; case WM_ACTIVATE: - if ((ctx->output_3d_type!=2) && ctx->fullscreen && (LOWORD(wParam)==WA_INACTIVE) && (hWnd==ctx->fs_hwnd)) { + if (ctx->fullscreen && (LOWORD(wParam)==WA_INACTIVE) + && (hWnd==ctx->fs_hwnd) +#ifndef GPAC_DISABLE_3D + && (ctx->output_3d_type!=2) +#endif + ) { evt.type = GF_EVENT_SHOWHIDE; - ret = vout->on_event(vout->evt_cbk_hdl, &evt); + vout->on_event(vout->evt_cbk_hdl, &evt); + } + /*fallthrough*/ + case WM_ACTIVATEAPP: + if (hWnd==ctx->os_hwnd) { + ctx->has_focus = 1; + SetFocus(hWnd); } break; - case WM_SETCURSOR: - if (ctx->cur_hwnd==hWnd) DD_SetCursor(vout, ctx->cursor_type); - return 1; + case WM_KILLFOCUS: + if (hWnd==ctx->os_hwnd) ctx->has_focus = 0; + break; + case WM_SETFOCUS: + if (hWnd==ctx->os_hwnd) ctx->has_focus = 1; + break; + case WM_IME_SETCONTEXT: + if ((hWnd==ctx->os_hwnd) && (wParam!=0) && !ctx->fullscreen) SetFocus(hWnd); + break; + case WM_ERASEBKGND: - //InvalidateRect(ctx->cur_hwnd, NULL, TRUE); - //break; + /*the erasebkgnd message causes flickering when resizing the window, we discard it*/ + break; case WM_PAINT: if (ctx->cur_hwnd==hWnd) { evt.type = GF_EVENT_REFRESH; vout->on_event(vout->evt_cbk_hdl, &evt); } - break; - case WM_KILLFOCUS: - if (hWnd==ctx->os_hwnd) ctx->has_focus = 0; + /*this avoids 100% cpu usage in Firefox*/ + return DefWindowProc (hWnd, msg, wParam, lParam); + + case WM_SETCURSOR: + if (ctx->cur_hwnd==hWnd) DD_SetCursor(vout, ctx->cursor_type); break; case WM_MOUSEMOVE: if (ctx->cur_hwnd!=hWnd) break; + if (ctx->last_mouse_pos != lParam) { ctx->last_mouse_pos = lParam; DD_SetCursor(vout, (ctx->cursor_type==GF_CURSOR_HIDE) ? ctx->cursor_type_backup : ctx->cursor_type); @@ -485,16 +508,19 @@ LRESULT APIENTRY DD_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam) evt.character.unicode_char = wParam; ret = vout->on_event(vout->evt_cbk_hdl, &evt); break; - } - - if (ret) return 1; - /* - if (ctx->parent_wnd && (hWnd==ctx->os_hwnd) ) { - return SendMessage(ctx->parent_wnd, msg, wParam, lParam); - } + case WM_CANCELMODE: + case WM_CAPTURECHANGED: + case WM_NCHITTEST: + return 0; */ - return DefWindowProc (hWnd, msg, wParam, lParam); + default: + return DefWindowProc (hWnd, msg, wParam, lParam); + } + + if (!ret &&(ctx->os_hwnd==hWnd) && ctx->orig_wnd_proc) + return CallWindowProc((WNDPROC) ctx->orig_wnd_proc, hWnd, msg, wParam, lParam); + return 0; } #ifndef WS_EX_LAYERED @@ -575,7 +601,7 @@ Bool DD_InitWindows(GF_VideoOutput *vout, DDContext *ctx) memset(&wc, 0, sizeof(WNDCLASS)); #ifndef _WIN32_WCE wc.style = CS_BYTEALIGNWINDOW; - wc.hIcon = LoadIcon (NULL, IDI_APPLICATION); + wc.hIcon = LoadIcon (hInst, MAKEINTRESOURCE(IDI_OSMO_ICON) ); wc.lpszClassName = "GPAC DirectDraw Output"; #else wc.lpszClassName = _T("GPAC DirectDraw Output"); @@ -590,12 +616,16 @@ Bool DD_InitWindows(GF_VideoOutput *vout, DDContext *ctx) ctx->switch_res = 0; if (!ctx->os_hwnd) { + u32 styles; if (flags & GF_TERM_WINDOWLESS) ctx->windowless = 1; + #ifdef _WIN32_WCE ctx->os_hwnd = CreateWindow(_T("GPAC DirectDraw Output"), _T("GPAC DirectDraw Output"), WS_POPUP, 0, 0, 120, 100, NULL, NULL, hInst, NULL); #else - ctx->os_hwnd = CreateWindow("GPAC DirectDraw Output", "GPAC DirectDraw Output", ctx->windowless ? WS_POPUP : WS_OVERLAPPEDWINDOW, 0, 0, 120, 100, NULL, NULL, hInst, NULL); + styles = WS_CLIPCHILDREN | WS_CLIPSIBLINGS; + styles |= ctx->windowless ? WS_POPUP : WS_OVERLAPPEDWINDOW; + ctx->os_hwnd = CreateWindow("GPAC DirectDraw Output", "GPAC DirectDraw Output", styles, 0, 0, 120, 100, NULL, NULL, hInst, NULL); #endif if (ctx->os_hwnd == NULL) { return 0; @@ -633,16 +663,7 @@ Bool DD_InitWindows(GF_VideoOutput *vout, DDContext *ctx) } ShowWindow(ctx->fs_hwnd, SW_HIDE); -#ifdef _WIN32_WCE - ctx->gl_hwnd = CreateWindow(_T("GPAC DirectDraw Output"), _T("GPAC OpenGL Offscreen"), WS_POPUP, 0, 0, 120, 100, NULL, NULL, hInst, NULL); -#else - ctx->gl_hwnd = CreateWindow("GPAC DirectDraw Output", "GPAC OpenGL Offscreen", WS_POPUP, 0, 0, 120, 100, NULL, NULL, hInst, NULL); -#endif - if (!ctx->gl_hwnd) { - return 0; - } - ShowWindow(ctx->gl_hwnd, SW_HIDE); - + /*if visible set focus*/ if (!ctx->switch_res) SetFocus(ctx->os_hwnd); @@ -652,7 +673,6 @@ Bool DD_InitWindows(GF_VideoOutput *vout, DDContext *ctx) /*load cursors*/ ctx->curs_normal = LoadCursor(NULL, IDC_ARROW); - assert(ctx->curs_normal); ctx->curs_hand = LoadCursor(hInst, MAKEINTRESOURCE(IDC_HAND_PTR)); ctx->curs_collide = LoadCursor(hInst, MAKEINTRESOURCE(IDC_COLLIDE)); ctx->cursor_type = GF_CURSOR_NORMAL; @@ -695,11 +715,14 @@ void DD_SetupWindow(GF_VideoOutput *dr, u32 flags) } ctx->switch_res = flags; - /*create event thread*/ - ctx->th = gf_th_new("DirectX Video"); - gf_th_run(ctx->th, DD_WindowThread, dr); - while (!ctx->th_state) gf_sleep(2); - + if (flags & GF_TERM_NO_THREAD) { + DD_InitWindows(dr, ctx); + } else { + /*create event thread*/ + ctx->th = gf_th_new("DirectX Video"); + gf_th_run(ctx->th, DD_WindowThread, dr); + while (!ctx->th_state) gf_sleep(2); + } if (!the_video_output) the_video_output = dr; } @@ -719,14 +742,25 @@ void DD_ShutdownWindow(GF_VideoOutput *dr) SetWindowLong(ctx->os_hwnd, GWL_WNDPROC, ctx->orig_wnd_proc); ctx->orig_wnd_proc = 0L; } + dd_closewindow(ctx->fs_hwnd); - dd_closewindow(ctx->gl_hwnd); +#ifndef GPAC_DISABLE_3D + if (ctx->gl_hwnd) dd_closewindow(ctx->gl_hwnd); +#endif + + if (ctx->th) { + while (ctx->th_state!=2) + gf_sleep(10); - while (ctx->th_state!=2) - gf_sleep(10); + gf_th_del(ctx->th); + ctx->th = NULL; + } - gf_th_del(ctx->th); - ctx->th = NULL; + /*special care for Firefox: the windows created by our NP plugin may still be called + after the shutdown of the plugin !!*/ + SetWindowLong(ctx->os_hwnd, GWL_USERDATA, (LONG) NULL); + SetWindowLong(ctx->fs_hwnd, GWL_USERDATA, (LONG) NULL); + SetWindowLong(ctx->fs_hwnd, GWL_WNDPROC, (DWORD) DefWindowProc); #ifdef _WIN32_WCE UnregisterClass(_T("GPAC DirectDraw Output"), GetModuleHandle(_T("gm_dx_hw.dll")) ); @@ -735,7 +769,9 @@ void DD_ShutdownWindow(GF_VideoOutput *dr) #endif ctx->os_hwnd = NULL; ctx->fs_hwnd = NULL; +#ifndef GPAC_DISABLE_3D ctx->gl_hwnd = NULL; +#endif the_video_output = NULL; } @@ -783,6 +819,13 @@ GF_Err DD_ProcessEvent(GF_VideoOutput*dr, GF_Event *evt) DDContext *ctx = (DDContext *)dr->opaque; if (!evt) { + if (!ctx->th) { + MSG msg; + while (PeekMessage (&(msg), NULL, 0, 0, PM_REMOVE)) { + TranslateMessage (&(msg)); + DispatchMessage (&(msg)); + } + } return GF_OK; } @@ -840,22 +883,29 @@ GF_Err DD_ProcessEvent(GF_VideoOutput*dr, GF_Event *evt) case GF_EVENT_VIDEO_SETUP: switch (evt->setup.opengl_mode) { case 0: +#ifndef GPAC_DISABLE_3D ctx->output_3d_type = 0; +#endif return DD_SetBackBufferSize(dr, evt->setup.width, evt->setup.height, evt->setup.system_memory); +#ifndef GPAC_DISABLE_3D case 1: ctx->output_3d_type = 1; ctx->width = evt->setup.width; ctx->height = evt->setup.height; ctx->gl_double_buffer = evt->setup.back_buffer; - return DD_SetupOpenGL(dr); + return DD_SetupOpenGL(dr, 0, 0); case 2: ctx->output_3d_type = 2; GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX Out] Attempting to resize Offscreen OpenGL window to %d x %d\n", evt->size.width, evt->size.height)); - SetWindowPos(ctx->gl_hwnd, NULL, 0, 0, evt->size.width, evt->size.height, SWP_NOZORDER | SWP_NOMOVE | SWP_ASYNCWINDOWPOS); + if (ctx->gl_hwnd) + SetWindowPos(ctx->gl_hwnd, NULL, 0, 0, evt->size.width, evt->size.height, SWP_NOZORDER | SWP_NOMOVE | SWP_ASYNCWINDOWPOS); GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[DX Out] Resizing Offscreen OpenGL window to %d x %d\n", evt->size.width, evt->size.height)); SetForegroundWindow(ctx->cur_hwnd); ctx->gl_double_buffer = evt->setup.back_buffer; - return DD_SetupOpenGL(dr); + return DD_SetupOpenGL(dr, evt->size.width, evt->size.height); +#else + return GF_NOT_SUPPORTED; +#endif } } return GF_OK; diff --git a/modules/dx_hw/resource.h b/modules/dx_hw/resource.h index 8a658fd..64f8f8c 100644 --- a/modules/dx_hw/resource.h +++ b/modules/dx_hw/resource.h @@ -1,9 +1,11 @@ //{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. +// Microsoft Visual C++ generated include file. // Used by dx_hw.rc // #define IDC_HAND_PTR 103 #define IDC_COLLIDE 104 +#define IDI_ICON1 105 +#define IDI_OSMO_ICON 105 #define IDC_HAND_CLOSE 148 #define IDC_HAND_OPEN 149 #define IDC_ZOOM_IN 150 @@ -13,7 +15,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_RESOURCE_VALUE 106 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/modules/epoc_hw/epoc_aout.cpp b/modules/epoc_hw/epoc_aout.cpp index 52c5435..4aef8dc 100644 --- a/modules/epoc_hw/epoc_aout.cpp +++ b/modules/epoc_hw/epoc_aout.cpp @@ -164,7 +164,7 @@ void EPOCAudio::Close(Bool and_wait) m_stream = NULL; } for (i=0; i<num_buffers; i++) { - if (buffers[i]) free(buffers[i]); + if (buffers[i]) gf_free(buffers[i]); buffers[i] = NULL; } num_buffers = 0; @@ -192,10 +192,10 @@ void EPOCAudio::MaoscBufferCopied(TInt aError, const TDesC8& a_Buffer) void EPOCAudio::MaoscPlayComplete(TInt aError) { if (aError) { - GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOCAudio] Playback stoped due to error %d\n", aError)); + GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[EPOCAudio] Playback stopped due to error %d\n", aError)); state = EPOC_AUDIO_ERROR; } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOCAudio] Playback stoped due to user request\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOCAudio] Playback stopped due to user request\n")); state = EPOC_AUDIO_OPEN; } } @@ -249,7 +249,7 @@ static GF_Err EAUD_ConfigureOutput(GF_AudioOutput *dr, u32 *SampleRate, u32 *NbC ctx->total_duration = ctx->buffer_len * ctx->num_buffers; for (i=0; i<ctx->num_buffers; i++) { - ctx->buffers[i] = (char *)malloc(sizeof(char)*ctx->buffer_size); + ctx->buffers[i] = (char *)gf_malloc(sizeof(char)*ctx->buffer_size); } GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[EPOCAudio] Output audio stream configured - %d buffers of %d ms each\n", ctx->num_buffers, ctx->buffer_len)); @@ -326,7 +326,7 @@ extern "C" { void *EPOC_aout_new() { GF_AudioOutput *driv; - driv = (GF_AudioOutput *) malloc(sizeof(GF_AudioOutput)); + driv = (GF_AudioOutput *) gf_malloc(sizeof(GF_AudioOutput)); memset(driv, 0, sizeof(GF_AudioOutput)); GF_REGISTER_MODULE_INTERFACE(driv, GF_AUDIO_OUTPUT_INTERFACE, "EPOC Audio Output", "gpac distribution") @@ -352,7 +352,7 @@ void EPOC_aout_del(void *ifce) GF_AudioOutput *dr = (GF_AudioOutput *) ifce; EPOCAudio *ctx = (EPOCAudio*)dr->opaque; delete ctx; - free(dr); + gf_free(dr); } #ifdef __cplusplus diff --git a/modules/epoc_hw/epoc_codec.cpp b/modules/epoc_hw/epoc_codec.cpp index 57dd7cb..edce981 100644 --- a/modules/epoc_hw/epoc_codec.cpp +++ b/modules/epoc_hw/epoc_codec.cpp @@ -117,11 +117,11 @@ static GF_Err EDEC_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) /*audio decs*/ switch (esd->decoderConfig->objectTypeIndication) { /*MPEG2 aac*/ - case 0x66: - case 0x67: - case 0x68: + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: /*MPEG4 aac*/ - case 0x40: + case GPAC_OTI_AUDIO_AAC_MPEG4: if (!esd->decoderConfig->decoderSpecificInfo || !esd->decoderConfig->decoderSpecificInfo->data) return GF_NON_COMPLIANT_BITSTREAM; if (gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg) != GF_OK) return GF_NON_COMPLIANT_BITSTREAM; @@ -341,11 +341,11 @@ static Bool EDEC_CanHandleStream(GF_BaseDecoder *ifcg, u32 StreamType, u32 Objec if (StreamType == GF_STREAM_AUDIO) { switch (ObjectType) { /*MPEG2 aac*/ - case 0x66: - case 0x67: - case 0x68: + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: /*MPEG4 aac*/ - case 0x40: + case GPAC_OTI_AUDIO_AAC_MPEG4: if (!decSpecInfoSize || !decSpecInfo) return 0; if (gf_m4a_get_config(decSpecInfo, decSpecInfoSize, &a_cfg) != GF_OK) return 0; switch (a_cfg.base_object_type) { @@ -358,9 +358,9 @@ static Bool EDEC_CanHandleStream(GF_BaseDecoder *ifcg, u32 StreamType, u32 Objec } break; /*MPEG1 audio*/ - case 0x69: + case GPAC_OTI_AUDIO_MPEG2_PART3: /*MPEG2 audio*/ - case 0x6B: + case GPAC_OTI_AUDIO_MPEG1: /* NOT SUPPORTED YET if (ctx->caps & GF_EPOC_HAS_MP3) return 1; */ break; /*non-mpeg4 codecs*/ @@ -415,8 +415,8 @@ void EPOC_codec_del(GF_BaseDecoder *ifcg) { EPOCCodec *ctx = (EPOCCodec *)ifcg->privateStack; - free(ctx); - free(ifcg); + gf_free(ctx); + gf_free(ifcg); } diff --git a/modules/epoc_hw/epoc_vout.cpp b/modules/epoc_hw/epoc_vout.cpp index 79884d5..eac6f09 100644 --- a/modules/epoc_hw/epoc_vout.cpp +++ b/modules/epoc_hw/epoc_vout.cpp @@ -191,7 +191,7 @@ static GF_Err EVID_InitSurface(GF_VideoOutput *dr) return GF_IO_ERR; } configSize = numOfConfigs; - configList = (EGLConfig*) malloc(sizeof(EGLConfig)*configSize); + configList = (EGLConfig*) gf_malloc(sizeof(EGLConfig)*configSize); // Define properties for the wanted EGLSurface EGLint atts[7]; @@ -207,7 +207,7 @@ static GF_Err EVID_InitSurface(GF_VideoOutput *dr) return GF_IO_ERR; } EGLConfig gl_cfg = configList[0]; - free(configList); + gf_free(configList); ctx->egl_surface = eglCreatePixmapSurface(ctx->egl_display, gl_cfg, ctx->surface, NULL); if (ctx->egl_surface == NULL) { @@ -279,7 +279,7 @@ static GF_Err EVID_SetupOGL_ES_Offscreen(GF_VideoOutput *dr, u32 width, u32 heig return GF_IO_ERR; } configSize = numOfConfigs; - configList = (EGLConfig*) malloc(sizeof(EGLConfig)*configSize); + configList = (EGLConfig*) gf_malloc(sizeof(EGLConfig)*configSize); // Define properties for the wanted EGLSurface EGLint atts[13]; @@ -297,7 +297,7 @@ static GF_Err EVID_SetupOGL_ES_Offscreen(GF_VideoOutput *dr, u32 width, u32 heig return GF_IO_ERR; } EGLConfig gl_cfg = configList[0]; - free(configList); + gf_free(configList); atts[0] = EGL_WIDTH; atts[1] = width; atts[2] = EGL_HEIGHT; atts[3] = height; @@ -468,8 +468,8 @@ static void EPOC_vout_del(void *ifce) { GF_VideoOutput *driv = (GF_VideoOutput *) ifce; EPOCVideo *priv = (EPOCVideo *)driv->opaque; - free(priv); - free(driv); + gf_free(priv); + gf_free(driv); } #ifdef __cplusplus @@ -485,12 +485,15 @@ void *EPOC_codec_new(); /*interface query*/ GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return 1; - if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return 1; - if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + GF_AUDIO_OUTPUT_INTERFACE, + GF_MEDIA_DECODER_INTERFACE, + 0 + }; + return si; } /*interface create*/ GF_EXPORT diff --git a/modules/ffmpeg_in/Makefile b/modules/ffmpeg_in/Makefile index fb67f0f..858dd59 100644 --- a/modules/ffmpeg_in/Makefile +++ b/modules/ffmpeg_in/Makefile @@ -15,7 +15,19 @@ LDFLAGS+=-pg endif LOCAL_LIB= -LINKLIBS=-lgpac -lavcodec -lavformat -lz +LINKLIBS=-lgpac -lavcodec -lavformat -lavutil -lz + +#darwin needs bz2 +ifeq ($(CONFIG_DARWIN),yes) +LINKLIBS+=-lbz2 +endif + +#old ffmpeg lib +ifeq ($(CONFIG_FFMPEG_OLD), yes) +CFLAGS+=-DFFMPEG_OLD_HEADERS +else +LINKLIBS+=-lswscale +endif #common obj OBJS=ffmpeg_decode.o ffmpeg_demux.o ffmpeg_load.o @@ -35,7 +47,7 @@ SRCS := $(OBJS:.o=.c) LIB=gm_ffmpeg_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols ffmpeg_in.def +#LDFLAGS+=-export-symbols ffmpeg_in.def endif #need to add cross-libraries if not local @@ -43,17 +55,12 @@ ifeq ($(CROSS_COMPILING),yes) EXTRALIBS+=-L$(prefix)/lib endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) -L../../bin/gcc $(LOCAL_LIB) $(LINKLIBS) $(EXTRALIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc $(LOCAL_LIB) $(LINKLIBS) $(EXTRALIBS) %.o: %.c diff --git a/modules/ffmpeg_in/ffmpeg_decode.c b/modules/ffmpeg_in/ffmpeg_decode.c index cdd2af4..fdeda0c 100644 --- a/modules/ffmpeg_in/ffmpeg_decode.c +++ b/modules/ffmpeg_in/ffmpeg_decode.c @@ -25,6 +25,17 @@ #include "ffmpeg_in.h" #include <gpac/avparse.h> +#ifndef FFMPEG_OLD_HEADERS +#if (LIBAVCODEC_VERSION_MAJOR <= 52) && (LIBAVCODEC_VERSION_MINOR <= 20) +#define USE_AVCODEC2 0 +#else +#define USE_AVCODEC2 1 +#endif +#else +#define USE_AVCODEC2 0 +#endif + + static AVCodec *ffmpeg_get_codec(u32 codec_4cc) { char name[5]; @@ -50,24 +61,24 @@ static AVCodec *ffmpeg_get_codec(u32 codec_4cc) } -static void FFDEC_LoadDSI(FFDec *ffd, GF_BitStream *bs, Bool from_ff_demux) +static void FFDEC_LoadDSI(FFDec *ffd, GF_BitStream *bs, AVCodec *codec, AVCodecContext *ctx, Bool from_ff_demux) { u32 dsi_size; - if (!ffd->codec) return; + if (!codec) return; dsi_size = (u32) gf_bs_available(bs); if (!dsi_size) return; /*demuxer is ffmpeg, extra data can be copied directly*/ if (from_ff_demux) { - free(ffd->ctx->extradata); - ffd->ctx->extradata_size = dsi_size; - ffd->ctx->extradata = (uint8_t*) malloc(sizeof(char)*ffd->ctx->extradata_size); - gf_bs_read_data(bs, ffd->ctx->extradata, ffd->ctx->extradata_size); + gf_free(ctx->extradata); + ctx->extradata_size = dsi_size; + ctx->extradata = (uint8_t*) gf_malloc(sizeof(char)*ctx->extradata_size); + gf_bs_read_data(bs, ctx->extradata, ctx->extradata_size); return; } - switch (ffd->codec->id) { + switch (codec->id) { case CODEC_ID_SVQ3: { u32 at_type, size; @@ -75,19 +86,19 @@ static void FFDEC_LoadDSI(FFDec *ffd, GF_BitStream *bs, Bool from_ff_demux) /*there should be an 'SMI' entry*/ at_type = gf_bs_read_u32(bs); if (at_type == GF_4CC('S', 'M', 'I', ' ')) { - free(ffd->ctx->extradata); - ffd->ctx->extradata_size = 0x5a + size; - ffd->ctx->extradata = (uint8_t*) malloc(sizeof(char)*ffd->ctx->extradata_size); - strcpy(ffd->ctx->extradata, "SVQ3"); - gf_bs_read_data(bs, (unsigned char *)ffd->ctx->extradata + 0x5a, size); + gf_free(ctx->extradata); + ctx->extradata_size = 0x5a + size; + ctx->extradata = (uint8_t*) gf_malloc(sizeof(char)*ctx->extradata_size); + strcpy(ctx->extradata, "SVQ3"); + gf_bs_read_data(bs, (unsigned char *)ctx->extradata + 0x5a, size); } } break; default: - free(ffd->ctx->extradata); - ffd->ctx->extradata_size = dsi_size; - ffd->ctx->extradata = (uint8_t*) malloc(sizeof(char)*ffd->ctx->extradata_size); - gf_bs_read_data(bs, ffd->ctx->extradata, ffd->ctx->extradata_size); + gf_free(ctx->extradata); + ctx->extradata_size = dsi_size; + ctx->extradata = (uint8_t*) gf_malloc(sizeof(char)*ctx->extradata_size); + gf_bs_read_data(bs, ctx->extradata, ctx->extradata_size); break; } } @@ -97,40 +108,68 @@ static GF_Err FFDEC_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) u32 codec_id; int gotpic; GF_BitStream *bs; + AVCodecContext **ctx; + AVCodec **codec; + AVFrame **frame; + +#ifndef GPAC_DISABLE_AV_PARSERS GF_M4VDecSpecInfo dsi; GF_Err e; +#endif FFDec *ffd = (FFDec *)plug->privateStack; - if (ffd->ES_ID || esd->dependsOnESID || esd->decoderConfig->upstream) return GF_NOT_SUPPORTED; + if (esd->decoderConfig->upstream) return GF_NOT_SUPPORTED; if (!ffd->oti) return GF_NOT_SUPPORTED; - ffd->ES_ID = esd->ESID; - ffd->ctx = avcodec_alloc_context(); - + + + /*locate any auxiliary video data descriptor on this stream*/ + if (esd->dependsOnESID) { + u32 i = 0; + GF_Descriptor *d = NULL; + if (esd->dependsOnESID != ffd->base_ES_ID) return GF_NOT_SUPPORTED; + while ((d = gf_list_enum(esd->extensionDescriptors, &i))) { + if (d->tag == GF_ODF_AUX_VIDEO_DATA) break; + } + if (!d) return GF_NOT_SUPPORTED; + + ffd->depth_ES_ID = esd->ESID; + ctx = &ffd->depth_ctx; + codec = &ffd->depth_codec; + frame = &ffd->depth_frame; + } else { + if (ffd->base_ES_ID) return GF_NOT_SUPPORTED; + ffd->base_ES_ID = esd->ESID; + ctx = &ffd->base_ctx; + codec = &ffd->base_codec; + frame = &ffd->base_frame; + } + *ctx = avcodec_alloc_context(); + /*private FFMPEG DSI*/ if (ffd->oti == GPAC_OTI_MEDIA_FFMPEG) { bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); codec_id = gf_bs_read_u32(bs); if (ffd->st==GF_STREAM_AUDIO) { - ffd->ctx->codec_type = CODEC_TYPE_AUDIO; - ffd->ctx->sample_rate = gf_bs_read_u32(bs); - ffd->ctx->channels = gf_bs_read_u16(bs); - ffd->ctx->frame_size = gf_bs_read_u16(bs); + (*ctx)->codec_type = CODEC_TYPE_AUDIO; + (*ctx)->sample_rate = gf_bs_read_u32(bs); + (*ctx)->channels = gf_bs_read_u16(bs); + (*ctx)->frame_size = gf_bs_read_u16(bs); /*bits_per_sample */gf_bs_read_u8(bs); /*num_frames_per_au*/ gf_bs_read_u8(bs); /*ffmpeg specific*/ - ffd->ctx->block_align = gf_bs_read_u16(bs); + (*ctx)->block_align = gf_bs_read_u16(bs); } else if (ffd->st==GF_STREAM_VISUAL) { - ffd->ctx->codec_type = CODEC_TYPE_VIDEO; - ffd->ctx->width = gf_bs_read_u16(bs); - ffd->ctx->height = gf_bs_read_u16(bs); + (*ctx)->codec_type = CODEC_TYPE_VIDEO; + (*ctx)->width = gf_bs_read_u16(bs); + (*ctx)->height = gf_bs_read_u16(bs); } - ffd->ctx->bit_rate = gf_bs_read_u32(bs); + (*ctx)->bit_rate = gf_bs_read_u32(bs); - ffd->ctx->codec_tag = gf_bs_read_u32(bs); + (*ctx)->codec_tag = gf_bs_read_u32(bs); - ffd->codec = avcodec_find_decoder(codec_id); - FFDEC_LoadDSI(ffd, bs, 1); + *codec = avcodec_find_decoder(codec_id); + FFDEC_LoadDSI(ffd, bs, *codec, *ctx, 1); gf_bs_del(bs); } /*private QT DSI*/ @@ -138,63 +177,64 @@ static GF_Err FFDEC_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); codec_id = gf_bs_read_u32(bs); if (ffd->st==GF_STREAM_AUDIO) { - ffd->ctx->codec_type = CODEC_TYPE_AUDIO; - ffd->ctx->sample_rate = gf_bs_read_u32(bs); - ffd->ctx->channels = gf_bs_read_u16(bs); - ffd->ctx->frame_size = gf_bs_read_u16(bs); + (*ctx)->codec_type = CODEC_TYPE_AUDIO; + (*ctx)->sample_rate = gf_bs_read_u32(bs); + (*ctx)->channels = gf_bs_read_u16(bs); + (*ctx)->frame_size = gf_bs_read_u16(bs); /*bits_per_sample */ gf_bs_read_u8(bs); /*num_frames_per_au*/ gf_bs_read_u8(bs); /*just in case...*/ if (codec_id == GF_4CC('a', 'm', 'r', ' ')) { - ffd->ctx->sample_rate = 8000; - ffd->ctx->channels = 1; - ffd->ctx->frame_size = 160; + (*ctx)->sample_rate = 8000; + (*ctx)->channels = 1; + (*ctx)->frame_size = 160; } } else if (ffd->st==GF_STREAM_VISUAL) { - ffd->ctx->codec_type = CODEC_TYPE_VIDEO; - ffd->ctx->width = gf_bs_read_u16(bs); - ffd->ctx->height = gf_bs_read_u16(bs); + (*ctx)->codec_type = CODEC_TYPE_VIDEO; + (*ctx)->width = gf_bs_read_u16(bs); + (*ctx)->height = gf_bs_read_u16(bs); } - ffd->codec = ffmpeg_get_codec(codec_id); - FFDEC_LoadDSI(ffd, bs, 0); + (*codec) = ffmpeg_get_codec(codec_id); + FFDEC_LoadDSI(ffd, bs, *codec, *ctx, 0); gf_bs_del(bs); } /*use std MPEG-4 st/oti*/ else { u32 codec_id = 0; if (ffd->st==GF_STREAM_VISUAL) { - ffd->ctx->codec_type = CODEC_TYPE_VIDEO; + (*ctx)->codec_type = CODEC_TYPE_VIDEO; switch (ffd->oti) { - case 0x20: + case GPAC_OTI_VIDEO_MPEG4_PART2: codec_id = CODEC_ID_MPEG4; break; - case 0x21: + case GPAC_OTI_VIDEO_AVC: codec_id = CODEC_ID_H264; /*ffmpeg H264/AVC needs that*/ - //ffd->ctx->codec_tag = 0x31637661; + //(*ctx)->codec_tag = 0x31637661; break; - case 0x6A: - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: + case GPAC_OTI_VIDEO_MPEG1: + case GPAC_OTI_VIDEO_MPEG2_SIMPLE: + case GPAC_OTI_VIDEO_MPEG2_MAIN: + case GPAC_OTI_VIDEO_MPEG2_SNR: + case GPAC_OTI_VIDEO_MPEG2_SPATIAL: + case GPAC_OTI_VIDEO_MPEG2_HIGH: + case GPAC_OTI_VIDEO_MPEG2_422: codec_id = CODEC_ID_MPEG2VIDEO; break; - case 0x6C: + case GPAC_OTI_IMAGE_JPEG: codec_id = CODEC_ID_MJPEG; + ffd->is_image=1; break; case 0xFF: codec_id = CODEC_ID_SVQ3; break; } } else if (ffd->st==GF_STREAM_AUDIO) { - ffd->ctx->codec_type = CODEC_TYPE_AUDIO; + (*ctx)->codec_type = CODEC_TYPE_AUDIO; switch (ffd->oti) { - case 0x69: - case 0x6B: - ffd->ctx->frame_size = 1152; + case GPAC_OTI_AUDIO_MPEG2_PART3: + case GPAC_OTI_AUDIO_MPEG1: + (*ctx)->frame_size = 1152; codec_id = CODEC_ID_MP2; break; } @@ -202,54 +242,58 @@ static GF_Err FFDEC_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) else if ((ffd->st==GF_STREAM_ND_SUBPIC) && (ffd->oti==0xe0)) { codec_id = CODEC_ID_DVD_SUBTITLE; } - ffd->codec = avcodec_find_decoder(codec_id); + *codec = avcodec_find_decoder(codec_id); } /*should never happen*/ - if (!ffd->codec) return GF_OUT_OF_MEM; + if (! (*codec)) return GF_OUT_OF_MEM; /*setup MPEG-4 video streams*/ if ((ffd->st==GF_STREAM_VISUAL)) { /*for all MPEG-4 variants get size*/ - if ((ffd->oti==0x20) || (ffd->oti == 0x21)) { + if ((ffd->oti==GPAC_OTI_VIDEO_MPEG4_PART2) || (ffd->oti == GPAC_OTI_VIDEO_AVC)) { /*if not set this may be a remap of non-mpeg4 transport (eg, transport on MPEG-TS) where the DSI is carried in-band*/ if (esd->decoderConfig->decoderSpecificInfo->data) { /*for regular MPEG-4, try to decode and if this fails try H263 decoder at first frame*/ - if (ffd->oti==0x20) { + if (ffd->oti==GPAC_OTI_VIDEO_MPEG4_PART2) { +#ifndef GPAC_DISABLE_AV_PARSERS e = gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); if (e) return e; - ffd->ctx->width = dsi.width; - ffd->ctx->height = dsi.height; + if (dsi.width%2) dsi.width++; + if (dsi.height%2) dsi.height++; + (*ctx)->width = dsi.width; + (*ctx)->height = dsi.height; if (!dsi.width && !dsi.height) ffd->check_short_header = 1; ffd->previous_par = (dsi.par_num<<16) | dsi.par_den; ffd->no_par_update = 1; - } else if (ffd->oti==0x21) { +#endif + } else if (ffd->oti==GPAC_OTI_VIDEO_AVC) { ffd->check_h264_isma = 1; } /*setup dsi for FFMPEG context BEFORE attaching decoder (otherwise not proper init)*/ - ffd->ctx->extradata = malloc(sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength); - memcpy(ffd->ctx->extradata, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); - ffd->ctx->extradata_size = esd->decoderConfig->decoderSpecificInfo->dataLength; + (*ctx)->extradata = gf_malloc(sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength); + memcpy((*ctx)->extradata, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + (*ctx)->extradata_size = esd->decoderConfig->decoderSpecificInfo->dataLength; } } - ffd->frame = avcodec_alloc_frame(); + *frame = avcodec_alloc_frame(); } - if (avcodec_open(ffd->ctx, ffd->codec)<0) return GF_NON_COMPLIANT_BITSTREAM; + if (avcodec_open((*ctx), (*codec) )<0) return GF_NON_COMPLIANT_BITSTREAM; /*setup audio streams*/ if (ffd->st==GF_STREAM_AUDIO) { - if ((ffd->codec->type == CODEC_ID_MP3LAME) || (ffd->codec->type == CODEC_ID_MP2)) { - ffd->ctx->frame_size = (ffd->ctx->sample_rate > 24000) ? 1152 : 576; + if ((*codec)->type == CODEC_ID_MP2) { + (*ctx)->frame_size = ((*ctx)->sample_rate > 24000) ? 1152 : 576; } /*may be 0 (cfg not known yet)*/ - ffd->out_size = ffd->ctx->channels * ffd->ctx->frame_size * 2 /*16 / 8*/; - if (!ffd->ctx->sample_rate) ffd->ctx->sample_rate = 44100; - if (!ffd->ctx->channels) ffd->ctx->channels = 2; + ffd->out_size = (*ctx)->channels * (*ctx)->frame_size * 2 /*16 / 8*/; + if (!(*ctx)->sample_rate) (*ctx)->sample_rate = 44100; + if (!(*ctx)->channels) (*ctx)->channels = 2; } else { - switch (ffd->codec->id) { + switch ((*codec)->id) { case CODEC_ID_MJPEG: case CODEC_ID_MJPEGB: case CODEC_ID_LJPEG: @@ -259,39 +303,70 @@ static GF_Err FFDEC_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) ffd->pix_fmt = GF_PIXEL_RGB_24; break; case CODEC_ID_DVD_SUBTITLE: - ffd->frame = avcodec_alloc_frame(); - avcodec_decode_video(ffd->ctx, ffd->frame, &gotpic, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + *frame = avcodec_alloc_frame(); + avcodec_decode_video((*ctx), *frame, &gotpic, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); ffd->pix_fmt = GF_PIXEL_YV12; break; default: ffd->pix_fmt = GF_PIXEL_YV12; break; } - ffd->out_size = ffd->ctx->width * ffd->ctx->height * 3; ffd->out_pix_fmt = ffd->pix_fmt; -#if defined(_WIN32_WCE) || defined(__SYMBIAN32__) -#else -// if (ffd->pix_fmt == GF_PIXEL_YV12) ffd->out_pix_fmt = GF_PIXEL_RGB_24; -#endif - if (ffd->out_pix_fmt != GF_PIXEL_RGB_24) ffd->out_size /= 2; + if (ffd->out_pix_fmt == GF_PIXEL_YV12) { + if (ffd->depth_codec) { + ffd->out_size = (*ctx)->width * (*ctx)->height * 5 / 2; + ffd->out_pix_fmt = GF_PIXEL_YUVD; + ffd->yuv_size = (*ctx)->width * (*ctx)->height * 3 / 2; + } else { + ffd->out_size = (*ctx)->width * (*ctx)->height * 3 / 2; + } + } else { + ffd->out_size = (*ctx)->width * (*ctx)->height * 3; + } } return GF_OK; } static GF_Err FFDEC_DetachStream(GF_BaseDecoder *plug, u16 ES_ID) { + AVCodecContext **ctx; + AVCodec **codec; +#ifdef FFMPEG_SWSCALE + struct SwsContext **sws; +#endif FFDec *ffd = (FFDec *)plug->privateStack; - if (!ffd->ES_ID) return GF_BAD_PARAM; - ffd->ES_ID = 0; - if (ffd->ctx) { - if (ffd->ctx->extradata) free(ffd->ctx->extradata); - avcodec_close(ffd->ctx); - ffd->ctx = NULL; + if (ffd->base_ES_ID==ES_ID) { + ffd->base_ES_ID = 0; + codec = &ffd->base_codec; + ctx = &ffd->base_ctx; +#ifdef FFMPEG_SWSCALE + sws = &ffd->base_sws; +#endif + } else if (ffd->depth_ES_ID==ES_ID) { + ffd->depth_ES_ID = 0; + codec = &ffd->depth_codec; + ctx = &ffd->depth_ctx; +#ifdef FFMPEG_SWSCALE + sws = &ffd->depth_sws; +#endif + } else { + return GF_OK; + } + + if (*ctx) { + if ((*ctx)->extradata) gf_free((*ctx)->extradata); + avcodec_close((*ctx)); + *ctx = NULL; } + *codec = NULL; + #ifdef FFMPEG_SWSCALE - if (ffd->sws_ctx) { sws_freeContext(ffd->sws_ctx); ffd->sws_ctx = NULL; } + if (*sws) { + sws_freeContext(*sws); + *sws = NULL; + } #endif return GF_OK; } @@ -314,7 +389,7 @@ static GF_Err FFDEC_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *ca return GF_OK; } - if (!ffd->ctx) { + if (!ffd->base_ctx) { capability->cap.valueInt = 0; return GF_OK; } @@ -325,10 +400,10 @@ static GF_Err FFDEC_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *ca capability->cap.valueInt = ffd->out_size; break; case GF_CODEC_SAMPLERATE: - capability->cap.valueInt = ffd->ctx->sample_rate; + capability->cap.valueInt = ffd->base_ctx->sample_rate; break; case GF_CODEC_NB_CHAN: - capability->cap.valueInt = ffd->ctx->channels; + capability->cap.valueInt = ffd->base_ctx->channels; break; case GF_CODEC_BITS_PER_SAMPLE: capability->cap.valueInt = 16; @@ -338,20 +413,20 @@ static GF_Err FFDEC_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *ca break; case GF_CODEC_BUFFER_MAX: /*for audio let the systems engine decide since we may have very large block size (1 sec with some QT movies)*/ - capability->cap.valueInt = (ffd->st==GF_STREAM_AUDIO) ? 0 : 4; + capability->cap.valueInt = (ffd->st==GF_STREAM_AUDIO) ? 0 : (ffd->is_image ? 1 : 4); break; /*by default AAC access unit lasts num_samples (timescale being sampleRate)*/ case GF_CODEC_CU_DURATION: - capability->cap.valueInt = (ffd->st==GF_STREAM_AUDIO) ? ffd->ctx->frame_size : 0; + capability->cap.valueInt = (ffd->st==GF_STREAM_AUDIO) ? ffd->base_ctx->frame_size : 0; break; case GF_CODEC_WIDTH: - capability->cap.valueInt = ffd->ctx->width; + capability->cap.valueInt = ffd->base_ctx->width; break; case GF_CODEC_HEIGHT: - capability->cap.valueInt = ffd->ctx->height; + capability->cap.valueInt = ffd->base_ctx->height; break; case GF_CODEC_STRIDE: - capability->cap.valueInt = ffd->ctx->width; + capability->cap.valueInt = ffd->base_ctx->width; if (ffd->out_pix_fmt==GF_PIXEL_RGB_24) capability->cap.valueInt *= 3; break; case GF_CODEC_FPS: @@ -361,7 +436,7 @@ static GF_Err FFDEC_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *ca capability->cap.valueInt = ffd->previous_par; break; case GF_CODEC_PIXEL_FORMAT: - if (ffd->ctx->width) capability->cap.valueInt = ffd->out_pix_fmt; + if (ffd->base_ctx->width) capability->cap.valueInt = ffd->out_pix_fmt; break; /*ffmpeg performs frame reordering internally*/ case GF_CODEC_REORDER: @@ -372,7 +447,7 @@ static GF_Err FFDEC_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *ca break; case GF_CODEC_CHANNEL_CONFIG: /*currently unused in ffmpeg*/ - if (ffd->ctx->channels==1) { + if (ffd->base_ctx->channels==1) { capability->cap.valueInt = GF_AUDIO_CH_FRONT_CENTER; } else { capability->cap.valueInt = GF_AUDIO_CH_FRONT_LEFT | GF_AUDIO_CH_FRONT_RIGHT; @@ -391,7 +466,10 @@ static GF_Err FFDEC_SetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability cap switch (capability.CapCode) { case GF_CODEC_WAIT_RAP: ffd->frame_start = 0; - if (ffd->st==GF_STREAM_VISUAL) avcodec_flush_buffers(ffd->ctx); + if (ffd->st==GF_STREAM_VISUAL) { + avcodec_flush_buffers(ffd->base_ctx); + if (ffd->depth_ctx) avcodec_flush_buffers(ffd->depth_ctx); + } return GF_OK; default: /*return unsupported to avoid confusion by the player (like color space changing ...) */ @@ -406,26 +484,55 @@ static GF_Err FFDEC_ProcessData(GF_MediaDecoder *plug, u8 PaddingBits, u32 mmlevel) { - s32 gotpic; + AVPacket pkt; + AVPicture pict; + u32 pix_out; + s32 w, h, gotpic; u32 outsize; + AVCodecContext *ctx; + AVCodec **codec; + AVFrame *frame; +#ifdef FFMPEG_SWSCALE + struct SwsContext **sws; +#endif FFDec *ffd = plug->privateStack; + + if (!ES_ID || (ffd->base_ES_ID==ES_ID)) { + ctx = ffd->base_ctx; + codec = &ffd->base_codec; + frame = ffd->base_frame; +#ifdef FFMPEG_SWSCALE + sws = &ffd->base_sws; +#endif + } else if (ffd->depth_ES_ID==ES_ID) { + ctx = ffd->depth_ctx; + codec = &ffd->depth_codec; + frame = ffd->depth_frame; +#ifdef FFMPEG_SWSCALE + sws = &ffd->depth_sws; +#endif + } else { + return GF_BAD_PARAM; + } + + /*WARNING: this breaks H264 (and maybe others) decoding, disabled for now*/ -#if 1 - if (!ffd->ctx->hurry_up) { +#if 0 + if (!ctx->hurry_up) { switch (mmlevel) { case GF_CODEC_LEVEL_SEEK: case GF_CODEC_LEVEL_DROP: /*skip as much as possible*/ - ffd->ctx->hurry_up = 5; + ctx->hurry_up = 5; break; case GF_CODEC_LEVEL_VERY_LATE: case GF_CODEC_LEVEL_LATE: /*skip B-frames*/ - ffd->ctx->hurry_up = 1; + ctx->hurry_up = 1; break; default: - ffd->ctx->hurry_up = 0; + ctx->hurry_up = 0; break; } } @@ -446,18 +553,18 @@ static GF_Err FFDEC_ProcessData(GF_MediaDecoder *plug, if (ffd->frame_start>inBufferLength) ffd->frame_start = 0; redecode: - len = avcodec_decode_audio(ffd->ctx, (short *)ffd->audio_buf, &gotpic, inBuffer + ffd->frame_start, inBufferLength - ffd->frame_start); + gotpic = AVCODEC_MAX_AUDIO_FRAME_SIZE; + len = avcodec_decode_audio2(ctx, (short *)ffd->audio_buf, &gotpic, inBuffer + ffd->frame_start, inBufferLength - ffd->frame_start); if (len<0) { ffd->frame_start = 0; return GF_NON_COMPLIANT_BITSTREAM; } if (gotpic<0) { ffd->frame_start = 0; return GF_OK; } - ffd->ctx->hurry_up = 0; - - if (ffd->ctx->frame_size < gotpic) ffd->ctx->frame_size = gotpic; + ctx->hurry_up = 0; /*first config*/ if (!ffd->out_size) { - ffd->out_size = ffd->ctx->channels * ffd->ctx->frame_size * 2 /* 16 / 8 */; + if (ctx->channels * ctx->frame_size* 2 < gotpic) ctx->frame_size = gotpic / 2 * ctx->channels; + ffd->out_size = ctx->channels * ctx->frame_size * 2 /* 16 / 8 */; } if (ffd->out_size < (u32) gotpic) { /*looks like relying on frame_size is not a good idea for all codecs, so we use gotpic*/ @@ -467,7 +574,7 @@ redecode: if (ffd->out_size > buf_size) { /*don't use too small output chunks otherwise we'll never have enough when mixing - we could also request more slots in the composition memory but let's not waste mem*/ - if (ffd->out_size < (u32) 576*ffd->ctx->channels) ffd->out_size=ffd->ctx->channels*576; + if (ffd->out_size < (u32) 576*ctx->channels) ffd->out_size=ctx->channels*576; (*outBufferLength) = ffd->out_size; return GF_BUFFER_TOO_SMALL; } @@ -483,174 +590,206 @@ redecode: return GF_OK; } /*still space go on*/ - if ((*outBufferLength)+ffd->ctx->frame_size<ffd->out_size) goto redecode; + if ((*outBufferLength)+ctx->frame_size<ffd->out_size) goto redecode; /*more frames in the current sample*/ return GF_PACKED_FRAMES; - } else { - s32 w = ffd->ctx->width; - s32 h = ffd->ctx->height; + } - if (ffd->check_h264_isma) { - /*for AVC bitstreams after ISMA decryption, in case (as we do) the decryption DRM tool - doesn't put back nalu size, do it ourselves...*/ - if (inBuffer && !inBuffer[0] && !inBuffer[1] && !inBuffer[2] && (inBuffer[3]==0x01)) { - u32 nalu_size; - u32 remain = inBufferLength; - char *start, *end; - - start = inBuffer; - end = inBuffer + 4; - while (remain>4) { - if (!end[0] && !end[1] && !end[2] && (end[3]==0x01)) { - nalu_size = end - start - 4; - start[0] = (nalu_size>>24)&0xFF; - start[1] = (nalu_size>>16)&0xFF; - start[2] = (nalu_size>>8)&0xFF; - start[3] = (nalu_size)&0xFF; - start = end; - end = start+4; - continue; - } - end++; - remain--; + /*visual stream*/ + w = ctx->width; + h = ctx->height; + + if (ffd->check_h264_isma) { + /*for AVC bitstreams after ISMA decryption, in case (as we do) the decryption DRM tool + doesn't put back nalu size, do it ourselves...*/ + if (inBuffer && !inBuffer[0] && !inBuffer[1] && !inBuffer[2] && (inBuffer[3]==0x01)) { + u32 nalu_size; + u32 remain = inBufferLength; + char *start, *end; + + start = inBuffer; + end = inBuffer + 4; + while (remain>4) { + if (!end[0] && !end[1] && !end[2] && (end[3]==0x01)) { + nalu_size = end - start - 4; + start[0] = (nalu_size>>24)&0xFF; + start[1] = (nalu_size>>16)&0xFF; + start[2] = (nalu_size>>8)&0xFF; + start[3] = (nalu_size)&0xFF; + start = end; + end = start+4; + continue; } - nalu_size = (inBuffer+inBufferLength) - start - 4; - start[0] = (nalu_size>>24)&0xFF; - start[1] = (nalu_size>>16)&0xFF; - start[2] = (nalu_size>>8)&0xFF; - start[3] = (nalu_size)&0xFF; - ffd->check_h264_isma = 2; - } - /*if we had ISMA E&A and lost it this is likely due to a pck loss - do NOT switch back to regular*/ - else if (ffd->check_h264_isma == 1) { - ffd->check_h264_isma = 0; + end++; + remain--; } + nalu_size = (inBuffer+inBufferLength) - start - 4; + start[0] = (nalu_size>>24)&0xFF; + start[1] = (nalu_size>>16)&0xFF; + start[2] = (nalu_size>>8)&0xFF; + start[3] = (nalu_size)&0xFF; + ffd->check_h264_isma = 2; } + /*if we had ISMA E&A and lost it this is likely due to a pck loss - do NOT switch back to regular*/ + else if (ffd->check_h264_isma == 1) { + ffd->check_h264_isma = 0; + } + } - if (avcodec_decode_video(ffd->ctx, ffd->frame, &gotpic, inBuffer, inBufferLength) < 0) { - if (!ffd->check_short_header) { + av_init_packet(&pkt); + pkt.data = inBuffer; + pkt.size = inBufferLength; + + +#if USE_AVCODEC2 + if (avcodec_decode_video2(ctx, frame, &gotpic, &pkt) < 0) { +#else + if (avcodec_decode_video(ctx, frame, &gotpic, inBuffer, inBufferLength) < 0) { +#endif + if (!ffd->check_short_header) { + return GF_NON_COMPLIANT_BITSTREAM; + } + + /*switch to H263 (ffmpeg MPEG-4 codec doesn't understand short headers)*/ + { + u32 old_codec = (*codec)->id; + ffd->check_short_header = 0; + /*OK we loose the DSI stored in the codec context, but H263 doesn't need any, and if we're + here this means the DSI was broken, so no big deal*/ + avcodec_close(ctx); + *codec = avcodec_find_decoder(CODEC_ID_H263); + if (! (*codec) || (avcodec_open(ctx, *codec)<0)) return GF_NON_COMPLIANT_BITSTREAM; + if (avcodec_decode_video(ctx, frame, &gotpic, inBuffer, inBufferLength) < 0) { + /*nope, stay in MPEG-4*/ + avcodec_close(ctx); + *codec = avcodec_find_decoder(old_codec); + assert(*codec); + avcodec_open(ctx, *codec); return GF_NON_COMPLIANT_BITSTREAM; } + } + } + ctx->hurry_up = 0; - /*switch to H263 (ffmpeg MPEG-4 codec doesn't understand short headers)*/ - { - u32 old_codec = ffd->codec->id; - ffd->check_short_header = 0; - /*OK we loose the DSI stored in the codec context, but H263 doesn't need any, and if we're - here this means the DSI was broken, so no big deal*/ - avcodec_close(ffd->ctx); - ffd->codec = avcodec_find_decoder(CODEC_ID_H263); - if (!ffd->codec || (avcodec_open(ffd->ctx, ffd->codec)<0)) return GF_NON_COMPLIANT_BITSTREAM; - if (avcodec_decode_video(ffd->ctx, ffd->frame, &gotpic, inBuffer, inBufferLength) < 0) { - /*nope, stay in MPEG-4*/ - avcodec_close(ffd->ctx); - ffd->codec = avcodec_find_decoder(old_codec); - assert(ffd->codec); - avcodec_open(ffd->ctx, ffd->codec); - return GF_NON_COMPLIANT_BITSTREAM; - } - } + /*some streams use odd width/height frame values*/ + if (ffd->out_pix_fmt == GF_PIXEL_YV12) { + if (ctx->width%2) ctx->width++; + if (ctx->height%2) ctx->height++; + } + + /*recompute outsize in case on-the-fly change*/ + if ((w != ctx->width) || (h != ctx->height)) { + outsize = ctx->width * ctx->height * 3; + if (ffd->out_pix_fmt != GF_PIXEL_RGB_24) outsize /= 2; + ffd->out_size = outsize; + *outBufferLength = ffd->out_size; + if (ffd->check_h264_isma) { + inBuffer[0] = inBuffer[1] = inBuffer[2] = 0; + inBuffer[3] = 1; } - ffd->ctx->hurry_up = 0; - /*recompute outsize in case on-the-fly change*/ - if ((w != ffd->ctx->width) || (h != ffd->ctx->height)) { - outsize = ffd->ctx->width * ffd->ctx->height * 3; - if (ffd->out_pix_fmt != GF_PIXEL_RGB_24) outsize /= 2; - ffd->out_size = outsize; - *outBufferLength = ffd->out_size; - if (ffd->check_h264_isma) { - inBuffer[0] = inBuffer[1] = inBuffer[2] = 0; - inBuffer[3] = 1; - } #ifdef FFMPEG_SWSCALE - if (ffd->sws_ctx) { sws_freeContext(ffd->sws_ctx); ffd->sws_ctx = NULL; } + if (*sws) { + sws_freeContext(*sws); + *sws = NULL; + } #endif + return GF_BUFFER_TOO_SMALL; + } + /*check PAR in case on-the-fly change*/ + if (!ffd->no_par_update && ctx->sample_aspect_ratio.num && ctx->sample_aspect_ratio.den) { + u32 new_par = (ctx->sample_aspect_ratio.num<<16) | ctx->sample_aspect_ratio.den; + if (new_par != ffd->previous_par) { + ffd->previous_par = new_par; + *outBufferLength = ffd->out_size; return GF_BUFFER_TOO_SMALL; } - /*check PAR in case on-the-fly change*/ - if (!ffd->no_par_update && ffd->ctx->sample_aspect_ratio.num && ffd->ctx->sample_aspect_ratio.den) { - u32 new_par = (ffd->ctx->sample_aspect_ratio.num<<16) | ffd->ctx->sample_aspect_ratio.den; - if (new_par != ffd->previous_par) { - ffd->previous_par = new_par; - *outBufferLength = ffd->out_size; - return GF_BUFFER_TOO_SMALL; - } + } + + *outBufferLength = 0; + if (mmlevel == GF_CODEC_LEVEL_SEEK) return GF_OK; + + if (!gotpic) return GF_OK; + + if (ES_ID == ffd->depth_ES_ID) { + s32 i; + u8 *pYO, *pYD; + pYO = frame->data[0]; + pYD = outBuffer+ffd->yuv_size; + for (i=0; i<ctx->height; i++) { + memcpy(pYD, pYO, sizeof(char) * ctx->width); + pYD += ctx->width; + pYO += frame->linesize[0]; } + *outBufferLength = ffd->out_size; + return GF_OK; + } - *outBufferLength = 0; - if (mmlevel == GF_CODEC_LEVEL_SEEK) return GF_OK; +#if defined(_WIN32_WCE) || defined(__SYMBIAN32__) + if (ffd->pix_fmt==GF_PIXEL_RGB_24) { + memcpy(outBuffer, frame->data[0], sizeof(char)*3*ctx->width); + } else { + s32 i; + char *pYO, *pUO, *pVO; + unsigned char *pYD, *pUD, *pVD; + pYO = frame->data[0]; + pUO = frame->data[1]; + pVO = frame->data[2]; + pYD = outBuffer; + pUD = outBuffer + ctx->width * ctx->height; + pVD = outBuffer + 5 * ctx->width * ctx->height / 4; + - if (gotpic) { -#if defined(_WIN32_WCE) || defined(__SYMBIAN32__) - if (ffd->pix_fmt==GF_PIXEL_RGB_24) { - memcpy(outBuffer, ffd->frame->data[0], sizeof(char)*3*ffd->ctx->width); - } else { - s32 i; - char *pYO, *pUO, *pVO; - unsigned char *pYD, *pUD, *pVD; - pYO = ffd->frame->data[0]; - pUO = ffd->frame->data[1]; - pVO = ffd->frame->data[2]; - pYD = outBuffer; - pUD = outBuffer + ffd->ctx->width * ffd->ctx->height; - pVD = outBuffer + 5 * ffd->ctx->width * ffd->ctx->height / 4; - - - for (i=0; i<ffd->ctx->height; i++) { - memcpy(pYD, pYO, sizeof(char) * ffd->ctx->width); - pYD += ffd->ctx->width; - pYO += ffd->frame->linesize[0]; - if (i%2) continue; - - memcpy(pUD, pUO, sizeof(char) * ffd->ctx->width/2); - memcpy(pVD, pVO, sizeof(char) * ffd->ctx->width/2); - pUD += ffd->ctx->width/2; - pVD += ffd->ctx->width/2; - pUO += ffd->frame->linesize[1]; - pVO += ffd->frame->linesize[2]; - } - *outBufferLength = ffd->out_size; - } + for (i=0; i<ctx->height; i++) { + memcpy(pYD, pYO, sizeof(char) * ctx->width); + pYD += ctx->width; + pYO += frame->linesize[0]; + if (i%2) continue; + + memcpy(pUD, pUO, sizeof(char) * ctx->width/2); + memcpy(pVD, pVO, sizeof(char) * ctx->width/2); + pUD += ctx->width/2; + pVD += ctx->width/2; + pUO += frame->linesize[1]; + pVO += frame->linesize[2]; + } + *outBufferLength = ffd->out_size; + } #else - AVPicture pict; - u32 pix_out; - memset(&pict, 0, sizeof(pict)); - if (ffd->out_pix_fmt==GF_PIXEL_RGB_24) { - pict.data[0] = outBuffer; - pict.linesize[0] = 3*ffd->ctx->width; - pix_out = PIX_FMT_RGB24; - } else { - pict.data[0] = outBuffer; - pict.data[1] = outBuffer + ffd->ctx->width * ffd->ctx->height; - pict.data[2] = outBuffer + 5 * ffd->ctx->width * ffd->ctx->height / 4; - pict.linesize[0] = ffd->ctx->width; - pict.linesize[1] = pict.linesize[2] = ffd->ctx->width/2; - pix_out = PIX_FMT_YUV420P; - if (!mmlevel && ffd->frame->interlaced_frame) { - avpicture_deinterlace((AVPicture *) ffd->frame, (AVPicture *) ffd->frame, ffd->ctx->pix_fmt, ffd->ctx->width, ffd->ctx->height); - } - - } - pict.data[3] = 0; - pict.linesize[3] = 0; + memset(&pict, 0, sizeof(pict)); + if (ffd->out_pix_fmt==GF_PIXEL_RGB_24) { + pict.data[0] = outBuffer; + pict.linesize[0] = 3*ctx->width; + pix_out = PIX_FMT_RGB24; + } else { + pict.data[0] = outBuffer; + pict.data[1] = outBuffer + ctx->width * ctx->height; + pict.data[2] = outBuffer + 5 * ctx->width * ctx->height / 4; + pict.linesize[0] = ctx->width; + pict.linesize[1] = pict.linesize[2] = ctx->width/2; + pix_out = PIX_FMT_YUV420P; + if (!mmlevel && frame->interlaced_frame) { + avpicture_deinterlace((AVPicture *) frame, (AVPicture *) frame, ctx->pix_fmt, ctx->width, ctx->height); + } + } + pict.data[3] = 0; + pict.linesize[3] = 0; #ifndef FFMPEG_SWSCALE - img_convert(&pict, pix_out, (AVPicture *) ffd->frame, ffd->ctx->pix_fmt, ffd->ctx->width, ffd->ctx->height); + img_convert(&pict, pix_out, (AVPicture *) frame, ctx->pix_fmt, ctx->width, ctx->height); #else - if (!ffd->sws_ctx) - ffd->sws_ctx = sws_getContext(ffd->ctx->width, ffd->ctx->height, - ffd->ctx->pix_fmt, ffd->ctx->width, ffd->ctx->height, pix_out, SWS_BICUBIC, - NULL, NULL, NULL); - - if (ffd->sws_ctx) - sws_scale(ffd->sws_ctx, ffd->frame->data, ffd->frame->linesize, 0, ffd->ctx->height->codec->height, pict.data, pict.linesize); + if (! (*sws)) + (*sws) = sws_getContext(ctx->width, ctx->height, + ctx->pix_fmt, ctx->width, ctx->height, pix_out, SWS_BICUBIC, + NULL, NULL, NULL); + + if ((*sws)) + sws_scale((*sws), frame->data, frame->linesize, 0, ctx->height, pict.data, pict.linesize); #endif - *outBufferLength = ffd->out_size; + *outBufferLength = ffd->out_size; #endif - } - } + return GF_OK; } @@ -688,7 +827,7 @@ static Bool FFDEC_CanHandleStream(GF_BaseDecoder *plug, u32 StreamType, u32 Obje } else if (StreamType==GF_STREAM_AUDIO) { /*std MPEG-2 audio*/ - if ((ObjectType==0x69) || (ObjectType==0x6B)) codec_id = CODEC_ID_MP2; + if ((ObjectType==GPAC_OTI_AUDIO_MPEG2_PART3) || (ObjectType==GPAC_OTI_AUDIO_MPEG1)) codec_id = CODEC_ID_MP2; /*std AC3 audio*/ //if (ObjectType==0xA5) codec_id = CODEC_ID_AC3; } @@ -697,23 +836,25 @@ static Bool FFDEC_CanHandleStream(GF_BaseDecoder *plug, u32 StreamType, u32 Obje else if (StreamType==GF_STREAM_VISUAL) { switch (ObjectType) { /*MPEG-4 v1 simple profile*/ - case 0x20: codec_id = CODEC_ID_MPEG4; break; + case GPAC_OTI_VIDEO_MPEG4_PART2: codec_id = CODEC_ID_MPEG4; break; /*H264 (not std OTI, just the way we use it internally)*/ - case 0x21: codec_id = CODEC_ID_H264; break; + case GPAC_OTI_VIDEO_AVC: codec_id = CODEC_ID_H264; break; /*MPEG1 video*/ - case 0x6A: + case GPAC_OTI_VIDEO_MPEG1: /*MPEG2 video*/ - case 0x60: - case 0x61: - case 0x62: - case 0x63: - case 0x64: - case 0x65: + case GPAC_OTI_VIDEO_MPEG2_SIMPLE: + case GPAC_OTI_VIDEO_MPEG2_MAIN: + case GPAC_OTI_VIDEO_MPEG2_SNR: + case GPAC_OTI_VIDEO_MPEG2_SPATIAL: + case GPAC_OTI_VIDEO_MPEG2_HIGH: + case GPAC_OTI_VIDEO_MPEG2_422: codec_id = CODEC_ID_MPEG2VIDEO; break; /*JPEG*/ - case 0x6C: - return 0; /*I'm having troubles with ffmpeg & jpeg, it appears to crash randomly*/ - return 1; + case GPAC_OTI_IMAGE_JPEG: +// return 0; /*I'm having troubles with ffmpeg & jpeg, it appears to crash randomly*/ + codec_id = CODEC_ID_MJPEG; + fprintf(stdout, "bla"); + break; default: return 0; } @@ -728,13 +869,12 @@ static Bool FFDEC_CanHandleStream(GF_BaseDecoder *plug, u32 StreamType, u32 Obje return 0; } -static char szCodec[100]; static const char *FFDEC_GetCodecName(GF_BaseDecoder *dec) { FFDec *ffd = dec->privateStack; - if (ffd->codec) { - sprintf(szCodec, "FFMPEG %s", ffd->codec->name ? ffd->codec->name : "unknown"); - return szCodec; + if (ffd->base_codec) { + sprintf(ffd->szCodec, "FFMPEG %s", ffd->base_codec->name ? ffd->base_codec->name : "unknown"); + return ffd->szCodec; } return NULL; } @@ -769,8 +909,13 @@ void FFDEC_Delete(void *ifce) GF_BaseDecoder *dec = ifce; FFDec *ffd = dec->privateStack; - if (ffd->ctx) avcodec_close(ffd->ctx); - free(ffd); - free(dec); + if (ffd->base_ctx) avcodec_close(ffd->base_ctx); + if (ffd->depth_ctx) avcodec_close(ffd->depth_ctx); +#ifdef FFMPEG_SWSCALE + if (ffd->base_sws) sws_freeContext(ffd->base_sws); + if (ffd->depth_sws) sws_freeContext(ffd->base_sws); +#endif + gf_free(ffd); + gf_free(dec); } diff --git a/modules/ffmpeg_in/ffmpeg_demux.c b/modules/ffmpeg_in/ffmpeg_demux.c index fcc9c63..001cf9a 100644 --- a/modules/ffmpeg_in/ffmpeg_demux.c +++ b/modules/ffmpeg_in/ffmpeg_demux.c @@ -167,15 +167,20 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url) char *ext, szName[1000], szExt[20]; const char *szExtList; + /*disable RTP/RTSP from ffmpeg*/ + if (!strnicmp(url, "rtsp://", 7)) return 0; + if (!strnicmp(url, "rtspu://", 8)) return 0; + if (!strnicmp(url, "rtp://", 6)) return 0; + if (!strnicmp(url, "plato://", 8)) return 0; + if (!strnicmp(url, "udp://", 6)) return 0; + if (!strnicmp(url, "tcp://", 6)) return 0; + if (!strnicmp(url, "data:", 5)) return 0; + strcpy(szName, url); ext = strrchr(szName, '#'); if (ext) ext[0] = 0; - - /*disable RTP/RTSP from ffmpeg*/ - if (!strnicmp(szName, "rtsp://", 7)) return 0; - if (!strnicmp(szName, "rtspu://", 8)) return 0; - if (!strnicmp(szName, "rtp://", 6)) return 0; - if (!strnicmp(szName, "plato://", 8)) return 0; + ext = strrchr(szName, '?'); + if (ext) ext[0] = 0; ext = strrchr(szName, '.'); if (ext) { @@ -193,6 +198,8 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url) || !strcmp(szExt, "amr") || !strcmp(szExt, "bt") || !strcmp(szExt, "wrl") || !strcmp(szExt, "x3dv") || !strcmp(szExt, "xmt") || !strcmp(szExt, "xmta") || !strcmp(szExt, "x3d") + + || !strcmp(szExt, "jpg") || !strcmp(szExt, "jpeg") || !strcmp(szExt, "png") ) return 0; /*check any default stuff that should work with ffmpeg*/ @@ -204,6 +211,8 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url) if (gf_term_check_extension(plug, "audio/vnd.wave", "wav", "WAV Audio", ext)) return 1; if (gf_term_check_extension(plug, "video/x-ms-asf", "asf wma wmv asx asr", "WindowsMedia Movies", ext)) return 1; if (gf_term_check_extension(plug, "video/x-ms-wmv", "asf wma wmv asx asr", "WindowsMedia Movies", ext)) return 1; + if (gf_term_check_extension(plug, "video/x-msvideo", "avi", "AVI Movies", ext)) return 1; + if (gf_term_check_extension(plug, "video/x-ms-video", "avi", "AVI Movies", ext)) return 1; if (gf_term_check_extension(plug, "video/avi", "avi", "AVI Movies", ext)) return 1; if (gf_term_check_extension(plug, "video/vnd.avi", "avi", "AVI Movies", ext)) return 1; @@ -261,11 +270,11 @@ static Bool FFD_CanHandleURL(GF_InputService *plug, const char *url) u32 len; char *buf; len = strlen(szExtList) + strlen(szExt) + 10; - buf = malloc(sizeof(char)*len); + buf = gf_malloc(sizeof(char)*len); sprintf(buf, "\"%s ", szExt); strcat(buf, &szExtList[1]); gf_modules_set_option((GF_BaseInterface *)plug, "MimeTypes", "application/x-ffmpeg", buf); - free(buf); + gf_free(buf); } } } @@ -291,16 +300,16 @@ static GF_ESD *FFD_GetESDescriptor(FFDemux *ffd, Bool for_audio) esd->slConfig->timestampResolution = ffd->audio_tscale.den; switch (dec->codec_id) { case CODEC_ID_MP2: - esd->decoderConfig->objectTypeIndication = 0x6B; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG1; break; case CODEC_ID_MP3: - esd->decoderConfig->objectTypeIndication = 0x69; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG2_PART3; break; case CODEC_ID_AAC: if (!dec->extradata_size) goto opaque_audio; - esd->decoderConfig->objectTypeIndication = 0x40; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; esd->decoderConfig->decoderSpecificInfo->dataLength = dec->extradata_size; - esd->decoderConfig->decoderSpecificInfo->data = malloc(sizeof(char)*dec->extradata_size); + esd->decoderConfig->decoderSpecificInfo->data = gf_malloc(sizeof(char)*dec->extradata_size); memcpy(esd->decoderConfig->decoderSpecificInfo->data, dec->extradata, sizeof(char)*dec->extradata_size); @@ -339,18 +348,18 @@ opaque_audio: /*if dsi not detected force use ffmpeg*/ if (!dec->extradata_size) goto opaque_video; /*otherwise use any MPEG-4 Visual*/ - esd->decoderConfig->objectTypeIndication = (dec->codec_id==CODEC_ID_H264) ? 0x21 : 0x20; + esd->decoderConfig->objectTypeIndication = (dec->codec_id==CODEC_ID_H264) ? GPAC_OTI_VIDEO_AVC : GPAC_OTI_VIDEO_MPEG4_PART2; esd->decoderConfig->decoderSpecificInfo->dataLength = dec->extradata_size; - esd->decoderConfig->decoderSpecificInfo->data = malloc(sizeof(char)*dec->extradata_size); + esd->decoderConfig->decoderSpecificInfo->data = gf_malloc(sizeof(char)*dec->extradata_size); memcpy(esd->decoderConfig->decoderSpecificInfo->data, dec->extradata, sizeof(char)*dec->extradata_size); break; case CODEC_ID_MPEG1VIDEO: - esd->decoderConfig->objectTypeIndication = 0x6A; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_MPEG1; break; case CODEC_ID_MPEG2VIDEO: - esd->decoderConfig->objectTypeIndication = 0x65; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_MPEG2_422; break; default: opaque_video: @@ -392,7 +401,7 @@ static void FFD_SetupObjects(FFDemux *ffd) GF_ObjectDescriptor *od; u32 audio_esid = 0; - if (ffd->audio_st>=0) { + if ((ffd->audio_st>=0) && (ffd->service_type != 1)) { od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); esd = FFD_GetESDescriptor(ffd, 1); od->objectDescriptorID = esd->ESID; @@ -400,7 +409,7 @@ static void FFD_SetupObjects(FFDemux *ffd) gf_list_add(od->ESDescriptors, esd); gf_term_add_media(ffd->service, (GF_Descriptor*)od, (ffd->video_st>=0) ? 1 : 0); } - if (ffd->video_st>=0) { + if ((ffd->video_st>=0) && (ffd->service_type != 2)) { od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); esd = FFD_GetESDescriptor(ffd, 0); od->objectDescriptorID = esd->ESID; @@ -412,17 +421,19 @@ static void FFD_SetupObjects(FFDemux *ffd) static int ff_url_read(void *h, unsigned char *buf, int size) { + u32 retry = 10; u32 read; int full_size; FFDemux *ffd = (FFDemux *)h; - gf_term_download_update_stats(ffd->dnload); full_size = 0; if (ffd->buffer_used) { if (ffd->buffer_used>size) { ffd->buffer_used-=size; memcpy(ffd->buffer, ffd->buffer+size, sizeof(char)*ffd->buffer_used); +#ifdef FFMPEG_DUMP_REMOTE if (ffd->outdbg) fwrite(buf, size, 1, ffd->outdbg); +#endif return size; } full_size += ffd->buffer_used; @@ -435,7 +446,15 @@ static int ff_url_read(void *h, unsigned char *buf, int size) GF_Err e = gf_dm_sess_fetch_data(ffd->dnload, buf, size, &read); if (e==GF_EOS) break; /*we're sync!!*/ - if (e==GF_IP_NETWORK_EMPTY) continue; + if (e==GF_IP_NETWORK_EMPTY) { + if (!retry) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG Demuxer] timeout fetching bytes from network\n") ); + return -1; + } + retry --; + gf_sleep(100); + continue; + } if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG Demuxer] error fetching bytes from network: %s\n", gf_error_to_string(e) ) ); return -1; @@ -445,7 +464,9 @@ static int ff_url_read(void *h, unsigned char *buf, int size) size -= read; buf += read; } +#ifdef FFMPEG_DUMP_REMOTE if (ffd->outdbg) fwrite(ffd->buffer, full_size, 1, ffd->outdbg); +#endif return full_size ? (int) full_size : -1; } @@ -453,11 +474,13 @@ static void FFD_NetIO(void *cbk, GF_NETIO_Parameter *param) { } + static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) { GF_Err e; s64 last_aud_pts; u32 i; + s32 res; Bool is_local; const char *sOpt; char *ext, szName[1000]; @@ -496,10 +519,12 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv, ffd->buffer_size = 8192; sOpt = gf_modules_get_option((GF_BaseInterface *)plug, "FFMPEG", "IOBufferSize"); if (sOpt) ffd->buffer_size = atoi(sOpt); - ffd->buffer = malloc(sizeof(char)*ffd->buffer_size); - ffd->outdbg = fopen("ffdeb.raw", "wb"); - + ffd->buffer = gf_malloc(sizeof(char)*ffd->buffer_size); +#ifdef FFMPEG_DUMP_REMOTE + ffd->outdbg = gf_f64_open("ffdeb.raw", "wb"); +#endif init_put_byte(&ffd->io, ffd->buffer, ffd->buffer_size, 0, ffd, ff_url_read, NULL, NULL); + ffd->io.is_streamed = 1; ffd->dnload = gf_term_download_new(ffd->service, url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_NOT_CACHED, FFD_NetIO, ffd); if (!ffd->dnload) return GF_URL_ERROR; @@ -519,29 +544,29 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv, if (!av_in) { return GF_NOT_SUPPORTED; } - if (ffd->outdbg) fwrite(ffd->buffer, ffd->buffer_used, 1, ffd->outdbg); - ffd->buffer_used = 0; - /*setup downloader*/ av_in->flags |= AVFMT_NOFILE; - i = av_open_input_stream(&ffd->ctx, &ffd->io, szName, av_in, NULL); + res = av_open_input_stream(&ffd->ctx, &ffd->io, szName, av_in, NULL); } else { - i = av_open_input_file(&ffd->ctx, szName, av_in, 0, NULL); + res = av_open_input_file(&ffd->ctx, szName, av_in, 0, NULL); } - switch (i) { + switch (res) { +#ifndef _WIN32_WCE case 0: e = GF_OK; break; case AVERROR_IO: e = GF_URL_ERROR; goto err_exit; case AVERROR_INVALIDDATA: e = GF_NON_COMPLIANT_BITSTREAM; goto err_exit; case AVERROR_NOMEM: e = GF_OUT_OF_MEM; goto err_exit; case AVERROR_NOFMT: e = GF_NOT_SUPPORTED; goto err_exit; +#endif default: e = GF_SERVICE_ERROR; goto err_exit; } GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[FFMPEG] looking for streams in %s - %d streams - type %s\n", ffd->ctx->filename, ffd->ctx->nb_streams, ffd->ctx->iformat->name)); - if (av_find_stream_info(ffd->ctx) <0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] cannot locate streams\n")); + res = av_find_stream_info(ffd->ctx); + if (res <0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[FFMPEG] cannot locate streams - error %d\n", res)); e = GF_NOT_SUPPORTED; goto err_exit; } @@ -581,22 +606,22 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv, if (sOpt) ffd->data_buffer_ms = atoi(sOpt); if (!ffd->data_buffer_ms) ffd->data_buffer_ms = FFD_DATA_BUFFER; - /*check we do have increasing pts. If not we can't rely on pts, we must skip SL - we assume video pts is always present*/ - if (ffd->audio_st>=0) { - last_aud_pts = 0; - for (i=0; i<20; i++) { - AVPacket pkt; - pkt.stream_index = -1; - if (av_read_frame(ffd->ctx, &pkt) <0) break; - if (pkt.pts == AV_NOPTS_VALUE) pkt.pts = pkt.dts; - if (pkt.stream_index==ffd->audio_st) last_aud_pts = pkt.pts; - } - if (last_aud_pts*ffd->audio_tscale.den<10*ffd->audio_tscale.num) ffd->unreliable_audio_timing = 1; - } - /*build seek*/ if (is_local) { + /*check we do have increasing pts. If not we can't rely on pts, we must skip SL + we assume video pts is always present*/ + if (ffd->audio_st>=0) { + last_aud_pts = 0; + for (i=0; i<20; i++) { + AVPacket pkt; + pkt.stream_index = -1; + if (av_read_frame(ffd->ctx, &pkt) <0) break; + if (pkt.pts == AV_NOPTS_VALUE) pkt.pts = pkt.dts; + if (pkt.stream_index==ffd->audio_st) last_aud_pts = pkt.pts; + } + if (last_aud_pts*ffd->audio_tscale.den<10*ffd->audio_tscale.num) ffd->unreliable_audio_timing = 1; + } + ffd->seekable = (av_seek_frame(ffd->ctx, -1, 0, AVSEEK_FLAG_BACKWARD)<0) ? 0 : 1; if (!ffd->seekable) { av_close_input_file(ffd->ctx); @@ -607,7 +632,7 @@ static GF_Err FFD_ConnectService(GF_InputService *plug, GF_ClientService *serv, /*let's go*/ gf_term_on_connect(serv, NULL, GF_OK); - if (!ffd->service_type) FFD_SetupObjects(ffd); + /*if (!ffd->service_type)*/ FFD_SetupObjects(ffd); ffd->service_type = 0; return GF_OK; @@ -671,16 +696,20 @@ static GF_Err FFD_CloseService(GF_InputService *plug) ffd->audio_run = ffd->video_run = 0; if (ffd->dnload) { - while (!ffd->is_running) gf_sleep(0); - ffd->is_running = 0; + if (ffd->is_running) { + while (!ffd->is_running) gf_sleep(0); + ffd->is_running = 0; + } gf_term_download_del(ffd->dnload); ffd->dnload = NULL; } - if (ffd->buffer) free(ffd->buffer); + if (ffd->buffer) gf_free(ffd->buffer); ffd->buffer = NULL; gf_term_on_disconnect(ffd->service, NULL, GF_OK); +#ifdef FFMPEG_DUMP_REMOTE if (ffd->outdbg) fclose(ffd->outdbg); +#endif return GF_OK; } @@ -817,18 +846,18 @@ static Bool FFD_CanHandleURLInService(GF_InputService *plug, const char *url) if ((url[0] != '#') && strnicmp(szURL, url, sizeof(char)*strlen(szURL))) return 0; sep = strrchr(url, '#'); - if (!stricmp(sep, "#video") && (ffd->video_st>=0)) return 1; - if (!stricmp(sep, "#audio") && (ffd->audio_st>=0)) return 1; + if (sep && !stricmp(sep, "#video") && (ffd->video_st>=0)) return 1; + if (sep && !stricmp(sep, "#audio") && (ffd->audio_st>=0)) return 1; return 0; } void *New_FFMPEG_Demux() { FFDemux *priv; - GF_InputService *ffd = malloc(sizeof(GF_InputService)); + GF_InputService *ffd = gf_malloc(sizeof(GF_InputService)); memset(ffd, 0, sizeof(GF_InputService)); - priv = malloc(sizeof(FFDemux)); + priv = gf_malloc(sizeof(FFDemux)); memset(priv, 0, sizeof(FFDemux)); /* register all codecs, demux and protocols */ @@ -862,8 +891,8 @@ void Delete_FFMPEG_Demux(void *ifce) gf_th_del(ffd->thread); gf_mx_del(ffd->mx); - free(ffd); - free(ptr); + gf_free(ffd); + gf_free(ptr); } diff --git a/modules/ffmpeg_in/ffmpeg_in.def b/modules/ffmpeg_in/ffmpeg_in.def deleted file mode 100644 index fee6546..0000000 --- a/modules/ffmpeg_in/ffmpeg_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_ffmpeg_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/ffmpeg_in/ffmpeg_in.h b/modules/ffmpeg_in/ffmpeg_in.h index 81358bb..dfc83fc 100644 --- a/modules/ffmpeg_in/ffmpeg_in.h +++ b/modules/ffmpeg_in/ffmpeg_in.h @@ -56,40 +56,61 @@ /*include FFMPEG APIs*/ + +#ifdef FFMPEG_OLD_HEADERS #include <ffmpeg/avformat.h> +#else +#include <libavformat/avformat.h> +#endif void gf_av_vlog(void* avcl, int level, const char *fmt, va_list vl); #if LIBAVCODEC_VERSION_INT > ((52<<16)+(0<<8)+0) #define FFMPEG_SWSCALE +#ifdef FFMPEG_OLD_HEADERS #include <ffmpeg/swscale.h> +#else +#include <libswscale/swscale.h> +#endif #endif /*FFMPEG decoder module */ typedef struct { - u32 ES_ID; + char szCodec[100]; u32 out_size; u32 oti, st; u32 previous_par; Bool no_par_update; Bool check_short_header; - AVCodecContext *ctx; - AVCodec *codec; - AVFrame *frame; u32 pix_fmt; u32 out_pix_fmt; - -#ifdef FFMPEG_SWSCALE - struct SwsContext *sws_ctx; -#endif + Bool is_image; /*for audio packed frames*/ u32 frame_start; char audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE]; Bool check_h264_isma; + + u32 base_ES_ID; + AVCodecContext *base_ctx; + AVCodec *base_codec; + AVFrame *base_frame; +#ifdef FFMPEG_SWSCALE + struct SwsContext *base_sws; +#endif + + u32 depth_ES_ID; + u32 yuv_size; + AVCodecContext *depth_ctx; + AVCodec *depth_codec; + AVFrame *depth_frame; +#ifdef FFMPEG_SWSCALE + struct SwsContext *depth_sws; +#endif + } FFDec; void *FFDEC_Load(); @@ -103,6 +124,7 @@ void FFDEC_Delete(void *ifce); //#define FFMPEG_IO_BUF_SIZE 16384 +//#define FFMPEG_DUMP_REMOTE typedef struct { @@ -142,7 +164,9 @@ typedef struct u32 buffer_used; +#ifdef FFMPEG_DUMP_REMOTE FILE *outdbg; +#endif } FFDemux; void *New_FFMPEG_Demux(); diff --git a/modules/ffmpeg_in/ffmpeg_load.c b/modules/ffmpeg_in/ffmpeg_load.c index ff5b320..5c26007 100644 --- a/modules/ffmpeg_in/ffmpeg_load.c +++ b/modules/ffmpeg_in/ffmpeg_load.c @@ -24,13 +24,20 @@ #include "ffmpeg_in.h" +#if defined(_WIN32_WCE) && !defined(__GNUC__) +#pragma comment(lib, "toolhelp") +#pragma comment(lib, "winsock") +#endif GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1; - if (InterfaceType == GF_NET_CLIENT_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_MEDIA_DECODER_INTERFACE, + GF_NET_CLIENT_INTERFACE, + 0 + }; + return si; } GF_EXPORT diff --git a/modules/ft_font/Makefile b/modules/ft_font/Makefile index a5db870..3d468db 100644 --- a/modules/ft_font/Makefile +++ b/modules/ft_font/Makefile @@ -21,24 +21,25 @@ SRCS := $(OBJS:.o=.c) LIB=gm_ft_font.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols ft_font.def +#LDFLAGS+=-export-symbols ft_font.def endif +ifneq ($(STATICBUILD),yes) LINKVAR=-L../../bin/gcc -lgpac $(FT_LIBS) - - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) else -OBJSPIC=$(OBJS) +LINKVAR=-L../../bin/gcc -lgpac_static $(FT_LIBS) endif + all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(LINKVAR) $(EXTRALIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKVAR) $(EXTRALIBS) +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ft_font-static.so $(OBJS) $(LINKVAR) $(EXTRALIBS) +endif %.o: %.c diff --git a/modules/ft_font/ft_font.c b/modules/ft_font/ft_font.c index 06ab03e..6db1a7f 100644 --- a/modules/ft_font/ft_font.c +++ b/modules/ft_font/ft_font.c @@ -44,15 +44,13 @@ typedef struct GF_List *loaded_fonts; /*default fonts*/ - char font_serif[1024]; - char font_sans[1024]; - char font_fixed[1024]; + char *font_serif, *font_sans, *font_fixed; } FTBuilder; static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path) { - char szFont[GF_MAX_PATH]; + char *szfont; FT_Face face; u32 num_faces, i; GF_FontReader *dr = cbck; @@ -61,7 +59,7 @@ static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path) GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Enumerating font %s (%s)\n", file_name, file_path)); if (FT_New_Face(ftpriv->library, file_path, 0, & face )) return 0; - if (!face) return 0; + if (!face || !face->family_name) return 0; num_faces = face->num_faces; /*locate right font in collection if several*/ @@ -69,69 +67,82 @@ static Bool ft_enum_fonts(void *cbck, char *file_name, char *file_path) /*only scan scalable fonts*/ if (face->face_flags & FT_FACE_FLAG_SCALABLE) { - Bool bold, italic, smallcaps; - strcpy(szFont, face->family_name); + Bool bold, italic; + szfont = gf_malloc(sizeof(char)* (strlen(face->family_name)+100)); + if (!szfont) continue; + strcpy(szfont, face->family_name); /*remember first font found which looks like a alphabetical one*/ - if (!strlen(ftpriv->font_dir)) { + if (!ftpriv->font_dir) { u32 gidx; FT_Select_Charmap(face, FT_ENCODING_UNICODE); gidx = FT_Get_Char_Index(face, (u32) 'a'); if (gidx) gidx = FT_Get_Char_Index(face, (u32) 'z'); if (gidx) gidx = FT_Get_Char_Index(face, (u32) '1'); if (gidx) gidx = FT_Get_Char_Index(face, (u32) '@'); - if (gidx) strcpy(ftpriv->font_dir, szFont); + if (gidx) ftpriv->font_dir = gf_strdup(szfont); } - bold = italic = smallcaps = 0; + bold = italic = 0; if (face->style_name) { - char *name = strdup(face->style_name); + char *name = gf_strdup(face->style_name); strupr(name); if (strstr(name, "BOLD")) bold = 1; if (strstr(name, "ITALIC")) italic = 1; - free(name); + /*if font is not regular style, append all styles blindly*/ + if (!strstr(name, "REGULAR")) { + strcat(szfont, " "); + strcat(szfont, face->style_name); + } + gf_free(name); } else { if (face->style_flags & FT_STYLE_FLAG_BOLD) bold = 1; if (face->style_flags & FT_STYLE_FLAG_ITALIC) italic = 1; + + if (bold) strcat(szfont, " Bold"); + if (italic) strcat(szfont, " Italic"); } - - if (bold) strcat(szFont, " Bold"); - if (italic) strcat(szFont, " Italic"); - if (smallcaps) strcat(szFont, " Smallcaps"); - gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", szFont, file_path); + gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", szfont, file_path); /*try to assign default fixed fonts*/ if (!bold && !italic) { Bool store = 0; - char szFont[1024]; - strcpy(szFont, face->family_name); - strlwr(szFont); + strcpy(szfont, face->family_name); + strlwr(szfont); - if (!strlen(ftpriv->font_fixed)) { + if (!ftpriv->font_fixed) { if (face->face_flags & FT_FACE_FLAG_FIXED_WIDTH) store = 1; else if (!strnicmp(face->family_name, "Courier", 15)) store = 1; - else if (strstr(szFont, "sans") || strstr(szFont, "serif")) store = 0; - else if (strstr(szFont, "monospace")) store = 1; + else if (strstr(szfont, "sans") || strstr(szfont, "serif")) store = 0; + else if (strstr(szfont, "monospace")) store = 1; - if (store) strcpy(ftpriv->font_fixed, face->family_name); + if (store) ftpriv->font_fixed = gf_strdup(face->family_name); } - if (!store && !strlen(ftpriv->font_sans)) { + if (!store && !ftpriv->font_sans) { if (!strnicmp(face->family_name, "Arial", 5)) store = 1; else if (!strnicmp(face->family_name, "Verdana", 7)) store = 1; - else if (strstr(szFont, "serif") || strstr(szFont, "fixed")) store = 0; - else if (strstr(szFont, "sans")) store = 1; + else if (strstr(szfont, "serif") || strstr(szfont, "fixed")) store = 0; + else if (strstr(szfont, "sans")) store = 1; - if (store) strcpy(ftpriv->font_sans, face->family_name); + if (store) ftpriv->font_sans = gf_strdup(face->family_name); } - if (!store && !strlen(ftpriv->font_serif)) { - if (!strnicmp(face->family_name, "Times New Roman", 15)) store = 1; - else if (strstr(szFont, "sans") || strstr(szFont, "fixed")) store = 0; - else if (strstr(szFont, "serif")) store = 1; - if (store) strcpy(ftpriv->font_serif, face->family_name); + if (!strnicmp(face->family_name, "Times New Roman", 15)) { + if (ftpriv->font_serif) gf_free(ftpriv->font_serif); + ftpriv->font_serif = gf_strdup(face->family_name); + } + else if (!store && !ftpriv->font_serif) { + if (!strnicmp(face->family_name, "Times New Roman", 15)) + store = 1; + else if (strstr(szfont, "sans") || strstr(szfont, "fixed")) store = 0; + else if (strstr(szfont, "serif")) store = 1; + + if (store) + ftpriv->font_serif = gf_strdup(face->family_name); } } + gf_free(szfont); } FT_Done_Face(face); @@ -154,8 +165,7 @@ static Bool ft_enum_fonts_dir(void *cbck, char *file_name, char *file_path) static void ft_rescan_fonts(GF_FontReader *dr) { - char *font_dir; - char font_def[1024]; + char *font_dir, *font_default; u32 i, count; GF_Config *cfg = gf_modules_get_config((GF_BaseInterface *)dr); FTBuilder *ftpriv = (FTBuilder *)dr->udta; @@ -176,24 +186,25 @@ static void ft_rescan_fonts(GF_FontReader *dr) } gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "RescanFonts", "no"); - strcpy(ftpriv->font_serif, ""); - strcpy(ftpriv->font_sans, ""); - strcpy(ftpriv->font_fixed, ""); + ftpriv->font_serif = NULL; + ftpriv->font_sans = NULL; + ftpriv->font_fixed = NULL; font_dir = ftpriv->font_dir; - /*here we will store the first font found*/ - font_def[0] = 0; - ftpriv->font_dir = font_def; - + ftpriv->font_dir = NULL; + gf_enum_directory(font_dir, 0, ft_enum_fonts, dr, "ttf;ttc"); gf_enum_directory(font_dir, 1, ft_enum_fonts_dir, dr, NULL); + + font_default = ftpriv->font_dir; ftpriv->font_dir = font_dir; - if ( strlen(font_def) ) { - if (!strlen(ftpriv->font_fixed)) strcpy(ftpriv->font_fixed, font_def); - if (!strlen(ftpriv->font_serif)) strcpy(ftpriv->font_serif, font_def); - if (!strlen(ftpriv->font_sans)) strcpy(ftpriv->font_sans, font_def); - } + if (!ftpriv->font_serif) ftpriv->font_serif = gf_strdup(font_default ? font_default : ""); + if (!ftpriv->font_sans) ftpriv->font_sans = gf_strdup(font_default ? font_default : ""); + if (!ftpriv->font_fixed) ftpriv->font_fixed = gf_strdup(font_default ? font_default : ""); + + if (font_default) gf_free(font_default); + gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontFixed", ftpriv->font_fixed); gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontSerif", ftpriv->font_serif); gf_modules_set_option((GF_BaseInterface *)dr, "FontEngine", "FontSans", ftpriv->font_sans); @@ -218,7 +229,7 @@ static GF_Err ft_init_font_engine(GF_FontReader *dr) } /*remove the final delimiter*/ - ftpriv->font_dir = strdup(sOpt); + ftpriv->font_dir = gf_strdup(sOpt); while ( (ftpriv->font_dir[strlen(ftpriv->font_dir)-1] == '\n') || (ftpriv->font_dir[strlen(ftpriv->font_dir)-1] == '\r') ) ftpriv->font_dir[strlen(ftpriv->font_dir)-1] = 0; @@ -227,10 +238,10 @@ static GF_Err ft_init_font_engine(GF_FontReader *dr) char ext[2], *temp; ext[0] = GF_PATH_SEPARATOR; ext[1] = 0; - temp = malloc(sizeof(char) * (strlen(ftpriv->font_dir) + 2)); + temp = gf_malloc(sizeof(char) * (strlen(ftpriv->font_dir) + 2)); strcpy(temp, ftpriv->font_dir); strcat(temp, ext); - free(ftpriv->font_dir); + gf_free(ftpriv->font_dir); ftpriv->font_dir = temp; } @@ -239,13 +250,13 @@ static GF_Err ft_init_font_engine(GF_FontReader *dr) ft_rescan_fonts(dr); sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", "FontSerif"); - if (sOpt) strcpy(ftpriv->font_serif, sOpt); + ftpriv->font_serif = gf_strdup(sOpt ? sOpt : ""); sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", "FontSans"); - if (sOpt) strcpy(ftpriv->font_sans, sOpt); + ftpriv->font_sans = gf_strdup(sOpt ? sOpt : ""); sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", "FontFixed"); - if (sOpt) strcpy(ftpriv->font_fixed, sOpt); + ftpriv->font_fixed = gf_strdup(sOpt ? sOpt : ""); GF_LOG(GF_LOG_DEBUG, GF_LOG_PARSER, ("[FreeType] Init OK - font directory %s\n", ftpriv->font_dir)); @@ -279,20 +290,20 @@ static Bool ft_check_face(FT_Face font, const char *fontName, u32 styles) if (fontName && stricmp(font->family_name, fontName)) return 0; ft_style = 0; if (font->style_name) { - name = strdup(font->style_name); + name = gf_strdup(font->style_name); strupr(name); if (strstr(name, "BOLD")) ft_style |= GF_FONT_WEIGHT_BOLD; if (strstr(name, "ITALIC")) ft_style |= GF_FONT_ITALIC; - free(name); + gf_free(name); } else { if (font->style_flags & FT_STYLE_FLAG_BOLD) ft_style |= GF_FONT_WEIGHT_BOLD; if (font->style_flags & FT_STYLE_FLAG_ITALIC) ft_style |= GF_FONT_ITALIC; } - name = strdup(font->family_name); + name = gf_strdup(font->family_name); strupr(name); if (strstr(name, "BOLD")) ft_style |= GF_FONT_WEIGHT_BOLD; if (strstr(name, "ITALIC")) ft_style |= GF_FONT_ITALIC; - free(name); + gf_free(name); loc_styles = styles & GF_FONT_WEIGHT_MASK; if (loc_styles>=GF_FONT_WEIGHT_BOLD) @@ -320,7 +331,7 @@ static FT_Face ft_font_in_cache(FTBuilder *ft, const char *fontName, u32 styles) static GF_Err ft_set_font(GF_FontReader *dr, const char *OrigFontName, u32 styles) { - char fname[1024]; + char *fname; char *fontName; const char *opt; FTBuilder *ftpriv = (FTBuilder *)dr->udta; @@ -342,14 +353,16 @@ static GF_Err ft_set_font(GF_FontReader *dr, const char *OrigFontName, u32 style ftpriv->active_face = ft_font_in_cache(ftpriv, fontName, styles); if (ftpriv->active_face) return GF_OK; - /*check cfg file - freetype is slow at loading fonts so we keep the (font name + styles)=fontfile associations + /*check cfg file - gf_free(type is slow at loading fonts so we keep the (font name + styles)=fontfile associations in the cfg file*/ if (!fontName || !strlen(fontName)) return GF_NOT_SUPPORTED; + fname = gf_malloc(sizeof(char) * (strlen(fontName) + 50)); strcpy(fname, fontName); if (styles & GF_FONT_WEIGHT_BOLD) strcat(fname, " Bold"); if (styles & GF_FONT_ITALIC) strcat(fname, " Italic"); opt = gf_modules_get_option((GF_BaseInterface *)dr, "FontEngine", fname); + gf_free(fname); if (opt) { FT_Face face; if (FT_New_Face(ftpriv->library, opt, 0, & face )) return GF_IO_ERR; @@ -359,7 +372,7 @@ static GF_Err ft_set_font(GF_FontReader *dr, const char *OrigFontName, u32 style return GF_OK; } - GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[FreeType] Font %s not found\n", fname)); + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[FreeType] Font %s not found\n", fontName)); return GF_NOT_SUPPORTED; } @@ -373,7 +386,7 @@ static GF_Err ft_get_font_info(GF_FontReader *dr, char **font_name, s32 *em_size *descent = ftpriv->active_face->descender; *underline = ftpriv->active_face->underline_position; *line_spacing = ftpriv->active_face->height; - *font_name = strdup(ftpriv->active_face->family_name); + *font_name = gf_strdup(ftpriv->active_face->family_name); *max_advance_h = ftpriv->active_face->max_advance_width; *max_advance_v = ftpriv->active_face->max_advance_height; return GF_OK; @@ -504,7 +517,7 @@ static GF_Glyph *ft_load_glyph(GF_FontReader *dr, u32 glyph_name) outl.path = glyph->path; outl.ftpriv = ftpriv; - /*freeType is marvelous and gives back the right advance on space char !!!*/ + /*FreeType is marvelous and gives back the right advance on space char !!!*/ FT_Outline_Decompose(&outline->outline, &ft_outl_funcs, &outl); FT_Glyph_Get_CBox((FT_Glyph) outline, ft_glyph_bbox_unscaled, &bbox); @@ -528,11 +541,11 @@ GF_FontReader *ft_load() { GF_FontReader *dr; FTBuilder *ftpriv; - dr = malloc(sizeof(GF_FontReader)); + dr = gf_malloc(sizeof(GF_FontReader)); memset(dr, 0, sizeof(GF_FontReader)); GF_REGISTER_MODULE_INTERFACE(dr, GF_FONT_READER_INTERFACE, "FreeType Font Reader", "gpac distribution"); - ftpriv = malloc(sizeof(FTBuilder)); + ftpriv = gf_malloc(sizeof(FTBuilder)); memset(ftpriv, 0, sizeof(FTBuilder)); ftpriv->loaded_fonts = gf_list_new(); @@ -556,22 +569,28 @@ void ft_delete(GF_BaseInterface *ifce) FTBuilder *ftpriv = dr->udta; - if (ftpriv->font_dir) free(ftpriv->font_dir); + if (ftpriv->font_dir) gf_free(ftpriv->font_dir); + if (ftpriv->font_serif) gf_free(ftpriv->font_serif); + if (ftpriv->font_sans) gf_free(ftpriv->font_sans); + if (ftpriv->font_fixed) gf_free(ftpriv->font_fixed); assert(!gf_list_count(ftpriv->loaded_fonts) ); gf_list_del(ftpriv->loaded_fonts); - free(dr->udta); - free(dr); + gf_free(dr->udta); + gf_free(dr); } #ifndef GPAC_STANDALONE_RENDER_2D GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_FONT_READER_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_FONT_READER_INTERFACE, + 0 + }; + return si; } GF_EXPORT diff --git a/modules/ft_font/ft_font.def b/modules/ft_font/ft_font.def deleted file mode 100644 index 77a3276..0000000 --- a/modules/ft_font/ft_font.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_ft_font.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/gapi/gapi.cpp b/modules/gapi/gapi.cpp index dd9cb8f..dc2967d 100644 --- a/modules/gapi/gapi.cpp +++ b/modules/gapi/gapi.cpp @@ -54,7 +54,7 @@ #endif -static Bool is_landscape = 0; +static Bool landscape = 0; #define PRINT(__str) OutputDebugString(_T(__str)) @@ -71,12 +71,18 @@ static void GAPI_GetCoordinates(DWORD lParam, GF_Event *evt) evt->mouse.x = LOWORD(lParam); evt->mouse.y = HIWORD(lParam); + if (ctx->scale_coords) { + evt->mouse.x = evt->mouse.x * the_video_driver->max_screen_width / ctx->sys_w; + evt->mouse.y = evt->mouse.y * the_video_driver->max_screen_height / ctx->sys_h; + } + + if (ctx->fullscreen) { POINT pt; pt.x = evt->mouse.x; pt.y = evt->mouse.y; ClientToScreen(ctx->hWnd, &pt); - if (is_landscape) { + if (landscape) { evt->mouse.x = ctx->fs_w - pt.y; evt->mouse.y = pt.x; } else { @@ -271,15 +277,15 @@ static void w32_translate_key(u32 wParam, u32 lParam, GF_EventKey *evt) /* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */ default: if ((wParam>=0x30) && (wParam<=0x39)) evt->key_code = GF_KEY_0 + wParam-0x30; - else if ((wParam>=0x41) && (wParam<=0x5A)) evt->key_code = GF_KEY_A + wParam-0x51; + else if ((wParam>=0x41) && (wParam<=0x5A)) evt->key_code = GF_KEY_A + wParam-0x41; else { GAPIPriv *ctx = (GAPIPriv *)the_video_driver->opaque; short res = (LOWORD(wParam) != 0x5b) ? LOWORD(wParam) : wParam; - if (res==ctx->keys.vkLeft) evt->key_code = is_landscape ? GF_KEY_UP : GF_KEY_LEFT; - else if (res==ctx->keys.vkRight) evt->key_code = is_landscape ? GF_KEY_DOWN : GF_KEY_RIGHT; - else if (res==ctx->keys.vkDown) evt->key_code = is_landscape ? GF_KEY_LEFT : GF_KEY_DOWN; - else if (res==ctx->keys.vkUp) evt->key_code = is_landscape ? GF_KEY_RIGHT : GF_KEY_UP; + if (res==ctx->keys.vkLeft) evt->key_code = landscape ? GF_KEY_UP : GF_KEY_LEFT; + else if (res==ctx->keys.vkRight) evt->key_code = landscape ? GF_KEY_DOWN : GF_KEY_RIGHT; + else if (res==ctx->keys.vkDown) evt->key_code = landscape ? GF_KEY_LEFT : GF_KEY_DOWN; + else if (res==ctx->keys.vkUp) evt->key_code = landscape ? GF_KEY_RIGHT : GF_KEY_UP; else if (res==ctx->keys.vkStart) evt->key_code = GF_KEY_ENTER; else if (res==ctx->keys.vkA) evt->key_code = GF_KEY_MEDIAPREVIOUSTRACK; @@ -301,7 +307,7 @@ static void w32_translate_key(u32 wParam, u32 lParam, GF_EventKey *evt) } } - +//#define DIRECT_BITBLT LRESULT APIENTRY GAPI_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam) { @@ -338,14 +344,17 @@ LRESULT APIENTRY GAPI_WindowProc(HWND hWnd, UINT msg, UINT wParam, LONG lParam) the_video_driver->on_event(the_video_driver->evt_cbk_hdl, &evt); break; case WM_PAINT: - { +#ifndef DIRECT_BITBLT + { GAPIPriv *gctx = (GAPIPriv *)the_video_driver->opaque; if (gctx->gx_mode || !gctx->bitmap) break; - BitBlt(gctx->hdc, gctx->dst_blt.x, gctx->dst_blt.y, gctx->bb_width, gctx->bb_height, gctx->hdcBitmap, 0, 0, SRCCOPY); - } + HDC dc = GetDC(gctx->hWnd); + BitBlt(dc, gctx->dst_blt.x, gctx->dst_blt.y, gctx->bb_width, gctx->bb_height, gctx->hdcBitmap, 0, 0, SRCCOPY); + ReleaseDC(gctx->hWnd, dc); + } +#endif break; - case WM_MOUSEMOVE: GAPI_GetCoordinates(lParam, &evt); evt.type = GF_EVENT_MOUSEMOVE; @@ -414,7 +423,9 @@ void GAPI_WindowThread(void *par) void GAPI_SetupWindow(GF_VideoOutput *dr) { +#ifdef GPAC_USE_OGL_ES GF_Err e; +#endif GAPIPriv *ctx = (GAPIPriv *)dr->opaque; if (the_video_driver) return; the_video_driver = dr; @@ -430,6 +441,15 @@ void GAPI_SetupWindow(GF_VideoOutput *dr) SetWindowLong(ctx->hWnd, GWL_WNDPROC, (DWORD) GAPI_WindowProc); } + { + HDC hdc; + hdc = GetDC(ctx->hWnd); + dr->dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); + dr->dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(ctx->hWnd, hdc); + } + + #ifdef GPAC_USE_OGL_ES ctx->use_pbuffer = 1; dr->hw_caps |= GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA; @@ -504,12 +524,17 @@ GF_Err GAPI_Clear(GF_VideoOutput *dr, u32 color) return GF_OK; } + static void createPixmap(GAPIPriv *ctx, u32 pix_type) { const size_t bmiSize = sizeof(BITMAPINFO) + 256U*sizeof(RGBQUAD); BITMAPINFO* bmi; DWORD* p; - bmi = (BITMAPINFO*)malloc(bmiSize); + u32 bpel = 0; + + if (ctx->bmi) gf_free(ctx->bmi); + + bmi = (BITMAPINFO*)gf_malloc(bmiSize); memset(bmi, 0, bmiSize); bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -524,16 +549,18 @@ static void createPixmap(GAPIPriv *ctx, u32 pix_type) switch (ctx->pixel_format) { case GF_PIXEL_RGB_555: p[0] = 0x00007c00; p[1] = 0x000003e0; p[2] = 0x0000001f; + bpel = 16; break; case GF_PIXEL_RGB_565: p[0] = 0x0000f800; p[1] = 0x000007e0; p[2] = 0x0000001f; + bpel = 16; break; case GF_PIXEL_RGB_24: p[0] = 0x00ff0000; p[1] = 0x0000ff00; p[2] = 0x000000ff; + bpel = 24; break; } - - ctx->hdc = GetDC(ctx->hWnd); + ctx->hdc = GetDC(NULL/*ctx->hWnd*/); if (pix_type==2) { #ifdef GPAC_USE_OGL_ES @@ -547,10 +574,14 @@ static void createPixmap(GAPIPriv *ctx, u32 pix_type) ctx->hdcBitmap = CreateCompatibleDC(ctx->hdc); ctx->bitmap = CreateDIBSection(ctx->hdc, bmi, DIB_RGB_COLORS, (void **) &ctx->backbuffer, NULL, 0); ctx->old_bitmap = (HBITMAP) SelectObject(ctx->hdcBitmap, ctx->bitmap); + /*watchout - win32 always create DWORD align memory, so align our pitch*/ while ((ctx->bb_pitch % 4) != 0) ctx->bb_pitch ++; } - free(bmi); + ReleaseDC(NULL/*ctx->hWnd*/, ctx->hdc); + + ctx->bmi = bmi; +// gf_free(bmi); } @@ -741,12 +772,14 @@ GF_Err GAPI_SetupOGL_ES_Offscreen(GF_VideoOutput *dr, u32 width, u32 height) void GAPI_ReleaseObjects(GAPIPriv *ctx) { + ctx->raw_ptr = NULL; + #ifdef GPAC_USE_OGL_ES if (ctx->output_3d_type) GAPI_ReleaseOGL_ES(ctx, 0); else #endif if (ctx->bitmap) DeleteObject(ctx->bitmap); - else if (ctx->backbuffer) free(ctx->backbuffer); + else if (ctx->backbuffer) gf_free(ctx->backbuffer); ctx->backbuffer = NULL; ctx->bitmap = NULL; @@ -756,7 +789,7 @@ void GAPI_ReleaseObjects(GAPIPriv *ctx) DeleteDC(ctx->hdcBitmap); ctx->hdcBitmap = NULL; } - if (ctx->hdc) ReleaseDC(ctx->hWnd, ctx->hdc); + if (ctx->hdc) ReleaseDC(NULL/*ctx->hWnd*/, ctx->hdc); ctx->hdc = NULL; } @@ -796,11 +829,6 @@ GF_Err GAPI_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, Bool no } else { return GF_NOT_SUPPORTED; } - dr->max_screen_width = gctx->screen_w = gx.cxWidth; - dr->max_screen_height = gctx->screen_h = gx.cyHeight; - is_landscape = (gx.ffFormat & kfLandscape) ? 1 : 0; - gctx->x_pitch = gx.cbxPitch; - gctx->y_pitch = gx.cbyPitch; GAPI_SetupWindow(dr); if (!gctx->hWnd) return GF_IO_ERR; @@ -813,6 +841,7 @@ GF_Err GAPI_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, Bool no GetClientRect(gctx->hWnd, &rc); gctx->backup_w = rc.right - rc.left; gctx->backup_h = rc.bottom - rc.top; + return GAPI_InitBackBuffer(dr, gctx->backup_w, gctx->backup_h); } @@ -850,7 +879,7 @@ static GF_Err GAPI_SetFullScreen(GF_VideoOutput *dr, Bool bOn, u32 *outWidth, u3 GXCloseDisplay(); e = GF_OK; if (bOn) { - if (!GXOpenDisplay(GetParent(gctx->hWnd), GX_FULLSCREEN)) { + if (!GXOpenDisplay(GetParent(gctx->hWnd), 0L/*GX_FULLSCREEN*/)) { GXOpenDisplay(gctx->hWnd, 0L); gctx->fullscreen = 0; e = GF_IO_ERR; @@ -862,57 +891,40 @@ static GF_Err GAPI_SetFullScreen(GF_VideoOutput *dr, Bool bOn, u32 *outWidth, u3 gctx->fullscreen = 0; } - is_landscape = 0; + landscape = 0; if (!e) { if (gctx->fullscreen) { gctx->backup_w = *outWidth; gctx->backup_h = *outHeight; - if (is_wide_scene && (gctx->screen_w > gctx->screen_h)) is_landscape = 0; - else if (!is_wide_scene && (gctx->screen_w < gctx->screen_h)) is_landscape = 0; - else is_landscape = 1; + if (is_wide_scene && (gctx->screen_w < gctx->screen_h)) landscape = 1; + else if (!is_wide_scene && (gctx->screen_w > gctx->screen_h)) landscape = 1; + else landscape = 0; - if (is_landscape) { + if (landscape) { gctx->fs_w = gctx->screen_h; gctx->fs_h = gctx->screen_w; } else { gctx->fs_w = gctx->screen_w; gctx->fs_h = gctx->screen_h; } + *outWidth = gctx->fs_w; *outHeight = gctx->fs_h; } else { *outWidth = gctx->backup_w; *outHeight = gctx->backup_h; } - e = GAPI_InitBackBuffer(dr, *outWidth, *outHeight); } gf_mx_v(gctx->mx); return e; } -GF_Err GAPI_ClearFS(GAPIPriv *gctx, unsigned char *ptr, s32 x_pitch, s32 y_pitch) +GF_Err GAPI_ClearFS(GAPIPriv *gctx, unsigned char *ptr) { - s32 i, j; gf_mx_p(gctx->mx); - if (gctx->BPP==3) { - for (i=0; i< (s32)gctx->fs_h; i++) { - unsigned char *_ptr = ptr + i*y_pitch; - for (j=0; j<(s32)gctx->fs_w; j++) { - _ptr[0] = _ptr[1] = _ptr[2] = 0; - _ptr += x_pitch; - } - } - } else { - for (i=0; i<(s32)gctx->fs_h; i++) { - unsigned char *_ptr = ptr + i*y_pitch; - for (j=0; j<(s32)gctx->fs_w; j++) { - * ((unsigned short *)_ptr) = 0; - _ptr += x_pitch; - } - } - } + memset(ptr, 0, sizeof(char) * gctx->screen_w*gctx->screen_h*gctx->BPP); gf_mx_v(gctx->mx); return GF_OK; } @@ -923,76 +935,66 @@ static GF_Err GAPI_FlipBackBuffer(GF_VideoOutput *dr) GF_VideoSurface src, dst; unsigned char *ptr; GAPICTX(dr); - s32 pitch_y = gctx->y_pitch; - s32 pitch_x = gctx->x_pitch; if (!gctx || !gctx->gx_mode) return GF_BAD_PARAM; - gf_mx_p(gctx->mx); - /*get a pointer to video memory*/ - ptr = (unsigned char *) GXBeginDraw(); - if (!ptr) { - gf_mx_v(gctx->mx); - return GF_IO_ERR; + if (gctx->gx_mode==1) { + ptr = (unsigned char *) GXBeginDraw(); + } else { + ptr = (unsigned char *) gctx->raw_ptr; } + if (!ptr) return GF_IO_ERR; src.video_buffer = gctx->backbuffer; src.width = gctx->bb_width; src.height = gctx->bb_height; - src.pitch = gctx->bb_pitch; + src.pitch_x = gctx->BPP; + src.pitch_y = gctx->y_pitch; src.pixel_format = gctx->pixel_format; src.is_hardware_memory = 0; + dst.width = gctx->dst_blt.w; dst.height = gctx->dst_blt.h; dst.pixel_format = gctx->pixel_format; dst.is_hardware_memory = 1; - + dst.video_buffer = (char*)ptr; + dst.pitch_x = gctx->x_pitch; + dst.pitch_y = gctx->y_pitch; if (gctx->fullscreen) { - if (is_landscape) { - if (gctx->y_pitch>0) { - pitch_x = -gctx->y_pitch; - /*start of frame-buffer is top-left corner*/ - if (gctx->x_pitch>0) { - ptr += gctx->screen_h * gctx->y_pitch; - pitch_y = gctx->x_pitch; - } - /*start of frame-buffer is top-right corner*/ - else { - ptr += gctx->screen_h * gctx->y_pitch + gctx->screen_w * gctx->x_pitch; - pitch_y = -gctx->x_pitch; - } - } else { - pitch_x = gctx->y_pitch; - /*start of frame-buffer is bottom-left corner*/ - if (gctx->x_pitch>0) { - pitch_y = gctx->x_pitch; - } - /*start of frame-buffer is bottom-right corner*/ - else { - ptr += gctx->screen_w * gctx->x_pitch; - pitch_y = gctx->x_pitch; - } - } - } if (gctx->erase_dest) { gctx->erase_dest = 0; - GAPI_ClearFS(gctx, ptr, pitch_x, pitch_y); + GAPI_ClearFS(gctx, ptr); } } else { gctx->dst_blt.x += gctx->off_x; gctx->dst_blt.y += gctx->off_y; } - ptr += gctx->dst_blt.x * pitch_x + pitch_y * gctx->dst_blt.y; - dst.video_buffer = (char*)ptr; - dst.pitch = pitch_y; - - gf_stretch_bits(&dst, &src, NULL, NULL, pitch_x, 0xFF, 0, NULL, NULL); + /*apply x/y offset*/ + if (!gctx->fullscreen) + dst.video_buffer += gctx->dst_blt.x * gctx->x_pitch + gctx->y_pitch * gctx->dst_blt.y; + + if (gctx->contiguous_mem) { + memcpy(dst.video_buffer, src.video_buffer, src.width*gctx->BPP*src.height ); + } else if (landscape) { + u32 y, lsize = dst.height*gctx->x_pitch; + for (y=0; y<dst.width; y++) { + char *s = src.video_buffer + y*gctx->y_pitch; + char *d = dst.video_buffer + y*gctx->y_pitch; + memcpy(d, s, lsize); + } + } else { + u32 y, lsize = dst.width*gctx->x_pitch; + for (y=0; y<dst.height; y++) { + char *s = src.video_buffer + y*gctx->y_pitch; + char *d = dst.video_buffer + y*gctx->y_pitch; + memcpy(d, s, lsize); + } + } - GXEndDraw(); - gf_mx_v(gctx->mx); + if (gctx->gx_mode==1) GXEndDraw(); return GF_OK; } @@ -1044,7 +1046,14 @@ static GF_Err GAPI_Flush(GF_VideoOutput *dr, GF_Window *dest) } e = GAPI_FlipBackBuffer(dr); } else { +#ifndef DIRECT_BITBLT InvalidateRect(gctx->hWnd, NULL, gctx->erase_dest); +#else +// BitBlt(gctx->hdc, gctx->dst_blt.x, gctx->dst_blt.y, gctx->bb_width, gctx->bb_height, gctx->hdcBitmap, 0, 0, SRCCOPY); + HDC dc = GetDC(NULL); + BitBlt(dc, gctx->dst_blt.x, gctx->dst_blt.y, gctx->bb_width, gctx->bb_height, gctx->hdcBitmap, 0, 0, SRCCOPY); + ReleaseDC(NULL, dc); +#endif gctx->erase_dest = 0; } } @@ -1087,9 +1096,171 @@ static GF_Err GAPI_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) return GF_OK; } +#if 1 + + + +#define ESC_QUERYESCSUPPORT 8 +#define GETGXINFO 0x00020000 + +typedef struct GXDeviceInfo +{ + long Version; //00 + void * pvFrameBuffer; //04 + unsigned long cbStride; //08 + unsigned long cxWidth; //0c + unsigned long cyHeight; //10 + unsigned long cBPP; //14 + unsigned long ffFormat; //18 + char Unused[0x84-7*4]; +} GXDeviceInfo; + + +static Bool check_resolution_switch(GF_VideoOutput *dr, u32 width, u32 height) +{ + GAPICTX(dr); + + gctx->sys_w = GetSystemMetrics(SM_CXSCREEN); + gctx->sys_h = GetSystemMetrics(SM_CYSCREEN); + gctx->scale_coords = 0; + if (gctx->sys_w != width) gctx->scale_coords = 1; + else if (gctx->sys_h != height) gctx->scale_coords = 1; + + if (gctx->scale_coords) { + gctx->off_x = gctx->off_x * width / gctx->sys_w; + gctx->off_y = gctx->off_y * height / gctx->sys_h; + } + + HDC hdc = GetDC(gctx->hWnd); + dr->dpi_x = (u32) (width * 25.4 / GetDeviceCaps(hdc, HORZSIZE) ); + dr->dpi_y = (u32) (height * 25.4 / GetDeviceCaps(hdc, VERTSIZE) ); + ReleaseDC(gctx->hWnd, hdc); + + if ((gctx->screen_w==width) && (gctx->screen_h==height)) return 0; + + GF_Event evt; + dr->max_screen_width = gctx->screen_w = width; + dr->max_screen_height = gctx->screen_h = height; + + evt.type = GF_EVENT_RESOLUTION; + evt.size.width = dr->max_screen_width; + evt.size.height = dr->max_screen_height; + dr->on_event(the_video_driver->evt_cbk_hdl, &evt); + + return 1; +} + +#ifndef GETRAWFRAMEBUFFER + #define GETRAWFRAMEBUFFER 0x00020001 + typedef struct _RawFrameBufferInfo + { + WORD wFormat; + WORD wBPP; + VOID *pFramePointer; + int cxStride; + int cyStride; + int cxPixels; + int cyPixels; + } RawFrameBufferInfo; + + #define FORMAT_565 1 + #define FORMAT_555 2 + #define FORMAT_OTHER 3 +#endif + +static GF_Err gapi_get_raw_fb(GF_VideoOutput *dr) +{ + long tmp; + RawFrameBufferInfo Info; + GAPICTX(dr); + HDC DC = GetDC(NULL); + memset(&Info,0,sizeof(RawFrameBufferInfo)); + + ExtEscape(DC, GETRAWFRAMEBUFFER, 0, NULL, sizeof(RawFrameBufferInfo), (char*)&Info); + if (!Info.pFramePointer /* && QueryPlatform(PLATFORM_VER) >= 421*/ ) + { + //try gxinfo + DWORD Code = GETGXINFO; + if (ExtEscape(DC, ESC_QUERYESCSUPPORT, sizeof(DWORD), (char*)&Code, 0, NULL) > 0) + { + DWORD DCWidth = GetDeviceCaps(DC,HORZRES); + DWORD DCHeight = GetDeviceCaps(DC,VERTRES); + GXDeviceInfo GXInfo; + memset(&GXInfo,0,sizeof(GXInfo)); + GXInfo.Version = 100; + ExtEscape(DC, GETGXINFO, 0, NULL, sizeof(GXInfo), (char*)&GXInfo); + + // avoid VGA devices (or QVGA smartphones emulating 176x220) + if (GXInfo.cbStride>0 && !(GXInfo.ffFormat & kfLandscape) && + ((DCWidth == GXInfo.cxWidth && DCHeight == GXInfo.cyHeight) || + (DCWidth == GXInfo.cyHeight && DCHeight == GXInfo.cxWidth))) + { + Bool Detect = 0; + int* p = (int*)GXInfo.pvFrameBuffer; + COLORREF Old = GetPixel(DC,0,0); + *p ^= -1; + Detect = GetPixel(DC,0,0) != Old; + *p ^= -1; + + if (Detect) + { + Info.pFramePointer = GXInfo.pvFrameBuffer; + Info.cxPixels = GXInfo.cxWidth; + Info.cyPixels = GXInfo.cyHeight; + Info.cxStride = GXInfo.cBPP/8; + Info.cyStride = GXInfo.cbStride; + Info.wBPP = (WORD)GXInfo.cBPP; + Info.wFormat = (WORD)GXInfo.ffFormat; + } + } + } + } + + ReleaseDC(NULL,DC); + + if (!Info.pFramePointer) return GF_NOT_SUPPORTED; + + gctx->x_pitch = Info.cxStride; + gctx->y_pitch = Info.cyStride; + + if (abs(Info.cyStride) < abs(Info.cxStride)) + { + if (abs(Info.cxStride)*8 < Info.cyPixels*Info.wBPP && + abs(Info.cxStride)*8 >= Info.cxPixels*Info.wBPP) { //swapped resolution + tmp = Info.cxPixels; + Info.cxPixels = Info.cyPixels; + Info.cyPixels = tmp; + } + } + else + { + if (abs(Info.cyStride)*8 < Info.cxPixels*Info.wBPP && + abs(Info.cyStride)*8 >= Info.cyPixels*Info.wBPP) {//swapped resolution + tmp = Info.cxPixels; + Info.cxPixels = Info.cyPixels; + Info.cyPixels = tmp; + } + } + + gctx->raw_ptr = (unsigned char *)Info.pFramePointer; + + if (Info.cxStride<0) + gctx->raw_ptr += (Info.cxStride * (Info.cxPixels-1)); + if (Info.cyStride<0) + gctx->raw_ptr += (Info.cyStride * (Info.cyPixels-1)); + + if (check_resolution_switch(dr, Info.cxPixels, Info.cyPixels)) + return GF_EOS; + + return GF_OK; +} + +#endif + static GF_Err GAPI_InitBackBuffer(GF_VideoOutput *dr, u32 VideoWidth, u32 VideoHeight) { + u32 gx_mode; GAPICTX(dr); if (!gctx || !VideoWidth || !VideoHeight) return GF_BAD_PARAM; @@ -1098,28 +1269,115 @@ static GF_Err GAPI_InitBackBuffer(GF_VideoOutput *dr, u32 VideoWidth, u32 VideoH GAPI_ReleaseObjects(gctx); + /*flip W&H in landscape mode*/ + if (landscape) { + u32 t = VideoWidth; + VideoWidth = VideoHeight; + VideoHeight = t; + } + + RECT rc; + GetWindowRect(gctx->hWnd, &rc); + gctx->off_x = rc.left; + gctx->off_y = rc.top; + gctx->erase_dest = 1; + + const char *opt = gf_modules_get_option((GF_BaseInterface *)dr, "GAPI", "FBAccess"); + if (!opt || !strcmp(opt, "raw")) gx_mode = 2; + else if (opt && !strcmp(opt, "gx")) gx_mode = 1; + else gx_mode = 0; + + if ((gx_mode != gctx->gx_mode) || !gctx->screen_w) { + struct GXDisplayProperties gx = GXGetDisplayProperties(); + + gctx->x_pitch = gx.cbxPitch; + gctx->y_pitch = gx.cbyPitch; + + gctx->gx_mode = gx_mode; + if (gctx->gx_mode==2) { + if (gapi_get_raw_fb(dr) == GF_EOS) { + gf_mx_v(gctx->mx); + return GF_OK; + } + } else if (check_resolution_switch(dr, gx.cxWidth, gx.cyHeight)) { + gf_mx_v(gctx->mx); + return GF_OK; + } + } + if (gctx->gx_mode==2) { + GF_Err e = gapi_get_raw_fb(dr); + if (e) { + gf_mx_v(gctx->mx); + if (e==GF_EOS) return GF_OK; + else return e; + } + } + + gctx->bb_size = VideoWidth * VideoHeight * gctx->BPP; gctx->bb_width = VideoWidth; gctx->bb_height = VideoHeight; gctx->bb_pitch = VideoWidth * gctx->BPP; - if (gctx->force_gx || gctx->fullscreen) { - gctx->backbuffer = (char *) malloc(sizeof(unsigned char) * gctx->bb_size); - gctx->gx_mode = 1; + + if (gctx->gx_mode) { + gctx->backbuffer = (char *) gf_malloc(sizeof(unsigned char) * gctx->bb_size); + + gctx->contiguous_mem = ((gctx->x_pitch==gctx->BPP) && (gctx->y_pitch==gctx->screen_w*gctx->BPP)) ? 1 : 0; } else { createPixmap(gctx, 0); - gctx->gx_mode = 0; } - RECT rc; - GetWindowRect(gctx->hWnd, &rc); - gctx->off_x = rc.left; - gctx->off_y = rc.top; - gctx->erase_dest = 1; - gf_mx_v(gctx->mx); return GF_OK; } + + +static void GAPI_AdjustLandscape(GAPIPriv *gctx, GF_VideoSurface *dst, s32 x_pitch, s32 y_pitch) +{ + if (y_pitch>0) { +#if 1 + dst->pitch_x = -y_pitch; + /*start of frame-buffer is top-left corner*/ + if (x_pitch>0) { + dst->video_buffer += dst->height * y_pitch; + dst->pitch_y = x_pitch; + } + /*start of frame-buffer is top-right corner*/ + else { + dst->video_buffer += dst->height * y_pitch + dst->width * x_pitch; + dst->pitch_y = -x_pitch; + } +#else + dst->pitch_x = y_pitch; + /*start of frame-buffer is top-left corner*/ + if (x_pitch>0) { + dst->video_buffer += y_pitch - x_pitch; + dst->pitch_y = -x_pitch; + } + /*start of frame-buffer is top-right corner*/ + else { + dst->video_buffer += dst->height * y_pitch + dst->width * x_pitch; + dst->pitch_y = -x_pitch; + } +#endif + } else { + dst->pitch_x = y_pitch; + /*start of frame-buffer is bottom-left corner*/ + if (x_pitch>0) { + dst->pitch_y = x_pitch; + } + /*start of frame-buffer is bottom-right corner*/ + else { + dst->video_buffer += dst->width * x_pitch; + dst->pitch_y = x_pitch; + } + } + u32 t = dst->width; + dst->width = dst->height; + dst->height = t; +} + static GF_Err GAPI_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool do_lock) { GAPICTX(dr); @@ -1128,10 +1386,14 @@ static GF_Err GAPI_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool if (!vi) return GF_BAD_PARAM; vi->width = gctx->bb_width; vi->height = gctx->bb_height; - vi->pitch = gctx->bb_pitch; - vi->pixel_format = gctx->pixel_format; vi->video_buffer = gctx->backbuffer; + vi->pixel_format = gctx->pixel_format; vi->is_hardware_memory = 0; + vi->pitch_x = gctx->x_pitch; + vi->pitch_y = gctx->y_pitch; + + if (landscape) + GAPI_AdjustLandscape(gctx, vi, gctx->x_pitch, gctx->y_pitch); } return GF_OK; } @@ -1140,21 +1402,19 @@ static GF_Err GAPI_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool static void *NewGAPIVideoOutput() { GAPIPriv *priv; - GF_VideoOutput *driv = (GF_VideoOutput *) malloc(sizeof(GF_VideoOutput)); + GF_VideoOutput *driv = (GF_VideoOutput *) gf_malloc(sizeof(GF_VideoOutput)); memset(driv, 0, sizeof(GF_VideoOutput)); GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "GAPI Video Output", "gpac distribution") - priv = (GAPIPriv *) malloc(sizeof(GAPIPriv)); + priv = (GAPIPriv *) gf_malloc(sizeof(GAPIPriv)); memset(priv, 0, sizeof(GAPIPriv)); priv->mx = gf_mx_new("GAPI"); driv->opaque = priv; - priv->force_gx = 0; - /*alpha and keying to do*/ - driv->hw_caps = GF_VIDEO_HW_CAN_ROTATE; #ifdef GPAC_USE_OGL_ES - driv->hw_caps = GF_VIDEO_HW_OPENGL; + driv->hw_caps = GF_VIDEO_HW_OPENGL | GF_VIDEO_HW_OPENGL_OFFSCREEN | GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA; #endif + /*rgb, yuv to do*/ driv->Setup = GAPI_Setup; driv->Shutdown = GAPI_Shutdown; @@ -1172,15 +1432,23 @@ static void DeleteVideoOutput(void *ifce) GAPICTX(driv); GAPI_Shutdown(driv); gf_mx_del(gctx->mx); - free(gctx); - free(driv); + gf_free(gctx); + gf_free(driv); } +#ifdef __cplusplus +extern "C" { +#endif + + /*interface query*/ -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + 0 + }; + return si; } /*interface create*/ GF_BaseInterface *LoadInterface(u32 InterfaceType) @@ -1199,3 +1467,8 @@ void ShutdownInterface(GF_BaseInterface *ifce) } } + +#ifdef __cplusplus +} +#endif + diff --git a/modules/gapi/gapi.def b/modules/gapi/gapi.def deleted file mode 100644 index 5cd98c1..0000000 --- a/modules/gapi/gapi.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_gapi.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/gapi/gapi.h b/modules/gapi/gapi.h index 0cd2c36..13bd738 100644 --- a/modules/gapi/gapi.h +++ b/modules/gapi/gapi.h @@ -47,6 +47,9 @@ typedef struct DWORD orig_wnd_proc; GF_Mutex *mx; + unsigned char *raw_ptr; + Bool contiguous_mem; + GXKeyList keys; u32 screen_w, screen_h; @@ -55,8 +58,10 @@ typedef struct u32 backup_w, backup_h; s32 x_pitch, y_pitch; Bool fullscreen; - Bool force_gx; - Bool gx_mode; + u32 gx_mode; + + u32 sys_w, sys_h; + Bool scale_coords; /*main surface info*/ char *backbuffer; @@ -75,7 +80,7 @@ typedef struct HBITMAP bitmap, old_bitmap; DWORD * bits; HDC hdcBitmap, hdc; - + BITMAPINFO* bmi; #ifdef GPAC_USE_OGL_ES u32 output_3d_type; diff --git a/modules/gdip_raster/gdip_font.cpp b/modules/gdip_raster/gdip_font.cpp index e53a350..66902cb 100644 --- a/modules/gdip_raster/gdip_font.cpp +++ b/modules/gdip_raster/gdip_font.cpp @@ -356,22 +356,24 @@ void gdip_delete_font_driver(GF_FontReader *dr) if (ctx->font) GdipDeleteFontFamily(ctx->font); ctx->font = NULL; - free(dr->udta); - free(dr); + gf_free(dr->udta); + gf_free(dr); } +#ifdef __cplusplus +extern "C" { +#endif - -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_FONT_READER_INTERFACE) return 1; - if (InterfaceType == GF_RASTER_2D_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_FONT_READER_INTERFACE, + GF_RASTER_2D_INTERFACE, + 0 + }; + return si; } -GF_Raster2D *gdip_LoadRenderer(); -void gdip_ShutdownRenderer(GF_Raster2D *driver); - GF_BaseInterface *LoadInterface(u32 InterfaceType) { if (InterfaceType==GF_FONT_READER_INTERFACE) return (GF_BaseInterface *)gdip_new_font_driver(); @@ -391,3 +393,6 @@ void ShutdownInterface(GF_BaseInterface *ifce) } } +#ifdef __cplusplus +} +#endif diff --git a/modules/gdip_raster/gdip_grad.cpp b/modules/gdip_raster/gdip_grad.cpp index fefeab0..7ab52fe 100644 --- a/modules/gdip_raster/gdip_grad.cpp +++ b/modules/gdip_raster/gdip_grad.cpp @@ -57,12 +57,12 @@ void gdip_delete_stencil(GF_STENCIL _this) if (_sten->pMat) GdipDeleteMatrix(_sten->pMat); if (_sten->pLinearMat) GdipDeleteMatrix(_sten->pLinearMat); if (_sten->pBitmap) GdipDisposeImage(_sten->pBitmap); - if (_sten->conv_buf) free(_sten->conv_buf); + if (_sten->conv_buf) gf_free(_sten->conv_buf); if (_sten->cols) delete [] _sten->cols; if (_sten->pos) delete [] _sten->pos; - free(_sten); + gf_free(_sten); } static GF_Err gdip_stencil_set_matrix(GF_STENCIL _this, GF_Matrix2D *mat) @@ -403,4 +403,4 @@ void gdip_init_driver_grad(GF_Raster2D *driver) driver->stencil_set_vertex_path = gdip_set_vertex_path; driver->stencil_set_vertex_center = gdip_set_vertex_center; driver->stencil_set_vertex_colors = gdip_set_vertex_colors; -} \ No newline at end of file +} diff --git a/modules/gdip_raster/gdip_priv.h b/modules/gdip_raster/gdip_priv.h index fd973ea..c144cd7 100644 --- a/modules/gdip_raster/gdip_priv.h +++ b/modules/gdip_raster/gdip_priv.h @@ -43,7 +43,7 @@ typedef s16 INT16; typedef u16 UINT16; #endif -#define SAFEALLOC(__ptr, __struc) __ptr = (__struc*)malloc(sizeof(__struc)); if (__ptr) memset(__ptr, 0, sizeof(__struc)); +#define SAFEALLOC(__ptr, __struc) __ptr = (__struc*)gf_malloc(sizeof(__struc)); if (__ptr) memset(__ptr, 0, sizeof(__struc)); /*all GDIPLUS includes for C api*/ @@ -209,5 +209,7 @@ GF_FontReader *gdip_new_font_driver(); void gdip_delete_font_driver(GF_FontReader *dr); +GF_Raster2D *gdip_LoadRenderer(); +void gdip_ShutdownRenderer(GF_Raster2D *driver); #endif //__GDIP_PRIV_H \ No newline at end of file diff --git a/modules/gdip_raster/gdip_rend.cpp b/modules/gdip_raster/gdip_rend.cpp index 20c1ec2..a481f8d 100644 --- a/modules/gdip_raster/gdip_rend.cpp +++ b/modules/gdip_raster/gdip_rend.cpp @@ -142,7 +142,7 @@ static void gdip_delete_surface(GF_SURFACE _this) { GPGRAPH(); - free(_graph); + gf_free(_graph); } /*should give the best results with the clippers*/ @@ -193,37 +193,43 @@ GF_Err gdip_attach_surface_to_texture(GF_SURFACE _this, GF_STENCIL sten) return GF_OK; } static -GF_Err gdip_attach_surface_to_buffer(GF_SURFACE _this, char *pixels, u32 width, u32 height, u32 stride, GF_PixelFormat pixelFormat) +GF_Err gdip_attach_surface_to_buffer(GF_SURFACE _this, char *pixels, u32 width, u32 height, s32 pitch_x, s32 pitch_y, GF_PixelFormat pixelFormat) { GpMatrix *mat; u32 pFormat; GPGRAPH(); - if (stride%4) return GF_NOT_SUPPORTED; + if (pitch_y%4) return GF_NOT_SUPPORTED; switch (pixelFormat) { case GF_PIXEL_ALPHAGREY: pFormat = PixelFormat16bppGrayScale; + if (pitch_x != 2) return GF_NOT_SUPPORTED; break; case GF_PIXEL_RGB_555: pFormat = PixelFormat16bppRGB555; + if (pitch_x != 2) return GF_NOT_SUPPORTED; break; case GF_PIXEL_RGB_565: pFormat = PixelFormat16bppRGB565; + if (pitch_x != 2) return GF_NOT_SUPPORTED; break; case GF_PIXEL_RGB_24: pFormat = PixelFormat24bppRGB; + if (pitch_x != 3) return GF_NOT_SUPPORTED; break; case GF_PIXEL_RGB_32: pFormat = PixelFormat32bppRGB; + if (pitch_x != 4) return GF_NOT_SUPPORTED; break; case GF_PIXEL_ARGB: pFormat = PixelFormat32bppARGB; + if (pitch_x != 4) return GF_NOT_SUPPORTED; break; default: return GF_NOT_SUPPORTED; } - GdipCreateBitmapFromScan0(width, height, stride, pFormat, (unsigned char*)pixels, &_graph->pBitmap); + GdipCreateBitmapFromScan0(width, height, pitch_y, pFormat, (unsigned char*)pixels, &_graph->pBitmap); GdipGetImageGraphicsContext(_graph->pBitmap, &_graph->graph); _graph->w = width; @@ -410,7 +416,11 @@ GF_Err gdip_surface_fill(GF_SURFACE _this, GF_STENCIL stencil) GdipCreateMatrix(&newmat); } /*gdip flip*/ - if (_graph->center_coords) GdipScaleMatrix(newmat, 1, -1, MatrixOrderPrepend); + if (_graph->center_coords && !(_sten->tiling&GF_TEXTURE_FLIP) ) + GdipScaleMatrix(newmat, 1, -1, MatrixOrderPrepend); + else if (!_graph->center_coords && (_sten->tiling&GF_TEXTURE_FLIP) ) + GdipScaleMatrix(newmat, 1, -1, MatrixOrderPrepend); + GdipSetTextureTransform((GpTexture*)_sten->pTexture, newmat); GdipDeleteMatrix(newmat); @@ -494,6 +504,6 @@ void gdip_ShutdownRenderer(GF_Raster2D *driver) struct _gdip_context *ctx = (struct _gdip_context *)driver->internal; GdiplusShutdown(ctx->gdiToken); - free(driver->internal); - free(driver); + gf_free(driver->internal); + gf_free(driver); } diff --git a/modules/gdip_raster/gdip_rend.def b/modules/gdip_raster/gdip_rend.def deleted file mode 100644 index a09ed49..0000000 --- a/modules/gdip_raster/gdip_rend.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_gdip_raster.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/gdip_raster/gdip_texture.cpp b/modules/gdip_raster/gdip_texture.cpp index 91efb38..e0d4b62 100644 --- a/modules/gdip_raster/gdip_texture.cpp +++ b/modules/gdip_raster/gdip_texture.cpp @@ -25,8 +25,8 @@ #include "gdip_priv.h" -#define COL_565(c) ( ( ( (c>>16) & 248) << 8) + ( ( (c>>8) & 252) << 3) + ( (c&0xFF) >> 3) ) -#define COL_555(c) ((( (c>>16) & 248)<<7) + (((c>>8) & 248)<<2) + ((c&0xFF)>>3)) +#define COL_565(c) GF_COL_ARGB(0xFF, (u8) ( (val >> 7) & 0xf8), (u8) ( (val >> 2) & 0xf8), (u8) ( (val << 3) & 0xf8) ) +#define COL_555(c) GF_COL_ARGB(0xFF, (u8) ( (val >> 8) & 0xf8), (u8) ( (val >> 3) & 0xfc), (u8) ( (val << 3) & 0xf8) ) static GF_Err gdip_set_texture(GF_STENCIL _this, char *pixels, u32 width, u32 height, u32 stride, GF_PixelFormat pixelFormat, GF_PixelFormat destination_format_hint, Bool no_copy) @@ -50,7 +50,7 @@ GF_Err gdip_set_texture(GF_STENCIL _this, char *pixels, u32 width, u32 height, u case GF_PIXEL_GREYSCALE: pFormat = PixelFormat24bppRGB; BPP = 1; - /*cannot get it to work without using 24bpp rgb*/ + /*no support for 8bit greyscale not indexed in GDIPlus ...*/ copy = 1; break; case GF_PIXEL_ALPHAGREY: @@ -137,8 +137,8 @@ GF_Err gdip_set_texture(GF_STENCIL _this, char *pixels, u32 width, u32 height, u for (i=0; i<_sten->width; i++) { switch (pixelFormat) { case GF_PIXEL_GREYSCALE: - col = GF_COL_ARGB(255, *ptr, *ptr, *ptr); - ptr ++; + r = *ptr++; + col = GF_COL_ARGB(255, r, r, r); break; case GF_PIXEL_ALPHAGREY: r = *ptr++; @@ -416,23 +416,25 @@ void gdip_convert_texture(struct _stencil *sten) format = PixelFormat32bppARGB; } if (BPP*sten->width*sten->height > sten->conv_size) { - if (sten->conv_buf) free(sten->conv_buf); + if (sten->conv_buf) gf_free(sten->conv_buf); sten->conv_size = BPP*sten->width*sten->height; - sten->conv_buf = (unsigned char *) malloc(sizeof(unsigned char)*sten->conv_size); + sten->conv_buf = (unsigned char *) gf_malloc(sizeof(unsigned char)*sten->conv_size); } src.height = sten->height; src.width = sten->width; - src.pitch = sten->orig_stride; + src.pitch_x =0; + src.pitch_y = sten->orig_stride; src.pixel_format = sten->orig_format; src.video_buffer = (char*)sten->orig_buf; dst.width = sten->width; dst.height = sten->height; - dst.pitch = BPP*sten->width; + dst.pitch_x = 0; + dst.pitch_y = BPP*sten->width; dst.video_buffer = (char*)sten->conv_buf; - gf_stretch_bits(&dst, &src, NULL, NULL, 0, 0xFF, 0, NULL, NULL); + gf_stretch_bits(&dst, &src, NULL, NULL, 0xFF, 0, NULL, NULL); if (sten->pBitmap) GdipDisposeImage(sten->pBitmap); GdipCreateBitmapFromScan0(sten->width, sten->height, BPP*sten->width, format, sten->conv_buf, &sten->pBitmap); diff --git a/modules/gpac_js/Makefile b/modules/gpac_js/Makefile index 31bbdb9..62c34b3 100644 --- a/modules/gpac_js/Makefile +++ b/modules/gpac_js/Makefile @@ -22,11 +22,15 @@ OBJS=gpac_js.o ifeq ($(CONFIG_JS),no) else -CFLAGS+=-DGPAC_HAS_SPIDERMONKEY $(JS_FLAGS) +CFLAGS+=$(JS_FLAGS) ifeq ($(CONFIG_JS),local) NEED_LOCAL_LIB="yes" LOCAL_LIB+=-L../../extra_lib/lib/gcc endif +ifeq ($(CONFIG_JS),prefix) +NEED_LOCAL_LIB="yes" +LOCAL_LIB+=-L$(prefix)/lib +endif LINKLIBS+= $(JS_LIBS) endif @@ -34,20 +38,15 @@ SRCS := $(OBJS:.o=.c) LIB=gm_gpac_js.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols gpac_js.def +#LDFLAGS+=-export-symbols gpac_js.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) %.o: %.c diff --git a/modules/gpac_js/gpac_js.c b/modules/gpac_js/gpac_js.c index 52af12b..0ca6e76 100644 --- a/modules/gpac_js/gpac_js.c +++ b/modules/gpac_js/gpac_js.c @@ -30,6 +30,7 @@ #include <gpac/download.h> #include <gpac/network.h> +#include <gpac/options.h> #include <gpac/xml.h> @@ -84,16 +85,16 @@ static JSBool gpac_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) if (!strcmp(prop_name, "last_working_directory")) { res = gf_cfg_get_key(term->user->config, "General", "LastWorkingDir"); - if (!res) res = ""; + if (!res) res = gf_cfg_get_key(term->user->config, "General", "ModulesDirectory"); *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, res)); return JS_TRUE; } if (!strcmp(prop_name, "scale_x")) { - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->zoom) * FIX2FLT(term->compositor->scale_x)) ); + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->scale_x)) ); return JS_TRUE; } if (!strcmp(prop_name, "scale_y")) { - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->zoom) * FIX2FLT(term->compositor->scale_y)) ); + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->scale_y)) ); return JS_TRUE; } if (!strcmp(prop_name, "translation_x")) { @@ -104,7 +105,62 @@ static JSBool gpac_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(term->compositor->trans_y)) ); return JS_TRUE; } - + if (!strcmp(prop_name, "rectangular_textures")) { + Bool any_size = 0; +#ifndef GPAC_DISABLE_3D + if (term->compositor->gl_caps.npot_texture || term->compositor->gl_caps.rect_texture) + any_size = 1; +#endif + *vp = BOOLEAN_TO_JSVAL( any_size ? JS_TRUE : JS_FALSE ); + return JS_TRUE; + } + if (!strcmp(prop_name, "batteryOn")) { + Bool on_battery = 0; + gf_sys_get_battery_state(&on_battery, NULL, NULL, NULL, NULL); + *vp = BOOLEAN_TO_JSVAL( on_battery ? JS_TRUE : JS_FALSE ); + return JS_TRUE; + } + if (!strcmp(prop_name, "batteryCharging")) { + Bool on_charge = 0; + gf_sys_get_battery_state(NULL, &on_charge, NULL, NULL, NULL); + *vp = BOOLEAN_TO_JSVAL( on_charge ? JS_TRUE : JS_FALSE ); + return JS_TRUE; + } + if (!strcmp(prop_name, "batteryPercent")) { + u32 level = 0; + gf_sys_get_battery_state(NULL, NULL, &level, NULL, NULL); + *vp = INT_TO_JSVAL( level ); + return JS_TRUE; + } + if (!strcmp(prop_name, "batteryLifeTime")) { + u32 level = 0; + gf_sys_get_battery_state(NULL, NULL, NULL, &level, NULL); + *vp = INT_TO_JSVAL( level ); + return JS_TRUE; + } + if (!strcmp(prop_name, "batteryFullLifeTime")) { + u32 level = 0; + gf_sys_get_battery_state(NULL, NULL, NULL, NULL, &level); + *vp = INT_TO_JSVAL( level ); + return JS_TRUE; + } + if (!strcmp(prop_name, "hostname")) { + char hostname[100]; + gf_sk_get_host_name((char*)hostname); + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, hostname)); + return JS_TRUE; + } + if (!strcmp(prop_name, "fullscreen")) { + *vp = BOOLEAN_TO_JSVAL( term->compositor->fullscreen ? JS_TRUE : JS_FALSE); + return JS_TRUE; + } + if (!strcmp(prop_name, "current_path")) { + char *url = gf_url_concatenate(term->root_scene->root_od->net_service->url, ""); + if (!url) url = strdup(""); + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, url)); + free(url); + return JS_TRUE; + } return JS_TRUE; } static JSBool gpac_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) @@ -122,13 +178,28 @@ static JSBool gpac_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) gf_cfg_set_key(term->user->config, "General", "LastWorkingDir", prop_val); return JS_TRUE; } + if (!strcmp(prop_name, "caption")) { + GF_Event evt; + if (!JSVAL_IS_STRING(*vp)) return JS_FALSE; + evt.type = GF_EVENT_SET_CAPTION; + evt.caption.caption = JS_GetStringBytes(JSVAL_TO_STRING(*vp)); + gf_term_user_event(term, &evt); + return JS_TRUE; + } + if (!strcmp(prop_name, "fullscreen")) { + Bool res = (JSVAL_TO_BOOLEAN(*vp)==JS_TRUE) ? 1 : 0; + if (term->compositor->fullscreen != res) { + gf_term_set_option(term, GF_OPT_FULLSCREEN, res); + } + return JS_TRUE; + } return JS_TRUE; } static JSBool gpac_getOption(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - const char *opt; + const char *opt, *sec_name; JSString *js_sec_name, *js_key_name, *s; GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); if (!term) return JS_FALSE; @@ -141,7 +212,14 @@ static JSBool gpac_getOption(JSContext *c, JSObject *obj, uintN argc, jsval *arg if (!JSVAL_IS_STRING(argv[1])) return JSVAL_FALSE; js_key_name = JSVAL_TO_STRING(argv[1]); - opt = gf_cfg_get_key(term->user->config, JS_GetStringBytes(js_sec_name), JS_GetStringBytes(js_key_name)); + sec_name = JS_GetStringBytes(js_sec_name); + if (!stricmp(sec_name, "audiofilters")) { + if (!term->compositor->audio_renderer->filter_chain.enable_filters) return JS_TRUE; + if (!term->compositor->audio_renderer->filter_chain.filters->filter->GetOption) return JS_TRUE; + opt = term->compositor->audio_renderer->filter_chain.filters->filter->GetOption(term->compositor->audio_renderer->filter_chain.filters->filter, JS_GetStringBytes(js_key_name)); + } else { + opt = gf_cfg_get_key(term->user->config, sec_name, JS_GetStringBytes(js_key_name)); + } s = JS_NewStringCopyZ(c, opt ? opt : ""); if (!s) return JS_FALSE; *rval = STRING_TO_JSVAL(s); @@ -150,22 +228,32 @@ static JSBool gpac_getOption(JSContext *c, JSObject *obj, uintN argc, jsval *arg static JSBool gpac_setOption(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - JSString *js_sec_name, *js_key_name, *js_key_val; + char *js_sec_name, *js_key_name, *js_key_val; GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); if (!term) return JS_FALSE; if (argc < 3) return JSVAL_FALSE; if (!JSVAL_IS_STRING(argv[0])) return JSVAL_FALSE; - js_sec_name = JSVAL_TO_STRING(argv[0]); + js_sec_name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); - if (!JSVAL_IS_STRING(argv[1])) return JSVAL_FALSE; - js_key_name = JSVAL_TO_STRING(argv[1]); - if (!JSVAL_IS_STRING(argv[2])) return JSVAL_FALSE; - js_key_val = JSVAL_TO_STRING(argv[2]); + if (!JSVAL_IS_STRING(argv[1])) return JSVAL_FALSE; + js_key_name = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); - gf_cfg_set_key(term->user->config, JS_GetStringBytes(js_sec_name), JS_GetStringBytes(js_key_name), JS_GetStringBytes(js_key_val)); + if (!JSVAL_IS_STRING(argv[2])) return JSVAL_FALSE; + js_key_val = JS_GetStringBytes(JSVAL_TO_STRING(argv[2])); + + if (!stricmp(js_sec_name, "audiofilters")) { + if (!term->compositor->audio_renderer->filter_chain.enable_filters) return JS_TRUE; + if (!term->compositor->audio_renderer->filter_chain.filters->filter->SetOption) return JS_TRUE; + term->compositor->audio_renderer->filter_chain.filters->filter->SetOption(term->compositor->audio_renderer->filter_chain.filters->filter, js_key_name, js_key_val); + } else { + gf_cfg_set_key(term->user->config, js_sec_name, js_key_name, js_key_val); + if (!strcmp(js_sec_name, "Audio") && !strcmp(js_key_name, "Filter")) { + gf_sc_reload_audio_filters(term->compositor); + } + } return JSVAL_TRUE; } @@ -178,6 +266,7 @@ typedef struct static Bool enum_dir_fct(void *cbck, char *file_name, char *file_path) { + u32 i, len; char *sep; JSString *s; jsuint idx; @@ -188,11 +277,23 @@ static Bool enum_dir_fct(void *cbck, char *file_name, char *file_path) obj = JS_NewObject(cbk->c, 0, 0, 0); s = JS_NewStringCopyZ(cbk->c, file_name); JS_DefineProperty(cbk->c, obj, "name", STRING_TO_JSVAL(s), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); - sep = strrchr(file_path, '\\'); - if (!sep) sep = strrchr(file_path, '/'); - if (sep) sep[1] = 0; - s = JS_NewStringCopyZ(cbk->c, file_path); - if (sep) sep[1] = '/'; + + sep=NULL; + len = strlen(file_path); + for (i=0; i<len; i++) { + sep = strchr("/\\", file_path[len-i-1]); + if (sep) { + sep = file_path+len-i-1; + break; + } + } + if (sep) { + sep[0] = '/'; + sep[1] = 0; + s = JS_NewStringCopyZ(cbk->c, file_path); + } else { + s = JS_NewStringCopyZ(cbk->c, file_path); + } JS_DefineProperty(cbk->c, obj, "path", STRING_TO_JSVAL(s), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); JS_DefineProperty(cbk->c, obj, "directory", BOOLEAN_TO_JSVAL(cbk->is_dir ? JS_TRUE : JS_FALSE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); @@ -204,26 +305,78 @@ static Bool enum_dir_fct(void *cbck, char *file_name, char *file_path) static JSBool gpac_enum_directory(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { + GF_Err err; enum_dir_cbk cbk; char *url = NULL; - char *dir = "D:\\"; + char *dir = "D:"; + char *filter = NULL; + Bool dir_only = 0; + Bool browse_root = 0; + if ((argc >= 1) && JSVAL_IS_STRING(argv[0])) { JSString *js_dir = JSVAL_TO_STRING(argv[0]); dir = JS_GetStringBytes(js_dir); + if (!strcmp(dir, "/")) browse_root = 1; } - if ((argc >= 2) && JSVAL_IS_BOOLEAN(argv[1])) { - if (JSVAL_TO_BOOLEAN(argv[1])==JS_TRUE) + if ((argc >= 2) && JSVAL_IS_STRING(argv[1])) { + JSString *js_fil = JSVAL_TO_STRING(argv[1]); + filter = JS_GetStringBytes(js_fil); + if (!strcmp(filter, "dir")) { + dir_only = 1; + filter = NULL; + } else if (!strlen(filter)) filter=NULL; + } + if ((argc >= 3) && JSVAL_IS_BOOLEAN(argv[2])) { + if (JSVAL_TO_BOOLEAN(argv[2])==JS_TRUE) { url = gf_url_concatenate(dir, ".."); + if (!strcmp(url, "..") || (url[0]==0)) { + if ((dir[1]==':') && ((dir[2]=='/') || (dir[2]=='\\')) ) browse_root = 1; + else if (!strcmp(dir, "/")) browse_root = 1; + } + } + } + + if (!strlen(dir) && (!url || !strlen(url))) browse_root = 1; + + if (browse_root) { + cbk.c = c; + cbk.array = JS_NewArrayObject(c, 0, 0); + cbk.is_dir = 1; + gf_enum_directory("/", 1, enum_dir_fct, &cbk, NULL); + *rval = OBJECT_TO_JSVAL(cbk.array); + if (url) gf_free(url); + return JS_TRUE; } + cbk.c = c; cbk.array = JS_NewArrayObject(c, 0, 0); cbk.is_dir = 1; - gf_enum_directory(url ? url : dir, 1, enum_dir_fct, &cbk, NULL); - cbk.is_dir = 0; - gf_enum_directory(url ? url : dir, 0, enum_dir_fct, &cbk, NULL); + err = gf_enum_directory(url ? url : dir, 1, enum_dir_fct, &cbk, NULL); + if (err==GF_IO_ERR) { + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + /*try to concatenate with service url*/ + char *an_url = gf_url_concatenate(term->root_scene->root_od->net_service->url, url ? url : dir); + gf_free(url); + url = an_url; + gf_enum_directory(url ? url : dir, 1, enum_dir_fct, &cbk, NULL); + } + + if (!dir_only) { + cbk.is_dir = 0; + err = gf_enum_directory(url ? url : dir, 0, enum_dir_fct, &cbk, filter); + if (dir_only && (err==GF_IO_ERR)) { + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + /*try to concatenate with service url*/ + char *an_url = gf_url_concatenate(term->root_scene->root_od->net_service->url, url ? url : dir); + gf_free(url); + url = an_url; + gf_enum_directory(url ? url : dir, 0, enum_dir_fct, &cbk, filter); + } + } + *rval = OBJECT_TO_JSVAL(cbk.array); - if (url) free(url); + if (url) gf_free(url); return JS_TRUE; } @@ -248,17 +401,122 @@ static JSBool gpac_set_size(JSContext *c, JSObject *obj, uintN argc, jsval *argv override_size_info = 1; if (w && h) { + GF_Event evt; if (override_size_info) { term->compositor->scene_width = w; term->compositor->scene_height = h; term->compositor->has_size_info = 1; } - gf_term_set_size(term, w, h); + if (term->user->os_window_handler) { + evt.type = GF_EVENT_SCENE_SIZE; + evt.size.width = w; + evt.size.height = h; + gf_term_send_event(term, &evt); + } else { + gf_sc_set_size(term->compositor, w, h); + } + } else if (override_size_info) { + term->compositor->has_size_info = 0; + term->compositor->recompute_ar = 1; + } + + return JS_TRUE; +} + +static JSBool gpac_get_horizontal_dpi(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + if (term) *rval = INT_TO_JSVAL(term->compositor->video_out->dpi_x); + return JS_TRUE; +} + +static JSBool gpac_get_vertical_dpi(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + if (term) *rval = INT_TO_JSVAL(term->compositor->video_out->dpi_y); + return JS_TRUE; +} + +static JSBool gpac_get_screen_width(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + *rval = INT_TO_JSVAL(term->compositor->video_out->max_screen_width); + return JS_TRUE; +} + +static JSBool gpac_get_screen_height(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + *rval = INT_TO_JSVAL(term->compositor->video_out->max_screen_height); + return JS_TRUE; +} + +static JSBool gpac_exit(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_Event evt; + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + evt.type = GF_EVENT_QUIT; + gf_term_send_event(term, &evt); + return JS_TRUE; +} + +static JSBool gpac_set_3d(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 type_3d = 0; + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + if (argc && JSVAL_IS_INT(argv[0])) type_3d = JSVAL_TO_INT(argv[0]); + if (term->compositor->inherit_type_3d != type_3d) { + term->compositor->inherit_type_3d = type_3d; + term->compositor->root_visual_setup = 0; + term->compositor->reset_graphics = 1; } + return JS_TRUE; +} + +static JSBool gpac_get_scene_time(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_SceneGraph *sg = NULL; + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + if (!argc || !JSVAL_IS_OBJECT(argv[0])) { + sg = term->root_scene->graph; + } else { + GF_Node *n = gf_sg_js_get_node(c, JSVAL_TO_OBJECT(argv[0])); + sg = n ? n->sgprivate->scenegraph : term->root_scene->graph; + } + *rval = DOUBLE_TO_JSVAL( JS_NewDouble(c, sg->GetSceneTime(sg->userpriv) ) ); return JS_TRUE; } +static JSBool gpac_migrate_url(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *url; + u32 i, count; + GF_NetworkCommand com; + GF_Terminal *term = (GF_Terminal *)JS_GetPrivate(c, obj); + if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_FALSE; + + url = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (!url) return JS_FALSE; + + count = gf_list_count(term->root_scene->resources); + for (i=0; i<count; i++) { + GF_ObjectManager *odm = gf_list_get(term->root_scene->resources, i); + if (!odm->net_service) continue; + if (!strstr(url, odm->net_service->url)) continue; + + memset(&com, 0, sizeof(GF_NetworkCommand)); + com.base.command_type = GF_NET_SERVICE_MIGRATION_INFO; + odm->net_service->ifce->ServiceCommand(odm->net_service->ifce, &com); + if (com.migrate.data) { + *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(c, com.migrate.data)); + } else { + *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(c, odm->net_service->url)); + } + break; + } + return JS_TRUE; +} static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext *c, JSObject *global, Bool unload) { @@ -267,14 +525,22 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext GF_JSAPIParam par; JSPropertySpec gpacClassProps[] = { - {0} + {0, 0, 0, 0, 0} }; JSFunctionSpec gpacClassFuncs[] = { - {"getOption", gpac_getOption, 3}, - {"setOption", gpac_setOption, 4}, - {"enum_directory", gpac_enum_directory, 1}, - {"set_size", gpac_set_size, 1}, - {0} + {"getOption", gpac_getOption, 3, 0, 0}, + {"setOption", gpac_setOption, 4, 0, 0}, + {"enum_directory", gpac_enum_directory, 1, 0, 0}, + {"set_size", gpac_set_size, 1, 0, 0}, + {"get_horizontal_dpi", gpac_get_horizontal_dpi, 0, 0, 0}, + {"get_vertical_dpi", gpac_get_vertical_dpi, 0, 0, 0}, + {"get_screen_width", gpac_get_screen_width, 0, 0, 0}, + {"get_screen_height", gpac_get_screen_height, 0, 0, 0}, + {"exit", gpac_exit, 0, 0, 0}, + {"set_3d", gpac_set_3d, 1, 0, 0}, + {"get_scene_time", gpac_get_scene_time, 1, 0, 0}, + {"migrate_url", gpac_migrate_url, 1, 0, 0}, + {0, 0, 0, 0, 0} }; /*nothing to do on unload*/ @@ -297,11 +563,6 @@ static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext } -#else -static void gjs_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext *c, JSObject *global, Bool unload) -{ -} -#endif @@ -309,7 +570,7 @@ GF_JSUserExtension *gjs_new() { GF_JSUserExtension *dr; GF_GPACJSExt *gjs; - dr = malloc(sizeof(GF_JSUserExtension)); + dr = gf_malloc(sizeof(GF_JSUserExtension)); memset(dr, 0, sizeof(GF_JSUserExtension)); GF_REGISTER_MODULE_INTERFACE(dr, GF_JS_USER_EXT_INTERFACE, "GPAC JavaScript Bindings", "gpac distribution"); @@ -324,21 +585,31 @@ void gjs_delete(GF_BaseInterface *ifce) { GF_JSUserExtension *dr = (GF_JSUserExtension *) ifce; GF_GPACJSExt *gjs = dr->udta; - free(gjs); - free(dr); + gf_free(gjs); + gf_free(dr); } +#endif + + GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_JS_USER_EXT_INTERFACE) return 1; - return 0; + static u32 si [] = { +#ifdef GPAC_HAS_SPIDERMONKEY + GF_JS_USER_EXT_INTERFACE, +#endif + 0 + }; + return si; } GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { +#ifdef GPAC_HAS_SPIDERMONKEY if (InterfaceType == GF_JS_USER_EXT_INTERFACE) return (GF_BaseInterface *)gjs_new(); +#endif return NULL; } @@ -346,8 +617,10 @@ GF_EXPORT void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#ifdef GPAC_HAS_SPIDERMONKEY case GF_JS_USER_EXT_INTERFACE: gjs_delete(ifce); break; +#endif } } diff --git a/modules/gpac_js/gpac_js.def b/modules/gpac_js/gpac_js.def deleted file mode 100644 index e339a08..0000000 --- a/modules/gpac_js/gpac_js.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_gpac_js.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/img_in/Makefile b/modules/img_in/Makefile index 107b90c..4af8368 100644 --- a/modules/img_in/Makefile +++ b/modules/img_in/Makefile @@ -16,7 +16,11 @@ endif NEED_LOCAL_LIB="no" LOCAL_LIB=../../bin/gcc +ifneq ($(STATICBUILD),yes) LINKLIBS= -lgpac +else +LINKLIBS= -lgpac_static +endif #common objects OBJS=img_dec.o img_in.o bmp_dec.o png_dec.o jpeg_dec.o @@ -47,20 +51,17 @@ SRCS := $(OBJS:.o=.c) LIB=gm_img_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) LINKLIBS+=-lwinmm -LDFLAGS+=-export-symbols img_in.def -endif - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) +#LDFLAGS+=-export-symbols img_in.def endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_img_in-static.so $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) +endif %.o: %.c diff --git a/modules/img_in/bmp_dec.c b/modules/img_in/bmp_dec.c index 52f7cd3..6dc1e21 100644 --- a/modules/img_in/bmp_dec.c +++ b/modules/img_in/bmp_dec.c @@ -184,7 +184,7 @@ static const char *BMP_GetCodecName(GF_BaseDecoder *dec) Bool NewBMPDec(GF_BaseDecoder *ifcd) { IMGDec *wrap = (IMGDec *) ifcd->privateStack; - BMPDec *dec = (BMPDec *) malloc(sizeof(BMPDec)); + BMPDec *dec = (BMPDec *) gf_malloc(sizeof(BMPDec)); memset(dec, 0, sizeof(BMPDec)); wrap->opaque = dec; wrap->type = DEC_BMP; @@ -202,5 +202,5 @@ Bool NewBMPDec(GF_BaseDecoder *ifcd) void DeleteBMPDec(GF_BaseDecoder *ifcg) { BMPCTX(); - free(ctx); + gf_free(ctx); } diff --git a/modules/img_in/img_dec.c b/modules/img_in/img_dec.c index 8493ca0..4fa0443 100644 --- a/modules/img_in/img_dec.c +++ b/modules/img_in/img_dec.c @@ -31,10 +31,17 @@ static Bool DEC_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, u32 ObjectT if (StreamType != GF_STREAM_VISUAL) return 0; switch (ObjectType) { - case 0x6D: return NewPNGDec(dec); - case 0x6C: return NewJPEGDec(dec); +#ifdef GPAC_HAS_PNG + case GPAC_OTI_IMAGE_PNG: + return NewPNGDec(dec); +#endif +#ifdef GPAC_HAS_JPEG + case GPAC_OTI_IMAGE_JPEG: + return NewJPEGDec(dec); +#endif #ifdef GPAC_HAS_JP2 - case 0x6E: return NewJP2Dec(dec); + case GPAC_OTI_IMAGE_JPEG_2000: + return NewJP2Dec(dec); #endif case GPAC_BMP_OTI: return NewBMPDec(dec); @@ -59,7 +66,7 @@ GF_BaseDecoder *NewBaseDecoder() if (!ifce) return NULL; GF_SAFEALLOC(wrap, IMGDec); if (!wrap) { - free(ifce); + gf_free(ifce); return NULL; } ifce->privateStack = wrap; @@ -92,21 +99,19 @@ void DeleteBaseDecoder(GF_BaseDecoder *ifcd) default: break; } - free(wrap); - free(ifcd); + gf_free(wrap); + gf_free(ifcd); } GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_MEDIA_DECODER_INTERFACE: - return 1; - case GF_NET_CLIENT_INTERFACE: - return 1; - default: - return 0; - } + static u32 si [] = { + GF_MEDIA_DECODER_INTERFACE, + GF_NET_CLIENT_INTERFACE, + 0 + }; + return si; } GF_EXPORT diff --git a/modules/img_in/img_in.c b/modules/img_in/img_in.c index 135db35..fea9a5a 100644 --- a/modules/img_in/img_in.c +++ b/modules/img_in/img_in.c @@ -30,6 +30,8 @@ enum IMG_JPEG = 1, IMG_PNG, IMG_BMP, + IMG_PNGD, + IMG_PNGDS, }; typedef struct @@ -72,6 +74,17 @@ GF_ESD *IMG_GetESD(IMGLoader *read) gf_img_parse(bs, &OTI, &mtype, &w, &h, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); esd->decoderConfig->objectTypeIndication = OTI; gf_bs_del(bs); + + if (read->img_type == IMG_PNGD) { + GF_Descriptor *d = gf_odf_desc_new(GF_ODF_AUX_VIDEO_DATA); + ((GF_AuxVideoDescriptor*)d)->aux_video_type = 1; + gf_list_add(esd->extensionDescriptors, d); + } + else if (read->img_type == IMG_PNGDS) { + GF_Descriptor *d = gf_odf_desc_new(GF_ODF_AUX_VIDEO_DATA); + ((GF_AuxVideoDescriptor*)d)->aux_video_type = 2; + gf_list_add(esd->extensionDescriptors, d); + } } return esd; } @@ -85,6 +98,8 @@ static Bool IMG_CanHandleURL(GF_InputService *plug, const char *url) if (gf_term_check_extension(plug, "image/jp2", "jp2", "JPEG2000 Images", sExt)) return 1; if (gf_term_check_extension(plug, "image/png", "png", "PNG Images", sExt)) return 1; if (gf_term_check_extension(plug, "image/bmp", "bmp", "MS Bitmap Images", sExt)) return 1; + if (gf_term_check_extension(plug, "image/x-png+depth", "pngd", "PNG+Depth Images", sExt)) return 1; + if (gf_term_check_extension(plug, "image/x-png+depth+mask", "pngds", "PNG+Depth+Mask Images", sExt)) return 1; return 0; } @@ -160,6 +175,8 @@ static GF_Err IMG_ConnectService(GF_InputService *plug, GF_ClientService *serv, sExt = strrchr(url, '.'); if (!stricmp(sExt, ".jpeg") || !stricmp(sExt, ".jpg")) read->img_type = IMG_JPEG; else if (!stricmp(sExt, ".png")) read->img_type = IMG_PNG; + else if (!stricmp(sExt, ".pngd")) read->img_type = IMG_PNGD; + else if (!stricmp(sExt, ".pngds")) read->img_type = IMG_PNGDS; else if (!stricmp(sExt, ".bmp")) read->img_type = IMG_BMP; if (read->dnload) gf_term_download_del(read->dnload); @@ -304,8 +321,8 @@ static GF_Err IMG_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, cha } *is_new_data = 1; fseek(read->stream, 0, SEEK_SET); - read->data = (char*) malloc(sizeof(char) * (read->data_size + read->pad_bytes)); - fread(read->data, sizeof(char) * read->data_size, 1, read->stream); + read->data = (char*) gf_malloc(sizeof(char) * (read->data_size + read->pad_bytes)); + read->data_size = fread(read->data, sizeof(char), read->data_size, read->stream); fseek(read->stream, 0, SEEK_SET); if (read->pad_bytes) memset(read->data + read->data_size, 0, sizeof(char) * read->pad_bytes); @@ -323,7 +340,7 @@ static GF_Err IMG_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) if (read->ch == channel) { if (!read->data) return GF_BAD_PARAM; - free(read->data); + gf_free(read->data); read->data = NULL; read->done = 1; return GF_OK; @@ -359,6 +376,6 @@ void DeleteLoaderInterface(void *ifce) { GF_InputService *plug = (GF_InputService *) ifce; IMGLoader *read = (IMGLoader *)plug->priv; - free(read); - free(plug); + gf_free(read); + gf_free(plug); } diff --git a/modules/img_in/img_in.def b/modules/img_in/img_in.def deleted file mode 100644 index 5ba5100..0000000 --- a/modules/img_in/img_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_img_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/img_in/jp2_dec.c b/modules/img_in/jp2_dec.c index d5bc0ca..9d39c02 100644 --- a/modules/img_in/jp2_dec.c +++ b/modules/img_in/jp2_dec.c @@ -44,7 +44,7 @@ static GF_Err JP2_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) JP2CTX(); if (esd->dependsOnESID || esd->decoderConfig->upstream) return GF_NOT_SUPPORTED; - if (esd->decoderConfig->objectTypeIndication==0x6E) { + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_JPEG_2000) { bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); ctx->height = gf_bs_read_u32(bs); ctx->width = gf_bs_read_u32(bs); @@ -220,13 +220,13 @@ static GF_Err JP2_ProcessData(GF_MediaDecoder *ifcg, if (ctx->dsi) { char *data; - data = malloc(sizeof(char) * (ctx->dsi_size+inBufferLength)); + data = gf_malloc(sizeof(char) * (ctx->dsi_size+inBufferLength)); memcpy(data, ctx->dsi, ctx->dsi_size); memcpy(data+ctx->dsi_size, inBuffer, inBufferLength); cio = opj_cio_open((opj_common_ptr)dinfo, data, ctx->dsi_size+inBufferLength); /* decode the stream and fill the image structure */ image = opj_decode(dinfo, cio); - free(data); + gf_free(data); } else { cio = opj_cio_open((opj_common_ptr)dinfo, inBuffer, inBufferLength); /* decode the stream and fill the image structure */ @@ -328,12 +328,12 @@ static GF_Err JP2_ProcessData(GF_MediaDecoder *ifcg, } } - /* free remaining structures */ + /* gf_free( remaining structures */ if(dinfo) { opj_destroy_decompress(dinfo); } - /* free image data structure */ + /* gf_free( image data structure */ opj_image_destroy(image); *outBufferLength = ctx->out_size; @@ -349,7 +349,7 @@ static const char *JP2_GetCodecName(GF_BaseDecoder *dec) Bool NewJP2Dec(GF_BaseDecoder *ifcd) { IMGDec *wrap = (IMGDec *) ifcd->privateStack; - JP2Dec *dec = (JP2Dec *) malloc(sizeof(JP2Dec)); + JP2Dec *dec = (JP2Dec *) gf_malloc(sizeof(JP2Dec)); memset(dec, 0, sizeof(JP2Dec)); wrap->opaque = dec; wrap->type = DEC_JPEG; @@ -367,7 +367,7 @@ Bool NewJP2Dec(GF_BaseDecoder *ifcd) void DeleteJP2Dec(GF_BaseDecoder *ifcg) { JP2CTX(); - free(ctx); + gf_free(ctx); } #endif diff --git a/modules/img_in/jpeg_dec.c b/modules/img_in/jpeg_dec.c index 59d976c..3676913 100644 --- a/modules/img_in/jpeg_dec.c +++ b/modules/img_in/jpeg_dec.c @@ -122,7 +122,7 @@ static const char *JPEG_GetCodecName(GF_BaseDecoder *dec) Bool NewJPEGDec(GF_BaseDecoder *ifcd) { IMGDec *wrap = (IMGDec *) ifcd->privateStack; - JPEGDec *dec = (JPEGDec *) malloc(sizeof(JPEGDec)); + JPEGDec *dec = (JPEGDec *) gf_malloc(sizeof(JPEGDec)); memset(dec, 0, sizeof(JPEGDec)); wrap->opaque = dec; wrap->type = DEC_JPEG; @@ -140,5 +140,5 @@ Bool NewJPEGDec(GF_BaseDecoder *ifcd) void DeleteJPEGDec(GF_BaseDecoder *ifcg) { JPEGCTX(); - free(ctx); + gf_free(ctx); } diff --git a/modules/img_in/png_dec.c b/modules/img_in/png_dec.c index e22ca11..fdf20d9 100644 --- a/modules/img_in/png_dec.c +++ b/modules/img_in/png_dec.c @@ -30,7 +30,7 @@ typedef struct { u16 ES_ID; u32 BPP, width, height, out_size, pixel_format; - Bool is_depth; + u32 aux_type; } PNGDec; #define PNGCTX() PNGDec *ctx = (PNGDec *) ((IMGDec *)ifcg->privateStack)->opaque @@ -46,7 +46,7 @@ static GF_Err PNG_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) while ((d = gf_list_enum(esd->extensionDescriptors, &i))) { if (d->tag == GF_ODF_AUX_VIDEO_DATA) { - ctx->is_depth = 1; + ctx->aux_type = ((GF_AuxVideoDescriptor*)d)->aux_video_type; break; } } @@ -123,7 +123,8 @@ static GF_Err PNG_ProcessData(GF_MediaDecoder *ifcg, case GF_PIXEL_RGBA: case GF_PIXEL_RGBD: ctx->BPP = 4; - if (ctx->is_depth) ctx->pixel_format = GF_PIXEL_RGBD; + if (ctx->aux_type==1) ctx->pixel_format = GF_PIXEL_RGBD; + else if (ctx->aux_type==2) ctx->pixel_format = GF_PIXEL_RGBDS; break; } ctx->out_size = *outBufferLength; @@ -138,7 +139,7 @@ static const char *PNG_GetCodecName(GF_BaseDecoder *dec) Bool NewPNGDec(GF_BaseDecoder *ifcd) { IMGDec *wrap = (IMGDec *) ifcd->privateStack; - PNGDec *dec = (PNGDec *) malloc(sizeof(PNGDec)); + PNGDec *dec = (PNGDec *) gf_malloc(sizeof(PNGDec)); memset(dec, 0, sizeof(PNGDec)); wrap->opaque = dec; wrap->type = DEC_PNG; @@ -156,5 +157,5 @@ Bool NewPNGDec(GF_BaseDecoder *ifcd) void DeletePNGDec(GF_BaseDecoder *ifcg) { PNGCTX(); - free(ctx); + gf_free(ctx); } diff --git a/modules/ismacryp/Makefile b/modules/ismacryp/Makefile index da5c6fd..c4b2131 100644 --- a/modules/ismacryp/Makefile +++ b/modules/ismacryp/Makefile @@ -21,20 +21,17 @@ SRCS := $(OBJS:.o=.c) LIB=gm_ismacryp.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols ismacryp.def -endif - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) +#LDFLAGS+=-export-symbols ismacryp.def endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_ismacryp-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/ismacryp/ismacryp.c b/modules/ismacryp/ismacryp.c index fea7d12..12ec5a9 100644 --- a/modules/ismacryp/ismacryp.c +++ b/modules/ismacryp/ismacryp.c @@ -30,6 +30,7 @@ #include <gpac/download.h> #include <gpac/internal/terminal_dev.h> +#ifndef GPAC_DISABLE_MCRYPT #define OMA_DRM_MP4MC @@ -68,7 +69,7 @@ static GF_Err ISMA_GetGPAC_KMS(ISMAEAPriv *priv, GF_Channel *ch, const char *kms e = GF_OK; /*try local*/ - t = (strstr(kms_url, "://") == NULL) ? fopen(kms_url, "r") : NULL; + t = (strstr(kms_url, "://") == NULL) ? gf_f64_open(kms_url, "r") : NULL; if (t) { fclose(t); return gf_ismacryp_gpac_get_info(ch->esd->ESID, (char *)kms_url, priv->key, priv->salt); @@ -302,8 +303,8 @@ void DeleteISMACrypTool(GF_IPMPTool *plug) ISMAEAPriv *priv = (ISMAEAPriv *)plug->udta; /*in case something went wrong*/ if (priv->crypt) gf_crypt_close(priv->crypt); - free(priv); - free(plug); + gf_free(priv); + gf_free(plug); } GF_IPMPTool *NewISMACrypTool() @@ -320,23 +321,28 @@ GF_IPMPTool *NewISMACrypTool() return (GF_IPMPTool *) tmp; } +#endif /*GPAC_DISABLE_MCRYPT*/ + GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_IPMP_TOOL_INTERFACE: - return 1; - default: - return 0; - } + static u32 si [] = { +#ifndef GPAC_DISABLE_MCRYPT + GF_IPMP_TOOL_INTERFACE, +#endif + 0 + }; + return si; } GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { switch (InterfaceType) { +#ifndef GPAC_DISABLE_MCRYPT case GF_IPMP_TOOL_INTERFACE: return (GF_BaseInterface *)NewISMACrypTool(); +#endif default: return NULL; } @@ -346,8 +352,10 @@ GF_EXPORT void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_MCRYPT case GF_IPMP_TOOL_INTERFACE: DeleteISMACrypTool((GF_IPMPTool *)ifce); break; +#endif } } diff --git a/modules/ismacryp/ismacryp.def b/modules/ismacryp/ismacryp.def deleted file mode 100644 index e6966dc..0000000 --- a/modules/ismacryp/ismacryp.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_ismacryp.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/isom_in/Makefile b/modules/isom_in/Makefile index 20690da..058daea 100644 --- a/modules/isom_in/Makefile +++ b/modules/isom_in/Makefile @@ -21,20 +21,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_isom_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols isom_in.def +#LDFLAGS+=-export-symbols isom_in.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) -L../../bin/gcc -lgpac $(EXTRALIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_isom_in-static.so $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) +endif %.o: %.c diff --git a/modules/isom_in/cache.c b/modules/isom_in/cache.c index aefebfa..714ca8e 100644 --- a/modules/isom_in/cache.c +++ b/modules/isom_in/cache.c @@ -24,7 +24,7 @@ #include "isom_in.h" -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE static GF_Err ISOW_Open(GF_StreamingCache *mc, GF_ClientService *serv, const char *location_and_name, Bool keep_existing_files) { @@ -38,13 +38,13 @@ static GF_Err ISOW_Open(GF_StreamingCache *mc, GF_ClientService *serv, const cha strcpy(szPath, szRoot); strcat(szPath, ".mp4"); if (keep_existing_files) { - FILE *f = fopen(szPath, "rb"); + FILE *f = gf_f64_open(szPath, "rb"); if (f) { u32 i=0; fclose(f); while (1) { sprintf(szPath, "%s_%04d.mp4", szRoot, i); - f = fopen(szPath, "rb"); + f = gf_f64_open(szPath, "rb"); if (!f) break; fclose(f); i++; @@ -72,7 +72,7 @@ static GF_Err ISOW_Close(GF_StreamingCache *mc, Bool delete_cache) gf_isom_add_sample(cache->mov, ch->track, 1, ch->cache_sample); gf_isom_sample_del(&ch->cache_sample); } - free(ch); + gf_free(ch); } if (delete_cache) { gf_isom_delete(cache->mov); @@ -158,7 +158,7 @@ static GF_Err ISOW_Write(GF_StreamingCache *mc, LPNETCHANNEL ch, char *data, u32 mch->cache_sample = gf_isom_sample_new(); mch->cache_sample->IsRAP = sl_hdr->randomAccessPointFlag; mch->cache_sample->dataLength = data_size; - mch->cache_sample->data = (char*)malloc(sizeof(char)*data_size); + mch->cache_sample->data = (char*)gf_malloc(sizeof(char)*data_size); memcpy(mch->cache_sample->data, data, sizeof(char)*data_size); return GF_OK; } @@ -207,7 +207,7 @@ static GF_Err ISOW_Write(GF_StreamingCache *mc, LPNETCHANNEL ch, char *data, u32 mch->cache_sample->DTS = DTS + mch->frame_cts_offset; mch->cache_sample->CTS_Offset = (u32) (sl_hdr->compositionTimeStamp - mch->cache_seed_ts - DTS); mch->cache_sample->dataLength = data_size; - mch->cache_sample->data = (char*)malloc(sizeof(char)*data_size); + mch->cache_sample->data = (char*)gf_malloc(sizeof(char)*data_size); memcpy(mch->cache_sample->data, data, sizeof(char)*data_size); return GF_OK; } @@ -259,9 +259,9 @@ void isow_delete_cache(GF_BaseInterface *bi) GF_StreamingCache *mc = (GF_StreamingCache*) bi; ISOMReader *cache = (ISOMReader *)mc->priv; gf_list_del(cache->channels); - free(cache); - free(bi); + gf_free(cache); + gf_free(bi); } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ diff --git a/modules/isom_in/isom_in.def b/modules/isom_in/isom_in.def deleted file mode 100644 index cdff88c..0000000 --- a/modules/isom_in/isom_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_isom_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/isom_in/isom_in.h b/modules/isom_in/isom_in.h index 50c0575..539647c 100644 --- a/modules/isom_in/isom_in.h +++ b/modules/isom_in/isom_in.h @@ -26,10 +26,12 @@ #ifndef _ISMO_IN_H_ #define _ISMO_IN_H_ -#include <gpac/modules/service.h> -#include <gpac/media_tools.h> #include <gpac/constants.h> +#include <gpac/modules/service.h> + +#ifndef GPAC_DISABLE_ISOM +#include <gpac/media_tools.h> /* reader module @@ -37,6 +39,7 @@ typedef struct { + GF_InputService *input; /*the service we're responsible for*/ GF_ClientService *service; @@ -53,6 +56,9 @@ typedef struct Bool no_service_desc; u32 base_track_id; + + /*0: not fragmented - 1 fragmented - 2 fragmented and last fragment received*/ + u32 frag_type; } ISOMReader; @@ -63,6 +69,7 @@ typedef struct ISOMReader *owner; u64 duration; + Bool wait_for_segment_switch; /*current sample*/ GF_ISOSample *sample; @@ -106,11 +113,12 @@ void isor_emulate_chapters(GF_ISOFile *file, GF_InitialObjectDescriptor *iod); void isor_declare_objects(ISOMReader *read); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_BaseInterface *isow_load_cache(); void isow_delete_cache(GF_BaseInterface *bi); #endif +#endif /*GPAC_DISABLE_ISOM*/ -#endif +#endif /*_ISMO_IN_H_*/ diff --git a/modules/isom_in/load.c b/modules/isom_in/load.c index 72ace59..eb9d3f1 100644 --- a/modules/isom_in/load.c +++ b/modules/isom_in/load.c @@ -24,6 +24,8 @@ #include "isom_in.h" +#ifndef GPAC_DISABLE_ISOM + void isor_emulate_chapters(GF_ISOFile *file, GF_InitialObjectDescriptor *iod) { GF_Segment *prev_seg; @@ -43,7 +45,7 @@ void isor_emulate_chapters(GF_ISOFile *file, GF_InitialObjectDescriptor *iod) seg = (GF_Segment *) gf_odf_desc_new(GF_ODF_SEGMENT_TAG); seg->startTime = (Double) (s64) start; seg->startTime /= 1000; - seg->SegmentName = strdup(name); + seg->SegmentName = gf_strdup(name); gf_list_add(iod->OCIDescriptors, seg); if (prev_seg) { prev_seg->Duration = (Double) (s64) (start - prev_start); @@ -96,6 +98,7 @@ void isor_declare_objects(ISOMReader *read) case GF_ISOM_MEDIA_AUDIO: case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: case GF_ISOM_MEDIA_SCENE: case GF_ISOM_MEDIA_SUBPIC: break; @@ -126,13 +129,13 @@ void isor_declare_objects(ISOMReader *read) } else { sprintf(szName, "%s%s_cover.%s", cdir, sep, (tlen & 0x80000000) ? "png" : "jpg"); } - t = fopen(szName, "wb"); + t = gf_f64_open(szName, "wb"); if (t) { fwrite(tag, tlen & 0x7FFFFFFF, 1, t); fclose(t); od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); od->objectDescriptorID = 1050; - od->URLString = strdup(szName); + od->URLString = gf_strdup(szName); gf_term_add_media(read->service, (GF_Descriptor*)od, 1); } } @@ -140,24 +143,32 @@ void isor_declare_objects(ISOMReader *read) gf_term_add_media(read->service, NULL, 0); } +#endif /*GPAC_DISABLE_ISOM*/ + GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_NET_CLIENT_INTERFACE) return 1; -#ifndef GPAC_READ_ONLY - if (InterfaceType == GF_STREAMING_MEDIA_CACHE) return 1; + static u32 si [] = { +#ifndef GPAC_DISABLE_ISOM + GF_NET_CLIENT_INTERFACE, +#endif +#ifndef GPAC_DISABLE_ISOM_WRITE + GF_STREAMING_MEDIA_CACHE, #endif - return 0; + 0 + }; + return si; } GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { +#ifndef GPAC_DISABLE_ISOM if (InterfaceType == GF_NET_CLIENT_INTERFACE) return (GF_BaseInterface *)isor_client_load(); - -#ifndef GPAC_READ_ONLY +#endif +#ifndef GPAC_DISABLE_ISOM_WRITE if (InterfaceType == GF_STREAMING_MEDIA_CACHE) return (GF_BaseInterface *)isow_load_cache(); #endif @@ -168,8 +179,10 @@ GF_EXPORT void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_ISOM case GF_NET_CLIENT_INTERFACE: isor_client_del(ifce); break; -#ifndef GPAC_READ_ONLY +#endif +#ifndef GPAC_DISABLE_ISOM_WRITE case GF_STREAMING_MEDIA_CACHE: isow_delete_cache(ifce); break; #endif } diff --git a/modules/isom_in/read.c b/modules/isom_in/read.c index 16a6321..64f385f 100644 --- a/modules/isom_in/read.c +++ b/modules/isom_in/read.c @@ -23,6 +23,9 @@ */ #include "isom_in.h" + +#ifndef GPAC_DISABLE_ISOM + #include <gpac/ismacryp.h> ISOMChannel *isor_get_channel(ISOMReader *reader, LPNETCHANNEL channel) @@ -42,7 +45,7 @@ static void isor_delete_channel(ISOMReader *reader, ISOMChannel *ch) while ((ch2 = (ISOMChannel *)gf_list_enum(reader->channels, &i))) { if (ch2 == ch) { isor_reset_reader(ch); - free(ch); + gf_free(ch); gf_list_rem(reader->channels, i-1); return; } @@ -151,6 +154,7 @@ void isor_net_io(void *cbk, GF_NETIO_Parameter *param) gf_term_on_connect(read->service, NULL, e); return; } + read->frag_type = gf_isom_is_fragmented(read->mov) ? 1 : 0; /*ok let's go*/ read->time_scale = gf_isom_get_timescale(read->mov); @@ -177,6 +181,7 @@ GF_Err ISOR_ConnectService(GF_InputService *plug, GF_ClientService *serv, const if (!plug || !plug->priv || !serv) return GF_SERVICE_ERROR; read = (ISOMReader *) plug->priv; + read->input = plug; read->service = serv; if (read->dnload) gf_term_download_del(read->dnload); @@ -198,11 +203,14 @@ GF_Err ISOR_ConnectService(GF_InputService *plug, GF_ClientService *serv, const } if (isor_is_local(szURL)) { - if (!read->mov) read->mov = gf_isom_open(szURL, GF_ISOM_OPEN_READ, NULL); +// if (!read->mov) read->mov = gf_isom_open(szURL, GF_ISOM_OPEN_READ, NULL); + GF_Err e = gf_isom_open_progressive(szURL, &read->mov, &read->missing_bytes); if (!read->mov) { gf_term_on_connect(serv, NULL, gf_isom_last_error(NULL)); return GF_OK; } + read->frag_type = gf_isom_is_fragmented(read->mov) ? 1 : 0; + read->time_scale = gf_isom_get_timescale(read->mov); /*reply to user*/ gf_term_on_connect(serv, NULL, GF_OK); @@ -692,7 +700,6 @@ GF_Err ISOR_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) } return GF_NOT_SUPPORTED; } - if (!com->base.on_channel) return GF_NOT_SUPPORTED; ch = isor_get_channel(read, com->base.on_channel); @@ -831,6 +838,8 @@ void isor_client_del(GF_BaseInterface *bi) ISOMReader *read = (ISOMReader *)plug->priv; gf_list_del(read->channels); - free(read); - free(bi); + gf_free(read); + gf_free(bi); } + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/modules/isom_in/read_ch.c b/modules/isom_in/read_ch.c index bb443cb..f2e15fc 100644 --- a/modules/isom_in/read_ch.c +++ b/modules/isom_in/read_ch.c @@ -25,6 +25,8 @@ #include "isom_in.h" +#ifndef GPAC_DISABLE_ISOM + void isor_reset_reader(ISOMChannel *ch) { @@ -67,6 +69,7 @@ static void init_reader(ISOMChannel *ch) } else { ch->last_state = gf_isom_get_sample_for_movie_time(ch->owner->mov, ch->track, ch->start, &ivar, GF_ISOM_SEARCH_SYNC_BACKWARD, &ch->sample, &ch->sample_num); } + ch->last_state = GF_OK; if (ch->has_rap && ch->has_edit_list) { ch->edit_sync_frame = ch->sample_num; @@ -85,7 +88,7 @@ static void init_reader(ISOMChannel *ch) } ch->last_state = GF_ISOM_INCOMPLETE_FILE; } else if (ch->sample_num) { - ch->last_state = GF_EOS; + ch->last_state = (ch->owner->frag_type==1) ? GF_OK : GF_EOS; } } else { ch->sample_time = ch->sample->DTS; @@ -97,6 +100,38 @@ static void init_reader(ISOMChannel *ch) } +static void check_segment_switch(ISOMReader *read) +{ + GF_NetworkCommand param; + u32 i, count; + if (!read->frag_type) return; + if (!read->input->query_proxy) return; + + count = gf_list_count(read->channels); + for (i=0; i<count; i++) { + ISOMChannel *ch = gf_list_get(read->channels, i); + /*check all playing channels are waiting for next segment*/ + if (ch->is_playing && !ch->wait_for_segment_switch) return; + } + /*close current segment*/ + gf_isom_release_segment(read->mov, 1); + + /*update current fragment if any*/ + param.command_type = GF_NET_SERVICE_QUERY_NEXT; + if ((read->input->query_proxy(read->input, ¶m)==GF_OK) && param.url_query.next_url){ + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("\nSegment switch detected - now playing %s\n", param.url_query.next_url)); + gf_isom_open_segment(read->mov, param.url_query.next_url); + + for (i=0; i<count; i++) { + ISOMChannel *ch = gf_list_get(read->channels, i); + ch->wait_for_segment_switch = 0; + } + } else { + /*consider we are done*/ + read->frag_type = 2; + } +} + void isor_reader_get_sample(ISOMChannel *ch) { GF_Err e; @@ -125,11 +160,22 @@ void isor_reader_get_sample(ISOMChannel *ch) /*we jumped to another segment - if RAP is needed look for closest rap in decoding order and force seek mode*/ if (ch->sample && !ch->sample->IsRAP && ch->has_rap && (ch->sample_num != prev_sample+1)) { - gf_isom_sample_del(&ch->sample); + GF_ISOSample *found = ch->sample; + u32 samp_num = ch->sample_num; + ch->sample = NULL; e = gf_isom_get_sample_for_movie_time(ch->owner->mov, ch->track, ch->sample_time + 1, &ivar, GF_ISOM_SEARCH_SYNC_BACKWARD, &ch->sample, &ch->sample_num); - ch->edit_sync_frame = ch->sample_num; - ch->sample->DTS = ch->sample_time; - ch->sample->CTS_Offset = 0; + /*if no sync point in the past, use the first non-sync for the given time*/ + if (!ch->sample || !ch->sample->data) { + gf_isom_sample_del(&ch->sample); + ch->sample = found; + ch->sample_time = ch->sample->DTS; + ch->sample_num = samp_num; + } else { + gf_isom_sample_del(&found); + ch->edit_sync_frame = ch->sample_num; + ch->sample->DTS = ch->sample_time; + ch->sample->CTS_Offset = 0; + } } else { if (ch->sample) ch->sample_time = ch->sample->DTS; } @@ -145,6 +191,10 @@ fetch_next: ch->sample_num++; goto fetch_next; } + /*if sample cannot be found and file is fragmented, rewind sample*/ + if (!ch->sample && ch->owner->frag_type) { + ch->sample_num--; + } } if (!ch->sample) { /*incomplete file - check if we're still downloading or not*/ @@ -156,9 +206,15 @@ fetch_next: } else { ch->last_state = GF_ISOM_INCOMPLETE_FILE; } - } else if (!ch->sample_num || (ch->sample_num > gf_isom_get_sample_count(ch->owner->mov, ch->track))) { - ch->last_state = GF_EOS; + } else if (!ch->sample_num || (ch->sample_num >= gf_isom_get_sample_count(ch->owner->mov, ch->track))) { + if (ch->owner->frag_type==1) { + ch->last_state = GF_OK; + ch->wait_for_segment_switch = 1; + } else { + ch->last_state = GF_EOS; + } } + if (ch->wait_for_segment_switch) check_segment_switch(ch->owner); return; } ch->last_state = GF_OK; @@ -184,7 +240,7 @@ fetch_next: if (ch->is_encrypted) { GF_ISMASample *ismasamp = gf_isom_get_ismacryp_sample(ch->owner->mov, ch->track, ch->sample, 1); if (ismasamp) { - free(ch->sample->data); + gf_free(ch->sample->data); ch->sample->data = ismasamp->data; ch->sample->dataLength = ismasamp->dataLength; ismasamp->data = NULL; @@ -208,3 +264,4 @@ void isor_reader_release_sample(ISOMChannel *ch) +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/modules/jack/Makefile b/modules/jack/Makefile index d25d9eb..8459d3e 100644 --- a/modules/jack/Makefile +++ b/modules/jack/Makefile @@ -20,19 +20,12 @@ OBJS= jack.o SRCS := $(OBJS:.o=.c) -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif - - LIB=gm_jack.$(DYN_LIB_SUFFIX) all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac -L/usr/lib -ljack +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -L/usr/lib -ljack %.o: %.c diff --git a/modules/jack/jack.c b/modules/jack/jack.c index d6872cd..0d92b7b 100644 --- a/modules/jack/jack.c +++ b/modules/jack/jack.c @@ -99,7 +99,7 @@ Jack_cleanup (JackContext * ctx) } if (ctx->buffer != NULL) { - free (ctx->buffer); + gf_free(ctx->buffer); ctx->bufferSz = 0; ctx->buffer = NULL; } @@ -111,7 +111,7 @@ Jack_cleanup (JackContext * ctx) jack_port_unregister (ctx->jack, ctx->jackPorts[channels]); ctx->jackPorts[channels] = NULL; } - free (ctx->jackPorts); + gf_free(ctx->jackPorts); ctx->jackPorts = NULL; } if (ctx->jack != NULL) @@ -120,7 +120,7 @@ Jack_cleanup (JackContext * ctx) } if (ctx->channels != NULL) { - free (ctx->channels); + gf_free(ctx->channels); ctx->channels = NULL; } ctx->numChannels = 0; @@ -197,10 +197,9 @@ onBufferSizeChanged (jack_nframes_t nframes, void *arg) if (ctx->buffer != NULL && ctx->bufferSz == realBuffSize) return 0; if (ctx->channels != NULL) - free (ctx->channels); + gf_free(ctx->channels); ctx->channels = NULL; - ctx->channels = - calloc (ctx->numChannels, sizeof (jack_default_audio_sample_t *)); + ctx->channels = gf_calloc (ctx->numChannels, sizeof (jack_default_audio_sample_t *)); if (ctx->channels == NULL) { Jack_cleanup (ctx); @@ -218,8 +217,8 @@ onBufferSizeChanged (jack_nframes_t nframes, void *arg) } if (ctx->buffer != NULL) - free (ctx->buffer); - ctx->buffer = calloc (realBuffSize, sizeof (char)); + gf_free(ctx->buffer); + ctx->buffer = gf_calloc (realBuffSize, sizeof (char)); if (ctx->buffer == NULL) { Jack_cleanup (ctx); @@ -356,7 +355,7 @@ Jack_ConfigureOutput (GF_AudioOutput * dr, u32 * SampleRate, u32 * NbChannels, ("[Jack] Jack_ConfigureOutput channels=%d, srate=%d bits/sample=%d\n", *NbChannels, *SampleRate, *nbBitsPerSample)); if (ctx->jackPorts == NULL) - ctx->jackPorts = calloc (ctx->numChannels, sizeof (jack_port_t *)); + ctx->jackPorts = gf_calloc (ctx->numChannels, sizeof (jack_port_t *)); if (ctx->jackPorts == NULL) { goto exit_cleanup; @@ -498,7 +497,7 @@ NewJackOutput () GF_SAFEALLOC (driv, GF_AudioOutput); if (!driv) { - free (ctx); + gf_free(ctx); return NULL; } driv->opaque = ctx; @@ -536,9 +535,9 @@ DeleteJackOutput (void *ifce) GF_AudioOutput *dr = (GF_AudioOutput *) ifce; JackContext *ctx = (JackContext *) dr->opaque; Jack_cleanup (ctx); - free (ctx); + gf_free(ctx); dr->opaque = NULL; - free (dr); + gf_free(dr); } /* @@ -546,12 +545,13 @@ DeleteJackOutput (void *ifce) * interface */ -Bool -QueryInterface (u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) - return 1; - return 0; + static u32 si [] = { + GF_AUDIO_OUTPUT_INTERFACE, + 0 + }; + return si; } GF_BaseInterface * diff --git a/modules/laser_dec/Makefile b/modules/laser_dec/Makefile index 947ec3c..a25d0ab 100644 --- a/modules/laser_dec/Makefile +++ b/modules/laser_dec/Makefile @@ -21,20 +21,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_laser_dec.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols laser_dec.def +#LDFLAGS+=-export-symbols laser_dec.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_laser_dec-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/laser_dec/laser_dec.c b/modules/laser_dec/laser_dec.c index a6de80a..c3931e4 100644 --- a/modules/laser_dec/laser_dec.c +++ b/modules/laser_dec/laser_dec.c @@ -27,11 +27,11 @@ #include <gpac/laser.h> #include <gpac/constants.h> -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER typedef struct { - GF_InlineScene *pScene; + GF_Scene *pScene; GF_Terminal *app; GF_LASeRCodec *codec; u32 PL, nb_streams; @@ -50,7 +50,7 @@ static GF_Err LSR_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapability return GF_OK; } -GF_Err LSR_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder) +GF_Err LSR_AttachScene(GF_SceneDecoder *plug, GF_Scene *scene, Bool is_scene_decoder) { LSRPriv *priv = (LSRPriv *)plug->privateStack; if (priv->codec) return GF_BAD_PARAM; @@ -59,7 +59,7 @@ GF_Err LSR_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_sce priv->codec = gf_laser_decoder_new(scene->graph); /*attach the clock*/ - gf_laser_decoder_set_clock(priv->codec, gf_inline_get_time, scene); + gf_laser_decoder_set_clock(priv->codec, gf_scene_get_time, scene); return GF_OK; } @@ -101,7 +101,7 @@ static GF_Err LSR_ProcessData(GF_SceneDecoder*plug, char *inBuffer, u32 inBuffer e = gf_laser_decode_au(priv->codec, ES_ID, inBuffer, inBufferLength); /*if scene not attached do it*/ - gf_inline_attach_to_compositor(priv->pScene); + gf_scene_attach_to_compositor(priv->pScene); return e; } @@ -117,8 +117,8 @@ void DeleteLSRDec(GF_BaseDecoder *plug) LSRPriv *priv = (LSRPriv *)plug->privateStack; /*in case something went wrong*/ if (priv->codec) gf_laser_decoder_del(priv->codec); - free(priv); - free(plug); + gf_free(priv); + gf_free(plug); } GF_BaseDecoder *NewLSRDec() @@ -143,23 +143,29 @@ GF_BaseDecoder *NewLSRDec() return (GF_BaseDecoder *) tmp; } +#endif + + GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_SCENE_DECODER_INTERFACE: - return 1; - default: - return 0; - } + static u32 si [] = { +#ifndef GPAC_DISABLE_LASER + GF_SCENE_DECODER_INTERFACE, +#endif + 0 + }; + return si; } GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { switch (InterfaceType) { +#ifndef GPAC_DISABLE_LASER case GF_SCENE_DECODER_INTERFACE: return (GF_BaseInterface *)NewLSRDec(); +#endif default: return NULL; } @@ -169,28 +175,11 @@ GF_EXPORT void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_LASER case GF_SCENE_DECODER_INTERFACE: DeleteLSRDec((GF_BaseDecoder *)ifce); break; +#endif } } -#else - -GF_EXPORT -Bool QueryInterface(u32 InterfaceType) -{ - return 0; -} - -GF_EXPORT -GF_BaseInterface *LoadInterface(u32 InterfaceType) -{ - return NULL; -} - -GF_EXPORT -void ShutdownInterface(GF_BaseInterface *ifce) -{ -} -#endif diff --git a/modules/laser_dec/laser_dec.def b/modules/laser_dec/laser_dec.def deleted file mode 100644 index 3ea674b..0000000 --- a/modules/laser_dec/laser_dec.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_laser_dec.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/m3u8_in/Makefile b/modules/m3u8_in/Makefile new file mode 100644 index 0000000..1aced0a --- /dev/null +++ b/modules/m3u8_in/Makefile @@ -0,0 +1,73 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/m3u8_in + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include -g -Wall -pedantic + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +#common obj +OBJS= m3u8_in.o m3u8_in_load.o playlist.o m3u8_parser.o + +SRCS := $(OBJS:.o=.c) + +NEED_LOCAL_LIB="no" +LOCAL_LIB=../../bin/gcc +LINKLIBS= -lgpac + +ifeq ($(CONFIG_OGG), local) +NEED_LOCAL_LIB="yes" +endif + + +#add local lib path +ifeq ($(NEED_LOCAL_LIB), "yes") +LOCAL_LIB+=-L../../extra_lib/lib/gcc +endif + + +LIB=gm_m3u8_in.$(DYN_LIB_SUFFIX) +ifeq ($(CONFIG_WIN32),yes) +#LDFLAGS+=-export-symbols m3u8_in.def +endif + + +all: $(LIB) + + +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + +tests: all test.o + $(CC) $(LDFLAGS) -o test $(OBJS) test.o $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) && ./test +clean: + rm -f $(OBJS) test test.o ../../bin/gcc/$(LIB) + +dep: depend + +depend: + rm -f .depend + GS) + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/m3u8_in/m3u8_in.c b/modules/m3u8_in/m3u8_in.c new file mode 100644 index 0000000..3d71f62 --- /dev/null +++ b/modules/m3u8_in/m3u8_in.c @@ -0,0 +1,500 @@ +/** + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * 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. + * Written by Pierre Souchay for VizionR SAS + * + */ + +#include <gpac/modules/service.h> +#include <gpac/internal/terminal_dev.h> +#include <gpac/thread.h> +#include <gpac/network.h> +#include "m3u8_in.h" +#include <gpac/list.h> +#include "m3u8_parser.h" + +#define MYLOG(xx) GF_LOG( GF_LOG_INFO, GF_LOG_NETWORK, xx ) + + +typedef struct s_M3UREADER +{ + GF_ClientService *service; + char * rootURL; + GF_DownloadSession * dnload; + char is_remote; + char needs_connection; + VariantPlaylist * playlist; + u32 preferredBitrate; + + PlaylistElement *ple; + + /* Service really managing the media */ + GF_InputService *media_ifce; + GF_Thread *dl_thread; + +} M3U8Reader; + + +static Bool M3U8_CanHandleURL(GF_InputService *plug, const char *url) +{ + char *sExt; + MYLOG(("***** M3U8_CanHandleURL %s\n", url)); + sExt = strrchr(url, '.'); + if (!sExt) return 0; + if (gf_term_check_extension(plug, "application/vnd.apple.mpegurl", "m3u8", "M3U8 Playlist", sExt)) + return 1; + if (gf_term_check_extension(plug, "application/x-mpegURL", "m3u8", "M3U8 Playlist", sExt)) + return 1; + if (gf_term_check_extension(plug, "text/plain", "m3u8", "M3U8 Playlist", sExt)) + return 1; + return 0; +} + +static Bool m3u8_is_local(const char *url) +{ + if (!strnicmp(url, "file://", 7)) return 1; + if (strstr(url, "://")) return 0; + return 1; +} + + +PlaylistElement * findNextPlaylistElementToPlay(M3U8Reader *read){ + VariantPlaylist * pl; + Program * p; + PlaylistElement * toPlay; + assert( read ); + assert( read->playlist); + pl = read->playlist; + p = variant_playlist_get_current_program(pl); + if (p == NULL) + return NULL; + toPlay = gf_list_get( p->bitrates, 0); + if (toPlay == NULL) + return NULL; + switch (toPlay->elementType){ + case TYPE_PLAYLIST: + return gf_list_get(toPlay->element.playlist.elements, 0); + case TYPE_UNKNOWN: + /* We have to download the file ! */ + case TYPE_STREAM: + default: + return toPlay; + } + +} + + +GF_Err M3U8_parseM3U8File(M3U8Reader * read){ + const char * szCache; + GF_Err e; + MYLOG(("***** M3U8_parseM3U8File\n")); + szCache = gf_dm_sess_get_cache_name(read->dnload); + if (!szCache){ + e = GF_CORRUPTED_DATA; + goto end; + } + + e = parse_root_playlist(szCache, & (read->playlist), read->rootURL); + if (e){ + MYLOG(("***** Failed to parse root playlist : %s\n", szCache)); + } else { + PlaylistElement * element = findNextPlaylistElementToPlay(read); + if (element != NULL){ + MYLOG(("FOUND Program : %s\n", element->url)); + playlist_element_dump( element, 2 ); + } + } +end: + gf_term_on_connect(read->service, NULL, e); + gf_term_download_del(read->dnload); + read->dnload = NULL; + return e; +} + +void M3U8_NetIO(void *cbk, GF_NETIO_Parameter *param) +{ + M3U8Reader *read = (M3U8Reader *) cbk; + MYLOG(("***** M3U8_NetIO %d\n", param->msg_type)); + gf_term_download_update_stats(read->dnload); + +} + +void M3U8_DownloadFile(GF_InputService *plug, const char *url) +{ + GF_Err e; + M3U8Reader *read = (M3U8Reader*) plug->priv; + MYLOG(("***** M3U8_DownloadFile %s\n", url)); + read->dnload = gf_term_download_new(read->service, url, GF_NETIO_SESSION_NOT_THREADED, M3U8_NetIO, read); + if (!read->dnload) { + MYLOG(("***** M3U8_DownloadFile FAILED\n")); + gf_term_on_connect(read->service, NULL, GF_NOT_SUPPORTED); + } + /* do the actual download (because not threaded )*/ + e = gf_dm_sess_process(read->dnload); + if (e!=GF_OK) { + gf_term_on_connect(read->service, NULL, GF_IO_ERR); + } +} + +static u32 download_media_files(void *par) +{ + GF_Err e; + M3U8Reader *read = (M3U8Reader*) par; + + /* + while (1) { + period = gf_list_get(mpdin->mpd.periods, mpdin->active_period_index); + rep = &period->representations[mpdin->active_rep_index]; + new_seg_url = rep->segment_urls[mpdin->active_segment_index]; + if (rep->default_base_url) { + new_base_seg_url = gf_url_concatenate(rep->default_base_url, new_seg_url); + } else { + new_base_seg_url = gf_strdup(new_seg_url); + } + + gf_dm_setup_from_url(read->dnload, new_base_seg_url); + gf_dm_sess_dash_reset(read->dnload); + fprintf(stderr, "Downloading new media file: %s\n", new_base_seg_url); + gf_free(new_base_seg_url); + + e = gf_dm_sess_process(read->dnload); + if (e == GF_OK) { + //signal the slave service the segment has been downloaded + if (read->dnload) { + } +// if (mpdin->active_segment_index<10) { + if (mpdin->active_segment_index<(rep->nb_segments-1)) { + mpdin->active_segment_index++; + } else { + break; + } + } else { + break; + } + gf_sleep(1000); + } + */ + gf_sleep(1000); + return 0; +} + +static GF_Err M3U8_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) +{ + char szURL[2048]; + GF_Err e; + FILE * f; + M3U8Reader *read = plug->priv; + MYLOG(("***** M3U8_ConnectService %s\n", url)); + if (read->rootURL){ + gf_free(read->rootURL); + read->rootURL = NULL; + } + assert( url ); + read->rootURL = strdup(url); + read->service = serv; + + if (read->dnload) gf_term_download_del(read->dnload); + read->dnload = NULL; + + /*read->service_type = 0;*/ + strcpy(szURL, url); + + /*remote fetch*/ + read->is_remote = !m3u8_is_local(szURL); + if (read->is_remote) { + MYLOG(("***** M3U8_ConnectService Remote %s\n", url)); + read->needs_connection = 1; + M3U8_DownloadFile(plug, szURL); + } else { + MYLOG(("***** M3U8_ConnectService local %s\n", url)); + f = fopen(szURL, "rb"); + if (!f) { + e = GF_URL_ERROR; + } else { + e = GF_OK; + } + } + e = M3U8_parseM3U8File( read ); + if (e){ + MYLOG(("***** Error while reading playlist %d\n", e)); + gf_term_on_connect(read->service, NULL, e); + return GF_OK; + } else { + read->ple = findNextPlaylistElementToPlay(read); + + if (read->dnload) gf_term_download_del(read->dnload); + read->dnload = gf_term_download_new(read->service, read->ple->url, GF_NETIO_SESSION_NOT_THREADED, + M3U8_NetIO, read); + if (!read->dnload) { + gf_term_on_connect(read->service, NULL, GF_BAD_PARAM); + return GF_OK; + } else { + e = gf_dm_sess_process(read->dnload); + if (e!=GF_OK) { + gf_term_on_connect(read->service, NULL, e); + return GF_OK; + } else { + const char *local_url = gf_dm_sess_get_cache_name(read->dnload); + /*load from mime type*/ + const char *sPlug = gf_cfg_get_key(read->service->term->user->config, "MimeTypes", "video/mp2t"); + if (sPlug) sPlug = strrchr(sPlug, '"'); + if (sPlug) { + sPlug += 2; + read->media_ifce = (GF_InputService *) gf_modules_load_interface_by_name(read->service->term->user->modules, sPlug, GF_NET_CLIENT_INTERFACE); + if (read->media_ifce) { +#if 1 + gf_th_run(read->dl_thread, download_media_files, read); +#else + e = download_media_files(read); + if (e) { + gf_term_on_connect(read->service, NULL, GF_BAD_PARAM); + return GF_OK; + } +#endif + /* Forward the ConnectService message to the appropriate service for this type of media */ + read->media_ifce->ConnectService(read->media_ifce, serv, local_url); + } else { + gf_term_on_connect(read->service, NULL, GF_BAD_PARAM); + return GF_OK; + } + } else { + gf_term_on_connect(read->service, NULL, GF_BAD_PARAM); + return GF_OK; + } + } + } + } + + gf_term_on_connect(serv, NULL, e); + return GF_OK; +} + +static GF_Err M3U8_CloseService(GF_InputService *plug) +{ + M3U8Reader *read = plug->priv; + MYLOG(("***** M3U8_CloseService %p\n", plug->priv)); + if (read == NULL) + return GF_OK; + if (read->media_ifce) { + read->media_ifce->CloseService(read->media_ifce); + } + MYLOG(("***** M3U8_CloseService2\n")); + gf_term_on_disconnect(read->service, NULL, GF_OK); + if (read->dnload){ + MYLOG(("***** M3U8_CloseService : stopping download\n")); + gf_term_download_del(read->dnload); + read->dnload = NULL; + } + + return GF_OK; +} + +static Bool M3U8_CanHandleURLInService(GF_InputService *plug, const char *url) +{ + MYLOG(("***** M3U8_CanHandleURLInService %s\n", url)); + return 0; +} + +static GF_Descriptor *M3U8_GetServiceDesc(GF_InputService *plug, u32 expect_type, const char *sub_url) +{ + M3U8Reader *read = plug->priv; + MYLOG(("***** M3U8_GetServiceDesc %s\n", sub_url)); + if (read->media_ifce) { + return read->media_ifce->GetServiceDescriptor(read->media_ifce, expect_type, sub_url); + } else { + return NULL; + } +} + +static GF_Err M3U8_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, const char *url, Bool upstream) +{ + M3U8Reader *read = plug->priv; + MYLOG(("***** M3U8_ConnectChannel\n")); + if (!plug || !plug->priv || !read->media_ifce) return GF_SERVICE_ERROR; + return read->media_ifce->ConnectChannel(read->media_ifce, channel, url, upstream); +} + +static GF_Err M3U8_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) +{ + M3U8Reader *read = plug->priv; + MYLOG(("***** M3U8_DisconnectChannel\n")); + if (!plug || !plug->priv || !read->media_ifce) return GF_SERVICE_ERROR; + return read->media_ifce->DisconnectChannel(read->media_ifce, channel); +} + +static GF_Err M3U8_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) +{ + M3U8Reader *read = plug->priv; + MYLOG(("***** M3U8_ChannelGetSLP\n")); + if (!plug || !plug->priv || !read->media_ifce) return GF_SERVICE_ERROR; + return read->media_ifce->ChannelGetSLP(read->media_ifce, channel, out_data_ptr, out_data_size, out_sl_hdr, sl_compressed, out_reception_status, is_new_data); +} + +static GF_Err M3U8_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) +{ + M3U8Reader *read = plug->priv; + MYLOG(("***** M3U8_ChannelReleaseSLP\n")); + if (!plug || !plug->priv || !read->media_ifce) return GF_SERVICE_ERROR; + return read->media_ifce->ChannelReleaseSLP(read->media_ifce, channel); +} + + +static GF_Err M3U8_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) +{ + M3U8Reader *read = plug->priv; + MYLOG(("***** M3U8_ServiceCommand %s\n", com)); + if (!plug || !plug->priv || !com || !read->media_ifce) return GF_SERVICE_ERROR; + + switch(com->command_type) { + case GF_NET_SERVICE_INFO: + /* defer to the real input service */ + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_SERVICE_HAS_AUDIO: + /* defer to the real input service */ + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_SET_PADDING: + /* for padding settings, the MPD level should not change anything */ + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_SET_PULL: + /* defer to the real input service */ + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_INTERACTIVE: + /* defer to the real input service */ + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_BUFFER: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_BUFFER_QUERY: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_DURATION: + /* Ignore the duration given by the input service and use the one given in the playlist */ + { + Double duration; + duration = (read->ple ? read->ple->durationInfo : 0); + com->duration.duration = duration; + return GF_OK; + } + break; + case GF_NET_CHAN_PLAY: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_STOP: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_PAUSE: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_RESUME: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_SET_SPEED: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_CONFIG: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_GET_PIXEL_AR: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_GET_DSI: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_MAP_TIME: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_RECONFIG: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_DRM_CFG: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_CHAN_GET_ESD: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_BUFFER_QUERY: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_GET_STATS: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_IS_CACHABLE: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + case GF_NET_SERVICE_MIGRATION_INFO: + return read->media_ifce->ServiceCommand(read->media_ifce, com); + break; + default: + return GF_SERVICE_ERROR; + } +} + +GF_InputService *M3U8_LoadDemux() +{ + M3U8Reader *reader; + GF_InputService *plug = gf_malloc(sizeof(GF_InputService)); + memset(plug, 0, sizeof(GF_InputService)); + MYLOG(("Loading M3U8\n")); + GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC M3U8 Reader", "gpac distribution") + /* Yes, we handle this */ + plug->CanHandleURL = M3U8_CanHandleURL; + /* Start read m3u8, we do */ + plug->ConnectService = M3U8_ConnectService; + plug->CloseService = M3U8_CloseService; + + /* Foward to service, none of our business */ + plug->GetServiceDescriptor = M3U8_GetServiceDesc; + plug->ConnectChannel = M3U8_ConnectChannel; + plug->DisconnectChannel = M3U8_DisconnectChannel; + plug->CanHandleURLInService = M3U8_CanHandleURLInService; + + /* To check for seeking / getTrackInfo... GF_NET_SERVICE_INFO */ + plug->ServiceCommand = M3U8_ServiceCommand; + + /* to transmit packets */ + plug->ChannelGetSLP = M3U8_ChannelGetSLP; + plug->ChannelReleaseSLP = M3U8_ChannelReleaseSLP; + + reader = gf_malloc(sizeof(M3U8Reader)); + memset(reader, 0, sizeof(M3U8Reader)); + reader->playlist = NULL; + reader->rootURL = NULL; + plug->priv = reader; + return plug; +} + +void M3U8_DeleteDemux(void *ifce) +{ + GF_InputService *plug = (GF_InputService *) ifce; + M3U8Reader *read = plug->priv; + if (read){ + if (read->rootURL) + gf_free(read->rootURL); + read->rootURL = NULL; + gf_free(read); + } + gf_free(plug); +} diff --git a/modules/m3u8_in/m3u8_in.h b/modules/m3u8_in/m3u8_in.h new file mode 100644 index 0000000..06b3279 --- /dev/null +++ b/modules/m3u8_in/m3u8_in.h @@ -0,0 +1,40 @@ +/** + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * 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. + * Written by Pierre Souchay for VizionR SAS + * + */ + +#ifndef M3U8_IN_H +#define M3U8_IN_H + +#include <gpac/modules/service.h> +#include <gpac/modules/codec.h> +#include <gpac/avparse.h> +#include <gpac/constants.h> +#include <gpac/thread.h> +#include "playlist.h" + +GF_InputService *M3U8_LoadDemux(); +void M3U8_DeleteDemux(void *); + +#endif + diff --git a/modules/m3u8_in/m3u8_in_load.c b/modules/m3u8_in/m3u8_in_load.c new file mode 100644 index 0000000..cec6214 --- /dev/null +++ b/modules/m3u8_in/m3u8_in_load.c @@ -0,0 +1,50 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * 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. + * + */ + +#include "m3u8_in.h" + +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_NET_CLIENT_INTERFACE, + 0 + }; + return si; +} + +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + if (InterfaceType == GF_NET_CLIENT_INTERFACE) + return (GF_BaseInterface *)M3U8_LoadDemux(); + return NULL; +} + +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { + case GF_NET_CLIENT_INTERFACE: + M3U8_DeleteDemux(ifce); + break; + } +} diff --git a/modules/m3u8_in/m3u8_parser.c b/modules/m3u8_in/m3u8_parser.c new file mode 100644 index 0000000..139ad93 --- /dev/null +++ b/modules/m3u8_in/m3u8_parser.c @@ -0,0 +1,458 @@ +/** + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * 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. + * Written by Pierre Souchay for VizionR SAS + * + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <string.h> +#include "m3u8_parser.h" +//#include <inttypes.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) + +#ifdef WIN32 +#define bzero(a, b) memset(a, 0x0, b) +#endif + +typedef struct _s_accumulated_attributes { + char * title; + int durationInSeconds; + int bandwidth; + int programId; + char * codecs; + int targetDurationInSeconds; + int minMediaSequence; + int currentMediaSequence; + Bool isVariantPlaylist; + Bool isPlaylistEnded; +} s_accumulated_attributes; + +static Bool safe_start_equals(const char * attribute, const char * line){ + int len, atlen; + if (line == NULL) + return 0; + len = strlen(line); + atlen = strlen(attribute); + if (len < atlen) + return 0; + return 0 == strncmp(attribute, line, atlen); +} + +static char ** extractAttributes(const char * name, const char * line, const int numberOfAttributes){ + int sz, i, currentAttribute, start; + char ** ret; + int len = strlen(line); + start = strlen(name); + if (len <= start) + return NULL; + if (!safe_start_equals(name, line)) + return NULL; + ret = calloc((numberOfAttributes + 1 ), sizeof(char*)); + currentAttribute = 0; + for (i = start ; i <= len ; i++){ + if (line[i] == '\0' || line[i] == ','){ + sz = 1 + i - start; + ret[currentAttribute] = calloc( (1+sz), sizeof(char)); + strncpy(ret[currentAttribute], &(line[start]), sz); + currentAttribute++; + start = i+1; + if (start == len){ + return ret; + } + } + } + if (currentAttribute == 0){ + gf_free(ret); + return NULL; + } + return ret; +} + +/** + * Parses the attributes and accumulate into the attributes structure + */ +static char ** parseAttributes(const char * line, s_accumulated_attributes * attributes){ + int intValue, i; + char ** ret; + char * endPtr; + char * utility; + if (line == NULL) + return NULL; + if (!safe_start_equals("#EXT", line)) + return NULL; + if (safe_start_equals("#EXT-X-ENDLIST", line)){ + attributes->isPlaylistEnded = 1; + return NULL; + } + ret = extractAttributes("#EXT-X-TARGETDURATION:", line, 1); + if (ret){ + /* #EXT-X-TARGETDURATION:<seconds> */ + if (ret[0]){ + intValue = strtol(ret[0], &endPtr, 10); + if (endPtr != ret[0]){ + attributes->targetDurationInSeconds = intValue; + } + } + return ret; + } + ret = extractAttributes("#EXT-X-MEDIA-SEQUENCE:", line, 1); + if (ret){ + /* #EXT-X-MEDIA-SEQUENCE:<number> */ + if (ret[0]){ + intValue = strtol(ret[0], &endPtr, 10); + if (endPtr != ret[0]){ + attributes->minMediaSequence = intValue; + attributes->currentMediaSequence = intValue; + } + } + return ret; + } + ret = extractAttributes("#EXTINF:", line, 2); + if (ret){ + /* #EXTINF:<duration>,<title> */ + if (ret[0]){ + intValue = strtol(ret[0], &endPtr, 10); + if (endPtr != ret[0]){ + attributes->durationInSeconds = intValue; + } + } + if (ret[1]){ + attributes->title = strdup(ret[1]); + } + return ret; + } + ret = extractAttributes("#EXT-X-KEY:", line, 2); + if (ret){ + /* #EXT-X-KEY:METHOD=<method>[,URI="<URI>"] */ + /* Not Supported for now */ + return ret; + } + ret = extractAttributes("#EXT-X-STREAM-INF:", line, 3); + if (ret){ + /* #EXT-X-STREAM-INF:[attribute=value][,attribute=value]* */ + i = 0; + attributes->isVariantPlaylist = 1; + while (ret[i] != NULL){ + if (safe_start_equals("BANDWIDTH=", ret[i])){ + utility = &(ret[i][10]); + intValue = strtol(utility, &endPtr, 10); + if (endPtr != utility) + attributes->bandwidth = intValue; + } else if (safe_start_equals("PROGRAM-ID=", ret[i])){ + utility = &(ret[i][11]); + intValue = strtol(utility, &endPtr, 10); + if (endPtr != utility) + attributes->programId = intValue; + } else if (safe_start_equals("CODECS=\"", ret[i])){ + intValue = strlen(ret[i]); + if (ret[i][intValue-1] == '"'){ + attributes->codecs = strdup(&(ret[i][7])); + } + } + i++; + } + return ret; + } + return NULL; +} + +#define M3U8_BUF_SIZE 2048 + +static char * parse_next_line( char * data, char * buf, int * readPointer, int * remainingBytes){ + int i, pos; + for (i = 0; i < *remainingBytes; i++){ + pos = *readPointer + i; + if ('\n' == data[pos]){ + bzero(buf, M3U8_BUF_SIZE); + memcpy(buf, data, pos); + buf[pos] = 0; + while (pos < *remainingBytes && (data[pos] == '\r' || data[pos] == '\n')) + pos++; + *remainingBytes = *remainingBytes - pos + *readPointer; + memcpy(data, &(data[pos]), *remainingBytes); + *readPointer = 0; + return buf; + } + } + /* OK, we did not find it, we discard this line if buffer is full */ + *readPointer+= *remainingBytes; + if ((*readPointer) + 1 >= M3U8_BUF_SIZE ) + *readPointer = 0; + return NULL; +} + + +GF_Err parse_root_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL) +{ + return parse_sub_playlist(file, playlist, baseURL, NULL, NULL); +} + +GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL, Program * in_program, PlaylistElement *sub_playlist) +{ + int readen, readPointer, len, i, currentLineNumber; + FILE * f; + VariantPlaylist * pl; + char data[M3U8_BUF_SIZE+1]; + char buf[M3U8_BUF_SIZE+1]; + char * currentLine; + char ** attributes = NULL; + s_accumulated_attributes attribs; + f = fopen(file, "rb"); + if (!f){ + return GF_SERVICE_ERROR; + } + if (*playlist == NULL){ + *playlist = variant_playlist_new(); + } + pl = *playlist; + readen=0; + readPointer = 0; + currentLineNumber = 0; + bzero(&attribs, sizeof(s_accumulated_attributes)); + attribs.bandwidth = 0; + attribs.isVariantPlaylist = 0; + attribs.isPlaylistEnded = 0; + attribs.minMediaSequence = 0; + attribs.currentMediaSequence = 0; + do { + readen = fread(data, 1, M3U8_BUF_SIZE - readPointer, f); + if (readen > 0){ + do { + currentLine = parse_next_line(data, buf, &readPointer, &readen); + if (currentLine != NULL){ + currentLineNumber++; + len = strlen( currentLine); + if (len < 1) + continue; + if (currentLineNumber == 1){ + /* Playlist MUST start with #EXTM3U */ + if (len < 7 || strncmp("#EXTM3U", currentLine, 7)!=0){ + MYLOG(("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){ + attributes = parseAttributes(currentLine, &attribs); + if (attributes == NULL){ + MYLOG(("Comment at line %d : %s\n", currentLineNumber, currentLine)); + } else { + MYLOG(("Directive at line %d: \"%s\", attributes=", currentLineNumber, currentLine)); + i = 0; + while (attributes[i] != NULL){ + MYLOG((" [%d]='%s'", i, attributes[i])); + gf_free(attributes[i]); + attributes[i] = NULL; + i++; + } + MYLOG(("\n")); + gf_free(attributes); + attributes = NULL; + } + } + } else { + char * fullURL = currentLine; + GF_List * currentBitrateList = NULL; + //printf("Line %d: '%s'\n", currentLineNumber, currentLine); + + if (gf_url_is_local(currentLine)){ + /* + if (gf_url_is_local(baseURL)){ + int num_chars = -1; + if (baseURL[strlen(baseURL)-1] == '/'){ + num_chars = asprintf(&fullURL, "%s%s", baseURL, currentLine); + } else { + num_chars = asprintf(&fullURL, "%s/%s", baseURL, currentLine); + } + if (num_chars < 0 || fullURL == NULL){ + variant_playlist_del(*playlist); + playlist = NULL; + return GF_OUT_OF_MEM; + } + } else */{ + fullURL = gf_url_concatenate(baseURL, currentLine); + } + assert( fullURL ); + /*printf("*** calculated full path = %s from %s and %s\n", fullURL, currentLine, baseURL);*/ + } + { + u32 count; + PlaylistElement * currentPlayList = sub_playlist; + /* First, we have to find the matching program */ + Program * program = in_program; + if (!in_program) program = variant_playlist_find_matching_program(pl, attribs.programId); + /* We did not found the program, we create it */ + if (program == NULL){ + program = program_new(attribs.programId); + if (program == NULL){ + /* OUT of memory */ + variant_playlist_del(*playlist); + playlist = NULL; + return GF_OUT_OF_MEM; + } + gf_list_add(pl->programs, program); + if (pl->currentProgram < 0) + pl->currentProgram = program->programId; + } + + /* OK, we have a program, we have to choose the elements with same bandwidth */ + assert( program ); + assert( program->bitrates); + count = gf_list_count( program->bitrates); + + if (!currentPlayList) { + for (i = 0; i < count; i++){ + PlaylistElement * itPlayListElement = gf_list_get(program->bitrates, i); + assert( itPlayListElement ); + if (itPlayListElement->bandwidth == attribs.bandwidth){ + currentPlayList = itPlayListElement; + break; + } + } + } + + if (attribs.isVariantPlaylist){ + /* We are the Variant Playlist */ + if (currentPlayList != NULL){ + /* should not happen, it means we redefine something previsouly added */ + //assert( 0 ); + } + currentPlayList = playlist_element_new( + TYPE_UNKNOWN, + fullURL, + attribs.title, + attribs.durationInSeconds); + if (currentPlayList == NULL){ + /* OUT of memory */ + variant_playlist_del(*playlist); + playlist = NULL; + return GF_OUT_OF_MEM; + } + assert( fullURL); + currentPlayList->url = strdup(fullURL); + currentPlayList->title = attribs.title ? strdup(attribs.title):NULL; + gf_list_add(program->bitrates, currentPlayList); + } else { + /* Normal Playlist */ + assert( pl->programs); + if (currentPlayList == NULL){ + /* This is in facts a "normal" playlist without any element in it */ + PlaylistElement * subElement; + assert(baseURL); + currentPlayList = playlist_element_new( + TYPE_PLAYLIST, + baseURL, + attribs.title, + attribs.durationInSeconds); + if (currentPlayList == NULL){ + /* OUT of memory */ + variant_playlist_del(*playlist); + playlist = NULL; + return GF_OUT_OF_MEM; + } + assert(currentPlayList->element.playlist.elements); + assert( fullURL); + currentPlayList->url = strdup(baseURL); + currentPlayList->title = strdup("NO_NAME"); + subElement = playlist_element_new( + TYPE_UNKNOWN, + fullURL, + attribs.title, + attribs.durationInSeconds); + if (subElement == NULL){ + variant_playlist_del(*playlist); + playlist_element_del(currentPlayList); + playlist = NULL; + return GF_OUT_OF_MEM; + } + gf_list_add(currentPlayList->element.playlist.elements, subElement); + gf_list_add(program->bitrates, currentPlayList); + assert( program ); + assert( program->bitrates); + assert( currentPlayList); + + } else { + PlaylistElement * subElement = playlist_element_new( + TYPE_UNKNOWN, + fullURL, + attribs.title, + attribs.durationInSeconds); + if (currentPlayList->elementType != TYPE_PLAYLIST) { + currentPlayList->elementType = TYPE_PLAYLIST; + if (!currentPlayList->element.playlist.elements) + currentPlayList->element.playlist.elements = gf_list_new(); + } + if (subElement == NULL){ + variant_playlist_del(*playlist); + playlist_element_del(currentPlayList); + playlist = NULL; + return GF_OUT_OF_MEM; + } + gf_list_add(currentPlayList->element.playlist.elements, subElement); + } + } + + currentPlayList->element.playlist.currentMediaSequence = attribs.currentMediaSequence ; + if (attribs.targetDurationInSeconds > 0){ + currentPlayList->element.playlist.target_duration = attribs.targetDurationInSeconds; + currentPlayList->durationInfo = attribs.targetDurationInSeconds; + } + if (attribs.durationInSeconds) + currentPlayList->durationInfo = attribs.durationInSeconds; + + currentPlayList->element.playlist.mediaSequenceMin = attribs.minMediaSequence; + currentPlayList->element.playlist.mediaSequenceMax = attribs.currentMediaSequence++; + if (attribs.bandwidth > 1) + currentPlayList->bandwidth = attribs.bandwidth; + if (attribs.isPlaylistEnded) + currentPlayList->element.playlist.is_ended = 1; + } + /* Cleanup all line-specific fields */ + if (attribs.title){ + gf_free(attribs.title); + attribs.title = NULL; + } + attribs.durationInSeconds = 0; + attribs.bandwidth = 0; + attribs.programId = 0; + if (attribs.codecs != NULL){ + gf_free(attribs.codecs); + attribs.codecs = NULL; + } + if (fullURL != currentLine){ + gf_free(fullURL); + } + } + } + } while (currentLine != NULL); + } + } while (readen > 0); + fclose(f); + return GF_OK; +} diff --git a/modules/m3u8_in/m3u8_parser.h b/modules/m3u8_in/m3u8_parser.h new file mode 100644 index 0000000..a48a36d --- /dev/null +++ b/modules/m3u8_in/m3u8_parser.h @@ -0,0 +1,47 @@ +/** + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * 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. + * Written by Pierre Souchay for VizionR SAS + * + */ +#ifndef M3U8_PARSER_H +#define M3U8_PARSER_H +#include "playlist.h" + +/** + * Parse the given playlist file + * @param file The file from cache to parse + * @param The playlist to fill. If argument is null, and file is valid, playlist will be allocated + * @return GF_OK if playlist valid + */ +GF_Err parse_root_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL); +/** + * Parse the given playlist file as a subplaylist of an existing playlist + * @param file The file from cache to parse + * @param The playlist to fill. + * @param baseURL base URL of the playlist + * @param program in which the playlist is parsed + * @param sub_playlist existing subplaylist element in the @playlist in which the playlist is parsed + * @return GF_OK if playlist valid + */ +GF_Err parse_sub_playlist(const char * file, VariantPlaylist ** playlist, const char * baseURL, Program * in_program, PlaylistElement *sub_playlist); + +#endif /* M3U8_PARSER_H */ \ No newline at end of file diff --git a/modules/m3u8_in/playlist.c b/modules/m3u8_in/playlist.c new file mode 100644 index 0000000..bb1df4a --- /dev/null +++ b/modules/m3u8_in/playlist.c @@ -0,0 +1,286 @@ +/** + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * 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. + * Written by Pierre Souchay for VizionR SAS + * + */ +#include "playlist.h" +#include <string.h> + +#ifdef WIN32 + #define bzero(a, b) memset(a, 0x0, b) +#endif + +GF_Err cleanup_list_of_elements(GF_List * list){ + int i, count; + GF_Err result = GF_OK; + if (list == NULL) + return result; + count = gf_list_count(list); + for (i = 0; i < count ; i++){ + PlaylistElement * pl = (PlaylistElement *) gf_list_get(list, i); + if (pl) + result |= playlist_element_del(pl); + } + gf_list_del(list); + return result; +} + +GF_Err playlist_element_del(PlaylistElement * e){ + GF_Err result = GF_OK; + if (e == NULL) + return result; + if (e->title){ + gf_free(e->title); + e->title = NULL; + } + assert( e->url); + gf_free(e->url); + e->url = NULL; + + switch (e->elementType) { + case TYPE_UNKNOWN: + case TYPE_STREAM: + break; + case TYPE_PLAYLIST: + assert( e->element.playlist.elements); + result |= cleanup_list_of_elements(e->element.playlist.elements); + e->element.playlist.elements = NULL; + default: + break; + } + return result; +} + +Program * program_new(int programId){ + Program * program = malloc(sizeof(Program)); + if (program == NULL){ + return NULL; + } + program->programId = programId; + program->bitrates = gf_list_new(); + if (program->bitrates == NULL){ + gf_free(program); + return NULL; + } + return program; +} + +GF_Err program_del(Program * program){ + int count, i; + GF_Err e = GF_OK; + if (program == NULL) + return e; + assert( program->bitrates); + count = gf_list_count(program->bitrates); + for (i = 0 ; i < count; i++){ + e |= cleanup_list_of_elements(gf_list_get(program->bitrates, i)); + } + gf_list_del(program->bitrates); + program->bitrates = NULL; + return e; +} + +/* +GF_Err playlist_del(Playlist * pl){ + GF_Err result = GF_OK; + if (pl == NULL) + return result; + if (pl->elements){ + result|= cleanup_list_of_elements(pl->elements); + pl->elements = NULL; + } + gf_free(pl); + return result; +}*/ + +PlaylistElement * playlist_element_new(PlaylistElementType elementType, const char * url, const char * title, int durationInfo){ + PlaylistElement * e = malloc(sizeof(PlaylistElement)); + bzero(e, sizeof(PlaylistElement)); + assert( url ); + if (e == NULL) + return NULL; + e->durationInfo = durationInfo; + e->title = (title ? strdup(title) : NULL); + assert( url); + e->url = strdup(url); + e->bandwidth = 0; + e->elementType = elementType; + if (elementType == TYPE_PLAYLIST){ + e->element.playlist.is_ended = 0; + e->element.playlist.target_duration = durationInfo; + e->element.playlist.currentMediaSequence = 0; + e->element.playlist.mediaSequenceMin = 0; + e->element.playlist.mediaSequenceMax = 0; + e->element.playlist.elements = gf_list_new(); + if (NULL == (e->element.playlist.elements)){ + if (e->title) + gf_free(e->title); + if (e->url) + gf_free(e->url); + e->url = NULL; + e->title = NULL; + gf_free(e); + return NULL; + } + } else { + /* Nothing to do, stream is an empty structure */ + } + assert(e->bandwidth == 0); + assert(e->url); + return e; +} +/* +Playlist * playlist_new(){ + Playlist * pl = malloc(sizeof(Playlist)); + if (pl == NULL) + return NULL; + pl->currentMediaSequence = 1; + pl->target_duration = 0; + pl->mediaSequenceMin = 0; + pl->mediaSequenceMax = 0; + pl->is_ended = 0; + pl->elements = gf_list_new(); + if (pl->elements == NULL){ + gf_free(pl); + return NULL; + } + return pl; +} + */ + +VariantPlaylist * variant_playlist_new () +{ + VariantPlaylist * pl = malloc( sizeof(VariantPlaylist) ); + if (pl == NULL) + return NULL; + pl->programs = gf_list_new(); + if (! pl->programs){ + gf_free( pl ); + return NULL; + } + pl->currentProgram = -1; + return pl; +} + +GF_Err variant_playlist_del (VariantPlaylist * playlist){ + int count, i, count2, j; + Program * p; + if (playlist == NULL) + return GF_OK; + assert( playlist->programs); + count = gf_list_count(playlist->programs); + for (i = 0; i < count ; i++){ + p = gf_list_get(playlist->programs, i); + assert(p); + count2 = gf_list_count( p->bitrates ); + for (j = 0; j < count2; j++){ + PlaylistElement * pl = gf_list_get(p->bitrates, j); + playlist_element_del(pl); + } + gf_list_del(p->bitrates); + p->bitrates = NULL; + } + gf_list_del(playlist->programs); + playlist->programs = NULL; + gf_free(playlist); + return GF_OK; +} + +GF_Err playlist_element_dump(const PlaylistElement * e, int indent){ + int i; + GF_Err r = GF_OK; + for (i = 0 ; i < indent; i++) + printf(" "); + if (e == NULL){ + printf("NULL PlaylistElement\n"); + return r; + } + printf("PlayListElement[%p, title=%s, duration=%d, bandwidth=%d, url=%s, type=%s]\n", + (void*)e, + e->title, + e->durationInfo, + e->bandwidth, + e->url, + e->elementType == TYPE_STREAM ? "stream" : "playlist"); + if (TYPE_PLAYLIST == e->elementType){ + int sz; + assert( e->element.playlist.elements); + sz = gf_list_count(e->element.playlist.elements); + indent+=2; + for (i = 0 ; i < sz ; i++){ + PlaylistElement * el = gf_list_get(e->element.playlist.elements, i); + assert( el); + r|= playlist_element_dump( el, indent); + } + } + return r; +} + +GF_Err variant_playlist_dump(const VariantPlaylist * pl){ + int i, count; + GF_Err e = GF_OK; + if (pl == NULL){ + printf("VariantPlaylist = NULL\n"); + return e; + } + printf("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); + assert( p->bitrates ); + countj = gf_list_count(p->bitrates); + for (j = 0; j < countj; j++){ + PlaylistElement * el = gf_list_get(p->bitrates, j); + assert(el); + e |= playlist_element_dump( el, 4); + } + printf(" }\n"); + } + printf("}\n"); + return e; +} + +Program * variant_playlist_find_matching_program(const VariantPlaylist * pl, const u32 programId){ + u32 count, i; + assert( pl); + assert( pl->programs); + assert(programId >= 0); + count = gf_list_count(pl->programs); + for (i = 0 ; i < count ; i++){ + Program * cur = gf_list_get(pl->programs, i); + assert( cur ); + if (programId == cur->programId){ + /* We found the program */ + return cur; + } + } + return NULL; +} + +Program * variant_playlist_get_current_program(const VariantPlaylist * pl){ + assert( pl ); + return variant_playlist_find_matching_program(pl, pl->currentProgram); +} diff --git a/modules/m3u8_in/playlist.h b/modules/m3u8_in/playlist.h new file mode 100644 index 0000000..276edbd --- /dev/null +++ b/modules/m3u8_in/playlist.h @@ -0,0 +1,162 @@ +/** + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * 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. + * Written by Pierre Souchay for VizionR SAS + * + */ +#ifndef M3U8_PLAYLIST_H +#define M3U8_PLAYLIST_H +#include <gpac/tools.h> +#include <gpac/list.h> + +/** + * Global Structure + * + * For a stream with multiple bandwidths and multiple programs + * + * VariantPlayList + * | + * |_ program id 1 + * | | + * | |_ bandwidth X : playlistElement1 + * | |- bandwidth Y : playlistElement2 + * | + * |- program id 2 + * | + * |_ bandwidth Z : playlistElement + * + * For a "normal" playlist + * + * VariantPlayList + * | + * |_ program id 1 + * | + * |_ bandwidth 0 : playlistElement1 + * + * Where PlaylistElement can be : + * - a stream (real resource) + * - a playlist (list of PlaylistElements itself) + */ + +/** + * Basic Stream structure + */ +typedef struct s_stream{ + u8 i; +} Stream; + +/** + * The playlist contains a list of elements to play + */ +typedef struct s_playList { + int currentMediaSequence; + int target_duration; + int mediaSequenceMin; + int mediaSequenceMax; + char is_ended; + GF_List * elements; +} Playlist; + +typedef enum e_playlistElementType { TYPE_PLAYLIST, TYPE_STREAM, TYPE_UNKNOWN} PlaylistElementType; + +/** + * The Structure containing the playlist element + */ +typedef struct s_playlistElement{ + int durationInfo; + int bandwidth; + char * title; + char * url; + PlaylistElementType elementType; + union { Playlist playlist; Stream stream; } element; + +} PlaylistElement; + +typedef struct s_program{ + int programId; + GF_List * bitrates; + int currentBitrateIndex; +} Program; + + +/** + * The root playlist, can contains several PlaylistElements structures + */ +typedef struct s_variantPlaylist { + GF_List * programs; + int currentProgram; +} VariantPlaylist; + +/** + * Creates a new playlist + * @return NULL if playlist could not be allocated + * +Playlist * playlist_new(); +*/ +/** + * Deletes a given playlist and all of its sub elements + * +GF_Err playlist_del(Playlist *); +*/ + +/** + * Deletes an Playlist element + */ +GF_Err playlist_element_del(PlaylistElement *); + +/** + * Creates a new program properly initialized + */ +Program * program_new(int programId); + +/** + * Deletes the specified program + */ +GF_Err program_del(Program * program); + +/** + * Creates an Playlist element. + * This element can be either a playlist of a stream according to first parameter. + * @return NULL if element could not be created. Element deletion will be deleted recusivly by #playlist_del(Playlist*) + */ +PlaylistElement * playlist_element_new(PlaylistElementType elementType, const char * url, const char * title, int durationInfo); + +/** + * Creates a new VariantPlaylist + * @return NULL if VariantPlaylist element could not be allocated + */ +VariantPlaylist * variant_playlist_new (); + +/** + * Deletes the given VariantPlaylist and all of its sub elements + */ +GF_Err variant_playlist_del(VariantPlaylist *); + +GF_Err playlist_element_dump(const PlaylistElement * e, int indent); + +GF_Err variant_playlist_dump(const VariantPlaylist *); + +Program * variant_playlist_find_matching_program(const VariantPlaylist *, const u32 programId); + +Program * variant_playlist_get_current_program(const VariantPlaylist *); + +#endif /* M3U8_PLAYLIST_H */ + diff --git a/modules/m3u8_in/test.c b/modules/m3u8_in/test.c new file mode 100644 index 0000000..25c0f27 --- /dev/null +++ b/modules/m3u8_in/test.c @@ -0,0 +1,31 @@ +#include "playlist.h" +#include "m3u8_parser.h" + +const char * files[] = { + "tests/spec_simple_playlist.m3u8", + "tests/relative_playlist.m3u8", + "tests/direct8.m3u8", + "tests/spec_sliding_window_playlist.m3u8", + "tests/spec_encrypted_media.m3u8", + "tests/spec_variant_playlist.m3u8", + "tests/spec_multiple_files.m3u8", + NULL +}; + +int main(int argc, char ** argv){ + int i = 0; + while (files[i] != NULL){ + VariantPlaylist * pl = NULL; + printf("Testing %s...\n", files[i]); + if (parse_root_playlist(files[i], &pl, "tests/")){ + printf("**** Error while reading playlist %s !\n", files[i]); + } + i++; + printf("DONE, now dumping...\n\n"); + variant_playlist_dump(pl); + printf("DONE, now deleting...\n\n"); + variant_playlist_del( pl ); + } + printf("Finished\n"); + return 0; +} diff --git a/modules/m3u8_in/tests/direct8.m3u8 b/modules/m3u8_in/tests/direct8.m3u8 new file mode 100644 index 0000000..f0ab16f --- /dev/null +++ b/modules/m3u8_in/tests/direct8.m3u8 @@ -0,0 +1,3 @@ +#EXTM3U +#EXTINF:0, +http://tv.freebox.fr/stream_direct8 diff --git a/modules/m3u8_in/tests/relative_playlist.m3u8 b/modules/m3u8_in/tests/relative_playlist.m3u8 new file mode 100644 index 0000000..4e390bf --- /dev/null +++ b/modules/m3u8_in/tests/relative_playlist.m3u8 @@ -0,0 +1,3 @@ +#EXTM3U +#EXTINF:15,Relative Track +relativeURL/test.ts diff --git a/modules/m3u8_in/tests/spec_encrypted_media.m3u8 b/modules/m3u8_in/tests/spec_encrypted_media.m3u8 new file mode 100644 index 0000000..670a914 --- /dev/null +++ b/modules/m3u8_in/tests/spec_encrypted_media.m3u8 @@ -0,0 +1,18 @@ +#EXTM3U +#EXT-X-MEDIA-SEQUENCE:7794 +#EXT-X-TARGETDURATION:15 + +#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=52" + +#EXTINF:15, +http://media.example.com/fileSequence7794.ts +#EXTINF:15, +http://media.example.com/fileSequence7795.ts +#EXTINF:15, +http://media.example.com/fileSequence7796.ts + +#EXT-X-KEY:METHOD=AES-128,URI="https://priv.example.com/key.php?r=53" + +#EXTINF:15, +http://media.example.com/fileSequence7797.ts + diff --git a/modules/m3u8_in/tests/spec_multiple_files.m3u8 b/modules/m3u8_in/tests/spec_multiple_files.m3u8 new file mode 100644 index 0000000..1074c2b --- /dev/null +++ b/modules/m3u8_in/tests/spec_multiple_files.m3u8 @@ -0,0 +1,19 @@ +#EXTM3U +# Taken from http://developer.apple.com/iphone/library/documentation/networkinginternet/conceptual/streamingmediaguide/HTTPStreamingArchitecture/HTTPStreamingArchitecture.html +#EXT-X-MEDIA-SEQUENCE:0 + +#EXT-X-TARGETDURATION:10 + +#EXTINF:10, + +http://media.example.com/segment1.ts + +#EXTINF:10, + +http://media.example.com/segment2.ts + +#EXTINF:10, + +http://media.example.com/segment3.ts + +#EXT-X-ENDLIST diff --git a/modules/m3u8_in/tests/spec_simple_playlist.m3u8 b/modules/m3u8_in/tests/spec_simple_playlist.m3u8 new file mode 100644 index 0000000..135707c --- /dev/null +++ b/modules/m3u8_in/tests/spec_simple_playlist.m3u8 @@ -0,0 +1,5 @@ +#EXTM3U +#EXT-X-TARGETDURATION:10 +#EXTINF:5220, +http://media.example.com/entire.ts +#EXT-X-ENDLIST diff --git a/modules/m3u8_in/tests/spec_sliding_window_playlist.m3u8 b/modules/m3u8_in/tests/spec_sliding_window_playlist.m3u8 new file mode 100644 index 0000000..1c565e2 --- /dev/null +++ b/modules/m3u8_in/tests/spec_sliding_window_playlist.m3u8 @@ -0,0 +1,11 @@ +#EXTM3U +#EXT-X-TARGETDURATION:8 +#EXT-X-MEDIA-SEQUENCE:2680 + +#EXTINF:8, +https://priv.example.com/fileSequence2680.ts +#EXTINF:8, +https://priv.example.com/fileSequence2681.ts +#EXTINF:8, +https://priv.example.com/fileSequence2682.ts + diff --git a/modules/m3u8_in/tests/spec_variant_playlist.m3u8 b/modules/m3u8_in/tests/spec_variant_playlist.m3u8 new file mode 100644 index 0000000..7960bab --- /dev/null +++ b/modules/m3u8_in/tests/spec_variant_playlist.m3u8 @@ -0,0 +1,10 @@ +#EXTM3U +#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1280000 +http://example.com/low.m3u8 +#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2560000 +http://example.com/mid.m3u8 +#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=7680000 +http://example.com/hi.m3u8 +#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=65000,CODECS="mp4a.40.5" +http://example.com/audio-only.m3u8 + diff --git a/modules/modules_export.cpp b/modules/modules_export.cpp new file mode 100644 index 0000000..4b050bf --- /dev/null +++ b/modules/modules_export.cpp @@ -0,0 +1,38 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * Copyright (c) ENST 2008 - + * 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. + * + */ + +/*this file is only used with Win32&MSVC to export the module interface symbols from each module DLL*/ +#include <gpac/setup.h> + +#ifdef _WIN32_WCE +#define EXPORT_SYMBOL(a) "/export:"#a +#else +#define EXPORT_SYMBOL(a) "/export:_"#a +#endif + +#pragma comment (linker, EXPORT_SYMBOL(QueryInterfaces) ) +#pragma comment (linker, EXPORT_SYMBOL(LoadInterface) ) +#pragma comment (linker, EXPORT_SYMBOL(ShutdownInterface) ) + diff --git a/modules/mp3_in/Makefile b/modules/mp3_in/Makefile index 00a1669..d4b5b36 100644 --- a/modules/mp3_in/Makefile +++ b/modules/mp3_in/Makefile @@ -36,20 +36,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_mp3_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols mp3_in.def +#LDFLAGS+=-export-symbols mp3_in.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) -L../../bin/gcc -lgpac $(EXTRALIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_mp3_in-static.so $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) +endif %.o: %.c diff --git a/modules/mp3_in/mad_dec.c b/modules/mp3_in/mad_dec.c index aa60e51..e8f5bdd 100644 --- a/modules/mp3_in/mad_dec.c +++ b/modules/mp3_in/mad_dec.c @@ -22,6 +22,7 @@ * */ + #ifdef GPAC_HAS_MAD #include <gpac/modules/codec.h> @@ -75,7 +76,7 @@ static GF_Err MAD_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) mad_synth_init(&ctx->synth); ctx->configured = 1; - ctx->buffer = malloc(sizeof(char) * 2*MAD_BUFFER_MDLEN); + ctx->buffer = gf_malloc(sizeof(char) * 2*MAD_BUFFER_MDLEN); /*we need a frame to init, so use default values*/ ctx->num_samples = 1152; @@ -92,7 +93,7 @@ static GF_Err MAD_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) MADCTX(); if (ES_ID != ctx->ES_ID) return GF_BAD_PARAM; ctx->ES_ID = 0; - if (ctx->buffer) free(ctx->buffer); + if (ctx->buffer) gf_free(ctx->buffer); ctx->buffer = NULL; ctx->sample_rate = ctx->out_size = ctx->num_samples = 0; ctx->num_channels = 0; @@ -298,9 +299,9 @@ static Bool MAD_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, u32 ObjectT switch (ObjectType) { /*MPEG1 audio*/ - case 0x69: + case GPAC_OTI_AUDIO_MPEG2_PART3: /*MPEG2 audio*/ - case 0x6B: + case GPAC_OTI_AUDIO_MPEG1: return 1; /*cap query*/ case 0: @@ -341,8 +342,8 @@ void DeleteMADDec(GF_MediaDecoder *ifcg) mad_frame_finish(&ctx->frame); mad_synth_finish(&ctx->synth); } - free(ctx); - free(ifcg); + gf_free(ctx); + gf_free(ifcg); } #endif diff --git a/modules/mp3_in/mp3_in.c b/modules/mp3_in/mp3_in.c index d6a490d..06fec40 100644 --- a/modules/mp3_in/mp3_in.c +++ b/modules/mp3_in/mp3_in.c @@ -27,6 +27,7 @@ #include <gpac/constants.h> #include <gpac/modules/codec.h> +#ifndef GPAC_DISABLE_AV_PARSERS typedef struct { @@ -70,6 +71,7 @@ static Bool MP3_CanHandleURL(GF_InputService *plug, const char *url) { char *sExt; sExt = strrchr(url, '.'); + if (!strnicmp(url, "rtsp://", 7)) return 0; if (!sExt) return 0; if (gf_term_check_extension(plug, "audio/mpeg", "mp2 mp3 mpga mpega", "MP3 Music", sExt)) return 1; if (gf_term_check_extension(plug, "audio/x-mpeg", "mp2 mp3 mpga mpega", "MP3 Music", sExt)) return 1; @@ -109,34 +111,33 @@ static void mp3_setup_object(MP3Reader *read) static Bool MP3_ConfigureFromFile(MP3Reader *read) { - u32 hdr, size, pos; + u32 hdr, size; + u64 pos; if (!read->stream) return 0; hdr = gf_mp3_get_next_header(read->stream); if (!hdr) return 0; read->sample_rate = gf_mp3_sampling_rate(hdr); read->oti = gf_mp3_object_type_indication(hdr); - fseek(read->stream, 0, SEEK_SET); + gf_f64_seek(read->stream, 0, SEEK_SET); if (!read->oti) return 0; /*we don't have the full file...*/ if (read->is_remote) return 1; - return 1; +// return 1; - read->duration = gf_mp3_window_size(hdr); - size = gf_mp3_frame_size(hdr); - pos = ftell(read->stream); - fseek(read->stream, pos + size - 4, SEEK_SET); + gf_f64_seek(read->stream, 0, SEEK_SET); + read->duration = 0; while (1) { hdr = gf_mp3_get_next_header(read->stream); if (!hdr) break; read->duration += gf_mp3_window_size(hdr); size = gf_mp3_frame_size(hdr); - pos = ftell(read->stream); - fseek(read->stream, pos + size - 4, SEEK_SET); + pos = gf_f64_tell(read->stream); + gf_f64_seek(read->stream, pos + size - 4, SEEK_SET); } - fseek(read->stream, 0, SEEK_SET); + gf_f64_seek(read->stream, 0, SEEK_SET); return 1; } @@ -161,6 +162,7 @@ static void MP3_OnLiveData(MP3Reader *read, char *data, u32 data_size) if (read->needs_connection) { hdr = gf_mp3_get_next_header_mem(data, data_size, &pos); if (!hdr) return; + read->sample_rate = gf_mp3_sampling_rate(hdr); read->oti = gf_mp3_object_type_indication(hdr); read->is_live = 1; @@ -172,7 +174,7 @@ static void MP3_OnLiveData(MP3Reader *read, char *data, u32 data_size) } if (!data_size) return; - read->data = realloc(read->data, sizeof(char)*(read->data_size+data_size) ); + read->data = gf_realloc(read->data, sizeof(char)*(read->data_size+data_size) ); memcpy(read->data + read->data_size, data, sizeof(char)*data_size); read->data_size += data_size; if (!read->ch) return; @@ -188,9 +190,9 @@ static void MP3_OnLiveData(MP3Reader *read, char *data, u32 data_size) /*not enough data, copy over*/ if (!hdr || (pos+size>data_size)) { - char *d = malloc(sizeof(char) * data_size); + char *d = gf_malloc(sizeof(char) * data_size); memcpy(d, data, sizeof(char) * data_size); - free(read->data); + gf_free(read->data); read->data = d; read->data_size = data_size; @@ -229,17 +231,17 @@ void MP3_NetIO(void *cbk, GF_NETIO_Parameter *param) } else if (param->msg_type==GF_NETIO_PARSE_HEADER) { if (!strcmp(param->name, "icy-name")) { - if (read->icy_name) free(read->icy_name); - read->icy_name = strdup(param->value); + if (read->icy_name) gf_free(read->icy_name); + read->icy_name = gf_strdup(param->value); } if (!strcmp(param->name, "icy-genre")) { - if (read->icy_genre) free(read->icy_genre); - read->icy_genre = strdup(param->value); + if (read->icy_genre) gf_free(read->icy_genre); + read->icy_genre = gf_strdup(param->value); } if (!strcmp(param->name, "icy-meta")) { GF_NetworkCommand com; char *meta; - if (read->icy_track_name) free(read->icy_track_name); + if (read->icy_track_name) gf_free(read->icy_track_name); read->icy_track_name = NULL; meta = param->value; while (meta && meta[0]) { @@ -247,7 +249,7 @@ void MP3_NetIO(void *cbk, GF_NETIO_Parameter *param) if (sep) sep[0] = 0; if (!strnicmp(meta, "StreamTitle=", 12)) { - read->icy_track_name = strdup(meta+12); + read->icy_track_name = gf_strdup(meta+12); } if (!sep) break; sep[0] = ';'; @@ -281,7 +283,7 @@ void MP3_NetIO(void *cbk, GF_NETIO_Parameter *param) szCache = gf_dm_sess_get_cache_name(read->dnload); if (!szCache) e = GF_IO_ERR; else { - read->stream = fopen((char *) szCache, "rb"); + read->stream = gf_f64_open((char *) szCache, "rb"); if (!read->stream) e = GF_SERVICE_ERROR; else { /*if full file at once (in cache) parse duration*/ @@ -291,7 +293,7 @@ void MP3_NetIO(void *cbk, GF_NETIO_Parameter *param) if (!MP3_ConfigureFromFile(read)) { gf_dm_sess_get_stats(read->dnload, NULL, NULL, NULL, &bytes_done, NULL, NULL); /*bad data - there's likely some ID3 around...*/ - if (bytes_done>10*1024) { + if (bytes_done>100*1024) { e = GF_CORRUPTED_DATA; } else { fclose(read->stream); @@ -349,7 +351,7 @@ static GF_Err MP3_ConnectService(GF_InputService *plug, GF_ClientService *serv, } reply = GF_OK; - read->stream = fopen(szURL, "rb"); + read->stream = gf_f64_open(szURL, "rb"); if (!read->stream) { reply = GF_URL_ERROR; } else if (!MP3_ConfigureFromFile(read)) { @@ -371,7 +373,7 @@ static GF_Err MP3_CloseService(GF_InputService *plug) if (read->dnload) gf_term_download_del(read->dnload); read->dnload = NULL; - if (read->data) free(read->data); + if (read->data) gf_free(read->data); read->data = NULL; gf_term_on_disconnect(read->service, NULL, GF_OK); return GF_OK; @@ -428,7 +430,7 @@ static GF_Err MP3_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) GF_Err e = GF_STREAM_NOT_FOUND; if (read->ch == channel) { read->ch = NULL; - if (read->data) free(read->data); + if (read->data) gf_free(read->data); read->data = NULL; e = GF_OK; } @@ -475,7 +477,7 @@ static GF_Err MP3_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) read->start_range = com->play.start_range; read->end_range = com->play.end_range; read->current_time = 0; - if (read->stream) fseek(read->stream, 0, SEEK_SET); + if (read->stream) gf_f64_seek(read->stream, 0, SEEK_SET); if (read->ch == com->base.on_channel) { read->done = 0; @@ -503,10 +505,12 @@ static GF_Err MP3_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) static GF_Err MP3_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) { - u32 pos, hdr, start_from; + u64 pos; + u32 hdr, start_from; MP3Reader *read = plug->priv; - if (read->ch != channel) return GF_STREAM_NOT_FOUND; + if (read->ch != channel) + return GF_STREAM_NOT_FOUND; *out_reception_status = GF_OK; *sl_compressed = 0; @@ -529,14 +533,14 @@ static GF_Err MP3_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, cha } *is_new_data = 1; - pos = ftell(read->stream); + pos = gf_f64_tell(read->stream); hdr = gf_mp3_get_next_header(read->stream); if (!hdr) { if (!read->dnload) { *out_reception_status = GF_EOS; read->done = 1; } else { - fseek(read->stream, pos, SEEK_SET); + gf_f64_seek(read->stream, pos, SEEK_SET); *out_reception_status = GF_OK; } return GF_OK; @@ -553,38 +557,38 @@ static GF_Err MP3_ChannelGetSLP(GF_InputService *plug, LPNETCHANNEL channel, cha if (read->start_range && read->duration) { read->current_time = 0; start_from = (u32) (read->start_range * read->sample_rate); - fseek(read->stream, 0, SEEK_SET); + gf_f64_seek(read->stream, 0, SEEK_SET); while (read->current_time<start_from) { hdr = gf_mp3_get_next_header(read->stream); if (!hdr) { read->start_range = 0; - *out_reception_status = GF_SERVICE_ERROR; + *out_reception_status = GF_EOS; return GF_OK; } read->current_time += gf_mp3_window_size(hdr); read->data_size = gf_mp3_frame_size(hdr); - fseek(read->stream, read->data_size-4, SEEK_CUR); + gf_f64_seek(read->stream, read->data_size-4, SEEK_CUR); } read->start_range = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[MP3Demux] Seeking to frame size %d - TS %d - file pos %d\n", read->data_size, read->current_time, ftell(read->stream))); + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[MP3Demux] Seeking to frame size %d - TS %d - file pos %d\n", read->data_size, read->current_time, gf_f64_tell(read->stream))); } read->sl_hdr.compositionTimeStamp = read->current_time; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[MP3Demux] Found new frame size %d - TS %d - file pos %d\n", read->data_size, read->current_time, ftell(read->stream))); + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[MP3Demux] Found new frame size %d - TS %d - file pos %d\n", read->data_size, read->current_time, gf_f64_tell(read->stream))); read->current_time += gf_mp3_window_size(hdr); - read->data = malloc(sizeof(char) * (read->data_size+read->pad_bytes)); + read->data = gf_malloc(sizeof(char) * (read->data_size+read->pad_bytes)); read->data[0] = (hdr >> 24) & 0xFF; read->data[1] = (hdr >> 16) & 0xFF; read->data[2] = (hdr >> 8) & 0xFF; read->data[3] = (hdr ) & 0xFF; /*end of file*/ if (fread(&read->data[4], 1, read->data_size - 4, read->stream) != read->data_size-4) { - free(read->data); + gf_free(read->data); read->data = NULL; if (read->is_remote) { - fseek(read->stream, pos, SEEK_SET); + gf_f64_seek(read->stream, pos, SEEK_SET); *out_reception_status = GF_OK; } else { *out_reception_status = GF_EOS; @@ -605,7 +609,7 @@ static GF_Err MP3_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) if (read->ch == channel) { if (!read->data) return GF_BAD_PARAM; - free(read->data); + gf_free(read->data); read->data = NULL; return GF_OK; } @@ -615,7 +619,7 @@ static GF_Err MP3_ChannelReleaseSLP(GF_InputService *plug, LPNETCHANNEL channel) GF_InputService *MP3_Load() { MP3Reader *reader; - GF_InputService *plug = malloc(sizeof(GF_InputService)); + GF_InputService *plug = gf_malloc(sizeof(GF_InputService)); memset(plug, 0, sizeof(GF_InputService)); GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC MP3 Reader", "gpac distribution") @@ -630,7 +634,7 @@ GF_InputService *MP3_Load() plug->ChannelGetSLP = MP3_ChannelGetSLP; plug->ChannelReleaseSLP = MP3_ChannelReleaseSLP; - reader = malloc(sizeof(MP3Reader)); + reader = gf_malloc(sizeof(MP3Reader)); memset(reader, 0, sizeof(MP3Reader)); plug->priv = reader; return plug; @@ -640,10 +644,11 @@ void MP3_Delete(void *ifce) { GF_InputService *plug = (GF_InputService *) ifce; MP3Reader *read = plug->priv; - free(read); - free(plug); + gf_free(read); + gf_free(plug); } +#endif /*GPAC_DISABLE_AV_PARSERS*/ #ifdef GPAC_HAS_MAD GF_BaseDecoder *NewMADDec(); @@ -651,19 +656,26 @@ void DeleteMADDec(GF_BaseDecoder *ifcg); #endif GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_NET_CLIENT_INTERFACE) return 1; + static u32 si [] = { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_NET_CLIENT_INTERFACE, +#endif #ifdef GPAC_HAS_MAD - if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1; + GF_MEDIA_DECODER_INTERFACE, #endif - return 0; + 0 + }; + return si; } GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { +#ifndef GPAC_DISABLE_AV_PARSERS if (InterfaceType == GF_NET_CLIENT_INTERFACE) return (GF_BaseInterface *)MP3_Load(); +#endif #ifdef GPAC_HAS_MAD if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)NewMADDec(); #endif @@ -679,8 +691,10 @@ void ShutdownInterface(GF_BaseInterface *ifce) DeleteMADDec((GF_BaseDecoder *) ifce); break; #endif +#ifndef GPAC_DISABLE_AV_PARSERS case GF_NET_CLIENT_INTERFACE: MP3_Delete(ifce); break; +#endif } } diff --git a/modules/mp3_in/mp3_in.def b/modules/mp3_in/mp3_in.def deleted file mode 100644 index 84a59f0..0000000 --- a/modules/mp3_in/mp3_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_mp3_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/mpegts_in/Makefile b/modules/mpegts_in/Makefile index 23a2090..b76fc21 100644 --- a/modules/mpegts_in/Makefile +++ b/modules/mpegts_in/Makefile @@ -26,20 +26,17 @@ SRCS := $(OBJS:.o=.c) LIB=gm_mpegts_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols mpegts_in.def -endif - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) +#LDFLAGS+=-export-symbols mpegts_in.def endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_mpegts_in-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/mpegts_in/mpegts_in.c b/modules/mpegts_in/mpegts_in.c index 5e79f16..b780ebd 100644 --- a/modules/mpegts_in/mpegts_in.c +++ b/modules/mpegts_in/mpegts_in.c @@ -11,16 +11,16 @@ * 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. - * + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * */ #include <gpac/modules/service.h> @@ -30,6 +30,9 @@ #include <gpac/network.h> #include <gpac/constants.h> +#ifndef GPAC_DISABLE_MPEG2TS + + #ifdef GPAC_HAS_LINUX_DVB #include <fcntl.h> #include <sys/ioctl.h> @@ -40,7 +43,7 @@ typedef struct { u32 freq; u16 vpid; - u16 apid; + u16 apid; fe_spectral_inversion_t specInv; fe_modulation_t modulation; fe_bandwidth_t bandwidth; @@ -68,6 +71,8 @@ typedef struct { typedef struct { + GF_InputService *owner; + GF_ClientService *service; GF_M2TS_Demuxer *ts; @@ -81,16 +86,16 @@ typedef struct GF_Mutex *mx; /*net playing*/ GF_Socket *sock; - + #ifdef GPAC_HAS_LINUX_DVB /*dvb playing*/ GF_Tuner *tuner; -#endif +#endif /*local file playing*/ FILE *file; char filename[GF_MAX_PATH]; u32 start_range, end_range; - u32 file_size; + u64 file_size; Double duration; u32 nb_playing; Bool file_regulate; @@ -98,6 +103,10 @@ typedef struct u32 stb_at_last_pcr; u32 nb_pck; + /*remote file handling*/ + GF_DownloadSession *dnload; + Bool ts_setup; + Bool epg_requested; Bool has_eit; LPNETCHANNEL eit_channel; @@ -114,7 +123,7 @@ static GF_Err gf_dvb_tune(GF_Tuner *tuner, char *url, const char *chan_path) { int demux1, front1; FILE *chanfile; char line[255], chan_name_t[255]; - char freq_str[255], inv[255], bw[255], lcr[255], hier[255], cr[255], + char freq_str[255], inv[255], bw[255], lcr[255], hier[255], cr[255], mod[255], transm[255], gi[255], apid_str[255], vpid_str[255]; const char *chan_conf = ":%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:"; char *chan_name; @@ -122,11 +131,11 @@ static GF_Err gf_dvb_tune(GF_Tuner *tuner, char *url, const char *chan_path) { char frontend_name[100], demux_name[100], dvr_name[100]; u32 adapter_num; - chanfile = fopen(chan_path, "r"); + chanfile = gf_f64_open(chan_path, "r"); if (!chanfile) return GF_BAD_PARAM; chan_name = url+6; // 6 = strlen("dvb://") - + // support for multiple frontends tmp = strchr(chan_name, '@'); if (tmp) { @@ -143,7 +152,7 @@ static GF_Err gf_dvb_tune(GF_Tuner *tuner, char *url, const char *chan_path) { if (line[0]=='\r') continue; if (line[0]=='\n') continue; - strncpy(chan_name_t, line, index(line, ':')-line); + strncpy(chan_name_t, line, index(line, ':')-line); if (strncmp(chan_name,chan_name_t,strlen(chan_name))==0) { sscanf(strstr(line,":"), chan_conf, freq_str, inv, bw, lcr, cr, mod, transm, gi, hier, apid_str, vpid_str); tuner->freq = (uint32_t) atoi(freq_str); @@ -175,13 +184,13 @@ static GF_Err gf_dvb_tune(GF_Tuner *tuner, char *url, const char *chan_path) { else if(! strcmp(cr, "FEC_7_8")) tuner->HP_CodeRate =FEC_7_8; else if(! strcmp(cr, "FEC_NONE")) tuner->HP_CodeRate =FEC_NONE; else tuner->HP_CodeRate =FEC_AUTO; - //Modulation + //Modulation if(! strcmp(mod, "QAM_128")) tuner->modulation = QAM_128; else if(! strcmp(mod, "QAM_256")) tuner->modulation = QAM_256; else if(! strcmp(mod, "QAM_64")) tuner->modulation = QAM_64; else if(! strcmp(mod, "QAM_32")) tuner->modulation = QAM_32; else if(! strcmp(mod, "QAM_16")) tuner->modulation = QAM_16; - //Bandwidth + //Bandwidth if(! strcmp(bw, "BANDWIDTH_6_MHZ")) tuner->bandwidth = BANDWIDTH_6_MHZ; else if(! strcmp(bw, "BANDWIDTH_7_MHZ")) tuner->bandwidth = BANDWIDTH_7_MHZ; else if(! strcmp(bw, "BANDWIDTH_8_MHZ")) tuner->bandwidth = BANDWIDTH_8_MHZ; @@ -193,19 +202,19 @@ static GF_Err gf_dvb_tune(GF_Tuner *tuner, char *url, const char *chan_path) { else if(! strcmp(gi, "GUARD_INTERVAL_1_16")) tuner->guardInterval = GUARD_INTERVAL_1_16; else if(! strcmp(gi, "GUARD_INTERVAL_1_8")) tuner->guardInterval = GUARD_INTERVAL_1_8; else tuner->guardInterval = GUARD_INTERVAL_1_4; - //Hierarchy + //Hierarchy if(! strcmp(hier, "HIERARCHY_1")) tuner->hierarchy = HIERARCHY_1; else if(! strcmp(hier, "HIERARCHY_2")) tuner->hierarchy = HIERARCHY_2; - else if(! strcmp(hier, "HIERARCHY_4")) tuner->hierarchy = HIERARCHY_4; + else if(! strcmp(hier, "HIERARCHY_4")) tuner->hierarchy = HIERARCHY_4; else if(! strcmp(hier, "HIERARCHY_AUTO")) tuner->hierarchy = HIERARCHY_AUTO; else tuner->hierarchy = HIERARCHY_NONE; - + break; } } } fclose(chanfile); - + sprintf(frontend_name, "/dev/dvb/adapter%d/frontend0", adapter_num); sprintf(demux_name, "/dev/dvb/adapter%d/demux0", adapter_num); sprintf(dvr_name, "/dev/dvb/adapter%d/dvr0", adapter_num); @@ -250,7 +259,7 @@ static GF_Err gf_dvb_tune(GF_Tuner *tuner, char *url, const char *chan_path) { /* The following code differs from mplayer and alike because the device is opened in blocking mode */ if ((tuner->ts_fd = open(dvr_name, O_RDONLY/*|O_NONBLOCK*/)) < 0){ return GF_IO_ERR; - } + } return GF_OK; } #endif @@ -258,25 +267,26 @@ static GF_Err gf_dvb_tune(GF_Tuner *tuner, char *url, const char *chan_path) { static Bool M2TS_CanHandleURL(GF_InputService *plug, const char *url) { char *sExt; - - if (!strnicmp(url, "udp://", 6) - || !strnicmp(url, "mpegts-udp://", 13) - || !strnicmp(url, "mpegts-tcp://", 13) + + if (!strnicmp(url, "udp://", 6) + || !strnicmp(url, "mpegts-udp://", 13) + || !strnicmp(url, "mpegts-tcp://", 13) #ifdef GPAC_HAS_LINUX_DVB - || !strnicmp(url, "dvb://", 6) + || !strnicmp(url, "dvb://", 6) #endif ) { return 1; } - + sExt = strrchr(url, '.'); if (!sExt) return 0; if (gf_term_check_extension(plug, "video/mpeg-2", "ts m2t", "MPEG-2 TS", sExt)) return 1; + if (gf_term_check_extension(plug, "video/mp2t", "ts m2t", "MPEG-2 TS", sExt)) return 1; return 0; } #ifdef GPAC_HAS_LINUX_DVB -static u32 gf_dvb_get_freq_from_url(const char *channels_config_path, const char *url) +static u32 gf_dvb_get_freq_from_url(const char *channels_config_path, const char *url) { FILE *channels_config_file; char line[255], name[255], *tmp, *channel_name; @@ -287,9 +297,9 @@ static u32 gf_dvb_get_freq_from_url(const char *channels_config_path, const char tmp = strchr(url, '@'); if (tmp) tmp[0] = 0; - channel_name = url+6; + channel_name = url+6; - channels_config_file = fopen(channels_config_path, "r"); + channels_config_file = gf_f64_open(channels_config_path, "r"); if (!channels_config_file) return GF_BAD_PARAM; freq = 0; @@ -301,7 +311,7 @@ static u32 gf_dvb_get_freq_from_url(const char *channels_config_path, const char tmp = strchr(line, ':'); tmp[0] = 0; - if (!strcmp(line, channel_name)) { + if (!strcmp(line, channel_name)) { char *tmp2; tmp++; tmp2 = strchr(tmp, ':'); @@ -322,7 +332,7 @@ static Bool M2TS_CanHandleURLInService(GF_InputService *plug, const char *url) #ifdef GPAC_HAS_LINUX_DVB if (!stricmp(url, "dvb://EPG")) return 1; - if (!strnicmp(url, "dvb://", 6)) { + if (!strnicmp(url, "dvb://", 6)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[DVBIn] Checking reuse of the same tuner for %s\n", url)); const char *chan_conf = gf_modules_get_option((GF_BaseInterface *)plug, "DVB", "ChannelsFile"); if (!chan_conf) { @@ -339,13 +349,13 @@ static Bool M2TS_CanHandleURLInService(GF_InputService *plug, const char *url) ret = 1; } if (frag) frag[0] = '#'; - } - } else + } + } else #endif - if (!strnicmp(url, "udp://", 6) - || !strnicmp(url, "mpegts-udp://", 13) + if (!strnicmp(url, "udp://", 6) + || !strnicmp(url, "mpegts-udp://", 13) || !strnicmp(url, "mpegts-tcp://", 13)) - { + { /* TODO: check IP address ...*/ ret = 0; } else { @@ -368,32 +378,31 @@ static GF_ObjectDescriptor *MP2TS_GetOD(M2TSIn *m2ts, GF_M2TS_PES *stream, char /*create a stream description for this channel*/ esd = gf_odf_desc_esd_new(0); esd->ESID = stream->pid; - /*ASSIGN PCR here*/ - esd->OCRESID = stream->program->pcr_pid; + switch (stream->stream_type) { case GF_M2TS_VIDEO_MPEG1: esd->decoderConfig->streamType = GF_STREAM_VISUAL; - esd->decoderConfig->objectTypeIndication = 0x6A; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_MPEG1; break; case GF_M2TS_VIDEO_MPEG2: esd->decoderConfig->streamType = GF_STREAM_VISUAL; - esd->decoderConfig->objectTypeIndication = 0x65; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_MPEG2_422; break; case GF_M2TS_VIDEO_MPEG4: esd->decoderConfig->streamType = GF_STREAM_VISUAL; - esd->decoderConfig->objectTypeIndication = 0x20; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_MPEG4_PART2; break; case GF_M2TS_VIDEO_H264: esd->decoderConfig->streamType = GF_STREAM_VISUAL; - esd->decoderConfig->objectTypeIndication = 0x21; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_AVC; break; case GF_M2TS_AUDIO_MPEG1: esd->decoderConfig->streamType = GF_STREAM_AUDIO; - esd->decoderConfig->objectTypeIndication = 0x6B; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG1; break; case GF_M2TS_AUDIO_MPEG2: esd->decoderConfig->streamType = GF_STREAM_AUDIO; - esd->decoderConfig->objectTypeIndication = 0x69; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_MPEG2_PART3; break; case GF_M2TS_AUDIO_LATM_AAC: case GF_M2TS_AUDIO_AAC: @@ -406,7 +415,7 @@ static GF_ObjectDescriptor *MP2TS_GetOD(M2TSIn *m2ts, GF_M2TS_PES *stream, char return NULL; } esd->decoderConfig->streamType = GF_STREAM_AUDIO; - esd->decoderConfig->objectTypeIndication = 0x40; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; break; case GF_M2TS_SYSTEMS_MPEG4_SECTIONS: default: @@ -421,10 +430,16 @@ static GF_ObjectDescriptor *MP2TS_GetOD(M2TSIn *m2ts, GF_M2TS_PES *stream, char esd->slConfig->useRandomAccessPointFlag = 1; esd->slConfig->AUSeqNumLength = 0; esd->slConfig->timestampResolution = 90000; - + + /*ASSIGN PCR here*/ + esd->OCRESID = stream->program->pcr_pid; + if (stream->pid == stream->program->pcr_pid) { + esd->slConfig->OCRResolution = 27000000; + } + /*decoder config*/ if (dsi) { - esd->decoderConfig->decoderSpecificInfo->data = malloc(sizeof(char)*dsi_size); + esd->decoderConfig->decoderSpecificInfo->data = gf_malloc(sizeof(char)*dsi_size); memcpy(esd->decoderConfig->decoderSpecificInfo->data, dsi, sizeof(char)*dsi_size); esd->decoderConfig->decoderSpecificInfo->dataLength = dsi_size; } @@ -460,19 +475,20 @@ static void MP2TS_SetupProgram(M2TSIn *m2ts, GF_M2TS_Program *prog, Bool regener } if (!found) return; } -#endif - m2ts->file_regulate = no_declare ? 0 : 1; +#endif + if (m2ts->file || m2ts->dnload) m2ts->file_regulate = no_declare ? 0 : 1; for (i=0; i<count; i++) { GF_M2TS_ES *es = gf_list_get(prog->streams, i); if (es->pid==prog->pmt_pid) continue; - /*move to skip mode for all PES until asked for playback*/ - if (!(es->flags & GF_M2TS_ES_IS_SECTION) && !es->user) + /*move to skip mode for all ES until asked for playback*/ + if (!es->user) gf_m2ts_set_pes_framing((GF_M2TS_PES *)es, GF_M2TS_PES_FRAMING_SKIP); if (!prog->pmt_iod && !no_declare) MP2TS_DeclareStream(m2ts, (GF_M2TS_PES *)es, NULL, 0); } + /*force scene regeneration*/ - if (regenerate_scene) + if (!prog->pmt_iod && regenerate_scene) gf_term_add_media(m2ts->service, NULL, 0); } @@ -480,21 +496,18 @@ static void MP2TS_SendPacket(M2TSIn *m2ts, GF_M2TS_PES_PCK *pck) { GF_SLHeader slh; + /*pcr not initialized, don't send any data*/ + if (! pck->stream->program->first_dts) return; if (!pck->stream->user) return; - if (!pck->stream->program->first_dts && pck->PTS) { - pck->stream->program->first_dts = (pck->DTS ? pck->DTS : pck->PTS) - m2ts->start_range * 90; - } - memset(&slh, 0, sizeof(GF_SLHeader)); slh.accessUnitStartFlag = (pck->flags & GF_M2TS_PES_PCK_AU_START) ? 1 : 0; if (slh.accessUnitStartFlag) { - if (pck->PTS < pck->stream->program->first_dts) return; slh.compositionTimeStampFlag = 1; - slh.compositionTimeStamp = pck->PTS - pck->stream->program->first_dts; + slh.compositionTimeStamp = pck->PTS; if (pck->DTS) { slh.decodingTimeStampFlag = 1; - slh.decodingTimeStamp = pck->DTS - pck->stream->program->first_dts; + slh.decodingTimeStamp = pck->DTS; } slh.randomAccessPointFlag = (pck->flags & GF_M2TS_PES_PCK_RAP) ? 1 : 0; } @@ -503,10 +516,19 @@ static void MP2TS_SendPacket(M2TSIn *m2ts, GF_M2TS_PES_PCK *pck) static GFINLINE void MP2TS_SendSLPacket(M2TSIn *m2ts, GF_M2TS_SL_PCK *pck) { - gf_term_on_sl_packet(m2ts->service, pck->stream->user, pck->data, pck->data_len, NULL, GF_OK); + GF_SLHeader SLHeader, *slh = NULL; + u32 SLHdrLen = 0; + + /*build a SL Header*/ + if (((GF_M2TS_ES*)pck->stream)->slcfg) { + gf_sl_depacketize(((GF_M2TS_ES*)pck->stream)->slcfg, &SLHeader, pck->data, pck->data_len, &SLHdrLen); + SLHeader.m2ts_version_number_plus_one = pck->version_number + 1; + slh = &SLHeader; + } + gf_term_on_sl_packet(m2ts->service, pck->stream->user, pck->data+SLHdrLen, pck->data_len-SLHdrLen, slh, GF_OK); } -static GF_ObjectDescriptor *M2TS_GenerateEPG_OD(M2TSIn *m2ts) +static GF_ObjectDescriptor *M2TS_GenerateEPG_OD(M2TSIn *m2ts) { /* declaring a special stream for displaying eit */ GF_ObjectDescriptor *od; @@ -530,7 +552,7 @@ static GF_ObjectDescriptor *M2TS_GenerateEPG_OD(M2TSIn *m2ts) /*declare object to terminal*/ od = (GF_ObjectDescriptor*)gf_odf_desc_new(GF_ODF_OD_TAG); gf_list_add(od->ESDescriptors, esd); - od->objectDescriptorID = GF_M2TS_PID_EIT_ST_CIT; + od->objectDescriptorID = GF_M2TS_PID_EIT_ST_CIT; return od; } @@ -548,11 +570,11 @@ static void M2TS_FlushRequested(M2TSIn *m2ts) if (es==NULL) continue; /*move to skip mode for all PES until asked for playback*/ - if (!(es->flags & GF_M2TS_ES_IS_SECTION) && !es->user) + if (!(es->flags & GF_M2TS_ES_IS_SECTION) && !es->user) gf_m2ts_set_pes_framing((GF_M2TS_PES *)es, GF_M2TS_PES_FRAMING_SKIP); MP2TS_DeclareStream(m2ts, (GF_M2TS_PES *)es, NULL, 0); gf_list_rem(m2ts->requested_pids, i); - free(req_pid); + gf_free(req_pid); i--; count--; found++; @@ -575,8 +597,8 @@ static void M2TS_FlushRequested(M2TSIn *m2ts) if (ts_prog->number==req_prog->id) { MP2TS_SetupProgram(m2ts, ts_prog, 0, 0); found++; - free(req_prog->fragment); - free(req_prog); + gf_free(req_prog->fragment); + gf_free(req_prog); gf_list_rem(m2ts->requested_progs, i); req_prog_count--; i--; @@ -616,14 +638,14 @@ static void M2TS_OnEvent(GF_M2TS_Demuxer *ts, u32 evt_type, void *param) case GF_M2TS_EVT_PMT_FOUND: if (gf_list_count(m2ts->ts->programs) == 1) gf_term_on_connect(m2ts->service, NULL, GF_OK); - + /*do not declare if single program was requested for playback*/ MP2TS_SetupProgram(m2ts, param, m2ts->request_all_pids, m2ts->request_all_pids ? 0 : 1); M2TS_FlushRequested(m2ts); break; case GF_M2TS_EVT_PMT_REPEAT: - case GF_M2TS_EVT_PMT_UPDATE: +// case GF_M2TS_EVT_PMT_UPDATE: M2TS_FlushRequested(m2ts); break; case GF_M2TS_EVT_SDT_REPEAT: @@ -649,13 +671,25 @@ static void M2TS_OnEvent(GF_M2TS_Demuxer *ts, u32 evt_type, void *param) if (!pck->stream->first_dts) { gf_m2ts_set_pes_framing(pck->stream, GF_M2TS_PES_FRAMING_SKIP); MP2TS_DeclareStream(m2ts, pck->stream, pck->data, pck->data_len); - m2ts->file_regulate = 1; + if (m2ts->file || m2ts->dnload) m2ts->file_regulate = 1; + pck->stream->first_dts=1; /*force scene regeneration*/ gf_term_add_media(m2ts->service, NULL, 0); } } break; case GF_M2TS_EVT_PES_PCR: + /*send pcr*/ + if (((GF_M2TS_PES_PCK *) param)->stream && ((GF_M2TS_PES_PCK *) param)->stream->user) { + GF_SLHeader slh; + memset(&slh, 0, sizeof(GF_SLHeader) ); + slh.OCRflag = 1; + slh.m2ts_pcr = 1; + slh.objectClockReference = ((GF_M2TS_PES_PCK *) param)->PTS; + gf_term_on_sl_packet(m2ts->service, ((GF_M2TS_PES_PCK *) param)->stream->user, NULL, 0, &slh, GF_OK); + } + ((GF_M2TS_PES_PCK *) param)->stream->program->first_dts = 1; + if (m2ts->file_regulate) { u64 pcr = ((GF_M2TS_PES_PCK *) param)->PTS; u32 stb = gf_sys_clock(); @@ -665,12 +699,32 @@ static void M2TS_OnEvent(GF_M2TS_Demuxer *ts, u32 evt_type, void *param) pcr_diff /= 27000; diff = (u32) pcr_diff - (stb - m2ts->stb_at_last_pcr); if (diff>0 && (diff<1000) ) { + u32 sleep_for=50; +#ifndef GPAC_DISABLE_LOG + u32 nb_sleep=0; +#endif /*query buffer level, don't sleep if too low*/ GF_NetworkCommand com; com.command_type = GF_NET_BUFFER_QUERY; - gf_term_on_command(m2ts->service, &com, GF_OK); - if (com.buffer.occupancy) gf_sleep(diff); - + while (1) { + gf_term_on_command(m2ts->service, &com, GF_OK); + if (com.buffer.occupancy < M2TS_BUFFER_MAX) + break; + /*We don't sleep for the entire buffer occupancy, because we would take + the risk of starving the audio chains. We try to keep buffers half full*/ +#ifndef GPAC_DISABLE_LOG + if (!nb_sleep) { + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Demux going to sleep (buffer occupancy %d ms)\n", com.buffer.occupancy)); + } + nb_sleep++; +#endif + gf_sleep(sleep_for); + } +#ifndef GPAC_DISABLE_LOG + if (nb_sleep) { + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[M2TS In] Demux resume after %d ms - current buffer occupancy %d ms\n", sleep_for*nb_sleep, com.buffer.occupancy)); + } +#endif m2ts->nb_pck = 0; m2ts->pcr_last = pcr; m2ts->stb_at_last_pcr = gf_sys_clock(); @@ -699,13 +753,14 @@ u32 M2TS_Run(void *_p) m2ts->ts->on_event = M2TS_OnEvent; gf_m2ts_reset_parsers(m2ts->ts); + #ifdef GPAC_HAS_LINUX_DVB if (m2ts->tuner) { // in case of DVB while (m2ts->run_state) { s32 ts_size = read(m2ts->tuner->ts_fd, dvbts, DVB_BUFFER_SIZE); if (ts_size>0) gf_m2ts_process_data(m2ts->ts, dvbts, (u32) ts_size); - } + } } else #endif if (m2ts->sock) { @@ -717,7 +772,7 @@ u32 M2TS_Run(void *_p) /*m2ts chunks by chunks*/ e = gf_sk_receive(m2ts->sock, data, UDP_BUFFER_SIZE, 0, &size); if (!size || e) { - gf_sleep(1); + gf_sleep(0); continue; } if (first_run) { @@ -734,11 +789,16 @@ u32 M2TS_Run(void *_p) gf_m2ts_process_data(m2ts->ts, data, size); } } - } else { - u32 pos = 0; + } else if (m2ts->dnload) { + while (m2ts->run_state) { + gf_dm_sess_process(m2ts->dnload); + gf_sleep(1); + } + } else if (m2ts->file) { + u64 pos = 0; if (m2ts->start_range && m2ts->duration) { Double perc = m2ts->start_range / (1000 * m2ts->duration); - pos = (u32) (s64) (perc * m2ts->file_size); + pos = (u64) (perc * m2ts->file_size); /*align to TS packet size*/ while (pos%188) pos++; if (pos>=m2ts->file_size) { @@ -746,7 +806,8 @@ u32 M2TS_Run(void *_p) pos = 0; } } - fseek(m2ts->file, pos, SEEK_SET); + gf_f64_seek(m2ts->file, pos, SEEK_SET); +restart_file: while (m2ts->run_state && !feof(m2ts->file) ) { /*m2ts chunks by chunks*/ size = fread(data, 1, 188, m2ts->file); @@ -756,11 +817,28 @@ u32 M2TS_Run(void *_p) m2ts->nb_pck++; /*if asked to regulate, wait until we get a play request*/ - while (m2ts->run_state && !m2ts->nb_playing && m2ts->file_regulate) { - gf_sleep(50); - continue; + if (m2ts->run_state && !m2ts->nb_playing && m2ts->file_regulate) { + while (m2ts->run_state && !m2ts->nb_playing && m2ts->file_regulate) { + gf_sleep(50); + continue; + } + } else if (m2ts->file) { + gf_sleep(1); } } + + if (feof(m2ts->file) && m2ts->owner && m2ts->owner->query_proxy) { + GF_NetworkCommand param; + fclose(m2ts->file); + m2ts->file = NULL; + param.command_type = GF_NET_SERVICE_QUERY_NEXT; + if ((m2ts->owner->query_proxy(m2ts->owner, ¶m)==GF_OK) && param.url_query.next_url){ + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("\nSegment switch detected - now playing %s\n", param.url_query.next_url)); + m2ts->file = gf_f64_open(param.url_query.next_url, "rb"); + if (m2ts->file) goto restart_file; + } + } + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("\nEOS reached\n")); if (m2ts->nb_playing) { for (i=0; i<GF_M2TS_MAX_STREAMS; i++) { @@ -771,7 +849,6 @@ u32 M2TS_Run(void *_p) gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_SKIP); } } - } m2ts->run_state = 2; return 0; @@ -809,13 +886,13 @@ void M2TS_SetupDVB(GF_InputService *plug, M2TSIn *m2ts, char *url) e = GF_SERVICE_ERROR; goto exit; } - + if (!m2ts->tuner) GF_SAFEALLOC(m2ts->tuner, GF_Tuner); if (m2ts->tuner->freq != 0 && m2ts->tuner->freq == gf_dvb_get_freq_from_url(chan_conf, url)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[DVBIn] Tuner already tuned to that frequency\n")); goto exit; - } + } e = gf_dvb_tune(m2ts->tuner, url, chan_conf); if (e) goto exit; @@ -829,6 +906,45 @@ exit: } #endif +void m2ts_net_io(void *cbk, GF_NETIO_Parameter *param) +{ + GF_Err e; + M2TSIn *m2ts = (M2TSIn *) cbk; + + /*handle service message*/ + gf_term_download_update_stats(m2ts->dnload); + + if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { + e = GF_EOS; + } else if (param->msg_type==GF_NETIO_DATA_EXCHANGE) { + e = GF_OK; + /*process chunk*/ + gf_m2ts_process_data(m2ts->ts, param->data, param->size); + + /*if asked to regulate, wait until we get a play request*/ + if (m2ts->run_state && !m2ts->nb_playing && m2ts->file_regulate) { + while (m2ts->run_state && !m2ts->nb_playing && m2ts->file_regulate) { + gf_sleep(50); + continue; + } + } else { + gf_sleep(1); + } + + } else { + e = param->error; + } + + if (e<GF_OK) { + /*error opening service*/ + if (!m2ts->ts_setup) { + m2ts->ts_setup = 1; + gf_term_on_connect(m2ts->service, NULL, e); + } + return; + } +} + void M2TS_SetupLive(GF_InputService *plug, M2TSIn *m2ts, char *url) { GF_Err e = GF_OK; @@ -876,6 +992,8 @@ void M2TS_SetupLive(GF_InputService *plug, M2TSIn *m2ts, char *url) } else { gf_sk_bind(m2ts->sock, (char*)mob_ip, port, url, 0, GF_SOCK_REUSE_PORT); } + } else { + gf_sk_bind(m2ts->sock, NULL, port, NULL, 0, GF_SOCK_REUSE_PORT); } if (str) str[0] = ':'; @@ -883,7 +1001,6 @@ void M2TS_SetupLive(GF_InputService *plug, M2TSIn *m2ts, char *url) gf_sk_set_block_mode(m2ts->sock, 0); m2ts->th = gf_th_new("MPEG-2 TS Demux"); - gf_th_set_priority(m2ts->th, GF_THREAD_PRIORITY_HIGHEST); /*start playing for tune-in*/ gf_th_run(m2ts->th, M2TS_Run, m2ts); @@ -897,26 +1014,26 @@ void M2TS_SetupFile(M2TSIn *m2ts, char *url) { #if 0 char data[188]; - u32 size, fsize; + u64 size, fsize; s32 nb_rwd; #endif if (m2ts->file && !strcmp(m2ts->filename, url)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEGTSIn] TS already being processed\n")); return; - } + } - m2ts->file = fopen(url, "rb"); + m2ts->file = gf_f64_open(url, "rb"); if (!m2ts->file) { gf_term_on_connect(m2ts->service, NULL, GF_URL_ERROR); return; } strcpy(m2ts->filename, url); - fseek(m2ts->file, 0, SEEK_END); - m2ts->file_size = ftell(m2ts->file); - + gf_f64_seek(m2ts->file, 0, SEEK_END); + m2ts->file_size = gf_f64_tell(m2ts->file); + #if 0 - /* + /* estimate duration by reading the end of the file m2ts->end_range is initialized to the PTS of the last TS packet m2ts->nb_playing is initialized to the PID of the last TS packet @@ -928,7 +1045,7 @@ void M2TS_SetupFile(M2TSIn *m2ts, char *url) fsize = m2ts->file_size; while (fsize % 188) fsize--; while (1) { - fseek(m2ts->file, fsize - 188 * nb_rwd, SEEK_SET); + gf_f64_seek(m2ts->file, fsize - 188 * nb_rwd, SEEK_SET); /*m2ts chunks by chunks*/ size = fread(data, 1, 188, m2ts->file); if (!size) break; @@ -938,11 +1055,11 @@ void M2TS_SetupFile(M2TSIn *m2ts, char *url) nb_rwd ++; } - /* - reset of the file - initialization of m2ts->start_range to the PTS of the first TS packet with PID = m2ts->nb_playing + /* + reset of the file + initialization of m2ts->start_range to the PTS of the first TS packet with PID = m2ts->nb_playing */ - fseek(m2ts->file, 0, SEEK_SET); + gf_f64_seek(m2ts->file, 0, SEEK_SET); gf_m2ts_reset_parsers(m2ts->ts); m2ts->start_range = 0; while (1) { @@ -975,6 +1092,7 @@ static GF_Err M2TS_ConnectService(GF_InputService *plug, GF_ClientService *serv, char szURL[2048]; char *frag; M2TSIn *m2ts = plug->priv; + m2ts->owner = plug; m2ts->service = serv; strcpy(szURL, url); @@ -985,17 +1103,26 @@ static GF_Err M2TS_ConnectService(GF_InputService *plug, GF_ClientService *serv, m2ts->duration = 0; if (!strnicmp(url, "udp://", 6) - || !strnicmp(url, "mpegts-udp://", 13) - || !strnicmp(url, "mpegts-tcp://", 13) + || !strnicmp(url, "mpegts-udp://", 13) + || !strnicmp(url, "mpegts-tcp://", 13) ) { M2TS_SetupLive(plug, m2ts, (char *) szURL); - } + } #ifdef GPAC_HAS_LINUX_DVB else if (!strnicmp(url, "dvb://", 6)) { // DVB Setup M2TS_SetupDVB(plug, m2ts, (char *) szURL); - } + } #endif + else if (!strnicmp(url, "http://", 7)) { + m2ts->dnload = gf_term_download_new(m2ts->service, url, GF_NETIO_SESSION_NOT_THREADED | GF_NETIO_SESSION_NOT_CACHED, m2ts_net_io, m2ts); + if (!m2ts->dnload) gf_term_on_connect(m2ts->service, NULL, GF_NOT_SUPPORTED); + else { + m2ts->th = gf_th_new("MPEG-2 TS Demux"); + /*start playing for tune-in*/ + gf_th_run(m2ts->th, M2TS_Run, m2ts); + } + } else { M2TS_SetupFile(m2ts, (char *) szURL); } @@ -1018,6 +1145,10 @@ static GF_Err M2TS_CloseService(GF_InputService *plug) if (m2ts->file) fclose(m2ts->file); m2ts->file = NULL; + + if (m2ts->dnload) gf_term_download_del(m2ts->dnload); + m2ts->dnload = NULL; + gf_term_on_disconnect(m2ts->service, NULL, GF_OK); return GF_OK; } @@ -1029,14 +1160,17 @@ static GF_Descriptor *M2TS_GetServiceDesc(GF_InputService *plug, u32 expect_type char *frag; frag = sub_url ? strrchr(sub_url, '#') : NULL; - /*we have been requested the entire TS*/ - if (!stricmp(sub_url, "dvb://EPG")) { - m2ts->epg_requested = 1; - } else if (!frag) { + if (frag) frag++; + + /* consider the channel name in DVB URL as a fragment */ + if (!frag && !strncmp(sub_url, "dvb://", 6)) { + frag = (char*)sub_url + 6; + } + + if (!frag) { m2ts->request_all_pids = 1; } else { M2TSIn_Prog *prog; - frag++; /*we need exclusive access*/ gf_mx_p(m2ts->mx); @@ -1059,20 +1193,20 @@ static GF_Descriptor *M2TS_GetServiceDesc(GF_InputService *plug, u32 expect_type if (!prog) { GF_SAFEALLOC(prog, M2TSIn_Prog); gf_list_add(m2ts->requested_progs, prog); - prog->fragment = strdup(frag); + prog->fragment = gf_strdup(frag); } } gf_mx_v(m2ts->mx); } - if (expect_type==GF_MEDIA_OBJECT_SCENE) { + if (expect_type==GF_MEDIA_OBJECT_SCENE) { if (gf_list_count(m2ts->ts->programs) == 1) { GF_M2TS_Program *prog = gf_list_get(m2ts->ts->programs, 0); if (prog->pmt_iod) { gf_odf_desc_copy((GF_Descriptor *)prog->pmt_iod, &desc); return desc; } - } + } if (m2ts->epg_requested) { GF_ObjectDescriptor *od = M2TS_GenerateEPG_OD(m2ts); m2ts->epg_requested = 0; @@ -1085,6 +1219,12 @@ static GF_Descriptor *M2TS_GetServiceDesc(GF_InputService *plug, u32 expect_type } } + /* restart the thread if the same service is reused and if the previous thread terminated */ + if (m2ts->run_state == 2) { + m2ts->file_regulate = 0; + gf_th_run(m2ts->th, M2TS_Run, m2ts); + } + return NULL; } @@ -1097,11 +1237,12 @@ static GF_Err M2TS_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, c e = GF_STREAM_NOT_FOUND; if (strstr(url, "ES_ID")) { sscanf(url, "ES_ID=%d", &ES_ID); - + /* In case there is a real IOD, we need to translate PID into ESID */ if (gf_list_count(m2ts->ts->programs) == 1) { GF_M2TS_Program *prog = gf_list_get(m2ts->ts->programs, 0); if (prog->pmt_iod) { + /* IOD is present */ u32 i; for (i=0; i<GF_M2TS_MAX_STREAMS; i++) { GF_M2TS_PES *pes = (GF_M2TS_PES *)m2ts->ts->ess[i]; @@ -1119,9 +1260,12 @@ static GF_Err M2TS_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, c } } } + /* Stream not found */ + return e; } - } + } + /* No IOD */ if (ES_ID == 18) { e = GF_OK; /* 18 is the PID of EIT packets */ m2ts->eit_channel = channel; @@ -1195,6 +1339,8 @@ static GF_Err M2TS_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) } return GF_STREAM_NOT_FOUND; } + /*mark pcr as not initialized*/ + if (pes->program->pcr_pid==pes->pid) pes->program->first_dts=0; gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_DEFAULT); GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("Setting default reframing\n")); /*this is a multplex, only trigger the play command for the first stream activated*/ @@ -1217,14 +1363,27 @@ static GF_Err M2TS_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) return GF_STREAM_NOT_FOUND; } gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_SKIP); - /*FIXME HOORIBLE HACK*/ - return GF_OK; assert(m2ts->nb_playing); m2ts->nb_playing--; /*stop demuxer*/ if (!m2ts->nb_playing && (m2ts->run_state==1)) { m2ts->run_state=0; while (m2ts->run_state!=2) gf_sleep(2); + if (gf_list_count(m2ts->requested_progs)) { + m2ts->file_regulate = 0; + gf_th_run(m2ts->th, M2TS_Run, m2ts); + } + } + return GF_OK; + case GF_NET_CHAN_CONFIG: + pes = M2TS_GetChannel(m2ts, com->base.on_channel); + /*filter all sections carrying SL data for the app to signal the version number of the section*/ + if (pes && pes->flags & GF_M2TS_ES_IS_SECTION) { + if (pes->slcfg) gf_free(pes->slcfg); + pes->slcfg = gf_malloc(sizeof(GF_SLConfig)); + memcpy(pes->slcfg, &com->cfg.sl_config, sizeof(GF_SLConfig)); + com->cfg.use_m2ts_sections = 1; + pes->flags |= GF_M2TS_ES_SEND_REPEATED_SECTIONS; } return GF_OK; default: @@ -1236,7 +1395,7 @@ static GF_Err M2TS_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) GF_InputService *NewM2TSReader() { M2TSIn *reader; - GF_InputService *plug = malloc(sizeof(GF_InputService)); + GF_InputService *plug = gf_malloc(sizeof(GF_InputService)); memset(plug, 0, sizeof(GF_InputService)); GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC MPEG-2 TS Reader", "gpac distribution") @@ -1249,7 +1408,7 @@ GF_InputService *NewM2TSReader() plug->DisconnectChannel = M2TS_DisconnectChannel; plug->ServiceCommand = M2TS_ServiceCommand; - reader = malloc(sizeof(M2TSIn)); + reader = gf_malloc(sizeof(M2TSIn)); memset(reader, 0, sizeof(M2TSIn)); plug->priv = reader; reader->requested_progs = gf_list_new(); @@ -1271,35 +1430,43 @@ void DeleteM2TSReader(void *ifce) count = gf_list_count(m2ts->requested_progs); for (i = 0; i < count; i++) { M2TSIn_Prog *prog = gf_list_get(m2ts->requested_progs, i); - free(prog->fragment); - free(prog); + gf_free(prog->fragment); + gf_free(prog); } gf_list_del(m2ts->requested_progs); count = gf_list_count(m2ts->requested_pids); for (i = 0; i < count; i++) { M2TSIn_Prog *prog = gf_list_get(m2ts->requested_pids, i); - free(prog); + gf_free(prog); } gf_list_del(m2ts->requested_pids); gf_m2ts_demux_del(m2ts->ts); gf_mx_del(m2ts->mx); - free(m2ts); - free(plug); + gf_free(m2ts); + gf_free(plug); } +#endif + -Bool QueryInterface(u32 InterfaceType) +GF_EXPORT +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_NET_CLIENT_INTERFACE: return 1; - default: return 0; - } + static u32 si [] = { +#ifndef GPAC_DISABLE_MPEG2TS + GF_NET_CLIENT_INTERFACE, +#endif + 0 + }; + return si; } GF_BaseInterface *LoadInterface(u32 InterfaceType) { switch (InterfaceType) { +#ifndef GPAC_DISABLE_MPEG2TS case GF_NET_CLIENT_INTERFACE: return (GF_BaseInterface *) NewM2TSReader(); +#endif default: return NULL; } } @@ -1307,6 +1474,8 @@ GF_BaseInterface *LoadInterface(u32 InterfaceType) void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_MPEG2TS case GF_NET_CLIENT_INTERFACE: DeleteM2TSReader(ifce); break; +#endif } } diff --git a/modules/mpegts_in/mpegts_in.def b/modules/mpegts_in/mpegts_in.def deleted file mode 100644 index 0159b44..0000000 --- a/modules/mpegts_in/mpegts_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_mpegts_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/odf_dec/Makefile b/modules/odf_dec/Makefile index f888c63..053858a 100644 --- a/modules/odf_dec/Makefile +++ b/modules/odf_dec/Makefile @@ -21,20 +21,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_odf_dec.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols odf_dec.def +#LDFLAGS+=-export-symbols odf_dec.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_odf_dec-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/odf_dec/odf_dec.c b/modules/odf_dec/odf_dec.c index 6a7fe0e..332e853 100644 --- a/modules/odf_dec/odf_dec.c +++ b/modules/odf_dec/odf_dec.c @@ -27,7 +27,7 @@ typedef struct { - GF_InlineScene *scene; + GF_Scene *scene; u32 PL; } ODPriv; @@ -43,27 +43,27 @@ static GF_Err ODF_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapability } -static GF_Err ODF_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_inline_scene) +static GF_Err ODF_AttachScene(GF_SceneDecoder *plug, GF_Scene *scene, Bool is_inline_scene) { ODPriv *priv = (ODPriv *)plug->privateStack; if (!priv->scene) priv->scene = scene; return GF_OK; } -static void ODS_SetupOD(GF_InlineScene *is, GF_ObjectDescriptor *od) +static void ODS_SetupOD(GF_Scene *scene, GF_ObjectDescriptor *od) { GF_ObjectManager *odm; - odm = gf_inline_find_odm(is, od->objectDescriptorID); + odm = gf_scene_find_odm(scene, od->objectDescriptorID); /*remove the old OD*/ if (odm) gf_odm_disconnect(odm, 1); odm = gf_odm_new(); odm->OD = od; - odm->term = is->root_od->term; - odm->parentscene = is; - gf_list_add(is->ODlist, odm); + odm->term = scene->root_od->term; + odm->parentscene = scene; + gf_list_add(scene->resources, odm); /*locate service owner*/ - gf_odm_setup_object(odm, is->root_od->net_service); + gf_odm_setup_object(odm, scene->root_od->net_service); } static GF_Err ODS_ODUpdate(ODPriv *priv, GF_ODUpdate *odU) @@ -90,7 +90,7 @@ static GF_Err ODS_RemoveOD(ODPriv *priv, GF_ODRemove *odR) { u32 i; for (i=0; i< odR->NbODs; i++) { - GF_ObjectManager *odm = gf_inline_find_odm(priv->scene, odR->OD_ID[i]); + GF_ObjectManager *odm = gf_scene_find_odm(priv->scene, odR->OD_ID[i]); if (odm) gf_odm_disconnect(odm, 1); } return GF_OK; @@ -102,7 +102,7 @@ static GF_Err ODS_UpdateESD(ODPriv *priv, GF_ESDUpdate *ESDs) GF_ObjectManager *odm; u32 count, i; - odm = gf_inline_find_odm(priv->scene, ESDs->ODID); + odm = gf_scene_find_odm(priv->scene, ESDs->ODID); /*spec: "ignore"*/ if (!odm) return GF_OK; @@ -130,7 +130,7 @@ static GF_Err ODS_UpdateESD(ODPriv *priv, GF_ESDUpdate *ESDs) } /*resetup object since a new ES has been inserted (typically an empty object first sent, then a stream added - cf how ogg demuxer works)*/ - gf_inline_setup_object(priv->scene, odm); + gf_scene_setup_object(priv->scene, odm); return GF_OK; } @@ -139,7 +139,7 @@ static GF_Err ODS_RemoveESD(ODPriv *priv, GF_ESDRemove *ESDs) { GF_ObjectManager *odm; u32 i; - odm = gf_inline_find_odm(priv->scene, ESDs->ODID); + odm = gf_scene_find_odm(priv->scene, ESDs->ODID); /*spec: "ignore"*/ if (!odm) return GF_OK; @@ -250,8 +250,8 @@ Bool ODF_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, u32 ObjectType, c void DeleteODDec(GF_BaseDecoder *plug) { ODPriv *priv = (ODPriv *)plug->privateStack; - free(priv); - free(plug); + gf_free(priv); + gf_free(plug); } GF_BaseDecoder *NewODDec() @@ -278,14 +278,13 @@ GF_BaseDecoder *NewODDec() GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_SCENE_DECODER_INTERFACE: - return 1; - default: - return 0; - } + static u32 si [] = { + GF_SCENE_DECODER_INTERFACE, + 0 + }; + return si; } GF_EXPORT diff --git a/modules/odf_dec/odf_dec.def b/modules/odf_dec/odf_dec.def deleted file mode 100644 index 9aa20e6..0000000 --- a/modules/odf_dec/odf_dec.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_odf_dec.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/ogg/Makefile b/modules/ogg/Makefile index 8d0f645..141d50f 100644 --- a/modules/ogg/Makefile +++ b/modules/ogg/Makefile @@ -58,21 +58,15 @@ endif LIB=gm_ogg_xiph.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols ogg.def +#LDFLAGS+=-export-symbols ogg.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif - all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L$(LOCAL_LIB) $(LINKLIBS) %.o: %.c diff --git a/modules/ogg/ogg.def b/modules/ogg/ogg.def deleted file mode 100644 index 9e6988b..0000000 --- a/modules/ogg/ogg.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_ogg_xiph.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/ogg/ogg_in.c b/modules/ogg/ogg_in.c index 2f9acad..4cfafbc 100644 --- a/modules/ogg/ogg_in.c +++ b/modules/ogg/ogg_in.c @@ -25,6 +25,8 @@ #include "ogg_in.h" #include <ogg/ogg.h> +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_OGG) + typedef struct { u32 streamType; /*MPEG-4 streamType*/ @@ -69,7 +71,7 @@ typedef struct GF_List *streams; FILE *ogfile; - u32 file_size; + u64 file_size; Bool is_remote, is_inline; u32 nb_playing, kill_demux, do_seek, service_type, init_remain, bos_done; @@ -122,7 +124,7 @@ static Bool OGG_ReadPage(OGGReader *read, ogg_page *oggpage) else if (!read->is_live && !read->ogfile) { const char *szCache = gf_dm_sess_get_cache_name(read->dnload); if (!szCache) return 0; - read->ogfile = fopen((char *) szCache, "rb"); + read->ogfile = gf_f64_open((char *) szCache, "rb"); if (!read->ogfile) return 0; } } @@ -183,7 +185,7 @@ static GF_ObjectDescriptor *OGG_GetOD(OGGStream *st) else esd->slConfig->useRandomAccessPointFlag = 1; esd->decoderConfig->decoderSpecificInfo->dataLength = st->dsi_len; - esd->decoderConfig->decoderSpecificInfo->data = (char *) malloc(sizeof(char) * st->dsi_len); + esd->decoderConfig->decoderSpecificInfo->data = (char *) gf_malloc(sizeof(char) * st->dsi_len); memcpy(esd->decoderConfig->decoderSpecificInfo->data, st->dsi, sizeof(char) * st->dsi_len); gf_list_add(od->ESDescriptors, esd); return od; @@ -354,7 +356,7 @@ static void OGG_NewStream(OGGReader *read, ogg_page *oggpage) || ((read->service_type==2) && (st->info.streamType==GF_STREAM_VISUAL)) ) { ogg_stream_clear(&st->os); - free(st); + gf_free(st); return; } @@ -461,7 +463,7 @@ void OGG_Process(OGGReader *read) bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); if (st->dsi) { gf_bs_write_data(bs, st->dsi, st->dsi_len); - free(st->dsi); + gf_free(st->dsi); st->dsi = NULL; st->dsi_len=0; } @@ -562,10 +564,10 @@ static u32 OggDemux(void *par) u32 seek_to = 0; read->resync_stream = NULL; if (read->dur) seek_to = (u32) (read->file_size * (read->start_range/read->dur) * 0.6f); - if ((s32) seek_to > ftell(read->ogfile) ) { - fseek(read->ogfile, seek_to, SEEK_SET); + if ((s32) seek_to > gf_f64_tell(read->ogfile) ) { + gf_f64_seek(read->ogfile, seek_to, SEEK_SET); } else { - fseek(read->ogfile, 0, SEEK_SET); + gf_f64_seek(read->ogfile, 0, SEEK_SET); } } } @@ -605,7 +607,7 @@ Bool OGG_CheckFile(OGGReader *read) ogg_stream_state os, the_os; u64 max_gran; Bool has_stream = 0; - fseek(read->ogfile, 0, SEEK_SET); + gf_f64_seek(read->ogfile, 0, SEEK_SET); ogg_sync_init(&read->oy); memset(&the_info, 0, sizeof(OGGInfo)); @@ -639,8 +641,8 @@ Bool OGG_CheckFile(OGGReader *read) } } ogg_sync_clear(&read->oy); - read->file_size = ftell(read->ogfile); - fseek(read->ogfile, 0, SEEK_SET); + read->file_size = gf_f64_tell(read->ogfile); + gf_f64_seek(read->ogfile, 0, SEEK_SET); read->dur = 0; if (has_stream) { ogg_stream_clear(&the_os); @@ -732,7 +734,7 @@ static GF_Err OGG_ConnectService(GF_InputService *plug, GF_ClientService *serv, OGG_DownloadFile(plug, szURL); return GF_OK; } else { - read->ogfile = fopen(szURL, "rb"); + read->ogfile = gf_f64_open(szURL, "rb"); if (!read->ogfile) { reply = GF_URL_ERROR; } else { @@ -929,7 +931,7 @@ static Bool OGG_CanHandleURLInService(GF_InputService *plug, const char *url) GF_InputService *OGG_LoadDemux() { OGGReader *reader; - GF_InputService *plug = malloc(sizeof(GF_InputService)); + GF_InputService *plug = gf_malloc(sizeof(GF_InputService)); memset(plug, 0, sizeof(GF_InputService)); GF_REGISTER_MODULE_INTERFACE(plug, GF_NET_CLIENT_INTERFACE, "GPAC OGG Reader", "gpac distribution") @@ -942,7 +944,7 @@ GF_InputService *OGG_LoadDemux() plug->ServiceCommand = OGG_ServiceCommand; plug->CanHandleURLInService = OGG_CanHandleURLInService; - reader = malloc(sizeof(OGGReader)); + reader = gf_malloc(sizeof(OGGReader)); memset(reader, 0, sizeof(OGGReader)); reader->streams = gf_list_new(); reader->demuxer = gf_th_new("OGGDemux"); @@ -963,10 +965,12 @@ void OGG_DeleteDemux(void *ifce) OGGStream *st = gf_list_get(read->streams, 0); gf_list_rem(read->streams, 0); ogg_stream_clear(&st->os); - if (st->dsi) free(st->dsi); - free(st); + if (st->dsi) gf_free(st->dsi); + gf_free(st); } gf_list_del(read->streams); - free(read); - free(plug); + gf_free(read); + gf_free(plug); } + +#endif /* !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_OGG)*/ diff --git a/modules/ogg/ogg_load.c b/modules/ogg/ogg_load.c index 4c507de..2b7fcf4 100644 --- a/modules/ogg/ogg_load.c +++ b/modules/ogg/ogg_load.c @@ -86,21 +86,28 @@ void DeleteOGGDecoder(GF_BaseDecoder *ifcd) default: break; } - free(wrap); - free(ifcd); + gf_free(wrap); + gf_free(ifcd); } -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_NET_CLIENT_INTERFACE) return 1; - if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1; - return 0; + static u32 si [] = { +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_OGG) + GF_NET_CLIENT_INTERFACE, +#endif + GF_MEDIA_DECODER_INTERFACE, + 0 + }; + return si; } GF_BaseInterface *LoadInterface(u32 InterfaceType) { +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_OGG) if (InterfaceType == GF_NET_CLIENT_INTERFACE) return (GF_BaseInterface *)OGG_LoadDemux(); +#endif if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)OGG_LoadDecoder(); return NULL; } @@ -108,9 +115,11 @@ GF_BaseInterface *LoadInterface(u32 InterfaceType) void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined(GPAC_DISABLE_OGG) case GF_NET_CLIENT_INTERFACE: OGG_DeleteDemux(ifce); break; +#endif case GF_MEDIA_DECODER_INTERFACE: DeleteOGGDecoder((GF_BaseDecoder *) ifce); break; diff --git a/modules/ogg/theora_dec.c b/modules/ogg/theora_dec.c index 721057d..43df4cf 100644 --- a/modules/ogg/theora_dec.c +++ b/modules/ogg/theora_dec.c @@ -69,14 +69,14 @@ static GF_Err THEO_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); while (gf_bs_available(bs)) { oggpacket.bytes = gf_bs_read_u16(bs); - oggpacket.packet = malloc(sizeof(char) * oggpacket.bytes); + oggpacket.packet = gf_malloc(sizeof(char) * oggpacket.bytes); gf_bs_read_data(bs, oggpacket.packet, oggpacket.bytes); if (theora_decode_header(&ctx->ti, &ctx->tc, &oggpacket) < 0 ) { - free(oggpacket.packet); + gf_free(oggpacket.packet); gf_bs_del(bs); return GF_NON_COMPLIANT_BITSTREAM; } - free(oggpacket.packet); + gf_free(oggpacket.packet); } theora_decode_init(&ctx->td, &ctx->ti); gf_bs_del(bs); @@ -227,7 +227,7 @@ u32 NewTheoraDecoder(GF_BaseDecoder *ifcd) void DeleteTheoraDecoder(GF_BaseDecoder *ifcg) { THEORACTX(); - free(ctx); + gf_free(ctx); } #endif diff --git a/modules/ogg/vorbis_dec.c b/modules/ogg/vorbis_dec.c index 70662ae..517f5ba 100644 --- a/modules/ogg/vorbis_dec.c +++ b/modules/ogg/vorbis_dec.c @@ -68,14 +68,14 @@ static GF_Err VORB_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); while (gf_bs_available(bs)) { oggpacket.bytes = gf_bs_read_u16(bs); - oggpacket.packet = malloc(sizeof(char) * oggpacket.bytes); + oggpacket.packet = gf_malloc(sizeof(char) * oggpacket.bytes); gf_bs_read_data(bs, oggpacket.packet, oggpacket.bytes); if (vorbis_synthesis_headerin(&ctx->vi, &ctx->vc, &oggpacket) < 0 ) { - free(oggpacket.packet); + gf_free(oggpacket.packet); gf_bs_del(bs); return GF_NON_COMPLIANT_BITSTREAM; } - free(oggpacket.packet); + gf_free(oggpacket.packet); } vorbis_synthesis_init(&ctx->vd, &ctx->vi); vorbis_block_init(&ctx->vd, &ctx->vb); @@ -262,7 +262,7 @@ u32 NewVorbisDecoder(GF_BaseDecoder *ifcd) void DeleteVorbisDecoder(GF_BaseDecoder *ifcg) { VORBISCTX(); - free(ctx); + gf_free(ctx); } #endif diff --git a/modules/opencv_is/Makefile b/modules/opencv_is/Makefile new file mode 100644 index 0000000..8e4b35b --- /dev/null +++ b/modules/opencv_is/Makefile @@ -0,0 +1,59 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/opencv_is + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +#common obj +OBJS= opencv.o + +SRCS := $(OBJS:.o=.c) + +LDFLAGS+=-lcv -lcvaux -lhighgui -lcxcore + +LIB=gm_opencv.$(DYN_LIB_SUFFIX) +ifeq ($(CONFIG_WIN32),yes) +#LDFLAGS+=-export-symbols opencv.def +endif + + +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) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/opencv_is/demo-sensor.bt b/modules/opencv_is/demo-sensor.bt new file mode 100644 index 0000000..8c61337 --- /dev/null +++ b/modules/opencv_is/demo-sensor.bt @@ -0,0 +1,93 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 640 + pixelHeight 480 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of a demo InputSensor" "" "GPAC Regression Tests" "$Date: 2009-06-22 15:54:46 $ - $Revision: 1.1 $" "(C) 2009 ENST"] + title "InputSensor Test - Demo device" + } + DEF TR Transform2D { + translation 0 0 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TEXT Text { + string ["Demo Tracker", ""] + fontStyle FontStyle { + justify ["BEGIN" "MIDDLE"] + size 30 + } + } + } + ] + } + DEF V Valuator {} + + InputSensor { + url [od:10] + buffer { + REPLACE TR.translation BY 0 0 + } + } + ] +} + +ROUTE TR.translation TO V.inSFVec2f +ROUTE V.outMFString TO TEXT.string + + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 5 + decConfigDescr DecoderConfigDescriptor { + streamType 10 + decSpecificInfo UIConfig { + deviceName "OpenCV" + } + } + } + ] + } + ] +} + diff --git a/modules/opencv_is/haarcascade_frontalface_default.xml b/modules/opencv_is/haarcascade_frontalface_default.xml new file mode 100644 index 0000000..8dff079 --- /dev/null +++ b/modules/opencv_is/haarcascade_frontalface_default.xml @@ -0,0 +1,35712 @@ +<?xml version="1.0"?> +<!-- + Stump-based 24x24 discrete(?) adaboost frontal face detector. + Created by Rainer Lienhart. + +//////////////////////////////////////////////////////////////////////////////////////// + + IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. + + By downloading, copying, installing or using the software you agree to this license. + If you do not agree to this license, do not download, install, + copy or use the software. + + + Intel License Agreement + For Open Source Computer Vision Library + + Copyright (C) 2000, Intel Corporation, all rights reserved. + Third party copyrights are property of their respective owners. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistribution's of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistribution's in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * The name of Intel Corporation may not be used to endorse or promote products + derived from this software without specific prior written permission. + + This software is provided by the copyright holders and contributors "as is" and + any express or implied warranties, including, but not limited to, the implied + warranties of merchantability and fitness for a particular purpose are disclaimed. + In no event shall the Intel Corporation or contributors be liable for any direct, + indirect, incidental, special, exemplary, or consequential damages + (including, but not limited to, procurement of substitute goods or services; + loss of use, data, or profits; or business interruption) however caused + and on any theory of liability, whether in contract, strict liability, + or tort (including negligence or otherwise) arising in any way out of + the use of this software, even if advised of the possibility of such damage. +--> +<opencv_storage> +<haarcascade_frontalface_default type_id="opencv-haar-classifier"> + <size>24 24</size> + <stages> + <_> + <!-- stage 0 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 9 -1.</_> + <_>6 7 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0315119996666908</threshold> + <left_val>2.0875380039215088</left_val> + <right_val>-2.2172100543975830</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 7 -1.</_> + <_>10 4 4 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0123960003256798</threshold> + <left_val>-1.8633940219879150</left_val> + <right_val>1.3272049427032471</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 18 9 -1.</_> + <_>3 12 18 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0219279993325472</threshold> + <left_val>-1.5105249881744385</left_val> + <right_val>1.0625729560852051</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 9 6 -1.</_> + <_>8 20 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.7529998011887074e-003</threshold> + <left_val>-0.8746389746665955</left_val> + <right_val>1.1760339736938477</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 4 19 -1.</_> + <_>5 5 2 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0150140002369881</threshold> + <left_val>-0.7794569730758667</left_val> + <right_val>1.2608419656753540</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 12 16 -1.</_> + <_>6 13 12 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0993710011243820</threshold> + <left_val>0.5575129985809326</left_val> + <right_val>-1.8743000030517578</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 12 6 -1.</_> + <_>5 11 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.7340000960975885e-003</threshold> + <left_val>-1.6911929845809937</left_val> + <right_val>0.4400970041751862</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 14 4 10 -1.</_> + <_>11 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0188590008765459</threshold> + <left_val>-1.4769539833068848</left_val> + <right_val>0.4435009956359863</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 7 6 -1.</_> + <_>4 3 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.9739998541772366e-003</threshold> + <left_val>-0.8590919971466065</left_val> + <right_val>0.8525559902191162</right_val></_></_></trees> + <stage_threshold>-5.0425500869750977</stage_threshold> + <parent>-1</parent> + <next>-1</next></_> + <_> + <!-- stage 1 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 6 -1.</_> + <_>6 8 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0211100000888109</threshold> + <left_val>1.2435649633407593</left_val> + <right_val>-1.5713009834289551</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 7 -1.</_> + <_>10 4 4 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0203559994697571</threshold> + <left_val>-1.6204780340194702</left_val> + <right_val>1.1817760467529297</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 8 19 12 -1.</_> + <_>1 12 19 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0213089995086193</threshold> + <left_val>-1.9415930509567261</left_val> + <right_val>0.7006909847259522</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 3 -1.</_> + <_>8 2 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0916600003838539</threshold> + <left_val>-0.5567010045051575</left_val> + <right_val>1.7284419536590576</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 9 6 15 -1.</_> + <_>9 14 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0362880006432533</threshold> + <left_val>0.2676379978656769</left_val> + <right_val>-2.1831810474395752</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 10 -1.</_> + <_>5 11 14 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0191099997609854</threshold> + <left_val>-2.6730210781097412</left_val> + <right_val>0.4567080140113831</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 14 9 -1.</_> + <_>5 3 14 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.2539999857544899e-003</threshold> + <left_val>-1.0852910280227661</left_val> + <right_val>0.5356420278549194</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 9 6 -1.</_> + <_>16 11 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0183550007641315</threshold> + <left_val>-0.3520019948482513</left_val> + <right_val>0.9333919882774353</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 6 10 -1.</_> + <_>9 5 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.0569999516010284e-003</threshold> + <left_val>0.9278209805488586</left_val> + <right_val>-0.6634989976882935</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 8 6 10 -1.</_> + <_>12 8 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.8770000040531158e-003</threshold> + <left_val>1.1577470302581787</left_val> + <right_val>-0.2977479994297028</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 4 9 -1.</_> + <_>4 5 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0158140007406473</threshold> + <left_val>-0.4196060001850128</left_val> + <right_val>1.3576040267944336</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 0 6 11 -1.</_> + <_>20 0 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0207000002264977</threshold> + <left_val>1.4590020179748535</left_val> + <right_val>-0.1973939985036850</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 24 13 -1.</_> + <_>8 6 8 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1376080065965653</threshold> + <left_val>1.1186759471893311</left_val> + <right_val>-0.5291550159454346</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0143189998343587</threshold> + <left_val>-0.3512719869613648</left_val> + <right_val>1.1440860033035278</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 18 10 6 -1.</_> + <_>7 20 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0102530000731349</threshold> + <left_val>-0.6085060238838196</left_val> + <right_val>0.7709850072860718</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 14 12 -1.</_> + <_>5 13 14 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0915080010890961</threshold> + <left_val>0.3881779909133911</left_val> + <right_val>-1.5122940540313721</right_val></_></_></trees> + <stage_threshold>-4.9842400550842285</stage_threshold> + <parent>0</parent> + <next>-1</next></_> + <_> + <!-- stage 2 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 24 3 -1.</_> + <_>8 3 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0697470009326935</threshold> + <left_val>-1.0130879878997803</left_val> + <right_val>1.4687349796295166</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 15 6 -1.</_> + <_>5 11 15 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0315029993653297</threshold> + <left_val>-1.6463639736175537</left_val> + <right_val>1.0000629425048828</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 5 14 -1.</_> + <_>9 13 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0142609998583794</threshold> + <left_val>0.4648030102252960</left_val> + <right_val>-1.5959889888763428</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 6 10 -1.</_> + <_>11 5 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0144530003890395</threshold> + <left_val>-0.6551190018653870</left_val> + <right_val>0.8302180171012878</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 3 12 -1.</_> + <_>6 12 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.0509999487549067e-003</threshold> + <left_val>-1.3982310295104980</left_val> + <right_val>0.4255059957504273</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 18 3 -1.</_> + <_>9 21 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0327229984104633</threshold> + <left_val>-0.5070260167121887</left_val> + <right_val>1.0526109933853149</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 13 6 -1.</_> + <_>5 8 13 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.2960001416504383e-003</threshold> + <left_val>0.3635689914226532</left_val> + <right_val>-1.3464889526367187</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 1 6 15 -1.</_> + <_>18 1 3 15 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0504250004887581</threshold> + <left_val>-0.3046140074729919</left_val> + <right_val>1.4504129886627197</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 6 15 -1.</_> + <_>4 1 3 15 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0468790009617805</threshold> + <left_val>-0.4028620123863220</left_val> + <right_val>1.2145609855651855</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 24 15 -1.</_> + <_>8 8 8 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0693589970469475</threshold> + <left_val>1.0539360046386719</left_val> + <right_val>-0.4571970105171204</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 12 -1.</_> + <_>5 6 7 6 2.</_> + <_>12 12 7 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0490339994430542</threshold> + <left_val>-1.6253089904785156</left_val> + <right_val>0.1537899971008301</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 21 12 -1.</_> + <_>2 16 21 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0848279967904091</threshold> + <left_val>0.2840299904346466</left_val> + <right_val>-1.5662059783935547</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 4 10 -1.</_> + <_>10 1 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.7229999648407102e-003</threshold> + <left_val>-1.0147459506988525</left_val> + <right_val>0.2329480051994324</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 13 20 10 -1.</_> + <_>2 13 10 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1156219989061356</threshold> + <left_val>-0.1673289984464645</left_val> + <right_val>1.2804069519042969</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 13 -1.</_> + <_>2 1 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0512799993157387</threshold> + <left_val>1.5162390470504761</left_val> + <right_val>-0.3027110099792481</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 2 4 13 -1.</_> + <_>20 2 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0427069999277592</threshold> + <left_val>1.7631920576095581</left_val> + <right_val>-0.0518320016562939</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 22 19 -1.</_> + <_>11 5 11 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.3717809915542603</threshold> + <left_val>-0.3138920068740845</left_val> + <right_val>1.5357979536056519</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 4 6 9 -1.</_> + <_>20 4 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0194129999727011</threshold> + <left_val>-0.1001759991049767</left_val> + <right_val>0.9365540146827698</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 11 -1.</_> + <_>2 3 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0174390003085136</threshold> + <left_val>-0.4037989974021912</left_val> + <right_val>0.9629300236701965</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 4 9 -1.</_> + <_>12 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0396389998495579</threshold> + <left_val>0.1703909933567047</left_val> + <right_val>-2.9602990150451660</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 19 3 -1.</_> + <_>0 7 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.1469995677471161e-003</threshold> + <left_val>0.8878679871559143</left_val> + <right_val>-0.4381870031356812</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 4 9 -1.</_> + <_>12 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.7219999572262168e-003</threshold> + <left_val>-0.3721860051155090</left_val> + <right_val>0.4001890122890472</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 4 9 -1.</_> + <_>10 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0302310008555651</threshold> + <left_val>0.0659240037202835</left_val> + <right_val>-2.6469180583953857</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 14 14 -1.</_> + <_>12 5 7 7 2.</_> + <_>5 12 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0787959992885590</threshold> + <left_val>-1.7491459846496582</left_val> + <right_val>0.2847529947757721</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 18 2 -1.</_> + <_>1 11 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.1110000088810921e-003</threshold> + <left_val>-0.9390810132026672</left_val> + <right_val>0.2320519983768463</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 13 4 11 -1.</_> + <_>17 13 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0270910002291203</threshold> + <left_val>-0.0526640005409718</left_val> + <right_val>1.0756820440292358</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 6 9 -1.</_> + <_>0 7 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0449649989604950</threshold> + <left_val>-1.8294479846954346</left_val> + <right_val>0.0995619967579842</right_val></_></_></trees> + <stage_threshold>-4.6551899909973145</stage_threshold> + <parent>1</parent> + <next>-1</next></_> + <_> + <!-- stage 3 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 9 -1.</_> + <_>6 7 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0657010003924370</threshold> + <left_val>1.1558510065078735</left_val> + <right_val>-1.0716359615325928</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 12 6 -1.</_> + <_>10 5 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0158399995416403</threshold> + <left_val>-1.5634720325469971</left_val> + <right_val>0.7687709927558899</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 5 -1.</_> + <_>8 1 8 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1457089930772781</threshold> + <left_val>-0.5745009779930115</left_val> + <right_val>1.3808720111846924</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 10 18 6 -1.</_> + <_>4 12 18 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.1389999464154243e-003</threshold> + <left_val>-1.4570560455322266</left_val> + <right_val>0.5161030292510986</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 17 12 6 -1.</_> + <_>2 17 6 3 2.</_> + <_>8 20 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.7179999314248562e-003</threshold> + <left_val>-0.8353360295295715</left_val> + <right_val>0.5852220058441162</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 3 4 13 -1.</_> + <_>19 3 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0185180008411407</threshold> + <left_val>-0.3131209909915924</left_val> + <right_val>1.1696679592132568</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 3 4 13 -1.</_> + <_>3 3 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0199580006301403</threshold> + <left_val>-0.4344260096549988</left_val> + <right_val>0.9544690251350403</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 23 -1.</_> + <_>8 1 8 23 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2775500118732452</threshold> + <left_val>1.4906179904937744</left_val> + <right_val>-0.1381590068340302</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 7 8 12 -1.</_> + <_>1 11 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.1859996318817139e-003</threshold> + <left_val>-0.9636150002479553</left_val> + <right_val>0.2766549885272980</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 7 3 14 -1.</_> + <_>14 14 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0377379991114140</threshold> + <left_val>-2.4464108943939209</left_val> + <right_val>0.2361959964036942</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 12 16 6 -1.</_> + <_>3 12 8 3 2.</_> + <_>11 15 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0184630006551743</threshold> + <left_val>0.1753920018672943</left_val> + <right_val>-1.3423130512237549</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 6 -1.</_> + <_>6 8 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0111149996519089</threshold> + <left_val>0.4871079921722412</left_val> + <right_val>-0.8985189795494080</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 6 12 -1.</_> + <_>8 13 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0339279994368553</threshold> + <left_val>0.1787420064210892</left_val> + <right_val>-1.6342279911041260</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 15 9 6 -1.</_> + <_>15 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0356490015983582</threshold> + <left_val>-1.9607399702072144</left_val> + <right_val>0.1810249984264374</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 17 18 3 -1.</_> + <_>1 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0114380000159144</threshold> + <left_val>0.9901069998741150</left_val> + <right_val>-0.3810319900512695</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 16 12 -1.</_> + <_>4 10 16 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0652360022068024</threshold> + <left_val>-2.5794160366058350</left_val> + <right_val>0.2475360035896301</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 4 20 -1.</_> + <_>2 1 2 20 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0422720015048981</threshold> + <left_val>1.4411840438842773</left_val> + <right_val>-0.2950829863548279</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 18 2 -1.</_> + <_>3 1 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.9219999667257071e-003</threshold> + <left_val>-0.4960860013961792</left_val> + <right_val>0.6317359805107117</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 20 14 -1.</_> + <_>1 5 10 7 2.</_> + <_>11 12 10 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1292179971933365</threshold> + <left_val>-2.3314270973205566</left_val> + <right_val>0.0544969998300076</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 14 12 -1.</_> + <_>5 12 14 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0229310002177954</threshold> + <left_val>-0.8444709777832031</left_val> + <right_val>0.3873809874057770</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 14 7 9 -1.</_> + <_>3 17 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0341200008988380</threshold> + <left_val>-1.4431500434875488</left_val> + <right_val>0.0984229966998100</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 9 6 -1.</_> + <_>14 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0262230001389980</threshold> + <left_val>0.1822309941053391</left_val> + <right_val>-1.2586519718170166</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 15 9 6 -1.</_> + <_>1 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0222369991242886</threshold> + <left_val>0.0698079988360405</left_val> + <right_val>-2.3820950984954834</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 8 10 -1.</_> + <_>15 6 4 5 2.</_> + <_>11 11 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.8240001089870930e-003</threshold> + <left_val>0.3933250010013580</left_val> + <right_val>-0.2754279971122742</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 14 14 -1.</_> + <_>5 5 7 7 2.</_> + <_>12 12 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0436530001461506</threshold> + <left_val>0.1483269929885864</left_val> + <right_val>-1.1368780136108398</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 12 5 -1.</_> + <_>10 0 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0572669990360737</threshold> + <left_val>0.2462809979915619</left_val> + <right_val>-1.2687400579452515</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 9 -1.</_> + <_>9 3 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.3409998975694180e-003</threshold> + <left_val>-0.7544890046119690</left_val> + <right_val>0.2716380059719086</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0129960002377629</threshold> + <left_val>-0.3639490008354187</left_val> + <right_val>0.7095919847488403</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0265170000493526</threshold> + <left_val>-2.3221859931945801</left_val> + <right_val>0.0357440002262592</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 6 9 -1.</_> + <_>12 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.8400002308189869e-003</threshold> + <left_val>0.4219430088996887</left_val> + <right_val>-0.0481849983334541</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 6 9 -1.</_> + <_>10 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0165689997375011</threshold> + <left_val>1.1099940538406372</left_val> + <right_val>-0.3484970033168793</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 8 18 4 -1.</_> + <_>9 8 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0681570023298264</threshold> + <left_val>-3.3269989490509033</left_val> + <right_val>0.2129900008440018</right_val></_></_></trees> + <stage_threshold>-4.4531588554382324</stage_threshold> + <parent>2</parent> + <next>-1</next></_> + <_> + <!-- stage 4 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 12 9 -1.</_> + <_>6 3 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0399740003049374</threshold> + <left_val>-1.2173449993133545</left_val> + <right_val>1.0826710462570190</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 6 -1.</_> + <_>8 0 8 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1881950050592423</threshold> + <left_val>-0.4828940033912659</left_val> + <right_val>1.4045250415802002</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 16 12 -1.</_> + <_>4 11 16 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0780270025134087</threshold> + <left_val>-1.0782150030136108</left_val> + <right_val>0.7404029965400696</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 6 6 -1.</_> + <_>11 6 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.1899999663000926e-004</threshold> + <left_val>-1.2019979953765869</left_val> + <right_val>0.3774920105934143</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 20 24 3 -1.</_> + <_>8 20 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0850569978356361</threshold> + <left_val>-0.4393909871578217</left_val> + <right_val>1.2647340297698975</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 4 9 -1.</_> + <_>11 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.9720003306865692e-003</threshold> + <left_val>-0.1844049990177155</left_val> + <right_val>0.4572640061378479</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 15 4 -1.</_> + <_>9 13 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.8120000436902046e-003</threshold> + <left_val>0.3039669990539551</left_val> + <right_val>-0.9599109888076782</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 4 9 -1.</_> + <_>11 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0235079992562532</threshold> + <left_val>1.2487529516220093</left_val> + <right_val>0.0462279990315437</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 4 9 -1.</_> + <_>11 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.0039997808635235e-003</threshold> + <left_val>-0.5944210290908814</left_val> + <right_val>0.5396329760551453</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 12 -1.</_> + <_>9 18 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0338519997894764</threshold> + <left_val>0.2849609851837158</left_val> + <right_val>-1.4895249605178833</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 22 18 2 -1.</_> + <_>1 23 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.2530000898987055e-003</threshold> + <left_val>0.4812079966068268</left_val> + <right_val>-0.5271239876747131</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 4 10 -1.</_> + <_>10 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0290970001369715</threshold> + <left_val>0.2674390077590942</left_val> + <right_val>-1.6007850170135498</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 8 10 -1.</_> + <_>6 12 8 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.4790000692009926e-003</threshold> + <left_val>-1.3107639551162720</left_val> + <right_val>0.1524309962987900</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 10 6 -1.</_> + <_>7 8 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0107950000092387</threshold> + <left_val>0.4561359882354736</left_val> + <right_val>-0.7205089926719666</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 10 4 -1.</_> + <_>0 16 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0246200002729893</threshold> + <left_val>-1.7320619821548462</left_val> + <right_val>0.0683630034327507</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 18 18 2 -1.</_> + <_>6 19 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.7380000576376915e-003</threshold> + <left_val>-0.1930329948663712</left_val> + <right_val>0.6824349761009216</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 22 3 -1.</_> + <_>1 2 22 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0122640002518892</threshold> + <left_val>-1.6095290184020996</left_val> + <right_val>0.0752680003643036</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 18 3 -1.</_> + <_>6 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.8670000396668911e-003</threshold> + <left_val>0.7428650259971619</left_val> + <right_val>-0.2151020020246506</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 4 6 15 -1.</_> + <_>5 4 3 15 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0767259970307350</threshold> + <left_val>-0.2683509886264801</left_val> + <right_val>1.3094140291213989</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 4 4 10 -1.</_> + <_>20 4 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0285780001431704</threshold> + <left_val>-0.0587930008769035</left_val> + <right_val>1.2196329832077026</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 4 10 -1.</_> + <_>2 4 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0196940004825592</threshold> + <left_val>-0.3514289855957031</left_val> + <right_val>0.8492699861526489</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 16 20 6 -1.</_> + <_>12 16 10 3 2.</_> + <_>2 19 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0290939994156361</threshold> + <left_val>-1.0507299900054932</left_val> + <right_val>0.2980630099773407</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 8 9 -1.</_> + <_>4 12 4 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0291440002620220</threshold> + <left_val>0.8254780173301697</left_val> + <right_val>-0.3268719911575317</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 6 9 -1.</_> + <_>14 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0197410006076097</threshold> + <left_val>0.2045260071754456</left_val> + <right_val>-0.8376020193099976</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 6 6 -1.</_> + <_>8 10 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.3299999088048935e-003</threshold> + <left_val>0.2057790011167526</left_val> + <right_val>-0.6682980060577393</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 8 12 6 -1.</_> + <_>17 8 6 3 2.</_> + <_>11 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0355009995400906</threshold> + <left_val>-1.2969900369644165</left_val> + <right_val>0.1389749944210053</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 12 6 -1.</_> + <_>0 8 6 3 2.</_> + <_>6 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0161729995161295</threshold> + <left_val>-1.3110569715499878</left_val> + <right_val>0.0757519975304604</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 6 9 -1.</_> + <_>14 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0221510007977486</threshold> + <left_val>-1.0524389743804932</left_val> + <right_val>0.1924110054969788</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 6 9 -1.</_> + <_>8 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0227070003747940</threshold> + <left_val>-1.3735309839248657</left_val> + <right_val>0.0667809993028641</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 14 9 6 -1.</_> + <_>8 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0166079998016357</threshold> + <left_val>-0.0371359996497631</left_val> + <right_val>0.7784640192985535</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 9 6 -1.</_> + <_>0 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0133090000599623</threshold> + <left_val>-0.9985070228576660</left_val> + <right_val>0.1224810034036636</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 8 6 10 -1.</_> + <_>12 8 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0337320007383823</threshold> + <left_val>1.4461359977722168</left_val> + <right_val>0.0131519995629787</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 19 12 3 -1.</_> + <_>9 19 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0169350001960993</threshold> + <left_val>-0.3712129890918732</left_val> + <right_val>0.5284219980239868</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 10 20 2 -1.</_> + <_>2 11 20 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.3259999472647905e-003</threshold> + <left_val>-0.5756850242614746</left_val> + <right_val>0.3926190137863159</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 9 18 12 -1.</_> + <_>2 9 9 6 2.</_> + <_>11 15 9 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0836440026760101</threshold> + <left_val>0.0161160007119179</left_val> + <right_val>-2.1173279285430908</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 18 24 -1.</_> + <_>3 0 9 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2578519880771637</threshold> + <left_val>-0.0816090032458305</left_val> + <right_val>0.9878249764442444</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 10 -1.</_> + <_>5 6 7 5 2.</_> + <_>12 11 7 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0365669988095760</threshold> + <left_val>-1.1512110233306885</left_val> + <right_val>0.0964590013027191</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 10 12 -1.</_> + <_>14 5 5 6 2.</_> + <_>9 11 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0164459999650717</threshold> + <left_val>0.3731549978256226</left_val> + <right_val>-0.1458539962768555</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 5 12 12 -1.</_> + <_>4 5 6 6 2.</_> + <_>10 11 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.7519999314099550e-003</threshold> + <left_val>0.2617929875850678</left_val> + <right_val>-0.5815669894218445</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 14 18 3 -1.</_> + <_>4 15 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.3660000450909138e-003</threshold> + <left_val>0.7547739744186401</left_val> + <right_val>-0.1705520004034042</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 13 8 8 -1.</_> + <_>6 17 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.8499999791383743e-003</threshold> + <left_val>0.2265399992465973</left_val> + <right_val>-0.6387640237808228</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 16 18 6 -1.</_> + <_>3 19 18 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0454940013587475</threshold> + <left_val>-1.2640299797058105</left_val> + <right_val>0.2526069879531860</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 6 -1.</_> + <_>3 0 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0239410009235144</threshold> + <left_val>0.8706840276718140</left_val> + <right_val>-0.2710469961166382</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 18 -1.</_> + <_>10 6 4 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0775580033659935</threshold> + <left_val>-1.3901610374450684</left_val> + <right_val>0.2361229956150055</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 4 14 -1.</_> + <_>8 1 2 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0236140005290508</threshold> + <left_val>0.0661400035023689</left_val> + <right_val>-1.2645419836044312</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 19 2 -1.</_> + <_>3 3 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.5750000495463610e-003</threshold> + <left_val>-0.5384169816970825</left_val> + <right_val>0.3037909865379334</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 8 22 13 -1.</_> + <_>12 8 11 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1201080009341240</threshold> + <left_val>-0.3534300029277802</left_val> + <right_val>0.5286620259284973</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 9 11 4 -1.</_> + <_>8 11 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.2899999748915434e-003</threshold> + <left_val>-0.5870199799537659</left_val> + <right_val>0.2406100034713745</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 15 10 -1.</_> + <_>5 12 5 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0697169974446297</threshold> + <left_val>-0.3334890007972717</left_val> + <right_val>0.5191630125045776</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 16 12 6 -1.</_> + <_>16 16 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0466700010001659</threshold> + <left_val>0.6979539990425110</left_val> + <right_val>-0.0148959998041391</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 12 6 -1.</_> + <_>4 16 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0501290000975132</threshold> + <left_val>0.8614619970321655</left_val> + <right_val>-0.2598600089550018</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 1 5 12 -1.</_> + <_>19 5 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0301479995250702</threshold> + <left_val>0.1933279931545258</left_val> + <right_val>-0.5913109779357910</right_val></_></_></trees> + <stage_threshold>-4.3864588737487793</stage_threshold> + <parent>3</parent> + <next>-1</next></_> + <_> + <!-- stage 5 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 4 -1.</_> + <_>8 2 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0910850018262863</threshold> + <left_val>-0.8923310041427612</left_val> + <right_val>1.0434230566024780</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 12 4 -1.</_> + <_>6 10 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0128189995884895</threshold> + <left_val>-1.2597670555114746</left_val> + <right_val>0.5531709790229797</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 9 6 -1.</_> + <_>10 5 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0159319993108511</threshold> + <left_val>-0.8625440001487732</left_val> + <right_val>0.6373180150985718</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 17 6 6 -1.</_> + <_>9 20 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.2780001163482666e-003</threshold> + <left_val>-0.7463920116424561</left_val> + <right_val>0.5315560102462769</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 22 15 -1.</_> + <_>0 12 22 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0318409986793995</threshold> + <left_val>-1.2650489807128906</left_val> + <right_val>0.3615390062332153</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 17 9 -1.</_> + <_>4 4 17 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.6960000395774841e-003</threshold> + <left_val>-0.9829040169715881</left_val> + <right_val>0.3601300120353699</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 6 10 -1.</_> + <_>9 5 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0120550002902746</threshold> + <left_val>0.6406840085983276</left_val> + <right_val>-0.5012500286102295</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 1 6 8 -1.</_> + <_>18 1 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0213249996304512</threshold> + <left_val>-0.2403499931097031</left_val> + <right_val>0.8544800281524658</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 7 -1.</_> + <_>3 1 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0304860007017851</threshold> + <left_val>-0.3427360057830811</left_val> + <right_val>1.1428849697113037</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 0 6 22 -1.</_> + <_>18 0 3 22 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0450799986720085</threshold> + <left_val>1.0976949930191040</left_val> + <right_val>-0.1797460019588471</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 22 -1.</_> + <_>3 0 3 22 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0717009976506233</threshold> + <left_val>1.5735000371932983</left_val> + <right_val>-0.3143349885940552</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 7 8 16 -1.</_> + <_>16 7 4 16 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0592180006206036</threshold> + <left_val>-0.2758240103721619</left_val> + <right_val>1.0448570251464844</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 10 19 6 -1.</_> + <_>2 12 19 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.7010000348091125e-003</threshold> + <left_val>-1.0974019765853882</left_val> + <right_val>0.1980119943618774</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 9 6 12 -1.</_> + <_>9 13 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0410469993948936</threshold> + <left_val>0.3054769933223724</left_val> + <right_val>-1.3287999629974365</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 15 17 6 -1.</_> + <_>2 17 17 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.5499999113380909e-004</threshold> + <left_val>0.2580710053443909</left_val> + <right_val>-0.7005289793014526</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 7 3 14 -1.</_> + <_>14 14 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0303600002080202</threshold> + <left_val>-1.2306419610977173</left_val> + <right_val>0.2260939925909042</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 8 10 -1.</_> + <_>5 6 4 5 2.</_> + <_>9 11 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0129300002008677</threshold> + <left_val>0.4075860083103180</left_val> + <right_val>-0.5123450160026550</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 8 9 11 -1.</_> + <_>18 8 3 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0373679995536804</threshold> + <left_val>-0.0947550013661385</left_val> + <right_val>0.6176509857177734</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 9 11 -1.</_> + <_>3 8 3 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0244340002536774</threshold> + <left_val>-0.4110060036182404</left_val> + <right_val>0.4763050079345703</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 10 18 -1.</_> + <_>8 15 10 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0570079982280731</threshold> + <left_val>0.2524929940700531</left_val> + <right_val>-0.6866980195045471</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 3 14 -1.</_> + <_>7 14 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0163139998912811</threshold> + <left_val>-0.9392840266227722</left_val> + <right_val>0.1144810020923615</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 24 8 -1.</_> + <_>8 14 8 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1764889955520630</threshold> + <left_val>1.2451089620590210</left_val> + <right_val>-0.0565190017223358</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 18 14 -1.</_> + <_>10 10 9 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1761460006237030</threshold> + <left_val>-0.3252820074558258</left_val> + <right_val>0.8279150128364563</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 12 6 6 -1.</_> + <_>14 15 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.3910001665353775e-003</threshold> + <left_val>0.3478370010852814</left_val> + <right_val>-0.1792909950017929</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 10 16 -1.</_> + <_>7 0 5 8 2.</_> + <_>12 8 5 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0608909986913204</threshold> + <left_val>0.0550980009138584</left_val> + <right_val>-1.5480779409408569</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 9 6 -1.</_> + <_>13 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0291230008006096</threshold> + <left_val>-1.0255639553070068</left_val> + <right_val>0.2410690039396286</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 16 4 -1.</_> + <_>12 3 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0456489995121956</threshold> + <left_val>1.0301599502563477</left_val> + <right_val>-0.3167209923267365</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 9 6 -1.</_> + <_>13 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0373330004513264</threshold> + <left_val>0.2162059992551804</left_val> + <right_val>-0.8258990049362183</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 20 4 -1.</_> + <_>1 1 10 2 2.</_> + <_>11 3 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0244110003113747</threshold> + <left_val>-1.5957959890365601</left_val> + <right_val>0.0511390008032322</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 9 6 -1.</_> + <_>13 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0598069988191128</threshold> + <left_val>-1.0312290191650391</left_val> + <right_val>0.1309230029582977</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 9 6 -1.</_> + <_>8 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0301060006022453</threshold> + <left_val>-1.4781630039215088</left_val> + <right_val>0.0372119992971420</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 10 6 -1.</_> + <_>8 20 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.4209999293088913e-003</threshold> + <left_val>-0.2402410060167313</left_val> + <right_val>0.4933399856090546</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 6 9 -1.</_> + <_>8 3 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.1909999195486307e-003</threshold> + <left_val>0.2894150018692017</left_val> + <right_val>-0.5725960135459900</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 3 12 6 -1.</_> + <_>7 5 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0208609998226166</threshold> + <left_val>-0.2314839959144592</left_val> + <right_val>0.6376590132713318</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 18 3 -1.</_> + <_>0 11 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.6990000195801258e-003</threshold> + <left_val>-1.2107750177383423</left_val> + <right_val>0.0640180036425591</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 22 3 -1.</_> + <_>1 11 22 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0187580008059740</threshold> + <left_val>0.2446130067110062</left_val> + <right_val>-0.9978669881820679</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 8 8 -1.</_> + <_>9 11 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0443230010569096</threshold> + <left_val>-1.3699189424514771</left_val> + <right_val>0.0360519997775555</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 11 6 6 -1.</_> + <_>12 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0228599999099970</threshold> + <left_val>0.2128839939832687</left_val> + <right_val>-1.0397620201110840</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 6 6 -1.</_> + <_>9 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.8600005730986595e-004</threshold> + <left_val>0.3244360089302063</left_val> + <right_val>-0.5429180264472961</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 10 11 6 -1.</_> + <_>7 12 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0172390006482601</threshold> + <left_val>-0.2832390069961548</left_val> + <right_val>0.4446820020675659</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 24 4 -1.</_> + <_>0 13 12 2 2.</_> + <_>12 15 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0345310010015965</threshold> + <left_val>-2.3107020854949951</left_val> + <right_val>-3.1399999279528856e-003</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 4 22 12 -1.</_> + <_>13 4 11 6 2.</_> + <_>2 10 11 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0670069977641106</threshold> + <left_val>0.2871569991111755</left_val> + <right_val>-0.6448100209236145</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 20 17 -1.</_> + <_>12 0 10 17 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2377689927816391</threshold> + <left_val>-0.2717480063438416</left_val> + <right_val>0.8021910190582275</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 2 24 -1.</_> + <_>14 0 1 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0129030002281070</threshold> + <left_val>-1.5317620038986206</left_val> + <right_val>0.2142360061407089</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 2 24 -1.</_> + <_>9 0 1 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0105149997398257</threshold> + <left_val>0.0770379975438118</left_val> + <right_val>-1.0581140518188477</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 1 2 22 -1.</_> + <_>14 1 1 22 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0169690009206533</threshold> + <left_val>0.1430670022964478</left_val> + <right_val>-0.8582839965820313</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 2 22 -1.</_> + <_>9 1 1 22 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.2460002265870571e-003</threshold> + <left_val>-1.1020129919052124</left_val> + <right_val>0.0649069994688034</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 6 3 18 -1.</_> + <_>18 6 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0105569995939732</threshold> + <left_val>0.0139640001580119</left_val> + <right_val>0.6360149979591370</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 14 9 6 -1.</_> + <_>6 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.1380001716315746e-003</threshold> + <left_val>-0.3454590141773224</left_val> + <right_val>0.5629680156707764</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 14 9 4 -1.</_> + <_>13 16 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0131580000743270</threshold> + <left_val>0.1992730051279068</left_val> + <right_val>-1.5040320158004761</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 18 3 -1.</_> + <_>3 19 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.1310000922530890e-003</threshold> + <left_val>-0.4090369939804077</left_val> + <right_val>0.3779639899730682</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 4 8 18 -1.</_> + <_>13 4 4 9 2.</_> + <_>9 13 4 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1092069968581200</threshold> + <left_val>-2.2227079868316650</left_val> + <right_val>0.1217819973826408</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 18 3 -1.</_> + <_>0 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.1820003688335419e-003</threshold> + <left_val>-0.2865200042724609</left_val> + <right_val>0.6789079904556274</right_val></_></_></trees> + <stage_threshold>-4.1299300193786621</stage_threshold> + <parent>4</parent> + <next>-1</next></_> + <_> + <!-- stage 6 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 12 4 -1.</_> + <_>6 2 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0313469991087914</threshold> + <left_val>-0.8888459801673889</left_val> + <right_val>0.9493680000305176</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 14 6 -1.</_> + <_>6 11 14 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0319180004298687</threshold> + <left_val>-1.1146880388259888</left_val> + <right_val>0.4888899922370911</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 6 6 -1.</_> + <_>10 5 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.5939999185502529e-003</threshold> + <left_val>-1.0097689628601074</left_val> + <right_val>0.4972380101680756</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 6 16 -1.</_> + <_>10 13 6 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0261480007320642</threshold> + <left_val>0.2599129974842072</left_val> + <right_val>-1.2537480592727661</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 4 9 16 -1.</_> + <_>4 4 3 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0128450002521276</threshold> + <left_val>-0.5713859796524048</left_val> + <right_val>0.5965949892997742</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 18 9 -1.</_> + <_>5 3 18 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0263449996709824</threshold> + <left_val>-0.5520319938659668</left_val> + <right_val>0.3021740019321442</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 15 5 8 -1.</_> + <_>9 19 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0150830000638962</threshold> + <left_val>-1.2871240377426147</left_val> + <right_val>0.2235420048236847</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 0 4 9 -1.</_> + <_>20 0 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0388870015740395</threshold> + <left_val>1.7425049543380737</left_val> + <right_val>-0.0997470021247864</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 18 3 -1.</_> + <_>2 1 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.7029998861253262e-003</threshold> + <left_val>-1.0523240566253662</left_val> + <right_val>0.1836259961128235</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 22 19 2 -1.</_> + <_>5 23 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.4860000228509307e-003</threshold> + <left_val>0.5678420066833496</left_val> + <right_val>-0.4674200117588043</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 4 9 -1.</_> + <_>2 0 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0284860003739595</threshold> + <left_val>1.3082909584045410</left_val> + <right_val>-0.2646090090274811</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 19 18 -1.</_> + <_>5 12 19 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0662249997258186</threshold> + <left_val>-0.4621070027351379</left_val> + <right_val>0.4174959957599640</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 9 -1.</_> + <_>2 1 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.8569996878504753e-003</threshold> + <left_val>-0.4147489964962006</left_val> + <right_val>0.5920479893684387</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 14 12 -1.</_> + <_>13 5 7 6 2.</_> + <_>6 11 7 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0113559998571873</threshold> + <left_val>0.3610309958457947</left_val> + <right_val>-0.4578120112419128</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 20 2 -1.</_> + <_>0 2 20 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.7679998893290758e-003</threshold> + <left_val>-0.8923889994621277</left_val> + <right_val>0.1419900059700012</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 22 3 -1.</_> + <_>1 3 22 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0112469997256994</threshold> + <left_val>0.2935340106487274</left_val> + <right_val>-0.9733060002326965</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 8 7 9 -1.</_> + <_>2 11 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.1970000863075256e-003</threshold> + <left_val>-0.7933490276336670</left_val> + <right_val>0.1831340044736862</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 22 4 -1.</_> + <_>13 12 11 2 2.</_> + <_>2 14 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0317689999938011</threshold> + <left_val>0.1552309989929199</left_val> + <right_val>-1.3245639801025391</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 22 4 -1.</_> + <_>0 12 11 2 2.</_> + <_>11 14 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0251739993691444</threshold> + <left_val>0.0342149995267391</left_val> + <right_val>-2.0948131084442139</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 7 6 11 -1.</_> + <_>11 7 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.5360001064836979e-003</threshold> + <left_val>-0.3945060074329376</left_val> + <right_val>0.5133399963378906</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 9 6 -1.</_> + <_>10 1 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0328730009496212</threshold> + <left_val>0.0883729979395866</left_val> + <right_val>-1.2814120054244995</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 2 4 10 -1.</_> + <_>11 7 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.7379998937249184e-003</threshold> + <left_val>0.5528650283813477</left_val> + <right_val>-0.4638499915599823</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 12 -1.</_> + <_>6 10 12 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0380750000476837</threshold> + <left_val>-1.8497270345687866</left_val> + <right_val>0.0459440015256405</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 1 6 15 -1.</_> + <_>18 6 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0389840006828308</threshold> + <left_val>-0.4822370111942291</left_val> + <right_val>0.3476060032844544</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 15 18 3 -1.</_> + <_>3 16 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.8029999230057001e-003</threshold> + <left_val>-0.4515469968318939</left_val> + <right_val>0.4280630052089691</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 5 6 9 -1.</_> + <_>18 8 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0541459992527962</threshold> + <left_val>-0.8452079892158508</left_val> + <right_val>0.1667490005493164</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 16 6 -1.</_> + <_>1 5 8 3 2.</_> + <_>9 8 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.3280000835657120e-003</threshold> + <left_val>0.3534829914569855</left_val> + <right_val>-0.4716320037841797</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 6 9 -1.</_> + <_>13 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0337780006229877</threshold> + <left_val>0.1846310049295425</left_val> + <right_val>-1.6686669588088989</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 24 14 -1.</_> + <_>0 4 12 7 2.</_> + <_>12 11 12 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1123809963464737</threshold> + <left_val>-1.2521569728851318</left_val> + <right_val>0.0359920002520084</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 4 13 -1.</_> + <_>13 0 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0104080000892282</threshold> + <left_val>-0.8162040114402771</left_val> + <right_val>0.2342859953641892</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 4 13 -1.</_> + <_>9 0 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.9439999274909496e-003</threshold> + <left_val>-0.9258469939231873</left_val> + <right_val>0.1003480032086372</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 6 9 -1.</_> + <_>13 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.3029998242855072e-003</threshold> + <left_val>0.5649930238723755</left_val> + <right_val>-0.1888190060853958</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 6 9 -1.</_> + <_>10 7 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0117499995976686</threshold> + <left_val>0.8030239939689636</left_val> + <right_val>-0.3827700018882752</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 17 9 6 -1.</_> + <_>13 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0232170000672340</threshold> + <left_val>-0.8492699861526489</left_val> + <right_val>0.1967120021581650</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 18 14 6 -1.</_> + <_>2 18 7 3 2.</_> + <_>9 21 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0168660003691912</threshold> + <left_val>-0.4059189856052399</left_val> + <right_val>0.5069530010223389</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 18 4 -1.</_> + <_>12 18 9 2 2.</_> + <_>3 20 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0240310002118349</threshold> + <left_val>-1.5297520160675049</left_val> + <right_val>0.2334499955177307</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 20 15 4 -1.</_> + <_>5 20 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0369459986686707</threshold> + <left_val>0.6300770044326782</left_val> + <right_val>-0.3178040087223053</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 15 15 9 -1.</_> + <_>14 15 5 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0615639984607697</threshold> + <left_val>0.5862789750099182</left_val> + <right_val>-0.0121079999953508</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 16 4 -1.</_> + <_>4 6 16 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0216610003262758</threshold> + <left_val>-0.2562370002269745</left_val> + <right_val>1.0409849882125854</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 10 6 -1.</_> + <_>7 8 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.6710000131279230e-003</threshold> + <left_val>0.2917110025882721</left_val> + <right_val>-0.8328729867935181</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 15 10 -1.</_> + <_>5 14 5 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0448490008711815</threshold> + <left_val>-0.3963319957256317</left_val> + <right_val>0.4566200077533722</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 9 10 14 -1.</_> + <_>12 9 5 7 2.</_> + <_>7 16 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0571950003504753</threshold> + <left_val>0.2102389931678772</left_val> + <right_val>-1.5004800558090210</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 6 9 -1.</_> + <_>9 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0113420002162457</threshold> + <left_val>0.4407129883766174</left_val> + <right_val>-0.3865379989147186</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 3 -1.</_> + <_>3 7 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0120040001347661</threshold> + <left_val>0.9395459890365601</left_val> + <right_val>-0.1058949977159500</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 18 3 -1.</_> + <_>0 11 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0225159991532564</threshold> + <left_val>9.4480002298951149e-003</left_val> + <right_val>-1.6799509525299072</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 16 18 4 -1.</_> + <_>12 16 9 2 2.</_> + <_>3 18 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0198090001940727</threshold> + <left_val>-1.0133639574050903</left_val> + <right_val>0.2414660006761551</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 14 6 -1.</_> + <_>4 6 7 3 2.</_> + <_>11 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0158910006284714</threshold> + <left_val>-0.3750759959220886</left_val> + <right_val>0.4661409854888916</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 2 18 -1.</_> + <_>13 0 1 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.1420002281665802e-003</threshold> + <left_val>-0.8048409819602966</left_val> + <right_val>0.1781699955463409</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 2 18 -1.</_> + <_>10 0 1 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.4740000739693642e-003</threshold> + <left_val>-1.0562069416046143</left_val> + <right_val>0.0733050033450127</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 15 10 -1.</_> + <_>10 7 5 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1274250000715256</threshold> + <left_val>0.2016559988260269</left_val> + <right_val>-1.5467929840087891</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 20 21 4 -1.</_> + <_>8 20 7 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0477030016481876</threshold> + <left_val>-0.3793779909610748</left_val> + <right_val>0.3788599967956543</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 5 18 -1.</_> + <_>10 14 5 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0536080002784729</threshold> + <left_val>0.2122049927711487</left_val> + <right_val>-1.2399710416793823</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 6 -1.</_> + <_>0 2 12 3 2.</_> + <_>12 5 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0396809987723827</threshold> + <left_val>-1.0257550477981567</left_val> + <right_val>0.0512829981744289</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 22 8 -1.</_> + <_>12 1 11 4 2.</_> + <_>1 5 11 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0673270002007484</threshold> + <left_val>-1.0304750204086304</left_val> + <right_val>0.2300529927015305</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 15 9 -1.</_> + <_>4 3 15 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1333760023117065</threshold> + <left_val>-0.2086900025606155</left_val> + <right_val>1.2272510528564453</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 19 -1.</_> + <_>8 0 8 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2091930061578751</threshold> + <left_val>0.8792989850044251</left_val> + <right_val>-0.0442549996078014</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 21 18 3 -1.</_> + <_>11 21 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0655890032649040</threshold> + <left_val>1.0443429946899414</left_val> + <right_val>-0.2168209999799728</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 7 10 4 -1.</_> + <_>9 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0618829987943172</threshold> + <left_val>0.1379819959402084</left_val> + <right_val>-1.9009059667587280</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 10 4 -1.</_> + <_>10 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0255789998918772</threshold> + <left_val>-1.6607600450515747</left_val> + <right_val>5.8439997956156731e-003</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 8 6 16 -1.</_> + <_>20 8 3 8 2.</_> + <_>17 16 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0348270013928413</threshold> + <left_val>0.7994040250778198</left_val> + <right_val>-0.0824069976806641</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 15 20 4 -1.</_> + <_>1 15 10 2 2.</_> + <_>11 17 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0182099994271994</threshold> + <left_val>-0.9607399702072144</left_val> + <right_val>0.0663200020790100</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 10 6 -1.</_> + <_>14 17 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0150709999725223</threshold> + <left_val>0.1989939957857132</left_val> + <right_val>-0.7643300294876099</right_val></_></_></trees> + <stage_threshold>-4.0218091011047363</stage_threshold> + <parent>5</parent> + <next>-1</next></_> + <_> + <!-- stage 7 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 16 9 -1.</_> + <_>3 3 16 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0463249981403351</threshold> + <left_val>-1.0362670421600342</left_val> + <right_val>0.8220149874687195</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 6 7 15 -1.</_> + <_>15 11 7 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0154069997370243</threshold> + <left_val>-1.2327589988708496</left_val> + <right_val>0.2964769899845123</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 6 13 -1.</_> + <_>11 1 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0128089999780059</threshold> + <left_val>-0.7585229873657227</left_val> + <right_val>0.5798550248146057</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 2 6 14 -1.</_> + <_>17 2 3 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0491509996354580</threshold> + <left_val>-0.3898389935493469</left_val> + <right_val>0.8968030214309692</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 14 12 10 -1.</_> + <_>3 14 6 5 2.</_> + <_>9 19 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0126210004091263</threshold> + <left_val>-0.7179930210113525</left_val> + <right_val>0.5044090151786804</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 10 6 -1.</_> + <_>7 8 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0187689997255802</threshold> + <left_val>0.5514760017395020</left_val> + <right_val>-0.7055540084838867</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 6 14 -1.</_> + <_>4 2 3 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0419650003314018</threshold> + <left_val>-0.4478209912776947</left_val> + <right_val>0.7098550200462341</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 4 5 12 -1.</_> + <_>10 8 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0514019988477230</threshold> + <left_val>-1.0932120084762573</left_val> + <right_val>0.2670190036296845</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 24 5 -1.</_> + <_>8 17 8 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0709609985351563</threshold> + <left_val>0.8361840248107910</left_val> + <right_val>-0.3831810057163239</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 7 5 12 -1.</_> + <_>15 11 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0167459994554520</threshold> + <left_val>-0.2573310136795044</left_val> + <right_val>0.2596650123596191</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 6 12 -1.</_> + <_>3 1 3 6 2.</_> + <_>6 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.2400000169873238e-003</threshold> + <left_val>0.3163149952888489</left_val> + <right_val>-0.5879690051078796</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 13 6 6 -1.</_> + <_>12 16 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0393979996442795</threshold> + <left_val>-1.0491210222244263</left_val> + <right_val>0.1682240068912506</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 13 6 6 -1.</_> + <_>6 16 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.</threshold> + <left_val>0.1614419966936112</left_val> + <right_val>-0.8787689805030823</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 6 3 16 -1.</_> + <_>14 14 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0223079994320869</threshold> + <left_val>-0.6905350089073181</left_val> + <right_val>0.2360700070858002</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 12 13 6 -1.</_> + <_>1 14 13 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.8919999711215496e-003</threshold> + <left_val>0.2498919963836670</left_val> + <right_val>-0.5658329725265503</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 1 4 9 -1.</_> + <_>13 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.0730000212788582e-003</threshold> + <left_val>-0.5041580200195313</left_val> + <right_val>0.3837450146675110</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 9 6 -1.</_> + <_>10 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0392309986054897</threshold> + <left_val>0.0426190011203289</left_val> + <right_val>-1.3875889778137207</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 2 6 9 -1.</_> + <_>12 2 3 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0622380003333092</threshold> + <left_val>0.1411940008401871</left_val> + <right_val>-1.0688860416412354</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 2 6 9 -1.</_> + <_>9 2 3 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.1399999968707561e-003</threshold> + <left_val>-0.8962240219116211</left_val> + <right_val>0.1979639977216721</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 18 12 6 -1.</_> + <_>6 20 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.1800000518560410e-004</threshold> + <left_val>-0.4533729851245880</left_val> + <right_val>0.4353269934654236</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 6 9 -1.</_> + <_>9 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.9169998168945313e-003</threshold> + <left_val>0.3382279872894287</left_val> + <right_val>-0.4479300081729889</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 12 3 -1.</_> + <_>7 7 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0238669998943806</threshold> + <left_val>-0.7890859842300415</left_val> + <right_val>0.2251179963350296</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 3 8 21 -1.</_> + <_>8 10 8 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1026280000805855</threshold> + <left_val>-2.2831439971923828</left_val> + <right_val>-5.3960001096129417e-003</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 4 10 12 -1.</_> + <_>7 8 10 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.5239998772740364e-003</threshold> + <left_val>0.3934670090675354</left_val> + <right_val>-0.5224220156669617</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 9 -1.</_> + <_>0 4 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0398770011961460</threshold> + <left_val>0.0327990017831326</left_val> + <right_val>-1.5079489946365356</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 2 2 20 -1.</_> + <_>15 2 1 20 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0131449997425079</threshold> + <left_val>-1.0839990377426147</left_val> + <right_val>0.1848240047693253</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 9 -1.</_> + <_>0 6 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0505909994244576</threshold> + <left_val>-1.8822289705276489</left_val> + <right_val>-2.2199999075382948e-003</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 3 2 21 -1.</_> + <_>15 3 1 21 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0249170009046793</threshold> + <left_val>0.1459340006113052</left_val> + <right_val>-2.2196519374847412</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 2 23 -1.</_> + <_>8 0 1 23 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.6370001770555973e-003</threshold> + <left_val>-1.0164569616317749</left_val> + <right_val>0.0587970018386841</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 8 9 4 -1.</_> + <_>15 10 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0429119989275932</threshold> + <left_val>0.1544300019741058</left_val> + <right_val>-1.1843889951705933</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 9 4 -1.</_> + <_>0 10 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.3000000510364771e-004</threshold> + <left_val>-0.7730579972267151</left_val> + <right_val>0.1218990013003349</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 14 9 6 -1.</_> + <_>8 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.0929996222257614e-003</threshold> + <left_val>-0.1145009994506836</left_val> + <right_val>0.7109130024909973</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 9 6 -1.</_> + <_>0 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0111450003460050</threshold> + <left_val>0.0700009986758232</left_val> + <right_val>-1.0534820556640625</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 18 4 -1.</_> + <_>9 10 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0524530000984669</threshold> + <left_val>-1.7594360113143921</left_val> + <right_val>0.1952379941940308</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 19 -1.</_> + <_>8 0 8 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2302069962024689</threshold> + <left_val>0.9584029912948608</left_val> + <right_val>-0.2504569888114929</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 8 12 -1.</_> + <_>9 7 8 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0163659993559122</threshold> + <left_val>0.4673190116882324</left_val> + <right_val>-0.2110839933156967</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 10 -1.</_> + <_>12 6 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0172080006450415</threshold> + <left_val>0.7083569765090942</left_val> + <right_val>-0.2801829874515533</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 9 10 12 -1.</_> + <_>12 9 5 6 2.</_> + <_>7 15 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0366480015218258</threshold> + <left_val>-1.1013339757919312</left_val> + <right_val>0.2434110045433044</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 3 19 -1.</_> + <_>6 0 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0103049995377660</threshold> + <left_val>-1.0933129787445068</left_val> + <right_val>0.0562589988112450</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 6 10 -1.</_> + <_>16 0 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0137130003422499</threshold> + <left_val>-0.2643809914588928</left_val> + <right_val>0.1982100009918213</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 6 12 -1.</_> + <_>2 0 3 6 2.</_> + <_>5 6 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0293080005794764</threshold> + <left_val>-0.2214239984750748</left_val> + <right_val>1.0525950193405151</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 24 2 -1.</_> + <_>0 12 24 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0240770000964403</threshold> + <left_val>0.1848569959402084</left_val> + <right_val>-1.7203969955444336</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 9 13 4 -1.</_> + <_>4 11 13 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.1280000954866409e-003</threshold> + <left_val>-0.9272149801254273</left_val> + <right_val>0.0587529987096787</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 6 9 -1.</_> + <_>9 11 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0223779994994402</threshold> + <left_val>1.9646559953689575</left_val> + <right_val>0.0277859997004271</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 16 4 -1.</_> + <_>0 14 16 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.0440000854432583e-003</threshold> + <left_val>0.2142760008573532</left_val> + <right_val>-0.4840759932994843</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 12 6 9 -1.</_> + <_>18 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0406030006706715</threshold> + <left_val>-1.1754349470138550</left_val> + <right_val>0.1606120020151138</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 6 9 -1.</_> + <_>0 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0244660004973412</threshold> + <left_val>-1.1239900588989258</left_val> + <right_val>0.0411100015044212</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 10 4 -1.</_> + <_>8 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.5309999473392963e-003</threshold> + <left_val>-0.1716970056295395</left_val> + <right_val>0.3217880129814148</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 6 9 -1.</_> + <_>10 7 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0195889994502068</threshold> + <left_val>0.8272020220756531</left_val> + <right_val>-0.2637670040130615</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 6 9 -1.</_> + <_>13 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0296359993517399</threshold> + <left_val>-1.1524770259857178</left_val> + <right_val>0.1499930024147034</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0150300003588200</threshold> + <left_val>-1.0491830110549927</left_val> + <right_val>0.0401609987020493</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 3 6 15 -1.</_> + <_>14 3 2 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0607150010764599</threshold> + <left_val>-1.0903840065002441</left_val> + <right_val>0.1533080041408539</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 6 15 -1.</_> + <_>8 3 2 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0127900000661612</threshold> + <left_val>0.4224860072135925</left_val> + <right_val>-0.4239920079708099</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 2 9 4 -1.</_> + <_>15 4 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0202479995787144</threshold> + <left_val>-0.9186699986457825</left_val> + <right_val>0.1848569959402084</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 6 7 -1.</_> + <_>8 10 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0306839998811483</threshold> + <left_val>-1.5958670377731323</left_val> + <right_val>2.5760000571608543e-003</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 14 6 10 -1.</_> + <_>9 19 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0207180008292198</threshold> + <left_val>-0.6629999876022339</left_val> + <right_val>0.3103719949722290</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 13 5 8 -1.</_> + <_>7 17 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.7290000105276704e-003</threshold> + <left_val>0.1918340027332306</left_val> + <right_val>-0.6508499979972839</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 5 3 16 -1.</_> + <_>14 13 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0313940010964870</threshold> + <left_val>-0.6364300251007080</left_val> + <right_val>0.1540839970111847</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 17 18 3 -1.</_> + <_>2 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0190030001103878</threshold> + <left_val>-0.1891939938068390</left_val> + <right_val>1.5294510126113892</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 18 19 3 -1.</_> + <_>5 19 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.1769997701048851e-003</threshold> + <left_val>-0.1059790030121803</left_val> + <right_val>0.6485959887504578</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 9 -1.</_> + <_>11 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0101659996435046</threshold> + <left_val>-1.0802700519561768</left_val> + <right_val>0.0371760018169880</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 4 3 18 -1.</_> + <_>13 4 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.4169999631121755e-003</threshold> + <left_val>0.3415749967098236</left_val> + <right_val>-0.0977379977703094</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 4 3 18 -1.</_> + <_>10 4 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.0799998678267002e-003</threshold> + <left_val>0.4762459993362427</left_val> + <right_val>-0.3436630070209503</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 3 18 9 -1.</_> + <_>9 3 6 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0440969988703728</threshold> + <left_val>0.9763429760932922</left_val> + <right_val>-0.0191730000078678</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 6 14 -1.</_> + <_>8 1 2 14 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0606699995696545</threshold> + <left_val>-2.1752851009368896</left_val> + <right_val>-0.0289259999990463</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 16 9 6 -1.</_> + <_>12 19 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0329319983720779</threshold> + <left_val>-0.6438310146331787</left_val> + <right_val>0.1649409979581833</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 3 20 16 -1.</_> + <_>1 3 10 8 2.</_> + <_>11 11 10 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1472280025482178</threshold> + <left_val>-1.4745830297470093</left_val> + <right_val>2.5839998852461576e-003</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 5 6 12 -1.</_> + <_>15 5 3 6 2.</_> + <_>12 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0119300000369549</threshold> + <left_val>0.4244140088558197</left_val> + <right_val>-0.1771260052919388</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 22 16 -1.</_> + <_>1 2 11 8 2.</_> + <_>12 10 11 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1451790034770966</threshold> + <left_val>0.0254449993371964</left_val> + <right_val>-1.2779400348663330</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 5 10 -1.</_> + <_>10 19 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0514479987323284</threshold> + <left_val>0.1567839980125427</left_val> + <right_val>-1.5188430547714233</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 18 3 -1.</_> + <_>3 22 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.1479999888688326e-003</threshold> + <left_val>-0.4042440056800842</left_val> + <right_val>0.3242970108985901</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 6 10 -1.</_> + <_>12 14 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0436000004410744</threshold> + <left_val>-1.9932260513305664</left_val> + <right_val>0.1501860022544861</right_val></_></_></trees> + <stage_threshold>-3.8832089900970459</stage_threshold> + <parent>6</parent> + <next>-1</next></_> + <_> + <!-- stage 8 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 4 -1.</_> + <_>8 2 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1289959996938705</threshold> + <left_val>-0.6216199994087219</left_val> + <right_val>1.1116520166397095</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 9 -1.</_> + <_>6 7 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0912619978189468</threshold> + <left_val>1.0143059492111206</left_val> + <right_val>-0.6133520007133484</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 5 -1.</_> + <_>10 6 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0142719997093081</threshold> + <left_val>-1.0261659622192383</left_val> + <right_val>0.3977999985218048</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 14 12 -1.</_> + <_>5 12 14 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0328899994492531</threshold> + <left_val>-1.1386079788208008</left_val> + <right_val>0.2869080007076263</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 14 8 10 -1.</_> + <_>4 14 4 5 2.</_> + <_>8 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0125900004059076</threshold> + <left_val>-0.5664560198783875</left_val> + <right_val>0.4517239928245544</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 5 14 -1.</_> + <_>11 13 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0146610001102090</threshold> + <left_val>0.3050599992275238</left_val> + <right_val>-0.6812959909439087</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 3 16 -1.</_> + <_>7 14 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0335559993982315</threshold> + <left_val>-1.7208939790725708</left_val> + <right_val>0.0614390000700951</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 18 8 -1.</_> + <_>9 7 6 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1425269991159439</threshold> + <left_val>0.2319220006465912</left_val> + <right_val>-1.7297149896621704</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 3 20 2 -1.</_> + <_>2 4 20 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.2079997733235359e-003</threshold> + <left_val>-1.2163300514221191</left_val> + <right_val>0.1216019988059998</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 12 19 6 -1.</_> + <_>3 14 19 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0181789994239807</threshold> + <left_val>0.3255369961261749</left_val> + <right_val>-0.8100399971008301</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 6 9 -1.</_> + <_>10 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0250369999557734</threshold> + <left_val>-0.3169879913330078</left_val> + <right_val>0.6736140251159668</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 6 6 14 -1.</_> + <_>16 6 3 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0465609990060329</threshold> + <left_val>-0.1108980029821396</left_val> + <right_val>0.8408250212669373</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 9 6 12 -1.</_> + <_>9 9 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.9999996125698090e-003</threshold> + <left_val>0.3957450091838837</left_val> + <right_val>-0.4762459993362427</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 6 6 18 -1.</_> + <_>21 6 3 9 2.</_> + <_>18 15 3 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0408059991896153</threshold> + <left_val>-1.8000000272877514e-004</left_val> + <right_val>0.9457070231437683</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 6 18 -1.</_> + <_>0 6 3 9 2.</_> + <_>3 15 3 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0342219993472099</threshold> + <left_val>0.7520629763603210</left_val> + <right_val>-0.3153150081634522</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 9 -1.</_> + <_>18 5 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0397160016000271</threshold> + <left_val>-0.8313959836959839</left_val> + <right_val>0.1774439960718155</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 15 6 -1.</_> + <_>3 20 15 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.5170000735670328e-003</threshold> + <left_val>-0.5937799811363220</left_val> + <right_val>0.2465700060129166</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 9 -1.</_> + <_>18 5 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0274289995431900</threshold> + <left_val>0.1599839925765991</left_val> + <right_val>-0.4278199970722199</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 9 -1.</_> + <_>0 5 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0349860005080700</threshold> + <left_val>0.0350559987127781</left_val> + <right_val>-1.5988600254058838</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 18 2 -1.</_> + <_>5 11 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.4970000162720680e-003</threshold> + <left_val>-0.5203430056571960</left_val> + <right_val>0.3782829940319061</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 12 6 -1.</_> + <_>6 2 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.7699999045580626e-003</threshold> + <left_val>-0.5318260192871094</left_val> + <right_val>0.2495100051164627</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 6 9 -1.</_> + <_>12 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0351740010082722</threshold> + <left_val>0.1998340040445328</left_val> + <right_val>-1.4446129798889160</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 6 9 -1.</_> + <_>10 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0259709991514683</threshold> + <left_val>0.0444269999861717</left_val> + <right_val>-1.3622980117797852</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 12 9 6 -1.</_> + <_>15 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0157839991152287</threshold> + <left_val>-0.9102039933204651</left_val> + <right_val>0.2719030082225800</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 13 6 -1.</_> + <_>3 8 13 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.5880000367760658e-003</threshold> + <left_val>0.0920649990439415</left_val> + <right_val>-0.8162890076637268</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 12 9 6 -1.</_> + <_>15 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0207540001720190</threshold> + <left_val>0.2118570059537888</left_val> + <right_val>-0.7472900152206421</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 6 15 -1.</_> + <_>5 5 3 15 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0598290003836155</threshold> + <left_val>-0.2730109989643097</left_val> + <right_val>0.8092330098152161</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 9 6 -1.</_> + <_>11 8 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0390390008687973</threshold> + <left_val>-0.1043229997158051</left_val> + <right_val>0.8622620105743408</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 3 14 -1.</_> + <_>8 13 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0216659996658564</threshold> + <left_val>0.0627090036869049</left_val> + <right_val>-0.9889429807662964</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 12 9 6 -1.</_> + <_>15 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0274969991296530</threshold> + <left_val>-0.9269099831581116</left_val> + <right_val>0.1558630019426346</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 10 4 -1.</_> + <_>9 12 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0104620000347495</threshold> + <left_val>0.1341809928417206</left_val> + <right_val>-0.7038639783859253</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 1 4 19 -1.</_> + <_>13 1 2 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0248709991574287</threshold> + <left_val>0.1970670074224472</left_val> + <right_val>-0.4026330113410950</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 4 19 -1.</_> + <_>9 1 2 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0160360001027584</threshold> + <left_val>-1.1409829854965210</left_val> + <right_val>0.0739979967474937</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 9 6 9 -1.</_> + <_>18 12 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0486270003020763</threshold> + <left_val>0.1699039936065674</left_val> + <right_val>-0.7215219736099243</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 21 18 3 -1.</_> + <_>1 22 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.2619999470189214e-003</threshold> + <left_val>-0.4738979935646057</left_val> + <right_val>0.2625499963760376</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 10 9 -1.</_> + <_>14 16 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0880350023508072</threshold> + <left_val>-2.1606519222259521</left_val> + <right_val>0.1455480009317398</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 22 4 -1.</_> + <_>1 13 11 2 2.</_> + <_>12 15 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0183569993823767</threshold> + <left_val>0.0447509996592999</left_val> + <right_val>-1.0766370296478271</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 16 6 -1.</_> + <_>12 6 8 3 2.</_> + <_>4 9 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0352750010788441</threshold> + <left_val>-0.0329190008342266</left_val> + <right_val>1.2153890132904053</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 18 22 -1.</_> + <_>1 0 9 11 2.</_> + <_>10 11 9 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2039290070533752</threshold> + <left_val>-1.3187999725341797</left_val> + <right_val>0.0155039997771382</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 8 14 -1.</_> + <_>14 7 4 7 2.</_> + <_>10 14 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0166190005838871</threshold> + <left_val>0.3685019910335541</left_val> + <right_val>-0.1528369933366776</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 6 20 -1.</_> + <_>0 4 3 10 2.</_> + <_>3 14 3 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0377390012145042</threshold> + <left_val>-0.2572779953479767</left_val> + <right_val>0.7065529823303223</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 6 9 -1.</_> + <_>17 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.2720000706613064e-003</threshold> + <left_val>-0.0776029974222183</left_val> + <right_val>0.3336780071258545</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 6 9 -1.</_> + <_>5 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0148029997944832</threshold> + <left_val>-0.7852479815483093</left_val> + <right_val>0.0769340023398399</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 12 6 12 -1.</_> + <_>18 12 3 6 2.</_> + <_>15 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0483190007507801</threshold> + <left_val>1.7022320032119751</left_val> + <right_val>0.0497220009565353</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 12 6 12 -1.</_> + <_>3 12 3 6 2.</_> + <_>6 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0295390002429485</threshold> + <left_val>0.7767069935798645</left_val> + <right_val>-0.2453429996967316</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 12 9 6 -1.</_> + <_>15 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0461690016090870</threshold> + <left_val>-1.4922779798507690</left_val> + <right_val>0.1234000027179718</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 9 6 -1.</_> + <_>0 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0280649997293949</threshold> + <left_val>-2.1345369815826416</left_val> + <right_val>-0.0257970001548529</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 14 19 3 -1.</_> + <_>4 15 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.7339998893439770e-003</threshold> + <left_val>0.5698260068893433</left_val> + <right_val>-0.1205660030245781</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 13 19 3 -1.</_> + <_>2 14 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0101110003888607</threshold> + <left_val>0.6791139841079712</left_val> + <right_val>-0.2663800120353699</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 10 6 -1.</_> + <_>14 17 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0113599998876452</threshold> + <left_val>0.2478979974985123</left_val> + <right_val>-0.6449300050735474</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 10 12 -1.</_> + <_>6 0 5 6 2.</_> + <_>11 6 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0518090017139912</threshold> + <left_val>0.0147160002961755</left_val> + <right_val>-1.2395579814910889</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 1 6 12 -1.</_> + <_>20 1 3 6 2.</_> + <_>17 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0332919992506504</threshold> + <left_val>-8.2559995353221893e-003</left_val> + <right_val>1.0168470144271851</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 6 12 -1.</_> + <_>1 1 3 6 2.</_> + <_>4 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0144940000027418</threshold> + <left_val>0.4506680071353912</left_val> + <right_val>-0.3625099956989288</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 14 6 9 -1.</_> + <_>16 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0342219993472099</threshold> + <left_val>-0.9529250264167786</left_val> + <right_val>0.2068459987640381</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 3 9 12 -1.</_> + <_>7 9 9 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0806540027260780</threshold> + <left_val>-2.0139501094818115</left_val> + <right_val>-0.0230849999934435</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 4 12 -1.</_> + <_>12 7 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.9399999706074595e-004</threshold> + <left_val>0.3957200050354004</left_val> + <right_val>-0.2935130000114441</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 14 8 -1.</_> + <_>4 4 14 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0971620008349419</threshold> + <left_val>-0.2498030066490173</left_val> + <right_val>1.0859220027923584</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 6 9 -1.</_> + <_>12 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0366140007972717</threshold> + <left_val>-0.0578440017998219</left_val> + <right_val>1.2162159681320190</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 10 18 3 -1.</_> + <_>8 10 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0516939982771873</threshold> + <left_val>0.0430629998445511</left_val> + <right_val>-1.0636160373687744</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 15 9 6 -1.</_> + <_>15 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0245570000261068</threshold> + <left_val>-0.4894680082798004</left_val> + <right_val>0.1718290001153946</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 21 23 -1.</_> + <_>7 1 7 23 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.3273679912090302</threshold> + <left_val>-0.2968859970569611</left_val> + <right_val>0.5179830193519592</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 17 4 -1.</_> + <_>6 11 17 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.6959999278187752e-003</threshold> + <left_val>-0.5980589985847473</left_val> + <right_val>0.2480320036411285</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 11 18 -1.</_> + <_>1 6 11 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1617220044136047</threshold> + <left_val>-0.0296139996498823</left_val> + <right_val>-2.3162529468536377</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 15 13 6 -1.</_> + <_>6 17 13 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.7889999113976955e-003</threshold> + <left_val>0.3745790123939514</left_val> + <right_val>-0.3277919888496399</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 9 6 -1.</_> + <_>0 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0184029992669821</threshold> + <left_val>-0.9969270229339600</left_val> + <right_val>0.0729480013251305</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 15 4 -1.</_> + <_>13 7 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0776650011539459</threshold> + <left_val>0.1417569965124130</left_val> + <right_val>-1.7238730192184448</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 9 -1.</_> + <_>9 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0189210008829832</threshold> + <left_val>-0.2127310037612915</left_val> + <right_val>1.0165189504623413</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 18 3 -1.</_> + <_>12 8 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0793979987502098</threshold> + <left_val>-1.3164349794387817</left_val> + <right_val>0.1498199999332428</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 24 4 -1.</_> + <_>8 14 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0680370032787323</threshold> + <left_val>0.4942199885845184</left_val> + <right_val>-0.2909100055694580</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 10 3 12 -1.</_> + <_>16 16 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.1010001227259636e-003</threshold> + <left_val>0.4243049919605255</left_val> + <right_val>-0.3389930129051209</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 24 3 -1.</_> + <_>0 4 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0319270007312298</threshold> + <left_val>-0.0310469996184111</left_val> + <right_val>-2.3459999561309814</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 17 10 6 -1.</_> + <_>14 19 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0298439990729094</threshold> + <left_val>-0.7898960113525391</left_val> + <right_val>0.1541769951581955</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 18 3 -1.</_> + <_>7 13 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0805419981479645</threshold> + <left_val>-2.2509229183197021</left_val> + <right_val>-0.0309069994837046</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 18 9 -1.</_> + <_>5 3 18 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.8109999150037766e-003</threshold> + <left_val>-0.2557730078697205</left_val> + <right_val>0.2378550022840500</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 16 9 -1.</_> + <_>4 6 16 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0336470007896423</threshold> + <left_val>-0.2254139930009842</left_val> + <right_val>0.9230740070343018</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 5 3 12 -1.</_> + <_>16 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.2809999585151672e-003</threshold> + <left_val>-0.2889620065689087</left_val> + <right_val>0.3104619979858398</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 18 4 -1.</_> + <_>6 7 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1010439991950989</threshold> + <left_val>-0.0348640009760857</left_val> + <right_val>-2.7102620601654053</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 6 9 -1.</_> + <_>12 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0100090000778437</threshold> + <left_val>0.5971540212631226</left_val> + <right_val>-0.0338310003280640</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 6 10 -1.</_> + <_>11 8 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.1919998154044151e-003</threshold> + <left_val>-0.4773800075054169</left_val> + <right_val>0.2268600016832352</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 15 6 9 -1.</_> + <_>11 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0249690003693104</threshold> + <left_val>0.2287770062685013</left_val> + <right_val>-1.0435529947280884</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 18 21 -1.</_> + <_>12 1 9 21 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2790800034999847</threshold> + <left_val>-0.2581810057163239</left_val> + <right_val>0.7678049802780151</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 12 7 -1.</_> + <_>6 8 6 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0442130006849766</threshold> + <left_val>-0.5979800224304199</left_val> + <right_val>0.2803989946842194</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 5 6 9 -1.</_> + <_>10 5 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0141369998455048</threshold> + <left_val>0.7098730206489563</left_val> + <right_val>-0.2564519941806793</right_val></_></_></trees> + <stage_threshold>-3.8424909114837646</stage_threshold> + <parent>7</parent> + <next>-1</next></_> + <_> + <!-- stage 9 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 4 -1.</_> + <_>8 2 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1377120018005371</threshold> + <left_val>-0.5587059855461121</left_val> + <right_val>1.0953769683837891</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 7 5 12 -1.</_> + <_>14 11 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0344609990715981</threshold> + <left_val>-0.7117189764976502</left_val> + <right_val>0.5289959907531738</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 5 12 -1.</_> + <_>5 11 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0185800008475780</threshold> + <left_val>-1.1157519817352295</left_val> + <right_val>0.4059399962425232</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0250419992953539</threshold> + <left_val>-0.4089249968528748</left_val> + <right_val>0.7412999868392944</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 17 -1.</_> + <_>3 1 3 17 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0571790002286434</threshold> + <left_val>-0.3805429935455322</left_val> + <right_val>0.7364770174026489</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 19 9 -1.</_> + <_>3 4 19 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0149320000782609</threshold> + <left_val>-0.6994550228118897</left_val> + <right_val>0.3795099854469299</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 12 6 -1.</_> + <_>3 18 6 3 2.</_> + <_>9 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.8900001719594002e-003</threshold> + <left_val>-0.5455859899520874</left_val> + <right_val>0.3633249998092651</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 4 4 19 -1.</_> + <_>20 4 2 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0304359998553991</threshold> + <left_val>-0.1012459993362427</left_val> + <right_val>0.7958589792251587</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 10 7 -1.</_> + <_>5 16 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0441600009799004</threshold> + <left_val>0.8441089987754822</left_val> + <right_val>-0.3297640085220337</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 10 12 -1.</_> + <_>13 7 5 6 2.</_> + <_>8 13 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0184610001742840</threshold> + <left_val>0.2632659971714020</left_val> + <right_val>-0.9673650264739990</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 10 12 -1.</_> + <_>6 7 5 6 2.</_> + <_>11 13 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0106149995699525</threshold> + <left_val>0.1525190025568008</left_val> + <right_val>-1.0589870214462280</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 2 9 6 -1.</_> + <_>12 2 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0459740012884140</threshold> + <left_val>-1.9918340444564819</left_val> + <right_val>0.1362909972667694</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 20 21 4 -1.</_> + <_>8 20 7 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0829000025987625</threshold> + <left_val>-0.3203719854354858</left_val> + <right_val>0.6030420064926148</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 9 6 -1.</_> + <_>9 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.9130001142621040e-003</threshold> + <left_val>0.5958660244941711</left_val> + <right_val>-0.2113959938287735</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 2 9 6 -1.</_> + <_>10 2 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0428140014410019</threshold> + <left_val>0.0229250006377697</left_val> + <right_val>-1.4679330587387085</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 4 14 -1.</_> + <_>13 0 2 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.7139997631311417e-003</threshold> + <left_val>-0.4398950040340424</left_val> + <right_val>0.2043969929218292</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 4 14 -1.</_> + <_>9 0 2 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.3390002101659775e-003</threshold> + <left_val>-0.8906679749488831</left_val> + <right_val>0.1046999990940094</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 9 6 -1.</_> + <_>14 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.0749997869133949e-003</threshold> + <left_val>0.2116419970989227</left_val> + <right_val>-0.4023160040378571</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 8 18 5 -1.</_> + <_>8 8 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0967390015721321</threshold> + <left_val>0.0133199999108911</left_val> + <right_val>-1.6085360050201416</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 3 6 11 -1.</_> + <_>20 3 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0305369999259710</threshold> + <left_val>1.0063740015029907</left_val> + <right_val>-0.1341329962015152</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 11 14 -1.</_> + <_>6 12 11 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0608559995889664</threshold> + <left_val>-1.4689979553222656</left_val> + <right_val>9.4240000471472740e-003</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 4 6 9 -1.</_> + <_>18 7 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0381620004773140</threshold> + <left_val>-0.8163639903068543</left_val> + <right_val>0.2617120146751404</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 9 6 -1.</_> + <_>7 8 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.6960002556443214e-003</threshold> + <left_val>0.1156169995665550</left_val> + <right_val>-0.7169319987297058</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 4 6 9 -1.</_> + <_>18 7 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0489029996097088</threshold> + <left_val>0.1305049955844879</left_val> + <right_val>-1.6448370218276978</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 6 9 -1.</_> + <_>0 7 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0416119992733002</threshold> + <left_val>-1.1795840263366699</left_val> + <right_val>0.0250170007348061</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 4 9 4 -1.</_> + <_>9 6 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0201880000531673</threshold> + <left_val>0.6318820118904114</left_val> + <right_val>-0.1049040034413338</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 22 19 2 -1.</_> + <_>0 23 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.7900000400841236e-004</threshold> + <left_val>0.1850779950618744</left_val> + <right_val>-0.5356590151786804</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 14 6 9 -1.</_> + <_>17 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0336220003664494</threshold> + <left_val>-0.9312760233879089</left_val> + <right_val>0.2007150053977966</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 14 6 9 -1.</_> + <_>1 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0194559991359711</threshold> + <left_val>0.0380290001630783</left_val> + <right_val>-1.0112210512161255</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 11 4 9 -1.</_> + <_>14 11 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.1800000579096377e-004</threshold> + <left_val>0.3645769953727722</left_val> + <right_val>-0.2761090099811554</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 4 9 -1.</_> + <_>8 11 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.8899999344721437e-004</threshold> + <left_val>0.1966589987277985</left_val> + <right_val>-0.5341050028800964</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 18 7 -1.</_> + <_>9 9 6 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0934960022568703</threshold> + <left_val>-1.6772350072860718</left_val> + <right_val>0.2072709947824478</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 10 -1.</_> + <_>9 17 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0778779983520508</threshold> + <left_val>-3.0760629177093506</left_val> + <right_val>-0.0358039997518063</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 6 9 -1.</_> + <_>14 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0169479995965958</threshold> + <left_val>0.2144739925861359</left_val> + <right_val>-0.7137629985809326</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 6 9 -1.</_> + <_>8 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0214590001851320</threshold> + <left_val>-1.1468060016632080</left_val> + <right_val>0.0158559996634722</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 17 18 3 -1.</_> + <_>6 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0128659997135401</threshold> + <left_val>0.8381239771842957</left_val> + <right_val>-0.0659440010786057</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 17 18 3 -1.</_> + <_>1 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.8220004215836525e-003</threshold> + <left_val>-0.2802680134773254</left_val> + <right_val>0.7937690019607544</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 11 12 -1.</_> + <_>10 12 11 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1029440015554428</threshold> + <left_val>0.1783230006694794</left_val> + <right_val>-0.6841220259666443</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 6 -1.</_> + <_>5 6 7 3 2.</_> + <_>12 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0374879986047745</threshold> + <left_val>0.9618999958038330</left_val> + <right_val>-0.2173559963703156</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 15 4 -1.</_> + <_>5 6 15 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0255059991031885</threshold> + <left_val>0.0101039996370673</left_val> + <right_val>1.2461110353469849</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 22 2 -1.</_> + <_>0 1 22 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.6700001480057836e-004</threshold> + <left_val>-0.5348820090293884</left_val> + <right_val>0.1474629938602448</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 24 -1.</_> + <_>8 0 8 24 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2886790037155151</threshold> + <left_val>0.8217279911041260</left_val> + <right_val>-0.0149480002000928</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 15 18 4 -1.</_> + <_>10 15 9 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0912949964404106</threshold> + <left_val>-0.1960539966821671</left_val> + <right_val>1.0803170204162598</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 12 9 -1.</_> + <_>6 11 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1205660030245781</threshold> + <left_val>-0.0238489992916584</left_val> + <right_val>1.1392610073089600</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 7 12 -1.</_> + <_>4 16 7 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0737750008702278</threshold> + <left_val>-1.3583840131759644</left_val> + <right_val>-4.2039998807013035e-003</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 22 6 -1.</_> + <_>12 2 11 3 2.</_> + <_>1 5 11 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0331280007958412</threshold> + <left_val>-0.6448320150375366</left_val> + <right_val>0.2414219975471497</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 20 14 3 -1.</_> + <_>12 20 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0439370013773441</threshold> + <left_val>0.8428540229797363</left_val> + <right_val>-0.2062480002641678</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 16 -1.</_> + <_>12 0 12 8 2.</_> + <_>0 8 12 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1811019927263260</threshold> + <left_val>0.1921209990978241</left_val> + <right_val>-1.2222139835357666</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 13 18 4 -1.</_> + <_>3 13 9 2 2.</_> + <_>12 15 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0118509996682405</threshold> + <left_val>-0.7267739772796631</left_val> + <right_val>0.0526879988610744</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 10 22 2 -1.</_> + <_>2 11 22 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.5920000411570072e-003</threshold> + <left_val>-0.3630520105361939</left_val> + <right_val>0.2922379970550537</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 11 8 -1.</_> + <_>6 7 11 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.0620002225041389e-003</threshold> + <left_val>0.0581160001456738</left_val> + <right_val>-0.6716160178184509</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 5 6 6 -1.</_> + <_>14 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0237150005996227</threshold> + <left_val>0.4714210033416748</left_val> + <right_val>0.0185800008475780</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 24 6 -1.</_> + <_>0 9 24 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0671719983220100</threshold> + <left_val>-1.1331889629364014</left_val> + <right_val>0.0237809997051954</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 10 10 -1.</_> + <_>19 0 5 5 2.</_> + <_>14 5 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0653100013732910</threshold> + <left_val>0.9825350046157837</left_val> + <right_val>0.0283620003610849</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 10 10 -1.</_> + <_>0 0 5 5 2.</_> + <_>5 5 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0227910000830889</threshold> + <left_val>-0.2821370065212250</left_val> + <right_val>0.5899339914321899</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 4 -1.</_> + <_>12 1 12 2 2.</_> + <_>0 3 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0190379992127419</threshold> + <left_val>-0.6371150016784668</left_val> + <right_val>0.2651459872722626</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 18 3 -1.</_> + <_>0 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.8689999170601368e-003</threshold> + <left_val>0.3748730123043060</left_val> + <right_val>-0.3323209881782532</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 15 16 6 -1.</_> + <_>13 15 8 3 2.</_> + <_>5 18 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0401460006833076</threshold> + <left_val>-1.3048729896545410</left_val> + <right_val>0.1572429984807968</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 15 16 6 -1.</_> + <_>3 15 8 3 2.</_> + <_>11 18 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0405309982597828</threshold> + <left_val>-2.0458049774169922</left_val> + <right_val>-0.0269259996712208</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 18 3 -1.</_> + <_>6 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0122539997100830</threshold> + <left_val>0.7764940261840820</left_val> + <right_val>-0.0429710000753403</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 21 10 -1.</_> + <_>0 18 21 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0272199995815754</threshold> + <left_val>0.1742440015077591</left_val> + <right_val>-0.4460090100765228</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 6 24 -1.</_> + <_>15 0 2 24 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0883660018444061</threshold> + <left_val>-1.5036419630050659</left_val> + <right_val>0.1428990066051483</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 4 6 11 -1.</_> + <_>9 4 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.9159997403621674e-003</threshold> + <left_val>0.2866669893264771</left_val> + <right_val>-0.3792369961738586</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 9 6 -1.</_> + <_>12 5 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0419600009918213</threshold> + <left_val>1.3846950531005859</left_val> + <right_val>0.0650269985198975</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 4 2 20 -1.</_> + <_>1 14 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0456629991531372</threshold> + <left_val>-0.2245229929685593</left_val> + <right_val>0.7952100038528442</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 6 24 -1.</_> + <_>15 0 2 24 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1409060060977936</threshold> + <left_val>-1.5879319906234741</left_val> + <right_val>0.1135900020599365</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 6 24 -1.</_> + <_>7 0 2 24 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0592160001397133</threshold> + <left_val>-1.1945960521697998</left_val> + <right_val>-7.1640000678598881e-003</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 7 6 14 -1.</_> + <_>19 7 3 7 2.</_> + <_>16 14 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.3390002101659775e-003</threshold> + <left_val>-0.1552869975566864</left_val> + <right_val>0.4066449999809265</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 4 12 -1.</_> + <_>6 7 2 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.0369999110698700e-003</threshold> + <left_val>0.2592790126800537</left_val> + <right_val>-0.3836829960346222</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 24 14 -1.</_> + <_>8 5 8 14 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2751649916172028</threshold> + <left_val>-0.0884979963302612</left_val> + <right_val>0.7678750157356262</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 13 10 6 -1.</_> + <_>5 15 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0266019999980927</threshold> + <left_val>0.7502449750900269</left_val> + <right_val>-0.2262199968099594</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 6 9 -1.</_> + <_>14 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0409060008823872</threshold> + <left_val>0.1215860024094582</left_val> + <right_val>-1.4566910266876221</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 6 14 -1.</_> + <_>2 7 3 7 2.</_> + <_>5 14 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.5320002138614655e-003</threshold> + <left_val>-0.3661150038242340</left_val> + <right_val>0.2596859931945801</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 2 9 15 -1.</_> + <_>18 2 3 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0318790003657341</threshold> + <left_val>-0.0750190019607544</left_val> + <right_val>0.4848479926586151</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 9 -1.</_> + <_>2 2 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0414820015430450</threshold> + <left_val>0.7822039723396301</left_val> + <right_val>-0.2199220061302185</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 2 10 14 -1.</_> + <_>17 2 5 7 2.</_> + <_>12 9 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0961309969425201</threshold> + <left_val>-0.8945630192756653</left_val> + <right_val>0.1468070000410080</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 2 18 -1.</_> + <_>12 6 1 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0115689998492599</threshold> + <left_val>0.8271409869194031</left_val> + <right_val>-0.2027560025453568</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 15 6 -1.</_> + <_>14 5 5 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0183129999786615</threshold> + <left_val>0.0163679998368025</left_val> + <right_val>0.2730680108070374</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 6 10 -1.</_> + <_>10 6 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0341660007834435</threshold> + <left_val>1.1307320594787598</left_val> + <right_val>-0.1881089955568314</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 6 9 -1.</_> + <_>14 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0244769994169474</threshold> + <left_val>-0.5779129862785339</left_val> + <right_val>0.1581249982118607</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 3 9 7 -1.</_> + <_>6 3 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0489570014178753</threshold> + <left_val>-0.0225649997591972</left_val> + <right_val>-1.6373280286788940</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 14 3 -1.</_> + <_>6 7 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0207029990851879</threshold> + <left_val>-0.5451210141181946</left_val> + <right_val>0.2408699989318848</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 8 6 -1.</_> + <_>11 7 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0230020005255938</threshold> + <left_val>-1.2236540317535400</left_val> + <right_val>-7.3440000414848328e-003</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 7 7 12 -1.</_> + <_>12 13 7 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0645850002765656</threshold> + <left_val>0.1469559967517853</left_val> + <right_val>-0.4496749937534332</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 18 -1.</_> + <_>10 6 2 9 2.</_> + <_>12 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0126660000532866</threshold> + <left_val>-0.2787390053272247</left_val> + <right_val>0.4387660026550293</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 14 6 9 -1.</_> + <_>16 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0120029998943210</threshold> + <left_val>-0.2428909987211227</left_val> + <right_val>0.2535009980201721</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 6 13 -1.</_> + <_>6 0 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0264439992606640</threshold> + <left_val>-0.8586480021476746</left_val> + <right_val>0.0260259993374348</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 21 3 -1.</_> + <_>9 2 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0255479998886585</threshold> + <left_val>0.6928790211677551</left_val> + <right_val>-2.1160000469535589e-003</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 5 12 -1.</_> + <_>5 8 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0391150005161762</threshold> + <left_val>-0.1658910065889359</left_val> + <right_val>1.5209139585494995</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 3 4 10 -1.</_> + <_>10 8 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.0330000706017017e-003</threshold> + <left_val>0.4385690093040466</left_val> + <right_val>-0.2161370068788528</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 4 5 8 -1.</_> + <_>8 8 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0339369997382164</threshold> + <left_val>-0.9799839854240418</left_val> + <right_val>0.0221330001950264</right_val></_></_></trees> + <stage_threshold>-3.6478610038757324</stage_threshold> + <parent>8</parent> + <next>-1</next></_> + <_> + <!-- stage 10 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 11 9 -1.</_> + <_>6 3 11 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0406729988753796</threshold> + <left_val>-0.9047470092773438</left_val> + <right_val>0.6441059708595276</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 5 -1.</_> + <_>10 6 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0256099998950958</threshold> + <left_val>-0.7921699881553650</left_val> + <right_val>0.5748999714851379</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 5 -1.</_> + <_>8 0 8 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1995950043201447</threshold> + <left_val>-0.3009960055351257</left_val> + <right_val>1.3143850564956665</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 23 6 -1.</_> + <_>1 12 23 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0124049996957183</threshold> + <left_val>-0.8988299965858460</left_val> + <right_val>0.2920579910278320</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 18 3 -1.</_> + <_>9 21 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0392079986631870</threshold> + <left_val>-0.4195519983768463</left_val> + <right_val>0.5346329808235169</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 21 6 -1.</_> + <_>3 8 21 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0308439992368221</threshold> + <left_val>0.4579339921474457</left_val> + <right_val>-0.4462909996509552</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 6 12 -1.</_> + <_>2 5 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0355230011045933</threshold> + <left_val>0.9131050109863281</left_val> + <right_val>-0.2737320065498352</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 15 -1.</_> + <_>10 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0616500005125999</threshold> + <left_val>-1.4697799682617187</left_val> + <right_val>0.2036409974098206</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 8 10 -1.</_> + <_>8 12 8 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0117399999871850</threshold> + <left_val>-1.0482879877090454</left_val> + <right_val>0.0678019970655441</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 15 12 -1.</_> + <_>10 7 5 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0669339969754219</threshold> + <left_val>0.2927449941635132</left_val> + <right_val>-0.5228289961814880</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 10 6 -1.</_> + <_>0 19 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0206310003995895</threshold> + <left_val>-1.2855139970779419</left_val> + <right_val>0.0445509999990463</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 18 9 6 -1.</_> + <_>14 20 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0223570000380278</threshold> + <left_val>-0.8575379848480225</left_val> + <right_val>0.1843400001525879</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 16 -1.</_> + <_>9 14 6 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.1500000255182385e-003</threshold> + <left_val>0.1640550047159195</left_val> + <right_val>-0.6912500262260437</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 18 9 6 -1.</_> + <_>14 20 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0358729995787144</threshold> + <left_val>0.1575649976730347</left_val> + <right_val>-0.8426259756088257</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 18 9 6 -1.</_> + <_>1 20 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0306599996984005</threshold> + <left_val>0.0216370001435280</left_val> + <right_val>-1.3634690046310425</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 9 9 6 -1.</_> + <_>15 11 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.5559999309480190e-003</threshold> + <left_val>-0.1673700064420700</left_val> + <right_val>0.2588840126991272</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 9 6 -1.</_> + <_>0 11 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.1160000041127205e-003</threshold> + <left_val>-0.9727180004119873</left_val> + <right_val>0.0661000013351440</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 3 6 9 -1.</_> + <_>19 3 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0303169991821051</threshold> + <left_val>0.9847419857978821</left_val> + <right_val>-0.0164480004459620</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 17 18 3 -1.</_> + <_>2 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.7200004383921623e-003</threshold> + <left_val>0.4760470092296600</left_val> + <right_val>-0.3251670002937317</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 15 21 6 -1.</_> + <_>3 17 21 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0571269989013672</threshold> + <left_val>-0.9592069983482361</left_val> + <right_val>0.1993820071220398</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 17 6 6 -1.</_> + <_>9 20 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.0059997700154781e-003</threshold> + <left_val>-0.5261250138282776</left_val> + <right_val>0.2242870032787323</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 3 6 9 -1.</_> + <_>18 6 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0337340012192726</threshold> + <left_val>0.1707009971141815</left_val> + <right_val>-1.0737580060958862</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 9 -1.</_> + <_>0 6 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0346419997513294</threshold> + <left_val>-1.1343129873275757</left_val> + <right_val>0.0365400016307831</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 16 10 -1.</_> + <_>12 0 8 5 2.</_> + <_>4 5 8 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0469230003654957</threshold> + <left_val>0.2583230137825012</left_val> + <right_val>-0.7153580188751221</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 10 16 -1.</_> + <_>2 0 5 8 2.</_> + <_>7 8 5 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.7660001590847969e-003</threshold> + <left_val>0.1964090019464493</left_val> + <right_val>-0.5335509777069092</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 10 5 -1.</_> + <_>14 0 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0656279996037483</threshold> + <left_val>-0.0511949993669987</left_val> + <right_val>0.9761070013046265</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 10 5 -1.</_> + <_>5 0 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0441650003194809</threshold> + <left_val>1.0631920099258423</left_val> + <right_val>-0.2346259951591492</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 3 6 10 -1.</_> + <_>18 3 3 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0173049997538328</threshold> + <left_val>-0.1858289986848831</left_val> + <right_val>0.4588989913463593</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 12 6 -1.</_> + <_>5 11 6 3 2.</_> + <_>11 14 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0331359989941120</threshold> + <left_val>-0.0293819997459650</left_val> + <right_val>-2.6651329994201660</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>21 0 3 18 -1.</_> + <_>22 0 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0210299994796515</threshold> + <left_val>0.9997990131378174</left_val> + <right_val>0.0249370001256466</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 6 9 -1.</_> + <_>8 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0297839995473623</threshold> + <left_val>-0.0296059995889664</left_val> + <right_val>-2.1695868968963623</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 9 7 -1.</_> + <_>11 8 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0552919991314411</threshold> + <left_val>-7.5599999399855733e-004</left_val> + <right_val>0.7465199828147888</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 12 8 10 -1.</_> + <_>7 12 4 5 2.</_> + <_>11 17 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0335979983210564</threshold> + <left_val>-1.5274159908294678</left_val> + <right_val>0.0110600003972650</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>21 0 3 18 -1.</_> + <_>22 0 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0196029990911484</threshold> + <left_val>0.0335749983787537</left_val> + <right_val>0.9952620267868042</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 9 -1.</_> + <_>12 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0207870006561279</threshold> + <left_val>0.7661290168762207</left_val> + <right_val>-0.2467080056667328</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 9 6 -1.</_> + <_>15 2 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0325360000133514</threshold> + <left_val>0.1626340001821518</left_val> + <right_val>-0.6113430261611939</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 3 -1.</_> + <_>0 3 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0107880001887679</threshold> + <left_val>-0.9783970117568970</left_val> + <right_val>0.0289699994027615</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 7 6 9 -1.</_> + <_>13 7 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.9560003727674484e-003</threshold> + <left_val>0.4614579975605011</left_val> + <right_val>-0.1351049989461899</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 6 10 -1.</_> + <_>9 6 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.7489999085664749e-003</threshold> + <left_val>0.2545819878578186</left_val> + <right_val>-0.5195559859275818</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 6 12 -1.</_> + <_>14 1 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0417799986898899</threshold> + <left_val>-0.8056510090827942</left_val> + <right_val>0.1520850062370300</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 12 -1.</_> + <_>6 10 12 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0342210009694099</threshold> + <left_val>-1.3137799501419067</left_val> + <right_val>-3.5800000187009573e-003</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 3 2 21 -1.</_> + <_>14 3 1 21 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0101300003007054</threshold> + <left_val>0.2017579972743988</left_val> + <right_val>-0.6133959889411926</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 12 8 -1.</_> + <_>6 5 12 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0898490026593208</threshold> + <left_val>0.9763280153274536</left_val> + <right_val>-0.2088479995727539</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 18 8 -1.</_> + <_>3 4 18 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0260979998856783</threshold> + <left_val>-0.1880799978971481</left_val> + <right_val>0.4770579934120178</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 18 3 -1.</_> + <_>3 1 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.7539999466389418e-003</threshold> + <left_val>-0.6798040270805359</left_val> + <right_val>0.1128880009055138</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 24 4 -1.</_> + <_>12 13 12 2 2.</_> + <_>0 15 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0319730006158352</threshold> + <left_val>0.1895170062780380</left_val> + <right_val>-1.4967479705810547</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 4 9 -1.</_> + <_>12 5 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0193329993635416</threshold> + <left_val>-0.2360990047454834</left_val> + <right_val>0.8132050037384033</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 6 9 -1.</_> + <_>13 1 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.9490000559017062e-003</threshold> + <left_val>0.2483039945363998</left_val> + <right_val>-0.0692119970917702</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 2 6 22 -1.</_> + <_>8 2 2 22 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0441469997167587</threshold> + <left_val>-1.0418920516967773</left_val> + <right_val>0.0480530001223087</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 10 8 14 -1.</_> + <_>20 10 4 7 2.</_> + <_>16 17 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0446819998323917</threshold> + <left_val>0.5134630203247070</left_val> + <right_val>-7.3799998499453068e-003</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 16 15 -1.</_> + <_>3 9 16 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1075749993324280</threshold> + <left_val>1.6202019453048706</left_val> + <right_val>-0.1866759955883026</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 10 8 14 -1.</_> + <_>20 10 4 7 2.</_> + <_>16 17 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1284680068492889</threshold> + <left_val>2.9869480133056641</left_val> + <right_val>0.0954279974102974</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 8 14 -1.</_> + <_>0 10 4 7 2.</_> + <_>4 17 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0447579994797707</threshold> + <left_val>0.6040530204772949</left_val> + <right_val>-0.2705869972705841</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 11 6 -1.</_> + <_>10 17 11 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0439909994602203</threshold> + <left_val>-0.6179050207138062</left_val> + <right_val>0.1599719971418381</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 24 9 -1.</_> + <_>8 7 8 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1226899996399880</threshold> + <left_val>0.6632720232009888</left_val> + <right_val>-0.2363699972629547</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 1 4 16 -1.</_> + <_>13 1 2 16 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0199829991906881</threshold> + <left_val>-1.1228660345077515</left_val> + <right_val>0.1961670070886612</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 4 16 -1.</_> + <_>9 1 2 16 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0155279999598861</threshold> + <left_val>-1.0770269632339478</left_val> + <right_val>0.0206930004060268</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 16 8 -1.</_> + <_>13 5 8 4 2.</_> + <_>5 9 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0489710010588169</threshold> + <left_val>0.8116829991340637</left_val> + <right_val>-0.0172520000487566</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 6 9 -1.</_> + <_>0 12 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0559759996831417</threshold> + <left_val>-0.0225290004163980</left_val> + <right_val>-1.7356760501861572</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 18 3 -1.</_> + <_>6 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.8580000922083855e-003</threshold> + <left_val>0.6788139939308167</left_val> + <right_val>-0.0581800006330013</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 12 6 9 -1.</_> + <_>3 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0134810004383326</threshold> + <left_val>0.0578479990363121</left_val> + <right_val>-0.7725530266761780</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 14 9 6 -1.</_> + <_>8 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.5609999001026154e-003</threshold> + <left_val>-0.1314689964056015</left_val> + <right_val>0.6705579757690430</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 13 8 10 -1.</_> + <_>2 13 4 5 2.</_> + <_>6 18 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.1149999275803566e-003</threshold> + <left_val>-0.3788059949874878</left_val> + <right_val>0.3097899854183197</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 5 3 18 -1.</_> + <_>15 11 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.8159998841583729e-003</threshold> + <left_val>-0.5847039818763733</left_val> + <right_val>0.2560209929943085</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 18 3 -1.</_> + <_>3 6 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.5319999381899834e-003</threshold> + <left_val>-0.3021700084209442</left_val> + <right_val>0.4125329852104187</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 5 6 11 -1.</_> + <_>19 5 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0274749994277954</threshold> + <left_val>0.5915470123291016</left_val> + <right_val>0.0179639998823404</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 6 11 -1.</_> + <_>3 5 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0395199991762638</threshold> + <left_val>0.9691349864006043</left_val> + <right_val>-0.2102030068635941</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 1 4 9 -1.</_> + <_>19 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0306589994579554</threshold> + <left_val>0.9115589857101440</left_val> + <right_val>0.0405500009655952</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 4 9 -1.</_> + <_>3 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.4680000022053719e-003</threshold> + <left_val>-0.6048979759216309</left_val> + <right_val>0.1696089953184128</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 15 18 9 -1.</_> + <_>4 15 9 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1907760053873062</threshold> + <left_val>0.0435150004923344</left_val> + <right_val>0.8189290165901184</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 12 4 -1.</_> + <_>6 11 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.1790000870823860e-003</threshold> + <left_val>-0.9361730217933655</left_val> + <right_val>0.0249370001256466</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 2 9 6 -1.</_> + <_>15 4 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0241260007023811</threshold> + <left_val>0.1817550063133240</left_val> + <right_val>-0.3418590128421783</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 9 6 -1.</_> + <_>0 4 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0263839997351170</threshold> + <left_val>-1.2912579774856567</left_val> + <right_val>-3.4280000254511833e-003</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 6 17 -1.</_> + <_>17 0 2 17 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.4139997810125351e-003</threshold> + <left_val>-0.0462919995188713</left_val> + <right_val>0.2526960074901581</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 6 17 -1.</_> + <_>5 0 2 17 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0542160011827946</threshold> + <left_val>-0.0128480000421405</left_val> + <right_val>-1.4304540157318115</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 17 9 4 -1.</_> + <_>8 19 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.3799999326001853e-004</threshold> + <left_val>-0.2667669951915741</left_val> + <right_val>0.3358829915523529</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 3 18 -1.</_> + <_>6 11 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0152169996872544</threshold> + <left_val>-0.5136730074882507</left_val> + <right_val>0.1300510019063950</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 14 12 -1.</_> + <_>5 8 14 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0170079991221428</threshold> + <left_val>0.4157589972019196</left_val> + <right_val>-0.3124119937419891</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 3 12 -1.</_> + <_>10 8 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0304969996213913</threshold> + <left_val>-0.2482099980115891</left_val> + <right_val>0.7082849740982056</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 14 15 -1.</_> + <_>10 12 14 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.5430002287030220e-003</threshold> + <left_val>-0.2263700067996979</left_val> + <right_val>0.1918459981679916</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 14 15 -1.</_> + <_>0 12 14 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1416399925947189</threshold> + <left_val>0.0652270019054413</left_val> + <right_val>-0.8880950212478638</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 9 6 -1.</_> + <_>15 2 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0193380005657673</threshold> + <left_val>0.1889120042324066</left_val> + <right_val>-0.2739770114421845</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 9 6 -1.</_> + <_>0 2 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0173240005970001</threshold> + <left_val>-0.9486669898033142</left_val> + <right_val>0.0241969991475344</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 6 14 -1.</_> + <_>14 6 2 14 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.2069999985396862e-003</threshold> + <left_val>0.3693839907646179</left_val> + <right_val>-0.1749490052461624</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 7 6 9 -1.</_> + <_>11 7 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0161090008914471</threshold> + <left_val>0.9615949988365173</left_val> + <right_val>-0.2000530064105988</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 6 15 -1.</_> + <_>14 6 2 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1012250036001205</threshold> + <left_val>-3.0699110031127930</left_val> + <right_val>0.1136379987001419</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 6 15 -1.</_> + <_>8 6 2 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.5509999878704548e-003</threshold> + <left_val>0.2292100042104721</left_val> + <right_val>-0.4564509987831116</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 3 8 9 -1.</_> + <_>15 3 4 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0442479997873306</threshold> + <left_val>-3.1599999056197703e-004</left_val> + <right_val>0.3922530114650726</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 9 21 -1.</_> + <_>3 0 3 21 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1163600012660027</threshold> + <left_val>0.9523370265960693</left_val> + <right_val>-0.2020159959793091</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 9 8 12 -1.</_> + <_>11 13 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.7360002063214779e-003</threshold> + <left_val>-0.0991770029067993</left_val> + <right_val>0.2037049978971481</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 10 12 -1.</_> + <_>6 7 5 6 2.</_> + <_>11 13 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0224590003490448</threshold> + <left_val>8.7280003353953362e-003</left_val> + <right_val>-1.0217070579528809</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 18 -1.</_> + <_>12 6 2 9 2.</_> + <_>10 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0121090002357960</threshold> + <left_val>0.6481260061264038</left_val> + <right_val>-0.0901490002870560</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 9 -1.</_> + <_>0 3 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0561200007796288</threshold> + <left_val>-0.0367599986493587</left_val> + <right_val>-1.9275590181350708</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 14 18 3 -1.</_> + <_>3 15 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.7379999458789825e-003</threshold> + <left_val>0.6926130056381226</left_val> + <right_val>-0.0683749988675117</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 14 8 10 -1.</_> + <_>3 14 4 5 2.</_> + <_>7 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.6399998031556606e-003</threshold> + <left_val>-0.4056980013847351</left_val> + <right_val>0.1862570047378540</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 24 4 -1.</_> + <_>12 12 12 2 2.</_> + <_>0 14 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0181319992989302</threshold> + <left_val>-0.6451820135116577</left_val> + <right_val>0.2197639942169190</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 3 20 -1.</_> + <_>1 2 1 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0227189995348454</threshold> + <left_val>0.9777619838714600</left_val> + <right_val>-0.1865430027246475</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 16 10 8 -1.</_> + <_>17 16 5 4 2.</_> + <_>12 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0127050001174212</threshold> + <left_val>-0.1054660007357597</left_val> + <right_val>0.3740409910678864</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 16 10 8 -1.</_> + <_>2 16 5 4 2.</_> + <_>7 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0136829996481538</threshold> + <left_val>0.6106410026550293</left_val> + <right_val>-0.2688109874725342</right_val></_></_></trees> + <stage_threshold>-3.8700489997863770</stage_threshold> + <parent>9</parent> + <next>-1</next></_> + <_> + <!-- stage 11 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 10 9 -1.</_> + <_>7 3 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0313579998910427</threshold> + <left_val>-1.0183910131454468</left_val> + <right_val>0.5752859711647034</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 3 -1.</_> + <_>8 0 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0930500030517578</threshold> + <left_val>-0.4129750132560730</left_val> + <right_val>1.0091199874877930</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 8 15 4 -1.</_> + <_>3 10 15 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0259499996900558</threshold> + <left_val>-0.5858790278434753</left_val> + <right_val>0.5660619735717773</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 12 6 -1.</_> + <_>10 5 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0164720006287098</threshold> + <left_val>-0.9285749793052673</left_val> + <right_val>0.3092449903488159</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 13 14 6 -1.</_> + <_>5 16 14 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.8779999809339643e-003</threshold> + <left_val>0.1195100024342537</left_val> + <right_val>-1.1180130243301392</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 14 4 10 -1.</_> + <_>11 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.0129999443888664e-003</threshold> + <left_val>-0.5784950256347656</left_val> + <right_val>0.3315440118312836</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 6 7 -1.</_> + <_>3 6 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0225479993969202</threshold> + <left_val>-0.3832510113716126</left_val> + <right_val>0.5246220231056213</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 0 6 6 -1.</_> + <_>18 0 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0377800017595291</threshold> + <left_val>1.1790670156478882</left_val> + <right_val>-0.0341669991612434</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 18 3 -1.</_> + <_>3 2 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.3799999877810478e-003</threshold> + <left_val>-0.8626589775085449</left_val> + <right_val>0.1186790019273758</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 14 18 -1.</_> + <_>9 12 14 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0238930005580187</threshold> + <left_val>-0.7495059967041016</left_val> + <right_val>0.2101140022277832</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 6 -1.</_> + <_>3 0 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0265219993889332</threshold> + <left_val>0.9212859869003296</left_val> + <right_val>-0.2825280129909515</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 6 6 -1.</_> + <_>13 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0122800003737211</threshold> + <left_val>0.2666279971599579</left_val> + <right_val>-0.7001360058784485</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 20 24 3 -1.</_> + <_>8 20 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0965949967503548</threshold> + <left_val>-0.2845399975776672</left_val> + <right_val>0.7316899895668030</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 6 7 -1.</_> + <_>13 11 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0274149999022484</threshold> + <left_val>-0.6149269938468933</left_val> + <right_val>0.1557620018720627</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 10 6 -1.</_> + <_>4 14 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0157670006155968</threshold> + <left_val>0.5755119919776917</left_val> + <right_val>-0.3436219990253449</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 6 6 -1.</_> + <_>13 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.1100000012665987e-003</threshold> + <left_val>0.3259969949722290</left_val> + <right_val>-0.1300829946994782</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 6 7 -1.</_> + <_>8 11 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0120069999247789</threshold> + <left_val>0.0893229991197586</left_val> + <right_val>-0.9602559804916382</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 4 11 12 -1.</_> + <_>7 8 11 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0154219996184111</threshold> + <left_val>0.3444949984550476</left_val> + <right_val>-0.4671199917793274</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 15 10 4 -1.</_> + <_>6 17 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.1579999960958958e-003</threshold> + <left_val>0.2369630038738251</left_val> + <right_val>-0.5256329774856567</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 6 9 -1.</_> + <_>16 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0211859997361898</threshold> + <left_val>-0.7426769733428955</left_val> + <right_val>0.2170200049877167</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 6 9 -1.</_> + <_>6 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0170770008116961</threshold> + <left_val>-0.9047179818153381</left_val> + <right_val>0.0660120025277138</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 2 4 15 -1.</_> + <_>11 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0408499985933304</threshold> + <left_val>-0.3444660007953644</left_val> + <right_val>0.2150370031595230</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 20 3 -1.</_> + <_>0 1 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.1930002197623253e-003</threshold> + <left_val>-0.9338859915733337</left_val> + <right_val>0.0504710003733635</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 18 10 6 -1.</_> + <_>13 20 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0192380007356405</threshold> + <left_val>-0.5320370197296143</left_val> + <right_val>0.1724060028791428</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 6 11 -1.</_> + <_>5 7 3 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0441920012235641</threshold> + <left_val>0.9207500219345093</left_val> + <right_val>-0.2214850038290024</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 10 9 -1.</_> + <_>10 17 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0623920001089573</threshold> + <left_val>-0.7105380296707153</left_val> + <right_val>0.1832389980554581</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 4 9 -1.</_> + <_>10 2 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.0079999919980764e-003</threshold> + <left_val>-0.8706309795379639</left_val> + <right_val>0.0553300008177757</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 3 10 4 -1.</_> + <_>14 3 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0238700006157160</threshold> + <left_val>-0.2285420000553131</left_val> + <right_val>0.5241559743881226</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 6 -1.</_> + <_>6 6 6 3 2.</_> + <_>12 9 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0213910005986691</threshold> + <left_val>-0.3032589852809906</left_val> + <right_val>0.5586060285568237</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 8 10 -1.</_> + <_>12 8 4 5 2.</_> + <_>8 13 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0202549993991852</threshold> + <left_val>0.2690150141716003</left_val> + <right_val>-0.7026180028915405</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 4 4 16 -1.</_> + <_>7 12 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0287720002233982</threshold> + <left_val>-1.1835030317306519</left_val> + <right_val>0.0465120002627373</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 9 4 -1.</_> + <_>8 10 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.4199999645352364e-003</threshold> + <left_val>-0.5465210080146790</left_val> + <right_val>0.2596249878406525</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 14 9 -1.</_> + <_>5 5 14 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0569830015301704</threshold> + <left_val>-0.2698290050029755</left_val> + <right_val>0.5817070007324219</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 16 19 8 -1.</_> + <_>3 20 19 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0938920006155968</threshold> + <left_val>-0.9104639887809753</left_val> + <right_val>0.1967770010232925</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 10 8 -1.</_> + <_>5 0 5 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0176999997347593</threshold> + <left_val>-0.4400329887866974</left_val> + <right_val>0.2134950011968613</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 16 18 -1.</_> + <_>5 2 8 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2284419983625412</threshold> + <left_val>0.0236050002276897</left_val> + <right_val>0.7717159986495972</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 24 11 -1.</_> + <_>8 11 8 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1828750073909760</threshold> + <left_val>0.7922859787940979</left_val> + <right_val>-0.2464479953050613</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 3 18 5 -1.</_> + <_>3 3 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0698919966816902</threshold> + <left_val>0.8026779890060425</left_val> + <right_val>-0.0360720008611679</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 16 18 3 -1.</_> + <_>1 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0152970002964139</threshold> + <left_val>-0.2007230073213577</left_val> + <right_val>1.1030600070953369</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 17 18 3 -1.</_> + <_>5 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.7500001750886440e-003</threshold> + <left_val>-0.0459679998457432</left_val> + <right_val>0.7209450006484985</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 9 6 -1.</_> + <_>1 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0159830003976822</threshold> + <left_val>-0.9035720229148865</left_val> + <right_val>0.0449879989027977</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 9 23 10 -1.</_> + <_>1 14 23 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0130880000069737</threshold> + <left_val>0.3529709875583649</left_val> + <right_val>-0.3771060109138489</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 18 3 -1.</_> + <_>3 8 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0130610000342131</threshold> + <left_val>-0.1958359926939011</left_val> + <right_val>1.1198940277099609</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 12 3 -1.</_> + <_>6 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0399070009589195</threshold> + <left_val>-1.3998429775238037</left_val> + <right_val>0.1914509981870651</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 2 3 22 -1.</_> + <_>7 2 1 22 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0150269996374846</threshold> + <left_val>2.3600000422447920e-003</left_val> + <right_val>-1.1611249446868896</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 17 10 6 -1.</_> + <_>14 19 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0205179993063211</threshold> + <left_val>-0.4890809953212738</left_val> + <right_val>0.1674340069293976</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 18 10 6 -1.</_> + <_>1 20 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0223590005189180</threshold> + <left_val>-1.2202980518341064</left_val> + <right_val>-0.0119759999215603</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 3 6 12 -1.</_> + <_>13 3 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.9150004312396049e-003</threshold> + <left_val>0.3722809851169586</left_val> + <right_val>-0.0850630030035973</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 9 -1.</_> + <_>12 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0152580002322793</threshold> + <left_val>-0.2941260039806366</left_val> + <right_val>0.5940639972686768</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 6 9 -1.</_> + <_>13 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0316659994423389</threshold> + <left_val>-1.4395569562911987</left_val> + <right_val>0.1357879936695099</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0307739991694689</threshold> + <left_val>-2.2545371055603027</left_val> + <right_val>-0.0339710004627705</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 10 9 6 -1.</_> + <_>15 10 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0154830003157258</threshold> + <left_val>0.3770070075988770</left_val> + <right_val>0.0158479996025562</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 6 9 -1.</_> + <_>5 11 3 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0351670011878014</threshold> + <left_val>-0.2944610118865967</left_val> + <right_val>0.5315909981727600</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 5 3 19 -1.</_> + <_>15 5 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0179060008376837</threshold> + <left_val>-0.9978820085525513</left_val> + <right_val>0.1623599976301193</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 9 6 -1.</_> + <_>6 8 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.1799999997019768e-003</threshold> + <left_val>0.0476570017635822</left_val> + <right_val>-0.7524989843368530</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 5 3 19 -1.</_> + <_>15 5 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0157200004905462</threshold> + <left_val>0.1487379968166351</left_val> + <right_val>-0.6537539958953857</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 9 -1.</_> + <_>0 6 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0298640001565218</threshold> + <left_val>-0.0149520002305508</left_val> + <right_val>-1.2275190353393555</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 21 18 3 -1.</_> + <_>5 22 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.9899999499320984e-003</threshold> + <left_val>-0.1426369994878769</left_val> + <right_val>0.4327279925346375</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 18 4 -1.</_> + <_>7 10 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0847499966621399</threshold> + <left_val>-0.0192809998989105</left_val> + <right_val>-1.1946409940719604</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 4 8 10 -1.</_> + <_>17 4 4 5 2.</_> + <_>13 9 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0587249994277954</threshold> + <left_val>-1.7328219413757324</left_val> + <right_val>0.1437470018863678</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 9 6 -1.</_> + <_>10 8 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0447559989988804</threshold> + <left_val>-0.2414059937000275</left_val> + <right_val>0.5401999950408936</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 9 9 8 -1.</_> + <_>15 9 3 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0403690002858639</threshold> + <left_val>5.7680001482367516e-003</left_val> + <right_val>0.5657809972763062</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 5 12 -1.</_> + <_>0 10 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0377359986305237</threshold> + <left_val>0.0381809994578362</left_val> + <right_val>-0.7937039732933044</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 14 6 -1.</_> + <_>14 6 7 3 2.</_> + <_>7 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0607529990375042</threshold> + <left_val>0.0764530003070831</left_val> + <right_val>1.4813209772109985</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 3 19 -1.</_> + <_>8 5 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0198320001363754</threshold> + <left_val>-1.6971720457077026</left_val> + <right_val>-0.0273700002580881</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 4 15 20 -1.</_> + <_>13 4 5 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1659269928932190</threshold> + <left_val>0.6297600269317627</left_val> + <right_val>0.0317629985511303</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 4 15 20 -1.</_> + <_>6 4 5 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0690149962902069</threshold> + <left_val>-0.3346320092678070</left_val> + <right_val>0.3007670044898987</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 10 6 6 -1.</_> + <_>13 10 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0113580003380775</threshold> + <left_val>0.2274149954319000</left_val> + <right_val>-0.3822470009326935</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 6 6 -1.</_> + <_>8 10 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.7000000225380063e-003</threshold> + <left_val>0.1922380030155182</left_val> + <right_val>-0.5273510217666626</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 2 6 14 -1.</_> + <_>17 2 3 7 2.</_> + <_>14 9 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0797690004110336</threshold> + <left_val>0.0914919972419739</left_val> + <right_val>2.1049048900604248</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 2 6 14 -1.</_> + <_>4 2 3 7 2.</_> + <_>7 9 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0571440011262894</threshold> + <left_val>-1.7452130317687988</left_val> + <right_val>-0.0409100018441677</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 4 6 7 -1.</_> + <_>12 4 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.3830001056194305e-003</threshold> + <left_val>-0.2421479970216751</left_val> + <right_val>0.3557780086994171</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 4 6 9 -1.</_> + <_>11 4 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0180409997701645</threshold> + <left_val>1.1779999732971191</left_val> + <right_val>-0.1767670065164566</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 4 8 10 -1.</_> + <_>11 4 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0945030003786087</threshold> + <left_val>0.1393609941005707</left_val> + <right_val>-1.2993700504302979</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 8 10 -1.</_> + <_>9 4 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.4210000671446323e-003</threshold> + <left_val>-0.5460860133171082</left_val> + <right_val>0.1391640007495880</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 10 6 -1.</_> + <_>8 20 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.0290002040565014e-003</threshold> + <left_val>-0.2159720063209534</left_val> + <right_val>0.3925809860229492</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 18 21 6 -1.</_> + <_>1 20 21 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0345159992575645</threshold> + <left_val>0.0631889998912811</left_val> + <right_val>-0.7210810184478760</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 2 12 6 -1.</_> + <_>9 2 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0519249998033047</threshold> + <left_val>0.6866760253906250</left_val> + <right_val>0.0632729977369308</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 12 6 -1.</_> + <_>9 2 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0691620036959648</threshold> + <left_val>1.7411810159683228</left_val> + <right_val>-0.1661929935216904</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 5 12 6 -1.</_> + <_>18 5 6 3 2.</_> + <_>12 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.5229999125003815e-003</threshold> + <left_val>0.3069469928741455</left_val> + <right_val>-0.1666290014982224</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 6 9 -1.</_> + <_>8 11 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0685999989509583</threshold> + <left_val>-0.2140540033578873</left_val> + <right_val>0.7318500280380249</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 20 6 -1.</_> + <_>2 9 20 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0670389980077744</threshold> + <left_val>-0.7936059832572937</left_val> + <right_val>0.2052579969167709</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 12 6 -1.</_> + <_>0 5 6 3 2.</_> + <_>6 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0210050009191036</threshold> + <left_val>0.3734439909458160</left_val> + <right_val>-0.2961860001087189</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 14 8 10 -1.</_> + <_>18 14 4 5 2.</_> + <_>14 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0202789995819330</threshold> + <left_val>-0.0152000002563000</left_val> + <right_val>0.4055530130863190</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 14 8 10 -1.</_> + <_>2 14 4 5 2.</_> + <_>6 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0471079982817173</threshold> + <left_val>1.2116849422454834</left_val> + <right_val>-0.1746429949998856</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 20 13 -1.</_> + <_>2 11 10 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1876849979162216</threshold> + <left_val>-0.0229090005159378</left_val> + <right_val>0.6964579820632935</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 12 5 -1.</_> + <_>12 9 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0432289987802505</threshold> + <left_val>-1.0602480173110962</left_val> + <right_val>-5.5599998449906707e-004</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 16 6 -1.</_> + <_>13 6 8 3 2.</_> + <_>5 9 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0200040005147457</threshold> + <left_val>-0.0327510014176369</left_val> + <right_val>0.5380510091781616</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 19 9 4 -1.</_> + <_>1 21 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.0880001187324524e-003</threshold> + <left_val>0.0375480018556118</left_val> + <right_val>-0.7476890087127686</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 12 5 -1.</_> + <_>11 5 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0271010007709265</threshold> + <left_val>-0.0817900002002716</left_val> + <right_val>0.3338710069656372</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 14 12 -1.</_> + <_>3 5 7 6 2.</_> + <_>10 11 7 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0917460024356842</threshold> + <left_val>-1.9213509559631348</left_val> + <right_val>-0.0389529988169670</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 4 9 6 -1.</_> + <_>12 4 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0124549996107817</threshold> + <left_val>0.4836060106754303</left_val> + <right_val>0.0181680005043745</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 6 19 3 -1.</_> + <_>2 7 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0146490000188351</threshold> + <left_val>-0.1990669965744019</left_val> + <right_val>0.7281540036201477</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 10 6 9 -1.</_> + <_>18 13 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0291019994765520</threshold> + <left_val>0.1987109929323196</left_val> + <right_val>-0.4921680092811585</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 18 2 -1.</_> + <_>3 8 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.7799998000264168e-003</threshold> + <left_val>-0.1949959993362427</left_val> + <right_val>0.7731739878654480</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 2 4 18 -1.</_> + <_>22 2 2 9 2.</_> + <_>20 11 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0547400005161762</threshold> + <left_val>1.8087190389633179</left_val> + <right_val>0.0683230012655258</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 18 20 3 -1.</_> + <_>2 19 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0147980004549026</threshold> + <left_val>0.7806490063667297</left_val> + <right_val>-0.1870959997177124</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 9 22 3 -1.</_> + <_>1 10 22 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0250129997730255</threshold> + <left_val>0.1528529971837997</left_val> + <right_val>-1.6021020412445068</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 4 18 -1.</_> + <_>0 2 2 9 2.</_> + <_>2 11 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0465480014681816</threshold> + <left_val>-0.1673820018768311</left_val> + <right_val>1.1902060508728027</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 0 4 23 -1.</_> + <_>19 0 2 23 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0176240000873804</threshold> + <left_val>-0.1028549969196320</left_val> + <right_val>0.3917590081691742</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 19 -1.</_> + <_>3 3 3 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1631959974765778</threshold> + <left_val>-0.0356240011751652</left_val> + <right_val>-1.6098170280456543</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 9 -1.</_> + <_>20 2 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0131379999220371</threshold> + <left_val>-0.0563590005040169</left_val> + <right_val>0.5415890216827393</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 10 6 -1.</_> + <_>0 7 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0156650003045797</threshold> + <left_val>0.2806310057640076</left_val> + <right_val>-0.3170860111713409</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 12 12 -1.</_> + <_>13 0 6 6 2.</_> + <_>7 6 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0805540010333061</threshold> + <left_val>0.1264040023088455</left_val> + <right_val>-1.0297529697418213</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 24 6 -1.</_> + <_>0 3 12 3 2.</_> + <_>12 6 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0353639982640743</threshold> + <left_val>0.0207529999315739</left_val> + <right_val>-0.7910559773445129</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 4 10 -1.</_> + <_>10 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0329869985580444</threshold> + <left_val>0.1905709952116013</left_val> + <right_val>-0.8383989930152893</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 9 4 15 -1.</_> + <_>8 14 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0121950004249811</threshold> + <left_val>0.0737290009856224</left_val> + <right_val>-0.6278070211410523</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 11 17 6 -1.</_> + <_>4 14 17 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0430659987032413</threshold> + <left_val>0.0473849996924400</left_val> + <right_val>1.5712939500808716</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 18 8 -1.</_> + <_>2 5 9 4 2.</_> + <_>11 9 9 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0303269997239113</threshold> + <left_val>-0.2731460034847260</left_val> + <right_val>0.3857200145721436</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 14 6 -1.</_> + <_>14 6 7 3 2.</_> + <_>7 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0354930013418198</threshold> + <left_val>0.0545939989387989</left_val> + <right_val>0.5258340239524841</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 14 6 -1.</_> + <_>3 6 7 3 2.</_> + <_>10 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0145969996228814</threshold> + <left_val>0.3815259933471680</left_val> + <right_val>-0.2833240032196045</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 5 3 18 -1.</_> + <_>17 5 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0126069998368621</threshold> + <left_val>0.1545509994029999</left_val> + <right_val>-0.3050149977207184</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 3 18 -1.</_> + <_>6 5 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0101720001548529</threshold> + <left_val>0.0236370004713535</left_val> + <right_val>-0.8721789717674255</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 10 14 4 -1.</_> + <_>10 12 14 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0288430005311966</threshold> + <left_val>0.1609099954366684</left_val> + <right_val>-0.2027759999036789</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 10 9 4 -1.</_> + <_>4 12 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.5100000463426113e-004</threshold> + <left_val>-0.6154540181159973</left_val> + <right_val>0.0809359997510910</right_val></_></_></trees> + <stage_threshold>-3.7160909175872803</stage_threshold> + <parent>10</parent> + <next>-1</next></_> + <_> + <!-- stage 12 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 18 9 -1.</_> + <_>2 3 18 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0483440011739731</threshold> + <left_val>-0.8490459918975830</left_val> + <right_val>0.5697439908981323</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 12 8 -1.</_> + <_>10 3 4 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0324600003659725</threshold> + <left_val>-0.8141729831695557</left_val> + <right_val>0.4478169977664948</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 8 5 -1.</_> + <_>5 1 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0333399996161461</threshold> + <left_val>-0.3642379939556122</left_val> + <right_val>0.6793739795684815</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 7 7 8 -1.</_> + <_>12 11 7 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.4019998535513878e-003</threshold> + <left_val>-1.1885459423065186</left_val> + <right_val>0.1923869997262955</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 22 4 -1.</_> + <_>0 14 22 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.6889997795224190e-003</threshold> + <left_val>0.3308529853820801</left_val> + <right_val>-0.7133409976959229</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 6 4 15 -1.</_> + <_>15 11 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0126980002969503</threshold> + <left_val>-0.5099080204963684</left_val> + <right_val>0.1137629970908165</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 7 8 -1.</_> + <_>5 11 7 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.0549997724592686e-003</threshold> + <left_val>-1.0470550060272217</left_val> + <right_val>0.2022259980440140</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 9 4 -1.</_> + <_>8 20 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.6420000940561295e-003</threshold> + <left_val>-0.5055940151214600</left_val> + <right_val>0.3644120097160339</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 22 4 -1.</_> + <_>1 4 22 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0169259998947382</threshold> + <left_val>-0.9954190254211426</left_val> + <right_val>0.1260219961404800</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 3 6 17 -1.</_> + <_>19 3 2 17 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0282359998673201</threshold> + <left_val>-0.0941379964351654</left_val> + <right_val>0.5778040289878845</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 8 18 -1.</_> + <_>8 11 8 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0104289995506406</threshold> + <left_val>0.2327290028333664</left_val> + <right_val>-0.5256969928741455</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 0 6 12 -1.</_> + <_>20 0 3 6 2.</_> + <_>17 6 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.8860003054141998e-003</threshold> + <left_val>-0.1031629964709282</left_val> + <right_val>0.4765760004520416</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0260150004178286</threshold> + <left_val>-1.0920000495389104e-003</left_val> + <right_val>-1.5581729412078857</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 5 9 12 -1.</_> + <_>15 11 9 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0255379993468523</threshold> + <left_val>-0.6545140147209168</left_val> + <right_val>0.1884319931268692</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 22 18 2 -1.</_> + <_>2 23 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.5310001112520695e-003</threshold> + <left_val>0.2814059853553772</left_val> + <right_val>-0.4457530081272125</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 10 12 6 -1.</_> + <_>16 10 6 3 2.</_> + <_>10 13 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.2449998483061790e-003</threshold> + <left_val>0.1561200022697449</left_val> + <right_val>-0.2137099951505661</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 4 11 -1.</_> + <_>2 1 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0210309997200966</threshold> + <left_val>-0.2917029857635498</left_val> + <right_val>0.5223410129547119</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 0 4 10 -1.</_> + <_>20 0 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0510630011558533</threshold> + <left_val>1.3661290407180786</left_val> + <right_val>0.0304659996181726</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 3 6 17 -1.</_> + <_>3 3 2 17 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0623300001025200</threshold> + <left_val>1.2207020521163940</left_val> + <right_val>-0.2243440002202988</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 15 9 6 -1.</_> + <_>15 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0329630002379417</threshold> + <left_val>-0.8201680183410645</left_val> + <right_val>0.1453189998865128</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 8 9 -1.</_> + <_>0 16 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0374180004000664</threshold> + <left_val>-1.2218099832534790</left_val> + <right_val>0.0194489993155003</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 8 6 12 -1.</_> + <_>16 12 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1240279972553253</threshold> + <left_val>0.1208230033516884</left_val> + <right_val>-0.9872930049896240</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 8 6 12 -1.</_> + <_>2 12 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.9229997247457504e-003</threshold> + <left_val>-1.1688489913940430</left_val> + <right_val>0.0211050007492304</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 15 -1.</_> + <_>10 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0598799996078014</threshold> + <left_val>-1.0689330101013184</left_val> + <right_val>0.1986020058393478</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 19 3 -1.</_> + <_>1 6 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.2620001845061779e-003</threshold> + <left_val>-0.3622959852218628</left_val> + <right_val>0.3800080120563507</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 8 9 7 -1.</_> + <_>14 8 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0176730006933212</threshold> + <left_val>0.4909409880638123</left_val> + <right_val>-0.1460669934749603</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 8 12 9 -1.</_> + <_>3 11 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0175790004432201</threshold> + <left_val>0.5872809886932373</left_val> + <right_val>-0.2777439951896668</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 3 -1.</_> + <_>3 7 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.1560001447796822e-003</threshold> + <left_val>-0.0751949995756149</left_val> + <right_val>0.6019309759140015</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 4 12 -1.</_> + <_>10 6 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0105999996885657</threshold> + <left_val>0.2763740122318268</left_val> + <right_val>-0.3779430091381073</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 18 14 -1.</_> + <_>3 9 9 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2088409960269928</threshold> + <left_val>-5.3599998354911804e-003</left_val> + <right_val>1.0317809581756592</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 4 9 -1.</_> + <_>2 0 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0264129992574453</threshold> + <left_val>0.8233640193939209</left_val> + <right_val>-0.2248059958219528</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 5 4 18 -1.</_> + <_>12 5 2 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0588920004665852</threshold> + <left_val>0.1309829950332642</left_val> + <right_val>-1.1853699684143066</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 5 4 18 -1.</_> + <_>10 5 2 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0115790003910661</threshold> + <left_val>-0.9066780209541321</left_val> + <right_val>0.0441269986331463</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 6 10 -1.</_> + <_>12 5 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0459880009293556</threshold> + <left_val>0.0101439999416471</left_val> + <right_val>1.0740900039672852</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 4 4 11 -1.</_> + <_>11 4 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0228380002081394</threshold> + <left_val>1.7791990041732788</left_val> + <right_val>-0.1731549948453903</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 16 18 3 -1.</_> + <_>4 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.1709995865821838e-003</threshold> + <left_val>0.5738630294799805</left_val> + <right_val>-0.0741060003638268</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 20 3 -1.</_> + <_>0 17 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.5359999164938927e-003</threshold> + <left_val>-0.3207289874553680</left_val> + <right_val>0.4018250107765198</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 9 6 12 -1.</_> + <_>9 13 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0494449995458126</threshold> + <left_val>0.1928800046443939</left_val> + <right_val>-1.2166700363159180</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 13 8 8 -1.</_> + <_>8 17 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.5139999818056822e-003</threshold> + <left_val>0.0695680007338524</left_val> + <right_val>-0.7132369875907898</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 10 3 12 -1.</_> + <_>13 16 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0309960003942251</threshold> + <left_val>-0.3886219859123230</left_val> + <right_val>0.1809879988431931</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 9 14 14 -1.</_> + <_>5 9 7 7 2.</_> + <_>12 16 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0864529982209206</threshold> + <left_val>-0.0257929991930723</left_val> + <right_val>-1.5453219413757324</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 10 -1.</_> + <_>12 0 12 5 2.</_> + <_>0 5 12 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1365260034799576</threshold> + <left_val>-1.9199420213699341</left_val> + <right_val>0.1661330014467239</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 11 18 2 -1.</_> + <_>1 12 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.7689999230206013e-003</threshold> + <left_val>-1.2822589874267578</left_val> + <right_val>-0.0159079991281033</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 5 5 12 -1.</_> + <_>19 9 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0178999993950129</threshold> + <left_val>-0.4040989875793457</left_val> + <right_val>0.2359160035848618</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 5 12 -1.</_> + <_>0 9 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0199699997901917</threshold> + <left_val>-0.7289190292358398</left_val> + <right_val>0.0562350004911423</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 6 8 18 -1.</_> + <_>20 6 4 9 2.</_> + <_>16 15 4 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0574930012226105</threshold> + <left_val>0.5783079862594605</left_val> + <right_val>-0.0157960001379251</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 8 18 -1.</_> + <_>0 6 4 9 2.</_> + <_>4 15 4 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0830560028553009</threshold> + <left_val>0.9151160120964050</left_val> + <right_val>-0.2112140059471130</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 5 12 12 -1.</_> + <_>18 5 6 6 2.</_> + <_>12 11 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0537710003554821</threshold> + <left_val>-0.5193129777908325</left_val> + <right_val>0.1857600063085556</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 6 9 -1.</_> + <_>9 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.3670001477003098e-003</threshold> + <left_val>0.2410970032215118</left_val> + <right_val>-0.3964860141277313</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 13 6 11 -1.</_> + <_>11 13 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0554069988429546</threshold> + <left_val>0.1677120029926300</left_val> + <right_val>-2.5664970874786377</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 12 12 -1.</_> + <_>0 5 6 6 2.</_> + <_>6 11 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0671809986233711</threshold> + <left_val>-1.3658570051193237</left_val> + <right_val>-0.0142320003360510</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 23 3 -1.</_> + <_>1 3 23 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0239000003784895</threshold> + <left_val>-1.7084569931030273</left_val> + <right_val>0.1650779992341995</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 15 19 3 -1.</_> + <_>1 16 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.5949999950826168e-003</threshold> + <left_val>-0.3137399852275848</left_val> + <right_val>0.3283790051937103</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 17 11 4 -1.</_> + <_>13 19 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0212949998676777</threshold> + <left_val>0.1495340019464493</left_val> + <right_val>-0.4857980012893677</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 8 5 -1.</_> + <_>4 13 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0246130004525185</threshold> + <left_val>0.7434639930725098</left_val> + <right_val>-0.2230519950389862</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 10 10 4 -1.</_> + <_>12 10 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0196260008960962</threshold> + <left_val>-0.4091829955577850</left_val> + <right_val>0.1889320015907288</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 9 9 -1.</_> + <_>4 9 9 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0532660000026226</threshold> + <left_val>0.8138160109519959</left_val> + <right_val>-0.2085369974374771</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 14 9 6 -1.</_> + <_>15 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.1290000341832638e-003</threshold> + <left_val>0.3299610018730164</left_val> + <right_val>-0.5993739962577820</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 12 9 6 -1.</_> + <_>1 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0224869996309280</threshold> + <left_val>-1.2551610469818115</left_val> + <right_val>-0.0204130001366138</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 20 8 -1.</_> + <_>13 10 10 4 2.</_> + <_>3 14 10 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0823109969496727</threshold> + <left_val>1.3821430206298828</left_val> + <right_val>0.0593089982867241</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 9 18 -1.</_> + <_>5 0 3 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1309700012207031</threshold> + <left_val>-0.0358439981937408</left_val> + <right_val>-1.5396369695663452</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 9 10 -1.</_> + <_>16 11 3 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0142930001020432</threshold> + <left_val>-0.1847520023584366</left_val> + <right_val>0.3745500147342682</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 8 5 -1.</_> + <_>5 2 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.3479999080300331e-003</threshold> + <left_val>-0.4490109980106354</left_val> + <right_val>0.1387699991464615</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 21 6 -1.</_> + <_>10 4 7 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0460550002753735</threshold> + <left_val>0.6783260107040405</left_val> + <right_val>-0.0170719996094704</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 10 14 -1.</_> + <_>7 0 5 7 2.</_> + <_>12 7 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0576939992606640</threshold> + <left_val>-0.0119559997692704</left_val> + <right_val>-1.2261159420013428</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 17 12 4 -1.</_> + <_>12 19 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.0609998181462288e-003</threshold> + <left_val>0.3395859897136688</left_val> + <right_val>6.2800000887364149e-004</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 23 4 -1.</_> + <_>0 8 23 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0521630011498928</threshold> + <left_val>-1.0621069669723511</left_val> + <right_val>-0.0137799996882677</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 10 8 10 -1.</_> + <_>17 10 4 5 2.</_> + <_>13 15 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0465729981660843</threshold> + <left_val>0.1453880071640015</left_val> + <right_val>-1.2384550571441650</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 18 3 -1.</_> + <_>0 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.5309998355805874e-003</threshold> + <left_val>-0.2446770071983337</left_val> + <right_val>0.5137709975242615</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 16 9 4 -1.</_> + <_>15 18 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0216150004416704</threshold> + <left_val>0.1307259947061539</left_val> + <right_val>-0.7099679708480835</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 9 4 -1.</_> + <_>0 18 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0178640000522137</threshold> + <left_val>-1.0474660396575928</left_val> + <right_val>4.9599999329075217e-004</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 6 6 -1.</_> + <_>13 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0371950007975101</threshold> + <left_val>-1.5126730203628540</left_val> + <right_val>0.1480139940977097</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 6 6 -1.</_> + <_>8 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.1100001069717109e-004</threshold> + <left_val>0.1397150009870529</left_val> + <right_val>-0.4686749875545502</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 24 6 -1.</_> + <_>12 3 12 3 2.</_> + <_>0 6 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0250429995357990</threshold> + <left_val>0.2863200008869171</left_val> + <right_val>-0.4179469943046570</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 4 18 3 -1.</_> + <_>2 5 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.3449996784329414e-003</threshold> + <left_val>-0.2733620107173920</left_val> + <right_val>0.4344469904899597</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 4 -1.</_> + <_>12 0 12 2 2.</_> + <_>0 2 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0323639996349812</threshold> + <left_val>0.1843889951705933</left_val> + <right_val>-0.9501929879188538</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 16 18 3 -1.</_> + <_>1 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.2299999408423901e-003</threshold> + <left_val>0.3258199989795685</left_val> + <right_val>-0.3081560134887695</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 15 9 6 -1.</_> + <_>15 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0514889992773533</threshold> + <left_val>0.1141600012779236</left_val> + <right_val>-1.9795479774475098</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 9 6 -1.</_> + <_>0 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0264490004628897</threshold> + <left_val>-1.1067299842834473</left_val> + <right_val>-8.5519999265670776e-003</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 17 18 3 -1.</_> + <_>6 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0154200000688434</threshold> + <left_val>0.8013870120048523</left_val> + <right_val>-0.0320350006222725</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 6 10 -1.</_> + <_>10 8 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0194569993764162</threshold> + <left_val>-0.2644949853420258</left_val> + <right_val>0.3875389993190765</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 6 9 -1.</_> + <_>12 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0336209982633591</threshold> + <left_val>0.0160520002245903</left_val> + <right_val>0.5884090065956116</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 5 8 -1.</_> + <_>8 12 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0289060007780790</threshold> + <left_val>0.0152160003781319</left_val> + <right_val>-0.9472360014915466</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 8 6 8 -1.</_> + <_>12 12 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.0300000323913991e-004</threshold> + <left_val>-0.3076600134372711</left_val> + <right_val>0.2123589962720871</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 6 11 -1.</_> + <_>8 5 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0491419993340969</threshold> + <left_val>-1.6058609485626221</left_val> + <right_val>-0.0310949999839067</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 6 8 9 -1.</_> + <_>13 9 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0764259994029999</threshold> + <left_val>0.0747589990496635</left_val> + <right_val>1.1639410257339478</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 7 21 6 -1.</_> + <_>1 9 21 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0238979998975992</threshold> + <left_val>-6.4320000819861889e-003</left_val> + <right_val>-1.1150749921798706</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 5 3 12 -1.</_> + <_>15 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.8970001041889191e-003</threshold> + <left_val>-0.2410569936037064</left_val> + <right_val>0.2085890024900436</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 11 12 -1.</_> + <_>6 13 11 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0894450023770332</threshold> + <left_val>1.9157789945602417</left_val> + <right_val>-0.1572110056877136</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 8 10 8 -1.</_> + <_>18 8 5 4 2.</_> + <_>13 12 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0150089999660850</threshold> + <left_val>-0.2517409920692444</left_val> + <right_val>0.1817989945411682</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 12 3 -1.</_> + <_>11 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0111459996551275</threshold> + <left_val>-0.6934949755668640</left_val> + <right_val>0.0449279993772507</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 18 4 -1.</_> + <_>12 11 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0945789963006973</threshold> + <left_val>0.1810210049152374</left_val> + <right_val>-0.7497860193252564</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 22 22 -1.</_> + <_>0 11 22 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.5503889918327332</threshold> + <left_val>-0.0309740006923676</left_val> + <right_val>-1.6746139526367188</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 2 6 8 -1.</_> + <_>11 6 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0413810014724731</threshold> + <left_val>0.0639100000262260</left_val> + <right_val>0.7656120061874390</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 9 -1.</_> + <_>11 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0247719995677471</threshold> + <left_val>0.0113800000399351</left_val> + <right_val>-0.8855940103530884</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 6 9 -1.</_> + <_>12 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0509990006685257</threshold> + <left_val>0.1489029973745346</left_val> + <right_val>-2.4634211063385010</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 3 6 14 -1.</_> + <_>8 3 3 7 2.</_> + <_>11 10 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0168939996510744</threshold> + <left_val>0.3887099921703339</left_val> + <right_val>-0.2988030016422272</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 18 8 -1.</_> + <_>9 10 6 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1216230019927025</threshold> + <left_val>-1.5542800426483154</left_val> + <right_val>0.1630080044269562</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 3 14 -1.</_> + <_>10 7 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.6049999762326479e-003</threshold> + <left_val>0.2184280008077622</left_val> + <right_val>-0.3731209933757782</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 16 20 -1.</_> + <_>4 13 16 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1157540008425713</threshold> + <left_val>-0.0470610000193119</left_val> + <right_val>0.5940369963645935</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 4 6 10 -1.</_> + <_>11 4 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0369039997458458</threshold> + <left_val>-0.2550860047340393</left_val> + <right_val>0.5539730191230774</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 16 4 -1.</_> + <_>5 2 16 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0114839999005198</threshold> + <left_val>-0.1812949925661087</left_val> + <right_val>0.4068279862403870</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 18 4 -1.</_> + <_>8 5 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0202339999377728</threshold> + <left_val>0.5431119799613953</left_val> + <right_val>-0.2382239997386932</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 6 9 -1.</_> + <_>15 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0287650004029274</threshold> + <left_val>-0.6917229890823364</left_val> + <right_val>0.1594330072402954</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 4 8 5 -1.</_> + <_>12 4 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.8320001699030399e-003</threshold> + <left_val>0.2944779992103577</left_val> + <right_val>-0.3400599956512451</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 10 10 4 -1.</_> + <_>12 10 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0554689988493919</threshold> + <left_val>0.9220079779624939</left_val> + <right_val>0.0940930023789406</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 10 10 4 -1.</_> + <_>7 10 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0148010002449155</threshold> + <left_val>-0.7953969836235046</left_val> + <right_val>0.0315219983458519</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 11 12 5 -1.</_> + <_>11 11 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.0940000005066395e-003</threshold> + <left_val>0.3309600055217743</left_val> + <right_val>-0.0508869998157024</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 8 10 -1.</_> + <_>3 10 4 5 2.</_> + <_>7 15 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0451240018010139</threshold> + <left_val>-1.3719749450683594</left_val> + <right_val>-0.0214089993387461</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 12 9 8 -1.</_> + <_>14 12 3 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0643770024180412</threshold> + <left_val>0.0639019981026649</left_val> + <right_val>0.9147830009460449</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 21 24 3 -1.</_> + <_>8 21 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0147270001471043</threshold> + <left_val>0.3605059981346130</left_val> + <right_val>-0.2861450016498566</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 20 18 4 -1.</_> + <_>9 20 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0450070016086102</threshold> + <left_val>-0.1561969965696335</left_val> + <right_val>0.5316029787063599</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 15 9 6 -1.</_> + <_>1 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.1330000124871731e-003</threshold> + <left_val>0.1342290043830872</left_val> + <right_val>-0.4435890018939972</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 17 10 4 -1.</_> + <_>11 19 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0494510009884834</threshold> + <left_val>0.1057180017232895</left_val> + <right_val>-2.5589139461517334</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 4 12 -1.</_> + <_>9 18 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0291029997169971</threshold> + <left_val>-0.0100880004465580</left_val> + <right_val>-1.1073939800262451</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 9 6 -1.</_> + <_>12 6 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0347860008478165</threshold> + <left_val>-2.7719999197870493e-003</left_val> + <right_val>0.5670099854469299</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 6 9 -1.</_> + <_>1 16 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.1309998854994774e-003</threshold> + <left_val>-0.4688940048217773</left_val> + <right_val>0.1263639926910400</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 12 4 -1.</_> + <_>6 18 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0155250001698732</threshold> + <left_val>-8.4279999136924744e-003</left_val> + <right_val>0.8746920228004456</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 20 3 -1.</_> + <_>1 6 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.9249999206513166e-003</threshold> + <left_val>-0.3443430066108704</left_val> + <right_val>0.2085160017013550</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 9 9 -1.</_> + <_>8 4 9 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0535710006952286</threshold> + <left_val>1.4982949495315552</left_val> + <right_val>0.0573280006647110</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 19 9 4 -1.</_> + <_>2 21 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0192179996520281</threshold> + <left_val>-0.9923409819602966</left_val> + <right_val>-9.3919998034834862e-003</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 4 18 -1.</_> + <_>11 7 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0552829988300800</threshold> + <left_val>-0.5768229961395264</left_val> + <right_val>0.1686059981584549</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 2 8 12 -1.</_> + <_>7 2 4 6 2.</_> + <_>11 8 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0563360005617142</threshold> + <left_val>-0.0337750017642975</left_val> + <right_val>-1.3889650106430054</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 10 9 8 -1.</_> + <_>14 10 3 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0238240007311106</threshold> + <left_val>0.4018209874629974</left_val> + <right_val>1.8360000103712082e-003</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 12 5 -1.</_> + <_>9 11 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.7810000572353601e-003</threshold> + <left_val>0.1814599931240082</left_val> + <right_val>-0.4174340069293976</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 9 9 6 -1.</_> + <_>14 9 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0376890003681183</threshold> + <left_val>0.5468310117721558</left_val> + <right_val>0.0182199999690056</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 6 9 -1.</_> + <_>7 10 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0241449996829033</threshold> + <left_val>0.6835209727287293</left_val> + <right_val>-0.1965020000934601</right_val></_></_></trees> + <stage_threshold>-3.5645289421081543</stage_threshold> + <parent>11</parent> + <next>-1</next></_> + <_> + <!-- stage 13 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 5 12 -1.</_> + <_>4 11 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0274449996650219</threshold> + <left_val>-0.8998420238494873</left_val> + <right_val>0.5187649726867676</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 21 6 -1.</_> + <_>9 0 7 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1155410036444664</threshold> + <left_val>-0.5652440190315247</left_val> + <right_val>0.7055130004882813</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 10 6 -1.</_> + <_>7 8 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0222970005124807</threshold> + <left_val>0.3607999980449677</left_val> + <right_val>-0.6686459779739380</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 15 -1.</_> + <_>11 0 2 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0133250001817942</threshold> + <left_val>-0.5557339787483215</left_val> + <right_val>0.3578999936580658</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 18 2 -1.</_> + <_>2 3 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.8060001097619534e-003</threshold> + <left_val>-1.0713000297546387</left_val> + <right_val>0.1885000020265579</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 17 8 6 -1.</_> + <_>8 20 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.6819999329745770e-003</threshold> + <left_val>-0.7158430218696594</left_val> + <right_val>0.2634449899196625</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 18 2 -1.</_> + <_>3 1 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.3819999080151320e-003</threshold> + <left_val>-0.4693079888820648</left_val> + <right_val>0.2665840089321137</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 9 6 -1.</_> + <_>11 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0376430004835129</threshold> + <left_val>0.2109870016574860</left_val> + <right_val>-1.0804339647293091</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 18 3 -1.</_> + <_>0 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0138619998469949</threshold> + <left_val>0.6691200137138367</left_val> + <right_val>-0.2794280052185059</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 12 5 -1.</_> + <_>10 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.7350001037120819e-003</threshold> + <left_val>-0.9533230066299439</left_val> + <right_val>0.2405129969120026</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 9 -1.</_> + <_>2 3 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0383369997143745</threshold> + <left_val>0.8143280148506165</left_val> + <right_val>-0.2491939961910248</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 2 4 9 -1.</_> + <_>20 2 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0346979983150959</threshold> + <left_val>1.2330100536346436</left_val> + <right_val>6.8600000813603401e-003</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 4 9 -1.</_> + <_>2 2 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0233609993010759</threshold> + <left_val>-0.3079470098018646</left_val> + <right_val>0.7071449756622315</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 4 -1.</_> + <_>12 1 12 2 2.</_> + <_>0 3 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0350579991936684</threshold> + <left_val>0.2120590060949326</left_val> + <right_val>-1.4399830102920532</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 9 6 -1.</_> + <_>0 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0132569996640086</threshold> + <left_val>-0.9026070237159729</left_val> + <right_val>0.0486100018024445</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 9 6 -1.</_> + <_>14 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0127400001510978</threshold> + <left_val>0.2265519946813583</left_val> + <right_val>-0.4464380145072937</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 19 3 -1.</_> + <_>0 16 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.6400000099092722e-003</threshold> + <left_val>-0.3981789946556091</left_val> + <right_val>0.3466539978981018</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 22 12 -1.</_> + <_>12 5 11 6 2.</_> + <_>1 11 11 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1006470024585724</threshold> + <left_val>0.1838359981775284</left_val> + <right_val>-1.3410769701004028</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 13 6 6 -1.</_> + <_>8 13 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.</threshold> + <left_val>0.1553640067577362</left_val> + <right_val>-0.5158249735832214</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 2 20 3 -1.</_> + <_>4 3 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0117089999839664</threshold> + <left_val>0.2165140062570572</left_val> + <right_val>-0.7270519733428955</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 14 6 10 -1.</_> + <_>10 14 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0359649993479252</threshold> + <left_val>-1.4789500236511230</left_val> + <right_val>-0.0243170000612736</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 12 16 6 -1.</_> + <_>14 12 8 3 2.</_> + <_>6 15 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0212360005825758</threshold> + <left_val>-0.1684409976005554</left_val> + <right_val>0.1952659934759140</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 13 8 9 -1.</_> + <_>2 16 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0148740001022816</threshold> + <left_val>0.0373359993100166</left_val> + <right_val>-0.8755729794502258</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 8 6 14 -1.</_> + <_>14 8 3 7 2.</_> + <_>11 15 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.1409997977316380e-003</threshold> + <left_val>0.3346650004386902</left_val> + <right_val>-0.2410970032215118</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 16 6 -1.</_> + <_>2 12 8 3 2.</_> + <_>10 15 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0234500002115965</threshold> + <left_val>5.5320002138614655e-003</left_val> + <right_val>-1.2509720325469971</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 16 16 8 -1.</_> + <_>5 20 16 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0250620003789663</threshold> + <left_val>0.4521239995956421</left_val> + <right_val>-0.0844699963927269</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 4 12 -1.</_> + <_>9 7 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.7400001464411616e-004</threshold> + <left_val>0.1524990051984787</left_val> + <right_val>-0.4848650097846985</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 8 10 -1.</_> + <_>12 2 4 5 2.</_> + <_>8 7 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0404839999973774</threshold> + <left_val>-1.3024920225143433</left_val> + <right_val>0.1798350065946579</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 6 -1.</_> + <_>6 6 6 3 2.</_> + <_>12 9 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0281709991395473</threshold> + <left_val>-0.2441090047359467</left_val> + <right_val>0.6227110028266907</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 6 9 -1.</_> + <_>12 7 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0456929989159107</threshold> + <left_val>0.0281220003962517</left_val> + <right_val>0.9239439964294434</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 8 12 -1.</_> + <_>0 0 4 6 2.</_> + <_>4 6 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0397070012986660</threshold> + <left_val>-0.2233279943466187</left_val> + <right_val>0.7767400145530701</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 8 6 9 -1.</_> + <_>18 11 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0505170002579689</threshold> + <left_val>0.2031999975442886</left_val> + <right_val>-1.0895930528640747</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 6 6 -1.</_> + <_>5 12 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0172669999301434</threshold> + <left_val>0.6859840154647827</left_val> + <right_val>-0.2330449968576431</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 21 3 -1.</_> + <_>10 21 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0801860019564629</threshold> + <left_val>-0.0102920001372695</left_val> + <right_val>0.6188110113143921</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 16 6 -1.</_> + <_>2 3 16 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0976760014891624</threshold> + <left_val>-0.2007029950618744</left_val> + <right_val>1.0088349580764771</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 6 7 6 -1.</_> + <_>13 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0155720002949238</threshold> + <left_val>0.4761529862880707</left_val> + <right_val>0.0456239990890026</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 4 14 -1.</_> + <_>6 11 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0153050003573298</threshold> + <left_val>-1.1077369451522827</left_val> + <right_val>4.5239999890327454e-003</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 7 6 9 -1.</_> + <_>11 7 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0164850000292063</threshold> + <left_val>1.0152939558029175</left_val> + <right_val>0.0163279995322227</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 6 14 -1.</_> + <_>7 8 3 7 2.</_> + <_>10 15 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0261419992893934</threshold> + <left_val>0.4172329902648926</left_val> + <right_val>-0.2864550054073334</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 8 4 16 -1.</_> + <_>18 16 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.8679995387792587e-003</threshold> + <left_val>0.2140499949455261</left_val> + <right_val>-0.1677280068397522</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 14 6 10 -1.</_> + <_>11 14 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0268869996070862</threshold> + <left_val>-1.1564220190048218</left_val> + <right_val>-0.0103240003809333</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 12 5 -1.</_> + <_>10 11 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.7789998613297939e-003</threshold> + <left_val>0.3535949885845184</left_val> + <right_val>-0.2961130142211914</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 23 3 -1.</_> + <_>0 13 23 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0159740000963211</threshold> + <left_val>-1.5374109745025635</left_val> + <right_val>-0.0299580004066229</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 6 12 -1.</_> + <_>15 0 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0208669994026423</threshold> + <left_val>0.2024410068988800</left_val> + <right_val>-0.7127019762992859</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 12 5 -1.</_> + <_>4 10 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0854820013046265</threshold> + <left_val>-0.0259329993277788</left_val> + <right_val>-1.5156569480895996</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 2 10 4 -1.</_> + <_>13 4 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0238729994744062</threshold> + <left_val>0.1680340021848679</left_val> + <right_val>-0.3880620002746582</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 6 12 -1.</_> + <_>7 0 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0391050018370152</threshold> + <left_val>-1.1958349943161011</left_val> + <right_val>-0.0203610006719828</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 9 6 -1.</_> + <_>14 6 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0779469981789589</threshold> + <left_val>-1.0898950099945068</left_val> + <right_val>0.1453029960393906</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 9 6 -1.</_> + <_>7 6 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0168760009109974</threshold> + <left_val>0.2804970145225525</left_val> + <right_val>-0.4133630096912384</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 18 13 -1.</_> + <_>12 11 6 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1187560036778450</threshold> + <left_val>-0.0434909984469414</left_val> + <right_val>0.4126369953155518</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 18 13 -1.</_> + <_>6 11 6 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1562419980764389</threshold> + <left_val>-0.2642959952354431</left_val> + <right_val>0.5512779951095581</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 16 12 6 -1.</_> + <_>16 16 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0459080003201962</threshold> + <left_val>0.6018919944763184</left_val> + <right_val>0.0189210008829832</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 21 3 -1.</_> + <_>0 7 21 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0103099998086691</threshold> + <left_val>0.3815299868583679</left_val> + <right_val>-0.2950789928436279</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 16 12 6 -1.</_> + <_>16 16 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0957690030336380</threshold> + <left_val>0.1324650049209595</left_val> + <right_val>-0.4626680016517639</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 6 14 -1.</_> + <_>5 14 6 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0136869996786118</threshold> + <left_val>0.1173869967460632</left_val> + <right_val>-0.5166410207748413</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 19 2 -1.</_> + <_>5 11 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.3990001063793898e-003</threshold> + <left_val>-0.3400759994983673</left_val> + <right_val>0.2095350027084351</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 14 4 -1.</_> + <_>5 6 14 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0332649983465672</threshold> + <left_val>-0.1705279946327210</left_val> + <right_val>1.4366799592971802</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 18 4 -1.</_> + <_>9 18 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0332060009241104</threshold> + <left_val>0.6129570007324219</left_val> + <right_val>-0.0415499992668629</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 4 9 -1.</_> + <_>9 0 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.7979998849332333e-003</threshold> + <left_val>-0.4855430126190186</left_val> + <right_val>0.1337269991636276</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 3 11 4 -1.</_> + <_>13 5 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0657920017838478</threshold> + <left_val>-4.0257668495178223</left_val> + <right_val>0.1087670028209686</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 9 6 -1.</_> + <_>5 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.1430000197142363e-003</threshold> + <left_val>-0.3917999863624573</left_val> + <right_val>0.2242709994316101</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 1 4 23 -1.</_> + <_>19 1 2 23 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0223639998584986</threshold> + <left_val>-0.0864299982786179</left_val> + <right_val>0.3778519928455353</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 4 23 -1.</_> + <_>3 1 2 23 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0574100017547607</threshold> + <left_val>1.1454069614410400</left_val> + <right_val>-0.1973659992218018</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 16 18 3 -1.</_> + <_>5 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.6550001502037048e-003</threshold> + <left_val>-0.0211050007492304</left_val> + <right_val>0.5845339894294739</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 11 4 -1.</_> + <_>0 5 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0123269995674491</threshold> + <left_val>0.0378170013427734</left_val> + <right_val>-0.6698700189590454</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 16 20 3 -1.</_> + <_>2 17 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.1869997084140778e-003</threshold> + <left_val>0.5636600255966187</left_val> + <right_val>-0.0768779963254929</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 3 13 4 -1.</_> + <_>5 5 13 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0366810001432896</threshold> + <left_val>-0.1734330058097839</left_val> + <right_val>1.1670149564743042</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 9 22 15 -1.</_> + <_>1 9 11 15 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.4022040069103241</threshold> + <left_val>1.2640819549560547</left_val> + <right_val>0.0433989986777306</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 14 3 -1.</_> + <_>10 4 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0221260003745556</threshold> + <left_val>0.6697810292243958</left_val> + <right_val>-0.2160529941320419</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 10 4 -1.</_> + <_>8 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0131569998338819</threshold> + <left_val>-0.4119859933853149</left_val> + <right_val>0.2021500021219254</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 10 4 -1.</_> + <_>11 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0128600001335144</threshold> + <left_val>-0.9158269762992859</left_val> + <right_val>0.0392329990863800</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 4 6 9 -1.</_> + <_>12 4 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0216279998421669</threshold> + <left_val>3.8719999138265848e-003</left_val> + <right_val>0.3566820025444031</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 12 9 6 -1.</_> + <_>4 12 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0118960002437234</threshold> + <left_val>-0.3730390071868897</left_val> + <right_val>0.1923509985208511</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 3 8 10 -1.</_> + <_>12 3 4 5 2.</_> + <_>8 8 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0195489991456270</threshold> + <left_val>-0.4237489998340607</left_val> + <right_val>0.2442959994077683</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 16 6 -1.</_> + <_>3 6 8 3 2.</_> + <_>11 9 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0644449964165688</threshold> + <left_val>-0.1655890047550201</left_val> + <right_val>1.2697030305862427</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 6 -1.</_> + <_>5 9 14 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1089849993586540</threshold> + <left_val>0.1489430069923401</left_val> + <right_val>-2.1534640789031982</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 9 6 -1.</_> + <_>4 5 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0340779982507229</threshold> + <left_val>1.3779460191726685</left_val> + <right_val>-0.1619849950075150</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 18 2 -1.</_> + <_>6 4 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.7489999085664749e-003</threshold> + <left_val>-0.3382860124111176</left_val> + <right_val>0.2115290015935898</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 9 6 -1.</_> + <_>10 6 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0109719997271895</threshold> + <left_val>0.7651789784431458</left_val> + <right_val>-0.1969259977340698</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 3 -1.</_> + <_>0 2 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0114850001409650</threshold> + <left_val>-0.6927120089530945</left_val> + <right_val>0.2165710031986237</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 10 6 -1.</_> + <_>0 19 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0259840004146099</threshold> + <left_val>-0.0119839999824762</left_val> + <right_val>-0.9969729781150818</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 18 3 -1.</_> + <_>3 19 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.2159999720752239e-003</threshold> + <left_val>-0.1020570024847984</left_val> + <right_val>0.4888440072536469</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 6 16 -1.</_> + <_>2 5 3 8 2.</_> + <_>5 13 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0476970002055168</threshold> + <left_val>1.0666010379791260</left_val> + <right_val>-0.1757629960775375</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 11 6 -1.</_> + <_>7 8 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.0300001273863018e-004</threshold> + <left_val>0.1852480024099350</left_val> + <right_val>-0.7479000091552734</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 12 22 -1.</_> + <_>5 13 12 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1153960004448891</threshold> + <left_val>-0.2201970070600510</left_val> + <right_val>0.5450999736785889</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 4 10 -1.</_> + <_>10 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0160210002213717</threshold> + <left_val>0.2548750042915344</left_val> + <right_val>-0.5074009895324707</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 4 18 -1.</_> + <_>9 6 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0566320009529591</threshold> + <left_val>-0.0112560000270605</left_val> + <right_val>-0.9596809744834900</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 8 6 9 -1.</_> + <_>18 11 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0107260001823306</threshold> + <left_val>-0.2854470014572144</left_val> + <right_val>0.1699479967355728</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 15 10 -1.</_> + <_>9 7 5 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1242000013589859</threshold> + <left_val>-0.0361399985849857</left_val> + <right_val>-1.3132710456848145</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 6 9 -1.</_> + <_>12 5 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.3799999877810478e-003</threshold> + <left_val>0.3309270143508911</left_val> + <right_val>0.0133079998195171</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 9 6 10 -1.</_> + <_>11 9 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0119080003350973</threshold> + <left_val>-0.3483029901981354</left_val> + <right_val>0.2404190003871918</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 14 6 10 -1.</_> + <_>13 14 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0430079996585846</threshold> + <left_val>-1.4390469789505005</left_val> + <right_val>0.1559959948062897</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 14 6 10 -1.</_> + <_>9 14 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0331499986350536</threshold> + <left_val>-1.1805850267410278</left_val> + <right_val>-0.0123479999601841</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 8 16 9 -1.</_> + <_>4 11 16 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0213419999927282</threshold> + <left_val>2.2119441032409668</left_val> + <right_val>0.0627370029687881</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 20 3 -1.</_> + <_>2 12 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0122189996764064</threshold> + <left_val>-1.8709750175476074</left_val> + <right_val>-0.0454999990761280</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 4 13 -1.</_> + <_>13 0 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0168609991669655</threshold> + <left_val>-0.7691270112991333</left_val> + <right_val>0.1533000022172928</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 4 13 -1.</_> + <_>9 0 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.4999999441206455e-003</threshold> + <left_val>-0.6298739910125732</left_val> + <right_val>0.0516000017523766</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 18 7 -1.</_> + <_>9 1 6 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0450379997491837</threshold> + <left_val>0.8542889952659607</left_val> + <right_val>6.2600001692771912e-003</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 11 6 9 -1.</_> + <_>1 14 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0390579998493195</threshold> + <left_val>-0.0324589982628822</left_val> + <right_val>-1.3325669765472412</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 9 6 -1.</_> + <_>8 20 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.6720000468194485e-003</threshold> + <left_val>-0.1942359954118729</left_val> + <right_val>0.3732869923114777</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 15 6 -1.</_> + <_>3 11 15 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0163610000163317</threshold> + <left_val>2.0605869293212891</left_val> + <right_val>-0.1504269987344742</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 19 2 -1.</_> + <_>5 11 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.1719999648630619e-003</threshold> + <left_val>-0.1161099970340729</left_val> + <right_val>0.2545540034770966</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 7 16 -1.</_> + <_>8 14 7 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0457220003008842</threshold> + <left_val>-0.0163400005549192</left_val> + <right_val>-1.0449140071868896</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 14 9 6 -1.</_> + <_>9 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.1209999471902847e-003</threshold> + <left_val>-0.0419979989528656</left_val> + <right_val>0.3968099951744080</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 8 12 -1.</_> + <_>0 11 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.7800000205170363e-004</threshold> + <left_val>-0.6642259955406189</left_val> + <right_val>0.0334430001676083</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 18 3 -1.</_> + <_>6 5 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.1109998971223831e-003</threshold> + <left_val>-0.0582319982349873</left_val> + <right_val>0.3785730004310608</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 12 6 -1.</_> + <_>4 16 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0498640015721321</threshold> + <left_val>0.6101940274238586</left_val> + <right_val>-0.2100570052862167</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 13 9 4 -1.</_> + <_>13 15 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0250119995325804</threshold> + <left_val>-0.5710009932518005</left_val> + <right_val>0.1784839928150177</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 14 14 -1.</_> + <_>5 8 7 7 2.</_> + <_>12 15 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0309399999678135</threshold> + <left_val>0.0563630014657974</left_val> + <right_val>-0.6473100185394287</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 16 22 6 -1.</_> + <_>12 16 11 3 2.</_> + <_>1 19 11 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0462710000574589</threshold> + <left_val>0.1748239994049072</left_val> + <right_val>-0.9890940189361572</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 9 -1.</_> + <_>11 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.1870000530034304e-003</threshold> + <left_val>-0.6680480241775513</left_val> + <right_val>0.0322670005261898</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 10 10 -1.</_> + <_>14 5 5 5 2.</_> + <_>9 10 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0243519991636276</threshold> + <left_val>0.2944490015506744</left_val> + <right_val>-1.3599999947473407e-003</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 10 10 -1.</_> + <_>5 5 5 5 2.</_> + <_>10 10 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0119740003719926</threshold> + <left_val>-0.2834509909152985</left_val> + <right_val>0.4717119932174683</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 16 6 -1.</_> + <_>12 6 8 3 2.</_> + <_>4 9 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0130700003355742</threshold> + <left_val>-0.1083460003137589</left_val> + <right_val>0.5719329714775085</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 6 9 -1.</_> + <_>0 10 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0591630004346371</threshold> + <left_val>-0.0509390011429787</left_val> + <right_val>-1.9059720039367676</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 10 8 14 -1.</_> + <_>20 10 4 7 2.</_> + <_>16 17 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0410949997603893</threshold> + <left_val>0.4510459899902344</left_val> + <right_val>-9.7599998116493225e-003</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 12 -1.</_> + <_>9 18 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0839890018105507</threshold> + <left_val>-2.0349199771881104</left_val> + <right_val>-0.0510190017521381</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 10 8 12 -1.</_> + <_>12 10 4 6 2.</_> + <_>8 16 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0446190014481544</threshold> + <left_val>0.1704110056161881</left_val> + <right_val>-1.2278720140457153</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 4 9 -1.</_> + <_>10 0 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0244190003722906</threshold> + <left_val>-0.0217969994992018</left_val> + <right_val>-1.0822949409484863</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 4 8 16 -1.</_> + <_>14 4 4 8 2.</_> + <_>10 12 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.3870001100003719e-003</threshold> + <left_val>0.3046669960021973</left_val> + <right_val>-0.3706659972667694</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 10 10 6 -1.</_> + <_>7 12 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0246079992502928</threshold> + <left_val>-0.3116950094699860</left_val> + <right_val>0.2365729957818985</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 14 -1.</_> + <_>12 6 7 7 2.</_> + <_>5 13 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0851820036768913</threshold> + <left_val>-1.7982350587844849</left_val> + <right_val>0.1525429934263229</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 20 2 -1.</_> + <_>2 12 20 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0218449998646975</threshold> + <left_val>-0.0518880002200603</left_val> + <right_val>-1.9017189741134644</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 8 4 16 -1.</_> + <_>18 16 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0168290007859468</threshold> + <left_val>0.2102590054273605</left_val> + <right_val>0.0216569993644953</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 11 12 10 -1.</_> + <_>1 11 6 5 2.</_> + <_>7 16 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0325479991734028</threshold> + <left_val>-0.2029259949922562</left_val> + <right_val>0.6094400286674500</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 12 4 -1.</_> + <_>6 11 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.4709999561309814e-003</threshold> + <left_val>-0.9537119865417481</left_val> + <right_val>0.1856839954853058</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 7 -1.</_> + <_>12 12 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0554159991443157</threshold> + <left_val>-0.1440529972314835</left_val> + <right_val>2.1506340503692627</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 4 8 16 -1.</_> + <_>14 4 4 8 2.</_> + <_>10 12 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1063549965620041</threshold> + <left_val>-1.0911970138549805</left_val> + <right_val>0.1322800070047379</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 8 16 -1.</_> + <_>6 4 4 8 2.</_> + <_>10 12 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.9889995977282524e-003</threshold> + <left_val>0.1025340035557747</left_val> + <right_val>-0.5174490213394165</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 9 9 6 -1.</_> + <_>11 9 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0755679979920387</threshold> + <left_val>0.0589650012552738</left_val> + <right_val>1.2354209423065186</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 16 12 -1.</_> + <_>1 5 8 6 2.</_> + <_>9 11 8 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0928059965372086</threshold> + <left_val>-1.3431650400161743</left_val> + <right_val>-0.0344629995524883</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 9 6 8 -1.</_> + <_>9 9 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0494319982826710</threshold> + <left_val>0.0496019981801510</left_val> + <right_val>1.6054730415344238</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 3 18 -1.</_> + <_>7 0 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0117729995399714</threshold> + <left_val>-1.0261050462722778</left_val> + <right_val>-4.1559999808669090e-003</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 9 5 14 -1.</_> + <_>17 16 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0858860015869141</threshold> + <left_val>0.0846429988741875</left_val> + <right_val>0.9522079825401306</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 9 5 14 -1.</_> + <_>2 16 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0810310021042824</threshold> + <left_val>-0.1468710005283356</left_val> + <right_val>1.9359990358352661</right_val></_></_></trees> + <stage_threshold>-3.7025990486145020</stage_threshold> + <parent>12</parent> + <next>-1</next></_> + <_> + <!-- stage 14 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 4 10 6 -1.</_> + <_>7 7 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0338409990072250</threshold> + <left_val>0.6588950157165527</left_val> + <right_val>-0.6975529789924622</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 3 23 18 -1.</_> + <_>1 9 23 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0154100004583597</threshold> + <left_val>-0.9072840213775635</left_val> + <right_val>0.3047859966754913</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 21 3 -1.</_> + <_>8 1 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0549059994518757</threshold> + <left_val>-0.4977479875087738</left_val> + <right_val>0.5713260173797607</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0213900003582239</threshold> + <left_val>-0.4256519973278046</left_val> + <right_val>0.5809680223464966</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 12 6 -1.</_> + <_>3 18 6 3 2.</_> + <_>9 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.8849997371435165e-003</threshold> + <left_val>-0.4790599942207336</left_val> + <right_val>0.4301649928092957</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 8 8 16 -1.</_> + <_>20 8 4 8 2.</_> + <_>16 16 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0375449992716312</threshold> + <left_val>0.5086159706115723</left_val> + <right_val>-0.1998589932918549</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 19 24 4 -1.</_> + <_>8 19 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1592579931020737</threshold> + <left_val>-0.2326360046863556</left_val> + <right_val>1.0993319749832153</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 8 8 16 -1.</_> + <_>20 8 4 8 2.</_> + <_>16 16 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0689399987459183</threshold> + <left_val>0.4056900143623352</left_val> + <right_val>0.0568550005555153</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 8 16 -1.</_> + <_>0 8 4 8 2.</_> + <_>4 16 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0336950011551380</threshold> + <left_val>0.4513280093669891</left_val> + <right_val>-0.3333280086517334</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 12 8 10 -1.</_> + <_>8 17 8 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0633149966597557</threshold> + <left_val>-0.8501570224761963</left_val> + <right_val>0.2234169989824295</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 5 8 -1.</_> + <_>5 11 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.3699997738003731e-003</threshold> + <left_val>-0.9308220148086548</left_val> + <right_val>0.0592169985175133</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 19 2 -1.</_> + <_>4 2 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.5969997346401215e-003</threshold> + <left_val>-1.2794899940490723</left_val> + <right_val>0.1844729930162430</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 24 9 -1.</_> + <_>8 12 8 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1306799948215485</threshold> + <left_val>0.5842689871788025</left_val> + <right_val>-0.2600719928741455</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 13 8 -1.</_> + <_>6 4 13 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0574029982089996</threshold> + <left_val>-0.0537890009582043</left_val> + <right_val>0.7117559909820557</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 3 -1.</_> + <_>0 1 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.2340001352131367e-003</threshold> + <left_val>-0.8696219921112061</left_val> + <right_val>0.0752149969339371</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 3 4 11 -1.</_> + <_>20 3 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0310989990830421</threshold> + <left_val>-0.0750069990754128</left_val> + <right_val>0.9078159928321838</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 6 9 -1.</_> + <_>10 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0358540005981922</threshold> + <left_val>-0.2479549944400787</left_val> + <right_val>0.7227209806442261</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 12 8 -1.</_> + <_>12 11 6 4 2.</_> + <_>6 15 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0315349996089935</threshold> + <left_val>-1.1238329410552979</left_val> + <right_val>0.2098830044269562</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 12 6 -1.</_> + <_>0 8 6 3 2.</_> + <_>6 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0194370001554489</threshold> + <left_val>-1.4499390125274658</left_val> + <right_val>-0.0151000004261732</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 17 18 3 -1.</_> + <_>6 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.2420001961290836e-003</threshold> + <left_val>0.5386490225791931</left_val> + <right_val>-0.1137539967894554</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 9 6 -1.</_> + <_>0 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.1639997661113739e-003</threshold> + <left_val>0.0668890029191971</left_val> + <right_val>-0.7687289714813232</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 3 4 9 -1.</_> + <_>20 3 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0436530001461506</threshold> + <left_val>1.1413530111312866</left_val> + <right_val>0.0402170009911060</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 4 9 -1.</_> + <_>2 3 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0265699997544289</threshold> + <left_val>-0.2471909970045090</left_val> + <right_val>0.5929509997367859</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 9 19 -1.</_> + <_>18 0 3 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0322169996798038</threshold> + <left_val>-0.0400249995291233</left_val> + <right_val>0.3268800079822540</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 9 19 -1.</_> + <_>3 0 3 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0722360014915466</threshold> + <left_val>0.5872939825057983</left_val> + <right_val>-0.2539600133895874</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 6 8 -1.</_> + <_>13 11 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0314249992370605</threshold> + <left_val>0.1531510055065155</left_val> + <right_val>-0.5604209899902344</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 6 8 -1.</_> + <_>8 11 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.7699999413453043e-004</threshold> + <left_val>0.1695889979600906</left_val> + <right_val>-0.5262669920921326</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 19 3 -1.</_> + <_>5 12 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.7189999818801880e-003</threshold> + <left_val>-0.1494459956884384</left_val> + <right_val>0.2965869903564453</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 20 18 4 -1.</_> + <_>9 20 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0328750014305115</threshold> + <left_val>-0.3994350135326386</left_val> + <right_val>0.2515659928321838</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 16 6 -1.</_> + <_>6 8 16 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0145530002191663</threshold> + <left_val>0.2797259986400604</left_val> + <right_val>-0.4720380008220673</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 9 6 -1.</_> + <_>9 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0380179993808270</threshold> + <left_val>-2.9200001154094934e-003</left_val> + <right_val>-1.1300059556961060</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 3 4 14 -1.</_> + <_>10 10 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.8659999370574951e-003</threshold> + <left_val>0.4111180007457733</left_val> + <right_val>-0.2622080147266388</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 15 12 -1.</_> + <_>1 11 15 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0416069999337196</threshold> + <left_val>-1.4293819665908813</left_val> + <right_val>-0.0191329997032881</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 12 8 5 -1.</_> + <_>11 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0248029995709658</threshold> + <left_val>-0.2501359879970551</left_val> + <right_val>0.1597869992256165</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 6 9 -1.</_> + <_>7 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0100980000570416</threshold> + <left_val>0.0437389984726906</left_val> + <right_val>-0.6998609900474548</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 6 9 -1.</_> + <_>14 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0209470000118017</threshold> + <left_val>-0.9413779973983765</left_val> + <right_val>0.2320400029420853</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 12 8 -1.</_> + <_>5 5 6 4 2.</_> + <_>11 9 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0224580001085997</threshold> + <left_val>-0.2718580067157745</left_val> + <right_val>0.4531919956207275</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 12 11 6 -1.</_> + <_>13 14 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0371109992265701</threshold> + <left_val>-1.0314660072326660</left_val> + <right_val>0.1442179977893829</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 21 3 -1.</_> + <_>0 14 21 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0106480000540614</threshold> + <left_val>0.6310700178146362</left_val> + <right_val>-0.2552079856395721</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 8 12 -1.</_> + <_>12 1 4 6 2.</_> + <_>8 7 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0554229989647865</threshold> + <left_val>0.1620659977197647</left_val> + <right_val>-1.7722640037536621</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 6 12 -1.</_> + <_>1 0 3 6 2.</_> + <_>4 6 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0216019991785288</threshold> + <left_val>-0.2501609921455383</left_val> + <right_val>0.5411980152130127</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 21 2 -1.</_> + <_>2 3 21 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.7000000348780304e-005</threshold> + <left_val>-0.2900890111923218</left_val> + <right_val>0.3350799977779388</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 19 3 -1.</_> + <_>2 3 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0144060002639890</threshold> + <left_val>-7.8840004280209541e-003</left_val> + <right_val>-1.1677219867706299</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 10 6 14 -1.</_> + <_>20 10 3 7 2.</_> + <_>17 17 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1077739968895912</threshold> + <left_val>0.1129200011491776</left_val> + <right_val>-2.4940319061279297</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 6 14 -1.</_> + <_>1 10 3 7 2.</_> + <_>4 17 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0359439998865128</threshold> + <left_val>-0.1948059946298599</left_val> + <right_val>0.9575750231742859</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 14 14 -1.</_> + <_>14 6 7 7 2.</_> + <_>7 13 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.9510000497102737e-003</threshold> + <left_val>0.3092780113220215</left_val> + <right_val>-0.2553020119667053</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 9 6 -1.</_> + <_>0 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0209420006722212</threshold> + <left_val>-7.6319999061524868e-003</left_val> + <right_val>-1.0086350440979004</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 14 8 9 -1.</_> + <_>15 17 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0298779997974634</threshold> + <left_val>-0.4602769911289215</left_val> + <right_val>0.1950719952583313</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 22 4 -1.</_> + <_>1 1 11 2 2.</_> + <_>12 3 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0259719993919134</threshold> + <left_val>-0.0121879996731877</left_val> + <right_val>-1.0035500526428223</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 11 9 6 -1.</_> + <_>9 13 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0106030004099011</threshold> + <left_val>-0.0759690031409264</left_val> + <right_val>0.4166989922523499</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 18 3 -1.</_> + <_>0 16 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.5819996893405914e-003</threshold> + <left_val>-0.2664859890937805</left_val> + <right_val>0.3911150097846985</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 14 7 9 -1.</_> + <_>16 17 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0212709996849298</threshold> + <left_val>0.1827390044927597</left_val> + <right_val>-0.3605229854583740</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 16 4 -1.</_> + <_>12 3 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0745180025696754</threshold> + <left_val>-0.1893839985132217</left_val> + <right_val>0.9265800118446350</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 12 5 -1.</_> + <_>7 6 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.6569998376071453e-003</threshold> + <left_val>-0.1450619995594025</left_val> + <right_val>0.3329460024833679</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 4 9 -1.</_> + <_>11 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.7119999974966049e-003</threshold> + <left_val>-0.5246400237083435</left_val> + <right_val>0.0898799970746040</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 4 10 -1.</_> + <_>12 1 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.8500004969537258e-004</threshold> + <left_val>-0.3838199973106384</left_val> + <right_val>0.2439299970865250</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 4 10 -1.</_> + <_>10 1 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0282339993864298</threshold> + <left_val>-5.7879998348653316e-003</left_val> + <right_val>-1.2617139816284180</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 15 6 9 -1.</_> + <_>15 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0326780006289482</threshold> + <left_val>-0.5795329809188843</left_val> + <right_val>0.1695529967546463</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 15 6 9 -1.</_> + <_>3 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0225360002368689</threshold> + <left_val>0.0222810003906488</left_val> + <right_val>-0.8786960244178772</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 1 3 19 -1.</_> + <_>16 1 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0216579996049404</threshold> + <left_val>-0.6510850191116333</left_val> + <right_val>0.1296689957380295</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 3 6 9 -1.</_> + <_>3 3 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.6799998059868813e-003</threshold> + <left_val>-0.3396520018577576</left_val> + <right_val>0.2201330065727234</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 3 19 -1.</_> + <_>16 0 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0145920002833009</threshold> + <left_val>0.1507730036973953</left_val> + <right_val>-0.5045239925384522</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 12 4 -1.</_> + <_>12 3 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0278680007904768</threshold> + <left_val>-0.2504529953002930</left_val> + <right_val>0.4574199914932251</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 4 9 -1.</_> + <_>10 5 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.6940000504255295e-003</threshold> + <left_val>-0.1094850003719330</left_val> + <right_val>0.5575780272483826</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 3 19 -1.</_> + <_>7 0 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0100029995664954</threshold> + <left_val>-0.9736629724502564</left_val> + <right_val>0.0184679999947548</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 3 12 -1.</_> + <_>11 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.0719998069107533e-003</threshold> + <left_val>0.3822219967842102</left_val> + <right_val>-0.1692110002040863</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 10 5 -1.</_> + <_>11 7 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0225939992815256</threshold> + <left_val>-1.0391089916229248</left_val> + <right_val>5.1839998923242092e-003</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 3 3 18 -1.</_> + <_>12 3 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0395799987018108</threshold> + <left_val>-5.5109229087829590</left_val> + <right_val>0.1116399988532066</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 3 6 12 -1.</_> + <_>11 3 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0175379998981953</threshold> + <left_val>0.9548580050468445</left_val> + <right_val>-0.1858450025320053</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 19 3 -1.</_> + <_>3 8 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.0300003066658974e-003</threshold> + <left_val>0.0104360003024340</left_val> + <right_val>0.8211479783058167</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 18 3 -1.</_> + <_>2 8 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.9539995640516281e-003</threshold> + <left_val>0.2263289988040924</left_val> + <right_val>-0.3456819951534271</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 13 18 4 -1.</_> + <_>12 13 9 2 2.</_> + <_>3 15 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0270910002291203</threshold> + <left_val>0.1643009930849075</left_val> + <right_val>-1.3926379680633545</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 6 9 -1.</_> + <_>5 5 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0206259991973639</threshold> + <left_val>-0.8636609911918640</left_val> + <right_val>2.3880000226199627e-003</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 20 4 -1.</_> + <_>14 1 10 2 2.</_> + <_>4 3 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0719899982213974</threshold> + <left_val>-2.8192629814147949</left_val> + <right_val>0.1157049983739853</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 20 4 -1.</_> + <_>0 1 10 2 2.</_> + <_>10 3 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0269649997353554</threshold> + <left_val>-1.2946130037307739</left_val> + <right_val>-0.0246610008180141</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 15 6 6 -1.</_> + <_>10 15 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0473779998719692</threshold> + <left_val>-0.8130639791488648</left_val> + <right_val>0.1183139979839325</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 8 -1.</_> + <_>8 2 8 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1089560016989708</threshold> + <left_val>0.6593790054321289</left_val> + <right_val>-0.2084390074014664</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 18 3 -1.</_> + <_>5 6 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0135740004479885</threshold> + <left_val>7.4240001849830151e-003</left_val> + <right_val>0.5315219759941101</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 15 6 6 -1.</_> + <_>11 15 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.6920001991093159e-003</threshold> + <left_val>0.3065580129623413</left_val> + <right_val>-0.3108429908752441</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 12 8 5 -1.</_> + <_>11 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.9070001803338528e-003</threshold> + <left_val>0.2557649910449982</left_val> + <right_val>-0.0529320016503334</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 12 8 5 -1.</_> + <_>9 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0376130007207394</threshold> + <left_val>-1.4350049495697021</left_val> + <right_val>-0.0154480002820492</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 14 6 -1.</_> + <_>5 2 14 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.6329998448491096e-003</threshold> + <left_val>-0.1688439995050430</left_val> + <right_val>0.4212490022182465</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 15 -1.</_> + <_>10 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0320970006287098</threshold> + <left_val>-0.6497939825057983</left_val> + <right_val>0.0411100015044212</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 5 12 -1.</_> + <_>10 11 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0584959983825684</threshold> + <left_val>-0.0529639981687069</left_val> + <right_val>0.6336830258369446</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 9 8 14 -1.</_> + <_>7 9 4 7 2.</_> + <_>11 16 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0409019999206066</threshold> + <left_val>-0.9210109710693359</left_val> + <right_val>9.0640000998973846e-003</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 22 6 -1.</_> + <_>12 5 11 3 2.</_> + <_>1 8 11 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0199250001460314</threshold> + <left_val>0.5375999808311462</left_val> + <right_val>-0.0629969984292984</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 6 6 -1.</_> + <_>0 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.6020001173019409e-003</threshold> + <left_val>-0.5433350205421448</left_val> + <right_val>0.0841049998998642</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 17 9 4 -1.</_> + <_>12 19 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0168249998241663</threshold> + <left_val>0.1556369960308075</left_val> + <right_val>-0.4017120003700256</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 18 19 3 -1.</_> + <_>2 19 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.4790002331137657e-003</threshold> + <left_val>-0.2424529939889908</left_val> + <right_val>0.5150949954986572</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 17 9 4 -1.</_> + <_>12 19 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0195349995046854</threshold> + <left_val>-0.5111839771270752</left_val> + <right_val>0.1383199989795685</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 17 18 3 -1.</_> + <_>1 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0107460003346205</threshold> + <left_val>-0.2185499966144562</left_val> + <right_val>0.6282870173454285</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 17 9 4 -1.</_> + <_>12 19 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0379270017147064</threshold> + <left_val>0.1164029985666275</left_val> + <right_val>-2.7301959991455078</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 3 -1.</_> + <_>0 1 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0163909997791052</threshold> + <left_val>-0.0146359996870160</left_val> + <right_val>-1.0797250270843506</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 14 4 -1.</_> + <_>5 2 14 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0197850000113249</threshold> + <left_val>1.2166420221328735</left_val> + <right_val>0.0332750007510185</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 14 9 6 -1.</_> + <_>6 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0110670002177358</threshold> + <left_val>-0.2538830041885376</left_val> + <right_val>0.4403859972953796</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 6 9 -1.</_> + <_>14 16 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.2479999139904976e-003</threshold> + <left_val>0.2249680012464523</left_val> + <right_val>-0.2421649992465973</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 20 13 4 -1.</_> + <_>5 22 13 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0111419996246696</threshold> + <left_val>0.2501809895038605</left_val> + <right_val>-0.3081150054931641</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 9 6 12 -1.</_> + <_>9 13 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0106669999659061</threshold> + <left_val>-0.3272910118103027</left_val> + <right_val>0.2616829872131348</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 21 3 -1.</_> + <_>8 10 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1054529994726181</threshold> + <left_val>-0.0557500012218952</left_val> + <right_val>-1.9605729579925537</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 9 6 -1.</_> + <_>11 8 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0548279993236065</threshold> + <left_val>-1.9519999623298645e-003</left_val> + <right_val>0.7386609911918640</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 9 7 -1.</_> + <_>6 10 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0177609995007515</threshold> + <left_val>-0.3064720034599304</left_val> + <right_val>0.2634699940681458</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 10 10 8 -1.</_> + <_>17 10 5 4 2.</_> + <_>12 14 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0311859995126724</threshold> + <left_val>-0.2460090070962906</left_val> + <right_val>0.1708219945430756</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 24 3 -1.</_> + <_>8 15 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0572960004210472</threshold> + <left_val>0.4703350067138672</left_val> + <right_val>-0.2604829967021942</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 5 9 6 -1.</_> + <_>8 7 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0113120004534721</threshold> + <left_val>0.3862890005111694</left_val> + <right_val>-0.2881700098514557</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 6 9 -1.</_> + <_>4 16 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0305920001119375</threshold> + <left_val>-0.0488260015845299</left_val> + <right_val>-1.7638969421386719</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 17 9 4 -1.</_> + <_>12 19 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.8489999929443002e-003</threshold> + <left_val>0.2109989970922470</left_val> + <right_val>-0.0259409993886948</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 6 -1.</_> + <_>9 15 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0114190001040697</threshold> + <left_val>-0.1682959944009781</left_val> + <right_val>1.0278660058975220</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 9 14 10 -1.</_> + <_>16 9 7 5 2.</_> + <_>9 14 7 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0814030021429062</threshold> + <left_val>0.1153199970722199</left_val> + <right_val>-1.2482399940490723</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 9 14 10 -1.</_> + <_>1 9 7 5 2.</_> + <_>8 14 7 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0534959994256496</threshold> + <left_val>-0.0463039986789227</left_val> + <right_val>-1.7165969610214233</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 9 17 -1.</_> + <_>11 7 3 17 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0239480007439852</threshold> + <left_val>-0.4024659991264343</left_val> + <right_val>0.2056210041046143</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 6 20 -1.</_> + <_>3 4 3 10 2.</_> + <_>6 14 3 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.7690000869333744e-003</threshold> + <left_val>-0.3315230011940002</left_val> + <right_val>0.2068340033292770</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 10 4 -1.</_> + <_>7 8 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0323439985513687</threshold> + <left_val>-0.7263280153274536</left_val> + <right_val>0.2007350027561188</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 4 9 -1.</_> + <_>12 7 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0378630012273788</threshold> + <left_val>-0.1563100069761276</left_val> + <right_val>1.6697460412979126</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 15 6 9 -1.</_> + <_>12 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0154400002211332</threshold> + <left_val>0.1948740035295487</left_val> + <right_val>-0.3538419902324677</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 8 6 16 -1.</_> + <_>3 8 3 8 2.</_> + <_>6 16 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0443760007619858</threshold> + <left_val>0.8209360241889954</left_val> + <right_val>-0.1819359958171845</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 17 9 4 -1.</_> + <_>12 19 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0231020003557205</threshold> + <left_val>-0.4304409921169281</left_val> + <right_val>0.1237540021538734</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 17 9 4 -1.</_> + <_>3 19 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0194000005722046</threshold> + <left_val>-0.0297260005027056</left_val> + <right_val>-1.1597590446472168</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 1 9 6 -1.</_> + <_>13 1 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1038570031523705</threshold> + <left_val>0.1114989966154099</left_val> + <right_val>-4.6835222244262695</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 4 10 -1.</_> + <_>5 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0189640000462532</threshold> + <left_val>2.1773819923400879</left_val> + <right_val>-0.1454440057277679</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 12 6 -1.</_> + <_>11 5 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0387509986758232</threshold> + <left_val>-0.0494460016489029</left_val> + <right_val>0.3401829898357391</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 9 8 -1.</_> + <_>9 4 3 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0227669999003410</threshold> + <left_val>-0.3280299901962280</left_val> + <right_val>0.3053140044212341</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 16 10 8 -1.</_> + <_>17 16 5 4 2.</_> + <_>12 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0313570015132427</threshold> + <left_val>1.1520819664001465</left_val> + <right_val>0.0273059997707605</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 16 10 8 -1.</_> + <_>2 16 5 4 2.</_> + <_>7 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.6909999847412109e-003</threshold> + <left_val>-0.3879950046539307</left_val> + <right_val>0.2151259928941727</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 4 -1.</_> + <_>12 0 12 2 2.</_> + <_>0 2 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0492849983274937</threshold> + <left_val>-1.6774909496307373</left_val> + <right_val>0.1577419936656952</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 9 6 -1.</_> + <_>0 8 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0395109988749027</threshold> + <left_val>-0.9764789938926697</left_val> + <right_val>-0.0105520002543926</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 24 6 -1.</_> + <_>12 4 12 3 2.</_> + <_>0 7 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0479979999363422</threshold> + <left_val>0.2084390074014664</left_val> + <right_val>-0.6899279952049255</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 11 4 -1.</_> + <_>5 2 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0514229983091354</threshold> + <left_val>-0.1666530072689056</left_val> + <right_val>1.2149239778518677</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 22 4 -1.</_> + <_>12 1 11 2 2.</_> + <_>1 3 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0142799997702241</threshold> + <left_val>0.2362769991159439</left_val> + <right_val>-0.4139679968357086</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 18 -1.</_> + <_>9 15 6 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0916119962930679</threshold> + <left_val>-0.9283090233802795</left_val> + <right_val>-0.0183450002223253</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 9 20 4 -1.</_> + <_>2 11 20 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.5080001950263977e-003</threshold> + <left_val>-0.7364720106124878</left_val> + <right_val>0.1949709951877594</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 14 14 -1.</_> + <_>5 9 14 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0357230007648468</threshold> + <left_val>0.1419779956340790</left_val> + <right_val>-0.4208930134773254</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 2 16 6 -1.</_> + <_>4 5 16 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0506380014121532</threshold> + <left_val>0.0116440001875162</left_val> + <right_val>0.7848659753799439</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 3 19 3 -1.</_> + <_>2 4 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0146139999851584</threshold> + <left_val>-1.1909500360488892</left_val> + <right_val>-0.0351280011236668</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 10 4 -1.</_> + <_>7 3 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0386629998683929</threshold> + <left_val>2.4314730167388916</left_val> + <right_val>0.0656479969620705</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 4 15 -1.</_> + <_>0 14 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0403469987213612</threshold> + <left_val>0.7175530195236206</left_val> + <right_val>-0.1910829991102219</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 10 21 3 -1.</_> + <_>2 11 21 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0239020008593798</threshold> + <left_val>0.1564619988203049</left_val> + <right_val>-0.7929480075836182</right_val></_></_></trees> + <stage_threshold>-3.4265899658203125</stage_threshold> + <parent>13</parent> + <next>-1</next></_> + <_> + <!-- stage 15 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 6 6 -1.</_> + <_>6 0 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.5640000179409981e-003</threshold> + <left_val>-0.8145070075988770</left_val> + <right_val>0.5887529850006104</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 14 9 -1.</_> + <_>6 7 14 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1329260021448135</threshold> + <left_val>0.9321339726448059</left_val> + <right_val>-0.2936730086803436</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 6 9 -1.</_> + <_>11 1 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.8400004208087921e-003</threshold> + <left_val>-0.5646290183067322</left_val> + <right_val>0.4164769947528839</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 8 9 9 -1.</_> + <_>15 11 9 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.0889998674392700e-003</threshold> + <left_val>-0.7923280000686646</left_val> + <right_val>0.1697500050067902</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 4 21 -1.</_> + <_>8 7 4 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0610390007495880</threshold> + <left_val>-1.4169000387191772</left_val> + <right_val>0.0250209998339415</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 22 19 2 -1.</_> + <_>3 23 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.6599999768659472e-004</threshold> + <left_val>0.3798249959945679</left_val> + <right_val>-0.4156709909439087</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 15 20 3 -1.</_> + <_>2 16 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.3889999613165855e-003</threshold> + <left_val>-0.4076859951019287</left_val> + <right_val>0.3554849922657013</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 0 4 13 -1.</_> + <_>19 0 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0210069995373487</threshold> + <left_val>-0.2408010065555573</left_val> + <right_val>0.8611270189285278</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 7 8 8 -1.</_> + <_>1 11 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.5559997931122780e-003</threshold> + <left_val>-0.8746719956398010</left_val> + <right_val>0.0985720008611679</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 14 6 9 -1.</_> + <_>14 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0247799996286631</threshold> + <left_val>0.1556620001792908</left_val> + <right_val>-0.6922979950904846</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 14 6 9 -1.</_> + <_>4 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0356200002133846</threshold> + <left_val>-1.1472270488739014</left_val> + <right_val>0.0363599993288517</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 5 4 10 -1.</_> + <_>14 5 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0198100004345179</threshold> + <left_val>0.1551620066165924</left_val> + <right_val>-0.6952009797096252</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 4 10 -1.</_> + <_>8 5 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0150199998170137</threshold> + <left_val>0.0419900007545948</left_val> + <right_val>-0.9662280082702637</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 5 6 6 -1.</_> + <_>14 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0231379996985197</threshold> + <left_val>0.4339689910411835</left_val> + <right_val>2.4160000029951334e-003</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 5 6 6 -1.</_> + <_>4 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0187430009245873</threshold> + <left_val>0.4348109960556030</left_val> + <right_val>-0.3252249956130981</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 21 -1.</_> + <_>8 2 8 21 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.4508000016212463</threshold> + <left_val>-0.0945739969611168</left_val> + <right_val>0.7242130041122437</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 6 13 -1.</_> + <_>3 2 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0118549996986985</threshold> + <left_val>-0.3813309967517853</left_val> + <right_val>0.3009839951992035</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 0 4 21 -1.</_> + <_>20 0 2 21 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0248300004750490</threshold> + <left_val>0.8930060267448425</left_val> + <right_val>-0.1029589995741844</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 4 20 -1.</_> + <_>2 4 2 20 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0447430014610291</threshold> + <left_val>0.8628029823303223</left_val> + <right_val>-0.2171649932861328</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 16 9 6 -1.</_> + <_>8 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0146000003442168</threshold> + <left_val>0.6006940007209778</left_val> + <right_val>-0.1590629965066910</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0245270002633333</threshold> + <left_val>-1.5872869491577148</left_val> + <right_val>-0.0218170005828142</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 12 7 9 -1.</_> + <_>16 15 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0230240002274513</threshold> + <left_val>0.1685339957475662</left_val> + <right_val>-0.3810690045356751</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 21 14 3 -1.</_> + <_>12 21 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0249170009046793</threshold> + <left_val>0.5081089735031128</left_val> + <right_val>-0.2727989852428436</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 5 6 9 -1.</_> + <_>11 5 3 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.0130000300705433e-003</threshold> + <left_val>-0.4313879907131195</left_val> + <right_val>0.2643809914588928</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 4 10 -1.</_> + <_>12 5 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0156030002981424</threshold> + <left_val>-0.3162420094013214</left_val> + <right_val>0.5571590065956116</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 6 9 -1.</_> + <_>12 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0266859997063875</threshold> + <left_val>1.0553920269012451</left_val> + <right_val>0.0290740001946688</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 6 9 -1.</_> + <_>10 5 3 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.3940000208094716e-003</threshold> + <left_val>-0.7187380194664002</left_val> + <right_val>0.0653909966349602</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 14 10 4 -1.</_> + <_>14 16 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.4799998654052615e-004</threshold> + <left_val>0.2488439977169037</left_val> + <right_val>-0.2097820043563843</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 14 14 -1.</_> + <_>5 5 7 7 2.</_> + <_>12 12 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0318880006670952</threshold> + <left_val>-0.6884449720382690</left_val> + <right_val>0.0635899975895882</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 8 12 6 -1.</_> + <_>18 8 6 3 2.</_> + <_>12 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.9290000461041927e-003</threshold> + <left_val>-0.5915250182151794</left_val> + <right_val>0.2794359922409058</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 12 -1.</_> + <_>6 6 6 6 2.</_> + <_>12 12 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0311680007725954</threshold> + <left_val>0.0452239997684956</left_val> + <right_val>-0.8863919973373413</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 13 6 10 -1.</_> + <_>13 13 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0336630009114742</threshold> + <left_val>-0.6159020066261292</left_val> + <right_val>0.1574929952621460</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 20 8 -1.</_> + <_>1 10 10 4 2.</_> + <_>11 14 10 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0119669996201992</threshold> + <left_val>-0.3060669898986816</left_val> + <right_val>0.4229330122470856</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 13 9 6 -1.</_> + <_>15 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0346800014376640</threshold> + <left_val>-1.3734940290451050</left_val> + <right_val>0.1590870022773743</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 9 -1.</_> + <_>9 3 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.9290004000067711e-003</threshold> + <left_val>-0.5586019754409790</left_val> + <right_val>0.1211920008063316</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 1 5 14 -1.</_> + <_>10 8 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0595749989151955</threshold> + <left_val>4.9720001406967640e-003</left_val> + <right_val>0.8205540180206299</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 16 6 -1.</_> + <_>3 6 16 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0654280036687851</threshold> + <left_val>1.5651429891586304</left_val> + <right_val>-0.1681749969720841</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 3 8 9 -1.</_> + <_>16 6 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0928959995508194</threshold> + <left_val>-1.5794529914855957</left_val> + <right_val>0.1466179937124252</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 13 6 10 -1.</_> + <_>9 13 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0411840006709099</threshold> + <left_val>-1.5518720149993896</left_val> + <right_val>-0.0299699995666742</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 13 9 6 -1.</_> + <_>15 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0214479994028807</threshold> + <left_val>0.1719630062580109</left_val> + <right_val>-0.6934319734573364</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 9 6 -1.</_> + <_>0 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0255699995905161</threshold> + <left_val>-1.3061310052871704</left_val> + <right_val>-0.0243369992822409</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 16 9 6 -1.</_> + <_>13 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0412009991705418</threshold> + <left_val>-1.3821059465408325</left_val> + <right_val>0.1480180025100708</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 16 9 6 -1.</_> + <_>2 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0176689997315407</threshold> + <left_val>-0.7088999748229981</left_val> + <right_val>0.0365240015089512</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 16 18 3 -1.</_> + <_>5 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.0060001239180565e-003</threshold> + <left_val>-0.0409139990806580</left_val> + <right_val>0.8037310242652893</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 16 18 3 -1.</_> + <_>1 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0116529995575547</threshold> + <left_val>0.5754680037498474</left_val> + <right_val>-0.2499170005321503</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 18 3 -1.</_> + <_>5 1 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.4780001305043697e-003</threshold> + <left_val>-0.4928089976310730</left_val> + <right_val>0.1981090009212494</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 19 2 -1.</_> + <_>1 2 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.5499999113380909e-004</threshold> + <left_val>-0.4885810017585754</left_val> + <right_val>0.1356309950351715</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 2 6 11 -1.</_> + <_>16 2 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0305380001664162</threshold> + <left_val>-0.6027839779853821</left_val> + <right_val>0.1852200031280518</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 15 15 6 -1.</_> + <_>9 15 5 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0188469998538494</threshold> + <left_val>0.2356559932231903</left_val> + <right_val>-0.3513630032539368</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 2 6 11 -1.</_> + <_>16 2 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.1129996106028557e-003</threshold> + <left_val>-0.0813049972057343</left_val> + <right_val>0.2106959968805313</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 2 6 11 -1.</_> + <_>6 2 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0348300002515316</threshold> + <left_val>-1.2065670490264893</left_val> + <right_val>-0.0142519995570183</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 9 -1.</_> + <_>18 5 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0190210007131100</threshold> + <left_val>0.2334990054368973</left_val> + <right_val>-0.4566490054130554</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 22 4 -1.</_> + <_>1 2 11 2 2.</_> + <_>12 4 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0190040003508329</threshold> + <left_val>-0.8107579946517944</left_val> + <right_val>0.0131400004029274</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 21 12 -1.</_> + <_>9 0 7 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0890579968690872</threshold> + <left_val>0.6154239773750305</left_val> + <right_val>0.0329830013215542</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 18 3 -1.</_> + <_>0 13 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.8620000965893269e-003</threshold> + <left_val>-0.2958309948444367</left_val> + <right_val>0.2700369954109192</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 2 6 9 -1.</_> + <_>14 2 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0282409992069006</threshold> + <left_val>-0.6110270023345947</left_val> + <right_val>0.1735749989748001</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 18 3 -1.</_> + <_>3 11 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.2099999953061342e-004</threshold> + <left_val>-0.5332289934158325</left_val> + <right_val>0.0685390010476112</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 3 8 9 -1.</_> + <_>16 6 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1082910001277924</threshold> + <left_val>-1.2879559993743896</left_val> + <right_val>0.1180170029401779</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 18 3 -1.</_> + <_>3 8 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0158789996057749</threshold> + <left_val>-0.1707260012626648</left_val> + <right_val>1.1103910207748413</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 11 6 9 -1.</_> + <_>11 11 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.6859995499253273e-003</threshold> + <left_val>-0.1099509969353676</left_val> + <right_val>0.4601050019264221</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 6 9 -1.</_> + <_>11 8 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0252349991351366</threshold> + <left_val>1.0220669507980347</left_val> + <right_val>-0.1869429945945740</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 2 18 -1.</_> + <_>15 0 1 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0135089997202158</threshold> + <left_val>-0.7831659913063049</left_val> + <right_val>0.1420260071754456</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 2 18 -1.</_> + <_>8 0 1 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.7149998396635056e-003</threshold> + <left_val>-0.8806070089340210</left_val> + <right_val>0.0110600003972650</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 3 7 9 -1.</_> + <_>17 6 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0715800002217293</threshold> + <left_val>0.1136939972639084</left_val> + <right_val>-1.1032789945602417</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 9 6 -1.</_> + <_>3 20 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0135540002956986</threshold> + <left_val>-0.8109650015830994</left_val> + <right_val>3.4080001059919596e-003</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 21 3 -1.</_> + <_>3 19 21 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.9450000729411840e-003</threshold> + <left_val>-0.0728799998760223</left_val> + <right_val>0.3499810099601746</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 7 9 -1.</_> + <_>0 6 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0508330017328262</threshold> + <left_val>-1.2868590354919434</left_val> + <right_val>-0.0288420002907515</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 22 3 -1.</_> + <_>2 8 22 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.7989997118711472e-003</threshold> + <left_val>0.4761359989643097</left_val> + <right_val>-0.1469040066003799</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 24 16 -1.</_> + <_>0 3 12 8 2.</_> + <_>12 11 12 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2142439931631088</threshold> + <left_val>-0.0597020015120506</left_val> + <right_val>-2.4802260398864746</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 17 9 4 -1.</_> + <_>13 19 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0139629999175668</threshold> + <left_val>0.1742029935121536</left_val> + <right_val>-0.4391100108623505</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 12 8 -1.</_> + <_>5 5 6 4 2.</_> + <_>11 9 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0425020009279251</threshold> + <left_val>-0.1996529996395111</left_val> + <right_val>0.7065479755401611</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 6 -1.</_> + <_>12 6 7 3 2.</_> + <_>5 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0198279991745949</threshold> + <left_val>-0.0691360011696815</left_val> + <right_val>0.6164339780807495</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 16 14 6 -1.</_> + <_>5 16 7 3 2.</_> + <_>12 19 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0335600003600121</threshold> + <left_val>-1.2740780115127563</left_val> + <right_val>-0.0256730001419783</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 9 -1.</_> + <_>18 5 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0635429993271828</threshold> + <left_val>0.1240350008010864</left_val> + <right_val>-1.0776289701461792</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 9 -1.</_> + <_>0 5 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0219330005347729</threshold> + <left_val>0.0149520002305508</left_val> + <right_val>-0.7102349996566773</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 20 10 -1.</_> + <_>13 4 10 5 2.</_> + <_>3 9 10 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0784249976277351</threshold> + <left_val>0.6203399896621704</left_val> + <right_val>0.0336109995841980</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 13 9 8 -1.</_> + <_>5 13 3 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0143900001421571</threshold> + <left_val>-0.3632459938526154</left_val> + <right_val>0.1730830073356628</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 1 21 15 -1.</_> + <_>9 1 7 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0673099979758263</threshold> + <left_val>0.5237410068511963</left_val> + <right_val>0.0127999996766448</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 12 14 8 -1.</_> + <_>12 12 7 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1304749995470047</threshold> + <left_val>-0.1712249964475632</left_val> + <right_val>1.1235200166702271</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 12 4 -1.</_> + <_>6 7 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0462459996342659</threshold> + <left_val>-1.1908329725265503</left_val> + <right_val>0.1742559969425201</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 9 6 -1.</_> + <_>9 5 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0298420004546642</threshold> + <left_val>0.8393059968948364</left_val> + <right_val>-0.1806419938802719</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 6 6 -1.</_> + <_>13 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.8099999073892832e-004</threshold> + <left_val>0.3553279936313629</left_val> + <right_val>-0.2384230047464371</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 6 6 -1.</_> + <_>8 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0223789997398853</threshold> + <left_val>-0.8794389963150024</left_val> + <right_val>-7.8399997437372804e-004</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 18 2 -1.</_> + <_>6 5 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.5569999814033508e-003</threshold> + <left_val>-0.1425330042839050</left_val> + <right_val>0.2587620019912720</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 11 -1.</_> + <_>2 2 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0120130004361272</threshold> + <left_val>-0.2901549935340881</left_val> + <right_val>0.2605110108852387</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 0 6 15 -1.</_> + <_>20 0 2 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0243849996477365</threshold> + <left_val>-0.0314389988780022</left_val> + <right_val>0.5869590044021606</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 13 -1.</_> + <_>2 0 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0471809990704060</threshold> + <left_val>0.6943010091781616</left_val> + <right_val>-0.2181610018014908</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 6 9 -1.</_> + <_>14 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0248939990997314</threshold> + <left_val>-0.6459929943084717</left_val> + <right_val>0.1561159938573837</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 6 9 -1.</_> + <_>8 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0219449996948242</threshold> + <left_val>-0.0277420002967119</left_val> + <right_val>-1.1346880197525024</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 4 -1.</_> + <_>8 2 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1880989968776703</threshold> + <left_val>-0.0100760003551841</left_val> + <right_val>1.2429029941558838</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 13 18 4 -1.</_> + <_>12 13 9 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0778720006346703</threshold> + <left_val>0.8500800132751465</left_val> + <right_val>-0.1901549994945526</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 7 10 4 -1.</_> + <_>9 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0487690009176731</threshold> + <left_val>-2.0763080120086670</left_val> + <right_val>0.1217940002679825</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 12 3 -1.</_> + <_>11 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0171150006353855</threshold> + <left_val>-0.8568729758262634</left_val> + <right_val>7.8760003671050072e-003</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 14 19 3 -1.</_> + <_>4 15 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.7499999850988388e-003</threshold> + <left_val>0.3864549994468689</left_val> + <right_val>-0.1139149963855743</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 4 20 -1.</_> + <_>10 10 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0987939983606339</threshold> + <left_val>-1.7233899831771851</left_val> + <right_val>-0.0560630001127720</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 15 9 6 -1.</_> + <_>8 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0219369996339083</threshold> + <left_val>0.5474939942359924</left_val> + <right_val>-0.0424819998443127</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 9 15 4 -1.</_> + <_>7 9 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0610969997942448</threshold> + <left_val>-0.0389450006186962</left_val> + <right_val>-1.0807880163192749</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 4 12 7 -1.</_> + <_>12 4 4 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0245639998465776</threshold> + <left_val>0.5831109881401062</left_val> + <right_val>-9.7599998116493225e-004</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 6 9 -1.</_> + <_>0 13 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0337520018219948</threshold> + <left_val>-0.0137959998100996</left_val> + <right_val>-0.8473029732704163</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 5 6 9 -1.</_> + <_>18 8 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0381990000605583</threshold> + <left_val>0.1511429995298386</left_val> + <right_val>-0.7947340011596680</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 18 16 6 -1.</_> + <_>0 18 8 3 2.</_> + <_>8 21 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0201179999858141</threshold> + <left_val>0.5157909989356995</left_val> + <right_val>-0.2144539952278137</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 18 14 6 -1.</_> + <_>16 18 7 3 2.</_> + <_>9 21 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0247349999845028</threshold> + <left_val>-0.0221050009131432</left_val> + <right_val>0.4291769862174988</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 20 20 4 -1.</_> + <_>1 20 10 2 2.</_> + <_>11 22 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0243570003658533</threshold> + <left_val>-0.8620129823684692</left_val> + <right_val>-3.6760000512003899e-003</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 8 20 6 -1.</_> + <_>12 8 10 3 2.</_> + <_>2 11 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0264420006424189</threshold> + <left_val>-0.4539749920368195</left_val> + <right_val>0.2246280014514923</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 6 9 -1.</_> + <_>9 8 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.4429999068379402e-003</threshold> + <left_val>0.1307300031185150</left_val> + <right_val>-0.3862270116806030</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 5 12 8 -1.</_> + <_>12 5 4 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1070170029997826</threshold> + <left_val>0.1315860003232956</left_val> + <right_val>-0.7930690050125122</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 5 12 8 -1.</_> + <_>8 5 4 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0451529994606972</threshold> + <left_val>-0.2529680132865906</left_val> + <right_val>0.4067240059375763</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 6 9 -1.</_> + <_>12 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0443499982357025</threshold> + <left_val>0.0226130001246929</left_val> + <right_val>0.7961810231208801</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 6 16 -1.</_> + <_>4 0 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.0839999886229634e-003</threshold> + <left_val>-0.3915840089321137</left_val> + <right_val>0.1163910031318665</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 4 6 12 -1.</_> + <_>15 8 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0714330002665520</threshold> + <left_val>0.0824669972062111</left_val> + <right_val>1.2530590295791626</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 6 12 -1.</_> + <_>3 8 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0358380004763603</threshold> + <left_val>-0.1820330023765564</left_val> + <right_val>0.7707870006561279</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 12 9 6 -1.</_> + <_>15 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0208390001207590</threshold> + <left_val>-0.6174439787864685</left_val> + <right_val>0.1589139997959137</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 15 22 -1.</_> + <_>4 11 15 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.4252580106258392</threshold> + <left_val>-0.0489780008792877</left_val> + <right_val>-1.8422030210494995</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 12 9 6 -1.</_> + <_>15 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0114080002531409</threshold> + <left_val>0.1791819930076599</left_val> + <right_val>-0.1538349986076355</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 9 6 -1.</_> + <_>0 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0153649998828769</threshold> + <left_val>-0.8401650190353394</left_val> + <right_val>-1.0280000278726220e-003</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 15 9 6 -1.</_> + <_>15 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0152120003476739</threshold> + <left_val>-0.1899569928646088</left_val> + <right_val>0.1713099926710129</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 9 6 -1.</_> + <_>0 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0189720001071692</threshold> + <left_val>-0.7954199910163879</left_val> + <right_val>6.6800001077353954e-003</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 8 10 -1.</_> + <_>14 0 4 5 2.</_> + <_>10 5 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.3330000005662441e-003</threshold> + <left_val>-0.2353080064058304</left_val> + <right_val>0.2473009973764420</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 4 16 -1.</_> + <_>3 0 2 16 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0932480022311211</threshold> + <left_val>-0.0547580011188984</left_val> + <right_val>-1.8324300050735474</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 10 6 -1.</_> + <_>7 8 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0125550003722310</threshold> + <left_val>0.2638520002365112</left_val> + <right_val>-0.3852640092372894</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 12 4 10 -1.</_> + <_>10 17 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0270700007677078</threshold> + <left_val>-0.6692979931831360</left_val> + <right_val>0.0203409995883703</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 4 10 6 -1.</_> + <_>8 6 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0236770007759333</threshold> + <left_val>0.6726530194282532</left_val> + <right_val>-0.0143440002575517</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 22 18 2 -1.</_> + <_>12 22 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0142750004306436</threshold> + <left_val>0.3018639981746674</left_val> + <right_val>-0.2851440012454987</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 11 6 -1.</_> + <_>7 9 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0280969999730587</threshold> + <left_val>0.1476600021123886</left_val> + <right_val>-1.4078520536422729</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 12 10 -1.</_> + <_>0 0 6 5 2.</_> + <_>6 5 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0508400015532970</threshold> + <left_val>-0.1861360073089600</left_val> + <right_val>0.7995300292968750</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 1 12 6 -1.</_> + <_>16 1 6 3 2.</_> + <_>10 4 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0115059996023774</threshold> + <left_val>0.1911839991807938</left_val> + <right_val>-0.0850350037217140</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 16 9 4 -1.</_> + <_>7 18 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0146610001102090</threshold> + <left_val>0.4523929953575134</left_val> + <right_val>-0.2220519930124283</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 15 16 -1.</_> + <_>10 7 5 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2284249961376190</threshold> + <left_val>0.1348839998245239</left_val> + <right_val>-1.2894610166549683</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 12 13 -1.</_> + <_>11 10 6 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1110690012574196</threshold> + <left_val>-0.2075379937887192</left_val> + <right_val>0.5456159710884094</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 2 12 6 -1.</_> + <_>12 2 6 3 2.</_> + <_>6 5 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.2450000289827585e-003</threshold> + <left_val>0.3205370008945465</left_val> + <right_val>-0.1640350073575974</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 12 9 -1.</_> + <_>3 12 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0853099972009659</threshold> + <left_val>-0.2021050006151199</left_val> + <right_val>0.5329679846763611</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 2 8 6 -1.</_> + <_>16 5 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0220480002462864</threshold> + <left_val>0.1569859981536865</left_val> + <right_val>-0.1701409965753555</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 8 6 -1.</_> + <_>0 5 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0156769994646311</threshold> + <left_val>-0.6286349892616272</left_val> + <right_val>0.0407619997859001</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 24 11 -1.</_> + <_>0 3 12 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.3311290144920349</threshold> + <left_val>0.1660930067300797</left_val> + <right_val>-1.0326379537582397</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 8 10 -1.</_> + <_>0 13 4 5 2.</_> + <_>4 18 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.8470000773668289e-003</threshold> + <left_val>-0.2507619857788086</left_val> + <right_val>0.3166059851646423</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 4 10 -1.</_> + <_>10 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0460800006985664</threshold> + <left_val>0.1535210013389587</left_val> + <right_val>-1.6333500146865845</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 21 -1.</_> + <_>10 9 4 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0377030000090599</threshold> + <left_val>0.5687379837036133</left_val> + <right_val>-0.2010259926319122</right_val></_></_></trees> + <stage_threshold>-3.5125269889831543</stage_threshold> + <parent>14</parent> + <next>-1</next></_> + <_> + <!-- stage 16 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 15 9 -1.</_> + <_>4 7 15 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0818089991807938</threshold> + <left_val>0.5712479948997498</left_val> + <right_val>-0.6743879914283752</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 6 -1.</_> + <_>8 1 8 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2176119983196259</threshold> + <left_val>-0.3861019909381867</left_val> + <right_val>0.9034399986267090</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 5 16 -1.</_> + <_>9 14 5 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0148780001327395</threshold> + <left_val>0.2224159985780716</left_val> + <right_val>-1.2779350280761719</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 18 3 -1.</_> + <_>9 21 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0524349994957447</threshold> + <left_val>-0.2869040071964264</left_val> + <right_val>0.7574229836463928</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 3 12 -1.</_> + <_>6 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.1429995372891426e-003</threshold> + <left_val>-0.6488040089607239</left_val> + <right_val>0.2226880043745041</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 4 9 -1.</_> + <_>11 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.9169999808073044e-003</threshold> + <left_val>-0.2925359904766083</left_val> + <right_val>0.3103019893169403</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 9 8 -1.</_> + <_>8 6 3 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0260840002447367</threshold> + <left_val>0.4553270041942596</left_val> + <right_val>-0.3850060105323792</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 20 2 -1.</_> + <_>4 4 20 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.9400000348687172e-003</threshold> + <left_val>-0.5126439929008484</left_val> + <right_val>0.2743229866027832</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 10 18 3 -1.</_> + <_>8 10 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0571300014853477</threshold> + <left_val>0.0157880000770092</left_val> + <right_val>-1.2133100032806396</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 15 10 6 -1.</_> + <_>7 17 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.1309998854994774e-003</threshold> + <left_val>0.3917460143566132</left_val> + <right_val>-0.3086679875850678</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 4 4 18 -1.</_> + <_>1 4 2 9 2.</_> + <_>3 13 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0404050014913082</threshold> + <left_val>1.1901949644088745</left_val> + <right_val>-0.2034710049629211</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 6 9 -1.</_> + <_>15 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0202970001846552</threshold> + <left_val>-0.6823949813842773</left_val> + <right_val>0.2045869976282120</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 6 9 -1.</_> + <_>7 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0171889998018742</threshold> + <left_val>-0.8493989706039429</left_val> + <right_val>0.0384330004453659</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 6 9 -1.</_> + <_>13 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0242159999907017</threshold> + <left_val>-1.1039420366287231</left_val> + <right_val>0.1597509980201721</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 9 6 -1.</_> + <_>9 7 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0568690001964569</threshold> + <left_val>-0.1959529966115952</left_val> + <right_val>1.1806850433349609</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 18 2 -1.</_> + <_>3 1 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.6199999158270657e-004</threshold> + <left_val>-0.4084779918193817</left_val> + <right_val>0.3293859958648682</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 20 4 -1.</_> + <_>0 10 10 2 2.</_> + <_>10 12 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.9790003150701523e-003</threshold> + <left_val>-0.2967300117015839</left_val> + <right_val>0.4154790043830872</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 12 -1.</_> + <_>10 8 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0526250004768372</threshold> + <left_val>-1.3069299459457397</left_val> + <right_val>0.1786260008811951</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 6 12 -1.</_> + <_>6 5 3 6 2.</_> + <_>9 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0137489996850491</threshold> + <left_val>0.2366580069065094</left_val> + <right_val>-0.4453659951686859</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 18 22 -1.</_> + <_>15 0 9 11 2.</_> + <_>6 11 9 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0305170007050037</threshold> + <left_val>0.2901830077171326</left_val> + <right_val>-0.1121010035276413</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 18 22 -1.</_> + <_>0 0 9 11 2.</_> + <_>9 11 9 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.3003750145435333</threshold> + <left_val>-2.4237680435180664</left_val> + <right_val>-0.0428309999406338</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 11 -1.</_> + <_>20 2 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0359909981489182</threshold> + <left_val>0.8820649981498718</left_val> + <right_val>-0.0470129996538162</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 11 -1.</_> + <_>2 2 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0551120005548000</threshold> + <left_val>0.8011900186538696</left_val> + <right_val>-0.2049099951982498</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 6 9 -1.</_> + <_>13 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0337620005011559</threshold> + <left_val>0.1461759954690933</left_val> + <right_val>-1.1349489688873291</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 20 3 -1.</_> + <_>0 1 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.2710003480315208e-003</threshold> + <left_val>-0.8160489797592163</left_val> + <right_val>0.0189880002290010</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 20 2 -1.</_> + <_>2 3 20 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.4399999789893627e-003</threshold> + <left_val>-0.7098090052604675</left_val> + <right_val>0.2234369963407517</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 18 2 -1.</_> + <_>1 11 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.1059999018907547e-003</threshold> + <left_val>-0.7280859947204590</left_val> + <right_val>0.0402249991893768</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 7 6 9 -1.</_> + <_>18 10 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0536519996821880</threshold> + <left_val>0.1717090010643005</left_val> + <right_val>-1.1163710355758667</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 22 9 -1.</_> + <_>0 3 22 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1254139989614487</threshold> + <left_val>2.7680370807647705</left_val> + <right_val>-0.1461150050163269</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 3 6 9 -1.</_> + <_>17 6 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0925420001149178</threshold> + <left_val>0.1160980015993118</left_val> + <right_val>-3.9635529518127441</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 6 9 -1.</_> + <_>0 10 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0385139994323254</threshold> + <left_val>-7.6399999670684338e-003</left_val> + <right_val>-0.9878090023994446</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 24 6 -1.</_> + <_>0 8 24 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.0200000144541264e-003</threshold> + <left_val>0.2305999994277954</left_val> + <right_val>-0.7497029900550842</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 10 -1.</_> + <_>2 2 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.7599998116493225e-003</threshold> + <left_val>-0.3113799989223480</left_val> + <right_val>0.3028779923915863</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 6 9 -1.</_> + <_>12 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0240950006991625</threshold> + <left_val>-0.0495299994945526</left_val> + <right_val>0.5269010066986084</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0179820004850626</threshold> + <left_val>-1.1610640287399292</left_val> + <right_val>-5.7000000961124897e-003</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 6 9 -1.</_> + <_>17 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0105550000444055</threshold> + <left_val>-0.2718909978866577</left_val> + <right_val>0.2359769940376282</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 6 9 -1.</_> + <_>5 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.2889998555183411e-003</threshold> + <left_val>-0.5421910285949707</left_val> + <right_val>0.0819140002131462</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 6 -1.</_> + <_>15 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0239390004426241</threshold> + <left_val>0.1797579973936081</left_val> + <right_val>-0.6704949736595154</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 18 3 -1.</_> + <_>0 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0183659996837378</threshold> + <left_val>0.6266430020332336</left_val> + <right_val>-0.2097010016441345</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 14 9 6 -1.</_> + <_>15 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0157159995287657</threshold> + <left_val>0.2419369965791702</left_val> + <right_val>-1.0444309711456299</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 23 6 -1.</_> + <_>0 17 23 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0488040000200272</threshold> + <left_val>-0.9406059980392456</left_val> + <right_val>-3.7519999314099550e-003</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 15 18 3 -1.</_> + <_>5 16 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.7130001261830330e-003</threshold> + <left_val>-0.0754320025444031</left_val> + <right_val>0.6157529950141907</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 9 6 -1.</_> + <_>0 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.7770001739263535e-003</threshold> + <left_val>0.0392850004136562</left_val> + <right_val>-0.8481029868125916</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 8 10 -1.</_> + <_>13 8 4 5 2.</_> + <_>9 13 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0147449998185039</threshold> + <left_val>0.1696899980306625</left_val> + <right_val>-0.5090640187263489</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 15 6 -1.</_> + <_>8 7 5 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0970790013670921</threshold> + <left_val>-0.0331030003726482</left_val> + <right_val>-1.2706379890441895</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 8 10 -1.</_> + <_>13 8 4 5 2.</_> + <_>9 13 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0482859984040260</threshold> + <left_val>0.0943299978971481</left_val> + <right_val>2.7203190326690674</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 6 12 -1.</_> + <_>8 0 3 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.7810002043843269e-003</threshold> + <left_val>-0.3953340053558350</left_val> + <right_val>0.1536380052566528</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 8 10 -1.</_> + <_>13 8 4 5 2.</_> + <_>9 13 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0398939996957779</threshold> + <left_val>-0.2276740074157715</left_val> + <right_val>0.1391399949789047</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 5 6 9 -1.</_> + <_>10 5 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0228480007499456</threshold> + <left_val>-0.2739199995994568</left_val> + <right_val>0.3419950008392334</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 18 -1.</_> + <_>12 6 2 9 2.</_> + <_>10 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.7179999314248562e-003</threshold> + <left_val>-0.1087429970502853</left_val> + <right_val>0.4812540113925934</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 12 4 -1.</_> + <_>11 7 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0595999993383884</threshold> + <left_val>-0.0495220012962818</left_val> + <right_val>-2.0117089748382568</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 8 10 -1.</_> + <_>13 8 4 5 2.</_> + <_>9 13 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.9340001791715622e-003</threshold> + <left_val>0.1503749936819077</left_val> + <right_val>-0.1127189993858337</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 8 10 -1.</_> + <_>7 8 4 5 2.</_> + <_>11 13 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0157570000737906</threshold> + <left_val>-0.0208850000053644</left_val> + <right_val>-1.1651979684829712</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 10 6 14 -1.</_> + <_>14 10 3 7 2.</_> + <_>11 17 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0496900007128716</threshold> + <left_val>-0.8021349906921387</left_val> + <right_val>0.1437229961156845</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 6 19 -1.</_> + <_>12 5 3 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0523470006883144</threshold> + <left_val>-0.2083670049905777</left_val> + <right_val>0.6167759895324707</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 12 12 6 -1.</_> + <_>12 12 6 3 2.</_> + <_>6 15 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0224309992045164</threshold> + <left_val>0.2030590027570725</left_val> + <right_val>-0.7532619833946228</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 9 18 6 -1.</_> + <_>1 9 9 3 2.</_> + <_>10 12 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0411420017480850</threshold> + <left_val>-0.1811819970607758</left_val> + <right_val>1.0033359527587891</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 14 8 10 -1.</_> + <_>20 14 4 5 2.</_> + <_>16 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0216320008039474</threshold> + <left_val>0.4999899864196777</left_val> + <right_val>-0.0346629992127419</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 22 8 -1.</_> + <_>0 9 11 4 2.</_> + <_>11 13 11 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0828080028295517</threshold> + <left_val>1.1711900234222412</left_val> + <right_val>-0.1843360066413879</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 12 6 -1.</_> + <_>14 18 6 3 2.</_> + <_>8 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.5060000419616699e-003</threshold> + <left_val>-0.0632250010967255</left_val> + <right_val>0.2902489900588989</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 20 18 -1.</_> + <_>0 6 10 9 2.</_> + <_>10 15 10 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0789050012826920</threshold> + <left_val>-0.2327450066804886</left_val> + <right_val>0.5969579815864563</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 20 12 -1.</_> + <_>13 6 10 6 2.</_> + <_>3 12 10 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0902070030570030</threshold> + <left_val>-0.8221189975738525</left_val> + <right_val>0.1777220070362091</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 10 8 -1.</_> + <_>0 16 5 4 2.</_> + <_>5 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0292690005153418</threshold> + <left_val>0.6086069941520691</left_val> + <right_val>-0.2146890014410019</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 18 3 -1.</_> + <_>6 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.9499998353421688e-003</threshold> + <left_val>-0.0426659993827343</left_val> + <right_val>0.6051210165023804</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 19 3 -1.</_> + <_>0 12 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.0629996955394745e-003</threshold> + <left_val>-1.1508270502090454</left_val> + <right_val>-0.0272860005497932</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 6 6 9 -1.</_> + <_>14 9 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0195959992706776</threshold> + <left_val>-9.1880001127719879e-003</left_val> + <right_val>0.5685780048370361</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 7 22 4 -1.</_> + <_>1 7 11 2 2.</_> + <_>12 9 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0148849999532104</threshold> + <left_val>0.3765879869461060</left_val> + <right_val>-0.2714950144290924</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 6 7 12 -1.</_> + <_>13 10 7 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0252170003950596</threshold> + <left_val>-0.0999910011887550</left_val> + <right_val>0.2466470003128052</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 11 9 -1.</_> + <_>4 10 11 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0158559996634722</threshold> + <left_val>0.6682670116424561</left_val> + <right_val>-0.2061470001935959</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 10 10 8 -1.</_> + <_>17 10 5 4 2.</_> + <_>12 14 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0294410008937120</threshold> + <left_val>0.1583220064640045</left_val> + <right_val>-0.7606089711189270</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 9 7 -1.</_> + <_>5 12 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.5279997438192368e-003</threshold> + <left_val>0.3821229934692383</left_val> + <right_val>-0.2540780007839203</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 14 6 9 -1.</_> + <_>16 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0244219992309809</threshold> + <left_val>0.1510509997606278</left_val> + <right_val>-0.2875289916992188</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 12 6 12 -1.</_> + <_>3 16 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0338869988918304</threshold> + <left_val>-0.6800280213356018</left_val> + <right_val>0.0343270003795624</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 6 6 -1.</_> + <_>14 16 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.0810000132769346e-003</threshold> + <left_val>0.2541390061378479</left_val> + <right_val>-0.2685909867286682</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 6 9 -1.</_> + <_>10 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0303589999675751</threshold> + <left_val>-0.0308420006185770</left_val> + <right_val>-1.1476809978485107</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 6 23 -1.</_> + <_>11 1 2 23 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.0210001170635223e-003</threshold> + <left_val>-0.3525379896163940</left_val> + <right_val>0.2986809909343720</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 9 6 -1.</_> + <_>0 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0276810005307198</threshold> + <left_val>-0.0381489992141724</left_val> + <right_val>-1.3262039422988892</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 17 18 3 -1.</_> + <_>4 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.9039996489882469e-003</threshold> + <left_val>-0.0237370003014803</left_val> + <right_val>0.7050300240516663</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 13 14 -1.</_> + <_>5 9 13 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0440310016274452</threshold> + <left_val>0.1067489981651306</left_val> + <right_val>-0.4526120126247406</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 8 12 -1.</_> + <_>19 0 4 6 2.</_> + <_>15 6 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0323709994554520</threshold> + <left_val>0.4667490124702454</left_val> + <right_val>-0.0615469999611378</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 8 12 -1.</_> + <_>0 0 4 6 2.</_> + <_>4 6 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0209330003708601</threshold> + <left_val>-0.2844789922237396</left_val> + <right_val>0.4384559988975525</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 8 7 -1.</_> + <_>8 2 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0252279993146658</threshold> + <left_val>-0.0225370004773140</left_val> + <right_val>0.7038909792900085</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 6 9 -1.</_> + <_>3 1 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.5520000644028187e-003</threshold> + <left_val>-0.3255490064620972</left_val> + <right_val>0.2402369976043701</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 8 6 12 -1.</_> + <_>17 8 3 6 2.</_> + <_>14 14 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0585579983890057</threshold> + <left_val>-1.2227720022201538</left_val> + <right_val>0.1166879981756210</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 8 6 12 -1.</_> + <_>4 8 3 6 2.</_> + <_>7 14 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0318999998271465</threshold> + <left_val>-0.0193050000816584</left_val> + <right_val>-1.0973169803619385</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 5 5 15 -1.</_> + <_>16 10 5 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0304450001567602</threshold> + <left_val>0.6558250188827515</left_val> + <right_val>0.0750909969210625</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 5 15 -1.</_> + <_>3 10 5 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0149330003187060</threshold> + <left_val>-0.5215579867362976</left_val> + <right_val>0.1152309998869896</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 4 6 9 -1.</_> + <_>18 7 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0490080006420612</threshold> + <left_val>-0.7830399870872498</left_val> + <right_val>0.1665720045566559</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 7 6 15 -1.</_> + <_>1 12 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0831589996814728</threshold> + <left_val>-2.6879999786615372e-003</left_val> + <right_val>-0.8528230190277100</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 15 12 8 -1.</_> + <_>17 15 6 4 2.</_> + <_>11 19 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0239029992371798</threshold> + <left_val>-0.0510109998285770</left_val> + <right_val>0.4199909865856171</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 4 -1.</_> + <_>0 2 12 2 2.</_> + <_>12 4 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0164289996027946</threshold> + <left_val>0.0192329995334148</left_val> + <right_val>-0.6504909992218018</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 1 2 19 -1.</_> + <_>15 1 1 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0118380002677441</threshold> + <left_val>-0.6240980029106140</left_val> + <right_val>0.1541119962930679</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 2 19 -1.</_> + <_>8 1 1 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.6799999866634607e-004</threshold> + <left_val>0.1758919954299927</left_val> + <right_val>-0.3433870077133179</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>22 1 2 20 -1.</_> + <_>22 1 1 20 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0191939994692802</threshold> + <left_val>0.0434189997613430</left_val> + <right_val>0.7906919717788696</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 2 20 -1.</_> + <_>1 1 1 20 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0100320000201464</threshold> + <left_val>0.4564889967441559</left_val> + <right_val>-0.2249480038881302</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 11 6 12 -1.</_> + <_>20 11 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0140040004625916</threshold> + <left_val>0.3357099890708923</left_val> + <right_val>-4.8799999058246613e-003</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 6 12 -1.</_> + <_>2 11 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1031989976763725</threshold> + <left_val>-2.3378000259399414</left_val> + <right_val>-0.0589330010116100</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 14 -1.</_> + <_>3 13 18 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0956970006227493</threshold> + <left_val>-0.6615390181541443</left_val> + <right_val>0.2009859979152679</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 10 7 8 -1.</_> + <_>6 14 7 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0414809994399548</threshold> + <left_val>0.4593920111656189</left_val> + <right_val>-0.2231409996747971</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 9 12 12 -1.</_> + <_>7 13 12 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.4099999573081732e-003</threshold> + <left_val>-0.2689859867095947</left_val> + <right_val>0.2492299973964691</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 18 18 5 -1.</_> + <_>11 18 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1072499975562096</threshold> + <left_val>-0.1864019930362701</left_val> + <right_val>0.7276980280876160</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 21 20 3 -1.</_> + <_>4 22 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.1870000530034304e-003</threshold> + <left_val>-0.0246089994907379</left_val> + <right_val>0.2864390015602112</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 12 -1.</_> + <_>9 12 3 6 2.</_> + <_>12 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0291670002043247</threshold> + <left_val>-0.0346830002963543</left_val> + <right_val>-1.1162580251693726</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 18 3 -1.</_> + <_>4 7 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0112870000302792</threshold> + <left_val>6.3760001212358475e-003</left_val> + <right_val>0.6663209795951843</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 3 -1.</_> + <_>3 7 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0120010003447533</threshold> + <left_val>0.4242010116577148</left_val> + <right_val>-0.2627980113029480</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 4 6 9 -1.</_> + <_>18 7 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0126959998160601</threshold> + <left_val>-0.0219570007175207</left_val> + <right_val>0.1893679946660996</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 9 6 -1.</_> + <_>2 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0245970003306866</threshold> + <left_val>-0.0349639989435673</left_val> + <right_val>-1.0989320278167725</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 14 18 4 -1.</_> + <_>13 14 9 2 2.</_> + <_>4 16 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0459530018270016</threshold> + <left_val>0.1110979989171028</left_val> + <right_val>-2.9306049346923828</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 6 14 -1.</_> + <_>7 7 3 7 2.</_> + <_>10 14 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0272410009056330</threshold> + <left_val>0.2910169959068298</left_val> + <right_val>-0.2740789949893951</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 13 12 6 -1.</_> + <_>13 13 6 3 2.</_> + <_>7 16 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0400639995932579</threshold> + <left_val>0.1187790036201477</left_val> + <right_val>-0.6280180215835571</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 12 9 -1.</_> + <_>10 7 4 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0230550002306700</threshold> + <left_val>0.1481380015611649</left_val> + <right_val>-0.3700749874114990</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 12 6 6 -1.</_> + <_>12 12 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0237370003014803</threshold> + <left_val>-0.5372480154037476</left_val> + <right_val>0.1935819983482361</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 4 10 -1.</_> + <_>0 7 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0775220021605492</threshold> + <left_val>-0.0601940006017685</left_val> + <right_val>-1.9489669799804688</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 9 6 -1.</_> + <_>11 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0133450003340840</threshold> + <left_val>-0.4522959887981415</left_val> + <right_val>0.1874150037765503</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 9 12 6 -1.</_> + <_>2 12 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0217199996113777</threshold> + <left_val>1.2144249677658081</left_val> + <right_val>-0.1536580026149750</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 10 6 9 -1.</_> + <_>13 13 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0714749991893768</threshold> + <left_val>-2.3047130107879639</left_val> + <right_val>0.1099990010261536</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 6 9 -1.</_> + <_>5 13 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.4999999701976776e-003</threshold> + <left_val>-0.7185519933700562</left_val> + <right_val>0.0201009996235371</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 15 9 6 -1.</_> + <_>9 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0267409998923540</threshold> + <left_val>0.0735450014472008</left_val> + <right_val>0.9878600239753723</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 16 12 6 -1.</_> + <_>5 19 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0394079983234406</threshold> + <left_val>-1.2227380275726318</left_val> + <right_val>-0.0435069985687733</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 20 3 -1.</_> + <_>3 3 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0258889999240637</threshold> + <left_val>0.1340930014848709</left_val> + <right_val>-1.1770780086517334</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 12 6 -1.</_> + <_>6 5 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0489250011742115</threshold> + <left_val>-0.0308100003749132</left_val> + <right_val>-0.9347950220108032</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 3 24 -1.</_> + <_>12 0 1 24 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0368929989635944</threshold> + <left_val>0.1333370059728622</left_val> + <right_val>-1.4998290538787842</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 16 15 4 -1.</_> + <_>8 16 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0789299979805946</threshold> + <left_val>-0.1453880071640015</left_val> + <right_val>1.5631790161132813</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 12 -1.</_> + <_>9 18 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0290060006082058</threshold> + <left_val>0.1938370019197464</left_val> + <right_val>-0.6764280200004578</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 15 12 8 -1.</_> + <_>1 15 6 4 2.</_> + <_>7 19 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.3089998438954353e-003</threshold> + <left_val>-0.3746539950370789</left_val> + <right_val>0.1085750013589859</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 10 8 14 -1.</_> + <_>19 10 4 7 2.</_> + <_>15 17 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0658309981226921</threshold> + <left_val>0.8105940222740173</left_val> + <right_val>0.0302019994705915</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 9 8 14 -1.</_> + <_>1 9 4 7 2.</_> + <_>5 16 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0689650028944016</threshold> + <left_val>0.8377259969711304</left_val> + <right_val>-0.1714099943637848</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 11 9 10 -1.</_> + <_>9 16 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1166910007596016</threshold> + <left_val>-0.9464719891548157</left_val> + <right_val>0.1312319934368134</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 12 6 -1.</_> + <_>6 9 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.3060000492259860e-003</threshold> + <left_val>0.0460079982876778</left_val> + <right_val>-0.5201159715652466</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 15 6 9 -1.</_> + <_>12 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0445589981973171</threshold> + <left_val>-1.9423669576644897</left_val> + <right_val>0.1320070028305054</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 9 7 -1.</_> + <_>10 8 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0510330013930798</threshold> + <left_val>-0.2148099988698959</left_val> + <right_val>0.4867390096187592</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 4 8 10 -1.</_> + <_>14 4 4 5 2.</_> + <_>10 9 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0315780006349087</threshold> + <left_val>0.5998979806900024</left_val> + <right_val>7.9159997403621674e-003</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 6 9 -1.</_> + <_>4 9 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0210200008004904</threshold> + <left_val>-0.2206950038671494</left_val> + <right_val>0.5404620170593262</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 24 12 -1.</_> + <_>8 6 8 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1382420063018799</threshold> + <left_val>0.6295750141143799</left_val> + <right_val>-0.0217129997909069</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 6 14 -1.</_> + <_>6 7 3 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0522289983928204</threshold> + <left_val>-0.2336090058088303</left_val> + <right_val>0.4976080060005188</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 8 5 8 -1.</_> + <_>19 12 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0258840005844831</threshold> + <left_val>0.1804199963808060</left_val> + <right_val>-0.2203920036554337</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 5 8 -1.</_> + <_>0 12 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0121389999985695</threshold> + <left_val>-0.6973189711570740</left_val> + <right_val>0.0157120004296303</right_val></_></_> + <_> + <!-- tree 137 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 3 6 6 -1.</_> + <_>17 6 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0242379996925592</threshold> + <left_val>0.3459329903125763</left_val> + <right_val>0.0714699998497963</right_val></_></_> + <_> + <!-- tree 138 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 3 6 6 -1.</_> + <_>1 6 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0252720005810261</threshold> + <left_val>-0.8758329749107361</left_val> + <right_val>-9.8240002989768982e-003</right_val></_></_> + <_> + <!-- tree 139 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 9 -1.</_> + <_>18 5 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0125970002263784</threshold> + <left_val>0.2364999949932098</left_val> + <right_val>-0.2873120009899139</right_val></_></_> + <_> + <!-- tree 140 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 9 -1.</_> + <_>0 5 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0573309995234013</threshold> + <left_val>-0.0615309998393059</left_val> + <right_val>-2.2326040267944336</right_val></_></_> + <_> + <!-- tree 141 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 3 18 6 -1.</_> + <_>3 5 18 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0166710000485182</threshold> + <left_val>-0.1985010057687759</left_val> + <right_val>0.4081070125102997</right_val></_></_> + <_> + <!-- tree 142 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 3 9 6 -1.</_> + <_>2 5 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0228189993649721</threshold> + <left_val>0.9648759961128235</left_val> + <right_val>-0.2024569958448410</right_val></_></_> + <_> + <!-- tree 143 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 3 10 8 -1.</_> + <_>14 3 5 4 2.</_> + <_>9 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.7000001611886546e-005</threshold> + <left_val>-0.0589089989662170</left_val> + <right_val>0.2705540060997009</right_val></_></_> + <_> + <!-- tree 144 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 3 10 8 -1.</_> + <_>5 3 5 4 2.</_> + <_>10 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.6700001955032349e-003</threshold> + <left_val>-0.4531710147857666</left_val> + <right_val>0.0896280035376549</right_val></_></_> + <_> + <!-- tree 145 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 11 6 12 -1.</_> + <_>10 11 3 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0940859988331795</threshold> + <left_val>0.1160459965467453</left_val> + <right_val>-1.0951169729232788</right_val></_></_> + <_> + <!-- tree 146 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 11 6 11 -1.</_> + <_>11 11 3 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0622670017182827</threshold> + <left_val>1.8096530437469482</left_val> + <right_val>-0.1477320045232773</right_val></_></_> + <_> + <!-- tree 147 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 10 4 -1.</_> + <_>7 8 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0174160003662109</threshold> + <left_val>0.2306820005178452</left_val> + <right_val>-0.4241760075092316</right_val></_></_> + <_> + <!-- tree 148 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 7 -1.</_> + <_>12 6 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0220660008490086</threshold> + <left_val>0.4927029907703400</left_val> + <right_val>-0.2063090056180954</right_val></_></_> + <_> + <!-- tree 149 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 18 18 3 -1.</_> + <_>5 19 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0104040000587702</threshold> + <left_val>0.6092429757118225</left_val> + <right_val>0.0281300004571676</right_val></_></_> + <_> + <!-- tree 150 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 4 6 9 -1.</_> + <_>10 4 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.3670003116130829e-003</threshold> + <left_val>0.4017120003700256</left_val> + <right_val>-0.2168170064687729</right_val></_></_> + <_> + <!-- tree 151 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 9 7 -1.</_> + <_>11 1 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0290399994701147</threshold> + <left_val>-0.8487650156021118</left_val> + <right_val>0.1424680054187775</right_val></_></_> + <_> + <!-- tree 152 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 6 6 -1.</_> + <_>9 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0210619997233152</threshold> + <left_val>-0.7919830083847046</left_val> + <right_val>-0.0125959999859333</right_val></_></_> + <_> + <!-- tree 153 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 12 4 11 -1.</_> + <_>14 12 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0370009988546371</threshold> + <left_val>-0.6748890280723572</left_val> + <right_val>0.1283040046691895</right_val></_></_> + <_> + <!-- tree 154 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 12 4 11 -1.</_> + <_>8 12 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0107359997928143</threshold> + <left_val>0.0367799997329712</left_val> + <right_val>-0.6339300274848938</right_val></_></_> + <_> + <!-- tree 155 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 12 18 -1.</_> + <_>12 0 4 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1636759936809540</threshold> + <left_val>0.1380389928817749</left_val> + <right_val>-0.4718900024890900</right_val></_></_> + <_> + <!-- tree 156 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 10 5 -1.</_> + <_>7 12 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0949179977178574</threshold> + <left_val>-0.1385570019483566</left_val> + <right_val>1.9492419958114624</right_val></_></_> + <_> + <!-- tree 157 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 20 22 3 -1.</_> + <_>2 21 22 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0352619998157024</threshold> + <left_val>0.1372189968824387</left_val> + <right_val>-2.1186530590057373</right_val></_></_> + <_> + <!-- tree 158 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 2 20 -1.</_> + <_>1 4 1 20 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0128110004588962</threshold> + <left_val>-0.2000810056924820</left_val> + <right_val>0.4950779974460602</right_val></_></_></trees> + <stage_threshold>-3.5939640998840332</stage_threshold> + <parent>15</parent> + <next>-1</next></_> + <_> + <!-- stage 17 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 4 -1.</_> + <_>8 2 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1390440016984940</threshold> + <left_val>-0.4658119976520538</left_val> + <right_val>0.7643160223960877</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 10 4 -1.</_> + <_>7 10 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0119169997051358</threshold> + <left_val>-0.9439899921417236</left_val> + <right_val>0.3972629904747009</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 8 10 -1.</_> + <_>6 7 4 5 2.</_> + <_>10 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0100069995969534</threshold> + <left_val>0.3271879851818085</left_val> + <right_val>-0.6336740255355835</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 6 14 -1.</_> + <_>17 0 3 7 2.</_> + <_>14 7 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.0479999519884586e-003</threshold> + <left_val>0.2742789983749390</left_val> + <right_val>-0.5744699835777283</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 11 5 8 -1.</_> + <_>4 15 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.2489999644458294e-003</threshold> + <left_val>0.2362930029630661</left_val> + <right_val>-0.6859350204467773</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 20 9 -1.</_> + <_>2 3 20 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0323820002377033</threshold> + <left_val>-0.5763019919395447</left_val> + <right_val>0.2749269902706146</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 12 8 -1.</_> + <_>6 7 6 4 2.</_> + <_>12 11 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0139579996466637</threshold> + <left_val>-0.6106150150299072</left_val> + <right_val>0.2454160004854202</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 17 6 6 -1.</_> + <_>9 20 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.1159999994561076e-003</threshold> + <left_val>-0.5653910040855408</left_val> + <right_val>0.2717930078506470</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 10 10 4 -1.</_> + <_>7 12 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.7000000045518391e-005</threshold> + <left_val>-0.8023599982261658</left_val> + <right_val>0.1150910034775734</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 12 9 -1.</_> + <_>10 5 4 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.5700000696815550e-004</threshold> + <left_val>-0.8120589852333069</left_val> + <right_val>0.2384469956159592</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 6 8 -1.</_> + <_>8 11 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.0460000745952129e-003</threshold> + <left_val>0.1390960067510605</left_val> + <right_val>-0.6616320013999939</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 4 4 17 -1.</_> + <_>18 4 2 17 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0143560003489256</threshold> + <left_val>-0.1648519933223724</left_val> + <right_val>0.4190169870853424</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 6 -1.</_> + <_>3 0 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0553749985992908</threshold> + <left_val>1.4425870180130005</left_val> + <right_val>-0.1882019937038422</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 4 4 17 -1.</_> + <_>18 4 2 17 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0935949981212616</threshold> + <left_val>0.1354829967021942</left_val> + <right_val>-0.9163609743118286</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 4 4 17 -1.</_> + <_>4 4 2 17 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0266249999403954</threshold> + <left_val>-0.3374829888343811</left_val> + <right_val>0.3923360109329224</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 18 19 3 -1.</_> + <_>5 19 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.7469998933374882e-003</threshold> + <left_val>-0.1161540001630783</left_val> + <right_val>0.4439930021762848</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 2 18 -1.</_> + <_>11 9 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0318860001862049</threshold> + <left_val>-0.9949830174446106</left_val> + <right_val>1.6120000509545207e-003</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 4 2 18 -1.</_> + <_>15 13 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0226000007241964</threshold> + <left_val>-0.4806739985942841</left_val> + <right_val>0.1700730025768280</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 4 2 18 -1.</_> + <_>7 13 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0252020005136728</threshold> + <left_val>0.0355800017714500</left_val> + <right_val>-0.8021540045738220</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 11 10 8 -1.</_> + <_>12 11 5 4 2.</_> + <_>7 15 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0310369990766048</threshold> + <left_val>-1.0895340442657471</left_val> + <right_val>0.1808190047740936</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 9 -1.</_> + <_>12 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0264759995043278</threshold> + <left_val>0.9567120075225830</left_val> + <right_val>-0.2104939967393875</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 6 9 -1.</_> + <_>12 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0138539997860789</threshold> + <left_val>-1.0370320081710815</left_val> + <right_val>0.2216670066118240</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 9 16 8 -1.</_> + <_>2 9 8 4 2.</_> + <_>10 13 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0629250034689903</threshold> + <left_val>0.9019939899444580</left_val> + <right_val>-0.1908529996871948</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 6 9 -1.</_> + <_>14 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0447509996592999</threshold> + <left_val>-1.0119110345840454</left_val> + <right_val>0.1469119936227799</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 6 9 -1.</_> + <_>10 7 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0204280000180006</threshold> + <left_val>0.6162449717521668</left_val> + <right_val>-0.2355269938707352</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 6 9 -1.</_> + <_>14 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.0329999327659607e-003</threshold> + <left_val>-0.0832799971103668</left_val> + <right_val>0.2172870039939880</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 12 12 6 -1.</_> + <_>3 14 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.7280003353953362e-003</threshold> + <left_val>0.0654589980840683</left_val> + <right_val>-0.6031870245933533</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 12 9 6 -1.</_> + <_>14 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0272020008414984</threshold> + <left_val>-0.9344739913940430</left_val> + <right_val>0.1527000069618225</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 12 9 6 -1.</_> + <_>1 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0164710003882647</threshold> + <left_val>-0.8417710065841675</left_val> + <right_val>0.0133320000022650</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 18 3 -1.</_> + <_>3 8 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0137440003454685</threshold> + <left_val>0.6056720018386841</left_val> + <right_val>-0.0920210033655167</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 7 22 6 -1.</_> + <_>1 9 22 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0291649997234344</threshold> + <left_val>-0.0281140003353357</left_val> + <right_val>-1.4014569520950317</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 4 6 6 -1.</_> + <_>18 7 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0374570004642010</threshold> + <left_val>0.1308059990406036</left_val> + <right_val>-0.4938249886035919</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 6 6 -1.</_> + <_>0 7 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0250700004398823</threshold> + <left_val>-1.1289390325546265</left_val> + <right_val>-0.0146000003442168</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 16 6 -1.</_> + <_>5 14 16 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0638120025396347</threshold> + <left_val>0.7587159872055054</left_val> + <right_val>-1.8200000049546361e-003</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 9 4 -1.</_> + <_>6 18 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.3900002539157867e-003</threshold> + <left_val>0.2993640005588532</left_val> + <right_val>-0.2948780059814453</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 6 9 -1.</_> + <_>14 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.6000002445653081e-004</threshold> + <left_val>0.0197250004857779</left_val> + <right_val>0.1999389976263046</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 15 6 9 -1.</_> + <_>4 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0217409990727901</threshold> + <left_val>-0.8524789810180664</left_val> + <right_val>0.0491699986159801</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 1 6 23 -1.</_> + <_>17 1 2 23 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0178699996322393</threshold> + <left_val>-0.0599859990179539</left_val> + <right_val>0.1522250026464462</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 21 24 3 -1.</_> + <_>8 21 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0248310007154942</threshold> + <left_val>0.3560340106487274</left_val> + <right_val>-0.2625989913940430</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 20 24 4 -1.</_> + <_>8 20 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1571550071239471</threshold> + <left_val>1.5599999460391700e-004</left_val> + <right_val>1.0428730249404907</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 6 23 -1.</_> + <_>5 1 2 23 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0690269991755486</threshold> + <left_val>-0.0330069996416569</left_val> + <right_val>-1.1796669960021973</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 17 18 3 -1.</_> + <_>3 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0110219996422529</threshold> + <left_val>0.5898770093917847</left_val> + <right_val>-0.0576479993760586</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 18 3 -1.</_> + <_>0 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0138349998742342</threshold> + <left_val>0.5950279831886292</left_val> + <right_val>-0.2441859990358353</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 16 22 4 -1.</_> + <_>12 16 11 2 2.</_> + <_>1 18 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0309410002082586</threshold> + <left_val>-1.1723799705505371</left_val> + <right_val>0.1690700054168701</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 9 6 -1.</_> + <_>0 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0212580002844334</threshold> + <left_val>-0.0189009997993708</left_val> + <right_val>-1.0684759616851807</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 10 21 3 -1.</_> + <_>9 10 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0930799990892410</threshold> + <left_val>0.1630560010671616</left_val> + <right_val>-1.3375270366668701</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 18 12 6 -1.</_> + <_>2 18 6 3 2.</_> + <_>8 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0296359993517399</threshold> + <left_val>-0.2252479940652847</left_val> + <right_val>0.4540010094642639</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 24 4 -1.</_> + <_>0 7 24 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.2199999764561653e-004</threshold> + <left_val>0.2740910053253174</left_val> + <right_val>-0.3737139999866486</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 15 -1.</_> + <_>10 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0420980006456375</threshold> + <left_val>-0.7582880258560181</left_val> + <right_val>0.0171370003372431</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 6 12 -1.</_> + <_>10 13 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0225050002336502</threshold> + <left_val>-0.2275930047035217</left_val> + <right_val>0.2369869947433472</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 6 9 -1.</_> + <_>8 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0128629999235272</threshold> + <left_val>0.1925240010023117</left_val> + <right_val>-0.3212710022926331</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 6 9 -1.</_> + <_>13 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0278600007295609</threshold> + <left_val>0.1672369986772537</left_val> + <right_val>-1.0209059715270996</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 7 6 9 -1.</_> + <_>11 7 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0278079994022846</threshold> + <left_val>1.2824759483337402</left_val> + <right_val>-0.1722529977560043</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 1 20 3 -1.</_> + <_>2 2 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.1630001291632652e-003</threshold> + <left_val>-0.5407289862632752</left_val> + <right_val>0.2388570010662079</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 18 12 6 -1.</_> + <_>1 18 6 3 2.</_> + <_>7 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0204360000789166</threshold> + <left_val>0.6335539817810059</left_val> + <right_val>-0.2109059989452362</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 2 4 13 -1.</_> + <_>13 2 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0123079996556044</threshold> + <left_val>-0.4977819919586182</left_val> + <right_val>0.1740259975194931</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 12 4 -1.</_> + <_>12 7 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0404939986765385</threshold> + <left_val>-1.1848740577697754</left_val> + <right_val>-0.0338909998536110</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 1 4 13 -1.</_> + <_>10 1 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0296570006757975</threshold> + <left_val>0.0217409990727901</left_val> + <right_val>1.0069919824600220</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 3 18 -1.</_> + <_>7 0 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.8379999138414860e-003</threshold> + <left_val>0.0292179994285107</left_val> + <right_val>-0.5990629792213440</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 3 10 5 -1.</_> + <_>14 3 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0161649994552135</threshold> + <left_val>-0.2100079953670502</left_val> + <right_val>0.3763729929924011</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 15 12 8 -1.</_> + <_>10 15 4 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0501930005848408</threshold> + <left_val>2.5319999549537897e-003</left_val> + <right_val>-0.7166820168495178</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 10 6 9 -1.</_> + <_>11 10 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.9680000841617584e-003</threshold> + <left_val>-0.2192140072584152</left_val> + <right_val>0.3229869902133942</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 3 4 9 -1.</_> + <_>10 3 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0249799992889166</threshold> + <left_val>-9.6840001642704010e-003</left_val> + <right_val>-0.7757290005683899</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 0 6 14 -1.</_> + <_>20 0 3 7 2.</_> + <_>17 7 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0158099997788668</threshold> + <left_val>0.4463750123977661</left_val> + <right_val>-0.0617600008845329</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 6 14 -1.</_> + <_>1 0 3 7 2.</_> + <_>4 7 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0372069999575615</threshold> + <left_val>-0.2049539983272553</left_val> + <right_val>0.5772219896316528</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 6 16 -1.</_> + <_>17 0 3 8 2.</_> + <_>14 8 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0792649984359741</threshold> + <left_val>-0.7674540281295776</left_val> + <right_val>0.1255040019750595</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 4 4 10 -1.</_> + <_>9 4 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0171520002186298</threshold> + <left_val>-1.4121830463409424</left_val> + <right_val>-0.0517040006816387</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 17 18 6 -1.</_> + <_>12 17 9 3 2.</_> + <_>3 20 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0327400006353855</threshold> + <left_val>0.1933400034904480</left_val> + <right_val>-0.6363369822502136</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 20 22 4 -1.</_> + <_>12 20 11 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1175699979066849</threshold> + <left_val>0.8432540297508240</left_val> + <right_val>-0.1801860034465790</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 3 10 5 -1.</_> + <_>14 3 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1205720007419586</threshold> + <left_val>0.1253000050783157</left_val> + <right_val>-2.1213600635528564</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 10 5 -1.</_> + <_>5 3 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.2779999785125256e-003</threshold> + <left_val>-0.4660440087318420</left_val> + <right_val>0.0896439999341965</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 12 16 -1.</_> + <_>16 6 4 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0725449994206429</threshold> + <left_val>0.5182650089263916</left_val> + <right_val>0.0168239995837212</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 12 16 -1.</_> + <_>4 6 4 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1771059930324554</threshold> + <left_val>-0.0309100002050400</left_val> + <right_val>-1.1046639680862427</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 9 5 15 -1.</_> + <_>10 14 5 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.4229996427893639e-003</threshold> + <left_val>0.2444580048322678</left_val> + <right_val>-0.3861309885978699</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 18 21 2 -1.</_> + <_>1 19 21 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0130350003018975</threshold> + <left_val>0.9800440073013306</left_val> + <right_val>-0.1701650023460388</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 9 6 -1.</_> + <_>15 2 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0189120005816221</threshold> + <left_val>0.2024849951267242</left_val> + <right_val>-0.3854590058326721</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 12 4 -1.</_> + <_>12 1 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0214479994028807</threshold> + <left_val>-0.2571719884872437</left_val> + <right_val>0.3518120050430298</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 12 12 -1.</_> + <_>12 0 6 6 2.</_> + <_>6 6 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0633570030331612</threshold> + <left_val>0.1699479967355728</left_val> + <right_val>-0.9138380289077759</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 10 8 12 -1.</_> + <_>8 10 4 6 2.</_> + <_>12 16 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0324359983205795</threshold> + <left_val>-0.8568159937858582</left_val> + <right_val>-0.0216809995472431</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 16 10 8 -1.</_> + <_>19 16 5 4 2.</_> + <_>14 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0235649999231100</threshold> + <left_val>0.5611559748649597</left_val> + <right_val>-2.2400000307243317e-004</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 10 8 -1.</_> + <_>0 16 5 4 2.</_> + <_>5 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0187890008091927</threshold> + <left_val>-0.2545979917049408</left_val> + <right_val>0.3451290130615234</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 12 12 5 -1.</_> + <_>14 12 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0310420002788305</threshold> + <left_val>7.5719999149441719e-003</left_val> + <right_val>0.3480019867420197</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 10 8 -1.</_> + <_>6 16 5 4 2.</_> + <_>11 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0112269995734096</threshold> + <left_val>-0.6021980047225952</left_val> + <right_val>0.0428149998188019</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 12 6 -1.</_> + <_>13 6 6 3 2.</_> + <_>7 9 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0128459995612502</threshold> + <left_val>0.4202040135860443</left_val> + <right_val>-0.0538010001182556</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 4 18 -1.</_> + <_>9 6 2 9 2.</_> + <_>11 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0127919996157289</threshold> + <left_val>0.2272450029850006</left_val> + <right_val>-0.3239800035953522</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 9 6 14 -1.</_> + <_>13 9 3 7 2.</_> + <_>10 16 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0686519965529442</threshold> + <left_val>0.0935320034623146</left_val> + <right_val>10.</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 9 6 14 -1.</_> + <_>8 9 3 7 2.</_> + <_>11 16 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.2789999172091484e-003</threshold> + <left_val>-0.2692629992961884</left_val> + <right_val>0.3330320119857788</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 4 11 12 -1.</_> + <_>7 10 11 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0387790016829968</threshold> + <left_val>-0.7236530184745789</left_val> + <right_val>0.1780650019645691</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 8 6 16 -1.</_> + <_>4 8 3 8 2.</_> + <_>7 16 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.1820000410079956e-003</threshold> + <left_val>-0.3511939942836762</left_val> + <right_val>0.1658630073070526</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 3 4 21 -1.</_> + <_>17 10 4 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1751520037651062</threshold> + <left_val>0.1162310019135475</left_val> + <right_val>-1.5419290065765381</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 3 4 21 -1.</_> + <_>3 10 4 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1162799969315529</threshold> + <left_val>-9.1479998081922531e-003</left_val> + <right_val>-0.9984260201454163</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 1 8 18 -1.</_> + <_>14 1 4 9 2.</_> + <_>10 10 4 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0229640007019043</threshold> + <left_val>0.2056539952754974</left_val> + <right_val>0.0154320001602173</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 16 8 -1.</_> + <_>2 5 8 4 2.</_> + <_>10 9 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0514100007712841</threshold> + <left_val>0.5807240009307861</left_val> + <right_val>-0.2011840045452118</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 12 -1.</_> + <_>3 10 18 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2247419953346252</threshold> + <left_val>0.0187289994210005</left_val> + <right_val>1.0829299688339233</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 10 16 12 -1.</_> + <_>4 14 16 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.4860000535845757e-003</threshold> + <left_val>-0.3317129909992218</left_val> + <right_val>0.1990299969911575</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 4 8 20 -1.</_> + <_>19 4 4 10 2.</_> + <_>15 14 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1184630021452904</threshold> + <left_val>1.3711010217666626</left_val> + <right_val>0.0689269974827766</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 2 9 6 -1.</_> + <_>10 2 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0378109999001026</threshold> + <left_val>-9.3600002583116293e-004</left_val> + <right_val>-0.8399699926376343</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 4 8 20 -1.</_> + <_>19 4 4 10 2.</_> + <_>15 14 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0222020000219345</threshold> + <left_val>-0.0119639998301864</left_val> + <right_val>0.3667399883270264</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 4 8 20 -1.</_> + <_>1 4 4 10 2.</_> + <_>5 14 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0363660007715225</threshold> + <left_val>0.3786650002002716</left_val> + <right_val>-0.2771480083465576</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 8 8 14 -1.</_> + <_>15 8 4 7 2.</_> + <_>11 15 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1318469941616058</threshold> + <left_val>-2.7481179237365723</left_val> + <right_val>0.1066690012812614</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 8 14 -1.</_> + <_>5 8 4 7 2.</_> + <_>9 15 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0416559986770153</threshold> + <left_val>0.4752430021762848</left_val> + <right_val>-0.2324980050325394</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 13 5 8 -1.</_> + <_>10 17 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0331519991159439</threshold> + <left_val>-0.5792940258979797</left_val> + <right_val>0.1743440032005310</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 7 9 -1.</_> + <_>4 16 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0157699994742870</threshold> + <left_val>-0.0112840002402663</left_val> + <right_val>-0.8370140194892883</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 24 10 -1.</_> + <_>0 18 24 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0393630005419254</threshold> + <left_val>0.3482159972190857</left_val> + <right_val>-0.1745540052652359</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 2 8 11 -1.</_> + <_>8 2 4 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0678490027785301</threshold> + <left_val>1.4225699901580811</left_val> + <right_val>-0.1476559937000275</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 8 16 -1.</_> + <_>14 2 4 8 2.</_> + <_>10 10 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0267750006169081</threshold> + <left_val>0.2394700050354004</left_val> + <right_val>0.0132719995453954</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 6 -1.</_> + <_>0 2 12 3 2.</_> + <_>12 5 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0399190001189709</threshold> + <left_val>-8.9999996125698090e-003</left_val> + <right_val>-0.7593889832496643</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 12 9 -1.</_> + <_>6 3 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1006560027599335</threshold> + <left_val>-0.0186850000172853</left_val> + <right_val>0.7624530196189880</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 12 12 -1.</_> + <_>1 2 6 6 2.</_> + <_>7 8 6 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0810220018029213</threshold> + <left_val>-0.9043909907341003</left_val> + <right_val>-8.5880002006888390e-003</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 5 6 9 -1.</_> + <_>18 8 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0212580002844334</threshold> + <left_val>-0.2131959944963455</left_val> + <right_val>0.2191970050334930</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 8 10 -1.</_> + <_>4 3 4 5 2.</_> + <_>8 8 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0106309996917844</threshold> + <left_val>0.1959809958934784</left_val> + <right_val>-0.3576810061931610</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 21 18 3 -1.</_> + <_>6 22 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.1300002057105303e-004</threshold> + <left_val>-0.0927949994802475</left_val> + <right_val>0.2614589929580689</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 18 2 -1.</_> + <_>1 11 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.4650000743567944e-003</threshold> + <left_val>-0.5533609986305237</left_val> + <right_val>0.0273860003799200</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 22 3 -1.</_> + <_>1 11 22 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0188359990715981</threshold> + <left_val>0.1844609975814819</left_val> + <right_val>-0.6693429946899414</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 8 12 9 -1.</_> + <_>2 11 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0256319995969534</threshold> + <left_val>1.9382879734039307</left_val> + <right_val>-0.1470890045166016</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 8 12 6 -1.</_> + <_>18 8 6 3 2.</_> + <_>12 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.0939999744296074e-003</threshold> + <left_val>-0.2645159959793091</left_val> + <right_val>0.2073320001363754</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 12 6 -1.</_> + <_>0 8 6 3 2.</_> + <_>6 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.9199998183175921e-004</threshold> + <left_val>-0.5503159761428833</left_val> + <right_val>0.0503749996423721</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 15 6 9 -1.</_> + <_>12 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0495180003345013</threshold> + <left_val>-2.5615389347076416</left_val> + <right_val>0.1314170062541962</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 13 9 6 -1.</_> + <_>7 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0116809997707605</threshold> + <left_val>-0.2481980025768280</left_val> + <right_val>0.3998270034790039</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 7 12 -1.</_> + <_>9 14 7 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0345639996230602</threshold> + <left_val>0.1617880016565323</left_val> + <right_val>-0.7141889929771423</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 9 6 -1.</_> + <_>7 13 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.2909995689988136e-003</threshold> + <left_val>0.2218009978532791</left_val> + <right_val>-0.2918170094490051</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 15 18 4 -1.</_> + <_>12 15 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0223580002784729</threshold> + <left_val>0.3104409873485565</left_val> + <right_val>-2.7280000504106283e-003</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 4 16 -1.</_> + <_>7 4 2 16 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0308010000735521</threshold> + <left_val>-0.9567270278930664</left_val> + <right_val>-8.3400001749396324e-003</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 15 6 9 -1.</_> + <_>12 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0437790006399155</threshold> + <left_val>0.1255690008401871</left_val> + <right_val>-1.1759619712829590</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 15 6 9 -1.</_> + <_>10 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0430460013449192</threshold> + <left_val>-0.0588769987225533</left_val> + <right_val>-1.8568470478057861</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 11 12 10 -1.</_> + <_>15 11 6 5 2.</_> + <_>9 16 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0271889995783567</threshold> + <left_val>0.0428580008447170</left_val> + <right_val>0.3903670012950897</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 14 6 -1.</_> + <_>3 8 14 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.4149997457861900e-003</threshold> + <left_val>-0.0435670018196106</left_val> + <right_val>-1.1094470024108887</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 2 17 8 -1.</_> + <_>4 6 17 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0943119972944260</threshold> + <left_val>0.0402569994330406</left_val> + <right_val>0.9844229817390442</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 2 12 21 -1.</_> + <_>6 9 12 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1702509969472885</threshold> + <left_val>0.0295100007206202</left_val> + <right_val>-0.6950929760932922</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 9 9 -1.</_> + <_>8 4 9 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0471480004489422</threshold> + <left_val>1.0338569879531860</left_val> + <right_val>0.0676020011305809</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 24 3 -1.</_> + <_>12 7 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1118630021810532</threshold> + <left_val>-0.0686829984188080</left_val> + <right_val>-2.4985830783843994</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 9 10 -1.</_> + <_>11 11 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0143539998680353</threshold> + <left_val>-0.5948190093040466</left_val> + <right_val>0.1500169932842255</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 18 3 -1.</_> + <_>2 12 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0340240001678467</threshold> + <left_val>-0.0648230016231537</left_val> + <right_val>-2.1382639408111572</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 16 9 4 -1.</_> + <_>8 18 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0216019991785288</threshold> + <left_val>0.0553099997341633</left_val> + <right_val>0.7829290032386780</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 9 6 -1.</_> + <_>0 2 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0217719990760088</threshold> + <left_val>-7.1279997937381268e-003</left_val> + <right_val>-0.7214810252189636</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 24 6 -1.</_> + <_>0 13 24 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0824169963598251</threshold> + <left_val>0.1460949927568436</left_val> + <right_val>-1.3636670112609863</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 9 20 6 -1.</_> + <_>2 12 20 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0846719965338707</threshold> + <left_val>-0.1778469979763031</left_val> + <right_val>0.7285770177841187</right_val></_></_> + <_> + <!-- tree 137 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 5 16 12 -1.</_> + <_>12 5 8 6 2.</_> + <_>4 11 8 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0551280006766319</threshold> + <left_val>-0.5940240025520325</left_val> + <right_val>0.1935780048370361</right_val></_></_> + <_> + <!-- tree 138 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 15 -1.</_> + <_>10 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0648230016231537</threshold> + <left_val>-1.0783840417861938</left_val> + <right_val>-0.0407340005040169</right_val></_></_> + <_> + <!-- tree 139 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 3 10 4 -1.</_> + <_>7 5 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0227690003812313</threshold> + <left_val>0.7790020108222961</left_val> + <right_val>3.4960000775754452e-003</right_val></_></_> + <_> + <!-- tree 140 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 15 6 8 -1.</_> + <_>9 19 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0547560006380081</threshold> + <left_val>-0.0656839981675148</left_val> + <right_val>-1.8188409805297852</right_val></_></_> + <_> + <!-- tree 141 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 0 7 10 -1.</_> + <_>17 5 7 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.9000001025851816e-005</threshold> + <left_val>-0.0178919993340969</left_val> + <right_val>0.2076829969882965</right_val></_></_> + <_> + <!-- tree 142 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 7 10 -1.</_> + <_>0 5 7 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0983619987964630</threshold> + <left_val>-0.0559469982981682</left_val> + <right_val>-1.4153920412063599</right_val></_></_> + <_> + <!-- tree 143 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 1 6 12 -1.</_> + <_>19 1 3 6 2.</_> + <_>16 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.0930002257227898e-003</threshold> + <left_val>0.3413529992103577</left_val> + <right_val>-0.1208989992737770</right_val></_></_> + <_> + <!-- tree 144 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 19 8 -1.</_> + <_>1 4 19 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0502780005335808</threshold> + <left_val>-0.2628670036792755</left_val> + <right_val>0.2579729855060577</right_val></_></_> + <_> + <!-- tree 145 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 2 9 4 -1.</_> + <_>12 4 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.7870000600814819e-003</threshold> + <left_val>-0.1317860037088394</left_val> + <right_val>0.1735019981861115</right_val></_></_> + <_> + <!-- tree 146 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 9 4 -1.</_> + <_>3 4 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0139739997684956</threshold> + <left_val>0.0285180006176233</left_val> + <right_val>-0.6115220189094544</right_val></_></_> + <_> + <!-- tree 147 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 2 10 6 -1.</_> + <_>12 4 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0214499998837709</threshold> + <left_val>0.0261819995939732</left_val> + <right_val>0.3030659854412079</right_val></_></_> + <_> + <!-- tree 148 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 18 2 -1.</_> + <_>12 4 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0292140003293753</threshold> + <left_val>0.4494059979915619</left_val> + <right_val>-0.2280309945344925</right_val></_></_> + <_> + <!-- tree 149 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 4 9 -1.</_> + <_>12 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.8099999548867345e-004</threshold> + <left_val>-0.1987999975681305</left_val> + <right_val>0.2074449956417084</right_val></_></_> + <_> + <!-- tree 150 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 4 9 -1.</_> + <_>10 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.7109999898821115e-003</threshold> + <left_val>-0.5403720140457153</left_val> + <right_val>0.0678659975528717</right_val></_></_> + <_> + <!-- tree 151 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 8 10 -1.</_> + <_>14 5 4 5 2.</_> + <_>10 10 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.6660003289580345e-003</threshold> + <left_val>-0.0131280003115535</left_val> + <right_val>0.5229790210723877</right_val></_></_> + <_> + <!-- tree 152 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 13 -1.</_> + <_>10 4 4 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0636579990386963</threshold> + <left_val>0.0682990029454231</left_val> + <right_val>-0.4923509955406189</right_val></_></_> + <_> + <!-- tree 153 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 5 6 6 -1.</_> + <_>13 5 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0279680006206036</threshold> + <left_val>0.6818389892578125</left_val> + <right_val>0.0787810012698174</right_val></_></_> + <_> + <!-- tree 154 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 12 3 -1.</_> + <_>7 5 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0489539988338947</threshold> + <left_val>-0.2062239944934845</left_val> + <right_val>0.5038809776306152</right_val></_></_></trees> + <stage_threshold>-3.3933560848236084</stage_threshold> + <parent>16</parent> + <next>-1</next></_> + <_> + <!-- stage 18 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 10 6 -1.</_> + <_>7 7 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0293129999190569</threshold> + <left_val>0.7128469944000244</left_val> + <right_val>-0.5823069810867310</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 21 5 -1.</_> + <_>9 0 7 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1241509988903999</threshold> + <left_val>-0.3686349987983704</left_val> + <right_val>0.6006720066070557</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 9 9 -1.</_> + <_>0 11 9 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.9349996522068977e-003</threshold> + <left_val>-0.8600829839706421</left_val> + <right_val>0.2172469943761826</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0303659997880459</threshold> + <left_val>-0.2718699872493744</left_val> + <right_val>0.6124789714813232</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 7 -1.</_> + <_>3 3 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0252180006355047</threshold> + <left_val>-0.3474830090999603</left_val> + <right_val>0.5042769908905029</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 18 12 6 -1.</_> + <_>15 18 6 3 2.</_> + <_>9 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0100140003487468</threshold> + <left_val>-0.3189899921417236</left_val> + <right_val>0.4137679934501648</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 8 20 6 -1.</_> + <_>2 8 10 3 2.</_> + <_>12 11 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0167750008404255</threshold> + <left_val>-0.6904810070991516</left_val> + <right_val>0.0948309972882271</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 2 10 4 -1.</_> + <_>13 4 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.6950000319629908e-003</threshold> + <left_val>-0.2082979977130890</left_val> + <right_val>0.2373719960451126</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 5 5 18 -1.</_> + <_>4 11 5 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0422579981386662</threshold> + <left_val>-0.4936670064926148</left_val> + <right_val>0.1817059963941574</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 4 4 9 -1.</_> + <_>20 4 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0485050007700920</threshold> + <left_val>1.3429640531539917</left_val> + <right_val>0.0397690013051033</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 8 14 -1.</_> + <_>8 13 8 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0289929993450642</threshold> + <left_val>0.0464960001409054</left_val> + <right_val>-0.8164349794387817</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 6 -1.</_> + <_>12 1 12 3 2.</_> + <_>0 4 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0400890000164509</threshold> + <left_val>-0.7119780182838440</left_val> + <right_val>0.2255389988422394</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 4 9 -1.</_> + <_>2 4 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0410219989717007</threshold> + <left_val>1.0057929754257202</left_val> + <right_val>-0.1969020068645477</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 3 -1.</_> + <_>3 7 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0118380002677441</threshold> + <left_val>-0.0126000000163913</left_val> + <right_val>0.8076710104942322</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 17 16 6 -1.</_> + <_>3 19 16 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0213280003517866</threshold> + <left_val>-0.8202390074729919</left_val> + <right_val>0.0205249991267920</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 6 6 9 -1.</_> + <_>13 9 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0239049997180700</threshold> + <left_val>0.5421050190925598</left_val> + <right_val>-0.0747670009732246</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 6 -1.</_> + <_>5 6 7 3 2.</_> + <_>12 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0180089995265007</threshold> + <left_val>-0.3382770121097565</left_val> + <right_val>0.4235860109329224</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 5 8 10 -1.</_> + <_>17 5 4 5 2.</_> + <_>13 10 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0436140000820160</threshold> + <left_val>-1.1983489990234375</left_val> + <right_val>0.1556620001792908</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 20 3 -1.</_> + <_>2 3 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.2449998483061790e-003</threshold> + <left_val>-0.8902999758720398</left_val> + <right_val>0.0110039999708533</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 2 9 6 -1.</_> + <_>12 2 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0474850013852119</threshold> + <left_val>0.1666409969329834</left_val> + <right_val>-0.9076449871063232</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 6 9 -1.</_> + <_>10 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0142339998856187</threshold> + <left_val>0.6269519925117493</left_val> + <right_val>-0.2579120099544525</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 3 4 11 -1.</_> + <_>12 3 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.8010000716894865e-003</threshold> + <left_val>-0.2822999954223633</left_val> + <right_val>0.2662459909915924</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 3 4 11 -1.</_> + <_>10 3 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.4330000635236502e-003</threshold> + <left_val>-0.6377199888229370</left_val> + <right_val>0.0984229966998100</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 3 8 10 -1.</_> + <_>12 3 4 5 2.</_> + <_>8 8 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0292210001498461</threshold> + <left_val>-0.7676990032196045</left_val> + <right_val>0.2263450026512146</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 2 18 -1.</_> + <_>12 1 1 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.4949998632073402e-003</threshold> + <left_val>0.4560010135173798</left_val> + <right_val>-0.2652890086174011</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 2 9 6 -1.</_> + <_>12 2 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0300340000540018</threshold> + <left_val>-0.7655109763145447</left_val> + <right_val>0.1400929987430573</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 19 3 -1.</_> + <_>0 3 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.8360000625252724e-003</threshold> + <left_val>0.0467559993267059</left_val> + <right_val>-0.7235620021820068</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 14 9 6 -1.</_> + <_>9 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.8550001382827759e-003</threshold> + <left_val>-0.0491419993340969</left_val> + <right_val>0.5147269964218140</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 8 18 5 -1.</_> + <_>7 8 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0959739983081818</threshold> + <left_val>-0.0200689993798733</left_val> + <right_val>-1.0850950479507446</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 6 9 -1.</_> + <_>14 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0328769981861115</threshold> + <left_val>-0.9587529897689819</left_val> + <right_val>0.1454360038042069</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 6 9 -1.</_> + <_>8 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0133840003982186</threshold> + <left_val>-0.7001360058784485</left_val> + <right_val>0.0291579999029636</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 6 4 15 -1.</_> + <_>13 11 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0152359995990992</threshold> + <left_val>-0.2823570072650909</left_val> + <right_val>0.2536799907684326</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 18 3 -1.</_> + <_>1 6 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0120540000498295</threshold> + <left_val>-0.2530339956283569</left_val> + <right_val>0.4652670025825501</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 7 14 6 -1.</_> + <_>9 9 14 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0762950032949448</threshold> + <left_val>-0.6991580128669739</left_val> + <right_val>0.1321720033884049</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 16 18 3 -1.</_> + <_>2 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0120400004088879</threshold> + <left_val>0.4589459896087647</left_val> + <right_val>-0.2385649979114533</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 6 -1.</_> + <_>15 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0219160001724958</threshold> + <left_val>0.1826860010623932</left_val> + <right_val>-0.6162970066070557</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 12 6 -1.</_> + <_>0 8 6 3 2.</_> + <_>6 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.7330000884830952e-003</threshold> + <left_val>-0.6325790286064148</left_val> + <right_val>0.0342190004885197</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 13 7 8 -1.</_> + <_>9 17 7 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0486520007252693</threshold> + <left_val>-1.0297729969024658</left_val> + <right_val>0.1738650053739548</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 17 20 3 -1.</_> + <_>2 18 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0104639995843172</threshold> + <left_val>0.3475730121135712</left_val> + <right_val>-0.2746410071849823</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 6 -1.</_> + <_>15 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.6550001502037048e-003</threshold> + <left_val>-0.2898029983043671</left_val> + <right_val>0.2403790056705475</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 15 4 -1.</_> + <_>4 2 15 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.5469996556639671e-003</threshold> + <left_val>-0.4434050023555756</left_val> + <right_val>0.1426739990711212</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 2 6 6 -1.</_> + <_>17 5 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0199139993637800</threshold> + <left_val>0.1774040013551712</left_val> + <right_val>-0.2409629970788956</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 9 -1.</_> + <_>0 6 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0220129992812872</threshold> + <left_val>-0.0108120003715158</left_val> + <right_val>-0.9469079971313477</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 6 -1.</_> + <_>15 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0521790012717247</threshold> + <left_val>1.6547499895095825</left_val> + <right_val>0.0964870005846024</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 9 6 -1.</_> + <_>0 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0196989998221397</threshold> + <left_val>-6.7560002207756042e-003</left_val> + <right_val>-0.8631150126457214</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 18 12 6 -1.</_> + <_>15 18 6 3 2.</_> + <_>9 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0230400003492832</threshold> + <left_val>-2.3519999813288450e-003</left_val> + <right_val>0.3853130042552948</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 15 6 9 -1.</_> + <_>3 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0150380004197359</threshold> + <left_val>-0.6190569996833801</left_val> + <right_val>0.0310779996216297</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 13 8 10 -1.</_> + <_>20 13 4 5 2.</_> + <_>16 18 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0499560013413429</threshold> + <left_val>0.7065749764442444</left_val> + <right_val>0.0478809997439384</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 24 4 -1.</_> + <_>8 14 8 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0692699998617172</threshold> + <left_val>0.3921290040016174</left_val> + <right_val>-0.2384800016880035</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 18 6 6 -1.</_> + <_>13 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.7399997711181641e-003</threshold> + <left_val>-0.0243090000003576</left_val> + <right_val>0.2538630068302155</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 8 10 -1.</_> + <_>0 13 4 5 2.</_> + <_>4 18 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0339239984750748</threshold> + <left_val>0.4693039953708649</left_val> + <right_val>-0.2332189977169037</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 24 6 -1.</_> + <_>0 17 24 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0162310004234314</threshold> + <left_val>0.3231920003890991</left_val> + <right_val>-0.2054560035467148</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 12 8 -1.</_> + <_>5 2 6 4 2.</_> + <_>11 6 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0501930005848408</threshold> + <left_val>-1.2277870178222656</left_val> + <right_val>-0.0407980009913445</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 9 9 6 -1.</_> + <_>11 9 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0569440014660358</threshold> + <left_val>0.0451840013265610</left_val> + <right_val>0.6019750237464905</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 16 4 -1.</_> + <_>4 5 16 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0409369990229607</threshold> + <left_val>-0.1677280068397522</left_val> + <right_val>0.8981930017471314</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 10 -1.</_> + <_>10 7 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.0839999672025442e-003</threshold> + <left_val>0.3371619880199432</left_val> + <right_val>-0.2724080085754395</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 4 5 8 -1.</_> + <_>8 8 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0326000005006790</threshold> + <left_val>-0.8544650077819824</left_val> + <right_val>0.0196649990975857</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 5 9 12 -1.</_> + <_>11 9 9 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0984809994697571</threshold> + <left_val>0.0547420009970665</left_val> + <right_val>0.6382730007171631</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 5 9 12 -1.</_> + <_>4 9 9 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0381850004196167</threshold> + <left_val>0.5227469801902771</left_val> + <right_val>-0.2338480055332184</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 6 6 9 -1.</_> + <_>14 9 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0459170006215572</threshold> + <left_val>0.6282920241355896</left_val> + <right_val>0.0328590013086796</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 4 20 12 -1.</_> + <_>2 8 20 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1195549964904785</threshold> + <left_val>-0.6157270073890686</left_val> + <right_val>0.0346800014376640</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 17 16 -1.</_> + <_>4 12 17 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1204439997673035</threshold> + <left_val>-0.8438000082969666</left_val> + <right_val>0.1653070002794266</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 7 6 -1.</_> + <_>8 10 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0706190019845963</threshold> + <left_val>-0.0632610023021698</left_val> + <right_val>-1.9863929748535156</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 9 23 2 -1.</_> + <_>1 10 23 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.4889996796846390e-003</threshold> + <left_val>-0.1766339987516403</left_val> + <right_val>0.3801119923591614</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0227109994739294</threshold> + <left_val>-0.0276059992611408</left_val> + <right_val>-0.9192140102386475</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 3 4 9 -1.</_> + <_>13 3 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.9700000090524554e-004</threshold> + <left_val>-0.2429320067167282</left_val> + <right_val>0.2287890017032623</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 6 13 -1.</_> + <_>10 1 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0346519984304905</threshold> + <left_val>-0.2370599955320358</left_val> + <right_val>0.5401099920272827</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 22 18 2 -1.</_> + <_>4 23 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.4700000435113907e-003</threshold> + <left_val>0.3907899856567383</left_val> + <right_val>-0.1269380003213882</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 9 6 -1.</_> + <_>6 10 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0236430000513792</threshold> + <left_val>-0.2666369974613190</left_val> + <right_val>0.3231259882450104</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 2 24 -1.</_> + <_>14 0 1 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0128130000084639</threshold> + <left_val>0.1754080057144165</left_val> + <right_val>-0.6078799962997437</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 2 24 -1.</_> + <_>9 0 1 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0112509997561574</threshold> + <left_val>-1.0852589607238770</left_val> + <right_val>-0.0280460007488728</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 18 10 -1.</_> + <_>9 2 6 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0415350012481213</threshold> + <left_val>0.7188739776611328</left_val> + <right_val>0.0279820002615452</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 15 6 -1.</_> + <_>9 13 5 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0934709981083870</threshold> + <left_val>-1.1906319856643677</left_val> + <right_val>-0.0448109991848469</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 18 3 -1.</_> + <_>9 21 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0272499993443489</threshold> + <left_val>0.6294249892234802</left_val> + <right_val>9.5039997249841690e-003</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 4 11 -1.</_> + <_>11 1 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0217599999159575</threshold> + <left_val>1.3233649730682373</left_val> + <right_val>-0.1502700001001358</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 7 10 4 -1.</_> + <_>9 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.6890004351735115e-003</threshold> + <left_val>-0.3394710123538971</left_val> + <right_val>0.1708579957485199</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 10 18 -1.</_> + <_>12 0 5 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0693959966301918</threshold> + <left_val>-0.2565779983997345</left_val> + <right_val>0.4765209853649139</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 6 16 -1.</_> + <_>14 1 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0312089994549751</threshold> + <left_val>0.1415400058031082</left_val> + <right_val>-0.3494200110435486</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 6 16 -1.</_> + <_>8 1 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0497270002961159</threshold> + <left_val>-1.1675560474395752</left_val> + <right_val>-0.0407579988241196</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 6 -1.</_> + <_>18 5 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0203019995242357</threshold> + <left_val>-0.3948639929294586</left_val> + <right_val>0.1581490039825440</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 18 2 -1.</_> + <_>3 6 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0153670003637671</threshold> + <left_val>0.4930000007152557</left_val> + <right_val>-0.2009209990501404</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 6 -1.</_> + <_>18 5 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0507350005209446</threshold> + <left_val>1.8736059665679932</left_val> + <right_val>0.0867300033569336</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 6 -1.</_> + <_>0 5 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0207260008901358</threshold> + <left_val>-0.8893839716911316</left_val> + <right_val>-7.3199998587369919e-003</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 11 6 -1.</_> + <_>13 13 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0309939999133348</threshold> + <left_val>-1.1664899587631226</left_val> + <right_val>0.1427460014820099</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 10 4 -1.</_> + <_>10 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.4269999489188194e-003</threshold> + <left_val>-0.6681510210037231</left_val> + <right_val>4.4120000675320625e-003</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 9 10 7 -1.</_> + <_>11 9 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0457439981400967</threshold> + <left_val>-0.4795520007610321</left_val> + <right_val>0.1512199938297272</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 10 7 -1.</_> + <_>8 9 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0166989993304014</threshold> + <left_val>0.1204859986901283</left_val> + <right_val>-0.4523589909076691</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 4 6 6 -1.</_> + <_>16 4 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.2210000790655613e-003</threshold> + <left_val>-0.0776150003075600</left_val> + <right_val>0.2784659862518311</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 10 8 -1.</_> + <_>5 6 5 4 2.</_> + <_>10 10 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0244340002536774</threshold> + <left_val>-0.1998710036277771</left_val> + <right_val>0.6725370287895203</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 21 16 3 -1.</_> + <_>7 21 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0796779990196228</threshold> + <left_val>0.9222239851951599</left_val> + <right_val>0.0925579965114594</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 21 16 3 -1.</_> + <_>9 21 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0445300005376339</threshold> + <left_val>-0.2669050097465515</left_val> + <right_val>0.3332050144672394</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 22 14 -1.</_> + <_>13 5 11 7 2.</_> + <_>2 12 11 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1252830028533936</threshold> + <left_val>-0.5425310134887695</left_val> + <right_val>0.1397629976272583</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 8 10 -1.</_> + <_>3 10 4 5 2.</_> + <_>7 15 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0179719999432564</threshold> + <left_val>0.0182199999690056</left_val> + <right_val>-0.6804850101470947</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 0 6 12 -1.</_> + <_>20 0 3 6 2.</_> + <_>17 6 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0191840007901192</threshold> + <left_val>-0.0125839998945594</left_val> + <right_val>0.5412669777870178</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 6 18 -1.</_> + <_>7 2 2 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0400240011513233</threshold> + <left_val>-0.1763879954814911</left_val> + <right_val>0.7881039977073669</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 6 9 -1.</_> + <_>15 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0135589996352792</threshold> + <left_val>0.2073760032653809</left_val> + <right_val>-0.4774430096149445</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 7 9 -1.</_> + <_>0 15 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0162209998816252</threshold> + <left_val>0.0230769999325275</left_val> + <right_val>-0.6118209958076477</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 13 8 10 -1.</_> + <_>19 13 4 5 2.</_> + <_>15 18 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0112290000542998</threshold> + <left_val>-0.0177280008792877</left_val> + <right_val>0.4176419973373413</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 6 12 -1.</_> + <_>1 0 3 6 2.</_> + <_>4 6 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0391930006444454</threshold> + <left_val>-0.1894849985837936</left_val> + <right_val>0.7401930093765259</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 3 12 -1.</_> + <_>12 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.5539996400475502e-003</threshold> + <left_val>0.4094710052013397</left_val> + <right_val>-0.1350889950990677</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 8 10 -1.</_> + <_>1 13 4 5 2.</_> + <_>5 18 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0278789997100830</threshold> + <left_val>-0.2035070061683655</left_val> + <right_val>0.6162539720535278</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 19 2 -1.</_> + <_>3 22 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0236009992659092</threshold> + <left_val>-1.6967060565948486</left_val> + <right_val>0.1463319957256317</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 4 13 -1.</_> + <_>8 3 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0269300006330013</threshold> + <left_val>-0.0304019991308451</left_val> + <right_val>-1.0909470319747925</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 18 3 -1.</_> + <_>5 11 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.8999999631196260e-004</threshold> + <left_val>-0.2007600069046021</left_val> + <right_val>0.2231409996747971</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 3 5 12 -1.</_> + <_>9 7 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0411249995231628</threshold> + <left_val>-0.4524219930171967</left_val> + <right_val>0.0573920011520386</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 2 4 15 -1.</_> + <_>11 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.6789998672902584e-003</threshold> + <left_val>0.2382490038871765</left_val> + <right_val>-0.2126210033893585</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 16 4 -1.</_> + <_>4 3 16 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0478649996221066</threshold> + <left_val>-0.1819480061531067</left_val> + <right_val>0.6191840171813965</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 18 3 -1.</_> + <_>6 1 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.1679999083280563e-003</threshold> + <left_val>-0.2739320099353790</left_val> + <right_val>0.2501730024814606</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 1 10 8 -1.</_> + <_>5 1 5 4 2.</_> + <_>10 5 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.6230002343654633e-003</threshold> + <left_val>-0.4628030061721802</left_val> + <right_val>0.0423979982733727</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 18 12 6 -1.</_> + <_>17 18 6 3 2.</_> + <_>11 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.4350000359117985e-003</threshold> + <left_val>0.4179680049419403</left_val> + <right_val>-1.7079999670386314e-003</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 15 12 3 -1.</_> + <_>11 15 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.8769999733194709e-003</threshold> + <left_val>0.1460230052471161</left_val> + <right_val>-0.3372110128402710</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 22 4 -1.</_> + <_>1 10 11 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0862260013818741</threshold> + <left_val>0.7514340281486511</left_val> + <right_val>0.0107119996100664</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 9 9 6 -1.</_> + <_>10 9 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0468339994549751</threshold> + <left_val>-0.1911959946155548</left_val> + <right_val>0.4841490089893341</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 12 5 -1.</_> + <_>10 11 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.2000002041459084e-005</threshold> + <left_val>0.3522039949893951</left_val> + <right_val>-0.1733330041170120</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 10 7 -1.</_> + <_>11 7 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0163439996540546</threshold> + <left_val>-0.6439769864082336</left_val> + <right_val>9.0680001303553581e-003</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 2 8 10 -1.</_> + <_>11 2 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0457039996981621</threshold> + <left_val>0.0182160008698702</left_val> + <right_val>0.3197079896926880</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 8 10 -1.</_> + <_>9 2 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0273829996585846</threshold> + <left_val>1.0564049482345581</left_val> + <right_val>-0.1727640032768250</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 18 6 -1.</_> + <_>15 4 9 3 2.</_> + <_>6 7 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0276020001620054</threshold> + <left_val>0.2971549928188324</left_val> + <right_val>-9.4600003212690353e-003</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 10 9 -1.</_> + <_>0 8 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.6939999125897884e-003</threshold> + <left_val>-0.2166029959917069</left_val> + <right_val>0.4738520085811615</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 21 6 -1.</_> + <_>2 9 21 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.0500001311302185e-004</threshold> + <left_val>0.2404879927635193</left_val> + <right_val>-0.2677600085735321</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 22 16 -1.</_> + <_>0 4 11 8 2.</_> + <_>11 12 11 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1105419993400574</threshold> + <left_val>-0.0335390008985996</left_val> + <right_val>-1.0233880281448364</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 22 -1.</_> + <_>9 11 6 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0687659978866577</threshold> + <left_val>-4.3239998631179333e-003</left_val> + <right_val>0.5715339779853821</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 3 12 -1.</_> + <_>9 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.7999999690800905e-003</threshold> + <left_val>0.0775749981403351</left_val> + <right_val>-0.4209269881248474</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 12 18 -1.</_> + <_>18 0 6 9 2.</_> + <_>12 9 6 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1923200041055679</threshold> + <left_val>0.0820219963788986</left_val> + <right_val>2.8810169696807861</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 12 18 -1.</_> + <_>0 0 6 9 2.</_> + <_>6 9 6 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1574209928512573</threshold> + <left_val>-0.1370819956064224</left_val> + <right_val>2.0890059471130371</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 22 4 -1.</_> + <_>12 1 11 2 2.</_> + <_>1 3 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0493870005011559</threshold> + <left_val>-1.8610910177230835</left_val> + <right_val>0.1433209925889969</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 18 4 -1.</_> + <_>3 2 18 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0519290007650852</threshold> + <left_val>-0.1873700022697449</left_val> + <right_val>0.5423160195350647</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 22 6 -1.</_> + <_>2 7 22 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0499650016427040</threshold> + <left_val>0.1417530030012131</left_val> + <right_val>-1.5625779628753662</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 6 9 -1.</_> + <_>5 3 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0426330007612705</threshold> + <left_val>1.6059479713439941</left_val> + <right_val>-0.1471289992332459</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 6 9 -1.</_> + <_>12 14 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0375539995729923</threshold> + <left_val>-0.8097490072250366</left_val> + <right_val>0.1325699985027313</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 14 6 9 -1.</_> + <_>10 14 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0371749997138977</threshold> + <left_val>-1.3945020437240601</left_val> + <right_val>-0.0570550002157688</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 18 18 3 -1.</_> + <_>5 19 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0139459995552897</threshold> + <left_val>0.0334270000457764</left_val> + <right_val>0.5747479796409607</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 6 13 -1.</_> + <_>9 0 3 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.4800000614486635e-004</threshold> + <left_val>-0.5532749891281128</left_val> + <right_val>0.0219529997557402</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 4 12 4 -1.</_> + <_>7 4 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0319930016994476</threshold> + <left_val>0.0203409995883703</left_val> + <right_val>0.3745920062065125</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 12 6 -1.</_> + <_>9 2 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.2799999937415123e-003</threshold> + <left_val>0.4442870020866394</left_val> + <right_val>-0.2299969941377640</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 18 3 -1.</_> + <_>4 2 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.8550003021955490e-003</threshold> + <left_val>0.1831579953432083</left_val> + <right_val>-0.4096499979496002</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 6 12 -1.</_> + <_>0 12 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0933569967746735</threshold> + <left_val>-0.0636610016226768</left_val> + <right_val>-1.6929290294647217</right_val></_></_> + <_> + <!-- tree 137 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 15 6 9 -1.</_> + <_>11 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0172099992632866</threshold> + <left_val>0.2015389949083328</left_val> + <right_val>-0.4606109857559204</right_val></_></_> + <_> + <!-- tree 138 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 10 6 13 -1.</_> + <_>11 10 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.4319999441504478e-003</threshold> + <left_val>-0.3200399875640869</left_val> + <right_val>0.1531219929456711</right_val></_></_> + <_> + <!-- tree 139 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 17 18 2 -1.</_> + <_>6 18 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0140549996867776</threshold> + <left_val>0.8688240051269531</left_val> + <right_val>0.0325750000774860</right_val></_></_> + <_> + <!-- tree 140 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 4 6 9 -1.</_> + <_>11 4 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.7180000953376293e-003</threshold> + <left_val>0.6368669867515564</left_val> + <right_val>-0.1842550039291382</right_val></_></_> + <_> + <!-- tree 141 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 6 9 -1.</_> + <_>12 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0280050002038479</threshold> + <left_val>0.1735749989748001</left_val> + <right_val>-0.4788359999656677</right_val></_></_> + <_> + <!-- tree 142 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 10 8 -1.</_> + <_>5 6 5 4 2.</_> + <_>10 10 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0188849996775389</threshold> + <left_val>0.2410160005092621</left_val> + <right_val>-0.2654759883880615</right_val></_></_> + <_> + <!-- tree 143 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 9 5 8 -1.</_> + <_>14 13 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0185850001871586</threshold> + <left_val>0.5423250198364258</left_val> + <right_val>0.0536330007016659</right_val></_></_> + <_> + <!-- tree 144 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 9 5 8 -1.</_> + <_>5 13 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0364370010793209</threshold> + <left_val>2.3908898830413818</left_val> + <right_val>-0.1363469958305359</right_val></_></_> + <_> + <!-- tree 145 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 11 9 6 -1.</_> + <_>14 13 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0324550010263920</threshold> + <left_val>0.1591069996356964</left_val> + <right_val>-0.6758149862289429</right_val></_></_> + <_> + <!-- tree 146 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 23 15 -1.</_> + <_>0 7 23 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0597819983959198</threshold> + <left_val>-2.3479999508708715e-003</left_val> + <right_val>-0.7305369973182678</right_val></_></_> + <_> + <!-- tree 147 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 0 8 12 -1.</_> + <_>16 6 8 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.8209995776414871e-003</threshold> + <left_val>-0.1144409999251366</left_val> + <right_val>0.3057030141353607</right_val></_></_> + <_> + <!-- tree 148 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 15 6 9 -1.</_> + <_>4 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0351639986038208</threshold> + <left_val>-1.0511469841003418</left_val> + <right_val>-0.0331030003726482</right_val></_></_> + <_> + <!-- tree 149 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 9 4 -1.</_> + <_>8 20 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.7429999317973852e-003</threshold> + <left_val>-0.2013539969921112</left_val> + <right_val>0.3275409936904907</right_val></_></_> + <_> + <!-- tree 150 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 18 3 -1.</_> + <_>0 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.1059997901320457e-003</threshold> + <left_val>-0.2138350009918213</left_val> + <right_val>0.4336209893226624</right_val></_></_> + <_> + <!-- tree 151 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 11 6 -1.</_> + <_>13 13 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0889429971575737</threshold> + <left_val>0.1094089969992638</left_val> + <right_val>-4.7609338760375977</right_val></_></_> + <_> + <!-- tree 152 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 11 6 -1.</_> + <_>0 13 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0300549995154142</threshold> + <left_val>-1.7169300317764282</left_val> + <right_val>-0.0609190016984940</right_val></_></_> + <_> + <!-- tree 153 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 24 6 -1.</_> + <_>12 9 12 3 2.</_> + <_>0 12 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0217349994927645</threshold> + <left_val>0.6477890014648438</left_val> + <right_val>-0.0328309983015060</right_val></_></_> + <_> + <!-- tree 154 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 8 8 -1.</_> + <_>6 20 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0376489982008934</threshold> + <left_val>-0.0100600002333522</left_val> + <right_val>-0.7656909823417664</right_val></_></_> + <_> + <!-- tree 155 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 16 14 6 -1.</_> + <_>10 18 14 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.7189999818801880e-003</threshold> + <left_val>0.1988890022039414</left_val> + <right_val>-0.0824790000915527</right_val></_></_> + <_> + <!-- tree 156 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 21 3 -1.</_> + <_>1 2 21 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0105480002239347</threshold> + <left_val>-0.8661360144615173</left_val> + <right_val>-0.0259860008955002</right_val></_></_> + <_> + <!-- tree 157 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 3 -1.</_> + <_>0 2 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1296630054712296</threshold> + <left_val>0.1391199976205826</left_val> + <right_val>-2.2271950244903564</right_val></_></_> + <_> + <!-- tree 158 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 15 8 5 -1.</_> + <_>6 15 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0176769997924566</threshold> + <left_val>0.3396770060062408</left_val> + <right_val>-0.2398959994316101</right_val></_></_> + <_> + <!-- tree 159 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 21 3 -1.</_> + <_>9 11 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0770519971847534</threshold> + <left_val>-2.5017969608306885</left_val> + <right_val>0.1284199953079224</right_val></_></_> + <_> + <!-- tree 160 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 18 12 6 -1.</_> + <_>1 18 6 3 2.</_> + <_>7 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0192300006747246</threshold> + <left_val>0.5064120292663574</left_val> + <right_val>-0.1975159943103790</right_val></_></_> + <_> + <!-- tree 161 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 4 10 -1.</_> + <_>10 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0512229986488819</threshold> + <left_val>-2.9333369731903076</left_val> + <right_val>0.1385850012302399</right_val></_></_> + <_> + <!-- tree 162 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 4 10 -1.</_> + <_>7 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.0830000285059214e-003</threshold> + <left_val>-0.6004359722137451</left_val> + <right_val>0.0297180004417896</right_val></_></_> + <_> + <!-- tree 163 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 6 12 -1.</_> + <_>9 12 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0254180002957582</threshold> + <left_val>0.3391579985618591</left_val> + <right_val>-0.1439200043678284</right_val></_></_> + <_> + <!-- tree 164 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 9 6 -1.</_> + <_>10 1 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0239059999585152</threshold> + <left_val>-1.1082680225372314</left_val> + <right_val>-0.0473770014941692</right_val></_></_> + <_> + <!-- tree 165 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 14 19 2 -1.</_> + <_>3 15 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.3740001060068607e-003</threshold> + <left_val>0.4453369975090027</left_val> + <right_val>-0.0670529976487160</right_val></_></_> + <_> + <!-- tree 166 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 10 10 -1.</_> + <_>7 7 5 5 2.</_> + <_>12 12 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0376989990472794</threshold> + <left_val>-1.0406579971313477</left_val> + <right_val>-0.0417900010943413</right_val></_></_> + <_> + <!-- tree 167 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 12 18 12 -1.</_> + <_>3 12 9 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2165510058403015</threshold> + <left_val>0.0338630005717278</left_val> + <right_val>0.8201730251312256</right_val></_></_> + <_> + <!-- tree 168 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 6 12 -1.</_> + <_>10 0 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0134009998291731</threshold> + <left_val>0.5290349721908569</left_val> + <right_val>-0.1913300007581711</right_val></_></_></trees> + <stage_threshold>-3.2396929264068604</stage_threshold> + <parent>17</parent> + <next>-1</next></_> + <_> + <!-- stage 19 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 17 9 -1.</_> + <_>3 3 17 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0712689980864525</threshold> + <left_val>-0.5363119840621948</left_val> + <right_val>0.6071529984474182</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 12 11 -1.</_> + <_>10 0 4 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0561110004782677</threshold> + <left_val>-0.5014160275459290</left_val> + <right_val>0.4397610127925873</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 6 13 -1.</_> + <_>4 0 3 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0404639989137650</threshold> + <left_val>-0.3292219936847687</left_val> + <right_val>0.5483469963073731</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 16 6 -1.</_> + <_>5 11 16 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0631550028920174</threshold> + <left_val>-0.3170169889926910</left_val> + <right_val>0.4615299999713898</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 5 12 -1.</_> + <_>8 14 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0103209996595979</threshold> + <left_val>0.1069499999284744</left_val> + <right_val>-0.9824389815330505</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 18 3 -1.</_> + <_>9 21 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0626069977879524</threshold> + <left_val>-0.1432970017194748</left_val> + <right_val>0.7109500169754028</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 6 -1.</_> + <_>3 0 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0394160002470016</threshold> + <left_val>0.9438019990921021</left_val> + <right_val>-0.2157209962606430</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 20 3 -1.</_> + <_>2 1 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.3960001096129417e-003</threshold> + <left_val>-0.5461199879646301</left_val> + <right_val>0.2530379891395569</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 15 10 -1.</_> + <_>9 6 5 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1077319979667664</threshold> + <left_val>0.0124960001558065</left_val> + <right_val>-1.0809199810028076</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0169820003211498</threshold> + <left_val>-0.3153640031814575</left_val> + <right_val>0.5123999714851379</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 9 -1.</_> + <_>11 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0312169995158911</threshold> + <left_val>-4.5199999585747719e-003</left_val> + <right_val>-1.2443480491638184</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 6 9 -1.</_> + <_>16 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0231069996953011</threshold> + <left_val>-0.7649289965629578</left_val> + <right_val>0.2064059972763062</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 16 9 6 -1.</_> + <_>7 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0112039996311069</threshold> + <left_val>0.2409269958734512</left_val> + <right_val>-0.3514209985733032</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 6 9 -1.</_> + <_>16 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.7479998320341110e-003</threshold> + <left_val>-0.0970079973340034</left_val> + <right_val>0.2063809931278229</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 6 9 -1.</_> + <_>6 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0173589996993542</threshold> + <left_val>-0.7902029752731323</left_val> + <right_val>0.0218529999256134</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 1 6 16 -1.</_> + <_>19 1 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0188519991934299</threshold> + <left_val>-0.1039460003376007</left_val> + <right_val>0.5484420061111450</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 6 16 -1.</_> + <_>3 1 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.2249998338520527e-003</threshold> + <left_val>-0.4040940105915070</left_val> + <right_val>0.2676379978656769</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 6 9 -1.</_> + <_>14 16 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0189159996807575</threshold> + <left_val>0.2050800025463104</left_val> + <right_val>-1.0206340551376343</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 9 -1.</_> + <_>0 3 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0311569999903440</threshold> + <left_val>1.2400000123307109e-003</left_val> + <right_val>-0.8729349970817566</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 6 6 -1.</_> + <_>9 5 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0209519993513823</threshold> + <left_val>-5.5559999309480190e-003</left_val> + <right_val>0.8035619854927063</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 9 6 -1.</_> + <_>6 10 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0112910000607371</threshold> + <left_val>-0.3647840023040772</left_val> + <right_val>0.2276789993047714</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 7 3 16 -1.</_> + <_>14 15 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0570110008120537</threshold> + <left_val>-1.4295619726181030</left_val> + <right_val>0.1432200074195862</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 10 14 12 -1.</_> + <_>4 10 7 6 2.</_> + <_>11 16 7 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0721940025687218</threshold> + <left_val>-0.0418500006198883</left_val> + <right_val>-1.9111829996109009</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 12 6 -1.</_> + <_>7 8 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0198740009218454</threshold> + <left_val>0.2642549872398377</left_val> + <right_val>-0.3261770009994507</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 2 4 20 -1.</_> + <_>9 2 2 20 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0166929997503757</threshold> + <left_val>-0.8390780091285706</left_val> + <right_val>4.0799999260343611e-004</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 6 9 -1.</_> + <_>14 16 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0398349985480309</threshold> + <left_val>-0.4885849952697754</left_val> + <right_val>0.1643610000610352</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 9 -1.</_> + <_>12 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0270099993795156</threshold> + <left_val>-0.1886249929666519</left_val> + <right_val>0.8341940045356751</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 6 9 -1.</_> + <_>14 16 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.9420002140104771e-003</threshold> + <left_val>0.2323150038719177</left_val> + <right_val>-0.0723600015044212</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 20 14 4 -1.</_> + <_>5 22 14 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0228330008685589</threshold> + <left_val>-0.0358840003609657</left_val> + <right_val>-1.1549400091171265</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 16 12 -1.</_> + <_>4 10 16 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0688880011439323</threshold> + <left_val>-1.7837309837341309</left_val> + <right_val>0.1515900045633316</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0430970005691051</threshold> + <left_val>-0.2160809934139252</left_val> + <right_val>0.5062410235404968</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 21 4 -1.</_> + <_>3 2 21 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.6239995434880257e-003</threshold> + <left_val>-0.1779559999704361</left_val> + <right_val>0.2895790040493012</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 6 9 -1.</_> + <_>4 16 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0145610002800822</threshold> + <left_val>-0.0114080002531409</left_val> + <right_val>-0.8940200209617615</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 16 5 8 -1.</_> + <_>16 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0115010002627969</threshold> + <left_val>0.3017199933528900</left_val> + <right_val>-0.0436590015888214</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 16 16 -1.</_> + <_>4 0 8 8 2.</_> + <_>12 8 8 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1097149997949600</threshold> + <left_val>-0.9514709711074829</left_val> + <right_val>-0.0199730005115271</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 14 6 -1.</_> + <_>13 6 7 3 2.</_> + <_>6 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0452280007302761</threshold> + <left_val>0.0331109985709190</left_val> + <right_val>0.9661980271339417</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 4 15 -1.</_> + <_>10 10 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0270479992032051</threshold> + <left_val>0.9796360135078430</left_val> + <right_val>-0.1726190000772476</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 15 12 8 -1.</_> + <_>15 15 6 4 2.</_> + <_>9 19 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0180309992283583</threshold> + <left_val>-0.0208010002970696</left_val> + <right_val>0.2738589942455292</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 12 4 -1.</_> + <_>12 7 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0505249984562397</threshold> + <left_val>-0.0568029992282391</left_val> + <right_val>-1.7775089740753174</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 6 -1.</_> + <_>12 6 7 3 2.</_> + <_>5 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0299239996820688</threshold> + <left_val>0.6532920002937317</left_val> + <right_val>-0.0235370006412268</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 10 -1.</_> + <_>3 6 9 5 2.</_> + <_>12 11 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0380580015480518</threshold> + <left_val>0.0263170003890991</left_val> + <right_val>-0.7066569924354553</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 18 21 -1.</_> + <_>12 0 6 21 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1856389939785004</threshold> + <left_val>-5.6039998307824135e-003</left_val> + <right_val>0.3287369906902313</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 21 -1.</_> + <_>8 0 8 21 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.0670000016689301e-003</threshold> + <left_val>0.3420479893684387</left_val> + <right_val>-0.3017159998416901</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 18 18 3 -1.</_> + <_>6 19 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0101089999079704</threshold> + <left_val>-7.3600001633167267e-003</left_val> + <right_val>0.5798159837722778</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 9 6 -1.</_> + <_>0 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0115670002996922</threshold> + <left_val>-0.5272219777107239</left_val> + <right_val>0.0464479997754097</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 19 2 -1.</_> + <_>4 4 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.5649999305605888e-003</threshold> + <left_val>-0.5852910280227661</left_val> + <right_val>0.1910189986228943</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 24 2 -1.</_> + <_>0 4 24 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0105820000171661</threshold> + <left_val>0.0210730005055666</left_val> + <right_val>-0.6889259815216065</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 14 9 4 -1.</_> + <_>15 16 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0203040000051260</threshold> + <left_val>-0.3640069961547852</left_val> + <right_val>0.1533879935741425</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 9 4 -1.</_> + <_>0 16 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.3529999889433384e-003</threshold> + <left_val>0.0361640006303787</left_val> + <right_val>-0.5982509851455689</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 15 18 2 -1.</_> + <_>6 16 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.4690000098198652e-003</threshold> + <left_val>-0.1470769941806793</left_val> + <right_val>0.3750799894332886</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 17 18 3 -1.</_> + <_>3 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.6449999362230301e-003</threshold> + <left_val>-0.2170850038528442</left_val> + <right_val>0.5193679928779602</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 3 23 -1.</_> + <_>13 0 1 23 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0243260003626347</threshold> + <left_val>-1.0846769809722900</left_val> + <right_val>0.1408479958772659</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 8 6 -1.</_> + <_>6 3 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0744189992547035</threshold> + <left_val>-0.1551380008459091</left_val> + <right_val>1.1822769641876221</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 18 3 -1.</_> + <_>6 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0170779991894960</threshold> + <left_val>0.0442310012876987</left_val> + <right_val>0.9156110286712647</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 3 23 -1.</_> + <_>10 0 1 23 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0245779994875193</threshold> + <left_val>-1.5504100322723389</left_val> + <right_val>-0.0547459982335567</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 4 10 -1.</_> + <_>10 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0302050001919270</threshold> + <left_val>0.1666280031204224</left_val> + <right_val>-1.0001239776611328</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 10 12 -1.</_> + <_>7 12 10 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0121360002085567</threshold> + <left_val>-0.7707909941673279</left_val> + <right_val>-4.8639997839927673e-003</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 9 6 14 -1.</_> + <_>17 9 3 7 2.</_> + <_>14 16 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0867170020937920</threshold> + <left_val>0.1106169968843460</left_val> + <right_val>-1.6857999563217163</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 10 9 -1.</_> + <_>2 3 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0423090010881424</threshold> + <left_val>1.1075930595397949</left_val> + <right_val>-0.1543859988451004</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 5 12 -1.</_> + <_>11 7 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.6420000940561295e-003</threshold> + <left_val>0.2745189964771271</left_val> + <right_val>-0.1845619976520538</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 4 12 10 -1.</_> + <_>1 4 6 5 2.</_> + <_>7 9 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0566620007157326</threshold> + <left_val>-0.8062559962272644</left_val> + <right_val>-0.0169280003756285</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 1 9 4 -1.</_> + <_>15 3 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0234750006347895</threshold> + <left_val>0.1418769955635071</left_val> + <right_val>-0.2550089955329895</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 8 10 -1.</_> + <_>1 2 4 5 2.</_> + <_>5 7 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0208030007779598</threshold> + <left_val>0.1982630044221878</left_val> + <right_val>-0.3117119967937470</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 1 5 12 -1.</_> + <_>10 5 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.2599998675286770e-003</threshold> + <left_val>-0.0505909994244576</left_val> + <right_val>0.4192380011081696</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 14 24 -1.</_> + <_>11 0 7 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.3416000008583069</threshold> + <left_val>-0.1667490005493164</left_val> + <right_val>0.9274860024452210</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 17 10 4 -1.</_> + <_>7 19 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.2029999680817127e-003</threshold> + <left_val>-0.1262589991092682</left_val> + <right_val>0.4044530093669891</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 4 10 -1.</_> + <_>10 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0326920002698898</threshold> + <left_val>-0.0326349996030331</left_val> + <right_val>-0.9893980026245117</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 15 6 9 -1.</_> + <_>15 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.1100000594742596e-004</threshold> + <left_val>-0.0645340010523796</left_val> + <right_val>0.2547369897365570</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 18 3 -1.</_> + <_>3 22 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.2100001852959394e-004</threshold> + <left_val>-0.3661859929561615</left_val> + <right_val>0.1197310015559197</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 15 6 9 -1.</_> + <_>15 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0544909983873367</threshold> + <left_val>0.1207349970936775</left_val> + <right_val>-1.0291390419006348</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 15 6 9 -1.</_> + <_>7 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0101410001516342</threshold> + <left_val>-0.5217720270156860</left_val> + <right_val>0.0337349995970726</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 18 -1.</_> + <_>12 6 2 9 2.</_> + <_>10 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0188159998506308</threshold> + <left_val>0.6518179774284363</left_val> + <right_val>1.3399999588727951e-003</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 3 6 11 -1.</_> + <_>9 3 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.3480002097785473e-003</threshold> + <left_val>0.1737069934606552</left_val> + <right_val>-0.3413200080394745</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 1 9 4 -1.</_> + <_>15 3 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0108470004051924</threshold> + <left_val>-0.1969989985227585</left_val> + <right_val>0.1504549980163574</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 14 8 -1.</_> + <_>5 8 14 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0499260015785694</threshold> + <left_val>-0.5088850259780884</left_val> + <right_val>0.0307620000094175</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 15 9 -1.</_> + <_>8 4 15 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0121600003913045</threshold> + <left_val>-0.0692519992589951</left_val> + <right_val>0.1874549984931946</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 2 8 10 -1.</_> + <_>7 2 4 5 2.</_> + <_>11 7 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.2189998999238014e-003</threshold> + <left_val>-0.4084909856319428</left_val> + <right_val>0.0799549967050552</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 2 6 12 -1.</_> + <_>12 2 3 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.1580000650137663e-003</threshold> + <left_val>-0.2112459987401962</left_val> + <right_val>0.2236640006303787</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 2 6 12 -1.</_> + <_>9 2 3 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.1439998894929886e-003</threshold> + <left_val>-0.4990029931068420</left_val> + <right_val>0.0629170015454292</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 12 4 -1.</_> + <_>7 7 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.3730000294744968e-003</threshold> + <left_val>-0.2055329978466034</left_val> + <right_val>0.2209669947624207</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 12 10 -1.</_> + <_>10 3 4 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0518120005726814</threshold> + <left_val>0.1809680014848709</left_val> + <right_val>-0.4349580109119415</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 16 6 -1.</_> + <_>13 6 8 3 2.</_> + <_>5 9 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0183400008827448</threshold> + <left_val>0.0152000002563000</left_val> + <right_val>0.3799169957637787</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 18 9 -1.</_> + <_>9 1 6 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1749079972505570</threshold> + <left_val>-0.2092079967260361</left_val> + <right_val>0.4001300036907196</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 8 18 5 -1.</_> + <_>9 8 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0539939999580383</threshold> + <left_val>0.2475160062313080</left_val> + <right_val>-0.2671290040016174</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 22 -1.</_> + <_>0 0 12 11 2.</_> + <_>12 11 12 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.3203319907188416</threshold> + <left_val>-1.9094380140304565</left_val> + <right_val>-0.0669609978795052</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 16 9 6 -1.</_> + <_>14 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0270600002259016</threshold> + <left_val>-0.7137129902839661</left_val> + <right_val>0.1590459942817688</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 24 8 -1.</_> + <_>0 20 24 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0774639993906021</threshold> + <left_val>-0.1697019934654236</left_val> + <right_val>0.7755299806594849</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 19 22 4 -1.</_> + <_>12 19 11 2 2.</_> + <_>1 21 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0237719994038343</threshold> + <left_val>0.1902189999818802</left_val> + <right_val>-0.6016209721565247</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 16 9 6 -1.</_> + <_>1 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0115010002627969</threshold> + <left_val>7.7039999887347221e-003</left_val> + <right_val>-0.6173030138015747</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 10 4 -1.</_> + <_>7 8 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0326160006225109</threshold> + <left_val>0.1715919971466065</left_val> + <right_val>-0.7097820043563843</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 15 6 9 -1.</_> + <_>11 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0443830005824566</threshold> + <left_val>-2.2606229782104492</left_val> + <right_val>-0.0732769966125488</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 18 12 6 -1.</_> + <_>16 18 6 3 2.</_> + <_>10 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0584760010242462</threshold> + <left_val>2.4087750911712646</left_val> + <right_val>0.0830919966101646</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 18 12 6 -1.</_> + <_>2 18 6 3 2.</_> + <_>8 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0193039998412132</threshold> + <left_val>-0.2708230018615723</left_val> + <right_val>0.2736999988555908</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 3 16 9 -1.</_> + <_>8 6 16 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0447059981524944</threshold> + <left_val>0.3135559856891632</left_val> + <right_val>-0.0624920018017292</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 10 6 -1.</_> + <_>0 7 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0603349991142750</threshold> + <left_val>-1.4515119791030884</left_val> + <right_val>-0.0587610006332397</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 18 3 -1.</_> + <_>5 6 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0116670001298189</threshold> + <left_val>-0.0180849991738796</left_val> + <right_val>0.5047969818115234</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 6 9 6 -1.</_> + <_>2 9 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0280099995434284</threshold> + <left_val>-0.2330289930105209</left_val> + <right_val>0.3070870041847229</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 2 10 9 -1.</_> + <_>14 5 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0653970018029213</threshold> + <left_val>0.1413590013980866</left_val> + <right_val>-0.5001090168952942</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 3 -1.</_> + <_>3 7 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.6239997074007988e-003</threshold> + <left_val>-0.2205460071563721</left_val> + <right_val>0.3919120132923126</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 2 15 6 -1.</_> + <_>9 4 15 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.5510000996291637e-003</threshold> + <left_val>-0.1138150021433830</left_val> + <right_val>0.2003230005502701</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 8 15 6 -1.</_> + <_>4 10 15 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0318470001220703</threshold> + <left_val>0.0254769995808601</left_val> + <right_val>-0.5332639813423157</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 24 4 -1.</_> + <_>12 5 12 2 2.</_> + <_>0 7 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0330550000071526</threshold> + <left_val>0.1780769973993301</left_val> + <right_val>-0.6279389858245850</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 6 12 -1.</_> + <_>9 8 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0476009994745255</threshold> + <left_val>-0.1474789977073669</left_val> + <right_val>1.4204180240631104</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 6 9 -1.</_> + <_>13 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0195719990879297</threshold> + <left_val>-0.5269349813461304</left_val> + <right_val>0.1583860069513321</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 6 12 -1.</_> + <_>0 12 3 6 2.</_> + <_>3 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0547300018370152</threshold> + <left_val>0.8823159933090210</left_val> + <right_val>-0.1662780046463013</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 12 10 6 -1.</_> + <_>14 14 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0226860009133816</threshold> + <left_val>-0.4838689863681793</left_val> + <right_val>0.1500010043382645</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 18 9 -1.</_> + <_>2 10 18 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1071320027112961</threshold> + <left_val>-0.2133619934320450</left_val> + <right_val>0.4233390092849731</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 14 10 9 -1.</_> + <_>11 17 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0363800004124641</threshold> + <left_val>-0.0741980001330376</left_val> + <right_val>0.1458940058946610</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 10 8 -1.</_> + <_>7 6 5 4 2.</_> + <_>12 10 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0139359999448061</threshold> + <left_val>-0.2491160035133362</left_val> + <right_val>0.2677119970321655</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 14 6 -1.</_> + <_>13 6 7 3 2.</_> + <_>6 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0209919996559620</threshold> + <left_val>8.7959999218583107e-003</left_val> + <right_val>0.4306499958038330</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 9 7 -1.</_> + <_>7 13 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0491189993917942</threshold> + <left_val>-0.1759199947118759</left_val> + <right_val>0.6928290128707886</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 10 6 12 -1.</_> + <_>17 10 3 6 2.</_> + <_>14 16 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0363159999251366</threshold> + <left_val>0.1314529925584793</left_val> + <right_val>-0.3359729945659638</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 10 6 12 -1.</_> + <_>4 10 3 6 2.</_> + <_>7 16 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0412280000746250</threshold> + <left_val>-0.0456920005381107</left_val> + <right_val>-1.3515930175781250</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 9 8 6 -1.</_> + <_>13 9 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0156720001250505</threshold> + <left_val>0.1754409968852997</left_val> + <right_val>-0.0605500005185604</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 3 4 14 -1.</_> + <_>10 3 2 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0162860006093979</threshold> + <left_val>-1.1308189630508423</left_val> + <right_val>-0.0395330004394054</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 0 3 18 -1.</_> + <_>18 0 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.0229999683797359e-003</threshold> + <left_val>-0.2245430052280426</left_val> + <right_val>0.2362809926271439</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 16 12 -1.</_> + <_>12 12 8 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1378629952669144</threshold> + <left_val>0.4537689983844757</left_val> + <right_val>-0.2109870016574860</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 6 14 -1.</_> + <_>17 0 2 14 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.6760001033544540e-003</threshold> + <left_val>-0.1510509997606278</left_val> + <right_val>0.2078170031309128</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 6 14 -1.</_> + <_>5 0 2 14 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0248399991542101</threshold> + <left_val>-0.6835029721260071</left_val> + <right_val>-8.0040004104375839e-003</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 2 12 20 -1.</_> + <_>16 2 4 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1396439969539642</threshold> + <left_val>0.6501129865646362</left_val> + <right_val>0.0465440005064011</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 12 20 -1.</_> + <_>4 2 4 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0821539983153343</threshold> + <left_val>0.4488719999790192</left_val> + <right_val>-0.2359199970960617</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 0 6 17 -1.</_> + <_>18 0 2 17 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.8449999410659075e-003</threshold> + <left_val>-0.0881730020046234</left_val> + <right_val>0.2734679877758026</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 6 17 -1.</_> + <_>4 0 2 17 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.6579999402165413e-003</threshold> + <left_val>-0.4686659872531891</left_val> + <right_val>0.0770019963383675</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 6 9 6 -1.</_> + <_>15 8 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0158980004489422</threshold> + <left_val>0.2926839888095856</left_val> + <right_val>-0.0219410005956888</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 9 6 -1.</_> + <_>0 8 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0509460009634495</threshold> + <left_val>-1.2093789577484131</left_val> + <right_val>-0.0421099998056889</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 1 6 13 -1.</_> + <_>20 1 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0168379992246628</threshold> + <left_val>-0.0455959998071194</left_val> + <right_val>0.5018069744110107</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 13 -1.</_> + <_>2 1 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0159189999103546</threshold> + <left_val>-0.2690429985523224</left_val> + <right_val>0.2651630043983460</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 0 4 9 -1.</_> + <_>16 0 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.6309999413788319e-003</threshold> + <left_val>-0.1304610073566437</left_val> + <right_val>0.3180710077285767</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 12 7 -1.</_> + <_>9 10 4 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0861449986696243</threshold> + <left_val>1.9443659782409668</left_val> + <right_val>-0.1397829949855804</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 9 12 6 -1.</_> + <_>12 11 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0331409983336926</threshold> + <left_val>0.1526679992675781</left_val> + <right_val>-0.0308660008013248</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 12 6 -1.</_> + <_>0 11 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.9679999463260174e-003</threshold> + <left_val>-0.7120230197906494</left_val> + <right_val>-0.0138440001755953</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 14 9 -1.</_> + <_>5 10 14 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0240080002695322</threshold> + <left_val>0.9200779795646668</left_val> + <right_val>0.0467239990830421</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 20 3 -1.</_> + <_>0 16 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.7320003658533096e-003</threshold> + <left_val>-0.2256730049848557</left_val> + <right_val>0.3193179965019226</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 10 8 10 -1.</_> + <_>12 10 4 5 2.</_> + <_>8 15 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0277869999408722</threshold> + <left_val>-0.7233710289001465</left_val> + <right_val>0.1701859980821610</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 13 9 -1.</_> + <_>5 7 13 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1945530027151108</threshold> + <left_val>1.2461860179901123</left_val> + <right_val>-0.1473619937896729</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 6 18 -1.</_> + <_>10 8 6 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1086969971656799</threshold> + <left_val>-1.4465179443359375</left_val> + <right_val>0.1214530020952225</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 6 9 -1.</_> + <_>8 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0194949992001057</threshold> + <left_val>-0.7815309762954712</left_val> + <right_val>-0.0237329993396997</right_val></_></_> + <_> + <!-- tree 137 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 12 4 -1.</_> + <_>6 11 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.0650000553578138e-003</threshold> + <left_val>-0.8547139763832092</left_val> + <right_val>0.1668699979782105</right_val></_></_> + <_> + <!-- tree 138 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 15 12 -1.</_> + <_>3 6 15 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0591939985752106</threshold> + <left_val>-0.1485369950532913</left_val> + <right_val>1.1273469924926758</right_val></_></_> + <_> + <!-- tree 139 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 12 5 -1.</_> + <_>16 0 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0542079992592335</threshold> + <left_val>0.5472699999809265</left_val> + <right_val>0.0355239994823933</right_val></_></_> + <_> + <!-- tree 140 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 18 3 -1.</_> + <_>6 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0393249988555908</threshold> + <left_val>0.3664259910583496</left_val> + <right_val>-0.2054399996995926</right_val></_></_> + <_> + <!-- tree 141 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 24 5 -1.</_> + <_>8 14 8 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0822789967060089</threshold> + <left_val>-0.0350079983472824</left_val> + <right_val>0.5399420261383057</right_val></_></_> + <_> + <!-- tree 142 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 1 3 18 -1.</_> + <_>6 1 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.4479999020695686e-003</threshold> + <left_val>-0.6153749823570252</left_val> + <right_val>-3.5319998860359192e-003</right_val></_></_> + <_> + <!-- tree 143 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 4 14 -1.</_> + <_>10 0 2 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.3770000599324703e-003</threshold> + <left_val>-0.0655910000205040</left_val> + <right_val>0.4196139872074127</right_val></_></_> + <_> + <!-- tree 144 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 3 4 9 -1.</_> + <_>11 3 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.0779998786747456e-003</threshold> + <left_val>-0.3412950038909912</left_val> + <right_val>0.1253679990768433</right_val></_></_> + <_> + <!-- tree 145 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 12 6 -1.</_> + <_>14 2 6 3 2.</_> + <_>8 5 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0155819999054074</threshold> + <left_val>-0.3024039864540100</left_val> + <right_val>0.2151100039482117</right_val></_></_> + <_> + <!-- tree 146 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 17 4 -1.</_> + <_>0 6 17 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.7399999089539051e-003</threshold> + <left_val>0.0765530019998550</left_val> + <right_val>-0.4106050133705139</right_val></_></_> + <_> + <!-- tree 147 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 16 5 8 -1.</_> + <_>16 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0706000030040741</threshold> + <left_val>-0.9735620021820068</left_val> + <right_val>0.1124180033802986</right_val></_></_> + <_> + <!-- tree 148 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 16 5 8 -1.</_> + <_>3 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0117060001939535</threshold> + <left_val>0.1856070011854172</left_val> + <right_val>-0.2975519895553589</right_val></_></_> + <_> + <!-- tree 149 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 18 18 2 -1.</_> + <_>6 19 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.1499997284263372e-004</threshold> + <left_val>-0.0596500001847744</left_val> + <right_val>0.2482469975948334</right_val></_></_> + <_> + <!-- tree 150 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 12 5 -1.</_> + <_>4 0 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0368660017848015</threshold> + <left_val>0.3275170028209686</left_val> + <right_val>-0.2305960059165955</right_val></_></_> + <_> + <!-- tree 151 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 3 6 12 -1.</_> + <_>17 3 3 6 2.</_> + <_>14 9 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0325269997119904</threshold> + <left_val>-0.2932029962539673</left_val> + <right_val>0.1542769968509674</right_val></_></_> + <_> + <!-- tree 152 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 6 12 -1.</_> + <_>2 12 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0748139992356300</threshold> + <left_val>-1.2143570184707642</left_val> + <right_val>-0.0522440001368523</right_val></_></_> + <_> + <!-- tree 153 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 3 21 3 -1.</_> + <_>2 4 21 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0414699986577034</threshold> + <left_val>0.1306249946355820</left_val> + <right_val>-2.3274369239807129</right_val></_></_> + <_> + <!-- tree 154 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 6 12 -1.</_> + <_>4 3 3 6 2.</_> + <_>7 9 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0288800001144409</threshold> + <left_val>-0.6607459783554077</left_val> + <right_val>-9.0960003435611725e-003</right_val></_></_> + <_> + <!-- tree 155 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 8 12 6 -1.</_> + <_>18 8 6 3 2.</_> + <_>12 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0463819988071918</threshold> + <left_val>0.1663019955158234</left_val> + <right_val>-0.6694949865341187</right_val></_></_> + <_> + <!-- tree 156 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 16 9 -1.</_> + <_>8 15 8 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2542499899864197</threshold> + <left_val>-0.0546419993042946</left_val> + <right_val>-1.2676080465316772</right_val></_></_> + <_> + <!-- tree 157 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 13 18 5 -1.</_> + <_>6 13 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.4000001139938831e-003</threshold> + <left_val>0.2027679979801178</left_val> + <right_val>0.0146679999306798</right_val></_></_> + <_> + <!-- tree 158 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 6 15 6 -1.</_> + <_>6 6 5 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0828059986233711</threshold> + <left_val>-0.7871360182762146</left_val> + <right_val>-0.0244689993560314</right_val></_></_> + <_> + <!-- tree 159 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 9 9 6 -1.</_> + <_>14 9 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0114380000159144</threshold> + <left_val>0.2862339913845062</left_val> + <right_val>-0.0308940000832081</right_val></_></_> + <_> + <!-- tree 160 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 15 11 -1.</_> + <_>8 0 5 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1291339993476868</threshold> + <left_val>1.7292929887771606</left_val> + <right_val>-0.1429390013217926</right_val></_></_> + <_> + <!-- tree 161 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 3 3 18 -1.</_> + <_>15 9 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0385529994964600</threshold> + <left_val>0.0192329995334148</left_val> + <right_val>0.3773260116577148</right_val></_></_> + <_> + <!-- tree 162 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 3 18 -1.</_> + <_>6 9 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1019140034914017</threshold> + <left_val>-0.0745339989662170</left_val> + <right_val>-3.3868899345397949</right_val></_></_> + <_> + <!-- tree 163 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 10 8 -1.</_> + <_>14 5 5 4 2.</_> + <_>9 9 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0190680008381605</threshold> + <left_val>0.3181410133838654</left_val> + <right_val>0.0192610006779432</right_val></_></_> + <_> + <!-- tree 164 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 16 8 -1.</_> + <_>4 4 8 4 2.</_> + <_>12 8 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0607750006020069</threshold> + <left_val>0.7693629860877991</left_val> + <right_val>-0.1764400005340576</right_val></_></_> + <_> + <!-- tree 165 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 12 3 -1.</_> + <_>7 7 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0246799997985363</threshold> + <left_val>0.1839649975299835</left_val> + <right_val>-0.3086880147457123</right_val></_></_> + <_> + <!-- tree 166 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 9 13 -1.</_> + <_>8 0 3 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0267590004950762</threshold> + <left_val>-0.2345490008592606</left_val> + <right_val>0.3305659890174866</right_val></_></_> + <_> + <!-- tree 167 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 6 9 -1.</_> + <_>13 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0149699999019504</threshold> + <left_val>0.1721359938383102</left_val> + <right_val>-0.1824889928102493</right_val></_></_> + <_> + <!-- tree 168 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0261429995298386</threshold> + <left_val>-0.0464639998972416</left_val> + <right_val>-1.1318379640579224</right_val></_></_> + <_> + <!-- tree 169 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 10 9 -1.</_> + <_>8 4 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0375120006501675</threshold> + <left_val>0.8040400147438049</left_val> + <right_val>0.0696600005030632</right_val></_></_> + <_> + <!-- tree 170 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 18 2 -1.</_> + <_>0 3 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.3229997865855694e-003</threshold> + <left_val>-0.8188440203666687</left_val> + <right_val>-0.0182249993085861</right_val></_></_> + <_> + <!-- tree 171 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 13 14 6 -1.</_> + <_>17 13 7 3 2.</_> + <_>10 16 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0178130008280277</threshold> + <left_val>0.1495780050754547</left_val> + <right_val>-0.1866720020771027</right_val></_></_> + <_> + <!-- tree 172 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 14 6 -1.</_> + <_>0 13 7 3 2.</_> + <_>7 16 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0340100005269051</threshold> + <left_val>-0.7285230159759522</left_val> + <right_val>-0.0166159998625517</right_val></_></_> + <_> + <!-- tree 173 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 2 3 21 -1.</_> + <_>21 2 1 21 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0159530006349087</threshold> + <left_val>0.5694400072097778</left_val> + <right_val>0.0138320000842214</right_val></_></_> + <_> + <!-- tree 174 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 5 12 -1.</_> + <_>0 13 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0197439994663000</threshold> + <left_val>0.0405250005424023</left_val> + <right_val>-0.4177339971065521</right_val></_></_> + <_> + <!-- tree 175 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 12 6 -1.</_> + <_>12 8 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1037480011582375</threshold> + <left_val>-1.9825149774551392</left_val> + <right_val>0.1196020022034645</right_val></_></_> + <_> + <!-- tree 176 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 8 20 3 -1.</_> + <_>1 9 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0192850008606911</threshold> + <left_val>0.5023059844970703</left_val> + <right_val>-0.1974589973688126</right_val></_></_> + <_> + <!-- tree 177 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 19 3 -1.</_> + <_>5 8 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0127800004556775</threshold> + <left_val>0.4019500017166138</left_val> + <right_val>-0.0269579999148846</right_val></_></_> + <_> + <!-- tree 178 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 12 9 6 -1.</_> + <_>1 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0163529999554157</threshold> + <left_val>-0.7660880088806152</left_val> + <right_val>-0.0242090001702309</right_val></_></_> + <_> + <!-- tree 179 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 10 14 12 -1.</_> + <_>6 14 14 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1276369988918304</threshold> + <left_val>0.8657850027084351</left_val> + <right_val>0.0642059966921806</right_val></_></_> + <_> + <!-- tree 180 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 18 -1.</_> + <_>5 12 14 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0190689992159605</threshold> + <left_val>-0.5592979788780212</left_val> + <right_val>-1.6880000475794077e-003</right_val></_></_> + <_> + <!-- tree 181 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 12 9 7 -1.</_> + <_>14 12 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0324809998273849</threshold> + <left_val>0.0407220013439655</left_val> + <right_val>0.4892509877681732</right_val></_></_> + <_> + <!-- tree 182 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 15 18 4 -1.</_> + <_>1 17 18 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.4849998131394386e-003</threshold> + <left_val>-0.1923190057277679</left_val> + <right_val>0.5113970041275024</right_val></_></_> + <_> + <!-- tree 183 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 14 6 9 -1.</_> + <_>11 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.0470000132918358e-003</threshold> + <left_val>0.1870680004358292</left_val> + <right_val>-0.1611360013484955</right_val></_></_> + <_> + <!-- tree 184 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 18 4 -1.</_> + <_>0 8 9 2 2.</_> + <_>9 10 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0412679985165596</threshold> + <left_val>-0.0488179996609688</left_val> + <right_val>-1.1326299905776978</right_val></_></_> + <_> + <!-- tree 185 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 20 6 -1.</_> + <_>13 10 10 3 2.</_> + <_>3 13 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0763589963316917</threshold> + <left_val>1.4169390201568604</left_val> + <right_val>0.0873199999332428</right_val></_></_> + <_> + <!-- tree 186 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 20 6 -1.</_> + <_>1 10 10 3 2.</_> + <_>11 13 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0728349983692169</threshold> + <left_val>1.3189860582351685</left_val> + <right_val>-0.1481910049915314</right_val></_></_> + <_> + <!-- tree 187 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 24 2 -1.</_> + <_>0 9 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0595769993960857</threshold> + <left_val>0.0483769997954369</left_val> + <right_val>0.8561180233955383</right_val></_></_> + <_> + <!-- tree 188 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 12 20 8 -1.</_> + <_>1 12 10 4 2.</_> + <_>11 16 10 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0202639997005463</threshold> + <left_val>-0.2104409933090210</left_val> + <right_val>0.3385899960994721</right_val></_></_> + <_> + <!-- tree 189 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 12 9 7 -1.</_> + <_>14 12 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0803010016679764</threshold> + <left_val>-1.2464400529861450</left_val> + <right_val>0.1185709983110428</right_val></_></_> + <_> + <!-- tree 190 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 9 7 -1.</_> + <_>7 12 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0178350005298853</threshold> + <left_val>0.2578229904174805</left_val> + <right_val>-0.2456479966640472</right_val></_></_> + <_> + <!-- tree 191 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 12 8 5 -1.</_> + <_>12 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0114310001954436</threshold> + <left_val>0.2294979989528656</left_val> + <right_val>-0.2949759960174561</right_val></_></_> + <_> + <!-- tree 192 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 8 5 -1.</_> + <_>8 12 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0255410000681877</threshold> + <left_val>-0.8625299930572510</left_val> + <right_val>-7.0400000549852848e-004</right_val></_></_> + <_> + <!-- tree 193 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 10 4 10 -1.</_> + <_>13 10 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.6899997657164931e-004</threshold> + <left_val>0.3151139914989471</left_val> + <right_val>-0.1434900015592575</right_val></_></_> + <_> + <!-- tree 194 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 15 20 2 -1.</_> + <_>11 15 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0144539996981621</threshold> + <left_val>0.2514849901199341</left_val> + <right_val>-0.2823289930820465</right_val></_></_> + <_> + <!-- tree 195 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 10 6 6 -1.</_> + <_>9 10 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.6730001494288445e-003</threshold> + <left_val>0.2660140097141266</left_val> + <right_val>-0.2819080054759979</right_val></_></_></trees> + <stage_threshold>-3.2103500366210937</stage_threshold> + <parent>18</parent> + <next>-1</next></_> + <_> + <!-- stage 20 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 21 3 -1.</_> + <_>7 1 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0547089986503124</threshold> + <left_val>-0.5414429903030396</left_val> + <right_val>0.6104300022125244</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 13 9 -1.</_> + <_>6 7 13 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1083879992365837</threshold> + <left_val>0.7173990011215210</left_val> + <right_val>-0.4119609892368317</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 12 5 -1.</_> + <_>10 5 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0229969993233681</threshold> + <left_val>-0.5826979875564575</left_val> + <right_val>0.2964560091495514</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 10 10 6 -1.</_> + <_>10 12 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.7540000155568123e-003</threshold> + <left_val>-0.7424389719963074</left_val> + <right_val>0.1418330073356628</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 12 5 8 -1.</_> + <_>6 16 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.1520000882446766e-003</threshold> + <left_val>0.1787990033626556</left_val> + <right_val>-0.6854860186576843</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 6 9 -1.</_> + <_>15 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0225590001791716</threshold> + <left_val>-1.0775549411773682</left_val> + <right_val>0.1238899976015091</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 10 18 6 -1.</_> + <_>8 10 6 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0830250009894371</threshold> + <left_val>0.0245009995996952</left_val> + <right_val>-1.0251879692077637</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 2 9 4 -1.</_> + <_>11 4 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.6740000620484352e-003</threshold> + <left_val>-0.4528310000896454</left_val> + <right_val>0.2123019993305206</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 20 21 3 -1.</_> + <_>8 20 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0764850005507469</threshold> + <left_val>-0.2697269916534424</left_val> + <right_val>0.4858019948005676</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 22 2 -1.</_> + <_>1 11 22 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.4910001344978809e-003</threshold> + <left_val>-0.4887120127677918</left_val> + <right_val>0.3161639869213104</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 18 3 -1.</_> + <_>0 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0104149999096990</threshold> + <left_val>0.4151290059089661</left_val> + <right_val>-0.3004480004310608</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 6 9 -1.</_> + <_>15 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0276079997420311</threshold> + <left_val>0.1620379984378815</left_val> + <right_val>-0.9986850023269653</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 6 9 -1.</_> + <_>7 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0232720002532005</threshold> + <left_val>-1.1024399995803833</left_val> + <right_val>0.0211249999701977</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 20 -1.</_> + <_>20 2 2 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0556199997663498</threshold> + <left_val>0.6503310203552246</left_val> + <right_val>-0.0279380008578300</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 20 -1.</_> + <_>2 2 2 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0406319983303547</threshold> + <left_val>0.4211730062961578</left_val> + <right_val>-0.2676379978656769</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 7 6 14 -1.</_> + <_>14 7 3 7 2.</_> + <_>11 14 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.3560001328587532e-003</threshold> + <left_val>0.3527779877185822</left_val> + <right_val>-0.3785400092601776</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 4 9 -1.</_> + <_>2 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0170070007443428</threshold> + <left_val>-0.2918950021266937</left_val> + <right_val>0.4105379879474640</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 14 9 4 -1.</_> + <_>12 16 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0370340012013912</threshold> + <left_val>-1.3216309547424316</left_val> + <right_val>0.1296650022268295</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 9 4 -1.</_> + <_>1 15 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0196330007165670</threshold> + <left_val>-0.8770229816436768</left_val> + <right_val>1.0799999581649899e-003</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 15 6 -1.</_> + <_>7 8 15 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0235469993203878</threshold> + <left_val>0.2610610127449036</left_val> + <right_val>-0.2148140072822571</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 3 18 -1.</_> + <_>8 8 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0433529987931252</threshold> + <left_val>-0.9908969998359680</left_val> + <right_val>-9.9560003727674484e-003</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 6 -1.</_> + <_>12 6 6 3 2.</_> + <_>6 9 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0221839994192123</threshold> + <left_val>0.6345440149307251</left_val> + <right_val>-0.0565470010042191</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 19 20 4 -1.</_> + <_>2 19 10 2 2.</_> + <_>12 21 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0165309999138117</threshold> + <left_val>0.0246649999171495</left_val> + <right_val>-0.7332680225372315</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 6 9 -1.</_> + <_>14 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0327440015971661</threshold> + <left_val>-0.5629720091819763</left_val> + <right_val>0.1664029955863953</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 18 14 -1.</_> + <_>3 5 9 7 2.</_> + <_>12 12 9 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0714159980416298</threshold> + <left_val>-3.0000001424923539e-004</left_val> + <right_val>-0.9328640103340149</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 6 4 18 -1.</_> + <_>17 6 2 9 2.</_> + <_>15 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.0999999772757292e-004</threshold> + <left_val>-0.0953800007700920</left_val> + <right_val>0.2518469989299774</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 4 18 -1.</_> + <_>5 6 2 9 2.</_> + <_>7 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.4090000018477440e-003</threshold> + <left_val>-0.6549680233001709</left_val> + <right_val>0.0673009976744652</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 6 9 -1.</_> + <_>13 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0172540005296469</threshold> + <left_val>-0.4649299979209900</left_val> + <right_val>0.1607089936733246</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0186410006135702</threshold> + <left_val>-1.0594010353088379</left_val> + <right_val>-0.0196170005947351</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 5 6 9 -1.</_> + <_>13 5 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.1979997232556343e-003</threshold> + <left_val>0.5071619749069214</left_val> + <right_val>-0.1533920019865036</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 6 6 -1.</_> + <_>12 5 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0185380000621080</threshold> + <left_val>-0.3049820065498352</left_val> + <right_val>0.7350620031356812</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 16 6 -1.</_> + <_>12 1 8 3 2.</_> + <_>4 4 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0503350012004375</threshold> + <left_val>-1.1140480041503906</left_val> + <right_val>0.1800010055303574</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 13 6 11 -1.</_> + <_>11 13 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0235290005803108</threshold> + <left_val>-0.8690789937973023</left_val> + <right_val>-0.0124599998816848</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 1 6 12 -1.</_> + <_>20 1 3 6 2.</_> + <_>17 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0271000005304813</threshold> + <left_val>0.6594290137290955</left_val> + <right_val>-0.0353239998221397</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 17 18 3 -1.</_> + <_>1 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.5879998728632927e-003</threshold> + <left_val>-0.2295340001583099</left_val> + <right_val>0.4242509901523590</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 13 10 8 -1.</_> + <_>7 17 10 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0233600009232759</threshold> + <left_val>0.1835619956254959</left_val> + <right_val>-0.9858729839324951</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 18 10 6 -1.</_> + <_>6 20 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0129469996318221</threshold> + <left_val>-0.3314740061759949</left_val> + <right_val>0.2132319957017899</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 14 9 4 -1.</_> + <_>9 16 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.6559999249875546e-003</threshold> + <left_val>-0.1195140033960342</left_val> + <right_val>0.2975279986858368</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 6 12 -1.</_> + <_>1 1 3 6 2.</_> + <_>4 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0225709993392229</threshold> + <left_val>0.3849940001964569</left_val> + <right_val>-0.2443449944257736</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 4 5 12 -1.</_> + <_>19 8 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0638139992952347</threshold> + <left_val>-0.8938350081443787</left_val> + <right_val>0.1421750038862228</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 8 8 -1.</_> + <_>4 0 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0499450005590916</threshold> + <left_val>0.5386440157890320</left_val> + <right_val>-0.2048529982566834</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 19 3 -1.</_> + <_>3 6 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.8319998681545258e-003</threshold> + <left_val>-0.0566789992153645</left_val> + <right_val>0.3997099995613098</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 12 6 -1.</_> + <_>1 5 6 3 2.</_> + <_>7 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0558359995484352</threshold> + <left_val>-1.5239470005035400</left_val> + <right_val>-0.0511830002069473</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 1 21 8 -1.</_> + <_>9 1 7 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.3195700049400330</threshold> + <left_val>0.0745740011334419</left_val> + <right_val>1.2447799444198608</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 16 8 -1.</_> + <_>4 5 16 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0809559971094131</threshold> + <left_val>-0.1966550052165985</left_val> + <right_val>0.5988969802856445</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 18 3 -1.</_> + <_>6 1 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0149119999259710</threshold> + <left_val>-0.6402059793472290</left_val> + <right_val>0.1580760031938553</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 10 14 -1.</_> + <_>4 11 10 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0467090010643005</threshold> + <left_val>0.0852390006184578</left_val> + <right_val>-0.4548720121383667</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 6 4 10 -1.</_> + <_>15 11 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.0539999976754189e-003</threshold> + <left_val>-0.4318400025367737</left_val> + <right_val>0.2245260030031204</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 18 3 -1.</_> + <_>9 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0343759991228580</threshold> + <left_val>0.4020250141620636</left_val> + <right_val>-0.2390359938144684</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 12 6 -1.</_> + <_>12 18 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0349240005016327</threshold> + <left_val>0.5287010073661804</left_val> + <right_val>0.0397090017795563</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 15 6 9 -1.</_> + <_>6 15 3 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.0030000489205122e-003</threshold> + <left_val>-0.3875429928302765</left_val> + <right_val>0.1419260054826737</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 7 6 8 -1.</_> + <_>15 11 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0141329998150468</threshold> + <left_val>0.8752840161323547</left_val> + <right_val>0.0855079963803291</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 6 8 -1.</_> + <_>3 11 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.7940000444650650e-003</threshold> + <left_val>-1.1649219989776611</left_val> + <right_val>-0.0339430011808872</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 9 18 6 -1.</_> + <_>14 9 9 3 2.</_> + <_>5 12 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0528860017657280</threshold> + <left_val>1.0930680036544800</left_val> + <right_val>0.0511870011687279</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 12 6 -1.</_> + <_>1 15 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.1079999860376120e-003</threshold> + <left_val>0.1369619965553284</left_val> + <right_val>-0.3384999930858612</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 10 6 -1.</_> + <_>14 17 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0183530002832413</threshold> + <left_val>0.1366160064935684</left_val> + <right_val>-0.4077779948711395</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 10 6 -1.</_> + <_>0 17 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0126719996333122</threshold> + <left_val>-0.0149360001087189</left_val> + <right_val>-0.8170750141143799</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 13 6 9 -1.</_> + <_>15 16 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0129249999299645</threshold> + <left_val>0.1762509942054749</left_val> + <right_val>-0.3249169886112213</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 13 6 9 -1.</_> + <_>3 16 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0179210007190704</threshold> + <left_val>-0.5274540185928345</left_val> + <right_val>0.0444430001080036</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 8 8 -1.</_> + <_>9 5 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.9160000374540687e-003</threshold> + <left_val>-0.1097859963774681</left_val> + <right_val>0.2206750065088272</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 18 12 6 -1.</_> + <_>1 18 6 3 2.</_> + <_>7 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0146979996934533</threshold> + <left_val>0.3906779885292053</left_val> + <right_val>-0.2222499996423721</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 19 10 4 -1.</_> + <_>13 21 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0149729996919632</threshold> + <left_val>-0.2545090019702911</left_val> + <right_val>0.1779000014066696</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 19 10 4 -1.</_> + <_>1 21 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0146369999274611</threshold> + <left_val>-0.0251250006258488</left_val> + <right_val>-0.8712130188941956</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 19 18 3 -1.</_> + <_>6 20 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0109740002080798</threshold> + <left_val>0.7908279895782471</left_val> + <right_val>0.0201210007071495</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 14 4 10 -1.</_> + <_>8 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.1599998995661736e-003</threshold> + <left_val>-0.4790689945220947</left_val> + <right_val>0.0522320009768009</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 6 -1.</_> + <_>0 2 24 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.6179997734725475e-003</threshold> + <left_val>-0.1724459975957871</left_val> + <right_val>0.3452779948711395</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 9 -1.</_> + <_>0 4 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0234769992530346</threshold> + <left_val>3.7760001141577959e-003</left_val> + <right_val>-0.6533370018005371</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 9 20 6 -1.</_> + <_>14 9 10 3 2.</_> + <_>4 12 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0317669995129108</threshold> + <left_val>0.0163640007376671</left_val> + <right_val>0.5872370004653931</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 15 19 8 -1.</_> + <_>1 19 19 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0184199996292591</threshold> + <left_val>0.1999389976263046</left_val> + <right_val>-0.3205649852752686</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 10 6 -1.</_> + <_>14 2 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0195439998060465</threshold> + <left_val>0.1845020055770874</left_val> + <right_val>-0.2379360049962997</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 21 14 -1.</_> + <_>8 10 7 14 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.4115949869155884</threshold> + <left_val>-0.0603820011019707</left_val> + <right_val>-1.6072119474411011</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 10 8 8 -1.</_> + <_>10 10 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0415959991514683</threshold> + <left_val>-0.3275620043277741</left_val> + <right_val>0.1505800038576126</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 10 4 -1.</_> + <_>11 8 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0103359995409846</threshold> + <left_val>-0.6239439845085144</left_val> + <right_val>0.0131120001897216</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 4 9 -1.</_> + <_>10 5 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0123929996043444</threshold> + <left_val>-0.0331149995326996</left_val> + <right_val>0.5557990074157715</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 6 10 -1.</_> + <_>9 5 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.7270000949501991e-003</threshold> + <left_val>0.1988320052623749</left_val> + <right_val>-0.3763560056686401</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 4 4 13 -1.</_> + <_>14 4 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0162950009107590</threshold> + <left_val>0.2037300020456314</left_val> + <right_val>-0.4280079901218414</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 4 13 -1.</_> + <_>8 4 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0104839997366071</threshold> + <left_val>-0.5684700012207031</left_val> + <right_val>0.0441990010440350</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 9 6 -1.</_> + <_>11 7 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0124319996684790</threshold> + <left_val>0.7464190125465393</left_val> + <right_val>0.0436789989471436</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 16 6 -1.</_> + <_>3 6 8 3 2.</_> + <_>11 9 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0503749996423721</threshold> + <left_val>0.8509010076522827</left_val> + <right_val>-0.1777379959821701</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 16 14 -1.</_> + <_>13 4 8 7 2.</_> + <_>5 11 8 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0495480000972748</threshold> + <left_val>0.1678490042686462</left_val> + <right_val>-0.2987749874591827</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 4 -1.</_> + <_>0 0 12 2 2.</_> + <_>12 2 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0410850010812283</threshold> + <left_val>-1.3302919864654541</left_val> + <right_val>-0.0491820015013218</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 9 6 -1.</_> + <_>12 1 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.0069999843835831e-003</threshold> + <left_val>-0.0605389997363091</left_val> + <right_val>0.1848320066928864</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 14 4 -1.</_> + <_>11 1 7 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0501429997384548</threshold> + <left_val>0.7644770145416260</left_val> + <right_val>-0.1835699975490570</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 7 9 -1.</_> + <_>10 17 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.7879998609423637e-003</threshold> + <left_val>0.2265599966049194</left_val> + <right_val>-0.0631569996476173</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 3 8 10 -1.</_> + <_>8 3 4 5 2.</_> + <_>12 8 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0501709990203381</threshold> + <left_val>-1.5899070501327515</left_val> + <right_val>-0.0612550005316734</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 3 12 5 -1.</_> + <_>11 3 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1021609976887703</threshold> + <left_val>0.1207180023193359</left_val> + <right_val>-1.4120110273361206</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 4 13 -1.</_> + <_>10 2 2 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0143729997798800</threshold> + <left_val>-1.3116970062255859</left_val> + <right_val>-0.0519360005855560</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 2 3 19 -1.</_> + <_>12 2 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0102819995954633</threshold> + <left_val>-2.1639999467879534e-003</left_val> + <right_val>0.4424720108509064</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 9 6 -1.</_> + <_>10 7 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0118140000849962</threshold> + <left_val>0.6537809967994690</left_val> + <right_val>-0.1872369945049286</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 22 20 2 -1.</_> + <_>4 22 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0721149966120720</threshold> + <left_val>0.0718469992280006</left_val> + <right_val>0.8149629831314087</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 24 4 -1.</_> + <_>0 16 12 2 2.</_> + <_>12 18 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0190019998699427</threshold> + <left_val>-0.6742720007896423</left_val> + <right_val>-4.3200000072829425e-004</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 3 12 5 -1.</_> + <_>11 3 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.6990001574158669e-003</threshold> + <left_val>0.3331150114536285</left_val> + <right_val>0.0557940006256104</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 8 14 -1.</_> + <_>1 10 4 7 2.</_> + <_>5 17 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0581570006906986</threshold> + <left_val>0.4557229876518250</left_val> + <right_val>-0.2030510008335114</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 16 6 6 -1.</_> + <_>11 19 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.1360000353306532e-003</threshold> + <left_val>-0.0446869991719723</left_val> + <right_val>0.2268189936876297</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 10 24 -1.</_> + <_>6 0 5 12 2.</_> + <_>11 12 5 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0494149997830391</threshold> + <left_val>0.2669459879398346</left_val> + <right_val>-0.2611699998378754</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 14 14 -1.</_> + <_>14 5 7 7 2.</_> + <_>7 12 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1191380023956299</threshold> + <left_val>-0.8301799893379211</left_val> + <right_val>0.1324850022792816</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 10 8 -1.</_> + <_>7 8 5 4 2.</_> + <_>12 12 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0183039996773005</threshold> + <left_val>-0.6749920248985291</left_val> + <right_val>0.0170920006930828</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 9 6 -1.</_> + <_>12 1 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.9199997708201408e-003</threshold> + <left_val>-0.0722870007157326</left_val> + <right_val>0.1442580074071884</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 24 3 -1.</_> + <_>12 6 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0519259981811047</threshold> + <left_val>0.0309219993650913</left_val> + <right_val>-0.5586060285568237</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 3 12 5 -1.</_> + <_>11 3 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0667240023612976</threshold> + <left_val>0.1366640031337738</left_val> + <right_val>-0.2941100001335144</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 22 4 -1.</_> + <_>1 13 11 2 2.</_> + <_>12 15 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0137780001387000</threshold> + <left_val>-0.5944390296936035</left_val> + <right_val>0.0153000000864267</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 12 6 -1.</_> + <_>9 14 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0177609995007515</threshold> + <left_val>0.4049650132656097</left_val> + <right_val>-3.3559999428689480e-003</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 9 6 -1.</_> + <_>0 7 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0422349981963634</threshold> + <left_val>-1.0897940397262573</left_val> + <right_val>-0.0402249991893768</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 23 6 -1.</_> + <_>1 7 23 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0135249998420477</threshold> + <left_val>0.2892189919948578</left_val> + <right_val>-0.2519479990005493</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 6 19 12 -1.</_> + <_>1 10 19 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0111060002818704</threshold> + <left_val>0.6531280279159546</left_val> + <right_val>-0.1805370002985001</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 6 21 -1.</_> + <_>9 8 6 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1228459998965263</threshold> + <left_val>-1.9570649862289429</left_val> + <right_val>0.1481540054082871</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 19 18 3 -1.</_> + <_>9 19 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0477159991860390</threshold> + <left_val>-0.2287559956312180</left_val> + <right_val>0.3423370122909546</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 14 6 9 -1.</_> + <_>11 14 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0318170003592968</threshold> + <left_val>0.1597629934549332</left_val> + <right_val>-1.0091969966888428</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 4 12 -1.</_> + <_>11 6 2 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.2570000514388084e-003</threshold> + <left_val>-0.3888129889965057</left_val> + <right_val>0.0842100009322166</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 0 6 9 -1.</_> + <_>18 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0613729991018772</threshold> + <left_val>1.7152810096740723</left_val> + <right_val>0.0593249984085560</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 6 9 -1.</_> + <_>4 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.7030000928789377e-003</threshold> + <left_val>-0.3816170096397400</left_val> + <right_val>0.0851270034909248</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 1 4 22 -1.</_> + <_>15 1 2 11 2.</_> + <_>13 12 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0685440003871918</threshold> + <left_val>-3.0925889015197754</left_val> + <right_val>0.1178800016641617</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 8 8 12 -1.</_> + <_>1 14 8 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1037250012159348</threshold> + <left_val>-0.1376930028200150</left_val> + <right_val>1.9009410142898560</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 7 7 9 -1.</_> + <_>14 10 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0157990008592606</threshold> + <left_val>-0.0626600012183189</left_val> + <right_val>0.2591769993305206</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 12 18 4 -1.</_> + <_>3 12 9 2 2.</_> + <_>12 14 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.8040001466870308e-003</threshold> + <left_val>-0.5629159808158875</left_val> + <right_val>0.0439230017364025</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 1 4 22 -1.</_> + <_>15 1 2 11 2.</_> + <_>13 12 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.0229995548725128e-003</threshold> + <left_val>0.2528710067272186</left_val> + <right_val>-0.0412259995937347</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 4 22 -1.</_> + <_>7 1 2 11 2.</_> + <_>9 12 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0637549981474876</threshold> + <left_val>-2.6178569793701172</left_val> + <right_val>-0.0740059986710548</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 20 4 -1.</_> + <_>14 7 10 2 2.</_> + <_>4 9 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0389549992978573</threshold> + <left_val>0.0590329989790916</left_val> + <right_val>0.8594560027122498</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 10 6 7 -1.</_> + <_>12 10 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0398029983043671</threshold> + <left_val>0.9360049962997437</left_val> + <right_val>-0.1563940048217773</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 10 4 -1.</_> + <_>7 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0503019988536835</threshold> + <left_val>0.1372590065002441</left_val> + <right_val>-2.5549728870391846</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 4 15 -1.</_> + <_>0 8 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0462500005960464</threshold> + <left_val>-0.0139640001580119</left_val> + <right_val>-0.7102620005607605</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 8 12 -1.</_> + <_>19 0 4 6 2.</_> + <_>15 6 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0621960014104843</threshold> + <left_val>0.0595260001718998</left_val> + <right_val>1.6509100198745728</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 8 12 -1.</_> + <_>1 0 4 6 2.</_> + <_>5 6 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0647760033607483</threshold> + <left_val>0.7136899828910828</left_val> + <right_val>-0.1727000027894974</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 5 6 16 -1.</_> + <_>16 5 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0275229997932911</threshold> + <left_val>0.1463160067796707</left_val> + <right_val>-0.0814289972186089</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 5 6 16 -1.</_> + <_>6 5 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.9900001138448715e-004</threshold> + <left_val>-0.3714450001716614</left_val> + <right_val>0.1015269979834557</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 6 16 -1.</_> + <_>17 0 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.3299999088048935e-003</threshold> + <left_val>-0.2375629991292954</left_val> + <right_val>0.2679840028285980</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 6 16 -1.</_> + <_>5 0 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0472970008850098</threshold> + <left_val>-0.0276820007711649</left_val> + <right_val>-0.8491029739379883</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 24 3 -1.</_> + <_>0 3 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0125089995563030</threshold> + <left_val>0.1873019933700562</left_val> + <right_val>-0.5600110292434692</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 10 4 -1.</_> + <_>7 3 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0458990000188351</threshold> + <left_val>-0.1560119986534119</left_val> + <right_val>0.9707300066947937</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 23 8 -1.</_> + <_>1 4 23 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1985339969396591</threshold> + <left_val>0.1489550024271011</left_val> + <right_val>-1.1015529632568359</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 17 19 3 -1.</_> + <_>1 18 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0166749991476536</threshold> + <left_val>-0.1661529988050461</left_val> + <right_val>0.8221099972724915</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 18 18 2 -1.</_> + <_>6 19 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.9829999655485153e-003</threshold> + <left_val>-0.0712499991059303</left_val> + <right_val>0.2881090044975281</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 17 9 6 -1.</_> + <_>1 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0224479995667934</threshold> + <left_val>-0.0209810007363558</left_val> + <right_val>-0.7841650247573853</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 15 6 9 -1.</_> + <_>15 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0139130000025034</threshold> + <left_val>-0.1816579997539520</left_val> + <right_val>0.2049179971218109</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 15 6 9 -1.</_> + <_>3 18 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.7659999951720238e-003</threshold> + <left_val>-0.4559589922428131</left_val> + <right_val>0.0635769963264465</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 14 20 6 -1.</_> + <_>4 17 20 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0132090002298355</threshold> + <left_val>0.2663230001926422</left_val> + <right_val>-0.1779599934816361</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 6 14 -1.</_> + <_>0 10 3 7 2.</_> + <_>3 17 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0490529984235764</threshold> + <left_val>-0.1547680050134659</left_val> + <right_val>1.1069979667663574</right_val></_></_> + <_> + <!-- tree 137 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 18 18 3 -1.</_> + <_>6 19 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0202639997005463</threshold> + <left_val>0.0689150020480156</left_val> + <right_val>0.6986749768257141</right_val></_></_> + <_> + <!-- tree 138 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 9 7 -1.</_> + <_>7 12 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0168280005455017</threshold> + <left_val>0.2760719954967499</left_val> + <right_val>-0.2513920068740845</right_val></_></_> + <_> + <!-- tree 139 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 10 18 5 -1.</_> + <_>12 10 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1693949997425079</threshold> + <left_val>-3.0767529010772705</left_val> + <right_val>0.1161750033497810</right_val></_></_> + <_> + <!-- tree 140 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 18 5 -1.</_> + <_>6 10 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1133610010147095</threshold> + <left_val>-1.4639229774475098</left_val> + <right_val>-0.0514470003545284</right_val></_></_> + <_> + <!-- tree 141 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 18 9 -1.</_> + <_>9 2 6 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0776859968900681</threshold> + <left_val>0.8843020200729370</left_val> + <right_val>0.0433069989085197</right_val></_></_> + <_> + <!-- tree 142 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 10 10 -1.</_> + <_>4 6 5 5 2.</_> + <_>9 11 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0155680002644658</threshold> + <left_val>0.1367249935865402</left_val> + <right_val>-0.3450550138950348</right_val></_></_> + <_> + <!-- tree 143 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 14 4 9 -1.</_> + <_>20 14 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0660189986228943</threshold> + <left_val>-1.0300110578536987</left_val> + <right_val>0.1160139963030815</right_val></_></_> + <_> + <!-- tree 144 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 4 9 -1.</_> + <_>2 14 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.3699999377131462e-003</threshold> + <left_val>0.0764290019869804</left_val> + <right_val>-0.4400250017642975</right_val></_></_> + <_> + <!-- tree 145 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 4 20 -1.</_> + <_>13 1 2 10 2.</_> + <_>11 11 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0354029983282089</threshold> + <left_val>0.1197950020432472</left_val> + <right_val>-0.7266830205917358</right_val></_></_> + <_> + <!-- tree 146 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 21 12 3 -1.</_> + <_>12 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0390510000288486</threshold> + <left_val>0.6737530231475830</left_val> + <right_val>-0.1819600015878677</right_val></_></_> + <_> + <!-- tree 147 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 4 20 -1.</_> + <_>13 1 2 10 2.</_> + <_>11 11 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.7899995744228363e-003</threshold> + <left_val>0.2126459926366806</left_val> + <right_val>0.0367560014128685</right_val></_></_> + <_> + <!-- tree 148 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 16 10 8 -1.</_> + <_>1 16 5 4 2.</_> + <_>6 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0230470001697540</threshold> + <left_val>0.4474219977855682</left_val> + <right_val>-0.2098670005798340</right_val></_></_> + <_> + <!-- tree 149 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 4 20 -1.</_> + <_>13 1 2 10 2.</_> + <_>11 11 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.1169999856501818e-003</threshold> + <left_val>0.0375440008938313</left_val> + <right_val>0.2780820131301880</right_val></_></_> + <_> + <!-- tree 150 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 3 19 -1.</_> + <_>2 0 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0131360003724694</threshold> + <left_val>-0.1984239965677261</left_val> + <right_val>0.5433570146560669</right_val></_></_> + <_> + <!-- tree 151 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 4 20 -1.</_> + <_>13 1 2 10 2.</_> + <_>11 11 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0147820003330708</threshold> + <left_val>0.1353060007095337</left_val> + <right_val>-0.1115360036492348</right_val></_></_> + <_> + <!-- tree 152 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 9 -1.</_> + <_>2 1 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0601390004158020</threshold> + <left_val>0.8403930068016052</left_val> + <right_val>-0.1671160012483597</right_val></_></_> + <_> + <!-- tree 153 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 19 4 -1.</_> + <_>3 9 19 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0519989989697933</threshold> + <left_val>0.1737200021743774</left_val> + <right_val>-0.7854760289192200</right_val></_></_> + <_> + <!-- tree 154 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 14 9 6 -1.</_> + <_>7 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0247920006513596</threshold> + <left_val>-0.1773920059204102</left_val> + <right_val>0.6675260066986084</right_val></_></_> + <_> + <!-- tree 155 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 1 7 6 -1.</_> + <_>17 4 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0120149999856949</threshold> + <left_val>-0.1426369994878769</left_val> + <right_val>0.1607050001621246</right_val></_></_> + <_> + <!-- tree 156 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 14 8 -1.</_> + <_>5 4 14 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0986559987068176</threshold> + <left_val>1.0429769754409790</left_val> + <right_val>-0.1577019989490509</right_val></_></_> + <_> + <!-- tree 157 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 1 8 6 -1.</_> + <_>16 4 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1175829991698265</threshold> + <left_val>0.1095570027828217</left_val> + <right_val>-4.4920377731323242</right_val></_></_> + <_> + <!-- tree 158 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 8 6 -1.</_> + <_>0 4 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0189229995012283</threshold> + <left_val>-0.7854340076446533</left_val> + <right_val>0.0129840001463890</right_val></_></_> + <_> + <!-- tree 159 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 18 4 -1.</_> + <_>15 0 9 2 2.</_> + <_>6 2 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0283909998834133</threshold> + <left_val>-0.6056990027427673</left_val> + <right_val>0.1290349960327148</right_val></_></_> + <_> + <!-- tree 160 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 9 6 -1.</_> + <_>0 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0131829995661974</threshold> + <left_val>-0.0144159998744726</left_val> + <right_val>-0.7321050167083740</right_val></_></_> + <_> + <!-- tree 161 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 18 8 -1.</_> + <_>9 7 6 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1165300011634827</threshold> + <left_val>-2.0442469120025635</left_val> + <right_val>0.1405310034751892</right_val></_></_> + <_> + <!-- tree 162 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 6 9 -1.</_> + <_>4 11 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.8880000356584787e-003</threshold> + <left_val>-0.4186159968376160</left_val> + <right_val>0.0787049978971481</right_val></_></_> + <_> + <!-- tree 163 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 6 9 -1.</_> + <_>12 5 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0312290005385876</threshold> + <left_val>0.0246329996734858</left_val> + <right_val>0.4187040030956268</right_val></_></_> + <_> + <!-- tree 164 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 18 -1.</_> + <_>10 6 2 9 2.</_> + <_>12 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0251989997923374</threshold> + <left_val>-0.1755779981613159</left_val> + <right_val>0.6471059918403626</right_val></_></_> + <_> + <!-- tree 165 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 1 4 20 -1.</_> + <_>13 1 2 10 2.</_> + <_>11 11 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0281240008771420</threshold> + <left_val>-0.2200559973716736</left_val> + <right_val>0.1412100046873093</right_val></_></_> + <_> + <!-- tree 166 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 4 20 -1.</_> + <_>9 1 2 10 2.</_> + <_>11 11 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0364990010857582</threshold> + <left_val>-0.0684269964694977</left_val> + <right_val>-2.3410849571228027</right_val></_></_> + <_> + <!-- tree 167 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 9 18 6 -1.</_> + <_>14 9 9 3 2.</_> + <_>5 12 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0722929984331131</threshold> + <left_val>1.2898750305175781</left_val> + <right_val>0.0848750025033951</right_val></_></_> + <_> + <!-- tree 168 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 6 9 -1.</_> + <_>8 4 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0416710004210472</threshold> + <left_val>-1.1630970239639282</left_val> + <right_val>-0.0537529997527599</right_val></_></_> + <_> + <!-- tree 169 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 16 8 6 -1.</_> + <_>10 16 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0477030016481876</threshold> + <left_val>0.0701010003685951</left_val> + <right_val>0.7367650270462036</right_val></_></_> + <_> + <!-- tree 170 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 18 8 -1.</_> + <_>0 0 9 4 2.</_> + <_>9 4 9 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0657930001616478</threshold> + <left_val>-0.1775529980659485</left_val> + <right_val>0.6978049874305725</right_val></_></_> + <_> + <!-- tree 171 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 14 12 -1.</_> + <_>13 5 7 6 2.</_> + <_>6 11 7 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0139049999415874</threshold> + <left_val>0.2193679958581924</left_val> + <right_val>-0.2039079964160919</right_val></_></_> + <_> + <!-- tree 172 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 15 7 -1.</_> + <_>9 3 5 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0277309995144606</threshold> + <left_val>0.6186789870262146</left_val> + <right_val>-0.1780409961938858</right_val></_></_> + <_> + <!-- tree 173 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 12 10 6 -1.</_> + <_>14 14 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0158799998462200</threshold> + <left_val>-0.4648410081863403</left_val> + <right_val>0.1882860064506531</right_val></_></_> + <_> + <!-- tree 174 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 4 10 -1.</_> + <_>0 16 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0741280019283295</threshold> + <left_val>-0.1285810023546219</left_val> + <right_val>3.2792479991912842</right_val></_></_> + <_> + <!-- tree 175 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 22 3 -1.</_> + <_>1 11 22 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.9000002481043339e-004</threshold> + <left_val>-0.3011760115623474</left_val> + <right_val>0.2381879985332489</right_val></_></_> + <_> + <!-- tree 176 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 9 6 10 -1.</_> + <_>10 9 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0179650001227856</threshold> + <left_val>-0.2228499948978424</left_val> + <right_val>0.2995400130748749</right_val></_></_> + <_> + <!-- tree 177 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 2 6 12 -1.</_> + <_>16 2 3 6 2.</_> + <_>13 8 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.5380000006407499e-003</threshold> + <left_val>0.2506439983844757</left_val> + <right_val>-0.1366560012102127</right_val></_></_> + <_> + <!-- tree 178 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 18 -1.</_> + <_>10 6 2 9 2.</_> + <_>12 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.0680001303553581e-003</threshold> + <left_val>0.2901749908924103</left_val> + <right_val>-0.2892970144748688</right_val></_></_> + <_> + <!-- tree 179 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 10 16 -1.</_> + <_>12 8 5 8 2.</_> + <_>7 16 5 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0491699986159801</threshold> + <left_val>0.1915639936923981</left_val> + <right_val>-0.6832870244979858</right_val></_></_> + <_> + <!-- tree 180 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 8 12 -1.</_> + <_>8 1 4 6 2.</_> + <_>12 7 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0306809991598129</threshold> + <left_val>-0.7567700147628784</left_val> + <right_val>-0.0132799996063113</right_val></_></_> + <_> + <!-- tree 181 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 12 14 -1.</_> + <_>13 1 6 7 2.</_> + <_>7 8 6 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1001740023493767</threshold> + <left_val>0.0844539999961853</left_val> + <right_val>1.0888710021972656</right_val></_></_> + <_> + <!-- tree 182 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 14 12 6 -1.</_> + <_>2 16 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.1950001139193773e-003</threshold> + <left_val>-0.2691940069198608</left_val> + <right_val>0.1953790038824081</right_val></_></_> + <_> + <!-- tree 183 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 16 6 6 -1.</_> + <_>11 19 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0355030000209808</threshold> + <left_val>0.1363230049610138</left_val> + <right_val>-0.5691720247268677</right_val></_></_> + <_> + <!-- tree 184 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 16 6 6 -1.</_> + <_>7 19 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.5900000259280205e-004</threshold> + <left_val>-0.4044399857521057</left_val> + <right_val>0.1407479941844940</right_val></_></_> + <_> + <!-- tree 185 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 4 4 10 -1.</_> + <_>13 4 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0252589993178844</threshold> + <left_val>0.1624320000410080</left_val> + <right_val>-0.5574179887771606</right_val></_></_> + <_> + <!-- tree 186 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 19 19 3 -1.</_> + <_>0 20 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.1549999043345451e-003</threshold> + <left_val>0.3113259971141815</left_val> + <right_val>-0.2275609970092773</right_val></_></_> + <_> + <!-- tree 187 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 8 6 8 -1.</_> + <_>12 12 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.5869999770075083e-003</threshold> + <left_val>-0.2686769962310791</left_val> + <right_val>0.1956540048122406</right_val></_></_> + <_> + <!-- tree 188 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 8 22 -1.</_> + <_>8 12 8 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0162049997597933</threshold> + <left_val>0.1548649966716766</left_val> + <right_val>-0.3405779898166657</right_val></_></_> + <_> + <!-- tree 189 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 8 6 8 -1.</_> + <_>12 12 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0296240001916885</threshold> + <left_val>1.1466799974441528</left_val> + <right_val>0.0905579999089241</right_val></_></_> + <_> + <!-- tree 190 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 6 8 -1.</_> + <_>6 12 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.5930000226944685e-003</threshold> + <left_val>-0.7125750184059143</left_val> + <right_val>-7.0400000549852848e-004</right_val></_></_> + <_> + <!-- tree 191 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 5 6 9 -1.</_> + <_>14 8 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0540190003812313</threshold> + <left_val>0.4153749942779541</left_val> + <right_val>0.0272460002452135</right_val></_></_> + <_> + <!-- tree 192 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 24 4 -1.</_> + <_>0 8 24 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0662110000848770</threshold> + <left_val>-1.3340090513229370</left_val> + <right_val>-0.0473529994487762</right_val></_></_> + <_> + <!-- tree 193 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 12 10 6 -1.</_> + <_>14 14 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0279409997165203</threshold> + <left_val>0.1444630026817322</left_val> + <right_val>-0.5151839852333069</right_val></_></_> + <_> + <!-- tree 194 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 10 6 -1.</_> + <_>0 14 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0289570000022650</threshold> + <left_val>-0.0499660000205040</left_val> + <right_val>-1.1929039955139160</right_val></_></_> + <_> + <!-- tree 195 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 19 3 -1.</_> + <_>4 7 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0204249992966652</threshold> + <left_val>0.6388130187988281</left_val> + <right_val>0.0381410010159016</right_val></_></_> + <_> + <!-- tree 196 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 6 19 3 -1.</_> + <_>1 7 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0124169997870922</threshold> + <left_val>-0.2154700011014938</left_val> + <right_val>0.4947769939899445</right_val></_></_></trees> + <stage_threshold>-3.2772979736328125</stage_threshold> + <parent>19</parent> + <next>-1</next></_> + <_> + <!-- stage 21 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 16 9 -1.</_> + <_>4 3 16 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0432740002870560</threshold> + <left_val>-0.8049439787864685</left_val> + <right_val>0.3989729881286621</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 5 -1.</_> + <_>8 1 8 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1861550062894821</threshold> + <left_val>-0.3165529966354370</left_val> + <right_val>0.6887729763984680</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 6 15 -1.</_> + <_>3 11 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0318609997630119</threshold> + <left_val>-0.6426619887351990</left_val> + <right_val>0.2555089890956879</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0140220001339912</threshold> + <left_val>-0.4592660069465637</left_val> + <right_val>0.3117119967937470</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 18 3 -1.</_> + <_>0 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.3029997982084751e-003</threshold> + <left_val>0.4602690041065216</left_val> + <right_val>-0.2743850052356720</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 22 18 2 -1.</_> + <_>6 23 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.4310001432895660e-003</threshold> + <left_val>0.3660860061645508</left_val> + <right_val>-0.2720580101013184</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 6 9 -1.</_> + <_>2 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0168229993432760</threshold> + <left_val>0.0234769992530346</left_val> + <right_val>-0.8844379782676697</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 12 6 9 -1.</_> + <_>18 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0260390006005764</threshold> + <left_val>0.1748879998922348</left_val> + <right_val>-0.5456470251083374</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 6 9 -1.</_> + <_>0 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0267200004309416</threshold> + <left_val>-0.9639649987220764</left_val> + <right_val>0.0235249996185303</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 14 4 10 -1.</_> + <_>11 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0170419998466969</threshold> + <left_val>-0.7084879875183106</left_val> + <right_val>0.2146809995174408</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 16 -1.</_> + <_>9 14 6 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.9569999575614929e-003</threshold> + <left_val>0.0736010000109673</left_val> + <right_val>-0.6822559833526611</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 10 10 -1.</_> + <_>7 12 10 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.8679999522864819e-003</threshold> + <left_val>-0.7493500113487244</left_val> + <right_val>0.2380339950323105</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 3 6 13 -1.</_> + <_>3 3 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0437749996781349</threshold> + <left_val>0.6832330226898193</left_val> + <right_val>-0.2138029932975769</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 1 6 13 -1.</_> + <_>18 1 3 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0516330003738403</threshold> + <left_val>-0.1256649941205978</left_val> + <right_val>0.6752380132675171</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 1 6 9 -1.</_> + <_>7 1 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.1780003383755684e-003</threshold> + <left_val>0.0706899985671043</left_val> + <right_val>-0.8066589832305908</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 2 6 11 -1.</_> + <_>18 2 3 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0528419986367226</threshold> + <left_val>0.9543390274047852</left_val> + <right_val>0.0165480002760887</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 11 -1.</_> + <_>3 2 3 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0525839999318123</threshold> + <left_val>-0.2841440141201019</left_val> + <right_val>0.4712980091571808</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 15 6 -1.</_> + <_>9 14 15 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0126590002328157</threshold> + <left_val>0.3844540119171143</left_val> + <right_val>-0.0622880011796951</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 20 3 -1.</_> + <_>2 3 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0116940001025796</threshold> + <left_val>5.6000000768108293e-005</left_val> + <right_val>-1.0173139572143555</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 9 -1.</_> + <_>10 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0239189993590117</threshold> + <left_val>0.8492130041122437</left_val> + <right_val>5.7399999350309372e-003</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 12 14 -1.</_> + <_>5 6 6 7 2.</_> + <_>11 13 6 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0616739988327026</threshold> + <left_val>-0.9257140159606934</left_val> + <right_val>-1.7679999582469463e-003</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 9 -1.</_> + <_>11 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.8279999494552612e-003</threshold> + <left_val>-0.5437229871749878</left_val> + <right_val>0.2493239939212799</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 9 6 -1.</_> + <_>10 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0352579988539219</threshold> + <left_val>-7.3719997890293598e-003</left_val> + <right_val>-0.9396399855613709</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 6 9 -1.</_> + <_>12 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0184380002319813</threshold> + <left_val>0.7213670015335083</left_val> + <right_val>0.0104919997975230</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 12 20 -1.</_> + <_>4 1 6 10 2.</_> + <_>10 11 6 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0383890010416508</threshold> + <left_val>0.1927260011434555</left_val> + <right_val>-0.3583210110664368</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 18 3 -1.</_> + <_>6 7 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0997209995985031</threshold> + <left_val>0.1135419979691505</left_val> + <right_val>-1.6304190158843994</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 18 3 -1.</_> + <_>9 7 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0844620019197464</threshold> + <left_val>-0.0534209981560707</left_val> + <right_val>-1.6981120109558105</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 20 18 3 -1.</_> + <_>9 20 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0402700006961823</threshold> + <left_val>-0.1078319996595383</left_val> + <right_val>0.5192660093307495</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0589359998703003</threshold> + <left_val>-0.1805370002985001</left_val> + <right_val>0.9511979818344116</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 2 12 15 -1.</_> + <_>10 2 4 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1495700031518936</threshold> + <left_val>0.1678529977798462</left_val> + <right_val>-1.1591869592666626</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 3 18 3 -1.</_> + <_>2 4 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.9399998756125569e-004</threshold> + <left_val>0.2049140036106110</left_val> + <right_val>-0.3311820030212402</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 4 4 18 -1.</_> + <_>21 4 2 9 2.</_> + <_>19 13 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0333690010011196</threshold> + <left_val>0.9346809983253479</left_val> + <right_val>-2.9639999847859144e-003</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 19 3 -1.</_> + <_>0 2 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.3759996816515923e-003</threshold> + <left_val>3.7000000011175871e-003</left_val> + <right_val>-0.7754979729652405</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 15 4 -1.</_> + <_>5 2 15 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0431939996778965</threshold> + <left_val>-2.2040000185370445e-003</left_val> + <right_val>0.7458969950675964</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 14 5 -1.</_> + <_>12 2 7 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0675550028681755</threshold> + <left_val>0.7229210138320923</left_val> + <right_val>-0.1840420067310333</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 22 14 -1.</_> + <_>1 2 11 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.3116860091686249</threshold> + <left_val>1.0014270544052124</left_val> + <right_val>0.0340030007064343</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 15 6 9 -1.</_> + <_>10 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0297439992427826</threshold> + <left_val>-0.0463560000061989</left_val> + <right_val>-1.2781809568405151</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 17 18 3 -1.</_> + <_>6 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0107370000332594</threshold> + <left_val>0.0148120000958443</left_val> + <right_val>0.6664999723434448</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 3 18 -1.</_> + <_>9 12 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0288410000503063</threshold> + <left_val>-0.9422259926795960</left_val> + <right_val>-0.0207969993352890</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 20 3 -1.</_> + <_>2 1 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.7649998925626278e-003</threshold> + <left_val>-0.4354189932346344</left_val> + <right_val>0.2338600009679794</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 5 12 -1.</_> + <_>5 8 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0284109991043806</threshold> + <left_val>-0.1761579960584641</left_val> + <right_val>0.8576530218124390</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 12 5 -1.</_> + <_>12 6 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0290079992264509</threshold> + <left_val>0.5797809958457947</left_val> + <right_val>0.0285659991204739</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 12 -1.</_> + <_>9 12 3 6 2.</_> + <_>12 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0249659996479750</threshold> + <left_val>-0.0227290000766516</left_val> + <right_val>-0.9677309989929199</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 14 8 10 -1.</_> + <_>18 14 4 5 2.</_> + <_>14 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0120360003784299</threshold> + <left_val>-0.1421470046043396</left_val> + <right_val>0.5168799757957459</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 14 8 10 -1.</_> + <_>2 14 4 5 2.</_> + <_>6 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0425140000879765</threshold> + <left_val>0.9727380275726318</left_val> + <right_val>-0.1811980009078980</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 18 12 6 -1.</_> + <_>16 18 6 3 2.</_> + <_>10 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0102760000154376</threshold> + <left_val>-0.0830999985337257</left_val> + <right_val>0.3176279962062836</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 3 6 9 -1.</_> + <_>1 6 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0691919997334480</threshold> + <left_val>-2.0668580532073975</left_val> + <right_val>-0.0601739995181561</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 3 3 20 -1.</_> + <_>12 3 1 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.6769999898970127e-003</threshold> + <left_val>0.4413180053234100</left_val> + <right_val>0.0232090000063181</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 14 6 -1.</_> + <_>4 6 7 3 2.</_> + <_>11 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0139239998534322</threshold> + <left_val>0.2860670089721680</left_val> + <right_val>-0.2915270030498505</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 12 13 -1.</_> + <_>10 5 4 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0153339998796582</threshold> + <left_val>-0.5741450190544128</left_val> + <right_val>0.2306330054998398</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 4 15 -1.</_> + <_>5 9 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0102390004321933</threshold> + <left_val>0.3447920083999634</left_val> + <right_val>-0.2608039975166321</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 16 15 4 -1.</_> + <_>14 16 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0509889982640743</threshold> + <left_val>0.5615410208702087</left_val> + <right_val>0.0612189993262291</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 6 14 -1.</_> + <_>7 8 3 7 2.</_> + <_>10 15 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0306899994611740</threshold> + <left_val>-0.1477279961109161</left_val> + <right_val>1.6378489732742310</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 10 6 -1.</_> + <_>7 8 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0112239997833967</threshold> + <left_val>0.2400619983673096</left_val> + <right_val>-0.4486489892005920</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 18 3 -1.</_> + <_>2 6 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.2899999320507050e-003</threshold> + <left_val>0.4311949908733368</left_val> + <right_val>-0.2380899935960770</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 1 15 8 -1.</_> + <_>5 5 15 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0785909965634346</threshold> + <left_val>0.0198650006204844</left_val> + <right_val>0.8085380196571350</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 8 18 -1.</_> + <_>7 10 8 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0101789999753237</threshold> + <left_val>0.1819320023059845</left_val> + <right_val>-0.3287779986858368</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 24 3 -1.</_> + <_>0 11 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0312270000576973</threshold> + <left_val>0.1497389972209930</left_val> + <right_val>-1.4180339574813843</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 13 -1.</_> + <_>2 2 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0401969999074936</threshold> + <left_val>-0.1976049989461899</left_val> + <right_val>0.5850819945335388</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 0 8 10 -1.</_> + <_>20 0 4 5 2.</_> + <_>16 5 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0161380004137754</threshold> + <left_val>5.0000002374872565e-004</left_val> + <right_val>0.3905000090599060</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 1 10 9 -1.</_> + <_>5 4 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0455190017819405</threshold> + <left_val>1.2646820545196533</left_val> + <right_val>-0.1563259959220886</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 18 3 -1.</_> + <_>5 7 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0181300006806850</threshold> + <left_val>0.6514850258827210</left_val> + <right_val>0.0102359997108579</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 3 -1.</_> + <_>0 2 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0140019999817014</threshold> + <left_val>-1.0344820022583008</left_val> + <right_val>-0.0321829989552498</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 4 6 11 -1.</_> + <_>13 4 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0388160012662411</threshold> + <left_val>-0.4787429869174957</left_val> + <right_val>0.1629070043563843</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 8 10 -1.</_> + <_>0 0 4 5 2.</_> + <_>4 5 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0316560007631779</threshold> + <left_val>-0.2098339945077896</left_val> + <right_val>0.5457590222358704</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 16 18 3 -1.</_> + <_>4 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0108399996533990</threshold> + <left_val>0.5189880132675171</left_val> + <right_val>-0.0150800002738833</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 16 18 3 -1.</_> + <_>2 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0120329996570945</threshold> + <left_val>-0.2110760062932968</left_val> + <right_val>0.7593700289726257</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 18 10 -1.</_> + <_>12 0 9 5 2.</_> + <_>3 5 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0707729980349541</threshold> + <left_val>0.1804880052804947</left_val> + <right_val>-0.7404850125312805</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 3 20 21 -1.</_> + <_>12 3 10 21 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.5313979983329773</threshold> + <left_val>-0.1449169963598251</left_val> + <right_val>1.5360039472579956</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 14 3 -1.</_> + <_>6 7 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0147740002721548</threshold> + <left_val>-0.2815369963645935</left_val> + <right_val>0.2040729969739914</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 12 6 -1.</_> + <_>0 9 6 3 2.</_> + <_>6 12 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.2410000674426556e-003</threshold> + <left_val>-0.4487630128860474</left_val> + <right_val>0.0539890006184578</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 14 21 4 -1.</_> + <_>10 14 7 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0499680005013943</threshold> + <left_val>0.0415140017867088</left_val> + <right_val>0.2941710054874420</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 21 4 -1.</_> + <_>7 14 7 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0477019995450974</threshold> + <left_val>0.3967429995536804</left_val> + <right_val>-0.2830179929733276</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 21 18 3 -1.</_> + <_>11 21 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0913110002875328</threshold> + <left_val>2.1994259357452393</left_val> + <right_val>0.0879649966955185</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 21 18 3 -1.</_> + <_>7 21 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0380700007081032</threshold> + <left_val>-0.2802560031414032</left_val> + <right_val>0.2515619993209839</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 4 4 18 -1.</_> + <_>21 4 2 9 2.</_> + <_>19 13 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0155389998108149</threshold> + <left_val>0.3415749967098236</left_val> + <right_val>0.0179249998182058</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 7 18 3 -1.</_> + <_>3 8 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0154459998011589</threshold> + <left_val>0.2868019938468933</left_val> + <right_val>-0.2513589859008789</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 4 4 18 -1.</_> + <_>21 4 2 9 2.</_> + <_>19 13 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0573880001902580</threshold> + <left_val>0.6383000016212463</left_val> + <right_val>0.0885979980230331</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 15 10 6 -1.</_> + <_>7 17 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.9440000914037228e-003</threshold> + <left_val>0.0790169984102249</left_val> + <right_val>-0.4077489972114563</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 13 11 9 -1.</_> + <_>9 16 11 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0699689984321594</threshold> + <left_val>-0.4464420080184937</left_val> + <right_val>0.1721960008144379</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 4 10 -1.</_> + <_>0 11 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0250649992376566</threshold> + <left_val>-0.9827020168304443</left_val> + <right_val>-0.0353880003094673</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 16 9 6 -1.</_> + <_>15 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0172160007059574</threshold> + <left_val>0.2270590066909790</left_val> + <right_val>-0.8055009841918945</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 4 18 -1.</_> + <_>1 5 2 9 2.</_> + <_>3 14 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0442790016531944</threshold> + <left_val>0.8395199775695801</left_val> + <right_val>-0.1742960065603256</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 8 10 -1.</_> + <_>13 8 4 5 2.</_> + <_>9 13 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0439889989793301</threshold> + <left_val>0.1155719980597496</left_val> + <right_val>-1.9666889905929565</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 8 10 -1.</_> + <_>7 8 4 5 2.</_> + <_>11 13 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0159070007503033</threshold> + <left_val>-0.0375760011374950</left_val> + <right_val>-1.0311100482940674</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 12 5 -1.</_> + <_>13 8 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0927549973130226</threshold> + <left_val>-1.3530019521713257</left_val> + <right_val>0.1214129999279976</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 9 7 -1.</_> + <_>10 8 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0710370019078255</threshold> + <left_val>-0.1768430024385452</left_val> + <right_val>0.7448520064353943</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 12 5 -1.</_> + <_>13 8 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0577620007097721</threshold> + <left_val>0.1283559948205948</left_val> + <right_val>-0.4444420039653778</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 9 7 -1.</_> + <_>10 6 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0164320003241301</threshold> + <left_val>0.8015270233154297</left_val> + <right_val>-0.1749169975519180</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 12 5 -1.</_> + <_>13 8 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0239390004426241</threshold> + <left_val>0.1614499986171722</left_val> + <right_val>-0.1236450001597405</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 4 18 -1.</_> + <_>10 11 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0126360002905130</threshold> + <left_val>0.1541199982166290</left_val> + <right_val>-0.3329379856586456</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 14 12 -1.</_> + <_>5 11 14 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0543479993939400</threshold> + <left_val>-1.8400700092315674</left_val> + <right_val>0.1483599990606308</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 11 4 -1.</_> + <_>0 3 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0132619999349117</threshold> + <left_val>-0.8083879947662354</left_val> + <right_val>-0.0277260001748800</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 10 6 10 -1.</_> + <_>11 10 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.1340001411736012e-003</threshold> + <left_val>-0.1378500014543533</left_val> + <right_val>0.3285849988460541</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 17 11 6 -1.</_> + <_>2 19 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0289910007268190</threshold> + <left_val>-0.0255169998854399</left_val> + <right_val>-0.8338720202445984</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 16 9 6 -1.</_> + <_>15 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0219860002398491</threshold> + <left_val>-0.7373999953269959</left_val> + <right_val>0.1788710057735443</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 18 2 -1.</_> + <_>1 11 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.3269998170435429e-003</threshold> + <left_val>-0.4544929862022400</left_val> + <right_val>0.0687910020351410</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 13 -1.</_> + <_>10 4 4 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0860479995608330</threshold> + <left_val>0.2100850045681000</left_val> + <right_val>-0.3780890107154846</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 18 18 3 -1.</_> + <_>0 19 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.5549997165799141e-003</threshold> + <left_val>0.4013499915599823</left_val> + <right_val>-0.2107409983873367</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 18 18 3 -1.</_> + <_>6 19 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.7790001630783081e-003</threshold> + <left_val>-0.0216489993035793</left_val> + <right_val>0.4542149901390076</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 9 6 -1.</_> + <_>0 18 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.3959998078644276e-003</threshold> + <left_val>-0.4981859922409058</left_val> + <right_val>0.0759079977869987</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 15 9 6 -1.</_> + <_>13 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.9469999074935913e-003</threshold> + <left_val>0.1785770058631897</left_val> + <right_val>-0.2845489978790283</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 15 9 6 -1.</_> + <_>2 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.2589999027550220e-003</threshold> + <left_val>0.0466249994933605</left_val> + <right_val>-0.5520629882812500</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 1 6 16 -1.</_> + <_>13 1 3 16 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0414769984781742</threshold> + <left_val>0.1755049973726273</left_val> + <right_val>-0.2070399969816208</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 1 6 16 -1.</_> + <_>8 1 3 16 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.7449999041855335e-003</threshold> + <left_val>-0.4639259874820709</left_val> + <right_val>0.0693039968609810</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 5 6 10 -1.</_> + <_>13 5 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0305649992078543</threshold> + <left_val>0.0517349988222122</left_val> + <right_val>0.7555050253868103</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 6 10 -1.</_> + <_>9 5 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.4780001305043697e-003</threshold> + <left_val>0.1489389985799789</left_val> + <right_val>-0.3190680146217346</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 6 24 -1.</_> + <_>12 0 2 24 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0890889987349510</threshold> + <left_val>0.1373880058526993</left_val> + <right_val>-1.1379710435867310</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 4 20 -1.</_> + <_>3 4 2 10 2.</_> + <_>5 14 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.3230001144111156e-003</threshold> + <left_val>-0.2882919907569885</left_val> + <right_val>0.1908860057592392</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 6 9 -1.</_> + <_>16 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0182050000876188</threshold> + <left_val>-0.3017860054969788</left_val> + <right_val>0.1679580062627792</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 6 9 -1.</_> + <_>6 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0258280001580715</threshold> + <left_val>-0.9813799858093262</left_val> + <right_val>-0.0198609996587038</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 5 18 5 -1.</_> + <_>10 5 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1093619987368584</threshold> + <left_val>0.0487900003790855</left_val> + <right_val>0.5311830043792725</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 6 9 -1.</_> + <_>7 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0114249996840954</threshold> + <left_val>0.2370599955320358</left_val> + <right_val>-0.2792530059814453</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 2 15 8 -1.</_> + <_>12 2 5 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0575659982860088</threshold> + <left_val>0.4725539982318878</left_val> + <right_val>0.0651710033416748</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 15 8 -1.</_> + <_>7 2 5 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1027830019593239</threshold> + <left_val>-0.2076510041952133</left_val> + <right_val>0.5094770193099976</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 4 9 -1.</_> + <_>10 0 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0270419996231794</threshold> + <left_val>0.1642120033502579</left_val> + <right_val>-1.4508620500564575</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 6 12 -1.</_> + <_>3 4 3 6 2.</_> + <_>6 10 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0136350002139807</threshold> + <left_val>-0.5654389858245850</left_val> + <right_val>0.0237889997661114</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 0 8 18 -1.</_> + <_>16 0 4 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.3215819895267487</threshold> + <left_val>-3.5602829456329346</left_val> + <right_val>0.1180130019783974</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 8 18 -1.</_> + <_>4 0 4 18 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2045810073614121</threshold> + <left_val>-0.0370160005986691</left_val> + <right_val>-1.0225499868392944</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 24 6 -1.</_> + <_>0 9 24 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0703470036387444</threshold> + <left_val>-0.5649189949035645</left_val> + <right_val>0.1852519959211350</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 14 3 -1.</_> + <_>11 7 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0378310009837151</threshold> + <left_val>-0.0299019999802113</left_val> + <right_val>-0.8292149901390076</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 8 8 15 -1.</_> + <_>10 8 4 15 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0702980011701584</threshold> + <left_val>-0.5317230224609375</left_val> + <right_val>0.1443019956350327</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 10 14 -1.</_> + <_>12 0 5 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0632210001349449</threshold> + <left_val>-0.2204120010137558</left_val> + <right_val>0.4795219898223877</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 10 8 10 -1.</_> + <_>17 10 4 5 2.</_> + <_>13 15 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0363930016756058</threshold> + <left_val>0.1422269940376282</left_val> + <right_val>-0.6119390130043030</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 4 9 -1.</_> + <_>5 0 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.0099998004734516e-003</threshold> + <left_val>-0.3456079959869385</left_val> + <right_val>0.1173869967460632</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 1 6 8 -1.</_> + <_>16 1 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0491060018539429</threshold> + <left_val>0.9598410129547119</left_val> + <right_val>0.0649349987506866</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 1 6 8 -1.</_> + <_>5 1 3 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0715830028057098</threshold> + <left_val>1.7385669946670532</left_val> + <right_val>-0.1425289958715439</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 12 -1.</_> + <_>3 10 18 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0380089990794659</threshold> + <left_val>1.3872820138931274</left_val> + <right_val>0.0661880001425743</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 16 4 -1.</_> + <_>4 14 16 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.1570000573992729e-003</threshold> + <left_val>0.0536770001053810</left_val> + <right_val>-0.5404800176620483</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 9 16 15 -1.</_> + <_>4 14 16 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0194589998573065</threshold> + <left_val>-0.0936200022697449</left_val> + <right_val>0.3913100063800812</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 8 10 -1.</_> + <_>3 10 4 5 2.</_> + <_>7 15 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0112939998507500</threshold> + <left_val>0.0372239984571934</left_val> + <right_val>-0.5425180196762085</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 16 6 -1.</_> + <_>16 18 8 3 2.</_> + <_>8 21 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0334950014948845</threshold> + <left_val>0.9530789852142334</left_val> + <right_val>0.0376969985663891</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 16 12 5 -1.</_> + <_>6 16 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0920350030064583</threshold> + <left_val>-0.1348839998245239</left_val> + <right_val>2.2897069454193115</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 14 9 4 -1.</_> + <_>14 16 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.7529999390244484e-003</threshold> + <left_val>0.2282419949769974</left_val> + <right_val>-0.5998370051383972</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 14 9 6 -1.</_> + <_>7 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0128480000421405</threshold> + <left_val>-0.2200520038604736</left_val> + <right_val>0.3722189962863922</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 10 16 12 -1.</_> + <_>4 14 16 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1431619971990585</threshold> + <left_val>1.2855789661407471</left_val> + <right_val>0.0472370013594627</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 19 6 -1.</_> + <_>0 15 19 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0968799963593483</threshold> + <left_val>-3.9550929069519043</left_val> + <right_val>-0.0729039981961250</right_val></_></_> + <_> + <!-- tree 137 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 13 9 6 -1.</_> + <_>10 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.8459998369216919e-003</threshold> + <left_val>0.3767499923706055</left_val> + <right_val>-0.0464840009808540</right_val></_></_> + <_> + <!-- tree 138 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 3 23 -1.</_> + <_>6 0 1 23 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0159000009298325</threshold> + <left_val>-0.0244570001959801</left_val> + <right_val>-0.8003479838371277</right_val></_></_> + <_> + <!-- tree 139 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 24 6 -1.</_> + <_>0 10 24 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0703720003366470</threshold> + <left_val>0.1701900064945221</left_val> + <right_val>-0.6306899785995483</right_val></_></_> + <_> + <!-- tree 140 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 5 12 -1.</_> + <_>0 9 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0379539988934994</threshold> + <left_val>-0.9366719722747803</left_val> + <right_val>-0.0412140004336834</right_val></_></_> + <_> + <!-- tree 141 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 19 18 -1.</_> + <_>3 9 19 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.5159789919853210</threshold> + <left_val>0.1308059990406036</left_val> + <right_val>-1.5802290439605713</right_val></_></_> + <_> + <!-- tree 142 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 11 6 12 -1.</_> + <_>9 11 3 6 2.</_> + <_>12 17 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0328430011868477</threshold> + <left_val>-1.1441620588302612</left_val> + <right_val>-0.0491739995777607</right_val></_></_> + <_> + <!-- tree 143 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 24 8 -1.</_> + <_>12 5 12 4 2.</_> + <_>0 9 12 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0363570004701614</threshold> + <left_val>0.4960640072822571</left_val> + <right_val>-0.0344589985907078</right_val></_></_> + <_> + <!-- tree 144 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 18 9 4 -1.</_> + <_>6 20 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.8080001510679722e-003</threshold> + <left_val>-0.3099780082702637</left_val> + <right_val>0.1705480068922043</right_val></_></_> + <_> + <!-- tree 145 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 10 6 -1.</_> + <_>8 10 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0161140002310276</threshold> + <left_val>-0.3790459930896759</left_val> + <right_val>0.1607899963855743</right_val></_></_> + <_> + <!-- tree 146 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 20 3 -1.</_> + <_>2 8 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.4530003368854523e-003</threshold> + <left_val>-0.1865549981594086</left_val> + <right_val>0.5636770129203796</right_val></_></_> + <_> + <!-- tree 147 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 7 20 -1.</_> + <_>12 10 7 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1375239938497543</threshold> + <left_val>-0.5898990035057068</left_val> + <right_val>0.1174950003623962</right_val></_></_> + <_> + <!-- tree 148 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 7 20 -1.</_> + <_>5 10 7 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1768800020217896</threshold> + <left_val>-0.1542489975690842</left_val> + <right_val>0.9291110038757324</right_val></_></_> + <_> + <!-- tree 149 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 2 2 18 -1.</_> + <_>14 11 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.9309996217489243e-003</threshold> + <left_val>0.3219070136547089</left_val> + <right_val>-0.1639260053634644</right_val></_></_> + <_> + <!-- tree 150 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 10 12 -1.</_> + <_>10 8 5 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1097180023789406</threshold> + <left_val>-0.1587650030851364</left_val> + <right_val>1.0186259746551514</right_val></_></_> + <_> + <!-- tree 151 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 12 8 -1.</_> + <_>12 9 6 4 2.</_> + <_>6 13 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0302930008620024</threshold> + <left_val>0.7558730244636536</left_val> + <right_val>0.0317949987947941</right_val></_></_> + <_> + <!-- tree 152 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 3 14 -1.</_> + <_>7 14 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0231180004775524</threshold> + <left_val>-0.8845149874687195</left_val> + <right_val>-9.5039997249841690e-003</right_val></_></_> + <_> + <!-- tree 153 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 2 12 16 -1.</_> + <_>17 2 6 8 2.</_> + <_>11 10 6 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.0900000128895044e-003</threshold> + <left_val>0.2383829951286316</left_val> + <right_val>-0.1160620003938675</right_val></_></_> + <_> + <!-- tree 154 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 6 9 -1.</_> + <_>9 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0333920009434223</threshold> + <left_val>-1.8738139867782593</left_val> + <right_val>-0.0685029998421669</right_val></_></_> + <_> + <!-- tree 155 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 14 9 4 -1.</_> + <_>13 16 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0131900003179908</threshold> + <left_val>0.1291989982128143</left_val> + <right_val>-0.6751220226287842</right_val></_></_> + <_> + <!-- tree 156 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 22 4 -1.</_> + <_>0 12 11 2 2.</_> + <_>11 14 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0146610001102090</threshold> + <left_val>-0.0248290002346039</left_val> + <right_val>-0.7439680099487305</right_val></_></_> + <_> + <!-- tree 157 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 12 22 6 -1.</_> + <_>12 12 11 3 2.</_> + <_>1 15 11 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0132480002939701</threshold> + <left_val>0.4682019948959351</left_val> + <right_val>-0.0241650007665157</right_val></_></_> + <_> + <!-- tree 158 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 9 6 -1.</_> + <_>9 6 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0162189994007349</threshold> + <left_val>0.4008379876613617</left_val> + <right_val>-0.2125570029020309</right_val></_></_> + <_> + <!-- tree 159 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 4 9 -1.</_> + <_>10 0 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0290520004928112</threshold> + <left_val>-1.5650019645690918</left_val> + <right_val>0.1437589973211289</right_val></_></_> + <_> + <!-- tree 160 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 8 18 7 -1.</_> + <_>9 8 6 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1015319973230362</threshold> + <left_val>-1.9220689535140991</left_val> + <right_val>-0.0695599988102913</right_val></_></_> + <_> + <!-- tree 161 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 24 6 -1.</_> + <_>0 8 24 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0377539992332459</threshold> + <left_val>0.1339679956436157</left_val> + <right_val>-2.2639141082763672</right_val></_></_> + <_> + <!-- tree 162 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 24 10 -1.</_> + <_>8 11 8 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2855559885501862</threshold> + <left_val>1.0215270519256592</left_val> + <right_val>-0.1523219943046570</right_val></_></_> + <_> + <!-- tree 163 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 3 18 21 -1.</_> + <_>9 3 6 21 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1536069959402084</threshold> + <left_val>-0.0974090024828911</left_val> + <right_val>0.4166240096092224</right_val></_></_> + <_> + <!-- tree 164 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 12 4 10 -1.</_> + <_>9 12 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.1199999901000410e-004</threshold> + <left_val>0.1127189993858337</left_val> + <right_val>-0.4165399968624115</right_val></_></_> + <_> + <!-- tree 165 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 16 10 8 -1.</_> + <_>15 16 5 4 2.</_> + <_>10 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0205979999154806</threshold> + <left_val>0.6054049730300903</left_val> + <right_val>0.0624679997563362</right_val></_></_> + <_> + <!-- tree 166 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 6 9 -1.</_> + <_>10 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0373539999127388</threshold> + <left_val>-0.1891900002956390</left_val> + <right_val>0.4646469950675964</right_val></_></_> + <_> + <!-- tree 167 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 10 6 12 -1.</_> + <_>15 10 3 6 2.</_> + <_>12 16 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0572750009596348</threshold> + <left_val>0.1156530007719994</left_val> + <right_val>-1.3213009834289551</right_val></_></_> + <_> + <!-- tree 168 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 10 6 12 -1.</_> + <_>6 10 3 6 2.</_> + <_>9 16 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.1029999740421772e-003</threshold> + <left_val>-0.2806150019168854</left_val> + <right_val>0.1931339949369431</right_val></_></_> + <_> + <!-- tree 169 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 12 6 12 -1.</_> + <_>19 12 3 6 2.</_> + <_>16 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0546449981629848</threshold> + <left_val>0.7242850065231323</left_val> + <right_val>0.0754479989409447</right_val></_></_> + <_> + <!-- tree 170 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 6 12 -1.</_> + <_>2 12 3 6 2.</_> + <_>5 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0253490004688501</threshold> + <left_val>-0.1948180049657822</left_val> + <right_val>0.4603280127048492</right_val></_></_> + <_> + <!-- tree 171 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 15 6 9 -1.</_> + <_>12 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0243110004812479</threshold> + <left_val>0.1556410044431686</left_val> + <right_val>-0.4991390109062195</right_val></_></_> + <_> + <!-- tree 172 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 15 6 9 -1.</_> + <_>10 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0359620004892349</threshold> + <left_val>-0.0585730001330376</left_val> + <right_val>-1.5418399572372437</right_val></_></_> + <_> + <!-- tree 173 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 20 10 4 -1.</_> + <_>14 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1000069975852966</threshold> + <left_val>-1.6100039482116699</left_val> + <right_val>0.1145050004124641</right_val></_></_> + <_> + <!-- tree 174 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 20 10 4 -1.</_> + <_>5 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0844359993934631</threshold> + <left_val>-0.0614069998264313</left_val> + <right_val>-1.4673349857330322</right_val></_></_> + <_> + <!-- tree 175 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 17 9 6 -1.</_> + <_>11 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0159479994326830</threshold> + <left_val>0.1628790050745010</left_val> + <right_val>-0.1102640032768250</right_val></_></_> + <_> + <!-- tree 176 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 14 4 -1.</_> + <_>3 4 14 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0338240005075932</threshold> + <left_val>-0.1793269962072372</left_val> + <right_val>0.5721840262413025</right_val></_></_> + <_> + <!-- tree 177 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 1 10 4 -1.</_> + <_>10 3 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0619960017502308</threshold> + <left_val>4.6511812210083008</left_val> + <right_val>0.0945340022444725</right_val></_></_> + <_> + <!-- tree 178 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 10 4 -1.</_> + <_>5 15 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0698769986629486</threshold> + <left_val>-0.1698590070009232</left_val> + <right_val>0.8702899813652039</right_val></_></_> + <_> + <!-- tree 179 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 2 3 19 -1.</_> + <_>20 2 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0279169995337725</threshold> + <left_val>0.9104250073432922</left_val> + <right_val>0.0568270012736321</right_val></_></_> + <_> + <!-- tree 180 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 9 8 -1.</_> + <_>7 12 3 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0127640003338456</threshold> + <left_val>0.2206670045852661</left_val> + <right_val>-0.2776910066604614</right_val></_></_></trees> + <stage_threshold>-3.3196411132812500</stage_threshold> + <parent>20</parent> + <next>-1</next></_> + <_> + <!-- stage 22 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 5 12 -1.</_> + <_>4 11 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0216620005667210</threshold> + <left_val>-0.8986889719963074</left_val> + <right_val>0.2943629920482636</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 3 -1.</_> + <_>8 1 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1004450023174286</threshold> + <left_val>-0.3765920102596283</left_val> + <right_val>0.6089100241661072</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 12 4 -1.</_> + <_>6 10 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0260039996355772</threshold> + <left_val>-0.3812850117683411</left_val> + <right_val>0.3921740055084229</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 3 4 10 -1.</_> + <_>19 3 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0284410007297993</threshold> + <left_val>-0.1818230003118515</left_val> + <right_val>0.5892720222473145</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 9 6 -1.</_> + <_>3 6 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0386120006442070</threshold> + <left_val>-0.2239959985017777</left_val> + <right_val>0.6377999782562256</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 0 6 22 -1.</_> + <_>20 0 2 22 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0465949997305870</threshold> + <left_val>0.7081220149993897</left_val> + <right_val>-0.1466619968414307</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 22 -1.</_> + <_>2 0 2 22 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0427919998764992</threshold> + <left_val>0.4768039882183075</left_val> + <right_val>-0.2923319935798645</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 15 19 3 -1.</_> + <_>5 16 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.7960000336170197e-003</threshold> + <left_val>-0.1851029992103577</left_val> + <right_val>0.5262669920921326</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 7 4 15 -1.</_> + <_>10 12 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0423489995300770</threshold> + <left_val>0.0392449982464314</left_val> + <right_val>-0.8919770121574402</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0195989999920130</threshold> + <left_val>-0.2335840016603470</left_val> + <right_val>0.4414649903774262</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 21 18 3 -1.</_> + <_>0 22 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.7400001939386129e-004</threshold> + <left_val>-0.4606359899044037</left_val> + <right_val>0.1768960058689117</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 3 10 15 -1.</_> + <_>7 8 10 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.3629999272525311e-003</threshold> + <left_val>0.3349319994449616</left_val> + <right_val>-0.2989340126514435</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 7 18 3 -1.</_> + <_>1 8 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0169730000197887</threshold> + <left_val>-0.1640869975090027</left_val> + <right_val>1.5993679761886597</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 9 6 -1.</_> + <_>11 2 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0360639989376068</threshold> + <left_val>0.2260169982910156</left_val> + <right_val>-0.5318610072135925</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 24 14 -1.</_> + <_>0 17 24 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0708649978041649</threshold> + <left_val>0.1522050052881241</left_val> + <right_val>-0.4191460013389587</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 9 8 10 -1.</_> + <_>17 9 4 5 2.</_> + <_>13 14 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0630759969353676</threshold> + <left_val>-1.4874019622802734</left_val> + <right_val>0.1295370012521744</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 4 9 -1.</_> + <_>12 5 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0296700000762939</threshold> + <left_val>-0.1914590001106262</left_val> + <right_val>0.9818490147590637</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 9 8 10 -1.</_> + <_>17 9 4 5 2.</_> + <_>13 14 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0378739982843399</threshold> + <left_val>0.1345950067043304</left_val> + <right_val>-0.5631629824638367</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 11 10 10 -1.</_> + <_>7 11 5 5 2.</_> + <_>12 16 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0332890003919601</threshold> + <left_val>-1.0828030109405518</left_val> + <right_val>-0.0115040000528097</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 18 4 -1.</_> + <_>13 13 9 2 2.</_> + <_>4 15 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0316089987754822</threshold> + <left_val>-0.5922449827194214</left_val> + <right_val>0.1339479982852936</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 19 2 -1.</_> + <_>0 1 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.0740000288933516e-003</threshold> + <left_val>-0.4918580055236816</left_val> + <right_val>0.0944460034370422</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 18 24 6 -1.</_> + <_>8 18 8 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0715560019016266</threshold> + <left_val>0.5971019864082336</left_val> + <right_val>-0.0395530015230179</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 8 16 -1.</_> + <_>6 12 8 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0811700001358986</threshold> + <left_val>-1.1817820072174072</left_val> + <right_val>-0.0282540004700422</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 10 4 -1.</_> + <_>7 10 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.4860001653432846e-003</threshold> + <left_val>-0.6102809906005859</left_val> + <right_val>0.2261909991502762</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 9 -1.</_> + <_>0 6 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0421760007739067</threshold> + <left_val>-1.1435619592666626</left_val> + <right_val>-0.0290019996464252</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 15 7 9 -1.</_> + <_>13 18 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0656400024890900</threshold> + <left_val>-1.6470279693603516</left_val> + <right_val>0.1281030029058456</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 12 6 -1.</_> + <_>3 18 6 3 2.</_> + <_>9 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0181889999657869</threshold> + <left_val>-0.3114939928054810</left_val> + <right_val>0.2573960125446320</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 14 6 9 -1.</_> + <_>12 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0515200011432171</threshold> + <left_val>-0.6920689940452576</left_val> + <right_val>0.1527079939842224</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 15 15 8 -1.</_> + <_>2 19 15 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0471509993076324</threshold> + <left_val>-0.7186830043792725</left_val> + <right_val>2.6879999786615372e-003</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 16 -1.</_> + <_>9 14 6 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0174889992922544</threshold> + <left_val>0.2237119972705841</left_val> + <right_val>-0.5538179874420166</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 7 12 -1.</_> + <_>6 10 7 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0252640005201101</threshold> + <left_val>1.0319819450378418</left_val> + <right_val>-0.1749649941921234</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 6 6 9 -1.</_> + <_>14 9 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0407450012862682</threshold> + <left_val>0.4496159851551056</left_val> + <right_val>0.0393490009009838</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 14 6 9 -1.</_> + <_>5 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0376669988036156</threshold> + <left_val>-0.8547570109367371</left_val> + <right_val>-0.0124639999121428</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 8 6 9 -1.</_> + <_>12 8 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0134110003709793</threshold> + <left_val>0.5784559845924377</left_val> + <right_val>-0.0174679998308420</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 4 18 -1.</_> + <_>6 6 2 9 2.</_> + <_>8 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.8999997640494257e-005</threshold> + <left_val>-0.3774920105934143</left_val> + <right_val>0.1396179944276810</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 9 6 12 -1.</_> + <_>17 9 3 6 2.</_> + <_>14 15 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0114150000736117</threshold> + <left_val>-0.2618660032749176</left_val> + <right_val>0.2371249943971634</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 9 6 12 -1.</_> + <_>4 9 3 6 2.</_> + <_>7 15 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0372000001370907</threshold> + <left_val>-0.0286260005086660</left_val> + <right_val>-1.2945239543914795</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 15 9 6 -1.</_> + <_>14 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.4050000831484795e-003</threshold> + <left_val>0.2053139954805374</left_val> + <right_val>-0.1874749958515167</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 20 18 4 -1.</_> + <_>0 20 9 2 2.</_> + <_>9 22 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0224830005317926</threshold> + <left_val>0.6702719926834106</left_val> + <right_val>-0.1959400027990341</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 18 9 6 -1.</_> + <_>13 20 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0232749991118908</threshold> + <left_val>0.1740539968013763</left_val> + <right_val>-0.3274630010128021</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 18 9 6 -1.</_> + <_>2 20 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0139170000329614</threshold> + <left_val>-0.8395429849624634</left_val> + <right_val>-6.3760001212358475e-003</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 18 3 -1.</_> + <_>6 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.5429999269545078e-003</threshold> + <left_val>-0.0341949984431267</left_val> + <right_val>0.5899819731712341</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 18 3 -1.</_> + <_>0 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0115390000864863</threshold> + <left_val>0.4214279949665070</left_val> + <right_val>-0.2351049929857254</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 2 4 22 -1.</_> + <_>21 2 2 11 2.</_> + <_>19 13 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0525019988417625</threshold> + <left_val>0.0693039968609810</left_val> + <right_val>0.7322649955749512</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 2 4 22 -1.</_> + <_>1 2 2 11 2.</_> + <_>3 13 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0527159981429577</threshold> + <left_val>-0.1568810045719147</left_val> + <right_val>1.0907289981842041</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 2 24 -1.</_> + <_>15 0 1 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0117260003462434</threshold> + <left_val>-0.7093430161476135</left_val> + <right_val>0.1682880073785782</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 20 16 4 -1.</_> + <_>11 20 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0959459990262985</threshold> + <left_val>-0.1619289964437485</left_val> + <right_val>1.0072519779205322</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 4 18 -1.</_> + <_>13 6 2 9 2.</_> + <_>11 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0158719997853041</threshold> + <left_val>0.3900839984416962</left_val> + <right_val>-0.0537770017981529</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 9 10 14 -1.</_> + <_>7 9 5 7 2.</_> + <_>12 16 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0348180010914803</threshold> + <left_val>0.0171799995005131</left_val> + <right_val>-0.9394180178642273</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 6 6 9 -1.</_> + <_>14 9 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0347919985651970</threshold> + <left_val>0.0504629984498024</left_val> + <right_val>0.5446569919586182</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 7 9 -1.</_> + <_>3 9 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0162840001285076</threshold> + <left_val>-0.2698130011558533</left_val> + <right_val>0.4036529958248138</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 4 4 20 -1.</_> + <_>22 4 2 10 2.</_> + <_>20 14 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0443190000951290</threshold> + <left_val>0.8439999818801880</left_val> + <right_val>0.0328829996287823</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 6 9 -1.</_> + <_>7 9 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.5689997971057892e-003</threshold> + <left_val>0.1530939936637878</left_val> + <right_val>-0.3495979905128479</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 10 14 -1.</_> + <_>12 0 5 7 2.</_> + <_>7 7 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0658420026302338</threshold> + <left_val>-0.9271119832992554</left_val> + <right_val>0.1680099964141846</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 1 18 6 -1.</_> + <_>11 1 9 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0733370035886765</threshold> + <left_val>0.5161449909210205</left_val> + <right_val>-0.2023600041866303</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 2 24 -1.</_> + <_>15 0 1 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0164500009268522</threshold> + <left_val>0.1395059973001480</left_val> + <right_val>-0.4930129945278168</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 2 24 -1.</_> + <_>8 0 1 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.2630004510283470e-003</threshold> + <left_val>-0.9010199904441834</left_val> + <right_val>-0.0161160007119179</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 12 6 7 -1.</_> + <_>13 12 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.9139998629689217e-003</threshold> + <left_val>0.1985819935798645</left_val> + <right_val>-0.1673129945993424</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 12 6 7 -1.</_> + <_>8 12 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.4699998842552304e-004</threshold> + <left_val>0.0940050035715103</left_val> + <right_val>-0.4157089889049530</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 18 19 -1.</_> + <_>9 5 6 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2053290009498596</threshold> + <left_val>-0.0600220002233982</left_val> + <right_val>0.7099360227584839</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 9 6 -1.</_> + <_>8 6 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0168830007314682</threshold> + <left_val>0.2439219951629639</left_val> + <right_val>-0.3055180013179779</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 9 6 -1.</_> + <_>12 5 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0191110000014305</threshold> + <left_val>0.6122990250587463</left_val> + <right_val>0.0242529995739460</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 16 10 8 -1.</_> + <_>3 16 5 4 2.</_> + <_>8 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0259629990905523</threshold> + <left_val>0.9076499938964844</left_val> + <right_val>-0.1672209948301315</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 8 5 15 -1.</_> + <_>19 13 5 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0217620003968477</threshold> + <left_val>-0.3138470053672791</left_val> + <right_val>0.2013459950685501</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 5 15 -1.</_> + <_>0 13 5 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0241199992597103</threshold> + <left_val>-0.6658840179443359</left_val> + <right_val>7.4559999629855156e-003</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 4 4 20 -1.</_> + <_>22 4 2 10 2.</_> + <_>20 14 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0471299998462200</threshold> + <left_val>0.0595339983701706</left_val> + <right_val>0.8780450224876404</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 4 20 -1.</_> + <_>0 4 2 10 2.</_> + <_>2 14 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0459849983453751</threshold> + <left_val>0.8006799817085266</left_val> + <right_val>-0.1725230067968369</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 10 4 -1.</_> + <_>7 7 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0265079997479916</threshold> + <left_val>0.1877409964799881</left_val> + <right_val>-0.6085060238838196</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 19 14 4 -1.</_> + <_>11 19 7 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0486150011420250</threshold> + <left_val>0.5864409804344177</left_val> + <right_val>-0.1942770034074783</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 11 12 3 -1.</_> + <_>10 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0185620002448559</threshold> + <left_val>-0.2558790147304535</left_val> + <right_val>0.1632619947195053</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 3 -1.</_> + <_>0 2 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0126780001446605</threshold> + <left_val>-0.0142280003055930</left_val> + <right_val>-0.7673810124397278</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 2 14 20 -1.</_> + <_>14 2 7 10 2.</_> + <_>7 12 7 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.1919999960809946e-003</threshold> + <left_val>0.2049500048160553</left_val> + <right_val>-0.1140429973602295</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 6 9 -1.</_> + <_>2 13 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0490889996290207</threshold> + <left_val>-1.0740849971771240</left_val> + <right_val>-0.0389409996569157</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 4 19 -1.</_> + <_>13 0 2 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0174369998276234</threshold> + <left_val>-0.5797380208969116</left_val> + <right_val>0.1858450025320053</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 11 14 3 -1.</_> + <_>8 11 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0147700002416968</threshold> + <left_val>-0.6615030169487000</left_val> + <right_val>5.3119999356567860e-003</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 16 20 -1.</_> + <_>15 1 8 10 2.</_> + <_>7 11 8 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2290520071983337</threshold> + <left_val>-0.4830510020256043</left_val> + <right_val>0.1232639998197556</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 21 9 -1.</_> + <_>7 10 7 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1270709931850433</threshold> + <left_val>0.5745260119438171</left_val> + <right_val>-0.1942040026187897</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 19 15 5 -1.</_> + <_>11 19 5 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0103390002623200</threshold> + <left_val>-0.0546419993042946</left_val> + <right_val>0.2450180053710938</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 10 6 6 -1.</_> + <_>11 10 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.9010001607239246e-003</threshold> + <left_val>0.1218060031533241</left_val> + <right_val>-0.3879739940166473</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 1 16 20 -1.</_> + <_>15 1 8 10 2.</_> + <_>7 11 8 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2902539968490601</threshold> + <left_val>0.1096619963645935</left_val> + <right_val>-30.</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 16 20 -1.</_> + <_>1 1 8 10 2.</_> + <_>9 11 8 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2380499988794327</threshold> + <left_val>-1.7352679967880249</left_val> + <right_val>-0.0638099983334541</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 4 3 12 -1.</_> + <_>16 10 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0624810010194778</threshold> + <left_val>0.1352300047874451</left_val> + <right_val>-0.7030109763145447</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 3 12 -1.</_> + <_>5 10 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.7109997831285000e-003</threshold> + <left_val>-0.4698410034179688</left_val> + <right_val>0.0603419989347458</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 10 8 -1.</_> + <_>12 6 5 4 2.</_> + <_>7 10 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0278159994632006</threshold> + <left_val>0.6980760097503662</left_val> + <right_val>1.3719999697059393e-003</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 9 6 6 -1.</_> + <_>4 12 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0170200001448393</threshold> + <left_val>1.6870440244674683</left_val> + <right_val>-0.1431480050086975</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 12 4 -1.</_> + <_>6 7 12 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0497549995779991</threshold> + <left_val>0.7949770092964172</left_val> + <right_val>7.7199999941512942e-004</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 2 5 15 -1.</_> + <_>9 7 5 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0747329965233803</threshold> + <left_val>-1.0132360458374023</left_val> + <right_val>-0.0193889997899532</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 9 6 -1.</_> + <_>15 2 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0320090018212795</threshold> + <left_val>0.1441210061311722</left_val> + <right_val>-0.4213910102844238</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 11 10 -1.</_> + <_>6 5 11 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0944639965891838</threshold> + <left_val>0.5068259835243225</left_val> + <right_val>-0.2047889977693558</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 7 4 12 -1.</_> + <_>12 13 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0154269998893142</threshold> + <left_val>-0.1581130027770996</left_val> + <right_val>0.1780689954757690</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 2 9 4 -1.</_> + <_>7 4 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.0540001355111599e-003</threshold> + <left_val>-0.5436670184135437</left_val> + <right_val>0.0312350001186132</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 13 6 -1.</_> + <_>6 2 13 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.0080000869929790e-003</threshold> + <left_val>-0.1737679988145828</left_val> + <right_val>0.3044170141220093</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 18 -1.</_> + <_>10 6 2 9 2.</_> + <_>12 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0100919995456934</threshold> + <left_val>0.2510380148887634</left_val> + <right_val>-0.2622410058975220</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 8 6 9 -1.</_> + <_>12 8 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0388180017471313</threshold> + <left_val>0.9322670102119446</left_val> + <right_val>0.0726599991321564</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 18 10 6 -1.</_> + <_>3 20 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0346519984304905</threshold> + <left_val>-0.0339349992573261</left_val> + <right_val>-0.8570790290832520</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 14 20 3 -1.</_> + <_>4 15 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.6729999594390392e-003</threshold> + <left_val>0.3496930003166199</left_val> + <right_val>-0.0485179983079433</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 15 9 6 -1.</_> + <_>2 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.8499997723847628e-004</threshold> + <left_val>0.0665730014443398</left_val> + <right_val>-0.4497379958629608</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 4 19 -1.</_> + <_>13 0 2 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0353170000016689</threshold> + <left_val>0.1427579969167709</left_val> + <right_val>-0.4672639966011047</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 4 19 -1.</_> + <_>9 0 2 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0235699992626905</threshold> + <left_val>-1.0286079645156860</left_val> + <right_val>-0.0452880002558231</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 4 22 2 -1.</_> + <_>1 5 22 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.9109999993816018e-003</threshold> + <left_val>-0.1965219974517822</left_val> + <right_val>0.2866100072860718</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 9 6 -1.</_> + <_>0 2 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0166590008884668</threshold> + <left_val>-0.7753220200538635</left_val> + <right_val>-8.3280000835657120e-003</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 24 18 -1.</_> + <_>0 9 24 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.6606220006942749</threshold> + <left_val>0.1323249936103821</left_val> + <right_val>-3.5266680717468262</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 16 8 -1.</_> + <_>3 6 16 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1097059994935989</threshold> + <left_val>-0.1554719954729080</left_val> + <right_val>1.4674140214920044</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 6 18 6 -1.</_> + <_>3 8 18 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0135009996592999</threshold> + <left_val>0.1523340046405792</left_val> + <right_val>-1.3020930290222168</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 6 10 -1.</_> + <_>5 1 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0228719990700483</threshold> + <left_val>-0.7132599949836731</left_val> + <right_val>-8.7040001526474953e-003</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 9 6 -1.</_> + <_>16 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0818210020661354</threshold> + <left_val>1.1127580404281616</left_val> + <right_val>0.0832199975848198</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 9 6 -1.</_> + <_>5 0 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0527280010282993</threshold> + <left_val>0.9316509962081909</left_val> + <right_val>-0.1710399985313416</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 15 -1.</_> + <_>10 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0252420008182526</threshold> + <left_val>-0.1973379999399185</left_val> + <right_val>0.2535940110683441</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 7 10 -1.</_> + <_>6 5 7 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0438189990818501</threshold> + <left_val>0.4181520044803619</left_val> + <right_val>-0.2458550035953522</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 20 4 -1.</_> + <_>12 2 10 2 2.</_> + <_>2 4 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0181889999657869</threshold> + <left_val>-0.5174319744110107</left_val> + <right_val>0.2017419934272766</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 19 3 -1.</_> + <_>2 12 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0234660003334284</threshold> + <left_val>-0.0430710017681122</left_val> + <right_val>-1.0636579990386963</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 8 6 9 -1.</_> + <_>12 8 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0342160016298294</threshold> + <left_val>0.0537809990346432</left_val> + <right_val>0.4970720112323761</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 6 9 -1.</_> + <_>10 8 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0256929993629456</threshold> + <left_val>-0.2380010038614273</left_val> + <right_val>0.4165149927139282</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 8 4 9 -1.</_> + <_>13 8 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0265650004148483</threshold> + <left_val>-0.8857480287551880</left_val> + <right_val>0.1336590051651001</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 11 9 9 -1.</_> + <_>6 11 3 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0609420016407967</threshold> + <left_val>-0.2066970020532608</left_val> + <right_val>0.5830900073051453</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 18 5 -1.</_> + <_>9 9 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1447450071573257</threshold> + <left_val>0.1328230053186417</left_val> + <right_val>-3.1449348926544189</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 4 2 20 -1.</_> + <_>2 14 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0534109994769096</threshold> + <left_val>-0.1732520014047623</left_val> + <right_val>0.6919069886207581</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 17 8 6 -1.</_> + <_>14 20 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0114080002531409</threshold> + <left_val>0.0548220016062260</left_val> + <right_val>0.3024039864540100</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 18 2 -1.</_> + <_>3 22 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.3179999552667141e-003</threshold> + <left_val>0.1582089960575104</left_val> + <right_val>-0.3197320103645325</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 15 6 -1.</_> + <_>10 4 5 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0296950004994869</threshold> + <left_val>0.7127479910850525</left_val> + <right_val>0.0581360012292862</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 15 12 6 -1.</_> + <_>2 17 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0272499993443489</threshold> + <left_val>-0.1575410068035126</left_val> + <right_val>0.9214379787445068</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 8 6 9 -1.</_> + <_>17 11 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.6200000904500484e-003</threshold> + <left_val>-0.3454839885234833</left_val> + <right_val>0.2022099941968918</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 20 4 -1.</_> + <_>2 12 10 2 2.</_> + <_>12 14 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0125789996236563</threshold> + <left_val>-0.5565029978752136</left_val> + <right_val>0.0203889999538660</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 24 6 -1.</_> + <_>0 19 24 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0888490006327629</threshold> + <left_val>-3.6100010871887207</left_val> + <right_val>0.1316419988870621</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 16 9 4 -1.</_> + <_>7 18 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0192569997161627</threshold> + <left_val>0.5190899968147278</left_val> + <right_val>-0.1928430050611496</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 1 4 22 -1.</_> + <_>17 1 2 11 2.</_> + <_>15 12 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0166669990867376</threshold> + <left_val>-0.0874999985098839</left_val> + <right_val>0.1581249982118607</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 1 4 22 -1.</_> + <_>5 1 2 11 2.</_> + <_>7 12 2 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0129319997504354</threshold> + <left_val>0.0274059996008873</left_val> + <right_val>-0.5512390136718750</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 13 8 9 -1.</_> + <_>11 16 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0134319998323917</threshold> + <left_val>0.2345779985189438</left_val> + <right_val>-0.0432350002229214</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 6 9 -1.</_> + <_>8 1 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0188100002706051</threshold> + <left_val>-0.0396809987723827</left_val> + <right_val>-0.9437329769134522</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 4 3 18 -1.</_> + <_>11 10 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.4349998719990253e-003</threshold> + <left_val>0.4570370018482208</left_val> + <right_val>-4.0520001202821732e-003</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 12 6 -1.</_> + <_>5 8 6 3 2.</_> + <_>11 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0242490004748106</threshold> + <left_val>-0.7624800205230713</left_val> + <right_val>-0.0198570005595684</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 7 5 8 -1.</_> + <_>15 11 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0296679995954037</threshold> + <left_val>-3.7412509918212891</left_val> + <right_val>0.1125060021877289</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 5 8 -1.</_> + <_>4 11 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.1150000654160976e-003</threshold> + <left_val>-0.6378179788589478</left_val> + <right_val>0.0112239997833967</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 6 12 -1.</_> + <_>15 6 3 6 2.</_> + <_>12 12 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.7819997891783714e-003</threshold> + <left_val>0.1937440037727356</left_val> + <right_val>-0.0820420011878014</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 6 12 -1.</_> + <_>6 6 3 6 2.</_> + <_>9 12 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0166069995611906</threshold> + <left_val>-0.1619209945201874</left_val> + <right_val>1.1334990262985229</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 9 14 8 -1.</_> + <_>12 9 7 4 2.</_> + <_>5 13 7 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0382280014455318</threshold> + <left_val>0.0211050007492304</left_val> + <right_val>0.7626420259475708</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 3 14 -1.</_> + <_>9 8 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0570940002799034</threshold> + <left_val>-1.6974929571151733</left_val> + <right_val>-0.0597620010375977</right_val></_></_> + <_> + <!-- tree 137 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 6 12 -1.</_> + <_>12 10 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0538830012083054</threshold> + <left_val>1.1850190162658691</left_val> + <right_val>0.0909669995307922</right_val></_></_> + <_> + <!-- tree 138 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 5 4 18 -1.</_> + <_>4 5 2 9 2.</_> + <_>6 14 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.6110000908374786e-003</threshold> + <left_val>-0.4094119966030121</left_val> + <right_val>0.0838209986686707</right_val></_></_> + <_> + <!-- tree 139 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 16 18 -1.</_> + <_>4 12 16 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2971439957618713</threshold> + <left_val>0.1552989929914475</left_val> + <right_val>-1.0995409488677979</right_val></_></_> + <_> + <!-- tree 140 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 7 20 -1.</_> + <_>5 14 7 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0890630036592484</threshold> + <left_val>0.4894720017910004</left_val> + <right_val>-0.2004120051860809</right_val></_></_> + <_> + <!-- tree 141 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 8 8 12 -1.</_> + <_>14 14 8 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0561930015683174</threshold> + <left_val>-0.2458139955997467</left_val> + <right_val>0.1436550021171570</right_val></_></_> + <_> + <!-- tree 142 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 10 6 14 -1.</_> + <_>9 10 3 7 2.</_> + <_>12 17 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0370049998164177</threshold> + <left_val>-0.0481689982116222</left_val> + <right_val>-1.2310709953308105</right_val></_></_> + <_> + <!-- tree 143 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 9 6 -1.</_> + <_>12 5 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.4840003401041031e-003</threshold> + <left_val>0.4337260127067566</left_val> + <right_val>0.0137799996882677</right_val></_></_> + <_> + <!-- tree 144 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 4 3 18 -1.</_> + <_>10 4 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.4379999376833439e-003</threshold> + <left_val>0.1894969940185547</left_val> + <right_val>-0.3229419887065888</right_val></_></_> + <_> + <!-- tree 145 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 4 22 14 -1.</_> + <_>12 4 11 7 2.</_> + <_>1 11 11 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0716399997472763</threshold> + <left_val>-0.4397900104522705</left_val> + <right_val>0.2273019999265671</right_val></_></_> + <_> + <!-- tree 146 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 18 2 -1.</_> + <_>2 8 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.2260002121329308e-003</threshold> + <left_val>-0.2054840028285980</left_val> + <right_val>0.5093330144882202</right_val></_></_> + <_> + <!-- tree 147 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 6 12 -1.</_> + <_>12 10 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.1360001564025879e-003</threshold> + <left_val>0.3115719854831696</left_val> + <right_val>0.0706809982657433</right_val></_></_> + <_> + <!-- tree 148 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 9 7 -1.</_> + <_>9 5 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0155950002372265</threshold> + <left_val>-0.3093479871749878</left_val> + <right_val>0.1562770009040833</right_val></_></_> + <_> + <!-- tree 149 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 7 4 12 -1.</_> + <_>12 13 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0259959995746613</threshold> + <left_val>0.1382160037755966</left_val> + <right_val>-0.1761659979820252</right_val></_></_> + <_> + <!-- tree 150 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 4 12 -1.</_> + <_>8 13 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0120850000530481</threshold> + <left_val>-0.5107020139694214</left_val> + <right_val>0.0584409981966019</right_val></_></_> + <_> + <!-- tree 151 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 2 10 22 -1.</_> + <_>7 13 10 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0678360015153885</threshold> + <left_val>0.4775710105895996</left_val> + <right_val>-0.0714460015296936</right_val></_></_> + <_> + <!-- tree 152 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 3 20 -1.</_> + <_>1 1 1 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0147150000557303</threshold> + <left_val>0.4523890018463135</left_val> + <right_val>-0.1986140012741089</right_val></_></_> + <_> + <!-- tree 153 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 18 4 -1.</_> + <_>13 13 9 2 2.</_> + <_>4 15 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0251189991831779</threshold> + <left_val>0.1295489966869354</left_val> + <right_val>-0.8626639842987061</right_val></_></_> + <_> + <!-- tree 154 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 13 18 4 -1.</_> + <_>2 13 9 2 2.</_> + <_>11 15 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0188260003924370</threshold> + <left_val>-0.0415700003504753</left_val> + <right_val>-1.1354700326919556</right_val></_></_> + <_> + <!-- tree 155 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 15 9 6 -1.</_> + <_>15 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0212639998644590</threshold> + <left_val>-0.3473800122737885</left_val> + <right_val>0.1577949970960617</right_val></_></_> + <_> + <!-- tree 156 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 9 6 -1.</_> + <_>0 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.4609996303915977e-003</threshold> + <left_val>4.8639997839927673e-003</left_val> + <right_val>-0.6165480017662048</right_val></_></_> + <_> + <!-- tree 157 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 18 24 -1.</_> + <_>15 0 9 12 2.</_> + <_>6 12 9 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2295770049095154</threshold> + <left_val>0.0813729986548424</left_val> + <right_val>0.6984140276908875</right_val></_></_> + <_> + <!-- tree 158 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 6 12 -1.</_> + <_>6 10 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0380619987845421</threshold> + <left_val>1.1616369485855103</left_val> + <right_val>-0.1497669965028763</right_val></_></_> + <_> + <!-- tree 159 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 10 4 -1.</_> + <_>8 9 10 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0134849995374680</threshold> + <left_val>-0.3203639984130859</left_val> + <right_val>0.1736509948968887</right_val></_></_> + <_> + <!-- tree 160 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 9 18 6 -1.</_> + <_>1 9 9 3 2.</_> + <_>10 12 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0362389981746674</threshold> + <left_val>-0.1815849989652634</left_val> + <right_val>0.6195669770240784</right_val></_></_> + <_> + <!-- tree 161 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 18 3 -1.</_> + <_>6 7 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.7210001870989799e-003</threshold> + <left_val>7.9600000753998756e-004</left_val> + <right_val>0.4244140088558197</right_val></_></_> + <_> + <!-- tree 162 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 9 8 -1.</_> + <_>10 7 3 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0965259969234467</threshold> + <left_val>-0.1469680070877075</left_val> + <right_val>1.2525680065155029</right_val></_></_> + <_> + <!-- tree 163 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 12 6 12 -1.</_> + <_>12 12 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0356569997966290</threshold> + <left_val>-0.3978169858455658</left_val> + <right_val>0.1419139951467514</right_val></_></_> + <_> + <!-- tree 164 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 14 18 3 -1.</_> + <_>3 15 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0107720000669360</threshold> + <left_val>-0.1819400042295456</left_val> + <right_val>0.5976219773292542</right_val></_></_> + <_> + <!-- tree 165 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 7 -1.</_> + <_>18 17 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0792799964547157</threshold> + <left_val>0.1464249938726425</left_val> + <right_val>-0.7883689999580383</right_val></_></_> + <_> + <!-- tree 166 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 12 10 6 -1.</_> + <_>1 14 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0328410007059574</threshold> + <left_val>-0.0624080002307892</left_val> + <right_val>-1.4227490425109863</right_val></_></_> + <_> + <!-- tree 167 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 7 -1.</_> + <_>18 17 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0277810003608465</threshold> + <left_val>0.3403309881687164</left_val> + <right_val>0.0306700002402067</right_val></_></_> + <_> + <!-- tree 168 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 3 3 19 -1.</_> + <_>11 3 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.0339999832212925e-003</threshold> + <left_val>0.3108470141887665</left_val> + <right_val>-0.2259570062160492</right_val></_></_> + <_> + <!-- tree 169 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 7 -1.</_> + <_>18 17 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.4260002002120018e-003</threshold> + <left_val>-0.0389369986951351</left_val> + <right_val>0.3170210123062134</right_val></_></_> + <_> + <!-- tree 170 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 11 9 -1.</_> + <_>6 4 11 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1121399998664856</threshold> + <left_val>-0.1757829934358597</left_val> + <right_val>0.6505659818649292</right_val></_></_> + <_> + <!-- tree 171 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 7 -1.</_> + <_>18 17 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1187810003757477</threshold> + <left_val>-1.0092990398406982</left_val> + <right_val>0.1106970012187958</right_val></_></_> + <_> + <!-- tree 172 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 11 6 -1.</_> + <_>6 8 11 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0415849983692169</threshold> + <left_val>-0.5380640029907227</left_val> + <right_val>0.0199050009250641</right_val></_></_> + <_> + <!-- tree 173 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 7 8 5 -1.</_> + <_>16 7 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0279660001397133</threshold> + <left_val>0.4814319908618927</left_val> + <right_val>0.0335909985005856</right_val></_></_> + <_> + <!-- tree 174 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 4 20 19 -1.</_> + <_>12 4 10 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1250640004873276</threshold> + <left_val>0.2635219991207123</left_val> + <right_val>-0.2573789954185486</right_val></_></_> + <_> + <!-- tree 175 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 1 21 6 -1.</_> + <_>9 1 7 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2366690039634705</threshold> + <left_val>0.0365080013871193</left_val> + <right_val>0.9065560102462769</right_val></_></_> + <_> + <!-- tree 176 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 12 14 -1.</_> + <_>6 5 6 7 2.</_> + <_>12 12 6 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0294759999960661</threshold> + <left_val>-0.6004880070686340</left_val> + <right_val>9.5880003646016121e-003</right_val></_></_> + <_> + <!-- tree 177 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 9 -1.</_> + <_>11 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0377929992973804</threshold> + <left_val>0.1550620049238205</left_val> + <right_val>-0.9573349952697754</right_val></_></_> + <_> + <!-- tree 178 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 8 5 -1.</_> + <_>6 11 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0720440000295639</threshold> + <left_val>-0.1452589929103851</left_val> + <right_val>1.3676730394363403</right_val></_></_> + <_> + <!-- tree 179 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 7 8 5 -1.</_> + <_>16 7 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.7759999334812164e-003</threshold> + <left_val>0.0129159996286035</left_val> + <right_val>0.2164089977741242</right_val></_></_> + <_> + <!-- tree 180 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 8 5 -1.</_> + <_>4 7 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0521540008485317</threshold> + <left_val>-0.0163599997758865</left_val> + <right_val>-0.8835629820823669</right_val></_></_> + <_> + <!-- tree 181 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 7 -1.</_> + <_>18 17 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0437909997999668</threshold> + <left_val>0.3582960069179535</left_val> + <right_val>0.0651310011744499</right_val></_></_> + <_> + <!-- tree 182 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 8 10 -1.</_> + <_>8 6 4 5 2.</_> + <_>12 11 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0383789986371994</threshold> + <left_val>1.1961040496826172</left_val> + <right_val>-0.1497150063514710</right_val></_></_> + <_> + <!-- tree 183 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 15 9 9 -1.</_> + <_>18 15 3 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0988389998674393</threshold> + <left_val>-0.6183400154113770</left_val> + <right_val>0.1278620064258575</right_val></_></_> + <_> + <!-- tree 184 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 9 9 -1.</_> + <_>3 15 3 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1219070032238960</threshold> + <left_val>-1.8276120424270630</left_val> + <right_val>-0.0648629963397980</right_val></_></_> + <_> + <!-- tree 185 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 10 9 7 -1.</_> + <_>15 10 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1198170036077499</threshold> + <left_val>-30.</left_val> + <right_val>0.1132330000400543</right_val></_></_> + <_> + <!-- tree 186 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 9 7 -1.</_> + <_>6 10 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0309100002050400</threshold> + <left_val>-0.2393400073051453</left_val> + <right_val>0.3633289933204651</right_val></_></_> + <_> + <!-- tree 187 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 15 10 8 -1.</_> + <_>18 15 5 4 2.</_> + <_>13 19 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0108009995892644</threshold> + <left_val>-0.0351400002837181</left_val> + <right_val>0.2770789861679077</right_val></_></_> + <_> + <!-- tree 188 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 12 -1.</_> + <_>0 1 3 6 2.</_> + <_>3 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0568449981510639</threshold> + <left_val>-0.1552429944276810</left_val> + <right_val>1.0802700519561768</right_val></_></_> + <_> + <!-- tree 189 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 6 12 -1.</_> + <_>13 0 3 6 2.</_> + <_>10 6 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.0280000278726220e-003</threshold> + <left_val>-0.0612029992043972</left_val> + <right_val>0.2050800025463104</right_val></_></_> + <_> + <!-- tree 190 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 10 12 -1.</_> + <_>7 0 5 6 2.</_> + <_>12 6 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0282739996910095</threshold> + <left_val>-0.6477800011634827</left_val> + <right_val>0.0239170007407665</right_val></_></_> + <_> + <!-- tree 191 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 1 16 8 -1.</_> + <_>4 1 8 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1601359993219376</threshold> + <left_val>1.0892050266265869</left_val> + <right_val>0.0583890005946159</right_val></_></_> + <_> + <!-- tree 192 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 21 19 3 -1.</_> + <_>0 22 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.9629998393356800e-003</threshold> + <left_val>-0.2580629885196686</left_val> + <right_val>0.2083459943532944</right_val></_></_> + <_> + <!-- tree 193 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 18 4 -1.</_> + <_>15 9 9 2 2.</_> + <_>6 11 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0469370000064373</threshold> + <left_val>0.1388629972934723</left_val> + <right_val>-1.5662620067596436</right_val></_></_> + <_> + <!-- tree 194 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 9 6 -1.</_> + <_>3 6 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0242860000580549</threshold> + <left_val>-0.2072830051183701</left_val> + <right_val>0.5243099927902222</right_val></_></_> + <_> + <!-- tree 195 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 6 15 -1.</_> + <_>9 6 6 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0702020004391670</threshold> + <left_val>0.1479689925909042</left_val> + <right_val>-1.3095090389251709</right_val></_></_> + <_> + <!-- tree 196 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 9 6 6 -1.</_> + <_>8 9 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.8120002076029778e-003</threshold> + <left_val>0.0279060006141663</left_val> + <right_val>-0.5086460113525391</right_val></_></_> + <_> + <!-- tree 197 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 1 14 9 -1.</_> + <_>5 4 14 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0562009997665882</threshold> + <left_val>1.2618130445480347</left_val> + <right_val>0.0638019964098930</right_val></_></_> + <_> + <!-- tree 198 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 8 20 -1.</_> + <_>3 0 4 10 2.</_> + <_>7 10 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1098280027508736</threshold> + <left_val>-0.1285009980201721</left_val> + <right_val>3.0776169300079346</right_val></_></_></trees> + <stage_threshold>-3.2573320865631104</stage_threshold> + <parent>21</parent> + <next>-1</next></_> + <_> + <!-- stage 23 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 7 9 -1.</_> + <_>5 3 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0209100004285574</threshold> + <left_val>-0.6855940222740173</left_val> + <right_val>0.3898429870605469</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 12 5 -1.</_> + <_>10 6 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0350320003926754</threshold> + <left_val>-0.4772439897060394</left_val> + <right_val>0.4502719938755035</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 8 14 -1.</_> + <_>4 1 4 14 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0397990010678768</threshold> + <left_val>-0.4701110124588013</left_val> + <right_val>0.4270249903202057</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 12 22 4 -1.</_> + <_>2 14 22 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.8409998416900635e-003</threshold> + <left_val>0.2561430037021637</left_val> + <right_val>-0.6655629873275757</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 17 6 6 -1.</_> + <_>8 20 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.3439999204128981e-003</threshold> + <left_val>-0.4808349907398224</left_val> + <right_val>0.2801379859447479</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 1 6 7 -1.</_> + <_>18 1 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0253129992634058</threshold> + <left_val>-0.2394820004701614</left_val> + <right_val>0.4419179856777191</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 6 -1.</_> + <_>3 0 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0321930013597012</threshold> + <left_val>0.7608669996261597</left_val> + <right_val>-0.2505910098552704</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 17 18 -1.</_> + <_>4 12 17 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0754090026021004</threshold> + <left_val>-0.3497459888458252</left_val> + <right_val>0.3438029885292053</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 12 6 -1.</_> + <_>6 0 6 3 2.</_> + <_>12 3 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0184690002351999</threshold> + <left_val>-0.7908560037612915</left_val> + <right_val>0.0347880013287067</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 18 4 -1.</_> + <_>13 7 9 2 2.</_> + <_>4 9 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0128020001575351</threshold> + <left_val>0.4710780084133148</left_val> + <right_val>-0.0600060001015663</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 10 6 -1.</_> + <_>4 14 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0265980008989573</threshold> + <left_val>0.6711609959602356</left_val> + <right_val>-0.2425750046968460</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 9 10 12 -1.</_> + <_>12 9 5 6 2.</_> + <_>7 15 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0219889990985394</threshold> + <left_val>0.2471749931573868</left_val> + <right_val>-0.4830169975757599</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 3 -1.</_> + <_>8 1 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1465409994125366</threshold> + <left_val>-0.2150409966707230</left_val> + <right_val>0.7205590009689331</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 6 6 -1.</_> + <_>13 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.5310001112520695e-003</threshold> + <left_val>0.2793099880218506</left_val> + <right_val>-0.3433989882469177</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 6 6 -1.</_> + <_>8 11 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.4010001048445702e-003</threshold> + <left_val>0.0558619983494282</left_val> + <right_val>-0.8214359879493713</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 19 3 -1.</_> + <_>3 11 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.6390003561973572e-003</threshold> + <left_val>-0.9962059855461121</left_val> + <right_val>0.1887499988079071</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 9 -1.</_> + <_>0 5 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0391930006444454</threshold> + <left_val>-1.1945559978485107</left_val> + <right_val>-0.0291980002075434</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 16 10 6 -1.</_> + <_>14 18 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0248550008982420</threshold> + <left_val>0.1498759984970093</left_val> + <right_val>-0.5413780212402344</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 10 6 -1.</_> + <_>0 18 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0349950008094311</threshold> + <left_val>-1.4210180044174194</left_val> + <right_val>-0.0423140004277229</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 9 6 -1.</_> + <_>14 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0183789990842342</threshold> + <left_val>-0.2824259996414185</left_val> + <right_val>0.1558180004358292</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 18 3 -1.</_> + <_>0 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0135920001193881</threshold> + <left_val>0.4731709957122803</left_val> + <right_val>-0.2193720042705536</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 18 3 -1.</_> + <_>6 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.2629999592900276e-003</threshold> + <left_val>-0.0597140006721020</left_val> + <right_val>0.6062589883804321</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 18 9 6 -1.</_> + <_>0 20 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0184780005365610</threshold> + <left_val>-0.8564720153808594</left_val> + <right_val>-0.0137839997187257</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 9 6 -1.</_> + <_>14 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0142360003665090</threshold> + <left_val>0.1665479987859726</left_val> + <right_val>-0.2771399915218353</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 2 6 9 -1.</_> + <_>8 2 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0325470007956028</threshold> + <left_val>-1.1728240251541138</left_val> + <right_val>-0.0401850007474422</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 8 4 12 -1.</_> + <_>15 8 2 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.6410000864416361e-003</threshold> + <left_val>0.2651430070400238</left_val> + <right_val>-0.0563430003821850</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 13 8 8 -1.</_> + <_>8 17 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.7799999164417386e-004</threshold> + <left_val>0.0365560017526150</left_val> + <right_val>-0.5507519841194153</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 20 18 3 -1.</_> + <_>10 20 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0473719984292984</threshold> + <left_val>-0.0426140017807484</left_val> + <right_val>0.4819490015506744</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 4 12 -1.</_> + <_>7 8 2 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.0790001191198826e-003</threshold> + <left_val>0.2869899868965149</left_val> + <right_val>-0.3292300105094910</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 12 3 -1.</_> + <_>7 7 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0431459993124008</threshold> + <left_val>-1.4065419435501099</left_val> + <right_val>0.1283639967441559</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 9 -1.</_> + <_>12 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0205920003354549</threshold> + <left_val>-0.2143529951572418</left_val> + <right_val>0.5398179888725281</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 20 18 3 -1.</_> + <_>11 20 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0223670005798340</threshold> + <left_val>0.3371829986572266</left_val> + <right_val>0.0452120006084442</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 20 18 3 -1.</_> + <_>7 20 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0500399991869926</threshold> + <left_val>-0.2512170076370239</left_val> + <right_val>0.4175049960613251</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 1 6 20 -1.</_> + <_>21 1 3 10 2.</_> + <_>18 11 3 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0617949999868870</threshold> + <left_val>0.0400849990546703</left_val> + <right_val>0.6877980232238770</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 6 20 -1.</_> + <_>0 1 3 10 2.</_> + <_>3 11 3 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0418619997799397</threshold> + <left_val>0.5302739739418030</left_val> + <right_val>-0.2290199995040894</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 3 4 18 -1.</_> + <_>15 3 2 9 2.</_> + <_>13 12 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.1959998887032270e-003</threshold> + <left_val>0.2516149878501892</left_val> + <right_val>-0.2151460051536560</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 6 12 -1.</_> + <_>0 6 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0242550000548363</threshold> + <left_val>7.2320001199841499e-003</left_val> + <right_val>-0.7251909971237183</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 9 12 6 -1.</_> + <_>18 9 6 3 2.</_> + <_>12 12 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0173039995133877</threshold> + <left_val>-0.4995819926261902</left_val> + <right_val>0.1839450001716614</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 3 4 18 -1.</_> + <_>7 3 2 9 2.</_> + <_>9 12 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.1470001451671124e-003</threshold> + <left_val>0.0852119997143745</left_val> + <right_val>-0.4636470079421997</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 6 9 -1.</_> + <_>16 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0143699999898672</threshold> + <left_val>-0.5225890278816223</left_val> + <right_val>0.2389259934425354</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 12 6 -1.</_> + <_>0 9 6 3 2.</_> + <_>6 12 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.0399999171495438e-003</threshold> + <left_val>-0.6325039863586426</left_val> + <right_val>0.0325510017573833</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 4 8 20 -1.</_> + <_>18 4 4 10 2.</_> + <_>14 14 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1237310022115707</threshold> + <left_val>1.2856210470199585</left_val> + <right_val>0.0765450000762939</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 4 8 20 -1.</_> + <_>2 4 4 10 2.</_> + <_>6 14 4 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0822219997644424</threshold> + <left_val>0.8320819735527039</left_val> + <right_val>-0.1859059929847717</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 13 9 6 -1.</_> + <_>14 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0656590014696121</threshold> + <left_val>0.1129880025982857</left_val> + <right_val>-30.</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 9 6 -1.</_> + <_>1 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0315829999744892</threshold> + <left_val>-1.3485900163650513</left_val> + <right_val>-0.0470970012247562</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 15 18 3 -1.</_> + <_>9 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0796360000967979</threshold> + <left_val>-1.3533639907836914</left_val> + <right_val>0.1566880047321320</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 13 9 6 -1.</_> + <_>5 15 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0188800003379583</threshold> + <left_val>0.4030030071735382</left_val> + <right_val>-0.2514890134334564</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 18 3 -1.</_> + <_>5 1 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.0149997696280479e-003</threshold> + <left_val>-0.2628709971904755</left_val> + <right_val>0.1858250051736832</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 6 7 -1.</_> + <_>11 2 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0122180003672838</threshold> + <left_val>0.5869240164756775</left_val> + <right_val>-0.1942770034074783</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 9 6 -1.</_> + <_>12 1 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.2710000155493617e-003</threshold> + <left_val>-0.1668899953365326</left_val> + <right_val>0.2300689965486527</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 9 6 -1.</_> + <_>9 1 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0297439992427826</threshold> + <left_val>0.0125200003385544</left_val> + <right_val>-0.6672359704971314</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 14 6 -1.</_> + <_>12 6 7 3 2.</_> + <_>5 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0281750001013279</threshold> + <left_val>-0.0170600004494190</left_val> + <right_val>0.6457939743995667</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 6 13 -1.</_> + <_>10 2 2 13 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0303450003266335</threshold> + <left_val>-0.2417870014905930</left_val> + <right_val>0.3487890064716339</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 12 6 -1.</_> + <_>12 11 6 3 2.</_> + <_>6 14 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0173259992152452</threshold> + <left_val>-0.5359939932823181</left_val> + <right_val>0.2099599987268448</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 18 15 -1.</_> + <_>9 1 6 15 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0841780006885529</threshold> + <left_val>0.7509329915046692</left_val> + <right_val>-0.1759320050477982</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 6 7 -1.</_> + <_>13 0 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.4950000271201134e-003</threshold> + <left_val>-0.1618809998035431</left_val> + <right_val>0.3065750002861023</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 3 16 6 -1.</_> + <_>3 6 16 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0564949996769428</threshold> + <left_val>-0.1731880009174347</left_val> + <right_val>1.0016150474548340</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 3 12 -1.</_> + <_>12 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.2939997985959053e-003</threshold> + <left_val>0.2341759949922562</left_val> + <right_val>-0.0653470009565353</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 6 9 -1.</_> + <_>9 7 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0149450004100800</threshold> + <left_val>0.2501890063285828</left_val> + <right_val>-0.3059119880199432</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 0 4 24 -1.</_> + <_>13 0 2 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0549190007150173</threshold> + <left_val>0.1312199980020523</left_val> + <right_val>-0.9376509785652161</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 4 24 -1.</_> + <_>9 0 2 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0197219997644424</threshold> + <left_val>-0.8397849798202515</left_val> + <right_val>-0.0234730001538992</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 9 5 12 -1.</_> + <_>11 13 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0671589970588684</threshold> + <left_val>2.3586840629577637</left_val> + <right_val>0.0829709991812706</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 15 9 6 -1.</_> + <_>7 17 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0143259996548295</threshold> + <left_val>0.1881449967622757</left_val> + <right_val>-0.3122160136699677</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 7 18 6 -1.</_> + <_>5 9 18 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0298410002142191</threshold> + <left_val>0.1482509970664978</left_val> + <right_val>-0.8468170166015625</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 9 5 12 -1.</_> + <_>8 13 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0518830008804798</threshold> + <left_val>-0.0437310002744198</left_val> + <right_val>-1.3366169929504395</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 17 17 6 -1.</_> + <_>4 19 17 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0411270000040531</threshold> + <left_val>0.1766009926795960</left_val> + <right_val>-0.6090409755706787</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 18 14 -1.</_> + <_>0 3 9 7 2.</_> + <_>9 10 9 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1286509931087494</threshold> + <left_val>-0.9870100021362305</left_val> + <right_val>-0.0377850010991097</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 24 2 -1.</_> + <_>0 2 24 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.4170000106096268e-003</threshold> + <left_val>-0.1611959934234619</left_val> + <right_val>0.3267570137977600</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 15 18 3 -1.</_> + <_>0 16 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.7030002139508724e-003</threshold> + <left_val>-0.2384150028228760</left_val> + <right_val>0.2931939959526062</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 9 -1.</_> + <_>11 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0455200001597404</threshold> + <left_val>0.1442459970712662</left_val> + <right_val>-1.5010160207748413</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 3 14 12 -1.</_> + <_>3 9 14 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0787009969353676</threshold> + <left_val>-1.0394560098648071</left_val> + <right_val>-0.0453759990632534</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 3 12 -1.</_> + <_>12 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.8619997948408127e-003</threshold> + <left_val>0.1963360011577606</left_val> + <right_val>-0.1447239965200424</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 6 9 -1.</_> + <_>10 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0134589998051524</threshold> + <left_val>-0.9063469767570496</left_val> + <right_val>-0.0380490012466908</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 6 10 -1.</_> + <_>12 6 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0288270004093647</threshold> + <left_val>-0.0294739995151758</left_val> + <right_val>0.6005839705467224</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 6 9 -1.</_> + <_>7 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0273659992963076</threshold> + <left_val>-0.9980400204658508</left_val> + <right_val>-0.0386530011892319</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 21 7 -1.</_> + <_>9 0 7 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0729179978370667</threshold> + <left_val>0.7336149811744690</left_val> + <right_val>0.0574400015175343</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 12 5 -1.</_> + <_>10 11 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0139889996498823</threshold> + <left_val>0.2789260149002075</left_val> + <right_val>-0.2651630043983460</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 9 8 -1.</_> + <_>11 7 3 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0432429984211922</threshold> + <left_val>4.7760000452399254e-003</left_val> + <right_val>0.3592590093612671</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 18 -1.</_> + <_>9 6 3 9 2.</_> + <_>12 15 3 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0295330006629229</threshold> + <left_val>-0.2008399963378906</left_val> + <right_val>0.5120289921760559</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 14 8 10 -1.</_> + <_>19 14 4 5 2.</_> + <_>15 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0318970009684563</threshold> + <left_val>0.6472169756889343</left_val> + <right_val>-1.3760000001639128e-003</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 14 8 10 -1.</_> + <_>1 14 4 5 2.</_> + <_>5 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0378689989447594</threshold> + <left_val>-0.1836380064487457</left_val> + <right_val>0.6134309768676758</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 0 8 10 -1.</_> + <_>15 0 4 5 2.</_> + <_>11 5 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0224179998040199</threshold> + <left_val>-0.2918789982795715</left_val> + <right_val>0.1819480061531067</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 8 10 -1.</_> + <_>5 0 4 5 2.</_> + <_>9 5 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0589589998126030</threshold> + <left_val>-0.0664519965648651</left_val> + <right_val>-1.9290030002593994</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 12 5 -1.</_> + <_>6 1 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0312229990959167</threshold> + <left_val>-0.0127320000901818</left_val> + <right_val>0.6156079769134522</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 12 18 2 -1.</_> + <_>10 12 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0374849997460842</threshold> + <left_val>-0.2085690051317215</left_val> + <right_val>0.4436399936676025</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 8 20 6 -1.</_> + <_>12 8 10 3 2.</_> + <_>2 11 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0209660008549690</threshold> + <left_val>-0.3571279942989349</left_val> + <right_val>0.2425220012664795</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 9 7 -1.</_> + <_>10 6 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0254779998213053</threshold> + <left_val>1.0846560001373291</left_val> + <right_val>-0.1505440026521683</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 8 16 -1.</_> + <_>14 5 4 8 2.</_> + <_>10 13 4 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.2570000775158405e-003</threshold> + <left_val>0.2130260020494461</left_val> + <right_val>-0.1830819994211197</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 16 8 -1.</_> + <_>3 9 8 4 2.</_> + <_>11 13 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0509830005466938</threshold> + <left_val>0.5173680186271668</left_val> + <right_val>-0.1883309930562973</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 10 4 -1.</_> + <_>7 8 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0206400007009506</threshold> + <left_val>-0.4403020143508911</left_val> + <right_val>0.2274599969387054</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 12 10 8 -1.</_> + <_>7 12 5 4 2.</_> + <_>12 16 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0106729995459318</threshold> + <left_val>0.0350599996745586</left_val> + <right_val>-0.5166500210762024</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 19 15 4 -1.</_> + <_>14 19 5 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0318959988653660</threshold> + <left_val>0.0132280001416802</left_val> + <right_val>0.3491519987583160</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 18 9 -1.</_> + <_>7 0 6 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0238249991089106</threshold> + <left_val>0.3411880135536194</left_val> + <right_val>-0.2151020020246506</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 4 10 8 -1.</_> + <_>18 4 5 4 2.</_> + <_>13 8 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.0680001042783260e-003</threshold> + <left_val>0.3293739855289459</left_val> + <right_val>-0.2852379977703095</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 16 18 4 -1.</_> + <_>9 16 6 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0238819997757673</threshold> + <left_val>-0.2533380091190338</left_val> + <right_val>0.2629610002040863</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 7 10 12 -1.</_> + <_>13 7 5 6 2.</_> + <_>8 13 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0279660001397133</threshold> + <left_val>0.1404909938573837</left_val> + <right_val>-0.4988709986209869</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 10 12 -1.</_> + <_>6 7 5 6 2.</_> + <_>11 13 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0146030001342297</threshold> + <left_val>-0.0153959998860955</left_val> + <right_val>-0.7695800065994263</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 18 7 -1.</_> + <_>10 6 6 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1087239980697632</threshold> + <left_val>0.1906960010528565</left_val> + <right_val>-0.3239310085773468</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 18 3 -1.</_> + <_>0 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0140380002558231</threshold> + <left_val>0.3492470085620880</left_val> + <right_val>-0.2235870063304901</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 17 18 3 -1.</_> + <_>3 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.0440000593662262e-003</threshold> + <left_val>-0.0383290015161037</left_val> + <right_val>0.5117729902267456</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 4 6 10 -1.</_> + <_>4 4 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.9769999459385872e-003</threshold> + <left_val>-0.4288829863071442</left_val> + <right_val>0.0491739995777607</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 0 8 24 -1.</_> + <_>16 0 4 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0851830020546913</threshold> + <left_val>0.6662459969520569</left_val> + <right_val>7.8079998493194580e-003</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 8 15 -1.</_> + <_>8 0 4 15 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.1559998858720064e-003</threshold> + <left_val>-0.4913519918918610</left_val> + <right_val>0.0695559978485107</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 0 8 24 -1.</_> + <_>16 0 4 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.3638449907302856</threshold> + <left_val>0.1299709975719452</left_val> + <right_val>-1.8949509859085083</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 4 18 9 -1.</_> + <_>7 4 6 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2208250015974045</threshold> + <left_val>-0.0572119988501072</left_val> + <right_val>-1.4281120300292969</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 12 9 6 -1.</_> + <_>15 14 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0161400008946657</threshold> + <left_val>-0.5758939981460571</left_val> + <right_val>0.1806250065565109</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 18 6 -1.</_> + <_>3 9 9 3 2.</_> + <_>12 12 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0483300015330315</threshold> + <left_val>0.9730849862098694</left_val> + <right_val>-0.1651300042867661</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 5 6 9 -1.</_> + <_>18 8 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0175299998372793</threshold> + <left_val>0.1793269962072372</left_val> + <right_val>-0.2794890105724335</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 6 9 -1.</_> + <_>0 8 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0343099981546402</threshold> + <left_val>-0.8107249736785889</left_val> + <right_val>-0.0165960006415844</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 18 4 -1.</_> + <_>13 7 9 2 2.</_> + <_>4 9 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.5830002054572105e-003</threshold> + <left_val>0.2790899872779846</left_val> + <right_val>-7.4519999325275421e-003</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 1 12 20 -1.</_> + <_>2 1 6 10 2.</_> + <_>8 11 6 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1289640069007874</threshold> + <left_val>-0.1350850015878677</left_val> + <right_val>2.5411539077758789</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 0 6 23 -1.</_> + <_>17 0 3 23 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0303610004484653</threshold> + <left_val>-0.0684190019965172</left_val> + <right_val>0.2873409986495972</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 6 2 18 -1.</_> + <_>1 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0440860018134117</threshold> + <left_val>-0.1813589930534363</left_val> + <right_val>0.6541320085525513</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 8 10 6 -1.</_> + <_>8 10 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.0159999150782824e-003</threshold> + <left_val>-0.1569049954414368</left_val> + <right_val>0.2696380019187927</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 20 6 -1.</_> + <_>0 6 10 3 2.</_> + <_>10 9 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0263369996100664</threshold> + <left_val>0.2917560040950775</left_val> + <right_val>-0.2527410089969635</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 12 12 5 -1.</_> + <_>15 12 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0278660003095865</threshold> + <left_val>0.4438750147819519</left_val> + <right_val>0.0550380013883114</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 3 19 -1.</_> + <_>1 4 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0117250001057982</threshold> + <left_val>-0.1934649944305420</left_val> + <right_val>0.4665670096874237</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 1 3 18 -1.</_> + <_>20 1 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.5689999563619494e-003</threshold> + <left_val>-8.2360003143548965e-003</left_val> + <right_val>0.2570089995861054</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 1 3 18 -1.</_> + <_>3 1 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.5550000611692667e-003</threshold> + <left_val>-0.4243089854717255</left_val> + <right_val>0.0711740031838417</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 18 3 -1.</_> + <_>9 10 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0316950008273125</threshold> + <left_val>-0.8539350032806397</left_val> + <right_val>0.1691620051860809</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 10 9 -1.</_> + <_>9 4 5 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0320970006287098</threshold> + <left_val>0.8378490209579468</left_val> + <right_val>-0.1759729981422424</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 13 14 7 -1.</_> + <_>7 13 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1554419994354248</threshold> + <left_val>0.0995500013232231</left_val> + <right_val>2.3873300552368164</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 13 14 7 -1.</_> + <_>10 13 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0880459994077683</threshold> + <left_val>-0.1872529983520508</left_val> + <right_val>0.6238430142402649</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 15 9 6 -1.</_> + <_>11 15 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.6720000421628356e-003</threshold> + <left_val>0.2500869929790497</left_val> + <right_val>-0.0651189982891083</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 14 8 10 -1.</_> + <_>4 14 4 5 2.</_> + <_>8 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.3409996479749680e-003</threshold> + <left_val>-0.3537890017032623</left_val> + <right_val>0.1071500033140183</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 14 4 10 -1.</_> + <_>10 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0371380001306534</threshold> + <left_val>0.1638700067996979</left_val> + <right_val>-0.9171839952468872</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 8 5 16 -1.</_> + <_>3 16 5 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0801839977502823</threshold> + <left_val>-0.1481299996376038</left_val> + <right_val>1.4895190000534058</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 10 9 6 -1.</_> + <_>15 12 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.9100002767518163e-004</threshold> + <left_val>-0.2132689952850342</left_val> + <right_val>0.1967640072107315</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 10 9 6 -1.</_> + <_>0 12 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.0400001928210258e-003</threshold> + <left_val>-0.7131869792938232</left_val> + <right_val>1.8240000354126096e-003</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 12 9 -1.</_> + <_>6 10 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1196239963173866</threshold> + <left_val>0.0330989994108677</left_val> + <right_val>1.0441709756851196</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 10 5 8 -1.</_> + <_>9 14 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.5280000194907188e-003</threshold> + <left_val>-0.2730849981307983</left_val> + <right_val>0.2722980082035065</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 3 12 -1.</_> + <_>12 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0296390000730753</threshold> + <left_val>0.3622579872608185</left_val> + <right_val>0.0567950010299683</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 15 6 9 -1.</_> + <_>10 15 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0266500003635883</threshold> + <left_val>-0.0480410009622574</left_val> + <right_val>-0.9672350287437439</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 6 7 6 -1.</_> + <_>16 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0444220006465912</threshold> + <left_val>0.1305290013551712</left_val> + <right_val>-0.3507730066776276</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 1 4 22 -1.</_> + <_>10 1 2 22 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0243599992245436</threshold> + <left_val>-1.0766899585723877</left_val> + <right_val>-0.0512229986488819</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 14 3 -1.</_> + <_>6 6 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0197349991649389</threshold> + <left_val>0.0262380000203848</left_val> + <right_val>0.2807050049304962</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 18 19 3 -1.</_> + <_>0 19 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.4930001497268677e-003</threshold> + <left_val>-0.2611129879951477</left_val> + <right_val>0.2101140022277832</right_val></_></_> + <_> + <!-- tree 137 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 0 6 24 -1.</_> + <_>17 0 3 24 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2320030033588409</threshold> + <left_val>-1.7748440504074097</left_val> + <right_val>0.1148260012269020</right_val></_></_> + <_> + <!-- tree 138 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 15 6 -1.</_> + <_>5 13 5 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0256140008568764</threshold> + <left_val>0.2990080118179321</left_val> + <right_val>-0.2250249981880188</right_val></_></_> + <_> + <!-- tree 139 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 10 14 -1.</_> + <_>14 6 5 7 2.</_> + <_>9 13 5 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.4949998632073402e-003</threshold> + <left_val>0.1956380009651184</left_val> + <right_val>-0.0997629985213280</right_val></_></_> + <_> + <!-- tree 140 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 6 8 10 -1.</_> + <_>1 6 4 5 2.</_> + <_>5 11 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.9840000681579113e-003</threshold> + <left_val>-0.4302150011062622</left_val> + <right_val>0.0812610015273094</right_val></_></_> + <_> + <!-- tree 141 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 12 5 -1.</_> + <_>7 6 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0358130000531673</threshold> + <left_val>-0.5098739862442017</left_val> + <right_val>0.1634590029716492</right_val></_></_> + <_> + <!-- tree 142 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 9 6 -1.</_> + <_>10 7 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0141690000891685</threshold> + <left_val>0.7797809839248657</left_val> + <right_val>-0.1747629940509796</right_val></_></_> + <_> + <!-- tree 143 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 8 14 14 -1.</_> + <_>14 8 7 7 2.</_> + <_>7 15 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1264210045337677</threshold> + <left_val>-0.6304789781570435</left_val> + <right_val>0.1272830069065094</right_val></_></_> + <_> + <!-- tree 144 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 8 14 14 -1.</_> + <_>3 8 7 7 2.</_> + <_>10 15 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0686779990792274</threshold> + <left_val>-0.0464479997754097</left_val> + <right_val>-1.1128979921340942</right_val></_></_> + <_> + <!-- tree 145 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 13 4 -1.</_> + <_>9 10 13 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0858649984002113</threshold> + <left_val>0.1183540001511574</left_val> + <right_val>-4.8235158920288086</right_val></_></_> + <_> + <!-- tree 146 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 6 12 -1.</_> + <_>3 2 3 6 2.</_> + <_>6 8 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0155119998380542</threshold> + <left_val>-0.0174679998308420</left_val> + <right_val>-0.6369339823722839</right_val></_></_> + <_> + <!-- tree 147 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 10 17 6 -1.</_> + <_>6 13 17 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0810910016298294</threshold> + <left_val>0.0861330032348633</left_val> + <right_val>2.4559431076049805</right_val></_></_> + <_> + <!-- tree 148 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 17 6 -1.</_> + <_>1 13 17 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0184950008988380</threshold> + <left_val>0.0402290001511574</left_val> + <right_val>-0.5085819959640503</right_val></_></_> + <_> + <!-- tree 149 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 7 8 9 -1.</_> + <_>16 10 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0863209962844849</threshold> + <left_val>-1.9006760120391846</left_val> + <right_val>0.1101910024881363</right_val></_></_> + <_> + <!-- tree 150 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 7 8 9 -1.</_> + <_>0 10 8 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0723550021648407</threshold> + <left_val>-0.0621119998395443</left_val> + <right_val>-1.4165179729461670</right_val></_></_> + <_> + <!-- tree 151 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 9 24 10 -1.</_> + <_>12 9 12 5 2.</_> + <_>0 14 12 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0781790018081665</threshold> + <left_val>0.8884930014610291</left_val> + <right_val>0.0423699989914894</right_val></_></_> + <_> + <!-- tree 152 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 15 8 -1.</_> + <_>8 2 5 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0966819971799850</threshold> + <left_val>-0.2209420055150986</left_val> + <right_val>0.3357509970664978</right_val></_></_> + <_> + <!-- tree 153 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 2 18 8 -1.</_> + <_>10 2 6 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0398759990930557</threshold> + <left_val>0.5780479907989502</left_val> + <right_val>0.0453479997813702</right_val></_></_> + <_> + <!-- tree 154 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 1 18 4 -1.</_> + <_>0 1 9 2 2.</_> + <_>9 3 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.5349997282028198e-003</threshold> + <left_val>-0.5417569875717163</left_val> + <right_val>3.2399999909102917e-003</right_val></_></_> + <_> + <!-- tree 155 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>20 2 3 18 -1.</_> + <_>21 2 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.0600000647827983e-004</threshold> + <left_val>-0.0815490037202835</left_val> + <right_val>0.3583790063858032</right_val></_></_> + <_> + <!-- tree 156 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 3 3 19 -1.</_> + <_>2 3 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0121079999953508</threshold> + <left_val>-0.2028039991855621</left_val> + <right_val>0.4376800060272217</right_val></_></_> + <_> + <!-- tree 157 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 8 6 16 -1.</_> + <_>20 8 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0208739992231131</threshold> + <left_val>0.4146989881992340</left_val> + <right_val>-0.0455680005252361</right_val></_></_> + <_> + <!-- tree 158 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 6 16 -1.</_> + <_>2 8 2 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0578880012035370</threshold> + <left_val>-0.0290099997073412</left_val> + <right_val>-0.9182230234146118</right_val></_></_> + <_> + <!-- tree 159 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 18 11 6 -1.</_> + <_>8 20 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.3200000103097409e-004</threshold> + <left_val>-0.1177240014076233</left_val> + <right_val>0.2000000029802322</right_val></_></_> + <_> + <!-- tree 160 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 12 5 -1.</_> + <_>8 6 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0171370003372431</threshold> + <left_val>0.3300479948520660</left_val> + <right_val>-0.2305520027875900</right_val></_></_> + <_> + <!-- tree 161 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 12 5 -1.</_> + <_>11 6 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0306550003588200</threshold> + <left_val>-0.0215450003743172</left_val> + <right_val>0.2687819898128510</right_val></_></_> + <_> + <!-- tree 162 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 9 6 -1.</_> + <_>9 3 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.8699999721720815e-004</threshold> + <left_val>-0.4410069882869721</left_val> + <right_val>0.0491579994559288</right_val></_></_> + <_> + <!-- tree 163 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 12 5 -1.</_> + <_>7 6 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0880369991064072</threshold> + <left_val>0.1178200021386147</left_val> + <right_val>-2.8293309211730957</right_val></_></_> + <_> + <!-- tree 164 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 8 6 7 -1.</_> + <_>12 8 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0390289984643459</threshold> + <left_val>0.9177719950675964</left_val> + <right_val>-0.1582739949226379</right_val></_></_> + <_> + <!-- tree 165 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 9 6 -1.</_> + <_>11 2 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0801059976220131</threshold> + <left_val>0.1128920018672943</left_val> + <right_val>-1.9937280416488647</right_val></_></_> + <_> + <!-- tree 166 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 14 6 9 -1.</_> + <_>8 17 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0395389981567860</threshold> + <left_val>-0.1435739994049072</left_val> + <right_val>1.3085240125656128</right_val></_></_> + <_> + <!-- tree 167 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 2 9 6 -1.</_> + <_>11 2 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0206840001046658</threshold> + <left_val>0.2004809975624085</left_val> + <right_val>-0.0441869981586933</right_val></_></_> + <_> + <!-- tree 168 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 16 20 -1.</_> + <_>4 3 8 10 2.</_> + <_>12 13 8 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0670379996299744</threshold> + <left_val>0.3261860013008118</left_val> + <right_val>-0.2055040001869202</right_val></_></_> + <_> + <!-- tree 169 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 10 12 -1.</_> + <_>12 6 5 6 2.</_> + <_>7 12 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0468150004744530</threshold> + <left_val>0.1582529991865158</left_val> + <right_val>-0.9553509950637817</right_val></_></_> + <_> + <!-- tree 170 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 7 12 -1.</_> + <_>0 6 7 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0784439966082573</threshold> + <left_val>-0.0746510028839111</left_val> + <right_val>-2.1161499023437500</right_val></_></_> + <_> + <!-- tree 171 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 17 11 6 -1.</_> + <_>12 19 11 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0663800016045570</threshold> + <left_val>0.1164190024137497</left_val> + <right_val>-1.6113519668579102</right_val></_></_> + <_> + <!-- tree 172 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 12 8 -1.</_> + <_>4 7 6 4 2.</_> + <_>10 11 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0300539992749691</threshold> + <left_val>-0.1656260043382645</left_val> + <right_val>0.7002540230751038</right_val></_></_> + <_> + <!-- tree 173 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 11 8 10 -1.</_> + <_>12 11 4 5 2.</_> + <_>8 16 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0171199999749660</threshold> + <left_val>0.2262769937515259</left_val> + <right_val>-0.4011499881744385</right_val></_></_> + <_> + <!-- tree 174 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 4 9 -1.</_> + <_>11 1 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0200730003416538</threshold> + <left_val>-0.1938969939947128</left_val> + <right_val>0.4442029893398285</right_val></_></_> + <_> + <!-- tree 175 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 3 22 -1.</_> + <_>15 0 1 22 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0331019982695580</threshold> + <left_val>0.1163749992847443</left_val> + <right_val>-1.5771679878234863</right_val></_></_> + <_> + <!-- tree 176 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 0 3 22 -1.</_> + <_>8 0 1 22 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0148820001631975</threshold> + <left_val>-0.8968030214309692</left_val> + <right_val>-0.0420100018382072</right_val></_></_> + <_> + <!-- tree 177 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 7 18 4 -1.</_> + <_>13 7 9 2 2.</_> + <_>4 9 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0102810002863407</threshold> + <left_val>0.3560299873352051</left_val> + <right_val>-0.0131240002810955</right_val></_></_> + <_> + <!-- tree 178 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 4 15 -1.</_> + <_>10 7 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0286950003355742</threshold> + <left_val>-0.4603959918022156</left_val> + <right_val>0.0268019996583462</right_val></_></_> + <_> + <!-- tree 179 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 3 12 -1.</_> + <_>12 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.7189998440444469e-003</threshold> + <left_val>0.2378879934549332</left_val> + <right_val>-0.0655189976096153</right_val></_></_> + <_> + <!-- tree 180 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 18 13 -1.</_> + <_>9 0 9 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.3220160007476807</threshold> + <left_val>-0.0284899994730949</left_val> + <right_val>-0.8423460125923157</right_val></_></_> + <_> + <!-- tree 181 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 0 3 24 -1.</_> + <_>17 0 1 24 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0170450005680323</threshold> + <left_val>-0.5093880295753479</left_val> + <right_val>0.1605760008096695</right_val></_></_> + <_> + <!-- tree 182 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 3 24 -1.</_> + <_>6 0 1 24 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.3469998314976692e-003</threshold> + <left_val>-0.5415499806404114</left_val> + <right_val>4.7320001758635044e-003</right_val></_></_> + <_> + <!-- tree 183 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 15 5 8 -1.</_> + <_>10 19 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0300019998103380</threshold> + <left_val>-0.8878579735755920</left_val> + <right_val>0.1362179964780808</right_val></_></_> + <_> + <!-- tree 184 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 18 18 2 -1.</_> + <_>2 19 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0112929996103048</threshold> + <left_val>0.8061519861221314</left_val> + <right_val>-0.1615950018167496</right_val></_></_> + <_> + <!-- tree 185 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 8 20 3 -1.</_> + <_>2 9 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.7749998047947884e-003</threshold> + <left_val>0.0129680000245571</left_val> + <right_val>0.5507990121841431</right_val></_></_> + <_> + <!-- tree 186 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 6 9 6 -1.</_> + <_>7 8 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.0710001960396767e-003</threshold> + <left_val>-0.0457280017435551</left_val> + <right_val>-1.0766259431838989</right_val></_></_> + <_> + <!-- tree 187 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 19 10 -1.</_> + <_>3 7 19 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1934410035610199</threshold> + <left_val>0.0712620019912720</left_val> + <right_val>1.1694519519805908</right_val></_></_> + <_> + <!-- tree 188 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 7 19 3 -1.</_> + <_>2 8 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.3750001825392246e-003</threshold> + <left_val>-0.1973620057106018</left_val> + <right_val>0.3820689916610718</right_val></_></_> + <_> + <!-- tree 189 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 6 9 4 -1.</_> + <_>15 8 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0682760030031204</threshold> + <left_val>-5.4372339248657227</left_val> + <right_val>0.1115190014243126</right_val></_></_> + <_> + <!-- tree 190 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 2 18 8 -1.</_> + <_>8 2 6 8 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0349330008029938</threshold> + <left_val>0.4479340016841888</left_val> + <right_val>-0.1865790039300919</right_val></_></_> + <_> + <!-- tree 191 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 9 14 4 -1.</_> + <_>10 9 7 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.1219998858869076e-003</threshold> + <left_val>-0.0148719996213913</left_val> + <right_val>0.1841389983892441</right_val></_></_> + <_> + <!-- tree 192 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 6 16 -1.</_> + <_>7 4 3 16 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0953119993209839</threshold> + <left_val>-0.1511709988117218</left_val> + <right_val>0.9499149918556213</right_val></_></_> + <_> + <!-- tree 193 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 8 9 16 -1.</_> + <_>18 8 3 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0628490000963211</threshold> + <left_val>0.4647360146045685</left_val> + <right_val>0.0384050011634827</right_val></_></_> + <_> + <!-- tree 194 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 9 16 -1.</_> + <_>3 8 3 16 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1704069972038269</threshold> + <left_val>-1.6499999761581421</left_val> + <right_val>-0.0632369965314865</right_val></_></_> + <_> + <!-- tree 195 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 0 6 14 -1.</_> + <_>20 0 2 14 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0105839995667338</threshold> + <left_val>-0.0383489988744259</left_val> + <right_val>0.4191380143165588</right_val></_></_> + <_> + <!-- tree 196 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 6 14 -1.</_> + <_>2 0 2 14 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0415790006518364</threshold> + <left_val>0.3446190059185028</left_val> + <right_val>-0.2118770033121109</right_val></_></_> + <_> + <!-- tree 197 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 0 6 22 -1.</_> + <_>17 0 2 22 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1271860003471375</threshold> + <left_val>0.1239819973707199</left_val> + <right_val>-2.1254889965057373</right_val></_></_> + <_> + <!-- tree 198 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 6 22 -1.</_> + <_>5 0 2 22 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0825570002198219</threshold> + <left_val>-0.0620240010321140</left_val> + <right_val>-1.4875819683074951</right_val></_></_> + <_> + <!-- tree 199 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 2 12 20 -1.</_> + <_>16 2 4 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0852930024266243</threshold> + <left_val>0.0170879997313023</left_val> + <right_val>0.3207660019397736</right_val></_></_> + <_> + <!-- tree 200 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 2 12 20 -1.</_> + <_>4 2 4 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0555440001189709</threshold> + <left_val>-0.2741400003433228</left_val> + <right_val>0.1897639930248261</right_val></_></_> + <_> + <!-- tree 201 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 4 9 -1.</_> + <_>11 6 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.5650000683963299e-003</threshold> + <left_val>-0.1792020052671433</left_val> + <right_val>0.2796730101108551</right_val></_></_> + <_> + <!-- tree 202 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 6 16 -1.</_> + <_>12 0 3 16 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0129979997873306</threshold> + <left_val>-0.3229750096797943</left_val> + <right_val>0.2694180011749268</right_val></_></_> + <_> + <!-- tree 203 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 1 3 12 -1.</_> + <_>12 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0578919984400272</threshold> + <left_val>0.1264439970254898</left_val> + <right_val>-0.6071349978446960</right_val></_></_> + <_> + <!-- tree 204 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 4 18 6 -1.</_> + <_>3 4 9 3 2.</_> + <_>12 7 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0228240005671978</threshold> + <left_val>-0.4968209862709045</left_val> + <right_val>0.0223769992589951</right_val></_></_> + <_> + <!-- tree 205 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 5 16 8 -1.</_> + <_>13 5 8 4 2.</_> + <_>5 9 8 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0483120009303093</threshold> + <left_val>0.0436070002615452</left_val> + <right_val>0.4853779971599579</right_val></_></_> + <_> + <!-- tree 206 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 10 6 -1.</_> + <_>0 15 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0257140006870031</threshold> + <left_val>-0.0429509989917278</left_val> + <right_val>-0.9302350282669067</right_val></_></_> + <_> + <!-- tree 207 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 14 9 6 -1.</_> + <_>8 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.9269998930394650e-003</threshold> + <left_val>-2.9680000152438879e-003</left_val> + <right_val>0.3429630100727081</right_val></_></_> + <_> + <!-- tree 208 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 2 9 6 -1.</_> + <_>9 2 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0344469994306564</threshold> + <left_val>-1.5299769639968872</left_val> + <right_val>-0.0610149987041950</right_val></_></_> + <_> + <!-- tree 209 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 1 10 8 -1.</_> + <_>19 1 5 4 2.</_> + <_>14 5 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0293879993259907</threshold> + <left_val>0.0375959984958172</left_val> + <right_val>0.6417239904403687</right_val></_></_> + <_> + <!-- tree 210 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 3 12 -1.</_> + <_>9 7 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.4319998919963837e-003</threshold> + <left_val>0.0990889966487885</left_val> + <right_val>-0.3968810141086578</right_val></_></_></trees> + <stage_threshold>-3.3703000545501709</stage_threshold> + <parent>22</parent> + <next>-1</next></_> + <_> + <!-- stage 24 --> + <trees> + <_> + <!-- tree 0 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 9 -1.</_> + <_>6 7 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0959440022706985</threshold> + <left_val>0.6241909861564636</left_val> + <right_val>-0.4587520062923431</right_val></_></_> + <_> + <!-- tree 1 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 12 6 -1.</_> + <_>10 5 4 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0168340001255274</threshold> + <left_val>-0.9307280182838440</left_val> + <right_val>0.2156360000371933</right_val></_></_> + <_> + <!-- tree 2 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 1 8 5 -1.</_> + <_>5 1 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0260499995201826</threshold> + <left_val>-0.4053229987621307</left_val> + <right_val>0.4225659966468811</right_val></_></_> + <_> + <!-- tree 3 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 12 6 8 -1.</_> + <_>12 16 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.6500001442618668e-004</threshold> + <left_val>0.0952880010008812</left_val> + <right_val>-0.6329810023307800</right_val></_></_> + <_> + <!-- tree 4 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 12 12 6 -1.</_> + <_>3 14 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.6940002143383026e-003</threshold> + <left_val>0.3724380135536194</left_val> + <right_val>-0.3033240139484406</right_val></_></_> + <_> + <!-- tree 5 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 18 12 6 -1.</_> + <_>15 18 6 3 2.</_> + <_>9 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0188740007579327</threshold> + <left_val>-0.2335720062255859</left_val> + <right_val>0.4033069908618927</right_val></_></_> + <_> + <!-- tree 6 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 13 6 6 -1.</_> + <_>4 16 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-1.6300000424962491e-004</threshold> + <left_val>0.0428869985044003</left_val> + <right_val>-0.7779679894447327</right_val></_></_> + <_> + <!-- tree 7 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 3 7 18 -1.</_> + <_>11 12 7 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0762590020895004</threshold> + <left_val>-0.4962849915027618</left_val> + <right_val>0.1633539944887161</right_val></_></_> + <_> + <!-- tree 8 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 18 3 -1.</_> + <_>9 9 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0501490011811256</threshold> + <left_val>0.0327470004558563</left_val> + <right_val>-0.8004789948463440</right_val></_></_> + <_> + <!-- tree 9 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 3 19 2 -1.</_> + <_>5 4 19 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-2.9239999130368233e-003</threshold> + <left_val>-0.5000280141830444</left_val> + <right_val>0.2548060119152069</right_val></_></_> + <_> + <!-- tree 10 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 2 12 6 -1.</_> + <_>4 2 6 3 2.</_> + <_>10 5 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0162439998239279</threshold> + <left_val>0.0389130003750324</left_val> + <right_val>-0.7072489857673645</right_val></_></_> + <_> + <!-- tree 11 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 6 9 -1.</_> + <_>11 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0378119982779026</threshold> + <left_val>-0.0662679970264435</left_val> + <right_val>0.7386879920959473</right_val></_></_> + <_> + <!-- tree 12 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 6 9 -1.</_> + <_>10 6 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0123199997469783</threshold> + <left_val>0.4869639873504639</left_val> + <right_val>-0.2448559999465942</right_val></_></_> + <_> + <!-- tree 13 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 9 5 15 -1.</_> + <_>16 14 5 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0580039992928505</threshold> + <left_val>0.1345909982919693</left_val> + <right_val>-0.1323210000991821</right_val></_></_> + <_> + <!-- tree 14 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 9 5 15 -1.</_> + <_>3 14 5 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.8630000092089176e-003</threshold> + <left_val>-0.4417290091514587</left_val> + <right_val>0.1400559991598129</right_val></_></_> + <_> + <!-- tree 15 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 6 14 6 -1.</_> + <_>13 6 7 3 2.</_> + <_>6 9 7 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0456909984350204</threshold> + <left_val>0.0312179997563362</left_val> + <right_val>0.8981829881668091</right_val></_></_> + <_> + <!-- tree 16 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 3 14 -1.</_> + <_>8 13 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0213210005313158</threshold> + <left_val>0.0120080001652241</left_val> + <right_val>-0.8606619834899902</right_val></_></_> + <_> + <!-- tree 17 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 24 5 -1.</_> + <_>8 16 8 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1567910015583038</threshold> + <left_val>0.0140559999272227</left_val> + <right_val>0.8533290028572083</right_val></_></_> + <_> + <!-- tree 18 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 20 20 3 -1.</_> + <_>10 20 10 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0103289997205138</threshold> + <left_val>0.2902280092239380</left_val> + <right_val>-0.2947880029678345</right_val></_></_> + <_> + <!-- tree 19 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 10 18 2 -1.</_> + <_>5 11 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.4290001019835472e-003</threshold> + <left_val>-0.4043990075588226</left_val> + <right_val>0.1940020024776459</right_val></_></_> + <_> + <!-- tree 20 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 6 10 -1.</_> + <_>2 6 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0233389995992184</threshold> + <left_val>0.3294520080089569</left_val> + <right_val>-0.2571269869804382</right_val></_></_> + <_> + <!-- tree 21 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 1 20 3 -1.</_> + <_>2 2 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.8970001302659512e-003</threshold> + <left_val>-0.5335299968719482</left_val> + <right_val>0.2163520008325577</right_val></_></_> + <_> + <!-- tree 22 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 13 6 11 -1.</_> + <_>11 13 2 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0344030000269413</threshold> + <left_val>-1.4425489902496338</left_val> + <right_val>-0.0446829982101917</right_val></_></_> + <_> + <!-- tree 23 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 15 6 8 -1.</_> + <_>9 19 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0212350003421307</threshold> + <left_val>-0.7901750206947327</left_val> + <right_val>0.1908410042524338</right_val></_></_> + <_> + <!-- tree 24 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 9 -1.</_> + <_>9 15 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.0620001014322042e-003</threshold> + <left_val>-0.2693119943141937</left_val> + <right_val>0.3148800134658814</right_val></_></_> + <_> + <!-- tree 25 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 18 2 -1.</_> + <_>5 12 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.2190002277493477e-003</threshold> + <left_val>-0.5446439981460571</left_val> + <right_val>0.1657460033893585</right_val></_></_> + <_> + <!-- tree 26 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 6 15 6 -1.</_> + <_>2 8 15 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0143349999561906</threshold> + <left_val>0.0221050009131432</left_val> + <right_val>-0.6234250068664551</right_val></_></_> + <_> + <!-- tree 27 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 18 3 -1.</_> + <_>6 1 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.2120001316070557e-003</threshold> + <left_val>-0.4988499879837036</left_val> + <right_val>0.1923709958791733</right_val></_></_> + <_> + <!-- tree 28 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 3 18 -1.</_> + <_>6 0 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.3350000679492950e-003</threshold> + <left_val>-0.7913119792938232</left_val> + <right_val>-0.0141439996659756</right_val></_></_> + <_> + <!-- tree 29 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 3 6 10 -1.</_> + <_>20 3 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0379379987716675</threshold> + <left_val>0.7984129786491394</left_val> + <right_val>-0.0337990000844002</right_val></_></_> + <_> + <!-- tree 30 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 6 10 -1.</_> + <_>2 3 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.7059999778866768e-003</threshold> + <left_val>-0.3316340148448944</left_val> + <right_val>0.2072629928588867</right_val></_></_> + <_> + <!-- tree 31 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 8 9 -1.</_> + <_>10 5 4 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-4.4499998912215233e-003</threshold> + <left_val>-0.2725630104541779</left_val> + <right_val>0.1840219944715500</right_val></_></_> + <_> + <!-- tree 32 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 5 8 9 -1.</_> + <_>10 5 4 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>5.2189999260008335e-003</threshold> + <left_val>-0.5309600234031677</left_val> + <right_val>0.0526079982519150</right_val></_></_> + <_> + <!-- tree 33 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 2 20 3 -1.</_> + <_>3 3 20 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.5399999991059303e-003</threshold> + <left_val>-0.5648540258407593</left_val> + <right_val>0.1926939934492111</right_val></_></_> + <_> + <!-- tree 34 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 13 4 -1.</_> + <_>5 4 13 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0449699983000755</threshold> + <left_val>-0.1741150021553040</left_val> + <right_val>0.9538260102272034</right_val></_></_> + <_> + <!-- tree 35 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>17 0 7 14 -1.</_> + <_>17 7 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0142090003937483</threshold> + <left_val>-0.0919490009546280</left_val> + <right_val>0.2483610063791275</right_val></_></_> + <_> + <!-- tree 36 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 7 14 -1.</_> + <_>0 7 7 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1638019979000092</threshold> + <left_val>-0.0584970004856586</left_val> + <right_val>-1.6404409408569336</right_val></_></_> + <_> + <!-- tree 37 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 11 10 6 -1.</_> + <_>9 11 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.5579999200999737e-003</threshold> + <left_val>0.2344799935817719</left_val> + <right_val>-0.0927340015769005</right_val></_></_> + <_> + <!-- tree 38 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 10 6 -1.</_> + <_>10 11 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.8499999791383743e-003</threshold> + <left_val>0.1788070052862167</left_val> + <right_val>-0.3584409952163696</right_val></_></_> + <_> + <!-- tree 39 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 6 3 18 -1.</_> + <_>11 12 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0252219997346401</threshold> + <left_val>-0.4290300011634827</left_val> + <right_val>0.2024450004100800</right_val></_></_> + <_> + <!-- tree 40 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 18 3 -1.</_> + <_>0 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0194150004535913</threshold> + <left_val>0.5801630020141602</left_val> + <right_val>-0.1880639940500259</right_val></_></_> + <_> + <!-- tree 41 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 16 18 3 -1.</_> + <_>6 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0144199999049306</threshold> + <left_val>0.0328469984233379</left_val> + <right_val>0.8198050260543823</right_val></_></_> + <_> + <!-- tree 42 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 9 10 -1.</_> + <_>4 11 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0515829995274544</threshold> + <left_val>0.0691760033369064</left_val> + <right_val>-0.4586629867553711</right_val></_></_> + <_> + <!-- tree 43 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 7 15 4 -1.</_> + <_>9 9 15 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0379600003361702</threshold> + <left_val>-1.2553000450134277</left_val> + <right_val>0.1433289945125580</right_val></_></_> + <_> + <!-- tree 44 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 6 12 6 -1.</_> + <_>5 6 6 3 2.</_> + <_>11 9 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0295609999448061</threshold> + <left_val>0.5315179824829102</left_val> + <right_val>-0.2059649974107742</right_val></_></_> + <_> + <!-- tree 45 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 1 12 9 -1.</_> + <_>6 4 12 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0391109995543957</threshold> + <left_val>1.1658719778060913</left_val> + <right_val>0.0538970008492470</right_val></_></_> + <_> + <!-- tree 46 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 9 6 12 -1.</_> + <_>7 9 3 6 2.</_> + <_>10 15 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0291590001434088</threshold> + <left_val>0.3930760025978088</left_val> + <right_val>-0.2218450009822846</right_val></_></_> + <_> + <!-- tree 47 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 5 13 6 -1.</_> + <_>11 7 13 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0836170017719269</threshold> + <left_val>-0.7374449968338013</left_val> + <right_val>0.1426820009946823</right_val></_></_> + <_> + <!-- tree 48 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 11 22 13 -1.</_> + <_>12 11 11 13 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.4200400114059448</threshold> + <left_val>-0.1427740007638931</left_val> + <right_val>1.7894840240478516</right_val></_></_> + <_> + <!-- tree 49 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 8 6 6 -1.</_> + <_>18 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0600050017237663</threshold> + <left_val>0.1197670027613640</left_val> + <right_val>-1.8886189460754395</right_val></_></_> + <_> + <!-- tree 50 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 6 6 -1.</_> + <_>0 11 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0189810004085302</threshold> + <left_val>-1.4148449897766113</left_val> + <right_val>-0.0565229989588261</right_val></_></_> + <_> + <!-- tree 51 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 6 24 3 -1.</_> + <_>0 7 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.0049998573958874e-003</threshold> + <left_val>0.4417079985141754</left_val> + <right_val>-0.1020080000162125</right_val></_></_> + <_> + <!-- tree 52 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 10 6 -1.</_> + <_>0 7 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0582140013575554</threshold> + <left_val>-1.3918470144271851</left_val> + <right_val>-0.0482689999043942</right_val></_></_> + <_> + <!-- tree 53 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 7 18 3 -1.</_> + <_>6 8 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0122710000723600</threshold> + <left_val>0.5131769776344299</left_val> + <right_val>-0.0936969965696335</right_val></_></_> + <_> + <!-- tree 54 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 10 6 -1.</_> + <_>0 2 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0465859994292259</threshold> + <left_val>-0.0574840009212494</left_val> + <right_val>-1.4283169507980347</right_val></_></_> + <_> + <!-- tree 55 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 0 3 19 -1.</_> + <_>20 0 1 19 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.2110000243410468e-003</threshold> + <left_val>-0.0808919966220856</left_val> + <right_val>0.3233320116996765</right_val></_></_> + <_> + <!-- tree 56 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 6 12 16 -1.</_> + <_>4 6 6 8 2.</_> + <_>10 14 6 8 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0886420011520386</threshold> + <left_val>-0.8644909858703613</left_val> + <right_val>-0.0331469997763634</right_val></_></_> + <_> + <!-- tree 57 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>19 6 4 18 -1.</_> + <_>21 6 2 9 2.</_> + <_>19 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0231849998235703</threshold> + <left_val>0.5216220021247864</left_val> + <right_val>-0.0161680001765490</right_val></_></_> + <_> + <!-- tree 58 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 6 4 18 -1.</_> + <_>1 6 2 9 2.</_> + <_>3 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0430900007486343</threshold> + <left_val>-0.1615380048751831</left_val> + <right_val>1.0915000438690186</right_val></_></_> + <_> + <!-- tree 59 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 21 18 3 -1.</_> + <_>3 22 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.0599999697878957e-004</threshold> + <left_val>-0.1709149926900864</left_val> + <right_val>0.3123669922351837</right_val></_></_> + <_> + <!-- tree 60 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 19 9 4 -1.</_> + <_>0 21 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.9159999042749405e-003</threshold> + <left_val>-6.7039998248219490e-003</left_val> + <right_val>-0.6881039738655090</right_val></_></_> + <_> + <!-- tree 61 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 18 12 6 -1.</_> + <_>18 18 6 3 2.</_> + <_>12 21 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0177529994398355</threshold> + <left_val>0.6329280138015747</left_val> + <right_val>-4.2360001243650913e-003</right_val></_></_> + <_> + <!-- tree 62 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 18 9 4 -1.</_> + <_>7 20 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.2299999408423901e-003</threshold> + <left_val>-0.3363719880580902</left_val> + <right_val>0.1279059946537018</right_val></_></_> + <_> + <!-- tree 63 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 16 10 8 -1.</_> + <_>17 16 5 4 2.</_> + <_>12 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0227700006216764</threshold> + <left_val>-0.0347039997577667</left_val> + <right_val>0.3914180099964142</right_val></_></_> + <_> + <!-- tree 64 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 16 10 8 -1.</_> + <_>2 16 5 4 2.</_> + <_>7 20 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0215349998325109</threshold> + <left_val>0.6476510167121887</left_val> + <right_val>-0.2009779959917069</right_val></_></_> + <_> + <!-- tree 65 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 0 10 12 -1.</_> + <_>19 0 5 6 2.</_> + <_>14 6 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0617589987814426</threshold> + <left_val>0.0542970001697540</left_val> + <right_val>0.9070010185241699</right_val></_></_> + <_> + <!-- tree 66 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 10 12 -1.</_> + <_>0 0 5 6 2.</_> + <_>5 6 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0780699998140335</threshold> + <left_val>0.6552339792251587</left_val> + <right_val>-0.1975439935922623</right_val></_></_> + <_> + <!-- tree 67 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 14 9 6 -1.</_> + <_>15 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0113150002434850</threshold> + <left_val>0.1938530057668686</left_val> + <right_val>-0.5170729756355286</right_val></_></_> + <_> + <!-- tree 68 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 9 6 -1.</_> + <_>0 16 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0255900006741285</threshold> + <left_val>-0.9309650063514710</left_val> + <right_val>-0.0315469987690449</right_val></_></_> + <_> + <!-- tree 69 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 14 10 6 -1.</_> + <_>14 16 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0380589999258518</threshold> + <left_val>-0.6832690238952637</left_val> + <right_val>0.1270910054445267</right_val></_></_> + <_> + <!-- tree 70 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 10 6 -1.</_> + <_>0 16 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>9.7970003262162209e-003</threshold> + <left_val>0.0155239999294281</left_val> + <right_val>-0.6334789991378784</right_val></_></_> + <_> + <!-- tree 71 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 18 18 2 -1.</_> + <_>5 19 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0138419996947050</threshold> + <left_val>1.0060529708862305</left_val> + <right_val>0.0628129988908768</right_val></_></_> + <_> + <!-- tree 72 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 18 18 3 -1.</_> + <_>0 19 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.3459997549653053e-003</threshold> + <left_val>-0.2338320016860962</left_val> + <right_val>0.3098269999027252</right_val></_></_> + <_> + <!-- tree 73 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 5 18 12 -1.</_> + <_>12 5 9 6 2.</_> + <_>3 11 9 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0714399963617325</threshold> + <left_val>-0.7250540256500244</left_val> + <right_val>0.1714829951524735</right_val></_></_> + <_> + <!-- tree 74 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 3 7 9 -1.</_> + <_>5 6 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0100060002878308</threshold> + <left_val>-0.2207199931144714</left_val> + <right_val>0.3526619970798492</right_val></_></_> + <_> + <!-- tree 75 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 19 15 -1.</_> + <_>4 5 19 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1100530028343201</threshold> + <left_val>0.1666200011968613</left_val> + <right_val>-0.7431899905204773</right_val></_></_> + <_> + <!-- tree 76 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 0 16 4 -1.</_> + <_>3 2 16 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0353109985589981</threshold> + <left_val>-0.2398270070552826</left_val> + <right_val>0.4143599867820740</right_val></_></_> + <_> + <!-- tree 77 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 12 16 12 -1.</_> + <_>4 12 8 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1117469966411591</threshold> + <left_val>0.5104539990425110</left_val> + <right_val>2.2319999989122152e-003</right_val></_></_> + <_> + <!-- tree 78 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 3 12 15 -1.</_> + <_>10 3 6 15 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1136780008673668</threshold> + <left_val>0.9047520160675049</left_val> + <right_val>-0.1661529988050461</right_val></_></_> + <_> + <!-- tree 79 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 4 2 19 -1.</_> + <_>16 4 1 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0166679993271828</threshold> + <left_val>0.1402450054883957</left_val> + <right_val>-0.5217850208282471</right_val></_></_> + <_> + <!-- tree 80 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 2 19 -1.</_> + <_>7 4 1 19 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.0340001732110977e-003</threshold> + <left_val>-0.6617839932441711</left_val> + <right_val>3.7640000227838755e-003</right_val></_></_> + <_> + <!-- tree 81 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 14 8 10 -1.</_> + <_>17 14 4 5 2.</_> + <_>13 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0330969989299774</threshold> + <left_val>0.8018590211868286</left_val> + <right_val>0.0593850016593933</right_val></_></_> + <_> + <!-- tree 82 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 14 8 10 -1.</_> + <_>3 14 4 5 2.</_> + <_>7 19 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0125479996204376</threshold> + <left_val>-0.3354550004005432</left_val> + <right_val>0.1457860022783279</right_val></_></_> + <_> + <!-- tree 83 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 3 18 -1.</_> + <_>12 12 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0420739986002445</threshold> + <left_val>-0.5550910234451294</left_val> + <right_val>0.1326660066843033</right_val></_></_> + <_> + <!-- tree 84 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 11 12 6 -1.</_> + <_>5 11 6 3 2.</_> + <_>11 14 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0252219997346401</threshold> + <left_val>-0.0616319999098778</left_val> + <right_val>-1.3678770065307617</right_val></_></_> + <_> + <!-- tree 85 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 8 10 -1.</_> + <_>14 5 4 5 2.</_> + <_>10 10 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0242689996957779</threshold> + <left_val>0.3418509960174561</left_val> + <right_val>-7.4160001240670681e-003</right_val></_></_> + <_> + <!-- tree 86 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 4 12 10 -1.</_> + <_>6 4 6 5 2.</_> + <_>12 9 6 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0122800003737211</threshold> + <left_val>0.2774580121040344</left_val> + <right_val>-0.3103390038013458</right_val></_></_> + <_> + <!-- tree 87 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 18 10 -1.</_> + <_>15 8 9 5 2.</_> + <_>6 13 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1137709990143776</threshold> + <left_val>1.1719540357589722</left_val> + <right_val>0.0836810022592545</right_val></_></_> + <_> + <!-- tree 88 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 18 10 -1.</_> + <_>0 8 9 5 2.</_> + <_>9 13 9 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0847719982266426</threshold> + <left_val>0.8169479966163635</left_val> + <right_val>-0.1783750057220459</right_val></_></_> + <_> + <!-- tree 89 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 3 18 -1.</_> + <_>12 12 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0245520006865263</threshold> + <left_val>-0.1862729936838150</left_val> + <right_val>0.1434009969234467</right_val></_></_> + <_> + <!-- tree 90 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 14 18 3 -1.</_> + <_>0 15 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-9.0269995853304863e-003</threshold> + <left_val>0.3265919983386993</left_val> + <right_val>-0.2354129999876022</right_val></_></_> + <_> + <!-- tree 91 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 6 3 18 -1.</_> + <_>12 12 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0111779998987913</threshold> + <left_val>0.1976120024919510</left_val> + <right_val>-0.0217010006308556</right_val></_></_> + <_> + <!-- tree 92 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 6 3 18 -1.</_> + <_>9 12 3 6 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0293669998645782</threshold> + <left_val>-0.9341480135917664</left_val> + <right_val>-0.0217049997299910</right_val></_></_> + <_> + <!-- tree 93 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 14 18 3 -1.</_> + <_>6 15 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.3640000298619270e-003</threshold> + <left_val>0.0255730003118515</left_val> + <right_val>0.4641279876232147</right_val></_></_> + <_> + <!-- tree 94 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 5 18 3 -1.</_> + <_>0 6 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0140260001644492</threshold> + <left_val>-0.2122859954833984</left_val> + <right_val>0.4007880091667175</right_val></_></_> + <_> + <!-- tree 95 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 5 22 3 -1.</_> + <_>2 6 22 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0133419996127486</threshold> + <left_val>0.7420269846916199</left_val> + <right_val>0.0290019996464252</right_val></_></_> + <_> + <!-- tree 96 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 21 10 -1.</_> + <_>7 0 7 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.2842279970645905</threshold> + <left_val>-0.1924359947443008</left_val> + <right_val>0.4363119900226593</right_val></_></_> + <_> + <!-- tree 97 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 3 18 17 -1.</_> + <_>12 3 6 17 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2372400015592575</threshold> + <left_val>0.6973639726638794</left_val> + <right_val>0.0693079978227615</right_val></_></_> + <_> + <!-- tree 98 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 18 17 -1.</_> + <_>6 3 6 17 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1116970032453537</threshold> + <left_val>0.3914720118045807</left_val> + <right_val>-0.2092200070619583</right_val></_></_> + <_> + <!-- tree 99 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 24 11 -1.</_> + <_>8 12 8 11 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1278750002384186</threshold> + <left_val>-0.0725559964776039</left_val> + <right_val>0.3608820140361786</right_val></_></_> + <_> + <!-- tree 100 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 10 16 6 -1.</_> + <_>4 13 16 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0629009976983070</threshold> + <left_val>0.9542499780654907</left_val> + <right_val>-0.1540279984474182</right_val></_></_> + <_> + <!-- tree 101 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 8 6 8 -1.</_> + <_>12 12 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0174390003085136</threshold> + <left_val>-0.0511349998414516</left_val> + <right_val>0.2775030136108398</right_val></_></_> + <_> + <!-- tree 102 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 14 8 7 -1.</_> + <_>10 14 4 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.2319999514147639e-003</threshold> + <left_val>0.0756279975175858</left_val> + <right_val>-0.3645609915256500</right_val></_></_> + <_> + <!-- tree 103 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 10 6 14 -1.</_> + <_>18 10 3 7 2.</_> + <_>15 17 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0274950005114079</threshold> + <left_val>0.0518440008163452</left_val> + <right_val>0.4156259894371033</right_val></_></_> + <_> + <!-- tree 104 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 6 14 -1.</_> + <_>3 10 3 7 2.</_> + <_>6 17 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0435439981520176</threshold> + <left_val>0.7196999788284302</left_val> + <right_val>-0.1713220030069351</right_val></_></_> + <_> + <!-- tree 105 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 12 18 2 -1.</_> + <_>6 13 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0110259996727109</threshold> + <left_val>0.1435460001230240</left_val> + <right_val>-0.6540300250053406</right_val></_></_> + <_> + <!-- tree 106 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 10 6 -1.</_> + <_>5 10 10 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0208659991621971</threshold> + <left_val>0.0400890000164509</left_val> + <right_val>-0.4574329853057861</right_val></_></_> + <_> + <!-- tree 107 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 11 9 4 -1.</_> + <_>12 13 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0223040003329515</threshold> + <left_val>0.5385500192642212</left_val> + <right_val>0.0716629996895790</right_val></_></_> + <_> + <!-- tree 108 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 11 9 6 -1.</_> + <_>0 13 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0324920006096363</threshold> + <left_val>-0.0459919981658459</left_val> + <right_val>-1.0047069787979126</right_val></_></_> + <_> + <!-- tree 109 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 2 3 18 -1.</_> + <_>12 2 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0122699998319149</threshold> + <left_val>0.0343349985778332</left_val> + <right_val>0.4243179857730866</right_val></_></_> + <_> + <!-- tree 110 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 2 3 18 -1.</_> + <_>11 2 1 18 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.3820000290870667e-003</threshold> + <left_val>-0.2585060000419617</left_val> + <right_val>0.2626349925994873</right_val></_></_> + <_> + <!-- tree 111 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 12 6 10 -1.</_> + <_>11 12 2 10 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0373539999127388</threshold> + <left_val>0.1569249927997589</left_val> + <right_val>-1.0429090261459351</right_val></_></_> + <_> + <!-- tree 112 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 10 6 9 -1.</_> + <_>1 13 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0141110001131892</threshold> + <left_val>-0.7317770123481751</left_val> + <right_val>-0.0202769991010427</right_val></_></_> + <_> + <!-- tree 113 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 16 6 -1.</_> + <_>14 9 8 3 2.</_> + <_>6 12 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0570669993758202</threshold> + <left_val>0.0833600014448166</left_val> + <right_val>1.5661499500274658</right_val></_></_> + <_> + <!-- tree 114 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 8 9 6 -1.</_> + <_>1 10 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.9680001102387905e-003</threshold> + <left_val>-0.3531819880008698</left_val> + <right_val>0.1469839960336685</right_val></_></_> + <_> + <!-- tree 115 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 7 16 6 -1.</_> + <_>7 9 16 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0244929995387793</threshold> + <left_val>0.2832590043544769</left_val> + <right_val>-3.4640000667423010e-003</right_val></_></_> + <_> + <!-- tree 116 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 0 18 3 -1.</_> + <_>0 1 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0112549997866154</threshold> + <left_val>-0.8401749730110169</left_val> + <right_val>-0.0362519994378090</right_val></_></_> + <_> + <!-- tree 117 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 0 6 9 -1.</_> + <_>12 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0345330014824867</threshold> + <left_val>0.1499850004911423</left_val> + <right_val>-0.8736709952354431</right_val></_></_> + <_> + <!-- tree 118 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 5 6 6 -1.</_> + <_>12 5 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0243030004203320</threshold> + <left_val>-0.1878750026226044</left_val> + <right_val>0.5948399901390076</right_val></_></_> + <_> + <!-- tree 119 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 18 -1.</_> + <_>12 6 2 9 2.</_> + <_>10 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-7.8790001571178436e-003</threshold> + <left_val>0.4431569874286652</left_val> + <right_val>-0.0565709993243217</right_val></_></_> + <_> + <!-- tree 120 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 0 6 9 -1.</_> + <_>10 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0351420007646084</threshold> + <left_val>-0.0564949996769428</left_val> + <right_val>-1.3617190122604370</right_val></_></_> + <_> + <!-- tree 121 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 6 9 -1.</_> + <_>9 4 6 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.6259998343884945e-003</threshold> + <left_val>-0.3116169869899750</left_val> + <right_val>0.2544769942760468</right_val></_></_> + <_> + <!-- tree 122 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 0 18 9 -1.</_> + <_>1 3 18 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0831310003995895</threshold> + <left_val>1.6424349546432495</left_val> + <right_val>-0.1442939937114716</right_val></_></_> + <_> + <!-- tree 123 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 3 24 3 -1.</_> + <_>0 4 24 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0140159996226430</threshold> + <left_val>-0.7781950235366821</left_val> + <right_val>0.1717330068349838</right_val></_></_> + <_> + <!-- tree 124 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 14 9 4 -1.</_> + <_>6 16 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.2450000504031777e-003</threshold> + <left_val>-0.2319139987230301</left_val> + <right_val>0.2852790057659149</right_val></_></_> + <_> + <!-- tree 125 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 9 8 10 -1.</_> + <_>12 9 4 5 2.</_> + <_>8 14 4 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0168030001223087</threshold> + <left_val>-0.3596509993076325</left_val> + <right_val>0.2041299939155579</right_val></_></_> + <_> + <!-- tree 126 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 13 9 -1.</_> + <_>5 5 13 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0767479985952377</threshold> + <left_val>0.7805050015449524</left_val> + <right_val>-0.1561280041933060</right_val></_></_> + <_> + <!-- tree 127 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 16 9 -1.</_> + <_>4 7 16 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2367199957370758</threshold> + <left_val>1.1813700199127197</left_val> + <right_val>0.0781119987368584</right_val></_></_> + <_> + <!-- tree 128 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 4 14 9 -1.</_> + <_>4 7 14 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1005740016698837</threshold> + <left_val>-0.4710409939289093</left_val> + <right_val>0.0791729986667633</right_val></_></_> + <_> + <!-- tree 129 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 5 9 6 -1.</_> + <_>8 7 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.3239999534562230e-003</threshold> + <left_val>0.2226269990205765</left_val> + <right_val>-0.3709979951381683</right_val></_></_> + <_> + <!-- tree 130 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 7 16 6 -1.</_> + <_>1 9 16 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0221529994159937</threshold> + <left_val>-0.0386490002274513</left_val> + <right_val>-0.9227499961853027</right_val></_></_> + <_> + <!-- tree 131 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 5 13 9 -1.</_> + <_>10 8 13 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1124619990587235</threshold> + <left_val>0.4189960062503815</left_val> + <right_val>0.0804110020399094</right_val></_></_> + <_> + <!-- tree 132 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 5 13 9 -1.</_> + <_>1 8 13 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0164810009300709</threshold> + <left_val>-0.1675669997930527</left_val> + <right_val>0.7184240221977234</right_val></_></_> + <_> + <!-- tree 133 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 4 24 6 -1.</_> + <_>12 4 12 3 2.</_> + <_>0 7 12 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0681139975786209</threshold> + <left_val>0.1571989953517914</left_val> + <right_val>-0.8768110275268555</right_val></_></_> + <_> + <!-- tree 134 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 14 10 9 -1.</_> + <_>1 17 10 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0160119999200106</threshold> + <left_val>-4.1600000113248825e-003</left_val> + <right_val>-0.5932779908180237</right_val></_></_> + <_> + <!-- tree 135 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 17 18 3 -1.</_> + <_>5 18 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.6640001237392426e-003</threshold> + <left_val>-0.0301539991050959</left_val> + <right_val>0.4834530055522919</right_val></_></_> + <_> + <!-- tree 136 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 18 3 -1.</_> + <_>0 17 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.7579997703433037e-003</threshold> + <left_val>-0.2266740053892136</left_val> + <right_val>0.3366230130195618</right_val></_></_> + <_> + <!-- tree 137 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 17 9 6 -1.</_> + <_>9 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.7289999201893806e-003</threshold> + <left_val>-0.0603739991784096</left_val> + <right_val>0.3145810067653656</right_val></_></_> + <_> + <!-- tree 138 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 20 22 4 -1.</_> + <_>1 20 11 2 2.</_> + <_>12 22 11 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.5869999080896378e-003</threshold> + <left_val>-0.2987259924411774</left_val> + <right_val>0.1778749972581863</right_val></_></_> + <_> + <!-- tree 139 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 14 8 6 -1.</_> + <_>8 17 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.8989999555051327e-003</threshold> + <left_val>0.2189020067453384</left_val> + <right_val>-0.2956709861755371</right_val></_></_> + <_> + <!-- tree 140 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 6 8 15 -1.</_> + <_>8 11 8 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0300539992749691</threshold> + <left_val>1.2150429487228394</left_val> + <right_val>-0.1435499936342239</right_val></_></_> + <_> + <!-- tree 141 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 4 18 3 -1.</_> + <_>5 5 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0141810001805425</threshold> + <left_val>0.0124519998207688</left_val> + <right_val>0.5549010038375855</right_val></_></_> + <_> + <!-- tree 142 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 3 5 10 -1.</_> + <_>9 8 5 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0605270005762577</threshold> + <left_val>-1.4933999776840210</left_val> + <right_val>-0.0652270019054413</right_val></_></_> + <_> + <!-- tree 143 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 8 12 3 -1.</_> + <_>6 8 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0198829993605614</threshold> + <left_val>-0.3852640092372894</left_val> + <right_val>0.1976120024919510</right_val></_></_> + <_> + <!-- tree 144 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 6 18 6 -1.</_> + <_>2 6 9 3 2.</_> + <_>11 9 9 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0312189999967813</threshold> + <left_val>-0.2128120064735413</left_val> + <right_val>0.2944650053977966</right_val></_></_> + <_> + <!-- tree 145 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 6 4 18 -1.</_> + <_>12 6 2 9 2.</_> + <_>10 15 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0182719994336367</threshold> + <left_val>9.7200000891461968e-004</left_val> + <right_val>0.6681420207023621</right_val></_></_> + <_> + <!-- tree 146 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>7 5 6 6 -1.</_> + <_>10 5 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>1.1089999461546540e-003</threshold> + <left_val>-0.6246790289878845</left_val> + <right_val>-1.6599999507889152e-003</right_val></_></_> + <_> + <!-- tree 147 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 5 2 18 -1.</_> + <_>14 14 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0367139987647533</threshold> + <left_val>-0.4233390092849731</left_val> + <right_val>0.1208470016717911</right_val></_></_> + <_> + <!-- tree 148 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>8 5 2 18 -1.</_> + <_>8 14 2 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0120440004393458</threshold> + <left_val>0.0258820001035929</left_val> + <right_val>-0.5073239803314209</right_val></_></_> + <_> + <!-- tree 149 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 2 10 6 -1.</_> + <_>9 2 5 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0747490003705025</threshold> + <left_val>0.1318469941616058</left_val> + <right_val>-0.2173960059881210</right_val></_></_> + <_> + <!-- tree 150 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 18 12 -1.</_> + <_>12 1 9 12 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.2347320020198822</threshold> + <left_val>1.1775610446929932</left_val> + <right_val>-0.1511469930410385</right_val></_></_> + <_> + <!-- tree 151 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 2 17 22 -1.</_> + <_>5 13 17 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1409649997949600</threshold> + <left_val>0.0339910015463829</left_val> + <right_val>0.3992309868335724</right_val></_></_> + <_> + <!-- tree 152 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>4 0 12 6 -1.</_> + <_>4 2 12 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>6.1789997853338718e-003</threshold> + <left_val>-0.3180670142173767</left_val> + <right_val>0.1168169975280762</right_val></_></_> + <_> + <!-- tree 153 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 9 16 6 -1.</_> + <_>14 9 8 3 2.</_> + <_>6 12 8 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0572169981896877</threshold> + <left_val>0.8439909815788269</left_val> + <right_val>0.0838890001177788</right_val></_></_> + <_> + <!-- tree 154 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 0 5 18 -1.</_> + <_>9 9 5 9 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0552270002663136</threshold> + <left_val>0.3688830137252808</left_val> + <right_val>-0.1891340017318726</right_val></_></_> + <_> + <!-- tree 155 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 0 6 9 -1.</_> + <_>14 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0215830001980066</threshold> + <left_val>-0.5216180086135864</left_val> + <right_val>0.1577260047197342</right_val></_></_> + <_> + <!-- tree 156 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 0 6 9 -1.</_> + <_>8 0 2 9 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0257479995489120</threshold> + <left_val>-0.0599219985306263</left_val> + <right_val>-1.0674990415573120</right_val></_></_> + <_> + <!-- tree 157 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 6 12 -1.</_> + <_>11 1 2 12 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0130989998579025</threshold> + <left_val>0.7895839810371399</left_val> + <right_val>0.0520999990403652</right_val></_></_> + <_> + <!-- tree 158 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 9 13 4 -1.</_> + <_>5 11 13 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.2799998987466097e-003</threshold> + <left_val>-1.1704430580139160</left_val> + <right_val>-0.0593569986522198</right_val></_></_> + <_> + <!-- tree 159 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 19 3 -1.</_> + <_>5 9 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>8.8060004636645317e-003</threshold> + <left_val>0.0417179986834526</left_val> + <right_val>0.6635259985923767</right_val></_></_> + <_> + <!-- tree 160 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 9 6 8 -1.</_> + <_>9 13 6 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-8.9699998497962952e-003</threshold> + <left_val>-0.3586269915103912</left_val> + <right_val>0.0604580007493496</right_val></_></_> + <_> + <!-- tree 161 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 9 4 15 -1.</_> + <_>11 14 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.0230001322925091e-003</threshold> + <left_val>0.2097939997911453</left_val> + <right_val>-0.2480600029230118</right_val></_></_> + <_> + <!-- tree 162 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 0 6 14 -1.</_> + <_>2 0 3 7 2.</_> + <_>5 7 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0250170007348061</threshold> + <left_val>-0.1879590004682541</left_val> + <right_val>0.3954710066318512</right_val></_></_> + <_> + <!-- tree 163 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 1 6 14 -1.</_> + <_>18 1 3 7 2.</_> + <_>15 8 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-5.9009999968111515e-003</threshold> + <left_val>0.2566390037536621</left_val> + <right_val>-0.0949190035462379</right_val></_></_> + <_> + <!-- tree 164 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 1 6 14 -1.</_> + <_>3 1 3 7 2.</_> + <_>6 8 3 7 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>4.3850000947713852e-003</threshold> + <left_val>0.0331390015780926</left_val> + <right_val>-0.4607540071010590</right_val></_></_> + <_> + <!-- tree 165 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 20 18 4 -1.</_> + <_>12 20 9 2 2.</_> + <_>3 22 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0337719991803169</threshold> + <left_val>-0.9888160228729248</left_val> + <right_val>0.1463689953088760</right_val></_></_> + <_> + <!-- tree 166 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 0 4 20 -1.</_> + <_>5 0 2 10 2.</_> + <_>7 10 2 10 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0445230007171631</threshold> + <left_val>-0.1328669935464859</left_val> + <right_val>1.5796790122985840</right_val></_></_> + <_> + <!-- tree 167 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 8 8 12 -1.</_> + <_>20 8 4 6 2.</_> + <_>16 14 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0409290008246899</threshold> + <left_val>0.3387709856033325</left_val> + <right_val>0.0749709978699684</right_val></_></_> + <_> + <!-- tree 168 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 8 8 12 -1.</_> + <_>0 8 4 6 2.</_> + <_>4 14 4 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0393519997596741</threshold> + <left_val>-0.1832789927721024</left_val> + <right_val>0.4698069989681244</right_val></_></_> + <_> + <!-- tree 169 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 13 10 8 -1.</_> + <_>18 13 5 4 2.</_> + <_>13 17 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0703229978680611</threshold> + <left_val>-0.9832270145416260</left_val> + <right_val>0.1180810034275055</right_val></_></_> + <_> + <!-- tree 170 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 13 10 8 -1.</_> + <_>1 13 5 4 2.</_> + <_>6 17 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0357430018484592</threshold> + <left_val>-0.0330509990453720</left_val> + <right_val>-0.8361089825630188</right_val></_></_> + <_> + <!-- tree 171 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 8 4 15 -1.</_> + <_>15 13 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0429619997739792</threshold> + <left_val>1.1670809984207153</left_val> + <right_val>0.0806920006871223</right_val></_></_> + <_> + <!-- tree 172 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>5 8 4 15 -1.</_> + <_>5 13 4 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0210079997777939</threshold> + <left_val>0.6386979818344116</left_val> + <right_val>-0.1762630045413971</right_val></_></_> + <_> + <!-- tree 173 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 11 16 12 -1.</_> + <_>6 15 16 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.1574220061302185</threshold> + <left_val>-0.2330249994993210</left_val> + <right_val>0.1251749992370606</right_val></_></_> + <_> + <!-- tree 174 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>2 11 16 12 -1.</_> + <_>2 15 16 4 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>7.8659998252987862e-003</threshold> + <left_val>-0.2203799933195114</left_val> + <right_val>0.2719680070877075</right_val></_></_> + <_> + <!-- tree 175 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>14 12 7 9 -1.</_> + <_>14 15 7 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0236220005899668</threshold> + <left_val>0.1612730026245117</left_val> + <right_val>-0.4332900047302246</right_val></_></_> + <_> + <!-- tree 176 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>10 1 3 21 -1.</_> + <_>10 8 3 7 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0746920034289360</threshold> + <left_val>-0.1699199974536896</left_val> + <right_val>0.5888490080833435</right_val></_></_> + <_> + <!-- tree 177 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 11 9 4 -1.</_> + <_>13 13 9 2 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-6.4799998654052615e-004</threshold> + <left_val>0.2584289908409119</left_val> + <right_val>-0.0359119996428490</right_val></_></_> + <_> + <!-- tree 178 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 10 17 9 -1.</_> + <_>3 13 17 3 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0162909999489784</threshold> + <left_val>-0.7676439881324768</left_val> + <right_val>-0.0204729996621609</right_val></_></_> + <_> + <!-- tree 179 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>13 8 8 15 -1.</_> + <_>13 13 8 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0331339985132217</threshold> + <left_val>-0.2718009948730469</left_val> + <right_val>0.1432570070028305</right_val></_></_> + <_> + <!-- tree 180 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 8 8 15 -1.</_> + <_>3 13 8 5 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0487979985773563</threshold> + <left_val>0.0764089971780777</left_val> + <right_val>-0.4144519865512848</right_val></_></_> + <_> + <!-- tree 181 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>11 14 10 8 -1.</_> + <_>16 14 5 4 2.</_> + <_>11 18 5 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>2.2869999520480633e-003</threshold> + <left_val>-0.0386289991438389</left_val> + <right_val>0.2075379937887192</right_val></_></_> + <_> + <!-- tree 182 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 18 22 6 -1.</_> + <_>0 18 11 3 2.</_> + <_>11 21 11 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0453040003776550</threshold> + <left_val>-0.1777790039777756</left_val> + <right_val>0.6346139907836914</right_val></_></_> + <_> + <!-- tree 183 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 16 24 4 -1.</_> + <_>0 16 12 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.1070580035448074</threshold> + <left_val>0.1897229999303818</left_val> + <right_val>-0.5123620033264160</right_val></_></_> + <_> + <!-- tree 184 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>6 20 12 3 -1.</_> + <_>12 20 6 3 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0405250005424023</threshold> + <left_val>0.7061499953269959</left_val> + <right_val>-0.1780329942703247</right_val></_></_> + <_> + <!-- tree 185 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>18 12 6 12 -1.</_> + <_>21 12 3 6 2.</_> + <_>18 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0319689996540546</threshold> + <left_val>0.0681499987840652</left_val> + <right_val>0.6873310208320618</right_val></_></_> + <_> + <!-- tree 186 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 12 6 12 -1.</_> + <_>0 12 3 6 2.</_> + <_>3 18 3 6 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0576170012354851</threshold> + <left_val>0.7517049908638001</left_val> + <right_val>-0.1576499938964844</right_val></_></_> + <_> + <!-- tree 187 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 6 -1.</_> + <_>15 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0135939996689558</threshold> + <left_val>0.1941190063953400</left_val> + <right_val>-0.2456189990043640</right_val></_></_> + <_> + <!-- tree 188 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>1 6 22 10 -1.</_> + <_>1 6 11 5 2.</_> + <_>12 11 11 5 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0713960006833076</threshold> + <left_val>-0.0468810014426708</left_val> + <right_val>-0.8819829821586609</right_val></_></_> + <_> + <!-- tree 189 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 6 -1.</_> + <_>15 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0148959998041391</threshold> + <left_val>-0.4453240036964417</left_val> + <right_val>0.1767989993095398</right_val></_></_> + <_> + <!-- tree 190 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 18 18 2 -1.</_> + <_>0 19 18 1 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0100260004401207</threshold> + <left_val>0.6512269973754883</left_val> + <right_val>-0.1670999974012375</right_val></_></_> + <_> + <!-- tree 191 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 15 19 3 -1.</_> + <_>3 16 19 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>3.7589999847114086e-003</threshold> + <left_val>-0.0583010017871857</left_val> + <right_val>0.3448329865932465</right_val></_></_> + <_> + <!-- tree 192 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 18 3 -1.</_> + <_>0 14 18 1 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0162630006670952</threshold> + <left_val>-0.1558150053024292</left_val> + <right_val>0.8643270134925842</right_val></_></_> + <_> + <!-- tree 193 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>15 17 9 6 -1.</_> + <_>15 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0401760004460812</threshold> + <left_val>-0.6102859973907471</left_val> + <right_val>0.1179639995098114</right_val></_></_> + <_> + <!-- tree 194 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 17 9 6 -1.</_> + <_>0 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0270809996873140</threshold> + <left_val>-0.0496019981801510</left_val> + <right_val>-0.8999000191688538</right_val></_></_> + <_> + <!-- tree 195 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>12 17 9 6 -1.</_> + <_>12 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0524200014770031</threshold> + <left_val>0.1129719987511635</left_val> + <right_val>-1.0833640098571777</right_val></_></_> + <_> + <!-- tree 196 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>3 17 9 6 -1.</_> + <_>3 19 9 2 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0191600006073713</threshold> + <left_val>-0.7988010048866272</left_val> + <right_val>-0.0340790003538132</right_val></_></_> + <_> + <!-- tree 197 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>16 2 3 20 -1.</_> + <_>17 2 1 20 3.</_></rects> + <tilted>0</tilted></feature> + <threshold>-3.7730000913143158e-003</threshold> + <left_val>-0.1912409961223602</left_val> + <right_val>0.2153519988059998</right_val></_></_> + <_> + <!-- tree 198 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>0 13 24 8 -1.</_> + <_>0 17 24 4 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>0.0757620036602020</threshold> + <left_val>-0.1342169940471649</left_val> + <right_val>1.6807060241699219</right_val></_></_> + <_> + <!-- tree 199 --> + <_> + <!-- root node --> + <feature> + <rects> + <_>9 1 6 22 -1.</_> + <_>12 1 3 11 2.</_> + <_>9 12 3 11 2.</_></rects> + <tilted>0</tilted></feature> + <threshold>-0.0221730004996061</threshold> + <left_val>0.4860099852085114</left_val> + <right_val>3.6160000599920750e-003</right_val></_></_></trees> + <stage_threshold>-2.9928278923034668</stage_threshold> + <parent>23</parent> + <next>-1</next></_></stages></haarcascade_frontalface_default> +</opencv_storage> diff --git a/modules/opencv_is/opencv_is.c b/modules/opencv_is/opencv_is.c new file mode 100644 index 0000000..643a0a1 --- /dev/null +++ b/modules/opencv_is/opencv_is.c @@ -0,0 +1,219 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * This file is part of GPAC / Dummy input 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/modules/codec.h> +#include <gpac/scenegraph_vrml.h> +#include <gpac/thread.h> + +#include <cvaux.h> +#include <highgui.h> + + + +typedef struct +{ + GF_Thread *th; + Bool running; + +} GF_OpenCV; + + +static Bool OCV_RegisterDevice(struct __input_device *ifce, const char *urn, GF_BitStream *dsi, void (*AddField)(struct __input_device *_this, u32 fieldType, const char *name)) +{ + if (strncmp(urn, "OpenCV", 6)) return 0; + + AddField(ifce, GF_SG_VRML_SFVEC2F, "position"); + + return 1; +} + + + +CvHaarClassifierCascade* load_object_detector( const char* cascade_path ) +{ + return (CvHaarClassifierCascade*)cvLoad( cascade_path, NULL, NULL, NULL ); +} + +int prev_x0=0, prev_y0=0; + +void detect_and_draw_objects(GF_InputSensorDevice *ifce, IplImage* image, + CvHaarClassifierCascade* cascade, + int do_pyramids ) +{ + IplImage* small_image = image; + CvMemStorage* storage = cvCreateMemStorage(0); + CvSeq* faces; + int i, scale = 1; + //CvRect* theRealFace; + int theRealX=0, theRealY=0, theRealHeight=0 , theRealWidth=0; + + int tmpMaxSurface=0; + + + if( do_pyramids ) + { + small_image = cvCreateImage( cvSize(image->width/2,image->height/2), IPL_DEPTH_8U, 3 ); + cvPyrDown( image, small_image, CV_GAUSSIAN_5x5 ); + scale = 2; + } + + faces = cvHaarDetectObjects( small_image, cascade, storage, 1.2, 2, CV_HAAR_DO_CANNY_PRUNING, cvSize(0,0) ); + + for( i = 0; i < faces->total; i++ ) + { + + CvRect face_rect = *(CvRect*)cvGetSeqElem( faces, i ); + /* cvRectangle( image, cvPoint(face_rect.x*scale,face_rect.y*scale), + cvPoint((face_rect.x+face_rect.width)*scale, + (face_rect.y+face_rect.height)*scale), + CV_RGB(0,255,0), 3 );*/ + if(face_rect.width*face_rect.height>tmpMaxSurface){ + theRealX=face_rect.x; + theRealY=face_rect.y; + theRealHeight=face_rect.height; + theRealWidth=face_rect.width; + tmpMaxSurface=face_rect.width*face_rect.height; + } + + } + cvRectangle( image, cvPoint(theRealX*scale,theRealY*scale), + cvPoint((theRealX+theRealWidth)*scale, + (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) ); + + /*send data frame to GPAC*/ + { + char *buf; + u32 buf_size; + GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + gf_bs_write_int(bs, 1, 1); + gf_bs_write_float(bs, (Float) (theRealX - 640/2) ); + gf_bs_write_float(bs, (Float) (480/2 - theRealY) ); + + gf_bs_align(bs); + gf_bs_get_content(bs, &buf, &buf_size); + gf_bs_del(bs); + ifce->DispatchFrame(ifce, buf, buf_size); + gf_free(buf); + } + + + prev_x0=theRealX; + prev_y0=theRealY; + + if( small_image != image ) + cvReleaseImage( &small_image ); + + cvReleaseMemStorage( &storage ); +} + +static u32 OCV_Run(void *par) +{ + IplImage* image; + CvCapture *capture; + GF_InputSensorDevice *ifce = (GF_InputSensorDevice *)par; + GF_OpenCV *ocv = (GF_OpenCV *)ifce->udta; + + capture= cvCaptureFromCAM(0); + cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH,640 ); + cvSetCaptureProperty( capture, CV_CAP_PROP_FRAME_HEIGHT, 480 ); + + cvNamedWindow( "test", 0 ); + + image = NULL; + while (ocv->running) { + if (cvGrabFrame(capture)) { + CvHaarClassifierCascade* cascade; + + image = cvRetrieveFrame(capture); + + cascade = load_object_detector("haarcascade_frontalface_default.xml"); + detect_and_draw_objects(ifce, image, cascade, 1 ); + + + cvShowImage( "test", image ); + cvWaitKey(40); + } + } + if (image) cvReleaseImage( &image); + return 0; +} + +static void OCV_Start(struct __input_device *ifce) +{ + GF_OpenCV *ocv = (GF_OpenCV*)ifce->udta; + ocv->running = 1; + gf_th_run(ocv->th, OCV_Run, ifce); +} + +static void OCV_Stop(struct __input_device *ifce) +{ + GF_OpenCV *ocv = (GF_OpenCV*)ifce->udta; + ocv->running = 0; +} + + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_INPUT_DEVICE_INTERFACE, + 0 + }; + return si; +} + +GF_EXPORT +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + GF_InputSensorDevice *plug; + GF_OpenCV *udta; + if (InterfaceType != GF_INPUT_DEVICE_INTERFACE) return NULL; + + GF_SAFEALLOC(plug, GF_InputSensorDevice); + GF_REGISTER_MODULE_INTERFACE(plug, GF_INPUT_DEVICE_INTERFACE, "GPAC Demo InputSensor", "gpac distribution") + + plug->RegisterDevice = OCV_RegisterDevice; + plug->Start = OCV_Start; + plug->Stop = OCV_Stop; + + GF_SAFEALLOC(udta, GF_OpenCV); + plug->udta = udta; + udta->th = gf_th_new("OpenCV"); + + return (GF_BaseInterface *)plug; +} + +GF_EXPORT +void ShutdownInterface(GF_BaseInterface *bi) +{ + GF_InputSensorDevice *ifcn = (GF_InputSensorDevice*)bi; + if (ifcn->InterfaceType==GF_INPUT_DEVICE_INTERFACE) { + gf_free(bi); + } +} diff --git a/modules/opensvc_dec/Makefile b/modules/opensvc_dec/Makefile new file mode 100644 index 0000000..50345c8 --- /dev/null +++ b/modules/opensvc_dec/Makefile @@ -0,0 +1,59 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/opensvc_dec + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +LDFLAGS+=-lsvc + +#common obj +OBJS= opensvc_dec.o + +SRCS := $(OBJS:.o=.c) + +LIB=gm_opensvc_dec.$(DYN_LIB_SUFFIX) + + +all: $(LIB) + + +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_opensvc_dec-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif + + +%.o: %.c + $(CC) $(CFLAGS) -c -o $@ $< + + +clean: + rm -f $(OBJS) ../../bin/gcc/$(LIB) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/opensvc_dec/opensvc_dec.c b/modules/opensvc_dec/opensvc_dec.c new file mode 100644 index 0000000..eba5571 --- /dev/null +++ b/modules/opensvc_dec/opensvc_dec.c @@ -0,0 +1,372 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Telecom ParisTech 2010- + * Author(s): Jean Le Feuvre + * All rights reserved + * + * This file is part of GPAC / OpenSVC Decoder 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/modules/codec.h> +#include <gpac/avparse.h> +#include <gpac/constants.h> + +typedef struct{ + int Width; + int Height; + unsigned char* pY[1]; + unsigned char* pU[1]; + unsigned char* pV[1]; +} OPENSVCFRAME; + + +enum { + SVC_STATUS_ERROR = -1, + SVC_STATUS_OK = 0, // no error and no frame ready + SVC_IMAGE_READY = 1, // no error and image ready + SVC_GHOST_IMAGE = 2 // no image for chosen layer but image could be ready for other layers +}; + +int SVCDecoder_init(void **PlayerStruct); +int SVCDecoder_close(void *PlayerStruct); +int decodeNAL(void *PlayerStruct, unsigned char* nal, int nal_length, OPENSVCFRAME *Frame, int DqIdMax); +/*ID vient du NAL type 14 et 20*/ +int setLayer(int num_layer); +void ParseAuPlayers(void *PlayerStruct, const unsigned char *buf, int buf_size, int nal_length_size, int is_avc); +int GetDqIdMax(const unsigned char *buf, int buf_size, int nal_length_size, int *DqidTable, int is_avc); +int Geth264NalSize(const unsigned char *buf, int buf_size, int *bufindex); +void UpdateLayer(int *DqIdTable, int *CurrDqId, int MaxDqId, int Command); + + +typedef struct +{ + u16 ES_ID; + u32 width, stride, height, out_size, pixel_ar, layer; + Bool first_frame; + + u32 nalu_size_length; + + /*OpenSVC things*/ + void *codec; + int InitParseAU; + int svc_init_done; + int save_Width; + int save_Height; + int CurrDqId; + int MaxDqId; + int DqIdTable [8]; +} OSVCDec; + + +static GF_Err OSVC_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) +{ + u32 i, count; + s32 res; + OPENSVCFRAME Picture; + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + + /*not supported in this version*/ + if (esd->dependsOnESID) return GF_NOT_SUPPORTED; + + ctx->ES_ID = esd->ESID; + ctx->width = ctx->height = ctx->out_size = 0; + + if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { + GF_AVCConfig *cfg = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + if (!cfg) return GF_NON_COMPLIANT_BITSTREAM; + ctx->nalu_size_length = cfg->nal_unit_size; + if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR; + + /*decode all NALUs*/ + count = gf_list_count(cfg->sequenceParameterSets); + for (i=0; i<count; i++) { + u32 w, h, par_n, par_d; + GF_AVCConfigSlot *slc = gf_list_get(cfg->sequenceParameterSets, i); + + gf_avc_get_sps_info(slc->data, slc->size, &w, &h, &par_n, &par_d); + /*by default use the base layer*/ + if (!i) { + if ((ctx->width<w) || (ctx->height<h)) { + ctx->width = w; + ctx->height = h; + if ( ((s32)par_n>0) && ((s32)par_d>0) ) + ctx->pixel_ar = (par_n<<16) || par_d; + } + } + res = decodeNAL(ctx->codec, slc->data, slc->size, &Picture, 0); + if (res<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding SPS %d\n", res)); + } + } + + count = gf_list_count(cfg->pictureParameterSets); + for (i=0; i<count; i++) { + GF_AVCConfigSlot *slc = gf_list_get(cfg->pictureParameterSets, i); + res = decodeNAL(ctx->codec, slc->data, slc->size, &Picture, 0); + if (res<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SVC Decoder] Error decoding PPS %d\n", res)); + } + } + + gf_odf_avc_cfg_del(cfg); + } else { + ctx->nalu_size_length = 0; + if (SVCDecoder_init(&ctx->codec) == SVC_STATUS_ERROR) return GF_IO_ERR; + } + ctx->stride = ctx->width + 32; + ctx->layer = 0; + setLayer(ctx->layer); + ctx->out_size = ctx->stride * ctx->height * 3 / 2; + return GF_OK; +} +static GF_Err OSVC_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) +{ + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + + if (ctx->codec) SVCDecoder_close(ctx->codec); + ctx->codec = NULL; + ctx->width = ctx->height = ctx->out_size = 0; + return GF_OK; +} +static GF_Err OSVC_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *capability) +{ + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + + switch (capability->CapCode) { + case GF_CODEC_RESILIENT: + capability->cap.valueInt = 1; + break; + case GF_CODEC_WIDTH: + capability->cap.valueInt = ctx->width; + break; + case GF_CODEC_HEIGHT: + capability->cap.valueInt = ctx->height; + break; + case GF_CODEC_STRIDE: + capability->cap.valueInt = ctx->stride; + break; + case GF_CODEC_PAR: + capability->cap.valueInt = ctx->pixel_ar; + break; + case GF_CODEC_OUTPUT_SIZE: + capability->cap.valueInt = ctx->out_size; + break; + case GF_CODEC_PIXEL_FORMAT: + capability->cap.valueInt = GF_PIXEL_YV12; + break; + case GF_CODEC_BUFFER_MIN: + capability->cap.valueInt = 1; + break; + case GF_CODEC_BUFFER_MAX: + capability->cap.valueInt = 4; + break; + case GF_CODEC_PADDING_BYTES: + capability->cap.valueInt = 32; + break; + case GF_CODEC_REORDER: + capability->cap.valueInt = 1; + break; + /*not known at our level...*/ + case GF_CODEC_CU_DURATION: + default: + capability->cap.valueInt = 0; + break; + } + return GF_OK; +} +static GF_Err OSVC_SetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability capability) +{ + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + switch (capability.CapCode) { + case GF_CODEC_MEDIA_SWITCH_QUALITY: + if (capability.cap.valueInt) { + if (ctx->layer<32) { + ctx->layer += 8; + setLayer(ctx->layer); + } + } else { + if (ctx->layer>=8) { + ctx->layer -= 8; + setLayer(ctx->layer); + } + } + return GF_OK; + } + /*return unsupported to avoid confusion by the player (like color space changing ...) */ + return GF_NOT_SUPPORTED; + +} + +static GF_Err OSVC_ProcessData(GF_MediaDecoder *ifcg, + char *inBuffer, u32 inBufferLength, + u16 ES_ID, + char *outBuffer, u32 *outBufferLength, + u8 PaddingBits, u32 mmlevel) +{ + + s32 got_pic; + OPENSVCFRAME pic; + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + + if (!ES_ID || (ES_ID!=ctx->ES_ID) || !ctx->codec) { + *outBufferLength = 0; + return GF_OK; + } + if (*outBufferLength < ctx->out_size) { + *outBufferLength = ctx->out_size; + return GF_BUFFER_TOO_SMALL; + } + + got_pic = 0; + if (ctx->nalu_size_length) { + u32 i, nalu_size = 0; + u8 *ptr = inBuffer; + + ctx->MaxDqId = GetDqIdMax(inBuffer, inBufferLength, ctx->nalu_size_length, ctx->DqIdTable, 1); + if(!ctx->InitParseAU){ + if (ctx->MaxDqId == -1) { + //AVC stream in a h264 file + ctx->MaxDqId = 0; + } else { +// ChangeOfLayer(ctx->MaxDqId, 2); +// ParseCmd(h); //mplayer pb with slice. Slice on the upper layer, end_of_slice is equal to 1 in the slice header of the 5. so no switch Layer +// + //Firts time only, we parse the first AU to know the file configuration + //does not need to ba called again ever after, unless SPS or PPS changed + UpdateLayer(ctx->DqIdTable, &ctx->CurrDqId, ctx->MaxDqId, 0); + ParseAuPlayers(ctx->codec, inBuffer, inBufferLength, ctx->nalu_size_length, 1); + } + ctx->InitParseAU = 1; + } + + while (inBufferLength) { + for (i=0; i<ctx->nalu_size_length; i++) { + nalu_size = (nalu_size<<8) + ptr[i]; + } + ptr += ctx->nalu_size_length; + + if (!got_pic) + got_pic = decodeNAL(ctx->codec, ptr, nalu_size, &pic, ctx->MaxDqId); + else + decodeNAL(ctx->codec, ptr, nalu_size, &pic, ctx->MaxDqId); + + ptr += nalu_size; + if (inBufferLength < nalu_size + ctx->nalu_size_length) break; + + inBufferLength -= nalu_size + ctx->nalu_size_length; + } + } else { + } + if (got_pic!=1) return GF_OK; + + if ((pic.Width != ctx->width) || (pic.Height!=ctx->height)) { + ctx->width = pic.Width; + ctx->stride = pic.Width + 32; + ctx->height = pic.Height; + ctx->out_size = ctx->stride * ctx->height * 3 / 2; + + /*always force layer resize*/ + *outBufferLength = ctx->out_size; + return GF_BUFFER_TOO_SMALL; + } + *outBufferLength = ctx->out_size; + memcpy(outBuffer, pic.pY[0], ctx->stride*ctx->height); + memcpy(outBuffer + ctx->stride * ctx->height, pic.pU[0], ctx->stride*ctx->height/4); + memcpy(outBuffer + 5*ctx->stride * ctx->height/4, pic.pV[0], ctx->stride*ctx->height/4); + + return GF_OK; +} + +static Bool OSVC_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, u32 ObjectType, char *decSpecInfo, u32 decSpecInfoSize, u32 PL) +{ + if (StreamType != GF_STREAM_VISUAL) return 0; + switch (ObjectType) { + case GPAC_OTI_VIDEO_AVC: + return 1; + /*cap query*/ + case 0: + return 1; + } + return 0; +} + +static const char *OSVC_GetCodecName(GF_BaseDecoder *dec) +{ + return "OpenSVC Decoder"; +} + +GF_BaseDecoder *NewOSVCDec() +{ + GF_MediaDecoder *ifcd; + OSVCDec *dec; + + GF_SAFEALLOC(ifcd, GF_MediaDecoder); + GF_SAFEALLOC(dec, OSVCDec); + GF_REGISTER_MODULE_INTERFACE(ifcd, GF_MEDIA_DECODER_INTERFACE, "OpenSVC Decoder", "gpac distribution") + + ifcd->privateStack = dec; + + /*setup our own interface*/ + ifcd->AttachStream = OSVC_AttachStream; + ifcd->DetachStream = OSVC_DetachStream; + ifcd->GetCapabilities = OSVC_GetCapabilities; + ifcd->SetCapabilities = OSVC_SetCapabilities; + ifcd->GetName = OSVC_GetCodecName; + ifcd->CanHandleStream = OSVC_CanHandleStream; + ifcd->ProcessData = OSVC_ProcessData; + return (GF_BaseDecoder *) ifcd; +} + +void DeleteOSVCDec(GF_BaseDecoder *ifcg) +{ + OSVCDec *ctx = (OSVCDec*) ifcg->privateStack; + gf_free(ctx); + gf_free(ifcg); +} + +const u32 *QueryInterfaces() +{ + static u32 si [] = { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_MEDIA_DECODER_INTERFACE, +#endif + 0 + }; + return si; +} + +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ +#ifndef GPAC_DISABLE_AV_PARSERS + if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)NewOSVCDec(); +#endif + return NULL; +} + +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_AV_PARSERS + case GF_MEDIA_DECODER_INTERFACE: + DeleteOSVCDec((GF_BaseDecoder*)ifce); + break; +#endif + } +} diff --git a/modules/oss_audio/Makefile b/modules/oss_audio/Makefile index 643dc5b..c4354d0 100644 --- a/modules/oss_audio/Makefile +++ b/modules/oss_audio/Makefile @@ -31,16 +31,14 @@ SRCS := $(OBJS:.o=.c) LIB=gm_oss_audio.$(DYN_LIB_SUFFIX) -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac $(OSS_LDFLAGS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac $(OSS_LDFLAGS) +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_oss_audio-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static $(OSS_LDFLAGS) +endif %.o: %.c diff --git a/modules/oss_audio/oss.c b/modules/oss_audio/oss.c index 079d113..f1f338f 100644 --- a/modules/oss_audio/oss.c +++ b/modules/oss_audio/oss.c @@ -89,9 +89,9 @@ static GF_Err OSS_Setup(GF_AudioOutput*dr, void *os_handle, u32 num_buffers, u32 static void OSS_Shutdown(GF_AudioOutput*dr) { OSSCTX(); - ioctl(ctx->audio_dev,SNDCTL_DSP_RESET); + ioctl(ctx->audio_dev,SNDCTL_DSP_RESET,NULL); close(ctx->audio_dev); - if (ctx->wav_buf) free(ctx->wav_buf); + if (ctx->wav_buf) gf_free(ctx->wav_buf); ctx->wav_buf = NULL; } @@ -104,9 +104,9 @@ static GF_Err OSS_ConfigureOutput(GF_AudioOutput*dr, u32 *SampleRate, u32 *NbCha if (!ctx) return GF_BAD_PARAM; /* reset and reopen audio-device */ - ioctl(ctx->audio_dev,SNDCTL_DSP_RESET); + ioctl(ctx->audio_dev,SNDCTL_DSP_RESET,NULL); close(ctx->audio_dev); - if (ctx->wav_buf) free(ctx->wav_buf); + if (ctx->wav_buf) gf_free(ctx->wav_buf); ctx->wav_buf = NULL; ctx->audio_dev=open(OSS_AUDIO_DEVICE,O_WRONLY|O_NONBLOCK); if (!ctx->audio_dev) return GF_IO_ERR; @@ -146,7 +146,7 @@ static GF_Err OSS_ConfigureOutput(GF_AudioOutput*dr, u32 *SampleRate, u32 *NbCha if ( ioctl(ctx->audio_dev, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0 ) return GF_IO_ERR; GF_LOG(GF_LOG_DEBUG, GF_LOG_MMIO, ("[OSS] setup %d buffers %d bytes each (%d ms buffer delay)", nb_bufs, ctx->buf_size, ctx->delay)); - ctx->wav_buf = realloc(ctx->wav_buf, ctx->buf_size*sizeof(char)); + ctx->wav_buf = gf_realloc(ctx->wav_buf, ctx->buf_size*sizeof(char)); if(!ctx->wav_buf) return GF_OUT_OF_MEM; memset(ctx->wav_buf, 0, ctx->buf_size*sizeof(char)); return GF_OK; @@ -158,7 +158,12 @@ static void OSS_WriteAudio(GF_AudioOutput*dr) OSSCTX(); written = dr->FillBuffer(dr->audio_renderer, ctx->wav_buf, ctx->buf_size); /*this will also perform sleep*/ - if (written) write(ctx->audio_dev, ctx->wav_buf, written); + if (written){ + u32 reallyWritten = write(ctx->audio_dev, ctx->wav_buf, written); + if (reallyWritten != written){ + GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[OSS] Failed to write all audio to device, has written %u, should have %u", reallyWritten, written)); + } + } } static void OSS_SetVolume(GF_AudioOutput*dr, u32 Volume) {} @@ -211,14 +216,14 @@ void *NewOSSRender() { OSSContext *ctx; GF_AudioOutput*driv; - ctx = malloc(sizeof(OSSContext)); + ctx = gf_malloc(sizeof(OSSContext)); if(!ctx) return NULL; memset(ctx, 0, sizeof(OSSContext)); - driv = malloc(sizeof(GF_AudioOutput)); + driv = gf_malloc(sizeof(GF_AudioOutput)); if(!driv) { - free(ctx); + gf_free(ctx); ctx=NULL; return NULL; } @@ -243,8 +248,8 @@ void DeleteOSSRender(void *ifce) { GF_AudioOutput*dr = (GF_AudioOutput*) ifce; OSSContext *ctx = (OSSContext *)dr->opaque; - free(ctx); - free(dr); + gf_free(ctx); + gf_free(dr); } @@ -252,11 +257,13 @@ void DeleteOSSRender(void *ifce) * ******************************************************************** * interface */ -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) - return 1; - return 0; + static u32 si [] = { + GF_AUDIO_OUTPUT_INTERFACE, + 0 + }; + return si; } GF_BaseInterface *LoadInterface(u32 InterfaceType) diff --git a/modules/platinum/GPACFileMediaServer.cpp b/modules/platinum/GPACFileMediaServer.cpp new file mode 100644 index 0000000..8b55958 --- /dev/null +++ b/modules/platinum/GPACFileMediaServer.cpp @@ -0,0 +1,570 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + +#include "PltUPnP.h" +#include "GPACFileMediaServer.h" +#include "PltMediaItem.h" +#include "PltService.h" +#include "PltTaskManager.h" +#include "PltHttpServer.h" +#include "PltDidl.h" +#include "PltMetadataHandler.h" +#include "PltVersion.h" + +#include <gpac/network.h> + +NPT_SET_LOCAL_LOGGER("gpac.media.server.file") + +GPAC_FileMediaServer::GPAC_FileMediaServer(const char* friendly_name, + bool show_ip, + const char* uuid, + NPT_UInt16 port) : PLT_FileMediaServer("", friendly_name, show_ip, uuid, port) +{ +} + +void GPAC_FileMediaServer::AddSharedDirectory(const char *path, const char *alias, Bool is_hidden) +{ + u8 buf[10]; + if (!alias) { + sprintf((char*)buf, "%08X", gf_crc_32((char*) path, strlen(path))); + alias = (const char *)buf; + } + m_Directories.Add(GPAC_MediaDirectory(alias, path, is_hidden)); +} + + + +NPT_Result +GPAC_FileMediaServer::OnBrowseDirectChildren(PLT_ActionReference& action, + const char* object_id, + const char* filter, + NPT_UInt32 start_index, + NPT_UInt32 req_count, + const NPT_List<NPT_String>& sort_criteria, + const PLT_HttpRequestContext& context) +{ + /*not the root of our server*/ + if (strcmp(object_id, "/") && strcmp(object_id, "\\") && strcmp(object_id, "0")) { + return PLT_FileMediaServer::OnBrowseDirectChildren(action, object_id, filter, start_index, req_count, sort_criteria, context); + } + + unsigned long cur_index = 0; + unsigned long num_returned = 0; + unsigned long total_matches = 0; + NPT_String didl = didl_header; + + PLT_MediaObjectReference item; + for (u32 i=0; i<m_Directories.GetItemCount(); i++) { + GPAC_MediaDirectory *alias; + m_Directories.Get(i, alias); + if (alias->m_Hide) continue; + + item = BuildFromFilePath(alias->m_Path, context, true, false); + + if (!item.IsNull()) { + if ((cur_index >= start_index) && ((num_returned < req_count) || (req_count == 0))) { + NPT_String tmp; + NPT_CHECK_SEVERE(PLT_Didl::ToDidl(*item.AsPointer(), filter, tmp)); + + didl += tmp; + num_returned++; + } + cur_index++; + total_matches++; + } + }; + + didl += didl_footer; + + NPT_CHECK_SEVERE(action->SetArgumentValue("Result", didl)); + NPT_CHECK_SEVERE(action->SetArgumentValue("NumberReturned", NPT_String::FromInteger(num_returned))); + NPT_CHECK_SEVERE(action->SetArgumentValue("TotalMatches", NPT_String::FromInteger(total_matches))); // 0 means we don't know how many we have but most browsers don't like that!! + NPT_CHECK_SEVERE(action->SetArgumentValue("UpdateId", "1")); + + return NPT_SUCCESS; +} + +NPT_Result +GPAC_FileMediaServer::ServeFile(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response, + const NPT_String& _file_path) +{ + NPT_COMPILER_UNUSED(context); + + NPT_String file_path = _file_path; + NPT_String uri_path = NPT_Uri::PercentDecode(request.GetUrl().GetPath()); + NPT_String query = request.GetUrl().GetQuery(); + if (! query.IsEmpty()) { + uri_path += "?"; + uri_path += query; + } + + // prevent hackers from accessing files outside of our root + if ((file_path.Find("/..") >= 0) || (file_path.Find("\\..") >= 0)) { + return NPT_FAILURE; + } + + NPT_String file_id = (const char *) file_path + ((file_path[0]=='0') ? 2:1); + for (u32 i=0; i<m_Directories.GetItemCount(); i++) { + GPAC_MediaDirectory *dir; + m_Directories.Get(i, dir); + if (file_id.StartsWith(dir->m_Alias)) { + file_path = dir->m_Path + ((const char *) file_id + strlen(dir->m_Alias)+1); + break; + } + } + + //Virtual File request + for (u32 i=0; i<m_VirtualFiles.GetItemCount(); i++) { + GPAC_VirtualFile vfile; + m_VirtualFiles.Get(i, vfile); + + NPT_String path = uri_path; + path.Replace('/', NPT_FilePath::Separator); + + if (path == vfile.m_URI) { + NPT_Result res; + NPT_Position start, end; + PLT_HttpHelper::GetRange(request, start, end); + res = ServeVirtualFile(response, &vfile, start, end, !request.GetMethod().Compare("HEAD")); + if (vfile.m_temporary) { + m_VirtualFiles.Remove(vfile); + } + return res; + } + } + + // File requested + NPT_String path = m_FileBaseUri.GetPath(); + if (path.Compare(uri_path.Left(path.GetLength()), true) == 0) { + NPT_Position start, end; + PLT_HttpHelper::GetRange(request, start, end); + + return PLT_FileServer::ServeFile(response, + file_path, + start, + end, + !request.GetMethod().Compare("HEAD")); + } + + // Album Art requested + path = m_AlbumArtBaseUri.GetPath(); + if (path.Compare(uri_path.Left(path.GetLength()), true) == 0) { + return OnAlbumArtRequest(response, file_path); + } + + return NPT_FAILURE; +} + +NPT_Result +GPAC_FileMediaServer::GetFilePath(const char* object_id, + NPT_String& filepath) +{ + if (!object_id) return NPT_ERROR_INVALID_PARAMETERS; + + NPT_String obj_id = object_id + (object_id[0]=='0' ? 2 : 1); + filepath = ""; + for (u32 i=0; i<m_Directories.GetItemCount(); i++) { + GPAC_MediaDirectory *dir; + m_Directories.Get(i, dir); + if (obj_id.StartsWith(dir->m_Alias)) { + filepath = dir->m_Path; + object_id += (object_id[0]=='0' ? 2 : 1); + if (!strcmp(object_id, dir->m_Alias)) { + object_id = ""; + } else { + object_id += strlen(dir->m_Alias) + 1; + } + break; + } + } + + if (NPT_StringLength(object_id) > 2 || object_id[0]!='0') { + filepath += (const char*)object_id + (object_id[0]=='0'?1:0); + } + + return NPT_SUCCESS; +} + +PLT_MediaObject* +GPAC_FileMediaServer::BuildFromFilePath(const NPT_String& filepath, + const PLT_HttpRequestContext &context, + bool with_count, + bool keep_extension_in_title) +{ + return BuildFromFilePathAndHost(filepath, &context, with_count, keep_extension_in_title, NULL); + +} + +PLT_MediaObject* +GPAC_FileMediaServer::BuildFromFilePathAndHost(const NPT_String& __filepath, + const PLT_HttpRequestContext *context, + bool with_count /* = true */, + bool keep_extension_in_title /* = false */, + const char *host) +{ + PLT_MediaItemResource resource; + PLT_MediaObject* object = NULL; + NPT_String filepath = __filepath; + unsigned int len; + + /* retrieve the entry type (directory or file) */ + NPT_FileInfo info; + NPT_CHECK_LABEL_FATAL(NPT_File::GetInfo(__filepath, &info), failure); + + len = 0; + for (u32 i=0; i<m_Directories.GetItemCount(); i++) { + GPAC_MediaDirectory *dir; + m_Directories.Get(i, dir); + if (__filepath.StartsWith(dir->m_Path) && (dir->m_Path.GetLength() > len) ) { + char *fp = __filepath; + filepath = NPT_FilePath::Separator + dir->m_Alias + NPT_String( fp + strlen(dir->m_Path) - 1); + len = dir->m_Path.GetLength(); + } + } + + + if (info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR) { + NPT_IpAddress ip; + + object = new PLT_MediaItem(); + + /* Set the title using the filename for now */ + object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title); + if (object->m_Title.GetLength() == 0) goto failure; + + /* Set the protocol Info from the extension */ + resource.m_ProtocolInfo = PLT_ProtocolInfo(PLT_MediaItem::GetProtocolInfo(filepath, true, context)); + if (!resource.m_ProtocolInfo.IsValid()) goto failure; + + /* Set the resource file size */ + resource.m_Size = info.m_Size; + + /* format the resource URI */ + NPT_String url = "0" + filepath; + + + if (host) { + ip.Parse(host); + + NPT_List<NPT_NetworkInterface*> if_list; + NPT_List<NPT_NetworkInterface*>::Iterator net_if; + NPT_List<NPT_NetworkInterfaceAddress>::Iterator net_if_addr; + + NPT_CHECK_LABEL_SEVERE(PLT_UPnPMessageHelper::GetNetworkInterfaces(if_list, true), failure); + + for (net_if = if_list.GetFirstItem(); net_if; net_if++) { + if ( (*net_if)->IsAddressInNetwork(ip) ) { + ip = (*net_if)->GetAddresses().GetFirstItem()->GetPrimaryAddress(); + break; + } + } + + } else if (context) { + ip = context->GetLocalAddress().GetIpAddress(); + } else { + // get list of ip addresses + NPT_List<NPT_IpAddress> ips; + NPT_CHECK_LABEL_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(ips), failure); + + // iterate through list and build list of resources + NPT_List<NPT_IpAddress>::Iterator ipi = ips.GetFirstItem(); + + ip = *ipi; + } + + /* Look to see if a metadatahandler exists for this extension */ + PLT_MetadataHandler* handler = NULL; + NPT_Result res = NPT_ContainerFind( + m_MetadataHandlers, + PLT_MetadataHandlerFinder(NPT_FilePath::FileExtension(filepath)), + handler); + if (NPT_SUCCEEDED(res) && handler) { + /* if it failed loading data, reset the metadatahandler so we don't use it */ + if (NPT_SUCCEEDED(handler->Load(filepath))) { + /* replace the title with the one from the Metadata */ + NPT_String newTitle; + if (handler->GetTitle(newTitle) != NULL) { + object->m_Title = newTitle; + } + + /* assign description */ + handler->GetDescription(object->m_Description.long_description); + + /* assign album art uri if we haven't yet */ + /* prepend the album art base URI and url encode it */ + if (object->m_ExtraInfo.album_art_uri.GetLength() == 0) { + object->m_ExtraInfo.album_art_uri = + NPT_Uri::PercentEncode(BuildResourceUri(m_AlbumArtBaseUri, ip.ToString(), url), + NPT_Uri::UnsafeCharsToEncode); + } + + /* duration */ + handler->GetDuration(resource.m_Duration); + + /* protection */ + handler->GetProtection(resource.m_Protection); + } + } + + object->m_ObjectClass.type = PLT_MediaItem::GetUPnPClass(filepath, context); + + resource.m_Uri = BuildResourceUri(m_FileBaseUri, ip.ToString(), url); + object->m_Resources.Add(resource); + + } else { + object = new PLT_MediaContainer; + + /* Assign a title for this container */ + if ((filepath.Compare("/", true) == 0) || (filepath.Compare("\\", true) == 0)) { + object->m_Title = "Root"; + } else { + filepath.TrimRight("/\\"); + object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title); + if (object->m_Title.GetLength() == 0) goto failure; + } + +#ifndef _WIN32_WCE + /* Get the number of children for this container */ + NPT_Cardinal count = 0; + if (with_count && NPT_SUCCEEDED(NPT_File::GetCount(__filepath, count))) { + ((PLT_MediaContainer*)object)->m_ChildrenCount = count; + } +#endif //_WIN32_WCE + + object->m_ObjectClass.type = "object.container"; + } + + /* is it the root? */ + if ((filepath.Compare("/", true) == 0) || (filepath.Compare("\\", true) == 0)) { + object->m_ParentID = "-1"; + object->m_ObjectID = "0"; + } else { + NPT_String directory = NPT_FilePath::DirName(filepath); + /* is the parent path the root? */ + if ((directory.Compare("/", true) == 0) || (directory.Compare("\\", true) == 0)) { + object->m_ParentID = "0"; + } else { + object->m_ParentID = "0" + directory; + } + object->m_ObjectID = "0" + filepath; + } + return object; + +failure: + delete object; + return NULL; +} + + +NPT_String GPAC_FileMediaServer::GetResourceURI(const char *url, const char *for_host) +{ + char *abs_url; + NPT_String res = url, path; + + abs_url = NULL; + for (u32 i=0; i<m_Directories.GetItemCount(); i++) { + GPAC_MediaDirectory *dir; + m_Directories.Get(i, dir); + abs_url = gf_url_concatenate(dir->m_Path, url); + FILE *f = gf_f64_open(abs_url, "rt"); + if (f) { + fclose(f); + break; + } + gf_free((void*)abs_url); + abs_url = NULL; + } + if (!abs_url ) return res; + + /*url was absolute, add its root directory*/ + if (!strcmp(abs_url, url)) { + Bool found = 0; + NPT_String newdir; + /*if the path is /my/example/path/test.ext, we want to share the parent directory + /my/example/, otherwise we will loose the ability to browse for resource in the parent dir + */ + u32 nb_sep=0; + u32 len = strlen(abs_url); + u32 i=0; + while (i<=len) { + if ((abs_url[len-i]=='\\') || (abs_url[len-i]=='/') ) { + nb_sep++; + if (nb_sep==2) break; + } + i++; + } + /*if no parent directory, we don't allow sharing of the resource*/ + if (nb_sep!=2) return ""; + + char sep = abs_url[len-i]; + abs_url[len-i] = 0; + newdir = abs_url; + abs_url[len-i] = sep; + + newdir.Replace('/', NPT_FilePath::Separator); + newdir += NPT_FilePath::Separator; + + for (u32 i=0; i<m_Directories.GetItemCount(); i++) { + GPAC_MediaDirectory *dir; + m_Directories.Get(i, dir); + if (!strcmp(newdir, dir->m_Path)) { + found = 1; + } + } + if (!found) + AddSharedDirectory(newdir, NULL, 1); + } + + path = abs_url; + /*replace all '/' with neptune file path separator otherwise file functions get screwed up ...*/ + path.Replace('/', NPT_FilePath::Separator); + + gf_free((void*)abs_url); + + PLT_MediaObject*mobj = BuildFromFilePathAndHost(path, NULL, true, false, for_host); + if (mobj) { + res = mobj->m_Resources[0].m_Uri; + delete mobj; + } + return res; +} + +void GPAC_FileMediaServer::ShareVirtualResource(const char *res_uri, const char *res_val, const char *res_mime, Bool temporary) +{ + NPT_String the_uri; + char *uri = (char *)res_uri; + char *sep = (char *) strstr(res_uri, "://"); + if (sep) { + sep = strchr(sep+3, '/'); + if (sep) uri = sep; + else uri="/"; + } + the_uri = ""; + while (1) { + sep = strchr(uri, '%'); + if (!sep) break; + + if (!strnicmp(sep, "%3f", 3) || !strnicmp(sep, "%5c", 3) || !strnicmp(sep, "%2f", 3)) { + sep[0]=0; + the_uri += uri; + sep[0]='%'; + + if (!strnicmp(sep, "%3f", 3)) + the_uri += "?"; + else if (!strnicmp(sep, "%5c", 3)) + the_uri += "/"; + else + the_uri += " "; + uri= sep+3; + continue; + } else { + the_uri += "%"; + uri= sep+1; + } + } + the_uri += uri; + the_uri.Replace('/', NPT_FilePath::Separator); + + 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); +} + +NPT_Result +GPAC_FileMediaServer::ServeVirtualFile(NPT_HttpResponse& response, + GPAC_VirtualFile *vfile, + NPT_Position start, + NPT_Position end, + bool request_is_head) +{ + NPT_LargeSize total_len; + NPT_Result result; + + NPT_MemoryStream* memory_stream = new NPT_MemoryStream(vfile->m_Content.GetChars(), vfile->m_Content.GetLength() ); + NPT_InputStreamReference stream(memory_stream); + + if (NPT_FAILED(result = stream->GetSize(total_len)) ) { + response.SetStatus(404, "File Not Found"); + return NPT_SUCCESS; + } + + fprintf(stdout, "Serving virtual file %s\n", vfile->m_Content.GetChars()); + + NPT_HttpEntity* entity = new NPT_HttpEntity(); + entity->SetContentLength(total_len); + response.SetEntity(entity); + entity->SetContentType(vfile->m_MIME); + + // request is HEAD, returns without setting a body + if (request_is_head) return NPT_SUCCESS; + + // see if it was a byte range request + if (start != (NPT_Position)-1 || end != (NPT_Position)-1) { + // we can only support a range from an offset to the end of the resource for now + // due to the fact we can't limit how much to read from a stream yet + NPT_Position start_offset = (NPT_Position)-1, end_offset = total_len - 1, len; + if (start == (NPT_Position)-1 && end != (NPT_Position)-1) { + // we are asked for the last N=end bytes + // adjust according to total length + if (end >= total_len) { + start_offset = 0; + } else { + start_offset = total_len-end; + } + } else if (start != (NPT_Position)-1) { + start_offset = start; + // if the end is specified but incorrect + // set the end_offset in order to generate a bad response + if (end != (NPT_Position)-1 && end < start) { + end_offset = (NPT_Position)-1; + } + } + + // in case the range request was invalid or we can't seek then respond appropriately + if (start_offset == (NPT_Position)-1 || end_offset == (NPT_Position)-1 || + start_offset > end_offset || NPT_FAILED(stream->Seek(start_offset))) { + response.SetStatus(416, "Requested range not satisfiable"); + } else { + len = end_offset - start_offset + 1; + response.SetStatus(206, "Partial Content"); + PLT_HttpHelper::SetContentRange(response, start_offset, end_offset, total_len); + + entity->SetInputStream(stream); + entity->SetContentLength(len); + } + } else { + entity->SetInputStream(stream); + } + return NPT_SUCCESS; +} + diff --git a/modules/platinum/GPACFileMediaServer.h b/modules/platinum/GPACFileMediaServer.h new file mode 100644 index 0000000..cdb2dfd --- /dev/null +++ b/modules/platinum/GPACFileMediaServer.h @@ -0,0 +1,138 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + + +#ifndef _GPAC_FILE_MEDIA_SERVER_H_ +#define _GPAC_FILE_MEDIA_SERVER_H_ + +#include "PltFileMediaServer.h" + +#include <gpac/list.h> + +#define MAX_PATH_LENGTH 1024 + +class PLT_MetadataHandler; + +class GPAC_MediaDirectory +{ +public: + /* + if is_hidden is set, directory is not visible during BrowseDirectChildren + if alias is NULL, a CRC32 of the path name will be used + */ + GPAC_MediaDirectory(const char *alias, const char *path, Bool is_hidden = 0) + { + m_Path = path; + m_Path.Replace('/', NPT_FilePath::Separator); + m_Path.TrimRight("/\\"); + m_Path += NPT_FilePath::Separator; + m_Alias = alias; + m_Alias.TrimRight("/\\"); + m_Alias.TrimLeft("/\\"); + m_Hide = is_hidden; + } + NPT_String m_Path; + NPT_String m_Alias; + Bool m_Hide; +}; + +class GPAC_VirtualFile +{ +public: + GPAC_VirtualFile(const char *uri="", const char *val="", const char *mime="", Bool temporary=0) + { + m_URI = uri; + m_Content = val; + m_MIME = mime; + m_temporary = temporary; + } + bool operator==(const GPAC_VirtualFile & v1) { + return m_URI==v1.m_URI; + } + + NPT_String m_URI; + NPT_String m_Content; + NPT_String m_MIME; + Bool m_temporary; +}; + +class GPAC_FileMediaServer : public PLT_FileMediaServer +{ +public: + GPAC_FileMediaServer(const char* friendly_name, + bool show_ip = false, + const char* uuid = NULL, + NPT_UInt16 port = 0); + + + void AddSharedDirectory(const char *path, const char *alias, Bool is_hidden = 0); + + NPT_String GetResourceURI(const char *file_path, const char *for_host); + void ShareVirtualResource(const char *res_uri, const char *res_val, const char *res_mime, Bool temporary = 0); + +protected: + virtual NPT_Result OnBrowseDirectChildren(PLT_ActionReference& action, + const char* object_id, + const char* filter, + NPT_UInt32 starting_index, + NPT_UInt32 requested_count, + const NPT_List<NPT_String>& sort_criteria, + const PLT_HttpRequestContext& context); + + virtual NPT_Result GetFilePath(const char* object_id, NPT_String& filepath); + + virtual NPT_Result ServeFile(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response, + const NPT_String& file_path); + + virtual PLT_MediaObject* BuildFromFilePath(const NPT_String& filepath, + const PLT_HttpRequestContext& context, + bool with_count = true, + bool keep_extension_in_title = false); + + PLT_MediaObject* BuildFromFilePathAndHost(const NPT_String& filepath, + const PLT_HttpRequestContext *context = NULL, + bool with_count = true, + bool keep_extension_in_title = false, + const char *for_host = NULL); + + NPT_Result ServeVirtualFile(NPT_HttpResponse& response, + GPAC_VirtualFile *vfile, + NPT_Position start, + NPT_Position end, + bool request_is_head); + +private: + NPT_List<GPAC_MediaDirectory> m_Directories; + NPT_List<GPAC_VirtualFile> m_VirtualFiles; +}; + +#endif /* _PLT_FILE_MEDIA_SERVER_H_ */ diff --git a/modules/platinum/GPACMediaController.cpp b/modules/platinum/GPACMediaController.cpp new file mode 100644 index 0000000..6dbf129 --- /dev/null +++ b/modules/platinum/GPACMediaController.cpp @@ -0,0 +1,323 @@ + +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + + +#include "GPACPlatinum.h" + +GPAC_MediaController::GPAC_MediaController(PLT_CtrlPointReference& ctrlPoint, GF_UPnP *upnp) +{ + m_MediaController = new PLT_MediaController(ctrlPoint, this); + m_MediaBrowser = new PLT_MediaBrowser(ctrlPoint, this); + + m_MediaServers = gf_list_new(); + m_MediaRenderers = gf_list_new(); + m_ControlPointLock = gf_mx_new("AVControlPoint"); + m_pUPnP = upnp; +} + + +GPAC_MediaController::~GPAC_MediaController() +{ + delete m_MediaController; + m_MediaController=NULL; + delete m_MediaBrowser; + m_MediaBrowser=NULL; + + while (gf_list_count(m_MediaServers)) { + GPAC_MediaServerItem*ms = (GPAC_MediaServerItem*)gf_list_get(m_MediaServers, 0); + gf_list_rem(m_MediaServers, 0); + delete ms; + } + gf_list_del(m_MediaServers); + + while (gf_list_count(m_MediaRenderers)) { + GPAC_MediaRendererItem *ms = (GPAC_MediaRendererItem *)gf_list_get(m_MediaRenderers, 0); + gf_list_rem(m_MediaRenderers, 0); + delete ms; + } + gf_list_del(m_MediaRenderers); + + gf_mx_del(m_ControlPointLock); +} + + + + +bool +GPAC_MediaController::OnMRAdded(PLT_DeviceDataReference& device) +{ + NPT_String uuid = device->GetUUID(); + + gf_mx_p(m_ControlPointLock); + + // test if it's a media renderer + PLT_Service* service; + if (NPT_SUCCEEDED(device->FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", service))) { + gf_list_add(m_MediaRenderers, new GPAC_MediaRendererItem(device, uuid) ); + } + m_pUPnP->OnMediaRendererAdd(device, 1); + gf_mx_v(m_ControlPointLock); + return true; +} + + +void +GPAC_MediaController::OnMRRemoved(PLT_DeviceDataReference& device) +{ + NPT_String uuid = device->GetUUID(); + + gf_mx_p(m_ControlPointLock); + + u32 i, count; + count = gf_list_count(m_MediaRenderers); + for (i=0; i<count; i++) { + GPAC_MediaRendererItem *ms = (GPAC_MediaRendererItem *) gf_list_get(m_MediaRenderers, i); + if (ms->m_UUID==uuid) { + delete ms; + gf_list_rem(m_MediaRenderers, i); + break; + } + } + + m_pUPnP->OnMediaRendererAdd(device, 0); + gf_mx_v(m_ControlPointLock); +} + +bool +GPAC_MediaController::OnMSAdded(PLT_DeviceDataReference& device) +{ + NPT_String uuid = device->GetUUID(); + + gf_mx_p(m_ControlPointLock); + // test if it's a media server + PLT_Service* service; + if (NPT_SUCCEEDED(device->FindServiceByType("urn:schemas-upnp-org:service:ContentDirectory:1", service))) { + gf_list_add(m_MediaServers, new GPAC_MediaServerItem(device, uuid) ); + } + m_pUPnP->OnMediaServerAdd(device, 1); + gf_mx_v(m_ControlPointLock); + return true; +} + + +void +GPAC_MediaController::OnMSRemoved(PLT_DeviceDataReference& device) +{ + NPT_String uuid = device->GetUUID(); + + gf_mx_p(m_ControlPointLock); + u32 i, count; + count = gf_list_count(m_MediaServers); + for (i=0; i<count; i++) { + GPAC_MediaServerItem *ms = (GPAC_MediaServerItem *) gf_list_get(m_MediaServers, i); + if (ms->m_UUID==uuid) { + delete ms; + gf_list_rem(m_MediaServers, i); + break; + } + } + m_pUPnP->OnMediaServerAdd(device, 0); + gf_mx_v(m_ControlPointLock); +} + + + +NPT_Result +GPAC_MediaController::OnActionResponse(NPT_Result res, + PLT_ActionReference& action, + void* userdata) +{ + return NPT_SUCCESS; +} + +NPT_Result GPAC_MediaController::OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars) +{ + return NPT_SUCCESS; +} + +void GPAC_MediaController::OnBrowseResult(NPT_Result res, PLT_DeviceDataReference& device, PLT_BrowseInfo* info, void* userdata) +{ + NPT_COMPILER_UNUSED(device); + + NPT_COMPILER_UNUSED(device); + + if (!userdata) return; + + PLT_BrowseDataReference* data = (PLT_BrowseDataReference*) userdata; + (*data)->res = res; + if (NPT_SUCCEEDED(res) && info) { + (*data)->info = *info; + } + (*data)->shared_var.SetValue(1); + delete data; +} + +void +GPAC_MediaController::OnMSStateVariablesChanged(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars) +{ + GPAC_MediaServerItem *ms = NULL; + gf_mx_p(m_ControlPointLock); + + u32 i, count; + count = gf_list_count(m_MediaServers); + for (i=0; i<count; i++) { + GPAC_MediaServerItem *ms = (GPAC_MediaServerItem *) gf_list_get(m_MediaServers, i); + if (ms->m_UUID==service->GetDevice()->GetUUID()) { + break; + } + ms = NULL; + } + + if (!ms) { + gf_mx_v(m_ControlPointLock); + return; + } + + PLT_StateVariable* var = PLT_StateVariable::Find(*vars, "ContainerUpdateIDs"); + if (var) { + // variable found, parse value + NPT_String value = var->GetValue(); + NPT_String item_id, update_id; + int index; + + while (value.GetLength()) { + // look for container id + index = value.Find(','); + if (index < 0) break; + item_id = value.Left(index); + value = value.SubString(index+1); + + // look for update id + if (value.GetLength()) { + index = value.Find(','); + update_id = (index<0)?value:value.Left(index); + value = (index<0)?"":value.SubString(index+1); + + m_pUPnP->ContainerChanged(ms->m_device, item_id, update_id); + } + } + } + gf_mx_v(m_ControlPointLock); +} + +NPT_Result +GPAC_MediaController::WaitForResponse(NPT_SharedVariable& shared_var) +{ + return shared_var.WaitUntilEquals(1, 30000); +} + + +NPT_Result +GPAC_MediaController::Browse(PLT_BrowseDataReference& browse_data, + PLT_DeviceDataReference& device, + const char* object_id, + NPT_Int32 index, + NPT_Int32 count, + bool browse_metadata, + const char* filter, + const char* sort) +{ + NPT_Result res; + + browse_data->shared_var.SetValue(0); + + // send off the browse packet. Note that this will + // not block. There is a call to WaitForResponse in order + // to block until the response comes back. + res = m_MediaBrowser->Browse(device, + (const char*)object_id, + index, + count, + browse_metadata, + filter, + sort, + new PLT_BrowseDataReference(browse_data)); + NPT_CHECK_SEVERE(res); + + return WaitForResponse(browse_data->shared_var); +} + +NPT_Result +GPAC_MediaController::Browse(GPAC_MediaServerItem *server, const char *object_id, const char *filter) +{ + NPT_Result res = NPT_FAILURE; + NPT_Int32 index = 0; + + // reset output params + server->m_BrowseResults = NULL; + + + do { + PLT_BrowseDataReference browse_data(new PLT_BrowseData()); + + // send off the browse packet. Note that this will + // not block. There is a call to WaitForResponse in order + // to block until the response comes back. + res = Browse(browse_data, + server->m_device, + (const char*)object_id, + index, + 1024, + false, + filter, + ""); + NPT_CHECK_LABEL_WARNING(res, done); + + if (NPT_FAILED(browse_data->res)) { + res = browse_data->res; + NPT_CHECK_LABEL_WARNING(res, done); + } + + if (browse_data->info.items->GetItemCount() == 0) + break; + + if (server->m_BrowseResults.IsNull()) { + server->m_BrowseResults = browse_data->info.items; + } else { + server->m_BrowseResults->Add(*browse_data->info.items); + // clear the list items so that the data inside is not + // cleaned up by PLT_MediaItemList dtor since we copied + // each pointer into the new list. + browse_data->info.items->Clear(); + } + + // stop now if our list contains exactly what the server said it had + if (browse_data->info.tm && browse_data->info.tm == server->m_BrowseResults->GetItemCount()) + break; + + // ask for the next chunk of entries + index = server->m_BrowseResults->GetItemCount(); + } while(1); + +done: + return res; +} + diff --git a/modules/platinum/GPACMediaController.h b/modules/platinum/GPACMediaController.h new file mode 100644 index 0000000..f996af5 --- /dev/null +++ b/modules/platinum/GPACMediaController.h @@ -0,0 +1,140 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + +#ifndef _GPAC_MEDIA_CONTROLLER_H_ +#define _GPAC_MEDIA_CONTROLLER_H_ + +#include "PltMediaServer.h" +#include "PltMediaController.h" +#include "PltMediaBrowser.h" +#include "NptMap.h" +#include "NptStack.h" + +#include <gpac/thread.h> + +typedef struct PLT_BrowseData { + NPT_SharedVariable shared_var; + NPT_Result res; + PLT_BrowseInfo info; +} PLT_BrowseData; + +/*basic class to hold each media renderer*/ +class GPAC_MediaRendererItem +{ +public: + GPAC_MediaRendererItem(PLT_DeviceDataReference device, NPT_String uuid) : m_device(device), m_UUID(uuid) { } + PLT_DeviceDataReference m_device; + NPT_String m_UUID; +}; + +/*basic class to hold each media server*/ +class GPAC_MediaServerItem +{ +public: + GPAC_MediaServerItem(PLT_DeviceDataReference device, NPT_String uuid) : m_device(device), m_UUID(uuid) , m_BrowseResults(NULL) { } + PLT_DeviceDataReference m_device; + NPT_String m_UUID; + /*results of the last browse request on this server*/ + PLT_MediaObjectListReference m_BrowseResults; + /*parent directory stack*/ + NPT_Stack<NPT_String> m_ParentDirectories; +}; + +typedef NPT_Reference<PLT_BrowseData> PLT_BrowseDataReference; + +class GF_UPnP; + +class GPAC_MediaController : public PLT_CtrlPointListener, + public PLT_MediaControllerDelegate, + public PLT_MediaBrowserDelegate +{ +public: + GPAC_MediaController(PLT_CtrlPointReference& ctrlPoint, GF_UPnP *upnp); + ~GPAC_MediaController(); + + virtual NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device) + { + return NPT_SUCCESS; + } + virtual NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device) + { + return NPT_SUCCESS; + } + virtual NPT_Result OnActionResponse(NPT_Result res, + PLT_ActionReference& action, + void* userdata); + virtual NPT_Result OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars); + + // PLT_MediaControllerDelegate + virtual bool OnMRAdded(PLT_DeviceDataReference& device); + virtual void OnMRRemoved(PLT_DeviceDataReference& device); + virtual void OnMRStateVariablesChanged(PLT_Service* /* service */, NPT_List<PLT_StateVariable*>* /* vars */) {}; + + + //PLT_MediaBrowserDelegate + virtual bool OnMSAdded(PLT_DeviceDataReference& device); + virtual void OnMSRemoved(PLT_DeviceDataReference& device); + virtual void OnMSStateVariablesChanged(PLT_Service *service, NPT_List<PLT_StateVariable*>* vars); + virtual void OnBrowseResult(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_BrowseInfo* info, + void* userdata); + + NPT_Result Browse(GPAC_MediaServerItem *server, const char *id, const char *filter); + + + GF_List *m_MediaRenderers; + GF_List *m_MediaServers; + + /* The UPnP MediaRenderer control point. */ + PLT_MediaController* m_MediaController; + /* The UPnP MediaServer control point. */ + PLT_MediaBrowser *m_MediaBrowser; + +protected: + NPT_Result Browse(PLT_BrowseDataReference& browse_data, + PLT_DeviceDataReference& device, + const char* object_id, + NPT_Int32 index, + NPT_Int32 count, + bool browse_metadata = false, + const char* filter = "*", + const char* sort = ""); + +private: + NPT_Result WaitForResponse(NPT_SharedVariable& shared_var); + + GF_UPnP *m_pUPnP; + GF_Mutex *m_ControlPointLock; + +}; + +#endif /* _GPAC_MEDIA_CONTROLLER_H_ */ + diff --git a/modules/platinum/GPACMediaRenderer.cpp b/modules/platinum/GPACMediaRenderer.cpp new file mode 100644 index 0000000..21caa1c --- /dev/null +++ b/modules/platinum/GPACMediaRenderer.cpp @@ -0,0 +1,583 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + +#include "GPACPlatinum.h" + +NPT_SET_LOCAL_LOGGER("gpac.media.renderer") + +extern NPT_UInt8 RDR_ConnectionManagerSCPD[]; +extern NPT_UInt8 RDR_AVTransportSCPD[]; +extern NPT_UInt8 RDR_RenderingControlSCPD[]; + + +void format_time_string(char *str, Double dur) +{ + u32 h, m, s; + h = (u32) (dur / 3600); + m = (u32) ( (dur - h*3600) / 60); + s = (u32) ((dur - h*3600 - m*60)); + sprintf(str, "%02d:%02d:%02d", h, m, s); +} + +GPAC_MediaRenderer::GPAC_MediaRenderer(GF_UPnP *upnp, const char* friendly_name, + bool show_ip, + const char* uuid, + unsigned int port) : + PLT_DeviceHost("/", uuid, "urn:schemas-upnp-org:device:MediaRenderer:1", friendly_name, show_ip, port) +{ + m_mediaHistoryList = gf_list_new(); + m_pUPnP = upnp; + m_connected = 0; + m_Duration = m_Time = 0; +} + +GPAC_MediaRenderer::~GPAC_MediaRenderer() +{ + if (m_mediaHistoryList) { + /* empty mediaHistoryList */ + while (gf_list_count(m_mediaHistoryList) > 0) { + char * last = (char*)gf_list_last(m_mediaHistoryList); + gf_list_rem_last(m_mediaHistoryList); + gf_free(last); + } + gf_list_del(m_mediaHistoryList); + } +} + +NPT_Result +GPAC_MediaRenderer::SetupServices(PLT_DeviceData& data) +{ + PLT_Service* service; + + { + /* AVTransport */ + m_pAVService = new PLT_Service( + &data, + "urn:schemas-upnp-org:service:AVTransport:1", + "urn:upnp-org:serviceId:AVT_1-0", + "urn:schemas-upnp-org:metadata-1-0/AVT/"); + NPT_CHECK_FATAL(m_pAVService->SetSCPDXML((const char*) RDR_AVTransportSCPD)); + NPT_CHECK_FATAL(m_pAVService->InitURLs("AVTransport", data.GetUUID())); + NPT_CHECK_FATAL(data.AddService(m_pAVService)); + + m_pAVService->SetStateVariableRate("LastChange", NPT_TimeInterval(0.2f)); + m_pAVService->SetStateVariable("A_ARG_TYPE_InstanceID", "0"); + + // GetCurrentTransportActions + m_pAVService->SetStateVariable("CurrentTransportActions", "Play,Pause,Stop,Seek,Next,Previous"); + + // GetDeviceCapabilities + m_pAVService->SetStateVariable("PossiblePlaybackStorageMedia", "NONE,NETWORK"); + m_pAVService->SetStateVariable("PossibleRecordStorageMedia", "NOT_IMPLEMENTED"); + m_pAVService->SetStateVariable("PossibleRecordQualityModes", "NOT_IMPLEMENTED"); + + // GetMediaInfo + m_pAVService->SetStateVariable("NumberOfTracks", "0"); + m_pAVService->SetStateVariable("CurrentMediaDuration", "00:00:00");; + m_pAVService->SetStateVariable("AVTransportURI", ""); + m_pAVService->SetStateVariable("AVTransportURIMetadata", "");; + m_pAVService->SetStateVariable("NextAVTransportURI", "NOT_IMPLEMENTED"); + m_pAVService->SetStateVariable("NextAVTransportURIMetadata", "NOT_IMPLEMENTED"); + m_pAVService->SetStateVariable("PlaybackStorageMedium", "NONE"); + m_pAVService->SetStateVariable("RecordStorageMedium", "NOT_IMPLEMENTED"); + m_pAVService->SetStateVariable("RecordMediumWriteStatus", "NOT_IMPLEMENTED"); + + // GetPositionInfo + m_pAVService->SetStateVariable("CurrentTrack", "0"); + m_pAVService->SetStateVariable("CurrentTrackDuration", "00:00:00"); + m_pAVService->SetStateVariable("CurrentTrackMetadata", ""); + m_pAVService->SetStateVariable("CurrentTrackURI", ""); + m_pAVService->SetStateVariable("RelativeTimePosition", "00:00:00"); + m_pAVService->SetStateVariable("AbsoluteTimePosition", "00:00:00"); + m_pAVService->SetStateVariable("RelativeCounterPosition", "2147483647"); // means NOT_IMPLEMENTED + m_pAVService->SetStateVariable("AbsoluteCounterPosition", "2147483647"); // means NOT_IMPLEMENTED + + // disable indirect eventing for certain state variables + PLT_StateVariable* var; + var = m_pAVService->FindStateVariable("RelativeTimePosition"); + //if (var) var->DisableIndirectEventing(); + var = m_pAVService->FindStateVariable("AbsoluteTimePosition"); + //if (var) var->DisableIndirectEventing(); + var = m_pAVService->FindStateVariable("RelativeCounterPosition"); + //if (var) var->DisableIndirectEventing(); + var = m_pAVService->FindStateVariable("AbsoluteCounterPosition"); + //if (var) var->DisableIndirectEventing(); + + // GetTransportInfo + m_pAVService->SetStateVariable("TransportState", "NO_MEDIA_PRESENT"); + m_pAVService->SetStateVariable("TransportStatus", "OK"); + m_pAVService->SetStateVariable("TransportPlaySpeed", "1"); + + // GetTransportSettings + m_pAVService->SetStateVariable("CurrentPlayMode", "NORMAL"); + m_pAVService->SetStateVariable("CurrentRecordQualityMode", "NOT_IMPLEMENTED"); + } + + { + /* ConnectionManager */ + service = new PLT_Service( + &data, + "urn:schemas-upnp-org:service:ConnectionManager:1", + "urn:upnp-org:serviceId:CMGR_1-0"); + NPT_CHECK_FATAL(service->SetSCPDXML((const char*) RDR_ConnectionManagerSCPD)); + NPT_CHECK_FATAL(service->InitURLs("ConnectionManager", data.GetUUID())); + NPT_CHECK_FATAL(data.AddService(service)); + + service->SetStateVariable("CurrentConnectionIDs", "0"); + + // put all supported mime types here instead + service->SetStateVariable("SinkProtocolInfo", "http-get:*:*:*, rtsp-rtp-udp:*:*:*"); + service->SetStateVariable("SourceProtocolInfo", ""); + } + + { + /* RenderingControl */ + service = new PLT_Service( + &data, + "urn:schemas-upnp-org:service:RenderingControl:1", + "urn:upnp-org:serviceId:RCS_1-0", + "urn:schemas-upnp-org:metadata-1-0/RCS/"); + NPT_CHECK_FATAL(service->SetSCPDXML((const char*) RDR_RenderingControlSCPD)); + NPT_CHECK_FATAL(service->InitURLs("RenderingControl", data.GetUUID())); + NPT_CHECK_FATAL(data.AddService(service)); + + service->SetStateVariableRate("LastChange", NPT_TimeInterval(0.2f)); + + service->SetStateVariable("Mute", "0"); + service->SetStateVariable("Volume", "100"); + } + + { +static NPT_UInt8 MIGRATION_SCPDXML[] = "<scpd xmlns=\"urn:schemas-upnp-org:service-1-0\">\ + <serviceStateTable>\ + <stateVariable>\ + <name>MigrationStatus</name>\ + <sendEventsAttribute>no</sendEventsAttribute>\ + <dataType>string</dataType>\ + <allowedValueList>\ + <allowedValue>OK</allowedValue>\ + <allowedValue>ERROR_OCCURRED</allowedValue>\ + </allowedValueList>\ + </stateVariable>\ + <stateVariable>\ + <name>MigrationMetaData</name>\ + <sendEventsAttribute>no</sendEventsAttribute>\ + <dataType>string</dataType>\ + </stateVariable>\ + <stateVariable>\ + <name>A_ARG_TYPE_InstanceID</name>\ + <sendEventsAttribute>no</sendEventsAttribute>\ + <dataType>ui4</dataType>\ + </stateVariable>\ + </serviceStateTable>\ + <actionList>\ + <action>\ + <name>StopForMigration</name>\ + <argumentList>\ + <argument>\ + <name>InstanceID</name>\ + <direction>in</direction>\ + <relatedStateVariable>A_ARG_TYPE_InstanceID</relatedStateVariable>\ + </argument>\ + <argument>\ + <name>MigrationStatus</name>\ + <direction>out</direction>\ + <relatedStateVariable>MigrationStatus</relatedStateVariable>\ + </argument>\ + <argument>\ + <name>MigrationMetaData</name>\ + <direction>out</direction>\ + <relatedStateVariable>MigrationMetaData</relatedStateVariable>\ + </argument>\ + </argumentList>\ + </action>\ + </actionList>\ +</scpd>"; + + /* MigrationService */ + m_pMigrationService = new PLT_Service(&data, "urn:intermedia:service:migration:1", "urn:intermedia:service:migration.001"); + + NPT_CHECK_FATAL(m_pMigrationService->SetSCPDXML((const char*) MIGRATION_SCPDXML)); + NPT_CHECK_FATAL(m_pMigrationService->InitURLs("SessionMigration", data.GetUUID())); + NPT_CHECK_FATAL(data.AddService(m_pMigrationService)); + + m_pMigrationService->SetStateVariable("MigrationStatus", "OK"); + m_pMigrationService->SetStateVariable("MigrationMetaData", ""); + } + + return NPT_SUCCESS; +} + +NPT_Result +GPAC_MediaRenderer::OnAction(PLT_ActionReference& action, + const PLT_HttpRequestContext& context) +{ + NPT_COMPILER_UNUSED(context); + + /* parse the action name */ + NPT_String name = action->GetActionDesc().GetName(); + + m_ip_src = context.GetRemoteAddress().GetIpAddress().ToString(); + + /* Is it a ConnectionManager Service Action ? */ + if (name.Compare("GetCurrentConnectionIDs", true) == 0) { + if (NPT_FAILED(action->SetArgumentsOutFromStateVariable())) { + return NPT_FAILURE; + } + return NPT_SUCCESS; + } + if (name.Compare("GetProtocolInfo", true) == 0) { + if (NPT_FAILED(action->SetArgumentsOutFromStateVariable())) { + return NPT_FAILURE; + } + return NPT_SUCCESS; + } + if (name.Compare("GetCurrentConnectionInfo", true) == 0) { + return OnGetCurrentConnectionInfo(action); + } + if (name.Compare("StopForMigration", true) == 0) { + NPT_String res = m_pUPnP->OnMigrate(); + m_pMigrationService->SetStateVariable("MigrationStatus", "OK"); + m_pMigrationService->SetStateVariable("MigrationMetaData", res); + + if (NPT_FAILED(action->SetArgumentsOutFromStateVariable())) { + return NPT_FAILURE; + } + return NPT_SUCCESS; + } + + /* Is it a AVTransport Service Action ? */ + + // since all actions take an instance ID and we only support 1 instance + // verify that the Instance ID is 0 and return an error here now if not + NPT_String serviceType = action->GetActionDesc().GetService()->GetServiceType(); + if (serviceType.Compare("urn:schemas-upnp-org:service:AVTransport:1", true) == 0) { + if (NPT_FAILED(action->VerifyArgumentValue("InstanceID", "0"))) { + action->SetError(802,"Not valid InstanceID."); + return NPT_FAILURE; + } + } + + if (name.Compare("GetCurrentTransportActions", true) == 0) { + if (NPT_FAILED(action->SetArgumentsOutFromStateVariable())) { + return NPT_FAILURE; + } + return NPT_SUCCESS; + } + if (name.Compare("GetDeviceCapabilities", true) == 0) { + if (NPT_FAILED(action->SetArgumentsOutFromStateVariable())) { + return NPT_FAILURE; + } + return NPT_SUCCESS; + } + if (name.Compare("GetMediaInfo", true) == 0) { + if (NPT_FAILED(action->SetArgumentsOutFromStateVariable())) { + return NPT_FAILURE; + } + return NPT_SUCCESS; + } + if (name.Compare("GetPositionInfo", true) == 0) { + if (m_pUPnP->m_pTerm->root_scene) { + char szVal[100]; + + m_pAVService->SetStateVariable("CurrentTrack", "0"); + format_time_string(szVal, m_Duration); + m_pAVService->SetStateVariable("CurrentTrackDuration", szVal); + + m_pAVService->SetStateVariable("CurrentTrackMetadata", ""); + m_pAVService->SetStateVariable("CurrentTrackURI", ""); + format_time_string(szVal, m_Time); + m_pAVService->SetStateVariable("RelativeTimePosition", szVal); + m_pAVService->SetStateVariable("AbsoluteTimePosition", szVal); + m_pAVService->SetStateVariable("RelativeCounterPosition", "2147483647"); // means NOT_IMPLEMENTED + m_pAVService->SetStateVariable("AbsoluteCounterPosition", "2147483647"); // means NOT_IMPLEMENTED + } else { + if (NPT_FAILED(action->SetArgumentsOutFromStateVariable())) { + return NPT_FAILURE; + } + } + return NPT_SUCCESS; + } + if (name.Compare("GetTransportInfo", true) == 0) { + if (NPT_FAILED(action->SetArgumentsOutFromStateVariable())) { + return NPT_FAILURE; + } + return NPT_SUCCESS; + } + if (name.Compare("GetTransportSettings", true) == 0) { + if (NPT_FAILED(action->SetArgumentsOutFromStateVariable())) { + return NPT_FAILURE; + } + return NPT_SUCCESS; + } + if (name.Compare("Next", true) == 0) { + return OnNext(action); + } + if (name.Compare("Pause", true) == 0) { + return OnPause(action); + } + if (name.Compare("Play", true) == 0) { + return OnPlay(action); + } + if (name.Compare("Previous", true) == 0) { + return OnPrevious(action); + } + if (name.Compare("Seek", true) == 0) { + return OnSeek(action); + } + if (name.Compare("Stop", true) == 0) { + return OnStop(action); + } + if (name.Compare("SetAVTransportURI", true) == 0) { + return OnSetAVTransportURI(action); + } + if (name.Compare("SetPlayMode", true) == 0) { + return OnSetPlayMode(action); + } + + /* Is it a RendererControl Service Action ? */ + if (serviceType.Compare("urn:schemas-upnp-org:service:RenderingControl:1", true) == 0) { + /* we only support master channel */ + if (NPT_FAILED(action->VerifyArgumentValue("Channel", "Master"))) { + action->SetError(402,"Invalid Args."); + return NPT_FAILURE; + } + } + + if (name.Compare("GetVolume", true) == 0) { + NPT_CHECK_SEVERE(action->SetArgumentsOutFromStateVariable()); + return NPT_SUCCESS; + } + + if (name.Compare("GetMute", true) == 0) { + NPT_CHECK_SEVERE(action->SetArgumentsOutFromStateVariable()); + return NPT_SUCCESS; + } + + if (name.Compare("SetVolume", true) == 0) { + return OnSetVolume(action); + } + + if (name.Compare("SetMute", true) == 0) { + return OnSetMute(action); + } + + action->SetError(401,"No Such Action."); + return NPT_FAILURE; +} + +NPT_Result +GPAC_MediaRenderer::OnGetCurrentConnectionInfo(PLT_ActionReference& action) +{ + if (NPT_FAILED(action->VerifyArgumentValue("ConnectionID", "0"))) { + action->SetError(706,"No Such Connection."); + return NPT_FAILURE; + } + + if (NPT_FAILED(action->SetArgumentValue("RcsID", "0"))){ + return NPT_FAILURE; + } + if (NPT_FAILED(action->SetArgumentValue("AVTransportID", "0"))) { + return NPT_FAILURE; + } + if (NPT_FAILED(action->SetArgumentValue("ProtocolInfo", "http-get:*:*:*"))) { + return NPT_FAILURE; + } + if (NPT_FAILED(action->SetArgumentValue("PeerConnectionManager", "/"))) { + return NPT_FAILURE; + } + if (NPT_FAILED(action->SetArgumentValue("PeerConnectionID", "-1"))) { + return NPT_FAILURE; + } + if (NPT_FAILED(action->SetArgumentValue("Direction", "Input"))) { + return NPT_FAILURE; + } + if (NPT_FAILED(action->SetArgumentValue("Status", "Unknown"))) { + return NPT_FAILURE; + } + + return NPT_SUCCESS; +} + +NPT_Result GPAC_MediaRenderer::OnSetAVTransportURI(PLT_ActionReference& action) +{ + char the_url[4096], szVal[100]; + NPT_String url_id; + const char *MediaUri; + if (NPT_FAILED(action->GetArgumentValue("CurrentURI", url_id))) { + return NPT_FAILURE; + } + MediaUri = url_id; + if (!MediaUri) return NPT_FAILURE; + + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Request: change media\n")); + + if (m_connected) { + m_connected = 0; + m_pUPnP->OnStop(m_ip_src); + } + const char *ext = strrchr(MediaUri, '.'); + if (ext && !stricmp(ext, ".m3u")) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] M3U playlists not supported yet\n")); + return NPT_SUCCESS; + } + + /* Load and add to mediaHistoryList */ + strcpy(the_url, MediaUri); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Adding media to the list : %s\n", MediaUri)); + gf_list_add(m_mediaHistoryList, gf_strdup(MediaUri)); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Opening URL %s\n", the_url)); + m_track_pos = gf_list_count(m_mediaHistoryList); + + m_connected = 1; + m_pUPnP->OnConnect(the_url, m_ip_src); + /* Set UPnP datas */ + m_pAVService->SetStateVariable("TransportState", "PLAYING"); + m_pAVService->SetStateVariable("AVTransportURI", the_url); + + sprintf(szVal, "%d", gf_list_count(m_mediaHistoryList)); + m_pAVService->SetStateVariable("NumberOfTracks", szVal); + sprintf(szVal, "%d", m_track_pos); + m_pAVService->SetStateVariable("CurrentTrack", szVal); + return NPT_SUCCESS; +} + +NPT_Result GPAC_MediaRenderer::OnPause(PLT_ActionReference& action) +{ + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Request: change state : PAUSE\n")); + m_pAVService->SetStateVariable("TransportState", "PAUSED_PLAYBACK"); + m_pUPnP->OnPause(0, m_ip_src); + return NPT_SUCCESS; +} + +NPT_Result GPAC_MediaRenderer::OnPlay(PLT_ActionReference& action) +{ + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Request: change state : PLAY\n")); + + /* if nothing playing, connect to first media of mediaHistoryList */ + if (m_connected) { + m_pAVService->SetStateVariable("TransportState", "PLAYING"); + m_pUPnP->OnPause(1, m_ip_src); + } else if (gf_list_count(m_mediaHistoryList) >= 1) { + char *track = (char *) gf_list_get(m_mediaHistoryList, 0); + m_track_pos = 1; + + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Reading first media : %s\n", track)); + m_pAVService->SetStateVariable("TransportState", "PLAYING"); + m_connected = 1; + m_pUPnP->OnConnect(track, m_ip_src); + //MRSetTrack(track, upnph->TrackPosition); + } + return NPT_SUCCESS; +} + + +NPT_Result GPAC_MediaRenderer::OnStop(PLT_ActionReference& action) +{ + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Request: change state : STOP\n")); + if (m_pUPnP->m_pTerm->root_scene) { + m_pAVService->SetStateVariable("TransportState", "STOPPED"); + m_pUPnP->OnStop(m_ip_src); + } + return NPT_SUCCESS; +} + +NPT_Result GPAC_MediaRenderer::OnPrevious(PLT_ActionReference& action) +{ + return NPT_SUCCESS; +} + +NPT_Result GPAC_MediaRenderer::OnNext(PLT_ActionReference& action) +{ + return NPT_SUCCESS; +} + +NPT_Result GPAC_MediaRenderer::OnSeek(PLT_ActionReference& action) +{ + u32 h, m, s; + Double time; + NPT_String unit, target; + if (NPT_FAILED(action->GetArgumentValue("Unit", unit))) { + return NPT_FAILURE; + } + if (NPT_FAILED(action->GetArgumentValue("Target", target))) { + return NPT_FAILURE; + } + if ((unit!="ABS_TIME") && (unit!="REL_TIME")) { + action->SetError(710,"Seek mode not supported"); + return NPT_FAILURE; + } + sscanf(target, "%d:%d:%d", &h, &m, &s); + time = h*3600.0 + m*60.0 + s; + m_pUPnP->OnSeek(time); + return NPT_SUCCESS; +} + + +NPT_Result GPAC_MediaRenderer::OnSetPlayMode(PLT_ActionReference& action) +{ + return NPT_SUCCESS; +} + + +NPT_Result GPAC_MediaRenderer::OnSetVolume(PLT_ActionReference& action) +{ + return NPT_SUCCESS; +} + +NPT_Result GPAC_MediaRenderer::OnSetMute(PLT_ActionReference& action) +{ + return NPT_SUCCESS; +} + +void GPAC_MediaRenderer::SetDuration(Double duration, Bool can_seek) +{ + char szVal[100]; + format_time_string(szVal, duration); + m_Duration = duration; + m_pAVService->SetStateVariable("CurrentTrackDuration", szVal); +} + +void GPAC_MediaRenderer::SetTime(Double time) +{ + char szVal[100]; + format_time_string(szVal, time); + m_Time = time; + m_pAVService->SetStateVariable("RelativeTimePosition", szVal); + m_pAVService->SetStateVariable("AbsoluteTimePosition", szVal); +} + +void GPAC_MediaRenderer::SetConnected(const char *url) +{ + m_pAVService->SetStateVariable("AVTransportURI", url); + m_pAVService->SetStateVariable("CurrentTrackURI", url); + m_pAVService->SetStateVariable("TransportState", "PLAYING"); + m_connected = url ? 1 : 0; +} diff --git a/modules/platinum/GPACMediaRenderer.h b/modules/platinum/GPACMediaRenderer.h new file mode 100644 index 0000000..3e8e996 --- /dev/null +++ b/modules/platinum/GPACMediaRenderer.h @@ -0,0 +1,99 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + + + +#ifndef _GPAC_MEDIA_RENDER_H_ +#define _GPAC_MEDIA_RENDER_H_ + +#include "Neptune.h" +#include "PltMediaRenderer.h" +#include "PltService.h" + +class GF_UPnP; + +class GPAC_MediaRenderer : public PLT_DeviceHost, + public PLT_MediaRendererInterface +{ +public: + GPAC_MediaRenderer (GF_UPnP *upnp, const char* friendly_name, + bool show_ip = false, + const char* uuid = NULL, + unsigned int port = 0); + + // PLT_DeviceHost methods + virtual NPT_Result SetupServices(PLT_DeviceData& data); + virtual NPT_Result OnAction(PLT_ActionReference &action, const PLT_HttpRequestContext& context); + + /*these are called when event filtering is used (no JS)*/ + void SetDuration(Double duration, Bool can_seek); + void SetTime(Double time); + void SetConnected(const char *url); + +protected: + virtual ~GPAC_MediaRenderer(); + + // PLT_MediaRendererInterface methods + // ConnectionManager + virtual NPT_Result OnGetCurrentConnectionInfo(PLT_ActionReference& action); + + // AVTransport + virtual NPT_Result OnNext(PLT_ActionReference& action); + virtual NPT_Result OnPause(PLT_ActionReference& action); + virtual NPT_Result OnPlay(PLT_ActionReference& action); + virtual NPT_Result OnPrevious(PLT_ActionReference& action); + virtual NPT_Result OnSeek(PLT_ActionReference& action); + virtual NPT_Result OnStop(PLT_ActionReference& action); + virtual NPT_Result OnSetAVTransportURI(PLT_ActionReference& action); + virtual NPT_Result OnSetPlayMode(PLT_ActionReference& action); + + // RenderingControl + //virtual NPT_Result OnGetVolume(PLT_ActionReference& action); + virtual NPT_Result OnSetVolume(PLT_ActionReference& action); + virtual NPT_Result OnSetMute(PLT_ActionReference& action); + +private: + GF_UPnP *m_pUPnP; + + Bool m_connected; + + /*pointer to the AV service for further StateVariable modifications*/ + PLT_Service *m_pAVService; + PLT_Service *m_pMigrationService; + + GF_List *m_mediaHistoryList; + u32 m_track_pos; + u32 m_volume; + Bool m_muted, m_l_muted, m_r_muted; + NPT_String m_ip_src; + Double m_Duration, m_Time; +}; + +#endif /*_GPAC_MEDIA_RENDER_H_*/ diff --git a/modules/platinum/GPACPlatinum.cpp b/modules/platinum/GPACPlatinum.cpp new file mode 100644 index 0000000..bf362df --- /dev/null +++ b/modules/platinum/GPACPlatinum.cpp @@ -0,0 +1,1547 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + + +#include "GPACPlatinum.h" + +#ifdef GPAC_HAS_SPIDERMONKEY + +#define _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; + +#if !defined(__GNUC__) +# if defined(_WIN32_WCE) +# pragma comment(lib, "js") +# elif defined (WIN32) +# pragma comment(lib, "js32") +# endif +#endif + +#endif + +GF_UPnP::GF_UPnP() +{ + m_pTerm = NULL; + m_pPlatinum = NULL; + m_pMediaRenderer = NULL; + m_pMediaServer = NULL; + m_pAVCtrlPoint = NULL; + m_renderer_bound = 0; + m_pGenericController = NULL; + +#ifdef GPAC_HAS_SPIDERMONKEY + m_Devices = NULL; + m_pJSCtx = NULL; + m_nbJSInstances=0; + last_time = 0; +#endif +} + +GF_UPnP::~GF_UPnP() +{ +#ifdef GPAC_HAS_SPIDERMONKEY + if (m_Devices) gf_list_del(m_Devices); +#endif +} + +void GF_UPnP::LockJavascript(Bool do_lock) +{ + gf_sg_lock_javascript(do_lock); +} + +void GF_UPnP::OnStop(const char *src_url) +{ + if (m_renderer_bound) { +#ifdef GPAC_HAS_SPIDERMONKEY + jsval funval, rval; + if (!m_pJSCtx) return; + LockJavascript(1); + JS_LookupProperty(m_pJSCtx, m_pObj, "onMediaStop", &funval); + if (JSVAL_IS_OBJECT(funval)) { + jsval argv[1]; + argv[0] = GetUPnPDevice(src_url); + JS_CallFunctionValue(m_pJSCtx, m_pObj, funval, 1, argv, &rval); + } + LockJavascript(0); +#endif + } else { +// gf_term_disconnect(m_pTerm); + gf_term_play_from_time(m_pTerm, 0, 1); + } +} + +NPT_String GF_UPnP::OnMigrate() +{ + NPT_String res = ""; + if (m_renderer_bound) { +#ifdef GPAC_HAS_SPIDERMONKEY + jsval funval, rval; + if (!m_pJSCtx) return res; + LockJavascript(1); + JS_LookupProperty(m_pJSCtx, m_pObj, "onMigrate", &funval); + if (JSVAL_IS_OBJECT(funval)) { + JS_CallFunctionValue(m_pJSCtx, m_pObj, funval, 0, NULL, &rval); + if (JSVAL_IS_STRING(rval)) { + res = JS_GetStringBytes(JSVAL_TO_STRING(rval)); + } + } + LockJavascript(0); +#endif + } else { + GF_NetworkCommand com; + + memset(&com, 0, sizeof(GF_NetworkCommand)); + com.base.command_type = GF_NET_SERVICE_MIGRATION_INFO; + m_pTerm->root_scene->root_od->net_service->ifce->ServiceCommand(m_pTerm->root_scene->root_od->net_service->ifce, &com); + if (com.migrate.data) { + res = com.migrate.data; + } else { + res = m_pTerm->root_scene->root_od->net_service->url; + } + } + return res; +} + +#ifdef GPAC_HAS_SPIDERMONKEY +jsval GF_UPnP::GetUPnPDevice(const char *src_url) +{ + return src_url ? STRING_TO_JSVAL( JS_NewStringCopyZ(m_pJSCtx, src_url ) ) : JSVAL_NULL; +} +#endif + +void GF_UPnP::OnConnect(const char *url, const char *src_url) +{ + if (m_renderer_bound) { +#ifdef GPAC_HAS_SPIDERMONKEY + jsval funval, rval; + if (!m_pJSCtx) return; + + LockJavascript(1); + JS_LookupProperty(m_pJSCtx, m_pObj, "onMediaConnect", &funval); + if (JSVAL_IS_OBJECT(funval)) { + jsval argv[2]; + argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(m_pJSCtx, url ) ); + argv[1] = GetUPnPDevice(src_url); + JS_CallFunctionValue(m_pJSCtx, m_pObj, funval, 2, argv, &rval); + } + LockJavascript(0); +#endif + } else { + gf_term_navigate_to(m_pTerm, url); + } +} +void GF_UPnP::OnPause(Bool do_resume, const char *src_url) +{ + if (m_renderer_bound) { +#ifdef GPAC_HAS_SPIDERMONKEY + jsval funval, rval; + if (!m_pJSCtx) return; + LockJavascript(1); + JS_LookupProperty(m_pJSCtx, m_pObj, do_resume ? "onMediaPlay" : "onMediaPause", &funval); + if (JSVAL_IS_OBJECT(funval)) { + jsval argv[1]; + argv[0] = GetUPnPDevice(src_url); + JS_CallFunctionValue(m_pJSCtx, m_pObj, funval, 1, argv, &rval); + } + LockJavascript(0); +#endif + } else { + gf_term_set_option(m_pTerm, GF_OPT_PLAY_STATE, do_resume ? GF_STATE_PLAYING : GF_STATE_PAUSED); + } +} + +void GF_UPnP::OnSeek(Double time) +{ + if (m_renderer_bound) { +#ifdef GPAC_HAS_SPIDERMONKEY + jsval funval, rval; + if (!m_pJSCtx) return; + LockJavascript(1); + JS_LookupProperty(m_pJSCtx, m_pObj, "onMediaSeek", &funval); + if (JSVAL_IS_OBJECT(funval)) { + jsval argv[1]; + argv[0] = DOUBLE_TO_JSVAL( JS_NewDouble(m_pJSCtx, time) ); + JS_CallFunctionValue(m_pJSCtx, m_pObj, funval, 2, argv, &rval); + } + LockJavascript(0); +#endif + } else { + /* CanSeek and Duration set for each media by event_proc */ + if (!m_pTerm->root_scene || (m_pTerm->root_scene->root_od->flags & GF_ODM_NO_TIME_CTRL) + || (m_pTerm->root_scene->duration<2000) + ) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] Scene not seekable\n")); + } else { + gf_term_play_from_time(m_pTerm, (u64) (time * 1000), 0); + } + } +} + +void GF_UPnP::ContainerChanged(PLT_DeviceDataReference& device, const char *item_id, const char *update_id) +{ +} + +Bool GF_UPnP::ProcessEvent(GF_Event *evt) +{ + if (!m_pMediaRenderer) return 0; + switch (evt->type) { + case GF_EVENT_CONNECT: + if (evt->connect.is_connected) { + const char *url = gf_term_get_url(m_pTerm); + if (url) { + m_pMediaRenderer->SetConnected(url); + } + } + break; + + case GF_EVENT_DURATION: + m_pMediaRenderer->SetDuration(evt->duration.duration, evt->duration.can_seek); + case GF_EVENT_METADATA: + if (m_pTerm->root_scene) { + char szName[1024]; + const char *artist; + NetInfoCommand com; + memset(&com, 0, sizeof(NetInfoCommand)); + + /*get any service info*/ + if (gf_term_get_service_info(m_pTerm, m_pTerm->root_scene->root_od, &com) == GF_OK) { + strcpy(szName, ""); + if (com.name) { strcat(szName, com.name); strcat(szName, " "); } + if (com.album) { strcat(szName, "("); strcat(szName, com.album); strcat(szName, ")"); } + + artist = "Unknown"; + if (com.artist) artist = com.artist; + else if (com.writer) artist = com.writer; + else if (com.composer) artist = com.composer; + + //MRSetMediaInfo(0, szName, com.artist ? com.artist : "Unknown"); + } + } + break; + } + return 0; +} + + +void GF_UPnP::Load(GF_Terminal *term) +{ + u16 port = 0; + Bool save_uuids=0; + Bool ignore_local_devices=0; + const char *uuid, *opt, *name; + char hostname[100], friendly_name[1024]; + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Starting UPnP\n")); + + m_pCtrlPoint = NULL; + m_pTerm = term; + + m_pPlatinum = new PLT_UPnP(); + m_pPlatinum->SetIgnoreLocalUUIDs(false); + + gf_sk_get_host_name((char*)hostname); + + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "AllowedDevicesIP"); + if (!opt) { + gf_cfg_set_key(m_pTerm->user->config, "UPnP", "AllowedDevicesIP", ""); + opt=""; + } + m_IPFilter = opt; + + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "IgnoreCreatedDevices"); + if (!opt || !strcmp(opt, "yes")) { + ignore_local_devices = 1; + if (!opt) gf_cfg_set_key(m_pTerm->user->config, "UPnP", "IgnoreCreatedDevices", "yes"); + } + + + + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "IgnoreCreatedDevices"); + if (!opt || !strcmp(opt, "yes")) { + ignore_local_devices = 1; + if (!opt) gf_cfg_set_key(m_pTerm->user->config, "UPnP", "IgnoreCreatedDevices", "yes"); + } + + + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "SaveUUIDs"); + if (opt && !strcmp(opt, "yes")) save_uuids = 1; + + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "MediaRendererEnabled"); + if (!opt || !strcmp(opt, "yes")) { + if (!opt) gf_cfg_set_key(m_pTerm->user->config, "UPnP", "MediaRendererEnabled", "yes"); + + name = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "MediaRendererName"); + if (!name) { + sprintf(friendly_name, "GPAC @ %s", hostname); + name = friendly_name; + } + + port = 0; + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "MediaRendererPort"); + if (opt) port = atoi(opt); + + uuid = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "MediaRendererUUID"); + if (uuid) { + m_pMediaRenderer = new GPAC_MediaRenderer(this, name, false, uuid, port); + } else { + m_pMediaRenderer = new GPAC_MediaRenderer(this, name, false, NULL, port); + if (save_uuids) { + uuid = m_pMediaRenderer->GetUUID(); + gf_cfg_set_key(m_pTerm->user->config, "UPnP", "MediaRendererUUID", uuid); + } + } + + PLT_DeviceHostReference device(m_pMediaRenderer ); + device->m_ModelDescription = "GPAC Media Renderer"; + device->m_ModelURL = "http://gpac.sourceforge.net"; + device->m_ModelNumber = GPAC_FULL_VERSION; + device->m_ModelName = "GPAC Media Renderer"; + device->m_Manufacturer = "Telecom ParisTech"; + device->m_ManufacturerURL = "http://www.telecom-paristech.fr/"; + m_pPlatinum->AddDevice(device); + } + + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "MediaServerEnabled"); + if (!opt || !strcmp(opt, "yes")) { + char *media_root; + if (!opt) gf_cfg_set_key(m_pTerm->user->config, "UPnP", "MediaServerEnabled", "yes"); + + name = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "MediaServerName"); + if (!name) { + sprintf(friendly_name, "GPAC @ %s", hostname); + name = friendly_name; + } + + port = 0; + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "MediaServerPort"); + if (opt) port = atoi(opt); + + uuid = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "MediaServerUUID"); + if (uuid) { + m_pMediaServer = new GPAC_FileMediaServer(name, false, uuid, port); + } else { + m_pMediaServer = new GPAC_FileMediaServer(name, false, NULL, port); + if (save_uuids) { + uuid = m_pMediaServer->GetUUID(); + gf_cfg_set_key(m_pTerm->user->config, "UPnP", "MediaServerUUID", uuid); + } + } + media_root = (char *) gf_cfg_get_key(m_pTerm->user->config, "UPnP", "MediaServerRoot"); + if (!media_root) { + gf_cfg_set_key(m_pTerm->user->config, "UPnP", "MediaServerRoot", "all:/"); + m_pMediaServer->AddSharedDirectory("/", "all"); + } else { + while (media_root) { + Bool is_hidden = 0; + char *sep1 = (char *)strchr(media_root, ':'); + if (!sep1) break; + char *sep2 = (char *)strchr(sep1, ';'); + + if (!strncmp(media_root, "(h)", 3)) { + media_root+=3; + is_hidden = 1; + } + sep1[0] = 0; + if (sep2) sep2[0] = 0; + m_pMediaServer->AddSharedDirectory(sep1+1, media_root, is_hidden); + sep1[0] = ':'; + if (sep2) sep2[0] = ';'; + else break; + media_root = sep2+1; + } + } + PLT_DeviceHostReference device(m_pMediaServer); + device->m_ModelDescription = "GPAC Media Server"; + device->m_ModelURL = "http://gpac.sourceforge.net"; + device->m_ModelNumber = GPAC_FULL_VERSION; + device->m_ModelName = "GPAC Media Server"; + device->m_Manufacturer = "Telecom ParisTech"; + device->m_ManufacturerURL = "http://www.telecom-paristech.fr/"; + m_pPlatinum->AddDevice(device); + } + + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "GenericControllerEnabled"); + if (!opt || !strcmp(opt, "yes")) { + if (!opt) gf_cfg_set_key(m_pTerm->user->config, "UPnP", "GenericControllerEnabled", "yes"); + /*create our generic control point*/ + if (!m_pCtrlPoint) { + m_pCtrlPoint = new PLT_CtrlPoint(); + m_ctrlPtRef = PLT_CtrlPointReference(m_pCtrlPoint); + } + m_pGenericController = new GPAC_GenericController(m_ctrlPtRef, this); + } + + opt = gf_cfg_get_key(m_pTerm->user->config, "UPnP", "AVCPEnabled"); + if (!opt || !strcmp(opt, "yes")) { + if (!opt) gf_cfg_set_key(m_pTerm->user->config, "UPnP", "AVCPEnabled", "yes"); + + if (!m_pCtrlPoint) { + m_pCtrlPoint = new PLT_CtrlPoint(); + m_ctrlPtRef = PLT_CtrlPointReference(m_pCtrlPoint); + } + m_pAVCtrlPoint = new GPAC_MediaController(m_ctrlPtRef, this); + } + + // add control point to upnp engine + if (m_pCtrlPoint) { + if (ignore_local_devices) { + if (m_pMediaServer) m_pCtrlPoint->IgnoreUUID(m_pMediaServer->GetUUID()); + if (m_pMediaRenderer) m_pCtrlPoint->IgnoreUUID(m_pMediaRenderer->GetUUID()); + } + m_pPlatinum->AddCtrlPoint(m_ctrlPtRef); + } + + //start UPnP engine + m_pPlatinum->Start(); + + /*if we have a control point, force a rescan of the network servcies*/ + if (m_pCtrlPoint) { + m_pCtrlPoint->Search(); + } +} + +void GF_UPnP::Unload() +{ + m_pPlatinum->Stop(); + if (m_pGenericController) delete m_pGenericController; + if (m_pAVCtrlPoint) delete m_pAVCtrlPoint; + /*this will delete all UPnP devices*/ + delete m_pPlatinum; +} + + +#ifdef GPAC_HAS_SPIDERMONKEY + +void GF_UPnP::OnMediaRendererAdd(PLT_DeviceDataReference& device, int added) +{ + jsval funval, rval; + if (!m_pJSCtx) return; + + if (m_IPFilter.GetLength() && (strstr((const char*)m_IPFilter, (const char*)device->GetURLBase().GetHost()) == NULL) ) return; + + LockJavascript(1); + + JS_LookupProperty(m_pJSCtx, m_pObj, "onMediaRendererAdd", &funval); + if (JSVAL_IS_OBJECT(funval)) { + jsval argv[3]; + argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(m_pJSCtx, device->GetFriendlyName() ) ); + argv[1] = STRING_TO_JSVAL( JS_NewStringCopyZ(m_pJSCtx, device->GetUUID() ) ); + argv[2] = BOOLEAN_TO_JSVAL( added ? JS_TRUE : JS_FALSE); + + JS_CallFunctionValue(m_pJSCtx, m_pObj, funval, 3, argv, &rval); + } + LockJavascript(0); +} + + +void GF_UPnP::OnMediaServerAdd(PLT_DeviceDataReference& device, int added) +{ + jsval funval, rval; + if (!m_pJSCtx) return; + + if (m_IPFilter.GetLength() && (strstr((const char*)m_IPFilter, (const char*)device->GetURLBase().GetHost()) == NULL) ) return; + + LockJavascript(1); + JS_LookupProperty(m_pJSCtx, m_pObj, "onMediaServerAdd", &funval); + if (JSVAL_IS_OBJECT(funval)) { + jsval argv[3]; + argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(m_pJSCtx, device->GetFriendlyName() ) ); + argv[1] = STRING_TO_JSVAL( JS_NewStringCopyZ(m_pJSCtx, device->GetUUID() ) ); + argv[2] = BOOLEAN_TO_JSVAL( added ? JS_TRUE : JS_FALSE); + + JS_CallFunctionValue(m_pJSCtx, m_pObj, funval, 3, argv, &rval); + } + LockJavascript(0); +} + +static JSBool upnpdevice_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + char *prop_name; + GPAC_DeviceItem *dev = (GPAC_DeviceItem *)JS_GetPrivate(c, obj); + if (!dev) return JS_FALSE; + + if (!JSVAL_IS_STRING(id)) return JS_TRUE; + prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + if (!prop_name) return JS_FALSE; + + if (!strcmp(prop_name, "Name")) { + *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, dev->m_device->GetFriendlyName()) ); + return JS_TRUE; + } + if (!strcmp(prop_name, "UUID")) { + *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, dev->m_device->GetUUID()) ); + return JS_TRUE; + } + if (!strcmp(prop_name, "PresentationURL")) { + *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, dev->m_device->m_PresentationURL) ); + return JS_TRUE; + } + + return JS_TRUE; +} + +static JSBool upnp_device_subscribe(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + PLT_Service* service; + char *service_uuid = ""; + GPAC_DeviceItem *item = (GPAC_DeviceItem *)JS_GetPrivate(c, obj); + if (!item || (argc!=2) ) return JS_FALSE; + + if (!JSVAL_IS_STRING(argv[0])) return JS_FALSE; + if (!JSVAL_IS_OBJECT(argv[1])) return JS_FALSE; + + service_uuid = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (item->m_device->FindServiceByType(service_uuid, service) == NPT_SUCCESS) { + item->m_pUPnP->m_pGenericController->m_CtrlPoint->Subscribe(service); + } + return JS_TRUE; +} +static JSBool upnp_device_find_service(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *service_uuid = ""; + GPAC_DeviceItem *item = (GPAC_DeviceItem *)JS_GetPrivate(c, obj); + if (!item || !argc) return JS_FALSE; + service_uuid = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + + GPAC_ServiceItem *serv = item->FindService(service_uuid); + if (!serv) { + *rval = JSVAL_NULL; + return JS_TRUE; + } + *rval = OBJECT_TO_JSVAL(serv->obj); + return JS_TRUE; +} + + +void GF_UPnP::OnDeviceAdd(GPAC_DeviceItem *item, int added) +{ + jsval funval, rval; + if (!m_pJSCtx) return; + + if (m_IPFilter.GetLength() && (strstr((const char*)m_IPFilter, (const char*)item->m_device->GetURLBase().GetHost()) == NULL) ) return; + + LockJavascript(1); + + if (added) { + item->js_ctx = m_pJSCtx; + item->obj = JS_NewObject(m_pJSCtx, &upnpGenericDeviceClass, 0, 0); + item->m_pUPnP = this; + gf_js_add_root(m_pJSCtx, &item->obj); + JS_SetPrivate(item->js_ctx, item->obj, item); + } + + JS_LookupProperty(m_pJSCtx, m_pObj, "onDeviceAdd", &funval); + if (JSVAL_IS_OBJECT(funval)) { + jsval argv[2]; + argv[0] = OBJECT_TO_JSVAL( item->obj ); + argv[1] = BOOLEAN_TO_JSVAL( added ? JS_TRUE : JS_FALSE); + JS_CallFunctionValue(m_pJSCtx, m_pObj, funval, 3, argv, &rval); + } + LockJavascript(0); +} + +static JSBool upnp_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + char *prop_name; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp) return JS_FALSE; + + if (!JSVAL_IS_STRING(id)) return JS_TRUE; + prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + if (!prop_name) return JS_FALSE; + + if (!strcmp(prop_name, "MediaRendererEnabled")) { + *vp = BOOLEAN_TO_JSVAL( upnp->m_pMediaRenderer ? JS_TRUE : JS_FALSE ); + return JS_TRUE; + } + if (!strcmp(prop_name, "MediaServerEnabled")) { + *vp = BOOLEAN_TO_JSVAL( upnp->m_pMediaServer ? JS_TRUE : JS_FALSE); + return JS_TRUE; + } + if (!strcmp(prop_name, "MediaControlEnabled")) { + *vp = BOOLEAN_TO_JSVAL( upnp->m_pAVCtrlPoint ? JS_TRUE : JS_FALSE); + return JS_TRUE; + } + if (!strcmp(prop_name, "MediaServersCount")) { + *vp = INT_TO_JSVAL( upnp->m_pAVCtrlPoint ? gf_list_count(upnp->m_pAVCtrlPoint->m_MediaServers) : 0); + return JS_TRUE; + } + if (!strcmp(prop_name, "MediaRenderersCount")) { + *vp = INT_TO_JSVAL( upnp->m_pAVCtrlPoint ? gf_list_count(upnp->m_pAVCtrlPoint->m_MediaRenderers) : 0); + return JS_TRUE; + } + if (!strcmp(prop_name, "DevicesCount")) { + *vp = INT_TO_JSVAL( upnp->m_pGenericController ? gf_list_count(upnp->m_pGenericController->m_Devices) : 0); + return JS_TRUE; + } + return JS_TRUE; +} + +static JSBool upnp_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + char *prop_name; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp) return JS_FALSE; + + if (!JSVAL_IS_STRING(id)) return JS_TRUE; + prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + if (!prop_name) return JS_FALSE; + + if (upnp->m_pMediaRenderer ) { + if (!strcmp(prop_name, "MovieDuration") && JSVAL_IS_DOUBLE(*vp)) { + jsdouble d; + JS_ValueToNumber(c, *vp, &d); + upnp->m_pMediaRenderer->SetDuration(d, 1); + return JS_TRUE; + } + if (!strcmp(prop_name, "MovieTime") && JSVAL_IS_DOUBLE(*vp)) { + jsdouble d; + JS_ValueToNumber(c, *vp, &d); + upnp->m_pMediaRenderer->SetTime(d); + return JS_TRUE; + } + if (!strcmp(prop_name, "MovieURL") && JSVAL_IS_STRING(*vp) ) { + const char *url = JS_GetStringBytes(JSVAL_TO_STRING(*vp)); + if (url) upnp->m_pMediaRenderer->SetConnected(url); + return JS_TRUE; + } + } + return JS_TRUE; +} + + +static JSBool upnp_get_device(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 idx; + GPAC_DeviceItem *device; + + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || !argc || !JSVAL_IS_INT(argv[0]) ) return JS_FALSE; + + idx = JSVAL_TO_INT(argv[0]); + if (!upnp->m_pGenericController) return JS_FALSE; + + device = (GPAC_DeviceItem *)gf_list_get(upnp->m_pGenericController->m_Devices, idx); + 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->m_pUPnP = upnp; + gf_js_add_root(upnp->m_pJSCtx, &device->obj); + JS_SetPrivate(device->js_ctx, device->obj, device); + } + *rval = OBJECT_TO_JSVAL(device->obj); + return JS_TRUE; +} + + +static JSBool upnp_find_service(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + const char *dev_ip; + const char *serv_name; + + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || (argc!=2) || !JSVAL_IS_STRING(argv[0]) || !JSVAL_IS_STRING(argv[1]) ) return JS_FALSE; + + dev_ip = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + serv_name = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + *rval = JSVAL_NULL; + if (!dev_ip || !serv_name || !upnp->m_pGenericController) return JS_TRUE; + + u32 i, count = gf_list_count(upnp->m_pGenericController->m_Devices); + for (i=0; i<count; i++) { + GPAC_DeviceItem *item = (GPAC_DeviceItem *) gf_list_get(upnp->m_pGenericController->m_Devices, i); + if (item->m_device->GetURLBase().GetHost() == dev_ip) { + GPAC_ServiceItem *serv = item->FindService(serv_name); + if (serv) { + *rval = OBJECT_TO_JSVAL(serv->obj); + return JS_TRUE; + } + } + } + return JS_TRUE; +} + +static GPAC_MediaRendererItem *upnp_renderer_get_device(GF_UPnP *upnp , JSContext *c, JSObject *obj) +{ + const char *uuid; + jsval val; + u32 i, count; + GPAC_MediaRendererItem *render; + if (!JS_LookupProperty(c, obj, "UUID", &val) || JSVAL_IS_NULL(val) || JSVAL_IS_VOID(val) ) + return NULL; + uuid = JS_GetStringBytes(JSVAL_TO_STRING(val)); + if (!uuid) return NULL; + + count = gf_list_count(upnp->m_pAVCtrlPoint->m_MediaRenderers); + for (i=0; i<count; i++) { + render = (GPAC_MediaRendererItem *)gf_list_get(upnp->m_pAVCtrlPoint->m_MediaRenderers, i); + if (render->m_UUID==uuid) return render; + } + return NULL; +} + +static GPAC_MediaServerItem *upnp_server_get_device(GF_UPnP *upnp , JSContext *c, JSObject *obj) +{ + const char *uuid; + jsval val; + u32 i, count; + GPAC_MediaServerItem *server; + if (!JS_LookupProperty(c, obj, "UUID", &val) || JSVAL_IS_NULL(val) || JSVAL_IS_VOID(val) ) + return NULL; + uuid = JS_GetStringBytes(JSVAL_TO_STRING(val)); + if (!uuid) return NULL; + + count = gf_list_count(upnp->m_pAVCtrlPoint->m_MediaServers); + for (i=0; i<count; i++) { + server = (GPAC_MediaServerItem *)gf_list_get(upnp->m_pAVCtrlPoint->m_MediaServers, i); + if (server->m_UUID==uuid) return server; + } + return NULL; +} + + +static JSBool upnp_renderer_open(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *sobj, *fobj; + jsval val; + GPAC_MediaRendererItem *render; + GPAC_MediaServerItem *server; + const char *item, *resource_url; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || (argc<1) ) return JS_FALSE; + + render = upnp_renderer_get_device(upnp, c, obj); + if (!render) return JS_TRUE; + + PLT_Service* service; + server = NULL; + if (argc==2) { + sobj = JSVAL_IS_NULL(argv[1]) ? NULL : JSVAL_TO_OBJECT(argv[1]); + server = sobj ? upnp_server_get_device(upnp, c, sobj) : NULL; + if (NPT_FAILED(server->m_device->FindServiceByType("urn:schemas-upnp-org:service:ContentDirectory:1", service))) { + server = NULL; + } + if (!server) return JS_TRUE; + } + item = NULL; + resource_url = NULL; + if (JSVAL_IS_OBJECT(argv[0])) { + fobj = JSVAL_TO_OBJECT(argv[0]); + if (!JS_LookupProperty(c, fobj, "ObjectID", &val) || JSVAL_IS_NULL(val) || !JSVAL_IS_STRING(val)) return JS_TRUE; + item = JS_GetStringBytes(JSVAL_TO_STRING(val)); + } + else if (JSVAL_IS_STRING(argv[0])) + resource_url = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + + if (!item && !resource_url) return JS_TRUE; + if (item && !server) return JS_TRUE; + + if (NPT_SUCCEEDED(render->m_device->FindServiceByType("urn:schemas-upnp-org:service:AVTransport:1", service))) { + if (resource_url) { + upnp->m_pAVCtrlPoint->m_MediaController->SetAVTransportURI(render->m_device, 0, resource_url, NULL, NULL); + upnp->m_pAVCtrlPoint->m_MediaController->Play(render->m_device, 0, "1", NULL); + } else { + NPT_String objID = item; + + // look back for the PLT_MediaItem in the results + PLT_MediaObject* track = NULL; + NPT_List<PLT_MediaObject*>::Iterator item = server->m_BrowseResults->GetFirstItem(); + while (item) { + if ((*item)->m_ObjectID == objID) { + if ((*item)->m_Resources.GetItemCount()) { + upnp->m_pAVCtrlPoint->m_MediaController->SetAVTransportURI(render->m_device, 0, (*item)->m_Resources[0].m_Uri, (*item)->m_Didl, NULL); + upnp->m_pAVCtrlPoint->m_MediaController->Play(render->m_device, 0, "1", NULL); + } + break; + } + ++item; + } + } + } + return JS_TRUE; +} + +static JSBool upnp_renderer_playback(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, u32 act_type) +{ + char szSpeed[20]; + GPAC_MediaRendererItem *render; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp) return JS_FALSE; + + render = upnp_renderer_get_device(upnp, c, obj); + if (!render) return JS_TRUE; + + switch (act_type) { + /*play/setspeed*/ + case 0: + strcpy(szSpeed, "1"); + if (argc && JSVAL_IS_NUMBER(argv[0]) ) { + jsdouble d; + JS_ValueToNumber(c, argv[0], &d); + sprintf(szSpeed, "%2.2f", d); + } + upnp->m_pAVCtrlPoint->m_MediaController->Play(render->m_device, 0, szSpeed, NULL); + break; + /*pause*/ + case 1: + upnp->m_pAVCtrlPoint->m_MediaController->Pause(render->m_device, 0, NULL); + break; + /*stop*/ + case 2: + upnp->m_pAVCtrlPoint->m_MediaController->Stop(render->m_device, 0, NULL); + break; + /*seek*/ + case 3: + if (argc && JSVAL_IS_NUMBER(argv[0]) ) { + char szVal[100]; + jsdouble d; + JS_ValueToNumber(c, argv[0], &d); + format_time_string(szVal, d); + upnp->m_pAVCtrlPoint->m_MediaController->Seek(render->m_device, 0, "ABS_TIME", szVal, NULL); + } + break; + } + return JS_TRUE; +} +static JSBool upnp_renderer_play(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return upnp_renderer_playback(c, obj, argc, argv, rval, 0); +} +static JSBool upnp_renderer_pause(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return upnp_renderer_playback(c, obj, argc, argv, rval, 1); +} +static JSBool upnp_renderer_stop(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return upnp_renderer_playback(c, obj, argc, argv, rval, 2); +} +static JSBool upnp_renderer_seek(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return upnp_renderer_playback(c, obj, argc, argv, rval, 3); +} + +static JSBool upnp_get_renderer(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *s_obj; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || !upnp->m_pAVCtrlPoint || (argc!=1) ) return JS_FALSE; + + GPAC_MediaRendererItem *mr = NULL; + if (JSVAL_IS_INT(argv[0])) { + u32 id = JSVAL_TO_INT(argv[0]); + mr = (GPAC_MediaRendererItem *) gf_list_get(upnp->m_pAVCtrlPoint->m_MediaRenderers, id); + } + else if (JSVAL_IS_STRING(argv[0])) { + u32 i=0; + const char *uuid = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + while ((mr = (GPAC_MediaRendererItem *) gf_list_enum(upnp->m_pAVCtrlPoint->m_MediaRenderers, &i))) { + if (mr->m_UUID==uuid) break; + } + } + if (!mr) return JS_FALSE; + + s_obj = JS_NewObject(c, &upnp->upnpDeviceClass, 0, 0); + JS_SetPrivate(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); + JS_DefineProperty(c, s_obj, "UUID", STRING_TO_JSVAL( JS_NewStringCopyZ(c, mr->m_UUID ) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, s_obj, "HostName", STRING_TO_JSVAL( JS_NewStringCopyZ(c, mr->m_device->GetURLBase().GetHost() ) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineFunction(c, s_obj, "Open", upnp_renderer_open, 2, 0); + JS_DefineFunction(c, s_obj, "Play", upnp_renderer_play, 1, 0); + JS_DefineFunction(c, s_obj, "Pause", upnp_renderer_pause, 0, 0); + JS_DefineFunction(c, s_obj, "Stop", upnp_renderer_stop, 0, 0); + JS_DefineFunction(c, s_obj, "Seek", upnp_renderer_seek, 0, 0); + + *rval = OBJECT_TO_JSVAL(s_obj); + return JS_TRUE; +} + +static JSBool upnp_server_browse(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + NPT_String parent; + GPAC_MediaServerItem *server; + const char *dir, *filter; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || (argc!=2) ) return JS_FALSE; + + server = upnp_server_get_device(upnp, c, obj); + if (!server) return JS_FALSE; + + dir = JSVAL_IS_NULL(argv[0]) ? NULL : JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (!dir) dir = "0"; + filter = JSVAL_IS_NULL(argv[1]) ? NULL : JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + if (!filter) filter = "*"; + + PLT_Service* service; + if (NPT_SUCCEEDED(server->m_device->FindServiceByType("urn:schemas-upnp-org:service:ContentDirectory:1", service))) { + if (!strcmp(dir, "0") || !strcmp(dir, "\\") || !strcmp(dir, "/")) { + server->m_ParentDirectories.Clear(); + } + if (!strcmp(dir, "..")) { + if (!server->m_ParentDirectories.GetItemCount()) return JS_FALSE; + server->m_ParentDirectories.Pop(parent); + server->m_ParentDirectories.Peek(parent); + dir=parent; + + if (server->m_ParentDirectories.GetItemCount()==1) + server->m_ParentDirectories.Clear(); + + } else { + server->m_ParentDirectories.Push(dir); + } + upnp->m_pAVCtrlPoint->Browse(server, dir, filter); + + + jsval rval = INT_TO_JSVAL(0); + if (!server->m_BrowseResults.IsNull()) { + rval = INT_TO_JSVAL(server->m_BrowseResults->GetItemCount()); + } + JS_SetProperty(c, obj, "FilesCount", &rval); + } + + return JS_TRUE; +} + + +static JSBool upnp_server_has_parent_dir(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GPAC_MediaServerItem *server; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp) return JS_FALSE; + + server = upnp_server_get_device(upnp, c, obj); + if (!server) return JS_TRUE; + *rval = BOOLEAN_TO_JSVAL( server->m_ParentDirectories.GetItemCount() ? JS_TRUE : JS_FALSE); + return JS_TRUE; +} + +static JSBool upnp_server_get_resource_uri(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 idx; + PLT_MediaObject *mo = (PLT_MediaObject *)JS_GetPrivate(c, obj); + if (!mo || (argc!=1) || !JSVAL_IS_INT(argv[0]) ) return JS_FALSE; + idx = JSVAL_TO_INT(argv[0]); + if (idx<mo->m_Resources.GetItemCount()) { + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, mo->m_Resources[idx].m_Uri)); + } else { + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "")); + } + return JS_TRUE; +} + +static JSBool upnp_server_get_file(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GPAC_MediaServerItem *server; + u32 id; + JSObject *f_obj; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || (argc!=1) || !JSVAL_IS_INT(argv[0]) ) return JS_FALSE; + + server = upnp_server_get_device(upnp, c, obj); + if (!server) return JS_TRUE; + if (server->m_BrowseResults.IsNull()) return JS_TRUE; + + id = JSVAL_TO_INT(argv[0]); + PLT_MediaObject *mo; + server->m_BrowseResults->Get(id, mo); + if (!mo) return JS_TRUE; + + f_obj = JS_NewObject(c, &upnp->upnpDeviceClass, 0, 0); + JS_SetPrivate(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); + JS_DefineProperty(c, f_obj, "Name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, mo->m_Title)), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, f_obj, "ParentID", STRING_TO_JSVAL( JS_NewStringCopyZ(c, mo->m_ParentID)), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, f_obj, "Directory", BOOLEAN_TO_JSVAL( mo->IsContainer() ? JS_TRUE : JS_FALSE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + if (!mo->IsContainer()) { + JS_DefineProperty(c, f_obj, "ResourceCount", INT_TO_JSVAL(mo->m_Resources.GetItemCount()), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineFunction(c, f_obj, "GetResourceURI", upnp_server_get_resource_uri, 1, 0); + } + *rval = OBJECT_TO_JSVAL(f_obj); + return JS_TRUE; +} + +static JSBool upnp_server_get_file_uri(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GPAC_MediaServerItem *server; + u32 id; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || (argc!=1) || !JSVAL_IS_INT(argv[0]) ) return JS_FALSE; + + server = upnp_server_get_device(upnp, c, obj); + if (!server) return JS_TRUE; + if (server->m_BrowseResults.IsNull()) return JS_TRUE; + + id = JSVAL_TO_INT(argv[0]); + PLT_MediaObject *mo; + server->m_BrowseResults->Get(id, mo); + if (!mo) return JS_TRUE; + + if (mo->m_Resources.GetItemCount()) { + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, mo->m_Resources[0].m_Uri) ); + } + return JS_TRUE; +} + +static JSBool upnp_get_server(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *s_obj; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || !upnp->m_pAVCtrlPoint || (argc!=1)) return JS_FALSE; + + + GPAC_MediaServerItem *ms = NULL; + if (JSVAL_IS_INT(argv[0])) { + u32 id = JSVAL_TO_INT(argv[0]); + ms = (GPAC_MediaServerItem *) gf_list_get(upnp->m_pAVCtrlPoint->m_MediaServers, id); + } + else if (JSVAL_IS_STRING(argv[0])) { + u32 i=0; + const char *uuid = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + while ((ms = (GPAC_MediaServerItem *) gf_list_enum(upnp->m_pAVCtrlPoint->m_MediaServers, &i))) { + if (ms->m_UUID==uuid) break; + } + } + if (!ms) return JS_FALSE; + s_obj = JS_NewObject(c, &upnp->upnpDeviceClass, 0, 0); + JS_SetPrivate(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); + JS_DefineProperty(c, s_obj, "UUID", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ms->m_UUID ) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, s_obj, "FilesCount", INT_TO_JSVAL(10), 0, 0, 0 | JSPROP_PERMANENT); + JS_DefineFunction(c, s_obj, "Browse", upnp_server_browse, 2, 0); + JS_DefineFunction(c, s_obj, "GetFile", upnp_server_get_file, 1, 0); + JS_DefineFunction(c, s_obj, "GetFileURI", upnp_server_get_file_uri, 1, 0); + JS_DefineFunction(c, s_obj, "HasParentDirectory", upnp_server_has_parent_dir, 0, 0); + + + *rval = OBJECT_TO_JSVAL(s_obj); + return JS_TRUE; +} + +static JSBool upnp_bind_renderer(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp) return JS_TRUE; + upnp->m_renderer_bound = 1; + + /*remove ourselves from the event filters since we will only be called through JS*/ + gf_term_unregister_event_filter(upnp->m_pTerm, upnp->term_ext); + + return JS_TRUE; +} + +static JSBool upnp_share_resource(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + const char *url, *host; + NPT_String resourceURI; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || !upnp->m_pMediaServer || !argc || !JSVAL_IS_STRING(argv[0]) ) return JS_TRUE; + url = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (!url) return JS_TRUE; + + host = NULL; + if (argc && JSVAL_IS_STRING(argv[1]) ) { + host = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + } + + resourceURI = upnp->m_pMediaServer->GetResourceURI(url, host); + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(upnp->m_pJSCtx, resourceURI ) ); + return JS_TRUE; +} + +static JSBool upnp_share_virtual_resource(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + Bool temp = 0; + const char *res_url, *res_val, *mime; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || !upnp->m_pMediaServer || (argc<2) || !JSVAL_IS_STRING(argv[0]) || !JSVAL_IS_STRING(argv[1]) ) return JS_TRUE; + res_url = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (!res_url) return JS_TRUE; + res_val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + if (!res_val) return JS_TRUE; + + mime = "application/octet-stream"; + if (argc==3) mime = JS_GetStringBytes(JSVAL_TO_STRING(argv[2])); + if ((argc==4) && JSVAL_IS_BOOLEAN(argv[3]) && (JSVAL_TO_BOOLEAN(argv[3])==JS_TRUE) ) temp = 1;; + + upnp->m_pMediaServer->ShareVirtualResource(res_url, res_val, mime, temp); + return JS_TRUE; +} + + +static NPT_UInt8 GENERIC_SCPDXML[] = "<scpd xmlns=\"urn:schemas-upnp-org:service-1-0\"><specVersion> <major>1</major> <minor>0</minor> </specVersion> <actionList> <action> <name>GetStatus</name> <argumentList> <argument> <name>ResultStatus</name> <direction>out</direction> <relatedStateVariable>Status</relatedStateVariable> </argument> </argumentList> </action> </actionList> <serviceStateTable> <stateVariable sendEvents=\"yes\"> <name>Status</name> <dataType>boolean</dataType> </stateVariable></serviceStateTable> </scpd>"; + + +static JSBool upnp_device_setup_service(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *name, *type, *id, *scpd_xml; + GPAC_GenericDevice *device = (GPAC_GenericDevice *)JS_GetPrivate(c, obj); + if (!device) return JS_FALSE; + if (argc<3) return JS_FALSE; + + name = NULL; + if (JSVAL_IS_STRING(argv[0])) name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (!name) return JS_FALSE; + + type = NULL; + if (JSVAL_IS_STRING(argv[1])) type = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + if (!type) return JS_FALSE; + + id = NULL; + if (JSVAL_IS_STRING(argv[2])) id = JS_GetStringBytes(JSVAL_TO_STRING(argv[2])); + if (!id) return JS_FALSE; + + scpd_xml = NULL; + if ((argc>3) && JSVAL_IS_STRING(argv[3])) scpd_xml = JS_GetStringBytes(JSVAL_TO_STRING(argv[3])); + if (!scpd_xml) scpd_xml = (char *)GENERIC_SCPDXML; + + + GPAC_Service* service = new GPAC_Service(device, type, id); + if (service->SetSCPDXML((const char*)scpd_xml) != NPT_SUCCESS) { + delete service; + return JS_FALSE; + } + if (service->InitURLs(name, device->GetUUID() ) != NPT_SUCCESS) { + delete service; + return JS_FALSE; + } + gf_list_add(device->m_pServices, service); + + service->SetupJS(c, device->m_pUPnP, device->obj); + *rval = OBJECT_TO_JSVAL(service->m_pObj); + return JS_TRUE; +} + + + +static JSBool upnp_device_start(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval sval; + char *str; + GPAC_GenericDevice *device = (GPAC_GenericDevice *)JS_GetPrivate(c, obj); + if (!device) return JS_FALSE; + + if (JS_LookupProperty(device->m_pUPnP->m_pJSCtx, obj, "PresentationURL", &sval) && JSVAL_IS_STRING(sval)) { + str = JS_GetStringBytes(JSVAL_TO_STRING(sval)); + char *url = gf_url_concatenate(device->js_source, str); + + /*we will use our media server to exchange the URL if file based + !!! THIS IS BROKEN IF MULTIPLE INTERFACES EXIST ON THE DEVICE !!! + */ + if (device->m_pUPnP->m_pMediaServer) { + device->m_PresentationURL = device->m_pUPnP->m_pMediaServer->GetResourceURI(url, NULL); + } + /*otherwise we can only use absolute URLs */ + else if (strstr(url, "://") && !strstr(url, "file://")) { + device->m_PresentationURL = url; + } + gf_free(url); + } + + str = NULL; + if (JS_LookupProperty(device->m_pUPnP->m_pJSCtx, obj, "ModelDescription", &sval) && JSVAL_IS_STRING(sval)) + str = JS_GetStringBytes(JSVAL_TO_STRING(sval)); + device->m_ModelDescription = str ? str : "GPAC Generic Device"; + + str = NULL; + if (JS_LookupProperty(device->m_pUPnP->m_pJSCtx, obj, "ModelURL", &sval) && JSVAL_IS_STRING(sval)) + str = JS_GetStringBytes(JSVAL_TO_STRING(sval)); + device->m_ModelURL = str ? str : "http://gpac.sourceforge.net"; + + str = NULL; + if (JS_LookupProperty(device->m_pUPnP->m_pJSCtx, obj, "ModelNumber", &sval) && JSVAL_IS_STRING(sval)) + str = JS_GetStringBytes(JSVAL_TO_STRING(sval)); + device->m_ModelNumber = str ? str : GPAC_FULL_VERSION; + + str = NULL; + if (JS_LookupProperty(device->m_pUPnP->m_pJSCtx, obj, "ModelName", &sval) && JSVAL_IS_STRING(sval)) + str = JS_GetStringBytes(JSVAL_TO_STRING(sval)); + device->m_ModelName = str ? str : "GPAC Generic Device"; + + device->m_Manufacturer = "Telecom ParisTech"; + device->m_ManufacturerURL = "http://www.telecom-paristech.fr/"; + + if (device->m_pUPnP->m_pGenericController) { + const char *opt = gf_cfg_get_key(device->m_pUPnP->m_pTerm->user->config, "UPnP", "IgnoreCreatedDevices"); + if (!opt || !strcmp(opt, "yes")) { + device->m_pUPnP->m_pGenericController->m_CtrlPoint->IgnoreUUID(device->GetUUID()); + } + } + if (JS_LookupProperty(device->m_pUPnP->m_pJSCtx, obj, "Run", &sval) && JSVAL_IS_OBJECT(sval)) { + device->obj = obj; + device->run_proc = sval; + gf_js_add_root(device->m_pUPnP->m_pJSCtx, &device->run_proc); + } + if (JS_LookupProperty(device->m_pUPnP->m_pJSCtx, obj, "OnAction", &sval) && JSVAL_IS_OBJECT(sval)) { + device->obj = obj; + device->act_proc = sval; + gf_js_add_root(device->m_pUPnP->m_pJSCtx, &device->act_proc); + } + PLT_DeviceHostReference devRef(device); + device->m_pUPnP->m_pPlatinum->AddDevice(devRef); + + return JS_TRUE; +} + +static JSBool upnp_device_stop(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GPAC_GenericDevice *device = (GPAC_GenericDevice *)JS_GetPrivate(c, obj); + if (!device) return JS_FALSE; + + PLT_DeviceHostReference devRef(device); + device->m_pUPnP->m_pPlatinum->RemoveDevice(devRef); + + return JS_TRUE; +} + + +static GPAC_GenericDevice *upnp_create_generic_device(GF_UPnP *upnp, JSObject*global, const char *id, const char *name) +{ + GPAC_GenericDevice *device; + device = new GPAC_GenericDevice(name, id); + device->m_pUPnP = upnp; + device->js_source = ""; + + device->obj = JS_NewObject(upnp->m_pJSCtx, &upnp->upnpDeviceClass, 0, global); + gf_js_add_root(upnp->m_pJSCtx, &device->obj); + + JS_DefineProperty(upnp->m_pJSCtx, device->obj, "Name", STRING_TO_JSVAL( JS_NewStringCopyZ(upnp->m_pJSCtx, name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(upnp->m_pJSCtx, device->obj, "ID", STRING_TO_JSVAL( JS_NewStringCopyZ(upnp->m_pJSCtx, id) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(upnp->m_pJSCtx, device->obj, "UUID", STRING_TO_JSVAL( JS_NewStringCopyZ(upnp->m_pJSCtx, device->GetUUID()) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineFunction(upnp->m_pJSCtx, device->obj, "SetupService", upnp_device_setup_service, 0, 0); + JS_DefineFunction(upnp->m_pJSCtx, device->obj, "Start", upnp_device_start, 0, 0); +// JS_DefineFunction(upnp->m_pJSCtx, device->obj, "Stop", upnp_device_stop, 0, 0); + JS_SetPrivate(upnp->m_pJSCtx, device->obj, device); + if (!upnp->m_Devices) upnp->m_Devices = gf_list_new(); + gf_list_add(upnp->m_Devices, device); + + return device; +} + +static JSBool upnp_create_device(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GPAC_GenericDevice *device; + const char *id, *name; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || (argc != 2)) return JS_FALSE; + + id = NULL; + if (JSVAL_IS_STRING(argv[0])) id = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + name = NULL; + if (JSVAL_IS_STRING(argv[1])) name = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + if (!id || !name) return JS_FALSE; + + device = upnp_create_generic_device(upnp, NULL, id, name); + if (device) + *rval = OBJECT_TO_JSVAL(device->obj); + + return JS_TRUE; +} + +static JSBool upnp_delete_device(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GPAC_GenericDevice *device; + GF_UPnP *upnp = (GF_UPnP *)JS_GetPrivate(c, obj); + if (!upnp || (argc != 1)) return JS_FALSE; + + device = (GPAC_GenericDevice *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + if (!device) return JS_FALSE; + + gf_list_del_item(upnp->m_Devices, device); + device->DetachJS(c); + PLT_DeviceHostReference devRef = PLT_DeviceHostReference(device); + upnp->m_pPlatinum->RemoveDevice(devRef); + devRef.Detach(); + return JS_TRUE; +} + +Bool GF_UPnP::LoadJS(GF_TermExtJS *param) +{ + u32 i, count; + JSPropertySpec upnpClassProps[] = { + {0, 0, 0, 0, 0} + }; + JSFunctionSpec upnpClassFuncs[] = { + {"BindRenderer", upnp_bind_renderer, 0, 0, 0}, + {"GetMediaServer", upnp_get_server, 1, 0, 0}, + {"GetMediaRenderer", upnp_get_renderer, 1, 0, 0}, + {"ShareResource", upnp_share_resource, 1, 0, 0}, + {"ShareVirtualResource", upnp_share_virtual_resource, 2, 0, 0}, + {"GetDevice", upnp_get_device, 1, 0, 0}, + {"FindService", upnp_find_service, 1, 0, 0}, + {"CreateDevice", upnp_create_device, 2, 0, 0}, + {"DeleteDevice", upnp_delete_device, 1, 0, 0}, + {0, 0, 0, 0, 0} + }; + + if (param->unload) { + if (m_nbJSInstances) { + m_nbJSInstances--; + if (m_pJSCtx==param->ctx) m_nbJSInstances = 0; + + if (!m_nbJSInstances) { + if (m_pGenericController) { + u32 i, count; + count = gf_list_count(m_pGenericController->m_Devices); + for (i=0; i<count; i++) { + GPAC_DeviceItem *item = (GPAC_DeviceItem *)gf_list_get(m_pGenericController->m_Devices, i); + item->DetachJS(); + item->js_ctx = NULL; + } + } + if (m_Devices) { + while (gf_list_count(m_Devices)) { + GPAC_GenericDevice *device = (GPAC_GenericDevice*)gf_list_get(m_Devices, 0); + gf_list_rem(m_Devices, 0); + device->DetachJS(m_pJSCtx); + } + gf_list_del(m_Devices); + m_Devices = NULL; + } + m_pJSCtx = NULL; + } + } + return 0; + } + if (m_nbJSInstances) { + m_nbJSInstances++; + JS_DefineProperty((JSContext*)param->ctx, (JSObject*)param->global, "UPnP", OBJECT_TO_JSVAL(m_pObj), 0, 0, 0); + return 0; + } + + m_pJSCtx = (JSContext*)param->ctx; + /*setup JS bindings*/ + _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); + JS_SetPrivate(m_pJSCtx, m_pObj, this); + + _SETUP_CLASS(upnpDeviceClass, "UPNPAVDEVICE", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, JS_FinalizeStub); + + /*setup JS bindings*/ + JSPropertySpec upnpDeviceClassProps[] = { + {0, 0, 0, 0, 0} + }; + JSFunctionSpec upnpDeviceClassFuncs[] = { + {"FindService", upnp_device_find_service, 0, 0, 0}, + {0, 0, 0, 0, 0} + }; + _SETUP_CLASS(upnpGenericDeviceClass, "UPNPDEVICE", JSCLASS_HAS_PRIVATE, upnpdevice_getProperty, JS_PropertyStub, JS_FinalizeStub); + JS_InitClass(m_pJSCtx, (JSObject*)param->global, 0, &upnpGenericDeviceClass, 0, 0, upnpDeviceClassProps, upnpDeviceClassFuncs, 0, 0); + + _SETUP_CLASS(upnpServiceClass, "UPNPSERVICEDEVICE", JSCLASS_HAS_PRIVATE, upnpservice_getProperty, JS_PropertyStub, JS_FinalizeStub); + JS_InitClass(m_pJSCtx, (JSObject*)param->global, 0, &upnpServiceClass, 0, 0, 0, 0, 0, 0); + + + m_nbJSInstances=1; + + upnp_init_time = gf_sys_clock(); + + count = gf_cfg_get_key_count(m_pTerm->user->config, "UPnPDevices"); + for (i=0; i<count; i++) { + char szFriendlyName[1024], szFile[1024], *sep; + const char *device_id = gf_cfg_get_key_name(m_pTerm->user->config, "UPnPDevices", i); + const char *dev = gf_cfg_get_key(m_pTerm->user->config, "UPnPDevices", device_id); + + if (!strncmp(dev, "off;", 4)) continue; + + if (!strncmp(dev, "on;", 3)) dev += 3; + + sep = (char*)strchr(dev, ';'); + if (!sep) continue; + sep[0] = 0; + strcpy(szFile, dev); + sep[0] = ';'; + + if (!sep[1]) continue; + strcpy(szFriendlyName, sep+1); + + FILE *f = gf_f64_open(szFile, "rt"); + if (!f) continue; + + + GPAC_GenericDevice *device = upnp_create_generic_device(this, (JSObject*)param->global, device_id, szFriendlyName); + device->js_source = szFile; + + jsval aval; + fseek(f, 0, SEEK_END); + u32 size = ftell(f); + fseek(f, 0, SEEK_SET); + char *buf = (char*)gf_malloc(sizeof(char)*(size+1)); + size = fread(buf, 1, size, f); + buf[size]=0; + /*evaluate the script on the object only*/ + if (JS_EvaluateScript(m_pJSCtx, device->obj, buf, size, 0, 0, &aval) != JS_TRUE) { + gf_js_remove_root(m_pJSCtx, &device->obj); + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] Unable to load device %s: script error in %s\n", szFriendlyName, szFile)); + gf_list_del_item(m_Devices, device); + delete device; + } + fclose(f); + gf_free(buf); + } + return 1; +} + +#endif + +static Bool upnp_process(GF_TermExt *termext, u32 action, void *param) +{ + const char *opt; + GF_UPnP *upnp = (GF_UPnP *) termext->udta; + + switch (action) { + case GF_TERM_EXT_START: + opt = gf_modules_get_option((GF_BaseInterface*)termext, "UPnP", "Enabled"); + if (!opt) { + opt = "yes"; + gf_modules_set_option((GF_BaseInterface*)termext, "UPnP", "Enabled", "yes"); + } + if (!strcmp(opt, "yes")) { + upnp->Load((GF_Terminal *)param); + return 1; + } + return 0; + + case GF_TERM_EXT_STOP: + upnp->Unload(); + break; + + case GF_TERM_EXT_PROCESS: +#ifdef GPAC_HAS_SPIDERMONKEY + if (upnp->m_Devices) { + u32 now; + now = gf_sys_clock() - upnp->upnp_init_time; + if (now - upnp->last_time > 200) { + u32 i, count; + jsval argv[1], rval; + upnp->LockJavascript(1); + argv[0] = DOUBLE_TO_JSVAL( JS_NewDouble(upnp->m_pJSCtx, (Double)now / 1000.0) ); + count = gf_list_count(upnp->m_Devices); + for (i=0; i<count; i++) { + GPAC_GenericDevice *device = (GPAC_GenericDevice *)gf_list_get(upnp->m_Devices, i); + if (device->run_proc) + JS_CallFunctionValue(upnp->m_pJSCtx, device->obj, device->run_proc, 1, argv, &rval); + } + upnp->LockJavascript(0); + upnp->last_time = now; + } + } +#endif + break; + + case GF_TERM_EXT_EVENT: + return upnp->ProcessEvent((GF_Event*)param); +#ifdef GPAC_HAS_SPIDERMONKEY + case GF_TERM_EXT_JSBIND: + return upnp->LoadJS((GF_TermExtJS*)param); +#endif + } + return 0; +} + + +GF_TermExt *upnp_new() +{ + GF_TermExt *dr; + GF_UPnP *ext; + dr = (GF_TermExt *) gf_malloc(sizeof(GF_TermExt)); + memset(dr, 0, sizeof(GF_TermExt)); + GF_REGISTER_MODULE_INTERFACE(dr, GF_TERM_EXT_INTERFACE, "GPAC UPnP Platinum", "gpac distribution"); + + dr->process = upnp_process; + ext = new GF_UPnP(); + dr->udta = ext; + ext->term_ext = dr; + + dr->caps = GF_TERM_EXTENSION_FILTER_EVENT | GF_TERM_EXTENSION_NOT_THREADED; +#ifdef GPAC_HAS_SPIDERMONKEY + dr->caps |= GF_TERM_EXTENSION_JS; +#endif + return dr; +} + + +void upnp_delete(GF_BaseInterface *ifce) +{ + GF_TermExt *dr = (GF_TermExt *) ifce; + GF_UPnP *ext = (GF_UPnP *) dr->udta; + delete ext; + gf_free(dr); +} + + + +#ifdef __cplusplus +extern "C" { +#endif + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_TERM_EXT_INTERFACE, + 0 + }; + return si; +} + +GF_EXPORT +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + if (InterfaceType == GF_TERM_EXT_INTERFACE) return (GF_BaseInterface *)upnp_new(); + return NULL; +} + +GF_EXPORT +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { + case GF_TERM_EXT_INTERFACE: + upnp_delete(ifce); + break; + } +} + +#ifdef __cplusplus +} +#endif diff --git a/modules/platinum/GPACPlatinum.h b/modules/platinum/GPACPlatinum.h new file mode 100644 index 0000000..5307672 --- /dev/null +++ b/modules/platinum/GPACPlatinum.h @@ -0,0 +1,146 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + + +#ifndef _GPAC_PLATINUM_H_ +#define _GPAC_PLATINUM_H_ + +#include "Platinum.h" +#include "PltUPnP.h" +#include "GPACFileMediaServer.h" +#include "GPACMediaRenderer.h" +#include "GPACMediaController.h" +#include "GenericDevice.h" + +#include <gpac/modules/term_ext.h> +#include <gpac/term_info.h> +#include <gpac/thread.h> +#include <gpac/network.h> +#include <gpac/options.h> +#include <gpac/internal/terminal_dev.h> + +#ifdef GPAC_HAS_SPIDERMONKEY + +#include <gpac/internal/scenegraph_dev.h> +#include <jsapi.h> + +#endif + +class GPAC_DeviceItem; + + +class GF_UPnP +{ +public: + GF_UPnP(); + ~GF_UPnP(); + + /*load UPnP services*/ + void Load(GF_Terminal *term); + /*unload UPnP services*/ + void Unload(); + + /*GPAC event filter*/ + Bool ProcessEvent(GF_Event *evt); + + GF_TermExt *term_ext; + /*GPAC's terminal*/ + GF_Terminal *m_pTerm; + + /*Platinum's UPnP stack*/ + PLT_UPnP *m_pPlatinum; + + /*GPAC UPnP/DLNA media renderer if loaded*/ + GPAC_MediaRenderer *m_pMediaRenderer; + /*is renderer bound to the script ? If so, events are dispatched to the script's "UPnP" object*/ + Bool m_renderer_bound; + NPT_String m_IPFilter; + + /*regular media file server from platinum*/ + GPAC_FileMediaServer *m_pMediaServer; + + /*GPAC's AVControlPoint*/ + GPAC_MediaController *m_pAVCtrlPoint; + + void LockJavascript(Bool do_lock); + + /*callback from GPAC MediaRenderer*/ + void OnConnect(const char *url, const char *src_url); + void OnPause(Bool do_resume, const char *src_url); + void OnStop(const char *src_url); + void OnSeek(Double time); + void OnSetPlayMode(const char *src_url); + void ContainerChanged(PLT_DeviceDataReference& device, const char *item_id, const char *update_id); + NPT_String OnMigrate(); + + GPAC_GenericController *m_pGenericController; + + PLT_CtrlPoint *m_pCtrlPoint; + PLT_CtrlPointReference m_ctrlPtRef; + + /*JS bindings*/ +#ifdef GPAC_HAS_SPIDERMONKEY + Bool LoadJS(GF_TermExtJS *param); + u32 m_nbJSInstances; + JSContext *m_pJSCtx; + JSObject *m_pObj; + JSClass upnpClass; + JSClass upnpDeviceClass; + JSClass upnpGenericDeviceClass; + JSClass upnpServiceClass; + + GF_List *m_Devices; + u32 last_time, upnp_init_time; + + /*callback from AVControlPoint device discovery*/ + void OnMediaServerAdd(PLT_DeviceDataReference& device, int added); + void OnMediaRendererAdd(PLT_DeviceDataReference& device, int added); + + void OnDeviceAdd(GPAC_DeviceItem *item, int added); + + + jsval GetUPnPDevice(const char *src_url); + +#else + void OnMediaServerAdd(PLT_DeviceDataReference& device, int added) {} + void OnMediaRendererAdd(PLT_DeviceDataReference& device, int added) {} + void OnDeviceAdd(GPAC_DeviceItem *item, int added) {} +#endif + +}; + +#ifdef GPAC_HAS_SPIDERMONKEY +JSBool upnpservice_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp); +#endif + +void format_time_string(char *str, Double dur); + + +#endif /*_GPAC_PLATINUM_H_*/ diff --git a/modules/platinum/GenericDevice.cpp b/modules/platinum/GenericDevice.cpp new file mode 100644 index 0000000..09c28b9 --- /dev/null +++ b/modules/platinum/GenericDevice.cpp @@ -0,0 +1,930 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + + +#include "GenericDevice.h" +#include "GPACPlatinum.h" +#include "PltXmlHelper.h" + +NPT_SET_LOCAL_LOGGER("gpac.genericdevice") + +GPAC_ServiceItem::GPAC_ServiceItem(GPAC_DeviceItem *device, PLT_Service *service) : m_device(device), m_service(service) +{ +#ifdef GPAC_HAS_SPIDERMONKEY + obj = NULL; + on_event = 0; + m_StateListeners = gf_list_new(); + m_ArgListeners = gf_list_new(); + subscribed = 0; + vars=NULL; +#endif +} + +GPAC_ServiceItem::~GPAC_ServiceItem() +{ +#ifdef GPAC_HAS_SPIDERMONKEY + DetachJS(); + gf_list_del(m_StateListeners); + gf_list_del(m_ArgListeners); +#endif +} + +#ifdef GPAC_HAS_SPIDERMONKEY +void GPAC_ServiceItem::DetachJS() +{ + if (obj) { + gf_js_remove_root(js_ctx, &obj); + JS_SetPrivate(js_ctx, obj, NULL); + obj = NULL; + } + if (on_event) { + gf_js_remove_root(js_ctx, &on_event); + on_event = NULL; + } + while (gf_list_count(m_StateListeners)) { + GPAC_StateVariableListener *svl = (GPAC_StateVariableListener *)gf_list_get(m_StateListeners, 0); + gf_list_rem(m_StateListeners, 0); + gf_js_remove_root(js_ctx, &svl->on_event); + delete svl; + } + while (gf_list_count(m_ArgListeners)) { + GPAC_ActionArgListener *argl = (GPAC_ActionArgListener *)gf_list_get(m_ArgListeners, 0); + gf_list_rem(m_ArgListeners, 0); + gf_js_remove_root(js_ctx, &argl->on_event); + delete argl; + } +} +#endif + + +GPAC_DeviceItem::GPAC_DeviceItem(PLT_DeviceDataReference device, NPT_String uuid) + : m_device(device), m_UUID(uuid) +{ +#ifdef GPAC_HAS_SPIDERMONKEY + obj = NULL; + js_ctx = NULL; + m_Services = gf_list_new(); +#endif +} + +GPAC_DeviceItem::~GPAC_DeviceItem() +{ +#ifdef GPAC_HAS_SPIDERMONKEY + DetachJS(); +#endif + gf_list_del(m_Services); +} + +#ifdef GPAC_HAS_SPIDERMONKEY +void GPAC_DeviceItem::DetachJS() { + if (obj) { + gf_js_remove_root(js_ctx, &obj); + JS_SetPrivate(js_ctx, obj, NULL); + obj = NULL; + } + while (gf_list_count(m_Services)) { + GPAC_ServiceItem *item = (GPAC_ServiceItem*)gf_list_get(m_Services, 0); + gf_list_rem(m_Services, 0); + delete item; + } +} +#endif + +#ifdef GPAC_HAS_SPIDERMONKEY +static JSBool upnp_service_set_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GPAC_StateVariableListener *svl = NULL; + const char *name; + u32 i; + GPAC_ServiceItem *service = (GPAC_ServiceItem *)JS_GetPrivate(c, obj); + if (!service || !argc || !JSVAL_IS_OBJECT(argv[0])) return JS_FALSE; + + if (argc<1) { + if (service->on_event) gf_js_remove_root(c, &service->on_event); + service->on_event = NULL; + if (!JSVAL_IS_NULL(argv[0])) { + service->on_event = argv[0]; + gf_js_add_root(c, &service->on_event); + if (!service->subscribed) { + service->m_device->m_pUPnP->m_pGenericController->m_CtrlPoint->Subscribe(service->m_service); + service->subscribed = 1; + } + } + return JS_TRUE; + } + if (!JSVAL_IS_STRING(argv[1])) return JS_FALSE; + name = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + if (!name) return JS_FALSE; + + /*variable state listener*/ + i=0; + while ((svl = (GPAC_StateVariableListener *)gf_list_enum(service->m_StateListeners, &i))) { + if (svl->name == name) break; + } + if (!svl) { + svl = new GPAC_StateVariableListener(); + svl->name = name; + svl->var = service->m_service->FindStateVariable(name); + gf_list_add(service->m_StateListeners, svl); + } + if (svl->on_event) gf_js_remove_root(c, &svl->on_event); + if (JSVAL_IS_NULL(argv[0])) { + gf_list_del_item(service->m_StateListeners, svl); + delete svl; + } + svl->on_event = argv[0]; + gf_js_add_root(c, &svl->on_event); + if (!service->subscribed) { + service->m_device->m_pUPnP->m_pGenericController->m_CtrlPoint->Subscribe(service->m_service); + service->subscribed = 1; + } + return JS_TRUE; +} + + +static JSBool upnp_service_set_action_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + PLT_ActionDesc *action; + PLT_ArgumentDesc *desc; + GPAC_ActionArgListener *argl = NULL; + const char *name; + Bool script_callback = 0; + u32 i; + GPAC_ServiceItem *service = (GPAC_ServiceItem *)JS_GetPrivate(c, obj); + if (!service || (argc<2) || !JSVAL_IS_STRING(argv[0]) || !JSVAL_IS_OBJECT(argv[1])) return JS_FALSE; + + name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (!name) return JS_FALSE; + + action = service->m_service->FindActionDesc(name); + if (!action) return JS_FALSE; + + + desc = NULL; + if (argc==3) { + if (JSVAL_IS_BOOLEAN(argv[2])) { + script_callback = 1; + } else { + if (!JSVAL_IS_STRING(argv[2]) ) return JS_FALSE; + name = JS_GetStringBytes(JSVAL_TO_STRING(argv[2])); + if (!name) return JS_FALSE; + desc = action->GetArgumentDesc(name); + if (!desc) return JS_FALSE; + } + } + + + /*action listener*/ + i=0; + while ((argl = (GPAC_ActionArgListener *)gf_list_enum(service->m_ArgListeners, &i))) { + if (argl->arg == desc) break; + } + if (!argl) { + argl = new GPAC_ActionArgListener(); + argl->arg = desc; + argl->action = action; + gf_list_add(service->m_ArgListeners, argl); + } + if (argl->on_event) gf_js_remove_root(c, &argl->on_event); + if (JSVAL_IS_NULL(argv[1])) { + gf_list_del_item(service->m_ArgListeners, argl); + delete argl; + } + argl->on_event = argv[1]; + argl->is_script = script_callback; + gf_js_add_root(c, &argl->on_event); + return JS_TRUE; +} + +JSBool upnpservice_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + char *prop_name; + GPAC_ServiceItem *service = (GPAC_ServiceItem *)JS_GetPrivate(c, obj); + if (!service) return JS_FALSE; + + if (!JSVAL_IS_STRING(id)) return JS_TRUE; + prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + if (!prop_name) return JS_FALSE; + + if (!strcmp(prop_name, "Device")) { + *vp = OBJECT_TO_JSVAL(service->m_device->obj); + return JS_TRUE; + } + if (!strcmp(prop_name, "ModifiedStateVariablesCount")) { + *vp = INT_TO_JSVAL(service->vars ? service->vars->GetItemCount() : 0); + return JS_TRUE; + } + return JS_TRUE; +} + + +static JSBool upnp_service_has_var(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *name = NULL; + GPAC_ServiceItem *service = (GPAC_ServiceItem *)JS_GetPrivate(c, obj); + if (!service || !argc || !JSVAL_IS_STRING(argv[0]) ) + return JS_FALSE; + + name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + *rval = BOOLEAN_TO_JSVAL( (service->m_service->FindStateVariable(name)==NULL) ? JS_FALSE : JS_TRUE ); + return JS_TRUE; +} + +static JSBool upnp_service_has_action(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + PLT_ActionDesc *action; + char *name = NULL; + GPAC_ServiceItem *service = (GPAC_ServiceItem *)JS_GetPrivate(c, obj); + if (!service || !argc || !JSVAL_IS_STRING(argv[0]) ) + return JS_FALSE; + + name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + action = service->m_service->FindActionDesc(name); + + *rval = BOOLEAN_TO_JSVAL(action ? JS_TRUE : JS_FALSE); + if (!action) return JS_TRUE; + + if ((argc==2) && JSVAL_IS_STRING(argv[1])) { + name = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + if (action->GetArgumentDesc(name) == NULL) *rval = BOOLEAN_TO_JSVAL(JS_FALSE); + } + return JS_TRUE; +} + +static JSBool upnp_service_call_action(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 i=1; + GPAC_ActionUDTA *act_udta = NULL; + char *action_name = NULL; + GPAC_ServiceItem *service = (GPAC_ServiceItem *)JS_GetPrivate(c, obj); + if (!service || !argc || !JSVAL_IS_STRING(argv[0]) ) return JS_FALSE; + + action_name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + + PLT_ActionDesc* action_desc = service->m_service->FindActionDesc(action_name); + if (action_desc == NULL) return JS_FALSE; + PLT_ActionReference action; + + NPT_CHECK_SEVERE( + service->m_device->m_pUPnP->m_pGenericController->m_CtrlPoint->CreateAction( + service->m_device->m_device, + service->m_service->GetServiceType(), + action_name, + action) + ); + + + if ((argc>=2) && JSVAL_IS_OBJECT(argv[1])) { + JSObject *list = JSVAL_TO_OBJECT(argv[1]); + u32 i, count; + JS_GetArrayLength(c, list, (jsuint*) &count); + + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling %s(", action_name)); + i=0; + while (i+2<=count) { + jsval an_arg; + char *param_val; + char szParamVal[1024]; + JS_GetElement(c, list, (jsint) i, &an_arg); + char *param_name = JSVAL_IS_STRING(an_arg) ? JS_GetStringBytes(JSVAL_TO_STRING(an_arg)) : NULL; + + JS_GetElement(c, list, (jsint) i+1, &an_arg); + + param_val = ""; + if (JSVAL_IS_STRING(an_arg)) { + param_val = JS_GetStringBytes(JSVAL_TO_STRING(an_arg)); + } else if (JSVAL_IS_BOOLEAN(an_arg)) { + param_val = (char *) ((JSVAL_TO_BOOLEAN(an_arg) == JS_TRUE) ? "true" : "false"); + } + else if (JSVAL_IS_INT(argv[1])) { + sprintf(szParamVal, "%d", JSVAL_TO_INT(an_arg)); + param_val = szParamVal; + } + else if (JSVAL_IS_NUMBER(an_arg)) { + jsdouble v; + JS_ValueToNumber(c, an_arg, &v); + sprintf(szParamVal, "%g", v); + param_val = szParamVal; + } + + if (!param_name || !param_val) return JS_FALSE; + + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, (" %s(%s)", param_name, param_val)); + + if (action->SetArgumentValue(param_name, param_val) != NPT_SUCCESS) + return JS_FALSE; + i+=2; + } + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, (" )\n")); + } + + if ((argc==3) && JSVAL_IS_OBJECT(argv[2])) { + act_udta = new GPAC_ActionUDTA(); + act_udta->udta = argv[2]; + gf_js_add_root(c, &act_udta->udta); + } + service->m_device->m_pUPnP->m_pGenericController->m_CtrlPoint->InvokeAction(action, act_udta); + return JS_TRUE; +} + +#endif + + +GPAC_ServiceItem *GPAC_DeviceItem::FindService(const char *type) +{ + u32 i, count; + GPAC_ServiceItem *serv; + + count = gf_list_count(m_Services); + for (i=0; i<count; i++) { + serv = (GPAC_ServiceItem*)gf_list_get(m_Services, i); + if (serv->m_service->GetServiceType() == type) + return serv; + } + + PLT_Service *service; + if (m_device->FindServiceByType(type, service) != NPT_SUCCESS) return NULL; + + serv = new GPAC_ServiceItem(this, service); + +#ifdef GPAC_HAS_SPIDERMONKEY + serv->js_ctx = js_ctx; + serv->obj = JS_NewObject(serv->js_ctx, &m_pUPnP->upnpServiceClass, 0, obj); + gf_js_add_root(serv->js_ctx, &serv->obj); + JS_SetPrivate(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); + JS_DefineProperty(serv->js_ctx, serv->obj, "Type", STRING_TO_JSVAL( JS_NewStringCopyZ(serv->js_ctx, service->GetServiceType()) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(serv->js_ctx, serv->obj, "Hostname", STRING_TO_JSVAL( JS_NewStringCopyZ(serv->js_ctx, m_device->GetURLBase().GetHost() ) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineFunction(serv->js_ctx, serv->obj, "SetStateVariableListener", upnp_service_set_listener, 1, 0); + JS_DefineFunction(serv->js_ctx, serv->obj, "HasStateVariable", upnp_service_has_var, 1, 0); + JS_DefineFunction(serv->js_ctx, serv->obj, "HasAction", upnp_service_has_action, 2, 0); + JS_DefineFunction(serv->js_ctx, serv->obj, "CallAction", upnp_service_call_action, 2, 0); + JS_DefineFunction(serv->js_ctx, serv->obj, "SetActionListener", upnp_service_set_action_listener, 2, 0); + +#endif + + gf_list_add(m_Services, serv); + return serv; +} + + +GPAC_GenericController::GPAC_GenericController(PLT_CtrlPointReference& ctrlPoint, GF_UPnP *upnp) +{ + m_pUPnP = upnp; + m_CtrlPoint = ctrlPoint; + m_CtrlPoint->AddListener(this); + m_ControlPointLock = gf_mx_new("GenericController"); + m_Devices = gf_list_new(); +} + +GPAC_GenericController::~GPAC_GenericController() +{ + m_CtrlPoint->RemoveListener(this); + gf_mx_del(m_ControlPointLock); + while (gf_list_count(m_Devices)) { + GPAC_DeviceItem*ms = (GPAC_DeviceItem*)gf_list_get(m_Devices, 0); + gf_list_rem(m_Devices, 0); + delete ms; + } + gf_list_del(m_Devices); +} + + + +NPT_Result GPAC_GenericController::OnDeviceAdded(PLT_DeviceDataReference& device) +{ + GPAC_DeviceItem *item; + NPT_String uuid = device->GetUUID(); + gf_mx_p(m_ControlPointLock); + + u32 i, count = gf_list_count(m_Devices); + for (i=0; i<count; i++) { + item = (GPAC_DeviceItem *) gf_list_get(m_Devices, i); + if (item->m_UUID == uuid ) { + gf_mx_v(m_ControlPointLock); + return NPT_SUCCESS; + } + } + item = new GPAC_DeviceItem(device, device->GetUUID() ); + gf_list_add(m_Devices, item ); + m_pUPnP->OnDeviceAdd(item, 1); + gf_mx_v(m_ControlPointLock); + return NPT_SUCCESS; +} +NPT_Result GPAC_GenericController::OnDeviceRemoved(PLT_DeviceDataReference& device) +{ + u32 i, count; + GPAC_DeviceItem *item = NULL; + NPT_String uuid = device->GetUUID(); + gf_mx_p(m_ControlPointLock); + count = gf_list_count(m_Devices); + for (i=0; i<count; i++) { + item = (GPAC_DeviceItem *) gf_list_get(m_Devices, i); + if (item->m_UUID == uuid ) { + gf_list_rem(m_Devices, i); + break; + } + item = NULL; + } + if (item) { + m_pUPnP->OnDeviceAdd(item, 0); + delete item; + } + gf_mx_v(m_ControlPointLock); + return NPT_SUCCESS; +} + + +#ifdef GPAC_HAS_SPIDERMONKEY + +static JSBool upnp_action_get_argument_value(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + NPT_String res; + char *arg_name = NULL; + PLT_Action *action = (PLT_Action *) JS_GetPrivate(c, obj); + if (!action || !argc || !JSVAL_IS_STRING(argv[0])) return JS_FALSE; + + arg_name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (!arg_name) return JS_FALSE; + + action->GetArgumentValue(arg_name, res); + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, res) ); + return JS_TRUE; +} +static JSBool upnp_action_get_error_code(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + NPT_String res; + char *arg_name = NULL; + PLT_Action *action = (PLT_Action *) JS_GetPrivate(c, obj); + if (!action ) return JS_FALSE; + *rval = INT_TO_JSVAL( action->GetErrorCode() ); + return JS_TRUE; +} + +static JSBool upnp_action_get_error(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + NPT_String res; + unsigned int code; + char *arg_name = NULL; + PLT_Action *action = (PLT_Action *) JS_GetPrivate(c, obj); + if (!action ) return JS_FALSE; + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, action->GetError( code ) ) ); + return JS_TRUE; +} + +#endif + + +NPT_Result GPAC_GenericController::OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata) +{ +#ifdef GPAC_HAS_SPIDERMONKEY + u32 i, count; + GPAC_DeviceItem *item = NULL; + GPAC_ServiceItem *serv = NULL; + GPAC_ActionArgListener *argl, *act_l; + PLT_Service* service = action->GetActionDesc().GetService(); + NPT_String uuid; + GPAC_ActionUDTA *act_udta = (GPAC_ActionUDTA *)userdata; + + /*this is NOT an actionResponse to an action triggered on a generic device*/ + if (act_udta && act_udta->m_Reserved) act_udta = NULL; + + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Receive %s Response - error code %d\n", (char *) action->GetActionDesc().GetName(), res)); + + gf_mx_p(m_ControlPointLock); + + /*get our device*/ + uuid = service->GetDevice()->GetUUID(); + count = gf_list_count(m_Devices); + for (i=0; i<count; i++) { + item = (GPAC_DeviceItem *) gf_list_get(m_Devices, i); + if (item->m_UUID == uuid ) { + break; + } + item = NULL; + } + gf_mx_v(m_ControlPointLock); + + if (!item) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] Receive %s Response on unknown device (uuid %s)\n", (char *) action->GetActionDesc().GetName(), (char *) uuid)); + goto exit; + } + /*get our service*/ + count = gf_list_count(item->m_Services); + for (i=0; i<count; i++) { + serv = (GPAC_ServiceItem *)gf_list_get(item->m_Services, i); + if (serv->m_service == service) break; + } + if (!serv) { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] Receive %s Response on unknown service %s\n", (char *) action->GetActionDesc().GetName(), (char *) service->GetServiceType())); + goto exit; + } + + /*locate our listeners*/ + act_l = NULL; + i=0; + while ((argl = (GPAC_ActionArgListener *)gf_list_enum(serv->m_ArgListeners, &i))) { + NPT_String value; + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] checking argument %s\n", (char *) argl->action->GetName() )); + if (argl->action->GetName() != action->GetActionDesc().GetName() ) continue; + + /*global action listener*/ + if (argl->arg==NULL) { + act_l = argl; + continue; + } + /*if error don't trigger listeners*/ + if (res != NPT_SUCCESS) { + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[UPnP] Receive %s Response: error on remote device %d\n", (char *) action->GetActionDesc().GetName(), res)); + continue; + } + /*action arg listener*/ + if (action->GetArgumentValue(argl->arg->GetName(), value) == NPT_SUCCESS) { + jsval argv[1], rval; + + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling handler for response %s argument %s\n", (char *) action->GetActionDesc().GetName(), (char *) argl->arg->GetName() )); + m_pUPnP->LockJavascript(1); + argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(serv->js_ctx, value) ); + JS_CallFunctionValue(serv->js_ctx, serv->obj, argl->on_event, 1, argv, &rval); + m_pUPnP->LockJavascript(0); + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] %s Response: couldn't get argument %s value\n", (char *) action->GetActionDesc().GetName(), (char *) argl->arg->GetName() )); + } + } + + if (act_l) { + jsval rval; + m_pUPnP->LockJavascript(1); + if (act_l->is_script) { + JSObject *act_obj; + jsval argv[2]; + + 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); + JS_SetPrivate(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); + JS_DefineFunction(serv->js_ctx, act_obj, "GetError", upnp_action_get_error, 1, 0); + + gf_js_add_root(serv->js_ctx, &act_obj); + argv[0] = OBJECT_TO_JSVAL(act_obj); + if (act_udta) { + argv[1] = act_udta->udta; + JS_CallFunctionValue(serv->js_ctx, serv->obj, act_l->on_event, 2, argv, &rval); + } else { + JS_CallFunctionValue(serv->js_ctx, serv->obj, act_l->on_event, 1, argv, &rval); + } + gf_js_remove_root(serv->js_ctx, &act_obj); + } + /*if error don't trigger listeners*/ + else if (res == NPT_SUCCESS) { + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling handler for response %s\n", (char *) action->GetActionDesc().GetName())); + JS_CallFunctionValue(serv->js_ctx, serv->obj, act_l->on_event, 0, 0, &rval); + } + else { + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[UPnP] response %s has error %d\n", (char *) action->GetActionDesc().GetName(), res )); + } + m_pUPnP->LockJavascript(0); + } + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Done processing response %s\n", (char *) action->GetActionDesc().GetName())); + +exit: + if (act_udta) { + gf_js_remove_root(serv->js_ctx, &act_udta->udta); + delete act_udta; + } + + return NPT_SUCCESS; +#else + return NPT_SUCCESS; +#endif +} + +NPT_Result GPAC_GenericController::OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars) +{ +#ifdef GPAC_HAS_SPIDERMONKEY + u32 i, count; + GPAC_DeviceItem *item = NULL; + GPAC_ServiceItem *serv = NULL; + GPAC_StateVariableListener *svl; + + gf_mx_p(m_ControlPointLock); + + NPT_String uuid = service->GetDevice()->GetUUID(); + count = gf_list_count(m_Devices); + for (i=0; i<count; i++) { + item = (GPAC_DeviceItem *) gf_list_get(m_Devices, i); + if (item->m_UUID == uuid ) { + break; + } + item = NULL; + } + gf_mx_v(m_ControlPointLock); + + if (!item) return NPT_SUCCESS; + + count = gf_list_count(item->m_Services); + for (i=0; i<count; i++) { + serv = (GPAC_ServiceItem *)gf_list_get(item->m_Services, i); + if (serv->m_service == service) break; + } + if (!serv) return NPT_SUCCESS; + + if (serv->on_event) { + jsval rval; + m_pUPnP->LockJavascript(1); + serv->vars = vars; + JS_CallFunctionValue(serv->js_ctx, serv->obj, serv->on_event, 0, 0, &rval); + m_pUPnP->LockJavascript(0); + serv->vars = NULL; + } + + i=0; + while ((svl = (GPAC_StateVariableListener *)gf_list_enum(serv->m_StateListeners, &i))) { + /*check if we can find our var in this list*/ + if (vars->Contains(svl->var)) { + jsval argv[1], rval; + m_pUPnP->LockJavascript(1); + argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(serv->js_ctx, svl->var->GetValue() ) ); + JS_CallFunctionValue(serv->js_ctx, serv->obj, svl->on_event, 1, argv, &rval); + m_pUPnP->LockJavascript(0); + } + + } + +#endif + return NPT_SUCCESS; +} + + +GPAC_Service::GPAC_Service(PLT_DeviceData* device, const char *type, const char *id, const char *last_change_namespace) + : PLT_Service(device, type, id, last_change_namespace) +{ +#ifdef GPAC_HAS_SPIDERMONKEY + m_pObj = NULL; + m_pCtx = NULL; +#endif +} + +GPAC_Service::~GPAC_Service() +{ +#ifdef GPAC_HAS_SPIDERMONKEY + if (m_pObj) gf_js_remove_root(m_pCtx, &m_pObj); +#endif +} + +#ifdef GPAC_HAS_SPIDERMONKEY + + +static JSBool upnp_service_set_state_variable(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *name, *val; + GPAC_Service* service = (GPAC_Service*) JS_GetPrivate(c, obj); + if (!service) return JS_FALSE; + + name = NULL; + if (JSVAL_IS_STRING(argv[0])) name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (!name) return JS_FALSE; + + val = NULL; + if (JSVAL_IS_STRING(argv[1])) val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + if (!val) return JS_FALSE; + + service->SetStateVariable(name, val); + return JS_TRUE; +} + +void GPAC_Service::SetupJS(JSContext *c, GF_UPnP *upnp, JSObject *parent) +{ + m_pCtx = c; + m_pObj = JS_NewObject(c, &upnp->upnpDeviceClass, 0, parent); + gf_js_add_root(m_pCtx, &m_pObj); + JS_SetPrivate(c, m_pObj, this); + JS_DefineFunction(c, m_pObj, "SetStateVariable", upnp_service_set_state_variable, 2, 0); + +} +#endif + + +GPAC_GenericDevice::GPAC_GenericDevice(const char* FriendlyName, const char *device_id) + : PLT_DeviceHost("/", "", device_id ? device_id : "urn:schemas-upnp-org:device:GenericDevice:1", FriendlyName) +{ + m_pServices = gf_list_new(); + +#ifdef GPAC_HAS_SPIDERMONKEY + run_proc = JSVAL_NULL; + act_proc = JSVAL_NULL; + obj = NULL; + js_source = ""; + act_ref = NULL; + m_pSema = NULL; + m_pMutex = gf_mx_new("UPnP Generic Device"); +#endif +} + +GPAC_GenericDevice::~GPAC_GenericDevice() +{ + gf_list_del(m_pServices); +#ifdef GPAC_HAS_SPIDERMONKEY + if (m_pSema) gf_sema_del(m_pSema); + m_pSema = NULL; + gf_mx_del(m_pMutex); +#endif +} + +#ifdef GPAC_HAS_SPIDERMONKEY +void GPAC_GenericDevice::DetachJS(JSContext *c) +{ + u32 i, count; + if (obj) gf_js_remove_root(c, &obj); + obj = NULL; + if (run_proc) gf_js_remove_root(c, &run_proc); + run_proc = NULL; + if (act_proc) gf_js_remove_root(c, &act_proc); + act_proc = NULL; + + count = gf_list_count(m_pServices); + for (i=0; i<count; i++) { + GPAC_Service *service = (GPAC_Service*)gf_list_get(m_pServices, i); + if (service->m_pObj) { + gf_js_remove_root(c, &service->m_pObj); + service->m_pObj = NULL; + } + } +} +#endif + +NPT_Result +GPAC_GenericDevice::SetupServices(PLT_DeviceData& data) +{ + u32 i, count; + count = gf_list_count(m_pServices); + for (i=0; i<count; i++) { + GPAC_Service *service = (GPAC_Service *)gf_list_get(m_pServices, i); + data.AddService(service); + } + return NPT_SUCCESS; +} + + +#ifdef GPAC_HAS_SPIDERMONKEY +static JSBool upnp_action_get_argument(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *act_name; + GPAC_GenericDevice *device = (GPAC_GenericDevice *)JS_GetPrivate(c, obj); + if (!device || !argc || !JSVAL_IS_STRING(argv[0]) ) return JS_FALSE; + + act_name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + NPT_String value; + + if (device->act_ref->GetArgumentValue(act_name, value) != NPT_SUCCESS) return JS_FALSE; + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, value) ); + return JS_TRUE; +} +#endif + +#ifdef GPAC_HAS_SPIDERMONKEY + +static JSBool upnp_action_send_reply(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 i=1; + GPAC_GenericDevice *device = (GPAC_GenericDevice *)JS_GetPrivate(c, obj); + if (!device) return JS_FALSE; + + if (argc && JSVAL_IS_OBJECT(argv[0]) ) { + JSObject *list = JSVAL_TO_OBJECT(argv[0]); + u32 i, count; + JS_GetArrayLength(c, list, (jsuint*) &count); + + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Calling response %s(", (char *) device->act_ref->GetActionDesc().GetName())); + i=0; + while (i+2<=count) { + jsval an_arg; + char *param_val; + char szParamVal[1024]; + JS_GetElement(c, list, (jsint) i, &an_arg); + char *param_name = JSVAL_IS_STRING(an_arg) ? JS_GetStringBytes(JSVAL_TO_STRING(an_arg)) : NULL; + + JS_GetElement(c, list, (jsint) i+1, &an_arg); + + param_val = ""; + if (JSVAL_IS_STRING(an_arg)) { + param_val = JS_GetStringBytes(JSVAL_TO_STRING(an_arg)); + } else if (JSVAL_IS_BOOLEAN(an_arg)) { + param_val = (char *) ((JSVAL_TO_BOOLEAN(an_arg) == JS_TRUE) ? "true" : "false"); + } + else if (JSVAL_IS_INT(argv[1])) { + sprintf(szParamVal, "%d", JSVAL_TO_INT(an_arg)); + param_val = szParamVal; + } + else if (JSVAL_IS_NUMBER(an_arg)) { + jsdouble v; + JS_ValueToNumber(c, an_arg, &v); + sprintf(szParamVal, "%g", v); + param_val = szParamVal; + } + + if (!param_name || !param_val) return JS_FALSE; + + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, (" %s(%s)", param_name, param_val)); + + if (device->act_ref->SetArgumentValue(param_name, param_val) != NPT_SUCCESS) + return JS_FALSE; + i+=2; + } + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, (" )\n")); + } + + //notify we are ready + if (device->m_pSema) { + gf_sema_notify(device->m_pSema, 1); + } + return JS_TRUE; +} +#endif + + +NPT_Result +GPAC_GenericDevice::OnAction(PLT_ActionReference& action, + const PLT_HttpRequestContext& context) +{ + NPT_COMPILER_UNUSED(context); + + gf_mx_p(m_pMutex); + PLT_ActionDesc &act_desc = action->GetActionDesc(); + NPT_String name = act_desc.GetName(); + assert(!m_pSema); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[UPnP] Action %s called (thread %d)\n", (char *) name, gf_th_id() )); + +#ifdef GPAC_HAS_SPIDERMONKEY + if (!act_proc) { + gf_mx_v(m_pMutex); + return NPT_SUCCESS; + } + + jsval argv[2]; + + m_pUPnP->LockJavascript(1); + + JSObject *js_action = JS_NewObject(m_pUPnP->m_pJSCtx, &m_pUPnP->upnpDeviceClass, 0, 0); + argv[0] = OBJECT_TO_JSVAL(js_action); + JS_SetPrivate(m_pUPnP->m_pJSCtx, js_action, this); + + act_ref = action; + + JS_DefineProperty(m_pUPnP->m_pJSCtx, js_action, "Name", STRING_TO_JSVAL( JS_NewStringCopyZ(m_pUPnP->m_pJSCtx, name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + GPAC_Service *service = (GPAC_Service *) act_desc.GetService(); + JS_DefineProperty(m_pUPnP->m_pJSCtx, js_action, "Service", service->m_pObj ? OBJECT_TO_JSVAL( service->m_pObj) : JSVAL_NULL, 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineFunction(m_pUPnP->m_pJSCtx, js_action, "GetArgument", upnp_action_get_argument, 1, 0); + JS_DefineFunction(m_pUPnP->m_pJSCtx, js_action, "SendReply", upnp_action_send_reply, 1, 0); + + /*create a semaphore*/ + m_pSema = gf_sema_new(1, 0); + + jsval rval; + JS_CallFunctionValue(m_pUPnP->m_pJSCtx, obj, act_proc, 1, argv, &rval); + JS_SetPrivate(m_pUPnP->m_pJSCtx, js_action, NULL); + m_pUPnP->LockJavascript(0); + + if (JSVAL_IS_INT(rval) && (JSVAL_TO_INT(rval) != 0)) { + action->SetError(JSVAL_TO_INT(rval), "Action Failed"); + } + /*wait on the semaphore*/ + if (!gf_sema_wait_for(m_pSema, 10000)) { + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("[UPnP] Reply processing to action %s timeout - sending incomplete reply)\n", (char *) name)); + } + gf_sema_del(m_pSema); + m_pSema = NULL; + + gf_mx_v(m_pMutex); +#endif + return NPT_SUCCESS; +} diff --git a/modules/platinum/GenericDevice.h b/modules/platinum/GenericDevice.h new file mode 100644 index 0000000..6df9974 --- /dev/null +++ b/modules/platinum/GenericDevice.h @@ -0,0 +1,203 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2009- Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / Platinum UPnP 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. + * + * + * ---------------------------------------------------------------------------------- + * PLATINUM IS LICENSED UNDER GPL or commercial agreement - cf platinum license + * ---------------------------------------------------------------------------------- + * + */ + + +#ifndef _GPAC_GENERIC_DEVICE_H_ +#define _GPAC_GENERIC_DEVICE_H_ + +#include "Neptune.h" +#include "PltCtrlPoint.h" +#include "PltDeviceHost.h" +#include "PltService.h" + +#include <gpac/thread.h> +#include <gpac/list.h> + +#ifdef GPAC_HAS_SPIDERMONKEY +#include <gpac/internal/scenegraph_dev.h> +#include <jsapi.h> +#endif + +class GF_UPnP; +class GPAC_ServiceItem; + +class GPAC_DeviceItem +{ +public: + GPAC_DeviceItem(PLT_DeviceDataReference device, NPT_String uuid); + ~GPAC_DeviceItem(); + + PLT_DeviceDataReference m_device; + NPT_String m_UUID; + GF_UPnP *m_pUPnP; + + GPAC_ServiceItem *FindService(const char *type); + + GF_List *m_Services; +#ifdef GPAC_HAS_SPIDERMONKEY + void DetachJS(); + JSObject *obj; + JSContext *js_ctx; +#endif +}; + +#ifdef GPAC_HAS_SPIDERMONKEY +class GPAC_StateVariableListener +{ +public: + GPAC_StateVariableListener() { + on_event = NULL; + name = ""; + var = NULL; + } + NPT_String name; + jsval on_event; + PLT_StateVariable *var; +}; + + +class GPAC_ActionArgListener +{ +public: + GPAC_ActionArgListener() { + on_event = NULL; + arg = NULL; + action = NULL; + } + jsval on_event; + PLT_ActionDesc *action; + PLT_ArgumentDesc *arg; + Bool is_script; +}; + +class GPAC_ActionUDTA +{ +public: + GPAC_ActionUDTA() { m_Reserved = NULL; udta = 0;} + /*members*/ + + /*this is used to differentiate browse request from JS (using BrowseDataReference) + as used in GPAC_MediaController and actionResponse used by the generic controller*/ + void *m_Reserved; + jsval udta; +}; + +#endif + + +class GPAC_ServiceItem +{ +public: + GPAC_ServiceItem(GPAC_DeviceItem *device, PLT_Service *service); + ~GPAC_ServiceItem(); + + + GPAC_DeviceItem *m_device; + PLT_Service *m_service; + + NPT_List<PLT_StateVariable*>*vars; + +#ifdef GPAC_HAS_SPIDERMONKEY + void DetachJS(); + JSObject *obj; + jsval on_event; + JSContext *js_ctx; + GF_List *m_StateListeners; + GF_List *m_ArgListeners; + Bool subscribed; +#endif + +}; + + +class GPAC_GenericController : public PLT_CtrlPointListener +{ +public: + GPAC_GenericController(PLT_CtrlPointReference& ctrlPoint, GF_UPnP *upnp); + ~GPAC_GenericController(); + + /*any device control point*/ + virtual NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device); + virtual NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device); + virtual NPT_Result OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata); + virtual NPT_Result OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars); + + GF_List *m_Devices; + GF_UPnP *m_pUPnP; + PLT_CtrlPointReference m_CtrlPoint; + GF_Mutex *m_ControlPointLock; +}; + + +class GPAC_GenericDevice : public PLT_DeviceHost +{ +public: + GPAC_GenericDevice(const char* FriendlyName, const char *device_id); + virtual ~GPAC_GenericDevice(); + +protected: + // PLT_DeviceHost methods + virtual NPT_Result SetupServices(PLT_DeviceData& data); + virtual NPT_Result OnAction(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); +public: + GF_UPnP *m_pUPnP; + GF_List *m_pServices; + +#ifdef GPAC_HAS_SPIDERMONKEY + void DetachJS(JSContext *c); + jsval run_proc; + jsval act_proc; + JSObject *obj; + NPT_String js_source; + PLT_ActionReference act_ref; + GF_Semaphore *m_pSema; + GF_Mutex *m_pMutex; +#endif +}; + +class GPAC_Service : public PLT_Service +{ +public: + GPAC_Service(PLT_DeviceData* device, const char* type = NULL, const char* id = NULL, const char* last_change_namespace = NULL); + ~GPAC_Service(); + +#ifdef GPAC_HAS_SPIDERMONKEY + void SetupJS(JSContext *c, GF_UPnP *upnp, JSObject *parent); + JSObject *m_pObj; + JSContext *m_pCtx; + jsval on_action; +#endif + +}; + + + +#endif //_GPAC_GENERIC_DEVICE_H_ diff --git a/modules/platinum/Makefile b/modules/platinum/Makefile new file mode 100644 index 0000000..8e02b60 --- /dev/null +++ b/modules/platinum/Makefile @@ -0,0 +1,70 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/platinum + +CFLAGS= $(CPPFLAGS) -I$(SRC_PATH)/include -ISDK/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +LINKLIBS= -lgpac -lPlatinum -lPltMediaServer -lPltMediaConnect -lPltMediaRenderer -lNeptune -lZlib +LOCAL_LIB=../../bin/gcc -LSDK/lib_gcc_x86 + +#common objects +OBJS=GPACFileMediaServer.o GPACMediaController.o GPACMediaRenderer.o GenericDevice.o GPACPlatinum.o + +ifeq ($(CONFIG_JS),no) +else +CFLAGS+= $(JS_FLAGS) +ifeq ($(CONFIG_JS),local) +NEED_LOCAL_LIB="yes" +LOCAL_LIB+=-L../../extra_lib/lib/gcc +endif +LINKLIBS+= $(JS_LIBS) +endif + +SRCS := $(OBJS:.o=.c) + +LIB=gm_platinum.$(DYN_LIB_SUFFIX) +ifeq ($(CONFIG_WIN32),yes) +#LDFLAGS+=-export-symbols platinum.def +endif + + +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) + +dep: depend + +depend: + rm -f .depend + $(CXX) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/platinum/SDK/ReadMe.txt b/modules/platinum/SDK/ReadMe.txt new file mode 100644 index 0000000..5316120 --- /dev/null +++ b/modules/platinum/SDK/ReadMe.txt @@ -0,0 +1,25 @@ +This directory contains a basic SDK for Platinum and Neptune libraries, version 0.5.4. + +Platinum has been slightly modified for GPAC usage: + support for PresentationURL in device description reading. + few workarounds for windowsCE compilation + +For most (99%) cases and most platforms, using the original platinum will work. + +The patched platinum library sources and binaries can be found here: + gpac.sourceforge.net/downloads/platinum_sdk_0.4.5.zip + + +include/ + Neptune and Platinum header files + +lib_arm/ + Neptune and Platinum libraries compiled for Smartphone ARM (MSVC8) + +lib_vc8/ + Neptune and Platinum libraries compiled for MS Windows (MSVC8) + +lib_gcc_x86/ + Neptune and Platinum libraries compiled for x86 linux (gcc) + + diff --git a/modules/platinum/SDK/include/Neptune.h b/modules/platinum/SDK/include/Neptune.h new file mode 100644 index 0000000..6c3c1f6 --- /dev/null +++ b/modules/platinum/SDK/include/Neptune.h @@ -0,0 +1,84 @@ +/***************************************************************** +| +| Neptune - Toplevel Include +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NEPTUNE_H_ +#define _NEPTUNE_H_ + +/*---------------------------------------------------------------------- +| flags ++---------------------------------------------------------------------*/ +#define NPT_EXTERNAL_USE /* do not expose internal definitions */ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConfig.h" +#include "NptCommon.h" +#include "NptResults.h" +#include "NptTypes.h" +#include "NptConstants.h" +#include "NptReferences.h" +#include "NptStreams.h" +#include "NptBufferedStreams.h" +#include "NptFile.h" +#include "NptNetwork.h" +#include "NptSockets.h" +#include "NptTime.h" +#include "NptThreads.h" +#include "NptSystem.h" +#include "NptMessaging.h" +#include "NptQueue.h" +#include "NptSimpleMessageQueue.h" +#include "NptSelectableMessageQueue.h" +#include "NptXml.h" +#include "NptStrings.h" +#include "NptArray.h" +#include "NptList.h" +#include "NptMap.h" +#include "NptStack.h" +#include "NptUri.h" +#include "NptHttp.h" +#include "NptDataBuffer.h" +#include "NptUtils.h" +#include "NptRingBuffer.h" +#include "NptBase64.h" +#include "NptConsole.h" +#include "NptLogging.h" +#include "NptSerialPort.h" +#include "NptVersion.h" +#include "NptDynamicLibraries.h" +#include "NptDynamicCast.h" + +// optional modules +#include "NptZip.h" +#include "NptTls.h" + +#endif // _NEPTUNE_H_ diff --git a/modules/platinum/SDK/include/NptArray.h b/modules/platinum/SDK/include/NptArray.h new file mode 100644 index 0000000..721bac8 --- /dev/null +++ b/modules/platinum/SDK/include/NptArray.h @@ -0,0 +1,522 @@ +/***************************************************************** +| +| Neptune - Arrays +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| +****************************************************************/ + +#ifndef _NPT_ARRAY_H_ +#define _NPT_ARRAY_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConfig.h" +#if defined(NPT_CONFIG_HAVE_NEW_H) +#include <new> +#endif +#include "NptTypes.h" +#include "NptResults.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int NPT_ARRAY_INITIAL_MAX_SIZE = 128; // bytes + +/*---------------------------------------------------------------------- +| NPT_Array ++---------------------------------------------------------------------*/ +template <typename T> +class NPT_Array +{ +public: + // types + typedef T Element; + typedef T* Iterator; + + // methods + NPT_Array<T>(): m_Capacity(0), m_ItemCount(0), m_Items(0) {} + explicit NPT_Array<T>(NPT_Cardinal count); + NPT_Array<T>(NPT_Cardinal count, const T& item); + NPT_Array<T>(const T* items, NPT_Cardinal item_count); + ~NPT_Array<T>(); + NPT_Array<T>(const NPT_Array<T>& copy); + NPT_Array<T>& operator=(const NPT_Array<T>& copy); + bool operator==(const NPT_Array<T>& other) const; + bool operator!=(const NPT_Array<T>& other) const; + NPT_Cardinal GetItemCount() const { return m_ItemCount; } + NPT_Result Add(const T& item); + T& operator[](NPT_Ordinal pos) { return m_Items[pos]; } + const T& operator[](NPT_Ordinal pos) const { return m_Items[pos]; } + NPT_Result Erase(Iterator which); + NPT_Result Erase(NPT_Ordinal which) { return Erase(&m_Items[which]); } + NPT_Result Erase(Iterator first, Iterator last); + NPT_Result Erase(NPT_Ordinal first, NPT_Ordinal last) { return Erase(&m_Items[first], &m_Items[last]); } + NPT_Result Insert(Iterator where, const T& item, NPT_Cardinal count = 1); + NPT_Result Reserve(NPT_Cardinal count); + NPT_Cardinal GetCapacity() const { return m_Capacity; } + NPT_Result Resize(NPT_Cardinal count); + NPT_Result Resize(NPT_Cardinal count, const T& fill); + NPT_Result Clear(); + bool Contains(const T& data) const; + Iterator GetFirstItem() const { return m_ItemCount?&m_Items[0]:NULL; } + Iterator GetLastItem() const { return m_ItemCount?&m_Items[m_ItemCount-1]:NULL; } + Iterator GetItem(NPT_Ordinal n) { return n<m_ItemCount?&m_Items[n]:NULL; } + + // template list operations + // keep these template members defined here because MSV6 does not let + // us define them later + template <typename X> + NPT_Result Apply(const X& function) const + { + for (unsigned int i=0; i<m_ItemCount; i++) function(m_Items[i]); + return NPT_SUCCESS; + } + + template <typename X, typename P> + NPT_Result ApplyUntil(const X& function, const P& predicate, bool* match = NULL) const + { + for (unsigned int i=0; i<m_ItemCount; i++) { + NPT_Result return_value; + if (predicate(function(m_Items[i]), return_value)) { + if (match) *match = true; + return return_value; + } + } + if (match) *match = false; + return NPT_SUCCESS; + } + + template <typename X> + T* Find(const X& predicate, NPT_Ordinal n=0, NPT_Ordinal* pos = NULL) const + { + if (pos) *pos = -1; + + for (unsigned int i=0; i<m_ItemCount; i++) { + if (predicate(m_Items[i])) { + if (pos) *pos = i; + if (n == 0) return &m_Items[i]; + --n; + } + } + return NULL; + } + +protected: + // methods + T* Allocate(NPT_Cardinal count, NPT_Cardinal& allocated); + + // members + NPT_Cardinal m_Capacity; + NPT_Cardinal m_ItemCount; + T* m_Items; +}; + +/*---------------------------------------------------------------------- +| NPT_Array<T>::NPT_Array<T> ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_Array<T>::NPT_Array(NPT_Cardinal count) : + m_Capacity(0), + m_ItemCount(0), + m_Items(0) +{ + Reserve(count); +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::NPT_Array<T> ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_Array<T>::NPT_Array(const NPT_Array<T>& copy) : + m_Capacity(0), + m_ItemCount(0), + m_Items(0) +{ + Reserve(copy.GetItemCount()); + for (NPT_Ordinal i=0; i<copy.m_ItemCount; i++) { + new ((void*)&m_Items[i]) T(copy.m_Items[i]); + } + m_ItemCount = copy.m_ItemCount; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::NPT_Array<T> ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_Array<T>::NPT_Array(NPT_Cardinal count, const T& item) : + m_Capacity(0), + m_ItemCount(count), + m_Items(0) +{ + Reserve(count); + for (NPT_Ordinal i=0; i<count; i++) { + new ((void*)&m_Items[i]) T(item); + } +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::NPT_Array<T> ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_Array<T>::NPT_Array(const T* items, NPT_Cardinal item_count) : + m_Capacity(0), + m_ItemCount(item_count), + m_Items(0) +{ + Reserve(item_count); + for (NPT_Ordinal i=0; i<item_count; i++) { + new ((void*)&m_Items[i]) T(items[i]); + } +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::~NPT_Array<T> ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_Array<T>::~NPT_Array() +{ + // remove all items + Clear(); + + // free the memory + ::operator delete((void*)m_Items); +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::operator= ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Array<T>& +NPT_Array<T>::operator=(const NPT_Array<T>& copy) +{ + // do nothing if we're assigning to ourselves + if (this == ©) return *this; + + // destroy all elements + Clear(); + + // copy all elements from the other object + Reserve(copy.GetItemCount()); + m_ItemCount = copy.m_ItemCount; + for (NPT_Ordinal i=0; i<copy.m_ItemCount; i++) { + new ((void*)&m_Items[i]) T(copy.m_Items[i]); + } + + return *this; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Clear ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_Array<T>::Clear() +{ + // destroy all items + for (NPT_Ordinal i=0; i<m_ItemCount; i++) { + m_Items[i].~T(); + } + + m_ItemCount = 0; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Allocate ++---------------------------------------------------------------------*/ +template <typename T> +T* +NPT_Array<T>::Allocate(NPT_Cardinal count, NPT_Cardinal& allocated) +{ + if (m_Capacity) { + allocated = 2*m_Capacity; + } else { + // start with just enough elements to fill + // NPT_ARRAY_INITIAL_MAX_SIZE worth of memory + allocated = NPT_ARRAY_INITIAL_MAX_SIZE/sizeof(T); + if (allocated == 0) allocated = 1; + } + if (allocated < count) allocated = count; + + // allocate the items + return (T*)::operator new(allocated*sizeof(T)); +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Reserve ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_Array<T>::Reserve(NPT_Cardinal count) +{ + if (count <= m_Capacity) return NPT_SUCCESS; + + // (re)allocate the items + NPT_Cardinal new_capacity; + T* new_items = Allocate(count, new_capacity); + if (new_items == NULL) { + return NPT_ERROR_OUT_OF_MEMORY; + } + if (m_ItemCount && m_Items) { + for (unsigned int i=0; i<m_ItemCount; i++) { + // construct the copy + new ((void*)&new_items[i])T(m_Items[i]); + + // destroy the item + m_Items[i].~T(); + } + } + ::operator delete((void*)m_Items); + m_Items = new_items; + m_Capacity = new_capacity; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Add ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_Result +NPT_Array<T>::Add(const T& item) +{ + // ensure capacity + NPT_Result result = Reserve(m_ItemCount+1); + if (result != NPT_SUCCESS) return result; + + // store the item + new ((void*)&m_Items[m_ItemCount++]) T(item); + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Erase ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_Result +NPT_Array<T>::Erase(Iterator which) +{ + return Erase(which, which); +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Erase ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_Array<T>::Erase(Iterator first, Iterator last) +{ + // check parameters + if (first == NULL || last == NULL) return NPT_ERROR_INVALID_PARAMETERS; + + // check the bounds + NPT_Ordinal first_index = (NPT_Ordinal)(NPT_POINTER_TO_LONG(first-m_Items)); + NPT_Ordinal last_index = (NPT_Ordinal)(NPT_POINTER_TO_LONG(last-m_Items)); + if (first_index >= m_ItemCount || + last_index >= m_ItemCount || + first_index > last_index) { + return NPT_ERROR_INVALID_PARAMETERS; + } + + // shift items to the left + NPT_Cardinal interval = last_index-first_index+1; + NPT_Cardinal shifted = m_ItemCount-last_index-1; + for (NPT_Ordinal i=first_index; i<first_index+shifted; i++) { + m_Items[i] = m_Items[i+interval]; + } + + // destruct the remaining items + for (NPT_Ordinal i=first_index+shifted; i<m_ItemCount; i++) { + m_Items[i].~T(); + } + + // update the item count + m_ItemCount -= interval; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Insert ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_Array<T>::Insert(Iterator where, const T& item, NPT_Cardinal repeat) +{ + // check bounds + NPT_Ordinal where_index = where?((NPT_Ordinal)NPT_POINTER_TO_LONG(where-m_Items)):m_ItemCount; + if (where > &m_Items[m_ItemCount] || repeat == 0) return NPT_ERROR_INVALID_PARAMETERS; + + NPT_Cardinal needed = m_ItemCount+repeat; + if (needed > m_Capacity) { + // allocate more memory + NPT_Cardinal new_capacity; + T* new_items = Allocate(needed, new_capacity); + if (new_items == NULL) return NPT_ERROR_OUT_OF_MEMORY; + m_Capacity = new_capacity; + + // move the items before the insertion point + for (NPT_Ordinal i=0; i<where_index; i++) { + new((void*)&new_items[i])T(m_Items[i]); + m_Items[i].~T(); + } + + // move the items after the insertion point + for (NPT_Ordinal i=where_index; i<m_ItemCount; i++) { + new((void*)&new_items[i+repeat])T(m_Items[i]); + m_Items[i].~T(); + } + + // use the new items instead of the current ones + ::operator delete((void*)m_Items); + m_Items = new_items; + } else { + // shift items after the insertion point to the right + for (NPT_Ordinal i=m_ItemCount; i>where_index; i--) { + new((void*)&m_Items[i+repeat-1])T(m_Items[i-1]); + m_Items[i-1].~T(); + } + } + + // insert the new items + for (NPT_Cardinal i=where_index; i<where_index+repeat; i++) { + new((void*)&m_Items[i])T(item); + } + + // update the item count + m_ItemCount += repeat; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Resize ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_Array<T>::Resize(NPT_Cardinal size) +{ + if (size < m_ItemCount) { + // shrink + for (NPT_Ordinal i=size; i<m_ItemCount; i++) { + m_Items[i].~T(); + } + m_ItemCount = size; + } else if (size > m_ItemCount) { + return Resize(size, T()); + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Resize ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_Array<T>::Resize(NPT_Cardinal size, const T& fill) +{ + if (size < m_ItemCount) { + return Resize(size); + } else if (size > m_ItemCount) { + Reserve(size); + for (NPT_Ordinal i=m_ItemCount; i<size; i++) { + new ((void*)&m_Items[i]) T(fill); + } + m_ItemCount = size; + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::Contains ++---------------------------------------------------------------------*/ +template <typename T> +bool +NPT_Array<T>::Contains(const T& data) const +{ + for (NPT_Ordinal i=0; i<m_ItemCount; i++) { + if (m_Items[i] == data) return true; + } + + return false; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::operator== ++---------------------------------------------------------------------*/ +template <typename T> +bool +NPT_Array<T>::operator==(const NPT_Array<T>& other) const +{ + // we need the same number of items + if (other.m_ItemCount != m_ItemCount) return false; + + // compare all items + for (NPT_Ordinal i=0; i<m_ItemCount; i++) { + if (!(m_Items[i] == other.m_Items[i])) return false; + } + + return true; +} + +/*---------------------------------------------------------------------- +| NPT_Array<T>::operator!= ++---------------------------------------------------------------------*/ +template <typename T> +inline +bool +NPT_Array<T>::operator!=(const NPT_Array<T>& other) const +{ + return !(*this == other); +} + +#endif // _NPT_ARRAY_H_ + + + + + + + + + + + + + diff --git a/modules/platinum/SDK/include/NptBase64.h b/modules/platinum/SDK/include/NptBase64.h new file mode 100644 index 0000000..89950de --- /dev/null +++ b/modules/platinum/SDK/include/NptBase64.h @@ -0,0 +1,68 @@ +/***************************************************************** +| +| Neptune - Base64 +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| +****************************************************************/ + +#ifndef _NPT_BASE64_H_ +#define _NPT_BASE64_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptDataBuffer.h" +#include "NptStrings.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const NPT_Cardinal NPT_BASE64_MIME_BLOCKS_PER_LINE = 19; +const NPT_Cardinal NPT_BASE64_PEM_BLOCKS_PER_LINE = 16; + +/*---------------------------------------------------------------------- +| NPT_Base64 ++---------------------------------------------------------------------*/ +class NPT_Base64 { +public: + // class methods + static NPT_Result Decode(const char* base64, + NPT_Size size, + NPT_DataBuffer& data, + bool url_safe = false); + static NPT_Result Encode(const NPT_Byte* data, + NPT_Size size, + NPT_String& base64, + NPT_Cardinal max_blocks_per_line = 0, + bool url_safe = false); + +private: + // this class is purely static + NPT_Base64(); +}; + +#endif // _NPT_BASE64_H_ diff --git a/modules/platinum/SDK/include/NptBufferedStreams.h b/modules/platinum/SDK/include/NptBufferedStreams.h new file mode 100644 index 0000000..a03f572 --- /dev/null +++ b/modules/platinum/SDK/include/NptBufferedStreams.h @@ -0,0 +1,101 @@ +/***************************************************************** +| +| Neptune - Buffered Byte Stream +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_BUFFERED_STREAMS_H_ +#define _NPT_BUFFERED_STREAMS_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptStreams.h" +#include "NptTypes.h" +#include "NptConstants.h" +#include "NptStrings.h" +#include "NptDebug.h" + +/*---------------------------------------------------------------------- +| NPT_BufferedStream ++---------------------------------------------------------------------*/ +const NPT_Size NPT_BUFFERED_BYTE_STREAM_DEFAULT_SIZE = 4096; + +/*---------------------------------------------------------------------- +| NPT_BufferedInputStream ++---------------------------------------------------------------------*/ +class NPT_BufferedInputStream : public NPT_InputStream +{ +public: + // constructors and destructor + NPT_BufferedInputStream(NPT_InputStreamReference& stream, + NPT_Size buffer_size = NPT_BUFFERED_BYTE_STREAM_DEFAULT_SIZE); + virtual ~NPT_BufferedInputStream(); + + // methods + virtual NPT_Result ReadLine(NPT_String& line, + NPT_Size max_chars = 4096, + bool break_on_cr = false); + virtual NPT_Result ReadLine(char* buffer, + NPT_Size buffer_size, + NPT_Size* chars_read = NULL, + bool break_on_cr = false); + virtual NPT_Result SetBufferSize(NPT_Size size, bool force = false); + virtual NPT_Result Peek(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read); + + // NPT_InputStream methods + NPT_Result Read(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read = NULL); + NPT_Result Seek(NPT_Position offset); + NPT_Result Tell(NPT_Position& offset); + NPT_Result GetSize(NPT_LargeSize& size); + NPT_Result GetAvailable(NPT_LargeSize& available); + +protected: + // members + NPT_InputStreamReference m_Source; + bool m_SkipNewline; + bool m_Eos; + struct { + NPT_Byte* data; + NPT_Size offset; + NPT_Size valid; + NPT_Size size; + } m_Buffer; + + // methods + virtual NPT_Result FillBuffer(); + virtual NPT_Result ReleaseBuffer(); +}; + +typedef NPT_Reference<NPT_BufferedInputStream> NPT_BufferedInputStreamReference; + +#endif // _NPT_BUFFERED_STREAMS_H_ diff --git a/modules/platinum/SDK/include/NptCommon.h b/modules/platinum/SDK/include/NptCommon.h new file mode 100644 index 0000000..4f6cb15 --- /dev/null +++ b/modules/platinum/SDK/include/NptCommon.h @@ -0,0 +1,169 @@ +/***************************************************************** +| +| Neptune - Common Definitions +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_COMMON_H_ +#define _NPT_COMMON_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptResults.h" + +/*---------------------------------------------------------------------- +| NPT_ObjectDeleter ++---------------------------------------------------------------------*/ +template <class T> +class NPT_ObjectDeleter { +public: + void operator()(T* object) const { + delete object; + } +}; + +/*---------------------------------------------------------------------- +| NPT_ObjectComparator ++---------------------------------------------------------------------*/ +template <class T> +class NPT_ObjectComparator { +public: + NPT_ObjectComparator(T& object) : m_Object(object) {} + bool operator()(const T& object) const { + return object == m_Object; + } +private: + T& m_Object; +}; + +/*---------------------------------------------------------------------- +| NPT_ContainerFind ++---------------------------------------------------------------------*/ +template <typename T, typename P> +NPT_Result NPT_ContainerFind(T& container, + const P& predicate, + typename T::Element& item, + NPT_Ordinal n=0) +{ + typename T::Iterator found = container.Find(predicate, n); + if (found) { + item = *found; + return NPT_SUCCESS; + } else { + return NPT_ERROR_NO_SUCH_ITEM; + } +} + +/*---------------------------------------------------------------------- +| NPT_ContainerFind ++---------------------------------------------------------------------*/ +template <typename T, typename P> +NPT_Result NPT_ContainerFind(T& container, + const P& predicate, + typename T::Iterator& iter, + NPT_Ordinal n=0) +{ + iter = container.Find(predicate, n); + return iter?NPT_SUCCESS:NPT_ERROR_NO_SUCH_ITEM; +} + +/*---------------------------------------------------------------------- +| NPT_UntilResultEquals ++---------------------------------------------------------------------*/ +class NPT_UntilResultEquals +{ +public: + // methods + NPT_UntilResultEquals(NPT_Result condition_result, + NPT_Result return_value = NPT_SUCCESS) : + m_ConditionResult(condition_result), + m_ReturnValue(return_value) {} + bool operator()(NPT_Result result, NPT_Result& return_value) const { + if (result == m_ConditionResult) { + return_value = m_ReturnValue; + return true; + } else { + return false; + } + } + +private: + // members + NPT_Result m_ConditionResult; + NPT_Result m_ReturnValue; +}; + +/*---------------------------------------------------------------------- +| NPT_UntilResultNotEquals ++---------------------------------------------------------------------*/ +class NPT_UntilResultNotEquals +{ +public: + // methods + NPT_UntilResultNotEquals(NPT_Result condition_result) : + m_ConditionResult(condition_result) {} + bool operator()(NPT_Result result, NPT_Result& return_value) const { + if (result != m_ConditionResult) { + return_value = result; + return true; + } else { + return false; + } + } + +private: + // members + NPT_Result m_ConditionResult; +}; + +/*---------------------------------------------------------------------- +| NPT_PropertyValue ++---------------------------------------------------------------------*/ +class NPT_PropertyValue +{ + public: + // typedefs + typedef enum {UNKNOWN, INTEGER, STRING} Type; + + // methods + NPT_PropertyValue() : m_Type(UNKNOWN), m_Integer(0) {} + NPT_PropertyValue(int value) : m_Type(INTEGER), m_Integer(value) {} + NPT_PropertyValue(const char* value) : m_Type(STRING), m_String(value) {} + + // members + Type m_Type; + union { + int m_Integer; + const char* m_String; + }; +}; + +#endif // _NPT_COMMON_H_ + diff --git a/modules/platinum/SDK/include/NptConfig.h b/modules/platinum/SDK/include/NptConfig.h new file mode 100644 index 0000000..897d8d8 --- /dev/null +++ b/modules/platinum/SDK/include/NptConfig.h @@ -0,0 +1,306 @@ +/***************************************************************** +| +| Neptune - Configuration +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_CONFIG_H_ +#define _NPT_CONFIG_H_ + +/*---------------------------------------------------------------------- +| defaults ++---------------------------------------------------------------------*/ +#define NPT_CONFIG_HAVE_ASSERT_H +#define NPT_CONFIG_HAVE_STD_C +#define NPT_CONFIG_HAVE_STDLIB_H +#define NPT_CONFIG_HAVE_STDIO_H +#define NPT_CONFIG_HAVE_STDARG_H +#define NPT_CONFIG_HAVE_STRING_H +#define NPT_CONFIG_HAVE_LIMITS_H + +/*---------------------------------------------------------------------- +| standard C runtime ++---------------------------------------------------------------------*/ +#if defined(NPT_CONFIG_HAVE_STD_C) +#define NPT_CONFIG_HAVE_MALLOC +#define NPT_CONFIG_HAVE_CALLOC +#define NPT_CONFIG_HAVE_REALLOC +#define NPT_CONFIG_HAVE_FREE +#define NPT_CONFIG_HAVE_MEMCPY +#define NPT_CONFIG_HAVE_MEMSET +#define NPT_CONFIG_HAVE_MEMCMP +#define NPT_CONFIG_HAVE_GETENV +#define NPT_CONFIG_HAVE_READDIR_R +#endif /* NPT_CONFIG_HAS_STD_C */ + +#if defined(NPT_CONFIG_HAVE_STRING_H) +#define NPT_CONFIG_HAVE_STRCMP +#define NPT_CONFIG_HAVE_STRNCMP +#define NPT_CONFIG_HAVE_STRDUP +#define NPT_CONFIG_HAVE_STRLEN +#define NPT_CONFIG_HAVE_STRCPY +#define NPT_CONFIG_HAVE_STRNCPY +#endif /* NPT_CONFIG_HAVE_STRING_H */ + +#if defined(NPT_CONFIG_HAVE_STDIO_H) +#define NPT_CONFIG_HAVE_SPRINTF +#define NPT_CONFIG_HAVE_SNPRINTF +#define NPT_CONFIG_HAVE_VSPRINTF +#define NPT_CONFIG_HAVE_VSNPRINTF +#endif /* NPT_CONFIG_HAVE_STDIO_H */ + +#if defined(NPT_CONFIG_HAVE_LIMITS_H) +#define NPT_CONFIG_HAVE_INT_MIN +#define NPT_CONFIG_HAVE_INT_MAX +#define NPT_CONFIG_HAVE_UINT_MAX +#define NPT_CONFIG_HAVE_LONG_MIN +#define NPT_CONFIG_HAVE_LONG_MAX +#define NPT_CONFIG_HAVE_ULONG_MAX +#endif + +/*---------------------------------------------------------------------- +| standard C++ runtime ++---------------------------------------------------------------------*/ +#define NPT_CONFIG_HAVE_NEW_H + +/*---------------------------------------------------------------------- +| sockets ++---------------------------------------------------------------------*/ +#define NPT_CONFIG_HAVE_SOCKADDR_SA_LEN + +/*---------------------------------------------------------------------- +| platform specifics ++---------------------------------------------------------------------*/ +/* Windows 32 */ +#if defined(_WIN32) || defined(_XBOX) +#if !defined(STRICT) +#define STRICT +#endif +#endif + +/* XBox */ +#if defined(_XBOX) +#define NPT_CONFIG_THREAD_STACK_SIZE 0x10000 +#endif + +/* QNX */ +#if defined(__QNX__) +#endif + +/* cygwin */ +#if defined(__CYGWIN__) +#undef NPT_CONFIG_HAVE_SOCKADDR_SA_LEN +#endif + +/* linux */ +#if defined(__linux__) +#undef NPT_CONFIG_HAVE_SOCKADDR_SA_LEN +#endif + +/* symbian */ +#if defined(__SYMBIAN32__) +/* If defined, specify the stack size of each NPT_Thread. */ +#define NPT_CONFIG_THREAD_STACK_SIZE 0x14000 +#endif + +/*---------------------------------------------------------------------- +| compiler specifics ++---------------------------------------------------------------------*/ +/* GCC */ +#if defined(__GNUC__) +#define NPT_LocalFunctionName __FUNCTION__ +#define NPT_COMPILER_UNUSED(p) (void)p +#else +#define NPT_COMPILER_UNUSED(p) +#endif + +/* TriMedia C/C++ Compiler */ +#if defined(__TCS__) +#undef NPT_CONFIG_HAVE_ASSERT_H +#undef NPT_CONFIG_HAVE_SNPRINTF +#undef NPT_CONFIG_HAVE_VSNPRINTF +#endif + +/* palmos compiler */ +#if defined(__PALMOS__) +#if __PALMOS__ <= 0x05000000 +#undef NPT_CONFIG_HAVE_ASSERT_H +#undef NPT_CONFIG_HAVE_SNPRINTF +#undef NPT_CONFIG_HAVE_VSNPRINTF +#endif +#endif + +/* Microsoft C/C++ Compiler */ +#if defined(_MSC_VER) +#define NPT_FORMAT_64 "I64" +#define NPT_CONFIG_INT64_TYPE __int64 +#define NPT_INT64_MIN _I64_MIN +#define NPT_INT64_MAX _I64_MAX +#define NPT_UINT64_MAX _UI64_MAX +#define NPT_INT64_C(_x) _x##i64 +#define NPT_UINT64_C(_x) _x##ui64 +#define NPT_LocalFunctionName __FUNCTION__ +#if !defined(_WIN32_WCE) +#define NPT_fseek _fseeki64 +#define NPT_ftell _ftelli64 +#else +#define NPT_fseek(a,b,c) fseek((a),(long)(b), (c)) +#define NPT_ftell ftell +#endif +#define NPT_stat NPT_stat_utf8 +#define NPT_stat_struct struct __stat64 +#if defined(_WIN64) +typedef __int64 NPT_PointerLong; +#else +#if _MSC_VER >= 1400 +typedef __w64 long NPT_PointerLong; +#else +typedef long NPT_PointerLong; +#endif +#endif +#define NPT_POINTER_TO_LONG(_p) ((NPT_PointerLong) (_p) ) +#if _MSC_VER >= 1400 && !defined(_WIN32_WCE) +#define NPT_CONFIG_HAVE_GMTIME_S +#define NPT_CONFIG_HAVE_LOCALTIME_S +#define NPT_CONFIG_HAVE_FOPEN_S +#define NPT_CONFIG_HAVE_FSOPEN +#define NPT_CONFIG_HAVE_SHARE_H +#define NPT_vsnprintf(s,c,f,a) _vsnprintf_s(s,c,_TRUNCATE,f,a) +#define NPT_snprintf(s,c,f,...) _snprintf_s(s,c,_TRUNCATE,f,__VA_ARGS__) +#define NPT_strncpy(d,s,c) strncpy_s(d,c+1,s,c) +#define NPT_strcpy(d,s) strcpy_s(d,strlen(s)+1,s) +#undef NPT_CONFIG_HAVE_GETENV +#define NPT_CONFIG_HAVE_DUPENV_S +#define dupenv_s _dupenv_s +#else +#define NPT_vsnprintf _vsnprintf +#define NPT_snprintf _snprintf +#endif +#if defined(_DEBUG) +#define _CRTDBG_MAP_ALLOC +#endif +#endif + +/* Windows CE */ +#if defined(_WIN32_WCE) +#if defined(NPT_CONFIG_HAVE_FOPEN_S) +#undef NPT_CONFIG_HAVE_FOPEN_S +#endif +#if defined(NPT_CONFIG_HAVE_GMTIME_S) +#undef NPT_CONFIG_HAVE_GMTIME_S +#endif +#if defined(NPT_CONFIG_HAVE_LOCALTIME_S) +#undef NPT_CONFIG_HAVE_LOCALTIME_S +#endif +#endif + +/* Symbian */ +#if defined(__SYMBIAN32__) +#undef NPT_CONFIG_HAVE_NEW_H +#include "e32std.h" +#define explicit +#define NPT_fseek fseek // no fseeko ? +#define NPT_ftell ftell // no ftello ? +#endif + +/* Android */ +#if defined(ANDROID) +#define NPT_CONFIG_NO_RTTI +#endif + +/*---------------------------------------------------------------------- +| defaults ++---------------------------------------------------------------------*/ +#if !defined(NPT_FORMAT_64) +#define NPT_FORMAT_64 "ll" +#endif + +#if !defined(NPT_POINTER_TO_LONG) +#define NPT_POINTER_TO_LONG(_p) ((long)(_p)) +#endif + +#if !defined(NPT_CONFIG_INT64_TYPE) +#define NPT_CONFIG_INT64_TYPE long long +#endif + +#if !defined(NPT_INT64_C) +#define NPT_INT64_C(_x) _x##LL +#endif + +#if !defined(NPT_UINT64_C) +#define NPT_UINT64_C(_x) _x##ULL +#endif + +#if !defined(NPT_snprintf) +#define NPT_snprintf snprintf +#endif + +#if !defined(NPT_strcpy) +#define NPT_strcpy strcpy +#endif + +#if !defined(NPT_strncpy) +#define NPT_strncpy strncpy +#endif + +#if !defined(NPT_vsnprintf) +#define NPT_vsnprintf vsnprintf +#endif + +#if !defined(NPT_LocalFunctionName) +#define NPT_LocalFunctionName (NULL) +#endif + +#if !defined(NPT_CONFIG_THREAD_STACK_SIZE) +#define NPT_CONFIG_THREAD_STACK_SIZE 0 +#endif + +#if !defined(NPT_fseek) +#define NPT_fseek fseeko +#endif + +#if !defined(NPT_ftell) +#define NPT_ftell ftello +#endif + +#if !defined(NPT_stat) +#define NPT_stat stat +#endif + +#if !defined(NPT_stat_struct) +#define NPT_stat_struct struct stat +#endif + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#if defined(DMALLOC) +#include <dmalloc.h> +#endif + +#endif // _NPT_CONFIG_H_ diff --git a/modules/platinum/SDK/include/NptConsole.h b/modules/platinum/SDK/include/NptConsole.h new file mode 100644 index 0000000..6502a79 --- /dev/null +++ b/modules/platinum/SDK/include/NptConsole.h @@ -0,0 +1,55 @@ +/***************************************************************** +| +| Neptune - Console +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| +****************************************************************/ +/** @file +* Header file for console support +*/ + +#ifndef _NPT_CONSOLE_H_ +#define _NPT_CONSOLE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptResults.h" + +/*---------------------------------------------------------------------- +| prototypes ++---------------------------------------------------------------------*/ +class NPT_Console { +public: + // class methods + static void Output(const char* message); + static void OutputF(const char* format, ...); +}; + + +#endif /* _NPT_CONSOLE_H_ */ diff --git a/modules/platinum/SDK/include/NptConstants.h b/modules/platinum/SDK/include/NptConstants.h new file mode 100644 index 0000000..6618bf8 --- /dev/null +++ b/modules/platinum/SDK/include/NptConstants.h @@ -0,0 +1,44 @@ +/***************************************************************** +| +| Neptune - Constants +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_CONSTANTS_H_ +#define _NPT_CONSTANTS_H_ + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#ifndef NULL +#define NULL 0 +#endif + +const int NPT_TIMEOUT_INFINITE = -1; + +#endif // _NPT_CONSTANTS_H_ diff --git a/modules/platinum/SDK/include/NptDataBuffer.h b/modules/platinum/SDK/include/NptDataBuffer.h new file mode 100644 index 0000000..7e57c01 --- /dev/null +++ b/modules/platinum/SDK/include/NptDataBuffer.h @@ -0,0 +1,83 @@ +/***************************************************************** +| +| Neptune - Datagram Packets +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_DATA_BUFFER_H_ +#define _NPT_DATA_BUFFER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptConstants.h" + +/*---------------------------------------------------------------------- +| NPT_DataBuffer ++---------------------------------------------------------------------*/ +class NPT_DataBuffer +{ + public: + // constructors & destructor + NPT_DataBuffer(); // size unknown until first set + NPT_DataBuffer(NPT_Size size); // initial size specified + NPT_DataBuffer(const void* data, NPT_Size size, bool copy = true); // initial data and size specified + NPT_DataBuffer(const NPT_DataBuffer& other); + virtual ~NPT_DataBuffer(); + + // operators + NPT_DataBuffer& operator=(const NPT_DataBuffer& copy); + bool operator==(const NPT_DataBuffer& other) const; + + // data buffer handling methods + virtual NPT_Result SetBuffer(NPT_Byte* buffer, NPT_Size bufferSize); + virtual NPT_Result SetBufferSize(NPT_Size bufferSize); + virtual NPT_Size GetBufferSize() const { return m_BufferSize; } + virtual NPT_Result Reserve(NPT_Size size); + virtual NPT_Result Clear(); + + // data handling methods + virtual const NPT_Byte* GetData() const { return m_Buffer; } + virtual NPT_Byte* UseData() { return m_Buffer; }; + virtual NPT_Size GetDataSize() const { return m_DataSize; } + virtual NPT_Result SetDataSize(NPT_Size size); + virtual NPT_Result SetData(const NPT_Byte* data, NPT_Size dataSize); + + protected: + // members + bool m_BufferIsLocal; + NPT_Byte* m_Buffer; + NPT_Size m_BufferSize; + NPT_Size m_DataSize; + + // methods + NPT_Result ReallocateBuffer(NPT_Size size); +}; + +#endif // _NPT_DATA_BUFFER_H_ diff --git a/modules/platinum/SDK/include/NptDebug.h b/modules/platinum/SDK/include/NptDebug.h new file mode 100644 index 0000000..d4973a2 --- /dev/null +++ b/modules/platinum/SDK/include/NptDebug.h @@ -0,0 +1,56 @@ +/***************************************************************** +| +| Neptune - Debug Utilities +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_DEBUG_H_ +#define _NPT_DEBUG_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConfig.h" + +/*---------------------------------------------------------------------- +| standard macros ++---------------------------------------------------------------------*/ +#if defined(NPT_CONFIG_HAVE_ASSERT_H) && defined(NPT_DEBUG) +#include <assert.h> +#define NPT_ASSERT(x) assert(x) +#else +#define NPT_ASSERT(x) ((void)0) +#endif + +/*---------------------------------------------------------------------- +| NPT_Debug ++---------------------------------------------------------------------*/ +extern void NPT_Debug(const char* format, ...); +extern void NPT_DebugOutput(const char* message); + +#endif // _NPT_DEBUG_H_ diff --git a/extra_lib/lib/arm_ppc02_deb/dummy b/modules/platinum/SDK/include/NptDefs.h similarity index 100% rename from extra_lib/lib/arm_ppc02_deb/dummy rename to modules/platinum/SDK/include/NptDefs.h diff --git a/modules/platinum/SDK/include/NptDynamicCast.h b/modules/platinum/SDK/include/NptDynamicCast.h new file mode 100644 index 0000000..0acab88 --- /dev/null +++ b/modules/platinum/SDK/include/NptDynamicCast.h @@ -0,0 +1,89 @@ +/***************************************************************** +| +| Neptune - Dynamic Cast Support +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_DYNAMIC_CAST_H_ +#define _NPT_DYNAMIC_CAST_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptCommon.h" +#include "NptResults.h" +#include "NptConfig.h" + +/*---------------------------------------------------------------------- +| macros ++---------------------------------------------------------------------*/ +#if defined(NPT_CONFIG_NO_RTTI) +#define NPT_DYNAMIC_CAST(_class,_object) \ +( ((_object)==0) ? 0 : reinterpret_cast<_class*>((_object)->DynamicCast(&_class::_class_##_class)) ) +#define NPT_IMPLEMENT_DYNAMIC_CAST(_class) \ +static int _class_##_class; \ +virtual void* DynamicCast(const void* class_anchor) { \ + if (class_anchor == &_class::_class_##_class) { \ + return static_cast<_class*>(this); \ + } \ + return NULL; \ +} +#define NPT_IMPLEMENT_DYNAMIC_CAST_D(_class,_superclass)\ +static int _class_##_class; \ +virtual void* DynamicCast(const void* class_anchor) { \ + if (class_anchor == &_class::_class_##_class) { \ + return static_cast<_class*>(this); \ + } else { \ + return _superclass::DynamicCast(class_anchor); \ + } \ +} +#define NPT_IMPLEMENT_DYNAMIC_CAST_D2(_class,_superclass,_mixin)\ +static int _class_##_class; \ +virtual void* DynamicCast(const void* class_anchor) { \ + if (class_anchor == &_class::_class_##_class) { \ + return static_cast<_class*>(this); \ + } else { \ + void* sup = _superclass::DynamicCast(class_anchor); \ + if (sup) return sup; \ + return _mixin::DynamicCast(class_anchor); \ + } \ +} +#define NPT_DEFINE_DYNAMIC_CAST_ANCHOR(_class) int _class::_class_##_class = 0; + +#else + +#define NPT_DYNAMIC_CAST(_class,_object) dynamic_cast<_class*>(_object) +#define NPT_IMPLEMENT_DYNAMIC_CAST(_class) +#define NPT_IMPLEMENT_DYNAMIC_CAST_D(_class,_superclass) +#define NPT_IMPLEMENT_DYNAMIC_CAST_D2(_class,_superclass,_mixin) +#define NPT_DEFINE_DYNAMIC_CAST_ANCHOR(_class) + +#endif + +#endif // _NPT_DYNAMIC_CAST_H_ diff --git a/modules/platinum/SDK/include/NptDynamicLibraries.h b/modules/platinum/SDK/include/NptDynamicLibraries.h new file mode 100644 index 0000000..4a2751e --- /dev/null +++ b/modules/platinum/SDK/include/NptDynamicLibraries.h @@ -0,0 +1,84 @@ +/***************************************************************** +| +| Neptune - Dynamic Libraries +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_DYNAMIC_LIBRARIES_H_ +#define _NPT_DYNAMIC_LIBRARIES_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#define NPT_DYANMIC_LIBRARY_LOAD_FLAG_NOW 1 + +/*---------------------------------------------------------------------- +| NPT_DynamicLibraryInterface ++---------------------------------------------------------------------*/ +class NPT_DynamicLibraryInterface +{ +public: + virtual ~NPT_DynamicLibraryInterface() {} + virtual NPT_Result FindSymbol(const char* name, void*& symbol) = 0; + virtual NPT_Result Unload() = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_DynamicLibrary ++---------------------------------------------------------------------*/ +class NPT_DynamicLibrary : public NPT_DynamicLibraryInterface +{ +public: + // class methods + static NPT_Result Load(const char* name, NPT_Flags flags, NPT_DynamicLibrary*& library); + + // destructor + ~NPT_DynamicLibrary() { delete m_Delegate; } + + // NPT_DynamicLibraryInterface methods + virtual NPT_Result FindSymbol(const char* name, void*& symbol) { + return m_Delegate->FindSymbol(name, symbol); + } + virtual NPT_Result Unload() { + return m_Delegate->Unload(); + } + +private: + // methods + NPT_DynamicLibrary(NPT_DynamicLibraryInterface* delegate) : m_Delegate(delegate) {} + + // members + NPT_DynamicLibraryInterface* m_Delegate; +}; + +#endif // _NPT_DYNAMIC_LIBRARIES_H_ diff --git a/modules/platinum/SDK/include/NptFile.h b/modules/platinum/SDK/include/NptFile.h new file mode 100644 index 0000000..a33ae5f --- /dev/null +++ b/modules/platinum/SDK/include/NptFile.h @@ -0,0 +1,203 @@ +/***************************************************************** +| +| Neptune - Files +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_FILE_H_ +#define _NPT_FILE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptStreams.h" +#include "NptTime.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int NPT_ERROR_NO_SUCH_FILE = NPT_ERROR_BASE_FILE - 0; +const int NPT_ERROR_FILE_NOT_OPEN = NPT_ERROR_BASE_FILE - 1; +const int NPT_ERROR_FILE_BUSY = NPT_ERROR_BASE_FILE - 2; +const int NPT_ERROR_FILE_ALREADY_OPEN = NPT_ERROR_BASE_FILE - 3; +const int NPT_ERROR_FILE_NOT_READABLE = NPT_ERROR_BASE_FILE - 4; +const int NPT_ERROR_FILE_NOT_WRITABLE = NPT_ERROR_BASE_FILE - 5; +const int NPT_ERROR_FILE_NOT_DIRECTORY = NPT_ERROR_BASE_FILE - 6; +const int NPT_ERROR_FILE_ALREADY_EXISTS = NPT_ERROR_BASE_FILE - 7; +const int NPT_ERROR_FILE_NOT_ENOUGH_SPACE = NPT_ERROR_BASE_FILE - 8; +const int NPT_ERROR_DIRECTORY_NOT_EMPTY = NPT_ERROR_BASE_FILE - 9; + +const unsigned int NPT_FILE_OPEN_MODE_READ = 0x01; +const unsigned int NPT_FILE_OPEN_MODE_WRITE = 0x02; +const unsigned int NPT_FILE_OPEN_MODE_CREATE = 0x04; +const unsigned int NPT_FILE_OPEN_MODE_TRUNCATE = 0x08; +const unsigned int NPT_FILE_OPEN_MODE_UNBUFFERED = 0x10; +const unsigned int NPT_FILE_OPEN_MODE_APPEND = 0x20; + +const unsigned int NPT_FILE_ATTRIBUTE_READ_ONLY = 0x01; +const unsigned int NPT_FILE_ATTRIBUTE_LINK = 0x02; + +#define NPT_FILE_STANDARD_INPUT "@STDIN" +#define NPT_FILE_STANDARD_OUTPUT "@STDOUT" +#define NPT_FILE_STANDARD_ERROR "@STDERR" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class NPT_DataBuffer; + +/*---------------------------------------------------------------------- +| NPT_FileInfo ++---------------------------------------------------------------------*/ +struct NPT_FileInfo +{ + // types + typedef enum { + FILE_TYPE_NONE, + FILE_TYPE_REGULAR, + FILE_TYPE_DIRECTORY, + FILE_TYPE_SPECIAL, + FILE_TYPE_OTHER + } FileType; + + // constructor + NPT_FileInfo() : m_Type(FILE_TYPE_NONE), m_Size(0), m_AttributesMask(0), m_Attributes(0) {} + + // members + FileType m_Type; + NPT_UInt64 m_Size; + NPT_Flags m_AttributesMask; + NPT_Flags m_Attributes; + NPT_TimeStamp m_Created; + NPT_TimeStamp m_Modified; +}; + +/*---------------------------------------------------------------------- +| NPT_FilePath ++---------------------------------------------------------------------*/ +class NPT_FilePath +{ +public: + // class members + static const NPT_String Separator; + + // class methods + static NPT_String BaseName(const char* path, bool with_extension = true); + static NPT_String DirName(const char* path); + static NPT_String FileExtension(const char* path); + static NPT_String Create(const char* directory, const char* base); + +private: + NPT_FilePath() {} // this class can't have instances +}; + +/*---------------------------------------------------------------------- +| NPT_FileInterface ++---------------------------------------------------------------------*/ +class NPT_FileInterface +{ +public: + // types + typedef unsigned int OpenMode; + + // constructors and destructor + virtual ~NPT_FileInterface() {} + + // methods + virtual NPT_Result Open(OpenMode mode) = 0; + virtual NPT_Result Close() = 0; + virtual NPT_Result GetInputStream(NPT_InputStreamReference& stream) = 0; + virtual NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_File ++---------------------------------------------------------------------*/ +class NPT_File : public NPT_FileInterface +{ +public: + // class methods + static NPT_Result GetRoots(NPT_List<NPT_String>& roots); + static NPT_Result GetSize(const char* path, NPT_LargeSize &size); + static NPT_Result GetInfo(const char* path, NPT_FileInfo* info = NULL); + static NPT_Result GetCount(const char* path, NPT_Cardinal& count); + static bool Exists(const char* path) { return NPT_SUCCEEDED(GetInfo(path)); } + static NPT_Result Remove(const char* path, bool recursively = false); + static NPT_Result RemoveFile(const char* path); + static NPT_Result RemoveDir(const char* path); + static NPT_Result RemoveDir(const char* path, bool recursively); + static NPT_Result Rename(const char* from_path, const char* to_path); + static NPT_Result ListDir(const char* path, NPT_List<NPT_String>& entries, NPT_Ordinal start = 0, NPT_Cardinal count = 0); + static NPT_Result CreateDir(const char* path); + static NPT_Result CreateDir(const char* path, bool recursively); + static NPT_Result GetWorkingDir(NPT_String& path); + static NPT_Result Load(const char* path, NPT_DataBuffer& buffer, NPT_FileInterface::OpenMode mode = NPT_FILE_OPEN_MODE_READ); + static NPT_Result Load(const char* path, NPT_String& data, NPT_FileInterface::OpenMode mode = NPT_FILE_OPEN_MODE_READ); + static NPT_Result Save(const char* path, NPT_String& data); + static NPT_Result Save(const char* path, const NPT_DataBuffer& buffer); + + // constructors and destructor + NPT_File(const char* path); + ~NPT_File() { delete m_Delegate; } + + // methods + NPT_Result Load(NPT_DataBuffer& buffer); + NPT_Result Save(const NPT_DataBuffer& buffer); + const NPT_String& GetPath() { return m_Path; } + NPT_Result GetSize(NPT_LargeSize &size); + NPT_Result GetInfo(NPT_FileInfo& info); + NPT_Result ListDir(NPT_List<NPT_String>& entries); + NPT_Result Rename(const char* path); + NPT_Result GetCount(NPT_Cardinal& count); + + // NPT_FileInterface methods + NPT_Result Open(OpenMode mode) { + return m_Delegate->Open(mode); + } + NPT_Result Close() { + return m_Delegate->Close(); + } + NPT_Result GetInputStream(NPT_InputStreamReference& stream) { + return m_Delegate->GetInputStream(stream); + } + NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) { + return m_Delegate->GetOutputStream(stream); + } + + // operators + NPT_File& operator=(const NPT_File& file); + +protected: + // members + NPT_FileInterface* m_Delegate; + NPT_String m_Path; + bool m_IsSpecial; +}; + +#endif // _NPT_FILE_H_ diff --git a/modules/platinum/SDK/include/NptHttp.h b/modules/platinum/SDK/include/NptHttp.h new file mode 100644 index 0000000..d7c7c91 --- /dev/null +++ b/modules/platinum/SDK/include/NptHttp.h @@ -0,0 +1,698 @@ +/***************************************************************** +| +| Neptune - HTTP Protocol +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_HTTP_H_ +#define _NPT_HTTP_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptUri.h" +#include "NptTypes.h" +#include "NptList.h" +#include "NptBufferedStreams.h" +#include "NptSockets.h" +#include "NptMap.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const unsigned int NPT_HTTP_DEFAULT_PORT = 80; +const unsigned int NPT_HTTP_INVALID_PORT = 0; + +const NPT_Timeout NPT_HTTP_CLIENT_DEFAULT_CONNECTION_TIMEOUT = 30000; +const NPT_Timeout NPT_HTTP_CLIENT_DEFAULT_IO_TIMEOUT = 30000; +const NPT_Timeout NPT_HTTP_CLIENT_DEFAULT_NAME_RESOLVER_TIMEOUT = 60000; + +const NPT_Timeout NPT_HTTP_SERVER_DEFAULT_CONNECTION_TIMEOUT = NPT_TIMEOUT_INFINITE; +const NPT_Timeout NPT_HTTP_SERVER_DEFAULT_IO_TIMEOUT = 60000; + +const int NPT_HTTP_PROTOCOL_MAX_LINE_LENGTH = 8192; +const int NPT_HTTP_PROTOCOL_MAX_HEADER_COUNT = 100; + +#define NPT_HTTP_PROTOCOL_1_0 "HTTP/1.0" +#define NPT_HTTP_PROTOCOL_1_1 "HTTP/1.1" +#define NPT_HTTP_METHOD_GET "GET" +#define NPT_HTTP_METHOD_HEAD "HEAD" +#define NPT_HTTP_METHOD_POST "POST" + +#define NPT_HTTP_HEADER_HOST "Host" +#define NPT_HTTP_HEADER_CONNECTION "Connection" +#define NPT_HTTP_HEADER_USER_AGENT "User-Agent" +#define NPT_HTTP_HEADER_SERVER "Server" +#define NPT_HTTP_HEADER_CONTENT_LENGTH "Content-Length" +#define NPT_HTTP_HEADER_CONTENT_TYPE "Content-Type" +#define NPT_HTTP_HEADER_CONTENT_ENCODING "Content-Encoding" +#define NPT_HTTP_HEADER_TRANSFER_ENCODING "Transfer-Encoding" +#define NPT_HTTP_HEADER_LOCATION "Location" +#define NPT_HTTP_HEADER_RANGE "Range" +#define NPT_HTTP_HEADER_CONTENT_RANGE "Content-Range" +#define NPT_HTTP_HEADER_COOKIE "Cookie" +#define NPT_HTTP_HEADER_ACCEPT_RANGES "Accept-Ranges" +#define NPT_HTTP_HEADER_CONTENT_RANGE "Content-Range" + +#define NPT_HTTP_TRANSFER_ENCODING_CHUNKED "chunked" + +#define NPT_HTTP_HEADER_AUTHORIZATION "Authorization" + +const int NPT_ERROR_HTTP_INVALID_RESPONSE_LINE = NPT_ERROR_BASE_HTTP - 0; +const int NPT_ERROR_HTTP_INVALID_REQUEST_LINE = NPT_ERROR_BASE_HTTP - 1; +const int NPT_ERROR_HTTP_NO_PROXY = NPT_ERROR_BASE_HTTP - 2; +const int NPT_ERROR_HTTP_INVALID_REQUEST = NPT_ERROR_BASE_HTTP - 3; +const int NPT_ERROR_HTTP_METHOD_NOT_SUPPORTED = NPT_ERROR_BASE_HTTP - 4; + +#define NPT_HTTP_LINE_TERMINATOR "\r\n" + +/*---------------------------------------------------------------------- +| types ++---------------------------------------------------------------------*/ +typedef unsigned int NPT_HttpStatusCode; +typedef NPT_UrlQuery NPT_HttpUrlQuery; // for backward compatibility + +/*---------------------------------------------------------------------- +| NPT_HttpUrl ++---------------------------------------------------------------------*/ +class NPT_HttpUrl : public NPT_Url { +public: + // constructors + NPT_HttpUrl() {} + NPT_HttpUrl(const char* host, + NPT_UInt16 port, + const char* path, + const char* query = NULL, + const char* fragment = NULL); + NPT_HttpUrl(const char* url, bool ignore_scheme = false); + + // methods + virtual NPT_String ToString(bool with_fragment = true) const; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpProtocol ++---------------------------------------------------------------------*/ +class NPT_HttpProtocol +{ +public: + // class methods + const char* GetStatusCodeString(NPT_HttpStatusCode status_code); +}; + +/*---------------------------------------------------------------------- +| NPT_HttpHeader ++---------------------------------------------------------------------*/ +class NPT_HttpHeader { +public: + // constructors and destructor + NPT_HttpHeader(const char* name, const char* value); + ~NPT_HttpHeader(); + + // methods + NPT_Result Emit(NPT_OutputStream& stream) const; + const NPT_String& GetName() const { return m_Name; } + const NPT_String& GetValue() const { return m_Value; } + NPT_Result SetName(const char* name); + NPT_Result SetValue(const char* value); + +private: + // members + NPT_String m_Name; + NPT_String m_Value; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpHeaders ++---------------------------------------------------------------------*/ +class NPT_HttpHeaders { +public: + // constructors and destructor + NPT_HttpHeaders(); + ~NPT_HttpHeaders(); + + // methods + NPT_Result Parse(NPT_BufferedInputStream& stream); + NPT_Result Emit(NPT_OutputStream& stream) const; + NPT_List<NPT_HttpHeader*>& GetHeaders() { return m_Headers; } + NPT_HttpHeader* GetHeader(const char* name) const; + const NPT_String* GetHeaderValue(const char* name) const; + NPT_Result SetHeader(const char* name, const char* value, bool replace=true); + NPT_Result AddHeader(const char* name, const char* value); + +private: + // members + NPT_List<NPT_HttpHeader*> m_Headers; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpEntity ++---------------------------------------------------------------------*/ +class NPT_HttpEntity { +public: + // constructors and destructor + NPT_HttpEntity(); + NPT_HttpEntity(const NPT_HttpHeaders& headers); + virtual ~NPT_HttpEntity(); + + // methods + NPT_Result SetInputStream(const NPT_InputStreamReference& stream, + bool update_content_length = false); + NPT_Result SetInputStream(const void* data, NPT_Size size); + NPT_Result SetInputStream(const NPT_String& string); + NPT_Result SetInputStream(const char* string); + NPT_Result GetInputStream(NPT_InputStreamReference& stream); + NPT_Result Load(NPT_DataBuffer& buffer); + NPT_Result SetHeaders(const NPT_HttpHeaders& headers); + + // field access + NPT_Result SetContentLength(NPT_LargeSize length); + NPT_Result SetContentType(const char* type); + NPT_Result SetContentEncoding(const char* encoding); + NPT_Result SetTransferEncoding(const char* encoding); + NPT_LargeSize GetContentLength() { return m_ContentLength; } + const NPT_String& GetContentType() { return m_ContentType; } + const NPT_String& GetContentEncoding() { return m_ContentEncoding; } + const NPT_String& GetTransferEncoding(){ return m_TransferEncoding;} + bool HasContentLength() { return m_HasContentLength;} + +private: + // members + NPT_InputStreamReference m_InputStream; + NPT_LargeSize m_ContentLength; + NPT_String m_ContentType; + NPT_String m_ContentEncoding; + NPT_String m_TransferEncoding; + bool m_HasContentLength; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpMessage ++---------------------------------------------------------------------*/ +class NPT_HttpMessage { +public: + // constructors and destructor + virtual ~NPT_HttpMessage(); + + // methods + const NPT_String& GetProtocol() const { + return m_Protocol; + } + NPT_Result SetProtocol(const char* protocol) { + m_Protocol = protocol; + return NPT_SUCCESS; + } + NPT_HttpHeaders& GetHeaders() { + return m_Headers; + } + NPT_Result SetEntity(NPT_HttpEntity* entity); + NPT_HttpEntity* GetEntity() { + return m_Entity; + } + virtual NPT_Result ParseHeaders(NPT_BufferedInputStream& stream); + +protected: + // constructors + NPT_HttpMessage(const char* protocol); + + // members + NPT_String m_Protocol; + NPT_HttpHeaders m_Headers; + NPT_HttpEntity* m_Entity; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpRequest ++---------------------------------------------------------------------*/ +class NPT_HttpRequest : public NPT_HttpMessage { +public: + // class methods + static NPT_Result Parse(NPT_BufferedInputStream& stream, + const NPT_SocketAddress* endpoint, + NPT_HttpRequest*& request); + + // constructors and destructor + NPT_HttpRequest(const NPT_HttpUrl& url, + const char* method, + const char* protocol = NPT_HTTP_PROTOCOL_1_0); + NPT_HttpRequest(const char* url, + const char* method, + const char* protocol = NPT_HTTP_PROTOCOL_1_0); + virtual ~NPT_HttpRequest(); + + // methods + const NPT_HttpUrl& GetUrl() const { return m_Url; } + NPT_HttpUrl& GetUrl() { return m_Url; } + NPT_Result SetUrl(const char* url); + NPT_Result SetUrl(const NPT_HttpUrl& url); + const NPT_String& GetMethod() const { return m_Method; } + virtual NPT_Result Emit(NPT_OutputStream& stream, bool use_proxy=false) const; + +protected: + // members + NPT_HttpUrl m_Url; + NPT_String m_Method; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpResponse ++---------------------------------------------------------------------*/ +class NPT_HttpResponse : public NPT_HttpMessage { +public: + // class methods + static NPT_Result Parse(NPT_BufferedInputStream& stream, + NPT_HttpResponse*& response, + bool reuse_response = false); + + // constructors and destructor + NPT_HttpResponse(NPT_HttpStatusCode status_code, + const char* reason_phrase, + const char* protocol = NPT_HTTP_PROTOCOL_1_0); + virtual ~NPT_HttpResponse(); + + // methods + NPT_Result SetStatus(NPT_HttpStatusCode status_code, + const char* reason_phrase, + const char* protocol = NPT_HTTP_PROTOCOL_1_0); + NPT_Result SetProtocol(const char* protocol); + NPT_HttpStatusCode GetStatusCode() { return m_StatusCode; } + NPT_String& GetReasonPhrase() { return m_ReasonPhrase; } + virtual NPT_Result Emit(NPT_OutputStream& stream) const; + +protected: + // members + NPT_HttpStatusCode m_StatusCode; + NPT_String m_ReasonPhrase; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpProxyAddress ++---------------------------------------------------------------------*/ +class NPT_HttpProxyAddress +{ +public: + NPT_HttpProxyAddress() : m_Port(NPT_HTTP_INVALID_PORT) {} + NPT_HttpProxyAddress(const char* hostname, NPT_UInt16 port) : + m_HostName(hostname), m_Port(port) {} + + const NPT_String& GetHostName() const { return m_HostName; } + void SetHostName(const char* hostname) { m_HostName = hostname; } + NPT_UInt16 GetPort() const { return m_Port; } + void SetPort(NPT_UInt16 port) { m_Port = port; } + +private: + NPT_String m_HostName; + NPT_UInt16 m_Port; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpProxySelector ++---------------------------------------------------------------------*/ +class NPT_HttpProxySelector +{ +public: + // class methods + static NPT_HttpProxySelector* GetSystemDefault(); + + // methods + virtual ~NPT_HttpProxySelector() {}; + virtual NPT_Result GetProxyForUrl(const NPT_HttpUrl& url, NPT_HttpProxyAddress& proxy) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpClient ++---------------------------------------------------------------------*/ +class NPT_HttpClient { +public: + // types + struct Config { + NPT_Timeout m_ConnectionTimeout; + NPT_Timeout m_IoTimeout; + NPT_Timeout m_NameResolverTimeout; + bool m_FollowRedirect; + }; + + class Connector { + public: + virtual ~Connector() {} + + virtual NPT_Result Connect(const char* hostname, + NPT_UInt16 port, + NPT_Timeout connection_timeout, + NPT_Timeout io_timeout, + NPT_Timeout name_resolver_timeout, + NPT_InputStreamReference& input_stream, + NPT_OutputStreamReference& output_stream) = 0; + + }; + + // class methods + static NPT_Result WriteRequest(NPT_OutputStream& output_stream, + NPT_HttpRequest& request, + bool use_proxy = false); + static NPT_Result ReadResponse(NPT_InputStreamReference& input_stream, + bool expect_entity, + NPT_HttpResponse*& response); + + /** + * @param connector Pointer to a Connector instance, or NULL to use + * the default (TCP) connector. + */ + NPT_HttpClient(Connector* connector = NULL); + + virtual ~NPT_HttpClient(); + + // methods + NPT_Result SendRequest(NPT_HttpRequest& request, + NPT_HttpResponse*& response); + NPT_Result SetConfig(const Config& config); + NPT_Result SetProxy(const char* hostname, NPT_UInt16 port); + NPT_Result SetProxySelector(NPT_HttpProxySelector* selector); + NPT_Result SetConnector(Connector* connector); + NPT_Result SetTimeouts(NPT_Timeout connection_timeout, + NPT_Timeout io_timeout, + NPT_Timeout name_resolver_timeout); + +protected: + // methods + NPT_Result SendRequestOnce(NPT_HttpRequest& request, + NPT_HttpResponse*& response); + + // members + Config m_Config; + NPT_HttpProxySelector* m_ProxySelector; + bool m_ProxySelectorIsOwned; + Connector* m_Connector; + +public: + static NPT_String m_UserAgentHeader; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpRequestContext ++---------------------------------------------------------------------*/ +class NPT_HttpRequestContext +{ +public: + // constructor + NPT_HttpRequestContext() {} + NPT_HttpRequestContext(const NPT_SocketAddress* local_address, + const NPT_SocketAddress* remote_address); + + // methods + const NPT_SocketAddress& GetLocalAddress() const { return m_LocalAddress; } + const NPT_SocketAddress& GetRemoteAddress() const { return m_RemoteAddress; } + void SetLocalAddress(const NPT_SocketAddress& address) { + m_LocalAddress = address; + } + void SetRemoteAddress(const NPT_SocketAddress& address) { + m_RemoteAddress = address; + } + +private: + // members + NPT_SocketAddress m_LocalAddress; + NPT_SocketAddress m_RemoteAddress; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpRequestHandler ++---------------------------------------------------------------------*/ +class NPT_HttpRequestHandler +{ +public: + // destructor + virtual ~NPT_HttpRequestHandler() {} + + // methods + virtual NPT_Result SetupResponse(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response) = 0; + + /** + * Override this method if you want to write the body yourself. + * The default implementation will simply write out the entity's + * input stream. + */ + virtual NPT_Result SendResponseBody(const NPT_HttpRequestContext& context, + NPT_HttpResponse& response, + NPT_OutputStream& output); +}; + +/*---------------------------------------------------------------------- +| NPT_HttpStaticRequestHandler ++---------------------------------------------------------------------*/ +class NPT_HttpStaticRequestHandler : public NPT_HttpRequestHandler +{ +public: + // constructors + NPT_HttpStaticRequestHandler(const char* document, + const char* mime_type = "text/html", + bool copy = true); + NPT_HttpStaticRequestHandler(const void* data, + NPT_Size size, + const char* mime_type = "text/html", + bool copy = true); + + // NPT_HttpRequestHandler methods + virtual NPT_Result SetupResponse(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + +protected: + NPT_String m_MimeType; + NPT_DataBuffer m_Buffer; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpFileRequestHandler_FileTypeMap ++---------------------------------------------------------------------*/ +typedef struct NPT_HttpFileRequestHandler_FileTypeMapEntry { + const char* extension; + const char* mime_type; +} NPT_HttpFileRequestHandler_FileTypeMapEntry; + +// specify size here so NPT_ARRAY_SIZE can work +extern const NPT_HttpFileRequestHandler_FileTypeMapEntry NPT_HttpFileRequestHandler_DefaultFileTypeMap[43]; + +/*---------------------------------------------------------------------- +| NPT_HttpFileRequestHandler ++---------------------------------------------------------------------*/ +class NPT_HttpFileRequestHandler : public NPT_HttpRequestHandler +{ +public: + // constructors + NPT_HttpFileRequestHandler(const char* url_root, + const char* file_root, + bool auto_dir = false); + + // NPT_HttpRequestHandler methods + virtual NPT_Result SetupResponse(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + + // accessors + NPT_Map<NPT_String,NPT_String>& GetFileTypeMap() { return m_FileTypeMap; } + void SetDefaultMimeType(const char* mime_type) { + m_DefaultMimeType = mime_type; + } + void SetUseDefaultFileTypeMap(bool use_default) { + m_UseDefaultFileTypeMap = use_default; + } + +protected: + // methods + const char* GetContentType(const NPT_String& filename); + +private: + NPT_String m_UrlRoot; + NPT_String m_FileRoot; + NPT_Map<NPT_String, NPT_String> m_FileTypeMap; + NPT_String m_DefaultMimeType; + bool m_UseDefaultFileTypeMap; + bool m_AutoDir; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpServer ++---------------------------------------------------------------------*/ +class NPT_HttpServer { +public: + // types + struct Config { + NPT_Timeout m_ConnectionTimeout; + NPT_Timeout m_IoTimeout; + NPT_IpAddress m_ListenAddress; + NPT_UInt16 m_ListenPort; + bool m_ReuseAddress; + }; + + // constructors and destructor + NPT_HttpServer(NPT_UInt16 listen_port = NPT_HTTP_DEFAULT_PORT, + bool reuse_address = true); + NPT_HttpServer(NPT_IpAddress listen_address, + NPT_UInt16 listen_port = NPT_HTTP_DEFAULT_PORT, + bool reuse_address = true); + virtual ~NPT_HttpServer(); + + // methods + NPT_Result SetConfig(const Config& config); + const Config& GetConfig() const { return m_Config; } + NPT_Result SetListenPort(NPT_UInt16 port, bool reuse_address = true); + NPT_Result SetTimeouts(NPT_Timeout connection_timeout, NPT_Timeout io_timeout); + NPT_Result Abort(); + NPT_Result WaitForNewClient(NPT_InputStreamReference& input, + NPT_OutputStreamReference& output, + NPT_HttpRequestContext* context); + NPT_Result Loop(); + NPT_UInt16 GetPort() { return m_BoundPort; } + + /** + * Add a request handler. The ownership of the handler is NOT transfered to this object, + * so the caller is responsible for the lifetime management of the handler object. + */ + NPT_Result AddRequestHandler(NPT_HttpRequestHandler* handler, const char* path, bool include_children = false); + NPT_HttpRequestHandler* FindRequestHandler(NPT_HttpRequest& request); + + /** + * Parse the request from a new client, form a response, and send it back. + */ + NPT_Result RespondToClient(NPT_InputStreamReference& input, + NPT_OutputStreamReference& output, + const NPT_HttpRequestContext& context); + +protected: + // types + struct HandlerConfig { + HandlerConfig(NPT_HttpRequestHandler* handler, + const char* path, + bool include_children); + ~HandlerConfig(); + + // methods + bool WillHandle(NPT_HttpRequest& request); + + // members + NPT_HttpRequestHandler* m_Handler; + NPT_String m_Path; + bool m_IncludeChildren; + }; + + // methods + NPT_Result Bind(); + + // members + NPT_TcpServerSocket m_Socket; + NPT_UInt16 m_BoundPort; + Config m_Config; + NPT_List<HandlerConfig*> m_RequestHandlers; + +public: + static NPT_String m_ServerHeader; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpResponder ++---------------------------------------------------------------------*/ +class NPT_HttpResponder { +public: + // types + struct Config { + NPT_Timeout m_IoTimeout; + }; + + // constructors and destructor + NPT_HttpResponder(NPT_InputStreamReference& input, + NPT_OutputStreamReference& output); + virtual ~NPT_HttpResponder(); + + // methods + NPT_Result SetConfig(const Config& config); + NPT_Result SetTimeout(NPT_Timeout io_timeout); + NPT_Result ParseRequest(NPT_HttpRequest*& request, + const NPT_SocketAddress* local_address = NULL); + NPT_Result SendResponseHeaders(NPT_HttpResponse& response); + +protected: + // members + Config m_Config; + NPT_BufferedInputStreamReference m_Input; + NPT_OutputStreamReference m_Output; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpChunkedInputStream ++---------------------------------------------------------------------*/ +class NPT_HttpChunkedInputStream : public NPT_InputStream +{ +public: + // constructors and destructor + NPT_HttpChunkedInputStream(NPT_BufferedInputStreamReference& stream); + virtual ~NPT_HttpChunkedInputStream(); + + // NPT_InputStream methods + NPT_Result Read(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read = NULL); + NPT_Result Seek(NPT_Position offset); + NPT_Result Tell(NPT_Position& offset); + NPT_Result GetSize(NPT_LargeSize& size); + NPT_Result GetAvailable(NPT_LargeSize& available); + +protected: + // members + NPT_BufferedInputStreamReference m_Source; + NPT_UInt32 m_CurrentChunkSize; + bool m_Eos; +}; + +/*---------------------------------------------------------------------- +| NPT_HttpChunkedOutputStream ++---------------------------------------------------------------------*/ +class NPT_HttpChunkedOutputStream : public NPT_OutputStream +{ +public: + // constructors and destructor + NPT_HttpChunkedOutputStream(NPT_OutputStream& stream); + virtual ~NPT_HttpChunkedOutputStream(); + + // NPT_OutputStream methods + NPT_Result Write(const void* buffer, + NPT_Size bytes_to_write, + NPT_Size* bytes_written = NULL); + NPT_Result Seek(NPT_Position /*offset*/) { return NPT_ERROR_NOT_SUPPORTED;} + NPT_Result Tell(NPT_Position& offset) { return m_Stream.Tell(offset); } + NPT_Result Flush() { return m_Stream.Flush(); } + +protected: + // members + NPT_OutputStream& m_Stream; +}; + +#endif // _NPT_HTTP_H_ + diff --git a/modules/platinum/SDK/include/NptInterfaces.h b/modules/platinum/SDK/include/NptInterfaces.h new file mode 100644 index 0000000..b0bb264 --- /dev/null +++ b/modules/platinum/SDK/include/NptInterfaces.h @@ -0,0 +1,115 @@ +/***************************************************************** +| +| Neptune - Interfaces +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_INTERFACES_H_ +#define _NPT_INTERFACES_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptCommon.h" +#include "NptResults.h" +#include "NptConfig.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int NPT_ERROR_NO_SUCH_INTERFACE = NPT_ERROR_BASE_INTERFACES - 0; + +/*---------------------------------------------------------------------- +| NPT_InterfaceId ++---------------------------------------------------------------------*/ +class NPT_InterfaceId +{ + public: + // methods + bool operator==(const NPT_InterfaceId& id) const { + return ((id.m_Id == m_Id) && (id.m_Version == m_Version)); + } + + // members + unsigned long m_Id; + unsigned long m_Version; +}; + +/*---------------------------------------------------------------------- +| NPT_Polymorphic ++---------------------------------------------------------------------*/ +class NPT_Polymorphic +{ +public: + // destructor + virtual ~NPT_Polymorphic() {} + + // methods + virtual NPT_Result GetInterface(const NPT_InterfaceId& id, + NPT_Interface*& iface) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_Interruptible ++---------------------------------------------------------------------*/ +class NPT_Interruptible +{ +public: + // destructor + virtual ~NPT_Interruptible() {} + + // methods + virtual NPT_Result Interrupt() = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_Configurable ++---------------------------------------------------------------------*/ +class NPT_Configurable +{ +public: + // destructor + virtual ~NPT_Configurable() {} + + // methods + virtual NPT_Result SetProperty(const char* /*name*/, + const char* /*value*/) { + return NPT_ERROR_NO_SUCH_PROPERTY; + } + virtual NPT_Result SetProperty(const char* /*name*/, + int /*value*/) { + return NPT_ERROR_NO_SUCH_PROPERTY; + } + virtual NPT_Result GetProperty(const char* /*name*/, + NPT_PropertyValue& /*value*/) { + return NPT_ERROR_NO_SUCH_PROPERTY; + } +}; + +#endif // _NPT_INTERFACES_H_ diff --git a/modules/platinum/SDK/include/NptList.h b/modules/platinum/SDK/include/NptList.h new file mode 100644 index 0000000..f91b498 --- /dev/null +++ b/modules/platinum/SDK/include/NptList.h @@ -0,0 +1,605 @@ +/***************************************************************** +| +| Neptune - Lists +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_LIST_H_ +#define _NPT_LIST_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptResults.h" +#include "NptTypes.h" +#include "NptConstants.h" +#include "NptCommon.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int NPT_ERROR_LIST_EMPTY = NPT_ERROR_BASE_LIST - 0; +const int NPT_ERROR_LIST_OPERATION_ABORTED = NPT_ERROR_BASE_LIST - 1; +const int NPT_ERROR_LIST_OPERATION_CONTINUE = NPT_ERROR_BASE_LIST - 2; + +/*---------------------------------------------------------------------- +| NPT_List ++---------------------------------------------------------------------*/ +template <typename T> +class NPT_List +{ +protected: + class Item; + +public: + // types + typedef T Element; + + class Iterator { + public: + Iterator() : m_Item(NULL) {} + explicit Iterator(Item* item) : m_Item(item) {} + Iterator(const Iterator& copy) : m_Item(copy.m_Item) {} + T& operator*() const { return m_Item->m_Data; } + T* operator->() const { return &m_Item->m_Data;} + Iterator& operator++() { // prefix + m_Item = m_Item->m_Next; + return (*this); + } + Iterator operator++(int) { // postfix + Iterator saved_this = *this; + m_Item = m_Item->m_Next; + return saved_this; + } + Iterator& operator--() { // prefix + m_Item = m_Item->m_Prev; + return (*this); + } + Iterator operator--(int) { // postfix + Iterator saved_this = *this; + m_Item = m_Item->m_Prev; + return saved_this; + } + operator bool() const { + return m_Item != NULL; + } + bool operator==(const Iterator& other) const { + return m_Item == other.m_Item; + } + bool operator!=(const Iterator& other) const { + return m_Item != other.m_Item; + } + void operator=(const Iterator& other) { + m_Item = other.m_Item; + } + void operator=(Item* item) { + m_Item = item; + } + + private: + Item* m_Item; + + // friends + friend class NPT_List<T>; + }; + + // methods + NPT_List<T>(); + NPT_List<T>(const NPT_List<T>& list); + ~NPT_List<T>(); + NPT_Result Add(const T& data); + NPT_Result Insert(const Iterator where, const T& data); + NPT_Result Remove(const T& data, bool all=false); + NPT_Result Erase(const Iterator position); + NPT_Result PopHead(T& data); + bool Contains(const T& data) const; + NPT_Result Clear(); + NPT_Result Get(NPT_Ordinal index, T& data) const; + NPT_Result Get(NPT_Ordinal index, T*& data) const; + NPT_Cardinal GetItemCount() const { return m_ItemCount; } + Iterator GetFirstItem() const { return Iterator(m_Head); } + Iterator GetLastItem() const { return Iterator(m_Tail); } + Iterator GetItem(NPT_Ordinal index) const; + + // list manipulation + NPT_Result Add(NPT_List<T>& list); + NPT_Result Remove(const NPT_List<T>& list, bool all=false); + + // item manipulation + NPT_Result Add(Item& item); + NPT_Result Detach(Item& item); + NPT_Result Insert(const Iterator where, Item& item); + + // list operations + // keep these template members defined here because MSV6 does not let + // us define them later + template <typename X> + NPT_Result Apply(const X& function) const + { + Item* item = m_Head; + while (item) { + function(item->m_Data); + item = item->m_Next; + } + + return NPT_SUCCESS; + } + + template <typename X, typename P> + NPT_Result ApplyUntil(const X& function, const P& predicate, bool* match = NULL) const + { + Item* item = m_Head; + while (item) { + NPT_Result return_value; + if (predicate(function(item->m_Data), return_value)) { + if (match) *match = true; + return return_value; + } + item = item->m_Next; + } + + if (match) *match = false; + return NPT_SUCCESS; + } + + template <typename P> + Iterator Find(const P& predicate, NPT_Ordinal n=0) const + { + Item* item = m_Head; + while (item) { + if (predicate(item->m_Data)) { + if (n == 0) { + return Iterator(item); + } + --n; + } + item = item->m_Next; + } + + return Iterator(NULL); + } + + // operators + void operator=(const NPT_List<T>& other); + bool operator==(const NPT_List<T>& other) const; + bool operator!=(const NPT_List<T>& other) const; + +protected: + // types + class Item + { + public: + // methods + Item(const T& data) : m_Next(0), m_Prev(0), m_Data(data) {} + + // members + Item* m_Next; + Item* m_Prev; + T m_Data; + + // friends + //friend class NPT_List<T>; + //friend class NPT_List<T>::Iterator; + }; + + // members + NPT_Cardinal m_ItemCount; + Item* m_Head; + Item* m_Tail; +}; + +/*---------------------------------------------------------------------- +| NPT_List<T>::NPT_List ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_List<T>::NPT_List() : m_ItemCount(0), m_Head(0), m_Tail(0) +{ +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::NPT_List ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_List<T>::NPT_List(const NPT_List<T>& list) : m_ItemCount(0), m_Head(0), m_Tail(0) +{ + *this = list; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::~NPT_List<T> ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_List<T>::~NPT_List() +{ + Clear(); +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::operator= ++---------------------------------------------------------------------*/ +template <typename T> +void +NPT_List<T>::operator=(const NPT_List<T>& list) +{ + // cleanup + Clear(); + + // copy the new list + Item* item = list.m_Head; + while (item) { + Add(item->m_Data); + item = item->m_Next; + } +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::operator== ++---------------------------------------------------------------------*/ +template <typename T> +bool +NPT_List<T>::operator==(const NPT_List<T>& other) const +{ + // quick test + if (m_ItemCount != other.m_ItemCount) return false; + + // compare all elements one by one + Item* our_item = m_Head; + Item* their_item = other.m_Head; + while (our_item && their_item) { + if (our_item->m_Data != their_item->m_Data) return false; + our_item = our_item->m_Next; + their_item = their_item->m_Next; + } + + return our_item == NULL && their_item == NULL; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::operator!= ++---------------------------------------------------------------------*/ +template <typename T> +inline +bool +NPT_List<T>::operator!=(const NPT_List<T>& other) const +{ + return !(*this == other); +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Clear ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Clear() +{ + // delete all items + Item* item = m_Head; + while (item) { + Item* next = item->m_Next; + delete item; + item = next; + } + + m_ItemCount = 0; + m_Head = NULL; + m_Tail = NULL; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Add ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Add(Item& item) +{ + // add element at the tail + if (m_Tail) { + item.m_Prev = m_Tail; + item.m_Next = NULL; + m_Tail->m_Next = &item; + m_Tail = &item; + } else { + m_Head = &item; + m_Tail = &item; + item.m_Next = NULL; + item.m_Prev = NULL; + } + + // one more item in the list now + ++m_ItemCount; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Add ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Add(NPT_List<T>& list) +{ + // copy the new list + Item* item = list.m_Head; + while (item) { + Add(item->m_Data); + item = item->m_Next; + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Add ++---------------------------------------------------------------------*/ +template <typename T> +inline +NPT_Result +NPT_List<T>::Add(const T& data) +{ + return Add(*new Item(data)); +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::GetItem ++---------------------------------------------------------------------*/ +template <typename T> +typename NPT_List<T>::Iterator +NPT_List<T>::GetItem(NPT_Ordinal n) const +{ + Iterator result; + if (n >= m_ItemCount) return result; + + result = m_Head; + for (unsigned int i=0; i<n; i++) { + ++result; + } + + return result; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Insert ++---------------------------------------------------------------------*/ +template <typename T> +inline NPT_Result +NPT_List<T>::Insert(Iterator where, const T&data) +{ + return Insert(where, *new Item(data)); +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Insert ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Insert(Iterator where, Item& item) +{ + // insert the item in the list + Item* position = where.m_Item; + if (position) { + // insert at position + item.m_Next = position; + item.m_Prev = position->m_Prev; + position->m_Prev = &item; + if (item.m_Prev) { + item.m_Prev->m_Next = &item; + } else { + // this is the new head + m_Head = &item; + } + + // one more item in the list now + ++m_ItemCount; + } else { + // insert at tail + return Add(item); + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Erase ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Erase(Iterator position) +{ + if (!position) return NPT_ERROR_NO_SUCH_ITEM; + Detach(*position.m_Item); + delete position.m_Item; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Remove ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Remove(const T& data, bool all) +{ + Item* item = m_Head; + NPT_Cardinal matches = 0; + + while (item) { + Item* next = item->m_Next; + if (item->m_Data == data) { + // we found a match + ++matches; + + // detach item + Detach(*item); + + // destroy the item + delete item; + + if (!all) return NPT_SUCCESS; + } + item = next; + } + + return matches?NPT_SUCCESS:NPT_ERROR_NO_SUCH_ITEM; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Remove ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Remove(const NPT_List<T>& list, bool all) +{ + Item* item = list.m_Head; + while (item) { + Remove(item->m_Data, all); + item = item->m_Next; + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Detach ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Detach(Item& item) +{ + // remove item + if (item.m_Prev) { + // item is not the head + if (item.m_Next) { + // item is not the tail + item.m_Next->m_Prev = item.m_Prev; + item.m_Prev->m_Next = item.m_Next; + } else { + // item is the tail + m_Tail = item.m_Prev; + m_Tail->m_Next = NULL; + } + } else { + // item is the head + m_Head = item.m_Next; + if (m_Head) { + // item is not the tail + m_Head->m_Prev = NULL; + } else { + // item is also the tail + m_Tail = NULL; + } + } + + // one less item in the list now + --m_ItemCount; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Get ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Get(NPT_Ordinal index, T& data) const +{ + T* data_pointer; + NPT_CHECK(Get(index, data_pointer)); + data = *data_pointer; + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Get ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::Get(NPT_Ordinal index, T*& data) const +{ + Item* item = m_Head; + + if (index < m_ItemCount) { + while (index--) item = item->m_Next; + data = &item->m_Data; + return NPT_SUCCESS; + } else { + data = NULL; + return NPT_ERROR_NO_SUCH_ITEM; + } +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::PopHead ++---------------------------------------------------------------------*/ +template <typename T> +NPT_Result +NPT_List<T>::PopHead(T& data) +{ + // check that we have an element + if (m_Head == NULL) return NPT_ERROR_LIST_EMPTY; + + // copy the head item's data + data = m_Head->m_Data; + + // discard the head item + Item* head = m_Head; + m_Head = m_Head->m_Next; + if (m_Head) { + m_Head->m_Prev = NULL; + } else { + m_Tail = NULL; + } + delete head; + + // update the count + --m_ItemCount; + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_List<T>::Contains ++---------------------------------------------------------------------*/ +template <typename T> +bool +NPT_List<T>::Contains(const T& data) const +{ + Item* item = m_Head; + while (item) { + if (item->m_Data == data) return true; + item = item->m_Next; + } + + return false; +} + +#endif // _NPT_LIST_H_ diff --git a/modules/platinum/SDK/include/NptLogging.h b/modules/platinum/SDK/include/NptLogging.h new file mode 100644 index 0000000..44ac630 --- /dev/null +++ b/modules/platinum/SDK/include/NptLogging.h @@ -0,0 +1,512 @@ +/***************************************************************** +| +| Neptune - Logging Support +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| +****************************************************************/ +/** @file +* Header file for logging +*/ + +#ifndef _NPT_LOGGING_H_ +#define _NPT_LOGGING_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConfig.h" +#include "NptDebug.h" +#include "NptTypes.h" +#include "NptTime.h" +#include "NptStrings.h" +#include "NptList.h" +#include "NptStreams.h" +#include "NptThreads.h" +#include "NptHttp.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class NPT_LogManager; + +/*---------------------------------------------------------------------- +| types ++---------------------------------------------------------------------*/ +class NPT_LogRecord { +public: + const char* m_LoggerName; + int m_Level; + const char* m_Message; + NPT_TimeStamp m_TimeStamp; + const char* m_SourceFile; + unsigned int m_SourceLine; + const char* m_SourceFunction; +}; + +class NPT_LogHandler { +public: + // class methods + static NPT_Result Create(const char* logger_name, + const char* handler_name, + NPT_LogHandler*& handler); + + // methods + virtual ~NPT_LogHandler() {} + virtual void Log(const NPT_LogRecord& record) = 0; + virtual NPT_String ToString() { return ""; } +}; + +class NPT_Logger { +public: + // methods + NPT_Logger(const char* name, NPT_LogManager& manager); + ~NPT_Logger(); + void Log(int level, + const char* source_file, + unsigned int source_line, + const char* source_function, + const char* msg, + ...); + + NPT_Result AddHandler(NPT_LogHandler* handler); + NPT_Result DeleteHandlers(); + NPT_Result SetParent(NPT_Logger* parent); + const NPT_String& GetName() const { return m_Name; } + int GetLevel() const { return m_Level; } + bool GetForwardToParent() const { return m_ForwardToParent; } + NPT_List<NPT_LogHandler*>& GetHandlers() { return m_Handlers; } + +private: + // members + NPT_LogManager& m_Manager; + NPT_String m_Name; + int m_Level; + bool m_LevelIsInherited; + bool m_ForwardToParent; + NPT_Logger* m_Parent; + NPT_List<NPT_LogHandler*> m_Handlers; + + // friends + friend class NPT_LogManager; +}; + +typedef struct { + NPT_Logger* logger; + const char* name; +} NPT_LoggerReference; + +class NPT_Log { +public: + // class methods + static int GetLogLevel(const char* name); + static const char* GetLogLevelName(int level); + static const char* GetLogLevelAnsiColor(int level); + static void FormatRecordToStream(const NPT_LogRecord& record, + NPT_OutputStream& stream, + bool use_colors, + NPT_Flags format_filter); +}; + +class NPT_LogConfigEntry { +public: + NPT_LogConfigEntry(const char* key, const char* value) : + m_Key(key), m_Value(value) {} + NPT_String m_Key; + NPT_String m_Value; +}; + +class NPT_LogManager { +public: + // class methods + static NPT_LogManager& GetDefault(); + static bool ConfigValueIsBooleanTrue(NPT_String& value); + static bool ConfigValueIsBooleanFalse(NPT_String& value); + static NPT_Logger* GetLogger(const char* name); + + // methods + NPT_LogManager(); + ~NPT_LogManager(); + NPT_Result Configure(const char* config_sources = NULL); + NPT_String* GetConfigValue(const char* prefix, const char* suffix); + NPT_List<NPT_Logger*>& GetLoggers() { return m_Loggers; } + NPT_List<NPT_LogConfigEntry>& GetConfig() { return m_Config; } + void Enable(bool value) { m_Enabled = value; } + void Lock() { m_Lock.Lock(); } + void Unlock() { m_Lock.Unlock(); } + +private: + // methods + NPT_Result SetConfigValue(const char* key, const char* value); + NPT_Result ParseConfig(const char* config, NPT_Size config_size); + NPT_Result ParseConfigSource(NPT_String& source); + NPT_Result ParseConfigFile(const char* filename); + bool HaveLoggerConfig(const char* name); + NPT_Logger* FindLogger(const char* name); + NPT_Result ConfigureLogger(NPT_Logger* logger); + + // members + NPT_Mutex m_Lock; + volatile bool m_Enabled; + volatile bool m_Configured; + volatile bool m_Configuring; + NPT_List<NPT_LogConfigEntry> m_Config; + NPT_List<NPT_Logger*> m_Loggers; + NPT_Logger* m_Root; +}; + +const unsigned short NPT_HTTP_LOGGER_CONFIGURATOR_DEFAULT_PORT = 6378; +class NPT_HttpLoggerConfigurator : NPT_HttpRequestHandler, public NPT_Thread { +public: + // constructor and destructor + NPT_HttpLoggerConfigurator(NPT_UInt16 port = NPT_HTTP_LOGGER_CONFIGURATOR_DEFAULT_PORT, + bool detached = true); + virtual ~NPT_HttpLoggerConfigurator(); + + // NPT_Runnable (NPT_Thread) methods + virtual void Run(); + +private: + // NPT_HttpRequestHandler methods + virtual NPT_Result SetupResponse(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + + // members + NPT_HttpServer* m_Server; +}; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#define NPT_LOG_LEVEL_FATAL 700 +#define NPT_LOG_LEVEL_SEVERE 600 +#define NPT_LOG_LEVEL_WARNING 500 +#define NPT_LOG_LEVEL_INFO 400 +#define NPT_LOG_LEVEL_FINE 300 +#define NPT_LOG_LEVEL_FINER 200 +#define NPT_LOG_LEVEL_FINEST 100 + +#define NPT_LOG_LEVEL_OFF 32767 +#define NPT_LOG_LEVEL_ALL 0 + +/*---------------------------------------------------------------------- +| macros ++---------------------------------------------------------------------*/ +#define NPT_LOG_GET_LOGGER(_logger) \ + if ((_logger).logger == NULL) { \ + (_logger).logger = NPT_LogManager::GetLogger((_logger).name); \ + } + +#if defined(NPT_CONFIG_ENABLE_LOGGING) + +#define NPT_DEFINE_LOGGER(_logger, _name) static NPT_LoggerReference _logger = { NULL, (_name) }; + +#define NPT_LOG_X(_logger, _level, _argsx) \ +do { \ + NPT_LOG_GET_LOGGER((_logger)) \ + if ((_logger).logger && (_level) >= (_logger).logger->GetLevel()) { \ + (_logger).logger->Log _argsx; \ + } \ +} while(0) + +#define NPT_CHECK_LL(_logger, _level, _result) do { \ + NPT_Result _x = (_result); \ + if (_x != NPT_SUCCESS) { \ + NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),"NPT_CHECK failed, result=%d (%s) [%s]", _x, NPT_ResultText(_x), #_result)); \ + return _x; \ + } \ +} while(0) + +#define NPT_CHECK_LABEL_LL(_logger, _level, _result, _label) do { \ + NPT_Result _x = (_result); \ + if (_x != NPT_SUCCESS) { \ + NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),"NPT_CHECK failed, result=%d (%s) [%s]", _x, NPT_ResultText(_x), #_result)); \ + goto _label; \ + } \ +} while(0) +#define NPT_CHECK_POINTER_LL(_logger, _level, _p) do { \ + if ((_p) == NULL) { \ + NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),"@@@ NULL pointer parameter")); \ + return NPT_ERROR_INVALID_PARAMETERS; \ + } \ +} while(0) +#define NPT_CHECK_POINTER_LABEL_LL(_logger, _level, _p, _label) do { \ + if ((_p) == NULL) { \ + NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),"@@@ NULL pointer parameter")); \ + goto _label; \ + } \ +} while(0) + +#else /* NPT_CONFIG_ENABLE_LOGGING */ + +#define NPT_DEFINE_LOGGER(_logger, _name) +#define NPT_LOG_X(_logger, _level, _argsx) +#define NPT_CHECK_LL(_logger, _level, _result) NPT_CHECK(_result) +#define NPT_CHECK_LABEL_LL(_logger, _level, _result, _label) NPT_CHECK_LABEL((_result), _label) +#define NPT_CHECK_POINTER_LL(_logger, _level, _p) NPT_CHECK_POINTER((_p)) +#define NPT_CHECK_POINTER_LABEL_LL(_logger, _level, _p, _label) NPT_CHECK_POINTER_LABEL((_p), _label) + +#endif /* NPT_CONFIG_ENABLE_LOGGING */ + +#define NPT_SET_LOCAL_LOGGER(_name) NPT_DEFINE_LOGGER(_NPT_LocalLogger, (_name)) +#define NPT_CHECK_L(_level, _result) NPT_CHECK_LL(_NPT_LocalLogger, (_level), (_result)) +#define NPT_CHECK_LABEL_L(_level, _result, _label) NPT_CHECK_LABEL_LL(_NPT_LocalLogger, (_level), NULL, (_result), _label) + +/* NOTE: the following are machine-generated, do not edit */ +#define NPT_LOG_LL(_logger,_level,_msg) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg))) +#define NPT_LOG(_level,_msg) NPT_LOG_LL((_NPT_LocalLogger),(_level),(_msg)) +#define NPT_LOG_L(_logger,_level,_msg) NPT_LOG_LL((_logger),(_level),(_msg)) +#define NPT_LOG_LL1(_logger,_level,_msg,_arg1) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg),(_arg1))) +#define NPT_LOG_1(_level,_msg,_arg1) NPT_LOG_LL1((_NPT_LocalLogger),(_level),(_msg),(_arg1)) +#define NPT_LOG_L1(_logger,_level,_msg,_arg1) NPT_LOG_LL1((_logger),(_level),(_msg),(_arg1)) +#define NPT_LOG_LL2(_logger,_level,_msg,_arg1,_arg2) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg),(_arg1),(_arg2))) +#define NPT_LOG_2(_level,_msg,_arg1,_arg2) NPT_LOG_LL2((_NPT_LocalLogger),(_level),(_msg),(_arg1),(_arg2)) +#define NPT_LOG_L2(_logger,_level,_msg,_arg1,_arg2) NPT_LOG_LL2((_logger),(_level),(_msg),(_arg1),(_arg2)) +#define NPT_LOG_LL3(_logger,_level,_msg,_arg1,_arg2,_arg3) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg),(_arg1),(_arg2),(_arg3))) +#define NPT_LOG_3(_level,_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_NPT_LocalLogger),(_level),(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_L3(_logger,_level,_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_logger),(_level),(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_LL4(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg),(_arg1),(_arg2),(_arg3),(_arg4))) +#define NPT_LOG_4(_level,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_NPT_LocalLogger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_L4(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_logger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_LL5(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5))) +#define NPT_LOG_5(_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_NPT_LocalLogger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_L5(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_logger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_LL6(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6))) +#define NPT_LOG_6(_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_NPT_LocalLogger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_L6(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_logger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_LL7(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7))) +#define NPT_LOG_7(_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_NPT_LocalLogger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_L7(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_logger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_LL8(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8))) +#define NPT_LOG_8(_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_NPT_LocalLogger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_L8(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_logger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_LL9(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_X((_logger),(_level),((_level),__FILE__,__LINE__,(NPT_LocalFunctionName),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9))) +#define NPT_LOG_9(_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_NPT_LocalLogger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_L9(_logger,_level,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_logger),(_level),(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) + +#define NPT_LOG_FATAL(_msg) NPT_LOG_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg)) +#define NPT_LOG_FATAL_L(_logger,_msg) NPT_LOG_LL((_logger),NPT_LOG_LEVEL_FATAL,(_msg)) +#define NPT_LOG_FATAL_1(_msg,_arg1) NPT_LOG_LL1((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1)) +#define NPT_LOG_FATAL_L1(_logger,_msg,_arg1) NPT_LOG_LL1((_logger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1)) +#define NPT_LOG_FATAL_2(_msg,_arg1,_arg2) NPT_LOG_LL2((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_FATAL_L2(_logger,_msg,_arg1,_arg2) NPT_LOG_LL2((_logger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_FATAL_3(_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_FATAL_L3(_logger,_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_logger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_FATAL_4(_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_FATAL_L4(_logger,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_logger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_FATAL_5(_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_FATAL_L5(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_logger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_FATAL_6(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_FATAL_L6(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_logger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_FATAL_7(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_FATAL_L7(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_logger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_FATAL_8(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_FATAL_L8(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_logger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_FATAL_9(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_FATAL_L9(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_logger),NPT_LOG_LEVEL_FATAL,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_SEVERE(_msg) NPT_LOG_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg)) +#define NPT_LOG_SEVERE_L(_logger,_msg) NPT_LOG_LL((_logger),NPT_LOG_LEVEL_SEVERE,(_msg)) +#define NPT_LOG_SEVERE_1(_msg,_arg1) NPT_LOG_LL1((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1)) +#define NPT_LOG_SEVERE_L1(_logger,_msg,_arg1) NPT_LOG_LL1((_logger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1)) +#define NPT_LOG_SEVERE_2(_msg,_arg1,_arg2) NPT_LOG_LL2((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_SEVERE_L2(_logger,_msg,_arg1,_arg2) NPT_LOG_LL2((_logger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_SEVERE_3(_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_SEVERE_L3(_logger,_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_logger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_SEVERE_4(_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_SEVERE_L4(_logger,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_logger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_SEVERE_5(_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_SEVERE_L5(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_logger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_SEVERE_6(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_SEVERE_L6(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_logger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_SEVERE_7(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_SEVERE_L7(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_logger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_SEVERE_8(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_SEVERE_L8(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_logger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_SEVERE_9(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_SEVERE_L9(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_logger),NPT_LOG_LEVEL_SEVERE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_WARNING(_msg) NPT_LOG_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg)) +#define NPT_LOG_WARNING_L(_logger,_msg) NPT_LOG_LL((_logger),NPT_LOG_LEVEL_WARNING,(_msg)) +#define NPT_LOG_WARNING_1(_msg,_arg1) NPT_LOG_LL1((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1)) +#define NPT_LOG_WARNING_L1(_logger,_msg,_arg1) NPT_LOG_LL1((_logger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1)) +#define NPT_LOG_WARNING_2(_msg,_arg1,_arg2) NPT_LOG_LL2((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_WARNING_L2(_logger,_msg,_arg1,_arg2) NPT_LOG_LL2((_logger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_WARNING_3(_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_WARNING_L3(_logger,_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_logger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_WARNING_4(_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_WARNING_L4(_logger,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_logger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_WARNING_5(_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_WARNING_L5(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_logger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_WARNING_6(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_WARNING_L6(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_logger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_WARNING_7(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_WARNING_L7(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_logger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_WARNING_8(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_WARNING_L8(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_logger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_WARNING_9(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_WARNING_L9(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_logger),NPT_LOG_LEVEL_WARNING,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_INFO(_msg) NPT_LOG_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg)) +#define NPT_LOG_INFO_L(_logger,_msg) NPT_LOG_LL((_logger),NPT_LOG_LEVEL_INFO,(_msg)) +#define NPT_LOG_INFO_1(_msg,_arg1) NPT_LOG_LL1((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1)) +#define NPT_LOG_INFO_L1(_logger,_msg,_arg1) NPT_LOG_LL1((_logger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1)) +#define NPT_LOG_INFO_2(_msg,_arg1,_arg2) NPT_LOG_LL2((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_INFO_L2(_logger,_msg,_arg1,_arg2) NPT_LOG_LL2((_logger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_INFO_3(_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_INFO_L3(_logger,_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_logger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_INFO_4(_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_INFO_L4(_logger,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_logger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_INFO_5(_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_INFO_L5(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_logger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_INFO_6(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_INFO_L6(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_logger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_INFO_7(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_INFO_L7(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_logger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_INFO_8(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_INFO_L8(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_logger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_INFO_9(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_INFO_L9(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_logger),NPT_LOG_LEVEL_INFO,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_FINE(_msg) NPT_LOG_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg)) +#define NPT_LOG_FINE_L(_logger,_msg) NPT_LOG_LL((_logger),NPT_LOG_LEVEL_FINE,(_msg)) +#define NPT_LOG_FINE_1(_msg,_arg1) NPT_LOG_LL1((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1)) +#define NPT_LOG_FINE_L1(_logger,_msg,_arg1) NPT_LOG_LL1((_logger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1)) +#define NPT_LOG_FINE_2(_msg,_arg1,_arg2) NPT_LOG_LL2((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_FINE_L2(_logger,_msg,_arg1,_arg2) NPT_LOG_LL2((_logger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_FINE_3(_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_FINE_L3(_logger,_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_logger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_FINE_4(_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_FINE_L4(_logger,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_logger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_FINE_5(_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_FINE_L5(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_logger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_FINE_6(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_FINE_L6(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_logger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_FINE_7(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_FINE_L7(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_logger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_FINE_8(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_FINE_L8(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_logger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_FINE_9(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_FINE_L9(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_logger),NPT_LOG_LEVEL_FINE,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_FINER(_msg) NPT_LOG_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg)) +#define NPT_LOG_FINER_L(_logger,_msg) NPT_LOG_LL((_logger),NPT_LOG_LEVEL_FINER,(_msg)) +#define NPT_LOG_FINER_1(_msg,_arg1) NPT_LOG_LL1((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1)) +#define NPT_LOG_FINER_L1(_logger,_msg,_arg1) NPT_LOG_LL1((_logger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1)) +#define NPT_LOG_FINER_2(_msg,_arg1,_arg2) NPT_LOG_LL2((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_FINER_L2(_logger,_msg,_arg1,_arg2) NPT_LOG_LL2((_logger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_FINER_3(_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_FINER_L3(_logger,_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_logger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_FINER_4(_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_FINER_L4(_logger,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_logger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_FINER_5(_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_FINER_L5(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_logger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_FINER_6(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_FINER_L6(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_logger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_FINER_7(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_FINER_L7(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_logger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_FINER_8(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_FINER_L8(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_logger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_FINER_9(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_FINER_L9(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_logger),NPT_LOG_LEVEL_FINER,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_FINEST(_msg) NPT_LOG_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg)) +#define NPT_LOG_FINEST_L(_logger,_msg) NPT_LOG_LL((_logger),NPT_LOG_LEVEL_FINEST,(_msg)) +#define NPT_LOG_FINEST_1(_msg,_arg1) NPT_LOG_LL1((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1)) +#define NPT_LOG_FINEST_L1(_logger,_msg,_arg1) NPT_LOG_LL1((_logger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1)) +#define NPT_LOG_FINEST_2(_msg,_arg1,_arg2) NPT_LOG_LL2((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_FINEST_L2(_logger,_msg,_arg1,_arg2) NPT_LOG_LL2((_logger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2)) +#define NPT_LOG_FINEST_3(_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_FINEST_L3(_logger,_msg,_arg1,_arg2,_arg3) NPT_LOG_LL3((_logger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3)) +#define NPT_LOG_FINEST_4(_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_FINEST_L4(_logger,_msg,_arg1,_arg2,_arg3,_arg4) NPT_LOG_LL4((_logger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4)) +#define NPT_LOG_FINEST_5(_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_FINEST_L5(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5) NPT_LOG_LL5((_logger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5)) +#define NPT_LOG_FINEST_6(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_FINEST_L6(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6) NPT_LOG_LL6((_logger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6)) +#define NPT_LOG_FINEST_7(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_FINEST_L7(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7) NPT_LOG_LL7((_logger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7)) +#define NPT_LOG_FINEST_8(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_FINEST_L8(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8) NPT_LOG_LL8((_logger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8)) +#define NPT_LOG_FINEST_9(_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) +#define NPT_LOG_FINEST_L9(_logger,_msg,_arg1,_arg2,_arg3,_arg4,_arg5,_arg6,_arg7,_arg8,_arg9) NPT_LOG_LL9((_logger),NPT_LOG_LEVEL_FINEST,(_msg),(_arg1),(_arg2),(_arg3),(_arg4),(_arg5),(_arg6),(_arg7),(_arg8),(_arg9)) + +#define NPT_CHECK_FATAL(_result) NPT_CHECK_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_result)) +#define NPT_CHECK_FATAL_L(_logger,_result) NPT_CHECK_LL((_logger),NPT_LOG_LEVEL_FATAL,(_result)) +#define NPT_CHECK_SEVERE(_result) NPT_CHECK_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_result)) +#define NPT_CHECK_SEVERE_L(_logger,_result) NPT_CHECK_LL((_logger),NPT_LOG_LEVEL_SEVERE,(_result)) +#define NPT_CHECK_WARNING(_result) NPT_CHECK_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_result)) +#define NPT_CHECK_WARNING_L(_logger,_result) NPT_CHECK_LL((_logger),NPT_LOG_LEVEL_WARNING,(_result)) +#define NPT_CHECK_INFO(_result) NPT_CHECK_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_result)) +#define NPT_CHECK_INFO_L(_logger,_result) NPT_CHECK_LL((_logger),NPT_LOG_LEVEL_INFO,(_result)) +#define NPT_CHECK_FINE(_result) NPT_CHECK_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_result)) +#define NPT_CHECK_FINE_L(_logger,_result) NPT_CHECK_LL((_logger),NPT_LOG_LEVEL_FINE,(_result)) +#define NPT_CHECK_FINER(_result) NPT_CHECK_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_result)) +#define NPT_CHECK_FINER_L(_logger,_result) NPT_CHECK_LL((_logger),NPT_LOG_LEVEL_FINER,(_result)) +#define NPT_CHECK_FINEST(_result) NPT_CHECK_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_result)) +#define NPT_CHECK_FINEST_L(_logger,_result) NPT_CHECK_LL((_logger),NPT_LOG_LEVEL_FINEST,(_result)) + +#define NPT_CHECK_LABEL_FATAL(_result,_label) NPT_CHECK_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_result),_label) +#define NPT_CHECK_LABEL_FATAL_L(_logger,_result,_label) NPT_CHECK_LABEL_LL((_logger),NPT_LOG_LEVEL_FATAL,(_result),_label) +#define NPT_CHECK_LABEL_SEVERE(_result,_label) NPT_CHECK_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_result),_label) +#define NPT_CHECK_LABEL_SEVERE_L(_logger,_result,_label) NPT_CHECK_LABEL_LL((_logger),NPT_LOG_LEVEL_SEVERE,(_result),_label) +#define NPT_CHECK_LABEL_WARNING(_result,_label) NPT_CHECK_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_result),_label) +#define NPT_CHECK_LABEL_WARNING_L(_logger,_result,_label) NPT_CHECK_LABEL_LL((_logger),NPT_LOG_LEVEL_WARNING,(_result),_label) +#define NPT_CHECK_LABEL_INFO(_result,_label) NPT_CHECK_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_result),_label) +#define NPT_CHECK_LABEL_INFO_L(_logger,_result,_label) NPT_CHECK_LABEL_LL((_logger),NPT_LOG_LEVEL_INFO,(_result),_label) +#define NPT_CHECK_LABEL_FINE(_result,_label) NPT_CHECK_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_result),_label) +#define NPT_CHECK_LABEL_FINE_L(_logger,_result,_label) NPT_CHECK_LABEL_LL((_logger),NPT_LOG_LEVEL_FINE,(_result),_label) +#define NPT_CHECK_LABEL_FINER(_result,_label) NPT_CHECK_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_result),_label) +#define NPT_CHECK_LABEL_FINER_L(_logger,_result,_label) NPT_CHECK_LABEL_LL((_logger),NPT_LOG_LEVEL_FINER,(_result),_label) +#define NPT_CHECK_LABEL_FINEST(_result,_label) NPT_CHECK_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_result),_label) +#define NPT_CHECK_LABEL_FINEST_L(_logger,_result,_label) NPT_CHECK_LABEL_LL((_logger),NPT_LOG_LEVEL_FINEST,(_result),_label) + +#define NPT_CHECK_POINTER_FATAL(_p) NPT_CHECK_POINTER_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_p)) +#define NPT_CHECK_POINTER_FATAL_L(_logger,_p) NPT_CHECK_POINTER_LL(_logger,NPT_LOG_LEVEL_FATAL,(_p)) +#define NPT_CHECK_POINTER_SEVERE(_p) NPT_CHECK_POINTER_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_p)) +#define NPT_CHECK_POINTER_SEVERE_L(_logger,_p) NPT_CHECK_POINTER_LL(_logger,NPT_LOG_LEVEL_SEVERE,(_p)) +#define NPT_CHECK_POINTER_WARNING(_p) NPT_CHECK_POINTER_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_p)) +#define NPT_CHECK_POINTER_WARNING_L(_logger,_p) NPT_CHECK_POINTER_LL(_logger,NPT_LOG_LEVEL_WARNING,(_p)) +#define NPT_CHECK_POINTER_INFO(_p) NPT_CHECK_POINTER_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_p)) +#define NPT_CHECK_POINTER_INFO_L(_logger,_p) NPT_CHECK_POINTER_LL(_logger,NPT_LOG_LEVEL_INFO,(_p)) +#define NPT_CHECK_POINTER_FINE(_p) NPT_CHECK_POINTER_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_p)) +#define NPT_CHECK_POINTER_FINE_L(_logger,_p) NPT_CHECK_POINTER_LL(_logger,NPT_LOG_LEVEL_FINE,(_p)) +#define NPT_CHECK_POINTER_FINER(_p) NPT_CHECK_POINTER_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_p)) +#define NPT_CHECK_POINTER_FINER_L(_logger,_p) NPT_CHECK_POINTER_LL(_logger,NPT_LOG_LEVEL_FINER,(_p)) +#define NPT_CHECK_POINTER_FINEST(_p) NPT_CHECK_POINTER_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_p)) +#define NPT_CHECK_POINTER_FINEST_L(_logger,_p) NPT_CHECK_POINTER_LL(_logger,NPT_LOG_LEVEL_FINEST,(_p)) + +#define NPT_CHECK_POINTER_LABEL_FATAL(_p,_label) NPT_CHECK_POINTER_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FATAL,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_FATAL_L(_logger,_p,_label) NPT_CHECK_POINTER_LABEL_LL(_logger,NPT_LOG_LEVEL_FATAL,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_SEVERE(_p,_label) NPT_CHECK_POINTER_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_SEVERE,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_SEVERE_L(_logger,_p,_label) NPT_CHECK_POINTER_LABEL_LL(_logger,NPT_LOG_LEVEL_SEVERE,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_WARNING(_p,_label) NPT_CHECK_POINTER_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_WARNING,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_WARNING_L(_logger,_p,_label) NPT_CHECK_POINTER_LABEL_LL(_logger,NPT_LOG_LEVEL_WARNING,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_INFO(_p,_label) NPT_CHECK_POINTER_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_INFO,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_INFO_L(_logger,_p,_label) NPT_CHECK_POINTER_LABEL_LL(_logger,NPT_LOG_LEVEL_INFO,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_FINE(_p, _label) NPT_CHECK_POINTER_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINE,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_FINE_L(_logger,_p,_label) NPT_CHECK_POINTER_LABEL_LL(_logger,NPT_LOG_LEVEL_FINE,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_FINER(_p,_label) NPT_CHECK_POINTER_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINER,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_FINER_L(_logger,_p,_label) NPT_CHECK_POINTER_LABEL_LL(_logger,NPT_LOG_LEVEL_FINER,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_FINEST(_p,_label) NNPT_CHECK_POINTER_LABEL_LL((_NPT_LocalLogger),NPT_LOG_LEVEL_FINEST,(_p),_label) +#define NPT_CHECK_POINTER_LABEL_FINEST_L(_logger,_p,_label) NPT_CHECK_POINTER_LABEL_LL(_logger,NPT_LOG_LEVEL_FINEST,(_p),_label) + +#endif /* _NPT_LOGGING_H_ */ diff --git a/modules/platinum/SDK/include/NptMap.h b/modules/platinum/SDK/include/NptMap.h new file mode 100644 index 0000000..dd1e337 --- /dev/null +++ b/modules/platinum/SDK/include/NptMap.h @@ -0,0 +1,330 @@ +/***************************************************************** +| +| Neptune - Maps +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| +****************************************************************/ + +#ifndef _NPT_MAP_H_ +#define _NPT_MAP_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptResults.h" +#include "NptList.h" + +/*---------------------------------------------------------------------- +| NPT_Map ++---------------------------------------------------------------------*/ +template <typename K, typename V> +class NPT_Map +{ +public: + // types + class Entry { + public: + // constructor + Entry(const K& key, const V& value) : m_Key(key), m_Value(value) {} + Entry(const K& key) : m_Key(key) {} + + // accessors + const K& GetKey() const { return m_Key; } + const V& GetValue() const { return m_Value; } + + // operators + bool operator==(const Entry& other) const { + return m_Key == other.m_Key && m_Value == other.m_Value; + } + + protected: + // methods + void SetValue(const V& value) { m_Value = value; } + + // members + K m_Key; + V m_Value; + + // friends + friend class NPT_Map<K,V>; + }; + + class EntryValueDeleter { + public: + void operator()(Entry* entry) const { + delete entry->GetValue(); + } + }; + + // constructors + NPT_Map<K,V>() {} + NPT_Map<K,V>(const NPT_Map<K,V>& copy); + + // destructor + ~NPT_Map<K,V>(); + + // methods + NPT_Result Put(const K& key, const V& value); + NPT_Result Get(const K& key, V*& value) const; + bool HasKey(const K& key) const { return GetEntry(key) != NULL; } + bool HasValue(const V& value) const; + NPT_Result Erase(const K& key); + NPT_Cardinal GetEntryCount() const { return m_Entries.GetItemCount(); } + const NPT_List<Entry*>& GetEntries() const { return m_Entries; } + NPT_Result Clear(); + + // operators + V& operator[](const K& key); + const NPT_Map<K,V>& operator=(const NPT_Map<K,V>& copy); + bool operator==(const NPT_Map<K,V>& other) const; + bool operator!=(const NPT_Map<K,V>& other) const; + +private: + // types + typedef typename NPT_List<Entry*>::Iterator ListIterator; + + // methods + Entry* GetEntry(const K& key) const; + + // members + NPT_List<Entry*> m_Entries; +}; + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::NPT_Map<K,V> ++---------------------------------------------------------------------*/ +template <typename K, typename V> +NPT_Map<K,V>::NPT_Map(const NPT_Map<K,V>& copy) +{ + *this = copy; +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::~NPT_Map<K,V> ++---------------------------------------------------------------------*/ +template <typename K, typename V> +inline +NPT_Map<K,V>::~NPT_Map() +{ + // call Clear to ensure we delete all entry objects + Clear(); +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::Clear ++---------------------------------------------------------------------*/ +template <typename K, typename V> +inline +NPT_Result +NPT_Map<K,V>::Clear() +{ + m_Entries.Apply(NPT_ObjectDeleter<Entry>()); + m_Entries.Clear(); + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::GetEntry ++---------------------------------------------------------------------*/ +template <typename K, typename V> +typename NPT_Map<K,V>::Entry* +NPT_Map<K,V>::GetEntry(const K& key) const +{ + typename NPT_List<Entry*>::Iterator entry = m_Entries.GetFirstItem(); + while (entry) { + if ((*entry)->GetKey() == key) { + return *entry; + } + ++entry; + } + + return NULL; +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::Put ++---------------------------------------------------------------------*/ +template <typename K, typename V> +inline +NPT_Result +NPT_Map<K,V>::Put(const K& key, const V& value) +{ + Entry* entry = GetEntry(key); + if (entry == NULL) { + // no existing entry for that key, create one + m_Entries.Add(new Entry(key, value)); + } else { + // replace the existing entry for that key + entry->SetValue(value); + } + + return NPT_SUCCESS; +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::Get ++---------------------------------------------------------------------*/ +template <typename K, typename V> +inline +NPT_Result +NPT_Map<K,V>::Get(const K& key, V*& value) const +{ + Entry* entry = GetEntry(key); + if (entry == NULL) { + // no existing entry for that key + value = NULL; + return NPT_ERROR_NO_SUCH_ITEM; + } else { + // found an entry with that key + value = &entry->m_Value; + return NPT_SUCCESS; + } +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::HasValue ++---------------------------------------------------------------------*/ +template <typename K, typename V> +bool +NPT_Map<K,V>::HasValue(const V& value) const +{ + ListIterator entry = m_Entries.GetFirstItem(); + while (entry) { + if (value == (*entry)->m_Value) { + return true; + } + ++entry; + } + + return false; +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::operator= ++---------------------------------------------------------------------*/ +template <typename K, typename V> +const NPT_Map<K,V>& +NPT_Map<K,V>::operator=(const NPT_Map<K,V>& copy) +{ + // do nothing if we're assigning to ourselves + if (this == ©) return copy; + + // destroy all entries + Clear(); + + // copy all entries one by one + ListIterator entry = copy.m_Entries.GetFirstItem(); + while (entry) { + m_Entries.Add(new Entry((*entry)->GetKey(), (*entry)->GetValue())); + ++entry; + } + + return *this; +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::Erase ++---------------------------------------------------------------------*/ +template <typename K, typename V> +inline +NPT_Result +NPT_Map<K,V>::Erase(const K& key) +{ + ListIterator entry = m_Entries.GetFirstItem(); + while (entry) { + if ((*entry)->GetKey() == key) { + delete *entry; // do this before removing the entry from the + // list, because Erase() will invalidate the + // iterator item + m_Entries.Erase(entry); + return NPT_SUCCESS; + } + ++entry; + } + + return NPT_ERROR_NO_SUCH_ITEM; +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::operator== ++---------------------------------------------------------------------*/ +template <typename K, typename V> +bool +NPT_Map<K,V>::operator==(const NPT_Map<K,V>& other) const +{ + // quick test + if (m_Entries.GetItemCount() != other.m_Entries.GetItemCount()) return false; + + // compare all entries to all other entries + ListIterator entry = m_Entries.GetFirstItem(); + while (entry) { + V* value; + if (NPT_SUCCEEDED(other.Get((*entry)->m_Key, value))) { + // the other map has an entry for this key, check the value + if (!(*value == (*entry)->m_Value)) return false; + } else { + // the other map does not have an entry for this key + return false; + } + ++entry; + } + + return true; +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::operator!= ++---------------------------------------------------------------------*/ +template <typename K, typename V> +inline +bool +NPT_Map<K,V>::operator!=(const NPT_Map<K,V>& other) const +{ + return !(*this == other); +} + +/*---------------------------------------------------------------------- +| NPT_Map<K,V>::operator[] ++---------------------------------------------------------------------*/ +template <typename K, typename V> +inline +V& +NPT_Map<K,V>::operator[](const K& key) +{ + Entry* entry = GetEntry(key); + if (entry == NULL) { + // create a new "default" entry for this key + entry = new Entry(key); + m_Entries.Add(entry); + } + + return entry->m_Value; +} + +#endif // _NPT_MAP_H_ diff --git a/modules/platinum/SDK/include/NptMessaging.h b/modules/platinum/SDK/include/NptMessaging.h new file mode 100644 index 0000000..72d5d4f --- /dev/null +++ b/modules/platinum/SDK/include/NptMessaging.h @@ -0,0 +1,176 @@ +/***************************************************************** +| +| Neptune - Messaging System +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_MESSAGING_H_ +#define _NPT_MESSAGING_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConstants.h" +#include "NptTypes.h" +#include "NptResults.h" +#include "NptList.h" +#include "NptDynamicCast.h" + +/*---------------------------------------------------------------------- +| forward references ++---------------------------------------------------------------------*/ +class NPT_Message; + +/*---------------------------------------------------------------------- +| NPT_MessageHandler ++---------------------------------------------------------------------*/ +class NPT_MessageHandler +{ +public: + NPT_IMPLEMENT_DYNAMIC_CAST(NPT_MessageHandler) + + // methods + virtual ~NPT_MessageHandler() {} + + // default message handler + virtual void OnMessage(NPT_Message*) {} + + // this method is a central point of handling for received messages. + // it can be overloaded by subclasses who wish to process all + // incoming messages + virtual NPT_Result HandleMessage(NPT_Message* message); +}; + +/*---------------------------------------------------------------------- +| NPT_Messsage ++---------------------------------------------------------------------*/ +class NPT_Message +{ +public: + // types + typedef const char* Type; + + // static members + static Type MessageType; + + // methods + virtual ~NPT_Message() {} + virtual Type GetType() { return MessageType; } + virtual NPT_Result Dispatch(NPT_MessageHandler* handler) { + return DefaultDeliver(handler); + } + // this method should really be called 'Deliver', but this would + // cause a problem when subclasses overload it + virtual NPT_Result DefaultDeliver(NPT_MessageHandler* handler) { + handler->OnMessage(this); + return NPT_SUCCESS; + } +}; + +/*---------------------------------------------------------------------- +| NPT_TerminateMesssage ++---------------------------------------------------------------------*/ +class NPT_TerminateMessage : public NPT_Message +{ + public: + // methods + NPT_Result Dispatch(NPT_MessageHandler* /*handler*/) { + return NPT_ERROR_TERMINATED; + } +}; + +/*---------------------------------------------------------------------- +| NPT_MessageQueue ++---------------------------------------------------------------------*/ +class NPT_MessageQueue +{ + public: + // methods + virtual ~NPT_MessageQueue() {} + virtual NPT_Result PumpMessage(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; + virtual NPT_Result QueueMessage(NPT_Message* message, + NPT_MessageHandler* handler) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_MessageReceiver ++---------------------------------------------------------------------*/ +class NPT_MessageReceiver +{ +public: + // methods + NPT_MessageReceiver() : m_Queue(NULL), m_Handler(NULL) {} + NPT_MessageReceiver(NPT_MessageHandler* handler) : + m_Queue(NULL), m_Handler(handler) {} + NPT_MessageReceiver(NPT_MessageQueue* queue) : + m_Queue(queue), m_Handler(NULL) {} + NPT_MessageReceiver(NPT_MessageHandler* handler, + NPT_MessageQueue* queue) : + m_Queue(queue), m_Handler(handler) {} + virtual ~NPT_MessageReceiver() {} + NPT_Result SetQueue(NPT_MessageQueue* queue) { + m_Queue = queue; + return NPT_SUCCESS; + } + NPT_Result SetHandler(NPT_MessageHandler* handler) { + m_Handler = handler; + return NPT_SUCCESS; + } + virtual NPT_Result PostMessage(NPT_Message* message) { + if (m_Queue) { + return m_Queue->QueueMessage(message, m_Handler); + } else { + return NPT_FAILURE; + } + } + +protected: + // members + NPT_MessageQueue* m_Queue; + NPT_MessageHandler* m_Handler; +}; + +/*---------------------------------------------------------------------- +| NPT_MessageBroadcaster ++---------------------------------------------------------------------*/ +class NPT_MessageBroadcaster +{ +public: + // methods + NPT_MessageBroadcaster(NPT_Message* message) : m_Message(message) {} + NPT_Result operator()(NPT_MessageReceiver*& receiver) const { + receiver->PostMessage(m_Message); + return NPT_SUCCESS; + } + +private: + // members + NPT_Message* m_Message; +}; + +#endif // _NPT_MESSAGING_H_ diff --git a/modules/platinum/SDK/include/NptNetwork.h b/modules/platinum/SDK/include/NptNetwork.h new file mode 100644 index 0000000..ca5dc46 --- /dev/null +++ b/modules/platinum/SDK/include/NptNetwork.h @@ -0,0 +1,228 @@ +/***************************************************************** +| +| Neptune - Network +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_NETWORK_H_ +#define _NPT_NETWORK_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptConstants.h" +#include "NptStrings.h" +#include "NptList.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const unsigned int NPT_NETWORK_MAX_MAC_ADDRESS_LENGTH = 8; + +/*---------------------------------------------------------------------- +| flags ++---------------------------------------------------------------------*/ +#define NPT_NETWORK_INTERFACE_FLAG_LOOPBACK 0x01 +#define NPT_NETWORK_INTERFACE_FLAG_PROMISCUOUS 0x02 +#define NPT_NETWORK_INTERFACE_FLAG_BROADCAST 0x04 +#define NPT_NETWORK_INTERFACE_FLAG_MULTICAST 0x08 +#define NPT_NETWORK_INTERFACE_FLAG_POINT_TO_POINT 0x10 + +/*---------------------------------------------------------------------- +| workarounds ++---------------------------------------------------------------------*/ +#if defined(_WIN32) +#if defined(SetPort) +#undef SetPort +#endif +#endif + +/*---------------------------------------------------------------------- +| types ++---------------------------------------------------------------------*/ +typedef unsigned int NPT_IpPort; + +/*---------------------------------------------------------------------- +| NPT_IpAddress ++---------------------------------------------------------------------*/ +class NPT_IpAddress +{ +public: + // class members + static const NPT_IpAddress Any; + + // constructors and destructor + NPT_IpAddress(); + NPT_IpAddress(unsigned long address); + + // methods + NPT_Result ResolveName(const char* name, + NPT_Timeout timeout = NPT_TIMEOUT_INFINITE); + NPT_Result Parse(const char* name); + NPT_Result Set(unsigned long address); + NPT_Result Set(const unsigned char bytes[4]); + const unsigned char* AsBytes() const; + unsigned long AsLong() const; + NPT_String ToString() const; + + // operators + bool operator==(const NPT_IpAddress& other) const; + +private: + // members + unsigned char m_Address[4]; +}; + +/*---------------------------------------------------------------------- +| NPT_MacAddress ++---------------------------------------------------------------------*/ +class NPT_MacAddress +{ +public: + // typedef enum + typedef enum { + TYPE_UNKNOWN, + TYPE_LOOPBACK, + TYPE_ETHERNET, + TYPE_PPP, + TYPE_IEEE_802_11 + } Type; + + // constructors and destructor + NPT_MacAddress() : m_Type(TYPE_UNKNOWN), m_Length(0) {} + NPT_MacAddress(Type type, + const unsigned char* addr, + unsigned int length); + + // methods + void SetAddress(Type type, const unsigned char* addr, + unsigned int length); + Type GetType() const { return m_Type; } + const unsigned char* GetAddress() const { return m_Address; } + unsigned int GetLength() const { return m_Length; } + NPT_String ToString() const; + +private: + // members + Type m_Type; + unsigned char m_Address[NPT_NETWORK_MAX_MAC_ADDRESS_LENGTH]; + unsigned int m_Length; +}; + +/*---------------------------------------------------------------------- +| NPT_NetworkInterfaceAddress ++---------------------------------------------------------------------*/ +class NPT_NetworkInterfaceAddress +{ +public: + // constructors and destructor + NPT_NetworkInterfaceAddress(const NPT_IpAddress& primary, + const NPT_IpAddress& broadcast, + const NPT_IpAddress& destination, + const NPT_IpAddress& netmask) : + m_PrimaryAddress(primary), + m_BroadcastAddress(broadcast), + m_DestinationAddress(destination), + m_NetMask(netmask) {} + + // methods + const NPT_IpAddress& GetPrimaryAddress() const { + return m_PrimaryAddress; + } + const NPT_IpAddress& GetBroadcastAddress() const { + return m_BroadcastAddress; + } + const NPT_IpAddress& GetDestinationAddress() const { + return m_DestinationAddress; + } + const NPT_IpAddress& GetNetMask() const { + return m_NetMask; + } + + bool IsAddressInNetwork(const NPT_IpAddress& adress) { + if (m_PrimaryAddress.AsLong() == adress.AsLong()) return true; + if (m_NetMask.AsLong() == 0) return false; + return (m_PrimaryAddress.AsLong() & m_NetMask.AsLong()) == (adress.AsLong() & m_NetMask.AsLong()); + } + +private: + // members + NPT_IpAddress m_PrimaryAddress; + NPT_IpAddress m_BroadcastAddress; + NPT_IpAddress m_DestinationAddress; + NPT_IpAddress m_NetMask; +}; + +/*---------------------------------------------------------------------- +| NPT_NetworkInterface ++---------------------------------------------------------------------*/ +class NPT_NetworkInterface +{ +public: + // class methods + static NPT_Result GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& interfaces); + + // constructors and destructor + NPT_NetworkInterface(const char* name, + const NPT_MacAddress& mac, + NPT_Flags flags); + ~NPT_NetworkInterface() {} + + // methods + NPT_Result AddAddress(const NPT_NetworkInterfaceAddress& address); + const NPT_String& GetName() const { + return m_Name; + } + const NPT_MacAddress& GetMacAddress() const { + return m_MacAddress; + } + NPT_Flags GetFlags() const { return m_Flags; } + const NPT_List<NPT_NetworkInterfaceAddress>& GetAddresses() const { + return m_Addresses; + } + + bool IsAddressInNetwork(const NPT_IpAddress& address) { + NPT_List<NPT_NetworkInterfaceAddress>::Iterator iter = m_Addresses.GetFirstItem(); + while (iter) { + if ((*iter).IsAddressInNetwork(address)) return true; + ++iter; + } + return false; + } + +private: + // members + NPT_String m_Name; + NPT_MacAddress m_MacAddress; + NPT_Flags m_Flags; + NPT_List<NPT_NetworkInterfaceAddress> m_Addresses; +}; + + +#endif // _NPT_NETWORK_H_ diff --git a/modules/platinum/SDK/include/NptQueue.h b/modules/platinum/SDK/include/NptQueue.h new file mode 100644 index 0000000..b153235 --- /dev/null +++ b/modules/platinum/SDK/include/NptQueue.h @@ -0,0 +1,96 @@ +/***************************************************************** +| +| Neptune - Queue +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_QUEUE_H_ +#define _NPT_QUEUE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptConstants.h" + +/*---------------------------------------------------------------------- +| NPT_QueueItem ++---------------------------------------------------------------------*/ +class NPT_QueueItem; + +/*---------------------------------------------------------------------- +| NPT_GenericQueue ++---------------------------------------------------------------------*/ +class NPT_GenericQueue +{ + public: + // class methods + static NPT_GenericQueue* CreateInstance(NPT_Cardinal max_items = 0); + + // methods + virtual ~NPT_GenericQueue() {} + virtual NPT_Result Push(NPT_QueueItem* item, + NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; + virtual NPT_Result Pop(NPT_QueueItem*& item, + NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; + virtual NPT_Result Peek(NPT_QueueItem*& item, + NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; + protected: + // methods + NPT_GenericQueue() {} +}; + +/*---------------------------------------------------------------------- +| NPT_Queue ++---------------------------------------------------------------------*/ +template <class T> +class NPT_Queue +{ + public: + // methods + NPT_Queue(NPT_Cardinal max_items = 0) : + m_Delegate(NPT_GenericQueue::CreateInstance(max_items)) {} + virtual ~NPT_Queue<T>() { delete m_Delegate; } + virtual NPT_Result Push(T* item, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return m_Delegate->Push(reinterpret_cast<NPT_QueueItem*>(item), timeout); + } + virtual NPT_Result Pop(T*& item, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return m_Delegate->Pop(reinterpret_cast<NPT_QueueItem*&>(item), + timeout); + } + virtual NPT_Result Peek(T*& item, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return m_Delegate->Peek(reinterpret_cast<NPT_QueueItem*&>(item), + timeout); + } + + protected: + // members + NPT_GenericQueue* m_Delegate; +}; + +#endif // _NPT_QUEUE_H_ diff --git a/modules/platinum/SDK/include/NptReferences.h b/modules/platinum/SDK/include/NptReferences.h new file mode 100644 index 0000000..94085ce --- /dev/null +++ b/modules/platinum/SDK/include/NptReferences.h @@ -0,0 +1,146 @@ +/***************************************************************** +| +| Neptune - References +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| +****************************************************************/ + +#ifndef _NPT_REFERENCES_H_ +#define _NPT_REFERENCES_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConstants.h" + +/*---------------------------------------------------------------------- +| NPT_Reference ++---------------------------------------------------------------------*/ +template <typename T> +class NPT_Reference +{ +public: + // constructors and destructor + NPT_Reference() : m_Object(NULL), m_Counter(NULL) {} + explicit NPT_Reference(T* object) : + m_Object(object), m_Counter(object?new NPT_Cardinal(1):NULL) {} + + NPT_Reference(const NPT_Reference<T>& ref) : + m_Object(ref.m_Object), m_Counter(ref.m_Counter) { + if (m_Counter) ++(*m_Counter); + } + + // this methods should be private, but this causes a problem on some + // compilers, because we need this function in order to implement + // the cast operator operator NPT_Reference<U>() below, which would + // have to be marked as a friend, and friend declarations with the + // same class name confuses some compilers + NPT_Reference(T* object, NPT_Cardinal* counter) : + m_Object(object), m_Counter(counter) { + if (m_Counter) ++(*m_Counter); + } + + ~NPT_Reference() { + Release(); + } + + // overloaded operators + NPT_Reference<T>& operator=(const NPT_Reference<T>& ref) { + if (this != &ref) { + Release(); + m_Object = ref.m_Object; + m_Counter = ref.m_Counter; + if (m_Counter) ++(*m_Counter); + } + return *this; + } + NPT_Reference<T>& operator=(T* object) { + Release(); + m_Object = object; + m_Counter = object?new NPT_Cardinal(1):NULL; + return *this; + } + T& operator*() const { return *m_Object; } + T* operator->() const { return m_Object; } + + bool operator==(const NPT_Reference<T>& ref) const { + return m_Object == ref.m_Object; + } + bool operator!=(const NPT_Reference<T>& ref) const { + return m_Object != ref.m_Object; + } + + // overloaded cast operators + template <typename U> operator NPT_Reference<U>() { + return NPT_Reference<U>(m_Object, m_Counter); + } + + // methods + /** + * Returns the naked pointer value. + */ + T* AsPointer() const { return m_Object; } + + /** + * Returns the reference counter value. + */ + NPT_Cardinal GetCounter() const { return *m_Counter; } + + /** + * Returns wether this references a NULL object. + */ + bool IsNull() const { return m_Object == NULL; } + + /** + * Detach the reference from the shared object. + * The reference count is decremented, but the object is not deleted if the + * reference count becomes 0. + * After the method returns, this reference does not point to any shared object. + */ + void Detach() { + if (m_Counter && --(*m_Counter) == 0) { + delete m_Counter; + } + m_Counter = NULL; + m_Object = NULL; + } + +private: + // methods + void Release() { + if (m_Counter && --(*m_Counter) == 0) { + delete m_Counter; m_Counter = NULL; + delete m_Object; m_Object = NULL; + } + } + + // members + T* m_Object; + NPT_Cardinal* m_Counter; +}; + +#endif // _NPT_REFERENCES_H_ diff --git a/modules/platinum/SDK/include/NptResults.h b/modules/platinum/SDK/include/NptResults.h new file mode 100644 index 0000000..be505cf --- /dev/null +++ b/modules/platinum/SDK/include/NptResults.h @@ -0,0 +1,160 @@ +/***************************************************************** +| +| Neptune - Result Codes +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_RESULTS_H_ +#define _NPT_RESULTS_H_ + +/*---------------------------------------------------------------------- +| macros ++---------------------------------------------------------------------*/ +#if defined(NPT_DEBUG) +#include "NptDebug.h" +#define NPT_CHECK(_x) \ +do { \ + NPT_Result _result = (_x); \ + if (_result != NPT_SUCCESS) { \ + NPT_Debug("%s(%d): @@@ NPT_CHECK failed, result=%d (%s)", __FILE__, __LINE__, _result, NPT_ResultText(_result)); \ + return _result; \ + } \ +} while(0) +#define NPT_CHECK_POINTER(_p) \ +do { \ + if ((_p) == NULL) { \ + NPT_Debug("%s(%d): @@@ NULL pointer parameter", __FILE__, __LINE__); \ + return NPT_ERROR_INVALID_PARAMETERS; \ + } \ +} while(0) +#define NPT_CHECK_LABEL(_x, label) \ +do { \ + NPT_Result _result = (_x); \ + if (_result != NPT_SUCCESS) { \ + NPT_Debug("%s(%d): @@@ NPT_CHECK failed, result=%d (%s)", __FILE__, __LINE__, _result, NPT_ResultText(_result)); \ + goto label; \ + } \ +} while(0) +#define NPT_CHECK_POINTER_LABEL(_p, label) \ +do { \ + if (_p == NULL) { \ + NPT_Debug("%s(%d): @@@ NULL pointer parameter", __FILE__, __LINE__); \ + goto label; \ + } \ +} while(0) +#else +#define NPT_CHECK(_x) \ +do { \ + NPT_Result _result = (_x); \ + if (_result != NPT_SUCCESS) { \ + return _result; \ + } \ +} while(0) +#define NPT_CHECK_POINTER(_p) \ +do { \ + if ((_p) == NULL) return NPT_ERROR_INVALID_PARAMETERS; \ +} while(0) +#define NPT_CHECK_LABEL(_x, label) \ +do { \ + NPT_Result _result = (_x); \ + if (_result != NPT_SUCCESS) { \ + goto label; \ + } \ +} while(0) +#define NPT_CHECK_POINTER_LABEL(_p, label) \ +do { \ + if ((_p) == NULL) { \ + goto label; \ + } \ +} while(0) +#endif + +#define NPT_FAILED(result) ((result) != NPT_SUCCESS) +#define NPT_SUCCEEDED(result) ((result) == NPT_SUCCESS) + +/*---------------------------------------------------------------------- +| result codes ++---------------------------------------------------------------------*/ +/** Result indicating that the operation or call succeeded */ +#define NPT_SUCCESS 0 + +/** Result indicating an unspecififed failure condition */ +#define NPT_FAILURE (-1) + +#if !defined(NPT_ERROR_BASE) +#define NPT_ERROR_BASE -20000 +#endif + +// error bases +const int NPT_ERROR_BASE_GENERAL = NPT_ERROR_BASE-0; +const int NPT_ERROR_BASE_LIST = NPT_ERROR_BASE-100; +const int NPT_ERROR_BASE_FILE = NPT_ERROR_BASE-200; +const int NPT_ERROR_BASE_IO = NPT_ERROR_BASE-300; +const int NPT_ERROR_BASE_SOCKET = NPT_ERROR_BASE-400; +const int NPT_ERROR_BASE_INTERFACES = NPT_ERROR_BASE-500; +const int NPT_ERROR_BASE_XML = NPT_ERROR_BASE-600; +const int NPT_ERROR_BASE_UNIX = NPT_ERROR_BASE-700; +const int NPT_ERROR_BASE_HTTP = NPT_ERROR_BASE-800; +const int NPT_ERROR_BASE_THREADS = NPT_ERROR_BASE-900; +const int NPT_ERROR_BASE_SERIAL_PORT = NPT_ERROR_BASE-1000; +const int NPT_ERROR_BASE_TLS = NPT_ERROR_BASE-1100; + +// general errors +const int NPT_ERROR_INVALID_PARAMETERS = NPT_ERROR_BASE_GENERAL - 0; +const int NPT_ERROR_PERMISSION_DENIED = NPT_ERROR_BASE_GENERAL - 1; +const int NPT_ERROR_OUT_OF_MEMORY = NPT_ERROR_BASE_GENERAL - 2; +const int NPT_ERROR_NO_SUCH_NAME = NPT_ERROR_BASE_GENERAL - 3; +const int NPT_ERROR_NO_SUCH_PROPERTY = NPT_ERROR_BASE_GENERAL - 4; +const int NPT_ERROR_NO_SUCH_ITEM = NPT_ERROR_BASE_GENERAL - 5; +const int NPT_ERROR_NO_SUCH_CLASS = NPT_ERROR_BASE_GENERAL - 6; +const int NPT_ERROR_OVERFLOW = NPT_ERROR_BASE_GENERAL - 7; +const int NPT_ERROR_INTERNAL = NPT_ERROR_BASE_GENERAL - 8; +const int NPT_ERROR_INVALID_STATE = NPT_ERROR_BASE_GENERAL - 9; +const int NPT_ERROR_INVALID_FORMAT = NPT_ERROR_BASE_GENERAL - 10; +const int NPT_ERROR_INVALID_SYNTAX = NPT_ERROR_BASE_GENERAL - 11; +const int NPT_ERROR_NOT_IMPLEMENTED = NPT_ERROR_BASE_GENERAL - 12; +const int NPT_ERROR_NOT_SUPPORTED = NPT_ERROR_BASE_GENERAL - 13; +const int NPT_ERROR_TIMEOUT = NPT_ERROR_BASE_GENERAL - 14; +const int NPT_ERROR_WOULD_BLOCK = NPT_ERROR_BASE_GENERAL - 15; +const int NPT_ERROR_TERMINATED = NPT_ERROR_BASE_GENERAL - 16; +const int NPT_ERROR_OUT_OF_RANGE = NPT_ERROR_BASE_GENERAL - 17; +const int NPT_ERROR_OUT_OF_RESOURCES = NPT_ERROR_BASE_GENERAL - 18; + +/* standard error codes */ +/* these are special codes to convey an errno */ +/* the error code is (SHI_ERROR_BASE_ERRNO - errno) */ +/* where errno is the positive integer from errno.h */ +const int NPT_ERROR_BASE_ERRNO = NPT_ERROR_BASE-2000; +#define NPT_ERROR_ERRNO(e) (NPT_ERROR_BASE_ERRNO - (e)) + +/*---------------------------------------------------------------------- +| functions ++---------------------------------------------------------------------*/ +const char* NPT_ResultText(int result); + +#endif // _NPT_RESULTS_H_ diff --git a/modules/platinum/SDK/include/NptRingBuffer.h b/modules/platinum/SDK/include/NptRingBuffer.h new file mode 100644 index 0000000..ceda43f --- /dev/null +++ b/modules/platinum/SDK/include/NptRingBuffer.h @@ -0,0 +1,84 @@ +/***************************************************************** +| +| Neptune - Ring Buffer +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_RING_BUFFER_H_ +#define _NPT_RING_BUFFER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptReferences.h" + +/*---------------------------------------------------------------------- +| NPT_RingBuffer ++---------------------------------------------------------------------*/ +class NPT_RingBuffer +{ + public: + // methods + NPT_RingBuffer(NPT_Size size); + NPT_RingBuffer(void* buffer, NPT_Size size); + virtual ~NPT_RingBuffer(); + NPT_Size GetSpace() const; + NPT_Size GetContiguousSpace() const; + NPT_Result Write(const void* buffer, NPT_Size byte_count); + NPT_Size GetAvailable() const; + NPT_Size GetContiguousAvailable() const; + NPT_Result Read(void* buffer, NPT_Size byte_count); + unsigned char ReadByte(); + unsigned char PeekByte(NPT_Position offset); + NPT_Result MoveIn(NPT_Position offset); + NPT_Result MoveOut(NPT_Position offset); + NPT_Result Flush(); + NPT_Result Close(); + bool IsClosed() { return m_Closed; } + + // accessors + unsigned char* GetWritePointer() { return m_In; } + unsigned char* GetReadPointer() { return m_Out;} + + private: + // members + struct { + unsigned char* start; + unsigned char* end; + } m_Data; + unsigned char* m_In; + unsigned char* m_Out; + NPT_Size m_Size; + bool m_BufferIsLocal; + bool m_Closed; +}; + +typedef NPT_Reference<NPT_RingBuffer> NPT_RingBufferReference; + +#endif // _NPT_RING_BUFFER_H_ diff --git a/modules/platinum/SDK/include/NptSelectableMessageQueue.h b/modules/platinum/SDK/include/NptSelectableMessageQueue.h new file mode 100644 index 0000000..23dd499 --- /dev/null +++ b/modules/platinum/SDK/include/NptSelectableMessageQueue.h @@ -0,0 +1,68 @@ +/***************************************************************** +| +| Neptune - Selectable Message Queue +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_SELECTABLE_MESSAGE_QUEUE_H_ +#define _NPT_SELECTABLE_MESSAGE_QUEUE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptMessaging.h" +#include "NptSimpleMessageQueue.h" + +/*---------------------------------------------------------------------- +| NPT_SelectableMessageQueue ++---------------------------------------------------------------------*/ +class NPT_SelectableMessageQueue : public NPT_SimpleMessageQueue +{ +public: + // methods + NPT_SelectableMessageQueue(); + virtual ~NPT_SelectableMessageQueue(); + + // NPT_MessageQueue methods + virtual NPT_Result PumpMessage(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE); + virtual NPT_Result QueueMessage(NPT_Message* message, + NPT_MessageHandler* handler); + + // methods + int GetEventFd() { return m_Pipe[0]; } + +private: + // methods + NPT_Result FlushEvent(); + + // members + int m_Pipe[2]; +}; + + +#endif /* _NPT_SELECTABLE_MESSAGE_QUEUE_H_ */ diff --git a/modules/platinum/SDK/include/NptSerialPort.h b/modules/platinum/SDK/include/NptSerialPort.h new file mode 100644 index 0000000..1e23a3d --- /dev/null +++ b/modules/platinum/SDK/include/NptSerialPort.h @@ -0,0 +1,119 @@ +/***************************************************************** +| +| Neptune - Serial Ports +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_SERIAL_PORT_H_ +#define _NPT_SERIAL_PORT_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptStreams.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int NPT_ERROR_NO_SUCH_SERIAL_PORT = NPT_ERROR_BASE_SERIAL_PORT - 0; +const int NPT_ERROR_SERIAL_PORT_NOT_OPEN = NPT_ERROR_BASE_SERIAL_PORT - 1; +const int NPT_ERROR_SERIAL_PORT_ALREADY_OPEN = NPT_ERROR_BASE_SERIAL_PORT - 2; +const int NPT_ERROR_SERIAL_PORT_BUSY = NPT_ERROR_BASE_SERIAL_PORT - 3; + +typedef enum { + NPT_SERIAL_PORT_PARITY_NONE, + NPT_SERIAL_PORT_PARITY_EVEN, + NPT_SERIAL_PORT_PARITY_ODD, + NPT_SERIAL_PORT_PARITY_MARK +} NPT_SerialPortParity; + +typedef enum { + NPT_SERIAL_PORT_STOP_BITS_1, + NPT_SERIAL_PORT_STOP_BITS_1_5, + NPT_SERIAL_PORT_STOP_BITS_2 +} NPT_SerialPortStopBits; + +typedef enum { + NPT_SERIAL_PORT_FLOW_CONTROL_NONE, + NPT_SERIAL_PORT_FLOW_CONTROL_HARDWARE, + NPT_SERIAL_PORT_FLOW_CONTROL_XON_XOFF +} NPT_SerialPortFlowControl; + +/*---------------------------------------------------------------------- +| NPT_SerialPortInterface ++---------------------------------------------------------------------*/ +class NPT_SerialPortInterface +{ +public: + // constructors and destructor + virtual ~NPT_SerialPortInterface() {} + + // methods + virtual NPT_Result Open(unsigned int speed, + NPT_SerialPortStopBits stop_bits, + NPT_SerialPortFlowControl flow_control, + NPT_SerialPortParity parity) = 0; + virtual NPT_Result Close() = 0; + virtual NPT_Result GetInputStream(NPT_InputStreamReference& stream) = 0; + virtual NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_SerialPort ++---------------------------------------------------------------------*/ +class NPT_SerialPort : public NPT_SerialPortInterface +{ +public: + // constructors and destructor + NPT_SerialPort(const char* name); + ~NPT_SerialPort() { delete m_Delegate; } + + // NPT_SerialPortInterface methods + NPT_Result Open(unsigned int speed, + NPT_SerialPortStopBits stop_bits = NPT_SERIAL_PORT_STOP_BITS_1, + NPT_SerialPortFlowControl flow_control = NPT_SERIAL_PORT_FLOW_CONTROL_NONE, + NPT_SerialPortParity parity = NPT_SERIAL_PORT_PARITY_NONE) { + return m_Delegate->Open(speed, stop_bits, flow_control, parity); + } + NPT_Result Close() { + return m_Delegate->Close(); + } + NPT_Result GetInputStream(NPT_InputStreamReference& stream) { + return m_Delegate->GetInputStream(stream); + } + NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) { + return m_Delegate->GetOutputStream(stream); + } + +protected: + // members + NPT_SerialPortInterface* m_Delegate; +}; + +#endif // _NPT_SERIAL_PORT_H_ diff --git a/modules/platinum/SDK/include/NptSimpleMessageQueue.h b/modules/platinum/SDK/include/NptSimpleMessageQueue.h new file mode 100644 index 0000000..82b3d91 --- /dev/null +++ b/modules/platinum/SDK/include/NptSimpleMessageQueue.h @@ -0,0 +1,68 @@ +/***************************************************************** +| +| Neptune - Simple Message Queue +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_SIMPLE_MESSAGE_QUEUE_H_ +#define _NPT_SIMPLE_MESSAGE_QUEUE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptThreads.h" +#include "NptMessaging.h" +#include "NptQueue.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +struct NPT_SimpleMessageCapsule; + +/*---------------------------------------------------------------------- +| NPT_SimpleMessageQueue ++---------------------------------------------------------------------*/ +class NPT_SimpleMessageQueue : public NPT_MessageQueue +{ + public: + // members + NPT_SimpleMessageQueue(); + virtual ~NPT_SimpleMessageQueue(); + + // NPT_MessageQueue methods + virtual NPT_Result QueueMessage(NPT_Message* message, + NPT_MessageHandler* handler); + virtual NPT_Result PumpMessage(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE); + + private: + // members + NPT_Queue<NPT_SimpleMessageCapsule> m_Queue; +}; + +#endif // _NPT_SIMPLE_MESSAGE_QUEUE_H_ diff --git a/modules/platinum/SDK/include/NptSockets.h b/modules/platinum/SDK/include/NptSockets.h new file mode 100644 index 0000000..cccea14 --- /dev/null +++ b/modules/platinum/SDK/include/NptSockets.h @@ -0,0 +1,335 @@ +/***************************************************************** +| +| Neptune - Network Sockets +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_SOCKETS_H_ +#define _NPT_SOCKETS_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptConstants.h" +#include "NptStreams.h" +#include "NptStrings.h" +#include "NptDataBuffer.h" +#include "NptNetwork.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int NPT_ERROR_CONNECTION_RESET = NPT_ERROR_BASE_SOCKET - 0; +const int NPT_ERROR_CONNECTION_ABORTED = NPT_ERROR_BASE_SOCKET - 1; +const int NPT_ERROR_CONNECTION_REFUSED = NPT_ERROR_BASE_SOCKET - 2; +const int NPT_ERROR_CONNECTION_FAILED = NPT_ERROR_BASE_SOCKET - 3; +const int NPT_ERROR_HOST_UNKNOWN = NPT_ERROR_BASE_SOCKET - 4; +const int NPT_ERROR_SOCKET_FAILED = NPT_ERROR_BASE_SOCKET - 5; +const int NPT_ERROR_GETSOCKOPT_FAILED = NPT_ERROR_BASE_SOCKET - 6; +const int NPT_ERROR_SETSOCKOPT_FAILED = NPT_ERROR_BASE_SOCKET - 7; +const int NPT_ERROR_SOCKET_CONTROL_FAILED = NPT_ERROR_BASE_SOCKET - 8; +const int NPT_ERROR_BIND_FAILED = NPT_ERROR_BASE_SOCKET - 9; +const int NPT_ERROR_LISTEN_FAILED = NPT_ERROR_BASE_SOCKET - 10; +const int NPT_ERROR_ACCEPT_FAILED = NPT_ERROR_BASE_SOCKET - 11; +const int NPT_ERROR_ADDRESS_IN_USE = NPT_ERROR_BASE_SOCKET - 12; +const int NPT_ERROR_NETWORK_DOWN = NPT_ERROR_BASE_SOCKET - 13; +const int NPT_ERROR_NETWORK_UNREACHABLE = NPT_ERROR_BASE_SOCKET - 14; + +/*---------------------------------------------------------------------- +| forward references ++---------------------------------------------------------------------*/ +class NPT_Socket; + +/*---------------------------------------------------------------------- +| NPT_SocketAddress ++---------------------------------------------------------------------*/ +class NPT_SocketAddress +{ +public: + // constructors and destructor + NPT_SocketAddress() : m_Port(0) {} + NPT_SocketAddress(const NPT_IpAddress& address, NPT_IpPort port) : + m_IpAddress(address), + m_Port(port) {} + + // methods + NPT_Result SetIpAddress(const NPT_IpAddress& address) { + m_IpAddress = address; + return NPT_SUCCESS; + } + const NPT_IpAddress& GetIpAddress() const { + return m_IpAddress; + } + NPT_Result SetPort(NPT_IpPort port) { + m_Port = port; + return NPT_SUCCESS; + } + NPT_IpPort GetPort() const { + return m_Port; + } + NPT_String ToString() const; + + // operators + bool operator==(const NPT_SocketAddress& other) const; + +private: + // members + NPT_IpAddress m_IpAddress; + NPT_IpPort m_Port; +}; + +/*---------------------------------------------------------------------- +| NPT_SocketInfo ++---------------------------------------------------------------------*/ +typedef struct { + NPT_SocketAddress local_address; + NPT_SocketAddress remote_address; +} NPT_SocketInfo; + +/*---------------------------------------------------------------------- +| NPT_SocketInterface ++---------------------------------------------------------------------*/ +class NPT_SocketInterface +{ + public: + virtual ~NPT_SocketInterface() {} + + // interface methods + virtual NPT_Result Bind(const NPT_SocketAddress& address, bool reuse_address = true) = 0; + virtual NPT_Result Connect(const NPT_SocketAddress& address, NPT_Timeout timeout) = 0; + virtual NPT_Result Disconnect() = 0; + virtual NPT_Result WaitForConnection(NPT_Timeout timeout) = 0; + virtual NPT_Result GetInputStream(NPT_InputStreamReference& stream) = 0; + virtual NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) = 0; + virtual NPT_Result GetInfo(NPT_SocketInfo& info) = 0; + virtual NPT_Result SetBlockingMode(bool blocking) = 0; + virtual NPT_Result SetReadTimeout(NPT_Timeout timeout) = 0; + virtual NPT_Result SetWriteTimeout(NPT_Timeout timeout) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_UdpSocketInterface ++---------------------------------------------------------------------*/ +class NPT_UdpSocketInterface +{ + public: + virtual ~NPT_UdpSocketInterface() {} + + // methods + virtual NPT_Result Send(const NPT_DataBuffer& packet, + const NPT_SocketAddress* address = NULL) = 0; + virtual NPT_Result Receive(NPT_DataBuffer& packet, + NPT_SocketAddress* address = NULL) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_UdpMulticastSocketInterface ++---------------------------------------------------------------------*/ +class NPT_UdpMulticastSocketInterface +{ + public: + virtual ~NPT_UdpMulticastSocketInterface() {} + + // methods + virtual NPT_Result JoinGroup(const NPT_IpAddress& group, + const NPT_IpAddress& iface) = 0; + virtual NPT_Result LeaveGroup(const NPT_IpAddress& group, + const NPT_IpAddress& iface) = 0; + virtual NPT_Result SetTimeToLive(unsigned char ttl) = 0; + virtual NPT_Result SetInterface(const NPT_IpAddress& iface) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_TcpServerSocketInterface ++---------------------------------------------------------------------*/ +class NPT_TcpServerSocketInterface +{ + public: + virtual ~NPT_TcpServerSocketInterface() {} + + // interface methods + virtual NPT_Result Listen(unsigned int max_clients) = 0; + virtual NPT_Result WaitForNewClient(NPT_Socket*& client, + NPT_Timeout timeout) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_Socket ++---------------------------------------------------------------------*/ +class NPT_Socket : public NPT_SocketInterface +{ +public: + // constructor and destructor + NPT_Socket(NPT_SocketInterface* delegate) : + m_SocketDelegate(delegate) {} + virtual ~NPT_Socket(); + + // delegate NPT_SocketInterface methods + NPT_Result Bind(const NPT_SocketAddress& address, bool reuse_address = true) { + return m_SocketDelegate->Bind(address, reuse_address); + } + NPT_Result Connect(const NPT_SocketAddress& address, + NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return m_SocketDelegate->Connect(address, timeout); + } + NPT_Result Disconnect() { + return m_SocketDelegate->Disconnect(); + } + NPT_Result WaitForConnection(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return m_SocketDelegate->WaitForConnection(timeout); + } + NPT_Result GetInputStream(NPT_InputStreamReference& stream) { + return m_SocketDelegate->GetInputStream(stream); + } + NPT_Result GetOutputStream(NPT_OutputStreamReference& stream) { + return m_SocketDelegate->GetOutputStream(stream); + } + NPT_Result GetInfo(NPT_SocketInfo& info) { + return m_SocketDelegate->GetInfo(info); + } + NPT_Result SetBlockingMode(bool blocking) { + return m_SocketDelegate->SetBlockingMode(blocking); + } + NPT_Result SetReadTimeout(NPT_Timeout timeout) { + return m_SocketDelegate->SetReadTimeout(timeout); + } + NPT_Result SetWriteTimeout(NPT_Timeout timeout) { + return m_SocketDelegate->SetWriteTimeout(timeout); + } + +protected: + // constructor + NPT_Socket() {} + + // members + NPT_SocketInterface* m_SocketDelegate; +}; + +typedef NPT_Reference<NPT_Socket> NPT_SocketReference; + +/*---------------------------------------------------------------------- +| NPT_UdpSocket ++---------------------------------------------------------------------*/ +class NPT_UdpSocket : public NPT_Socket, + public NPT_UdpSocketInterface +{ + public: + // constructor and destructor + NPT_UdpSocket(); + virtual ~NPT_UdpSocket(); + + // delegate NPT_UdpSocketInterface methods + NPT_Result Send(const NPT_DataBuffer& packet, + const NPT_SocketAddress* address = NULL) { + return m_UdpSocketDelegate->Send(packet, address); + } + NPT_Result Receive(NPT_DataBuffer& packet, + NPT_SocketAddress* address = NULL) { + return m_UdpSocketDelegate->Receive(packet, address); + } + +protected: + // constructor + NPT_UdpSocket(NPT_UdpSocketInterface* delegate); + + // members + NPT_UdpSocketInterface* m_UdpSocketDelegate; +}; + +/*---------------------------------------------------------------------- +| NPT_UdpMulticastSocket ++---------------------------------------------------------------------*/ +class NPT_UdpMulticastSocket : public NPT_UdpSocket, + public NPT_UdpMulticastSocketInterface +{ +public: + // constructor and destructor + NPT_UdpMulticastSocket(); + virtual ~NPT_UdpMulticastSocket(); + + // delegate NPT_UdpMulticastSocketInterface methods + NPT_Result JoinGroup(const NPT_IpAddress& group, + const NPT_IpAddress& iface = + NPT_IpAddress::Any) { + return m_UdpMulticastSocketDelegate->JoinGroup(group, iface); + } + NPT_Result LeaveGroup(const NPT_IpAddress& group, + const NPT_IpAddress& iface = + NPT_IpAddress::Any) { + return m_UdpMulticastSocketDelegate->LeaveGroup(group, iface); + } + NPT_Result SetTimeToLive(unsigned char ttl) { + return m_UdpMulticastSocketDelegate->SetTimeToLive(ttl); + } + NPT_Result SetInterface(const NPT_IpAddress& iface) { + return m_UdpMulticastSocketDelegate->SetInterface(iface); + } + +protected: + // members + NPT_UdpMulticastSocketInterface* m_UdpMulticastSocketDelegate; +}; + +/*---------------------------------------------------------------------- +| NPT_TcpClientSocket ++---------------------------------------------------------------------*/ +class NPT_TcpClientSocket : public NPT_Socket +{ +public: + // constructors and destructor + NPT_TcpClientSocket(); + virtual ~NPT_TcpClientSocket(); +}; + +/*---------------------------------------------------------------------- +| NPT_TcpServerSocket ++---------------------------------------------------------------------*/ +class NPT_TcpServerSocket : public NPT_Socket, + public NPT_TcpServerSocketInterface +{ +public: + // constructors and destructor + NPT_TcpServerSocket(); + virtual ~NPT_TcpServerSocket(); + + // delegate NPT_TcpServerSocketInterface methods + NPT_Result Listen(unsigned int max_clients) { + return m_TcpServerSocketDelegate->Listen(max_clients); + } + NPT_Result WaitForNewClient(NPT_Socket*& client, + NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return m_TcpServerSocketDelegate->WaitForNewClient(client, timeout); + } + +protected: + // members + NPT_TcpServerSocketInterface* m_TcpServerSocketDelegate; +}; + +#endif // _NPT_SOCKETS_H_ diff --git a/modules/platinum/SDK/include/NptStack.h b/modules/platinum/SDK/include/NptStack.h new file mode 100644 index 0000000..034b3ec --- /dev/null +++ b/modules/platinum/SDK/include/NptStack.h @@ -0,0 +1,72 @@ +/***************************************************************** +| +| Neptune - Stack +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| +****************************************************************/ + +#ifndef _NPT_STACK_H_ +#define _NPT_STACK_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptResults.h" +#include "NptTypes.h" +#include "NptList.h" + +/*---------------------------------------------------------------------- +| NPT_Stack ++---------------------------------------------------------------------*/ +template <typename T> +class NPT_Stack : public NPT_List<T> +{ +public: + // methods + NPT_Result Push(const T& value) { + return Add(value); + } + + NPT_Result Peek(T& value) { + // NOTE: we must use the this-> accessor here because the standard + // requires it when the member to look up is in a parent template + if (this->m_ItemCount == 0) return NPT_ERROR_NO_SUCH_ITEM; + value = this->m_Tail->m_Data; + return NPT_SUCCESS; + } + + NPT_Result Pop(T& value) { + // NOTE: we must use the this-> accessor here because the standard + // requires it when the member to look up is in a parent template + if (this->m_ItemCount == 0) return NPT_ERROR_NO_SUCH_ITEM; + typename NPT_List<T>::Iterator tail = this->GetLastItem(); + value = *tail; + return this->Erase(tail); + } +}; + +#endif // _NPT_STACK_H_ diff --git a/modules/platinum/SDK/include/NptStreams.h b/modules/platinum/SDK/include/NptStreams.h new file mode 100644 index 0000000..7e49f25 --- /dev/null +++ b/modules/platinum/SDK/include/NptStreams.h @@ -0,0 +1,322 @@ +/***************************************************************** +| +| Neptune - Byte Streams +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_STREAMS_H_ +#define _NPT_STREAMS_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptReferences.h" +#include "NptConstants.h" +#include "NptResults.h" +#include "NptDataBuffer.h" +#include "NptStrings.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class NPT_String; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int NPT_ERROR_READ_FAILED = NPT_ERROR_BASE_IO - 0; +const int NPT_ERROR_WRITE_FAILED = NPT_ERROR_BASE_IO - 1; +const int NPT_ERROR_EOS = NPT_ERROR_BASE_IO - 2; + +/*---------------------------------------------------------------------- +| NPT_InputStream ++---------------------------------------------------------------------*/ +class NPT_InputStream +{ + public: + // constructor and destructor + virtual ~NPT_InputStream() {}; + + // methods + virtual NPT_Result Load(NPT_DataBuffer& buffer, NPT_Size max_read = 0); + virtual NPT_Result Read(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read = NULL) = 0; + virtual NPT_Result ReadFully(void* buffer, + NPT_Size bytes_to_read); + virtual NPT_Result Seek(NPT_Position offset) = 0; + virtual NPT_Result Skip(NPT_Size offset); + virtual NPT_Result Tell(NPT_Position& offset) = 0; + virtual NPT_Result GetSize(NPT_LargeSize& size) = 0; + virtual NPT_Result GetAvailable(NPT_LargeSize& available) = 0; + virtual NPT_Result Close() { return NPT_SUCCESS; } + + // data access methods + NPT_Result ReadUI64(NPT_UInt64& value); + NPT_Result ReadUI32(NPT_UInt32& value); + NPT_Result ReadUI24(NPT_UInt32& value); + NPT_Result ReadUI16(NPT_UInt16& value); + NPT_Result ReadUI08(NPT_UInt8& value); +}; + +typedef NPT_Reference<NPT_InputStream> NPT_InputStreamReference; + +/*---------------------------------------------------------------------- +| NPT_OutputStream ++---------------------------------------------------------------------*/ +class NPT_OutputStream +{ +public: + // constructor and destructor + virtual ~NPT_OutputStream() {}; + + // methods + virtual NPT_Result Write(const void* buffer, + NPT_Size bytes_to_write, + NPT_Size* bytes_written = NULL) = 0; + virtual NPT_Result WriteFully(const void* buffer, + NPT_Size bytes_to_write); + virtual NPT_Result WriteString(const char* string_buffer); + virtual NPT_Result WriteLine(const char* line_buffer); + virtual NPT_Result Seek(NPT_Position offset) = 0; + virtual NPT_Result Tell(NPT_Position& offset) = 0; + virtual NPT_Result Flush() { return NPT_SUCCESS; } + + // data access methods + NPT_Result WriteUI64(NPT_UInt64 value); + NPT_Result WriteUI32(NPT_UInt32 value); + NPT_Result WriteUI24(NPT_UInt32 value); + NPT_Result WriteUI16(NPT_UInt16 value); + NPT_Result WriteUI08(NPT_UInt8 value); +}; + +typedef NPT_Reference<NPT_OutputStream> NPT_OutputStreamReference; + +/*---------------------------------------------------------------------- +| NPT_StreamToStreamCopy ++---------------------------------------------------------------------*/ +NPT_Result NPT_StreamToStreamCopy(NPT_InputStream& from, + NPT_OutputStream& to, + NPT_Position offset = 0, + NPT_LargeSize size = 0, /* 0 means the entire stream */ + NPT_LargeSize* bytes_written = NULL); + +/*---------------------------------------------------------------------- +| NPT_DelegatingInputStream +| +| Use this class as a base class if you need to inherit both from +| NPT_InputStream and NPT_OutputStream which share the Seek and Tell +| method. In this case, you override the base-specific version of +| those methods, InputSeek, InputTell, instead of the Seek and Tell +| methods. ++---------------------------------------------------------------------*/ +class NPT_DelegatingInputStream : public NPT_InputStream +{ +public: + // NPT_InputStream methods + NPT_Result Seek(NPT_Position offset) { + return InputSeek(offset); + } + NPT_Result Tell(NPT_Position& offset) { + return InputTell(offset); + } + +private: + // methods + virtual NPT_Result InputSeek(NPT_Position offset) = 0; + virtual NPT_Result InputTell(NPT_Position& offset) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_DelegatingOutputStream +| +| Use this class as a base class if you need to inherit both from +| NPT_InputStream and NPT_OutputStream which share the Seek and Tell +| method. In this case, you override the base-specific version of +| those methods, OutputSeek and OutputTell, instead of the Seek and +| Tell methods. ++---------------------------------------------------------------------*/ +class NPT_DelegatingOutputStream : public NPT_OutputStream +{ +public: + // NPT_OutputStream methods + NPT_Result Seek(NPT_Position offset) { + return OutputSeek(offset); + } + NPT_Result Tell(NPT_Position& offset) { + return OutputTell(offset); + } + +private: + // methods + virtual NPT_Result OutputSeek(NPT_Position offset) = 0; + virtual NPT_Result OutputTell(NPT_Position& offset) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_MemoryStream ++---------------------------------------------------------------------*/ +class NPT_MemoryStream : + public NPT_DelegatingInputStream, + public NPT_DelegatingOutputStream +{ +public: + // constructor and destructor + NPT_MemoryStream(NPT_Size initial_capacity = 0); + NPT_MemoryStream(const void* data, NPT_Size size); + virtual ~NPT_MemoryStream() {} + + // accessors + const NPT_DataBuffer& GetBuffer() const { return m_Buffer; } + + // NPT_InputStream methods + NPT_Result Read(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read = NULL); + NPT_Result GetSize(NPT_LargeSize& size) { + size = m_Buffer.GetDataSize(); + return NPT_SUCCESS; + } + NPT_Result GetAvailable(NPT_LargeSize& available) { + available = (NPT_LargeSize)m_Buffer.GetDataSize()-m_ReadOffset; + return NPT_SUCCESS; + } + + // NPT_OutputStream methods + NPT_Result Write(const void* buffer, + NPT_Size bytes_to_write, + NPT_Size* bytes_written = NULL); + + // methods delegated to m_Buffer + const NPT_Byte* GetData() const { return m_Buffer.GetData(); } + NPT_Byte* UseData() { return m_Buffer.UseData(); } + NPT_Size GetDataSize() const { return m_Buffer.GetDataSize(); } + NPT_Size GetBufferSize() const { return m_Buffer.GetBufferSize();} + + // methods + NPT_Result SetDataSize(NPT_Size size); + +private: + // NPT_DelegatingInputStream methods + NPT_Result InputSeek(NPT_Position offset); + NPT_Result InputTell(NPT_Position& offset) { + offset = m_ReadOffset; + return NPT_SUCCESS; + } + + // NPT_DelegatingOutputStream methods + NPT_Result OutputSeek(NPT_Position offset); + NPT_Result OutputTell(NPT_Position& offset) { + offset = m_WriteOffset; + return NPT_SUCCESS; + } + +protected: + // members + NPT_DataBuffer m_Buffer; + NPT_Size m_ReadOffset; + NPT_Size m_WriteOffset; +}; + +typedef NPT_Reference<NPT_MemoryStream> NPT_MemoryStreamReference; + +/*---------------------------------------------------------------------- +| NPT_StringOutputStream ++---------------------------------------------------------------------*/ +class NPT_StringOutputStream : public NPT_OutputStream +{ +public: + // methods + NPT_StringOutputStream(NPT_Size size = 4096); + NPT_StringOutputStream(NPT_String* storage); + virtual ~NPT_StringOutputStream() ; + + const NPT_String& GetString() const { return *m_String; } + NPT_Result Reset() { if (m_String) m_String->SetLength(0); return NPT_SUCCESS; } + + // NPT_OutputStream methods + NPT_Result Write(const void* buffer, NPT_Size bytes_to_write, NPT_Size* bytes_written = NULL); + + NPT_Result Seek(NPT_Position /*offset*/) { return NPT_ERROR_NOT_SUPPORTED; } + NPT_Result Tell(NPT_Position& offset) { offset = m_String->GetLength(); return NPT_SUCCESS; } + +protected: + NPT_String* m_String; + bool m_StringIsOwned; +}; + +typedef NPT_Reference<NPT_StringOutputStream> NPT_StringOutputStreamReference; + +/*---------------------------------------------------------------------- +| NPT_SubInputStream ++---------------------------------------------------------------------*/ +class NPT_SubInputStream : public NPT_InputStream +{ +public: + // constructor and destructor + NPT_SubInputStream(NPT_InputStreamReference& source, + NPT_Position start, + NPT_LargeSize size); + + // methods + virtual NPT_Result Read(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read = NULL) = 0; + virtual NPT_Result Seek(NPT_Position offset) = 0; + virtual NPT_Result Tell(NPT_Position& offset) = 0; + virtual NPT_Result GetSize(NPT_LargeSize& size) = 0; + virtual NPT_Result GetAvailable(NPT_LargeSize& available) = 0; + +private: + NPT_InputStreamReference m_Source; + NPT_Position m_Position; + NPT_Position m_Start; + NPT_LargeSize m_Size; +}; + +/*---------------------------------------------------------------------- +| NPT_NullOutputStream ++---------------------------------------------------------------------*/ +class NPT_NullOutputStream : public NPT_OutputStream +{ +public: + // methods + NPT_NullOutputStream() {} + virtual ~NPT_NullOutputStream() {} + + // NPT_OutputStream methods + NPT_Result Write(const void* buffer, NPT_Size bytes_to_write, NPT_Size* bytes_written = NULL); + + NPT_Result Seek(NPT_Position /*offset*/) { return NPT_ERROR_NOT_SUPPORTED; } + NPT_Result Tell(NPT_Position& /*offset*/) { return NPT_ERROR_NOT_SUPPORTED; } +}; + +typedef NPT_Reference<NPT_NullOutputStream> NPT_NullOutputStreamReference; + +#endif // _NPT_STREAMS_H_ diff --git a/modules/platinum/SDK/include/NptStrings.h b/modules/platinum/SDK/include/NptStrings.h new file mode 100644 index 0000000..cbf2522 --- /dev/null +++ b/modules/platinum/SDK/include/NptStrings.h @@ -0,0 +1,339 @@ +/***************************************************************** +| +| Neptune - String Objects +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_STRINGS_H_ +#define _NPT_STRINGS_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConfig.h" +#if defined(NPT_CONFIG_HAVE_NEW_H) +#include <new> +#endif +#include "NptTypes.h" +#include "NptConstants.h" +#include "NptList.h" +#include "NptDebug.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int NPT_STRING_SEARCH_FAILED = -1; + +/*---------------------------------------------------------------------- +| NPT_String ++---------------------------------------------------------------------*/ +class NPT_String +{ +public: + // factories + static NPT_String FromInteger(NPT_Int64 value); + static NPT_String FromIntegerU(NPT_UInt64 value); + static NPT_String Format(const char* format, ...); + + // constructors + NPT_String(const NPT_String& str); + NPT_String(const char* str); + NPT_String(const char* str, NPT_Size length); + NPT_String(const char* str, NPT_Ordinal first, NPT_Size length); + NPT_String(char c, NPT_Cardinal repeat = 1); + NPT_String() : m_Chars(NULL) {} + ~NPT_String() { if (m_Chars) delete GetBuffer(); } + + // string info and manipulations + bool IsEmpty() const { return m_Chars == NULL || GetBuffer()->GetLength() == 0; } + NPT_Size GetLength() const { return m_Chars ? GetBuffer()->GetLength() : 0; } + NPT_Size GetCapacity() const { return m_Chars ? GetBuffer()->GetAllocated() : 0; } + NPT_Result SetLength(NPT_Size length, bool pad = false); + void Assign(const char* chars, NPT_Size size); + void Append(const char* chars, NPT_Size size); + void Append(const char* s) { Append(s, StringLength(s)); } + int Compare(const char* s, bool ignore_case = false) const; + static int Compare(const char* s1, const char* s2, bool ignore_case = false); + int CompareN(const char* s, NPT_Size count, bool ignore_case = false) const; + static int CompareN(const char* s1, const char* s2, NPT_Size count, bool ignore_case = false); + + // substrings + NPT_String SubString(NPT_Ordinal first, NPT_Size length) const; + NPT_String SubString(NPT_Ordinal first) const { + return SubString(first, GetLength()); + } + NPT_String Left(NPT_Size length) const { + return SubString(0, length); + } + NPT_String Right(NPT_Size length) const { + return length >= GetLength() ? + *this : + SubString(GetLength()-length, length); + } + NPT_List<NPT_String> Split(const char* separator) const; + static NPT_String Join(NPT_List<NPT_String>& args, const char* separator); + + // buffer management + void Reserve(NPT_Size length); + + // conversions + NPT_String ToLowercase() const; + NPT_String ToUppercase() const; + NPT_Result ToInteger(int& value, bool relaxed = true) const; + NPT_Result ToInteger(unsigned int& value, bool relaxed = true) const; + NPT_Result ToInteger(long& value, bool relaxed = true) const; + NPT_Result ToInteger(unsigned long& value, bool relaxed = true) const; + NPT_Result ToInteger32(NPT_Int32& value, bool relaxed = true) const; + NPT_Result ToInteger32(NPT_UInt32& value, bool relaxed = true) const; + NPT_Result ToInteger64(NPT_Int64& value, bool relaxed = true) const; + NPT_Result ToInteger64(NPT_UInt64& value, bool relaxed = true) const; + NPT_Result ToFloat(float& value, bool relaxed = true) const; + + // processing + void MakeLowercase(); + void MakeUppercase(); + void Replace(char a, char b); + void Replace(char a, const char* b); + + // search + int Find(char c, NPT_Ordinal start = 0, bool ignore_case = false) const; + int Find(const char* s, NPT_Ordinal start = 0, bool ignore_case = false) const; + int ReverseFind(char c, NPT_Ordinal start = 0, bool ignore_case = false) const; + int ReverseFind(const char* s, NPT_Ordinal start = 0, bool ignore_case = false) const; + bool StartsWith(const char* s, bool ignore_case = false) const; + bool EndsWith(const char* s, bool ignore_case = false) const; + + // editing + void Insert(const char* s, NPT_Ordinal where = 0); + void Erase(NPT_Ordinal start, NPT_Cardinal count = 1); + void Replace(NPT_Ordinal start, NPT_Cardinal count, const char* s); + void TrimLeft(); + void TrimLeft(char c); + void TrimLeft(const char* chars); + void TrimRight(); + void TrimRight(char c); + void TrimRight(const char* chars); + void Trim(); + void Trim(char c); + void Trim(const char* chars); + + // type casting + operator char*() const { return m_Chars ? m_Chars: &EmptyString; } + operator const char* () const { return m_Chars ? m_Chars: &EmptyString; } + const char* GetChars() const { return m_Chars ? m_Chars: &EmptyString; } + char* UseChars() { return m_Chars ? m_Chars: &EmptyString; } + + // operator overloading + NPT_String& operator=(const char* str); + NPT_String& operator=(const NPT_String& str); + NPT_String& operator=(char c); + const NPT_String& operator+=(const NPT_String& s) { + Append(s.GetChars(), s.GetLength()); + return *this; + } + const NPT_String& operator+=(const char* s) { + Append(s); + return *this; + } + const NPT_String& operator+=(char c) { + Append(&c, 1); + return *this; + } + char operator[](int index) const { + NPT_ASSERT((unsigned int)index < GetLength()); + return GetChars()[index]; + } + char& operator[](int index) { + NPT_ASSERT((unsigned int)index < GetLength()); + return UseChars()[index]; + } + + // friend operators + friend NPT_String operator+(const NPT_String& s1, const NPT_String& s2) { + return s1+s2.GetChars(); + } + friend NPT_String operator+(const NPT_String& s1, const char* s2); + friend NPT_String operator+(const char* s1, const NPT_String& s2); + friend NPT_String operator+(const NPT_String& s, char c); + friend NPT_String operator+(char c, const NPT_String& s); + +protected: + // inner classes + class Buffer { + public: + // class methods + static Buffer* Allocate(NPT_Size allocated, NPT_Size length) { + void* mem = ::operator new(sizeof(Buffer)+allocated+1); + return new(mem) Buffer(allocated, length); + } + static char* Create(NPT_Size allocated, NPT_Size length=0) { + Buffer* shared = Allocate(allocated, length); + return shared->GetChars(); + } + static char* Create(const char* copy) { + NPT_Size length = StringLength(copy); + Buffer* shared = Allocate(length, length); + CopyString(shared->GetChars(), copy); + return shared->GetChars(); + } + static char* Create(const char* copy, NPT_Size length) { + Buffer* shared = Allocate(length, length); + CopyBuffer(shared->GetChars(), copy, length); + shared->GetChars()[length] = '\0'; + return shared->GetChars(); + } + static char* Create(char c, NPT_Cardinal repeat) { + Buffer* shared = Allocate(repeat, repeat); + char* s = shared->GetChars(); + while (repeat--) { + *s++ = c; + } + *s = '\0'; + return shared->GetChars(); + } + + // methods + char* GetChars() { + // return a pointer to the first char + return reinterpret_cast<char*>(this+1); + } + NPT_Size GetLength() const { return m_Length; } + void SetLength(NPT_Size length) { m_Length = length; } + NPT_Size GetAllocated() const { return m_Allocated; } + + private: + // methods + Buffer(NPT_Size allocated, NPT_Size length = 0) : + m_Length(length), + m_Allocated(allocated) {} + + // members + NPT_Cardinal m_Length; + NPT_Cardinal m_Allocated; + // the actual string data follows + + }; + + // members + char* m_Chars; + +private: + // friends + friend class Buffer; + + // static members + static char EmptyString; + + // methods + Buffer* GetBuffer() const { + return reinterpret_cast<Buffer*>(m_Chars)-1; + } + void Reset() { + if (m_Chars != NULL) { + delete GetBuffer(); + m_Chars = NULL; + } + } + char* PrepareToWrite(NPT_Size length); + void PrepareToAppend(NPT_Size length, NPT_Size allocate); + + // static methods + static void CopyString(char* dst, const char* src) { + while ((*dst++ = *src++)){} + } + + static void CopyBuffer(char* dst, const char* src, NPT_Size size) { + while (size--) *dst++ = *src++; + } + + static NPT_Size StringLength(const char* str) { + NPT_Size length = 0; + while (*str++) length++; + return length; + } +}; + +/*---------------------------------------------------------------------- +| external operators ++---------------------------------------------------------------------*/ +inline bool operator==(const NPT_String& s1, const NPT_String& s2) { + return s1.Compare(s2) == 0; +} +inline bool operator==(const NPT_String& s1, const char* s2) { + return s1.Compare(s2) == 0; +} +inline bool operator==(const char* s1, const NPT_String& s2) { + return s2.Compare(s1) == 0; +} +inline bool operator!=(const NPT_String& s1, const NPT_String& s2) { + return s1.Compare(s2) != 0; +} +inline bool operator!=(const NPT_String& s1, const char* s2) { + return s1.Compare(s2) != 0; +} +inline bool operator!=(const char* s1, const NPT_String& s2) { + return s2.Compare(s1) != 0; +} +inline bool operator<(const NPT_String& s1, const NPT_String& s2) { + return s1.Compare(s2) < 0; +} +inline bool operator<(const NPT_String& s1, const char* s2) { + return s1.Compare(s2) < 0; +} +inline bool operator<(const char* s1, const NPT_String& s2) { + return s2.Compare(s1) > 0; +} +inline bool operator>(const NPT_String& s1, const NPT_String& s2) { + return s1.Compare(s2) > 0; +} +inline bool operator>(const NPT_String& s1, const char* s2) { + return s1.Compare(s2) > 0; +} +inline bool operator>(const char* s1, const NPT_String& s2) { + return s2.Compare(s1) < 0; +} +inline bool operator<=(const NPT_String& s1, const NPT_String& s2) { + return s1.Compare(s2) <= 0; +} +inline bool operator<=(const NPT_String& s1, const char* s2) { + return s1.Compare(s2) <= 0; +} +inline bool operator<=(const char* s1, const NPT_String& s2) { + return s2.Compare(s1) >= 0; +} +inline bool operator>=(const NPT_String& s1, const NPT_String& s2) { + return s1.Compare(s2) >= 0; +} +inline bool operator>=(const NPT_String& s1, const char* s2) { + return s1.Compare(s2) >= 0; +} +inline bool operator>=(const char* s1, const NPT_String& s2) { + return s2.Compare(s1) <= 0; +} + +#endif // _NPT_STRINGS_H_ diff --git a/modules/platinum/SDK/include/NptSystem.h b/modules/platinum/SDK/include/NptSystem.h new file mode 100644 index 0000000..c79d590 --- /dev/null +++ b/modules/platinum/SDK/include/NptSystem.h @@ -0,0 +1,60 @@ +/***************************************************************** +| +| Neptune - System +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_SYSTEM_H_ +#define _NPT_SYSTEM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptTime.h" + +/*---------------------------------------------------------------------- +| NPT_System ++---------------------------------------------------------------------*/ +class NPT_System +{ +public: + // methods + static NPT_Result GetProcessId(NPT_UInt32& id); + static NPT_Result GetCurrentTimeStamp(NPT_TimeStamp& now); + static NPT_Result Sleep(const NPT_TimeInterval& duration); + static NPT_Result SleepUntil(const NPT_TimeStamp& when); + static NPT_Result SetRandomSeed(unsigned int seed); + static NPT_UInt32 GetRandomInteger(); + +protected: + // constructor + NPT_System() {} +}; + +#endif // _NPT_SYSTEM_H_ diff --git a/modules/platinum/SDK/include/NptThreads.h b/modules/platinum/SDK/include/NptThreads.h new file mode 100644 index 0000000..d79b9ea --- /dev/null +++ b/modules/platinum/SDK/include/NptThreads.h @@ -0,0 +1,283 @@ +/***************************************************************** +| +| Neptune - Threads +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_THREADS_H_ +#define _NPT_THREADS_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptConstants.h" +#include "NptInterfaces.h" + +/*---------------------------------------------------------------------- +| error codes ++---------------------------------------------------------------------*/ +const int NPT_ERROR_CALLBACK_HANDLER_SHUTDOWN = NPT_ERROR_BASE_THREADS-0; +const int NPT_ERROR_CALLBACK_NOTHING_PENDING = NPT_ERROR_BASE_THREADS-1; + +/*---------------------------------------------------------------------- +| NPT_MutexInterface ++---------------------------------------------------------------------*/ +class NPT_MutexInterface +{ + public: + // methods + virtual ~NPT_MutexInterface() {} + virtual NPT_Result Lock() = 0; + virtual NPT_Result Unlock() = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_Mutex ++---------------------------------------------------------------------*/ +class NPT_Mutex : public NPT_MutexInterface +{ + public: + // methods + NPT_Mutex(); + ~NPT_Mutex() { delete m_Delegate; } + NPT_Result Lock() { return m_Delegate->Lock(); } + NPT_Result Unlock() { return m_Delegate->Unlock(); } + + private: + // members + NPT_MutexInterface* m_Delegate; +}; + +/*---------------------------------------------------------------------- +| NPT_AutoLock ++---------------------------------------------------------------------*/ +class NPT_AutoLock +{ + public: + // methods + NPT_AutoLock(NPT_Mutex &mutex) : m_Mutex(mutex) { + m_Mutex.Lock(); + } + ~NPT_AutoLock() { + m_Mutex.Unlock(); + } + + private: + // members + NPT_Mutex& m_Mutex; +}; + +/*---------------------------------------------------------------------- +| NPT_Lock ++---------------------------------------------------------------------*/ +template <typename T> +class NPT_Lock : public T, + public NPT_Mutex +{ +}; + +/*---------------------------------------------------------------------- +| NPT_SharedVariableInterface ++---------------------------------------------------------------------*/ +class NPT_SharedVariableInterface +{ + public: + // methods + virtual ~NPT_SharedVariableInterface() {} + virtual void SetValue(int value)= 0; + virtual int GetValue() = 0; + virtual NPT_Result WaitUntilEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; + virtual NPT_Result WaitWhileEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_SharedVariable ++---------------------------------------------------------------------*/ +class NPT_SharedVariable : public NPT_SharedVariableInterface +{ + public: + // methods + NPT_SharedVariable(int value = 0); + ~NPT_SharedVariable() { delete m_Delegate; } + void SetValue(int value) { + m_Delegate->SetValue(value); + } + int GetValue() { + return m_Delegate->GetValue(); + } + NPT_Result WaitUntilEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return m_Delegate->WaitUntilEquals(value, timeout); + } + NPT_Result WaitWhileEquals(int value, NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return m_Delegate->WaitWhileEquals(value, timeout); + } + + private: + // members + NPT_SharedVariableInterface* m_Delegate; +}; + +/*---------------------------------------------------------------------- +| NPT_AtomicVariableInterface ++---------------------------------------------------------------------*/ +class NPT_AtomicVariableInterface +{ + public: + // methods + virtual ~NPT_AtomicVariableInterface() {} + virtual int Increment() = 0; + virtual int Decrement() = 0; + virtual int GetValue() = 0; + virtual void SetValue(int value) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_AtomicVariable ++---------------------------------------------------------------------*/ +class NPT_AtomicVariable : public NPT_AtomicVariableInterface +{ + public: + // methods + NPT_AtomicVariable(int value = 0); + ~NPT_AtomicVariable() { delete m_Delegate; } + int Increment() { return m_Delegate->Increment();} + int Decrement() { return m_Delegate->Decrement();} + void SetValue(int value) { m_Delegate->SetValue(value); } + int GetValue() { return m_Delegate->GetValue(); } + + private: + // members + NPT_AtomicVariableInterface* m_Delegate; +}; + +/*---------------------------------------------------------------------- +| NPT_Runnable ++---------------------------------------------------------------------*/ +class NPT_Runnable +{ +public: + virtual ~NPT_Runnable() {} + virtual void Run() = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_ThreadInterface ++---------------------------------------------------------------------*/ +class NPT_ThreadInterface: public NPT_Runnable, public NPT_Interruptible +{ + public: + // methods + virtual ~NPT_ThreadInterface() {} + virtual NPT_Result Start() = 0; + virtual NPT_Result Wait(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_Thread ++---------------------------------------------------------------------*/ +class NPT_Thread : public NPT_ThreadInterface +{ + public: + // types + typedef unsigned long ThreadId; + + // class methods + static ThreadId GetCurrentThreadId(); + + // methods + explicit NPT_Thread(bool detached = false); + explicit NPT_Thread(NPT_Runnable& target, bool detached = false); + ~NPT_Thread() { delete m_Delegate; } + + // NPT_ThreadInterface methods + NPT_Result Start() { + return m_Delegate->Start(); + } + NPT_Result Wait(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return m_Delegate->Wait(timeout); + } + + // NPT_Runnable methods + virtual void Run() {} + + // NPT_Interruptible methods + virtual NPT_Result Interrupt() { + return m_Delegate->Interrupt(); + } + + private: + // members + NPT_ThreadInterface* m_Delegate; +}; + + +/*---------------------------------------------------------------------- +| NPT_ThreadCallbackReceiver ++---------------------------------------------------------------------*/ +class NPT_ThreadCallbackReceiver +{ +public: + virtual ~NPT_ThreadCallbackReceiver() {} + virtual void OnCallback(void* args) = 0; +}; + +/*---------------------------------------------------------------------- +| NPT_ThreadCallbackSlot ++---------------------------------------------------------------------*/ +class NPT_ThreadCallbackSlot +{ +public: + // types + class NotificationHelper { + public: + virtual ~NotificationHelper() {}; + virtual void Notify(void) = 0; + }; + + // constructor + NPT_ThreadCallbackSlot(); + + // methods + NPT_Result ReceiveCallback(NPT_ThreadCallbackReceiver& receiver, NPT_Timeout timeout = 0); + NPT_Result SendCallback(void* args); + NPT_Result SetNotificationHelper(NotificationHelper* helper); + NPT_Result Shutdown(); + +protected: + // members + volatile void* m_CallbackArgs; + volatile bool m_Shutdown; + NPT_SharedVariable m_Pending; + NPT_SharedVariable m_Ack; + NPT_Mutex m_ReadLock; + NPT_Mutex m_WriteLock; + NotificationHelper* m_NotificationHelper; +}; + +#endif // _NPT_THREADS_H_ diff --git a/modules/platinum/SDK/include/NptTime.h b/modules/platinum/SDK/include/NptTime.h new file mode 100644 index 0000000..38e27ae --- /dev/null +++ b/modules/platinum/SDK/include/NptTime.h @@ -0,0 +1,150 @@ +/***************************************************************** +| +| Neptune - Time +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_TIME_H_ +#define _NPT_TIME_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" + +/*---------------------------------------------------------------------- +| NPT_TimeStamp ++---------------------------------------------------------------------*/ +class NPT_TimeStamp +{ + public: + // methods + NPT_TimeStamp(unsigned long seconds = 0, unsigned long nano_seconds = 0) : + m_Seconds(seconds), m_NanoSeconds(nano_seconds) {} + NPT_TimeStamp(float seconds); + operator float() const; + NPT_TimeStamp& operator+=(const NPT_TimeStamp& time_stamp); + NPT_TimeStamp& operator-=(const NPT_TimeStamp& time_stamp); + bool operator==(const NPT_TimeStamp& time_stamp) const; + bool operator!=(const NPT_TimeStamp& time_stamp) const; + bool operator>(const NPT_TimeStamp& time_stamp) const; + bool operator<(const NPT_TimeStamp& time_stamp) const; + bool operator>=(const NPT_TimeStamp& time_stamp) const; + bool operator<=(const NPT_TimeStamp& time_stamp) const; + + // friend operators + friend NPT_TimeStamp operator+(const NPT_TimeStamp& timestamp, long seconds); + friend NPT_TimeStamp operator-(const NPT_TimeStamp& timestamp, long seconds); + + // members + long m_Seconds; + long m_NanoSeconds; +}; + +/*---------------------------------------------------------------------- +| operator+ ++---------------------------------------------------------------------*/ +inline +NPT_TimeStamp +operator+(const NPT_TimeStamp& t1, const NPT_TimeStamp& t2) +{ + NPT_TimeStamp t = t1; + return t += t2; +} + +/*---------------------------------------------------------------------- +| operator- ++---------------------------------------------------------------------*/ +inline +NPT_TimeStamp +operator-(const NPT_TimeStamp& t1, const NPT_TimeStamp& t2) +{ + NPT_TimeStamp t = t1; + return t -= t2; +} + +/*---------------------------------------------------------------------- +| NPT_TimeInterval ++---------------------------------------------------------------------*/ +typedef NPT_TimeStamp NPT_TimeInterval; + +/*---------------------------------------------------------------------- +| NPT_DateTime ++---------------------------------------------------------------------*/ +typedef struct { + NPT_Int32 year; + NPT_Int32 month; + NPT_Int32 day; + NPT_Int32 hours; + NPT_Int32 minutes; + NPT_Int32 seconds; + NPT_Int32 milliseconds; +} NPT_DateTime; + +typedef NPT_Int32 NPT_TimeZone; /* minutes westward of GMT */ +typedef NPT_DateTime NPT_LocalDate; + +/*---------------------------------------------------------------------- +| NPT_Date ++---------------------------------------------------------------------*/ +typedef struct { + NPT_LocalDate local; + NPT_TimeZone timezone; +} NPT_Date; + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#define NPT_TIME_MIN_YEAR 1970 +#define NPT_TIME_MAX_YEAR 2106 + +/*---------------------------------------------------------------------- +| NPT_Time ++---------------------------------------------------------------------*/ +class NPT_Time +{ +public: + // methods + static NPT_Result GetGMTDateFromTimeStamp(const NPT_TimeStamp& timestamp, + NPT_Date& date); + static NPT_Result GetLocalDate(NPT_LocalDate& today, NPT_TimeStamp& now); + + // helper functions + static NPT_Result FormatDate(const NPT_Date& date, + char* output, + NPT_Size size); + static NPT_Result GetDateFromString(const char* input, + NPT_Date& date); + static NPT_Result ParseANSIDate(const char* ansi_date, + NPT_Date& date, + bool relaxed = true); + static NPT_Result ParseRFC850Date(const char* rfc850_date, + NPT_Date& date); +}; + +#endif // _NPT_TIME_H_ diff --git a/modules/platinum/SDK/include/NptTls.h b/modules/platinum/SDK/include/NptTls.h new file mode 100644 index 0000000..26dabb9 --- /dev/null +++ b/modules/platinum/SDK/include/NptTls.h @@ -0,0 +1,161 @@ +/***************************************************************** +| +| Neptune - TLS/SSL Support +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_TLS_H_ +#define _NPT_TLS_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConfig.h" +#include "NptStreams.h" + +/*---------------------------------------------------------------------- +| error codes ++---------------------------------------------------------------------*/ +const NPT_Result NPT_ERROR_INVALID_PASSWORD = (NPT_ERROR_BASE_TLS-1); +const NPT_Result NPT_ERROR_TLS_INVALID_HANDSHAKE = (NPT_ERROR_BASE_TLS-2); +const NPT_Result NPT_ERROR_TLS_INVALID_PROTOCOL_MESSAGE = (NPT_ERROR_BASE_TLS-3); +const NPT_Result NPT_ERROR_TLS_INVALID_HMAC = (NPT_ERROR_BASE_TLS-4); +const NPT_Result NPT_ERROR_TLS_INVALID_VERSION = (NPT_ERROR_BASE_TLS-5); +const NPT_Result NPT_ERROR_TLS_INVALID_SESSION = (NPT_ERROR_BASE_TLS-6); +const NPT_Result NPT_ERROR_TLS_NO_CIPHER = (NPT_ERROR_BASE_TLS-7); +const NPT_Result NPT_ERROR_TLS_BAD_CERTIFICATE = (NPT_ERROR_BASE_TLS-8); +const NPT_Result NPT_ERROR_INVALID_KEY = (NPT_ERROR_BASE_TLS-9); + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const unsigned int NPT_TLS_NULL_WITH_NULL_NULL = 0x00; +const unsigned int NPT_TLS_RSA_WITH_RC4_128_MD5 = 0x04; +const unsigned int NPT_TLS_RSA_WITH_RC4_128_SHA = 0x05; +const unsigned int NPT_TLS_RSA_WITH_AES_128_CBC_SHA = 0x2F; +const unsigned int NPT_TLS_RSA_WITH_AES_256_CBC_SHA = 0x35; + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class NPT_TlsContextImpl; +class NPT_TlsSessionImpl; + +/*---------------------------------------------------------------------- +| types ++---------------------------------------------------------------------*/ +typedef enum { + NPT_TLS_KEY_FORMAT_RSA_PRIVATE, + NPT_TLS_KEY_FORMAT_PKCS8, + NPT_TLS_KEY_FORMAT_PKCS12 +} NPT_TlsKeyFormat; + +/*---------------------------------------------------------------------- +| NPT_TlsContext ++---------------------------------------------------------------------*/ +class NPT_TlsContext +{ +public: + NPT_TlsContext(); + ~NPT_TlsContext(); + + // methods + NPT_Result LoadKey(NPT_TlsKeyFormat key_format, + const unsigned char* key_data, + NPT_Size key_data_size, + const char* password); + + +protected: + NPT_TlsContextImpl* m_Impl; + + // friends + friend class NPT_TlsClientSession; + friend class NPT_TlsServerSession; +}; + +typedef NPT_Reference<NPT_TlsContext> NPT_TlsContextReference; + +/*---------------------------------------------------------------------- +| NPT_TlsCertificateInfo ++---------------------------------------------------------------------*/ +struct NPT_TlsCertificateInfo +{ + struct { + NPT_String common_name; + NPT_String organization; + NPT_String organizational_name; + } subject; + struct { + NPT_String common_name; + NPT_String organization; + NPT_String organizational_name; + } issuer; + struct { + unsigned char sha1[20]; + unsigned char md5[16]; + } fingerprint; +}; + +/*---------------------------------------------------------------------- +| NPT_TlsClientSession ++---------------------------------------------------------------------*/ +class NPT_TlsClientSession +{ +public: + NPT_TlsClientSession(NPT_TlsContextReference& context, + NPT_InputStreamReference& input, + NPT_OutputStreamReference& output); + ~NPT_TlsClientSession(); + NPT_Result Handshake(); + NPT_Result GetSessionId(NPT_DataBuffer& session_id); + NPT_UInt32 GetCipherSuiteId(); + NPT_Result GetPeerCertificateInfo(NPT_TlsCertificateInfo& info); + NPT_Result GetInputStream(NPT_InputStreamReference& stream); + NPT_Result GetOutputStream(NPT_OutputStreamReference& stream); + +protected: + NPT_TlsContextReference m_Context; + NPT_Reference<NPT_TlsSessionImpl> m_Impl; +}; + +/*---------------------------------------------------------------------- +| NPT_TlsServerSession ++---------------------------------------------------------------------*/ +class NPT_TlsServerSession +{ +public: + NPT_TlsServerSession(NPT_TlsContext& context, + NPT_InputStreamReference input, + NPT_OutputStreamReference output); + +protected: + NPT_TlsSessionImpl* m_Impl; +}; + +#endif // _NPT_TLS_H_ diff --git a/modules/platinum/SDK/include/NptTypes.h b/modules/platinum/SDK/include/NptTypes.h new file mode 100644 index 0000000..743b805 --- /dev/null +++ b/modules/platinum/SDK/include/NptTypes.h @@ -0,0 +1,149 @@ +/***************************************************************** +| +| Neptune - Types +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_TYPES_H_ +#define _NPT_TYPES_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConfig.h" + +/*---------------------------------------------------------------------- +| sized types (this assumes that ints are 32 bits) ++---------------------------------------------------------------------*/ +typedef NPT_CONFIG_INT64_TYPE NPT_Int64; +typedef unsigned NPT_CONFIG_INT64_TYPE NPT_UInt64; +typedef unsigned int NPT_UInt32; +typedef int NPT_Int32; +typedef unsigned short NPT_UInt16; +typedef short NPT_Int16; +typedef unsigned char NPT_UInt8; +typedef char NPT_Int8; +typedef float NPT_Float; + +/*---------------------------------------------------------------------- +| named types ++---------------------------------------------------------------------*/ +typedef int NPT_Result; +typedef unsigned int NPT_Cardinal; +typedef unsigned int NPT_Ordinal; +typedef unsigned long NPT_Size; +typedef NPT_UInt64 NPT_LargeSize; +typedef signed long NPT_Offset; +typedef NPT_UInt64 NPT_Position; +typedef long NPT_Timeout; +typedef void NPT_Interface; +typedef unsigned char NPT_Byte; +typedef unsigned int NPT_Flags; +typedef void* NPT_Any; +typedef const void* NPT_AnyConst; + +/*---------------------------------------------------------------------- +| limits ++---------------------------------------------------------------------*/ +#if defined(NPT_CONFIG_HAVE_LIMITS_H) +#include <limits.h> +#endif + +#if !defined(NPT_INT_MIN) +#if defined(NPT_CONFIG_HAVE_INT_MIN) +#define NPT_INT_MIN INT_MIN +#endif +#endif + +#if !defined(NPT_INT_MAX) +#if defined(NPT_CONFIG_HAVE_INT_MAX) +#define NPT_INT_MAX INT_MAX +#endif +#endif + +#if !defined(NPT_UINT_MAX) +#if defined(NPT_CONFIG_HAVE_UINT_MAX) +#define NPT_UINT_MAX UINT_MAX +#endif +#endif + +#if !defined(NPT_LONG_MIN) +#if defined(NPT_CONFIG_HAVE_LONG_MIN) +#define NPT_LONG_MIN LONG_MIN +#endif +#endif + +#if !defined(NPT_LONG_MAX) +#if defined(NPT_CONFIG_HAVE_LONG_MAX) +#define NPT_LONG_MAX LONG_MAX +#endif +#endif + +#if !defined(NPT_ULONG_MAX) +#if defined(NPT_CONFIG_HAVE_ULONG_MAX) +#define NPT_ULONG_MAX ULONG_MAX +#endif +#endif + +#if !defined(NPT_INT32_MAX) +#define NPT_INT32_MAX 0x7FFFFFFF +#endif + +#if !defined(NPT_INT32_MIN) +#define NPT_INT32_MIN (-NPT_INT32_MAX - 1) +#endif + +#if !defined(NPT_UINT32_MAX) +#define NPT_UINT32_MAX 0xFFFFFFFF +#endif + +#if !defined(NPT_INT64_MAX) +#if defined(NPT_CONFIG_HAVE_LLONG_MAX) +#define NPT_INT64_MAX LLONG_MAX +#else +#define NPT_INT64_MAX 0x7FFFFFFFFFFFFFFFLL +#endif +#endif + +#if !defined(NPT_INT64_MIN) +#if defined(NPT_CONFIG_HAVE_LLONG_MIN) +#define NPT_INT64_MIN LLONG_MIN +#else +#define NPT_INT64_MIN (-NPT_INT64_MAX - 1LL) +#endif +#endif + +#if !defined(NPT_UINT64_MAX) +#if defined(NPT_CONFIG_HAVE_ULLONG_MAX) +#define NPT_UINT64_MAX ULLONG_MAX +#else +#define NPT_UINT64_MAX 0xFFFFFFFFFFFFFFFFULL +#endif +#endif + +#endif // _NPT_TYPES_H_ diff --git a/modules/platinum/SDK/include/NptUri.h b/modules/platinum/SDK/include/NptUri.h new file mode 100644 index 0000000..58ce423 --- /dev/null +++ b/modules/platinum/SDK/include/NptUri.h @@ -0,0 +1,170 @@ +/***************************************************************** +| +| Neptune - URI +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_URI_H_ +#define _NPT_URI_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptStrings.h" +#include "NptList.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const NPT_UInt16 NPT_URL_INVALID_PORT = 0; + +/*---------------------------------------------------------------------- +| NPT_Uri ++---------------------------------------------------------------------*/ +class NPT_Uri { +public: + // types + typedef enum { + SCHEME_ID_UNKNOWN, + SCHEME_ID_HTTP + } SchemeId; + + // constants. use as a parameter to Encode() + static const char* const PathCharsToEncode; + static const char* const QueryCharsToEncode; + static const char* const FragmentCharsToEncode; + static const char* const UnsafeCharsToEncode; + + // class methods + static NPT_String PercentEncode(const char* str, const char* chars, bool encode_percents=true); + static NPT_String PercentDecode(const char* str); + static SchemeId ParseScheme(const NPT_String& scheme); + + // methods + NPT_Uri() : m_SchemeId(SCHEME_ID_UNKNOWN) {} + virtual ~NPT_Uri() {} + const NPT_String& GetScheme() const { + return m_Scheme; + } + void SetScheme(const char* scheme); + NPT_Result SetSchemeFromUri(const char* uri); + SchemeId GetSchemeId() const { + return m_SchemeId; + } + +protected: + // members + NPT_String m_Scheme; + SchemeId m_SchemeId; +}; + +/*---------------------------------------------------------------------- +| NPT_UrlQuery ++---------------------------------------------------------------------*/ +class NPT_UrlQuery +{ +public: + // class methods + static NPT_String UrlEncode(const char* str, bool encode_percents=true); + static NPT_String UrlDecode(const char* str); + + // types + struct Field { + Field(const char* name, const char* value) : + m_Name(name), m_Value(value) {} + NPT_String m_Name; + NPT_String m_Value; + }; + + // constructor + NPT_UrlQuery() {} + NPT_UrlQuery(const char* query); + + // accessors + NPT_List<Field>& GetFields() { return m_Fields; } + + // methods + NPT_Result Parse(const char* query); + NPT_Result SetField(const char* name, const char* value); + NPT_Result AddField(const char* name, const char* value); + const char* GetField(const char* name); + NPT_String ToString(); + +private: + // members + NPT_List<Field> m_Fields; +}; + +/*---------------------------------------------------------------------- +| NPT_Url ++---------------------------------------------------------------------*/ +class NPT_Url : public NPT_Uri { +public: + // constructors and destructor + NPT_Url(); + NPT_Url(const char* url, + SchemeId expected_scheme = SCHEME_ID_UNKNOWN, + NPT_UInt16 default_port = NPT_URL_INVALID_PORT); + NPT_Url(const char* scheme, + const char* host, + NPT_UInt16 port, + const char* path, + const char* query = NULL, + const char* fragment = NULL); + + // methods + const NPT_String& GetHost() const { return m_Host; } + NPT_UInt16 GetPort() const { return m_Port; } + const NPT_String& GetPath() const { return m_Path; } + const NPT_String& GetQuery() const { return m_Query; } + const NPT_String& GetFragment() const { return m_Fragment; } + virtual bool IsValid() const; + bool HasQuery() const { return m_HasQuery; } + bool HasFragment() const { return m_HasFragment; } + NPT_Result SetHost(const char* host); + NPT_Result SetPort(NPT_UInt16 port); + NPT_Result SetPath(const char* path); + NPT_Result SetPathPlus(const char* path_plus); + NPT_Result SetQuery(const char* query); + NPT_Result SetFragment(const char* fragment); + virtual NPT_String ToRequestString(bool with_fragment = false) const; + virtual NPT_String ToStringWithDefaultPort(NPT_UInt16 default_port, bool with_fragment = true) const; + virtual NPT_String ToString(bool with_fragment = true) const; + +protected: + // members + NPT_String m_Host; + NPT_UInt16 m_Port; + NPT_String m_Path; + bool m_HasQuery; + NPT_String m_Query; + bool m_HasFragment; + NPT_String m_Fragment; +}; + +#endif // _NPT_URI_H_ diff --git a/modules/platinum/SDK/include/NptUtils.h b/modules/platinum/SDK/include/NptUtils.h new file mode 100644 index 0000000..05a38a0 --- /dev/null +++ b/modules/platinum/SDK/include/NptUtils.h @@ -0,0 +1,219 @@ +/***************************************************************** +| +| Neptune Utils +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_UTILS_H_ +#define _NPT_UTILS_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConfig.h" +#include "NptTypes.h" +#include "NptStrings.h" +#include "NptMap.h" + +#if defined (NPT_CONFIG_HAVE_STDIO_H) +#include <stdio.h> +#endif + +#if defined (NPT_CONFIG_HAVE_STRING_H) +#include <string.h> +#endif + +#if defined(NPT_CONFIG_HAVE_STDARG_H) +#include <stdarg.h> +#endif + +/*---------------------------------------------------------------------- +| macros ++---------------------------------------------------------------------*/ +#define NPT_ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0])) + +/*---------------------------------------------------------------------- +| byte I/O ++---------------------------------------------------------------------*/ +extern void NPT_BytesFromInt64Be(unsigned char* buffer, NPT_UInt64 value); +extern void NPT_BytesFromInt32Be(unsigned char* buffer, NPT_UInt32 value); +extern void NPT_BytesFromInt24Be(unsigned char* buffer, NPT_UInt32 value); +extern void NPT_BytesFromInt16Be(unsigned char* buffer, NPT_UInt16 value); +extern NPT_UInt64 NPT_BytesToInt64Be(const unsigned char* buffer); +extern NPT_UInt32 NPT_BytesToInt32Be(const unsigned char* buffer); +extern NPT_UInt32 NPT_BytesToInt24Be(const unsigned char* buffer); +extern NPT_UInt16 NPT_BytesToInt16Be(const unsigned char* buffer); + +extern void NPT_BytesFromInt64Le(unsigned char* buffer, NPT_UInt64 value); +extern void NPT_BytesFromInt32Le(unsigned char* buffer, NPT_UInt32 value); +extern void NPT_BytesFromInt24Le(unsigned char* buffer, NPT_UInt32 value); +extern void NPT_BytesFromInt16Le(unsigned char* buffer, NPT_UInt16 value); +extern NPT_UInt64 NPT_BytesToInt64Le(const unsigned char* buffer); +extern NPT_UInt32 NPT_BytesToInt32Le(const unsigned char* buffer); +extern NPT_UInt32 NPT_BytesToInt24Le(const unsigned char* buffer); +extern NPT_UInt16 NPT_BytesToInt16Le(const unsigned char* buffer); + +/*---------------------------------------------------------------------- +| conversion utilities ++---------------------------------------------------------------------*/ +extern NPT_Result +NPT_ParseFloat(const char* str, float& result, bool relaxed = true); + +extern NPT_Result +NPT_ParseInteger(const char* str, long& result, bool relaxed = true, NPT_Cardinal* chars_used = 0); + +extern NPT_Result +NPT_ParseInteger(const char* str, unsigned long& result, bool relaxed = true, NPT_Cardinal* chars_used = 0); + +extern NPT_Result +NPT_ParseInteger(const char* str, int& result, bool relaxed = true, NPT_Cardinal* chars_used = 0); + +extern NPT_Result +NPT_ParseInteger(const char* str, unsigned int& result, bool relaxed = true, NPT_Cardinal* chars_used = 0); + +extern NPT_Result +NPT_ParseInteger32(const char* str, NPT_Int32& result, bool relaxed = true, NPT_Cardinal* chars_used = 0); + +extern NPT_Result +NPT_ParseInteger32(const char* str, NPT_UInt32& result, bool relaxed = true, NPT_Cardinal* chars_used = 0); + +extern NPT_Result +NPT_ParseInteger64(const char* str, NPT_Int64& result, bool relaxed = true, NPT_Cardinal* chars_used = 0); + +extern NPT_Result +NPT_ParseInteger64(const char* str, NPT_UInt64& result, bool relaxed = true, NPT_Cardinal* chars_used = 0); + +/*---------------------------------------------------------------------- +| formatting ++---------------------------------------------------------------------*/ +void +NPT_FormatOutput(void (*function)(void* parameter, const char* message), + void* function_parameter, + const char* format, + va_list args); + +void NPT_ByteToHex(NPT_Byte b, char* buffer, bool uppercase=false); +NPT_Result NPT_HexToByte(const char* buffer, NPT_Byte& b); +NPT_String NPT_HexString(const unsigned char* data, + NPT_Size data_size, + const char* separator = NULL, + bool uppercase=false); +char NPT_NibbleToHex(unsigned int nibble, bool uppercase = true); +int NPT_HexToNibble(char hex); + +/*---------------------------------------------------------------------- +| parsing ++---------------------------------------------------------------------*/ +NPT_Result +NPT_ParseMimeParameters(const char* encoded, + NPT_Map<NPT_String, NPT_String>& parameters); + +/*---------------------------------------------------------------------- +| environment variables ++---------------------------------------------------------------------*/ +NPT_Result NPT_GetEnvironment(const char* name, NPT_String& value); + +/*---------------------------------------------------------------------- +| string utils ++---------------------------------------------------------------------*/ +#if defined (NPT_CONFIG_HAVE_STDIO_H) +#include <stdio.h> +#endif + +#if defined (NPT_CONFIG_HAVE_STRING_H) +#include <string.h> +#endif + +#if defined (NPT_CONFIG_HAVE_SNPRINTF) +#define NPT_FormatString NPT_snprintf +#else +int NPT_FormatString(char* str, NPT_Size size, const char* format, ...); +#endif + +#if defined(NPT_CONFIG_HAVE_VSNPRINTF) +#define NPT_FormatStringVN(s,c,f,a) NPT_vsnprintf(s,c,f,a) +#else +extern int NPT_FormatStringVN(char *buffer, size_t count, const char *format, va_list argptr); +#endif + +#if defined(NPT_CONFIG_HAVE_MEMCPY) +#define NPT_CopyMemory memcpy +#else +extern void NPT_CopyMemory(void* dest, void* src, NPT_Size size); +#endif + +#if defined(NPT_CONFIG_HAVE_STRCMP) +#define NPT_StringsEqual(s1, s2) (strcmp((s1), (s2)) == 0) +#else +extern int NPT_StringsEqual(const char* s1, const char* s2); +#endif + +#if defined(NPT_CONFIG_HAVE_STRNCMP) +#define NPT_StringsEqualN(s1, s2, n) (strncmp((s1), (s2), (n)) == 0) +#else +extern int NPT_StringsEqualN(const char* s1, const char* s2, unsigned long size); +#endif + +#if defined(NPT_CONFIG_HAVE_STRLEN) +#define NPT_StringLength(s) (NPT_Size)(strlen(s)) +#else +extern unsigned long NPT_StringLength(const char* s); +#endif + +#if defined(NPT_CONFIG_HAVE_STRCPY) +#define NPT_CopyString(dst, src) ((void)NPT_strcpy((dst), (src))) +#else +extern void NPT_CopyString(char* dst, const char* src); +#endif + +/** + * Copy up to n characters from src to dst. + * The destination buffer will be null-terminated, so it must + * have enough space for n+1 characters (n from the source plus + * the null terminator). + */ +#if defined(NPT_CONFIG_HAVE_STRNCPY) +#define NPT_CopyStringN(dst, src, n) \ +do { ((void)NPT_strncpy((dst), (src), n)); (dst)[(n)] = '\0'; } while(0) +#else +extern int NPT_CopyStringN(char* dst, const char* src, unsigned long n); +#endif + +#if defined(NPT_CONFIG_HAVE_MEMSET) +#define NPT_SetMemory memset +#else +extern void NPT_SetMemory(void* dest, int c, NPT_Size size); +#endif + +#if defined(NPT_CONFIG_HAVE_MEMCMP) +#define NPT_MemoryEqual(s1, s2, n) (memcmp((s1), (s2), (n)) == 0) +#else +extern int NPT_MemoryEqual(const void* s1, const void* s2, unsigned long n); +#endif + +#endif // _NPT_UTILS_H_ diff --git a/modules/platinum/SDK/include/NptVersion.h b/modules/platinum/SDK/include/NptVersion.h new file mode 100644 index 0000000..ab9aa6e --- /dev/null +++ b/modules/platinum/SDK/include/NptVersion.h @@ -0,0 +1,41 @@ +/***************************************************************** +| +| Neptune - Version Info +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_VERSION_H_ +#define _NPT_VERSION_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#define NPT_NEPTUNE_VERSION 0x01000200 +#define NPT_NEPTUNE_VERSION_STRING "1.0.2" + +#endif // _NPT_VERSION_H_ diff --git a/modules/platinum/SDK/include/NptXml.h b/modules/platinum/SDK/include/NptXml.h new file mode 100644 index 0000000..3324658 --- /dev/null +++ b/modules/platinum/SDK/include/NptXml.h @@ -0,0 +1,385 @@ +/***************************************************************** +| +| Neptune - Xml Support +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_XML_H_ +#define _NPT_XML_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptList.h" +#include "NptStrings.h" +#include "NptStreams.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +const int NPT_ERROR_XML_INVALID_NESTING = NPT_ERROR_BASE_XML - 0; +const int NPT_ERROR_XML_TAG_MISMATCH = NPT_ERROR_BASE_XML - 1; + +#define NPT_XML_ANY_NAMESPACE "*" +#define NPT_XML_NO_NAMESPACE NULL + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class NPT_XmlProcessor; + +/*---------------------------------------------------------------------- +| NPT_XmlAttribute ++---------------------------------------------------------------------*/ +class NPT_XmlAttribute +{ + public: + // methods + NPT_XmlAttribute(const char* name, const char* value); + NPT_XmlAttribute(const char* prefix, const char* name, const char* value) : + m_Prefix(prefix), m_Name(name), m_Value(value) {} + const NPT_String& GetPrefix() const { return m_Prefix; } + const NPT_String& GetName() const { return m_Name; } + const NPT_String& GetValue() const { return m_Value; } + void SetValue(const char* value) { m_Value = value; } + + private: + // members + NPT_String m_Prefix; + NPT_String m_Name; + NPT_String m_Value; + + NPT_XmlAttribute(const NPT_XmlAttribute& attribute) : + m_Prefix(attribute.m_Prefix), + m_Name(attribute.m_Name), + m_Value(attribute.m_Value) {} + NPT_XmlAttribute& operator=(const NPT_XmlAttribute& a); + + // friends + friend class NPT_XmlAttributeFinder; + friend class NPT_XmlAttributeFinderWithPrefix; +}; + +/*---------------------------------------------------------------------- +| NPT_XmlNamespaceMap ++---------------------------------------------------------------------*/ +class NPT_XmlNamespaceMap +{ +public: + // destructor + ~NPT_XmlNamespaceMap(); + + // methods + NPT_Result SetNamespaceUri(const char* prefix, const char* uri); + const NPT_String* GetNamespaceUri(const char* prefix); + const NPT_String* GetNamespacePrefix(const char* uri); + +private: + // types + class Entry { + public: + // constructor + Entry(const char* prefix, const char* uri) : + m_Prefix(prefix), m_Uri(uri) {} + + // members + NPT_String m_Prefix; + NPT_String m_Uri; + }; + + // members + NPT_List<Entry*> m_Entries; + + // friends + friend class NPT_XmlWriter; + friend class NPT_XmlNodeWriter; + friend class NPT_XmlNodeCanonicalWriter; +}; + +/*---------------------------------------------------------------------- +| NPT_XmlNode ++---------------------------------------------------------------------*/ +class NPT_XmlElementNode; +class NPT_XmlTextNode; +class NPT_XmlNode +{ + public: + // types + typedef enum { + DOCUMENT, + ELEMENT, + TEXT + } Type; + + // methods + NPT_XmlNode(Type type) : m_Type(type), m_Parent(NULL) {} + virtual ~NPT_XmlNode() {} + Type GetType() const { return m_Type; } + NPT_XmlNode* GetParent() const { return m_Parent; } + + // type casting + virtual NPT_XmlElementNode* AsElementNode() { return NULL; } + virtual const NPT_XmlElementNode* AsElementNode() const { return NULL; } + virtual NPT_XmlTextNode* AsTextNode() { return NULL; } + virtual const NPT_XmlTextNode* AsTextNode() const { return NULL; } + + protected: + // methods + virtual void SetParent(NPT_XmlNode* parent) { m_Parent = parent; } + + // members + Type m_Type; + NPT_XmlNode* m_Parent; + + // friends + friend class NPT_XmlNodeFinder; + friend class NPT_XmlSerializer; + friend class NPT_XmlWriter; + friend class NPT_XmlElementNode; // to allow access to SetParent() +}; + +/*---------------------------------------------------------------------- +| NPT_XmlElementNode ++---------------------------------------------------------------------*/ +class NPT_XmlElementNode : public NPT_XmlNode +{ + public: + // methods + NPT_XmlElementNode(const char* tag); + NPT_XmlElementNode(const char* prefix, const char* tag); + virtual ~NPT_XmlElementNode(); + NPT_List<NPT_XmlNode*>& GetChildren() { return m_Children; } + const NPT_List<NPT_XmlNode*>& + GetChildren() const { return m_Children; } + NPT_XmlElementNode* GetChild(const char* tag, + const char* namespc = NPT_XML_NO_NAMESPACE, + NPT_Ordinal n=0) const; + NPT_Result AddChild(NPT_XmlNode* child); + NPT_Result SetAttribute(const char* prefix, + const char* name, + const char* value); + NPT_Result SetAttribute(const char* name, + const char* value); + NPT_Result AddText(const char* text); + NPT_List<NPT_XmlAttribute*>& + GetAttributes() { return m_Attributes; } + const NPT_List<NPT_XmlAttribute*>& + GetAttributes() const { return m_Attributes; } + const NPT_String* GetAttribute(const char* name, + const char* namespc = NPT_XML_NO_NAMESPACE) const; + const NPT_String& GetPrefix() const { return m_Prefix; } + const NPT_String& GetTag() const { return m_Tag; } + const NPT_String* GetText(NPT_Ordinal n=0) const; + + // bring all the namespace definitions used in this element of one of its descendants + // into the namespace map of this element so that it may be serialized as a + // standalone element without any prefixes with undefined namespace uris + NPT_Result MakeStandalone(); + + // namespace methods + const NPT_String* GetNamespace() const; + NPT_Result SetNamespaceUri(const char* prefix, const char* uri); + const NPT_String* GetNamespaceUri(const char* prefix) const; + const NPT_String* GetNamespacePrefix(const char* uri) const; + + // type casting + NPT_XmlElementNode* AsElementNode() { return this; } + const NPT_XmlElementNode* AsElementNode() const { return this; } + +protected: + // methods + void SetParent(NPT_XmlNode* parent); + void SetNamespaceParent(NPT_XmlElementNode* parent); + void RelinkNamespaceMaps(); + + NPT_Result AddAttribute(const char* name, const char* value); + + // members + NPT_String m_Prefix; + NPT_String m_Tag; + NPT_List<NPT_XmlNode*> m_Children; + NPT_List<NPT_XmlAttribute*> m_Attributes; + NPT_XmlNamespaceMap* m_NamespaceMap; + NPT_XmlElementNode* m_NamespaceParent; + + // friends + friend class NPT_XmlTagFinder; + friend class NPT_XmlSerializer; + friend class NPT_XmlWriter; + friend class NPT_XmlNodeWriter; + friend class NPT_XmlNodeCanonicalWriter; + friend class NPT_XmlParser; + friend class NPT_XmlProcessor; + friend class NPT_XmlNamespaceCollapser; +}; + +/*---------------------------------------------------------------------- +| NPT_XmlTextNode ++---------------------------------------------------------------------*/ +class NPT_XmlTextNode : public NPT_XmlNode +{ + public: + // types + typedef enum { + CHARACTER_DATA, + IGNORABLE_WHITESPACE, + CDATA_SECTION, + ENTITY_REFERENCE, + COMMENT + } TokenType; + + // constructor + NPT_XmlTextNode(TokenType token_type, const char* text); + + // methods + const NPT_String& GetString() const { return m_Text; } + + // type casting + NPT_XmlTextNode* AsTextNode() { return this; } + const NPT_XmlTextNode* AsTextNode() const { return this; } + + private: + // members + TokenType m_TokenType; + NPT_String m_Text; +}; + +/*---------------------------------------------------------------------- +| NPT_XmlParser ++---------------------------------------------------------------------*/ +class NPT_XmlParser +{ + public: + // methods + NPT_XmlParser(bool keep_whitespace = true); + virtual ~NPT_XmlParser(); + virtual NPT_Result Parse(const char* xml, + NPT_XmlNode*& tree, + bool incremental=false); + virtual NPT_Result Parse(const char* xml, + NPT_Size size, + NPT_XmlNode*& tree, + bool incremental=false); + virtual NPT_Result Parse(NPT_InputStream& stream, + NPT_XmlNode*& tree, + bool incremental=false); + virtual NPT_Result Parse(NPT_InputStream& stream, + NPT_Size& size, + NPT_XmlNode*& tree, + bool incremental=false); + + protected: + // NPT_XmlHandler methods + NPT_Result OnStartElement(const char* name); + NPT_Result OnElementAttribute(const char* name, const char* value); + NPT_Result OnEndElement(const char* name); + NPT_Result OnCharacterData(const char* data, unsigned long size); + void RemoveIgnorableWhitespace(); + + // members + NPT_XmlProcessor* m_Processor; + NPT_XmlElementNode* m_Tree; + NPT_XmlElementNode* m_CurrentElement; + bool m_KeepWhitespace; + + // friends + friend class NPT_XmlProcessor; +}; + +/*---------------------------------------------------------------------- +| NPT_XmlSerializer ++---------------------------------------------------------------------*/ +class NPT_XmlSerializer +{ +public: + // methods + NPT_XmlSerializer(NPT_OutputStream* output, + NPT_Cardinal indentation = 0, + bool shrink_empty_elements = true, + bool add_header = true); + virtual ~NPT_XmlSerializer(); + virtual NPT_Result StartDocument(); + virtual NPT_Result EndDocument(); + virtual NPT_Result StartElement(const char* prefix, const char* name); + virtual NPT_Result EndElement(const char* prefix, const char* name); + virtual NPT_Result Attribute(const char* prefix, const char* name, const char* value); + virtual NPT_Result Text(const char* text); + virtual NPT_Result CdataSection(const char* data); + virtual NPT_Result Comment(const char* comment); + +protected: + // methods + void EscapeChar(unsigned char c, char* text); + NPT_Result ProcessPending(); + NPT_Result OutputEscapedString(const char* text, bool attribute); + void OutputIndentation(bool start); + + // members + NPT_OutputStream* m_Output; + bool m_ElementPending; + NPT_Cardinal m_Depth; + NPT_Cardinal m_Indentation; + NPT_String m_IndentationPrefix; + bool m_ElementHasText; + bool m_ShrinkEmptyElements; + bool m_AddHeader; +}; + +/*---------------------------------------------------------------------- +| NPT_XmlWriter ++---------------------------------------------------------------------*/ +class NPT_XmlWriter +{ +public: + // constructor + explicit NPT_XmlWriter(NPT_Cardinal indentation = 0) : m_Indentation(indentation) {} + + // methods + NPT_Result Serialize(NPT_XmlNode& node, + NPT_OutputStream& stream, + bool add_header = true); + +private: + // members + NPT_Cardinal m_Indentation; +}; + +/*---------------------------------------------------------------------- +| NPT_XmlCanonicalizer ++---------------------------------------------------------------------*/ +class NPT_XmlCanonicalizer +{ +public: + // methods + NPT_Result Serialize(NPT_XmlNode& node, + NPT_OutputStream& stream, + bool add_header = true); +}; + +#endif // _NPT_XML_H_ diff --git a/modules/platinum/SDK/include/NptZip.h b/modules/platinum/SDK/include/NptZip.h new file mode 100644 index 0000000..12802fa --- /dev/null +++ b/modules/platinum/SDK/include/NptZip.h @@ -0,0 +1,144 @@ +/***************************************************************** +| +| Neptune - Zip Support +| +| Copyright (c) 2002-2008, Axiomatic Systems, LLC. +| All rights reserved. +| +| Redistribution and use in source and binary forms, with or without +| modification, are permitted provided that the following conditions are met: +| * Redistributions of source code must retain the above copyright +| notice, this list of conditions and the following disclaimer. +| * Redistributions in binary form must reproduce the above copyright +| notice, this list of conditions and the following disclaimer in the +| documentation and/or other materials provided with the distribution. +| * Neither the name of Axiomatic Systems nor the +| names of its contributors may be used to endorse or promote products +| derived from this software without specific prior written permission. +| +| THIS SOFTWARE IS PROVIDED BY AXIOMATIC SYSTEMS ''AS IS'' AND ANY +| EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +| WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +| DISCLAIMED. IN NO EVENT SHALL AXIOMATIC SYSTEMS BE LIABLE FOR ANY +| DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +| (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +| LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +| ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +| SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +| + ****************************************************************/ + +#ifndef _NPT_ZIP_H_ +#define _NPT_ZIP_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptConfig.h" +#include "NptStreams.h" + +/*---------------------------------------------------------------------- +| class references ++---------------------------------------------------------------------*/ +class NPT_ZipInflateState; +class NPT_ZipDeflateState; + +/*---------------------------------------------------------------------- +| NPT_Zip ++---------------------------------------------------------------------*/ +const int NPT_ZIP_COMPRESSION_LEVEL_DEFAULT = -1; +const int NPT_ZIP_COMPRESSION_LEVEL_MIN = 0; +const int NPT_ZIP_COMPRESSION_LEVEL_MAX = 9; +const int NPT_ZIP_COMPRESSION_LEVEL_NONE = 0; +class NPT_Zip +{ +public: + // class methods + static NPT_Result MapError(int err); + + /** + * Compressed data format + */ + typedef enum { + ZLIB, + GZIP + } Format; + + /** + * Deflate (i.e compress) a buffer + */ + static NPT_Result Deflate(const NPT_DataBuffer& in, + NPT_DataBuffer& out, + int compression_level = NPT_ZIP_COMPRESSION_LEVEL_DEFAULT, + Format format = ZLIB); + + /** + * Inflate (i.e decompress) a buffer + */ + static NPT_Result Inflate(const NPT_DataBuffer& in, + NPT_DataBuffer& out); +}; + +/*---------------------------------------------------------------------- +| NPT_ZipInflatingInputStream ++---------------------------------------------------------------------*/ +class NPT_ZipInflatingInputStream : public NPT_InputStream +{ +public: + NPT_ZipInflatingInputStream(NPT_InputStreamReference& source); + ~NPT_ZipInflatingInputStream(); + + // NPT_InputStream methods + virtual NPT_Result Read(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read = NULL); + virtual NPT_Result Seek(NPT_Position offset); + virtual NPT_Result Tell(NPT_Position& offset); + virtual NPT_Result GetSize(NPT_LargeSize& size); + virtual NPT_Result GetAvailable(NPT_LargeSize& available); + +private: + NPT_InputStreamReference m_Source; + NPT_Position m_Position; + NPT_ZipInflateState* m_State; + NPT_DataBuffer m_Buffer; +}; + +/*---------------------------------------------------------------------- +| NPT_ZipInflatingOutputStream ++---------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------- +| NPT_ZipDeflatingInputStream ++---------------------------------------------------------------------*/ +class NPT_ZipDeflatingInputStream : public NPT_InputStream +{ +public: + NPT_ZipDeflatingInputStream(NPT_InputStreamReference& source, + int compression_level = NPT_ZIP_COMPRESSION_LEVEL_DEFAULT, + NPT_Zip::Format format = NPT_Zip::ZLIB); + ~NPT_ZipDeflatingInputStream(); + + // NPT_InputStream methods + virtual NPT_Result Read(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read = NULL); + virtual NPT_Result Seek(NPT_Position offset); + virtual NPT_Result Tell(NPT_Position& offset); + virtual NPT_Result GetSize(NPT_LargeSize& size); + virtual NPT_Result GetAvailable(NPT_LargeSize& available); + +private: + NPT_InputStreamReference m_Source; + NPT_Position m_Position; + bool m_Eos; + NPT_ZipDeflateState* m_State; + NPT_DataBuffer m_Buffer; +}; + +/*---------------------------------------------------------------------- +| NPT_ZipDeflatingInputStream ++---------------------------------------------------------------------*/ + +#endif // _NPT_ZIP_H_ diff --git a/modules/platinum/SDK/include/Platinum.h b/modules/platinum/SDK/include/Platinum.h new file mode 100644 index 0000000..bdce930 --- /dev/null +++ b/modules/platinum/SDK/include/Platinum.h @@ -0,0 +1,55 @@ +/***************************************************************** +| +| Platinum - Top Level Include +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| + ****************************************************************/ + +#ifndef _PLATINUM_H_ +#define _PLATINUM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "PltUPnP.h" +#include "PltCtrlPoint.h" +#include "PltDeviceData.h" +#include "PltHttpServer.h" +#include "PltVersion.h" +#include "PltSvnVersion.h" +#include "PltTime.h" + +#ifdef PLT_DEVICE_HEADERS_INCLUDE +#include "PltMediaServer.h" +#include "PltMediaBrowser.h" +#include "PltMediaRenderer.h" +#include "PltMediaController.h" +#endif + +#endif /* _PLATINUM_H_ */ diff --git a/modules/platinum/SDK/include/PltAction.h b/modules/platinum/SDK/include/PltAction.h new file mode 100644 index 0000000..1610613 --- /dev/null +++ b/modules/platinum/SDK/include/PltAction.h @@ -0,0 +1,168 @@ +/***************************************************************** +| +| Platinum - Service Action +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_ACTION_H_ +#define _PLT_ACTION_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltArgument.h" +#include "PltDeviceData.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_Service; + +/*---------------------------------------------------------------------- +| PLT_ActionDesc ++---------------------------------------------------------------------*/ +class PLT_ActionDesc +{ +public: + PLT_ActionDesc(const char* name, PLT_Service* service); + ~PLT_ActionDesc(); + + NPT_Array<PLT_ArgumentDesc*>& GetArgumentDescs() { + return m_ArgumentDescs; + } + + const NPT_String& GetName() const { return m_Name;} + PLT_ArgumentDesc* GetArgumentDesc(const char* name); + NPT_Result GetSCPDXML(NPT_XmlElementNode* node); + PLT_Service* GetService(); + +protected: + //members + NPT_String m_Name; + PLT_Service* m_Service; + NPT_Array<PLT_ArgumentDesc*> m_ArgumentDescs; +}; + +/*---------------------------------------------------------------------- +| PLT_Action ++---------------------------------------------------------------------*/ +class PLT_Action +{ +public: + ~PLT_Action(); + + PLT_ActionDesc& GetActionDesc() { return m_ActionDesc; } + + NPT_Result GetArgumentValue(const char* name, NPT_String& value); + NPT_Result GetArgumentValue(const char* name, NPT_UInt32& value); + NPT_Result GetArgumentValue(const char* name, NPT_Int32& value); + NPT_Result GetArgumentValue(const char* name, bool& value); + NPT_Result VerifyArgumentValue(const char* name, const char* value); + NPT_Result VerifyArguments(bool input); + NPT_Result SetArgumentOutFromStateVariable(const char* name); + NPT_Result SetArgumentsOutFromStateVariable(); + NPT_Result SetArgumentValue(const char* name, const char* value); + + NPT_Result SetError(unsigned int code, const char* description); + const char* GetError(unsigned int& code); + unsigned int GetErrorCode(); + + NPT_Result FormatSoapRequest(NPT_OutputStream& stream); + NPT_Result FormatSoapResponse(NPT_OutputStream& stream); + + static NPT_Result FormatSoapError(unsigned int code, + NPT_String desc, + NPT_OutputStream& stream); + +private: + // only PLT_DeviceHost and PLT_CtrlPoint can instantiate those directly + friend class PLT_DeviceHost; + friend class PLT_CtrlPoint; + PLT_Action(PLT_ActionDesc& action_desc); + PLT_Action(PLT_ActionDesc& action_desc, PLT_DeviceDataReference& root_device); + +private: + NPT_Result SetArgumentOutFromStateVariable(PLT_ArgumentDesc* arg_desc); + PLT_Argument* GetArgument(const char* name); + +protected: + // members + PLT_ActionDesc& m_ActionDesc; + PLT_Arguments m_Arguments; + unsigned int m_ErrorCode; + NPT_String m_ErrorDescription; + // keep reference to device to prevent it + // from being released during action lifetime + PLT_DeviceDataReference m_RootDevice; +}; + +typedef NPT_Reference<PLT_Action> PLT_ActionReference; + +/*---------------------------------------------------------------------- +| PLT_GetSCPDXMLIterator ++---------------------------------------------------------------------*/ +template <class T> +class PLT_GetSCPDXMLIterator +{ +public: + PLT_GetSCPDXMLIterator<T>(NPT_XmlElementNode* node) : + m_Node(node) {} + + NPT_Result operator()(T* const & data) const { + return data->GetSCPDXML(m_Node); + } + +private: + NPT_XmlElementNode* m_Node; +}; + +/*---------------------------------------------------------------------- +| PLT_ActionDescNameFinder ++---------------------------------------------------------------------*/ +class PLT_ActionDescNameFinder +{ +public: + // methods + PLT_ActionDescNameFinder(PLT_Service* service, const char* name) : + m_Service(service), m_Name(name) {} + virtual ~PLT_ActionDescNameFinder() {} + + bool operator()(const PLT_ActionDesc* const & action_desc) const { + return action_desc->GetName().Compare(m_Name, true) ? false : true; + } + +private: + // members + PLT_Service* m_Service; + NPT_String m_Name; +}; + +#endif /* _PLT_ACTION_H_ */ diff --git a/modules/platinum/SDK/include/PltArgument.h b/modules/platinum/SDK/include/PltArgument.h new file mode 100644 index 0000000..fe4229c --- /dev/null +++ b/modules/platinum/SDK/include/PltArgument.h @@ -0,0 +1,142 @@ +/***************************************************************** +| +| Platinum - Action Argument +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_ARGUMENT_H_ +#define _PLT_ARGUMENT_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_StateVariable; +class PLT_Argument; +class PLT_ActionDesc; +typedef NPT_Array<PLT_Argument*> PLT_Arguments; + +/*---------------------------------------------------------------------- +| PLT_ArgumentDesc ++---------------------------------------------------------------------*/ +class PLT_ArgumentDesc +{ +public: + PLT_ArgumentDesc(const char* name, + NPT_Ordinal position, + const char* direction = "in", + PLT_StateVariable* variable = NULL, + bool has_ret = false); + + // accessor methods + NPT_Result GetSCPDXML(NPT_XmlElementNode* node); + const NPT_String& GetName() const { return m_Name; } + const NPT_String& GetDirection() const { return m_Direction; } + NPT_Ordinal GetPosition() { return m_Position; } + PLT_StateVariable* GetRelatedStateVariable() { return m_RelatedStateVariable; } + bool HasRetValue() { return m_HasReturnValue; } + +protected: + NPT_String m_Name; + NPT_Ordinal m_Position; + NPT_String m_Direction; + PLT_StateVariable* m_RelatedStateVariable; + bool m_HasReturnValue; +}; + +/*---------------------------------------------------------------------- +| PLT_Argument ++---------------------------------------------------------------------*/ +class PLT_Argument +{ +public: + PLT_Argument(PLT_ArgumentDesc& arg_desc); + + // class methods + static NPT_Result CreateArgument(PLT_ActionDesc& action_desc, + const char* arg_name, + const char* arg_value, + PLT_Argument*& arg); + + // accessor methods + PLT_ArgumentDesc& GetDesc() { return m_ArgDesc; } + NPT_Ordinal GetPosition() { return m_ArgDesc.GetPosition(); } + NPT_Result SetValue(const char* value); + const NPT_String& GetValue(); + +private: + NPT_Result ValidateValue(const char* value); + +protected: + PLT_ArgumentDesc& m_ArgDesc; + NPT_String m_Value; +}; + +/*---------------------------------------------------------------------- +| PLT_ArgumentNameFinder ++---------------------------------------------------------------------*/ +class PLT_ArgumentNameFinder +{ +public: + // methods + PLT_ArgumentNameFinder(const char* name) : m_Name(name) {} + + bool operator()(PLT_Argument* const & argument) const { + return argument->GetDesc().GetName().Compare(m_Name, true) ? false : true; + } + +private: + // members + NPT_String m_Name; +}; + +/*---------------------------------------------------------------------- +| PLT_ArgumentDescNameFinder ++---------------------------------------------------------------------*/ +class PLT_ArgumentDescNameFinder +{ +public: + // methods + PLT_ArgumentDescNameFinder(const char* name) : m_Name(name) {} + + bool operator()(PLT_ArgumentDesc* const & arg_desc) const { + return arg_desc->GetName().Compare(m_Name, true) ? false : true; + } + +private: + // members + NPT_String m_Name; +}; + +#endif /* _PLT_ARGUMENT_H_ */ diff --git a/modules/platinum/SDK/include/PltConstants.h b/modules/platinum/SDK/include/PltConstants.h new file mode 100644 index 0000000..79cdb30 --- /dev/null +++ b/modules/platinum/SDK/include/PltConstants.h @@ -0,0 +1,59 @@ +/***************************************************************** +| +| Platinum - UPnP Constants +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_UPNP_CONSTANTS_H_ +#define _PLT_UPNP_CONSTANTS_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| PLT_Constants ++---------------------------------------------------------------------*/ +class PLT_Constants +{ +public: + // class methods + static PLT_Constants& GetInstance(); + + PLT_Constants(); + ~PLT_Constants() {}; + + // members + NPT_TimeInterval m_DefaultDeviceLease; + NPT_TimeInterval m_DefaultSubscribeLease; +}; + +#endif /* _PLT_UPNP_CONSTANTS_H_ */ diff --git a/modules/platinum/SDK/include/PltCtrlPoint.h b/modules/platinum/SDK/include/PltCtrlPoint.h new file mode 100644 index 0000000..4bf525e --- /dev/null +++ b/modules/platinum/SDK/include/PltCtrlPoint.h @@ -0,0 +1,203 @@ +/***************************************************************** +| +| Platinum - Control Point +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_CONTROL_POINT_H_ +#define _PLT_CONTROL_POINT_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltService.h" +#include "PltHttpServerListener.h" +#include "PltSsdpListener.h" +#include "PltDeviceData.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_HttpServer; +class PLT_CtrlPointHouseKeepingTask; +class PLT_SsdpSearchTask; +class PLT_SsdpListenTask; +class PLT_CtrlPointGetSCPDRequest; + +/*---------------------------------------------------------------------- +| PLT_CtrlPointListener class ++---------------------------------------------------------------------*/ +class PLT_CtrlPointListener +{ +public: + virtual ~PLT_CtrlPointListener() {} + + virtual NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device) = 0; + virtual NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device) = 0; + virtual NPT_Result OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata) = 0; + virtual NPT_Result OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars) = 0; +}; + +typedef NPT_List<PLT_CtrlPointListener*> PLT_CtrlPointListenerList; + +/*---------------------------------------------------------------------- +| PLT_CtrlPoint class ++---------------------------------------------------------------------*/ +class PLT_CtrlPoint : public PLT_SsdpPacketListener, + public PLT_SsdpSearchResponseListener +{ +public: + PLT_CtrlPoint(const char* search_criteria = "upnp:rootdevice"); // pass NULL to prevent repeated automatic search + + // delegation + NPT_Result AddListener(PLT_CtrlPointListener* listener); + NPT_Result RemoveListener(PLT_CtrlPointListener* listener); + + // discovery + void IgnoreUUID(const char* uuid); + NPT_Result InspectDevice(const char* location, + const char* uuid, + NPT_Timeout leasetime = PLT_Constants::GetInstance().m_DefaultDeviceLease); + NPT_Result Search(const NPT_HttpUrl& url = NPT_HttpUrl("239.255.255.250", 1900, "*"), + const char* target = "upnp:rootdevice", + NPT_Cardinal mx = 5, + NPT_Timeout frequency = 50000); // pass 0 for one time only + NPT_Result Discover(const NPT_HttpUrl& url = NPT_HttpUrl("239.255.255.250", 1900, "*"), + const char* target = "ssdp:all", + NPT_Cardinal mx = 5, + NPT_Timeout frequency = 50000); // pass 0 for one time only + + // actions + NPT_Result FindActionDesc(PLT_DeviceDataReference& device, + const char* service_type, + const char* action_name, + PLT_ActionDesc*& action_desc); + NPT_Result CreateAction(PLT_DeviceDataReference& device, + const char* service_type, + const char* action_name, + PLT_ActionReference& action); + NPT_Result InvokeAction(PLT_ActionReference& action, void* userdata = NULL); + + // events + NPT_Result Subscribe(PLT_Service* service, + bool cancel = false, + void* userdata = NULL); + + // NPT_HttpRequestHandler methods + virtual NPT_Result ProcessHttpRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + + // PLT_SsdpSearchResponseListener methods + virtual NPT_Result ProcessSsdpSearchResponse(NPT_Result res, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); + // PLT_SsdpPacketListener method + virtual NPT_Result OnSsdpPacket(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context); + +protected: + virtual ~PLT_CtrlPoint(); + + NPT_Result Start(PLT_SsdpListenTask* task); + NPT_Result Stop(PLT_SsdpListenTask* task); + + NPT_Result ProcessSsdpNotify(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context); + NPT_Result ProcessSsdpMessage(NPT_HttpMessage* message, + const NPT_HttpRequestContext& context, + NPT_String& uuid); + NPT_Result ProcessGetDescriptionResponse(NPT_Result res, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response, + PLT_DeviceDataReference& root_device); + NPT_Result ProcessGetSCPDResponse(NPT_Result res, + PLT_CtrlPointGetSCPDRequest* request, + NPT_HttpResponse* response, + PLT_DeviceDataReference& root_device); + NPT_Result ProcessActionResponse(NPT_Result res, + NPT_HttpResponse* response, + PLT_ActionReference& action, + void* userdata); + NPT_Result ProcessSubscribeResponse(NPT_Result res, + NPT_HttpResponse* response, + PLT_Service* service, + void* userdata); + NPT_Result ProcessHttpNotify(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); +private: + // methods + NPT_Result RenewSubscribers(); + NPT_Result RenewSubscriber(PLT_EventSubscriber& subscriber); + NPT_Result DoHouseKeeping(); + NPT_Result FetchDeviceSCPDs(PLT_HttpClientSocketTask& task, + PLT_DeviceDataReference& device, + NPT_Cardinal level); + NPT_Result FindDevice(const char* uuid, PLT_DeviceDataReference& device, bool return_root = false); + NPT_Result AddDevice(PLT_DeviceDataReference& data); + NPT_Result NotifyDeviceReady(PLT_DeviceDataReference& data); + NPT_Result RemoveDevice(PLT_DeviceDataReference& data); + NPT_Result NotifyDeviceRemoved(PLT_DeviceDataReference& data); + NPT_Result CleanupDevice(PLT_DeviceDataReference& data); + + NPT_Result ParseFault(PLT_ActionReference& action, NPT_XmlElementNode* fault); + PLT_SsdpSearchTask* CreateSearchTask(const NPT_HttpUrl& url, + const char* target, + NPT_Cardinal mx, + NPT_Timeout frequency, + const NPT_IpAddress& address); + +private: + friend class NPT_Reference<PLT_CtrlPoint>; + friend class PLT_UPnP; + friend class PLT_UPnP_CtrlPointStartIterator; + friend class PLT_UPnP_CtrlPointStopIterator; + friend class PLT_EventSubscriberRemoverIterator; + friend class PLT_CtrlPointGetDescriptionTask; + friend class PLT_CtrlPointGetSCPDTask; + friend class PLT_CtrlPointInvokeActionTask; + friend class PLT_CtrlPointHouseKeepingTask; + friend class PLT_CtrlPointSubscribeEventTask; + + NPT_List<NPT_String> m_UUIDsToIgnore; + NPT_Lock<PLT_CtrlPointListenerList> m_ListenerList; + PLT_HttpServer* m_EventHttpServer; + NPT_HttpRequestHandler* m_EventHttpServerHandler; + PLT_TaskManager m_TaskManager; + NPT_Lock<NPT_List<PLT_DeviceDataReference> > m_Devices; + NPT_Lock<NPT_List<PLT_EventSubscriber*> > m_Subscribers; + NPT_String m_SearchCriteria; +}; + +typedef NPT_Reference<PLT_CtrlPoint> PLT_CtrlPointReference; + +#endif /* _PLT_CONTROL_POINT_H_ */ diff --git a/modules/platinum/SDK/include/PltCtrlPointTask.h b/modules/platinum/SDK/include/PltCtrlPointTask.h new file mode 100644 index 0000000..ffedf87 --- /dev/null +++ b/modules/platinum/SDK/include/PltCtrlPointTask.h @@ -0,0 +1,184 @@ +/***************************************************************** +| +| Platinum - Control Point Tasks +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_CONTROL_POINT_TASK_H_ +#define _PLT_CONTROL_POINT_TASK_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltHttpClientTask.h" +#include "PltDatagramStream.h" +#include "PltDeviceData.h" +#include "PltCtrlPoint.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_Action; + +/*---------------------------------------------------------------------- +| PLT_CtrlPointGetDescriptionTask class ++---------------------------------------------------------------------*/ +class PLT_CtrlPointGetDescriptionTask : public PLT_HttpClientSocketTask +{ +public: + PLT_CtrlPointGetDescriptionTask(const NPT_HttpUrl& url, + PLT_CtrlPoint* ctrl_point, + PLT_DeviceDataReference& root_device); + virtual ~PLT_CtrlPointGetDescriptionTask(); + +protected: + // PLT_HttpClientSocketTask methods + NPT_Result ProcessResponse(NPT_Result res, + NPT_HttpRequest* request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); + +protected: + PLT_CtrlPoint* m_CtrlPoint; + PLT_DeviceDataReference m_RootDevice; +}; + +/*---------------------------------------------------------------------- +| PLT_CtrlPointGetSCPDRequest class ++---------------------------------------------------------------------*/ +class PLT_CtrlPointGetSCPDRequest : public NPT_HttpRequest +{ +public: + PLT_CtrlPointGetSCPDRequest(const char* url, + const char* method, + const char* protocol) : + NPT_HttpRequest(url, method, protocol) {} + ~PLT_CtrlPointGetSCPDRequest() {} + + // members + PLT_Service* m_Service; +}; + +/*---------------------------------------------------------------------- +| PLT_CtrlPointGetSCPDTask class ++---------------------------------------------------------------------*/ +class PLT_CtrlPointGetSCPDTask : public PLT_HttpClientSocketTask +{ +public: + PLT_CtrlPointGetSCPDTask(PLT_CtrlPoint* ctrl_point, + PLT_DeviceDataReference& root_device); + virtual ~PLT_CtrlPointGetSCPDTask(); + +protected: + // PLT_HttpClientSocketTask methods + NPT_Result ProcessResponse(NPT_Result res, + NPT_HttpRequest* request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); + +protected: + PLT_CtrlPoint* m_CtrlPoint; + PLT_DeviceDataReference m_RootDevice; +}; + +/*---------------------------------------------------------------------- +| PLT_CtrlPointInvokeActionTask class ++---------------------------------------------------------------------*/ +class PLT_CtrlPointInvokeActionTask : public PLT_HttpClientSocketTask +{ +public: + PLT_CtrlPointInvokeActionTask(NPT_HttpRequest* request, + PLT_CtrlPoint* ctrl_point, + PLT_ActionReference& action, + void* userdata); + virtual ~PLT_CtrlPointInvokeActionTask(); + +protected: + // PLT_HttpClientSocketTask methods + NPT_Result ProcessResponse(NPT_Result res, + NPT_HttpRequest* request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); + +protected: + PLT_CtrlPoint* m_CtrlPoint; + PLT_ActionReference m_Action; + void* m_Userdata; +}; + +/*---------------------------------------------------------------------- +| PLT_CtrlPointHouseKeepingTask class ++---------------------------------------------------------------------*/ +class PLT_CtrlPointHouseKeepingTask : public PLT_ThreadTask +{ +public: + PLT_CtrlPointHouseKeepingTask(PLT_CtrlPoint* ctrl_point, + NPT_TimeInterval timer = NPT_TimeInterval(5, 0)); + +protected: + ~PLT_CtrlPointHouseKeepingTask() {} + + // PLT_ThreadTask methods + virtual void DoRun(); + +protected: + PLT_CtrlPoint* m_CtrlPoint; + NPT_TimeInterval m_Timer; +}; + +/*---------------------------------------------------------------------- +| PLT_CtrlPointSubscribeEventTask class ++---------------------------------------------------------------------*/ +class PLT_CtrlPointSubscribeEventTask : public PLT_HttpClientSocketTask +{ +public: + PLT_CtrlPointSubscribeEventTask(NPT_HttpRequest* request, + PLT_CtrlPoint* ctrl_point, + PLT_DeviceDataReference &device, + PLT_Service* service, + void* userdata = NULL); + virtual ~PLT_CtrlPointSubscribeEventTask(); + +protected: + // PLT_HttpClientSocketTask methods + NPT_Result ProcessResponse(NPT_Result res, + NPT_HttpRequest* request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); + +protected: + PLT_CtrlPoint* m_CtrlPoint; + PLT_Service* m_Service; + PLT_DeviceDataReference m_Device; // force to keep a reference to device owning m_Service + void* m_Userdata; +}; + +#endif /* _PLT_CONTROL_POINT_TASK_H_ */ diff --git a/modules/platinum/SDK/include/PltDatagramStream.h b/modules/platinum/SDK/include/PltDatagramStream.h new file mode 100644 index 0000000..d8fba74 --- /dev/null +++ b/modules/platinum/SDK/include/PltDatagramStream.h @@ -0,0 +1,99 @@ +/***************************************************************** +| +| Platinum - Datagram Stream +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_DATAGRAM_H_ +#define _PLT_DATAGRAM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| PLT_InputDatagramStream ++---------------------------------------------------------------------*/ +class PLT_InputDatagramStream : public NPT_InputStream +{ +public: + // methods + PLT_InputDatagramStream(NPT_UdpSocket* socket); + virtual ~PLT_InputDatagramStream(); + + NPT_Result GetInfo(NPT_SocketInfo& info); + + // NPT_InputStream methods + NPT_Result Read(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read = 0); + + NPT_Result Seek(NPT_Position offset) { NPT_COMPILER_UNUSED(offset); return NPT_FAILURE; } + NPT_Result Skip(NPT_Size offset) { NPT_COMPILER_UNUSED(offset); return NPT_FAILURE; } + NPT_Result Tell(NPT_Position& offset){ NPT_COMPILER_UNUSED(offset); return NPT_FAILURE; } + NPT_Result GetSize(NPT_LargeSize& size) { NPT_COMPILER_UNUSED(size); return NPT_FAILURE; } + NPT_Result GetAvailable(NPT_LargeSize& available) { NPT_COMPILER_UNUSED(available); return NPT_FAILURE; } + +protected: + NPT_UdpSocket* m_Socket; + NPT_SocketInfo m_Info; +}; + +typedef NPT_Reference<PLT_InputDatagramStream> PLT_InputDatagramStreamReference; + +/*---------------------------------------------------------------------- +| PLT_OutputDatagramStream ++---------------------------------------------------------------------*/ +class PLT_OutputDatagramStream : public NPT_OutputStream +{ +public: + // methods + PLT_OutputDatagramStream(NPT_UdpSocket* socket, + NPT_Size size = 4096, + const NPT_SocketAddress* address = NULL); + virtual ~PLT_OutputDatagramStream(); + + // NPT_OutputStream methods + NPT_Result Write(const void* buffer, NPT_Size bytes_to_write, NPT_Size* bytes_written = NULL); + NPT_Result Flush(); + + NPT_Result Seek(NPT_Position offset) { NPT_COMPILER_UNUSED(offset); return NPT_FAILURE; } + NPT_Result Tell(NPT_Position& offset) { NPT_COMPILER_UNUSED(offset); return NPT_FAILURE; } + +protected: + NPT_UdpSocket* m_Socket; + NPT_DataBuffer m_Buffer; + NPT_SocketAddress* m_Address; +}; + +typedef NPT_Reference<PLT_OutputDatagramStream> PLT_OutputDatagramStreamReference; + +#endif /* _PLT_DATAGRAM_H_ */ diff --git a/modules/platinum/SDK/include/PltDeviceData.h b/modules/platinum/SDK/include/PltDeviceData.h new file mode 100644 index 0000000..e616748 --- /dev/null +++ b/modules/platinum/SDK/include/PltDeviceData.h @@ -0,0 +1,215 @@ +/***************************************************************** +| +| Platinum - Device Data +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_DEVICE_DATA_H_ +#define _PLT_DEVICE_DATA_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltConstants.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_Service; +class PLT_DeviceData; + +typedef NPT_Reference<PLT_DeviceData> PLT_DeviceDataReference; +typedef NPT_List<PLT_DeviceDataReference> PLT_DeviceDataReferenceList; + +/*---------------------------------------------------------------------- +| PLT_DeviceIcon class ++---------------------------------------------------------------------*/ +class PLT_DeviceIcon +{ +public: + PLT_DeviceIcon(const char* mimetype = "", + NPT_Int32 width = 0, + NPT_Int32 height = 0, + NPT_Int32 depth = 0, + const char* urlpath = "") : + m_MimeType(mimetype), + m_Width(width), + m_Height(height), + m_Depth(depth), + m_UrlPath(urlpath) {} + virtual ~PLT_DeviceIcon() {} + + NPT_String m_MimeType; + NPT_Int32 m_Width; + NPT_Int32 m_Height; + NPT_Int32 m_Depth; + NPT_String m_UrlPath; +}; + +/*---------------------------------------------------------------------- +| PLT_DeviceData class ++---------------------------------------------------------------------*/ +class PLT_DeviceData +{ +public: + PLT_DeviceData( + NPT_HttpUrl description_url = NPT_HttpUrl(NULL, 0, "/"), + const char* uuid = "", + NPT_TimeInterval lease_time = PLT_Constants::GetInstance().m_DefaultDeviceLease, + const char* device_type = "", + const char* friendly_name = ""); + + /* Getters */ + virtual NPT_Result GetDescription(NPT_String& desc); + virtual NPT_String GetDescriptionUrl(const char* bind_addr = NULL); + virtual NPT_HttpUrl GetURLBase(); + virtual NPT_HttpUrl NormalizeURL(const NPT_String& url); + virtual NPT_Result GetDescription(NPT_XmlElementNode* parent, NPT_XmlElementNode** device = NULL); + virtual NPT_String GetIconUrl(const char* mimetype = NULL, NPT_Int32 maxsize = 0, NPT_Int32 maxdepth = 0); + + const NPT_TimeInterval& GetLeaseTime() const { return m_LeaseTime; } + const NPT_String& GetUUID() const { return m_UUID; } + const NPT_String& GetFriendlyName() const { return m_FriendlyName; } + const NPT_String& GetType() const { return m_DeviceType; } + const NPT_String& GetModelDescription() const { return m_ModelDescription; } + const NPT_String& GetParentUUID() const { return m_ParentUUID; } + bool IsRoot() { return m_ParentUUID.IsEmpty(); } + + const NPT_Array<PLT_Service*>& GetServices() const { return m_Services; } + const NPT_Array<PLT_DeviceDataReference>& GetEmbeddedDevices() const { return m_EmbeddedDevices; } + + NPT_Result FindEmbeddedDevice(const char* uuid, PLT_DeviceDataReference& device); + NPT_Result FindEmbeddedDeviceByType(const char* type, PLT_DeviceDataReference& device); + NPT_Result FindServiceById(const char* id, PLT_Service*& service); + NPT_Result FindServiceByType(const char* type, PLT_Service*& service); + NPT_Result FindServiceBySCPDURL(const char* url, PLT_Service*& service); + NPT_Result FindServiceByControlURL(const char* url, PLT_Service*& service, bool recursive = false); + NPT_Result FindServiceByEventSubURL(const char* url, PLT_Service*& service, bool recursive = false); + + /* called by PLT_Device subclasses */ + NPT_Result AddEmbeddedDevice(PLT_DeviceDataReference& device); + NPT_Result RemoveEmbeddedDevice(PLT_DeviceDataReference& device); + NPT_Result AddService(PLT_Service* service); + + operator const char* (); + +protected: + virtual ~PLT_DeviceData(); + virtual void Cleanup(); + virtual NPT_Result OnAddExtraInfo(NPT_XmlElementNode* /*device_node*/) { return NPT_SUCCESS; } + +private: + /* called by PLT_CtrlPoint when new device is discovered */ + NPT_Result SetURLBase(NPT_HttpUrl& url_base); + NPT_TimeStamp GetLeaseTimeLastUpdate(); + NPT_Result SetLeaseTime(NPT_TimeInterval lease_time); + NPT_Result SetDescription(const char* szDescription, + const NPT_IpAddress& local_iface_ip); + NPT_Result SetDescriptionDevice(NPT_XmlElementNode* device_node); + +public: + NPT_String m_Manufacturer; + NPT_String m_ManufacturerURL; + NPT_String m_ModelDescription; + NPT_String m_ModelName; + NPT_String m_ModelNumber; + NPT_String m_ModelURL; + NPT_String m_SerialNumber; + NPT_String m_UPC; + NPT_String m_PresentationURL; + NPT_String m_DlnaDoc; + NPT_String m_DlnaCap; + NPT_String m_AggregationFlags; + +protected: + friend class NPT_Reference<PLT_DeviceData>; + friend class PLT_CtrlPoint; + friend class PLT_DeviceReadyIterator; + friend class PLT_DeviceHost; + + //members + NPT_String m_ParentUUID; + NPT_String m_UUID; + NPT_HttpUrl m_URLDescription; + NPT_HttpUrl m_URLBase; + NPT_String m_DeviceType; + NPT_String m_FriendlyName; + NPT_TimeInterval m_LeaseTime; + NPT_TimeStamp m_LeaseTimeLastUpdate; + NPT_Array<PLT_Service*> m_Services; + NPT_Array<PLT_DeviceDataReference> m_EmbeddedDevices; + NPT_Array<PLT_DeviceIcon> m_Icons; + + /* IP address of interface used when retrieving device description. + We need the info for the control point subscription callback */ + NPT_IpAddress m_LocalIfaceIp; + NPT_String m_Representation; +}; + +/*---------------------------------------------------------------------- +| PLT_DeviceDataFinder ++---------------------------------------------------------------------*/ +class PLT_DeviceDataFinder +{ +public: + // methods + PLT_DeviceDataFinder(const char* uuid) : m_UUID(uuid) {} + virtual ~PLT_DeviceDataFinder() {} + + bool operator()(const PLT_DeviceDataReference& data) const { + return data->GetUUID().Compare(m_UUID, true) ? false : true; + } + +private: + // members + NPT_String m_UUID; +}; + +/*---------------------------------------------------------------------- +| PLT_DeviceDataFinderByType ++---------------------------------------------------------------------*/ +class PLT_DeviceDataFinderByType +{ +public: + // methods + PLT_DeviceDataFinderByType(const char* type) : m_Type(type) {} + virtual ~PLT_DeviceDataFinderByType() {} + + bool operator()(const PLT_DeviceDataReference& data) const { + return data->GetType().Compare(m_Type, true) ? false : true; + } + +private: + // members + NPT_String m_Type; +}; + +#endif /* _PLT_DEVICE_DATA_H_ */ diff --git a/modules/platinum/SDK/include/PltDeviceHost.h b/modules/platinum/SDK/include/PltDeviceHost.h new file mode 100644 index 0000000..83e409d --- /dev/null +++ b/modules/platinum/SDK/include/PltDeviceHost.h @@ -0,0 +1,166 @@ +/***************************************************************** +| +| Platinum - Device Host +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_DEVICE_HOST_H_ +#define _PLT_DEVICE_HOST_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltDeviceData.h" +#include "PltHttpServerListener.h" +#include "PltSsdpListener.h" +#include "PltTaskManager.h" +#include "PltAction.h" +#include "PltHttp.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_HttpServer; +class PLT_HttpServerHandler; +class PLT_SsdpDeviceAnnounceTask; +class PLT_SsdpListenTask; + +/*---------------------------------------------------------------------- +| PLT_DeviceHost class ++---------------------------------------------------------------------*/ +class PLT_DeviceHost : public PLT_DeviceData, + public PLT_SsdpPacketListener +{ +public: + PLT_DeviceHost(const char* description_path = "/", + const char* uuid = "", + const char* device_type = "", + const char* friendly_name = "", + bool show_ip = false, + NPT_UInt16 port = 0, + bool port_rebind = false); + + // public methods + virtual void SetBroadcast(bool broadcast) { m_Broadcast = broadcast; } + virtual NPT_UInt16 GetPort() { return m_Port; }; + + // NPT_HttpRequestHandler forward for control/event requests + virtual NPT_Result ProcessHttpRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + + // PLT_SsdpDeviceAnnounceTask & PLT_SsdpDeviceAnnounceUnicastTask + virtual NPT_Result Announce(PLT_DeviceData* device, + NPT_HttpRequest& request, + NPT_UdpSocket& socket, + bool byebye); + + virtual NPT_Result Announce(NPT_HttpRequest& request, + NPT_UdpSocket& socket, + bool byebye) { + return Announce(this, request, socket, byebye); + } + + // PLT_SsdpPacketListener method + virtual NPT_Result OnSsdpPacket(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context); + + // PLT_SsdpDeviceSearchListenTask + virtual NPT_Result ProcessSsdpSearchRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context); + + // PLT_SsdpDeviceSearchResponseTask + virtual NPT_Result SendSsdpSearchResponse(PLT_DeviceData* device, + NPT_HttpResponse& response, + NPT_UdpSocket& socket, + const char* st, + const NPT_SocketAddress* addr = NULL); + virtual NPT_Result SendSsdpSearchResponse(NPT_HttpResponse& response, + NPT_UdpSocket& socket, + const char* ST, + const NPT_SocketAddress* addr = NULL) { + return SendSsdpSearchResponse(this, response, socket, ST, addr); + } + +protected: + virtual ~PLT_DeviceHost(); + + // pure methods + virtual NPT_Result SetupServices(PLT_DeviceData& data) = 0; + + // setup methods + virtual NPT_Result SetupIcons(); + virtual NPT_Result SetupDevice(); + + // overridable methods + virtual NPT_Result AddIcon(const PLT_DeviceIcon& icon, + const char* filepath); + virtual NPT_Result AddIcon(const PLT_DeviceIcon& icon, + const void* data, + NPT_Size size, + bool copy = true); + virtual NPT_Result Start(PLT_SsdpListenTask* task); + virtual NPT_Result Stop(PLT_SsdpListenTask* task); + virtual NPT_Result SetupServiceSCPDHandler(PLT_Service* service); + virtual NPT_Result OnAction(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + virtual NPT_Result ProcessGetDescription(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + virtual NPT_Result ProcessHttpGetRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + virtual NPT_Result ProcessHttpPostRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + virtual NPT_Result ProcessHttpSubscriberRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + +protected: + friend class PLT_UPnP; + friend class PLT_UPnP_DeviceStartIterator; + friend class PLT_UPnP_DeviceStopIterator; + friend class PLT_Service; + friend class NPT_Reference<PLT_DeviceHost>; + +private: + PLT_TaskManager m_TaskManager; + PLT_HttpServer* m_HttpServer; + bool m_Broadcast; + NPT_UInt16 m_Port; + bool m_PortRebind; + NPT_List<NPT_HttpRequestHandler*> m_RequestHandlers; +}; + +typedef NPT_Reference<PLT_DeviceHost> PLT_DeviceHostReference; + +#endif /* _PLT_DEVICE_HOST_H_ */ diff --git a/modules/platinum/SDK/include/PltDidl.h b/modules/platinum/SDK/include/PltDidl.h new file mode 100644 index 0000000..6329b6a --- /dev/null +++ b/modules/platinum/SDK/include/PltDidl.h @@ -0,0 +1,130 @@ +/***************************************************************** +| +| Platinum - DIDL handling +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_DIDL_H_ +#define _PLT_DIDL_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltMediaItem.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#define PLT_FILTER_MASK_ALL 0xFFFFFFFF + +#define PLT_FILTER_MASK_CREATOR 0x00000001 +#define PLT_FILTER_MASK_ARTIST 0x00000002 +#define PLT_FILTER_MASK_ALBUM 0x00000004 +#define PLT_FILTER_MASK_GENRE 0x00000008 +#define PLT_FILTER_MASK_ALBUMARTURI 0x00000010 +#define PLT_FILTER_MASK_DESCRIPTION 0x00000020 +#define PLT_FILTER_MASK_SEARCHABLE 0x00000040 +#define PLT_FILTER_MASK_CHILDCOUNT 0x00000080 +#define PLT_FILTER_MASK_ORIGINALTRACK 0x00000100 +#define PLT_FILTER_MASK_ACTOR 0x00000200 +#define PLT_FILTER_MASK_AUTHOR 0x00000400 +#define PLT_FILTER_MASK_DATE 0x00000800 + +#define PLT_FILTER_MASK_RES 0x00010000 +#define PLT_FILTER_MASK_RES_DURATION 0x00020000 +#define PLT_FILTER_MASK_RES_SIZE 0x00040000 +#define PLT_FILTER_MASK_RES_PROTECTION 0x00080000 +#define PLT_FILTER_MASK_RES_RESOLUTION 0x00100000 +#define PLT_FILTER_MASK_RES_BITRATE 0x00200000 +#define PLT_FILTER_MASK_RES_BITSPERSAMPLE 0x00400000 +#define PLT_FILTER_MASK_RES_NRAUDIOCHANNELS 0x00800000 +#define PLT_FILTER_MASK_RES_SAMPLEFREQUENCY 0x01000000 + +#define PLT_FILTER_MASK_TOC 0x02000000 + +#define PLT_FILTER_FIELD_CREATOR "dc:creator" +#define PLT_FILTER_FIELD_DATE "dc:date" +#define PLT_FILTER_FIELD_ARTIST "upnp:artist" +#define PLT_FILTER_FIELD_ACTOR "upnp:actor" +#define PLT_FILTER_FIELD_AUTHOR "upnp:author" +#define PLT_FILTER_FIELD_ALBUM "upnp:album" +#define PLT_FILTER_FIELD_GENRE "upnp:genre" +#define PLT_FILTER_FIELD_ALBUMARTURI "upnp:albumArtURI" +#define PLT_FILTER_FIELD_DESCRIPTION "upnp:longDescription" +#define PLT_FILTER_FIELD_ORIGINALTRACK "upnp:originalTrackNumber" +#define PLT_FILTER_FIELD_SEARCHABLE "@searchable" +#define PLT_FILTER_FIELD_CHILDCOUNT "@childcount" +#define PLT_FILTER_FIELD_CONTAINER_CHILDCOUNT "container@childCount" +#define PLT_FILTER_FIELD_CONTAINER_SEARCHABLE "container@searchable" + +#define PLT_FILTER_FIELD_RES "res" +#define PLT_FILTER_FIELD_RES_DURATION "res@duration" +#define PLT_FILTER_FIELD_RES_SIZE "res@size" +#define PLT_FILTER_FIELD_RES_PROTECTION "res@protection" +#define PLT_FILTER_FIELD_RES_RESOLUTION "res@resolution" +#define PLT_FILTER_FIELD_RES_BITRATE "res@bitrate" +#define PLT_FILTER_FIELD_RES_BITSPERSAMPLE "res@bitsPerSample" +#define PLT_FILTER_FIELD_RES_NRAUDIOCHANNELS "res@nrAudioChannels" +#define PLT_FILTER_FIELD_RES_SAMPLEFREQUENCY "res@sampleFrequency" + +extern const char* didl_header; +extern const char* didl_footer; +extern const char* didl_namespace_dc; +extern const char* didl_namespace_upnp; + +/*---------------------------------------------------------------------- +| PLT_Didl class ++---------------------------------------------------------------------*/ +class PLT_Didl +{ +public: + static NPT_Result ToDidl(PLT_MediaObject& object, + NPT_String filter, + NPT_String& didl); + static NPT_Result FromDidl(const char* didl, + PLT_MediaObjectListReference& objects); + + static void AppendXmlEscape(NPT_String& out, const char* in); + static void AppendXmlUnEscape(NPT_String& out, const char* in); + static NPT_Result ParseTimeStamp(NPT_String timestamp, NPT_UInt32& seconds); + static void FormatTimeStamp(NPT_String& out, NPT_UInt32 seconds); + + static NPT_Result ParseTimeStamp(NPT_String in, NPT_TimeStamp& timestamp) { + NPT_UInt32 seconds; + NPT_Result res = ParseTimeStamp(in, seconds); + timestamp = NPT_TimeStamp(seconds, 0); + return res; + } + + static NPT_UInt32 ConvertFilterToMask(NPT_String filter); +}; + +#endif /* _PLT_DIDL_H_ */ diff --git a/modules/platinum/SDK/include/PltDownloader.h b/modules/platinum/SDK/include/PltDownloader.h new file mode 100644 index 0000000..4a497ab --- /dev/null +++ b/modules/platinum/SDK/include/PltDownloader.h @@ -0,0 +1,91 @@ +/***************************************************************** +| +|| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_DOWNLOADER_H_ +#define _PLT_DOWNLOADER_H_ + +/*---------------------------------------------------------------------- +| Includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltHttpClientTask.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_Downloader; + +/*---------------------------------------------------------------------- +| types ++---------------------------------------------------------------------*/ +typedef PLT_HttpClientTask<PLT_Downloader> PLT_HttpDownloadTask; + +typedef enum { + PLT_DOWNLOADER_IDLE, + PLT_DOWNLOADER_STARTED, + PLT_DOWNLOADER_DOWNLOADING, + PLT_DOWNLOADER_ERROR, + PLT_DOWNLOADER_SUCCESS +} Plt_DowloaderState; + +/*---------------------------------------------------------------------- +| PLT_Downloader class ++---------------------------------------------------------------------*/ +class PLT_Downloader +{ +public: + PLT_Downloader(PLT_TaskManager* task_manager, + const char* url, + NPT_OutputStreamReference& output); + virtual ~PLT_Downloader(); + + NPT_Result Start(); + NPT_Result Stop(); + Plt_DowloaderState GetState() { return m_State; } + + // PLT_HttpClientTask method + NPT_Result ProcessResponse(NPT_Result res, + NPT_HttpRequest* request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); + + +private: + // members + NPT_String m_URL; + NPT_OutputStreamReference m_Output; + PLT_TaskManager* m_TaskManager; + PLT_HttpDownloadTask* m_Task; + Plt_DowloaderState m_State; +}; + +#endif /* _PLT_DOWNLOADER_H_ */ diff --git a/modules/platinum/SDK/include/PltEvent.h b/modules/platinum/SDK/include/PltEvent.h new file mode 100644 index 0000000..b4a6c24 --- /dev/null +++ b/modules/platinum/SDK/include/PltEvent.h @@ -0,0 +1,141 @@ +/***************************************************************** +| +| Platinum - Event +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_EVENT_H_ +#define _PLT_EVENT_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltHttpClientTask.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_StateVariable; +class PLT_DeviceData; +class PLT_Service; +class PLT_TaskManager; +class PLT_CtrlPoint; + +/*---------------------------------------------------------------------- +| PLT_EventSubscriber class ++---------------------------------------------------------------------*/ +class PLT_EventSubscriber +{ +public: + PLT_EventSubscriber(PLT_TaskManager* task_manager, + PLT_Service* service, + const char* sid, + int timeout = -1); + ~PLT_EventSubscriber(); + + PLT_Service* GetService(); + NPT_Ordinal GetEventKey(); + NPT_Result SetEventKey(NPT_Ordinal value); + NPT_SocketAddress GetLocalIf(); + NPT_Result SetLocalIf(NPT_SocketAddress value); + NPT_TimeStamp GetExpirationTime(); + NPT_Result SetTimeout(NPT_Cardinal timeout); + const NPT_String& GetSID() const { return m_SID; } + NPT_Result FindCallbackURL(const char* callback_url); + NPT_Result AddCallbackURL(const char* callback_url); + NPT_Result Notify(NPT_List<PLT_StateVariable*>& vars); + +protected: + //members + PLT_TaskManager* m_TaskManager; + PLT_Service* m_Service; + NPT_Ordinal m_EventKey; + PLT_HttpClientSocketTask* m_SubscriberTask; + NPT_String m_SID; + NPT_SocketAddress m_LocalIf; + NPT_Array<NPT_String> m_CallbackURLs; + NPT_TimeStamp m_ExpirationTime; +}; + +/*---------------------------------------------------------------------- +| PLT_EventSubscriberFinderBySID ++---------------------------------------------------------------------*/ +class PLT_EventSubscriberFinderBySID +{ +public: + // methods + PLT_EventSubscriberFinderBySID(const char* sid) : m_SID(sid) {} + + bool operator()(PLT_EventSubscriber* const & sub) const { + return m_SID.Compare(sub->GetSID(), true) ? false : true; + } + +private: + // members + NPT_String m_SID; +}; + +/*---------------------------------------------------------------------- +| PLT_EventSubscriberFinderByCallbackURL ++---------------------------------------------------------------------*/ +class PLT_EventSubscriberFinderByCallbackURL +{ +public: + // methods + PLT_EventSubscriberFinderByCallbackURL(const char* callback_url) : + m_CallbackURL(callback_url) {} + + bool operator()(PLT_EventSubscriber* const & sub) const { + return NPT_SUCCEEDED(sub->FindCallbackURL(m_CallbackURL)); + } + +private: + // members + NPT_String m_CallbackURL; +}; + +/*---------------------------------------------------------------------- +| PLT_EventSubscriberFinderByService ++---------------------------------------------------------------------*/ +class PLT_EventSubscriberFinderByService +{ +public: + // methods + PLT_EventSubscriberFinderByService(PLT_Service* service) : m_Service(service) {} + virtual ~PLT_EventSubscriberFinderByService() {} + bool operator()(PLT_EventSubscriber* const & eventSub) const; + +private: + // members + PLT_Service* m_Service; +}; + +#endif /* _PLT_EVENT_H_ */ diff --git a/modules/platinum/SDK/include/PltFileMediaServer.h b/modules/platinum/SDK/include/PltFileMediaServer.h new file mode 100644 index 0000000..52fb70c --- /dev/null +++ b/modules/platinum/SDK/include/PltFileMediaServer.h @@ -0,0 +1,143 @@ +/***************************************************************** +| +| Platinum - File Media Server +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_FILE_MEDIA_SERVER_H_ +#define _PLT_FILE_MEDIA_SERVER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltMediaServer.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#define MAX_PATH_LENGTH 1024 +#define ALBUMART_QUERY "aa" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_MetadataHandler; + +/*---------------------------------------------------------------------- +| PLT_FileMediaServer class ++---------------------------------------------------------------------*/ +class PLT_FileMediaServer : public PLT_MediaServer +{ +public: + // class methods + static NPT_String BuildSafeResourceUri(const NPT_HttpUrl& base_uri, + const char* host, + const char* file_path); + + // constructor + PLT_FileMediaServer(const char* path, + const char* friendly_name, + bool show_ip = false, + const char* uuid = NULL, + NPT_UInt16 port = 0, + bool port_rebind = false); + + // overridable + virtual NPT_Result AddMetadataHandler(PLT_MetadataHandler* handler); + virtual NPT_Result ExtractResourcePath(const NPT_HttpUrl& url, NPT_String& file_path); + virtual NPT_String BuildResourceUri(const NPT_HttpUrl& base_uri, const char* host, const char* file_path); + +protected: + virtual ~PLT_FileMediaServer(); + + // overridable + virtual NPT_Result ProcessFileRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + // PLT_DeviceHost methods + virtual NPT_Result SetupDevice(); + virtual NPT_Result ProcessHttpGetRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + virtual NPT_Result ProcessGetDescription(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + // PLT_MediaServer methods + virtual NPT_Result OnBrowseMetadata(PLT_ActionReference& action, + const char* object_id, + const char* filter, + NPT_UInt32 starting_index, + NPT_UInt32 requested_count, + const NPT_List<NPT_String>& sort_criteria, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnBrowseDirectChildren(PLT_ActionReference& action, + const char* object_id, + const char* filter, + NPT_UInt32 starting_index, + NPT_UInt32 requested_count, + const NPT_List<NPT_String>& sort_criteria, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnSearchContainer(PLT_ActionReference& action, + const char* object_id, + const char* search_criteria, + const char* filter, + NPT_UInt32 starting_index, + NPT_UInt32 requested_count, + const NPT_List<NPT_String>& sort_criteria, + const PLT_HttpRequestContext& context); + + virtual NPT_Result ServeFile(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response, + const NPT_String& file_path); + virtual NPT_Result OnAlbumArtRequest(NPT_HttpResponse& response, + NPT_String file_path); + virtual NPT_Result GetFilePath(const char* object_id, NPT_String& filepath); + virtual bool ProcessFile(const NPT_String&) { return true;} + virtual PLT_MediaObject* BuildFromFilePath(const NPT_String& filepath, + const PLT_HttpRequestContext& context, + bool with_count = true, + bool keep_extension_in_title = false); + +public: + NPT_UInt16 m_FileServerPort; + +protected: + friend class PLT_MediaItem; + + NPT_String m_Path; + NPT_HttpUrl m_FileBaseUri; + NPT_HttpUrl m_AlbumArtBaseUri; + NPT_List<PLT_MetadataHandler*> m_MetadataHandlers; + bool m_FilterUnknownOut; +}; + +#endif /* _PLT_FILE_MEDIA_SERVER_H_ */ diff --git a/modules/platinum/SDK/include/PltHttp.h b/modules/platinum/SDK/include/PltHttp.h new file mode 100644 index 0000000..88b4c2a --- /dev/null +++ b/modules/platinum/SDK/include/PltHttp.h @@ -0,0 +1,135 @@ +/***************************************************************** +| +| Platinum - HTTP Helper +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_HTTP_H_ +#define _PLT_HTTP_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| PLT_HttpHelper ++---------------------------------------------------------------------*/ +class PLT_HttpHelper { + public: + static bool IsConnectionKeepAlive(NPT_HttpMessage& message); + static bool IsBodyStreamSeekable(NPT_HttpMessage& message); + + static NPT_Result ToLog(NPT_LoggerReference logger, int level, NPT_HttpRequest* request); + static NPT_Result ToLog(NPT_LoggerReference logger, int level, NPT_HttpResponse* response); + + static NPT_Result GetContentType(NPT_HttpMessage& message, NPT_String& type); + static void SetContentType(NPT_HttpMessage& message, const char* type); + static NPT_Result GetContentLength(NPT_HttpMessage& message, NPT_LargeSize& len); + static void SetContentLength(NPT_HttpMessage& message, NPT_LargeSize len); + + static NPT_Result GetHost(NPT_HttpRequest& request, NPT_String& value); + static void SetHost(NPT_HttpRequest& request, const char* host); + static NPT_Result GetRange(NPT_HttpRequest& request, NPT_Position& start, NPT_Position& end); + static void SetRange(NPT_HttpRequest& request, NPT_Position start, NPT_Position end = (NPT_Position)-1); + + static NPT_Result GetContentRange(NPT_HttpResponse& response, NPT_Position& start, NPT_Position& end, NPT_LargeSize& length); + static NPT_Result SetContentRange(NPT_HttpResponse& response, NPT_Position start, NPT_Position end, NPT_LargeSize length); + + static NPT_Result SetBody(NPT_HttpMessage& message, NPT_String& body); + static NPT_Result SetBody(NPT_HttpMessage& message, const char* body, NPT_Size len); + static NPT_Result SetBody(NPT_HttpMessage& message, NPT_InputStreamReference& stream, NPT_LargeSize len = 0); + + + static NPT_Result GetBody(NPT_HttpMessage& message, NPT_String& body); + static NPT_Result ParseBody(NPT_HttpMessage& message, NPT_XmlElementNode*& xml); + + static NPT_Result Connect(NPT_Socket& connection, + NPT_HttpRequest& request, + NPT_Timeout timeout = NPT_TIMEOUT_INFINITE); + static void SetBasicAuthorization(NPT_HttpRequest& request, const char* login, const char* password); +}; + +/*---------------------------------------------------------------------- +| PLT_HttpRequestContext ++---------------------------------------------------------------------*/ +class PLT_HttpRequestContext : public NPT_HttpRequestContext { +public: + // constructors and destructor + PLT_HttpRequestContext(NPT_HttpRequest& request) : + m_Request(request) {} + PLT_HttpRequestContext(NPT_HttpRequest& request, const NPT_HttpRequestContext& context) : + NPT_HttpRequestContext(&context.GetLocalAddress(), &context.GetRemoteAddress()), + m_Request(request) {} + virtual ~PLT_HttpRequestContext() {} + + NPT_HttpRequest& GetRequest() const { return m_Request; } + +private: + NPT_HttpRequest& m_Request; +}; + +/*---------------------------------------------------------------------- +| macros ++---------------------------------------------------------------------*/ +#if defined(NPT_CONFIG_ENABLE_LOGGING) +#define PLT_LOG_HTTP_MESSAGE_L(_logger, _level, _msg) \ + PLT_HttpHelper::ToLog((_logger), (_level), (_msg)) +#define PLT_LOG_HTTP_MESSAGE(_level, _msg) \ + PLT_HttpHelper::ToLog((_NPT_LocalLogger), (_level), (_msg)) + +#else /* NPT_CONFIG_ENABLE_LOGGING */ +#define PLT_LOG_HTTP_MESSAGE_L(_logger, _level, _msg) +#define PLT_LOG_HTTP_MESSAGE(_level, _msg) +#endif /* NPT_CONFIG_ENABLE_LOGGING */ + +/*---------------------------------------------------------------------- +| PLT_HttpRequestHandler ++---------------------------------------------------------------------*/ +template <class T> +class PLT_HttpRequestHandler : public NPT_HttpRequestHandler +{ +public: + PLT_HttpRequestHandler<T>(T* data) : m_Data(data) {} + virtual ~PLT_HttpRequestHandler<T>() {} + + // NPT_HttpRequestHandler methods + NPT_Result SetupResponse(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response) { + return m_Data->ProcessHttpRequest(request, context, response); + } + +private: + T* m_Data; +}; + + +#endif /* _PLT_HTTP_H_ */ diff --git a/modules/platinum/SDK/include/PltHttpClientTask.h b/modules/platinum/SDK/include/PltHttpClientTask.h new file mode 100644 index 0000000..65af073 --- /dev/null +++ b/modules/platinum/SDK/include/PltHttpClientTask.h @@ -0,0 +1,158 @@ +/***************************************************************** +| +| Platinum - HTTP Client Tasks +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_HTTP_CLIENT_TASK_H_ +#define _PLT_HTTP_CLIENT_TASK_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltHttp.h" +#include "PltThreadTask.h" + +/*---------------------------------------------------------------------- +| PLT_HttpTcpConnector ++---------------------------------------------------------------------*/ +class PLT_HttpTcpConnector : public NPT_HttpClient::Connector +{ +public: + PLT_HttpTcpConnector(); + virtual ~PLT_HttpTcpConnector(); + virtual NPT_Result Connect(const char* hostname, + NPT_UInt16 port, + NPT_Timeout connection_timeout, + NPT_Timeout io_timeout, + NPT_Timeout name_resolver_timeout, + NPT_InputStreamReference& input_stream, + NPT_OutputStreamReference& output_stream); + +public: + void GetInfo(NPT_SocketInfo& info) { info = m_SocketInfo;} + void Abort() { if (!m_Socket.IsNull()) m_Socket->Disconnect(); } + +private: + NPT_String m_HostName; + NPT_UInt16 m_Port; + NPT_InputStreamReference m_InputStream; + NPT_OutputStreamReference m_OutputStream; + NPT_SocketInfo m_SocketInfo; + NPT_Reference<NPT_Socket> m_Socket; +}; + +/*---------------------------------------------------------------------- +| PLT_HttpClientSocketTask class ++---------------------------------------------------------------------*/ +class PLT_HttpClientSocketTask : public PLT_ThreadTask +{ +friend class PLT_ThreadTask; + +public: + PLT_HttpClientSocketTask(NPT_HttpRequest* request = NULL, + bool wait_forever = false); + + virtual NPT_Result AddRequest(NPT_HttpRequest* request); + +protected: + virtual ~PLT_HttpClientSocketTask(); + +protected: + virtual NPT_Result SetConnector(PLT_HttpTcpConnector* connector); + + // PLT_ThreadTask methods + virtual void DoAbort(); + virtual void DoRun(); + + virtual NPT_Result ProcessResponse(NPT_Result res, + NPT_HttpRequest* request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); + +private: + NPT_Result GetNextRequest(NPT_HttpRequest*& request, NPT_Timeout timeout); + +protected: + NPT_HttpClient m_Client; + bool m_WaitForever; + NPT_Queue<NPT_HttpRequest> m_Requests; + NPT_Mutex m_ConnectorLock; + PLT_HttpTcpConnector* m_Connector; +}; + +/*---------------------------------------------------------------------- +| PLT_HttpClientTask class ++---------------------------------------------------------------------*/ +template <class T> +class PLT_HttpClientTask : public PLT_HttpClientSocketTask +{ +public: + PLT_HttpClientTask<T>(const NPT_HttpUrl& url, T* data) : + PLT_HttpClientSocketTask(new NPT_HttpRequest(url, "GET", NPT_HTTP_PROTOCOL_1_1)), + m_Data(data) {} + protected: + virtual ~PLT_HttpClientTask<T>() {} + +protected: + // PLT_HttpClientSocketTask method + NPT_Result ProcessResponse(NPT_Result res, + NPT_HttpRequest* request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response) { + return m_Data->ProcessResponse(res, request, context, response); + } + +protected: + T* m_Data; +}; + +/*---------------------------------------------------------------------- +| PLT_FileHttpClientTask class ++---------------------------------------------------------------------*/ +class PLT_FileHttpClientTask : public PLT_HttpClientSocketTask +{ +public: + PLT_FileHttpClientTask(const NPT_HttpUrl& url) : + PLT_HttpClientSocketTask(new NPT_HttpRequest(url, "GET", NPT_HTTP_PROTOCOL_1_1)) {} + +protected: + virtual ~PLT_FileHttpClientTask() {} + +protected: + // PLT_HttpClientSocketTask method + NPT_Result ProcessResponse(NPT_Result res, + NPT_HttpRequest* request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); +}; + +#endif /* _PLT_HTTP_CLIENT_TASK_H_ */ diff --git a/modules/platinum/SDK/include/PltHttpServer.h b/modules/platinum/SDK/include/PltHttpServer.h new file mode 100644 index 0000000..1a667ee --- /dev/null +++ b/modules/platinum/SDK/include/PltHttpServer.h @@ -0,0 +1,98 @@ +/***************************************************************** +| +| Platinum - HTTP Server +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_HTTP_SERVER_H_ +#define _PLT_HTTP_SERVER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltHttpServerListener.h" +#include "PltHttpServerTask.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_HttpServerStartIterator; + +/*---------------------------------------------------------------------- +| PLT_HttpServer class ++---------------------------------------------------------------------*/ +class PLT_HttpServer : public PLT_HttpServerListener, + public NPT_HttpServer +{ + friend class PLT_HttpServerTask<class PLT_HttpServer>; + friend class PLT_HttpServerStartIterator; + +public: + PLT_HttpServer(unsigned int port = 0, + bool port_rebind = false, + NPT_Cardinal max_clients = 0, + bool reuse_address = false); + virtual ~PLT_HttpServer(); + + // PLT_HttpServerListener method + virtual NPT_Result ProcessHttpRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse*& response, + bool& headers_only); + + virtual NPT_Result Start(); + virtual NPT_Result Stop(); + virtual unsigned int GetPort() { return m_Port; } + +private: + PLT_TaskManager* m_TaskManager; + unsigned int m_Port; + bool m_PortRebind; + bool m_ReuseAddress; + PLT_HttpServerListenTask* m_HttpListenTask; +}; + +/*---------------------------------------------------------------------- +| PLT_FileServer class ++---------------------------------------------------------------------*/ +class PLT_FileServer +{ +public: + // class methods + static NPT_Result ServeFile(NPT_HttpResponse& response, + NPT_String file_path, + NPT_Position start = (NPT_Position)-1, + NPT_Position end = (NPT_Position)-1, + bool request_is_head = false); + static const char* GetMimeType(const NPT_String& filename); +}; + +#endif /* _PLT_HTTP_SERVER_H_ */ diff --git a/modules/platinum/SDK/include/PltHttpServerListener.h b/modules/platinum/SDK/include/PltHttpServerListener.h new file mode 100644 index 0000000..264b76f --- /dev/null +++ b/modules/platinum/SDK/include/PltHttpServerListener.h @@ -0,0 +1,55 @@ +/***************************************************************** +| +| Platinum - HTTP Server Listener +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ +#ifndef _PLT_HTTP_SERVER_LISTENER_H_ +#define _PLT_HTTP_SERVER_LISTENER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| PLT_HttpServerListener Interface ++---------------------------------------------------------------------*/ +class PLT_HttpServerListener +{ + public: + virtual ~PLT_HttpServerListener() {} + + virtual NPT_Result ProcessHttpRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse*& response, + bool& headers_only) = 0; +}; + +#endif /* _PLT_HTTP_SERVER_LISTENER_H_ */ diff --git a/modules/platinum/SDK/include/PltHttpServerTask.h b/modules/platinum/SDK/include/PltHttpServerTask.h new file mode 100644 index 0000000..db85154 --- /dev/null +++ b/modules/platinum/SDK/include/PltHttpServerTask.h @@ -0,0 +1,163 @@ +/***************************************************************** +| +| Platinum - HTTP Server Tasks +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_HTTP_SERVER_TASK_H_ +#define _PLT_HTTP_SERVER_TASK_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltHttp.h" +#include "PltDatagramStream.h" +#include "PltThreadTask.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +template <class T> class PLT_HttpListenTask; +class PLT_HttpServerListener; +typedef PLT_HttpListenTask<PLT_HttpServerListener> PLT_HttpServerListenTask; + +/*---------------------------------------------------------------------- +| PLT_HttpServerSocketTask class ++---------------------------------------------------------------------*/ +class PLT_HttpServerSocketTask : public PLT_ThreadTask +{ + friend class PLT_ThreadTask; + +public: + PLT_HttpServerSocketTask(NPT_Socket* socket, bool stay_alive_forever = false); + +protected: + virtual ~PLT_HttpServerSocketTask(); + +protected: + // Request callback handler + virtual NPT_Result ProcessRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse*& response, + bool& headers_only) = 0; + + // overridables + virtual NPT_Result GetInputStream(NPT_InputStreamReference& stream); + virtual NPT_Result GetInfo(NPT_SocketInfo& info); + + // PLT_ThreadTask methods + virtual void DoAbort() { m_Socket->Disconnect(); } + virtual void DoRun(); + +private: + virtual NPT_Result Read(NPT_BufferedInputStreamReference& buffered_input_stream, + NPT_HttpRequest*& request, + NPT_HttpRequestContext* context = NULL); + virtual NPT_Result Write(NPT_HttpResponse* response, + bool& keep_alive, + bool headers_only = false); + +protected: + NPT_Socket* m_Socket; + bool m_StayAliveForever; +}; + +/*---------------------------------------------------------------------- +| PLT_HttpServerTask class ++---------------------------------------------------------------------*/ +template <class T> +class PLT_HttpServerTask : public PLT_HttpServerSocketTask +{ +public: + PLT_HttpServerTask<T>(T* data, + NPT_Socket* socket, + bool keep_alive = false) : + PLT_HttpServerSocketTask(socket, keep_alive), m_Data(data) {} + +protected: + virtual ~PLT_HttpServerTask<T>() {} + +protected: + NPT_Result ProcessRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse*& response, + bool& headers_only) { + return m_Data->ProcessHttpRequest(request, context, response, headers_only); + } + +protected: + T* m_Data; +}; + +/*---------------------------------------------------------------------- +| PLT_HttpListenTask class ++---------------------------------------------------------------------*/ +template <class T> +class PLT_HttpListenTask : public PLT_ThreadTask +{ +public: + PLT_HttpListenTask<T>(T* data, NPT_TcpServerSocket* socket, bool cleanup_socket = true) : + m_Data(data), m_Socket(socket), m_CleanupSocket(cleanup_socket) {} + +protected: + virtual ~PLT_HttpListenTask<T>() { + if (m_CleanupSocket) delete m_Socket; + } + +protected: + // PLT_ThreadTask methods + virtual void DoAbort() { m_Socket->Disconnect(); } + virtual void DoRun() { + while (!IsAborting(0)) { + NPT_Socket* client = NULL; + NPT_Result result = m_Socket->WaitForNewClient(client, 5000); + if (NPT_FAILED(result) && result != NPT_ERROR_TIMEOUT) { + if (client) delete client; + //NPT_LOG_WARNING_2("PLT_HttpListenTask exiting with %d (%s)", result, NPT_ResultText(result)); + break; + } + + if (NPT_SUCCEEDED(result)) { + PLT_ThreadTask* task = new PLT_HttpServerTask<T>(m_Data, client); + if (NPT_FAILED(m_TaskManager->StartTask(task))) { + task->Kill(); + } + } + } + } + +protected: + T* m_Data; + NPT_TcpServerSocket* m_Socket; + bool m_CleanupSocket; +}; + +#endif /* _PLT_HTTP_SERVER_TASK_H_ */ diff --git a/modules/platinum/SDK/include/PltLeaks.h b/modules/platinum/SDK/include/PltLeaks.h new file mode 100644 index 0000000..e00a315 --- /dev/null +++ b/modules/platinum/SDK/include/PltLeaks.h @@ -0,0 +1,50 @@ +/***************************************************************** +| +| Platinum - Leaks +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_LEAKS_H_ +#define _PLT_LEAKS_H_ + +/*---------------------------------------------------------------------- +| functions ++---------------------------------------------------------------------*/ +#if defined(__cplusplus) +extern "C" { +#endif + +void PLT_Leak_Enable(void); + +#if defined(__cplusplus) +} +#endif + +#endif /* _PLT_LEAKS_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaBrowser.h b/modules/platinum/SDK/include/PltMediaBrowser.h new file mode 100644 index 0000000..cfd3b5e --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaBrowser.h @@ -0,0 +1,140 @@ +/***************************************************************** +| +| Platinum - AV Media Browser (Media Server Control Point) +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_BROWSER_H_ +#define _PLT_MEDIA_BROWSER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "PltCtrlPoint.h" +#include "PltMediaItem.h" + +/*---------------------------------------------------------------------- +| PLT_BrowseInfo ++---------------------------------------------------------------------*/ +struct PLT_BrowseInfo { + NPT_String object_id; + PLT_MediaObjectListReference items; + NPT_UInt32 nr; + NPT_UInt32 tm; + NPT_UInt32 uid; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaBrowserDelegate class ++---------------------------------------------------------------------*/ +class PLT_MediaBrowserDelegate +{ +public: + virtual ~PLT_MediaBrowserDelegate() {} + + virtual bool OnMSAdded(PLT_DeviceDataReference& /* device */) { return true; } + virtual void OnMSRemoved(PLT_DeviceDataReference& /* device */) {} + virtual void OnMSStateVariablesChanged( + PLT_Service* /*service*/, + NPT_List<PLT_StateVariable*>* /*vars*/) {} + + // ContentDirectory + virtual void OnBrowseResult( + NPT_Result /*res*/, + PLT_DeviceDataReference& /*device*/, + PLT_BrowseInfo* /*info*/, + void* /*userdata*/) {} + + virtual void OnSearchResult( + NPT_Result /*res*/, + PLT_DeviceDataReference& /*device*/, + PLT_BrowseInfo* /*info*/, + void* /*userdata*/) {} +}; + +/*---------------------------------------------------------------------- +| PLT_MediaBrowser class ++---------------------------------------------------------------------*/ +class PLT_MediaBrowser : public PLT_CtrlPointListener +{ +public: + PLT_MediaBrowser(PLT_CtrlPointReference& ctrl_point, + PLT_MediaBrowserDelegate* delegate = NULL); + virtual ~PLT_MediaBrowser(); + + // ContentDirectory service + virtual NPT_Result Browse(PLT_DeviceDataReference& device, + const char* object_id, + NPT_UInt32 start_index, + NPT_UInt32 count = 30, // DLNA recommendations + bool browse_metadata = false, + const char* filter = "dc:date,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:album,upnp:artist,upnp:author", // explicitely specify res otherwise WMP won't return a URL! + const char* sort_criteria = "", + void* userdata = NULL); + + virtual NPT_Result Search(PLT_DeviceDataReference& device, + const char* container_id, + const char* search_criteria, + NPT_UInt32 start_index, + NPT_UInt32 count = 30, // DLNA recommendations + const char* filter = "dc:date,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:album,upnp:artist,upnp:author", // explicitely specify res otherwise WMP won't return a URL! + void* userdata = NULL); + //BBMOD END + + // methods + virtual const NPT_Lock<PLT_DeviceDataReferenceList>& GetMediaServers() { return m_MediaServers; } + virtual NPT_Result FindServer(const char* uuid, PLT_DeviceDataReference& device); + virtual void SetDelegate(PLT_MediaBrowserDelegate* delegate) { m_Delegate = delegate; } + +protected: + // PLT_CtrlPointListener methods + virtual NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device); + virtual NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device); + virtual NPT_Result OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata); + virtual NPT_Result OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars); + + // ContentDirectory service responses + virtual NPT_Result OnBrowseResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata); + + virtual NPT_Result OnSearchResponse(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_ActionReference& action, + void* userdata); + +protected: + PLT_CtrlPointReference m_CtrlPoint; + PLT_MediaBrowserDelegate* m_Delegate; + NPT_Lock<PLT_DeviceDataReferenceList> m_MediaServers; +}; + +#endif /* _PLT_MEDIA_BROWSER_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaBrowserListener.h b/modules/platinum/SDK/include/PltMediaBrowserListener.h new file mode 100644 index 0000000..f0d6479 --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaBrowserListener.h @@ -0,0 +1,80 @@ +/***************************************************************** +| +| Platinum - AV Media Browser Listener +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_BROWSER_LISTENER_H_ +#define _PLT_MEDIA_BROWSER_LISTENER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "PltMediaItem.h" +#include "PltDeviceData.h" + +/*---------------------------------------------------------------------- +| PLT_BrowseInfo ++---------------------------------------------------------------------*/ +class PLT_BrowseInfo { +public: + PLT_BrowseInfo() : nr(0), tm(0), uid(0) {} + + NPT_String object_id; + PLT_MediaObjectListReference items; + NPT_UInt32 nr; + NPT_UInt32 tm; + NPT_UInt32 uid; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaBrowserListener class ++---------------------------------------------------------------------*/ +class PLT_MediaBrowserListener +{ +public: + virtual ~PLT_MediaBrowserListener() {} + + virtual void OnMSAddedRemoved( + PLT_DeviceDataReference& /*device*/, + int /*added*/) {} + + virtual void OnMSStateVariablesChanged( + PLT_Service* /*service*/, + NPT_List<PLT_StateVariable*>* /*vars*/) {} + + virtual void OnMSBrowseResult( + NPT_Result /*res*/, + PLT_DeviceDataReference& /*device*/, + PLT_BrowseInfo* /*info*/, + void* /*userdata*/) {} +}; + +#endif /* _PLT_MEDIA_BROWSER_LISTENER_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaCache.h b/modules/platinum/SDK/include/PltMediaCache.h new file mode 100644 index 0000000..4cb89e8 --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaCache.h @@ -0,0 +1,75 @@ +/***************************************************************** +| +| Platinum - AV Media Cache +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_CACHE_H_ +#define _PLT_MEDIA_CACHE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltMediaItem.h" +#include "PltDeviceData.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------- +| typedefs ++---------------------------------------------------------------------*/ +typedef NPT_Map<NPT_String, PLT_MediaObjectListReference>::Entry PLT_MediaCacheEntry; + +/*---------------------------------------------------------------------- +| PLT_MediaCache class ++---------------------------------------------------------------------*/ +class PLT_MediaCache +{ +public: + PLT_MediaCache(); + virtual ~PLT_MediaCache(); + + NPT_Result Put(const char* device_uuid, const char* item_id, PLT_MediaObjectListReference& list); + NPT_Result Get(const char* device_uuid, const char* item_id, PLT_MediaObjectListReference& list); + NPT_Result Clear(const char* device_uuid, const char* item_id); + NPT_Result Clear(const char* device_uuid = NULL); + +private: + NPT_String GenerateKey(const char* device_uuid, const char* item_id); + +private: + NPT_Mutex m_Mutex; + NPT_Map<NPT_String, PLT_MediaObjectListReference> m_Items; +}; + +#endif /* _PLT_MEDIA_CACHE_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaConnect.h b/modules/platinum/SDK/include/PltMediaConnect.h new file mode 100644 index 0000000..a5a6412 --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaConnect.h @@ -0,0 +1,116 @@ +/***************************************************************** +| +| Platinum - AV Media Connect Device +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_CONNECT_H_ +#define _PLT_MEDIA_CONNECT_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltFileMediaServer.h" + +/*---------------------------------------------------------------------- +| PLT_MediaConnectInfo ++---------------------------------------------------------------------*/ +class PLT_MediaConnectInfo +{ +public: + PLT_MediaConnectInfo(bool authorized = false) : + m_Authorized(authorized), m_Validated(false) {} + + bool m_Authorized; + bool m_Validated; + NPT_String m_UDN; +}; + +/*---------------------------------------------------------------------- +| defines ++---------------------------------------------------------------------*/ +typedef NPT_Map<NPT_String, PLT_MediaConnectInfo> PLT_MediaConnectDeviceInfoMap; +typedef NPT_Map<NPT_String, PLT_MediaConnectInfo>::Entry PLT_MediaConnectDeviceInfoMapEntry; +typedef NPT_Map<NPT_String, NPT_String> PLT_UDNtoMACMap; +typedef NPT_Map<NPT_String, NPT_String>::Entry PLT_UDNtoMACMapEntry; + +/*---------------------------------------------------------------------- +| PLT_MediaConnect ++---------------------------------------------------------------------*/ +class PLT_MediaConnect : public PLT_FileMediaServer +{ +public: + PLT_MediaConnect(const char* path, + const char* friendly_name, + bool show_ip = false, + const char* udn = NULL, + NPT_UInt16 port = 0, + bool port_rebind = false); + + NPT_Result Authorize(PLT_MediaConnectInfo* info, bool state); + NPT_Result Validate(PLT_MediaConnectInfo* info, bool state); + +protected: + virtual ~PLT_MediaConnect(); + + + // PLT_DeviceHost methods + virtual NPT_Result SetupServices(PLT_DeviceData& data); + virtual NPT_Result OnAction(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + virtual NPT_Result ProcessGetDescription(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse& response); + + // PLT_FileMediaServer methods + virtual NPT_Result GetFilePath(const char* object_id, NPT_String& filepath); + + // X_MS_MediaReceiverRegistrar + virtual NPT_Result OnIsAuthorized(PLT_ActionReference& action, + PLT_MediaConnectInfo* mediaConnectInfo); + virtual NPT_Result OnRegisterDevice(PLT_ActionReference& action, + PLT_MediaConnectInfo* mediaConnectInfo); + virtual NPT_Result OnIsValidated(PLT_ActionReference& action, + PLT_MediaConnectInfo* mediaConnectInfo); + +private: + NPT_Result LookUpMediaConnectInfo(NPT_String deviceID, + PLT_MediaConnectInfo*& mediaConnectInfo); + +protected: + PLT_MediaConnectDeviceInfoMap m_MediaConnectDeviceInfoMap; + PLT_UDNtoMACMap m_MediaConnectUDNMap; + +private: + PLT_Service* m_RegistrarService; +}; + +#endif /* _PLT_MEDIA_CONNECT_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaController.h b/modules/platinum/SDK/include/PltMediaController.h new file mode 100644 index 0000000..2ed3163 --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaController.h @@ -0,0 +1,338 @@ +/***************************************************************** +| +| Platinum - AV Media Controller (Media Renderer Control Point) +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_CONTROLLER_H_ +#define _PLT_MEDIA_CONTROLLER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "PltCtrlPoint.h" +#include "PltMediaItem.h" + +/*---------------------------------------------------------------------- +| Defines ++---------------------------------------------------------------------*/ +typedef NPT_List<NPT_String> PLT_StringList; + +struct PLT_DeviceCapabilities { + PLT_StringList play_media; + PLT_StringList rec_media; + PLT_StringList rec_quality_modes; +}; + +struct PLT_MediaInfo { + NPT_UInt32 num_tracks; + NPT_TimeStamp media_duration; + NPT_String cur_uri; + NPT_String cur_metadata; + NPT_String next_uri; + NPT_String next_metadata; + NPT_String play_medium; + NPT_String rec_medium; + NPT_String write_status; +}; + +struct PLT_PositionInfo { + NPT_UInt32 track; + NPT_TimeStamp track_duration; + NPT_String track_metadata; + NPT_String track_uri; + NPT_TimeStamp rel_time; + NPT_TimeStamp abs_time; + NPT_Int32 rel_count; + NPT_Int32 abs_count; +}; + +struct PLT_TransportInfo { + NPT_String cur_transport_state; + NPT_String cur_transport_status; + NPT_String cur_speed; +}; + +struct PLT_TransportSettings { + NPT_String play_mode; + NPT_String rec_quality_mode; +}; + +struct PLT_ConnectionInfo { + NPT_UInt32 rcs_id; + NPT_UInt32 avtransport_id; + NPT_String protocol_info; + NPT_String peer_connection_mgr; + NPT_UInt32 peer_connection_id; + NPT_String direction; + NPT_String status; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaControllerDelegate class ++---------------------------------------------------------------------*/ +class PLT_MediaControllerDelegate +{ +public: + virtual ~PLT_MediaControllerDelegate() {} + + virtual bool OnMRAdded(PLT_DeviceDataReference& /* device */) { return true; } + virtual void OnMRRemoved(PLT_DeviceDataReference& /* device */) {} + virtual void OnMRStateVariablesChanged(PLT_Service* /* service */, + NPT_List<PLT_StateVariable*>* /* vars */) {} + + // AVTransport + virtual void OnGetCurrentTransportActionsResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_StringList* /* actions */, + void* /* userdata */) {} + + virtual void OnGetDeviceCapabilitiesResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_DeviceCapabilities* /* capabilities */, + void* /* userdata */) {} + + virtual void OnGetMediaInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_MediaInfo* /* info */, + void* /* userdata */) {} + + virtual void OnGetPositionInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_PositionInfo* /* info */, + void* /* userdata */) {} + + virtual void OnGetTransportInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_TransportInfo* /* info */, + void* /* userdata */) {} + + virtual void OnGetTransportSettingsResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_TransportSettings* /* settings */, + void* /* userdata */) {} + + virtual void OnNextResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnPauseResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnPlayResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnPreviousResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnSeekResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnSetAVTransportURIResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnSetPlayModeResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnStopResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + // ConnectionManager + virtual void OnGetCurrentConnectionIDsResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_StringList* /* ids */, + void* /* userdata */) {} + + virtual void OnGetCurrentConnectionInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_ConnectionInfo* /* info */, + void* /* userdata */) {} + + virtual void OnGetProtocolInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_StringList* /* sources */, + PLT_StringList* /* sinks */, + void* /* userdata */) {} + + // RenderingControl + virtual void OnSetMuteResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnGetMuteResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + const char* /* channel */, + bool /* mute */, + void* /* userdata */) {} + + virtual void OnSetVolumeResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnGetVolumeResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + const char* /* channel */, + NPT_UInt32 /* volume */, + void* /* userdata */) {} +}; + +/*---------------------------------------------------------------------- +| PLT_MediaController class ++---------------------------------------------------------------------*/ +class PLT_MediaController : public PLT_CtrlPointListener +{ +public: + PLT_MediaController(PLT_CtrlPointReference& ctrl_point, + PLT_MediaControllerDelegate* delegate = NULL); + virtual ~PLT_MediaController(); + + // public methods + virtual void SetDelegate(PLT_MediaControllerDelegate* delegate) { + m_Delegate = delegate; + } + + // PLT_CtrlPointListener methods + virtual NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device); + virtual NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device); + virtual NPT_Result OnActionResponse(NPT_Result res, PLT_ActionReference& action, void* userdata); + virtual NPT_Result OnEventNotify(PLT_Service* service, NPT_List<PLT_StateVariable*>* vars); + + // AVTransport + NPT_Result GetCurrentTransportActions(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + NPT_Result GetDeviceCapabilities(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + NPT_Result GetMediaInfo(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + NPT_Result GetPositionInfo(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + NPT_Result GetTransportInfo(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + NPT_Result GetTransportSettings(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + NPT_Result Next(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + NPT_Result Pause(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + NPT_Result Play(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, NPT_String speed, void* userdata); + NPT_Result Previous(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + NPT_Result Seek(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, NPT_String unit, NPT_String target, void* userdata); + NPT_Result SetAVTransportURI(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* uri, const char* metadata, void* userdata); + NPT_Result SetPlayMode(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, NPT_String new_play_mode, void* userdata); + NPT_Result Stop(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, void* userdata); + + // ConnectionManager + NPT_Result GetCurrentConnectionIDs(PLT_DeviceDataReference& device, void* userdata); + NPT_Result GetCurrentConnectionInfo(PLT_DeviceDataReference& device, NPT_UInt32 connection_id, void* userdata); + NPT_Result GetProtocolInfo(PLT_DeviceDataReference& device, void* userdata); + + // RenderingControl + NPT_Result SetMute(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* channel, bool mute, void* userdata); + NPT_Result GetMute(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* channel, void* userdata); + NPT_Result SetVolume(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* channel, int volume, void* userdata); + NPT_Result GetVolume(PLT_DeviceDataReference& device, NPT_UInt32 instance_id, const char* channel, void* userdata); + + // methods + virtual NPT_Result FindRenderer(const char* uuid, PLT_DeviceDataReference& device); + virtual NPT_Result GetProtocolInfoSink(PLT_DeviceDataReference& device, NPT_List<NPT_String>& sinks); + virtual NPT_Result FindMatchingProtocolInfo(NPT_List<NPT_String>& sinks, + const char* protocol_info); + virtual NPT_Result FindBestResource(PLT_DeviceDataReference& device, PLT_MediaObject& item, NPT_Cardinal& resource_index); + +private: + NPT_Result InvokeActionWithInstance(PLT_ActionReference& action, + NPT_UInt32 instance_id, + void* userdata = NULL); + + NPT_Result OnGetCurrentTransportActionsResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + NPT_Result OnGetDeviceCapabilitiesResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + NPT_Result OnGetMediaInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + NPT_Result OnGetPositionInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + NPT_Result OnGetTransportInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + NPT_Result OnGetTransportSettingsResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + + NPT_Result OnGetCurrentConnectionIDsResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + NPT_Result OnGetCurrentConnectionInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + NPT_Result OnGetProtocolInfoResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + + NPT_Result OnGetMuteResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + NPT_Result OnGetVolumeResponse(NPT_Result res, PLT_DeviceDataReference& device, PLT_ActionReference& action, void* userdata); + +public: + static void ParseCSV(const char* csv, PLT_StringList& values) { + const char* start = csv; + const char* p = start; + + // look for the , character + while (*p) { + if (*p == ',') { + NPT_String val(start, (int)(p-start)); + val.Trim(' '); + values.Add(val); + start = p + 1; + } + p++; + } + + // last one + NPT_String last(start, (int)(p-start)); + last.Trim(' '); + if (last.GetLength()) { + values.Add(last); + } + } + +private: + PLT_CtrlPointReference m_CtrlPoint; + PLT_MediaControllerDelegate* m_Delegate; + NPT_Lock<PLT_DeviceDataReferenceList> m_MediaRenderers; +}; + +#endif /* _PLT_MEDIA_CONTROLLER_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaControllerListener.h b/modules/platinum/SDK/include/PltMediaControllerListener.h new file mode 100644 index 0000000..1ab3a91 --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaControllerListener.h @@ -0,0 +1,203 @@ +/***************************************************************** +| +| Platinum - AV Media Controller Listener +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_CONTROLLER_LISTENER_H_ +#define _PLT_MEDIA_CONTROLLER_LISTENER_H_ + +/*---------------------------------------------------------------------- +| Defines ++---------------------------------------------------------------------*/ +typedef NPT_List<NPT_String> PLT_StringList; + +struct PLT_DeviceCapabilities { + PLT_StringList play_media; + PLT_StringList rec_media; + PLT_StringList rec_quality_modes; +}; + +struct PLT_MediaInfo { + NPT_UInt32 num_tracks; + NPT_TimeStamp media_duration; + NPT_String cur_uri; + NPT_String cur_metadata; + NPT_String next_uri; + NPT_String next_metadata; + NPT_String play_medium; + NPT_String rec_medium; + NPT_String write_status; +}; + +struct PLT_PositionInfo { + NPT_UInt32 track; + NPT_TimeStamp track_duration; + NPT_String track_metadata; + NPT_String track_uri; + NPT_TimeStamp rel_time; + NPT_TimeStamp abs_time; + NPT_Int32 rel_count; + NPT_Int32 abs_count; +}; + +struct PLT_TransportInfo { + NPT_String cur_transport_state; + NPT_String cur_transport_status; + NPT_String cur_speed; +}; + +struct PLT_TransportSettings { + NPT_String play_mode; + NPT_String rec_quality_mode; +}; + +struct PLT_ConnectionInfo { + NPT_UInt32 rcs_id; + NPT_UInt32 avtransport_id; + NPT_String protocol_info; + NPT_String peer_connection_mgr; + NPT_UInt32 peer_connection_id; + NPT_String direction; + NPT_String status; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaControllerListener class ++---------------------------------------------------------------------*/ +class PLT_MediaControllerListener +{ +public: + virtual ~PLT_MediaControllerListener() {} + + virtual void OnMRAddedRemoved(PLT_DeviceDataReference& /* device */, + int /* added */) {} + virtual void OnMRStateVariablesChanged(PLT_Service* /* service */, + NPT_List<PLT_StateVariable*>* /* vars */) {} + + // AVTransport + virtual void OnGetCurrentTransportActionsResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_StringList* /* actions */, + void* /* userdata */) {} + + virtual void OnGetDeviceCapabilitiesResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_DeviceCapabilities* /* capabilities */, + void* /* userdata */) {} + + virtual void OnGetMediaInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_MediaInfo* /* info */, + void* /* userdata */) {} + + virtual void OnGetPositionInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_PositionInfo* /* info */, + void* /* userdata */) {} + + virtual void OnGetTransportInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_TransportInfo* /* info */, + void* /* userdata */) {} + + virtual void OnGetTransportSettingsResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_TransportSettings* /* settings */, + void* /* userdata */) {} + + virtual void OnNextResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnPauseResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnPlayResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnPreviousResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnSeekResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnSetAVTransportURIResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnSetPlayModeResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + virtual void OnStopResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + void* /* userdata */) {} + + // ConnectionManager + virtual void OnGetCurrentConnectionIDsResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_StringList* /* ids */, + void* /* userdata */) {} + + virtual void OnGetCurrentConnectionInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_ConnectionInfo* /* info */, + void* /* userdata */) {} + + virtual void OnGetProtocolInfoResult( + NPT_Result /* res */, + PLT_DeviceDataReference& /* device */, + PLT_StringList* /* sources */, + PLT_StringList* /* sinks */, + void* /* userdata */) {} +}; + +#endif /* _PLT_MEDIA_CONTROLLER_LISTENER_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaItem.h b/modules/platinum/SDK/include/PltMediaItem.h new file mode 100644 index 0000000..a0292a6 --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaItem.h @@ -0,0 +1,326 @@ +/***************************************************************** +| +| Platinum - AV Media Item +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_ITEM_H_ +#define _PLT_MEDIA_ITEM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltHttp.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_MediaServer; + +/*---------------------------------------------------------------------- +| typedefs ++---------------------------------------------------------------------*/ +typedef struct { + NPT_String type; + NPT_String friendly_name; +} PLT_ObjectClass; + +typedef struct { + NPT_String type; + NPT_String friendly_name; + bool include_derived; +} PLT_SearchClass; + +typedef struct { + NPT_String name; + NPT_String role; +} PLT_PersonRole; + +class PLT_PersonRoles : public NPT_List<PLT_PersonRole> +{ +public: + NPT_Result Add(const NPT_String& name, const NPT_String& role = ""); + NPT_Result ToDidl(NPT_String& didl, const NPT_String& tag); + NPT_Result FromDidl(const NPT_Array<NPT_XmlElementNode*>& nodes); +}; + +typedef struct { + NPT_String allowed_use; // (CSV) + NPT_String validity_start; + NPT_String validity_end; + NPT_String remaining_time; + NPT_String usage_info; + NPT_String rights_info_uri; + NPT_String content_info_uri; +} PLT_Constraint; + +typedef struct { + PLT_PersonRoles artists; + PLT_PersonRoles actors; + PLT_PersonRoles authors; + NPT_String producer; + NPT_String director; + NPT_String publisher; + NPT_String contributor; // should match m_Creator (dc:creator) +} PLT_PeopleInfo; + +typedef struct { + NPT_List<NPT_String> genre; + NPT_String album; + NPT_String playlist; // dc:title of the playlist item the content belongs too +} PLT_AffiliationInfo; + +typedef struct { + NPT_String description; + NPT_String long_description; + NPT_String icon_uri; + NPT_String region; + NPT_String rating; + NPT_String rights; + NPT_String date; + NPT_String language; +} PLT_Description; + +typedef struct { + NPT_String album_art_uri; + NPT_String album_art_uri_dlna_profile; + NPT_String artist_discography_uri; + NPT_String lyrics_uri; + NPT_List<NPT_String> relation; // dc:relation +} PLT_ExtraInfo; + +typedef struct { + NPT_UInt32 dvdregioncode; + NPT_UInt32 original_track_number; + NPT_String toc; + NPT_String user_annotation; +} PLT_MiscInfo; + +typedef struct { + int total; + int used; + int free; + int max_partition; + NPT_String medium; +} PLT_StorageInfo; + +/*---------------------------------------------------------------------- +| PLT_ProtocolInfo class ++---------------------------------------------------------------------*/ +class PLT_ProtocolInfo +{ +public: + class FieldEntry { + public: + FieldEntry(const char* key, const char* value) : + m_Key(key), m_Value(value) {} + NPT_String m_Key; + NPT_String m_Value; + }; + + PLT_ProtocolInfo(); + PLT_ProtocolInfo(const char* protocol_info); + PLT_ProtocolInfo(const char* protocol, + const char* mask, + const char* content_type, + const char* extra); + const NPT_String& GetProtocol() const { return m_Protocol; } + const NPT_String& GetMask() const { return m_Mask; } + const NPT_String& GetContentType() const { return m_ContentType; } + const NPT_String& GetExtra() const { return m_Extra; } + + const NPT_String& GetDLNA_PN() const { return m_DLNA_PN; } + + bool IsValid() { return m_Valid; } + NPT_String ToString() const; + + bool Match(const PLT_ProtocolInfo& other) const; + +private: + NPT_Result ValidateField(const char* val, + const char* valid_chars, + NPT_Cardinal num_chars = 0); // 0 means variable number of chars + NPT_Result ParseExtra(NPT_List<FieldEntry>& entries); + NPT_Result ValidateExtra(); + +private: + NPT_String m_Protocol; + NPT_String m_Mask; + NPT_String m_ContentType; + NPT_String m_Extra; + + NPT_String m_DLNA_PN; + NPT_String m_DLNA_OP; + NPT_String m_DLNA_PS; + NPT_String m_DLNA_CI; + NPT_String m_DLNA_FLAGS; + NPT_String m_DLNA_MAXSP; + + NPT_List<FieldEntry> m_DLNA_OTHER; + bool m_Valid; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaItemResource class ++---------------------------------------------------------------------*/ +class PLT_MediaItemResource +{ +public: + PLT_MediaItemResource(); + ~PLT_MediaItemResource() {} + + NPT_String m_Uri; + PLT_ProtocolInfo m_ProtocolInfo; + NPT_UInt32 m_Duration; /* seconds */ + NPT_LargeSize m_Size; + NPT_String m_Protection; + NPT_UInt32 m_Bitrate; /* bytes/seconds */ + NPT_UInt32 m_BitsPerSample; + NPT_UInt32 m_SampleFrequency; + NPT_UInt32 m_NbAudioChannels; + NPT_String m_Resolution; + NPT_UInt32 m_ColorDepth; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaObject class ++---------------------------------------------------------------------*/ +class PLT_MediaObject +{ +public: + PLT_MediaObject() {} + virtual ~PLT_MediaObject() {} + + bool IsContainer() { return m_ObjectClass.type.StartsWith("object.container"); } + + static const char* GetMimeType(const NPT_String& filename, + const PLT_HttpRequestContext* context = NULL); + static const char* GetMimeTypeFromExtension(const NPT_String& extension, + const PLT_HttpRequestContext* context = NULL); + static NPT_String GetProtocolInfo(const char* filename, + bool with_dlna_extension = true, + const PLT_HttpRequestContext* context = NULL); + static NPT_String GetMimeTypeFromProtocolInfo(const char* protocol_info); + static const char* GetUPnPClass(const char* filename, + const PLT_HttpRequestContext* context = NULL); + static const char* GetDlnaExtension(const char* mime_type, + const PLT_HttpRequestContext* context = NULL); + + virtual NPT_Result Reset(); + virtual NPT_Result ToDidl(NPT_UInt32 mask, NPT_String& didl); + virtual NPT_Result FromDidl(NPT_XmlElementNode* entry); + +public: + /* common properties */ + PLT_ObjectClass m_ObjectClass; + NPT_String m_ObjectID; + NPT_String m_ParentID; + + /* metadata */ + NPT_String m_Title; + NPT_String m_Creator; + NPT_String m_Date; + PLT_PeopleInfo m_People; + PLT_AffiliationInfo m_Affiliation; + PLT_Description m_Description; + + /* properties */ + bool m_Restricted; + + /* extras */ + PLT_ExtraInfo m_ExtraInfo; + + /* miscellaneous info */ + PLT_MiscInfo m_MiscInfo; + + /* resources related */ + NPT_Array<PLT_MediaItemResource> m_Resources; + + /* original DIDL for Control Points to pass to a renderer when invoking SetAVTransportURI */ + NPT_String m_Didl; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaItem class ++---------------------------------------------------------------------*/ +class PLT_MediaItem : public PLT_MediaObject +{ +public: + PLT_MediaItem(); + virtual ~PLT_MediaItem(); + + // PLT_MediaObject methods + NPT_Result ToDidl(NPT_UInt32 mask, NPT_String& didl); + NPT_Result FromDidl(NPT_XmlElementNode* entry); +}; + +/*---------------------------------------------------------------------- +| PLT_MediaContainer class ++---------------------------------------------------------------------*/ +class PLT_MediaContainer : public PLT_MediaObject +{ +public: + PLT_MediaContainer(); + virtual ~PLT_MediaContainer(); + + // PLT_MediaObject methods + NPT_Result Reset(); + NPT_Result ToDidl(NPT_UInt32 mask, NPT_String& didl); + NPT_Result FromDidl(NPT_XmlElementNode* entry); + +public: + NPT_List<PLT_SearchClass> m_SearchClasses; + + /* properties */ + bool m_Searchable; + + /* container info related */ + NPT_Int32 m_ChildrenCount; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaObjectList class ++---------------------------------------------------------------------*/ +class PLT_MediaObjectList : public NPT_List<PLT_MediaObject*> +{ +public: + PLT_MediaObjectList(); + +protected: + virtual ~PLT_MediaObjectList(void); + friend class NPT_Reference<PLT_MediaObjectList>; +}; + +typedef NPT_Reference<PLT_MediaObjectList> PLT_MediaObjectListReference; +typedef NPT_Reference<PLT_MediaObject> PLT_MediaObjectReference; + + +#endif /* _PLT_MEDIA_ITEM_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaPlaylist.h b/modules/platinum/SDK/include/PltMediaPlaylist.h new file mode 100644 index 0000000..a53766b --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaPlaylist.h @@ -0,0 +1,85 @@ +/***************************************************************** +| +| Platinum - AV Media Playlist +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_PLAYLIST_H_ +#define _PLT_MEDIA_PLAYLIST_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltMediaItem.h" + +/*---------------------------------------------------------------------- +| typedefs ++---------------------------------------------------------------------*/ +typedef NPT_List<PLT_MediaItem*> PLT_MediaItemList; +typedef NPT_Reference<PLT_MediaItemList> PLT_MediaItemListReference; + +/*---------------------------------------------------------------------- +| PLT_MediaPlaylist class ++---------------------------------------------------------------------*/ +class PLT_MediaPlaylist +{ +public: + PLT_MediaPlaylist(); + ~PLT_MediaPlaylist(void); + + NPT_Result Clear(); + NPT_Result Queue(PLT_MediaItem* item); + NPT_Result Queue(PLT_MediaItemList* list); + template <typename X> + NPT_Result Apply(const X& function) { + return m_List->Apply(function); + } + +private: + PLT_MediaItemListReference m_List; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaItemQueueIterator class ++---------------------------------------------------------------------*/ +class PLT_MediaItemQueueIterator +{ +public: + PLT_MediaItemQueueIterator(PLT_MediaPlaylist* playlist) : m_Playlist(playlist) {} + NPT_Result operator()(PLT_MediaItem*& item) const { + return m_Playlist->Queue(item); + } + +private: + PLT_MediaPlaylist* m_Playlist; +}; + +#endif /* _PLT_MEDIA_PLAYLIST_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaRenderer.h b/modules/platinum/SDK/include/PltMediaRenderer.h new file mode 100644 index 0000000..b17bcde --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaRenderer.h @@ -0,0 +1,110 @@ +/***************************************************************** +| +| Platinum - AV Media Renderer Device +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_RENDERER_H_ +#define _PLT_MEDIA_RENDERER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "PltDeviceHost.h" + +/*---------------------------------------------------------------------- +| PLT_MediaRenderer class ++---------------------------------------------------------------------*/ +class PLT_MediaRendererInterface +{ +public: + virtual ~PLT_MediaRendererInterface() {} + + // ConnectionManager + virtual NPT_Result OnGetCurrentConnectionInfo(PLT_ActionReference& action) = 0; + + // AVTransport + virtual NPT_Result OnNext(PLT_ActionReference& action) = 0; + virtual NPT_Result OnPause(PLT_ActionReference& action) = 0; + virtual NPT_Result OnPlay(PLT_ActionReference& action) = 0; + virtual NPT_Result OnPrevious(PLT_ActionReference& action) = 0; + virtual NPT_Result OnSeek(PLT_ActionReference& action) = 0; + virtual NPT_Result OnStop(PLT_ActionReference& action) = 0; + virtual NPT_Result OnSetAVTransportURI(PLT_ActionReference& action) = 0; + virtual NPT_Result OnSetPlayMode(PLT_ActionReference& action) = 0; + + // RenderingControl + virtual NPT_Result OnSetVolume(PLT_ActionReference& action) = 0; + virtual NPT_Result OnSetMute(PLT_ActionReference& action) = 0; +}; + +/*---------------------------------------------------------------------- +| PLT_MediaRenderer class ++---------------------------------------------------------------------*/ +class PLT_MediaRenderer : public PLT_DeviceHost, + public PLT_MediaRendererInterface +{ +public: + PLT_MediaRenderer(const char* friendly_name, + bool show_ip = false, + const char* uuid = NULL, + unsigned int port = 0, + bool port_rebind = false); + + // PLT_DeviceHost methods + virtual NPT_Result SetupServices(PLT_DeviceData& data); + virtual NPT_Result OnAction(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + +protected: + virtual ~PLT_MediaRenderer(); + + // PLT_MediaRendererInterface methods + // ConnectionManager + virtual NPT_Result OnGetCurrentConnectionInfo(PLT_ActionReference& action); + + // AVTransport + virtual NPT_Result OnNext(PLT_ActionReference& action); + virtual NPT_Result OnPause(PLT_ActionReference& action); + virtual NPT_Result OnPlay(PLT_ActionReference& action); + virtual NPT_Result OnPrevious(PLT_ActionReference& action); + virtual NPT_Result OnSeek(PLT_ActionReference& action); + virtual NPT_Result OnStop(PLT_ActionReference& action); + virtual NPT_Result OnSetAVTransportURI(PLT_ActionReference& action); + virtual NPT_Result OnSetPlayMode(PLT_ActionReference& action); + + // RenderingControl + virtual NPT_Result OnSetVolume(PLT_ActionReference& action); + virtual NPT_Result OnSetVolumeDB(PLT_ActionReference &action); + virtual NPT_Result OnGetVolumeDBRange(PLT_ActionReference &action); + virtual NPT_Result OnSetMute(PLT_ActionReference& action); +}; + +#endif /* _PLT_MEDIA_RENDERER_H_ */ diff --git a/modules/platinum/SDK/include/PltMediaServer.h b/modules/platinum/SDK/include/PltMediaServer.h new file mode 100644 index 0000000..d277b0a --- /dev/null +++ b/modules/platinum/SDK/include/PltMediaServer.h @@ -0,0 +1,131 @@ +/***************************************************************** +| +| Platinum - AV Media Server Device +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_MEDIA_SERVER_H_ +#define _PLT_MEDIA_SERVER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltDeviceHost.h" +#include "PltMediaItem.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#define MAX_PATH_LENGTH 1024 + +/* BrowseFlags */ +enum BrowseFlags { + BROWSEMETADATA, + BROWSEDIRECTCHILDREN +}; + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +extern const char* BrowseFlagsStr[]; +class PLT_HttpFileServerHandler; + +/*---------------------------------------------------------------------- +| PLT_MediaServer class ++---------------------------------------------------------------------*/ +class PLT_MediaServer : public PLT_DeviceHost +{ +public: + PLT_MediaServer(const char* friendly_name, + bool show_ip = false, + const char* uuid = NULL, + NPT_UInt16 port = 0, + bool port_rebind = false); + virtual ~PLT_MediaServer(); + + // PLT_DeviceHost methods + virtual NPT_Result SetupServices(PLT_DeviceData& data); + virtual NPT_Result OnAction(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + + // class methods + static NPT_Result GetBrowseFlag(const char* str, BrowseFlags& flag); + +protected: + // ConnectionManager + virtual NPT_Result OnGetCurrentConnectionIDs(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnGetProtocolInfo(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnGetCurrentConnectionInfo(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + + // ContentDirectory + virtual NPT_Result OnGetSortCapabilities(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnGetSearchCapabilities(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnGetSystemUpdateID(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnBrowse(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnSearch(PLT_ActionReference& action, + const PLT_HttpRequestContext& context); + + // overridable methods + virtual NPT_Result OnBrowseMetadata(PLT_ActionReference& action, + const char* object_id, + const char* filter, + NPT_UInt32 starting_index, + NPT_UInt32 requested_count, + const NPT_List<NPT_String>& sort_criteria, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnBrowseDirectChildren(PLT_ActionReference& action, + const char* object_id, + const char* filter, + NPT_UInt32 starting_index, + NPT_UInt32 requested_count, + const NPT_List<NPT_String>& sort_criteria, + const PLT_HttpRequestContext& context); + virtual NPT_Result OnSearchContainer(PLT_ActionReference& action, + const char* container_id, + const char* search_criteria, + const char* filter, + NPT_UInt32 starting_index, + NPT_UInt32 requested_count, + const NPT_List<NPT_String>& sort_criteria, + const PLT_HttpRequestContext& context); + + // methods + virtual NPT_Result ParseSort(const NPT_String& sort, NPT_List<NPT_String>& list); +}; + +#endif /* _PLT_MEDIA_SERVER_H_ */ diff --git a/modules/platinum/SDK/include/PltMetadataHandler.h b/modules/platinum/SDK/include/PltMetadataHandler.h new file mode 100644 index 0000000..a5a8bf9 --- /dev/null +++ b/modules/platinum/SDK/include/PltMetadataHandler.h @@ -0,0 +1,90 @@ +/***************************************************************** +| +| Platinum - Metadata Handler +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_METADATA_HANDLER_H_ +#define _PLT_METADATA_HANDLER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| PLT_MetadataHandler class ++---------------------------------------------------------------------*/ +class PLT_MetadataHandler +{ +public: + virtual ~PLT_MetadataHandler() {} + + // metadata overridables + virtual bool HandleExtension(const char* extension) = 0; + virtual NPT_Result Load(NPT_InputStream& stream, + NPT_TimeInterval sleeptime = NPT_TimeInterval(0, 10000), + NPT_TimeInterval timeout = NPT_TimeInterval(30, 0)) = 0; + virtual NPT_Result Save(NPT_OutputStream& stream, + NPT_TimeInterval sleeptime = NPT_TimeInterval(0, 10000), + NPT_TimeInterval timeout = NPT_TimeInterval(30, 0)) = 0; + + virtual const char* GetLicenseData(NPT_String& licenseData) = 0; + virtual NPT_Result GetCoverArtData(char*& caData, int& len) = 0; + virtual const char* GetContentID(NPT_String& value) = 0; + virtual const char* GetTitle(NPT_String& value) = 0; + virtual const char* GetDescription(NPT_String& value) = 0; + virtual NPT_Result GetDuration(NPT_UInt32& seconds) = 0; + virtual const char* GetProtection(NPT_String& protection) = 0; + virtual NPT_Result GetYear(NPT_Size& year) = 0; + + // helper functions + virtual NPT_Result Load(const char* filename); + virtual NPT_Result Save(const char* filename); +}; + +/*---------------------------------------------------------------------- +| PLT_MetadataHandlerFinder ++---------------------------------------------------------------------*/ +class PLT_MetadataHandlerFinder +{ +public: + // methods + PLT_MetadataHandlerFinder(const char* extension) : m_Extension(extension) {} + bool operator()(PLT_MetadataHandler* const & handler) const { + return handler->HandleExtension(m_Extension) ? true : false; + } + +private: + // members + NPT_String m_Extension; +}; + +#endif /* _PLT_METADATA_HANDLER_H_ */ diff --git a/modules/platinum/SDK/include/PltRingBufferStream.h b/modules/platinum/SDK/include/PltRingBufferStream.h new file mode 100644 index 0000000..68a3115 --- /dev/null +++ b/modules/platinum/SDK/include/PltRingBufferStream.h @@ -0,0 +1,113 @@ +/***************************************************************** +| +| Platinum - Ring buffer stream +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_RING_BUFFER_STREAM_H_ +#define _PLT_RING_BUFFER_STREAM_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptStreams.h" +#include "NptRingBuffer.h" +#include "NptThreads.h" + +/*---------------------------------------------------------------------- +| PLT_RingBufferStream class ++---------------------------------------------------------------------*/ +class PLT_RingBufferStream : public NPT_DelegatingInputStream, + public NPT_DelegatingOutputStream +{ +public: + PLT_RingBufferStream(NPT_Size buffer_size = 4096, bool blocking = true); + PLT_RingBufferStream(NPT_RingBufferReference& buffer, bool blocking = true); + virtual ~PLT_RingBufferStream(); + + void SetEos() {m_Eos = true;} + + // NPT_InputStream methods + NPT_Result Read(void* buffer, + NPT_Size bytes_to_read, + NPT_Size* bytes_read = NULL); + NPT_Result GetSize(NPT_LargeSize& size) { + NPT_AutoLock autoLock(m_Lock); + size = m_TotalBytesWritten; + return NPT_SUCCESS; + } + NPT_Result GetAvailable(NPT_LargeSize& available) { + NPT_AutoLock autoLock(m_Lock); + available = m_RingBuffer->GetAvailable(); + return NPT_SUCCESS; + } + + // NPT_OutputStream methods + NPT_Result Write(const void* buffer, + NPT_Size bytes_to_write, + NPT_Size* bytes_written = NULL); + NPT_Result Flush(); + NPT_Result Close() { m_RingBuffer->Close(); return NPT_SUCCESS; } + +protected: + // NPT_DelegatingInputStream methods + NPT_Result InputSeek(NPT_Position offset) { + NPT_COMPILER_UNUSED(offset); + return NPT_FAILURE; + } + NPT_Result InputTell(NPT_Position& offset) { + NPT_AutoLock autoLock(m_Lock); + offset = m_TotalBytesRead; + return NPT_SUCCESS; + } + + // NPT_DelegatingOutputStream methods + NPT_Result OutputSeek(NPT_Position offset) { + NPT_COMPILER_UNUSED(offset); + return NPT_FAILURE; + } + NPT_Result OutputTell(NPT_Position& offset) { + NPT_AutoLock autoLock(m_Lock); + offset = m_TotalBytesWritten; + return NPT_SUCCESS; + } + +private: + NPT_RingBufferReference m_RingBuffer; + NPT_Offset m_TotalBytesRead; + NPT_Offset m_TotalBytesWritten; + NPT_Mutex m_Lock; + bool m_Eos; + bool m_Blocking; +}; + +typedef NPT_Reference<PLT_RingBufferStream> PLT_RingBufferStreamReference; + +#endif // _PLT_RING_BUFFER_STREAM_H_ diff --git a/modules/platinum/SDK/include/PltService.h b/modules/platinum/SDK/include/PltService.h new file mode 100644 index 0000000..64fd079 --- /dev/null +++ b/modules/platinum/SDK/include/PltService.h @@ -0,0 +1,272 @@ +/***************************************************************** +| +| Platinum - Service +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_SERVICE_H_ +#define _PLT_SERVICE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltEvent.h" +#include "PltArgument.h" +#include "PltStateVariable.h" +#include "PltAction.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_DeviceData; + +/*---------------------------------------------------------------------- +| PLT_Service class ++---------------------------------------------------------------------*/ +class PLT_Service +{ +public: + // methods + PLT_Service(PLT_DeviceData* device, + const char* type = NULL, + const char* id = NULL, + const char* last_change_namespace = NULL); + ~PLT_Service(); + + // class methods + NPT_Result InitURLs(const char* service_name, const char* device_uuid); + bool IsInitted() { + return (m_ActionDescs.GetItemCount() > 0); + } + NPT_Result PauseEventing(bool paused = true); + + // static methods + static bool IsTrue(const NPT_String& value) { + if (value.Compare("1", true) && + value.Compare("true", true) && + value.Compare("yes", true)) { + return false; + } + return true; + } + + // accessor methods + NPT_String GetSCPDURL(bool absolute = false); + NPT_String GetControlURL(bool absolute = false); + NPT_String GetEventSubURL(bool absolute = false); + const NPT_String& GetServiceID() const { return m_ServiceID; } + const NPT_String& GetServiceType() const { return m_ServiceType; } + PLT_DeviceData* GetDevice() { return m_Device; } + NPT_Result ForceVersion(NPT_Cardinal version); + + // XML + NPT_Result GetSCPDXML(NPT_String& xml); + NPT_Result SetSCPDXML(const char* xml); + NPT_Result GetDescription(NPT_XmlElementNode* parent, NPT_XmlElementNode** service = NULL); + + // State Variables + NPT_Result SetStateVariable(const char* name, const char* value); + NPT_Result SetStateVariableRate(const char* name, NPT_TimeInterval rate); + NPT_Result SetStateVariableExtraAttribute(const char* name, + const char* key, + const char* value); + NPT_Result IncStateVariable(const char* name); + PLT_StateVariable* FindStateVariable(const char* name); + NPT_Result GetStateVariableValue(const char* name, NPT_String& value); + bool IsSubscribable(); + + // Actions + PLT_ActionDesc* FindActionDesc(const char* name); + +private: + void Cleanup(); + NPT_Result AddChanged(PLT_StateVariable* var); + NPT_Result UpdateLastChange(NPT_List<PLT_StateVariable*>& vars); + NPT_Result NotifyChanged(); + + + /*---------------------------------------------------------------------- + | PLT_ServiceEventTask + +---------------------------------------------------------------------*/ + class PLT_ServiceEventTask : public PLT_ThreadTask + { + public: + PLT_ServiceEventTask(PLT_Service* service) : m_Service(service) {} + + void DoRun() { + while (!IsAborting(100)) m_Service->NotifyChanged(); + } + + private: + PLT_Service* m_Service; + }; + + // Events + NPT_Result ProcessNewSubscription( + PLT_TaskManager* task_manager, + const NPT_SocketAddress& addr, + const NPT_String& callback_urls, + int timeout, + NPT_HttpResponse& response); + + NPT_Result ProcessRenewSubscription( + const NPT_SocketAddress& addr, + const NPT_String& sid, + int timeout, + NPT_HttpResponse& response); + + NPT_Result ProcessCancelSubscription( + const NPT_SocketAddress& addr, + const NPT_String& sid, + NPT_HttpResponse& response); + + +protected: + friend class PLT_StateVariable; // so that we can call AddChanged from StateVariable + friend class PLT_DeviceHost; + friend class PLT_DeviceData; + + //members + PLT_DeviceData* m_Device; + NPT_String m_ServiceType; + NPT_String m_ServiceID; + NPT_String m_SCPDURL; + NPT_String m_ControlURL; + NPT_String m_EventSubURL; + + PLT_ServiceEventTask* m_EventTask; + NPT_Array<PLT_ActionDesc*> m_ActionDescs; + NPT_List<PLT_StateVariable*> m_StateVars; + NPT_Mutex m_Lock; + NPT_List<PLT_StateVariable*> m_StateVarsChanged; + NPT_List<PLT_StateVariable*> m_StateVarsToPublish; + NPT_List<PLT_EventSubscriber*> m_Subscribers; + bool m_EventingPaused; + NPT_String m_LastChangeNamespace; +}; + +/*---------------------------------------------------------------------- +| PLT_ServiceSCPDURLFinder ++---------------------------------------------------------------------*/ +class PLT_ServiceSCPDURLFinder +{ +public: + // methods + PLT_ServiceSCPDURLFinder(const char* url) : m_URL(url) {} + virtual ~PLT_ServiceSCPDURLFinder() {} + bool operator()(PLT_Service* const & service) const; + +private: + // members + NPT_String m_URL; +}; + +/*---------------------------------------------------------------------- +| PLT_ServiceControlURLFinder ++---------------------------------------------------------------------*/ +class PLT_ServiceControlURLFinder +{ +public: + // methods + PLT_ServiceControlURLFinder(const char* url) : m_URL(url) {} + virtual ~PLT_ServiceControlURLFinder() {} + bool operator()(PLT_Service* const & service) const; + +private: + // members + NPT_String m_URL; +}; + +/*---------------------------------------------------------------------- +| PLT_ServiceEventSubURLFinder ++---------------------------------------------------------------------*/ +class PLT_ServiceEventSubURLFinder +{ +public: + // methods + PLT_ServiceEventSubURLFinder(const char* url) : m_URL(url) {} + virtual ~PLT_ServiceEventSubURLFinder() {} + bool operator()(PLT_Service* const & service) const; + +private: + // members + NPT_String m_URL; +}; + +/*---------------------------------------------------------------------- +| PLT_ServiceIDFinder ++---------------------------------------------------------------------*/ +class PLT_ServiceIDFinder +{ +public: + // methods + PLT_ServiceIDFinder(const char* id) : m_Id(id) {} + virtual ~PLT_ServiceIDFinder() {} + bool operator()(PLT_Service* const & service) const; + +private: + // members + NPT_String m_Id; +}; + +/*---------------------------------------------------------------------- +| PLT_ServiceTypeFinder ++---------------------------------------------------------------------*/ +class PLT_ServiceTypeFinder +{ +public: + // methods + PLT_ServiceTypeFinder(const char* type) : m_Type(type) {} + virtual ~PLT_ServiceTypeFinder() {} + bool operator()(PLT_Service* const & service) const; + +private: + // members + NPT_String m_Type; +}; + +/*---------------------------------------------------------------------- +| PLT_LastChangeXMLIterator ++---------------------------------------------------------------------*/ +class PLT_LastChangeXMLIterator +{ +public: + // methods + PLT_LastChangeXMLIterator(NPT_XmlElementNode* node) : m_Node(node) {} + virtual ~PLT_LastChangeXMLIterator() {} + + NPT_Result operator()(PLT_StateVariable* const & var) const; + +private: + NPT_XmlElementNode* m_Node; +}; + +#endif /* _PLT_SERVICE_H_ */ diff --git a/modules/platinum/SDK/include/PltSsdp.h b/modules/platinum/SDK/include/PltSsdp.h new file mode 100644 index 0000000..136c92c --- /dev/null +++ b/modules/platinum/SDK/include/PltSsdp.h @@ -0,0 +1,300 @@ +/***************************************************************** +| +| Platinum - SSDP +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_SSDP_H_ +#define _PLT_SSDP_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltSsdpListener.h" +#include "PltThreadTask.h" +#include "PltHttpServerTask.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_DeviceHost; + +/*---------------------------------------------------------------------- +| PLT_SsdpSender class ++---------------------------------------------------------------------*/ +class PLT_SsdpSender +{ +public: + static NPT_Result SendSsdp(NPT_HttpRequest& request, + const char* usn, + const char* nt, + NPT_UdpSocket& socket, + bool notify, + const NPT_SocketAddress* addr = NULL); + + static NPT_Result SendSsdp(NPT_HttpResponse& response, + const char* usn, + const char* nt, + NPT_UdpSocket& socket, + bool notify, + const NPT_SocketAddress* addr = NULL); + +private: + static NPT_Result FormatPacket(NPT_HttpMessage& message, + const char* usn, + const char* nt, + NPT_UdpSocket& socket, + bool notify); +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpDeviceSearchResponseInterfaceIterator class ++---------------------------------------------------------------------*/ +class PLT_SsdpDeviceSearchResponseInterfaceIterator +{ +public: + PLT_SsdpDeviceSearchResponseInterfaceIterator(PLT_DeviceHost* device, + NPT_SocketAddress remote_addr, + const char* st) : + m_Device(device), m_RemoteAddr(remote_addr), m_ST(st) {} + virtual ~PLT_SsdpDeviceSearchResponseInterfaceIterator() {} + + NPT_Result operator()(NPT_NetworkInterface*& if_addr) const; + +private: + PLT_DeviceHost* m_Device; + NPT_SocketAddress m_RemoteAddr; + NPT_String m_ST; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpDeviceSearchResponseTask class ++---------------------------------------------------------------------*/ +class PLT_SsdpDeviceSearchResponseTask : public PLT_ThreadTask +{ +public: + PLT_SsdpDeviceSearchResponseTask(PLT_DeviceHost* device, + NPT_SocketAddress remote_addr, + const char* st) : + m_Device(device), m_RemoteAddr(remote_addr), m_ST(st) {} + +protected: + virtual ~PLT_SsdpDeviceSearchResponseTask() {} + + // PLT_ThreadTask methods + virtual void DoRun(); + +protected: + PLT_DeviceHost* m_Device; + NPT_SocketAddress m_RemoteAddr; + NPT_String m_ST; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpAnnounceInterfaceIterator class ++---------------------------------------------------------------------*/ +class PLT_SsdpAnnounceInterfaceIterator +{ +public: + PLT_SsdpAnnounceInterfaceIterator(PLT_DeviceHost* device, bool is_byebye = false, bool broadcast = false) : + m_Device(device), m_IsByeBye(is_byebye), m_Broadcast(broadcast) {} + + NPT_Result operator()(NPT_NetworkInterface*& if_addr) const; + +private: + PLT_DeviceHost* m_Device; + bool m_IsByeBye; + bool m_Broadcast; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpInitMulticastIterator class ++---------------------------------------------------------------------*/ +class PLT_SsdpInitMulticastIterator +{ +public: + PLT_SsdpInitMulticastIterator(NPT_UdpMulticastSocket* socket) : + m_Socket(socket) {} + + NPT_Result operator()(NPT_IpAddress& if_addr) const { + NPT_IpAddress addr; + addr.ResolveName("239.255.255.250"); + return m_Socket->JoinGroup(addr, if_addr); + } + +private: + NPT_UdpMulticastSocket* m_Socket; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpDeviceAnnounceTask class ++---------------------------------------------------------------------*/ +class PLT_SsdpDeviceAnnounceTask : public PLT_ThreadTask +{ +public: + PLT_SsdpDeviceAnnounceTask(PLT_DeviceHost* device, + NPT_TimeInterval repeat, + bool is_byebye_first = false, + bool broadcast = false) : + m_Device(device), + m_Repeat(repeat), m_IsByeByeFirst(is_byebye_first), + m_IsBroadcast(broadcast) {} + +protected: + virtual ~PLT_SsdpDeviceAnnounceTask() {} + + // PLT_ThreadTask methods + virtual void DoRun(); + +protected: + PLT_DeviceHost* m_Device; + NPT_TimeInterval m_Repeat; + bool m_IsByeByeFirst; + bool m_IsBroadcast; +}; + +/*---------------------------------------------------------------------- +| PLT_NetworkInterfaceAddressSearchIterator class ++---------------------------------------------------------------------*/ +class PLT_NetworkInterfaceAddressSearchIterator +{ +public: + PLT_NetworkInterfaceAddressSearchIterator(NPT_String ip) : m_Ip(ip) {} + virtual ~PLT_NetworkInterfaceAddressSearchIterator() {} + + NPT_Result operator()(NPT_NetworkInterface*& addr) const { + NPT_List<NPT_NetworkInterfaceAddress>::Iterator niaddr = addr->GetAddresses().GetFirstItem(); + if (!niaddr) return NPT_FAILURE; + + return (m_Ip.Compare((*niaddr).GetPrimaryAddress().ToString(), true) == 0) ? NPT_SUCCESS : NPT_FAILURE; + } + +private: + NPT_String m_Ip; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpPacketListenerIterator class ++---------------------------------------------------------------------*/ +class PLT_SsdpPacketListenerIterator +{ +public: + PLT_SsdpPacketListenerIterator(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context) : + m_Request(request), m_Context(context) {} + + NPT_Result operator()(PLT_SsdpPacketListener*& listener) const { + return listener->OnSsdpPacket(m_Request, m_Context); + } + +private: + NPT_HttpRequest& m_Request; + const NPT_HttpRequestContext& m_Context; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpListenTask class ++---------------------------------------------------------------------*/ +class PLT_SsdpListenTask : public PLT_HttpServerSocketTask +{ +public: + PLT_SsdpListenTask(NPT_Socket* socket, + bool multicast = true, + bool join_hard = false) : + PLT_HttpServerSocketTask(socket, true), + m_Multicast(multicast), m_JoinHard(join_hard) {} + + NPT_Result AddListener(PLT_SsdpPacketListener* listener) { + NPT_AutoLock lock(m_Mutex); + m_Listeners.Add(listener); + return NPT_SUCCESS; + } + + NPT_Result RemoveListener(PLT_SsdpPacketListener* listener) { + NPT_AutoLock lock(m_Mutex); + m_Listeners.Remove(listener); + return NPT_SUCCESS; + } + +protected: + virtual ~PLT_SsdpListenTask() {} + + // PLT_ThreadTask methods + virtual void DoInit(); + + // PLT_HttpServerSocketTask methods + NPT_Result GetInputStream(NPT_InputStreamReference& stream); + NPT_Result GetInfo(NPT_SocketInfo& info); + NPT_Result ProcessRequest(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse*& response, + bool& headers_only); + +protected: + PLT_InputDatagramStreamReference m_Datagram; + bool m_Multicast; + bool m_JoinHard; + NPT_List<PLT_SsdpPacketListener*> m_Listeners; + NPT_Mutex m_Mutex; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpSearchTask class ++---------------------------------------------------------------------*/ +class PLT_SsdpSearchTask : public PLT_ThreadTask +{ +public: + PLT_SsdpSearchTask(NPT_UdpSocket* socket, + PLT_SsdpSearchResponseListener* listener, + NPT_HttpRequest* request, + NPT_Timeout frequency); // pass 0 for one time + +protected: + virtual ~PLT_SsdpSearchTask(); + + // PLT_ThreadTask methods + virtual void DoAbort(); + virtual void DoRun(); + + virtual NPT_Result ProcessResponse(NPT_Result res, + NPT_HttpRequest* request, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response); + +private: + PLT_SsdpSearchResponseListener* m_Listener; + NPT_HttpRequest* m_Request; + NPT_Timeout m_Timeout; + bool m_Repeat; + NPT_UdpSocket* m_Socket; +}; + +#endif /* _PLT_SSDP_H_ */ diff --git a/modules/platinum/SDK/include/PltSsdpListener.h b/modules/platinum/SDK/include/PltSsdpListener.h new file mode 100644 index 0000000..00dda7c --- /dev/null +++ b/modules/platinum/SDK/include/PltSsdpListener.h @@ -0,0 +1,65 @@ +/***************************************************************** +| +| Platinum - SSDP Listener +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_SSDP_LISTENER_H_ +#define _PLT_SSDP_LISTENER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| PLT_SsdpPacketListener class ++---------------------------------------------------------------------*/ +class PLT_SsdpPacketListener +{ +public: + virtual ~PLT_SsdpPacketListener() {} + virtual NPT_Result OnSsdpPacket(NPT_HttpRequest& request, + const NPT_HttpRequestContext& context) = 0; +}; + +/*---------------------------------------------------------------------- +| PLT_SsdpSearchResponseListener class ++---------------------------------------------------------------------*/ +class PLT_SsdpSearchResponseListener +{ +public: + virtual ~PLT_SsdpSearchResponseListener() {} + virtual NPT_Result ProcessSsdpSearchResponse(NPT_Result res, + const NPT_HttpRequestContext& context, + NPT_HttpResponse* response) = 0; +}; + +#endif /* _PLT_SSDP_LISTENER_H_ */ diff --git a/modules/platinum/SDK/include/PltStateVariable.h b/modules/platinum/SDK/include/PltStateVariable.h new file mode 100644 index 0000000..27b58d4 --- /dev/null +++ b/modules/platinum/SDK/include/PltStateVariable.h @@ -0,0 +1,144 @@ +/***************************************************************** +| +| Platinum - Service State Variable +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_STATE_VARIABLE_H_ +#define _PLT_STATE_VARIABLE_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_Argument; +class PLT_Service; + +/*---------------------------------------------------------------------- +| NPT_AllowedValueRange class ++---------------------------------------------------------------------*/ +typedef struct { + NPT_Int32 min_value; + NPT_Int32 max_value; + NPT_Int32 step; +} NPT_AllowedValueRange; + +/*---------------------------------------------------------------------- +| PLT_StateVariable class ++---------------------------------------------------------------------*/ +class PLT_StateVariable +{ +public: + PLT_StateVariable(PLT_Service* service); + ~PLT_StateVariable(); + + NPT_Result GetSCPDXML(NPT_XmlElementNode* node); + PLT_Service* GetService(); + bool IsSendingEvents(bool indirectly = false); + void DisableIndirectEventing(); + NPT_Result SetRate(NPT_TimeInterval rate); + NPT_Result SetValue(const char* value); + NPT_Result ValidateValue(const char* value); + NPT_Result Serialize(NPT_XmlElementNode& node); + NPT_Result SetExtraAttribute(const char* name, const char* value); + + const NPT_String& GetName() const { return m_Name; } + const NPT_String& GetValue() const { return m_Value; } + const NPT_String& GetDataType() const { return m_DataType; } + const NPT_AllowedValueRange* GetAllowedValueRange() const { return m_AllowedValueRange; } + + static PLT_StateVariable* Find(NPT_List<PLT_StateVariable*>& vars, + const char* name); + +protected: + bool IsReadyToPublish(); + +protected: + friend class PLT_Service; + + //members + PLT_Service* m_Service; + NPT_AllowedValueRange* m_AllowedValueRange; + NPT_String m_Name; + NPT_String m_DataType; + NPT_String m_DefaultValue; + bool m_IsSendingEvents; + bool m_IsSendingEventsIndirectly; + NPT_TimeInterval m_Rate; + NPT_TimeStamp m_LastEvent; + NPT_Array<NPT_String*> m_AllowedValues; + NPT_String m_Value; + + NPT_Map<NPT_String,NPT_String> m_ExtraAttributes; +}; + +/*---------------------------------------------------------------------- +| PLT_StateVariableNameFinder ++---------------------------------------------------------------------*/ +class PLT_StateVariableNameFinder +{ +public: + // methods + PLT_StateVariableNameFinder(const char* name) : m_Name(name) {} + virtual ~PLT_StateVariableNameFinder() {} + + bool operator()(const PLT_StateVariable* const & state_variable) const { + return state_variable->GetName().Compare(m_Name, true) ? false : true; + } + +private: + // members + NPT_String m_Name; +}; + +/*---------------------------------------------------------------------- +| PLT_ListStateVariableNameFinder ++---------------------------------------------------------------------*/ +class PLT_ListStateVariableNameFinder +{ +public: + // methods + PLT_ListStateVariableNameFinder(const char* name) : m_Name(name) {} + virtual ~PLT_ListStateVariableNameFinder() {} + + bool operator()(const PLT_StateVariable* const & state_variable) const { + return state_variable->GetName().Compare(m_Name, true) ? false : true; + } + +private: + // members + NPT_String m_Name; +}; + +#endif /* _PLT_STATE_VARIABLE_H_ */ diff --git a/modules/platinum/SDK/include/PltStreamPump.h b/modules/platinum/SDK/include/PltStreamPump.h new file mode 100644 index 0000000..2584510 --- /dev/null +++ b/modules/platinum/SDK/include/PltStreamPump.h @@ -0,0 +1,131 @@ +/***************************************************************** +| +| Platinum - Stream Pump +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_STREAM_PUMP_H_ +#define _PLT_STREAM_PUMP_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptStreams.h" +#include "NptRingBuffer.h" + +/*---------------------------------------------------------------------- +| PLT_PipeInputStream ++---------------------------------------------------------------------*/ +class PLT_PipeInputStream +{ +public: + // constructor and destructor + virtual ~PLT_PipeInputStream() {}; + + // methods + virtual NPT_Result Receive(NPT_InputStream& stream, NPT_Size max_bytes_to_read, NPT_Size* bytes_read = 0) = 0; +}; + +typedef NPT_Reference<PLT_PipeInputStream> PLT_PipeInputStreamReference; + +/*---------------------------------------------------------------------- +| PLT_PipeOutputStream ++---------------------------------------------------------------------*/ +class PLT_PipeOutputStream +{ +public: + // constructor and destructor + virtual ~PLT_PipeOutputStream() {}; + + // methods + virtual NPT_Result Transmit(NPT_OutputStream& stream) = 0; +}; + +typedef NPT_Reference<PLT_PipeOutputStream> PLT_PipeOutputStreamReference; + +/*---------------------------------------------------------------------- +| PLT_StreamPump class ++---------------------------------------------------------------------*/ +class PLT_StreamPump +{ +public: + virtual ~PLT_StreamPump(); + +protected: + // methods + PLT_StreamPump(NPT_Size size = 65535); + NPT_Result PullData(NPT_InputStream& input, NPT_Size max_bytes_to_read); + NPT_Result PushData(NPT_OutputStream& output, NPT_Size& bytes_written); + + // members + NPT_RingBuffer* m_RingBuffer; + NPT_Offset m_TotalBytesRead; + NPT_Offset m_TotalBytesWritten; +}; + +/*---------------------------------------------------------------------- +| PLT_PipeInputStreamPump class ++---------------------------------------------------------------------*/ +class PLT_PipeInputStreamPump : public PLT_StreamPump, + public PLT_PipeInputStream +{ +public: + PLT_PipeInputStreamPump(NPT_OutputStreamReference& output, NPT_Size size = 65535); + virtual ~PLT_PipeInputStreamPump(); + + NPT_Result Receive(NPT_InputStream& input, NPT_Size max_bytes_to_read, NPT_Size* bytes_read); + +protected: + NPT_OutputStreamReference m_Output; + NPT_Result m_LastRes; +}; + +/*---------------------------------------------------------------------- +| PLT_PipeInputStreamPump class ++---------------------------------------------------------------------*/ +class PLT_PipeOutputStreamPump : public PLT_StreamPump, + public PLT_PipeOutputStream +{ +public: + PLT_PipeOutputStreamPump(NPT_InputStreamReference& input, + NPT_Size size = 65535, + NPT_Size max_bytes_to_read = 0); + virtual ~PLT_PipeOutputStreamPump(); + + NPT_Result Transmit(NPT_OutputStream& output); + +protected: + NPT_InputStreamReference m_Input; + NPT_Size m_MaxBytesToRead; + NPT_Result m_LastRes; +}; + + +#endif // _PLT_STREAM_PUMP_H_ diff --git a/modules/platinum/SDK/include/PltSvnVersion.h b/modules/platinum/SDK/include/PltSvnVersion.h new file mode 100644 index 0000000..0aeffb3 --- /dev/null +++ b/modules/platinum/SDK/include/PltSvnVersion.h @@ -0,0 +1,3 @@ +/* DO NOT EDIT. This file was automatically generated by GenSvnVersionHeader.py */ +#define PLT_SVN_VERSION 498 +#define PLT_SVN_VERSION_STRING "498" diff --git a/modules/platinum/SDK/include/PltSyncMediaBrowser.h b/modules/platinum/SDK/include/PltSyncMediaBrowser.h new file mode 100644 index 0000000..35d0bf2 --- /dev/null +++ b/modules/platinum/SDK/include/PltSyncMediaBrowser.h @@ -0,0 +1,168 @@ +/***************************************************************** +| +| Platinum - Synchronous Media Browser +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_SYNC_MEDIA_BROWSER_ +#define _PLT_SYNC_MEDIA_BROWSER_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltCtrlPoint.h" +#include "PltMediaBrowser.h" +#include "PltMediaCache.h" + +/*---------------------------------------------------------------------- +| types ++---------------------------------------------------------------------*/ +typedef NPT_Map<NPT_String, PLT_DeviceDataReference> PLT_DeviceMap; +typedef NPT_Map<NPT_String, PLT_DeviceDataReference>::Entry PLT_DeviceMapEntry; + +typedef struct PLT_BrowseData { + NPT_SharedVariable shared_var; + NPT_Result res; + PLT_BrowseInfo info; +} PLT_BrowseData; + +typedef NPT_Reference<PLT_BrowseData> PLT_BrowseDataReference; + +/*---------------------------------------------------------------------- +| PLT_MediaContainerListener ++---------------------------------------------------------------------*/ +class PLT_MediaContainerChangesListener +{ +public: + virtual ~PLT_MediaContainerChangesListener() {} + virtual void OnContainerChanged(PLT_DeviceDataReference& device, + const char* item_id, + const char* update_id) = 0; +}; + +/*---------------------------------------------------------------------- +| PLT_SyncMediaBrowser ++---------------------------------------------------------------------*/ +class PLT_SyncMediaBrowser : public PLT_MediaBrowser, + public PLT_MediaBrowserDelegate +{ +public: + PLT_SyncMediaBrowser(PLT_CtrlPointReference& ctrlPoint, + bool use_cache = false, + PLT_MediaContainerChangesListener* listener = NULL); + virtual ~PLT_SyncMediaBrowser(); + + // PLT_MediaBrowser methods + virtual NPT_Result OnDeviceAdded(PLT_DeviceDataReference& device); + virtual NPT_Result OnDeviceRemoved(PLT_DeviceDataReference& device); + + // PLT_MediaBrowserDelegate methods + virtual void OnMSStateVariablesChanged(PLT_Service* service, + NPT_List<PLT_StateVariable*>* vars); + virtual void OnBrowseResult(NPT_Result res, + PLT_DeviceDataReference& device, + PLT_BrowseInfo* info, + void* userdata); + + // methods + void SetContainerListener(PLT_MediaContainerChangesListener* listener) { + m_ContainerListener = listener; + } + NPT_Result BrowseSync(PLT_DeviceDataReference& device, + const char* id, + PLT_MediaObjectListReference& list, + bool metadata = false, + NPT_Int32 start = 0, + NPT_Cardinal max_results = 0); // 0 means all + + const NPT_Lock<PLT_DeviceMap>& GetMediaServersMap() const { return m_MediaServers; } + bool IsCached(const char* uuid, const char* object_id); + +protected: + NPT_Result BrowseSync(PLT_BrowseDataReference& browse_data, + PLT_DeviceDataReference& device, + const char* object_id, + NPT_Int32 index, + NPT_Int32 count, + bool browse_metadata = false, + const char* filter = "dc:date,upnp:genre,res,res@duration,res@size,upnp:albumArtURI,upnp:album,upnp:artist,upnp:author", // explicitely specify res otherwise WMP won't return a URL! + const char* sort = ""); +private: + NPT_Result Find(const char* ip, PLT_DeviceDataReference& device); + NPT_Result WaitForResponse(NPT_SharedVariable& shared_var); + +private: + NPT_Lock<PLT_DeviceMap> m_MediaServers; + PLT_MediaContainerChangesListener* m_ContainerListener; + bool m_UseCache; + PLT_MediaCache m_Cache; +}; + +/*---------------------------------------------------------------------- +| PLT_DeviceMapFinderByIp ++---------------------------------------------------------------------*/ +class PLT_DeviceMapFinderByIp +{ +public: + // methods + PLT_DeviceMapFinderByIp(const char* ip) : m_IP(ip) {} + + bool operator()(const PLT_DeviceMapEntry* const& entry) const { + PLT_DeviceDataReference device = entry->GetValue(); + return (device->GetURLBase().GetHost() == m_IP); + } + +private: + // members + NPT_String m_IP; +}; + +/*---------------------------------------------------------------------- +| PLT_DeviceFinderByUUID ++---------------------------------------------------------------------*/ +class PLT_DeviceMapFinderByUUID +{ +public: + // methods + PLT_DeviceMapFinderByUUID(const char* uuid) : m_UUID(uuid) {} + + bool operator()(const PLT_DeviceMapEntry* const& entry) const { + PLT_DeviceDataReference device = entry->GetValue(); + return device->GetUUID() == m_UUID; + } + +private: + // members + NPT_String m_UUID; +}; + +#endif /* _PLT_SYNC_MEDIA_BROWSER_ */ + diff --git a/modules/platinum/SDK/include/PltTaskManager.h b/modules/platinum/SDK/include/PltTaskManager.h new file mode 100644 index 0000000..6cab063 --- /dev/null +++ b/modules/platinum/SDK/include/PltTaskManager.h @@ -0,0 +1,82 @@ +/***************************************************************** +| +| Platinum - Task Manager +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_TASKMANAGER_H_ +#define _PLT_TASKMANAGER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| forward declarations ++---------------------------------------------------------------------*/ +class PLT_ThreadTask; + +/*---------------------------------------------------------------------- +| PLT_TaskManager class ++---------------------------------------------------------------------*/ +class PLT_TaskManager +{ + friend class PLT_ThreadTask; + friend class PLT_ThreadTaskCallback; + +public: + PLT_TaskManager(NPT_Cardinal max_items = 0); + virtual ~PLT_TaskManager(); + + // tasks related methods + virtual NPT_Result StartTask(PLT_ThreadTask* task, + NPT_TimeInterval* delay = NULL, + bool auto_destroy = true); + + // methods + NPT_Result StopAllTasks(); + +private: + // called by PLT_ThreadTaskCallback + NPT_Mutex& GetCallbackLock() { return m_CallbackLock; } + + // called by PLT_ThreadTask + NPT_Result AddTask(PLT_ThreadTask* task); + NPT_Result RemoveTask(PLT_ThreadTask* task); + +private: + NPT_List<PLT_ThreadTask*> m_Tasks; + NPT_Mutex m_TasksLock; + NPT_Mutex m_CallbackLock; + NPT_Queue<int>* m_Queue; +}; + +#endif /* _PLT_TASKMANAGER_H_ */ diff --git a/modules/platinum/SDK/include/PltThreadTask.h b/modules/platinum/SDK/include/PltThreadTask.h new file mode 100644 index 0000000..7cd9242 --- /dev/null +++ b/modules/platinum/SDK/include/PltThreadTask.h @@ -0,0 +1,108 @@ +/***************************************************************** +| +| Platinum - Thread Tasks +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_THREADTASK_H_ +#define _PLT_THREADTASK_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +#include "PltTaskManager.h" + +/*---------------------------------------------------------------------- +| PLT_ThreadTask class ++---------------------------------------------------------------------*/ +class PLT_ThreadTask : public NPT_Runnable +{ +public: + friend class PLT_TaskManager; + + PLT_ThreadTask(); + + NPT_Result Kill(); + + virtual bool IsAborting(NPT_Timeout timeout = NPT_TIMEOUT_INFINITE) { + return NPT_SUCCEEDED(m_Abort.WaitUntilEquals(1, timeout)); + } + +protected: + NPT_Result Start(PLT_TaskManager* task_manager = NULL, + NPT_TimeInterval* delay = NULL, + bool auto_destroy = true); + NPT_Result Stop(bool blocking = true); + + // overridable + virtual void DoAbort() {} + virtual void DoRun() {} + virtual void DoInit() {} + + // the task manager will destroy the task when finished + // if m_AutoDestroy is set otherwise use Kill + virtual ~PLT_ThreadTask(); + +private: + // NPT_Thread methods + void Run(); + +protected: + // members + PLT_TaskManager* m_TaskManager; + +private: + // members + NPT_SharedVariable m_Abort; + NPT_Thread* m_Thread; + bool m_AutoDestroy; + NPT_TimeInterval m_Delay; +}; + +/*---------------------------------------------------------------------- +| PLT_ThreadTaskCallback class ++---------------------------------------------------------------------*/ +class PLT_ThreadTaskCallback +{ +public: + PLT_ThreadTaskCallback(NPT_Mutex& lock) : m_Lock(lock) {} + virtual ~PLT_ThreadTaskCallback() {}; + + NPT_Result Callback(); + +protected: + virtual NPT_Result DoCallback() = 0; + +protected: + NPT_Mutex& m_Lock; +}; + +#endif /* _PLT_THREADTASK_H_ */ diff --git a/modules/platinum/SDK/include/PltTime.h b/modules/platinum/SDK/include/PltTime.h new file mode 100644 index 0000000..ceec181 --- /dev/null +++ b/modules/platinum/SDK/include/PltTime.h @@ -0,0 +1,57 @@ +/***************************************************************** +| +| Platinum - Time +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_TIME_H_ +#define _PLT_TIME_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "NptTypes.h" +#include "NptTime.h" + +/*---------------------------------------------------------------------- +| PLT_Time ++---------------------------------------------------------------------*/ +class PLT_Time +{ +public: + // methods + static NPT_Result GetTimeStampFromDate(const NPT_Date& date, + NPT_TimeStamp& timestamp); + + /* helper functions */ + static NPT_Result SetDateTimeZone(NPT_Date& date, NPT_TimeZone tz); +}; + +#endif // _NPT_TIME_H_ diff --git a/modules/platinum/SDK/include/PltUPnP.h b/modules/platinum/SDK/include/PltUPnP.h new file mode 100644 index 0000000..43c19f4 --- /dev/null +++ b/modules/platinum/SDK/include/PltUPnP.h @@ -0,0 +1,92 @@ +/***************************************************************** +| +| Platinum - UPnP Engine +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_UPNP_H_ +#define _PLT_UPNP_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "PltTaskManager.h" +#include "PltCtrlPoint.h" +#include "PltDeviceHost.h" +#include "PltUPnPHelper.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#define PLT_DLNA_SSDP_DELAY 0.02f + +/*---------------------------------------------------------------------- +| forward definitions ++---------------------------------------------------------------------*/ +class PLT_SsdpListenTask; + +/*---------------------------------------------------------------------- +| PLT_UPnP class ++---------------------------------------------------------------------*/ +class PLT_UPnP +{ +public: + PLT_UPnP(NPT_UInt32 ssdp_port = 1900, bool multicast = true); + ~PLT_UPnP(); + + NPT_Result AddDevice(PLT_DeviceHostReference& device); + NPT_Result AddCtrlPoint(PLT_CtrlPointReference& ctrlpoint); + + NPT_Result RemoveDevice(PLT_DeviceHostReference& device); + NPT_Result RemoveCtrlPoint(PLT_CtrlPointReference& ctrlpoint); + + NPT_Result Start(); + NPT_Result Stop(); + + void SetIgnoreLocalUUIDs(bool ignore) { m_IgnoreLocalUUIDs = ignore; } + +private: + // members + NPT_Mutex m_Lock; + NPT_List<PLT_DeviceHostReference> m_Devices; + NPT_List<PLT_CtrlPointReference> m_CtrlPoints; + PLT_TaskManager m_TaskManager; + + // since we can only have one socket listening on port 1900, + // we create it in here and we will attach every control points + // and devices to it when they're added + bool m_Started; + NPT_UInt32 m_Port; + bool m_Multicast; + PLT_SsdpListenTask* m_SsdpListenTask; + bool m_IgnoreLocalUUIDs; +}; + +#endif /* _PLT_UPNP_H_ */ diff --git a/modules/platinum/SDK/include/PltUPnPHelper.h b/modules/platinum/SDK/include/PltUPnPHelper.h new file mode 100644 index 0000000..3cfdd7b --- /dev/null +++ b/modules/platinum/SDK/include/PltUPnPHelper.h @@ -0,0 +1,341 @@ +/***************************************************************** +| +| Platinum - UPnP Helper +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_UPNP_HELPER_H_ +#define _PLT_UPNP_HELPER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" + +/*---------------------------------------------------------------------- +| NPT_StringFinder ++---------------------------------------------------------------------*/ +class NPT_StringFinder +{ +public: + // methods + NPT_StringFinder(const char* value) : m_Value(value) {} + virtual ~NPT_StringFinder() {} + bool operator()(const NPT_String* const & value) const { + return value->Compare(m_Value) ? false : true; + } + bool operator()(const NPT_String& value) const { + return value.Compare(m_Value) ? false : true; + } + +private: + // members + NPT_String m_Value; +}; + +/*---------------------------------------------------------------------- +| PLT_UPnPMessageHelper class ++---------------------------------------------------------------------*/ +class PLT_UPnPMessageHelper +{ +public: + // methods + static const NPT_String* GetST(NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("ST"); + } + static NPT_Result SetST(NPT_HttpMessage& message, + const char* st) { + return message.GetHeaders().SetHeader("ST", st); + } + static const NPT_String* GetNT(NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("NT"); + } + static NPT_Result SetNT(NPT_HttpMessage& message, + const char* nt) { + return message.GetHeaders().SetHeader("NT", nt); + } + static const NPT_String* GetNTS(NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("NTS"); + } + static NPT_Result SetNTS(NPT_HttpMessage& message, + const char* nts) { + return message.GetHeaders().SetHeader("NTS", nts); + } + static const NPT_String* GetMAN(NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("MAN"); + } + static NPT_Result SetMAN(NPT_HttpMessage& message, + const char* man) { + return message.GetHeaders().SetHeader("MAN", man); + } + static const NPT_String* GetLocation(NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("LOCATION"); + } + static NPT_Result SetLocation(NPT_HttpMessage& message, + const char* location) { + return message.GetHeaders().SetHeader("LOCATION", location); + } + static const NPT_String* GetServer(NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue(NPT_HTTP_HEADER_SERVER); + } + static NPT_Result SetServer(NPT_HttpMessage& message, + const char* server, + bool replace = true) { + return message.GetHeaders().SetHeader( + NPT_HTTP_HEADER_SERVER, + server, + replace); + } + static const NPT_String* GetUSN(NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("USN"); + } + static NPT_Result SetUSN(NPT_HttpMessage& message, + const char* usn) { + return message.GetHeaders().SetHeader("USN", usn); + } + static const NPT_String* GetCallbacks(NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("CALLBACK"); + } + static NPT_Result SetCallbacks(NPT_HttpMessage& message, + const char* callbacks) { + return message.GetHeaders().SetHeader("CALLBACK", callbacks); + } + static const NPT_String* GetSID(NPT_HttpMessage& message) { + return message.GetHeaders().GetHeaderValue("SID"); + } + static NPT_Result SetSID(NPT_HttpMessage& message, + const char* sid) { + return message.GetHeaders().SetHeader("SID", sid); + } + static NPT_Result GetLeaseTime(NPT_HttpMessage& message, + NPT_Timeout& value) { + value = 0; + const NPT_String* cc = + message.GetHeaders().GetHeaderValue("CACHE-CONTROL"); + NPT_CHECK_POINTER(cc); + return ExtractLeaseTime(*cc, value); + } + static NPT_Result SetLeaseTime(NPT_HttpMessage& message, + const NPT_Timeout lease) { + return message.GetHeaders().SetHeader( + "CACHE-CONTROL", + "max-age="+NPT_String::FromInteger(lease)); + } + static NPT_Result GetTimeOut(NPT_HttpMessage& message, + NPT_Int32& value) { + value = 0; + const NPT_String* timeout = + message.GetHeaders().GetHeaderValue("TIMEOUT"); + NPT_CHECK_POINTER(timeout); + return ExtractTimeOut(*timeout, value); + } + static NPT_Result SetTimeOut(NPT_HttpMessage& message, + const NPT_Int32 timeout) { + if (timeout >= 0) { + return message.GetHeaders().SetHeader( + "TIMEOUT", + "Second-"+NPT_String::FromInteger(timeout)); + } else { + return message.GetHeaders().SetHeader( + "TIMEOUT", "Second-infinite"); + } + } + static NPT_Result GetMX(NPT_HttpMessage& message, + NPT_UInt32& value) { + value = 0; + const NPT_String* mx = + message.GetHeaders().GetHeaderValue("MX"); + NPT_CHECK_POINTER(mx); + return NPT_ParseInteger32(*mx, value); + } + static NPT_Result SetMX(NPT_HttpMessage& message, + const NPT_UInt32 mx) { + return message.GetHeaders().SetHeader( + "MX", + NPT_String::FromInteger(mx)); + } + static NPT_Result GetSeq(NPT_HttpMessage& message, + NPT_UInt32& value) { + value = 0; + const NPT_String* seq = + message.GetHeaders().GetHeaderValue("SEQ"); + NPT_CHECK_POINTER(seq); + return NPT_ParseInteger32(*seq, value); + } + static NPT_Result SetSeq(NPT_HttpMessage& message, + const NPT_UInt32 seq) { + return message.GetHeaders().SetHeader( + "SEQ", + NPT_String::FromInteger(seq)); + } + static const char* GenerateUUID(int count, + NPT_String& uuid) { + uuid = ""; + for (int i=0;i<(count<100?count:100);i++) { + int random = NPT_System::GetRandomInteger(); + uuid += (char)((random % 25) + 66); + } + return uuid; + } + static const char* GenerateGUID(NPT_String& guid) { + guid = ""; + for (int i=0;i<32;i++) { + char nibble = (char)(NPT_System::GetRandomInteger() % 16); + guid += (nibble < 10) ? ('0' + nibble) : ('a' + (nibble-10)); + if (i == 7 || i == 11 || i == 15 || i == 19) { + guid += '-'; + } + } + return guid; + } + static NPT_Result ExtractLeaseTime(const char* cache_control, + NPT_Timeout& lease) { + int value; + if (cache_control && + sscanf(cache_control, "max-age=%d", &value) == 1) { + lease = value; + return NPT_SUCCESS; + } + return NPT_FAILURE; + } + static NPT_Result ExtractTimeOut(const char* timeout, + NPT_Int32& len) { + NPT_String temp = timeout; + if (temp.CompareN("Second-", 7, true)) { + return NPT_ERROR_INVALID_FORMAT; + } + + if (temp.Compare("Second-infinite", true) == 0) { + len = NPT_TIMEOUT_INFINITE; + return NPT_SUCCESS; + } + return temp.SubString(7).ToInteger(len); + } + static NPT_Result GetIPAddresses(NPT_List<NPT_IpAddress>& ips, + bool with_localhost = false) { + NPT_List<NPT_NetworkInterface*> if_list; + NPT_CHECK(NPT_NetworkInterface::GetNetworkInterfaces(if_list)); + + NPT_List<NPT_NetworkInterface*>::Iterator iface = + if_list.GetFirstItem(); + while (iface) { + NPT_IpAddress ip = + (*(*iface)->GetAddresses().GetFirstItem()).GetPrimaryAddress(); + if (ip.ToString().Compare("0.0.0.0") && ip.ToString().Compare("127.0.0.1")) { + ips.Add(ip); + } + ++iface; + } + + if (ips.GetItemCount() == 0 || with_localhost) { + NPT_IpAddress localhost; + localhost.Parse("127.0.0.1"); + ips.Add(localhost); + } + + if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>()); + return NPT_SUCCESS; + } + + static NPT_Result GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& if_list, + bool with_localhost = false) { + NPT_CHECK(_GetNetworkInterfaces(if_list, false)); + + // if no valid interfaces or if requested, add localhost capable interface + if (if_list.GetItemCount() == 0 || with_localhost) { + NPT_CHECK(_GetNetworkInterfaces(if_list, true)); + } + return NPT_SUCCESS; + } + + static NPT_Result GetMACAddresses(NPT_List<NPT_String>& addresses) { + NPT_List<NPT_NetworkInterface*> if_list; + NPT_CHECK(NPT_NetworkInterface::GetNetworkInterfaces(if_list)); + + NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem(); + while (iface) { + NPT_String ip = (*(*iface)->GetAddresses().GetFirstItem()).GetPrimaryAddress().ToString(); + if (ip.Compare("0.0.0.0") && ip.Compare("127.0.0.1")) { + addresses.Add((*iface)->GetMacAddress().ToString()); + } + ++iface; + } + + if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>()); + return NPT_SUCCESS; + } + + + static bool IsLocalNetworkAddress(const NPT_IpAddress& address) { + if(address.ToString() == "127.0.0.1") return true; + + NPT_List<NPT_NetworkInterface*> if_list; + NPT_NetworkInterface::GetNetworkInterfaces(if_list); + + NPT_List<NPT_NetworkInterface*>::Iterator iface = if_list.GetFirstItem(); + while (iface) { + if((*iface)->IsAddressInNetwork(address)) return true; + ++iface; + } + + if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>()); + return false; + } + +private: + + static NPT_Result _GetNetworkInterfaces(NPT_List<NPT_NetworkInterface*>& if_list, + bool only_localhost = false) { + NPT_List<NPT_NetworkInterface*> _if_list; + NPT_CHECK(NPT_NetworkInterface::GetNetworkInterfaces(_if_list)); + + NPT_NetworkInterface* iface; + while (NPT_SUCCEEDED(_if_list.PopHead(iface))) { + NPT_String ip = + iface->GetAddresses().GetFirstItem()->GetPrimaryAddress().ToString(); + if (ip.Compare("0.0.0.0") && + ((!only_localhost && ip.Compare("127.0.0.1")) || + (only_localhost && !ip.Compare("127.0.0.1")))) { + if_list.Add(iface); + + // add localhost only once + if (only_localhost) break; + } else { + delete iface; + } + } + + // cleanup any remaining items in list if we breaked early + _if_list.Apply(NPT_ObjectDeleter<NPT_NetworkInterface>()); + return NPT_SUCCESS; + } +}; + +#endif /* _PLT_UPNP_HELPER_H_ */ diff --git a/modules/platinum/SDK/include/PltVersion.h b/modules/platinum/SDK/include/PltVersion.h new file mode 100644 index 0000000..7140429 --- /dev/null +++ b/modules/platinum/SDK/include/PltVersion.h @@ -0,0 +1,48 @@ +/***************************************************************** +| +| Platinum - Version Info +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_VERSION_H_ +#define _PLT_VERSION_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "PltSvnVersion.h" + +/*---------------------------------------------------------------------- +| constants ++---------------------------------------------------------------------*/ +#define PLT_PLATINUM_SDK_VERSION 0x00050400 +#define PLT_PLATINUM_SDK_VERSION_STRING "0.5.4.0" + +#endif // _PLT_VERSION_H_ diff --git a/modules/platinum/SDK/include/PltXmlHelper.h b/modules/platinum/SDK/include/PltXmlHelper.h new file mode 100644 index 0000000..be71cef --- /dev/null +++ b/modules/platinum/SDK/include/PltXmlHelper.h @@ -0,0 +1,299 @@ +/***************************************************************** +| +| Platinum - Xml Helper +| +| Copyright (c) 2004-2008, Plutinosoft, LLC. +| All rights reserved. +| http://www.plutinosoft.com +| +| This program is free software; you can redistribute it and/or +| modify it under the terms of the GNU General Public License +| as published by the Free Software Foundation; either version 2 +| of the License, or (at your option) any later version. +| +| OEMs, ISVs, VARs and other distributors that combine and +| distribute commercially licensed software with Platinum software +| and do not wish to distribute the source code for the commercially +| licensed software under version 2, or (at your option) any later +| version, of the GNU General Public License (the "GPL") must enter +| into a commercial license agreement with Plutinosoft, LLC. +| +| This program is distributed in the hope that it will be useful, +| but WITHOUT ANY WARRANTY; without even the implied warranty of +| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +| GNU General Public License for more details. +| +| You should have received a copy of the GNU General Public License +| along with this program; see the file LICENSE.txt. If not, write to +| the Free Software Foundation, Inc., +| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +| http://www.gnu.org/licenses/gpl-2.0.html +| +****************************************************************/ + +#ifndef _PLT_XML_HELPER_H_ +#define _PLT_XML_HELPER_H_ + +/*---------------------------------------------------------------------- +| includes ++---------------------------------------------------------------------*/ +#include "Neptune.h" +/*---------------------------------------------------------------------- +| PLT_XmlAttributeFinder ++---------------------------------------------------------------------*/ +class PLT_XmlAttributeFinder +{ +public: + // if 'namespc' is NULL, we're looking for ANY namespace + // if 'namespc' is '\0', we're looking for NO namespace + // if 'namespc' is non-empty, look for that SPECIFIC namespace + PLT_XmlAttributeFinder(const NPT_XmlElementNode& element, + const char* name, + const char* namespc) : + m_Element(element), m_Name(name), m_Namespace(namespc) {} + + bool operator()(const NPT_XmlAttribute* const & attribute) const { + if (attribute->GetName() == m_Name) { + if (m_Namespace) { + const NPT_String& prefix = attribute->GetPrefix(); + if (m_Namespace[0] == '\0') { + // match if the attribute has NO namespace + return prefix.IsEmpty(); + } else { + // match if the attribute has the SPECIFIC namespace + // we're looking for + const NPT_String* namespc = m_Element.GetNamespaceUri(prefix); + return namespc && *namespc == m_Namespace; + } + } else { + // ANY namespace will match + return true; + } + } else { + return false; + } + } + +private: + const NPT_XmlElementNode& m_Element; + const char* m_Name; + const char* m_Namespace; +}; + +/*---------------------------------------------------------------------- +| PLT_XmlHelper ++---------------------------------------------------------------------*/ +class PLT_XmlHelper +{ +public: + + // static methods + static NPT_Result GetChildText(NPT_XmlElementNode* node, + const char* tag, + NPT_String& value, + const char* namespc = "") { + value = ""; + + if (!node) return NPT_FAILURE; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + + NPT_XmlElementNode* child = node->GetChild(tag, namespc); + if (!child) return NPT_FAILURE; + + const NPT_String* text = child->GetText(); + value = text?*text:""; + return NPT_SUCCESS; + } + + static NPT_Result RemoveAttribute(NPT_XmlElementNode* node, + const char* name, + const char* namespc = "") { + if (!node) return NPT_FAILURE; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + + NPT_List<NPT_XmlAttribute*>::Iterator attribute; + attribute = node->GetAttributes().Find(PLT_XmlAttributeFinder(*node, name, namespc)); + if (!attribute) return NPT_FAILURE; + + delete *attribute; + NPT_CHECK(node->GetAttributes().Erase(attribute)); + + return NPT_SUCCESS; + } + + static NPT_Result GetAttribute(NPT_XmlElementNode* node, + const char* name, + NPT_XmlAttribute*& attr, + const char* namespc = "") { + attr = NULL; + + if (!node) return NPT_FAILURE; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + + NPT_List<NPT_XmlAttribute*>::Iterator attribute; + attribute = node->GetAttributes().Find(PLT_XmlAttributeFinder(*node, name, namespc)); + if (!attribute) return NPT_FAILURE; + + attr = (*attribute); + return NPT_SUCCESS; + } + + static NPT_Result GetAttribute(NPT_XmlElementNode* node, + const char* name, + NPT_String& value, + const char* namespc = "") { + value = ""; + + NPT_XmlAttribute* attribute = NULL; + NPT_CHECK(GetAttribute(node, name, attribute, namespc)); + if (!attribute) return NPT_FAILURE; + + value = attribute->GetValue(); + return NPT_SUCCESS; + } + + static NPT_Result SetAttribute(NPT_XmlElementNode* node, + const char* name, + NPT_String& value, + const char* namespc = "") { + NPT_XmlAttribute* attribute = NULL; + NPT_CHECK(GetAttribute(node, name, attribute, namespc)); + if (!attribute) return NPT_FAILURE; + + attribute->SetValue(value); + return NPT_SUCCESS; + } + + static NPT_Result AddChildText(NPT_XmlElementNode* node, + const char* tag, + const char* text, + const char* prefix = NULL) { + if (!node) return NPT_FAILURE; + NPT_XmlElementNode* child = new NPT_XmlElementNode(prefix, tag); + child->AddText(text); + return node->AddChild(child); + } + + static bool IsMatch(const NPT_XmlNode* const & node, const char* tag, const char* namespc_mapped) { + // if m_Namespace is NULL, we're looking for ANY namespace + // if m_Namespace is '\0', we're looking for NO namespace + // if m_Namespace is non-empty, look for that SPECIFIC namespace + + const NPT_XmlElementNode* element = node->AsElementNode(); + // is tag the same (case sensitive)? + if (element && element->GetTag() == tag) { + if (namespc_mapped) { + // look for a SPECIFIC namespace or NO namespace + const NPT_String* namespc = element->GetNamespace(); + if (namespc) { + // the element has a namespace, match if it is equal to + // what we're looking for + return *namespc == namespc_mapped; + } else { + // the element does not have a namespace, match if we're + // looking for NO namespace + return namespc_mapped[0] == '\0'; + } + } else { + // ANY namespace will match + return true; + } + } + return false; + } + + static NPT_Result GetChildren(NPT_XmlElementNode* node, + NPT_Array<NPT_XmlElementNode*>& children, + const char* tag, + const char* namespc = "") { + if (!node) return NPT_FAILURE; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + + const char* namespc_mapped = (namespc==NULL)?"":(namespc[0]=='*' && namespc[1]=='\0')?NULL:namespc; + + // get all children first + NPT_List<NPT_XmlNode*>& allchildren = node->GetChildren(); + + // iterate through children and add only elements with matching tag + NPT_List<NPT_XmlNode*>::Iterator child = allchildren.GetFirstItem(); + while (child) { + if (IsMatch(*child, tag, namespc_mapped)) { + children.Add((*child)->AsElementNode()); + } + ++child; + } + return NPT_SUCCESS; + } + + static NPT_XmlElementNode* GetChild(NPT_XmlElementNode* node, + const char* tag, + const char* namespc = "") { + if (!node) return NULL; + + // special case "" means we look for the same namespace as the parent + if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE; + + return node->GetChild(tag, namespc); + } + + static NPT_Result GetChild(NPT_XmlElementNode* parent, + NPT_XmlElementNode*& child, + NPT_Ordinal n = 0) { + if (!parent) return NPT_FAILURE; + + // reset child + child = NULL; + + // get all children first + NPT_List<NPT_XmlNode*>::Iterator children = parent->GetChildren().GetFirstItem(); + while (children) { + if ((*children)->AsElementNode() && n-- == 0) { + child = (*children)->AsElementNode(); + return NPT_SUCCESS; + } + children++; + } + + return NPT_FAILURE; + } + + static NPT_Result Serialize(NPT_XmlNode& node, NPT_String& xml, bool add_header = true) { + NPT_XmlWriter writer(0); + NPT_StringOutputStreamReference stream(new NPT_StringOutputStream(&xml)); + NPT_CHECK(writer.Serialize(node, *stream, add_header)); + return NPT_SUCCESS; + } + + static NPT_String Serialize(NPT_XmlNode& node, bool add_header = true) { + NPT_XmlWriter writer(0); + NPT_String xml; + NPT_StringOutputStreamReference stream(new NPT_StringOutputStream(&xml)); + if (NPT_FAILED(writer.Serialize(node, *stream, add_header))) { + NPT_Debug("Failed to serialize xml node"); + return ""; + } + + return xml; + } +private: + // members +}; + +#endif // _PLT_XML_HELPER_H_ + + + + + + + + + diff --git a/modules/pulseaudio/Makefile b/modules/pulseaudio/Makefile index 64fda77..dd91c55 100644 --- a/modules/pulseaudio/Makefile +++ b/modules/pulseaudio/Makefile @@ -17,12 +17,6 @@ endif #common obj OBJS= pulseaudio.o -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif - SRCS := $(OBJS:.o=.c) @@ -30,8 +24,8 @@ LIB=gm_pulseaudio.$(DYN_LIB_SUFFIX) all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac -L/usr/lib -lpulse-simple +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -L/usr/lib -lpulse-simple %.o: %.c diff --git a/modules/pulseaudio/pulseaudio.c b/modules/pulseaudio/pulseaudio.c index a1e1413..dc59fc4 100644 --- a/modules/pulseaudio/pulseaudio.c +++ b/modules/pulseaudio/pulseaudio.c @@ -269,7 +269,7 @@ NewPulseAudioOutput () GF_SAFEALLOC (driv, GF_AudioOutput); if (!driv) { - free (ctx); + gf_free(ctx); return NULL; } driv->opaque = ctx; @@ -295,7 +295,7 @@ DeletePulseAudioOutput (void *ifce) GF_AudioOutput *dr = (GF_AudioOutput *) ifce; free_pulseaudio_resources (dr); if (dr != NULL) - free (dr); + gf_free(dr); } @@ -303,12 +303,13 @@ DeletePulseAudioOutput (void *ifce) * ******************************************************************** * interface */ -Bool -QueryInterface (u32 InterfaceType) +const u32 *QueryInterface (u32 InterfaceType) { - if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) - return 1; - return 0; + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + 0 + }; + return si; } GF_BaseInterface * diff --git a/modules/raw_out/Makefile b/modules/raw_out/Makefile index 68e5787..a359a43 100644 --- a/modules/raw_out/Makefile +++ b/modules/raw_out/Makefile @@ -2,7 +2,7 @@ include ../../config.mak vpath %.c $(SRC_PATH)/modules/raw_out -CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include -DGPAC_HAVE_CONFIG_H -I../../ ifeq ($(DEBUGBUILD), yes) CFLAGS+=-g @@ -14,6 +14,14 @@ CFLAGS+=-pg LDFLAGS+=-pg endif +ifeq ($(ENABLE_JOYSTICK), yes) +CFLAGS+=-DENABLE_JOYSTICK +endif + +ifeq ($(ENABLE_JOYSTICK_NO_CURSOR), yes) +CFLAGS+=-DENABLE_JOYSTICK_NO_CURSOR +endif + #common obj OBJS= raw_video.o @@ -21,20 +29,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_raw_out.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols raw_out.def +#LDFLAGS+=-export-symbols raw_out.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_raw_out-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/raw_out/raw_out.def b/modules/raw_out/raw_out.def deleted file mode 100644 index a8ca11b..0000000 --- a/modules/raw_out/raw_out.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_raw_out.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/raw_out/raw_video.c b/modules/raw_out/raw_video.c index 025f50d..f336083 100644 --- a/modules/raw_out/raw_video.c +++ b/modules/raw_out/raw_video.c @@ -29,6 +29,8 @@ #include <gpac/list.h> #include <gpac/constants.h> +#include <gpac/setup.h> + typedef struct { char *pixels; @@ -44,11 +46,10 @@ typedef struct static GF_Err raw_resize(GF_VideoOutput *dr, u32 w, u32 h) { RAWCTX; - - if (rc->pixels) free(rc->pixels); + if (rc->pixels) gf_free(rc->pixels); rc->width = w; rc->height = h; - rc->pixels = malloc(sizeof(char) * NBPP * w * h); + rc->pixels = gf_malloc(sizeof(char) * NBPP * w * h); if (!rc->pixels) return GF_OUT_OF_MEM; return GF_OK; } @@ -63,7 +64,9 @@ GF_Err RAW_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, u32 init static void RAW_Shutdown(GF_VideoOutput *dr) { RAWCTX; - if (rc->pixels) free(rc->pixels); + int err=0; + + if (rc->pixels) gf_free(rc->pixels); rc->pixels = NULL; } @@ -81,7 +84,8 @@ static GF_Err RAW_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *vi, Bool d vi->height = rc->height; vi->width = rc->width; vi->video_buffer = rc->pixels; - vi->pitch = NBPP * vi->width; + vi->pitch_x = NBPP; + vi->pitch_y = NBPP * vi->width; vi->pixel_format = RAW_OUT_PIXEL_FORMAT; } return GF_OK; @@ -102,11 +106,11 @@ static GF_Err RAW_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) GF_VideoOutput *NewRawVideoOutput() { RawContext *pCtx; - GF_VideoOutput *driv = (GF_VideoOutput *) malloc(sizeof(GF_VideoOutput)); + GF_VideoOutput *driv = (GF_VideoOutput *) gf_malloc(sizeof(GF_VideoOutput)); memset(driv, 0, sizeof(GF_VideoOutput)); GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "Raw Video Output", "gpac distribution") - pCtx = malloc(sizeof(RawContext)); + pCtx = gf_malloc(sizeof(RawContext)); memset(pCtx, 0, sizeof(RawContext)); driv->opaque = pCtx; @@ -126,17 +130,21 @@ void DeleteVideoOutput(void *ifce) RAW_Shutdown(driv); rc = (RawContext *)driv->opaque; - free(rc); - free(driv); + gf_free(rc); + gf_free(driv); } #ifndef GPAC_STANDALONE_RENDER_2D /*interface query*/ -Bool QueryInterface(u32 InterfaceType) +GF_EXPORT +const u32 *QueryInterfaces() { - if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + 0 + }; + return si; } /*interface create*/ GF_BaseInterface *LoadInterface(u32 InterfaceType) diff --git a/modules/redirect_av/Makefile b/modules/redirect_av/Makefile new file mode 100644 index 0000000..062f989 --- /dev/null +++ b/modules/redirect_av/Makefile @@ -0,0 +1,58 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/redirect_av + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +LINKLIBS= -lgpac +LOCAL_LIB=../../bin/gcc + +#common objects +OBJS=redirect_av.o + + + +SRCS := $(OBJS:.o=.c) + +LIB=gm_redirect_av.$(DYN_LIB_SUFFIX) + +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) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/redirect_av/redirect_av.c b/modules/redirect_av/redirect_av.c new file mode 100644 index 0000000..f47c441 --- /dev/null +++ b/modules/redirect_av/redirect_av.c @@ -0,0 +1,232 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2010-20XX Telecom ParisTech + * All rights reserved + * + * This file is part of GPAC / AVI Recorder 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 + * 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/modules/term_ext.h> +#include <gpac/internal/terminal_dev.h> +#include <gpac/internal/compositor_dev.h> + +/*sample raw AVI writing*/ +#include <gpac/internal/avilib.h> + + +typedef struct +{ + GF_Terminal *term; + + Bool is_open; + GF_AudioListener audio_listen; + GF_VideoListener video_listen; + + avi_t *avi_out; + + char *frame; + u32 size; +} GF_AVRedirect; + +static void avr_on_audio_frame(void *udta, char *buffer, u32 buffer_size, u32 time, u32 delay_ms) +{ + GF_AVRedirect *avr = (GF_AVRedirect *)udta; + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[AVRedirect] Audio frame size %d - delay %d\n", buffer_size, delay_ms)); + AVI_write_audio(avr->avi_out, buffer, buffer_size); +} + +static void avr_on_audio_reconfig(void *udta, u32 samplerate, u32 bits_per_sample, u32 nb_channel, u32 channel_cfg) +{ + GF_AVRedirect *avr = (GF_AVRedirect *)udta; + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Audio reconfig sr %d bps %d nb_ch %d\n", samplerate, bits_per_sample, nb_channel)); + AVI_set_audio(avr->avi_out, nb_channel, samplerate, bits_per_sample, WAVE_FORMAT_PCM, 0); +} + +static void avr_on_video_frame(void *udta, u32 time) +{ + u32 i, j; + GF_Err e; + GF_VideoSurface fb; + GF_AVRedirect *avr = (GF_AVRedirect *)udta; + + e = gf_sc_get_screen_buffer(avr->term->compositor, &fb, 0); + if (e) { + 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 + (fb.height-i-1) * fb.pitch_y; + for (j=0; j<fb.width; j++) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + src+=4; + dst += 3; + } + } + + if (AVI_write_frame(avr->avi_out, avr->frame, avr->size, 1) <0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[AVRedirect] Error writing video frame\n")); + } + gf_sc_release_screen_buffer(avr->term->compositor, &fb); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MODULE, ("[AVRedirect] Writing video frame\n")); +} + +static void avr_on_video_reconfig(void *udta, u32 width, u32 height) +{ + char comp[5]; + GF_AVRedirect *avr = (GF_AVRedirect *)udta; + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Video reconfig width %d height %d\n", width, height)); + + + comp[0] = comp[1] = comp[2] = comp[3] = comp[4] = 0; + AVI_set_video(avr->avi_out, width, height, 30, comp); + + if (avr->frame) free(avr->frame); + avr->size = 3*width*height; + avr->frame = malloc(sizeof(char)*avr->size); +} + + +static void avr_open(GF_AVRedirect *avr) +{ + if (avr->is_open) return; + + avr->avi_out = AVI_open_output_file("dump.avi"); + if (!avr->avi_out) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MODULE, ("[AVRedirect] Error opening output AVI file\n")); + return; + } + gf_sc_add_audio_listener(avr->term->compositor, &avr->audio_listen); + gf_sc_add_video_listener(avr->term->compositor, &avr->video_listen); + avr->is_open = 1; + + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Open output AVI file %s\n", "dump.avi")); +} + +static void avr_close(GF_AVRedirect *avr) +{ + if (!avr->is_open) return; + gf_sc_remove_audio_listener(avr->term->compositor, &avr->audio_listen); + gf_sc_remove_video_listener(avr->term->compositor, &avr->video_listen); + avr->is_open = 0; + AVI_close(avr->avi_out); + GF_LOG(GF_LOG_INFO, GF_LOG_MODULE, ("[AVRedirect] Closing output AVI file\n")); +} + +static Bool avr_process(GF_TermExt *termext, u32 action, void *param) +{ + const char *opt; + GF_AVRedirect *avr = termext->udta; + + switch (action) { + case GF_TERM_EXT_START: + avr->term = (GF_Terminal *)param; + opt = gf_modules_get_option((GF_BaseInterface*)termext, "AVRedirect", "Enabled"); + if (!opt || strcmp(opt, "yes")) return 0; + termext->caps |= GF_TERM_EXTENSION_FILTER_EVENT; + + avr->audio_listen.udta = avr; + avr->audio_listen.on_audio_frame = avr_on_audio_frame; + avr->audio_listen.on_audio_reconfig = avr_on_audio_reconfig; + avr->video_listen.udta = avr; + avr->video_listen.on_video_frame = avr_on_video_frame; + avr->video_listen.on_video_reconfig = avr_on_video_reconfig; + return 1; + + case GF_TERM_EXT_STOP: + avr->term = NULL; + break; + + case GF_TERM_EXT_EVENT: + { + GF_Event *evt = (GF_Event *)param; + switch (evt->type) { + case GF_EVENT_CONNECT: + if (evt->connect.is_connected) { + avr_open(avr); + } else { + avr_close(avr); + } + break; + } + } + break; + + /*if not threaded, perform our tasks here*/ + case GF_TERM_EXT_PROCESS: + break; + } + return 0; +} + + +GF_TermExt *avr_new() +{ + GF_TermExt *dr; + GF_AVRedirect *uir; + dr = gf_malloc(sizeof(GF_TermExt)); + memset(dr, 0, sizeof(GF_TermExt)); + GF_REGISTER_MODULE_INTERFACE(dr, GF_TERM_EXT_INTERFACE, "GPAC Output Recorder", "gpac distribution"); + + GF_SAFEALLOC(uir, GF_AVRedirect); + dr->process = avr_process; + dr->udta = uir; + return dr; +} + + +void avr_delete(GF_BaseInterface *ifce) +{ + GF_TermExt *dr = (GF_TermExt *) ifce; + GF_AVRedirect *uir = dr->udta; + gf_free(uir); + gf_free(dr); +} + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_TERM_EXT_INTERFACE, + 0 + }; + return si; +} + +GF_EXPORT +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + if (InterfaceType == GF_TERM_EXT_INTERFACE) return (GF_BaseInterface *)avr_new(); + return NULL; +} + +GF_EXPORT +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { + case GF_TERM_EXT_INTERFACE: + avr_delete(ifce); + break; + } +} diff --git a/modules/rtp_in/Makefile b/modules/rtp_in/Makefile index b671ef2..6f0c1d2 100644 --- a/modules/rtp_in/Makefile +++ b/modules/rtp_in/Makefile @@ -22,20 +22,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_rtp_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols rtp_in.def +#LDFLAGS+=-export-symbols rtp_in.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) -L../../bin/gcc -lgpac $(EXTRALIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_rtp_in-static.so $(OBJS) -L../../bin/gcc -lgpac_static $(EXTRALIBS) +endif %.o: %.c diff --git a/modules/rtp_in/rtp_in.c b/modules/rtp_in/rtp_in.c index 1bd38f0..b972101 100644 --- a/modules/rtp_in/rtp_in.c +++ b/modules/rtp_in/rtp_in.c @@ -24,6 +24,8 @@ #include "rtp_in.h" +#ifndef GPAC_DISABLE_STREAMING + static void RT_LoadPrefs(GF_InputService *plug, RTPClient *rtp) { const char *sOpt; @@ -109,8 +111,8 @@ static void RP_cleanup(RTPClient *rtp) rtp->session_desc = NULL; if (rtp->sdp_temp) { - free(rtp->sdp_temp->remote_url); - free(rtp->sdp_temp); + gf_free(rtp->sdp_temp->remote_url); + gf_free(rtp->sdp_temp); } rtp->sdp_temp = NULL; } @@ -200,7 +202,7 @@ GF_Err RP_ConnectServiceEx(GF_InputService *plug, GF_ClientService *serv, const if (priv->dnload) gf_term_download_del(priv->dnload); priv->dnload = NULL; - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[RTP] Opening service %s\n", url)); + GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Opening service %s\n", url)); /*load preferences*/ RT_LoadPrefs(plug, priv); @@ -211,15 +213,15 @@ GF_Err RP_ConnectServiceEx(GF_InputService *plug, GF_ClientService *serv, const if (!skip_migration) { session_cache = (char *) gf_modules_get_option((GF_BaseInterface *) plug, "Streaming", "SessionMigrationFile"); if (session_cache && session_cache[0]) { - FILE *f = fopen(session_cache, "rb"); + FILE *f = gf_f64_open(session_cache, "rb"); if (f) { fclose(f); - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[RTP] Restarting RTSP session from %s\n", session_cache)); + GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Restarting RTSP session from %s\n", session_cache)); RP_FetchSDP(priv, (char *) session_cache, NULL, (char *) url); return GF_OK; } if (!strncmp(session_cache, "http://", 7)) { - GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[RTP] Restarting RTSP session from %s\n", session_cache)); + GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Restarting RTSP session from %s\n", session_cache)); RP_FetchSDP(priv, (char *) session_cache, NULL, (char *) url); return GF_OK; } @@ -235,7 +237,7 @@ GF_Err RP_ConnectServiceEx(GF_InputService *plug, GF_ClientService *serv, const /*rtsp and rtsp over udp*/ if (!strnicmp(url, "rtsp://", 7) || !strnicmp(url, "rtspu://", 8)) { - char *the_url = strdup(url); + char *the_url = gf_strdup(url); char *the_ext = strrchr(the_url, '#'); if (the_ext) { if (!stricmp(the_ext, "#audio")) priv->media_type = GF_MEDIA_OBJECT_AUDIO; @@ -243,7 +245,7 @@ GF_Err RP_ConnectServiceEx(GF_InputService *plug, GF_ClientService *serv, const the_ext[0] = 0; } sess = RP_NewSession(priv, (char *) the_url); - free(the_url); + gf_free(the_url); if (!sess) { gf_term_on_connect(serv, NULL, GF_NOT_SUPPORTED); } else { @@ -287,12 +289,11 @@ static GF_Err RP_CloseService(GF_InputService *plug) const char *opt; RTSPSession *sess; RTPClient *rtp = (RTPClient *)plug->priv; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[RTP] Closing service\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] Closing service\n")); RP_FlushCommands(rtp); - opt = gf_modules_get_option((GF_BaseInterface *) plug, "Network", "SessionMigration"); - if (opt && !strcmp(opt, "yes") ) { + if (rtp->session_migration) { opt = gf_modules_get_option((GF_BaseInterface *) plug, "Streaming", "SessionMigrationPause"); if (opt && !strcmp(opt, "yes")) { GF_NetworkCommand com; @@ -304,13 +305,14 @@ static GF_Err RP_CloseService(GF_InputService *plug) RP_UserCommand(sess, NULL, &com); } } - RP_SaveSessionState(rtp); } else { /*remove session state file*/ - if (rtp->session_state) { - gf_delete_file(rtp->session_state); - } + if (rtp->session_state_data) { + gf_free(rtp->session_state_data); + rtp->session_state_data = NULL; + } + /*send teardown on all sessions*/ i=0; while ((sess = (RTSPSession *)gf_list_enum(rtp->sessions, &i))) { @@ -332,7 +334,7 @@ static GF_Descriptor *RP_GetServiceDesc(GF_InputService *plug, u32 expect_type, GF_Descriptor *desc; RTPClient *priv = (RTPClient *)plug->priv; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[RTP] Fetching service descriptor\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] Fetching service descriptor\n")); if ((expect_type!=GF_MEDIA_OBJECT_UNDEF) && (expect_type!=GF_MEDIA_OBJECT_SCENE) && (expect_type!=GF_MEDIA_OBJECT_UPDATES)) { /*ignore the SDP IOD and regenerate one*/ if (priv->session_desc) gf_odf_desc_del(priv->session_desc); @@ -356,7 +358,7 @@ static GF_Err RP_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, con if (upstream) return GF_NOT_SUPPORTED; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[RTP] Connecting channel @%08x - %s\n", channel, url)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] Connecting channel @%08x - %s\n", channel, url)); ch = RP_FindChannel(priv, channel, 0, (char *) url, 0); if (ch && (ch->status != RTP_Disconnected) ) return GF_SERVICE_ERROR; @@ -387,7 +389,7 @@ static GF_Err RP_ConnectChannel(GF_InputService *plug, LPNETCHANNEL channel, con ) { GF_SAFEALLOC(ch, RTPStream); - ch->control = strdup(url); + ch->control = gf_strdup(url); ch->owner = priv; ch->channel = channel; ch->status = RTP_Connected; @@ -419,7 +421,7 @@ static GF_Err RP_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) RTPStream *ch; RTPClient *priv = (RTPClient *)plug->priv; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[RTP] Disconnecting channel @%08x\n", channel)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] Disconnecting channel @%08x\n", channel)); ch = RP_FindChannel(priv, channel, 0, NULL, 0); if (!ch) return GF_STREAM_NOT_FOUND; @@ -447,6 +449,16 @@ static GF_Err RP_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) } return GF_NOT_SUPPORTED; } + if (com->command_type==GF_NET_SERVICE_MIGRATION_INFO) { + RP_SaveSessionState(priv); + priv->session_migration=1; + if (priv->session_state_data) { + com->migrate.data = priv->session_state_data; + com->migrate.data_len = strlen(priv->session_state_data); + return GF_OK; + } + return GF_NOT_SUPPORTED; + } /*ignore commands other than channels one*/ if (!com->base.on_channel) { @@ -499,7 +511,7 @@ static GF_Err RP_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) return GF_OK; case GF_NET_CHAN_PLAY: - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[RTP] Processing play on channel @%08x - %s\n", ch, ch->rtsp ? "RTSP control" : "No control (RTP)" )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] Processing play on channel @%08x - %s\n", ch, ch->rtsp ? "RTSP control" : "No control (RTP)" )); /*is this RTSP or direct RTP?*/ ch->flags &= ~RTP_EOS; if (ch->rtsp) { @@ -517,9 +529,12 @@ static GF_Err RP_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) } else { ch->status = RTP_Running; if (ch->rtp_ch) { - ch->check_rtp_time = 1; + /*technically we shouldn't attempt to synchronize streams based on RTP, we should use RTCP/ However it + may happen that the RTCP traffic is absent ...*/ + ch->check_rtp_time = RTP_SET_TIME_RTP; + ch->rtcp_init = 0; gf_mx_p(priv->mx); - RP_InitStream(ch, 0); + RP_InitStream(ch, (ch->flags & RTP_CONNECTED) ? 1 : 0); gf_mx_v(priv->mx); gf_rtp_set_info_rtp(ch->rtp_ch, 0, 0, 0); } else { @@ -533,14 +548,14 @@ static GF_Err RP_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) case GF_NET_CHAN_STOP: /*is this RTSP or direct RTP?*/ if (ch->rtsp) { - const char *opt = gf_modules_get_option((GF_BaseInterface *) plug, "Network", "SessionMigration"); - if (opt && !strcmp(opt, "yes")) { - } else { + if (! ch->owner->session_migration) { RP_UserCommand(ch->rtsp, ch, com); } } else { ch->status = RTP_Connected; + ch->owner->last_ntp = 0; } + ch->rtcp_init = 0; return GF_OK; case GF_NET_CHAN_SET_SPEED: case GF_NET_CHAN_PAUSE: @@ -552,7 +567,7 @@ static GF_Err RP_ServiceCommand(GF_InputService *plug, GF_NetworkCommand *com) case GF_NET_CHAN_GET_DSI: if (ch->depacketizer && ch->depacketizer->sl_map.configSize) { com->get_dsi.dsi_len = ch->depacketizer->sl_map.configSize; - com->get_dsi.dsi = (char*)malloc(sizeof(char)*com->get_dsi.dsi_len); + com->get_dsi.dsi = (char*)gf_malloc(sizeof(char)*com->get_dsi.dsi_len); memcpy(com->get_dsi.dsi, ch->depacketizer->sl_map.config, sizeof(char)*com->get_dsi.dsi_len); } else { com->get_dsi.dsi = NULL; @@ -654,7 +669,23 @@ static Bool RP_CanHandleURLInService(GF_InputService *plug, const char *url) || strstr(url, "data:application/mpeg4-es-au;base64") ) return 1; - if (!RP_CanHandleURL(plug, url)) return 0; + if (url[0]=='#') { + Bool st_type = 0; + if (!stricmp(url, "#video")) st_type = GF_STREAM_VISUAL; + else if (!stricmp(url, "#audio")) st_type = GF_STREAM_AUDIO; + + if (st_type) { + u32 i=0; + RTPStream *st; + while ((st = (RTPStream *)gf_list_enum(priv->channels, &i))) { + if (st->depacketizer && (st->depacketizer->sl_map.StreamType==st_type)) + return 1; + } + } + return 0; + } else if (!RP_CanHandleURL(plug, url)) { + return 0; + } /*if this URL is part of a running session then ok*/ sess = RP_CheckSession(priv, (char *) url); if (sess) return 1; @@ -713,30 +744,38 @@ void RTP_Delete(GF_BaseInterface *bi) } assert(retry); - if (rtp->session_state) free(rtp->session_state); - if (rtp->remote_session_state) free(rtp->remote_session_state); - + if (rtp->session_state_data) gf_free(rtp->session_state_data); RP_cleanup(rtp); gf_th_del(rtp->th); gf_mx_del(rtp->mx); gf_list_del(rtp->sessions); gf_list_del(rtp->channels); - free(rtp); - free(bi); + gf_free(rtp); + gf_free(bi); } +#endif + + GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_NET_CLIENT_INTERFACE) return 1; - return 0; + static u32 si [] = { +#ifndef GPAC_DISABLE_STREAMING + GF_NET_CLIENT_INTERFACE, +#endif + 0 + }; + return si; } GF_EXPORT GF_BaseInterface *LoadInterface(u32 InterfaceType) { +#ifndef GPAC_DISABLE_STREAMING if (InterfaceType == GF_NET_CLIENT_INTERFACE) return (GF_BaseInterface *)RTP_Load(); +#endif return NULL; } @@ -744,8 +783,10 @@ GF_EXPORT void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_STREAMING case GF_NET_CLIENT_INTERFACE: RTP_Delete(ifce); break; +#endif } } diff --git a/modules/rtp_in/rtp_in.def b/modules/rtp_in/rtp_in.def deleted file mode 100644 index b838420..0000000 --- a/modules/rtp_in/rtp_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_rtp_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/rtp_in/rtp_in.h b/modules/rtp_in/rtp_in.h index 2a9bc93..1ce20ba 100644 --- a/modules/rtp_in/rtp_in.h +++ b/modules/rtp_in/rtp_in.h @@ -25,11 +25,13 @@ #ifndef RTP_IN_H #define RTP_IN_H +/*module interface*/ +#include <gpac/modules/service.h> +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/thread.h> #include <gpac/constants.h> #include <gpac/base_coding.h> -/*module interface*/ -#include <gpac/modules/service.h> /*IETF lib*/ #include <gpac/ietf.h> @@ -37,7 +39,6 @@ #define RTP_BUFFER_SIZE 0x100000ul #define RTSP_BUFFER_SIZE 5000 #define RTSP_TCP_BUFFER_SIZE 0x100000ul -#define RTSP_CLIENTNAME "GPAC " GPAC_VERSION " RTSP Client" #define RTSP_LANGUAGE "English" @@ -82,12 +83,15 @@ typedef struct /*for single-object control*/ u32 media_type; - /*location of the session state (SDP file)*/ - char *session_state; - char *remote_session_state; - char *tmp_buf; + /*session state data, formatyed as "data:application/sdp;SDPDATA"*/ + char *session_state_data; + /*if set ANNOUNCE (sent by server) will be handled*/ // Bool handle_announce; + + Double last_ntp; + + Bool session_migration; } RTPClient; enum @@ -180,8 +184,19 @@ enum RTP_CONNECTED = (1<<5), /*EOS signaled (RTCP or range-based)*/ RTP_EOS = (1<<6), + + /*RTP stream is using mobileIP - this will disable RTP over RTSP*/ + RTP_MOBILEIP = (1<<7), + }; +enum +{ + RTP_SET_TIME_NONE = 0, + RTP_SET_TIME_RTP, + RTP_SET_TIME_RTP_SEEK, + }; + /*rtp channel*/ typedef struct { @@ -206,12 +221,13 @@ typedef struct LPNETCHANNEL channel; u32 status; - u32 ES_ID; + u32 ES_ID, OD_ID; char *control; /*rtp receive buffer*/ char buffer[RTP_BUFFER_SIZE]; - /*set at seek stages to resync app NPT to RTP time*/ + /*set at play/seek stages to sync app NPT to RTP time (RTSP) or NTP to RTP (RTCP) + */ u32 check_rtp_time; /*can we control the stream ?*/ @@ -219,6 +235,8 @@ typedef struct /*current start time in npt (for pause/resume)*/ Double current_start; + Bool paused; + Bool rtcp_init; /*UDP time-out detection*/ u32 last_udp_time; /*RTP stats*/ @@ -333,6 +351,9 @@ typedef struct _sdp_fetch void RP_SaveSessionState(RTPClient *rtp); + +#endif /*GPAC_DISABLE_STREAMING*/ + #endif diff --git a/modules/rtp_in/rtp_session.c b/modules/rtp_in/rtp_session.c index 1fa3a8e..f688019 100644 --- a/modules/rtp_in/rtp_session.c +++ b/modules/rtp_in/rtp_session.c @@ -24,6 +24,9 @@ #include "rtp_in.h" +#ifndef GPAC_DISABLE_STREAMING + + void RP_SendFailure(RTSPSession *sess, GF_RTSPCommand *com, GF_Err e) { char sMsg[1000]; @@ -135,7 +138,8 @@ void RP_ProcessCommands(RTSPSession *sess) return; } /*process*/ - com->User_Agent = RTSP_CLIENTNAME; + com->User_Agent = (char*)gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(sess->owner->service), "Downloader", "UserAgent"); + if (!com->User_Agent) com->User_Agent = "GPAC " GPAC_VERSION " RTSP Client"; com->Accept_Language = RTSP_LANGUAGE; /*if no session assigned and a session ID is valid, use it*/ if (sess->session_id && !com->Session) @@ -230,7 +234,7 @@ RTSPSession *RP_NewSession(RTPClient *rtp, char *session_control) if (!session_control) return NULL; /*little fix: some servers don't understand DESCRIBE URL/trackID=, so remove the trackID...*/ - szCtrl = strdup(session_control); + szCtrl = gf_strdup(session_control); szExt = szCtrl ? strrchr(szCtrl, '.') : NULL; if (szExt) { szExt = strchr(szExt, '/'); @@ -240,7 +244,7 @@ RTSPSession *RP_NewSession(RTPClient *rtp, char *session_control) } rtsp = gf_rtsp_session_new(szCtrl, rtp->default_port); - free(szCtrl); + gf_free(szCtrl); if (!rtsp) return NULL; @@ -316,8 +320,8 @@ GF_Err RP_AddStream(RTPClient *rtp, RTPStream *stream, char *session_control) ctrl = strstr(stream->control, service_name); if (ctrl && (strlen(ctrl) != strlen(service_name)) ) { ctrl += strlen(service_name) + 1; - service_name = strdup(ctrl); - free(stream->control); + service_name = gf_strdup(ctrl); + gf_free(stream->control); stream->control = service_name; } } @@ -328,9 +332,10 @@ GF_Err RP_AddStream(RTPClient *rtp, RTPStream *stream, char *session_control) } if (in_session) { - in_session->flags |= RTSP_AGG_CONTROL; + if (has_aggregated_control) + in_session->flags |= RTSP_AGG_CONTROL; } else if (stream->control) { - free(stream->control); + gf_free(stream->control); stream->control = NULL; } stream->rtsp = in_session; @@ -379,9 +384,10 @@ void RP_DelSession(RTSPSession *sess) gf_list_del(sess->rtsp_commands); gf_rtsp_response_del(sess->rtsp_rsp); gf_rtsp_session_del(sess->session); - if (sess->control) free(sess->control); - if (sess->session_id) free(sess->session_id); - free(sess); + if (sess->control) gf_free(sess->control); + if (sess->session_id) gf_free(sess->session_id); + gf_free(sess); } +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/modules/rtp_in/rtp_signaling.c b/modules/rtp_in/rtp_signaling.c index 84cf824..e05e3d0 100644 --- a/modules/rtp_in/rtp_signaling.c +++ b/modules/rtp_in/rtp_signaling.c @@ -24,6 +24,8 @@ #include "rtp_in.h" +#ifndef GPAC_DISABLE_STREAMING + Bool channel_is_valid(RTPClient *rtp, RTPStream *ch) { @@ -88,7 +90,7 @@ void RP_Setup(RTPStream *ch) GF_RTSPTransport *trans; com = gf_rtsp_command_new(); - com->method = strdup(GF_RTSP_SETUP); + com->method = gf_strdup(GF_RTSP_SETUP); def_first_port = 0; opt = gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(ch->owner->service), "Streaming", "ForceFirstPort"); @@ -114,11 +116,11 @@ void RP_Setup(RTPStream *ch) opt = gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(ch->owner->service), "Streaming", "ForceMulticastIP"); if (opt) { trans->IsUnicast = 0; - trans->destination = strdup(opt); + trans->destination = gf_strdup(opt); opt = gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(ch->owner->service), "Streaming", "ForceMulticastTTL"); trans->TTL = opt ? atoi(opt) : 127; - if (trans->Profile) free(trans->Profile); - trans->Profile = strdup(GF_RTSP_PROFILE_RTP_AVP); + if (trans->Profile) gf_free(trans->Profile); + trans->Profile = gf_strdup(GF_RTSP_PROFILE_RTP_AVP); if (!(ch->rtsp->flags & RTSP_DSS_SERVER) ) { trans->port_first = trans->client_port_first; trans->port_last = trans->client_port_last; @@ -130,13 +132,13 @@ void RP_Setup(RTPStream *ch) } /*2: RTP over RTSP forced*/ else if (ch->rtsp->flags & RTSP_FORCE_INTER) { - if (trans->Profile) free(trans->Profile); - trans->Profile = strdup(GF_RTSP_PROFILE_RTP_AVP_TCP); + if (trans->Profile) gf_free(trans->Profile); + trans->Profile = gf_strdup(GF_RTSP_PROFILE_RTP_AVP_TCP); gf_rtp_setup_transport(ch->rtp_ch, trans, NULL); } if (trans->source) { - free(trans->source); + gf_free(trans->source); trans->source = NULL; } @@ -144,7 +146,7 @@ void RP_Setup(RTPStream *ch) through RTP/AVP/TCP profile so it's OK)*/ trans->IsInterleaved = 0; gf_list_add(com->Transports, trans); - if (strlen(ch->control)) com->ControlString = strdup(ch->control); + if (strlen(ch->control)) com->ControlString = gf_strdup(ch->control); com->user_data = ch; ch->status = RTP_WaitingForAck; @@ -211,7 +213,7 @@ void RP_ProcessSetup(RTSPSession *sess, GF_RTSPCommand *com, GF_Err e) e = GF_SERVICE_ERROR; goto exit; } - if (!sess->session_id) sess->session_id = strdup(sess->rtsp_rsp->Session); + if (!sess->session_id) sess->session_id = gf_strdup(sess->rtsp_rsp->Session); assert(!ch->session_id); /*transport setup: break at the first correct transport */ @@ -270,8 +272,8 @@ Bool RP_PreprocessDescribe(RTSPSession *sess, GF_RTSPCommand *com) /*channel has been described already, skip describe and send setup directly*/ RP_SetupChannel(ch, ch_desc); - if (ch_desc->esd_url) free(ch_desc->esd_url); - free(ch_desc); + if (ch_desc->esd_url) gf_free(ch_desc->esd_url); + gf_free(ch_desc); return 0; } @@ -330,7 +332,7 @@ exit: gf_term_on_connect(sess->owner->service, ch_desc->channel, e); } } - if (ch_desc) free(ch_desc); + if (ch_desc) gf_free(ch_desc); return GF_OK; } @@ -356,13 +358,13 @@ void RP_Describe(RTSPSession *sess, char *esd_url, LPNETCHANNEL channel) default: break; } - ch_desc = (ChannelDescribe *)malloc(sizeof(ChannelDescribe)); - ch_desc->esd_url = esd_url ? strdup(esd_url) : NULL; + ch_desc = (ChannelDescribe *)gf_malloc(sizeof(ChannelDescribe)); + ch_desc->esd_url = esd_url ? gf_strdup(esd_url) : NULL; ch_desc->channel = channel; RP_SetupChannel(ch, ch_desc); - if (esd_url) free(ch_desc->esd_url); - free(ch_desc); + if (esd_url) gf_free(ch_desc->esd_url); + gf_free(ch_desc); return; } /*channel not found, send describe on service*/ @@ -370,21 +372,21 @@ void RP_Describe(RTSPSession *sess, char *esd_url, LPNETCHANNEL channel) /*send describe*/ com = gf_rtsp_command_new(); - com->method = strdup(GF_RTSP_DESCRIBE); + com->method = gf_strdup(GF_RTSP_DESCRIBE); if (channel || esd_url) { - com->Accept = strdup("application/sdp"); - com->ControlString = esd_url ? strdup(esd_url) : NULL; + com->Accept = gf_strdup("application/sdp"); + com->ControlString = esd_url ? gf_strdup(esd_url) : NULL; - ch_desc = (ChannelDescribe *)malloc(sizeof(ChannelDescribe)); - ch_desc->esd_url = esd_url ? strdup(esd_url) : NULL; + ch_desc = (ChannelDescribe *)gf_malloc(sizeof(ChannelDescribe)); + ch_desc->esd_url = esd_url ? gf_strdup(esd_url) : NULL; ch_desc->channel = channel; com->user_data = ch_desc; } else { //always accept both SDP and IOD - com->Accept = strdup("application/sdp, application/mpeg4-iod"); -// com->Accept = strdup("application/sdp"); + com->Accept = gf_strdup("application/sdp, application/mpeg4-iod"); +// com->Accept = gf_strdup("application/sdp"); } /*need better tuning ...*/ @@ -394,6 +396,21 @@ void RP_Describe(RTSPSession *sess, char *esd_url, LPNETCHANNEL channel) RP_QueueCommand(sess, NULL, com, 0); } + +static void SkipCommandOnSession(RTPStream *ch) +{ + u32 i; + RTPStream *a_ch; + if (!ch || (ch->flags & RTP_SKIP_NEXT_COM) || !(ch->rtsp->flags & RTSP_AGG_CONTROL) ) return; + i=0; + while ((a_ch = (RTPStream *)gf_list_enum(ch->owner->channels, &i))) { + if ((ch == a_ch) || (a_ch->rtsp != ch->rtsp) ) continue; + if (a_ch->status>=RTP_Connected) + a_ch->flags |= RTP_SKIP_NEXT_COM; + } +} + + /* channel control functions */ @@ -411,7 +428,7 @@ Bool RP_PreprocessUserCom(RTSPSession *sess, GF_RTSPCommand *com) ch = ch_ctrl->ch; if (!ch->channel || !channel_is_valid(sess->owner, ch)) { - free(ch_ctrl); + gf_free(ch_ctrl); com->user_data = NULL; return 0; } @@ -428,12 +445,15 @@ Bool RP_PreprocessUserCom(RTSPSession *sess, GF_RTSPCommand *com) } /*this is a stop, no need for SessionID just skip*/ skip_it = 1; + } else { + SkipCommandOnSession(ch); } + /*check if aggregation discards this command*/ if (skip_it || ( (sess->flags & RTSP_AGG_CONTROL) && (ch->flags & RTP_SKIP_NEXT_COM) )) { ch->flags &= ~RTP_SKIP_NEXT_COM; gf_term_on_command(sess->owner->service, &ch_ctrl->com, GF_OK); - free(ch_ctrl); + gf_free(ch_ctrl); com->user_data = NULL; return 0; } @@ -442,26 +462,13 @@ Bool RP_PreprocessUserCom(RTSPSession *sess, GF_RTSPCommand *com) err_exit: gf_rtsp_reset_aggregation(ch->rtsp->session); ch->status = RTP_Disconnected; - ch->check_rtp_time = 0; + ch->check_rtp_time = RTP_SET_TIME_NONE; gf_term_on_command(sess->owner->service, &ch_ctrl->com, e); - free(ch_ctrl); + gf_free(ch_ctrl); com->user_data = NULL; return 0; } -static void SkipCommandOnSession(RTPStream *ch) -{ - u32 i; - RTPStream *a_ch; - if (!ch || (ch->flags & RTP_SKIP_NEXT_COM) || !(ch->rtsp->flags & RTSP_AGG_CONTROL) ) return; - i=0; - while ((a_ch = (RTPStream *)gf_list_enum(ch->owner->channels, &i))) { - if ((ch == a_ch) || (a_ch->rtsp != ch->rtsp) ) continue; - a_ch->flags |= RTP_SKIP_NEXT_COM; - } -} - - void RP_ProcessUserCommand(RTSPSession *sess, GF_RTSPCommand *com, GF_Err e) { ChannelControl *ch_ctrl; @@ -474,7 +481,7 @@ void RP_ProcessUserCommand(RTSPSession *sess, GF_RTSPCommand *com, GF_Err e) ch = ch_ctrl->ch; if (ch) { if (!ch->channel || !channel_is_valid(sess->owner, ch)) { - free(ch_ctrl); + gf_free(ch_ctrl); com->user_data = NULL; return; } @@ -535,18 +542,18 @@ process_reply: if (!agg_ch || (agg_ch->rtsp != sess) ) continue; /*channel is already playing*/ if (agg_ch->status == RTP_Running) { - // gf_rtp_set_info_rtp(agg_ch->rtp_ch, info->seq, info->rtp_time, info->ssrc); - // agg_ch->check_rtp_time = 1; + gf_rtp_set_info_rtp(agg_ch->rtp_ch, info->seq, info->rtp_time, info->ssrc); + agg_ch->check_rtp_time = RTP_SET_TIME_RTP; continue; } /*if play/seeking we must send update RTP/NPT link*/ if (ch_ctrl->com.command_type != GF_NET_CHAN_RESUME) { - agg_ch->check_rtp_time = 1; + agg_ch->check_rtp_time = RTP_SET_TIME_RTP; } /*this is used to discard RTP packets re-sent on resume*/ else { - agg_ch->check_rtp_time = 2; + agg_ch->check_rtp_time = RTP_SET_TIME_RTP_SEEK; } /* reset the buffers */ RP_InitStream(agg_ch, 1); @@ -568,7 +575,7 @@ process_reply: /*no rtp info (just in case), no time mapped - set to 0 and specify we're not interactive*/ if (!i) { ch->current_start = 0.0; - ch->check_rtp_time = 1; + ch->check_rtp_time = RTP_SET_TIME_RTP; RP_InitStream(ch, 1); ch->status = RTP_Running; if (gf_rtp_is_interleaved(ch->rtp_ch)) { @@ -585,7 +592,7 @@ process_reply: } } else if (ch_ctrl->com.command_type == GF_NET_CHAN_STOP) { } - free(ch_ctrl); + gf_free(ch_ctrl); com->user_data = NULL; return; @@ -595,9 +602,9 @@ err_exit: if (ch) { ch->status = RTP_Disconnected; gf_rtsp_reset_aggregation(ch->rtsp->session); - ch->check_rtp_time = 0; + ch->check_rtp_time = RTP_SET_TIME_NONE; } - free(ch_ctrl); + gf_free(ch_ctrl); com->user_data = NULL; } @@ -625,7 +632,7 @@ static void RP_FlushAndTearDown(RTSPSession *sess) /*no private stack on teardown - shutdown now*/ com = gf_rtsp_command_new(); - com->method = strdup(GF_RTSP_TEARDOWN); + com->method = gf_strdup(GF_RTSP_TEARDOWN); RP_QueueCommand(sess, NULL, com, 1); } #endif @@ -679,7 +686,9 @@ void RP_UserCommand(RTSPSession *sess, RTPStream *ch, GF_NetworkCommand *command range->start = ch->range_start; range->end = ch->range_end; - com->method = strdup(GF_RTSP_PLAY); + com->method = gf_strdup(GF_RTSP_PLAY); + + ch->paused=0; /*specify pause range on resume - this is not mandatory but most servers need it*/ if (command->command_type==GF_NET_CHAN_RESUME) { @@ -721,19 +730,19 @@ void RP_UserCommand(RTSPSession *sess, RTPStream *ch, GF_NetworkCommand *command if (sess->flags & RTSP_AGG_CONTROL) SkipCommandOnSession(ch); else if (strlen(ch->control)) - com->ControlString = strdup(ch->control); + com->ControlString = gf_strdup(ch->control); if (RP_SessionActive(ch)) { - if (!com->ControlString && ch->control) com->ControlString = strdup(ch->control); + if (!com->ControlString && ch->control) com->ControlString = gf_strdup(ch->control); } else { if (com->ControlString) { - free(com->ControlString); + gf_free(com->ControlString); com->ControlString=NULL; } } } else if (command->command_type==GF_NET_CHAN_PAUSE) { - com->method = strdup(GF_RTSP_PAUSE); + com->method = gf_strdup(GF_RTSP_PAUSE); if (ch) { range = gf_rtsp_range_new(); /*update current time*/ @@ -742,6 +751,13 @@ void RP_UserCommand(RTSPSession *sess, RTPStream *ch, GF_NetworkCommand *command range->start = ch->current_start; range->end = -1.0; com->Range = range; + + if (sess->flags & RTSP_AGG_CONTROL) + SkipCommandOnSession(ch); + else if (strlen(ch->control)) + com->ControlString = gf_strdup(ch->control); + + ch->paused=1; } } else if (command->command_type==GF_NET_CHAN_STOP) { @@ -762,13 +778,17 @@ void RP_UserCommand(RTSPSession *sess, RTPStream *ch, GF_NetworkCommand *command } /* otherwise send a PAUSE on the stream */ else { + if (ch->paused) { + if (com) gf_rtsp_command_del(com); + return; + } range = gf_rtsp_range_new(); range->start = 0; range->end = -1; - com->method = strdup(GF_RTSP_PAUSE); + com->method = gf_strdup(GF_RTSP_PAUSE); com->Range = range; /*only pause the specified stream*/ - if (ch->control) com->ControlString = strdup(ch->control); + if (ch->control) com->ControlString = gf_strdup(ch->control); } } else { gf_term_on_command(sess->owner->service, command, GF_NOT_SUPPORTED); @@ -776,7 +796,7 @@ void RP_UserCommand(RTSPSession *sess, RTPStream *ch, GF_NetworkCommand *command return; } - ch_ctrl = (ChannelControl *)malloc(sizeof(ChannelControl)); + ch_ctrl = (ChannelControl *)gf_malloc(sizeof(ChannelControl)); ch_ctrl->ch = ch; memcpy(&ch_ctrl->com, command, sizeof(GF_NetworkCommand)); com->user_data = ch_ctrl; @@ -793,10 +813,10 @@ void RP_ProcessTeardown(RTSPSession *sess, GF_RTSPCommand *com, GF_Err e) { RTPStream *ch = (RTPStream *)com->user_data; if (ch) { - if (ch->session_id) free(ch->session_id); + if (ch->session_id) gf_free(ch->session_id); ch->session_id = NULL; } else { - if (sess->session_id) free(sess->session_id); + if (sess->session_id) gf_free(sess->session_id); sess->session_id = NULL; } } @@ -804,20 +824,21 @@ void RP_ProcessTeardown(RTSPSession *sess, GF_RTSPCommand *com, GF_Err e) void RP_Teardown(RTSPSession *sess, RTPStream *ch) { GF_RTSPCommand *com; - + if (sess->owner->session_migration) return; /*we need a session id*/ if (!sess->session_id) return; /*ignore teardown on channels*/ if ((sess->flags & RTSP_AGG_CONTROL) && ch) return; com = gf_rtsp_command_new(); - com->method = strdup(GF_RTSP_TEARDOWN); + com->method = gf_strdup(GF_RTSP_TEARDOWN); /*this only works in RTSP2*/ if (ch && ch->control) { - com->ControlString = strdup(ch->control); + com->ControlString = gf_strdup(ch->control); com->user_data = ch; } RP_QueueCommand(sess, ch, com, 1); } +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/modules/rtp_in/rtp_stream.c b/modules/rtp_in/rtp_stream.c index f22cfc4..1e053f9 100644 --- a/modules/rtp_in/rtp_stream.c +++ b/modules/rtp_in/rtp_stream.c @@ -25,6 +25,7 @@ #include "rtp_in.h" #include <gpac/internal/ietf_dev.h> +#ifndef GPAC_DISABLE_STREAMING void RP_ConfirmChannelConnect(RTPStream *ch, GF_Err e) { @@ -76,8 +77,11 @@ GF_Err RP_InitStream(RTPStream *ch, Bool ResetOnly) ip_ifce = gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(ch->owner->service), "Network", "DefaultMCastInterface"); if (!ip_ifce) { const char *mob_on = gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(ch->owner->service), "Network", "MobileIPEnabled"); - if (mob_on && !strcmp(mob_on, "yes")) + if (mob_on && !strcmp(mob_on, "yes")) { ip_ifce = gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(ch->owner->service), "Network", "MobileIP"); + ch->flags |= RTP_MOBILEIP; + } + } } return gf_rtp_initialize(ch->rtp_ch, RTP_BUFFER_SIZE, 0, 0, reorder_size, 200, (char *)ip_ifce); @@ -90,7 +94,7 @@ GF_Err RP_InitStream(RTPStream *ch, Bool ResetOnly) void RP_DeleteStream(RTPStream *ch) { if (ch->rtsp) { - if ((ch->status == RTP_Running)) { + if (ch->status == RTP_Running) { RP_Teardown(ch->rtsp, ch); ch->status = RTP_Disconnected; } @@ -101,15 +105,18 @@ void RP_DeleteStream(RTPStream *ch) if (ch->depacketizer) gf_rtp_depacketizer_del(ch->depacketizer); if (ch->rtp_ch) gf_rtp_del(ch->rtp_ch); - if (ch->control) free(ch->control); - if (ch->session_id) free(ch->session_id); - free(ch); + if (ch->control) gf_free(ch->control); + if (ch->session_id) gf_free(ch->session_id); + gf_free(ch); } static void rtp_sl_packet_cbk(void *udta, char *payload, u32 size, GF_SLHeader *hdr, GF_Err e) { RTPStream *ch = (RTPStream *)udta; + + if (ch->rtp_ch->packet_loss) e = GF_REMOTE_SERVICE_ERROR; + if (ch->owner->first_packet_drop && (hdr->packetSequenceNumber >= ch->owner->first_packet_drop) ) { if ( (hdr->packetSequenceNumber - ch->owner->first_packet_drop) % ch->owner->frequency_drop) gf_term_on_sl_packet(ch->owner->service, ch->channel, payload, size, hdr, e); @@ -124,12 +131,13 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP GF_RTSPRange *range; RTPStream *tmp; GF_RTPMap *map; - u32 i, ESID, ssrc, rtp_seq, rtp_time; + u32 i, ESID, ODID, ssrc, rtp_seq, rtp_time; Bool force_bcast = 0; Double Start, End; Float CurrentTime; u32 s_port_first, s_port_last; GF_X_Attribute *att; + Bool is_migration = 0; char *ctrl; GF_SDPConnection *conn; GF_RTSPTransport trans; @@ -138,6 +146,7 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP Start = 0.0; End = -1.0; CurrentTime = 0.0f; + ODID = 0; ESID = 0; ctrl = NULL; range = NULL; @@ -148,10 +157,15 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP if (!stricmp(att->Name, "control")) ctrl = att->Value; else if (!stricmp(att->Name, "gpac-broadcast")) force_bcast = 1; else if (!stricmp(att->Name, "mpeg4-esid") && att->Value) ESID = atoi(att->Value); + else if (!stricmp(att->Name, "mpeg4-odid") && att->Value) ODID = atoi(att->Value); else if (!stricmp(att->Name, "range") && !range) range = gf_rtsp_range_parse(att->Value); else if (!stricmp(att->Name, "x-stream-state") ) { sscanf(att->Value, "server-port=%d-%d;ssrc=%X;npt=%g;seq=%d;rtptime=%d", &s_port_first, &s_port_last, &ssrc, &CurrentTime, &rtp_seq, &rtp_time); + is_migration = 1; + } + else if (!stricmp(att->Name, "x-server-port") ) { + sscanf(att->Value, "%d-%d", &s_port_first, &s_port_last); } } @@ -163,6 +177,8 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP /*check connection*/ conn = sdp->c_connection; + if (conn && (!conn->host || !strcmp(conn->host, "0.0.0.0"))) conn = NULL; + if (!conn) conn = (GF_SDPConnection*)gf_list_get(media->Connections, 0); if (!conn) { @@ -200,8 +216,9 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP /*create an RTP channel*/ tmp->rtp_ch = gf_rtp_new(); - if (ctrl) tmp->control = strdup(ctrl); + if (ctrl) tmp->control = gf_strdup(ctrl); tmp->ES_ID = ESID; + tmp->OD_ID = ODID; memset(&trans, 0, sizeof(GF_RTSPTransport)); trans.Profile = media->Profile; @@ -214,8 +231,8 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP } else { trans.client_port_first = media->PortNumber; trans.client_port_last = media->PortNumber + 1; - trans.port_first = s_port_first; - trans.port_last = s_port_last; + trans.port_first = s_port_first ? s_port_first : trans.client_port_first; + trans.port_last = s_port_last ? s_port_last : trans.client_port_last; } if (gf_rtp_setup_transport(tmp->rtp_ch, &trans, NULL) != GF_OK) { @@ -246,9 +263,9 @@ RTPStream *RP_NewStream(RTPClient *rtp, GF_SDPMedia *media, GF_SDPInfo *sdp, RTP if (force_bcast) tmp->flags |= RTP_FORCE_BROADCAST; - if (s_port_first) { + if (is_migration) { tmp->current_start = (Double) CurrentTime; - tmp->check_rtp_time = 1; + tmp->check_rtp_time = RTP_SET_TIME_RTP; gf_rtp_set_info_rtp(tmp->rtp_ch, rtp_seq, rtp_time, ssrc); tmp->status = RTP_SessionResume; } @@ -293,7 +310,7 @@ void RP_ProcessRTP(RTPStream *ch, char *pck, u32 size) ch_time = gf_rtp_get_current_time(ch->rtp_ch); /*this is the first packet on the channel (no PAUSE)*/ - if (ch->check_rtp_time == 1) { + if (ch->check_rtp_time == RTP_SET_TIME_RTP) { /*Note: in a SEEK with RTSP, the rtp-info time given by the server is the rtp time of the desired range. But the server may (and should) send from the previous I frame on video, so the time of the first rtp packet after @@ -304,15 +321,23 @@ void RP_ProcessRTP(RTPStream *ch, char *pck, u32 size) memset(&com, 0, sizeof(com)); com.command_type = GF_NET_CHAN_MAP_TIME; com.base.on_channel = ch->channel; - com.map_time.media_time = ch->current_start + ch_time; + if (ch->rtsp) { + com.map_time.media_time = ch->current_start + ch_time; + } else { + com.map_time.media_time = 0; + } + com.map_time.timestamp = hdr.TimeStamp; - com.map_time.reset_buffers = 1; + com.map_time.reset_buffers = 0; gf_term_on_command(ch->owner->service, &com, GF_OK); - GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Mapping RTP Time seq %d TS %d - rtp info seq %d TS %d\n", - hdr.SequenceNumber, hdr.TimeStamp, ch->rtp_ch->rtp_first_SN, ch->rtp_ch->rtp_time + GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Mapping RTP Time seq %d TS %d Media Time %g - rtp info seq %d TS %d\n", + hdr.SequenceNumber, hdr.TimeStamp, com.map_time.media_time, ch->rtp_ch->rtp_first_SN, ch->rtp_ch->rtp_time )); + /*skip RTCP clock init when RTSP is used*/ + if (ch->rtsp) ch->rtcp_init = 1; + // if (ch->depacketizer->payt==GF_RTP_PAYT_H264_AVC) ch->depacketizer->flags |= GF_RTP_AVC_WAIT_RAP; } /*this is RESUME on channel, filter packet based on time (darwin seems to send @@ -322,7 +347,7 @@ void RP_ProcessRTP(RTPStream *ch, char *pck, u32 size) else if (ch_time <= 0.021) { return; } - ch->check_rtp_time = 0; + ch->check_rtp_time = RTP_SET_TIME_NONE; } gf_rtp_depacketizer_process(ch->depacketizer, &hdr, pck + PayloadStart, size - PayloadStart); @@ -342,14 +367,45 @@ void RP_ProcessRTP(RTPStream *ch, char *pck, u32 size) void RP_ProcessRTCP(RTPStream *ch, char *pck, u32 size) { + Bool has_sr; GF_Err e; if (ch->status == RTP_Connected) return; ch->rtcp_bytes += size; - e = gf_rtp_decode_rtcp(ch->rtp_ch, pck, size); - + e = gf_rtp_decode_rtcp(ch->rtp_ch, pck, size, &has_sr); + if (e<0) return; + + /*update sync if on pure RTP*/ + if (!ch->rtcp_init && has_sr) { + GF_NetworkCommand com; + memset(&com, 0, sizeof(com)); + com.command_type = GF_NET_CHAN_MAP_TIME; + com.base.on_channel = ch->channel; + com.map_time.media_time = ch->rtp_ch->last_SR_NTP_sec; + com.map_time.media_time += ((Double)ch->rtp_ch->last_SR_NTP_frac)/0xFFFFFFFF; + + if (!ch->owner->last_ntp) { + ch->owner->last_ntp = com.map_time.media_time; + } + if (com.map_time.media_time >= ch->owner->last_ntp) { + com.map_time.media_time -= ch->owner->last_ntp; + } else { + com.map_time.media_time = 0; + } + com.map_time.timestamp = ch->rtp_ch->last_SR_rtp_time; + com.map_time.reset_buffers = 0; + ch->rtcp_init = 1; + ch->check_rtp_time = RTP_SET_TIME_NONE; + gf_term_on_command(ch->owner->service, &com, GF_OK); + + GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTCP] Using Sender Report to map RTP Time TS %d Media Time %g\n", + com.map_time.timestamp, com.map_time.media_time + )); + + } + if (e == GF_EOS) { ch->flags |= RTP_EOS; ch->stat_stop_time = gf_sys_clock(); @@ -413,7 +469,7 @@ void RP_ReadStream(RTPStream *ch) if (ch->owner->udp_time_out) { if (!ch->last_udp_time) { ch->last_udp_time = gf_sys_clock(); - } else { + } else if (ch->rtp_ch->net_info.IsUnicast && !(ch->flags & RTP_MOBILEIP) ){ u32 diff = gf_sys_clock() - ch->last_udp_time; if (diff >= ch->owner->udp_time_out) { char szMessage[1024]; @@ -425,3 +481,4 @@ void RP_ReadStream(RTPStream *ch) } } +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/modules/rtp_in/sdp_fetch.c b/modules/rtp_in/sdp_fetch.c index 455f3e9..97d8cd4 100644 --- a/modules/rtp_in/sdp_fetch.c +++ b/modules/rtp_in/sdp_fetch.c @@ -24,6 +24,8 @@ #include "rtp_in.h" +#ifndef GPAC_DISABLE_STREAMING + void RP_SDPFromData(RTPClient *rtp, char *s_url, RTPStream *stream) { @@ -63,12 +65,12 @@ void RP_SDPFromFile(RTPClient *rtp, char *file_name, RTPStream *stream) fseek(_sdp, 0, SEEK_END); sdp_size = ftell(_sdp); fseek(_sdp, 0, SEEK_SET); - sdp_buf = (char*)malloc(sdp_size); + sdp_buf = (char*)gf_malloc(sdp_size); fread(sdp_buf, sdp_size, 1, _sdp); RP_LoadSDP(rtp, sdp_buf, sdp_size, stream); fclose(_sdp); - free(sdp_buf); + gf_free(sdp_buf); } void SDP_NetIO(void *cbk, GF_NETIO_Parameter *param) @@ -109,9 +111,9 @@ void SDP_NetIO(void *cbk, GF_NETIO_Parameter *param) } else { e = GF_OK; RP_SDPFromFile(rtp, (char *) szFile, sdp->chan); - free(sdp->remote_url); - if (sdp->original_url) free(sdp->original_url); - free(sdp); + gf_free(sdp->remote_url); + if (sdp->original_url) gf_free(sdp->original_url); + gf_free(sdp); rtp->sdp_temp = NULL; return; } @@ -122,12 +124,12 @@ void SDP_NetIO(void *cbk, GF_NETIO_Parameter *param) if (sdp->original_url) { char *url = sdp->original_url; - free(sdp->remote_url); - free(sdp); + gf_free(sdp->remote_url); + gf_free(sdp); rtp->sdp_temp = NULL; gf_term_on_message(rtp->service, e, "Error fetching session state - restarting"); RP_ConnectServiceEx(gf_term_get_service_interface(rtp->service), rtp->service, url, 1); - free(url); + gf_free(url); return; } @@ -138,9 +140,9 @@ void SDP_NetIO(void *cbk, GF_NETIO_Parameter *param) gf_term_on_connect(rtp->service, NULL, e); rtp->sdp_temp = NULL; } - free(sdp->remote_url); - if (sdp->original_url) free(sdp->original_url); - free(sdp); + gf_free(sdp->remote_url); + if (sdp->original_url) gf_free(sdp->original_url); + gf_free(sdp); rtp->sdp_temp = NULL; } @@ -158,13 +160,13 @@ void RP_FetchSDP(RTPClient *rtp, char *url, RTPStream *stream, char *original_ur return; } - sdp = (SDPFetch*)malloc(sizeof(SDPFetch)); + sdp = (SDPFetch*)gf_malloc(sizeof(SDPFetch)); memset(sdp, 0, sizeof(SDPFetch)); sdp->client = rtp; - sdp->remote_url = strdup(url); + sdp->remote_url = gf_strdup(url); sdp->chan = stream; if (original_url) { - sdp->original_url = strdup(original_url); + sdp->original_url = gf_strdup(original_url); } /*otherwise setup download*/ @@ -177,3 +179,4 @@ void RP_FetchSDP(RTPClient *rtp, char *url, RTPStream *stream, char *original_ur /*service confirm is done once fetched*/ } +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/modules/rtp_in/sdp_load.c b/modules/rtp_in/sdp_load.c index 3318114..6f7a3ae 100644 --- a/modules/rtp_in/sdp_load.c +++ b/modules/rtp_in/sdp_load.c @@ -25,6 +25,7 @@ #include "rtp_in.h" #include <gpac/internal/ietf_dev.h> +#ifndef GPAC_DISABLE_STREAMING GF_Err RP_SetupSDP(RTPClient *rtp, GF_SDPInfo *sdp, RTPStream *stream) { @@ -64,7 +65,7 @@ GF_Err RP_SetupSDP(RTPClient *rtp, GF_SDPInfo *sdp, RTPStream *stream) if (url) { migrate_sess = RP_NewSession(rtp, url); if (migrate_sess && session_id) { - migrate_sess->session_id = strdup(session_id); + migrate_sess->session_id = gf_strdup(session_id); } sess_ctrl = url; } @@ -169,7 +170,8 @@ static GF_ObjectDescriptor *RP_GetChannelOD(RTPStream *ch, u32 ch_idx) GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); if (!ch->ES_ID) ch->ES_ID = ch_idx + 1; - od->objectDescriptorID = ch->ES_ID; + od->objectDescriptorID = ch->OD_ID ? ch->OD_ID : ch->ES_ID; + esd = gf_odf_desc_esd_new(0); esd->slConfig->timestampResolution = gf_rtp_get_clockrate(ch->rtp_ch); esd->slConfig->useRandomAccessPointFlag = 1; @@ -180,7 +182,7 @@ static GF_ObjectDescriptor *RP_GetChannelOD(RTPStream *ch, u32 ch_idx) esd->decoderConfig->streamType = ch->depacketizer->sl_map.StreamType; esd->decoderConfig->objectTypeIndication = ch->depacketizer->sl_map.ObjectTypeIndication; if (ch->depacketizer->sl_map.config) { - esd->decoderConfig->decoderSpecificInfo->data = (char*)malloc(sizeof(char) * ch->depacketizer->sl_map.configSize); + esd->decoderConfig->decoderSpecificInfo->data = (char*)gf_malloc(sizeof(char) * ch->depacketizer->sl_map.configSize); memcpy(esd->decoderConfig->decoderSpecificInfo->data, ch->depacketizer->sl_map.config, sizeof(char) * ch->depacketizer->sl_map.configSize); esd->decoderConfig->decoderSpecificInfo->dataLength = ch->depacketizer->sl_map.configSize; } @@ -296,7 +298,7 @@ void RP_LoadSDP(RTPClient *rtp, char *sdp_text, u32 sdp_len, RTPStream *stream) i=0; while ((ch = (RTPStream *)gf_list_enum(rtp->channels, &i))) { if ((ch->depacketizer->payt==GF_RTP_PAYT_MPEG4) && (ch->depacketizer->sl_map.StreamType==GF_STREAM_SCENE) - || ((ch->depacketizer->payt==GF_RTP_PAYT_3GPP_DIMS) && (ch->depacketizer->sl_map.StreamType==GF_STREAM_SCENE)) +// || ((ch->depacketizer->payt==GF_RTP_PAYT_3GPP_DIMS) && (ch->depacketizer->sl_map.StreamType==GF_STREAM_SCENE)) ) { needs_iod = 1; break; @@ -325,42 +327,15 @@ void RP_LoadSDP(RTPClient *rtp, char *sdp_text, u32 sdp_len, RTPStream *stream) RP_SetupChannel(stream, NULL); } } - + /*store SDP for later session migration*/ if (sdp) { - char *cache = (char *) gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(rtp->service), - "Streaming", "SessionMigrationFile"); - - if (cache && cache[0]) { - char *out = NULL; - - if (!strncmp(cache, "http://", 7)) { - char temp[20]; - char *cdir = (char *) gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(rtp->service), - "General", "CacheDirectory"); - - rtp->session_state = malloc(sizeof(char)*4096); - strcpy(rtp->session_state, cdir); - strcat(rtp->session_state, "/"); - sprintf(temp, "mig%08x.sdp", (u32) rtp); - strcat(rtp->session_state, temp); - - rtp->remote_session_state = strdup(cache); - } else { - rtp->session_state = strdup(cache); - } - - gf_sdp_info_write(sdp, &out); - if (out) { - FILE *f = fopen(rtp->session_state, "wb"); - if (f) { - fprintf(f, out); - fclose(f); - } else { - free(rtp->session_state); - rtp->session_state = NULL; - } - free(out); - } + char *buf=NULL; + gf_sdp_info_write(sdp, &buf); + if (buf) { + rtp->session_state_data = gf_malloc(sizeof(char) * (strlen("data:application/sdp,") + strlen(buf) + 1) ); + strcpy(rtp->session_state_data, "data:application/sdp,"); + strcat(rtp->session_state_data, buf); + gf_free(buf); } gf_sdp_info_del(sdp); } @@ -376,28 +351,17 @@ void MigrateSDP_NetIO(void *cbk, GF_NETIO_Parameter *param) case GF_NETIO_GET_METHOD: param->name = "POST"; return; - case GF_NETIO_GET_CONTENT: - if (rtp->session_state) { - char szBody[4096], *opt; - u32 len1, len2; - FILE *f; - opt = (char *) gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(rtp->service), "Network", "MobileIP"); - sprintf(szBody, "ipadd\n%s\n\nurl\n%s\n\ndata\n", opt, gf_term_get_service_url(rtp->service) ); - len1 = strlen(szBody); - f = fopen(rtp->session_state, "r+t"); - fseek(f, 0, SEEK_END); - len2 = ftell(f); - fseek(f, 0, SEEK_SET); - len2 = fread(szBody+len1, 1, len2, f); - fclose(f); - szBody[len1+len2] = 0; - - rtp->tmp_buf = strdup(szBody); - param->data = rtp->tmp_buf; - param->size = strlen(szBody); - } + case GF_NETIO_GET_HEADER: + if (!strcmp(param->name, "POST")) { + param->name = "Content-Type"; + param->value = "application/sdp"; + } return; + case GF_NETIO_GET_CONTENT: + param->data = rtp->session_state_data + strlen("data:application/sdp,"); + param->size = strlen(param->data); + return; } } @@ -405,35 +369,18 @@ void MigrateSDP_NetIO(void *cbk, GF_NETIO_Parameter *param) void RP_SaveSessionState(RTPClient *rtp) { GF_Err e; - FILE *f; char *sdp_buf; + const char *opt; GF_X_Attribute*att; u32 i, j; - u32 sdp_size; GF_SDPInfo *sdp; RTSPSession *sess = NULL; - if (!rtp->session_state) return; - - sdp_buf = NULL; - f = fopen(rtp->session_state, "rt"); - if (!f) { - if (strncmp(rtp->session_state, "http://", 7)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[RTP] Cannot load session state %s\n", rtp->session_state)); - return; - } - } - fseek(f, 0, SEEK_END); - sdp_size = ftell(f); - fseek(f, 0, SEEK_SET); - sdp_buf = (char*)malloc(sdp_size); - fread(sdp_buf, sdp_size, 1, f); - fclose(f); - + if (!rtp->session_state_data) return; + sdp_buf = rtp->session_state_data + strlen("data:application/sdp,"); sdp = gf_sdp_info_new(); - e = gf_sdp_info_parse(sdp, sdp_buf, sdp_size); - free(sdp_buf); + e = gf_sdp_info_parse(sdp, sdp_buf, strlen(sdp_buf) ); for (i=0; i<gf_list_count(rtp->channels); i++) { GF_SDPMedia *media = NULL; @@ -446,7 +393,7 @@ void RP_SaveSessionState(RTPClient *rtp) for (k=0; k<gf_list_count(med->Attributes); k++) { att = (GF_X_Attribute*)gf_list_get(med->Attributes, k); - if (!stricmp(att->Name, "control") && !strcmp(att->Value, ch->control)) { + if (!stricmp(att->Name, "control") && (strstr(att->Value, ch->control)!=NULL) ) { media = med; break; } @@ -458,31 +405,35 @@ void RP_SaveSessionState(RTPClient *rtp) if (ch->rtp_ch->net_info.IsUnicast) { char szPorts[4096]; + u16 porta, portb; media->PortNumber = ch->rtp_ch->net_info.client_port_first; /*remove x-server-port extension*/ for (j=0; j<gf_list_count(media->Attributes); j++) { att = (GF_X_Attribute*)gf_list_get(media->Attributes, j); if (!stricmp(att->Name, "x-stream-state") ) { - free(att->Name); - free(att->Value); - free(att); + gf_free(att->Name); + gf_free(att->Value); + gf_free(att); gf_list_rem(media->Attributes, j); } } ch->current_start += gf_rtp_get_current_time(ch->rtp_ch); GF_SAFEALLOC(att, GF_X_Attribute); - att->Name = strdup("x-stream-state"); + att->Name = gf_strdup("x-stream-state"); + porta = ch->rtp_ch->net_info.port_first ? ch->rtp_ch->net_info.port_first : ch->rtp_ch->net_info.client_port_first; + portb = ch->rtp_ch->net_info.port_last ? ch->rtp_ch->net_info.port_last : ch->rtp_ch->net_info.client_port_last; + sprintf(szPorts, "server-port=%d-%d;ssrc=%X;npt=%g;seq=%d;rtptime=%d", - ch->rtp_ch->net_info.port_first, - ch->rtp_ch->net_info.port_last, + porta, + portb, ch->rtp_ch->SenderSSRC, ch->current_start, ch->rtp_ch->rtp_first_SN, ch->rtp_ch->rtp_time ); - att->Value = strdup(szPorts); + att->Value = gf_strdup(szPorts); gf_list_add(media->Attributes, att); if (ch->rtsp) @@ -497,57 +448,72 @@ void RP_SaveSessionState(RTPClient *rtp) att = (GF_X_Attribute*)gf_list_get(sdp->Attributes, j); if (!stricmp(att->Name, "x-session-id") || !stricmp(att->Name, "x-session-name") ) { - free(att->Name); - free(att->Value); - free(att); + gf_free(att->Name); + gf_free(att->Value); + gf_free(att); gf_list_rem(sdp->Attributes, j); } } - if (sess && sess->session_id) { - GF_SAFEALLOC(att, GF_X_Attribute); - att->Name = strdup("x-session-id"); - att->Value = strdup(sess->session_id); - gf_list_add(sdp->Attributes, att); - } - { + if (sess) { char szURL[4096]; + + if (sess->session_id) { + GF_SAFEALLOC(att, GF_X_Attribute); + att->Name = gf_strdup("x-session-id"); + att->Value = gf_strdup(sess->session_id); + gf_list_add(sdp->Attributes, att); + } + GF_SAFEALLOC(att, GF_X_Attribute); - att->Name = strdup("x-session-name"); + att->Name = gf_strdup("x-session-name"); sprintf(szURL, "rtsp://%s:%d/%s", sess->session->Server, sess->session->Port, sess->session->Service); - att->Value = strdup(szURL); + att->Value = gf_strdup(szURL); gf_list_add(sdp->Attributes, att); } - - f = fopen(rtp->session_state, "wb"); - if (f) { - char *out = NULL; - gf_sdp_info_write(sdp, &out); - if (out) { - fprintf(f, out); - free(out); - } - fclose(f); + gf_free(rtp->session_state_data); + sdp_buf = NULL; + gf_sdp_info_write(sdp, &sdp_buf); + if (sdp_buf) { + rtp->session_state_data = gf_malloc(sizeof(char) * (strlen("data:application/sdp,") + strlen(sdp_buf) + 1) ); + strcpy(rtp->session_state_data, "data:application/sdp,"); + strcat(rtp->session_state_data, sdp_buf); + gf_free(sdp_buf); } + gf_sdp_info_del(sdp); - if (rtp->remote_session_state && rtp->session_state) { + + opt = (char *) gf_modules_get_option((GF_BaseInterface *) gf_term_get_service_interface(rtp->service), "Streaming", "SessionMigrationServer"); + if (opt) { if (rtp->dnload) gf_term_download_del(rtp->dnload); rtp->dnload = NULL; - rtp->dnload = gf_term_download_new(rtp->service, rtp->remote_session_state, GF_NETIO_SESSION_NOT_THREADED, MigrateSDP_NetIO, rtp); - while (1) { - char buffer[100]; - u32 read; - e = gf_dm_sess_fetch_data(rtp->dnload, buffer, 100, &read); - if (e && (e!=GF_IP_NETWORK_EMPTY)) break; + if (strnicmp(opt, "http://", 7)) { + rtp->dnload = gf_term_download_new(rtp->service, opt, GF_NETIO_SESSION_NOT_THREADED, MigrateSDP_NetIO, rtp); + while (1) { + char buffer[100]; + u32 read; + e = gf_dm_sess_fetch_data(rtp->dnload, buffer, 100, &read); + if (e && (e!=GF_IP_NETWORK_EMPTY)) break; + } + gf_term_download_del(rtp->dnload); + rtp->dnload = NULL; + } else { + FILE *f = gf_f64_open(opt, "wt"); + if (f) { + sdp_buf = rtp->session_state_data + strlen("data:application/sdp,"); + fwrite(sdp_buf, 1, strlen(sdp_buf), f); + fclose(f); + } else { + e = GF_IO_ERR; + } } - if (rtp->tmp_buf) free(rtp->tmp_buf); - gf_term_download_del(rtp->dnload); - rtp->dnload = NULL; if (e<0) { gf_term_on_message(sess->owner->service, e, "Error saving session state"); } } } + +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/modules/saf_in/Makefile b/modules/saf_in/Makefile index cdab347..3448748 100644 --- a/modules/saf_in/Makefile +++ b/modules/saf_in/Makefile @@ -22,20 +22,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_saf_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols saf_in.def +#LDFLAGS+=-export-symbols saf_in.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_dummy_in-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/saf_in/saf_in.c b/modules/saf_in/saf_in.c index e611c62..8c88f41 100644 --- a/modules/saf_in/saf_in.c +++ b/modules/saf_in/saf_in.c @@ -114,7 +114,8 @@ static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param) GF_Err e; Bool is_rap, go; SAFChannel *ch; - u32 cts, au_sn, au_size, bs_pos, type, i, stream_id; + u32 cts, au_sn, au_size, type, i, stream_id; + u64 bs_pos; GF_BitStream *bs; GF_SLHeader sl_hdr; @@ -149,7 +150,7 @@ static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param) if (!read->run_state) return; if (read->alloc_size < read->saf_size + param->size) { - read->saf_data = (char*)realloc(read->saf_data, sizeof(char)*(read->saf_size + param->size) ); + read->saf_data = (char*)gf_realloc(read->saf_data, sizeof(char)*(read->saf_size + param->size) ); read->alloc_size = read->saf_size + param->size; } memcpy(read->saf_data + read->saf_size, param->data, sizeof(char)*param->size); @@ -163,8 +164,8 @@ static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param) go = 1; while (go) { - u32 avail = (u32) gf_bs_available(bs); - bs_pos = (u32) gf_bs_get_position(bs); + u64 avail = gf_bs_available(bs); + bs_pos = gf_bs_get_position(bs); if (avail<10) break; @@ -212,14 +213,14 @@ static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param) } if (type==7) { u16 urlLen = gf_bs_read_u16(bs); - ch->esd->URLString = (char*)malloc(sizeof(char)*(urlLen+1)); + ch->esd->URLString = (char*)gf_malloc(sizeof(char)*(urlLen+1)); gf_bs_read_data(bs, ch->esd->URLString, urlLen); ch->esd->URLString[urlLen] = 0; au_size -= urlLen+2; } if (au_size) { ch->esd->decoderConfig->decoderSpecificInfo->dataLength = au_size; - ch->esd->decoderConfig->decoderSpecificInfo->data = (char*)malloc(sizeof(char)*au_size); + ch->esd->decoderConfig->decoderSpecificInfo->data = (char*)gf_malloc(sizeof(char)*au_size); gf_bs_read_data(bs, ch->esd->decoderConfig->decoderSpecificInfo->data, au_size); } if (ch->esd->decoderConfig->streamType==4) ch->buffer_min=100; @@ -232,7 +233,7 @@ static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param) gf_term_on_connect(read->service, NULL, GF_OK); } else if (read->needs_connection) { gf_odf_desc_del((GF_Descriptor *) ch->esd); - free(ch); + gf_free(ch); ch = NULL; } else { GF_ObjectDescriptor *od; @@ -249,7 +250,7 @@ static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param) break; case 4: if (ch) { - bs_pos = (u32) gf_bs_get_position(bs); + bs_pos = gf_bs_get_position(bs); memset(&sl_hdr, 0, sizeof(GF_SLHeader)); sl_hdr.accessUnitLength = au_size; sl_hdr.AU_sequenceNumber = au_sn; @@ -279,7 +280,7 @@ static void SAF_NetIO(void *cbk, GF_NETIO_Parameter *param) gf_bs_del(bs); if (bs_pos) { - u32 remain = read->saf_size - bs_pos; + u32 remain = (u32) (read->saf_size - bs_pos); if (remain) memmove(read->saf_data, read->saf_data+bs_pos, sizeof(char)*remain); read->saf_size = remain; } @@ -296,7 +297,7 @@ u32 SAF_Run(void *_p) par.msg_type = GF_NETIO_DATA_EXCHANGE; par.data = data; - fseek(read->stream, 0, SEEK_SET); + gf_f64_seek(read->stream, 0, SEEK_SET); read->saf_size=0; read->run_state = 1; while (read->run_state && !feof(read->stream) ) { @@ -331,7 +332,7 @@ static void SAF_CheckFile(SAFIn *read) u32 nb_streams, i, cts, au_size, au_type, stream_id, ts_res; GF_BitStream *bs; StreamInfo si[1024]; - fseek(read->stream, 0, SEEK_SET); + gf_f64_seek(read->stream, 0, SEEK_SET); bs = gf_bs_from_file(read->stream, GF_BITSTREAM_READ); nb_streams=0; @@ -363,7 +364,7 @@ static void SAF_CheckFile(SAFIn *read) gf_bs_skip_bytes(bs, au_size); } gf_bs_del(bs); - fseek(read->stream, 0, SEEK_SET); + gf_f64_seek(read->stream, 0, SEEK_SET); } static GF_Err SAF_ConnectService(GF_InputService *plug, GF_ClientService *serv, const char *url) @@ -391,7 +392,7 @@ static GF_Err SAF_ConnectService(GF_InputService *plug, GF_ClientService *serv, return GF_OK; } - read->stream = fopen(szURL, "rb"); + read->stream = gf_f64_open(szURL, "rb"); if (!read->stream) { gf_term_on_connect(serv, NULL, GF_URL_ERROR); return GF_OK; @@ -479,7 +480,7 @@ static GF_Err SAF_DisconnectChannel(GF_InputService *plug, LPNETCHANNEL channel) if (ch) { gf_list_del_item(read->channels, ch); if (ch->esd) gf_odf_desc_del((GF_Descriptor*)ch->esd); - free(ch); + gf_free(ch); e = GF_OK; } gf_term_on_disconnect(read->service, channel, e); @@ -557,22 +558,23 @@ void DeleteSAFReader(void *ifce) SAFChannel *ch = (SAFChannel *)gf_list_last(read->channels); gf_list_rem_last(read->channels); if (ch->esd) gf_odf_desc_del((GF_Descriptor *) ch->esd); - free(ch); + gf_free(ch); } gf_list_del(read->channels); - if (read->saf_data) free(read->saf_data); - free(read); - free(plug); + if (read->saf_data) gf_free(read->saf_data); + gf_free(read); + gf_free(plug); } GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - switch (InterfaceType) { - case GF_NET_CLIENT_INTERFACE: return 1; - default: return 0; - } + static u32 si [] = { + GF_NET_CLIENT_INTERFACE, + 0 + }; + return si; } GF_EXPORT diff --git a/modules/saf_in/saf_in.def b/modules/saf_in/saf_in.def deleted file mode 100644 index 8f7ac7c..0000000 --- a/modules/saf_in/saf_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_saf_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/sdl_out/Makefile b/modules/sdl_out/Makefile index 4cdea4b..2879d79 100644 --- a/modules/sdl_out/Makefile +++ b/modules/sdl_out/Makefile @@ -15,15 +15,6 @@ LDFLAGS+=-pg endif LINKFLAGS=$(SDL_LIBS) -ifeq ($(CONFIG_X11), yes) -CFLAGS+=-DGPAC_HAS_X11 -LINKFLAGS+=-lX11 -ifeq ($(X11_INC_PATH), "") -else -CFLAGS+=-I$(X11_INC_PATH) -LINKFLAGS+=-L$(X11_LIB_PATH) -endif -endif #common obj OBJS=sdl_out.o audio.o video.o @@ -32,20 +23,15 @@ SRCS := $(OBJS:.o=.c) LIB=gm_sdl_out.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols sdl_out.def +#LDFLAGS+=-export-symbols sdl_out.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(LINKFLAGS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(LINKFLAGS) -L../../bin/gcc -lgpac %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< diff --git a/modules/sdl_out/audio.c b/modules/sdl_out/audio.c index 7351f1e..e5bf357 100644 --- a/modules/sdl_out/audio.c +++ b/modules/sdl_out/audio.c @@ -174,10 +174,10 @@ void *SDL_NewAudio() GF_AudioOutput *dr; - ctx = malloc(sizeof(SDLAudCtx)); + ctx = gf_malloc(sizeof(SDLAudCtx)); memset(ctx, 0, sizeof(SDLAudCtx)); - dr = malloc(sizeof(GF_AudioOutput)); + dr = gf_malloc(sizeof(GF_AudioOutput)); memset(dr, 0, sizeof(GF_AudioOutput)); GF_REGISTER_MODULE_INTERFACE(dr, GF_AUDIO_OUTPUT_INTERFACE, "SDL Audio Output", "gpac distribution"); @@ -204,7 +204,7 @@ void SDL_DeleteAudio(void *ifce) GF_AudioOutput *dr = (GF_AudioOutput*)ifce; SDLAUD(); - free(ctx); - free(ifce); + gf_free(ctx); + gf_free(ifce); } diff --git a/modules/sdl_out/sdl_out.c b/modules/sdl_out/sdl_out.c index 208b0b0..56fb7bb 100644 --- a/modules/sdl_out/sdl_out.c +++ b/modules/sdl_out/sdl_out.c @@ -50,11 +50,14 @@ void SDLOUT_CloseSDL() /*interface query*/ -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return 1; - if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + GF_AUDIO_OUTPUT_INTERFACE, + 0 + }; + return si; } /*interface create*/ GF_BaseInterface *LoadInterface(u32 InterfaceType) diff --git a/modules/sdl_out/sdl_out.def b/modules/sdl_out/sdl_out.def deleted file mode 100644 index 81c51d1..0000000 --- a/modules/sdl_out/sdl_out.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_sdl_out.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/sdl_out/sdl_out.h b/modules/sdl_out/sdl_out.h index 72b7fc6..ef1f111 100644 --- a/modules/sdl_out/sdl_out.h +++ b/modules/sdl_out/sdl_out.h @@ -35,11 +35,16 @@ Bool SDLOUT_InitSDL(); void SDLOUT_CloseSDL(); +//#define SDL_WINDOW_THREAD + + typedef struct { +#ifdef SDL_WINDOW_THREAD GF_Thread *sdl_th; - GF_Mutex *evt_mx; u32 sdl_th_state; +#endif + GF_Mutex *evt_mx; Bool is_init, fullscreen; /*fullscreen display size*/ u32 fs_width, fs_height; @@ -47,17 +52,24 @@ typedef struct u32 store_width, store_height; /*cursors*/ SDL_Cursor *curs_def, *curs_hand, *curs_collide; - Bool systems_memory; + Bool use_systems_memory; SDL_Surface *screen; SDL_Surface *back_buffer; + SDL_Surface *pool_rgb, *pool_rgba; + SDL_Overlay *yuv_overlay; + u32 width, height; SDL_Surface *offscreen_gl; u32 output_3d_type; void *os_handle; + + + u32 last_mouse_move; + Bool cursor_on; } SDLVidCtx; void SDL_DeleteVideo(void *ifce); diff --git a/modules/sdl_out/video.c b/modules/sdl_out/video.c index b567874..664dc5a 100644 --- a/modules/sdl_out/video.c +++ b/modules/sdl_out/video.c @@ -111,10 +111,6 @@ static char collide_data[] = #define SDLVID() SDLVidCtx *ctx = (SDLVidCtx *)dr->opaque -#ifdef GPAC_HAS_X11 -#include <X11/Xlib.h> -#endif - static u32 video_modes[] = { 320, 200, @@ -275,7 +271,6 @@ static void sdl_translate_key(u32 SDLkey, GF_EventKey *evt) case SDLK_UNDERSCORE: evt->key_code = GF_KEY_UNDERSCORE; break; case SDLK_BACKQUOTE: evt->key_code = GF_KEY_GRAVEACCENT; break; case SDLK_DELETE: evt->key_code = GF_KEY_DEL; break; - case SDLK_EURO: evt->key_code = GF_KEY_EURO; break; case SDLK_UNDO: evt->key_code = GF_KEY_UNDO; break; case SDLK_UP: evt->key_code = GF_KEY_UP; break; @@ -390,15 +385,18 @@ static void sdl_translate_key(u32 SDLkey, GF_EventKey *evt) #if 0 void SDLVid_SetHack(void *os_handle, Bool set_on) { - unsetenv("SDL_WINDOWID="); - if (!os_handle) return; - if (set_on) { - char buf[16]; - snprintf(buf, sizeof(buf), "%u", (u32) os_handle); - setenv("SDL_WINDOWID", buf, 1); + char buf[50]; + if (set_on && os_handle) { sprintf(buf, "SDL_WINDOWID=%u", (u32) os_handle); - putenv(buf); + } else { + strcpy(buf, "SDL_WINDOWID="); } +#ifdef WIN32 + putenv(buf); +#else + if (set_on) unsetenv("SDL_WINDOWID="); + else putenv(buf); +#endif } #endif @@ -406,6 +404,12 @@ static void SDLVid_DestroyObjects(SDLVidCtx *ctx) { if (ctx->back_buffer) SDL_FreeSurface(ctx->back_buffer); ctx->back_buffer = NULL; + if (ctx->pool_rgb) SDL_FreeSurface(ctx->pool_rgb); + ctx->pool_rgb = NULL; + if (ctx->pool_rgba) SDL_FreeSurface(ctx->pool_rgba); + ctx->pool_rgba = NULL; + SDL_FreeYUVOverlay(ctx->yuv_overlay); + ctx->yuv_overlay=NULL; } @@ -462,139 +466,153 @@ GF_Err SDLVid_ResizeWindow(GF_VideoOutput *dr, u32 width, u32 height) } -u32 SDLVid_EventProc(void *par) +static Bool SDLVid_InitializeWindow(SDLVidCtx *ctx, GF_VideoOutput *dr) { - u32 flags, last_mouse_move; - Bool cursor_on; - SDL_Event sdl_evt; - GF_Event gpac_evt; - GF_VideoOutput *dr = (GF_VideoOutput *)par; - SDLVID(); + u32 flags; + const SDL_VideoInfo *vinf; flags = SDL_WasInit(SDL_INIT_VIDEO); if (!(flags & SDL_INIT_VIDEO)) { if (SDL_InitSubSystem(SDL_INIT_VIDEO)<0) { - ctx->sdl_th_state = 3; return 0; } } - /*note we create the window on the first resize. This is the only way to keep synchronous with X and cope with GL threading*/ - - ctx->sdl_th_state = 1; ctx->curs_def = SDL_GetCursor(); ctx->curs_hand = SDLVid_LoadCursor(hand_data); ctx->curs_collide = SDLVid_LoadCursor(collide_data); SDL_EnableUNICODE(1); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); - last_mouse_move = SDL_GetTicks(); - cursor_on = 1; - - /*save display resolution (SDL doesn't give acees to that)*/ - dr->max_screen_width = dr->max_screen_height = 0; -#ifdef GPAC_HAS_X11 - { - Display *dpy = XOpenDisplay(NULL); - if (dpy) { - dr->max_screen_width = DisplayWidth(dpy, DefaultScreen(dpy)); - dr->max_screen_height = DisplayHeight(dpy, DefaultScreen(dpy)); - XCloseDisplay(dpy); - } - } -#endif -#ifdef WIN32 - dr->max_screen_width = GetSystemMetrics(SM_CXSCREEN); - dr->max_screen_height = GetSystemMetrics(SM_CYSCREEN); -#endif - + ctx->last_mouse_move = SDL_GetTicks(); + ctx->cursor_on = 1; + /*save display resolution - SDL seems to get the screen resolution if asked for video info before + changing the video mode - to check on other platforms*/ + vinf = SDL_GetVideoInfo(); + dr->max_screen_width = vinf->current_w; + dr->max_screen_height = vinf->current_h; + + SDLVid_ResizeWindow(dr, 100, 100); if (!ctx->os_handle) SDLVid_SetCaption(); - while (ctx->sdl_th_state==1) { - /*after much testing: we must ensure nothing is using the event queue when resizing window. - -- under X, it throws Xlib "unexpected async reply" under linux, therefore we don't wait events, - we check for events and execute them if any - -- under Win32, the SDL_SetVideoMode deadlocks, so we don't force exclusive access to events - */ -#ifndef WIN32 - gf_mx_p(ctx->evt_mx); -#endif - while (SDL_PollEvent(&sdl_evt)) { - switch (sdl_evt.type) { - case SDL_VIDEORESIZE: - gpac_evt.type = GF_EVENT_SIZE; - gpac_evt.size.width = sdl_evt.resize.w; - gpac_evt.size.height = sdl_evt.resize.h; + GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[SDL] Video output initialized - screen resolution %d %d\n", dr->max_screen_width, dr->max_screen_height)); + return 1; +} + +static void SDLVid_ShutdownWindow(SDLVidCtx *ctx) +{ + SDLVid_DestroyObjects(ctx); + SDL_FreeCursor(ctx->curs_hand); + SDL_FreeCursor(ctx->curs_collide); + SDL_QuitSubSystem(SDL_INIT_VIDEO); +} + + +Bool SDLVid_ProcessMessageQueue(SDLVidCtx *ctx, GF_VideoOutput *dr) +{ + SDL_Event sdl_evt; + GF_Event gpac_evt; + + while (SDL_PollEvent(&sdl_evt)) { + switch (sdl_evt.type) { + case SDL_VIDEORESIZE: + gpac_evt.type = GF_EVENT_SIZE; + gpac_evt.size.width = sdl_evt.resize.w; + gpac_evt.size.height = sdl_evt.resize.h; + dr->on_event(dr->evt_cbk_hdl, &gpac_evt); + break; + case SDL_QUIT: + gpac_evt.type = GF_EVENT_QUIT; + dr->on_event(dr->evt_cbk_hdl, &gpac_evt); + return 0; + + case SDL_VIDEOEXPOSE: + gpac_evt.type = GF_EVENT_REFRESH; + dr->on_event(dr->evt_cbk_hdl, &gpac_evt); + break; + + /*keyboard*/ + case SDL_KEYDOWN: + case SDL_KEYUP: + sdl_translate_key(sdl_evt.key.keysym.sym, &gpac_evt.key); + gpac_evt.type = (sdl_evt.key.type==SDL_KEYDOWN) ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP; + dr->on_event(dr->evt_cbk_hdl, &gpac_evt); + if ((sdl_evt.key.type==SDL_KEYDOWN) && sdl_evt.key.keysym.unicode) { + gpac_evt.character.unicode_char = sdl_evt.key.keysym.unicode; + gpac_evt.type = GF_EVENT_TEXTINPUT; dr->on_event(dr->evt_cbk_hdl, &gpac_evt); - break; - case SDL_QUIT: - if (ctx->sdl_th_state==1) { - gpac_evt.type = GF_EVENT_QUIT; - dr->on_event(dr->evt_cbk_hdl, &gpac_evt); - } else { - goto exit; - } - break; - case SDL_VIDEOEXPOSE: - gpac_evt.type = GF_EVENT_REFRESH; + } + break; + + /*mouse*/ + case SDL_MOUSEMOTION: + ctx->last_mouse_move = SDL_GetTicks(); + gpac_evt.type = GF_EVENT_MOUSEMOVE; + gpac_evt.mouse.x = sdl_evt.motion.x; + gpac_evt.mouse.y = sdl_evt.motion.y; + dr->on_event(dr->evt_cbk_hdl, &gpac_evt); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + ctx->last_mouse_move = SDL_GetTicks(); + gpac_evt.mouse.x = sdl_evt.motion.x; + gpac_evt.mouse.y = sdl_evt.motion.y; + gpac_evt.type = (sdl_evt.type==SDL_MOUSEBUTTONUP) ? GF_EVENT_MOUSEUP : GF_EVENT_MOUSEDOWN; + switch (sdl_evt.button.button) { + case SDL_BUTTON_LEFT: + gpac_evt.mouse.button = GF_MOUSE_LEFT; dr->on_event(dr->evt_cbk_hdl, &gpac_evt); break; - - /*keyboard*/ - case SDL_KEYDOWN: - case SDL_KEYUP: - sdl_translate_key(sdl_evt.key.keysym.sym, &gpac_evt.key); - gpac_evt.type = (sdl_evt.key.type==SDL_KEYDOWN) ? GF_EVENT_KEYDOWN : GF_EVENT_KEYUP; + case SDL_BUTTON_MIDDLE: + gpac_evt.mouse.button = GF_MOUSE_MIDDLE; dr->on_event(dr->evt_cbk_hdl, &gpac_evt); - if ((sdl_evt.key.type==SDL_KEYDOWN) && sdl_evt.key.keysym.unicode) { - gpac_evt.character.unicode_char = sdl_evt.key.keysym.unicode; - gpac_evt.type = GF_EVENT_TEXTINPUT; - dr->on_event(dr->evt_cbk_hdl, &gpac_evt); - } break; - - /*mouse*/ - case SDL_MOUSEMOTION: - last_mouse_move = SDL_GetTicks(); - gpac_evt.type = GF_EVENT_MOUSEMOVE; - gpac_evt.mouse.x = sdl_evt.motion.x; - gpac_evt.mouse.y = sdl_evt.motion.y; + case SDL_BUTTON_RIGHT: + gpac_evt.mouse.button = GF_MOUSE_RIGHT; dr->on_event(dr->evt_cbk_hdl, &gpac_evt); break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - last_mouse_move = SDL_GetTicks(); - gpac_evt.mouse.x = sdl_evt.motion.x; - gpac_evt.mouse.y = sdl_evt.motion.y; - gpac_evt.type = (sdl_evt.type==SDL_MOUSEBUTTONUP) ? GF_EVENT_MOUSEUP : GF_EVENT_MOUSEDOWN; - switch (sdl_evt.button.button) { - case SDL_BUTTON_LEFT: - gpac_evt.mouse.button = GF_MOUSE_LEFT; - dr->on_event(dr->evt_cbk_hdl, &gpac_evt); - break; - case SDL_BUTTON_MIDDLE: - gpac_evt.mouse.button = GF_MOUSE_MIDDLE; - dr->on_event(dr->evt_cbk_hdl, &gpac_evt); - break; - case SDL_BUTTON_RIGHT: - gpac_evt.mouse.button = GF_MOUSE_RIGHT; - dr->on_event(dr->evt_cbk_hdl, &gpac_evt); - break; #ifdef SDL_BUTTON_WHEELUP - case SDL_BUTTON_WHEELUP: - case SDL_BUTTON_WHEELDOWN: - /*SDL handling is not perfect there, it just says up/down but no info on how much - the wheel was rotated...*/ - gpac_evt.mouse.wheel_pos = (sdl_evt.button.button==SDL_BUTTON_WHEELUP) ? FIX_ONE : -FIX_ONE; - gpac_evt.type = GF_EVENT_MOUSEWHEEL; - dr->on_event(dr->evt_cbk_hdl, &gpac_evt); - break; -#endif - } + case SDL_BUTTON_WHEELUP: + case SDL_BUTTON_WHEELDOWN: + /*SDL handling is not perfect there, it just says up/down but no info on how much + the wheel was rotated...*/ + gpac_evt.mouse.wheel_pos = (sdl_evt.button.button==SDL_BUTTON_WHEELUP) ? FIX_ONE : -FIX_ONE; + gpac_evt.type = GF_EVENT_MOUSEWHEEL; + dr->on_event(dr->evt_cbk_hdl, &gpac_evt); break; +#endif } + break; } + } + return 1; +} + +#ifdef SDL_WINDOW_THREAD +u32 SDLVid_EventProc(void *par) +{ + u32 flags, last_mouse_move; + Bool ret; + GF_VideoOutput *dr = (GF_VideoOutput *)par; + SDLVID(); + + ctx->sdl_th_state = 1; + if (!SDLVid_InitializeWindow(ctx, dr)) { + ctx->sdl_th_state = 3; + } + + while (ctx->sdl_th_state==1) { + /*after much testing: we must ensure nothing is using the event queue when resizing window. + -- under X, it throws Xlib "unexpected async reply" under linux, therefore we don't wait events, + we check for events and execute them if any + -- under Win32, the SDL_SetVideoMode deadlocks, so we don't force exclusive access to events + */ +#ifndef WIN32 + gf_mx_p(ctx->evt_mx); +#endif + + ret = SDLVid_ProcessMessageQueue(ctx, dr); #ifndef WIN32 gf_mx_v(ctx->evt_mx); @@ -610,31 +628,33 @@ u32 SDLVid_EventProc(void *par) cursor_on = 1; } #endif - - gf_sleep(5); + + /*QUIT message has been processed*/ + if (!ret) break; + + gf_sleep(0); } -exit: - SDLVid_DestroyObjects(ctx); - SDL_FreeCursor(ctx->curs_hand); - SDL_FreeCursor(ctx->curs_collide); - SDL_QuitSubSystem(SDL_INIT_VIDEO); + SDLVid_ShutdownWindow(ctx); ctx->sdl_th_state = 3; return 0; } +#endif /*SDL_WINDOW_THREAD*/ GF_Err SDLVid_Setup(struct _video_out *dr, void *os_handle, void *os_display, u32 init_flags) { SDLVID(); /*we don't allow SDL hack, not stable enough*/ - //if (os_handle) return GF_NOT_SUPPORTED; + //if (os_handle) SDLVid_SetHack(os_handle, 1); + ctx->os_handle = os_handle; ctx->is_init = 0; ctx->output_3d_type = 0; - ctx->systems_memory = (init_flags & (GF_TERM_NO_VISUAL_THREAD | GF_TERM_NO_REGULATION) ) ? 2 : 0; + if (!SDLOUT_InitSDL()) return GF_IO_ERR; +#ifdef SDL_WINDOW_THREAD ctx->sdl_th_state = 0; gf_th_run(ctx->sdl_th, SDLVid_EventProc, dr); while (!ctx->sdl_th_state) gf_sleep(10); @@ -643,6 +663,13 @@ GF_Err SDLVid_Setup(struct _video_out *dr, void *os_handle, void *os_display, u3 ctx->sdl_th_state = 0; return GF_IO_ERR; } +#else + if (!SDLVid_InitializeWindow(ctx, dr)) { + SDLOUT_CloseSDL(); + return GF_IO_ERR; + } +#endif + ctx->is_init = 1; return GF_OK; } @@ -653,6 +680,7 @@ static void SDLVid_Shutdown(GF_VideoOutput *dr) /*remove all surfaces*/ if (!ctx->is_init) return; +#ifdef SDL_WINDOW_THREAD if (ctx->sdl_th_state==1) { SDL_Event evt; ctx->sdl_th_state = 2; @@ -660,6 +688,10 @@ static void SDLVid_Shutdown(GF_VideoOutput *dr) SDL_PushEvent(&evt); while (ctx->sdl_th_state != 3) gf_sleep(100); } +#else + SDLVid_ShutdownWindow(ctx); +#endif + SDLOUT_CloseSDL(); ctx->is_init = 0; } @@ -726,7 +758,7 @@ GF_Err SDLVid_SetFullScreen(GF_VideoOutput *dr, u32 bFullScreenOn, u32 *screen_w return GF_OK; } -GF_Err SDLVid_SetBackbufferSize(GF_VideoOutput *dr, u32 newWidth, u32 newHeight) +GF_Err SDLVid_SetBackbufferSize(GF_VideoOutput *dr, u32 newWidth, u32 newHeight, Bool system_mem) { u32 col; const char *opt; @@ -734,10 +766,12 @@ GF_Err SDLVid_SetBackbufferSize(GF_VideoOutput *dr, u32 newWidth, u32 newHeight) if (ctx->output_3d_type==1) return GF_BAD_PARAM; - if (ctx->systems_memory<2) { + if (system_mem) { opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "UseHardwareMemory"); - ctx->systems_memory = (opt && !strcmp(opt, "yes")) ? 0 : 1; + if (opt && !strcmp(opt, "yes")) system_mem = 0; } + ctx->use_systems_memory = system_mem; + /*clear screen*/ col = SDL_MapRGB(ctx->screen->format, 0, 0, 0); @@ -748,7 +782,7 @@ GF_Err SDLVid_SetBackbufferSize(GF_VideoOutput *dr, u32 newWidth, u32 newHeight) return GF_OK; } if (ctx->back_buffer) SDL_FreeSurface(ctx->back_buffer); - ctx->back_buffer = SDL_CreateRGBSurface(ctx->systems_memory ? SDL_SWSURFACE : SDL_HWSURFACE, newWidth, newHeight, ctx->screen->format->BitsPerPixel, ctx->screen->format->Rmask, ctx->screen->format->Gmask, ctx->screen->format->Bmask, 0); + ctx->back_buffer = SDL_CreateRGBSurface(ctx->use_systems_memory ? SDL_SWSURFACE : SDL_HWSURFACE, newWidth, newHeight, ctx->screen->format->BitsPerPixel, ctx->screen->format->Rmask, ctx->screen->format->Gmask, ctx->screen->format->Bmask, 0); ctx->width = newWidth; ctx->height = newHeight; if (!ctx->back_buffer) return GF_IO_ERR; @@ -787,10 +821,11 @@ static GF_Err SDLVid_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *video_i if (SDL_LockSurface(ctx->back_buffer)<0) return GF_IO_ERR; video_info->width = ctx->back_buffer->w; video_info->height = ctx->back_buffer->h; - video_info->pitch = ctx->back_buffer->pitch; + video_info->pitch_x = 0; + video_info->pitch_y = ctx->back_buffer->pitch; video_info->video_buffer = ctx->back_buffer->pixels; video_info->pixel_format = SDLVid_MapPixelFormat(ctx->back_buffer->format); - video_info->is_hardware_memory = !ctx->systems_memory; + video_info->is_hardware_memory = !ctx->use_systems_memory; } else { SDL_UnlockSurface(ctx->back_buffer); } @@ -818,17 +853,19 @@ static GF_Err SDLVid_Flush(GF_VideoOutput *dr, GF_Window *dest) src.height = ctx->back_buffer->h; src.width = ctx->back_buffer->w; - src.pitch = ctx->back_buffer->pitch; + src.pitch_x = 0; + src.pitch_y = ctx->back_buffer->pitch; src.pixel_format = SDLVid_MapPixelFormat(ctx->back_buffer->format); src.video_buffer = ctx->back_buffer->pixels; dst.height = ctx->screen->h; dst.width = ctx->screen->w; - dst.pitch = ctx->screen->pitch; + dst.pitch_x = 0; + dst.pitch_y = ctx->screen->pitch; dst.pixel_format = SDLVid_MapPixelFormat(ctx->screen->format); dst.video_buffer = ctx->screen->pixels; - gf_stretch_bits(&dst, &src, dest, NULL, 0, 0xFF, 0, NULL, NULL); + gf_stretch_bits(&dst, &src, dest, NULL, 0xFF, 0, NULL, NULL); SDL_UnlockSurface(ctx->back_buffer); SDL_UnlockSurface(ctx->screen); @@ -862,7 +899,13 @@ static void SDLVid_SetCursor(GF_VideoOutput *dr, u32 cursor_type) static GF_Err SDLVid_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) { - if (!evt) return GF_OK; + if (!evt) { +#ifndef SDL_WINDOW_THREAD + SDLVID(); + SDLVid_ProcessMessageQueue(ctx, dr); +#endif + return GF_OK; + } switch (evt->type) { case GF_EVENT_SET_CURSOR: SDLVid_SetCursor(dr, evt->cursor.cursor_type); @@ -883,7 +926,7 @@ static GF_Err SDLVid_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) switch (evt->setup.opengl_mode) { case 0: ctx->output_3d_type = 0; - return SDLVid_SetBackbufferSize(dr, evt->setup.width, evt->setup.height); + return SDLVid_SetBackbufferSize(dr, evt->setup.width, evt->setup.height, evt->setup.system_memory); case 1: ctx->output_3d_type = 1; return SDLVid_ResizeWindow(dr, evt->setup.width, evt->setup.height); @@ -899,6 +942,146 @@ static GF_Err SDLVid_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt) } +static void copy_yuv(u8 *pYD, u8 *pVD, u8 *pUD, u32 pixel_format , u32 pitch_y, unsigned char *src, u32 src_stride, u32 src_pf, + u32 src_width, u32 src_height, const GF_Window *src_wnd) +{ + unsigned char *pY, *pU, *pV; + pY = src; + pU = src + src_stride * src_height; + pV = src + 5*src_stride * src_height/4; + + + pY = pY + src_stride * src_wnd->y + src_wnd->x; + /*because of U and V downsampling by 2x2, working with odd Y offset will lead to a half-line shift between Y and UV components. We + therefore force an even Y offset for U and V planes.*/ + pU = pU + (src_stride * (src_wnd->y / 2) + src_wnd->x) / 2; + pV = pV + (src_stride * (src_wnd->y / 2) + src_wnd->x) / 2; + + + /*complete source copy*/ + if ( (pitch_y == (s32) src_stride) && (src_wnd->w == src_width) && (src_wnd->h == src_height)) { + assert(!src_wnd->x); + assert(!src_wnd->y); + memcpy(pYD, pY, sizeof(unsigned char)*src_width*src_height); + memcpy(pVD, pV, sizeof(unsigned char)*src_width*src_height/4); + memcpy(pUD, pU, sizeof(unsigned char)*src_width*src_height/4); + } else { + u32 i; + unsigned char *dst, *src, *dst2, *src2, *dst3, *src3; + + src = pY; + dst = pYD; + + src2 = (pixel_format != GF_PIXEL_YV12) ? pU : pV; + dst2 = pVD; + src3 = (pixel_format != GF_PIXEL_YV12) ? pV : pU; + dst3 = pUD; + for (i=0; i<src_wnd->h; i++) { + memcpy(dst, src, src_wnd->w); + src += src_stride; + dst += pitch_y; + if (i<src_wnd->h/2) { + memcpy(dst2, src2, src_wnd->w/2); + src2 += src_stride/2; + dst2 += pitch_y/2; + memcpy(dst3, src3, src_wnd->w/2); + src3 += src_stride/2; + dst3 += pitch_y/2; + } + } + } +} + +static GF_Err SDL_Blit(GF_VideoOutput *dr, GF_VideoSurface *video_src, GF_Window *src_wnd, GF_Window *dst_wnd, u32 overlay_type) +{ + SDLVID(); + u32 amask = 0; + u32 bpp, i; + u8 *dst, *src; + SDL_Rect srcrc, dstrc; + SDL_Surface **pool; + + if (overlay_type) { + if (!video_src) { + if (ctx->yuv_overlay) { + SDL_FreeYUVOverlay(ctx->yuv_overlay); + ctx->yuv_overlay=NULL; + } + return GF_OK; + } + if (!ctx->yuv_overlay || (ctx->yuv_overlay->w != src_wnd->w) || (ctx->yuv_overlay->h != src_wnd->h) ) { + if (ctx->yuv_overlay) SDL_FreeYUVOverlay(ctx->yuv_overlay); + + ctx->yuv_overlay = SDL_CreateYUVOverlay(src_wnd->w, src_wnd->h, SDL_YV12_OVERLAY, ctx->screen); + if (!ctx->yuv_overlay) return GF_NOT_SUPPORTED; + } + /*copy pixels*/ + SDL_LockYUVOverlay(ctx->yuv_overlay); + + copy_yuv(ctx->yuv_overlay->pixels[0], ctx->yuv_overlay->pixels[1], ctx->yuv_overlay->pixels[2], GF_PIXEL_YV12, ctx->yuv_overlay->pitches[0], + video_src->video_buffer, video_src->pitch_y, video_src->pixel_format, + video_src->width, video_src->height, src_wnd); + + SDL_UnlockYUVOverlay(ctx->yuv_overlay); + + dstrc.w = dst_wnd->w; + dstrc.h = dst_wnd->h; + dstrc.x = dst_wnd->x; + dstrc.y = dst_wnd->y; + SDL_DisplayYUVOverlay(ctx->yuv_overlay, &dstrc); + return GF_OK; + } + + /*SDL doesn't support stretching ...*/ + if ((src_wnd->w != dst_wnd->w) || (src_wnd->h!=dst_wnd->h)) return GF_NOT_SUPPORTED; + + switch (video_src->pixel_format) { + case GF_PIXEL_RGB_24: + pool = &ctx->pool_rgb; + bpp = 3; + break; + case GF_PIXEL_RGBA: + pool = &ctx->pool_rgba; + amask = 0xFF000000; + bpp = 4; + break; + default: + return GF_NOT_SUPPORTED; + } + + if (! *pool || ((*pool)->w < src_wnd->w) || ((*pool)->h < src_wnd->h) ) { + if ((*pool)) SDL_FreeSurface((*pool)); + (*pool) = SDL_CreateRGBSurface(ctx->use_systems_memory ? SDL_SWSURFACE : SDL_HWSURFACE, + src_wnd->w, src_wnd->h, 8*bpp, + 0x000000FF, 0x0000FF00, 0x00FF0000, amask); + if (! (*pool) ) return GF_IO_ERR; + } + + SDL_LockSurface(*pool); + + dst = (u8 *) ( (*pool)->pixels); + src = video_src->video_buffer + video_src->pitch_y*src_wnd->y + src_wnd->x*bpp; + for (i=0; i<src_wnd->h; i++) { + memcpy(dst, src, bpp * src_wnd->w); + src += video_src->pitch_y; + dst += (*pool)->pitch; + } + SDL_UnlockSurface(*pool); + + srcrc.w = src_wnd->w; + srcrc.h = src_wnd->h; + srcrc.x = 0; + srcrc.y = 0; + + dstrc.w = dst_wnd->w; + dstrc.h = dst_wnd->h; + dstrc.x = dst_wnd->x; + dstrc.y = dst_wnd->y; + + SDL_BlitSurface(*pool, &srcrc, ctx->back_buffer, &dstrc); + return GF_OK; +} + void *SDL_NewVideo() @@ -906,13 +1089,15 @@ void *SDL_NewVideo() SDLVidCtx *ctx; GF_VideoOutput *driv; - driv = malloc(sizeof(GF_VideoOutput)); + driv = gf_malloc(sizeof(GF_VideoOutput)); memset(driv, 0, sizeof(GF_VideoOutput)); GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "SDL Video Output", "gpac distribution"); - ctx = malloc(sizeof(SDLVidCtx)); + ctx = gf_malloc(sizeof(SDLVidCtx)); memset(ctx, 0, sizeof(SDLVidCtx)); +#ifdef SDL_WINDOW_THREAD ctx->sdl_th = gf_th_new("SDLVideo"); +#endif ctx->evt_mx = gf_mx_new("SDLEvents"); driv->opaque = ctx; @@ -925,11 +1110,26 @@ void *SDL_NewVideo() driv->hw_caps |= GF_VIDEO_HW_OPENGL; /*no YUV hardware blitting in SDL (only overlays)*/ - - /*NO BLIT in SDL (we rely on GPAC to do it by soft)*/ - driv->Blit = NULL; + driv->hw_caps |= GF_VIDEO_HW_HAS_YUV_OVERLAY | GF_VIDEO_HW_HAS_RGB | GF_VIDEO_HW_HAS_RGBA; + driv->Blit = SDL_Blit; driv->LockBackBuffer = SDLVid_LockBackBuffer; driv->LockOSContext = NULL; + + /*color keying with overlays are not supported in SDL ...*/ +#if 0 + /*get YUV overlay key*/ + opt = gf_modules_get_option((GF_BaseInterface *)driv, "Video", "OverlayColorKey"); + /*no set is the default*/ + if (!opt) { + opt = "0101FE"; + gf_modules_set_option((GF_BaseInterface *)driv, "Video", "OverlayColorKey", "0101FE"); + } + sscanf(opt, "%06x", &driv->overlay_color_key); + if (driv->overlay_color_key) driv->overlay_color_key |= 0xFF000000; + GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[SDL Out] YUV Overlays enabled - ColorKey enabled: %s (key %x)\n", + driv->overlay_color_key ? "Yes" : "No", driv->overlay_color_key + )); +#endif return driv; } @@ -937,9 +1137,11 @@ void SDL_DeleteVideo(void *ifce) { GF_VideoOutput *dr = (GF_VideoOutput *)ifce; SDLVID(); +#ifdef SDL_WINDOW_THREAD gf_th_del(ctx->sdl_th); +#endif gf_mx_del(ctx->evt_mx); - free(ctx); - free(dr); + gf_free(ctx); + gf_free(dr); } diff --git a/modules/soft_raster/Makefile b/modules/soft_raster/Makefile index 459dcbb..56de8dc 100644 --- a/modules/soft_raster/Makefile +++ b/modules/soft_raster/Makefile @@ -27,21 +27,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_soft_raster.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols rast_soft.def -endif - -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) +#LDFLAGS+=-export-symbols rast_soft.def endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_soft_raster-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/soft_raster/ftgrays.c b/modules/soft_raster/ftgrays.c index 2fb9bfd..b49f2c3 100644 --- a/modules/soft_raster/ftgrays.c +++ b/modules/soft_raster/ftgrays.c @@ -159,7 +159,7 @@ static GFINLINE void gray_record_cell( TRaster *raster ) if (y>=0) { AAScanline *sl = &raster->scanlines[y]; if (sl->num >= sl->alloc) { - sl->cells = (AACell*)realloc(sl->cells, sizeof(AACell)* (sl->alloc + AA_CELL_STEP_ALLOC)); + sl->cells = (AACell*)gf_realloc(sl->cells, sizeof(AACell)* (sl->alloc + AA_CELL_STEP_ALLOC)); sl->alloc += AA_CELL_STEP_ALLOC; } cell = &sl->cells[sl->num]; @@ -726,7 +726,7 @@ int evg_raster_render(EVG_Raster raster, EVG_Raster_Params* params) size_y = raster->max_ey - raster->min_ey; if (raster->max_lines < size_y) { - raster->scanlines = (AAScanline*)realloc(raster->scanlines, sizeof(AAScanline)*size_y); + raster->scanlines = (AAScanline*)gf_realloc(raster->scanlines, sizeof(AAScanline)*size_y); memset(&raster->scanlines[raster->max_lines], 0, sizeof(AAScanline)*(size_y-raster->max_lines) ); raster->max_lines = size_y; } @@ -753,9 +753,9 @@ int evg_raster_render(EVG_Raster raster, EVG_Raster_Params* params) #if 0 for (i=0; i<raster->max_lines; i++) { - free(raster->scanlines[i].cells); + gf_free(raster->scanlines[i].cells); } - free(raster->scanlines); + gf_free(raster->scanlines); raster->scanlines = 0; raster->max_lines = 0; #endif @@ -774,10 +774,10 @@ void evg_raster_del(EVG_Raster raster) { int i; for (i=0; i<raster->max_lines; i++) { - free(raster->scanlines[i].cells); + gf_free(raster->scanlines[i].cells); } - free(raster->scanlines); - free(raster); + gf_free(raster->scanlines); + gf_free(raster); } /* END */ diff --git a/modules/soft_raster/rast_soft.def b/modules/soft_raster/rast_soft.def deleted file mode 100644 index 7b6dded..0000000 --- a/modules/soft_raster/rast_soft.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_soft_raster.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/soft_raster/rast_soft.h b/modules/soft_raster/rast_soft.h index 7653352..04bd70e 100644 --- a/modules/soft_raster/rast_soft.h +++ b/modules/soft_raster/rast_soft.h @@ -119,7 +119,8 @@ struct _evg_surface /*surface info*/ char *pixels; u32 pixelFormat, BPP; - u32 width, height, stride; + u32 width, height; + s32 pitch_x, pitch_y; Bool center_coords; /*color buffer for variable stencils - size of width*/ @@ -144,8 +145,10 @@ struct _evg_surface void *raster_cbk; /*fills line pixels without any blending operation*/ void (*raster_fill_run_no_alpha)(void *cbk, u32 x, u32 y, u32 run_h_len, GF_Color color); - /*fills line pixels without blending operation - alpha combines both fill color and anti-aliasing blending*/ - void (*raster_fill_run_alpha)(void *cbk, u32 x, u32 y, u32 run_h_len, GF_Color color, u32 alpha); + /*fills line pixels with blending operation - alpha combines both fill color and anti-aliasing blending*/ + void (*raster_fill_run_alpha)(void *cbk, u32 x, u32 y, u32 run_h_len, GF_Color color, u8 alpha); + /*fills rectangle with or without blending operation - alpha combines both fill color and anti-aliasing blending*/ + void (*raster_fill_rectangle)(void *cbk, u32 x, u32 y, u32 width, u32 height, GF_Color color); /*in solid color mode to speed things*/ @@ -289,7 +292,7 @@ GF_Err evg_stencil_create_texture(GF_STENCIL st, u32 width, u32 height, GF_Pixel GF_SURFACE evg_surface_new(GF_Raster2D *, Bool center_coords); void evg_surface_delete(GF_SURFACE _this); void evg_surface_detach(GF_SURFACE _this); -GF_Err evg_surface_attach_to_buffer(GF_SURFACE _this, char *pixels, u32 width, u32 height, u32 stride, GF_PixelFormat pixelFormat); +GF_Err evg_surface_attach_to_buffer(GF_SURFACE _this, char *pixels, u32 width, u32 height, s32 pitch_x, s32 pitch_y, GF_PixelFormat pixelFormat); GF_Err evg_surface_attach_to_texture(GF_SURFACE _this, GF_STENCIL sten); GF_Err evg_surface_attach_to_callbacks(GF_SURFACE _this, GF_RasterCallback *callbacks, u32 width, u32 height); @@ -317,6 +320,11 @@ void evg_rgb32_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf); void evg_rgb32_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf); void evg_rgb32_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf); +void evg_bgr32_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf); +void evg_bgr32_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf); +void evg_bgr32_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf); +GF_Err evg_surface_clear_bgr32(GF_SURFACE surf, GF_IRect rc, GF_Color col); + void evg_rgb_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf); void evg_rgb_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf); void evg_rgb_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf); diff --git a/modules/soft_raster/raster_565.c b/modules/soft_raster/raster_565.c index 229c0f6..5b6fbe8 100644 --- a/modules/soft_raster/raster_565.c +++ b/modules/soft_raster/raster_565.c @@ -56,7 +56,7 @@ static u16 overmask_565(u32 src, u16 dst, u32 alpha) return GF_COL_565(resr, resg, resb); } -void overmask_565_const_run(u32 src, u16 *dst, u32 count) +void overmask_565_const_run(u32 src, u16 *dst, s32 dst_pitch_x, u32 count) { u32 resr, resg, resb; u8 srca = (src >> 24) & 0xff; @@ -74,7 +74,7 @@ void overmask_565_const_run(u32 src, u16 *dst, u32 count) resg = mul255(srca, srcg - dstg) + dstg; resb = mul255(srca, srcb - dstb) + dstb; *dst = GF_COL_565(resr, resg, resb); - dst++; + dst = (u16*) (((u8*)dst)+dst_pitch_x); count--; } } @@ -84,25 +84,26 @@ void evg_565_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) u16 col565 = surf->fill_565; u32 col = surf->fill_col; register u32 a, fin, col_no_a; - u16 *dst = (u16 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; register s32 i; - u32 x, len; + u32 len; + s32 x; u8 aa_lev = surf->AALevel; col_no_a = col&0x00FFFFFF; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x; + x = spans[i].x * surf->pitch_x; len = spans[i].len; if (spans[i].coverage != 0xFF) { a = mul255(0xFF, spans[i].coverage); fin = (a<<24) | (col_no_a); - overmask_565_const_run(fin, &dst[x], len); + overmask_565_const_run(fin, (u16*) (dst+x), surf->pitch_x, len); } else { while (len--) { - dst[x] = col565; - x++; + *(u16*) (dst + x) = col565; + x+=surf->pitch_x; } } } @@ -110,7 +111,7 @@ void evg_565_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) void evg_565_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u16 *dst = (u16 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; u32 col = surf->fill_col; register u32 a, fin, col_no_a; register s32 i; @@ -122,48 +123,49 @@ void evg_565_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) if (spans[i].coverage<aa_lev) continue; fin = mul255(a, spans[i].coverage); fin = (fin<<24) | col_no_a; - overmask_565_const_run(fin, &dst[spans[i].x], spans[i].len); + overmask_565_const_run(fin, (u16*) (dst + spans[i].x * surf->pitch_x), surf->pitch_x, spans[i].len); } } void evg_565_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u16 *dst = (u16 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; register u8 spanalpha, col_a; - register s32 i; - register u32 x, len; + register s32 i, x; + register u32 len; register u32 *col; u8 aa_lev = surf->AALevel; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x; len = spans[i].len; spanalpha = spans[i].coverage; - surf->sten->fill_run(surf->sten, surf, x, y, len); + surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len); col = surf->stencil_pix_run; + x = spans[i].x * surf->pitch_x; while (len--) { col_a = GF_COL_A(*col); if (col_a) { if ((spanalpha!=0xFF) || (col_a != 0xFF)) { - dst[x] = overmask_565(*col, dst[x], spanalpha); + *(u16*) (dst+x) = overmask_565(*col, *(u16*) (dst+x), spanalpha); } else { - dst[x] = GF_COL_TO_565(*col); + *(u16*) (dst+x) = GF_COL_TO_565(*col); } } col++; - x ++; + x += surf->pitch_x; } } } GF_Err evg_surface_clear_565(GF_SURFACE surf, GF_IRect rc, GF_Color col) { - register u32 x, y, w, h, st, sx, sy; + register u32 x, y, w, h, sx, sy; + s32 st; register u16 val; EVGSurface *_this = (EVGSurface *)surf; - st = _this->stride; + st = _this->pitch_y; h = rc.height; w = rc.width; @@ -174,9 +176,10 @@ GF_Err evg_surface_clear_565(GF_SURFACE surf, GF_IRect rc, GF_Color col) val = GF_COL_TO_565(col); for (y=0; y<h; y++) { - register u16 *data = (u16 *) (_this->pixels + (sy+y) * _this->stride + 2*sx); + u8 *data = _this->pixels + (sy+y) * st + _this->pitch_x*sx; for (x=0; x<w; x++) { - *data++ = val; + *(u16*) data = val; + data += _this->pitch_x; } } return GF_OK; @@ -208,7 +211,7 @@ static u16 overmask_555(u32 src, u16 dst, u32 alpha) return GF_COL_555(resr, resg, resb); } -static void overmask_555_const_run(u32 src, u16 *dst, u32 count) +static void overmask_555_const_run(u32 src, u16 *dst, s32 dst_pitch_x, u32 count) { u32 resr, resg, resb; u8 srca = (src >> 24) & 0xff; @@ -226,7 +229,7 @@ static void overmask_555_const_run(u32 src, u16 *dst, u32 count) resg = mul255(srca, srcg - dstg) + dstg; resb = mul255(srca, srcb - dstb) + dstb; *dst = GF_COL_555(resr, resg, resb); - dst++; + dst = (u16*) (((u8*)dst)+dst_pitch_x); count--; } } @@ -236,24 +239,24 @@ void evg_555_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) u16 col555 = surf->fill_555; u32 col = surf->fill_col; u32 a, fin, col_no_a; - u16 *dst = (u16 *) (surf->pixels + y * surf->stride); - s32 i; - u32 x, len; + u8 *dst = surf->pixels + y * surf->pitch_y; + s32 i, x; + u32 len; u8 aa_lev = surf->AALevel; col_no_a = col&0x00FFFFFF; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x; + x = spans[i].x * surf->pitch_x; len = spans[i].len; if (spans[i].coverage != 0xFF) { a = mul255(0xFF, spans[i].coverage); fin = (a<<24) | col_no_a; - overmask_555_const_run(fin, &dst[x], len); + overmask_555_const_run(fin, (u16*) (dst+x), surf->pitch_x, len); } else { while (len--) { - dst[x] = col555; - x++; + *(u16*) (dst+x) = col555; + x+=surf->pitch_x; } } } @@ -261,7 +264,7 @@ void evg_555_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) void evg_555_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u16 *dst = (u16 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_x; u32 col = surf->fill_col; u32 a, fin, col_no_a; s32 i; @@ -273,49 +276,48 @@ void evg_555_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) if (spans[i].coverage<aa_lev) continue; fin = mul255(a, spans[i].coverage); fin = (fin<<24) | col_no_a; - overmask_555_const_run(fin, &dst[spans[i].x], spans[i].len); + overmask_555_const_run(fin, (u16*) (dst + spans[i].x*surf->pitch_x), surf->pitch_x, spans[i].len); } } void evg_555_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u16 *dst = (u16 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; u8 spanalpha, col_a; - s32 i; - u32 x, len; + s32 i, x; + u32 len; u32 *col; u8 aa_lev = surf->AALevel; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x; len = spans[i].len; spanalpha = spans[i].coverage; - surf->sten->fill_run(surf->sten, surf, x, y, len); + surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len); col = surf->stencil_pix_run; + x = spans[i].x * surf->pitch_x; while (len--) { col_a = GF_COL_A(*col); if (col_a) { if ((spanalpha!=0xFF) || (col_a != 0xFF)) { - dst[x] = overmask_555(*col, dst[x], spanalpha); + *(u16*) (dst+x) = overmask_555(*col, *(u16*) (dst+x), spanalpha); } else { - dst[x] = GF_COL_TO_555(*col); + *(u16*) (dst+x) = GF_COL_TO_555(*col); } } col++; - x ++; + x += surf->pitch_x; } } } GF_Err evg_surface_clear_555(GF_SURFACE surf, GF_IRect rc, GF_Color col) { - u32 x, y, w, h, st, sx, sy; + u32 x, y, w, h, sx, sy; u16 val; EVGSurface *_this = (EVGSurface *)surf; - st = _this->stride; h = rc.height; w = rc.width; @@ -326,9 +328,10 @@ GF_Err evg_surface_clear_555(GF_SURFACE surf, GF_IRect rc, GF_Color col) val = GF_COL_TO_555(col); for (y=0; y<h; y++) { - u16 *data = (u16 *) (_this->pixels + (sy+y) * _this->stride + 2*sx); + u8 *data = _this->pixels + (sy+y) * _this->pitch_y + _this->pitch_x*sx; for (x=0; x<w; x++) { - *data++ = val; + *(u16*)data = val; + data += _this->pitch_x; } } return GF_OK; @@ -362,7 +365,7 @@ static u16 overmask_444(u32 src, u16 dst, u32 alpha) return GF_COL_444(resr, resg, resb); } -static void overmask_444_const_run(u32 src, u16 *dst, u32 count) +static void overmask_444_const_run(u32 src, u16 *dst, s32 dst_pitch_x, u32 count) { u32 resr, resg, resb; u8 srca = (src >> 24) & 0xff; @@ -380,7 +383,7 @@ static void overmask_444_const_run(u32 src, u16 *dst, u32 count) resg = mul255(srca, srcg - dstg) + dstg; resb = mul255(srca, srcb - dstb) + dstb; *dst = GF_COL_444(resr, resg, resb); - dst++; + dst = (u16*) (((u8*)dst)+dst_pitch_x); count--; } } @@ -390,24 +393,24 @@ void evg_444_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) u16 col444 = surf->fill_444; u32 col = surf->fill_col; u32 a, fin, col_no_a; - u16 *dst = (u16 *) (surf->pixels + y * surf->stride); - s32 i; - u32 x, len; + u8 *dst = surf->pixels + y * surf->pitch_y; + s32 i, x; + u32 len; u8 aa_lev = surf->AALevel; col_no_a = col&0x00FFFFFF; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x; + x = spans[i].x * surf->pitch_x; len = spans[i].len; if (spans[i].coverage != 0xFF) { a = mul255(0xFF, spans[i].coverage); fin = (a<<24) | col_no_a; - overmask_444_const_run(fin, &dst[x], len); + overmask_444_const_run(fin, (u16*) (dst+x), surf->pitch_x, len); } else { while (len--) { - dst[x] = col444; - x++; + *(u16*) (dst+x) = col444; + x+=surf->pitch_x; } } } @@ -415,7 +418,7 @@ void evg_444_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) void evg_444_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u16 *dst = (u16 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; u32 col = surf->fill_col; u32 a, fin, col_no_a; s32 i; @@ -427,50 +430,48 @@ void evg_444_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) if (spans[i].coverage<aa_lev) continue; fin = mul255(a, spans[i].coverage); fin = (fin<<24) | col_no_a; - overmask_444_const_run(fin, &dst[spans[i].x], spans[i].len); + overmask_444_const_run(fin, (u16*) (dst + spans[i].x*surf->pitch_x), surf->pitch_x, spans[i].len); } } void evg_444_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u16 *dst = (u16 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_x; u8 spanalpha, col_a; - s32 i; - u32 x, len; + s32 i, x; + u32 len; u32 *col; u8 aa_lev = surf->AALevel; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x; len = spans[i].len; spanalpha = spans[i].coverage; - surf->sten->fill_run(surf->sten, surf, x, y, len); + surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len); col = surf->stencil_pix_run; + x = spans[i].x + surf->pitch_x; while (len--) { col_a = GF_COL_A(*col); if (col_a) { if ((spanalpha!=0xFF) || (col_a != 0xFF)) { - dst[x] = overmask_444(*col, dst[x], spanalpha); + *(u16*) (dst+x) = overmask_444(*col, *(u16*) (dst+x), spanalpha); } else { - dst[x] = GF_COL_TO_444(*col); + *(u16*) (dst+x) = GF_COL_TO_444(*col); } } col++; - x ++; + x += surf->pitch_x; } } } GF_Err evg_surface_clear_444(GF_SURFACE surf, GF_IRect rc, GF_Color col) { - u32 x, y, w, h, st, sx, sy; + u32 x, y, w, h, sx, sy; u16 val; EVGSurface *_this = (EVGSurface *)surf; - st = _this->stride; - h = rc.height; w = rc.width; sx = rc.x; @@ -479,9 +480,10 @@ GF_Err evg_surface_clear_444(GF_SURFACE surf, GF_IRect rc, GF_Color col) val = GF_COL_TO_444(col); for (y=0; y<h; y++) { - u16 *data = (u16 *) (_this->pixels + (sy+y) * _this->stride + 2*sx); + u8 *data = _this->pixels + (sy+y) * _this->pitch_y + _this->pitch_x*sx; for (x=0; x<w; x++) { - *data++ = val; + *(u16*)data = val; + data += _this->pitch_x; } } return GF_OK; diff --git a/modules/soft_raster/raster_argb.c b/modules/soft_raster/raster_argb.c index 0e767d8..5a64015 100644 --- a/modules/soft_raster/raster_argb.c +++ b/modules/soft_raster/raster_argb.c @@ -66,7 +66,7 @@ static u32 overmask_argb(u32 src, u32 dst, u32 alpha) return (srca << 24) | (srcr << 16) | (srcg << 8) | (srcb); } -static void overmask_argb_const_run(u32 src, u32 *dst, u32 count) +static void overmask_argb_const_run(u32 src, u32 *dst, s32 dst_pitch_x, u32 count) { u32 resa ,resr, resg, resb; @@ -94,7 +94,7 @@ static void overmask_argb_const_run(u32 src, u32 *dst, u32 count) } else { *dst = src; } - dst++; + dst = (u32*) ( ((u8 *)dst) +dst_pitch_x); count--; } } @@ -103,25 +103,25 @@ void evg_argb_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { u32 col = surf->fill_col; u32 a, fin, col_no_a; - u32 *dst = (u32 *) (surf->pixels + y * surf->stride); - s32 i; - u32 x, len; + u8 *dst = surf->pixels + y * surf->pitch_y; + s32 i, x; + u32 len; u8 aa_lev = surf->AALevel; col_no_a = col & 0x00FFFFFF; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x; + x = spans[i].x * surf->pitch_x; len = spans[i].len; if (spans[i].coverage != 0xFF) { a = mul255(0xFF, spans[i].coverage); fin = (a<<24) | col_no_a; - overmask_argb_const_run(fin, &dst[x], len); + overmask_argb_const_run(fin, (u32 *) (dst + x), surf->pitch_x, len); } else { while (len--) { - dst[x] = col; - x ++; + * ((u32 *) (dst + x) ) = col; + x += surf->pitch_x; } } } @@ -129,7 +129,7 @@ void evg_argb_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) void evg_argb_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u32 *dst = (u32 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; u32 col = surf->fill_col; u32 a, fin, col_no_a; u8 aa_lev = surf->AALevel; @@ -141,38 +141,38 @@ void evg_argb_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) if (spans[i].coverage<aa_lev) continue; fin = mul255(a, spans[i].coverage); fin = (fin<<24) | col_no_a; - overmask_argb_const_run(fin, &dst[spans[i].x], spans[i].len); + overmask_argb_const_run(fin, (u32 *) (dst + surf->pitch_x*spans[i].x), surf->pitch_x, spans[i].len); } } void evg_argb_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u32 *dst = (u32 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; u8 spanalpha, col_a; - s32 i; - u32 x, len; + s32 i, x; + u32 len; u32 *col; u8 aa_lev = surf->AALevel; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x; len = spans[i].len; spanalpha = spans[i].coverage; - surf->sten->fill_run(surf->sten, surf, x, y, len); + surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len); + x = spans[i].x * surf->pitch_x; col = surf->stencil_pix_run; while (len--) { col_a = GF_COL_A(*col); if (col_a) { if ((spanalpha!=0xFF) || (col_a != 0xFF)) { - dst[x] = overmask_argb(*col, dst[x], spanalpha); + *(u32*) (dst + x) = overmask_argb(*col, *(u32*) (dst + x) , spanalpha); } else { - dst[x] = *col; + *(u32*) (dst + x) = *col; } } col++; - x ++; + x += surf->pitch_x; } } } @@ -180,9 +180,10 @@ void evg_argb_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) GF_Err evg_surface_clear_argb(GF_SURFACE surf, GF_IRect rc, GF_Color col) { u32 *data; - u32 x, y, w, h, st, sx, sy; + u32 x, y, w, h, sx, sy; + s32 st; EVGSurface *_this = (EVGSurface *)surf; - st = _this->stride; + st = _this->pitch_y; h = rc.height; w = rc.width; @@ -190,9 +191,10 @@ GF_Err evg_surface_clear_argb(GF_SURFACE surf, GF_IRect rc, GF_Color col) sy = rc.y; for (y = 0; y < h; y++) { - data = (u32 *) (_this ->pixels + (sy+y)* st + 4*sx); + data = (u32 *) (_this ->pixels + (sy+y)* st + _this->pitch_x*sx); for (x = 0; x < w; x++) { - *data++ = col; + *data = col; + data = (u32*) ( ((u8*)data)+_this->pitch_x); } } return GF_OK; @@ -222,7 +224,7 @@ static u32 overmask_rgb32(u32 src, u32 dst, u32 alpha) return (0xFF << 24) | (resr << 16) | (resg << 8) | resb; } -GFINLINE void overmask_rgb32_const_run(u32 src, u32 *dst, u32 count) +GFINLINE void overmask_rgb32_const_run(u32 src, u32 *dst, s32 dst_pitch_x, u32 count) { u32 val, res; s32 srca = (src>>24) & 0xff; @@ -240,7 +242,7 @@ GFINLINE void overmask_rgb32_const_run(u32 src, u32 *dst, u32 count) res <<=8; res |= srcb + ((inva*((val) & 0xff))>>8); *dst = res; - dst++; + dst = (u32*) ( ((u8*)dst) + dst_pitch_x); count--; } } @@ -249,9 +251,9 @@ void evg_rgb32_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { u32 col = surf->fill_col; u32 fin, col_no_a, col2, spana; - u32 *dst = (u32 *) (surf->pixels + y * surf->stride); - s32 i; - u32 x, len; + u8 *dst = surf->pixels + y * surf->pitch_y; + s32 i, x; + u32 len; u8 aa_lev = surf->AALevel; col_no_a = col & 0x00FFFFFF; @@ -259,16 +261,16 @@ void evg_rgb32_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) for (i=0; i<count; i++) { spana = spans[i].coverage; if (spana<aa_lev) continue; - x = spans[i].x; + x = spans[i].x * surf->pitch_x; len = spans[i].len; if (spana != 0xFF) { fin = (spana<<24) | col_no_a; - overmask_rgb32_const_run(fin, &dst[x], len); + overmask_rgb32_const_run(fin, (u32*) (dst + x), surf->pitch_x, len); } else { while (len--) { - dst[x] = col2; - x ++; + *(u32*) (dst + x) = col2; + x += surf->pitch_x; } } } @@ -276,7 +278,7 @@ void evg_rgb32_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) void evg_rgb32_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u32 *dst = (u32 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; u32 col = surf->fill_col; u32 a, fin, col_no_a; u8 aa_lev = surf->AALevel; @@ -288,47 +290,48 @@ void evg_rgb32_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) if (spans[i].coverage<aa_lev) continue; fin = mul255(a, spans[i].coverage); fin = (fin<<24) | col_no_a; - overmask_rgb32_const_run(fin, &dst[spans[i].x], spans[i].len); + overmask_rgb32_const_run(fin, (u32*) (dst + surf->pitch_x*spans[i].x), surf->pitch_x, spans[i].len); } } void evg_rgb32_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u32 *dst = (u32 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; u8 spanalpha, col_a; - s32 i; - u32 x, len; + s32 i, x; + u32 len; u32 *col; u8 aa_lev = surf->AALevel; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x; len = spans[i].len; spanalpha = spans[i].coverage; - surf->sten->fill_run(surf->sten, surf, x, y, len); + surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len); col = surf->stencil_pix_run; + x = spans[i].x * surf->pitch_x; while (len--) { col_a = GF_COL_A(*col); if (col_a) { if ((spanalpha!=0xFF) || (col_a != 0xFF)) { - dst[x] = overmask_rgb32(*col, dst[x], spanalpha); + *(u32*)(dst+x) = overmask_rgb32(*col, *(u32*)(dst+x), spanalpha); } else { - dst[x] = *col; + *(u32*)(dst+x) = *col; } } col++; - x ++; + x += surf->pitch_x; } } } GF_Err evg_surface_clear_rgb32(GF_SURFACE surf, GF_IRect rc, GF_Color col) { - u32 x, y, w, h, st, sx, sy; + u32 x, y, w, h, sx, sy; + s32 st; EVGSurface *_this = (EVGSurface *)surf; - st = _this->stride; + st = _this->pitch_x; h = rc.height; w = rc.width; @@ -337,9 +340,169 @@ GF_Err evg_surface_clear_rgb32(GF_SURFACE surf, GF_IRect rc, GF_Color col) col = 0xFF000000 | (col & 0x00FFFFFF); for (y = 0; y < h; y++) { - u32 *data = (u32 *) (_this ->pixels + (y + sy) * st + 4*sx); + u32 *data = (u32 *) (_this ->pixels + (y + sy) * st + _this->pitch_x*sx); + for (x = 0; x < w; x++) { + *data = col; + data = (u32*) (((u8*)data)+_this->pitch_x); + } + } + return GF_OK; +} + + + +/* + 32 bit BGR +*/ + +static u32 overmask_bgr32(u32 src, u32 dst, u32 alpha) +{ + u32 resr, resg, resb; + + s32 srca = (src >> 24) & 0xff; + s32 srcr = (src >> 16) & 0xff; + s32 srcg = (src >> 8) & 0xff; + s32 srcb = (src >> 0) & 0xff; + + s32 dstb = (dst >> 16) & 0xff; + s32 dstg = (dst >> 8) & 0xff; + s32 dstr = (dst) & 0xff; + + srca = mul255(srca, alpha); + resr = mul255(srca, srcr - dstr) + dstr; + resg = mul255(srca, srcg - dstg) + dstg; + resb = mul255(srca, srcb - dstb) + dstb; + return (0xFF << 24) | (resb << 16) | (resg << 8) | resr; +} + +GFINLINE void overmask_bgr32_const_run(u32 src, u32 *dst, s32 dst_pitch_x, u32 count) +{ + u32 val, res; + s32 srca = (src>>24) & 0xff; + u32 srcr = mul255(srca, ((src >> 16) & 0xff)) ; + u32 srcg = mul255(srca, ((src >> 8) & 0xff)) ; + u32 srcb = mul255(srca, ((src) & 0xff)) ; + u32 inva = 1 + 0xFF - srca; + + while (count) { + val = *dst; + res = 0xFF00; + res |= srcb + ((inva*((val >> 16) & 0xff))>>8); + res <<=8; + res |= srcg + ((inva*((val >> 8) & 0xff))>>8); + res <<=8; + res |= srcr + ((inva*((val) & 0xff))>>8); + *dst = res; + dst = (u32*) ( ((u8*)dst) + dst_pitch_x); + count--; + } +} + +void evg_bgr32_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) +{ + u32 col = surf->fill_col; + u32 fin, col_no_a, col2, spana; + u8 *dst = surf->pixels + y * surf->pitch_y; + u8 r, g, b; + s32 i, x; + u32 len; + u8 aa_lev = surf->AALevel; + + col_no_a = col & 0x00FFFFFF; + r = GF_COL_R(col); + g = GF_COL_G(col); + b = GF_COL_B(col); + col2 = GF_COL_ARGB(0xFF, b, g, r); + for (i=0; i<count; i++) { + spana = spans[i].coverage; + if (spana<aa_lev) continue; + x = spans[i].x * surf->pitch_x; + len = spans[i].len; + + if (spana != 0xFF) { + fin = (spana<<24) | col_no_a; + overmask_bgr32_const_run(fin, (u32*) (dst + x), surf->pitch_x, len); + } else { + while (len--) { + *(u32*) (dst + x) = col2; + x += surf->pitch_x; + } + } + } +} + +void evg_bgr32_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) +{ + u8 *dst = surf->pixels + y * surf->pitch_y; + u32 col = surf->fill_col; + u32 a, fin, col_no_a; + u8 aa_lev = surf->AALevel; + s32 i; + + a = (col>>24)&0xFF; + col_no_a = col & 0x00FFFFFF; + for (i=0; i<count; i++) { + if (spans[i].coverage<aa_lev) continue; + fin = mul255(a, spans[i].coverage); + fin = (fin<<24) | col_no_a; + overmask_bgr32_const_run(fin, (u32*) (dst + surf->pitch_x*spans[i].x), surf->pitch_x, spans[i].len); + } +} + + +void evg_bgr32_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) +{ + u8 *dst = surf->pixels + y * surf->pitch_y; + u8 spanalpha, col_a; + s32 i, x; + u32 len; + u32 *col; + u8 aa_lev = surf->AALevel; + + for (i=0; i<count; i++) { + if (spans[i].coverage<aa_lev) continue; + len = spans[i].len; + spanalpha = spans[i].coverage; + surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len); + col = surf->stencil_pix_run; + x = spans[i].x * surf->pitch_x; + while (len--) { + col_a = GF_COL_A(*col); + if (col_a) { + if ((spanalpha!=0xFF) || (col_a != 0xFF)) { + *(u32*)(dst+x) = overmask_bgr32(*col, *(u32*)(dst+x), spanalpha); + } else { + *(u32*)(dst+x) = *col; + } + } + col++; + x += surf->pitch_x; + } + } +} + +GF_Err evg_surface_clear_bgr32(GF_SURFACE surf, GF_IRect rc, GF_Color col) +{ + u32 x, y, w, h, sx, sy; + u8 r,g,b; + s32 st; + EVGSurface *_this = (EVGSurface *)surf; + st = _this->pitch_x; + + h = rc.height; + w = rc.width; + sx = rc.x; + sy = rc.y; + + r = GF_COL_R(col); + g = GF_COL_G(col); + b = GF_COL_B(col); + col = GF_COL_ARGB(0xFF, b, g, r); + for (y = 0; y < h; y++) { + u32 *data = (u32 *) (_this ->pixels + (y + sy) * _this->pitch_y + st*sx); for (x = 0; x < w; x++) { - *data++ = col; + *data = col; + data = (u32*) (((u8*)data)+st); } } return GF_OK; @@ -375,7 +538,7 @@ static void overmask_rgba(u32 src, char *dst, u32 alpha) } } -static void overmask_rgba_const_run(u32 src, char *dst, u32 count) +static void overmask_rgba_const_run(u32 src, char *dst, s32 dst_pitch_x, u32 count) { u8 srca = GF_COL_A(src); u8 srcr = GF_COL_R(src); @@ -399,7 +562,7 @@ static void overmask_rgba_const_run(u32 src, char *dst, u32 count) dst[2] = srcb; dst[3] = srca; } - dst+=4; + dst+=dst_pitch_x; count--; } } @@ -409,7 +572,7 @@ void evg_rgba_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) u32 col = surf->fill_col; u32 new_a, fin, col_no_a; u8 a, r, g, b; - char *dst = (surf->pixels + y * surf->stride); + char *dst = surf->pixels + y * surf->pitch_y; char *p; s32 i; u32 len; @@ -423,20 +586,20 @@ void evg_rgba_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - p = dst + spans[i].x*4; + p = dst + spans[i].x*surf->pitch_x; len = spans[i].len; if (spans[i].coverage != 0xFF) { new_a = spans[i].coverage; fin = (new_a<<24) | col_no_a; - overmask_rgba_const_run(fin, p, len); + overmask_rgba_const_run(fin, p, surf->pitch_x, len); } else { while (len--) { *(p) = r; *(p+1) = g; *(p+2) = b; *(p+3) = a; - p += 4; + p += surf->pitch_x; } } } @@ -444,7 +607,7 @@ void evg_rgba_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) void evg_rgba_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u32 *dst = (u32 *) (surf->pixels + y * surf->stride); + u8 *dst = surf->pixels + y * surf->pitch_y; u32 a, fin, col_no_a; u8 aa_lev = surf->AALevel; s32 i; @@ -456,14 +619,14 @@ void evg_rgba_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) if (spans[i].coverage<aa_lev) continue; fin = mul255(a, spans[i].coverage); fin = (fin<<24) | col_no_a; - overmask_rgba_const_run(fin, (char*) &dst[spans[i].x], spans[i].len); + overmask_rgba_const_run(fin, dst + spans[i].x*surf->pitch_x, surf->pitch_x, spans[i].len); } } void evg_rgba_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - u8 *dst = surf->pixels + y * surf->stride; + u8 *dst = surf->pixels + y * surf->pitch_y; u8 *p; u8 spanalpha, col_a; s32 i; @@ -473,7 +636,7 @@ void evg_rgba_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - p = dst + spans[i].x * 4; + p = dst + spans[i].x * surf->pitch_x; len = spans[i].len; spanalpha = spans[i].coverage; surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len); @@ -492,7 +655,7 @@ void evg_rgba_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) } } col++; - p += 4; + p += surf->pitch_x; } } } @@ -501,13 +664,13 @@ GF_Err evg_surface_clear_rgba(GF_SURFACE surf, GF_IRect rc, GF_Color col) { u8 *data; u8 a, r, g, b; - u32 x, y, w, h, st, sx, sy; + u32 x, y, w, h, sy; + s32 st; EVGSurface *_this = (EVGSurface *)surf; - st = _this->stride; + st = _this->pitch_y; h = rc.height; w = rc.width; - sx = 4 * rc.x; sy = rc.y; a = GF_COL_A(col); @@ -515,9 +678,9 @@ GF_Err evg_surface_clear_rgba(GF_SURFACE surf, GF_IRect rc, GF_Color col) g = GF_COL_G(col); b = GF_COL_B(col); - if (a) { + if (a || (_this->pitch_x !=4) ) { for (y = 0; y < h; y++) { - data = (_this ->pixels + (sy+y)* st + sx); + data = (_this ->pixels + (sy+y)* st + _this->pitch_x * rc.x); for (x = 0; x < w; x++) { *(data) = r; *(data+1) = g; @@ -529,7 +692,7 @@ GF_Err evg_surface_clear_rgba(GF_SURFACE surf, GF_IRect rc, GF_Color col) } else { u32 sw = 4*w; for (y = 0; y < h; y++) { - memset(_this ->pixels + (sy+y)* st + sx, 0, sizeof(char)*sw); + memset(_this ->pixels + (sy+y)* st + _this->pitch_x * rc.x, 0, sizeof(char)*sw); } } return GF_OK; diff --git a/modules/soft_raster/raster_load.c b/modules/soft_raster/raster_load.c index 40b9a21..d395186 100644 --- a/modules/soft_raster/raster_load.c +++ b/modules/soft_raster/raster_load.c @@ -60,6 +60,7 @@ GF_Raster2D *EVG_LoadRenderer() dr->surface_set_clipper = evg_surface_set_clipper; dr->surface_set_path = evg_surface_set_path; dr->surface_fill = evg_surface_fill; + dr->surface_attach_to_callbacks = evg_surface_attach_to_callbacks; dr->surface_flush = NULL; dr->surface_clear = evg_surface_clear; return dr; @@ -67,16 +68,19 @@ GF_Raster2D *EVG_LoadRenderer() void EVG_ShutdownRenderer(GF_Raster2D *dr) { - free(dr); + gf_free(dr); } #ifndef GPAC_STANDALONE_RENDER_2D GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_RASTER_2D_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_RASTER_2D_INTERFACE, + 0 + }; + return si; } GF_EXPORT diff --git a/modules/soft_raster/raster_rgb.c b/modules/soft_raster/raster_rgb.c index 36061d9..c3e3eac 100644 --- a/modules/soft_raster/raster_rgb.c +++ b/modules/soft_raster/raster_rgb.c @@ -54,7 +54,7 @@ static void overmask_rgb(u32 src, char *dst, u32 alpha) *(dst+2) = mul255(srca, srcb - dstb) + dstb; } -static void overmask_rgb_const_run(u32 src, char *dst, u32 count) +static void overmask_rgb_const_run(u32 src, char *dst, s32 dst_pitch_x, u32 count) { u8 srca = (src >> 24) & 0xff; u8 srcr = (src >> 16) & 0xff; @@ -68,7 +68,7 @@ static void overmask_rgb_const_run(u32 src, char *dst, u32 count) *dst = (u8) mul255(srca, srcr - dstr) + dstr; *(dst+1) = (u8) mul255(srca, srcg - dstg) + dstg; *(dst+2) = (u8) mul255(srca, srcb - dstb) + dstb; - dst += 3; + dst += dst_pitch_x; count--; } } @@ -77,10 +77,10 @@ void evg_rgb_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { u32 col = surf->fill_col; u32 a, fin, col_no_a; - char *dst = surf->pixels + y * surf->stride; + char *dst = surf->pixels + y * surf->pitch_y; char *p; s32 i; - u32 x, len, r, g, b; + u32 len, r, g, b; u8 aa_lev = surf->AALevel; r = GF_COL_R(col); @@ -90,20 +90,19 @@ void evg_rgb_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) col_no_a = col & 0x00FFFFFF; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x * 3; len = spans[i].len; - p = dst + x; + p = dst + spans[i].x * surf->pitch_x; if (spans[i].coverage != 0xFF) { a = mul255(0xFF, spans[i].coverage); fin = (a<<24) | col_no_a; - overmask_rgb_const_run(fin, p, len); + overmask_rgb_const_run(fin, p, surf->pitch_x, len); } else { while (len--) { *(p) = r; *(p + 1) = g; *(p + 2) = b; - p += 3; + p += surf->pitch_x; } } } @@ -111,7 +110,7 @@ void evg_rgb_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) void evg_rgb_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - char *dst = surf->pixels + y * surf->stride; + char *dst = surf->pixels + y * surf->pitch_y; u32 col = surf->fill_col; u32 a, fin, col_no_a; s32 i; @@ -123,17 +122,18 @@ void evg_rgb_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) if (spans[i].coverage<aa_lev) continue; fin = mul255(a, spans[i].coverage); fin = (fin<<24) | (col&0x00FFFFFF); - overmask_rgb_const_run(fin, dst + 3 * spans[i].x, spans[i].len); + overmask_rgb_const_run(fin, dst + surf->pitch_x * spans[i].x, surf->pitch_x, spans[i].len); } } void evg_rgb_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - char *dst = surf->pixels + y * surf->stride; + char *dst = surf->pixels + y * surf->pitch_y; u8 spanalpha, col_a; s32 i; - u32 x, len, bpp; + s32 x; + u32 len, bpp; u32 *col; u8 aa_lev = surf->AALevel; bpp = surf->BPP; @@ -144,30 +144,31 @@ void evg_rgb_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) spanalpha = spans[i].coverage; surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len); col = surf->stencil_pix_run; - x = 3*spans[i].x; + x = surf->pitch_x * spans[i].x; while (len--) { col_a = GF_COL_A(*col); if (col_a) { if ((spanalpha!=0xFF) || (col_a != 0xFF)) { overmask_rgb(*col, dst + x, spanalpha); } else { - dst[x] = GF_COL_R(*col); - dst[x+1] = GF_COL_G(*col); - dst[x+2] = GF_COL_B(*col); + *(dst + x) = GF_COL_R(*col); + *(dst + x + 1) = GF_COL_G(*col); + *(dst + x + 2) = GF_COL_B(*col); } } col++; - x += 3; + x += surf->pitch_x; } } } GF_Err evg_surface_clear_rgb(GF_SURFACE surf, GF_IRect rc, GF_Color col) { - u32 x, y, w, h, st, sx, sy; + u32 x, y, w, h, sx, sy; + s32 st; u8 r, g, b; EVGSurface *_this = (EVGSurface *)surf; - st = _this->stride; + st = _this->pitch_y; h = rc.height; w = rc.width; @@ -179,12 +180,12 @@ GF_Err evg_surface_clear_rgb(GF_SURFACE surf, GF_IRect rc, GF_Color col) b = GF_COL_B(col); for (y = 0; y < h; y++) { - char *data = _this ->pixels + (y + sy) * st + 3*sx; + char *data = _this ->pixels + (y + sy) * st + _this->pitch_x*sx; for (x = 0; x < w; x++) { *(data) = r; *(data+1) = g; *(data+2) = b; - data += 3; + data += _this->pitch_x; } } return GF_OK; @@ -213,7 +214,7 @@ static void overmask_bgr(u32 src, char *dst, u32 alpha) *(dst+2) = mul255(srca, srcr - dstr) + dstr; } -static void overmask_bgr_const_run(u32 src, char *dst, u32 count) +static void overmask_bgr_const_run(u32 src, char *dst, s32 dst_pitch_x, u32 count) { u8 srca = (src >> 24) & 0xff; u8 srcr = (src >> 16) & 0xff; @@ -227,7 +228,7 @@ static void overmask_bgr_const_run(u32 src, char *dst, u32 count) *dst = (u8) mul255(srca, srcb - dstb) + dstb; *(dst+1) = (u8) mul255(srca, srcg - dstg) + dstg; *(dst+2) = (u8) mul255(srca, srcr - dstr) + dstr; - dst += 3; + dst += dst_pitch_x; count--; } } @@ -236,10 +237,10 @@ void evg_bgr_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { u32 col = surf->fill_col; u32 a, fin, col_no_a; - char *dst = surf->pixels + y * surf->stride; + char *dst = surf->pixels + y * surf->pitch_y; char *p; s32 i; - u32 x, len, r, g, b; + u32 len, r, g, b; u8 aa_lev = surf->AALevel; r = GF_COL_R(col); @@ -249,20 +250,19 @@ void evg_bgr_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) col_no_a = col & 0x00FFFFFF; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x * 3; len = spans[i].len; - p = dst + x; + p = dst + spans[i].x * surf->pitch_x; if (spans[i].coverage != 0xFF) { a = mul255(0xFF, spans[i].coverage); fin = (a<<24) | col_no_a; - overmask_bgr_const_run(fin, p, len); + overmask_bgr_const_run(fin, p, surf->pitch_x, len); } else { while (len--) { *(p) = b; *(p + 1) = g; *(p + 2) = r; - p += 3; + p += surf->pitch_x; } } } @@ -270,7 +270,7 @@ void evg_bgr_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) void evg_bgr_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - char *dst = surf->pixels + y * surf->stride; + char *dst = surf->pixels + y * surf->pitch_y; u32 col = surf->fill_col; u32 a, fin, col_no_a; s32 i; @@ -282,24 +282,23 @@ void evg_bgr_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) if (spans[i].coverage<aa_lev) continue; fin = mul255(a, spans[i].coverage); fin = (fin<<24) | col_no_a; - overmask_bgr_const_run(fin, dst + 3 * spans[i].x, spans[i].len); + overmask_bgr_const_run(fin, dst + surf->pitch_x * spans[i].x, surf->pitch_x, spans[i].len); } } void evg_bgr_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) { - char *dst = surf->pixels + y * surf->stride; + char *dst = surf->pixels + y * surf->pitch_y; u8 spanalpha, col_a; - s32 i; - u32 x, len, bpp; + s32 i, x; + u32 len; u32 *col; u8 aa_lev = surf->AALevel; - bpp = surf->BPP; for (i=0; i<count; i++) { if (spans[i].coverage<aa_lev) continue; - x = spans[i].x * bpp; + x = spans[i].x * surf->pitch_x; len = spans[i].len; spanalpha = spans[i].coverage; surf->sten->fill_run(surf->sten, surf, x, y, len); @@ -310,23 +309,24 @@ void evg_bgr_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) if ((spanalpha!=0xFF) || (col_a != 0xFF)) { overmask_bgr(*col, dst + x, spanalpha); } else { - dst[x] = GF_COL_B(*col); - dst[x+1] = GF_COL_G(*col); - dst[x+2] = GF_COL_R(*col); + *(dst + x) = GF_COL_B(*col); + *(dst + x + 1) = GF_COL_G(*col); + *(dst + x + 2) = GF_COL_R(*col); } } col++; - x += 3; + x += surf->pitch_x; } } } GF_Err evg_surface_clear_bgr(GF_SURFACE surf, GF_IRect rc, GF_Color col) { - u32 x, y, w, h, st, sx, sy; + u32 x, y, w, h, sx, sy; + s32 st; u8 r, g, b; EVGSurface *_this = (EVGSurface *)surf; - st = _this->stride; + st = _this->pitch_y; h = rc.height; w = rc.width; @@ -338,7 +338,7 @@ GF_Err evg_surface_clear_bgr(GF_SURFACE surf, GF_IRect rc, GF_Color col) b = GF_COL_B(col); for (y = 0; y < h; y++) { - char *data = _this ->pixels + (y+sy) * st + 3*sx; + char *data = _this ->pixels + (y+sy) * st + _this->pitch_x*sx; for (x = 0; x < w; x++) { *(data) = b; *(data+1) = g; @@ -420,25 +420,3 @@ void evg_user_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf) } } -GF_Err evg_surface_clear_user(GF_SURFACE surf, GF_IRect rc, GF_Color col) -{ - u32 y, w, h, sx, sy, a; - EVGSurface *_this = (EVGSurface *)surf; - - h = rc.height; - w = rc.width; - sx = rc.x; - sy = rc.y; - a = GF_COL_A(col); - if (a==0xFF) { - for (y = 0; y < h; y++) { - _this->raster_fill_run_no_alpha(_this->raster_cbk, sx, y+sy, w, col); - } - } else { - col |= 0xFF000000; - for (y = 0; y < h; y++) { - _this->raster_fill_run_alpha(_this->raster_cbk, sx, y+sy, w, col, a); - } - } - return GF_OK; -} diff --git a/modules/soft_raster/stencil.c b/modules/soft_raster/stencil.c index 9fbe9ba..5a9026c 100644 --- a/modules/soft_raster/stencil.c +++ b/modules/soft_raster/stencil.c @@ -167,16 +167,16 @@ void evg_stencil_delete(GF_STENCIL st) case GF_STENCIL_SOLID: case GF_STENCIL_LINEAR_GRADIENT: case GF_STENCIL_RADIAL_GRADIENT: - free(_this); + gf_free(_this); return; case GF_STENCIL_TEXTURE: { EVG_Texture *tx = (EVG_Texture *)_this; /*destroy conversion buffer if any*/ - if ( tx->conv_buf) free( tx->conv_buf ); + if ( tx->conv_buf) gf_free( tx->conv_buf ); /*destroy local texture iof any*/ - if (tx->owns_texture && tx->pixels) free(tx->pixels); - free(_this); + if (tx->owns_texture && tx->pixels) gf_free(tx->pixels); + gf_free(_this); } return; } @@ -400,9 +400,10 @@ GF_Err evg_stencil_set_radial_gradient(GF_STENCIL st, Fixed cx, Fixed cy, Fixed Texture stencil - this is just a crude texture mapper, it lacks precision and filtering ... */ -#if 0 -static s32 -mul255(s32 a, s32 b) +#define USE_BILINEAR 0 + +#if USE_BILINEAR +static GFINLINE s32 mul255(s32 a, s32 b) { return ((a+1) * b) >> 8; } @@ -412,6 +413,8 @@ static u32 EVG_LERP(u32 c0, u32 c1, u8 t) s32 a1, r1, g1, b1; s32 a2, r2, g2, b2; + if (!t) return c0; + a0 = GF_COL_A(c0); r0 = GF_COL_R(c0); g0 = GF_COL_G(c0); @@ -429,24 +432,92 @@ static u32 EVG_LERP(u32 c0, u32 c1, u8 t) } #endif +static void bmp_untransform_coord(EVG_Texture *_this, s32 _x, s32 _y, Fixed *outx, Fixed *outy) +{ + u32 checkx, checky; + Fixed x, y, dim; + + /* reverse to texture coords*/ + x = INT2FIX(_x); + y = INT2FIX(_y); + gf_mx2d_apply_coords(&_this->smat, &x, &y); + + checkx = checky = 0; + if (ABS(x)< FIX_ONE/20) checkx = 1; + if (ABS(y)< FIX_ONE/20) checky = 1; + + /*we may have a numerical stability issues, try to figure out whether we are close from 0 or width/height*/ + if ( checkx || checky) { + Fixed tx, ty; + tx = INT2FIX(_x+1); + ty = INT2FIX(_y+1); + gf_mx2d_apply_coords(&_this->smat, &tx, &ty); + + if (checkx) { + if (tx<0) x = INT2FIX(_this->width - 1); + else x = 0; + } + if (checky) { + if (ty<0) y = INT2FIX(_this->height - 1); + else y = 0; + } + } + + dim = INT2FIX(_this->width); + if (_this->mod & GF_TEXTURE_REPEAT_S) { + if (x<0) { + while (x<0) x += dim; + } else { + while (x>dim) x -= dim; + } + } else { + if (x<-dim) { + x = 0; + } else if (x>dim) { + x = dim; + } + while (x<0) x+=dim; + } + + dim = INT2FIX(_this->height); + if (_this->mod & GF_TEXTURE_REPEAT_T) { + if (y<0) { + while (y<0) y += dim; + } else { + while (y>dim) y -= dim; + } + } else { + if (y<-dim) { + y = 0; + } else if (y>dim) { + y = dim; + } + while (y<0) y+=dim; + } + + *outx=x; + *outy=y; +} + static void bmp_fill_run(EVGStencil *p, EVGSurface *surf, s32 _x, s32 _y, u32 count) { - s32 cx; - u32 x0, y0, pix, replace_col; + s32 cx, x0, y0; + u32 pix, replace_col; Bool has_alpha, has_replace_cmat, has_cmat, repeat_s, repeat_t; Fixed x, y, _fd; +#if USE_BILINEAR + s32 incx, incy; +#endif u32 *data = surf->stencil_pix_run; EVG_Texture *_this = (EVG_Texture *) p; - /* reverse to texture coords*/ - x = INT2FIX(_x); - y = INT2FIX(_y); - gf_mx2d_apply_coords(&_this->smat, &x, &y); + bmp_untransform_coord(_this, _x, _y, &x, &y); + +#if USE_BILINEAR + incx = (_this->inc_x>0) ? 1 : -1; + incy = (_this->inc_y>0) ? 1 : -1; +#endif - /*ugly hack we may have a numerical stability issue*/ - if (ABS(x) < FIX_ONE/10) x = 0; - if (ABS(y) < FIX_ONE/10) y = 0; - _fd = INT2FIX(_this->width); repeat_s = _this->mod & GF_TEXTURE_REPEAT_S; if (!repeat_s && (x < - _fd)) x = 0; @@ -455,7 +526,7 @@ static void bmp_fill_run(EVGStencil *p, EVGSurface *surf, s32 _x, s32 _y, u32 co _fd = INT2FIX(_this->height); repeat_t = _this->mod & GF_TEXTURE_REPEAT_T; if (!repeat_t && (y < - _fd)) y = 0; - while (y<0) y += _fd; + while (y<0) y += _fd; y0 = (s32) FIX2INT(y); has_alpha = (_this->alpha != 255) ? 1 : 0; @@ -466,46 +537,71 @@ static void bmp_fill_run(EVGStencil *p, EVGSurface *surf, s32 _x, s32 _y, u32 co while (count) { x0 = FIX2INT(x); assert((s32)x0 >=0); - if (repeat_s) { x0 = (x0) % _this->width; } else { - x0 = MIN(x0, _this->width-1); + x0 = MIN(x0, (s32) _this->width - 1); } - x += _this->inc_x; - if (x<0) x+=INT2FIX(_this->width); y0 = FIX2INT(y); assert((s32)y0 >=0); if (repeat_t) { y0 = (y0) % _this->height; - } else if (y0 >= _this->height) + } else if (y0 >= (s32) _this->height) { y0 = _this->height-1; - y += _this->inc_y; - if (y<0) y+=INT2FIX(_this->height); + } pix = _this->tx_get_pixel(_this->pixels + _this->stride*y0 + _this->Bpp*x0); - + _x++; + bmp_untransform_coord(_this, _x, _y, &x, &y); + + if (x<0) x+=INT2FIX(_this->width); + if (y<0) y+=INT2FIX(_this->height); + /*bilinear filtering - disabled (too slow and not precise enough)*/ -#if 0 +#if USE_BILINEAR if (_this->filter==GF_TEXTURE_FILTER_HIGH_QUALITY) { - u32 p00, p01, p10, p11, x1, y1; + u32 p00, p01, p10, p11; + s32 x1, y1; u8 tx, ty; - x1 = (x0+1) % _this->width; - y1 = (y0+1) % _this->height; - p00 = pix; - p01 = _this->tx_get_pixel(_this->pixels + _this->stride*y0 + _this->Bpp*x1); - p10 = _this->tx_get_pixel(_this->pixels + _this->stride*y1 + _this->Bpp*x0); - p11 = _this->tx_get_pixel(_this->pixels + _this->stride*y1 + _this->Bpp*x1); - tx = FIX2INT(gf_muldiv(x, 255, _this->width) ); ty = FIX2INT(gf_muldiv(y, 255, _this->height) ); - p00 = EVG_LERP(p00, p01, tx); - p10 = EVG_LERP(p10, p11, tx); - pix = EVG_LERP(p00, p10, ty); + if (tx>120 || ty>120) { + x1 = (x0+incx); + if (x1<0) { + while (x1<0) x1 += _this->width; + } else { + x1 = x1 % _this->width; + } + y1 = (y0+incy); + if (y1<0) { + while (y1<0) y1+=_this->height; + } else { + y1 = y1 % _this->height; + } + if (incx>0) { + if (x1<x0) tx = 255-tx; + } else { + if (x1>x0) tx = 255-tx; + } + if (incy>0) { + if (y1<y0) ty = 255-ty; + } else { + if (y1>y0) ty = 255-ty; + } + + p00 = pix; + p01 = _this->tx_get_pixel(_this->pixels + _this->stride*y0 + _this->Bpp*x1); + p10 = _this->tx_get_pixel(_this->pixels + _this->stride*y1 + _this->Bpp*x0); + p11 = _this->tx_get_pixel(_this->pixels + _this->stride*y1 + _this->Bpp*x1); + + p00 = EVG_LERP(p00, p01, tx); + p10 = EVG_LERP(p10, p11, tx); + pix = EVG_LERP(p00, p10, ty); + } } #endif @@ -543,9 +639,17 @@ static void bmp_fill_run_straight(EVGStencil *p, EVGSurface *surf, s32 _x, s32 _ x = _this->smat.m[0]*_x + _this->smat.m[2]; y = _this->smat.m[4]*_y + _this->smat.m[5]; - /*ugly hack we may have a numerical stability issue*/ - if (ABS(x)< FIX_ONE/10) x = 0; - if (ABS(y)< FIX_ONE/10) y = 0; + /*we may have a numerical stability issues, try to figure out whether we are close from 0 or width/height*/ + if (ABS(x)< FIX_ONE/10) { + Fixed test = _this->smat.m[0]*(_x+1) + _this->smat.m[2]; + if (test<0) x = INT2FIX(_this->width - 1); + else x = 0; + } + if (ABS(y)< FIX_ONE/10) { + Fixed test = _this->smat.m[4]*(_y+1) + _this->smat.m[5]; + if (test<0) y = INT2FIX(_this->height - 1); + else y = 0; + } /* and move in absolute coords*/ _fdim = INT2FIX(_this->width); @@ -787,24 +891,26 @@ void evg_set_texture_active(EVGStencil *st) _this->pixel_format = GF_PIXEL_ARGB; } if (_this->Bpp * _this->width * _this->height > _this->conv_size) { - if (_this->conv_buf) free(_this->conv_buf); + if (_this->conv_buf) gf_free(_this->conv_buf); _this->conv_size = _this->Bpp * _this->width * _this->height; - _this->conv_buf = (unsigned char *) malloc(sizeof(unsigned char)*_this->conv_size); + _this->conv_buf = (unsigned char *) gf_malloc(sizeof(unsigned char)*_this->conv_size); } src.height = _this->height; src.width = _this->width; - src.pitch = _this->orig_stride; + src.pitch_x = 0; + src.pitch_y = _this->orig_stride; src.pixel_format = _this->orig_format; src.video_buffer = _this->orig_buf; dst.width = _this->width; dst.height = _this->height; - dst.pitch = _this->Bpp * _this->width; + dst.pitch_x = _this->Bpp; + dst.pitch_y = _this->Bpp * _this->width; dst.pixel_format = _this->pixel_format; dst.video_buffer = _this->conv_buf; - gf_stretch_bits(&dst, &src, NULL, NULL, 0, 0xFF, 0, NULL, NULL); + gf_stretch_bits(&dst, &src, NULL, NULL, 0xFF, 0, NULL, NULL); _this->is_converted = 1; _this->pixels = (char *) _this->conv_buf; @@ -846,8 +952,8 @@ GF_Err evg_stencil_create_texture(GF_STENCIL st, u32 width, u32 height, GF_Pixel _this->height = height; _this->stride = width*_this->Bpp; - if (_this->pixels) free(_this->pixels); - _this->pixels = (char *) malloc(sizeof(char) * _this->stride * _this->height); + if (_this->pixels) gf_free(_this->pixels); + _this->pixels = (char *) gf_malloc(sizeof(char) * _this->stride * _this->height); memset(_this->pixels, 0, sizeof(char) * _this->stride * _this->height); _this->owns_texture = 1; texture_set_callback(_this); diff --git a/modules/soft_raster/surface.c b/modules/soft_raster/surface.c index 9f136cc..a20403a 100644 --- a/modules/soft_raster/surface.c +++ b/modules/soft_raster/surface.c @@ -53,11 +53,11 @@ void evg_surface_delete(GF_SURFACE _this) { EVGSurface *surf = (EVGSurface *)_this; #ifndef INLINE_POINT_CONVERSION - if (surf->points) free(surf->points); + if (surf->points) gf_free(surf->points); #endif - if (surf->stencil_pix_run) free(surf->stencil_pix_run); + if (surf->stencil_pix_run) gf_free(surf->stencil_pix_run); evg_raster_del(surf->raster); - free(surf); + gf_free(surf); } GF_Err evg_surface_set_matrix(GF_SURFACE _this, GF_Matrix2D *mat) @@ -79,22 +79,23 @@ GF_Err evg_surface_attach_to_callbacks(GF_SURFACE _this, GF_RasterCallback *call { EVGSurface *surf = (EVGSurface *)_this; if (!surf || !width || !height || !callbacks) return GF_BAD_PARAM; - if (!callbacks->cbk || !callbacks->fill_run_alpha || !callbacks->fill_run_no_alpha) return GF_BAD_PARAM; + if (!callbacks->cbk || !callbacks->fill_run_alpha || !callbacks->fill_run_no_alpha || !callbacks->fill_rect) return GF_BAD_PARAM; surf->width = width; surf->height = height; - if (surf->stencil_pix_run) free(surf->stencil_pix_run); - surf->stencil_pix_run = (u32 *) malloc(sizeof(u32) * (width+2)); + if (surf->stencil_pix_run) gf_free(surf->stencil_pix_run); + surf->stencil_pix_run = (u32 *) gf_malloc(sizeof(u32) * (width+2)); surf->raster_cbk = callbacks->cbk; surf->raster_fill_run_alpha = callbacks->fill_run_alpha; surf->raster_fill_run_no_alpha = callbacks->fill_run_no_alpha; + surf->raster_fill_rectangle = callbacks->fill_rect; evg_surface_set_matrix(surf, NULL); return GF_OK; } -GF_Err evg_surface_attach_to_buffer(GF_SURFACE _this, char *pixels, u32 width, u32 height, u32 stride, GF_PixelFormat pixelFormat) +GF_Err evg_surface_attach_to_buffer(GF_SURFACE _this, char *pixels, u32 width, u32 height, s32 pitch_x, s32 pitch_y, GF_PixelFormat pixelFormat) { u32 BPP; EVGSurface *surf = (EVGSurface *)_this; @@ -117,16 +118,18 @@ GF_Err evg_surface_attach_to_buffer(GF_SURFACE _this, char *pixels, u32 width, u case GF_PIXEL_RGB_32: case GF_PIXEL_ARGB: case GF_PIXEL_RGBA: + case GF_PIXEL_BGR_32: BPP = 4; break; - case GF_PIXEL_BGR_32: default: return GF_NOT_SUPPORTED; } - surf->stride = stride; + if (!pitch_x) pitch_x = BPP; + surf->pitch_x = pitch_x; + surf->pitch_y = pitch_y; if (!surf->stencil_pix_run || (surf->width != width)) { - if (surf->stencil_pix_run) free(surf->stencil_pix_run); - surf->stencil_pix_run = (u32 *) malloc(sizeof(u32) * (width+2)); + if (surf->stencil_pix_run) gf_free(surf->stencil_pix_run); + surf->stencil_pix_run = (u32 *) gf_malloc(sizeof(u32) * (width+2)); } surf->width = width; surf->height = height; @@ -168,6 +171,7 @@ GF_Err evg_surface_attach_to_texture(GF_SURFACE _this, GF_STENCIL sten) BPP = 3; break; case GF_PIXEL_RGB_32: + case GF_PIXEL_BGR_32: case GF_PIXEL_ARGB: case GF_PIXEL_RGBA: BPP = 4; @@ -175,9 +179,10 @@ GF_Err evg_surface_attach_to_texture(GF_SURFACE _this, GF_STENCIL sten) default: return GF_NOT_SUPPORTED; } - surf->stride = tx->stride; - if (surf->stencil_pix_run) free(surf->stencil_pix_run); - surf->stencil_pix_run = (u32 *) malloc(sizeof(u32) * (tx->width+2)); + surf->pitch_x = BPP; + surf->pitch_y = tx->stride; + if (surf->stencil_pix_run) gf_free(surf->stencil_pix_run); + surf->stencil_pix_run = (u32 *) gf_malloc(sizeof(u32) * (tx->width+2)); surf->width = tx->width; surf->height = tx->height; @@ -238,13 +243,16 @@ GF_Err evg_surface_clear(GF_SURFACE _this, GF_IRect *rc, u32 color) } if (surf->raster_cbk) { - return evg_surface_clear_user(surf, clear, color); + surf->raster_fill_rectangle(surf->raster_cbk, clear.x, clear.y, clear.width, clear.height, color); + return GF_OK; } switch (surf->pixelFormat) { case GF_PIXEL_ARGB: case GF_PIXEL_RGB_32: return evg_surface_clear_argb(surf, clear, color); + case GF_PIXEL_BGR_32: + return evg_surface_clear_bgr32(surf, clear, color); case GF_PIXEL_RGBA: return evg_surface_clear_rgba(surf, clear, color); case GF_PIXEL_BGR_24: @@ -281,7 +289,7 @@ GF_Err evg_surface_set_raster_level(GF_SURFACE _this, GF_RasterLevel RasterSetti break; case GF_RASTER_HIGH_SPEED: default: - surf->AALevel = 180; + surf->AALevel = 254; surf->texture_filter = GF_TEXTURE_FILTER_HIGH_SPEED; break; } @@ -393,6 +401,20 @@ static Bool setup_grey_callback(EVGSurface *surf) surf->ftparams.gray_spans = (EVG_Raster_Span_Func) evg_rgb32_fill_var; } break; + + case GF_PIXEL_BGR_32: + if (use_const) { + if (!a) return 0; + if (a!=0xFF) { + surf->ftparams.gray_spans = (EVG_Raster_Span_Func) evg_bgr32_fill_const_a; + } else { + surf->ftparams.gray_spans = (EVG_Raster_Span_Func) evg_bgr32_fill_const; + } + } else { + surf->ftparams.gray_spans = (EVG_Raster_Span_Func) evg_bgr32_fill_var; + } + break; + case GF_PIXEL_RGB_24: if (use_const) { if (!a) return 0; @@ -428,6 +450,7 @@ static Bool setup_grey_callback(EVGSurface *surf) } } else { surf->ftparams.gray_spans = (EVG_Raster_Span_Func) evg_565_fill_var; + assert(surf->sten->fill_run); } break; #ifdef GF_RGB_444_SUPORT @@ -499,7 +522,7 @@ GF_Err evg_surface_set_path(GF_SURFACE _this, GF_Path *gp) surf->ftparams.mx = &surf->mat; #else if (surf->pointlen < gp->n_points) { - surf->points = realloc(surf->points, sizeof(EVG_Vector) * gp->n_points); + surf->points = gf_realloc(surf->points, sizeof(EVG_Vector) * gp->n_points); if (surf->points == NULL) { surf->pointlen = 0; return GF_OUT_OF_MEM; diff --git a/modules/svg_in/Makefile b/modules/svg_in/Makefile index 1a4a140..4096c1e 100644 --- a/modules/svg_in/Makefile +++ b/modules/svg_in/Makefile @@ -16,7 +16,7 @@ endif ifeq ($(CONFIG_ZLIB), local) CFLAGS+= -I$(LOCAL_INC_PATH)/zlib -EXTRALIBS+=-L../extra_lib/lib/gcc +EXTRALIBS+=-L../../extra_lib/lib/gcc endif #common obj @@ -26,20 +26,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_svg_in.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols svg_in.def +#LDFLAGS+=-export-symbols svg_in.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac -lz +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac -lz +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_svg_in-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static -lz +endif %.o: %.c diff --git a/modules/svg_in/svg_in.c b/modules/svg_in/svg_in.c index 5590786..b6f47e9 100644 --- a/modules/svg_in/svg_in.c +++ b/modules/svg_in/svg_in.c @@ -34,7 +34,7 @@ typedef struct { GF_SceneLoader loader; - GF_InlineScene *inline_scene; + GF_Scene *scene; u8 oti; char *file_name; u32 file_size; @@ -46,10 +46,11 @@ typedef struct static Bool svg_check_download(SVGIn *svgin) { - u32 size; - FILE *f = fopen(svgin->file_name, "rb"); - fseek(f, 0, SEEK_END); - size = ftell(f); + u64 size; + FILE *f = gf_f64_open(svgin->file_name, "rb"); + if (!f) return 0; + gf_f64_seek(f, 0, SEEK_END); + size = gf_f64_tell(f); fclose(f); if (size==svgin->file_size) return 1; return 0; @@ -105,7 +106,7 @@ static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffe gf_sm_load_done(&svgin->loader); svgin->loader.fileName = NULL; svgin->file_pos = 0; - gf_sg_reset(svgin->inline_scene->graph); + gf_sg_reset(svgin->scene->graph); return GF_OK; } @@ -133,6 +134,7 @@ static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffe svgin->src = gzopen(svgin->file_name, "rb"); if (!svgin->src) return GF_URL_ERROR; svgin->loader.fileName = svgin->file_name; + gf_sm_load_init(&svgin->loader); } e = GF_OK; entry_time = gf_sys_clock(); @@ -144,11 +146,11 @@ static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffe /*we may have read nothing but we still need to call parse in case the parser got suspended*/ if (nb_read<=0) { nb_read = 0; - e = gf_sm_load_run(&svgin->loader); if ((e==GF_EOS) && gzeof(svgin->src)) { gf_set_progress("SVG Parsing", svgin->file_pos, svgin->file_size); gzclose(svgin->src); svgin->src = NULL; + gf_sm_load_done(&svgin->loader); } goto exit; } @@ -164,9 +166,11 @@ static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffe if (svgin->file_pos > svgin->file_size) svgin->file_size = svgin->file_pos + 1; if (e) break; - diff = gf_sys_clock() - entry_time; gf_set_progress("SVG Parsing", svgin->file_pos, svgin->file_size); - if (diff > svgin->sax_max_duration) break; + diff = gf_sys_clock() - entry_time; + if (diff > svgin->sax_max_duration) { + break; + } } } break; @@ -185,13 +189,14 @@ static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffe case GPAC_OTI_SCENE_DIMS: { u8 prev, dims_hdr; - u32 nb_bytes, pos, size; + u32 nb_bytes, size; + u64 pos; GF_BitStream *bs = gf_bs_new(inBuffer, inBufferLength, GF_BITSTREAM_READ); // -// FILE *f = fopen("dump.svg", "wb"); +// FILE *f = gf_f64_open("dump.svg", "wb"); // while (gf_bs_available(bs)) { - pos = (u32) gf_bs_get_position(bs); + pos = gf_bs_get_position(bs); size = gf_bs_read_u16(bs); nb_bytes = 2; /*GPAC internal hack*/ @@ -224,8 +229,8 @@ static GF_Err SVG_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffe } exit: - if ((svgin->inline_scene->graph_attached!=1) && (gf_sg_get_root_node(svgin->loader.scene_graph)!=NULL) ) { - gf_inline_attach_to_compositor(svgin->inline_scene); + if ((svgin->scene->graph_attached!=1) && (gf_sg_get_root_node(svgin->loader.scene_graph)!=NULL) ) { + gf_scene_attach_to_compositor(svgin->scene); } /*prepare for next playback*/ if (e==GF_EOS) { @@ -237,17 +242,20 @@ exit: -static GF_Err SVG_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder) +static GF_Err SVG_AttachScene(GF_SceneDecoder *plug, GF_Scene *scene, Bool is_scene_decoder) { SVGIn *svgin = (SVGIn *)plug->privateStack; memset(&svgin->loader, 0, sizeof(GF_SceneLoader)); svgin->loader.is = scene; - svgin->inline_scene = scene; + svgin->scene = scene; svgin->loader.scene_graph = scene->graph; svgin->loader.localPath = gf_modules_get_option((GF_BaseInterface *)plug, "General", "CacheDirectory"); /*Warning: svgin->loader.type may be overriden in attach stream */ - svgin->loader.type = GF_SM_LOAD_SVG_DA; + svgin->loader.type = GF_SM_LOAD_SVG; svgin->loader.flags = GF_SM_LOAD_FOR_PLAYBACK; + + if (svgin->oti!= GPAC_OTI_PRIVATE_SCENE_SVG) + gf_sm_load_init(&svgin->loader); return GF_OK; } @@ -263,7 +271,7 @@ static GF_Err SVG_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) SVGIn *svgin = (SVGIn *)plug->privateStack; if (esd->decoderConfig->upstream) return GF_NOT_SUPPORTED; - svgin->loader.type = GF_SM_LOAD_SVG_DA; + svgin->loader.type = GF_SM_LOAD_SVG; /* decSpecInfo is not null only when reading from an SVG file (local or distant, cached or not) */ switch (esd->decoderConfig->objectTypeIndication) { case GPAC_OTI_SCENE_SVG: @@ -284,7 +292,7 @@ static GF_Err SVG_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) svgin->file_size = gf_bs_read_u32(bs); svgin->file_pos = 0; gf_bs_del(bs); - svgin->file_name = (char *) malloc(sizeof(char)*(1 + esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32)) ); + svgin->file_name = (char *) gf_malloc(sizeof(char)*(1 + esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32)) ); memcpy(svgin->file_name, esd->decoderConfig->decoderSpecificInfo->data + sizeof(u32), esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32) ); svgin->file_name[esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32) ] = 0; break; @@ -312,7 +320,7 @@ static GF_Err SVG_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) static GF_Err SVG_DetachStream(GF_BaseDecoder *plug, u16 ES_ID) { SVGIn *svgin = (SVGIn *)plug->privateStack; - if (svgin->file_name) free(svgin->file_name); + if (svgin->file_name) gf_free(svgin->file_name); svgin->file_name = NULL; gf_sm_load_done(&svgin->loader); return GF_OK; @@ -353,8 +361,12 @@ static GF_Err SVG_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *cap) return GF_NOT_SUPPORTED; } -static GF_Err SVG_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapability capability) +static GF_Err SVG_SetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability cap) { + if (cap.CapCode==GF_CODEC_ABORT) { + SVGIn *svgin = (SVGIn *)plug->privateStack; + gf_sm_load_suspend(&svgin->loader, 1); + } return GF_OK; } @@ -393,17 +405,10 @@ void ShutdownInterface(GF_BaseInterface *ifce) SVGIn *svgin = (SVGIn *) sdec->privateStack; if (sdec->InterfaceType != GF_SCENE_DECODER_INTERFACE) return; - free(svgin); - free(sdec); + gf_free(svgin); + gf_free(sdec); } -/*interface query*/ -GF_EXPORT -Bool QueryInterface(u32 InterfaceType) -{ - if (InterfaceType == GF_SCENE_DECODER_INTERFACE) return 1; - return 0; -} #else @@ -421,10 +426,17 @@ void ShutdownInterface(GF_BaseInterface *ifce) { } +#endif + /*interface query*/ GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - return 0; -} + static u32 si [] = { +#ifndef GPAC_DISABLE_SVG + GF_SCENE_DECODER_INTERFACE, #endif + 0 + }; + return si; +} diff --git a/modules/svg_in/svg_in.def b/modules/svg_in/svg_in.def deleted file mode 100644 index 1f70017..0000000 --- a/modules/svg_in/svg_in.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_svg_in.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/timedtext/Makefile b/modules/timedtext/Makefile index 76e9656..6225e93 100644 --- a/modules/timedtext/Makefile +++ b/modules/timedtext/Makefile @@ -21,20 +21,18 @@ SRCS := $(OBJS:.o=.c) LIB=gm_timedtext.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols timedtext.def +#LDFLAGS+=-export-symbols timedtext.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) -L../../bin/gcc -lgpac +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_timedtext-static.so $(OBJS) $(EXTRALIBS) -L../../bin/gcc -lgpac_static +endif %.o: %.c diff --git a/modules/timedtext/timedtext.def b/modules/timedtext/timedtext.def deleted file mode 100644 index 2ed55d2..0000000 --- a/modules/timedtext/timedtext.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_timedtext.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/timedtext/timedtext_dec.c b/modules/timedtext/timedtext_dec.c index f236a69..46cc5d3 100644 --- a/modules/timedtext/timedtext_dec.c +++ b/modules/timedtext/timedtext_dec.c @@ -28,6 +28,8 @@ #include <gpac/constants.h> #include <gpac/nodes_mpeg4.h> +#if !defined(GPAC_DISABLE_VRML) && !defined(GPAC_DISABLE_ISOM) + /* this decoder is simply a scene decoder generating its own scene graph based on input data, @@ -66,7 +68,7 @@ typedef struct { - GF_InlineScene *inlineScene; + GF_Scene *inlineScene; GF_Terminal *app; u32 PL, nb_streams; @@ -86,12 +88,12 @@ typedef struct GF_List *blink_nodes; u32 scroll_type, scroll_mode; Fixed scroll_time, scroll_delay; - Bool is_active, use_texture; + Bool is_active, use_texture, outline; } TTDPriv; -static void ttd_set_blink_fraction(GF_Node *node); -static void ttd_set_scroll_fraction(GF_Node *node); +static void ttd_set_blink_fraction(GF_Node *node, GF_Route *route); +static void ttd_set_scroll_fraction(GF_Node *node, GF_Route *route); static void TTD_ResetDisplay(TTDPriv *priv); /*the WORST thing about 3GP in MPEG4 is positioning of the text track...*/ @@ -111,7 +113,7 @@ static void TTD_UpdateSizeInfo(TTDPriv *priv) } gf_sg_get_scene_size_info(priv->sg, &w, &h); if (!w || !h) return; - gf_inline_force_scene_size(priv->inlineScene, w, h); + gf_scene_force_size(priv->inlineScene, w, h); } if (!w || !h) return; @@ -133,7 +135,7 @@ static void TTD_UpdateSizeInfo(TTDPriv *priv) } if (set_size) { gf_sg_set_scene_size_info(priv->sg, w, h, 1); - gf_inline_force_scene_size(priv->inlineScene, w, h); + gf_scene_force_size(priv->inlineScene, w, h); } } else { /*otherwise override (mainly used for SRT & TTXT file direct loading*/ @@ -193,15 +195,15 @@ static GF_Err TTD_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapability if (capability.cap.valueInt) { TTD_ResetDisplay(priv); TTD_UpdateSizeInfo(priv); - gf_inline_register_extra_graph(priv->inlineScene, priv->sg, 0); + gf_scene_register_extra_graph(priv->inlineScene, priv->sg, 0); } else { - gf_inline_register_extra_graph(priv->inlineScene, priv->sg, 1); + gf_scene_register_extra_graph(priv->inlineScene, priv->sg, 1); } } return GF_OK; } -GF_Err TTD_AttachScene(GF_SceneDecoder *plug, GF_InlineScene *scene, Bool is_scene_decoder) +GF_Err TTD_AttachScene(GF_SceneDecoder *plug, GF_Scene *scene, Bool is_scene_decoder) { TTDPriv *priv = (TTDPriv *)plug->privateStack; if (priv->nb_streams) return GF_BAD_PARAM; @@ -338,6 +340,8 @@ static GF_Err TTD_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) /*option setup*/ opt = gf_modules_get_option((GF_BaseInterface *)plug, "StreamingText", "UseTexturing"); priv->use_texture = (opt && !strcmp(opt, "yes")) ? 1 : 0; + opt = gf_modules_get_option((GF_BaseInterface *)plug, "StreamingText", "OutlineText"); + priv->outline = (opt && !strcmp(opt, "yes")) ? 1 : 0; return e; } @@ -346,7 +350,7 @@ static GF_Err TTD_DetachStream(GF_BaseDecoder *plug, u16 ES_ID) TTDPriv *priv = (TTDPriv *)plug->privateStack; if (!priv->nb_streams) return GF_BAD_PARAM; - gf_inline_register_extra_graph(priv->inlineScene, priv->sg, 1); + gf_scene_register_extra_graph(priv->inlineScene, priv->sg, 1); gf_node_unregister((GF_Node *) priv->ts_blink, NULL); gf_node_unregister((GF_Node *) priv->process_blink, NULL); @@ -362,7 +366,7 @@ static GF_Err TTD_DetachStream(GF_BaseDecoder *plug, u16 ES_ID) return GF_OK; } -static void ttd_set_blink_fraction(GF_Node *node) +static void ttd_set_blink_fraction(GF_Node *node, GF_Route *route) { M_Material2D *m; u32 i; @@ -379,7 +383,7 @@ static void ttd_set_blink_fraction(GF_Node *node) } } -static void ttd_set_scroll_fraction(GF_Node *node) +static void ttd_set_scroll_fraction(GF_Node *node, GF_Route *route) { Fixed frac; TTDPriv *priv = (TTDPriv *)gf_node_get_private(node); @@ -534,16 +538,16 @@ static void TTD_NewTextChunk(TTDPriv *priv, GF_TextSampleDescriptor *tsd, M_Form gf_node_register(n2, txt_model); text = (M_Text *) n2; fs = (M_FontStyle *) ttd_create_node(priv, TAG_MPEG4_FontStyle, NULL); - free(fs->family.vals[0]); + gf_free(fs->family.vals[0]); /*translate default fonts to MPEG-4/VRML names*/ - if (!stricmp(fontName, "Serif")) fs->family.vals[0] = strdup("SERIF"); - else if (!stricmp(fontName, "Sans-Serif")) fs->family.vals[0] = strdup("SANS"); - else if (!stricmp(fontName, "Monospace")) fs->family.vals[0] = strdup("TYPEWRITER"); - else fs->family.vals[0] = strdup(fontName); + if (!stricmp(fontName, "Serif")) fs->family.vals[0] = gf_strdup("SERIF"); + else if (!stricmp(fontName, "Sans-Serif")) fs->family.vals[0] = gf_strdup("SANS"); + else if (!stricmp(fontName, "Monospace")) fs->family.vals[0] = gf_strdup("TYPEWRITER"); + else fs->family.vals[0] = gf_strdup(fontName); fs->size = INT2FIX(fontSize); - free(fs->style.buffer); + gf_free(fs->style.buffer); strcpy(szStyle, ""); if (styleFlags & GF_TXT_STYLE_BOLD) { if (styleFlags & GF_TXT_STYLE_ITALIC) strcpy(szStyle, "BOLDITALIC"); @@ -566,8 +570,9 @@ static void TTD_NewTextChunk(TTDPriv *priv, GF_TextSampleDescriptor *tsd, M_Form on text box size (in MP4Box, it actually defaults to the entire video area) and drawing a too large texture & bitmap could slow down rendering*/ if (priv->use_texture) strcat(szStyle, " TEXTURED"); + if (priv->outline) strcat(szStyle, " OUTLINED"); - fs->style.buffer = strdup(szStyle); + fs->style.buffer = gf_strdup(szStyle); fs->horizontal = (tsd->displayFlags & GF_TXT_VERTICAL) ? 0 : 1; text->fontStyle = (GF_Node *) fs; gf_node_register((GF_Node *)fs, (GF_Node *)text); @@ -578,8 +583,8 @@ static void TTD_NewTextChunk(TTDPriv *priv, GF_TextSampleDescriptor *tsd, M_Form M_Anchor *anc = (M_Anchor *) ttd_create_node(priv, TAG_MPEG4_Anchor, NULL); gf_sg_vrml_mf_append(&anc->url, GF_SG_VRML_MFURL, (void **) &s); s->OD_ID = 0; - s->url = strdup(tc->hlink->URL); - if (tc->hlink->URL_hint) anc->description.buffer = strdup(tc->hlink->URL_hint); + s->url = gf_strdup(tc->hlink->URL); + if (tc->hlink->URL_hint) anc->description.buffer = gf_strdup(tc->hlink->URL_hint); gf_node_list_add_child(& anc->children, txt_model); gf_node_register(txt_model, (GF_Node *)anc); txt_model = (GF_Node *)anc; @@ -629,7 +634,7 @@ static void TTD_NewTextChunk(TTDPriv *priv, GF_TextSampleDescriptor *tsd, M_Form szLine[len] = 0; gf_sg_vrml_mf_append(&text->string, GF_SG_VRML_MFSTRING, (void **) &st); - st->buffer = strdup(szLine); + st->buffer = gf_strdup(szLine); } start_char = i+1; if (new_line) { @@ -670,7 +675,7 @@ void TTD_SplitChunks(GF_TextSample *txt, u32 nb_chars, GF_List *chunks, GF_Box * /*need to split chunk at begin*/ if (tc->start_char<start_char) { TTDTextChunk *tc2; - tc2 = (TTDTextChunk *) malloc(sizeof(TTDTextChunk)); + tc2 = (TTDTextChunk *) gf_malloc(sizeof(TTDTextChunk)); memcpy(tc2, tc, sizeof(TTDTextChunk)); tc2->start_char = start_char; tc2->end_char = tc->end_char; @@ -682,7 +687,7 @@ void TTD_SplitChunks(GF_TextSample *txt, u32 nb_chars, GF_List *chunks, GF_Box * /*need to split chunks at end*/ if (tc->end_char>end_char) { TTDTextChunk *tc2; - tc2 = (TTDTextChunk *) malloc(sizeof(TTDTextChunk)); + tc2 = (TTDTextChunk *) gf_malloc(sizeof(TTDTextChunk)); memcpy(tc2, tc, sizeof(TTDTextChunk)); tc2->start_char = tc->start_char; tc2->end_char = end_char; @@ -931,7 +936,7 @@ static void TTD_ApplySample(TTDPriv *priv, GF_TextSample *txt, u32 sdi, Bool is_ tc = (TTDTextChunk*)gf_list_get(chunks, 0); gf_list_rem(chunks, 0); TTD_NewTextChunk(priv, td, form, utf16_text, tc); - free(tc); + gf_free(tc); } gf_list_del(chunks); @@ -958,7 +963,7 @@ static void TTD_ApplySample(TTDPriv *priv, GF_TextSample *txt, u32 sdi, Bool is_ gf_sg_vrml_mf_append(&form->groups, GF_SG_VRML_MFINT32, (void **) &id); (*id) = -1; } else { /*spread horizontal 0 pixels (eg align) all items in line*/ - gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s); s->buffer = strdup(vertical ? "SV 0" : "SH 0"); + gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s); s->buffer = gf_strdup(vertical ? "SV 0" : "SH 0"); for (j=start_idx; j<i; j++) { gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = idx.vals[j]; /*also add a group for the line, for final justif*/ @@ -972,7 +977,7 @@ static void TTD_ApplySample(TTDPriv *priv, GF_TextSample *txt, u32 sdi, Bool is_ nb_lines ++; } } - free(idx.vals); + gf_free(idx.vals); /*finally add constraints on lines*/ start_idx = gf_node_list_get_count(form->children) + 1; @@ -980,15 +985,15 @@ static void TTD_ApplySample(TTDPriv *priv, GF_TextSample *txt, u32 sdi, Bool is_ gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s); if (vertical) { switch (td->vert_justif) { - case 1: s->buffer = strdup("AV"); break;/*center*/ - case -1: s->buffer = strdup("AB"); break;/*bottom*/ - default: s->buffer = strdup("AT"); break;/*top*/ + case 1: s->buffer = gf_strdup("AV"); break;/*center*/ + case -1: s->buffer = gf_strdup("AB"); break;/*bottom*/ + default: s->buffer = gf_strdup("AT"); break;/*top*/ } } else { switch (td->horiz_justif) { - case 1: s->buffer = strdup("AH"); break;/*center*/ - case -1: s->buffer = strdup("AR"); break;/*right*/ - default: s->buffer = strdup("AL"); break;/*left*/ + case 1: s->buffer = gf_strdup("AH"); break;/*center*/ + case -1: s->buffer = gf_strdup("AR"); break;/*right*/ + default: s->buffer = gf_strdup("AL"); break;/*left*/ } } gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = 0; @@ -999,7 +1004,7 @@ static void TTD_ApplySample(TTDPriv *priv, GF_TextSample *txt, u32 sdi, Bool is_ /*vertical alignment: first align all items vertically, 0 pixel */ - gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s); s->buffer = strdup(vertical ? "SH 0" : "SV 0"); + gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s); s->buffer = gf_strdup(vertical ? "SH 0" : "SV 0"); gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = 0; for (i=0; i<nb_lines; i++) { gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = i+start_idx; @@ -1016,15 +1021,15 @@ static void TTD_ApplySample(TTDPriv *priv, GF_TextSample *txt, u32 sdi, Bool is_ gf_sg_vrml_mf_append(&form->constraints, GF_SG_VRML_MFSTRING, (void **) &s); if (vertical) { switch (td->horiz_justif) { - case 1: s->buffer = strdup("AH"); break;/*center*/ - case -1: s->buffer = strdup("AR"); break;/*right*/ - default: s->buffer = strdup("AL"); break;/*left*/ + case 1: s->buffer = gf_strdup("AH"); break;/*center*/ + case -1: s->buffer = gf_strdup("AR"); break;/*right*/ + default: s->buffer = gf_strdup("AL"); break;/*left*/ } } else { switch (td->vert_justif) { - case 1: s->buffer = strdup("AV"); break;/*center*/ - case -1: s->buffer = strdup("AB"); break;/*bottom*/ - default: s->buffer = strdup("AT"); break;/*top*/ + case 1: s->buffer = gf_strdup("AV"); break;/*center*/ + case -1: s->buffer = gf_strdup("AB"); break;/*bottom*/ + default: s->buffer = gf_strdup("AT"); break;/*top*/ } } gf_sg_vrml_mf_append(&form->groupsIndex, GF_SG_VRML_MFINT32, (void **) &id); (*id) = 0; @@ -1104,8 +1109,8 @@ void DeleteTimedTextDec(GF_BaseDecoder *plug) TTDPriv *priv = (TTDPriv *)plug->privateStack; /*in case something went wrong*/ if (priv->cfg) gf_odf_desc_del((GF_Descriptor *) priv->cfg); - free(priv); - free(plug); + gf_free(priv); + gf_free(plug); } GF_BaseDecoder *NewTimedTextDec() @@ -1130,18 +1135,7 @@ GF_BaseDecoder *NewTimedTextDec() return (GF_BaseDecoder *) tmp; } -GF_EXPORT -Bool QueryInterface(u32 InterfaceType) -{ - switch (InterfaceType) { - case GF_SCENE_DECODER_INTERFACE: return 1; - case GF_NET_CLIENT_INTERFACE: return 1; - default: return 0; - } -} - - -#ifndef GPAC_READ_ONLY +#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT) void DeleteTTReader(void *ifce); void *NewTTReader(); #endif @@ -1151,7 +1145,7 @@ GF_BaseInterface *LoadInterface(u32 InterfaceType) { switch (InterfaceType) { case GF_SCENE_DECODER_INTERFACE: return (GF_BaseInterface *)NewTimedTextDec(); -#ifndef GPAC_READ_ONLY +#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT) case GF_NET_CLIENT_INTERFACE: return (GF_BaseInterface *)NewTTReader(); #endif default: return NULL; @@ -1165,10 +1159,33 @@ void ShutdownInterface(GF_BaseInterface *ifce) case GF_SCENE_DECODER_INTERFACE: DeleteTimedTextDec((GF_BaseDecoder *)ifce); break; -#ifndef GPAC_READ_ONLY +#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT) case GF_NET_CLIENT_INTERFACE: DeleteTTReader(ifce); break; #endif } } + +#else + +GF_EXPORT +GF_BaseInterface *LoadInterface(u32 InterfaceType) { return NULL; } +GF_EXPORT +void ShutdownInterface(GF_BaseInterface *ifce) {} + + +#endif /*!defined(GPAC_DISABLE_VRML) && !defined(GPAC_DISABLE_ISOM)*/ + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { +#if !defined(GPAC_DISABLE_VRML) && !defined(GPAC_DISABLE_ISOM) + GF_SCENE_DECODER_INTERFACE, + GF_NET_CLIENT_INTERFACE, +#endif + 0 + }; + return si; +} diff --git a/modules/timedtext/timedtext_in.c b/modules/timedtext/timedtext_in.c index d4429ed..be7a689 100644 --- a/modules/timedtext/timedtext_in.c +++ b/modules/timedtext/timedtext_in.c @@ -26,7 +26,7 @@ #include <gpac/modules/codec.h> #include <gpac/constants.h> -#ifndef GPAC_READ_ONLY +#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT) #include <gpac/media_tools.h> @@ -106,7 +106,7 @@ GF_Err TTIn_LoadFile(GF_InputService *plug, const char *url, Bool is_cache) tti->mp4 = gf_isom_open(szFILE, GF_ISOM_OPEN_WRITE, NULL); if (!tti->mp4) return gf_isom_last_error(NULL); - tti->szFile = strdup(szFILE); + tti->szFile = gf_strdup(szFILE); memset(&import, 0, sizeof(GF_MediaImporter)); import.dest = tti->mp4; @@ -193,7 +193,7 @@ static GF_Err TTIn_CloseService(GF_InputService *plug) tti->mp4 = NULL; if (tti->szFile) { gf_delete_file(tti->szFile); - free(tti->szFile); + gf_free(tti->szFile); tti->szFile = NULL; } if (tti->dnload) gf_term_download_del(tti->dnload); @@ -375,8 +375,8 @@ void DeleteTTReader(void *ifce) { GF_InputService *plug = (GF_InputService *) ifce; TTIn *tti = (TTIn *)plug->priv; - free(tti); - free(plug); + gf_free(tti); + gf_free(plug); } -#endif +#endif /* !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT)*/ diff --git a/modules/ui_rec/Makefile b/modules/ui_rec/Makefile new file mode 100644 index 0000000..a43ccb1 --- /dev/null +++ b/modules/ui_rec/Makefile @@ -0,0 +1,62 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/ui_rec + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +LINKLIBS= -lgpac +LOCAL_LIB=../../bin/gcc + +#common objects +OBJS=ui_rec.o + + + +SRCS := $(OBJS:.o=.c) + +LIB=gm_ui_rec.$(DYN_LIB_SUFFIX) +ifeq ($(CONFIG_WIN32),yes) +#LDFLAGS+=-export-symbols ui_rec.def +endif + + +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) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/ui_rec/readme.txt b/modules/ui_rec/readme.txt new file mode 100644 index 0000000..721f531 --- /dev/null +++ b/modules/ui_rec/readme.txt @@ -0,0 +1,14 @@ +This is a UI recorder module for the GPAC framework. This module allows recording and playback of user events (mouse and keyboard). + +To use this module: +- The variable "Mode" in the section [UIRecord] has to be set to one of the following values + * "Disable": module is disabled + * "Record": module will record user interaction + * "Play": module will play user interaction + +The module is designed to work with one scene, events are recorded according to the scene time of the event dispatch. +The events are recorded/read from a file, which is indicated by the variable "File" of the [UIRecord] section. +Note that the module will automatically set the mode to "Disabled" when closing the player. + +This module has been successfully tested under Win32 and Linux + diff --git a/modules/ui_rec/ui_rec.c b/modules/ui_rec/ui_rec.c new file mode 100644 index 0000000..2eedfcf --- /dev/null +++ b/modules/ui_rec/ui_rec.c @@ -0,0 +1,249 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2007-200X ENST + * All rights reserved + * + * This file is part of GPAC / User Event Recorder 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. + * + */ + +/*base SVG type*/ +#include <gpac/modules/term_ext.h> +#include <gpac/internal/terminal_dev.h> +#include <gpac/internal/compositor_dev.h> + + +typedef struct __ui_rec +{ + FILE *uif; + GF_BitStream *bs; + GF_Terminal *term; + GF_Clock *ck; + + GF_Event next_event; + u32 next_time; + Bool evt_loaded; + + Bool (*on_event)(struct __ui_rec *uir , GF_Event *event); +} GF_UIRecord; + +Bool uir_on_event_play(GF_UIRecord *uir , GF_Event *event) +{ + switch (event->type) { + case GF_EVENT_CONNECT: + if (event->connect.is_connected) { + uir->ck = uir->term->root_scene->scene_codec ? uir->term->root_scene->scene_codec->ck : uir->term->root_scene->dyn_ck; + } + break; + } + return 0; +} + +Bool uir_on_event_record(GF_UIRecord *uir , GF_Event *event) +{ + switch (event->type) { + case GF_EVENT_CONNECT: + if (event->connect.is_connected) { + uir->ck = uir->term->root_scene->scene_codec ? uir->term->root_scene->scene_codec->ck : uir->term->root_scene->dyn_ck; + } + break; + case GF_EVENT_CLICK: + case GF_EVENT_MOUSEUP: + case GF_EVENT_MOUSEDOWN: + case GF_EVENT_MOUSEOVER: + case GF_EVENT_MOUSEOUT: + /*!! ALL MOUSE EVENTS SHALL BE DECLARED BEFORE MOUSEMOVE !! */ + case GF_EVENT_MOUSEMOVE: + /*mouse wheel event*/ + case GF_EVENT_MOUSEWHEEL: + gf_bs_write_u32(uir->bs, gf_clock_time(uir->ck) ); + gf_bs_write_u8(uir->bs, event->type); + gf_bs_write_u8(uir->bs, event->mouse.button); + gf_bs_write_u32(uir->bs, event->mouse.x); + gf_bs_write_u32(uir->bs, event->mouse.y); + gf_bs_write_float(uir->bs, FIX2FLT(event->mouse.wheel_pos) ); + gf_bs_write_u8(uir->bs, event->mouse.key_states); + break; + /*Key Events*/ + case GF_EVENT_KEYUP: + case GF_EVENT_KEYDOWN: + case GF_EVENT_LONGKEYPRESS: + gf_bs_write_u32(uir->bs, gf_clock_time(uir->ck) ); + gf_bs_write_u8(uir->bs, event->type); + gf_bs_write_u32(uir->bs, event->key.key_code); + gf_bs_write_u32(uir->bs, event->key.hw_code); + gf_bs_write_u32(uir->bs, event->key.flags); + break; + /*character input*/ + case GF_EVENT_TEXTINPUT: + gf_bs_write_u32(uir->bs, gf_clock_time(uir->ck) ); + gf_bs_write_u8(uir->bs, event->type); + gf_bs_write_u32(uir->bs, event->character.unicode_char); + break; + } + return 0; +} + +void uir_load_event(GF_UIRecord *uir) +{ + memset(&uir->next_event, 0, sizeof(GF_Event)); + uir->evt_loaded = 0; + if (!gf_bs_available(uir->bs)) return; + + + uir->next_time = gf_bs_read_u32(uir->bs); + uir->next_event.type = gf_bs_read_u8(uir->bs); + switch (uir->next_event.type) { + case GF_EVENT_CLICK: + case GF_EVENT_MOUSEUP: + case GF_EVENT_MOUSEDOWN: + case GF_EVENT_MOUSEOVER: + case GF_EVENT_MOUSEOUT: + /*!! ALL MOUSE EVENTS SHALL BE DECLARED BEFORE MOUSEMOVE !! */ + case GF_EVENT_MOUSEMOVE: + /*mouse wheel event*/ + case GF_EVENT_MOUSEWHEEL: + uir->next_event.mouse.button = gf_bs_read_u8(uir->bs); + uir->next_event.mouse.x = gf_bs_read_u32(uir->bs); + uir->next_event.mouse.y = gf_bs_read_u32(uir->bs); + uir->next_event.mouse.wheel_pos = FLT2FIX( gf_bs_read_float(uir->bs) ); + uir->next_event.mouse.key_states = gf_bs_read_u8(uir->bs); + break; + /*Key Events*/ + case GF_EVENT_KEYUP: + case GF_EVENT_KEYDOWN: + case GF_EVENT_LONGKEYPRESS: + uir->next_event.key.key_code = gf_bs_read_u32(uir->bs); + uir->next_event.key.hw_code = gf_bs_read_u32(uir->bs); + uir->next_event.key.flags = gf_bs_read_u32(uir->bs); + break; + /*character input*/ + case GF_EVENT_TEXTINPUT: + uir->next_event.character.unicode_char = gf_bs_read_u32(uir->bs); + break; + } + uir->evt_loaded = 1; +} + +static Bool uir_process(GF_TermExt *termext, u32 action, void *param) +{ + const char *opt, *uifile; + GF_UIRecord *uir = termext->udta; + + switch (action) { + case GF_TERM_EXT_START: + uir->term = (GF_Terminal *) param; + opt = gf_modules_get_option((GF_BaseInterface*)termext, "UIRecord", "Mode"); + if (!opt) return 0; + uifile = gf_modules_get_option((GF_BaseInterface*)termext, "UIRecord", "File"); + if (!opt) return 0; + + if (!strcmp(opt, "Play")) { + uir->uif = fopen(uifile, "rb"); + if (!uir->uif) return 0; + uir->bs = gf_bs_from_file(uir->uif, GF_BITSTREAM_READ); + termext->caps |= GF_TERM_EXTENSION_NOT_THREADED; + + uir->on_event = uir_on_event_play; + termext->caps |= GF_TERM_EXTENSION_FILTER_EVENT; + + uir_load_event(uir); + } else if (!strcmp(opt, "Record")) { + uir->uif = fopen(uifile, "wb"); + if (!uir->uif) return 0; + uir->bs = gf_bs_from_file(uir->uif, GF_BITSTREAM_WRITE); + + uir->on_event = uir_on_event_record; + termext->caps |= GF_TERM_EXTENSION_FILTER_EVENT; + } else { + return 0; + } + return 1; + + case GF_TERM_EXT_STOP: + if (uir->uif) fclose(uir->uif); + if (uir->bs) gf_bs_del(uir->bs); + uir->term = NULL; + /*auto-disable the plugin by default*/ + gf_modules_set_option((GF_BaseInterface*)termext, "UIRecord", "Mode", "Disable"); + break; + + case GF_TERM_EXT_PROCESS: + /*flush all events until current time if reached*/ + while (uir->evt_loaded && uir->ck && (uir->next_time <= gf_clock_time(uir->ck) )) { + uir->term->compositor->video_out->on_event(uir->term->compositor->video_out->evt_cbk_hdl, &uir->next_event); + uir_load_event(uir); + } + break; + case GF_TERM_EXT_EVENT: + return uir->on_event(uir, (GF_Event*)param); + } + return 0; +} + + +GF_TermExt *uir_new() +{ + GF_TermExt *dr; + GF_UIRecord *uir; + dr = malloc(sizeof(GF_TermExt)); + memset(dr, 0, sizeof(GF_TermExt)); + GF_REGISTER_MODULE_INTERFACE(dr, GF_TERM_EXT_INTERFACE, "GPAC UI Recorder", "gpac distribution"); + + GF_SAFEALLOC(uir, GF_UIRecord); + dr->process = uir_process; + dr->udta = uir; + return dr; +} + + +void uir_delete(GF_BaseInterface *ifce) +{ + GF_TermExt *dr = (GF_TermExt *) ifce; + GF_UIRecord *uir = dr->udta; + free(uir); + free(dr); +} + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_TERM_EXT_INTERFACE, + 0 + }; + return si; +} + +GF_EXPORT +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + if (InterfaceType == GF_TERM_EXT_INTERFACE) return (GF_BaseInterface *)uir_new(); + return NULL; +} + +GF_EXPORT +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { + case GF_TERM_EXT_INTERFACE: + uir_delete(ifce); + break; + } +} diff --git a/modules/wav_out/Makefile b/modules/wav_out/Makefile index 3d9ba63..87bc9b6 100644 --- a/modules/wav_out/Makefile +++ b/modules/wav_out/Makefile @@ -21,7 +21,7 @@ OBJS=wav_out.o SRCS := $(OBJS:.o=.c) LIB=gm_wav_audio.$(DYN_LIB_SUFFIX) -LDFLAGS+=-export-symbols wav_out.def +#LDFLAGS+=-export-symbols wav_out.def all: $(LIB) diff --git a/modules/wav_out/wav_out.c b/modules/wav_out/wav_out.c index df70a02..321fef5 100644 --- a/modules/wav_out/wav_out.c +++ b/modules/wav_out/wav_out.c @@ -148,7 +148,7 @@ static void close_waveform(GF_AudioOutput *dr) SetEvent(ctx->event); waveOutReset(ctx->hwo); waveOutClose(ctx->hwo); - if (ctx->wav_buf) free(ctx->wav_buf); + if (ctx->wav_buf) gf_free(ctx->wav_buf); ctx->wav_buf = NULL; CloseHandle(ctx->event); ctx->event = NULL; @@ -179,7 +179,7 @@ static void close_waveform(GF_AudioOutput *dr) } ctx->hwo = NULL; } - if (ctx->wav_buf) free(ctx->wav_buf); + if (ctx->wav_buf) gf_free(ctx->wav_buf); ctx->wav_buf = NULL; CloseHandle(ctx->event); ctx->event = NULL; @@ -274,7 +274,7 @@ static GF_Err WAV_ConfigureOutput(GF_AudioOutput *dr, u32 *SampleRate, u32 *NbCh /*make sure we're aligned*/ while (ctx->buffer_size % ctx->fmt.nBlockAlign) ctx->buffer_size++; - ctx->wav_buf = malloc(ctx->buffer_size*ctx->num_buffers*sizeof(char)); + ctx->wav_buf = gf_malloc(ctx->buffer_size*ctx->num_buffers*sizeof(char)); memset(ctx->wav_buf, 0, ctx->buffer_size*ctx->num_buffers*sizeof(char)); /*setup wave headers*/ @@ -430,12 +430,12 @@ void *NewWAVRender() { WAVContext *ctx; GF_AudioOutput *driv; - ctx = malloc(sizeof(WAVContext)); + ctx = gf_malloc(sizeof(WAVContext)); memset(ctx, 0, sizeof(WAVContext)); ctx->num_buffers = 10; ctx->pan = 50; ctx->vol = 100; - driv = malloc(sizeof(GF_AudioOutput)); + driv = gf_malloc(sizeof(GF_AudioOutput)); memset(driv, 0, sizeof(GF_AudioOutput)); GF_REGISTER_MODULE_INTERFACE(driv, GF_AUDIO_OUTPUT_INTERFACE, "Windows MME Output", "gpac distribution") @@ -460,14 +460,17 @@ void DeleteWAVRender(void *ifce) { GF_AudioOutput *dr = (GF_AudioOutput *) ifce; WAVContext *ctx = (WAVContext *)dr->opaque; - free(ctx); - free(dr); + gf_free(ctx); + gf_free(dr); } -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return 1; - return 0; + static u32 si [] = { + GF_AUDIO_OUTPUT_INTERFACE, + 0 + }; + return si; } GF_BaseInterface *LoadInterface(u32 InterfaceType) diff --git a/modules/wav_out/wav_out.def b/modules/wav_out/wav_out.def deleted file mode 100644 index 8f4b53f..0000000 --- a/modules/wav_out/wav_out.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_wav_out.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/widgetman/Makefile b/modules/widgetman/Makefile new file mode 100644 index 0000000..582ff91 --- /dev/null +++ b/modules/widgetman/Makefile @@ -0,0 +1,75 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/widgetman + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +LINKLIBS= -lgpac -lz +LOCAL_LIB=-L../../bin/gcc + +#common objects +OBJS=widgetman.o unzip.o widget.o wgt_load.o + +ifeq ($(CONFIG_ZLIB), local) +CFLAGS+=-I$(LOCAL_INC_PATH)/zlib +LOCAL_LIB+= -L../../extra_lib/lib/gcc +endif + +ifeq ($(CONFIG_JS),no) +else +CFLAGS+=$(JS_FLAGS) +ifeq ($(CONFIG_JS),local) +NEED_LOCAL_LIB="yes" +LOCAL_LIB+= -L../../extra_lib/lib/gcc +endif +LINKLIBS+= $(JS_LIBS) +endif + +SRCS := $(OBJS:.o=.c) + +LIB=gm_widgetman.$(DYN_LIB_SUFFIX) +ifeq ($(CONFIG_WIN32),yes) +#LDFLAGS+=-export-symbols widgetman.def +endif + + +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) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/widgetman/unzip.c b/modules/widgetman/unzip.c new file mode 100644 index 0000000..2a77dca --- /dev/null +++ b/modules/widgetman/unzip.c @@ -0,0 +1,1368 @@ +/* + miniunz.c + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +#ifndef _WIN32_WCE +#include <errno.h> +#include <fcntl.h> + +#ifdef WIN32 +# include <direct.h> +# include <io.h> +#else +# include <unistd.h> +# include <utime.h> +#endif + +#endif + +# include "unzip.h" + + + +/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ + +#ifndef SEEK_CUR +#define SEEK_CUR 1 +#endif + +#ifndef SEEK_END +#define SEEK_END 2 +#endif + +#ifndef SEEK_SET +#define SEEK_SET 0 +#endif + +voidpf ZCALLBACK fopen_file_func OF(( + voidpf opaque, + const char* filename, + int mode)); + +uLong ZCALLBACK fread_file_func OF(( + voidpf opaque, + voidpf stream, + void* buf, + uLong size)); + +uLong ZCALLBACK fwrite_file_func OF(( + voidpf opaque, + voidpf stream, + const void* buf, + uLong size)); + +long ZCALLBACK ftell_file_func OF(( + voidpf opaque, + voidpf stream)); + +long ZCALLBACK fseek_file_func OF(( + voidpf opaque, + voidpf stream, + uLong offset, + int origin)); + +int ZCALLBACK fclose_file_func OF(( + voidpf opaque, + voidpf stream)); + +int ZCALLBACK ferror_file_func OF(( + voidpf opaque, + voidpf stream)); + + +voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) + voidpf opaque; + const char* filename; + int mode; +{ + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else + if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else + if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; + + if ((filename!=NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; +} + + +uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + + +uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) + voidpf opaque; + voidpf stream; + const void* buf; + uLong size; +{ + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); + return ret; +} + +long ZCALLBACK ftell_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + long ret; + ret = ftell((FILE *)stream); + return ret; +} + +long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) + voidpf opaque; + voidpf stream; + uLong offset; + int origin; +{ + int fseek_origin=0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR : + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END : + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET : + fseek_origin = SEEK_SET; + break; + default: return -1; + } + ret = 0; + fseek((FILE *)stream, offset, fseek_origin); + return ret; +} + +int ZCALLBACK fclose_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = fclose((FILE *)stream); + return ret; +} + +int ZCALLBACK ferror_file_func (opaque, stream) + voidpf opaque; + voidpf stream; +{ + int ret; + ret = ferror((FILE *)stream); + return ret; +} + +void fill_fopen_filefunc (pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; +{ + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; +} + +static int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + int *pi; +{ + unsigned char c; + int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); + if (err==1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR(*pzlib_filefunc_def,filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } +} + +static int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +static int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; + uLong *pX; +{ + uLong x ; + int i; + int err; + + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x = (uLong)i; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<8; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<16; + + if (err==UNZ_OK) + err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); + x += ((uLong)i)<<24; + + if (err==UNZ_OK) + *pX = x; + else + *pX = 0; + return err; +} + +static uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) + const zlib_filefunc_def* pzlib_filefunc_def; + voidpf filestream; +{ + unsigned char* buf; + uLong uSizeFile; + uLong uBackRead; + uLong uMaxBack=0xffff; /* maximum size of global comment */ + uLong uPosFound=0; + + if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + + + uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); + + if (uMaxBack>uSizeFile) + uMaxBack = uSizeFile; + + buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); + if (buf==NULL) + return 0; + + uBackRead = 4; + while (uBackRead<uMaxBack) + { + uLong uReadSize,uReadPos ; + int i; + if (uBackRead+BUFREADCOMMENT>uMaxBack) + uBackRead = uMaxBack; + else + uBackRead+=BUFREADCOMMENT; + uReadPos = uSizeFile-uBackRead ; + + uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? + (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); + if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) + break; + + if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) + break; + + for (i=(int)uReadSize-3; (i--)>0;) + if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && + ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) + { + uPosFound = uReadPos+i; + break; + } + + if (uPosFound!=0) + break; + } + TRYFREE(buf); + return uPosFound; +} + + +/* + Translate date/time from Dos format to tm_unz (readable more easilty) +*/ +void unzlocal_DosDateToTmuDate (ulDosDate, ptm) + uLong ulDosDate; + tm_unz* ptm; +{ + uLong uDate; + uDate = (uLong)(ulDosDate>>16); + ptm->tm_mday = (uInt)(uDate&0x1f) ; + ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; + ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + + ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); + ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; + ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; +} + +static int unzlocal_GetCurrentFileInfoInternal (file, + pfile_info, + pfile_info_internal, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize) + unzFile file; + unz_file_info *pfile_info; + unz_file_info_internal *pfile_info_internal; + char *szFileName; + uLong fileNameBufferSize; + void *extraField; + uLong extraFieldBufferSize; + char *szComment; + uLong commentBufferSize; +{ + unz_s* s; + unz_file_info file_info; + unz_file_info_internal file_info_internal; + int err=UNZ_OK; + uLong uMagic; + long lSeek=0; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (ZSEEK(s->z_filefunc, s->filestream, + s->pos_in_central_dir+s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + + /* we check the magic */ + if (err==UNZ_OK) + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x02014b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) + err=UNZ_ERRNO; + + unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) + err=UNZ_ERRNO; + + lSeek+=file_info.size_filename; + if ((err==UNZ_OK) && (szFileName!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_filename<fileNameBufferSize) + { + *(szFileName+file_info.size_filename)='\0'; + uSizeRead = file_info.size_filename; + } + else + uSizeRead = fileNameBufferSize; + + if ((file_info.size_filename>0) && (fileNameBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek -= uSizeRead; + } + + + if ((err==UNZ_OK) && (extraField!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_extra<extraFieldBufferSize) + uSizeRead = file_info.size_file_extra; + else + uSizeRead = extraFieldBufferSize; + + if (lSeek!=0) + if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - uSizeRead; + } + else + lSeek+=file_info.size_file_extra; + + + if ((err==UNZ_OK) && (szComment!=NULL)) + { + uLong uSizeRead ; + if (file_info.size_file_comment<commentBufferSize) + { + *(szComment+file_info.size_file_comment)='\0'; + uSizeRead = file_info.size_file_comment; + } + else + uSizeRead = commentBufferSize; + + if (lSeek!=0) + if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) + lSeek=0; + else + err=UNZ_ERRNO; + if ((file_info.size_file_comment>0) && (commentBufferSize>0)) + if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) + err=UNZ_ERRNO; + lSeek+=file_info.size_file_comment - uSizeRead; + } + else + lSeek+=file_info.size_file_comment; + + if ((err==UNZ_OK) && (pfile_info!=NULL)) + *pfile_info=file_info; + + if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) + *pfile_info_internal=file_info_internal; + + return err; +} + +int unzGetCurrentFileInfo(unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize) +{ + return unzlocal_GetCurrentFileInfoInternal(file, pfile_info, NULL, szFileName, fileNameBufferSize, extraField, extraFieldBufferSize, szComment, commentBufferSize); +} + +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ +int unzGoToNextFile (file) + unzFile file; +{ + unz_s* s; + int err; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file+1==s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; + + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; + s->num_file++; + err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ +int unzGoToFirstFile (file) + unzFile file; +{ + int err=UNZ_OK; + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + s->pos_in_central_dir=s->offset_central_dir; + s->num_file=0; + err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, + &s->cur_file_info_internal, + NULL,0,NULL,0,NULL,0); + s->current_file_ok = (err == UNZ_OK); + return err; +} + +int unzGetGlobalInfo (file,pglobal_info) + unzFile file; + unz_global_info *pglobal_info; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + *pglobal_info=s->gi; + return UNZ_OK; +} + +/* + Close the file in zip opened with unzipOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ +int unzCloseCurrentFile (file) + unzFile file; +{ + int err=UNZ_OK; + + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err=UNZ_CRCERROR; + } + + + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised) + inflateEnd(&pfile_in_zip_read_info->stream); + + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); + + s->pfile_in_zip_read=NULL; + + return err; +} + + +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer + "zlib/zlib114.zip". + If the zipfile cannot be opened (file doesn't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ +extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) + const char *path; + zlib_filefunc_def* pzlib_filefunc_def; +{ + unz_s us; + unz_s *s; + uLong central_pos,uL; + + uLong number_disk; /* number of the current dist, used for + spaning ZIP, unsupported, always 0*/ + uLong number_disk_with_CD; /* number the the disk with central dir, used + for spaning ZIP, unsupported, always 0*/ + uLong number_entry_CD; /* total number of entries in + the central dir + (same than number_entry on nospan) */ + + int err=UNZ_OK; + + if (pzlib_filefunc_def==NULL) + fill_fopen_filefunc(&us.z_filefunc); + else + us.z_filefunc = *pzlib_filefunc_def; + + us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream==NULL) + return NULL; + + central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); + if (central_pos==0) + err=UNZ_ERRNO; + + if (ZSEEK(us.z_filefunc, us.filestream, + central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) + err=UNZ_ERRNO; + + /* the signature, already checked */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) + err=UNZ_ERRNO; + + /* number of the disk with the start of the central directory */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir on this disk */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) + err=UNZ_ERRNO; + + /* total number of entries in the central dir */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((number_entry_CD!=us.gi.number_entry) || + (number_disk_with_CD!=0) || + (number_disk!=0)) + err=UNZ_BADZIPFILE; + + /* size of the central directory */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* offset of start of central directory with respect to the + starting disk number */ + if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) + err=UNZ_ERRNO; + + /* zipfile comment length */ + if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) + err=UNZ_ERRNO; + + if ((central_pos<us.offset_central_dir+us.size_central_dir) && + (err==UNZ_OK)) + err=UNZ_BADZIPFILE; + + if (err!=UNZ_OK) + { + ZCLOSE(us.z_filefunc, us.filestream); + return NULL; + } + + us.byte_before_the_zipfile = central_pos - + (us.offset_central_dir+us.size_central_dir); + us.central_pos = central_pos; + us.pfile_in_zip_read = NULL; + us.encrypted = 0; + + + s=(unz_s*)ALLOC(sizeof(unz_s)); + *s=us; + unzGoToFirstFile((unzFile)s); + return (unzFile)s; +} + + +/* + Read bytes from the current file. + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ +int unzReadCurrentFile (file, buf, len) + unzFile file; + voidp buf; + unsigned len; +{ + int err=UNZ_OK; + uInt iRead = 0; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + pfile_in_zip_read_info=s->pfile_in_zip_read; + + if (pfile_in_zip_read_info==NULL) + return UNZ_PARAMERROR; + + + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len==0) + return 0; + + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + + pfile_in_zip_read_info->stream.avail_out = (uInt)len; + + if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + + if ((len>pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed+ + pfile_in_zip_read_info->stream.avail_in; + + while (pfile_in_zip_read_info->stream.avail_out>0) + { + if ((pfile_in_zip_read_info->stream.avail_in==0) && + (pfile_in_zip_read_info->rest_read_compressed>0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressed<uReadThis) + uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + if (ZREAD(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis)!=uReadThis) + return UNZ_ERRNO; + + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; + + pfile_in_zip_read_info->rest_read_compressed-=uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy,i ; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead==0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out ; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in ; + + for (i=0;i<uDoCopy;i++) + *(pfile_in_zip_read_info->stream.next_out+i) = + *(pfile_in_zip_read_info->stream.next_in+i); + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else + { + uLong uTotalOutBefore,uTotalOutAfter; + const Bytef *bufBefore; + uLong uOutThis; + int flush=Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* + if ((pfile_in_zip_read_info->rest_read_uncompressed == + pfile_in_zip_read_info->stream.avail_out) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + flush = Z_FINISH; + */ + err=inflate(&pfile_in_zip_read_info->stream,flush); + + if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) + err = Z_DATA_ERROR; + + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter-uTotalOutBefore; + + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32,bufBefore, + (uInt)(uOutThis)); + + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; + + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + if (err==Z_STREAM_END) + return (iRead==0) ? UNZ_EOF : iRead; + if (err!=Z_OK) + break; + } + } + + if (err==Z_OK) + return iRead; + return err; +} + +/* + Read the local header of the current zipfile + Check the coherency of the local header and info in the end of central + directory about this file + store in *piSizeVar the size of extra info in local header + (filename and size of extra field data) +*/ +int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, + poffset_local_extrafield, + psize_local_extrafield) + unz_s* s; + uInt* piSizeVar; + uLong *poffset_local_extrafield; + uInt *psize_local_extrafield; +{ + uLong uMagic,uData,uFlags; + uLong size_filename; + uLong size_extra_field; + int err=UNZ_OK; + + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; + + if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + + s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) + return UNZ_ERRNO; + + + if (err==UNZ_OK) + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) + err=UNZ_ERRNO; + else if (uMagic!=0x04034b50) + err=UNZ_BADZIPFILE; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; +/* + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) + err=UNZ_BADZIPFILE; +*/ + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) + err=UNZ_ERRNO; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) + err=UNZ_BADZIPFILE; + + if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ + err=UNZ_ERRNO; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && + ((uFlags & 8)==0)) + err=UNZ_BADZIPFILE; + + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) + err=UNZ_ERRNO; + else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) + err=UNZ_BADZIPFILE; + + *piSizeVar += (uInt)size_filename; + + if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) + err=UNZ_ERRNO; + *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; + + *piSizeVar += (uInt)size_extra_field; + + return err; +} + +/* + Open for reading data the current file in the zipfile. + If there is no error and the file is opened, the return value is UNZ_OK. +*/ +int unzOpenCurrentFile3 (file, method, level, raw, password) + unzFile file; + int* method; + int* level; + int raw; + const char* password; +{ + int err=UNZ_OK; + uInt iSizeVar; + unz_s* s; + file_in_zip_read_info_s* pfile_in_zip_read_info; + uLong offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + + if (password != NULL) + return UNZ_PARAMERROR; + + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, + &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip_read_info_s*) + ALLOC(sizeof(file_in_zip_read_info_s)); + if (pfile_in_zip_read_info==NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield=0; + pfile_in_zip_read_info->raw=raw; + + if (pfile_in_zip_read_info->read_buffer==NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised=0; + + if (method!=NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level!=NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6 : *level = 1; break; + case 4 : *level = 2; break; + case 2 : *level = 9; break; + } + } + + if ((s->cur_file_info.compression_method!=0) && + (s->cur_file_info.compression_method!=Z_DEFLATED)) + err=UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; + pfile_in_zip_read_info->crc32=0; + pfile_in_zip_read_info->compression_method = + s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream=s->filestream; + pfile_in_zip_read_info->z_filefunc=s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method==Z_DEFLATED) && + (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised=1; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. + * Note that in this case inflate *requires* an extra "dummy" byte + * after the compressed stream in order to complete decompression and + * return Z_STREAM_END. + * In unzip, i don't wait absolutely Z_STREAM_END because I known the + * size of both compressed and uncompressed data + */ + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size ; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size ; + + + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; + + pfile_in_zip_read_info->stream.avail_in = (uInt)0; + + s->pfile_in_zip_read = pfile_in_zip_read_info; + + return UNZ_OK; +} + +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzipOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ +extern int ZEXPORT unzClose (file) + unzFile file; +{ + unz_s* s; + if (file==NULL) + return UNZ_PARAMERROR; + s=(unz_s*)file; + + if (s->pfile_in_zip_read!=NULL) + unzCloseCurrentFile(file); + + ZCLOSE(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; +} + +#ifndef _WIN32_WCE + +/* mymkdir and change_file_date are not 100 % portable + As I don't know well Unix, I wait feedback for the unix portion */ + +int mymkdir(dirname) + const char* dirname; +{ + int ret=0; +#if defined(WIN32) || defined(_WIN32_WCE) + return mkdir(dirname); +#else + return mkdir (dirname, 700); +#endif + return ret; +} + +int makedir (newdir) + char *newdir; +{ + char *buffer ; + char *p; + int len = (int)strlen(newdir); + + if (len <= 0) + return 0; + + buffer = (char*)malloc(len+1); + strcpy(buffer,newdir); + + if (buffer[len-1] == '/') { + buffer[len-1] = '\0'; + } + if (mymkdir(buffer) == 0) + { + free(buffer); + return 1; + } + + p = buffer+1; + while (1) + { + char hold; + + while(*p && *p != '\\' && *p != '/') + p++; + hold = *p; + *p = 0; + if ((mymkdir(buffer) == -1) && (errno == ENOENT)) + { + printf("couldn't create directory %s\n",buffer); + free(buffer); + return 0; + } + if (hold == 0) + break; + *p++ = hold; + } + free(buffer); + return 1; +} +#else +int makedir (newdir) +{ + return 0; +} +#endif + + +int do_extract_currentfile(uf) + unzFile uf; +{ + char filename_inzip[256]; + char* filename_withoutpath; + char* p; + int err=UNZ_OK; + FILE *fout=NULL; + void* buf; + uInt size_buf; + + unz_file_info file_info; + uLong ratio=0; + err = unzlocal_GetCurrentFileInfoInternal(uf,&file_info,NULL,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); + + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzGetCurrentFileInfo\n",err); + return err; + } + + size_buf = WRITEBUFFERSIZE; + buf = (void*)malloc(size_buf); + if (buf==NULL) + { + printf("Error allocating memory\n"); + return UNZ_INTERNALERROR; + } + + p = filename_withoutpath = filename_inzip; + while ((*p) != '\0') + { + if (((*p)=='/') || ((*p)=='\\')) + filename_withoutpath = p+1; + p++; + } + + if ((*filename_withoutpath)=='\0') + { +#ifndef _WIN32_WCE + printf("creating directory: %s\n",filename_inzip); + mymkdir(filename_inzip); +#endif + } + else + { + const char* write_filename; + int skip=0; + + write_filename = filename_inzip; + + err = unzOpenCurrentFile3(uf, NULL, NULL, 0, NULL/*password*/); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err); + } + + if ((skip==0) && (err==UNZ_OK)) + { + fout=fopen(write_filename,"wb"); + + /* some zipfile don't contain directory alone before file */ + if ((fout==NULL) && (filename_withoutpath!=(char*)filename_inzip)) + { + char c=*(filename_withoutpath-1); + *(filename_withoutpath-1)='\0'; + makedir(write_filename); + *(filename_withoutpath-1)=c; + fout=fopen(write_filename,"wb"); + } + + if (fout==NULL) + { + printf("error opening %s\n",write_filename); + } + } + + if (fout!=NULL) + { + printf(" extracting: %s\n",write_filename); + + do + { + err = unzReadCurrentFile(uf,buf,size_buf); + if (err<0) + { + printf("error %d with zipfile in unzReadCurrentFile\n",err); + break; + } + if (err>0) + if (fwrite(buf,err,1,fout)!=1) + { + printf("error in writing extracted file\n"); + err=UNZ_ERRNO; + break; + } + } + while (err>0); + if (fout) + fclose(fout); + } + + if (err==UNZ_OK) + { + err = unzCloseCurrentFile (uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzCloseCurrentFile\n",err); + } + } + else + unzCloseCurrentFile(uf); /* don't lose the error */ + } + + free(buf); + return err; +} + + +int gf_unzip_archive(const char *zipfilename, const char *dirname) +{ + uLong i; + unz_global_info gi; + int err; + FILE* fout=NULL; + + unzFile uf=NULL; + + uf = unzOpen2(zipfilename, NULL); + if (uf==NULL) + { + printf("Cannot open %s\n", zipfilename); + return 1; + } +#ifndef _WIN32_WCE + if (chdir(dirname)) + { + printf("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); + + for (i=0;i<gi.number_entry;i++) + { + if (do_extract_currentfile(uf) != UNZ_OK) + break; + + if ((i+1)<gi.number_entry) + { + err = unzGoToNextFile(uf); + if (err!=UNZ_OK) + { + printf("error %d with zipfile in unzGoToNextFile\n",err); + break; + } + } + } + unzClose(uf); + + return 0; +} + +int gf_unzip_probe(const char *zipfilename) +{ + int ret = 0; + FILE *f = fopen(zipfilename, "r"); + if (!f) return 0; + if (fgetc(f)=='P') + if (fgetc(f)=='K') + if (fgetc(f)==3) + if (fgetc(f)==4) + ret = 1; + fclose(f); + return ret; +} diff --git a/modules/widgetman/unzip.h b/modules/widgetman/unzip.h new file mode 100644 index 0000000..0dceeb0 --- /dev/null +++ b/modules/widgetman/unzip.h @@ -0,0 +1,485 @@ +/* unzip.h -- IO for uncompress .zip files using zlib + Version 1.01e, February 12th, 2005 + + Copyright (C) 1998-2005 Gilles Vollant + + This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g + WinZip, InfoZip tools and compatible. + + Multi volume ZipFile (span) are not supported. + Encryption compatible with pkzip 2.04g only supported + Old compressions used by old PKZip 1.x are not supported + + + I WAIT FEEDBACK at mail info@winimage.com + Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution + + Condition of use and distribution are the same than zlib : + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + +*/ + +/* for more info about .ZIP format, see + http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip + http://www.info-zip.org/pub/infozip/doc/ + PkWare has also a specification at : + ftp://ftp.pkware.com/probdesc.zip +*/ + +#ifndef _unz_H +#define _unz_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include <zlib.h> + +#define ZCALLBACK + +#define ZLIB_FILEFUNC_SEEK_CUR (1) +#define ZLIB_FILEFUNC_SEEK_END (2) +#define ZLIB_FILEFUNC_SEEK_SET (0) + +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) + +#define ZLIB_FILEFUNC_MODE_EXISTING (4) +#define ZLIB_FILEFUNC_MODE_CREATE (8) + +typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); +typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); +typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); +typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); +typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); +typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + +typedef struct zlib_filefunc_def_s +{ + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; +} zlib_filefunc_def; + + + +void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); + +#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) +#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) +#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) +#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) +#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) +#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) + +#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) +/* like the STRICT of WIN32, we define a pointer that cannot be converted + from (void*) without cast */ +typedef struct TagunzFile__ { int unused; } unzFile__; +typedef unzFile__ *unzFile; +#else +typedef voidp unzFile; +#endif + + +#ifndef UNZ_BUFSIZE +#define UNZ_BUFSIZE (16384) +#endif + +#ifndef UNZ_MAXFILENAMEINZIP +#define UNZ_MAXFILENAMEINZIP (256) +#endif + +#ifndef ALLOC +# define ALLOC(size) (malloc(size)) +#endif +#ifndef TRYFREE +# define TRYFREE(p) {if (p) free(p);} +#endif + +#define SIZECENTRALDIRITEM (0x2e) +#define SIZEZIPLOCALHEADER (0x1e) + +#ifndef BUFREADCOMMENT +#define BUFREADCOMMENT (0x400) +#endif + +#define WRITEBUFFERSIZE (8192) + + + + +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) + +/* tm_unz contain date/time info */ +typedef struct tm_unz_s +{ + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ +} tm_unz; + +/* unz_global_info structure contain global data about the ZIPfile + These data comes from the end of central dir */ +typedef struct unz_global_info_s +{ + uLong number_entry; /* total number of entries in + the central dir on this disk */ + uLong size_comment; /* size of the global comment of the zipfile */ +} unz_global_info; + + +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_info_s +{ + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ + + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + + tm_unz tmu_date; +} unz_file_info; + + + +/* unz_file_info_interntal contain internal info about a file in zipfile*/ +typedef struct unz_file_info_internal_s +{ + uLong offset_curfile;/* relative offset of local header 4 bytes */ +} unz_file_info_internal; + + +/* file_in_zip_read_info_s contain internal information about a file in zipfile, + when reading and decompress it */ +typedef struct +{ + char *read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ + + uLong pos_in_zipfile; /* position in byte on the zipfile, for gf_f64_seek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ + + uLong offset_local_extrafield;/* offset of the local extra field */ + uInt size_local_extrafield;/* size of the local extra field */ + uLong pos_local_extrafield; /* position in the local extra field in read*/ + + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + uLong rest_read_compressed; /* number of byte to be decompressed */ + uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int raw; +} file_in_zip_read_info_s; + + +/* unz_s contain internal information about the zipfile +*/ +typedef struct +{ + zlib_filefunc_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info gi; /* public global information */ + uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + uLong num_file; /* number of the current file in the zipfile*/ + uLong pos_in_central_dir; /* pos of the current file in the central dir*/ + uLong current_file_ok; /* flag about the usability of the current file*/ + uLong central_pos; /* position of the beginning of the central dir*/ + + uLong size_central_dir; /* size of the central directory */ + uLong offset_central_dir; /* offset of start of central directory with + respect to the starting disk number */ + + unz_file_info cur_file_info; /* public info about the current file in zip*/ + unz_file_info_internal cur_file_info_internal; /* private info about it*/ + file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current + file if we are decompressing it */ + int encrypted; +# ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +# endif +} unz_s; + + + +extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, + const char* fileName2, + int iCaseSensitivity)); +/* + Compare two filename (fileName1,fileName2). + If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) + If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi + or strcasecmp) + If iCaseSenisivity = 0, case sensitivity is defaut of your operating system + (like 1 on Unix, 2 on Windows) +*/ + + +extern unzFile ZEXPORT unzOpen OF((const char *path)); +/* + Open a Zip file. path contain the full pathname (by example, + on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer + "zlib/zlib113.zip". + If the zipfile cannot be opened (file don't exist or in not valid), the + return value is NULL. + Else, the return value is a unzFile Handle, usable with other function + of this unzip package. +*/ + +extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def* pzlib_filefunc_def)); +/* + Open a Zip file, like unzOpen, but provide a set of file low level API + for read/write the zip file (see ioapi.h) +*/ + +extern int ZEXPORT unzClose OF((unzFile file)); +/* + Close a ZipFile opened with unzipOpen. + If there is files inside the .Zip opened with unzOpenCurrentFile (see later), + these files MUST be closed with unzipCloseCurrentFile before call unzipClose. + return UNZ_OK if there is no problem. */ + +extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); +/* + Write info about the ZipFile in the *pglobal_info structure. + No preparation of the structure is needed + return UNZ_OK if there is no problem. */ + + +extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); +/* + Get the global comment string of the ZipFile, in the szComment buffer. + uSizeBuf is the size of the szComment buffer. + return the number of byte copied or an error code <0 +*/ + + +/***************************************************************************/ +/* Unzip package allow you browse the directory of the zipfile */ + +extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); +/* + Set the current file of the zipfile to the first file. + return UNZ_OK if there is no problem +*/ + +extern int ZEXPORT unzGoToNextFile OF((unzFile file)); +/* + Set the current file of the zipfile to the next file. + return UNZ_OK if there is no problem + return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. +*/ + +extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); +/* + Try locate the file szFileName in the zipfile. + For the iCaseSensitivity signification, see unzStringFileNameCompare + + return value : + UNZ_OK if the file is found. It becomes the current file. + UNZ_END_OF_LIST_OF_FILE if the file is not found +*/ + + +/* ****************************************** */ +/* Ryan supplied functions */ +/* unz_file_info contain information about a file in the zipfile */ +typedef struct unz_file_pos_s +{ + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ +} unz_file_pos; + +extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos* file_pos); + +extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos* file_pos); + +/* ****************************************** */ + +extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); +/* + Get Info about the current file + if pfile_info!=NULL, the *pfile_info structure will contain somes info about + the current file + if szFileName!=NULL, the filemane string will be copied in szFileName + (fileNameBufferSize is the size of the buffer) + if extraField!=NULL, the extra field information will be copied in extraField + (extraFieldBufferSize is the size of the buffer). + This is the Central-header version of the extra field + if szComment!=NULL, the comment string of the file will be copied in szComment + (commentBufferSize is the size of the buffer) +*/ + +/***************************************************************************/ +/* for reading the content of the current zipfile, you can open it, read data + from it, and close it (you can close it before reading all the file) + */ + +extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); +/* + Open for reading data the current file in the zipfile. + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char* password)); +/* + Open for reading data the current file in the zipfile. + password is a crypting password + If there is no error, the return value is UNZ_OK. +*/ + +extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int* method, + int* level, + int raw)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + +extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int* method, + int* level, + int raw, + const char* password)); +/* + Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) + if raw==1 + *method will receive method of compression, *level will receive level of + compression + note : you can set level parameter as NULL (if you did not want known level, + but you CANNOT set method parameter as NULL +*/ + + +extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); +/* + Close the file in zip opened with unzOpenCurrentFile + Return UNZ_CRCERROR if all the file was read but the CRC is not good +*/ + +extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read bytes from the current file (opened by unzOpenCurrentFile) + buf contain buffer where data must be copied + len the size of buf. + + return the number of byte copied if somes bytes are copied + return 0 if the end of file was reached + return <0 with error code if there is an error + (UNZ_ERRNO for IO error, or zLib error for uncompress error) +*/ + +extern z_off_t ZEXPORT unztell OF((unzFile file)); +/* + Give the current position in uncompressed data +*/ + +extern int ZEXPORT unzeof OF((unzFile file)); +/* + return 1 if the end of file was reached, 0 elsewhere +*/ + +extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); +/* + Read extra field from the current file (opened by unzOpenCurrentFile) + This is the local-header version of the extra field (sometimes, there is + more info in the local-header version than in the central-header) + + if buf==NULL, it return the size of the local extra field + + if buf!=NULL, len is the size of the buffer, the extra header is copied in + buf. + the return value is the number of bytes copied in buf, or (if <0) + the error code +*/ + +/***************************************************************************/ + +/* Get the current file offset */ +extern uLong ZEXPORT unzGetOffset (unzFile file); + +/* Set the current file offset */ +extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + + +int gf_unzip_probe(const char *zipfilename); + +#ifdef __cplusplus +} +#endif + +#endif /* _unz_H */ diff --git a/modules/widgetman/wgt_load.c b/modules/widgetman/wgt_load.c new file mode 100644 index 0000000..f2783e7 --- /dev/null +++ b/modules/widgetman/wgt_load.c @@ -0,0 +1,290 @@ +//This software module was originally developed by TelecomParisTech in the +//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard. +// +//This software module is an implementation of a part of one or +//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets +//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets +//(ISO/IEC 23007-1) free license to this software module or modifications +//thereof for use in hardware or software products claiming conformance to +//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software +//module in hardware or software products are advised that its use may +//infringe existing patents. +//The original developer of this software module and his/her company, the +//subsequent editors and their companies, and ISO/IEC have no liability +//for use of this software module or modifications thereof in an implementation. +//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming +//products. +//Telecom ParisTech retains full right to use the code for his/her own purpose, +//assign or donate the code to a third party and to inhibit third parties from +//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products. +// +//This copyright notice must be included in all copies or derivative works. +// +//Copyright (c) 2009. +// +///////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// +// +// Authors: +// Cyril Concolato, Telecom ParisTech +// Jean Le Feuvre, Telecom ParisTech +// +///////////////////////////////////////////////////////////////////////////////// + + +#include <gpac/internal/terminal_dev.h> +#include <gpac/internal/scenegraph_dev.h> +#include <gpac/nodes_svg.h> +#include <gpac/constants.h> + +#ifdef GPAC_HAS_SPIDERMONKEY + +typedef struct +{ + GF_Scene *scene; + u8 oti; + char *file_name; + u32 file_size; + Bool loaded; +} WgtLoad; + +static GF_Err WGT_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBufferLength, + u16 ES_ID, u32 stream_time, u32 mmlevel) +{ + GF_Err e = GF_OK; + WgtLoad *wgtload = (WgtLoad *)plug->privateStack; + + if (stream_time==(u32)-1) { + gf_sg_reset(wgtload->scene->graph); + return GF_OK; + } + + switch (wgtload->oti) { + case GPAC_OTI_PRIVATE_SCENE_WGT: + if (wgtload->file_name && !wgtload->loaded) { + const char *path, *wmpath; + char *tmp; + GF_Node *n, *root; + GF_FieldInfo info; + FILE *jsfile; + GF_ChildNodeItem *last; + + wgtload->loaded = 1; + + gf_sg_add_namespace(wgtload->scene->graph, "http://www.w3.org/2000/svg", NULL); + gf_sg_add_namespace(wgtload->scene->graph, "http://www.w3.org/1999/xlink", "xlink"); + gf_sg_add_namespace(wgtload->scene->graph, "http://www.w3.org/2001/xml-events", "ev"); + gf_sg_set_scene_size_info(wgtload->scene->graph, 800, 600, 1); + + /* modify the scene with an Inline/Animation pointing to the widget start file URL */ + n = root = gf_node_new(wgtload->scene->graph, TAG_SVG_svg); + gf_node_register(root, NULL); + gf_sg_set_root_node(wgtload->scene->graph, root); + gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_viewBox, 1, 0, &info); + gf_svg_parse_attribute(n, &info, "0 0 320 240", 0); + gf_node_get_attribute_by_name(n, "xmlns", 0, 1, 0, &info); + gf_svg_parse_attribute(n, &info, "http://www.w3.org/2000/svg", 0); +/* + gf_sg_set_scene_size_info(wgtload->scene->graph, 800, 600, 1); + gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_width, 1, 0, &info); + gf_svg_parse_attribute(n, &info, "800", 0); + gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_height, 1, 0, &info); + gf_svg_parse_attribute(n, &info, "600", 0); +*/ + gf_node_init(n); + + n = gf_node_new(wgtload->scene->graph, TAG_SVG_animation); + gf_node_set_id(n, 1, "w_anim"); + gf_node_register(n, root); + gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last); + gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_width, 1, 0, &info); + gf_svg_parse_attribute(n, &info, "320", 0); + gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_height, 1, 0, &info); + gf_svg_parse_attribute(n, &info, "240", 0); + gf_node_init(n); + + tmp = wgtload->file_name; + while (tmp = strchr(tmp, '\\')) { + tmp[0] = '/'; + tmp++; + } + + n = gf_node_new(wgtload->scene->graph, TAG_SVG_script); + gf_node_register(n, root); + gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last); + path = gf_modules_get_option((GF_BaseInterface *)plug, "Widgets", "WidgetLoadScript"); + jsfile = path ? gf_f64_open(path, "rt") : NULL; + if (jsfile) { + fclose(jsfile); + gf_node_get_attribute_by_tag(n, TAG_XLINK_ATT_href, 1, 0, &info); + gf_svg_parse_attribute(n, &info, (char *) path, 0); + } else { + const char *load_fun = "function load_widget(wid_url) {\n" + " var wid = WidgetManager.load(wid_url);\n" + " var anim = document.getElementById('w_anim');\n" + " if (wid != null) {\n" + " wid.activate(anim);" + " anim.setAttributeNS('http://www.w3.org/1999/xlink', 'href', wid.main);\n" + " } else {\n" + " alert('Widget ' + wid_url + ' is not valid');\n" + " }\n" + "}\n"; + + gf_dom_add_text_node(n, gf_strdup(load_fun) ); + } + gf_node_init(n); + + + wmpath = gf_modules_get_option((GF_BaseInterface *)plug, "Widgets", "WidgetManagerScript"); + jsfile = wmpath ? gf_f64_open(wmpath, "rt") : NULL; + if (jsfile) { + fclose(jsfile); + n = gf_node_new(wgtload->scene->graph, TAG_SVG_script); + gf_node_register(n, root); + gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last); + gf_node_get_attribute_by_tag(n, TAG_XLINK_ATT_href, 1, 0, &info); + gf_svg_parse_attribute(n, &info, (char *) wmpath, 0); + gf_node_init(n); + + n = gf_node_new(wgtload->scene->graph, TAG_SVG_script); + gf_node_register(n, root); + gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last); + gf_dom_add_text_node(n, gf_strdup("widget_manager_init();") ); + gf_node_init(n); + } + + tmp = gf_malloc(sizeof(char) * (strlen(wgtload->file_name)+50) ); + sprintf(tmp, "load_widget(\"%s\");\n", wgtload->file_name); + + n = gf_node_new(wgtload->scene->graph, TAG_SVG_script); + gf_node_register(n, root); + gf_node_list_add_child_last(&((GF_ParentNode *)root)->children, n, &last); + gf_dom_add_text_node(n, gf_strdup(tmp) ); + gf_free(tmp); + + gf_node_init(n); + + if ((wgtload->scene->graph_attached!=1) && (gf_sg_get_root_node(wgtload->scene->graph)!=NULL) ) { + gf_scene_attach_to_compositor(wgtload->scene); + e = GF_EOS; + } + } + break; + + default: + return GF_BAD_PARAM; + } + return e; +} + +static GF_Err WGT_AttachScene(GF_SceneDecoder *plug, GF_Scene *scene, Bool is_scene_decoder) +{ + WgtLoad *wgtload = (WgtLoad *)plug->privateStack; + wgtload->scene = scene; + return GF_OK; +} + +static GF_Err WGT_ReleaseScene(GF_SceneDecoder *plug) +{ + WgtLoad *wgtload = (WgtLoad *)plug->privateStack; + wgtload->scene = NULL; + return GF_OK; +} + +static GF_Err WGT_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) +{ + GF_BitStream *bs; + WgtLoad *wgtload = (WgtLoad *)plug->privateStack; + if (esd->decoderConfig->upstream) return GF_NOT_SUPPORTED; + + /* decSpecInfo is not null only when reading from an WGT file (local or distant, cached or not) */ + switch (esd->decoderConfig->objectTypeIndication) { + case GPAC_OTI_PRIVATE_SCENE_WGT: + default: + if (!esd->decoderConfig->decoderSpecificInfo) return GF_NON_COMPLIANT_BITSTREAM; + bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); + wgtload->file_size = gf_bs_read_u32(bs); + gf_bs_del(bs); + wgtload->file_name = (char *) gf_malloc(sizeof(char)*(1 + esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32)) ); + memcpy(wgtload->file_name, esd->decoderConfig->decoderSpecificInfo->data + sizeof(u32), esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32) ); + wgtload->file_name[esd->decoderConfig->decoderSpecificInfo->dataLength - sizeof(u32) ] = 0; + break; + } + wgtload->oti = esd->decoderConfig->objectTypeIndication; + return GF_OK; +} + +static GF_Err WGT_DetachStream(GF_BaseDecoder *plug, u16 ES_ID) +{ + WgtLoad *wgtload = (WgtLoad *)plug->privateStack; + if (wgtload->file_name) gf_free(wgtload->file_name); + wgtload->file_name = NULL; + return GF_OK; +} + +const char *WGT_GetName(struct _basedecoder *plug) +{ + return "GPAC W3C Widget Loader"; +} + +Bool WGT_CanHandleStream(GF_BaseDecoder *ifce, u32 StreamType, u32 ObjectType, char *decSpecInfo, u32 decSpecInfoSize, u32 PL) +{ + if (StreamType==GF_STREAM_PRIVATE_SCENE) { + if (ObjectType==GPAC_OTI_PRIVATE_SCENE_WGT) return 1; + return 0; + } + return 0; +} + +static GF_Err WGT_GetCapabilities(GF_BaseDecoder *plug, GF_CodecCapability *cap) +{ + cap->cap.valueInt = 0; + if (cap->CapCode==GF_CODEC_PADDING_BYTES) { + /* Adding one byte of padding for \r\n problems*/ + cap->cap.valueInt = 1; + return GF_OK; + } + return GF_NOT_SUPPORTED; +} + +static GF_Err WGT_SetCapabilities(GF_BaseDecoder *plug, const GF_CodecCapability capability) +{ + return GF_OK; +} + +/*interface create*/ +GF_BaseInterface *LoadWidgetReader() +{ + WgtLoad *wgtload; + GF_SceneDecoder *sdec; + + GF_SAFEALLOC(sdec, GF_SceneDecoder) + GF_REGISTER_MODULE_INTERFACE(sdec, GF_SCENE_DECODER_INTERFACE, "GPAC W3C Widget Loader", "gpac distribution"); + + GF_SAFEALLOC(wgtload, WgtLoad); + sdec->privateStack = wgtload; + sdec->AttachStream = WGT_AttachStream; + sdec->CanHandleStream = WGT_CanHandleStream; + sdec->DetachStream = WGT_DetachStream; + sdec->AttachScene = WGT_AttachScene; + sdec->ReleaseScene = WGT_ReleaseScene; + sdec->ProcessData = WGT_ProcessData; + sdec->GetName = WGT_GetName; + sdec->SetCapabilities = WGT_SetCapabilities; + sdec->GetCapabilities = WGT_GetCapabilities; + return (GF_BaseInterface *)sdec; +} + + +/*interface destroy*/ +void ShutdownWidgetReader(GF_BaseInterface *ifce) +{ + GF_SceneDecoder *sdec = (GF_SceneDecoder *)ifce; + WgtLoad *wgtload = (WgtLoad *) sdec->privateStack; + + gf_free(wgtload); + gf_free(sdec); +} + +#endif /*GPAC_HAS_SPIDERMONKEY*/ diff --git a/modules/widgetman/wgt_load_base.js b/modules/widgetman/wgt_load_base.js new file mode 100644 index 0000000..bdaadbd --- /dev/null +++ b/modules/widgetman/wgt_load_base.js @@ -0,0 +1,84 @@ +var wid = null; +var xmlns_xlink = 'http://www.w3.org/1999/xlink'; + +function debug(s) { + alert('[Widget Loader] '+s); +} + +function add_text_span(parent, string) { + var span = document.createElement('tspan'); + span.textContent = string; + parent.appendChild(span); + parent.appendChild(document.createElement('tbreak')); +} + +function load_widget(wid_url) { + debug('Loading Widget: '+wid_url); + wid = WidgetManager.load(wid_url); + var anim = document.getElementById('w_anim'); + width = 320; + height = 240; + anim.setAttribute('height', height/3); + + var info = document.createElement('textArea'); + document.documentElement.appendChild(info); + info.setAttribute('y', height/3); + info.setAttribute('width', width); + + info.setAttribute('font-size', '7'); + info.setAttribute('font-family', 'Arial Unicode MS'); + if (wid != null) { + debug('Loading scene: '+wid.main); + anim.setAttributeNS(xmlns_xlink, 'href', wid.main); + add_text_span(info, 'Widget Metadata'); + add_text_span(info, 'UA Locale: \'' + gpac.getOption('Systems', 'Language2CC') + '\''); + add_text_span(info, 'widget src (abs.): \'' + wid.url + '\''); + add_text_span(info, 'config src (abs.): \'' + wid.manifest + '\''); + add_text_span(info, 'content src (rel.&loc./abs.): \''+wid.main+'\' / \''+wid.localizedSrc+'\' ('+wid.mainMimeType+';'+wid.mainEncoding+')'); + add_text_span(info, 'id: \'' + wid.identifier + '\''); + add_text_span(info, 'shortname/name: \''+wid.shortName+ '\' / \''+wid.name+'\''); + add_text_span(info, 'version: \''+wid.version+'\''); + add_text_span(info, 'license/href: \''+wid.license+'\' / \''+wid.licenseHref+'\''); + add_text_span(info, 'description: \''+wid.description+'\''); + add_text_span(info, 'author (name/email/href): \''+wid.authorName+ '\' / \''+wid.authorEmail +'\' / \''+wid.authorHref+'\''); + var s = 'icons src (rel.&loc./abs.): '; + for (var i=0; i<wid.icons.length; i++) { + if (i) s += ' , '; + s += '\'' + wid.icons[i].src + '\' / \'' + wid.icons[i].relocated_src + '\'' + ' ('+wid.icons[i].width+'x'+wid.icons[i].height+')'; + } + add_text_span(info, s); + + s = 'preferences: '; + for (var i=0; i<wid.preferences.length; i++) { + var p = wid.preferences[i]; + if (i) s += ' , '; + s += '' + p.name + '=\'' + p.value + '\' (ro:'+p.readonly+')'; + } + add_text_span(info, s); + + s = 'features: '; + add_text_span(info, s); + + for (var i=0; i<wid.features.length; i++) { + var f = wid.features[i]; + s = 'feature: '; + s += '' + f.name + '(' + f.required + ')'; + add_text_span(info, s); + if (f.params.length) { + s = '-params: '; + for (var j=0; j<f.params.length; j++) { + var p = f.params[j]; + if (j != 0) s += ' , '; + s += '' + p.name + '=\'' + p.value + '\''; + } + add_text_span(info, s); + } + } + + add_text_span(info, 'size: '+wid.defaultWidth+'x'+wid.defaultHeight); + add_text_span(info, 'viewmodes: \''+wid.viewmodes+'\''); + } else { + debug('Invalid Widget'); + info.textContent = 'Invalid widget - no info available'; + } +} diff --git a/modules/widgetman/widget.c b/modules/widgetman/widget.c new file mode 100644 index 0000000..2fd2ef6 --- /dev/null +++ b/modules/widgetman/widget.c @@ -0,0 +1,416 @@ +//This software module was originally developed by TelecomParisTech in the +//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard. +// +//This software module is an implementation of a part of one or +//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets +//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets +//(ISO/IEC 23007-1) free license to this software module or modifications +//thereof for use in hardware or software products claiming conformance to +//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software +//module in hardware or software products are advised that its use may +//infringe existing patents. +//The original developer of this software module and his/her company, the +//subsequent editors and their companies, and ISO/IEC have no liability +//for use of this software module or modifications thereof in an implementation. +//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming +//products. +//Telecom ParisTech retains full right to use the code for his/her own purpose, +//assign or donate the code to a third party and to inhibit third parties from +//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products. +// +//This copyright notice must be included in all copies or derivative works. +// +//Copyright (c) 2009. +// +///////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// +// +// Authors: +// Jean Le Feuvre, Telecom ParisTech +// +///////////////////////////////////////////////////////////////////////////////// + + +#include "widgetman.h" + +#ifdef GPAC_HAS_SPIDERMONKEY + +JSBool widget_has_feature(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + const char *feat_name; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_FALSE; + + if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE; + + feat_name = JS_GetStringBytes(JSVAL_TO_STRING( argv[0] )); + *rval = BOOLEAN_TO_JSVAL( JS_FALSE ); + + if (!strcmp(feat_name, "urn:mpeg:systems:mpeg-u:2009")) *rval = BOOLEAN_TO_JSVAL( JS_TRUE ); + + return JS_TRUE; +} + +JSBool widget_open_url(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_Event evt; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || !argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE; + + memset(&evt, 0, sizeof(GF_Event)); + evt.type = GF_EVENT_NAVIGATE; + evt.navigate.to_url = JS_GetStringBytes(JSVAL_TO_STRING( argv[0] )); + return gf_term_send_event(wid->widget->wm->term, &evt); + return JS_TRUE; +} + +JSBool widget_get_attention(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval fval; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_TRUE; + + if ((JS_LookupProperty(c, wid->widget->wm->obj, "getAttention", &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) { + jsval args[1]; + args[0] = OBJECT_TO_JSVAL(wid->obj); + JS_CallFunctionValue(c, wid->widget->wm->obj, fval, 1, args, rval); + } + return JS_TRUE; +} + +JSBool widget_show_notification(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval fval; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_TRUE; + + if ((JS_LookupProperty(c, wid->widget->wm->obj, "showNotification", &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) { + jsval *vars; + u32 i; + vars = gf_malloc(sizeof(jsval)*(argc+1)); + vars[0] = OBJECT_TO_JSVAL(wid->obj); + for (i=0; i<argc; i++) + vars[i+1] = argv[i]; + + JS_CallFunctionValue(c, wid->widget->wm->obj, fval, argc+1, vars, rval); + } + return JS_TRUE; +} + + +static JSBool widget_call_message_reply_callback(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSObject *list; + jsval *vals, fval; + u32 i, count; + GF_WidgetMessage *msg = JS_GetPrivate(c, obj); + if (!msg || !argc || !JSVAL_IS_OBJECT(argv[0]) ) return JS_FALSE; + + if ((JS_LookupProperty(c, obj, "replyCallback", &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) { + list = JSVAL_TO_OBJECT(argv[0]); + JS_GetArrayLength(c, list, (jsuint*) &count); + vals = gf_malloc(sizeof(jsval)*(count+1)); + vals[0] = OBJECT_TO_JSVAL(obj); + for (i=0; i<count; i++) { + JS_GetElement(c, list, (jsint) i, &vals[i+1]); + } + JS_CallFunctionValue(c, obj, fval, count, vals, rval); + gf_free(vals); + } + return JS_TRUE; +} + +static JSBool widget_message_handler_factory(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *msg_name; + u32 i, count; + GF_WidgetInstance *wid = NULL; + GF_WidgetInterfaceInstance *bifce = (GF_WidgetInterfaceInstance *)JS_GetPrivate(c, obj); + if (!bifce) return JS_FALSE; + + if (!argc) return JS_FALSE; + if (!JSVAL_IS_STRING(argv[0])) return JS_FALSE; + + msg_name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (!msg_name ) return JS_FALSE; + + *rval = JSVAL_NULL; + count = gf_list_count(bifce->ifce->messages); + 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); + JS_SetPrivate(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); + JS_DefineFunction(c, an_obj, "onInvokeReply", widget_call_message_reply_callback, 1, 0); + + if ((argc==2) && JSVAL_IS_OBJECT(argv[1]) && !JSVAL_IS_NULL(argv[1])) + JS_DefineProperty(c, an_obj, "replyCallback", argv[1], 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + + *rval = OBJECT_TO_JSVAL(an_obj); + } + } + return JS_TRUE; +} +static JSBool widget_invoke_message(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval oval; + GF_WidgetMessage *msg = NULL; + GF_WidgetInterfaceInstance *bifce = (GF_WidgetInterfaceInstance *)JS_GetPrivate(c, obj); + if (!bifce) return JS_FALSE; + + *rval = JSVAL_NULL; + + if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE; + if (JSVAL_IS_NULL(argv[0])) return JS_FALSE; + msg = (GF_WidgetMessage *)JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + if (!msg) return JS_FALSE; + + /*look for JS Callback "invoke" in the widget manager script*/ + if (JS_LookupProperty(c, bifce->ifce->obj, "invoke", &oval)==JS_TRUE) { + if (JSVAL_IS_OBJECT(oval)) { + JS_CallFunctionValue(bifce->wid->widget->wm->ctx, bifce->ifce->obj, oval, argc, argv, rval); + } + } + + return JS_TRUE; +} + +static JSBool widget_invoke_message_reply(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + jsval oval; + GF_WidgetMessage *msg = NULL; + GF_WidgetInterfaceInstance *bifce = (GF_WidgetInterfaceInstance *)JS_GetPrivate(c, obj); + if (!bifce) return JS_FALSE; + + *rval = JSVAL_NULL; + + if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE; + if (JSVAL_IS_NULL(argv[0])) return JS_FALSE; + msg = (GF_WidgetMessage *)JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + if (!msg) return JS_FALSE; + + /*look for JS Callback "invokeReply" in the widget manager script*/ + if (JS_LookupProperty(c, bifce->ifce->obj, "invokeReply", &oval)==JS_TRUE) { + if (JSVAL_IS_OBJECT(oval)) { + JS_CallFunctionValue(bifce->wid->widget->wm->ctx, bifce->ifce->obj, oval, argc, argv, rval); + } + } + return JS_TRUE; +} + +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); + JS_SetPrivate(c, ifce->obj, ifce); + gf_js_add_root(c, &ifce->obj); + JS_DefineProperty(c, ifce->obj, "type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ifce->ifce->type) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, ifce->obj, "bound", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ifce->hostname) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineFunction(c, ifce->obj, "invoke", widget_invoke_message, 1, 0); + JS_DefineFunction(c, ifce->obj, "msgHandlerFactory", widget_message_handler_factory, 1, 0); + JS_DefineFunction(c, ifce->obj, "invokeReply", widget_invoke_message_reply, 1, 0); + } +} + +static JSBool widget_get_interfaces(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 i, count; + char *ifce_name; + JSObject *list; + jsuint idx; + jsval v; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_FALSE; + + if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE; + ifce_name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + + list = JS_NewArrayObject(c, 0, 0); + + count = gf_list_count(wid->bound_ifces); + for (i=0; i<count; i++) { + GF_WidgetInterfaceInstance *ifce = gf_list_get(wid->bound_ifces, i); + if (strcmp(ifce->ifce->type, ifce_name)) continue; + + widget_interface_js_bind(c, ifce); + + JS_GetArrayLength(c, list, &idx); + v = OBJECT_TO_JSVAL(ifce->obj); + JS_SetElement(c, list, idx, &v); + } + *rval = OBJECT_TO_JSVAL(list); + return JS_TRUE; +} + +static JSBool widget_activate_component(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, Bool is_deactivate) +{ + u32 i, count; + char *comp_id; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_FALSE; + + if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE; + comp_id = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + + count = gf_list_count(wid->widget->main->components); + for (i=0; i<count; i++) { + GF_WidgetComponent *comp = gf_list_get(wid->widget->main->components, i); + if (!comp->id || strcmp(comp->id, comp_id)) continue; + + if (is_deactivate) { + wm_deactivate_component(c, wid, comp, NULL); + } else { + wm_activate_component(c, wid, comp, 0); + } + return JS_TRUE; + } + return JS_TRUE; +} + +static JSBool widget_activate_widget(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return widget_activate_component(c, obj, argc, argv, rval, 0); +} + +static JSBool widget_deactivate_widget(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return widget_activate_component(c, obj, argc, argv, rval, 1); +} + +void widget_on_interface_bind(GF_WidgetInterfaceInstance *ifce, Bool unbind) +{ + jsval funval, rval, argv[1]; + + const char *fun_name = unbind ? "onInterfaceUnbind" : "onInterfaceBind"; + if (!ifce || !ifce->wid || !ifce->wid->scene_context) return; + + /*look for JS Callback "invoke" in the widget manager script*/ + if (JS_LookupProperty(ifce->wid->scene_context, ifce->wid->scene_obj, fun_name, &funval)!=JS_TRUE) + return; + if (!JSVAL_IS_OBJECT(funval)) return; + + widget_interface_js_bind(ifce->wid->widget->wm->ctx, ifce); + argv[0] = OBJECT_TO_JSVAL(ifce->obj); + JS_CallFunctionValue(ifce->wid->widget->wm->ctx, ifce->ifce->obj, funval, 1, argv, &rval); + +} + +JSBool widget_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *rval) +{ + const char *opt; + char *prop_name; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_FALSE; + + if (!JSVAL_IS_STRING(id)) return JS_TRUE; + prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + if (!prop_name) return JS_FALSE; + + if (!strcmp(prop_name, "viewMode")) { + *rval = 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) ); + } + else if (!strcmp(prop_name, "identifier")) { + if (wid->widget->identifier) *rval = 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) ); + } + else if (!strcmp(prop_name, "authorEmail")) { + if (wid->widget->authorEmail) *rval = 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) ); + } + else if (!strcmp(prop_name, "name")) { + if (wid->widget->name) *rval = 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) ); + } + else if (!strcmp(prop_name, "description")) { + if (wid->widget->description) *rval = 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( JS_NewDouble(c, 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( JS_NewDouble(c, opt ? atoi(opt) : 0) ); + } + else if (!strcmp(prop_name, "preferences")) { + } + return JS_TRUE; +} + +JSBool widget_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + return JS_TRUE; +} + +void widget_load(GF_WidgetManager *wm, GF_SceneGraph *scene, JSContext *c, JSObject *global, Bool unload) +{ + u32 i, count; + GF_WidgetInstance *wi; + + /*Is this scenegraph a widget or not ? To find out, browse all widget instances*/ + i=0; + while ((wi = gf_list_enum(wm->widget_instances, &i))) { + if (!wi->scene || (wi->scene != scene)) continue; + break; + } + if (!wi) return; + + /*OK we found our widget*/ + + if (unload) { + /*detach all bound interfaces from this script*/ + count = gf_list_count(wi->bound_ifces); + for (i=0; i<count; i++) { + GF_WidgetInterfaceInstance *ifce = gf_list_get(wi->bound_ifces, i); + if (ifce->obj) { + JS_SetPrivate(c, ifce->obj, NULL); + gf_js_remove_root(c, &ifce->obj); + ifce->obj = NULL; + } + } + return; + } else { + + JSPropertySpec widgetClassProps[] = { + {0, 0, 0, 0, 0} + }; + JSFunctionSpec widgetClassFuncs[] = { + /*W3C*/ + {"has_feature", widget_has_feature, 1, 0, 0}, + {"openURL", widget_open_url, 1, 0, 0}, + {"getAttention", widget_get_attention, 0, 0, 0}, + {"showNotification", widget_show_notification, 0, 0, 0}, + /*MPEG*/ + {"getInterfaceHandlersByType", widget_get_interfaces, 1, 0, 0}, + {"activateComponentWidget", widget_activate_widget, 1, 0, 0}, + {"deactivateComponentWidget", widget_deactivate_widget, 1, 0, 0}, + {0, 0, 0, 0, 0} + }; + + 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); + JS_AliasProperty(c, global, "widget", "MPEGWidget"); + JS_SetPrivate(c, wi->scene_obj, wi); + /*and remember the script*/ + wi->scene_context = c; + wi->scene_global = global; + } +} + +#endif diff --git a/modules/widgetman/widgetman.c b/modules/widgetman/widgetman.c new file mode 100644 index 0000000..37001ea --- /dev/null +++ b/modules/widgetman/widgetman.c @@ -0,0 +1,3510 @@ +//This software module was originally developed by TelecomParisTech in the +//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard. +// +//This software module is an implementation of a part of one or +//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets +//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets +//(ISO/IEC 23007-1) free license to this software module or modifications +//thereof for use in hardware or software products claiming conformance to +//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software +//module in hardware or software products are advised that its use may +//infringe existing patents. +//The original developer of this software module and his/her company, the +//subsequent editors and their companies, and ISO/IEC have no liability +//for use of this software module or modifications thereof in an implementation. +//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming +//products. +//Telecom ParisTech retains full right to use the code for his/her own purpose, +//assign or donate the code to a third party and to inhibit third parties from +//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products. +// +//This copyright notice must be included in all copies or derivative works. +// +//Copyright (c) 2009. +// +///////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// +// +// Authors: +// Jean Le Feuvre, Telecom ParisTech +// Cyril Concolato, Telecom ParisTech +// +///////////////////////////////////////////////////////////////////////////////// + +#include "widgetman.h" + +#ifdef GPAC_HAS_SPIDERMONKEY + +#if !defined(__GNUC__) +# if defined(_WIN32_WCE) +# pragma comment(lib, "js") +# elif defined (WIN32) +# pragma comment(lib, "js32") +# endif +#endif + + +JSBool gf_sg_js_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node); +JSBool gf_sg_js_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node); + + + +static Bool is_same_path(const char *p1, const char *p2, u32 len) +{ + char c1, c2; + u32 i=0; + do { + if (len && (i==len)) + break; + c1 = p1[i]; + c2 = p2[i]; + if (p1[i] != p2[i]) { + if ((c1=='/') && (c2=='\\')) {} + else if ((c1=='\\') && (c2=='/')) {} + else return 0; + } + i++; + } while (c1); + return 1; +} + +static void widget_package_extract_file(GF_WidgetPackage *wpack, GF_WidgetPackageResource *res) +{ + u32 i, count; + + if (wpack->is_zip) { + unz_global_info gi; + unzFile uf = unzOpen2(wpack->package_path, NULL); + if (!uf) return; + + unzGetGlobalInfo(uf, &gi); + for (i=0; i<gi.number_entry; i++) { + char buf[8192]; + int err; + FILE *fout; + char filename_inzip[256]; + + unz_file_info file_info; + unzGetCurrentFileInfo(uf, &file_info, filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); + + if (strcmp(res->inner_path, filename_inzip)) { + if ((i+1)<gi.number_entry) + unzGoToNextFile(uf); + continue; + } + + unzOpenCurrentFile3(uf, NULL, NULL, 0, NULL/*password*/); + + fout=gf_f64_open(res->extracted_path, "wb"); + if (!fout) break; + do { + err = unzReadCurrentFile(uf,buf,8192); + if (err<0) break; + if (err>0) + if (fwrite(buf,err,1,fout)!=1) { + err=UNZ_ERRNO; + break; + } + } while (err>0); + if (fout) fclose(fout); + + res->extracted = 1; + break; + } + unzClose(uf); + } else { + GF_ISOFile *isom = gf_isom_open(wpack->package_path, GF_ISOM_OPEN_READ, 0); + if (!isom ) return; + + count = gf_isom_get_meta_item_count(isom, 1, 0); + for (i=0; i<count; i++) { + u32 ID; + const char *url, *urn, *enc; + Bool self_ref; + const char *item_name; + + gf_isom_get_meta_item_info(isom, 1, 0, i+1, &ID, NULL, &self_ref, &item_name, NULL, &enc, &url, &urn); + if (strcmp(res->inner_path, item_name)) continue; + + gf_isom_extract_meta_item(isom, 1, 0, ID, res->extracted_path); + res->extracted = 1; + break; + } + gf_isom_close(isom); + } + +} + +static Bool package_find_res(GF_WidgetPackage *wpack, char *res_path, char *relocated_path, char *localized_rel_path) +{ + u32 count, i; + count = gf_list_count(wpack->resources); + for (i=0;i<count;i++) { + GF_WidgetPackageResource *pack_res = gf_list_get(wpack->resources, i); + if (is_same_path(res_path, pack_res->inner_path, 0)) { + strcpy(localized_rel_path, res_path); + strcpy(relocated_path, pack_res->extracted_path); + if (!pack_res->extracted) widget_package_extract_file(wpack, pack_res); + return 1; + } + } + return 0; +} + +/* Checks if a resource in the package has the given rel_path, potentially in a localized sub-folder */ +static Bool widget_package_relocate_uri(void *__self, const char *parent_uri, const char *rel_path, char *relocated_path, char *localized_rel_path) +{ + char path[GF_MAX_PATH]; + const char *opt; + GF_WidgetPackage *wpack = (GF_WidgetPackage *)__self; + + assert(parent_uri); + /*resource belongs to our archive*/ + if (strstr(rel_path, wpack->archive_id)) { + rel_path = strstr(rel_path, wpack->archive_id) + strlen(wpack->archive_id); + } + /*parent resource belongs to our archive*/ + else if (strstr(parent_uri, wpack->archive_id)) { + } + /*resource doesn't belong to our archive*/ + else { + return 0; + } + + /* First try to locate the resource in the locales folder */ + opt = gf_cfg_get_key(wpack->wm->term->user->config, "Systems", "Language2CC"); + if (opt) { + if (!strcmp(opt, "*") || !strcmp(opt, "un") ) + opt = NULL; + } + + while (opt) { + char lan[100]; + char *sep; + char *sep_lang = strchr(opt, ';'); + if (sep_lang) sep_lang[0] = 0; + + while (strchr(" \t", opt[0])) + opt++; + strcpy(lan, opt); + + if (sep_lang) { + sep_lang[0] = ';'; + opt = sep_lang+1; + } else { + opt = NULL; + } + + while (1) { + sep = strstr(lan, "-*"); + if (!sep) break; + strncpy(sep, sep+2, strlen(sep)-2); + } + + sprintf(path, "locales/%s/%s", lan, rel_path); + if (package_find_res(wpack, path, relocated_path, localized_rel_path)) + return 1; + + /*recursively remove region (sub)tags*/ + while (1) { + sep = strrchr(lan, '-'); + if (!sep) break; + sep[0] = 0; + sprintf(path, "locales/%s/%s", lan, rel_path); + if (package_find_res(wpack, path, relocated_path, localized_rel_path)) + return 1; + } + } + + /*no locale*/ + if (package_find_res(wpack, (char*)rel_path, relocated_path, localized_rel_path)) + return 1; + + strcpy(localized_rel_path, ""); + strcpy(relocated_path, ""); + return 0; +} + +static GF_WidgetPackage *widget_isom_new(GF_WidgetManager *wm, const char *path) +{ + GF_WidgetPackageResource *pack_res; + char szPath[GF_MAX_PATH]; + const char *dir; + GF_WidgetPackage *wzip; + u32 brand = 0; + u32 meta = 0; + u32 i, count; + GF_ISOFile *isom = gf_isom_open(path, GF_ISOM_OPEN_READ, 0); + if (!isom ) return NULL; + + brand = gf_isom_get_meta_type(isom, 1, 0); + if ((brand!=GF_4CC('m','w','g','t') ) || !gf_isom_has_meta_xml(isom, 1, 0) ) { + gf_isom_close(isom); + return NULL; + } + + GF_SAFEALLOC(wzip, GF_WidgetPackage); + + wzip->wm = wm; + wzip->relocate_uri = widget_package_relocate_uri; + wzip->resources = gf_list_new(); + dir = gf_cfg_get_key(wm->term->user->config, "General", "CacheDirectory"); + /* create the extracted path for the package root using: + the cache dir + a CRC of the file path and the instance*/ + sprintf(wzip->root_extracted_path, "%s%08X", path, (u32) wzip); + i = gf_crc_32((char *)wzip->root_extracted_path, strlen(wzip->root_extracted_path)); + sprintf(wzip->archive_id, "GWM_%08X_", i); + sprintf(wzip->root_extracted_path, "%s/%s", dir, wzip->archive_id); + + + strcpy(szPath, wzip->root_extracted_path); + strcat(szPath, "config.xml"); + if (gf_isom_extract_meta_xml(isom, 1, 0, szPath, NULL) != GF_OK) { + gf_list_del(wzip->resources); + gf_free(wzip); + gf_isom_close(isom); + return NULL; + } + + wzip->package_path = gf_strdup(path); + + GF_SAFEALLOC(pack_res, GF_WidgetPackageResource); + pack_res->extracted_path = gf_strdup(szPath); + pack_res->inner_path = gf_strdup("config.xml"); + pack_res->extracted = 1; + gf_list_add(wzip->resources, pack_res); + + + count = gf_isom_get_meta_item_count(isom, 1, 0); + for (i=0; i<count; i++) { + u32 ID; + const char *url, *urn, *enc; + Bool self_ref; + char *sep; + const char *item_name; + + gf_isom_get_meta_item_info(isom, 1, 0, i+1, &ID, NULL, &self_ref, &item_name, NULL, &enc, &url, &urn); + + sep = strrchr(item_name, '/'); + if (!sep) sep = strrchr(item_name, '\\'); + if (sep) { + sep[0] = 0; + sprintf(szPath, "%s_%08X_%s", wzip->root_extracted_path, gf_crc_32((char*)item_name, strlen(item_name)), sep+1); + sep[0] = '/'; + } else { + strcpy(szPath, wzip->root_extracted_path); + strcat(szPath, item_name); + } + GF_SAFEALLOC(pack_res, GF_WidgetPackageResource); + pack_res->extracted_path = gf_strdup(szPath); + pack_res->inner_path = gf_strdup(item_name); + pack_res->extracted = 0; + gf_list_add(wzip->resources, pack_res); + } + gf_isom_close(isom); + + + /* register this widget package as a relocator to enable localization of resources inside this package */ + gf_mx_p(wm->term->net_mx); + gf_list_add(wm->term->uri_relocators, wzip); + gf_mx_v(wm->term->net_mx); + return wzip; +} + +static GF_WidgetPackage *widget_zip_new(GF_WidgetManager *wm, const char *path) +{ + unz_global_info gi; + const char *dir; + u32 i; + GF_WidgetPackage *wzip; + unzFile uf = unzOpen2(path, NULL); + if (!uf) return NULL; + + GF_SAFEALLOC(wzip, GF_WidgetPackage); + + wzip->wm = wm; + wzip->is_zip = 1; + wzip->relocate_uri = widget_package_relocate_uri; + wzip->resources = gf_list_new(); + wzip->package_path = gf_strdup(path); + dir = gf_cfg_get_key(wm->term->user->config, "General", "CacheDirectory"); + /* create the extracted path for the package root using: + the cache dir + a CRC of the file path and the instance*/ + sprintf(wzip->root_extracted_path, "%s%08X", path, (u32) wzip); + i = gf_crc_32((char *)wzip->root_extracted_path, strlen(wzip->root_extracted_path)); + sprintf(wzip->archive_id, "GWM_%08X_", i); + sprintf(wzip->root_extracted_path, "%s/%s", dir, wzip->archive_id); + + unzGetGlobalInfo(uf, &gi); + for (i=0; i<gi.number_entry; i++) { + char szPath[GF_MAX_PATH]; + char *sep; + GF_WidgetPackageResource *pack_res; + char filename_inzip[256]; + unz_file_info file_info; + unzGetCurrentFileInfo(uf, &file_info, filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0); + + sep = strrchr(filename_inzip, '/'); + if (!sep) sep = strrchr(filename_inzip, '\\'); + if (sep) { + sep[0] = 0; + sprintf(szPath, "%s_%08X_%s", wzip->root_extracted_path, gf_crc_32(filename_inzip, strlen(filename_inzip)), sep+1); + sep[0] = '/'; + } else { + strcpy(szPath, wzip->root_extracted_path); + strcat(szPath, filename_inzip); + } + + + if (!strcmp(filename_inzip, "config.xml")) { + int err; + char buf[8192]; + FILE *fout; + unzOpenCurrentFile3(uf, NULL, NULL, 0, NULL/*password*/); + + fout=gf_f64_open(szPath,"wb"); + if (!fout) return NULL; + + do { + err = unzReadCurrentFile(uf,buf,8192); + if (err<0) break; + + if (err>0) + if (fwrite(buf,err,1,fout)!=1) { + err=UNZ_ERRNO; + break; + } + } while (err>0); + if (fout) fclose(fout); + if (err==0) { + GF_SAFEALLOC(pack_res, GF_WidgetPackageResource); + pack_res->extracted_path = gf_strdup(szPath); + pack_res->inner_path = gf_strdup(filename_inzip); + pack_res->extracted = 1; + gf_list_add(wzip->resources, pack_res); + } + } else { + GF_SAFEALLOC(pack_res, GF_WidgetPackageResource); + pack_res->extracted_path = gf_strdup(szPath); + pack_res->inner_path = gf_strdup(filename_inzip); + pack_res->extracted = 0; + gf_list_add(wzip->resources, pack_res); + } + + if ((i+1)<gi.number_entry) + unzGoToNextFile(uf); + } + unzClose(uf); + + /* register this widget package as a relocator to enable localization of resources inside this package */ + gf_mx_p(wm->term->net_mx); + gf_list_add(wm->term->uri_relocators, wzip); + gf_mx_v(wm->term->net_mx); + return wzip; +} + +GF_WidgetPackage *widget_package_new(GF_WidgetManager *wm, const char *path) +{ + if (gf_unzip_probe(path)) { + return widget_zip_new(wm, path); + } + /*ISOFF-based packaged widget */ + else if (gf_isom_probe_file(path)) { + return widget_isom_new(wm, path); + } + return NULL; +} + +static void widget_package_del(GF_WidgetManager *wm, GF_WidgetPackage *wpackage) +{ + gf_mx_p(wm->term->net_mx); + gf_list_del_item(wm->term->uri_relocators, wpackage); + gf_mx_v(wm->term->net_mx); + + while (gf_list_count(wpackage->resources)) { + GF_WidgetPackageResource *wu = gf_list_get(wpackage->resources, 0); + gf_list_rem(wpackage->resources, 0); + gf_delete_file(wu->extracted_path); + gf_free(wu->extracted_path); + gf_free(wu->inner_path); + gf_free(wu); + } + gf_list_del(wpackage->resources); + if (wpackage->sess) gf_dm_sess_del(wpackage->sess); + gf_free(wpackage->package_path); + gf_free(wpackage); +} + + + +static void wm_delete_message_param(GF_WidgetPin *mp) +{ + if (!mp) return; + if (mp->node) gf_free(mp->node); + if (mp->attribute) gf_free(mp->attribute); + if (mp->default_value) gf_free(mp->default_value); + if (mp->name) gf_free(mp->name); + gf_free(mp); +} + +static void wm_delete_widget_content(GF_WidgetContent *content) +{ + if (!content) return; + + while (gf_list_count(content->interfaces)) { + GF_WidgetInterface*ifce = gf_list_last(content->interfaces); + gf_list_rem_last(content->interfaces); + + while (gf_list_count(ifce->messages)) { + GF_WidgetMessage *msg = gf_list_last(ifce->messages); + gf_list_rem_last(ifce->messages); + + while (gf_list_count(msg->params)) { + GF_WidgetPin *par = gf_list_last(msg->params); + gf_list_rem_last(msg->params); + wm_delete_message_param(par); + } + gf_list_del(msg->params); + + wm_delete_message_param(msg->input_action); + wm_delete_message_param(msg->output_trigger); + gf_free(msg->name); + gf_free(msg); + } + gf_list_del(ifce->messages); + wm_delete_message_param(ifce->bind_action); + wm_delete_message_param(ifce->unbind_action); + if (ifce->obj) gf_js_remove_root(ifce->content->widget->wm->ctx, &ifce->obj); + + if (ifce->connectTo) gf_free(ifce->connectTo); + gf_free(ifce->type); + gf_free(ifce); + } + gf_list_del(content->interfaces); + + while (gf_list_count(content->components)) { + GF_WidgetComponent *comp = gf_list_last(content->components); + gf_list_rem_last(content->components); + + wm_delete_message_param(comp->activateTrigger); + wm_delete_message_param(comp->deactivateTrigger); + + while (gf_list_count(comp->required_interfaces)) { + char *type = gf_list_last(comp->required_interfaces); + gf_list_rem_last(comp->required_interfaces); + if (type) gf_free(type); + } + gf_list_del(comp->required_interfaces); + if (comp->id) gf_free(comp->id); + if (comp->src) gf_free(comp->src); + gf_free(comp); + } + gf_list_del(content->components); + + while (gf_list_count(content->preferences)) { + GF_WidgetPreference *pref = gf_list_last(content->preferences); + gf_list_rem_last(content->preferences); + + wm_delete_message_param(pref->connectTo); + if (pref->value) gf_free(pref->value); + gf_free(pref->name); + gf_free(pref); + } + gf_list_del(content->preferences); + + wm_delete_message_param(content->saveTrigger); + wm_delete_message_param(content->restoreTrigger); + wm_delete_message_param(content->savedAction); + wm_delete_message_param(content->restoredAction); + + gf_free(content->src); + gf_free(content->relocated_src); + gf_free(content->mimetype); + gf_free(content->encoding); + gf_free(content); +} + +static void wm_delete_widget(GF_WidgetManager *wm, GF_Widget *wid) +{ + gf_list_del_item(wm->widgets, wid); + + if (wid->url) gf_free(wid->url); + if (wid->manifest_path) gf_free(wid->manifest_path); + wm_delete_widget_content(wid->main); + if (wid->local_path) gf_free(wid->local_path); + if (wid->name) gf_free(wid->name); + if (wid->shortname) gf_free(wid->shortname); + if (wid->identifier) gf_free(wid->identifier); + if (wid->authorName) gf_free(wid->authorName); + if (wid->authorEmail) gf_free(wid->authorEmail); + if (wid->authorHref) gf_free(wid->authorHref); + if (wid->description) gf_free(wid->description); + if (wid->license) gf_free(wid->license); + if (wid->licenseHref) gf_free(wid->licenseHref); + if (wid->viewmodes) gf_free(wid->viewmodes); + if (wid->version) gf_free(wid->version); + if (wid->uuid) gf_free(wid->uuid); + + + while (gf_list_count(wid->icons)) { + GF_WidgetContent *icon = gf_list_get(wid->icons, 0); + gf_list_rem(wid->icons, 0); + wm_delete_widget_content(icon); + } + gf_list_del(wid->icons); + + while (gf_list_count(wid->features)) { + GF_WidgetFeature *f = gf_list_get(wid->features, 0); + gf_list_rem(wid->features, 0); + if (f->name) gf_free(f->name); + while (gf_list_count(f->params)) { + GF_WidgetFeatureParam *p = gf_list_get(f->params, 0); + gf_list_rem(f->params, 0); + if (p->name) gf_free(p->name); + if (p->value) gf_free(p->value); + gf_free(p); + } + gf_free(f); + } + gf_list_del(wid->features); + + if (wid->wpack) widget_package_del(wm, wid->wpack); + gf_free(wid); +} + +static void wm_delete_interface_instance(GF_WidgetManager *wm, GF_WidgetInterfaceInstance *bifce) +{ + if (bifce->hostname) gf_free(bifce->hostname); + if (bifce->obj) { + JS_SetPrivate(wm->ctx, bifce->obj, NULL); + gf_js_remove_root(wm->ctx, &bifce->obj); + } + gf_free(bifce); +} + +static void wm_delete_widget_instance(GF_WidgetManager *wm, GF_WidgetInstance *widg) +{ + + while (gf_list_count(widg->components)) { + GF_WidgetComponentInstance *comp = gf_list_get(widg->components, 0); + gf_list_rem(widg->components, 0); + if (comp->wid) wm_delete_widget_instance(wm, comp->wid); + gf_free(comp); + } + gf_list_del(widg->components); + + while (gf_list_count(widg->bound_ifces)) { + GF_WidgetInterfaceInstance *bifce = gf_list_get(widg->bound_ifces, 0); + gf_list_rem(widg->bound_ifces, 0); + wm_delete_interface_instance(wm, bifce); + } + gf_list_del(widg->bound_ifces); + + gf_list_del(widg->output_triggers); + + if (widg->obj) { + JS_SetPrivate(wm->ctx, widg->obj, NULL); + gf_js_remove_root(wm->ctx, &widg->obj); + } + gf_list_del_item(wm->widget_instances, widg); + widg->widget->nb_instances--; + if (!widg->widget->nb_instances) wm_delete_widget(wm, widg->widget); + + if (!widg->permanent) { + gf_cfg_del_section(wm->term->user->config, widg->secname); + gf_cfg_set_key(wm->term->user->config, "Widgets", widg->secname, NULL); + } + if (widg->mpegu_context) gf_xml_dom_del(widg->mpegu_context); + + gf_free(widg); +} + + + +static JSBool wm_widget_call_script(GF_WidgetInstance *wid, GF_WidgetPin *pin, uintN argc, jsval *argv, jsval *rval) +{ + jsval fval; + if (!wid->scene_context || !wid->scene_global) return JS_FALSE; + + /*if on_load property is assigned to this widget, add an event listener on the root.*/ + JS_LookupProperty(wid->scene_context, wid->scene_global, pin->node, &fval); + if (JSVAL_IS_OBJECT(fval)) { + JS_CallFunctionValue(wid->scene_context, wid->scene_global, fval, argc, argv, rval); + } + return JS_TRUE; +} + +static JSBool wm_widget_set_scene_input_value(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, u32 type, GF_WidgetInstance *wid, GF_WidgetPin *param, const char *value) +{ + const char *str_val; + GF_Node *n; + GF_FieldInfo info; + GF_WidgetMessage *msg; + GF_WidgetInterface *ifce; + + if (!wid && obj) wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_FALSE; + if (!wid->scene) return JS_TRUE; + + if (!param) { + if (!JSVAL_IS_OBJECT(argv[0])) return JS_TRUE; + + switch (type) { + /*set_input*/ + case 0: + if (argc!=2) return JS_FALSE; + param = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + break; + /*call_input_action*/ + case 1: + msg = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + param = msg ? msg->input_action : NULL; + break; + /*bind_interface*/ + case 2: + ifce = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + param = ifce ? ifce->bind_action : NULL; + break; + /*unbind_interface*/ + case 3: + ifce = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + param = ifce ? ifce->unbind_action : NULL; + break; + } + } + + if (!param || !param->node) return JS_TRUE; + /*this is a script call*/ + if (!param->attribute) { + return wm_widget_call_script(wid, param, 0, NULL, rval); + } + + n = gf_sg_find_node_by_name(wid->scene, param->node); + if (!n) return JS_TRUE; + + if (param->in_action) return JS_TRUE; + + param->in_action = 1; + +#ifndef GPAC_DISABLE_SVG + if (n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) { + u32 evt_type; + if (!type) { + if (value) { + str_val = value; + } else { + if (!JSVAL_IS_STRING(argv[1])) goto exit; + str_val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + } + + /* first check if the set_input refers to an attribute name or to an event name */ + evt_type = gf_dom_event_type_by_name(param->attribute); + + /*events are not allowed for <input> and <output>*/ + if (evt_type == GF_EVENT_UNKNOWN) { + /* modify an attribute */ + if (!strcmp(param->attribute, "textContent")) { + gf_dom_set_textContent(n, (char *)str_val); + gf_node_changed(n, NULL); + } + else { + if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) { + gf_svg_parse_attribute(n, &info, (char *)str_val, 0); + if (info.fieldType==XMLRI_datatype) gf_node_dirty_set(n, GF_SG_SVG_XLINK_HREF_DIRTY, 0); + gf_node_changed(n, &info); + } + } + } + } else { + GF_DOM_Event evt; + memset(&evt, 0, sizeof(GF_DOM_Event)); + /* first check if the set_input refers to an attribute name or to an event name */ + evt_type = gf_dom_event_type_by_name(param->attribute); + /* launch an event */ + if (evt_type != GF_EVENT_UNKNOWN) { + evt.type = evt_type; + gf_dom_event_fire(n, &evt); + } else { + /*should we fire a DOMAttrModified event ? to clarify in the spec*/ + + if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) { + evt.bubbles = 1; + evt.type = GF_EVENT_ATTR_MODIFIED; + evt.attr = &info; + gf_dom_event_fire(n, &evt); + } + } + } + } else +#endif + + +#ifndef GPAC_DISABLE_VRML + { + if (gf_node_get_field_by_name(n, param->attribute, &info) != GF_OK) return JS_TRUE; + + if (!type) { + jsdouble val; + + switch (info.fieldType) { + case GF_SG_VRML_SFSTRING: + if (value) { + str_val = value; + } else { + if (!JSVAL_IS_STRING(argv[1]))goto exit; + str_val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + } + if ( ((SFString*)info.far_ptr)->buffer) gf_free(((SFString*)info.far_ptr)->buffer); + ((SFString*)info.far_ptr)->buffer = str_val ? gf_strdup(str_val) : NULL; + break; + case GF_SG_VRML_SFBOOL: + if (value) *((SFBool*)info.far_ptr) = (!strcmp(value, "true")) ? 1 : 0; + else if (JSVAL_IS_BOOLEAN(argv[1])) *((SFBool*)info.far_ptr) = JSVAL_TO_BOOLEAN(argv[1]); + else if (JSVAL_IS_INT(argv[1])) *((SFBool*)info.far_ptr) = JSVAL_TO_INT(argv[1]); + else if (JSVAL_IS_STRING(argv[1])) { + str_val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + *((SFBool*)info.far_ptr) = (str_val && !strcmp(str_val, "true")) ? 1 : 0; + } else + goto exit; + break; + case GF_SG_VRML_SFINT32: + if (value) *((SFInt32*)info.far_ptr) = (s32) atof(value); + else if (JSVAL_IS_INT(argv[1])) *((SFInt32*)info.far_ptr) = JSVAL_TO_INT(argv[1]); + else if (JSVAL_IS_NUMBER(argv[1])) { + JS_ValueToNumber(c, argv[1], &val); + *((SFInt32*)info.far_ptr) = (s32) val; + } else if (JSVAL_IS_STRING(argv[1])) { + Double a_val; + str_val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + a_val = str_val ? atof(str_val) : 0; + *((SFInt32*)info.far_ptr) = (s32) a_val; + } else + goto exit; + break; + case GF_SG_VRML_SFFLOAT: + if (value) *((SFFloat*)info.far_ptr) = FLT2FIX(atof(value)); + else if (JSVAL_IS_INT(argv[1])) *((SFFloat *)info.far_ptr) = INT2FIX( JSVAL_TO_INT(argv[1]) ); + else if (JSVAL_IS_NUMBER(argv[1])) { + JS_ValueToNumber(c, argv[1], &val); + *((SFFloat *)info.far_ptr) = FLT2FIX( val ); + } else if (JSVAL_IS_STRING(argv[1])) { + Double a_val; + str_val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + a_val = str_val ? atof(str_val) : 0; + *((SFFloat*)info.far_ptr) = FLT2FIX(a_val); + } else + goto exit; + break; + case GF_SG_VRML_SFTIME: + if (value) *((SFTime*)info.far_ptr) = atof(value); + else if (JSVAL_IS_INT(argv[1])) *((SFTime *)info.far_ptr) = JSVAL_TO_INT(argv[1]); + else if (JSVAL_IS_NUMBER(argv[1])) { + JS_ValueToNumber(c, argv[1], &val); + *((SFTime *)info.far_ptr) = val; + } else if (JSVAL_IS_STRING(argv[1])) { + Double a_val; + str_val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + a_val = str_val ? atof(str_val) : 0; + *((SFTime *)info.far_ptr) = a_val; + } else + goto exit; + break; + case GF_SG_VRML_MFSTRING: + if (value) { + str_val = value; + } else { + if (!JSVAL_IS_STRING(argv[1])) goto exit; + str_val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); + } + if ( ((GenMFField *)info.far_ptr)->count != 1) { + gf_sg_vrml_mf_reset(info.far_ptr, GF_SG_VRML_MFSTRING); + gf_sg_vrml_mf_alloc(info.far_ptr, GF_SG_VRML_MFSTRING, 1); + } + if ( ((MFString*)info.far_ptr)->vals[0]) gf_free( ((MFString*)info.far_ptr)->vals[0] ); + ((MFString*)info.far_ptr)->vals[0] = str_val ? gf_strdup(str_val) : NULL; + break; + } + } + + //if this is a script eventIn call directly script + if ((n->sgprivate->tag==TAG_MPEG4_Script) || (n->sgprivate->tag==TAG_X3D_Script) ) + gf_sg_script_event_in(n, &info); + + gf_node_changed(n, &info); + + /*if this is an exposedField, route it*/ + if (info.eventType==GF_SG_EVENT_EXPOSED_FIELD) { + gf_node_event_out(n, info.fieldIndex); + } + } +#endif /*GPAC_DISABLE_VRML*/ + +exit: + param->in_action = 0; + return JS_TRUE; +} + + +static JSBool wm_widget_set_input(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return wm_widget_set_scene_input_value(c, obj, argc, argv, rval, 0, NULL, NULL, NULL); +} +static JSBool wm_widget_call_input_action(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return wm_widget_set_scene_input_value(c, obj, 1, argv, rval, 1, NULL, NULL, NULL); +} + + +static JSBool wm_widget_call_input_script(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_WidgetMessage *msg; + GF_WidgetPin *param; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || (argc!=2) ) return JS_FALSE; + if (!wid->scene) return JS_TRUE; + + if (!JSVAL_IS_OBJECT(argv[0])) return JS_TRUE; + msg = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + param = msg ? msg->input_action : NULL; + if (!param || !param->node || param->attribute) return JS_FALSE; + + if (JSVAL_IS_OBJECT(argv[1])) { + jsval *args; + JSObject *list = JSVAL_TO_OBJECT(argv[1]); + u32 i, count; + JS_GetArrayLength(c, list, (jsuint*) &count); + args = gf_malloc(sizeof(jsval)*count); + for (i=0; i<count; i++) { + JS_GetElement(c, list, (jsint) i, &args[i] ); + } + + wm_widget_call_script(wid, param, count, args, rval); + + gf_free(args); + } + return JS_TRUE; +} + + +static void wm_handler_destroy(GF_Node *node, void *rs, Bool is_destroy) +{ + if (is_destroy) { + SVG_handlerElement *handler = (SVG_handlerElement *)node; + if (handler->js_fun_val) { + gf_js_remove_root(handler->js_context, &handler->js_fun_val); + handler->js_fun_val=0; + } + } +} + +static SVG_handlerElement *wm_create_scene_listener(GF_WidgetInstance *wid, GF_WidgetPin *param) +{ + /*FIXME - we need to split SVG and base DOM !!*/ +#ifdef GPAC_DISABLE_SVG + return NULL; +#else + u32 evt_type, att_name; + GF_Node *listener; + GF_FieldInfo info; + GF_Node *n = NULL; + SVG_handlerElement *handler; + + evt_type = GF_EVENT_ATTR_MODIFIED; + n = gf_sg_find_node_by_name(wid->scene, param->node); + if (!n) return NULL; + + att_name = 0; + +#ifndef GPAC_DISABLE_SVG + if (n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) { + /* first check if the set_input refers to an attribute name or to an event name */ + evt_type = gf_dom_event_type_by_name(param->attribute); + if (evt_type == GF_EVENT_UNKNOWN) { + evt_type = GF_EVENT_ATTR_MODIFIED; + + /* modify textContent */ + if (!strcmp(param->attribute, "textContent")) { + att_name = (u32) -1; + } + /* modify an attribute */ + else if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) { + att_name = info.fieldIndex; + } + else { + return NULL; + } + } + } else +#endif + { + if (gf_node_get_field_by_name(n, param->attribute, &info) != GF_OK) + return NULL; + att_name = info.fieldIndex; + } + + listener = gf_node_new(wid->scene, TAG_SVG_listener); + + handler = (SVG_handlerElement *) gf_node_new(wid->scene, TAG_SVG_handler); + /*we register the handler with the listener node to avoid modifying the DOM*/ + gf_node_register((GF_Node *)handler, listener); + gf_node_list_add_child(& ((GF_ParentNode *)listener)->children, (GF_Node*)handler); + handler->sgprivate->UserCallback = wm_handler_destroy; + + /*create attributes if needed*/ + gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_event, 1, 0, &info); + ((XMLEV_Event*)info.far_ptr)->type = evt_type; + ((XMLEV_Event*)info.far_ptr)->parameter = att_name; + gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_handler, 1, 0, &info); + ((XMLRI*)info.far_ptr)->target = (GF_Node*)handler; + gf_node_get_attribute_by_tag(listener, TAG_XMLEV_ATT_target, 1, 0, &info); + ((XMLRI*)info.far_ptr)->target = n; + + gf_node_get_attribute_by_tag((GF_Node*)handler, TAG_XMLEV_ATT_event, 1, 0, &info); + ((XMLEV_Event*)info.far_ptr)->type = evt_type; + ((XMLEV_Event*)info.far_ptr)->parameter = att_name; + + gf_node_dom_listener_add((GF_Node *) n, listener); + + return handler; +#endif +} + +static void wm_component_activation_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer, Bool unload) +{ + JSObject *obj; + JSContext *c; + GF_WidgetInstance *wid; + GF_WidgetComponent *comp; + SVG_handlerElement *handler = (SVG_handlerElement *)hdl; + + c = handler->js_context; + obj = handler->evt_listen_obj; + if (!c || !obj) return; + wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return; + + comp = (GF_WidgetComponent *)handler->js_fun; + if (unload) { + wm_deactivate_component(c, wid, comp, NULL); + } else { + wm_activate_component(c, wid, comp, 0); + } +} +static void wm_component_activate_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer) +{ + wm_component_activation_event(hdl, evt, observer, 0); +} +static void wm_component_deactivate_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer) +{ + wm_component_activation_event(hdl, evt, observer, 1); +} + +static void wm_widget_set_pref_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer) +{ + char *att; + SVG_handlerElement *handler = (SVG_handlerElement *)hdl; + GF_WidgetInstance *wid = (GF_WidgetInstance *) handler->evt_listen_obj; + GF_WidgetPreference *pref = (GF_WidgetPreference *) handler->js_fun; + + if (evt->type != GF_EVENT_ATTR_MODIFIED) return; + + if (evt->detail == (u32) -1) { + att = gf_dom_flatten_textContent(evt->target); + } else { + att = gf_node_dump_attribute(evt->target, evt->attr); + if (!att) return; + } + gf_cfg_set_key(wid->widget->wm->term->user->config, wid->secname, pref->name, att); + gf_free(att); +} + +static void on_widget_activated(JSContext *c, JSObject *obj) +{ + jsval funval, rval; + u32 i, count; + GF_XMLNode *context = NULL; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || wid->activated) return; + + /*widget is now activated*/ + wid->activated = 1; + + /*for all components, setup bindings on activateTrigger & deactivateTrigger*/ + count = gf_list_count(wid->widget->main->components); + for (i=0; i<count; i++) { + GF_WidgetComponent *comp = gf_list_get(wid->widget->main->components, i); + /*setup listener*/ + if (comp->activateTrigger && comp->activateTrigger->attribute) { + SVG_handlerElement *a_hdl = wm_create_scene_listener(wid, comp->activateTrigger); + if (!a_hdl) return; + a_hdl->evt_listen_obj = obj; + a_hdl->js_context = c; + a_hdl->js_fun = comp; + a_hdl->handle_event = wm_component_activate_event; + } + /*setup listener*/ + if (comp->deactivateTrigger && comp->deactivateTrigger->attribute) { + SVG_handlerElement *a_hdl = wm_create_scene_listener(wid, comp->deactivateTrigger); + if (!a_hdl) continue; + a_hdl->evt_listen_obj = obj; + a_hdl->js_context = c; + a_hdl->js_fun = comp; + a_hdl->handle_event = wm_component_deactivate_event; + } + } + + if (wid->mpegu_context) + context = gf_xml_dom_get_root(wid->mpegu_context); + + /*load preferences*/ + count = gf_list_count(wid->widget->main->preferences); + for (i=0; i<count; i++) { + const char *value; + GF_WidgetPreference *pref = gf_list_get(wid->widget->main->preferences, i); + + + /*get stored value for this preference*/ + value = gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, pref->name); + /*if none found, use preference*/ + if (!value) value = pref->value; + + /*and overload with migrated context*/ + if (context) { + GF_XMLNode *pref_node; + u32 j=0; + while ((pref_node = gf_list_enum(context->content, &j))) { + const char *att; + if (pref_node->type != GF_XML_NODE_TYPE) continue; + if (strcmp(pref_node->name, "preference")) continue; + att = wm_xml_get_attr(pref_node, "name"); + if (!att) continue; + if (strcmp(att, pref->name)) continue; + + att = wm_xml_get_attr(pref_node, "value"); + if (att) value = att; + break; + } + } + + if (pref->connectTo) { + SVG_handlerElement *hdl; + + if (value) + wm_widget_set_scene_input_value(NULL, NULL, 0, 0, 0, 0, wid, pref->connectTo, value); + + /*preference is read only, do not setup listener*/ + if (pref->flags & GF_WM_PREF_READONLY) continue; + /*preference is migratable only, do not setup listener*/ + if (!(pref->flags & GF_WM_PREF_SAVE)) continue; + + /*create the listener*/ + hdl = wm_create_scene_listener(wid, pref->connectTo); + if (!hdl) continue; + + hdl->evt_listen_obj = wid; + hdl->js_fun = pref; + hdl->handle_event = wm_widget_set_pref_event; + + } + } + if (count && wid->widget->main->restoredAction) { + wm_widget_set_scene_input_value(wid->widget->wm->ctx, wid->obj, 0, NULL, &rval, 0, wid, wid->widget->main->restoredAction, NULL); + } + + if (wid->mpegu_context) { + gf_xml_dom_del(wid->mpegu_context); + wid->mpegu_context = NULL; + } + + /*refresh all interface bindings*/ + JS_LookupProperty(wid->widget->wm->ctx, wid->widget->wm->obj, "check_bindings", &funval); + if (JSVAL_IS_OBJECT(funval)) { + JS_CallFunctionValue(wid->widget->wm->ctx, wid->widget->wm->obj, funval, 0, 0, &rval); + } + + /*if on_load property is assigned to this widget, call it.*/ + JS_LookupProperty(c, obj, "on_load", &funval); + if (JSVAL_IS_OBJECT(funval)) { + JS_CallFunctionValue(wid->widget->wm->ctx, wid->obj, funval, 0, 0, &rval); + } +} + + +static void wm_widget_load_event(GF_Node *hdl, GF_DOM_Event *evt, GF_Node *observer) +{ + JSObject *obj; + JSContext *c; + SVG_handlerElement *handler = (SVG_handlerElement *)hdl; + + c = handler->js_context; + obj = handler->evt_listen_obj; + if (!c || !obj) return; + + on_widget_activated(c, obj); +} + + +static JSBool wm_widget_activate(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + SVG_handlerElement *handler; + GF_MediaObject *mo; + Bool direct_trigger = 0; + MFURL url; + SFURL _url; + GF_Node *inl; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || !argc) return JS_FALSE; + + if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE; + + inl = gf_sg_js_get_node(c, JSVAL_TO_OBJECT(argv[0]) ); + if (!inl) return JS_FALSE; + + _url.OD_ID = 0; + _url.url = gf_url_concatenate(wid->widget->url, wid->widget->main->relocated_src); + url.count = 1; + url.vals = &_url; + mo = gf_mo_register(inl, &url, 0, 1); + if (mo) { + wid->scene = gf_mo_get_scenegraph(mo); + if (wid->scene && gf_sg_get_root_node(wid->scene)) direct_trigger = 1; + } + if (_url.url) gf_free(_url.url); + + wid->anchor = inl; + + if (direct_trigger) { + on_widget_activated(c, obj); + } else { +#ifndef GPAC_DISABLE_SVG + handler = gf_dom_listener_build(inl, GF_EVENT_SCENE_ATTACHED, 0); + handler->handle_event = wm_widget_load_event; + handler->js_context = c; + handler->evt_listen_obj = obj; +#endif + } + + return JS_TRUE; +} + + +static void wm_handle_dom_event(GF_Node *hdl, GF_DOM_Event *event, GF_Node *observer) +{ + JSBool ret; + GF_FieldInfo info; + GF_Node *n; + jsval argv[1], rval, jsfun; + SVG_handlerElement *handler = (SVG_handlerElement *) hdl; + GF_WidgetPin *param = handler->js_fun; + GF_WidgetInstance *wid = (GF_WidgetInstance *)handler->evt_listen_obj; + + if (!wid->scene) + return; + + n = gf_sg_find_node_by_name(wid->scene, param->node); + if (!n) return; + + /*this is a regular event output*/ + if (event->type != GF_EVENT_ATTR_MODIFIED) { + jsfun = (jsval) handler->js_fun_val; + if (JSVAL_IS_OBJECT(jsfun)) + ret = JS_CallFunctionValue(handler->js_context, wid->obj, (jsval) handler->js_fun_val, 0, 0, &rval); + return; + } + + /*otherwise this is a node.attr output through DOMAttributeModified*/ + argv[0] = JSVAL_NULL; + +#ifndef GPAC_DISABLE_SVG + if (n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) { + if (!strcmp(param->attribute, "textContent")) { + char *txt = gf_dom_flatten_textContent(n); + argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(handler->js_context, txt ? txt : "") ); + if (txt) gf_free(txt); + } else if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) { + char *attValue; + if (event->attr->fieldIndex != info.fieldIndex) return; + + attValue = gf_node_dump_attribute(n, &info); + argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(handler->js_context, attValue) ); + if (attValue) gf_free(attValue); + } else { + return; + } + } else +#endif + { + if (gf_node_get_field_by_name(n, param->attribute, &info) != GF_OK) return; + if (event->attr->fieldIndex != info.fieldIndex) return; + + switch (info.fieldType) { + case GF_SG_VRML_SFSTRING: + argv[0] = STRING_TO_JSVAL( JS_NewStringCopyZ(handler->js_context, ((SFString*)info.far_ptr)->buffer ) ); + break; + case GF_SG_VRML_SFINT32: + argv[0] = INT_TO_JSVAL( *((SFInt32*)info.far_ptr) ); + break; + case GF_SG_VRML_SFBOOL: + argv[0] = BOOLEAN_TO_JSVAL( *((SFBool*)info.far_ptr) ); + break; + case GF_SG_VRML_SFFLOAT: + argv[0] = DOUBLE_TO_JSVAL( JS_NewDouble(handler->js_context, FIX2FLT( *((SFFloat*)info.far_ptr) ) ) ); + break; + case GF_SG_VRML_SFTIME: + argv[0] = DOUBLE_TO_JSVAL( JS_NewDouble(handler->js_context, *((SFTime *)info.far_ptr) ) ); + break; + } + } + + jsfun = (jsval) handler->js_fun_val; + if (JSVAL_IS_OBJECT(jsfun)) + ret = JS_CallFunctionValue(handler->js_context, wid->obj, (jsval) handler->js_fun_val, 1, argv, &rval); +} + +static JSBool wm_widget_get_param_value(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_Node *n; + GF_FieldInfo info; + GF_WidgetPin *param; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || !wid->scene || !argc || !JSVAL_IS_OBJECT(argv[0]) ) return JS_FALSE; + + param = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + if (!param) return JS_FALSE; + + if (!param->node) { + if (param->default_value) { + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, param->default_value) ); + return JS_TRUE; + } + return JS_FALSE; + } + + n = gf_sg_find_node_by_name(wid->scene, param->node); + if (!n) return JS_FALSE; + +#ifndef GPAC_DISABLE_SVG + if (n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) { + if (!strcmp(param->attribute, "textContent")) { + char *txt = gf_dom_flatten_textContent(n); + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, txt ? txt : "") ); + if (txt) gf_free(txt); + } else if (gf_node_get_attribute_by_name(n, param->attribute, 0, 1, 0, &info)==GF_OK) { + char *attValue = gf_node_dump_attribute(n, &info); + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, attValue) ); + if (attValue) gf_free(attValue); + } else { + return JS_FALSE; + } + } else +#endif + { + if (gf_node_get_field_by_name(n, param->attribute, &info) != GF_OK) return JS_FALSE; + + switch (info.fieldType) { + case GF_SG_VRML_SFSTRING: + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, ((SFString*)info.far_ptr)->buffer ) ); + break; + case GF_SG_VRML_SFINT32: + *rval = INT_TO_JSVAL( *((SFInt32*)info.far_ptr) ); + break; + case GF_SG_VRML_SFBOOL: + *rval = BOOLEAN_TO_JSVAL( *((SFBool*)info.far_ptr) ); + break; + case GF_SG_VRML_SFFLOAT: + *rval = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT( *((SFFloat*)info.far_ptr) ) ) ); + break; + case GF_SG_VRML_SFTIME: + *rval = DOUBLE_TO_JSVAL( JS_NewDouble(c, *((SFTime *)info.far_ptr) ) ); + break; + } + } + + return JS_TRUE; +} + +static JSBool wm_wm_widget_get_message_param(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_WidgetPin *par = NULL; + GF_WidgetMessage *msg = (GF_WidgetMessage *)JS_GetPrivate(c, obj); + if (!msg || !argc ) return JS_FALSE; + + if (JSVAL_IS_INT(argv[0])) { + u32 idx = JSVAL_TO_INT(argv[0]); + par = gf_list_get(msg->params, idx); + } else if (JSVAL_IS_STRING(argv[0])) { + u32 i, count = gf_list_count(msg->params); + char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + for (i=0; i<count; i++) { + par = gf_list_get(msg->params, i); + if (!strcmp(par->name, name)) break; + par = NULL; + } + } + + if (par) { + JSObject *obj = JS_NewObject(c, &msg->ifce->content->widget->wm->widgetAnyClass, 0, 0); + JS_SetPrivate(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); + switch (par->script_type) { + case GF_WM_PARAM_SCRIPT_BOOL: + JS_DefineProperty(c, obj, "script_type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, "boolean") ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + break; + case GF_WM_PARAM_SCRIPT_NUMBER: + JS_DefineProperty(c, obj, "script_type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, "number") ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + break; + case GF_WM_PARAM_SCRIPT_STRING: + default: + JS_DefineProperty(c, obj, "script_type", STRING_TO_JSVAL( JS_NewStringCopyZ(c, "string") ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + break; + } + *rval = OBJECT_TO_JSVAL(obj); + } + return JS_TRUE; +} + +static JSBool wm_widget_get_message(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_WidgetMessage *msg; + GF_WidgetInterface *ifce = (GF_WidgetInterface*)JS_GetPrivate(c, obj); + if (!ifce || !argc) return JS_FALSE; + + if (JSVAL_IS_INT(argv[0])) { + u32 idx; + idx = JSVAL_TO_INT(argv[0]); + msg = gf_list_get(ifce->messages, idx); + } else if (JSVAL_IS_STRING(argv[0])) { + u32 i, count = gf_list_count(ifce->messages); + char *name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + for (i=0; i<count; i++) { + msg = gf_list_get(ifce->messages, i); + if (!strcmp(msg->name, name)) break; + msg = NULL; + } + } + if (msg) { + JSObject *obj = JS_NewObject(c, &ifce->content->widget->wm->widgetAnyClass, 0, 0); + JS_SetPrivate(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); + JS_DefineProperty(c, obj, "is_input", BOOLEAN_TO_JSVAL( msg->is_output ? JS_FALSE : JS_TRUE ) , 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, obj, "has_output_trigger", BOOLEAN_TO_JSVAL( msg->output_trigger ? JS_TRUE : JS_FALSE) , 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, obj, "has_input_action", BOOLEAN_TO_JSVAL( (msg->input_action && msg->input_action->attribute) ? JS_TRUE : JS_FALSE) , 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, obj, "has_script_input", BOOLEAN_TO_JSVAL( (msg->input_action && !msg->input_action->attribute) ? JS_TRUE : JS_FALSE) , 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineFunction(c, obj, "get_param", wm_wm_widget_get_message_param, 1, 0); + + *rval = OBJECT_TO_JSVAL(obj); + } + return JS_TRUE; +} + +static JSBool wm_widget_get_component(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + const char *comp_id; + u32 i, count; + GF_WidgetComponentInstance *comp_inst; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || !argc || !JSVAL_IS_STRING(argv[0]) ) return JS_FALSE; + + comp_id = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + count = gf_list_count(wid->components); + for (i=0; i<count;i++) { + comp_inst = gf_list_get(wid->components, i); + if (comp_inst->comp->id && !strcmp(comp_inst->comp->id, comp_id)) { + *rval = OBJECT_TO_JSVAL(comp_inst->wid->obj); + return JS_TRUE; + } + } + /*if requested load the component*/ + if ((argc==2) && JSVAL_IS_BOOLEAN(argv[1]) && (JSVAL_TO_BOOLEAN(argv[1])==JS_TRUE) ) { + count = gf_list_count(wid->widget->main->components); + for (i=0; i<count; i++) { + GF_WidgetComponent *comp = gf_list_get(wid->widget->main->components, i); + if (!comp->id || strcmp(comp->id, comp_id)) continue; + + comp_inst = wm_activate_component(c, wid, comp, 1); + if (comp_inst) { + *rval = OBJECT_TO_JSVAL(comp_inst->wid->obj); + return JS_TRUE; + } + return JS_TRUE; + } + + + } + return JS_TRUE; +} + + + +static JSBool wm_widget_get_interface(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 idx; + GF_WidgetInterface *ifce; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || !argc || !JSVAL_IS_INT(argv[0]) ) return JS_FALSE; + + idx = JSVAL_TO_INT(argv[0]); + ifce = gf_list_get(wid->widget->main->interfaces, idx); + + if (ifce) { + if (!ifce->obj) { + ifce->obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0); + JS_SetPrivate(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); + JS_DefineProperty(c, ifce->obj, "serviceProvider", BOOLEAN_TO_JSVAL( ifce->provider ? JS_TRUE : JS_FALSE ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, ifce->obj, "multipleBinding", BOOLEAN_TO_JSVAL( ifce->multiple_binding ? JS_TRUE : JS_FALSE ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineFunction(c, ifce->obj, "get_message", wm_widget_get_message, 1, 0); + gf_js_add_root(c, &ifce->obj); + } + *rval = OBJECT_TO_JSVAL(ifce->obj); + } + return JS_TRUE; +} + + + +static JSBool wm_widget_bind_output_trigger(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_WidgetMessage *msg; + GF_WidgetPin *param; + SVG_handlerElement *handler; + + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || !wid->scene || (argc!=3)) return JS_FALSE; + + if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE; + if (!JSVAL_IS_OBJECT(argv[1])) return JS_FALSE; + if (!JSVAL_IS_OBJECT(argv[2])) return JS_FALSE; + + msg = (GF_WidgetMessage *)JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0])); + if (!msg) return JS_FALSE; + param = msg->output_trigger; + if (!param) return JS_FALSE; + + + handler = wm_create_scene_listener(wid, param); + if (!handler) return JS_FALSE; + handler->js_fun_val = argv[1]; + gf_js_add_root(c, &handler->js_fun_val); + handler->evt_listen_obj = wid; + handler->js_fun = param; + handler->js_context = c; + handler->handle_event = wm_handle_dom_event; + handler->sgprivate->UserPrivate = JSVAL_TO_OBJECT(argv[2]); + + gf_list_add(wid->output_triggers, handler); + + return JS_TRUE; +} + +static JSBool wm_widget_get_context(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_BitStream *bs; + u32 i, count; + const char *str; + char *att; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || !wid->scene) return JS_FALSE; + + bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<contextInformation xmlns=\"urn:mpeg:mpegu:schema:widgets:contextinfo:2010\">\n"; + gf_bs_write_data(bs, (u8 *) str, strlen(str) ); + + count = gf_list_count(wid->widget->main->preferences); + for (i=0; i<count; i++) { + GF_WidgetPreference *pref = gf_list_get(wid->widget->main->preferences, i); + + /*preference is read only, do not include in context*/ + if (pref->flags & GF_WM_PREF_READONLY) continue; + /*preference is not migratable, do not include in context*/ + if (!(pref->flags & GF_WM_PREF_MIGRATE)) continue; + + str = " <preference name=\""; + gf_bs_write_data(bs, (u8 *) str, strlen(str) ); + + gf_bs_write_data(bs, (u8 *) pref->name, strlen(pref->name) ); + + str = "\" value=\""; + gf_bs_write_data(bs, (u8 *) str, strlen(str) ); + + /*read from node*/ + if (pref->connectTo && pref->connectTo->attribute) { + GF_FieldInfo info; + GF_Node *n = gf_sg_find_node_by_name(wid->scene, pref->connectTo->node); + if (n) { + +#ifndef GPAC_DISABLE_SVG + if ((n->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) && !strcmp(pref->connectTo->attribute, "textContent")) { + char *txt = gf_dom_flatten_textContent(n); + gf_bs_write_data(bs, (u8 *) txt, strlen(txt) ); + } else +#endif + if (gf_node_get_field_by_name(n, pref->connectTo->attribute, &info)==GF_OK) { + att = gf_node_dump_attribute(n, &info); + if (att) { + gf_bs_write_data(bs, (u8 *) att, strlen(att) ); + gf_free(att); + } + } + } + } + /*read from config*/ + else { + att = (char *)gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, pref->name); + if (!att) att = pref->value; + + if (att) gf_bs_write_data(bs, (u8 *) att, strlen(att) ); + } + + str = "\"/>\n"; + gf_bs_write_data(bs, (u8 *) str, strlen(str) ); + } + str = "</contextInformation>\n"; + gf_bs_write_data(bs, (u8 *) str, strlen(str) ); + + gf_bs_write_u8(bs, 0); + att = NULL; + gf_bs_get_content(bs, &att, &count); + gf_bs_del(bs); + + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, att) ); + gf_free(att); + + return JS_TRUE; +} + + +static JSBool wm_widget_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + JSString *s; + char *prop_name; + const char *opt; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_FALSE; + + if (!JSVAL_IS_STRING(id)) return JS_TRUE; + prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + if (!prop_name) return JS_FALSE; + + /* + Manifest properties + */ + if (!strcmp(prop_name, "manifest")) { + s = JS_NewStringCopyZ(c, wid->widget->manifest_path); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "url")) { + s = JS_NewStringCopyZ(c, wid->widget->local_path ? wid->widget->local_path : wid->widget->url); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "main")) { + s = JS_NewStringCopyZ(c, wid->widget->main->relocated_src); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "localizedSrc")) { + s = JS_NewStringCopyZ(c, wid->widget->main->src); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "mainEncoding")) { + s = JS_NewStringCopyZ(c, wid->widget->main->encoding); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "mainMimeType")) { + s = JS_NewStringCopyZ(c, wid->widget->main->mimetype); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "defaultWidth")) { + *vp = INT_TO_JSVAL(wid->widget->width); + } + else if (!strcmp(prop_name, "defaultHeight")) { + *vp = INT_TO_JSVAL(wid->widget->height); + } + else if (!strcmp(prop_name, "icons")) { + u32 i, count; + JSObject *arr; + count = gf_list_count(wid->widget->icons); + arr = JS_NewArrayObject(c, count, NULL); + for (i = 0; i<count; i++) { + GF_WidgetContent *icon = gf_list_get(wid->widget->icons, i); + if (icon) { + char *abs_reloc_url; + jsval icon_obj_val; + JSObject *icon_obj = JS_NewObject(c, &wid->widget->wm->widgetAnyClass, 0, 0); + JS_SetPrivate(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); + else abs_reloc_url = gf_strdup(""); + JS_DefineProperty(c, icon_obj, "relocated_src", STRING_TO_JSVAL( JS_NewStringCopyZ(c, abs_reloc_url) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, icon_obj, "width", INT_TO_JSVAL( icon->width ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, icon_obj, "height", INT_TO_JSVAL( icon->height ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + icon_obj_val = OBJECT_TO_JSVAL(icon_obj); + JS_SetElement(c, arr, i, &icon_obj_val); + gf_free(abs_reloc_url); + } + } + *vp = OBJECT_TO_JSVAL(arr); + } + else if (!strcmp(prop_name, "preferences")) { + u32 i, count; + JSObject *arr; + count = gf_list_count(wid->widget->main->preferences); + arr = JS_NewArrayObject(c, count, NULL); + for (i = 0; i<count; i++) { + 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); + JS_SetPrivate(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); + JS_DefineProperty(c, pref_obj, "readonly", STRING_TO_JSVAL( JS_NewStringCopyZ(c, ((pref->flags & GF_WM_PREF_READONLY)?"true":"false")) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + pref_obj_val = OBJECT_TO_JSVAL(pref_obj); + JS_SetElement(c, arr, i, &pref_obj_val); + } + } + *vp = OBJECT_TO_JSVAL(arr); + } + else if (!strcmp(prop_name, "features")) { + u32 i, count; + JSObject *arr; + count = gf_list_count(wid->widget->features); + arr = JS_NewArrayObject(c, count, NULL); + for (i = 0; i<count; i++) { + 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); + JS_SetPrivate(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); + { + u32 j, pcount; + JSObject *params_arr; + pcount = gf_list_count(feat->params); + 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); + jsval param_obj_val; + JS_SetPrivate(c, param_obj, param); + JS_DefineProperty(c, param_obj, "name", STRING_TO_JSVAL( JS_NewStringCopyZ(c, param->name) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + JS_DefineProperty(c, param_obj, "value", STRING_TO_JSVAL( JS_NewStringCopyZ(c, param->value) ), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + param_obj_val = OBJECT_TO_JSVAL(param_obj); + JS_SetElement(c, params_arr, j, ¶m_obj_val); + } + JS_DefineProperty(c, feat_obj, "params", OBJECT_TO_JSVAL(params_arr), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT); + } + feat_obj_val = OBJECT_TO_JSVAL(feat_obj); + JS_SetElement(c, arr, i, &feat_obj_val); + } + } + *vp = OBJECT_TO_JSVAL(arr); + } + + else if (!strcmp(prop_name, "components")) { + u32 i, count; + jsval val; + JSObject *arr; + count = gf_list_count(wid->components); + arr = JS_NewArrayObject(c, count, NULL); + for (i = 0; i<count; i++) { + GF_WidgetComponentInstance *comp = gf_list_get(wid->components, i); + val = OBJECT_TO_JSVAL(comp->wid->obj); + JS_SetElement(c, arr, i, &val); + } + *vp = OBJECT_TO_JSVAL(arr); + } + else if (!strcmp(prop_name, "identifier")) { + s = JS_NewStringCopyZ(c, wid->widget->identifier); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "name")) { + s = JS_NewStringCopyZ(c, wid->widget->name); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "shortName")) { + s = JS_NewStringCopyZ(c, wid->widget->shortname); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "authorName")) { + s = JS_NewStringCopyZ(c, wid->widget->authorName); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "authorEmail")) { + s = JS_NewStringCopyZ(c, wid->widget->authorEmail); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "authorHref")) { + s = JS_NewStringCopyZ(c, wid->widget->authorHref); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "description")) { + s = JS_NewStringCopyZ(c, wid->widget->description); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "viewmodes")) { + if (wid->widget->viewmodes) s = JS_NewStringCopyZ(c, wid->widget->viewmodes); + else s = JS_NewStringCopyZ(c, ""); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "license")) { + s = JS_NewStringCopyZ(c, wid->widget->license); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "licenseHref")) { + s = JS_NewStringCopyZ(c, wid->widget->licenseHref); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "version")) { + s = JS_NewStringCopyZ(c, wid->widget->version); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "uuid")) { + s = JS_NewStringCopyZ(c, wid->widget->uuid); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "discardable")) { + *vp = BOOLEAN_TO_JSVAL( wid->widget->discardable ? JS_TRUE : JS_FALSE); + } + else if (!strcmp(prop_name, "multipleInstances")) { + *vp = BOOLEAN_TO_JSVAL( wid->widget->multipleInstance ? JS_TRUE : JS_FALSE); + } + + /* + Widget Manager special properties (common to all implementations) + */ + else if (!strcmp(prop_name, "permanent")) { + *vp = BOOLEAN_TO_JSVAL( wid->permanent ? JS_TRUE : JS_FALSE); + } + else if (!strcmp(prop_name, "is_component")) { + *vp = BOOLEAN_TO_JSVAL( wid->parent ? JS_TRUE : JS_FALSE); + } + else if (!strcmp(prop_name, "parent")) { + *vp = wid->parent ? OBJECT_TO_JSVAL(wid->parent->obj) : JSVAL_NULL; + } + else if (!strcmp(prop_name, "activated")) { + *vp = BOOLEAN_TO_JSVAL( wid->activated ? JS_TRUE : JS_FALSE); + } + else if (!strcmp(prop_name, "section")) { + s = JS_NewStringCopyZ(c, wid->secname); + *vp = STRING_TO_JSVAL(s); + } + else if (!strcmp(prop_name, "num_instances")) { + *vp = INT_TO_JSVAL( wid->widget->nb_instances); + } + else if (!strcmp(prop_name, "num_interfaces")) { + *vp = INT_TO_JSVAL( gf_list_count(wid->widget->main->interfaces)); + } + else if (!strcmp(prop_name, "num_components")) { + *vp = INT_TO_JSVAL( gf_list_count(wid->components)); + } + else if (!strcmp(prop_name, "num_bound_interfaces")) { + *vp = INT_TO_JSVAL( gf_list_count(wid->bound_ifces)); + } + /*all variables used by the WidgetManager script but not stored*/ + else if (!strcmp(prop_name, "originating_device_ip") + || !strcmp(prop_name, "originating_device") + || !strcmp(prop_name, "device") + ) { + } + /* + Widget properties, common to each implementation + */ + else { + char szName[1024]; + sprintf(szName, "WM:%s", prop_name); + opt = gf_cfg_get_key(wid->widget->wm->term->user->config, wid->secname, szName); + if (opt) { + Double val=0; + if (!strcmp(opt, "true")) *vp = BOOLEAN_TO_JSVAL(JS_TRUE); + else if (!strcmp(opt, "false")) *vp = BOOLEAN_TO_JSVAL(JS_FALSE); + else if (sscanf(opt, "%lf", &val)==1) { + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, val) ); + } else { + s = JS_NewStringCopyZ(c, opt); + *vp = STRING_TO_JSVAL(s); + } + } + } + + return JS_TRUE; +} +static JSBool wm_widget_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + char szVal[32]; + jsdouble val; + char *prop_name; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_FALSE; + + if (!JSVAL_IS_STRING(id)) return JS_TRUE; + prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + + /*internal to WidgetManager, never stored*/ + if (!strcmp(prop_name, "permanent")) { + wid->permanent = (JSVAL_TO_BOOLEAN(*vp)==JS_TRUE) ? 1 : 0; + } + + /*any widget properties*/ + else { + char szName[1024], *value; + + if (JSVAL_IS_STRING(*vp)) { + value = JS_GetStringBytes(JSVAL_TO_STRING(*vp)); + if (!value) value = ""; + } + else if (JSVAL_IS_BOOLEAN(*vp)) { + strcpy(szVal, (JSVAL_TO_BOOLEAN(*vp)==JS_TRUE) ? "true" : "false"); + value = szVal; + } + else if (JSVAL_IS_NUMBER(*vp)) { + JS_ValueToNumber(c, *vp, &val); + sprintf(szVal, "%f", val); + value = szVal; + } else { + return JS_TRUE; + } + + sprintf(szName, "WM:%s", prop_name); + gf_cfg_set_key(wid->widget->wm->term->user->config, wid->secname, szName, value); + } + + return JS_TRUE; +} + + + +static JSBool wm_widget_bind_interface_ex(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, Bool is_unbind) +{ + u32 i, count; + GF_WidgetInterfaceInstance *bifce; + GF_WidgetInterface *ifce; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || !wid->scene) return JS_FALSE; + + ifce = NULL; + if (argc) { + if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE; + ifce = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + if (!ifce) return JS_FALSE; + } + + if (!is_unbind) { + char *hostname; + JSObject *cookie; + if ((argc<3) || !JSVAL_IS_OBJECT(argv[1]) || !JSVAL_IS_STRING(argv[2])) return JS_FALSE; + + cookie = JSVAL_TO_OBJECT(argv[1]); + hostname = JS_GetStringBytes(JSVAL_TO_STRING(argv[2]) ); + count = gf_list_count(wid->bound_ifces); + for (i=0; i<count; i++) { + bifce = gf_list_get(wid->bound_ifces, i); + if (!strcmp(bifce->ifce->type, ifce->type) && (bifce->cookie==cookie) ) return JS_TRUE; + } + GF_SAFEALLOC(bifce, GF_WidgetInterfaceInstance); + bifce->wid = wid; + bifce->ifce = ifce; + bifce->cookie = cookie; + bifce->hostname = gf_strdup(hostname); + gf_list_add(wid->bound_ifces, bifce); + + if (ifce->bind_action) { + return wm_widget_set_scene_input_value(c, obj, 1, argv, rval, 2, NULL, NULL, NULL); + } else { + widget_on_interface_bind(bifce, 0); + } + } else { + JSObject *cookie = NULL; + if ((argc==2) && JSVAL_IS_OBJECT(argv[1])) cookie = JSVAL_TO_OBJECT(argv[1]); + + count = gf_list_count(wid->bound_ifces); + for (i=0; i<count; i++) { + bifce = gf_list_get(wid->bound_ifces, i); + if (!ifce || ( !strcmp(bifce->ifce->type, ifce->type) && (bifce->cookie==cookie)) ) { + gf_list_rem(wid->bound_ifces, i); + if (bifce->ifce->unbind_action) { + wm_widget_set_scene_input_value(c, NULL, 0, NULL, rval, 3, wid, bifce->ifce->unbind_action, NULL); + } else { + widget_on_interface_bind(bifce, 1); + } + if (ifce) { + /*unregister our message handlers*/ + count = gf_list_count(wid->output_triggers); + for (i=0; i<count; i++) { + u32 j, c2, found; + GF_DOMHandler *handler = gf_list_get(wid->output_triggers, i); + GF_WidgetPin *param = handler->js_fun; + + if (handler->sgprivate->UserPrivate != cookie) continue; + found = 0; + c2 = gf_list_count(bifce->ifce->messages); + for (j=0; j<c2; j++) { + GF_WidgetMessage *msg = gf_list_get(bifce->ifce->messages, j); + if (msg->output_trigger == param) { + found = 1; + break; + } + } + if (found) { + GF_Node *listener = handler->sgprivate->parents->node; + gf_dom_listener_del(listener, listener->sgprivate->UserPrivate); + gf_list_rem(wid->output_triggers, i); + i--; + count--; + } + } + } + wm_delete_interface_instance(wid->widget->wm, bifce); + if (ifce) return JS_TRUE; + i--; + count--; + } + } + } + return JS_TRUE; +} + +static JSBool wm_widget_bind_interface(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return wm_widget_bind_interface_ex(c, obj, argc, argv, rval, 0); +} +static JSBool wm_widget_unbind_interface(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return wm_widget_bind_interface_ex(c, obj, argc, argv, rval, 1); +} + + +static JSBool wm_widget_deactivate(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 i, count; + jsval funval; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid) return JS_FALSE; + + /*widget is a component of another widget, unregister*/ + if (wid->parent) { + GF_WidgetInstance *par_wid = wid->parent; + count = gf_list_count(par_wid->components); + for (i=0; i<count; i++) { + GF_WidgetComponentInstance *comp = gf_list_get(par_wid->components, i); + if (comp->wid == wid) { + gf_list_rem(par_wid->components, i); + gf_free(comp); + break; + } + } + wid->parent = NULL; + } + + /*remove all components*/ + while (gf_list_count(wid->components)) { + GF_WidgetComponentInstance *comp = gf_list_get(wid->components, 0); + wm_deactivate_component(c, wid, NULL, comp); + gf_list_rem(wid->components, 0); + } + + /*mark the widget as deactivated, so it is no longer valid when checking all widgets bindings*/ + wid->activated = 0; + + /*unbind existing widgets*/ + JS_LookupProperty(wid->widget->wm->ctx, wid->widget->wm->obj, "unbind_widget", &funval); + if (JSVAL_IS_OBJECT(funval)) { + jsval an_argv[1]; + an_argv[0] = OBJECT_TO_JSVAL(obj); + JS_CallFunctionValue(wid->widget->wm->ctx, wid->widget->wm->obj, funval, 1, an_argv, rval); + } + + /*unbind all interfaces of this widget*/ + wm_widget_bind_interface_ex(c, obj, 0, NULL, rval, 1); + + /*detach scene now that all unbind events have been sent*/ + wid->scene = NULL; + return JS_TRUE; +} + + +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); + JS_SetPrivate(wm->ctx, wid->obj, wid); + /*protect from GC*/ + gf_js_add_root(wm->ctx, &wid->obj); +} + +void wm_deactivate_component(JSContext *c, GF_WidgetInstance *wid, GF_WidgetComponent *comp, GF_WidgetComponentInstance *comp_inst) +{ + jsval fval, rval; + + if (!comp_inst) { + u32 i=0; + while ((comp_inst = gf_list_enum(wid->components, &i))) { + if (comp_inst->comp == comp) break; + comp_inst = NULL; + } + } + if (!comp_inst) return; + + if ((JS_LookupProperty(c, wid->widget->wm->obj, "on_widget_remove", &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) { + jsval argv[1]; + argv[0] = OBJECT_TO_JSVAL(comp_inst->wid->obj); + JS_CallFunctionValue(wid->widget->wm->ctx, wid->obj, fval, 1, argv, &rval); + } +} + +GF_WidgetComponentInstance *wm_activate_component(JSContext *c, GF_WidgetInstance *wid, GF_WidgetComponent *comp, Bool skip_wm_notification) +{ + u32 i, count; + const char *fun_name = NULL; + jsval fval, rval; + GF_WidgetComponentInstance *comp_inst; + GF_WidgetInstance *comp_wid; + + comp_wid = NULL; + if (comp->src) { + char *url = gf_url_concatenate(wid->widget->url, comp->src); + + count = gf_list_count(wid->widget->wm->widget_instances); + for (i=0; i<count; i++) { + comp_wid = gf_list_get(wid->widget->wm->widget_instances, i); + if (!strcmp(comp_wid->widget->url, url) && !comp_wid->parent) break; + comp_wid = NULL; + } + if (!comp_wid) { + comp_wid = wm_load_widget(wid->widget->wm, url, 0); + if (comp_wid) comp_wid->permanent = 0; + } + gf_free(url); + } + if (!comp_wid) return NULL; + + if (!comp_wid->activated) + fun_name = "on_widget_add"; + + GF_SAFEALLOC(comp_inst, GF_WidgetComponentInstance); + comp_inst->comp = comp; + comp_inst->wid = comp_wid; + comp_wid->parent = wid; + + gf_list_add(wid->components, comp_inst); + + if (!comp_inst->wid->obj) wm_widget_jsbind(wid->widget->wm, comp_inst->wid); + + if (!skip_wm_notification && fun_name && (JS_LookupProperty(c, wid->widget->wm->obj, fun_name, &fval)==JS_TRUE) && JSVAL_IS_OBJECT(fval)) { + jsval argv[1]; + argv[0] = OBJECT_TO_JSVAL(comp_inst->wid->obj); + JS_CallFunctionValue(wid->widget->wm->ctx, wid->obj, fval, 1, argv, &rval); + } + if (comp_inst) return comp_inst; + return NULL; +} + +static JSBool wm_widget_is_interface_bound(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 i, count; + Bool check_fake_bind = 0; + JSObject *cookie; + GF_WidgetInterface *ifce; + GF_WidgetInstance *wid = (GF_WidgetInstance *)JS_GetPrivate(c, obj); + if (!wid || !wid->scene || (argc<1) || !JSVAL_IS_OBJECT(argv[0]) ) return JS_FALSE; + + ifce = JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + if (!ifce) return JS_FALSE; + cookie = NULL; + if ((argc==2) && JSVAL_IS_OBJECT(argv[1]) ) + cookie = JSVAL_TO_OBJECT(argv[1]); + + if ((argc==3) && JSVAL_IS_BOOLEAN(argv[2]) ) + check_fake_bind = JSVAL_TO_BOOLEAN(argv[2])==JS_TRUE ? 1 : 0; + + + *rval = BOOLEAN_TO_JSVAL(JS_FALSE); + count = gf_list_count(wid->bound_ifces); + for (i=0; i<count; i++) { + GF_WidgetInterfaceInstance *bifce = gf_list_get(wid->bound_ifces, i); + if (!strcmp(bifce->ifce->type, ifce->type) && (!cookie || (bifce->cookie==cookie))) { + *rval = BOOLEAN_TO_JSVAL(JS_TRUE); + break; + } + } + return JS_TRUE; +} + + +static JSBool wm_load(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 i, count; + const char *manifest; + GF_WidgetInstance *wid; + GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj); + if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE; + + manifest = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + + wid=NULL; + count = gf_list_count(wm->widget_instances); + for (i=0; i<count; i++) { + wid = gf_list_get(wm->widget_instances, i); + if (!strcmp(wid->widget->url, manifest) && !wid->activated) break; + wid = NULL; + } + if (!wid) { + wid = wm_load_widget(wm, manifest, 0); + if (!wid) return JS_TRUE; + } + wm_widget_jsbind(wm, wid); + *rval = OBJECT_TO_JSVAL(wid->obj); + return JS_TRUE; +} + +static JSBool wm_unload(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + GF_WidgetInstance *wid; + GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(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; + wid = (GF_WidgetInstance *)JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0]) ); + if (!wid) return JS_TRUE; + + /*unless explecetely requested, remove the section*/ + if ((argc!=2) || !JSVAL_IS_BOOLEAN(argv[1]) || (JSVAL_TO_BOOLEAN(argv[1])==JS_TRUE) ) { + /*create section*/ + gf_cfg_del_section(wm->term->user->config, wid->secname); + gf_cfg_set_key(wm->term->user->config, "Widgets", wid->secname, NULL); + } + wm_delete_widget_instance(wm, wid); + return JS_TRUE; +} + + + +static JSBool wm_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + char *prop_name; + GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj); + if (!wm) return JS_FALSE; + + if (!JSVAL_IS_STRING(id)) return JS_TRUE; + prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + if (!prop_name) return JS_FALSE; + + if (!strcmp(prop_name, "num_widgets")) { + *vp = INT_TO_JSVAL(gf_list_count(wm->widget_instances)); + return JS_TRUE; + } + if (!strcmp(prop_name, "last_widget_dir")) { + const char *opt = gf_cfg_get_key(wm->term->user->config, "Widgets", "last_widget_dir"); + if (!opt) opt = "/"; + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(c, opt)); + return JS_TRUE; + } + + + return JS_TRUE; +} +static JSBool wm_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + char *prop_name; + GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj); + if (!wm) return JS_FALSE; + + if (!JSVAL_IS_STRING(*vp)) return JS_TRUE; + if (!JSVAL_IS_STRING(id)) return JS_TRUE; + prop_name = JS_GetStringBytes(JSVAL_TO_STRING(id)); + + if (!strcmp(prop_name, "last_widget_dir")) { + gf_cfg_set_key(wm->term->user->config, "Widgets", "last_widget_dir", JS_GetStringBytes(JSVAL_TO_STRING(*vp))); + return JS_TRUE; + } + + return JS_TRUE; +} + +static JSBool wm_get(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 i; + GF_WidgetInstance *wid; + GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj); + if (!argc || !JSVAL_IS_INT(argv[0])) return JS_TRUE; + + i = JSVAL_TO_INT(argv[0]); + wid = gf_list_get(wm->widget_instances, i); + if (wid) *rval = OBJECT_TO_JSVAL(wid->obj); + return JS_TRUE; +} + +static JSBool wm_find_interface(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *ifce_name; + u32 i; + GF_WidgetInstance *wid; + GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj); + if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE; + + ifce_name = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + i=0; + while ( (wid = gf_list_enum(wm->widget_instances, &i) )) { + u32 j=0; + GF_WidgetInterface *wid_ifce; + while ((wid_ifce = gf_list_enum(wid->widget->main->interfaces, &j))) { + if (!strcmp(wid_ifce->type, ifce_name)) { + *rval = OBJECT_TO_JSVAL(wid->obj); + return JS_TRUE; + } + } + } + return JS_TRUE; +} + + +const char *wm_xml_get_attr(GF_XMLNode *root, const char *name) +{ + + u32 i, count; + count = gf_list_count(root->attributes); + for (i=0; i<count; i++) { + char *sep; + GF_XMLAttribute *att = gf_list_get(root->attributes, i); + if (!att->name) continue; + if (!strcmp(att->name, name)) return att->value; + sep = strchr(att->name, ':'); + if (sep && !strcmp(sep+1, name)) return att->value; + } + return NULL; +} + +/* TODO Implement real language check according to BCP 47*/ +static Bool wm_check_language(const char *xml_lang_value, const char *user_locale) +{ + Bool ret = 0; + char *sep, *val; + val = (char*)xml_lang_value; + while (!ret) { + sep = strchr(val, ';'); + if (sep) sep[0] = 0; + if (strstr(user_locale, val)) ret = 1; + if (sep) { + sep[0] = ';'; + val = sep+1; + } else { + break; + } + } + return ret; +} + +static GF_XMLNode *wm_xml_find(GF_XMLNode *root, const char *ns_prefix, const char *name, const char *user_locale) +{ + GF_XMLNode *localized = NULL; + GF_XMLNode *non_localized = NULL; + u32 i, count; + + if (!root) return NULL; + + count = gf_list_count(root->content); + for (i=0; i<count; i++) { + GF_XMLNode *n = gf_list_get(root->content, i); + if (n->type==GF_XML_NODE_TYPE && n->name && !strcmp(n->name, name) && ((!ns_prefix && !n->ns) || (ns_prefix && n->ns && !strcmp(ns_prefix, n->ns)))) { + const char *lang = wm_xml_get_attr(n, "xml:lang"); + if (!lang) { + if (!non_localized) non_localized = n; + } else { + if (user_locale && wm_check_language(lang, user_locale) && !localized) localized = n; + } + } + } + if (localized) return localized; + else return non_localized; +} + +static GF_WidgetPin *wm_parse_pin(const char *value, u16 type, const char *pin_name, const char *scriptType, const char *default_value) +{ + GF_WidgetPin *pin; + char *sep; + + if (!value && !scriptType && !default_value) return NULL; + + GF_SAFEALLOC(pin, GF_WidgetPin); + pin->type = type; + if (pin_name) pin->name = gf_strdup(pin_name); + + if (value) { + sep = strrchr(value, '.'); + if (!sep && (type==GF_WM_PREF_CONNECT)) { + gf_free(pin); + return NULL; + } + + /*node.event || node.attribute*/ + if (sep) { + sep[0] = 0; + pin->node = gf_strdup(value); + pin->attribute = gf_strdup(sep+1); + sep[0] = '.'; + } + /*script function*/ + else { + pin->node = gf_strdup(value); + } + } + + if (scriptType) { + if (!strcmp(scriptType, "boolean")) pin->script_type = GF_WM_PARAM_SCRIPT_BOOL; + else if (!strcmp(scriptType, "number")) pin->script_type = GF_WM_PARAM_SCRIPT_NUMBER; + } else if (default_value) { + pin->default_value = gf_strdup(default_value); + } + return pin; +} + +static void wm_parse_mpegu_content_element(GF_WidgetContent *content, GF_XMLNode *root, const char *ns_prefix, GF_List *global_prefs) +{ + GF_XMLNode *ifces, *context, *pref_node; + GF_WidgetMessage *msg; + GF_WidgetInterface *ifce; + GF_XMLNode *ifce_node; + GF_WidgetPreference *pref; + const char *att; + u32 i = 0; + + ifces = wm_xml_find(root, ns_prefix, "interfaces", NULL); + if (ifces) { + + /*get all interface element*/ + while ((ifce_node = gf_list_enum(ifces->content, &i))) { + GF_XMLNode *msg_node; + u32 j; + const char *ifce_type, *act; + if (ifce_node->type != GF_XML_NODE_TYPE) continue; + if (strcmp(ifce_node->name, "interface")) continue; + ifce_type = wm_xml_get_attr(ifce_node, "type"); + if (!ifce_type) continue; + + GF_SAFEALLOC(ifce, GF_WidgetInterface); + ifce->type = gf_strdup(ifce_type); + ifce->messages = gf_list_new(); + ifce->content = content; + gf_list_add(content->interfaces, ifce); + + act = wm_xml_get_attr(ifce_node, "serviceProvider"); + if (act && !strcmp(act, "true")) ifce->provider = 1; + + act = wm_xml_get_attr(ifce_node, "multipleBindings"); + if (act && !strcmp(act, "true")) ifce->multiple_binding = 1; + + act = wm_xml_get_attr(ifce_node, "required"); + if (act && !strcmp(act, "true")) ifce->required = 1; + + act = wm_xml_get_attr(ifce_node, "connectTo"); + if (act) ifce->connectTo = gf_strdup(act); + + act = wm_xml_get_attr(ifce_node, "bindAction"); + if (act) { + ifce->bind_action = wm_parse_pin(act, GF_WM_BIND_ACTION, NULL, NULL, NULL); + } + act = wm_xml_get_attr(ifce_node, "unbindAction"); + if (act) { + ifce->unbind_action = wm_parse_pin(act, GF_WM_UNBIND_ACTION, NULL, NULL, NULL); + } + + j=0; + while ((msg_node = gf_list_enum(ifce_node->content, &j))) { + u32 k; + GF_XMLNode *par_node; + const char *msg_name, *action; + if (msg_node->type != GF_XML_NODE_TYPE) continue; + if (strcmp(msg_node->name, "messageIn") && strcmp(msg_node->name, "messageOut")) continue; + + msg_name = wm_xml_get_attr(msg_node, "name"); + if (!msg_name) continue; + GF_SAFEALLOC(msg, GF_WidgetMessage); + msg->name = gf_strdup(msg_name); + msg->params = gf_list_new(); + msg->ifce = ifce; + if (!strcmp(msg_node->name, "messageOut")) msg->is_output = 1; + + gf_list_add(ifce->messages, msg); + + /*get inputAction*/ + action = wm_xml_get_attr(msg_node, "inputAction"); + if (action) { + msg->input_action = wm_parse_pin(action, GF_WM_INPUT_ACTION, NULL, NULL, NULL); + } + + /*get outputTrigger*/ + action = wm_xml_get_attr(msg_node, "outputTrigger"); + if (action) { + msg->output_trigger = wm_parse_pin(action, GF_WM_OUTPUT_TRIGGER, NULL, NULL, NULL); + } + + /*get params*/ + k=0; + while ((par_node=gf_list_enum(msg_node->content, &k))) { + GF_WidgetPin *wpin; + u16 type; + const char *par_name, *att_name; + if (par_node->type != GF_XML_NODE_TYPE) continue; + if (strcmp(par_node->name, "input") && strcmp(par_node->name, "output")) continue; + + + par_name = wm_xml_get_attr(par_node, "name"); + /*invalid param, discard message*/ + if (!par_name) { + gf_list_del_item(ifce->messages, msg); + gf_list_del(msg->params); + gf_free(msg->name); + gf_free(msg); + break; + } + + if (!strcmp(par_node->name, "output")) { + type = GF_WM_PARAM_OUTPUT; + att_name = wm_xml_get_attr(par_node, "attributeModified"); + } else { + type = GF_WM_PARAM_INPUT; + att_name = wm_xml_get_attr(par_node, "setAttribute"); + } + wpin = wm_parse_pin(att_name, type, par_name, wm_xml_get_attr(par_node, "scriptParamType"), wm_xml_get_attr(par_node, "default")); + if (!wpin) continue; + wpin->msg = msg; + + gf_list_add(msg->params, wpin); + } + } + } + } + + /*get all component elements*/ + i=0; + while (root && (ifce_node = gf_list_enum(root->content, &i))) { + GF_XMLNode *req_node; + u32 j; + const char *src, *id, *act; + GF_WidgetComponent *comp; + if (ifce_node->type != GF_XML_NODE_TYPE) continue; + if (strcmp(ifce_node->name, "component")) continue; + src = wm_xml_get_attr(ifce_node, "src"); + id = wm_xml_get_attr(ifce_node, "id"); + + GF_SAFEALLOC(comp, GF_WidgetComponent); + comp->required_interfaces = gf_list_new(); + comp->content = content; + if (id) comp->id = gf_strdup(id); + if (src) comp->src = gf_strdup(src); + j=0; + while ((req_node=gf_list_enum(ifce_node->content, &j))) { + const char *ifce_type; + if (req_node->type != GF_XML_NODE_TYPE) continue; + if (strcmp(req_node->name, "requiredInterface")) continue; + ifce_type = wm_xml_get_attr(req_node, "type"); + if (!ifce_type) continue; + gf_list_add(comp->required_interfaces, gf_strdup(ifce_type)); + } + + act = wm_xml_get_attr(ifce_node, "activateTrigger"); + if (act) comp->activateTrigger = wm_parse_pin(act, GF_WM_ACTIVATE_TRIGGER, NULL, NULL, NULL); + act = wm_xml_get_attr(ifce_node, "deactivateTrigger"); + if (act) comp->deactivateTrigger = wm_parse_pin(act, GF_WM_DEACTIVATE_TRIGGER, NULL, NULL, NULL); + + gf_list_add(content->components, comp); + } + + /*clone global prefs for this content*/ + i=0; + while ((pref = gf_list_enum(global_prefs, &i))) { + GF_WidgetPreference *apref; + GF_SAFEALLOC(apref, GF_WidgetPreference); + apref->name = gf_strdup(pref->name); + if (pref->value) apref->value = gf_strdup(pref->value); + apref->flags = pref->flags; + gf_list_add(content->preferences, apref); + } + + context = wm_xml_find(root, ns_prefix, "contextConfiguration", NULL); + if (context) { + u32 j; + /*get all preference elements*/ + i=0; + while ((pref_node = gf_list_enum(context->content, &i))) { + const char *att; + if (pref_node->type != GF_XML_NODE_TYPE) continue; + if (strcmp(pref_node->name, "preferenceConnect")) continue; + att = wm_xml_get_attr(pref_node, "name"); + if (!att) continue; + + j=0; + while ((pref = gf_list_enum(content->preferences, &j))) { + if (!strcmp(pref->name, att) && !pref->connectTo) break; + } + + if (!pref) { + GF_SAFEALLOC(pref, GF_WidgetPreference); + pref->name = gf_strdup(att); + gf_list_add(content->preferences, pref); + } + att = wm_xml_get_attr(pref_node, "value"); + if (att) { + if (pref->value) gf_free(pref->value); + pref->value = gf_strdup(att); + } + att = wm_xml_get_attr(pref_node, "readOnly"); + if (att && !strcmp(att, "true")) pref->flags |= GF_WM_PREF_READONLY; + att = wm_xml_get_attr(pref_node, "migratable"); + if (att && !strcmp(att, "saveOnly")) pref->flags |= GF_WM_PREF_SAVE; + else if (att && !strcmp(att, "migrateOnly")) pref->flags |= GF_WM_PREF_MIGRATE; + else pref->flags |= GF_WM_PREF_SAVE | GF_WM_PREF_MIGRATE; + + att = wm_xml_get_attr(pref_node, "connectTo"); + if (att) pref->connectTo = wm_parse_pin(att, GF_WM_PREF_CONNECT, NULL, NULL, NULL); + } + + att = wm_xml_get_attr(context, "savedAction"); + if (att) content->savedAction = wm_parse_pin(att, GF_WM_PREF_SAVEDACTION, NULL, NULL, NULL); + att = wm_xml_get_attr(context, "restoredAction"); + if (att) content->restoredAction = wm_parse_pin(att, GF_WM_PREF_RESTOREDACTION, NULL, NULL, NULL); + att = wm_xml_get_attr(context, "saveTrigger"); + if (att) content->saveTrigger = wm_parse_pin(att, GF_WM_PREF_SAVETRIGGER, NULL, NULL, NULL); + att = wm_xml_get_attr(context, "restoreTrigger"); + if (att) content->restoreTrigger = wm_parse_pin(att, GF_WM_PREF_RESTORETRIGGER, NULL, NULL, NULL); + } +} + +/* Implements the W3C P&C rule for getting a single attribute value + see http://www.w3.org/TR/widgets/#rule-for-getting-a-single-attribute-valu0 + should be different from getting normalized text but for now it's ok + */ +static char *wm_get_single_attribute(const char *input) { + u32 i, j, len; + char *output; + Bool first_space_copied; + + if (!input) return gf_strdup(""); + + len = strlen(input); + output = gf_malloc(len+1); + + first_space_copied = 1; + j = 0; + for (i = 0; i<len; i++) { + switch (input[i]) { + case ' ': + case '\t': + case '\r': + case '\n': + if (!first_space_copied) { + output[j] = ' '; + j++; + first_space_copied = 1; + } + break; + default: + output[j] = input[i]; + j++; + first_space_copied = 0; + } + } + if (j && output[j-1] == ' ') output[j-1] = 0; + output[j] = 0; + return output; +} + +/* Implements the W3C P&C rule for getting a single attribute value + see http://www.w3.org/TR/widgets/#rule-for-getting-a-single-attribute-valu0 */ +static u32 wm_parse_non_neg(const char *input) { + u32 result = 0; + if (strlen(input) && !strchr(input, '-')) { + if (sscanf(input, "%u", &result) != 1) result = 0; + } + return result; +} + +/* returns the localized concatenated text content +see http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-textContent +and http://www.w3.org/TR/widgets/#rule-for-getting-text-content0 +*/ +static char *wm_get_text_content(GF_XMLNode *node, char *inherited_locale, const char *user_locale) { + if (node->type == GF_XML_TEXT_TYPE) { + if (node->name) return gf_strdup(node->name); + else return gf_strdup(""); + } else { + char *xml_lang = (char *)wm_xml_get_attr(node, "xml:lang"); + if (!xml_lang) xml_lang = inherited_locale; + /* + if (xml_lang && user_locale && wm_check_language(xml_lang, user_locale)) + */ + { + u32 i, count; + char *text_content; + u32 text_content_len = 0; + text_content = gf_strdup(""); + count = gf_list_count(node->content); + for (i=0; i<count; i++) { + GF_XMLNode *child = (GF_XMLNode *)gf_list_get(node->content, i); + char *child_content = wm_get_text_content(child, xml_lang, user_locale); + u32 child_content_len = strlen(child_content); + text_content = gf_realloc(text_content, text_content_len+child_content_len+1); + memcpy(text_content+text_content_len, child_content, child_content_len); + text_content[text_content_len+child_content_len] = 0; + text_content_len+=child_content_len; + gf_free(child_content); + } + return text_content; + } + /* + } else { + return gf_strdup(""); + */ + } +} + +static char *wm_get_normalized_text_content(GF_XMLNode *node, char *inherited_locale, const char *user_locale) { + char *text_content, *result; + /* first aggregate text content */ + text_content = wm_get_text_content(node, inherited_locale, user_locale); + /* calling normalization of text content */ + result = wm_get_single_attribute(text_content); + gf_free(text_content); + return result; +} + +/* When relocating resources over HTTP, we check if the resources for a given locale exists + on the server by sending a HEAD message with an Accept-Language header. */ +void wm_relocate_proc(void *usr_cbk, GF_NETIO_Parameter *parameter) +{ + switch (parameter->msg_type) { + case GF_NETIO_GET_METHOD: + parameter->name = "HEAD"; + break; + } +} + +/* relocate the given resource name (res_name) using registered relocators (e.g. locales, package folder) + The result is the path of the file, possibly uncompressed, possibly localized. + The parameter widget_path provides the path for converting relative resource paths into absolute paths.*/ +static Bool wm_relocate_url(GF_WidgetManager *wm, const char *widget_path, const char *res_name, char *relocated_name, char *localized_res_name) +{ + Bool ok = 0; + char *res_url; + Bool result = gf_term_relocate_url(wm->term, res_name, widget_path, relocated_name, localized_res_name); + if (result) return result; + + res_url = gf_url_concatenate(widget_path, res_name); + + /*try with HTTP HEAD */ + if (!strnicmp(widget_path, "http", 4)) { + GF_Err e; + /*fetch the remote widget manifest synchronously and load it */ + GF_DownloadSession *sess = gf_dm_sess_new(wm->term->downloader, (char *)res_url, GF_NETIO_SESSION_NOT_THREADED, wm_relocate_proc, NULL, &e); + if (sess) { + e = gf_dm_sess_process(sess); + gf_dm_sess_del(sess); + if (e==GF_OK) { + const char *opt = gf_cfg_get_key(wm->term->user->config, "Systems", "Language2CC"); + strcpy(relocated_name, res_url); + if (opt) + sprintf(localized_res_name, "%s/%s", opt, res_name); + else + strcpy(localized_res_name, res_name); + ok = 1; + } + } + } + gf_free(res_url); + return ok; +} + +/* function that checks if the default start file exists in the widget (package or folder) + according to the default start files table from the W3C P&C spec. + The widget path attribute is used to get the associated relocator from the registered relocators */ +static void wm_set_default_start_file(GF_WidgetManager *wm, GF_WidgetContent *content, const char *widget_path) { + Bool result; + char localized_path[GF_MAX_PATH], relocated_path[GF_MAX_PATH]; + char *mimetype = "text/html"; + result = wm_relocate_url(wm, widget_path, "index.htm", relocated_path, localized_path); + if (result) { + mimetype = "text/html"; + } else { + result = wm_relocate_url(wm, widget_path, "index.html", relocated_path, localized_path); + if (result) { + mimetype = "text/html"; + } else { + result = wm_relocate_url(wm, widget_path, "index.svg", relocated_path, localized_path); + if (result) { + mimetype = "image/svg+xml"; + } else { + result = wm_relocate_url(wm, widget_path, "index.xhtml", relocated_path, localized_path); + if (result) { + mimetype = "application/xhtml+xml"; + } else { + result = wm_relocate_url(wm, widget_path, "index.xht", relocated_path, localized_path); + if (result) mimetype = "application/xhtml+xml"; + } + } + } + } + if (content->src) gf_free(content->src); + content->src = gf_strdup(localized_path); + if (content->relocated_src) gf_free(content->relocated_src); + content->relocated_src = gf_strdup(relocated_path); + if (content->mimetype) gf_free(content->mimetype); + content->mimetype = gf_strdup(mimetype); + if (content->encoding) gf_free(content->encoding); + content->encoding = gf_strdup("utf-8"); +} + +static GF_WidgetContent *wm_add_icon(GF_Widget *widget, const char *icon_relocated_path, const char *icon_localized_path) +{ + GF_WidgetContent *icon; + u32 i, count; + Bool already_in = 0; + + count = gf_list_count(widget->icons); + for (i =0; i<count; i++) { + GF_WidgetContent *in_icon = gf_list_get(widget->icons, i); + if (!strcmp(icon_localized_path, in_icon->src)) { + already_in = 1; + break; + } + } + if (already_in) return NULL; + + GF_SAFEALLOC(icon, GF_WidgetContent); + icon->src = gf_strdup(icon_localized_path); + icon->relocated_src = gf_strdup(icon_relocated_path); + icon->interfaces = gf_list_new(); + icon->components = gf_list_new(); + icon->preferences = gf_list_new(); + icon->widget = widget; + gf_list_add(widget->icons, icon); + return icon; +} + +/* Scans the W3C default icons table and add each icon */ +static void wm_set_default_icon_files(GF_WidgetManager *wm, const char *widget_path, GF_Widget *widget) { + char relocated_path[GF_MAX_PATH], localized_path[GF_MAX_PATH]; + Bool result; + + result = wm_relocate_url(wm, widget_path, "icon.svg", relocated_path, localized_path); + if (result) wm_add_icon(widget, relocated_path, localized_path); + + result = wm_relocate_url(wm, widget_path, "icon.ico", relocated_path, localized_path); + if (result) wm_add_icon(widget, relocated_path, localized_path); + + result = wm_relocate_url(wm, widget_path, "icon.png", relocated_path, localized_path); + if (result) wm_add_icon(widget, relocated_path, localized_path); + + result = wm_relocate_url(wm, widget_path, "icon.gif", relocated_path, localized_path); + if (result) wm_add_icon(widget, relocated_path, localized_path); + + result = wm_relocate_url(wm, widget_path, "icon.jpg", relocated_path, localized_path); + if (result) wm_add_icon(widget, relocated_path, localized_path); +} + +GF_WidgetInstance *wm_load_widget(GF_WidgetManager *wm, const char *path, u32 InstanceID) +{ + char szName[GF_MAX_PATH]; + u32 i, count; + GF_Widget *widget = NULL; + GF_WidgetInstance *wi = NULL; + GF_XMLNode *root, *icon, *main, *name, *xml_node; + GF_Err e; + GF_DOMParser *dom = NULL; + GF_WidgetPackage *wpackage = NULL; + + GF_DownloadSession *sess = NULL; + const char *widget_ns_prefix = NULL; + const char *mpegu_ns_prefix = NULL; + const char *user_locale = gf_cfg_get_key(wm->term->user->config, "Systems", "Language2CC"); + + /* Try to see if this widget is already loaded */ + e = GF_OK; + count = gf_list_count(wm->widgets); + for (i=0; i<count; i++) { + widget = gf_list_get(wm->widgets, i); + if (!strcmp(widget->url, path)) break; + widget = NULL; + } + + /*not found, retrieve the widget (if http), check the package if needed and parse the configuration document/widget manifest*/ + if (!widget) { + Bool isDownloadedPackage = 0; + + /* path used to locate the widget (config.xml if unpackaged or zip/isoff package), potentially after download */ + const char *szLocalPath = path; + /* used to locate the config document/widget manifest potentially after unzipping */ + const char *szManifestPath = path; + /* */ + const char *szWidgetPath = path; + const char *desc; + GF_WidgetPreference *pref; + GF_List *global_prefs; + GF_WidgetContent *content; + Bool correct_ns = 0; + + if (strstr(path, "http://")) { + /*fetch the remote widget manifest synchronously and load it */ + sess = gf_dm_sess_new(wm->term->downloader, (char *)path, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL, &e); + if (sess) { + e = gf_dm_sess_process(sess); + if (e==GF_OK) { + szLocalPath = gf_dm_sess_get_cache_name(sess); + + if (gf_unzip_probe(szLocalPath)) { + isDownloadedPackage = 1; + } else { + /* TODO ISOFF-based packaged widget */ + } + } + } + if (!sess || (e!=GF_OK) || !szLocalPath) goto exit; + } + + /* Check if the widget package is a valid package and if it contains a config.xml file */ + szManifestPath = szLocalPath; + + wpackage = widget_package_new(wm, szLocalPath); + if (wpackage) { + count = gf_list_count(wpackage->resources); + for (i=0; i<count; i++) { + GF_WidgetPackageResource *wu = gf_list_get(wpackage->resources, i); + /* According to W3C WPC, the config.xml file (lower case) shall only be located + at the root of the package + see http://www.w3.org/TR/widgets/#ta-dxzVDWpaWg */ + if (!strcmp(wu->inner_path, "config.xml")) { + szManifestPath = wu->extracted_path; + break; + } + } + szWidgetPath = szManifestPath; + } + + + /* Parse the Widget Config Document as a DOM */ + dom = gf_xml_dom_new(); + e = gf_xml_dom_parse(dom, szManifestPath, NULL, NULL); + if (e) goto exit; + + root = gf_xml_dom_get_root(dom); + if (!root) goto exit; + + correct_ns = 0; + count = gf_list_count(root->attributes); + for (i=0; i<count; i++) { + GF_XMLAttribute *att = gf_list_get(root->attributes, i); + if (att->name) { + if (!strcmp(att->name, "xmlns")) { + if (!strcmp(att->value, "http://www.w3.org/ns/widgets")) { + correct_ns = 1; + } + } else if (!strnicmp(att->name, "xmlns:", 6)) { + if (!strcmp(att->value, "http://www.w3.org/ns/widgets")) { + widget_ns_prefix = att->name+6; + correct_ns = 1; + } else if (!strcmp(att->value, "urn:mpeg:mpegu:schema:widgets:manifest:2010")) { + mpegu_ns_prefix = att->name+6; + } + } + } + } + /* According to the spec, wrong or no namespace means invalid widget + see http://www.w3.org/TR/widgets/#ta-ACCJfDGwDQ */ + if (!correct_ns) goto exit; + + /* see http://www.w3.org/TR/widgets/#ta-ACCJfDGwDQ */ + if ((root->ns && (!widget_ns_prefix || strcmp(root->ns, widget_ns_prefix) || strcmp(root->name, "widget"))) || + (!root->ns && (widget_ns_prefix || strcmp(root->name, "widget")))) + goto exit; + + + /*pre-parse the root-level preference for use when parsing MPEG-U elements */ + global_prefs = gf_list_new(); + i=0; + while ((main = gf_list_enum(root->content, &i))) { + const char *pname, *pvalue; + /* 'normalized' preference name and readonly*/ + char *npname, *npro; + u32 i, count; + Bool pref_exists = 0; + Bool readOnly = 0; + if (main->type != GF_XML_NODE_TYPE) continue; + if (strcmp(main->name, "preference")) continue; + pname = wm_xml_get_attr(main, "name"); + npname = wm_get_single_attribute(pname); + if (!npname || !strlen(npname)) continue; + + count = gf_list_count(global_prefs); + for (i = 0; i < count; i++) { + GF_WidgetPreference *tmp_pref = gf_list_get(global_prefs, i); + if (!strcmp(tmp_pref->name, npname)) { + pref_exists = 1; + break; + } + } + if (pref_exists) continue; + + pvalue = wm_xml_get_attr(main, "readonly"); + npro = wm_get_single_attribute(pvalue); + if (npro && strlen(npro) && !strcmp(npro, "true")) readOnly=1; + if (npro) gf_free(npro); + + pvalue = wm_xml_get_attr(main, "value"); + + GF_SAFEALLOC(pref, GF_WidgetPreference); + pref->name = npname; + if (pvalue) pref->value = wm_get_single_attribute(pvalue); + /*global preferences are save and migratable*/ + pref->flags = GF_WM_PREF_SAVE | GF_WM_PREF_MIGRATE; + if (readOnly) pref->flags |= GF_WM_PREF_READONLY; + gf_list_add(global_prefs, pref); + } + + /* get the content element from the XML Config document */ + GF_SAFEALLOC(content, GF_WidgetContent); + content->interfaces = gf_list_new(); + content->components = gf_list_new(); + content->preferences = gf_list_new(); + main = wm_xml_find(root, widget_ns_prefix, "content", NULL); + if (!main) { + /* if not found, use the default table of start files */ + wm_set_default_start_file(wm, content, szWidgetPath); + } else { + const char *src, *encoding, *mimetype; + src = wm_xml_get_attr(main, "src"); + + /*check the resource exists*/ + if (src) { + Bool result; + char relocated_path[GF_MAX_PATH], localized_path[GF_MAX_PATH]; + /*remove any existing fragment*/ + char *sep = strchr(src, '#'); + if (sep) sep[0] = 0; + result = wm_relocate_url(wm, szWidgetPath, src, relocated_path, localized_path); + if (sep) sep[0] = '#'; + if (result) { + content->relocated_src = gf_strdup(relocated_path); + content->src = gf_strdup(localized_path); + } + } + + encoding = wm_xml_get_attr(main, "encoding"); + if (encoding && strlen(encoding)) content->encoding = wm_get_single_attribute(encoding); + else content->encoding = gf_strdup("utf-8"); + + mimetype = wm_xml_get_attr(main, "type"); + if (mimetype && strlen(mimetype)) { + char *sep = strchr(mimetype, ';'); + if (sep) sep[0] = 0; + content->mimetype = wm_get_single_attribute(mimetype); + if (sep) sep[0] = ';'; + } + else content->mimetype = gf_strdup("text/html"); + + if (!content->relocated_src) wm_set_default_start_file(wm, content, szWidgetPath); + } + if (strlen(content->relocated_src) == 0) { + gf_list_del(content->interfaces); + gf_list_del(content->components); + gf_list_del(content->preferences); + gf_free(content); + content = NULL; + goto exit; + } + /* We need to call the parse of the MPEG-U elements to clone the global preferences into widget preferences, + this should probably be changed to extract the clone from that function */ + wm_parse_mpegu_content_element(content, main, mpegu_ns_prefix, global_prefs); + + GF_SAFEALLOC(widget, GF_Widget); + widget->url = gf_strdup(path); + widget->manifest_path = gf_strdup(szManifestPath); + if (isDownloadedPackage) widget->local_path = gf_strdup(szLocalPath); + widget->wm = wm; + widget->main = content; + content->widget = widget; + widget->icons = gf_list_new(); + widget->features = gf_list_new(); + if (wpackage) { + widget->wpack = wpackage; + wpackage->widget = widget; + /*attach downloader to our package to avoid destroying the cache file*/ + wpackage->sess = sess; + sess = NULL; + } + + /*check for icon - can be optional*/ + i=0; + while ((icon = gf_list_enum(root->content, &i))) { + if (icon->type==GF_XML_NODE_TYPE && + icon->name && !strcmp(icon->name, "icon") && + ((!widget_ns_prefix && !icon->ns) || !strcmp(widget_ns_prefix, icon->ns))) { + char *sep; + char relocated[GF_MAX_PATH], localized_path[GF_MAX_PATH]; + char *icon_width, *icon_height; + GF_WidgetContent *iconic; + Bool result; + + char *pname = (char *)wm_xml_get_attr(icon, "src"); + if (!pname || !strlen(pname)) continue; + + /*remove any existing fragment*/ + sep = strchr(pname, '#'); + if (sep) sep[0] = 0; + result = wm_relocate_url(wm, szWidgetPath, pname, relocated, localized_path); + if (sep) sep[0] = '#'; + if (!result) continue; + + iconic = wm_add_icon(widget, relocated, localized_path); + if (iconic) { + wm_parse_mpegu_content_element(iconic, icon, mpegu_ns_prefix, global_prefs); + icon_width = (char *)wm_xml_get_attr(icon, "width"); + if (icon_width) iconic->width = wm_parse_non_neg(icon_width); + icon_height = (char *)wm_xml_get_attr(icon, "height"); + if (icon_height) iconic->height = wm_parse_non_neg(icon_height); + } + } + } + /* after processing the icon elements (wether there are valid icons or not), we use the default icon table + see http://dev.w3.org/2006/waf/widgets/test-suite/test-cases/ta-FAFYMEGELU/004/ */ + wm_set_default_icon_files(wm, szWidgetPath, widget); + + /*delete the root-level preference*/ + i=0; + while ((pref = gf_list_enum(global_prefs , &i))) { + if (pref->value) gf_free(pref->value); + gf_free(pref->name); + gf_free(pref); + } + gf_list_del(global_prefs); + + /*check for optionnal meta data*/ + name = wm_xml_find(root, widget_ns_prefix, "name", user_locale); + if (name) { + const char *shortname = wm_xml_get_attr(name, "short"); + widget->shortname = wm_get_single_attribute(shortname); + + widget->name = wm_get_normalized_text_content(name, NULL, user_locale); + } + + desc = wm_xml_get_attr(root, "id"); + if (desc) { + /* TODO check if this is a valid IRI, for the moment, just hack to pass the test, check for ':' + see http://dev.w3.org/2006/waf/widgets/test-suite/test-cases/ta-RawAIWHoMs/ */ + if (strchr(desc, ':')) + widget->identifier = wm_get_single_attribute(desc); + } + + desc = wm_xml_get_attr(root, "width"); + if (desc) { + widget->width = wm_parse_non_neg(desc); + } + desc = wm_xml_get_attr(root, "height"); + if (desc) { + widget->height = wm_parse_non_neg(desc); + } + + name = wm_xml_find(root, widget_ns_prefix, "description", user_locale); + if (name) { + widget->description = wm_get_normalized_text_content(name, NULL, user_locale); + } + + name = wm_xml_find(root, widget_ns_prefix, "license", user_locale); + if (name) { + const char *href = wm_xml_get_attr(name, "href"); + widget->licenseHref = wm_get_single_attribute(href); + + /* Warning the license text content should not be normalized */ + widget->license = wm_get_text_content(name, NULL, user_locale); + } + + desc = wm_xml_get_attr(root, "version"); + if (desc) widget->version = wm_get_single_attribute(desc); + + desc = wm_xml_get_attr(root, "uuid"); + if (desc) widget->uuid = gf_strdup(desc); + + desc = wm_xml_get_attr(root, "discardable"); + if (desc) widget->discardable = !strcmp(desc, "true") ? 1 : 0; + + desc = wm_xml_get_attr(root, "multipleInstances"); + if (desc) widget->multipleInstance = !strcmp(desc, "true") ? 1 : 0; + + name = wm_xml_find(root, widget_ns_prefix, "author", NULL); + if (name) { + desc = wm_xml_get_attr(name, "href"); + if (desc && strchr(desc, ':')) widget->authorHref = wm_get_single_attribute(desc); + + desc = wm_xml_get_attr(name, "email"); + widget->authorEmail = wm_get_single_attribute(desc); + + widget->authorName = wm_get_normalized_text_content(name, NULL, user_locale); + } + + i=0; + while ((xml_node = gf_list_enum(root->content, &i))) { + if (xml_node->type==GF_XML_NODE_TYPE && + xml_node->name && !strcmp(xml_node->name, "feature") && + ((!widget_ns_prefix && !xml_node->ns) || !strcmp(widget_ns_prefix, xml_node->ns))) { + + u32 i, count; + Bool already_in = 0; + GF_WidgetFeature *feat; + const char *feature_name, *req_att; + char *nfname; + Bool required = 1; + u32 j; + GF_XMLNode *param_node; + + feature_name = (char *)wm_xml_get_attr(xml_node, "name"); + if (!feature_name || !strlen(feature_name) || !strchr(feature_name, ':')) continue; + nfname = wm_get_single_attribute(feature_name); + + req_att = (char *)wm_xml_get_attr(xml_node, "required"); + if (req_att && !strcmp(req_att, "false")) required = 0; + + count = gf_list_count(widget->features); + for (i = 0; i<count; i++) { + GF_WidgetFeature *tmp = gf_list_get(widget->features, i); + if (!strcmp(nfname, tmp->name)) { + already_in = 1; + break; + } + } + if (already_in) continue; + + GF_SAFEALLOC(feat, GF_WidgetFeature); + feat->name = nfname; + feat->required = required; + feat->params = gf_list_new(); + gf_list_add(widget->features, feat); + + j = 0; + while ((param_node = gf_list_enum(xml_node->content, &j))) { + if (param_node->type==GF_XML_NODE_TYPE && + param_node->name && !strcmp(param_node->name, "param") && + ((!widget_ns_prefix && !param_node->ns) || !strcmp(widget_ns_prefix, param_node->ns))) { + GF_WidgetFeatureParam *wfp; + const char *param_name, *param_value; + char *npname, *npvalue; + + param_name = (char *)wm_xml_get_attr(param_node, "name"); + npname = wm_get_single_attribute(param_name); + if (!strlen(npname)) continue; + + param_value = (char *)wm_xml_get_attr(param_node, "value"); + npvalue = wm_get_single_attribute(param_value); + if (!strlen(npvalue)) { + gf_free(npname); + continue; + } + + GF_SAFEALLOC(wfp, GF_WidgetFeatureParam); + wfp->name = npname; + wfp->value = npvalue; + gf_list_add(feat->params, wfp); + + } + } + + } + } + + gf_list_add(wm->widgets, widget); + } + + GF_SAFEALLOC(wi, GF_WidgetInstance); + wi->widget = widget; + wi->bound_ifces = gf_list_new(); + wi->output_triggers = gf_list_new(); + wi->components = gf_list_new(); + widget->nb_instances++; + wi->instance_id = InstanceID; + wi->permanent = 1; + + if (!InstanceID) { + char szInst[20]; + + count = gf_list_count(wm->widget_instances); + for (i=0; i<count; i++) { + GF_WidgetInstance *awi = gf_list_get(wm->widget_instances, i); + if (awi->widget == wi->widget) + wi->instance_id = awi->instance_id; + } + wi->instance_id ++; + + sprintf(szName, "%s#%s#Instance%d", path, wi->widget->name, wi->instance_id); + sprintf(wi->secname, "Widget#%08X", gf_crc_32(szName, strlen(szName))); + + /*create section*/ + gf_cfg_set_key(wm->term->user->config, "Widgets", wi->secname, " "); + gf_cfg_set_key(wm->term->user->config, wi->secname, "WM:Manifest", wi->widget->url); + sprintf(szInst, "%d", wi->instance_id); + gf_cfg_set_key(wm->term->user->config, wi->secname, "WM:InstanceID", szInst); + } + gf_list_add(wm->widget_instances, wi); + + + if (strstr(path, "http://")) { + GF_XMLNode *context; + GF_DownloadSession *ctx_sess = NULL; + char *ctxPath; + + /*fetch the remote widget context synchronously and load it */ + ctxPath = gf_malloc(sizeof(char) * (strlen(path) + 1 + 15/*?mpeg-u-context*/)); + strcpy(ctxPath, path); + if ((strchr(path, '?') == NULL) && (strstr(path, "%3f")==NULL) && (strstr(path, "%3F")==NULL) ) { + strcat(ctxPath, "?mpeg-u-context"); + } else { + strcat(ctxPath, "&mpeg-u-context"); + } + + /*try to fetch the associated context*/ + ctx_sess = gf_dm_sess_new(wm->term->downloader, (char *)ctxPath, GF_NETIO_SESSION_NOT_THREADED|GF_NETIO_SESSION_FORCE_RESTART, NULL, NULL, &e); + if (ctx_sess) { + e = gf_dm_sess_process(ctx_sess); + if (e==GF_OK) { + wi->mpegu_context = gf_xml_dom_new(); + e = gf_xml_dom_parse(wi->mpegu_context , gf_dm_sess_get_cache_name(ctx_sess), NULL, NULL); + if (!e) { + context = gf_xml_dom_get_root(wi->mpegu_context); + if (strcmp(context->name, "contextInformation")) context = NULL; + } + } + gf_dm_sess_del(ctx_sess); + } + gf_free(ctxPath); + + if (!context && wi->mpegu_context) { + gf_xml_dom_del(wi->mpegu_context); + wi->mpegu_context = NULL; + } + + } + +exit: + if (dom) gf_xml_dom_del(dom); + if (sess) gf_dm_sess_del(sess); + if (e || !wi) { + if (wi) wm_delete_widget_instance(wm, wi); + else { + if (wpackage) widget_package_del(wm, wpackage); + } + return NULL; + } + return wi; +} + + +static Bool wm_enum_widget(void *cbk, char *file_name, char *file_path) +{ + GF_WidgetInstance *wid; + GF_WidgetManager *wm = (GF_WidgetManager *)cbk; + wid = wm_load_widget(wm, file_path, 0); + if (wid) { + wm_widget_jsbind(wm, wid); + /*remove section info*/ + gf_cfg_del_section(wm->term->user->config, wid->secname); + gf_cfg_set_key(wm->term->user->config, "Widgets", wid->secname, NULL); + } + return 0; +} + +static Bool wm_enum_dir(void *cbk, char *file_name, char *file_path) +{ + return gf_enum_directory(file_path, 0, wm_enum_widget, cbk, "mgt"); +} + + +static JSBool wm_initialize(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + u32 i, count; + const char*opt; + GF_WidgetManager *wm = (GF_WidgetManager *)JS_GetPrivate(c, obj); + + count = gf_cfg_get_key_count(wm->term->user->config, "Widgets"); + for (i=0; i<count; i++) { + const char *name = gf_cfg_get_key_name(wm->term->user->config, "Widgets", i); + /*this is a previously loaded widgets - reload it*/ + if (!strnicmp(name, "Widget#", 7)) { + const char *manifest = gf_cfg_get_key(wm->term->user->config, name, "WM:Manifest"); + if (manifest) { + const char *ID = gf_cfg_get_key(wm->term->user->config, name, "WM:InstanceID"); + u32 instID = ID ? atoi(ID) : 0; + GF_WidgetInstance *wi = wm_load_widget(wm, manifest, instID); + if (wi) { + strcpy(wi->secname, name); + wm_widget_jsbind(wm, wi); + } + } + } + } + + opt = gf_cfg_get_key(wm->term->user->config, "Widgets", "WidgetStore"); + if (opt) gf_enum_directory(opt, 1, wm_enum_dir, wm, NULL); + + return JS_TRUE; +} + +static void widgetmanager_load(GF_JSUserExtension *jsext, GF_SceneGraph *scene, JSContext *c, JSObject *global, Bool unload) +{ + GF_WidgetManager *wm; + + GF_JSAPIParam par; + JSPropertySpec wmClassProps[] = { + {0, 0, 0, 0, 0} + }; + JSFunctionSpec wmClassFuncs[] = { + {"initialize", wm_initialize, 0, 0, 0}, + {"load", wm_load, 1, 0, 0}, + {"unload", wm_unload, 1, 0, 0}, + {"get", wm_get, 1, 0, 0}, + {"findByInterface", wm_find_interface, 1, 0, 0}, + {0, 0, 0, 0, 0} + }; + + wm = jsext->udta; + /*widget manager is only loaded once*/ + if (wm->ctx && (wm->ctx != c)) { + /*load the 'Widget' object in the global scope*/ + widget_load(wm, scene, c, global, unload); + return; + } + + /*unload widgets*/ + if (unload) { + if (wm->obj) { + gf_js_remove_root(wm->ctx, &wm->obj); + wm->obj = NULL; + } + + while (gf_list_count(wm->widget_instances)) { + GF_WidgetInstance *widg = gf_list_get(wm->widget_instances, 0); + wm_delete_widget_instance(wm, widg); + } + wm->ctx = NULL; + return; + } + wm->ctx = c; + + if (!scene) return; + + /*setup JS bindings*/ + _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); + JS_SetPrivate(c, wm->obj, wm); + gf_js_add_root(c, &wm->obj); + + + { + JSPropertySpec wmWidgetClassProps[] = { + {0, 0, 0, 0, 0} + }; + JSFunctionSpec wmWidgetClassFuncs[] = { + {"activate", wm_widget_activate, 1, 0, 0}, + {"deactivate", wm_widget_deactivate, 0, 0, 0}, + {"get_interface", wm_widget_get_interface, 1, 0, 0}, + {"bind_output_trigger", wm_widget_bind_output_trigger, 2, 0, 0}, + {"set_input", wm_widget_set_input, 2, 0, 0}, + {"bind_interface", wm_widget_bind_interface, 2, 0, 0}, + {"unbind_interface", wm_widget_unbind_interface, 1, 0, 0}, + {"call_input_action", wm_widget_call_input_action, 1, 0, 0}, + {"call_input_script", wm_widget_call_input_script, 2, 0, 0}, + {"is_interface_bound", wm_widget_is_interface_bound, 1, 0, 0}, + {"get_param_value", wm_widget_get_param_value, 1, 0, 0}, + {"get_context", wm_widget_get_context, 0, 0, 0}, + {"get_component", wm_widget_get_component, 2, 0, 0}, + + {0, 0, 0, 0, 0} + }; + /*setup JS bindings*/ + _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); + + _SETUP_CLASS(wm->widgetAnyClass, "WIDGETANY", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, JS_FinalizeStub); + JS_InitClass(c, global, 0, &wm->widgetAnyClass, 0, 0, 0, 0, 0, 0); + } + + _SETUP_CLASS(wm->widgetClass, "MPEGWidget", JSCLASS_HAS_PRIVATE, widget_getProperty, widget_setProperty, JS_FinalizeStub); + + if (scene->script_action) { + if (!scene->script_action(scene->script_action_cbck, GF_JSAPI_OP_GET_TERM, scene->RootNode, &par)) + return; + wm->term = par.term; + } + +} + + +static GF_JSUserExtension *gwm_new() +{ + GF_JSUserExtension *dr; + GF_WidgetManager *wm; + dr = gf_malloc(sizeof(GF_JSUserExtension)); + memset(dr, 0, sizeof(GF_JSUserExtension)); + GF_REGISTER_MODULE_INTERFACE(dr, GF_JS_USER_EXT_INTERFACE, "WidgetManager JavaScript Bindings", "gpac distribution"); + + GF_SAFEALLOC(wm, GF_WidgetManager); + wm->widget_instances = gf_list_new(); + wm->widgets = gf_list_new(); + dr->load = widgetmanager_load; + dr->udta = wm; + return dr; +} + + +static void gwm_delete(GF_BaseInterface *ifce) +{ + GF_JSUserExtension *dr = (GF_JSUserExtension *) ifce; + GF_WidgetManager *wm = dr->udta; + gf_list_del(wm->widget_instances); + gf_list_del(wm->widgets); + gf_free(wm); + gf_free(dr); +} +#endif + + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { +#ifdef GPAC_HAS_SPIDERMONKEY + GF_JS_USER_EXT_INTERFACE, + GF_SCENE_DECODER_INTERFACE, +#endif + 0 + }; + return si; +} + +GF_EXPORT +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ +#ifdef GPAC_HAS_SPIDERMONKEY + if (InterfaceType == GF_JS_USER_EXT_INTERFACE) return (GF_BaseInterface *)gwm_new(); + else if (InterfaceType == GF_SCENE_DECODER_INTERFACE) return (GF_BaseInterface *)LoadWidgetReader(); +#endif + return NULL; +} + +GF_EXPORT +void ShutdownInterface(GF_BaseInterface *ifce) +{ + switch (ifce->InterfaceType) { +#ifdef GPAC_HAS_SPIDERMONKEY + case GF_JS_USER_EXT_INTERFACE: + gwm_delete(ifce); + break; + case GF_SCENE_DECODER_INTERFACE: + ShutdownWidgetReader(ifce); + break; +#endif + } +} + diff --git a/modules/widgetman/widgetman.h b/modules/widgetman/widgetman.h new file mode 100644 index 0000000..52d7ade --- /dev/null +++ b/modules/widgetman/widgetman.h @@ -0,0 +1,370 @@ +//This software module was originally developed by TelecomParisTech in the +//course of the development of MPEG-U Widgets (ISO/IEC 23007-1) standard. +// +//This software module is an implementation of a part of one or +//more MPEG-U Widgets (ISO/IEC 23007-1) tools as specified by the MPEG-U Widgets +//(ISO/IEC 23007-1) standard. ISO/IEC gives users of the MPEG-U Widgets +//(ISO/IEC 23007-1) free license to this software module or modifications +//thereof for use in hardware or software products claiming conformance to +//the MPEG-U Widgets (ISO/IEC 23007-1). Those intending to use this software +//module in hardware or software products are advised that its use may +//infringe existing patents. +//The original developer of this software module and his/her company, the +//subsequent editors and their companies, and ISO/IEC have no liability +//for use of this software module or modifications thereof in an implementation. +//Copyright is not released for non MPEG-U Widgets (ISO/IEC 23007-1) conforming +//products. +//Telecom ParisTech retains full right to use the code for his/her own purpose, +//assign or donate the code to a third party and to inhibit third parties from +//using the code for non MPEG-U Widgets (ISO/IEC 23007-1) conforming products. +// +//This copyright notice must be included in all copies or derivative works. +// +//Copyright (c) 2009. +// +///////////////////////////////////////////////////////////////////////////////// + +///////////////////////////////////////////////////////////////////////////////// +// +// Authors: +// Jean Le Feuvre, Telecom ParisTech +// Cyril Concolato, Telecom ParisTech +// +///////////////////////////////////////////////////////////////////////////////// + +#ifndef _WIDGETMAN_H_ +#define _WIDGETMAN_H_ + +/*base SVG type*/ +#include <gpac/modules/js_usr.h> + +#ifdef GPAC_HAS_SPIDERMONKEY + +#include <gpac/nodes_mpeg4.h> +#include <gpac/nodes_x3d.h> +#include <gpac/nodes_svg.h> +/*dom events*/ +#include <gpac/events.h> + +#include <gpac/download.h> +#include <gpac/crypt.h> +#include <gpac/network.h> +#include <gpac/xml.h> +#include <gpac/internal/scenegraph_dev.h> + + +#include <gpac/isomedia.h> + +#include "unzip.h" + +#include <jsapi.h> + +#include <gpac/internal/terminal_dev.h> +#include <gpac/internal/compositor_dev.h> + + +JSBool gf_sg_js_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node); +JSBool gf_sg_js_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node); + +typedef struct _widget_manager +{ + JSContext *ctx; + /*widget manager class*/ + JSClass widmanClass; + /*widget class used by the widget manager*/ + JSClass wmWidgetClass; + + /*widget class used by the widget scripts*/ + JSClass widgetClass; + + JSClass widgetAnyClass; + + JSObject *obj; + GF_Terminal *term; + GF_List *widget_instances; + /*list of loaded prototypes (eg 1 per all instances of the same widget*/ + GF_List *widgets; +} GF_WidgetManager; + + + +enum +{ + GF_WPIN_STRING, + GF_WPIN_INTEGER, + GF_WPIN_NUMBER, +}; + +typedef struct +{ + char *inner_path; + char *extracted_path; + Bool extracted; +} GF_WidgetPackageResource; + +typedef struct _widget_package_relocator +{ + GF_TERM_URI_RELOCATOR + GF_List *resources; + struct _widget *widget; + GF_WidgetManager *wm; + Bool is_zip; + char root_extracted_path[GF_MAX_PATH]; + char archive_id[14]; + char *package_path; + GF_DownloadSession *sess; +} GF_WidgetPackage; + + +enum +{ + GF_WM_PARAM_OUTPUT, + GF_WM_PARAM_INPUT, + GF_WM_INPUT_ACTION, + GF_WM_OUTPUT_TRIGGER, + GF_WM_BIND_ACTION, + GF_WM_UNBIND_ACTION, + GF_WM_PREF_CONNECT, + GF_WM_ACTIVATE_TRIGGER, + GF_WM_DEACTIVATE_TRIGGER, + GF_WM_PREF_SAVEDACTION, + GF_WM_PREF_RESTOREDACTION, + GF_WM_PREF_SAVETRIGGER, + GF_WM_PREF_RESTORETRIGGER, +}; + +#define GF_WM_PARAM_SCRIPT_STRING (u16) 0 +#define GF_WM_PARAM_SCRIPT_BOOL (u16) 1 +#define GF_WM_PARAM_SCRIPT_NUMBER (u16) 2 + +typedef struct +{ + struct __widget_message *msg; + + u16 type; + u16 script_type; + Bool in_action; + + char *name; + char *node; + char *attribute; + char *default_value; +} GF_WidgetPin; + +typedef struct __widget_message +{ + struct _widget_interface *ifce; + + char *name; + Bool is_output; + GF_List *params; + + GF_WidgetPin *input_action; + GF_WidgetPin *output_trigger; + +} GF_WidgetMessage; + +typedef struct _widget_interface +{ + struct __widget_content *content; + char *type; + GF_List *messages; + + GF_WidgetPin *bind_action; + GF_WidgetPin *unbind_action; + Bool provider, multiple_binding, required; + char *connectTo; + + JSObject *obj; +} GF_WidgetInterface; + +typedef struct _widget_component +{ + struct __widget_content *content; + char *id; /*may be NULL*/ + char *src; /*may be NULL*/ + GF_List *required_interfaces; /*may be empty*/ + GF_WidgetPin *activateTrigger; + GF_WidgetPin *deactivateTrigger; + GF_WidgetPin *activatedAction; + GF_WidgetPin *deactivatedAction; +} GF_WidgetComponent; + +enum +{ + GF_WM_PREF_READONLY = 1, + GF_WM_PREF_SAVE = 1<<1, + GF_WM_PREF_MIGRATE = 1<<2, +}; + +typedef struct +{ + char *name, *value; + u32 flags; + GF_WidgetPin *connectTo; +} GF_WidgetPreference; + +typedef struct +{ + char *name, *value; +} GF_WidgetFeatureParam; + +typedef struct +{ + char *name; + Bool required; + GF_List *params; +} GF_WidgetFeature; + +typedef struct __widget_content +{ + struct _widget *widget; + + char *src; + char *relocated_src; + u32 width, height; + + char *encoding, *mimetype; + + GF_List *interfaces; + GF_List *components; + /*list of preferences for the widget content*/ + GF_List *preferences; + + GF_WidgetPin *savedAction; + GF_WidgetPin *restoredAction; + GF_WidgetPin *saveTrigger; + GF_WidgetPin *restoreTrigger; +} GF_WidgetContent; + +typedef struct _widget +{ + GF_WidgetManager *wm; + + u32 nb_instances; + + /* url to the file.wgt file when zip packaged or to the config.xml file when unpackaged */ + char *url; + /* path to the manifest/config document */ + char *manifest_path; + + GF_List *icons; +/* + GF_WidgetContent *simple; + char *icon_url; +*/ + GF_WidgetContent *main; + + GF_WidgetPackage *wpack; + + /*misc metadata for W3C Widgets API*/ + char *name, *shortname, *identifier, + *authorName, *authorEmail, *authorHref, + *description, *version, + *uuid, *license, *licenseHref, *viewmodes; + + u32 width, height; + + GF_List *features; + + Bool discardable, multipleInstance; + + /*when a widget is being received from a remote peer, + we remember where we locally store it to be able to further remote it + This is only supported for packaged widgets*/ + char *local_path; +} GF_Widget; + +typedef struct _widget_instance +{ + GF_Widget *widget; + + u32 instance_id; + JSObject *obj; + u8 secname[18]; + GF_SceneGraph *scene; + /*node in the widget manager which holds the widget: Inline {} , <animation>, ...*/ + GF_Node *anchor; + + Bool activated, permanent; + + GF_List *output_triggers; + GF_List *bound_ifces; + /*list of components for a parent widget*/ + GF_List *components; + /*parent of the widget for a component widget*/ + struct _widget_instance *parent; + + GF_DOMParser *mpegu_context; + + + /*scripting context of the widget scene*/ + JSContext *scene_context; + JSObject *scene_global; + /*"Widget" object in the scene*/ + JSObject *scene_obj; +} GF_WidgetInstance; + + +typedef struct +{ + GF_WidgetInterface *ifce; + GF_WidgetInstance *wid; + char *hostname; + JSObject *obj; + JSObject *cookie; +} GF_WidgetInterfaceInstance; + +typedef struct +{ + GF_WidgetComponent *comp; + GF_WidgetInstance *wid; +} GF_WidgetComponentInstance; + + +GF_WidgetInstance *wm_load_widget(GF_WidgetManager *wm, const char *path, u32 InstanceID); + + +#define _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; + + + + +JSBool widget_has_feature(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +JSBool widget_open_url(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +JSBool widget_get_attention(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +JSBool widget_show_notification(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +JSBool widget_get_interface(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval); +JSBool widget_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp); +JSBool widget_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp); + +void widget_on_interface_bind(GF_WidgetInterfaceInstance *ifce, Bool unbind); + +void widget_load(GF_WidgetManager *wm, GF_SceneGraph *scene, JSContext *c, JSObject *global, Bool unload); + +GF_WidgetComponentInstance *wm_activate_component(JSContext *c, GF_WidgetInstance *wid, GF_WidgetComponent *comp, Bool skip_wm_notification); + +void wm_deactivate_component(JSContext *c, GF_WidgetInstance *wid, GF_WidgetComponent *comp, GF_WidgetComponentInstance *comp_inst); + + + +const char *wm_xml_get_attr(GF_XMLNode *root, const char *name); + +GF_BaseInterface *LoadWidgetReader(); +void ShutdownWidgetReader(GF_BaseInterface *ifce); + + +#endif /*GPAC_HAS_SPIDERMONKEY*/ + +#endif diff --git a/modules/wiiis/Makefile b/modules/wiiis/Makefile new file mode 100644 index 0000000..8d78286 --- /dev/null +++ b/modules/wiiis/Makefile @@ -0,0 +1,60 @@ +include ../../config.mak + +vpath %.c $(SRC_PATH)/modules/wiiis + +CFLAGS= $(OPTFLAGS) -I$(SRC_PATH)/include + +ifeq ($(DEBUGBUILD), yes) +CFLAGS+=-g +LDFLAGS+=-g +endif + +ifeq ($(GPROFBUILD), yes) +CFLAGS+=-pg +LDFLAGS+=-pg +endif + +CFLAGS+= -I$(LOCAL_INC_PATH) +EXTRALIBS+= -L../../extra_lib/lib/gcc -lwiiuse + +#common obj +OBJS= wiiis.o + +SRCS := $(OBJS:.o=.c) + +LIB=gm_wiiis.$(DYN_LIB_SUFFIX) +ifeq ($(CONFIG_WIN32),yes) +#LDFLAGS+=-export-symbols wiiis.def +endif + + +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) + +dep: depend + +depend: + rm -f .depend + $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend + +distclean: clean + rm -f Makefile.bak .depend + + + +# include dependency files if they exist +# +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/modules/wiiis/test_wii.bt b/modules/wiiis/test_wii.bt new file mode 100644 index 0000000..9bae656 --- /dev/null +++ b/modules/wiiis/test_wii.bt @@ -0,0 +1,251 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0x01 + sceneProfileLevelIndication 0x01 + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFE + graphicsProfileLevelIndication 0x01 + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { +//Group { + children [ + Background2D {backColor 1 1 1} + + WorldInfo { + title "InputSensor Test - StringSensor device" + info ["This shows usage of String Sensor" "" "GPAC Regression Tests" "(C) 2002 ENST"] + } + DEF VP Viewpoint { + position 0 0 400 + } + + Transform2D { + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0.0 0.0 0.0 + filled TRUE + } + } + geometry DEF TEXT Text { + string [ "WiiMote Sensor" ] + fontStyle FontStyle { + justify [ "MIDDLE" "MIDDLE" ] + size 20.0 + } + } + } + ] + } + DEF RECT Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } +# geometry Box { size 100 100 100 } + geometry Rectangle { size 100 100 } + } + ] + } + + DEF SC Script { + eventIn SFInt32 on_uid + eventIn SFBool on_key_one + eventIn SFBool on_key_two + eventIn SFBool on_key_A + eventIn SFBool on_key_B + eventIn SFBool on_key_minus + eventIn SFBool on_key_home + eventIn SFBool on_key_plus + eventIn SFBool on_key_left + eventIn SFBool on_key_right + eventIn SFBool on_key_down + eventIn SFBool on_key_up + eventIn SFVec3f on_ypr + eventIn SFVec3f on_gravity + + field SFNode text USE TEXT + field SFNode rect USE RECT + field SFNode vp USE VP + url "javascript: + +function initialize() +{ + uid=0; + key_one = key_two = key_A = key_B = key_minus = key_home = key_plus = key_left = key_right = key_down = key_up = FALSE; + ypr = new SFVec3f(0,0,0); + grav = new SFVec3f(0,0,0); + h_rot = new SFRotation(0,1,0,0); + v_rot = new SFRotation(1,0,0,0); +} + +function update() +{ + text.string[1] = 'UID '+uid; + text.string[2] = '1 '+key_one + ' ; 2 '+key_two; + text.string[3] = 'A '+key_A + ' ; B '+key_B; + text.string[4] = '- '+key_minus + ' ; home '+key_home + ' ; + '+key_plus; + text.string[5] = 'left '+key_left + ' ; right '+key_right + ' ; down '+key_down + ' ; up '+key_up; + text.string[6] = 'Yaw '+ypr.x; + text.string[7] = 'Pitch '+ypr.y; + text.string[8] = 'Roll '+ypr.z; + text.string[9] = 'GravX '+grav.x; + text.string[10] = 'GravY '+grav.y; + text.string[11] = 'GravZ '+grav.z; + +// rect.rotationAngle = -ypr.y; + h_rot.angle = -ypr.z; + v_rot.angle = -ypr.y; + vp.orientation = h_rot.multiply(v_rot); + + if (key_A) vp.position.z -= 40; + else if (key_B) vp.position.z += 40; + + rect.rotationAngle = -grav.z; +} + +function on_uid(value) +{ + uid=value; + update(); +} + +function on_key_one(value) +{ + key_one=value; + update(); +} +function on_key_two(value) +{ + key_two=value; + update(); +} +function on_key_A(value) +{ +print(''+value); + key_A=value; + update(); +} +function on_key_B(value) +{ + key_B=value; + update(); +} +function on_key_minus(value) +{ + key_minus=value; + update(); +} +function on_key_home(value) +{ + key_home=value; + update(); +} +function on_key_plus(value) +{ + key_plus=value; + update(); +} +function on_key_left(value) +{ + key_left=value; + update(); +} +function on_key_right(value) +{ + key_right=value; + update(); +} +function on_key_down(value) +{ + key_down=value; + update(); +} +function on_key_up(value) +{ + key_up=value; + update(); +} +function on_ypr(value) +{ + ypr = value; + update(); +} +function on_gravity(value) +{ + grav = value; + update(); +} + + + " + } + + InputSensor { + url [ "10" ] + buffer { + REPLACE SC.on_uid BY 0 + REPLACE SC.on_key_one BY FALSE + REPLACE SC.on_key_two BY FALSE + REPLACE SC.on_key_A BY FALSE + REPLACE SC.on_key_B BY FALSE + REPLACE SC.on_key_minus BY FALSE + REPLACE SC.on_key_home BY FALSE + REPLACE SC.on_key_plus BY FALSE + REPLACE SC.on_key_left BY FALSE + REPLACE SC.on_key_right BY FALSE + REPLACE SC.on_key_down BY FALSE + REPLACE SC.on_key_up BY FALSE + REPLACE SC.on_ypr BY 0 0 0 + REPLACE SC.on_gravity BY 0 0 0 + } + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esdescr [ + ES_Descriptor { + es_id 5 + decConfigDescr DecoderConfigDescriptor { + streamType 0x0A + decSpecificInfo UIConfig { + deviceName "WiiMote" + } + } + } + ] + } + ] +} diff --git a/modules/wiiis/wiiis.c b/modules/wiiis/wiiis.c new file mode 100644 index 0000000..b283984 --- /dev/null +++ b/modules/wiiis/wiiis.c @@ -0,0 +1,263 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) ENST 2009- + * Authors: Jean Le Feuvre + * All rights reserved + * + * This file is part of GPAC / Dummy input 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/modules/codec.h> +#include <gpac/scenegraph_vrml.h> +#include <gpac/thread.h> + +#include <wiiuse.h> + +typedef struct +{ + u32 nb_wiimotes; + wiimote** wiimotes; + Bool running; + u32 prev_id; + + GF_Thread *th; +} GF_WiiMote; + +static Bool WII_RegisterDevice(struct __input_device *ifce, const char *urn, GF_BitStream *dsi, void (*AddField)(struct __input_device *_this, u32 fieldType, const char *name)) +{ + const char *opt; + GF_WiiMote *wii = (GF_WiiMote *)ifce->udta; + if (strcmp(urn, "WiiMote")) return 0; + + /*init wiiuse lib*/ + opt = gf_modules_get_option((GF_BaseInterface*)ifce, "WII", "MaxWiimotes"); + if (opt) wii->nb_wiimotes = atoi(opt); + if (!wii->nb_wiimotes) wii->nb_wiimotes = 1; + + wii->wiimotes = wiiuse_init(wii->nb_wiimotes); + if (!wii->wiimotes) { + GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[Wii] Cannot initialize wiiuse library\n")); + return 0; + } + + /*declare the interface*/ + AddField(ifce, GF_SG_VRML_SFINT32, "uid"); + AddField(ifce, GF_SG_VRML_SFBOOL, "1"); + AddField(ifce, GF_SG_VRML_SFBOOL, "2"); + AddField(ifce, GF_SG_VRML_SFBOOL, "A"); + AddField(ifce, GF_SG_VRML_SFBOOL, "B"); + AddField(ifce, GF_SG_VRML_SFBOOL, "-"); + AddField(ifce, GF_SG_VRML_SFBOOL, "home"); + AddField(ifce, GF_SG_VRML_SFBOOL, "+"); + AddField(ifce, GF_SG_VRML_SFBOOL, "left"); + AddField(ifce, GF_SG_VRML_SFBOOL, "right"); + AddField(ifce, GF_SG_VRML_SFBOOL, "down"); + AddField(ifce, GF_SG_VRML_SFBOOL, "up"); + AddField(ifce, GF_SG_VRML_SFVEC3F, "ypr"); + AddField(ifce, GF_SG_VRML_SFVEC3F, "gravity"); + + return 1; +} + +#define WRITE_BUTTON(_b) \ + if (IS_JUST_PRESSED(wm, _b)) { gf_bs_write_int(bs, 1, 1); gf_bs_write_int(bs, 1, 1); } \ + else if (IS_RELEASED(wm, _b)) { gf_bs_write_int(bs, 1, 1); gf_bs_write_int(bs, 0, 1); } \ + else gf_bs_write_int(bs, 0, 1); \ + + +#define WII_PI 3.1415926535898f + +static u32 WII_Run(void *par) +{ + GF_BitStream *bs; + char *buf; + u32 i, buf_size, count, scan_delay; + const char *opt; + + GF_InputSensorDevice *ifce = (GF_InputSensorDevice *)par; + GF_WiiMote *wii = (GF_WiiMote *)ifce->udta; + + + scan_delay = 5; + opt = gf_modules_get_option((GF_BaseInterface*)ifce, "WII", "ScanDelay"); + if (opt) scan_delay = atoi(opt); + + /*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)); + } else { + GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[Wii] Failed to connect to any wiimote\n")); + } + + opt = gf_modules_get_option((GF_BaseInterface*)ifce, "WII", "MotionSensing"); + /*enable motion sensing*/ + if (!opt || !strcmp(opt, "yes")) { + Float smooth_alpha = 0.5; + Float ori_threshold = 10.0; + opt = gf_modules_get_option((GF_BaseInterface*)ifce, "WII", "OrientationThreshold"); + if (opt) ori_threshold = (Float) atof(opt); + opt = gf_modules_get_option((GF_BaseInterface*)ifce, "WII", "SmoothAlpha"); + if (opt) { + smooth_alpha = (Float) atof(opt); + if (smooth_alpha<0) smooth_alpha = 0.5; + else if (smooth_alpha>1.0) smooth_alpha=0.5; + } + GF_LOG(GF_LOG_INFO, GF_LOG_MMIO, ("[Wii] Enabling motion sensing - Alpha smoothing %f - Orientation Threshold %f\n", smooth_alpha, ori_threshold)); + + for (i=0; i<count; i++) { + wiiuse_motion_sensing(wii->wiimotes[i], 1); + wiiuse_set_smooth_alpha(wii->wiimotes[i],smooth_alpha); + wiiuse_set_orient_threshold(wii->wiimotes[i], ori_threshold); + } + } + + while (wii->running) { + count = wiiuse_poll(wii->wiimotes, wii->nb_wiimotes); + if (!count) { + continue; + } + for (i=0; i<count; i++) { + struct wiimote_t* wm = wii->wiimotes[i]; + switch (wm->event) { + case WIIUSE_EVENT:/* A generic event occured on the wiimote. */ + /*create the data frame*/ + bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + /*if not the same wiimote write the UID*/ + if (wii->prev_id != wm->unid) { + gf_bs_write_int(bs, 1, 1); + gf_bs_write_int(bs, wm->unid, 32); + wii->prev_id = wm->unid; + } else { + gf_bs_write_int(bs, 0, 1); + } + + /*write buttons state*/ + WRITE_BUTTON(WIIMOTE_BUTTON_ONE); + WRITE_BUTTON(WIIMOTE_BUTTON_TWO); + WRITE_BUTTON(WIIMOTE_BUTTON_A); + WRITE_BUTTON(WIIMOTE_BUTTON_B); + WRITE_BUTTON(WIIMOTE_BUTTON_MINUS); + WRITE_BUTTON(WIIMOTE_BUTTON_HOME); + WRITE_BUTTON(WIIMOTE_BUTTON_PLUS); + WRITE_BUTTON(WIIMOTE_BUTTON_LEFT); + WRITE_BUTTON(WIIMOTE_BUTTON_RIGHT); + WRITE_BUTTON(WIIMOTE_BUTTON_DOWN); + WRITE_BUTTON(WIIMOTE_BUTTON_UP); + + /*write yaw-pitch-roll - FIXME: wiiuse seems to output NaN in these values upon init*/ + gf_bs_write_int(bs, 1, 1); + gf_bs_write_float(bs, WII_PI * wm->orient.yaw / 24 ); + gf_bs_write_float(bs, WII_PI * wm->orient.pitch / 180); + gf_bs_write_float(bs, WII_PI * wm->orient.roll / 180); + + /*write gravity - FIXME: wiiuse seems to output NaN in these values upon init*/ + gf_bs_write_int(bs, 1, 1); + gf_bs_write_float(bs, wm->gforce.x); + gf_bs_write_float(bs, wm->gforce.y); + gf_bs_write_float(bs, wm->gforce.z); + + gf_bs_align(bs); + gf_bs_get_content(bs, &buf, &buf_size); + gf_bs_del(bs); + + ifce->DispatchFrame(ifce, buf, buf_size); + gf_free(buf); + break; + case WIIUSE_STATUS: /*A status report was obtained from the wiimote. */ + break; + case WIIUSE_DISCONNECT:/*The wiimote disconnected. */ + break; + case WIIUSE_READ_DATA:/* Data was returned that was previously requested from the wiimote ROM/registers. */ + break; + case WIIUSE_NUNCHUK_INSERTED: + case WIIUSE_NUNCHUK_REMOVED: + case WIIUSE_CLASSIC_CTRL_INSERTED: + case WIIUSE_CLASSIC_CTRL_REMOVED: + case WIIUSE_GUITAR_HERO_3_CTRL_INSERTED: + case WIIUSE_GUITAR_HERO_3_CTRL_REMOVED: + break; + } + } + } + return 0; +} + +static void WII_Start(struct __input_device *ifce) +{ + GF_WiiMote *wii = (GF_WiiMote *)ifce->udta; + wii->running = 1; + gf_th_run(wii->th, WII_Run, ifce); +} + +static void WII_Stop(struct __input_device *ifce) +{ + GF_WiiMote *wii = (GF_WiiMote *)ifce->udta; + wii->running = 0; +} + + +GF_EXPORT +const u32 *QueryInterfaces() +{ + static u32 si [] = { + GF_INPUT_DEVICE_INTERFACE, + 0 + }; + return si; +} + +GF_EXPORT +GF_BaseInterface *LoadInterface(u32 InterfaceType) +{ + GF_WiiMote *wii; + GF_InputSensorDevice *plug; + if (InterfaceType != GF_INPUT_DEVICE_INTERFACE) return NULL; + + GF_SAFEALLOC(plug, GF_InputSensorDevice); + GF_REGISTER_MODULE_INTERFACE(plug, GF_INPUT_DEVICE_INTERFACE, "GPAC Wiimote InputSensor", "gpac distribution") + + plug->RegisterDevice = WII_RegisterDevice; + plug->Start = WII_Start; + plug->Stop = WII_Stop; + + GF_SAFEALLOC(wii, GF_WiiMote); + plug->udta = wii; + wii->th = gf_th_new("WiiMote"); + return (GF_BaseInterface *)plug; +} + +GF_EXPORT +void ShutdownInterface(GF_BaseInterface *bi) +{ + GF_WiiMote *wii; + GF_InputSensorDevice *ifce = (GF_InputSensorDevice*)bi; + if (ifce->InterfaceType!=GF_INPUT_DEVICE_INTERFACE) return; + + wii = ifce->udta; + if (wii->wiimotes) { + wiiuse_cleanup(wii->wiimotes, wii->nb_wiimotes); + } + gf_free(wii); + gf_free(bi); +} diff --git a/modules/x11_out/Makefile b/modules/x11_out/Makefile index 3cac27e..af8ca4e 100644 --- a/modules/x11_out/Makefile +++ b/modules/x11_out/Makefile @@ -14,14 +14,10 @@ CFLAGS+=-pg LDFLAGS+=-pg endif -CFLAGS+=-I$(SRC_PATH)/include -DGPAC_HAVE_CONFIG_H -I../../ +CFLAGS+=-I$(SRC_PATH)/include # -I/usr/local/arm/3.3.2/include -ifeq ($(ENABLE_JOYSTICK), yes) -CFLAGS+=-DENABLE_JOYSTICK -endif - ifeq ($(X11_INC_PATH), ) else CFLAGS+=-I$(X11_INC_PATH) @@ -45,9 +41,11 @@ endif ifeq ($(HAS_OPENGL), yes) ifeq ($(GPAC_USE_TINYGL), yes) else -#CFLAGS +=-DGPAC_HAS_OPENGL -LDFLAGS+=-lGL -#LDFLAGS+=-lTinyGL -L$(SRC_PATH)../../TinyGL/lib/ +CFLAGS+=$(OGL_INCLS) +LDFLAGS+=$(OGL_LIBS) +ifeq ($(CONFIG_DARWIN),yes) +LDFLAGS+=-lGL -lGLU +endif endif endif @@ -58,21 +56,22 @@ SRCS := $(OBJS:.o=.c) LIB=gm_x11_out.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols +#LDFLAGS+=-export-symbols endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -lX11 -L../../bin/gcc -lgpac -o ../../bin/gcc/$@ $(OBJSPIC) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -lX11 -L../../bin/gcc -lgpac -o ../../bin/gcc/$@ $(OBJS) +ifeq ($(STATICBUILD),yes) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_x11_out-static.so $(OBJS) -lX11 -L../../bin/gcc -lgpac_static +endif +#static-bin: +# $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/gm_x11_out-static.so $(OBJS) -lX11 -L../../bin/gcc -lgpac_static + %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< diff --git a/modules/x11_out/x11_out.c b/modules/x11_out/x11_out.c index 9629044..a0176bf 100644 --- a/modules/x11_out/x11_out.c +++ b/modules/x11_out/x11_out.c @@ -25,6 +25,7 @@ #include "x11_out.h" #include <gpac/constants.h> +#include <sys/time.h> void X11_SetupWindow (GF_VideoOutput * vout); @@ -190,6 +191,12 @@ GF_Err X11_Blit(struct _video_out *vout, GF_VideoSurface *video_src, GF_Window * Window cur_wnd; XWindow *xwin = (XWindow *)vout->opaque; + if (!video_src) { + if (overlay_type && xwin->xvport) { + } + return GF_OK; + } + if (video_src->pixel_format != GF_PIXEL_YV12) return GF_NOT_SUPPORTED; cur_wnd = xwin->fullscreen ? xwin->full_wnd : xwin->wnd; /*init if needed*/ @@ -270,7 +277,7 @@ GF_Err X11_Flush(struct _video_out *vout, GF_Window * dest) #endif { XSync(xWindow->display, False); - XRaiseWindow(xWindow->display, xWindow->wnd); + //XRaiseWindow(xWindow->display, xWindow->wnd); XPutImage (xWindow->display, cur_wnd, xWindow->the_gc, xWindow->surface, 0, 0, dest->x, dest->y, dest->w, dest->h); } @@ -519,9 +526,6 @@ static void X11_HandleEvents(GF_VideoOutput *vout) X11VID(); unsigned char keybuf[32]; XEvent xevent; -#ifdef ENABLE_JOYSTICK - struct js_event jsevent; -#endif the_window = xWindow->fullscreen ? xWindow->full_wnd : xWindow->wnd; XSync(xWindow->display, False); @@ -564,8 +568,6 @@ static void X11_HandleEvents(GF_VideoOutput *vout) vout->on_event(vout->evt_cbk_hdl, &evt); } break; - -#ifndef ENABLE_JOYSTICK case KeyPress: case KeyRelease: @@ -652,131 +654,9 @@ static void X11_HandleEvents(GF_VideoOutput *vout) default: break; -#endif } } -#ifdef ENABLE_JOYSTICK - while (read (xWindow->fd, &jsevent, sizeof(struct js_event)) > 0){ - s32 mul; - - switch (jsevent.type) { - case JS_EVENT_BUTTON: - - if (jsevent.value){ - /*pressed event*/ - if (!xWindow->fullscreen && !xWindow->has_focus ) xWindow->has_focus = 1; - if (jsevent.number<4) evt.type = GF_EVENT_MOUSEDOWN; - else evt.type = GF_EVENT_KEYDOWN; - - } else { - - if (jsevent.number<4) evt.type = GF_EVENT_MOUSEUP; - else evt.type = GF_EVENT_KEYUP; - - } - - - switch (jsevent.number){ - case 0: - evt.mouse.button = GF_MOUSE_LEFT; - evt.mouse.x = xWindow->prev_x; - evt.mouse.y = xWindow->prev_y; - vout->on_event (vout->evt_cbk_hdl, &evt); - break; - - case 1: - evt.mouse.button = GF_MOUSE_MIDDLE; - evt.mouse.x = xWindow->prev_x; - evt.mouse.y = xWindow->prev_y; - vout->on_event (vout->evt_cbk_hdl, &evt); - break; - - case 2: - evt.mouse.button = GF_MOUSE_RIGHT; - evt.mouse.x = xWindow->prev_x; - evt.mouse.y = xWindow->prev_y; - vout->on_event (vout->evt_cbk_hdl, &evt); - break; - - case 4: - case 5: - case 6: - case 7: - evt.key.key_code = GF_KEY_JOYSTICK; - evt.key.hw_code = jsevent.number; - vout->on_event (vout->evt_cbk_hdl, &evt); - break; - - default: - break; - } - - - break; - case JS_EVENT_AXIS: - if (ABS(jsevent.value)>16000) mul = 6; - else if (ABS(jsevent.value)>1024) mul = 2; - else mul = 1; - if (jsevent.number==0) { - if (jsevent.value>0) xWindow->prev_x += mul; - else if (jsevent.value<0) { - xWindow->prev_x -= mul; - // if (xWindow->prev_x <0) xWindow->prev_x=0; - } - if (vout->centered_mode==1){ - xWindow->prev_x = ((0xFFFF/2) + jsevent.value) * xWindow->w_width; - xWindow->prev_x /= 0xFFFF; - } - - } - else if (jsevent.number==1) { - if (jsevent.value>0) xWindow->prev_y += mul; - else if (jsevent.value<0) { - xWindow->prev_y -= mul; - // if (xWindow->prev_y <0) xWindow->prev_y=0; - } - if (vout->centered_mode==1) { - xWindow->prev_y = ((0xFFFF/2) + jsevent.value) * xWindow->w_height; - xWindow->prev_y /= 0xFFFF; - } - /* if (jsevent.value>0) xWindow->prev_y += mul; - else xWindow->prev_y -= mul; */ - - } - /* fprintf(stdout, "X %d - y %d\n", xWindow->prev_x, xWindow->prev_y); */ - evt.type = GF_EVENT_MOUSEMOVE; - evt.mouse.x = xWindow->prev_x; - evt.mouse.y = xWindow->prev_y; - vout->on_event (vout->evt_cbk_hdl, &evt); - break; - - case PropertyNotify: - break; - case MapNotify: - break; - case CirculateNotify: - break; - case UnmapNotify: - break; - case ReparentNotify: - break; - case FocusOut: - // if (!xWindow->fullscreen) xWindow->has_focus = 0; - break; - case FocusIn: - // if (!xWindow->fullscreen) xWindow->has_focus = 1; - break; - - case DestroyNotify: - evt.type = GF_EVENT_QUIT; - vout->on_event(vout->evt_cbk_hdl, &evt); - break; - - // case JS_EVENT_INIT: - } - } -#endif } @@ -887,13 +767,13 @@ static void X11_ReleaseBackBuffer (GF_VideoOutput * vout) if (xWindow->shmseginfo->shmaddr) shmdt(xWindow->shmseginfo->shmaddr); if (xWindow->shmseginfo->shmid >= 0) shmctl (xWindow->shmseginfo->shmid, IPC_RMID, NULL); - free (xWindow->shmseginfo); + gf_free(xWindow->shmseginfo); xWindow->shmseginfo = NULL; } #endif if (xWindow->surface) { if (xWindow->surface->data) - free (xWindow->surface->data); + gf_free(xWindow->surface->data); XFree(xWindow->surface); xWindow->surface = NULL; } @@ -960,7 +840,7 @@ GF_Err X11_InitBackBuffer (GF_VideoOutput * vout, u32 VideoWidth, u32 VideoHeigh } else #endif { - char *data = (char *) malloc(sizeof(char)*size); + char *data = (char *) gf_malloc(sizeof(char)*size); xWindow->surface = XCreateImage (xWindow->display, xWindow->visual, xWindow->depth, ZPixmap, 0, @@ -968,7 +848,7 @@ GF_Err X11_InitBackBuffer (GF_VideoOutput * vout, u32 VideoWidth, u32 VideoHeigh VideoWidth, VideoHeight, xWindow->bpp*8, xWindow->bpp*VideoWidth); if (!xWindow->surface) { - free(data); + gf_free(data); return GF_IO_ERR; } @@ -1012,10 +892,6 @@ GF_Err X11_ProcessEvent (struct _video_out * vout, GF_Event * evt) /*if owning the window and not in fullscreen, resize it (initial scene size)*/ xWindow->w_width = evt->size.width; xWindow->w_height = evt->size.height; -#ifdef ENABLE_JOYSTICK - xWindow->prev_x = xWindow->w_width/2; - xWindow->prev_y = xWindow->w_height/2; -#endif if (!xWindow->fullscreen) { if (xWindow->par_wnd) { @@ -1111,14 +987,16 @@ GF_Err X11_LockBackBuffer(struct _video_out * vout, GF_VideoSurface * vi, u32 do if (xWindow->surface) { vi->width = xWindow->surface->width; vi->height = xWindow->surface->height; - vi->pitch = xWindow->surface->width*xWindow->bpp; + vi->pitch_x = xWindow->bpp; + vi->pitch_y = xWindow->surface->width*xWindow->bpp; vi->pixel_format = xWindow->pixel_format; vi->video_buffer = xWindow->surface->data; } else { #ifdef GPAC_HAS_X11_SHM vi->width = xWindow->pwidth; vi->height = xWindow->pheight; - vi->pitch = xWindow->pwidth*xWindow->bpp; + vi->pitch_x = xWindow->bpp; + vi->pitch_y = xWindow->pwidth*xWindow->bpp; vi->pixel_format = xWindow->pixel_format; vi->video_buffer = (unsigned char *) xWindow->shmseginfo->shmaddr; #endif @@ -1175,6 +1053,7 @@ X11_SetupWindow (GF_VideoOutput * vout) { X11VID (); const char *sOpt; + Bool autorepeat, supported; xWindow->display = XOpenDisplay (NULL); xWindow->screennum = DefaultScreen (xWindow->display); @@ -1182,6 +1061,15 @@ X11_SetupWindow (GF_VideoOutput * vout) xWindow->visual = DefaultVisualOfScreen (xWindow->screenptr); xWindow->depth = DefaultDepth (xWindow->display, xWindow->screennum); + { + Float screenWidth = (Float)XWidthOfScreen(xWindow->screenptr); + Float screenWidthIn = (Float)XWidthMMOfScreen(xWindow->screenptr) / 25.4f; + Float screenHeight = (Float)XHeightOfScreen(xWindow->screenptr); + Float screenHeightIn = (Float)XHeightMMOfScreen(xWindow->screenptr) / 25.4f; + vout->dpi_x = (u32)(screenWidth / screenWidthIn); + vout->dpi_y = (u32)(screenHeight / screenHeightIn); + } + switch (xWindow->depth) { case 8: xWindow->pixel_format = GF_PIXEL_GREYSCALE; @@ -1273,6 +1161,9 @@ xWindow->screennum=0; Hints->flags |= USPosition; XSetWMNormalHints (xWindow->display, xWindow->full_wnd, Hints); + autorepeat = 1; + XkbSetDetectableAutoRepeat(xWindow->display, autorepeat, &supported); + xWindow->the_gc = XCreateGC (xWindow->display, xWindow->wnd, 0, NULL); xWindow->use_shared_memory = 0; @@ -1429,9 +1320,6 @@ GF_Err X11_Setup(struct _video_out *vout, void *os_handle, void *os_display, u32 /*OSMOZILLA HACK*/ if (os_display) xWindow->no_select_input = 1; -#ifdef ENABLE_JOYSTICK - xWindow->fd = open ("/dev/input/js0", O_NONBLOCK); -#endif /*the rest is done THROUGH THE MAIN RENDERER TRHEAD!!*/ return GF_OK; } @@ -1440,6 +1328,7 @@ GF_Err X11_Setup(struct _video_out *vout, void *os_handle, void *os_display, u32 void X11_Shutdown (struct _video_out *vout) { X11VID (); + int err=0; if (xWindow->output_3d_mode==1) { #ifdef GPAC_HAS_OPENGL @@ -1448,9 +1337,6 @@ void X11_Shutdown (struct _video_out *vout) } else { X11_ReleaseBackBuffer (vout); } -#ifdef ENABLE_JOYSTICK - close(xWindow->fd); -#endif XFreeGC (xWindow->display, xWindow->the_gc); XUnmapWindow (xWindow->display, (Window) xWindow->wnd); XDestroyWindow (xWindow->display, (Window) xWindow->wnd); @@ -1466,7 +1352,7 @@ void X11_Shutdown (struct _video_out *vout) X11_XScreenSaverState(xWindow, 1); XCloseDisplay (xWindow->display); - free (xWindow); + gf_free(xWindow); } @@ -1480,7 +1366,7 @@ void *NewX11VideoOutput () if (!driv) return NULL; GF_SAFEALLOC(xWindow, XWindow); if (!xWindow) { - free(driv); + gf_free(driv); return NULL; } GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "X11 Video Output", "gpac distribution") @@ -1504,18 +1390,19 @@ void *NewX11VideoOutput () void DeleteX11VideoOutput (GF_VideoOutput * vout) { - free (vout); + gf_free(vout); } /* * interface query */ -Bool -QueryInterface (u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) - return 1; - return 0; + static u32 si [] = { + GF_VIDEO_OUTPUT_INTERFACE, + 0 + }; + return si; } diff --git a/modules/x11_out/x11_out.h b/modules/x11_out/x11_out.h index 5bd605a..5ad4cba 100644 --- a/modules/x11_out/x11_out.h +++ b/modules/x11_out/x11_out.h @@ -58,14 +58,14 @@ extern "C" #include <X11/extensions/Xvlib.h> #endif -#ifdef ENABLE_JOYSTICK +#if defined(ENABLE_JOYSTICK) || defined(ENABLE_JOYSTICK_NO_CURSOR) #include <linux/joystick.h> #include <unistd.h> #include <fcntl.h> #endif #define X11VID() XWindow *xWindow = (XWindow *)vout->opaque; - + #define RGB555(r,g,b) (((r&248)<<7) + ((g&248)<<2) + (b>>3)) #define RGB565(r,g,b) (((r&248)<<8) + ((g&252)<<3) + (b>>3)) @@ -117,10 +117,9 @@ typedef struct Window gl_wnd; u32 offscreen_type; #endif -#ifdef ENABLE_JOYSTICK +#if defined(ENABLE_JOYSTICK) || defined(ENABLE_JOYSTICK_NO_CURSOR) /*joystick device file descriptor*/ - u32 fd; - s32 prev_x, prev_y; + s32 prev_x, prev_y, fd; #endif } XWindow; diff --git a/modules/xvid_dec/Makefile b/modules/xvid_dec/Makefile index dae8564..01cedf2 100644 --- a/modules/xvid_dec/Makefile +++ b/modules/xvid_dec/Makefile @@ -20,7 +20,7 @@ OBJS=xvid_dec.o #local xvid lib ifeq ($(CONFIG_XVID), local) CFLAGS+= -I$(LOCAL_INC_PATH)/xvid -EXTRALIBS+= -L../../extra_lib/lib/gcc +LDFLAGS+= -L../../extra_lib/lib/gcc endif EXTRALIBS+= -lxvidcore @@ -28,20 +28,23 @@ SRCS := $(OBJS:.o=.c) LIB=gm_xvid_dec.$(DYN_LIB_SUFFIX) ifeq ($(CONFIG_WIN32),yes) -LDFLAGS+=-export-symbols xvid_dec.def +#LDFLAGS+=-export-symbols xvid_dec.def endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) + +ifneq ($(prefix), /usr/local) +EXTRALIBS+=-L$(prefix)/lib else -OBJSPIC=$(OBJS) +ifneq ($(prefix), /usr) +EXTRALIBS+=-L$(prefix)/lib +endif endif all: $(LIB) -$(LIB): $(OBJSPIC) - $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJSPIC) -L../../bin/gcc -lgpac $(EXTRALIBS) +$(LIB): $(OBJS) + $(CC) $(SHFLAGS) $(LDFLAGS) -o ../../bin/gcc/$@ $(OBJS) -L../../bin/gcc -lgpac $(EXTRALIBS) %.o: %.c diff --git a/modules/xvid_dec/xvid_dec.c b/modules/xvid_dec/xvid_dec.c index 43278d3..14f9587 100644 --- a/modules/xvid_dec/xvid_dec.c +++ b/modules/xvid_dec/xvid_dec.c @@ -27,6 +27,9 @@ #include <gpac/avparse.h> #include <gpac/constants.h> +/*if we don't have M4V (A)SP parser, we con't get width and height and xvid is then unusable ...*/ +#ifndef GPAC_DISABLE_AV_PARSERS + #include "xvid.h" #ifndef XVID_DEC_FRAME @@ -141,7 +144,7 @@ static GF_Err XVID_AttachStream(GF_BaseDecoder *ifcg, GF_ESD *esd) /*output in YV12 only - let the player handle conversion*/ if (ctx->depth_codec) { ctx->out_size = ctx->width * ctx->height * 5 / 2; - ctx->temp_uv = malloc(sizeof(char)*ctx->width * ctx->height / 2); + ctx->temp_uv = gf_malloc(sizeof(char)*ctx->width * ctx->height / 2); } else { ctx->yuv_size = ctx->out_size = ctx->width * ctx->height * 3 / 2; } @@ -160,7 +163,7 @@ static GF_Err XVID_DetachStream(GF_BaseDecoder *ifcg, u16 ES_ID) if (ctx->depth_codec) xvid_decore(ctx->depth_codec, XVID_DEC_DESTROY, NULL, NULL); ctx->depth_codec = NULL; ctx->depth_ES_ID = 0; - if (ctx->temp_uv) free(ctx->temp_uv); + if (ctx->temp_uv) gf_free(ctx->temp_uv); ctx->temp_uv = NULL; } return GF_OK; @@ -192,7 +195,7 @@ static GF_Err XVID_GetCapabilities(GF_BaseDecoder *ifcg, GF_CodecCapability *cap capability->cap.valueInt = ctx->out_size; break; case GF_CODEC_PIXEL_FORMAT: - capability->cap.valueInt = ctx->depth_codec ? GF_PIXEL_YUVA : GF_PIXEL_YV12; + capability->cap.valueInt = ctx->depth_codec ? GF_PIXEL_YUVD : GF_PIXEL_YV12; break; case GF_CODEC_BUFFER_MIN: capability->cap.valueInt = 1; @@ -367,7 +370,7 @@ static Bool XVID_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, u32 Object { if (StreamType != GF_STREAM_VISUAL) return 0; switch (ObjectType) { - case 0x20: + case GPAC_OTI_VIDEO_MPEG4_PART2: return 1; /*cap query*/ case 0: @@ -456,28 +459,38 @@ void DeleteXVIDDec(GF_BaseDecoder *ifcg) XVIDCTX(); if (ctx->base_codec) xvid_decore(ctx->base_codec, XVID_DEC_DESTROY, NULL, NULL); if (ctx->depth_codec) xvid_decore(ctx->depth_codec, XVID_DEC_DESTROY, NULL, NULL); - free(ctx); - free(ifcg); + gf_free(ctx); + gf_free(ifcg); } +#endif /*GPAC_DISABLE_AV_PARSERS*/ -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1; - return 0; + static u32 si [] = { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_MEDIA_DECODER_INTERFACE, +#endif + 0 + }; + return si; } GF_BaseInterface *LoadInterface(u32 InterfaceType) { +#ifndef GPAC_DISABLE_AV_PARSERS if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return (GF_BaseInterface *)NewXVIDDec(); +#endif return NULL; } void ShutdownInterface(GF_BaseInterface *ifce) { switch (ifce->InterfaceType) { +#ifndef GPAC_DISABLE_AV_PARSERS case GF_MEDIA_DECODER_INTERFACE: DeleteXVIDDec((GF_BaseDecoder*)ifce); break; +#endif } } diff --git a/modules/xvid_dec/xvid_dec.def b/modules/xvid_dec/xvid_dec.def deleted file mode 100644 index 951d50e..0000000 --- a/modules/xvid_dec/xvid_dec.def +++ /dev/null @@ -1,6 +0,0 @@ -LIBRARY gm_xvid_dec.dll - -EXPORTS - QueryInterface - LoadInterface - ShutdownInterface diff --git a/modules/xvid_dec/xvid_dec_wce.cpp b/modules/xvid_dec/xvid_dec_wce.cpp index f6baab0..c92b16b 100644 --- a/modules/xvid_dec/xvid_dec_wce.cpp +++ b/modules/xvid_dec/xvid_dec_wce.cpp @@ -220,7 +220,7 @@ static Bool XVID_CanHandleStream(GF_BaseDecoder *dec, u32 StreamType, u32 Object { if (StreamType != GF_STREAM_VISUAL) return 0; switch (ObjectType) { - case 0x20: + case GPAC_OTI_VIDEO_MPEG4_PART2: return 1; /*cap query*/ case 0: @@ -236,10 +236,10 @@ GF_BaseDecoder *NewXVIDDec() GF_MediaDecoder *ifcd; XVIDDec *dec; - ifcd = (GF_MediaDecoder*) malloc(sizeof(GF_MediaDecoder)); + ifcd = (GF_MediaDecoder*) gf_malloc(sizeof(GF_MediaDecoder)); memset(ifcd, 0, sizeof(GF_MediaDecoder)); - dec = (XVIDDec*) malloc(sizeof(XVIDDec)); + dec = (XVIDDec*) gf_malloc(sizeof(XVIDDec)); memset(dec, 0, sizeof(XVIDDec)); dec->cb_size = 4; @@ -261,8 +261,8 @@ void DeleteXVIDDec(GF_BaseDecoder *ifcg) { XVIDCTX(); if (ctx->codec) CloseCodec(ctx->codec); - free(ctx); - free(ifcg); + gf_free(ctx); + gf_free(ifcg); } @@ -271,10 +271,15 @@ extern "C" { #endif GF_EXPORT -Bool QueryInterface(u32 InterfaceType) +const u32 *QueryInterfaces() { - if (InterfaceType == GF_MEDIA_DECODER_INTERFACE) return 1; - return 0; + static u32 si [] = { +#ifndef GPAC_DISABLE_AV_PARSERS + GF_MEDIA_DECODER_INTERFACE, +#endif + 0 + }; + return si; } GF_EXPORT diff --git a/modules/xvid_dec/xvid_wce/AUTHORS b/modules/xvid_dec/xvid_wce/AUTHORS index 71b9500..36902a8 100644 --- a/modules/xvid_dec/xvid_wce/AUTHORS +++ b/modules/xvid_dec/xvid_wce/AUTHORS @@ -33,4 +33,4 @@ Dirk Knop <dknop@stud.uni-goettingen.de> Guillaume Morin <guillaume@morinfr.org> MinChen <chenm001@163.com> -Last edited: $Date: 2005/07/13 14:36:12 $ +Last edited: $Date: 2005-07-13 14:36:12 $ diff --git a/modules/xvid_dec/xvid_wce/TODO b/modules/xvid_dec/xvid_wce/TODO index a954d9e..f194d8d 100644 --- a/modules/xvid_dec/xvid_wce/TODO +++ b/modules/xvid_dec/xvid_wce/TODO @@ -49,4 +49,4 @@ Already completed items: * YV12/I420/USER clarification (christoph) * vfw and dshow link dynamically to xvidcore.dll (syskin) -Last edited: $Date: 2005/07/13 14:36:16 $ +Last edited: $Date: 2005-07-13 14:36:16 $ diff --git a/modules/xvid_dec/xvid_wce/bitstream.cpp b/modules/xvid_dec/xvid_wce/bitstream.cpp index 20d7be0..7125167 100644 --- a/modules/xvid_dec/xvid_wce/bitstream.cpp +++ b/modules/xvid_dec/xvid_wce/bitstream.cpp @@ -20,7 +20,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: bitstream.cpp,v 1.1.1.1 2005/07/13 14:36:12 jeanlf Exp $ + * $Id: bitstream.cpp,v 1.1.1.1 2005-07-13 14:36:12 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/bitstream.h b/modules/xvid_dec/xvid_wce/bitstream.h index db27fbe..f774e0d 100644 --- a/modules/xvid_dec/xvid_wce/bitstream.h +++ b/modules/xvid_dec/xvid_wce/bitstream.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: bitstream.h,v 1.1.1.1 2005/07/13 14:36:12 jeanlf Exp $ + * $Id: bitstream.h,v 1.1.1.1 2005-07-13 14:36:12 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/decoder.cpp b/modules/xvid_dec/xvid_wce/decoder.cpp index ae16b4d..e3d9713 100644 --- a/modules/xvid_dec/xvid_wce/decoder.cpp +++ b/modules/xvid_dec/xvid_wce/decoder.cpp @@ -20,7 +20,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: decoder.cpp,v 1.4 2008/08/20 13:57:54 jeanlf Exp $ + * $Id: decoder.cpp,v 1.4 2008-08-20 13:57:54 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/decoder.h b/modules/xvid_dec/xvid_wce/decoder.h index a52bb17..aee49e0 100644 --- a/modules/xvid_dec/xvid_wce/decoder.h +++ b/modules/xvid_dec/xvid_wce/decoder.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: decoder.h,v 1.1.1.1 2005/07/13 14:36:13 jeanlf Exp $ + * $Id: decoder.h,v 1.1.1.1 2005-07-13 14:36:13 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/font.cpp b/modules/xvid_dec/xvid_wce/font.cpp index 4c6e03d..d8efc69 100644 --- a/modules/xvid_dec/xvid_wce/font.cpp +++ b/modules/xvid_dec/xvid_wce/font.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: font.cpp,v 1.1.1.1 2005/07/13 14:36:13 jeanlf Exp $ + * $Id: font.cpp,v 1.1.1.1 2005-07-13 14:36:13 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/global.h b/modules/xvid_dec/xvid_wce/global.h index d801a0d..6f954fc 100644 --- a/modules/xvid_dec/xvid_wce/global.h +++ b/modules/xvid_dec/xvid_wce/global.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: global.h,v 1.1.1.1 2005/07/13 14:36:14 jeanlf Exp $ + * $Id: global.h,v 1.1.1.1 2005-07-13 14:36:14 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/gmc.cpp b/modules/xvid_dec/xvid_wce/gmc.cpp index 935a0d8..7a81329 100644 --- a/modules/xvid_dec/xvid_wce/gmc.cpp +++ b/modules/xvid_dec/xvid_wce/gmc.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: gmc.cpp,v 1.1.1.1 2005/07/13 14:36:14 jeanlf Exp $ + * $Id: gmc.cpp,v 1.1.1.1 2005-07-13 14:36:14 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/gmc.h b/modules/xvid_dec/xvid_wce/gmc.h index a729ef0..0cd5fe4 100644 --- a/modules/xvid_dec/xvid_wce/gmc.h +++ b/modules/xvid_dec/xvid_wce/gmc.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: gmc.h,v 1.1.1.1 2005/07/13 14:36:14 jeanlf Exp $ + * $Id: gmc.h,v 1.1.1.1 2005-07-13 14:36:14 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/idct.cpp b/modules/xvid_dec/xvid_wce/idct.cpp index fa11bf7..98edddc 100644 --- a/modules/xvid_dec/xvid_wce/idct.cpp +++ b/modules/xvid_dec/xvid_wce/idct.cpp @@ -20,7 +20,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: idct.cpp,v 1.2 2006/12/13 15:12:27 jeanlf Exp $ + * $Id: idct.cpp,v 1.2 2006-12-13 15:12:27 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/image.cpp b/modules/xvid_dec/xvid_wce/image.cpp index 0ad1c93..cabab5b 100644 --- a/modules/xvid_dec/xvid_wce/image.cpp +++ b/modules/xvid_dec/xvid_wce/image.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: image.cpp,v 1.1.1.1 2005/07/13 14:36:14 jeanlf Exp $ + * $Id: image.cpp,v 1.1.1.1 2005-07-13 14:36:14 jeanlf Exp $ * ****************************************************************************/ //#include <math.h> diff --git a/modules/xvid_dec/xvid_wce/image.h b/modules/xvid_dec/xvid_wce/image.h index 9ff217e..7224724 100644 --- a/modules/xvid_dec/xvid_wce/image.h +++ b/modules/xvid_dec/xvid_wce/image.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: image.h,v 1.1.1.1 2005/07/13 14:36:14 jeanlf Exp $ + * $Id: image.h,v 1.1.1.1 2005-07-13 14:36:14 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/interpolate8x8.cpp b/modules/xvid_dec/xvid_wce/interpolate8x8.cpp index ea32053..93c8140 100644 --- a/modules/xvid_dec/xvid_wce/interpolate8x8.cpp +++ b/modules/xvid_dec/xvid_wce/interpolate8x8.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: interpolate8x8.cpp,v 1.1.1.1 2005/07/13 14:36:15 jeanlf Exp $ + * $Id: interpolate8x8.cpp,v 1.1.1.1 2005-07-13 14:36:15 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/interpolate8x8.h b/modules/xvid_dec/xvid_wce/interpolate8x8.h index 5e735ee..54a3d3e 100644 --- a/modules/xvid_dec/xvid_wce/interpolate8x8.h +++ b/modules/xvid_dec/xvid_wce/interpolate8x8.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: interpolate8x8.h,v 1.1.1.1 2005/07/13 14:36:15 jeanlf Exp $ + * $Id: interpolate8x8.h,v 1.1.1.1 2005-07-13 14:36:15 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/mbcoding.cpp b/modules/xvid_dec/xvid_wce/mbcoding.cpp index 7d3b9f5..31b4e28 100644 --- a/modules/xvid_dec/xvid_wce/mbcoding.cpp +++ b/modules/xvid_dec/xvid_wce/mbcoding.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: mbcoding.cpp,v 1.1.1.1 2005/07/13 14:36:15 jeanlf Exp $ + * $Id: mbcoding.cpp,v 1.1.1.1 2005-07-13 14:36:15 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/mbprediction.cpp b/modules/xvid_dec/xvid_wce/mbprediction.cpp index ecea2ef..c816b6a 100644 --- a/modules/xvid_dec/xvid_wce/mbprediction.cpp +++ b/modules/xvid_dec/xvid_wce/mbprediction.cpp @@ -20,7 +20,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: mbprediction.cpp,v 1.1.1.1 2005/07/13 14:36:15 jeanlf Exp $ + * $Id: mbprediction.cpp,v 1.1.1.1 2005-07-13 14:36:15 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/mbprediction.h b/modules/xvid_dec/xvid_wce/mbprediction.h index 9528589..89348b9 100644 --- a/modules/xvid_dec/xvid_wce/mbprediction.h +++ b/modules/xvid_dec/xvid_wce/mbprediction.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: mbprediction.h,v 1.1.1.1 2005/07/13 14:36:15 jeanlf Exp $ + * $Id: mbprediction.h,v 1.1.1.1 2005-07-13 14:36:15 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/mem_align.cpp b/modules/xvid_dec/xvid_wce/mem_align.cpp index 9894d7b..c865859 100644 --- a/modules/xvid_dec/xvid_wce/mem_align.cpp +++ b/modules/xvid_dec/xvid_wce/mem_align.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: mem_align.cpp,v 1.2 2008/08/20 13:57:54 jeanlf Exp $ + * $Id: mem_align.cpp,v 1.3 2010-02-23 16:23:32 jeanlf Exp $ * ****************************************************************************/ @@ -57,7 +57,7 @@ void *xvid_malloc(long size, dword alignment){ if (!alignment) { /* We have not to satisfy any alignment */ - //mem_ptr = (byte*)malloc(size + 1); + //mem_ptr = (byte*)gf_malloc(size + 1); //mem_ptr = new(ELeave) byte[size+1]; mem_ptr = new byte[size+1]; if(mem_ptr) { @@ -73,7 +73,7 @@ void *xvid_malloc(long size, dword alignment){ /* Allocate the required size memory + alignment so we * can realign the data if necessary */ - //tmp = (byte *) malloc(size + alignment); + //tmp = (byte *) gf_malloc(size + alignment); //tmp = new(ELeave) byte[size + alignment]; tmp = new byte[size + alignment]; if(tmp) { @@ -82,7 +82,7 @@ void *xvid_malloc(long size, dword alignment){ mem_ptr = (byte *) ((dword)(tmp + alignment - 1) & (~(dword)(alignment - 1))); - /* Special case where malloc have already satisfied the alignment + /* Special case where gf_malloc have already satisfied the alignment * We must add alignment to mem_ptr because we must store * (mem_ptr - tmp) in *(mem_ptr-1) * If we do not add alignment to mem_ptr then *(mem_ptr-1) points @@ -91,7 +91,7 @@ void *xvid_malloc(long size, dword alignment){ mem_ptr += alignment; /* (mem_ptr - tmp) is stored in *(mem_ptr-1) so we are able to retrieve - * the real malloc block allocated and free it in xvid_free */ + * the real gf_malloc block allocated and free it in xvid_free */ *(mem_ptr - 1) = (byte) (mem_ptr - tmp); /* Return the aligned pointer */ diff --git a/modules/xvid_dec/xvid_wce/mem_align.h b/modules/xvid_dec/xvid_wce/mem_align.h index da44425..752dc06 100644 --- a/modules/xvid_dec/xvid_wce/mem_align.h +++ b/modules/xvid_dec/xvid_wce/mem_align.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: mem_align.h,v 1.1.1.1 2005/07/13 14:36:15 jeanlf Exp $ + * $Id: mem_align.h,v 1.1.1.1 2005-07-13 14:36:15 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/mem_transfer.cpp b/modules/xvid_dec/xvid_wce/mem_transfer.cpp index 4aedeba..a5a2b67 100644 --- a/modules/xvid_dec/xvid_wce/mem_transfer.cpp +++ b/modules/xvid_dec/xvid_wce/mem_transfer.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: mem_transfer.cpp,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: mem_transfer.cpp,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/mem_transfer.h b/modules/xvid_dec/xvid_wce/mem_transfer.h index 07aa771..225d643 100644 --- a/modules/xvid_dec/xvid_wce/mem_transfer.h +++ b/modules/xvid_dec/xvid_wce/mem_transfer.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: mem_transfer.h,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: mem_transfer.h,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/portab.h b/modules/xvid_dec/xvid_wce/portab.h index a4e2d6c..48af417 100644 --- a/modules/xvid_dec/xvid_wce/portab.h +++ b/modules/xvid_dec/xvid_wce/portab.h @@ -21,7 +21,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: portab.h,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: portab.h,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/quant.h b/modules/xvid_dec/xvid_wce/quant.h index bcf8da4..629076f 100644 --- a/modules/xvid_dec/xvid_wce/quant.h +++ b/modules/xvid_dec/xvid_wce/quant.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: quant.h,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: quant.h,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/quant_h263.cpp b/modules/xvid_dec/xvid_wce/quant_h263.cpp index 167bfbb..8eb36be 100644 --- a/modules/xvid_dec/xvid_wce/quant_h263.cpp +++ b/modules/xvid_dec/xvid_wce/quant_h263.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: quant_h263.cpp,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: quant_h263.cpp,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/quant_matrix.cpp b/modules/xvid_dec/xvid_wce/quant_matrix.cpp index 7e5ba5d..e2ac83c 100644 --- a/modules/xvid_dec/xvid_wce/quant_matrix.cpp +++ b/modules/xvid_dec/xvid_wce/quant_matrix.cpp @@ -20,7 +20,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: quant_matrix.cpp,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: quant_matrix.cpp,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/quant_matrix.h b/modules/xvid_dec/xvid_wce/quant_matrix.h index 562b9ef..f0c0c11 100644 --- a/modules/xvid_dec/xvid_wce/quant_matrix.h +++ b/modules/xvid_dec/xvid_wce/quant_matrix.h @@ -20,7 +20,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: quant_matrix.h,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: quant_matrix.h,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/quant_mpeg.cpp b/modules/xvid_dec/xvid_wce/quant_mpeg.cpp index 5ce7ed6..7e0e67e 100644 --- a/modules/xvid_dec/xvid_wce/quant_mpeg.cpp +++ b/modules/xvid_dec/xvid_wce/quant_mpeg.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: quant_mpeg.cpp,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: quant_mpeg.cpp,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/reduced.cpp b/modules/xvid_dec/xvid_wce/reduced.cpp index 0c13a70..9a0bb72 100644 --- a/modules/xvid_dec/xvid_wce/reduced.cpp +++ b/modules/xvid_dec/xvid_wce/reduced.cpp @@ -50,7 +50,7 @@ * exception also makes it possible to release a modified version which * carries forward this exception. * - * $Id: reduced.cpp,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: reduced.cpp,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/reduced.h b/modules/xvid_dec/xvid_wce/reduced.h index 34a1716..9ab7177 100644 --- a/modules/xvid_dec/xvid_wce/reduced.h +++ b/modules/xvid_dec/xvid_wce/reduced.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: reduced.h,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: reduced.h,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/vlc_codes.h b/modules/xvid_dec/xvid_wce/vlc_codes.h index 9f159c5..a802063 100644 --- a/modules/xvid_dec/xvid_wce/vlc_codes.h +++ b/modules/xvid_dec/xvid_wce/vlc_codes.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: vlc_codes.h,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: vlc_codes.h,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ #ifndef _VLC_CODES_H_ diff --git a/modules/xvid_dec/xvid_wce/xvid.cpp b/modules/xvid_dec/xvid_wce/xvid.cpp index 8724fa3..924d77a 100644 --- a/modules/xvid_dec/xvid_wce/xvid.cpp +++ b/modules/xvid_dec/xvid_wce/xvid.cpp @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: xvid.cpp,v 1.1.1.1 2005/07/13 14:36:16 jeanlf Exp $ + * $Id: xvid.cpp,v 1.1.1.1 2005-07-13 14:36:16 jeanlf Exp $ * ****************************************************************************/ diff --git a/modules/xvid_dec/xvid_wce/xvid.h b/modules/xvid_dec/xvid_wce/xvid.h index 4f00a22..29eb1eb 100644 --- a/modules/xvid_dec/xvid_wce/xvid.h +++ b/modules/xvid_dec/xvid_wce/xvid.h @@ -19,7 +19,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: xvid.h,v 1.2 2006/12/13 15:12:27 jeanlf Exp $ + * $Id: xvid.h,v 1.2 2006-12-13 15:12:27 jeanlf Exp $ * ****************************************************************************/ diff --git a/regression_tests/_mozilla_ie_simple.html b/regression_tests/_mozilla_ie_simple.html index e880aa9..c49a41a 100644 --- a/regression_tests/_mozilla_ie_simple.html +++ b/regression_tests/_mozilla_ie_simple.html @@ -8,7 +8,9 @@ <body> <object id="gpac" width="300" height="200" type="application/x-gpac" > - <param name="src" value="bifs-command-animated-osmo4logo.mp4" /> + <!--param name="src" value="bifs-command-animated-osmo4logo.bt" /--> + <!--param name="src" value="D:\MediaStreams\raw_streams\mpeg\dead.mpeg" /--> + <param name="src" value="bifs-3D-shapes-box.bt" /> Your browser doesn't support GPAC ... </object> diff --git a/regression_tests/bifs-2D-background-background2D-bind.bt b/regression_tests/bifs-2D-background-background2D-bind.bt deleted file mode 100644 index 257c324..0000000 --- a/regression_tests/bifs-2D-background-background2D-bind.bt +++ /dev/null @@ -1,71 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D { - backColor $FFFFFF - } - DEF B2 Background2D { - backColor 1 0 0 - } - WorldInfo { - info [ - "This shows 2 Background2D nodes and the bind mechanism" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:37:08 $ - $Revision: 1.4 $" - "(C) 2002-2006 GPAC Team" - ] - title "Background Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - DEF TS TouchSensor {} - ] - } - DEF C2 Conditional { - buffer { - REPLACE B1.set_bind BY TRUE - } - } - DEF C1 Conditional { - buffer { - REPLACE B2.set_bind BY TRUE - } - } - ] -} - -ROUTE TS.isOver TO C1.activate -ROUTE TS.isOver TO C2.reverseActivate diff --git a/regression_tests/bifs-2D-background-background2D-image.bt b/regression_tests/bifs-2D-background-background2D-image.bt deleted file mode 100644 index f645c90..0000000 --- a/regression_tests/bifs-2D-background-background2D-image.bt +++ /dev/null @@ -1,97 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D { - url [od:10] - } - DEF B2 Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Background2D with image" "and binding mechanism" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Background Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - DEF TS TouchSensor {} - ] - } - DEF C2 Conditional { - buffer { - REPLACE B1.set_bind BY TRUE - } - } - DEF C1 Conditional { - buffer { - REPLACE B2.set_bind BY TRUE - } - } - ] -} - -ROUTE TS.isOver TO C1.activate -ROUTE TS.isOver TO C2.reverseActivate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ] -} - -AT 1000 { - REPLACE B2.set_bind BY TRUE -} - -AT 2000 { - REPLACE B1.set_bind BY TRUE -} - diff --git a/regression_tests/bifs-2D-background-background2D-layer2D.bt b/regression_tests/bifs-2D-background-background2D-layer2D.bt deleted file mode 100644 index 36f5fac..0000000 --- a/regression_tests/bifs-2D-background-background2D-layer2D.bt +++ /dev/null @@ -1,92 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Background2D within a layer2D" "Note that the background is stretched to the layer size" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] - title "Background Test" - } - Transform2D { - translation 100 0 - children [ - DEF L Layer2D { - size 400 300 - children [ - Shape { - appearance Appearance { - material Material2D { - filled TRUE - transparency 0 - } - } - geometry DEF RC Rectangle { - size 200 100 - } - } - ] - background Background2D { - url [od:10] - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF PI PositionInterpolator2D { - key [0 0.75 1] - keyValue [400 300 0 0 0 0] - } - ] -} - -ROUTE TS.fraction_changed TO PI.set_fraction -ROUTE PI.value_changed TO L.size - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-background-background2D-movie.bt b/regression_tests/bifs-2D-background-background2D-movie.bt deleted file mode 100644 index bb52476..0000000 --- a/regression_tests/bifs-2D-background-background2D-movie.bt +++ /dev/null @@ -1,94 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D { - url [od:10] - } - DEF B2 Background2D { - backColor 1 1 1 - } - MediaControl { - url [od:10] - loop TRUE - } - WorldInfo { - info ["This shows Background2D with image" "and binding mechanism" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Background Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - DEF TS TouchSensor {} - ] - } - DEF C2 Conditional { - buffer { - REPLACE B1.set_bind BY TRUE - } - } - DEF C1 Conditional { - buffer { - REPLACE B2.set_bind BY TRUE - } - } - ] -} - -ROUTE TS.isOver TO C1.activate -ROUTE TS.isOver TO C2.reverseActivate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-background-background2D-url-change.bt b/regression_tests/bifs-2D-background-background2D-url-change.bt deleted file mode 100644 index b20208c..0000000 --- a/regression_tests/bifs-2D-background-background2D-url-change.bt +++ /dev/null @@ -1,105 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D { - url [od:20] - } - WorldInfo { - info ["This shows Background2D with dynamic image change" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Background Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - DEF TS TouchSensor {} - ] - } - DEF C1 Conditional { - buffer { - REPLACE B1.url BY ["od:20"] - } - } - DEF RC1 Conditional { - buffer { - REPLACE B1.url BY ["od:10"] - } - } - ] -} - -ROUTE TS.isOver TO C1.activate -ROUTE TS.isOver TO RC1.reverseActivate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 20 - esDescr [ - ES_Descriptor { - ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - -AT 2000 { - REPLACE B1.url BY ["od:20"] -} - -AT 4000 { - REPLACE B1.url BY ["od:10"] -} - diff --git a/regression_tests/bifs-2D-interactivity-discsensor.bt b/regression_tests/bifs-2D-interactivity-discsensor.bt deleted file mode 100644 index 9a2cc57..0000000 --- a/regression_tests/bifs-2D-interactivity-discsensor.bt +++ /dev/null @@ -1,129 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the use of the disc sensor which computes the angle in the mouse motion between mouse down and mouse up." - "It also uses the auto-offset field, which allows storing reusing the angle from the previous mouse up." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "DiscSensor" - } - DEF T1 Transform2D { - scale 1 2 - scaleOrientation 0.75 - translation -150 0 - children [ - DEF S Shape { - appearance Appearance { - texture ImageTexture { - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry Rectangle { - size 100 100 - } - } - DEF DS1 DiscSensor {} - ] - } - Transform2D { - translation -150 0 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Auto-offset on"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 24 - } - } - } - ] - } - DEF T2 Transform2D { - scale 1 2 - scaleOrientation 0.75 - translation 150 0 - children [ - USE S - DEF DS2 DiscSensor { - autoOffset FALSE - } - ] - } - Transform2D { - translation 150 0 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Auto-offset off"] - fontStyle USE FS - } - } - ] - } - ] -} - -ROUTE DS1.rotation_changed TO T1.rotationAngle -ROUTE DS2.rotation_changed TO T2.rotationAngle - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-interactivity-htk-sensor.bt b/regression_tests/bifs-2D-interactivity-htk-sensor.bt deleted file mode 100644 index fa54dbd..0000000 --- a/regression_tests/bifs-2D-interactivity-htk-sensor.bt +++ /dev/null @@ -1,175 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of String Sensor" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002 ENST"] - title "InputSensor Test - StringSensor device" - } - Transform2D { - translation 0 90 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["HTKSensor"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 30 - } - } - } - ] - } - Transform2D { - translation -50 20 - children [ - Shape { - appearance USE APP - geometry Text { - string ["spoken Text"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 90 20 - children [ - Shape { - appearance USE APP - geometry DEF T2 Text { - string [""] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -50 -20 - children [ - Shape { - appearance USE APP - geometry Text { - string ["text index in dict"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 90 -20 - children [ - Shape { - appearance USE APP - geometry DEF T3 Text { - string [""] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -50 -50 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Recogn Score"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 90 -50 - children [ - Shape { - appearance USE APP - geometry DEF T4 Text { - string [""] - fontStyle USE FS - } - } - ] - } - DEF VN3 Valuator { - Factor2 0 - Factor3 0 - } - DEF VN4 Valuator { - Factor2 0 - Factor3 0 - } - InputSensor { - url [od:10] - buffer { - REPLACE T2.string[0] BY "" - REPLACE VN3.inSFInt32 BY 0 - REPLACE VN4.inSFFloat BY 0 - } - } - ] -} - -ROUTE VN3.outMFString TO T3.string -ROUTE VN4.outMFString TO T4.string - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 5 - decConfigDescr DecoderConfigDescriptor { - streamType 10 - decSpecificInfo UIConfig { - deviceName "HTKSensor" - uiData "HTK:BLEU vcl bb ll eu sp;ROUGE rr ou jj sp;VERT vv ai rr sp" - } - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-interactivity-keysensor.bt b/regression_tests/bifs-2D-interactivity-keysensor.bt deleted file mode 100644 index 9bc2e7b..0000000 --- a/regression_tests/bifs-2D-interactivity-keysensor.bt +++ /dev/null @@ -1,810 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 600 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows usage of the InputSensor node to detect keys and trigger of events" - "The InputSensor in this case has a url which points to a specific pseudo-media object. This object contains one stream, called interaction stream." - "This stream is made of Device Data Frame whose content is specialized depending on the kind of input device." - "The InputSensor node in the scene specifies how to dispatch the content of the DDF." - "For each piece of information in the DDF, a REPLACE command is associated." - "The value of the target property is replaced by the associated content from the DDF." - "" - "If the configuration of the stream says 'KeySensor', like here, the input device is a keyboard and the DDF content is as follows:" - "- the key code for the pressed key (0 if none)," - "- the key code for the released key (0 if none)," - "- the key code for the action key (F1, ...) pressed (0 if none)," - "- the key code for the action key (F1, ...) released (0 for none)," - "- and the state of the modifier keys (CTRL, ALT and Shift)." - "In this example, the target nodes are Valuator nodes which cast the key code into the char representation, and the result is displayed." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "InputSensor Node for detecting keys (KeySensor)" - } - DEF N33 Switch { - choice [ - Group { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 1 - filled TRUE - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - ] - } - Group { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 0.5 1 - filled TRUE - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - ] - } - Group { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 1 1 - filled TRUE - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - ] - } - Group { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 1 - filled TRUE - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - ] - } - Group { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - ] - } - Group { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - ] - } - Group { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - ] - } - Group { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - ] - } - ] - } - DEF N10 Conditional { - buffer { - REPLACE N33.whichChoice BY 0 - } - } - Group { - children [ - DEF N12 TouchSensor {} - Transform2D { - translation -195 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 1 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - Shape { - appearance DEF N29 Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["F1"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - DEF N20 Conditional { - buffer { - REPLACE N33.whichChoice BY 1 - } - } - Group { - children [ - DEF N19 TouchSensor {} - Transform2D { - translation -195 0 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 0.5 1 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - Shape { - appearance USE N29 - geometry Text { - string ["F2"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - DEF N23 Conditional { - buffer { - REPLACE N33.whichChoice BY 2 - } - } - Group { - children [ - DEF N9 TouchSensor {} - Transform2D { - translation -195 120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 1 1 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - Shape { - appearance USE N29 - geometry Text { - string ["F3"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - DEF N14 Conditional { - buffer { - REPLACE N33.whichChoice BY 3 - } - } - Group { - children [ - DEF N31 TouchSensor {} - Transform2D { - translation -195 240 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 1 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - Shape { - appearance USE N29 - geometry Text { - string ["F4"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - DEF N15 Conditional { - buffer { - REPLACE N33.whichChoice BY 4 - } - } - Group { - children [ - DEF N25 TouchSensor {} - Transform2D { - translation 195 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - Shape { - appearance USE N29 - geometry Text { - string ["F5"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - DEF N16 Conditional { - buffer { - REPLACE N33.whichChoice BY 5 - } - } - Group { - children [ - DEF N11 TouchSensor {} - Transform2D { - translation 195 0 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - Shape { - appearance USE N29 - geometry Text { - string ["F6"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - DEF N17 Conditional { - buffer { - REPLACE N33.whichChoice BY 6 - } - } - Group { - children [ - DEF N18 TouchSensor {} - Transform2D { - translation 195 120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - Shape { - appearance USE N29 - geometry Text { - string ["F7"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - DEF N27 Conditional { - buffer { - REPLACE N33.whichChoice BY 7 - } - } - Group { - children [ - DEF N13 TouchSensor {} - Transform2D { - translation 195 240 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - Shape { - appearance USE N29 - geometry Text { - string ["F8"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - Transform2D { - translation 0 -120 - children [ - Shape { - appearance USE N29 - geometry Text { - string ["KeySensor"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 30 - } - } - } - ] - } - Transform2D { - translation -50 -150 - children [ - Shape { - appearance USE N29 - geometry Text { - string ["KeyPress"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 90 -150 - children [ - Shape { - appearance USE N29 - geometry DEF N32 Text { - string ["0"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -50 -170 - children [ - Shape { - appearance USE N29 - geometry Text { - string ["KeyRelease"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 90 -170 - children [ - Shape { - appearance USE N29 - geometry DEF N30 Text { - string ["0"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -50 -190 - children [ - Shape { - appearance USE N29 - geometry Text { - string ["ActionKeyPress"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 90 -190 - children [ - Shape { - appearance USE N29 - geometry DEF N28 Text { - string ["0"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -50 -210 - children [ - Shape { - appearance USE N29 - geometry Text { - string ["ActionKeyRelease"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 90 -210 - children [ - Shape { - appearance USE N29 - geometry DEF N26 Text { - string ["0"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -50 -230 - children [ - Shape { - appearance USE N29 - geometry Text { - string ["shiftKey_changed"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 90 -230 - children [ - Shape { - appearance USE N29 - geometry DEF N24 Text { - string ["0"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -50 -250 - children [ - Shape { - appearance USE N29 - geometry Text { - string ["controlKey_changed"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 90 -250 - children [ - Shape { - appearance USE N29 - geometry DEF N22 Text { - string ["0"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -50 -270 - children [ - Shape { - appearance USE N29 - geometry Text { - string ["altKey_changed"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 90 -270 - children [ - Shape { - appearance USE N29 - geometry DEF N21 Text { - string ["0"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - DEF N3 Valuator {} - DEF N7 Valuator { - Offset1 -1 - } - DEF N6 Valuator {} - DEF N5 Valuator {} - DEF N4 Valuator {} - DEF N2 Valuator {} - DEF N1 Valuator {} - DEF N0 Valuator {} - InputSensor { - url [od:10] - buffer { - REPLACE N6.inSFInt32 BY 0 - REPLACE N5.inSFInt32 BY 0 - REPLACE N3.inSFInt32 BY 0 - REPLACE N4.inSFInt32 BY 0 - REPLACE N2.inSFBool BY TRUE - REPLACE N1.inSFBool BY TRUE - REPLACE N0.inSFBool BY TRUE - } - } - Group { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - ] - } - ] -} - -ROUTE N6.outMFString TO N32.string -ROUTE N5.outMFString TO N30.string -ROUTE N4.outMFString TO N26.string -ROUTE N2.outMFString TO N24.string -ROUTE N1.outMFString TO N22.string -ROUTE N0.outMFString TO N21.string -ROUTE N3.outSFInt32 TO N7.inSFInt32 -ROUTE N3.outMFString TO N28.string -ROUTE N7.outSFInt32 TO N33.whichChoice -ROUTE N12.isActive TO N10.activate -ROUTE N19.isActive TO N20.activate -ROUTE N9.isActive TO N23.activate -ROUTE N31.isActive TO N14.activate -ROUTE N25.isActive TO N15.activate -ROUTE N11.isActive TO N16.activate -ROUTE N18.isActive TO N17.activate -ROUTE N13.isActive TO N27.activate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 5 - decConfigDescr DecoderConfigDescriptor { - streamType 10 - decSpecificInfo UIConfig { - deviceName "KeySensor" - } - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-interactivity-mousesensor.bt b/regression_tests/bifs-2D-interactivity-mousesensor.bt deleted file mode 100644 index bad6754..0000000 --- a/regression_tests/bifs-2D-interactivity-mousesensor.bt +++ /dev/null @@ -1,182 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 600 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows usage of the InputSensor node to detect keys and trigger of events" - "The InputSensor in this case has a url which points to a specific pseudo-media object. This object contains one stream, called interaction stream." - "This stream is made of Device Data Frame whose content is specialized depending on the kind of input device." - "The InputSensor node in the scene specifies how to dispatch the content of the DDF." - "For each piece of information in the DDF, a REPLACE command is associated." - "The value of the target property is replaced by the associated content from the DDF." - "" - "If the configuration of the stream says 'MouseSensor', like here, the input device is a mouse and the DDF content is as follows:" - "- the mouse position," - "- the status of the left button," - "- the status of the middle button," - "- the status of the right button," - "- and the status of the wheel." - "This configuration allows doing different things than the TouchSensor because the TouchSensor cannot give information about the buttons, or the wheel. On the other hand, it can be triggered based on sibling geometry, which is not the case of the InputSensor node in MouseSensor mode." - "In this example, the result of the InputSensor node triggers ECMAScript actions." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "InputSensor Node for mouse events (MouseSensor)" - } - Transform2D { - translation -120 -100 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT1 Text { - string ["Left Down" ""] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 0 -100 - children [ - Shape { - appearance USE APP - geometry DEF TXT2 Text { - string ["Middle Down" ""] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 120 -100 - children [ - Shape { - appearance USE APP - geometry DEF TXT3 Text { - string ["Right Down" ""] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance USE APP - geometry DEF TXT4 Text { - string [""] - fontStyle USE FS - } - } - ] - } - DEF SC Script { - eventIn SFBool set_left - eventIn SFBool set_middle - eventIn SFBool set_right - eventIn SFFloat set_wheel - field SFFloat wheel_pos 0 - field SFNode t1 USE TXT1 - field SFNode t2 USE TXT2 - field SFNode t3 USE TXT3 - field SFNode t4 USE TXT4 - url ["javascript:function set_left(value, timestamp) {t1.string[1] = '' + value;}function set_middle(value, timestamp) {t2.string[1] = '' + value;}function set_right(value, timestamp) {t3.string[1] = '' + value;}function set_wheel(value, timestamp) {wheel_pos += value;t4.string[0] = 'Wheel Pos ' + wheel_pos;}" ] - } - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - texture ImageTexture { - url [od:2] - } - } - geometry Bitmap {} - - } - ] - } - InputSensor { - url [od:10] - buffer { - REPLACE TR.translation BY 0 0 - REPLACE SC.set_left BY FALSE - REPLACE SC.set_middle BY FALSE - REPLACE SC.set_right BY FALSE - REPLACE SC.set_wheel BY 0 - } - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 2 - esDescr [ - ES_Descriptor { - ES_ID 3 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 5 - decConfigDescr DecoderConfigDescriptor { - streamType 10 - decSpecificInfo UIConfig { - deviceName "Mouse" - } - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-interactivity-nested-sensors.bt b/regression_tests/bifs-2D-interactivity-nested-sensors.bt deleted file mode 100644 index fec681e..0000000 --- a/regression_tests/bifs-2D-interactivity-nested-sensors.bt +++ /dev/null @@ -1,123 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows a mixed usage of TouchSensor and PlaneSensor2D nodes on a single shape." - "In some circumstances, the object can be dragged and in some other, it can be clicked." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Nested Sensors" - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["PlaneSensor2D and TouchSensor:" "Drag the shape on the blue part" "and click on the center"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - ] - } - DEF T1 Transform2D { - children [ - DEF TS TouchSensor {} - DEF PS PlaneSensor2D { - maxPosition 200 200 - minPosition -200 -200 - } - Shape { - appearance DEF A1 Appearance { - material DEF M1 Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Circle { - radius 60 - } - } - Transform2D { - children [ - Shape { - appearance Appearance { - material DEF M2 Material2D { - emissiveColor 1 0 1 - filled TRUE - } - } - geometry Circle { - radius 40 - } - } - DEF TS2 TouchSensor {} - ] - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE M1.filled BY FALSE - } - } - DEF C2 Conditional { - buffer { - REPLACE M1.filled BY TRUE - } - } - DEF C3 Conditional { - buffer { - REPLACE M2.emissiveColor BY 0 1 0 - } - } - DEF C4 Conditional { - buffer { - REPLACE M2.emissiveColor BY 1 0 1 - } - } - ] -} - -ROUTE TS.isOver TO C1.activate -ROUTE TS.isOver TO C2.reverseActivate -ROUTE TS2.isActive TO C3.activate -ROUTE TS2.isActive TO C4.reverseActivate -ROUTE PS.translation_changed TO T1.translation - diff --git a/regression_tests/bifs-2D-interactivity-planesensor2D.bt b/regression_tests/bifs-2D-interactivity-planesensor2D.bt deleted file mode 100644 index f1fa0f9..0000000 --- a/regression_tests/bifs-2D-interactivity-planesensor2D.bt +++ /dev/null @@ -1,124 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the use of the PlaneSensor2D node, and its auto-offset property." - "The PlaneSensor2D is used to detect mouse motion between mouse down and mouse up." - "This allows to move objects between mouse down and mouse up." - "The auto-offset is used to automatically store the mouse position at mouse release and use it as the offset to the next translation." - "This tests shows two images (clipped by circles) which can be dragged." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team"] - title "PlaneSensor2D for dragging objects" - } - DEF T1 Transform2D { - translation -150 0 - children [ - DEF S Shape { - appearance Appearance { - texture ImageTexture { - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry Circle { - radius 100 - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Auto-offset on"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 24 - } - } - } - DEF PS1 PlaneSensor2D { - maxPosition 200 200 - minPosition -200 -200 - offset -150 0 - } - ] - } - DEF T2 Transform2D { - translation 150 0 - children [ - USE S - Shape { - appearance USE APP - geometry Text { - string ["Auto-offset off"] - fontStyle USE FS - } - } - DEF PS2 PlaneSensor2D { - autoOffset FALSE - maxPosition 200 200 - minPosition -200 -200 - offset 150 0 - } - ] - } - ] -} - -ROUTE PS1.translation_changed TO T1.translation -ROUTE PS2.translation_changed TO T2.translation - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-interactivity-proximitysensor2D.bt b/regression_tests/bifs-2D-interactivity-proximitysensor2D.bt deleted file mode 100644 index d4d77c9..0000000 --- a/regression_tests/bifs-2D-interactivity-proximitysensor2D.bt +++ /dev/null @@ -1,89 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the usage of the ProximitySensor2D node" - "Two ProximitySensor2D nodes are placed on a single shape. The Shape is a 300x300 rectangle, and the ProximitySensor2D nodes define two areas centered on the rectangle: a 50x50 rectangle and a 200x200 rectangle." - "When the mouse enters or exits an area, an action is triggered." - "Here, nothing happens when the mouse enters the object, then it turns red if the mouse enters the first area, and it turns empty if the mouse enters the second area." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "ProximitySensor2D" - } - DEF T1 Transform2D { - children [ - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 0.5 0.6 0.4 - filled TRUE - } - } - geometry Rectangle { - size 300 300 - } - } - DEF PSOUT ProximitySensor2D { - size 200 200 - } - DEF PSIN ProximitySensor2D { - size 50 50 - } - ] - } - DEF CIN Conditional { - buffer { - REPLACE M1.filled BY FALSE - } - } - DEF RCIN Conditional { - buffer { - REPLACE M1.filled BY TRUE - } - } - DEF COUT Conditional { - buffer { - REPLACE M1.emissiveColor BY 1 0 0 - } - } - DEF RCOUT Conditional { - buffer { - REPLACE M1.emissiveColor BY 0.5 0.6 0.4 - } - } - ] -} - -ROUTE PSOUT.isActive TO COUT.activate -ROUTE PSOUT.isActive TO RCOUT.reverseActivate -ROUTE PSIN.isActive TO CIN.activate -ROUTE PSIN.isActive TO RCIN.reverseActivate - diff --git a/regression_tests/bifs-2D-interactivity-stringsensor.bt b/regression_tests/bifs-2D-interactivity-stringsensor.bt deleted file mode 100644 index 58afaed..0000000 --- a/regression_tests/bifs-2D-interactivity-stringsensor.bt +++ /dev/null @@ -1,153 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows usage of the InputSensor node to detect keys and trigger of events" - "The InputSensor in this case has a url which points to a specific pseudo-media object. This object contains one stream, called interaction stream." - "This stream is made of Device Data Frame whose content is specialized depending on the kind of input device." - "The InputSensor node in the scene specifies how to dispatch the content of the DDF." - "For each piece of information in the DDF, a REPLACE command is associated." - "The value of the target property is replaced by the associated content from the DDF." - "" - "If the configuration of the stream says 'StringSensor', like here, the input device is a keyboard and the DDF content is as follows:" - "- the string being edited/input," - "and the previous string after final editing (return key)" - "In this example, the target nodes are Text nodes which display the string being edited and the final one." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "InputSensor Node for detecting string input (StringSensor)" - } - Transform2D { - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["StringSensor"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 30 - } - } - } - ] - } - Transform2D { - translation -50 -30 - children [ - Shape { - appearance USE APP - geometry Text { - string ["enteredText"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 90 -30 - children [ - Shape { - appearance USE APP - geometry DEF N3 Text { - string [""] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -50 -50 - children [ - Shape { - appearance USE APP - geometry Text { - string ["finalText"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 90 -50 - children [ - Shape { - appearance USE APP - geometry DEF N2 Text { - string [""] - fontStyle USE FS - } - } - ] - } - InputSensor { - url [od:10] - buffer { - REPLACE N3.string[0] BY "" - REPLACE N2.string[0] BY "" - } - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 5 - decConfigDescr DecoderConfigDescriptor { - streamType 10 - decSpecificInfo UIConfig { - deviceName "StringSensor" - } - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-interactivity-touchsensor-4states.bt b/regression_tests/bifs-2D-interactivity-touchsensor-4states.bt deleted file mode 100644 index 9c79d84..0000000 --- a/regression_tests/bifs-2D-interactivity-touchsensor-4states.bt +++ /dev/null @@ -1,103 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 140 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This shows how to make a 4 states button" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" - "(C) 2002-2006 GPAC Team" - ] - title "4 States Button" - } - Transform2D { - scale 0.5 0.5 - children [ - Transform2D { - translation 0 60 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - DEF TS1 TouchSensor {} - ] - } - Transform2D { - translation -100 -50 - children [ - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Circle { - radius 50 - } - } - ] - } - DEF OverC Conditional { - buffer { - REPLACE M1.emissiveColor BY 1 1 0 - } - } - DEF OverRC Conditional { - buffer { - REPLACE M1.emissiveColor BY 0 1 1 - } - } - DEF C Conditional { - buffer { - REPLACE M1.emissiveColor BY 1 0 0 - } - } - DEF RC Conditional { - buffer { - REPLACE M1.emissiveColor BY 0 0 1 - } - } - ] - } - ] -} - -ROUTE TS1.isActive TO C.activate -ROUTE TS1.isActive TO RC.reverseActivate -ROUTE TS1.isOver TO OverC.activate -ROUTE TS1.isOver TO OverRC.reverseActivate - diff --git a/regression_tests/bifs-2D-interactivity-touchsensor-hitpoint.bt b/regression_tests/bifs-2D-interactivity-touchsensor-hitpoint.bt deleted file mode 100644 index 71e9d46..0000000 --- a/regression_tests/bifs-2D-interactivity-touchsensor-hitpoint.bt +++ /dev/null @@ -1,91 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 254 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 254 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to retrieve the mouse position when it is moved." - "The TouchSensor node generates the hitPoint event, which is a 3D point, when the mouse moves. This can be used in scripts to trigger actions." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "TouchSensor & hitPoint" - } - Transform2D { - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Rectangle {} - - } - ] - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 198 198 - } - } - DEF TS TouchSensor {} - ] - } - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APP - geometry DEF TXT Text { - string [""] - fontStyle FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - DEF V Valuator { - Factor3 0 - } - ] -} - -ROUTE TS.hitPoint_changed TO V.inSFVec3f -ROUTE V.outMFString TO TXT.string - diff --git a/regression_tests/bifs-2D-interactivity-touchsensor-isactive-exposedfield.bt b/regression_tests/bifs-2D-interactivity-touchsensor-isactive-exposedfield.bt deleted file mode 100644 index d5b695a..0000000 --- a/regression_tests/bifs-2D-interactivity-touchsensor-isactive-exposedfield.bt +++ /dev/null @@ -1,99 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 140 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows a TouchSensor node used to modify the filled property of 2 Material2D nodes." - "cf bifs-2D-interactivity-touchsensor-isactive" - "The difference with the above test is the event propagation. Instead of routing the TouchSensor isActive event to both Material2D node, the event is only sent to one Material2D node, but since the emissiveColor field is an exposedField, it generate in turns a new event and that event is routed to the second Material2D node." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "TouchSensor, isActive & Event Propagation" - - } - Transform2D { - scale 0.5 0.5 - children [ - Transform2D { - translation 0 60 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - DEF TS1 TouchSensor {} - DEF TS2 TouchSensor {} - ] - } - Transform2D { - translation -100 -50 - children [ - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 1 1 0 - } - } - geometry Circle { - radius 50 - } - } - ] - } - Transform2D { - translation 100 -50 - children [ - Shape { - appearance Appearance { - material DEF M2 Material2D { - emissiveColor 0 1 1 - } - } - geometry Circle { - radius 50 - } - } - ] - } - ] - } - ] -} - -ROUTE TS1.isActive TO M1.filled -ROUTE M1.filled TO M2.filled - diff --git a/regression_tests/bifs-2D-interactivity-touchsensor-isactive.bt b/regression_tests/bifs-2D-interactivity-touchsensor-isactive.bt deleted file mode 100644 index 01ddc8f..0000000 --- a/regression_tests/bifs-2D-interactivity-touchsensor-isactive.bt +++ /dev/null @@ -1,98 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 140 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows a TouchSensor node used to modify the filled property of 2 Material2D nodes." - "The TouchSensor node sends an isActive event each time a Mouse Button is pressed. The value of the event is TRUE if the Mouse is over a sibling shape of the TouchSensor node. Otherwise it is FALSE." - "In this example, the event value is routed to the filled property of 2 different circles. So, when the mouse is clicked on the square, both circled are filled and when the mouse is released, both circles become empty." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "TouchSensor & isActive" - } - Transform2D { - scale 0.5 0.5 - children [ - Transform2D { - translation 0 60 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - DEF TS1 TouchSensor {} - DEF TS2 TouchSensor {} - ] - } - Transform2D { - translation -100 -50 - children [ - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 1 1 0 - } - } - geometry Circle { - radius 50 - } - } - ] - } - Transform2D { - translation 100 -50 - children [ - Shape { - appearance Appearance { - material DEF M2 Material2D { - emissiveColor 0 1 1 - } - } - geometry Circle { - radius 50 - } - } - ] - } - ] - } - ] -} - -ROUTE TS1.isActive TO M1.filled -ROUTE TS2.isActive TO M2.filled - diff --git a/regression_tests/bifs-2D-interactivity-touchsensor-isover.bt b/regression_tests/bifs-2D-interactivity-touchsensor-isover.bt deleted file mode 100644 index 2a4251d..0000000 --- a/regression_tests/bifs-2D-interactivity-touchsensor-isover.bt +++ /dev/null @@ -1,59 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 260 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows a TouchSensor node used to modify the filled property of a Material2D node." - "The TouchSensor node sends an isOver event when the Mouse enters or exits the region delimited by a Shape node, sibling of the TouchSensor node. The value is TRUE, when it enters, and FALSE when it leaves." - "In this example, the TouchSensor has only one sibling a rectangle, which turns empty when the mouse is not over it." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "TouchSensor & isOver" - } - Transform2D { - children [ - DEF TS TouchSensor {} - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 0 0 1 - } - } - geometry Rectangle { - size 200 100 - } - } - ] - } - ] -} - -ROUTE TS.isOver TO M1.filled - diff --git a/regression_tests/bifs-2D-interactivity-touchsensor-move_over.bt b/regression_tests/bifs-2D-interactivity-touchsensor-move_over.bt deleted file mode 100644 index d8fcb70..0000000 --- a/regression_tests/bifs-2D-interactivity-touchsensor-move_over.bt +++ /dev/null @@ -1,268 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 254 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 254 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how a TouchSensor node and a TimeSensor can be used to make a new Event called MoveOver, which is TRUE when the mouse moves over a Shape or FALSE when the mouse has not moved over the Shape for a certain period of time." - "This is an example to show how new events can be created based on existing tools and events (no scripting). This particular event simulates the Lingo MouseWithin event. " - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" - "(C) 2002-2006 GPAC Team" - ] - title "Move Over" - } - Transform2D { - children [ - Shape { - appearance Appearance { - material DEF M Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - DEF TS TouchSensor {} - ] - } - DEF V_ISOVER_TO_FACTOR Valuator { - } - DEF V_HITPOINT_CHANGED_TO_ONE Valuator { - Factor1 0 - Offset1 1 - } - DEF DUMMY_TIMER TimeSensor { enabled FALSE } - DEF T TimeSensor { - cycleInterval 1 - loop TRUE - startTime -1 - } - DEF STOP_TIME_OFFSETER Valuator { Offset1 0.1 } # minimum duration between two mouse move - - DEF START_TIMER Conditional { - buffer { - REPLACE DUMMY_TIMER.startTime BY 0 - REPLACE T.startTime BY 0 - } - } - DEF VALUATOR Valuator { - } - DEF V_MOVE_OVER Valuator { - } - DEF OUT Conditional { - buffer { - REPLACE T.stopTime BY 0 - } - } - DEF C Conditional { - buffer { - REPLACE M.emissiveColor BY 0 1 0 - } - } - DEF RC Conditional { - buffer { - REPLACE M.emissiveColor BY 1 0 0 - } - } - Transform2D { - translation 20 60 - children [ - Transform2D { - translation -80 0 - children [ - Transform2D { - translation 0 20 - children [ - Shape { - appearance DEF TEXT_APP Appearance { material Material2D { emissiveColor 0 0 0 filled TRUE } } - geometry Text { - string "Mouse Over & " - fontStyle DEF TEXT_STYLE FontStyle { size 10 family "SANS" justify ["MIDDLE" "MIDDLE" ] } - } - } - ] - } - Shape { - appearance USE TEXT_APP - geometry DEF MOUSE_OVER_TEXT Text { - fontStyle USE TEXT_STYLE - } - } - ] - } - Transform2D { - translation -10 0 - children [ - Transform2D { - translation 0 20 - children [ - Shape { - appearance USE TEXT_APP - geometry Text { - string [ " Mouse has " " moved recently =" ] - fontStyle USE TEXT_STYLE - } - } - ] - } - Shape { - appearance USE TEXT_APP - geometry DEF TIMER_STATUS_TEXT Text { - fontStyle USE TEXT_STYLE - } - } - ] - } - Transform2D { - translation 60 0 - children [ - Transform2D { - translation 0 20 - children [ - Shape { - appearance USE TEXT_APP - geometry Text { - string [ "Result" "Move Over" ] - fontStyle USE TEXT_STYLE - } - } - ] - } - Shape { - appearance USE TEXT_APP - geometry DEF RESULT_TEXT Text { - fontStyle USE TEXT_STYLE - } - } - ] - } - ] - } -# Transform2D { -# translation -60 -80 -# children [ -# Transform2D { -# translation 0 0 -# children [ -# Transform2D { -# translation 0 20 -# children [ -# Shape { -# appearance USE TEXT_APP -# geometry Text { -# string "Start Time" -# fontStyle USE TEXT_STYLE -# } -# } -# ] -# } -# Shape { -# appearance USE TEXT_APP -# geometry DEF START_TIME_TEXT Text { -# fontStyle USE TEXT_STYLE -# } -# } -# ] -# } -# Transform2D { -# translation 60 0 -# children [ -# Transform2D { -# translation 0 20 -# children [ -# Shape { -# appearance USE TEXT_APP -# geometry Text { -# string "Stop Time" -# fontStyle USE TEXT_STYLE -# } -# } -# ] -# } -# Shape { -# appearance USE TEXT_APP -# geometry DEF STOP_TIME_TEXT Text { -# fontStyle USE TEXT_STYLE -# } -# } -# ] -# } -# ] -# } -# DEF V_START_TIME Valuator {Factor1 100} -# DEF V_STOP_TIME Valuator {Factor1 100} - ] -} - -# These two routes do the following: -# read the startTime field of a DUMMY_TIMER (which is equal to NOW because, has been replaced by 0) -# offset this value by the appropriate delay -# set the stoptime value of the real timer -ROUTE DUMMY_TIMER.startTime TO STOP_TIME_OFFSETER.inSFTime -ROUTE STOP_TIME_OFFSETER.outSFTime TO T.stopTime - -# This is a route to force the stop of the timer when the mouse exits the shape -ROUTE TS.isOver TO OUT.reverseActivate - -# These 2 routes convert the isOver (a boolean) into a float -# and stores the value in the factor of a valuator -ROUTE TS.isOver TO V_ISOVER_TO_FACTOR.inSFBool -ROUTE V_ISOVER_TO_FACTOR.outSFFloat TO V_MOVE_OVER.Factor1 - -# Display the status of the IsOver boolean -ROUTE V_ISOVER_TO_FACTOR.outMFString TO MOUSE_OVER_TEXT.string - -#These 2 routes create an event (Boolean = TRUE) whenever the mouse moves -#and activates a conditional -ROUTE TS.hitPoint_changed TO V_HITPOINT_CHANGED_TO_ONE.inSFVec3f -ROUTE V_HITPOINT_CHANGED_TO_ONE.outSFBool TO START_TIMER.activate - -# When the timer is active, it means the mouse is moving, we route this event to the move_over valuator -ROUTE T.isActive TO V_MOVE_OVER.inSFBool - -# Display of the status of the timer -ROUTE T.isActive TO VALUATOR.inSFBool -ROUTE VALUATOR.outMFString TO TIMER_STATUS_TEXT.string - -# Trigger one action when the result is TRUE -ROUTE V_MOVE_OVER.outSFBool TO C.activate -# Trigger one action when the result is FALSE -ROUTE V_MOVE_OVER.outSFBool TO RC.reverseActivate - -# Display of the final result -ROUTE V_MOVE_OVER.outMFString TO RESULT_TEXT.string - -# Display of the startTime of the Timer -#ROUTE T.startTime TO V_START_TIME.inSFTime -#ROUTE V_START_TIME.outMFString TO START_TIME_TEXT.string - -# Display of the stopTime of the Timer -#ROUTE T.stopTime TO V_STOP_TIME.inSFTime -#ROUTE V_STOP_TIME.outMFString TO STOP_TIME_TEXT.string \ No newline at end of file diff --git a/regression_tests/bifs-2D-painting-colortransform-alpha.bt b/regression_tests/bifs-2D-painting-colortransform-alpha.bt deleted file mode 100644 index 5569742..0000000 --- a/regression_tests/bifs-2D-painting-colortransform-alpha.bt +++ /dev/null @@ -1,101 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to modify the color components on a graphical object using the ColorTransform node." - "A group made of a circle and a rectangle is reused under a ColorTransform node which animates only the Red-Blue component from 0 to 1" - "Note: the transparency is specified for a set of objects but is applied individually, that is why the overlapping region of the circle and of the rectangle gets black faster than the rest of the group." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "ColorTranform" - } - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - } - geometry Rectangle { - size 200 50 - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 1 - filled TRUE - } - } - geometry Circle { - radius 50 - } - } - ] - } - DEF CT ColorTransform { - mrr 0 - mgg 0 - mbb 0 - maa 0 - ta 1 - children [ - DEF MX TransformMatrix2D { - mxx 0.5 - mxy 0.5 - myy 0.5 - ty -100 - children [ - USE TR - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF CI PositionInterpolator2D { - key [0 0.5 1] - keyValue [0 0 100 100 0 0] - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO CT.ta - diff --git a/regression_tests/bifs-2D-painting-colortransform-bitmap.bt b/regression_tests/bifs-2D-painting-colortransform-bitmap.bt deleted file mode 100644 index 908351a..0000000 --- a/regression_tests/bifs-2D-painting-colortransform-bitmap.bt +++ /dev/null @@ -1,109 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to modify the color components of an image using the ColorTransform node." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "ColorTranform on an image" - } - DEF TR Transform2D { - children [ - DEF S Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - texture ImageTexture { - url ["od:2"] - } - } - geometry Rectangle { size 200 80} - } - ] - } - DEF CT ColorTransform { - mrr 1 - mgg 1 - mbb 0.2 - tr 0 - children [ - Transform2D { - translation 0 -100 - children [ - USE S - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF CI PositionInterpolator2D { - key [0 0.5 1] - keyValue [0 0 100 100 0 0] - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO TR.translation -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO CT.mrb -ROUTE TS.fraction_changed TO CT.maa - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 2 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ] -} diff --git a/regression_tests/bifs-2D-painting-colortransform-color.bt b/regression_tests/bifs-2D-painting-colortransform-color.bt deleted file mode 100644 index 2746a73..0000000 --- a/regression_tests/bifs-2D-painting-colortransform-color.bt +++ /dev/null @@ -1,102 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to modify the color components on a graphical object using the ColorTransform node." - "A group made of a circle and a rectangle is reused under a ColorTransform node which sets the color components to 0 and the alpha component is animated from 0 to 1" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "ColorTranform and color changes" - } - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - } - geometry Rectangle { - size 200 50 - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 1 - filled TRUE - } - } - geometry Circle { - radius 50 - } - } - ] - } - DEF CT ColorTransform { - mrr 0 - mgg 0 - mbb 0 - maa 0 - ta 1 - children [ - DEF MX TransformMatrix2D { - mxx 0.5 - mxy 0.5 - myy 0.5 - ty -100 - children [ - USE TR - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF CI PositionInterpolator2D { - key [0 0.5 1] - keyValue [0 0 100 100 0 0] - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO TR.translation -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO CT.mrb - diff --git a/regression_tests/bifs-2D-painting-lineproperties.bt b/regression_tests/bifs-2D-painting-lineproperties.bt deleted file mode 100644 index 0e3ba88..0000000 --- a/regression_tests/bifs-2D-painting-lineproperties.bt +++ /dev/null @@ -1,168 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 500 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to set basic outline properties, using the LineProperties node" - "The properties are width, lineColor and lineStyle." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" - "(C) 2002-2006 GPAC Team" - ] - title "Setting simple line properties - the LineProperties node" - } - DEF TR1 Transform2D { - translation -190 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - lineStyle 0 - width 15 - } - } - } - geometry DEF LS IndexedLineSet2D { - coord Coordinate2D { - point [-50 0 0 50 50 0] - } - } - } - ] - } - Transform2D { - translation -190 -30 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["lineStyle 0"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 16 - } - } - } - ] - } - DEF TR2 Transform2D { - translation -65 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 1 0 0 - lineStyle 1 - width 15 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation -65 -30 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["lineStyle 1"] - fontStyle USE FS - } - } - ] - } - DEF TR3 Transform2D { - translation 65 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 0 1 1 - lineStyle 2 - width 15 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation 65 -30 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["lineStyle 2"] - fontStyle USE FS - } - } - ] - } - DEF TR4 Transform2D { - translation 190 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 0 1 0 - lineStyle 3 - width 15 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation 190 -30 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["lineStyle 3"] - fontStyle USE FS - } - } - ] - } - ] -} diff --git a/regression_tests/bifs-2D-painting-material2D.bt b/regression_tests/bifs-2D-painting-material2D.bt deleted file mode 100644 index 329dd82..0000000 --- a/regression_tests/bifs-2D-painting-material2D.bt +++ /dev/null @@ -1,154 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to specify the filling and simple outlining of 2D shapes" - "It uses the Material2D node. The filled property indicates if the shape is filled or not. The emissiveColor property specifies the fill color if filled or the outline color if not filled. Transparency can be set using the transparency property." - "In this simple example, the width and other properties of the outline cannot be set. To set more properties, use the LineProperties or XLineProperties nodes." - "cf bifs-2D-painting-lineproperties" - "cf bifs-2D-painting-xlineproperties-cap" - "cf bifs-2D-painting-xlineproperties-compositetexture2D" - "cf bifs-2D-painting-xlineproperties-dash" - "cf bifs-2D-painting-xlineproperties-imagetexture" - "cf bifs-2D-painting-xlineproperties-join" - "cf bifs-2D-painting-xlineproperties-lineargradient" - "cf bifs-2D-painting-xlineproperties-radialgradient" - "cf bifs-2D-painting-xlineproperties-scalable" - "cf bifs-2D-painting-xlineproperties-transparent" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.4 $" - "(C) 2002-2006 GPAC Team"] - title "Material2D properties" - } - Transform2D { - translation -180 0 - children [ - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Rectangle { - size 80 80 - } - } - ] - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 1 - } - } - geometry DEF REC Rectangle { - size 150 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Not filled, Color 1 0 1"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 14 - } - } - } - ] - } - ] - } - Transform2D { - children [ - USE TR - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 1 - filled TRUE - } - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["filled, Color 1 0 1"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 180 0 - children [ - USE TR - Shape { - appearance Appearance { - material DEF M Material2D { - emissiveColor 1 0 1 - filled TRUE - transparency 0.6 - } - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["filled, Color 1 0 1" "transparency 0.6"] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} diff --git a/regression_tests/bifs-2D-painting-xlineproperties-cap.bt b/regression_tests/bifs-2D-painting-xlineproperties-cap.bt deleted file mode 100644 index c98e188..0000000 --- a/regression_tests/bifs-2D-painting-xlineproperties-cap.bt +++ /dev/null @@ -1,211 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 500 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the usage of cap styles of the XLineProperties node" - "Moving the mouse over the 'Anim' button will superpose the different lines to highlight the linecap differences" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Changing line caps using the XLineProperties node" - } - DEF TR1 Transform2D { - translation -190 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 0 0 1 - lineCap 2 - width 15 - } - } - } - geometry DEF LS IndexedLineSet2D { - coord Coordinate2D { - point [-50 0 0 50 50 0] - } - } - } - ] - } - Transform2D { - translation -190 -30 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Cap square"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 16 - } - } - } - ] - } - DEF TR2 Transform2D { - translation -65 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 1 0 0 - lineCap 1 - width 15 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation -65 -30 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Cap round"] - fontStyle USE FS - } - } - ] - } - DEF TR3 Transform2D { - translation 65 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 0 1 1 - lineCap 3 - width 15 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation 65 -30 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Cap triangle"] - fontStyle USE FS - } - } - ] - } - DEF TR4 Transform2D { - translation 190 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 0 1 0 - width 15 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation 190 -30 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Cap 'butt'"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 225 -75 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Anim"] - fontStyle USE FS - } - } - DEF TS TouchSensor {} - ] - } - DEF C Conditional { - buffer { - REPLACE TR1.translation BY 0 0 - REPLACE TR2.translation BY 0 0 - REPLACE TR3.translation BY 0 0 - REPLACE TR4.translation BY 0 0 - } - } - DEF RC Conditional { - buffer { - REPLACE TR1.translation BY -190 0 - REPLACE TR2.translation BY -65 0 - REPLACE TR3.translation BY 65 0 - REPLACE TR4.translation BY 190 0 - } - } - ] -} - -ROUTE TS.isOver TO C.activate -ROUTE TS.isOver TO RC.reverseActivate - diff --git a/regression_tests/bifs-2D-painting-xlineproperties-compositetexture2D.bt b/regression_tests/bifs-2D-painting-xlineproperties-compositetexture2D.bt deleted file mode 100644 index 71bf4a4..0000000 --- a/regression_tests/bifs-2D-painting-xlineproperties-compositetexture2D.bt +++ /dev/null @@ -1,153 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This shows line texturing with a composite texture using the CompositeTexture2D node using variable width and different line alignment" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Complex line texturing with the XLineProperties node" - } - Transform2D { - translation 0 150 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Line width varying between 0 and 100"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -140 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps DEF XLP XLineProperties { - width 20 - textureTransform TextureTransform { scale 8 8} - texture DEF IM CompositeTexture2D { - pixelWidth 32 - pixelHeight 32 - children [ - Shape { - appearance Appearance { - material Material2D { emissiveColor 0 1 0 filled TRUE } - } - geometry DEF C Circle { - radius 6 - } - } - ] - } - } - } - } - geometry Rectangle { - size 150 150 - } - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Line centered on shape"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 160 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps DEF XLP2 XLineProperties { - isCenterAligned FALSE - width 0 - texture USE IM - } - } - } - geometry Rectangle { - size 150 150 - } - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Line inside shape"] - fontStyle USE FS - } - } - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 100 0] - } - DEF SI2 ScalarInterpolator { - key [0 0.5 1] - keyValue [6 10 6] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO XLP.width -ROUTE SI.value_changed TO XLP2.width -ROUTE TS.fraction_changed TO SI2.set_fraction -ROUTE SI2.value_changed TO C.radius - diff --git a/regression_tests/bifs-2D-painting-xlineproperties-dash.bt b/regression_tests/bifs-2D-painting-xlineproperties-dash.bt deleted file mode 100644 index d873544..0000000 --- a/regression_tests/bifs-2D-painting-xlineproperties-dash.bt +++ /dev/null @@ -1,142 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the usage of line dashing using the XLineProperties node." - "Two properties are demonstrated: dash pattern and dash offset. The offset is animated on the left, the dash length is animated on the right." - "" - "GPAC Regression Tests" "$Date: 2007/09/14 16:42:18 $ - $Revision: 1.4 $" - "(C) 2002-2006 GPAC Team" - ] - title "Animating the line dashes using the XLineProperties node" - } - Transform2D { - translation 140 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps DEF XLP1 XLineProperties { - lineColor 0 0 1 - lineStyle 6 - isScalable TRUE - lineCap 1 - width 20 - dashes [0.1 80] - } - } - } - geometry DEF LS Curve2D { - fineness 1 - type [2] - point Coordinate2D { - point [-100 0 -50 200 50 -200 100 0] - } - } - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["dash pattern animation"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - Transform2D { - translation -140 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps DEF XLP2 XLineProperties { - lineColor 0 0 1 - lineStyle 6 - isScalable TRUE - lineCap 1 - width 20 - dashes [3 80] - } - } - } - geometry USE LS - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["dash offset animation"] - fontStyle USE FS - } - } - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval 3 - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 16 0] - } - DEF CI CoordinateInterpolator2D { - key [0 0.5 1] - keyValue [0.2 0 80 0 17.5 0 80 0 0.2 0 80 0] - } - DEF V Valuator { - Factor2 0 - Factor3 0 - Factor4 0 - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO XLP2.dashOffset -ROUTE TS.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO V.inMFVec2f -ROUTE V.outMFFloat TO XLP1.dashes - diff --git a/regression_tests/bifs-2D-painting-xlineproperties-imagetexture.bt b/regression_tests/bifs-2D-painting-xlineproperties-imagetexture.bt deleted file mode 100644 index 5c4b010..0000000 --- a/regression_tests/bifs-2D-painting-xlineproperties-imagetexture.bt +++ /dev/null @@ -1,159 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 560 - pixelHeight 420 - } - } - } - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This shows line texturing with an image using variable width and different line alignment" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Line texturing with Images - the XLineProperties node" - } - Transform2D { - translation 0 140 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Line width varying between 0 and 100"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -140 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps DEF XLP XLineProperties { - width 20 - texture DEF IM ImageTexture { - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - } - } - geometry Rectangle { - size 150 150 - } - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Line centered on shape"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 140 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps DEF XLP2 XLineProperties { - isCenterAligned FALSE - width 0 - texture USE IM - } - } - } - geometry Rectangle { - size 150 150 - } - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Line inside shape"] - fontStyle USE FS - } - } - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 100 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO XLP.width -ROUTE SI.value_changed TO XLP2.width - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-painting-xlineproperties-join.bt b/regression_tests/bifs-2D-painting-xlineproperties-join.bt deleted file mode 100644 index ecba234..0000000 --- a/regression_tests/bifs-2D-painting-xlineproperties-join.bt +++ /dev/null @@ -1,215 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the usage of line join styles of the XLineProperties node" - "Moving the mouse over the 'Anim' button will superpose the different lines to highlight the linejoin differences" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Changing line caps using the XLineProperties node" - } - DEF TR1 Transform2D { - translation -200 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 0 0 1 - width 20 - } - } - } - geometry DEF LS IndexedLineSet2D { - coord Coordinate2D { - point [-50 0 0 50 50 0] - } - } - } - ] - } - Transform2D { - translation -200 -50 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Join Miter" "miterLimit: default"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 16 - } - } - } - ] - } - DEF TR3 Transform2D { - translation 70 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 0 1 0 - lineJoin 1 - width 20 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation 70 -50 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Join Round"] - fontStyle USE FS - } - } - ] - } - - - DEF TR4 Transform2D { - translation 200 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 1 0 1 - lineJoin 2 - width 20 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation 200 -50 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Join Bevel"] - fontStyle USE FS - } - } - ] - } - - DEF TR2 Transform2D { - translation -70 0 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 1 0 0 - miterLimit 0.4 - width 20 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation -70 -50 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Join Miter" "miterLimit: 0.4"] - fontStyle USE FS - } - } - ] - } - - Transform2D { - translation 280 -75 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Anim"] - fontStyle USE FS - } - } - DEF TS TouchSensor {} - ] - } - DEF C Conditional { - buffer { - REPLACE TR1.translation BY 0 0 - REPLACE TR2.translation BY 0 0 - REPLACE TR3.translation BY 0 0 - REPLACE TR4.translation BY 0 0 - } - } - DEF RC Conditional { - buffer { - REPLACE TR1.translation BY -190 0 - REPLACE TR2.translation BY -65 0 - REPLACE TR3.translation BY 65 0 - REPLACE TR4.translation BY 190 0 - } - } - ] -} - -ROUTE TS.isOver TO C.activate -ROUTE TS.isOver TO RC.reverseActivate - diff --git a/regression_tests/bifs-2D-painting-xlineproperties-lineargradient.bt b/regression_tests/bifs-2D-painting-xlineproperties-lineargradient.bt deleted file mode 100644 index f416069..0000000 --- a/regression_tests/bifs-2D-painting-xlineproperties-lineargradient.bt +++ /dev/null @@ -1,122 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows line texturing with a linear gradient with different spread method and animated end point" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team"] - title "Linear Gradient and Lines using XLineProperties" - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Move over and click" "to change the spread method"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - TransformMatrix2D { - mxy 0.5 - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - lineProps XLineProperties { - width 40 - texture DEF GL LinearGradient { - endPoint 0 0.5 - key [0 0.5 1] - keyValue [0 0 1 1 0 0 0 1 0] - } - } - } - } - geometry DEF R Rectangle { - size 200 200 - } - } - DEF TS TouchSensor {} - ] - } - ] - } - DEF C Conditional { - buffer { - REPLACE GL.spreadMethod BY 2 - } - } - DEF RC Conditional { - buffer { - REPLACE GL.spreadMethod BY 0 - } - } - DEF C2 Conditional { - buffer { - REPLACE GL.spreadMethod BY 1 - } - } - DEF RC2 Conditional { - buffer { - REPLACE GL.spreadMethod BY 2 - } - } - DEF TIME TimeSensor { - cycleInterval 4 - loop TRUE - } - DEF CI PositionInterpolator2D { - key [0 0.5 1] - keyValue [0 0.5 1 0.5 0 0.5] - } - ] -} - -ROUTE TS.isOver TO C.activate -ROUTE TS.isOver TO RC.reverseActivate -ROUTE TS.isActive TO C2.activate -ROUTE TS.isActive TO RC2.reverseActivate -ROUTE TIME.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO GL.endPoint - diff --git a/regression_tests/bifs-2D-painting-xlineproperties-radialgradient.bt b/regression_tests/bifs-2D-painting-xlineproperties-radialgradient.bt deleted file mode 100644 index b403696..0000000 --- a/regression_tests/bifs-2D-painting-xlineproperties-radialgradient.bt +++ /dev/null @@ -1,124 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows line texturing with a radial gradient with different spread method and animated focal point" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team"] - title "Radial Gradient on lines using XLineProperties node" - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Move over and click" "to change the spread method"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - DEF TR TransformMatrix2D { - mxy 1 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - isCenterAligned TRUE - width 40 - texture DEF GR RadialGradient { - focalPoint 0 0.5 - key [0 0.5 1] - keyValue [0 0 1 1 0 0 0 1 0] - } - } - } - } - geometry DEF R Rectangle { - size 200 200 - } - } - DEF TS TouchSensor {} - ] - } - DEF C Conditional { - buffer { - REPLACE GR.spreadMethod BY 2 - } - } - DEF RC Conditional { - buffer { - REPLACE GR.spreadMethod BY 0 - } - } - DEF C2 Conditional { - buffer { - REPLACE GR.spreadMethod BY 1 - } - } - DEF RC2 Conditional { - buffer { - REPLACE GR.spreadMethod BY 2 - } - } - DEF TIME TimeSensor { - cycleInterval 4 - loop TRUE - } - DEF CI PositionInterpolator2D { - key [0 0.25 0.5 0.75 1] - keyValue [0 0.5 0.5 1 1 0.5 0.5 0 0 0.5] - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.isOver TO C.activate -ROUTE TS.isOver TO RC.reverseActivate -ROUTE TS.isActive TO C2.activate -ROUTE TS.isActive TO RC2.reverseActivate -ROUTE TIME.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO GR.focalPoint -ROUTE TIME.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO TR.mxy - diff --git a/regression_tests/bifs-2D-painting-xlineproperties-scalable.bt b/regression_tests/bifs-2D-painting-xlineproperties-scalable.bt deleted file mode 100644 index 62cd528..0000000 --- a/regression_tests/bifs-2D-painting-xlineproperties-scalable.bt +++ /dev/null @@ -1,123 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the usage of scalable flag in the XLineProperties node" - "We see that the right line's width changes during the animation while the left one does not change." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2004 GPAC Team" - ] - title "Scalability of the outline - the XLineProperties node" - } - DEF TR1 Transform2D { - scale 2 2 - translation -150 -50 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - width 2 - } - } - } - geometry DEF LS IndexedLineSet2D { - coord Coordinate2D { - point [-50 0 0 50 50 0] - } - } - } - ] - } - Transform2D { - translation -150 -50 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Not scalable"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 16 - } - } - } - ] - } - DEF TR2 Transform2D { - scale 2 2 - translation 150 -50 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps XLineProperties { - lineColor 0 0 1 - width 2 - } - } - } - geometry USE LS - } - ] - } - Transform2D { - translation 150 -50 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Scalable"] - fontStyle USE FS - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 4 - loop TRUE - } - DEF PI PositionInterpolator2D { - key [0 0.5 1] - keyValue [1 1 3 3 1 1] - } - ] -} - -ROUTE TS.fraction_changed TO PI.set_fraction -ROUTE PI.value_changed TO TR1.scale -ROUTE PI.value_changed TO TR2.scale - diff --git a/regression_tests/bifs-2D-painting-xlineproperties-transparent.bt b/regression_tests/bifs-2D-painting-xlineproperties-transparent.bt deleted file mode 100644 index 0f7f027..0000000 --- a/regression_tests/bifs-2D-painting-xlineproperties-transparent.bt +++ /dev/null @@ -1,176 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows usage of line transparency and line alignment" - "The outline or its outside is centered on the shape depending on the value of the isCenterAligned." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Positioning lines and setting transparency using the XLineProperties node" - } - Transform2D { - translation -100 100 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - lineProps XLineProperties { - lineColor 0 0 1 - width 10 - } - } - } - geometry DEF RC Rectangle { - size 150 100 - } - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance DEF TXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["No line transparency" "CenterAligned TRUE"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] - } - Transform2D { - translation 100 100 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - lineProps XLineProperties { - lineColor 0 0 1 - isCenterAligned FALSE - width 10 - } - } - } - geometry USE RC - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["No line transparency" "CenterAligned FALSE"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation -100 -80 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - lineProps XLineProperties { - lineColor 0 0 1 - transparency 0.5 - width 10 - } - } - } - geometry USE RC - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["Line transparency: 0.5" "CenterAligned TRUE"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 100 -80 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - lineProps XLineProperties { - lineColor 0 0 1 - isCenterAligned FALSE - transparency 0.5 - width 10 - } - } - } - geometry USE RC - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["Line transparency: 0.5" "CenterAligned FALSE"] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-clipper2D.bt b/regression_tests/bifs-2D-positioning-clipper2D.bt deleted file mode 100644 index 9e9a623..0000000 --- a/regression_tests/bifs-2D-positioning-clipper2D.bt +++ /dev/null @@ -1,316 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - url [od:5] - } - WorldInfo { - info ["This shows combination of Clipper2D objects" "with different modes" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Clipper2D Test" - } - Transform2D { - scale 0.5 0.5 - translation -200 100 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Rectangle { - size 200 200 - } - } - DEF PS PlaneSensor2D { - maxPosition 150 150 - minPosition -150 -150 - } - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Translate" "round" "cliper"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 40 - } - } - } - ] - } - Transform2D { - scale 0.5 0.5 - translation -80 100 - children [ - DEF S1 Switch { - whichChoice 0 - choice [ - Group { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Round Clipper" "inside = FALSE"] - fontStyle USE FS - } - } - DEF TS1 TouchSensor {} - ] - } - Group { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Round Clipper" "inside = TRUE"] - fontStyle USE FS - } - } - DEF RTS1 TouchSensor {} - ] - } - ] - } - ] - } - Transform2D { - scale 0.5 0.5 - translation -80 0 - children [ - DEF SX1 Switch { - whichChoice 0 - choice [ - Group { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["XOR = FALSE"] - fontStyle USE FS - } - } - DEF TSX1 TouchSensor {} - ] - } - Group { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["XOR = TRUE"] - fontStyle USE FS - } - } - DEF RTSX1 TouchSensor {} - ] - } - ] - } - ] - } - Transform2D { - scale 0.5 0.5 - translation -200 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 1 - filled TRUE - } - } - geometry Circle { - radius 100 - } - } - DEF DS DiscSensor {} - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Rotate" "square" "cliper"] - fontStyle USE FS - } - } - ] - } - Transform2D { - scale 0.5 0.5 - translation -80 -120 - children [ - DEF S2 Switch { - whichChoice 0 - choice [ - Group { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Rect Clipper" "inside = FALSE"] - fontStyle USE FS - } - } - DEF TS2 TouchSensor {} - ] - } - Group { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Rect Clipper" "inside = TRUE"] - fontStyle USE FS - } - } - DEF RTS2 TouchSensor {} - ] - } - ] - } - ] - } - Transform2D { - translation 150 0 - children [ - DEF CLIP_SQ Clipper2D { - inside FALSE - children [ - DEF CLIP_RD Clipper2D { - inside FALSE - children [ - Shape { - appearance Appearance { - texture ImageTexture { - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry Circle { - radius 100 - } - } - ] - geometry Circle { - radius 50 - } - transform DEF TR_RD Transform2D {} - - } - ] - geometry Rectangle { - size 200 75 - } - transform DEF TR_SQ Transform2D {} - - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE CLIP_RD.inside BY TRUE - REPLACE S1.whichChoice BY 1 - } - } - DEF RC1 Conditional { - buffer { - REPLACE CLIP_RD.inside BY FALSE - REPLACE S1.whichChoice BY 0 - } - } - DEF CX1 Conditional { - buffer { - REPLACE CLIP_RD.XOR BY TRUE - REPLACE SX1.whichChoice BY 1 - } - } - DEF RCX1 Conditional { - buffer { - REPLACE CLIP_RD.XOR BY FALSE - REPLACE SX1.whichChoice BY 0 - } - } - DEF C2 Conditional { - buffer { - REPLACE CLIP_SQ.inside BY TRUE - REPLACE S2.whichChoice BY 1 - } - } - DEF RC2 Conditional { - buffer { - REPLACE CLIP_SQ.inside BY FALSE - REPLACE S2.whichChoice BY 0 - } - } - ] -} - -ROUTE PS.translation_changed TO TR_RD.translation -ROUTE DS.rotation_changed TO TR_SQ.rotationAngle -ROUTE TS1.isActive TO C1.activate -ROUTE RTS1.isActive TO RC1.activate -ROUTE TSX1.isActive TO CX1.activate -ROUTE RTSX1.isActive TO RCX1.activate -ROUTE TS2.isActive TO C2.activate -ROUTE RTS2.isActive TO RC2.activate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 10 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-positioning-form-align-center.bt b/regression_tests/bifs-2D-positioning-form-align-center.bt deleted file mode 100644 index d8f9332..0000000 --- a/regression_tests/bifs-2D-positioning-form-align-center.bt +++ /dev/null @@ -1,162 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Form node" "with horizontal and vertical center alignment" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Form Test" - } - Transform2D { - translation -100 0 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 100 200 - } - } - Transform2D { - translation 0 -120 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Constraints: AT AB AH "] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Form { - size 100 200 - groups [1 -1 2 -1] - constraints ["AT" "AB" "AH"] - groupsIndex [0 1 -1 0 2 -1 1 2 -1] - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 30 - } - } - DEF S2 Transform2D { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 60 20 - } - } - ] - } - Transform2D { - translation -20 -20 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - ] - } - ] - } - ] - } - ] - } - Transform2D { - translation 75 0 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 200 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Constraints: AL AR AV"] - fontStyle USE FS - } - } - ] - } - Form { - size 200 100 - groups [1 -1 2 -1] - constraints ["AL" "AR" "AV"] - groupsIndex [0 1 -1 0 2 -1 1 2 -1] - children [ - USE S1 - USE S2 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-form-align-horiz.bt b/regression_tests/bifs-2D-positioning-form-align-horiz.bt deleted file mode 100644 index f8c7234..0000000 --- a/regression_tests/bifs-2D-positioning-form-align-horiz.bt +++ /dev/null @@ -1,129 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Form node" "with horizontal alignment" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Form Test" - } - Transform2D { - translation -75 0 - children [ - DEF FORM Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 100 200 - } - } - Transform2D { - translation 0 -120 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Constraints: AL AL 10"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Form { - size 100 200 - groups [1 -1 2 -1] - constraints ["AL" "AL 10"] - groupsIndex [0 1 -1 1 2 -1] - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 30 - } - } - DEF S2 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - ] - } - ] - } - Transform2D { - translation 75 0 - children [ - USE FORM - Transform2D { - translation 0 -120 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Constraints: AR AR 10"] - fontStyle USE FS - } - } - ] - } - Form { - size 100 200 - groups [1 -1 2 -1] - constraints ["AR" "AR 10"] - groupsIndex [0 1 -1 1 2 -1] - children [ - USE S1 - USE S2 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-form-align-vert.bt b/regression_tests/bifs-2D-positioning-form-align-vert.bt deleted file mode 100644 index f6e6018..0000000 --- a/regression_tests/bifs-2D-positioning-form-align-vert.bt +++ /dev/null @@ -1,129 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Form node" "with vertical alignment" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Form Test" - } - Transform2D { - translation 0 75 - children [ - DEF FORM Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 200 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Constraints: AT AT 10"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Form { - size 200 100 - groups [1 -1 2 -1] - constraints ["AT" "AT 10"] - groupsIndex [0 1 -1 1 2 -1] - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 30 - } - } - DEF S2 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - ] - } - ] - } - Transform2D { - translation 0 -75 - children [ - USE FORM - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Constraints: AB AB 10"] - fontStyle USE FS - } - } - ] - } - Form { - size 200 100 - groups [1 -1 2 -1] - constraints ["AB" "AB 10"] - groupsIndex [0 1 -1 1 2 -1] - children [ - USE S1 - USE S2 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-form-spread-horiz.bt b/regression_tests/bifs-2D-positioning-form-spread-horiz.bt deleted file mode 100644 index adb335e..0000000 --- a/regression_tests/bifs-2D-positioning-form-spread-horiz.bt +++ /dev/null @@ -1,182 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Form node" "with different horizontal spreads" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Form Test" - } - Transform2D { - translation 0 130 - children [ - DEF FORM Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 200 100 - } - } - Transform2D { - translation 0 -65 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Constraints: AL SH 10"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Form { - size 200 100 - groups [1 -1 2 -1 3 -1] - constraints ["AL" "SH 10"] - groupsIndex [0 1 -1 1 2 3 -1] - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 30 - } - } - DEF S2 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 60 40 - } - } - ] - } - ] - } - Transform2D { - children [ - USE FORM - Transform2D { - translation 0 -65 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Constraints: AL AR SH"] - fontStyle USE FS - } - } - ] - } - Form { - size 200 100 - groups [1 -1 2 -1 3 -1] - constraints ["AL" "AR" "SH"] - groupsIndex [0 1 -1 0 3 -1 1 2 3 -1] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 -130 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 110 100 - } - } - Transform2D { - translation 0 -65 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Constraints: SHin"] - fontStyle USE FS - } - } - ] - } - Form { - size 110 100 - groups [1 -1 2 -1] - constraints ["SHin"] - groupsIndex [1 2 -1] - children [ - Transform2D { - children [ - USE S1 - USE S2 - ] - } - USE S3 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-form-spread-vert.bt b/regression_tests/bifs-2D-positioning-form-spread-vert.bt deleted file mode 100644 index 31cce0a..0000000 --- a/regression_tests/bifs-2D-positioning-form-spread-vert.bt +++ /dev/null @@ -1,170 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Form node" "with different vertical spreads" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Form Test" - } - Transform2D { - translation -120 20 - children [ - DEF FORM Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 100 200 - } - } - Transform2D { - translation 0 -120 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Constraints:" "AT SV 10"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Form { - size 100 200 - groups [1 -1 2 -1 3 -1] - constraints ["AT" "SV 10"] - groupsIndex [0 1 -1 1 2 3 -1] - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 30 - } - } - DEF S2 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 60 40 - } - } - ] - } - ] - } - Transform2D { - translation 0 20 - children [ - USE FORM - Transform2D { - translation 0 -120 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Constraints:" "AT AB SV"] - fontStyle USE FS - } - } - ] - } - Form { - size 100 200 - groups [1 -1 2 -1 3 -1] - constraints ["AT" "AB" "SV"] - groupsIndex [0 1 -1 0 3 -1 1 2 3 -1] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 120 20 - children [ - USE FORM - Transform2D { - translation 0 -120 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Constraints:" "SVin"] - fontStyle USE FS - } - } - ] - } - Form { - size 100 200 - groups [1 -1 2 -1 3 -1] - constraints ["SVin"] - groupsIndex [1 2 3 -1] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layer2D.bt b/regression_tests/bifs-2D-positioning-layer2D.bt deleted file mode 100644 index 630cbd2..0000000 --- a/regression_tests/bifs-2D-positioning-layer2D.bt +++ /dev/null @@ -1,129 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { backColor 1 1 1 } - WorldInfo { - info [ - "This test shows the usage of the Layer2D node." - "A 2D layer is defined with a size 200x200, its content is a grey square and a grey ellipse." - "Within the layer, the content is clipped along the 200x200 rectangle and filled with a red background." - "Behind this layer, a rotated blue rectangle is displayed." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Layer2D - Rectangular Axis Aligned Clipping" - } - Transform2D { - translation 125 125 - children [ - Shape { - appearance Appearance { material Material2D { filled TRUE emissiveColor 1 1 0 } } - geometry Rectangle { size 50 50 } - } - Shape { - appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } - geometry Text { string "Click Me" fontStyle FontStyle { justify [ "MIDDLE" "MIDDLE" ] size 10 }} - } - DEF S TouchSensor {} - ] - } - Transform2D { - rotationAngle 0.57 - children [ - Shape { - appearance Appearance { - material Material2D { - filled TRUE - emissiveColor 0 0 1 - } - } - geometry Rectangle { - size 100 400 - } - } - ] - } - DEF ROT Transform2D { - translation 0 0 - children [ - Layer2D { - size 200 200 - children [ - Background2D { backColor 1 0 0 } - Transform2D { - translation -100 0 - children [ - Shape { - appearance Appearance { - material Material2D { - filled TRUE - } - } - geometry Ellipse { - radius 100 400 - } - } - ] - } - Transform2D { - translation 25 0 - children [ - Shape { - appearance Appearance { - material Material2D { - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - ] - } - ] - } - ] - } - DEF C Conditional { - buffer { - REPLACE TS.startTime BY 0 - } - } - DEF TS TimeSensor { - cycleInterval 5 - startTime -1 - } - DEF SI ScalarInterpolator { - key [0 1] - keyValue [0 1.57] - } - ] -} - -ROUTE S.isActive TO C.activate -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO ROT.rotationAngle - diff --git a/regression_tests/bifs-2D-positioning-layer2d-in-layer2d.bt b/regression_tests/bifs-2D-positioning-layer2d-in-layer2d.bt deleted file mode 100644 index 07c5148..0000000 --- a/regression_tests/bifs-2D-positioning-layer2d-in-layer2d.bt +++ /dev/null @@ -1,111 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFE - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D {backColor 1 1 1} - WorldInfo { - title "Nested Clipping - Layer2D" - info [ - "This test shows nested Layer2D nodes." - "Both layer sizes are animated" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - } - - Transform2D { - translation 100 0 - children [ - DEF L1 Layer2D { - size 300 300 - background Background2D {url 10} - children [ - Shape { - appearance Appearance { material Material2D { filled TRUE } } - geometry DEF RC Rectangle {size 100 75} - } - Transform2D { - translation -150 0 - children [ - DEF L2 Layer2D { - size 100 100 - background Background2D {backColor 0 0 1} - children [ - Shape { - appearance Appearance { material Material2D { emissiveColor 1 0 0 filled TRUE } } - geometry Circle {radius 20} - } - ] - } - ] - } - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval 2.0 - loop TRUE - } - DEF PI1 PositionInterpolator2D { - key [0.0 1.0] - keyValue [400.0 300.0 0.0 0.0] - } - DEF PI2 PositionInterpolator2D { - key [0.0 1.0] - keyValue [100.0 100.0 0.0 0.0] - } - ] -} - - -ROUTE TS.fraction_changed TO PI1.set_fraction -ROUTE PI1.value_changed TO L1.size -ROUTE TS.fraction_changed TO PI2.set_fraction -ROUTE PI2.value_changed TO L2.size - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "./auxiliary_files/sky.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-positioning-layout-horiz-ltr-nowrap.bt b/regression_tests/bifs-2D-positioning-layout-horiz-ltr-nowrap.bt deleted file mode 100644 index fe57b32..0000000 --- a/regression_tests/bifs-2D-positioning-layout-horiz-ltr-nowrap.bt +++ /dev/null @@ -1,403 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 800 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different horizontal justification" "going left to right without line wrap" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -250 160 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 200 60 - } - } - Transform2D { - translation 0 -50 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - size 200 60 - justify ["BEGIN" "BEGIN"] - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation -250 60 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment BEGIN FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["BEGIN" "FIRST"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -250 -40 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["BEGIN" "MIDDLE"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -250 -140 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["BEGIN" "END"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["MIDDLE" "BEGIN"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 60 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment MIDDLE FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["MIDDLE" "FIRST"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 -40 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["MIDDLE" "MIDDLE"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 -140 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["MIDDLE" "END"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 250 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["END" "BEGIN"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 250 60 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment END FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["END" "FIRST"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 250 -40 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["END" "MIDDLE"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 250 -140 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment END END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["END" "END"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-horiz-ltr-wrap-btt.bt b/regression_tests/bifs-2D-positioning-layout-horiz-ltr-wrap-btt.bt deleted file mode 100644 index 28d8317..0000000 --- a/regression_tests/bifs-2D-positioning-layout-horiz-ltr-wrap-btt.bt +++ /dev/null @@ -1,445 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 650 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different horizontal justification" "going left to right with line wrap" "in direction bottom to top and 1.1 line spacing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -200 260 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 140 120 - } - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "BEGIN"] - topToBottom FALSE - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance USE APPTEXT - geometry Text { - string ["Text#2"] - fontStyle USE FS - } - } - DEF S4 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation -200 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "FIRST"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -200 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "MIDDLE"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -200 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "END"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 260 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "BEGIN"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "FIRST"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "MIDDLE"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "END"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 260 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "BEGIN"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "FIRST"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "MIDDLE"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "END"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-horiz-ltr-wrap-ttb.bt b/regression_tests/bifs-2D-positioning-layout-horiz-ltr-wrap-ttb.bt deleted file mode 100644 index 4b415b7..0000000 --- a/regression_tests/bifs-2D-positioning-layout-horiz-ltr-wrap-ttb.bt +++ /dev/null @@ -1,434 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 650 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different horizontal justification" "going left to right with line wrap" "in direction top to bottom and 1.1 line spacing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -200 260 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 140 120 - } - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "BEGIN"] - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance USE APPTEXT - geometry Text { - string ["Text#2"] - fontStyle USE FS - } - } - DEF S4 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation -200 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "FIRST"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -200 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "MIDDLE"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -200 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "END"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 260 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "BEGIN"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "FIRST"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "MIDDLE"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "END"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 260 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "BEGIN"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "FIRST"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "MIDDLE"] - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "END"] - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-horiz-rtl-nowrap.bt b/regression_tests/bifs-2D-positioning-layout-horiz-rtl-nowrap.bt deleted file mode 100644 index 4c06488..0000000 --- a/regression_tests/bifs-2D-positioning-layout-horiz-rtl-nowrap.bt +++ /dev/null @@ -1,415 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 800 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different horizontal justification" "going right to left without line wrap" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -250 160 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 200 60 - } - } - Transform2D { - translation 0 -50 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - size 200 60 - justify ["BEGIN" "BEGIN"] - leftToRight FALSE - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation -250 60 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment BEGIN FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["BEGIN" "FIRST"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -250 -40 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["BEGIN" "MIDDLE"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -250 -140 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["BEGIN" "END"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["MIDDLE" "BEGIN"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 60 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment MIDDLE FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["MIDDLE" "FIRST"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 -40 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["MIDDLE" "MIDDLE"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 -140 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["MIDDLE" "END"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 250 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["END" "BEGIN"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 250 60 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment END FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["END" "FIRST"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 250 -40 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["END" "MIDDLE"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 250 -140 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment END END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 200 60 - justify ["END" "END"] - leftToRight FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-horiz-rtl-wrap-btt.bt b/regression_tests/bifs-2D-positioning-layout-horiz-rtl-wrap-btt.bt deleted file mode 100644 index 817f801..0000000 --- a/regression_tests/bifs-2D-positioning-layout-horiz-rtl-wrap-btt.bt +++ /dev/null @@ -1,469 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 650 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different horizontal justification" "going right to left with line wrap" "in direction bottom to top and 1.1 line spacing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -200 260 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 140 120 - } - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "BEGIN"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance USE APPTEXT - geometry Text { - string ["Text#2"] - fontStyle USE FS - } - } - DEF S4 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation -200 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "FIRST"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -200 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "MIDDLE"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -200 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "END"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 260 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "BEGIN"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "FIRST"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "MIDDLE"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "END"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 260 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "BEGIN"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "FIRST"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "MIDDLE"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "END"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-horiz-rtl-wrap-ttb.bt b/regression_tests/bifs-2D-positioning-layout-horiz-rtl-wrap-ttb.bt deleted file mode 100644 index 0406589..0000000 --- a/regression_tests/bifs-2D-positioning-layout-horiz-rtl-wrap-ttb.bt +++ /dev/null @@ -1,457 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 650 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different horizontal justification" "going right to left with line wrap" "in direction top to bottom and 1.1 line spacing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -200 260 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 140 120 - } - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "BEGIN"] - leftToRight FALSE - spacing 1.1 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance USE APPTEXT - geometry Text { - string ["Text#2"] - fontStyle USE FS - } - } - DEF S4 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation -200 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "FIRST"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -200 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "MIDDLE"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -200 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["BEGIN" "END"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 260 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "BEGIN"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "FIRST"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "MIDDLE"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["MIDDLE" "END"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 260 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "BEGIN"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 100 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END FIRST"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "FIRST"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 -60 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "MIDDLE"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 200 -220 - children [ - USE BOUNDS - Transform2D { - translation 0 -80 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 140 120 - justify ["END" "END"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-horiz-text.bt b/regression_tests/bifs-2D-positioning-layout-horiz-text.bt deleted file mode 100644 index da026b3..0000000 --- a/regression_tests/bifs-2D-positioning-layout-horiz-text.bt +++ /dev/null @@ -1,84 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 650 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing text splitting at word boundaries" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Text Test" - } - Transform2D { - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 160 160 - } - } - Transform2D { - translation 0 -100 - children [ - DEF S Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Sample text use to check if text splitting is ok with layout: aei pqg dtS..."] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 160 160 - justify ["BEGIN" "END"] - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample text used to check if text splitting is ok with layout: aei pqg dtS..."] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-scroll-child.bt b/regression_tests/bifs-2D-positioning-layout-scroll-child.bt deleted file mode 100644 index fe4e35e..0000000 --- a/regression_tests/bifs-2D-positioning-layout-scroll-child.bt +++ /dev/null @@ -1,87 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 800 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node used in another layout" "both perform scrolling" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { size 300 200 } - } - Layout { - size 300 200 - smoothScroll TRUE - loop TRUE - scrollVertical FALSE - scrollRate 0.1 - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { size 100 200 } - } - Layout { - wrap TRUE - size 100 200 - smoothScroll TRUE - loop TRUE - scrollRate 0.2 - children [ - DEF N0 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - USE N0 - USE N0 - ] - } - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-scroll-full.bt b/regression_tests/bifs-2D-positioning-layout-scroll-full.bt deleted file mode 100644 index 3b42b4f..0000000 --- a/regression_tests/bifs-2D-positioning-layout-scroll-full.bt +++ /dev/null @@ -1,344 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 800 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing scrolling in different direction" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -250 160 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 200 60 - } - } - Transform2D { - translation 0 -50 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["scroll smooth vertical"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 200 60 - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollRate 0.1 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation -250 60 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["scroll smooth vertical inverse"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 200 60 - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollRate -0.1 - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -250 -40 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["scroll smooth horizontal"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 200 60 - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollVertical FALSE - scrollRate 0.1 - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -250 -140 - children [ - USE BOUNDS - Transform2D { - translation 0 -50 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["scroll smooth horizontal inverse"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 200 60 - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollVertical FALSE - scrollRate -0.1 - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 120 - children [ - DEF BOUNDS2 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 100 150 - } - } - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["scroll smooth vertical"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 100 150 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollRate 0.1 - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 200 120 - children [ - USE BOUNDS2 - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["scroll smooth vertical inverse"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 100 150 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollRate -0.1 - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 -80 - children [ - USE BOUNDS2 - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["scroll smooth horizontal"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 100 150 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollVertical FALSE - scrollRate 0.1 - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 200 -80 - children [ - USE BOUNDS2 - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["scroll smooth horizontal inverse"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 100 150 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollVertical FALSE - scrollRate -0.1 - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-scroll-modes-horiz.bt b/regression_tests/bifs-2D-positioning-layout-scroll-modes-horiz.bt deleted file mode 100644 index 95163cf..0000000 --- a/regression_tests/bifs-2D-positioning-layout-scroll-modes-horiz.bt +++ /dev/null @@ -1,349 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows an horizontal Layout node" "with different scrolling modes, direction and rates" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team", "(C) 2006 ENST ATG Conformance Streams"] - title "Layout Test" - } - Transform2D { - translation 0 40 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 200 60 - } - } - DEF LAY Layout { - wrap TRUE - size 200 60 - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollVertical FALSE - scrollRate 0.1 - scrollMode -1 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - ] - } - Transform2D { - translation 0 -50 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT_MODE Text { - string ["mode: scroll-in"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 16 - } - } - } - ] - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry DEF TXT_ALIGN Text { - string ["align: begin"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry DEF TXT_DIR Text { - string ["scroll dir: horizontal"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 0 -110 - children [ - Shape { - appearance USE APPTEXT - geometry DEF TXT_RATE Text { - string ["scroll rate: 0.1"] - fontStyle USE FS - } - } - ] - } - ] - } - - Transform2D { - translation -160 80 - children [ - DEF S Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.7 0.7 0.7 - filled TRUE - lineProps LineProperties { lineColor 0 0 0 } - } - } - geometry Rectangle {size 80 20} - } - Shape { - appearance USE APPTEXT - geometry Text { - string ["Begin"] - fontStyle USE FS - } - } - DEF TS_BE TouchSensor {} - ] - } - Transform2D { - translation -160 60 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Middle"] - fontStyle USE FS - } - } - DEF TS_ME TouchSensor {} - ] - } - Transform2D { - translation -160 40 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["End"] - fontStyle USE FS - } - } - DEF TS_EE TouchSensor {} - ] - } - - Transform2D { - translation -160 0 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Scroll In"] - fontStyle USE FS - } - } - DEF TS_SI TouchSensor {} - ] - } - Transform2D { - translation -160 -20 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Scroll InOut"] - fontStyle USE FS - } - } - DEF TS_SIO TouchSensor {} - ] - } - Transform2D { - translation -160 -40 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Scroll Out"] - fontStyle USE FS - } - } - DEF TS_SO TouchSensor {} - ] - } - - Transform2D { - translation 160 80 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Rate>0"] - fontStyle USE FS - } - } - DEF TS_RP TouchSensor {} - ] - } - Transform2D { - translation 160 60 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Rate<0"] - fontStyle USE FS - } - } - DEF TS_RN TouchSensor {} - ] - } - - Transform2D { - translation 160 30 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Horiz"] - fontStyle USE FS - } - } - DEF TS_SH TouchSensor {} - ] - } - Transform2D { - translation 160 10 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Vert"] - fontStyle USE FS - } - } - DEF TS_SV TouchSensor {} - ] - } - - DEF C_BE Conditional { buffer { - REPLACE LAY.justify BY ["BEGIN", "BEGIN"] - REPLACE TXT_ALIGN.string BY ["align: begin"] - } } - DEF C_ME Conditional { buffer { - REPLACE LAY.justify BY ["MIDDLE", "BEGIN"] - REPLACE TXT_ALIGN.string BY ["align: middle"] - } } - DEF C_EE Conditional { buffer { - REPLACE LAY.justify BY ["END", "BEGIN"] - REPLACE TXT_ALIGN.string BY ["align: end"] - } } - - DEF C_SI Conditional { buffer { - REPLACE LAY.scrollMode BY -1 - REPLACE TXT_MODE.string BY ["mode: scroll-in"] - } } - DEF C_SIO Conditional { buffer { - REPLACE LAY.scrollMode BY 0 - REPLACE TXT_MODE.string BY ["mode: scroll-in-out"] - } } - DEF C_SO Conditional { buffer { - REPLACE LAY.scrollMode BY 1 - REPLACE TXT_MODE.string BY ["mode: scroll-out"] - } } - DEF C_RP Conditional { buffer { - REPLACE LAY.scrollRate BY 0.1 - REPLACE TXT_RATE.string BY ["scroll rate: 0.1"] - } } - DEF C_RN Conditional { buffer { - REPLACE LAY.scrollRate BY -0.1 - REPLACE TXT_RATE.string BY ["scroll rate: -0.1"] - } } - DEF C_SH Conditional { buffer { - REPLACE LAY.scrollVertical BY FALSE - REPLACE TXT_DIR.string BY ["scroll dir: horizontal"] - } } - DEF C_SV Conditional { buffer { - REPLACE LAY.scrollVertical BY TRUE - REPLACE TXT_DIR.string BY ["scroll dir: vertical"] - } } - ] -} - -ROUTE TS_BE.isActive TO C_BE.activate -ROUTE TS_ME.isActive TO C_ME.activate -ROUTE TS_EE.isActive TO C_EE.activate - -ROUTE TS_SI.isActive TO C_SI.activate -ROUTE TS_SIO.isActive TO C_SIO.activate -ROUTE TS_SO.isActive TO C_SO.activate - -ROUTE TS_RP.isActive TO C_RP.activate -ROUTE TS_RN.isActive TO C_RN.activate - -ROUTE TS_SH.isActive TO C_SH.activate -ROUTE TS_SV.isActive TO C_SV.activate - diff --git a/regression_tests/bifs-2D-positioning-layout-scroll-modes-vert.bt b/regression_tests/bifs-2D-positioning-layout-scroll-modes-vert.bt deleted file mode 100644 index a10da74..0000000 --- a/regression_tests/bifs-2D-positioning-layout-scroll-modes-vert.bt +++ /dev/null @@ -1,350 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows a vertical Layout node" "with different scrolling modes, direction and rates" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team", "(C) 2006 ENST ATG Conformance Streams"] - title "Layout Test" - } - Transform2D { - translation 0 80 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 60 200 - } - } - DEF LAY Layout { - wrap TRUE - size 60 200 - justify ["BEGIN" "BEGIN"] - horizontal FALSE - smoothScroll TRUE - loop TRUE - scrollVertical FALSE - scrollRate 0.1 - scrollMode -1 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - ] - } - Transform2D { - translation 0 -120 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT_MODE Text { - string ["mode: scroll-in"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 16 - } - } - } - ] - } - Transform2D { - translation 0 -140 - children [ - Shape { - appearance USE APPTEXT - geometry DEF TXT_ALIGN Text { - string ["align: begin"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 0 -160 - children [ - Shape { - appearance USE APPTEXT - geometry DEF TXT_DIR Text { - string ["scroll dir: horizontal"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 0 -180 - children [ - Shape { - appearance USE APPTEXT - geometry DEF TXT_RATE Text { - string ["scroll rate: 0.1"] - fontStyle USE FS - } - } - ] - } - ] - } - - Transform2D { - translation -110 180 - children [ - DEF S Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.7 0.7 0.7 - filled TRUE - lineProps LineProperties { lineColor 0 0 0 } - } - } - geometry Rectangle {size 80 20} - } - Shape { - appearance USE APPTEXT - geometry Text { - string ["Begin"] - fontStyle USE FS - } - } - DEF TS_BE TouchSensor {} - ] - } - Transform2D { - translation -110 160 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Middle"] - fontStyle USE FS - } - } - DEF TS_ME TouchSensor {} - ] - } - Transform2D { - translation -110 140 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["End"] - fontStyle USE FS - } - } - DEF TS_EE TouchSensor {} - ] - } - - Transform2D { - translation -110 100 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Scroll In"] - fontStyle USE FS - } - } - DEF TS_SI TouchSensor {} - ] - } - Transform2D { - translation -110 80 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Scroll InOut"] - fontStyle USE FS - } - } - DEF TS_SIO TouchSensor {} - ] - } - Transform2D { - translation -110 60 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Scroll Out"] - fontStyle USE FS - } - } - DEF TS_SO TouchSensor {} - ] - } - - Transform2D { - translation 110 180 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Rate>0"] - fontStyle USE FS - } - } - DEF TS_RP TouchSensor {} - ] - } - Transform2D { - translation 110 160 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Rate<0"] - fontStyle USE FS - } - } - DEF TS_RN TouchSensor {} - ] - } - - Transform2D { - translation 110 130 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Horiz"] - fontStyle USE FS - } - } - DEF TS_SH TouchSensor {} - ] - } - Transform2D { - translation 110 110 - children [ - USE S - Shape { - appearance USE APPTEXT - geometry Text { - string ["Vert"] - fontStyle USE FS - } - } - DEF TS_SV TouchSensor {} - ] - } - - DEF C_BE Conditional { buffer { - REPLACE LAY.justify BY ["BEGIN", "BEGIN"] - REPLACE TXT_ALIGN.string BY ["align: begin"] - } } - DEF C_ME Conditional { buffer { - REPLACE LAY.justify BY ["MIDDLE", "BEGIN"] - REPLACE TXT_ALIGN.string BY ["align: middle"] - } } - DEF C_EE Conditional { buffer { - REPLACE LAY.justify BY ["END", "BEGIN"] - REPLACE TXT_ALIGN.string BY ["align: end"] - } } - - DEF C_SI Conditional { buffer { - REPLACE LAY.scrollMode BY -1 - REPLACE TXT_MODE.string BY ["mode: scroll-in"] - } } - DEF C_SIO Conditional { buffer { - REPLACE LAY.scrollMode BY 0 - REPLACE TXT_MODE.string BY ["mode: scroll-in-out"] - } } - DEF C_SO Conditional { buffer { - REPLACE LAY.scrollMode BY 1 - REPLACE TXT_MODE.string BY ["mode: scroll-out"] - } } - DEF C_RP Conditional { buffer { - REPLACE LAY.scrollRate BY 0.1 - REPLACE TXT_RATE.string BY ["scroll rate: 0.1"] - } } - DEF C_RN Conditional { buffer { - REPLACE LAY.scrollRate BY -0.1 - REPLACE TXT_RATE.string BY ["scroll rate: -0.1"] - } } - DEF C_SH Conditional { buffer { - REPLACE LAY.scrollVertical BY FALSE - REPLACE TXT_DIR.string BY ["scroll dir: horizontal"] - } } - DEF C_SV Conditional { buffer { - REPLACE LAY.scrollVertical BY TRUE - REPLACE TXT_DIR.string BY ["scroll dir: vertical"] - } } - ] -} - -ROUTE TS_BE.isActive TO C_BE.activate -ROUTE TS_ME.isActive TO C_ME.activate -ROUTE TS_EE.isActive TO C_EE.activate - -ROUTE TS_SI.isActive TO C_SI.activate -ROUTE TS_SIO.isActive TO C_SIO.activate -ROUTE TS_SO.isActive TO C_SO.activate - -ROUTE TS_RP.isActive TO C_RP.activate -ROUTE TS_RN.isActive TO C_RN.activate - -ROUTE TS_SH.isActive TO C_SH.activate -ROUTE TS_SV.isActive TO C_SV.activate - diff --git a/regression_tests/bifs-2D-positioning-layout-scroll-on-off.bt b/regression_tests/bifs-2D-positioning-layout-scroll-on-off.bt deleted file mode 100644 index 57e53c5..0000000 --- a/regression_tests/bifs-2D-positioning-layout-scroll-on-off.bt +++ /dev/null @@ -1,218 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing scrolling with scrool pause/play through scrollRate field" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation 0 -40 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 200 60 - } - } - Transform2D { - translation 0 -50 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["scroll smooth vertical"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 16 - } - } - } - ] - } - DEF LAY Layout { - wrap TRUE - size 200 60 - justify ["BEGIN" "BEGIN"] - smoothScroll TRUE - loop TRUE - scrollRate 0 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation -100 40 - children [ - Shape { - appearance DEF TXT_APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - string ["ScrollRate: 0"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 0 40 - children [ - DEF BACK_RC Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - lineProps LineProperties { - lineColor 0 0 0 - } - } - } - geometry Rectangle { - size 60 25 - } - } - Shape { - appearance USE TXT_APP - geometry Text { - string ["UP"] - fontStyle USE FS - } - } - DEF TS_UP TouchSensor {} - ] - } - Transform2D { - translation 60 40 - children [ - USE BACK_RC - Shape { - appearance USE TXT_APP - geometry Text { - string ["DOWN"] - fontStyle USE FS - } - } - DEF TS_DOWN TouchSensor {} - ] - } - - DEF C_UP Conditional { - buffer { - REPLACE LAY.scrollRate BY 0.1 - REPLACE TXT.string[0] BY "ScrollRate 0.1" - } - } - DEF RC_UP Conditional { - buffer { - REPLACE LAY.scrollRate BY 0 - REPLACE TXT.string[0] BY "ScrollRate 0" - } - } - DEF C2_UP Conditional { - buffer { - REPLACE LAY.scrollRate BY 0.2 - REPLACE TXT.string[0] BY "ScrollRate 0.2" - } - } - DEF RC2_UP Conditional { - buffer { - REPLACE LAY.scrollRate BY 0.1 - REPLACE TXT.string[0] BY "ScrollRate 0.1" - } - } - - DEF C_DOWN Conditional { - buffer { - REPLACE LAY.scrollRate BY -0.1 - REPLACE TXT.string[0] BY "ScrollRate -0.1" - } - } - DEF RC_DOWN Conditional { - buffer { - REPLACE LAY.scrollRate BY 0 - REPLACE TXT.string[0] BY "ScrollRate 0" - } - } - DEF C2_DOWN Conditional { - buffer { - REPLACE LAY.scrollRate BY -0.2 - REPLACE TXT.string[0] BY "ScrollRate -0.2" - } - } - DEF RC2_DOWN Conditional { - buffer { - REPLACE LAY.scrollRate BY -0.1 - REPLACE TXT.string[0] BY "ScrollRate -0.1" - } - } - ] -} - -ROUTE TS_UP.isOver TO C_UP.activate -ROUTE TS_UP.isOver TO RC_UP.reverseActivate -ROUTE TS_UP.isActive TO C2_UP.activate -ROUTE TS_UP.isActive TO RC2_UP.reverseActivate -ROUTE TS_DOWN.isOver TO C_DOWN.activate -ROUTE TS_DOWN.isOver TO RC_DOWN.reverseActivate -ROUTE TS_DOWN.isActive TO C2_DOWN.activate -ROUTE TS_DOWN.isActive TO RC2_DOWN.reverseActivate diff --git a/regression_tests/bifs-2D-positioning-layout-vert-btt-nowrap.bt b/regression_tests/bifs-2D-positioning-layout-vert-btt-nowrap.bt deleted file mode 100644 index b611cbe..0000000 --- a/regression_tests/bifs-2D-positioning-layout-vert-btt-nowrap.bt +++ /dev/null @@ -1,340 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 350 - pixelHeight 650 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different vertical justification" "going bottom to top without column wrap" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -120 230 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 100 150 - } - } - Transform2D { - translation 0 -90 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - topToBottom FALSE - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation 0 230 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 120 230 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["BEGIN" "END"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -120 10 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 10 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 120 10 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["MIDDLE" "END"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -120 -210 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["END" "BEGIN"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 -210 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["END" "MIDDLE"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 120 -210 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["END" "END"] - topToBottom FALSE - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-vert-btt-wrap-ltr.bt b/regression_tests/bifs-2D-positioning-layout-vert-btt-wrap-ltr.bt deleted file mode 100644 index 71d9f12..0000000 --- a/regression_tests/bifs-2D-positioning-layout-vert-btt-wrap-ltr.bt +++ /dev/null @@ -1,372 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 500 - pixelHeight 500 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different vertical justification" "going from bottom to top with column wrap" "in direction left to right and 1.1 column spacing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -170 160 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 150 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - topToBottom FALSE - spacing 1.1 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - DEF S4 Shape { - appearance USE APPTEXT - geometry Text { - string ["#2"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "END"] - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -170 0 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 0 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "END"] - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -170 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "BEGIN"] - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "MIDDLE"] - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "END"] - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-vert-btt-wrap-rtl.bt b/regression_tests/bifs-2D-positioning-layout-vert-btt-wrap-rtl.bt deleted file mode 100644 index 779e57f..0000000 --- a/regression_tests/bifs-2D-positioning-layout-vert-btt-wrap-rtl.bt +++ /dev/null @@ -1,381 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 500 - pixelHeight 500 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different vertical justification" "going bottom to top with column wrap" "in direction right to left and 1.1 column spacing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -170 160 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 150 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - DEF S4 Shape { - appearance USE APPTEXT - geometry Text { - string ["#2"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "END"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -170 0 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 0 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "END"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -170 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "BEGIN"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "MIDDLE"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "END"] - leftToRight FALSE - topToBottom FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-vert-ttb-nowrap.bt b/regression_tests/bifs-2D-positioning-layout-vert-ttb-nowrap.bt deleted file mode 100644 index a7cf1ba..0000000 --- a/regression_tests/bifs-2D-positioning-layout-vert-ttb-nowrap.bt +++ /dev/null @@ -1,331 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 350 - pixelHeight 650 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different vertical justification" "going top to bottom without column wrap" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -120 230 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 100 150 - } - } - Transform2D { - translation 0 -90 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - ] - } - ] - } - Transform2D { - translation 0 230 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 120 230 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["BEGIN" "END"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -120 10 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 10 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 120 10 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["MIDDLE" "END"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation -120 -210 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["END" "BEGIN"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 0 -210 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["END" "MIDDLE"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - Transform2D { - translation 120 -210 - children [ - USE BOUNDS - Transform2D { - translation 0 -90 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - size 100 150 - horizontal FALSE - justify ["END" "END"] - children [ - USE S1 - USE S2 - USE S3 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-vert-ttb-wrap-ltr.bt b/regression_tests/bifs-2D-positioning-layout-vert-ttb-wrap-ltr.bt deleted file mode 100644 index 915a78f..0000000 --- a/regression_tests/bifs-2D-positioning-layout-vert-ttb-wrap-ltr.bt +++ /dev/null @@ -1,363 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 500 - pixelHeight 500 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different vertical justification" "going top to bottom with column wrap" "in direction left to right and 1.1 column spacing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -170 160 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 150 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - spacing 1.1 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - DEF S4 Shape { - appearance USE APPTEXT - geometry Text { - string ["#2"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "END"] - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -170 0 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 0 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "END"] - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -170 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "BEGIN"] - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "MIDDLE"] - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "END"] - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-layout-vert-ttb-wrap-rtl.bt b/regression_tests/bifs-2D-positioning-layout-vert-ttb-wrap-rtl.bt deleted file mode 100644 index ba9ac3c..0000000 --- a/regression_tests/bifs-2D-positioning-layout-vert-ttb-wrap-rtl.bt +++ /dev/null @@ -1,372 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 500 - pixelHeight 500 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Layout node" "performing different vertical justification" "going top to bottom with column wrap" "in direction right to left and 1.1 column spacing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Layout Test" - } - Transform2D { - translation -170 160 - children [ - DEF BOUNDS Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 150 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF APPTEXT Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Alignment" "BEGIN BEGIN"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 16 - } - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "BEGIN"] - leftToRight FALSE - spacing 1.1 - children [ - DEF S1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - DEF S2 Shape { - appearance USE APPTEXT - geometry Text { - string ["Sample Text"] - fontStyle USE FS - } - } - DEF S3 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } - DEF S4 Shape { - appearance USE APPTEXT - geometry Text { - string ["#2"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "BEGIN END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["BEGIN" "END"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -170 0 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 0 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "MIDDLE END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["MIDDLE" "END"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation -170 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END BEGIN"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "BEGIN"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 0 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END MIDDLE"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "MIDDLE"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - Transform2D { - translation 170 -160 - children [ - USE BOUNDS - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE APPTEXT - geometry Text { - string ["Alignment" "END END"] - fontStyle USE FS - } - } - ] - } - Layout { - wrap TRUE - size 150 100 - horizontal FALSE - justify ["END" "END"] - leftToRight FALSE - spacing 1.1 - children [ - USE S1 - USE S2 - USE S3 - USE S4 - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-orderedgroup.bt b/regression_tests/bifs-2D-positioning-orderedgroup.bt deleted file mode 100644 index 8725f1a..0000000 --- a/regression_tests/bifs-2D-positioning-orderedgroup.bt +++ /dev/null @@ -1,86 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 0 - } - WorldInfo { - info [ - "This test shows the usage of the OrderedGroup node." - "The OrderedGroup node is similar to the Group node but allows for more possibilities." - "The difference is the addition of the 'order' property which explicitely gives the display order of the children of the OrderedGroup." - "Order varies from 0 to N-1, where N is the number of children. [3 2 1 0] will display the children in reverse order." - "This test shows how to interactively change the order based on a click." - "If you click on the rectangle or the circle, and keep the mouse button down, the display order is reversed. If you release the button, the display order goes back to initial." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "OrderedGroup" - } - DEF OG OrderedGroup { - order [1 0] - children [ - DEF S1 Shape { - appearance DEF A1 Appearance { - material Material2D { - emissiveColor 1 1 1 - filled TRUE - } - } - geometry Rectangle { - size 160 60 - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - } - geometry Circle { - radius 40 - } - } - DEF TS TouchSensor {} - ] - } - DEF C Conditional { - buffer { - REPLACE OG.order BY [0 1] - } - } - DEF RC Conditional { - buffer { - REPLACE OG.order BY [1 0] - } - } - ] -} - -ROUTE TS.isActive TO C.activate -ROUTE TS.isActive TO RC.reverseActivate - diff --git a/regression_tests/bifs-2D-positioning-pathlayout.bt b/regression_tests/bifs-2D-positioning-pathlayout.bt deleted file mode 100644 index 0293a8d..0000000 --- a/regression_tests/bifs-2D-positioning-pathlayout.bt +++ /dev/null @@ -1,164 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows PathLayout usage" "with text and graphics layout" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "PathLayout Test" - } - Transform2D { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - filled TRUE - } - } - geometry DEF LS Curve2D { - fineness 1 - type [2] - point DEF C2D Coordinate2D { - point [-100 0 -50 400 50 -400 100 0] - } - } - } - DEF TOUCH TouchSensor {} - ] - } - DEF PL PathLayout { - alignment [0 1] - pathOffset 0.25 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["text and "] - fontStyle DEF FS FontStyle { - size 20 - } - } - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 30 20 - } - } - DEF TSSTOP TouchSensor {} - ] - } - Shape { - appearance USE APP - geometry Text { - string ["along a path"] - fontStyle USE FS - } - } - ] - geometry USE LS - } - ] - } - Transform2D { - translation 0 -140 - children [ - Shape { - appearance USE APP - geometry Text { - string ["move over shape and click" "to change the layout wrapping mode"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 20 - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [-0.5 1.5 -0.5] - } - DEF C1 Conditional { - buffer { - REPLACE PL.wrapMode BY 1 - } - } - DEF RC1 Conditional { - buffer { - REPLACE PL.wrapMode BY 0 - } - } - DEF C2 Conditional { - buffer { - REPLACE PL.wrapMode BY 2 - } - } - DEF RC2 Conditional { - buffer { - REPLACE PL.wrapMode BY 1 - } - } - DEF C3 Conditional { - buffer { - REPLACE TS.enabled BY FALSE - } - } - DEF RC3 Conditional { - buffer { - REPLACE TS.enabled BY TRUE - } - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO PL.pathOffset -ROUTE TSSTOP.isOver TO C3.activate -ROUTE TSSTOP.isOver TO RC3.reverseActivate -ROUTE TOUCH.isOver TO C1.activate -ROUTE TOUCH.isOver TO RC1.reverseActivate -ROUTE TOUCH.isActive TO C2.activate -ROUTE TOUCH.isActive TO RC2.reverseActivate - diff --git a/regression_tests/bifs-2D-positioning-transform2D.bt b/regression_tests/bifs-2D-positioning-transform2D.bt deleted file mode 100644 index 427f3a9..0000000 --- a/regression_tests/bifs-2D-positioning-transform2D.bt +++ /dev/null @@ -1,133 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to apply affine transformations on a rectangle." - "A graphical object can be moved, rotated or scaled using the Transform2D node." - "The object (or objects) to be transformed is (are) placed in the children property of the Transform2D node." - "The Transform2D node indicates the transformation from the local coordinate system to the global coordinate system. It applies to any graphical object." - "Possible transformations are limited to translation, rotation (including with a center different from the origin) and scaling (including along different axes that original system) using respectively the translation, rotationAngle, center, scale, scaleOrientation." - "For skewing, you should see the TransformMatrix2D node." - "cf bifs-2D-positioning-transformmatrix2D" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team"] - title "Apply transformations on local coordinate systems - Transform2D node" - } - Transform2D { - translation -100 150 - children [ - Transform2D { - children [ - DEF RECT Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry Rectangle { - size 150 100 - } - } - ] - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Rectangle" "translation only"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 12 - } - } - } - ] - } - ] - } - Transform2D { - translation 100 0 - children [ - Transform2D { - scale 1 1.5 - scaleOrientation 1 - children [ - USE RECT - ] - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Scale 1.0 1.5" "Scale Orientation 1.0"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation -100 -100 - children [ - Transform2D { - rotationAngle 1 - scale 1 1.5 - children [ - USE RECT - ] - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Scale 1.0 1.5" "rotation 1.0"] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-positioning-transformmatrix2D.bt b/regression_tests/bifs-2D-positioning-transformmatrix2D.bt deleted file mode 100644 index ad87b05..0000000 --- a/regression_tests/bifs-2D-positioning-transformmatrix2D.bt +++ /dev/null @@ -1,179 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 550 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to apply affine transformations on a rectangle." - "The TransformMatrix2D works like the Transform2D node, but it requires giving the coefficients of a 3x2 matrix." - "It allows for skewing and for simple animations of skewing." - "Click on the transformed rectangles to start transformation animations." - "cf bifs-2D-positioning-transform2D" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.4 $" - "(C) 2002-2006 GPAC Team" - ] - title "Apply transformations on local coordinate systems - TransformMatrix2D node" - } - TransformMatrix2D { - tx 175 - ty 80 - children [ - DEF N1 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 200 100 - } - } - Shape { - appearance DEF N7 Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["translated rectangle"] - fontStyle DEF N0 FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 15 - } - } - } - ] - } - DEF N12 TransformMatrix2D { - mxx 0.707107 - mxy 0.707107 - tx -150 - myx -0.707107 - myy 0.707107 - ty 80 - children [ - USE N1 - Shape { - appearance USE N7 - geometry Text { - string ["translated" "and" "Pi/4-rotated rectangle"] - fontStyle USE N0 - } - } - DEF N17 TouchSensor {} - DEF N4 TimeSensor { - cycleInterval 2 - startTime -1 - } - DEF N9 ScalarInterpolator { - key [0 1] - keyValue [0.707107 1] - } - DEF N8 ScalarInterpolator { - key [0 1] - keyValue [0.707107 0] - } - DEF N6 ScalarInterpolator { - key [0 1] - keyValue [-0.707107 0] - } - DEF N5 ScalarInterpolator { - key [0 1] - keyValue [0.707107 1] - } - ] - } - DEF N11 TransformMatrix2D { - mxy 1 - tx 120 - ty -80 - children [ - USE N1 - Shape { - appearance USE N7 - geometry Text { - string ["translated" "and" "Pi/4-X-Skewed rectangle"] - fontStyle USE N0 - } - } - DEF N15 TouchSensor {} - DEF N3 TimeSensor { - cycleInterval 2 - startTime -1 - } - DEF N16 ScalarInterpolator { - key [0 1] - keyValue [1 0] - } - ] - } - DEF N10 TransformMatrix2D { - tx -50 - myx 1 - ty -50 - children [ - USE N1 - Shape { - appearance USE N7 - geometry Text { - string ["translated" "and" "Pi/4-Y-Skewed rectangle"] - fontStyle USE N0 - } - } - DEF N14 TouchSensor {} - DEF N2 TimeSensor { - cycleInterval 2 - startTime -1 - } - DEF N13 ScalarInterpolator { - key [0 1] - keyValue [1 0] - } - ] - } - ] -} - -ROUTE N17.touchTime TO N4.startTime -ROUTE N4.fraction_changed TO N9.set_fraction -ROUTE N9.value_changed TO N12.mxx -ROUTE N4.fraction_changed TO N8.set_fraction -ROUTE N8.value_changed TO N12.mxy -ROUTE N4.fraction_changed TO N6.set_fraction -ROUTE N6.value_changed TO N12.myx -ROUTE N4.fraction_changed TO N5.set_fraction -ROUTE N5.value_changed TO N12.myy -ROUTE N15.touchTime TO N3.startTime -ROUTE N3.fraction_changed TO N16.set_fraction -ROUTE N16.value_changed TO N11.mxy -ROUTE N14.touchTime TO N2.startTime -ROUTE N2.fraction_changed TO N13.set_fraction -ROUTE N13.value_changed TO N10.myx - diff --git a/regression_tests/bifs-2D-shapes-all.bt b/regression_tests/bifs-2D-shapes-all.bt deleted file mode 100644 index 44d61c2..0000000 --- a/regression_tests/bifs-2D-shapes-all.bt +++ /dev/null @@ -1,267 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 460 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "The MPEG-4 primitive to display graphical objects on screen is the Shape node." - "The Shape node is allowed to have a child node contained in its geometry property." - "This test shows the possible 2D nodes allowed in this geometry property:" - "* IndexedLineSet2D: this node is used to draw polylines. This geometry is not considered closed, even if last point is equal to first point. As such, it cannot be filled. The origin of its local coordinate system is the point of coordinate (0,0)." - "* Circle: its only property is its radius. The origin of its local coordinate system is the center of the circle." - "* Rectangle: its only property is its size (WxH). The origin of its local coordinate system is the center of the rectangle." - "* Curve2D (middle row): this node is used to display complex paths using Bezier Curves. It has two properties: type, points. Type gives the drawing types (segments or bezier), points gives the list of points to be consumed when reading the types. The node XCurve2D allows more drawing types (elliptical arcs ...):" - "cf bifs-2D-shapes-xcurve2D" - "* IndexedFaceSet2D: this node is similar to the IndexedLineSet2D node. It is used to display polygons (i.e. a list of segments implicitely closed by the segment [last point, first point]). The origin of its local coordinate system is the point of coordinate (0,0)." - "cf bifs-2D-shapes-indexfaceset2D" - "* PointSet2D: a list of points to be displayed (not really useful)" - "" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 15:19:18 $ - $Revision: 1.5 $" - "(C) 2002-2006 GPAC Team" - ] - title "Basic 2D Geometry nodes" - } - Transform2D { - translation -150 150 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - } - } - geometry IndexedLineSet2D { - coord Coordinate2D { - point [-50 0 0 50 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["IndexedLineSet2D" "[-50 0 0 50 50 0]"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 12 - } - } - } - ] - } - ] - } - Transform2D { - translation 0 150 - children [ - Shape { - appearance USE APP - geometry Circle { - radius 50 - } - } - Transform2D { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Circle" "radius 50"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 150 150 - children [ - Shape { - appearance USE APP - geometry Rectangle { - size 100 50 - } - } - Transform2D { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Rectangle" "Size 100 50"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -40 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Curve2D Points:" "-50 0, -100 50, 0 20, 10 30, 40 80, 50 0"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -150 0 - children [ - Shape { - appearance USE APP - geometry Curve2D { - point DEF C2D Coordinate2D { - point [-50 0 -100 50 0 20 10 30 40 80 50 0] - } - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["no type"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 3] - point USE C2D - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["type [2 3]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 170 0 - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [1 3 1] - point USE C2D - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["type [1 3 1]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation -150 -150 - children [ - Shape { - appearance USE APP - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-50 0 -25 25 0 80 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["IndexedFaceSet2D" "-50 0, -25, 25, 0 80, 50 0"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance USE APP - geometry PointSet2D { - coord Coordinate2D { - point [-50 0 -25 25 0 80 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["PointSet2D" "-50 0, -25, 25, 0 80, 50 0"] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-shapes-indexfaceset2D.bt b/regression_tests/bifs-2D-shapes-indexfaceset2D.bt deleted file mode 100644 index 49711fa..0000000 --- a/regression_tests/bifs-2D-shapes-indexfaceset2D.bt +++ /dev/null @@ -1,123 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 420 - pixelHeight 420 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows a bit more how to use the IndexedFaceSet2D node with different color fill modes." - "This node can hold a Coordinate2D node to list points and use the coordIndex field to form faces (-1 separated indexes)." - "Each face can have different color. If colorPerVertex is TRUE each point has a separate color and the result is that a face is filled using color interpolation." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "IndexedFaceSet2D and Color Modes" - } - Transform2D { - scale 0.8 0.8 - translation -120 120 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - lineProps DEF LP LineProperties { - width 6 - } - } - } - geometry IndexedFaceSet2D { - colorIndex [0 1 2 3 4 5] - coordIndex [0 1 2 3 4 5] - color Color { - color [0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1] - } - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - Transform2D { - scale 0.8 0.8 - translation 120 120 - children [ - Shape { - appearance Appearance { - material Material2D { - filled TRUE - } - } - geometry IndexedFaceSet2D { - colorIndex [0 1 2 3 4 5] - coordIndex [0 1 2 3 4 5] - color Color { - color [0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1] - } - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - Transform2D { - scale 0.8 0.8 - translation -120 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps USE LP - } - } - geometry DEF IFS2 IndexedFaceSet2D { - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - Transform2D { - scale 0.8 0.8 - translation 120 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - filled TRUE - } - } - geometry USE IFS2 - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-shapes-indexlineset2D.bt b/regression_tests/bifs-2D-shapes-indexlineset2D.bt deleted file mode 100644 index 3fe8886..0000000 --- a/regression_tests/bifs-2D-shapes-indexlineset2D.bt +++ /dev/null @@ -1,100 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 420 - pixelHeight 420 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows a bit more how to use the IndexedLineSet2D node with different line color modes." - "Similarly to the IndexedFaceSet2D, one can give a color to each point." - "The result will be a line with a gradient color" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team"] - title "IndexedLineSet2D" - } - Transform2D { - scale 0.5 0.5 - translation -120 80 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0.1 0.1 0.8 - width 10 - } - } - } - geometry IndexedLineSet2D { - colorIndex [1 0 2 1 -1 1 0 2 1] - coordIndex [0 1 2 0 -1 3 4 5 3] - color Color { - color [1 1 0 1 0 1 0 1 1] - } - coord DEF COORD Coordinate2D { - point [-100 -100 0 -10 100 -100 100 100 0 10 -100 100] - } - } - } - ] - } - Transform2D { - scale 0.5 0.5 - translation 120 80 - children [ - Shape { - appearance USE APP - geometry IndexedLineSet2D { - colorIndex [1 0 2 -1 0 2 1] - colorPerVertex FALSE - coordIndex [0 1 2 0 -1 3 4 5 3] - color Color { - color [1 1 0 1 0 1 0 1 1] - } - coord USE COORD - } - } - ] - } - Transform2D { - scale 0.5 0.5 - translation 0 -80 - children [ - Shape { - appearance USE APP - geometry IndexedLineSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 0 -1 3 4 5 3] - coord USE COORD - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-shapes-pointset2D.bt b/regression_tests/bifs-2D-shapes-pointset2D.bt deleted file mode 100644 index 53b77ef..0000000 --- a/regression_tests/bifs-2D-shapes-pointset2D.bt +++ /dev/null @@ -1,56 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This shows the use of PointSet2D which is to display individual pixels on the screen." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "PointSet2D" - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - } - } - geometry PointSet2D { - coord DEF COORD Coordinate2D { - point [-0.25 -0.25 0.25 -0.25 0.25 0.25 -0.25 0.25] - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-shapes-xcurve2D.bt b/regression_tests/bifs-2D-shapes-xcurve2D.bt deleted file mode 100644 index 225d35e..0000000 --- a/regression_tests/bifs-2D-shapes-xcurve2D.bt +++ /dev/null @@ -1,188 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This shows the use of XCurve2D." - "This node is an extension of the Curve2D node. It allows more drawing types: quadratic Bezier curves and elliptical arcs." - "Both XCurve2D and Curve2D are similar to IndexedFaceSet2D and IndexedLineSet2D because they can be used to represent polygons and polylines. The difference is that it is not possible to assign a color or texture per point, nor a color per closed path. " - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "XCurve2D" - } - Transform2D { - translation -150 140 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - width 8 - } - } - } - geometry XCurve2D { - type [4] - point Coordinate2D { - point [0 0 40 0 40 0 40 40] - } - } - } - Transform2D { - translation 40 -60 - children [ - Shape { - appearance DEF TXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["anti-clockwise arc to" "point [0 0 40 0 40 0 40 40]"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] - } - Transform2D { - translation 50 140 - children [ - Shape { - appearance USE APP - geometry XCurve2D { - type [5] - point Coordinate2D { - point [0 0 40 0 40 0 40 40] - } - } - } - Transform2D { - translation 40 -60 - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["clockwise arc to" "point [0 0 40 0 40 0 40 40]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation -150 0 - children [ - Shape { - appearance USE APP - geometry XCurve2D { - type [7] - point Coordinate2D { - point [0 0 40 40 80 0] - } - } - } - Transform2D { - translation 40 -30 - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["Quadratic Bezier arc to" "point [0 0 40 40 80 0 ]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 50 0 - children [ - Shape { - appearance USE APP - geometry XCurve2D { - type [7 6] - point Coordinate2D { - point [0 0 40 40 80 0] - } - } - } - Transform2D { - translation 40 -30 - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["Quadratic Bezier arc to" "with close path"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation -50 -120 - children [ - Shape { - appearance USE APP - geometry XCurve2D { - type [7 1] - point Coordinate2D { - point [0 0 40 40 80 0 0 0] - } - } - } - Transform2D { - translation 40 -30 - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["Quadratic Bezier arc to" "without close path (lineTo origin)"] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-texturing-compositetexture2D-background.bt b/regression_tests/bifs-2D-texturing-compositetexture2D-background.bt deleted file mode 100644 index 2e67628..0000000 --- a/regression_tests/bifs-2D-texturing-compositetexture2D-background.bt +++ /dev/null @@ -1,116 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the usage of the CompositeTexture node and how its background can be changed dynamically." - "Here, the texture is a circle repeated on the X and Y directions. Just one circle object is used here, the result of the drawing is translated in each directions, the object is not duplicated." - "When the user moves the mouse over a circle, the background is changed. When the user clicks on a circle, the background is also changed." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "CompositeTexture and Background2D nodes" - } - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 0 1 0 - } - texture CompositeTexture2D { - pixelWidth 64 - pixelHeight 64 - children [ - DEF B1 Background2D { backColor 0 1 1 } - DEF B2 Background2D { backColor 1 1 0 } - DEF B3 Background2D { backColor 1 0 0 } - DEF S Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - transparency 0.5 - } - } - geometry Circle { - radius 24 - } - } - DEF TS TouchSensor {} - ] - } - textureTransform TextureTransform { scale 8 4 } - } - geometry Rectangle { size 300 150 } - } - - Transform2D { - translation 140 -110 - children [ - USE S - Transform2D { - translation 0 -50 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Composite Texture Pattern" "Black color with 0.5 transparency"] - fontStyle DEF FS FontStyle { - family ["SANS"] - justify ["MIDDLE" "BEGIN"] - size 20 - } - } - } - ] - } - ] - } - Transform2D { - translation -150 160 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Move mouse over texture" "to change texture background"] - fontStyle USE FS - } - } - ] - } - ] -} - -ROUTE TS.isOver TO B2.set_bind -ROUTE TS.isActive TO B3.set_bind - diff --git a/regression_tests/bifs-2D-texturing-compositetexture2D-bitmap.bt b/regression_tests/bifs-2D-texturing-compositetexture2D-bitmap.bt deleted file mode 100644 index 3f7c1bd..0000000 --- a/regression_tests/bifs-2D-texturing-compositetexture2D-bitmap.bt +++ /dev/null @@ -1,89 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the usage of the CompositeTexture node." - "It allows defining a texture made of vector graphics objects, and to use the texture like images or video. It enables using hardware acceleration for texture operations." - "In mixed 3D/2D environment, it allows mapping 2D graphics on 3D objects." - "Texture in general may be repeated without the complexity of duplicating and translating the objects." - "Here, the texture is an animated circle on a red background. The resulting texture is used on a Bitmap node." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "CompositeTexture and Bitmap nodes" - } - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 0 1 0 - } - texture CompositeTexture2D { - pixelWidth 100 - pixelHeight 100 - background Background2D { backColor 1 0 0} - children [ - DEF S Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE -# transparency 0.5 - lineProps LineProperties { width 0 } - } - } - geometry DEF C Circle { - radius 20 - } - } - ] - } - } - geometry Bitmap {scale 2 2} - } - - Transform2D { - translation 200 0 - children [ - USE S - ] - } - DEF TS TimeSensor { - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [25 10 25] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO C.radius - diff --git a/regression_tests/bifs-2D-texturing-compositetexture2D-transparent.bt b/regression_tests/bifs-2D-texturing-compositetexture2D-transparent.bt deleted file mode 100644 index e04a8e6..0000000 --- a/regression_tests/bifs-2D-texturing-compositetexture2D-transparent.bt +++ /dev/null @@ -1,131 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - DEF B Background2D { - backColor 1 1 0 - } - WorldInfo { - info [ - "This test shows how transparency applies to composite textures." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "CompositeTexture and Transparency" - } - Transform2D { - translation -20 80 - rotationAngle 0.57 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { size 380 40 } - } - ] - } - Transform2D { - translation -20 80 - children [ - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 0 1 0 - } - texture CompositeTexture2D { - pixelWidth 100 - pixelHeight 100 - children [ - DEF S Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - transparency 0.5 - } - } - geometry Circle { - radius 50 - } - } - DEF TS TouchSensor {} - ] - } - textureTransform TextureTransform { - scale 8 4 - } - } - #geometry Curve2D { type [2] point Coordinate2D { point [-300 0 -150 -500 150 500 300 0] } } - geometry Rectangle { size 300 150 } - } - ] - } - Transform2D { - translation 140 -100 - children [ - USE S - Transform2D { - translation 0 -50 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Composite Texture Pattern" "Black Circle Half-Transparent"] - fontStyle DEF FS FontStyle { - family ["SANS"] - justify ["MIDDLE" "BEGIN"] - size 20 - } - } - } - ] - } - ] - } - DEF C Conditional { - buffer { - REPLACE B.backColor BY 1 0 0 - } - } - DEF RC Conditional { - buffer { - REPLACE B.backColor BY 1 1 0 - } - } - ] -} - -ROUTE TS.isActive TO C.activate -ROUTE TS.isActive TO RC.reverseActivate - diff --git a/regression_tests/bifs-2D-texturing-gradients-text.bt b/regression_tests/bifs-2D-texturing-gradients-text.bt deleted file mode 100644 index 86567ca..0000000 --- a/regression_tests/bifs-2D-texturing-gradients-text.bt +++ /dev/null @@ -1,137 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test uses a Viewport node, Gradient nodes and animation and TransformMatrix2D node in a text mirroring-like effect." - "" - "GPAC Regression Tests" "$Date: 2008/10/31 18:08:50 $ - $Revision: 1.7 $" - "(C) 2002-2006 GPAC Team" - ] - title "Text Mirroring Effect" - } - Viewport { - size 200 200 - description "Initial Viewport" - } -#if 0 - Viewport { - position -30 20 - size 50 50 - description "Text Center View" - } - Viewport { - position 75 0 - size 50 50 - description "Blending Zone View" - } -#endif - - DEF TR Transform2D { - children [ - DEF PS PlaneSensor2D { - maxPosition 100 100 - minPosition -100 0 - } - Transform2D { - translation 2 -2 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - transparency 0 - filled TRUE - } - } - geometry DEF T Text { - string ["Gradient" "Text Demo"] - fontStyle FontStyle { - justify ["MIDDLE" "END"] - size 30 - style "BOLD" - } - } - } - ] - } - DEF TESTSHAPE Shape { - appearance Appearance { - texture RadialGradient { - focalPoint 0.35 0.55 - key [0 0.7 1] - keyValue [0 1 0.5 0 0.5 1 0 1 1] - radius 0.8 - } - } - geometry USE T - } - ] - } - TransformMatrix2D { - mxy 1.5 - myy -1 - children [ - USE TR - ] - } - Transform2D { - translation 0 -100 - children [ - Shape { - appearance Appearance { - texture RadialGradient { - center 0.5 1 - focalPoint 0.5 1 - key [0 0.5 1] - keyValue [1 1 0 0.8 0 0.2 0.8 0 0.2] - opacity [0.8 1 1] - radius 1.2 - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - DEF TIME TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF PI PositionInterpolator2D { - key [0 0.5 1] - keyValue [1 1 1 0.75 1 1] - } - ] -} - -ROUTE PS.translation_changed TO TR.translation -ROUTE TIME.fraction_changed TO PI.set_fraction -ROUTE PI.value_changed TO TR.scale - diff --git a/regression_tests/bifs-2D-texturing-gradients-transparent.bt b/regression_tests/bifs-2D-texturing-gradients-transparent.bt deleted file mode 100644 index 58a5add..0000000 --- a/regression_tests/bifs-2D-texturing-gradients-transparent.bt +++ /dev/null @@ -1,120 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This shows usage of transparency with gradient" - "Move the rectangle over the circle to see that the gradient is not uniformly transparent." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Gradient and Transparency" - } - DEF TR Transform2D { - translation 200 50 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - width 0 - } - } - texture DEF GL LinearGradient { - endPoint 1 1 - key [0 0.4 1] - keyValue [0 0 1 1 0 1 0 1 1] - spreadMethod 1 - } - } - geometry Rectangle { - size 200 200 - } - } - DEF PS PlaneSensor2D { - maxPosition 300 300 - minPosition -300 -300 - offset 200 50 - } - ] - } - Transform2D { - scale 1 1.2 - translation -50 0 - children [ - Shape { - appearance Appearance { - texture RadialGradient { - focalPoint 0.75 0.5 - key [0 0.6 1] - keyValue [1 1 1 1 0 0 1 1 0] - opacity [1 1 0.3] - } - } - geometry Circle { - radius 100 - } - } - ] - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Drag square around screen"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF C PositionInterpolator2D { - key [0 0.5 1] - keyValue [1 1 1 0 1 1] - } - ] -} - -ROUTE TS.fraction_changed TO C.set_fraction -ROUTE C.value_changed TO GL.endPoint -ROUTE PS.translation_changed TO TR.translation - diff --git a/regression_tests/bifs-2D-texturing-imagetexture-shapes.bt b/regression_tests/bifs-2D-texturing-imagetexture-shapes.bt deleted file mode 100644 index 7abc7f5..0000000 --- a/regression_tests/bifs-2D-texturing-imagetexture-shapes.bt +++ /dev/null @@ -1,282 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 440 - pixelHeight 440 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows image displayed on the basic 2D shapes." - "Image is considered as a texture and described in the ImageTexture node." - "The url of this node points to the image using any internet protocol (http, rtsp) or using MPEG-4 OD." - "The ImageTexture node is associated to the geometry as a children of the Shape node. The image is then clipped along the bounding box of the shape." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Displaying Images as a texture on any shape" - } - Transform2D { - translation -150 150 - children [ - Shape { - appearance DEF APP Appearance { - texture ImageTexture { - url [od:10] - } - } - geometry IndexedLineSet2D { - coord Coordinate2D { - point [-50 0 0 50 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["IndexedLineSet2D" "[-50 0 0 50 50 0]"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 12 - } - } - } - ] - } - ] - } - Transform2D { - translation 0 150 - children [ - Shape { - appearance USE APP - geometry Circle { - radius 50 - } - } - Transform2D { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Circle" "radius 50"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 150 150 - children [ - Shape { - appearance USE APP - geometry Rectangle { - size 100 50 - } - } - Transform2D { - translation 0 -40 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Rectangle" "Size 100 50"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -40 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Curve2D Points:" "-50 0, -100 50, 0 20, 10 30, 40 80, 50 0"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -150 0 - children [ - Shape { - appearance USE APP - geometry Curve2D { - point DEF C2D Coordinate2D { - point [-50 0 -100 50 0 20 10 30 40 80 50 0] - } - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["no type"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 3] - point USE C2D - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["type [2 3]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 170 0 - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [1 3 1] - point USE C2D - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["type [1 3 1]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation -150 -150 - children [ - Shape { - appearance USE APP - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-50 0 -25 25 0 80 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["IndexedFaceSet2D" "-50 0, -25, 25, 0 80, 50 0"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance USE APP - geometry PointSet2D { - coord Coordinate2D { - point [-50 0 -25 25 0 80 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["PointSet2D" "-50 0, -25, 25, 0 80, 50 0"] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-texturing-lineargradient-simple.bt b/regression_tests/bifs-2D-texturing-lineargradient-simple.bt deleted file mode 100644 index ae295b7..0000000 --- a/regression_tests/bifs-2D-texturing-lineargradient-simple.bt +++ /dev/null @@ -1,75 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 500 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to fill object with linear gradients." - "Here the start and end point of the gradient are close" - "You can click on the rectangle to move the start and the end of gradient." - "You can also drag it." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Linear Gradient" - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - width 0 - } - } - texture DEF GL LinearGradient { - key [0 0.45 0.5 0.55 1] - keyValue [0.2118 0.447 0.039 0.2118 0.447 0.039 0.2627 0.933 0 0.2392 0.3098 0.04313 0.2392 0.3098 0.04313] - startPoint -1 0 - } - } - geometry DEF R Rectangle { - size 400 20 - } - } - DEF TS TouchSensor {} - ] - } - DEF SC Script { - eventIn SFVec3f set_frac - eventIn SFBool set_down - field SFNode grad USE GL - field SFBool isDown FALSE - url ["javascript:function set_down(value, timestamp) {isDown = value;}function set_frac(value, timestamp) {if (!isDown) return;pos = (value.x + 200)/400;grad.startPoint.x = pos - 1;grad.endPoint.x = 1 + pos;print('pos ' + pos);}" ] - } - ] -} - -ROUTE TS.isActive TO SC.set_down -ROUTE TS.hitPoint_changed TO SC.set_frac - diff --git a/regression_tests/bifs-2D-texturing-lineargradient-spread.bt b/regression_tests/bifs-2D-texturing-lineargradient-spread.bt deleted file mode 100644 index fe3f212..0000000 --- a/regression_tests/bifs-2D-texturing-lineargradient-spread.bt +++ /dev/null @@ -1,113 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the different methods for spreading the gradients when the size of the object to be filled is large" - "The end point of the gradient is also animated to change the gradient aspect." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Linear Gradient Spread Methods" - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Move over and click" "to change the spread method"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF GL LinearGradient { - endPoint 0 0.5 - key [0 0.5 1] - keyValue [0 0 1 1 0 0 0 1 0] - } - } - geometry Circle { - radius 100 - } - } - DEF TS TouchSensor {} - ] - } - DEF C Conditional { - buffer { - REPLACE GL.spreadMethod BY 1 - } - } - DEF RC Conditional { - buffer { - REPLACE GL.spreadMethod BY 0 - } - } - DEF C2 Conditional { - buffer { - REPLACE GL.spreadMethod BY 2 - } - } - DEF RC2 Conditional { - buffer { - REPLACE GL.spreadMethod BY 1 - } - } - DEF TIME TimeSensor { - cycleInterval 4 - loop TRUE - } - DEF CI PositionInterpolator2D { - key [0 0.5 1] - keyValue [0 0.5 1 0.5 0 0.5] - } - ] -} - -ROUTE TS.isOver TO C.activate -ROUTE TS.isOver TO RC.reverseActivate -ROUTE TS.isActive TO C2.activate -ROUTE TS.isActive TO RC2.reverseActivate -ROUTE TIME.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO GL.endPoint - diff --git a/regression_tests/bifs-2D-texturing-movietexture-shapes.bt b/regression_tests/bifs-2D-texturing-movietexture-shapes.bt deleted file mode 100644 index 5f226eb..0000000 --- a/regression_tests/bifs-2D-texturing-movietexture-shapes.bt +++ /dev/null @@ -1,285 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 440 - pixelHeight 440 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows a video displayed on the basic 2D shapes." - "Video, like image, is considered as a texture and described in the MovieTexture node." - "The url of this node points to the video using any internet protocol (http, rtsp) or using MPEG-4 OD." - "The MovieTexture node is associated to the geometry as a children of the Shape node. The video is then clipped along the bounding box of the shape." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.4 $" - "(C) 2002-2006 GPAC Team" - ] - title "Displaying Videos as a texture on any shape" - } - Transform2D { - translation -150 150 - children [ - Shape { - appearance DEF APP Appearance { - texture MovieTexture { - loop TRUE - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry IndexedLineSet2D { - coord Coordinate2D { - point [-50 0 0 50 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Text { - string ["IndexedLineSet2D" "[-50 0 0 50 50 0]"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 12 - } - } - } - ] - } - ] - } - Transform2D { - translation 0 150 - children [ - Shape { - appearance USE APP - geometry Circle { - radius 50 - } - } - Transform2D { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Circle" "radius 50"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 150 150 - children [ - Shape { - appearance USE APP - geometry Rectangle { - size 100 50 - } - } - Transform2D { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Rectangle" "Size 100 50"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -40 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Curve2D Points:" "-50 0, -100 50, 0 20, 10 30, 40 80, 50 0"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -150 0 - children [ - Shape { - appearance USE APP - geometry Curve2D { - point DEF C2D Coordinate2D { - point [-50 0 -100 50 0 20 10 30 40 80 50 0] - } - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["no type"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 3] - point USE C2D - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["type [2 3]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 170 0 - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [1 3 1] - point USE C2D - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["type [1 3 1]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation -150 -150 - children [ - Shape { - appearance USE APP - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-50 0 -25 25 0 80 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["IndexedFaceSet2D" "-50 0, -25, 25, 0 80, 50 0"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance USE APP - geometry PointSet2D { - coord Coordinate2D { - point [-50 0 -25 25 0 80 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["PointSet2D" "-50 0, -25, 25, 0 80, 50 0"] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-texturing-pixeltexture.bt b/regression_tests/bifs-2D-texturing-pixeltexture.bt deleted file mode 100644 index 9b8872a..0000000 --- a/regression_tests/bifs-2D-texturing-pixeltexture.bt +++ /dev/null @@ -1,191 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - DEF B Background2D { - backColor 1 0 0 - } - WorldInfo { - info [ - "This test shows the usage of the PixelTexture node." - "The PixelTexture allows to define a non-vectorial synthetic texture. The texture is defined by giving its size, the color depth in byte, and the color components (ARGB) for each pixel in the texture" - "In this scene, 4 circles are filled with a 4x4-pixels texture whose color depth are respectively 1 byte, 2 bytes, 3 and 4 bytes." - "1 byte corresponds to 8-bits grey scale" - "2 bytes corresponds to 8-bits grey scale + 8-bits transparency" - "3 bytes corresponds to 24-bits RGB" - "4 bytes corresponds to 32-bits ARGB" - "The background color of the scene is animated to see the effect on the texture." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Synthetic Non Vectorial Texture" - } - Transform2D { - translation -80 90 - children [ - Shape { - appearance Appearance { - texture PixelTexture { - image 4 4 1 - 0xFF 0xFF 0x00 0x00 - 0xFF 0xFF 0x00 0x00 - 0x00 0x00 0xFF 0xFF - 0x00 0x00 0xFF 0xFF - } - } - geometry Circle { - radius 50 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF TA Appearance { - material Material2D { - emissiveColor 1 1 1 - filled TRUE - } - } - geometry Text { - string [ "Color Depth:" "1 Byte" ] - fontStyle DEF FS FontStyle { - size 20 - justify [ "MIDDLE" "MIDDLE" ] - family "SANS" - } - } - } - ] - } - ] - } - Transform2D { - translation 80 90 - children [ - Shape { - appearance Appearance { - texture PixelTexture { - image 4 4 2 - 0x00FF 0x00FF 0x0000 0x0000 - 0x00FF 0x00FF 0x0000 0x0000 - 0x0000 0x0000 0x00FF 0x00FF - 0x0000 0x0000 0x00FF 0x00FF - } - } - geometry Circle { - radius 50 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TA - geometry Text { - string [ "Color Depth:" "2 Bytes" ] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation -80 -60 - children [ - Shape { - appearance Appearance { - texture PixelTexture { - image 4 4 3 - 0xFFFFFF 0xFFFFFF 0x00FF00 0x00FF00 - 0xFFFFFF 0xFFFFFF 0x00FF00 0x00FF00 - 0xFF00FF 0xFF00FF 0x000000 0x000000 - 0xFF00FF 0xFF00FF 0x000000 0x000000 - } - } - geometry Circle { - radius 50 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TA - geometry Text { - string [ "Color Depth:" "3 Bytes" ] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 80 -60 - children [ - Shape { - appearance Appearance { - texture PixelTexture { - image 4 4 4 - 0xFFFFFF00 0xFFFFFF00 0x00FF00FF 0x00FF00FF - 0xFFFFFF00 0xFFFFFF00 0x00FF00FF 0x00FF00FF - 0xFF00FFFF 0xFF00FFFF 0x00000000 0x00000000 - 0xFF00FFFF 0xFF00FFFF 0x00000000 0x00000000 - } - } - geometry Circle { - radius 50 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TA - geometry Text { - string [ "Color Depth:" "4 Bytes" ] - fontStyle USE FS - } - } - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF CI ColorInterpolator { - key [0 0.5 1] - keyValue [1 0 0 0 0 1 1 0 0] - } - ] -} - -ROUTE TS.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO B.backColor - diff --git a/regression_tests/bifs-2D-texturing-radialgradient-simple.bt b/regression_tests/bifs-2D-texturing-radialgradient-simple.bt deleted file mode 100644 index 1365479..0000000 --- a/regression_tests/bifs-2D-texturing-radialgradient-simple.bt +++ /dev/null @@ -1,94 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to fill object with radial gradients" - "The focal point can be moved to see the effect on the gradient." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Radial Gradient Focal Point" - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Drag mouse on Shape" "to change the focal point"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF GR RadialGradient { - focalPoint 0.5 0.5 - key [0 0.5 1] - keyValue [0 0 1 0 1 1 0 1 0] - radius 0.25 - spreadMethod 1 - } - } - geometry DEF R Rectangle { - size 200 200 - } - } - DEF PS PlaneSensor2D { - maxPosition 100 100 - minPosition -100 -100 - } - ] - } - DEF V Valuator { - Factor1 0.01 - Factor2 0.01 - Factor3 0 - Factor4 0 - Offset1 0.5 - Offset2 0.5 - } - ] -} - -ROUTE PS.translation_changed TO V.inSFVec2f -ROUTE V.outSFVec2f TO GR.focalPoint - diff --git a/regression_tests/bifs-2D-texturing-radialgradient-spread.bt b/regression_tests/bifs-2D-texturing-radialgradient-spread.bt deleted file mode 100644 index 2428dc7..0000000 --- a/regression_tests/bifs-2D-texturing-radialgradient-spread.bt +++ /dev/null @@ -1,118 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows the different methods for spreading radial gradients when the size of the object to be filled is large" - "The focal point of the gradient is also animated to change the gradient aspect over time." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Radial Gradient Spread Methods" - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Move over and click" "to change the spread method"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - width 0 - } - } - texture DEF GR RadialGradient { - focalPoint 0 0.5 - key [0 0.5 1] - keyValue [0 0 1 1 0 0 0 1 0] - } - } - geometry DEF R Rectangle { - size 200 200 - } - } - DEF TS TouchSensor {} - ] - } - DEF C Conditional { - buffer { - REPLACE GR.spreadMethod BY 2 - } - } - DEF RC Conditional { - buffer { - REPLACE GR.spreadMethod BY 0 - } - } - DEF C2 Conditional { - buffer { - REPLACE GR.spreadMethod BY 1 - } - } - DEF RC2 Conditional { - buffer { - REPLACE GR.spreadMethod BY 2 - } - } - DEF TIME TimeSensor { - cycleInterval 4 - loop TRUE - } - DEF CI PositionInterpolator2D { - key [0 0.25 0.5 0.75 1] - keyValue [0 0.5 0.5 1 1 0.5 0.5 0 0 0.5] - } - ] -} - -ROUTE TS.isOver TO C.activate -ROUTE TS.isOver TO RC.reverseActivate -ROUTE TS.isActive TO C2.activate -ROUTE TS.isActive TO RC2.reverseActivate -ROUTE TIME.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO GR.focalPoint - diff --git a/regression_tests/bifs-2D-texturing-texturetransform-base.bt b/regression_tests/bifs-2D-texturing-texturetransform-base.bt deleted file mode 100644 index d668e9e..0000000 --- a/regression_tests/bifs-2D-texturing-texturetransform-base.bt +++ /dev/null @@ -1,234 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how a texture can be modified: either changing its positionning in the shape or its transparency" - "The positioning is given using the TextureTransform node and the transparency using the Material2D node." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "TextureTransform" - } - Transform2D { - translation -180 0 - children [ - Shape { - appearance Appearance { - texture DEF TEXTURE ImageTexture { - url [od:10] - } - } - geometry DEF REC Rectangle { - size 150 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["No Transform"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 14 - } - } - } - ] - } - ] - } - Transform2D { - translation 0 140 - children [ - Shape { - appearance Appearance { - texture USE TEXTURE - textureTransform TextureTransform { - rotation 0.78 - } - } - geometry USE REC - } - Transform2D { - translation 0 -60 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["TextureTransform: rotation PI/4"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 10 - children [ - Shape { - appearance Appearance { - texture USE TEXTURE - textureTransform TextureTransform { - scale 0.5 1.5 - } - } - geometry USE REC - } - Transform2D { - translation 0 -60 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["TextureTransform: scale 0.5 1.5"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -120 - children [ - Shape { - appearance Appearance { - texture USE TEXTURE - textureTransform TextureTransform { - translation 0.5 0 - } - } - geometry USE REC - } - Transform2D { - translation 0 -60 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["TextureTransform: translation 0.5 0"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 180 100 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 1 - filled TRUE - transparency 0.8 - } - texture USE TEXTURE - } - geometry USE REC - } - Transform2D { - translation 0 -60 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Material Transparency 0.8"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 180 -100 - children [ - Shape { - appearance Appearance { - texture USE TEXTURE - textureTransform TextureTransform { - center 0.5 0.5 - rotation 0.78 - } - } - geometry Circle { - radius 60 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Rotated On a Circle"] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-texturing-texturetransform-interact.bt b/regression_tests/bifs-2D-texturing-texturetransform-interact.bt deleted file mode 100644 index a066d93..0000000 --- a/regression_tests/bifs-2D-texturing-texturetransform-interact.bt +++ /dev/null @@ -1,231 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how to apply transformations to texture independantly of the transformation on the shape." - "The TextureTransform node is used here." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Transforming Textures" - } - Transform2D { - translation -150 100 - children [ - Shape { - appearance Appearance { - texture DEF IMG ImageTexture { - url [od:10] - } - textureTransform DEF TXT1 TextureTransform { - center 0.5 0.5 - } - } - geometry DEF REC Rectangle { - size 200 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Drag mouse to change" "rotation angle"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 14 - } - } - } - ] - } - DEF PS1 PlaneSensor2D { - maxPosition 400 400 - minPosition -400 -400 - } - ] - } - Transform2D { - translation -150 -100 - children [ - Shape { - appearance Appearance { - texture USE IMG - textureTransform DEF TXT2 TextureTransform { - center 0.5 0.5 - rotation 0.78 - } - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Drag mouse to change" "rotation center"] - fontStyle USE FS - } - } - ] - } - DEF PS2 PlaneSensor2D { - maxPosition 100 50 - minPosition -100 -50 - } - ] - } - Transform2D { - translation 150 100 - children [ - Shape { - appearance Appearance { - texture USE IMG - textureTransform DEF TXT3 TextureTransform {} - - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Drag mouse to" "translate texture"] - fontStyle USE FS - } - } - ] - } - DEF PS3 PlaneSensor2D { - maxPosition 400 400 - minPosition -400 -400 - } - ] - } - Transform2D { - translation 150 -100 - children [ - Shape { - appearance Appearance { - texture USE IMG - textureTransform DEF TXT4 TextureTransform { - rotation 0.78 - } - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Drag mouse to change" "texture scaling"] - fontStyle USE FS - } - } - ] - } - DEF PS4 PlaneSensor2D { - maxPosition 100 100 - minPosition -100 -100 - } - ] - } - DEF V1 Valuator { - Factor1 0.01 - } - DEF V2 Valuator { - Factor1 0.005 - Factor2 0.01 - Offset1 0.5 - Offset2 0.5 - } - DEF V3 Valuator { - Factor1 -0.005 - Factor2 -0.01 - } - DEF V4 Valuator { - Factor1 0.1 - Factor2 0.1 - } - DEF TS TimeSensor { - cycleInterval 4 - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1.56 0] - } - ] -} - -ROUTE PS1.translation_changed TO V1.inSFVec2f -ROUTE V1.outSFFloat TO TXT1.rotation -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO TXT2.rotation -ROUTE PS2.translation_changed TO V2.inSFVec2f -ROUTE V2.outSFVec2f TO TXT2.center -ROUTE PS3.translation_changed TO V3.inSFVec2f -ROUTE V3.outSFVec2f TO TXT3.translation -ROUTE PS4.translation_changed TO V4.inSFVec2f -ROUTE V4.outSFVec2f TO TXT4.scale - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-texturing-texturetransform-transformmatrix2D.bt b/regression_tests/bifs-2D-texturing-texturetransform-transformmatrix2D.bt deleted file mode 100644 index 48936ef..0000000 --- a/regression_tests/bifs-2D-texturing-texturetransform-transformmatrix2D.bt +++ /dev/null @@ -1,242 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows a texture being transformed (e.g. skewed) and this transformation is animated." - "The TransformMatrix2D is used here to allow skewing." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "ImageTexture" - } - Transform2D { - translation -180 100 - children [ - Shape { - appearance Appearance { - texture DEF TEXTURE ImageTexture { - url [od:10] - } - textureTransform DEF MX1 TransformMatrix2D {} - - } - geometry DEF REC Rectangle { - size 150 100 - } - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Texture horizontal scaling"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 14 - } - } - } - ] - } - ] - } - Transform2D { - translation -180 -100 - children [ - Shape { - appearance Appearance { - texture USE TEXTURE - textureTransform DEF MX2 TransformMatrix2D {} - - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Texture vertical scaling"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 100 - children [ - Shape { - appearance Appearance { - texture USE TEXTURE - textureTransform DEF MX3 TransformMatrix2D {} - - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Texture horizontal skewing"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -100 - children [ - Shape { - appearance Appearance { - texture USE TEXTURE - textureTransform DEF MX4 TransformMatrix2D { - mxy 1 - } - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Texture vertical skewing"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 180 100 - children [ - Shape { - appearance Appearance { - texture USE TEXTURE - textureTransform DEF MX5 TransformMatrix2D {} - - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Texture horizontal translating"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 180 -100 - children [ - Shape { - appearance Appearance { - texture USE TEXTURE - textureTransform DEF MX6 TransformMatrix2D {} - - } - geometry USE REC - } - Transform2D { - translation 0 -70 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Texture vertical translating"] - fontStyle USE FS - } - } - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 2 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO MX1.mxx -ROUTE SI.value_changed TO MX2.myy -ROUTE SI.value_changed TO MX3.mxy -ROUTE SI.value_changed TO MX4.myx -ROUTE SI.value_changed TO MX5.tx -ROUTE SI.value_changed TO MX6.ty - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-2D-viewport-complete.bt b/regression_tests/bifs-2D-viewport-complete.bt deleted file mode 100644 index 30f6aeb..0000000 --- a/regression_tests/bifs-2D-viewport-complete.bt +++ /dev/null @@ -1,715 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows usage of the viewport per layer" "Translated from SVG" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "SVG Test Suite - (C) W3C 2002"] - title "Animation Stream" - } - Background2D { - backColor 1 1 1 - } - Transform2D { - translation -225 225 - children [ - Transform2D { - translation 0 -30 - children [ - Transform2D { - translation 10 -30 - children [ - Shape { - appearance DEF N0 Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["BIFS to fit"] - fontStyle DEF N13 FontStyle { - family ["SANS"] - size 9 - } - } - } - ] - } - Transform2D { - translation 20 -40 - children [ - DEF N4 Transform2D { - children [ - Transform2D { - translation 15 -20 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - lineProps LineProperties { - lineColor 1 0 0 - } - } - } - geometry Rectangle { - size 29 39 - } - } - ] - } - Transform2D { - translation 0 -5 - children [ - Transform2D { - translation 15 -15 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Circle { - radius 10 - } - } - ] - } - Transform2D { - translation 12 -12 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Circle { - radius 1.5 - } - } - ] - } - Transform2D { - translation 17 -12 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Circle { - radius 1.5 - } - } - ] - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - lineProps LineProperties { - width 2 - } - } - } - geometry Curve2D { - type [2] - point Coordinate2D { - point [10 -19 15 -22.75 15 -22.75 20 -19] - } - } - } - ] - } - ] - } - ] - } - Transform2D { - translation 10 -110 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["Viewport 1"] - fontStyle USE N13 - } - } - ] - } - Transform2D { - translation 10 -120 - children [ - DEF N12 Transform2D { - translation 25 -15 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - } - } - } - geometry Rectangle { - size 49 29 - } - } - ] - } - ] - } - Transform2D { - translation 10 -180 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["Viewport 2"] - fontStyle USE N13 - } - } - ] - } - Transform2D { - translation 20 -190 - children [ - DEF N10 Transform2D { - translation 15 -30 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - } - } - } - geometry Rectangle { - size 29 59 - } - } - ] - } - ] - } - Transform2D { - translation 100 -60 - children [ - DEF N7 Transform2D { - translation 0 30 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["-------------- fit= 1 --------------"] - fontStyle USE N13 - } - } - ] - } - Transform2D { - children [ - DEF N14 Transform2D { - translation 15 15 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["alignment" "[ -1 * ]"] - fontStyle DEF N1 FontStyle { - family ["SANS"] - justify ["MIDDLE"] - size 9 - } - } - } - ] - } - USE N12 - Transform2D { - translation 25 -15 - children [ - Layer2D { - size 50 30 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [-1 0] - fit 1 - } - } - ] - } - ] - } - Transform2D { - translation 70 0 - children [ - DEF N9 Transform2D { - translation 15 15 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["alignment" "[ 0 * ]"] - fontStyle USE N1 - } - } - ] - } - USE N12 - Transform2D { - translation 25 -15 - children [ - Layer2D { - size 50 30 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [0 0] - fit 1 - } - } - ] - } - ] - } - Transform2D { - translation 0 -70 - children [ - DEF N5 Transform2D { - translation 15 15 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["alignment" "[ 1 * ]"] - fontStyle USE N1 - } - } - ] - } - USE N12 - Transform2D { - translation 25 -15 - children [ - Layer2D { - size 50 30 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [1 0] - fit 1 - } - } - ] - } - ] - } - ] - } - Transform2D { - translation 250 -60 - children [ - USE N7 - Transform2D { - children [ - DEF N11 Transform2D { - translation 15 15 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["alignment" "[ * -1 ]"] - fontStyle USE N1 - } - } - ] - } - USE N10 - Transform2D { - translation 15 -30 - children [ - Layer2D { - size 30 60 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [0 -1] - fit 1 - } - } - ] - } - Transform2D { - translation 50 0 - children [ - DEF N3 Transform2D { - translation 15 15 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["alignment" "[ * 0 ]"] - fontStyle USE N1 - } - } - ] - } - USE N10 - Transform2D { - translation 15 -30 - children [ - Layer2D { - size 30 60 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [0 0] - fit 1 - } - } - ] - } - ] - } - Transform2D { - translation 100 0 - children [ - DEF N2 Transform2D { - translation 15 15 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["alignment" "[ * 1 ]"] - fontStyle USE N1 - } - } - ] - } - USE N10 - Transform2D { - translation 15 -30 - children [ - Layer2D { - size 30 60 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [0 1] - fit 1 - } - } - ] - } - ] - } - ] - } - ] - } - Transform2D { - translation 100 -220 - children [ - DEF N6 Transform2D { - translation 0 30 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["---------- fit = 2 ----------"] - fontStyle USE N13 - } - } - ] - } - USE N14 - USE N10 - Transform2D { - translation 15 -30 - children [ - Layer2D { - size 30 60 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [-1 0] - fit 2 - } - } - ] - } - Transform2D { - translation 50 0 - children [ - USE N9 - USE N10 - Transform2D { - translation 15 -30 - children [ - Layer2D { - size 30 60 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [0 0] - fit 2 - } - } - ] - } - ] - } - Transform2D { - translation 100 0 - children [ - USE N5 - USE N10 - Transform2D { - translation 15 -30 - children [ - Layer2D { - size 30 60 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [1 0] - fit 2 - } - } - ] - } - ] - } - ] - } - Transform2D { - translation 250 -190 - children [ - Transform2D { - translation 0 -30 - children [ - USE N6 - Transform2D { - children [ - USE N11 - USE N12 - Transform2D { - translation 25 -15 - children [ - Layer2D { - size 50 30 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [0 -1] - fit 2 - } - } - ] - } - ] - } - Transform2D { - translation 70 0 - children [ - USE N3 - USE N12 - Transform2D { - translation 25 -15 - children [ - Layer2D { - size 50 30 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [0 0] - fit 2 - } - } - ] - } - ] - } - Transform2D { - translation 140 0 - children [ - USE N2 - USE N12 - Transform2D { - translation 25 -15 - children [ - Layer2D { - size 50 30 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - alignment [0 1] - fit 2 - } - } - ] - } - ] - } - ] - } - ] - } - Transform2D { - translation 175 -300 - children [ - Transform2D { - translation 0 -30 - children [ - Transform2D { - translation 0 30 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["---------- fit = 0 ----------"] - fontStyle USE N13 - } - } - ] - } - Transform2D { - children [ - DEF N8 Transform2D { - translation 15 15 - children [ - Shape { - appearance USE N0 - geometry Text { - string ["alignment" "[ * * ]"] - fontStyle USE N1 - } - } - ] - } - USE N12 - Transform2D { - translation 25 -15 - children [ - Layer2D { - size 50 30 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - } - } - ] - } - ] - } - Transform2D { - translation 100 0 - children [ - USE N8 - USE N10 - Transform2D { - translation 15 -30 - children [ - Layer2D { - size 30 60 - children [ - USE N4 - ] - viewport Viewport { - position 15 -20 - size 30 40 - } - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-2D-viewport-simple.bt b/regression_tests/bifs-2D-viewport-simple.bt deleted file mode 100644 index 54c3827..0000000 --- a/regression_tests/bifs-2D-viewport-simple.bt +++ /dev/null @@ -1,88 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D { - url [od:10] - } - WorldInfo { - info ["This shows usage of Viewport in the scene" "viewport can be changed through the player's viewport list" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Viewport Test" - } - DEF VP Viewport { - size 200 200 - orientation 0.5 - alignment [0 0] - fit 2 - description "basic Viewport" - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture RadialGradient { - focalPoint 0.5 0.5 - key [0 1] - keyValue [0 1 0 0 1 1] - radius 0.8 - } - } - geometry Rectangle { - size 100 100 - } - } - DEF TS TouchSensor {} - ] - } - ] -} - -ROUTE TS.isOver TO VP.set_bind - -AT 0 { - REPLACE VP.set_bind BY FALSE -} - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 22 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-background-images.bt b/regression_tests/bifs-3D-background-images.bt deleted file mode 100644 index 9805472..0000000 --- a/regression_tests/bifs-3D-background-images.bt +++ /dev/null @@ -1,87 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - includeInlineProfileLevelFlag true - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - WorldInfo { - info ["This shows Background with transparent texture on all back planes" "" "GPAC Regression Tests" "$Date: 2008/06/26 07:55:39 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Background Test" - } - Viewpoint {} - Background { - groundAngle [0.56 1.2] - groundColor [0 0 0, 0.1 0.8 0.8, 0.5 1 0] - skyAngle [0.5 1.2 1.8] - skyColor [0 0 0.5, 0.2 0.4 0.2, 0.4 0.1 0.0, 0.5 0.5 0.2] - frontUrl ["20"] - backUrl ["20"] - leftUrl ["20"] - rightUrl ["20"] - topUrl ["20"] - bottomUrl ["20"] - } - -#if 0 - Transform { - children [ - Shape { - appearance Appearance { - material Material { - diffuseColor 1 1 1 - } - texture ImageTexture { url ["./auxiliary_files/logo.jpg"] } - } - geometry Box { - size 3 2 5 - } - } - ] - } -#endif - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 20 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.png" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-background.bt b/regression_tests/bifs-3D-background.bt deleted file mode 100644 index 8500f6f..0000000 --- a/regression_tests/bifs-3D-background.bt +++ /dev/null @@ -1,56 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - includeInlineProfileLevelFlag true - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - WorldInfo { - info ["This shows a background node" "with ground and sky" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Background Test" - } - Viewpoint {} - Background { - groundAngle [0.56 1.2] - groundColor [0 0 0, 0.1 0.8 0.8, 0.5 1 0] - skyAngle [0.5 1.2 1.8] - skyColor [0 0 0.5, 0.2 0.4 0.2, 0.4 0.1 0.0, 0.5 0.5 0.2] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { - diffuseColor 1 1 1 - } - texture ImageTexture { url ["./auxiliary_files/logo.jpg"] } - } - geometry Box { - size 3 2 5 - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-3D-interactivity-collision-proxy.bt b/regression_tests/bifs-3D-interactivity-collision-proxy.bt deleted file mode 100644 index d288452..0000000 --- a/regression_tests/bifs-3D-interactivity-collision-proxy.bt +++ /dev/null @@ -1,80 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 200 - } - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Collision Test" - info ["This shows the collision node " "used with a sphere proxy" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - DEF C Collision { - proxy Shape { geometry Sphere { radius 6 } } - children [ - Shape { - appearance Appearance { - material DEF MAT Material { diffuseColor 0 1 0 } - } - geometry Box {size 20 2 0.1} - } - ] - } - DEF S Script { - eventIn SFTime on_collide - eventOut MFString outText - eventOut SFColor outCol - url "javascript: - function on_collide(value) { - v = new SFColor(1, 0, 0); - outCol = v; - outText[0] = 'collision time: ' + value; - } - " - } - - Transform { - translation 0 2 0 - children [ - Shape { - appearance Appearance { - material Material2D { emissiveColor 0 0 0 filled TRUE } - } - geometry DEF T Text { - string "no collision" - fontStyle FontStyle { - size 2 - justify "MIDDLE" - } - } - } - ] - } - - ] -} - -ROUTE C.collideTime TO S.on_collide -ROUTE S.outText TO T.string -ROUTE S.outCol TO MAT.diffuseColor - diff --git a/regression_tests/bifs-3D-interactivity-collision.bt b/regression_tests/bifs-3D-interactivity-collision.bt deleted file mode 100644 index 9a74e32..0000000 --- a/regression_tests/bifs-3D-interactivity-collision.bt +++ /dev/null @@ -1,79 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 200 - } - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Collision Test" - info ["This shows the collision node " "used without proxy" "" "GPAC Regression Tests" "$Date: 2008/06/26 07:55:39 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - DEF C Collision { - children [ - DEF B Shape { - appearance Appearance { - material DEF MAT Material { diffuseColor 0 1 0 } - } - geometry Box {size 20 0.5 0.1} - } - ] - } - DEF S Script { - eventIn SFTime on_collide - eventOut MFString outText - eventOut SFColor outCol - url "javascript: - function on_collide(value) { - v = new SFColor(1, 0, 0); - outCol = v; - outText[0] = 'collision time: ' + value; - } - " - } - - Transform { - translation 0 0 0.055 - children [ - Shape { - appearance Appearance { - material Material2D { emissiveColor 0 0 0 filled TRUE } - } - geometry DEF T Text { - string "no collision" - fontStyle FontStyle { - size 2 - justify "MIDDLE" - } - } - } - ] - } - - ] -} - -ROUTE C.collideTime TO S.on_collide -ROUTE S.outText TO T.string -ROUTE S.outCol TO MAT.diffuseColor - diff --git a/regression_tests/bifs-3D-interactivity-cylindersensor.bt b/regression_tests/bifs-3D-interactivity-cylindersensor.bt deleted file mode 100644 index 8992761..0000000 --- a/regression_tests/bifs-3D-interactivity-cylindersensor.bt +++ /dev/null @@ -1,90 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - WorldInfo { - title "CylinderSensor test" - info ["This shows a cylinderSensor" "exercising isActive, rotationChanged and trackPoint_changed events" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - Background2D {backColor 1 1 1} - Viewpoint {} - DEF TF Transform { - translation 2 0 0 - children [ - DEF CS CylinderSensor { - } - Shape { - appearance Appearance { - material Material { - diffuseColor 1 0 0 - } - } - geometry Box { - size 2 2 1 - } - } - ] - } - - Transform { - translation -5 1 -10 - children [ - Shape { - appearance Appearance { - material DEF M Material { - diffuseColor 1 0 0.245 - } - } - geometry Sphere { radius 2 } - } - ] - } - Transform { - translation 0 -3 0 - children [ - Shape { - #appearance Appearance { material Material2D { filled TRUE emissiveColor 0 1 0} } - appearance Appearance { material Material {emissiveColor 0 1 0 diffuseColor 0 0 1} } - geometry DEF TXT Text { string "Trackpoint" fontStyle FontStyle {size 0.8 justify "MIDDLE" } } - } - ] - } - DEF V Valuator{} - - DEF C Conditional { - buffer { REPLACE M.diffuseColor BY 0 0.25 0.65 } - } - DEF RC Conditional { - buffer { REPLACE M.diffuseColor BY 1 0 0.245} - } - - ] -} -ROUTE CS.isActive TO C.activate -ROUTE CS.isActive TO RC.reverseActivate -ROUTE CS.rotation_changed TO TF.rotation - -ROUTE CS.trackPoint_changed TO V.inSFVec3f -ROUTE V.outMFString TO TXT.string diff --git a/regression_tests/bifs-3D-interactivity-planesensor.bt b/regression_tests/bifs-3D-interactivity-planesensor.bt deleted file mode 100644 index 7157084..0000000 --- a/regression_tests/bifs-3D-interactivity-planesensor.bt +++ /dev/null @@ -1,93 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - Viewpoint {} - WorldInfo { - title "PlaneSensor test" - info ["This shows a planeSensor" "exercising isActive, translationChanged and trackPoint_changed events" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - Background2D {backColor 1 1 1} - - DEF TF Transform { - translation 2 0 0 - children [ - DEF PS PlaneSensor { - maxPosition 2 2 - minPosition -2 -2 - offset 2 0 0 - } - Shape { - appearance Appearance { - material Material { - diffuseColor 1 0 0 - } - } - geometry Box { - size 2 2 1 - } - } - ] - } - - Transform { - translation -5 1 -10 - children [ - Shape { - appearance Appearance { - material DEF M Material { - diffuseColor 1 0 0.245 - } - } - geometry Sphere { radius 2 } - } - ] - } - Transform { - translation 0 -3 0 - children [ - Shape { - appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0} } - geometry DEF TXT Text { string "Trackpoint" fontStyle FontStyle {size 0.8 justify "MIDDLE"} } - } - ] - } - DEF V Valuator{} - - DEF C Conditional { - buffer { REPLACE M.diffuseColor BY 0 0.25 0.65 } - } - DEF RC Conditional { - buffer { REPLACE M.diffuseColor BY 1 0 0.245} - } - - ] -} -ROUTE PS.isActive TO C.activate -ROUTE PS.isActive TO RC.reverseActivate -ROUTE PS.translation_changed TO TF.translation - -ROUTE PS.trackPoint_changed TO V.inSFVec3f -ROUTE V.outMFString TO TXT.string diff --git a/regression_tests/bifs-3D-interactivity-proximitysensor.bt b/regression_tests/bifs-3D-interactivity-proximitysensor.bt deleted file mode 100644 index 66c74fc..0000000 --- a/regression_tests/bifs-3D-interactivity-proximitysensor.bt +++ /dev/null @@ -1,80 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "ProximitySensor test" - info ["This shows a ProximitySensor" "exercising isActive event" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - Viewpoint {position 0 0 10} - DEF Box Transform { - children [ - DEF PS ProximitySensor { - center 0 0 0 - size 8 8 8 - } - Shape { - appearance Appearance { - material DEF M1 Material { - diffuseColor 1 0 0 - } - } - geometry Box { - size 2 2 2 - } - } - ] - } - - - DEF TS TimeSensor { - cycleInterval 5.0 - loop TRUE - startTime -1 - } - - DEF Animation OrientationInterpolator { - key [0.0, - 0.20, - 0.40, - 0.60, - 0.80, - 1.0] - keyValue [0 1 0 0, - 0 1 0 1.57079, - 0 1 0 3.14159, - 0 1 0 4.71238, - 0 1 0 5.52456, - 0 1 0 6.28318] - } - ] -} - -ROUTE PS.enterTime TO TS.startTime -ROUTE PS.exitTime TO TS.stopTime - -ROUTE TS.fraction_changed TO Animation.set_fraction -ROUTE Animation.value_changed TO Box.rotation diff --git a/regression_tests/bifs-3D-interactivity-spheresensor.bt b/regression_tests/bifs-3D-interactivity-spheresensor.bt deleted file mode 100644 index 9447374..0000000 --- a/regression_tests/bifs-3D-interactivity-spheresensor.bt +++ /dev/null @@ -1,90 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - Viewpoint {} - WorldInfo { - title "SphereSensor test" - info ["This shows a SphereSensor" "exercising isActive, rotationChanged and trackPoint_changed events" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - Background2D {backColor 1 1 1} - - DEF TF Transform { - translation 2 0 0 - children [ - DEF CS SphereSensor { - } - Shape { - appearance Appearance { - material Material { - diffuseColor 1 0 0 - } - } - geometry Box { - size 4 4 1 - } - } - ] - } - - Transform { - translation -5 1 -10 - children [ - Shape { - appearance Appearance { - material DEF M Material { - diffuseColor 1 0 0.245 - } - } - geometry Sphere { radius 2 } - } - ] - } - Transform { - translation 0 -3 0 - children [ - Shape { - appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0} } - geometry DEF TXT Text { string "Trackpoint" fontStyle FontStyle {size 0.8 justify "MIDDLE"} } - } - ] - } - DEF V Valuator{} - - DEF C Conditional { - buffer { REPLACE M.diffuseColor BY 0 0.25 0.65 } - } - DEF RC Conditional { - buffer { REPLACE M.diffuseColor BY 1 0 0.245} - } - - ] -} -ROUTE CS.isActive TO C.activate -ROUTE CS.isActive TO RC.reverseActivate -ROUTE CS.rotation_changed TO TF.rotation - -ROUTE CS.trackPoint_changed TO V.inSFVec3f -ROUTE V.outMFString TO TXT.string diff --git a/regression_tests/bifs-3D-interactivity-visibilitysensor.bt b/regression_tests/bifs-3D-interactivity-visibilitysensor.bt deleted file mode 100644 index 25dbe7b..0000000 --- a/regression_tests/bifs-3D-interactivity-visibilitysensor.bt +++ /dev/null @@ -1,100 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - - Viewpoint {position 0 0 10} - - WorldInfo { - title "VisibilitySensor test" - info ["This shows a VisibiliitySensor" "controling spinning of a cube" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - - Transform { - translation 10 0 0 - children [ - DEF PS VisibilitySensor { - center 0 0 0 - size 8 8 8 - } - Shape { - appearance Appearance { - material Material { - diffuseColor 1 1 0 - } - } - geometry Box { - size 8 8 8 - } - } - ] - } - - - DEF Box Transform { - children [ - Shape { - appearance Appearance { - material DEF M1 Material { - diffuseColor 1 0 0 - } - } - geometry Box { - size 2 2 2 - } - } - ] - } - - - DEF TS TimeSensor { - cycleInterval 5.0 - loop TRUE - startTime -1 - } - - DEF Animation OrientationInterpolator { - key [0.0, - 0.20, - 0.40, - 0.60, - 0.80, - 1.0] - keyValue [0 1 0 0, - 0 1 0 1.57079, - 0 1 0 3.14159, - 0 1 0 4.71238, - 0 1 0 5.52456, - 0 1 0 6.28318] - } - ] -} - -ROUTE PS.enterTime TO TS.startTime -ROUTE PS.exitTime TO TS.stopTime - -ROUTE TS.fraction_changed TO Animation.set_fraction -ROUTE Animation.value_changed TO Box.rotation diff --git a/regression_tests/bifs-3D-lighting-directionalLight.bt b/regression_tests/bifs-3D-lighting-directionalLight.bt deleted file mode 100644 index e9063de..0000000 --- a/regression_tests/bifs-3D-lighting-directionalLight.bt +++ /dev/null @@ -1,63 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -Group { -children [ - NavigationInfo {type ["ANY" "EXAMINE"] headlight FALSE} - - WorldInfo { - title "DirectionalLight test" - info ["This shows a directional light" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - DirectionalLight { - color 1 0 0 - direction 0 1 1 - } - DEF BB Group { - children [ - DEF B Shape { - appearance Appearance { material Material {}} - geometry Box { size 1 1 1} - } - Transform { - translation 2 0 0 - children [ USE B] - } - Transform { - translation -2 0 0 - children [ USE B] - } - ] - } - Transform { - translation 0 2 0 - children [ USE BB] - } - Transform { - translation 0 -2 0 - children [ USE BB] - } - ] -} diff --git a/regression_tests/bifs-3D-lighting-fog.bt b/regression_tests/bifs-3D-lighting-fog.bt deleted file mode 100644 index a5d4d69..0000000 --- a/regression_tests/bifs-3D-lighting-fog.bt +++ /dev/null @@ -1,56 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - WorldInfo { - title "Fog test" - info ["This shows a fog" "with varying visibility range" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - DEF AFOG Fog {color 0.2 0.2 0.2 visibilityRange 4} - Transform { - children [ - Inline { url "./auxiliary_files/nefertiti.wrl"} - DirectionalLight { color 1 0 0 direction 1 1 -1 } - DEF TOUCH TouchSensor{} - ] - } - DEF TS TimeSensor {cycleInterval 6.0 loop TRUE } - DEF SI ScalarInterpolator{ - key [0 0.5 1] - keyValue [16 0 16] - } - DEF V Valuator { - Factor1 -1 - Offset1 1 - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO AFOG.visibilityRange - -ROUTE TOUCH.isOver TO V.inSFBool -ROUTE V.outSFBool TO AFOG.set_bind - diff --git a/regression_tests/bifs-3D-lighting-pointlight.bt b/regression_tests/bifs-3D-lighting-pointlight.bt deleted file mode 100644 index b1ef0e0..0000000 --- a/regression_tests/bifs-3D-lighting-pointlight.bt +++ /dev/null @@ -1,71 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -Group { -children [ - NavigationInfo {type ["ANY" "EXAMINE"] headlight FALSE} - - WorldInfo { - title "PointLight test" - info ["This shows a point light" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - DEF SP PointLight { - location 0.0 0.0 2.0 - color 0 0 1 - attenuation 1 0.5 0 - } - DEF BB Group { - children [ - DEF B Shape { - appearance Appearance { material Material {}} - geometry Box { size 1 1 1} - } - Transform { - translation 2 0 0 - children [ USE B] - } - Transform { - translation -2 0 0 - children [ USE B] - } - ] - } - Transform { - translation 0 2 0 - children [ USE BB] - } - Transform { - translation 0 -2 0 - children [ USE BB] - } - DEF TS TimeSensor { loop TRUE cycleInterval 2} - DEF CI PositionInterpolator { - key [0 0.5 1] - keyValue [1 0 0 1 1 0 1 0 0] - } - ] -} - -ROUTE TS.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO SP.attenuation diff --git a/regression_tests/bifs-3D-lighting-spotlight.bt b/regression_tests/bifs-3D-lighting-spotlight.bt deleted file mode 100644 index d812be1..0000000 --- a/regression_tests/bifs-3D-lighting-spotlight.bt +++ /dev/null @@ -1,72 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -Group { -children [ - NavigationInfo {type ["ANY" "EXAMINE"] headlight FALSE} - - WorldInfo { - title "SpotLight test" - info ["This shows a spot light" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - DEF SL SpotLight { - location 0.0 0.0 2.0 - color 0 0 1 - direction 0 0 -1 - } - DEF BB Group { - children [ - DEF B Shape { - appearance Appearance { material Material {}} - geometry Box { size 1 1 1} - } - Transform { - translation 2 0 0 - children [ USE B] - } - Transform { - translation -2 0 0 - children [ USE B] - } - ] - } - Transform { - translation 0 2 0 - children [ USE BB] - } - Transform { - translation 0 -2 0 - children [ USE BB] - } - - DEF TS TimeSensor { loop TRUE cycleInterval 2} - DEF CI PositionInterpolator { - key [0 0.5 1] - keyValue [-2 0 -1 2 0 -1 -2 0 -1] - } - ] -} - -ROUTE TS.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO SL.direction diff --git a/regression_tests/bifs-3D-positioning-billboard-viewer-alignment.bt b/regression_tests/bifs-3D-positioning-billboard-viewer-alignment.bt deleted file mode 100644 index f9c1a1a..0000000 --- a/regression_tests/bifs-3D-positioning-billboard-viewer-alignment.bt +++ /dev/null @@ -1,62 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "Billboard Test" - info ["This shows a Billboard in viewer-align mode" "The green box coordinate system should onlyt be a translation of the viewer one" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - Viewpoint {position 0 0 10} - NavigationInfo { type ["EXAMINE" "ANY"] } - Billboard { - axisOfRotation 0 0 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 0 1 0 - shininess 0.5 - } - } - geometry Box {size 0.5 0.5 0.5} - } - ] - } - Transform { - translation -1 0 0 - children [ - Shape { - appearance Appearance { - material Material { - diffuseColor 1 0 0 - } - } - geometry Box {size 0.5 0.5 0.5} - } - ] - } - ] -} diff --git a/regression_tests/bifs-3D-positioning-billboard.bt b/regression_tests/bifs-3D-positioning-billboard.bt deleted file mode 100644 index c05da35..0000000 --- a/regression_tests/bifs-3D-positioning-billboard.bt +++ /dev/null @@ -1,61 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - WorldInfo { - title "Billboard Test" - info ["This shows a Billboard" "The green box should rotate to face the viewer" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Viewpoint {position 0 0 10} - Billboard { - axisOfRotation 0 1 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 0 1 0 - shininess 0.5 - } - } - geometry Box {size 0.5 0.5 0.5} - } - ] - } - Transform { - translation -1 0 0 - children [ - Shape { - appearance Appearance { - material Material { - diffuseColor 1 0 0 - } - } - geometry Box {size 0.5 0.5 0.5} - } - ] - } - ] -} diff --git a/regression_tests/bifs-3D-positioning-gravity.bt b/regression_tests/bifs-3D-positioning-gravity.bt deleted file mode 100644 index f653e61..0000000 --- a/regression_tests/bifs-3D-positioning-gravity.bt +++ /dev/null @@ -1,71 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -Group { - children [ - NavigationInfo {avatarSize [0.25 1.6 8] } - Viewpoint {position 0 0 50} - WorldInfo { - title "Gravity test" - info ["This shows an rectangle used as ground" "with an jumpable obstacle" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - Group { - children [ - Background2D { backColor 1 1 1} - DEF TR Transform { - rotation 1 0 0 1.57 - translation 0 -8 -10 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 0 1 0 - shininess 0.5 - } - } - geometry Rectangle {size 50 100} - } - ] - } - Transform { - translation 0 -8 -10 - children [ - DEF B Shape { - appearance Appearance { - texture ImageTexture { url "./auxiliary_files/logo.jpg"} - } - geometry Box { size 2 2 2 } - } - ] - } - Transform { - translation -10 -7 -10 - children [ - USE B Shape - ] - } - ] - } - ] -} diff --git a/regression_tests/bifs-3D-positioning-layer3D-views.bt b/regression_tests/bifs-3D-positioning-layer3D-views.bt deleted file mode 100644 index 89c09d1..0000000 --- a/regression_tests/bifs-3D-positioning-layer3D-views.bt +++ /dev/null @@ -1,160 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 200 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - - Background2D {backColor 1 1 1 url "od:10"} - MediaControl {url "od:10" loop TRUE} - - WorldInfo { - title "Layer3D test" - info ["This shows several Layer3D nodes" "offering different views of the same scene" "navigation is not enabled on all layers" "" "GPAC Regression Tests" "$Date: 2008/11/24 14:58:25 $ - $Revision: 1.6 $" "(C) 2002-2004 GPAC Team"] - } - Transform2D { - translation -100 0 - children [ - Shape { - appearance DEF TXTAPP Appearance { - material Material2D { emissiveColor 1 0 0 filled TRUE } - } - geometry Text { - string ["This text" "is behind"] - fontStyle FontStyle { - size 26 - justify ["MIDDLE", "BEGIN"] - } - } - } - Layer3D { - #SHORTCUT inline viewpoint otherwise the rotation will make all models rotate - viewpoint Viewpoint {position 0 -100 1000 } - # this forbids navigation in layer - navigationInfo NavigationInfo {type ["None"]} - size 200 200 - children [ - DEF TR Transform { - children [ - DEF NEF Inline { url "auxiliary_files/nefertiti.wrl" } - ] - } - ] - } - Shape { - appearance USE TXTAPP - geometry Text { - string ["This text" "is in front"] - fontStyle FontStyle { - size 26 - justify ["MIDDLE", "END"] - } - } - } - ] - } - - Transform2D { - translation 100 50 - children [ - Layer3D { - viewpoint Viewpoint {position 0 -100 1000 } - navigationInfo NavigationInfo {type ["EXAMINE"] } - size 200 100 - children [ - Background2D {url "20" } - USE NEF - ] - } - ] - } - Transform2D { - translation 100 -50 - children [ - Layer3D { - viewpoint Viewpoint {position 0 -100 1000 } - navigationInfo NavigationInfo {headlight FALSE} - size 200 100 - children [ - Background2D { backColor 0 0 1 } - DEF DL DirectionalLight { color 0.8 0.2 0.2 direction 0 0 -1 } - USE NEF - ] - } - ] - } - - - DEF TS TimeSensor { cycleInterval 8.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [0 1 0 0, 0 1 0 3.14, 0 1 0 6.26] - } - DEF OI_L PositionInterpolator { - key [0 0.25 0.5 0.75 1] - keyValue [-1 0 0, 0 0 -1, 1 0 0, 0 0 -1, -1 0 0] - } - ] -} - -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation - -ROUTE TS.fraction_changed TO OI_L.set_fraction -ROUTE OI_L.value_changed TO DL.direction - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 10 - OCR_ES_ID 10 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 20 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.png" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-positioning-layer3D.bt b/regression_tests/bifs-3D-positioning-layer3D.bt deleted file mode 100644 index 3e0f790..0000000 --- a/regression_tests/bifs-3D-positioning-layer3D.bt +++ /dev/null @@ -1,186 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - - Background2D {url "./auxiliary_files/sky.jpg" } - - WorldInfo { - title "Layer3D test" - info ["This shows a Layer3D using the entire window" "and layer2D/layer3D defining a 2D control panel" "" "GPAC Regression Tests" "$Date: 2008/11/24 14:58:25 $ - $Revision: 1.5 $" "(C) 2002-2004 GPAC Team"] - } - - Switch { - whichChoice 0 - choice [ - Layer3D { - size 400 200 - navigationInfo DEF NAV NavigationInfo {type ["Walk","ANY"] } - children [ - DEF BACK Background {frontUrl "./auxiliary_files/logo.png" } - Inline {url "./auxiliary_files/nefertiti.wrl"} - ] - } - ] - } - Layer2D { - size -1 -1 - children [ - Transform2D { - translation 0 100 - children [ - Shape { - appearance DEF TXTAPP Appearance {material Material2D { emissiveColor 0 0 0 filled TRUE } } - geometry Text { - string ["This is a Layer3D displaying" "an inline scene with a Layer2D interface"] - fontStyle DEF FS FontStyle { - size 18 - justify ["MIDDLE", "BEGIN"] - } - } - } - ] - } - Transform2D { - translation -150 -60 - children [ - Shape { - appearance Appearance { material DEF MAT_NAV Material2D {filled TRUE emissiveColor 1 0 0} } - geometry Rectangle { size 20 20 } - } - DEF TS_NAV TouchSensor {} - Transform2D { - scale 0.8 0.8 - translation 0 -20 - children [ - Shape { - appearance USE TXTAPP - geometry DEF TXT_NAV Text { - string ["Walk"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 150 -60 - children [ - Layer3D { - size 40 40 - navigationInfo NavigationInfo {type ["Examine"] } - viewpoint Viewpoint {position 0 0 40} - children [ - Background2D {backColor 1 0 0} - DEF TR Transform { - children [ - Shape { - appearance Appearance { -# material Material { emissiveColor 0 1 0} - texture ImageTexture { url './auxiliary_files/logo.jpg"} - } - geometry Box { size 20 20 20} - } - DEF TS_BACK TouchSensor {} - ] - } - ] - } - Transform2D { - scale 0.8 0.8 - translation 0 -20 - children [ - Shape { - appearance USE TXTAPP - geometry DEF TXT_BACK Text { - string ["Background Off"] - fontStyle USE FS - } - } - ] - } - ] - } - ] - } - DEF SC Script { - eventIn SFBool set_nav - eventIn SFBool set_back - field SFNode the_nav USE NAV - field SFNode the_back USE BACK - field SFNode navmat USE MAT_NAV - field SFNode navtxt USE TXT_NAV - field SFNode backtxt USE TXT_BACK - url "javascript: - function initialize(value) { - nav_set = 0; - back_set = 0; - } - function set_nav(value) { - if (!value) return; - if (nav_set) { - nav_set = 0; - navmat.emissiveColor = new SFColor(1, 0, 0); - navtxt.string[0] = 'Walk'; - the_nav.type[0] = 'Walk'; - } else { - navmat.emissiveColor = new SFColor(0, 1, 0); - navtxt.string[0] = 'Examine'; - the_nav.type[0] = 'Examine'; - nav_set = 1; - } - } - function set_back(value) { - if (!value) return; - if (back_set) { - the_back.set_bind = false; - backtxt.string[0] = 'Background Off'; - back_set = 0; - } else { - backtxt.string[0] = 'Background On'; - the_back.set_bind = true; - back_set = 1; - } - } - " - } - - DEF TIME TimeSensor { cycleInterval 2.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - ] -} - - -ROUTE TS_NAV.isActive TO SC.set_nav -ROUTE TS_BACK.isActive TO SC.set_back -ROUTE TIME.fraction_changed TO OI.set_fraction -#ROUTE OI.value_changed TO TR.rotation - - -AT 100 { REPLACE BACK.set_bind BY 0 } diff --git a/regression_tests/bifs-3D-positioning-lod.bt b/regression_tests/bifs-3D-positioning-lod.bt deleted file mode 100644 index a6070ef..0000000 --- a/regression_tests/bifs-3D-positioning-lod.bt +++ /dev/null @@ -1,63 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - DirectionalLight { - color 1 1 1 - } - WorldInfo { - title "LOD test" - info ["This shows LOD with 2 level of details" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - LOD { - range [ 4 ] - center 0 0 0 - level [ - Shape { - appearance Appearance { - material Material { - diffuseColor 1 0 0 - } - } - geometry Sphere { radius 1 } - } - Shape { - appearance Appearance { - material Material { - diffuseColor 0 1 0 - } - } - geometry Box { size 1 1 1 } - } - ] - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-positioning-transform.bt b/regression_tests/bifs-3D-positioning-transform.bt deleted file mode 100644 index c4e0524..0000000 --- a/regression_tests/bifs-3D-positioning-transform.bt +++ /dev/null @@ -1,64 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "Transform test" - info ["This shows 3D transform on a box" "using DEF/USE and oriented scaling" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - DEF TR Transform { - translation -50 0 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 1 1 0 - } - } - geometry Box {size 50 50 50} - } - ] - } - DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - Transform { - translation 100 0 0 - scale 0.5 0.5 1 - scaleOrientation 1 0 0 0.2 - children [ - USE TR - ] - - } - ] -} - -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation diff --git a/regression_tests/bifs-3D-shapes-box-transparent.bt b/regression_tests/bifs-3D-shapes-box-transparent.bt deleted file mode 100644 index 43286a8..0000000 --- a/regression_tests/bifs-3D-shapes-box-transparent.bt +++ /dev/null @@ -1,118 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0x01 - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0x01 - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric TRUE - pixelWidth 300 - pixelHeight 200 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - Background2D {backColor 1 1 1} - WorldInfo { - title "Bitmap Test" - info ["This shows dragable bitmap with outscale" "with movieTexture in Meter Metrics" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - - DEF TR Transform { - children [ - Shape { - appearance Appearance { - material DEF MAT Material{} - texture ImageTexture { url 5} - } - geometry Box {size 50 50 50} - } - ] - } - - Transform2D { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - texture MovieTexture { - url 10 - loop TRUE - } - } - geometry Bitmap {scale 2 2} - } - DEF PS PlaneSensor2D { - maxPosition 200 200 - minPosition -200 -200 - } - ] - } - ] - } - DEF TS TimeSensor { cycleInterval 10.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.25 0.5 0.75 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26, 1 1 1 3.14, 1 1 1 6.26] - } - DEF PI PositionInterpolator { - key [0 0.25 0.5 0.75 1] - keyValue [-180 120 0, 180 120 0, 180 -120 0, -180 -120 0, -180 120 0] - } - ] -} - -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation -ROUTE TS.fraction_changed TO PI.set_fraction -ROUTE PI.value_changed TO TR.translation -ROUTE TS.fraction_changed TO MAT.transparency - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 10 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-shapes-box.bt b/regression_tests/bifs-3D-shapes-box.bt deleted file mode 100644 index 06c67cf..0000000 --- a/regression_tests/bifs-3D-shapes-box.bt +++ /dev/null @@ -1,45 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Box test" - info ["This shows a box" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - rotation 1 1 1 1.57 - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Box {size 120 100 80} - } - ] - } - ] -} diff --git a/regression_tests/bifs-3D-shapes-cone.bt b/regression_tests/bifs-3D-shapes-cone.bt deleted file mode 100644 index 62824cd..0000000 --- a/regression_tests/bifs-3D-shapes-cone.bt +++ /dev/null @@ -1,58 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Cone test" - info ["This shows a cone" "with and without cap" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - translation -70 0 0 - rotation 1 0 0 4 - children [ - Shape { - appearance Appearance { - material Material {diffuseColor 1.0 0.0 0.0 } - } - geometry Cone {height 150 bottomRadius 25} - } - ] - } - Transform { - translation 70 0 0 - rotation 1 0 0 4 - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Cone {height 150 bottomRadius 25 bottom FALSE} - } - ] - } - ] -} diff --git a/regression_tests/bifs-3D-shapes-cylinder.bt b/regression_tests/bifs-3D-shapes-cylinder.bt deleted file mode 100644 index 5cba704..0000000 --- a/regression_tests/bifs-3D-shapes-cylinder.bt +++ /dev/null @@ -1,92 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 380 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Cylinder test" - info ["This shows a cylinder" "with and without cap and side" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - translation -100 100 0 - children [ - Shape { - appearance Appearance { - material Material {diffuseColor 1.0 0.0 0.0 } - } - geometry Cylinder {height 150 radius 25} - } - ] - } - Transform { - translation 0 100 0 - rotation 1 0 0 0.78 - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Cylinder {height 150 radius 25 top FALSE} - } - ] - } - Transform { - translation -100 -100 0 - rotation 1 0 0 -0.78 - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Cylinder {height 150 radius 25 bottom FALSE} - } - ] - } - Transform { - translation 0 -100 0 - rotation 1 0 0 1.2 - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Cylinder {height 150 radius 25 bottom FALSE top FALSE} - } - ] - } - Transform { - translation 100 0 0 - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Cylinder {height 150 radius 25 side FALSE } - } - ] - } - ] -} diff --git a/regression_tests/bifs-3D-shapes-elevationgrid.bt b/regression_tests/bifs-3D-shapes-elevationgrid.bt deleted file mode 100644 index b22a907..0000000 --- a/regression_tests/bifs-3D-shapes-elevationgrid.bt +++ /dev/null @@ -1,74 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -Group { - children [ - NavigationInfo {type ["ANY" "EXAMINE"]} - Background2D { backColor 1 0 1} - Viewpoint { position 0 0 300 } - WorldInfo { - title "ElevationGrid test" - info ["This shows an ElevationGrid" "with interaction and texturing" "" "GPAC Regression Tests" "$Date: 2008/06/26 07:55:39 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - Transform { - translation -100 0 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { diffuseColor 1 0 0 } - texture DEF TX ImageTexture {url "auxiliary_files/logo.jpg"} - } - geometry ElevationGrid { - creaseAngle 2 - xSpacing 15 - zSpacing 8 - xDimension 12 - zDimension 11 - height [ 17, 14, 16, 12, 14, 21, 20, 11, 9, 16, 13, 13, - 22, 14, 17, 12, 15, 21, 17, 10, 14, 12, 19, 16, - 17, 11, 13, 11, 9, 13, 11, 11, 17, 9, 15, 11, - 9, 8, 6, 10, 7, 12, 15, 8, 11, 5, 7, 9, - 0, 0, 0, 0, 0, 5, 12, 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, - 6, 2, 0, -2, -6,-12,-11, -7, -2, 0, 1, 6, - 9, 3, -1, -4, -9,-15,-13,-11, -4, -1, 3, 9, - 11, 8, 1, -5,-11,-15,-11, -9, -7, -1, 5, 7, - 9, 8, -2,-10, -9, -9,-11,-13, -9, 1, 8, 6 ] - } - } - ] - } - DEF TS TouchSensor {} - DEF C1 Conditional { buffer { REPLACE MAT.diffuseColor BY 0 0 1} } - DEF RC1 Conditional { buffer { REPLACE MAT.diffuseColor BY 1 0 0} } - DEF C2 Conditional { buffer { REPLACE TX.url BY "./auxiliary_files/logo.png"} } - DEF RC2 Conditional { buffer { REPLACE TX.url BY ""} } - ] -} - -ROUTE TS.isOver TO C1.activate -ROUTE TS.isOver TO RC1.reverseActivate -ROUTE TS.isActive TO C2.activate -ROUTE TS.isActive TO RC2.reverseActivate diff --git a/regression_tests/bifs-3D-shapes-extrusion.bt b/regression_tests/bifs-3D-shapes-extrusion.bt deleted file mode 100644 index 1bea80f..0000000 --- a/regression_tests/bifs-3D-shapes-extrusion.bt +++ /dev/null @@ -1,99 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -Group { - children [ - - Background2D { backColor 1 1 1} - DEF VIEWPOINT Viewpoint { - description "one" - position 0 0 10 - orientation 0 1 0 0 - } - WorldInfo { - title "Extrusion test" - info ["This shows an Extrusion" "with interaction and texturing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - - DEF TR Transform { - translation 0 -1 0 - children [ - Shape { - appearance Appearance {material Material {diffuseColor 1.0 0.8 0.0} texture DEF TX ImageTexture{} } - geometry Extrusion { - creaseAngle 1 - endCap FALSE - beginCap TRUE - solid FALSE - crossSection [ - # Circle - 1.00 0.00, 0.92 -0.38, - 0.71 -0.71, 0.38 -0.92, - 0.00 -1.00, -0.38 -0.92, - -0.71 -0.71, -0.92 -0.38, - -1.00 -0.00, -0.92 0.38, - -0.71 0.71, -0.38 0.92, - 0.00 1.00, 0.38 0.92, - 0.71 0.71, 0.92 0.38, - 1.00 0.00 - ] - spine [ - # Straight-line - 0.0 0.0 0.0, 0.0 0.4 0.0, - 0.0 0.8 0.0, 0.0 1.2 0.0, - 0.0 1.6 0.0, 0.0 2.0 0.0, - 0.0 2.4 0.0, 0.0 2.8 0.0, - 0.0 3.2 0.0, 0.0 3.6 0.0, - 0.0 4.0 0.0 - ] - scale [ - 1.8 1.8, 1.95 1.95, - 2.0 2.0, 1.95 1.95 - 1.8 1.8, 1.5 1.5 - 1.2 1.2, 1.05 1.05, - 1.0 1.0, 1.05 1.05, - 1.15 1.15, - ] - } - } - DEF TOUCH TouchSensor {} - ] - } - - DEF TS TimeSensor { cycleInterval 8.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - DEF C Conditional { buffer { REPLACE TX.url BY "./auxiliary_files/logo.png"} } - DEF RC Conditional { buffer { REPLACE TX.url BY ""} } - ] -} - -ROUTE TOUCH.isActive TO C.activate -ROUTE TOUCH.isActive TO RC.reverseActivate - -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation diff --git a/regression_tests/bifs-3D-shapes-indexedfaceset.bt b/regression_tests/bifs-3D-shapes-indexedfaceset.bt deleted file mode 100644 index fbae195..0000000 --- a/regression_tests/bifs-3D-shapes-indexedfaceset.bt +++ /dev/null @@ -1,66 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "IndexedFaceSet test" - info ["This shows an IFS" "with and without colorPerVertex" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - translation -1.5 0 0 - children [ - Shape { - geometry IndexedFaceSet { - coord DEF COORD Coordinate { - point [-1 -1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1 -1 1 -1 -1 -1 -1 1 -1 -1] - } - coordIndex [0 1 2 3 -1 1 7 4 2 -1 7 6 5 4 -1 0 3 5 6 -1 3 2 4 5 -1 6 7 1 0 -1] - color DEF COL Color { - color [ 1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 0 1 1, 1 0.5 0.5, 0.5 0.5 1] - } - colorPerVertex TRUE - } - } - ] - } - Transform { - translation 1.5 0 0 - children [ - Shape { - geometry IndexedFaceSet { - coord USE COORD - coordIndex [0 1 2 3 -1 1 7 4 2 -1 7 6 5 4 -1 0 3 5 6 -1 3 2 4 5 -1 6 7 1 0 -1] - color USE COL - colorPerVertex FALSE - colorIndex [0 1 2 3 4 5 6 7] - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-shapes-indexedlineset.bt b/regression_tests/bifs-3D-shapes-indexedlineset.bt deleted file mode 100644 index 02e1795..0000000 --- a/regression_tests/bifs-3D-shapes-indexedlineset.bt +++ /dev/null @@ -1,99 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "IndexedLineSet test" - info ["This shows an ILS" "with and without color per vertex" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - translation -1.5 0 0 - children [ - Shape { - geometry IndexedLineSet { - coord DEF COORD Coordinate { - point [ - # the top of the cube - -1.0 1.0 1.0, - 1.0 1.0 1.0, - 1.0 1.0 -1.0, - -1.0 1.0 -1.0, - # around the bottom of the cube - -1.0 -1.0 1.0, - 1.0 -1.0 1.0, - 1.0 -1.0 -1.0, - -1.0 -1.0 -1.0 - ] - } - coordIndex [ - # top - 0, 1, 2, 3, 0, -1, - # bottom - 4, 5, 6, 7, 4, -1, - # vertical edges - 0, 4, -1, - 1, 5, -1, - 2, 6, -1, - 3, 7 - ] - color Color { - color [1 0 0, 0 1 0, 0 0 1, 1 1 0] - } - colorPerVertex TRUE - colorIndex [0, 1, 2, 3, 0, -1, 0, 1, 2, 3, 0, -1, 0, 3, -1, 0, 2, -1, 0, 1, -1, 1 3] - } - } - ] - } - Transform { - translation 1.5 0 0 - children [ - Shape { - geometry IndexedLineSet { - coord USE COORD - coordIndex [ - # top - 0, 1, 2, 3, 0, -1, - # bottom - 4, 5, 6, 7, 4, -1, - # vertical edges - 0, 4, -1, - 1, 5, -1, - 2, 6, -1, - 3, 7 - ] - color Color { - color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 0 1 1, 1 0 1] - } - colorPerVertex FALSE - colorIndex [0, 1, 2, 3, 4, 5] - } - } - ] - } - ] -} diff --git a/regression_tests/bifs-3D-shapes-nonlineardeformer.bt b/regression_tests/bifs-3D-shapes-nonlineardeformer.bt deleted file mode 100644 index 3010f57..0000000 --- a/regression_tests/bifs-3D-shapes-nonlineardeformer.bt +++ /dev/null @@ -1,796 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - - WorldInfo { - info ["This shows NonLinearDeformer" "in different modes and differnet axis." "Deformation is controled through the NLD.extend field" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "NonLinearDeformer Test" - } - Viewpoint { position 0 -1 10 } - NavigationInfo {type ["EXAMINE"]} - Transform { - translation -0.1337 -2.107 -1.839 - children [ - - Shape { - appearance Appearance { - material Material { - diffuseColor 0.9804 0.9804 0.9804 - } - } - geometry DEF NLD NonLinearDeformer { - type 0 - param 1 - axis 0 1 0 - extend [0 0.5 0.5 1 1 0.2] - geometry IndexedFaceSet { - ccw TRUE - solid FALSE - creaseAngle 2 - coord Coordinate { point [ - -2.116 1.757 -1.271, -2.036 1.587 -1.231, -2.136 1.607 -1.391, - -2.206 1.837 -1.361, -2.216 1.867 -1.161, -2.116 1.697 -1.111, - -2.066 1.457 -1.131, -1.946 1.607 -0.9606, -1.966 1.387 -1.011, - -2.076 1.337 -1.251, -2.096 1.397 -1.301, -2.396 1.687 -1.561, - -2.306 1.477 -1.521, -2.466 1.527 -1.711, -2.446 1.737 -1.651, - -2.396 1.877 -1.491, -2.326 1.217 -1.511, -2.186 1.437 -1.431, - -2.086 1.257 -1.391, -2.096 1.127 -1.411, -2.196 0.9375 -1.391, - -2.386 1.017 -1.521, -2.486 1.217 -1.691, -2.056 0.9875 -1.251, - -1.976 1.267 -1.141, -1.876 1.167 -1.121, -1.996 0.8775 -1.001, - -2.116 0.8775 -1.201, -1.946 1.267 -1.001, -1.916 1.297 -0.9206, - -1.966 1.197 -0.9206, -1.886 1.127 -0.9906, -1.946 1.287 -1.081, - -1.986 1.017 -0.8106, -1.926 1.127 -0.7606, -1.896 0.9375 -0.6006, - -1.976 0.7975 -0.6606, -1.926 0.9575 -0.9206, -2.136 0.7675 -0.8906, - -1.996 0.5875 -0.6606, -2.136 0.5575 -0.9806, -2.226 0.7575 -1.111, - -1.906 0.3475 -0.6006, -1.856 0.5175 -0.5106, -1.746 0.2775 -0.5806, - -1.906 0.2275 -0.7406, -2.036 0.3375 -0.9706, -2.046 0.4775 -0.7806, - -1.866 0.7975 -0.5406, -2.296 0.8575 -1.351, -2.196 0.6175 -1.211, - -2.236 0.6575 -1.421, -2.346 0.8575 -1.581, -2.386 0.9575 -1.541, - -2.116 0.4775 -1.171, -1.776 0.2875 -0.9306, -1.846 0.4775 -1.181, - -1.566 0.2275 -0.7506, -1.566 0.4375 -0.9906, -1.636 0.7175 -1.341, - -1.986 0.7375 -1.431, -1.756 1.027 -1.601, -2.136 1.097 -1.701, - -2.276 1.537 -1.751, -2.536 1.687 -1.771, -2.466 1.217 -1.751, - -1.966 1.377 -1.751, -2.076 1.717 -1.721, -2.316 1.877 -1.631, - -2.546 1.537 -1.741, -2.546 1.747 -1.671, -2.556 1.937 -1.611, - -2.536 1.897 -1.581, -2.206 1.947 -1.611, -2.326 2.037 -1.421, - -2.316 2.027 -1.231, -2.176 2.067 -1.291, -2.356 1.927 -1.331, - -2.186 1.907 -1.061, -1.976 1.957 -1.001, -2.106 1.857 -1.041, - -1.866 0.9475 -0.3906, -1.936 1.367 -0.2506, -1.946 1.297 -0.0005862, - -1.886 0.8775 0.4194, -1.806 0.4475 0.2294, -1.786 0.1875 0.1694, - -1.806 0.3175 -0.2706, -1.366 0.3575 -2.181, -1.406 0.05749 -1.281, - -1.556 -0.1525 -0.7106, -1.516 -0.6325 -1.151, -1.146 -0.6925 -1.741, - -1.086 -0.2125 -1.911, -1.786 -0.1825 0.03941, -1.766 -0.1525 -0.3606, - -1.706 -0.09251 0.3694, -1.706 -0.3625 0.2894, -1.616 -1.023 -0.1406, - -1.646 -0.8525 -0.4206, -1.576 -0.8825 -0.6006, -1.556 -1.053 -0.4206, - -1.346 -1.333 -0.3906, -1.486 -1.393 -0.9606, -0.7163 -0.6425 -2.381, - -1.036 -1.113 -2.021, -0.7363 -1.093 -2.401, -0.0763 -0.5625 -2.381, - -0.5963 -0.5225 -2.471, -0.5563 -0.4825 -2.571, -1.056 -0.03251 -2.361, - -0.0963 -1.093 -2.371, -0.1063 -1.473 -2.511, -0.7963 -1.483 -2.531, - -1.366 -1.963 -1.861, -1.386 -2.313 -2.071, -0.9363 -1.943 -2.681, - -0.7963 -1.913 -2.791, -0.8963 -3.243 -3.621, -1.706 -3.973 -3.811, - -0.9963 -4.103 -4.111, -0.2363 -4.093 -4.191, -0.2063 -3.353 -3.741, - -0.1663 -2.603 -3.231, -0.8963 -2.513 -3.141, -1.126 -2.563 -3.001, - -1.386 -3.223 -3.371, -0.1363 -2.063 -2.891, -1.826 -3.313 -2.851, - -2.236 -3.693 -2.581, -2.136 -3.713 -3.151, -1.536 -2.833 -2.451, - -1.946 -3.423 -2.331, -1.926 -3.633 -2.031, -1.956 -4.303 -1.764, - -2.226 -3.873 -2.171, -1.676 -3.073 -2.071, -1.666 -3.253 -1.851, - -1.696 -4.023 -1.671, -1.426 -4.363 -1.411, -1.276 -5.023 -1.261, - -1.666 -4.683 -1.501, -1.486 -3.683 -1.491, -1.246 -4.053 -1.211, - -1.216 -4.623 -1.281, -1.376 -3.073 -1.221, -1.476 -2.773 -1.491, - -1.406 -2.483 -1.201, -1.166 -2.893 -0.7706, -1.046 -3.473 -0.8406, - -1.526 -2.563 -1.731, -1.446 -2.233 -1.511, -0.8263 -5.193 -1.071, - -0.9163 -4.373 -1.001, -0.6763 -4.483 -1.001, -0.5263 -5.313 -1.121, - -0.3563 -5.333 -1.131, -0.3663 -4.643 -1.021, -0.1763 -4.753 -1.051, - -0.1963 -5.383 -1.131, -0.4363 -3.893 -0.7006, -0.8863 -3.613 -0.7806, - -0.4763 -3.393 -0.5006, -0.1263 -3.533 -0.5006, -0.1463 -4.033 -0.7306, - -1.456 -1.853 -1.241, -1.386 -1.483 -1.611, -1.486 -1.443 -1.231, - -1.316 -2.193 -0.8206, -0.5163 -2.813 -0.2806, -1.036 -3.023 -0.7006, - -1.196 -2.353 -0.6606, -0.8663 -2.103 -0.1806, -0.5563 -1.883 0.2294, - -0.0963 -2.933 -0.2106, -1.346 -1.533 -0.5406, -1.096 -1.573 -0.1606, - -0.0563 -1.943 0.3194, -0.0363 -1.683 0.7494, -0.5663 -1.643 0.5794, - -1.146 -1.393 0.3994, -1.516 -1.173 -0.2506, -1.286 -1.353 0.1994, - -1.386 -1.193 0.4494, -0.5363 -1.483 1.049, -0.9463 -1.283 1.249, - -0.5563 -1.473 1.399, -0.0063 -1.513 1.649, -1.566 -0.8925 0.3994, - -1.396 -0.7425 0.8494, -1.636 0.04749 0.7194, -1.476 -0.1825 0.9894, - -1.296 -0.3925 1.199, -1.146 -0.7725 1.289, -0.9763 -1.073 1.419, - -0.6263 -1.363 1.779, -0.2763 -1.483 1.829, -0.7363 -1.173 1.769, - -0.5263 -1.183 2.009, -0.3963 -1.373 1.969, 0.0137 -1.353 2.069, - -0.3563 -1.223 2.149, -0.3663 -0.9425 2.139, 0.0237 -1.013 2.219, - 0.0237 -1.233 2.209, -0.9063 -0.8825 1.549, -0.9963 -0.5625 1.519, - -0.7563 -0.6625 1.699, -0.6463 -0.8825 1.859, -1.736 0.2775 0.4994, - -1.846 0.8575 0.7094, -1.696 0.3575 0.8394, -1.576 0.3675 1.109, - -1.386 -0.1125 1.169, -1.756 0.8475 1.009, -1.536 0.8375 1.299, - -1.326 0.4575 1.419, -1.056 0.08749 1.569, -1.106 0.6175 1.629, - -0.8663 0.3575 1.769, -0.8263 0.05749 1.839, -1.026 -0.2525 1.579, - -0.2263 -0.6525 2.109, -0.3863 -0.6325 2.069, -0.2463 -0.5525 2.179, - 0.0337 -0.6925 2.129, -0.4063 -0.5325 2.129, -0.4963 -0.4525 2.019, - -0.4163 -0.3925 2.099, -0.2663 -0.4225 2.199, -0.0963 -0.4525 2.209, - 0.0437 -0.5625 2.209, -0.1563 -0.2725 2.139, 0.0537 -0.3125 2.179, - 0.0437 -0.4525 2.229, -0.5263 -0.5725 1.919, -0.7363 -0.3125 1.709, - -0.5263 0.02749 1.999, -0.4263 -0.08251 2.099, -0.4263 -0.1925 2.079, - -0.4063 -0.2825 2.039, -0.2963 -0.2825 2.109, -0.3363 -0.1525 2.159, - -0.0563 -0.1425 2.299, -0.1863 -0.1425 2.229, -0.1263 0.02749 2.299, - 0.0637 -0.002507 2.319, 0.0537 -0.1425 2.299, -0.3363 -0.04251 2.209, - -0.0863 0.1175 2.279, -0.2563 0.4275 2.069, -0.0263 0.3575 2.229, - 0.0737 0.3275 2.229, 0.0637 0.1175 2.259, -0.6963 0.1875 1.899, - -0.4263 0.4675 1.969, -0.0763 0.6175 2.109, -0.3663 0.5675 2.149, - -0.2263 0.6175 2.279, -0.0963 0.5975 2.359, -0.0163 0.5075 2.409, - -0.4363 0.6075 2.049, -0.4963 0.6675 1.899, -0.3963 0.7375 2.139, - -0.2663 0.6775 2.319, -0.0963 0.6675 2.489, -0.1363 0.8275 2.439, - -0.0063 0.8675 2.529, 0.0937 0.7575 2.569, 0.0837 0.4875 2.439, - -1.306 0.8475 1.509, -1.456 1.227 1.339, -1.206 1.167 1.509, - -0.9263 0.8775 1.709, -0.8763 1.187 1.649, -1.126 1.447 1.479, - -0.8663 1.457 1.549, -0.5663 1.487 1.569, -0.4163 1.357 1.749, - -0.5063 1.017 1.849, -0.2963 0.9775 1.999, -0.2063 0.9075 2.229, - -0.0763 1.177 2.229, -0.3263 1.697 1.629, -0.0663 2.097 1.749, - 0.1037 1.417 2.229, 0.1237 2.127 1.839, -1.386 1.727 1.249, - -1.466 1.567 1.219, -1.646 1.747 0.9494, -1.346 1.887 1.359, - -1.296 1.767 1.359, -1.206 1.647 1.409, -1.096 1.607 1.479, - -1.146 1.707 1.479, -0.9963 1.697 1.529, -0.8663 1.597 1.529, - -0.6463 1.607 1.549, -0.7663 1.707 1.549, -0.5263 1.727 1.479, - -0.4563 1.667 1.539, -0.5063 1.947 1.539, -0.3563 2.047 1.509, - -1.646 1.277 1.149, -1.816 1.417 0.8194, -1.906 1.207 0.5394, - -1.906 1.537 0.2594, -1.836 1.747 0.4994, -1.806 1.717 0.7294, - -1.436 2.037 1.149, -1.716 1.877 0.8394, -1.596 2.197 1.099, - -1.186 2.287 1.359, -1.786 2.037 0.7494, -1.886 1.877 0.009414, - -1.796 2.277 0.4294, -1.656 2.317 1.039, -0.9863 2.337 1.459, - -0.8663 2.057 1.589, -1.086 2.037 1.549, -0.9963 2.527 1.529, - -0.6863 2.507 1.579, -0.7163 2.307 1.479, -0.4863 2.207 1.479, - -0.3563 2.367 1.649, -0.3163 2.517 1.709, -0.6463 2.677 1.629, - -0.5563 2.997 1.479, -0.1163 2.867 1.549, -1.036 2.737 1.529, - -1.326 2.467 1.369, -1.386 2.627 1.359, -1.026 3.027 1.369, - 0.1337 2.747 1.589, 0.1437 3.517 1.219, -0.3963 3.517 1.239, - -1.026 3.427 1.129, -1.436 3.257 0.9294, -1.386 2.897 1.179, - -1.696 2.607 0.7894, -1.836 2.567 0.06941, -1.706 2.937 0.5194, - -1.916 2.047 -0.7406, 1.934 0.7375 0.6094, 1.854 0.7275 0.9194, - 1.944 1.297 0.7194, 2.004 1.917 -0.8406, 2.044 1.827 -1.101, - 1.994 1.477 -1.061, 2.004 1.237 -0.3506, 2.004 1.747 -0.09059, - 2.024 1.167 -0.1006, 2.014 1.407 0.1594, 1.964 1.627 0.3994, - 1.964 2.157 0.3294, 1.994 2.447 -0.03059, 1.694 3.157 0.8494, - 1.914 2.817 0.4294, 1.634 2.797 1.099, 1.624 2.527 1.279, - 1.904 2.487 0.6994, 1.854 2.207 0.9494, 1.284 2.957 1.309, - 1.304 3.357 1.069, 0.6837 3.487 1.209, 0.8237 2.957 1.439, - 0.3837 2.847 1.539, 1.554 2.377 1.299, 1.794 2.087 1.009, - 1.404 2.207 1.289, 1.624 1.937 1.069, 1.234 2.457 1.469, - 0.9037 2.627 1.589, 1.284 2.667 1.469, 0.9237 2.457 1.539, - 0.5937 2.337 1.629, 0.2937 2.087 1.739, 0.5637 2.487 1.689, - 0.5637 2.017 1.489, 1.294 1.957 1.489, 1.534 1.797 1.289, - 0.7137 1.907 1.509, 0.7037 2.167 1.449, 0.9437 2.257 1.439, - 1.074 1.997 1.539, 1.214 2.267 1.399, 1.874 1.757 0.7494, - 1.954 1.917 0.6494, 1.944 1.597 0.6294, 1.804 1.637 0.8594, - 2.004 1.077 0.4394, 1.954 0.7575 0.3194, 0.7437 1.447 1.539, - 0.5937 1.327 1.719, 0.6437 1.627 1.509, 1.624 1.467 1.139, - 1.294 1.367 1.419, 1.384 1.567 1.339, 1.784 1.167 1.059, - 1.654 0.7375 1.219, 1.604 1.127 1.259, 1.354 1.087 1.439, - 0.5137 1.667 1.609, 0.7137 1.687 1.449, 0.9537 1.647 1.509, - 1.184 1.627 1.469, 1.044 1.537 1.479, 1.334 1.627 1.419, - 1.474 1.677 1.289, 0.8237 1.557 1.509, 1.034 1.397 1.499, - 1.274 1.527 1.419, 1.554 1.637 1.169, 1.754 0.2475 0.7494, - 0.6637 0.9775 1.819, 0.4637 0.9575 1.979, 0.1937 0.8575 2.519, - 0.3137 0.8175 2.429, 0.2637 1.167 2.219, 0.3837 0.8875 2.209, - 0.4337 0.6575 2.299, 0.5537 0.7075 2.119, 0.6337 0.6275 1.869, - 1.064 0.8175 1.659, 0.9737 0.2975 1.719, 1.224 0.5375 1.569, - 0.5537 0.4375 1.939, 1.034 1.127 1.599, 1.434 0.7575 1.439, - 1.424 0.3675 1.349, 0.1737 0.4975 2.409, 0.2637 0.6575 2.479, - 0.1637 0.3475 2.229, 0.3837 0.5975 2.259, 0.2537 0.5875 2.349, - 0.5137 0.5375 2.129, 0.3937 0.4075 2.049, 0.5837 0.5775 2.019, - 0.2237 0.6075 2.099, 0.6337 -0.01251 1.969, 0.8037 0.1375 1.859, - 0.9237 -0.002507 1.789, 0.2437 0.01749 2.289, 0.2137 0.1075 2.269, - 0.4437 -0.07251 2.189, 0.2537 -0.2825 2.129, 0.2937 -0.1625 2.219, - 0.4337 -0.1725 2.139, 0.5237 -0.2225 2.059, 0.5237 -0.1125 2.079, - 0.1637 -0.1525 2.289, 0.3537 -0.4425 2.179, 0.3837 -0.3025 2.089, - 0.4937 -0.3125 2.019, 0.4937 -0.4225 2.079, 0.8037 -0.7125 1.659, - 0.5837 -0.6125 1.889, 0.8037 -0.3625 1.669, 0.5737 -0.4825 1.989, - 1.084 -0.3225 1.529, 1.034 -0.6325 1.469, 0.6837 -0.9225 1.829, - 0.4137 -0.9725 2.119, 0.4537 -0.6625 2.049, 0.3237 -0.5725 2.169, - 0.1837 -0.4625 2.199, 0.4837 -0.5625 2.109, 0.2937 -0.6725 2.099, - 1.324 -0.4725 1.129, 1.164 -0.8425 1.229, 1.514 -0.2825 0.9094, - 1.434 -0.2025 1.099, 1.674 -0.06251 0.6294, 1.144 0.01749 1.509, - 1.654 0.2675 1.029, 1.774 0.1675 0.4094, 1.844 0.3275 0.1394, - 1.804 0.06749 0.07941, 1.714 -0.2025 0.2794, 0.7537 -1.223 1.729, - 0.5537 -1.213 1.979, 0.9737 -1.133 1.369, 0.9237 -0.9425 1.499, - 0.9237 -1.343 1.199, 0.4037 -1.403 1.949, 0.2737 -1.503 1.819, - 0.5337 -1.513 1.369, 0.3837 -1.243 2.129, 0.6237 -1.403 1.749, - 1.694 -0.4725 0.1994, 1.524 -0.9925 0.3194, 1.384 -0.8325 0.7794, - 1.324 -1.283 0.3794, 1.074 -1.463 0.3394, 1.534 -1.123 -0.2206, - 1.564 -0.9525 -0.5006, 1.464 -1.153 -0.5006, 0.4937 -1.513 1.019, - 0.4837 -1.673 0.5494, 1.424 -1.263 -0.3306, 1.204 -1.433 0.1394, - 1.234 -1.413 -0.4606, 0.9837 -1.643 -0.2106, 0.4437 -1.913 0.1994, - 0.2337 -3.413 -0.5206, 0.7137 -2.153 -0.2206, 1.004 -2.423 -0.7206, - 1.124 -2.273 -0.8806, 1.214 -1.613 -0.6106, 1.344 -1.483 -1.031, - 0.7737 -3.533 -0.8906, 0.6137 -3.663 -0.8206, 0.9337 -2.963 -0.8206, - 0.8037 -3.083 -0.7506, 1.184 -2.563 -1.271, 0.3237 -2.843 -0.3006, - 0.8537 -1.173 -2.071, 1.204 -1.563 -1.681, 1.004 -0.7625 -1.801, - 1.414 -0.7225 -1.231, 1.324 -1.533 -1.301, 1.144 -2.043 -1.931, - 1.224 -2.323 -1.581, 1.264 -1.943 -1.311, 1.214 -2.863 -1.561, - 0.9137 -4.123 -1.271, 0.5837 -4.423 -1.041, 0.3337 -4.513 -1.031, - 0.1437 -3.913 -0.7206, 0.0137 -4.653 -1.031, -0.0463 -5.343 -1.141, - 0.1237 -5.333 -1.141, 0.4337 -5.233 -1.101, 0.8437 -4.693 -1.331, - 0.8837 -5.093 -1.321, 1.344 -4.123 -1.751, 1.584 -4.413 -1.854, - 1.284 -4.773 -1.581, 1.164 -3.773 -1.561, 1.354 -3.353 -1.931, - 1.264 -2.653 -1.801, 1.124 -2.393 -2.141, 1.364 -3.173 -2.151, - 1.114 -3.153 -1.281, 1.064 -4.443 -1.471, 1.004 -3.303 -3.431, - 1.244 -4.073 -3.891, 1.724 -3.833 -3.251, 1.854 -3.823 -2.691, - 1.854 -4.003 -2.281, 1.594 -3.533 -2.421, 1.224 -2.923 -2.521, - 0.6737 -1.993 -2.721, 0.8037 -2.623 -3.051, 1.584 -3.743 -2.121, - 1.464 -3.423 -2.941, 0.5237 -1.953 -2.821, 0.5737 -2.563 -3.181, - 0.4937 -3.283 -3.661, 0.5137 -4.153 -4.151, 0.5437 -1.133 -2.431, - 0.5637 -1.523 -2.571, 0.4337 -0.5525 -2.501, 0.3937 -0.5125 -2.591, - 1.274 0.2775 -2.251, 0.9237 -0.09251 -2.411, 0.9737 -0.2825 -1.961, - 0.5537 -0.6825 -2.411, 1.734 -0.2625 -0.4506, 1.504 -0.2525 -0.7906, - 1.484 -0.9825 -0.6806, 1.724 0.1675 -0.6706, 1.774 -0.2925 -0.05059, - 1.804 0.1975 -0.3606, 1.534 0.1275 -0.8306, 1.854 0.3975 -0.6106, - 1.884 0.6775 -0.6406, 1.534 0.3375 -1.071, 1.334 -0.03251 -1.351, - 1.604 0.6175 -1.421, 1.734 0.9175 -1.691, 1.944 1.177 -1.021, - 1.954 1.007 -0.8606, 1.904 0.8275 -0.4906, 1.924 0.8175 -0.7006, - 1.994 1.257 -1.111, 2.164 1.557 -1.221, 2.164 1.717 -1.151, - 2.234 1.927 -1.401, 2.244 1.767 -1.181, 2.374 1.877 -1.351, - 2.264 1.727 -1.281, 2.404 1.777 -1.451, 2.564 1.737 -1.711, - 2.434 1.717 -1.621, 2.244 1.697 -1.481, 2.464 1.577 -1.781, - 2.564 1.587 -1.801, 2.374 1.887 -1.541, 2.244 1.807 -1.731, - 2.094 1.587 -1.831, 2.344 1.727 -1.751, 2.584 1.767 -1.741, - 2.544 1.527 -1.901, 2.114 0.9575 -1.811, 2.314 0.7075 -1.701, - 2.444 1.057 -1.881, 2.314 1.327 -1.641, 2.464 1.367 -1.841, - 2.464 1.057 -1.821, 2.364 0.8675 -1.641, 2.364 0.8075 -1.661, - 2.544 1.377 -1.871, 1.954 1.247 -1.851, 2.274 1.387 -1.871, - 1.954 0.6075 -1.531, 1.814 0.3575 -1.271, 2.194 0.5175 -1.541, - 1.744 0.1775 -1.021, 1.874 0.1075 -0.8406, 2.004 0.2075 -1.071, - 2.084 0.3375 -1.281, 2.114 0.4175 -1.091, 2.164 0.4775 -1.321, - 2.214 0.6175 -1.231, 2.034 0.3475 -0.8906, 1.994 0.4575 -0.7606, - 2.274 0.7075 -1.471, 2.104 0.7375 -1.311, 2.174 0.7975 -1.501, - 1.984 0.6675 -0.7606, 1.894 0.2275 -0.7006, 1.994 0.7475 -1.101, - 1.934 0.8375 -1.021, 1.884 1.047 -1.221, 1.904 1.007 -1.091, - 2.134 0.6275 -1.001, 1.994 1.067 -1.021, 2.004 0.8875 -0.9106, - 2.094 1.207 -1.361, 1.964 1.157 -1.181, 1.994 1.137 -1.241, - 1.974 1.137 -1.101, 2.114 1.257 -1.411, 2.084 1.127 -1.501, - 2.044 0.8575 -1.361, 2.084 0.9975 -1.521, 2.194 1.297 -1.541, - 2.164 1.467 -1.501, 2.064 1.457 -1.341, 2.314 1.067 -1.631, - 2.414 1.537 -1.681, 2.094 1.327 -1.241, 2.154 1.617 -1.381] - } - coordIndex [ - 1, 0, 2, -1, - 2, 0, 3, -1, 3, 0, 4, -1, 4, 0, 5, -1, 5, 0, 1, -1, - 5, 6, 7, -1, 7, 6, 8, -1, 8, 6, 9, -1, 9, 6, 10, -1, - 10, 6, 1, -1, 1, 6, 5, -1, 3, 11, 2, -1, 2, 11, 12, -1, - 12, 11, 13, -1, 13, 11, 14, -1, 14, 11, 15, -1, 15, 11, 3, -1, - 12, 16, 17, -1, 17, 16, 10, -1, 10, 16, 18, -1, 18, 16, 19, -1, - 19, 16, 20, -1, 20, 16, 21, -1, 21, 16, 22, -1, 22, 16, 12, -1, - 1, 2, 10, -1, 17, 10, 2, -1, 17, 2, 12, -1, 9, 23, 24, -1, - 24, 23, 25, -1, 25, 23, 26, -1, 26, 23, 27, -1, 27, 23, 20, -1, - 20, 23, 19, -1, 19, 23, 18, -1, 18, 23, 9, -1, 18, 9, 10, -1, - 8, 28, 29, -1, 29, 28, 30, -1, 30, 28, 31, -1, 31, 28, 25, -1, - 25, 28, 32, -1, 32, 28, 8, -1, 25, 32, 24, -1, 24, 32, 9, -1, - 9, 32, 8, -1, 31, 33, 30, -1, 30, 33, 34, -1, 34, 33, 35, -1, - 35, 33, 36, -1, 36, 33, 37, -1, 37, 33, 31, -1, 30, 34, 29, -1, - 26, 38, 36, -1, 36, 38, 39, -1, 39, 38, 40, -1, 40, 38, 41, -1, - 41, 38, 26, -1, 36, 37, 26, -1, 31, 25, 37, -1, 37, 25, 26, -1, - 26, 27, 41, -1, 39, 42, 43, -1, 43, 42, 44, -1, 44, 42, 45, -1, - 45, 42, 46, -1, 46, 42, 47, -1, 47, 42, 39, -1, 43, 48, 39, -1, - 36, 39, 48, -1, 36, 48, 35, -1, 21, 49, 20, -1, 20, 49, 27, -1, - 27, 49, 41, -1, 41, 49, 50, -1, 50, 49, 51, -1, 51, 49, 52, -1, - 52, 49, 53, -1, 53, 49, 21, -1, 39, 40, 47, -1, 47, 40, 46, -1, - 40, 41, 50, -1, 51, 54, 50, -1, 50, 54, 40, -1, 40, 54, 46, -1, - 46, 54, 55, -1, 55, 54, 56, -1, 56, 54, 51, -1, 45, 46, 55, -1, - 45, 55, 57, -1, 45, 57, 44, -1, 57, 55, 58, -1, 56, 58, 55, -1, - 58, 56, 59, -1, 61, 60, 62, -1, 62, 60, 52, -1, 52, 60, 51, -1, - 51, 60, 56, -1, 56, 60, 59, -1, 59, 60, 61, -1, 64, 63, 65, -1, - 65, 63, 62, -1, 62, 63, 66, -1, 66, 63, 67, -1, 67, 63, 68, -1, - 68, 63, 64, -1, 66, 62, 61, -1, 14, 69, 13, -1, 13, 69, 22, -1, - 22, 69, 65, -1, 65, 69, 64, -1, 64, 69, 70, -1, 70, 69, 14, -1, - 52, 53, 65, -1, 53, 21, 65, -1, 22, 65, 21, -1, 13, 22, 12, -1, - 52, 65, 62, -1, 72, 71, 70, -1, 70, 71, 64, -1, 64, 71, 68, -1, - 68, 71, 73, -1, 73, 71, 74, -1, 74, 71, 75, -1, 75, 71, 72, -1, - 68, 73, 67, -1, 76, 73, 74, -1, 76, 74, 75, -1, 70, 14, 72, -1, - 72, 14, 15, -1, 4, 77, 3, -1, 3, 77, 15, -1, 15, 77, 72, -1, - 72, 77, 75, -1, 75, 77, 4, -1, 79, 78, 80, -1, 80, 78, 5, -1, - 5, 78, 4, -1, 4, 78, 75, -1, 75, 78, 76, -1, 76, 78, 79, -1, - 7, 79, 80, -1, 7, 80, 5, -1, 8, 29, 7, -1, 29, 81, 7, -1, - 7, 81, 82, -1, 82, 81, 83, -1, 83, 81, 84, -1, 84, 81, 85, -1, - 85, 81, 86, -1, 86, 81, 87, -1, 87, 81, 48, -1, 48, 81, 35, -1, - 35, 81, 34, -1, 34, 81, 29, -1, 61, 88, 59, -1, 58, 59, 88, -1, - 58, 89, 57, -1, 57, 89, 90, -1, 90, 89, 91, -1, 91, 89, 92, -1, - 92, 89, 93, -1, 93, 89, 88, -1, 88, 89, 58, -1, 87, 48, 43, -1, - 87, 43, 44, -1, 90, 44, 57, -1, 95, 94, 44, -1, 44, 94, 87, -1, - 87, 94, 86, -1, 86, 94, 96, -1, 96, 94, 97, -1, 97, 94, 98, -1, - 98, 94, 99, -1, 99, 94, 95, -1, 95, 44, 90, -1, 91, 100, 90, -1, - 90, 100, 99, -1, 99, 100, 101, -1, 101, 100, 102, -1, - 102, 100, 103, -1, 103, 100, 91, -1, 90, 99, 95, -1, - 93, 104, 92, -1, 92, 104, 105, -1, 105, 104, 106, -1, - 106, 104, 107, -1, 107, 104, 108, -1, 108, 104, 93, -1, - 109, 108, 110, -1, 93, 110, 108, -1, 110, 93, 88, -1, - 108, 109, 107, -1, 106, 111, 112, -1, 106, 113, 105, -1, - 105, 113, 114, -1, 114, 113, 115, -1, 115, 113, 116, -1, - 116, 113, 117, -1, 117, 113, 112, -1, 112, 113, 106, -1, - 111, 106, 107, -1, 119, 118, 120, -1, 120, 118, 121, -1, - 121, 118, 122, -1, 122, 118, 123, -1, 123, 118, 124, -1, - 124, 118, 125, -1, 125, 118, 126, -1, 126, 118, 119, -1, - 125, 116, 117, -1, 125, 117, 124, -1, 123, 124, 117, -1, - 123, 117, 127, -1, 112, 127, 117, -1, 129, 128, 130, -1, - 130, 128, 126, -1, 126, 128, 125, -1, 125, 128, 131, -1, - 131, 128, 132, -1, 132, 128, 129, -1, 134, 133, 135, -1, - 135, 133, 132, -1, 132, 133, 136, -1, 136, 133, 137, -1, - 137, 133, 138, -1, 138, 133, 134, -1, 131, 116, 125, -1, - 115, 116, 131, -1, 115, 131, 136, -1, 132, 136, 131, -1, - 135, 132, 129, -1, 119, 130, 126, -1, 140, 139, 141, -1, - 141, 139, 138, -1, 138, 139, 142, -1, 142, 139, 143, -1, - 143, 139, 144, -1, 144, 139, 140, -1, 143, 145, 142, -1, - 142, 145, 146, -1, 146, 145, 147, -1, 147, 145, 148, -1, - 148, 145, 149, -1, 149, 145, 143, -1, 146, 150, 137, -1, - 137, 150, 136, -1, 136, 150, 115, -1, 115, 150, 114, -1, - 114, 150, 151, -1, 151, 150, 146, -1, 138, 142, 137, -1, - 146, 137, 142, -1, 134, 141, 138, -1, 140, 152, 144, -1, - 143, 144, 152, -1, 143, 152, 153, -1, 154, 153, 152, -1, - 154, 152, 155, -1, 154, 155, 156, -1, 154, 156, 157, -1, - 158, 157, 156, -1, 158, 156, 159, -1, 158, 160, 157, -1, - 157, 160, 154, -1, 154, 160, 161, -1, 161, 160, 162, -1, - 162, 160, 163, -1, 163, 160, 164, -1, 164, 160, 158, -1, - 153, 154, 161, -1, 153, 161, 149, -1, 153, 149, 143, -1, - 146, 147, 151, -1, 151, 165, 166, -1, 166, 165, 167, -1, - 167, 165, 103, -1, 103, 165, 168, -1, 168, 165, 147, -1, - 147, 165, 151, -1, 151, 166, 114, -1, 105, 114, 166, -1, - 103, 91, 167, -1, 166, 167, 91, -1, 166, 91, 92, -1, - 166, 92, 105, -1, 162, 169, 170, -1, 170, 169, 171, -1, - 171, 169, 172, -1, 172, 169, 173, -1, 173, 169, 174, -1, - 174, 169, 162, -1, 148, 170, 171, -1, 148, 171, 168, -1, - 148, 168, 147, -1, 162, 170, 161, -1, 148, 161, 170, -1, - 161, 148, 149, -1, 176, 175, 168, -1, 168, 175, 103, -1, - 103, 175, 102, -1, 102, 175, 176, -1, 168, 171, 176, -1, - 172, 176, 171, -1, 176, 172, 173, -1, 163, 174, 162, -1, - 177, 173, 174, -1, 173, 177, 178, -1, 173, 178, 179, -1, - 173, 179, 180, -1, 173, 180, 176, -1, 101, 102, 181, -1, - 101, 181, 98, -1, 98, 182, 183, -1, 183, 182, 180, -1, - 180, 182, 176, -1, 176, 182, 102, -1, 102, 182, 181, -1, - 181, 182, 98, -1, 178, 184, 179, -1, 179, 184, 180, -1, - 180, 184, 185, -1, 185, 184, 186, -1, 186, 184, 187, -1, - 187, 184, 178, -1, 101, 98, 99, -1, 183, 188, 98, -1, - 98, 188, 97, -1, 183, 180, 185, -1, 97, 189, 96, -1, - 96, 189, 190, -1, 190, 189, 191, -1, 191, 189, 192, -1, - 192, 189, 193, -1, 193, 189, 194, -1, 194, 189, 185, -1, - 185, 189, 183, -1, 183, 189, 188, -1, 188, 189, 97, -1, - 196, 195, 186, -1, 186, 195, 185, -1, 185, 195, 197, -1, - 197, 195, 198, -1, 198, 195, 199, -1, 199, 195, 196, -1, - 196, 187, 200, -1, 200, 201, 199, -1, 199, 201, 198, -1, - 198, 201, 202, -1, 202, 201, 203, -1, 203, 201, 204, -1, - 204, 201, 200, -1, 187, 196, 186, -1, 196, 200, 199, -1, - 185, 197, 194, -1, 194, 205, 193, -1, 193, 205, 206, -1, - 206, 205, 207, -1, 207, 205, 208, -1, 208, 205, 197, -1, - 197, 205, 194, -1, 202, 208, 198, -1, 197, 198, 208, -1, - 190, 209, 96, -1, 96, 209, 86, -1, 86, 209, 85, -1, - 85, 209, 84, -1, 84, 209, 210, -1, 210, 209, 211, -1, - 211, 209, 190, -1, 213, 212, 191, -1, 191, 212, 211, -1, - 211, 212, 214, -1, 214, 212, 215, -1, 215, 212, 216, -1, - 216, 212, 213, -1, 216, 217, 218, -1, 218, 217, 219, -1, - 219, 217, 220, -1, 220, 217, 221, -1, 221, 217, 192, -1, - 192, 217, 213, -1, 213, 217, 216, -1, 191, 211, 190, -1, - 192, 213, 191, -1, 206, 192, 193, -1, 192, 206, 221, -1, - 203, 222, 202, -1, 202, 222, 223, -1, 223, 222, 224, -1, - 224, 222, 225, -1, 225, 222, 203, -1, 223, 226, 227, -1, - 227, 226, 228, -1, 228, 226, 229, -1, 229, 226, 224, -1, - 224, 226, 223, -1, 231, 230, 224, -1, 224, 230, 229, -1, - 229, 230, 232, -1, 232, 230, 233, -1, 233, 230, 234, -1, - 234, 230, 231, -1, 231, 224, 225, -1, 227, 235, 223, -1, - 223, 235, 208, -1, 208, 235, 207, -1, 202, 223, 208, -1, - 207, 236, 206, -1, 206, 236, 221, -1, 221, 236, 220, -1, - 220, 236, 237, -1, 237, 236, 238, -1, 238, 236, 239, -1, - 239, 236, 240, -1, 240, 236, 228, -1, 228, 236, 227, -1, - 227, 236, 235, -1, 235, 236, 207, -1, 229, 241, 228, -1, - 228, 241, 240, -1, 240, 241, 239, -1, 239, 241, 242, -1, - 242, 241, 232, -1, 232, 241, 229, -1, 233, 243, 232, -1, - 232, 243, 244, -1, 244, 243, 245, -1, 245, 243, 246, -1, - 246, 243, 247, -1, 247, 243, 233, -1, 245, 248, 244, -1, - 244, 248, 242, -1, 242, 248, 238, -1, 238, 248, 237, -1, - 242, 238, 239, -1, 244, 242, 232, -1, 245, 249, 248, -1, - 248, 249, 237, -1, 237, 249, 250, -1, 250, 249, 251, -1, - 251, 249, 252, -1, 252, 249, 253, -1, 253, 249, 246, -1, - 246, 249, 245, -1, 255, 254, 237, -1, 237, 254, 220, -1, - 220, 254, 219, -1, 219, 254, 255, -1, 255, 237, 250, -1, - 257, 256, 258, -1, 258, 256, 259, -1, 259, 256, 260, -1, - 260, 256, 251, -1, 251, 256, 250, -1, 250, 261, 255, -1, - 255, 261, 262, -1, 262, 261, 263, -1, 263, 261, 264, -1, - 264, 261, 257, -1, 257, 261, 250, -1, 257, 258, 264, -1, - 260, 265, 259, -1, 259, 265, 258, -1, 258, 265, 264, -1, - 264, 265, 266, -1, 266, 265, 267, -1, 267, 265, 268, -1, - 251, 252, 260, -1, 269, 260, 252, -1, 268, 265, 260, -1, - 268, 260, 269, -1, 218, 270, 216, -1, 216, 270, 215, -1, - 215, 270, 271, -1, 271, 270, 272, -1, 272, 270, 273, -1, - 273, 270, 218, -1, 273, 274, 272, -1, 272, 274, 275, -1, - 275, 274, 276, -1, 276, 274, 277, -1, 277, 274, 278, -1, - 278, 274, 279, -1, 279, 274, 273, -1, 255, 262, 219, -1, - 218, 219, 273, -1, 262, 273, 219, -1, 279, 273, 262, -1, - 279, 262, 280, -1, 263, 280, 262, -1, 266, 281, 263, -1, - 263, 281, 280, -1, 266, 263, 264, -1, 266, 282, 281, -1, - 281, 282, 280, -1, 280, 282, 278, -1, 278, 282, 283, -1, - 283, 282, 284, -1, 284, 282, 285, -1, 285, 282, 267, -1, - 267, 282, 266, -1, 267, 268, 285, -1, 280, 278, 279, -1, - 211, 214, 210, -1, 286, 284, 285, -1, 288, 287, 289, -1, - 289, 287, 290, -1, 290, 287, 291, -1, 291, 287, 292, -1, - 292, 287, 288, -1, 275, 293, 292, -1, 292, 293, 294, -1, - 294, 293, 295, -1, 295, 293, 296, -1, 296, 293, 276, -1, - 276, 293, 275, -1, 277, 297, 276, -1, 276, 297, 296, -1, - 296, 297, 298, -1, 299, 297, 300, -1, 300, 297, 277, -1, - 291, 292, 294, -1, 295, 296, 298, -1, 299, 300, 301, -1, - 283, 301, 300, -1, 283, 300, 278, -1, 302, 283, 284, -1, - 302, 301, 283, -1, 275, 288, 272, -1, 271, 272, 288, -1, - 288, 303, 271, -1, 271, 303, 215, -1, 215, 303, 214, -1, - 214, 303, 304, -1, 304, 303, 289, -1, 289, 303, 288, -1, - 275, 292, 288, -1, 278, 300, 277, -1, 210, 305, 84, -1, - 84, 305, 83, -1, 83, 305, 306, -1, 306, 305, 307, -1, - 307, 305, 308, -1, 308, 305, 304, -1, 304, 305, 210, -1, - 289, 308, 304, -1, 290, 309, 289, -1, 289, 309, 310, -1, - 310, 309, 311, -1, 311, 309, 312, -1, 312, 309, 290, -1, - 289, 310, 308, -1, 307, 308, 310, -1, 310, 313, 307, -1, - 307, 313, 314, -1, 314, 313, 315, -1, 315, 313, 316, -1, - 316, 313, 311, -1, 311, 313, 310, -1, 318, 317, 319, -1, - 319, 317, 312, -1, 312, 317, 320, -1, 320, 317, 321, -1, - 321, 317, 322, -1, 322, 317, 318, -1, 301, 323, 318, -1, - 318, 323, 322, -1, 322, 323, 321, -1, 321, 323, 324, -1, - 324, 323, 302, -1, 302, 323, 301, -1, 312, 290, 319, -1, - 284, 324, 302, -1, 284, 325, 324, -1, 324, 325, 326, -1, - 326, 325, 327, -1, 327, 325, 328, -1, 328, 325, 286, -1, - 286, 325, 284, -1, 324, 326, 321, -1, 320, 321, 326, -1, - 326, 329, 320, -1, 320, 329, 330, -1, 330, 329, 331, -1, - 331, 329, 332, -1, 332, 329, 327, -1, 327, 329, 326, -1, - 320, 330, 312, -1, 330, 311, 312, -1, 311, 330, 316, -1, - 316, 330, 331, -1, 286, 333, 328, -1, 334, 328, 333, -1, - 335, 328, 334, -1, 328, 335, 327, -1, 332, 327, 335, -1, - 332, 335, 336, -1, 332, 336, 337, -1, 332, 337, 338, -1, - 332, 338, 331, -1, 331, 339, 316, -1, 316, 339, 315, -1, - 315, 339, 340, -1, 340, 339, 341, -1, 341, 339, 338, -1, - 338, 339, 331, -1, 341, 338, 337, -1, 315, 340, 342, -1, - 315, 342, 314, -1, 307, 314, 306, -1, 83, 306, 314, -1, - 83, 314, 82, -1, 342, 82, 314, -1, 82, 342, 7, -1, - 79, 7, 342, -1, 214, 304, 210, -1, 344, 343, 345, -1, - 347, 346, 348, -1, 349, 348, 346, -1, 346, 350, 349, -1, - 351, 349, 350, -1, 351, 350, 352, -1, 353, 352, 350, -1, - 354, 350, 346, -1, 354, 346, 355, -1, 357, 356, 358, -1, - 358, 359, 360, -1, 357, 358, 360, -1, 355, 357, 360, -1, - 354, 355, 360, -1, 361, 354, 360, -1, 359, 361, 360, -1, - 362, 359, 358, -1, 362, 358, 356, -1, 362, 356, 363, -1, - 362, 363, 364, -1, 362, 364, 365, -1, 366, 365, 364, -1, - 364, 334, 366, -1, 334, 333, 366, -1, 286, 366, 333, -1, - 361, 359, 367, -1, 368, 361, 367, -1, 367, 369, 368, -1, - 370, 368, 369, -1, 371, 369, 367, -1, 365, 372, 373, -1, - 362, 365, 373, -1, 359, 362, 373, -1, 367, 359, 373, -1, - 371, 367, 373, -1, 372, 371, 373, -1, 371, 372, 374, -1, - 375, 374, 372, -1, 286, 376, 377, -1, 366, 286, 377, -1, - 365, 366, 377, -1, 372, 365, 377, -1, 375, 372, 377, -1, - 376, 375, 377, -1, 376, 378, 375, -1, 369, 379, 380, -1, - 378, 381, 382, -1, 375, 378, 382, -1, 374, 375, 382, -1, - 383, 374, 382, -1, 384, 383, 382, -1, 381, 384, 382, -1, - 383, 384, 385, -1, 374, 383, 385, -1, 371, 374, 385, -1, - 369, 371, 385, -1, 379, 369, 385, -1, 384, 379, 385, -1, - 368, 386, 387, -1, 361, 368, 387, -1, 354, 361, 387, -1, - 350, 354, 387, -1, 353, 350, 387, -1, 386, 353, 387, -1, - 353, 386, 388, -1, 389, 388, 386, -1, 369, 380, 370, -1, - 386, 368, 370, -1, 389, 386, 370, -1, 380, 389, 370, -1, - 389, 345, 388, -1, 345, 343, 390, -1, 388, 345, 390, -1, - 353, 388, 390, -1, 352, 353, 390, -1, 351, 352, 390, -1, - 391, 351, 390, -1, 343, 391, 390, -1, 393, 392, 394, -1, - 396, 395, 397, -1, 389, 395, 398, -1, 345, 389, 398, -1, - 344, 345, 398, -1, 399, 344, 398, -1, 400, 399, 398, -1, - 395, 400, 398, -1, 400, 395, 401, -1, 396, 401, 395, -1, - 378, 402, 381, -1, 378, 376, 402, -1, 402, 393, 394, -1, - 403, 381, 394, -1, 405, 404, 406, -1, 408, 407, 397, -1, - 394, 392, 409, -1, 403, 394, 409, -1, 404, 403, 409, -1, - 406, 404, 409, -1, 410, 406, 409, -1, 392, 410, 409, -1, - 410, 396, 411, -1, 406, 410, 411, -1, 405, 406, 411, -1, - 407, 405, 411, -1, 397, 407, 411, -1, 396, 397, 411, -1, - 397, 395, 412, -1, 408, 397, 412, -1, 380, 408, 412, -1, - 389, 380, 412, -1, 395, 389, 412, -1, 286, 285, 376, -1, - 413, 343, 344, -1, 415, 414, 393, -1, 416, 285, 268, -1, - 416, 417, 418, -1, 285, 416, 418, -1, 376, 285, 418, -1, - 402, 376, 418, -1, 393, 402, 418, -1, 415, 393, 418, -1, - 419, 415, 418, -1, 417, 419, 418, -1, 417, 420, 421, -1, - 421, 415, 419, -1, 417, 421, 419, -1, 421, 422, 415, -1, - 414, 415, 422, -1, 414, 422, 423, -1, 422, 424, 423, -1, - 425, 423, 424, -1, 426, 424, 422, -1, 414, 423, 427, -1, - 393, 414, 427, -1, 392, 393, 427, -1, 410, 392, 427, -1, - 396, 410, 427, -1, 401, 396, 427, -1, 423, 401, 427, -1, - 423, 425, 428, -1, 401, 423, 428, -1, 400, 401, 428, -1, - 399, 400, 428, -1, 429, 399, 428, -1, 425, 429, 428, -1, - 268, 269, 430, -1, 268, 430, 431, -1, 269, 252, 430, -1, - 432, 430, 252, -1, 416, 268, 431, -1, 417, 416, 431, -1, - 420, 417, 431, -1, 433, 420, 431, -1, 434, 433, 431, -1, - 430, 434, 431, -1, 435, 420, 433, -1, 435, 436, 437, -1, - 420, 435, 437, -1, 421, 420, 437, -1, 422, 421, 437, -1, - 426, 422, 437, -1, 436, 426, 437, -1, 432, 436, 438, -1, - 430, 432, 438, -1, 434, 430, 438, -1, 433, 434, 438, -1, - 435, 433, 438, -1, 436, 435, 438, -1, 426, 436, 439, -1, - 424, 426, 440, -1, 441, 424, 440, -1, 439, 441, 440, -1, - 426, 439, 440, -1, 246, 442, 443, -1, 253, 246, 443, -1, - 252, 253, 443, -1, 432, 252, 443, -1, 436, 432, 443, -1, - 439, 436, 443, -1, 444, 439, 443, -1, 442, 444, 443, -1, - 446, 445, 447, -1, 447, 448, 449, -1, 449, 439, 444, -1, - 447, 449, 444, -1, 446, 447, 444, -1, 442, 446, 444, -1, - 247, 233, 450, -1, 246, 247, 450, -1, 442, 246, 450, -1, - 446, 442, 450, -1, 445, 446, 450, -1, 233, 445, 450, -1, - 445, 451, 452, -1, 447, 445, 452, -1, 448, 447, 452, -1, - 453, 448, 452, -1, 454, 453, 452, -1, 451, 454, 452, -1, - 456, 455, 457, -1, 458, 456, 457, -1, 454, 458, 457, -1, - 453, 454, 457, -1, 448, 453, 457, -1, 449, 448, 457, -1, - 439, 449, 457, -1, 441, 439, 457, -1, 459, 441, 457, -1, - 460, 459, 457, -1, 455, 460, 457, -1, 462, 461, 463, -1, - 461, 455, 456, -1, 463, 461, 456, -1, 458, 463, 456, -1, - 231, 225, 464, -1, 234, 231, 465, -1, 233, 234, 465, -1, - 445, 233, 465, -1, 451, 445, 465, -1, 464, 451, 465, -1, - 231, 464, 465, -1, 464, 463, 466, -1, 451, 464, 466, -1, - 454, 451, 466, -1, 458, 454, 466, -1, 463, 458, 466, -1, - 225, 203, 467, -1, 464, 225, 467, -1, 463, 464, 467, -1, - 462, 463, 467, -1, 203, 462, 467, -1, 468, 459, 460, -1, - 460, 469, 468, -1, 468, 470, 471, -1, 470, 472, 413, -1, - 471, 429, 473, -1, 468, 471, 473, -1, 459, 468, 473, -1, - 441, 459, 473, -1, 424, 441, 473, -1, 425, 424, 473, -1, - 429, 425, 473, -1, 429, 471, 474, -1, 399, 429, 474, -1, - 344, 399, 474, -1, 413, 344, 474, -1, 470, 413, 474, -1, - 471, 470, 474, -1, 413, 472, 475, -1, 343, 413, 475, -1, - 391, 343, 475, -1, 476, 391, 475, -1, 477, 476, 475, -1, - 478, 477, 475, -1, 472, 478, 475, -1, 479, 461, 480, -1, - 462, 480, 461, -1, 479, 481, 482, -1, 461, 479, 482, -1, - 455, 461, 482, -1, 460, 455, 482, -1, 469, 460, 482, -1, - 481, 469, 482, -1, 483, 481, 479, -1, 485, 484, 200, -1, - 187, 486, 485, -1, 204, 200, 487, -1, 203, 204, 487, -1, - 462, 203, 487, -1, 480, 462, 487, -1, 484, 480, 487, -1, - 200, 484, 487, -1, 485, 200, 187, -1, 484, 485, 488, -1, - 480, 484, 488, -1, 479, 480, 488, -1, 483, 479, 488, -1, - 486, 483, 488, -1, 485, 486, 488, -1, 490, 489, 491, -1, - 492, 490, 491, -1, 483, 492, 491, -1, 481, 483, 491, -1, - 469, 481, 491, -1, 468, 469, 491, -1, 470, 468, 491, -1, - 472, 470, 491, -1, 478, 472, 491, -1, 489, 478, 491, -1, - 492, 483, 493, -1, 494, 489, 490, -1, 492, 494, 490, -1, - 496, 495, 494, -1, 187, 178, 497, -1, 486, 187, 497, -1, - 483, 486, 497, -1, 493, 483, 497, -1, 498, 493, 497, -1, - 178, 498, 497, -1, 499, 494, 500, -1, 501, 499, 500, -1, - 502, 501, 500, -1, 493, 502, 500, -1, 492, 493, 500, -1, - 494, 492, 500, -1, 496, 494, 499, -1, 496, 499, 501, -1, - 503, 502, 493, -1, 503, 493, 498, -1, 503, 498, 178, -1, - 503, 178, 177, -1, 177, 174, 503, -1, 163, 504, 174, -1, - 502, 503, 505, -1, 505, 506, 502, -1, 507, 502, 506, -1, - 501, 502, 508, -1, 509, 501, 508, -1, 507, 509, 508, -1, - 502, 507, 508, -1, 511, 510, 512, -1, 512, 513, 511, -1, - 504, 511, 513, -1, 512, 514, 507, -1, 512, 507, 506, -1, - 512, 506, 513, -1, 515, 513, 506, -1, 174, 504, 515, -1, - 503, 174, 515, -1, 505, 503, 515, -1, 506, 505, 515, -1, - 504, 513, 515, -1, 517, 516, 518, -1, 517, 518, 519, -1, - 517, 519, 520, -1, 509, 520, 519, -1, 516, 517, 521, -1, - 522, 521, 517, -1, 514, 522, 523, -1, 507, 514, 523, -1, - 509, 507, 523, -1, 520, 509, 523, -1, 517, 520, 523, -1, - 522, 517, 523, -1, 524, 522, 514, -1, 526, 525, 510, -1, - 526, 510, 511, -1, 526, 511, 527, -1, 164, 158, 528, -1, - 163, 164, 528, -1, 504, 163, 528, -1, 511, 504, 528, -1, - 527, 511, 528, -1, 529, 527, 528, -1, 158, 529, 528, -1, - 158, 159, 530, -1, 158, 530, 529, -1, 527, 529, 530, -1, - 527, 530, 531, -1, 527, 531, 532, -1, 527, 532, 526, -1, - 525, 526, 532, -1, 525, 532, 533, -1, 534, 533, 532, -1, - 536, 535, 537, -1, 524, 538, 539, -1, 535, 539, 538, -1, - 522, 524, 540, -1, 521, 522, 540, -1, 541, 521, 540, -1, - 542, 541, 540, -1, 539, 542, 540, -1, 524, 539, 540, -1, - 510, 525, 543, -1, 512, 510, 543, -1, 514, 512, 543, -1, - 524, 514, 543, -1, 538, 524, 543, -1, 525, 538, 543, -1, - 533, 534, 544, -1, 525, 533, 544, -1, 538, 525, 544, -1, - 535, 538, 544, -1, 537, 535, 544, -1, 534, 537, 544, -1, - 546, 545, 547, -1, 549, 548, 550, -1, 550, 551, 542, -1, - 541, 542, 551, -1, 541, 551, 552, -1, 551, 553, 552, -1, - 535, 536, 554, -1, 539, 535, 554, -1, 542, 539, 554, -1, - 550, 542, 554, -1, 549, 550, 554, -1, 536, 549, 554, -1, - 550, 548, 555, -1, 551, 550, 555, -1, 553, 551, 555, -1, - 545, 553, 555, -1, 547, 545, 555, -1, 548, 547, 555, -1, - 112, 556, 127, -1, 123, 127, 556, -1, 123, 556, 557, -1, - 553, 557, 556, -1, 553, 556, 552, -1, 545, 546, 558, -1, - 553, 545, 558, -1, 557, 553, 558, -1, 123, 557, 558, -1, - 122, 123, 558, -1, 121, 122, 558, -1, 559, 121, 558, -1, - 546, 559, 558, -1, 111, 107, 560, -1, 112, 560, 561, -1, - 556, 112, 561, -1, 552, 556, 561, -1, 541, 552, 561, -1, - 521, 541, 561, -1, 516, 521, 561, -1, 560, 516, 561, -1, - 560, 112, 111, -1, 562, 107, 563, -1, 565, 564, 566, -1, - 566, 562, 565, -1, 563, 565, 562, -1, 562, 566, 567, -1, - 107, 562, 567, -1, 560, 107, 567, -1, 516, 560, 567, -1, - 518, 516, 567, -1, 566, 518, 567, -1, 569, 568, 495, -1, - 509, 519, 570, -1, 501, 509, 570, -1, 496, 501, 570, -1, - 495, 496, 570, -1, 569, 495, 570, -1, 519, 569, 570, -1, - 568, 569, 571, -1, 495, 568, 572, -1, 494, 495, 572, -1, - 489, 494, 572, -1, 478, 489, 572, -1, 477, 478, 572, -1, - 573, 477, 572, -1, 571, 573, 572, -1, 568, 571, 572, -1, - 569, 574, 571, -1, 573, 571, 575, -1, 573, 575, 576, -1, - 564, 577, 578, -1, 566, 564, 578, -1, 518, 566, 578, -1, - 519, 518, 578, -1, 569, 519, 578, -1, 574, 569, 578, -1, - 577, 574, 578, -1, 577, 564, 579, -1, 580, 579, 564, -1, - 582, 581, 583, -1, 584, 582, 583, -1, 576, 584, 583, -1, - 573, 576, 583, -1, 477, 573, 583, -1, 476, 477, 583, -1, - 391, 476, 583, -1, 351, 391, 583, -1, 349, 351, 583, -1, - 348, 349, 583, -1, 581, 348, 583, -1, 585, 348, 581, -1, - 348, 586, 587, -1, 348, 587, 347, -1, 588, 347, 589, -1, - 590, 588, 589, -1, 591, 590, 589, -1, 586, 591, 589, -1, - 587, 586, 589, -1, 347, 587, 589, -1, 590, 591, 592, -1, - 593, 590, 592, -1, 594, 593, 592, -1, 595, 594, 592, -1, - 591, 595, 592, -1, 593, 594, 596, -1, 597, 593, 596, -1, - 588, 590, 598, -1, 588, 598, 599, -1, 601, 600, 599, -1, - 590, 593, 602, -1, 598, 590, 602, -1, 599, 598, 602, -1, - 601, 599, 602, -1, 603, 601, 602, -1, 597, 603, 602, -1, - 593, 597, 602, -1, 605, 604, 606, -1, 608, 607, 609, -1, - 609, 610, 606, -1, 611, 606, 610, -1, 605, 606, 611, -1, - 597, 596, 612, -1, 603, 597, 612, -1, 606, 603, 612, -1, - 609, 606, 612, -1, 608, 609, 612, -1, 596, 608, 612, -1, - 604, 580, 613, -1, 601, 603, 614, -1, 600, 601, 614, -1, - 613, 600, 614, -1, 604, 613, 614, -1, 606, 604, 614, -1, - 603, 606, 614, -1, 579, 580, 615, -1, 616, 579, 615, -1, - 617, 616, 615, -1, 605, 617, 615, -1, 604, 605, 615, -1, - 580, 604, 615, -1, 577, 579, 616, -1, 616, 618, 577, -1, - 574, 577, 618, -1, 619, 571, 574, -1, 619, 574, 618, -1, - 619, 618, 620, -1, 616, 617, 621, -1, 618, 616, 621, -1, - 620, 618, 621, -1, 622, 620, 621, -1, 623, 622, 621, -1, - 617, 623, 621, -1, 622, 623, 624, -1, 625, 620, 622, -1, - 626, 625, 622, -1, 611, 610, 627, -1, 605, 611, 627, -1, - 617, 605, 627, -1, 623, 617, 627, -1, 624, 623, 627, -1, - 628, 624, 627, -1, 629, 628, 627, -1, 610, 629, 627, -1, - 630, 584, 576, -1, 630, 576, 626, -1, 575, 626, 576, -1, - 625, 626, 631, -1, 620, 625, 631, -1, 619, 620, 631, -1, - 571, 619, 631, -1, 575, 571, 631, -1, 626, 575, 631, -1, - 632, 624, 628, -1, 633, 632, 634, -1, 635, 633, 634, -1, - 630, 632, 633, -1, 624, 632, 636, -1, 622, 624, 636, -1, - 626, 622, 636, -1, 630, 626, 636, -1, 632, 630, 636, -1, - 637, 581, 582, -1, 633, 635, 638, -1, 630, 633, 638, -1, - 584, 630, 638, -1, 582, 584, 638, -1, 637, 582, 638, -1, - 635, 637, 638, -1, 639, 585, 640, -1, 641, 639, 640, -1, - 634, 641, 640, -1, 640, 585, 642, -1, 634, 640, 642, -1, - 635, 634, 642, -1, 637, 635, 642, -1, 581, 637, 642, -1, - 585, 581, 642, -1, 644, 643, 639, -1, 644, 639, 645, -1, - 646, 644, 645, -1, 629, 646, 645, -1, 628, 629, 645, -1, - 632, 628, 645, -1, 634, 632, 645, -1, 641, 634, 645, -1, - 639, 641, 645, -1, 647, 607, 648, -1, 647, 648, 643, -1, - 649, 643, 648, -1, 609, 607, 650, -1, 610, 609, 650, -1, - 629, 610, 650, -1, 646, 629, 650, -1, 644, 646, 650, -1, - 643, 644, 650, -1, 647, 643, 650, -1, 607, 647, 650, -1, - 594, 595, 651, -1, 596, 594, 651, -1, 608, 596, 651, -1, - 607, 608, 651, -1, 648, 607, 651, -1, 595, 648, 651, -1, - 649, 586, 652, -1, 643, 649, 652, -1, 639, 643, 652, -1, - 585, 639, 652, -1, 348, 585, 652, -1, 586, 348, 652, -1, - 586, 649, 653, -1, 591, 586, 653, -1, 595, 591, 653, -1, - 648, 595, 653, -1, 649, 648, 653, -1, 319, 290, 291, -1, - 319, 291, 294, -1, 319, 294, 295, -1, 319, 295, 318, -1, - 318, 298, 301, -1, 301, 298, 299, -1, 381, 403, 404, -1, - 405, 384, 404, -1, 379, 384, 405, -1, 379, 405, 407, -1, - 380, 379, 407, -1, 394, 381, 402, -1, 408, 380, 407, -1, - 318, 295, 298, -1, 299, 298, 297, -1, 381, 404, 384, -1, - 257, 250, 256, -1] - } - } - } - ] - } - - DEF TS TimeSensor {cycleInterval 4 loop TRUE} - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [1 2 1] - } - - Billboard { - axisOfRotation 0 0 0 - children [ - - Transform { - translation -2 2 0 - children [ - Shape { - appearance Appearance {material Material2D { emissiveColor 1 0 0 filled TRUE}} - geometry Rectangle { size 4 1} - } - Shape { - appearance Appearance {material Material2D { emissiveColor 1 1 1 filled TRUE}} - geometry DEF TEXT Text { string "Taper" fontStyle DEF FS FontStyle { size 0.8 justify ["MIDDLE" "MIDDLE"] style "TEXTURED"}} - } - DEF TS_MODE TouchSensor {} - ] - } - Transform { - translation 2 2 0 - children [ - Shape { - appearance Appearance {material Material2D { emissiveColor 0 0 1 filled TRUE}} - geometry Rectangle { size 4 1} - } - Shape { - appearance Appearance {material Material2D { emissiveColor 1 1 1 filled TRUE}} - geometry DEF TEXT_AXIS Text { string "Y Axis" fontStyle USE FS} - } - DEF TS_AXIS TouchSensor {} - ] - } - ] - } - - -DEF SC Script { - eventIn SFBool change_mode - eventIn SFBool change_axis - field SFNode deform USE NLD - field SFNode inter USE SI - field SFNode txt USE TEXT - field SFNode txt_axis USE TEXT_AXIS - url ["javascript: - function initialize() { - def_mode = 0; - def_axis = 0; - } - function change_mode(value, timestamp) { - if (!value) return; - def_mode++; - if (def_mode==3) def_mode = 0; - deform.type = def_mode; - switch (def_mode) { - case 0: - txt.string[0] = 'Taper'; - deform.extend[1] = 0.5; - deform.extend[3] = 1; - deform.extend[5] = 0.2; - inter.keyValue = new MFFloat(1, 2, 1); - break; - case 1: - txt.string[0] = 'Twister'; - deform.extend[1] = 0; - deform.extend[3] = 6.18; - deform.extend[5] = 0.0; - inter.keyValue = new MFFloat(-1, 1, -1); - break; - case 2: - txt.string[0] = 'Bender'; - deform.extend[1] = 0; - deform.extend[3] = 3.14; - deform.extend[5] = 0; - inter.keyValue = new MFFloat(-1, 1, -1); - break; - } - } - function change_axis(value, timestamp) { - if (!value) return; - def_axis++; - if (def_axis==3) def_axis = 0; - switch (def_axis) { - case 0: - txt_axis.string[0] = 'Y Axis'; - deform.axis = new SFVec3f(0, 1, 0); - break; - case 1: - txt_axis.string[0] = 'X Axis'; - deform.axis = new SFVec3f(1, 0, 0); - break; - case 2: - txt_axis.string[0] = 'Z Axis'; - deform.axis = new SFVec3f(0, 0, 1); - break; - } - } - "] -} - - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO NLD.param - -ROUTE TS_MODE.isActive TO SC.change_mode -ROUTE TS_AXIS.isActive TO SC.change_axis diff --git a/regression_tests/bifs-3D-shapes-pointset.bt b/regression_tests/bifs-3D-shapes-pointset.bt deleted file mode 100644 index 4704b48..0000000 --- a/regression_tests/bifs-3D-shapes-pointset.bt +++ /dev/null @@ -1,46 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetrics false - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -Group { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows PointSet" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "PointSet Test" - } - Shape { - appearance Appearance { - material Material { diffuseColor 1 0 0} - } - geometry PointSet { - coord DEF COORD Coordinate { - point [-1 1 1, 1 1 1, 1 1 -1, -1 1 -1, -1 -1 1, 1 -1 1, 1 -1 -1, -1 -1 -1] - } - } - } - ] -} - - diff --git a/regression_tests/bifs-3D-texturing-box-transparent.bt b/regression_tests/bifs-3D-texturing-box-transparent.bt deleted file mode 100644 index b4992ed..0000000 --- a/regression_tests/bifs-3D-texturing-box-transparent.bt +++ /dev/null @@ -1,73 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "Box test" - info ["This shows a 3D cube with transparency" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - translation 0 0 -50 - children [ - Shape { - appearance Appearance { - material Material { - emissiveColor 1 0 1 - diffuseColor 1 1 1 - } - } - geometry Box {size 150 100 10} - } - ] - } - - DEF TR Transform { - translation -50 0 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 1 1 0 - shininess 0.5 - transparency 0.5 - } - } - geometry Box {size 50 50 50} - } - ] - } - DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - ] -} - -ROUTE TS.fraction_changed TO MAT.transparency -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation diff --git a/regression_tests/bifs-3D-texturing-box-video.bt b/regression_tests/bifs-3D-texturing-box-video.bt deleted file mode 100644 index 44ebcc1..0000000 --- a/regression_tests/bifs-3D-texturing-box-video.bt +++ /dev/null @@ -1,184 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric FALSE - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { -children [ - - Background2D { - backColor 1 1 1 - } - Viewpoint {} - WorldInfo { - info ["This shows spinning cubes with image and video textures" "GPAC Regression Tests" "$Date: 2008/11/24 14:58:25 $ - $Revision: 1.5 $" "(C) 2002-2004 GPAC Team"] - title "Cube, Texture Test" - } - - DEF TR Transform { - rotation 1 1 1 0.5 - children [ - Transform { - children [ - DEF Red Transform { - children [ - Shape { - appearance DEF Red-App Appearance { - material Material { - diffuseColor 1.0 0.0 0.0 - } - texture ImageTexture { url "5" } - } - geometry Box { } - } - ] - } - Transform { translation 2.0 2.0 0.0 children [ USE Red ] } - Transform { translation -2.0 2.0 0.0 children [USE Red ] } - Transform { translation 2.0 -2.0 0.0 children [USE Red ]} - Transform { translation -2.0 -2.0 0.0 children [USE Red ]} - Transform { translation 0.0 -2.0 2.0 children [USE Red ]} - Transform { translation 0.0 2.0 2.0 children [USE Red ]} - Transform { translation 2.0 0.0 2.0 children [USE Red ]} - Transform { translation -2.0 0.0 2.0 children [USE Red ]} - Transform { translation 0.0 -2.0 -2.0 children [USE Red ]} - Transform { translation 0.0 2.0 -2.0 children [USE Red ]} - Transform { translation 2.0 0.0 -2.0 children [USE Red ]} - Transform { translation -2.0 0.0 -2.0 children [USE Red ]} - ] - } - - Transform { - children [ - DEF Blue Transform { - translation 2.0 0.0 0.0 - children [ - Shape { - appearance DEF Blue-App Appearance { - material Material { - diffuseColor 0.0 0.0 1.0 - } - texture DEF M2 MovieTexture { url "10" loop TRUE } - } - geometry Box { } - } - ] - } - Transform { translation -4.0 0.0 0.0 children [USE Blue] } - Transform { translation -2.0 0.0 2.0 children [USE Blue] } - Transform { translation -2.0 0.0 -2.0 children [USE Blue] } - Transform { translation -2.0 2.0 0.0 children [USE Blue] } - Transform { translation -2.0 -2.0 0.0 children [USE Blue] } - Transform { translation 0.0 2.0 2.0 children [USE Blue] } - Transform { translation 0.0 2.0 -2.0 children [USE Blue] } - Transform { translation -4.0 2.0 2.0 children [USE Blue] } - Transform { translation -4.0 2.0 -2.0 children [USE Blue] } - Transform { translation 0.0 -2.0 2.0 children [USE Blue] } - Transform { translation 0.0 -2.0 -2.0 children [USE Blue] } - Transform { translation -4.0 -2.0 2.0 children [USE Blue] } - Transform { translation -4.0 -2.0 -2.0 children [USE Blue] } - ] - } - - DEF Clock TimeSensor { - cycleInterval 3.0 - loop FALSE - } - - DEF Trigger TimeSensor { - loop TRUE - cycleInterval 5.0 - } - - DEF RedScale PositionInterpolator { - key [ 0.0, 0.5, 1.0 ] - keyValue [ - 1.0 1.0 1.0, - 0.0001 0.0001 0.0001, - 1.0 1.0 1.0, - ] - } - - DEF BlueScale PositionInterpolator { - key [ 0.0, 0.25, 0.5, 0.75, 1.0 ] - keyValue [ - 1.0 1.0 1.0, - 0.0001 0.0001 0.0001, - 1.0 1.0 1.0, - 0.0001 0.0001 0.0001, - 1.0 1.0 1.0, - ] - } - ] - } - - DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - -] -} - -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation -ROUTE Trigger.cycleTime TO Clock.startTime -ROUTE Clock.fraction_changed TO RedScale.set_fraction -ROUTE Clock.fraction_changed TO BlueScale.set_fraction -ROUTE RedScale.value_changed TO Red.scale -ROUTE BlueScale.value_changed TO Blue.scale - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 10 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-texturing-box.bt b/regression_tests/bifs-3D-texturing-box.bt deleted file mode 100644 index d592ef6..0000000 --- a/regression_tests/bifs-3D-texturing-box.bt +++ /dev/null @@ -1,69 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Box test" - info ["This shows a box" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - rotation 1 1 1 1.57 - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - texture ImageTexture { url "5" } - } - geometry Box {size 120 100 80} - } - ] - } - ] -} - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 10 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-texturing-compositetexture3D-bitmap.bt b/regression_tests/bifs-3D-texturing-compositetexture3D-bitmap.bt deleted file mode 100644 index 895ab1f..0000000 --- a/regression_tests/bifs-3D-texturing-compositetexture3D-bitmap.bt +++ /dev/null @@ -1,113 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - - WorldInfo { - title "Box test" - info ["This shows a bitmap using" "a compositetexture3D" "the 3D texture is a spinning box with an image texture" "" "GPAC Regression Tests" "$Date: 2008/07/22 10:54:58 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - Background2D{url 20} - - Shape { - appearance Appearance { - material DEF MAT Material2D { emissiveColor 1 1 0 filled FALSE transparency 0} - texture CompositeTexture3D { - pixelWidth 128 - pixelHeight 128 - children [ - DEF BACK Background2D {backColor 0 1 0} - DEF TR2 Transform { - rotation 1 1 1 -0.65 - children [ - Shape { - appearance Appearance { - material DEF MAT2 Material { emissiveColor 0 0 1 } - texture ImageTexture {url 10} - } - geometry Box {size 50 50 50} - } - DEF TOUCH TouchSensor{} - ] - } - ] - } - } -# geometry Bitmap{} - geometry Circle {radius 60} - } - - DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - - ] -} - -ROUTE TS.fraction_changed TO OI.set_fraction -#ROUTE TS.fraction_changed TO MAT2.transparency -ROUTE OI.value_changed TO TR2.rotation -ROUTE TOUCH.isActive TO BACK.set_bind - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 10 - muxInfo MuxInfo { - fileName "./auxiliary_files/logo.png" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 20 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "./auxiliary_files/sky.jpg" - } - } - ] - } - ] -} - -#take care of bind delay -AT 100 { -# REPLACE BACK.set_bind BY FALSE -} diff --git a/regression_tests/bifs-3D-texturing-compositetexture3D-box.bt b/regression_tests/bifs-3D-texturing-compositetexture3D-box.bt deleted file mode 100644 index 58bca32..0000000 --- a/regression_tests/bifs-3D-texturing-compositetexture3D-box.bt +++ /dev/null @@ -1,106 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - - Background2D { backColor 1 1 1} - - WorldInfo { - title "Composite Texture test" - info ["This shows a box" "with a 3D composite texture" "the texture is a spinning sphere with an image texture" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - - DEF TR Transform { - translation 0 0 0 - children [ - Shape { - appearance Appearance { - texture CompositeTexture3D { - pixelWidth 128 - pixelHeight 128 - children [ - #MPEG-4 is stupid here, background2D can't be encoded in the CT3D.background field - Background2D {url "auxiliary_files/sky.jpg" backColor 1 0 0} - DEF TR2 Transform { - scale 1 0.5 1 - children [ - Shape { - appearance Appearance { - material DEF MAT2 Material { diffuseColor 0 0 1 } - texture ImageTexture { url "10"} - } - geometry Sphere {radius 60} - } - ] - } - ] - } - } - geometry Box {size 64 64 64 } - } - ] - } - - DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 0.8 0] - } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - ] -} - -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation -ROUTE OI.value_changed TO TR2.rotation -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO MAT2.transparency - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-texturing-cone-transparent.bt b/regression_tests/bifs-3D-texturing-cone-transparent.bt deleted file mode 100644 index 0c54f1b..0000000 --- a/regression_tests/bifs-3D-texturing-cone-transparent.bt +++ /dev/null @@ -1,68 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Cone test" - info ["This shows cones with and without cap" "with transparency - objects should appear behing each-other" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - translation -70 0 0 - rotation 1 0 0 4 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { diffuseColor 1.0 0.0 0.0 transparency 0.5} - } - geometry Cone {height 150 bottomRadius 25} - } - ] - } - Transform { - translation 70 0 0 - rotation 1 0 0 4 - children [ - Shape { - appearance Appearance { -# material USE MAT - material Material { diffuseColor 1.0 0.0 1.0} - } - geometry Cone {height 150 bottomRadius 25 bottom FALSE} - } - ] - } - DEF TS TimeSensor {loop TRUE cycleInterval 6} - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO MAT.transparency - diff --git a/regression_tests/bifs-3D-texturing-cone.bt b/regression_tests/bifs-3D-texturing-cone.bt deleted file mode 100644 index 5d953c2..0000000 --- a/regression_tests/bifs-3D-texturing-cone.bt +++ /dev/null @@ -1,81 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Cone test" - info ["This shows a cone" "with and without cap" "and a texture map" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - translation -70 0 0 - rotation 1 0 0 4 - children [ - Shape { - appearance DEF APP Appearance { - material Material {diffuseColor 1.0 0.0 0.0 } - texture ImageTexture { url "5" } - } - geometry Cone {height 150 bottomRadius 25} - } - ] - } - Transform { - translation 70 0 0 - rotation 1 0 0 4 - children [ - Shape { - appearance USE APP - geometry Cone {height 150 bottomRadius 25 bottom FALSE} - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 10 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-texturing-cylinder-transparent.bt b/regression_tests/bifs-3D-texturing-cylinder-transparent.bt deleted file mode 100644 index e5478f0..0000000 --- a/regression_tests/bifs-3D-texturing-cylinder-transparent.bt +++ /dev/null @@ -1,93 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 380 - pixelHeight 300 - } - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Cylinder test" - info ["This shows a cylinder" "with and without cap and side and transparent material" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - translation -100 100 0 - children [ - Shape { - appearance DEF APP Appearance { - material DEF MAT Material {diffuseColor 1.0 0.0 0.0 } - } - geometry Cylinder {height 150 radius 25} - } - ] - } - Transform { - translation 0 100 0 - rotation 1 0 0 0.78 - children [ - Shape { - appearance USE APP - geometry Cylinder {height 150 radius 25 top FALSE} - } - ] - } - Transform { - translation -100 -100 0 - rotation 1 0 0 -0.78 - children [ - Shape { - appearance USE APP - geometry Cylinder {height 150 radius 25 bottom FALSE} - } - ] - } - Transform { - translation 0 -100 0 - rotation 1 0 0 1.2 - children [ - Shape { - appearance USE APP - geometry Cylinder {height 150 radius 25 bottom FALSE top FALSE} - } - ] - } - Transform { - translation 100 0 0 - children [ - Shape { - appearance USE APP - geometry Cylinder {height 150 radius 25 side FALSE } - } - ] - } - DEF TS TimeSensor {loop TRUE cycleInterval 6} - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO MAT.transparency - diff --git a/regression_tests/bifs-3D-texturing-cylinder.bt b/regression_tests/bifs-3D-texturing-cylinder.bt deleted file mode 100644 index fdc798c..0000000 --- a/regression_tests/bifs-3D-texturing-cylinder.bt +++ /dev/null @@ -1,107 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 380 - pixelHeight 300 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "Cylinder test" - info ["This shows a cylinder" "with and without cap and side and a texture map" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - translation -100 100 0 - children [ - Shape { - appearance DEF APP Appearance { - material Material {diffuseColor 1.0 0.0 0.0 } - texture ImageTexture { url "5" } - } - geometry Cylinder {height 150 radius 25} - } - ] - } - Transform { - translation 0 100 0 - rotation 1 0 0 0.78 - children [ - Shape { - appearance USE APP - geometry Cylinder {height 150 radius 25 top FALSE} - } - ] - } - Transform { - translation -100 -100 0 - rotation 1 0 0 -0.78 - children [ - Shape { - appearance USE APP - geometry Cylinder {height 150 radius 25 bottom FALSE} - } - ] - } - Transform { - translation 0 -100 0 - rotation 1 0 0 1.2 - children [ - Shape { - appearance USE APP - geometry Cylinder {height 150 radius 25 bottom FALSE top FALSE} - } - ] - } - Transform { - translation 100 0 0 - children [ - Shape { - appearance USE APP - geometry Cylinder {height 150 radius 25 side FALSE } - } - ] - } - ] -} - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 10 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} diff --git a/regression_tests/bifs-3D-texturing-transform-box.bt b/regression_tests/bifs-3D-texturing-transform-box.bt deleted file mode 100644 index 7b44a38..0000000 --- a/regression_tests/bifs-3D-texturing-transform-box.bt +++ /dev/null @@ -1,85 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "Texture Transform test" - info ["This shows a 3D cube" "mapped with an alpha PNG and texture transform" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - DEF TR Transform { - rotation 1 1 1 0.75 - children [ - Shape { - appearance Appearance { - material DEF MAT Material {} - textureTransform DEF MX TextureTransform { scale 4 4 } - texture ImageTexture { url "10"} - } - geometry Box {size 64 64 64 } - } - ] - } - - DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } - DEF PI PositionInterpolator2D { - key [0 0.25 0.5 0.75 1] - keyValue [1 1, 4 1, 4 4, 1 4, 1 1] - } - DEF CI ColorInterpolator { - key [0 0.5 1] - keyValue [1 1 1, 0 0 1, 1 1 1] - } - ] -} - -ROUTE TS.fraction_changed TO PI.set_fraction -ROUTE PI.value_changed TO MX.scale -ROUTE TS.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO MAT.diffuseColor - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-texturing-transform-matrix-box.bt b/regression_tests/bifs-3D-texturing-transform-matrix-box.bt deleted file mode 100644 index 9bf53af..0000000 --- a/regression_tests/bifs-3D-texturing-transform-matrix-box.bt +++ /dev/null @@ -1,91 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "Texture Transform test" - info ["This shows a 3D cube" "mapped with an alpha PNG and texture transform" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - DEF TR Transform { - rotation 1 1 1 0.75 - children [ - Shape { - appearance Appearance { - material DEF MAT Material {} - textureTransform DEF MX TransformMatrix2D {mxx 3 myy 2} - texture ImageTexture { url "10"} - } - geometry Box {size 64 64 64 } - } - ] - } - - DEF TS TimeSensor { cycleInterval 8.0 loop TRUE } - DEF SI ScalarInterpolator { - key [0 0.25 0.5 0.75 1] - keyValue [1 1 1 6 1] - } - DEF SI2 ScalarInterpolator { - key [0 0.25 0.5 0.75 1] - keyValue [1 6 1 1 1] - } - DEF CI ColorInterpolator { - key [0 0.5 1] - keyValue [1 1 1, 0 0 1, 1 1 1] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO MX.mxy -ROUTE TS.fraction_changed TO SI2.set_fraction -ROUTE SI2.value_changed TO MX.myx -ROUTE TS.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO MAT.diffuseColor - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-3D-viewpoint-anim.bt b/regression_tests/bifs-3D-viewpoint-anim.bt deleted file mode 100644 index 0ed10b8..0000000 --- a/regression_tests/bifs-3D-viewpoint-anim.bt +++ /dev/null @@ -1,84 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 200 - } - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "Viewpoint animation test test" - info ["This shows a sphere" "and dynamic viewpoint" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - DEF VP Viewpoint {position -200 0 100 orientation 0 1 0 -1.0 } - - Transform { - translation 0 0 -50 - children [ - Shape { - appearance Appearance { - material Material { - diffuseColor 1 1 1 - } - } - geometry Box {size 150 100 10} - } - ] - } - - DEF TR Transform { - translation -50 0 0 - scale 0.75 1 1 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 1 1 0 - shininess 0.5 - } - } - geometry Sphere {radius 25 } - } - ] - } - DEF TS TimeSensor { cycleInterval 4.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [0 0 1 0, 0 0 1 3.14, 0 0 1 6.26] - } - DEF OI2 OrientationInterpolator { - key [0 0.5 1] - keyValue [0 1 0 -1, 0 1 0 1, 0 1 0 -1] - } - DEF PI PositionInterpolator { - key [0 0.5 1] - keyValue [-200 0 100, 200 0 100, -200 0 100] - } - ] -} - -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation -ROUTE TS.fraction_changed TO OI2.set_fraction -ROUTE OI2.value_changed TO VP.orientation -ROUTE TS.fraction_changed TO PI.set_fraction -ROUTE PI.value_changed TO VP.position diff --git a/regression_tests/bifs-3D-viewpoint-bind-jump.bt b/regression_tests/bifs-3D-viewpoint-bind-jump.bt deleted file mode 100644 index c091612..0000000 --- a/regression_tests/bifs-3D-viewpoint-bind-jump.bt +++ /dev/null @@ -1,114 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -Group { - children [ - WorldInfo { - title "Viewpoint bind test" - info ["This shows sensors triggering viewpoint binding" "Viewpoint switching shall not be animated" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - DEF VP1 Viewpoint {description "Front View" position 0 0 300} - DEF VP2 Viewpoint {description "Above View" position 0 300 30 orientation 1 0 0 -1.2 } - - DEF TR Transform { - translation 50 0 0 - children [ - Shape { - appearance Appearance { - material Material { - diffuseColor 0 1 1 - } - } - geometry DEF BOX Box {size 50 50 50} - } - DEF TS2 TouchSensor {} - ] - } - - Transform { - translation -80 0 20 - children [ - Shape { - appearance Appearance { - material Material2D { emissiveColor 1 0 0 filled TRUE } - } - geometry DEF RC_RED Rectangle {size 100 100} - } - ] - } - - Shape { - appearance Appearance { - material Material2D { emissiveColor 1 1 1 filled TRUE } - } - geometry DEF RC_WHITE Rectangle { size 200 200 } - } - - - Transform { - translation -30 0 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 1 1 0 - } - } - geometry DEF SPHERE Sphere {radius 30} - } - DEF TOUCH TouchSensor {} - ] - } - DEF TS TimeSensor { enabled FALSE cycleInterval 2.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - - DEF C Conditional { buffer { REPLACE MAT.diffuseColor BY 0 0 1 } } - DEF RC Conditional { buffer { REPLACE MAT.diffuseColor BY 1 1 0 } } - - DEF SETVP1 Conditional { - buffer { - REPLACE VP1.set_bind BY TRUE - REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP2.activate - } - } - DEF SETVP2 Conditional { - buffer { - REPLACE VP2.set_bind BY TRUE - REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP1.activate - } - } - - ] -} - -DEF MVP ROUTE TOUCH.isActive TO SETVP2.activate -ROUTE TOUCH.isOver TO TS.enabled -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation -ROUTE TS2.isActive TO C.activate -ROUTE TS2.isActive TO RC.reverseActivate diff --git a/regression_tests/bifs-3D-viewpoint-bind.bt b/regression_tests/bifs-3D-viewpoint-bind.bt deleted file mode 100644 index 55c4c38..0000000 --- a/regression_tests/bifs-3D-viewpoint-bind.bt +++ /dev/null @@ -1,115 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - useNames true - } - } - } - ] -} - -Group { - children [ - WorldInfo { - title "Viewpoint bind test" - info ["This shows sensors triggering viewpoint binding" "Viewpoint switching shall be animated" "" "GPAC Regression Tests" "$Date: 2008/11/24 14:58:25 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - - DEF VP1 Viewpoint {description "Front View" position 0 0 200 jump FALSE fieldOfView 0.39} - DEF VP2 Viewpoint {description "Above View" position 0 300 30 orientation 1 0 0 -1.2 jump FALSE} - - DEF TR Transform { - translation 50 0 0 - children [ - Shape { - appearance Appearance { - material Material { - diffuseColor 0 1 1 - } - } - geometry DEF BOX Box {size 50 50 50} - } - DEF TS2 TouchSensor {} - ] - } - - Transform { - translation -80 0 20 - children [ - Shape { - appearance Appearance { - material Material2D { emissiveColor 1 0 0 filled TRUE } - } - geometry DEF RC_RED Rectangle {size 100 100} - } - ] - } - - Shape { - appearance Appearance { - material Material2D { emissiveColor 1 1 1 filled TRUE } - } - geometry DEF RC_WHITE Rectangle { size 200 200 } - } - - - Transform { - translation -30 0 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 1 1 0 - } - } - geometry DEF SPHERE Sphere {radius 30} - } - DEF TOUCH TouchSensor {} - ] - } - DEF TS TimeSensor { enabled FALSE cycleInterval 2.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - - DEF C Conditional { buffer { REPLACE MAT.diffuseColor BY 0 0 1 } } - DEF RC Conditional { buffer { REPLACE MAT.diffuseColor BY 1 1 0 } } - - DEF SETVP1 Conditional { - buffer { - REPLACE VP1.set_bind BY TRUE - REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP2.activate - } - } - DEF SETVP2 Conditional { - buffer { - REPLACE VP2.set_bind BY TRUE - REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP1.activate - } - } - - ] -} - -DEF MVP ROUTE TOUCH.isActive TO SETVP2.activate -ROUTE TOUCH.isOver TO TS.enabled -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation -ROUTE TS2.isActive TO C.activate -ROUTE TS2.isActive TO RC.reverseActivate diff --git a/regression_tests/bifs-3D-viewpoint-ortho-bind.bt b/regression_tests/bifs-3D-viewpoint-ortho-bind.bt deleted file mode 100644 index ff1804e..0000000 --- a/regression_tests/bifs-3D-viewpoint-ortho-bind.bt +++ /dev/null @@ -1,114 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - title "Viewpoint bind test" - info ["This shows sensors triggering viewpoint binding" "Viewpoint switching shall be animated" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - DEF VP1 Viewpoint {description "Front View" position 0 0 200 jump FALSE} - DEF VP2 Viewpoint {description "Above View" position 0 300 30 orientation 1 0 0 -1.2 jump FALSE} - - DEF TR Transform { - translation 50 0 0 - children [ - Shape { - appearance Appearance { - material Material { - diffuseColor 0 1 1 - } - } - geometry DEF BOX Box {size 50 50 50} - } - DEF TS2 TouchSensor {} - ] - } - - Transform { - translation -80 0 20 - children [ - Shape { - appearance Appearance { - material Material2D { emissiveColor 1 0 0 filled TRUE } - } - geometry DEF RC_RED Rectangle {size 100 100} - } - ] - } - - Shape { - appearance Appearance { - material Material2D { emissiveColor 1 1 1 filled TRUE } - } - geometry DEF RC_WHITE Rectangle { size 200 200 } - } - - - Transform { - translation -30 0 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 1 1 0 - } - } - geometry DEF SPHERE Sphere {radius 30} - } - DEF TOUCH TouchSensor {} - ] - } - DEF TS TimeSensor { enabled FALSE cycleInterval 2.0 loop TRUE } - DEF OI OrientationInterpolator { - key [0 0.5 1] - keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] - } - - DEF C Conditional { buffer { REPLACE MAT.diffuseColor BY 0 0 1 } } - DEF RC Conditional { buffer { REPLACE MAT.diffuseColor BY 1 1 0 } } - - DEF SETVP1 Conditional { - buffer { - REPLACE VP1.set_bind BY TRUE - REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP2.activate - } - } - DEF SETVP2 Conditional { - buffer { - REPLACE VP2.set_bind BY TRUE - REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP1.activate - } - } - - ] -} - -DEF MVP ROUTE TOUCH.isActive TO SETVP2.activate -ROUTE TOUCH.isOver TO TS.enabled -ROUTE TS.fraction_changed TO OI.set_fraction -ROUTE OI.value_changed TO TR.rotation -ROUTE TS2.isActive TO C.activate -ROUTE TS2.isActive TO RC.reverseActivate diff --git a/regression_tests/bifs-bitmap-image-meter-metrics.bt b/regression_tests/bifs-bitmap-image-meter-metrics.bt deleted file mode 100644 index 088253f..0000000 --- a/regression_tests/bifs-bitmap-image-meter-metrics.bt +++ /dev/null @@ -1,80 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelWidth 400 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows dragable bitmap with scale 0.75 0.75" "in Meter Metrics" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Bitmap Test" - } - Transform2D { - children [ - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - texture ImageTexture { - url [od:10] - } - } - geometry Bitmap { - scale 0.75 0.75 - } - } - DEF PS PlaneSensor2D { - maxPosition 1 1 - minPosition -1 -1 - } - ] - } - ] - } - ] -} - -ROUTE PS.translation_changed TO TR.translation - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-bitmap-image-pixel-metrics.bt b/regression_tests/bifs-bitmap-image-pixel-metrics.bt deleted file mode 100644 index 6dfb121..0000000 --- a/regression_tests/bifs-bitmap-image-pixel-metrics.bt +++ /dev/null @@ -1,89 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 0 - } - WorldInfo { - info [ - "This test shows an Image (the Osmo4 logo), which has an alpha component being display on a yellow background." - "The geometry node use to display the image is a Bitmap node with a scale of 0.75 0.75" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:08 $ - $Revision: 1.4 $" - "(C) 2002-2004 GPAC Team" - ] - title "Bitmap and Transparent Images" - } - Transform2D { - children [ - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - texture ImageTexture { - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap { - scale 0.75 0.75 - } - } - DEF PS PlaneSensor2D { - maxPosition 200 200 - minPosition -200 -200 - } - ] - } - ] - } - ] -} - -ROUTE PS.translation_changed TO TR.translation - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.png" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-bitmap-image-resizing.bt b/regression_tests/bifs-bitmap-image-resizing.bt deleted file mode 100644 index 4590288..0000000 --- a/regression_tests/bifs-bitmap-image-resizing.bt +++ /dev/null @@ -1,153 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows an image whose size is animated." - "The result is displayed on top of a static image." - "Both textures use a Bitmap node to allow efficient handling of the textures." - "The resizing of the image is not done using a Transform2D node (or TransformMatrix2D) but by changing the size property of the Bitmap node." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.4 $" - "(C) 2002-2006 GPAC Team" - ] - title "Image Resizing" - } - Transform2D { - translation 0 128 - children [ - DEF TR Transform2D { - children [ - Transform2D { - translation -128 0 - children [ - DEF S Shape { - appearance Appearance { - texture ImageTexture { - url [od:12] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap {} - - } - ] - } - Transform2D { - children [ - USE S - ] - } - Transform2D { - translation 128 0 - children [ - USE S - ] - } - ] - } - ] - } - Transform2D { - children [ - USE TR - ] - } - Transform2D { - translation 0 -128 - children [ - USE TR - ] - } - Transform2D { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - texture ImageTexture { - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry DEF BMP Bitmap { - scale 0.75 0.75 - } - } - ] - } - ] - } - DEF TS TimeSensor { - loop TRUE - } - DEF PI PositionInterpolator2D { - key [0 0.5 1] - keyValue [0.75 0.75 0.25 0.25 0.75 0.75] - } - ] -} - -ROUTE TS.fraction_changed TO PI.set_fraction -ROUTE PI.value_changed TO BMP.scale - -RAP AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 12 - esDescr [ - ES_Descriptor { - ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-bitmap-movie-materialkey.bt b/regression_tests/bifs-bitmap-movie-materialkey.bt deleted file mode 100644 index 3dd9cd2..0000000 --- a/regression_tests/bifs-bitmap-movie-materialkey.bt +++ /dev/null @@ -1,101 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - DEF B Background2D { - backColor 0 0 1 - } - WorldInfo { - info [ - "This test shows how to do Color Keying on Video." - "The MaterialKey node allows defining a key color or color range and to make that color transparent in the texture. The degree of transparency can be specified using the transparency property." - - "" - "GPAC Regression Tests" "$Date: 2008/05/19 15:28:17 $ - $Revision: 1.6 $" - "(C) 2002-2004 GPAC Team" - ] - title "Color Keying on Video using the MaterialKey node" - } - Transform2D { - scale 2 2 - children [ - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - texture MovieTexture { - url [od:10] - loop FALSE - } - material DEF MK MaterialKey { - isKeyed TRUE - lowThreshold 0.4 - highThreshold 0.4 - keyColor 1 1 0 - transparency 0 - } - } - geometry Bitmap { - scale 1 1 - } - } - ] - } - ] - } - DEF TS TimeSensor {loop TRUE cycleInterval 10.0} - DEF CI ColorInterpolator { - key [0 1] - keyValue [1 1 1, 0 0 1] - } - ] -} - -#ROUTE TS.fraction_changed TO MK.highThreshold -ROUTE TS.fraction_changed TO CI.set_fraction -ROUTE CI.value_changed TO B.backColor - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-bitmap-movie.bt b/regression_tests/bifs-bitmap-movie.bt deleted file mode 100644 index 5fad0a4..0000000 --- a/regression_tests/bifs-bitmap-movie.bt +++ /dev/null @@ -1,84 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "The Bitmap node is a geometry node which defines a rectangle on which the texture is mapped. The difference with a Rectangle node is that its size is given by the texture, hence no resampling of the texture is needed during the display. Hardware accelerated operations can be used." - "This test shows a dragable video. The Bitmap node allows efficient draging and display of the video." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.4 $" - "(C) 2002-2006 GPAC Team" - ] - title "Efficient Display of Video using the Bitmap node" - } - Transform2D { - scale 2 2 - children [ - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - texture MovieTexture { - url [od:10] - loop FALSE - } - } - geometry Bitmap { - scale 1 1 - } - } - ] - } - ] - } - ] -} - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-bitmap-video-resizing.bt b/regression_tests/bifs-bitmap-video-resizing.bt deleted file mode 100644 index 6509472..0000000 --- a/regression_tests/bifs-bitmap-video-resizing.bt +++ /dev/null @@ -1,152 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows a video whose size is animated, the result is displayed on top of a static image." - "Both textures use a Bitmap node to allow efficient handling of the textures." - "The resizing of the video is not done using a Transform2D node (or TransformMatrix2D) but by changing the size property of the Bitmap node." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.5 $" - "(C) 2002-2006 GPAC Team" - ] - title "Bitmap Video Resizing" - } - Transform2D { - translation 0 128 - children [ - DEF TR Transform2D { - children [ - Transform2D { - translation -128 0 - children [ - DEF S Shape { - appearance Appearance { - texture ImageTexture { - url [od:12] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap {} - - } - ] - } - Transform2D { - children [ - USE S - ] - } - Transform2D { - translation 128 0 - children [ - USE S - ] - } - ] - } - ] - } - Transform2D { - children [ - USE TR - ] - } - Transform2D { - translation 0 -128 - children [ - USE TR - ] - } - Transform2D { - children [ - Transform2D { - children [ - Shape { - appearance Appearance { - texture MovieTexture { - loop TRUE - url [od:10] - } - } - geometry DEF BMP Bitmap { - scale 0.75 0.75 - } - } - ] - } - ] - } - DEF TS TimeSensor { - loop TRUE - } - DEF PI PositionInterpolator2D { - key [0 0.5 1] - keyValue [2 2 0.25 0.25 2 2] - } - ] -} - -ROUTE TS.fraction_changed TO PI.set_fraction -ROUTE PI.value_changed TO BMP.scale - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 12 - esDescr [ - ES_Descriptor { - ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-command-animated-osmo4logo.bt b/regression_tests/bifs-command-animated-osmo4logo.bt deleted file mode 100644 index a6f726c..0000000 --- a/regression_tests/bifs-command-animated-osmo4logo.bt +++ /dev/null @@ -1,315 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 0 1 1 - } - WorldInfo { - info ["This shows the Osmo4 logo" "animated through BIFS commands" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Osmo4 Logo" - } - Shape { - appearance Appearance { - texture LinearGradient { - endPoint 0 1 - key [0 0.33 1] - keyValue [0 0.5 0.5 0 0.75 0.75 0 0.75 1] - } - } - geometry Rectangle { - size 300 300 - } - } - Switch { - choice [ - DEF BCIRCLE Shape { - appearance DEF ABLACK Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Circle { - radius 60 - } - } - DEF BTRIANGLE Shape { - appearance USE ABLACK - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coord Coordinate2D { - point [-40 0 40 0 0 -60] - } - } - } - DEF RCIRCLE Shape { - appearance Appearance { - material DEF RMAT Material2D { - lineProps DEF LP XLineProperties { - lineColor 1 0 0 - width 20 - } - } - } - geometry Circle { - radius 100 - } - } - ] - } - DEF MOV Transform2D { - children [ - DEF LOGO Transform2D {} - ] - } - ] -} - - -AT 1000 { - APPEND TO LOGO.children DEF BR Transform2D { - scale 0 0 - translation -150 -150 - children [ - USE BCIRCLE - ] - } - APPEND TO MOV.children DEF TIME TimeSensor { - cycleInterval 1.5 - } - APPEND TO MOV.children DEF POS PositionInterpolator2D { - key [0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1] - keyValue [-150 -150 -135 135 120 120 105 -105 -90 -90 -75 75 60 60 45 -45 -30 -30 -15 15 0 0] - } - APPEND TO MOV.children DEF SCALE PositionInterpolator2D { - key [0 1] - keyValue [0.1 0.1 1 1] - } - INSERT ROUTE DEF R1 TIME.fraction_changed TO POS.set_fraction - INSERT ROUTE DEF R2 TIME.fraction_changed TO SCALE.set_fraction - INSERT ROUTE DEF R3 POS.value_changed TO BR.translation - INSERT ROUTE DEF R4 SCALE.value_changed TO BR.scale -} - -AT 2500 { - DELETE ROUTE R1 - DELETE ROUTE R2 - DELETE ROUTE R3 - DELETE ROUTE R4 - DELETE TIME - DELETE POS - DELETE SCALE - REPLACE BR.translation BY 0 0 - REPLACE BR.scale BY 1 1 - APPEND TO LOGO.children DEF BT Transform2D { - scale 9 0.5 - translation 0 20 - children [ - USE BTRIANGLE - ] - } - APPEND TO MOV.children DEF TIME2 TimeSensor { - cycleInterval 1.5 - } - APPEND TO MOV.children DEF POS_BT PositionInterpolator2D { - key [0 1] - keyValue [0 20 0 90] - } - APPEND TO MOV.children DEF POS_BR PositionInterpolator2D { - key [0 1] - keyValue [0 0 0 -30] - } - APPEND TO MOV.children DEF SCALE_BR PositionInterpolator2D { - key [0 0.7 1] - keyValue [1 1 1.4 1.4 1 1] - } - APPEND TO MOV.children DEF SCALE_BT PositionInterpolator2D { - key [0 0.7 1] - keyValue [9 0.5 5 0.7 1 1] - } - INSERT ROUTE DEF R1 TIME2.fraction_changed TO POS_BT.set_fraction - INSERT ROUTE DEF R2 TIME2.fraction_changed TO POS_BR.set_fraction - INSERT ROUTE DEF R3 TIME2.fraction_changed TO SCALE_BT.set_fraction - INSERT ROUTE DEF R4 TIME2.fraction_changed TO SCALE_BR.set_fraction - INSERT ROUTE DEF R5 POS_BT.value_changed TO BT.translation - INSERT ROUTE DEF R6 POS_BR.value_changed TO BR.translation - INSERT ROUTE DEF R7 SCALE_BT.value_changed TO BT.scale - INSERT ROUTE DEF R8 SCALE_BR.value_changed TO BR.scale -} - -AT 4000 { - DELETE ROUTE R1 - DELETE ROUTE R2 - DELETE ROUTE R3 - DELETE ROUTE R4 - DELETE ROUTE R5 - DELETE ROUTE R6 - DELETE ROUTE R7 - DELETE ROUTE R8 - DELETE TIME2 - DELETE POS_BT - DELETE SCALE_BT - DELETE POS_BR - DELETE SCALE_BR - REPLACE BT.translation BY 0 90 - REPLACE BR.translation BY 0 -30 - REPLACE BR.scale BY 1 1 - REPLACE BT.scale BY 1 1 - REPLACE LP.width BY 0 - APPEND TO LOGO.children DEF RC Transform2D { - children [ - USE RCIRCLE - ] - } - APPEND TO MOV.children DEF TIME3 TimeSensor { - cycleInterval 1.5 - } - APPEND TO MOV.children DEF WIDTH ScalarInterpolator { - key [0 0.5 0.75 1] - keyValue [0 25 15 20] - } - APPEND TO MOV.children DEF COL ColorInterpolator { - key [0 1] - keyValue [0 0 0 1 0 0] - } - INSERT ROUTE DEF R1 TIME3.fraction_changed TO WIDTH.set_fraction - INSERT ROUTE DEF R2 TIME3.fraction_changed TO COL.set_fraction - INSERT ROUTE DEF R3 WIDTH.value_changed TO LP.width - INSERT ROUTE DEF R4 COL.value_changed TO LP.lineColor -} - -AT 5500 { - DELETE ROUTE R1 - DELETE ROUTE R2 - DELETE ROUTE R3 - DELETE ROUTE R4 - DELETE TIME3 - DELETE WIDTH - DELETE COL - REPLACE LP.width BY 20 - REPLACE LP.transparency BY 0 - REPLACE LP.lineColor BY 1 0 0 - APPEND TO MOV.children Transform2D { - translation 110 38 - children [ - Shape { - appearance Appearance { - material DEF TXTMAT Material2D { - emissiveColor 0.1 0 0.1 - filled TRUE - transparency 1 - } - } - geometry Text { - string ["sm"] - fontStyle DEF FS FontStyle { - justify ["BEGIN" "BEGIN"] - size 160 - } - } - } - ] - } - APPEND TO MOV.children Transform2D { - scale 0.3 0.3 - translation 340 -70 - children [ - USE LOGO - ] - } - APPEND TO MOV.children Transform2D { - translation 380 38 - children [ - Shape { - appearance Appearance { - material USE TXTMAT - } - geometry Text { - string ["4"] - fontStyle USE FS - } - } - ] - } - APPEND TO MOV.children DEF TIME4 TimeSensor { - cycleInterval 1.5 - } - APPEND TO MOV.children DEF POS_MOV PositionInterpolator2D { - key [0 0.5 1] - keyValue [0 0 75 0 -75 0] - } - APPEND TO MOV.children DEF SCALE_MOV PositionInterpolator2D { - key [0 0.5 1] - keyValue [1 1 0.4 0.4 0.4 0.4] - } - APPEND TO MOV.children DEF ALPHA2 ScalarInterpolator { - key [0 0.9 1] - keyValue [0.95 0.5 0] - } - INSERT ROUTE DEF R1 TIME4.fraction_changed TO POS_MOV.set_fraction - INSERT ROUTE DEF R2 TIME4.fraction_changed TO SCALE_MOV.set_fraction - INSERT ROUTE DEF R3 TIME4.fraction_changed TO ALPHA2.set_fraction - INSERT ROUTE DEF R4 POS_MOV.value_changed TO MOV.translation - INSERT ROUTE DEF R5 SCALE_MOV.value_changed TO MOV.scale - INSERT ROUTE DEF R6 ALPHA2.value_changed TO TXTMAT.transparency -} - -AT 7000 { - DELETE ROUTE R1 - DELETE ROUTE R2 - DELETE ROUTE R3 - DELETE ROUTE R4 - DELETE ROUTE R5 - DELETE ROUTE R6 - DELETE TIME4 - DELETE ALPHA2 - DELETE POS_MOV - DELETE SCALE_MOV - REPLACE TXTMAT.transparency BY 0.5 - REPLACE MOV.translation BY -75 0 - REPLACE MOV.scale BY 0.4 0.4 - - APPEND TO LOGO.children Transform2D { - children [ - DEF TS TimeSensor { - cycleInterval 4 - loop TRUE - } - DEF PI PositionInterpolator2D { - key [0 0.25 0.5 0.75 1] - keyValue [1 1 -1 1 1 1 1 -1 1 1] - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 0.8 0] - } - ] - } - INSERT ROUTE TS.fraction_changed TO PI.set_fraction - INSERT ROUTE TS.fraction_changed TO SI.set_fraction - INSERT ROUTE PI.value_changed TO LOGO.scale - INSERT ROUTE SI.value_changed TO TXTMAT.transparency -} - diff --git a/regression_tests/bifs-command-delete-index.bt b/regression_tests/bifs-command-delete-index.bt deleted file mode 100644 index 933ecff..0000000 --- a/regression_tests/bifs-command-delete-index.bt +++ /dev/null @@ -1,58 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows indexed value deletion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Indexed Value delete test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - Transform2D { - scale 0.5 0.5 - children [ - DEF S Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - DELETE COORD.point[0] -} - diff --git a/regression_tests/bifs-command-delete-node.bt b/regression_tests/bifs-command-delete-node.bt deleted file mode 100644 index eb6477f..0000000 --- a/regression_tests/bifs-command-delete-node.bt +++ /dev/null @@ -1,58 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows node deletion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Node delete test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - Transform2D { - scale 0.5 0.5 - children [ - DEF S Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - DELETE MAT -} - diff --git a/regression_tests/bifs-command-delete-route.bt b/regression_tests/bifs-command-delete-route.bt deleted file mode 100644 index 59aa2f0..0000000 --- a/regression_tests/bifs-command-delete-route.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows route deletion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Route delete test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - DEF TS TimeSensor { - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -DEF R1 ROUTE SI.value_changed TO MAT.transparency - -AT 2500 { - DELETE ROUTE R1 -} - diff --git a/regression_tests/bifs-command-global-qp.bt b/regression_tests/bifs-command-global-qp.bt deleted file mode 100644 index 8269eea..0000000 --- a/regression_tests/bifs-command-global-qp.bt +++ /dev/null @@ -1,66 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -DEF OG OrderedGroup { - children [ - WorldInfo { - info ["This shows GlobalQuantizer usage" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "GlobalQuantizer test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - ] -} - - -AT 100 { - GLOBALQP QuantizationParameter { - position2DQuant TRUE - position2DMin -100 -100 - position2DMax 100 100 - position2DNbBits 2 - } -} - -AT 1000 { - APPEND TO OG.children DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } -} - diff --git a/regression_tests/bifs-command-insert-index.bt b/regression_tests/bifs-command-insert-index.bt deleted file mode 100644 index fd51f0d..0000000 --- a/regression_tests/bifs-command-insert-index.bt +++ /dev/null @@ -1,58 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows indexed value insertion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Indexed Value insert test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - Transform2D { - scale 0.5 0.5 - children [ - DEF S Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - INSERT AT COORD.point[0] -50 -50 -} - diff --git a/regression_tests/bifs-command-insert-node.bt b/regression_tests/bifs-command-insert-node.bt deleted file mode 100644 index b34c875..0000000 --- a/regression_tests/bifs-command-insert-node.bt +++ /dev/null @@ -1,74 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -DEF OG OrderedGroup { - children [ - WorldInfo { - info ["This shows node insertion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Node insert test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - DEF S Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - INSERT AT OG.children[0] Transform2D { - scale 0.5 0.5 - translation -100 -50 - children [ - USE S - ] - } -} - -AT 4000 { - APPEND TO OG.children Transform2D { - scale 0.5 0.5 - translation 100 50 - children [ - USE S - ] - } -} - diff --git a/regression_tests/bifs-command-insert-nodedef.bt b/regression_tests/bifs-command-insert-nodedef.bt deleted file mode 100644 index 3bfd59a..0000000 --- a/regression_tests/bifs-command-insert-nodedef.bt +++ /dev/null @@ -1,64 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -DEF OG OrderedGroup { - children [ - WorldInfo { - info ["This shows node insertion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Node insert test" - } - Background2D { - backColor 1 1 1 - } - Transform2D { - scale 0.5 0.5 - children [ - DEF S Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - INSERT AT OG.children[0] DEF TR2 Transform2D { - scale 0.5 0.5 - translation -100 -50 - children [ - USE S - ] - } -} - diff --git a/regression_tests/bifs-command-insert-route.bt b/regression_tests/bifs-command-insert-route.bt deleted file mode 100644 index fced44e..0000000 --- a/regression_tests/bifs-command-insert-route.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows route insertion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "route insert test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - DEF TS TimeSensor { - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -DEF R1 ROUTE SI.value_changed TO MAT.transparency - -AT 2000 { - INSERT ROUTE SI.value_changed TO TR.rotationAngle -} - diff --git a/regression_tests/bifs-command-multiple-replace-field.bt b/regression_tests/bifs-command-multiple-replace-field.bt deleted file mode 100644 index a4d750a..0000000 --- a/regression_tests/bifs-command-multiple-replace-field.bt +++ /dev/null @@ -1,66 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - includeInlineProfileLevelFlag true - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows multiple field replacement" "through BIFS extended commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "multiple field replace test" - } - DEF N0 Background2D { - backColor 1 1 1 - } - DEF N1 Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF N2 Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF N3 Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 1000 { - MULTIPLEREPLACE N2 { - emissiveColor 0 1 0 - transparency 0.9 - lineProps LineProperties { - lineColor 0 0 1 - width 2 - } - } -} - diff --git a/regression_tests/bifs-command-multiple-replace-index.bt b/regression_tests/bifs-command-multiple-replace-index.bt deleted file mode 100644 index 1fd07bd..0000000 --- a/regression_tests/bifs-command-multiple-replace-index.bt +++ /dev/null @@ -1,62 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows multiple indexed field replacement" "through BIFS Extended commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "multiple indexed field replace test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - MULTIPLEINDREPLACE COORD.point [ - 0 BY -20 0 - 2 BY 50 50 - 5 BY -50 -80 - ] -} - diff --git a/regression_tests/bifs-command-node-delete-ex.bt b/regression_tests/bifs-command-node-delete-ex.bt deleted file mode 100644 index 1ae1f39..0000000 --- a/regression_tests/bifs-command-node-delete-ex.bt +++ /dev/null @@ -1,125 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows extended node deletion" "through BIFS extended commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Node delete test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF OG OrderedGroup { - order [2 1 3] - children [ - DEF TR Transform2D { - scale 0.5 0.5 - children [ - DEF S Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - Transform2D { - translation -50 40 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 1 - filled TRUE - } - } - geometry Circle { - radius 30 - } - } - ] - } - Transform2D { - translation 50 -50 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 1 - filled TRUE - } - } - geometry Rectangle { - size 100 50 - } - } - ] - } - ] - } - Transform2D { - translation 0 -100 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - string ["test"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 24 - } - } - } - ] - } - DEF SC Script { - eventIn SFTime set_text - field SFNode t USE TXT - field SFNode g USE OG - url ["javascript: function set_text(value, ts) {t.string[0] = 'order: ' + g.order;}" ] - } - DEF TS TimeSensor { - loop TRUE - } - ] -} - -ROUTE TS.cycleTime TO SC.set_text - -AT 2000 { - XDELETE TR -} - diff --git a/regression_tests/bifs-command-proto-delete.bt b/regression_tests/bifs-command-proto-delete.bt deleted file mode 100644 index 278cedf..0000000 --- a/regression_tests/bifs-command-proto-delete.bt +++ /dev/null @@ -1,93 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -PROTO MYPROTO [ - exposedField SFVec2f translation 0 0 -] { - Transform2D { - translation IS translation - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - ] - } -} -PROTO MYOTHERPROTO [ - exposedField SFVec2f translation 0 0 -] { - Transform2D { - translation IS translation - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 50 - } - } - ] - } -} -DEF ORD OrderedGroup { - children [ - DEF BACK Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows proto declaration deletion" "through BIFS Extended commands" "The player should complain about unknown proto" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Proto Delete test" - } - MYPROTO {} - ] -} - - -AT 1000 { - DELETEPROTO ALL -} - -AT 2000 { - INSERT AT ORD.children[2] MYPROTO { - translation -100 0 - } -} - -AT 3000 { - INSERT AT ORD.children[2] MYOTHERPROTO { - translation 100 0 - } -} - diff --git a/regression_tests/bifs-command-proto-insert.bt b/regression_tests/bifs-command-proto-insert.bt deleted file mode 100644 index 1e3b534..0000000 --- a/regression_tests/bifs-command-proto-insert.bt +++ /dev/null @@ -1,83 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -DEF ORD OrderedGroup { - children [ - DEF BACK Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows proto declaration insertion" "through BIFS Extended commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Proto Insert test" - } - DEF TR Transform2D { - scale 0.5 0.5 - translation -100 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 1000 { - INSERTPROTO [ - PROTO MYPROTO [ - exposedField SFVec2f translation 0 0 - ] { - Transform2D { - translation IS translation - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - ] - } - } - ] - INSERT AT ORD.children[0] MYPROTO { - translation 100 0 - } -} - diff --git a/regression_tests/bifs-command-protolist-delete.bt b/regression_tests/bifs-command-protolist-delete.bt deleted file mode 100644 index d419fc5..0000000 --- a/regression_tests/bifs-command-protolist-delete.bt +++ /dev/null @@ -1,93 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -PROTO MYPROTO [ - exposedField SFVec2f translation 0 0 -] { - Transform2D { - translation IS translation - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } - ] - } -} -PROTO MYOTHERPROTO [ - exposedField SFVec2f translation 0 0 -] { - Transform2D { - translation IS translation - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 50 - } - } - ] - } -} -DEF ORD OrderedGroup { - children [ - DEF BACK Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows proto declaration list deletion" "through BIFS Extended commands" "The player should complain about unknown nodes" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Proto List Delete test" - } - MYPROTO {} - ] -} - - -AT 1000 { - DELETEPROTO [MYPROTO] -} - -AT 2000 { - INSERT AT ORD.children[0] MYPROTO { - translation -100 0 - } -} - -AT 3000 { - INSERT AT ORD.children[0] MYOTHERPROTO { - translation 100 0 - } -} - diff --git a/regression_tests/bifs-command-quantification.bt b/regression_tests/bifs-command-quantification.bt deleted file mode 100644 index 0d54474..0000000 --- a/regression_tests/bifs-command-quantification.bt +++ /dev/null @@ -1,186 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows quantification of IFS2D" "with several values" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Quantification Test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - QuantizationParameter { - position2DQuant TRUE - position2DMin -100 -100 - position2DMax 100 100 - position2DNbBits 9 - colorQuant FALSE - } - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - REPLACE TR BY DEF TR1 Transform2D { - scale 0.5 0.5 - children [ - QuantizationParameter { - position2DQuant TRUE - position2DMin -100 -100 - position2DMax 100 100 - position2DNbBits 8 - colorQuant FALSE - } - Shape { - appearance Appearance { - material USE MAT - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } -} - -AT 4000 { - REPLACE TR1 BY DEF TR2 Transform2D { - scale 0.5 0.5 - children [ - QuantizationParameter { - position2DQuant TRUE - position2DMin -100 -100 - position2DMax 100 100 - position2DNbBits 6 - colorQuant FALSE - } - Shape { - appearance Appearance { - material USE MAT - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } -} - -AT 6000 { - REPLACE TR2 BY DEF TR3 Transform2D { - scale 0.5 0.5 - children [ - QuantizationParameter { - position2DQuant TRUE - position2DMin -100 -100 - position2DMax 100 100 - position2DNbBits 4 - colorQuant FALSE - } - Shape { - appearance Appearance { - material USE MAT - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } -} - -AT 8000 { - REPLACE TR3 BY DEF TR4 Transform2D { - scale 0.5 0.5 - children [ - QuantizationParameter { - position2DQuant TRUE - position2DMin -100 -100 - position2DMax 100 100 - position2DNbBits 2 - colorQuant FALSE - } - Shape { - appearance Appearance { - material USE MAT - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } -} - -AT 10000 { - REPLACE TR4 BY DEF TR5 Transform2D { - scale 0.5 0.5 - children [ - QuantizationParameter { - position2DQuant TRUE - position2DMin -100 -100 - position2DMax 100 100 - position2DNbBits 1 - colorQuant FALSE - } - Shape { - appearance Appearance { - material USE MAT - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } -} - diff --git a/regression_tests/bifs-command-replace-field.bt b/regression_tests/bifs-command-replace-field.bt deleted file mode 100644 index d5bb9e6..0000000 --- a/regression_tests/bifs-command-replace-field.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info [ - "This test shows field replacement using BIFS commands." - "At initialization, the scene shows a polygon filled in red" - "At 2s, the scene is modified and the polygon is not filled, just the border is diplayed." - "The command used in this sequence replaces the content of the field and not just a single value" - "It applies to both SFField and MFField, for replacement of single value in an MFField, use Indexed Replacement" - "cf bifs-command-replace-index" - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" - "(C) 2002-2004 GPAC Team"] - title "Field Replacement" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - REPLACE MAT.filled BY FALSE -} - diff --git a/regression_tests/bifs-command-replace-index.bt b/regression_tests/bifs-command-replace-index.bt deleted file mode 100644 index 6f31dbe..0000000 --- a/regression_tests/bifs-command-replace-index.bt +++ /dev/null @@ -1,58 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows indexed value replacement" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Indexed Value replace test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - REPLACE COORD.point[2] BY 100 100 -} - diff --git a/regression_tests/bifs-command-replace-node-null.bt b/regression_tests/bifs-command-replace-node-null.bt deleted file mode 100644 index 735ff3c..0000000 --- a/regression_tests/bifs-command-replace-node-null.bt +++ /dev/null @@ -1,65 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info [ - "This test shows a BIFS command replacing a node by the NULL node" - "Initially, the scene has a white background but at 2s, the Background2D node is replaced by a NULL node. Since the Background2D node is not used anymore, it is deleted." - "Replacing with a NULL node does not change the index of the following siblings." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Node Replacement with a NULL node" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - REPLACE BACK BY NULL -} - diff --git a/regression_tests/bifs-command-replace-node.bt b/regression_tests/bifs-command-replace-node.bt deleted file mode 100644 index 3ce1e78..0000000 --- a/regression_tests/bifs-command-replace-node.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info [ - "This test shows node replacement through BIFS commands" - "Initally, the scene has a white background, but at 2s the Background2D node is replaced by a new node defining a yellow background." - "The same test could be done replacing the field backColor of the Background2D node, this would be a field replacement." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Node Replacement" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - -AT 2000 { - REPLACE BACK BY Background2D { - backColor 0 1 1 - } -} - diff --git a/regression_tests/bifs-command-replace-route.bt b/regression_tests/bifs-command-replace-route.bt deleted file mode 100644 index 70323ed..0000000 --- a/regression_tests/bifs-command-replace-route.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows route replacement" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "route replace test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - DEF TS TimeSensor { - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -DEF R1 ROUTE SI.value_changed TO MAT.transparency - -AT 2000 { - REPLACE ROUTE R1 BY SI.value_changed TO TR.rotationAngle -} - diff --git a/regression_tests/bifs-command-replace-scene-null.bt b/regression_tests/bifs-command-replace-scene-null.bt deleted file mode 100644 index 96a0faf..0000000 --- a/regression_tests/bifs-command-replace-scene-null.bt +++ /dev/null @@ -1,37 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - objectTypeIndication 1 - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 0 - } - WorldInfo { - info ["This shows scene replacement" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "scene replace test" - } - ] -} - - -AT 2000 { - REPLACE SCENE BY NULL - -} - diff --git a/regression_tests/bifs-command-replace-scene.bt b/regression_tests/bifs-command-replace-scene.bt deleted file mode 100644 index 7208b0e..0000000 --- a/regression_tests/bifs-command-replace-scene.bt +++ /dev/null @@ -1,76 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 0 - } - WorldInfo { - info [ - "This test shows scene replacement using BIFS commands." - "At initialization, the scene is empty, only a yellow background." - "At 2s, the whole scene is replaced by a new one containing a red polygon." - "All resources belonging to the previous scene are reclaimed." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" - "(C) 2002-2004 GPAC Team"] - title "Scene Replacement" - } - ] -} - - -AT 2000 { - REPLACE SCENE BY OrderedGroup { - children [ - WorldInfo { - info ["This shows scene replacement" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "scene replace test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] - } - -} - diff --git a/regression_tests/bifs-command-route-add-children.bt b/regression_tests/bifs-command-route-add-children.bt deleted file mode 100644 index 9de3bfa..0000000 --- a/regression_tests/bifs-command-route-add-children.bt +++ /dev/null @@ -1,79 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -DEF OG OrderedGroup { - children [ - WorldInfo { - info ["This shows node routing" "through addChildren field" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Node Routing test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR1 Transform2D { - translation -100 0 - } - DEF TR2 Transform2D { - translation 100 0 - } - ] -} - -ROUTE TR1.children TO TR2.addChildren - -AT 2000 { - APPEND TO TR1.children Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 50 - } - } -} - -AT 4000 { - REPLACE M1.filled BY FALSE -} - -AT 6000 { - REPLACE TR1.children[0] BY NULL -} - -AT 8000 { - APPEND TO TR1.children Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } -} - diff --git a/regression_tests/bifs-command-route-children.bt b/regression_tests/bifs-command-route-children.bt deleted file mode 100644 index a29b410..0000000 --- a/regression_tests/bifs-command-route-children.bt +++ /dev/null @@ -1,79 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 300 - } - } - } - ] -} - -DEF OG OrderedGroup { - children [ - WorldInfo { - info ["This shows node routing" "through children field" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Node duplicate test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR1 Transform2D { - translation -100 0 - } - DEF TR2 Transform2D { - translation 100 0 - } - ] -} - -ROUTE TR1.children TO TR2.children - -AT 2000 { - APPEND TO TR1.children Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 50 - } - } -} - -AT 4000 { - REPLACE M1.filled BY FALSE -} - -AT 6000 { - REPLACE TR1.children[0] BY NULL -} - -AT 8000 { - APPEND TO TR1.children Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 25 - } - } -} - diff --git a/regression_tests/bifs-command-route-node-exposedfield.bt b/regression_tests/bifs-command-route-node-exposedfield.bt deleted file mode 100644 index e08426c..0000000 --- a/regression_tests/bifs-command-route-node-exposedfield.bt +++ /dev/null @@ -1,80 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -DEF OG OrderedGroup { - children [ - WorldInfo { - info ["This shows exposed field routing" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Field Routing Test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - Transform2D { - translation -100 0 - children [ - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 50 - } - } - ] - } - Transform2D { - translation 100 0 - children [ - Shape { - appearance Appearance { - material DEF M2 Material2D { - emissiveColor 1 1 0 - } - } - geometry Circle { - radius 50 - } - } - ] - } - ] -} - -ROUTE M1.filled TO M2.filled - -AT 2000 { - REPLACE M1.filled BY TRUE -} - -AT 4000 { - REPLACE M1.filled BY FALSE -} - -AT 6000 { - REPLACE M2.filled BY TRUE -} - diff --git a/regression_tests/bifs-command-route-node.bt b/regression_tests/bifs-command-route-node.bt deleted file mode 100644 index 1d217f3..0000000 --- a/regression_tests/bifs-command-route-node.bt +++ /dev/null @@ -1,76 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -DEF OG OrderedGroup { - children [ - WorldInfo { - info ["This shows node routing" "through exposed fields" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Node routing test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - Transform2D { - translation -100 0 - children [ - Shape { - appearance DEF APP1 Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 50 - } - } - ] - } - Transform2D { - translation 100 0 - children [ - Shape { - appearance DEF APP2 Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Circle { - radius 50 - } - } - ] - } - ] -} - -ROUTE APP1.material TO APP2.material - -AT 2000 { - REPLACE APP1.material BY Material2D { - emissiveColor 1 0 1 - filled TRUE - } -} - diff --git a/regression_tests/bifs-command-route-remove-children.bt b/regression_tests/bifs-command-route-remove-children.bt deleted file mode 100644 index 03384ea..0000000 --- a/regression_tests/bifs-command-route-remove-children.bt +++ /dev/null @@ -1,93 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -DEF OG OrderedGroup { - children [ - WorldInfo { - info ["This shows node deletion" "through removeChildren field" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Node delete test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR1 Transform2D { - translation -100 0 - } - DEF TR2 Transform2D { - translation 100 0 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Circle { - radius 50 - } - } - ] - } - ] -} - -DEF R1 ROUTE TR1.children TO TR2.addChildren - -AT 2000 { - APPEND TO TR1.children Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 50 - } - } -} - -AT 3000 { - DELETE ROUTE R1 - INSERT ROUTE TR1.children TO TR2.removeChildren -} - -AT 4000 { - APPEND TO TR1.children Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 1 - filled TRUE - } - } - geometry Circle { - radius 20 - } - } -} - -AT 100000 { - DELETE ROUTE R1 -} - diff --git a/regression_tests/bifs-externproto-forestgump-lib.bt b/regression_tests/bifs-externproto-forestgump-lib.bt deleted file mode 100644 index 80fbde8..0000000 --- a/regression_tests/bifs-externproto-forestgump-lib.bt +++ /dev/null @@ -1,463 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO FORESTGUMP [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFFloat lineWidth 3 - exposedField SFColor lineColor 0.121569 0.101961 0.0901961 - exposedField SFTime runTime 1 - exposedField SFBool loop TRUE - exposedField SFTime start 0 -] { - Transform2D { - rotationAngle IS rotation - scale IS scale - translation IS translation - children [ - DEF MYSWITCH Switch { - whichChoice 0 - choice [ - Transform2D { - scale 0.0899561 0.0900365 - translation 260.243 42.9024 - children [ - Transform2D { - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - geometry Curve2D { - type [1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-2827 -11 -2864 -2 -2864 -2 -2883 -2 -2883 -2 -2892 -2 -2901 -11 -2911 -11 -2920 -11 -2929 -20 -2939 -29 -2939 -29 -2957 -48 -2957 -48 -2966 -57 -2957 -57 -2966 -76 -2966 -85 -2976 -95 -2976 -104 -2976 -104 -2976 -132 -2976 -132 -2976 -132 -2976 -160 -2976 -160 -2966 -178 -2957 -188 -2957 -188 -2957 -188 -2939 -197 -2939 -197 -2939 -197 -2920 -197 -2920 -197 -2920 -197 -2911 -206 -2911 -206 -2911 -206 -2892 -206 -2892 -206 -2892 -206 -2873 -206 -2873 -206 -2873 -206 -2855 -215 -2855 -215 -2855 -215 -2836 -215 -2836 -215 -2836 -215 -2827 -206 -2827 -206 -2827 -206 -2808 -197 -2808 -197 -2799 -188 -2799 -188 -2790 -178 -2790 -178 -2790 -169 -2790 -169 -2780 -160 -2780 -160 -2771 -150 -2771 -150 -2771 -141 -2771 -141 -2771 -132 -2771 -132 -2771 -122 -2771 -122 -2771 -113 -2771 -113 -2771 -104 -2771 -104 -2771 -95 -2771 -95 -2771 -85 -2771 -85 -2771 -76 -2780 -57 -2780 -48 -2780 -48 -2790 -29 -2790 -29 -2790 -29 -2808 -20 -2808 -20 -2808 -20 -2818 -11 -2818 -11 -2827 -2 -2827 -2 -2836 -2 -2836 -2 -2846 -2 -2855 -2 -2873 -2 -2883 -2] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 2 1 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-2883 -225 -2883 -262 -2883 -262 -2883 -281 -2883 -281 -2883 -290 -2883 -299 -2883 -308 -2883 -327 -2883 -327 -2892 -336 -2892 -336 -2892 -336 -2892 -383 -2892 -392 -2892 -401 -2892 -429 -2892 -439 -2892 -439 -2892 -467 -2892 -467 -2892 -467 -2892 -485 -2892 -485 -2901 -485 -2901 -485 -2901 -494 -2901 -494 -2901 -504 -2901 -513 -2901 -532 -2901 -541] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-3004 -755 -2994 -727 -2985 -708 -2976 -690 -2976 -680 -2976 -643 -2976 -643 -2957 -625 -3004 -653 -3004 -653 -3004 -653 -3115 -718 -3115 -708 -3115 -662 -3032 -541 -2957 -541 -2939 -541 -2901 -522 -2883 -541 -2883 -541 -2855 -560 -2855 -560 -2846 -569 -2818 -587 -2818 -606 -2818 -625 -2790 -662 -2790 -708 -2790 -773 -2799 -848 -2799 -913 -2799 -931 -2808 -931 -2808 -950 -2808 -959 -2790 -931 -2790 -931 -2780 -904 -2743 -857 -2734 -829 -2734 -820 -2697 -773 -2706 -773] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-2985 -346 -2994 -346 -3022 -374 -3032 -374 -3041 -374 -3050 -383 -3050 -392 -3050 -392 -3134 -392 -3143 -392 -3152 -392 -3134 -364 -3134 -364 -3134 -364 -3106 -346 -3106 -346 -3097 -336 -2985 -253 -2957 -253 -2939 -253 -2920 -271 -2911 -271 -2901 -271 -2873 -281 -2864 -281 -2836 -271 -2790 -234 -2771 -225 -2762 -225 -2734 -206 -2725 -197 -2715 -188 -2669 -160 -2669 -160 -2660 -160 -2660 -150 -2660 -169 -2660 -206 -2641 -262 -2641 -299] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0900093 0.0899546 - translation 190.415 42.8184 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-2083 -20 -2120 -20 -2120 -20 -2130 -20 -2130 -20 -2139 -20 -2139 -20 -2148 -20 -2148 -20 -2148 -20 -2167 -20 -2167 -20 -2167 -20 -2195 -30 -2195 -30 -2195 -30 -2204 -48 -2213 -58 -2213 -58 -2232 -67 -2241 -76 -2241 -76 -2241 -113 -2241 -113 -2241 -113 -2250 -132 -2250 -141 -2250 -151 -2241 -169 -2241 -169 -2241 -179 -2223 -188 -2223 -188 -2223 -188 -2213 -216 -2204 -216 -2195 -216 -2195 -225 -2185 -225 -2185 -225 -2157 -225 -2157 -225 -2157 -225 -2139 -225 -2139 -225 -2139 -225 -2120 -225 -2120 -225 -2120 -225 -2111 -216 -2111 -216 -2111 -216 -2092 -216 -2092 -216 -2092 -216 -2074 -206 -2074 -206 -2074 -206 -2064 -197 -2064 -197 -2064 -197 -2055 -179 -2055 -179 -2046 -179 -2046 -179 -2046 -169 -2046 -169 -2037 -160 -2037 -160 -2037 -151 -2037 -151 -2037 -141 -2037 -141 -2037 -132 -2037 -132 -2037 -123 -2037 -123 -2037 -113 -2037 -113 -2037 -104 -2037 -104 -2037 -95 -2037 -95 -2037 -95 -2037 -76 -2037 -76 -2037 -76 -2055 -39 -2055 -39 -2055 -39 -2074 -30 -2074 -30 -2074 -30 -2092 -20 -2092 -20 -2092 -20 -2102 -11 -2102 -11 -2111 -11 -2111 -11 -2120 -11 -2120 -11 -2120 -2 -2120 -2 -2157 -2 -2157 -2] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-2130 -244 -2130 -290 -2130 -318 -2130 -355 -2130 -383 -2130 -402 -2139 -420 -2139 -439 -2139 -448 -2139 -476 -2139 -485 -2139 -495 -2139 -504 -2139 -513 -2139 -523 -2139 -523 -2139 -532 -2139 -532 -2139 -541 -2139 -541 -2130 -551 -2130 -551] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-2306 -792 -2269 -764 -2232 -718 -2204 -690 -2195 -681 -2204 -690 -2213 -690 -2241 -681 -2325 -671 -2343 -653 -2343 -653 -2362 -644 -2362 -644 -2371 -634 -2278 -569 -2278 -569 -2241 -560 -2213 -551 -2176 -551 -2139 -551 -2027 -578 -2027 -616 -2027 -625 -2018 -625 -2018 -634 -1999 -671 -1999 -709 -1999 -755 -1999 -811 -2074 -904 -2111 -922 -2148 -941 -2139 -950 -2102 -950 -2064 -950 -2009 -950 -1971 -950] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-2223 -402 -2260 -420 -2325 -439 -2353 -411 -2371 -392 -2381 -374 -2381 -355 -2381 -318 -2371 -290 -2343 -281 -2306 -262 -2232 -244 -2185 -244 -2176 -244 -2139 -225 -2130 -225 -2120 -225 -2046 -234 -2027 -234 -1981 -234 -1897 -253 -1878 -299 -1869 -318 -1851 -346 -1851 -383 -1851 -411 -1860 -448 -1860 -467] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0899291 0.0900198 - translation 123.698 44.4248 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 1 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-1283 -11 -1320 -11 -1320 -11 -1330 -11 -1330 -11 -1339 -11 -1339 -11 -1348 -11 -1348 -11 -1348 -11 -1367 -11 -1367 -11 -1367 -20 -1367 -20 -1376 -20 -1376 -20 -1376 -20 -1413 -39 -1413 -39 -1413 -39 -1432 -76 -1432 -76 -1432 -85 -1441 -104 -1441 -113 -1441 -123 -1451 -141 -1451 -151 -1451 -169 -1451 -160 -1441 -169 -1441 -169 -1432 -188 -1432 -188 -1432 -188 -1423 -206 -1423 -206 -1423 -206 -1404 -216 -1404 -216 -1395 -216 -1386 -225 -1376 -225 -1376 -225 -1348 -225 -1348 -225 -1348 -225 -1330 -225 -1330 -225 -1330 -225 -1311 -225 -1311 -225 -1311 -225 -1293 -216 -1293 -216 -1293 -216 -1283 -206 -1283 -206 -1283 -206 -1265 -197 -1265 -197 -1265 -197 -1255 -188 -1255 -188 -1255 -188 -1246 -169 -1246 -169 -1237 -169 -1237 -169 -1237 -160 -1237 -160 -1237 -151 -1237 -151 -1237 -141 -1237 -141 -1237 -132 -1237 -132 -1237 -123 -1237 -123 -1237 -113 -1237 -113 -1237 -104 -1237 -104 -1237 -95 -1237 -95 -1237 -85 -1237 -85 -1237 -85 -1237 -67 -1237 -67 -1237 -67 -1255 -48 -1255 -39 -1255 -39 -1265 -20 -1265 -20 -1265 -20 -1283 -11 -1283 -11 -1283 -11 -1302 -2 -1302 -2 -1311 -2 -1311 -2 -1320 -2 -1320 -2 -1330 -2 -1339 -2 -1358 -2 -1367 -2] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 1 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-1311 -234 -1311 -271 -1311 -271 -1311 -281 -1311 -281 -1311 -299 -1311 -318 -1311 -355 -1311 -374 -1311 -392 -1311 -430 -1311 -448 -1311 -457 -1311 -485 -1311 -495 -1311 -495 -1311 -513 -1311 -513 -1311 -523 -1311 -523 -1311 -532 -1311 -532 -1311 -541 -1311 -560 -1311 -578 -1311 -560] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-1572 -662 -1534 -709 -1469 -755 -1441 -783 -1423 -802 -1451 -764 -1451 -764 -1460 -736 -1506 -578 -1469 -560 -1451 -550 -1330 -597 -1320 -597 -1293 -606 -1274 -616 -1274 -662 -1274 -690 -1274 -727 -1283 -746 -1283 -755 -1293 -792 -1302 -811 -1339 -885 -1274 -904 -1274 -987] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2] - point Coordinate2D { - point [-1609 -541 -1618 -467 -1599 -504 -1590 -448 -1562 -309 -1423 -253 -1283 -253 -1237 -253 -1144 -281 -1144 -327 -1144 -346 -1135 -355 -1144 -374 -1153 -392 -1227 -467 -1227 -485] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0899947 0.0899257 - translation 62.0964 37.7238 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 1 2 1 2 1] - point Coordinate2D { - point [-511 -30 -549 -30 -567 -30 -577 -30 -586 -30 -604 -48 -604 -48 -614 -48 -623 -67 -623 -76 -623 -86 -642 -76 -642 -95 -642 -95 -642 -123 -642 -123 -642 -132 -642 -141 -642 -151 -642 -160 -623 -179 -623 -179 -623 -179 -614 -188 -614 -188 -614 -188 -595 -188 -595 -188 -595 -188 -586 -197 -586 -197 -586 -197 -567 -197 -567 -197 -567 -197 -549 -207 -549 -207 -549 -207 -539 -197 -539 -197 -539 -197 -521 -197 -521 -197 -521 -197 -502 -188 -502 -188 -493 -179 -493 -179 -484 -169 -484 -169 -474 -169 -474 -169 -474 -160 -474 -160 -465 -160 -465 -160 -465 -151 -465 -151 -465 -141 -465 -141 -465 -132 -465 -132 -456 -132 -456 -132 -456 -114 -456 -114 -456 -86 -465 -86 -465 -86 -465 -86 -474 -67 -474 -58 -474 -48 -484 -48 -484 -39 -484 -39 -493 -21 -493 -21 -502 -21 -502 -21 -511 -11 -511 -11 -521 -2 -521 -2 -558 -2 -511 -30 -521 -2] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 1 2 2] - point Coordinate2D { - point [-539 -225 -539 -262 -549 -281 -549 -318 -549 -337 -558 -355 -558 -374 -558 -383 -558 -411 -558 -430 -558 -439 -558 -448 -558 -467 -558 -476 -558 -504 -567 -513 -558 -523] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 1 2 2 2 2 2] - point Coordinate2D { - point [-865 -551 -865 -569 -846 -653 -846 -672 -846 -690 -837 -699 -837 -709 -837 -718 -828 -718 -828 -709 -828 -681 -763 -606 -735 -588 -716 -579 -651 -541 -632 -541 -577 -541 -521 -532 -465 -560 -446 -569 -400 -616 -381 -634 -381 -634 -353 -699 -372 -699 -400 -699 -428 -672 -428 -672 -437 -672 -437 -672 -474 -653 -474 -653 -484 -653 -493 -662 -493 -672 -493 -690 -502 -755 -502 -774 -502 -783 -502 -792 -493 -811 -484 -830 -474 -848 -474 -830] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2] - point Coordinate2D { - point [-1023 -365 -976 -318 -930 -300 -874 -272 -865 -272 -837 -253 -828 -253 -716 -216 -577 -262 -456 -262 -428 -262 -335 -318 -363 -346 -372 -355 -437 -346 -456 -346 -456 -346 -511 -337 -511 -337 -530 -337 -539 -318 -549 -318] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0899962 0.0899977 - translation -16.1993 42.7489 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [279 -20 260 -20 232 -1 223 -1 214 -1 205 -20 195 -20 186 -20 167 -29 167 -39 167 -48 149 -66 149 -76 139 -94 139 -94 139 -113 139 -132 130 -141 130 -159 130 -169 139 -178 139 -187 139 -187 149 -206 149 -206 149 -206 158 -225 158 -225 158 -225 177 -234 177 -234 177 -234 195 -234 195 -234 195 -234 214 -234 214 -234 214 -234 232 -234 232 -234 242 -234 251 -225 260 -225 270 -225 270 -225 279 -215 279 -215 288 -215 288 -215 298 -206 298 -206 307 -197 307 -197 316 -187 316 -187 316 -178 316 -178 325 -169 325 -169 335 -159 335 -159 335 -141 335 -141 335 -132 335 -122 335 -113 335 -94 325 -85 325 -76 325 -76 325 -48 325 -48 325 -48 316 -29 316 -29 316 -29 298 -20 298 -20 288 -11 288 -11 279 -11 279 -11 270 -11 260 -11 232 -11 223 -11] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 1 2 1 2] - point Coordinate2D { - point [232 -252 232 -280 214 -327 214 -345 214 -364 205 -411 205 -429 205 -438 205 -466 205 -476 205 -494 205 -494 205 -513 205 -513 195 -531 195 -531 195 -569 195 -569] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 1 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [56 -848 65 -857 130 -913 149 -931 158 -941 186 -968 149 -913 149 -913 130 -866 130 -773 130 -717 130 -680 112 -662 112 -624 112 -578 139 -522 195 -522 260 -522 409 -531 409 -615 409 -615 428 -634 400 -634 372 -634 298 -615 279 -624 260 -634 279 -736 279 -755] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-56 -327 -46 -290 -37 -243 -28 -197 -28 -187 0 -159 9 -141 9 -132 19 -141 19 -150 28 -169 112 -243 149 -243 167 -243 214 -262 251 -262 279 -262 298 -252 316 -271 325 -280 353 -299 353 -299 353 -299 381 -327 391 -327 446 -355 325 -373 316 -373 279 -383 205 -373 177 -345] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0900707 0.0899924 - translation -85.7923 41.9814 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [1060 -20 1060 -20 1014 -2 1004 -2 995 -2 986 -11 976 -11 976 -11 949 -20 949 -20 939 -20 921 -48 921 -58 921 -58 902 -86 902 -86 902 -86 902 -104 902 -104 902 -113 902 -123 902 -132 902 -132 911 -151 911 -151 911 -151 921 -169 921 -169 921 -169 939 -188 939 -188 939 -188 949 -197 949 -197 949 -197 967 -206 967 -206 967 -206 986 -206 995 -206 1004 -206 1004 -206 1014 -206 1014 -206 1023 -206 1023 -206 1032 -206 1032 -206 1051 -197 1051 -197 1060 -197 1060 -197 1069 -188 1069 -188 1079 -179 1079 -179 1079 -169 1079 -169 1088 -169 1088 -169 1088 -169 1088 -151 1088 -151 1088 -141 1097 -123 1097 -104 1097 -86 1097 -86 1088 -67 1088 -67 1079 -48 1079 -48 1079 -48 1069 -39 1069 -39 1060 -30 1060 -30 1051 -30 1051 -30 1042 -20 1032 -20 1014 -11 1004 -11] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 1 2 1 2] - point Coordinate2D { - point [995 -225 995 -253 1014 -318 1014 -346 1014 -365 1014 -411 1014 -430 1014 -439 1014 -467 1014 -476 1014 -485 1014 -485 1014 -504 1014 -504 1014 -513 1014 -523 1014 -541 1023 -541] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 1 2 2 2 2 2 2] - point Coordinate2D { - point [809 -932 846 -932 893 -913 921 -913 958 -913 930 -895 930 -895 921 -895 893 -895 865 -774 865 -764 837 -699 921 -569 976 -541 1014 -523 1088 -578 1097 -588 1107 -597 1144 -625 1153 -634 1209 -690 1069 -644 1051 -662 1032 -681 1116 -792 1153 -792] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2] - point Coordinate2D { - point [688 -532 688 -485 716 -374 753 -355 800 -327 883 -262 939 -262 976 -262 1032 -281 1069 -262 1125 -234 1190 -309 1209 -327 1237 -355 1181 -383 1162 -402 1144 -420 1107 -448 1107 -476] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0899064 0.08998 - translation -164.619 43.1904 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 2 1 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [1878 -20 1851 -11 1841 -1 1813 -1 1804 -1 1804 -11 1795 -11 1785 -11 1767 -39 1767 -48 1758 -57 1739 -66 1739 -85 1739 -85 1739 -113 1739 -113 1739 -122 1748 -132 1748 -141 1748 -141 1758 -159 1758 -169 1758 -169 1767 -187 1767 -187 1767 -187 1776 -206 1776 -206 1776 -206 1785 -215 1785 -215 1785 -215 1804 -225 1804 -225 1804 -225 1823 -225 1823 -225 1823 -225 1841 -225 1841 -225 1841 -225 1860 -215 1860 -215 1869 -215 1869 -215 1878 -206 1878 -206 1888 -197 1888 -197 1897 -187 1897 -187 1906 -178 1906 -178 1916 -169 1916 -169 1916 -159 1916 -159 1925 -150 1925 -150 1925 -150 1925 -132 1925 -132 1925 -122 1925 -122 1934 -113 1934 -113 1934 -113 1934 -85 1925 -76 1925 -76 1906 -66 1906 -57 1906 -48 1906 -39 1897 -29 1897 -29 1878 -20 1878 -20 1869 -20 1869 -20 1860 -11 1860 -11 1851 -11 1841 -11 1823 -1 1804 -1] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 1 2 1 2] - point Coordinate2D { - point [1832 -234 1832 -271 1841 -327 1841 -364 1841 -383 1841 -411 1841 -429 1841 -429 1841 -466 1841 -466 1841 -466 1841 -485 1841 -485 1851 -485 1851 -485 1851 -494 1851 -494 1841 -494 1841 -494 1841 -531 1841 -531] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [1758 -959 1767 -931 1804 -894 1813 -866 1813 -857 1851 -792 1851 -792 1851 -792 1851 -792 1851 -792 1851 -792 1841 -801 1841 -801 1813 -829 1776 -708 1776 -699 1776 -662 1767 -606 1776 -578 1776 -578 1776 -550 1776 -550 1776 -550 1785 -559 1795 -559 1841 -559 1916 -550 1953 -513 1962 -504 1999 -485 1999 -485 1999 -485 2018 -466 2018 -466 2018 -466 2037 -457 2037 -457 2037 -457 2027 -457 2027 -457 2009 -476 1944 -606 1944 -652 1944 -652 1934 -680 1934 -680 1934 -680 1962 -662 1962 -662 1971 -652 2018 -615 2037 -606 2037 -606 2092 -597 2074 -597] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2] - point Coordinate2D { - point [1674 -476 1646 -448 1618 -411 1590 -383 1581 -373 1572 -345 1572 -345 1553 -327 1692 -262 1730 -252 1776 -243 1767 -225 1804 -243 1813 -243 1897 -243 1906 -243 1944 -243 1990 -271 1999 -280 2027 -308 2092 -383 2092 -411] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.089974 0.090028 - translation -247.069 37.0465 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2 1] - point Coordinate2D { - point [2715 -4 2687 -4 2660 -13 2641 -13 2641 -13 2622 -23 2622 -23 2613 -32 2585 -69 2585 -69 2585 -78 2576 -106 2576 -116 2576 -134 2567 -125 2576 -143 2576 -143 2576 -171 2576 -171 2576 -171 2594 -190 2594 -190 2594 -190 2604 -209 2604 -209 2604 -209 2613 -218 2613 -218 2613 -218 2632 -218 2632 -218 2632 -218 2650 -218 2650 -218 2650 -218 2669 -218 2669 -218 2669 -218 2687 -209 2687 -209 2687 -209 2706 -209 2706 -209 2715 -199 2715 -199 2725 -199 2725 -199 2734 -199 2734 -199 2743 -190 2743 -190 2753 -190 2753 -190 2762 -181 2762 -181 2762 -171 2762 -171 2771 -171 2771 -171 2771 -162 2771 -162 2780 -153 2780 -153 2780 -153 2780 -134 2780 -134 2780 -125 2780 -97 2780 -88 2780 -78 2771 -69 2771 -60 2771 -60 2762 -50 2762 -50 2762 -50 2753 -32 2753 -32 2753 -23 2753 -23 2743 -13 2743 -13 2734 -13 2734 -13 2715 5 2715 -4 2734 -13] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 1 2 1 2] - point Coordinate2D { - point [2660 -255 2660 -274 2660 -311 2660 -329 2660 -348 2660 -376 2660 -395 2660 -413 2660 -413 2660 -432 2660 -432 2660 -450 2660 -460 2660 -497 2660 -506] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [2464 -822 2483 -794 2520 -748 2539 -720 2539 -711 2576 -683 2567 -683 2529 -683 2483 -711 2446 -711 2427 -711 2474 -636 2474 -636 2492 -608 2539 -571 2567 -553 2576 -553 2585 -534 2594 -534 2622 -525 2641 -506 2669 -506 2697 -506 2734 -506 2762 -506 2780 -506 2873 -553 2883 -571 2883 -571 2892 -590 2892 -599 2892 -599 2901 -627 2901 -627 2901 -627 2911 -608 2911 -608 2920 -581 2957 -534 2957 -506] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2] - point Coordinate2D { - point [2641 -292 2585 -311 2529 -320 2464 -320 2427 -320 2483 -274 2483 -274 2529 -227 2687 -227 2799 -227 2836 -227 2920 -227 2948 -236 2966 -246 3004 -264 3004 -274 3013 -292 3050 -320 3050 -329] - } - } - } - ] - } - ] - } - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval IS runTime - loop IS loop - startTime IS start - } - DEF VAL Valuator { - Factor1 8 - } - ROUTE TS.fraction_changed TO VAL.inSFFloat - ROUTE VAL.outSFInt32 TO MYSWITCH.whichChoice -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This file is used as a proto library by another file." - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" - ] - title "ExternProto Library File" - } - Shape { - appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } - geometry Text { - string [ - "This file is used as a proto library by another file." - "" - "GPAC Regression Tests" - "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" - "(C) 2002-2004 GPAC Team" - ] - fontStyle FontStyle { - size 25 - justify [ "MIDDLE" "MIDDLE" ] - } - } - } - ] -} - - diff --git a/regression_tests/bifs-externproto-forestgump.bt b/regression_tests/bifs-externproto-forestgump.bt deleted file mode 100644 index 20b4798..0000000 --- a/regression_tests/bifs-externproto-forestgump.bt +++ /dev/null @@ -1,96 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -EXTERNPROTO FORESTGUMP [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFFloat lineWidth 3 - exposedField SFColor lineColor 0.121569 0.101961 0.0901961 - exposedField SFTime runTime 1 - exposedField SFBool loop TRUE - exposedField SFTime start 0 -] ""od:20"" - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["Each animated logo is an instance of a single proto" "defined in an external library" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Complexe proto Test" - } - FORESTGUMP { - translation -75 -75 - scale 1.1 1.1 - rotation 0.75 - runTime 0.5 - } - FORESTGUMP { - translation -100 50 - scale 1 1.5 - runTime 0.75 - start 2 - } - FORESTGUMP { - translation 0 10 - scale 1.8 1.8 - start 4 - } - DEF ANIM FORESTGUMP { - translation 75 -75 - rotation -1.25 - runTime 0.8 - start 6 - } - DEF TIMER TimeSensor { - cycleInterval 2 - loop TRUE - startTime 6 - } - DEF SI ScalarInterpolator { - key [0 1] - keyValue [0 6.283] - } - ] -} - -ROUTE TIMER.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO ANIM.rotation - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 20 - URLstring "bifs-externproto-forestgump-lib.mp4" - } - ] -} - diff --git a/regression_tests/bifs-externproto-mfurl-lib.bt b/regression_tests/bifs-externproto-mfurl-lib.bt deleted file mode 100644 index 0045ae7..0000000 --- a/regression_tests/bifs-externproto-mfurl-lib.bt +++ /dev/null @@ -1,52 +0,0 @@ - -PROTO testURL [ - exposedField MFString theURL [""] -] { - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF MYTEXT ImageTexture { - url IS theURL - } - } - geometry Bitmap {} - - } - ] - } -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This file is used as a proto library by another file." - "GPAC Regression Tests" - "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" - "(C) 2002-2004 GPAC Team" - ] - title "ExternProto Library File" - } - Shape { - appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } - geometry Text { - string [ - "This file is used as a proto library by another file." - "" - "GPAC Regression Tests" - "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" - "(C) 2002-2004 GPAC Team" - ] - fontStyle FontStyle { - size 25 - justify [ "MIDDLE" "MIDDLE" ] - } - } - } - ] -} - - diff --git a/regression_tests/bifs-externproto-mfurl.bt b/regression_tests/bifs-externproto-mfurl.bt deleted file mode 100644 index 151bbdc..0000000 --- a/regression_tests/bifs-externproto-mfurl.bt +++ /dev/null @@ -1,69 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -EXTERNPROTO testURL [ - exposedField MFString theURL [""] -] ""od:20"" - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This is a proto with an MF URL ISed field" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "ExternProto with URL Test" - } - DEF testInstance testURL { - theURL ["10"] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 20 - URLstring "bifs-externproto-mfurl-lib.mp4" - } - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 3 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-externproto-nood-lib.bt b/regression_tests/bifs-externproto-nood-lib.bt deleted file mode 100644 index 6926dba..0000000 --- a/regression_tests/bifs-externproto-nood-lib.bt +++ /dev/null @@ -1,109 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] { - Transform2D { - translation IS translation - children [ - DEF S Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - Transform2D { - translation -100 0 - children [ - USE S - ] - } - ] - } -} -PROTO GEO_PRO [ - exposedField SFVec2f translation 0 0 - exposedField SFNode obj NULL -] { - Transform2D { - translation IS translation - children [ - DEF S Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - } - ] - } -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This file is used as a proto library by another file." - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" - ] - title "ExternProto Library File" - } - Shape { - appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } - geometry Text { - string [ - "This file is used as a proto library by another file." - "" - "GPAC Regression Tests" - "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" - "(C) 2002-2004 GPAC Team" - ] - fontStyle FontStyle { - size 25 - justify [ "MIDDLE" "MIDDLE" ] - } - } - } - ] -} diff --git a/regression_tests/bifs-externproto-nood.bt b/regression_tests/bifs-externproto-nood.bt deleted file mode 100644 index f5dd172..0000000 --- a/regression_tests/bifs-externproto-nood.bt +++ /dev/null @@ -1,70 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -EXTERNPROTO EXPR1 [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFColor color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] "bifs-externproto-nood-lib.bt#GEOMETRY_PROTO" - -EXTERNPROTO EXPR2 [ - exposedField SFVec2f translation 0 0 - exposedField SFNode obj NULL -] "bifs-externproto-nood-lib.bt#GEO_PRO" - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of extern proto" "with vrml-like addressing (no MPEG-4 ODs)" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] - title "Simple ExternProto Test" - } - EXPR1 { - translation 20 50 - color 0 1 0 - obj DEF C Circle { - radius 75 - } - } - EXPR2 { - translation -50 -50 - obj USE C - } - ] -} - - diff --git a/regression_tests/bifs-externproto-simple-lib.bt b/regression_tests/bifs-externproto-simple-lib.bt deleted file mode 100644 index 4b22e75..0000000 --- a/regression_tests/bifs-externproto-simple-lib.bt +++ /dev/null @@ -1,90 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] { - Transform2D { - translation IS translation - children [ - DEF S Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - Transform2D { - translation -100 0 - children [ - USE S - ] - } - ] - } -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This file is used as a proto library by another file." - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" - ] - title "ExternProto Library File" - } - Shape { - appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } - geometry Text { - string [ - "This file is used as a proto library by another file." - "" - "GPAC Regression Tests" - "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" - "(C) 2002-2004 GPAC Team" - ] - fontStyle FontStyle { - size 25 - justify [ "MIDDLE" "MIDDLE" ] - } - } - } - ] -} diff --git a/regression_tests/bifs-externproto-simple.bt b/regression_tests/bifs-externproto-simple.bt deleted file mode 100644 index 1b57e7d..0000000 --- a/regression_tests/bifs-externproto-simple.bt +++ /dev/null @@ -1,81 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -EXTERNPROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] ""od:20"" - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of extern proto with regular addressing by proto ID" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Simple ExternProto Test" - } - DEF G GEOMETRY_PROTO { - translation 200 0 - scale 1 1.5 - rotation 0.78 - Color 1 0 1 - transparency 0.75 - lineColor 1 0 0 - lineWidth 2 - obj Circle { - radius 75 - } - } - Transform2D { - translation -300 0 - children [ - USE G - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 20 - URLstring "bifs-externproto-simple-lib.mp4" - } - ] -} - diff --git a/regression_tests/bifs-game-arrange.bt b/regression_tests/bifs-game-arrange.bt deleted file mode 100644 index 3aa3699..0000000 --- a/regression_tests/bifs-game-arrange.bt +++ /dev/null @@ -1,452 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This file demonstrates how to use ECMAScript to make games in BIFS." - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" - ] - title "Arrange" - } - Transform2D { - translation 0 150 - children [ - DEF StartTS TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 0.5 0.5 - filled TRUE - } - } - geometry Rectangle { - size 100 30 - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Text { - string ["Start Game"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - DEF TimeSensorTick TimeSensor { - enabled FALSE - loop TRUE - } - Transform2D { - translation 0 75 - children [ - Shape { - appearance DEF TA Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry DEF TextField Text { - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 22 - } - } - } - ] - } - Switch { - choice [ - DEF Hole Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 1 - filled TRUE - } - } - geometry DEF R Rectangle { - size 50 50 - } - } - ] - } - Transform2D { - translation 0 -50 - children [ - DEF Table Form { - size 150 150 - groups [1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 7 -1 8 -1 9 -1 1 2 3 -1 4 5 6 -1 7 8 9 -1] - constraints ["SHin" "SHin" "SHin" "SVin"] - groupsIndex [1 2 3 -1 4 5 6 -1 7 8 9 -1 10 11 12 -1] - children [ - DEF a_1_1 Switch { - whichChoice 0 - choice [ - Transform2D { - children [ - DEF TS_1_1 TouchSensor {} - Shape { - appearance DEF RA Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry USE R - } - Shape { - appearance USE TA - geometry Text { - string ["1"] - fontStyle USE FS - } - } - ] - } - USE Hole - ] - } - DEF a_1_2 Switch { - whichChoice 0 - choice [ - Transform2D { - children [ - DEF TS_1_2 TouchSensor {} - Shape { - appearance USE RA - geometry USE R - } - Shape { - appearance USE TA - geometry Text { - string ["2"] - fontStyle USE FS - } - } - ] - } - USE Hole - ] - } - DEF a_1_3 Switch { - whichChoice 0 - choice [ - Transform2D { - children [ - DEF TS_1_3 TouchSensor {} - Shape { - appearance USE RA - geometry USE R - } - Shape { - appearance USE TA - geometry Text { - string ["3"] - fontStyle USE FS - } - } - ] - } - USE Hole - ] - } - DEF a_2_1 Switch { - whichChoice 0 - choice [ - Transform2D { - children [ - DEF TS_2_1 TouchSensor {} - Shape { - appearance USE RA - geometry USE R - } - Shape { - appearance USE TA - geometry Text { - string ["4"] - fontStyle USE FS - } - } - ] - } - USE Hole - ] - } - DEF a_2_2 Switch { - whichChoice 0 - choice [ - Transform2D { - children [ - DEF TS_2_2 TouchSensor {} - Shape { - appearance USE RA - geometry USE R - } - Shape { - appearance USE TA - geometry Text { - string ["5"] - fontStyle USE FS - } - } - ] - } - USE Hole - ] - } - DEF a_2_3 Switch { - whichChoice 0 - choice [ - Transform2D { - children [ - DEF TS_2_3 TouchSensor {} - Shape { - appearance USE RA - geometry USE R - } - Shape { - appearance USE TA - geometry Text { - string ["6"] - fontStyle USE FS - } - } - ] - } - USE Hole - ] - } - DEF a_3_1 Switch { - whichChoice 0 - choice [ - Transform2D { - children [ - DEF TS_3_1 TouchSensor {} - Shape { - appearance USE RA - geometry USE R - } - Shape { - appearance USE TA - geometry Text { - string ["7"] - fontStyle USE FS - } - } - ] - } - USE Hole - ] - } - DEF a_3_2 Switch { - whichChoice 0 - choice [ - Transform2D { - children [ - DEF TS_3_2 TouchSensor {} - Shape { - appearance USE RA - geometry USE R - } - Shape { - appearance USE TA - geometry Text { - string ["8"] - fontStyle USE FS - } - } - ] - } - USE Hole - ] - } - DEF a_3_3 Switch { - whichChoice 1 - choice [ - Transform2D { - children [ - DEF TS_3_3 TouchSensor {} - Shape { - appearance USE RA - geometry USE R - } - Shape { - appearance USE TA - geometry Text { - string ["9"] - fontStyle USE FS - } - } - ] - } - USE Hole - ] - } - ] - } - ] - } - DEF SC Script { - eventIn SFVec2f move - eventIn SFBool startGame - eventIn SFTime tickTime - field SFNode txtField USE TextField - field SFNode table USE Table - field SFInt32 gsize 3 - field SFInt32 ghrow 2 - field SFInt32 ghcol 2 - field SFInt32 gtime 0 - field SFInt32 gmoves 0 - field SFInt32 gshuffling 0 - field SFInt32 size 3 - field SFBool isStarted FALSE - eventOut SFBool hasWin - url ["javascript: - function r(low,hi) {return Math.floor((hi-low)*Math.random()+low); } - function r1(hi) {return Math.floor((hi-1)*Math.random()+1); } - function r0(hi) {return Math.floor((hi)*Math.random()); } - function startGame(value) {if (value) {shuffle();gtime = 0;gmoves = 0;isStarted = !isStarted; hasWin = false;}} - function stopGame(){isStarted = !isStarted;} - function tickTime(value){showStatus();gtime++;} - function checkWin(){if (!isStarted) return; if (!isHole(gsize-1,gsize-1)) return;for (i=0;i<gsize;i++)for (j=0;j<gsize;j++) {if (!(i==gsize-1 && j==gsize-1)) {if (getValue(i,j)!=(i*gsize+j+1).toString()) return;}}hasWin = true;stopGame();txtField.string[0] = '!! CONGRATS !!';txtField.string[1] = 'You have done it in ' + gtime + ' secs ' + 'with ' + gmoves + ' moves!';txtField.string[2] = 'Your speed is ' + Math.round(1000*gmoves/gtime)/1000 + ' moves/sec';} - function showStatus() {if (hasWin) return;txtField.string[0] = 'Time: ' + gtime + ' secs Moves: ' + gmoves;txtField.string[1] = '';txtField.string[2] = '';} - function getCell(row, col) {return table.children[row * gsize + col];} - function setValue(row,col,val) {v = getCell(row, col);v.whichChoice = 0;v.choice[0].children[2].geometry.string[0] = val;} - function getValue(row,col) {v = getCell(row, col);return v.choice[0].children[2].geometry.string[0];} - function setHole(row,col) { v = getCell(row, col);v.whichChoice = 1;ghrow = row;ghcol = col;} - function getRow(obj){a = obj.id.split('_');return a[1];} - function getCol(obj) {a = obj.id.split('_');return a[2];} - function isHole(row, col) {return (row==ghrow && col==ghcol) ? true : false;} - function getHoleInRow(row) {return (row==ghrow) ? ghcol : -1;} - function getHoleInCol(col) {return (col==ghcol) ? ghrow : -1;} - function shiftHoleRow(src,dest,row) {src = parseInt(src);dest = parseInt(dest);if (src < dest) {for (i=src;i<dest;i++) {setValue(row,i,getValue(row,i+1));setHole(row,i+1);}}if (dest < src) {for (i=src;i>dest;i--) {setValue(row,i,getValue(row,i-1));setHole(row,i-1);}}} - function shiftHoleCol(src,dest,col) {src = parseInt(src);dest = parseInt(dest);if (src < dest) {for (i=src;i<dest;i++) {setValue(i,col,getValue(i+1,col));setHole(i+1,col);}}if (dest < src){for (i=src;i>dest;i--){ setValue(i,col,getValue(i-1,col));setHole(i-1,col);}}} - function moveRowCol(r,c) { if (!isStarted && !gshuffling) { return; }if (isHole(r,c)) {return; }hc = getHoleInRow(r);if (hc != -1) {shiftHoleRow(hc,c,r);gmoves++;checkWin();return;} hr = getHoleInCol(c);if (hr != -1){shiftHoleCol(hr,r,c);gmoves++;checkWin();return;} } - function move(value) {moveRowCol(value.x-1,value.y-1);} - function shuffle() {gshuffling = true;for (i=0;i<gsize;i++) {for (j=0;j<gsize+10;j++) { if (j==0) {t = r0(gsize);while (t == ghrow) t = r0(gsize); moveRowCol(t, ghcol);} else {t = r0(gsize);while (t == ghcol) t = r0(gsize); moveRowCol(ghrow, t);}}}gshuffling = false;}" ] - } - DEF V_1_1 Valuator {} - DEF C_1_1 Conditional { - buffer { - REPLACE V_1_1.inSFVec2f BY 1 1 - } - } - DEF V_1_2 Valuator {} - DEF C_1_2 Conditional { - buffer { - REPLACE V_1_2.inSFVec2f BY 1 2 - } - } - DEF V_1_3 Valuator {} - DEF C_1_3 Conditional { - buffer { - REPLACE V_1_3.inSFVec2f BY 1 3 - } - } - DEF V_2_1 Valuator {} - DEF C_2_1 Conditional { - buffer { - REPLACE V_2_1.inSFVec2f BY 2 1 - } - } - DEF V_2_2 Valuator {} - DEF C_2_2 Conditional { - buffer { - REPLACE V_2_2.inSFVec2f BY 2 2 - } - } - DEF V_2_3 Valuator {} - DEF C_2_3 Conditional { - buffer { - REPLACE V_2_3.inSFVec2f BY 2 3 - } - } - DEF V_3_1 Valuator {} - DEF C_3_1 Conditional { - buffer { - REPLACE V_3_1.inSFVec2f BY 3 1 - } - } - DEF V_3_2 Valuator {} - DEF C_3_2 Conditional { - buffer { - REPLACE V_3_2.inSFVec2f BY 3 2 - } - } - DEF V_3_3 Valuator {} - DEF C_3_3 Conditional { - buffer { - REPLACE V_3_3.inSFVec2f BY 3 3 - } - } - DEF WinConditional Conditional { - buffer { - REPLACE TimeSensorTick.enabled BY FALSE -# REPLACE TimeSensorTick.stopTime BY 0 - } - } - DEF StartConditional Conditional { - buffer { - REPLACE TimeSensorTick.enabled BY TRUE -# REPLACE TimeSensorTick.startTime BY 0 - } - } - ] -} - -ROUTE StartTS.isActive TO StartConditional.activate -ROUTE StartTS.isActive TO SC.startGame -ROUTE TimeSensorTick.cycleTime TO SC.tickTime -ROUTE SC.hasWin TO WinConditional.activate -ROUTE TS_1_1.isActive TO C_1_1.activate -ROUTE TS_1_2.isActive TO C_1_2.activate -ROUTE TS_1_3.isActive TO C_1_3.activate -ROUTE TS_2_1.isActive TO C_2_1.activate -ROUTE TS_2_2.isActive TO C_2_2.activate -ROUTE TS_2_3.isActive TO C_2_3.activate -ROUTE TS_3_1.isActive TO C_3_1.activate -ROUTE TS_3_2.isActive TO C_3_2.activate -ROUTE TS_3_3.isActive TO C_3_3.activate -ROUTE V_1_1.outSFVec2f TO SC.move -ROUTE V_1_2.outSFVec2f TO SC.move -ROUTE V_1_3.outSFVec2f TO SC.move -ROUTE V_2_1.outSFVec2f TO SC.move -ROUTE V_2_2.outSFVec2f TO SC.move -ROUTE V_2_3.outSFVec2f TO SC.move -ROUTE V_3_1.outSFVec2f TO SC.move -ROUTE V_3_2.outSFVec2f TO SC.move -ROUTE V_3_3.outSFVec2f TO SC.move - diff --git a/regression_tests/bifs-game-breakout.bt b/regression_tests/bifs-game-breakout.bt deleted file mode 100644 index 07c4ab5..0000000 --- a/regression_tests/bifs-game-breakout.bt +++ /dev/null @@ -1,1035 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - objectTypeIndication 2 - streamType 3 - bufferSizeDB 5000 - maxBitrate 13616 - avgBitrate 13616 - decSpecificInfo BIFSv2Config { - nodeIDbits 10 - routeIDbits 10 - protoIDbits 10 - isCommandStream true - pixelMetric true - pixelWidth 500 - pixelHeight 500 - } - } - slConfigDescr SLConfigDescriptor { - useAccessUnitStartFlag true - useAccessUnitEndFlag true - useTimeStampsFlag true - timeStampResolution 1000 - timeStampLength 32 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This game was translated from" "the site http://javascript.internet.com'" - "Written and designed by Nick Young (ywing9787@aol.com)" - "Translated and adapted by " "Cyril Concolato (cyril.concolato@enst.fr), June 2003" - "GPAC Regression Tests" "$Date: 2008/05/19 15:28:18 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team" - ] - title "Breakout using MPEG-4 BIFS and Javascript" - } - Transform2D { - translation 0 200 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Breakout Using MPEG-4 BIFS and Javascript"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - style "BOLD" - } - } - } - ] - } - DEF N0 TimeSensor { - cycleInterval 0.001 - enabled FALSE - loop TRUE - } - Transform2D { - translation -215 150 - children [ - DEF N1 TouchSensor {} - Transform2D { - translation 16 -16 - children [ - Transform2D { - translation 197 -150 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Rectangle { - size 394 300 - } - } - ] - } - ] - } - DEF N2 Transform2D { - translation 21 -8 - children [ - Transform2D { - translation 29 -48 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry DEF N3 Rectangle { - size 42 16 - } - } - ] - } - Transform2D { - translation 75 -48 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 121 -48 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 167 -48 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 213 -48 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 259 -48 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 305 -48 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 351 -48 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 29 -68 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.75 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 75 -68 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.75 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 121 -68 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.75 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 167 -68 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.75 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 213 -68 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.75 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 259 -68 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.75 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 305 -68 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.75 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 351 -68 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.75 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 29 -88 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 75 -88 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 121 -88 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 167 -88 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 213 -88 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 259 -88 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 305 -88 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 351 -88 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.5 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 29 -108 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.25 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 75 -108 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.25 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 121 -108 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.25 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 167 -108 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.25 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 213 -108 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.25 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 259 -108 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.25 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 305 -108 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.25 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 351 -108 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0.25 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 29 -128 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 75 -128 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 121 -128 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 167 -128 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 213 -128 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 259 -128 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 305 -128 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - Transform2D { - translation 351 -128 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry USE N3 - } - ] - } - ] - } - DEF N4 Transform2D { - translation 209 -270 - children [ - Transform2D { - translation 4 -4 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.7 0.7 0.7 - filled TRUE - } - } - geometry Rectangle { - size 4 8 - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.7 0.7 0.7 - filled TRUE - } - } - geometry Rectangle { - size 8 4 - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 1 - filled TRUE - } - } - geometry Rectangle { - size 4 4 - } - } - ] - } - ] - } - DEF N5 Transform2D { - translation 193 -280 - children [ - Transform2D { - translation 20 -2 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.7 0.7 1 - filled TRUE - } - } - geometry Rectangle { - size 40 4 - } - } - ] - } - ] - } - DEF N6 Switch { - whichChoice 0 - choice [ - Transform2D { - translation 210 -215 - children [ - DEF N7 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 0.5 0.5 - filled TRUE - } - } - geometry Rectangle { - size 100 30 - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Start Game"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] - } - ] - } - DEF N8 Script { - eventIn SFBool startGame - eventIn SFVec3f set_X - eventIn SFTime tickTime - field SFNode timer USE N0 - field SFNode ball USE N4 - field SFNode racket USE N5 - field SFNode starter USE N6 - field SFNode table USE N2 - field SFInt32 loadFLG 0 - field SFInt32 gameFLG 0 - field SFInt32 missFLG 0 - field SFTime tim 0 - field MFColor blcol [1 1 0 1 0.75 0 1 0.5 0 1 0.25 0 1 0 0 0 0 0] - field MFInt32 blsta [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] - field MFInt32 blNO [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] - field SFInt32 blclr 0 - field SFFloat ballX 209 - field SFFloat ballY -270 - field SFInt32 ballN 5 - field SFFloat ballDX 0 - field SFFloat ballDY 0 - field SFFloat tmpRL 193 - url ["javascript: -function startGame(value) { - if (value) { - initG(); - } -} -function tickTime(value) { - mainF(); -} -function mainF() { - ballX+=ballDX; - ballY+=ballDY; - outCHK(); - blkCHK(); - ball.translation.y=ballY; - ball.translation.x=ballX; - racket.translation.x=tmpRL; -} -function initG() { - if (blclr>=40) { - blclr=0; - ballN=3; - for (ib=0;ib<5;ib++){ - for (ia=0;ia<8;ia++){ - chc(ib*8+ia+1,ib); - blsta[ib*8+ia]=ib; - } - } - } - starter.whichChoice=-1; - gameFLG=1; - loadFLG=1; - ballX=209; - ballY=-270; - ballDX=-3; - ballDY=3; - tmpRL=193; - missFLG=0; -} -function set_X(value) { - if (loadFLG==1) { - tmpRL=value.x + 197; - if (tmpRL<21) { - tmpRL=21; - } - if (tmpRL>373) { - tmpRL=373; - } - } -} -function outCHK() { - if (ballX<16) { - ballX=32-ballX; - ballDX=-ballDX; - } - if (ballX>401) { - ballX=802-ballX; - ballDX=-ballDX; - } - if (ballY>-16) { - ballY=-32-ballY; - ballDY=-ballDY; - } - if (ballY<=-272) { - if (missFLG==0) { - tmpX=(ballDX/ballDY)*(-272-ballY)+ballX; - if (tmpX>=tmpRL-12) { - if (tmpX<=tmpRL+42) { - ballY=-272; - ballDY=-ballDY; - ballX=tmpX; - ballRD=tmpX-tmpRL; - ballDX=8*Math.abs(ballDX)/ballDX; - if (ballRD<-4) { - ballDX=-15; - } - if (ballRD>36) { - ballDX=15; - } - if (ballRD>=14) { - if (ballRD<=16) { - ballDX=-2; - } - } - if (ballRD>=17) { - if (ballRD<=20) { - ballDX=2; - } - } - if (ballRD>=0) { - if (ballRD<=4) { - ballDX=-4; - } - } - if (ballRD>=28) { - if (ballRD<=32) { - ballDX=4; - } - } - if (ballRD>=-4) { - if (ballRD<=-1) { - ballDX=-11; - } - } - if (ballRD>=33) { - if (ballRD<=36) { - ballDX=11; - } - } - } - } - if (ballDY<0) { - missFLG=1; - } - } - else { - if (ballY<-290) { - missFLG=0; - ballN=ballN-1; - gameEnd(); - } - } - } -} -function blkCHK() { - tmpY=ballY-4; - tmpY=-tmpY; - tmpX=ballX+4; - if (tmpY>=48) { - if (tmpY<=147) { - if (tmpX>=29) { - if (tmpX<=396) { - ia=Math.floor((tmpX-29)/46); - ib=Math.floor((tmpY-48)/20); - ic=ib*8+ia; - if (blsta[ic]<=4) { - tmpbc=blsta[ic]+1; - blsta[ic]=tmpbc; - chc(ic+1,tmpbc); - if (tmpbc==5) { - blclr=blclr+1; - } - if (blclr>=40) { - gameEnd(); - } - if (ballDX>0) { - iy=(-ballDY/ballDX)*(29+46*ia-tmpX)+tmpY; - if (iy>48+20*ib+18) { - tmpY1=48+20*ib+18; - tmpX1=(ballDX/-ballDY)*(48+20*ib+18-tmpY)+tmpX; - ballX=tmpX1-4; - ballY=-(tmpY1+4); - ballDY=-ballDY; - } - else { - if (iy<44+20*ib) { - tmpY1=48+20*ib; - tmpX1=(ballDX/-ballDY)*(48+20*ib-tmpY)+tmpX; - ballX=tmpX1-4; - ballY=-(tmpY1+4); - ballDY=-ballDY; - } - else { - tmpX1=29+46*ia; - tmpY1=(-ballDY/ballDX)*(29+46*ia-tmpX)+tmpY; - ballX=tmpX1-4; - ballY=-(tmpY1+4); - ballDX=-ballDX; - } - } - } - else { - iy=(-ballDY/ballDX)*(29+46*ia+44-tmpX)+tmpY; - if (iy>48+20*ib+18) { - tmpY1=48+20*ib+18; - tmpX1=(ballDX/-ballDY)*(48+20*ib+18-tmpY)+tmpX; - ballX=tmpX1-4; - ballY=-(tmpY1+4); - ballDY=-ballDY; - } - else { - if (iy<44+20*ib) { - tmpY1=48+20*ib; - tmpX1=(ballDX/-ballDY)*(48+20*ib-tmpY)+tmpX; - ballX=tmpX1-4; - ballY=-(tmpY1+4); - ballDY=-ballDY; - } - else { - tmpX1=29+46*ia+44; - tmpY1=(-ballDY/ballDX)*(29+46*ia+44-tmpX)+tmpY; - ballX=tmpX1-4; - ballY=-(tmpY1+4); - ballDX=-ballDX; - } - } - } - } - } - } - } - } -} -function gameEnd() { - gameFLG=0; - loadFLG=0; - timer.enabled=false; - starter.whichChoice=0; - if (ballN<=0) { - blclr=40; - } -} -function initialize() { - for (ib=0;ib<5;ib++){ - for (ia=0;ia<8;ia++){ - blsta[ib*8+ia]=ib; - } - } -} -function chc(bno,bcl) { - monBlock=table.children[bno-1].children[0].appearance.material; - monBlock.emissiveColor=blcol[bcl]; -} - -" - ] - } - DEF N9 Conditional { - buffer { - REPLACE N0.enabled BY TRUE - } - } - ] -} - -ROUTE N7.isActive TO N8.startGame -ROUTE N7.isActive TO N9.activate -ROUTE N0.cycleTime TO N8.tickTime -ROUTE N1.hitPoint_changed TO N8.set_X - diff --git a/regression_tests/bifs-game-bubble.bt b/regression_tests/bifs-game-bubble.bt deleted file mode 100644 index 05f6786..0000000 --- a/regression_tests/bifs-game-bubble.bt +++ /dev/null @@ -1,433 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - useNames true - } - } - } - ] -} - -PROTO Bubble [ - exposedField SFInt32 index 0 - exposedField SFInt32 state 0 - exposedField SFInt32 display 0 - exposedField SFVec2f position 0 0 - - exposedField SFFloat size 9 - exposedField SFColor color 0 0 0 - exposedField SFFloat red 0 - exposedField SFFloat green 0 - exposedField SFFloat blue 0 - - exposedField SFFloat strokeWidth 2 - exposedField SFFloat strokeTransparency 0.3 - exposedField SFBool alignStroke FALSE - - eventOut SFInt32 isOver - eventOut SFInt32 isActive -] { - Switch { - whichChoice IS display - choice [ - Transform2D { - translation IS position - children [ - ColorTransform { - mrr 0.7 - mgg 0.5 - mbb 0.9 - maa 0.6 - ta 0.274 - tr IS red - tg IS green - tb IS blue - children [ - Shape { - geometry DEF C Circle { radius IS size } - appearance Appearance { - material Material2D { - filled TRUE - } - texture RadialGradient { - center 0.5 0.5 - focalPoint 0.5 0.5 - key [ 0 1 ] - keyValue [ 1 1 1 0 0 0 ] - } - } - } - ] - } - Shape { - geometry USE C - appearance Appearance { - material Material2D { - filled FALSE - lineProps XLineProperties { - width 2 - lineColor 0.2 0.2 0.2 - transparency IS strokeTransparency - isCenterAligned IS alignStroke - } - } - } - } - DEF TS TouchSensor {} - DEF Vindex Valuator { - inSFInt32 IS index - } - DEF VOver Valuator { - outSFInt32 IS isOver - } - DEF VActive Valuator { - outSFInt32 IS isActive - } - ] - } - ] - } - ROUTE Vindex.outSFFloat TO VOver.Factor1 - ROUTE Vindex.outSFFloat TO VActive.Factor1 - ROUTE TS.isOver TO VOver.inSFBool - ROUTE TS.isActive TO VActive.inSFBool -} -OrderedGroup { - children [ - WorldInfo { - title "Classic Bubble Game" - info [ - "This test shows the classic bubble game." - "It features:" - " - a PROTO which defines a single Bubble node. This node takes as input the index of the bubble in the bubbleGrid. The bubble outputs this index on separate events: one when the mouse enters the bubble and one when a click on the bubble happens. This PROTO does not use any scripting for that." - " - a Script node which handles the initialization (colors, size, index) and dynamic positionning of the bubbles. It is also responsible for the game logic." - "The number of of lines and columns in the bubble grid can be easily modified in the Script node." - "" - "GPAC Regression Tests" "$Date: 2008/11/24 14:58:25 $ - $Revision: 1.6 $" - "(C) 2002-2006 GPAC Team" - ] - } - DEF VIEWPORT Viewport { - size 410 300 - fit 1 - } - Background2D { backColor 1 1 1 } - DEF CANVAS_TRANSFORM Transform2D { - children [ - Shape { - geometry DEF CANVAS Rectangle { size 0 0 } - appearance Appearance { - material Material2D { - filled TRUE - emissiveColor 1 1 1 - lineProps XLineProperties { - width 2 - isScalable FALSE - lineColor 0 0 0 - } - } - } - } - DEF BUBBLE_ROOT Transform2D {} - ] - } - DEF TEXT_TRANSFORM Transform2D { - children [ - Shape { - geometry DEF SCORE_TEXT Text { - fontStyle FontStyle { - size 20 - family "SANS" - justify [ "BEGIN" "FIRST" ] - } - } - appearance Appearance { - material Material2D { - filled TRUE - emissiveColor 0 0 0 - } - } - } - ] - } - DEF Vover Valuator {} - DEF Vclick Valuator {} - DEF BUBBLE_SCRIPT Script { - field SFNode score_text USE SCORE_TEXT - field SFNode bubble_root USE BUBBLE_ROOT - - field SFNode canvas USE CANVAS - field SFNode canvas_pos USE CANVAS_TRANSFORM - field SFNode viewport USE VIEWPORT - field SFNode trans_text USE TEXT_TRANSFORM - - field SFNode val_over USE Vover - field SFNode val_click USE Vclick - - eventIn SFInt32 bubbleOnClick - eventIn SFInt32 bubbleMouseOver - - url [ "javascript: - function initialize() { - bubbleGrid = new Array(); - nbLines = 15; - nbCols = 26; - bubble_radius = 9; - score = 0; - neutral_state = 0; - selected_state = 1; - exploded_state = 2; - empty_state = 4; - - for (i=0; i<nbLines; i++) { - for (j=0; j<nbCols; j++) { - bubbleGrid[i*nbCols+j] = new bubble(bubble_root, i, j); -// print('index: '+(i*nbCols+j)); - } - } - - gridWidth = nbCols*(bubble_radius+1)*2; - gridHeight = nbLines*(bubble_radius+1)*2; - - viewport.size = new SFVec2f(gridWidth, gridHeight+50); - canvas.size = new SFVec2f(gridWidth, gridHeight); - canvas_pos.translation = new SFVec2f(0, 50/2-2); - - score_text.string[0] = 'Score: 0'; - bubble_root.scale = new SFVec2f(1, -1); - bubble_root.translation = new SFVec2f(-gridWidth/2 + 10, gridHeight/2-10); - trans_text.translation = new SFVec2f(-gridWidth/2 + 10, -(gridHeight+50)/2+10); - } - - function set_neutral(bubble) { - bubble.state = neutral_state; - bubble.alignStroke = FALSE; - bubble.strokeWidth = 2; - bubble.strokeTransparency = 0.7; - } - - function set_selected(bubble) { - bubble.state = selected_state; - bubble.alignStroke = TRUE; - bubble.strokeWidth = 3; - bubble.strokeTransparency = 0.3; - } - - function set_empty(bubble) { - bubble.state = empty_state; - bubble.display = -1; - } - - function set_exploded(bubble) { - bubble.display = -1; - bubble.state = exploded_state; - bubble.alignStroke = FALSE; - bubble.strokeWidth = 2; - bubble.strokeTransparency = 0.3; - } - - function set_visible(bubble) { - bubble.display = 0; - } - - function bubble(parent, line, column) { - var bubble; - bubble = new SFNode('_Proto1'); - bubble.position = new SFVec2f(2*column*(bubble_radius+1), 2*line*(bubble_radius+1)); - bubble.index = line*nbCols+column + 1; //1-based index - bubble.size = bubble_radius; - set_neutral(bubble); - bubble.red = 170/255.0; - bubble.green = Math.round(Math.random()*1)*150/255.0; - bubble.blue = Math.round(Math.random()*1)*255/255.0; - bubble.color = new SFColor(bubble.red, bubble.green, bubble.blue); -// print('Color: red '+ bubble.red + ' green ' + bubble.green + ' blue '+bubble.blue); - parent.children[parent.children.length] = bubble; - Browser.addRoute(bubble, 'isOver', val_over, 'inSFInt32'); - Browser.addRoute(bubble, 'isActive', val_click, 'inSFInt32'); - return bubble; - } - - function bubbleMouseOver(value) { - if (!value) return; - value--; - if (bubbleGrid[value].state == neutral_state) { - for (i=0; i<nbLines; i++) { - for (j=0; j<nbCols; j++) { - if (bubbleGrid[i*nbCols+j].state != empty_state) { - set_neutral(bubbleGrid[i*nbCols+j]); - } - } - } - line = Math.floor(value / nbCols); - column = value % nbCols; -// print('MouseOver l: '+line+' c: '+column); - if (propagate(line, column, bubbleGrid[line*nbCols+column].color)==1) { - set_neutral(bubbleGrid[line*nbCols+column]); - } - } - } - - function bubbleOnClick(value) { - if (!value) return; - value--; - if (bubbleGrid[value].state == selected_state) { - line = Math.floor(value / nbCols); - column = value % nbCols; - explode(line, column, bubbleGrid[value].color); - gravity(); - connexity(); - } - } - - function isColorEqual(c1, c2) { - if (c1.r != c2.r) return 0; - if (c1.g != c2.g) return 0; - if (c1.b != c2.b) return 0; - return 1; - } - - function propagate(line, column, color) { - var colmin, colmax, curcol, k, res; -// print('propagate l: '+line+' c: '+column); - if ( isColorEqual(bubbleGrid[line*nbCols+column].color, color) && - (bubbleGrid[line*nbCols+column].state == neutral_state)) { - res = 1; - set_selected(bubbleGrid[line*nbCols+column]); - - //before the bubble on the same line - curcol = column-1; - while ( (curcol>=0) && - isColorEqual(bubbleGrid[line*nbCols+curcol].color,color) && - (bubbleGrid[line*nbCols+curcol].state == neutral_state)) { -// print('propagate before l: '+line+' c: '+curcol); - set_selected(bubbleGrid[line*nbCols+curcol]); - curcol--; - res++; - } - - //after the bubble on the same line - colmin = ++curcol; - curcol = column+1; - while ( (curcol<nbCols) && - isColorEqual(bubbleGrid[line*nbCols+curcol].color, color) && - (bubbleGrid[line*nbCols+curcol].state == neutral_state)) { -// print('propagate after l: '+line+' c: '+curcol); - set_selected(bubbleGrid[line*nbCols+curcol]); - curcol++; - res++; - } - - colmax = --curcol; - for (k=colmin; k<=colmax; k++) { - if (line>0) { - if (isColorEqual(bubbleGrid[(line-1)*nbCols+k].color, color)&& - (bubbleGrid[(line-1)*nbCols+k].state == neutral_state)) - res = res + propagate(line-1, k, color); - } - if (line<nbLines-1) { - if (isColorEqual(bubbleGrid[(line+1)*nbCols+k].color, color)&& - (bubbleGrid[(line+1)*nbCols+k].state == neutral_state)) - res = res + propagate(line+1, k, color); - } - } - return res; - } else { - return 0; - } - } - - function explode(line, column, color) { -// print('explode l: '+line+' c: '+column); - if (isColorEqual(bubbleGrid[line*nbCols+column].color, color) && - (bubbleGrid[line*nbCols+column].state == selected_state)) { - set_exploded(bubbleGrid[line*nbCols+column]); - if (line>0) explode(line-1, column, color); - if (column>0) explode(line, column-1, color); - if (column<nbCols-1) explode(line, column+1, color); - if (line<nbLines-1) explode(line+1, column, color); - } - } - - function gravity() { - exploded = 0; - for (j=0; j<nbCols; j++) { - for (i=0; i<nbLines; i++) { - if (bubbleGrid[i*nbCols+j].state == exploded_state) { - start = end = i; - while ((end<nbLines)&&(bubbleGrid[end*nbCols+j].state == exploded_state)) { - // ???? - set_visible(bubbleGrid[end*nbCols+j]); - end++; - } - lg = end-start; - exploded +=lg; - for (k=end-1; k>=0; k--) { - if (k-lg>=0) { - if (bubbleGrid[(k-lg)*nbCols+j].state != empty_state) { - movebubble(k-lg, j, k, j); - } else { - set_empty(bubbleGrid[k*nbCols+j]); - } - } else { - set_empty(bubbleGrid[k*nbCols+j]); - } - } - } - } - } - score += exploded * exploded; - score_text.string[0] = 'Score: '+score; - } - - function movebubble(lsrc, csrc, ldst, cdst) { -// print('Move src l: '+lsrc+' c: '+csrc); -// print('Move dst l: '+ldst+' c: '+cdst); - // move a bubble from the (lsrc, csrc) position to the (ldst, cdst) position - // and let the src empty - bubbleGrid[ldst*nbCols+cdst].color = bubbleGrid[lsrc*nbCols+csrc].color; - bubbleGrid[ldst*nbCols+cdst].red = bubbleGrid[lsrc*nbCols+csrc].red; - bubbleGrid[ldst*nbCols+cdst].green = bubbleGrid[lsrc*nbCols+csrc].green; - bubbleGrid[ldst*nbCols+cdst].blue = bubbleGrid[lsrc*nbCols+csrc].blue; - bubbleGrid[ldst*nbCols+cdst].state = bubbleGrid[lsrc*nbCols+csrc].state; - if (bubbleGrid[ldst*nbCols+cdst].state != empty_state) - set_visible(bubbleGrid[ldst*nbCols+cdst]); - set_empty(bubbleGrid[lsrc*nbCols+csrc]); - } - - function movecolumn(colnumber, delta) { - for (i=0; i<nbLines; i++) movebubble(i, colnumber,i, colnumber+delta); - } - - function connexity() { - // if there is a hole in the last line, the whole column is free and must be suppressed - for (j=0; j<nbCols; j++) { - if (bubbleGrid[(nbLines-1)*nbCols+j].state == empty_state) { - if (j<nbCols/2) { - for (k=j-1; k>=0; k--) movecolumn(k, +1); - } else { - for (k=j+1; k<nbCols; k++) movecolumn(k, -1); - } - } - } - } - - "] - } - ] -} -ROUTE Vover.outSFInt32 TO BUBBLE_SCRIPT.bubbleMouseOver -ROUTE Vclick.outSFInt32 TO BUBBLE_SCRIPT.bubbleOnClick diff --git a/regression_tests/bifs-game-minesweeper.bt b/regression_tests/bifs-game-minesweeper.bt deleted file mode 100644 index 6dc1684..0000000 --- a/regression_tests/bifs-game-minesweeper.bt +++ /dev/null @@ -1,1538 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - objectTypeIndication 2 - streamType 3 - bufferSizeDB 50000 - decSpecificInfo BIFSv2Config { - nodeIDbits 10 - routeIDbits 10 - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - slConfigDescr SLConfigDescriptor { - useAccessUnitStartFlag true - useAccessUnitEndFlag true - useTimeStampsFlag true - timeStampResolution 1000 - timeStampLength 32 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This game was translated from" - "the site http://javascript.internet.com'" - "Written and designed by Peter Occil (poccil@yahoo.com)" - "Translated and adapted by " - "Cyril Concolato (cyril.concolato@enst.fr), June 2003" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" -] - title "Winmine using MPEG-4 BIFS and Javascript" - } - Transform2D { - translation 0 175 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["MineSweeper using" "MPEG-4 BIFS and Javascript"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - style "BOLD" - } - } - } - ] - } - Transform2D { - scale 1.5 1.5 - children [ - DEF N0 TimeSensor { - enabled FALSE - loop TRUE - } - Switch { - choice [ - DEF N1 Transform2D { - children [ - DEF N2 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.3 0.3 0.3 - filled TRUE - } - } - geometry DEF N3 Rectangle { - size 16 16 - } - } - ] - } - DEF N4 Transform2D { - children [ - USE N2 - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 4 4 - } - } - ] - } - DEF N5 Transform2D { - children [ - USE N2 - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Text { - string ["?"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 10 - } - } - } - ] - } - DEF N6 Transform2D { - children [ - USE N2 - DEF N7 Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.4 0.4 0.4 - filled TRUE - } - } - geometry Rectangle { - size 15 15 - } - } - Shape { - appearance DEF N9 Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Text { - string [""] - fontStyle DEF N8 FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 15 - } - } - } - ] - } - DEF N10 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance USE N9 - geometry Text { - string ["1"] - fontStyle USE N8 - } - } - ] - } - DEF N11 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance USE N9 - geometry Text { - string ["2"] - fontStyle USE N8 - } - } - ] - } - DEF N12 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance USE N9 - geometry Text { - string ["3"] - fontStyle USE N8 - } - } - ] - } - DEF N13 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance USE N9 - geometry Text { - string ["4"] - fontStyle USE N8 - } - } - ] - } - DEF N14 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance USE N9 - geometry Text { - string ["5"] - fontStyle USE N8 - } - } - ] - } - DEF N15 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance USE N9 - geometry Text { - string ["6"] - fontStyle USE N8 - } - } - ] - } - DEF N16 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance USE N9 - geometry Text { - string ["7"] - fontStyle USE N8 - } - } - ] - } - DEF N17 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance USE N9 - geometry Text { - string ["8"] - fontStyle USE N8 - } - } - ] - } - DEF N18 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Circle { - radius 6 - } - } - ] - } - DEF N19 Transform2D { - children [ - USE N2 - USE N7 - ] - } - DEF N20 Transform2D { - children [ - USE N2 - USE N7 - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Text { - string ["x"] - fontStyle USE N8 - } - } - ] - } - DEF N21 Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 1 - filled TRUE - } - } - geometry Circle { - radius 10 - } - } - ] - } - DEF N22 Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - } - geometry Circle { - radius 10 - } - } - ] - } - ] - } - Transform2D { - translation -40 80 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Rectangle { - size 35 21 - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry DEF N23 Text { - string ["010"] - fontStyle USE N8 - } - } - ] - } - DEF N24 Transform2D { - translation 0 80 - children [ - DEF N25 TouchSensor {} - USE N22 - ] - } - Transform2D { - translation 40 80 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Rectangle { - size 35 21 - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry DEF N26 Text { - string ["000"] - fontStyle USE N8 - } - } - ] - } - DEF N27 Form { - size 128 128 - groups [1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 7 -1 8 -1 9 -1 10 -1 11 -1 12 -1 13 -1 14 -1 15 -1 16 -1 17 -1 18 -1 19 -1 20 -1 21 -1 22 -1 23 -1 24 -1 25 -1 26 -1 27 -1 28 -1 29 -1 30 -1 31 -1 32 -1 33 -1 34 -1 35 -1 36 -1 37 -1 38 -1 39 -1 40 -1 41 -1 42 -1 43 -1 44 -1 45 -1 46 -1 47 -1 48 -1 49 -1 50 -1 51 -1 52 -1 53 -1 54 -1 55 -1 56 -1 57 -1 58 -1 59 -1 60 -1 61 -1 62 -1 63 -1 64 -1 1 2 3 4 5 6 7 8 -1 9 10 11 12 13 14 15 16 -1 17 18 19 20 21 22 23 24 -1 25 26 27 28 29 30 31 32 -1 33 34 35 36 37 38 39 40 -1 41 42 43 44 45 46 47 48 -1 49 50 51 52 53 54 55 56 -1 57 58 59 60 61 62 63 64 -1] - constraints ["SHin" "SHin" "SHin" "SHin" "SHin" "SHin" "SHin" "SHin" "SVin"] - groupsIndex [1 2 3 4 5 6 7 8 -1 9 10 11 12 13 14 15 16 -1 17 18 19 20 21 22 23 24 -1 25 26 27 28 29 30 31 32 -1 33 34 35 36 37 38 39 40 -1 41 42 43 44 45 46 47 48 -1 49 50 51 52 53 54 55 56 -1 57 58 59 60 61 62 63 64 -1 65 66 67 68 69 70 71 72 -1] - children [ - Transform2D { - children [ - DEF N28 TouchSensor {} - USE N1 - DEF N29 Valuator {} - DEF N30 Conditional { - buffer { - REPLACE N29.inSFVec2f BY 0 0 - } - } - ] - } - Transform2D { - children [ - DEF N31 TouchSensor {} - USE N1 - DEF N32 Valuator {} - DEF N33 Conditional { - buffer { - REPLACE N32.inSFVec2f BY 0 1 - } - } - ] - } - Transform2D { - children [ - DEF N34 TouchSensor {} - USE N1 - DEF N35 Valuator {} - DEF N36 Conditional { - buffer { - REPLACE N35.inSFVec2f BY 0 2 - } - } - ] - } - Transform2D { - children [ - DEF N37 TouchSensor {} - USE N1 - DEF N38 Valuator {} - DEF N39 Conditional { - buffer { - REPLACE N38.inSFVec2f BY 0 3 - } - } - ] - } - Transform2D { - children [ - DEF N40 TouchSensor {} - USE N1 - DEF N41 Valuator {} - DEF N42 Conditional { - buffer { - REPLACE N41.inSFVec2f BY 0 4 - } - } - ] - } - Transform2D { - children [ - DEF N43 TouchSensor {} - USE N1 - DEF N44 Valuator {} - DEF N45 Conditional { - buffer { - REPLACE N44.inSFVec2f BY 0 5 - } - } - ] - } - Transform2D { - children [ - DEF N46 TouchSensor {} - USE N1 - DEF N47 Valuator {} - DEF N48 Conditional { - buffer { - REPLACE N47.inSFVec2f BY 0 6 - } - } - ] - } - Transform2D { - children [ - DEF N49 TouchSensor {} - USE N1 - DEF N50 Valuator {} - DEF N51 Conditional { - buffer { - REPLACE N50.inSFVec2f BY 0 7 - } - } - ] - } - Transform2D { - children [ - DEF N52 TouchSensor {} - USE N1 - DEF N53 Valuator {} - DEF N54 Conditional { - buffer { - REPLACE N53.inSFVec2f BY 1 0 - } - } - ] - } - Transform2D { - children [ - DEF N55 TouchSensor {} - USE N1 - DEF N56 Valuator {} - DEF N57 Conditional { - buffer { - REPLACE N56.inSFVec2f BY 1 1 - } - } - ] - } - Transform2D { - children [ - DEF N58 TouchSensor {} - USE N1 - DEF N59 Valuator {} - DEF N60 Conditional { - buffer { - REPLACE N59.inSFVec2f BY 1 2 - } - } - ] - } - Transform2D { - children [ - DEF N61 TouchSensor {} - USE N1 - DEF N62 Valuator {} - DEF N63 Conditional { - buffer { - REPLACE N62.inSFVec2f BY 1 3 - } - } - ] - } - Transform2D { - children [ - DEF N64 TouchSensor {} - USE N1 - DEF N65 Valuator {} - DEF N66 Conditional { - buffer { - REPLACE N65.inSFVec2f BY 1 4 - } - } - ] - } - Transform2D { - children [ - DEF N67 TouchSensor {} - USE N1 - DEF N68 Valuator {} - DEF N69 Conditional { - buffer { - REPLACE N68.inSFVec2f BY 1 5 - } - } - ] - } - Transform2D { - children [ - DEF N70 TouchSensor {} - USE N1 - DEF N71 Valuator {} - DEF N72 Conditional { - buffer { - REPLACE N71.inSFVec2f BY 1 6 - } - } - ] - } - Transform2D { - children [ - DEF N73 TouchSensor {} - USE N1 - DEF N74 Valuator {} - DEF N75 Conditional { - buffer { - REPLACE N74.inSFVec2f BY 1 7 - } - } - ] - } - Transform2D { - children [ - DEF N76 TouchSensor {} - USE N1 - DEF N77 Valuator {} - DEF N78 Conditional { - buffer { - REPLACE N77.inSFVec2f BY 2 0 - } - } - ] - } - Transform2D { - children [ - DEF N79 TouchSensor {} - USE N1 - DEF N80 Valuator {} - DEF N81 Conditional { - buffer { - REPLACE N80.inSFVec2f BY 2 1 - } - } - ] - } - Transform2D { - children [ - DEF N82 TouchSensor {} - USE N1 - DEF N83 Valuator {} - DEF N84 Conditional { - buffer { - REPLACE N83.inSFVec2f BY 2 2 - } - } - ] - } - Transform2D { - children [ - DEF N85 TouchSensor {} - USE N1 - DEF N86 Valuator {} - DEF N87 Conditional { - buffer { - REPLACE N86.inSFVec2f BY 2 3 - } - } - ] - } - Transform2D { - children [ - DEF N88 TouchSensor {} - USE N1 - DEF N89 Valuator {} - DEF N90 Conditional { - buffer { - REPLACE N89.inSFVec2f BY 2 4 - } - } - ] - } - Transform2D { - children [ - DEF N91 TouchSensor {} - USE N1 - DEF N92 Valuator {} - DEF N93 Conditional { - buffer { - REPLACE N92.inSFVec2f BY 2 5 - } - } - ] - } - Transform2D { - children [ - DEF N94 TouchSensor {} - USE N1 - DEF N95 Valuator {} - DEF N96 Conditional { - buffer { - REPLACE N95.inSFVec2f BY 2 6 - } - } - ] - } - Transform2D { - children [ - DEF N97 TouchSensor {} - USE N1 - DEF N98 Valuator {} - DEF N99 Conditional { - buffer { - REPLACE N98.inSFVec2f BY 2 7 - } - } - ] - } - Transform2D { - children [ - DEF N100 TouchSensor {} - USE N1 - DEF N101 Valuator {} - DEF N102 Conditional { - buffer { - REPLACE N101.inSFVec2f BY 3 0 - } - } - ] - } - Transform2D { - children [ - DEF N103 TouchSensor {} - USE N1 - DEF N104 Valuator {} - DEF N105 Conditional { - buffer { - REPLACE N104.inSFVec2f BY 3 1 - } - } - ] - } - Transform2D { - children [ - DEF N106 TouchSensor {} - USE N1 - DEF N107 Valuator {} - DEF N108 Conditional { - buffer { - REPLACE N107.inSFVec2f BY 3 2 - } - } - ] - } - Transform2D { - children [ - DEF N109 TouchSensor {} - USE N1 - DEF N110 Valuator {} - DEF N111 Conditional { - buffer { - REPLACE N110.inSFVec2f BY 3 3 - } - } - ] - } - Transform2D { - children [ - DEF N112 TouchSensor {} - USE N1 - DEF N113 Valuator {} - DEF N114 Conditional { - buffer { - REPLACE N113.inSFVec2f BY 3 4 - } - } - ] - } - Transform2D { - children [ - DEF N115 TouchSensor {} - USE N1 - DEF N116 Valuator {} - DEF N117 Conditional { - buffer { - REPLACE N116.inSFVec2f BY 3 5 - } - } - ] - } - Transform2D { - children [ - DEF N118 TouchSensor {} - USE N1 - DEF N119 Valuator {} - DEF N120 Conditional { - buffer { - REPLACE N119.inSFVec2f BY 3 6 - } - } - ] - } - Transform2D { - children [ - DEF N121 TouchSensor {} - USE N1 - DEF N122 Valuator {} - DEF N123 Conditional { - buffer { - REPLACE N122.inSFVec2f BY 3 7 - } - } - ] - } - Transform2D { - children [ - DEF N124 TouchSensor {} - USE N1 - DEF N125 Valuator {} - DEF N126 Conditional { - buffer { - REPLACE N125.inSFVec2f BY 4 0 - } - } - ] - } - Transform2D { - children [ - DEF N127 TouchSensor {} - USE N1 - DEF N128 Valuator {} - DEF N129 Conditional { - buffer { - REPLACE N128.inSFVec2f BY 4 1 - } - } - ] - } - Transform2D { - children [ - DEF N130 TouchSensor {} - USE N1 - DEF N131 Valuator {} - DEF N132 Conditional { - buffer { - REPLACE N131.inSFVec2f BY 4 2 - } - } - ] - } - Transform2D { - children [ - DEF N133 TouchSensor {} - USE N1 - DEF N134 Valuator {} - DEF N135 Conditional { - buffer { - REPLACE N134.inSFVec2f BY 4 3 - } - } - ] - } - Transform2D { - children [ - DEF N136 TouchSensor {} - USE N1 - DEF N137 Valuator {} - DEF N138 Conditional { - buffer { - REPLACE N137.inSFVec2f BY 4 4 - } - } - ] - } - Transform2D { - children [ - DEF N139 TouchSensor {} - USE N1 - DEF N140 Valuator {} - DEF N141 Conditional { - buffer { - REPLACE N140.inSFVec2f BY 4 5 - } - } - ] - } - Transform2D { - children [ - DEF N142 TouchSensor {} - USE N1 - DEF N143 Valuator {} - DEF N144 Conditional { - buffer { - REPLACE N143.inSFVec2f BY 4 6 - } - } - ] - } - Transform2D { - children [ - DEF N145 TouchSensor {} - USE N1 - DEF N146 Valuator {} - DEF N147 Conditional { - buffer { - REPLACE N146.inSFVec2f BY 4 7 - } - } - ] - } - Transform2D { - children [ - DEF N148 TouchSensor {} - USE N1 - DEF N149 Valuator {} - DEF N150 Conditional { - buffer { - REPLACE N149.inSFVec2f BY 5 0 - } - } - ] - } - Transform2D { - children [ - DEF N151 TouchSensor {} - USE N1 - DEF N152 Valuator {} - DEF N153 Conditional { - buffer { - REPLACE N152.inSFVec2f BY 5 1 - } - } - ] - } - Transform2D { - children [ - DEF N154 TouchSensor {} - USE N1 - DEF N155 Valuator {} - DEF N156 Conditional { - buffer { - REPLACE N155.inSFVec2f BY 5 2 - } - } - ] - } - Transform2D { - children [ - DEF N157 TouchSensor {} - USE N1 - DEF N158 Valuator {} - DEF N159 Conditional { - buffer { - REPLACE N158.inSFVec2f BY 5 3 - } - } - ] - } - Transform2D { - children [ - DEF N160 TouchSensor {} - USE N1 - DEF N161 Valuator {} - DEF N162 Conditional { - buffer { - REPLACE N161.inSFVec2f BY 5 4 - } - } - ] - } - Transform2D { - children [ - DEF N163 TouchSensor {} - USE N1 - DEF N164 Valuator {} - DEF N165 Conditional { - buffer { - REPLACE N164.inSFVec2f BY 5 5 - } - } - ] - } - Transform2D { - children [ - DEF N166 TouchSensor {} - USE N1 - DEF N167 Valuator {} - DEF N168 Conditional { - buffer { - REPLACE N167.inSFVec2f BY 5 6 - } - } - ] - } - Transform2D { - children [ - DEF N169 TouchSensor {} - USE N1 - DEF N170 Valuator {} - DEF N171 Conditional { - buffer { - REPLACE N170.inSFVec2f BY 5 7 - } - } - ] - } - Transform2D { - children [ - DEF N172 TouchSensor {} - USE N1 - DEF N173 Valuator {} - DEF N174 Conditional { - buffer { - REPLACE N173.inSFVec2f BY 6 0 - } - } - ] - } - Transform2D { - children [ - DEF N175 TouchSensor {} - USE N1 - DEF N176 Valuator {} - DEF N177 Conditional { - buffer { - REPLACE N176.inSFVec2f BY 6 1 - } - } - ] - } - Transform2D { - children [ - DEF N178 TouchSensor {} - USE N1 - DEF N179 Valuator {} - DEF N180 Conditional { - buffer { - REPLACE N179.inSFVec2f BY 6 2 - } - } - ] - } - Transform2D { - children [ - DEF N181 TouchSensor {} - USE N1 - DEF N182 Valuator {} - DEF N183 Conditional { - buffer { - REPLACE N182.inSFVec2f BY 6 3 - } - } - ] - } - Transform2D { - children [ - DEF N184 TouchSensor {} - USE N1 - DEF N185 Valuator {} - DEF N186 Conditional { - buffer { - REPLACE N185.inSFVec2f BY 6 4 - } - } - ] - } - Transform2D { - children [ - DEF N187 TouchSensor {} - USE N1 - DEF N188 Valuator {} - DEF N189 Conditional { - buffer { - REPLACE N188.inSFVec2f BY 6 5 - } - } - ] - } - Transform2D { - children [ - DEF N190 TouchSensor {} - USE N1 - DEF N191 Valuator {} - DEF N192 Conditional { - buffer { - REPLACE N191.inSFVec2f BY 6 6 - } - } - ] - } - Transform2D { - children [ - DEF N193 TouchSensor {} - USE N1 - DEF N194 Valuator {} - DEF N195 Conditional { - buffer { - REPLACE N194.inSFVec2f BY 6 7 - } - } - ] - } - Transform2D { - children [ - DEF N196 TouchSensor {} - USE N1 - DEF N197 Valuator {} - DEF N198 Conditional { - buffer { - REPLACE N197.inSFVec2f BY 7 0 - } - } - ] - } - Transform2D { - children [ - DEF N199 TouchSensor {} - USE N1 - DEF N200 Valuator {} - DEF N201 Conditional { - buffer { - REPLACE N200.inSFVec2f BY 7 1 - } - } - ] - } - Transform2D { - children [ - DEF N202 TouchSensor {} - USE N1 - DEF N203 Valuator {} - DEF N204 Conditional { - buffer { - REPLACE N203.inSFVec2f BY 7 2 - } - } - ] - } - Transform2D { - children [ - DEF N205 TouchSensor {} - USE N1 - DEF N206 Valuator {} - DEF N207 Conditional { - buffer { - REPLACE N206.inSFVec2f BY 7 3 - } - } - ] - } - Transform2D { - children [ - DEF N208 TouchSensor {} - USE N1 - DEF N209 Valuator {} - DEF N210 Conditional { - buffer { - REPLACE N209.inSFVec2f BY 7 4 - } - } - ] - } - Transform2D { - children [ - DEF N211 TouchSensor {} - USE N1 - DEF N212 Valuator {} - DEF N213 Conditional { - buffer { - REPLACE N212.inSFVec2f BY 7 5 - } - } - ] - } - Transform2D { - children [ - DEF N214 TouchSensor {} - USE N1 - DEF N215 Valuator {} - DEF N216 Conditional { - buffer { - REPLACE N215.inSFVec2f BY 7 6 - } - } - ] - } - Transform2D { - children [ - DEF N217 TouchSensor {} - USE N1 - DEF N218 Valuator {} - DEF N219 Conditional { - buffer { - REPLACE N218.inSFVec2f BY 7 7 - } - } - ] - } - ] - } - ] - } - DEF N220 Script { - eventIn SFTime timeOut - eventIn SFBool startGame - eventIn SFVec2f click - eventIn SFInt32 keyPressed - eventIn SFInt32 keyReleased - field SFNode timer USE N0 - field MFNode sqtimages [ - USE N1 - USE N4 - USE N5 - ] - field MFNode sqimages [ - USE N6 - USE N10 - USE N11 - USE N12 - USE N13 - USE N14 - USE N15 - USE N16 - USE N17 - ] - field SFNode mineImage USE N18 - field SFNode noMineImage USE N20 - field SFNode mineredImage USE N19 - field SFNode flagsNode USE N23 - field SFNode conditionNode USE N24 - field SFNode elapsedNode USE N26 - field SFNode board USE N27 - field SFNode btndead USE N21 - field SFNode btncool USE N22 - url ["javascript: -function initialize() { - gridx=8; - gridy=8; - mines=new Array(gridx) ; - shown=new Array(gridy) ; - maxmines=10; - squaresleft=0; - flagsleft=0; - elapsedtime=0; - playing=0; - placeflag=0; - clicked=0; - gridSq=gridx*16; - grid8=gridSq-128; - grid16=gridx-8; - grid32=grid16*8; - grid64=grid16*16; - topBarWidth=8+grid64; - menuBarWidth=86+grid64; - wideWidth=gridx*16; - highHeight=gridy*16; - cplLeft=6+grid32; - cplRight=4+grid32; - totalWidth=gridSq+32; - tW6=totalWidth-6; - ww2=wideWidth+2; - newgame(0); -} -function keyPressed(value) { - print('keyPressed:'+value); - if (value) { - placeflag=true; - setStatus(); - } -} -function keyReleased(value) { - print('keyReleased'+value); - if (value) { - placeflag=false; - setStatus(); - } -} -function startGame(value,timestamp) { - if (value) { - newgame(timestamp); - } -} -function newgame(timestamp) { - for (y=0;y<gridy;++y){ - mines[y]=new Array(gridx) ; - shown[y]=new Array(gridx) ; - for (x=0;x<gridx;x++){ - mines[y][x]=false; - shown[y][x]=0; - board.children[x*gridx+y].children[1]=sqtimages[0]; - } - } - conditionNode.children[1]=btncool; - for (m=0;m<maxmines;++m){ - x=Math.floor(Math.random()*gridx); - y=Math.floor(Math.random()*gridy); - while (mines[y][x]){ - x=Math.floor(Math.random()*gridx); - y=Math.floor(Math.random()*gridy); - } - mines[y][x]=true; - } - squaresleft=gridy*gridx; - flagsleft=maxmines; - elapsedtime=0; - playing=true; - clicked=false; - placeflag=false; - timer.startTime=timestamp; - timer.enabled=true; -} -function timeOut(value,timestamp) { - ticker(); -} -function ticker() { - if (playing) { - if (clicked) { - elapsedtime++; - setStatus(); - } - } -} -function setStatus() { - elapsedNode.string[0]=''+elapsedtime; - flagsNode.string[0]=''+flagsleft; -} -function surrounding(y,x) { - count=0; - if (y>0&&x>0&&mines[y-1][x-1]) count++; - if (y>0&&mines[y-1][x]) count++; - if (y>0&&x<gridx-1&&mines[y-1][x+1]) count++; - if (x>0&&mines[y][x-1]) count++; - if (x<gridx-1&&mines[y][x+1]) count++; - if (y<gridy-1&&x>0&&mines[y+1][x-1]) count++; - if (y<gridy-1&&mines[y+1][x]) count++; - if (y<gridy-1&&x<gridx-1&&mines[y+1][x+1]) count++; - return count; - -} -function rollback(y,x) { - if (y>=0&&y<gridy&&x>=0&&x<gridx) { - if (shown[y][x]!=3) { - c=surrounding(y,x); - shown[y][x]=3; - squaresleft--; - board.children[x*gridx+y].children[1]=sqimages[c]; - if (c==0) { - rollback(y-1,x-1); - rollback(y-1,x); - rollback(y-1,x+1); - rollback(y,x-1); - rollback(y,x+1); - rollback(y+1,x-1); - rollback(y+1,x); - rollback(y+1,x+1); - } - } - } -} -function dead() { - for (y=0;y<gridy;++y){ - for (x=0;x<gridx;++x){ - if (mines[y][x]) { - if (shown[y][x]!=1) { - board.children[x*gridx+y].children[1]=mineImage; - } - } - else if (shown[y][x]==1) { - board.children[x*gridx+y].children[1]=noMineImage; - } - } - } - conditionNode.children[1]=btndead; - playing=false; - clicked=false; -} -function click(value) { - gridclick(value.y,value.x); -} -function gridclick(y,x) { - if (playing) { - clicked=true; - if (placeflag) { - if (shown[y][x]<3) { - s=shown[y][x]; - change=true; - if (s==1) { - flagsleft++; - squaresleft++; - } - if (flagsleft==0&&s==0) { - change=false; - } - else { - if (s==2) s=0; - else s++; - if (s==1) { - flagsleft--; - squaresleft--; - } - } - if (change) { - shown[y][x]=s; - board.children[x*gridx+y].children[1]=sqtimages[s]; - setStatus(); - } - if (squaresleft==0) { - conditionNode.children[1]=btncool; - playing=false; - } - } - } - else if (shown[y][x]!=1) { - if (mines[y][x]) { - board.children[x*gridx+y].children[1]=mineredImage; - dead(); - } - else { - rollback(y,x); - } - } - } -} - " - ] - } - ] -} - -ROUTE N25.isActive TO N220.startGame -ROUTE N0.cycleTime TO N220.timeOut -ROUTE N28.isActive TO N30.activate -ROUTE N29.outSFVec2f TO N220.click -ROUTE N31.isActive TO N33.activate -ROUTE N32.outSFVec2f TO N220.click -ROUTE N34.isActive TO N36.activate -ROUTE N35.outSFVec2f TO N220.click -ROUTE N37.isActive TO N39.activate -ROUTE N38.outSFVec2f TO N220.click -ROUTE N40.isActive TO N42.activate -ROUTE N41.outSFVec2f TO N220.click -ROUTE N43.isActive TO N45.activate -ROUTE N44.outSFVec2f TO N220.click -ROUTE N46.isActive TO N48.activate -ROUTE N47.outSFVec2f TO N220.click -ROUTE N49.isActive TO N51.activate -ROUTE N50.outSFVec2f TO N220.click -ROUTE N52.isActive TO N54.activate -ROUTE N53.outSFVec2f TO N220.click -ROUTE N55.isActive TO N57.activate -ROUTE N56.outSFVec2f TO N220.click -ROUTE N58.isActive TO N60.activate -ROUTE N59.outSFVec2f TO N220.click -ROUTE N61.isActive TO N63.activate -ROUTE N62.outSFVec2f TO N220.click -ROUTE N64.isActive TO N66.activate -ROUTE N65.outSFVec2f TO N220.click -ROUTE N67.isActive TO N69.activate -ROUTE N68.outSFVec2f TO N220.click -ROUTE N70.isActive TO N72.activate -ROUTE N71.outSFVec2f TO N220.click -ROUTE N73.isActive TO N75.activate -ROUTE N74.outSFVec2f TO N220.click -ROUTE N76.isActive TO N78.activate -ROUTE N77.outSFVec2f TO N220.click -ROUTE N79.isActive TO N81.activate -ROUTE N80.outSFVec2f TO N220.click -ROUTE N82.isActive TO N84.activate -ROUTE N83.outSFVec2f TO N220.click -ROUTE N85.isActive TO N87.activate -ROUTE N86.outSFVec2f TO N220.click -ROUTE N88.isActive TO N90.activate -ROUTE N89.outSFVec2f TO N220.click -ROUTE N91.isActive TO N93.activate -ROUTE N92.outSFVec2f TO N220.click -ROUTE N94.isActive TO N96.activate -ROUTE N95.outSFVec2f TO N220.click -ROUTE N97.isActive TO N99.activate -ROUTE N98.outSFVec2f TO N220.click -ROUTE N100.isActive TO N102.activate -ROUTE N101.outSFVec2f TO N220.click -ROUTE N103.isActive TO N105.activate -ROUTE N104.outSFVec2f TO N220.click -ROUTE N106.isActive TO N108.activate -ROUTE N107.outSFVec2f TO N220.click -ROUTE N109.isActive TO N111.activate -ROUTE N110.outSFVec2f TO N220.click -ROUTE N112.isActive TO N114.activate -ROUTE N113.outSFVec2f TO N220.click -ROUTE N115.isActive TO N117.activate -ROUTE N116.outSFVec2f TO N220.click -ROUTE N118.isActive TO N120.activate -ROUTE N119.outSFVec2f TO N220.click -ROUTE N121.isActive TO N123.activate -ROUTE N122.outSFVec2f TO N220.click -ROUTE N124.isActive TO N126.activate -ROUTE N125.outSFVec2f TO N220.click -ROUTE N127.isActive TO N129.activate -ROUTE N128.outSFVec2f TO N220.click -ROUTE N130.isActive TO N132.activate -ROUTE N131.outSFVec2f TO N220.click -ROUTE N133.isActive TO N135.activate -ROUTE N134.outSFVec2f TO N220.click -ROUTE N136.isActive TO N138.activate -ROUTE N137.outSFVec2f TO N220.click -ROUTE N139.isActive TO N141.activate -ROUTE N140.outSFVec2f TO N220.click -ROUTE N142.isActive TO N144.activate -ROUTE N143.outSFVec2f TO N220.click -ROUTE N145.isActive TO N147.activate -ROUTE N146.outSFVec2f TO N220.click -ROUTE N148.isActive TO N150.activate -ROUTE N149.outSFVec2f TO N220.click -ROUTE N151.isActive TO N153.activate -ROUTE N152.outSFVec2f TO N220.click -ROUTE N154.isActive TO N156.activate -ROUTE N155.outSFVec2f TO N220.click -ROUTE N157.isActive TO N159.activate -ROUTE N158.outSFVec2f TO N220.click -ROUTE N160.isActive TO N162.activate -ROUTE N161.outSFVec2f TO N220.click -ROUTE N163.isActive TO N165.activate -ROUTE N164.outSFVec2f TO N220.click -ROUTE N166.isActive TO N168.activate -ROUTE N167.outSFVec2f TO N220.click -ROUTE N169.isActive TO N171.activate -ROUTE N170.outSFVec2f TO N220.click -ROUTE N172.isActive TO N174.activate -ROUTE N173.outSFVec2f TO N220.click -ROUTE N175.isActive TO N177.activate -ROUTE N176.outSFVec2f TO N220.click -ROUTE N178.isActive TO N180.activate -ROUTE N179.outSFVec2f TO N220.click -ROUTE N181.isActive TO N183.activate -ROUTE N182.outSFVec2f TO N220.click -ROUTE N184.isActive TO N186.activate -ROUTE N185.outSFVec2f TO N220.click -ROUTE N187.isActive TO N189.activate -ROUTE N188.outSFVec2f TO N220.click -ROUTE N190.isActive TO N192.activate -ROUTE N191.outSFVec2f TO N220.click -ROUTE N193.isActive TO N195.activate -ROUTE N194.outSFVec2f TO N220.click -ROUTE N196.isActive TO N198.activate -ROUTE N197.outSFVec2f TO N220.click -ROUTE N199.isActive TO N201.activate -ROUTE N200.outSFVec2f TO N220.click -ROUTE N202.isActive TO N204.activate -ROUTE N203.outSFVec2f TO N220.click -ROUTE N205.isActive TO N207.activate -ROUTE N206.outSFVec2f TO N220.click -ROUTE N208.isActive TO N210.activate -ROUTE N209.outSFVec2f TO N220.click -ROUTE N211.isActive TO N213.activate -ROUTE N212.outSFVec2f TO N220.click -ROUTE N214.isActive TO N216.activate -ROUTE N215.outSFVec2f TO N220.click -ROUTE N217.isActive TO N219.activate -ROUTE N218.outSFVec2f TO N220.click - diff --git a/regression_tests/bifs-game-othello.bt b/regression_tests/bifs-game-othello.bt deleted file mode 100644 index 1ef5a4f..0000000 --- a/regression_tests/bifs-game-othello.bt +++ /dev/null @@ -1,2836 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 1 - sceneProfileLevelIndication 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSv2Config { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" - ] - title "Othello using BIFS and ECMAScript" - } - DEF TimeOutSensor TimeSensor { - enabled FALSE - cycleInterval 0.15 - } - Transform2D { - translation 0 180 - children [ - DEF StartTS TouchSensor {} - Shape { - geometry Rectangle { size 100 25 } - appearance Appearance { material Material2D { emissiveColor 0.5 0.5 0.5 filled TRUE } } - } - Shape { - appearance Appearance { - material Material2D { - filled TRUE - emissiveColor 1 0 0 - } - } - geometry Text { - string [ "Start Game" ] - fontStyle FontStyle { - size 20 - justify ["MIDDLE" "MIDDLE"] - } - } - } - ] - } - Switch { - whichChoice -1 - choice [ - DEF BlankPiece Transform2D { - children [ - DEF BackRectangle Shape { - geometry DEF R Rectangle { size 42 42 } - appearance Appearance { - material Material2D { - filled TRUE - emissiveColor 0 0.5 0.5 - } - } - } - Shape { - geometry DEF C Circle { radius 18 } - appearance Appearance { - material Material2D { - filled TRUE - emissiveColor 0 0.5 0.5 - } - } - } - ] - } - DEF WhitePiece Transform2D { - children [ - USE BackRectangle - DEF WhiteC Shape { - geometry USE C - appearance Appearance { - material Material2D { - filled TRUE - emissiveColor 1 1 1 - } - } - } - ] - } - DEF WhiteTransPiece Transform2D { - children [ - USE BackRectangle - USE WhiteC - ] - } - DEF BlackPiece Transform2D { - children [ - USE BackRectangle - DEF BlackC Shape { - geometry USE C - appearance Appearance { - material Material2D { - filled TRUE - emissiveColor 0 0 0 - } - } - } - ] - } - DEF BlackTransPiece Transform2D { - children [ - USE BackRectangle - USE BlackC - ] - } - DEF Trans1 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "1" ] - fontStyle DEF TFS FontStyle { - size 20 - justify [ "MIDDLE" "MIDDLE" ] - } - } - appearance DEF TA Appearance { - material Material2D { - filled TRUE - emissiveColor 0 1 0 - } - } - } - ] - } - DEF Trans2 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "2" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans3 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "3" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans4 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "4" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans5 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "5" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans6 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "6" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans7 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "7" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans8 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "8" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans9 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "9" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans10 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "10" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans11 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "11" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans12 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "12" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans13 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "13" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans14 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "14" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans15 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "15" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans16 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "16" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans17 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "17" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans18 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "18" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans19 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "19" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans20 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "20" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - DEF Trans21 Transform2D { - children [ - USE BackRectangle - Shape { - geometry Text { - string [ "21" ] - fontStyle USE TFS - } - appearance USE TA - } - ] - } - - ] - } - DEF Board Form { - size 345 345 - groups [ - 1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 7 -1 8 -1 - 9 -1 10 -1 11 -1 12 -1 13 -1 14 -1 15 -1 16 -1 - 17 -1 18 -1 19 -1 20 -1 21 -1 22 -1 23 -1 24 -1 - 25 -1 26 -1 27 -1 28 -1 29 -1 30 -1 31 -1 32 -1 - 33 -1 34 -1 35 -1 36 -1 37 -1 38 -1 39 -1 40 -1 - 41 -1 42 -1 43 -1 44 -1 45 -1 46 -1 47 -1 48 -1 - 49 -1 50 -1 51 -1 52 -1 53 -1 54 -1 55 -1 56 -1 - 57 -1 58 -1 59 -1 60 -1 61 -1 62 -1 63 -1 64 -1 - 1 2 3 4 5 6 7 8 -1 - 9 10 11 12 13 14 15 16 -1 - 17 18 19 20 21 22 23 24 -1 - 25 26 27 28 29 30 31 32 -1 - 33 34 35 36 37 38 39 40 -1 - 41 42 43 44 45 46 47 48 -1 - 49 50 51 52 53 54 55 56 -1 - 57 58 59 60 61 62 63 64 -1 - ] - groupsIndex [ - 1 2 3 4 5 6 7 8 -1 - 9 10 11 12 13 14 15 16 -1 - 17 18 19 20 21 22 23 24 -1 - 25 26 27 28 29 30 31 32 -1 - 33 34 35 36 37 38 39 40 -1 - 41 42 43 44 45 46 47 48 -1 - 49 50 51 52 53 54 55 56 -1 - 57 58 59 60 61 62 63 64 -1 - 65 66 67 68 69 70 71 72 -1 - ] - constraints [ - "SHin" - "SHin" - "SHin" - "SHin" - "SHin" - "SHin" - "SHin" - "SHin" - "SVin" - ] - children [ - Transform2D { - children [ - DEF TS00 TouchSensor {} - USE BlankPiece - DEF V00_Over Valuator {} - DEF V00_Out Valuator {} - DEF V00_Click Valuator {} - DEF C00_Over Conditional { - buffer { - REPLACE V00_Over.inSFVec2f BY 0 0 - } - } - DEF C00_Out Conditional { - buffer { - REPLACE V00_Out.inSFVec2f BY 0 0 - } - } - DEF C00_Click Conditional { - buffer { - REPLACE V00_Click.inSFVec2f BY 0 0 - } - } - ] - } - Transform2D { - children [ - DEF TS01 TouchSensor {} - USE BlankPiece - DEF V01_Over Valuator {} - DEF V01_Out Valuator {} - DEF V01_Click Valuator {} - DEF C01_Over Conditional { - buffer { - REPLACE V01_Over.inSFVec2f BY 0 1 - } - } - DEF C01_Out Conditional { - buffer { - REPLACE V01_Out.inSFVec2f BY 0 1 - } - } - DEF C01_Click Conditional { - buffer { - REPLACE V01_Click.inSFVec2f BY 0 1 - } - } - ] - } - Transform2D { - children [ - DEF TS02 TouchSensor {} - USE BlankPiece - DEF V02_Over Valuator {} - DEF V02_Out Valuator {} - DEF V02_Click Valuator {} - DEF C02_Over Conditional { - buffer { - REPLACE V02_Over.inSFVec2f BY 0 2 - } - } - DEF C02_Out Conditional { - buffer { - REPLACE V02_Out.inSFVec2f BY 0 2 - } - } - DEF C02_Click Conditional { - buffer { - REPLACE V02_Click.inSFVec2f BY 0 2 - } - } - ] - } - Transform2D { - children [ - DEF TS03 TouchSensor {} - USE BlankPiece - DEF V03_Over Valuator {} - DEF V03_Out Valuator {} - DEF V03_Click Valuator {} - DEF C03_Over Conditional { - buffer { - REPLACE V03_Over.inSFVec2f BY 0 3 - } - } - DEF C03_Out Conditional { - buffer { - REPLACE V03_Out.inSFVec2f BY 0 3 - } - } - DEF C03_Click Conditional { - buffer { - REPLACE V03_Click.inSFVec2f BY 0 3 - } - } - ] - } - Transform2D { - children [ - DEF TS04 TouchSensor {} - USE BlankPiece - DEF V04_Over Valuator {} - DEF V04_Out Valuator {} - DEF V04_Click Valuator {} - DEF C04_Over Conditional { - buffer { - REPLACE V04_Over.inSFVec2f BY 0 4 - } - } - DEF C04_Out Conditional { - buffer { - REPLACE V04_Out.inSFVec2f BY 0 4 - } - } - DEF C04_Click Conditional { - buffer { - REPLACE V04_Click.inSFVec2f BY 0 4 - } - } - ] - } - Transform2D { - children [ - DEF TS05 TouchSensor {} - USE BlankPiece - DEF V05_Over Valuator {} - DEF V05_Out Valuator {} - DEF V05_Click Valuator {} - DEF C05_Over Conditional { - buffer { - REPLACE V05_Over.inSFVec2f BY 0 5 - } - } - DEF C05_Out Conditional { - buffer { - REPLACE V05_Out.inSFVec2f BY 0 5 - } - } - DEF C05_Click Conditional { - buffer { - REPLACE V05_Click.inSFVec2f BY 0 5 - } - } - ] - } - Transform2D { - children [ - DEF TS06 TouchSensor {} - USE BlankPiece - DEF V06_Over Valuator {} - DEF V06_Out Valuator {} - DEF V06_Click Valuator {} - DEF C06_Over Conditional { - buffer { - REPLACE V06_Over.inSFVec2f BY 0 6 - } - } - DEF C06_Out Conditional { - buffer { - REPLACE V06_Out.inSFVec2f BY 0 6 - } - } - DEF C06_Click Conditional { - buffer { - REPLACE V06_Click.inSFVec2f BY 0 6 - } - } - ] - } - Transform2D { - children [ - DEF TS07 TouchSensor {} - USE BlankPiece - DEF V07_Over Valuator {} - DEF V07_Out Valuator {} - DEF V07_Click Valuator {} - DEF C07_Over Conditional { - buffer { - REPLACE V07_Over.inSFVec2f BY 0 7 - } - } - DEF C07_Out Conditional { - buffer { - REPLACE V07_Out.inSFVec2f BY 0 7 - } - } - DEF C07_Click Conditional { - buffer { - REPLACE V07_Click.inSFVec2f BY 0 7 - } - } - ] - } - Transform2D { - children [ - DEF TS10 TouchSensor {} - USE BlankPiece - DEF V10_Over Valuator {} - DEF V10_Out Valuator {} - DEF V10_Click Valuator {} - DEF C10_Over Conditional { - buffer { - REPLACE V10_Over.inSFVec2f BY 1 0 - } - } - DEF C10_Out Conditional { - buffer { - REPLACE V10_Out.inSFVec2f BY 1 0 - } - } - DEF C10_Click Conditional { - buffer { - REPLACE V10_Click.inSFVec2f BY 1 0 - } - } - ] - } - Transform2D { - children [ - DEF TS11 TouchSensor {} - USE BlankPiece - DEF V11_Over Valuator {} - DEF V11_Out Valuator {} - DEF V11_Click Valuator {} - DEF C11_Over Conditional { - buffer { - REPLACE V11_Over.inSFVec2f BY 1 1 - } - } - DEF C11_Out Conditional { - buffer { - REPLACE V11_Out.inSFVec2f BY 1 1 - } - } - DEF C11_Click Conditional { - buffer { - REPLACE V11_Click.inSFVec2f BY 1 1 - } - } - ] - } - Transform2D { - children [ - DEF TS12 TouchSensor {} - USE BlankPiece - DEF V12_Over Valuator {} - DEF V12_Out Valuator {} - DEF V12_Click Valuator {} - DEF C12_Over Conditional { - buffer { - REPLACE V12_Over.inSFVec2f BY 1 2 - } - } - DEF C12_Out Conditional { - buffer { - REPLACE V12_Out.inSFVec2f BY 1 2 - } - } - DEF C12_Click Conditional { - buffer { - REPLACE V12_Click.inSFVec2f BY 1 2 - } - } - ] - } - Transform2D { - children [ - DEF TS13 TouchSensor {} - USE BlankPiece - DEF V13_Over Valuator {} - DEF V13_Out Valuator {} - DEF V13_Click Valuator {} - DEF C13_Over Conditional { - buffer { - REPLACE V13_Over.inSFVec2f BY 1 3 - } - } - DEF C13_Out Conditional { - buffer { - REPLACE V13_Out.inSFVec2f BY 1 3 - } - } - DEF C13_Click Conditional { - buffer { - REPLACE V13_Click.inSFVec2f BY 1 3 - } - } - ] - } - Transform2D { - children [ - DEF TS14 TouchSensor {} - USE BlankPiece - DEF V14_Over Valuator {} - DEF V14_Out Valuator {} - DEF V14_Click Valuator {} - DEF C14_Over Conditional { - buffer { - REPLACE V14_Over.inSFVec2f BY 1 4 - } - } - DEF C14_Out Conditional { - buffer { - REPLACE V14_Out.inSFVec2f BY 1 4 - } - } - DEF C14_Click Conditional { - buffer { - REPLACE V14_Click.inSFVec2f BY 1 4 - } - } - ] - } - Transform2D { - children [ - DEF TS15 TouchSensor {} - USE BlankPiece - DEF V15_Over Valuator {} - DEF V15_Out Valuator {} - DEF V15_Click Valuator {} - DEF C15_Over Conditional { - buffer { - REPLACE V15_Over.inSFVec2f BY 1 5 - } - } - DEF C15_Out Conditional { - buffer { - REPLACE V15_Out.inSFVec2f BY 1 5 - } - } - DEF C15_Click Conditional { - buffer { - REPLACE V15_Click.inSFVec2f BY 1 5 - } - } - ] - } - Transform2D { - children [ - DEF TS16 TouchSensor {} - USE BlankPiece - DEF V16_Over Valuator {} - DEF V16_Out Valuator {} - DEF V16_Click Valuator {} - DEF C16_Over Conditional { - buffer { - REPLACE V16_Over.inSFVec2f BY 1 6 - } - } - DEF C16_Out Conditional { - buffer { - REPLACE V16_Out.inSFVec2f BY 1 6 - } - } - DEF C16_Click Conditional { - buffer { - REPLACE V16_Click.inSFVec2f BY 1 6 - } - } - ] - } - Transform2D { - children [ - DEF TS17 TouchSensor {} - USE BlankPiece - DEF V17_Over Valuator {} - DEF V17_Out Valuator {} - DEF V17_Click Valuator {} - DEF C17_Over Conditional { - buffer { - REPLACE V17_Over.inSFVec2f BY 1 7 - } - } - DEF C17_Out Conditional { - buffer { - REPLACE V17_Out.inSFVec2f BY 1 7 - } - } - DEF C17_Click Conditional { - buffer { - REPLACE V17_Click.inSFVec2f BY 1 7 - } - } - ] - } - Transform2D { - children [ - DEF TS20 TouchSensor {} - USE BlankPiece - DEF V20_Over Valuator {} - DEF V20_Out Valuator {} - DEF V20_Click Valuator {} - DEF C20_Over Conditional { - buffer { - REPLACE V20_Over.inSFVec2f BY 2 0 - } - } - DEF C20_Out Conditional { - buffer { - REPLACE V20_Out.inSFVec2f BY 2 0 - } - } - DEF C20_Click Conditional { - buffer { - REPLACE V20_Click.inSFVec2f BY 2 0 - } - } - ] - } - Transform2D { - children [ - DEF TS21 TouchSensor {} - USE BlankPiece - DEF V21_Over Valuator {} - DEF V21_Out Valuator {} - DEF V21_Click Valuator {} - DEF C21_Over Conditional { - buffer { - REPLACE V21_Over.inSFVec2f BY 2 1 - } - } - DEF C21_Out Conditional { - buffer { - REPLACE V21_Out.inSFVec2f BY 2 1 - } - } - DEF C21_Click Conditional { - buffer { - REPLACE V21_Click.inSFVec2f BY 2 1 - } - } - ] - } - Transform2D { - children [ - DEF TS22 TouchSensor {} - USE BlankPiece - DEF V22_Over Valuator {} - DEF V22_Out Valuator {} - DEF V22_Click Valuator {} - DEF C22_Over Conditional { - buffer { - REPLACE V22_Over.inSFVec2f BY 2 2 - } - } - DEF C22_Out Conditional { - buffer { - REPLACE V22_Out.inSFVec2f BY 2 2 - } - } - DEF C22_Click Conditional { - buffer { - REPLACE V22_Click.inSFVec2f BY 2 2 - } - } - ] - } - Transform2D { - children [ - DEF TS23 TouchSensor {} - USE BlankPiece - DEF V23_Over Valuator {} - DEF V23_Out Valuator {} - DEF V23_Click Valuator {} - DEF C23_Over Conditional { - buffer { - REPLACE V23_Over.inSFVec2f BY 2 3 - } - } - DEF C23_Out Conditional { - buffer { - REPLACE V23_Out.inSFVec2f BY 2 3 - } - } - DEF C23_Click Conditional { - buffer { - REPLACE V23_Click.inSFVec2f BY 2 3 - } - } - ] - } - Transform2D { - children [ - DEF TS24 TouchSensor {} - USE BlankPiece - DEF V24_Over Valuator {} - DEF V24_Out Valuator {} - DEF V24_Click Valuator {} - DEF C24_Over Conditional { - buffer { - REPLACE V24_Over.inSFVec2f BY 2 4 - } - } - DEF C24_Out Conditional { - buffer { - REPLACE V24_Out.inSFVec2f BY 2 4 - } - } - DEF C24_Click Conditional { - buffer { - REPLACE V24_Click.inSFVec2f BY 2 4 - } - } - ] - } - Transform2D { - children [ - DEF TS25 TouchSensor {} - USE BlankPiece - DEF V25_Over Valuator {} - DEF V25_Out Valuator {} - DEF V25_Click Valuator {} - DEF C25_Over Conditional { - buffer { - REPLACE V25_Over.inSFVec2f BY 2 5 - } - } - DEF C25_Out Conditional { - buffer { - REPLACE V25_Out.inSFVec2f BY 2 5 - } - } - DEF C25_Click Conditional { - buffer { - REPLACE V25_Click.inSFVec2f BY 2 5 - } - } - ] - } - Transform2D { - children [ - DEF TS26 TouchSensor {} - USE BlankPiece - DEF V26_Over Valuator {} - DEF V26_Out Valuator {} - DEF V26_Click Valuator {} - DEF C26_Over Conditional { - buffer { - REPLACE V26_Over.inSFVec2f BY 2 6 - } - } - DEF C26_Out Conditional { - buffer { - REPLACE V26_Out.inSFVec2f BY 2 6 - } - } - DEF C26_Click Conditional { - buffer { - REPLACE V26_Click.inSFVec2f BY 2 6 - } - } - ] - } - Transform2D { - children [ - DEF TS27 TouchSensor {} - USE BlankPiece - DEF V27_Over Valuator {} - DEF V27_Out Valuator {} - DEF V27_Click Valuator {} - DEF C27_Over Conditional { - buffer { - REPLACE V27_Over.inSFVec2f BY 2 7 - } - } - DEF C27_Out Conditional { - buffer { - REPLACE V27_Out.inSFVec2f BY 2 7 - } - } - DEF C27_Click Conditional { - buffer { - REPLACE V27_Click.inSFVec2f BY 2 7 - } - } - ] - } - Transform2D { - children [ - DEF TS30 TouchSensor {} - USE BlankPiece - DEF V30_Over Valuator {} - DEF V30_Out Valuator {} - DEF V30_Click Valuator {} - DEF C30_Over Conditional { - buffer { - REPLACE V30_Over.inSFVec2f BY 3 0 - } - } - DEF C30_Out Conditional { - buffer { - REPLACE V30_Out.inSFVec2f BY 3 0 - } - } - DEF C30_Click Conditional { - buffer { - REPLACE V30_Click.inSFVec2f BY 3 0 - } - } - ] - } - Transform2D { - children [ - DEF TS31 TouchSensor {} - USE BlankPiece - DEF V31_Over Valuator {} - DEF V31_Out Valuator {} - DEF V31_Click Valuator {} - DEF C31_Over Conditional { - buffer { - REPLACE V31_Over.inSFVec2f BY 3 1 - } - } - DEF C31_Out Conditional { - buffer { - REPLACE V31_Out.inSFVec2f BY 3 1 - } - } - DEF C31_Click Conditional { - buffer { - REPLACE V31_Click.inSFVec2f BY 3 1 - } - } - ] - } - Transform2D { - children [ - DEF TS32 TouchSensor {} - USE BlankPiece - DEF V32_Over Valuator {} - DEF V32_Out Valuator {} - DEF V32_Click Valuator {} - DEF C32_Over Conditional { - buffer { - REPLACE V32_Over.inSFVec2f BY 3 2 - } - } - DEF C32_Out Conditional { - buffer { - REPLACE V32_Out.inSFVec2f BY 3 2 - } - } - DEF C32_Click Conditional { - buffer { - REPLACE V32_Click.inSFVec2f BY 3 2 - } - } - ] - } - Transform2D { - children [ - DEF TS33 TouchSensor {} - USE WhitePiece - DEF V33_Over Valuator {} - DEF V33_Out Valuator {} - DEF V33_Click Valuator {} - DEF C33_Over Conditional { - buffer { - REPLACE V33_Over.inSFVec2f BY 3 3 - } - } - DEF C33_Out Conditional { - buffer { - REPLACE V33_Out.inSFVec2f BY 3 3 - } - } - DEF C33_Click Conditional { - buffer { - REPLACE V33_Click.inSFVec2f BY 3 3 - } - } - ] - } - Transform2D { - children [ - DEF TS34 TouchSensor {} - USE BlackPiece - DEF V34_Over Valuator {} - DEF V34_Out Valuator {} - DEF V34_Click Valuator {} - DEF C34_Over Conditional { - buffer { - REPLACE V34_Over.inSFVec2f BY 3 4 - } - } - DEF C34_Out Conditional { - buffer { - REPLACE V34_Out.inSFVec2f BY 3 4 - } - } - DEF C34_Click Conditional { - buffer { - REPLACE V34_Click.inSFVec2f BY 3 4 - } - } - ] - } - Transform2D { - children [ - DEF TS35 TouchSensor {} - USE BlankPiece - DEF V35_Over Valuator {} - DEF V35_Out Valuator {} - DEF V35_Click Valuator {} - DEF C35_Over Conditional { - buffer { - REPLACE V35_Over.inSFVec2f BY 3 5 - } - } - DEF C35_Out Conditional { - buffer { - REPLACE V35_Out.inSFVec2f BY 3 5 - } - } - DEF C35_Click Conditional { - buffer { - REPLACE V35_Click.inSFVec2f BY 3 5 - } - } - ] - } - Transform2D { - children [ - DEF TS36 TouchSensor {} - USE BlankPiece - DEF V36_Over Valuator {} - DEF V36_Out Valuator {} - DEF V36_Click Valuator {} - DEF C36_Over Conditional { - buffer { - REPLACE V36_Over.inSFVec2f BY 3 6 - } - } - DEF C36_Out Conditional { - buffer { - REPLACE V36_Out.inSFVec2f BY 3 6 - } - } - DEF C36_Click Conditional { - buffer { - REPLACE V36_Click.inSFVec2f BY 3 6 - } - } - ] - } - Transform2D { - children [ - DEF TS37 TouchSensor {} - USE BlankPiece - DEF V37_Over Valuator {} - DEF V37_Out Valuator {} - DEF V37_Click Valuator {} - DEF C37_Over Conditional { - buffer { - REPLACE V37_Over.inSFVec2f BY 3 7 - } - } - DEF C37_Out Conditional { - buffer { - REPLACE V37_Out.inSFVec2f BY 3 7 - } - } - DEF C37_Click Conditional { - buffer { - REPLACE V37_Click.inSFVec2f BY 3 7 - } - } - ] - } - Transform2D { - children [ - DEF TS40 TouchSensor {} - USE BlankPiece - DEF V40_Over Valuator {} - DEF V40_Out Valuator {} - DEF V40_Click Valuator {} - DEF C40_Over Conditional { - buffer { - REPLACE V40_Over.inSFVec2f BY 4 0 - } - } - DEF C40_Out Conditional { - buffer { - REPLACE V40_Out.inSFVec2f BY 4 0 - } - } - DEF C40_Click Conditional { - buffer { - REPLACE V40_Click.inSFVec2f BY 4 0 - } - } - ] - } - Transform2D { - children [ - DEF TS41 TouchSensor {} - USE BlankPiece - DEF V41_Over Valuator {} - DEF V41_Out Valuator {} - DEF V41_Click Valuator {} - DEF C41_Over Conditional { - buffer { - REPLACE V41_Over.inSFVec2f BY 4 1 - } - } - DEF C41_Out Conditional { - buffer { - REPLACE V41_Out.inSFVec2f BY 4 1 - } - } - DEF C41_Click Conditional { - buffer { - REPLACE V41_Click.inSFVec2f BY 4 1 - } - } - ] - } - Transform2D { - children [ - DEF TS42 TouchSensor {} - USE BlankPiece - DEF V42_Over Valuator {} - DEF V42_Out Valuator {} - DEF V42_Click Valuator {} - DEF C42_Over Conditional { - buffer { - REPLACE V42_Over.inSFVec2f BY 4 2 - } - } - DEF C42_Out Conditional { - buffer { - REPLACE V42_Out.inSFVec2f BY 4 2 - } - } - DEF C42_Click Conditional { - buffer { - REPLACE V42_Click.inSFVec2f BY 4 2 - } - } - ] - } - Transform2D { - children [ - DEF TS43 TouchSensor {} - USE BlackPiece - DEF V43_Over Valuator {} - DEF V43_Out Valuator {} - DEF V43_Click Valuator {} - DEF C43_Over Conditional { - buffer { - REPLACE V43_Over.inSFVec2f BY 4 3 - } - } - DEF C43_Out Conditional { - buffer { - REPLACE V43_Out.inSFVec2f BY 4 3 - } - } - DEF C43_Click Conditional { - buffer { - REPLACE V43_Click.inSFVec2f BY 4 3 - } - } - ] - } - Transform2D { - children [ - DEF TS44 TouchSensor {} - USE WhitePiece - DEF V44_Over Valuator {} - DEF V44_Out Valuator {} - DEF V44_Click Valuator {} - DEF C44_Over Conditional { - buffer { - REPLACE V44_Over.inSFVec2f BY 4 4 - } - } - DEF C44_Out Conditional { - buffer { - REPLACE V44_Out.inSFVec2f BY 4 4 - } - } - DEF C44_Click Conditional { - buffer { - REPLACE V44_Click.inSFVec2f BY 4 4 - } - } - ] - } - Transform2D { - children [ - DEF TS45 TouchSensor {} - USE BlankPiece - DEF V45_Over Valuator {} - DEF V45_Out Valuator {} - DEF V45_Click Valuator {} - DEF C45_Over Conditional { - buffer { - REPLACE V45_Over.inSFVec2f BY 4 5 - } - } - DEF C45_Out Conditional { - buffer { - REPLACE V45_Out.inSFVec2f BY 4 5 - } - } - DEF C45_Click Conditional { - buffer { - REPLACE V45_Click.inSFVec2f BY 4 5 - } - } - ] - } - Transform2D { - children [ - DEF TS46 TouchSensor {} - USE BlankPiece - DEF V46_Over Valuator {} - DEF V46_Out Valuator {} - DEF V46_Click Valuator {} - DEF C46_Over Conditional { - buffer { - REPLACE V46_Over.inSFVec2f BY 4 6 - } - } - DEF C46_Out Conditional { - buffer { - REPLACE V46_Out.inSFVec2f BY 4 6 - } - } - DEF C46_Click Conditional { - buffer { - REPLACE V46_Click.inSFVec2f BY 4 6 - } - } - ] - } - Transform2D { - children [ - DEF TS47 TouchSensor {} - USE BlankPiece - DEF V47_Over Valuator {} - DEF V47_Out Valuator {} - DEF V47_Click Valuator {} - DEF C47_Over Conditional { - buffer { - REPLACE V47_Over.inSFVec2f BY 4 7 - } - } - DEF C47_Out Conditional { - buffer { - REPLACE V47_Out.inSFVec2f BY 4 7 - } - } - DEF C47_Click Conditional { - buffer { - REPLACE V47_Click.inSFVec2f BY 4 7 - } - } - ] - } - Transform2D { - children [ - DEF TS50 TouchSensor {} - USE BlankPiece - DEF V50_Over Valuator {} - DEF V50_Out Valuator {} - DEF V50_Click Valuator {} - DEF C50_Over Conditional { - buffer { - REPLACE V50_Over.inSFVec2f BY 5 0 - } - } - DEF C50_Out Conditional { - buffer { - REPLACE V50_Out.inSFVec2f BY 5 0 - } - } - DEF C50_Click Conditional { - buffer { - REPLACE V50_Click.inSFVec2f BY 5 0 - } - } - ] - } - Transform2D { - children [ - DEF TS51 TouchSensor {} - USE BlankPiece - DEF V51_Over Valuator {} - DEF V51_Out Valuator {} - DEF V51_Click Valuator {} - DEF C51_Over Conditional { - buffer { - REPLACE V51_Over.inSFVec2f BY 5 1 - } - } - DEF C51_Out Conditional { - buffer { - REPLACE V51_Out.inSFVec2f BY 5 1 - } - } - DEF C51_Click Conditional { - buffer { - REPLACE V51_Click.inSFVec2f BY 5 1 - } - } - ] - } - Transform2D { - children [ - DEF TS52 TouchSensor {} - USE BlankPiece - DEF V52_Over Valuator {} - DEF V52_Out Valuator {} - DEF V52_Click Valuator {} - DEF C52_Over Conditional { - buffer { - REPLACE V52_Over.inSFVec2f BY 5 2 - } - } - DEF C52_Out Conditional { - buffer { - REPLACE V52_Out.inSFVec2f BY 5 2 - } - } - DEF C52_Click Conditional { - buffer { - REPLACE V52_Click.inSFVec2f BY 5 2 - } - } - ] - } - Transform2D { - children [ - DEF TS53 TouchSensor {} - USE BlankPiece - DEF V53_Over Valuator {} - DEF V53_Out Valuator {} - DEF V53_Click Valuator {} - DEF C53_Over Conditional { - buffer { - REPLACE V53_Over.inSFVec2f BY 5 3 - } - } - DEF C53_Out Conditional { - buffer { - REPLACE V53_Out.inSFVec2f BY 5 3 - } - } - DEF C53_Click Conditional { - buffer { - REPLACE V53_Click.inSFVec2f BY 5 3 - } - } - ] - } - Transform2D { - children [ - DEF TS54 TouchSensor {} - USE BlankPiece - DEF V54_Over Valuator {} - DEF V54_Out Valuator {} - DEF V54_Click Valuator {} - DEF C54_Over Conditional { - buffer { - REPLACE V54_Over.inSFVec2f BY 5 4 - } - } - DEF C54_Out Conditional { - buffer { - REPLACE V54_Out.inSFVec2f BY 5 4 - } - } - DEF C54_Click Conditional { - buffer { - REPLACE V54_Click.inSFVec2f BY 5 4 - } - } - ] - } - Transform2D { - children [ - DEF TS55 TouchSensor {} - USE BlankPiece - DEF V55_Over Valuator {} - DEF V55_Out Valuator {} - DEF V55_Click Valuator {} - DEF C55_Over Conditional { - buffer { - REPLACE V55_Over.inSFVec2f BY 5 5 - } - } - DEF C55_Out Conditional { - buffer { - REPLACE V55_Out.inSFVec2f BY 5 5 - } - } - DEF C55_Click Conditional { - buffer { - REPLACE V55_Click.inSFVec2f BY 5 5 - } - } - ] - } - Transform2D { - children [ - DEF TS56 TouchSensor {} - USE BlankPiece - DEF V56_Over Valuator {} - DEF V56_Out Valuator {} - DEF V56_Click Valuator {} - DEF C56_Over Conditional { - buffer { - REPLACE V56_Over.inSFVec2f BY 5 6 - } - } - DEF C56_Out Conditional { - buffer { - REPLACE V56_Out.inSFVec2f BY 5 6 - } - } - DEF C56_Click Conditional { - buffer { - REPLACE V56_Click.inSFVec2f BY 5 6 - } - } - ] - } - Transform2D { - children [ - DEF TS57 TouchSensor {} - USE BlankPiece - DEF V57_Over Valuator {} - DEF V57_Out Valuator {} - DEF V57_Click Valuator {} - DEF C57_Over Conditional { - buffer { - REPLACE V57_Over.inSFVec2f BY 5 7 - } - } - DEF C57_Out Conditional { - buffer { - REPLACE V57_Out.inSFVec2f BY 5 7 - } - } - DEF C57_Click Conditional { - buffer { - REPLACE V57_Click.inSFVec2f BY 5 7 - } - } - ] - } - Transform2D { - children [ - DEF TS60 TouchSensor {} - USE BlankPiece - DEF V60_Over Valuator {} - DEF V60_Out Valuator {} - DEF V60_Click Valuator {} - DEF C60_Over Conditional { - buffer { - REPLACE V60_Over.inSFVec2f BY 6 0 - } - } - DEF C60_Out Conditional { - buffer { - REPLACE V60_Out.inSFVec2f BY 6 0 - } - } - DEF C60_Click Conditional { - buffer { - REPLACE V60_Click.inSFVec2f BY 6 0 - } - } - ] - } - Transform2D { - children [ - DEF TS61 TouchSensor {} - USE BlankPiece - DEF V61_Over Valuator {} - DEF V61_Out Valuator {} - DEF V61_Click Valuator {} - DEF C61_Over Conditional { - buffer { - REPLACE V61_Over.inSFVec2f BY 6 1 - } - } - DEF C61_Out Conditional { - buffer { - REPLACE V61_Out.inSFVec2f BY 6 1 - } - } - DEF C61_Click Conditional { - buffer { - REPLACE V61_Click.inSFVec2f BY 6 1 - } - } - ] - } - Transform2D { - children [ - DEF TS62 TouchSensor {} - USE BlankPiece - DEF V62_Over Valuator {} - DEF V62_Out Valuator {} - DEF V62_Click Valuator {} - DEF C62_Over Conditional { - buffer { - REPLACE V62_Over.inSFVec2f BY 6 2 - } - } - DEF C62_Out Conditional { - buffer { - REPLACE V62_Out.inSFVec2f BY 6 2 - } - } - DEF C62_Click Conditional { - buffer { - REPLACE V62_Click.inSFVec2f BY 6 2 - } - } - ] - } - Transform2D { - children [ - DEF TS63 TouchSensor {} - USE BlankPiece - DEF V63_Over Valuator {} - DEF V63_Out Valuator {} - DEF V63_Click Valuator {} - DEF C63_Over Conditional { - buffer { - REPLACE V63_Over.inSFVec2f BY 6 3 - } - } - DEF C63_Out Conditional { - buffer { - REPLACE V63_Out.inSFVec2f BY 6 3 - } - } - DEF C63_Click Conditional { - buffer { - REPLACE V63_Click.inSFVec2f BY 6 3 - } - } - ] - } - Transform2D { - children [ - DEF TS64 TouchSensor {} - USE BlankPiece - DEF V64_Over Valuator {} - DEF V64_Out Valuator {} - DEF V64_Click Valuator {} - DEF C64_Over Conditional { - buffer { - REPLACE V64_Over.inSFVec2f BY 6 4 - } - } - DEF C64_Out Conditional { - buffer { - REPLACE V64_Out.inSFVec2f BY 6 4 - } - } - DEF C64_Click Conditional { - buffer { - REPLACE V64_Click.inSFVec2f BY 6 4 - } - } - ] - } - Transform2D { - children [ - DEF TS65 TouchSensor {} - USE BlankPiece - DEF V65_Over Valuator {} - DEF V65_Out Valuator {} - DEF V65_Click Valuator {} - DEF C65_Over Conditional { - buffer { - REPLACE V65_Over.inSFVec2f BY 6 5 - } - } - DEF C65_Out Conditional { - buffer { - REPLACE V65_Out.inSFVec2f BY 6 5 - } - } - DEF C65_Click Conditional { - buffer { - REPLACE V65_Click.inSFVec2f BY 6 5 - } - } - ] - } - Transform2D { - children [ - DEF TS66 TouchSensor {} - USE BlankPiece - DEF V66_Over Valuator {} - DEF V66_Out Valuator {} - DEF V66_Click Valuator {} - DEF C66_Over Conditional { - buffer { - REPLACE V66_Over.inSFVec2f BY 6 6 - } - } - DEF C66_Out Conditional { - buffer { - REPLACE V66_Out.inSFVec2f BY 6 6 - } - } - DEF C66_Click Conditional { - buffer { - REPLACE V66_Click.inSFVec2f BY 6 6 - } - } - ] - } - Transform2D { - children [ - DEF TS67 TouchSensor {} - USE BlankPiece - DEF V67_Over Valuator {} - DEF V67_Out Valuator {} - DEF V67_Click Valuator {} - DEF C67_Over Conditional { - buffer { - REPLACE V67_Over.inSFVec2f BY 6 7 - } - } - DEF C67_Out Conditional { - buffer { - REPLACE V67_Out.inSFVec2f BY 6 7 - } - } - DEF C67_Click Conditional { - buffer { - REPLACE V67_Click.inSFVec2f BY 6 7 - } - } - ] - } - Transform2D { - children [ - DEF TS70 TouchSensor {} - USE BlankPiece - DEF V70_Over Valuator {} - DEF V70_Out Valuator {} - DEF V70_Click Valuator {} - DEF C70_Over Conditional { - buffer { - REPLACE V70_Over.inSFVec2f BY 7 0 - } - } - DEF C70_Out Conditional { - buffer { - REPLACE V70_Out.inSFVec2f BY 7 0 - } - } - DEF C70_Click Conditional { - buffer { - REPLACE V70_Click.inSFVec2f BY 7 0 - } - } - ] - } - Transform2D { - children [ - DEF TS71 TouchSensor {} - USE BlankPiece - DEF V71_Over Valuator {} - DEF V71_Out Valuator {} - DEF V71_Click Valuator {} - DEF C71_Over Conditional { - buffer { - REPLACE V71_Over.inSFVec2f BY 7 1 - } - } - DEF C71_Out Conditional { - buffer { - REPLACE V71_Out.inSFVec2f BY 7 1 - } - } - DEF C71_Click Conditional { - buffer { - REPLACE V71_Click.inSFVec2f BY 7 1 - } - } - ] - } - Transform2D { - children [ - DEF TS72 TouchSensor {} - USE BlankPiece - DEF V72_Over Valuator {} - DEF V72_Out Valuator {} - DEF V72_Click Valuator {} - DEF C72_Over Conditional { - buffer { - REPLACE V72_Over.inSFVec2f BY 7 2 - } - } - DEF C72_Out Conditional { - buffer { - REPLACE V72_Out.inSFVec2f BY 7 2 - } - } - DEF C72_Click Conditional { - buffer { - REPLACE V72_Click.inSFVec2f BY 7 2 - } - } - ] - } - Transform2D { - children [ - DEF TS73 TouchSensor {} - USE BlankPiece - DEF V73_Over Valuator {} - DEF V73_Out Valuator {} - DEF V73_Click Valuator {} - DEF C73_Over Conditional { - buffer { - REPLACE V73_Over.inSFVec2f BY 7 3 - } - } - DEF C73_Out Conditional { - buffer { - REPLACE V73_Out.inSFVec2f BY 7 3 - } - } - DEF C73_Click Conditional { - buffer { - REPLACE V73_Click.inSFVec2f BY 7 3 - } - } - ] - } - Transform2D { - children [ - DEF TS74 TouchSensor {} - USE BlankPiece - DEF V74_Over Valuator {} - DEF V74_Out Valuator {} - DEF V74_Click Valuator {} - DEF C74_Over Conditional { - buffer { - REPLACE V74_Over.inSFVec2f BY 7 4 - } - } - DEF C74_Out Conditional { - buffer { - REPLACE V74_Out.inSFVec2f BY 7 4 - } - } - DEF C74_Click Conditional { - buffer { - REPLACE V74_Click.inSFVec2f BY 7 4 - } - } - ] - } - Transform2D { - children [ - DEF TS75 TouchSensor {} - USE BlankPiece - DEF V75_Over Valuator {} - DEF V75_Out Valuator {} - DEF V75_Click Valuator {} - DEF C75_Over Conditional { - buffer { - REPLACE V75_Over.inSFVec2f BY 7 5 - } - } - DEF C75_Out Conditional { - buffer { - REPLACE V75_Out.inSFVec2f BY 7 5 - } - } - DEF C75_Click Conditional { - buffer { - REPLACE V75_Click.inSFVec2f BY 7 5 - } - } - ] - } - Transform2D { - children [ - DEF TS76 TouchSensor {} - USE BlankPiece - DEF V76_Over Valuator {} - DEF V76_Out Valuator {} - DEF V76_Click Valuator {} - DEF C76_Over Conditional { - buffer { - REPLACE V76_Over.inSFVec2f BY 7 6 - } - } - DEF C76_Out Conditional { - buffer { - REPLACE V76_Out.inSFVec2f BY 7 6 - } - } - DEF C76_Click Conditional { - buffer { - REPLACE V76_Click.inSFVec2f BY 7 6 - } - } - ] - } - Transform2D { - children [ - DEF TS77 TouchSensor {} - USE BlankPiece - DEF V77_Over Valuator {} - DEF V77_Out Valuator {} - DEF V77_Click Valuator {} - DEF C77_Over Conditional { - buffer { - REPLACE V77_Over.inSFVec2f BY 7 7 - } - } - DEF C77_Out Conditional { - buffer { - REPLACE V77_Out.inSFVec2f BY 7 7 - } - } - DEF C77_Click Conditional { - buffer { - REPLACE V77_Click.inSFVec2f BY 7 7 - } - } - ] - } - ] - } - DEF SC Script { -eventIn SFBool startGame -eventIn SFVec2f mouseOver -eventIn SFVec2f mouseOut -eventIn SFVec2f click -eventIn SFBool timeOut - -field SFNode timer USE TimeOutSensor - -# some internal global variables -field MFNode picture [ - USE BlankPiece - USE WhitePiece - USE BlackPiece - USE WhiteTransPiece - USE BlackTransPiece - USE Trans1 - USE Trans2 - USE Trans3 - USE Trans4 - USE Trans5 - USE Trans6 - USE Trans7 - USE Trans8 - USE Trans9 - USE Trans10 - USE Trans11 - USE Trans12 - USE Trans13 - USE Trans14 - USE Trans15 - USE Trans16 - USE Trans17 - USE Trans18 - USE Trans19 - USE Trans20 - USE Trans21 -] -field SFNode images USE Board - - url "javascript: -// JavaScript Othello Game -// Copyright (c) 2000, 2001 Kelly Yancey <kbyanc@posi.net> -// All rights reserved. -// -// Redistribution and use in source form, with or without modification, is -// permitted provided that the following conditions are met: -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer, -// without modification, immediately at the beginning of the file. -// 2. All advertising materials mentioning features or use of this software -// must display the following acknowledgement: -// This product includes software developed by Kelly Yancey -// and a reference to the URL http://www.posi.net/software/othello/ -// 3. The name of the author may not be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// picture numbers -function initialize() { -EMPTY = 0; // empty square -WHITE = 1; // white piece -BLACK = 2; // black piece -WHITETRANS = 3; // white transparent cursor piece -BLACKTRANS = 4; // black transparent cursor piece -NUMBASE = 5; // beginning of numeric pictures - -// size of the pictures used to represent pieces (all pictures must be the same size) -piecewidth = 42; -pieceheight = 42; - -// size of the board -width = 8; -height = 8; - -// player settings -human = BLACK; -showcursor = true; // display cursor showing user where they can go -showflips = false; // display counts showing how many pieces they can flip by putting a piece in a given square - -// AI settings -weightsquares = 1; // whether AI prefers squares that yield higher flip counts -edgesensitive = 1; // whether AI is sensitive to the importance of edge squares - -// some internal global variables -board = new Array(width); -score = new Array(); -turn = BLACK; - - -human = BLACK; -showcursor = true; -showflips = true; -weightsquares = true; -edgesensitive = true; - -InitializeBoard(); - -Play(0); - -} - -function piece(x,y) { -// object definition for 'piece' type - this.imagenum = x * width + y; - this.player = EMPTY; - // how many pieces each player could flip by taking this square - this.flips = new Array(); - this.flips[WHITE] = 0; - this.flips[BLACK] = 0; - // how valuable this location is to each player - this.value = new Array(); - this.value[WHITE] = 0; - this.value[BLACK] = 0; -} - - -function SetPieceImage(x, y, src) { -// routine to set the image associated with the given piece - if(images.children[board[x][y].imagenum].children[1] != src) { - // we explicitely check to see if we are changing the image source to prevent - // unnecessary redrawing of images which do not change - images.children[board[x][y].imagenum].children[1] = src; - } -} - -function InitializeBoard() { -// routine to initialize the state of the game and draw the board - // build the board array - for(x = 0; x < width; x++) - board[x] = new Array (height); - - for(y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - // place initial pieces - if((x == 3 && y == 3) || (x == 4 && y == 4)) player = WHITE; - else if((x == 3 && y == 4) || (x == 4 && y == 3)) player = BLACK; - else player = EMPTY; - board[x][y] = new piece(x,y); - board[x][y].player = player; - } - } - // initialize scores - score[WHITE] = 2; - score[BLACK] = 2; -} - -function ResetBoard() { -// routine to reset all of the pieces on the board - - // reset the board - for(y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - board[x][y].player = EMPTY; - SetPieceImage(x, y, picture[EMPTY]); - } - } - - // reset scores - score[WHITE] = 0; - score[BLACK] = 0; - - // put initial pieces back on the board - RawPutPiece(3, 3, WHITE); - RawPutPiece(4, 4, WHITE); - RawPutPiece(3, 4, BLACK); - RawPutPiece(4, 3, BLACK); - - turn = BLACK; -} - -function NumFlips(x, y, player) { - count = 0; - - for(deltay = -1; deltay <= 1; deltay++) { - for(deltax = -1; deltax <= 1; deltax++) { - for(distance = 1;; distance++) { - posx = x + (distance * deltax); - posy = y + (distance * deltay); - // stop if we go off the board - if(posx < 0 || posx >= width || posy < 0 || posy >= height) - break; - // stop when we reach an empty square - if(board[posx][posy].player == EMPTY) - break; - // only update the flip count when we reach another of the - // player's pieces - if(board[posx][posy].player == player) { - count += distance - 1; - break; - } - } - } - } - return(count); -} - -function CalcFlipCounts() { - - for(y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - board[x][y].flips[WHITE] = 0; - board[x][y].flips[BLACK] = 0; - - if(board[x][y].player != EMPTY) continue; - - board[x][y].flips[WHITE] = NumFlips(x, y, WHITE); - board[x][y].flips[BLACK] = NumFlips(x, y, BLACK); - } - } -} - -function RawPutPiece(x, y, player) { - other = OtherPlayer(player); - if(board[x][y].player == other) score[other]--; - - board[x][y].player = player; - SetPieceImage(x, y, picture[player]); - score[player]++; -} - -function FlipPieces(x, y, player) { - count = 0; - - // put a piece down at the desired location - RawPutPiece(x, y, player); - - for(deltay = -1; deltay <= 1; deltay++) { - for(deltax = -1; deltax <= 1; deltax++) { - for(distance = 1;; distance++) { - posx = x + (distance * deltax); - posy = y + (distance * deltay); - // stop if we go off the board - if(posx < 0 || posx >= width || posy < 0 || posy >= height) - break; - // stop when we reach an empty square - if(board[posx][posy].player == EMPTY) - break; - if(board[posx][posy].player == player) { - // backtrack, flipping pieces - for(distance--; distance > 0; distance--) { - posx = x + (distance * deltax); - posy = y + (distance * deltay); - RawPutPiece(posx, posy, player); - } - break; - } - } - } - } - return(count); -} - -function AnyMoves(player) { - - for(y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - if(board[x][y].player != EMPTY) continue; - if(NumFlips(x, y, player) > 0) return(true); - } - } - return(false); -} - -function CanPutPiece(x, y, player) { -// determine whether the player can put a piece at the given position - if(turn != player) - return(false); - if(board[x][y].player != EMPTY) - return(false); - return(NumFlips(x, y, player) > 0); -} - -function CheckPutPiece(x, y) { - if(! showcursor) return; - if(! CanPutPiece(x, y, human)) return; - if(human == WHITE) over = WHITETRANS; - else over = BLACKTRANS; - - SetPieceImage(x, y, picture[over]); -} - -function RestorePiece(x, y) { - if(showflips && RawShowFlipCount(x, y, human)) return; - SetPieceImage(x, y, picture[board[x][y].player]); -} - -function PutPiece(x, y, timestamp) { - if(! CanPutPiece(x, y, human)) return; - - FlipPieces(x, y, human); - DoneTurn(timestamp); -} - -function RawShowFlipCount(x, y, player) { - if(board[x][y].player != EMPTY) return(false); - if((flips = board[x][y].flips[player]) == 0) return(false); - SetPieceImage(x, y, picture[NUMBASE + flips]); - return(true); -} - -function ShowFlipCounts(player) { - - CalcFlipCounts(); - for(y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - RawShowFlipCount(x, y, player); - } - } -} - -function HideFlipCounts() { - - for(y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - if(board[x][y].player == EMPTY) - SetPieceImage(x, y, picture[EMPTY]); - } - } -} - -function OtherPlayer(player) { - return((player == WHITE)? BLACK: WHITE); -} - -function DoneTurn(timestamp) { - moves = AnyMoves(turn); - turn = OtherPlayer(turn); - - // check whether the new player has any moves - if(! AnyMoves(turn)) { - if(! moves) return(GameOver()); - - // XXX inform user the player has no move - // and switch players again - turn = OtherPlayer(turn); - } - - // add a slight delay before the computer takes it's turn so game feels - // 'warmer'; when computer is playing itself, add larger delay so user - // can watch - if(turn != human) { - HideFlipCounts(); - timer.cycleInterval = ((human == EMPTY)? 1: 0.150); - timer.startTime = timestamp; - timer.enabled = true; - } else if(showflips) ShowFlipCounts(human); -} - -function Rate(x, y, player) { - - if(board[x][y].player != EMPTY) return(0); - if(x < 0 || x >= width || y < 0 || y >= height) return(0); - - rating = board[x][y].flips[player]; - - if(! weightsquares) - rating = (rating > 0)? 1: 0; - - if(edgesensitive && rating > 0) { - // increase all non-zero weightings by 3 so we have room - // to wait 'less ideal' squares below the baseline - rating += 10; - - // raise edge ratings 4 points, corners are raised 8 - if(x == 0 || x == width - 1) rating += 4; - if(y == 0 || y == height - 1) rating += 4; - // lower next-to-edge ratings by 5 points, next-to-corner by 10 - if(x == 1 || x == width - 2) rating -= 5; - if(y == 1 || y == height - 2) rating -= 5; - - // we cannot rule out a move because of bad location; we must - // always go somewhere - if(rating < 1) rating = 1; - } - return(rating); -} - -function OthelloAI(player, timestamp) { - best = 0; - numbest = 0; - - // rank each position on the board by the potential flip count - CalcFlipCounts(); - - // apply AI rating algorithm - for(y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - rating = Rate(x, y, player); - - // store the rating back into the board - board[x][y].value[player] = rating; - - if(rating == best) - numbest++; - else if(rating > best) { - best = rating; - numbest = 1; - } - } - } - - while(numbest > 0) { - // pick a square to put our piece - pick = Math.floor(Math.random() * numbest); - count = 0; - for(y = 0; y < height; y++) { - for(x = 0; x < width; x++) { - rating = board[x][y].value[player]; - if(rating == best) { - if(count == pick) { - FlipPieces(x, y, player); - DoneTurn(timestamp); - return; - } - else count++; - } - } - } - } - - // if we make it here, then there was nowhere to go - DoneTurn(timestamp); -} - -function Play(timestamp) { - // black always goes first - if(human != BLACK) - OthelloAI(BLACK,timestamp); - else if(showflips) - ShowFlipCounts(human); -} - -function GameOver() { - turn = EMPTY; -} - -function timeOut(value, timestamp) { - if (!value) { - OthelloAI(turn, timestamp); - } -} - -function startGame(value,timestamp) { - if (value) { - Play(timestamp); - } -} - -function click(value, timestamp) { - PutPiece(value.x, value.y, timestamp); -} - -function mouseOver(value) { - CheckPutPiece(value.x, value.y); -} - -function mouseOut(value) { - RestorePiece(value.x, value.y); -} - - - " - } - ] -} -ROUTE StartTS.isActive TO SC.startGame -ROUTE TimeOutSensor.isActive TO SC.timeOut - -ROUTE TS00.isActive TO C00_Click.activate -ROUTE TS00.isOver TO C00_Over.activate -ROUTE TS00.isOver TO C00_Out.reverseActivate -ROUTE V00_Over.outSFVec2f TO SC.mouseOver -ROUTE V00_Out.outSFVec2f TO SC.mouseOut -ROUTE V00_Click.outSFVec2f TO SC.click -ROUTE TS01.isActive TO C01_Click.activate -ROUTE TS01.isOver TO C01_Over.activate -ROUTE TS01.isOver TO C01_Out.reverseActivate -ROUTE V01_Over.outSFVec2f TO SC.mouseOver -ROUTE V01_Out.outSFVec2f TO SC.mouseOut -ROUTE V01_Click.outSFVec2f TO SC.click -ROUTE TS02.isActive TO C02_Click.activate -ROUTE TS02.isOver TO C02_Over.activate -ROUTE TS02.isOver TO C02_Out.reverseActivate -ROUTE V02_Over.outSFVec2f TO SC.mouseOver -ROUTE V02_Out.outSFVec2f TO SC.mouseOut -ROUTE V02_Click.outSFVec2f TO SC.click -ROUTE TS03.isActive TO C03_Click.activate -ROUTE TS03.isOver TO C03_Over.activate -ROUTE TS03.isOver TO C03_Out.reverseActivate -ROUTE V03_Over.outSFVec2f TO SC.mouseOver -ROUTE V03_Out.outSFVec2f TO SC.mouseOut -ROUTE V03_Click.outSFVec2f TO SC.click -ROUTE TS04.isActive TO C04_Click.activate -ROUTE TS04.isOver TO C04_Over.activate -ROUTE TS04.isOver TO C04_Out.reverseActivate -ROUTE V04_Over.outSFVec2f TO SC.mouseOver -ROUTE V04_Out.outSFVec2f TO SC.mouseOut -ROUTE V04_Click.outSFVec2f TO SC.click -ROUTE TS05.isActive TO C05_Click.activate -ROUTE TS05.isOver TO C05_Over.activate -ROUTE TS05.isOver TO C05_Out.reverseActivate -ROUTE V05_Over.outSFVec2f TO SC.mouseOver -ROUTE V05_Out.outSFVec2f TO SC.mouseOut -ROUTE V05_Click.outSFVec2f TO SC.click -ROUTE TS06.isActive TO C06_Click.activate -ROUTE TS06.isOver TO C06_Over.activate -ROUTE TS06.isOver TO C06_Out.reverseActivate -ROUTE V06_Over.outSFVec2f TO SC.mouseOver -ROUTE V06_Out.outSFVec2f TO SC.mouseOut -ROUTE V06_Click.outSFVec2f TO SC.click -ROUTE TS07.isActive TO C07_Click.activate -ROUTE TS07.isOver TO C07_Over.activate -ROUTE TS07.isOver TO C07_Out.reverseActivate -ROUTE V07_Over.outSFVec2f TO SC.mouseOver -ROUTE V07_Out.outSFVec2f TO SC.mouseOut -ROUTE V07_Click.outSFVec2f TO SC.click -ROUTE TS10.isActive TO C10_Click.activate -ROUTE TS10.isOver TO C10_Over.activate -ROUTE TS10.isOver TO C10_Out.reverseActivate -ROUTE V10_Over.outSFVec2f TO SC.mouseOver -ROUTE V10_Out.outSFVec2f TO SC.mouseOut -ROUTE V10_Click.outSFVec2f TO SC.click -ROUTE TS11.isActive TO C11_Click.activate -ROUTE TS11.isOver TO C11_Over.activate -ROUTE TS11.isOver TO C11_Out.reverseActivate -ROUTE V11_Over.outSFVec2f TO SC.mouseOver -ROUTE V11_Out.outSFVec2f TO SC.mouseOut -ROUTE V11_Click.outSFVec2f TO SC.click -ROUTE TS12.isActive TO C12_Click.activate -ROUTE TS12.isOver TO C12_Over.activate -ROUTE TS12.isOver TO C12_Out.reverseActivate -ROUTE V12_Over.outSFVec2f TO SC.mouseOver -ROUTE V12_Out.outSFVec2f TO SC.mouseOut -ROUTE V12_Click.outSFVec2f TO SC.click -ROUTE TS13.isActive TO C13_Click.activate -ROUTE TS13.isOver TO C13_Over.activate -ROUTE TS13.isOver TO C13_Out.reverseActivate -ROUTE V13_Over.outSFVec2f TO SC.mouseOver -ROUTE V13_Out.outSFVec2f TO SC.mouseOut -ROUTE V13_Click.outSFVec2f TO SC.click -ROUTE TS14.isActive TO C14_Click.activate -ROUTE TS14.isOver TO C14_Over.activate -ROUTE TS14.isOver TO C14_Out.reverseActivate -ROUTE V14_Over.outSFVec2f TO SC.mouseOver -ROUTE V14_Out.outSFVec2f TO SC.mouseOut -ROUTE V14_Click.outSFVec2f TO SC.click -ROUTE TS15.isActive TO C15_Click.activate -ROUTE TS15.isOver TO C15_Over.activate -ROUTE TS15.isOver TO C15_Out.reverseActivate -ROUTE V15_Over.outSFVec2f TO SC.mouseOver -ROUTE V15_Out.outSFVec2f TO SC.mouseOut -ROUTE V15_Click.outSFVec2f TO SC.click -ROUTE TS16.isActive TO C16_Click.activate -ROUTE TS16.isOver TO C16_Over.activate -ROUTE TS16.isOver TO C16_Out.reverseActivate -ROUTE V16_Over.outSFVec2f TO SC.mouseOver -ROUTE V16_Out.outSFVec2f TO SC.mouseOut -ROUTE V16_Click.outSFVec2f TO SC.click -ROUTE TS17.isActive TO C17_Click.activate -ROUTE TS17.isOver TO C17_Over.activate -ROUTE TS17.isOver TO C17_Out.reverseActivate -ROUTE V17_Over.outSFVec2f TO SC.mouseOver -ROUTE V17_Out.outSFVec2f TO SC.mouseOut -ROUTE V17_Click.outSFVec2f TO SC.click -ROUTE TS20.isActive TO C20_Click.activate -ROUTE TS20.isOver TO C20_Over.activate -ROUTE TS20.isOver TO C20_Out.reverseActivate -ROUTE V20_Over.outSFVec2f TO SC.mouseOver -ROUTE V20_Out.outSFVec2f TO SC.mouseOut -ROUTE V20_Click.outSFVec2f TO SC.click -ROUTE TS21.isActive TO C21_Click.activate -ROUTE TS21.isOver TO C21_Over.activate -ROUTE TS21.isOver TO C21_Out.reverseActivate -ROUTE V21_Over.outSFVec2f TO SC.mouseOver -ROUTE V21_Out.outSFVec2f TO SC.mouseOut -ROUTE V21_Click.outSFVec2f TO SC.click -ROUTE TS22.isActive TO C22_Click.activate -ROUTE TS22.isOver TO C22_Over.activate -ROUTE TS22.isOver TO C22_Out.reverseActivate -ROUTE V22_Over.outSFVec2f TO SC.mouseOver -ROUTE V22_Out.outSFVec2f TO SC.mouseOut -ROUTE V22_Click.outSFVec2f TO SC.click -ROUTE TS23.isActive TO C23_Click.activate -ROUTE TS23.isOver TO C23_Over.activate -ROUTE TS23.isOver TO C23_Out.reverseActivate -ROUTE V23_Over.outSFVec2f TO SC.mouseOver -ROUTE V23_Out.outSFVec2f TO SC.mouseOut -ROUTE V23_Click.outSFVec2f TO SC.click -ROUTE TS24.isActive TO C24_Click.activate -ROUTE TS24.isOver TO C24_Over.activate -ROUTE TS24.isOver TO C24_Out.reverseActivate -ROUTE V24_Over.outSFVec2f TO SC.mouseOver -ROUTE V24_Out.outSFVec2f TO SC.mouseOut -ROUTE V24_Click.outSFVec2f TO SC.click -ROUTE TS25.isActive TO C25_Click.activate -ROUTE TS25.isOver TO C25_Over.activate -ROUTE TS25.isOver TO C25_Out.reverseActivate -ROUTE V25_Over.outSFVec2f TO SC.mouseOver -ROUTE V25_Out.outSFVec2f TO SC.mouseOut -ROUTE V25_Click.outSFVec2f TO SC.click -ROUTE TS26.isActive TO C26_Click.activate -ROUTE TS26.isOver TO C26_Over.activate -ROUTE TS26.isOver TO C26_Out.reverseActivate -ROUTE V26_Over.outSFVec2f TO SC.mouseOver -ROUTE V26_Out.outSFVec2f TO SC.mouseOut -ROUTE V26_Click.outSFVec2f TO SC.click -ROUTE TS27.isActive TO C27_Click.activate -ROUTE TS27.isOver TO C27_Over.activate -ROUTE TS27.isOver TO C27_Out.reverseActivate -ROUTE V27_Over.outSFVec2f TO SC.mouseOver -ROUTE V27_Out.outSFVec2f TO SC.mouseOut -ROUTE V27_Click.outSFVec2f TO SC.click -ROUTE TS30.isActive TO C30_Click.activate -ROUTE TS30.isOver TO C30_Over.activate -ROUTE TS30.isOver TO C30_Out.reverseActivate -ROUTE V30_Over.outSFVec2f TO SC.mouseOver -ROUTE V30_Out.outSFVec2f TO SC.mouseOut -ROUTE V30_Click.outSFVec2f TO SC.click -ROUTE TS31.isActive TO C31_Click.activate -ROUTE TS31.isOver TO C31_Over.activate -ROUTE TS31.isOver TO C31_Out.reverseActivate -ROUTE V31_Over.outSFVec2f TO SC.mouseOver -ROUTE V31_Out.outSFVec2f TO SC.mouseOut -ROUTE V31_Click.outSFVec2f TO SC.click -ROUTE TS32.isActive TO C32_Click.activate -ROUTE TS32.isOver TO C32_Over.activate -ROUTE TS32.isOver TO C32_Out.reverseActivate -ROUTE V32_Over.outSFVec2f TO SC.mouseOver -ROUTE V32_Out.outSFVec2f TO SC.mouseOut -ROUTE V32_Click.outSFVec2f TO SC.click -ROUTE TS33.isActive TO C33_Click.activate -ROUTE TS33.isOver TO C33_Over.activate -ROUTE TS33.isOver TO C33_Out.reverseActivate -ROUTE V33_Over.outSFVec2f TO SC.mouseOver -ROUTE V33_Out.outSFVec2f TO SC.mouseOut -ROUTE V33_Click.outSFVec2f TO SC.click -ROUTE TS34.isActive TO C34_Click.activate -ROUTE TS34.isOver TO C34_Over.activate -ROUTE TS34.isOver TO C34_Out.reverseActivate -ROUTE V34_Over.outSFVec2f TO SC.mouseOver -ROUTE V34_Out.outSFVec2f TO SC.mouseOut -ROUTE V34_Click.outSFVec2f TO SC.click -ROUTE TS35.isActive TO C35_Click.activate -ROUTE TS35.isOver TO C35_Over.activate -ROUTE TS35.isOver TO C35_Out.reverseActivate -ROUTE V35_Over.outSFVec2f TO SC.mouseOver -ROUTE V35_Out.outSFVec2f TO SC.mouseOut -ROUTE V35_Click.outSFVec2f TO SC.click -ROUTE TS36.isActive TO C36_Click.activate -ROUTE TS36.isOver TO C36_Over.activate -ROUTE TS36.isOver TO C36_Out.reverseActivate -ROUTE V36_Over.outSFVec2f TO SC.mouseOver -ROUTE V36_Out.outSFVec2f TO SC.mouseOut -ROUTE V36_Click.outSFVec2f TO SC.click -ROUTE TS37.isActive TO C37_Click.activate -ROUTE TS37.isOver TO C37_Over.activate -ROUTE TS37.isOver TO C37_Out.reverseActivate -ROUTE V37_Over.outSFVec2f TO SC.mouseOver -ROUTE V37_Out.outSFVec2f TO SC.mouseOut -ROUTE V37_Click.outSFVec2f TO SC.click -ROUTE TS40.isActive TO C40_Click.activate -ROUTE TS40.isOver TO C40_Over.activate -ROUTE TS40.isOver TO C40_Out.reverseActivate -ROUTE V40_Over.outSFVec2f TO SC.mouseOver -ROUTE V40_Out.outSFVec2f TO SC.mouseOut -ROUTE V40_Click.outSFVec2f TO SC.click -ROUTE TS41.isActive TO C41_Click.activate -ROUTE TS41.isOver TO C41_Over.activate -ROUTE TS41.isOver TO C41_Out.reverseActivate -ROUTE V41_Over.outSFVec2f TO SC.mouseOver -ROUTE V41_Out.outSFVec2f TO SC.mouseOut -ROUTE V41_Click.outSFVec2f TO SC.click -ROUTE TS42.isActive TO C42_Click.activate -ROUTE TS42.isOver TO C42_Over.activate -ROUTE TS42.isOver TO C42_Out.reverseActivate -ROUTE V42_Over.outSFVec2f TO SC.mouseOver -ROUTE V42_Out.outSFVec2f TO SC.mouseOut -ROUTE V42_Click.outSFVec2f TO SC.click -ROUTE TS43.isActive TO C43_Click.activate -ROUTE TS43.isOver TO C43_Over.activate -ROUTE TS43.isOver TO C43_Out.reverseActivate -ROUTE V43_Over.outSFVec2f TO SC.mouseOver -ROUTE V43_Out.outSFVec2f TO SC.mouseOut -ROUTE V43_Click.outSFVec2f TO SC.click -ROUTE TS44.isActive TO C44_Click.activate -ROUTE TS44.isOver TO C44_Over.activate -ROUTE TS44.isOver TO C44_Out.reverseActivate -ROUTE V44_Over.outSFVec2f TO SC.mouseOver -ROUTE V44_Out.outSFVec2f TO SC.mouseOut -ROUTE V44_Click.outSFVec2f TO SC.click -ROUTE TS45.isActive TO C45_Click.activate -ROUTE TS45.isOver TO C45_Over.activate -ROUTE TS45.isOver TO C45_Out.reverseActivate -ROUTE V45_Over.outSFVec2f TO SC.mouseOver -ROUTE V45_Out.outSFVec2f TO SC.mouseOut -ROUTE V45_Click.outSFVec2f TO SC.click -ROUTE TS46.isActive TO C46_Click.activate -ROUTE TS46.isOver TO C46_Over.activate -ROUTE TS46.isOver TO C46_Out.reverseActivate -ROUTE V46_Over.outSFVec2f TO SC.mouseOver -ROUTE V46_Out.outSFVec2f TO SC.mouseOut -ROUTE V46_Click.outSFVec2f TO SC.click -ROUTE TS47.isActive TO C47_Click.activate -ROUTE TS47.isOver TO C47_Over.activate -ROUTE TS47.isOver TO C47_Out.reverseActivate -ROUTE V47_Over.outSFVec2f TO SC.mouseOver -ROUTE V47_Out.outSFVec2f TO SC.mouseOut -ROUTE V47_Click.outSFVec2f TO SC.click -ROUTE TS50.isActive TO C50_Click.activate -ROUTE TS50.isOver TO C50_Over.activate -ROUTE TS50.isOver TO C50_Out.reverseActivate -ROUTE V50_Over.outSFVec2f TO SC.mouseOver -ROUTE V50_Out.outSFVec2f TO SC.mouseOut -ROUTE V50_Click.outSFVec2f TO SC.click -ROUTE TS51.isActive TO C51_Click.activate -ROUTE TS51.isOver TO C51_Over.activate -ROUTE TS51.isOver TO C51_Out.reverseActivate -ROUTE V51_Over.outSFVec2f TO SC.mouseOver -ROUTE V51_Out.outSFVec2f TO SC.mouseOut -ROUTE V51_Click.outSFVec2f TO SC.click -ROUTE TS52.isActive TO C52_Click.activate -ROUTE TS52.isOver TO C52_Over.activate -ROUTE TS52.isOver TO C52_Out.reverseActivate -ROUTE V52_Over.outSFVec2f TO SC.mouseOver -ROUTE V52_Out.outSFVec2f TO SC.mouseOut -ROUTE V52_Click.outSFVec2f TO SC.click -ROUTE TS53.isActive TO C53_Click.activate -ROUTE TS53.isOver TO C53_Over.activate -ROUTE TS53.isOver TO C53_Out.reverseActivate -ROUTE V53_Over.outSFVec2f TO SC.mouseOver -ROUTE V53_Out.outSFVec2f TO SC.mouseOut -ROUTE V53_Click.outSFVec2f TO SC.click -ROUTE TS54.isActive TO C54_Click.activate -ROUTE TS54.isOver TO C54_Over.activate -ROUTE TS54.isOver TO C54_Out.reverseActivate -ROUTE V54_Over.outSFVec2f TO SC.mouseOver -ROUTE V54_Out.outSFVec2f TO SC.mouseOut -ROUTE V54_Click.outSFVec2f TO SC.click -ROUTE TS55.isActive TO C55_Click.activate -ROUTE TS55.isOver TO C55_Over.activate -ROUTE TS55.isOver TO C55_Out.reverseActivate -ROUTE V55_Over.outSFVec2f TO SC.mouseOver -ROUTE V55_Out.outSFVec2f TO SC.mouseOut -ROUTE V55_Click.outSFVec2f TO SC.click -ROUTE TS56.isActive TO C56_Click.activate -ROUTE TS56.isOver TO C56_Over.activate -ROUTE TS56.isOver TO C56_Out.reverseActivate -ROUTE V56_Over.outSFVec2f TO SC.mouseOver -ROUTE V56_Out.outSFVec2f TO SC.mouseOut -ROUTE V56_Click.outSFVec2f TO SC.click -ROUTE TS57.isActive TO C57_Click.activate -ROUTE TS57.isOver TO C57_Over.activate -ROUTE TS57.isOver TO C57_Out.reverseActivate -ROUTE V57_Over.outSFVec2f TO SC.mouseOver -ROUTE V57_Out.outSFVec2f TO SC.mouseOut -ROUTE V57_Click.outSFVec2f TO SC.click -ROUTE TS60.isActive TO C60_Click.activate -ROUTE TS60.isOver TO C60_Over.activate -ROUTE TS60.isOver TO C60_Out.reverseActivate -ROUTE V60_Over.outSFVec2f TO SC.mouseOver -ROUTE V60_Out.outSFVec2f TO SC.mouseOut -ROUTE V60_Click.outSFVec2f TO SC.click -ROUTE TS61.isActive TO C61_Click.activate -ROUTE TS61.isOver TO C61_Over.activate -ROUTE TS61.isOver TO C61_Out.reverseActivate -ROUTE V61_Over.outSFVec2f TO SC.mouseOver -ROUTE V61_Out.outSFVec2f TO SC.mouseOut -ROUTE V61_Click.outSFVec2f TO SC.click -ROUTE TS62.isActive TO C62_Click.activate -ROUTE TS62.isOver TO C62_Over.activate -ROUTE TS62.isOver TO C62_Out.reverseActivate -ROUTE V62_Over.outSFVec2f TO SC.mouseOver -ROUTE V62_Out.outSFVec2f TO SC.mouseOut -ROUTE V62_Click.outSFVec2f TO SC.click -ROUTE TS63.isActive TO C63_Click.activate -ROUTE TS63.isOver TO C63_Over.activate -ROUTE TS63.isOver TO C63_Out.reverseActivate -ROUTE V63_Over.outSFVec2f TO SC.mouseOver -ROUTE V63_Out.outSFVec2f TO SC.mouseOut -ROUTE V63_Click.outSFVec2f TO SC.click -ROUTE TS64.isActive TO C64_Click.activate -ROUTE TS64.isOver TO C64_Over.activate -ROUTE TS64.isOver TO C64_Out.reverseActivate -ROUTE V64_Over.outSFVec2f TO SC.mouseOver -ROUTE V64_Out.outSFVec2f TO SC.mouseOut -ROUTE V64_Click.outSFVec2f TO SC.click -ROUTE TS65.isActive TO C65_Click.activate -ROUTE TS65.isOver TO C65_Over.activate -ROUTE TS65.isOver TO C65_Out.reverseActivate -ROUTE V65_Over.outSFVec2f TO SC.mouseOver -ROUTE V65_Out.outSFVec2f TO SC.mouseOut -ROUTE V65_Click.outSFVec2f TO SC.click -ROUTE TS66.isActive TO C66_Click.activate -ROUTE TS66.isOver TO C66_Over.activate -ROUTE TS66.isOver TO C66_Out.reverseActivate -ROUTE V66_Over.outSFVec2f TO SC.mouseOver -ROUTE V66_Out.outSFVec2f TO SC.mouseOut -ROUTE V66_Click.outSFVec2f TO SC.click -ROUTE TS67.isActive TO C67_Click.activate -ROUTE TS67.isOver TO C67_Over.activate -ROUTE TS67.isOver TO C67_Out.reverseActivate -ROUTE V67_Over.outSFVec2f TO SC.mouseOver -ROUTE V67_Out.outSFVec2f TO SC.mouseOut -ROUTE V67_Click.outSFVec2f TO SC.click -ROUTE TS70.isActive TO C70_Click.activate -ROUTE TS70.isOver TO C70_Over.activate -ROUTE TS70.isOver TO C70_Out.reverseActivate -ROUTE V70_Over.outSFVec2f TO SC.mouseOver -ROUTE V70_Out.outSFVec2f TO SC.mouseOut -ROUTE V70_Click.outSFVec2f TO SC.click -ROUTE TS71.isActive TO C71_Click.activate -ROUTE TS71.isOver TO C71_Over.activate -ROUTE TS71.isOver TO C71_Out.reverseActivate -ROUTE V71_Over.outSFVec2f TO SC.mouseOver -ROUTE V71_Out.outSFVec2f TO SC.mouseOut -ROUTE V71_Click.outSFVec2f TO SC.click -ROUTE TS72.isActive TO C72_Click.activate -ROUTE TS72.isOver TO C72_Over.activate -ROUTE TS72.isOver TO C72_Out.reverseActivate -ROUTE V72_Over.outSFVec2f TO SC.mouseOver -ROUTE V72_Out.outSFVec2f TO SC.mouseOut -ROUTE V72_Click.outSFVec2f TO SC.click -ROUTE TS73.isActive TO C73_Click.activate -ROUTE TS73.isOver TO C73_Over.activate -ROUTE TS73.isOver TO C73_Out.reverseActivate -ROUTE V73_Over.outSFVec2f TO SC.mouseOver -ROUTE V73_Out.outSFVec2f TO SC.mouseOut -ROUTE V73_Click.outSFVec2f TO SC.click -ROUTE TS74.isActive TO C74_Click.activate -ROUTE TS74.isOver TO C74_Over.activate -ROUTE TS74.isOver TO C74_Out.reverseActivate -ROUTE V74_Over.outSFVec2f TO SC.mouseOver -ROUTE V74_Out.outSFVec2f TO SC.mouseOut -ROUTE V74_Click.outSFVec2f TO SC.click -ROUTE TS75.isActive TO C75_Click.activate -ROUTE TS75.isOver TO C75_Over.activate -ROUTE TS75.isOver TO C75_Out.reverseActivate -ROUTE V75_Over.outSFVec2f TO SC.mouseOver -ROUTE V75_Out.outSFVec2f TO SC.mouseOut -ROUTE V75_Click.outSFVec2f TO SC.click -ROUTE TS76.isActive TO C76_Click.activate -ROUTE TS76.isOver TO C76_Over.activate -ROUTE TS76.isOver TO C76_Out.reverseActivate -ROUTE V76_Over.outSFVec2f TO SC.mouseOver -ROUTE V76_Out.outSFVec2f TO SC.mouseOut -ROUTE V76_Click.outSFVec2f TO SC.click -ROUTE TS77.isActive TO C77_Click.activate -ROUTE TS77.isOver TO C77_Over.activate -ROUTE TS77.isOver TO C77_Out.reverseActivate -ROUTE V77_Over.outSFVec2f TO SC.mouseOver -ROUTE V77_Out.outSFVec2f TO SC.mouseOut -ROUTE V77_Click.outSFVec2f TO SC.click diff --git a/regression_tests/bifs-interpolation-colorinterpolator.bt b/regression_tests/bifs-interpolation-colorinterpolator.bt deleted file mode 100644 index 9dbc4aa..0000000 --- a/regression_tests/bifs-interpolation-colorinterpolator.bt +++ /dev/null @@ -1,63 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 240 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows color interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Color Interpolator" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - DEF TS TimeSensor { - loop TRUE - } - DEF SI ColorInterpolator { - key [0 0.5 1] - keyValue [1 0 0 0 1 0 1 0 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -DEF R1 ROUTE SI.value_changed TO MAT.emissiveColor - diff --git a/regression_tests/bifs-interpolation-coordinateinterpolator2D.bt b/regression_tests/bifs-interpolation-coordinateinterpolator2D.bt deleted file mode 100644 index c511964..0000000 --- a/regression_tests/bifs-interpolation-coordinateinterpolator2D.bt +++ /dev/null @@ -1,64 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows scaling interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Position Interpolator" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF SI CoordinateInterpolator2D { - key [0 0.25 0.5 0.75 1] - keyValue [-100 0 -50 100 50 100 100 0 50 -100 -50 -100 100 0 -50 100 50 100 -100 0 50 -100 -50 -100 -100 0 -50 100 50 100 100 0 50 -100 -50 -100 -100 0 50 100 -50 100 100 0 -50 -100 50 -100 -100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO COORD.point - diff --git a/regression_tests/bifs-interpolation-positionanimator.bt b/regression_tests/bifs-interpolation-positionanimator.bt deleted file mode 100644 index e8d378c..0000000 --- a/regression_tests/bifs-interpolation-positionanimator.bt +++ /dev/null @@ -1,63 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0x01 - sceneProfileLevelIndication 0x01 - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFE - graphicsProfileLevelIndication 0x01 - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 200 - } - } - } - ] -} - -Group { - children [ - Viewpoint {position 0 0 100 } - WorldInfo { - title "PositionAnimator test" - info ["This shows PositionAnimator using bezier spline interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - DEF BACK Background2D { backColor 1 1 1} - DEF TR Transform { - scale 0.5 0.5 0.5 - rotation 1 1 1 0.75 - children [ - Shape { - appearance Appearance { material DEF MAT Material { diffuseColor 1 0 0} } - geometry Box {size 50 50 50} - } - ] - } - DEF TS TimeSensor { - cycleInterval 4.0 - loop TRUE - } - DEF V Valuator { - Factor2 0 - Offset2 0.5 - } - DEF SI PositionAnimator { - key [0 0.25 0.5 0.75 1] - - keyValueType 1 - keyValue [-50 0 -50, 0 50 0, 50 0 -50] - keyType 4 - keySpline [0.75 0, 0.25 1] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -DEF R1 ROUTE SI.value_changed TO TR.translation diff --git a/regression_tests/bifs-interpolation-positionanimator2D.bt b/regression_tests/bifs-interpolation-positionanimator2D.bt deleted file mode 100644 index 3421b46..0000000 --- a/regression_tests/bifs-interpolation-positionanimator2D.bt +++ /dev/null @@ -1,65 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0x01 - sceneProfileLevelIndication 0x01 - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFE - graphicsProfileLevelIndication 0x01 - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - title "PositionAnimator2D test" - info ["This shows PositionAnimator2D using bezier spline interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - DEF BACK Background2D { backColor 1 1 1} - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { material DEF MAT Material2D { emissiveColor 1 0 0 filled TRUE } } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0, -50 100, 50 100, 100 0, 50 -100, -50 -100] - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 4.0 - loop TRUE - } - DEF V Valuator { - Factor2 0 - Offset2 0.5 - } - DEF SI PositionAnimator2D { - key [0 0.25 0.5 0.75 1] - - keyValueType 1 - keyValue [-50 0 0 50 50 0] - keyType 4 - keySpline [0.75 0, 0.25 1] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -DEF R1 ROUTE SI.value_changed TO TR.translation diff --git a/regression_tests/bifs-interpolation-positioninterpolator-position.bt b/regression_tests/bifs-interpolation-positioninterpolator-position.bt deleted file mode 100644 index 273548a..0000000 --- a/regression_tests/bifs-interpolation-positioninterpolator-position.bt +++ /dev/null @@ -1,94 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - NavigationInfo {type ["ANY" "EXAMINE"]} - WorldInfo { - info ["This shows position interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "PositionInterpolator" - } - Transform { - children [ - Shape { - appearance Appearance { - texture MovieTexture { - loop TRUE - url [od:10] - } - } - geometry Box { - size 100 100 100 - } - } - ] - } - DEF TR Transform { - children [ - Shape { - appearance Appearance { - material Material {diffuseColor 0 1 0 } - } - geometry Box { - size 100 100 100 - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 10 - loop TRUE - } - DEF SI PositionInterpolator { - key [0 0.25 0.5 0.75 1] - keyValue [100 100 100, -100 100 -100, -100 -100 -100, 100 -100 100, 100 100 100] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO TR.translation - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-interpolation-positioninterpolator-size.bt b/regression_tests/bifs-interpolation-positioninterpolator-size.bt deleted file mode 100644 index a56ed3e..0000000 --- a/regression_tests/bifs-interpolation-positioninterpolator-size.bt +++ /dev/null @@ -1,58 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -Group { - children [ - WorldInfo { - info ["This shows 3D size interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "PositionInterpolator" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform { - scale 0.5 0.5 0.5 - rotation 1 1 1 0.75 - children [ - Shape { - appearance Appearance { - material DEF MAT Material {diffuseColor 1 0 0 } - } - geometry Box {size 100 100 50} - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF SI PositionInterpolator { - key [0 0.25 0.5 0.75 1] - keyValue [1 1 1, 1 2 0.25, 1 1 1, 2 1 1.75, 1 1 1] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO TR.scale - diff --git a/regression_tests/bifs-interpolation-positioninterpolator2D-position.bt b/regression_tests/bifs-interpolation-positioninterpolator2D-position.bt deleted file mode 100644 index 4971f01..0000000 --- a/regression_tests/bifs-interpolation-positioninterpolator2D-position.bt +++ /dev/null @@ -1,96 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows 2D position interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "PositionInterpolator2D" - } - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - texture MovieTexture { - loop TRUE - url [od:10] - } - } - geometry Rectangle { - size 100 100 - } - } - ] - } - DEF TR2 Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 10 - loop TRUE - } - DEF SI PositionInterpolator2D { - key [0 0.25 0.5 0.75 1] - keyValue [100 100 -100 100 -100 -100 100 -100 100 100] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO TR2.translation - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-interpolation-positioninterpolator2D-size.bt b/regression_tests/bifs-interpolation-positioninterpolator2D-size.bt deleted file mode 100644 index 814650b..0000000 --- a/regression_tests/bifs-interpolation-positioninterpolator2D-size.bt +++ /dev/null @@ -1,64 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows 2D size interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "PositionInterpolator2D" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - DEF SI PositionInterpolator2D { - key [0 0.25 0.5 0.75 1] - keyValue [1 1 2 1 1 1 1 2 1 1] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO TR.scale - diff --git a/regression_tests/bifs-interpolation-scalaranimator.bt b/regression_tests/bifs-interpolation-scalaranimator.bt deleted file mode 100644 index f1203b5..0000000 --- a/regression_tests/bifs-interpolation-scalaranimator.bt +++ /dev/null @@ -1,66 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0x01 - sceneProfileLevelIndication 0x01 - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFE - graphicsProfileLevelIndication 0x01 - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - title "ScalarAnimator test" - info ["This shows ScalarAnimator using bezier spline interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - DEF BACK Background2D { backColor 1 1 1} - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { material DEF MAT Material2D { emissiveColor 1 0 0 filled TRUE } } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0, -50 100, 50 100, 100 0, 50 -100, -50 -100] - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 4.0 - loop TRUE - } - DEF V Valuator { - Factor2 0 - Offset2 0.5 - } - DEF SI ScalarAnimator { -# key [0 0.25 0.5 0.75 1] - - keyValueType 2 - keyValue [0.5 0.0 1 0.5] - keyType 2 - keySpline [0.4 0.5, 0.15 0.15] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -DEF R1 ROUTE SI.value_changed TO V.inSFFloat -ROUTE V.outSFVec2f TO TR.scale diff --git a/regression_tests/bifs-interpolation-scalarinterpolator.bt b/regression_tests/bifs-interpolation-scalarinterpolator.bt deleted file mode 100644 index 1785d39..0000000 --- a/regression_tests/bifs-interpolation-scalarinterpolator.bt +++ /dev/null @@ -1,63 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This shows transparency interpolation" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Scalar Interpolator" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - DEF TS TimeSensor { - loop TRUE - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -DEF R1 ROUTE SI.value_changed TO MAT.transparency - diff --git a/regression_tests/bifs-interpolation-timesensor-enabled.bt b/regression_tests/bifs-interpolation-timesensor-enabled.bt deleted file mode 100644 index 894a3ed..0000000 --- a/regression_tests/bifs-interpolation-timesensor-enabled.bt +++ /dev/null @@ -1,82 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of timesensor" "with enabling/disabling" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "TimeSensor enabled test" - } - Transform2D { - translation -100 0 - children [ - DEF N3 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Rectangle { - size 80 80 - } - } - ] - } - DEF N2 TimeSensor { - cycleInterval 10 - enabled FALSE - loop TRUE - stopTime -1 - } - DEF N0 PositionInterpolator2D { - key [0 1] - keyValue [100 -100 100 100] - } - DEF N4 Transform2D { - translation 100 -100 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 0.5 0.5 - filled TRUE - } - } - geometry Rectangle { - size 80 80 - } - } - ] - } - ] -} - -ROUTE N3.isOver TO N2.enabled -ROUTE N2.fraction_changed TO N0.set_fraction -ROUTE N0.value_changed TO N4.translation - diff --git a/regression_tests/bifs-interpolation-timesensor-starttime_norestart.bt b/regression_tests/bifs-interpolation-timesensor-starttime_norestart.bt deleted file mode 100644 index 1ca29b2..0000000 --- a/regression_tests/bifs-interpolation-timesensor-starttime_norestart.bt +++ /dev/null @@ -1,81 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of timesensor start time" "Animation shall not be restartable until over" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "TimeSensor startTime test" - } - Transform2D { - translation -100 0 - children [ - DEF N3 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Rectangle { - size 80 80 - } - } - ] - } - DEF N2 TimeSensor { - cycleInterval 2 - startTime 2 - stopTime -1 - } - DEF N0 PositionInterpolator2D { - key [0 1] - keyValue [100 -100 100 100] - } - DEF N4 Transform2D { - translation 100 -100 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 0.5 0.5 - filled TRUE - } - } - geometry Rectangle { - size 80 80 - } - } - ] - } - ] -} - -ROUTE N3.touchTime TO N2.startTime -ROUTE N2.fraction_changed TO N0.set_fraction -ROUTE N0.value_changed TO N4.translation - diff --git a/regression_tests/bifs-interpolation-timesensor-starttime_restart.bt b/regression_tests/bifs-interpolation-timesensor-starttime_restart.bt deleted file mode 100644 index ff0912f..0000000 --- a/regression_tests/bifs-interpolation-timesensor-starttime_restart.bt +++ /dev/null @@ -1,82 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of timesensor start time" "Animation can be restarted even if not over" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "TimeSensor startTime test" - } - Transform2D { - translation -100 0 - children [ - DEF N3 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Rectangle { - size 80 80 - } - } - ] - } - DEF N2 TimeSensor { - cycleInterval 2 - startTime 2 - stopTime -1 - } - DEF N0 PositionInterpolator2D { - key [0 1] - keyValue [100 -100 100 100] - } - DEF N4 Transform2D { - translation 100 -100 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 0.5 0.5 - filled TRUE - } - } - geometry Rectangle { - size 80 80 - } - } - ] - } - ] -} - -ROUTE N3.touchTime TO N2.stopTime -ROUTE N3.touchTime TO N2.startTime -ROUTE N2.fraction_changed TO N0.set_fraction -ROUTE N0.value_changed TO N4.translation - diff --git a/regression_tests/bifs-interpolation-valuator-sftime.bt b/regression_tests/bifs-interpolation-valuator-sftime.bt deleted file mode 100644 index ac679a9..0000000 --- a/regression_tests/bifs-interpolation-valuator-sftime.bt +++ /dev/null @@ -1,58 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage Valuator" "with SFTime to SFString formatting" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Valuator Test" - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - fontStyle DEF FONT FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - DEF V Valuator { - } - DEF TS TimeSensor { - cycleInterval 2 - loop TRUE - } - ] -} - -ROUTE TS.time TO V.inSFTime -ROUTE V.outMFString TO TXT.string - diff --git a/regression_tests/bifs-linking-anchor-mp4-next.bt b/regression_tests/bifs-linking-anchor-mp4-next.bt deleted file mode 100644 index c7cc4a0..0000000 --- a/regression_tests/bifs-linking-anchor-mp4-next.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D { - backColor 1 0 1 - } - WorldInfo { - info ["This shows Anchor with MP4 hyperlinking" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Anchor Test" - } - Anchor { - url ["bifs-linking-anchor-mp4-prev.mp4"] - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Rectangle { - size 200 150 - } - } - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Click here to open" "prev.mp4"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-linking-anchor-mp4-prev.bt b/regression_tests/bifs-linking-anchor-mp4-prev.bt deleted file mode 100644 index 859fa60..0000000 --- a/regression_tests/bifs-linking-anchor-mp4-prev.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D { - backColor 0 1 1 - } - WorldInfo { - info ["This shows Anchor with MP4 hyperlinking" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Anchor Test" - } - Anchor { - url ["bifs-linking-anchor-mp4-next.mp4"] - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 100 - } - } - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Click here to open" "next.mp4"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-linking-anchor-viewpoint.bt b/regression_tests/bifs-linking-anchor-viewpoint.bt deleted file mode 100644 index fe2142f..0000000 --- a/regression_tests/bifs-linking-anchor-viewpoint.bt +++ /dev/null @@ -1,92 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 200 - pixelHeight 200 - } - } - } - ] -} - -Group { - children [ - WorldInfo { - title "Anchor and Viewpoints test" - info ["This shows anchors triggering viewpoint binding" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - - DEF VP1 Viewpoint {description "Front View" position 0 0 300} - DEF VP2 Viewpoint {description "Above View" position 0 300 30 orientation 1 0 0 -1.2 } - - DEF TR Transform { - translation 50 0 0 - children [ - Anchor { - url "#VP2" - children [ - Shape { - appearance Appearance { - material Material { - diffuseColor 0 1 1 - } - } - geometry DEF BOX Box {size 50 50 50} - } - ] - } - ] - } - - Transform { - translation -80 0 20 - children [ - Shape { - appearance Appearance { - material Material2D { emissiveColor 1 0 0 filled TRUE } - } - geometry DEF RC_RED Rectangle {size 100 100} - } - ] - } - - Anchor { - url "bifs-3D-viewpoint-bind.mp4#VP2" - children [ - Shape { - appearance Appearance { - material Material2D { emissiveColor 1 1 1 filled TRUE } - } - geometry DEF RC_WHITE Rectangle { size 200 200 } - } - ] - } - - Transform { - translation -30 0 0 - children [ - Shape { - appearance Appearance { - material DEF MAT Material { - diffuseColor 1 1 0 - } - } - geometry DEF SPHERE Sphere {radius 30} - } - ] - } - ] -} diff --git a/regression_tests/bifs-linking-anchor-www.bt b/regression_tests/bifs-linking-anchor-www.bt deleted file mode 100644 index 56b42ff..0000000 --- a/regression_tests/bifs-linking-anchor-www.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 255 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - DEF B1 Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Anchor with WWW hyperlinking" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Anchor Test" - } - Anchor { - url ["http://www.chiariglione.org/mpeg/"] - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 200 100 - } - } - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Click here to go" "to MPEG Web Site"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-linking-animationstream.bt b/regression_tests/bifs-linking-animationstream.bt deleted file mode 100644 index e0a5369..0000000 --- a/regression_tests/bifs-linking-animationstream.bt +++ /dev/null @@ -1,136 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - includeInlineProfileLevelFlag true - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows an AnimationStream node" "using a BIFS-command stream" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Animation Stream" - } - DEF N0 Transform2D { - translation 100 0 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 100 100 - } - } - ] - } - AnimationStream { - loop TRUE - url [od:10] - } - Transform2D { - translation 0 -100 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Position modified" "through animationStream"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] -} - - -RAP AT 0 IN 5 { - REPLACE N0.translation BY 100 0 -} - -RAP AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 5 - dependsOn_ES_ID 1 - OCR_ES_ID 5 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - nodeIDbits 1 - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - slConfigDescr SLConfigDescriptor { - useAccessUnitStartFlag true - useAccessUnitEndFlag true - useTimeStampsFlag true - timeStampResolution 1000 - OCRResolution 1000 - timeStampLength 32 - } - } - ] - } - ] -} - -RAP AT 500 IN 5 { - REPLACE N0.translation BY 100 100 -} - -RAP AT 1000 IN 5 { - REPLACE N0.translation BY -100 100 -} - -RAP AT 1500 IN 5 { - REPLACE N0.translation BY -100 0 -} - -RAP AT 2000 IN 5 { - REPLACE N0.translation BY 100 0 -} - diff --git a/regression_tests/bifs-linking-inline-direct-inline.bt b/regression_tests/bifs-linking-inline-direct-inline.bt deleted file mode 100644 index fcebe9c..0000000 --- a/regression_tests/bifs-linking-inline-direct-inline.bt +++ /dev/null @@ -1,75 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["Inlined scene with planeSensor2D" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Inline Test" - } - Background2D { - backColor 1 1 0 - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Circle { - radius 100 - } - } - ] - } - Transform2D { - children [ - DEF T1 Transform2D { - children [ - DEF PS PlaneSensor2D { - maxPosition 150 150 - minPosition -150 -150 - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 0.6 0.4 - filled TRUE - } - } - geometry DEF REC Rectangle { - size 50 100 - } - } - ] - } - ] - } - ] -} - -ROUTE PS.translation_changed TO T1.translation - diff --git a/regression_tests/bifs-linking-inline-direct.bt b/regression_tests/bifs-linking-inline-direct.bt deleted file mode 100644 index 4884329..0000000 --- a/regression_tests/bifs-linking-inline-direct.bt +++ /dev/null @@ -1,51 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 0 - } - WorldInfo { - info ["This shows usage of the inline node" "with rotation and scaling on the inlined scene" "Inline scene is referenced without OD" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Inline Test" - } - Transform2D { - rotationAngle 0.78 - scale 1.5 1 - children [ - Inline { - url ["bifs-linking-inline-direct-inline.mp4"] - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-linking-inline-od-inline.bt b/regression_tests/bifs-linking-inline-od-inline.bt deleted file mode 100644 index 91cc6c9..0000000 --- a/regression_tests/bifs-linking-inline-od-inline.bt +++ /dev/null @@ -1,76 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["Inlined scene with planeSensor2D" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Inline Test" - } - - Background2D { - backColor 1 1 0 - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Circle { - radius 100 - } - } - ] - } - Transform2D { - children [ - DEF T1 Transform2D { - children [ - DEF PS PlaneSensor2D { - maxPosition 150 150 - minPosition -150 -150 - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0.5 0.6 0.4 - filled TRUE - } - } - geometry DEF REC Rectangle { - size 50 100 - } - } - ] - } - ] - } - ] -} - -ROUTE PS.translation_changed TO T1.translation - diff --git a/regression_tests/bifs-linking-inline-od.bt b/regression_tests/bifs-linking-inline-od.bt deleted file mode 100644 index fac7d66..0000000 --- a/regression_tests/bifs-linking-inline-od.bt +++ /dev/null @@ -1,60 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of the inline node" "with rotation and scaling on the inlined scene" "Inline scene is referenced through an OD" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Inline Test" - } - Transform2D { - rotationAngle 0.78 - scale 1.5 1 - children [ - Inline { - url [od:8] - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - URLstring "bifs-linking-inline-od-inline.mp4" - } - ] -} - diff --git a/regression_tests/bifs-linking-inline-rtsp-no-od.bt b/regression_tests/bifs-linking-inline-rtsp-no-od.bt deleted file mode 100644 index d9f3c14..0000000 --- a/regression_tests/bifs-linking-inline-rtsp-no-od.bt +++ /dev/null @@ -1,48 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of the inline node" "using remote (rtsp) scene for inline" "Inline scene is referenced with OD" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Inline Test" - } - Transform2D { - children [ - Inline { - url ["rtsp://a1749.q.kamai.net/7/1749/1416/3c964c64/neo.qtv.apple.com/secure/may/preview/classic_cars_300.mp4"] - } - ] - } - ] -} - diff --git a/regression_tests/bifs-linking-inline-rtsp.bt b/regression_tests/bifs-linking-inline-rtsp.bt deleted file mode 100644 index 91eb29c..0000000 --- a/regression_tests/bifs-linking-inline-rtsp.bt +++ /dev/null @@ -1,59 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of the inline node" "using remote (rtsp) scene for inline" "Inline scene is referenced with OD" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.5 $" "(C) 2002-2004 GPAC Team"] - title "Inline Test" - } - Transform2D { - children [ - Inline { - url [od:8] - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 -# URLstring "rtsp://a1749.q.kamai.net/7/1749/1416/3c964c64/neo.qtv.apple.com/secure/may/preview/civ3_700.mp4" - URLstring "rtsp://kara/bhusa.mp4" - } - ] -} - diff --git a/regression_tests/bifs-linking-inline-segment-inline.bt b/regression_tests/bifs-linking-inline-segment-inline.bt deleted file mode 100644 index bcc6c16..0000000 --- a/regression_tests/bifs-linking-inline-segment-inline.bt +++ /dev/null @@ -1,74 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] - ociDescr [ - SegmentDescriptor { startTime 0 duration 4 name "Begin" } - SegmentDescriptor { startTime 4 duration 2 name "Middle" } - SegmentDescriptor { startTime 6 duration 4 name "End" } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of MediaSensor" "with media segments defined" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Sensor Test #2" - } - Shape { - appearance Appearance { - texture DEF MOV MovieTexture { - loop TRUE - stopTime -1 - url [od:8] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap {} - } - ] -} - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-linking-inline-segment.bt b/regression_tests/bifs-linking-inline-segment.bt deleted file mode 100644 index afbd4e8..0000000 --- a/regression_tests/bifs-linking-inline-segment.bt +++ /dev/null @@ -1,41 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of the inline node" "with rotation and scaling on the inlined scene" "Inline scene is referenced through an OD" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Inline Test" - } - Transform2D { - children [ - Inline { - url ["bifs-linking-inline-segment-inline.mp4#Middle"] - } - ] - } - ] -} diff --git a/regression_tests/bifs-media-audiobuffer.bt b/regression_tests/bifs-media-audiobuffer.bt deleted file mode 100644 index 57d868c..0000000 --- a/regression_tests/bifs-media-audiobuffer.bt +++ /dev/null @@ -1,203 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - objectTypeIndication 1 - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - OCR_ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows audiobuffer" "with loop and pitch" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "AudioBuffer Test" - } - Sound2D { - source DEF AUDBUF AudioBuffer { - loop TRUE - numChan 2 - length 2 - children [ - AudioSource { - url [od:10] - stopTime -1 - } - ] - } - } - Transform2D { - translation 0 -50 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 100 50 - } - } - Shape { - appearance DEF TXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["restart"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 16 - } - } - } - DEF TS1 TouchSensor {} - ] - } - DEF C1 Conditional { - buffer { - REPLACE AUDBUF.stopTime BY 0 - REPLACE AUDBUF.startTime BY 0 - } - } - Transform2D { - translation -100 50 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 1 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE TXTAPP - geometry Text { - string ["pitch" "0.5"] - fontStyle USE FS - } - } - DEF TS2 TouchSensor {} - ] - } - Transform2D { - translation 0 50 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE TXTAPP - geometry Text { - string ["pitch" "1.0"] - fontStyle USE FS - } - } - DEF TS3 TouchSensor {} - ] - } - Transform2D { - translation 100 50 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE TXTAPP - geometry Text { - string ["pitch" "2"] - fontStyle USE FS - } - } - DEF TS4 TouchSensor {} - ] - } - DEF C2 Conditional { - buffer { - REPLACE AUDBUF.pitch BY 0.5 - } - } - DEF C3 Conditional { - buffer { - REPLACE AUDBUF.pitch BY 1 - } - } - DEF C4 Conditional { - buffer { - REPLACE AUDBUF.pitch BY 2 - } - } - ] -} - -ROUTE TS1.isActive TO C1.activate -ROUTE TS2.isActive TO C2.activate -ROUTE TS3.isActive TO C3.activate -ROUTE TS4.isActive TO C4.activate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_audio.aac" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-audioclip-urlchanged.bt b/regression_tests/bifs-media-audioclip-urlchanged.bt deleted file mode 100644 index 7b93a75..0000000 --- a/regression_tests/bifs-media-audioclip-urlchanged.bt +++ /dev/null @@ -1,145 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows AudioClip" "and direct modification of URL" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "AudioClip Test" - } - DEF SD Sound2D { - source DEF AS AudioClip { - loop TRUE - url [od:20] - } - } - Transform2D { - translation -50 0 - children [ - DEF TS1 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Sound1"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE AS.url BY ["od:20"] - } - } - Transform2D { - translation 50 0 - children [ - DEF TS2 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE APP - geometry Text { - string ["Sound2"] - fontStyle USE FS - } - } - ] - } - DEF C2 Conditional { - buffer { - REPLACE AS.url BY ["od:10"] - } - } - ] -} - -ROUTE TS1.isActive TO C1.activate -ROUTE TS2.isActive TO C2.activate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_german.mp3" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 20 - esDescr [ - ES_Descriptor { - ES_ID 21 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/count_arabic.mp3" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-audioclip.bt b/regression_tests/bifs-media-audioclip.bt deleted file mode 100644 index b4d14b2..0000000 --- a/regression_tests/bifs-media-audioclip.bt +++ /dev/null @@ -1,133 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows AudioClip" "controled through startTime and stopTime" "audio clock is independent from BIFS clock, thus audio restarts from begining" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "AudioClip Test" - } - DEF SD Sound2D { - source DEF AS AudioClip { - loop TRUE - url [od:10] - } - } - Transform2D { - translation -50 0 - children [ - DEF TS1 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Stop"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE AS.stopTime BY 0 - } - } - Transform2D { - translation 50 0 - children [ - DEF TS2 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE APP - geometry Text { - string ["Start"] - fontStyle USE FS - } - } - ] - } - DEF C2 Conditional { - buffer { - REPLACE AS.startTime BY 0 - } - } - ] -} - -ROUTE TS1.isActive TO C1.activate -ROUTE TS2.isActive TO C2.activate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_audio.aac" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-audiosource-mixing.bt b/regression_tests/bifs-media-audiosource-mixing.bt deleted file mode 100644 index 8a9c861..0000000 --- a/regression_tests/bifs-media-audiosource-mixing.bt +++ /dev/null @@ -1,194 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -PROTO AudioControler [ - exposedField MFString the_url [] - exposedField MFString comment [] - exposedField SFVec2f position 0 0 - exposedField SFColor color 0 0 0 - exposedField SFFloat vol 1.0 - exposedField SFInt32 numChannels 2 -] { - Transform2D { - translation IS position - children [ - Transform2D { - children [ - Shape { - appearance Appearance { material Material2D {emissiveColor IS color filled TRUE} } - geometry Rectangle { size 200 20 } - } - DEF TS TouchSensor {} - ] - } - Transform2D { - translation -120 0 - children [ - Shape { - appearance DEF TXTAPP Appearance { material DEF MAT Material2D {emissiveColor 0 0 0 filled TRUE} } - geometry DEF TXT Text { string ["volume", "0"] fontStyle DEF FS FontStyle { size 12 justify ["MIDDLE"]} } - } - - ] - } - Transform2D { - translation 0 20 - children [ - Shape { - appearance USE TXTAPP - geometry Text { string IS comment fontStyle USE FS} - } - - ] - } - DEF SND Sound2D { - intensity IS vol - source AudioSource { - url IS the_url - startTime 0 - numChan IS numChannels - } - } - MediaControl { - url IS the_url - loop TRUE - } - ] - } - DEF SC Script { - eventIn SFVec3f set_frac - eventIn SFBool set_down - field SFNode s USE SND - field SFNode t USE TXT - field SFBool isDown FALSE - url ["javascript: - function initialize() { - t.string[1] = '' + s.intensity; - } - function set_down(value, timestamp) {isDown = value;} - function set_frac(value, timestamp) { - if (!isDown) return; - pos = (value.x + 100)/200; - s.intensity = pos; - t.string[1] = '' + pos; - } - " - ] - } - ROUTE TS.isActive TO SC.set_down - ROUTE TS.hitPoint_changed TO SC.set_frac - -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows MediaControl" "controling audio playback speed" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - - AudioControler { - position 0 100 - color 1 0 0 - the_url ["od:10"] - numChannels 2 - vol 1 - comment ["Audio #1 - running on its own timeline"] - } - AudioControler { - position 0 33 - color 0 1 0 - the_url ["od:11"] - numChannels 2 - vol 0 - comment ["Audio #2 - running on its own timeline"] - } - AudioControler { - position 0 -33 - color 0 0 1 - the_url ["od:11"] - numChannels 2 - vol 0 - comment ["Audio #3 reusing Audio #2 object"] - } - AudioControler { - position 0 -100 - color 1 0 1 - the_url ["od:12"] - numChannels 2 - vol 0 - comment ["Audio #4 - running on Audio #2 timeline"] - } - ] -} - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 10 - OCR_ES_ID 10 - muxInfo MuxInfo { - fileName "auxiliary_files/count_english.mp3" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 11 - esDescr [ - ES_Descriptor { - ES_ID 11 - OCR_ES_ID 11 - muxInfo MuxInfo { - fileName "auxiliary_files/count_english.mp3" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 12 - esDescr [ - ES_Descriptor { - ES_ID 12 - OCR_ES_ID 11 - muxInfo MuxInfo { - fileName "auxiliary_files/count_english.mp3" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-audiosource-urlchanged.bt b/regression_tests/bifs-media-audiosource-urlchanged.bt deleted file mode 100644 index 31c7514..0000000 --- a/regression_tests/bifs-media-audiosource-urlchanged.bt +++ /dev/null @@ -1,146 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows AudioSource" "and direct modification of URL" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "AudioSource Test" - } - DEF SD Sound2D { - source DEF AS AudioSource { - url [od:20] - } - } - Transform2D { - translation -50 0 - children [ - DEF TS1 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Sound1"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE AS.startTime BY 0 - REPLACE AS.url BY ["od:20"] - } - } - Transform2D { - translation 50 0 - children [ - DEF TS2 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE APP - geometry Text { - string ["Sound2"] - fontStyle USE FS - } - } - ] - } - DEF C2 Conditional { - buffer { - REPLACE AS.startTime BY 0 - REPLACE AS.url BY ["od:10"] - } - } - ] -} - -ROUTE TS1.isActive TO C1.activate -ROUTE TS2.isActive TO C2.activate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_english.mp3" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 20 - esDescr [ - ES_Descriptor { - ES_ID 21 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/count_french.mp3" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-audiosource.bt b/regression_tests/bifs-media-audiosource.bt deleted file mode 100644 index f4284b3..0000000 --- a/regression_tests/bifs-media-audiosource.bt +++ /dev/null @@ -1,133 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows AudioSource" "controled through startTime and stopTime" "audio clock is independent from BIFS clock, thus audio restarts from begining" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "AudioSource Test" - } - DEF SD Sound2D { - source DEF AS AudioSource { - url [od:10] - stopTime 4 - } - } - Transform2D { - translation -50 0 - children [ - DEF TS1 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Stop"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE AS.stopTime BY 0 - } - } - Transform2D { - translation 50 0 - children [ - DEF TS2 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE APP - geometry Text { - string ["Start"] - fontStyle USE FS - } - } - ] - } - DEF C2 Conditional { - buffer { - REPLACE AS.startTime BY 0 - } - } - ] -} - -ROUTE TS1.isActive TO C1.activate -ROUTE TS2.isActive TO C2.activate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_italian.mp3" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-imagetexture-OD-reuse.bt b/regression_tests/bifs-media-imagetexture-OD-reuse.bt deleted file mode 100644 index ab62590..0000000 --- a/regression_tests/bifs-media-imagetexture-OD-reuse.bt +++ /dev/null @@ -1,89 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows two ImageTexture nodes" "using the same OD" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Image Texture test" - } - Transform2D { - translation -80 0 - children [ - Shape { - appearance Appearance { - texture ImageTexture { - url [od:10] - } - } - geometry Rectangle { - size 100 50 - } - } - ] - } - Transform2D { - translation 80 0 - children [ - Shape { - appearance Appearance { - material Material2D { filled TRUE transparency 0.5 } - texture ImageTexture { - url [od:10] - } - } - geometry Circle { - radius 50 - } - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-imagetexture-no-od.bt b/regression_tests/bifs-media-imagetexture-no-od.bt deleted file mode 100644 index 1b0f32c..0000000 --- a/regression_tests/bifs-media-imagetexture-no-od.bt +++ /dev/null @@ -1,60 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 254 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 254 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 0 1 - } - WorldInfo { - info [ - "This test shows how a URL in an ImageTexture node can be a regular URL (http, file, ...) and not an OD URL." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" - "(C) 2002-2006 GPAC Team" - ] - title "Image referenced by a non-OD URL" - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF TXT ImageTexture { - url ["auxiliary_files/logo.jpg"] - } - } - geometry Bitmap {} - - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-media-imagetexture-object-scale.bt b/regression_tests/bifs-media-imagetexture-object-scale.bt deleted file mode 100644 index 2950755..0000000 --- a/regression_tests/bifs-media-imagetexture-object-scale.bt +++ /dev/null @@ -1,97 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 440 - pixelHeight 440 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows image texture" "with object scaling and texture transform" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Image Texture Test" - } - DEF TR Transform2D { - rotationAngle 0.78 - children [ - Shape { - geometry IndexedLineSet2D { - coord Coordinate2D { - point [0 200 0 -200] - } - } - } - Shape { - appearance Appearance { - texture ImageTexture { - url [od:10] - } - textureTransform DEF TX TextureTransform { - translation 0 0.5 - } - } - geometry Rectangle { - size 200 200 - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 4 - loop TRUE - } - DEF PI PositionInterpolator2D { - key [0 0.5 1] - keyValue [-0.5 -0.5 0.5 0.5 -0.5 -0.5] - } - DEF SI PositionInterpolator2D { - key [0 0.5 1] - keyValue [0.5 0.5 1.5 1.5 0.5 0.5] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO TR.scale - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-imagetexture-transparent.bt b/regression_tests/bifs-media-imagetexture-transparent.bt deleted file mode 100644 index cc59870..0000000 --- a/regression_tests/bifs-media-imagetexture-transparent.bt +++ /dev/null @@ -1,275 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 440 - pixelHeight 440 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 0 1 1 - } - WorldInfo { - info ["This shows basic 2D shapes" "with transparent image texture mapping" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Image Texture Test" - } - Transform2D { - translation -150 150 - children [ - Shape { - appearance DEF APP Appearance { - texture ImageTexture { - url [od:10] - } - } - geometry IndexedLineSet2D { - coord Coordinate2D { - point [-50 0 0 50 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["IndexedLineSet2D" "[-50 0 0 50 50 0]"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 12 - } - } - } - ] - } - ] - } - Transform2D { - translation 0 150 - children [ - Shape { - appearance USE APP - geometry Circle { - radius 50 - } - } - Transform2D { - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Circle" "radius 50"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 150 150 - children [ - Shape { - appearance USE APP - geometry Rectangle { - size 100 50 - } - } - Transform2D { - translation 0 -40 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Rectangle" "Size 100 50"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -40 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Curve2D Points:" "-50 0, -100 50, 0 20, 10 30, 40 80, 50 0"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -150 0 - children [ - Shape { - appearance USE APP - geometry Curve2D { - point DEF C2D Coordinate2D { - point [-50 0 -100 50 0 20 10 30 40 80 50 0] - } - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["no type"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 3] - point USE C2D - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["type [2 3]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 170 0 - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [1 3 1] - point USE C2D - } - } - Transform2D { - translation 0 -10 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["type [1 3 1]"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation -150 -150 - children [ - Shape { - appearance USE APP - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [-50 0 -25 25 0 80 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["IndexedFaceSet2D" "-50 0, -25, 25, 0 80, 50 0"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -150 - children [ - Shape { - appearance USE APP - geometry PointSet2D { - coord Coordinate2D { - point [-50 0 -25 25 0 80 50 0] - } - } - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["PointSet2D" "-50 0, -25, 25, 0 80, 50 0"] - fontStyle USE FS - } - } - ] - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.png" - useDataReference true - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-imagetexture-url-change.bt b/regression_tests/bifs-media-imagetexture-url-change.bt deleted file mode 100644 index 0f53e3c..0000000 --- a/regression_tests/bifs-media-imagetexture-url-change.bt +++ /dev/null @@ -1,95 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 254 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 254 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 0 1 - } - WorldInfo { - info ["This shows basic 2D shapes" "with dynamic URL change" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Image Texture Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF TXT ImageTexture { - url [od:10] - } - } - geometry Bitmap {} - - } - DEF TS TouchSensor {} - ] - } - DEF C1 Conditional { - buffer { - REPLACE TXT.url BY ["od:20"] - } - } - DEF RC1 Conditional { - buffer { - REPLACE TXT.url BY ["od:10"] - } - } - ] -} - -ROUTE TS.isActive TO C1.activate -ROUTE TS.isActive TO RC1.reverseActivate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 20 - esDescr [ - ES_Descriptor { - ES_ID 3 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 4 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.png" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-movietexture-control.bt b/regression_tests/bifs-media-movietexture-control.bt deleted file mode 100644 index fca2f5e..0000000 --- a/regression_tests/bifs-media-movietexture-control.bt +++ /dev/null @@ -1,148 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 180 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows MovieTexture with playback control" "through usage of start/stop fields of movieTexture" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "MovieTexture Test" - } - Transform2D { - children [ - DEF TR Transform2D { - translation 0 30 - children [ - Shape { - appearance Appearance { - texture DEF MT MovieTexture { - loop TRUE - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap {} - - } - ] - } - ] - } - Transform2D { - translation -50 -70 - children [ - DEF TS1 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Stop"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE MT.stopTime BY 0 - } - } - Transform2D { - translation 50 -70 - children [ - DEF TS2 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - Shape { - appearance USE APP - geometry Text { - string ["Start"] - fontStyle USE FS - } - } - ] - } - DEF C2 Conditional { - buffer { - REPLACE MT.startTime BY 0 - } - } - ] -} - -ROUTE TS1.isActive TO C1.activate -ROUTE TS2.isActive TO C2.activate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-movietexture-no-od.bt b/regression_tests/bifs-media-movietexture-no-od.bt deleted file mode 100644 index 1320a16..0000000 --- a/regression_tests/bifs-media-movietexture-no-od.bt +++ /dev/null @@ -1,65 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info [ - "This test shows how a URL in a MovieTexture node can be a regular URL (http, file, ...) and not an OD URL." - "" - "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.7 $" - "(C) 2002-2006 GPAC Team" - ] - title "Video referenced by a non-OD URL" - } - Sound2D { - source AudioClip { - loop TRUE - url ["auxiliary_files/enst_audio.aac"] - #url ["rtsp://tasmanie/bhusa.mp4"] - } - } - Shape { - appearance Appearance { - texture DEF MT MovieTexture { - loop TRUE - url ["auxiliary_files/enst_video.h264"] - #url ["rtsp://tasmanie/bhusa.mp4"] - } - } - geometry Bitmap {} - - } - ] -} - - diff --git a/regression_tests/bifs-media-movietexture-od-joinsession.bt b/regression_tests/bifs-media-movietexture-od-joinsession.bt deleted file mode 100644 index 99c090b..0000000 --- a/regression_tests/bifs-media-movietexture-od-joinsession.bt +++ /dev/null @@ -1,93 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 180 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows MovieTexture nodes" "using the same OD and looping" "with different start and stop times" "one movieTexture joins the session of the other" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "MovieTexture Test" - } - Transform2D { - translation -100 0 - children [ - Shape { - appearance DEF APP Appearance { - texture MovieTexture { - loop TRUE - startTime 4 - url [od:10] - } - } - geometry Circle { - radius 50 - } - } - ] - } - Transform2D { - translation 100 0 - children [ - Shape { - appearance Appearance { - texture MovieTexture { - loop TRUE - stopTime -1 - url [od:10] - } - } - geometry Rectangle { - size 100 50 - } - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-movietexture-od-leave-session.bt b/regression_tests/bifs-media-movietexture-od-leave-session.bt deleted file mode 100644 index e8c1138..0000000 --- a/regression_tests/bifs-media-movietexture-od-leave-session.bt +++ /dev/null @@ -1,93 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 180 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows MovieTexture nodes" "using the same OD and looping" "with different start and stop times" "one movieTexture leaves the session of the other" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "MovieTexture Test" - } - Transform2D { - translation -100 0 - children [ - Shape { - appearance DEF APP Appearance { - texture MovieTexture { - loop TRUE - stopTime -1 - url [od:10] - } - } - geometry Circle { - radius 50 - } - } - ] - } - Transform2D { - translation 100 0 - children [ - Shape { - appearance Appearance { - texture MovieTexture { - loop TRUE - stopTime 8 - url [od:10] - } - } - geometry Rectangle { - size 100 50 - } - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-movietexture-owns-OCR.bt b/regression_tests/bifs-media-movietexture-owns-OCR.bt deleted file mode 100644 index 9ed503f..0000000 --- a/regression_tests/bifs-media-movietexture-owns-OCR.bt +++ /dev/null @@ -1,75 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 180 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows MovieTexture node on bitmap" "looping (visual object de-synchronized from BIFS)" "Video shall restart when done playing" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "MovieTexture Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture MovieTexture { - loop TRUE - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap {} - - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-movietexture-shares-OCR.bt b/regression_tests/bifs-media-movietexture-shares-OCR.bt deleted file mode 100644 index 9ee42bf..0000000 --- a/regression_tests/bifs-media-movietexture-shares-OCR.bt +++ /dev/null @@ -1,74 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 180 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows MovieTexture node on bitmap" "looping (visual object synchronized on BIFS)" "results at end of video are undefined" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "MovieTexture Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture MovieTexture { - loop TRUE - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap {} - - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-movietexture-url-change.bt b/regression_tests/bifs-media-movietexture-url-change.bt deleted file mode 100644 index e193a38..0000000 --- a/regression_tests/bifs-media-movietexture-url-change.bt +++ /dev/null @@ -1,158 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 255 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 180 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows dynamic URL change of MovieTexture" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.5 $" "(C) 2002-2004 GPAC Team"] - title "MovieTexture Test" - } - Transform2D { - children [ - DEF TR Transform2D { - translation 0 30 - children [ - Shape { - appearance Appearance { - texture DEF MT MovieTexture { - loop TRUE - url [od:20] - } - } - geometry Bitmap {} - - } - ] - } - ] - } - Transform2D { - translation -50 -70 - children [ - DEF TS1 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 80 30 - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Movie 1"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE MT.url BY ["od:20"] - } - } - Transform2D { - translation 50 -70 - children [ - DEF TS2 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 80 30 - } - } - Shape { - appearance USE APP - geometry Text { - string ["Movie 2"] - fontStyle USE FS - } - } - ] - } - DEF C2 Conditional { - buffer { - REPLACE MT.url BY ["od:10"] - } - } - ] -} - -ROUTE TS1.isActive TO C1.activate -ROUTE TS2.isActive TO C2.activate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 20 - esDescr [ - ES_Descriptor { - ES_ID 21 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-sound-spatialize.bt b/regression_tests/bifs-media-sound-spatialize.bt deleted file mode 100644 index d49595c..0000000 --- a/regression_tests/bifs-media-sound-spatialize.bt +++ /dev/null @@ -1,77 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0x01 - sceneProfileLevelIndication 0x01 - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFE - graphicsProfileLevelIndication 0x01 - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric FALSE - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "Sound Test" - info ["This shows Sound node" "with distance volume control and spatialization on" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - - Sound { - location 0 0 1 - spatialize TRUE - source AudioClip { - url [ "od:10" ] - loop TRUE - } - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1 0 0 } - } - geometry Box { size 2 2 2} - } - ] - } - ] -} - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "./auxiliary_files/count_spanish.mp3" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-media-sound.bt b/regression_tests/bifs-media-sound.bt deleted file mode 100644 index 381b59c..0000000 --- a/regression_tests/bifs-media-sound.bt +++ /dev/null @@ -1,77 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0x01 - sceneProfileLevelIndication 0x01 - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFE - graphicsProfileLevelIndication 0x01 - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric FALSE - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - es_id 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -Group { - children [ - - WorldInfo { - title "Sound Test" - info ["This shows Sound node" "with distance volume control" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - - Sound { - location 0 0 1 - spatialize FALSE - source AudioClip { - url [ "od:10" ] - loop TRUE - } - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1 0 0 } - } - geometry Box { size 2 2 2} - } - ] - } - ] -} - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "./auxiliary_files/count_english.mp3" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-misc-UTF16-input.bt b/regression_tests/bifs-misc-UTF16-input.bt deleted file mode 100644 index 93db2f8..0000000 --- a/regression_tests/bifs-misc-UTF16-input.bt +++ /dev/null @@ -1,55 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 260 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows non ASCII Text characters" "Input BT file is in UTF-16 Little Endian format" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "MP4Box Test" - } - Transform2D { - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Non-Ansi:" "" "é à è ù ü ä ë ï ö ü ÿ" "" "" "XML escapes:" "" "& ' \\" > <"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 26 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-misc-cyclic-graph.bt b/regression_tests/bifs-misc-cyclic-graph.bt deleted file mode 100644 index 687c2ac..0000000 --- a/regression_tests/bifs-misc-cyclic-graph.bt +++ /dev/null @@ -1,55 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows a cyclic scene graph" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2005 GPAC Team"] - title "Cyclic Scene Graph Test" - } - DEF TR Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D {emissiveColor 1 0 0 filled TRUE } - } - geometry Circle { radius 60 } - } - Transform2D { - scale 0.98 0.98 - translation 1 0 - children [ - ColorTransform { - mrr 0.95 - children [ USE TR ] - } - ] - } - ] - } - ] -} - diff --git a/regression_tests/bifs-misc-hc-proto-pathextrusion.bt b/regression_tests/bifs-misc-hc-proto-pathextrusion.bt deleted file mode 100644 index fd5da2f..0000000 --- a/regression_tests/bifs-misc-hc-proto-pathextrusion.bt +++ /dev/null @@ -1,103 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - - -EXTERNPROTO PathExtrusion [ - exposedField SFNode geometry NULL - exposedField MFVec3f spine [] - exposedField SFBool beginCap TRUE - exposedField SFBool endCap TRUE - exposedField SFFloat creaseAngle 1.0 - exposedField MFRotation orientation [] - exposedField MFVec2f scale [] - exposedField SFBool txAlongSpine FALSE -] -[ "urn:inet:gpac:builtin:PathExtrusion"] - - - -Group { - children [ - - WorldInfo { - info ["This shows GPAC PathExtrusion HardcodedProto" "The text is extruded along a spline to get a solid text in 3D" "GPAC Regression Tests" "$Date: 2008/05/19 15:28:18 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "PathExtrusion HardcodedProto" - } - NavigationInfo { type ["EXAMINE", "ANY"] headlight FALSE} - Background2D {backColor 0 0 0 url "./auxiliary_files/logo.jpg"} - DEF VIEWPOINT Viewpoint { - description "one" - position 0 0 10 - } - - DirectionalLight { - direction -1 -1 -1 - } - -Shape { - appearance Appearance { - material Material { - diffuseColor 1.0 0.8 0.0 -# specularColor 1 1 1 -# shininess 0.3 - } -# texture ImageTexture { url "../../auxiliary_files/logo.jpg"} - } - - geometry PathExtrusion { -# geometry Curve2D { fineness 1.0 point Coordinate2D { point [0 0, 0.25 1, 0.75 1, 1 0, 1.5 0, 0.8 -2, 0 0] } type [2 0 3] } -# geometry Rectangle { size 0.5 1.0 } - - geometry Text { - string ["G"] - fontStyle FontStyle { - size 2.0 - justify ["MIDDLE", "MIDDLE"] - } - } - - creaseAngle 0.5 - endCap FALSE - beginCap TRUE - txAlongSpine FALSE - spine [ - # Straight-line - 0.0 0.0 0.0, 0.0 1 0, -# 0.0 0.0 -0.8, 0.0 0.0 -1.2, -# 0.0 0.0 -1.6, 0.0 0.0 -2.0 - ] -# scale [ -# 1.8 1.8, 1.95 1.95, -# 2.0 2.0, 1.95 1.95 -# 1.8 1.8, 1.5 1.5 -# 1.2 1.2, 1.05 1.05, -# 1.0 1.0, 1.05 1.05, -# 1.15 1.15, -# ] - } -} - -] -} - diff --git a/regression_tests/bifs-misc-hc-proto-planarextrusion.bt b/regression_tests/bifs-misc-hc-proto-planarextrusion.bt deleted file mode 100644 index c61f267..0000000 --- a/regression_tests/bifs-misc-hc-proto-planarextrusion.bt +++ /dev/null @@ -1,87 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - - -EXTERNPROTO PlanarExtrusion [ - exposedField SFNode geometry NULL - exposedField SFNode spine NULL - exposedField SFBool beginCap TRUE - exposedField SFBool endCap TRUE - exposedField SFFloat creaseAngle 1.0 - exposedField MFFloat orientationKeys [] - exposedField MFRotation orientation [] - exposedField MFFloat scaleKeys [] - exposedField MFVec2f scale [] - exposedField SFBool txAlongSpine FALSE -] -[ "urn:inet:gpac:builtin:PlanarExtrusion"] - - - -Group { - children [ - WorldInfo { - info ["This shows GPAC PlanarExtrusion HardcodedProto" "A circle is extruded along another circle to get a nice 3D torus" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "PlanarExtrusion HardcodedProto" - } - - Background2D { backColor 1 1 1} - DEF VIEWPOINT Viewpoint { - description "one" - position 0 0 10 - } - - -Shape { - appearance Appearance { - material Material { - diffuseColor 1.0 0.8 0.0 - } -# texture ImageTexture { url "../../auxiliary_files/logo.jpg"} - } - - geometry PlanarExtrusion { - geometry Circle { radius 1} -# geometry Curve2D { -# type [2] -# point Coordinate2D { -# point [0 0 0.75 2 1.5 0 2 2] -# } -# } - spine Circle {radius 5} -# spine Rectangle {size 20 10} - creaseAngle 1 - endCap FALSE - beginCap FALSE -# scaleKeys [0 0.1 0.25 0.5 0.75 0.9 1] -# scale [0 0, 0 0, 1 1, 2 2.5, 1 1, 0 0, 0 0] -# orientationKeys [0 0.25 0.5 0.75 1] -# orientation [0 1 0 0, 0 1 1 0.25, 0 0 1 0.25, 0 1 1 0.25, 0 1 0 0] - txAlongSpine TRUE - } -} - -] -} - diff --git a/regression_tests/bifs-misc-hc-proto-planeclipper.bt b/regression_tests/bifs-misc-hc-proto-planeclipper.bt deleted file mode 100644 index db35666..0000000 --- a/regression_tests/bifs-misc-hc-proto-planeclipper.bt +++ /dev/null @@ -1,69 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - ODProfileLevelIndication 0xFF - sceneProfileLevelIndication 0xFE - audioProfileLevelIndication 0xFF - visualProfileLevelIndication 0xFF - graphicsProfileLevelIndication 0xFE - - esdescr [ - ES_Descriptor { - es_id 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric false - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - - -EXTERNPROTO PlaneClipper [ - exposedField SFVec3f plane_normal 1 0 0 - exposedField SFFloat plane_distance 0.0 - exposedField MFNode children [] -] -[ "urn:inet:gpac:builtin:PlaneClipper"] - - - -Group { - children [ - WorldInfo { - info ["This shows GPAC PlaneClipper HardcodedProto" "The plane clipper normal and distance are interpolated to cut the mesh at different places" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "PlaneClipper HardcodedProto" - } - Background2D { backColor 1 1 0} - DEF VIEWPOINT Viewpoint { - description "one" - position 0 0 10 - } - DEF PC PlaneClipper { - children [ - Inline { url "./auxiliary_files/nefertiti.wrl" } - ] - } - DEF TS TimeSensor { cycleInterval 4.0 loop TRUE} - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [-3 3 -3] - } - DEF TS2 TimeSensor { cycleInterval 12.0 loop TRUE} - DEF PI PositionInterpolator { -# key [0 0.333 0.334 0.666 0.667 1] -# keyValue [1 0 0 1 0 0 0 1 0 0 1 0 0 0 -1 0 0 -1] - key [0 0.33 0.666 1] - keyValue [1 0 0, 0 1 0, 0 0 -1, 1 1 0] - } - ] -} - -ROUTE TS.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO PC.plane_distance -ROUTE TS2.fraction_changed TO PI.set_fraction -ROUTE PI.value_changed TO PC.plane_normal diff --git a/regression_tests/bifs-misc-non-linear-parsing-conditional.bt b/regression_tests/bifs-misc-non-linear-parsing-conditional.bt deleted file mode 100644 index bf5dc40..0000000 --- a/regression_tests/bifs-misc-non-linear-parsing-conditional.bt +++ /dev/null @@ -1,69 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This tests encoding of non-linear declared nodes used in conditionals" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Non-linear conditional test" - } - DEF N0 Conditional { - buffer { - REPLACE N1.point BY [-75 0 -40 75 40 75 75 0 40 -75 -40 -75] - } - } - DEF N2 Conditional { - buffer { - REPLACE N1.point BY [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - DELETE ROUTE R0 - DELETE ROUTE R1 - } - } - Transform2D { - scale 0.5 0.5 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF N1 Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - DEF N3 TouchSensor {} - ] - } - ] -} - -DEF R0 ROUTE N3.isActive TO N0.activate -DEF R1 ROUTE N3.isActive TO N2.reverseActivate - diff --git a/regression_tests/bifs-misc-non-linear-parsing-use.bt b/regression_tests/bifs-misc-non-linear-parsing-use.bt deleted file mode 100644 index 7bf33cb..0000000 --- a/regression_tests/bifs-misc-non-linear-parsing-use.bt +++ /dev/null @@ -1,60 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - info ["This tests encoding of non-linear declared nodes used in file" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Non-linear USE test" - } - DEF BACK Background2D { - backColor 1 1 1 - } - DEF TR Transform2D { - scale 0.5 0.5 - children [ - Transform2D { - translation 150 100 - children [ - USE S1 - ] - } - DEF S1 Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - coord DEF COORD Coordinate2D { - point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-misc-srt-import-3gpp-control-share-ocr.bt b/regression_tests/bifs-misc-srt-import-3gpp-control-share-ocr.bt deleted file mode 100644 index a155f92..0000000 --- a/regression_tests/bifs-misc-srt-import-3gpp-control-share-ocr.bt +++ /dev/null @@ -1,64 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 0 1 - } - WorldInfo { - info ["This shows usage of SRT importer" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "SRT importing Test" - } - AnimationStream { - url [od:5] - startTime 5 - stopTime 10 - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 4 - OCR_ES_ID 1 - muxInfo MuxInfo { - fileName "auxiliary_files/subtitle.srt" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-misc-srt-import-3gpp-control.bt b/regression_tests/bifs-misc-srt-import-3gpp-control.bt deleted file mode 100644 index f416779..0000000 --- a/regression_tests/bifs-misc-srt-import-3gpp-control.bt +++ /dev/null @@ -1,64 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 0 1 - } - WorldInfo { - info ["This shows usage of SRT importer" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "SRT importing Test" - } - AnimationStream { - url [od:5] - startTime 5 - stopTime 10 - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 4 - OCR_ES_ID 4 - muxInfo MuxInfo { - fileName "auxiliary_files/subtitle.srt" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-misc-srt-import-3gpp.bt b/regression_tests/bifs-misc-srt-import-3gpp.bt deleted file mode 100644 index 2e0c8b0..0000000 --- a/regression_tests/bifs-misc-srt-import-3gpp.bt +++ /dev/null @@ -1,64 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 0 1 - } - WorldInfo { - info ["This shows usage of SRT importer" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "SRT importing Test" - } - AnimationStream { - url [od:5] - startTime 0 - stopTime 0 - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 4 - OCR_ES_ID 1 - muxInfo MuxInfo { - fileName "auxiliary_files/subtitle.srt" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-misc-srt-import.bt b/regression_tests/bifs-misc-srt-import.bt deleted file mode 100644 index 72b53c5..0000000 --- a/regression_tests/bifs-misc-srt-import.bt +++ /dev/null @@ -1,75 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 240 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of SRT importer" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "SRT importing Test" - } - Shape { - appearance Appearance { - material Material2D {emissiveColor 0 0 0 filled TRUE } - } - geometry DEF TXT Text { - fontStyle DEF FONT FontStyle { - justify ["MIDDLE"] - size 30 - } - } - } - AnimationStream { - url [od:5] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 5 - esDescr [ - ES_Descriptor { - ES_ID 4 - OCR_ES_ID 1 - muxInfo MuxInfo { - fileName "auxiliary_files/subtitle.srt" - textNode "TXT" - fontNode "FONT" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-od-remove-esd.bt b/regression_tests/bifs-od-remove-esd.bt deleted file mode 100644 index 42ba515..0000000 --- a/regression_tests/bifs-od-remove-esd.bt +++ /dev/null @@ -1,78 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This tests ESDRemove command" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "ESD Remove" - } - Transform2D { - children [ - Shape { - appearance DEF APP Appearance { - texture ImageTexture { - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry Circle { - radius 100 - } - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - -AT 2000 { - REMOVE ESD FROM 10 [20] -} - diff --git a/regression_tests/bifs-od-remove-od.bt b/regression_tests/bifs-od-remove-od.bt deleted file mode 100644 index 6a35767..0000000 --- a/regression_tests/bifs-od-remove-od.bt +++ /dev/null @@ -1,78 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This tests ODRemove command" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "OD Remove test" - } - Transform2D { - children [ - Shape { - appearance DEF APP Appearance { - texture ImageTexture { - url [od:10] - repeatS FALSE - repeatT FALSE - } - } - geometry Circle { - radius 100 - } - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - -AT 2000 { - REMOVE OD [10] -} - diff --git a/regression_tests/bifs-od-update-od.bt b/regression_tests/bifs-od-update-od.bt deleted file mode 100644 index 00756bc..0000000 --- a/regression_tests/bifs-od-update-od.bt +++ /dev/null @@ -1,89 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This tests ODUpdate command" "by sending a new OD with the same ID" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "OD Update" - } - Transform2D { - translation -150 0 - children [ - Shape { - appearance Appearance { - texture ImageTexture { - url [od:10] - } - } - geometry Circle { - radius 100 - } - } - ] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 3 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - -AT 2000 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 4 - muxInfo MuxInfo { - fileName "auxiliary_files/sky.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-proto-conditional.bt b/regression_tests/bifs-proto-conditional.bt deleted file mode 100644 index 8a15970..0000000 --- a/regression_tests/bifs-proto-conditional.bt +++ /dev/null @@ -1,107 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - eventIn SFBool act - eventIn SFBool reverseAct - exposedField SFVec2f translation 0 0 - exposedField SFFloat rotation 0 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] { - DEF TR Transform2D { - rotationAngle IS rotation - scale 2 1 - translation IS translation - children [ - DEF S Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - ] - } - DEF C Conditional { - activate IS act - buffer { - REPLACE TR.scale BY 1 1 - } - } - DEF RC Conditional { - reverseActivate IS reverseAct - buffer { - REPLACE TR.scale BY 2 1 - } - } -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of a conditional inside a proto" "getting events outside the proto" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Simple proto Test" - } - DEF PT1 GEOMETRY_PROTO { - translation 100 0 - rotation 0.78 - Color 1 0 1 - transparency 0.75 - lineColor 1 0 0 - lineWidth 2 - obj Circle { - radius 75 - } - } - DEF PT2 Transform2D { - translation -100 0 - children [ - GEOMETRY_PROTO { - Color 1 0 0 - obj Rectangle { - size 50 50 - } - } - DEF TS TouchSensor {} - ] - } - ] -} - -ROUTE TS.isActive TO PT1.act -ROUTE TS.isActive TO PT1.reverseAct - diff --git a/regression_tests/bifs-proto-delete-def.bt b/regression_tests/bifs-proto-delete-def.bt deleted file mode 100644 index bc7b02f..0000000 --- a/regression_tests/bifs-proto-delete-def.bt +++ /dev/null @@ -1,91 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] { - Transform2D { - rotationAngle IS rotation - scale IS scale - translation IS translation - children [ - DEF S Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - Transform2D { - translation -100 0 - children [ - USE S - ] - } - ] - } -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows deleteion of a proto instance by ID" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Simple proto Test" - } - DEF G GEOMETRY_PROTO { - translation 200 0 - scale 1 1.5 - rotation 0.78 - Color 1 0 1 - transparency 0.75 - lineColor 1 0 0 - lineWidth 2 - obj Circle { - radius 75 - } - } - ] -} - - -AT 2000 { - REPLACE G BY NULL -} - diff --git a/regression_tests/bifs-proto-delete-index.bt b/regression_tests/bifs-proto-delete-index.bt deleted file mode 100644 index 2a43fd2..0000000 --- a/regression_tests/bifs-proto-delete-index.bt +++ /dev/null @@ -1,95 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] { - Transform2D { - rotationAngle IS rotation - scale IS scale - translation IS translation - children [ - DEF S Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - Transform2D { - translation -100 0 - children [ - USE S - ] - } - ] - } -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows deleteion of a proto instance by index" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Proto Delete Test" - } - DEF TR Transform2D { - children [ - DEF G GEOMETRY_PROTO { - translation 200 0 - scale 1 1.5 - rotation 0.78 - Color 1 0 1 - transparency 0.75 - lineColor 1 0 0 - lineWidth 2 - obj Circle { - radius 75 - } - } - ] - } - ] -} - - -AT 2000 { - REPLACE TR.children[0] BY NULL -} - diff --git a/regression_tests/bifs-proto-forestgump.bt b/regression_tests/bifs-proto-forestgump.bt deleted file mode 100644 index 18054e4..0000000 --- a/regression_tests/bifs-proto-forestgump.bt +++ /dev/null @@ -1,478 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 250 - pixelHeight 250 - } - } - } - ] -} - -PROTO FORESTGUMP [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFFloat lineWidth 3 - exposedField SFColor lineColor 0.121569 0.101961 0.0901961 - exposedField SFTime runTime 1 - exposedField SFBool loop TRUE - exposedField SFTime start 0 -] { - Transform2D { - rotationAngle IS rotation - scale IS scale - translation IS translation - children [ - DEF MYSWITCH Switch { - whichChoice 0 - choice [ - Transform2D { - scale 0.0899561 0.0900365 - translation 260.243 42.9024 - children [ - Transform2D { - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - geometry Curve2D { - type [1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-2827 -11 -2864 -2 -2864 -2 -2883 -2 -2883 -2 -2892 -2 -2901 -11 -2911 -11 -2920 -11 -2929 -20 -2939 -29 -2939 -29 -2957 -48 -2957 -48 -2966 -57 -2957 -57 -2966 -76 -2966 -85 -2976 -95 -2976 -104 -2976 -104 -2976 -132 -2976 -132 -2976 -132 -2976 -160 -2976 -160 -2966 -178 -2957 -188 -2957 -188 -2957 -188 -2939 -197 -2939 -197 -2939 -197 -2920 -197 -2920 -197 -2920 -197 -2911 -206 -2911 -206 -2911 -206 -2892 -206 -2892 -206 -2892 -206 -2873 -206 -2873 -206 -2873 -206 -2855 -215 -2855 -215 -2855 -215 -2836 -215 -2836 -215 -2836 -215 -2827 -206 -2827 -206 -2827 -206 -2808 -197 -2808 -197 -2799 -188 -2799 -188 -2790 -178 -2790 -178 -2790 -169 -2790 -169 -2780 -160 -2780 -160 -2771 -150 -2771 -150 -2771 -141 -2771 -141 -2771 -132 -2771 -132 -2771 -122 -2771 -122 -2771 -113 -2771 -113 -2771 -104 -2771 -104 -2771 -95 -2771 -95 -2771 -85 -2771 -85 -2771 -76 -2780 -57 -2780 -48 -2780 -48 -2790 -29 -2790 -29 -2790 -29 -2808 -20 -2808 -20 -2808 -20 -2818 -11 -2818 -11 -2827 -2 -2827 -2 -2836 -2 -2836 -2 -2846 -2 -2855 -2 -2873 -2 -2883 -2] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 2 1 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-2883 -225 -2883 -262 -2883 -262 -2883 -281 -2883 -281 -2883 -290 -2883 -299 -2883 -308 -2883 -327 -2883 -327 -2892 -336 -2892 -336 -2892 -336 -2892 -383 -2892 -392 -2892 -401 -2892 -429 -2892 -439 -2892 -439 -2892 -467 -2892 -467 -2892 -467 -2892 -485 -2892 -485 -2901 -485 -2901 -485 -2901 -494 -2901 -494 -2901 -504 -2901 -513 -2901 -532 -2901 -541] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-3004 -755 -2994 -727 -2985 -708 -2976 -690 -2976 -680 -2976 -643 -2976 -643 -2957 -625 -3004 -653 -3004 -653 -3004 -653 -3115 -718 -3115 -708 -3115 -662 -3032 -541 -2957 -541 -2939 -541 -2901 -522 -2883 -541 -2883 -541 -2855 -560 -2855 -560 -2846 -569 -2818 -587 -2818 -606 -2818 -625 -2790 -662 -2790 -708 -2790 -773 -2799 -848 -2799 -913 -2799 -931 -2808 -931 -2808 -950 -2808 -959 -2790 -931 -2790 -931 -2780 -904 -2743 -857 -2734 -829 -2734 -820 -2697 -773 -2706 -773] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-2985 -346 -2994 -346 -3022 -374 -3032 -374 -3041 -374 -3050 -383 -3050 -392 -3050 -392 -3134 -392 -3143 -392 -3152 -392 -3134 -364 -3134 -364 -3134 -364 -3106 -346 -3106 -346 -3097 -336 -2985 -253 -2957 -253 -2939 -253 -2920 -271 -2911 -271 -2901 -271 -2873 -281 -2864 -281 -2836 -271 -2790 -234 -2771 -225 -2762 -225 -2734 -206 -2725 -197 -2715 -188 -2669 -160 -2669 -160 -2660 -160 -2660 -150 -2660 -169 -2660 -206 -2641 -262 -2641 -299] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0900093 0.0899546 - translation 190.415 42.8184 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-2083 -20 -2120 -20 -2120 -20 -2130 -20 -2130 -20 -2139 -20 -2139 -20 -2148 -20 -2148 -20 -2148 -20 -2167 -20 -2167 -20 -2167 -20 -2195 -30 -2195 -30 -2195 -30 -2204 -48 -2213 -58 -2213 -58 -2232 -67 -2241 -76 -2241 -76 -2241 -113 -2241 -113 -2241 -113 -2250 -132 -2250 -141 -2250 -151 -2241 -169 -2241 -169 -2241 -179 -2223 -188 -2223 -188 -2223 -188 -2213 -216 -2204 -216 -2195 -216 -2195 -225 -2185 -225 -2185 -225 -2157 -225 -2157 -225 -2157 -225 -2139 -225 -2139 -225 -2139 -225 -2120 -225 -2120 -225 -2120 -225 -2111 -216 -2111 -216 -2111 -216 -2092 -216 -2092 -216 -2092 -216 -2074 -206 -2074 -206 -2074 -206 -2064 -197 -2064 -197 -2064 -197 -2055 -179 -2055 -179 -2046 -179 -2046 -179 -2046 -169 -2046 -169 -2037 -160 -2037 -160 -2037 -151 -2037 -151 -2037 -141 -2037 -141 -2037 -132 -2037 -132 -2037 -123 -2037 -123 -2037 -113 -2037 -113 -2037 -104 -2037 -104 -2037 -95 -2037 -95 -2037 -95 -2037 -76 -2037 -76 -2037 -76 -2055 -39 -2055 -39 -2055 -39 -2074 -30 -2074 -30 -2074 -30 -2092 -20 -2092 -20 -2092 -20 -2102 -11 -2102 -11 -2111 -11 -2111 -11 -2120 -11 -2120 -11 -2120 -2 -2120 -2 -2157 -2 -2157 -2] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-2130 -244 -2130 -290 -2130 -318 -2130 -355 -2130 -383 -2130 -402 -2139 -420 -2139 -439 -2139 -448 -2139 -476 -2139 -485 -2139 -495 -2139 -504 -2139 -513 -2139 -523 -2139 -523 -2139 -532 -2139 -532 -2139 -541 -2139 -541 -2130 -551 -2130 -551] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-2306 -792 -2269 -764 -2232 -718 -2204 -690 -2195 -681 -2204 -690 -2213 -690 -2241 -681 -2325 -671 -2343 -653 -2343 -653 -2362 -644 -2362 -644 -2371 -634 -2278 -569 -2278 -569 -2241 -560 -2213 -551 -2176 -551 -2139 -551 -2027 -578 -2027 -616 -2027 -625 -2018 -625 -2018 -634 -1999 -671 -1999 -709 -1999 -755 -1999 -811 -2074 -904 -2111 -922 -2148 -941 -2139 -950 -2102 -950 -2064 -950 -2009 -950 -1971 -950] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-2223 -402 -2260 -420 -2325 -439 -2353 -411 -2371 -392 -2381 -374 -2381 -355 -2381 -318 -2371 -290 -2343 -281 -2306 -262 -2232 -244 -2185 -244 -2176 -244 -2139 -225 -2130 -225 -2120 -225 -2046 -234 -2027 -234 -1981 -234 -1897 -253 -1878 -299 -1869 -318 -1851 -346 -1851 -383 -1851 -411 -1860 -448 -1860 -467] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0899291 0.0900198 - translation 123.698 44.4248 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 1 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-1283 -11 -1320 -11 -1320 -11 -1330 -11 -1330 -11 -1339 -11 -1339 -11 -1348 -11 -1348 -11 -1348 -11 -1367 -11 -1367 -11 -1367 -20 -1367 -20 -1376 -20 -1376 -20 -1376 -20 -1413 -39 -1413 -39 -1413 -39 -1432 -76 -1432 -76 -1432 -85 -1441 -104 -1441 -113 -1441 -123 -1451 -141 -1451 -151 -1451 -169 -1451 -160 -1441 -169 -1441 -169 -1432 -188 -1432 -188 -1432 -188 -1423 -206 -1423 -206 -1423 -206 -1404 -216 -1404 -216 -1395 -216 -1386 -225 -1376 -225 -1376 -225 -1348 -225 -1348 -225 -1348 -225 -1330 -225 -1330 -225 -1330 -225 -1311 -225 -1311 -225 -1311 -225 -1293 -216 -1293 -216 -1293 -216 -1283 -206 -1283 -206 -1283 -206 -1265 -197 -1265 -197 -1265 -197 -1255 -188 -1255 -188 -1255 -188 -1246 -169 -1246 -169 -1237 -169 -1237 -169 -1237 -160 -1237 -160 -1237 -151 -1237 -151 -1237 -141 -1237 -141 -1237 -132 -1237 -132 -1237 -123 -1237 -123 -1237 -113 -1237 -113 -1237 -104 -1237 -104 -1237 -95 -1237 -95 -1237 -85 -1237 -85 -1237 -85 -1237 -67 -1237 -67 -1237 -67 -1255 -48 -1255 -39 -1255 -39 -1265 -20 -1265 -20 -1265 -20 -1283 -11 -1283 -11 -1283 -11 -1302 -2 -1302 -2 -1311 -2 -1311 -2 -1320 -2 -1320 -2 -1330 -2 -1339 -2 -1358 -2 -1367 -2] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [1 2 1 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [-1311 -234 -1311 -271 -1311 -271 -1311 -281 -1311 -281 -1311 -299 -1311 -318 -1311 -355 -1311 -374 -1311 -392 -1311 -430 -1311 -448 -1311 -457 -1311 -485 -1311 -495 -1311 -495 -1311 -513 -1311 -513 -1311 -523 -1311 -523 -1311 -532 -1311 -532 -1311 -541 -1311 -560 -1311 -578 -1311 -560] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-1572 -662 -1534 -709 -1469 -755 -1441 -783 -1423 -802 -1451 -764 -1451 -764 -1460 -736 -1506 -578 -1469 -560 -1451 -550 -1330 -597 -1320 -597 -1293 -606 -1274 -616 -1274 -662 -1274 -690 -1274 -727 -1283 -746 -1283 -755 -1293 -792 -1302 -811 -1339 -885 -1274 -904 -1274 -987] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2] - point Coordinate2D { - point [-1609 -541 -1618 -467 -1599 -504 -1590 -448 -1562 -309 -1423 -253 -1283 -253 -1237 -253 -1144 -281 -1144 -327 -1144 -346 -1135 -355 -1144 -374 -1153 -392 -1227 -467 -1227 -485] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0899947 0.0899257 - translation 62.0964 37.7238 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 1 2 1 2 1] - point Coordinate2D { - point [-511 -30 -549 -30 -567 -30 -577 -30 -586 -30 -604 -48 -604 -48 -614 -48 -623 -67 -623 -76 -623 -86 -642 -76 -642 -95 -642 -95 -642 -123 -642 -123 -642 -132 -642 -141 -642 -151 -642 -160 -623 -179 -623 -179 -623 -179 -614 -188 -614 -188 -614 -188 -595 -188 -595 -188 -595 -188 -586 -197 -586 -197 -586 -197 -567 -197 -567 -197 -567 -197 -549 -207 -549 -207 -549 -207 -539 -197 -539 -197 -539 -197 -521 -197 -521 -197 -521 -197 -502 -188 -502 -188 -493 -179 -493 -179 -484 -169 -484 -169 -474 -169 -474 -169 -474 -160 -474 -160 -465 -160 -465 -160 -465 -151 -465 -151 -465 -141 -465 -141 -465 -132 -465 -132 -456 -132 -456 -132 -456 -114 -456 -114 -456 -86 -465 -86 -465 -86 -465 -86 -474 -67 -474 -58 -474 -48 -484 -48 -484 -39 -484 -39 -493 -21 -493 -21 -502 -21 -502 -21 -511 -11 -511 -11 -521 -2 -521 -2 -558 -2 -511 -30 -521 -2] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 1 2 2] - point Coordinate2D { - point [-539 -225 -539 -262 -549 -281 -549 -318 -549 -337 -558 -355 -558 -374 -558 -383 -558 -411 -558 -430 -558 -439 -558 -448 -558 -467 -558 -476 -558 -504 -567 -513 -558 -523] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 1 2 2 2 2 2] - point Coordinate2D { - point [-865 -551 -865 -569 -846 -653 -846 -672 -846 -690 -837 -699 -837 -709 -837 -718 -828 -718 -828 -709 -828 -681 -763 -606 -735 -588 -716 -579 -651 -541 -632 -541 -577 -541 -521 -532 -465 -560 -446 -569 -400 -616 -381 -634 -381 -634 -353 -699 -372 -699 -400 -699 -428 -672 -428 -672 -437 -672 -437 -672 -474 -653 -474 -653 -484 -653 -493 -662 -493 -672 -493 -690 -502 -755 -502 -774 -502 -783 -502 -792 -493 -811 -484 -830 -474 -848 -474 -830] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2] - point Coordinate2D { - point [-1023 -365 -976 -318 -930 -300 -874 -272 -865 -272 -837 -253 -828 -253 -716 -216 -577 -262 -456 -262 -428 -262 -335 -318 -363 -346 -372 -355 -437 -346 -456 -346 -456 -346 -511 -337 -511 -337 -530 -337 -539 -318 -549 -318] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0899962 0.0899977 - translation -16.1993 42.7489 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [279 -20 260 -20 232 -1 223 -1 214 -1 205 -20 195 -20 186 -20 167 -29 167 -39 167 -48 149 -66 149 -76 139 -94 139 -94 139 -113 139 -132 130 -141 130 -159 130 -169 139 -178 139 -187 139 -187 149 -206 149 -206 149 -206 158 -225 158 -225 158 -225 177 -234 177 -234 177 -234 195 -234 195 -234 195 -234 214 -234 214 -234 214 -234 232 -234 232 -234 242 -234 251 -225 260 -225 270 -225 270 -225 279 -215 279 -215 288 -215 288 -215 298 -206 298 -206 307 -197 307 -197 316 -187 316 -187 316 -178 316 -178 325 -169 325 -169 335 -159 335 -159 335 -141 335 -141 335 -132 335 -122 335 -113 335 -94 325 -85 325 -76 325 -76 325 -48 325 -48 325 -48 316 -29 316 -29 316 -29 298 -20 298 -20 288 -11 288 -11 279 -11 279 -11 270 -11 260 -11 232 -11 223 -11] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 1 2 1 2] - point Coordinate2D { - point [232 -252 232 -280 214 -327 214 -345 214 -364 205 -411 205 -429 205 -438 205 -466 205 -476 205 -494 205 -494 205 -513 205 -513 195 -531 195 -531 195 -569 195 -569] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 1 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [56 -848 65 -857 130 -913 149 -931 158 -941 186 -968 149 -913 149 -913 130 -866 130 -773 130 -717 130 -680 112 -662 112 -624 112 -578 139 -522 195 -522 260 -522 409 -531 409 -615 409 -615 428 -634 400 -634 372 -634 298 -615 279 -624 260 -634 279 -736 279 -755] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [-56 -327 -46 -290 -37 -243 -28 -197 -28 -187 0 -159 9 -141 9 -132 19 -141 19 -150 28 -169 112 -243 149 -243 167 -243 214 -262 251 -262 279 -262 298 -252 316 -271 325 -280 353 -299 353 -299 353 -299 381 -327 391 -327 446 -355 325 -373 316 -373 279 -383 205 -373 177 -345] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0900707 0.0899924 - translation -85.7923 41.9814 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [1060 -20 1060 -20 1014 -2 1004 -2 995 -2 986 -11 976 -11 976 -11 949 -20 949 -20 939 -20 921 -48 921 -58 921 -58 902 -86 902 -86 902 -86 902 -104 902 -104 902 -113 902 -123 902 -132 902 -132 911 -151 911 -151 911 -151 921 -169 921 -169 921 -169 939 -188 939 -188 939 -188 949 -197 949 -197 949 -197 967 -206 967 -206 967 -206 986 -206 995 -206 1004 -206 1004 -206 1014 -206 1014 -206 1023 -206 1023 -206 1032 -206 1032 -206 1051 -197 1051 -197 1060 -197 1060 -197 1069 -188 1069 -188 1079 -179 1079 -179 1079 -169 1079 -169 1088 -169 1088 -169 1088 -169 1088 -151 1088 -151 1088 -141 1097 -123 1097 -104 1097 -86 1097 -86 1088 -67 1088 -67 1079 -48 1079 -48 1079 -48 1069 -39 1069 -39 1060 -30 1060 -30 1051 -30 1051 -30 1042 -20 1032 -20 1014 -11 1004 -11] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 1 2 1 2] - point Coordinate2D { - point [995 -225 995 -253 1014 -318 1014 -346 1014 -365 1014 -411 1014 -430 1014 -439 1014 -467 1014 -476 1014 -485 1014 -485 1014 -504 1014 -504 1014 -513 1014 -523 1014 -541 1023 -541] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 1 2 2 2 2 2 2] - point Coordinate2D { - point [809 -932 846 -932 893 -913 921 -913 958 -913 930 -895 930 -895 921 -895 893 -895 865 -774 865 -764 837 -699 921 -569 976 -541 1014 -523 1088 -578 1097 -588 1107 -597 1144 -625 1153 -634 1209 -690 1069 -644 1051 -662 1032 -681 1116 -792 1153 -792] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2] - point Coordinate2D { - point [688 -532 688 -485 716 -374 753 -355 800 -327 883 -262 939 -262 976 -262 1032 -281 1069 -262 1125 -234 1190 -309 1209 -327 1237 -355 1181 -383 1162 -402 1144 -420 1107 -448 1107 -476] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.0899064 0.08998 - translation -164.619 43.1904 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 2 1 2 2 2 2 2 1 2 1 2] - point Coordinate2D { - point [1878 -20 1851 -11 1841 -1 1813 -1 1804 -1 1804 -11 1795 -11 1785 -11 1767 -39 1767 -48 1758 -57 1739 -66 1739 -85 1739 -85 1739 -113 1739 -113 1739 -122 1748 -132 1748 -141 1748 -141 1758 -159 1758 -169 1758 -169 1767 -187 1767 -187 1767 -187 1776 -206 1776 -206 1776 -206 1785 -215 1785 -215 1785 -215 1804 -225 1804 -225 1804 -225 1823 -225 1823 -225 1823 -225 1841 -225 1841 -225 1841 -225 1860 -215 1860 -215 1869 -215 1869 -215 1878 -206 1878 -206 1888 -197 1888 -197 1897 -187 1897 -187 1906 -178 1906 -178 1916 -169 1916 -169 1916 -159 1916 -159 1925 -150 1925 -150 1925 -150 1925 -132 1925 -132 1925 -122 1925 -122 1934 -113 1934 -113 1934 -113 1934 -85 1925 -76 1925 -76 1906 -66 1906 -57 1906 -48 1906 -39 1897 -29 1897 -29 1878 -20 1878 -20 1869 -20 1869 -20 1860 -11 1860 -11 1851 -11 1841 -11 1823 -1 1804 -1] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 1 2 1 2] - point Coordinate2D { - point [1832 -234 1832 -271 1841 -327 1841 -364 1841 -383 1841 -411 1841 -429 1841 -429 1841 -466 1841 -466 1841 -466 1841 -485 1841 -485 1851 -485 1851 -485 1851 -494 1851 -494 1841 -494 1841 -494 1841 -531 1841 -531] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [1758 -959 1767 -931 1804 -894 1813 -866 1813 -857 1851 -792 1851 -792 1851 -792 1851 -792 1851 -792 1851 -792 1841 -801 1841 -801 1813 -829 1776 -708 1776 -699 1776 -662 1767 -606 1776 -578 1776 -578 1776 -550 1776 -550 1776 -550 1785 -559 1795 -559 1841 -559 1916 -550 1953 -513 1962 -504 1999 -485 1999 -485 1999 -485 2018 -466 2018 -466 2018 -466 2037 -457 2037 -457 2037 -457 2027 -457 2027 -457 2009 -476 1944 -606 1944 -652 1944 -652 1934 -680 1934 -680 1934 -680 1962 -662 1962 -662 1971 -652 2018 -615 2037 -606 2037 -606 2092 -597 2074 -597] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2] - point Coordinate2D { - point [1674 -476 1646 -448 1618 -411 1590 -383 1581 -373 1572 -345 1572 -345 1553 -327 1692 -262 1730 -252 1776 -243 1767 -225 1804 -243 1813 -243 1897 -243 1906 -243 1944 -243 1990 -271 1999 -280 2027 -308 2092 -383 2092 -411] - } - } - } - ] - } - ] - } - Transform2D { - scale 0.089974 0.090028 - translation -247.069 37.0465 - children [ - Transform2D { - children [ - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2 1] - point Coordinate2D { - point [2715 -4 2687 -4 2660 -13 2641 -13 2641 -13 2622 -23 2622 -23 2613 -32 2585 -69 2585 -69 2585 -78 2576 -106 2576 -116 2576 -134 2567 -125 2576 -143 2576 -143 2576 -171 2576 -171 2576 -171 2594 -190 2594 -190 2594 -190 2604 -209 2604 -209 2604 -209 2613 -218 2613 -218 2613 -218 2632 -218 2632 -218 2632 -218 2650 -218 2650 -218 2650 -218 2669 -218 2669 -218 2669 -218 2687 -209 2687 -209 2687 -209 2706 -209 2706 -209 2715 -199 2715 -199 2725 -199 2725 -199 2734 -199 2734 -199 2743 -190 2743 -190 2753 -190 2753 -190 2762 -181 2762 -181 2762 -171 2762 -171 2771 -171 2771 -171 2771 -162 2771 -162 2780 -153 2780 -153 2780 -153 2780 -134 2780 -134 2780 -125 2780 -97 2780 -88 2780 -78 2771 -69 2771 -60 2771 -60 2762 -50 2762 -50 2762 -50 2753 -32 2753 -32 2753 -23 2753 -23 2743 -13 2743 -13 2734 -13 2734 -13 2715 5 2715 -4 2734 -13] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 1 2 1 2] - point Coordinate2D { - point [2660 -255 2660 -274 2660 -311 2660 -329 2660 -348 2660 -376 2660 -395 2660 -413 2660 -413 2660 -432 2660 -432 2660 -450 2660 -460 2660 -497 2660 -506] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2 2 2 2 2 2 2 2] - point Coordinate2D { - point [2464 -822 2483 -794 2520 -748 2539 -720 2539 -711 2576 -683 2567 -683 2529 -683 2483 -711 2446 -711 2427 -711 2474 -636 2474 -636 2492 -608 2539 -571 2567 -553 2576 -553 2585 -534 2594 -534 2622 -525 2641 -506 2669 -506 2697 -506 2734 -506 2762 -506 2780 -506 2873 -553 2883 -571 2883 -571 2892 -590 2892 -599 2892 -599 2901 -627 2901 -627 2901 -627 2911 -608 2911 -608 2920 -581 2957 -534 2957 -506] - } - } - } - Shape { - appearance USE APP - geometry Curve2D { - type [2 2 2 2 2 2] - point Coordinate2D { - point [2641 -292 2585 -311 2529 -320 2464 -320 2427 -320 2483 -274 2483 -274 2529 -227 2687 -227 2799 -227 2836 -227 2920 -227 2948 -236 2966 -246 3004 -264 3004 -274 3013 -292 3050 -320 3050 -329] - } - } - } - ] - } - ] - } - ] - } - ] - } - DEF TS TimeSensor { - cycleInterval IS runTime - loop IS loop - startTime IS start - } - DEF VAL Valuator { - Factor1 8 - } - DEF R1 ROUTE TS.fraction_changed TO VAL.inSFFloat - ROUTE VAL.outSFInt32 TO MYSWITCH.whichChoice -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["Each animated logo is an instance of a single proto" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Complexe proto Test" - } - FORESTGUMP { - translation -75 -75 - scale 1.1 1.1 - rotation 0.75 - runTime 0.5 - } - FORESTGUMP { - translation -100 50 - scale 1 1.5 - runTime 0.75 - start 2 - } - FORESTGUMP { - translation 0 10 - scale 1.8 1.8 - start 4 - } - DEF ANIM FORESTGUMP { - translation 75 -75 - rotation -1.25 - runTime 0.8 - start 6 - } - DEF TIMER TimeSensor { - cycleInterval 2 - loop TRUE - startTime 6 - } - DEF SI ScalarInterpolator { - key [0 1] - keyValue [0 6.283] - } - ] -} - -ROUTE TIMER.fraction_changed TO SI.set_fraction -ROUTE SI.value_changed TO ANIM.rotation - diff --git a/regression_tests/bifs-proto-mfurl.bt b/regression_tests/bifs-proto-mfurl.bt deleted file mode 100644 index 3aa8908..0000000 --- a/regression_tests/bifs-proto-mfurl.bt +++ /dev/null @@ -1,78 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -PROTO testURL [ - exposedField MFString theURL [""] -] { - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF MYTEXT ImageTexture { - url IS theURL - } - } - geometry Bitmap {} - - } - ] - } -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This is a proto with an MF URL ISed field" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Proto with URL Test" - } - DEF testInstance testURL { - theURL ["10"] - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/logo.jpg" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-proto-multiple.bt b/regression_tests/bifs-proto-multiple.bt deleted file mode 100644 index d4300ce..0000000 --- a/regression_tests/bifs-proto-multiple.bt +++ /dev/null @@ -1,180 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -PROTO PaletteElement [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFColor color 0 0 0 - exposedField SFFloat proto_ident 0 - eventOut SFBool isOver - eventOut SFInt32 active_proto -] { - Transform2D { - scale IS scale - translation IS translation - children [ - DEF TS TouchSensor { - isOver IS isOver - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor IS color - filled TRUE - lineProps LineProperties { - width 3 - } - } - } - geometry IndexedFaceSet2D { - coordIndex [0 1 2 3 4 5 -1] - coord Coordinate2D { - point [100 0 50 86.6 -50 86.6 -100 0 -50 -86.6 50 -86.6] - } - } - } - ] - } - DEF V Valuator { - outSFInt32 IS active_proto - Factor1 0 - Factor2 0 - Factor3 0 - Factor4 0 - Offset1 IS proto_ident - } - ROUTE TS.isActive TO V.inSFBool -} -PROTO Palette [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - eventOut SFColor selectedColor - eventOut MFString active -] { - DEF TR Transform2D { - scale IS scale - translation IS translation - children [ - DEF RedPaletteElement PaletteElement { - color 1 0 0 - proto_ident 1 - } - DEF GreenPaletteElement PaletteElement { - translation 150 86.6 - color 0 1 0 - proto_ident 2 - } - DEF BluePaletteElement PaletteElement { - translation -150 86.6 - color 0 0 1 - proto_ident 3 - } - ] - } - DEF ColorValuator Valuator { - outSFColor IS selectedColor - } - DEF RConditional Conditional { - buffer { - REPLACE ColorValuator.inSFColor BY 1 0 0 - } - } - DEF GConditional Conditional { - buffer { - REPLACE ColorValuator.inSFColor BY 0 1 0 - } - } - DEF BConditional Conditional { - buffer { - REPLACE ColorValuator.inSFColor BY 0 0 1 - } - } - DEF V2 Valuator { - outMFString IS active - } - ROUTE RedPaletteElement.isOver TO RConditional.activate - ROUTE GreenPaletteElement.isOver TO GConditional.activate - ROUTE BluePaletteElement.isOver TO BConditional.activate - ROUTE RedPaletteElement.active_proto TO V2.inSFInt32 - ROUTE GreenPaletteElement.active_proto TO V2.inSFInt32 - ROUTE BluePaletteElement.active_proto TO V2.inSFInt32 -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows a Proto using Protos" "Each palette element is a proto" "The whole palette is another proto" "with routes and conditionals" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Nested Proto test" - } - Transform2D { - translation 0 100 - children [ - Shape { - appearance Appearance { - material DEF Material2DNode Material2D { - filled TRUE - lineProps LineProperties { - width 3 - } - } - } - geometry Rectangle { - size 10 10 - } - } - ] - } - Transform2D { - scale 0.5 0.5 - translation 0 -50 - children [ - DEF P Palette {} - ] - } - Transform2D { - translation 0 50 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - string ["Active Palette"] - fontStyle FontStyle { - size 20 - } - } - } - ] - } - ] -} - -ROUTE P.selectedColor TO Material2DNode.emissiveColor -ROUTE P.active TO TXT.string - diff --git a/regression_tests/bifs-proto-nested.bt b/regression_tests/bifs-proto-nested.bt deleted file mode 100644 index 153de9a..0000000 --- a/regression_tests/bifs-proto-nested.bt +++ /dev/null @@ -1,132 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -PROTO Palette [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - eventOut SFColor selectedColor -] { - PROTO PaletteElement [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFColor color 0 0 0 - eventOut SFBool isOver - ] { - Transform2D { - scale IS scale - translation IS translation - children [ - TouchSensor { - isOver IS isOver - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor IS color - filled TRUE - lineProps LineProperties { - width 3 - } - } - } - geometry IndexedFaceSet2D { - coordIndex [0 1 2 3 4 5 -1] - coord Coordinate2D { - point [100 0 50 86.6 -50 86.6 -100 0 -50 -86.6 50 -86.6] - } - } - } - ] - } - } - DEF TR Transform2D { - scale IS scale - translation IS translation - children [ - DEF RedPaletteElement PaletteElement { - color 1 0 0 - } - ] - } - DEF ColorValuator Valuator { - outSFColor IS selectedColor - } - DEF RConditional Conditional { - buffer { - REPLACE ColorValuator.inSFColor BY 1 0 0 - } - } - DEF Conditional Conditional { - buffer { - REPLACE ColorValuator.inSFColor BY 0.8 0.8 0.8 - } - } - ROUTE RedPaletteElement.isOver TO RConditional.activate - ROUTE RedPaletteElement.isOver TO Conditional.reverseActivate -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows a Proto using DEF/USE Protos" "declared inside the proto itself" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Nested Proto test" - } - Transform2D { - translation 0 100 - children [ - Shape { - appearance Appearance { - material DEF Material2DNode Material2D { - filled TRUE - lineProps LineProperties { - width 3 - } - } - } - geometry Rectangle { - size 10 10 - } - } - ] - } - Transform2D { - scale 0.5 0.5 - translation -100 -50 - children [ - DEF P Palette {} - ] - } - Transform2D { - scale 0.5 0.5 - translation 50 -50 - children [ - Palette {} - ] - } - ] -} - -ROUTE P.selectedColor TO Material2DNode.emissiveColor - diff --git a/regression_tests/bifs-proto-route.bt b/regression_tests/bifs-proto-route.bt deleted file mode 100644 index bf4ee24..0000000 --- a/regression_tests/bifs-proto-route.bt +++ /dev/null @@ -1,110 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] { - Transform2D { - rotationAngle IS rotation - scale IS scale - translation IS translation - children [ - DEF S Shape { - geometry IS obj - appearance Appearance { - material DEF M Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - DEF TOUCH TouchSensor {} - ] - } - DEF TS TimeSensor { - loop TRUE - } - DEF C Conditional { - buffer { - DELETE ROUTE RTS - } - } - DEF RC Conditional { - buffer { - INSERT ROUTE DEF RTS TS.fraction_changed TO M.transparency - } - } - DEF RTS ROUTE TS.fraction_changed TO M.transparency - ROUTE TOUCH.isActive TO C.activate - ROUTE TOUCH.isActive TO RC.reverseActivate -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of ROUTES inside a proto" "with deletion/insertion through conditionals" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Simple proto Test" - } - GEOMETRY_PROTO { - translation 200 0 - scale 1 1.5 - rotation 0.78 - Color 1 0 1 - transparency 0.75 - lineColor 1 0 0 - lineWidth 2 - obj DEF C Circle { - radius 75 - } - } - Transform2D { - translation -300 0 - children [ - GEOMETRY_PROTO { - translation 200 0 - scale 1 1.5 - rotation 0.78 - Color 0 0 1 - obj USE C - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-proto-sftime-protocode.bt b/regression_tests/bifs-proto-sftime-protocode.bt deleted file mode 100644 index 98d1ec1..0000000 --- a/regression_tests/bifs-proto-sftime-protocode.bt +++ /dev/null @@ -1,99 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] { - DEF TR Transform2D { - scale IS scale - translation IS translation - children [ - Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - DEF TS TimeSensor { - cycleInterval 4 - loop TRUE - } - ] - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1.76 0] - } - ROUTE TS.fraction_changed TO SI.set_fraction - ROUTE SI.value_changed TO TR.rotationAngle -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["The animation start time embedded in proto body" "Animation shall begin at node creation time" "if objects rotations are in sync the player is broken" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Proto SFTime Test" - } - DEF ROOT Transform2D { - children [ - GEOMETRY_PROTO { - translation -120 0 - Color 0 1 1 - obj Rectangle { - size 200 100 - } - } - ] - } - ] -} - - -AT 2000 { - APPEND TO ROOT.children GEOMETRY_PROTO { - translation 120 0 - Color 1 0 1 - lineColor 1 0 0 - obj Rectangle { - size 200 100 - } - } -} - diff --git a/regression_tests/bifs-proto-sftime-protointerface.bt b/regression_tests/bifs-proto-sftime-protointerface.bt deleted file mode 100644 index 07b4dd2..0000000 --- a/regression_tests/bifs-proto-sftime-protointerface.bt +++ /dev/null @@ -1,104 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFTime start 0 - exposedField SFNode obj NULL -] { - DEF TR Transform2D { - scale IS scale - translation IS translation - children [ - Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - DEF TS TimeSensor { - cycleInterval 4 - loop TRUE - startTime IS start - } - ] - } - DEF SI ScalarInterpolator { - key [0 0.5 1] - keyValue [0 1.5708 0] - } - ROUTE TS.fraction_changed TO SI.set_fraction - ROUTE SI.value_changed TO TR.rotationAngle -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["The animation start time is part of proto interface" "Second object appears at 2 sec and starts moving at 4 sec(2+2)" "If objects rotations are not in sync the player is broken" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Proto SFTime Test" - } - DEF ROOT Transform2D { - children [ - GEOMETRY_PROTO { - translation -120 0 - Color 0 1 1 - obj Rectangle { - size 200 100 - } - } - ] - } - ] -} - - -AT 2000 { - APPEND TO ROOT.children GEOMETRY_PROTO { - translation 120 0 - Color 1 0 1 - transparency 0.75 - lineColor 1 0 0 - lineWidth 2 - start 2 - obj Rectangle { - size 200 100 - } - } -} - diff --git a/regression_tests/bifs-proto-simple.bt b/regression_tests/bifs-proto-simple.bt deleted file mode 100644 index bfa2add..0000000 --- a/regression_tests/bifs-proto-simple.bt +++ /dev/null @@ -1,88 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] { - Transform2D { - rotationAngle IS rotation - scale IS scale - translation IS translation - children [ - Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - ] - } -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows simple proto usage" "The shapes are all instances of a single proto" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Simple proto Test" - } - GEOMETRY_PROTO { - translation -100 0 - Color 0 1 1 - obj Rectangle { - size 100 100 - } - } - GEOMETRY_PROTO { - translation 100 0 - scale 1 1.5 - rotation 0.78 - Color 1 0 1 - transparency 0.75 - lineColor 1 0 0 - lineWidth 2 - obj Circle { - radius 75 - } - } - ] -} - - diff --git a/regression_tests/bifs-proto-use.bt b/regression_tests/bifs-proto-use.bt deleted file mode 100644 index 414565d..0000000 --- a/regression_tests/bifs-proto-use.bt +++ /dev/null @@ -1,93 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -PROTO GEOMETRY_PROTO [ - exposedField SFVec2f translation 0 0 - exposedField SFVec2f scale 1 1 - exposedField SFFloat rotation 0 - exposedField SFColor Color 1 1 1 - exposedField SFBool filled TRUE - exposedField SFFloat transparency 0 - exposedField SFColor lineColor 0 0 0 - exposedField SFFloat lineWidth 0 - exposedField SFNode obj NULL -] { - Transform2D { - rotationAngle IS rotation - scale IS scale - translation IS translation - children [ - DEF S Shape { - geometry IS obj - appearance Appearance { - material Material2D { - emissiveColor IS Color - filled IS filled - transparency IS transparency - lineProps LineProperties { - lineColor IS lineColor - width IS lineWidth - } - } - } - } - Transform2D { - translation -100 0 - children [ - USE S - ] - } - ] - } -} -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of DEF/USE inside a proto" "and DEF/USE of a proto" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Simple proto Test" - } - DEF G GEOMETRY_PROTO { - translation 200 0 - scale 1 1.5 - rotation 0.78 - Color 1 0 1 - transparency 0.75 - lineColor 1 0 0 - lineWidth 2 - obj Circle { - radius 75 - } - } - Transform2D { - translation -300 0 - children [ - USE G - ] - } - ] -} - - diff --git a/regression_tests/bifs-script-char-to-int.bt b/regression_tests/bifs-script-char-to-int.bt deleted file mode 100644 index b559ead..0000000 --- a/regression_tests/bifs-script-char-to-int.bt +++ /dev/null @@ -1,87 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows script sending eventOuts" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Script eventOut test" - } - Transform2D { - translation -150 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TEXT Text { - string ["What"] - fontStyle FontStyle { - justify ["BEGIN" "BEGIN"] - size 20 - } - } - } - ] - } - Transform2D { - translation 150 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TEXT_TEST Text { - string ["T"] - fontStyle FontStyle { - justify ["BEGIN" "BEGIN"] - size 20 - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 0.1 - loop TRUE - } - DEF SCRIPT Script { - eventIn SFTime act - field SFInt32 int_val 0 - field SFNode txt USE TEXT - field SFNode txt2 USE TEXT_TEST - url ["javascript: function initialize(value, timestamp) {int_val = txt.string[0].charCodeAt(0);txt2.string[0] = 'char val: ' + String.fromCharCode(int_val) + ' ' + int_val;}" ] - } - ] -} - - diff --git a/regression_tests/bifs-script-child-create.bt b/regression_tests/bifs-script-child-create.bt deleted file mode 100644 index 4a276b1..0000000 --- a/regression_tests/bifs-script-child-create.bt +++ /dev/null @@ -1,61 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows script creating a new node in an MF field" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Script Node Creation test" - } - Transform2D { - children [ - DEF TS TouchSensor {} - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - ] - } - DEF TR Transform2D { - translation -150 -120 - } - DEF SCRIPT Script { - eventIn SFBool act - field SFNode t USE TR - url ["javascript: function act(value, timestamp) {if (!value) return;t.children[0] = new SFNode('Shape');t.children[0].geometry = new SFNode('Rectangle');t.children[0].geometry.size = new SFVec2f(100, 50);t.children[0].appearance = new SFNode('Appearance');t.children[0].appearance.material = new SFNode('Material2D');t.children[0].appearance.material.filled = true;t.children[0].appearance.material.emissiveColor = new SFColor(0, 0, 1);}" ] - } - ] -} - -ROUTE TS.isActive TO SCRIPT.act - diff --git a/regression_tests/bifs-script-date.bt b/regression_tests/bifs-script-date.bt deleted file mode 100644 index 7875605..0000000 --- a/regression_tests/bifs-script-date.bt +++ /dev/null @@ -1,64 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 260 - pixelHeight 70 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows script used to retrieve system time" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Script Date() test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - string ["MPEG4 time on your system"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - DEF TIMER TimeSensor { - loop TRUE - } - DEF SC Script { - eventIn SFTime set_time - field SFNode str USE TXT - url ["javascript:function set_time(value, text) {today = new Date();the_day = today.getDate();the_weekday = today.getDay();the_month = today.getMonth();the_year = today.getYear();the_hour = today.getHours();the_minute = today.getMinutes();the_second = today.getSeconds();am_pm = 0;the_initials = 'a.m.';if (the_year < 1900) the_year = the_year + 1900;if ((the_hour >=2) && (the_hour <=11)) {am_pm = the_hour;the_initials = 'a.m.';} else if (the_hour == 0) {am_pm = 12;the_initials = 'a.m.';} else if (the_hour == 12) {am_pm = 12;the_initials = 'p.m.';} else if (the_hour >=13) {am_pm = the_hour - 12;the_initials = 'p.m.';}if (the_minute <=9) the_minute = '0' + (the_minute);if (the_second <=9) the_second = '0' + (the_second);if (the_month == '0') the_month = 'January';else if (the_month == '1') the_month = 'February';else if (the_month == '2') the_month = 'March';else if (the_month == '3') the_month = 'April';else if (the_month == '4') the_month = 'May';else if (the_month == '5') the_month = 'June';else if (the_month == '6') the_month = 'July';else if (the_month == '7') the_month = 'August';else if (the_month == '8') the_month = 'September';else if (the_month == '9') the_month = 'October';else if (the_month == '10') the_month = 'November';else if (the_month == '11') the_month = 'December';if (the_weekday == '0') the_weekday = 'Sunday';else if (the_weekday == '1') the_weekday = 'Monday';else if (the_weekday == '2') the_weekday = 'Tuesday';else if (the_weekday == '3') the_weekday = 'Wednesday';else if (the_weekday == '4') the_weekday = 'Thursday';else if (the_weekday == '5') the_weekday = 'Friday';else if (the_weekday == '6') the_weekday = 'Saturday';if (the_day == '1') the_day = '1st';else if (the_day == '2') the_day = '2nd';else if (the_day == '3') the_day = '3rd';else if (the_day == '4') the_day = '4th';else if (the_day == '21') the_day = '21st';else if (the_day == '22') the_day = '23rd';else if (the_day == '31') the_day = '31st';else the_day = the_day + 'th';str.string[1] = the_weekday + ' ' + the_day + ' ' + the_month + ', ' + the_year;str.string[2] = am_pm + ':' + the_minute + ':' + the_second + ' ' + the_initials;}function initialize() {set_time(0, 0);}" ] - } - ] -} - -ROUTE TIMER.cycleTime TO SC.set_time - diff --git a/regression_tests/bifs-script-event-out.bt b/regression_tests/bifs-script-event-out.bt deleted file mode 100644 index 58efb3d..0000000 --- a/regression_tests/bifs-script-event-out.bt +++ /dev/null @@ -1,85 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows script sending eventOuts" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Script eventOut test" - } - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry DEF IFS IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 4 5] - coord Coordinate2D { - point [-120 0 -50 100 50 100 120 0 50 -100 -50 -100] - } - } - } - Transform2D { - translation -150 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TEXT Text { - string [""] - fontStyle FontStyle { - justify ["BEGIN" "BEGIN"] - size 20 - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 0.1 - loop TRUE - } - DEF SCRIPT Script { - eventIn SFTime act - field SFInt32 count 0 - eventOut SFFloat transp - eventOut MFString txt - url ["javascript: function act(value, timestamp) {count++;if (count>= 20) count = 0;transp = count / 20;txt[0] = 'transparency: ' + transp; }" ] - } - ] -} - -ROUTE TS.cycleTime TO SCRIPT.act -ROUTE SCRIPT.transp TO MAT.transparency -ROUTE SCRIPT.txt TO TEXT.string - diff --git a/regression_tests/bifs-script-initialize.bt b/regression_tests/bifs-script-initialize.bt deleted file mode 100644 index b903f81..0000000 --- a/regression_tests/bifs-script-initialize.bt +++ /dev/null @@ -1,86 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows script Initialize usage" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Script initialize test" - } - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry DEF IFS IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 4 5] - coord Coordinate2D { - point [-120 0 -50 100 50 100 120 0 50 -100 -50 -100] - } - } - } - Transform2D { - translation -150 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TEXT Text { - string [""] - fontStyle FontStyle { - family ["SANS"] - justify ["BEGIN" "BEGIN"] - size 20 - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 0.2 - loop TRUE - } - DEF SCRIPT Script { - eventIn SFTime act - field SFInt32 count 0 - eventOut SFFloat transp - eventOut MFString txt - url ["javascript: function initialize(value, timestamp) {my_global_string = 'global int = ';my_global_int = 10;}function act(value, timestamp) {count++;if (count>= 20) count = 0;transp = count / 20;txt[0] = 'transparency: ' + transp; txt[1] = my_global_string + my_global_int; }" ] - } - ] -} - -ROUTE TS.cycleTime TO SCRIPT.act -ROUTE SCRIPT.transp TO MAT.transparency -ROUTE SCRIPT.txt TO TEXT.string - diff --git a/regression_tests/bifs-script-load-url.bt b/regression_tests/bifs-script-load-url.bt deleted file mode 100644 index 459c5e4..0000000 --- a/regression_tests/bifs-script-load-url.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows script loading URL" "" "GPAC Regression Tests" "$Date: 2008/07/18 17:27:50 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Script URL loading" - } - Transform2D { - children [ - DEF TS TouchSensor {} - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - ] - } - DEF TR Transform2D { - translation -150 -120 - } - DEF SCRIPT Script { - eventIn SFBool act - field SFNode t USE TR - url ["javascript: - function act(value, timestamp) { - if (!value) return; - str = new MFString('http://gpac.sourceforge.net'); - Browser.loadURL(str) ; - } - " ] - } - ] -} - -ROUTE TS.isActive TO SCRIPT.act - diff --git a/regression_tests/bifs-script-node-access.bt b/regression_tests/bifs-script-node-access.bt deleted file mode 100644 index 83e91eb..0000000 --- a/regression_tests/bifs-script-node-access.bt +++ /dev/null @@ -1,86 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows script modifying nodes directly" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Node Modification Script test" - } - Shape { - appearance Appearance { - material DEF MAT Material2D { - filled TRUE - } - } - geometry DEF IFS IndexedFaceSet2D { - colorIndex [0 1 2 3 4 5] - coordIndex [0 1 2 3 4 5] - color Color { - color [0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1] - } - coord Coordinate2D { - point [-120 0 -50 100 50 100 120 0 50 -100 -50 -100] - } - } - } - DEF TS TimeSensor { - loop TRUE - } - Transform2D { - translation -150 -120 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TEXT Text { - string [""] - fontStyle FontStyle { - family ["SANS"] - justify ["BEGIN" "BEGIN"] - size 20 - } - } - } - ] - } - DEF SCRIPT Script { - eventIn SFTime act - field SFNode n USE IFS - field SFNode t USE TS - field SFNode txt USE TEXT - field SFInt32 roll 0 - url ["javascript: function act(value, timestamp) {roll++;count = n.colorIndex.length;first = n.colorIndex[0];for (i=0; i<count; i++) {if (i+1==count) {n.colorIndex[i] = first;} else {n.colorIndex[i] = n.colorIndex[i+1];}}txt.string[0] = 'ColorIndexes: ' + n.colorIndex.toSource();txt.string[2] = 'Current Cycle length: ' + (count * t.cycleInterval) + ' seconds';txt.string[1] = 'Running for ' + timestamp + ' seconds';switch (roll) {case 6:t.enabled = FALSE;t.cycleInterval = 0.5;t.enabled = TRUE;break;case 18:t.enabled = FALSE;t.cycleInterval = 0.1;t.enabled = TRUE;break;case 78:t.enabled = FALSE;t.cycleInterval = 0.05;t.enabled = TRUE;break;case 198:roll = 0;t.enabled = FALSE;t.cycleInterval = 1;t.enabled = TRUE;break;}}" ] - } - ] -} - -ROUTE TS.cycleTime TO SCRIPT.act - diff --git a/regression_tests/bifs-script-node-create.bt b/regression_tests/bifs-script-node-create.bt deleted file mode 100644 index 01625e8..0000000 --- a/regression_tests/bifs-script-node-create.bt +++ /dev/null @@ -1,80 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows script creating a new node at an SF field" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Script Node Creation test" - } - Transform2D { - children [ - DEF TS TouchSensor {} - Shape { - appearance Appearance { - material DEF MAT Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 50 50 - } - } - ] - } - Transform2D { - translation -150 -120 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TEXT Text { - string ["test node create"] - fontStyle FontStyle { - family ["SANS"] - justify ["BEGIN" "BEGIN"] - size 40 - style "BOLDITALIC" - } - } - } - ] - } - DEF SCRIPT Script { - eventIn SFBool act - field SFNode ap USE APP - url ["javascript: function act(value, timestamp) {mat = new SFNode('Material2D');if (value) {mat.emissiveColor = new SFColor(1, 0, 0);mat.filled = TRUE;} else {mat.emissiveColor = new SFColor(0, 0, 0);mat.filled = TRUE;}ap.material = mat;}" ] - } - ] -} - -ROUTE TS.isActive TO SCRIPT.act - diff --git a/regression_tests/bifs-script-proto.bt b/regression_tests/bifs-script-proto.bt deleted file mode 100644 index a47a0a8..0000000 --- a/regression_tests/bifs-script-proto.bt +++ /dev/null @@ -1,223 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ] -} - -PROTO P0 [ - field SFVec2f trans 0 0 -] { - Transform2D { - translation IS trans - children [ - DEF TS TouchSensor {} - DEF TR1 Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps DEF LP LineProperties { - lineColor 0.2 0.5 0.8 - width 0 - } - } - } - geometry Circle { - radius 8 - } - } - ] - } - DEF TIMER TimeSensor { - cycleInterval 0.5 - startTime -1 - } - ] - } - DEF SC Script { - eventIn SFBool set_over - eventIn SFFloat set_fraction - eventIn SFBool set_active - field SFNode tim USE TIMER - field SFNode line USE LP - eventOut SFFloat frac_changed - url ["javascript: - function set_active(value, timestamp) { - line.width = value ? 2 : 0; - } - function set_over(value, timestamp) { - is_over = value; - if (!tim.isActive) tim.startTime = timestamp; - } - function set_fraction(value, timestamp) { - if (is_over) { - frac_changed = value; - } else { - frac_changed = 1 - value; - } - } - " ] - } - DEF PI PositionInterpolator2D { - key [0 1] - keyValue [1 1 4 4] - } - ROUTE TS.isOver TO SC.set_over - ROUTE TIMER.isActive TO SC.set_active - ROUTE TIMER.fraction_changed TO SC.set_fraction - ROUTE SC.frac_changed TO PI.set_fraction - ROUTE PI.value_changed TO TR1.scale -} -PROTO P1 [ - field SFVec2f trans 0 0 -] { - Transform2D { - translation IS trans - children [ - P0 { - trans -180 0 - } - P0 { - trans -160 0 - } - P0 { - trans -140 0 - } - P0 { - trans -120 0 - } - P0 { - trans -100 0 - } - P0 { - trans -80 0 - } - P0 { - trans -60 0 - } - P0 { - trans -40 0 - } - P0 { - trans -20 0 - } - P0 {} - P0 { - trans 20 0 - } - P0 { - trans 40 0 - } - P0 { - trans 60 0 - } - P0 { - trans 80 0 - } - P0 { - trans 100 0 - } - P0 { - trans 120 0 - } - P0 { - trans 140 0 - } - P0 { - trans 160 0 - } - P0 { - trans 180 0 - } - ] - } -} -OrderedGroup { - children [ - Background2D { - backColor 0.2 0.4 0.7 - } - WorldInfo { - info ["This shows script used in proto for a bubble-like effect" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Script and Proto test" - } - Transform2D { - children [ - P1 { - trans 0 180 - } - P1 { - trans 0 160 - } - P1 { - trans 0 140 - } - P1 { - trans 0 120 - } - P1 { - trans 0 100 - } - P1 { - trans 0 80 - } - P1 { - trans 0 60 - } - P1 { - trans 0 40 - } - P1 { - trans 0 20 - } - P1 {} - P1 { - trans 0 -20 - } - P1 { - trans 0 -40 - } - P1 { - trans 0 -60 - } - P1 { - trans 0 -80 - } - P1 { - trans 0 -100 - } - P1 { - trans 0 -120 - } - P1 { - trans 0 -140 - } - P1 { - trans 0 -160 - } - P1 { - trans 0 -180 - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-script-timestamp.bt b/regression_tests/bifs-script-timestamp.bt deleted file mode 100644 index 5ba29e5..0000000 --- a/regression_tests/bifs-script-timestamp.bt +++ /dev/null @@ -1,67 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows script timestamp value" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Script timing test" - } - Transform2D { - translation -150 0 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TEXT Text { - string [""] - fontStyle FontStyle { - family ["SANS"] - justify ["BEGIN" "MIDDLE"] - size 20 - } - } - } - ] - } - DEF TS TimeSensor { - cycleInterval 0.2 - loop TRUE - } - 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);}" ] - } - ] -} - -ROUTE TS.cycleTime TO SCRIPT.act - diff --git a/regression_tests/bifs-stream-text-switch.bt b/regression_tests/bifs-stream-text-switch.bt deleted file mode 100644 index 7b13a22..0000000 --- a/regression_tests/bifs-stream-text-switch.bt +++ /dev/null @@ -1,143 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - includeInlineProfileLevelFlag true - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 0 1 0 - } - WorldInfo { - info ["This shows an AnimationStream node" "controling a 3GPP text stream" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2005 GPAC Team"] - title "3GPP Text Switch" - } - - Transform2D { - translation -50 0 - children [ - DEF TS1 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 75 50 - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["English"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - Transform2D { - translation 50 0 - children [ - DEF TS2 TouchSensor {} - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Rectangle { - size 75 50 - } - } - Shape { - appearance USE APP - geometry Text { - string ["French"] - fontStyle USE FS - } - } - ] - } - - DEF AS AnimationStream { - loop TRUE - url [od:20] - } - DEF C1 Conditional { buffer { - REPLACE AS.stopTime BY 0 - REPLACE AS.url BY ["od:10"] - REPLACE AS.startTime BY 0 - } - } - DEF C2 Conditional { buffer { - REPLACE AS.stopTime BY 0 - REPLACE AS.url BY ["od:20"] - REPLACE AS.startTime BY 0 - } } - ] -} - -ROUTE TS1.isActive TO C1.activate -ROUTE TS2.isActive TO C2.activate - - -RAP AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 5 - OCR_ES_ID 5 - muxInfo MuxInfo { fileName "auxiliary_files/subtitle.srt" } - } - ] - } - ObjectDescriptor { - objectDescriptorID 20 - esDescr [ - ES_Descriptor { - ES_ID 6 - OCR_ES_ID 6 - muxInfo MuxInfo { fileName "auxiliary_files/subtitle_fr.srt" } - } - ] - } - ] -} diff --git a/regression_tests/bifs-text-align-horiz1.bt b/regression_tests/bifs-text-align-horiz1.bt deleted file mode 100644 index 794ea54..0000000 --- a/regression_tests/bifs-text-align-horiz1.bt +++ /dev/null @@ -1,304 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text alignment for horizontal text" "top to bottom = TRUE" "left to right = TRUE" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Horizontal Text alignment" - } - Transform2D { - translation -180 180 - children [ - DEF LINES Shape { - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1] - coord Coordinate2D { - point [-50 0 50 0 0 -50 0 50] - } - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["M:Begin" "m:Begin"] - fontStyle FontStyle { - justify ["BEGIN" "BEGIN"] - size 20 - } - } - } - ] - } - Transform2D { - translation -80 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:Middle"] - fontStyle FontStyle { - justify ["BEGIN" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 20 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:End"] - fontStyle FontStyle { - justify ["BEGIN" "END"] - size 20 - } - } - } - ] - } - Transform2D { - translation 120 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:First"] - fontStyle FontStyle { - justify ["BEGIN" "FIRST"] - size 20 - } - } - } - ] - } - Transform2D { - translation -180 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:Begin"] - fontStyle FontStyle { - justify ["MIDDLE" "BEGIN"] - size 20 - } - } - } - ] - } - Transform2D { - translation -80 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:Middle"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 20 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:End"] - fontStyle FontStyle { - justify ["MIDDLE" "END"] - size 20 - } - } - } - ] - } - Transform2D { - translation 120 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:First"] - fontStyle FontStyle { - justify ["MIDDLE" "FIRST"] - size 20 - } - } - } - ] - } - Transform2D { - translation -180 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:Begin"] - fontStyle FontStyle { - justify ["END" "BEGIN"] - size 20 - } - } - } - ] - } - Transform2D { - translation -80 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:Middle"] - fontStyle FontStyle { - justify ["END" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 20 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:End"] - fontStyle FontStyle { - justify ["END" "END"] - size 20 - } - } - } - ] - } - Transform2D { - translation 120 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:First"] - fontStyle FontStyle { - justify ["END" "FIRST"] - size 20 - } - } - } - ] - } - Transform2D { - translation -180 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:Begin"] - fontStyle FontStyle { - justify ["FIRST" "BEGIN"] - size 20 - } - } - } - ] - } - Transform2D { - translation -80 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:Middle"] - fontStyle FontStyle { - justify ["FIRST" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 20 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:End"] - fontStyle FontStyle { - justify ["FIRST" "END"] - size 20 - } - } - } - ] - } - Transform2D { - translation 120 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:First"] - fontStyle FontStyle { - justify ["FIRST" "FIRST"] - size 20 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-align-horiz2.bt b/regression_tests/bifs-text-align-horiz2.bt deleted file mode 100644 index 1aac58c..0000000 --- a/regression_tests/bifs-text-align-horiz2.bt +++ /dev/null @@ -1,320 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text alignment for horizontal text" "top to bottom = FALSE" "left to right = TRUE" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Horizontal Text alignment" - } - Transform2D { - translation -180 180 - children [ - DEF LINES Shape { - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1] - coord Coordinate2D { - point [-50 0 50 0 0 -50 0 50] - } - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["M:Begin" "m:Begin"] - fontStyle FontStyle { - justify ["BEGIN" "BEGIN"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -80 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:Middle"] - fontStyle FontStyle { - justify ["BEGIN" "MIDDLE"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 20 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:End"] - fontStyle FontStyle { - justify ["BEGIN" "END"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 120 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:First"] - fontStyle FontStyle { - justify ["BEGIN" "FIRST"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -180 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:Begin"] - fontStyle FontStyle { - justify ["MIDDLE" "BEGIN"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -80 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:Middle"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 20 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:End"] - fontStyle FontStyle { - justify ["MIDDLE" "END"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 120 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:First"] - fontStyle FontStyle { - justify ["MIDDLE" "FIRST"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -180 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:Begin"] - fontStyle FontStyle { - justify ["END" "BEGIN"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -80 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:Middle"] - fontStyle FontStyle { - justify ["END" "MIDDLE"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 20 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:End"] - fontStyle FontStyle { - justify ["END" "END"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 120 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:First"] - fontStyle FontStyle { - justify ["END" "FIRST"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -180 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:Begin"] - fontStyle FontStyle { - justify ["FIRST" "BEGIN"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -80 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:Middle"] - fontStyle FontStyle { - justify ["FIRST" "MIDDLE"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 20 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:End"] - fontStyle FontStyle { - justify ["FIRST" "END"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 120 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:First"] - fontStyle FontStyle { - justify ["FIRST" "FIRST"] - size 20 - topToBottom FALSE - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-align-horiz3.bt b/regression_tests/bifs-text-align-horiz3.bt deleted file mode 100644 index fa05d75..0000000 --- a/regression_tests/bifs-text-align-horiz3.bt +++ /dev/null @@ -1,320 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text alignment for horizontal text" "top to bottom = TRUE" "left to right = FALSE" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Horizontal Text alignment" - } - Transform2D { - translation -180 180 - children [ - DEF LINES Shape { - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1] - coord Coordinate2D { - point [-50 0 50 0 0 -50 0 50] - } - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["M:Begin" "m:Begin"] - fontStyle FontStyle { - justify ["BEGIN" "BEGIN"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation -80 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:Middle"] - fontStyle FontStyle { - justify ["BEGIN" "MIDDLE"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 20 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:End"] - fontStyle FontStyle { - justify ["BEGIN" "END"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 120 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:First"] - fontStyle FontStyle { - justify ["BEGIN" "FIRST"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation -180 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:Begin"] - fontStyle FontStyle { - justify ["MIDDLE" "BEGIN"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation -80 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:Middle"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 20 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:End"] - fontStyle FontStyle { - justify ["MIDDLE" "END"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 120 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:First"] - fontStyle FontStyle { - justify ["MIDDLE" "FIRST"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation -180 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:Begin"] - fontStyle FontStyle { - justify ["END" "BEGIN"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation -80 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:Middle"] - fontStyle FontStyle { - justify ["END" "MIDDLE"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 20 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:End"] - fontStyle FontStyle { - justify ["END" "END"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 120 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:First"] - fontStyle FontStyle { - justify ["END" "FIRST"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation -180 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:Begin"] - fontStyle FontStyle { - justify ["FIRST" "BEGIN"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation -80 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:Middle"] - fontStyle FontStyle { - justify ["FIRST" "MIDDLE"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 20 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:End"] - fontStyle FontStyle { - justify ["FIRST" "END"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 120 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:First"] - fontStyle FontStyle { - justify ["FIRST" "FIRST"] - leftToRight FALSE - size 20 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-align-horiz4.bt b/regression_tests/bifs-text-align-horiz4.bt deleted file mode 100644 index 970368e..0000000 --- a/regression_tests/bifs-text-align-horiz4.bt +++ /dev/null @@ -1,336 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text alignment for horizontal text" "top to bottom = FALSE" "left to right = FALSE" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Horizontal Text alignment" - } - Transform2D { - translation -180 180 - children [ - DEF LINES Shape { - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1] - coord Coordinate2D { - point [-50 0 50 0 0 -50 0 50] - } - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["M:Begin" "m:Begin"] - fontStyle FontStyle { - justify ["BEGIN" "BEGIN"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -80 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:Middle"] - fontStyle FontStyle { - justify ["BEGIN" "MIDDLE"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 20 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:End"] - fontStyle FontStyle { - justify ["BEGIN" "END"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 120 180 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Begin" "m:First"] - fontStyle FontStyle { - justify ["BEGIN" "FIRST"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -180 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:Begin"] - fontStyle FontStyle { - justify ["MIDDLE" "BEGIN"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -80 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:Middle"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 20 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:End"] - fontStyle FontStyle { - justify ["MIDDLE" "END"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 120 50 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:Middle" "m:First"] - fontStyle FontStyle { - justify ["MIDDLE" "FIRST"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -180 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:Begin"] - fontStyle FontStyle { - justify ["END" "BEGIN"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -80 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:Middle"] - fontStyle FontStyle { - justify ["END" "MIDDLE"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 20 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:End"] - fontStyle FontStyle { - justify ["END" "END"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 120 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:End" "m:First"] - fontStyle FontStyle { - justify ["END" "FIRST"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -180 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:Begin"] - fontStyle FontStyle { - justify ["FIRST" "BEGIN"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -80 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:Middle"] - fontStyle FontStyle { - justify ["FIRST" "MIDDLE"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 20 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:End"] - fontStyle FontStyle { - justify ["FIRST" "END"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 120 -160 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["M:First" "m:First"] - fontStyle FontStyle { - justify ["FIRST" "FIRST"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-align-vert1.bt b/regression_tests/bifs-text-align-vert1.bt deleted file mode 100644 index f1eada6..0000000 --- a/regression_tests/bifs-text-align-vert1.bt +++ /dev/null @@ -1,200 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text alignment for vertical text" "top to bottom = TRUE" "left to right = TRUE" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Vertical Text alignment" - } - Transform2D { - translation -150 220 - children [ - DEF LINES Shape { - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1] - coord Coordinate2D { - point [-50 0 50 0 0 -50 0 50] - } - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["MBegin" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "BEGIN"] - size 20 - } - } - } - ] - } - Transform2D { - translation -150 70 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MBegin" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -150 -90 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MBegin" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "END"] - size 20 - } - } - } - ] - } - Transform2D { - translation 0 150 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - size 20 - } - } - } - ] - } - Transform2D { - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 0 -150 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "END"] - size 20 - } - } - } - ] - } - Transform2D { - translation 150 100 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "BEGIN"] - size 20 - } - } - } - ] - } - Transform2D { - translation 150 -80 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 150 -200 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "END"] - size 20 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-align-vert2.bt b/regression_tests/bifs-text-align-vert2.bt deleted file mode 100644 index 7c37412..0000000 --- a/regression_tests/bifs-text-align-vert2.bt +++ /dev/null @@ -1,209 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text alignment for vertical text" "top to bottom = FALSE" "left to right = TRUE" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Vertical Text alignment" - } - Transform2D { - translation -150 100 - children [ - DEF LINES Shape { - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1] - coord Coordinate2D { - point [-50 0 50 0 0 -50 0 50] - } - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["MBegin" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "BEGIN"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -150 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MBegin" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -150 -200 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MBegin" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "END"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 0 150 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 0 -150 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "END"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 150 200 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "BEGIN"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 150 60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "MIDDLE"] - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 150 -120 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "END"] - size 20 - topToBottom FALSE - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-align-vert3.bt b/regression_tests/bifs-text-align-vert3.bt deleted file mode 100644 index 4a282f1..0000000 --- a/regression_tests/bifs-text-align-vert3.bt +++ /dev/null @@ -1,209 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text alignment for vertical text" "top to bottom = TRUE" "left to right = FALSE" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Vertical Text alignment" - } - Transform2D { - translation -150 220 - children [ - DEF LINES Shape { - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1] - coord Coordinate2D { - point [-50 0 50 0 0 -50 0 50] - } - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["MBegin" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "BEGIN"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation -150 70 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MBegin" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation -150 -90 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MBegin" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "END"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 0 150 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 0 -150 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "END"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 150 100 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "BEGIN"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 150 -80 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "MIDDLE"] - leftToRight FALSE - size 20 - } - } - } - ] - } - Transform2D { - translation 150 -200 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "END"] - leftToRight FALSE - size 20 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-align-vert4.bt b/regression_tests/bifs-text-align-vert4.bt deleted file mode 100644 index cb15fff..0000000 --- a/regression_tests/bifs-text-align-vert4.bt +++ /dev/null @@ -1,218 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text alignment for vertical text" "top to bottom = FALSE" "left to right = FALSE" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Vertical Text alignment" - } - Transform2D { - translation -150 100 - children [ - DEF LINES Shape { - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1] - coord Coordinate2D { - point [-50 0 50 0 0 -50 0 50] - } - } - } - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["MBegin" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "BEGIN"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -150 -60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MBegin" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "MIDDLE"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation -150 -200 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MBegin" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["BEGIN" "END"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 0 150 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "BEGIN"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 0 -150 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MMiddle" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "END"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 150 200 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mBegin"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "BEGIN"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 150 60 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mMiddle"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "MIDDLE"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - Transform2D { - translation 150 -120 - children [ - USE LINES - Shape { - appearance USE APP - geometry Text { - string ["MEnd" "mEnd"] - fontStyle FontStyle { - horizontal FALSE - justify ["END" "END"] - leftToRight FALSE - size 20 - topToBottom FALSE - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-glyph-advance.bt b/regression_tests/bifs-text-glyph-advance.bt deleted file mode 100644 index 2a55f2d..0000000 --- a/regression_tests/bifs-text-glyph-advance.bt +++ /dev/null @@ -1,436 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSv2Config { - isCommandStream true - pixelMetric true - pixelWidth 480 - pixelHeight 360 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { backColor 1 1 1 } - WorldInfo { - info ["This test shows glyphs, along with their bounding boxes, the font baseline, the word bounding box and the two-lines text bounding box" "If the Arial font is found and used, bounding-boxes should be properly positioned" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2006 GPAC Team"] - title "Text bounding boxes test" - } - Transform2D { - translation -140 80 - children [ - Transform2D { - scale 0.048828125 0.048828125 - children [ - # Em Box Y Axis - Shape { - appearance DEF A1 Appearance { - material Material2D { - filled FALSE - lineProps LineProperties { - width 1 - lineColor 0 0 0 - } - } - } - geometry IndexedLineSet2D { - coord Coordinate2D { - point [ 0 -4000 0 1491 ] - } - } - } - - # Baseline - DEF BASELINE Shape { - appearance USE A1 - geometry IndexedLineSet2D { - coord Coordinate2D { - point [ 0 0 8000 0 ] - } - } - } - - # bounding box for glyph a - Transform2D { - translation 0 0 - children [ - Shape { - appearance DEF A2 Appearance { - material Material2D { - filled FALSE - lineProps LineProperties { - width 1 - lineColor 1 0 0 - } - } - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 74 -24 1052 -24 1052 1086 74 1086 ] - } - } - } - ] - } - - # bounding box for glyph b - Transform2D { - translation 1139 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 134 -24 1055 -24 1055 1466 134 1466 ] - } - } - } - ] - } - - # bounding box for glyph c - Transform2D { - translation 2278 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 80 -24 - 1005 -24 - 1005 1086 - 80 1086 ] - } - } - } - ] - } - - # bounding box for glyph d - Transform2D { - translation 3302 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 70 -24 - 991 -24 - 991 1466 - 70 1466 ] - } - } - } - ] - } - - # bounding box for glyph e - Transform2D { - translation 4441 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 75 -24 - 1054 -24 - 1054 1086 - 75 1086 ] - } - } - } - ] - } - - # bounding box for glyph f - Transform2D { - translation 5580 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 19 0 - 640 0 - 640 1491 - 19 1491 ] - } - } - } - ] - } - - # bounding box for glyph g - Transform2D { - translation 6149 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 66 -431 - 1002 -431 - 1002 1086 - 66 1086 ] - } - } - } - ] - } - - # bounding box for the first line - Transform2D { - translation 0 0 - children [ - Shape { - appearance DEF A3 Appearance { - material Material2D { - filled FALSE - lineProps LineProperties { - width 1 - lineColor 0 0.5 0 - } - } - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 74 -431 - 74 1491 - 7151 1491 - 7151 -431 ] - } - } - } - ] - } - Transform2D { - translation 0 -2048 - children [ - USE BASELINE - # bounding box for glyph h - Transform2D { - translation 0 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 135 0 - 1000 0 - 1000 1466 - 135 1466 ] - } - } - } - ] - } - - # bounding box for glyph i - Transform2D { - translation 1139 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 136 0 - 316 0 - 316 1466 - 136 1466 ] - } - } - } - ] - } - - # bounding box for glyph j - Transform2D { - translation 1594 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ -94 -431 - 314 -431 - 314 1466 - -94 1466 ] - } - } - } - ] - } - - # bounding box for glyph k - Transform2D { - translation 2049 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 136 0 - 1016 0 - 1016 1466 - 136 1466 ] - } - } - } - ] - } - - # bounding box for glyph l - Transform2D { - translation 3087 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 131 0 - 311 0 - 311 1466 - 131 1466 ] - } - } - } - ] - } - - # bounding box for glyph m - Transform2D { - translation 3542 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 135 0 - 1574 0 - 1574 1086 - 135 1086 ] - } - } - } - ] - } - - # bounding box for glyph n - Transform2D { - translation 5248 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 135 0 - 998 0 - 998 1086 - 135 1086 ] - } - } - } - ] - } - - # bounding box for glyph o - Transform2D { - translation 6387 0 - children [ - Shape { - appearance USE A2 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 68 -24 - 1063 -24 - 1063 1086 - 68 1086 ] - } - } - } - ] - } - - # bounding box for the second line - Transform2D { - translation 0 0 - children [ - Shape { - appearance USE A3 - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 135 -431 - 135 1466 - 7436 1466 - 7436 -431 ] - } - } - } - ] - } - - ] - } - - # bounding box for the whole text - Transform2D { - translation 0 0 - children [ - Shape { - appearance Appearance { - material Material2D { - filled FALSE - lineProps LineProperties { - width 1 - lineColor 1 1 0 - } - } - } - geometry IndexedFaceSet2D { - coord Coordinate2D { - point [ 74 1491 - 7436 1491 - 7436 -2479 - 74 -2479 ] - } - } - } - ] - } - - ] - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string [ "abcdefg" "hijklmno"] - fontStyle FontStyle { - family ["Arial"] - justify ["BEGIN" "FIRST"] - size 100 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-length.bt b/regression_tests/bifs-text-length.bt deleted file mode 100644 index 3e111f6..0000000 --- a/regression_tests/bifs-text-length.bt +++ /dev/null @@ -1,230 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 450 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text with and without length fields" "All texts use the same font and size" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Text length Test" - } - Transform2D { - translation -75 0 - children [ - Shape { - geometry IndexedLineSet2D { - coord Coordinate2D { - point [0 200 0 -120] - } - } - } - ] - } - Transform2D { - translation 75 0 - children [ - Shape { - geometry IndexedLineSet2D { - coord Coordinate2D { - point [0 200 0 -120] - } - } - } - ] - } - Transform2D { - translation 0 150 - children [ - Shape { - geometry IndexedLineSet2D { - coord Coordinate2D { - point [200 0 -200 0] - } - } - } - ] - } - Transform2D { - translation -150 180 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["No length"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE"] - size 24 - } - } - } - ] - } - Transform2D { - translation 0 180 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Length on " "longest line"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 150 180 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Length on" "all lines"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -150 100 - children [ - DEF SQUARE Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Rectangle { - size 100 80 - } - } - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Text" "to test length"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 0 100 - children [ - USE SQUARE - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Text" "to test length"] - length [-1 100] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 150 100 - children [ - USE SQUARE - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Text" "to test length"] - length [100 100] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -150 -50 - children [ - DEF VSQUARE Shape { - appearance USE APP - geometry Rectangle { - size 80 100 - } - } - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Length" "Test"] - fontStyle DEF FS2 FontStyle { - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - size 24 - } - } - } - ] - } - Transform2D { - translation 0 -50 - children [ - USE VSQUARE - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Length" "Test"] - length [100 -1] - fontStyle USE FS2 - } - } - ] - } - Transform2D { - translation 150 -50 - children [ - USE VSQUARE - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Length" "Test"] - length [100 100] - fontStyle USE FS2 - } - } - ] - } - Transform2D { - scale 0.8 0.8 - translation 0 -160 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Horizontal Rectangles are 100x80 pixels" "Vertical Rectangles are 80x100 pixels" "Length is set to longest dimension of the rectangle"] - fontStyle USE FS - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-maxextend.bt b/regression_tests/bifs-text-maxextend.bt deleted file mode 100644 index 17d8b58..0000000 --- a/regression_tests/bifs-text-maxextend.bt +++ /dev/null @@ -1,176 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 350 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text with and without max Extent" "All texts use the same font and size" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Text maxExtend Test" - } - Shape { - geometry IndexedLineSet2D { - coord Coordinate2D { - point [0 200 0 -160] - } - } - } - Transform2D { - translation -80 160 - children [ - Shape { - appearance DEF TEXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["maxExtent off"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 80 160 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["maxExtent on"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -80 100 - children [ - DEF SQUARE Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 1 1 0 - filled TRUE - } - } - geometry Rectangle { - size 90 80 - } - } - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Some Text" "to test extent"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 80 100 - children [ - USE SQUARE - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Some Text" "to test extent"] - maxExtent 90 - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -80 -60 - children [ - DEF VSQUARE Shape { - appearance USE APP - geometry Rectangle { - size 80 100 - } - } - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Extent" "Text"] - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 80 -60 - children [ - USE VSQUARE - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Extent" "Text"] - maxExtent 100 - fontStyle FontStyle { - horizontal FALSE - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 0 -180 - children [ - Shape { - appearance USE TEXTAPP - geometry Text { - string ["Horizontal Rectangles: 100x80 pixels" "Vertical Rectangles: 80x100 pixels" "MaxExtent: longest dimension"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-style.bt b/regression_tests/bifs-text-style.bt deleted file mode 100644 index c9efdd1..0000000 --- a/regression_tests/bifs-text-style.bt +++ /dev/null @@ -1,184 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 260 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows Text with different styles" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Font Style Test" - } - Transform2D { - translation 0 180 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Plain Text"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation 0 140 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Bold Text"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - style "BOLD" - } - } - } - ] - } - Transform2D { - translation 0 100 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Italic Text"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - style "ITALIC" - } - } - } - ] - } - Transform2D { - translation 0 60 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Bold Italic Text"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - style "BOLDITALIC" - } - } - } - ] - } - Transform2D { - translation 0 20 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Underlined Text"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - style "UNDERLINED" - } - } - } - ] - } - Transform2D { - translation 0 -20 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Underlined Italic Text"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - style "ITALIC UNDERLINED" - } - } - } - ] - } - Transform2D { - translation 0 -60 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Underlined Bold Text"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - style "BOLD UNDERLINED" - } - } - } - ] - } - Transform2D { - translation 0 -100 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Underlined Bold" "Italic Text"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - style "BOLDITALIC UNDERLINED" - } - } - } - ] - } - Transform2D { - translation 0 -160 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Strikeout Text" "(Not Normative)"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 20 - style "STRIKEOUT" - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-unicode.bt b/regression_tests/bifs-text-unicode.bt deleted file mode 100644 index 398dc99..0000000 --- a/regression_tests/bifs-text-unicode.bt +++ /dev/null @@ -1,55 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 260 - pixelHeight 450 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows non ASCII Text characters" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "Font Style Test" - } - Transform2D { - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Non-Ansi:" "" "é à è ù ü ä ë ï ö ü ÿ" "" "" "XML escapes:" "" "& ' \\" > <"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 26 - } - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-text-vrml-alignment.bt b/regression_tests/bifs-text-vrml-alignment.bt deleted file mode 100644 index dc506b5..0000000 --- a/regression_tests/bifs-text-vrml-alignment.bt +++ /dev/null @@ -1,161 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 1 - visualProfileLevelIndication 1 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSv2Config { - isCommandStream true - pixelMetric true - pixelWidth 480 - pixelHeight 360 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows VRML text basline alignment" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "VRML Text alignmentSRT importing Test" - } - Transform2D { - translation -200 150 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Conformance Test"] - fontStyle FontStyle { - family ["Courier"] - justify ["BEGIN" "MIDDLE"] - size 15 - style "BOLD" - } - } - } - ] - } - Transform2D { - translation -200 40 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Sample from VRML 97 Spec (Section 6.20.1)" "FontStyle Parameters:" " family \"Courier\"" " size 20" " spacing 1.5" " justify [ \"BEGIN\" \"FIRST\" ]" "Text Position is (0,0)" "Thin lines are drawn at Y = 20, Y = -10, Y =-40." "Thick lines are drawn at Y = 0, Y = -30, Y =-60." "According to VRML, thick lines should match baseline."] - fontStyle FontStyle { - family ["Courier"] - justify ["BEGIN" "MIDDLE"] - size 15 - } - } - } - ] - } - Transform2D { - translation -215 -80 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Text { - string ["(0,0)"] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 15 - } - } - } - ] - } - Transform2D { - translation -200 -80 - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - width 2 - } - } - } - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1 4 5 -1] - coord Coordinate2D { - point [0 0 400 0 0 -30 400 -30 0 -60 400 -60] - } - } - } - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties {} - - } - } - geometry IndexedLineSet2D { - coordIndex [0 1 -1 2 3 -1 4 5 -1 6 7 -1 8 9 -1] - coord Coordinate2D { - point [0 20 400 20 0 -10 400 -10 0 -40 400 -40 0 20 0 -60 400 20 400 -60] - } - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Text { - string ["This is a line of text." "This is the 2nd line of text." "This is the third."] - fontStyle FontStyle { - family ["Courier"] - justify ["BEGIN" "FIRST"] - size 20 - spacing 1.5 - } - } - } - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Circle { - radius 2 - } - } - ] - } - ] -} - - diff --git a/regression_tests/bifs-timeline-mediacontrol-OCR.bt b/regression_tests/bifs-timeline-mediacontrol-OCR.bt deleted file mode 100644 index c22f60c..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-OCR.bt +++ /dev/null @@ -1,245 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 400 - pixelHeight 400 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows media streams synchronized to an empty OCR stream" "and mediaControl controling the OCR playback" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Animation Stream" - } - Transform2D { - translation 0 160 - children [ - Shape { - appearance DEF TXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Click on video to switch streams"] - fontStyle DEF TXTFT FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 16 - } - } - } - ] - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF MT MovieTexture { - url [od:12] - } - } - geometry Bitmap {} - - } - DEF TS TouchSensor {} - ] - } - Transform2D { - translation -120 -160 - children [ - Shape { - appearance Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 40 20 - } - } - Shape { - appearance USE TXTAPP - geometry DEF TXT Text { - string ["Stop"] - fontStyle USE TXTFT - } - } - DEF TS2 TouchSensor {} - ] - } - Transform2D { - translation 40 -160 - children [ - Transform2D { - translation -30 0 - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["OCR Time:"] - fontStyle USE TXTFT - } - } - ] - } - Transform2D { - translation 60 0 - children [ - Shape { - appearance USE TXTAPP - geometry DEF OCR_TIME Text { - string ["Stop"] - fontStyle USE TXTFT - } - } - ] - } - ] - } - Transform2D { - translation 40 -180 - children [ - Transform2D { - translation -30 0 - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["OCR Duration:"] - fontStyle USE TXTFT - } - } - ] - } - Transform2D { - translation 60 0 - children [ - Shape { - appearance USE TXTAPP - geometry DEF OCR_DUR Text { - string ["Stop"] - fontStyle USE TXTFT - } - } - ] - } - ] - } - DEF C Conditional { - buffer { - REPLACE MT.url BY ["od:12"] - REPLACE ROUTE R1 BY TS.isActive TO RC.activate - } - } - DEF RC Conditional { - buffer { - REPLACE MT.url BY ["od:10"] - REPLACE ROUTE R1 BY TS.isActive TO C.activate - } - } - DEF MC MediaControl { - url [od:8] - loop TRUE - preRoll FALSE - } - DEF MS MediaSensor { - url [od:8] - } - DEF VMS Valuator {} - DEF VMS2 Valuator {} - DEF C2 Conditional { - buffer { - REPLACE MC.mediaSpeed BY 0 - REPLACE TXT.string BY ["Play"] - REPLACE ROUTE R2 BY TS2.isActive TO RC2.activate - } - } - DEF RC2 Conditional { - buffer { - REPLACE MC.mediaSpeed BY 1 - REPLACE TXT.string BY ["Stop"] - REPLACE ROUTE R2 BY TS2.isActive TO C2.activate - } - } - ] -} - -DEF R1 ROUTE TS.isActive TO C.activate -DEF R2 ROUTE TS2.isActive TO C2.activate -ROUTE MS.mediaCurrentTime TO VMS.inSFTime -ROUTE VMS.outMFString TO OCR_TIME.string -ROUTE MS.mediaDuration TO VMS2.inSFTime -ROUTE VMS2.outMFString TO OCR_DUR.string - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 8 - OCR_ES_ID 8 - decConfigDescr DecoderConfigDescriptor { - objectTypeIndication 1 - streamType 2 - } - muxInfo MuxInfo { - duration 10000 - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 5 - OCR_ES_ID 8 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 12 - esDescr [ - ES_Descriptor { - ES_ID 4 - OCR_ES_ID 8 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-audio-speed.bt b/regression_tests/bifs-timeline-mediacontrol-audio-speed.bt deleted file mode 100644 index 08859d8..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-audio-speed.bt +++ /dev/null @@ -1,214 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows MediaControl" "controling audio playback speed" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - Sound2D { - source AudioSource { - url [od:10] - stopTime -1 - numChan 2 - } - } - DEF MC MediaControl { - url [od:10] - loop TRUE - } - Transform2D { - translation -100 0 - children [ - DEF TS1 TouchSensor {} - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Circle { - radius 30 - } - } - Transform2D { - children [ - Shape { - appearance DEF TXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT_FAST Text { - string ["Faster" "x 2"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] - } - Transform2D { - translation 100 0 - children [ - DEF TS2 TouchSensor {} - Shape { - appearance Appearance { - material DEF M2 Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Circle { - radius 30 - } - } - Transform2D { - children [ - Shape { - appearance USE TXTAPP - geometry DEF TXT_SLOW Text { - string ["Slower" "x 0.5"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - children [ - DEF TS3 TouchSensor {} - Shape { - appearance Appearance { - material DEF M3 Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 30 - } - } - Transform2D { - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["Mute"] - fontStyle USE FS - } - } - ] - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE MC.mediaSpeed BY 2 - REPLACE TXT_FAST.string BY ["Faster", "x 2"] - REPLACE M1.emissiveColor BY 1 0.5 0.5 - } - } - DEF AC1 Conditional { - buffer { - REPLACE MC.mediaSpeed BY 4 - REPLACE TXT_FAST.string BY ["Faster", "x 4"] - REPLACE M1.emissiveColor BY 1 0.5 0.5 - } - } - DEF C2 Conditional { - buffer { - REPLACE MC.mediaSpeed BY 0.5 - REPLACE TXT_SLOW.string BY ["Slower", "x 0.5"] - REPLACE M2.emissiveColor BY 0.5 0.5 1 - } - } - DEF AC2 Conditional { - buffer { - REPLACE MC.mediaSpeed BY 0.25 - REPLACE TXT_SLOW.string BY ["Slower", "x 0.25"] - REPLACE M2.emissiveColor BY 0.5 0.5 1 - } - } - DEF C3 Conditional { - buffer { - REPLACE MC.mute BY TRUE - REPLACE M3.emissiveColor BY 0.5 1 0.5 - } - } - DEF RESET Conditional { - buffer { - REPLACE MC.mediaSpeed BY 1 - REPLACE MC.mute BY FALSE - REPLACE M1.emissiveColor BY 1 0 0 - REPLACE M2.emissiveColor BY 0 0 1 - REPLACE M3.emissiveColor BY 0 1 0 - } - } - ] -} - -ROUTE TS1.isOver TO C1.activate -ROUTE TS1.isOver TO RESET.reverseActivate -ROUTE TS1.isActive TO AC1.activate -ROUTE TS1.isActive TO C1.reverseActivate -ROUTE TS2.isOver TO C2.activate -ROUTE TS2.isOver TO RESET.reverseActivate -ROUTE TS2.isActive TO AC2.activate -ROUTE TS2.isActive TO C2.reverseActivate -ROUTE TS3.isOver TO C3.activate -ROUTE TS3.isOver TO RESET.reverseActivate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_english.mp3" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-audio.bt b/regression_tests/bifs-timeline-mediacontrol-audio.bt deleted file mode 100644 index e3d0ad5..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-audio.bt +++ /dev/null @@ -1,352 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows complex scripting and MediaControl" "providing complete control of the media" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - Sound2D { - source AudioSource { - url [od:10] - stopTime -1 - } - } - DEF MC MediaControl { - url [od:10] - preRoll FALSE - } - DEF MS MediaSensor { - url [od:10] - } - DEF PANEL Transform2D { - translation 0 80 - children [ - DEF TRPAUSE Transform2D { - translation -100 0 - children [ - DEF PAUSE TouchSensor {} - DEF WHICHBUT Switch { - whichChoice 0 - choice [ - Shape { - appearance DEF BUTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] - } - } - } - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coord Coordinate2D { - point [-8 7.5 -8 -7.5 5 0] - } - } - } - ] - } - ] - } - DEF TRSTOP Transform2D { - translation -60 0 - children [ - DEF STOP TouchSensor {} - Shape { - appearance USE BUTAPP - geometry Rectangle { - size 15 15 - } - } - ] - } - DEF TRFF Transform2D { - translation -20 0 - children [ - DEF FASTF TouchSensor {} - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] - } - } - } - ] - } - DEF TRLOOP Transform2D { - translation 20 0 - children [ - DEF LOOP TouchSensor {} - Shape { - appearance Appearance { - material DEF MAT_LOOP Material2D { - emissiveColor 0 0 0 - } - } - geometry Circle { - radius 6 - } - } - ] - } - Transform2D { - translation 0 -160 - children [ - DEF TS TouchSensor {} - Transform2D { - children [ - Shape { - appearance USE BUTAPP - geometry DEF PROGBAR Rectangle { - size 200 15 - } - } - ] - } - DEF CURS Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - width 4 - } - } - } - geometry Rectangle { - size 6 15 - } - } - ] - } - ] - } - DEF TIMER Transform2D { - translation 80 0 - children [ - DEF RTIME TouchSensor {} - Shape { - appearance USE BUTAPP - geometry DEF TIME Text { - string [""] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] - } - DEF SC Script { - eventIn SFTime set_cursor - eventIn SFVec3f set_seek - eventIn SFBool restart - eventIn SFBool rev_time - eventIn SFBool pause - eventIn SFBool stop - eventIn SFBool set_loop - eventIn SFBool set_ff - eventIn SFTime set_duration - field SFNode loop USE MAT_LOOP - field SFNode app USE CURS - field SFNode ctrl USE MC - field SFNode bar USE PROGBAR - field SFNode txt USE TIME - field SFNode but USE WHICHBUT - field SFNode pan USE PANEL - field SFTime curSeek 0 - field SFInt32 isDown 0 - field SFBool reverse FALSE - field SFBool isPaused FALSE - field SFBool isLooping FALSE - field SFTime duration -1 - eventOut SFFloat fraction_changed - url ["javascript: - function set_duration(value, timestamp) { - duration = value; - } - function set_loop(value, timestamp) { - if (!value) return; - isLooping = !isLooping; - loop.filled = isLooping; - ctrl.loop = isLooping; - } - function pause(value, timestamp) { - if (!value) return; - if (isPaused) { - ctrl.mediaSpeed = 1; - but.whichChoice = 0; - } else { - ctrl.mediaSpeed = 0; - but.whichChoice = 1; - ctrl.mediaStartTime = -1; - } - isPaused = !isPaused; - } - function stop(value, timestamp) { - if (!value) return; - txt.string[0] = ''; - app.translation.x = - bar.size.x / 2; - ctrl.mediaStartTime = 0; - ctrl.mediaSpeed = 0; - but.whichChoice = 1; - isPaused = 1; - } - function rev_time(value, timestamp) { - if (value) reverse = !reverse; - } - function set_time(value, timestamp) { - timing = new String(''); - if (duration>=0) { - if (!isLooping && value + 0.1 >=duration) { - stop(true, timestamp); - return; - } - } - if (isPaused) return; - if (duration>=0 && reverse) { - value = duration - value; - if (value<0) value=0; - timing += '-'; - } else { - timing += ' '; - } - hours = 0;mins = 0;secs = 0; - if (value) { - hours = Math.floor(value/3600); - value -= hours*3600; - mins = Math.floor(value / 60); - value -= mins*60; - secs = Math.floor(value); - } - if (hours<10) timing += '0'; - timing += hours + ':'; - if (mins<10) timing += '0'; - timing += mins + ':'; - if (secs<10) timing += '0'; - timing += secs; - txt.string[0] = timing; - } - function set_cursor(value, timestamp) { - set_time(value, timestamp); - if (duration<0) return; - if (ctrl.mediaSpeed && isDown != 1) { - if (value>duration) value = duration; - pos = value; - pos /= duration; - app.translation.x = bar.size.x * (pos - 0.5); - fraction_changed = pos; - } - } - function set_seek(myval, timestamp) { - if (duration<0) return; - pos = myval[0]; - pos /= bar.size.x; - pos += 0.5; - if (pos>1) pos = 0; - curSeek = duration; - curSeek *= pos; - if (isDown == 1) { - app.translation.x = bar.size.x*(pos - 0.5); - } else if (isDown==2) { - isDown = 0; - } - } - function restart(myval, timestamp) { - if (myval) { - ctrl.mediaSpeed = 0; - isDown = 1; - } else if (isDown == 1) { - ctrl.mediaStartTime = curSeek; - ctrl.mediaSpeed = 1; - isDown = 2; - but.whichChoice = 0; - isPaused = FALSE; - } - } - function set_ff(value, timestamp) { - ctrl.mediaStartTime = -1; - if (value) { - ctrl.mediaSpeed = 2; - } else { - ctrl.mediaSpeed = 1; - } - } - " ] - } - ] -} - -ROUTE MS.mediaCurrentTime TO SC.set_cursor -ROUTE TS.hitPoint_changed TO SC.set_seek -ROUTE TS.isActive TO SC.restart -ROUTE RTIME.isActive TO SC.rev_time -ROUTE PAUSE.isActive TO SC.pause -ROUTE STOP.isActive TO SC.stop -ROUTE LOOP.isActive TO SC.set_loop -ROUTE FASTF.isActive TO SC.set_ff -ROUTE MS.mediaDuration TO SC.set_duration -ROUTE FASTF.isActive TO SC.set_ff - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_audio.aac" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-complete.bt b/regression_tests/bifs-timeline-mediacontrol-complete.bt deleted file mode 100644 index 4f0d168..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-complete.bt +++ /dev/null @@ -1,266 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 240 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows complex scripting and MediaControl" "providing complete control of the media" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF MT MovieTexture { - url [od:8] - } - } - geometry Bitmap {} - - } - ] - } - Sound2D { - source AudioSource { - url [od:10] - stopTime -1 - } - } - DEF MC MediaControl { - url [od:10] - preRoll FALSE - } - DEF MS MediaSensor { - url [od:8] - } - DEF PANEL Transform2D { - translation 0 85 - children [ - DEF TRPAUSE Transform2D { - translation -100 0 - children [ - DEF PAUSE TouchSensor {} - DEF WHICHBUT Switch { - whichChoice 0 - choice [ - Shape { - appearance DEF BUTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] - } - } - } - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coord Coordinate2D { - point [-8 7.5 -8 -7.5 5 0] - } - } - } - ] - } - ] - } - DEF TRSTOP Transform2D { - translation -60 0 - children [ - DEF STOP TouchSensor {} - Shape { - appearance USE BUTAPP - geometry Rectangle { - size 15 15 - } - } - ] - } - DEF TRFF Transform2D { - translation -20 0 - children [ - DEF FASTF TouchSensor {} - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] - } - } - } - ] - } - DEF TRLOOP Transform2D { - translation 20 0 - children [ - DEF LOOP TouchSensor {} - Shape { - appearance Appearance { - material DEF MAT_LOOP Material2D { - emissiveColor 0 0 0 - } - } - geometry Circle { - radius 6 - } - } - ] - } - Transform2D { - translation 0 -170 - children [ - DEF TS TouchSensor {} - Transform2D { - children [ - Shape { - appearance USE BUTAPP - geometry DEF PROGBAR Rectangle { - size 200 15 - } - } - ] - } - DEF CURS Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - width 4 - } - } - } - geometry Rectangle { - size 6 15 - } - } - ] - } - ] - } - DEF TIMER Transform2D { - translation 80 0 - children [ - DEF RTIME TouchSensor {} - Shape { - appearance USE BUTAPP - geometry DEF TIME Text { - string [""] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] - } - DEF SC Script { - eventIn SFTime set_cursor - eventIn SFVec3f set_seek - eventIn SFBool restart - eventIn SFBool rev_time - eventIn SFBool pause - eventIn SFBool stop - eventIn SFBool set_loop - eventIn SFBool set_ff - eventIn SFTime set_duration - field SFNode loop USE MAT_LOOP - field SFNode app USE CURS - field SFNode ctrl USE MC - field SFNode bar USE PROGBAR - field SFNode txt USE TIME - field SFNode but USE WHICHBUT - field SFNode pan USE PANEL - field SFTime curSeek 0 - field SFInt32 isDown 0 - field SFBool reverse FALSE - field SFBool isPaused FALSE - field SFBool isLooping FALSE - field SFTime duration -1 - eventOut SFFloat fraction_changed - url ["javascript:function set_duration(value, timestamp) {duration = value;}function set_loop(value, timestamp) {if (!value) return;isLooping = !isLooping;loop.filled = isLooping;ctrl.loop = isLooping;}function pause(value, timestamp) {if (!value) return;if (isPaused) {ctrl.mediaSpeed = 1;but.whichChoice = 0;} else {ctrl.mediaSpeed = 0;but.whichChoice = 1;ctrl.mediaStartTime = -1;}isPaused = !isPaused;}function stop(value, timestamp) {if (!value) return;txt.string[0] = '';app.translation.x = - bar.size.x / 2;ctrl.mediaStartTime = 0;ctrl.mediaSpeed = 0;but.whichChoice = 1;isPaused = 1;}function rev_time(value, timestamp) {if (value) reverse = !reverse;}function set_time(value, timestamp) {timing = new String('');if (duration>=0) { if (!isLooping && value + 0.1 >=duration) {stop(true, timestamp);return;}}if (isPaused) return;if (duration>=0 && reverse) {value = duration - value;if (value<0) value=0;timing += '-';} else {timing += ' ';}hours = 0;mins = 0;secs = 0;if (value) {hours = Math.floor(value/3600);value -= hours*3600;mins = Math.floor(value / 60);value -= mins*60;secs = Math.floor(value);}if (hours<10) timing += '0';timing += hours + ':';if (mins<10) timing += '0';timing += mins + ':';if (secs<10) timing += '0';timing += secs;txt.string[0] = timing;}function set_cursor(value, timestamp) {set_time(value, timestamp);if (duration<0) return;if (ctrl.mediaSpeed && isDown != 1) {if (value>duration) value = duration;pos = value;pos /= duration;app.translation.x = bar.size.x * (pos - 0.5);fraction_changed = pos;} }function set_seek(myval, timestamp) {if (duration<0) return;pos = myval[0]; pos /= bar.size.x;pos += 0.5;if (pos>1) pos = 0;curSeek = duration;curSeek *= pos;if (isDown == 1) {app.translation.x = bar.size.x*(pos - 0.5);} else if (isDown==2) {isDown = 0;}}function restart(myval, timestamp) {if (myval) {ctrl.mediaSpeed = 0;isDown = 1;} else if (isDown == 1) {ctrl.mediaStartTime = curSeek;ctrl.mediaSpeed = 1;isDown = 2;but.whichChoice = 0;isPaused = FALSE;}}function set_ff(value, timestamp) {ctrl.mediaStartTime = -1;if (value) {ctrl.mediaSpeed = 4;} else {ctrl.mediaSpeed = 1;}}" ] - } - ] -} - -ROUTE MS.mediaCurrentTime TO SC.set_cursor -ROUTE TS.hitPoint_changed TO SC.set_seek -ROUTE TS.isActive TO SC.restart -ROUTE RTIME.isActive TO SC.rev_time -ROUTE PAUSE.isActive TO SC.pause -ROUTE STOP.isActive TO SC.stop -ROUTE LOOP.isActive TO SC.set_loop -ROUTE FASTF.isActive TO SC.set_ff -ROUTE MS.mediaDuration TO SC.set_duration -ROUTE FASTF.isActive TO SC.set_ff - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 21 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_audio.aac" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-deactivation.bt b/regression_tests/bifs-timeline-mediacontrol-deactivation.bt deleted file mode 100644 index 6f72756..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-deactivation.bt +++ /dev/null @@ -1,105 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 240 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows MediaControl and mediaSensor" "used to watch deactivation of a node" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF MT MovieTexture { - url [od:8] - } - } - geometry Bitmap {} - - } - DEF TS TouchSensor {} - ] - } - DEF MC MediaControl { - url [od:8] - mediaStartTime 2 - mediaStopTime 4 - preRoll FALSE - } - DEF MS MediaSensor { - url [od:8] - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - string [""] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - DEF V Valuator {} - ] -} - -ROUTE MS.isActive TO V.inSFBool -ROUTE V.outMFString TO TXT.string - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 21 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-inline-av.bt b/regression_tests/bifs-timeline-mediacontrol-inline-av.bt deleted file mode 100644 index cc3f5cc..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-inline-av.bt +++ /dev/null @@ -1,96 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - OCR_ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - title "Simple Audio-video scene" - info [ - "This simple scene contains an audio stream and a video stream." - "It is used by other regression tests." - "" - "GPAC Regression Tests" - "$Date: 2007/07/31 13:12:35 $ - $Revision: 1.4 $" - "(C) 2002-2004 GPAC Team" - ] - } - Background2D {} - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF MT MovieTexture { - url [od:8] - } - } - geometry Bitmap {} - - } - ] - } - Sound2D { - source AudioSource { - url [od:10] - stopTime -1 - } - } - ] -} - - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 1 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_audio.aac" - } - } - ] - } - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 21 - OCR_ES_ID 1 - muxInfo MuxInfo { - fileName "auxiliary_files/enst_video.h264" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-inline-segments.bt b/regression_tests/bifs-timeline-mediacontrol-inline-segments.bt deleted file mode 100644 index d5e2f45..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-inline-segments.bt +++ /dev/null @@ -1,66 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - OCR_ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - objectTypeIndication 1 - streamType 3 - decSpecificInfo BIFSConfig { - nodeIDbits 10 - routeIDbits 10 - isCommandStream true - pixelMetric true - pixelWidth 600 - pixelHeight 400 - } - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows inline scene with segments" "and mediaControl on each of the inline segments" "" "GPAC Regression Tests" "$Date: 2008/08/21 17:05:41 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] - title "MediaControl and Inline" - } - Inline { - url ["bifs-timeline-mediacontrol-seg-inline.mp4"] - } - MediaSensor { - url ["bifs-timeline-mediacontrol-seg-inline.mp4"] - } - MediaControl { - url ["bifs-timeline-mediacontrol-seg-inline.mp4#red" "bifs-timeline-mediacontrol-seg-inline.mp4#blue" "bifs-timeline-mediacontrol-seg-inline.mp4#green"] - loop TRUE - } - Transform2D { - translation 0 -100 - children [ - Shape { - appearance Appearance { - material Material2D { - filled TRUE - emissiveColor 0 0 0 - } - } - geometry Text { - string ["Colors should alternate between" "red, blue and green in order"] - fontStyle FontStyle { - justify ["MIDDLE"] - size 30 - } - } - } - ] - } - - ] -} - - diff --git a/regression_tests/bifs-timeline-mediacontrol-inline.bt b/regression_tests/bifs-timeline-mediacontrol-inline.bt deleted file mode 100644 index 20e10e1..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-inline.bt +++ /dev/null @@ -1,231 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 240 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows complex scripting and MediaControl" "providing complete control of an inline scene" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - Inline { - url [od:8] - } - DEF MC MediaControl { - url [od:8] - preRoll FALSE - } - DEF MS MediaSensor { - url [od:8] - } - DEF PANEL Transform2D { - translation 0 80 - children [ - DEF TRPAUSE Transform2D { - translation -100 0 - children [ - DEF PAUSE TouchSensor {} - DEF WHICHBUT Switch { - whichChoice 0 - choice [ - Shape { - appearance DEF BUTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] - } - } - } - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coord Coordinate2D { - point [-8 7.5 -8 -7.5 5 0] - } - } - } - ] - } - ] - } - DEF TRSTOP Transform2D { - translation -60 0 - children [ - DEF STOP TouchSensor {} - Shape { - appearance USE BUTAPP - geometry Rectangle { - size 15 15 - } - } - ] - } - DEF TRFF Transform2D { - translation -20 0 - children [ - DEF FASTF TouchSensor {} - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] - } - } - } - ] - } - DEF TRLOOP Transform2D { - translation 20 0 - children [ - DEF LOOP TouchSensor {} - Shape { - appearance Appearance { - material DEF MAT_LOOP Material2D { - emissiveColor 0 0 0 - } - } - geometry Circle { - radius 6 - } - } - ] - } - Transform2D { - translation 0 -160 - children [ - DEF TS TouchSensor {} - Transform2D { - children [ - Shape { - appearance USE BUTAPP - geometry DEF PROGBAR Rectangle { - size 200 15 - } - } - ] - } - DEF CURS Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - width 4 - } - } - } - geometry Rectangle { - size 6 15 - } - } - ] - } - ] - } - DEF TIMER Transform2D { - translation 80 0 - children [ - DEF RTIME TouchSensor {} - Shape { - appearance USE BUTAPP - geometry DEF TIME Text { - string [""] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] - } - DEF SC Script { - eventIn SFTime set_cursor - eventIn SFVec3f set_seek - eventIn SFBool restart - eventIn SFBool rev_time - eventIn SFBool pause - eventIn SFBool stop - eventIn SFBool set_loop - eventIn SFBool set_ff - eventIn SFTime set_duration - field SFNode loop USE MAT_LOOP - field SFNode app USE CURS - field SFNode ctrl USE MC - field SFNode bar USE PROGBAR - field SFNode txt USE TIME - field SFNode but USE WHICHBUT - field SFNode pan USE PANEL - field SFTime curSeek 0 - field SFInt32 isDown 0 - field SFBool reverse FALSE - field SFBool isPaused FALSE - field SFBool isLooping FALSE - field SFTime duration -1 - field SFBool reset_startTime FALSE - eventOut SFFloat fraction_changed - url ["javascript:function set_duration(value, timestamp) {duration = value;}function set_loop(value, timestamp) {if (!value) return;isLooping = !isLooping;loop.filled = isLooping;ctrl.loop = isLooping;}function pause(value, timestamp) {if (!value) return;if (isPaused) {ctrl.mediaSpeed = 1;but.whichChoice = 0;if (ctrl.mediaStartTime == 0) reset_startTime = TRUE;} else {ctrl.mediaSpeed = 0;but.whichChoice = 1;ctrl.mediaStartTime = -1;}isPaused = !isPaused;}function stop(value, timestamp) {if (!value || isPaused) return;txt.string[0] = '';app.translation.x = - bar.size.x / 2;ctrl.mediaStartTime = 0;ctrl.mediaSpeed = 0;but.whichChoice = 1;isPaused = 1;}function rev_time(value, timestamp) {if (value) reverse = !reverse;}function set_time(value, timestamp) {timing = new String('');if (isPaused) return;if (duration>=0) { if (value + 0.1 >=duration) {if (!isLooping) {stop(true, timestamp);} else {ctrl.mediaStartTime = 0;reset_startTime = TRUE;}return;}}if (reset_startTime) {ctrl.mediaStartTime = -1;reset_startTime = FALSE;}if (duration>=0 && reverse) {value = duration - value;if (value<0) value=0;timing += '-';} else {timing += ' ';}hours = 0;mins = 0;secs = 0;if (value) {hours = Math.floor(value/3600);value -= hours*3600;mins = Math.floor(value / 60);value -= mins*60;secs = Math.floor(value);}if (hours<10) timing += '0';timing += hours + ':';if (mins<10) timing += '0';timing += mins + ':';if (secs<10) timing += '0';timing += secs;txt.string[0] = timing;}function set_cursor(value, timestamp) {set_time(value, timestamp);if (duration<0) return;if (ctrl.mediaSpeed && isDown != 1) {if (value>duration) value = duration;pos = value;pos /= duration;app.translation.x = bar.size.x * (pos - 0.5);fraction_changed = pos;} }function set_seek(myval, timestamp) {if (duration<0) return;pos = myval[0]; pos /= bar.size.x;pos += 0.5;if (pos>1) pos = 0;curSeek = duration;curSeek *= pos;if (isDown == 1) {app.translation.x = bar.size.x*(pos - 0.5);} else if (isDown==2) {isDown = 0;}}function restart(myval, timestamp) {if (myval) {ctrl.mediaSpeed = 0;isDown = 1;} else if (isDown == 1) {ctrl.mediaStartTime = curSeek;ctrl.mediaSpeed = 1;isDown = 2;but.whichChoice = 0;isPaused = FALSE;}}function set_ff(value, timestamp) {ctrl.mediaStartTime = -1;if (value) {ctrl.mediaSpeed = 8;} else {ctrl.mediaSpeed = 1;}}" ] - } - ] -} - -ROUTE MS.mediaCurrentTime TO SC.set_cursor -ROUTE TS.hitPoint_changed TO SC.set_seek -ROUTE TS.isActive TO SC.restart -ROUTE RTIME.isActive TO SC.rev_time -ROUTE PAUSE.isActive TO SC.pause -ROUTE STOP.isActive TO SC.stop -ROUTE LOOP.isActive TO SC.set_loop -ROUTE FASTF.isActive TO SC.set_ff -ROUTE MS.mediaDuration TO SC.set_duration -ROUTE FASTF.isActive TO SC.set_ff - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - URLstring "bifs-timeline-mediacontrol-inline-av.mp4" - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-rtsp.bt b/regression_tests/bifs-timeline-mediacontrol-rtsp.bt deleted file mode 100644 index af2a462..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-rtsp.bt +++ /dev/null @@ -1,340 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 320 - pixelHeight 220 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows complex scripting and MediaControl" "providing complete control of an inline scene" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - Inline { - url [od:8] - } - DEF MC MediaControl { - url [od:8] - preRoll FALSE - } - DEF MS MediaSensor { - url [od:8] - } - DEF PANEL Transform2D { - translation 0 100 - children [ - DEF TRPAUSE Transform2D { - translation -100 0 - children [ - DEF PAUSE TouchSensor {} - DEF WHICHBUT Switch { - whichChoice 0 - choice [ - Shape { - appearance DEF BUTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] - } - } - } - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coord Coordinate2D { - point [-8 7.5 -8 -7.5 5 0] - } - } - } - ] - } - ] - } - DEF TRSTOP Transform2D { - translation -60 0 - children [ - DEF STOP TouchSensor {} - Shape { - appearance USE BUTAPP - geometry Rectangle { - size 15 15 - } - } - ] - } - DEF TRFF Transform2D { - translation -20 0 - children [ - DEF FASTF TouchSensor {} - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] - } - } - } - ] - } - DEF TRLOOP Transform2D { - translation 20 0 - children [ - DEF LOOP TouchSensor {} - Shape { - appearance Appearance { - material DEF MAT_LOOP Material2D { - emissiveColor 0 0 0 - } - } - geometry Circle { - radius 6 - } - } - ] - } - Transform2D { - translation 0 -200 - children [ - DEF TS TouchSensor {} - Transform2D { - children [ - Shape { - appearance USE BUTAPP - geometry DEF PROGBAR Rectangle { - size 200 15 - } - } - ] - } - DEF CURS Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - width 4 - } - } - } - geometry Rectangle { - size 6 15 - } - } - ] - } - ] - } - DEF TIMER Transform2D { - translation 80 0 - children [ - DEF RTIME TouchSensor {} - Shape { - appearance USE BUTAPP - geometry DEF TIME Text { - string [""] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] - } - DEF SC Script { - eventIn SFTime set_cursor - eventIn SFVec3f set_seek - eventIn SFBool restart - eventIn SFBool rev_time - eventIn SFBool pause - eventIn SFBool stop - eventIn SFBool set_loop - eventIn SFBool set_ff - eventIn SFTime set_duration - field SFNode loop USE MAT_LOOP - field SFNode app USE CURS - field SFNode ctrl USE MC - field SFNode bar USE PROGBAR - field SFNode txt USE TIME - field SFNode but USE WHICHBUT - field SFNode pan USE PANEL - field SFTime curSeek 0 - field SFInt32 isDown 0 - field SFBool reverse FALSE - field SFBool isPaused FALSE - field SFBool isLooping FALSE - field SFTime duration -1 - field SFBool reset_startTime FALSE - eventOut SFFloat fraction_changed - url ["javascript: - function set_duration(value, timestamp) { - duration = value; - } - function set_loop(value, timestamp) { - if (!value) return; - isLooping = !isLooping; - loop.filled = isLooping; - ctrl.loop = isLooping; - } - function pause(value, timestamp) { - if (!value) return; - if (isPaused) { - ctrl.mediaSpeed = 1; - but.whichChoice = 0; - if (ctrl.mediaStartTime == 0) reset_startTime = TRUE; - } else { - ctrl.mediaSpeed = 0; - but.whichChoice = 1; - ctrl.mediaStartTime = -1; - } - isPaused = !isPaused; - } - function stop(value, timestamp) { - if (!value || isPaused) return; - txt.string[0] = ''; - app.translation.x = - bar.size.x / 2; - ctrl.mediaStartTime = 0; - ctrl.mediaSpeed = 0; - but.whichChoice = 1; - isPaused = 1; - } - function rev_time(value, timestamp) {if (value) reverse = !reverse;} - function set_time(value, timestamp) { - timing = new String(''); - if (isPaused) return; - if (duration>=0.1) { - if (value + 0.1 >=duration) { - if (!isLooping) { - stop(true, timestamp); - } else { - ctrl.mediaStartTime = 0; - reset_startTime = TRUE; - } - return; - } - } - if (reset_startTime) { - ctrl.mediaStartTime = -1; - reset_startTime = FALSE; - } - if (duration>=0 && reverse) { - value = duration - value; - if (value<0) value=0; - timing += '-'; - } else { - timing += ' '; - } - hours = 0; - mins = 0; - secs = 0; - if (value) { - hours = Math.floor(value/3600);value -= hours*3600;mins = Math.floor(value / 60); - value -= mins*60;secs = Math.floor(value); - } - if (hours<10) timing += '0';timing += hours + ':';if (mins<10) timing += '0';timing += mins + ':';if (secs<10) timing += '0';timing += secs;txt.string[0] = timing; - } - function set_cursor(value, timestamp) { - set_time(value, timestamp); - if (duration<0) return; - if (ctrl.mediaSpeed && isDown != 1) { - if (value>duration) value = duration; - pos = value; - pos /= duration; - app.translation.x = bar.size.x * (pos - 0.5);fraction_changed = pos; - } - } - function set_seek(myval, timestamp) { - if (duration<0) return; - pos = myval[0]; - pos /= bar.size.x;pos += 0.5; - if (pos>1) pos = 0; - curSeek = duration; - curSeek *= pos; - if (isDown == 1) { - app.translation.x = bar.size.x*(pos - 0.5); - } else if (isDown==2) {isDown = 0;} - } - function restart(myval, timestamp) { - if (myval) { - ctrl.mediaSpeed = 0; - isDown = 1; - } else if (isDown == 1) { - ctrl.mediaStartTime = curSeek; - ctrl.mediaSpeed = 1; - isDown = 2; - but.whichChoice = 0; - isPaused = FALSE; - } - } - function set_ff(value, timestamp) { - ctrl.mediaStartTime = -1; - if (value) { - ctrl.mediaSpeed = 8; - } else { - ctrl.mediaSpeed = 1; - } - } - " - ] - } - ] -} - -ROUTE MS.mediaCurrentTime TO SC.set_cursor -ROUTE TS.hitPoint_changed TO SC.set_seek -ROUTE TS.isActive TO SC.restart -ROUTE RTIME.isActive TO SC.rev_time -ROUTE PAUSE.isActive TO SC.pause -ROUTE STOP.isActive TO SC.stop -ROUTE LOOP.isActive TO SC.set_loop -ROUTE FASTF.isActive TO SC.set_ff -ROUTE MS.mediaDuration TO SC.set_duration -ROUTE FASTF.isActive TO SC.set_ff - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - URLstring "rtsp://a1749.q.kamai.net/7/1749/1416/3c964c64/neo.qtv.apple.com/secure/may/preview/civ3_700.mp4" - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-seg-inline.bt b/regression_tests/bifs-timeline-mediacontrol-seg-inline.bt deleted file mode 100644 index f385bbf..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-seg-inline.bt +++ /dev/null @@ -1,81 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 254 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 254 - graphicsProfileLevelIndication 254 - ODProfileLevelIndication 254 - includeInlineProfileLevelFlag true - esDescr [ - ES_Descriptor { - ES_ID 5 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 576 - pixelHeight 432 - } - } - } - ] - ociDescr [ - SegmentDescriptor { - startTime 0 - duration 3 - name "red" - } - SegmentDescriptor { - startTime 3 - duration 3 - name "green" - } - SegmentDescriptor { - startTime 6 - duration 3 - name "blue" - } - ] -} - -OrderedGroup { - children [ - WorldInfo { - title "Simple BIFS stream with chapters" - info [ - "This simple scene contains a BIFS stream with the definition of 3 segments." - "It is used by other regression tests." - "" - "GPAC Regression Tests" - "$Date: 2007/07/31 13:12:35 $ - $Revision: 1.3 $" - "(C) 2002-2004 GPAC Team" - ] - } - Shape { - appearance Appearance { - material DEF M Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Rectangle { - size 200 100 - } - } - ] -} - - -AT 3000 { - REPLACE M.emissiveColor BY 0 1 0 -} - -AT 6000 { - REPLACE M.emissiveColor BY 0 0 1 -} - -AT 9000 { - REPLACE M.emissiveColor BY 0 0 1 -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-segments.bt b/regression_tests/bifs-timeline-mediacontrol-segments.bt deleted file mode 100644 index 91cc3ec..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-segments.bt +++ /dev/null @@ -1,154 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 240 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows chapter selection" "through segment switching in MediaControl" "" "GPAC Regression Tests" "$Date: 2008/08/28 16:17:57 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF MT MovieTexture { - url [od:8] - } - } - geometry Bitmap {} - - } - DEF TS TouchSensor {} - ] - } -#if 0 - Sound2D { - source DEF ASRC AudioSource { - url [od:10] - } - } -#endif - DEF MC MediaControl { - url ["od:8#Begin" "od:8#End"] - loop TRUE - preRoll FALSE - } - DEF MS MediaSensor { - url [od:8] - } - Transform2D { - translation 0 -80 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - string [""] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - DEF V Valuator {} - DEF C Conditional { - buffer { - REPLACE MC.url BY ["od:8#Middle"] - } - } - DEF RC Conditional { - buffer { - REPLACE MC.url BY ["od:8#Begin" "od:8#End"] - } - } - ] -} - -ROUTE MS.mediaCurrentTime TO V.inSFTime -ROUTE V.outMFString TO TXT.string -ROUTE TS.isOver TO C.activate -ROUTE TS.isOver TO RC.reverseActivate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 21 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - ociDescr [ - SegmentDescriptor { - startTime 0 - duration 4 - name "Begin" - } - SegmentDescriptor { - startTime 4 - duration 2 - name "Middle" - } - SegmentDescriptor { - startTime 6 - duration 4 - name "End" - } - ] - } -#if 0 - ObjectDescriptor { - objectDescriptorID 10 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/count_english.mp3" - } - } - ] - } -#endif - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-video.bt b/regression_tests/bifs-timeline-mediacontrol-video.bt deleted file mode 100644 index de0bddc..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-video.bt +++ /dev/null @@ -1,248 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 240 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows complete control of media" "through scripting and MediaControl" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - Transform2D { - children [ - Shape { - appearance Appearance { - texture DEF MT MovieTexture { - url [od:8] - } - } - geometry Bitmap {} - - } - ] - } - DEF MC MediaControl { - url [od:8] - preRoll FALSE - } - DEF MS MediaSensor { - url [od:8] - } - DEF PANEL Transform2D { - translation 0 80 - children [ - DEF TRPAUSE Transform2D { - translation -100 0 - children [ - DEF PAUSE TouchSensor {} - DEF WHICHBUT Switch { - whichChoice 0 - choice [ - Shape { - appearance DEF BUTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] - } - } - } - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coord Coordinate2D { - point [-8 7.5 -8 -7.5 5 0] - } - } - } - ] - } - ] - } - DEF TRSTOP Transform2D { - translation -60 0 - children [ - DEF STOP TouchSensor {} - Shape { - appearance USE BUTAPP - geometry Rectangle { - size 15 15 - } - } - ] - } - DEF TRFF Transform2D { - translation -20 0 - children [ - DEF FASTF TouchSensor {} - Shape { - appearance USE BUTAPP - geometry IndexedFaceSet2D { - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 4 5 6 7 -1] - coord Coordinate2D { - point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] - } - } - } - ] - } - DEF TRLOOP Transform2D { - translation 20 0 - children [ - DEF LOOP TouchSensor {} - Shape { - appearance Appearance { - material DEF MAT_LOOP Material2D { - emissiveColor 0 0 0 - } - } - geometry Circle { - radius 6 - } - } - ] - } - Transform2D { - translation 0 -160 - children [ - DEF TS TouchSensor {} - Transform2D { - children [ - Shape { - appearance USE BUTAPP - geometry DEF PROGBAR Rectangle { - size 200 15 - } - } - ] - } - DEF CURS Transform2D { - children [ - Shape { - appearance Appearance { - material Material2D { - lineProps LineProperties { - lineColor 0 0 1 - width 4 - } - } - } - geometry Rectangle { - size 6 15 - } - } - ] - } - ] - } - DEF TIMER Transform2D { - translation 80 0 - children [ - DEF RTIME TouchSensor {} - Shape { - appearance USE BUTAPP - geometry DEF TIME Text { - string [""] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] - } - DEF SC Script { - eventIn SFTime set_cursor - eventIn SFVec3f set_seek - eventIn SFBool restart - eventIn SFBool rev_time - eventIn SFBool pause - eventIn SFBool stop - eventIn SFBool set_loop - eventIn SFBool set_ff - eventIn SFTime set_duration - field SFNode loop USE MAT_LOOP - field SFNode app USE CURS - field SFNode ctrl USE MC - field SFNode bar USE PROGBAR - field SFNode txt USE TIME - field SFNode but USE WHICHBUT - field SFNode pan USE PANEL - field SFTime curSeek 0 - field SFInt32 isDown 0 - field SFBool reverse FALSE - field SFBool isPaused FALSE - field SFBool isLooping FALSE - field SFTime duration -1 - eventOut SFFloat fraction_changed - url ["javascript:function set_duration(value, timestamp) {duration = value;}function set_loop(value, timestamp) {if (!value) return;isLooping = !isLooping;loop.filled = isLooping;ctrl.loop = isLooping;}function pause(value, timestamp) {if (!value) return;if (isPaused) {ctrl.mediaSpeed = 1;but.whichChoice = 0;} else {ctrl.mediaSpeed = 0;but.whichChoice = 1;ctrl.mediaStartTime = -1;}isPaused = !isPaused;}function stop(value, timestamp) {if (!value) return;txt.string[0] = '';app.translation.x = - bar.size.x / 2;ctrl.mediaStartTime = 0;ctrl.mediaSpeed = 0;but.whichChoice = 1;isPaused = 1;}function rev_time(value, timestamp) {if (value) reverse = !reverse;}function set_time(value, timestamp) {timing = new String('');if (duration>=0) { if (!isLooping && value + 0.1 >=duration) {stop(true, timestamp);print('script stop ' + value + ' ' + duration);return;}}if (isPaused) return;if (duration>=0 && reverse) {value = duration - value;if (value<0) value=0;timing += '-';} else {timing += ' ';}hours = 0;mins = 0;secs = 0;if (value) {hours = Math.floor(value/3600);value -= hours*3600;mins = Math.floor(value / 60);value -= mins*60;secs = Math.floor(value);}if (hours<10) timing += '0';timing += hours + ':';if (mins<10) timing += '0';timing += mins + ':';if (secs<10) timing += '0';timing += secs;txt.string[0] = timing;}function set_cursor(value, timestamp) {set_time(value, timestamp);if (duration<0) return;if (ctrl.mediaSpeed && isDown != 1) {if (value>duration) value = duration;pos = value;pos /= duration;app.translation.x = bar.size.x * (pos - 0.5);fraction_changed = pos;} }function set_seek(myval, timestamp) {if (duration<0) return;pos = myval[0]; pos /= bar.size.x;pos += 0.5;if (pos>1) pos = 0;curSeek = duration;curSeek *= pos;if (isDown == 1) {app.translation.x = bar.size.x*(pos - 0.5);} else if (isDown==2) {isDown = 0;}}function restart(myval, timestamp) {if (myval) {ctrl.mediaSpeed = 0;isDown = 1;} else if (isDown == 1) {ctrl.mediaStartTime = curSeek;ctrl.mediaSpeed = 1;isDown = 2;but.whichChoice = 0;isPaused = FALSE;}}function set_ff(value, timestamp) {ctrl.mediaStartTime = -1;if (value) {ctrl.mediaSpeed = 4;} else {ctrl.mediaSpeed = 1;}}" ] - } - ] -} - -ROUTE MS.mediaCurrentTime TO SC.set_cursor -ROUTE TS.hitPoint_changed TO SC.set_seek -ROUTE TS.isActive TO SC.restart -ROUTE RTIME.isActive TO SC.rev_time -ROUTE PAUSE.isActive TO SC.pause -ROUTE STOP.isActive TO SC.stop -ROUTE LOOP.isActive TO SC.set_loop -ROUTE FASTF.isActive TO SC.set_ff -ROUTE MS.mediaDuration TO SC.set_duration -ROUTE FASTF.isActive TO SC.set_ff - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 21 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediacontrol-videospeed.bt b/regression_tests/bifs-timeline-mediacontrol-videospeed.bt deleted file mode 100644 index 5189d32..0000000 --- a/regression_tests/bifs-timeline-mediacontrol-videospeed.bt +++ /dev/null @@ -1,202 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 200 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows MediaControl" "controling video playback speed" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Control Test" - } - DEF MC MediaControl { - url [od:8] - loop TRUE - } - Transform2D { - translation -100 -65 - children [ - DEF TS1 TouchSensor {} - Shape { - appearance Appearance { - material DEF M1 Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry Circle { - radius 30 - } - } - Transform2D { - children [ - Shape { - appearance DEF TXTAPP Appearance { - material Material2D { - emissiveColor 0 0 0 - filled TRUE - } - } - geometry Text { - string ["Speed" "x4"] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 18 - } - } - } - ] - } - ] - } - Transform2D { - translation 100 -65 - children [ - DEF TS2 TouchSensor {} - Shape { - appearance Appearance { - material DEF M2 Material2D { - emissiveColor 0 0 1 - filled TRUE - } - } - geometry Circle { - radius 30 - } - } - Transform2D { - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["Speed" "x0.5"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 -65 - children [ - DEF TS3 TouchSensor {} - Shape { - appearance Appearance { - material DEF M3 Material2D { - emissiveColor 0 1 0 - filled TRUE - } - } - geometry Circle { - radius 30 - } - } - Transform2D { - children [ - Shape { - appearance USE TXTAPP - geometry Text { - string ["Mute"] - fontStyle USE FS - } - } - ] - } - ] - } - Transform2D { - translation 0 30 - children [ - Shape { - appearance Appearance { - texture MovieTexture { - url [od:8] - } - } - geometry Bitmap {} - - } - ] - } - DEF C1 Conditional { - buffer { - REPLACE MC.mediaSpeed BY 4 - REPLACE M1.emissiveColor BY 1 0.5 0.5 - } - } - DEF C2 Conditional { - buffer { - REPLACE MC.mediaSpeed BY 0.5 - REPLACE M2.emissiveColor BY 0.5 0.5 1 - } - } - DEF C3 Conditional { - buffer { - REPLACE MC.mute BY TRUE - REPLACE M3.emissiveColor BY 0.5 1 0.5 - } - } - DEF RESET Conditional { - buffer { - REPLACE MC.mediaSpeed BY 1 - REPLACE MC.mute BY FALSE - REPLACE M1.emissiveColor BY 1 0 0 - REPLACE M2.emissiveColor BY 0 0 1 - REPLACE M3.emissiveColor BY 0 1 0 - } - } - ] -} - -ROUTE TS1.isOver TO C1.activate -ROUTE TS1.isOver TO RESET.reverseActivate -ROUTE TS2.isOver TO C2.activate -ROUTE TS2.isOver TO RESET.reverseActivate -ROUTE TS3.isOver TO C3.activate -ROUTE TS3.isOver TO RESET.reverseActivate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 21 - OCR_ES_ID 21 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediasensor-segment-switch.bt b/regression_tests/bifs-timeline-mediasensor-segment-switch.bt deleted file mode 100644 index c07547a..0000000 --- a/regression_tests/bifs-timeline-mediasensor-segment-switch.bt +++ /dev/null @@ -1,226 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of MediaSensor" "with media segments defined" "and dynamic changes of watched segments" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Sensor Test #3" - } - Shape { - appearance Appearance { - texture DEF MOV MovieTexture { - loop TRUE - stopTime -1 - url [od:8] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap {} - - } - DEF MS MediaSensor { - url [od:8] - } - DEF MSALL MediaSensor { - url [od:8] - } - DEF VAL Valuator {} - DEF VAL2 Valuator {} - Transform2D { - translation 50 -90 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - string [""] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -50 -90 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Media Time:"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -60 -120 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Segment Start Time:"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 70 -120 - children [ - Shape { - appearance USE APP - geometry DEF START Text { - string [""] - fontStyle USE FS - } - } - ] - } - DEF VAL3 Valuator {} - Transform2D { - translation -50 120 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Segment Name:"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 50 120 - children [ - Shape { - appearance USE APP - geometry DEF NAME Text { - string [""] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -70 90 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Segment Duration: "] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 60 90 - children [ - Shape { - appearance USE APP - geometry DEF TXT2 Text { - string [""] - fontStyle USE FS - } - } - ] - } - DEF S Script { - eventIn SFBool switch_seg - field SFNode ms_node USE MS - field SFInt32 num_seg 0 - url ["javascript:function switch_seg(value, timestamp) {if (value) return;switch (num_seg) {case 0:ms_node.url[0] = '8#End';break;case 1:ms_node.url[0] = '8#Middle';break;case 2:ms_node.url[0] = '8#Begin';break;case 3:ms_node.url = new MFString('8#Begin', '8#Middle');break;case 4:ms_node.url = new MFString('8#Begin', '8#End');break;case 5:ms_node.url = new MFString('8#Middle', '8#End');break;}num_seg++;}" ] - } - DEF C Conditional { - buffer { - REPLACE TXT.string BY [""] - REPLACE TXT2.string BY [""] - REPLACE NAME.string BY [""] - REPLACE START.string BY [""] - } - } - ] -} - -ROUTE MS.mediaCurrentTime TO VAL.inSFTime -ROUTE VAL.outMFString TO TXT.string -ROUTE MS.mediaDuration TO VAL2.inSFTime -ROUTE VAL2.outMFString TO TXT2.string -ROUTE MS.info TO NAME.string -ROUTE MS.streamObjectStartTime TO VAL3.inSFTime -ROUTE VAL3.outMFString TO START.string -ROUTE MS.isActive TO C.reverseActivate -ROUTE MSALL.isActive TO S.switch_seg - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - duration 8930 - } - } - ] - ociDescr [ - SegmentDescriptor { - startTime 0 - duration 4 - name "Begin" - } - SegmentDescriptor { - startTime 4 - duration 2 - name "Middle" - } - SegmentDescriptor { - startTime 6 - duration 4 - name "End" - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediasensor-segment.bt b/regression_tests/bifs-timeline-mediasensor-segment.bt deleted file mode 100644 index f70d6f8..0000000 --- a/regression_tests/bifs-timeline-mediasensor-segment.bt +++ /dev/null @@ -1,215 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of MediaSensor" "with media segments defined" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Sensor Test #2" - } - Shape { - appearance Appearance { - texture DEF MOV MovieTexture { - loop TRUE - stopTime -1 - url [od:8] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap {} - - } - DEF MS MediaSensor { - url ["od:8#Begin" "od:8#End"] - } - DEF VAL Valuator {} - DEF VAL2 Valuator {} - Transform2D { - translation 50 -90 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - string [""] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -50 -90 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Media Time:"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -60 -120 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Segment Start Time:"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 70 -120 - children [ - Shape { - appearance USE APP - geometry DEF START Text { - string [""] - fontStyle USE FS - } - } - ] - } - DEF VAL3 Valuator {} - Transform2D { - translation -50 120 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Segment Name:"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 50 120 - children [ - Shape { - appearance USE APP - geometry DEF NAME Text { - string [""] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -70 90 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Segment Duration: "] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 60 90 - children [ - Shape { - appearance USE APP - geometry DEF TXT2 Text { - string [""] - fontStyle USE FS - } - } - ] - } - DEF C Conditional { - buffer { - REPLACE TXT.string BY [""] - REPLACE TXT2.string BY [""] - REPLACE NAME.string BY [""] - REPLACE START.string BY [""] - } - } - ] -} - -ROUTE MS.mediaCurrentTime TO VAL.inSFTime -ROUTE VAL.outMFString TO TXT.string -ROUTE MS.mediaDuration TO VAL2.inSFTime -ROUTE VAL2.outMFString TO TXT2.string -ROUTE MS.info TO NAME.string -ROUTE MS.streamObjectStartTime TO VAL3.inSFTime -ROUTE VAL3.outMFString TO START.string -ROUTE MS.isActive TO C.reverseActivate - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - ociDescr [ - SegmentDescriptor { - startTime 0 - duration 4 - name "Begin" - } - SegmentDescriptor { - startTime 4 - duration 2 - name "Middle" - } - SegmentDescriptor { - startTime 6 - duration 4 - name "End" - } - ] - } - ] -} - diff --git a/regression_tests/bifs-timeline-mediasensor.bt b/regression_tests/bifs-timeline-mediasensor.bt deleted file mode 100644 index 88a1923..0000000 --- a/regression_tests/bifs-timeline-mediasensor.bt +++ /dev/null @@ -1,137 +0,0 @@ -InitialObjectDescriptor { - objectDescriptorID 1 - audioProfileLevelIndication 255 - visualProfileLevelIndication 254 - sceneProfileLevelIndication 1 - graphicsProfileLevelIndication 1 - ODProfileLevelIndication 1 - esDescr [ - ES_Descriptor { - ES_ID 1 - decConfigDescr DecoderConfigDescriptor { - streamType 3 - decSpecificInfo BIFSConfig { - isCommandStream true - pixelMetric true - pixelWidth 300 - pixelHeight 300 - } - } - } - ES_Descriptor { - ES_ID 2 - decConfigDescr DecoderConfigDescriptor { - streamType 1 - } - } - ] -} - -OrderedGroup { - children [ - Background2D { - backColor 1 1 1 - } - WorldInfo { - info ["This shows usage of MediaSensor" "without media segments defined" "" "GPAC Regression Tests" "$Date: 2007/07/27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - title "Media Sensor Test #1" - } - Shape { - appearance Appearance { - texture DEF MOV MovieTexture { - loop TRUE - stopTime -1 - url [od:8] - repeatS FALSE - repeatT FALSE - } - } - geometry Bitmap {} - - } - DEF MS MediaSensor { - url [od:8] - } - DEF VAL Valuator {} - DEF VAL2 Valuator {} - Transform2D { - translation 50 -90 - children [ - Shape { - appearance DEF APP Appearance { - material Material2D { - emissiveColor 1 0 0 - filled TRUE - } - } - geometry DEF TXT Text { - string [""] - fontStyle DEF FS FontStyle { - justify ["MIDDLE" "MIDDLE"] - size 20 - } - } - } - ] - } - Transform2D { - translation -50 -90 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Media Time:"] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation -60 90 - children [ - Shape { - appearance USE APP - geometry Text { - string ["Media Duration: "] - fontStyle USE FS - } - } - ] - } - Transform2D { - translation 60 90 - children [ - Shape { - appearance USE APP - geometry DEF TXT2 Text { - string [""] - fontStyle USE FS - } - } - ] - } - ] -} - -ROUTE MS.mediaCurrentTime TO VAL.inSFTime -ROUTE VAL.outMFString TO TXT.string -ROUTE MS.mediaDuration TO VAL2.inSFTime -ROUTE VAL2.outMFString TO TXT2.string - -AT 0 { - UPDATE OD [ - ObjectDescriptor { - objectDescriptorID 8 - esDescr [ - ES_Descriptor { - ES_ID 20 - OCR_ES_ID 20 - muxInfo MuxInfo { - fileName "auxiliary_files/count_video.cmp" - } - } - ] - } - ] -} - diff --git a/regression_tests/bifs/bifs-2D-background-background2D-bind.bt b/regression_tests/bifs/bifs-2D-background-background2D-bind.bt new file mode 100644 index 0000000..39f7cd4 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-background-background2D-bind.bt @@ -0,0 +1,71 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D { + backColor $FFFFFF + } + DEF B2 Background2D { + backColor 1 0 0 + } + WorldInfo { + info [ + "This shows 2 Background2D nodes and the bind mechanism" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:37:08 $ - $Revision: 1.4 $" + "(C) 2002-2006 GPAC Team" + ] + title "Background Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + DEF TS TouchSensor {} + ] + } + DEF C2 Conditional { + buffer { + REPLACE B1.set_bind BY TRUE + } + } + DEF C1 Conditional { + buffer { + REPLACE B2.set_bind BY TRUE + } + } + ] +} + +ROUTE TS.isOver TO C1.activate +ROUTE TS.isOver TO C2.reverseActivate diff --git a/regression_tests/bifs/bifs-2D-background-background2D-image.bt b/regression_tests/bifs/bifs-2D-background-background2D-image.bt new file mode 100644 index 0000000..e7ea268 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-background-background2D-image.bt @@ -0,0 +1,97 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D { + url [od:10] + } + DEF B2 Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Background2D with image" "and binding mechanism" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Background Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + DEF TS TouchSensor {} + ] + } + DEF C2 Conditional { + buffer { + REPLACE B1.set_bind BY TRUE + } + } + DEF C1 Conditional { + buffer { + REPLACE B2.set_bind BY TRUE + } + } + ] +} + +ROUTE TS.isOver TO C1.activate +ROUTE TS.isOver TO C2.reverseActivate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} + +AT 1000 { + REPLACE B2.set_bind BY TRUE +} + +AT 2000 { + REPLACE B1.set_bind BY TRUE +} + diff --git a/regression_tests/bifs/bifs-2D-background-background2D-layer2D.bt b/regression_tests/bifs/bifs-2D-background-background2D-layer2D.bt new file mode 100644 index 0000000..fe53529 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-background-background2D-layer2D.bt @@ -0,0 +1,92 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Background2D within a layer2D" "Note that the background is stretched to the layer size" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] + title "Background Test" + } + Transform2D { + translation 100 0 + children [ + DEF L Layer2D { + size 400 300 + children [ + Shape { + appearance Appearance { + material Material2D { + filled TRUE + transparency 0 + } + } + geometry DEF RC Rectangle { + size 200 100 + } + } + ] + background Background2D { + url [od:10] + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF PI PositionInterpolator2D { + key [0 0.75 1] + keyValue [400 300 0 0 0 0] + } + ] +} + +ROUTE TS.fraction_changed TO PI.set_fraction +ROUTE PI.value_changed TO L.size + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-background-background2D-movie.bt b/regression_tests/bifs/bifs-2D-background-background2D-movie.bt new file mode 100644 index 0000000..f0a5c3c --- /dev/null +++ b/regression_tests/bifs/bifs-2D-background-background2D-movie.bt @@ -0,0 +1,94 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D { + url [od:10] + } + DEF B2 Background2D { + backColor 1 1 1 + } + MediaControl { + url [od:10] + loop TRUE + } + WorldInfo { + info ["This shows Background2D with image" "and binding mechanism" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Background Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + DEF TS TouchSensor {} + ] + } + DEF C2 Conditional { + buffer { + REPLACE B1.set_bind BY TRUE + } + } + DEF C1 Conditional { + buffer { + REPLACE B2.set_bind BY TRUE + } + } + ] +} + +ROUTE TS.isOver TO C1.activate +ROUTE TS.isOver TO C2.reverseActivate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-background-background2D-url-change.bt b/regression_tests/bifs/bifs-2D-background-background2D-url-change.bt new file mode 100644 index 0000000..4e55407 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-background-background2D-url-change.bt @@ -0,0 +1,105 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D { + url [od:20] + } + WorldInfo { + info ["This shows Background2D with dynamic image change" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Background Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + DEF TS TouchSensor {} + ] + } + DEF C1 Conditional { + buffer { + REPLACE B1.url BY ["od:20"] + } + } + DEF RC1 Conditional { + buffer { + REPLACE B1.url BY ["od:10"] + } + } + ] +} + +ROUTE TS.isOver TO C1.activate +ROUTE TS.isOver TO RC1.reverseActivate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 20 + esDescr [ + ES_Descriptor { + ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + +AT 2000 { + REPLACE B1.url BY ["od:20"] +} + +AT 4000 { + REPLACE B1.url BY ["od:10"] +} + diff --git a/regression_tests/bifs/bifs-2D-interactivity-discsensor.bt b/regression_tests/bifs/bifs-2D-interactivity-discsensor.bt new file mode 100644 index 0000000..cc8e0d5 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-discsensor.bt @@ -0,0 +1,129 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the use of the disc sensor which computes the angle in the mouse motion between mouse down and mouse up." + "It also uses the auto-offset field, which allows storing reusing the angle from the previous mouse up." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "DiscSensor" + } + DEF T1 Transform2D { + scale 1 2 + scaleOrientation 0.75 + translation -150 0 + children [ + DEF S Shape { + appearance Appearance { + texture ImageTexture { + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry Rectangle { + size 100 100 + } + } + DEF DS1 DiscSensor {} + ] + } + Transform2D { + translation -150 0 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Auto-offset on"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 24 + } + } + } + ] + } + DEF T2 Transform2D { + scale 1 2 + scaleOrientation 0.75 + translation 150 0 + children [ + USE S + DEF DS2 DiscSensor { + autoOffset FALSE + } + ] + } + Transform2D { + translation 150 0 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Auto-offset off"] + fontStyle USE FS + } + } + ] + } + ] +} + +ROUTE DS1.rotation_changed TO T1.rotationAngle +ROUTE DS2.rotation_changed TO T2.rotationAngle + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-interactivity-htk-sensor.bt b/regression_tests/bifs/bifs-2D-interactivity-htk-sensor.bt new file mode 100644 index 0000000..3c1f2e2 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-htk-sensor.bt @@ -0,0 +1,175 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of String Sensor" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002 ENST"] + title "InputSensor Test - StringSensor device" + } + Transform2D { + translation 0 90 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["HTKSensor"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 30 + } + } + } + ] + } + Transform2D { + translation -50 20 + children [ + Shape { + appearance USE APP + geometry Text { + string ["spoken Text"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 90 20 + children [ + Shape { + appearance USE APP + geometry DEF T2 Text { + string [""] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -50 -20 + children [ + Shape { + appearance USE APP + geometry Text { + string ["text index in dict"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 90 -20 + children [ + Shape { + appearance USE APP + geometry DEF T3 Text { + string [""] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -50 -50 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Recogn Score"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 90 -50 + children [ + Shape { + appearance USE APP + geometry DEF T4 Text { + string [""] + fontStyle USE FS + } + } + ] + } + DEF VN3 Valuator { + Factor2 0 + Factor3 0 + } + DEF VN4 Valuator { + Factor2 0 + Factor3 0 + } + InputSensor { + url [od:10] + buffer { + REPLACE T2.string[0] BY "" + REPLACE VN3.inSFInt32 BY 0 + REPLACE VN4.inSFFloat BY 0 + } + } + ] +} + +ROUTE VN3.outMFString TO T3.string +ROUTE VN4.outMFString TO T4.string + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 5 + decConfigDescr DecoderConfigDescriptor { + streamType 10 + decSpecificInfo UIConfig { + deviceName "HTKSensor" + uiData "HTK:BLEU vcl bb ll eu sp;ROUGE rr ou jj sp;VERT vv ai rr sp" + } + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-interactivity-keysensor.bt b/regression_tests/bifs/bifs-2D-interactivity-keysensor.bt new file mode 100644 index 0000000..c202567 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-keysensor.bt @@ -0,0 +1,810 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 600 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows usage of the InputSensor node to detect keys and trigger of events" + "The InputSensor in this case has a url which points to a specific pseudo-media object. This object contains one stream, called interaction stream." + "This stream is made of Device Data Frame whose content is specialized depending on the kind of input device." + "The InputSensor node in the scene specifies how to dispatch the content of the DDF." + "For each piece of information in the DDF, a REPLACE command is associated." + "The value of the target property is replaced by the associated content from the DDF." + "" + "If the configuration of the stream says 'KeySensor', like here, the input device is a keyboard and the DDF content is as follows:" + "- the key code for the pressed key (0 if none)," + "- the key code for the released key (0 if none)," + "- the key code for the action key (F1, ...) pressed (0 if none)," + "- the key code for the action key (F1, ...) released (0 for none)," + "- and the state of the modifier keys (CTRL, ALT and Shift)." + "In this example, the target nodes are Valuator nodes which cast the key code into the char representation, and the result is displayed." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "InputSensor Node for detecting keys (KeySensor)" + } + DEF N33 Switch { + choice [ + Group { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 1 + filled TRUE + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + ] + } + Group { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 0.5 1 + filled TRUE + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + ] + } + Group { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 1 1 + filled TRUE + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + ] + } + Group { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 1 + filled TRUE + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + ] + } + Group { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + ] + } + Group { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + ] + } + Group { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + ] + } + Group { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + ] + } + ] + } + DEF N10 Conditional { + buffer { + REPLACE N33.whichChoice BY 0 + } + } + Group { + children [ + DEF N12 TouchSensor {} + Transform2D { + translation -195 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 1 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + Shape { + appearance DEF N29 Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["F1"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + DEF N20 Conditional { + buffer { + REPLACE N33.whichChoice BY 1 + } + } + Group { + children [ + DEF N19 TouchSensor {} + Transform2D { + translation -195 0 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 0.5 1 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + Shape { + appearance USE N29 + geometry Text { + string ["F2"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + DEF N23 Conditional { + buffer { + REPLACE N33.whichChoice BY 2 + } + } + Group { + children [ + DEF N9 TouchSensor {} + Transform2D { + translation -195 120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 1 1 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + Shape { + appearance USE N29 + geometry Text { + string ["F3"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + DEF N14 Conditional { + buffer { + REPLACE N33.whichChoice BY 3 + } + } + Group { + children [ + DEF N31 TouchSensor {} + Transform2D { + translation -195 240 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 1 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + Shape { + appearance USE N29 + geometry Text { + string ["F4"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + DEF N15 Conditional { + buffer { + REPLACE N33.whichChoice BY 4 + } + } + Group { + children [ + DEF N25 TouchSensor {} + Transform2D { + translation 195 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + Shape { + appearance USE N29 + geometry Text { + string ["F5"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + DEF N16 Conditional { + buffer { + REPLACE N33.whichChoice BY 5 + } + } + Group { + children [ + DEF N11 TouchSensor {} + Transform2D { + translation 195 0 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + Shape { + appearance USE N29 + geometry Text { + string ["F6"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + DEF N17 Conditional { + buffer { + REPLACE N33.whichChoice BY 6 + } + } + Group { + children [ + DEF N18 TouchSensor {} + Transform2D { + translation 195 120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + Shape { + appearance USE N29 + geometry Text { + string ["F7"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + DEF N27 Conditional { + buffer { + REPLACE N33.whichChoice BY 7 + } + } + Group { + children [ + DEF N13 TouchSensor {} + Transform2D { + translation 195 240 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + Shape { + appearance USE N29 + geometry Text { + string ["F8"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + Transform2D { + translation 0 -120 + children [ + Shape { + appearance USE N29 + geometry Text { + string ["KeySensor"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 30 + } + } + } + ] + } + Transform2D { + translation -50 -150 + children [ + Shape { + appearance USE N29 + geometry Text { + string ["KeyPress"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 90 -150 + children [ + Shape { + appearance USE N29 + geometry DEF N32 Text { + string ["0"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -50 -170 + children [ + Shape { + appearance USE N29 + geometry Text { + string ["KeyRelease"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 90 -170 + children [ + Shape { + appearance USE N29 + geometry DEF N30 Text { + string ["0"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -50 -190 + children [ + Shape { + appearance USE N29 + geometry Text { + string ["ActionKeyPress"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 90 -190 + children [ + Shape { + appearance USE N29 + geometry DEF N28 Text { + string ["0"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -50 -210 + children [ + Shape { + appearance USE N29 + geometry Text { + string ["ActionKeyRelease"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 90 -210 + children [ + Shape { + appearance USE N29 + geometry DEF N26 Text { + string ["0"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -50 -230 + children [ + Shape { + appearance USE N29 + geometry Text { + string ["shiftKey_changed"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 90 -230 + children [ + Shape { + appearance USE N29 + geometry DEF N24 Text { + string ["0"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -50 -250 + children [ + Shape { + appearance USE N29 + geometry Text { + string ["controlKey_changed"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 90 -250 + children [ + Shape { + appearance USE N29 + geometry DEF N22 Text { + string ["0"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -50 -270 + children [ + Shape { + appearance USE N29 + geometry Text { + string ["altKey_changed"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 90 -270 + children [ + Shape { + appearance USE N29 + geometry DEF N21 Text { + string ["0"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + DEF N3 Valuator {} + DEF N7 Valuator { + Offset1 -1 + } + DEF N6 Valuator {} + DEF N5 Valuator {} + DEF N4 Valuator {} + DEF N2 Valuator {} + DEF N1 Valuator {} + DEF N0 Valuator {} + InputSensor { + url [od:10] + buffer { + REPLACE N6.inSFInt32 BY 0 + REPLACE N5.inSFInt32 BY 0 + REPLACE N3.inSFInt32 BY 0 + REPLACE N4.inSFInt32 BY 0 + REPLACE N2.inSFBool BY TRUE + REPLACE N1.inSFBool BY TRUE + REPLACE N0.inSFBool BY TRUE + } + } + Group { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + ] + } + ] +} + +ROUTE N6.outMFString TO N32.string +ROUTE N5.outMFString TO N30.string +ROUTE N4.outMFString TO N26.string +ROUTE N2.outMFString TO N24.string +ROUTE N1.outMFString TO N22.string +ROUTE N0.outMFString TO N21.string +ROUTE N3.outSFInt32 TO N7.inSFInt32 +ROUTE N3.outMFString TO N28.string +ROUTE N7.outSFInt32 TO N33.whichChoice +ROUTE N12.isActive TO N10.activate +ROUTE N19.isActive TO N20.activate +ROUTE N9.isActive TO N23.activate +ROUTE N31.isActive TO N14.activate +ROUTE N25.isActive TO N15.activate +ROUTE N11.isActive TO N16.activate +ROUTE N18.isActive TO N17.activate +ROUTE N13.isActive TO N27.activate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 5 + decConfigDescr DecoderConfigDescriptor { + streamType 10 + decSpecificInfo UIConfig { + deviceName "KeySensor" + } + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-interactivity-mousesensor.bt b/regression_tests/bifs/bifs-2D-interactivity-mousesensor.bt new file mode 100644 index 0000000..c22f1b4 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-mousesensor.bt @@ -0,0 +1,182 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 600 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows usage of the InputSensor node to detect keys and trigger of events" + "The InputSensor in this case has a url which points to a specific pseudo-media object. This object contains one stream, called interaction stream." + "This stream is made of Device Data Frame whose content is specialized depending on the kind of input device." + "The InputSensor node in the scene specifies how to dispatch the content of the DDF." + "For each piece of information in the DDF, a REPLACE command is associated." + "The value of the target property is replaced by the associated content from the DDF." + "" + "If the configuration of the stream says 'MouseSensor', like here, the input device is a mouse and the DDF content is as follows:" + "- the mouse position," + "- the status of the left button," + "- the status of the middle button," + "- the status of the right button," + "- and the status of the wheel." + "This configuration allows doing different things than the TouchSensor because the TouchSensor cannot give information about the buttons, or the wheel. On the other hand, it can be triggered based on sibling geometry, which is not the case of the InputSensor node in MouseSensor mode." + "In this example, the result of the InputSensor node triggers ECMAScript actions." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "InputSensor Node for mouse events (MouseSensor)" + } + Transform2D { + translation -120 -100 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT1 Text { + string ["Left Down" ""] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 0 -100 + children [ + Shape { + appearance USE APP + geometry DEF TXT2 Text { + string ["Middle Down" ""] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 120 -100 + children [ + Shape { + appearance USE APP + geometry DEF TXT3 Text { + string ["Right Down" ""] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance USE APP + geometry DEF TXT4 Text { + string [""] + fontStyle USE FS + } + } + ] + } + DEF SC Script { + eventIn SFBool set_left + eventIn SFBool set_middle + eventIn SFBool set_right + eventIn SFFloat set_wheel + field SFFloat wheel_pos 0 + field SFNode t1 USE TXT1 + field SFNode t2 USE TXT2 + field SFNode t3 USE TXT3 + field SFNode t4 USE TXT4 + url ["javascript:function set_left(value, timestamp) {t1.string[1] = '' + value;}function set_middle(value, timestamp) {t2.string[1] = '' + value;}function set_right(value, timestamp) {t3.string[1] = '' + value;}function set_wheel(value, timestamp) {wheel_pos += value;t4.string[0] = 'Wheel Pos ' + wheel_pos;}" ] + } + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + texture ImageTexture { + url [od:2] + } + } + geometry Bitmap {} + + } + ] + } + InputSensor { + url [od:10] + buffer { + REPLACE TR.translation BY 0 0 + REPLACE SC.set_left BY FALSE + REPLACE SC.set_middle BY FALSE + REPLACE SC.set_right BY FALSE + REPLACE SC.set_wheel BY 0 + } + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 2 + esDescr [ + ES_Descriptor { + ES_ID 3 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 5 + decConfigDescr DecoderConfigDescriptor { + streamType 10 + decSpecificInfo UIConfig { + deviceName "Mouse" + } + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-interactivity-nested-sensors.bt b/regression_tests/bifs/bifs-2D-interactivity-nested-sensors.bt new file mode 100644 index 0000000..7fd299a --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-nested-sensors.bt @@ -0,0 +1,123 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows a mixed usage of TouchSensor and PlaneSensor2D nodes on a single shape." + "In some circumstances, the object can be dragged and in some other, it can be clicked." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Nested Sensors" + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["PlaneSensor2D and TouchSensor:" "Drag the shape on the blue part" "and click on the center"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + DEF T1 Transform2D { + children [ + DEF TS TouchSensor {} + DEF PS PlaneSensor2D { + maxPosition 200 200 + minPosition -200 -200 + } + Shape { + appearance DEF A1 Appearance { + material DEF M1 Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Circle { + radius 60 + } + } + Transform2D { + children [ + Shape { + appearance Appearance { + material DEF M2 Material2D { + emissiveColor 1 0 1 + filled TRUE + } + } + geometry Circle { + radius 40 + } + } + DEF TS2 TouchSensor {} + ] + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE M1.filled BY FALSE + } + } + DEF C2 Conditional { + buffer { + REPLACE M1.filled BY TRUE + } + } + DEF C3 Conditional { + buffer { + REPLACE M2.emissiveColor BY 0 1 0 + } + } + DEF C4 Conditional { + buffer { + REPLACE M2.emissiveColor BY 1 0 1 + } + } + ] +} + +ROUTE TS.isOver TO C1.activate +ROUTE TS.isOver TO C2.reverseActivate +ROUTE TS2.isActive TO C3.activate +ROUTE TS2.isActive TO C4.reverseActivate +ROUTE PS.translation_changed TO T1.translation + diff --git a/regression_tests/bifs/bifs-2D-interactivity-planesensor2D.bt b/regression_tests/bifs/bifs-2D-interactivity-planesensor2D.bt new file mode 100644 index 0000000..c7a9d02 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-planesensor2D.bt @@ -0,0 +1,124 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the use of the PlaneSensor2D node, and its auto-offset property." + "The PlaneSensor2D is used to detect mouse motion between mouse down and mouse up." + "This allows to move objects between mouse down and mouse up." + "The auto-offset is used to automatically store the mouse position at mouse release and use it as the offset to the next translation." + "This tests shows two images (clipped by circles) which can be dragged." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team"] + title "PlaneSensor2D for dragging objects" + } + DEF T1 Transform2D { + translation -150 0 + children [ + DEF S Shape { + appearance Appearance { + texture ImageTexture { + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry Circle { + radius 100 + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Auto-offset on"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 24 + } + } + } + DEF PS1 PlaneSensor2D { + maxPosition 200 200 + minPosition -200 -200 + offset -150 0 + } + ] + } + DEF T2 Transform2D { + translation 150 0 + children [ + USE S + Shape { + appearance USE APP + geometry Text { + string ["Auto-offset off"] + fontStyle USE FS + } + } + DEF PS2 PlaneSensor2D { + autoOffset FALSE + maxPosition 200 200 + minPosition -200 -200 + offset 150 0 + } + ] + } + ] +} + +ROUTE PS1.translation_changed TO T1.translation +ROUTE PS2.translation_changed TO T2.translation + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-interactivity-proximitysensor2D.bt b/regression_tests/bifs/bifs-2D-interactivity-proximitysensor2D.bt new file mode 100644 index 0000000..0fc0549 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-proximitysensor2D.bt @@ -0,0 +1,89 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the usage of the ProximitySensor2D node" + "Two ProximitySensor2D nodes are placed on a single shape. The Shape is a 300x300 rectangle, and the ProximitySensor2D nodes define two areas centered on the rectangle: a 50x50 rectangle and a 200x200 rectangle." + "When the mouse enters or exits an area, an action is triggered." + "Here, nothing happens when the mouse enters the object, then it turns red if the mouse enters the first area, and it turns empty if the mouse enters the second area." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "ProximitySensor2D" + } + DEF T1 Transform2D { + children [ + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 0.5 0.6 0.4 + filled TRUE + } + } + geometry Rectangle { + size 300 300 + } + } + DEF PSOUT ProximitySensor2D { + size 200 200 + } + DEF PSIN ProximitySensor2D { + size 50 50 + } + ] + } + DEF CIN Conditional { + buffer { + REPLACE M1.filled BY FALSE + } + } + DEF RCIN Conditional { + buffer { + REPLACE M1.filled BY TRUE + } + } + DEF COUT Conditional { + buffer { + REPLACE M1.emissiveColor BY 1 0 0 + } + } + DEF RCOUT Conditional { + buffer { + REPLACE M1.emissiveColor BY 0.5 0.6 0.4 + } + } + ] +} + +ROUTE PSOUT.isActive TO COUT.activate +ROUTE PSOUT.isActive TO RCOUT.reverseActivate +ROUTE PSIN.isActive TO CIN.activate +ROUTE PSIN.isActive TO RCIN.reverseActivate + diff --git a/regression_tests/bifs/bifs-2D-interactivity-stringsensor.bt b/regression_tests/bifs/bifs-2D-interactivity-stringsensor.bt new file mode 100644 index 0000000..8c23027 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-stringsensor.bt @@ -0,0 +1,153 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows usage of the InputSensor node to detect keys and trigger of events" + "The InputSensor in this case has a url which points to a specific pseudo-media object. This object contains one stream, called interaction stream." + "This stream is made of Device Data Frame whose content is specialized depending on the kind of input device." + "The InputSensor node in the scene specifies how to dispatch the content of the DDF." + "For each piece of information in the DDF, a REPLACE command is associated." + "The value of the target property is replaced by the associated content from the DDF." + "" + "If the configuration of the stream says 'StringSensor', like here, the input device is a keyboard and the DDF content is as follows:" + "- the string being edited/input," + "and the previous string after final editing (return key)" + "In this example, the target nodes are Text nodes which display the string being edited and the final one." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "InputSensor Node for detecting string input (StringSensor)" + } + Transform2D { + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["StringSensor"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 30 + } + } + } + ] + } + Transform2D { + translation -50 -30 + children [ + Shape { + appearance USE APP + geometry Text { + string ["enteredText"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 90 -30 + children [ + Shape { + appearance USE APP + geometry DEF N3 Text { + string [""] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -50 -50 + children [ + Shape { + appearance USE APP + geometry Text { + string ["finalText"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 90 -50 + children [ + Shape { + appearance USE APP + geometry DEF N2 Text { + string [""] + fontStyle USE FS + } + } + ] + } + InputSensor { + url [od:10] + buffer { + REPLACE N3.string[0] BY "" + REPLACE N2.string[0] BY "" + } + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 5 + decConfigDescr DecoderConfigDescriptor { + streamType 10 + decSpecificInfo UIConfig { + deviceName "StringSensor" + } + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-interactivity-touchsensor-4states.bt b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-4states.bt new file mode 100644 index 0000000..3ad8d41 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-4states.bt @@ -0,0 +1,103 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 140 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This shows how to make a 4 states button" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" + "(C) 2002-2006 GPAC Team" + ] + title "4 States Button" + } + Transform2D { + scale 0.5 0.5 + children [ + Transform2D { + translation 0 60 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + DEF TS1 TouchSensor {} + ] + } + Transform2D { + translation -100 -50 + children [ + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Circle { + radius 50 + } + } + ] + } + DEF OverC Conditional { + buffer { + REPLACE M1.emissiveColor BY 1 1 0 + } + } + DEF OverRC Conditional { + buffer { + REPLACE M1.emissiveColor BY 0 1 1 + } + } + DEF C Conditional { + buffer { + REPLACE M1.emissiveColor BY 1 0 0 + } + } + DEF RC Conditional { + buffer { + REPLACE M1.emissiveColor BY 0 0 1 + } + } + ] + } + ] +} + +ROUTE TS1.isActive TO C.activate +ROUTE TS1.isActive TO RC.reverseActivate +ROUTE TS1.isOver TO OverC.activate +ROUTE TS1.isOver TO OverRC.reverseActivate + diff --git a/regression_tests/bifs/bifs-2D-interactivity-touchsensor-hitpoint.bt b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-hitpoint.bt new file mode 100644 index 0000000..ec590c5 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-hitpoint.bt @@ -0,0 +1,91 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 254 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 254 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to retrieve the mouse position when it is moved." + "The TouchSensor node generates the hitPoint event, which is a 3D point, when the mouse moves. This can be used in scripts to trigger actions." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "TouchSensor & hitPoint" + } + Transform2D { + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Rectangle {} + + } + ] + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 198 198 + } + } + DEF TS TouchSensor {} + ] + } + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APP + geometry DEF TXT Text { + string [""] + fontStyle FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + DEF V Valuator { + Factor3 0 + } + ] +} + +ROUTE TS.hitPoint_changed TO V.inSFVec3f +ROUTE V.outMFString TO TXT.string + diff --git a/regression_tests/bifs/bifs-2D-interactivity-touchsensor-isactive-exposedfield.bt b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-isactive-exposedfield.bt new file mode 100644 index 0000000..3a47a6c --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-isactive-exposedfield.bt @@ -0,0 +1,99 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 140 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows a TouchSensor node used to modify the filled property of 2 Material2D nodes." + "cf bifs-2D-interactivity-touchsensor-isactive" + "The difference with the above test is the event propagation. Instead of routing the TouchSensor isActive event to both Material2D node, the event is only sent to one Material2D node, but since the emissiveColor field is an exposedField, it generate in turns a new event and that event is routed to the second Material2D node." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "TouchSensor, isActive & Event Propagation" + + } + Transform2D { + scale 0.5 0.5 + children [ + Transform2D { + translation 0 60 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + DEF TS1 TouchSensor {} + DEF TS2 TouchSensor {} + ] + } + Transform2D { + translation -100 -50 + children [ + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 1 1 0 + } + } + geometry Circle { + radius 50 + } + } + ] + } + Transform2D { + translation 100 -50 + children [ + Shape { + appearance Appearance { + material DEF M2 Material2D { + emissiveColor 0 1 1 + } + } + geometry Circle { + radius 50 + } + } + ] + } + ] + } + ] +} + +ROUTE TS1.isActive TO M1.filled +ROUTE M1.filled TO M2.filled + diff --git a/regression_tests/bifs/bifs-2D-interactivity-touchsensor-isactive.bt b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-isactive.bt new file mode 100644 index 0000000..ea4f9ff --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-isactive.bt @@ -0,0 +1,98 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 140 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows a TouchSensor node used to modify the filled property of 2 Material2D nodes." + "The TouchSensor node sends an isActive event each time a Mouse Button is pressed. The value of the event is TRUE if the Mouse is over a sibling shape of the TouchSensor node. Otherwise it is FALSE." + "In this example, the event value is routed to the filled property of 2 different circles. So, when the mouse is clicked on the square, both circled are filled and when the mouse is released, both circles become empty." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "TouchSensor & isActive" + } + Transform2D { + scale 0.5 0.5 + children [ + Transform2D { + translation 0 60 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + DEF TS1 TouchSensor {} + DEF TS2 TouchSensor {} + ] + } + Transform2D { + translation -100 -50 + children [ + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 1 1 0 + } + } + geometry Circle { + radius 50 + } + } + ] + } + Transform2D { + translation 100 -50 + children [ + Shape { + appearance Appearance { + material DEF M2 Material2D { + emissiveColor 0 1 1 + } + } + geometry Circle { + radius 50 + } + } + ] + } + ] + } + ] +} + +ROUTE TS1.isActive TO M1.filled +ROUTE TS2.isActive TO M2.filled + diff --git a/regression_tests/bifs/bifs-2D-interactivity-touchsensor-isover.bt b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-isover.bt new file mode 100644 index 0000000..1d45d14 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-isover.bt @@ -0,0 +1,59 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 260 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows a TouchSensor node used to modify the filled property of a Material2D node." + "The TouchSensor node sends an isOver event when the Mouse enters or exits the region delimited by a Shape node, sibling of the TouchSensor node. The value is TRUE, when it enters, and FALSE when it leaves." + "In this example, the TouchSensor has only one sibling a rectangle, which turns empty when the mouse is not over it." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "TouchSensor & isOver" + } + Transform2D { + children [ + DEF TS TouchSensor {} + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 0 0 1 + } + } + geometry Rectangle { + size 200 100 + } + } + ] + } + ] +} + +ROUTE TS.isOver TO M1.filled + diff --git a/regression_tests/bifs/bifs-2D-interactivity-touchsensor-move_over.bt b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-move_over.bt new file mode 100644 index 0000000..f57fcdb --- /dev/null +++ b/regression_tests/bifs/bifs-2D-interactivity-touchsensor-move_over.bt @@ -0,0 +1,268 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 254 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 254 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how a TouchSensor node and a TimeSensor can be used to make a new Event called MoveOver, which is TRUE when the mouse moves over a Shape or FALSE when the mouse has not moved over the Shape for a certain period of time." + "This is an example to show how new events can be created based on existing tools and events (no scripting). This particular event simulates the Lingo MouseWithin event. " + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" + "(C) 2002-2006 GPAC Team" + ] + title "Move Over" + } + Transform2D { + children [ + Shape { + appearance Appearance { + material DEF M Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + DEF TS TouchSensor {} + ] + } + DEF V_ISOVER_TO_FACTOR Valuator { + } + DEF V_HITPOINT_CHANGED_TO_ONE Valuator { + Factor1 0 + Offset1 1 + } + DEF DUMMY_TIMER TimeSensor { enabled FALSE } + DEF T TimeSensor { + cycleInterval 1 + loop TRUE + startTime -1 + } + DEF STOP_TIME_OFFSETER Valuator { Offset1 0.1 } # minimum duration between two mouse move + + DEF START_TIMER Conditional { + buffer { + REPLACE DUMMY_TIMER.startTime BY 0 + REPLACE T.startTime BY 0 + } + } + DEF VALUATOR Valuator { + } + DEF V_MOVE_OVER Valuator { + } + DEF OUT Conditional { + buffer { + REPLACE T.stopTime BY 0 + } + } + DEF C Conditional { + buffer { + REPLACE M.emissiveColor BY 0 1 0 + } + } + DEF RC Conditional { + buffer { + REPLACE M.emissiveColor BY 1 0 0 + } + } + Transform2D { + translation 20 60 + children [ + Transform2D { + translation -80 0 + children [ + Transform2D { + translation 0 20 + children [ + Shape { + appearance DEF TEXT_APP Appearance { material Material2D { emissiveColor 0 0 0 filled TRUE } } + geometry Text { + string "Mouse Over & " + fontStyle DEF TEXT_STYLE FontStyle { size 10 family "SANS" justify ["MIDDLE" "MIDDLE" ] } + } + } + ] + } + Shape { + appearance USE TEXT_APP + geometry DEF MOUSE_OVER_TEXT Text { + fontStyle USE TEXT_STYLE + } + } + ] + } + Transform2D { + translation -10 0 + children [ + Transform2D { + translation 0 20 + children [ + Shape { + appearance USE TEXT_APP + geometry Text { + string [ " Mouse has " " moved recently =" ] + fontStyle USE TEXT_STYLE + } + } + ] + } + Shape { + appearance USE TEXT_APP + geometry DEF TIMER_STATUS_TEXT Text { + fontStyle USE TEXT_STYLE + } + } + ] + } + Transform2D { + translation 60 0 + children [ + Transform2D { + translation 0 20 + children [ + Shape { + appearance USE TEXT_APP + geometry Text { + string [ "Result" "Move Over" ] + fontStyle USE TEXT_STYLE + } + } + ] + } + Shape { + appearance USE TEXT_APP + geometry DEF RESULT_TEXT Text { + fontStyle USE TEXT_STYLE + } + } + ] + } + ] + } +# Transform2D { +# translation -60 -80 +# children [ +# Transform2D { +# translation 0 0 +# children [ +# Transform2D { +# translation 0 20 +# children [ +# Shape { +# appearance USE TEXT_APP +# geometry Text { +# string "Start Time" +# fontStyle USE TEXT_STYLE +# } +# } +# ] +# } +# Shape { +# appearance USE TEXT_APP +# geometry DEF START_TIME_TEXT Text { +# fontStyle USE TEXT_STYLE +# } +# } +# ] +# } +# Transform2D { +# translation 60 0 +# children [ +# Transform2D { +# translation 0 20 +# children [ +# Shape { +# appearance USE TEXT_APP +# geometry Text { +# string "Stop Time" +# fontStyle USE TEXT_STYLE +# } +# } +# ] +# } +# Shape { +# appearance USE TEXT_APP +# geometry DEF STOP_TIME_TEXT Text { +# fontStyle USE TEXT_STYLE +# } +# } +# ] +# } +# ] +# } +# DEF V_START_TIME Valuator {Factor1 100} +# DEF V_STOP_TIME Valuator {Factor1 100} + ] +} + +# These two routes do the following: +# read the startTime field of a DUMMY_TIMER (which is equal to NOW because, has been replaced by 0) +# offset this value by the appropriate delay +# set the stoptime value of the real timer +ROUTE DUMMY_TIMER.startTime TO STOP_TIME_OFFSETER.inSFTime +ROUTE STOP_TIME_OFFSETER.outSFTime TO T.stopTime + +# This is a route to force the stop of the timer when the mouse exits the shape +ROUTE TS.isOver TO OUT.reverseActivate + +# These 2 routes convert the isOver (a boolean) into a float +# and stores the value in the factor of a valuator +ROUTE TS.isOver TO V_ISOVER_TO_FACTOR.inSFBool +ROUTE V_ISOVER_TO_FACTOR.outSFFloat TO V_MOVE_OVER.Factor1 + +# Display the status of the IsOver boolean +ROUTE V_ISOVER_TO_FACTOR.outMFString TO MOUSE_OVER_TEXT.string + +#These 2 routes create an event (Boolean = TRUE) whenever the mouse moves +#and activates a conditional +ROUTE TS.hitPoint_changed TO V_HITPOINT_CHANGED_TO_ONE.inSFVec3f +ROUTE V_HITPOINT_CHANGED_TO_ONE.outSFBool TO START_TIMER.activate + +# When the timer is active, it means the mouse is moving, we route this event to the move_over valuator +ROUTE T.isActive TO V_MOVE_OVER.inSFBool + +# Display of the status of the timer +ROUTE T.isActive TO VALUATOR.inSFBool +ROUTE VALUATOR.outMFString TO TIMER_STATUS_TEXT.string + +# Trigger one action when the result is TRUE +ROUTE V_MOVE_OVER.outSFBool TO C.activate +# Trigger one action when the result is FALSE +ROUTE V_MOVE_OVER.outSFBool TO RC.reverseActivate + +# Display of the final result +ROUTE V_MOVE_OVER.outMFString TO RESULT_TEXT.string + +# Display of the startTime of the Timer +#ROUTE T.startTime TO V_START_TIME.inSFTime +#ROUTE V_START_TIME.outMFString TO START_TIME_TEXT.string + +# Display of the stopTime of the Timer +#ROUTE T.stopTime TO V_STOP_TIME.inSFTime +#ROUTE V_STOP_TIME.outMFString TO STOP_TIME_TEXT.string \ No newline at end of file diff --git a/regression_tests/bifs/bifs-2D-painting-colortransform-alpha.bt b/regression_tests/bifs/bifs-2D-painting-colortransform-alpha.bt new file mode 100644 index 0000000..0191d5c --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-colortransform-alpha.bt @@ -0,0 +1,101 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to modify the color components on a graphical object using the ColorTransform node." + "A group made of a circle and a rectangle is reused under a ColorTransform node which animates only the Red-Blue component from 0 to 1" + "Note: the transparency is specified for a set of objects but is applied individually, that is why the overlapping region of the circle and of the rectangle gets black faster than the rest of the group." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "ColorTranform" + } + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + } + geometry Rectangle { + size 200 50 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 1 + filled TRUE + } + } + geometry Circle { + radius 50 + } + } + ] + } + DEF CT ColorTransform { + mrr 0 + mgg 0 + mbb 0 + maa 0 + ta 1 + children [ + DEF MX TransformMatrix2D { + mxx 0.5 + mxy 0.5 + myy 0.5 + ty -100 + children [ + USE TR + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF CI PositionInterpolator2D { + key [0 0.5 1] + keyValue [0 0 100 100 0 0] + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO CT.ta + diff --git a/regression_tests/bifs/bifs-2D-painting-colortransform-bitmap.bt b/regression_tests/bifs/bifs-2D-painting-colortransform-bitmap.bt new file mode 100644 index 0000000..88d2c9a --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-colortransform-bitmap.bt @@ -0,0 +1,109 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to modify the color components of an image using the ColorTransform node." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "ColorTranform on an image" + } + DEF TR Transform2D { + children [ + DEF S Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + texture ImageTexture { + url ["od:2"] + } + } + geometry Rectangle { size 200 80} + } + ] + } + DEF CT ColorTransform { + mrr 1 + mgg 1 + mbb 0.2 + tr 0 + children [ + Transform2D { + translation 0 -100 + children [ + USE S + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF CI PositionInterpolator2D { + key [0 0.5 1] + keyValue [0 0 100 100 0 0] + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO TR.translation +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO CT.mrb +ROUTE TS.fraction_changed TO CT.maa + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 2 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-2D-painting-colortransform-color.bt b/regression_tests/bifs/bifs-2D-painting-colortransform-color.bt new file mode 100644 index 0000000..6f30e60 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-colortransform-color.bt @@ -0,0 +1,102 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to modify the color components on a graphical object using the ColorTransform node." + "A group made of a circle and a rectangle is reused under a ColorTransform node which sets the color components to 0 and the alpha component is animated from 0 to 1" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "ColorTranform and color changes" + } + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + } + geometry Rectangle { + size 200 50 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 1 + filled TRUE + } + } + geometry Circle { + radius 50 + } + } + ] + } + DEF CT ColorTransform { + mrr 0 + mgg 0 + mbb 0 + maa 0 + ta 1 + children [ + DEF MX TransformMatrix2D { + mxx 0.5 + mxy 0.5 + myy 0.5 + ty -100 + children [ + USE TR + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF CI PositionInterpolator2D { + key [0 0.5 1] + keyValue [0 0 100 100 0 0] + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO TR.translation +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO CT.mrb + diff --git a/regression_tests/bifs/bifs-2D-painting-lineproperties.bt b/regression_tests/bifs/bifs-2D-painting-lineproperties.bt new file mode 100644 index 0000000..4513915 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-lineproperties.bt @@ -0,0 +1,168 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 500 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to set basic outline properties, using the LineProperties node" + "The properties are width, lineColor and lineStyle." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" + "(C) 2002-2006 GPAC Team" + ] + title "Setting simple line properties - the LineProperties node" + } + DEF TR1 Transform2D { + translation -190 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + lineStyle 0 + width 15 + } + } + } + geometry DEF LS IndexedLineSet2D { + coord Coordinate2D { + point [-50 0 0 50 50 0] + } + } + } + ] + } + Transform2D { + translation -190 -30 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["lineStyle 0"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 16 + } + } + } + ] + } + DEF TR2 Transform2D { + translation -65 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 1 0 0 + lineStyle 1 + width 15 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation -65 -30 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["lineStyle 1"] + fontStyle USE FS + } + } + ] + } + DEF TR3 Transform2D { + translation 65 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 0 1 1 + lineStyle 2 + width 15 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation 65 -30 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["lineStyle 2"] + fontStyle USE FS + } + } + ] + } + DEF TR4 Transform2D { + translation 190 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 0 1 0 + lineStyle 3 + width 15 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation 190 -30 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["lineStyle 3"] + fontStyle USE FS + } + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-2D-painting-material2D.bt b/regression_tests/bifs/bifs-2D-painting-material2D.bt new file mode 100644 index 0000000..71169e4 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-material2D.bt @@ -0,0 +1,154 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to specify the filling and simple outlining of 2D shapes" + "It uses the Material2D node. The filled property indicates if the shape is filled or not. The emissiveColor property specifies the fill color if filled or the outline color if not filled. Transparency can be set using the transparency property." + "In this simple example, the width and other properties of the outline cannot be set. To set more properties, use the LineProperties or XLineProperties nodes." + "cf bifs-2D-painting-lineproperties" + "cf bifs-2D-painting-xlineproperties-cap" + "cf bifs-2D-painting-xlineproperties-compositetexture2D" + "cf bifs-2D-painting-xlineproperties-dash" + "cf bifs-2D-painting-xlineproperties-imagetexture" + "cf bifs-2D-painting-xlineproperties-join" + "cf bifs-2D-painting-xlineproperties-lineargradient" + "cf bifs-2D-painting-xlineproperties-radialgradient" + "cf bifs-2D-painting-xlineproperties-scalable" + "cf bifs-2D-painting-xlineproperties-transparent" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.4 $" + "(C) 2002-2006 GPAC Team"] + title "Material2D properties" + } + Transform2D { + translation -180 0 + children [ + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Rectangle { + size 80 80 + } + } + ] + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 1 + } + } + geometry DEF REC Rectangle { + size 150 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Not filled, Color 1 0 1"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 14 + } + } + } + ] + } + ] + } + Transform2D { + children [ + USE TR + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 1 + filled TRUE + } + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["filled, Color 1 0 1"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 180 0 + children [ + USE TR + Shape { + appearance Appearance { + material DEF M Material2D { + emissiveColor 1 0 1 + filled TRUE + transparency 0.6 + } + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["filled, Color 1 0 1" "transparency 0.6"] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-2D-painting-xlineproperties-cap.bt b/regression_tests/bifs/bifs-2D-painting-xlineproperties-cap.bt new file mode 100644 index 0000000..145066b --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-xlineproperties-cap.bt @@ -0,0 +1,211 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 500 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the usage of cap styles of the XLineProperties node" + "Moving the mouse over the 'Anim' button will superpose the different lines to highlight the linecap differences" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Changing line caps using the XLineProperties node" + } + DEF TR1 Transform2D { + translation -190 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 0 0 1 + lineCap 2 + width 15 + } + } + } + geometry DEF LS IndexedLineSet2D { + coord Coordinate2D { + point [-50 0 0 50 50 0] + } + } + } + ] + } + Transform2D { + translation -190 -30 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Cap square"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 16 + } + } + } + ] + } + DEF TR2 Transform2D { + translation -65 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 1 0 0 + lineCap 1 + width 15 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation -65 -30 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Cap round"] + fontStyle USE FS + } + } + ] + } + DEF TR3 Transform2D { + translation 65 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 0 1 1 + lineCap 3 + width 15 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation 65 -30 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Cap triangle"] + fontStyle USE FS + } + } + ] + } + DEF TR4 Transform2D { + translation 190 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 0 1 0 + width 15 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation 190 -30 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Cap 'butt'"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 225 -75 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Anim"] + fontStyle USE FS + } + } + DEF TS TouchSensor {} + ] + } + DEF C Conditional { + buffer { + REPLACE TR1.translation BY 0 0 + REPLACE TR2.translation BY 0 0 + REPLACE TR3.translation BY 0 0 + REPLACE TR4.translation BY 0 0 + } + } + DEF RC Conditional { + buffer { + REPLACE TR1.translation BY -190 0 + REPLACE TR2.translation BY -65 0 + REPLACE TR3.translation BY 65 0 + REPLACE TR4.translation BY 190 0 + } + } + ] +} + +ROUTE TS.isOver TO C.activate +ROUTE TS.isOver TO RC.reverseActivate + diff --git a/regression_tests/bifs/bifs-2D-painting-xlineproperties-compositetexture2D.bt b/regression_tests/bifs/bifs-2D-painting-xlineproperties-compositetexture2D.bt new file mode 100644 index 0000000..5a315f8 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-xlineproperties-compositetexture2D.bt @@ -0,0 +1,153 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This shows line texturing with a composite texture using the CompositeTexture2D node using variable width and different line alignment" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Complex line texturing with the XLineProperties node" + } + Transform2D { + translation 0 150 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Line width varying between 0 and 100"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -140 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps DEF XLP XLineProperties { + width 20 + textureTransform TextureTransform { scale 8 8} + texture DEF IM CompositeTexture2D { + pixelWidth 32 + pixelHeight 32 + children [ + Shape { + appearance Appearance { + material Material2D { emissiveColor 0 1 0 filled TRUE } + } + geometry DEF C Circle { + radius 6 + } + } + ] + } + } + } + } + geometry Rectangle { + size 150 150 + } + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Line centered on shape"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 160 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps DEF XLP2 XLineProperties { + isCenterAligned FALSE + width 0 + texture USE IM + } + } + } + geometry Rectangle { + size 150 150 + } + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Line inside shape"] + fontStyle USE FS + } + } + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 100 0] + } + DEF SI2 ScalarInterpolator { + key [0 0.5 1] + keyValue [6 10 6] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO XLP.width +ROUTE SI.value_changed TO XLP2.width +ROUTE TS.fraction_changed TO SI2.set_fraction +ROUTE SI2.value_changed TO C.radius + diff --git a/regression_tests/bifs/bifs-2D-painting-xlineproperties-dash.bt b/regression_tests/bifs/bifs-2D-painting-xlineproperties-dash.bt new file mode 100644 index 0000000..6749e72 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-xlineproperties-dash.bt @@ -0,0 +1,142 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the usage of line dashing using the XLineProperties node." + "Two properties are demonstrated: dash pattern and dash offset. The offset is animated on the left, the dash length is animated on the right." + "" + "GPAC Regression Tests" "$Date: 2007-09-14 16:42:18 $ - $Revision: 1.4 $" + "(C) 2002-2006 GPAC Team" + ] + title "Animating the line dashes using the XLineProperties node" + } + Transform2D { + translation 140 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps DEF XLP1 XLineProperties { + lineColor 0 0 1 + lineStyle 6 + isScalable TRUE + lineCap 1 + width 20 + dashes [0.1 80] + } + } + } + geometry DEF LS Curve2D { + fineness 1 + type [2] + point Coordinate2D { + point [-100 0 -50 200 50 -200 100 0] + } + } + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["dash pattern animation"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + Transform2D { + translation -140 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps DEF XLP2 XLineProperties { + lineColor 0 0 1 + lineStyle 6 + isScalable TRUE + lineCap 1 + width 20 + dashes [3 80] + } + } + } + geometry USE LS + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["dash offset animation"] + fontStyle USE FS + } + } + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval 3 + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 16 0] + } + DEF CI CoordinateInterpolator2D { + key [0 0.5 1] + keyValue [0.2 0 80 0 17.5 0 80 0 0.2 0 80 0] + } + DEF V Valuator { + Factor2 0 + Factor3 0 + Factor4 0 + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO XLP2.dashOffset +ROUTE TS.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO V.inMFVec2f +ROUTE V.outMFFloat TO XLP1.dashes + diff --git a/regression_tests/bifs/bifs-2D-painting-xlineproperties-imagetexture.bt b/regression_tests/bifs/bifs-2D-painting-xlineproperties-imagetexture.bt new file mode 100644 index 0000000..3c5f012 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-xlineproperties-imagetexture.bt @@ -0,0 +1,159 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 560 + pixelHeight 420 + } + } + } + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This shows line texturing with an image using variable width and different line alignment" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Line texturing with Images - the XLineProperties node" + } + Transform2D { + translation 0 140 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Line width varying between 0 and 100"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -140 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps DEF XLP XLineProperties { + width 20 + texture DEF IM ImageTexture { + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + } + } + geometry Rectangle { + size 150 150 + } + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Line centered on shape"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 140 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps DEF XLP2 XLineProperties { + isCenterAligned FALSE + width 0 + texture USE IM + } + } + } + geometry Rectangle { + size 150 150 + } + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Line inside shape"] + fontStyle USE FS + } + } + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 100 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO XLP.width +ROUTE SI.value_changed TO XLP2.width + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-painting-xlineproperties-join.bt b/regression_tests/bifs/bifs-2D-painting-xlineproperties-join.bt new file mode 100644 index 0000000..d193dc3 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-xlineproperties-join.bt @@ -0,0 +1,215 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the usage of line join styles of the XLineProperties node" + "Moving the mouse over the 'Anim' button will superpose the different lines to highlight the linejoin differences" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Changing line caps using the XLineProperties node" + } + DEF TR1 Transform2D { + translation -200 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 0 0 1 + width 20 + } + } + } + geometry DEF LS IndexedLineSet2D { + coord Coordinate2D { + point [-50 0 0 50 50 0] + } + } + } + ] + } + Transform2D { + translation -200 -50 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Join Miter" "miterLimit: default"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 16 + } + } + } + ] + } + DEF TR3 Transform2D { + translation 70 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 0 1 0 + lineJoin 1 + width 20 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation 70 -50 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Join Round"] + fontStyle USE FS + } + } + ] + } + + + DEF TR4 Transform2D { + translation 200 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 1 0 1 + lineJoin 2 + width 20 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation 200 -50 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Join Bevel"] + fontStyle USE FS + } + } + ] + } + + DEF TR2 Transform2D { + translation -70 0 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 1 0 0 + miterLimit 0.4 + width 20 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation -70 -50 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Join Miter" "miterLimit: 0.4"] + fontStyle USE FS + } + } + ] + } + + Transform2D { + translation 280 -75 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Anim"] + fontStyle USE FS + } + } + DEF TS TouchSensor {} + ] + } + DEF C Conditional { + buffer { + REPLACE TR1.translation BY 0 0 + REPLACE TR2.translation BY 0 0 + REPLACE TR3.translation BY 0 0 + REPLACE TR4.translation BY 0 0 + } + } + DEF RC Conditional { + buffer { + REPLACE TR1.translation BY -190 0 + REPLACE TR2.translation BY -65 0 + REPLACE TR3.translation BY 65 0 + REPLACE TR4.translation BY 190 0 + } + } + ] +} + +ROUTE TS.isOver TO C.activate +ROUTE TS.isOver TO RC.reverseActivate + diff --git a/regression_tests/bifs/bifs-2D-painting-xlineproperties-lineargradient.bt b/regression_tests/bifs/bifs-2D-painting-xlineproperties-lineargradient.bt new file mode 100644 index 0000000..51ffa6e --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-xlineproperties-lineargradient.bt @@ -0,0 +1,122 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows line texturing with a linear gradient with different spread method and animated end point" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team"] + title "Linear Gradient and Lines using XLineProperties" + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Move over and click" "to change the spread method"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + TransformMatrix2D { + mxy 0.5 + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + lineProps XLineProperties { + width 40 + texture DEF GL LinearGradient { + endPoint 0 0.5 + key [0 0.5 1] + keyValue [0 0 1 1 0 0 0 1 0] + } + } + } + } + geometry DEF R Rectangle { + size 200 200 + } + } + DEF TS TouchSensor {} + ] + } + ] + } + DEF C Conditional { + buffer { + REPLACE GL.spreadMethod BY 2 + } + } + DEF RC Conditional { + buffer { + REPLACE GL.spreadMethod BY 0 + } + } + DEF C2 Conditional { + buffer { + REPLACE GL.spreadMethod BY 1 + } + } + DEF RC2 Conditional { + buffer { + REPLACE GL.spreadMethod BY 2 + } + } + DEF TIME TimeSensor { + cycleInterval 4 + loop TRUE + } + DEF CI PositionInterpolator2D { + key [0 0.5 1] + keyValue [0 0.5 1 0.5 0 0.5] + } + ] +} + +ROUTE TS.isOver TO C.activate +ROUTE TS.isOver TO RC.reverseActivate +ROUTE TS.isActive TO C2.activate +ROUTE TS.isActive TO RC2.reverseActivate +ROUTE TIME.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO GL.endPoint + diff --git a/regression_tests/bifs/bifs-2D-painting-xlineproperties-radialgradient.bt b/regression_tests/bifs/bifs-2D-painting-xlineproperties-radialgradient.bt new file mode 100644 index 0000000..c80d86e --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-xlineproperties-radialgradient.bt @@ -0,0 +1,124 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows line texturing with a radial gradient with different spread method and animated focal point" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team"] + title "Radial Gradient on lines using XLineProperties node" + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Move over and click" "to change the spread method"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + DEF TR TransformMatrix2D { + mxy 1 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + isCenterAligned TRUE + width 40 + texture DEF GR RadialGradient { + focalPoint 0 0.5 + key [0 0.5 1] + keyValue [0 0 1 1 0 0 0 1 0] + } + } + } + } + geometry DEF R Rectangle { + size 200 200 + } + } + DEF TS TouchSensor {} + ] + } + DEF C Conditional { + buffer { + REPLACE GR.spreadMethod BY 2 + } + } + DEF RC Conditional { + buffer { + REPLACE GR.spreadMethod BY 0 + } + } + DEF C2 Conditional { + buffer { + REPLACE GR.spreadMethod BY 1 + } + } + DEF RC2 Conditional { + buffer { + REPLACE GR.spreadMethod BY 2 + } + } + DEF TIME TimeSensor { + cycleInterval 4 + loop TRUE + } + DEF CI PositionInterpolator2D { + key [0 0.25 0.5 0.75 1] + keyValue [0 0.5 0.5 1 1 0.5 0.5 0 0 0.5] + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.isOver TO C.activate +ROUTE TS.isOver TO RC.reverseActivate +ROUTE TS.isActive TO C2.activate +ROUTE TS.isActive TO RC2.reverseActivate +ROUTE TIME.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO GR.focalPoint +ROUTE TIME.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO TR.mxy + diff --git a/regression_tests/bifs/bifs-2D-painting-xlineproperties-scalable.bt b/regression_tests/bifs/bifs-2D-painting-xlineproperties-scalable.bt new file mode 100644 index 0000000..c691d9d --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-xlineproperties-scalable.bt @@ -0,0 +1,123 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the usage of scalable flag in the XLineProperties node" + "We see that the right line's width changes during the animation while the left one does not change." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2004 GPAC Team" + ] + title "Scalability of the outline - the XLineProperties node" + } + DEF TR1 Transform2D { + scale 2 2 + translation -150 -50 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + width 2 + } + } + } + geometry DEF LS IndexedLineSet2D { + coord Coordinate2D { + point [-50 0 0 50 50 0] + } + } + } + ] + } + Transform2D { + translation -150 -50 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Not scalable"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 16 + } + } + } + ] + } + DEF TR2 Transform2D { + scale 2 2 + translation 150 -50 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps XLineProperties { + lineColor 0 0 1 + width 2 + } + } + } + geometry USE LS + } + ] + } + Transform2D { + translation 150 -50 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Scalable"] + fontStyle USE FS + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 4 + loop TRUE + } + DEF PI PositionInterpolator2D { + key [0 0.5 1] + keyValue [1 1 3 3 1 1] + } + ] +} + +ROUTE TS.fraction_changed TO PI.set_fraction +ROUTE PI.value_changed TO TR1.scale +ROUTE PI.value_changed TO TR2.scale + diff --git a/regression_tests/bifs/bifs-2D-painting-xlineproperties-transparent.bt b/regression_tests/bifs/bifs-2D-painting-xlineproperties-transparent.bt new file mode 100644 index 0000000..26436a5 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-painting-xlineproperties-transparent.bt @@ -0,0 +1,176 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows usage of line transparency and line alignment" + "The outline or its outside is centered on the shape depending on the value of the isCenterAligned." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Positioning lines and setting transparency using the XLineProperties node" + } + Transform2D { + translation -100 100 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + lineProps XLineProperties { + lineColor 0 0 1 + width 10 + } + } + } + geometry DEF RC Rectangle { + size 150 100 + } + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance DEF TXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["No line transparency" "CenterAligned TRUE"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] + } + Transform2D { + translation 100 100 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + lineProps XLineProperties { + lineColor 0 0 1 + isCenterAligned FALSE + width 10 + } + } + } + geometry USE RC + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["No line transparency" "CenterAligned FALSE"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation -100 -80 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + lineProps XLineProperties { + lineColor 0 0 1 + transparency 0.5 + width 10 + } + } + } + geometry USE RC + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["Line transparency: 0.5" "CenterAligned TRUE"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 100 -80 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + lineProps XLineProperties { + lineColor 0 0 1 + isCenterAligned FALSE + transparency 0.5 + width 10 + } + } + } + geometry USE RC + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["Line transparency: 0.5" "CenterAligned FALSE"] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-clipper2D.bt b/regression_tests/bifs/bifs-2D-positioning-clipper2D.bt new file mode 100644 index 0000000..b2eaf52 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-clipper2D.bt @@ -0,0 +1,316 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + url [od:5] + } + WorldInfo { + info ["This shows combination of Clipper2D objects" "with different modes" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Clipper2D Test" + } + Transform2D { + scale 0.5 0.5 + translation -200 100 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Rectangle { + size 200 200 + } + } + DEF PS PlaneSensor2D { + maxPosition 150 150 + minPosition -150 -150 + } + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Translate" "round" "cliper"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 40 + } + } + } + ] + } + Transform2D { + scale 0.5 0.5 + translation -80 100 + children [ + DEF S1 Switch { + whichChoice 0 + choice [ + Group { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Round Clipper" "inside = FALSE"] + fontStyle USE FS + } + } + DEF TS1 TouchSensor {} + ] + } + Group { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Round Clipper" "inside = TRUE"] + fontStyle USE FS + } + } + DEF RTS1 TouchSensor {} + ] + } + ] + } + ] + } + Transform2D { + scale 0.5 0.5 + translation -80 0 + children [ + DEF SX1 Switch { + whichChoice 0 + choice [ + Group { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["XOR = FALSE"] + fontStyle USE FS + } + } + DEF TSX1 TouchSensor {} + ] + } + Group { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["XOR = TRUE"] + fontStyle USE FS + } + } + DEF RTSX1 TouchSensor {} + ] + } + ] + } + ] + } + Transform2D { + scale 0.5 0.5 + translation -200 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 1 + filled TRUE + } + } + geometry Circle { + radius 100 + } + } + DEF DS DiscSensor {} + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Rotate" "square" "cliper"] + fontStyle USE FS + } + } + ] + } + Transform2D { + scale 0.5 0.5 + translation -80 -120 + children [ + DEF S2 Switch { + whichChoice 0 + choice [ + Group { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Rect Clipper" "inside = FALSE"] + fontStyle USE FS + } + } + DEF TS2 TouchSensor {} + ] + } + Group { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Rect Clipper" "inside = TRUE"] + fontStyle USE FS + } + } + DEF RTS2 TouchSensor {} + ] + } + ] + } + ] + } + Transform2D { + translation 150 0 + children [ + DEF CLIP_SQ Clipper2D { + inside FALSE + children [ + DEF CLIP_RD Clipper2D { + inside FALSE + children [ + Shape { + appearance Appearance { + texture ImageTexture { + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry Circle { + radius 100 + } + } + ] + geometry Circle { + radius 50 + } + transform DEF TR_RD Transform2D {} + + } + ] + geometry Rectangle { + size 200 75 + } + transform DEF TR_SQ Transform2D {} + + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE CLIP_RD.inside BY TRUE + REPLACE S1.whichChoice BY 1 + } + } + DEF RC1 Conditional { + buffer { + REPLACE CLIP_RD.inside BY FALSE + REPLACE S1.whichChoice BY 0 + } + } + DEF CX1 Conditional { + buffer { + REPLACE CLIP_RD.XOR BY TRUE + REPLACE SX1.whichChoice BY 1 + } + } + DEF RCX1 Conditional { + buffer { + REPLACE CLIP_RD.XOR BY FALSE + REPLACE SX1.whichChoice BY 0 + } + } + DEF C2 Conditional { + buffer { + REPLACE CLIP_SQ.inside BY TRUE + REPLACE S2.whichChoice BY 1 + } + } + DEF RC2 Conditional { + buffer { + REPLACE CLIP_SQ.inside BY FALSE + REPLACE S2.whichChoice BY 0 + } + } + ] +} + +ROUTE PS.translation_changed TO TR_RD.translation +ROUTE DS.rotation_changed TO TR_SQ.rotationAngle +ROUTE TS1.isActive TO C1.activate +ROUTE RTS1.isActive TO RC1.activate +ROUTE TSX1.isActive TO CX1.activate +ROUTE RTSX1.isActive TO RCX1.activate +ROUTE TS2.isActive TO C2.activate +ROUTE RTS2.isActive TO RC2.activate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 10 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-positioning-form-align-center.bt b/regression_tests/bifs/bifs-2D-positioning-form-align-center.bt new file mode 100644 index 0000000..700a43c --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-form-align-center.bt @@ -0,0 +1,162 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Form node" "with horizontal and vertical center alignment" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Form Test" + } + Transform2D { + translation -100 0 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 100 200 + } + } + Transform2D { + translation 0 -120 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Constraints: AT AB AH "] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Form { + size 100 200 + groups [1 -1 2 -1] + constraints ["AT" "AB" "AH"] + groupsIndex [0 1 -1 0 2 -1 1 2 -1] + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 30 + } + } + DEF S2 Transform2D { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 60 20 + } + } + ] + } + Transform2D { + translation -20 -20 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + ] + } + ] + } + ] + } + ] + } + Transform2D { + translation 75 0 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 200 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Constraints: AL AR AV"] + fontStyle USE FS + } + } + ] + } + Form { + size 200 100 + groups [1 -1 2 -1] + constraints ["AL" "AR" "AV"] + groupsIndex [0 1 -1 0 2 -1 1 2 -1] + children [ + USE S1 + USE S2 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-form-align-horiz.bt b/regression_tests/bifs/bifs-2D-positioning-form-align-horiz.bt new file mode 100644 index 0000000..b254b7e --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-form-align-horiz.bt @@ -0,0 +1,129 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Form node" "with horizontal alignment" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Form Test" + } + Transform2D { + translation -75 0 + children [ + DEF FORM Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 100 200 + } + } + Transform2D { + translation 0 -120 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Constraints: AL AL 10"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Form { + size 100 200 + groups [1 -1 2 -1] + constraints ["AL" "AL 10"] + groupsIndex [0 1 -1 1 2 -1] + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 30 + } + } + DEF S2 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + ] + } + ] + } + Transform2D { + translation 75 0 + children [ + USE FORM + Transform2D { + translation 0 -120 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Constraints: AR AR 10"] + fontStyle USE FS + } + } + ] + } + Form { + size 100 200 + groups [1 -1 2 -1] + constraints ["AR" "AR 10"] + groupsIndex [0 1 -1 1 2 -1] + children [ + USE S1 + USE S2 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-form-align-vert.bt b/regression_tests/bifs/bifs-2D-positioning-form-align-vert.bt new file mode 100644 index 0000000..690de39 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-form-align-vert.bt @@ -0,0 +1,129 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Form node" "with vertical alignment" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Form Test" + } + Transform2D { + translation 0 75 + children [ + DEF FORM Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 200 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Constraints: AT AT 10"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Form { + size 200 100 + groups [1 -1 2 -1] + constraints ["AT" "AT 10"] + groupsIndex [0 1 -1 1 2 -1] + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 30 + } + } + DEF S2 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + ] + } + ] + } + Transform2D { + translation 0 -75 + children [ + USE FORM + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Constraints: AB AB 10"] + fontStyle USE FS + } + } + ] + } + Form { + size 200 100 + groups [1 -1 2 -1] + constraints ["AB" "AB 10"] + groupsIndex [0 1 -1 1 2 -1] + children [ + USE S1 + USE S2 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-form-spread-horiz.bt b/regression_tests/bifs/bifs-2D-positioning-form-spread-horiz.bt new file mode 100644 index 0000000..4545dd9 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-form-spread-horiz.bt @@ -0,0 +1,182 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Form node" "with different horizontal spreads" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Form Test" + } + Transform2D { + translation 0 130 + children [ + DEF FORM Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 200 100 + } + } + Transform2D { + translation 0 -65 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Constraints: AL SH 10"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Form { + size 200 100 + groups [1 -1 2 -1 3 -1] + constraints ["AL" "SH 10"] + groupsIndex [0 1 -1 1 2 3 -1] + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 30 + } + } + DEF S2 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 60 40 + } + } + ] + } + ] + } + Transform2D { + children [ + USE FORM + Transform2D { + translation 0 -65 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Constraints: AL AR SH"] + fontStyle USE FS + } + } + ] + } + Form { + size 200 100 + groups [1 -1 2 -1 3 -1] + constraints ["AL" "AR" "SH"] + groupsIndex [0 1 -1 0 3 -1 1 2 3 -1] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 -130 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 110 100 + } + } + Transform2D { + translation 0 -65 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Constraints: SHin"] + fontStyle USE FS + } + } + ] + } + Form { + size 110 100 + groups [1 -1 2 -1] + constraints ["SHin"] + groupsIndex [1 2 -1] + children [ + Transform2D { + children [ + USE S1 + USE S2 + ] + } + USE S3 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-form-spread-vert.bt b/regression_tests/bifs/bifs-2D-positioning-form-spread-vert.bt new file mode 100644 index 0000000..48c3956 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-form-spread-vert.bt @@ -0,0 +1,170 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Form node" "with different vertical spreads" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Form Test" + } + Transform2D { + translation -120 20 + children [ + DEF FORM Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 100 200 + } + } + Transform2D { + translation 0 -120 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Constraints:" "AT SV 10"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Form { + size 100 200 + groups [1 -1 2 -1 3 -1] + constraints ["AT" "SV 10"] + groupsIndex [0 1 -1 1 2 3 -1] + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 30 + } + } + DEF S2 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 60 40 + } + } + ] + } + ] + } + Transform2D { + translation 0 20 + children [ + USE FORM + Transform2D { + translation 0 -120 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Constraints:" "AT AB SV"] + fontStyle USE FS + } + } + ] + } + Form { + size 100 200 + groups [1 -1 2 -1 3 -1] + constraints ["AT" "AB" "SV"] + groupsIndex [0 1 -1 0 3 -1 1 2 3 -1] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 120 20 + children [ + USE FORM + Transform2D { + translation 0 -120 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Constraints:" "SVin"] + fontStyle USE FS + } + } + ] + } + Form { + size 100 200 + groups [1 -1 2 -1 3 -1] + constraints ["SVin"] + groupsIndex [1 2 3 -1] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layer2D.bt b/regression_tests/bifs/bifs-2D-positioning-layer2D.bt new file mode 100644 index 0000000..122ca4d --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layer2D.bt @@ -0,0 +1,129 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { backColor 1 1 1 } + WorldInfo { + info [ + "This test shows the usage of the Layer2D node." + "A 2D layer is defined with a size 200x200, its content is a grey square and a grey ellipse." + "Within the layer, the content is clipped along the 200x200 rectangle and filled with a red background." + "Behind this layer, a rotated blue rectangle is displayed." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Layer2D - Rectangular Axis Aligned Clipping" + } + Transform2D { + translation 125 125 + children [ + Shape { + appearance Appearance { material Material2D { filled TRUE emissiveColor 1 1 0 } } + geometry Rectangle { size 50 50 } + } + Shape { + appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } + geometry Text { string "Click Me" fontStyle FontStyle { justify [ "MIDDLE" "MIDDLE" ] size 10 }} + } + DEF S TouchSensor {} + ] + } + Transform2D { + rotationAngle 0.57 + children [ + Shape { + appearance Appearance { + material Material2D { + filled TRUE + emissiveColor 0 0 1 + } + } + geometry Rectangle { + size 100 400 + } + } + ] + } + DEF ROT Transform2D { + translation 0 0 + children [ + Layer2D { + size 200 200 + children [ + Background2D { backColor 1 0 0 } + Transform2D { + translation -100 0 + children [ + Shape { + appearance Appearance { + material Material2D { + filled TRUE + } + } + geometry Ellipse { + radius 100 400 + } + } + ] + } + Transform2D { + translation 25 0 + children [ + Shape { + appearance Appearance { + material Material2D { + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + ] + } + ] + } + ] + } + DEF C Conditional { + buffer { + REPLACE TS.startTime BY 0 + } + } + DEF TS TimeSensor { + cycleInterval 5 + startTime -1 + } + DEF SI ScalarInterpolator { + key [0 1] + keyValue [0 1.57] + } + ] +} + +ROUTE S.isActive TO C.activate +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO ROT.rotationAngle + diff --git a/regression_tests/bifs/bifs-2D-positioning-layer2d-in-layer2d.bt b/regression_tests/bifs/bifs-2D-positioning-layer2d-in-layer2d.bt new file mode 100644 index 0000000..c8ad56d --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layer2d-in-layer2d.bt @@ -0,0 +1,111 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFE + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D {backColor 1 1 1} + WorldInfo { + title "Nested Clipping - Layer2D" + info [ + "This test shows nested Layer2D nodes." + "Both layer sizes are animated" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + } + + Transform2D { + translation 100 0 + children [ + DEF L1 Layer2D { + size 300 300 + background Background2D {url 10} + children [ + Shape { + appearance Appearance { material Material2D { filled TRUE } } + geometry DEF RC Rectangle {size 100 75} + } + Transform2D { + translation -150 0 + children [ + DEF L2 Layer2D { + size 100 100 + background Background2D {backColor 0 0 1} + children [ + Shape { + appearance Appearance { material Material2D { emissiveColor 1 0 0 filled TRUE } } + geometry Circle {radius 20} + } + ] + } + ] + } + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval 2.0 + loop TRUE + } + DEF PI1 PositionInterpolator2D { + key [0.0 1.0] + keyValue [400.0 300.0 0.0 0.0] + } + DEF PI2 PositionInterpolator2D { + key [0.0 1.0] + keyValue [100.0 100.0 0.0 0.0] + } + ] +} + + +ROUTE TS.fraction_changed TO PI1.set_fraction +ROUTE PI1.value_changed TO L1.size +ROUTE TS.fraction_changed TO PI2.set_fraction +ROUTE PI2.value_changed TO L2.size + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "./../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-nowrap.bt b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-nowrap.bt new file mode 100644 index 0000000..67e3f27 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-nowrap.bt @@ -0,0 +1,403 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 800 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different horizontal justification" "going left to right without line wrap" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -250 160 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 200 60 + } + } + Transform2D { + translation 0 -50 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + size 200 60 + justify ["BEGIN" "BEGIN"] + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation -250 60 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment BEGIN FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["BEGIN" "FIRST"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -250 -40 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["BEGIN" "MIDDLE"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -250 -140 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["BEGIN" "END"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["MIDDLE" "BEGIN"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 60 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment MIDDLE FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["MIDDLE" "FIRST"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 -40 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["MIDDLE" "MIDDLE"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 -140 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["MIDDLE" "END"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 250 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["END" "BEGIN"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 250 60 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment END FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["END" "FIRST"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 250 -40 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["END" "MIDDLE"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 250 -140 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment END END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["END" "END"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-btt.bt b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-btt.bt new file mode 100644 index 0000000..2ec7e53 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-btt.bt @@ -0,0 +1,445 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 650 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different horizontal justification" "going left to right with line wrap" "in direction bottom to top and 1.1 line spacing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -200 260 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 140 120 + } + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "BEGIN"] + topToBottom FALSE + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance USE APPTEXT + geometry Text { + string ["Text#2"] + fontStyle USE FS + } + } + DEF S4 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation -200 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "FIRST"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -200 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "MIDDLE"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -200 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "END"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 260 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "BEGIN"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "FIRST"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "MIDDLE"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "END"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 260 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "BEGIN"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "FIRST"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "MIDDLE"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "END"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-ttb.bt b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-ttb.bt new file mode 100644 index 0000000..b30eaac --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-ltr-wrap-ttb.bt @@ -0,0 +1,434 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 650 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different horizontal justification" "going left to right with line wrap" "in direction top to bottom and 1.1 line spacing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -200 260 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 140 120 + } + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "BEGIN"] + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance USE APPTEXT + geometry Text { + string ["Text#2"] + fontStyle USE FS + } + } + DEF S4 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation -200 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "FIRST"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -200 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "MIDDLE"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -200 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "END"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 260 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "BEGIN"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "FIRST"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "MIDDLE"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "END"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 260 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "BEGIN"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "FIRST"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "MIDDLE"] + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "END"] + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-nowrap.bt b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-nowrap.bt new file mode 100644 index 0000000..fc949de --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-nowrap.bt @@ -0,0 +1,415 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 800 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different horizontal justification" "going right to left without line wrap" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -250 160 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 200 60 + } + } + Transform2D { + translation 0 -50 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + size 200 60 + justify ["BEGIN" "BEGIN"] + leftToRight FALSE + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation -250 60 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment BEGIN FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["BEGIN" "FIRST"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -250 -40 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["BEGIN" "MIDDLE"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -250 -140 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["BEGIN" "END"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["MIDDLE" "BEGIN"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 60 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment MIDDLE FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["MIDDLE" "FIRST"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 -40 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["MIDDLE" "MIDDLE"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 -140 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["MIDDLE" "END"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 250 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["END" "BEGIN"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 250 60 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment END FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["END" "FIRST"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 250 -40 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["END" "MIDDLE"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 250 -140 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment END END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 200 60 + justify ["END" "END"] + leftToRight FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-btt.bt b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-btt.bt new file mode 100644 index 0000000..54767c3 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-btt.bt @@ -0,0 +1,469 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 650 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different horizontal justification" "going right to left with line wrap" "in direction bottom to top and 1.1 line spacing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -200 260 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 140 120 + } + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "BEGIN"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance USE APPTEXT + geometry Text { + string ["Text#2"] + fontStyle USE FS + } + } + DEF S4 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation -200 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "FIRST"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -200 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "MIDDLE"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -200 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "END"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 260 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "BEGIN"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "FIRST"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "MIDDLE"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "END"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 260 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "BEGIN"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "FIRST"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "MIDDLE"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "END"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-ttb.bt b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-ttb.bt new file mode 100644 index 0000000..6675d08 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-rtl-wrap-ttb.bt @@ -0,0 +1,457 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 650 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different horizontal justification" "going right to left with line wrap" "in direction top to bottom and 1.1 line spacing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -200 260 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 140 120 + } + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "BEGIN"] + leftToRight FALSE + spacing 1.1 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance USE APPTEXT + geometry Text { + string ["Text#2"] + fontStyle USE FS + } + } + DEF S4 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation -200 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "FIRST"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -200 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "MIDDLE"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -200 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["BEGIN" "END"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 260 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "BEGIN"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "FIRST"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "MIDDLE"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["MIDDLE" "END"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 260 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "BEGIN"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 100 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END FIRST"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "FIRST"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 -60 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "MIDDLE"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 200 -220 + children [ + USE BOUNDS + Transform2D { + translation 0 -80 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 140 120 + justify ["END" "END"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-horiz-text.bt b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-text.bt new file mode 100644 index 0000000..2fe00d9 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-horiz-text.bt @@ -0,0 +1,84 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 650 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing text splitting at word boundaries" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Text Test" + } + Transform2D { + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 160 160 + } + } + Transform2D { + translation 0 -100 + children [ + DEF S Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Sample text use to check if text splitting is ok with layout: aei pqg dtS..."] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 160 160 + justify ["BEGIN" "END"] + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample text used to check if text splitting is ok with layout: aei pqg dtS..."] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-scroll-child.bt b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-child.bt new file mode 100644 index 0000000..50f0c9f --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-child.bt @@ -0,0 +1,87 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 800 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node used in another layout" "both perform scrolling" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { size 300 200 } + } + Layout { + size 300 200 + smoothScroll TRUE + loop TRUE + scrollVertical FALSE + scrollRate 0.1 + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { size 100 200 } + } + Layout { + wrap TRUE + size 100 200 + smoothScroll TRUE + loop TRUE + scrollRate 0.2 + children [ + DEF N0 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + USE N0 + USE N0 + ] + } + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-scroll-full.bt b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-full.bt new file mode 100644 index 0000000..b47b4a2 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-full.bt @@ -0,0 +1,344 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 800 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing scrolling in different direction" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -250 160 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 200 60 + } + } + Transform2D { + translation 0 -50 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["scroll smooth vertical"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 200 60 + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollRate 0.1 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation -250 60 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["scroll smooth vertical inverse"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 200 60 + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollRate -0.1 + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -250 -40 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["scroll smooth horizontal"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 200 60 + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollVertical FALSE + scrollRate 0.1 + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -250 -140 + children [ + USE BOUNDS + Transform2D { + translation 0 -50 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["scroll smooth horizontal inverse"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 200 60 + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollVertical FALSE + scrollRate -0.1 + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 120 + children [ + DEF BOUNDS2 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 100 150 + } + } + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["scroll smooth vertical"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 100 150 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollRate 0.1 + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 200 120 + children [ + USE BOUNDS2 + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["scroll smooth vertical inverse"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 100 150 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollRate -0.1 + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 -80 + children [ + USE BOUNDS2 + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["scroll smooth horizontal"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 100 150 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollVertical FALSE + scrollRate 0.1 + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 200 -80 + children [ + USE BOUNDS2 + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["scroll smooth horizontal inverse"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 100 150 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollVertical FALSE + scrollRate -0.1 + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-scroll-modes-horiz.bt b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-modes-horiz.bt new file mode 100644 index 0000000..f9ffa8d --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-modes-horiz.bt @@ -0,0 +1,349 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows an horizontal Layout node" "with different scrolling modes, direction and rates" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team", "(C) 2006 ENST ATG Conformance Streams"] + title "Layout Test" + } + Transform2D { + translation 0 40 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 200 60 + } + } + DEF LAY Layout { + wrap TRUE + size 200 60 + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollVertical FALSE + scrollRate 0.1 + scrollMode -1 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + ] + } + Transform2D { + translation 0 -50 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT_MODE Text { + string ["mode: scroll-in"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 16 + } + } + } + ] + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry DEF TXT_ALIGN Text { + string ["align: begin"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry DEF TXT_DIR Text { + string ["scroll dir: horizontal"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 0 -110 + children [ + Shape { + appearance USE APPTEXT + geometry DEF TXT_RATE Text { + string ["scroll rate: 0.1"] + fontStyle USE FS + } + } + ] + } + ] + } + + Transform2D { + translation -160 80 + children [ + DEF S Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.7 0.7 0.7 + filled TRUE + lineProps LineProperties { lineColor 0 0 0 } + } + } + geometry Rectangle {size 80 20} + } + Shape { + appearance USE APPTEXT + geometry Text { + string ["Begin"] + fontStyle USE FS + } + } + DEF TS_BE TouchSensor {} + ] + } + Transform2D { + translation -160 60 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Middle"] + fontStyle USE FS + } + } + DEF TS_ME TouchSensor {} + ] + } + Transform2D { + translation -160 40 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["End"] + fontStyle USE FS + } + } + DEF TS_EE TouchSensor {} + ] + } + + Transform2D { + translation -160 0 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Scroll In"] + fontStyle USE FS + } + } + DEF TS_SI TouchSensor {} + ] + } + Transform2D { + translation -160 -20 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Scroll InOut"] + fontStyle USE FS + } + } + DEF TS_SIO TouchSensor {} + ] + } + Transform2D { + translation -160 -40 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Scroll Out"] + fontStyle USE FS + } + } + DEF TS_SO TouchSensor {} + ] + } + + Transform2D { + translation 160 80 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Rate>0"] + fontStyle USE FS + } + } + DEF TS_RP TouchSensor {} + ] + } + Transform2D { + translation 160 60 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Rate<0"] + fontStyle USE FS + } + } + DEF TS_RN TouchSensor {} + ] + } + + Transform2D { + translation 160 30 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Horiz"] + fontStyle USE FS + } + } + DEF TS_SH TouchSensor {} + ] + } + Transform2D { + translation 160 10 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Vert"] + fontStyle USE FS + } + } + DEF TS_SV TouchSensor {} + ] + } + + DEF C_BE Conditional { buffer { + REPLACE LAY.justify BY ["BEGIN", "BEGIN"] + REPLACE TXT_ALIGN.string BY ["align: begin"] + } } + DEF C_ME Conditional { buffer { + REPLACE LAY.justify BY ["MIDDLE", "BEGIN"] + REPLACE TXT_ALIGN.string BY ["align: middle"] + } } + DEF C_EE Conditional { buffer { + REPLACE LAY.justify BY ["END", "BEGIN"] + REPLACE TXT_ALIGN.string BY ["align: end"] + } } + + DEF C_SI Conditional { buffer { + REPLACE LAY.scrollMode BY -1 + REPLACE TXT_MODE.string BY ["mode: scroll-in"] + } } + DEF C_SIO Conditional { buffer { + REPLACE LAY.scrollMode BY 0 + REPLACE TXT_MODE.string BY ["mode: scroll-in-out"] + } } + DEF C_SO Conditional { buffer { + REPLACE LAY.scrollMode BY 1 + REPLACE TXT_MODE.string BY ["mode: scroll-out"] + } } + DEF C_RP Conditional { buffer { + REPLACE LAY.scrollRate BY 0.1 + REPLACE TXT_RATE.string BY ["scroll rate: 0.1"] + } } + DEF C_RN Conditional { buffer { + REPLACE LAY.scrollRate BY -0.1 + REPLACE TXT_RATE.string BY ["scroll rate: -0.1"] + } } + DEF C_SH Conditional { buffer { + REPLACE LAY.scrollVertical BY FALSE + REPLACE TXT_DIR.string BY ["scroll dir: horizontal"] + } } + DEF C_SV Conditional { buffer { + REPLACE LAY.scrollVertical BY TRUE + REPLACE TXT_DIR.string BY ["scroll dir: vertical"] + } } + ] +} + +ROUTE TS_BE.isActive TO C_BE.activate +ROUTE TS_ME.isActive TO C_ME.activate +ROUTE TS_EE.isActive TO C_EE.activate + +ROUTE TS_SI.isActive TO C_SI.activate +ROUTE TS_SIO.isActive TO C_SIO.activate +ROUTE TS_SO.isActive TO C_SO.activate + +ROUTE TS_RP.isActive TO C_RP.activate +ROUTE TS_RN.isActive TO C_RN.activate + +ROUTE TS_SH.isActive TO C_SH.activate +ROUTE TS_SV.isActive TO C_SV.activate + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-scroll-modes-vert.bt b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-modes-vert.bt new file mode 100644 index 0000000..ca53ff8 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-modes-vert.bt @@ -0,0 +1,350 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows a vertical Layout node" "with different scrolling modes, direction and rates" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team", "(C) 2006 ENST ATG Conformance Streams"] + title "Layout Test" + } + Transform2D { + translation 0 80 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 60 200 + } + } + DEF LAY Layout { + wrap TRUE + size 60 200 + justify ["BEGIN" "BEGIN"] + horizontal FALSE + smoothScroll TRUE + loop TRUE + scrollVertical FALSE + scrollRate 0.1 + scrollMode -1 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + ] + } + Transform2D { + translation 0 -120 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT_MODE Text { + string ["mode: scroll-in"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 16 + } + } + } + ] + } + Transform2D { + translation 0 -140 + children [ + Shape { + appearance USE APPTEXT + geometry DEF TXT_ALIGN Text { + string ["align: begin"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 0 -160 + children [ + Shape { + appearance USE APPTEXT + geometry DEF TXT_DIR Text { + string ["scroll dir: horizontal"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 0 -180 + children [ + Shape { + appearance USE APPTEXT + geometry DEF TXT_RATE Text { + string ["scroll rate: 0.1"] + fontStyle USE FS + } + } + ] + } + ] + } + + Transform2D { + translation -110 180 + children [ + DEF S Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.7 0.7 0.7 + filled TRUE + lineProps LineProperties { lineColor 0 0 0 } + } + } + geometry Rectangle {size 80 20} + } + Shape { + appearance USE APPTEXT + geometry Text { + string ["Begin"] + fontStyle USE FS + } + } + DEF TS_BE TouchSensor {} + ] + } + Transform2D { + translation -110 160 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Middle"] + fontStyle USE FS + } + } + DEF TS_ME TouchSensor {} + ] + } + Transform2D { + translation -110 140 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["End"] + fontStyle USE FS + } + } + DEF TS_EE TouchSensor {} + ] + } + + Transform2D { + translation -110 100 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Scroll In"] + fontStyle USE FS + } + } + DEF TS_SI TouchSensor {} + ] + } + Transform2D { + translation -110 80 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Scroll InOut"] + fontStyle USE FS + } + } + DEF TS_SIO TouchSensor {} + ] + } + Transform2D { + translation -110 60 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Scroll Out"] + fontStyle USE FS + } + } + DEF TS_SO TouchSensor {} + ] + } + + Transform2D { + translation 110 180 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Rate>0"] + fontStyle USE FS + } + } + DEF TS_RP TouchSensor {} + ] + } + Transform2D { + translation 110 160 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Rate<0"] + fontStyle USE FS + } + } + DEF TS_RN TouchSensor {} + ] + } + + Transform2D { + translation 110 130 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Horiz"] + fontStyle USE FS + } + } + DEF TS_SH TouchSensor {} + ] + } + Transform2D { + translation 110 110 + children [ + USE S + Shape { + appearance USE APPTEXT + geometry Text { + string ["Vert"] + fontStyle USE FS + } + } + DEF TS_SV TouchSensor {} + ] + } + + DEF C_BE Conditional { buffer { + REPLACE LAY.justify BY ["BEGIN", "BEGIN"] + REPLACE TXT_ALIGN.string BY ["align: begin"] + } } + DEF C_ME Conditional { buffer { + REPLACE LAY.justify BY ["MIDDLE", "BEGIN"] + REPLACE TXT_ALIGN.string BY ["align: middle"] + } } + DEF C_EE Conditional { buffer { + REPLACE LAY.justify BY ["END", "BEGIN"] + REPLACE TXT_ALIGN.string BY ["align: end"] + } } + + DEF C_SI Conditional { buffer { + REPLACE LAY.scrollMode BY -1 + REPLACE TXT_MODE.string BY ["mode: scroll-in"] + } } + DEF C_SIO Conditional { buffer { + REPLACE LAY.scrollMode BY 0 + REPLACE TXT_MODE.string BY ["mode: scroll-in-out"] + } } + DEF C_SO Conditional { buffer { + REPLACE LAY.scrollMode BY 1 + REPLACE TXT_MODE.string BY ["mode: scroll-out"] + } } + DEF C_RP Conditional { buffer { + REPLACE LAY.scrollRate BY 0.1 + REPLACE TXT_RATE.string BY ["scroll rate: 0.1"] + } } + DEF C_RN Conditional { buffer { + REPLACE LAY.scrollRate BY -0.1 + REPLACE TXT_RATE.string BY ["scroll rate: -0.1"] + } } + DEF C_SH Conditional { buffer { + REPLACE LAY.scrollVertical BY FALSE + REPLACE TXT_DIR.string BY ["scroll dir: horizontal"] + } } + DEF C_SV Conditional { buffer { + REPLACE LAY.scrollVertical BY TRUE + REPLACE TXT_DIR.string BY ["scroll dir: vertical"] + } } + ] +} + +ROUTE TS_BE.isActive TO C_BE.activate +ROUTE TS_ME.isActive TO C_ME.activate +ROUTE TS_EE.isActive TO C_EE.activate + +ROUTE TS_SI.isActive TO C_SI.activate +ROUTE TS_SIO.isActive TO C_SIO.activate +ROUTE TS_SO.isActive TO C_SO.activate + +ROUTE TS_RP.isActive TO C_RP.activate +ROUTE TS_RN.isActive TO C_RN.activate + +ROUTE TS_SH.isActive TO C_SH.activate +ROUTE TS_SV.isActive TO C_SV.activate + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-scroll-on-off.bt b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-on-off.bt new file mode 100644 index 0000000..1cb2bf0 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-scroll-on-off.bt @@ -0,0 +1,218 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing scrolling with scrool pause/play through scrollRate field" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation 0 -40 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 200 60 + } + } + Transform2D { + translation 0 -50 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["scroll smooth vertical"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 16 + } + } + } + ] + } + DEF LAY Layout { + wrap TRUE + size 200 60 + justify ["BEGIN" "BEGIN"] + smoothScroll TRUE + loop TRUE + scrollRate 0 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation -100 40 + children [ + Shape { + appearance DEF TXT_APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + string ["ScrollRate: 0"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 0 40 + children [ + DEF BACK_RC Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + lineProps LineProperties { + lineColor 0 0 0 + } + } + } + geometry Rectangle { + size 60 25 + } + } + Shape { + appearance USE TXT_APP + geometry Text { + string ["UP"] + fontStyle USE FS + } + } + DEF TS_UP TouchSensor {} + ] + } + Transform2D { + translation 60 40 + children [ + USE BACK_RC + Shape { + appearance USE TXT_APP + geometry Text { + string ["DOWN"] + fontStyle USE FS + } + } + DEF TS_DOWN TouchSensor {} + ] + } + + DEF C_UP Conditional { + buffer { + REPLACE LAY.scrollRate BY 0.1 + REPLACE TXT.string[0] BY "ScrollRate 0.1" + } + } + DEF RC_UP Conditional { + buffer { + REPLACE LAY.scrollRate BY 0 + REPLACE TXT.string[0] BY "ScrollRate 0" + } + } + DEF C2_UP Conditional { + buffer { + REPLACE LAY.scrollRate BY 0.2 + REPLACE TXT.string[0] BY "ScrollRate 0.2" + } + } + DEF RC2_UP Conditional { + buffer { + REPLACE LAY.scrollRate BY 0.1 + REPLACE TXT.string[0] BY "ScrollRate 0.1" + } + } + + DEF C_DOWN Conditional { + buffer { + REPLACE LAY.scrollRate BY -0.1 + REPLACE TXT.string[0] BY "ScrollRate -0.1" + } + } + DEF RC_DOWN Conditional { + buffer { + REPLACE LAY.scrollRate BY 0 + REPLACE TXT.string[0] BY "ScrollRate 0" + } + } + DEF C2_DOWN Conditional { + buffer { + REPLACE LAY.scrollRate BY -0.2 + REPLACE TXT.string[0] BY "ScrollRate -0.2" + } + } + DEF RC2_DOWN Conditional { + buffer { + REPLACE LAY.scrollRate BY -0.1 + REPLACE TXT.string[0] BY "ScrollRate -0.1" + } + } + ] +} + +ROUTE TS_UP.isOver TO C_UP.activate +ROUTE TS_UP.isOver TO RC_UP.reverseActivate +ROUTE TS_UP.isActive TO C2_UP.activate +ROUTE TS_UP.isActive TO RC2_UP.reverseActivate +ROUTE TS_DOWN.isOver TO C_DOWN.activate +ROUTE TS_DOWN.isOver TO RC_DOWN.reverseActivate +ROUTE TS_DOWN.isActive TO C2_DOWN.activate +ROUTE TS_DOWN.isActive TO RC2_DOWN.reverseActivate diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-nowrap.bt b/regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-nowrap.bt new file mode 100644 index 0000000..ab89c0a --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-nowrap.bt @@ -0,0 +1,340 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 350 + pixelHeight 650 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different vertical justification" "going bottom to top without column wrap" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -120 230 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 100 150 + } + } + Transform2D { + translation 0 -90 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + topToBottom FALSE + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation 0 230 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 120 230 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["BEGIN" "END"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -120 10 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 10 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 120 10 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["MIDDLE" "END"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -120 -210 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["END" "BEGIN"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 -210 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["END" "MIDDLE"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 120 -210 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["END" "END"] + topToBottom FALSE + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-wrap-ltr.bt b/regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-wrap-ltr.bt new file mode 100644 index 0000000..0d2354f --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-wrap-ltr.bt @@ -0,0 +1,372 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 500 + pixelHeight 500 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different vertical justification" "going from bottom to top with column wrap" "in direction left to right and 1.1 column spacing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -170 160 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 150 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + topToBottom FALSE + spacing 1.1 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + DEF S4 Shape { + appearance USE APPTEXT + geometry Text { + string ["#2"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "END"] + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -170 0 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 0 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "END"] + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -170 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "BEGIN"] + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "MIDDLE"] + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "END"] + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-wrap-rtl.bt b/regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-wrap-rtl.bt new file mode 100644 index 0000000..2742b2b --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-vert-btt-wrap-rtl.bt @@ -0,0 +1,381 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 500 + pixelHeight 500 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different vertical justification" "going bottom to top with column wrap" "in direction right to left and 1.1 column spacing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -170 160 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 150 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + DEF S4 Shape { + appearance USE APPTEXT + geometry Text { + string ["#2"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "END"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -170 0 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 0 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "END"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -170 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "BEGIN"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "MIDDLE"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "END"] + leftToRight FALSE + topToBottom FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-nowrap.bt b/regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-nowrap.bt new file mode 100644 index 0000000..cc799d8 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-nowrap.bt @@ -0,0 +1,331 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 350 + pixelHeight 650 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different vertical justification" "going top to bottom without column wrap" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -120 230 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 100 150 + } + } + Transform2D { + translation 0 -90 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + ] + } + ] + } + Transform2D { + translation 0 230 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 120 230 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["BEGIN" "END"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -120 10 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 10 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 120 10 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["MIDDLE" "END"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation -120 -210 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["END" "BEGIN"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 0 -210 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["END" "MIDDLE"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + Transform2D { + translation 120 -210 + children [ + USE BOUNDS + Transform2D { + translation 0 -90 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + size 100 150 + horizontal FALSE + justify ["END" "END"] + children [ + USE S1 + USE S2 + USE S3 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-ltr.bt b/regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-ltr.bt new file mode 100644 index 0000000..0fd71f7 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-ltr.bt @@ -0,0 +1,363 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 500 + pixelHeight 500 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different vertical justification" "going top to bottom with column wrap" "in direction left to right and 1.1 column spacing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:07 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -170 160 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 150 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + spacing 1.1 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + DEF S4 Shape { + appearance USE APPTEXT + geometry Text { + string ["#2"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "END"] + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -170 0 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 0 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "END"] + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -170 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "BEGIN"] + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "MIDDLE"] + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "END"] + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-rtl.bt b/regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-rtl.bt new file mode 100644 index 0000000..e6f0557 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-layout-vert-ttb-wrap-rtl.bt @@ -0,0 +1,372 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 500 + pixelHeight 500 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Layout node" "performing different vertical justification" "going top to bottom with column wrap" "in direction right to left and 1.1 column spacing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Layout Test" + } + Transform2D { + translation -170 160 + children [ + DEF BOUNDS Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 150 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF APPTEXT Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Alignment" "BEGIN BEGIN"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 16 + } + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "BEGIN"] + leftToRight FALSE + spacing 1.1 + children [ + DEF S1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + DEF S2 Shape { + appearance USE APPTEXT + geometry Text { + string ["Sample Text"] + fontStyle USE FS + } + } + DEF S3 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } + DEF S4 Shape { + appearance USE APPTEXT + geometry Text { + string ["#2"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "BEGIN END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["BEGIN" "END"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -170 0 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 0 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "MIDDLE END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["MIDDLE" "END"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation -170 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END BEGIN"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "BEGIN"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 0 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END MIDDLE"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "MIDDLE"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + Transform2D { + translation 170 -160 + children [ + USE BOUNDS + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE APPTEXT + geometry Text { + string ["Alignment" "END END"] + fontStyle USE FS + } + } + ] + } + Layout { + wrap TRUE + size 150 100 + horizontal FALSE + justify ["END" "END"] + leftToRight FALSE + spacing 1.1 + children [ + USE S1 + USE S2 + USE S3 + USE S4 + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-orderedgroup.bt b/regression_tests/bifs/bifs-2D-positioning-orderedgroup.bt new file mode 100644 index 0000000..9206dee --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-orderedgroup.bt @@ -0,0 +1,86 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 0 + } + WorldInfo { + info [ + "This test shows the usage of the OrderedGroup node." + "The OrderedGroup node is similar to the Group node but allows for more possibilities." + "The difference is the addition of the 'order' property which explicitely gives the display order of the children of the OrderedGroup." + "Order varies from 0 to N-1, where N is the number of children. [3 2 1 0] will display the children in reverse order." + "This test shows how to interactively change the order based on a click." + "If you click on the rectangle or the circle, and keep the mouse button down, the display order is reversed. If you release the button, the display order goes back to initial." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "OrderedGroup" + } + DEF OG OrderedGroup { + order [1 0] + children [ + DEF S1 Shape { + appearance DEF A1 Appearance { + material Material2D { + emissiveColor 1 1 1 + filled TRUE + } + } + geometry Rectangle { + size 160 60 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + } + geometry Circle { + radius 40 + } + } + DEF TS TouchSensor {} + ] + } + DEF C Conditional { + buffer { + REPLACE OG.order BY [0 1] + } + } + DEF RC Conditional { + buffer { + REPLACE OG.order BY [1 0] + } + } + ] +} + +ROUTE TS.isActive TO C.activate +ROUTE TS.isActive TO RC.reverseActivate + diff --git a/regression_tests/bifs/bifs-2D-positioning-pathlayout-graphics.bt b/regression_tests/bifs/bifs-2D-positioning-pathlayout-graphics.bt new file mode 100644 index 0000000..2a4b481 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-pathlayout-graphics.bt @@ -0,0 +1,177 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows PathLayout usage" "with text and graphics layout" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "PathLayout Test" + } + Transform2D { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + filled TRUE + } + } + geometry DEF LS Curve2D { + fineness 1 + type [2] + point DEF C2D Coordinate2D { + point [-100 0 -50 400 50 -400 100 0] + } + } + } + DEF TOUCH TouchSensor {} + ] + } + DEF PL PathLayout { + alignment [0 1] + pathOffset 0.25 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 30 20 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 30 20 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 30 20 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Rectangle { + size 30 20 + } + } + DEF TSSTOP TouchSensor {} + ] + geometry USE LS + } + ] + } + Transform2D { + translation 0 -140 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["move over shape and click" "to change the layout wrapping mode"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 20 + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [-0.5 1.5 -0.5] + } + DEF C1 Conditional { + buffer { + REPLACE PL.wrapMode BY 1 + } + } + DEF RC1 Conditional { + buffer { + REPLACE PL.wrapMode BY 0 + } + } + DEF C2 Conditional { + buffer { + REPLACE PL.wrapMode BY 2 + } + } + DEF RC2 Conditional { + buffer { + REPLACE PL.wrapMode BY 1 + } + } + DEF C3 Conditional { + buffer { + REPLACE TS.enabled BY FALSE + } + } + DEF RC3 Conditional { + buffer { + REPLACE TS.enabled BY TRUE + } + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO PL.pathOffset +ROUTE TSSTOP.isOver TO C3.activate +ROUTE TSSTOP.isOver TO RC3.reverseActivate +ROUTE TOUCH.isOver TO C1.activate +ROUTE TOUCH.isOver TO RC1.reverseActivate +ROUTE TOUCH.isActive TO C2.activate +ROUTE TOUCH.isActive TO RC2.reverseActivate + diff --git a/regression_tests/bifs/bifs-2D-positioning-pathlayout.bt b/regression_tests/bifs/bifs-2D-positioning-pathlayout.bt new file mode 100644 index 0000000..c914686 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-pathlayout.bt @@ -0,0 +1,164 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows PathLayout usage" "with text and graphics layout" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "PathLayout Test" + } + Transform2D { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + filled TRUE + } + } + geometry DEF LS Curve2D { + fineness 1 + type [2] + point DEF C2D Coordinate2D { + point [-100 0 -50 400 50 -400 100 0] + } + } + } + DEF TOUCH TouchSensor {} + ] + } + DEF PL PathLayout { + alignment [0 1] + pathOffset 0.25 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["text and "] + fontStyle DEF FS FontStyle { + size 20 + } + } + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 30 20 + } + } + DEF TSSTOP TouchSensor {} + ] + } + Shape { + appearance USE APP + geometry Text { + string ["along a path"] + fontStyle USE FS + } + } + ] + geometry USE LS + } + ] + } + Transform2D { + translation 0 -140 + children [ + Shape { + appearance USE APP + geometry Text { + string ["move over shape and click" "to change the layout wrapping mode"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 20 + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [-0.5 1.5 -0.5] + } + DEF C1 Conditional { + buffer { + REPLACE PL.wrapMode BY 1 + } + } + DEF RC1 Conditional { + buffer { + REPLACE PL.wrapMode BY 0 + } + } + DEF C2 Conditional { + buffer { + REPLACE PL.wrapMode BY 2 + } + } + DEF RC2 Conditional { + buffer { + REPLACE PL.wrapMode BY 1 + } + } + DEF C3 Conditional { + buffer { + REPLACE TS.enabled BY FALSE + } + } + DEF RC3 Conditional { + buffer { + REPLACE TS.enabled BY TRUE + } + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO PL.pathOffset +ROUTE TSSTOP.isOver TO C3.activate +ROUTE TSSTOP.isOver TO RC3.reverseActivate +ROUTE TOUCH.isOver TO C1.activate +ROUTE TOUCH.isOver TO RC1.reverseActivate +ROUTE TOUCH.isActive TO C2.activate +ROUTE TOUCH.isActive TO RC2.reverseActivate + diff --git a/regression_tests/bifs/bifs-2D-positioning-transform2D.bt b/regression_tests/bifs/bifs-2D-positioning-transform2D.bt new file mode 100644 index 0000000..2c0242f --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-transform2D.bt @@ -0,0 +1,133 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to apply affine transformations on a rectangle." + "A graphical object can be moved, rotated or scaled using the Transform2D node." + "The object (or objects) to be transformed is (are) placed in the children property of the Transform2D node." + "The Transform2D node indicates the transformation from the local coordinate system to the global coordinate system. It applies to any graphical object." + "Possible transformations are limited to translation, rotation (including with a center different from the origin) and scaling (including along different axes that original system) using respectively the translation, rotationAngle, center, scale, scaleOrientation." + "For skewing, you should see the TransformMatrix2D node." + "cf bifs-2D-positioning-transformmatrix2D" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team"] + title "Apply transformations on local coordinate systems - Transform2D node" + } + Transform2D { + translation -100 150 + children [ + Transform2D { + children [ + DEF RECT Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry Rectangle { + size 150 100 + } + } + ] + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Rectangle" "translation only"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 12 + } + } + } + ] + } + ] + } + Transform2D { + translation 100 0 + children [ + Transform2D { + scale 1 1.5 + scaleOrientation 1 + children [ + USE RECT + ] + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Scale 1.0 1.5" "Scale Orientation 1.0"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation -100 -100 + children [ + Transform2D { + rotationAngle 1 + scale 1 1.5 + children [ + USE RECT + ] + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Scale 1.0 1.5" "rotation 1.0"] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-positioning-transformmatrix2D.bt b/regression_tests/bifs/bifs-2D-positioning-transformmatrix2D.bt new file mode 100644 index 0000000..6029f77 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-positioning-transformmatrix2D.bt @@ -0,0 +1,179 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 550 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to apply affine transformations on a rectangle." + "The TransformMatrix2D works like the Transform2D node, but it requires giving the coefficients of a 3x2 matrix." + "It allows for skewing and for simple animations of skewing." + "Click on the transformed rectangles to start transformation animations." + "cf bifs-2D-positioning-transform2D" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.4 $" + "(C) 2002-2006 GPAC Team" + ] + title "Apply transformations on local coordinate systems - TransformMatrix2D node" + } + TransformMatrix2D { + tx 175 + ty 80 + children [ + DEF N1 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 200 100 + } + } + Shape { + appearance DEF N7 Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["translated rectangle"] + fontStyle DEF N0 FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 15 + } + } + } + ] + } + DEF N12 TransformMatrix2D { + mxx 0.707107 + mxy 0.707107 + tx -150 + myx -0.707107 + myy 0.707107 + ty 80 + children [ + USE N1 + Shape { + appearance USE N7 + geometry Text { + string ["translated" "and" "Pi/4-rotated rectangle"] + fontStyle USE N0 + } + } + DEF N17 TouchSensor {} + DEF N4 TimeSensor { + cycleInterval 2 + startTime -1 + } + DEF N9 ScalarInterpolator { + key [0 1] + keyValue [0.707107 1] + } + DEF N8 ScalarInterpolator { + key [0 1] + keyValue [0.707107 0] + } + DEF N6 ScalarInterpolator { + key [0 1] + keyValue [-0.707107 0] + } + DEF N5 ScalarInterpolator { + key [0 1] + keyValue [0.707107 1] + } + ] + } + DEF N11 TransformMatrix2D { + mxy 1 + tx 120 + ty -80 + children [ + USE N1 + Shape { + appearance USE N7 + geometry Text { + string ["translated" "and" "Pi/4-X-Skewed rectangle"] + fontStyle USE N0 + } + } + DEF N15 TouchSensor {} + DEF N3 TimeSensor { + cycleInterval 2 + startTime -1 + } + DEF N16 ScalarInterpolator { + key [0 1] + keyValue [1 0] + } + ] + } + DEF N10 TransformMatrix2D { + tx -50 + myx 1 + ty -50 + children [ + USE N1 + Shape { + appearance USE N7 + geometry Text { + string ["translated" "and" "Pi/4-Y-Skewed rectangle"] + fontStyle USE N0 + } + } + DEF N14 TouchSensor {} + DEF N2 TimeSensor { + cycleInterval 2 + startTime -1 + } + DEF N13 ScalarInterpolator { + key [0 1] + keyValue [1 0] + } + ] + } + ] +} + +ROUTE N17.touchTime TO N4.startTime +ROUTE N4.fraction_changed TO N9.set_fraction +ROUTE N9.value_changed TO N12.mxx +ROUTE N4.fraction_changed TO N8.set_fraction +ROUTE N8.value_changed TO N12.mxy +ROUTE N4.fraction_changed TO N6.set_fraction +ROUTE N6.value_changed TO N12.myx +ROUTE N4.fraction_changed TO N5.set_fraction +ROUTE N5.value_changed TO N12.myy +ROUTE N15.touchTime TO N3.startTime +ROUTE N3.fraction_changed TO N16.set_fraction +ROUTE N16.value_changed TO N11.mxy +ROUTE N14.touchTime TO N2.startTime +ROUTE N2.fraction_changed TO N13.set_fraction +ROUTE N13.value_changed TO N10.myx + diff --git a/regression_tests/bifs/bifs-2D-shapes-all.bt b/regression_tests/bifs/bifs-2D-shapes-all.bt new file mode 100644 index 0000000..c214757 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-shapes-all.bt @@ -0,0 +1,267 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 460 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "The MPEG-4 primitive to display graphical objects on screen is the Shape node." + "The Shape node is allowed to have a child node contained in its geometry property." + "This test shows the possible 2D nodes allowed in this geometry property:" + "* IndexedLineSet2D: this node is used to draw polylines. This geometry is not considered closed, even if last point is equal to first point. As such, it cannot be filled. The origin of its local coordinate system is the point of coordinate (0,0)." + "* Circle: its only property is its radius. The origin of its local coordinate system is the center of the circle." + "* Rectangle: its only property is its size (WxH). The origin of its local coordinate system is the center of the rectangle." + "* Curve2D (middle row): this node is used to display complex paths using Bezier Curves. It has two properties: type, points. Type gives the drawing types (segments or bezier), points gives the list of points to be consumed when reading the types. The node XCurve2D allows more drawing types (elliptical arcs ...):" + "cf bifs-2D-shapes-xcurve2D" + "* IndexedFaceSet2D: this node is similar to the IndexedLineSet2D node. It is used to display polygons (i.e. a list of segments implicitely closed by the segment [last point, first point]). The origin of its local coordinate system is the point of coordinate (0,0)." + "cf bifs-2D-shapes-indexfaceset2D" + "* PointSet2D: a list of points to be displayed (not really useful)" + "" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 15:19:18 $ - $Revision: 1.5 $" + "(C) 2002-2006 GPAC Team" + ] + title "Basic 2D Geometry nodes" + } + Transform2D { + translation -150 150 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + } + } + geometry IndexedLineSet2D { + coord Coordinate2D { + point [-50 0 0 50 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["IndexedLineSet2D" "[-50 0 0 50 50 0]"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 12 + } + } + } + ] + } + ] + } + Transform2D { + translation 0 150 + children [ + Shape { + appearance USE APP + geometry Circle { + radius 50 + } + } + Transform2D { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Circle" "radius 50"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 150 150 + children [ + Shape { + appearance USE APP + geometry Rectangle { + size 100 50 + } + } + Transform2D { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Rectangle" "Size 100 50"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -40 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Curve2D Points:" "-50 0, -100 50, 0 20, 10 30, 40 80, 50 0"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -150 0 + children [ + Shape { + appearance USE APP + geometry Curve2D { + point DEF C2D Coordinate2D { + point [-50 0 -100 50 0 20 10 30 40 80 50 0] + } + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["no type"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 3] + point USE C2D + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["type [2 3]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 170 0 + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [1 3 1] + point USE C2D + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["type [1 3 1]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation -150 -150 + children [ + Shape { + appearance USE APP + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-50 0 -25 25 0 80 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["IndexedFaceSet2D" "-50 0, -25, 25, 0 80, 50 0"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance USE APP + geometry PointSet2D { + coord Coordinate2D { + point [-50 0 -25 25 0 80 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["PointSet2D" "-50 0, -25, 25, 0 80, 50 0"] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-shapes-indexfaceset2D.bt b/regression_tests/bifs/bifs-2D-shapes-indexfaceset2D.bt new file mode 100644 index 0000000..d80b803 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-shapes-indexfaceset2D.bt @@ -0,0 +1,123 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 420 + pixelHeight 420 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows a bit more how to use the IndexedFaceSet2D node with different color fill modes." + "This node can hold a Coordinate2D node to list points and use the coordIndex field to form faces (-1 separated indexes)." + "Each face can have different color. If colorPerVertex is TRUE each point has a separate color and the result is that a face is filled using color interpolation." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "IndexedFaceSet2D and Color Modes" + } + Transform2D { + scale 0.8 0.8 + translation -120 120 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + lineProps DEF LP LineProperties { + width 6 + } + } + } + geometry IndexedFaceSet2D { + colorIndex [0 1 2 3 4 5] + coordIndex [0 1 2 3 4 5] + color Color { + color [0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1] + } + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + Transform2D { + scale 0.8 0.8 + translation 120 120 + children [ + Shape { + appearance Appearance { + material Material2D { + filled TRUE + } + } + geometry IndexedFaceSet2D { + colorIndex [0 1 2 3 4 5] + coordIndex [0 1 2 3 4 5] + color Color { + color [0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1] + } + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + Transform2D { + scale 0.8 0.8 + translation -120 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps USE LP + } + } + geometry DEF IFS2 IndexedFaceSet2D { + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + Transform2D { + scale 0.8 0.8 + translation 120 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + filled TRUE + } + } + geometry USE IFS2 + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-shapes-indexlineset2D.bt b/regression_tests/bifs/bifs-2D-shapes-indexlineset2D.bt new file mode 100644 index 0000000..a2fd01e --- /dev/null +++ b/regression_tests/bifs/bifs-2D-shapes-indexlineset2D.bt @@ -0,0 +1,100 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 420 + pixelHeight 420 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows a bit more how to use the IndexedLineSet2D node with different line color modes." + "Similarly to the IndexedFaceSet2D, one can give a color to each point." + "The result will be a line with a gradient color" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team"] + title "IndexedLineSet2D" + } + Transform2D { + scale 0.5 0.5 + translation -120 80 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0.1 0.1 0.8 + width 10 + } + } + } + geometry IndexedLineSet2D { + colorIndex [1 0 2 1 -1 1 0 2 1] + coordIndex [0 1 2 0 -1 3 4 5 3] + color Color { + color [1 1 0 1 0 1 0 1 1] + } + coord DEF COORD Coordinate2D { + point [-100 -100 0 -10 100 -100 100 100 0 10 -100 100] + } + } + } + ] + } + Transform2D { + scale 0.5 0.5 + translation 120 80 + children [ + Shape { + appearance USE APP + geometry IndexedLineSet2D { + colorIndex [1 0 2 -1 0 2 1] + colorPerVertex FALSE + coordIndex [0 1 2 0 -1 3 4 5 3] + color Color { + color [1 1 0 1 0 1 0 1 1] + } + coord USE COORD + } + } + ] + } + Transform2D { + scale 0.5 0.5 + translation 0 -80 + children [ + Shape { + appearance USE APP + geometry IndexedLineSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 0 -1 3 4 5 3] + coord USE COORD + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-shapes-pointset2D.bt b/regression_tests/bifs/bifs-2D-shapes-pointset2D.bt new file mode 100644 index 0000000..1902fe8 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-shapes-pointset2D.bt @@ -0,0 +1,56 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This shows the use of PointSet2D which is to display individual pixels on the screen." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "PointSet2D" + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + } + } + geometry PointSet2D { + coord DEF COORD Coordinate2D { + point [-0.25 -0.25 0.25 -0.25 0.25 0.25 -0.25 0.25] + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-shapes-xcurve2D.bt b/regression_tests/bifs/bifs-2D-shapes-xcurve2D.bt new file mode 100644 index 0000000..65cf2cf --- /dev/null +++ b/regression_tests/bifs/bifs-2D-shapes-xcurve2D.bt @@ -0,0 +1,188 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This shows the use of XCurve2D." + "This node is an extension of the Curve2D node. It allows more drawing types: quadratic Bezier curves and elliptical arcs." + "Both XCurve2D and Curve2D are similar to IndexedFaceSet2D and IndexedLineSet2D because they can be used to represent polygons and polylines. The difference is that it is not possible to assign a color or texture per point, nor a color per closed path. " + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "XCurve2D" + } + Transform2D { + translation -150 140 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + width 8 + } + } + } + geometry XCurve2D { + type [4] + point Coordinate2D { + point [0 0 40 0 40 0 40 40] + } + } + } + Transform2D { + translation 40 -60 + children [ + Shape { + appearance DEF TXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["anti-clockwise arc to" "point [0 0 40 0 40 0 40 40]"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] + } + Transform2D { + translation 50 140 + children [ + Shape { + appearance USE APP + geometry XCurve2D { + type [5] + point Coordinate2D { + point [0 0 40 0 40 0 40 40] + } + } + } + Transform2D { + translation 40 -60 + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["clockwise arc to" "point [0 0 40 0 40 0 40 40]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation -150 0 + children [ + Shape { + appearance USE APP + geometry XCurve2D { + type [7] + point Coordinate2D { + point [0 0 40 40 80 0] + } + } + } + Transform2D { + translation 40 -30 + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["Quadratic Bezier arc to" "point [0 0 40 40 80 0 ]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 50 0 + children [ + Shape { + appearance USE APP + geometry XCurve2D { + type [7 6] + point Coordinate2D { + point [0 0 40 40 80 0] + } + } + } + Transform2D { + translation 40 -30 + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["Quadratic Bezier arc to" "with close path"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation -50 -120 + children [ + Shape { + appearance USE APP + geometry XCurve2D { + type [7 1] + point Coordinate2D { + point [0 0 40 40 80 0 0 0] + } + } + } + Transform2D { + translation 40 -30 + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["Quadratic Bezier arc to" "without close path (lineTo origin)"] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-texturing-compositetexture2D-background.bt b/regression_tests/bifs/bifs-2D-texturing-compositetexture2D-background.bt new file mode 100644 index 0000000..8089122 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-compositetexture2D-background.bt @@ -0,0 +1,117 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the usage of the CompositeTexture node and how its background can be changed dynamically." + "Here, the texture is a circle repeated on the X and Y directions. Just one circle object is used here, the result of the drawing is translated in each directions, the object is not duplicated." + "When the user moves the mouse over a circle, the background is changed. When the user clicks on a circle, the background is also changed." + "" + "GPAC Regression Tests" "$Date: 2009-09-30 18:01:04 $ - $Revision: 1.4 $" + "(C) 2002-2006 GPAC Team" + ] + title "CompositeTexture and Background2D nodes" + } + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 0 1 0 + filled TRUE + } + texture CompositeTexture2D { + pixelWidth 64 + pixelHeight 64 + children [ + DEF B1 Background2D { backColor 0 1 1 } + DEF B2 Background2D { backColor 1 1 0 } + DEF B3 Background2D { backColor 1 0 0 } + DEF S Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + transparency 0.5 + } + } + geometry Circle { + radius 24 + } + } + DEF TS TouchSensor {} + ] + } + textureTransform TextureTransform { scale 8 4 } + } + geometry Rectangle { size 300 150 } + } + + Transform2D { + translation 140 -110 + children [ + USE S + Transform2D { + translation 0 -50 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Composite Texture Pattern" "Black color with 0.5 transparency"] + fontStyle DEF FS FontStyle { + family ["SANS"] + justify ["MIDDLE" "BEGIN"] + size 20 + } + } + } + ] + } + ] + } + Transform2D { + translation -150 160 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Move mouse over texture" "to change texture background"] + fontStyle USE FS + } + } + ] + } + ] +} + +ROUTE TS.isOver TO B2.set_bind +ROUTE TS.isActive TO B3.set_bind + diff --git a/regression_tests/bifs/bifs-2D-texturing-compositetexture2D-bitmap.bt b/regression_tests/bifs/bifs-2D-texturing-compositetexture2D-bitmap.bt new file mode 100644 index 0000000..ea4de0b --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-compositetexture2D-bitmap.bt @@ -0,0 +1,89 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the usage of the CompositeTexture node." + "It allows defining a texture made of vector graphics objects, and to use the texture like images or video. It enables using hardware acceleration for texture operations." + "In mixed 3D/2D environment, it allows mapping 2D graphics on 3D objects." + "Texture in general may be repeated without the complexity of duplicating and translating the objects." + "Here, the texture is an animated circle on a red background. The resulting texture is used on a Bitmap node." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "CompositeTexture and Bitmap nodes" + } + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 0 1 0 + } + texture CompositeTexture2D { + pixelWidth 100 + pixelHeight 100 + background Background2D { backColor 1 0 0} + children [ + DEF S Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE +# transparency 0.5 + lineProps LineProperties { width 0 } + } + } + geometry DEF C Circle { + radius 20 + } + } + ] + } + } + geometry Bitmap {scale 2 2} + } + + Transform2D { + translation 200 0 + children [ + USE S + ] + } + DEF TS TimeSensor { + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [25 10 25] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO C.radius + diff --git a/regression_tests/bifs/bifs-2D-texturing-compositetexture2D-transparent.bt b/regression_tests/bifs/bifs-2D-texturing-compositetexture2D-transparent.bt new file mode 100644 index 0000000..fb5a95f --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-compositetexture2D-transparent.bt @@ -0,0 +1,129 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + DEF B Background2D { + backColor 1 1 0 + } + WorldInfo { + info [ + "This test shows how transparency applies to composite textures." + "" + "GPAC Regression Tests" "$Date: 2009-05-20 17:11:40 $ - $Revision: 1.4 $" + "(C) 2002-2006 GPAC Team" + ] + title "CompositeTexture and Transparency" + } + Transform2D { + translation -20 80 + rotationAngle 0.57 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { size 380 40 } + } + ] + } + Transform2D { + translation -20 80 + children [ + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 0 1 0 + } + texture CompositeTexture2D { + pixelWidth 100 + pixelHeight 100 + children [ + DEF S Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + transparency 0.5 + } + } + geometry Circle { radius 50 } + } + DEF TS TouchSensor {} + ] + } + textureTransform TextureTransform { + scale 8 4 + } + } + #geometry Curve2D { type [2] point Coordinate2D { point [-300 0 -150 -500 150 500 300 0] } } + geometry Rectangle { size 300 150 } + } + ] + } + Transform2D { + translation 140 -100 + children [ + USE S + Transform2D { + translation 0 -50 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Composite Texture Pattern" "Black Circle Half-Transparent"] + fontStyle DEF FS FontStyle { + family ["SANS"] + justify ["MIDDLE" "BEGIN"] + size 20 + } + } + } + ] + } + ] + } + DEF C Conditional { + buffer { + REPLACE B.backColor BY 1 0 0 + } + } + DEF RC Conditional { + buffer { + REPLACE B.backColor BY 1 1 0 + } + } + ] +} + +ROUTE TS.isActive TO C.activate +ROUTE TS.isActive TO RC.reverseActivate + diff --git a/regression_tests/bifs/bifs-2D-texturing-gradients-text.bt b/regression_tests/bifs/bifs-2D-texturing-gradients-text.bt new file mode 100644 index 0000000..0e9c6f3 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-gradients-text.bt @@ -0,0 +1,137 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test uses a Viewport node, Gradient nodes and animation and TransformMatrix2D node in a text mirroring-like effect." + "" + "GPAC Regression Tests" "$Date: 2008-10-31 18:08:50 $ - $Revision: 1.7 $" + "(C) 2002-2006 GPAC Team" + ] + title "Text Mirroring Effect" + } + Viewport { + size 200 200 + description "Initial Viewport" + } +#if 0 + Viewport { + position -30 20 + size 50 50 + description "Text Center View" + } + Viewport { + position 75 0 + size 50 50 + description "Blending Zone View" + } +#endif + + DEF TR Transform2D { + children [ + DEF PS PlaneSensor2D { + maxPosition 100 100 + minPosition -100 0 + } + Transform2D { + translation 2 -2 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + transparency 0 + filled TRUE + } + } + geometry DEF T Text { + string ["Gradient" "Text Demo"] + fontStyle FontStyle { + justify ["MIDDLE" "END"] + size 30 + style "BOLD" + } + } + } + ] + } + DEF TESTSHAPE Shape { + appearance Appearance { + texture RadialGradient { + focalPoint 0.35 0.55 + key [0 0.7 1] + keyValue [0 1 0.5 0 0.5 1 0 1 1] + radius 0.8 + } + } + geometry USE T + } + ] + } + TransformMatrix2D { + mxy 1.5 + myy -1 + children [ + USE TR + ] + } + Transform2D { + translation 0 -100 + children [ + Shape { + appearance Appearance { + texture RadialGradient { + center 0.5 1 + focalPoint 0.5 1 + key [0 0.5 1] + keyValue [1 1 0 0.8 0 0.2 0.8 0 0.2] + opacity [0.8 1 1] + radius 1.2 + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + DEF TIME TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF PI PositionInterpolator2D { + key [0 0.5 1] + keyValue [1 1 1 0.75 1 1] + } + ] +} + +ROUTE PS.translation_changed TO TR.translation +ROUTE TIME.fraction_changed TO PI.set_fraction +ROUTE PI.value_changed TO TR.scale + diff --git a/regression_tests/bifs/bifs-2D-texturing-gradients-transparent.bt b/regression_tests/bifs/bifs-2D-texturing-gradients-transparent.bt new file mode 100644 index 0000000..cba47bf --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-gradients-transparent.bt @@ -0,0 +1,120 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This shows usage of transparency with gradient" + "Move the rectangle over the circle to see that the gradient is not uniformly transparent." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Gradient and Transparency" + } + DEF TR Transform2D { + translation 200 50 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + width 0 + } + } + texture DEF GL LinearGradient { + endPoint 1 1 + key [0 0.4 1] + keyValue [0 0 1 1 0 1 0 1 1] + spreadMethod 1 + } + } + geometry Rectangle { + size 200 200 + } + } + DEF PS PlaneSensor2D { + maxPosition 300 300 + minPosition -300 -300 + offset 200 50 + } + ] + } + Transform2D { + scale 1 1.2 + translation -50 0 + children [ + Shape { + appearance Appearance { + texture RadialGradient { + focalPoint 0.75 0.5 + key [0 0.6 1] + keyValue [1 1 1 1 0 0 1 1 0] + opacity [1 1 0.3] + } + } + geometry Circle { + radius 100 + } + } + ] + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Drag square around screen"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF C PositionInterpolator2D { + key [0 0.5 1] + keyValue [1 1 1 0 1 1] + } + ] +} + +ROUTE TS.fraction_changed TO C.set_fraction +ROUTE C.value_changed TO GL.endPoint +ROUTE PS.translation_changed TO TR.translation + diff --git a/regression_tests/bifs/bifs-2D-texturing-imagetexture-shapes.bt b/regression_tests/bifs/bifs-2D-texturing-imagetexture-shapes.bt new file mode 100644 index 0000000..22b3976 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-imagetexture-shapes.bt @@ -0,0 +1,282 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 440 + pixelHeight 440 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows image displayed on the basic 2D shapes." + "Image is considered as a texture and described in the ImageTexture node." + "The url of this node points to the image using any internet protocol (http, rtsp) or using MPEG-4 OD." + "The ImageTexture node is associated to the geometry as a children of the Shape node. The image is then clipped along the bounding box of the shape." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Displaying Images as a texture on any shape" + } + Transform2D { + translation -150 150 + children [ + Shape { + appearance DEF APP Appearance { + texture ImageTexture { + url [od:10] + } + } + geometry IndexedLineSet2D { + coord Coordinate2D { + point [-50 0 0 50 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["IndexedLineSet2D" "[-50 0 0 50 50 0]"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 12 + } + } + } + ] + } + ] + } + Transform2D { + translation 0 150 + children [ + Shape { + appearance USE APP + geometry Circle { + radius 50 + } + } + Transform2D { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Circle" "radius 50"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 150 150 + children [ + Shape { + appearance USE APP + geometry Rectangle { + size 100 50 + } + } + Transform2D { + translation 0 -40 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Rectangle" "Size 100 50"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -40 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Curve2D Points:" "-50 0, -100 50, 0 20, 10 30, 40 80, 50 0"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -150 0 + children [ + Shape { + appearance USE APP + geometry Curve2D { + point DEF C2D Coordinate2D { + point [-50 0 -100 50 0 20 10 30 40 80 50 0] + } + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["no type"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 3] + point USE C2D + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["type [2 3]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 170 0 + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [1 3 1] + point USE C2D + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["type [1 3 1]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation -150 -150 + children [ + Shape { + appearance USE APP + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-50 0 -25 25 0 80 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["IndexedFaceSet2D" "-50 0, -25, 25, 0 80, 50 0"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance USE APP + geometry PointSet2D { + coord Coordinate2D { + point [-50 0 -25 25 0 80 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["PointSet2D" "-50 0, -25, 25, 0 80, 50 0"] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-texturing-lineargradient-simple.bt b/regression_tests/bifs/bifs-2D-texturing-lineargradient-simple.bt new file mode 100644 index 0000000..b653937 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-lineargradient-simple.bt @@ -0,0 +1,75 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 500 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to fill object with linear gradients." + "Here the start and end point of the gradient are close" + "You can click on the rectangle to move the start and the end of gradient." + "You can also drag it." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Linear Gradient" + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + width 0 + } + } + texture DEF GL LinearGradient { + key [0 0.45 0.5 0.55 1] + keyValue [0.2118 0.447 0.039 0.2118 0.447 0.039 0.2627 0.933 0 0.2392 0.3098 0.04313 0.2392 0.3098 0.04313] + startPoint -1 0 + } + } + geometry DEF R Rectangle { + size 400 20 + } + } + DEF TS TouchSensor {} + ] + } + DEF SC Script { + eventIn SFVec3f set_frac + eventIn SFBool set_down + field SFNode grad USE GL + field SFBool isDown FALSE + url ["javascript:function set_down(value, timestamp) {isDown = value;}function set_frac(value, timestamp) {if (!isDown) return;pos = (value.x + 200)/400;grad.startPoint.x = pos - 1;grad.endPoint.x = 1 + pos;print('pos ' + pos);}" ] + } + ] +} + +ROUTE TS.isActive TO SC.set_down +ROUTE TS.hitPoint_changed TO SC.set_frac + diff --git a/regression_tests/bifs/bifs-2D-texturing-lineargradient-spread.bt b/regression_tests/bifs/bifs-2D-texturing-lineargradient-spread.bt new file mode 100644 index 0000000..9231fe1 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-lineargradient-spread.bt @@ -0,0 +1,113 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the different methods for spreading the gradients when the size of the object to be filled is large" + "The end point of the gradient is also animated to change the gradient aspect." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Linear Gradient Spread Methods" + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Move over and click" "to change the spread method"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF GL LinearGradient { + endPoint 0 0.5 + key [0 0.5 1] + keyValue [0 0 1 1 0 0 0 1 0] + } + } + geometry Circle { + radius 100 + } + } + DEF TS TouchSensor {} + ] + } + DEF C Conditional { + buffer { + REPLACE GL.spreadMethod BY 1 + } + } + DEF RC Conditional { + buffer { + REPLACE GL.spreadMethod BY 0 + } + } + DEF C2 Conditional { + buffer { + REPLACE GL.spreadMethod BY 2 + } + } + DEF RC2 Conditional { + buffer { + REPLACE GL.spreadMethod BY 1 + } + } + DEF TIME TimeSensor { + cycleInterval 4 + loop TRUE + } + DEF CI PositionInterpolator2D { + key [0 0.5 1] + keyValue [0 0.5 1 0.5 0 0.5] + } + ] +} + +ROUTE TS.isOver TO C.activate +ROUTE TS.isOver TO RC.reverseActivate +ROUTE TS.isActive TO C2.activate +ROUTE TS.isActive TO RC2.reverseActivate +ROUTE TIME.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO GL.endPoint + diff --git a/regression_tests/bifs/bifs-2D-texturing-movietexture-shapes.bt b/regression_tests/bifs/bifs-2D-texturing-movietexture-shapes.bt new file mode 100644 index 0000000..94b4eb2 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-movietexture-shapes.bt @@ -0,0 +1,285 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 440 + pixelHeight 440 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows a video displayed on the basic 2D shapes." + "Video, like image, is considered as a texture and described in the MovieTexture node." + "The url of this node points to the video using any internet protocol (http, rtsp) or using MPEG-4 OD." + "The MovieTexture node is associated to the geometry as a children of the Shape node. The video is then clipped along the bounding box of the shape." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.4 $" + "(C) 2002-2006 GPAC Team" + ] + title "Displaying Videos as a texture on any shape" + } + Transform2D { + translation -150 150 + children [ + Shape { + appearance DEF APP Appearance { + texture MovieTexture { + loop TRUE + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry IndexedLineSet2D { + coord Coordinate2D { + point [-50 0 0 50 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Text { + string ["IndexedLineSet2D" "[-50 0 0 50 50 0]"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 12 + } + } + } + ] + } + ] + } + Transform2D { + translation 0 150 + children [ + Shape { + appearance USE APP + geometry Circle { + radius 50 + } + } + Transform2D { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Circle" "radius 50"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 150 150 + children [ + Shape { + appearance USE APP + geometry Rectangle { + size 100 50 + } + } + Transform2D { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Rectangle" "Size 100 50"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -40 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Curve2D Points:" "-50 0, -100 50, 0 20, 10 30, 40 80, 50 0"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -150 0 + children [ + Shape { + appearance USE APP + geometry Curve2D { + point DEF C2D Coordinate2D { + point [-50 0 -100 50 0 20 10 30 40 80 50 0] + } + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["no type"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 3] + point USE C2D + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["type [2 3]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 170 0 + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [1 3 1] + point USE C2D + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["type [1 3 1]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation -150 -150 + children [ + Shape { + appearance USE APP + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-50 0 -25 25 0 80 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["IndexedFaceSet2D" "-50 0, -25, 25, 0 80, 50 0"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance USE APP + geometry PointSet2D { + coord Coordinate2D { + point [-50 0 -25 25 0 80 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["PointSet2D" "-50 0, -25, 25, 0 80, 50 0"] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-texturing-pixeltexture.bt b/regression_tests/bifs/bifs-2D-texturing-pixeltexture.bt new file mode 100644 index 0000000..d7e4048 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-pixeltexture.bt @@ -0,0 +1,191 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + DEF B Background2D { + backColor 1 0 0 + } + WorldInfo { + info [ + "This test shows the usage of the PixelTexture node." + "The PixelTexture allows to define a non-vectorial synthetic texture. The texture is defined by giving its size, the color depth in byte, and the color components (ARGB) for each pixel in the texture" + "In this scene, 4 circles are filled with a 4x4-pixels texture whose color depth are respectively 1 byte, 2 bytes, 3 and 4 bytes." + "1 byte corresponds to 8-bits grey scale" + "2 bytes corresponds to 8-bits grey scale + 8-bits transparency" + "3 bytes corresponds to 24-bits RGB" + "4 bytes corresponds to 32-bits ARGB" + "The background color of the scene is animated to see the effect on the texture." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Synthetic Non Vectorial Texture" + } + Transform2D { + translation -80 90 + children [ + Shape { + appearance Appearance { + texture PixelTexture { + image 4 4 1 + 0xFF 0xFF 0x00 0x00 + 0xFF 0xFF 0x00 0x00 + 0x00 0x00 0xFF 0xFF + 0x00 0x00 0xFF 0xFF + } + } + geometry Circle { + radius 50 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF TA Appearance { + material Material2D { + emissiveColor 1 1 1 + filled TRUE + } + } + geometry Text { + string [ "Color Depth:" "1 Byte" ] + fontStyle DEF FS FontStyle { + size 20 + justify [ "MIDDLE" "MIDDLE" ] + family "SANS" + } + } + } + ] + } + ] + } + Transform2D { + translation 80 90 + children [ + Shape { + appearance Appearance { + texture PixelTexture { + image 4 4 2 + 0x00FF 0x00FF 0x0000 0x0000 + 0x00FF 0x00FF 0x0000 0x0000 + 0x0000 0x0000 0x00FF 0x00FF + 0x0000 0x0000 0x00FF 0x00FF + } + } + geometry Circle { + radius 50 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TA + geometry Text { + string [ "Color Depth:" "2 Bytes" ] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation -80 -60 + children [ + Shape { + appearance Appearance { + texture PixelTexture { + image 4 4 3 + 0xFFFFFF 0xFFFFFF 0x00FF00 0x00FF00 + 0xFFFFFF 0xFFFFFF 0x00FF00 0x00FF00 + 0xFF00FF 0xFF00FF 0x000000 0x000000 + 0xFF00FF 0xFF00FF 0x000000 0x000000 + } + } + geometry Circle { + radius 50 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TA + geometry Text { + string [ "Color Depth:" "3 Bytes" ] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 80 -60 + children [ + Shape { + appearance Appearance { + texture PixelTexture { + image 4 4 4 + 0xFFFFFF00 0xFFFFFF00 0x00FF00FF 0x00FF00FF + 0xFFFFFF00 0xFFFFFF00 0x00FF00FF 0x00FF00FF + 0xFF00FFFF 0xFF00FFFF 0x00000000 0x00000000 + 0xFF00FFFF 0xFF00FFFF 0x00000000 0x00000000 + } + } + geometry Circle { + radius 50 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TA + geometry Text { + string [ "Color Depth:" "4 Bytes" ] + fontStyle USE FS + } + } + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF CI ColorInterpolator { + key [0 0.5 1] + keyValue [1 0 0 0 0 1 1 0 0] + } + ] +} + +ROUTE TS.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO B.backColor + diff --git a/regression_tests/bifs/bifs-2D-texturing-radialgradient-simple.bt b/regression_tests/bifs/bifs-2D-texturing-radialgradient-simple.bt new file mode 100644 index 0000000..8d93e2b --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-radialgradient-simple.bt @@ -0,0 +1,94 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to fill object with radial gradients" + "The focal point can be moved to see the effect on the gradient." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Radial Gradient Focal Point" + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Drag mouse on Shape" "to change the focal point"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF GR RadialGradient { + focalPoint 0.5 0.5 + key [0 0.5 1] + keyValue [0 0 1 0 1 1 0 1 0] + radius 0.25 + spreadMethod 1 + } + } + geometry DEF R Rectangle { + size 200 200 + } + } + DEF PS PlaneSensor2D { + maxPosition 100 100 + minPosition -100 -100 + } + ] + } + DEF V Valuator { + Factor1 0.01 + Factor2 0.01 + Factor3 0 + Factor4 0 + Offset1 0.5 + Offset2 0.5 + } + ] +} + +ROUTE PS.translation_changed TO V.inSFVec2f +ROUTE V.outSFVec2f TO GR.focalPoint + diff --git a/regression_tests/bifs/bifs-2D-texturing-radialgradient-spread.bt b/regression_tests/bifs/bifs-2D-texturing-radialgradient-spread.bt new file mode 100644 index 0000000..1c2c5ad --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-radialgradient-spread.bt @@ -0,0 +1,118 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows the different methods for spreading radial gradients when the size of the object to be filled is large" + "The focal point of the gradient is also animated to change the gradient aspect over time." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Radial Gradient Spread Methods" + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Move over and click" "to change the spread method"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + width 0 + } + } + texture DEF GR RadialGradient { + focalPoint 0 0.5 + key [0 0.5 1] + keyValue [0 0 1 1 0 0 0 1 0] + } + } + geometry DEF R Rectangle { + size 200 200 + } + } + DEF TS TouchSensor {} + ] + } + DEF C Conditional { + buffer { + REPLACE GR.spreadMethod BY 2 + } + } + DEF RC Conditional { + buffer { + REPLACE GR.spreadMethod BY 0 + } + } + DEF C2 Conditional { + buffer { + REPLACE GR.spreadMethod BY 1 + } + } + DEF RC2 Conditional { + buffer { + REPLACE GR.spreadMethod BY 2 + } + } + DEF TIME TimeSensor { + cycleInterval 4 + loop TRUE + } + DEF CI PositionInterpolator2D { + key [0 0.25 0.5 0.75 1] + keyValue [0 0.5 0.5 1 1 0.5 0.5 0 0 0.5] + } + ] +} + +ROUTE TS.isOver TO C.activate +ROUTE TS.isOver TO RC.reverseActivate +ROUTE TS.isActive TO C2.activate +ROUTE TS.isActive TO RC2.reverseActivate +ROUTE TIME.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO GR.focalPoint + diff --git a/regression_tests/bifs/bifs-2D-texturing-texturetransform-base.bt b/regression_tests/bifs/bifs-2D-texturing-texturetransform-base.bt new file mode 100644 index 0000000..f811d24 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-texturetransform-base.bt @@ -0,0 +1,234 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how a texture can be modified: either changing its positionning in the shape or its transparency" + "The positioning is given using the TextureTransform node and the transparency using the Material2D node." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "TextureTransform" + } + Transform2D { + translation -180 0 + children [ + Shape { + appearance Appearance { + texture DEF TEXTURE ImageTexture { + url [od:10] + } + } + geometry DEF REC Rectangle { + size 150 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["No Transform"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 14 + } + } + } + ] + } + ] + } + Transform2D { + translation 0 140 + children [ + Shape { + appearance Appearance { + texture USE TEXTURE + textureTransform TextureTransform { + rotation 0.78 + } + } + geometry USE REC + } + Transform2D { + translation 0 -60 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["TextureTransform: rotation PI/4"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 10 + children [ + Shape { + appearance Appearance { + texture USE TEXTURE + textureTransform TextureTransform { + scale 0.5 1.5 + } + } + geometry USE REC + } + Transform2D { + translation 0 -60 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["TextureTransform: scale 0.5 1.5"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -120 + children [ + Shape { + appearance Appearance { + texture USE TEXTURE + textureTransform TextureTransform { + translation 0.5 0 + } + } + geometry USE REC + } + Transform2D { + translation 0 -60 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["TextureTransform: translation 0.5 0"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 180 100 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 1 + filled TRUE + transparency 0.8 + } + texture USE TEXTURE + } + geometry USE REC + } + Transform2D { + translation 0 -60 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Material Transparency 0.8"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 180 -100 + children [ + Shape { + appearance Appearance { + texture USE TEXTURE + textureTransform TextureTransform { + center 0.5 0.5 + rotation 0.78 + } + } + geometry Circle { + radius 60 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Rotated On a Circle"] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-texturing-texturetransform-interact.bt b/regression_tests/bifs/bifs-2D-texturing-texturetransform-interact.bt new file mode 100644 index 0000000..239d3fd --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-texturetransform-interact.bt @@ -0,0 +1,231 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how to apply transformations to texture independantly of the transformation on the shape." + "The TextureTransform node is used here." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Transforming Textures" + } + Transform2D { + translation -150 100 + children [ + Shape { + appearance Appearance { + texture DEF IMG ImageTexture { + url [od:10] + } + textureTransform DEF TXT1 TextureTransform { + center 0.5 0.5 + } + } + geometry DEF REC Rectangle { + size 200 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Drag mouse to change" "rotation angle"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 14 + } + } + } + ] + } + DEF PS1 PlaneSensor2D { + maxPosition 400 400 + minPosition -400 -400 + } + ] + } + Transform2D { + translation -150 -100 + children [ + Shape { + appearance Appearance { + texture USE IMG + textureTransform DEF TXT2 TextureTransform { + center 0.5 0.5 + rotation 0.78 + } + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Drag mouse to change" "rotation center"] + fontStyle USE FS + } + } + ] + } + DEF PS2 PlaneSensor2D { + maxPosition 100 50 + minPosition -100 -50 + } + ] + } + Transform2D { + translation 150 100 + children [ + Shape { + appearance Appearance { + texture USE IMG + textureTransform DEF TXT3 TextureTransform {} + + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Drag mouse to" "translate texture"] + fontStyle USE FS + } + } + ] + } + DEF PS3 PlaneSensor2D { + maxPosition 400 400 + minPosition -400 -400 + } + ] + } + Transform2D { + translation 150 -100 + children [ + Shape { + appearance Appearance { + texture USE IMG + textureTransform DEF TXT4 TextureTransform { + rotation 0.78 + } + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Drag mouse to change" "texture scaling"] + fontStyle USE FS + } + } + ] + } + DEF PS4 PlaneSensor2D { + maxPosition 100 100 + minPosition -100 -100 + } + ] + } + DEF V1 Valuator { + Factor1 0.01 + } + DEF V2 Valuator { + Factor1 0.005 + Factor2 0.01 + Offset1 0.5 + Offset2 0.5 + } + DEF V3 Valuator { + Factor1 -0.005 + Factor2 -0.01 + } + DEF V4 Valuator { + Factor1 0.1 + Factor2 0.1 + } + DEF TS TimeSensor { + cycleInterval 4 + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1.56 0] + } + ] +} + +ROUTE PS1.translation_changed TO V1.inSFVec2f +ROUTE V1.outSFFloat TO TXT1.rotation +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO TXT2.rotation +ROUTE PS2.translation_changed TO V2.inSFVec2f +ROUTE V2.outSFVec2f TO TXT2.center +ROUTE PS3.translation_changed TO V3.inSFVec2f +ROUTE V3.outSFVec2f TO TXT3.translation +ROUTE PS4.translation_changed TO V4.inSFVec2f +ROUTE V4.outSFVec2f TO TXT4.scale + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-texturing-texturetransform-transformmatrix2D.bt b/regression_tests/bifs/bifs-2D-texturing-texturetransform-transformmatrix2D.bt new file mode 100644 index 0000000..6c70b4d --- /dev/null +++ b/regression_tests/bifs/bifs-2D-texturing-texturetransform-transformmatrix2D.bt @@ -0,0 +1,242 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows a texture being transformed (e.g. skewed) and this transformation is animated." + "The TransformMatrix2D is used here to allow skewing." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "ImageTexture" + } + Transform2D { + translation -180 100 + children [ + Shape { + appearance Appearance { + texture DEF TEXTURE ImageTexture { + url [od:10] + } + textureTransform DEF MX1 TransformMatrix2D {} + + } + geometry DEF REC Rectangle { + size 150 100 + } + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Texture horizontal scaling"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 14 + } + } + } + ] + } + ] + } + Transform2D { + translation -180 -100 + children [ + Shape { + appearance Appearance { + texture USE TEXTURE + textureTransform DEF MX2 TransformMatrix2D {} + + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Texture vertical scaling"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 100 + children [ + Shape { + appearance Appearance { + texture USE TEXTURE + textureTransform DEF MX3 TransformMatrix2D {} + + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Texture horizontal skewing"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -100 + children [ + Shape { + appearance Appearance { + texture USE TEXTURE + textureTransform DEF MX4 TransformMatrix2D { + mxy 1 + } + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Texture vertical skewing"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 180 100 + children [ + Shape { + appearance Appearance { + texture USE TEXTURE + textureTransform DEF MX5 TransformMatrix2D {} + + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Texture horizontal translating"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 180 -100 + children [ + Shape { + appearance Appearance { + texture USE TEXTURE + textureTransform DEF MX6 TransformMatrix2D {} + + } + geometry USE REC + } + Transform2D { + translation 0 -70 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Texture vertical translating"] + fontStyle USE FS + } + } + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 2 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO MX1.mxx +ROUTE SI.value_changed TO MX2.myy +ROUTE SI.value_changed TO MX3.mxy +ROUTE SI.value_changed TO MX4.myx +ROUTE SI.value_changed TO MX5.tx +ROUTE SI.value_changed TO MX6.ty + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-2D-viewport-complete.bt b/regression_tests/bifs/bifs-2D-viewport-complete.bt new file mode 100644 index 0000000..6ef2094 --- /dev/null +++ b/regression_tests/bifs/bifs-2D-viewport-complete.bt @@ -0,0 +1,715 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows usage of the viewport per layer" "Translated from SVG" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "SVG Test Suite - (C) W3C 2002"] + title "Animation Stream" + } + Background2D { + backColor 1 1 1 + } + Transform2D { + translation -225 225 + children [ + Transform2D { + translation 0 -30 + children [ + Transform2D { + translation 10 -30 + children [ + Shape { + appearance DEF N0 Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["BIFS to fit"] + fontStyle DEF N13 FontStyle { + family ["SANS"] + size 9 + } + } + } + ] + } + Transform2D { + translation 20 -40 + children [ + DEF N4 Transform2D { + children [ + Transform2D { + translation 15 -20 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + lineProps LineProperties { + lineColor 1 0 0 + } + } + } + geometry Rectangle { + size 29 39 + } + } + ] + } + Transform2D { + translation 0 -5 + children [ + Transform2D { + translation 15 -15 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Circle { + radius 10 + } + } + ] + } + Transform2D { + translation 12 -12 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Circle { + radius 1.5 + } + } + ] + } + Transform2D { + translation 17 -12 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Circle { + radius 1.5 + } + } + ] + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + lineProps LineProperties { + width 2 + } + } + } + geometry Curve2D { + type [2] + point Coordinate2D { + point [10 -19 15 -22.75 15 -22.75 20 -19] + } + } + } + ] + } + ] + } + ] + } + Transform2D { + translation 10 -110 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["Viewport 1"] + fontStyle USE N13 + } + } + ] + } + Transform2D { + translation 10 -120 + children [ + DEF N12 Transform2D { + translation 25 -15 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + } + } + } + geometry Rectangle { + size 49 29 + } + } + ] + } + ] + } + Transform2D { + translation 10 -180 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["Viewport 2"] + fontStyle USE N13 + } + } + ] + } + Transform2D { + translation 20 -190 + children [ + DEF N10 Transform2D { + translation 15 -30 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + } + } + } + geometry Rectangle { + size 29 59 + } + } + ] + } + ] + } + Transform2D { + translation 100 -60 + children [ + DEF N7 Transform2D { + translation 0 30 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["-------------- fit= 1 --------------"] + fontStyle USE N13 + } + } + ] + } + Transform2D { + children [ + DEF N14 Transform2D { + translation 15 15 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["alignment" "[ -1 * ]"] + fontStyle DEF N1 FontStyle { + family ["SANS"] + justify ["MIDDLE"] + size 9 + } + } + } + ] + } + USE N12 + Transform2D { + translation 25 -15 + children [ + Layer2D { + size 50 30 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [-1 0] + fit 1 + } + } + ] + } + ] + } + Transform2D { + translation 70 0 + children [ + DEF N9 Transform2D { + translation 15 15 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["alignment" "[ 0 * ]"] + fontStyle USE N1 + } + } + ] + } + USE N12 + Transform2D { + translation 25 -15 + children [ + Layer2D { + size 50 30 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [0 0] + fit 1 + } + } + ] + } + ] + } + Transform2D { + translation 0 -70 + children [ + DEF N5 Transform2D { + translation 15 15 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["alignment" "[ 1 * ]"] + fontStyle USE N1 + } + } + ] + } + USE N12 + Transform2D { + translation 25 -15 + children [ + Layer2D { + size 50 30 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [1 0] + fit 1 + } + } + ] + } + ] + } + ] + } + Transform2D { + translation 250 -60 + children [ + USE N7 + Transform2D { + children [ + DEF N11 Transform2D { + translation 15 15 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["alignment" "[ * -1 ]"] + fontStyle USE N1 + } + } + ] + } + USE N10 + Transform2D { + translation 15 -30 + children [ + Layer2D { + size 30 60 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [0 -1] + fit 1 + } + } + ] + } + Transform2D { + translation 50 0 + children [ + DEF N3 Transform2D { + translation 15 15 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["alignment" "[ * 0 ]"] + fontStyle USE N1 + } + } + ] + } + USE N10 + Transform2D { + translation 15 -30 + children [ + Layer2D { + size 30 60 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [0 0] + fit 1 + } + } + ] + } + ] + } + Transform2D { + translation 100 0 + children [ + DEF N2 Transform2D { + translation 15 15 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["alignment" "[ * 1 ]"] + fontStyle USE N1 + } + } + ] + } + USE N10 + Transform2D { + translation 15 -30 + children [ + Layer2D { + size 30 60 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [0 1] + fit 1 + } + } + ] + } + ] + } + ] + } + ] + } + Transform2D { + translation 100 -220 + children [ + DEF N6 Transform2D { + translation 0 30 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["---------- fit = 2 ----------"] + fontStyle USE N13 + } + } + ] + } + USE N14 + USE N10 + Transform2D { + translation 15 -30 + children [ + Layer2D { + size 30 60 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [-1 0] + fit 2 + } + } + ] + } + Transform2D { + translation 50 0 + children [ + USE N9 + USE N10 + Transform2D { + translation 15 -30 + children [ + Layer2D { + size 30 60 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [0 0] + fit 2 + } + } + ] + } + ] + } + Transform2D { + translation 100 0 + children [ + USE N5 + USE N10 + Transform2D { + translation 15 -30 + children [ + Layer2D { + size 30 60 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [1 0] + fit 2 + } + } + ] + } + ] + } + ] + } + Transform2D { + translation 250 -190 + children [ + Transform2D { + translation 0 -30 + children [ + USE N6 + Transform2D { + children [ + USE N11 + USE N12 + Transform2D { + translation 25 -15 + children [ + Layer2D { + size 50 30 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [0 -1] + fit 2 + } + } + ] + } + ] + } + Transform2D { + translation 70 0 + children [ + USE N3 + USE N12 + Transform2D { + translation 25 -15 + children [ + Layer2D { + size 50 30 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [0 0] + fit 2 + } + } + ] + } + ] + } + Transform2D { + translation 140 0 + children [ + USE N2 + USE N12 + Transform2D { + translation 25 -15 + children [ + Layer2D { + size 50 30 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + alignment [0 1] + fit 2 + } + } + ] + } + ] + } + ] + } + ] + } + Transform2D { + translation 175 -300 + children [ + Transform2D { + translation 0 -30 + children [ + Transform2D { + translation 0 30 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["---------- fit = 0 ----------"] + fontStyle USE N13 + } + } + ] + } + Transform2D { + children [ + DEF N8 Transform2D { + translation 15 15 + children [ + Shape { + appearance USE N0 + geometry Text { + string ["alignment" "[ * * ]"] + fontStyle USE N1 + } + } + ] + } + USE N12 + Transform2D { + translation 25 -15 + children [ + Layer2D { + size 50 30 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + } + } + ] + } + ] + } + Transform2D { + translation 100 0 + children [ + USE N8 + USE N10 + Transform2D { + translation 15 -30 + children [ + Layer2D { + size 30 60 + children [ + USE N4 + ] + viewport Viewport { + position 15 -20 + size 30 40 + } + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-2D-viewport-simple.bt b/regression_tests/bifs/bifs-2D-viewport-simple.bt new file mode 100644 index 0000000..14e463c --- /dev/null +++ b/regression_tests/bifs/bifs-2D-viewport-simple.bt @@ -0,0 +1,88 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D { + url [od:10] + } + WorldInfo { + info ["This shows usage of Viewport in the scene" "viewport can be changed through the player's viewport list" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Viewport Test" + } + DEF VP Viewport { + size 200 200 + orientation 0.5 + alignment [0 0] + fit 2 + description "basic Viewport" + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture RadialGradient { + focalPoint 0.5 0.5 + key [0 1] + keyValue [0 1 0 0 1 1] + radius 0.8 + } + } + geometry Rectangle { + size 100 100 + } + } + DEF TS TouchSensor {} + ] + } + ] +} + +ROUTE TS.isOver TO VP.set_bind + +AT 0 { + REPLACE VP.set_bind BY FALSE +} + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 22 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-background-images.bt b/regression_tests/bifs/bifs-3D-background-images.bt new file mode 100644 index 0000000..ded44b2 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-background-images.bt @@ -0,0 +1,87 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + includeInlineProfileLevelFlag true + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + WorldInfo { + info ["This shows Background with transparent texture on all back planes" "" "GPAC Regression Tests" "$Date: 2008-06-26 07:55:39 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Background Test" + } + Viewpoint {} + Background { + groundAngle [0.56 1.2] + groundColor [0 0 0, 0.1 0.8 0.8, 0.5 1 0] + skyAngle [0.5 1.2 1.8] + skyColor [0 0 0.5, 0.2 0.4 0.2, 0.4 0.1 0.0, 0.5 0.5 0.2] + frontUrl ["20"] + backUrl ["20"] + leftUrl ["20"] + rightUrl ["20"] + topUrl ["20"] + bottomUrl ["20"] + } + +#if 0 + Transform { + children [ + Shape { + appearance Appearance { + material Material { + diffuseColor 1 1 1 + } + texture ImageTexture { url ["./../auxiliary_files/logo.jpg"] } + } + geometry Box { + size 3 2 5 + } + } + ] + } +#endif + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 20 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.png" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-background.bt b/regression_tests/bifs/bifs-3D-background.bt new file mode 100644 index 0000000..516daac --- /dev/null +++ b/regression_tests/bifs/bifs-3D-background.bt @@ -0,0 +1,56 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + includeInlineProfileLevelFlag true + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + WorldInfo { + info ["This shows a background node" "with ground and sky" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Background Test" + } + Viewpoint {} + Background { + groundAngle [0.56 1.2] + groundColor [0 0 0, 0.1 0.8 0.8, 0.5 1 0] + skyAngle [0.5 1.2 1.8] + skyColor [0 0 0.5, 0.2 0.4 0.2, 0.4 0.1 0.0, 0.5 0.5 0.2] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { + diffuseColor 1 1 1 + } + texture ImageTexture { url ["./../auxiliary_files/logo.jpg"] } + } + geometry Box { + size 3 2 5 + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-3D-interactivity-collision-proxy.bt b/regression_tests/bifs/bifs-3D-interactivity-collision-proxy.bt new file mode 100644 index 0000000..4fe2acf --- /dev/null +++ b/regression_tests/bifs/bifs-3D-interactivity-collision-proxy.bt @@ -0,0 +1,80 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 200 + } + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Collision Test" + info ["This shows the collision node " "used with a sphere proxy" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + DEF C Collision { + proxy Shape { geometry Sphere { radius 6 } } + children [ + Shape { + appearance Appearance { + material DEF MAT Material { diffuseColor 0 1 0 } + } + geometry Box {size 20 2 0.1} + } + ] + } + DEF S Script { + eventIn SFTime on_collide + eventOut MFString outText + eventOut SFColor outCol + url "javascript: + function on_collide(value) { + v = new SFColor(1, 0, 0); + outCol = v; + outText[0] = 'collision time: ' + value; + } + " + } + + Transform { + translation 0 2 0 + children [ + Shape { + appearance Appearance { + material Material2D { emissiveColor 0 0 0 filled TRUE } + } + geometry DEF T Text { + string "no collision" + fontStyle FontStyle { + size 2 + justify "MIDDLE" + } + } + } + ] + } + + ] +} + +ROUTE C.collideTime TO S.on_collide +ROUTE S.outText TO T.string +ROUTE S.outCol TO MAT.diffuseColor + diff --git a/regression_tests/bifs/bifs-3D-interactivity-collision.bt b/regression_tests/bifs/bifs-3D-interactivity-collision.bt new file mode 100644 index 0000000..7f94e4f --- /dev/null +++ b/regression_tests/bifs/bifs-3D-interactivity-collision.bt @@ -0,0 +1,79 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 200 + } + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Collision Test" + info ["This shows the collision node " "used without proxy" "" "GPAC Regression Tests" "$Date: 2008-06-26 07:55:39 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + DEF C Collision { + children [ + DEF B Shape { + appearance Appearance { + material DEF MAT Material { diffuseColor 0 1 0 } + } + geometry Box {size 20 0.5 0.1} + } + ] + } + DEF S Script { + eventIn SFTime on_collide + eventOut MFString outText + eventOut SFColor outCol + url "javascript: + function on_collide(value) { + v = new SFColor(1, 0, 0); + outCol = v; + outText[0] = 'collision time: ' + value; + } + " + } + + Transform { + translation 0 0 0.055 + children [ + Shape { + appearance Appearance { + material Material2D { emissiveColor 0 0 0 filled TRUE } + } + geometry DEF T Text { + string "no collision" + fontStyle FontStyle { + size 2 + justify "MIDDLE" + } + } + } + ] + } + + ] +} + +ROUTE C.collideTime TO S.on_collide +ROUTE S.outText TO T.string +ROUTE S.outCol TO MAT.diffuseColor + diff --git a/regression_tests/bifs/bifs-3D-interactivity-cylindersensor.bt b/regression_tests/bifs/bifs-3D-interactivity-cylindersensor.bt new file mode 100644 index 0000000..f19045b --- /dev/null +++ b/regression_tests/bifs/bifs-3D-interactivity-cylindersensor.bt @@ -0,0 +1,90 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + WorldInfo { + title "CylinderSensor test" + info ["This shows a cylinderSensor" "exercising isActive, rotationChanged and trackPoint_changed events" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + Background2D {backColor 1 1 1} + Viewpoint {} + DEF TF Transform { + translation 2 0 0 + children [ + DEF CS CylinderSensor { + } + Shape { + appearance Appearance { + material Material { + diffuseColor 1 0 0 + } + } + geometry Box { + size 2 2 1 + } + } + ] + } + + Transform { + translation -5 1 -10 + children [ + Shape { + appearance Appearance { + material DEF M Material { + diffuseColor 1 0 0.245 + } + } + geometry Sphere { radius 2 } + } + ] + } + Transform { + translation 0 -3 0 + children [ + Shape { + #appearance Appearance { material Material2D { filled TRUE emissiveColor 0 1 0} } + appearance Appearance { material Material {emissiveColor 0 1 0 diffuseColor 0 0 1} } + geometry DEF TXT Text { string "Trackpoint" fontStyle FontStyle {size 0.8 justify "MIDDLE" } } + } + ] + } + DEF V Valuator{} + + DEF C Conditional { + buffer { REPLACE M.diffuseColor BY 0 0.25 0.65 } + } + DEF RC Conditional { + buffer { REPLACE M.diffuseColor BY 1 0 0.245} + } + + ] +} +ROUTE CS.isActive TO C.activate +ROUTE CS.isActive TO RC.reverseActivate +ROUTE CS.rotation_changed TO TF.rotation + +ROUTE CS.trackPoint_changed TO V.inSFVec3f +ROUTE V.outMFString TO TXT.string diff --git a/regression_tests/bifs/bifs-3D-interactivity-planesensor.bt b/regression_tests/bifs/bifs-3D-interactivity-planesensor.bt new file mode 100644 index 0000000..08f14e2 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-interactivity-planesensor.bt @@ -0,0 +1,93 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + Viewpoint {} + WorldInfo { + title "PlaneSensor test" + info ["This shows a planeSensor" "exercising isActive, translationChanged and trackPoint_changed events" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + Background2D {backColor 1 1 1} + + DEF TF Transform { + translation 2 0 0 + children [ + DEF PS PlaneSensor { + maxPosition 2 2 + minPosition -2 -2 + offset 2 0 0 + } + Shape { + appearance Appearance { + material Material { + diffuseColor 1 0 0 + } + } + geometry Box { + size 2 2 1 + } + } + ] + } + + Transform { + translation -5 1 -10 + children [ + Shape { + appearance Appearance { + material DEF M Material { + diffuseColor 1 0 0.245 + } + } + geometry Sphere { radius 2 } + } + ] + } + Transform { + translation 0 -3 0 + children [ + Shape { + appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0} } + geometry DEF TXT Text { string "Trackpoint" fontStyle FontStyle {size 0.8 justify "MIDDLE"} } + } + ] + } + DEF V Valuator{} + + DEF C Conditional { + buffer { REPLACE M.diffuseColor BY 0 0.25 0.65 } + } + DEF RC Conditional { + buffer { REPLACE M.diffuseColor BY 1 0 0.245} + } + + ] +} +ROUTE PS.isActive TO C.activate +ROUTE PS.isActive TO RC.reverseActivate +ROUTE PS.translation_changed TO TF.translation + +ROUTE PS.trackPoint_changed TO V.inSFVec3f +ROUTE V.outMFString TO TXT.string diff --git a/regression_tests/bifs/bifs-3D-interactivity-proximitysensor.bt b/regression_tests/bifs/bifs-3D-interactivity-proximitysensor.bt new file mode 100644 index 0000000..82598d3 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-interactivity-proximitysensor.bt @@ -0,0 +1,80 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "ProximitySensor test" + info ["This shows a ProximitySensor" "exercising isActive event" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + Viewpoint {position 0 0 10} + DEF Box Transform { + children [ + DEF PS ProximitySensor { + center 0 0 0 + size 8 8 8 + } + Shape { + appearance Appearance { + material DEF M1 Material { + diffuseColor 1 0 0 + } + } + geometry Box { + size 2 2 2 + } + } + ] + } + + + DEF TS TimeSensor { + cycleInterval 5.0 + loop TRUE + startTime -1 + } + + DEF Animation OrientationInterpolator { + key [0.0, + 0.20, + 0.40, + 0.60, + 0.80, + 1.0] + keyValue [0 1 0 0, + 0 1 0 1.57079, + 0 1 0 3.14159, + 0 1 0 4.71238, + 0 1 0 5.52456, + 0 1 0 6.28318] + } + ] +} + +ROUTE PS.enterTime TO TS.startTime +ROUTE PS.exitTime TO TS.stopTime + +ROUTE TS.fraction_changed TO Animation.set_fraction +ROUTE Animation.value_changed TO Box.rotation diff --git a/regression_tests/bifs/bifs-3D-interactivity-spheresensor.bt b/regression_tests/bifs/bifs-3D-interactivity-spheresensor.bt new file mode 100644 index 0000000..1f8549a --- /dev/null +++ b/regression_tests/bifs/bifs-3D-interactivity-spheresensor.bt @@ -0,0 +1,90 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + Viewpoint {} + WorldInfo { + title "SphereSensor test" + info ["This shows a SphereSensor" "exercising isActive, rotationChanged and trackPoint_changed events" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + Background2D {backColor 1 1 1} + + DEF TF Transform { + translation 2 0 0 + children [ + DEF CS SphereSensor { + } + Shape { + appearance Appearance { + material Material { + diffuseColor 1 0 0 + } + } + geometry Box { + size 4 4 1 + } + } + ] + } + + Transform { + translation -5 1 -10 + children [ + Shape { + appearance Appearance { + material DEF M Material { + diffuseColor 1 0 0.245 + } + } + geometry Sphere { radius 2 } + } + ] + } + Transform { + translation 0 -3 0 + children [ + Shape { + appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0} } + geometry DEF TXT Text { string "Trackpoint" fontStyle FontStyle {size 0.8 justify "MIDDLE"} } + } + ] + } + DEF V Valuator{} + + DEF C Conditional { + buffer { REPLACE M.diffuseColor BY 0 0.25 0.65 } + } + DEF RC Conditional { + buffer { REPLACE M.diffuseColor BY 1 0 0.245} + } + + ] +} +ROUTE CS.isActive TO C.activate +ROUTE CS.isActive TO RC.reverseActivate +ROUTE CS.rotation_changed TO TF.rotation + +ROUTE CS.trackPoint_changed TO V.inSFVec3f +ROUTE V.outMFString TO TXT.string diff --git a/regression_tests/bifs/bifs-3D-interactivity-visibilitysensor.bt b/regression_tests/bifs/bifs-3D-interactivity-visibilitysensor.bt new file mode 100644 index 0000000..77d1c7f --- /dev/null +++ b/regression_tests/bifs/bifs-3D-interactivity-visibilitysensor.bt @@ -0,0 +1,100 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + + Viewpoint {position 0 0 10} + + WorldInfo { + title "VisibilitySensor test" + info ["This shows a VisibiliitySensor" "controling spinning of a cube" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + + Transform { + translation 10 0 0 + children [ + DEF PS VisibilitySensor { + center 0 0 0 + size 8 8 8 + } + Shape { + appearance Appearance { + material Material { + diffuseColor 1 1 0 + } + } + geometry Box { + size 8 8 8 + } + } + ] + } + + + DEF Box Transform { + children [ + Shape { + appearance Appearance { + material DEF M1 Material { + diffuseColor 1 0 0 + } + } + geometry Box { + size 2 2 2 + } + } + ] + } + + + DEF TS TimeSensor { + cycleInterval 5.0 + loop TRUE + startTime -1 + } + + DEF Animation OrientationInterpolator { + key [0.0, + 0.20, + 0.40, + 0.60, + 0.80, + 1.0] + keyValue [0 1 0 0, + 0 1 0 1.57079, + 0 1 0 3.14159, + 0 1 0 4.71238, + 0 1 0 5.52456, + 0 1 0 6.28318] + } + ] +} + +ROUTE PS.enterTime TO TS.startTime +ROUTE PS.exitTime TO TS.stopTime + +ROUTE TS.fraction_changed TO Animation.set_fraction +ROUTE Animation.value_changed TO Box.rotation diff --git a/regression_tests/bifs/bifs-3D-lighting-directionalLight.bt b/regression_tests/bifs/bifs-3D-lighting-directionalLight.bt new file mode 100644 index 0000000..dfa5a7b --- /dev/null +++ b/regression_tests/bifs/bifs-3D-lighting-directionalLight.bt @@ -0,0 +1,63 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +Group { +children [ + NavigationInfo {type ["ANY" "EXAMINE"] headlight FALSE} + + WorldInfo { + title "DirectionalLight test" + info ["This shows a directional light" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + DirectionalLight { + color 1 0 0 + direction 0 1 1 + } + DEF BB Group { + children [ + DEF B Shape { + appearance Appearance { material Material {}} + geometry Box { size 1 1 1} + } + Transform { + translation 2 0 0 + children [ USE B] + } + Transform { + translation -2 0 0 + children [ USE B] + } + ] + } + Transform { + translation 0 2 0 + children [ USE BB] + } + Transform { + translation 0 -2 0 + children [ USE BB] + } + ] +} diff --git a/regression_tests/bifs/bifs-3D-lighting-fog.bt b/regression_tests/bifs/bifs-3D-lighting-fog.bt new file mode 100644 index 0000000..3135364 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-lighting-fog.bt @@ -0,0 +1,56 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + WorldInfo { + title "Fog test" + info ["This shows a fog" "with varying visibility range" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + DEF AFOG Fog {color 0.2 0.2 0.2 visibilityRange 4} + Transform { + children [ + Inline { url "./../auxiliary_files/nefertiti.wrl"} + DirectionalLight { color 1 0 0 direction 1 1 -1 } + DEF TOUCH TouchSensor{} + ] + } + DEF TS TimeSensor {cycleInterval 6.0 loop TRUE } + DEF SI ScalarInterpolator{ + key [0 0.5 1] + keyValue [16 0 16] + } + DEF V Valuator { + Factor1 -1 + Offset1 1 + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO AFOG.visibilityRange + +ROUTE TOUCH.isOver TO V.inSFBool +ROUTE V.outSFBool TO AFOG.set_bind + diff --git a/regression_tests/bifs/bifs-3D-lighting-pointlight.bt b/regression_tests/bifs/bifs-3D-lighting-pointlight.bt new file mode 100644 index 0000000..835ff8b --- /dev/null +++ b/regression_tests/bifs/bifs-3D-lighting-pointlight.bt @@ -0,0 +1,71 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +Group { +children [ + NavigationInfo {type ["ANY" "EXAMINE"] headlight FALSE} + + WorldInfo { + title "PointLight test" + info ["This shows a point light" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + DEF SP PointLight { + location 0.0 0.0 2.0 + color 0 0 1 + attenuation 1 0.5 0 + } + DEF BB Group { + children [ + DEF B Shape { + appearance Appearance { material Material {}} + geometry Box { size 1 1 1} + } + Transform { + translation 2 0 0 + children [ USE B] + } + Transform { + translation -2 0 0 + children [ USE B] + } + ] + } + Transform { + translation 0 2 0 + children [ USE BB] + } + Transform { + translation 0 -2 0 + children [ USE BB] + } + DEF TS TimeSensor { loop TRUE cycleInterval 2} + DEF CI PositionInterpolator { + key [0 0.5 1] + keyValue [1 0 0 1 1 0 1 0 0] + } + ] +} + +ROUTE TS.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO SP.attenuation diff --git a/regression_tests/bifs/bifs-3D-lighting-spotlight.bt b/regression_tests/bifs/bifs-3D-lighting-spotlight.bt new file mode 100644 index 0000000..abf83d9 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-lighting-spotlight.bt @@ -0,0 +1,72 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +Group { +children [ + NavigationInfo {type ["ANY" "EXAMINE"] headlight FALSE} + + WorldInfo { + title "SpotLight test" + info ["This shows a spot light" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + DEF SL SpotLight { + location 0.0 0.0 2.0 + color 0 0 1 + direction 0 0 -1 + } + DEF BB Group { + children [ + DEF B Shape { + appearance Appearance { material Material {}} + geometry Box { size 1 1 1} + } + Transform { + translation 2 0 0 + children [ USE B] + } + Transform { + translation -2 0 0 + children [ USE B] + } + ] + } + Transform { + translation 0 2 0 + children [ USE BB] + } + Transform { + translation 0 -2 0 + children [ USE BB] + } + + DEF TS TimeSensor { loop TRUE cycleInterval 2} + DEF CI PositionInterpolator { + key [0 0.5 1] + keyValue [-2 0 -1 2 0 -1 -2 0 -1] + } + ] +} + +ROUTE TS.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO SL.direction diff --git a/regression_tests/bifs/bifs-3D-positioning-billboard-viewer-alignment.bt b/regression_tests/bifs/bifs-3D-positioning-billboard-viewer-alignment.bt new file mode 100644 index 0000000..372e079 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-positioning-billboard-viewer-alignment.bt @@ -0,0 +1,62 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "Billboard Test" + info ["This shows a Billboard in viewer-align mode" "The green box coordinate system should onlyt be a translation of the viewer one" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + Viewpoint {position 0 0 10} + NavigationInfo { type ["EXAMINE" "ANY"] } + Billboard { + axisOfRotation 0 0 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 0 1 0 + shininess 0.5 + } + } + geometry Box {size 0.5 0.5 0.5} + } + ] + } + Transform { + translation -1 0 0 + children [ + Shape { + appearance Appearance { + material Material { + diffuseColor 1 0 0 + } + } + geometry Box {size 0.5 0.5 0.5} + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-3D-positioning-billboard.bt b/regression_tests/bifs/bifs-3D-positioning-billboard.bt new file mode 100644 index 0000000..5d43e6c --- /dev/null +++ b/regression_tests/bifs/bifs-3D-positioning-billboard.bt @@ -0,0 +1,61 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + WorldInfo { + title "Billboard Test" + info ["This shows a Billboard" "The green box should rotate to face the viewer" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Viewpoint {position 0 0 10} + Billboard { + axisOfRotation 0 1 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 0 1 0 + shininess 0.5 + } + } + geometry Box {size 0.5 0.5 0.5} + } + ] + } + Transform { + translation -1 0 0 + children [ + Shape { + appearance Appearance { + material Material { + diffuseColor 1 0 0 + } + } + geometry Box {size 0.5 0.5 0.5} + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-3D-positioning-gravity.bt b/regression_tests/bifs/bifs-3D-positioning-gravity.bt new file mode 100644 index 0000000..b7f2ba7 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-positioning-gravity.bt @@ -0,0 +1,71 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +Group { + children [ + NavigationInfo {avatarSize [0.25 1.6 8] } + Viewpoint {position 0 0 50} + WorldInfo { + title "Gravity test" + info ["This shows an rectangle used as ground" "with an jumpable obstacle" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + Group { + children [ + Background2D { backColor 1 1 1} + DEF TR Transform { + rotation 1 0 0 1.57 + translation 0 -8 -10 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 0 1 0 + shininess 0.5 + } + } + geometry Rectangle {size 50 100} + } + ] + } + Transform { + translation 0 -8 -10 + children [ + DEF B Shape { + appearance Appearance { + texture ImageTexture { url "./../auxiliary_files/logo.jpg"} + } + geometry Box { size 2 2 2 } + } + ] + } + Transform { + translation -10 -7 -10 + children [ + USE B Shape + ] + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-3D-positioning-layer3D-views.bt b/regression_tests/bifs/bifs-3D-positioning-layer3D-views.bt new file mode 100644 index 0000000..1f7b076 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-positioning-layer3D-views.bt @@ -0,0 +1,160 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 200 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + + Background2D {backColor 1 1 1 url "od:10"} + MediaControl {url "od:10" loop TRUE} + + WorldInfo { + title "Layer3D test" + info ["This shows several Layer3D nodes" "offering different views of the same scene" "navigation is not enabled on all layers" "" "GPAC Regression Tests" "$Date: 2008-11-24 14:58:25 $ - $Revision: 1.6 $" "(C) 2002-2004 GPAC Team"] + } + Transform2D { + translation -100 0 + children [ + Shape { + appearance DEF TXTAPP Appearance { + material Material2D { emissiveColor 1 0 0 filled TRUE } + } + geometry Text { + string ["This text" "is behind"] + fontStyle FontStyle { + size 26 + justify ["MIDDLE", "BEGIN"] + } + } + } + Layer3D { + #SHORTCUT inline viewpoint otherwise the rotation will make all models rotate + viewpoint Viewpoint {position 0 -100 1000 } + # this forbids navigation in layer + navigationInfo NavigationInfo {type ["None"]} + size 200 200 + children [ + DEF TR Transform { + children [ + DEF NEF Inline { url "../auxiliary_files/nefertiti.wrl" } + ] + } + ] + } + Shape { + appearance USE TXTAPP + geometry Text { + string ["This text" "is in front"] + fontStyle FontStyle { + size 26 + justify ["MIDDLE", "END"] + } + } + } + ] + } + + Transform2D { + translation 100 50 + children [ + Layer3D { + viewpoint Viewpoint {position 0 -100 1000 } + navigationInfo NavigationInfo {type ["EXAMINE"] } + size 200 100 + children [ + Background2D {url "20" } + USE NEF + ] + } + ] + } + Transform2D { + translation 100 -50 + children [ + Layer3D { + viewpoint Viewpoint {position 0 -100 1000 } + navigationInfo NavigationInfo {headlight FALSE} + size 200 100 + children [ + Background2D { backColor 0 0 1 } + DEF DL DirectionalLight { color 0.8 0.2 0.2 direction 0 0 -1 } + USE NEF + ] + } + ] + } + + + DEF TS TimeSensor { cycleInterval 8.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [0 1 0 0, 0 1 0 3.14, 0 1 0 6.26] + } + DEF OI_L PositionInterpolator { + key [0 0.25 0.5 0.75 1] + keyValue [-1 0 0, 0 0 -1, 1 0 0, 0 0 -1, -1 0 0] + } + ] +} + +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation + +ROUTE TS.fraction_changed TO OI_L.set_fraction +ROUTE OI_L.value_changed TO DL.direction + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 10 + OCR_ES_ID 10 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 20 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.png" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-positioning-layer3D.bt b/regression_tests/bifs/bifs-3D-positioning-layer3D.bt new file mode 100644 index 0000000..dbf640e --- /dev/null +++ b/regression_tests/bifs/bifs-3D-positioning-layer3D.bt @@ -0,0 +1,186 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + + Background2D {url "./../auxiliary_files/sky.jpg" } + + WorldInfo { + title "Layer3D test" + info ["This shows a Layer3D using the entire window" "and layer2D/layer3D defining a 2D control panel" "" "GPAC Regression Tests" "$Date: 2008-11-24 14:58:25 $ - $Revision: 1.5 $" "(C) 2002-2004 GPAC Team"] + } + + Switch { + whichChoice 0 + choice [ + Layer3D { + size 400 200 + navigationInfo DEF NAV NavigationInfo {type ["Walk","ANY"] } + children [ + DEF BACK Background {frontUrl "./../auxiliary_files/logo.png" } + Inline {url "./../auxiliary_files/nefertiti.wrl"} + ] + } + ] + } + Layer2D { + size -1 -1 + children [ + Transform2D { + translation 0 100 + children [ + Shape { + appearance DEF TXTAPP Appearance {material Material2D { emissiveColor 0 0 0 filled TRUE } } + geometry Text { + string ["This is a Layer3D displaying" "an inline scene with a Layer2D interface"] + fontStyle DEF FS FontStyle { + size 18 + justify ["MIDDLE", "BEGIN"] + } + } + } + ] + } + Transform2D { + translation -150 -60 + children [ + Shape { + appearance Appearance { material DEF MAT_NAV Material2D {filled TRUE emissiveColor 1 0 0} } + geometry Rectangle { size 20 20 } + } + DEF TS_NAV TouchSensor {} + Transform2D { + scale 0.8 0.8 + translation 0 -20 + children [ + Shape { + appearance USE TXTAPP + geometry DEF TXT_NAV Text { + string ["Walk"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 150 -60 + children [ + Layer3D { + size 40 40 + navigationInfo NavigationInfo {type ["Examine"] } + viewpoint Viewpoint {position 0 0 40} + children [ + Background2D {backColor 1 0 0} + DEF TR Transform { + children [ + Shape { + appearance Appearance { +# material Material { emissiveColor 0 1 0} + texture ImageTexture { url './../auxiliary_files/logo.jpg"} + } + geometry Box { size 20 20 20} + } + DEF TS_BACK TouchSensor {} + ] + } + ] + } + Transform2D { + scale 0.8 0.8 + translation 0 -20 + children [ + Shape { + appearance USE TXTAPP + geometry DEF TXT_BACK Text { + string ["Background Off"] + fontStyle USE FS + } + } + ] + } + ] + } + ] + } + DEF SC Script { + eventIn SFBool set_nav + eventIn SFBool set_back + field SFNode the_nav USE NAV + field SFNode the_back USE BACK + field SFNode navmat USE MAT_NAV + field SFNode navtxt USE TXT_NAV + field SFNode backtxt USE TXT_BACK + url "javascript: + function initialize(value) { + nav_set = 0; + back_set = 0; + } + function set_nav(value) { + if (!value) return; + if (nav_set) { + nav_set = 0; + navmat.emissiveColor = new SFColor(1, 0, 0); + navtxt.string[0] = 'Walk'; + the_nav.type[0] = 'Walk'; + } else { + navmat.emissiveColor = new SFColor(0, 1, 0); + navtxt.string[0] = 'Examine'; + the_nav.type[0] = 'Examine'; + nav_set = 1; + } + } + function set_back(value) { + if (!value) return; + if (back_set) { + the_back.set_bind = false; + backtxt.string[0] = 'Background Off'; + back_set = 0; + } else { + backtxt.string[0] = 'Background On'; + the_back.set_bind = true; + back_set = 1; + } + } + " + } + + DEF TIME TimeSensor { cycleInterval 2.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + ] +} + + +ROUTE TS_NAV.isActive TO SC.set_nav +ROUTE TS_BACK.isActive TO SC.set_back +ROUTE TIME.fraction_changed TO OI.set_fraction +#ROUTE OI.value_changed TO TR.rotation + + +AT 100 { REPLACE BACK.set_bind BY 0 } diff --git a/regression_tests/bifs/bifs-3D-positioning-lod.bt b/regression_tests/bifs/bifs-3D-positioning-lod.bt new file mode 100644 index 0000000..c0b89a4 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-positioning-lod.bt @@ -0,0 +1,63 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + DirectionalLight { + color 1 1 1 + } + WorldInfo { + title "LOD test" + info ["This shows LOD with 2 level of details" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + LOD { + range [ 4 ] + center 0 0 0 + level [ + Shape { + appearance Appearance { + material Material { + diffuseColor 1 0 0 + } + } + geometry Sphere { radius 1 } + } + Shape { + appearance Appearance { + material Material { + diffuseColor 0 1 0 + } + } + geometry Box { size 1 1 1 } + } + ] + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-positioning-transform.bt b/regression_tests/bifs/bifs-3D-positioning-transform.bt new file mode 100644 index 0000000..16bc8e2 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-positioning-transform.bt @@ -0,0 +1,64 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "Transform test" + info ["This shows 3D transform on a box" "using DEF/USE and oriented scaling" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + DEF TR Transform { + translation -50 0 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 1 1 0 + } + } + geometry Box {size 50 50 50} + } + ] + } + DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + Transform { + translation 100 0 0 + scale 0.5 0.5 1 + scaleOrientation 1 0 0 0.2 + children [ + USE TR + ] + + } + ] +} + +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation diff --git a/regression_tests/bifs/bifs-3D-shapes-box-transparent.bt b/regression_tests/bifs/bifs-3D-shapes-box-transparent.bt new file mode 100644 index 0000000..b7388f2 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-box-transparent.bt @@ -0,0 +1,118 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0x01 + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0x01 + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric TRUE + pixelWidth 300 + pixelHeight 200 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + Background2D {backColor 1 1 1} + WorldInfo { + title "Bitmap Test" + info ["This shows dragable bitmap with outscale" "with movieTexture in Meter Metrics" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + + DEF TR Transform { + children [ + Shape { + appearance Appearance { + material DEF MAT Material{} + texture ImageTexture { url 5} + } + geometry Box {size 50 50 50} + } + ] + } + + Transform2D { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + texture MovieTexture { + url 10 + loop TRUE + } + } + geometry Bitmap {scale 2 2} + } + DEF PS PlaneSensor2D { + maxPosition 200 200 + minPosition -200 -200 + } + ] + } + ] + } + DEF TS TimeSensor { cycleInterval 10.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.25 0.5 0.75 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26, 1 1 1 3.14, 1 1 1 6.26] + } + DEF PI PositionInterpolator { + key [0 0.25 0.5 0.75 1] + keyValue [-180 120 0, 180 120 0, 180 -120 0, -180 -120 0, -180 120 0] + } + ] +} + +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation +ROUTE TS.fraction_changed TO PI.set_fraction +ROUTE PI.value_changed TO TR.translation +ROUTE TS.fraction_changed TO MAT.transparency + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 10 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-shapes-box.bt b/regression_tests/bifs/bifs-3D-shapes-box.bt new file mode 100644 index 0000000..bf63809 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-box.bt @@ -0,0 +1,45 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Box test" + info ["This shows a box" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + rotation 1 1 1 1.57 + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Box {size 120 100 80} + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-3D-shapes-cone.bt b/regression_tests/bifs/bifs-3D-shapes-cone.bt new file mode 100644 index 0000000..edbed7a --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-cone.bt @@ -0,0 +1,58 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Cone test" + info ["This shows a cone" "with and without cap" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + translation -70 0 0 + rotation 1 0 0 4 + children [ + Shape { + appearance Appearance { + material Material {diffuseColor 1.0 0.0 0.0 } + } + geometry Cone {height 150 bottomRadius 25} + } + ] + } + Transform { + translation 70 0 0 + rotation 1 0 0 4 + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Cone {height 150 bottomRadius 25 bottom FALSE} + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-3D-shapes-cylinder.bt b/regression_tests/bifs/bifs-3D-shapes-cylinder.bt new file mode 100644 index 0000000..a1ed975 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-cylinder.bt @@ -0,0 +1,92 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 380 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Cylinder test" + info ["This shows a cylinder" "with and without cap and side" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + translation -100 100 0 + children [ + Shape { + appearance Appearance { + material Material {diffuseColor 1.0 0.0 0.0 } + } + geometry Cylinder {height 150 radius 25} + } + ] + } + Transform { + translation 0 100 0 + rotation 1 0 0 0.78 + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Cylinder {height 150 radius 25 top FALSE} + } + ] + } + Transform { + translation -100 -100 0 + rotation 1 0 0 -0.78 + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Cylinder {height 150 radius 25 bottom FALSE} + } + ] + } + Transform { + translation 0 -100 0 + rotation 1 0 0 1.2 + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Cylinder {height 150 radius 25 bottom FALSE top FALSE} + } + ] + } + Transform { + translation 100 0 0 + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Cylinder {height 150 radius 25 side FALSE } + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-3D-shapes-elevationgrid.bt b/regression_tests/bifs/bifs-3D-shapes-elevationgrid.bt new file mode 100644 index 0000000..0d6fe66 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-elevationgrid.bt @@ -0,0 +1,74 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +Group { + children [ + NavigationInfo {type ["ANY" "EXAMINE"]} + Background2D { backColor 1 0 1} + Viewpoint { position 0 0 300 } + WorldInfo { + title "ElevationGrid test" + info ["This shows an ElevationGrid" "with interaction and texturing" "" "GPAC Regression Tests" "$Date: 2008-06-26 07:55:39 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + Transform { + translation -100 0 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { diffuseColor 1 0 0 } + texture DEF TX ImageTexture {url "../auxiliary_files/logo.jpg"} + } + geometry ElevationGrid { + creaseAngle 2 + xSpacing 15 + zSpacing 8 + xDimension 12 + zDimension 11 + height [ 17, 14, 16, 12, 14, 21, 20, 11, 9, 16, 13, 13, + 22, 14, 17, 12, 15, 21, 17, 10, 14, 12, 19, 16, + 17, 11, 13, 11, 9, 13, 11, 11, 17, 9, 15, 11, + 9, 8, 6, 10, 7, 12, 15, 8, 11, 5, 7, 9, + 0, 0, 0, 0, 0, 5, 12, 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, + 6, 2, 0, -2, -6,-12,-11, -7, -2, 0, 1, 6, + 9, 3, -1, -4, -9,-15,-13,-11, -4, -1, 3, 9, + 11, 8, 1, -5,-11,-15,-11, -9, -7, -1, 5, 7, + 9, 8, -2,-10, -9, -9,-11,-13, -9, 1, 8, 6 ] + } + } + ] + } + DEF TS TouchSensor {} + DEF C1 Conditional { buffer { REPLACE MAT.diffuseColor BY 0 0 1} } + DEF RC1 Conditional { buffer { REPLACE MAT.diffuseColor BY 1 0 0} } + DEF C2 Conditional { buffer { REPLACE TX.url BY "./../auxiliary_files/logo.png"} } + DEF RC2 Conditional { buffer { REPLACE TX.url BY ""} } + ] +} + +ROUTE TS.isOver TO C1.activate +ROUTE TS.isOver TO RC1.reverseActivate +ROUTE TS.isActive TO C2.activate +ROUTE TS.isActive TO RC2.reverseActivate diff --git a/regression_tests/bifs/bifs-3D-shapes-extrusion.bt b/regression_tests/bifs/bifs-3D-shapes-extrusion.bt new file mode 100644 index 0000000..02d9f91 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-extrusion.bt @@ -0,0 +1,99 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +Group { + children [ + + Background2D { backColor 1 1 1} + DEF VIEWPOINT Viewpoint { + description "one" + position 0 0 10 + orientation 0 1 0 0 + } + WorldInfo { + title "Extrusion test" + info ["This shows an Extrusion" "with interaction and texturing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + + DEF TR Transform { + translation 0 -1 0 + children [ + Shape { + appearance Appearance {material Material {diffuseColor 1.0 0.8 0.0} texture DEF TX ImageTexture{} } + geometry Extrusion { + creaseAngle 1 + endCap FALSE + beginCap TRUE + solid FALSE + crossSection [ + # Circle + 1.00 0.00, 0.92 -0.38, + 0.71 -0.71, 0.38 -0.92, + 0.00 -1.00, -0.38 -0.92, + -0.71 -0.71, -0.92 -0.38, + -1.00 -0.00, -0.92 0.38, + -0.71 0.71, -0.38 0.92, + 0.00 1.00, 0.38 0.92, + 0.71 0.71, 0.92 0.38, + 1.00 0.00 + ] + spine [ + # Straight-line + 0.0 0.0 0.0, 0.0 0.4 0.0, + 0.0 0.8 0.0, 0.0 1.2 0.0, + 0.0 1.6 0.0, 0.0 2.0 0.0, + 0.0 2.4 0.0, 0.0 2.8 0.0, + 0.0 3.2 0.0, 0.0 3.6 0.0, + 0.0 4.0 0.0 + ] + scale [ + 1.8 1.8, 1.95 1.95, + 2.0 2.0, 1.95 1.95 + 1.8 1.8, 1.5 1.5 + 1.2 1.2, 1.05 1.05, + 1.0 1.0, 1.05 1.05, + 1.15 1.15, + ] + } + } + DEF TOUCH TouchSensor {} + ] + } + + DEF TS TimeSensor { cycleInterval 8.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + DEF C Conditional { buffer { REPLACE TX.url BY "./../auxiliary_files/logo.png"} } + DEF RC Conditional { buffer { REPLACE TX.url BY ""} } + ] +} + +ROUTE TOUCH.isActive TO C.activate +ROUTE TOUCH.isActive TO RC.reverseActivate + +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation diff --git a/regression_tests/bifs/bifs-3D-shapes-indexedfaceset.bt b/regression_tests/bifs/bifs-3D-shapes-indexedfaceset.bt new file mode 100644 index 0000000..1a02a75 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-indexedfaceset.bt @@ -0,0 +1,66 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "IndexedFaceSet test" + info ["This shows an IFS" "with and without colorPerVertex" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + translation -1.5 0 0 + children [ + Shape { + geometry IndexedFaceSet { + coord DEF COORD Coordinate { + point [-1 -1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1 -1 1 -1 -1 -1 -1 1 -1 -1] + } + coordIndex [0 1 2 3 -1 1 7 4 2 -1 7 6 5 4 -1 0 3 5 6 -1 3 2 4 5 -1 6 7 1 0 -1] + color DEF COL Color { + color [ 1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 0 1 1, 1 0.5 0.5, 0.5 0.5 1] + } + colorPerVertex TRUE + } + } + ] + } + Transform { + translation 1.5 0 0 + children [ + Shape { + geometry IndexedFaceSet { + coord USE COORD + coordIndex [0 1 2 3 -1 1 7 4 2 -1 7 6 5 4 -1 0 3 5 6 -1 3 2 4 5 -1 6 7 1 0 -1] + color USE COL + colorPerVertex FALSE + colorIndex [0 1 2 3 4 5 6 7] + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-shapes-indexedlineset.bt b/regression_tests/bifs/bifs-3D-shapes-indexedlineset.bt new file mode 100644 index 0000000..6b6eec5 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-indexedlineset.bt @@ -0,0 +1,99 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "IndexedLineSet test" + info ["This shows an ILS" "with and without color per vertex" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + translation -1.5 0 0 + children [ + Shape { + geometry IndexedLineSet { + coord DEF COORD Coordinate { + point [ + # the top of the cube + -1.0 1.0 1.0, + 1.0 1.0 1.0, + 1.0 1.0 -1.0, + -1.0 1.0 -1.0, + # around the bottom of the cube + -1.0 -1.0 1.0, + 1.0 -1.0 1.0, + 1.0 -1.0 -1.0, + -1.0 -1.0 -1.0 + ] + } + coordIndex [ + # top + 0, 1, 2, 3, 0, -1, + # bottom + 4, 5, 6, 7, 4, -1, + # vertical edges + 0, 4, -1, + 1, 5, -1, + 2, 6, -1, + 3, 7 + ] + color Color { + color [1 0 0, 0 1 0, 0 0 1, 1 1 0] + } + colorPerVertex TRUE + colorIndex [0, 1, 2, 3, 0, -1, 0, 1, 2, 3, 0, -1, 0, 3, -1, 0, 2, -1, 0, 1, -1, 1 3] + } + } + ] + } + Transform { + translation 1.5 0 0 + children [ + Shape { + geometry IndexedLineSet { + coord USE COORD + coordIndex [ + # top + 0, 1, 2, 3, 0, -1, + # bottom + 4, 5, 6, 7, 4, -1, + # vertical edges + 0, 4, -1, + 1, 5, -1, + 2, 6, -1, + 3, 7 + ] + color Color { + color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 0 1 1, 1 0 1] + } + colorPerVertex FALSE + colorIndex [0, 1, 2, 3, 4, 5] + } + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-3D-shapes-nonlineardeformer.bt b/regression_tests/bifs/bifs-3D-shapes-nonlineardeformer.bt new file mode 100644 index 0000000..2fa3559 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-nonlineardeformer.bt @@ -0,0 +1,796 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + + WorldInfo { + info ["This shows NonLinearDeformer" "in different modes and differnet axis." "Deformation is controled through the NLD.extend field" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "NonLinearDeformer Test" + } + Viewpoint { position 0 -1 10 } + NavigationInfo {type ["EXAMINE"]} + Transform { + translation -0.1337 -2.107 -1.839 + children [ + + Shape { + appearance Appearance { + material Material { + diffuseColor 0.9804 0.9804 0.9804 + } + } + geometry DEF NLD NonLinearDeformer { + type 0 + param 1 + axis 0 1 0 + extend [0 0.5 0.5 1 1 0.2] + geometry IndexedFaceSet { + ccw TRUE + solid FALSE + creaseAngle 2 + coord Coordinate { point [ + -2.116 1.757 -1.271, -2.036 1.587 -1.231, -2.136 1.607 -1.391, + -2.206 1.837 -1.361, -2.216 1.867 -1.161, -2.116 1.697 -1.111, + -2.066 1.457 -1.131, -1.946 1.607 -0.9606, -1.966 1.387 -1.011, + -2.076 1.337 -1.251, -2.096 1.397 -1.301, -2.396 1.687 -1.561, + -2.306 1.477 -1.521, -2.466 1.527 -1.711, -2.446 1.737 -1.651, + -2.396 1.877 -1.491, -2.326 1.217 -1.511, -2.186 1.437 -1.431, + -2.086 1.257 -1.391, -2.096 1.127 -1.411, -2.196 0.9375 -1.391, + -2.386 1.017 -1.521, -2.486 1.217 -1.691, -2.056 0.9875 -1.251, + -1.976 1.267 -1.141, -1.876 1.167 -1.121, -1.996 0.8775 -1.001, + -2.116 0.8775 -1.201, -1.946 1.267 -1.001, -1.916 1.297 -0.9206, + -1.966 1.197 -0.9206, -1.886 1.127 -0.9906, -1.946 1.287 -1.081, + -1.986 1.017 -0.8106, -1.926 1.127 -0.7606, -1.896 0.9375 -0.6006, + -1.976 0.7975 -0.6606, -1.926 0.9575 -0.9206, -2.136 0.7675 -0.8906, + -1.996 0.5875 -0.6606, -2.136 0.5575 -0.9806, -2.226 0.7575 -1.111, + -1.906 0.3475 -0.6006, -1.856 0.5175 -0.5106, -1.746 0.2775 -0.5806, + -1.906 0.2275 -0.7406, -2.036 0.3375 -0.9706, -2.046 0.4775 -0.7806, + -1.866 0.7975 -0.5406, -2.296 0.8575 -1.351, -2.196 0.6175 -1.211, + -2.236 0.6575 -1.421, -2.346 0.8575 -1.581, -2.386 0.9575 -1.541, + -2.116 0.4775 -1.171, -1.776 0.2875 -0.9306, -1.846 0.4775 -1.181, + -1.566 0.2275 -0.7506, -1.566 0.4375 -0.9906, -1.636 0.7175 -1.341, + -1.986 0.7375 -1.431, -1.756 1.027 -1.601, -2.136 1.097 -1.701, + -2.276 1.537 -1.751, -2.536 1.687 -1.771, -2.466 1.217 -1.751, + -1.966 1.377 -1.751, -2.076 1.717 -1.721, -2.316 1.877 -1.631, + -2.546 1.537 -1.741, -2.546 1.747 -1.671, -2.556 1.937 -1.611, + -2.536 1.897 -1.581, -2.206 1.947 -1.611, -2.326 2.037 -1.421, + -2.316 2.027 -1.231, -2.176 2.067 -1.291, -2.356 1.927 -1.331, + -2.186 1.907 -1.061, -1.976 1.957 -1.001, -2.106 1.857 -1.041, + -1.866 0.9475 -0.3906, -1.936 1.367 -0.2506, -1.946 1.297 -0.0005862, + -1.886 0.8775 0.4194, -1.806 0.4475 0.2294, -1.786 0.1875 0.1694, + -1.806 0.3175 -0.2706, -1.366 0.3575 -2.181, -1.406 0.05749 -1.281, + -1.556 -0.1525 -0.7106, -1.516 -0.6325 -1.151, -1.146 -0.6925 -1.741, + -1.086 -0.2125 -1.911, -1.786 -0.1825 0.03941, -1.766 -0.1525 -0.3606, + -1.706 -0.09251 0.3694, -1.706 -0.3625 0.2894, -1.616 -1.023 -0.1406, + -1.646 -0.8525 -0.4206, -1.576 -0.8825 -0.6006, -1.556 -1.053 -0.4206, + -1.346 -1.333 -0.3906, -1.486 -1.393 -0.9606, -0.7163 -0.6425 -2.381, + -1.036 -1.113 -2.021, -0.7363 -1.093 -2.401, -0.0763 -0.5625 -2.381, + -0.5963 -0.5225 -2.471, -0.5563 -0.4825 -2.571, -1.056 -0.03251 -2.361, + -0.0963 -1.093 -2.371, -0.1063 -1.473 -2.511, -0.7963 -1.483 -2.531, + -1.366 -1.963 -1.861, -1.386 -2.313 -2.071, -0.9363 -1.943 -2.681, + -0.7963 -1.913 -2.791, -0.8963 -3.243 -3.621, -1.706 -3.973 -3.811, + -0.9963 -4.103 -4.111, -0.2363 -4.093 -4.191, -0.2063 -3.353 -3.741, + -0.1663 -2.603 -3.231, -0.8963 -2.513 -3.141, -1.126 -2.563 -3.001, + -1.386 -3.223 -3.371, -0.1363 -2.063 -2.891, -1.826 -3.313 -2.851, + -2.236 -3.693 -2.581, -2.136 -3.713 -3.151, -1.536 -2.833 -2.451, + -1.946 -3.423 -2.331, -1.926 -3.633 -2.031, -1.956 -4.303 -1.764, + -2.226 -3.873 -2.171, -1.676 -3.073 -2.071, -1.666 -3.253 -1.851, + -1.696 -4.023 -1.671, -1.426 -4.363 -1.411, -1.276 -5.023 -1.261, + -1.666 -4.683 -1.501, -1.486 -3.683 -1.491, -1.246 -4.053 -1.211, + -1.216 -4.623 -1.281, -1.376 -3.073 -1.221, -1.476 -2.773 -1.491, + -1.406 -2.483 -1.201, -1.166 -2.893 -0.7706, -1.046 -3.473 -0.8406, + -1.526 -2.563 -1.731, -1.446 -2.233 -1.511, -0.8263 -5.193 -1.071, + -0.9163 -4.373 -1.001, -0.6763 -4.483 -1.001, -0.5263 -5.313 -1.121, + -0.3563 -5.333 -1.131, -0.3663 -4.643 -1.021, -0.1763 -4.753 -1.051, + -0.1963 -5.383 -1.131, -0.4363 -3.893 -0.7006, -0.8863 -3.613 -0.7806, + -0.4763 -3.393 -0.5006, -0.1263 -3.533 -0.5006, -0.1463 -4.033 -0.7306, + -1.456 -1.853 -1.241, -1.386 -1.483 -1.611, -1.486 -1.443 -1.231, + -1.316 -2.193 -0.8206, -0.5163 -2.813 -0.2806, -1.036 -3.023 -0.7006, + -1.196 -2.353 -0.6606, -0.8663 -2.103 -0.1806, -0.5563 -1.883 0.2294, + -0.0963 -2.933 -0.2106, -1.346 -1.533 -0.5406, -1.096 -1.573 -0.1606, + -0.0563 -1.943 0.3194, -0.0363 -1.683 0.7494, -0.5663 -1.643 0.5794, + -1.146 -1.393 0.3994, -1.516 -1.173 -0.2506, -1.286 -1.353 0.1994, + -1.386 -1.193 0.4494, -0.5363 -1.483 1.049, -0.9463 -1.283 1.249, + -0.5563 -1.473 1.399, -0.0063 -1.513 1.649, -1.566 -0.8925 0.3994, + -1.396 -0.7425 0.8494, -1.636 0.04749 0.7194, -1.476 -0.1825 0.9894, + -1.296 -0.3925 1.199, -1.146 -0.7725 1.289, -0.9763 -1.073 1.419, + -0.6263 -1.363 1.779, -0.2763 -1.483 1.829, -0.7363 -1.173 1.769, + -0.5263 -1.183 2.009, -0.3963 -1.373 1.969, 0.0137 -1.353 2.069, + -0.3563 -1.223 2.149, -0.3663 -0.9425 2.139, 0.0237 -1.013 2.219, + 0.0237 -1.233 2.209, -0.9063 -0.8825 1.549, -0.9963 -0.5625 1.519, + -0.7563 -0.6625 1.699, -0.6463 -0.8825 1.859, -1.736 0.2775 0.4994, + -1.846 0.8575 0.7094, -1.696 0.3575 0.8394, -1.576 0.3675 1.109, + -1.386 -0.1125 1.169, -1.756 0.8475 1.009, -1.536 0.8375 1.299, + -1.326 0.4575 1.419, -1.056 0.08749 1.569, -1.106 0.6175 1.629, + -0.8663 0.3575 1.769, -0.8263 0.05749 1.839, -1.026 -0.2525 1.579, + -0.2263 -0.6525 2.109, -0.3863 -0.6325 2.069, -0.2463 -0.5525 2.179, + 0.0337 -0.6925 2.129, -0.4063 -0.5325 2.129, -0.4963 -0.4525 2.019, + -0.4163 -0.3925 2.099, -0.2663 -0.4225 2.199, -0.0963 -0.4525 2.209, + 0.0437 -0.5625 2.209, -0.1563 -0.2725 2.139, 0.0537 -0.3125 2.179, + 0.0437 -0.4525 2.229, -0.5263 -0.5725 1.919, -0.7363 -0.3125 1.709, + -0.5263 0.02749 1.999, -0.4263 -0.08251 2.099, -0.4263 -0.1925 2.079, + -0.4063 -0.2825 2.039, -0.2963 -0.2825 2.109, -0.3363 -0.1525 2.159, + -0.0563 -0.1425 2.299, -0.1863 -0.1425 2.229, -0.1263 0.02749 2.299, + 0.0637 -0.002507 2.319, 0.0537 -0.1425 2.299, -0.3363 -0.04251 2.209, + -0.0863 0.1175 2.279, -0.2563 0.4275 2.069, -0.0263 0.3575 2.229, + 0.0737 0.3275 2.229, 0.0637 0.1175 2.259, -0.6963 0.1875 1.899, + -0.4263 0.4675 1.969, -0.0763 0.6175 2.109, -0.3663 0.5675 2.149, + -0.2263 0.6175 2.279, -0.0963 0.5975 2.359, -0.0163 0.5075 2.409, + -0.4363 0.6075 2.049, -0.4963 0.6675 1.899, -0.3963 0.7375 2.139, + -0.2663 0.6775 2.319, -0.0963 0.6675 2.489, -0.1363 0.8275 2.439, + -0.0063 0.8675 2.529, 0.0937 0.7575 2.569, 0.0837 0.4875 2.439, + -1.306 0.8475 1.509, -1.456 1.227 1.339, -1.206 1.167 1.509, + -0.9263 0.8775 1.709, -0.8763 1.187 1.649, -1.126 1.447 1.479, + -0.8663 1.457 1.549, -0.5663 1.487 1.569, -0.4163 1.357 1.749, + -0.5063 1.017 1.849, -0.2963 0.9775 1.999, -0.2063 0.9075 2.229, + -0.0763 1.177 2.229, -0.3263 1.697 1.629, -0.0663 2.097 1.749, + 0.1037 1.417 2.229, 0.1237 2.127 1.839, -1.386 1.727 1.249, + -1.466 1.567 1.219, -1.646 1.747 0.9494, -1.346 1.887 1.359, + -1.296 1.767 1.359, -1.206 1.647 1.409, -1.096 1.607 1.479, + -1.146 1.707 1.479, -0.9963 1.697 1.529, -0.8663 1.597 1.529, + -0.6463 1.607 1.549, -0.7663 1.707 1.549, -0.5263 1.727 1.479, + -0.4563 1.667 1.539, -0.5063 1.947 1.539, -0.3563 2.047 1.509, + -1.646 1.277 1.149, -1.816 1.417 0.8194, -1.906 1.207 0.5394, + -1.906 1.537 0.2594, -1.836 1.747 0.4994, -1.806 1.717 0.7294, + -1.436 2.037 1.149, -1.716 1.877 0.8394, -1.596 2.197 1.099, + -1.186 2.287 1.359, -1.786 2.037 0.7494, -1.886 1.877 0.009414, + -1.796 2.277 0.4294, -1.656 2.317 1.039, -0.9863 2.337 1.459, + -0.8663 2.057 1.589, -1.086 2.037 1.549, -0.9963 2.527 1.529, + -0.6863 2.507 1.579, -0.7163 2.307 1.479, -0.4863 2.207 1.479, + -0.3563 2.367 1.649, -0.3163 2.517 1.709, -0.6463 2.677 1.629, + -0.5563 2.997 1.479, -0.1163 2.867 1.549, -1.036 2.737 1.529, + -1.326 2.467 1.369, -1.386 2.627 1.359, -1.026 3.027 1.369, + 0.1337 2.747 1.589, 0.1437 3.517 1.219, -0.3963 3.517 1.239, + -1.026 3.427 1.129, -1.436 3.257 0.9294, -1.386 2.897 1.179, + -1.696 2.607 0.7894, -1.836 2.567 0.06941, -1.706 2.937 0.5194, + -1.916 2.047 -0.7406, 1.934 0.7375 0.6094, 1.854 0.7275 0.9194, + 1.944 1.297 0.7194, 2.004 1.917 -0.8406, 2.044 1.827 -1.101, + 1.994 1.477 -1.061, 2.004 1.237 -0.3506, 2.004 1.747 -0.09059, + 2.024 1.167 -0.1006, 2.014 1.407 0.1594, 1.964 1.627 0.3994, + 1.964 2.157 0.3294, 1.994 2.447 -0.03059, 1.694 3.157 0.8494, + 1.914 2.817 0.4294, 1.634 2.797 1.099, 1.624 2.527 1.279, + 1.904 2.487 0.6994, 1.854 2.207 0.9494, 1.284 2.957 1.309, + 1.304 3.357 1.069, 0.6837 3.487 1.209, 0.8237 2.957 1.439, + 0.3837 2.847 1.539, 1.554 2.377 1.299, 1.794 2.087 1.009, + 1.404 2.207 1.289, 1.624 1.937 1.069, 1.234 2.457 1.469, + 0.9037 2.627 1.589, 1.284 2.667 1.469, 0.9237 2.457 1.539, + 0.5937 2.337 1.629, 0.2937 2.087 1.739, 0.5637 2.487 1.689, + 0.5637 2.017 1.489, 1.294 1.957 1.489, 1.534 1.797 1.289, + 0.7137 1.907 1.509, 0.7037 2.167 1.449, 0.9437 2.257 1.439, + 1.074 1.997 1.539, 1.214 2.267 1.399, 1.874 1.757 0.7494, + 1.954 1.917 0.6494, 1.944 1.597 0.6294, 1.804 1.637 0.8594, + 2.004 1.077 0.4394, 1.954 0.7575 0.3194, 0.7437 1.447 1.539, + 0.5937 1.327 1.719, 0.6437 1.627 1.509, 1.624 1.467 1.139, + 1.294 1.367 1.419, 1.384 1.567 1.339, 1.784 1.167 1.059, + 1.654 0.7375 1.219, 1.604 1.127 1.259, 1.354 1.087 1.439, + 0.5137 1.667 1.609, 0.7137 1.687 1.449, 0.9537 1.647 1.509, + 1.184 1.627 1.469, 1.044 1.537 1.479, 1.334 1.627 1.419, + 1.474 1.677 1.289, 0.8237 1.557 1.509, 1.034 1.397 1.499, + 1.274 1.527 1.419, 1.554 1.637 1.169, 1.754 0.2475 0.7494, + 0.6637 0.9775 1.819, 0.4637 0.9575 1.979, 0.1937 0.8575 2.519, + 0.3137 0.8175 2.429, 0.2637 1.167 2.219, 0.3837 0.8875 2.209, + 0.4337 0.6575 2.299, 0.5537 0.7075 2.119, 0.6337 0.6275 1.869, + 1.064 0.8175 1.659, 0.9737 0.2975 1.719, 1.224 0.5375 1.569, + 0.5537 0.4375 1.939, 1.034 1.127 1.599, 1.434 0.7575 1.439, + 1.424 0.3675 1.349, 0.1737 0.4975 2.409, 0.2637 0.6575 2.479, + 0.1637 0.3475 2.229, 0.3837 0.5975 2.259, 0.2537 0.5875 2.349, + 0.5137 0.5375 2.129, 0.3937 0.4075 2.049, 0.5837 0.5775 2.019, + 0.2237 0.6075 2.099, 0.6337 -0.01251 1.969, 0.8037 0.1375 1.859, + 0.9237 -0.002507 1.789, 0.2437 0.01749 2.289, 0.2137 0.1075 2.269, + 0.4437 -0.07251 2.189, 0.2537 -0.2825 2.129, 0.2937 -0.1625 2.219, + 0.4337 -0.1725 2.139, 0.5237 -0.2225 2.059, 0.5237 -0.1125 2.079, + 0.1637 -0.1525 2.289, 0.3537 -0.4425 2.179, 0.3837 -0.3025 2.089, + 0.4937 -0.3125 2.019, 0.4937 -0.4225 2.079, 0.8037 -0.7125 1.659, + 0.5837 -0.6125 1.889, 0.8037 -0.3625 1.669, 0.5737 -0.4825 1.989, + 1.084 -0.3225 1.529, 1.034 -0.6325 1.469, 0.6837 -0.9225 1.829, + 0.4137 -0.9725 2.119, 0.4537 -0.6625 2.049, 0.3237 -0.5725 2.169, + 0.1837 -0.4625 2.199, 0.4837 -0.5625 2.109, 0.2937 -0.6725 2.099, + 1.324 -0.4725 1.129, 1.164 -0.8425 1.229, 1.514 -0.2825 0.9094, + 1.434 -0.2025 1.099, 1.674 -0.06251 0.6294, 1.144 0.01749 1.509, + 1.654 0.2675 1.029, 1.774 0.1675 0.4094, 1.844 0.3275 0.1394, + 1.804 0.06749 0.07941, 1.714 -0.2025 0.2794, 0.7537 -1.223 1.729, + 0.5537 -1.213 1.979, 0.9737 -1.133 1.369, 0.9237 -0.9425 1.499, + 0.9237 -1.343 1.199, 0.4037 -1.403 1.949, 0.2737 -1.503 1.819, + 0.5337 -1.513 1.369, 0.3837 -1.243 2.129, 0.6237 -1.403 1.749, + 1.694 -0.4725 0.1994, 1.524 -0.9925 0.3194, 1.384 -0.8325 0.7794, + 1.324 -1.283 0.3794, 1.074 -1.463 0.3394, 1.534 -1.123 -0.2206, + 1.564 -0.9525 -0.5006, 1.464 -1.153 -0.5006, 0.4937 -1.513 1.019, + 0.4837 -1.673 0.5494, 1.424 -1.263 -0.3306, 1.204 -1.433 0.1394, + 1.234 -1.413 -0.4606, 0.9837 -1.643 -0.2106, 0.4437 -1.913 0.1994, + 0.2337 -3.413 -0.5206, 0.7137 -2.153 -0.2206, 1.004 -2.423 -0.7206, + 1.124 -2.273 -0.8806, 1.214 -1.613 -0.6106, 1.344 -1.483 -1.031, + 0.7737 -3.533 -0.8906, 0.6137 -3.663 -0.8206, 0.9337 -2.963 -0.8206, + 0.8037 -3.083 -0.7506, 1.184 -2.563 -1.271, 0.3237 -2.843 -0.3006, + 0.8537 -1.173 -2.071, 1.204 -1.563 -1.681, 1.004 -0.7625 -1.801, + 1.414 -0.7225 -1.231, 1.324 -1.533 -1.301, 1.144 -2.043 -1.931, + 1.224 -2.323 -1.581, 1.264 -1.943 -1.311, 1.214 -2.863 -1.561, + 0.9137 -4.123 -1.271, 0.5837 -4.423 -1.041, 0.3337 -4.513 -1.031, + 0.1437 -3.913 -0.7206, 0.0137 -4.653 -1.031, -0.0463 -5.343 -1.141, + 0.1237 -5.333 -1.141, 0.4337 -5.233 -1.101, 0.8437 -4.693 -1.331, + 0.8837 -5.093 -1.321, 1.344 -4.123 -1.751, 1.584 -4.413 -1.854, + 1.284 -4.773 -1.581, 1.164 -3.773 -1.561, 1.354 -3.353 -1.931, + 1.264 -2.653 -1.801, 1.124 -2.393 -2.141, 1.364 -3.173 -2.151, + 1.114 -3.153 -1.281, 1.064 -4.443 -1.471, 1.004 -3.303 -3.431, + 1.244 -4.073 -3.891, 1.724 -3.833 -3.251, 1.854 -3.823 -2.691, + 1.854 -4.003 -2.281, 1.594 -3.533 -2.421, 1.224 -2.923 -2.521, + 0.6737 -1.993 -2.721, 0.8037 -2.623 -3.051, 1.584 -3.743 -2.121, + 1.464 -3.423 -2.941, 0.5237 -1.953 -2.821, 0.5737 -2.563 -3.181, + 0.4937 -3.283 -3.661, 0.5137 -4.153 -4.151, 0.5437 -1.133 -2.431, + 0.5637 -1.523 -2.571, 0.4337 -0.5525 -2.501, 0.3937 -0.5125 -2.591, + 1.274 0.2775 -2.251, 0.9237 -0.09251 -2.411, 0.9737 -0.2825 -1.961, + 0.5537 -0.6825 -2.411, 1.734 -0.2625 -0.4506, 1.504 -0.2525 -0.7906, + 1.484 -0.9825 -0.6806, 1.724 0.1675 -0.6706, 1.774 -0.2925 -0.05059, + 1.804 0.1975 -0.3606, 1.534 0.1275 -0.8306, 1.854 0.3975 -0.6106, + 1.884 0.6775 -0.6406, 1.534 0.3375 -1.071, 1.334 -0.03251 -1.351, + 1.604 0.6175 -1.421, 1.734 0.9175 -1.691, 1.944 1.177 -1.021, + 1.954 1.007 -0.8606, 1.904 0.8275 -0.4906, 1.924 0.8175 -0.7006, + 1.994 1.257 -1.111, 2.164 1.557 -1.221, 2.164 1.717 -1.151, + 2.234 1.927 -1.401, 2.244 1.767 -1.181, 2.374 1.877 -1.351, + 2.264 1.727 -1.281, 2.404 1.777 -1.451, 2.564 1.737 -1.711, + 2.434 1.717 -1.621, 2.244 1.697 -1.481, 2.464 1.577 -1.781, + 2.564 1.587 -1.801, 2.374 1.887 -1.541, 2.244 1.807 -1.731, + 2.094 1.587 -1.831, 2.344 1.727 -1.751, 2.584 1.767 -1.741, + 2.544 1.527 -1.901, 2.114 0.9575 -1.811, 2.314 0.7075 -1.701, + 2.444 1.057 -1.881, 2.314 1.327 -1.641, 2.464 1.367 -1.841, + 2.464 1.057 -1.821, 2.364 0.8675 -1.641, 2.364 0.8075 -1.661, + 2.544 1.377 -1.871, 1.954 1.247 -1.851, 2.274 1.387 -1.871, + 1.954 0.6075 -1.531, 1.814 0.3575 -1.271, 2.194 0.5175 -1.541, + 1.744 0.1775 -1.021, 1.874 0.1075 -0.8406, 2.004 0.2075 -1.071, + 2.084 0.3375 -1.281, 2.114 0.4175 -1.091, 2.164 0.4775 -1.321, + 2.214 0.6175 -1.231, 2.034 0.3475 -0.8906, 1.994 0.4575 -0.7606, + 2.274 0.7075 -1.471, 2.104 0.7375 -1.311, 2.174 0.7975 -1.501, + 1.984 0.6675 -0.7606, 1.894 0.2275 -0.7006, 1.994 0.7475 -1.101, + 1.934 0.8375 -1.021, 1.884 1.047 -1.221, 1.904 1.007 -1.091, + 2.134 0.6275 -1.001, 1.994 1.067 -1.021, 2.004 0.8875 -0.9106, + 2.094 1.207 -1.361, 1.964 1.157 -1.181, 1.994 1.137 -1.241, + 1.974 1.137 -1.101, 2.114 1.257 -1.411, 2.084 1.127 -1.501, + 2.044 0.8575 -1.361, 2.084 0.9975 -1.521, 2.194 1.297 -1.541, + 2.164 1.467 -1.501, 2.064 1.457 -1.341, 2.314 1.067 -1.631, + 2.414 1.537 -1.681, 2.094 1.327 -1.241, 2.154 1.617 -1.381] + } + coordIndex [ + 1, 0, 2, -1, + 2, 0, 3, -1, 3, 0, 4, -1, 4, 0, 5, -1, 5, 0, 1, -1, + 5, 6, 7, -1, 7, 6, 8, -1, 8, 6, 9, -1, 9, 6, 10, -1, + 10, 6, 1, -1, 1, 6, 5, -1, 3, 11, 2, -1, 2, 11, 12, -1, + 12, 11, 13, -1, 13, 11, 14, -1, 14, 11, 15, -1, 15, 11, 3, -1, + 12, 16, 17, -1, 17, 16, 10, -1, 10, 16, 18, -1, 18, 16, 19, -1, + 19, 16, 20, -1, 20, 16, 21, -1, 21, 16, 22, -1, 22, 16, 12, -1, + 1, 2, 10, -1, 17, 10, 2, -1, 17, 2, 12, -1, 9, 23, 24, -1, + 24, 23, 25, -1, 25, 23, 26, -1, 26, 23, 27, -1, 27, 23, 20, -1, + 20, 23, 19, -1, 19, 23, 18, -1, 18, 23, 9, -1, 18, 9, 10, -1, + 8, 28, 29, -1, 29, 28, 30, -1, 30, 28, 31, -1, 31, 28, 25, -1, + 25, 28, 32, -1, 32, 28, 8, -1, 25, 32, 24, -1, 24, 32, 9, -1, + 9, 32, 8, -1, 31, 33, 30, -1, 30, 33, 34, -1, 34, 33, 35, -1, + 35, 33, 36, -1, 36, 33, 37, -1, 37, 33, 31, -1, 30, 34, 29, -1, + 26, 38, 36, -1, 36, 38, 39, -1, 39, 38, 40, -1, 40, 38, 41, -1, + 41, 38, 26, -1, 36, 37, 26, -1, 31, 25, 37, -1, 37, 25, 26, -1, + 26, 27, 41, -1, 39, 42, 43, -1, 43, 42, 44, -1, 44, 42, 45, -1, + 45, 42, 46, -1, 46, 42, 47, -1, 47, 42, 39, -1, 43, 48, 39, -1, + 36, 39, 48, -1, 36, 48, 35, -1, 21, 49, 20, -1, 20, 49, 27, -1, + 27, 49, 41, -1, 41, 49, 50, -1, 50, 49, 51, -1, 51, 49, 52, -1, + 52, 49, 53, -1, 53, 49, 21, -1, 39, 40, 47, -1, 47, 40, 46, -1, + 40, 41, 50, -1, 51, 54, 50, -1, 50, 54, 40, -1, 40, 54, 46, -1, + 46, 54, 55, -1, 55, 54, 56, -1, 56, 54, 51, -1, 45, 46, 55, -1, + 45, 55, 57, -1, 45, 57, 44, -1, 57, 55, 58, -1, 56, 58, 55, -1, + 58, 56, 59, -1, 61, 60, 62, -1, 62, 60, 52, -1, 52, 60, 51, -1, + 51, 60, 56, -1, 56, 60, 59, -1, 59, 60, 61, -1, 64, 63, 65, -1, + 65, 63, 62, -1, 62, 63, 66, -1, 66, 63, 67, -1, 67, 63, 68, -1, + 68, 63, 64, -1, 66, 62, 61, -1, 14, 69, 13, -1, 13, 69, 22, -1, + 22, 69, 65, -1, 65, 69, 64, -1, 64, 69, 70, -1, 70, 69, 14, -1, + 52, 53, 65, -1, 53, 21, 65, -1, 22, 65, 21, -1, 13, 22, 12, -1, + 52, 65, 62, -1, 72, 71, 70, -1, 70, 71, 64, -1, 64, 71, 68, -1, + 68, 71, 73, -1, 73, 71, 74, -1, 74, 71, 75, -1, 75, 71, 72, -1, + 68, 73, 67, -1, 76, 73, 74, -1, 76, 74, 75, -1, 70, 14, 72, -1, + 72, 14, 15, -1, 4, 77, 3, -1, 3, 77, 15, -1, 15, 77, 72, -1, + 72, 77, 75, -1, 75, 77, 4, -1, 79, 78, 80, -1, 80, 78, 5, -1, + 5, 78, 4, -1, 4, 78, 75, -1, 75, 78, 76, -1, 76, 78, 79, -1, + 7, 79, 80, -1, 7, 80, 5, -1, 8, 29, 7, -1, 29, 81, 7, -1, + 7, 81, 82, -1, 82, 81, 83, -1, 83, 81, 84, -1, 84, 81, 85, -1, + 85, 81, 86, -1, 86, 81, 87, -1, 87, 81, 48, -1, 48, 81, 35, -1, + 35, 81, 34, -1, 34, 81, 29, -1, 61, 88, 59, -1, 58, 59, 88, -1, + 58, 89, 57, -1, 57, 89, 90, -1, 90, 89, 91, -1, 91, 89, 92, -1, + 92, 89, 93, -1, 93, 89, 88, -1, 88, 89, 58, -1, 87, 48, 43, -1, + 87, 43, 44, -1, 90, 44, 57, -1, 95, 94, 44, -1, 44, 94, 87, -1, + 87, 94, 86, -1, 86, 94, 96, -1, 96, 94, 97, -1, 97, 94, 98, -1, + 98, 94, 99, -1, 99, 94, 95, -1, 95, 44, 90, -1, 91, 100, 90, -1, + 90, 100, 99, -1, 99, 100, 101, -1, 101, 100, 102, -1, + 102, 100, 103, -1, 103, 100, 91, -1, 90, 99, 95, -1, + 93, 104, 92, -1, 92, 104, 105, -1, 105, 104, 106, -1, + 106, 104, 107, -1, 107, 104, 108, -1, 108, 104, 93, -1, + 109, 108, 110, -1, 93, 110, 108, -1, 110, 93, 88, -1, + 108, 109, 107, -1, 106, 111, 112, -1, 106, 113, 105, -1, + 105, 113, 114, -1, 114, 113, 115, -1, 115, 113, 116, -1, + 116, 113, 117, -1, 117, 113, 112, -1, 112, 113, 106, -1, + 111, 106, 107, -1, 119, 118, 120, -1, 120, 118, 121, -1, + 121, 118, 122, -1, 122, 118, 123, -1, 123, 118, 124, -1, + 124, 118, 125, -1, 125, 118, 126, -1, 126, 118, 119, -1, + 125, 116, 117, -1, 125, 117, 124, -1, 123, 124, 117, -1, + 123, 117, 127, -1, 112, 127, 117, -1, 129, 128, 130, -1, + 130, 128, 126, -1, 126, 128, 125, -1, 125, 128, 131, -1, + 131, 128, 132, -1, 132, 128, 129, -1, 134, 133, 135, -1, + 135, 133, 132, -1, 132, 133, 136, -1, 136, 133, 137, -1, + 137, 133, 138, -1, 138, 133, 134, -1, 131, 116, 125, -1, + 115, 116, 131, -1, 115, 131, 136, -1, 132, 136, 131, -1, + 135, 132, 129, -1, 119, 130, 126, -1, 140, 139, 141, -1, + 141, 139, 138, -1, 138, 139, 142, -1, 142, 139, 143, -1, + 143, 139, 144, -1, 144, 139, 140, -1, 143, 145, 142, -1, + 142, 145, 146, -1, 146, 145, 147, -1, 147, 145, 148, -1, + 148, 145, 149, -1, 149, 145, 143, -1, 146, 150, 137, -1, + 137, 150, 136, -1, 136, 150, 115, -1, 115, 150, 114, -1, + 114, 150, 151, -1, 151, 150, 146, -1, 138, 142, 137, -1, + 146, 137, 142, -1, 134, 141, 138, -1, 140, 152, 144, -1, + 143, 144, 152, -1, 143, 152, 153, -1, 154, 153, 152, -1, + 154, 152, 155, -1, 154, 155, 156, -1, 154, 156, 157, -1, + 158, 157, 156, -1, 158, 156, 159, -1, 158, 160, 157, -1, + 157, 160, 154, -1, 154, 160, 161, -1, 161, 160, 162, -1, + 162, 160, 163, -1, 163, 160, 164, -1, 164, 160, 158, -1, + 153, 154, 161, -1, 153, 161, 149, -1, 153, 149, 143, -1, + 146, 147, 151, -1, 151, 165, 166, -1, 166, 165, 167, -1, + 167, 165, 103, -1, 103, 165, 168, -1, 168, 165, 147, -1, + 147, 165, 151, -1, 151, 166, 114, -1, 105, 114, 166, -1, + 103, 91, 167, -1, 166, 167, 91, -1, 166, 91, 92, -1, + 166, 92, 105, -1, 162, 169, 170, -1, 170, 169, 171, -1, + 171, 169, 172, -1, 172, 169, 173, -1, 173, 169, 174, -1, + 174, 169, 162, -1, 148, 170, 171, -1, 148, 171, 168, -1, + 148, 168, 147, -1, 162, 170, 161, -1, 148, 161, 170, -1, + 161, 148, 149, -1, 176, 175, 168, -1, 168, 175, 103, -1, + 103, 175, 102, -1, 102, 175, 176, -1, 168, 171, 176, -1, + 172, 176, 171, -1, 176, 172, 173, -1, 163, 174, 162, -1, + 177, 173, 174, -1, 173, 177, 178, -1, 173, 178, 179, -1, + 173, 179, 180, -1, 173, 180, 176, -1, 101, 102, 181, -1, + 101, 181, 98, -1, 98, 182, 183, -1, 183, 182, 180, -1, + 180, 182, 176, -1, 176, 182, 102, -1, 102, 182, 181, -1, + 181, 182, 98, -1, 178, 184, 179, -1, 179, 184, 180, -1, + 180, 184, 185, -1, 185, 184, 186, -1, 186, 184, 187, -1, + 187, 184, 178, -1, 101, 98, 99, -1, 183, 188, 98, -1, + 98, 188, 97, -1, 183, 180, 185, -1, 97, 189, 96, -1, + 96, 189, 190, -1, 190, 189, 191, -1, 191, 189, 192, -1, + 192, 189, 193, -1, 193, 189, 194, -1, 194, 189, 185, -1, + 185, 189, 183, -1, 183, 189, 188, -1, 188, 189, 97, -1, + 196, 195, 186, -1, 186, 195, 185, -1, 185, 195, 197, -1, + 197, 195, 198, -1, 198, 195, 199, -1, 199, 195, 196, -1, + 196, 187, 200, -1, 200, 201, 199, -1, 199, 201, 198, -1, + 198, 201, 202, -1, 202, 201, 203, -1, 203, 201, 204, -1, + 204, 201, 200, -1, 187, 196, 186, -1, 196, 200, 199, -1, + 185, 197, 194, -1, 194, 205, 193, -1, 193, 205, 206, -1, + 206, 205, 207, -1, 207, 205, 208, -1, 208, 205, 197, -1, + 197, 205, 194, -1, 202, 208, 198, -1, 197, 198, 208, -1, + 190, 209, 96, -1, 96, 209, 86, -1, 86, 209, 85, -1, + 85, 209, 84, -1, 84, 209, 210, -1, 210, 209, 211, -1, + 211, 209, 190, -1, 213, 212, 191, -1, 191, 212, 211, -1, + 211, 212, 214, -1, 214, 212, 215, -1, 215, 212, 216, -1, + 216, 212, 213, -1, 216, 217, 218, -1, 218, 217, 219, -1, + 219, 217, 220, -1, 220, 217, 221, -1, 221, 217, 192, -1, + 192, 217, 213, -1, 213, 217, 216, -1, 191, 211, 190, -1, + 192, 213, 191, -1, 206, 192, 193, -1, 192, 206, 221, -1, + 203, 222, 202, -1, 202, 222, 223, -1, 223, 222, 224, -1, + 224, 222, 225, -1, 225, 222, 203, -1, 223, 226, 227, -1, + 227, 226, 228, -1, 228, 226, 229, -1, 229, 226, 224, -1, + 224, 226, 223, -1, 231, 230, 224, -1, 224, 230, 229, -1, + 229, 230, 232, -1, 232, 230, 233, -1, 233, 230, 234, -1, + 234, 230, 231, -1, 231, 224, 225, -1, 227, 235, 223, -1, + 223, 235, 208, -1, 208, 235, 207, -1, 202, 223, 208, -1, + 207, 236, 206, -1, 206, 236, 221, -1, 221, 236, 220, -1, + 220, 236, 237, -1, 237, 236, 238, -1, 238, 236, 239, -1, + 239, 236, 240, -1, 240, 236, 228, -1, 228, 236, 227, -1, + 227, 236, 235, -1, 235, 236, 207, -1, 229, 241, 228, -1, + 228, 241, 240, -1, 240, 241, 239, -1, 239, 241, 242, -1, + 242, 241, 232, -1, 232, 241, 229, -1, 233, 243, 232, -1, + 232, 243, 244, -1, 244, 243, 245, -1, 245, 243, 246, -1, + 246, 243, 247, -1, 247, 243, 233, -1, 245, 248, 244, -1, + 244, 248, 242, -1, 242, 248, 238, -1, 238, 248, 237, -1, + 242, 238, 239, -1, 244, 242, 232, -1, 245, 249, 248, -1, + 248, 249, 237, -1, 237, 249, 250, -1, 250, 249, 251, -1, + 251, 249, 252, -1, 252, 249, 253, -1, 253, 249, 246, -1, + 246, 249, 245, -1, 255, 254, 237, -1, 237, 254, 220, -1, + 220, 254, 219, -1, 219, 254, 255, -1, 255, 237, 250, -1, + 257, 256, 258, -1, 258, 256, 259, -1, 259, 256, 260, -1, + 260, 256, 251, -1, 251, 256, 250, -1, 250, 261, 255, -1, + 255, 261, 262, -1, 262, 261, 263, -1, 263, 261, 264, -1, + 264, 261, 257, -1, 257, 261, 250, -1, 257, 258, 264, -1, + 260, 265, 259, -1, 259, 265, 258, -1, 258, 265, 264, -1, + 264, 265, 266, -1, 266, 265, 267, -1, 267, 265, 268, -1, + 251, 252, 260, -1, 269, 260, 252, -1, 268, 265, 260, -1, + 268, 260, 269, -1, 218, 270, 216, -1, 216, 270, 215, -1, + 215, 270, 271, -1, 271, 270, 272, -1, 272, 270, 273, -1, + 273, 270, 218, -1, 273, 274, 272, -1, 272, 274, 275, -1, + 275, 274, 276, -1, 276, 274, 277, -1, 277, 274, 278, -1, + 278, 274, 279, -1, 279, 274, 273, -1, 255, 262, 219, -1, + 218, 219, 273, -1, 262, 273, 219, -1, 279, 273, 262, -1, + 279, 262, 280, -1, 263, 280, 262, -1, 266, 281, 263, -1, + 263, 281, 280, -1, 266, 263, 264, -1, 266, 282, 281, -1, + 281, 282, 280, -1, 280, 282, 278, -1, 278, 282, 283, -1, + 283, 282, 284, -1, 284, 282, 285, -1, 285, 282, 267, -1, + 267, 282, 266, -1, 267, 268, 285, -1, 280, 278, 279, -1, + 211, 214, 210, -1, 286, 284, 285, -1, 288, 287, 289, -1, + 289, 287, 290, -1, 290, 287, 291, -1, 291, 287, 292, -1, + 292, 287, 288, -1, 275, 293, 292, -1, 292, 293, 294, -1, + 294, 293, 295, -1, 295, 293, 296, -1, 296, 293, 276, -1, + 276, 293, 275, -1, 277, 297, 276, -1, 276, 297, 296, -1, + 296, 297, 298, -1, 299, 297, 300, -1, 300, 297, 277, -1, + 291, 292, 294, -1, 295, 296, 298, -1, 299, 300, 301, -1, + 283, 301, 300, -1, 283, 300, 278, -1, 302, 283, 284, -1, + 302, 301, 283, -1, 275, 288, 272, -1, 271, 272, 288, -1, + 288, 303, 271, -1, 271, 303, 215, -1, 215, 303, 214, -1, + 214, 303, 304, -1, 304, 303, 289, -1, 289, 303, 288, -1, + 275, 292, 288, -1, 278, 300, 277, -1, 210, 305, 84, -1, + 84, 305, 83, -1, 83, 305, 306, -1, 306, 305, 307, -1, + 307, 305, 308, -1, 308, 305, 304, -1, 304, 305, 210, -1, + 289, 308, 304, -1, 290, 309, 289, -1, 289, 309, 310, -1, + 310, 309, 311, -1, 311, 309, 312, -1, 312, 309, 290, -1, + 289, 310, 308, -1, 307, 308, 310, -1, 310, 313, 307, -1, + 307, 313, 314, -1, 314, 313, 315, -1, 315, 313, 316, -1, + 316, 313, 311, -1, 311, 313, 310, -1, 318, 317, 319, -1, + 319, 317, 312, -1, 312, 317, 320, -1, 320, 317, 321, -1, + 321, 317, 322, -1, 322, 317, 318, -1, 301, 323, 318, -1, + 318, 323, 322, -1, 322, 323, 321, -1, 321, 323, 324, -1, + 324, 323, 302, -1, 302, 323, 301, -1, 312, 290, 319, -1, + 284, 324, 302, -1, 284, 325, 324, -1, 324, 325, 326, -1, + 326, 325, 327, -1, 327, 325, 328, -1, 328, 325, 286, -1, + 286, 325, 284, -1, 324, 326, 321, -1, 320, 321, 326, -1, + 326, 329, 320, -1, 320, 329, 330, -1, 330, 329, 331, -1, + 331, 329, 332, -1, 332, 329, 327, -1, 327, 329, 326, -1, + 320, 330, 312, -1, 330, 311, 312, -1, 311, 330, 316, -1, + 316, 330, 331, -1, 286, 333, 328, -1, 334, 328, 333, -1, + 335, 328, 334, -1, 328, 335, 327, -1, 332, 327, 335, -1, + 332, 335, 336, -1, 332, 336, 337, -1, 332, 337, 338, -1, + 332, 338, 331, -1, 331, 339, 316, -1, 316, 339, 315, -1, + 315, 339, 340, -1, 340, 339, 341, -1, 341, 339, 338, -1, + 338, 339, 331, -1, 341, 338, 337, -1, 315, 340, 342, -1, + 315, 342, 314, -1, 307, 314, 306, -1, 83, 306, 314, -1, + 83, 314, 82, -1, 342, 82, 314, -1, 82, 342, 7, -1, + 79, 7, 342, -1, 214, 304, 210, -1, 344, 343, 345, -1, + 347, 346, 348, -1, 349, 348, 346, -1, 346, 350, 349, -1, + 351, 349, 350, -1, 351, 350, 352, -1, 353, 352, 350, -1, + 354, 350, 346, -1, 354, 346, 355, -1, 357, 356, 358, -1, + 358, 359, 360, -1, 357, 358, 360, -1, 355, 357, 360, -1, + 354, 355, 360, -1, 361, 354, 360, -1, 359, 361, 360, -1, + 362, 359, 358, -1, 362, 358, 356, -1, 362, 356, 363, -1, + 362, 363, 364, -1, 362, 364, 365, -1, 366, 365, 364, -1, + 364, 334, 366, -1, 334, 333, 366, -1, 286, 366, 333, -1, + 361, 359, 367, -1, 368, 361, 367, -1, 367, 369, 368, -1, + 370, 368, 369, -1, 371, 369, 367, -1, 365, 372, 373, -1, + 362, 365, 373, -1, 359, 362, 373, -1, 367, 359, 373, -1, + 371, 367, 373, -1, 372, 371, 373, -1, 371, 372, 374, -1, + 375, 374, 372, -1, 286, 376, 377, -1, 366, 286, 377, -1, + 365, 366, 377, -1, 372, 365, 377, -1, 375, 372, 377, -1, + 376, 375, 377, -1, 376, 378, 375, -1, 369, 379, 380, -1, + 378, 381, 382, -1, 375, 378, 382, -1, 374, 375, 382, -1, + 383, 374, 382, -1, 384, 383, 382, -1, 381, 384, 382, -1, + 383, 384, 385, -1, 374, 383, 385, -1, 371, 374, 385, -1, + 369, 371, 385, -1, 379, 369, 385, -1, 384, 379, 385, -1, + 368, 386, 387, -1, 361, 368, 387, -1, 354, 361, 387, -1, + 350, 354, 387, -1, 353, 350, 387, -1, 386, 353, 387, -1, + 353, 386, 388, -1, 389, 388, 386, -1, 369, 380, 370, -1, + 386, 368, 370, -1, 389, 386, 370, -1, 380, 389, 370, -1, + 389, 345, 388, -1, 345, 343, 390, -1, 388, 345, 390, -1, + 353, 388, 390, -1, 352, 353, 390, -1, 351, 352, 390, -1, + 391, 351, 390, -1, 343, 391, 390, -1, 393, 392, 394, -1, + 396, 395, 397, -1, 389, 395, 398, -1, 345, 389, 398, -1, + 344, 345, 398, -1, 399, 344, 398, -1, 400, 399, 398, -1, + 395, 400, 398, -1, 400, 395, 401, -1, 396, 401, 395, -1, + 378, 402, 381, -1, 378, 376, 402, -1, 402, 393, 394, -1, + 403, 381, 394, -1, 405, 404, 406, -1, 408, 407, 397, -1, + 394, 392, 409, -1, 403, 394, 409, -1, 404, 403, 409, -1, + 406, 404, 409, -1, 410, 406, 409, -1, 392, 410, 409, -1, + 410, 396, 411, -1, 406, 410, 411, -1, 405, 406, 411, -1, + 407, 405, 411, -1, 397, 407, 411, -1, 396, 397, 411, -1, + 397, 395, 412, -1, 408, 397, 412, -1, 380, 408, 412, -1, + 389, 380, 412, -1, 395, 389, 412, -1, 286, 285, 376, -1, + 413, 343, 344, -1, 415, 414, 393, -1, 416, 285, 268, -1, + 416, 417, 418, -1, 285, 416, 418, -1, 376, 285, 418, -1, + 402, 376, 418, -1, 393, 402, 418, -1, 415, 393, 418, -1, + 419, 415, 418, -1, 417, 419, 418, -1, 417, 420, 421, -1, + 421, 415, 419, -1, 417, 421, 419, -1, 421, 422, 415, -1, + 414, 415, 422, -1, 414, 422, 423, -1, 422, 424, 423, -1, + 425, 423, 424, -1, 426, 424, 422, -1, 414, 423, 427, -1, + 393, 414, 427, -1, 392, 393, 427, -1, 410, 392, 427, -1, + 396, 410, 427, -1, 401, 396, 427, -1, 423, 401, 427, -1, + 423, 425, 428, -1, 401, 423, 428, -1, 400, 401, 428, -1, + 399, 400, 428, -1, 429, 399, 428, -1, 425, 429, 428, -1, + 268, 269, 430, -1, 268, 430, 431, -1, 269, 252, 430, -1, + 432, 430, 252, -1, 416, 268, 431, -1, 417, 416, 431, -1, + 420, 417, 431, -1, 433, 420, 431, -1, 434, 433, 431, -1, + 430, 434, 431, -1, 435, 420, 433, -1, 435, 436, 437, -1, + 420, 435, 437, -1, 421, 420, 437, -1, 422, 421, 437, -1, + 426, 422, 437, -1, 436, 426, 437, -1, 432, 436, 438, -1, + 430, 432, 438, -1, 434, 430, 438, -1, 433, 434, 438, -1, + 435, 433, 438, -1, 436, 435, 438, -1, 426, 436, 439, -1, + 424, 426, 440, -1, 441, 424, 440, -1, 439, 441, 440, -1, + 426, 439, 440, -1, 246, 442, 443, -1, 253, 246, 443, -1, + 252, 253, 443, -1, 432, 252, 443, -1, 436, 432, 443, -1, + 439, 436, 443, -1, 444, 439, 443, -1, 442, 444, 443, -1, + 446, 445, 447, -1, 447, 448, 449, -1, 449, 439, 444, -1, + 447, 449, 444, -1, 446, 447, 444, -1, 442, 446, 444, -1, + 247, 233, 450, -1, 246, 247, 450, -1, 442, 246, 450, -1, + 446, 442, 450, -1, 445, 446, 450, -1, 233, 445, 450, -1, + 445, 451, 452, -1, 447, 445, 452, -1, 448, 447, 452, -1, + 453, 448, 452, -1, 454, 453, 452, -1, 451, 454, 452, -1, + 456, 455, 457, -1, 458, 456, 457, -1, 454, 458, 457, -1, + 453, 454, 457, -1, 448, 453, 457, -1, 449, 448, 457, -1, + 439, 449, 457, -1, 441, 439, 457, -1, 459, 441, 457, -1, + 460, 459, 457, -1, 455, 460, 457, -1, 462, 461, 463, -1, + 461, 455, 456, -1, 463, 461, 456, -1, 458, 463, 456, -1, + 231, 225, 464, -1, 234, 231, 465, -1, 233, 234, 465, -1, + 445, 233, 465, -1, 451, 445, 465, -1, 464, 451, 465, -1, + 231, 464, 465, -1, 464, 463, 466, -1, 451, 464, 466, -1, + 454, 451, 466, -1, 458, 454, 466, -1, 463, 458, 466, -1, + 225, 203, 467, -1, 464, 225, 467, -1, 463, 464, 467, -1, + 462, 463, 467, -1, 203, 462, 467, -1, 468, 459, 460, -1, + 460, 469, 468, -1, 468, 470, 471, -1, 470, 472, 413, -1, + 471, 429, 473, -1, 468, 471, 473, -1, 459, 468, 473, -1, + 441, 459, 473, -1, 424, 441, 473, -1, 425, 424, 473, -1, + 429, 425, 473, -1, 429, 471, 474, -1, 399, 429, 474, -1, + 344, 399, 474, -1, 413, 344, 474, -1, 470, 413, 474, -1, + 471, 470, 474, -1, 413, 472, 475, -1, 343, 413, 475, -1, + 391, 343, 475, -1, 476, 391, 475, -1, 477, 476, 475, -1, + 478, 477, 475, -1, 472, 478, 475, -1, 479, 461, 480, -1, + 462, 480, 461, -1, 479, 481, 482, -1, 461, 479, 482, -1, + 455, 461, 482, -1, 460, 455, 482, -1, 469, 460, 482, -1, + 481, 469, 482, -1, 483, 481, 479, -1, 485, 484, 200, -1, + 187, 486, 485, -1, 204, 200, 487, -1, 203, 204, 487, -1, + 462, 203, 487, -1, 480, 462, 487, -1, 484, 480, 487, -1, + 200, 484, 487, -1, 485, 200, 187, -1, 484, 485, 488, -1, + 480, 484, 488, -1, 479, 480, 488, -1, 483, 479, 488, -1, + 486, 483, 488, -1, 485, 486, 488, -1, 490, 489, 491, -1, + 492, 490, 491, -1, 483, 492, 491, -1, 481, 483, 491, -1, + 469, 481, 491, -1, 468, 469, 491, -1, 470, 468, 491, -1, + 472, 470, 491, -1, 478, 472, 491, -1, 489, 478, 491, -1, + 492, 483, 493, -1, 494, 489, 490, -1, 492, 494, 490, -1, + 496, 495, 494, -1, 187, 178, 497, -1, 486, 187, 497, -1, + 483, 486, 497, -1, 493, 483, 497, -1, 498, 493, 497, -1, + 178, 498, 497, -1, 499, 494, 500, -1, 501, 499, 500, -1, + 502, 501, 500, -1, 493, 502, 500, -1, 492, 493, 500, -1, + 494, 492, 500, -1, 496, 494, 499, -1, 496, 499, 501, -1, + 503, 502, 493, -1, 503, 493, 498, -1, 503, 498, 178, -1, + 503, 178, 177, -1, 177, 174, 503, -1, 163, 504, 174, -1, + 502, 503, 505, -1, 505, 506, 502, -1, 507, 502, 506, -1, + 501, 502, 508, -1, 509, 501, 508, -1, 507, 509, 508, -1, + 502, 507, 508, -1, 511, 510, 512, -1, 512, 513, 511, -1, + 504, 511, 513, -1, 512, 514, 507, -1, 512, 507, 506, -1, + 512, 506, 513, -1, 515, 513, 506, -1, 174, 504, 515, -1, + 503, 174, 515, -1, 505, 503, 515, -1, 506, 505, 515, -1, + 504, 513, 515, -1, 517, 516, 518, -1, 517, 518, 519, -1, + 517, 519, 520, -1, 509, 520, 519, -1, 516, 517, 521, -1, + 522, 521, 517, -1, 514, 522, 523, -1, 507, 514, 523, -1, + 509, 507, 523, -1, 520, 509, 523, -1, 517, 520, 523, -1, + 522, 517, 523, -1, 524, 522, 514, -1, 526, 525, 510, -1, + 526, 510, 511, -1, 526, 511, 527, -1, 164, 158, 528, -1, + 163, 164, 528, -1, 504, 163, 528, -1, 511, 504, 528, -1, + 527, 511, 528, -1, 529, 527, 528, -1, 158, 529, 528, -1, + 158, 159, 530, -1, 158, 530, 529, -1, 527, 529, 530, -1, + 527, 530, 531, -1, 527, 531, 532, -1, 527, 532, 526, -1, + 525, 526, 532, -1, 525, 532, 533, -1, 534, 533, 532, -1, + 536, 535, 537, -1, 524, 538, 539, -1, 535, 539, 538, -1, + 522, 524, 540, -1, 521, 522, 540, -1, 541, 521, 540, -1, + 542, 541, 540, -1, 539, 542, 540, -1, 524, 539, 540, -1, + 510, 525, 543, -1, 512, 510, 543, -1, 514, 512, 543, -1, + 524, 514, 543, -1, 538, 524, 543, -1, 525, 538, 543, -1, + 533, 534, 544, -1, 525, 533, 544, -1, 538, 525, 544, -1, + 535, 538, 544, -1, 537, 535, 544, -1, 534, 537, 544, -1, + 546, 545, 547, -1, 549, 548, 550, -1, 550, 551, 542, -1, + 541, 542, 551, -1, 541, 551, 552, -1, 551, 553, 552, -1, + 535, 536, 554, -1, 539, 535, 554, -1, 542, 539, 554, -1, + 550, 542, 554, -1, 549, 550, 554, -1, 536, 549, 554, -1, + 550, 548, 555, -1, 551, 550, 555, -1, 553, 551, 555, -1, + 545, 553, 555, -1, 547, 545, 555, -1, 548, 547, 555, -1, + 112, 556, 127, -1, 123, 127, 556, -1, 123, 556, 557, -1, + 553, 557, 556, -1, 553, 556, 552, -1, 545, 546, 558, -1, + 553, 545, 558, -1, 557, 553, 558, -1, 123, 557, 558, -1, + 122, 123, 558, -1, 121, 122, 558, -1, 559, 121, 558, -1, + 546, 559, 558, -1, 111, 107, 560, -1, 112, 560, 561, -1, + 556, 112, 561, -1, 552, 556, 561, -1, 541, 552, 561, -1, + 521, 541, 561, -1, 516, 521, 561, -1, 560, 516, 561, -1, + 560, 112, 111, -1, 562, 107, 563, -1, 565, 564, 566, -1, + 566, 562, 565, -1, 563, 565, 562, -1, 562, 566, 567, -1, + 107, 562, 567, -1, 560, 107, 567, -1, 516, 560, 567, -1, + 518, 516, 567, -1, 566, 518, 567, -1, 569, 568, 495, -1, + 509, 519, 570, -1, 501, 509, 570, -1, 496, 501, 570, -1, + 495, 496, 570, -1, 569, 495, 570, -1, 519, 569, 570, -1, + 568, 569, 571, -1, 495, 568, 572, -1, 494, 495, 572, -1, + 489, 494, 572, -1, 478, 489, 572, -1, 477, 478, 572, -1, + 573, 477, 572, -1, 571, 573, 572, -1, 568, 571, 572, -1, + 569, 574, 571, -1, 573, 571, 575, -1, 573, 575, 576, -1, + 564, 577, 578, -1, 566, 564, 578, -1, 518, 566, 578, -1, + 519, 518, 578, -1, 569, 519, 578, -1, 574, 569, 578, -1, + 577, 574, 578, -1, 577, 564, 579, -1, 580, 579, 564, -1, + 582, 581, 583, -1, 584, 582, 583, -1, 576, 584, 583, -1, + 573, 576, 583, -1, 477, 573, 583, -1, 476, 477, 583, -1, + 391, 476, 583, -1, 351, 391, 583, -1, 349, 351, 583, -1, + 348, 349, 583, -1, 581, 348, 583, -1, 585, 348, 581, -1, + 348, 586, 587, -1, 348, 587, 347, -1, 588, 347, 589, -1, + 590, 588, 589, -1, 591, 590, 589, -1, 586, 591, 589, -1, + 587, 586, 589, -1, 347, 587, 589, -1, 590, 591, 592, -1, + 593, 590, 592, -1, 594, 593, 592, -1, 595, 594, 592, -1, + 591, 595, 592, -1, 593, 594, 596, -1, 597, 593, 596, -1, + 588, 590, 598, -1, 588, 598, 599, -1, 601, 600, 599, -1, + 590, 593, 602, -1, 598, 590, 602, -1, 599, 598, 602, -1, + 601, 599, 602, -1, 603, 601, 602, -1, 597, 603, 602, -1, + 593, 597, 602, -1, 605, 604, 606, -1, 608, 607, 609, -1, + 609, 610, 606, -1, 611, 606, 610, -1, 605, 606, 611, -1, + 597, 596, 612, -1, 603, 597, 612, -1, 606, 603, 612, -1, + 609, 606, 612, -1, 608, 609, 612, -1, 596, 608, 612, -1, + 604, 580, 613, -1, 601, 603, 614, -1, 600, 601, 614, -1, + 613, 600, 614, -1, 604, 613, 614, -1, 606, 604, 614, -1, + 603, 606, 614, -1, 579, 580, 615, -1, 616, 579, 615, -1, + 617, 616, 615, -1, 605, 617, 615, -1, 604, 605, 615, -1, + 580, 604, 615, -1, 577, 579, 616, -1, 616, 618, 577, -1, + 574, 577, 618, -1, 619, 571, 574, -1, 619, 574, 618, -1, + 619, 618, 620, -1, 616, 617, 621, -1, 618, 616, 621, -1, + 620, 618, 621, -1, 622, 620, 621, -1, 623, 622, 621, -1, + 617, 623, 621, -1, 622, 623, 624, -1, 625, 620, 622, -1, + 626, 625, 622, -1, 611, 610, 627, -1, 605, 611, 627, -1, + 617, 605, 627, -1, 623, 617, 627, -1, 624, 623, 627, -1, + 628, 624, 627, -1, 629, 628, 627, -1, 610, 629, 627, -1, + 630, 584, 576, -1, 630, 576, 626, -1, 575, 626, 576, -1, + 625, 626, 631, -1, 620, 625, 631, -1, 619, 620, 631, -1, + 571, 619, 631, -1, 575, 571, 631, -1, 626, 575, 631, -1, + 632, 624, 628, -1, 633, 632, 634, -1, 635, 633, 634, -1, + 630, 632, 633, -1, 624, 632, 636, -1, 622, 624, 636, -1, + 626, 622, 636, -1, 630, 626, 636, -1, 632, 630, 636, -1, + 637, 581, 582, -1, 633, 635, 638, -1, 630, 633, 638, -1, + 584, 630, 638, -1, 582, 584, 638, -1, 637, 582, 638, -1, + 635, 637, 638, -1, 639, 585, 640, -1, 641, 639, 640, -1, + 634, 641, 640, -1, 640, 585, 642, -1, 634, 640, 642, -1, + 635, 634, 642, -1, 637, 635, 642, -1, 581, 637, 642, -1, + 585, 581, 642, -1, 644, 643, 639, -1, 644, 639, 645, -1, + 646, 644, 645, -1, 629, 646, 645, -1, 628, 629, 645, -1, + 632, 628, 645, -1, 634, 632, 645, -1, 641, 634, 645, -1, + 639, 641, 645, -1, 647, 607, 648, -1, 647, 648, 643, -1, + 649, 643, 648, -1, 609, 607, 650, -1, 610, 609, 650, -1, + 629, 610, 650, -1, 646, 629, 650, -1, 644, 646, 650, -1, + 643, 644, 650, -1, 647, 643, 650, -1, 607, 647, 650, -1, + 594, 595, 651, -1, 596, 594, 651, -1, 608, 596, 651, -1, + 607, 608, 651, -1, 648, 607, 651, -1, 595, 648, 651, -1, + 649, 586, 652, -1, 643, 649, 652, -1, 639, 643, 652, -1, + 585, 639, 652, -1, 348, 585, 652, -1, 586, 348, 652, -1, + 586, 649, 653, -1, 591, 586, 653, -1, 595, 591, 653, -1, + 648, 595, 653, -1, 649, 648, 653, -1, 319, 290, 291, -1, + 319, 291, 294, -1, 319, 294, 295, -1, 319, 295, 318, -1, + 318, 298, 301, -1, 301, 298, 299, -1, 381, 403, 404, -1, + 405, 384, 404, -1, 379, 384, 405, -1, 379, 405, 407, -1, + 380, 379, 407, -1, 394, 381, 402, -1, 408, 380, 407, -1, + 318, 295, 298, -1, 299, 298, 297, -1, 381, 404, 384, -1, + 257, 250, 256, -1] + } + } + } + ] + } + + DEF TS TimeSensor {cycleInterval 4 loop TRUE} + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [1 2 1] + } + + Billboard { + axisOfRotation 0 0 0 + children [ + + Transform { + translation -2 2 0 + children [ + Shape { + appearance Appearance {material Material2D { emissiveColor 1 0 0 filled TRUE}} + geometry Rectangle { size 4 1} + } + Shape { + appearance Appearance {material Material2D { emissiveColor 1 1 1 filled TRUE}} + geometry DEF TEXT Text { string "Taper" fontStyle DEF FS FontStyle { size 0.8 justify ["MIDDLE" "MIDDLE"] style "TEXTURED"}} + } + DEF TS_MODE TouchSensor {} + ] + } + Transform { + translation 2 2 0 + children [ + Shape { + appearance Appearance {material Material2D { emissiveColor 0 0 1 filled TRUE}} + geometry Rectangle { size 4 1} + } + Shape { + appearance Appearance {material Material2D { emissiveColor 1 1 1 filled TRUE}} + geometry DEF TEXT_AXIS Text { string "Y Axis" fontStyle USE FS} + } + DEF TS_AXIS TouchSensor {} + ] + } + ] + } + + +DEF SC Script { + eventIn SFBool change_mode + eventIn SFBool change_axis + field SFNode deform USE NLD + field SFNode inter USE SI + field SFNode txt USE TEXT + field SFNode txt_axis USE TEXT_AXIS + url ["javascript: + function initialize() { + def_mode = 0; + def_axis = 0; + } + function change_mode(value, timestamp) { + if (!value) return; + def_mode++; + if (def_mode==3) def_mode = 0; + deform.type = def_mode; + switch (def_mode) { + case 0: + txt.string[0] = 'Taper'; + deform.extend[1] = 0.5; + deform.extend[3] = 1; + deform.extend[5] = 0.2; + inter.keyValue = new MFFloat(1, 2, 1); + break; + case 1: + txt.string[0] = 'Twister'; + deform.extend[1] = 0; + deform.extend[3] = 6.18; + deform.extend[5] = 0.0; + inter.keyValue = new MFFloat(-1, 1, -1); + break; + case 2: + txt.string[0] = 'Bender'; + deform.extend[1] = 0; + deform.extend[3] = 3.14; + deform.extend[5] = 0; + inter.keyValue = new MFFloat(-1, 1, -1); + break; + } + } + function change_axis(value, timestamp) { + if (!value) return; + def_axis++; + if (def_axis==3) def_axis = 0; + switch (def_axis) { + case 0: + txt_axis.string[0] = 'Y Axis'; + deform.axis = new SFVec3f(0, 1, 0); + break; + case 1: + txt_axis.string[0] = 'X Axis'; + deform.axis = new SFVec3f(1, 0, 0); + break; + case 2: + txt_axis.string[0] = 'Z Axis'; + deform.axis = new SFVec3f(0, 0, 1); + break; + } + } + "] +} + + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO NLD.param + +ROUTE TS_MODE.isActive TO SC.change_mode +ROUTE TS_AXIS.isActive TO SC.change_axis diff --git a/regression_tests/bifs/bifs-3D-shapes-pointset.bt b/regression_tests/bifs/bifs-3D-shapes-pointset.bt new file mode 100644 index 0000000..87c5873 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-shapes-pointset.bt @@ -0,0 +1,46 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetrics false + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +Group { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows PointSet" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "PointSet Test" + } + Shape { + appearance Appearance { + material Material { diffuseColor 1 0 0} + } + geometry PointSet { + coord DEF COORD Coordinate { + point [-1 1 1, 1 1 1, 1 1 -1, -1 1 -1, -1 -1 1, 1 -1 1, 1 -1 -1, -1 -1 -1] + } + } + } + ] +} + + diff --git a/regression_tests/bifs/bifs-3D-texturing-box-transparent.bt b/regression_tests/bifs/bifs-3D-texturing-box-transparent.bt new file mode 100644 index 0000000..6ca24ab --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-box-transparent.bt @@ -0,0 +1,73 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "Box test" + info ["This shows a 3D cube with transparency" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + translation 0 0 -50 + children [ + Shape { + appearance Appearance { + material Material { + emissiveColor 1 0 1 + diffuseColor 1 1 1 + } + } + geometry Box {size 150 100 10} + } + ] + } + + DEF TR Transform { + translation -50 0 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 1 1 0 + shininess 0.5 + transparency 0.5 + } + } + geometry Box {size 50 50 50} + } + ] + } + DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + ] +} + +ROUTE TS.fraction_changed TO MAT.transparency +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation diff --git a/regression_tests/bifs/bifs-3D-texturing-box-video.bt b/regression_tests/bifs/bifs-3D-texturing-box-video.bt new file mode 100644 index 0000000..998cb1d --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-box-video.bt @@ -0,0 +1,184 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric FALSE + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { +children [ + + Background2D { + backColor 1 1 1 + } + Viewpoint {} + WorldInfo { + info ["This shows spinning cubes with image and video textures" "GPAC Regression Tests" "$Date: 2008-11-24 14:58:25 $ - $Revision: 1.5 $" "(C) 2002-2004 GPAC Team"] + title "Cube, Texture Test" + } + + DEF TR Transform { + rotation 1 1 1 0.5 + children [ + Transform { + children [ + DEF Red Transform { + children [ + Shape { + appearance DEF Red-App Appearance { + material Material { + diffuseColor 1.0 0.0 0.0 + } + texture ImageTexture { url "5" } + } + geometry Box { } + } + ] + } + Transform { translation 2.0 2.0 0.0 children [ USE Red ] } + Transform { translation -2.0 2.0 0.0 children [USE Red ] } + Transform { translation 2.0 -2.0 0.0 children [USE Red ]} + Transform { translation -2.0 -2.0 0.0 children [USE Red ]} + Transform { translation 0.0 -2.0 2.0 children [USE Red ]} + Transform { translation 0.0 2.0 2.0 children [USE Red ]} + Transform { translation 2.0 0.0 2.0 children [USE Red ]} + Transform { translation -2.0 0.0 2.0 children [USE Red ]} + Transform { translation 0.0 -2.0 -2.0 children [USE Red ]} + Transform { translation 0.0 2.0 -2.0 children [USE Red ]} + Transform { translation 2.0 0.0 -2.0 children [USE Red ]} + Transform { translation -2.0 0.0 -2.0 children [USE Red ]} + ] + } + + Transform { + children [ + DEF Blue Transform { + translation 2.0 0.0 0.0 + children [ + Shape { + appearance DEF Blue-App Appearance { + material Material { + diffuseColor 0.0 0.0 1.0 + } + texture DEF M2 MovieTexture { url "10" loop TRUE } + } + geometry Box { } + } + ] + } + Transform { translation -4.0 0.0 0.0 children [USE Blue] } + Transform { translation -2.0 0.0 2.0 children [USE Blue] } + Transform { translation -2.0 0.0 -2.0 children [USE Blue] } + Transform { translation -2.0 2.0 0.0 children [USE Blue] } + Transform { translation -2.0 -2.0 0.0 children [USE Blue] } + Transform { translation 0.0 2.0 2.0 children [USE Blue] } + Transform { translation 0.0 2.0 -2.0 children [USE Blue] } + Transform { translation -4.0 2.0 2.0 children [USE Blue] } + Transform { translation -4.0 2.0 -2.0 children [USE Blue] } + Transform { translation 0.0 -2.0 2.0 children [USE Blue] } + Transform { translation 0.0 -2.0 -2.0 children [USE Blue] } + Transform { translation -4.0 -2.0 2.0 children [USE Blue] } + Transform { translation -4.0 -2.0 -2.0 children [USE Blue] } + ] + } + + DEF Clock TimeSensor { + cycleInterval 3.0 + loop FALSE + } + + DEF Trigger TimeSensor { + loop TRUE + cycleInterval 5.0 + } + + DEF RedScale PositionInterpolator { + key [ 0.0, 0.5, 1.0 ] + keyValue [ + 1.0 1.0 1.0, + 0.0001 0.0001 0.0001, + 1.0 1.0 1.0, + ] + } + + DEF BlueScale PositionInterpolator { + key [ 0.0, 0.25, 0.5, 0.75, 1.0 ] + keyValue [ + 1.0 1.0 1.0, + 0.0001 0.0001 0.0001, + 1.0 1.0 1.0, + 0.0001 0.0001 0.0001, + 1.0 1.0 1.0, + ] + } + ] + } + + DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + +] +} + +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation +ROUTE Trigger.cycleTime TO Clock.startTime +ROUTE Clock.fraction_changed TO RedScale.set_fraction +ROUTE Clock.fraction_changed TO BlueScale.set_fraction +ROUTE RedScale.value_changed TO Red.scale +ROUTE BlueScale.value_changed TO Blue.scale + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 10 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-texturing-box.bt b/regression_tests/bifs/bifs-3D-texturing-box.bt new file mode 100644 index 0000000..0340282 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-box.bt @@ -0,0 +1,69 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Box test" + info ["This shows a box" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + rotation 1 1 1 1.57 + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + texture ImageTexture { url "5" } + } + geometry Box {size 120 100 80} + } + ] + } + ] +} + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 10 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-texturing-compositetexture3D-bitmap.bt b/regression_tests/bifs/bifs-3D-texturing-compositetexture3D-bitmap.bt new file mode 100644 index 0000000..b935640 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-compositetexture3D-bitmap.bt @@ -0,0 +1,113 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + + WorldInfo { + title "Box test" + info ["This shows a bitmap using" "a compositetexture3D" "the 3D texture is a spinning box with an image texture" "" "GPAC Regression Tests" "$Date: 2008-07-22 10:54:58 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + Background2D{url 20} + + Shape { + appearance Appearance { + material DEF MAT Material2D { emissiveColor 1 1 0 filled FALSE transparency 0} + texture CompositeTexture3D { + pixelWidth 128 + pixelHeight 128 + children [ + DEF BACK Background2D {backColor 0 1 0} + DEF TR2 Transform { + rotation 1 1 1 -0.65 + children [ + Shape { + appearance Appearance { + material DEF MAT2 Material { emissiveColor 0 0 1 } + texture ImageTexture {url 10} + } + geometry Box {size 50 50 50} + } + DEF TOUCH TouchSensor{} + ] + } + ] + } + } +# geometry Bitmap{} + geometry Circle {radius 60} + } + + DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + + ] +} + +ROUTE TS.fraction_changed TO OI.set_fraction +#ROUTE TS.fraction_changed TO MAT2.transparency +ROUTE OI.value_changed TO TR2.rotation +ROUTE TOUCH.isActive TO BACK.set_bind + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 10 + muxInfo MuxInfo { + fileName "./../auxiliary_files/logo.png" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 20 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "./../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} + +#take care of bind delay +AT 100 { +# REPLACE BACK.set_bind BY FALSE +} diff --git a/regression_tests/bifs/bifs-3D-texturing-compositetexture3D-box.bt b/regression_tests/bifs/bifs-3D-texturing-compositetexture3D-box.bt new file mode 100644 index 0000000..dcfc2d6 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-compositetexture3D-box.bt @@ -0,0 +1,106 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + + Background2D { backColor 1 1 1} + + WorldInfo { + title "Composite Texture test" + info ["This shows a box" "with a 3D composite texture" "the texture is a spinning sphere with an image texture" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + + DEF TR Transform { + translation 0 0 0 + children [ + Shape { + appearance Appearance { + texture CompositeTexture3D { + pixelWidth 128 + pixelHeight 128 + children [ + #MPEG-4 is stupid here, background2D can't be encoded in the CT3D.background field + Background2D {url "../auxiliary_files/sky.jpg" backColor 1 0 0} + DEF TR2 Transform { + scale 1 0.5 1 + children [ + Shape { + appearance Appearance { + material DEF MAT2 Material { diffuseColor 0 0 1 } + texture ImageTexture { url "10"} + } + geometry Sphere {radius 60} + } + ] + } + ] + } + } + geometry Box {size 64 64 64 } + } + ] + } + + DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 0.8 0] + } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + ] +} + +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation +ROUTE OI.value_changed TO TR2.rotation +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO MAT2.transparency + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-texturing-cone-transparent.bt b/regression_tests/bifs/bifs-3D-texturing-cone-transparent.bt new file mode 100644 index 0000000..da9cb61 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-cone-transparent.bt @@ -0,0 +1,68 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Cone test" + info ["This shows cones with and without cap" "with transparency - objects should appear behing each-other" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + translation -70 0 0 + rotation 1 0 0 4 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { diffuseColor 1.0 0.0 0.0 transparency 0.5} + } + geometry Cone {height 150 bottomRadius 25} + } + ] + } + Transform { + translation 70 0 0 + rotation 1 0 0 4 + children [ + Shape { + appearance Appearance { +# material USE MAT + material Material { diffuseColor 1.0 0.0 1.0} + } + geometry Cone {height 150 bottomRadius 25 bottom FALSE} + } + ] + } + DEF TS TimeSensor {loop TRUE cycleInterval 6} + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO MAT.transparency + diff --git a/regression_tests/bifs/bifs-3D-texturing-cone.bt b/regression_tests/bifs/bifs-3D-texturing-cone.bt new file mode 100644 index 0000000..5ae2968 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-cone.bt @@ -0,0 +1,81 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Cone test" + info ["This shows a cone" "with and without cap" "and a texture map" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + translation -70 0 0 + rotation 1 0 0 4 + children [ + Shape { + appearance DEF APP Appearance { + material Material {diffuseColor 1.0 0.0 0.0 } + texture ImageTexture { url "5" } + } + geometry Cone {height 150 bottomRadius 25} + } + ] + } + Transform { + translation 70 0 0 + rotation 1 0 0 4 + children [ + Shape { + appearance USE APP + geometry Cone {height 150 bottomRadius 25 bottom FALSE} + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 10 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-texturing-cylinder-transparent.bt b/regression_tests/bifs/bifs-3D-texturing-cylinder-transparent.bt new file mode 100644 index 0000000..d7455f0 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-cylinder-transparent.bt @@ -0,0 +1,93 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 380 + pixelHeight 300 + } + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Cylinder test" + info ["This shows a cylinder" "with and without cap and side and transparent material" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + translation -100 100 0 + children [ + Shape { + appearance DEF APP Appearance { + material DEF MAT Material {diffuseColor 1.0 0.0 0.0 } + } + geometry Cylinder {height 150 radius 25} + } + ] + } + Transform { + translation 0 100 0 + rotation 1 0 0 0.78 + children [ + Shape { + appearance USE APP + geometry Cylinder {height 150 radius 25 top FALSE} + } + ] + } + Transform { + translation -100 -100 0 + rotation 1 0 0 -0.78 + children [ + Shape { + appearance USE APP + geometry Cylinder {height 150 radius 25 bottom FALSE} + } + ] + } + Transform { + translation 0 -100 0 + rotation 1 0 0 1.2 + children [ + Shape { + appearance USE APP + geometry Cylinder {height 150 radius 25 bottom FALSE top FALSE} + } + ] + } + Transform { + translation 100 0 0 + children [ + Shape { + appearance USE APP + geometry Cylinder {height 150 radius 25 side FALSE } + } + ] + } + DEF TS TimeSensor {loop TRUE cycleInterval 6} + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO MAT.transparency + diff --git a/regression_tests/bifs/bifs-3D-texturing-cylinder.bt b/regression_tests/bifs/bifs-3D-texturing-cylinder.bt new file mode 100644 index 0000000..57efe14 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-cylinder.bt @@ -0,0 +1,107 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 380 + pixelHeight 300 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "Cylinder test" + info ["This shows a cylinder" "with and without cap and side and a texture map" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + translation -100 100 0 + children [ + Shape { + appearance DEF APP Appearance { + material Material {diffuseColor 1.0 0.0 0.0 } + texture ImageTexture { url "5" } + } + geometry Cylinder {height 150 radius 25} + } + ] + } + Transform { + translation 0 100 0 + rotation 1 0 0 0.78 + children [ + Shape { + appearance USE APP + geometry Cylinder {height 150 radius 25 top FALSE} + } + ] + } + Transform { + translation -100 -100 0 + rotation 1 0 0 -0.78 + children [ + Shape { + appearance USE APP + geometry Cylinder {height 150 radius 25 bottom FALSE} + } + ] + } + Transform { + translation 0 -100 0 + rotation 1 0 0 1.2 + children [ + Shape { + appearance USE APP + geometry Cylinder {height 150 radius 25 bottom FALSE top FALSE} + } + ] + } + Transform { + translation 100 0 0 + children [ + Shape { + appearance USE APP + geometry Cylinder {height 150 radius 25 side FALSE } + } + ] + } + ] +} + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 10 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-3D-texturing-transform-box.bt b/regression_tests/bifs/bifs-3D-texturing-transform-box.bt new file mode 100644 index 0000000..d559c0d --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-transform-box.bt @@ -0,0 +1,85 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "Texture Transform test" + info ["This shows a 3D cube" "mapped with an alpha PNG and texture transform" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + DEF TR Transform { + rotation 1 1 1 0.75 + children [ + Shape { + appearance Appearance { + material DEF MAT Material {} + textureTransform DEF MX TextureTransform { scale 4 4 } + texture ImageTexture { url "10"} + } + geometry Box {size 64 64 64 } + } + ] + } + + DEF TS TimeSensor { cycleInterval 2.0 loop TRUE } + DEF PI PositionInterpolator2D { + key [0 0.25 0.5 0.75 1] + keyValue [1 1, 4 1, 4 4, 1 4, 1 1] + } + DEF CI ColorInterpolator { + key [0 0.5 1] + keyValue [1 1 1, 0 0 1, 1 1 1] + } + ] +} + +ROUTE TS.fraction_changed TO PI.set_fraction +ROUTE PI.value_changed TO MX.scale +ROUTE TS.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO MAT.diffuseColor + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-texturing-transform-matrix-box.bt b/regression_tests/bifs/bifs-3D-texturing-transform-matrix-box.bt new file mode 100644 index 0000000..2797b12 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-texturing-transform-matrix-box.bt @@ -0,0 +1,91 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "Texture Transform test" + info ["This shows a 3D cube" "mapped with an alpha PNG and texture transform" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + DEF TR Transform { + rotation 1 1 1 0.75 + children [ + Shape { + appearance Appearance { + material DEF MAT Material {} + textureTransform DEF MX TransformMatrix2D {mxx 3 myy 2} + texture ImageTexture { url "10"} + } + geometry Box {size 64 64 64 } + } + ] + } + + DEF TS TimeSensor { cycleInterval 8.0 loop TRUE } + DEF SI ScalarInterpolator { + key [0 0.25 0.5 0.75 1] + keyValue [1 1 1 6 1] + } + DEF SI2 ScalarInterpolator { + key [0 0.25 0.5 0.75 1] + keyValue [1 6 1 1 1] + } + DEF CI ColorInterpolator { + key [0 0.5 1] + keyValue [1 1 1, 0 0 1, 1 1 1] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO MX.mxy +ROUTE TS.fraction_changed TO SI2.set_fraction +ROUTE SI2.value_changed TO MX.myx +ROUTE TS.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO MAT.diffuseColor + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-3D-viewpoint-anim.bt b/regression_tests/bifs/bifs-3D-viewpoint-anim.bt new file mode 100644 index 0000000..bf8000f --- /dev/null +++ b/regression_tests/bifs/bifs-3D-viewpoint-anim.bt @@ -0,0 +1,84 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 200 + } + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "Viewpoint animation test test" + info ["This shows a sphere" "and dynamic viewpoint" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + DEF VP Viewpoint {position -200 0 100 orientation 0 1 0 -1.0 } + + Transform { + translation 0 0 -50 + children [ + Shape { + appearance Appearance { + material Material { + diffuseColor 1 1 1 + } + } + geometry Box {size 150 100 10} + } + ] + } + + DEF TR Transform { + translation -50 0 0 + scale 0.75 1 1 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 1 1 0 + shininess 0.5 + } + } + geometry Sphere {radius 25 } + } + ] + } + DEF TS TimeSensor { cycleInterval 4.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [0 0 1 0, 0 0 1 3.14, 0 0 1 6.26] + } + DEF OI2 OrientationInterpolator { + key [0 0.5 1] + keyValue [0 1 0 -1, 0 1 0 1, 0 1 0 -1] + } + DEF PI PositionInterpolator { + key [0 0.5 1] + keyValue [-200 0 100, 200 0 100, -200 0 100] + } + ] +} + +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation +ROUTE TS.fraction_changed TO OI2.set_fraction +ROUTE OI2.value_changed TO VP.orientation +ROUTE TS.fraction_changed TO PI.set_fraction +ROUTE PI.value_changed TO VP.position diff --git a/regression_tests/bifs/bifs-3D-viewpoint-bind-jump.bt b/regression_tests/bifs/bifs-3D-viewpoint-bind-jump.bt new file mode 100644 index 0000000..6912730 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-viewpoint-bind-jump.bt @@ -0,0 +1,114 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +Group { + children [ + WorldInfo { + title "Viewpoint bind test" + info ["This shows sensors triggering viewpoint binding" "Viewpoint switching shall not be animated" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + DEF VP1 Viewpoint {description "Front View" position 0 0 300} + DEF VP2 Viewpoint {description "Above View" position 0 300 30 orientation 1 0 0 -1.2 } + + DEF TR Transform { + translation 50 0 0 + children [ + Shape { + appearance Appearance { + material Material { + diffuseColor 0 1 1 + } + } + geometry DEF BOX Box {size 50 50 50} + } + DEF TS2 TouchSensor {} + ] + } + + Transform { + translation -80 0 20 + children [ + Shape { + appearance Appearance { + material Material2D { emissiveColor 1 0 0 filled TRUE } + } + geometry DEF RC_RED Rectangle {size 100 100} + } + ] + } + + Shape { + appearance Appearance { + material Material2D { emissiveColor 1 1 1 filled TRUE } + } + geometry DEF RC_WHITE Rectangle { size 200 200 } + } + + + Transform { + translation -30 0 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 1 1 0 + } + } + geometry DEF SPHERE Sphere {radius 30} + } + DEF TOUCH TouchSensor {} + ] + } + DEF TS TimeSensor { enabled FALSE cycleInterval 2.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + + DEF C Conditional { buffer { REPLACE MAT.diffuseColor BY 0 0 1 } } + DEF RC Conditional { buffer { REPLACE MAT.diffuseColor BY 1 1 0 } } + + DEF SETVP1 Conditional { + buffer { + REPLACE VP1.set_bind BY TRUE + REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP2.activate + } + } + DEF SETVP2 Conditional { + buffer { + REPLACE VP2.set_bind BY TRUE + REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP1.activate + } + } + + ] +} + +DEF MVP ROUTE TOUCH.isActive TO SETVP2.activate +ROUTE TOUCH.isOver TO TS.enabled +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation +ROUTE TS2.isActive TO C.activate +ROUTE TS2.isActive TO RC.reverseActivate diff --git a/regression_tests/bifs/bifs-3D-viewpoint-bind.bt b/regression_tests/bifs/bifs-3D-viewpoint-bind.bt new file mode 100644 index 0000000..a3e716b --- /dev/null +++ b/regression_tests/bifs/bifs-3D-viewpoint-bind.bt @@ -0,0 +1,115 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + useNames true + } + } + } + ] +} + +Group { + children [ + WorldInfo { + title "Viewpoint bind test" + info ["This shows sensors triggering viewpoint binding" "Viewpoint switching shall be animated" "" "GPAC Regression Tests" "$Date: 2008-11-24 14:58:25 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + + DEF VP1 Viewpoint {description "Front View" position 0 0 200 jump FALSE fieldOfView 0.39} + DEF VP2 Viewpoint {description "Above View" position 0 300 30 orientation 1 0 0 -1.2 jump FALSE} + + DEF TR Transform { + translation 50 0 0 + children [ + Shape { + appearance Appearance { + material Material { + diffuseColor 0 1 1 + } + } + geometry DEF BOX Box {size 50 50 50} + } + DEF TS2 TouchSensor {} + ] + } + + Transform { + translation -80 0 20 + children [ + Shape { + appearance Appearance { + material Material2D { emissiveColor 1 0 0 filled TRUE } + } + geometry DEF RC_RED Rectangle {size 100 100} + } + ] + } + + Shape { + appearance Appearance { + material Material2D { emissiveColor 1 1 1 filled TRUE } + } + geometry DEF RC_WHITE Rectangle { size 200 200 } + } + + + Transform { + translation -30 0 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 1 1 0 + } + } + geometry DEF SPHERE Sphere {radius 30} + } + DEF TOUCH TouchSensor {} + ] + } + DEF TS TimeSensor { enabled FALSE cycleInterval 2.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + + DEF C Conditional { buffer { REPLACE MAT.diffuseColor BY 0 0 1 } } + DEF RC Conditional { buffer { REPLACE MAT.diffuseColor BY 1 1 0 } } + + DEF SETVP1 Conditional { + buffer { + REPLACE VP1.set_bind BY TRUE + REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP2.activate + } + } + DEF SETVP2 Conditional { + buffer { + REPLACE VP2.set_bind BY TRUE + REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP1.activate + } + } + + ] +} + +DEF MVP ROUTE TOUCH.isActive TO SETVP2.activate +ROUTE TOUCH.isOver TO TS.enabled +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation +ROUTE TS2.isActive TO C.activate +ROUTE TS2.isActive TO RC.reverseActivate diff --git a/regression_tests/bifs/bifs-3D-viewpoint-ortho-bind.bt b/regression_tests/bifs/bifs-3D-viewpoint-ortho-bind.bt new file mode 100644 index 0000000..f2e2219 --- /dev/null +++ b/regression_tests/bifs/bifs-3D-viewpoint-ortho-bind.bt @@ -0,0 +1,114 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + title "Viewpoint bind test" + info ["This shows sensors triggering viewpoint binding" "Viewpoint switching shall be animated" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + DEF VP1 Viewpoint {description "Front View" position 0 0 200 jump FALSE} + DEF VP2 Viewpoint {description "Above View" position 0 300 30 orientation 1 0 0 -1.2 jump FALSE} + + DEF TR Transform { + translation 50 0 0 + children [ + Shape { + appearance Appearance { + material Material { + diffuseColor 0 1 1 + } + } + geometry DEF BOX Box {size 50 50 50} + } + DEF TS2 TouchSensor {} + ] + } + + Transform { + translation -80 0 20 + children [ + Shape { + appearance Appearance { + material Material2D { emissiveColor 1 0 0 filled TRUE } + } + geometry DEF RC_RED Rectangle {size 100 100} + } + ] + } + + Shape { + appearance Appearance { + material Material2D { emissiveColor 1 1 1 filled TRUE } + } + geometry DEF RC_WHITE Rectangle { size 200 200 } + } + + + Transform { + translation -30 0 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 1 1 0 + } + } + geometry DEF SPHERE Sphere {radius 30} + } + DEF TOUCH TouchSensor {} + ] + } + DEF TS TimeSensor { enabled FALSE cycleInterval 2.0 loop TRUE } + DEF OI OrientationInterpolator { + key [0 0.5 1] + keyValue [1 1 1 0, 1 1 1 3.14, 1 1 1 6.26] + } + + DEF C Conditional { buffer { REPLACE MAT.diffuseColor BY 0 0 1 } } + DEF RC Conditional { buffer { REPLACE MAT.diffuseColor BY 1 1 0 } } + + DEF SETVP1 Conditional { + buffer { + REPLACE VP1.set_bind BY TRUE + REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP2.activate + } + } + DEF SETVP2 Conditional { + buffer { + REPLACE VP2.set_bind BY TRUE + REPLACE ROUTE MVP BY TOUCH.isActive TO SETVP1.activate + } + } + + ] +} + +DEF MVP ROUTE TOUCH.isActive TO SETVP2.activate +ROUTE TOUCH.isOver TO TS.enabled +ROUTE TS.fraction_changed TO OI.set_fraction +ROUTE OI.value_changed TO TR.rotation +ROUTE TS2.isActive TO C.activate +ROUTE TS2.isActive TO RC.reverseActivate diff --git a/regression_tests/bifs/bifs-bitmap-image-meter-metrics.bt b/regression_tests/bifs/bifs-bitmap-image-meter-metrics.bt new file mode 100644 index 0000000..47a6350 --- /dev/null +++ b/regression_tests/bifs/bifs-bitmap-image-meter-metrics.bt @@ -0,0 +1,80 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelWidth 400 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows dragable bitmap with scale 0.75 0.75" "in Meter Metrics" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Bitmap Test" + } + Transform2D { + children [ + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + texture ImageTexture { + url [od:10] + } + } + geometry Bitmap { + scale 0.75 0.75 + } + } + DEF PS PlaneSensor2D { + maxPosition 1 1 + minPosition -1 -1 + } + ] + } + ] + } + ] +} + +ROUTE PS.translation_changed TO TR.translation + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-bitmap-image-pixel-metrics.bt b/regression_tests/bifs/bifs-bitmap-image-pixel-metrics.bt new file mode 100644 index 0000000..be6bbdf --- /dev/null +++ b/regression_tests/bifs/bifs-bitmap-image-pixel-metrics.bt @@ -0,0 +1,89 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 0 + } + WorldInfo { + info [ + "This test shows an Image (the Osmo4 logo), which has an alpha component being display on a yellow background." + "The geometry node use to display the image is a Bitmap node with a scale of 0.75 0.75" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:08 $ - $Revision: 1.4 $" + "(C) 2002-2004 GPAC Team" + ] + title "Bitmap and Transparent Images" + } + Transform2D { + children [ + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + texture ImageTexture { + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap { + scale 0.75 0.75 + } + } + DEF PS PlaneSensor2D { + maxPosition 200 200 + minPosition -200 -200 + } + ] + } + ] + } + ] +} + +ROUTE PS.translation_changed TO TR.translation + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.png" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-bitmap-image-resizing.bt b/regression_tests/bifs/bifs-bitmap-image-resizing.bt new file mode 100644 index 0000000..fe1befe --- /dev/null +++ b/regression_tests/bifs/bifs-bitmap-image-resizing.bt @@ -0,0 +1,153 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows an image whose size is animated." + "The result is displayed on top of a static image." + "Both textures use a Bitmap node to allow efficient handling of the textures." + "The resizing of the image is not done using a Transform2D node (or TransformMatrix2D) but by changing the size property of the Bitmap node." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.4 $" + "(C) 2002-2006 GPAC Team" + ] + title "Image Resizing" + } + Transform2D { + translation 0 128 + children [ + DEF TR Transform2D { + children [ + Transform2D { + translation -128 0 + children [ + DEF S Shape { + appearance Appearance { + texture ImageTexture { + url [od:12] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap {} + + } + ] + } + Transform2D { + children [ + USE S + ] + } + Transform2D { + translation 128 0 + children [ + USE S + ] + } + ] + } + ] + } + Transform2D { + children [ + USE TR + ] + } + Transform2D { + translation 0 -128 + children [ + USE TR + ] + } + Transform2D { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + texture ImageTexture { + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry DEF BMP Bitmap { + scale 0.75 0.75 + } + } + ] + } + ] + } + DEF TS TimeSensor { + loop TRUE + } + DEF PI PositionInterpolator2D { + key [0 0.5 1] + keyValue [0.75 0.75 0.25 0.25 0.75 0.75] + } + ] +} + +ROUTE TS.fraction_changed TO PI.set_fraction +ROUTE PI.value_changed TO BMP.scale + +RAP AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 12 + esDescr [ + ES_Descriptor { + ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-bitmap-movie-materialkey.bt b/regression_tests/bifs/bifs-bitmap-movie-materialkey.bt new file mode 100644 index 0000000..eff8f19 --- /dev/null +++ b/regression_tests/bifs/bifs-bitmap-movie-materialkey.bt @@ -0,0 +1,101 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + DEF B Background2D { + backColor 0 0 1 + } + WorldInfo { + info [ + "This test shows how to do Color Keying on Video." + "The MaterialKey node allows defining a key color or color range and to make that color transparent in the texture. The degree of transparency can be specified using the transparency property." + + "" + "GPAC Regression Tests" "$Date: 2008-05-19 15:28:17 $ - $Revision: 1.6 $" + "(C) 2002-2004 GPAC Team" + ] + title "Color Keying on Video using the MaterialKey node" + } + Transform2D { + scale 2 2 + children [ + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + texture MovieTexture { + url [od:10] + loop FALSE + } + material DEF MK MaterialKey { + isKeyed TRUE + lowThreshold 0.4 + highThreshold 0.4 + keyColor 1 1 0 + transparency 0 + } + } + geometry Bitmap { + scale 1 1 + } + } + ] + } + ] + } + DEF TS TimeSensor {loop TRUE cycleInterval 10.0} + DEF CI ColorInterpolator { + key [0 1] + keyValue [1 1 1, 0 0 1] + } + ] +} + +#ROUTE TS.fraction_changed TO MK.highThreshold +ROUTE TS.fraction_changed TO CI.set_fraction +ROUTE CI.value_changed TO B.backColor + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-bitmap-movie.bt b/regression_tests/bifs/bifs-bitmap-movie.bt new file mode 100644 index 0000000..58a410b --- /dev/null +++ b/regression_tests/bifs/bifs-bitmap-movie.bt @@ -0,0 +1,84 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "The Bitmap node is a geometry node which defines a rectangle on which the texture is mapped. The difference with a Rectangle node is that its size is given by the texture, hence no resampling of the texture is needed during the display. Hardware accelerated operations can be used." + "This test shows a dragable video. The Bitmap node allows efficient draging and display of the video." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.4 $" + "(C) 2002-2006 GPAC Team" + ] + title "Efficient Display of Video using the Bitmap node" + } + Transform2D { + scale 2 2 + children [ + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + texture MovieTexture { + url [od:10] + loop FALSE + } + } + geometry Bitmap { + scale 1 1 + } + } + ] + } + ] + } + ] +} + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-bitmap-video-resizing.bt b/regression_tests/bifs/bifs-bitmap-video-resizing.bt new file mode 100644 index 0000000..5120836 --- /dev/null +++ b/regression_tests/bifs/bifs-bitmap-video-resizing.bt @@ -0,0 +1,152 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows a video whose size is animated, the result is displayed on top of a static image." + "Both textures use a Bitmap node to allow efficient handling of the textures." + "The resizing of the video is not done using a Transform2D node (or TransformMatrix2D) but by changing the size property of the Bitmap node." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.5 $" + "(C) 2002-2006 GPAC Team" + ] + title "Bitmap Video Resizing" + } + Transform2D { + translation 0 128 + children [ + DEF TR Transform2D { + children [ + Transform2D { + translation -128 0 + children [ + DEF S Shape { + appearance Appearance { + texture ImageTexture { + url [od:12] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap {} + + } + ] + } + Transform2D { + children [ + USE S + ] + } + Transform2D { + translation 128 0 + children [ + USE S + ] + } + ] + } + ] + } + Transform2D { + children [ + USE TR + ] + } + Transform2D { + translation 0 -128 + children [ + USE TR + ] + } + Transform2D { + children [ + Transform2D { + children [ + Shape { + appearance Appearance { + texture MovieTexture { + loop TRUE + url [od:10] + } + } + geometry DEF BMP Bitmap { + scale 0.75 0.75 + } + } + ] + } + ] + } + DEF TS TimeSensor { + loop TRUE + } + DEF PI PositionInterpolator2D { + key [0 0.5 1] + keyValue [2 2 0.25 0.25 2 2] + } + ] +} + +ROUTE TS.fraction_changed TO PI.set_fraction +ROUTE PI.value_changed TO BMP.scale + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 12 + esDescr [ + ES_Descriptor { + ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-command-animated-osmo4logo.bt b/regression_tests/bifs/bifs-command-animated-osmo4logo.bt new file mode 100644 index 0000000..fb0626c --- /dev/null +++ b/regression_tests/bifs/bifs-command-animated-osmo4logo.bt @@ -0,0 +1,315 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 0 1 1 + } + WorldInfo { + info ["This shows the Osmo4 logo" "animated through BIFS commands" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Osmo4 Logo" + } + Shape { + appearance Appearance { + texture LinearGradient { + endPoint 0 1 + key [0 0.33 1] + keyValue [0 0.5 0.5 0 0.75 0.75 0 0.75 1] + } + } + geometry Rectangle { + size 300 300 + } + } + Switch { + choice [ + DEF BCIRCLE Shape { + appearance DEF ABLACK Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Circle { + radius 60 + } + } + DEF BTRIANGLE Shape { + appearance USE ABLACK + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coord Coordinate2D { + point [-40 0 40 0 0 -60] + } + } + } + DEF RCIRCLE Shape { + appearance Appearance { + material DEF RMAT Material2D { + lineProps DEF LP XLineProperties { + lineColor 1 0 0 + width 20 + } + } + } + geometry Circle { + radius 100 + } + } + ] + } + DEF MOV Transform2D { + children [ + DEF LOGO Transform2D {} + ] + } + ] +} + + +AT 1000 { + APPEND TO LOGO.children DEF BR Transform2D { + scale 0 0 + translation -150 -150 + children [ + USE BCIRCLE + ] + } + APPEND TO MOV.children DEF TIME TimeSensor { + cycleInterval 1.5 + } + APPEND TO MOV.children DEF POS PositionInterpolator2D { + key [0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1] + keyValue [-150 -150 -135 135 120 120 105 -105 -90 -90 -75 75 60 60 45 -45 -30 -30 -15 15 0 0] + } + APPEND TO MOV.children DEF SCALE PositionInterpolator2D { + key [0 1] + keyValue [0.1 0.1 1 1] + } + INSERT ROUTE DEF R1 TIME.fraction_changed TO POS.set_fraction + INSERT ROUTE DEF R2 TIME.fraction_changed TO SCALE.set_fraction + INSERT ROUTE DEF R3 POS.value_changed TO BR.translation + INSERT ROUTE DEF R4 SCALE.value_changed TO BR.scale +} + +AT 2500 { + DELETE ROUTE R1 + DELETE ROUTE R2 + DELETE ROUTE R3 + DELETE ROUTE R4 + DELETE TIME + DELETE POS + DELETE SCALE + REPLACE BR.translation BY 0 0 + REPLACE BR.scale BY 1 1 + APPEND TO LOGO.children DEF BT Transform2D { + scale 9 0.5 + translation 0 20 + children [ + USE BTRIANGLE + ] + } + APPEND TO MOV.children DEF TIME2 TimeSensor { + cycleInterval 1.5 + } + APPEND TO MOV.children DEF POS_BT PositionInterpolator2D { + key [0 1] + keyValue [0 20 0 90] + } + APPEND TO MOV.children DEF POS_BR PositionInterpolator2D { + key [0 1] + keyValue [0 0 0 -30] + } + APPEND TO MOV.children DEF SCALE_BR PositionInterpolator2D { + key [0 0.7 1] + keyValue [1 1 1.4 1.4 1 1] + } + APPEND TO MOV.children DEF SCALE_BT PositionInterpolator2D { + key [0 0.7 1] + keyValue [9 0.5 5 0.7 1 1] + } + INSERT ROUTE DEF R1 TIME2.fraction_changed TO POS_BT.set_fraction + INSERT ROUTE DEF R2 TIME2.fraction_changed TO POS_BR.set_fraction + INSERT ROUTE DEF R3 TIME2.fraction_changed TO SCALE_BT.set_fraction + INSERT ROUTE DEF R4 TIME2.fraction_changed TO SCALE_BR.set_fraction + INSERT ROUTE DEF R5 POS_BT.value_changed TO BT.translation + INSERT ROUTE DEF R6 POS_BR.value_changed TO BR.translation + INSERT ROUTE DEF R7 SCALE_BT.value_changed TO BT.scale + INSERT ROUTE DEF R8 SCALE_BR.value_changed TO BR.scale +} + +AT 4000 { + DELETE ROUTE R1 + DELETE ROUTE R2 + DELETE ROUTE R3 + DELETE ROUTE R4 + DELETE ROUTE R5 + DELETE ROUTE R6 + DELETE ROUTE R7 + DELETE ROUTE R8 + DELETE TIME2 + DELETE POS_BT + DELETE SCALE_BT + DELETE POS_BR + DELETE SCALE_BR + REPLACE BT.translation BY 0 90 + REPLACE BR.translation BY 0 -30 + REPLACE BR.scale BY 1 1 + REPLACE BT.scale BY 1 1 + REPLACE LP.width BY 0 + APPEND TO LOGO.children DEF RC Transform2D { + children [ + USE RCIRCLE + ] + } + APPEND TO MOV.children DEF TIME3 TimeSensor { + cycleInterval 1.5 + } + APPEND TO MOV.children DEF WIDTH ScalarInterpolator { + key [0 0.5 0.75 1] + keyValue [0 25 15 20] + } + APPEND TO MOV.children DEF COL ColorInterpolator { + key [0 1] + keyValue [0 0 0 1 0 0] + } + INSERT ROUTE DEF R1 TIME3.fraction_changed TO WIDTH.set_fraction + INSERT ROUTE DEF R2 TIME3.fraction_changed TO COL.set_fraction + INSERT ROUTE DEF R3 WIDTH.value_changed TO LP.width + INSERT ROUTE DEF R4 COL.value_changed TO LP.lineColor +} + +AT 5500 { + DELETE ROUTE R1 + DELETE ROUTE R2 + DELETE ROUTE R3 + DELETE ROUTE R4 + DELETE TIME3 + DELETE WIDTH + DELETE COL + REPLACE LP.width BY 20 + REPLACE LP.transparency BY 0 + REPLACE LP.lineColor BY 1 0 0 + APPEND TO MOV.children Transform2D { + translation 110 38 + children [ + Shape { + appearance Appearance { + material DEF TXTMAT Material2D { + emissiveColor 0.1 0 0.1 + filled TRUE + transparency 1 + } + } + geometry Text { + string ["sm"] + fontStyle DEF FS FontStyle { + justify ["BEGIN" "BEGIN"] + size 160 + } + } + } + ] + } + APPEND TO MOV.children Transform2D { + scale 0.3 0.3 + translation 340 -70 + children [ + USE LOGO + ] + } + APPEND TO MOV.children Transform2D { + translation 380 38 + children [ + Shape { + appearance Appearance { + material USE TXTMAT + } + geometry Text { + string ["4"] + fontStyle USE FS + } + } + ] + } + APPEND TO MOV.children DEF TIME4 TimeSensor { + cycleInterval 1.5 + } + APPEND TO MOV.children DEF POS_MOV PositionInterpolator2D { + key [0 0.5 1] + keyValue [0 0 75 0 -75 0] + } + APPEND TO MOV.children DEF SCALE_MOV PositionInterpolator2D { + key [0 0.5 1] + keyValue [1 1 0.4 0.4 0.4 0.4] + } + APPEND TO MOV.children DEF ALPHA2 ScalarInterpolator { + key [0 0.9 1] + keyValue [0.95 0.5 0] + } + INSERT ROUTE DEF R1 TIME4.fraction_changed TO POS_MOV.set_fraction + INSERT ROUTE DEF R2 TIME4.fraction_changed TO SCALE_MOV.set_fraction + INSERT ROUTE DEF R3 TIME4.fraction_changed TO ALPHA2.set_fraction + INSERT ROUTE DEF R4 POS_MOV.value_changed TO MOV.translation + INSERT ROUTE DEF R5 SCALE_MOV.value_changed TO MOV.scale + INSERT ROUTE DEF R6 ALPHA2.value_changed TO TXTMAT.transparency +} + +AT 7000 { + DELETE ROUTE R1 + DELETE ROUTE R2 + DELETE ROUTE R3 + DELETE ROUTE R4 + DELETE ROUTE R5 + DELETE ROUTE R6 + DELETE TIME4 + DELETE ALPHA2 + DELETE POS_MOV + DELETE SCALE_MOV + REPLACE TXTMAT.transparency BY 0.5 + REPLACE MOV.translation BY -75 0 + REPLACE MOV.scale BY 0.4 0.4 + + APPEND TO LOGO.children Transform2D { + children [ + DEF TS TimeSensor { + cycleInterval 4 + loop TRUE + } + DEF PI PositionInterpolator2D { + key [0 0.25 0.5 0.75 1] + keyValue [1 1 -1 1 1 1 1 -1 1 1] + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 0.8 0] + } + ] + } + INSERT ROUTE TS.fraction_changed TO PI.set_fraction + INSERT ROUTE TS.fraction_changed TO SI.set_fraction + INSERT ROUTE PI.value_changed TO LOGO.scale + INSERT ROUTE SI.value_changed TO TXTMAT.transparency +} + diff --git a/regression_tests/bifs/bifs-command-delete-index.bt b/regression_tests/bifs/bifs-command-delete-index.bt new file mode 100644 index 0000000..383d848 --- /dev/null +++ b/regression_tests/bifs/bifs-command-delete-index.bt @@ -0,0 +1,58 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows indexed value deletion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Indexed Value delete test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + Transform2D { + scale 0.5 0.5 + children [ + DEF S Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + DELETE COORD.point[0] +} + diff --git a/regression_tests/bifs/bifs-command-delete-node.bt b/regression_tests/bifs/bifs-command-delete-node.bt new file mode 100644 index 0000000..6454af8 --- /dev/null +++ b/regression_tests/bifs/bifs-command-delete-node.bt @@ -0,0 +1,58 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows node deletion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Node delete test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + Transform2D { + scale 0.5 0.5 + children [ + DEF S Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + DELETE MAT +} + diff --git a/regression_tests/bifs/bifs-command-delete-route.bt b/regression_tests/bifs/bifs-command-delete-route.bt new file mode 100644 index 0000000..bab08b6 --- /dev/null +++ b/regression_tests/bifs/bifs-command-delete-route.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows route deletion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Route delete test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + DEF TS TimeSensor { + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +DEF R1 ROUTE SI.value_changed TO MAT.transparency + +AT 2500 { + DELETE ROUTE R1 +} + diff --git a/regression_tests/bifs/bifs-command-global-qp.bt b/regression_tests/bifs/bifs-command-global-qp.bt new file mode 100644 index 0000000..b9d929c --- /dev/null +++ b/regression_tests/bifs/bifs-command-global-qp.bt @@ -0,0 +1,66 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +DEF OG OrderedGroup { + children [ + WorldInfo { + info ["This shows GlobalQuantizer usage" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "GlobalQuantizer test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + ] +} + + +AT 100 { + GLOBALQP QuantizationParameter { + position2DQuant TRUE + position2DMin -100 -100 + position2DMax 100 100 + position2DNbBits 2 + } +} + +AT 1000 { + APPEND TO OG.children DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } +} + diff --git a/regression_tests/bifs/bifs-command-insert-index.bt b/regression_tests/bifs/bifs-command-insert-index.bt new file mode 100644 index 0000000..2f2aeff --- /dev/null +++ b/regression_tests/bifs/bifs-command-insert-index.bt @@ -0,0 +1,58 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows indexed value insertion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Indexed Value insert test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + Transform2D { + scale 0.5 0.5 + children [ + DEF S Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + INSERT AT COORD.point[0] -50 -50 +} + diff --git a/regression_tests/bifs/bifs-command-insert-node.bt b/regression_tests/bifs/bifs-command-insert-node.bt new file mode 100644 index 0000000..2e61ce6 --- /dev/null +++ b/regression_tests/bifs/bifs-command-insert-node.bt @@ -0,0 +1,74 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +DEF OG OrderedGroup { + children [ + WorldInfo { + info ["This shows node insertion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Node insert test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + DEF S Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + INSERT AT OG.children[0] Transform2D { + scale 0.5 0.5 + translation -100 -50 + children [ + USE S + ] + } +} + +AT 4000 { + APPEND TO OG.children Transform2D { + scale 0.5 0.5 + translation 100 50 + children [ + USE S + ] + } +} + diff --git a/regression_tests/bifs/bifs-command-insert-nodedef.bt b/regression_tests/bifs/bifs-command-insert-nodedef.bt new file mode 100644 index 0000000..5ae9c48 --- /dev/null +++ b/regression_tests/bifs/bifs-command-insert-nodedef.bt @@ -0,0 +1,64 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +DEF OG OrderedGroup { + children [ + WorldInfo { + info ["This shows node insertion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Node insert test" + } + Background2D { + backColor 1 1 1 + } + Transform2D { + scale 0.5 0.5 + children [ + DEF S Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + INSERT AT OG.children[0] DEF TR2 Transform2D { + scale 0.5 0.5 + translation -100 -50 + children [ + USE S + ] + } +} + diff --git a/regression_tests/bifs/bifs-command-insert-route.bt b/regression_tests/bifs/bifs-command-insert-route.bt new file mode 100644 index 0000000..715f520 --- /dev/null +++ b/regression_tests/bifs/bifs-command-insert-route.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows route insertion" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "route insert test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + DEF TS TimeSensor { + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +DEF R1 ROUTE SI.value_changed TO MAT.transparency + +AT 2000 { + INSERT ROUTE SI.value_changed TO TR.rotationAngle +} + diff --git a/regression_tests/bifs/bifs-command-multiple-replace-field.bt b/regression_tests/bifs/bifs-command-multiple-replace-field.bt new file mode 100644 index 0000000..215d8d5 --- /dev/null +++ b/regression_tests/bifs/bifs-command-multiple-replace-field.bt @@ -0,0 +1,66 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + includeInlineProfileLevelFlag true + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows multiple field replacement" "through BIFS extended commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "multiple field replace test" + } + DEF N0 Background2D { + backColor 1 1 1 + } + DEF N1 Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF N2 Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF N3 Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 1000 { + MULTIPLEREPLACE N2 { + emissiveColor 0 1 0 + transparency 0.9 + lineProps LineProperties { + lineColor 0 0 1 + width 2 + } + } +} + diff --git a/regression_tests/bifs/bifs-command-multiple-replace-index.bt b/regression_tests/bifs/bifs-command-multiple-replace-index.bt new file mode 100644 index 0000000..7022891 --- /dev/null +++ b/regression_tests/bifs/bifs-command-multiple-replace-index.bt @@ -0,0 +1,62 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows multiple indexed field replacement" "through BIFS Extended commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "multiple indexed field replace test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + MULTIPLEINDREPLACE COORD.point [ + 0 BY -20 0 + 2 BY 50 50 + 5 BY -50 -80 + ] +} + diff --git a/regression_tests/bifs/bifs-command-node-delete-ex.bt b/regression_tests/bifs/bifs-command-node-delete-ex.bt new file mode 100644 index 0000000..f74fbd0 --- /dev/null +++ b/regression_tests/bifs/bifs-command-node-delete-ex.bt @@ -0,0 +1,125 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows extended node deletion" "through BIFS extended commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Node delete test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF OG OrderedGroup { + order [2 1 3] + children [ + DEF TR Transform2D { + scale 0.5 0.5 + children [ + DEF S Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + Transform2D { + translation -50 40 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 1 + filled TRUE + } + } + geometry Circle { + radius 30 + } + } + ] + } + Transform2D { + translation 50 -50 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 1 + filled TRUE + } + } + geometry Rectangle { + size 100 50 + } + } + ] + } + ] + } + Transform2D { + translation 0 -100 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + string ["test"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 24 + } + } + } + ] + } + DEF SC Script { + eventIn SFTime set_text + field SFNode t USE TXT + field SFNode g USE OG + url ["javascript: function set_text(value, ts) {t.string[0] = 'order: ' + g.order;}" ] + } + DEF TS TimeSensor { + loop TRUE + } + ] +} + +ROUTE TS.cycleTime TO SC.set_text + +AT 2000 { + XDELETE TR +} + diff --git a/regression_tests/bifs/bifs-command-proto-delete.bt b/regression_tests/bifs/bifs-command-proto-delete.bt new file mode 100644 index 0000000..5943639 --- /dev/null +++ b/regression_tests/bifs/bifs-command-proto-delete.bt @@ -0,0 +1,93 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +PROTO MYPROTO [ + exposedField SFVec2f translation 0 0 +] { + Transform2D { + translation IS translation + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + ] + } +} +PROTO MYOTHERPROTO [ + exposedField SFVec2f translation 0 0 +] { + Transform2D { + translation IS translation + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 50 + } + } + ] + } +} +DEF ORD OrderedGroup { + children [ + DEF BACK Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows proto declaration deletion" "through BIFS Extended commands" "The player should complain about unknown proto" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Proto Delete test" + } + MYPROTO {} + ] +} + + +AT 1000 { + DELETEPROTO ALL +} + +AT 2000 { + INSERT AT ORD.children[2] MYPROTO { + translation -100 0 + } +} + +AT 3000 { + INSERT AT ORD.children[2] MYOTHERPROTO { + translation 100 0 + } +} + diff --git a/regression_tests/bifs/bifs-command-proto-insert.bt b/regression_tests/bifs/bifs-command-proto-insert.bt new file mode 100644 index 0000000..7c0d9e5 --- /dev/null +++ b/regression_tests/bifs/bifs-command-proto-insert.bt @@ -0,0 +1,83 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +DEF ORD OrderedGroup { + children [ + DEF BACK Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows proto declaration insertion" "through BIFS Extended commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Proto Insert test" + } + DEF TR Transform2D { + scale 0.5 0.5 + translation -100 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 1000 { + INSERTPROTO [ + PROTO MYPROTO [ + exposedField SFVec2f translation 0 0 + ] { + Transform2D { + translation IS translation + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + ] + } + } + ] + INSERT AT ORD.children[0] MYPROTO { + translation 100 0 + } +} + diff --git a/regression_tests/bifs/bifs-command-protolist-delete.bt b/regression_tests/bifs/bifs-command-protolist-delete.bt new file mode 100644 index 0000000..5985443 --- /dev/null +++ b/regression_tests/bifs/bifs-command-protolist-delete.bt @@ -0,0 +1,93 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +PROTO MYPROTO [ + exposedField SFVec2f translation 0 0 +] { + Transform2D { + translation IS translation + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } + ] + } +} +PROTO MYOTHERPROTO [ + exposedField SFVec2f translation 0 0 +] { + Transform2D { + translation IS translation + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 50 + } + } + ] + } +} +DEF ORD OrderedGroup { + children [ + DEF BACK Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows proto declaration list deletion" "through BIFS Extended commands" "The player should complain about unknown nodes" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Proto List Delete test" + } + MYPROTO {} + ] +} + + +AT 1000 { + DELETEPROTO [MYPROTO] +} + +AT 2000 { + INSERT AT ORD.children[0] MYPROTO { + translation -100 0 + } +} + +AT 3000 { + INSERT AT ORD.children[0] MYOTHERPROTO { + translation 100 0 + } +} + diff --git a/regression_tests/bifs/bifs-command-quantification.bt b/regression_tests/bifs/bifs-command-quantification.bt new file mode 100644 index 0000000..dd62a05 --- /dev/null +++ b/regression_tests/bifs/bifs-command-quantification.bt @@ -0,0 +1,186 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows quantification of IFS2D" "with several values" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Quantification Test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + QuantizationParameter { + position2DQuant TRUE + position2DMin -100 -100 + position2DMax 100 100 + position2DNbBits 9 + colorQuant FALSE + } + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + REPLACE TR BY DEF TR1 Transform2D { + scale 0.5 0.5 + children [ + QuantizationParameter { + position2DQuant TRUE + position2DMin -100 -100 + position2DMax 100 100 + position2DNbBits 8 + colorQuant FALSE + } + Shape { + appearance Appearance { + material USE MAT + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } +} + +AT 4000 { + REPLACE TR1 BY DEF TR2 Transform2D { + scale 0.5 0.5 + children [ + QuantizationParameter { + position2DQuant TRUE + position2DMin -100 -100 + position2DMax 100 100 + position2DNbBits 6 + colorQuant FALSE + } + Shape { + appearance Appearance { + material USE MAT + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } +} + +AT 6000 { + REPLACE TR2 BY DEF TR3 Transform2D { + scale 0.5 0.5 + children [ + QuantizationParameter { + position2DQuant TRUE + position2DMin -100 -100 + position2DMax 100 100 + position2DNbBits 4 + colorQuant FALSE + } + Shape { + appearance Appearance { + material USE MAT + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } +} + +AT 8000 { + REPLACE TR3 BY DEF TR4 Transform2D { + scale 0.5 0.5 + children [ + QuantizationParameter { + position2DQuant TRUE + position2DMin -100 -100 + position2DMax 100 100 + position2DNbBits 2 + colorQuant FALSE + } + Shape { + appearance Appearance { + material USE MAT + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } +} + +AT 10000 { + REPLACE TR4 BY DEF TR5 Transform2D { + scale 0.5 0.5 + children [ + QuantizationParameter { + position2DQuant TRUE + position2DMin -100 -100 + position2DMax 100 100 + position2DNbBits 1 + colorQuant FALSE + } + Shape { + appearance Appearance { + material USE MAT + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } +} + diff --git a/regression_tests/bifs/bifs-command-replace-field.bt b/regression_tests/bifs/bifs-command-replace-field.bt new file mode 100644 index 0000000..c76ff89 --- /dev/null +++ b/regression_tests/bifs/bifs-command-replace-field.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info [ + "This test shows field replacement using BIFS commands." + "At initialization, the scene shows a polygon filled in red" + "At 2s, the scene is modified and the polygon is not filled, just the border is diplayed." + "The command used in this sequence replaces the content of the field and not just a single value" + "It applies to both SFField and MFField, for replacement of single value in an MFField, use Indexed Replacement" + "cf bifs-command-replace-index" + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" + "(C) 2002-2004 GPAC Team"] + title "Field Replacement" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + REPLACE MAT.filled BY FALSE +} + diff --git a/regression_tests/bifs/bifs-command-replace-index.bt b/regression_tests/bifs/bifs-command-replace-index.bt new file mode 100644 index 0000000..4c17c46 --- /dev/null +++ b/regression_tests/bifs/bifs-command-replace-index.bt @@ -0,0 +1,58 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows indexed value replacement" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Indexed Value replace test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + REPLACE COORD.point[2] BY 100 100 +} + diff --git a/regression_tests/bifs/bifs-command-replace-node-null.bt b/regression_tests/bifs/bifs-command-replace-node-null.bt new file mode 100644 index 0000000..8d58522 --- /dev/null +++ b/regression_tests/bifs/bifs-command-replace-node-null.bt @@ -0,0 +1,65 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info [ + "This test shows a BIFS command replacing a node by the NULL node" + "Initially, the scene has a white background but at 2s, the Background2D node is replaced by a NULL node. Since the Background2D node is not used anymore, it is deleted." + "Replacing with a NULL node does not change the index of the following siblings." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Node Replacement with a NULL node" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + REPLACE BACK BY NULL +} + diff --git a/regression_tests/bifs/bifs-command-replace-node.bt b/regression_tests/bifs/bifs-command-replace-node.bt new file mode 100644 index 0000000..c32fdb9 --- /dev/null +++ b/regression_tests/bifs/bifs-command-replace-node.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info [ + "This test shows node replacement through BIFS commands" + "Initally, the scene has a white background, but at 2s the Background2D node is replaced by a new node defining a yellow background." + "The same test could be done replacing the field backColor of the Background2D node, this would be a field replacement." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Node Replacement" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + +AT 2000 { + REPLACE BACK BY Background2D { + backColor 0 1 1 + } +} + diff --git a/regression_tests/bifs/bifs-command-replace-route.bt b/regression_tests/bifs/bifs-command-replace-route.bt new file mode 100644 index 0000000..692f331 --- /dev/null +++ b/regression_tests/bifs/bifs-command-replace-route.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows route replacement" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "route replace test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + DEF TS TimeSensor { + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +DEF R1 ROUTE SI.value_changed TO MAT.transparency + +AT 2000 { + REPLACE ROUTE R1 BY SI.value_changed TO TR.rotationAngle +} + diff --git a/regression_tests/bifs/bifs-command-replace-scene-null.bt b/regression_tests/bifs/bifs-command-replace-scene-null.bt new file mode 100644 index 0000000..7b18bb8 --- /dev/null +++ b/regression_tests/bifs/bifs-command-replace-scene-null.bt @@ -0,0 +1,37 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + objectTypeIndication 1 + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 0 + } + WorldInfo { + info ["This shows scene replacement" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "scene replace test" + } + ] +} + + +AT 2000 { + REPLACE SCENE BY NULL + +} + diff --git a/regression_tests/bifs/bifs-command-replace-scene.bt b/regression_tests/bifs/bifs-command-replace-scene.bt new file mode 100644 index 0000000..361bac3 --- /dev/null +++ b/regression_tests/bifs/bifs-command-replace-scene.bt @@ -0,0 +1,76 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 0 + } + WorldInfo { + info [ + "This test shows scene replacement using BIFS commands." + "At initialization, the scene is empty, only a yellow background." + "At 2s, the whole scene is replaced by a new one containing a red polygon." + "All resources belonging to the previous scene are reclaimed." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" + "(C) 2002-2004 GPAC Team"] + title "Scene Replacement" + } + ] +} + + +AT 2000 { + REPLACE SCENE BY OrderedGroup { + children [ + WorldInfo { + info ["This shows scene replacement" "through BIFS commands" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "scene replace test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] + } + +} + diff --git a/regression_tests/bifs/bifs-command-route-add-children.bt b/regression_tests/bifs/bifs-command-route-add-children.bt new file mode 100644 index 0000000..516435b --- /dev/null +++ b/regression_tests/bifs/bifs-command-route-add-children.bt @@ -0,0 +1,79 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +DEF OG OrderedGroup { + children [ + WorldInfo { + info ["This shows node routing" "through addChildren field" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Node Routing test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR1 Transform2D { + translation -100 0 + } + DEF TR2 Transform2D { + translation 100 0 + } + ] +} + +ROUTE TR1.children TO TR2.addChildren + +AT 2000 { + APPEND TO TR1.children Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 50 + } + } +} + +AT 4000 { + REPLACE M1.filled BY FALSE +} + +AT 6000 { + REPLACE TR1.children[0] BY NULL +} + +AT 8000 { + APPEND TO TR1.children Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } +} + diff --git a/regression_tests/bifs/bifs-command-route-children.bt b/regression_tests/bifs/bifs-command-route-children.bt new file mode 100644 index 0000000..5ea4706 --- /dev/null +++ b/regression_tests/bifs/bifs-command-route-children.bt @@ -0,0 +1,79 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 300 + } + } + } + ] +} + +DEF OG OrderedGroup { + children [ + WorldInfo { + info ["This shows node routing" "through children field" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Node duplicate test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR1 Transform2D { + translation -100 0 + } + DEF TR2 Transform2D { + translation 100 0 + } + ] +} + +ROUTE TR1.children TO TR2.children + +AT 2000 { + APPEND TO TR1.children Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 50 + } + } +} + +AT 4000 { + REPLACE M1.filled BY FALSE +} + +AT 6000 { + REPLACE TR1.children[0] BY NULL +} + +AT 8000 { + APPEND TO TR1.children Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 25 + } + } +} + diff --git a/regression_tests/bifs/bifs-command-route-node-exposedfield.bt b/regression_tests/bifs/bifs-command-route-node-exposedfield.bt new file mode 100644 index 0000000..0210d78 --- /dev/null +++ b/regression_tests/bifs/bifs-command-route-node-exposedfield.bt @@ -0,0 +1,80 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +DEF OG OrderedGroup { + children [ + WorldInfo { + info ["This shows exposed field routing" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Field Routing Test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + Transform2D { + translation -100 0 + children [ + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 50 + } + } + ] + } + Transform2D { + translation 100 0 + children [ + Shape { + appearance Appearance { + material DEF M2 Material2D { + emissiveColor 1 1 0 + } + } + geometry Circle { + radius 50 + } + } + ] + } + ] +} + +ROUTE M1.filled TO M2.filled + +AT 2000 { + REPLACE M1.filled BY TRUE +} + +AT 4000 { + REPLACE M1.filled BY FALSE +} + +AT 6000 { + REPLACE M2.filled BY TRUE +} + diff --git a/regression_tests/bifs/bifs-command-route-node.bt b/regression_tests/bifs/bifs-command-route-node.bt new file mode 100644 index 0000000..a6e9d21 --- /dev/null +++ b/regression_tests/bifs/bifs-command-route-node.bt @@ -0,0 +1,76 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +DEF OG OrderedGroup { + children [ + WorldInfo { + info ["This shows node routing" "through exposed fields" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Node routing test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + Transform2D { + translation -100 0 + children [ + Shape { + appearance DEF APP1 Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 50 + } + } + ] + } + Transform2D { + translation 100 0 + children [ + Shape { + appearance DEF APP2 Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Circle { + radius 50 + } + } + ] + } + ] +} + +ROUTE APP1.material TO APP2.material + +AT 2000 { + REPLACE APP1.material BY Material2D { + emissiveColor 1 0 1 + filled TRUE + } +} + diff --git a/regression_tests/bifs/bifs-command-route-remove-children.bt b/regression_tests/bifs/bifs-command-route-remove-children.bt new file mode 100644 index 0000000..2037c05 --- /dev/null +++ b/regression_tests/bifs/bifs-command-route-remove-children.bt @@ -0,0 +1,93 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +DEF OG OrderedGroup { + children [ + WorldInfo { + info ["This shows node deletion" "through removeChildren field" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Node delete test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR1 Transform2D { + translation -100 0 + } + DEF TR2 Transform2D { + translation 100 0 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Circle { + radius 50 + } + } + ] + } + ] +} + +DEF R1 ROUTE TR1.children TO TR2.addChildren + +AT 2000 { + APPEND TO TR1.children Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 50 + } + } +} + +AT 3000 { + DELETE ROUTE R1 + INSERT ROUTE TR1.children TO TR2.removeChildren +} + +AT 4000 { + APPEND TO TR1.children Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 1 + filled TRUE + } + } + geometry Circle { + radius 20 + } + } +} + +AT 100000 { + DELETE ROUTE R1 +} + diff --git a/regression_tests/bifs/bifs-externproto-forestgump-lib.bt b/regression_tests/bifs/bifs-externproto-forestgump-lib.bt new file mode 100644 index 0000000..d6123e8 --- /dev/null +++ b/regression_tests/bifs/bifs-externproto-forestgump-lib.bt @@ -0,0 +1,463 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO FORESTGUMP [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFFloat lineWidth 3 + exposedField SFColor lineColor 0.121569 0.101961 0.0901961 + exposedField SFTime runTime 1 + exposedField SFBool loop TRUE + exposedField SFTime start 0 +] { + Transform2D { + rotationAngle IS rotation + scale IS scale + translation IS translation + children [ + DEF MYSWITCH Switch { + whichChoice 0 + choice [ + Transform2D { + scale 0.0899561 0.0900365 + translation 260.243 42.9024 + children [ + Transform2D { + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + geometry Curve2D { + type [1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-2827 -11 -2864 -2 -2864 -2 -2883 -2 -2883 -2 -2892 -2 -2901 -11 -2911 -11 -2920 -11 -2929 -20 -2939 -29 -2939 -29 -2957 -48 -2957 -48 -2966 -57 -2957 -57 -2966 -76 -2966 -85 -2976 -95 -2976 -104 -2976 -104 -2976 -132 -2976 -132 -2976 -132 -2976 -160 -2976 -160 -2966 -178 -2957 -188 -2957 -188 -2957 -188 -2939 -197 -2939 -197 -2939 -197 -2920 -197 -2920 -197 -2920 -197 -2911 -206 -2911 -206 -2911 -206 -2892 -206 -2892 -206 -2892 -206 -2873 -206 -2873 -206 -2873 -206 -2855 -215 -2855 -215 -2855 -215 -2836 -215 -2836 -215 -2836 -215 -2827 -206 -2827 -206 -2827 -206 -2808 -197 -2808 -197 -2799 -188 -2799 -188 -2790 -178 -2790 -178 -2790 -169 -2790 -169 -2780 -160 -2780 -160 -2771 -150 -2771 -150 -2771 -141 -2771 -141 -2771 -132 -2771 -132 -2771 -122 -2771 -122 -2771 -113 -2771 -113 -2771 -104 -2771 -104 -2771 -95 -2771 -95 -2771 -85 -2771 -85 -2771 -76 -2780 -57 -2780 -48 -2780 -48 -2790 -29 -2790 -29 -2790 -29 -2808 -20 -2808 -20 -2808 -20 -2818 -11 -2818 -11 -2827 -2 -2827 -2 -2836 -2 -2836 -2 -2846 -2 -2855 -2 -2873 -2 -2883 -2] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 2 1 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-2883 -225 -2883 -262 -2883 -262 -2883 -281 -2883 -281 -2883 -290 -2883 -299 -2883 -308 -2883 -327 -2883 -327 -2892 -336 -2892 -336 -2892 -336 -2892 -383 -2892 -392 -2892 -401 -2892 -429 -2892 -439 -2892 -439 -2892 -467 -2892 -467 -2892 -467 -2892 -485 -2892 -485 -2901 -485 -2901 -485 -2901 -494 -2901 -494 -2901 -504 -2901 -513 -2901 -532 -2901 -541] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-3004 -755 -2994 -727 -2985 -708 -2976 -690 -2976 -680 -2976 -643 -2976 -643 -2957 -625 -3004 -653 -3004 -653 -3004 -653 -3115 -718 -3115 -708 -3115 -662 -3032 -541 -2957 -541 -2939 -541 -2901 -522 -2883 -541 -2883 -541 -2855 -560 -2855 -560 -2846 -569 -2818 -587 -2818 -606 -2818 -625 -2790 -662 -2790 -708 -2790 -773 -2799 -848 -2799 -913 -2799 -931 -2808 -931 -2808 -950 -2808 -959 -2790 -931 -2790 -931 -2780 -904 -2743 -857 -2734 -829 -2734 -820 -2697 -773 -2706 -773] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-2985 -346 -2994 -346 -3022 -374 -3032 -374 -3041 -374 -3050 -383 -3050 -392 -3050 -392 -3134 -392 -3143 -392 -3152 -392 -3134 -364 -3134 -364 -3134 -364 -3106 -346 -3106 -346 -3097 -336 -2985 -253 -2957 -253 -2939 -253 -2920 -271 -2911 -271 -2901 -271 -2873 -281 -2864 -281 -2836 -271 -2790 -234 -2771 -225 -2762 -225 -2734 -206 -2725 -197 -2715 -188 -2669 -160 -2669 -160 -2660 -160 -2660 -150 -2660 -169 -2660 -206 -2641 -262 -2641 -299] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0900093 0.0899546 + translation 190.415 42.8184 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-2083 -20 -2120 -20 -2120 -20 -2130 -20 -2130 -20 -2139 -20 -2139 -20 -2148 -20 -2148 -20 -2148 -20 -2167 -20 -2167 -20 -2167 -20 -2195 -30 -2195 -30 -2195 -30 -2204 -48 -2213 -58 -2213 -58 -2232 -67 -2241 -76 -2241 -76 -2241 -113 -2241 -113 -2241 -113 -2250 -132 -2250 -141 -2250 -151 -2241 -169 -2241 -169 -2241 -179 -2223 -188 -2223 -188 -2223 -188 -2213 -216 -2204 -216 -2195 -216 -2195 -225 -2185 -225 -2185 -225 -2157 -225 -2157 -225 -2157 -225 -2139 -225 -2139 -225 -2139 -225 -2120 -225 -2120 -225 -2120 -225 -2111 -216 -2111 -216 -2111 -216 -2092 -216 -2092 -216 -2092 -216 -2074 -206 -2074 -206 -2074 -206 -2064 -197 -2064 -197 -2064 -197 -2055 -179 -2055 -179 -2046 -179 -2046 -179 -2046 -169 -2046 -169 -2037 -160 -2037 -160 -2037 -151 -2037 -151 -2037 -141 -2037 -141 -2037 -132 -2037 -132 -2037 -123 -2037 -123 -2037 -113 -2037 -113 -2037 -104 -2037 -104 -2037 -95 -2037 -95 -2037 -95 -2037 -76 -2037 -76 -2037 -76 -2055 -39 -2055 -39 -2055 -39 -2074 -30 -2074 -30 -2074 -30 -2092 -20 -2092 -20 -2092 -20 -2102 -11 -2102 -11 -2111 -11 -2111 -11 -2120 -11 -2120 -11 -2120 -2 -2120 -2 -2157 -2 -2157 -2] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-2130 -244 -2130 -290 -2130 -318 -2130 -355 -2130 -383 -2130 -402 -2139 -420 -2139 -439 -2139 -448 -2139 -476 -2139 -485 -2139 -495 -2139 -504 -2139 -513 -2139 -523 -2139 -523 -2139 -532 -2139 -532 -2139 -541 -2139 -541 -2130 -551 -2130 -551] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-2306 -792 -2269 -764 -2232 -718 -2204 -690 -2195 -681 -2204 -690 -2213 -690 -2241 -681 -2325 -671 -2343 -653 -2343 -653 -2362 -644 -2362 -644 -2371 -634 -2278 -569 -2278 -569 -2241 -560 -2213 -551 -2176 -551 -2139 -551 -2027 -578 -2027 -616 -2027 -625 -2018 -625 -2018 -634 -1999 -671 -1999 -709 -1999 -755 -1999 -811 -2074 -904 -2111 -922 -2148 -941 -2139 -950 -2102 -950 -2064 -950 -2009 -950 -1971 -950] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-2223 -402 -2260 -420 -2325 -439 -2353 -411 -2371 -392 -2381 -374 -2381 -355 -2381 -318 -2371 -290 -2343 -281 -2306 -262 -2232 -244 -2185 -244 -2176 -244 -2139 -225 -2130 -225 -2120 -225 -2046 -234 -2027 -234 -1981 -234 -1897 -253 -1878 -299 -1869 -318 -1851 -346 -1851 -383 -1851 -411 -1860 -448 -1860 -467] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0899291 0.0900198 + translation 123.698 44.4248 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 1 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-1283 -11 -1320 -11 -1320 -11 -1330 -11 -1330 -11 -1339 -11 -1339 -11 -1348 -11 -1348 -11 -1348 -11 -1367 -11 -1367 -11 -1367 -20 -1367 -20 -1376 -20 -1376 -20 -1376 -20 -1413 -39 -1413 -39 -1413 -39 -1432 -76 -1432 -76 -1432 -85 -1441 -104 -1441 -113 -1441 -123 -1451 -141 -1451 -151 -1451 -169 -1451 -160 -1441 -169 -1441 -169 -1432 -188 -1432 -188 -1432 -188 -1423 -206 -1423 -206 -1423 -206 -1404 -216 -1404 -216 -1395 -216 -1386 -225 -1376 -225 -1376 -225 -1348 -225 -1348 -225 -1348 -225 -1330 -225 -1330 -225 -1330 -225 -1311 -225 -1311 -225 -1311 -225 -1293 -216 -1293 -216 -1293 -216 -1283 -206 -1283 -206 -1283 -206 -1265 -197 -1265 -197 -1265 -197 -1255 -188 -1255 -188 -1255 -188 -1246 -169 -1246 -169 -1237 -169 -1237 -169 -1237 -160 -1237 -160 -1237 -151 -1237 -151 -1237 -141 -1237 -141 -1237 -132 -1237 -132 -1237 -123 -1237 -123 -1237 -113 -1237 -113 -1237 -104 -1237 -104 -1237 -95 -1237 -95 -1237 -85 -1237 -85 -1237 -85 -1237 -67 -1237 -67 -1237 -67 -1255 -48 -1255 -39 -1255 -39 -1265 -20 -1265 -20 -1265 -20 -1283 -11 -1283 -11 -1283 -11 -1302 -2 -1302 -2 -1311 -2 -1311 -2 -1320 -2 -1320 -2 -1330 -2 -1339 -2 -1358 -2 -1367 -2] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 1 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-1311 -234 -1311 -271 -1311 -271 -1311 -281 -1311 -281 -1311 -299 -1311 -318 -1311 -355 -1311 -374 -1311 -392 -1311 -430 -1311 -448 -1311 -457 -1311 -485 -1311 -495 -1311 -495 -1311 -513 -1311 -513 -1311 -523 -1311 -523 -1311 -532 -1311 -532 -1311 -541 -1311 -560 -1311 -578 -1311 -560] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-1572 -662 -1534 -709 -1469 -755 -1441 -783 -1423 -802 -1451 -764 -1451 -764 -1460 -736 -1506 -578 -1469 -560 -1451 -550 -1330 -597 -1320 -597 -1293 -606 -1274 -616 -1274 -662 -1274 -690 -1274 -727 -1283 -746 -1283 -755 -1293 -792 -1302 -811 -1339 -885 -1274 -904 -1274 -987] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2] + point Coordinate2D { + point [-1609 -541 -1618 -467 -1599 -504 -1590 -448 -1562 -309 -1423 -253 -1283 -253 -1237 -253 -1144 -281 -1144 -327 -1144 -346 -1135 -355 -1144 -374 -1153 -392 -1227 -467 -1227 -485] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0899947 0.0899257 + translation 62.0964 37.7238 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 1 2 1 2 1] + point Coordinate2D { + point [-511 -30 -549 -30 -567 -30 -577 -30 -586 -30 -604 -48 -604 -48 -614 -48 -623 -67 -623 -76 -623 -86 -642 -76 -642 -95 -642 -95 -642 -123 -642 -123 -642 -132 -642 -141 -642 -151 -642 -160 -623 -179 -623 -179 -623 -179 -614 -188 -614 -188 -614 -188 -595 -188 -595 -188 -595 -188 -586 -197 -586 -197 -586 -197 -567 -197 -567 -197 -567 -197 -549 -207 -549 -207 -549 -207 -539 -197 -539 -197 -539 -197 -521 -197 -521 -197 -521 -197 -502 -188 -502 -188 -493 -179 -493 -179 -484 -169 -484 -169 -474 -169 -474 -169 -474 -160 -474 -160 -465 -160 -465 -160 -465 -151 -465 -151 -465 -141 -465 -141 -465 -132 -465 -132 -456 -132 -456 -132 -456 -114 -456 -114 -456 -86 -465 -86 -465 -86 -465 -86 -474 -67 -474 -58 -474 -48 -484 -48 -484 -39 -484 -39 -493 -21 -493 -21 -502 -21 -502 -21 -511 -11 -511 -11 -521 -2 -521 -2 -558 -2 -511 -30 -521 -2] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 1 2 2] + point Coordinate2D { + point [-539 -225 -539 -262 -549 -281 -549 -318 -549 -337 -558 -355 -558 -374 -558 -383 -558 -411 -558 -430 -558 -439 -558 -448 -558 -467 -558 -476 -558 -504 -567 -513 -558 -523] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 1 2 2 2 2 2] + point Coordinate2D { + point [-865 -551 -865 -569 -846 -653 -846 -672 -846 -690 -837 -699 -837 -709 -837 -718 -828 -718 -828 -709 -828 -681 -763 -606 -735 -588 -716 -579 -651 -541 -632 -541 -577 -541 -521 -532 -465 -560 -446 -569 -400 -616 -381 -634 -381 -634 -353 -699 -372 -699 -400 -699 -428 -672 -428 -672 -437 -672 -437 -672 -474 -653 -474 -653 -484 -653 -493 -662 -493 -672 -493 -690 -502 -755 -502 -774 -502 -783 -502 -792 -493 -811 -484 -830 -474 -848 -474 -830] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2] + point Coordinate2D { + point [-1023 -365 -976 -318 -930 -300 -874 -272 -865 -272 -837 -253 -828 -253 -716 -216 -577 -262 -456 -262 -428 -262 -335 -318 -363 -346 -372 -355 -437 -346 -456 -346 -456 -346 -511 -337 -511 -337 -530 -337 -539 -318 -549 -318] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0899962 0.0899977 + translation -16.1993 42.7489 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [279 -20 260 -20 232 -1 223 -1 214 -1 205 -20 195 -20 186 -20 167 -29 167 -39 167 -48 149 -66 149 -76 139 -94 139 -94 139 -113 139 -132 130 -141 130 -159 130 -169 139 -178 139 -187 139 -187 149 -206 149 -206 149 -206 158 -225 158 -225 158 -225 177 -234 177 -234 177 -234 195 -234 195 -234 195 -234 214 -234 214 -234 214 -234 232 -234 232 -234 242 -234 251 -225 260 -225 270 -225 270 -225 279 -215 279 -215 288 -215 288 -215 298 -206 298 -206 307 -197 307 -197 316 -187 316 -187 316 -178 316 -178 325 -169 325 -169 335 -159 335 -159 335 -141 335 -141 335 -132 335 -122 335 -113 335 -94 325 -85 325 -76 325 -76 325 -48 325 -48 325 -48 316 -29 316 -29 316 -29 298 -20 298 -20 288 -11 288 -11 279 -11 279 -11 270 -11 260 -11 232 -11 223 -11] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 1 2 1 2] + point Coordinate2D { + point [232 -252 232 -280 214 -327 214 -345 214 -364 205 -411 205 -429 205 -438 205 -466 205 -476 205 -494 205 -494 205 -513 205 -513 195 -531 195 -531 195 -569 195 -569] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 1 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [56 -848 65 -857 130 -913 149 -931 158 -941 186 -968 149 -913 149 -913 130 -866 130 -773 130 -717 130 -680 112 -662 112 -624 112 -578 139 -522 195 -522 260 -522 409 -531 409 -615 409 -615 428 -634 400 -634 372 -634 298 -615 279 -624 260 -634 279 -736 279 -755] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-56 -327 -46 -290 -37 -243 -28 -197 -28 -187 0 -159 9 -141 9 -132 19 -141 19 -150 28 -169 112 -243 149 -243 167 -243 214 -262 251 -262 279 -262 298 -252 316 -271 325 -280 353 -299 353 -299 353 -299 381 -327 391 -327 446 -355 325 -373 316 -373 279 -383 205 -373 177 -345] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0900707 0.0899924 + translation -85.7923 41.9814 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [1060 -20 1060 -20 1014 -2 1004 -2 995 -2 986 -11 976 -11 976 -11 949 -20 949 -20 939 -20 921 -48 921 -58 921 -58 902 -86 902 -86 902 -86 902 -104 902 -104 902 -113 902 -123 902 -132 902 -132 911 -151 911 -151 911 -151 921 -169 921 -169 921 -169 939 -188 939 -188 939 -188 949 -197 949 -197 949 -197 967 -206 967 -206 967 -206 986 -206 995 -206 1004 -206 1004 -206 1014 -206 1014 -206 1023 -206 1023 -206 1032 -206 1032 -206 1051 -197 1051 -197 1060 -197 1060 -197 1069 -188 1069 -188 1079 -179 1079 -179 1079 -169 1079 -169 1088 -169 1088 -169 1088 -169 1088 -151 1088 -151 1088 -141 1097 -123 1097 -104 1097 -86 1097 -86 1088 -67 1088 -67 1079 -48 1079 -48 1079 -48 1069 -39 1069 -39 1060 -30 1060 -30 1051 -30 1051 -30 1042 -20 1032 -20 1014 -11 1004 -11] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 1 2 1 2] + point Coordinate2D { + point [995 -225 995 -253 1014 -318 1014 -346 1014 -365 1014 -411 1014 -430 1014 -439 1014 -467 1014 -476 1014 -485 1014 -485 1014 -504 1014 -504 1014 -513 1014 -523 1014 -541 1023 -541] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 1 2 2 2 2 2 2] + point Coordinate2D { + point [809 -932 846 -932 893 -913 921 -913 958 -913 930 -895 930 -895 921 -895 893 -895 865 -774 865 -764 837 -699 921 -569 976 -541 1014 -523 1088 -578 1097 -588 1107 -597 1144 -625 1153 -634 1209 -690 1069 -644 1051 -662 1032 -681 1116 -792 1153 -792] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2] + point Coordinate2D { + point [688 -532 688 -485 716 -374 753 -355 800 -327 883 -262 939 -262 976 -262 1032 -281 1069 -262 1125 -234 1190 -309 1209 -327 1237 -355 1181 -383 1162 -402 1144 -420 1107 -448 1107 -476] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0899064 0.08998 + translation -164.619 43.1904 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 2 1 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [1878 -20 1851 -11 1841 -1 1813 -1 1804 -1 1804 -11 1795 -11 1785 -11 1767 -39 1767 -48 1758 -57 1739 -66 1739 -85 1739 -85 1739 -113 1739 -113 1739 -122 1748 -132 1748 -141 1748 -141 1758 -159 1758 -169 1758 -169 1767 -187 1767 -187 1767 -187 1776 -206 1776 -206 1776 -206 1785 -215 1785 -215 1785 -215 1804 -225 1804 -225 1804 -225 1823 -225 1823 -225 1823 -225 1841 -225 1841 -225 1841 -225 1860 -215 1860 -215 1869 -215 1869 -215 1878 -206 1878 -206 1888 -197 1888 -197 1897 -187 1897 -187 1906 -178 1906 -178 1916 -169 1916 -169 1916 -159 1916 -159 1925 -150 1925 -150 1925 -150 1925 -132 1925 -132 1925 -122 1925 -122 1934 -113 1934 -113 1934 -113 1934 -85 1925 -76 1925 -76 1906 -66 1906 -57 1906 -48 1906 -39 1897 -29 1897 -29 1878 -20 1878 -20 1869 -20 1869 -20 1860 -11 1860 -11 1851 -11 1841 -11 1823 -1 1804 -1] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 1 2 1 2] + point Coordinate2D { + point [1832 -234 1832 -271 1841 -327 1841 -364 1841 -383 1841 -411 1841 -429 1841 -429 1841 -466 1841 -466 1841 -466 1841 -485 1841 -485 1851 -485 1851 -485 1851 -494 1851 -494 1841 -494 1841 -494 1841 -531 1841 -531] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [1758 -959 1767 -931 1804 -894 1813 -866 1813 -857 1851 -792 1851 -792 1851 -792 1851 -792 1851 -792 1851 -792 1841 -801 1841 -801 1813 -829 1776 -708 1776 -699 1776 -662 1767 -606 1776 -578 1776 -578 1776 -550 1776 -550 1776 -550 1785 -559 1795 -559 1841 -559 1916 -550 1953 -513 1962 -504 1999 -485 1999 -485 1999 -485 2018 -466 2018 -466 2018 -466 2037 -457 2037 -457 2037 -457 2027 -457 2027 -457 2009 -476 1944 -606 1944 -652 1944 -652 1934 -680 1934 -680 1934 -680 1962 -662 1962 -662 1971 -652 2018 -615 2037 -606 2037 -606 2092 -597 2074 -597] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2] + point Coordinate2D { + point [1674 -476 1646 -448 1618 -411 1590 -383 1581 -373 1572 -345 1572 -345 1553 -327 1692 -262 1730 -252 1776 -243 1767 -225 1804 -243 1813 -243 1897 -243 1906 -243 1944 -243 1990 -271 1999 -280 2027 -308 2092 -383 2092 -411] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.089974 0.090028 + translation -247.069 37.0465 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2 1] + point Coordinate2D { + point [2715 -4 2687 -4 2660 -13 2641 -13 2641 -13 2622 -23 2622 -23 2613 -32 2585 -69 2585 -69 2585 -78 2576 -106 2576 -116 2576 -134 2567 -125 2576 -143 2576 -143 2576 -171 2576 -171 2576 -171 2594 -190 2594 -190 2594 -190 2604 -209 2604 -209 2604 -209 2613 -218 2613 -218 2613 -218 2632 -218 2632 -218 2632 -218 2650 -218 2650 -218 2650 -218 2669 -218 2669 -218 2669 -218 2687 -209 2687 -209 2687 -209 2706 -209 2706 -209 2715 -199 2715 -199 2725 -199 2725 -199 2734 -199 2734 -199 2743 -190 2743 -190 2753 -190 2753 -190 2762 -181 2762 -181 2762 -171 2762 -171 2771 -171 2771 -171 2771 -162 2771 -162 2780 -153 2780 -153 2780 -153 2780 -134 2780 -134 2780 -125 2780 -97 2780 -88 2780 -78 2771 -69 2771 -60 2771 -60 2762 -50 2762 -50 2762 -50 2753 -32 2753 -32 2753 -23 2753 -23 2743 -13 2743 -13 2734 -13 2734 -13 2715 5 2715 -4 2734 -13] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 1 2 1 2] + point Coordinate2D { + point [2660 -255 2660 -274 2660 -311 2660 -329 2660 -348 2660 -376 2660 -395 2660 -413 2660 -413 2660 -432 2660 -432 2660 -450 2660 -460 2660 -497 2660 -506] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [2464 -822 2483 -794 2520 -748 2539 -720 2539 -711 2576 -683 2567 -683 2529 -683 2483 -711 2446 -711 2427 -711 2474 -636 2474 -636 2492 -608 2539 -571 2567 -553 2576 -553 2585 -534 2594 -534 2622 -525 2641 -506 2669 -506 2697 -506 2734 -506 2762 -506 2780 -506 2873 -553 2883 -571 2883 -571 2892 -590 2892 -599 2892 -599 2901 -627 2901 -627 2901 -627 2911 -608 2911 -608 2920 -581 2957 -534 2957 -506] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2] + point Coordinate2D { + point [2641 -292 2585 -311 2529 -320 2464 -320 2427 -320 2483 -274 2483 -274 2529 -227 2687 -227 2799 -227 2836 -227 2920 -227 2948 -236 2966 -246 3004 -264 3004 -274 3013 -292 3050 -320 3050 -329] + } + } + } + ] + } + ] + } + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval IS runTime + loop IS loop + startTime IS start + } + DEF VAL Valuator { + Factor1 8 + } + ROUTE TS.fraction_changed TO VAL.inSFFloat + ROUTE VAL.outSFInt32 TO MYSWITCH.whichChoice +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This file is used as a proto library by another file." + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" + ] + title "ExternProto Library File" + } + Shape { + appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } + geometry Text { + string [ + "This file is used as a proto library by another file." + "" + "GPAC Regression Tests" + "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" + "(C) 2002-2004 GPAC Team" + ] + fontStyle FontStyle { + size 25 + justify [ "MIDDLE" "MIDDLE" ] + } + } + } + ] +} + + diff --git a/regression_tests/bifs/bifs-externproto-forestgump.bt b/regression_tests/bifs/bifs-externproto-forestgump.bt new file mode 100644 index 0000000..dbf1e30 --- /dev/null +++ b/regression_tests/bifs/bifs-externproto-forestgump.bt @@ -0,0 +1,96 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +EXTERNPROTO FORESTGUMP [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFFloat lineWidth 3 + exposedField SFColor lineColor 0.121569 0.101961 0.0901961 + exposedField SFTime runTime 1 + exposedField SFBool loop TRUE + exposedField SFTime start 0 +] ""od:20"" + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["Each animated logo is an instance of a single proto" "defined in an external library" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Complexe proto Test" + } + FORESTGUMP { + translation -75 -75 + scale 1.1 1.1 + rotation 0.75 + runTime 0.5 + } + FORESTGUMP { + translation -100 50 + scale 1 1.5 + runTime 0.75 + start 2 + } + FORESTGUMP { + translation 0 10 + scale 1.8 1.8 + start 4 + } + DEF ANIM FORESTGUMP { + translation 75 -75 + rotation -1.25 + runTime 0.8 + start 6 + } + DEF TIMER TimeSensor { + cycleInterval 2 + loop TRUE + startTime 6 + } + DEF SI ScalarInterpolator { + key [0 1] + keyValue [0 6.283] + } + ] +} + +ROUTE TIMER.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO ANIM.rotation + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 20 + URLstring "bifs-externproto-forestgump-lib.mp4" + } + ] +} + diff --git a/regression_tests/bifs/bifs-externproto-mfurl-lib.bt b/regression_tests/bifs/bifs-externproto-mfurl-lib.bt new file mode 100644 index 0000000..3139371 --- /dev/null +++ b/regression_tests/bifs/bifs-externproto-mfurl-lib.bt @@ -0,0 +1,52 @@ + +PROTO testURL [ + exposedField MFString theURL [""] +] { + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF MYTEXT ImageTexture { + url IS theURL + } + } + geometry Bitmap {} + + } + ] + } +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This file is used as a proto library by another file." + "GPAC Regression Tests" + "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" + "(C) 2002-2004 GPAC Team" + ] + title "ExternProto Library File" + } + Shape { + appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } + geometry Text { + string [ + "This file is used as a proto library by another file." + "" + "GPAC Regression Tests" + "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" + "(C) 2002-2004 GPAC Team" + ] + fontStyle FontStyle { + size 25 + justify [ "MIDDLE" "MIDDLE" ] + } + } + } + ] +} + + diff --git a/regression_tests/bifs/bifs-externproto-mfurl.bt b/regression_tests/bifs/bifs-externproto-mfurl.bt new file mode 100644 index 0000000..71308b6 --- /dev/null +++ b/regression_tests/bifs/bifs-externproto-mfurl.bt @@ -0,0 +1,69 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +EXTERNPROTO testURL [ + exposedField MFString theURL [""] +] ""od:20"" + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This is a proto with an MF URL ISed field" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "ExternProto with URL Test" + } + DEF testInstance testURL { + theURL ["10"] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 20 + URLstring "bifs-externproto-mfurl-lib.mp4" + } + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 3 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-externproto-nood-lib.bt b/regression_tests/bifs/bifs-externproto-nood-lib.bt new file mode 100644 index 0000000..b053634 --- /dev/null +++ b/regression_tests/bifs/bifs-externproto-nood-lib.bt @@ -0,0 +1,109 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] { + Transform2D { + translation IS translation + children [ + DEF S Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + Transform2D { + translation -100 0 + children [ + USE S + ] + } + ] + } +} +PROTO GEO_PRO [ + exposedField SFVec2f translation 0 0 + exposedField SFNode obj NULL +] { + Transform2D { + translation IS translation + children [ + DEF S Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + } + ] + } +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This file is used as a proto library by another file." + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" + ] + title "ExternProto Library File" + } + Shape { + appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } + geometry Text { + string [ + "This file is used as a proto library by another file." + "" + "GPAC Regression Tests" + "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" + "(C) 2002-2004 GPAC Team" + ] + fontStyle FontStyle { + size 25 + justify [ "MIDDLE" "MIDDLE" ] + } + } + } + ] +} diff --git a/regression_tests/bifs/bifs-externproto-nood.bt b/regression_tests/bifs/bifs-externproto-nood.bt new file mode 100644 index 0000000..bf7509c --- /dev/null +++ b/regression_tests/bifs/bifs-externproto-nood.bt @@ -0,0 +1,70 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +EXTERNPROTO EXPR1 [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFColor color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] "bifs-externproto-nood-lib.bt#GEOMETRY_PROTO" + +EXTERNPROTO EXPR2 [ + exposedField SFVec2f translation 0 0 + exposedField SFNode obj NULL +] "bifs-externproto-nood-lib.bt#GEO_PRO" + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of extern proto" "with vrml-like addressing (no MPEG-4 ODs)" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] + title "Simple ExternProto Test" + } + EXPR1 { + translation 20 50 + color 0 1 0 + obj DEF C Circle { + radius 75 + } + } + EXPR2 { + translation -50 -50 + obj USE C + } + ] +} + + diff --git a/regression_tests/bifs/bifs-externproto-simple-lib.bt b/regression_tests/bifs/bifs-externproto-simple-lib.bt new file mode 100644 index 0000000..f495c80 --- /dev/null +++ b/regression_tests/bifs/bifs-externproto-simple-lib.bt @@ -0,0 +1,90 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] { + Transform2D { + translation IS translation + children [ + DEF S Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + Transform2D { + translation -100 0 + children [ + USE S + ] + } + ] + } +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This file is used as a proto library by another file." + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" + ] + title "ExternProto Library File" + } + Shape { + appearance Appearance { material Material2D { filled TRUE emissiveColor 0 0 0 } } + geometry Text { + string [ + "This file is used as a proto library by another file." + "" + "GPAC Regression Tests" + "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" + "(C) 2002-2004 GPAC Team" + ] + fontStyle FontStyle { + size 25 + justify [ "MIDDLE" "MIDDLE" ] + } + } + } + ] +} diff --git a/regression_tests/bifs/bifs-externproto-simple.bt b/regression_tests/bifs/bifs-externproto-simple.bt new file mode 100644 index 0000000..e7b41e5 --- /dev/null +++ b/regression_tests/bifs/bifs-externproto-simple.bt @@ -0,0 +1,81 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +EXTERNPROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] ""od:20"" + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of extern proto with regular addressing by proto ID" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Simple ExternProto Test" + } + DEF G GEOMETRY_PROTO { + translation 200 0 + scale 1 1.5 + rotation 0.78 + Color 1 0 1 + transparency 0.75 + lineColor 1 0 0 + lineWidth 2 + obj Circle { + radius 75 + } + } + Transform2D { + translation -300 0 + children [ + USE G + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 20 + URLstring "bifs-externproto-simple-lib.mp4" + } + ] +} + diff --git a/regression_tests/bifs/bifs-game-arrange.bt b/regression_tests/bifs/bifs-game-arrange.bt new file mode 100644 index 0000000..ed2229a --- /dev/null +++ b/regression_tests/bifs/bifs-game-arrange.bt @@ -0,0 +1,452 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This file demonstrates how to use ECMAScript to make games in BIFS." + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" + ] + title "Arrange" + } + Transform2D { + translation 0 150 + children [ + DEF StartTS TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 0.5 0.5 + filled TRUE + } + } + geometry Rectangle { + size 100 30 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Text { + string ["Start Game"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + DEF TimeSensorTick TimeSensor { + enabled FALSE + loop TRUE + } + Transform2D { + translation 0 75 + children [ + Shape { + appearance DEF TA Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry DEF TextField Text { + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 22 + } + } + } + ] + } + Switch { + choice [ + DEF Hole Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 1 + filled TRUE + } + } + geometry DEF R Rectangle { + size 50 50 + } + } + ] + } + Transform2D { + translation 0 -50 + children [ + DEF Table Form { + size 150 150 + groups [1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 7 -1 8 -1 9 -1 1 2 3 -1 4 5 6 -1 7 8 9 -1] + constraints ["SHin" "SHin" "SHin" "SVin"] + groupsIndex [1 2 3 -1 4 5 6 -1 7 8 9 -1 10 11 12 -1] + children [ + DEF a_1_1 Switch { + whichChoice 0 + choice [ + Transform2D { + children [ + DEF TS_1_1 TouchSensor {} + Shape { + appearance DEF RA Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry USE R + } + Shape { + appearance USE TA + geometry Text { + string ["1"] + fontStyle USE FS + } + } + ] + } + USE Hole + ] + } + DEF a_1_2 Switch { + whichChoice 0 + choice [ + Transform2D { + children [ + DEF TS_1_2 TouchSensor {} + Shape { + appearance USE RA + geometry USE R + } + Shape { + appearance USE TA + geometry Text { + string ["2"] + fontStyle USE FS + } + } + ] + } + USE Hole + ] + } + DEF a_1_3 Switch { + whichChoice 0 + choice [ + Transform2D { + children [ + DEF TS_1_3 TouchSensor {} + Shape { + appearance USE RA + geometry USE R + } + Shape { + appearance USE TA + geometry Text { + string ["3"] + fontStyle USE FS + } + } + ] + } + USE Hole + ] + } + DEF a_2_1 Switch { + whichChoice 0 + choice [ + Transform2D { + children [ + DEF TS_2_1 TouchSensor {} + Shape { + appearance USE RA + geometry USE R + } + Shape { + appearance USE TA + geometry Text { + string ["4"] + fontStyle USE FS + } + } + ] + } + USE Hole + ] + } + DEF a_2_2 Switch { + whichChoice 0 + choice [ + Transform2D { + children [ + DEF TS_2_2 TouchSensor {} + Shape { + appearance USE RA + geometry USE R + } + Shape { + appearance USE TA + geometry Text { + string ["5"] + fontStyle USE FS + } + } + ] + } + USE Hole + ] + } + DEF a_2_3 Switch { + whichChoice 0 + choice [ + Transform2D { + children [ + DEF TS_2_3 TouchSensor {} + Shape { + appearance USE RA + geometry USE R + } + Shape { + appearance USE TA + geometry Text { + string ["6"] + fontStyle USE FS + } + } + ] + } + USE Hole + ] + } + DEF a_3_1 Switch { + whichChoice 0 + choice [ + Transform2D { + children [ + DEF TS_3_1 TouchSensor {} + Shape { + appearance USE RA + geometry USE R + } + Shape { + appearance USE TA + geometry Text { + string ["7"] + fontStyle USE FS + } + } + ] + } + USE Hole + ] + } + DEF a_3_2 Switch { + whichChoice 0 + choice [ + Transform2D { + children [ + DEF TS_3_2 TouchSensor {} + Shape { + appearance USE RA + geometry USE R + } + Shape { + appearance USE TA + geometry Text { + string ["8"] + fontStyle USE FS + } + } + ] + } + USE Hole + ] + } + DEF a_3_3 Switch { + whichChoice 1 + choice [ + Transform2D { + children [ + DEF TS_3_3 TouchSensor {} + Shape { + appearance USE RA + geometry USE R + } + Shape { + appearance USE TA + geometry Text { + string ["9"] + fontStyle USE FS + } + } + ] + } + USE Hole + ] + } + ] + } + ] + } + DEF SC Script { + eventIn SFVec2f move + eventIn SFBool startGame + eventIn SFTime tickTime + field SFNode txtField USE TextField + field SFNode table USE Table + field SFInt32 gsize 3 + field SFInt32 ghrow 2 + field SFInt32 ghcol 2 + field SFInt32 gtime 0 + field SFInt32 gmoves 0 + field SFInt32 gshuffling 0 + field SFInt32 size 3 + field SFBool isStarted FALSE + eventOut SFBool hasWin + url ["javascript: + function r(low,hi) {return Math.floor((hi-low)*Math.random()+low); } + function r1(hi) {return Math.floor((hi-1)*Math.random()+1); } + function r0(hi) {return Math.floor((hi)*Math.random()); } + function startGame(value) {if (value) {shuffle();gtime = 0;gmoves = 0;isStarted = !isStarted; hasWin = false;}} + function stopGame(){isStarted = !isStarted;} + function tickTime(value){showStatus();gtime++;} + function checkWin(){if (!isStarted) return; if (!isHole(gsize-1,gsize-1)) return;for (i=0;i<gsize;i++)for (j=0;j<gsize;j++) {if (!(i==gsize-1 && j==gsize-1)) {if (getValue(i,j)!=(i*gsize+j+1).toString()) return;}}hasWin = true;stopGame();txtField.string[0] = '!! CONGRATS !!';txtField.string[1] = 'You have done it in ' + gtime + ' secs ' + 'with ' + gmoves + ' moves!';txtField.string[2] = 'Your speed is ' + Math.round(1000*gmoves/gtime)/1000 + ' moves/sec';} + function showStatus() {if (hasWin) return;txtField.string[0] = 'Time: ' + gtime + ' secs Moves: ' + gmoves;txtField.string[1] = '';txtField.string[2] = '';} + function getCell(row, col) {return table.children[row * gsize + col];} + function setValue(row,col,val) {v = getCell(row, col);v.whichChoice = 0;v.choice[0].children[2].geometry.string[0] = val;} + function getValue(row,col) {v = getCell(row, col);return v.choice[0].children[2].geometry.string[0];} + function setHole(row,col) { v = getCell(row, col);v.whichChoice = 1;ghrow = row;ghcol = col;} + function getRow(obj){a = obj.id.split('_');return a[1];} + function getCol(obj) {a = obj.id.split('_');return a[2];} + function isHole(row, col) {return (row==ghrow && col==ghcol) ? true : false;} + function getHoleInRow(row) {return (row==ghrow) ? ghcol : -1;} + function getHoleInCol(col) {return (col==ghcol) ? ghrow : -1;} + function shiftHoleRow(src,dest,row) {src = parseInt(src);dest = parseInt(dest);if (src < dest) {for (i=src;i<dest;i++) {setValue(row,i,getValue(row,i+1));setHole(row,i+1);}}if (dest < src) {for (i=src;i>dest;i--) {setValue(row,i,getValue(row,i-1));setHole(row,i-1);}}} + function shiftHoleCol(src,dest,col) {src = parseInt(src);dest = parseInt(dest);if (src < dest) {for (i=src;i<dest;i++) {setValue(i,col,getValue(i+1,col));setHole(i+1,col);}}if (dest < src){for (i=src;i>dest;i--){ setValue(i,col,getValue(i-1,col));setHole(i-1,col);}}} + function moveRowCol(r,c) { if (!isStarted && !gshuffling) { return; }if (isHole(r,c)) {return; }hc = getHoleInRow(r);if (hc != -1) {shiftHoleRow(hc,c,r);gmoves++;checkWin();return;} hr = getHoleInCol(c);if (hr != -1){shiftHoleCol(hr,r,c);gmoves++;checkWin();return;} } + function move(value) {moveRowCol(value.x-1,value.y-1);} + function shuffle() {gshuffling = true;for (i=0;i<gsize;i++) {for (j=0;j<gsize+10;j++) { if (j==0) {t = r0(gsize);while (t == ghrow) t = r0(gsize); moveRowCol(t, ghcol);} else {t = r0(gsize);while (t == ghcol) t = r0(gsize); moveRowCol(ghrow, t);}}}gshuffling = false;}" ] + } + DEF V_1_1 Valuator {} + DEF C_1_1 Conditional { + buffer { + REPLACE V_1_1.inSFVec2f BY 1 1 + } + } + DEF V_1_2 Valuator {} + DEF C_1_2 Conditional { + buffer { + REPLACE V_1_2.inSFVec2f BY 1 2 + } + } + DEF V_1_3 Valuator {} + DEF C_1_3 Conditional { + buffer { + REPLACE V_1_3.inSFVec2f BY 1 3 + } + } + DEF V_2_1 Valuator {} + DEF C_2_1 Conditional { + buffer { + REPLACE V_2_1.inSFVec2f BY 2 1 + } + } + DEF V_2_2 Valuator {} + DEF C_2_2 Conditional { + buffer { + REPLACE V_2_2.inSFVec2f BY 2 2 + } + } + DEF V_2_3 Valuator {} + DEF C_2_3 Conditional { + buffer { + REPLACE V_2_3.inSFVec2f BY 2 3 + } + } + DEF V_3_1 Valuator {} + DEF C_3_1 Conditional { + buffer { + REPLACE V_3_1.inSFVec2f BY 3 1 + } + } + DEF V_3_2 Valuator {} + DEF C_3_2 Conditional { + buffer { + REPLACE V_3_2.inSFVec2f BY 3 2 + } + } + DEF V_3_3 Valuator {} + DEF C_3_3 Conditional { + buffer { + REPLACE V_3_3.inSFVec2f BY 3 3 + } + } + DEF WinConditional Conditional { + buffer { + REPLACE TimeSensorTick.enabled BY FALSE +# REPLACE TimeSensorTick.stopTime BY 0 + } + } + DEF StartConditional Conditional { + buffer { + REPLACE TimeSensorTick.enabled BY TRUE +# REPLACE TimeSensorTick.startTime BY 0 + } + } + ] +} + +ROUTE StartTS.isActive TO StartConditional.activate +ROUTE StartTS.isActive TO SC.startGame +ROUTE TimeSensorTick.cycleTime TO SC.tickTime +ROUTE SC.hasWin TO WinConditional.activate +ROUTE TS_1_1.isActive TO C_1_1.activate +ROUTE TS_1_2.isActive TO C_1_2.activate +ROUTE TS_1_3.isActive TO C_1_3.activate +ROUTE TS_2_1.isActive TO C_2_1.activate +ROUTE TS_2_2.isActive TO C_2_2.activate +ROUTE TS_2_3.isActive TO C_2_3.activate +ROUTE TS_3_1.isActive TO C_3_1.activate +ROUTE TS_3_2.isActive TO C_3_2.activate +ROUTE TS_3_3.isActive TO C_3_3.activate +ROUTE V_1_1.outSFVec2f TO SC.move +ROUTE V_1_2.outSFVec2f TO SC.move +ROUTE V_1_3.outSFVec2f TO SC.move +ROUTE V_2_1.outSFVec2f TO SC.move +ROUTE V_2_2.outSFVec2f TO SC.move +ROUTE V_2_3.outSFVec2f TO SC.move +ROUTE V_3_1.outSFVec2f TO SC.move +ROUTE V_3_2.outSFVec2f TO SC.move +ROUTE V_3_3.outSFVec2f TO SC.move + diff --git a/regression_tests/bifs/bifs-game-breakout.bt b/regression_tests/bifs/bifs-game-breakout.bt new file mode 100644 index 0000000..9bc0d1c --- /dev/null +++ b/regression_tests/bifs/bifs-game-breakout.bt @@ -0,0 +1,1035 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + objectTypeIndication 2 + streamType 3 + bufferSizeDB 5000 + maxBitrate 13616 + avgBitrate 13616 + decSpecificInfo BIFSv2Config { + nodeIDbits 10 + routeIDbits 10 + protoIDbits 10 + isCommandStream true + pixelMetric true + pixelWidth 500 + pixelHeight 500 + } + } + slConfigDescr SLConfigDescriptor { + useAccessUnitStartFlag true + useAccessUnitEndFlag true + useTimeStampsFlag true + timeStampResolution 1000 + timeStampLength 32 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This game was translated from" "the site http://javascript.internet.com'" + "Written and designed by Nick Young (ywing9787@aol.com)" + "Translated and adapted by " "Cyril Concolato (cyril.concolato@enst.fr), June 2003" + "GPAC Regression Tests" "$Date: 2008-05-19 15:28:18 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team" + ] + title "Breakout using MPEG-4 BIFS and Javascript" + } + Transform2D { + translation 0 200 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Breakout Using MPEG-4 BIFS and Javascript"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + style "BOLD" + } + } + } + ] + } + DEF N0 TimeSensor { + cycleInterval 0.001 + enabled FALSE + loop TRUE + } + Transform2D { + translation -215 150 + children [ + DEF N1 TouchSensor {} + Transform2D { + translation 16 -16 + children [ + Transform2D { + translation 197 -150 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Rectangle { + size 394 300 + } + } + ] + } + ] + } + DEF N2 Transform2D { + translation 21 -8 + children [ + Transform2D { + translation 29 -48 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry DEF N3 Rectangle { + size 42 16 + } + } + ] + } + Transform2D { + translation 75 -48 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 121 -48 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 167 -48 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 213 -48 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 259 -48 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 305 -48 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 351 -48 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 29 -68 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.75 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 75 -68 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.75 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 121 -68 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.75 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 167 -68 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.75 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 213 -68 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.75 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 259 -68 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.75 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 305 -68 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.75 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 351 -68 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.75 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 29 -88 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 75 -88 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 121 -88 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 167 -88 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 213 -88 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 259 -88 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 305 -88 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 351 -88 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.5 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 29 -108 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.25 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 75 -108 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.25 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 121 -108 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.25 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 167 -108 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.25 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 213 -108 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.25 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 259 -108 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.25 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 305 -108 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.25 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 351 -108 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0.25 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 29 -128 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 75 -128 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 121 -128 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 167 -128 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 213 -128 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 259 -128 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 305 -128 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + Transform2D { + translation 351 -128 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry USE N3 + } + ] + } + ] + } + DEF N4 Transform2D { + translation 209 -270 + children [ + Transform2D { + translation 4 -4 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.7 0.7 0.7 + filled TRUE + } + } + geometry Rectangle { + size 4 8 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.7 0.7 0.7 + filled TRUE + } + } + geometry Rectangle { + size 8 4 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 1 + filled TRUE + } + } + geometry Rectangle { + size 4 4 + } + } + ] + } + ] + } + DEF N5 Transform2D { + translation 193 -280 + children [ + Transform2D { + translation 20 -2 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.7 0.7 1 + filled TRUE + } + } + geometry Rectangle { + size 40 4 + } + } + ] + } + ] + } + DEF N6 Switch { + whichChoice 0 + choice [ + Transform2D { + translation 210 -215 + children [ + DEF N7 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 0.5 0.5 + filled TRUE + } + } + geometry Rectangle { + size 100 30 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Start Game"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] + } + ] + } + DEF N8 Script { + eventIn SFBool startGame + eventIn SFVec3f set_X + eventIn SFTime tickTime + field SFNode timer USE N0 + field SFNode ball USE N4 + field SFNode racket USE N5 + field SFNode starter USE N6 + field SFNode table USE N2 + field SFInt32 loadFLG 0 + field SFInt32 gameFLG 0 + field SFInt32 missFLG 0 + field SFTime tim 0 + field MFColor blcol [1 1 0 1 0.75 0 1 0.5 0 1 0.25 0 1 0 0 0 0 0] + field MFInt32 blsta [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] + field MFInt32 blNO [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] + field SFInt32 blclr 0 + field SFFloat ballX 209 + field SFFloat ballY -270 + field SFInt32 ballN 5 + field SFFloat ballDX 0 + field SFFloat ballDY 0 + field SFFloat tmpRL 193 + url ["javascript: +function startGame(value) { + if (value) { + initG(); + } +} +function tickTime(value) { + mainF(); +} +function mainF() { + ballX+=ballDX; + ballY+=ballDY; + outCHK(); + blkCHK(); + ball.translation.y=ballY; + ball.translation.x=ballX; + racket.translation.x=tmpRL; +} +function initG() { + if (blclr>=40) { + blclr=0; + ballN=3; + for (ib=0;ib<5;ib++){ + for (ia=0;ia<8;ia++){ + chc(ib*8+ia+1,ib); + blsta[ib*8+ia]=ib; + } + } + } + starter.whichChoice=-1; + gameFLG=1; + loadFLG=1; + ballX=209; + ballY=-270; + ballDX=-3; + ballDY=3; + tmpRL=193; + missFLG=0; +} +function set_X(value) { + if (loadFLG==1) { + tmpRL=value.x + 197; + if (tmpRL<21) { + tmpRL=21; + } + if (tmpRL>373) { + tmpRL=373; + } + } +} +function outCHK() { + if (ballX<16) { + ballX=32-ballX; + ballDX=-ballDX; + } + if (ballX>401) { + ballX=802-ballX; + ballDX=-ballDX; + } + if (ballY>-16) { + ballY=-32-ballY; + ballDY=-ballDY; + } + if (ballY<=-272) { + if (missFLG==0) { + tmpX=(ballDX/ballDY)*(-272-ballY)+ballX; + if (tmpX>=tmpRL-12) { + if (tmpX<=tmpRL+42) { + ballY=-272; + ballDY=-ballDY; + ballX=tmpX; + ballRD=tmpX-tmpRL; + ballDX=8*Math.abs(ballDX)/ballDX; + if (ballRD<-4) { + ballDX=-15; + } + if (ballRD>36) { + ballDX=15; + } + if (ballRD>=14) { + if (ballRD<=16) { + ballDX=-2; + } + } + if (ballRD>=17) { + if (ballRD<=20) { + ballDX=2; + } + } + if (ballRD>=0) { + if (ballRD<=4) { + ballDX=-4; + } + } + if (ballRD>=28) { + if (ballRD<=32) { + ballDX=4; + } + } + if (ballRD>=-4) { + if (ballRD<=-1) { + ballDX=-11; + } + } + if (ballRD>=33) { + if (ballRD<=36) { + ballDX=11; + } + } + } + } + if (ballDY<0) { + missFLG=1; + } + } + else { + if (ballY<-290) { + missFLG=0; + ballN=ballN-1; + gameEnd(); + } + } + } +} +function blkCHK() { + tmpY=ballY-4; + tmpY=-tmpY; + tmpX=ballX+4; + if (tmpY>=48) { + if (tmpY<=147) { + if (tmpX>=29) { + if (tmpX<=396) { + ia=Math.floor((tmpX-29)/46); + ib=Math.floor((tmpY-48)/20); + ic=ib*8+ia; + if (blsta[ic]<=4) { + tmpbc=blsta[ic]+1; + blsta[ic]=tmpbc; + chc(ic+1,tmpbc); + if (tmpbc==5) { + blclr=blclr+1; + } + if (blclr>=40) { + gameEnd(); + } + if (ballDX>0) { + iy=(-ballDY/ballDX)*(29+46*ia-tmpX)+tmpY; + if (iy>48+20*ib+18) { + tmpY1=48+20*ib+18; + tmpX1=(ballDX/-ballDY)*(48+20*ib+18-tmpY)+tmpX; + ballX=tmpX1-4; + ballY=-(tmpY1+4); + ballDY=-ballDY; + } + else { + if (iy<44+20*ib) { + tmpY1=48+20*ib; + tmpX1=(ballDX/-ballDY)*(48+20*ib-tmpY)+tmpX; + ballX=tmpX1-4; + ballY=-(tmpY1+4); + ballDY=-ballDY; + } + else { + tmpX1=29+46*ia; + tmpY1=(-ballDY/ballDX)*(29+46*ia-tmpX)+tmpY; + ballX=tmpX1-4; + ballY=-(tmpY1+4); + ballDX=-ballDX; + } + } + } + else { + iy=(-ballDY/ballDX)*(29+46*ia+44-tmpX)+tmpY; + if (iy>48+20*ib+18) { + tmpY1=48+20*ib+18; + tmpX1=(ballDX/-ballDY)*(48+20*ib+18-tmpY)+tmpX; + ballX=tmpX1-4; + ballY=-(tmpY1+4); + ballDY=-ballDY; + } + else { + if (iy<44+20*ib) { + tmpY1=48+20*ib; + tmpX1=(ballDX/-ballDY)*(48+20*ib-tmpY)+tmpX; + ballX=tmpX1-4; + ballY=-(tmpY1+4); + ballDY=-ballDY; + } + else { + tmpX1=29+46*ia+44; + tmpY1=(-ballDY/ballDX)*(29+46*ia+44-tmpX)+tmpY; + ballX=tmpX1-4; + ballY=-(tmpY1+4); + ballDX=-ballDX; + } + } + } + } + } + } + } + } +} +function gameEnd() { + gameFLG=0; + loadFLG=0; + timer.enabled=false; + starter.whichChoice=0; + if (ballN<=0) { + blclr=40; + } +} +function initialize() { + for (ib=0;ib<5;ib++){ + for (ia=0;ia<8;ia++){ + blsta[ib*8+ia]=ib; + } + } +} +function chc(bno,bcl) { + monBlock=table.children[bno-1].children[0].appearance.material; + monBlock.emissiveColor=blcol[bcl]; +} + +" + ] + } + DEF N9 Conditional { + buffer { + REPLACE N0.enabled BY TRUE + } + } + ] +} + +ROUTE N7.isActive TO N8.startGame +ROUTE N7.isActive TO N9.activate +ROUTE N0.cycleTime TO N8.tickTime +ROUTE N1.hitPoint_changed TO N8.set_X + diff --git a/regression_tests/bifs/bifs-game-bubble.bt b/regression_tests/bifs/bifs-game-bubble.bt new file mode 100644 index 0000000..ba30646 --- /dev/null +++ b/regression_tests/bifs/bifs-game-bubble.bt @@ -0,0 +1,433 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + useNames true + } + } + } + ] +} + +PROTO Bubble [ + exposedField SFInt32 index 0 + exposedField SFInt32 state 0 + exposedField SFInt32 display 0 + exposedField SFVec2f position 0 0 + + exposedField SFFloat size 9 + exposedField SFColor color 0 0 0 + exposedField SFFloat red 0 + exposedField SFFloat green 0 + exposedField SFFloat blue 0 + + exposedField SFFloat strokeWidth 2 + exposedField SFFloat strokeTransparency 0.3 + exposedField SFBool alignStroke FALSE + + eventOut SFInt32 isOver + eventOut SFInt32 isActive +] { + Switch { + whichChoice IS display + choice [ + Transform2D { + translation IS position + children [ + ColorTransform { + mrr 0.7 + mgg 0.5 + mbb 0.9 + maa 0.6 + ta 0.274 + tr IS red + tg IS green + tb IS blue + children [ + Shape { + geometry DEF C Circle { radius IS size } + appearance Appearance { + material Material2D { + filled TRUE + } + texture RadialGradient { + center 0.5 0.5 + focalPoint 0.5 0.5 + key [ 0 1 ] + keyValue [ 1 1 1 0 0 0 ] + } + } + } + ] + } + Shape { + geometry USE C + appearance Appearance { + material Material2D { + filled FALSE + lineProps XLineProperties { + width 2 + lineColor 0.2 0.2 0.2 + transparency IS strokeTransparency + isCenterAligned IS alignStroke + } + } + } + } + DEF TS TouchSensor {} + DEF Vindex Valuator { + inSFInt32 IS index + } + DEF VOver Valuator { + outSFInt32 IS isOver + } + DEF VActive Valuator { + outSFInt32 IS isActive + } + ] + } + ] + } + ROUTE Vindex.outSFFloat TO VOver.Factor1 + ROUTE Vindex.outSFFloat TO VActive.Factor1 + ROUTE TS.isOver TO VOver.inSFBool + ROUTE TS.isActive TO VActive.inSFBool +} +OrderedGroup { + children [ + WorldInfo { + title "Classic Bubble Game" + info [ + "This test shows the classic bubble game." + "It features:" + " - a PROTO which defines a single Bubble node. This node takes as input the index of the bubble in the bubbleGrid. The bubble outputs this index on separate events: one when the mouse enters the bubble and one when a click on the bubble happens. This PROTO does not use any scripting for that." + " - a Script node which handles the initialization (colors, size, index) and dynamic positionning of the bubbles. It is also responsible for the game logic." + "The number of of lines and columns in the bubble grid can be easily modified in the Script node." + "" + "GPAC Regression Tests" "$Date: 2008-11-24 14:58:25 $ - $Revision: 1.6 $" + "(C) 2002-2006 GPAC Team" + ] + } + DEF VIEWPORT Viewport { + size 410 300 + fit 1 + } + Background2D { backColor 1 1 1 } + DEF CANVAS_TRANSFORM Transform2D { + children [ + Shape { + geometry DEF CANVAS Rectangle { size 0 0 } + appearance Appearance { + material Material2D { + filled TRUE + emissiveColor 1 1 1 + lineProps XLineProperties { + width 2 + isScalable FALSE + lineColor 0 0 0 + } + } + } + } + DEF BUBBLE_ROOT Transform2D {} + ] + } + DEF TEXT_TRANSFORM Transform2D { + children [ + Shape { + geometry DEF SCORE_TEXT Text { + fontStyle FontStyle { + size 20 + family "SANS" + justify [ "BEGIN" "FIRST" ] + } + } + appearance Appearance { + material Material2D { + filled TRUE + emissiveColor 0 0 0 + } + } + } + ] + } + DEF Vover Valuator {} + DEF Vclick Valuator {} + DEF BUBBLE_SCRIPT Script { + field SFNode score_text USE SCORE_TEXT + field SFNode bubble_root USE BUBBLE_ROOT + + field SFNode canvas USE CANVAS + field SFNode canvas_pos USE CANVAS_TRANSFORM + field SFNode viewport USE VIEWPORT + field SFNode trans_text USE TEXT_TRANSFORM + + field SFNode val_over USE Vover + field SFNode val_click USE Vclick + + eventIn SFInt32 bubbleOnClick + eventIn SFInt32 bubbleMouseOver + + url [ "javascript: + function initialize() { + bubbleGrid = new Array(); + nbLines = 15; + nbCols = 26; + bubble_radius = 9; + score = 0; + neutral_state = 0; + selected_state = 1; + exploded_state = 2; + empty_state = 4; + + for (i=0; i<nbLines; i++) { + for (j=0; j<nbCols; j++) { + bubbleGrid[i*nbCols+j] = new bubble(bubble_root, i, j); +// print('index: '+(i*nbCols+j)); + } + } + + gridWidth = nbCols*(bubble_radius+1)*2; + gridHeight = nbLines*(bubble_radius+1)*2; + + viewport.size = new SFVec2f(gridWidth, gridHeight+50); + canvas.size = new SFVec2f(gridWidth, gridHeight); + canvas_pos.translation = new SFVec2f(0, 50/2-2); + + score_text.string[0] = 'Score: 0'; + bubble_root.scale = new SFVec2f(1, -1); + bubble_root.translation = new SFVec2f(-gridWidth/2 + 10, gridHeight/2-10); + trans_text.translation = new SFVec2f(-gridWidth/2 + 10, -(gridHeight+50)/2+10); + } + + function set_neutral(bubble) { + bubble.state = neutral_state; + bubble.alignStroke = FALSE; + bubble.strokeWidth = 2; + bubble.strokeTransparency = 0.7; + } + + function set_selected(bubble) { + bubble.state = selected_state; + bubble.alignStroke = TRUE; + bubble.strokeWidth = 3; + bubble.strokeTransparency = 0.3; + } + + function set_empty(bubble) { + bubble.state = empty_state; + bubble.display = -1; + } + + function set_exploded(bubble) { + bubble.display = -1; + bubble.state = exploded_state; + bubble.alignStroke = FALSE; + bubble.strokeWidth = 2; + bubble.strokeTransparency = 0.3; + } + + function set_visible(bubble) { + bubble.display = 0; + } + + function bubble(parent, line, column) { + var bubble; + bubble = new SFNode('_Proto1'); + bubble.position = new SFVec2f(2*column*(bubble_radius+1), 2*line*(bubble_radius+1)); + bubble.index = line*nbCols+column + 1; //1-based index + bubble.size = bubble_radius; + set_neutral(bubble); + bubble.red = 170/255.0; + bubble.green = Math.round(Math.random()*1)*150/255.0; + bubble.blue = Math.round(Math.random()*1)*255/255.0; + bubble.color = new SFColor(bubble.red, bubble.green, bubble.blue); +// print('Color: red '+ bubble.red + ' green ' + bubble.green + ' blue '+bubble.blue); + parent.children[parent.children.length] = bubble; + Browser.addRoute(bubble, 'isOver', val_over, 'inSFInt32'); + Browser.addRoute(bubble, 'isActive', val_click, 'inSFInt32'); + return bubble; + } + + function bubbleMouseOver(value) { + if (!value) return; + value--; + if (bubbleGrid[value].state == neutral_state) { + for (i=0; i<nbLines; i++) { + for (j=0; j<nbCols; j++) { + if (bubbleGrid[i*nbCols+j].state != empty_state) { + set_neutral(bubbleGrid[i*nbCols+j]); + } + } + } + line = Math.floor(value / nbCols); + column = value % nbCols; +// print('MouseOver l: '+line+' c: '+column); + if (propagate(line, column, bubbleGrid[line*nbCols+column].color)==1) { + set_neutral(bubbleGrid[line*nbCols+column]); + } + } + } + + function bubbleOnClick(value) { + if (!value) return; + value--; + if (bubbleGrid[value].state == selected_state) { + line = Math.floor(value / nbCols); + column = value % nbCols; + explode(line, column, bubbleGrid[value].color); + gravity(); + connexity(); + } + } + + function isColorEqual(c1, c2) { + if (c1.r != c2.r) return 0; + if (c1.g != c2.g) return 0; + if (c1.b != c2.b) return 0; + return 1; + } + + function propagate(line, column, color) { + var colmin, colmax, curcol, k, res; +// print('propagate l: '+line+' c: '+column); + if ( isColorEqual(bubbleGrid[line*nbCols+column].color, color) && + (bubbleGrid[line*nbCols+column].state == neutral_state)) { + res = 1; + set_selected(bubbleGrid[line*nbCols+column]); + + //before the bubble on the same line + curcol = column-1; + while ( (curcol>=0) && + isColorEqual(bubbleGrid[line*nbCols+curcol].color,color) && + (bubbleGrid[line*nbCols+curcol].state == neutral_state)) { +// print('propagate before l: '+line+' c: '+curcol); + set_selected(bubbleGrid[line*nbCols+curcol]); + curcol--; + res++; + } + + //after the bubble on the same line + colmin = ++curcol; + curcol = column+1; + while ( (curcol<nbCols) && + isColorEqual(bubbleGrid[line*nbCols+curcol].color, color) && + (bubbleGrid[line*nbCols+curcol].state == neutral_state)) { +// print('propagate after l: '+line+' c: '+curcol); + set_selected(bubbleGrid[line*nbCols+curcol]); + curcol++; + res++; + } + + colmax = --curcol; + for (k=colmin; k<=colmax; k++) { + if (line>0) { + if (isColorEqual(bubbleGrid[(line-1)*nbCols+k].color, color)&& + (bubbleGrid[(line-1)*nbCols+k].state == neutral_state)) + res = res + propagate(line-1, k, color); + } + if (line<nbLines-1) { + if (isColorEqual(bubbleGrid[(line+1)*nbCols+k].color, color)&& + (bubbleGrid[(line+1)*nbCols+k].state == neutral_state)) + res = res + propagate(line+1, k, color); + } + } + return res; + } else { + return 0; + } + } + + function explode(line, column, color) { +// print('explode l: '+line+' c: '+column); + if (isColorEqual(bubbleGrid[line*nbCols+column].color, color) && + (bubbleGrid[line*nbCols+column].state == selected_state)) { + set_exploded(bubbleGrid[line*nbCols+column]); + if (line>0) explode(line-1, column, color); + if (column>0) explode(line, column-1, color); + if (column<nbCols-1) explode(line, column+1, color); + if (line<nbLines-1) explode(line+1, column, color); + } + } + + function gravity() { + exploded = 0; + for (j=0; j<nbCols; j++) { + for (i=0; i<nbLines; i++) { + if (bubbleGrid[i*nbCols+j].state == exploded_state) { + start = end = i; + while ((end<nbLines)&&(bubbleGrid[end*nbCols+j].state == exploded_state)) { + // ???? + set_visible(bubbleGrid[end*nbCols+j]); + end++; + } + lg = end-start; + exploded +=lg; + for (k=end-1; k>=0; k--) { + if (k-lg>=0) { + if (bubbleGrid[(k-lg)*nbCols+j].state != empty_state) { + movebubble(k-lg, j, k, j); + } else { + set_empty(bubbleGrid[k*nbCols+j]); + } + } else { + set_empty(bubbleGrid[k*nbCols+j]); + } + } + } + } + } + score += exploded * exploded; + score_text.string[0] = 'Score: '+score; + } + + function movebubble(lsrc, csrc, ldst, cdst) { +// print('Move src l: '+lsrc+' c: '+csrc); +// print('Move dst l: '+ldst+' c: '+cdst); + // move a bubble from the (lsrc, csrc) position to the (ldst, cdst) position + // and let the src empty + bubbleGrid[ldst*nbCols+cdst].color = bubbleGrid[lsrc*nbCols+csrc].color; + bubbleGrid[ldst*nbCols+cdst].red = bubbleGrid[lsrc*nbCols+csrc].red; + bubbleGrid[ldst*nbCols+cdst].green = bubbleGrid[lsrc*nbCols+csrc].green; + bubbleGrid[ldst*nbCols+cdst].blue = bubbleGrid[lsrc*nbCols+csrc].blue; + bubbleGrid[ldst*nbCols+cdst].state = bubbleGrid[lsrc*nbCols+csrc].state; + if (bubbleGrid[ldst*nbCols+cdst].state != empty_state) + set_visible(bubbleGrid[ldst*nbCols+cdst]); + set_empty(bubbleGrid[lsrc*nbCols+csrc]); + } + + function movecolumn(colnumber, delta) { + for (i=0; i<nbLines; i++) movebubble(i, colnumber,i, colnumber+delta); + } + + function connexity() { + // if there is a hole in the last line, the whole column is free and must be suppressed + for (j=0; j<nbCols; j++) { + if (bubbleGrid[(nbLines-1)*nbCols+j].state == empty_state) { + if (j<nbCols/2) { + for (k=j-1; k>=0; k--) movecolumn(k, +1); + } else { + for (k=j+1; k<nbCols; k++) movecolumn(k, -1); + } + } + } + } + + "] + } + ] +} +ROUTE Vover.outSFInt32 TO BUBBLE_SCRIPT.bubbleMouseOver +ROUTE Vclick.outSFInt32 TO BUBBLE_SCRIPT.bubbleOnClick diff --git a/regression_tests/bifs/bifs-game-minesweeper.bt b/regression_tests/bifs/bifs-game-minesweeper.bt new file mode 100644 index 0000000..dba7f0a --- /dev/null +++ b/regression_tests/bifs/bifs-game-minesweeper.bt @@ -0,0 +1,1538 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + objectTypeIndication 2 + streamType 3 + bufferSizeDB 50000 + decSpecificInfo BIFSv2Config { + nodeIDbits 10 + routeIDbits 10 + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + slConfigDescr SLConfigDescriptor { + useAccessUnitStartFlag true + useAccessUnitEndFlag true + useTimeStampsFlag true + timeStampResolution 1000 + timeStampLength 32 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This game was translated from" + "the site http://javascript.internet.com'" + "Written and designed by Peter Occil (poccil@yahoo.com)" + "Translated and adapted by " + "Cyril Concolato (cyril.concolato@enst.fr), June 2003" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" +] + title "Winmine using MPEG-4 BIFS and Javascript" + } + Transform2D { + translation 0 175 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["MineSweeper using" "MPEG-4 BIFS and Javascript"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + style "BOLD" + } + } + } + ] + } + Transform2D { + scale 1.5 1.5 + children [ + DEF N0 TimeSensor { + enabled FALSE + loop TRUE + } + Switch { + choice [ + DEF N1 Transform2D { + children [ + DEF N2 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.3 0.3 0.3 + filled TRUE + } + } + geometry DEF N3 Rectangle { + size 16 16 + } + } + ] + } + DEF N4 Transform2D { + children [ + USE N2 + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 4 4 + } + } + ] + } + DEF N5 Transform2D { + children [ + USE N2 + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Text { + string ["?"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 10 + } + } + } + ] + } + DEF N6 Transform2D { + children [ + USE N2 + DEF N7 Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.4 0.4 0.4 + filled TRUE + } + } + geometry Rectangle { + size 15 15 + } + } + Shape { + appearance DEF N9 Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Text { + string [""] + fontStyle DEF N8 FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 15 + } + } + } + ] + } + DEF N10 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance USE N9 + geometry Text { + string ["1"] + fontStyle USE N8 + } + } + ] + } + DEF N11 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance USE N9 + geometry Text { + string ["2"] + fontStyle USE N8 + } + } + ] + } + DEF N12 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance USE N9 + geometry Text { + string ["3"] + fontStyle USE N8 + } + } + ] + } + DEF N13 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance USE N9 + geometry Text { + string ["4"] + fontStyle USE N8 + } + } + ] + } + DEF N14 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance USE N9 + geometry Text { + string ["5"] + fontStyle USE N8 + } + } + ] + } + DEF N15 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance USE N9 + geometry Text { + string ["6"] + fontStyle USE N8 + } + } + ] + } + DEF N16 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance USE N9 + geometry Text { + string ["7"] + fontStyle USE N8 + } + } + ] + } + DEF N17 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance USE N9 + geometry Text { + string ["8"] + fontStyle USE N8 + } + } + ] + } + DEF N18 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Circle { + radius 6 + } + } + ] + } + DEF N19 Transform2D { + children [ + USE N2 + USE N7 + ] + } + DEF N20 Transform2D { + children [ + USE N2 + USE N7 + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Text { + string ["x"] + fontStyle USE N8 + } + } + ] + } + DEF N21 Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 1 + filled TRUE + } + } + geometry Circle { + radius 10 + } + } + ] + } + DEF N22 Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + } + geometry Circle { + radius 10 + } + } + ] + } + ] + } + Transform2D { + translation -40 80 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Rectangle { + size 35 21 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry DEF N23 Text { + string ["010"] + fontStyle USE N8 + } + } + ] + } + DEF N24 Transform2D { + translation 0 80 + children [ + DEF N25 TouchSensor {} + USE N22 + ] + } + Transform2D { + translation 40 80 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Rectangle { + size 35 21 + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry DEF N26 Text { + string ["000"] + fontStyle USE N8 + } + } + ] + } + DEF N27 Form { + size 128 128 + groups [1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 7 -1 8 -1 9 -1 10 -1 11 -1 12 -1 13 -1 14 -1 15 -1 16 -1 17 -1 18 -1 19 -1 20 -1 21 -1 22 -1 23 -1 24 -1 25 -1 26 -1 27 -1 28 -1 29 -1 30 -1 31 -1 32 -1 33 -1 34 -1 35 -1 36 -1 37 -1 38 -1 39 -1 40 -1 41 -1 42 -1 43 -1 44 -1 45 -1 46 -1 47 -1 48 -1 49 -1 50 -1 51 -1 52 -1 53 -1 54 -1 55 -1 56 -1 57 -1 58 -1 59 -1 60 -1 61 -1 62 -1 63 -1 64 -1 1 2 3 4 5 6 7 8 -1 9 10 11 12 13 14 15 16 -1 17 18 19 20 21 22 23 24 -1 25 26 27 28 29 30 31 32 -1 33 34 35 36 37 38 39 40 -1 41 42 43 44 45 46 47 48 -1 49 50 51 52 53 54 55 56 -1 57 58 59 60 61 62 63 64 -1] + constraints ["SHin" "SHin" "SHin" "SHin" "SHin" "SHin" "SHin" "SHin" "SVin"] + groupsIndex [1 2 3 4 5 6 7 8 -1 9 10 11 12 13 14 15 16 -1 17 18 19 20 21 22 23 24 -1 25 26 27 28 29 30 31 32 -1 33 34 35 36 37 38 39 40 -1 41 42 43 44 45 46 47 48 -1 49 50 51 52 53 54 55 56 -1 57 58 59 60 61 62 63 64 -1 65 66 67 68 69 70 71 72 -1] + children [ + Transform2D { + children [ + DEF N28 TouchSensor {} + USE N1 + DEF N29 Valuator {} + DEF N30 Conditional { + buffer { + REPLACE N29.inSFVec2f BY 0 0 + } + } + ] + } + Transform2D { + children [ + DEF N31 TouchSensor {} + USE N1 + DEF N32 Valuator {} + DEF N33 Conditional { + buffer { + REPLACE N32.inSFVec2f BY 0 1 + } + } + ] + } + Transform2D { + children [ + DEF N34 TouchSensor {} + USE N1 + DEF N35 Valuator {} + DEF N36 Conditional { + buffer { + REPLACE N35.inSFVec2f BY 0 2 + } + } + ] + } + Transform2D { + children [ + DEF N37 TouchSensor {} + USE N1 + DEF N38 Valuator {} + DEF N39 Conditional { + buffer { + REPLACE N38.inSFVec2f BY 0 3 + } + } + ] + } + Transform2D { + children [ + DEF N40 TouchSensor {} + USE N1 + DEF N41 Valuator {} + DEF N42 Conditional { + buffer { + REPLACE N41.inSFVec2f BY 0 4 + } + } + ] + } + Transform2D { + children [ + DEF N43 TouchSensor {} + USE N1 + DEF N44 Valuator {} + DEF N45 Conditional { + buffer { + REPLACE N44.inSFVec2f BY 0 5 + } + } + ] + } + Transform2D { + children [ + DEF N46 TouchSensor {} + USE N1 + DEF N47 Valuator {} + DEF N48 Conditional { + buffer { + REPLACE N47.inSFVec2f BY 0 6 + } + } + ] + } + Transform2D { + children [ + DEF N49 TouchSensor {} + USE N1 + DEF N50 Valuator {} + DEF N51 Conditional { + buffer { + REPLACE N50.inSFVec2f BY 0 7 + } + } + ] + } + Transform2D { + children [ + DEF N52 TouchSensor {} + USE N1 + DEF N53 Valuator {} + DEF N54 Conditional { + buffer { + REPLACE N53.inSFVec2f BY 1 0 + } + } + ] + } + Transform2D { + children [ + DEF N55 TouchSensor {} + USE N1 + DEF N56 Valuator {} + DEF N57 Conditional { + buffer { + REPLACE N56.inSFVec2f BY 1 1 + } + } + ] + } + Transform2D { + children [ + DEF N58 TouchSensor {} + USE N1 + DEF N59 Valuator {} + DEF N60 Conditional { + buffer { + REPLACE N59.inSFVec2f BY 1 2 + } + } + ] + } + Transform2D { + children [ + DEF N61 TouchSensor {} + USE N1 + DEF N62 Valuator {} + DEF N63 Conditional { + buffer { + REPLACE N62.inSFVec2f BY 1 3 + } + } + ] + } + Transform2D { + children [ + DEF N64 TouchSensor {} + USE N1 + DEF N65 Valuator {} + DEF N66 Conditional { + buffer { + REPLACE N65.inSFVec2f BY 1 4 + } + } + ] + } + Transform2D { + children [ + DEF N67 TouchSensor {} + USE N1 + DEF N68 Valuator {} + DEF N69 Conditional { + buffer { + REPLACE N68.inSFVec2f BY 1 5 + } + } + ] + } + Transform2D { + children [ + DEF N70 TouchSensor {} + USE N1 + DEF N71 Valuator {} + DEF N72 Conditional { + buffer { + REPLACE N71.inSFVec2f BY 1 6 + } + } + ] + } + Transform2D { + children [ + DEF N73 TouchSensor {} + USE N1 + DEF N74 Valuator {} + DEF N75 Conditional { + buffer { + REPLACE N74.inSFVec2f BY 1 7 + } + } + ] + } + Transform2D { + children [ + DEF N76 TouchSensor {} + USE N1 + DEF N77 Valuator {} + DEF N78 Conditional { + buffer { + REPLACE N77.inSFVec2f BY 2 0 + } + } + ] + } + Transform2D { + children [ + DEF N79 TouchSensor {} + USE N1 + DEF N80 Valuator {} + DEF N81 Conditional { + buffer { + REPLACE N80.inSFVec2f BY 2 1 + } + } + ] + } + Transform2D { + children [ + DEF N82 TouchSensor {} + USE N1 + DEF N83 Valuator {} + DEF N84 Conditional { + buffer { + REPLACE N83.inSFVec2f BY 2 2 + } + } + ] + } + Transform2D { + children [ + DEF N85 TouchSensor {} + USE N1 + DEF N86 Valuator {} + DEF N87 Conditional { + buffer { + REPLACE N86.inSFVec2f BY 2 3 + } + } + ] + } + Transform2D { + children [ + DEF N88 TouchSensor {} + USE N1 + DEF N89 Valuator {} + DEF N90 Conditional { + buffer { + REPLACE N89.inSFVec2f BY 2 4 + } + } + ] + } + Transform2D { + children [ + DEF N91 TouchSensor {} + USE N1 + DEF N92 Valuator {} + DEF N93 Conditional { + buffer { + REPLACE N92.inSFVec2f BY 2 5 + } + } + ] + } + Transform2D { + children [ + DEF N94 TouchSensor {} + USE N1 + DEF N95 Valuator {} + DEF N96 Conditional { + buffer { + REPLACE N95.inSFVec2f BY 2 6 + } + } + ] + } + Transform2D { + children [ + DEF N97 TouchSensor {} + USE N1 + DEF N98 Valuator {} + DEF N99 Conditional { + buffer { + REPLACE N98.inSFVec2f BY 2 7 + } + } + ] + } + Transform2D { + children [ + DEF N100 TouchSensor {} + USE N1 + DEF N101 Valuator {} + DEF N102 Conditional { + buffer { + REPLACE N101.inSFVec2f BY 3 0 + } + } + ] + } + Transform2D { + children [ + DEF N103 TouchSensor {} + USE N1 + DEF N104 Valuator {} + DEF N105 Conditional { + buffer { + REPLACE N104.inSFVec2f BY 3 1 + } + } + ] + } + Transform2D { + children [ + DEF N106 TouchSensor {} + USE N1 + DEF N107 Valuator {} + DEF N108 Conditional { + buffer { + REPLACE N107.inSFVec2f BY 3 2 + } + } + ] + } + Transform2D { + children [ + DEF N109 TouchSensor {} + USE N1 + DEF N110 Valuator {} + DEF N111 Conditional { + buffer { + REPLACE N110.inSFVec2f BY 3 3 + } + } + ] + } + Transform2D { + children [ + DEF N112 TouchSensor {} + USE N1 + DEF N113 Valuator {} + DEF N114 Conditional { + buffer { + REPLACE N113.inSFVec2f BY 3 4 + } + } + ] + } + Transform2D { + children [ + DEF N115 TouchSensor {} + USE N1 + DEF N116 Valuator {} + DEF N117 Conditional { + buffer { + REPLACE N116.inSFVec2f BY 3 5 + } + } + ] + } + Transform2D { + children [ + DEF N118 TouchSensor {} + USE N1 + DEF N119 Valuator {} + DEF N120 Conditional { + buffer { + REPLACE N119.inSFVec2f BY 3 6 + } + } + ] + } + Transform2D { + children [ + DEF N121 TouchSensor {} + USE N1 + DEF N122 Valuator {} + DEF N123 Conditional { + buffer { + REPLACE N122.inSFVec2f BY 3 7 + } + } + ] + } + Transform2D { + children [ + DEF N124 TouchSensor {} + USE N1 + DEF N125 Valuator {} + DEF N126 Conditional { + buffer { + REPLACE N125.inSFVec2f BY 4 0 + } + } + ] + } + Transform2D { + children [ + DEF N127 TouchSensor {} + USE N1 + DEF N128 Valuator {} + DEF N129 Conditional { + buffer { + REPLACE N128.inSFVec2f BY 4 1 + } + } + ] + } + Transform2D { + children [ + DEF N130 TouchSensor {} + USE N1 + DEF N131 Valuator {} + DEF N132 Conditional { + buffer { + REPLACE N131.inSFVec2f BY 4 2 + } + } + ] + } + Transform2D { + children [ + DEF N133 TouchSensor {} + USE N1 + DEF N134 Valuator {} + DEF N135 Conditional { + buffer { + REPLACE N134.inSFVec2f BY 4 3 + } + } + ] + } + Transform2D { + children [ + DEF N136 TouchSensor {} + USE N1 + DEF N137 Valuator {} + DEF N138 Conditional { + buffer { + REPLACE N137.inSFVec2f BY 4 4 + } + } + ] + } + Transform2D { + children [ + DEF N139 TouchSensor {} + USE N1 + DEF N140 Valuator {} + DEF N141 Conditional { + buffer { + REPLACE N140.inSFVec2f BY 4 5 + } + } + ] + } + Transform2D { + children [ + DEF N142 TouchSensor {} + USE N1 + DEF N143 Valuator {} + DEF N144 Conditional { + buffer { + REPLACE N143.inSFVec2f BY 4 6 + } + } + ] + } + Transform2D { + children [ + DEF N145 TouchSensor {} + USE N1 + DEF N146 Valuator {} + DEF N147 Conditional { + buffer { + REPLACE N146.inSFVec2f BY 4 7 + } + } + ] + } + Transform2D { + children [ + DEF N148 TouchSensor {} + USE N1 + DEF N149 Valuator {} + DEF N150 Conditional { + buffer { + REPLACE N149.inSFVec2f BY 5 0 + } + } + ] + } + Transform2D { + children [ + DEF N151 TouchSensor {} + USE N1 + DEF N152 Valuator {} + DEF N153 Conditional { + buffer { + REPLACE N152.inSFVec2f BY 5 1 + } + } + ] + } + Transform2D { + children [ + DEF N154 TouchSensor {} + USE N1 + DEF N155 Valuator {} + DEF N156 Conditional { + buffer { + REPLACE N155.inSFVec2f BY 5 2 + } + } + ] + } + Transform2D { + children [ + DEF N157 TouchSensor {} + USE N1 + DEF N158 Valuator {} + DEF N159 Conditional { + buffer { + REPLACE N158.inSFVec2f BY 5 3 + } + } + ] + } + Transform2D { + children [ + DEF N160 TouchSensor {} + USE N1 + DEF N161 Valuator {} + DEF N162 Conditional { + buffer { + REPLACE N161.inSFVec2f BY 5 4 + } + } + ] + } + Transform2D { + children [ + DEF N163 TouchSensor {} + USE N1 + DEF N164 Valuator {} + DEF N165 Conditional { + buffer { + REPLACE N164.inSFVec2f BY 5 5 + } + } + ] + } + Transform2D { + children [ + DEF N166 TouchSensor {} + USE N1 + DEF N167 Valuator {} + DEF N168 Conditional { + buffer { + REPLACE N167.inSFVec2f BY 5 6 + } + } + ] + } + Transform2D { + children [ + DEF N169 TouchSensor {} + USE N1 + DEF N170 Valuator {} + DEF N171 Conditional { + buffer { + REPLACE N170.inSFVec2f BY 5 7 + } + } + ] + } + Transform2D { + children [ + DEF N172 TouchSensor {} + USE N1 + DEF N173 Valuator {} + DEF N174 Conditional { + buffer { + REPLACE N173.inSFVec2f BY 6 0 + } + } + ] + } + Transform2D { + children [ + DEF N175 TouchSensor {} + USE N1 + DEF N176 Valuator {} + DEF N177 Conditional { + buffer { + REPLACE N176.inSFVec2f BY 6 1 + } + } + ] + } + Transform2D { + children [ + DEF N178 TouchSensor {} + USE N1 + DEF N179 Valuator {} + DEF N180 Conditional { + buffer { + REPLACE N179.inSFVec2f BY 6 2 + } + } + ] + } + Transform2D { + children [ + DEF N181 TouchSensor {} + USE N1 + DEF N182 Valuator {} + DEF N183 Conditional { + buffer { + REPLACE N182.inSFVec2f BY 6 3 + } + } + ] + } + Transform2D { + children [ + DEF N184 TouchSensor {} + USE N1 + DEF N185 Valuator {} + DEF N186 Conditional { + buffer { + REPLACE N185.inSFVec2f BY 6 4 + } + } + ] + } + Transform2D { + children [ + DEF N187 TouchSensor {} + USE N1 + DEF N188 Valuator {} + DEF N189 Conditional { + buffer { + REPLACE N188.inSFVec2f BY 6 5 + } + } + ] + } + Transform2D { + children [ + DEF N190 TouchSensor {} + USE N1 + DEF N191 Valuator {} + DEF N192 Conditional { + buffer { + REPLACE N191.inSFVec2f BY 6 6 + } + } + ] + } + Transform2D { + children [ + DEF N193 TouchSensor {} + USE N1 + DEF N194 Valuator {} + DEF N195 Conditional { + buffer { + REPLACE N194.inSFVec2f BY 6 7 + } + } + ] + } + Transform2D { + children [ + DEF N196 TouchSensor {} + USE N1 + DEF N197 Valuator {} + DEF N198 Conditional { + buffer { + REPLACE N197.inSFVec2f BY 7 0 + } + } + ] + } + Transform2D { + children [ + DEF N199 TouchSensor {} + USE N1 + DEF N200 Valuator {} + DEF N201 Conditional { + buffer { + REPLACE N200.inSFVec2f BY 7 1 + } + } + ] + } + Transform2D { + children [ + DEF N202 TouchSensor {} + USE N1 + DEF N203 Valuator {} + DEF N204 Conditional { + buffer { + REPLACE N203.inSFVec2f BY 7 2 + } + } + ] + } + Transform2D { + children [ + DEF N205 TouchSensor {} + USE N1 + DEF N206 Valuator {} + DEF N207 Conditional { + buffer { + REPLACE N206.inSFVec2f BY 7 3 + } + } + ] + } + Transform2D { + children [ + DEF N208 TouchSensor {} + USE N1 + DEF N209 Valuator {} + DEF N210 Conditional { + buffer { + REPLACE N209.inSFVec2f BY 7 4 + } + } + ] + } + Transform2D { + children [ + DEF N211 TouchSensor {} + USE N1 + DEF N212 Valuator {} + DEF N213 Conditional { + buffer { + REPLACE N212.inSFVec2f BY 7 5 + } + } + ] + } + Transform2D { + children [ + DEF N214 TouchSensor {} + USE N1 + DEF N215 Valuator {} + DEF N216 Conditional { + buffer { + REPLACE N215.inSFVec2f BY 7 6 + } + } + ] + } + Transform2D { + children [ + DEF N217 TouchSensor {} + USE N1 + DEF N218 Valuator {} + DEF N219 Conditional { + buffer { + REPLACE N218.inSFVec2f BY 7 7 + } + } + ] + } + ] + } + ] + } + DEF N220 Script { + eventIn SFTime timeOut + eventIn SFBool startGame + eventIn SFVec2f click + eventIn SFInt32 keyPressed + eventIn SFInt32 keyReleased + field SFNode timer USE N0 + field MFNode sqtimages [ + USE N1 + USE N4 + USE N5 + ] + field MFNode sqimages [ + USE N6 + USE N10 + USE N11 + USE N12 + USE N13 + USE N14 + USE N15 + USE N16 + USE N17 + ] + field SFNode mineImage USE N18 + field SFNode noMineImage USE N20 + field SFNode mineredImage USE N19 + field SFNode flagsNode USE N23 + field SFNode conditionNode USE N24 + field SFNode elapsedNode USE N26 + field SFNode board USE N27 + field SFNode btndead USE N21 + field SFNode btncool USE N22 + url ["javascript: +function initialize() { + gridx=8; + gridy=8; + mines=new Array(gridx) ; + shown=new Array(gridy) ; + maxmines=10; + squaresleft=0; + flagsleft=0; + elapsedtime=0; + playing=0; + placeflag=0; + clicked=0; + gridSq=gridx*16; + grid8=gridSq-128; + grid16=gridx-8; + grid32=grid16*8; + grid64=grid16*16; + topBarWidth=8+grid64; + menuBarWidth=86+grid64; + wideWidth=gridx*16; + highHeight=gridy*16; + cplLeft=6+grid32; + cplRight=4+grid32; + totalWidth=gridSq+32; + tW6=totalWidth-6; + ww2=wideWidth+2; + newgame(0); +} +function keyPressed(value) { + print('keyPressed:'+value); + if (value) { + placeflag=true; + setStatus(); + } +} +function keyReleased(value) { + print('keyReleased'+value); + if (value) { + placeflag=false; + setStatus(); + } +} +function startGame(value,timestamp) { + if (value) { + newgame(timestamp); + } +} +function newgame(timestamp) { + for (y=0;y<gridy;++y){ + mines[y]=new Array(gridx) ; + shown[y]=new Array(gridx) ; + for (x=0;x<gridx;x++){ + mines[y][x]=false; + shown[y][x]=0; + board.children[x*gridx+y].children[1]=sqtimages[0]; + } + } + conditionNode.children[1]=btncool; + for (m=0;m<maxmines;++m){ + x=Math.floor(Math.random()*gridx); + y=Math.floor(Math.random()*gridy); + while (mines[y][x]){ + x=Math.floor(Math.random()*gridx); + y=Math.floor(Math.random()*gridy); + } + mines[y][x]=true; + } + squaresleft=gridy*gridx; + flagsleft=maxmines; + elapsedtime=0; + playing=true; + clicked=false; + placeflag=false; + timer.startTime=timestamp; + timer.enabled=true; +} +function timeOut(value,timestamp) { + ticker(); +} +function ticker() { + if (playing) { + if (clicked) { + elapsedtime++; + setStatus(); + } + } +} +function setStatus() { + elapsedNode.string[0]=''+elapsedtime; + flagsNode.string[0]=''+flagsleft; +} +function surrounding(y,x) { + count=0; + if (y>0&&x>0&&mines[y-1][x-1]) count++; + if (y>0&&mines[y-1][x]) count++; + if (y>0&&x<gridx-1&&mines[y-1][x+1]) count++; + if (x>0&&mines[y][x-1]) count++; + if (x<gridx-1&&mines[y][x+1]) count++; + if (y<gridy-1&&x>0&&mines[y+1][x-1]) count++; + if (y<gridy-1&&mines[y+1][x]) count++; + if (y<gridy-1&&x<gridx-1&&mines[y+1][x+1]) count++; + return count; + +} +function rollback(y,x) { + if (y>=0&&y<gridy&&x>=0&&x<gridx) { + if (shown[y][x]!=3) { + c=surrounding(y,x); + shown[y][x]=3; + squaresleft--; + board.children[x*gridx+y].children[1]=sqimages[c]; + if (c==0) { + rollback(y-1,x-1); + rollback(y-1,x); + rollback(y-1,x+1); + rollback(y,x-1); + rollback(y,x+1); + rollback(y+1,x-1); + rollback(y+1,x); + rollback(y+1,x+1); + } + } + } +} +function dead() { + for (y=0;y<gridy;++y){ + for (x=0;x<gridx;++x){ + if (mines[y][x]) { + if (shown[y][x]!=1) { + board.children[x*gridx+y].children[1]=mineImage; + } + } + else if (shown[y][x]==1) { + board.children[x*gridx+y].children[1]=noMineImage; + } + } + } + conditionNode.children[1]=btndead; + playing=false; + clicked=false; +} +function click(value) { + gridclick(value.y,value.x); +} +function gridclick(y,x) { + if (playing) { + clicked=true; + if (placeflag) { + if (shown[y][x]<3) { + s=shown[y][x]; + change=true; + if (s==1) { + flagsleft++; + squaresleft++; + } + if (flagsleft==0&&s==0) { + change=false; + } + else { + if (s==2) s=0; + else s++; + if (s==1) { + flagsleft--; + squaresleft--; + } + } + if (change) { + shown[y][x]=s; + board.children[x*gridx+y].children[1]=sqtimages[s]; + setStatus(); + } + if (squaresleft==0) { + conditionNode.children[1]=btncool; + playing=false; + } + } + } + else if (shown[y][x]!=1) { + if (mines[y][x]) { + board.children[x*gridx+y].children[1]=mineredImage; + dead(); + } + else { + rollback(y,x); + } + } + } +} + " + ] + } + ] +} + +ROUTE N25.isActive TO N220.startGame +ROUTE N0.cycleTime TO N220.timeOut +ROUTE N28.isActive TO N30.activate +ROUTE N29.outSFVec2f TO N220.click +ROUTE N31.isActive TO N33.activate +ROUTE N32.outSFVec2f TO N220.click +ROUTE N34.isActive TO N36.activate +ROUTE N35.outSFVec2f TO N220.click +ROUTE N37.isActive TO N39.activate +ROUTE N38.outSFVec2f TO N220.click +ROUTE N40.isActive TO N42.activate +ROUTE N41.outSFVec2f TO N220.click +ROUTE N43.isActive TO N45.activate +ROUTE N44.outSFVec2f TO N220.click +ROUTE N46.isActive TO N48.activate +ROUTE N47.outSFVec2f TO N220.click +ROUTE N49.isActive TO N51.activate +ROUTE N50.outSFVec2f TO N220.click +ROUTE N52.isActive TO N54.activate +ROUTE N53.outSFVec2f TO N220.click +ROUTE N55.isActive TO N57.activate +ROUTE N56.outSFVec2f TO N220.click +ROUTE N58.isActive TO N60.activate +ROUTE N59.outSFVec2f TO N220.click +ROUTE N61.isActive TO N63.activate +ROUTE N62.outSFVec2f TO N220.click +ROUTE N64.isActive TO N66.activate +ROUTE N65.outSFVec2f TO N220.click +ROUTE N67.isActive TO N69.activate +ROUTE N68.outSFVec2f TO N220.click +ROUTE N70.isActive TO N72.activate +ROUTE N71.outSFVec2f TO N220.click +ROUTE N73.isActive TO N75.activate +ROUTE N74.outSFVec2f TO N220.click +ROUTE N76.isActive TO N78.activate +ROUTE N77.outSFVec2f TO N220.click +ROUTE N79.isActive TO N81.activate +ROUTE N80.outSFVec2f TO N220.click +ROUTE N82.isActive TO N84.activate +ROUTE N83.outSFVec2f TO N220.click +ROUTE N85.isActive TO N87.activate +ROUTE N86.outSFVec2f TO N220.click +ROUTE N88.isActive TO N90.activate +ROUTE N89.outSFVec2f TO N220.click +ROUTE N91.isActive TO N93.activate +ROUTE N92.outSFVec2f TO N220.click +ROUTE N94.isActive TO N96.activate +ROUTE N95.outSFVec2f TO N220.click +ROUTE N97.isActive TO N99.activate +ROUTE N98.outSFVec2f TO N220.click +ROUTE N100.isActive TO N102.activate +ROUTE N101.outSFVec2f TO N220.click +ROUTE N103.isActive TO N105.activate +ROUTE N104.outSFVec2f TO N220.click +ROUTE N106.isActive TO N108.activate +ROUTE N107.outSFVec2f TO N220.click +ROUTE N109.isActive TO N111.activate +ROUTE N110.outSFVec2f TO N220.click +ROUTE N112.isActive TO N114.activate +ROUTE N113.outSFVec2f TO N220.click +ROUTE N115.isActive TO N117.activate +ROUTE N116.outSFVec2f TO N220.click +ROUTE N118.isActive TO N120.activate +ROUTE N119.outSFVec2f TO N220.click +ROUTE N121.isActive TO N123.activate +ROUTE N122.outSFVec2f TO N220.click +ROUTE N124.isActive TO N126.activate +ROUTE N125.outSFVec2f TO N220.click +ROUTE N127.isActive TO N129.activate +ROUTE N128.outSFVec2f TO N220.click +ROUTE N130.isActive TO N132.activate +ROUTE N131.outSFVec2f TO N220.click +ROUTE N133.isActive TO N135.activate +ROUTE N134.outSFVec2f TO N220.click +ROUTE N136.isActive TO N138.activate +ROUTE N137.outSFVec2f TO N220.click +ROUTE N139.isActive TO N141.activate +ROUTE N140.outSFVec2f TO N220.click +ROUTE N142.isActive TO N144.activate +ROUTE N143.outSFVec2f TO N220.click +ROUTE N145.isActive TO N147.activate +ROUTE N146.outSFVec2f TO N220.click +ROUTE N148.isActive TO N150.activate +ROUTE N149.outSFVec2f TO N220.click +ROUTE N151.isActive TO N153.activate +ROUTE N152.outSFVec2f TO N220.click +ROUTE N154.isActive TO N156.activate +ROUTE N155.outSFVec2f TO N220.click +ROUTE N157.isActive TO N159.activate +ROUTE N158.outSFVec2f TO N220.click +ROUTE N160.isActive TO N162.activate +ROUTE N161.outSFVec2f TO N220.click +ROUTE N163.isActive TO N165.activate +ROUTE N164.outSFVec2f TO N220.click +ROUTE N166.isActive TO N168.activate +ROUTE N167.outSFVec2f TO N220.click +ROUTE N169.isActive TO N171.activate +ROUTE N170.outSFVec2f TO N220.click +ROUTE N172.isActive TO N174.activate +ROUTE N173.outSFVec2f TO N220.click +ROUTE N175.isActive TO N177.activate +ROUTE N176.outSFVec2f TO N220.click +ROUTE N178.isActive TO N180.activate +ROUTE N179.outSFVec2f TO N220.click +ROUTE N181.isActive TO N183.activate +ROUTE N182.outSFVec2f TO N220.click +ROUTE N184.isActive TO N186.activate +ROUTE N185.outSFVec2f TO N220.click +ROUTE N187.isActive TO N189.activate +ROUTE N188.outSFVec2f TO N220.click +ROUTE N190.isActive TO N192.activate +ROUTE N191.outSFVec2f TO N220.click +ROUTE N193.isActive TO N195.activate +ROUTE N194.outSFVec2f TO N220.click +ROUTE N196.isActive TO N198.activate +ROUTE N197.outSFVec2f TO N220.click +ROUTE N199.isActive TO N201.activate +ROUTE N200.outSFVec2f TO N220.click +ROUTE N202.isActive TO N204.activate +ROUTE N203.outSFVec2f TO N220.click +ROUTE N205.isActive TO N207.activate +ROUTE N206.outSFVec2f TO N220.click +ROUTE N208.isActive TO N210.activate +ROUTE N209.outSFVec2f TO N220.click +ROUTE N211.isActive TO N213.activate +ROUTE N212.outSFVec2f TO N220.click +ROUTE N214.isActive TO N216.activate +ROUTE N215.outSFVec2f TO N220.click +ROUTE N217.isActive TO N219.activate +ROUTE N218.outSFVec2f TO N220.click + diff --git a/regression_tests/bifs/bifs-game-othello.bt b/regression_tests/bifs/bifs-game-othello.bt new file mode 100644 index 0000000..f471071 --- /dev/null +++ b/regression_tests/bifs/bifs-game-othello.bt @@ -0,0 +1,2836 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 1 + sceneProfileLevelIndication 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSv2Config { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team" + ] + title "Othello using BIFS and ECMAScript" + } + DEF TimeOutSensor TimeSensor { + enabled FALSE + cycleInterval 0.15 + } + Transform2D { + translation 0 180 + children [ + DEF StartTS TouchSensor {} + Shape { + geometry Rectangle { size 100 25 } + appearance Appearance { material Material2D { emissiveColor 0.5 0.5 0.5 filled TRUE } } + } + Shape { + appearance Appearance { + material Material2D { + filled TRUE + emissiveColor 1 0 0 + } + } + geometry Text { + string [ "Start Game" ] + fontStyle FontStyle { + size 20 + justify ["MIDDLE" "MIDDLE"] + } + } + } + ] + } + Switch { + whichChoice -1 + choice [ + DEF BlankPiece Transform2D { + children [ + DEF BackRectangle Shape { + geometry DEF R Rectangle { size 42 42 } + appearance Appearance { + material Material2D { + filled TRUE + emissiveColor 0 0.5 0.5 + } + } + } + Shape { + geometry DEF C Circle { radius 18 } + appearance Appearance { + material Material2D { + filled TRUE + emissiveColor 0 0.5 0.5 + } + } + } + ] + } + DEF WhitePiece Transform2D { + children [ + USE BackRectangle + DEF WhiteC Shape { + geometry USE C + appearance Appearance { + material Material2D { + filled TRUE + emissiveColor 1 1 1 + } + } + } + ] + } + DEF WhiteTransPiece Transform2D { + children [ + USE BackRectangle + USE WhiteC + ] + } + DEF BlackPiece Transform2D { + children [ + USE BackRectangle + DEF BlackC Shape { + geometry USE C + appearance Appearance { + material Material2D { + filled TRUE + emissiveColor 0 0 0 + } + } + } + ] + } + DEF BlackTransPiece Transform2D { + children [ + USE BackRectangle + USE BlackC + ] + } + DEF Trans1 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "1" ] + fontStyle DEF TFS FontStyle { + size 20 + justify [ "MIDDLE" "MIDDLE" ] + } + } + appearance DEF TA Appearance { + material Material2D { + filled TRUE + emissiveColor 0 1 0 + } + } + } + ] + } + DEF Trans2 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "2" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans3 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "3" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans4 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "4" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans5 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "5" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans6 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "6" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans7 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "7" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans8 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "8" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans9 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "9" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans10 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "10" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans11 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "11" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans12 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "12" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans13 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "13" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans14 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "14" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans15 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "15" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans16 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "16" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans17 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "17" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans18 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "18" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans19 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "19" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans20 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "20" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + DEF Trans21 Transform2D { + children [ + USE BackRectangle + Shape { + geometry Text { + string [ "21" ] + fontStyle USE TFS + } + appearance USE TA + } + ] + } + + ] + } + DEF Board Form { + size 345 345 + groups [ + 1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 7 -1 8 -1 + 9 -1 10 -1 11 -1 12 -1 13 -1 14 -1 15 -1 16 -1 + 17 -1 18 -1 19 -1 20 -1 21 -1 22 -1 23 -1 24 -1 + 25 -1 26 -1 27 -1 28 -1 29 -1 30 -1 31 -1 32 -1 + 33 -1 34 -1 35 -1 36 -1 37 -1 38 -1 39 -1 40 -1 + 41 -1 42 -1 43 -1 44 -1 45 -1 46 -1 47 -1 48 -1 + 49 -1 50 -1 51 -1 52 -1 53 -1 54 -1 55 -1 56 -1 + 57 -1 58 -1 59 -1 60 -1 61 -1 62 -1 63 -1 64 -1 + 1 2 3 4 5 6 7 8 -1 + 9 10 11 12 13 14 15 16 -1 + 17 18 19 20 21 22 23 24 -1 + 25 26 27 28 29 30 31 32 -1 + 33 34 35 36 37 38 39 40 -1 + 41 42 43 44 45 46 47 48 -1 + 49 50 51 52 53 54 55 56 -1 + 57 58 59 60 61 62 63 64 -1 + ] + groupsIndex [ + 1 2 3 4 5 6 7 8 -1 + 9 10 11 12 13 14 15 16 -1 + 17 18 19 20 21 22 23 24 -1 + 25 26 27 28 29 30 31 32 -1 + 33 34 35 36 37 38 39 40 -1 + 41 42 43 44 45 46 47 48 -1 + 49 50 51 52 53 54 55 56 -1 + 57 58 59 60 61 62 63 64 -1 + 65 66 67 68 69 70 71 72 -1 + ] + constraints [ + "SHin" + "SHin" + "SHin" + "SHin" + "SHin" + "SHin" + "SHin" + "SHin" + "SVin" + ] + children [ + Transform2D { + children [ + DEF TS00 TouchSensor {} + USE BlankPiece + DEF V00_Over Valuator {} + DEF V00_Out Valuator {} + DEF V00_Click Valuator {} + DEF C00_Over Conditional { + buffer { + REPLACE V00_Over.inSFVec2f BY 0 0 + } + } + DEF C00_Out Conditional { + buffer { + REPLACE V00_Out.inSFVec2f BY 0 0 + } + } + DEF C00_Click Conditional { + buffer { + REPLACE V00_Click.inSFVec2f BY 0 0 + } + } + ] + } + Transform2D { + children [ + DEF TS01 TouchSensor {} + USE BlankPiece + DEF V01_Over Valuator {} + DEF V01_Out Valuator {} + DEF V01_Click Valuator {} + DEF C01_Over Conditional { + buffer { + REPLACE V01_Over.inSFVec2f BY 0 1 + } + } + DEF C01_Out Conditional { + buffer { + REPLACE V01_Out.inSFVec2f BY 0 1 + } + } + DEF C01_Click Conditional { + buffer { + REPLACE V01_Click.inSFVec2f BY 0 1 + } + } + ] + } + Transform2D { + children [ + DEF TS02 TouchSensor {} + USE BlankPiece + DEF V02_Over Valuator {} + DEF V02_Out Valuator {} + DEF V02_Click Valuator {} + DEF C02_Over Conditional { + buffer { + REPLACE V02_Over.inSFVec2f BY 0 2 + } + } + DEF C02_Out Conditional { + buffer { + REPLACE V02_Out.inSFVec2f BY 0 2 + } + } + DEF C02_Click Conditional { + buffer { + REPLACE V02_Click.inSFVec2f BY 0 2 + } + } + ] + } + Transform2D { + children [ + DEF TS03 TouchSensor {} + USE BlankPiece + DEF V03_Over Valuator {} + DEF V03_Out Valuator {} + DEF V03_Click Valuator {} + DEF C03_Over Conditional { + buffer { + REPLACE V03_Over.inSFVec2f BY 0 3 + } + } + DEF C03_Out Conditional { + buffer { + REPLACE V03_Out.inSFVec2f BY 0 3 + } + } + DEF C03_Click Conditional { + buffer { + REPLACE V03_Click.inSFVec2f BY 0 3 + } + } + ] + } + Transform2D { + children [ + DEF TS04 TouchSensor {} + USE BlankPiece + DEF V04_Over Valuator {} + DEF V04_Out Valuator {} + DEF V04_Click Valuator {} + DEF C04_Over Conditional { + buffer { + REPLACE V04_Over.inSFVec2f BY 0 4 + } + } + DEF C04_Out Conditional { + buffer { + REPLACE V04_Out.inSFVec2f BY 0 4 + } + } + DEF C04_Click Conditional { + buffer { + REPLACE V04_Click.inSFVec2f BY 0 4 + } + } + ] + } + Transform2D { + children [ + DEF TS05 TouchSensor {} + USE BlankPiece + DEF V05_Over Valuator {} + DEF V05_Out Valuator {} + DEF V05_Click Valuator {} + DEF C05_Over Conditional { + buffer { + REPLACE V05_Over.inSFVec2f BY 0 5 + } + } + DEF C05_Out Conditional { + buffer { + REPLACE V05_Out.inSFVec2f BY 0 5 + } + } + DEF C05_Click Conditional { + buffer { + REPLACE V05_Click.inSFVec2f BY 0 5 + } + } + ] + } + Transform2D { + children [ + DEF TS06 TouchSensor {} + USE BlankPiece + DEF V06_Over Valuator {} + DEF V06_Out Valuator {} + DEF V06_Click Valuator {} + DEF C06_Over Conditional { + buffer { + REPLACE V06_Over.inSFVec2f BY 0 6 + } + } + DEF C06_Out Conditional { + buffer { + REPLACE V06_Out.inSFVec2f BY 0 6 + } + } + DEF C06_Click Conditional { + buffer { + REPLACE V06_Click.inSFVec2f BY 0 6 + } + } + ] + } + Transform2D { + children [ + DEF TS07 TouchSensor {} + USE BlankPiece + DEF V07_Over Valuator {} + DEF V07_Out Valuator {} + DEF V07_Click Valuator {} + DEF C07_Over Conditional { + buffer { + REPLACE V07_Over.inSFVec2f BY 0 7 + } + } + DEF C07_Out Conditional { + buffer { + REPLACE V07_Out.inSFVec2f BY 0 7 + } + } + DEF C07_Click Conditional { + buffer { + REPLACE V07_Click.inSFVec2f BY 0 7 + } + } + ] + } + Transform2D { + children [ + DEF TS10 TouchSensor {} + USE BlankPiece + DEF V10_Over Valuator {} + DEF V10_Out Valuator {} + DEF V10_Click Valuator {} + DEF C10_Over Conditional { + buffer { + REPLACE V10_Over.inSFVec2f BY 1 0 + } + } + DEF C10_Out Conditional { + buffer { + REPLACE V10_Out.inSFVec2f BY 1 0 + } + } + DEF C10_Click Conditional { + buffer { + REPLACE V10_Click.inSFVec2f BY 1 0 + } + } + ] + } + Transform2D { + children [ + DEF TS11 TouchSensor {} + USE BlankPiece + DEF V11_Over Valuator {} + DEF V11_Out Valuator {} + DEF V11_Click Valuator {} + DEF C11_Over Conditional { + buffer { + REPLACE V11_Over.inSFVec2f BY 1 1 + } + } + DEF C11_Out Conditional { + buffer { + REPLACE V11_Out.inSFVec2f BY 1 1 + } + } + DEF C11_Click Conditional { + buffer { + REPLACE V11_Click.inSFVec2f BY 1 1 + } + } + ] + } + Transform2D { + children [ + DEF TS12 TouchSensor {} + USE BlankPiece + DEF V12_Over Valuator {} + DEF V12_Out Valuator {} + DEF V12_Click Valuator {} + DEF C12_Over Conditional { + buffer { + REPLACE V12_Over.inSFVec2f BY 1 2 + } + } + DEF C12_Out Conditional { + buffer { + REPLACE V12_Out.inSFVec2f BY 1 2 + } + } + DEF C12_Click Conditional { + buffer { + REPLACE V12_Click.inSFVec2f BY 1 2 + } + } + ] + } + Transform2D { + children [ + DEF TS13 TouchSensor {} + USE BlankPiece + DEF V13_Over Valuator {} + DEF V13_Out Valuator {} + DEF V13_Click Valuator {} + DEF C13_Over Conditional { + buffer { + REPLACE V13_Over.inSFVec2f BY 1 3 + } + } + DEF C13_Out Conditional { + buffer { + REPLACE V13_Out.inSFVec2f BY 1 3 + } + } + DEF C13_Click Conditional { + buffer { + REPLACE V13_Click.inSFVec2f BY 1 3 + } + } + ] + } + Transform2D { + children [ + DEF TS14 TouchSensor {} + USE BlankPiece + DEF V14_Over Valuator {} + DEF V14_Out Valuator {} + DEF V14_Click Valuator {} + DEF C14_Over Conditional { + buffer { + REPLACE V14_Over.inSFVec2f BY 1 4 + } + } + DEF C14_Out Conditional { + buffer { + REPLACE V14_Out.inSFVec2f BY 1 4 + } + } + DEF C14_Click Conditional { + buffer { + REPLACE V14_Click.inSFVec2f BY 1 4 + } + } + ] + } + Transform2D { + children [ + DEF TS15 TouchSensor {} + USE BlankPiece + DEF V15_Over Valuator {} + DEF V15_Out Valuator {} + DEF V15_Click Valuator {} + DEF C15_Over Conditional { + buffer { + REPLACE V15_Over.inSFVec2f BY 1 5 + } + } + DEF C15_Out Conditional { + buffer { + REPLACE V15_Out.inSFVec2f BY 1 5 + } + } + DEF C15_Click Conditional { + buffer { + REPLACE V15_Click.inSFVec2f BY 1 5 + } + } + ] + } + Transform2D { + children [ + DEF TS16 TouchSensor {} + USE BlankPiece + DEF V16_Over Valuator {} + DEF V16_Out Valuator {} + DEF V16_Click Valuator {} + DEF C16_Over Conditional { + buffer { + REPLACE V16_Over.inSFVec2f BY 1 6 + } + } + DEF C16_Out Conditional { + buffer { + REPLACE V16_Out.inSFVec2f BY 1 6 + } + } + DEF C16_Click Conditional { + buffer { + REPLACE V16_Click.inSFVec2f BY 1 6 + } + } + ] + } + Transform2D { + children [ + DEF TS17 TouchSensor {} + USE BlankPiece + DEF V17_Over Valuator {} + DEF V17_Out Valuator {} + DEF V17_Click Valuator {} + DEF C17_Over Conditional { + buffer { + REPLACE V17_Over.inSFVec2f BY 1 7 + } + } + DEF C17_Out Conditional { + buffer { + REPLACE V17_Out.inSFVec2f BY 1 7 + } + } + DEF C17_Click Conditional { + buffer { + REPLACE V17_Click.inSFVec2f BY 1 7 + } + } + ] + } + Transform2D { + children [ + DEF TS20 TouchSensor {} + USE BlankPiece + DEF V20_Over Valuator {} + DEF V20_Out Valuator {} + DEF V20_Click Valuator {} + DEF C20_Over Conditional { + buffer { + REPLACE V20_Over.inSFVec2f BY 2 0 + } + } + DEF C20_Out Conditional { + buffer { + REPLACE V20_Out.inSFVec2f BY 2 0 + } + } + DEF C20_Click Conditional { + buffer { + REPLACE V20_Click.inSFVec2f BY 2 0 + } + } + ] + } + Transform2D { + children [ + DEF TS21 TouchSensor {} + USE BlankPiece + DEF V21_Over Valuator {} + DEF V21_Out Valuator {} + DEF V21_Click Valuator {} + DEF C21_Over Conditional { + buffer { + REPLACE V21_Over.inSFVec2f BY 2 1 + } + } + DEF C21_Out Conditional { + buffer { + REPLACE V21_Out.inSFVec2f BY 2 1 + } + } + DEF C21_Click Conditional { + buffer { + REPLACE V21_Click.inSFVec2f BY 2 1 + } + } + ] + } + Transform2D { + children [ + DEF TS22 TouchSensor {} + USE BlankPiece + DEF V22_Over Valuator {} + DEF V22_Out Valuator {} + DEF V22_Click Valuator {} + DEF C22_Over Conditional { + buffer { + REPLACE V22_Over.inSFVec2f BY 2 2 + } + } + DEF C22_Out Conditional { + buffer { + REPLACE V22_Out.inSFVec2f BY 2 2 + } + } + DEF C22_Click Conditional { + buffer { + REPLACE V22_Click.inSFVec2f BY 2 2 + } + } + ] + } + Transform2D { + children [ + DEF TS23 TouchSensor {} + USE BlankPiece + DEF V23_Over Valuator {} + DEF V23_Out Valuator {} + DEF V23_Click Valuator {} + DEF C23_Over Conditional { + buffer { + REPLACE V23_Over.inSFVec2f BY 2 3 + } + } + DEF C23_Out Conditional { + buffer { + REPLACE V23_Out.inSFVec2f BY 2 3 + } + } + DEF C23_Click Conditional { + buffer { + REPLACE V23_Click.inSFVec2f BY 2 3 + } + } + ] + } + Transform2D { + children [ + DEF TS24 TouchSensor {} + USE BlankPiece + DEF V24_Over Valuator {} + DEF V24_Out Valuator {} + DEF V24_Click Valuator {} + DEF C24_Over Conditional { + buffer { + REPLACE V24_Over.inSFVec2f BY 2 4 + } + } + DEF C24_Out Conditional { + buffer { + REPLACE V24_Out.inSFVec2f BY 2 4 + } + } + DEF C24_Click Conditional { + buffer { + REPLACE V24_Click.inSFVec2f BY 2 4 + } + } + ] + } + Transform2D { + children [ + DEF TS25 TouchSensor {} + USE BlankPiece + DEF V25_Over Valuator {} + DEF V25_Out Valuator {} + DEF V25_Click Valuator {} + DEF C25_Over Conditional { + buffer { + REPLACE V25_Over.inSFVec2f BY 2 5 + } + } + DEF C25_Out Conditional { + buffer { + REPLACE V25_Out.inSFVec2f BY 2 5 + } + } + DEF C25_Click Conditional { + buffer { + REPLACE V25_Click.inSFVec2f BY 2 5 + } + } + ] + } + Transform2D { + children [ + DEF TS26 TouchSensor {} + USE BlankPiece + DEF V26_Over Valuator {} + DEF V26_Out Valuator {} + DEF V26_Click Valuator {} + DEF C26_Over Conditional { + buffer { + REPLACE V26_Over.inSFVec2f BY 2 6 + } + } + DEF C26_Out Conditional { + buffer { + REPLACE V26_Out.inSFVec2f BY 2 6 + } + } + DEF C26_Click Conditional { + buffer { + REPLACE V26_Click.inSFVec2f BY 2 6 + } + } + ] + } + Transform2D { + children [ + DEF TS27 TouchSensor {} + USE BlankPiece + DEF V27_Over Valuator {} + DEF V27_Out Valuator {} + DEF V27_Click Valuator {} + DEF C27_Over Conditional { + buffer { + REPLACE V27_Over.inSFVec2f BY 2 7 + } + } + DEF C27_Out Conditional { + buffer { + REPLACE V27_Out.inSFVec2f BY 2 7 + } + } + DEF C27_Click Conditional { + buffer { + REPLACE V27_Click.inSFVec2f BY 2 7 + } + } + ] + } + Transform2D { + children [ + DEF TS30 TouchSensor {} + USE BlankPiece + DEF V30_Over Valuator {} + DEF V30_Out Valuator {} + DEF V30_Click Valuator {} + DEF C30_Over Conditional { + buffer { + REPLACE V30_Over.inSFVec2f BY 3 0 + } + } + DEF C30_Out Conditional { + buffer { + REPLACE V30_Out.inSFVec2f BY 3 0 + } + } + DEF C30_Click Conditional { + buffer { + REPLACE V30_Click.inSFVec2f BY 3 0 + } + } + ] + } + Transform2D { + children [ + DEF TS31 TouchSensor {} + USE BlankPiece + DEF V31_Over Valuator {} + DEF V31_Out Valuator {} + DEF V31_Click Valuator {} + DEF C31_Over Conditional { + buffer { + REPLACE V31_Over.inSFVec2f BY 3 1 + } + } + DEF C31_Out Conditional { + buffer { + REPLACE V31_Out.inSFVec2f BY 3 1 + } + } + DEF C31_Click Conditional { + buffer { + REPLACE V31_Click.inSFVec2f BY 3 1 + } + } + ] + } + Transform2D { + children [ + DEF TS32 TouchSensor {} + USE BlankPiece + DEF V32_Over Valuator {} + DEF V32_Out Valuator {} + DEF V32_Click Valuator {} + DEF C32_Over Conditional { + buffer { + REPLACE V32_Over.inSFVec2f BY 3 2 + } + } + DEF C32_Out Conditional { + buffer { + REPLACE V32_Out.inSFVec2f BY 3 2 + } + } + DEF C32_Click Conditional { + buffer { + REPLACE V32_Click.inSFVec2f BY 3 2 + } + } + ] + } + Transform2D { + children [ + DEF TS33 TouchSensor {} + USE WhitePiece + DEF V33_Over Valuator {} + DEF V33_Out Valuator {} + DEF V33_Click Valuator {} + DEF C33_Over Conditional { + buffer { + REPLACE V33_Over.inSFVec2f BY 3 3 + } + } + DEF C33_Out Conditional { + buffer { + REPLACE V33_Out.inSFVec2f BY 3 3 + } + } + DEF C33_Click Conditional { + buffer { + REPLACE V33_Click.inSFVec2f BY 3 3 + } + } + ] + } + Transform2D { + children [ + DEF TS34 TouchSensor {} + USE BlackPiece + DEF V34_Over Valuator {} + DEF V34_Out Valuator {} + DEF V34_Click Valuator {} + DEF C34_Over Conditional { + buffer { + REPLACE V34_Over.inSFVec2f BY 3 4 + } + } + DEF C34_Out Conditional { + buffer { + REPLACE V34_Out.inSFVec2f BY 3 4 + } + } + DEF C34_Click Conditional { + buffer { + REPLACE V34_Click.inSFVec2f BY 3 4 + } + } + ] + } + Transform2D { + children [ + DEF TS35 TouchSensor {} + USE BlankPiece + DEF V35_Over Valuator {} + DEF V35_Out Valuator {} + DEF V35_Click Valuator {} + DEF C35_Over Conditional { + buffer { + REPLACE V35_Over.inSFVec2f BY 3 5 + } + } + DEF C35_Out Conditional { + buffer { + REPLACE V35_Out.inSFVec2f BY 3 5 + } + } + DEF C35_Click Conditional { + buffer { + REPLACE V35_Click.inSFVec2f BY 3 5 + } + } + ] + } + Transform2D { + children [ + DEF TS36 TouchSensor {} + USE BlankPiece + DEF V36_Over Valuator {} + DEF V36_Out Valuator {} + DEF V36_Click Valuator {} + DEF C36_Over Conditional { + buffer { + REPLACE V36_Over.inSFVec2f BY 3 6 + } + } + DEF C36_Out Conditional { + buffer { + REPLACE V36_Out.inSFVec2f BY 3 6 + } + } + DEF C36_Click Conditional { + buffer { + REPLACE V36_Click.inSFVec2f BY 3 6 + } + } + ] + } + Transform2D { + children [ + DEF TS37 TouchSensor {} + USE BlankPiece + DEF V37_Over Valuator {} + DEF V37_Out Valuator {} + DEF V37_Click Valuator {} + DEF C37_Over Conditional { + buffer { + REPLACE V37_Over.inSFVec2f BY 3 7 + } + } + DEF C37_Out Conditional { + buffer { + REPLACE V37_Out.inSFVec2f BY 3 7 + } + } + DEF C37_Click Conditional { + buffer { + REPLACE V37_Click.inSFVec2f BY 3 7 + } + } + ] + } + Transform2D { + children [ + DEF TS40 TouchSensor {} + USE BlankPiece + DEF V40_Over Valuator {} + DEF V40_Out Valuator {} + DEF V40_Click Valuator {} + DEF C40_Over Conditional { + buffer { + REPLACE V40_Over.inSFVec2f BY 4 0 + } + } + DEF C40_Out Conditional { + buffer { + REPLACE V40_Out.inSFVec2f BY 4 0 + } + } + DEF C40_Click Conditional { + buffer { + REPLACE V40_Click.inSFVec2f BY 4 0 + } + } + ] + } + Transform2D { + children [ + DEF TS41 TouchSensor {} + USE BlankPiece + DEF V41_Over Valuator {} + DEF V41_Out Valuator {} + DEF V41_Click Valuator {} + DEF C41_Over Conditional { + buffer { + REPLACE V41_Over.inSFVec2f BY 4 1 + } + } + DEF C41_Out Conditional { + buffer { + REPLACE V41_Out.inSFVec2f BY 4 1 + } + } + DEF C41_Click Conditional { + buffer { + REPLACE V41_Click.inSFVec2f BY 4 1 + } + } + ] + } + Transform2D { + children [ + DEF TS42 TouchSensor {} + USE BlankPiece + DEF V42_Over Valuator {} + DEF V42_Out Valuator {} + DEF V42_Click Valuator {} + DEF C42_Over Conditional { + buffer { + REPLACE V42_Over.inSFVec2f BY 4 2 + } + } + DEF C42_Out Conditional { + buffer { + REPLACE V42_Out.inSFVec2f BY 4 2 + } + } + DEF C42_Click Conditional { + buffer { + REPLACE V42_Click.inSFVec2f BY 4 2 + } + } + ] + } + Transform2D { + children [ + DEF TS43 TouchSensor {} + USE BlackPiece + DEF V43_Over Valuator {} + DEF V43_Out Valuator {} + DEF V43_Click Valuator {} + DEF C43_Over Conditional { + buffer { + REPLACE V43_Over.inSFVec2f BY 4 3 + } + } + DEF C43_Out Conditional { + buffer { + REPLACE V43_Out.inSFVec2f BY 4 3 + } + } + DEF C43_Click Conditional { + buffer { + REPLACE V43_Click.inSFVec2f BY 4 3 + } + } + ] + } + Transform2D { + children [ + DEF TS44 TouchSensor {} + USE WhitePiece + DEF V44_Over Valuator {} + DEF V44_Out Valuator {} + DEF V44_Click Valuator {} + DEF C44_Over Conditional { + buffer { + REPLACE V44_Over.inSFVec2f BY 4 4 + } + } + DEF C44_Out Conditional { + buffer { + REPLACE V44_Out.inSFVec2f BY 4 4 + } + } + DEF C44_Click Conditional { + buffer { + REPLACE V44_Click.inSFVec2f BY 4 4 + } + } + ] + } + Transform2D { + children [ + DEF TS45 TouchSensor {} + USE BlankPiece + DEF V45_Over Valuator {} + DEF V45_Out Valuator {} + DEF V45_Click Valuator {} + DEF C45_Over Conditional { + buffer { + REPLACE V45_Over.inSFVec2f BY 4 5 + } + } + DEF C45_Out Conditional { + buffer { + REPLACE V45_Out.inSFVec2f BY 4 5 + } + } + DEF C45_Click Conditional { + buffer { + REPLACE V45_Click.inSFVec2f BY 4 5 + } + } + ] + } + Transform2D { + children [ + DEF TS46 TouchSensor {} + USE BlankPiece + DEF V46_Over Valuator {} + DEF V46_Out Valuator {} + DEF V46_Click Valuator {} + DEF C46_Over Conditional { + buffer { + REPLACE V46_Over.inSFVec2f BY 4 6 + } + } + DEF C46_Out Conditional { + buffer { + REPLACE V46_Out.inSFVec2f BY 4 6 + } + } + DEF C46_Click Conditional { + buffer { + REPLACE V46_Click.inSFVec2f BY 4 6 + } + } + ] + } + Transform2D { + children [ + DEF TS47 TouchSensor {} + USE BlankPiece + DEF V47_Over Valuator {} + DEF V47_Out Valuator {} + DEF V47_Click Valuator {} + DEF C47_Over Conditional { + buffer { + REPLACE V47_Over.inSFVec2f BY 4 7 + } + } + DEF C47_Out Conditional { + buffer { + REPLACE V47_Out.inSFVec2f BY 4 7 + } + } + DEF C47_Click Conditional { + buffer { + REPLACE V47_Click.inSFVec2f BY 4 7 + } + } + ] + } + Transform2D { + children [ + DEF TS50 TouchSensor {} + USE BlankPiece + DEF V50_Over Valuator {} + DEF V50_Out Valuator {} + DEF V50_Click Valuator {} + DEF C50_Over Conditional { + buffer { + REPLACE V50_Over.inSFVec2f BY 5 0 + } + } + DEF C50_Out Conditional { + buffer { + REPLACE V50_Out.inSFVec2f BY 5 0 + } + } + DEF C50_Click Conditional { + buffer { + REPLACE V50_Click.inSFVec2f BY 5 0 + } + } + ] + } + Transform2D { + children [ + DEF TS51 TouchSensor {} + USE BlankPiece + DEF V51_Over Valuator {} + DEF V51_Out Valuator {} + DEF V51_Click Valuator {} + DEF C51_Over Conditional { + buffer { + REPLACE V51_Over.inSFVec2f BY 5 1 + } + } + DEF C51_Out Conditional { + buffer { + REPLACE V51_Out.inSFVec2f BY 5 1 + } + } + DEF C51_Click Conditional { + buffer { + REPLACE V51_Click.inSFVec2f BY 5 1 + } + } + ] + } + Transform2D { + children [ + DEF TS52 TouchSensor {} + USE BlankPiece + DEF V52_Over Valuator {} + DEF V52_Out Valuator {} + DEF V52_Click Valuator {} + DEF C52_Over Conditional { + buffer { + REPLACE V52_Over.inSFVec2f BY 5 2 + } + } + DEF C52_Out Conditional { + buffer { + REPLACE V52_Out.inSFVec2f BY 5 2 + } + } + DEF C52_Click Conditional { + buffer { + REPLACE V52_Click.inSFVec2f BY 5 2 + } + } + ] + } + Transform2D { + children [ + DEF TS53 TouchSensor {} + USE BlankPiece + DEF V53_Over Valuator {} + DEF V53_Out Valuator {} + DEF V53_Click Valuator {} + DEF C53_Over Conditional { + buffer { + REPLACE V53_Over.inSFVec2f BY 5 3 + } + } + DEF C53_Out Conditional { + buffer { + REPLACE V53_Out.inSFVec2f BY 5 3 + } + } + DEF C53_Click Conditional { + buffer { + REPLACE V53_Click.inSFVec2f BY 5 3 + } + } + ] + } + Transform2D { + children [ + DEF TS54 TouchSensor {} + USE BlankPiece + DEF V54_Over Valuator {} + DEF V54_Out Valuator {} + DEF V54_Click Valuator {} + DEF C54_Over Conditional { + buffer { + REPLACE V54_Over.inSFVec2f BY 5 4 + } + } + DEF C54_Out Conditional { + buffer { + REPLACE V54_Out.inSFVec2f BY 5 4 + } + } + DEF C54_Click Conditional { + buffer { + REPLACE V54_Click.inSFVec2f BY 5 4 + } + } + ] + } + Transform2D { + children [ + DEF TS55 TouchSensor {} + USE BlankPiece + DEF V55_Over Valuator {} + DEF V55_Out Valuator {} + DEF V55_Click Valuator {} + DEF C55_Over Conditional { + buffer { + REPLACE V55_Over.inSFVec2f BY 5 5 + } + } + DEF C55_Out Conditional { + buffer { + REPLACE V55_Out.inSFVec2f BY 5 5 + } + } + DEF C55_Click Conditional { + buffer { + REPLACE V55_Click.inSFVec2f BY 5 5 + } + } + ] + } + Transform2D { + children [ + DEF TS56 TouchSensor {} + USE BlankPiece + DEF V56_Over Valuator {} + DEF V56_Out Valuator {} + DEF V56_Click Valuator {} + DEF C56_Over Conditional { + buffer { + REPLACE V56_Over.inSFVec2f BY 5 6 + } + } + DEF C56_Out Conditional { + buffer { + REPLACE V56_Out.inSFVec2f BY 5 6 + } + } + DEF C56_Click Conditional { + buffer { + REPLACE V56_Click.inSFVec2f BY 5 6 + } + } + ] + } + Transform2D { + children [ + DEF TS57 TouchSensor {} + USE BlankPiece + DEF V57_Over Valuator {} + DEF V57_Out Valuator {} + DEF V57_Click Valuator {} + DEF C57_Over Conditional { + buffer { + REPLACE V57_Over.inSFVec2f BY 5 7 + } + } + DEF C57_Out Conditional { + buffer { + REPLACE V57_Out.inSFVec2f BY 5 7 + } + } + DEF C57_Click Conditional { + buffer { + REPLACE V57_Click.inSFVec2f BY 5 7 + } + } + ] + } + Transform2D { + children [ + DEF TS60 TouchSensor {} + USE BlankPiece + DEF V60_Over Valuator {} + DEF V60_Out Valuator {} + DEF V60_Click Valuator {} + DEF C60_Over Conditional { + buffer { + REPLACE V60_Over.inSFVec2f BY 6 0 + } + } + DEF C60_Out Conditional { + buffer { + REPLACE V60_Out.inSFVec2f BY 6 0 + } + } + DEF C60_Click Conditional { + buffer { + REPLACE V60_Click.inSFVec2f BY 6 0 + } + } + ] + } + Transform2D { + children [ + DEF TS61 TouchSensor {} + USE BlankPiece + DEF V61_Over Valuator {} + DEF V61_Out Valuator {} + DEF V61_Click Valuator {} + DEF C61_Over Conditional { + buffer { + REPLACE V61_Over.inSFVec2f BY 6 1 + } + } + DEF C61_Out Conditional { + buffer { + REPLACE V61_Out.inSFVec2f BY 6 1 + } + } + DEF C61_Click Conditional { + buffer { + REPLACE V61_Click.inSFVec2f BY 6 1 + } + } + ] + } + Transform2D { + children [ + DEF TS62 TouchSensor {} + USE BlankPiece + DEF V62_Over Valuator {} + DEF V62_Out Valuator {} + DEF V62_Click Valuator {} + DEF C62_Over Conditional { + buffer { + REPLACE V62_Over.inSFVec2f BY 6 2 + } + } + DEF C62_Out Conditional { + buffer { + REPLACE V62_Out.inSFVec2f BY 6 2 + } + } + DEF C62_Click Conditional { + buffer { + REPLACE V62_Click.inSFVec2f BY 6 2 + } + } + ] + } + Transform2D { + children [ + DEF TS63 TouchSensor {} + USE BlankPiece + DEF V63_Over Valuator {} + DEF V63_Out Valuator {} + DEF V63_Click Valuator {} + DEF C63_Over Conditional { + buffer { + REPLACE V63_Over.inSFVec2f BY 6 3 + } + } + DEF C63_Out Conditional { + buffer { + REPLACE V63_Out.inSFVec2f BY 6 3 + } + } + DEF C63_Click Conditional { + buffer { + REPLACE V63_Click.inSFVec2f BY 6 3 + } + } + ] + } + Transform2D { + children [ + DEF TS64 TouchSensor {} + USE BlankPiece + DEF V64_Over Valuator {} + DEF V64_Out Valuator {} + DEF V64_Click Valuator {} + DEF C64_Over Conditional { + buffer { + REPLACE V64_Over.inSFVec2f BY 6 4 + } + } + DEF C64_Out Conditional { + buffer { + REPLACE V64_Out.inSFVec2f BY 6 4 + } + } + DEF C64_Click Conditional { + buffer { + REPLACE V64_Click.inSFVec2f BY 6 4 + } + } + ] + } + Transform2D { + children [ + DEF TS65 TouchSensor {} + USE BlankPiece + DEF V65_Over Valuator {} + DEF V65_Out Valuator {} + DEF V65_Click Valuator {} + DEF C65_Over Conditional { + buffer { + REPLACE V65_Over.inSFVec2f BY 6 5 + } + } + DEF C65_Out Conditional { + buffer { + REPLACE V65_Out.inSFVec2f BY 6 5 + } + } + DEF C65_Click Conditional { + buffer { + REPLACE V65_Click.inSFVec2f BY 6 5 + } + } + ] + } + Transform2D { + children [ + DEF TS66 TouchSensor {} + USE BlankPiece + DEF V66_Over Valuator {} + DEF V66_Out Valuator {} + DEF V66_Click Valuator {} + DEF C66_Over Conditional { + buffer { + REPLACE V66_Over.inSFVec2f BY 6 6 + } + } + DEF C66_Out Conditional { + buffer { + REPLACE V66_Out.inSFVec2f BY 6 6 + } + } + DEF C66_Click Conditional { + buffer { + REPLACE V66_Click.inSFVec2f BY 6 6 + } + } + ] + } + Transform2D { + children [ + DEF TS67 TouchSensor {} + USE BlankPiece + DEF V67_Over Valuator {} + DEF V67_Out Valuator {} + DEF V67_Click Valuator {} + DEF C67_Over Conditional { + buffer { + REPLACE V67_Over.inSFVec2f BY 6 7 + } + } + DEF C67_Out Conditional { + buffer { + REPLACE V67_Out.inSFVec2f BY 6 7 + } + } + DEF C67_Click Conditional { + buffer { + REPLACE V67_Click.inSFVec2f BY 6 7 + } + } + ] + } + Transform2D { + children [ + DEF TS70 TouchSensor {} + USE BlankPiece + DEF V70_Over Valuator {} + DEF V70_Out Valuator {} + DEF V70_Click Valuator {} + DEF C70_Over Conditional { + buffer { + REPLACE V70_Over.inSFVec2f BY 7 0 + } + } + DEF C70_Out Conditional { + buffer { + REPLACE V70_Out.inSFVec2f BY 7 0 + } + } + DEF C70_Click Conditional { + buffer { + REPLACE V70_Click.inSFVec2f BY 7 0 + } + } + ] + } + Transform2D { + children [ + DEF TS71 TouchSensor {} + USE BlankPiece + DEF V71_Over Valuator {} + DEF V71_Out Valuator {} + DEF V71_Click Valuator {} + DEF C71_Over Conditional { + buffer { + REPLACE V71_Over.inSFVec2f BY 7 1 + } + } + DEF C71_Out Conditional { + buffer { + REPLACE V71_Out.inSFVec2f BY 7 1 + } + } + DEF C71_Click Conditional { + buffer { + REPLACE V71_Click.inSFVec2f BY 7 1 + } + } + ] + } + Transform2D { + children [ + DEF TS72 TouchSensor {} + USE BlankPiece + DEF V72_Over Valuator {} + DEF V72_Out Valuator {} + DEF V72_Click Valuator {} + DEF C72_Over Conditional { + buffer { + REPLACE V72_Over.inSFVec2f BY 7 2 + } + } + DEF C72_Out Conditional { + buffer { + REPLACE V72_Out.inSFVec2f BY 7 2 + } + } + DEF C72_Click Conditional { + buffer { + REPLACE V72_Click.inSFVec2f BY 7 2 + } + } + ] + } + Transform2D { + children [ + DEF TS73 TouchSensor {} + USE BlankPiece + DEF V73_Over Valuator {} + DEF V73_Out Valuator {} + DEF V73_Click Valuator {} + DEF C73_Over Conditional { + buffer { + REPLACE V73_Over.inSFVec2f BY 7 3 + } + } + DEF C73_Out Conditional { + buffer { + REPLACE V73_Out.inSFVec2f BY 7 3 + } + } + DEF C73_Click Conditional { + buffer { + REPLACE V73_Click.inSFVec2f BY 7 3 + } + } + ] + } + Transform2D { + children [ + DEF TS74 TouchSensor {} + USE BlankPiece + DEF V74_Over Valuator {} + DEF V74_Out Valuator {} + DEF V74_Click Valuator {} + DEF C74_Over Conditional { + buffer { + REPLACE V74_Over.inSFVec2f BY 7 4 + } + } + DEF C74_Out Conditional { + buffer { + REPLACE V74_Out.inSFVec2f BY 7 4 + } + } + DEF C74_Click Conditional { + buffer { + REPLACE V74_Click.inSFVec2f BY 7 4 + } + } + ] + } + Transform2D { + children [ + DEF TS75 TouchSensor {} + USE BlankPiece + DEF V75_Over Valuator {} + DEF V75_Out Valuator {} + DEF V75_Click Valuator {} + DEF C75_Over Conditional { + buffer { + REPLACE V75_Over.inSFVec2f BY 7 5 + } + } + DEF C75_Out Conditional { + buffer { + REPLACE V75_Out.inSFVec2f BY 7 5 + } + } + DEF C75_Click Conditional { + buffer { + REPLACE V75_Click.inSFVec2f BY 7 5 + } + } + ] + } + Transform2D { + children [ + DEF TS76 TouchSensor {} + USE BlankPiece + DEF V76_Over Valuator {} + DEF V76_Out Valuator {} + DEF V76_Click Valuator {} + DEF C76_Over Conditional { + buffer { + REPLACE V76_Over.inSFVec2f BY 7 6 + } + } + DEF C76_Out Conditional { + buffer { + REPLACE V76_Out.inSFVec2f BY 7 6 + } + } + DEF C76_Click Conditional { + buffer { + REPLACE V76_Click.inSFVec2f BY 7 6 + } + } + ] + } + Transform2D { + children [ + DEF TS77 TouchSensor {} + USE BlankPiece + DEF V77_Over Valuator {} + DEF V77_Out Valuator {} + DEF V77_Click Valuator {} + DEF C77_Over Conditional { + buffer { + REPLACE V77_Over.inSFVec2f BY 7 7 + } + } + DEF C77_Out Conditional { + buffer { + REPLACE V77_Out.inSFVec2f BY 7 7 + } + } + DEF C77_Click Conditional { + buffer { + REPLACE V77_Click.inSFVec2f BY 7 7 + } + } + ] + } + ] + } + DEF SC Script { +eventIn SFBool startGame +eventIn SFVec2f mouseOver +eventIn SFVec2f mouseOut +eventIn SFVec2f click +eventIn SFBool timeOut + +field SFNode timer USE TimeOutSensor + +# some internal global variables +field MFNode picture [ + USE BlankPiece + USE WhitePiece + USE BlackPiece + USE WhiteTransPiece + USE BlackTransPiece + USE Trans1 + USE Trans2 + USE Trans3 + USE Trans4 + USE Trans5 + USE Trans6 + USE Trans7 + USE Trans8 + USE Trans9 + USE Trans10 + USE Trans11 + USE Trans12 + USE Trans13 + USE Trans14 + USE Trans15 + USE Trans16 + USE Trans17 + USE Trans18 + USE Trans19 + USE Trans20 + USE Trans21 +] +field SFNode images USE Board + + url "javascript: +// JavaScript Othello Game +// Copyright (c) 2000, 2001 Kelly Yancey <kbyanc@posi.net> +// All rights reserved. +// +// Redistribution and use in source form, with or without modification, is +// permitted provided that the following conditions are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer, +// without modification, immediately at the beginning of the file. +// 2. All advertising materials mentioning features or use of this software +// must display the following acknowledgement: +// This product includes software developed by Kelly Yancey +// and a reference to the URL http://www.posi.net/software/othello/ +// 3. The name of the author may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// picture numbers +function initialize() { +EMPTY = 0; // empty square +WHITE = 1; // white piece +BLACK = 2; // black piece +WHITETRANS = 3; // white transparent cursor piece +BLACKTRANS = 4; // black transparent cursor piece +NUMBASE = 5; // beginning of numeric pictures + +// size of the pictures used to represent pieces (all pictures must be the same size) +piecewidth = 42; +pieceheight = 42; + +// size of the board +width = 8; +height = 8; + +// player settings +human = BLACK; +showcursor = true; // display cursor showing user where they can go +showflips = false; // display counts showing how many pieces they can flip by putting a piece in a given square + +// AI settings +weightsquares = 1; // whether AI prefers squares that yield higher flip counts +edgesensitive = 1; // whether AI is sensitive to the importance of edge squares + +// some internal global variables +board = new Array(width); +score = new Array(); +turn = BLACK; + + +human = BLACK; +showcursor = true; +showflips = true; +weightsquares = true; +edgesensitive = true; + +InitializeBoard(); + +Play(0); + +} + +function piece(x,y) { +// object definition for 'piece' type + this.imagenum = x * width + y; + this.player = EMPTY; + // how many pieces each player could flip by taking this square + this.flips = new Array(); + this.flips[WHITE] = 0; + this.flips[BLACK] = 0; + // how valuable this location is to each player + this.value = new Array(); + this.value[WHITE] = 0; + this.value[BLACK] = 0; +} + + +function SetPieceImage(x, y, src) { +// routine to set the image associated with the given piece + if(images.children[board[x][y].imagenum].children[1] != src) { + // we explicitely check to see if we are changing the image source to prevent + // unnecessary redrawing of images which do not change + images.children[board[x][y].imagenum].children[1] = src; + } +} + +function InitializeBoard() { +// routine to initialize the state of the game and draw the board + // build the board array + for(x = 0; x < width; x++) + board[x] = new Array (height); + + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + // place initial pieces + if((x == 3 && y == 3) || (x == 4 && y == 4)) player = WHITE; + else if((x == 3 && y == 4) || (x == 4 && y == 3)) player = BLACK; + else player = EMPTY; + board[x][y] = new piece(x,y); + board[x][y].player = player; + } + } + // initialize scores + score[WHITE] = 2; + score[BLACK] = 2; +} + +function ResetBoard() { +// routine to reset all of the pieces on the board + + // reset the board + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + board[x][y].player = EMPTY; + SetPieceImage(x, y, picture[EMPTY]); + } + } + + // reset scores + score[WHITE] = 0; + score[BLACK] = 0; + + // put initial pieces back on the board + RawPutPiece(3, 3, WHITE); + RawPutPiece(4, 4, WHITE); + RawPutPiece(3, 4, BLACK); + RawPutPiece(4, 3, BLACK); + + turn = BLACK; +} + +function NumFlips(x, y, player) { + count = 0; + + for(deltay = -1; deltay <= 1; deltay++) { + for(deltax = -1; deltax <= 1; deltax++) { + for(distance = 1;; distance++) { + posx = x + (distance * deltax); + posy = y + (distance * deltay); + // stop if we go off the board + if(posx < 0 || posx >= width || posy < 0 || posy >= height) + break; + // stop when we reach an empty square + if(board[posx][posy].player == EMPTY) + break; + // only update the flip count when we reach another of the + // player's pieces + if(board[posx][posy].player == player) { + count += distance - 1; + break; + } + } + } + } + return(count); +} + +function CalcFlipCounts() { + + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + board[x][y].flips[WHITE] = 0; + board[x][y].flips[BLACK] = 0; + + if(board[x][y].player != EMPTY) continue; + + board[x][y].flips[WHITE] = NumFlips(x, y, WHITE); + board[x][y].flips[BLACK] = NumFlips(x, y, BLACK); + } + } +} + +function RawPutPiece(x, y, player) { + other = OtherPlayer(player); + if(board[x][y].player == other) score[other]--; + + board[x][y].player = player; + SetPieceImage(x, y, picture[player]); + score[player]++; +} + +function FlipPieces(x, y, player) { + count = 0; + + // put a piece down at the desired location + RawPutPiece(x, y, player); + + for(deltay = -1; deltay <= 1; deltay++) { + for(deltax = -1; deltax <= 1; deltax++) { + for(distance = 1;; distance++) { + posx = x + (distance * deltax); + posy = y + (distance * deltay); + // stop if we go off the board + if(posx < 0 || posx >= width || posy < 0 || posy >= height) + break; + // stop when we reach an empty square + if(board[posx][posy].player == EMPTY) + break; + if(board[posx][posy].player == player) { + // backtrack, flipping pieces + for(distance--; distance > 0; distance--) { + posx = x + (distance * deltax); + posy = y + (distance * deltay); + RawPutPiece(posx, posy, player); + } + break; + } + } + } + } + return(count); +} + +function AnyMoves(player) { + + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + if(board[x][y].player != EMPTY) continue; + if(NumFlips(x, y, player) > 0) return(true); + } + } + return(false); +} + +function CanPutPiece(x, y, player) { +// determine whether the player can put a piece at the given position + if(turn != player) + return(false); + if(board[x][y].player != EMPTY) + return(false); + return(NumFlips(x, y, player) > 0); +} + +function CheckPutPiece(x, y) { + if(! showcursor) return; + if(! CanPutPiece(x, y, human)) return; + if(human == WHITE) over = WHITETRANS; + else over = BLACKTRANS; + + SetPieceImage(x, y, picture[over]); +} + +function RestorePiece(x, y) { + if(showflips && RawShowFlipCount(x, y, human)) return; + SetPieceImage(x, y, picture[board[x][y].player]); +} + +function PutPiece(x, y, timestamp) { + if(! CanPutPiece(x, y, human)) return; + + FlipPieces(x, y, human); + DoneTurn(timestamp); +} + +function RawShowFlipCount(x, y, player) { + if(board[x][y].player != EMPTY) return(false); + if((flips = board[x][y].flips[player]) == 0) return(false); + SetPieceImage(x, y, picture[NUMBASE + flips]); + return(true); +} + +function ShowFlipCounts(player) { + + CalcFlipCounts(); + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + RawShowFlipCount(x, y, player); + } + } +} + +function HideFlipCounts() { + + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + if(board[x][y].player == EMPTY) + SetPieceImage(x, y, picture[EMPTY]); + } + } +} + +function OtherPlayer(player) { + return((player == WHITE)? BLACK: WHITE); +} + +function DoneTurn(timestamp) { + moves = AnyMoves(turn); + turn = OtherPlayer(turn); + + // check whether the new player has any moves + if(! AnyMoves(turn)) { + if(! moves) return(GameOver()); + + // XXX inform user the player has no move + // and switch players again + turn = OtherPlayer(turn); + } + + // add a slight delay before the computer takes it's turn so game feels + // 'warmer'; when computer is playing itself, add larger delay so user + // can watch + if(turn != human) { + HideFlipCounts(); + timer.cycleInterval = ((human == EMPTY)? 1: 0.150); + timer.startTime = timestamp; + timer.enabled = true; + } else if(showflips) ShowFlipCounts(human); +} + +function Rate(x, y, player) { + + if(board[x][y].player != EMPTY) return(0); + if(x < 0 || x >= width || y < 0 || y >= height) return(0); + + rating = board[x][y].flips[player]; + + if(! weightsquares) + rating = (rating > 0)? 1: 0; + + if(edgesensitive && rating > 0) { + // increase all non-zero weightings by 3 so we have room + // to wait 'less ideal' squares below the baseline + rating += 10; + + // raise edge ratings 4 points, corners are raised 8 + if(x == 0 || x == width - 1) rating += 4; + if(y == 0 || y == height - 1) rating += 4; + // lower next-to-edge ratings by 5 points, next-to-corner by 10 + if(x == 1 || x == width - 2) rating -= 5; + if(y == 1 || y == height - 2) rating -= 5; + + // we cannot rule out a move because of bad location; we must + // always go somewhere + if(rating < 1) rating = 1; + } + return(rating); +} + +function OthelloAI(player, timestamp) { + best = 0; + numbest = 0; + + // rank each position on the board by the potential flip count + CalcFlipCounts(); + + // apply AI rating algorithm + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + rating = Rate(x, y, player); + + // store the rating back into the board + board[x][y].value[player] = rating; + + if(rating == best) + numbest++; + else if(rating > best) { + best = rating; + numbest = 1; + } + } + } + + while(numbest > 0) { + // pick a square to put our piece + pick = Math.floor(Math.random() * numbest); + count = 0; + for(y = 0; y < height; y++) { + for(x = 0; x < width; x++) { + rating = board[x][y].value[player]; + if(rating == best) { + if(count == pick) { + FlipPieces(x, y, player); + DoneTurn(timestamp); + return; + } + else count++; + } + } + } + } + + // if we make it here, then there was nowhere to go + DoneTurn(timestamp); +} + +function Play(timestamp) { + // black always goes first + if(human != BLACK) + OthelloAI(BLACK,timestamp); + else if(showflips) + ShowFlipCounts(human); +} + +function GameOver() { + turn = EMPTY; +} + +function timeOut(value, timestamp) { + if (!value) { + OthelloAI(turn, timestamp); + } +} + +function startGame(value,timestamp) { + if (value) { + Play(timestamp); + } +} + +function click(value, timestamp) { + PutPiece(value.x, value.y, timestamp); +} + +function mouseOver(value) { + CheckPutPiece(value.x, value.y); +} + +function mouseOut(value) { + RestorePiece(value.x, value.y); +} + + + " + } + ] +} +ROUTE StartTS.isActive TO SC.startGame +ROUTE TimeOutSensor.isActive TO SC.timeOut + +ROUTE TS00.isActive TO C00_Click.activate +ROUTE TS00.isOver TO C00_Over.activate +ROUTE TS00.isOver TO C00_Out.reverseActivate +ROUTE V00_Over.outSFVec2f TO SC.mouseOver +ROUTE V00_Out.outSFVec2f TO SC.mouseOut +ROUTE V00_Click.outSFVec2f TO SC.click +ROUTE TS01.isActive TO C01_Click.activate +ROUTE TS01.isOver TO C01_Over.activate +ROUTE TS01.isOver TO C01_Out.reverseActivate +ROUTE V01_Over.outSFVec2f TO SC.mouseOver +ROUTE V01_Out.outSFVec2f TO SC.mouseOut +ROUTE V01_Click.outSFVec2f TO SC.click +ROUTE TS02.isActive TO C02_Click.activate +ROUTE TS02.isOver TO C02_Over.activate +ROUTE TS02.isOver TO C02_Out.reverseActivate +ROUTE V02_Over.outSFVec2f TO SC.mouseOver +ROUTE V02_Out.outSFVec2f TO SC.mouseOut +ROUTE V02_Click.outSFVec2f TO SC.click +ROUTE TS03.isActive TO C03_Click.activate +ROUTE TS03.isOver TO C03_Over.activate +ROUTE TS03.isOver TO C03_Out.reverseActivate +ROUTE V03_Over.outSFVec2f TO SC.mouseOver +ROUTE V03_Out.outSFVec2f TO SC.mouseOut +ROUTE V03_Click.outSFVec2f TO SC.click +ROUTE TS04.isActive TO C04_Click.activate +ROUTE TS04.isOver TO C04_Over.activate +ROUTE TS04.isOver TO C04_Out.reverseActivate +ROUTE V04_Over.outSFVec2f TO SC.mouseOver +ROUTE V04_Out.outSFVec2f TO SC.mouseOut +ROUTE V04_Click.outSFVec2f TO SC.click +ROUTE TS05.isActive TO C05_Click.activate +ROUTE TS05.isOver TO C05_Over.activate +ROUTE TS05.isOver TO C05_Out.reverseActivate +ROUTE V05_Over.outSFVec2f TO SC.mouseOver +ROUTE V05_Out.outSFVec2f TO SC.mouseOut +ROUTE V05_Click.outSFVec2f TO SC.click +ROUTE TS06.isActive TO C06_Click.activate +ROUTE TS06.isOver TO C06_Over.activate +ROUTE TS06.isOver TO C06_Out.reverseActivate +ROUTE V06_Over.outSFVec2f TO SC.mouseOver +ROUTE V06_Out.outSFVec2f TO SC.mouseOut +ROUTE V06_Click.outSFVec2f TO SC.click +ROUTE TS07.isActive TO C07_Click.activate +ROUTE TS07.isOver TO C07_Over.activate +ROUTE TS07.isOver TO C07_Out.reverseActivate +ROUTE V07_Over.outSFVec2f TO SC.mouseOver +ROUTE V07_Out.outSFVec2f TO SC.mouseOut +ROUTE V07_Click.outSFVec2f TO SC.click +ROUTE TS10.isActive TO C10_Click.activate +ROUTE TS10.isOver TO C10_Over.activate +ROUTE TS10.isOver TO C10_Out.reverseActivate +ROUTE V10_Over.outSFVec2f TO SC.mouseOver +ROUTE V10_Out.outSFVec2f TO SC.mouseOut +ROUTE V10_Click.outSFVec2f TO SC.click +ROUTE TS11.isActive TO C11_Click.activate +ROUTE TS11.isOver TO C11_Over.activate +ROUTE TS11.isOver TO C11_Out.reverseActivate +ROUTE V11_Over.outSFVec2f TO SC.mouseOver +ROUTE V11_Out.outSFVec2f TO SC.mouseOut +ROUTE V11_Click.outSFVec2f TO SC.click +ROUTE TS12.isActive TO C12_Click.activate +ROUTE TS12.isOver TO C12_Over.activate +ROUTE TS12.isOver TO C12_Out.reverseActivate +ROUTE V12_Over.outSFVec2f TO SC.mouseOver +ROUTE V12_Out.outSFVec2f TO SC.mouseOut +ROUTE V12_Click.outSFVec2f TO SC.click +ROUTE TS13.isActive TO C13_Click.activate +ROUTE TS13.isOver TO C13_Over.activate +ROUTE TS13.isOver TO C13_Out.reverseActivate +ROUTE V13_Over.outSFVec2f TO SC.mouseOver +ROUTE V13_Out.outSFVec2f TO SC.mouseOut +ROUTE V13_Click.outSFVec2f TO SC.click +ROUTE TS14.isActive TO C14_Click.activate +ROUTE TS14.isOver TO C14_Over.activate +ROUTE TS14.isOver TO C14_Out.reverseActivate +ROUTE V14_Over.outSFVec2f TO SC.mouseOver +ROUTE V14_Out.outSFVec2f TO SC.mouseOut +ROUTE V14_Click.outSFVec2f TO SC.click +ROUTE TS15.isActive TO C15_Click.activate +ROUTE TS15.isOver TO C15_Over.activate +ROUTE TS15.isOver TO C15_Out.reverseActivate +ROUTE V15_Over.outSFVec2f TO SC.mouseOver +ROUTE V15_Out.outSFVec2f TO SC.mouseOut +ROUTE V15_Click.outSFVec2f TO SC.click +ROUTE TS16.isActive TO C16_Click.activate +ROUTE TS16.isOver TO C16_Over.activate +ROUTE TS16.isOver TO C16_Out.reverseActivate +ROUTE V16_Over.outSFVec2f TO SC.mouseOver +ROUTE V16_Out.outSFVec2f TO SC.mouseOut +ROUTE V16_Click.outSFVec2f TO SC.click +ROUTE TS17.isActive TO C17_Click.activate +ROUTE TS17.isOver TO C17_Over.activate +ROUTE TS17.isOver TO C17_Out.reverseActivate +ROUTE V17_Over.outSFVec2f TO SC.mouseOver +ROUTE V17_Out.outSFVec2f TO SC.mouseOut +ROUTE V17_Click.outSFVec2f TO SC.click +ROUTE TS20.isActive TO C20_Click.activate +ROUTE TS20.isOver TO C20_Over.activate +ROUTE TS20.isOver TO C20_Out.reverseActivate +ROUTE V20_Over.outSFVec2f TO SC.mouseOver +ROUTE V20_Out.outSFVec2f TO SC.mouseOut +ROUTE V20_Click.outSFVec2f TO SC.click +ROUTE TS21.isActive TO C21_Click.activate +ROUTE TS21.isOver TO C21_Over.activate +ROUTE TS21.isOver TO C21_Out.reverseActivate +ROUTE V21_Over.outSFVec2f TO SC.mouseOver +ROUTE V21_Out.outSFVec2f TO SC.mouseOut +ROUTE V21_Click.outSFVec2f TO SC.click +ROUTE TS22.isActive TO C22_Click.activate +ROUTE TS22.isOver TO C22_Over.activate +ROUTE TS22.isOver TO C22_Out.reverseActivate +ROUTE V22_Over.outSFVec2f TO SC.mouseOver +ROUTE V22_Out.outSFVec2f TO SC.mouseOut +ROUTE V22_Click.outSFVec2f TO SC.click +ROUTE TS23.isActive TO C23_Click.activate +ROUTE TS23.isOver TO C23_Over.activate +ROUTE TS23.isOver TO C23_Out.reverseActivate +ROUTE V23_Over.outSFVec2f TO SC.mouseOver +ROUTE V23_Out.outSFVec2f TO SC.mouseOut +ROUTE V23_Click.outSFVec2f TO SC.click +ROUTE TS24.isActive TO C24_Click.activate +ROUTE TS24.isOver TO C24_Over.activate +ROUTE TS24.isOver TO C24_Out.reverseActivate +ROUTE V24_Over.outSFVec2f TO SC.mouseOver +ROUTE V24_Out.outSFVec2f TO SC.mouseOut +ROUTE V24_Click.outSFVec2f TO SC.click +ROUTE TS25.isActive TO C25_Click.activate +ROUTE TS25.isOver TO C25_Over.activate +ROUTE TS25.isOver TO C25_Out.reverseActivate +ROUTE V25_Over.outSFVec2f TO SC.mouseOver +ROUTE V25_Out.outSFVec2f TO SC.mouseOut +ROUTE V25_Click.outSFVec2f TO SC.click +ROUTE TS26.isActive TO C26_Click.activate +ROUTE TS26.isOver TO C26_Over.activate +ROUTE TS26.isOver TO C26_Out.reverseActivate +ROUTE V26_Over.outSFVec2f TO SC.mouseOver +ROUTE V26_Out.outSFVec2f TO SC.mouseOut +ROUTE V26_Click.outSFVec2f TO SC.click +ROUTE TS27.isActive TO C27_Click.activate +ROUTE TS27.isOver TO C27_Over.activate +ROUTE TS27.isOver TO C27_Out.reverseActivate +ROUTE V27_Over.outSFVec2f TO SC.mouseOver +ROUTE V27_Out.outSFVec2f TO SC.mouseOut +ROUTE V27_Click.outSFVec2f TO SC.click +ROUTE TS30.isActive TO C30_Click.activate +ROUTE TS30.isOver TO C30_Over.activate +ROUTE TS30.isOver TO C30_Out.reverseActivate +ROUTE V30_Over.outSFVec2f TO SC.mouseOver +ROUTE V30_Out.outSFVec2f TO SC.mouseOut +ROUTE V30_Click.outSFVec2f TO SC.click +ROUTE TS31.isActive TO C31_Click.activate +ROUTE TS31.isOver TO C31_Over.activate +ROUTE TS31.isOver TO C31_Out.reverseActivate +ROUTE V31_Over.outSFVec2f TO SC.mouseOver +ROUTE V31_Out.outSFVec2f TO SC.mouseOut +ROUTE V31_Click.outSFVec2f TO SC.click +ROUTE TS32.isActive TO C32_Click.activate +ROUTE TS32.isOver TO C32_Over.activate +ROUTE TS32.isOver TO C32_Out.reverseActivate +ROUTE V32_Over.outSFVec2f TO SC.mouseOver +ROUTE V32_Out.outSFVec2f TO SC.mouseOut +ROUTE V32_Click.outSFVec2f TO SC.click +ROUTE TS33.isActive TO C33_Click.activate +ROUTE TS33.isOver TO C33_Over.activate +ROUTE TS33.isOver TO C33_Out.reverseActivate +ROUTE V33_Over.outSFVec2f TO SC.mouseOver +ROUTE V33_Out.outSFVec2f TO SC.mouseOut +ROUTE V33_Click.outSFVec2f TO SC.click +ROUTE TS34.isActive TO C34_Click.activate +ROUTE TS34.isOver TO C34_Over.activate +ROUTE TS34.isOver TO C34_Out.reverseActivate +ROUTE V34_Over.outSFVec2f TO SC.mouseOver +ROUTE V34_Out.outSFVec2f TO SC.mouseOut +ROUTE V34_Click.outSFVec2f TO SC.click +ROUTE TS35.isActive TO C35_Click.activate +ROUTE TS35.isOver TO C35_Over.activate +ROUTE TS35.isOver TO C35_Out.reverseActivate +ROUTE V35_Over.outSFVec2f TO SC.mouseOver +ROUTE V35_Out.outSFVec2f TO SC.mouseOut +ROUTE V35_Click.outSFVec2f TO SC.click +ROUTE TS36.isActive TO C36_Click.activate +ROUTE TS36.isOver TO C36_Over.activate +ROUTE TS36.isOver TO C36_Out.reverseActivate +ROUTE V36_Over.outSFVec2f TO SC.mouseOver +ROUTE V36_Out.outSFVec2f TO SC.mouseOut +ROUTE V36_Click.outSFVec2f TO SC.click +ROUTE TS37.isActive TO C37_Click.activate +ROUTE TS37.isOver TO C37_Over.activate +ROUTE TS37.isOver TO C37_Out.reverseActivate +ROUTE V37_Over.outSFVec2f TO SC.mouseOver +ROUTE V37_Out.outSFVec2f TO SC.mouseOut +ROUTE V37_Click.outSFVec2f TO SC.click +ROUTE TS40.isActive TO C40_Click.activate +ROUTE TS40.isOver TO C40_Over.activate +ROUTE TS40.isOver TO C40_Out.reverseActivate +ROUTE V40_Over.outSFVec2f TO SC.mouseOver +ROUTE V40_Out.outSFVec2f TO SC.mouseOut +ROUTE V40_Click.outSFVec2f TO SC.click +ROUTE TS41.isActive TO C41_Click.activate +ROUTE TS41.isOver TO C41_Over.activate +ROUTE TS41.isOver TO C41_Out.reverseActivate +ROUTE V41_Over.outSFVec2f TO SC.mouseOver +ROUTE V41_Out.outSFVec2f TO SC.mouseOut +ROUTE V41_Click.outSFVec2f TO SC.click +ROUTE TS42.isActive TO C42_Click.activate +ROUTE TS42.isOver TO C42_Over.activate +ROUTE TS42.isOver TO C42_Out.reverseActivate +ROUTE V42_Over.outSFVec2f TO SC.mouseOver +ROUTE V42_Out.outSFVec2f TO SC.mouseOut +ROUTE V42_Click.outSFVec2f TO SC.click +ROUTE TS43.isActive TO C43_Click.activate +ROUTE TS43.isOver TO C43_Over.activate +ROUTE TS43.isOver TO C43_Out.reverseActivate +ROUTE V43_Over.outSFVec2f TO SC.mouseOver +ROUTE V43_Out.outSFVec2f TO SC.mouseOut +ROUTE V43_Click.outSFVec2f TO SC.click +ROUTE TS44.isActive TO C44_Click.activate +ROUTE TS44.isOver TO C44_Over.activate +ROUTE TS44.isOver TO C44_Out.reverseActivate +ROUTE V44_Over.outSFVec2f TO SC.mouseOver +ROUTE V44_Out.outSFVec2f TO SC.mouseOut +ROUTE V44_Click.outSFVec2f TO SC.click +ROUTE TS45.isActive TO C45_Click.activate +ROUTE TS45.isOver TO C45_Over.activate +ROUTE TS45.isOver TO C45_Out.reverseActivate +ROUTE V45_Over.outSFVec2f TO SC.mouseOver +ROUTE V45_Out.outSFVec2f TO SC.mouseOut +ROUTE V45_Click.outSFVec2f TO SC.click +ROUTE TS46.isActive TO C46_Click.activate +ROUTE TS46.isOver TO C46_Over.activate +ROUTE TS46.isOver TO C46_Out.reverseActivate +ROUTE V46_Over.outSFVec2f TO SC.mouseOver +ROUTE V46_Out.outSFVec2f TO SC.mouseOut +ROUTE V46_Click.outSFVec2f TO SC.click +ROUTE TS47.isActive TO C47_Click.activate +ROUTE TS47.isOver TO C47_Over.activate +ROUTE TS47.isOver TO C47_Out.reverseActivate +ROUTE V47_Over.outSFVec2f TO SC.mouseOver +ROUTE V47_Out.outSFVec2f TO SC.mouseOut +ROUTE V47_Click.outSFVec2f TO SC.click +ROUTE TS50.isActive TO C50_Click.activate +ROUTE TS50.isOver TO C50_Over.activate +ROUTE TS50.isOver TO C50_Out.reverseActivate +ROUTE V50_Over.outSFVec2f TO SC.mouseOver +ROUTE V50_Out.outSFVec2f TO SC.mouseOut +ROUTE V50_Click.outSFVec2f TO SC.click +ROUTE TS51.isActive TO C51_Click.activate +ROUTE TS51.isOver TO C51_Over.activate +ROUTE TS51.isOver TO C51_Out.reverseActivate +ROUTE V51_Over.outSFVec2f TO SC.mouseOver +ROUTE V51_Out.outSFVec2f TO SC.mouseOut +ROUTE V51_Click.outSFVec2f TO SC.click +ROUTE TS52.isActive TO C52_Click.activate +ROUTE TS52.isOver TO C52_Over.activate +ROUTE TS52.isOver TO C52_Out.reverseActivate +ROUTE V52_Over.outSFVec2f TO SC.mouseOver +ROUTE V52_Out.outSFVec2f TO SC.mouseOut +ROUTE V52_Click.outSFVec2f TO SC.click +ROUTE TS53.isActive TO C53_Click.activate +ROUTE TS53.isOver TO C53_Over.activate +ROUTE TS53.isOver TO C53_Out.reverseActivate +ROUTE V53_Over.outSFVec2f TO SC.mouseOver +ROUTE V53_Out.outSFVec2f TO SC.mouseOut +ROUTE V53_Click.outSFVec2f TO SC.click +ROUTE TS54.isActive TO C54_Click.activate +ROUTE TS54.isOver TO C54_Over.activate +ROUTE TS54.isOver TO C54_Out.reverseActivate +ROUTE V54_Over.outSFVec2f TO SC.mouseOver +ROUTE V54_Out.outSFVec2f TO SC.mouseOut +ROUTE V54_Click.outSFVec2f TO SC.click +ROUTE TS55.isActive TO C55_Click.activate +ROUTE TS55.isOver TO C55_Over.activate +ROUTE TS55.isOver TO C55_Out.reverseActivate +ROUTE V55_Over.outSFVec2f TO SC.mouseOver +ROUTE V55_Out.outSFVec2f TO SC.mouseOut +ROUTE V55_Click.outSFVec2f TO SC.click +ROUTE TS56.isActive TO C56_Click.activate +ROUTE TS56.isOver TO C56_Over.activate +ROUTE TS56.isOver TO C56_Out.reverseActivate +ROUTE V56_Over.outSFVec2f TO SC.mouseOver +ROUTE V56_Out.outSFVec2f TO SC.mouseOut +ROUTE V56_Click.outSFVec2f TO SC.click +ROUTE TS57.isActive TO C57_Click.activate +ROUTE TS57.isOver TO C57_Over.activate +ROUTE TS57.isOver TO C57_Out.reverseActivate +ROUTE V57_Over.outSFVec2f TO SC.mouseOver +ROUTE V57_Out.outSFVec2f TO SC.mouseOut +ROUTE V57_Click.outSFVec2f TO SC.click +ROUTE TS60.isActive TO C60_Click.activate +ROUTE TS60.isOver TO C60_Over.activate +ROUTE TS60.isOver TO C60_Out.reverseActivate +ROUTE V60_Over.outSFVec2f TO SC.mouseOver +ROUTE V60_Out.outSFVec2f TO SC.mouseOut +ROUTE V60_Click.outSFVec2f TO SC.click +ROUTE TS61.isActive TO C61_Click.activate +ROUTE TS61.isOver TO C61_Over.activate +ROUTE TS61.isOver TO C61_Out.reverseActivate +ROUTE V61_Over.outSFVec2f TO SC.mouseOver +ROUTE V61_Out.outSFVec2f TO SC.mouseOut +ROUTE V61_Click.outSFVec2f TO SC.click +ROUTE TS62.isActive TO C62_Click.activate +ROUTE TS62.isOver TO C62_Over.activate +ROUTE TS62.isOver TO C62_Out.reverseActivate +ROUTE V62_Over.outSFVec2f TO SC.mouseOver +ROUTE V62_Out.outSFVec2f TO SC.mouseOut +ROUTE V62_Click.outSFVec2f TO SC.click +ROUTE TS63.isActive TO C63_Click.activate +ROUTE TS63.isOver TO C63_Over.activate +ROUTE TS63.isOver TO C63_Out.reverseActivate +ROUTE V63_Over.outSFVec2f TO SC.mouseOver +ROUTE V63_Out.outSFVec2f TO SC.mouseOut +ROUTE V63_Click.outSFVec2f TO SC.click +ROUTE TS64.isActive TO C64_Click.activate +ROUTE TS64.isOver TO C64_Over.activate +ROUTE TS64.isOver TO C64_Out.reverseActivate +ROUTE V64_Over.outSFVec2f TO SC.mouseOver +ROUTE V64_Out.outSFVec2f TO SC.mouseOut +ROUTE V64_Click.outSFVec2f TO SC.click +ROUTE TS65.isActive TO C65_Click.activate +ROUTE TS65.isOver TO C65_Over.activate +ROUTE TS65.isOver TO C65_Out.reverseActivate +ROUTE V65_Over.outSFVec2f TO SC.mouseOver +ROUTE V65_Out.outSFVec2f TO SC.mouseOut +ROUTE V65_Click.outSFVec2f TO SC.click +ROUTE TS66.isActive TO C66_Click.activate +ROUTE TS66.isOver TO C66_Over.activate +ROUTE TS66.isOver TO C66_Out.reverseActivate +ROUTE V66_Over.outSFVec2f TO SC.mouseOver +ROUTE V66_Out.outSFVec2f TO SC.mouseOut +ROUTE V66_Click.outSFVec2f TO SC.click +ROUTE TS67.isActive TO C67_Click.activate +ROUTE TS67.isOver TO C67_Over.activate +ROUTE TS67.isOver TO C67_Out.reverseActivate +ROUTE V67_Over.outSFVec2f TO SC.mouseOver +ROUTE V67_Out.outSFVec2f TO SC.mouseOut +ROUTE V67_Click.outSFVec2f TO SC.click +ROUTE TS70.isActive TO C70_Click.activate +ROUTE TS70.isOver TO C70_Over.activate +ROUTE TS70.isOver TO C70_Out.reverseActivate +ROUTE V70_Over.outSFVec2f TO SC.mouseOver +ROUTE V70_Out.outSFVec2f TO SC.mouseOut +ROUTE V70_Click.outSFVec2f TO SC.click +ROUTE TS71.isActive TO C71_Click.activate +ROUTE TS71.isOver TO C71_Over.activate +ROUTE TS71.isOver TO C71_Out.reverseActivate +ROUTE V71_Over.outSFVec2f TO SC.mouseOver +ROUTE V71_Out.outSFVec2f TO SC.mouseOut +ROUTE V71_Click.outSFVec2f TO SC.click +ROUTE TS72.isActive TO C72_Click.activate +ROUTE TS72.isOver TO C72_Over.activate +ROUTE TS72.isOver TO C72_Out.reverseActivate +ROUTE V72_Over.outSFVec2f TO SC.mouseOver +ROUTE V72_Out.outSFVec2f TO SC.mouseOut +ROUTE V72_Click.outSFVec2f TO SC.click +ROUTE TS73.isActive TO C73_Click.activate +ROUTE TS73.isOver TO C73_Over.activate +ROUTE TS73.isOver TO C73_Out.reverseActivate +ROUTE V73_Over.outSFVec2f TO SC.mouseOver +ROUTE V73_Out.outSFVec2f TO SC.mouseOut +ROUTE V73_Click.outSFVec2f TO SC.click +ROUTE TS74.isActive TO C74_Click.activate +ROUTE TS74.isOver TO C74_Over.activate +ROUTE TS74.isOver TO C74_Out.reverseActivate +ROUTE V74_Over.outSFVec2f TO SC.mouseOver +ROUTE V74_Out.outSFVec2f TO SC.mouseOut +ROUTE V74_Click.outSFVec2f TO SC.click +ROUTE TS75.isActive TO C75_Click.activate +ROUTE TS75.isOver TO C75_Over.activate +ROUTE TS75.isOver TO C75_Out.reverseActivate +ROUTE V75_Over.outSFVec2f TO SC.mouseOver +ROUTE V75_Out.outSFVec2f TO SC.mouseOut +ROUTE V75_Click.outSFVec2f TO SC.click +ROUTE TS76.isActive TO C76_Click.activate +ROUTE TS76.isOver TO C76_Over.activate +ROUTE TS76.isOver TO C76_Out.reverseActivate +ROUTE V76_Over.outSFVec2f TO SC.mouseOver +ROUTE V76_Out.outSFVec2f TO SC.mouseOut +ROUTE V76_Click.outSFVec2f TO SC.click +ROUTE TS77.isActive TO C77_Click.activate +ROUTE TS77.isOver TO C77_Over.activate +ROUTE TS77.isOver TO C77_Out.reverseActivate +ROUTE V77_Over.outSFVec2f TO SC.mouseOver +ROUTE V77_Out.outSFVec2f TO SC.mouseOut +ROUTE V77_Click.outSFVec2f TO SC.click diff --git a/regression_tests/bifs/bifs-interpolation-colorinterpolator.bt b/regression_tests/bifs/bifs-interpolation-colorinterpolator.bt new file mode 100644 index 0000000..bad4c4e --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-colorinterpolator.bt @@ -0,0 +1,63 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 240 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows color interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Color Interpolator" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + DEF TS TimeSensor { + loop TRUE + } + DEF SI ColorInterpolator { + key [0 0.5 1] + keyValue [1 0 0 0 1 0 1 0 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +DEF R1 ROUTE SI.value_changed TO MAT.emissiveColor + diff --git a/regression_tests/bifs/bifs-interpolation-coordinateinterpolator2D.bt b/regression_tests/bifs/bifs-interpolation-coordinateinterpolator2D.bt new file mode 100644 index 0000000..0813b97 --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-coordinateinterpolator2D.bt @@ -0,0 +1,64 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows scaling interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Position Interpolator" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF SI CoordinateInterpolator2D { + key [0 0.25 0.5 0.75 1] + keyValue [-100 0 -50 100 50 100 100 0 50 -100 -50 -100 100 0 -50 100 50 100 -100 0 50 -100 -50 -100 -100 0 -50 100 50 100 100 0 50 -100 -50 -100 -100 0 50 100 -50 100 100 0 -50 -100 50 -100 -100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO COORD.point + diff --git a/regression_tests/bifs/bifs-interpolation-positionanimator.bt b/regression_tests/bifs/bifs-interpolation-positionanimator.bt new file mode 100644 index 0000000..8b012af --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-positionanimator.bt @@ -0,0 +1,63 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0x01 + sceneProfileLevelIndication 0x01 + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFE + graphicsProfileLevelIndication 0x01 + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 200 + } + } + } + ] +} + +Group { + children [ + Viewpoint {position 0 0 100 } + WorldInfo { + title "PositionAnimator test" + info ["This shows PositionAnimator using bezier spline interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + DEF BACK Background2D { backColor 1 1 1} + DEF TR Transform { + scale 0.5 0.5 0.5 + rotation 1 1 1 0.75 + children [ + Shape { + appearance Appearance { material DEF MAT Material { diffuseColor 1 0 0} } + geometry Box {size 50 50 50} + } + ] + } + DEF TS TimeSensor { + cycleInterval 4.0 + loop TRUE + } + DEF V Valuator { + Factor2 0 + Offset2 0.5 + } + DEF SI PositionAnimator { + key [0 0.25 0.5 0.75 1] + + keyValueType 1 + keyValue [-50 0 -50, 0 50 0, 50 0 -50] + keyType 4 + keySpline [0.75 0, 0.25 1] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +DEF R1 ROUTE SI.value_changed TO TR.translation diff --git a/regression_tests/bifs/bifs-interpolation-positionanimator2D.bt b/regression_tests/bifs/bifs-interpolation-positionanimator2D.bt new file mode 100644 index 0000000..abb4320 --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-positionanimator2D.bt @@ -0,0 +1,65 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0x01 + sceneProfileLevelIndication 0x01 + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFE + graphicsProfileLevelIndication 0x01 + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + title "PositionAnimator2D test" + info ["This shows PositionAnimator2D using bezier spline interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + DEF BACK Background2D { backColor 1 1 1} + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { material DEF MAT Material2D { emissiveColor 1 0 0 filled TRUE } } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0, -50 100, 50 100, 100 0, 50 -100, -50 -100] + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 4.0 + loop TRUE + } + DEF V Valuator { + Factor2 0 + Offset2 0.5 + } + DEF SI PositionAnimator2D { + key [0 0.25 0.5 0.75 1] + + keyValueType 1 + keyValue [-50 0 0 50 50 0] + keyType 4 + keySpline [0.75 0, 0.25 1] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +DEF R1 ROUTE SI.value_changed TO TR.translation diff --git a/regression_tests/bifs/bifs-interpolation-positioninterpolator-position.bt b/regression_tests/bifs/bifs-interpolation-positioninterpolator-position.bt new file mode 100644 index 0000000..834629a --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-positioninterpolator-position.bt @@ -0,0 +1,94 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + NavigationInfo {type ["ANY" "EXAMINE"]} + WorldInfo { + info ["This shows position interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "PositionInterpolator" + } + Transform { + children [ + Shape { + appearance Appearance { + texture MovieTexture { + loop TRUE + url [od:10] + } + } + geometry Box { + size 100 100 100 + } + } + ] + } + DEF TR Transform { + children [ + Shape { + appearance Appearance { + material Material {diffuseColor 0 1 0 } + } + geometry Box { + size 100 100 100 + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 10 + loop TRUE + } + DEF SI PositionInterpolator { + key [0 0.25 0.5 0.75 1] + keyValue [100 100 100, -100 100 -100, -100 -100 -100, 100 -100 100, 100 100 100] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO TR.translation + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-interpolation-positioninterpolator-size.bt b/regression_tests/bifs/bifs-interpolation-positioninterpolator-size.bt new file mode 100644 index 0000000..7091a9f --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-positioninterpolator-size.bt @@ -0,0 +1,58 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +Group { + children [ + WorldInfo { + info ["This shows 3D size interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "PositionInterpolator" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform { + scale 0.5 0.5 0.5 + rotation 1 1 1 0.75 + children [ + Shape { + appearance Appearance { + material DEF MAT Material {diffuseColor 1 0 0 } + } + geometry Box {size 100 100 50} + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF SI PositionInterpolator { + key [0 0.25 0.5 0.75 1] + keyValue [1 1 1, 1 2 0.25, 1 1 1, 2 1 1.75, 1 1 1] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO TR.scale + diff --git a/regression_tests/bifs/bifs-interpolation-positioninterpolator2D-position.bt b/regression_tests/bifs/bifs-interpolation-positioninterpolator2D-position.bt new file mode 100644 index 0000000..3878baa --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-positioninterpolator2D-position.bt @@ -0,0 +1,96 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows 2D position interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "PositionInterpolator2D" + } + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + texture MovieTexture { + loop TRUE + url [od:10] + } + } + geometry Rectangle { + size 100 100 + } + } + ] + } + DEF TR2 Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 10 + loop TRUE + } + DEF SI PositionInterpolator2D { + key [0 0.25 0.5 0.75 1] + keyValue [100 100 -100 100 -100 -100 100 -100 100 100] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO TR2.translation + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-interpolation-positioninterpolator2D-size.bt b/regression_tests/bifs/bifs-interpolation-positioninterpolator2D-size.bt new file mode 100644 index 0000000..2da915b --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-positioninterpolator2D-size.bt @@ -0,0 +1,64 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows 2D size interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "PositionInterpolator2D" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + DEF SI PositionInterpolator2D { + key [0 0.25 0.5 0.75 1] + keyValue [1 1 2 1 1 1 1 2 1 1] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO TR.scale + diff --git a/regression_tests/bifs/bifs-interpolation-scalaranimator.bt b/regression_tests/bifs/bifs-interpolation-scalaranimator.bt new file mode 100644 index 0000000..7f1f217 --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-scalaranimator.bt @@ -0,0 +1,66 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0x01 + sceneProfileLevelIndication 0x01 + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFE + graphicsProfileLevelIndication 0x01 + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + title "ScalarAnimator test" + info ["This shows ScalarAnimator using bezier spline interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + DEF BACK Background2D { backColor 1 1 1} + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { material DEF MAT Material2D { emissiveColor 1 0 0 filled TRUE } } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0, -50 100, 50 100, 100 0, 50 -100, -50 -100] + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 4.0 + loop TRUE + } + DEF V Valuator { + Factor2 0 + Offset2 0.5 + } + DEF SI ScalarAnimator { +# key [0 0.25 0.5 0.75 1] + + keyValueType 2 + keyValue [0.5 0.0 1 0.5] + keyType 2 + keySpline [0.4 0.5, 0.15 0.15] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +DEF R1 ROUTE SI.value_changed TO V.inSFFloat +ROUTE V.outSFVec2f TO TR.scale diff --git a/regression_tests/bifs/bifs-interpolation-scalarinterpolator.bt b/regression_tests/bifs/bifs-interpolation-scalarinterpolator.bt new file mode 100644 index 0000000..a5c15b3 --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-scalarinterpolator.bt @@ -0,0 +1,63 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This shows transparency interpolation" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Scalar Interpolator" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + DEF TS TimeSensor { + loop TRUE + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +DEF R1 ROUTE SI.value_changed TO MAT.transparency + diff --git a/regression_tests/bifs/bifs-interpolation-timesensor-enabled.bt b/regression_tests/bifs/bifs-interpolation-timesensor-enabled.bt new file mode 100644 index 0000000..99edc1a --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-timesensor-enabled.bt @@ -0,0 +1,82 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of timesensor" "with enabling/disabling" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "TimeSensor enabled test" + } + Transform2D { + translation -100 0 + children [ + DEF N3 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Rectangle { + size 80 80 + } + } + ] + } + DEF N2 TimeSensor { + cycleInterval 10 + enabled FALSE + loop TRUE + stopTime -1 + } + DEF N0 PositionInterpolator2D { + key [0 1] + keyValue [100 -100 100 100] + } + DEF N4 Transform2D { + translation 100 -100 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 0.5 0.5 + filled TRUE + } + } + geometry Rectangle { + size 80 80 + } + } + ] + } + ] +} + +ROUTE N3.isOver TO N2.enabled +ROUTE N2.fraction_changed TO N0.set_fraction +ROUTE N0.value_changed TO N4.translation + diff --git a/regression_tests/bifs/bifs-interpolation-timesensor-starttime_norestart.bt b/regression_tests/bifs/bifs-interpolation-timesensor-starttime_norestart.bt new file mode 100644 index 0000000..1478c75 --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-timesensor-starttime_norestart.bt @@ -0,0 +1,81 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of timesensor start time" "Animation shall not be restartable until over" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:09 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "TimeSensor startTime test" + } + Transform2D { + translation -100 0 + children [ + DEF N3 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Rectangle { + size 80 80 + } + } + ] + } + DEF N2 TimeSensor { + cycleInterval 2 + startTime 2 + stopTime -1 + } + DEF N0 PositionInterpolator2D { + key [0 1] + keyValue [100 -100 100 100] + } + DEF N4 Transform2D { + translation 100 -100 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 0.5 0.5 + filled TRUE + } + } + geometry Rectangle { + size 80 80 + } + } + ] + } + ] +} + +ROUTE N3.touchTime TO N2.startTime +ROUTE N2.fraction_changed TO N0.set_fraction +ROUTE N0.value_changed TO N4.translation + diff --git a/regression_tests/bifs/bifs-interpolation-timesensor-starttime_restart.bt b/regression_tests/bifs/bifs-interpolation-timesensor-starttime_restart.bt new file mode 100644 index 0000000..f43bf6a --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-timesensor-starttime_restart.bt @@ -0,0 +1,82 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of timesensor start time" "Animation can be restarted even if not over" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "TimeSensor startTime test" + } + Transform2D { + translation -100 0 + children [ + DEF N3 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Rectangle { + size 80 80 + } + } + ] + } + DEF N2 TimeSensor { + cycleInterval 2 + startTime 2 + stopTime -1 + } + DEF N0 PositionInterpolator2D { + key [0 1] + keyValue [100 -100 100 100] + } + DEF N4 Transform2D { + translation 100 -100 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 0.5 0.5 + filled TRUE + } + } + geometry Rectangle { + size 80 80 + } + } + ] + } + ] +} + +ROUTE N3.touchTime TO N2.stopTime +ROUTE N3.touchTime TO N2.startTime +ROUTE N2.fraction_changed TO N0.set_fraction +ROUTE N0.value_changed TO N4.translation + diff --git a/regression_tests/bifs/bifs-interpolation-valuator-sftime.bt b/regression_tests/bifs/bifs-interpolation-valuator-sftime.bt new file mode 100644 index 0000000..61f39bb --- /dev/null +++ b/regression_tests/bifs/bifs-interpolation-valuator-sftime.bt @@ -0,0 +1,58 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage Valuator" "with SFTime to SFString formatting" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Valuator Test" + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + fontStyle DEF FONT FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + DEF V Valuator { + } + DEF TS TimeSensor { + cycleInterval 2 + loop TRUE + } + ] +} + +ROUTE TS.time TO V.inSFTime +ROUTE V.outMFString TO TXT.string + diff --git a/regression_tests/bifs/bifs-linking-anchor-mp4-next.bt b/regression_tests/bifs/bifs-linking-anchor-mp4-next.bt new file mode 100644 index 0000000..11c3eb6 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-anchor-mp4-next.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D { + backColor 1 0 1 + } + WorldInfo { + info ["This shows Anchor with MP4 hyperlinking" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Anchor Test" + } + Anchor { + url ["bifs-linking-anchor-mp4-prev.mp4"] + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Rectangle { + size 200 150 + } + } + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Click here to open" "prev.mp4"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-linking-anchor-mp4-prev.bt b/regression_tests/bifs/bifs-linking-anchor-mp4-prev.bt new file mode 100644 index 0000000..b7817a8 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-anchor-mp4-prev.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D { + backColor 0 1 1 + } + WorldInfo { + info ["This shows Anchor with MP4 hyperlinking" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Anchor Test" + } + Anchor { + url ["bifs-linking-anchor-mp4-next.mp4"] + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 100 + } + } + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Click here to open" "next.mp4"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-linking-anchor-viewpoint.bt b/regression_tests/bifs/bifs-linking-anchor-viewpoint.bt new file mode 100644 index 0000000..856a9bc --- /dev/null +++ b/regression_tests/bifs/bifs-linking-anchor-viewpoint.bt @@ -0,0 +1,92 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 200 + pixelHeight 200 + } + } + } + ] +} + +Group { + children [ + WorldInfo { + title "Anchor and Viewpoints test" + info ["This shows anchors triggering viewpoint binding" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + + DEF VP1 Viewpoint {description "Front View" position 0 0 300} + DEF VP2 Viewpoint {description "Above View" position 0 300 30 orientation 1 0 0 -1.2 } + + DEF TR Transform { + translation 50 0 0 + children [ + Anchor { + url "#VP2" + children [ + Shape { + appearance Appearance { + material Material { + diffuseColor 0 1 1 + } + } + geometry DEF BOX Box {size 50 50 50} + } + ] + } + ] + } + + Transform { + translation -80 0 20 + children [ + Shape { + appearance Appearance { + material Material2D { emissiveColor 1 0 0 filled TRUE } + } + geometry DEF RC_RED Rectangle {size 100 100} + } + ] + } + + Anchor { + url "bifs-3D-viewpoint-bind.mp4#VP2" + children [ + Shape { + appearance Appearance { + material Material2D { emissiveColor 1 1 1 filled TRUE } + } + geometry DEF RC_WHITE Rectangle { size 200 200 } + } + ] + } + + Transform { + translation -30 0 0 + children [ + Shape { + appearance Appearance { + material DEF MAT Material { + diffuseColor 1 1 0 + } + } + geometry DEF SPHERE Sphere {radius 30} + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-linking-anchor-www.bt b/regression_tests/bifs/bifs-linking-anchor-www.bt new file mode 100644 index 0000000..9e8ee13 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-anchor-www.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 255 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + DEF B1 Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Anchor with WWW hyperlinking" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Anchor Test" + } + Anchor { + url ["http://www.chiariglione.org/mpeg/"] + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 200 100 + } + } + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Click here to go" "to MPEG Web Site"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-linking-animationstream.bt b/regression_tests/bifs/bifs-linking-animationstream.bt new file mode 100644 index 0000000..c51cf15 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-animationstream.bt @@ -0,0 +1,135 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + includeInlineProfileLevelFlag true + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows an AnimationStream node" "using a BIFS-command stream" "" "GPAC Regression Tests" "$Date: 2009-09-30 18:01:04 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Animation Stream" + } + DEF N0 Transform2D { + translation 100 0 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 100 100 + } + } + ] + } + AnimationStream { + loop TRUE + url [od:10] + } + Transform2D { + translation 0 -100 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Position modified" "through animationStream"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] +} + + +RAP AT 0 IN 5 { + REPLACE N0.translation BY 100 0 +} + +RAP AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 5 + dependsOn_ES_ID 1 + OCR_ES_ID 5 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + nodeIDbits 1 + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + slConfigDescr SLConfigDescriptor { + useAccessUnitStartFlag true + useAccessUnitEndFlag true + useTimeStampsFlag true + timeStampResolution 1000 + timeStampLength 32 + } + } + ] + } + ] +} + +RAP AT 500 IN 5 { + REPLACE N0.translation BY 100 100 +} + +RAP AT 1000 IN 5 { + REPLACE N0.translation BY -100 100 +} + +RAP AT 1500 IN 5 { + REPLACE N0.translation BY -100 0 +} + +RAP AT 2000 IN 5 { + REPLACE N0.translation BY 100 0 +} + diff --git a/regression_tests/bifs/bifs-linking-inline-direct-inline.bt b/regression_tests/bifs/bifs-linking-inline-direct-inline.bt new file mode 100644 index 0000000..14891e5 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-inline-direct-inline.bt @@ -0,0 +1,75 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["Inlined scene with planeSensor2D" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Inline Test" + } + Background2D { + backColor 1 1 0 + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Circle { + radius 100 + } + } + ] + } + Transform2D { + children [ + DEF T1 Transform2D { + children [ + DEF PS PlaneSensor2D { + maxPosition 150 150 + minPosition -150 -150 + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 0.6 0.4 + filled TRUE + } + } + geometry DEF REC Rectangle { + size 50 100 + } + } + ] + } + ] + } + ] +} + +ROUTE PS.translation_changed TO T1.translation + diff --git a/regression_tests/bifs/bifs-linking-inline-direct.bt b/regression_tests/bifs/bifs-linking-inline-direct.bt new file mode 100644 index 0000000..4965245 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-inline-direct.bt @@ -0,0 +1,51 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 0 + } + WorldInfo { + info ["This shows usage of the inline node" "with rotation and scaling on the inlined scene" "Inline scene is referenced without OD" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Inline Test" + } + Transform2D { + rotationAngle 0.78 + scale 1.5 1 + children [ + Inline { + url ["bifs-linking-inline-direct-inline.mp4"] + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-linking-inline-od-inline.bt b/regression_tests/bifs/bifs-linking-inline-od-inline.bt new file mode 100644 index 0000000..e316518 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-inline-od-inline.bt @@ -0,0 +1,76 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["Inlined scene with planeSensor2D" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Inline Test" + } + + Background2D { + backColor 1 1 0 + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Circle { + radius 100 + } + } + ] + } + Transform2D { + children [ + DEF T1 Transform2D { + children [ + DEF PS PlaneSensor2D { + maxPosition 150 150 + minPosition -150 -150 + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0.5 0.6 0.4 + filled TRUE + } + } + geometry DEF REC Rectangle { + size 50 100 + } + } + ] + } + ] + } + ] +} + +ROUTE PS.translation_changed TO T1.translation + diff --git a/regression_tests/bifs/bifs-linking-inline-od.bt b/regression_tests/bifs/bifs-linking-inline-od.bt new file mode 100644 index 0000000..0075146 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-inline-od.bt @@ -0,0 +1,60 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of the inline node" "with rotation and scaling on the inlined scene" "Inline scene is referenced through an OD" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Inline Test" + } + Transform2D { + rotationAngle 0.78 + scale 1.5 1 + children [ + Inline { + url [od:8] + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + URLstring "bifs-linking-inline-od-inline.mp4" + } + ] +} + diff --git a/regression_tests/bifs/bifs-linking-inline-rtsp-no-od.bt b/regression_tests/bifs/bifs-linking-inline-rtsp-no-od.bt new file mode 100644 index 0000000..6532f8d --- /dev/null +++ b/regression_tests/bifs/bifs-linking-inline-rtsp-no-od.bt @@ -0,0 +1,48 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of the inline node" "using remote (rtsp) scene for inline" "Inline scene is referenced with OD" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Inline Test" + } + Transform2D { + children [ + Inline { + url ["rtsp://a1749.q.kamai.net/7/1749/1416/3c964c64/neo.qtv.apple.com/secure/may/preview/classic_cars_300.mp4"] + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-linking-inline-rtsp.bt b/regression_tests/bifs/bifs-linking-inline-rtsp.bt new file mode 100644 index 0000000..14cee04 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-inline-rtsp.bt @@ -0,0 +1,59 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of the inline node" "using remote (rtsp) scene for inline" "Inline scene is referenced with OD" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.5 $" "(C) 2002-2004 GPAC Team"] + title "Inline Test" + } + Transform2D { + children [ + Inline { + url [od:8] + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 +# URLstring "rtsp://a1749.q.kamai.net/7/1749/1416/3c964c64/neo.qtv.apple.com/secure/may/preview/civ3_700.mp4" + URLstring "rtsp://kara/bhusa.mp4" + } + ] +} + diff --git a/regression_tests/bifs/bifs-linking-inline-segment-inline.bt b/regression_tests/bifs/bifs-linking-inline-segment-inline.bt new file mode 100644 index 0000000..f9bea75 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-inline-segment-inline.bt @@ -0,0 +1,74 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] + ociDescr [ + SegmentDescriptor { startTime 0 duration 4 name "Begin" } + SegmentDescriptor { startTime 4 duration 2 name "Middle" } + SegmentDescriptor { startTime 6 duration 4 name "End" } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of MediaSensor" "with media segments defined" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Sensor Test #2" + } + Shape { + appearance Appearance { + texture DEF MOV MovieTexture { + loop TRUE + stopTime -1 + url [od:8] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap {} + } + ] +} + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-linking-inline-segment.bt b/regression_tests/bifs/bifs-linking-inline-segment.bt new file mode 100644 index 0000000..6934066 --- /dev/null +++ b/regression_tests/bifs/bifs-linking-inline-segment.bt @@ -0,0 +1,41 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of the inline node" "with rotation and scaling on the inlined scene" "Inline scene is referenced through an OD" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Inline Test" + } + Transform2D { + children [ + Inline { + url ["bifs-linking-inline-segment-inline.mp4#Middle"] + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-media-audiobuffer.bt b/regression_tests/bifs/bifs-media-audiobuffer.bt new file mode 100644 index 0000000..722e1f3 --- /dev/null +++ b/regression_tests/bifs/bifs-media-audiobuffer.bt @@ -0,0 +1,203 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + objectTypeIndication 1 + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + OCR_ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows audiobuffer" "with loop and pitch" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "AudioBuffer Test" + } + Sound2D { + source DEF AUDBUF AudioBuffer { + loop TRUE + numChan 2 + length 2 + children [ + AudioSource { + url [od:10] + stopTime -1 + } + ] + } + } + Transform2D { + translation 0 -50 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 100 50 + } + } + Shape { + appearance DEF TXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["restart"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 16 + } + } + } + DEF TS1 TouchSensor {} + ] + } + DEF C1 Conditional { + buffer { + REPLACE AUDBUF.stopTime BY 0 + REPLACE AUDBUF.startTime BY 0 + } + } + Transform2D { + translation -100 50 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 1 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE TXTAPP + geometry Text { + string ["pitch" "0.5"] + fontStyle USE FS + } + } + DEF TS2 TouchSensor {} + ] + } + Transform2D { + translation 0 50 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE TXTAPP + geometry Text { + string ["pitch" "1.0"] + fontStyle USE FS + } + } + DEF TS3 TouchSensor {} + ] + } + Transform2D { + translation 100 50 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE TXTAPP + geometry Text { + string ["pitch" "2"] + fontStyle USE FS + } + } + DEF TS4 TouchSensor {} + ] + } + DEF C2 Conditional { + buffer { + REPLACE AUDBUF.pitch BY 0.5 + } + } + DEF C3 Conditional { + buffer { + REPLACE AUDBUF.pitch BY 1 + } + } + DEF C4 Conditional { + buffer { + REPLACE AUDBUF.pitch BY 2 + } + } + ] +} + +ROUTE TS1.isActive TO C1.activate +ROUTE TS2.isActive TO C2.activate +ROUTE TS3.isActive TO C3.activate +ROUTE TS4.isActive TO C4.activate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_audio.aac" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-audioclip-urlchanged.bt b/regression_tests/bifs/bifs-media-audioclip-urlchanged.bt new file mode 100644 index 0000000..7e3a58d --- /dev/null +++ b/regression_tests/bifs/bifs-media-audioclip-urlchanged.bt @@ -0,0 +1,145 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows AudioClip" "and direct modification of URL" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "AudioClip Test" + } + DEF SD Sound2D { + source DEF AS AudioClip { + loop TRUE + url [od:20] + } + } + Transform2D { + translation -50 0 + children [ + DEF TS1 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Sound1"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE AS.url BY ["od:20"] + } + } + Transform2D { + translation 50 0 + children [ + DEF TS2 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE APP + geometry Text { + string ["Sound2"] + fontStyle USE FS + } + } + ] + } + DEF C2 Conditional { + buffer { + REPLACE AS.url BY ["od:10"] + } + } + ] +} + +ROUTE TS1.isActive TO C1.activate +ROUTE TS2.isActive TO C2.activate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_german.mp3" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 20 + esDescr [ + ES_Descriptor { + ES_ID 21 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_arabic.mp3" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-audioclip.bt b/regression_tests/bifs/bifs-media-audioclip.bt new file mode 100644 index 0000000..d342d55 --- /dev/null +++ b/regression_tests/bifs/bifs-media-audioclip.bt @@ -0,0 +1,133 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows AudioClip" "controled through startTime and stopTime" "audio clock is independent from BIFS clock, thus audio restarts from begining" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "AudioClip Test" + } + DEF SD Sound2D { + source DEF AS AudioClip { + loop TRUE + url [od:10] + } + } + Transform2D { + translation -50 0 + children [ + DEF TS1 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Stop"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE AS.stopTime BY 0 + } + } + Transform2D { + translation 50 0 + children [ + DEF TS2 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE APP + geometry Text { + string ["Start"] + fontStyle USE FS + } + } + ] + } + DEF C2 Conditional { + buffer { + REPLACE AS.startTime BY 0 + } + } + ] +} + +ROUTE TS1.isActive TO C1.activate +ROUTE TS2.isActive TO C2.activate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_audio.aac" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-audiosource-mixing.bt b/regression_tests/bifs/bifs-media-audiosource-mixing.bt new file mode 100644 index 0000000..b8ac94e --- /dev/null +++ b/regression_tests/bifs/bifs-media-audiosource-mixing.bt @@ -0,0 +1,194 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +PROTO AudioControler [ + exposedField MFString the_url [] + exposedField MFString comment [] + exposedField SFVec2f position 0 0 + exposedField SFColor color 0 0 0 + exposedField SFFloat vol 1.0 + exposedField SFInt32 numChannels 2 +] { + Transform2D { + translation IS position + children [ + Transform2D { + children [ + Shape { + appearance Appearance { material Material2D {emissiveColor IS color filled TRUE} } + geometry Rectangle { size 200 20 } + } + DEF TS TouchSensor {} + ] + } + Transform2D { + translation -120 0 + children [ + Shape { + appearance DEF TXTAPP Appearance { material DEF MAT Material2D {emissiveColor 0 0 0 filled TRUE} } + geometry DEF TXT Text { string ["volume", "0"] fontStyle DEF FS FontStyle { size 12 justify ["MIDDLE"]} } + } + + ] + } + Transform2D { + translation 0 20 + children [ + Shape { + appearance USE TXTAPP + geometry Text { string IS comment fontStyle USE FS} + } + + ] + } + DEF SND Sound2D { + intensity IS vol + source AudioSource { + url IS the_url + startTime 0 + numChan IS numChannels + } + } + MediaControl { + url IS the_url + loop TRUE + } + ] + } + DEF SC Script { + eventIn SFVec3f set_frac + eventIn SFBool set_down + field SFNode s USE SND + field SFNode t USE TXT + field SFBool isDown FALSE + url ["javascript: + function initialize() { + t.string[1] = '' + s.intensity; + } + function set_down(value, timestamp) {isDown = value;} + function set_frac(value, timestamp) { + if (!isDown) return; + pos = (value.x + 100)/200; + s.intensity = pos; + t.string[1] = '' + pos; + } + " + ] + } + ROUTE TS.isActive TO SC.set_down + ROUTE TS.hitPoint_changed TO SC.set_frac + +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows MediaControl" "controling audio playback speed" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + + AudioControler { + position 0 100 + color 1 0 0 + the_url ["od:10"] + numChannels 2 + vol 1 + comment ["Audio #1 - running on its own timeline"] + } + AudioControler { + position 0 33 + color 0 1 0 + the_url ["od:11"] + numChannels 2 + vol 0 + comment ["Audio #2 - running on its own timeline"] + } + AudioControler { + position 0 -33 + color 0 0 1 + the_url ["od:11"] + numChannels 2 + vol 0 + comment ["Audio #3 reusing Audio #2 object"] + } + AudioControler { + position 0 -100 + color 1 0 1 + the_url ["od:12"] + numChannels 2 + vol 0 + comment ["Audio #4 - running on Audio #2 timeline"] + } + ] +} + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 10 + OCR_ES_ID 10 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_english.mp3" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 11 + esDescr [ + ES_Descriptor { + ES_ID 11 + OCR_ES_ID 11 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_english.mp3" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 12 + esDescr [ + ES_Descriptor { + ES_ID 12 + OCR_ES_ID 11 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_english.mp3" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-audiosource-urlchanged.bt b/regression_tests/bifs/bifs-media-audiosource-urlchanged.bt new file mode 100644 index 0000000..00da0f4 --- /dev/null +++ b/regression_tests/bifs/bifs-media-audiosource-urlchanged.bt @@ -0,0 +1,146 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows AudioSource" "and direct modification of URL" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "AudioSource Test" + } + DEF SD Sound2D { + source DEF AS AudioSource { + url [od:20] + } + } + Transform2D { + translation -50 0 + children [ + DEF TS1 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Sound1"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE AS.startTime BY 0 + REPLACE AS.url BY ["od:20"] + } + } + Transform2D { + translation 50 0 + children [ + DEF TS2 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE APP + geometry Text { + string ["Sound2"] + fontStyle USE FS + } + } + ] + } + DEF C2 Conditional { + buffer { + REPLACE AS.startTime BY 0 + REPLACE AS.url BY ["od:10"] + } + } + ] +} + +ROUTE TS1.isActive TO C1.activate +ROUTE TS2.isActive TO C2.activate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_english.mp3" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 20 + esDescr [ + ES_Descriptor { + ES_ID 21 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_french.mp3" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-audiosource.bt b/regression_tests/bifs/bifs-media-audiosource.bt new file mode 100644 index 0000000..345b0b1 --- /dev/null +++ b/regression_tests/bifs/bifs-media-audiosource.bt @@ -0,0 +1,133 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows AudioSource" "controled through startTime and stopTime" "audio clock is independent from BIFS clock, thus audio restarts from begining" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "AudioSource Test" + } + DEF SD Sound2D { + source DEF AS AudioSource { + url [od:10] + stopTime 4 + } + } + Transform2D { + translation -50 0 + children [ + DEF TS1 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Stop"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE AS.stopTime BY 0 + } + } + Transform2D { + translation 50 0 + children [ + DEF TS2 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE APP + geometry Text { + string ["Start"] + fontStyle USE FS + } + } + ] + } + DEF C2 Conditional { + buffer { + REPLACE AS.startTime BY 0 + } + } + ] +} + +ROUTE TS1.isActive TO C1.activate +ROUTE TS2.isActive TO C2.activate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_italian.mp3" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-imagetexture-OD-reuse.bt b/regression_tests/bifs/bifs-media-imagetexture-OD-reuse.bt new file mode 100644 index 0000000..f872112 --- /dev/null +++ b/regression_tests/bifs/bifs-media-imagetexture-OD-reuse.bt @@ -0,0 +1,89 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows two ImageTexture nodes" "using the same OD" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Image Texture test" + } + Transform2D { + translation -80 0 + children [ + Shape { + appearance Appearance { + texture ImageTexture { + url [od:10] + } + } + geometry Rectangle { + size 100 50 + } + } + ] + } + Transform2D { + translation 80 0 + children [ + Shape { + appearance Appearance { + material Material2D { filled TRUE transparency 0.5 } + texture ImageTexture { + url [od:10] + } + } + geometry Circle { + radius 50 + } + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-imagetexture-no-od.bt b/regression_tests/bifs/bifs-media-imagetexture-no-od.bt new file mode 100644 index 0000000..cb81595 --- /dev/null +++ b/regression_tests/bifs/bifs-media-imagetexture-no-od.bt @@ -0,0 +1,60 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 254 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 254 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 0 1 + } + WorldInfo { + info [ + "This test shows how a URL in an ImageTexture node can be a regular URL (http, file, ...) and not an OD URL." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" + "(C) 2002-2006 GPAC Team" + ] + title "Image referenced by a non-OD URL" + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF TXT ImageTexture { + url ["../auxiliary_files/logo.jpg"] + } + } + geometry Bitmap {} + + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-media-imagetexture-object-scale.bt b/regression_tests/bifs/bifs-media-imagetexture-object-scale.bt new file mode 100644 index 0000000..37ae1c8 --- /dev/null +++ b/regression_tests/bifs/bifs-media-imagetexture-object-scale.bt @@ -0,0 +1,97 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 440 + pixelHeight 440 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows image texture" "with object scaling and texture transform" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Image Texture Test" + } + DEF TR Transform2D { + rotationAngle 0.78 + children [ + Shape { + geometry IndexedLineSet2D { + coord Coordinate2D { + point [0 200 0 -200] + } + } + } + Shape { + appearance Appearance { + texture ImageTexture { + url [od:10] + } + textureTransform DEF TX TextureTransform { + translation 0 0.5 + } + } + geometry Rectangle { + size 200 200 + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 4 + loop TRUE + } + DEF PI PositionInterpolator2D { + key [0 0.5 1] + keyValue [-0.5 -0.5 0.5 0.5 -0.5 -0.5] + } + DEF SI PositionInterpolator2D { + key [0 0.5 1] + keyValue [0.5 0.5 1.5 1.5 0.5 0.5] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO TR.scale + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-imagetexture-transparent.bt b/regression_tests/bifs/bifs-media-imagetexture-transparent.bt new file mode 100644 index 0000000..ebc40a6 --- /dev/null +++ b/regression_tests/bifs/bifs-media-imagetexture-transparent.bt @@ -0,0 +1,275 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 440 + pixelHeight 440 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 0 1 1 + } + WorldInfo { + info ["This shows basic 2D shapes" "with transparent image texture mapping" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Image Texture Test" + } + Transform2D { + translation -150 150 + children [ + Shape { + appearance DEF APP Appearance { + texture ImageTexture { + url [od:10] + } + } + geometry IndexedLineSet2D { + coord Coordinate2D { + point [-50 0 0 50 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["IndexedLineSet2D" "[-50 0 0 50 50 0]"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 12 + } + } + } + ] + } + ] + } + Transform2D { + translation 0 150 + children [ + Shape { + appearance USE APP + geometry Circle { + radius 50 + } + } + Transform2D { + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Circle" "radius 50"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 150 150 + children [ + Shape { + appearance USE APP + geometry Rectangle { + size 100 50 + } + } + Transform2D { + translation 0 -40 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Rectangle" "Size 100 50"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -40 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Curve2D Points:" "-50 0, -100 50, 0 20, 10 30, 40 80, 50 0"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -150 0 + children [ + Shape { + appearance USE APP + geometry Curve2D { + point DEF C2D Coordinate2D { + point [-50 0 -100 50 0 20 10 30 40 80 50 0] + } + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["no type"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 3] + point USE C2D + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["type [2 3]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 170 0 + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [1 3 1] + point USE C2D + } + } + Transform2D { + translation 0 -10 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["type [1 3 1]"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation -150 -150 + children [ + Shape { + appearance USE APP + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [-50 0 -25 25 0 80 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["IndexedFaceSet2D" "-50 0, -25, 25, 0 80, 50 0"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -150 + children [ + Shape { + appearance USE APP + geometry PointSet2D { + coord Coordinate2D { + point [-50 0 -25 25 0 80 50 0] + } + } + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["PointSet2D" "-50 0, -25, 25, 0 80, 50 0"] + fontStyle USE FS + } + } + ] + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.png" + useDataReference true + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-imagetexture-url-change.bt b/regression_tests/bifs/bifs-media-imagetexture-url-change.bt new file mode 100644 index 0000000..405b3c4 --- /dev/null +++ b/regression_tests/bifs/bifs-media-imagetexture-url-change.bt @@ -0,0 +1,95 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 254 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 254 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 0 1 + } + WorldInfo { + info ["This shows basic 2D shapes" "with dynamic URL change" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Image Texture Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF TXT ImageTexture { + url [od:10] + } + } + geometry Bitmap {} + + } + DEF TS TouchSensor {} + ] + } + DEF C1 Conditional { + buffer { + REPLACE TXT.url BY ["od:20"] + } + } + DEF RC1 Conditional { + buffer { + REPLACE TXT.url BY ["od:10"] + } + } + ] +} + +ROUTE TS.isActive TO C1.activate +ROUTE TS.isActive TO RC1.reverseActivate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 20 + esDescr [ + ES_Descriptor { + ES_ID 3 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 4 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.png" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-movietexture-control.bt b/regression_tests/bifs/bifs-media-movietexture-control.bt new file mode 100644 index 0000000..ed36b41 --- /dev/null +++ b/regression_tests/bifs/bifs-media-movietexture-control.bt @@ -0,0 +1,148 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 180 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows MovieTexture with playback control" "through usage of start/stop fields of movieTexture" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "MovieTexture Test" + } + Transform2D { + children [ + DEF TR Transform2D { + translation 0 30 + children [ + Shape { + appearance Appearance { + texture DEF MT MovieTexture { + loop TRUE + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap {} + + } + ] + } + ] + } + Transform2D { + translation -50 -70 + children [ + DEF TS1 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Stop"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE MT.stopTime BY 0 + } + } + Transform2D { + translation 50 -70 + children [ + DEF TS2 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + Shape { + appearance USE APP + geometry Text { + string ["Start"] + fontStyle USE FS + } + } + ] + } + DEF C2 Conditional { + buffer { + REPLACE MT.startTime BY 0 + } + } + ] +} + +ROUTE TS1.isActive TO C1.activate +ROUTE TS2.isActive TO C2.activate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-movietexture-no-od.bt b/regression_tests/bifs/bifs-media-movietexture-no-od.bt new file mode 100644 index 0000000..e55b68c --- /dev/null +++ b/regression_tests/bifs/bifs-media-movietexture-no-od.bt @@ -0,0 +1,65 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info [ + "This test shows how a URL in a MovieTexture node can be a regular URL (http, file, ...) and not an OD URL." + "" + "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.7 $" + "(C) 2002-2006 GPAC Team" + ] + title "Video referenced by a non-OD URL" + } + Sound2D { + source AudioClip { + loop TRUE + url ["../auxiliary_files/enst_audio.aac"] + #url ["rtsp://tasmanie/bhusa.mp4"] + } + } + Shape { + appearance Appearance { + texture DEF MT MovieTexture { + loop TRUE + url ["../auxiliary_files/enst_video.h264"] + #url ["rtsp://tasmanie/bhusa.mp4"] + } + } + geometry Bitmap {} + + } + ] +} + + diff --git a/regression_tests/bifs/bifs-media-movietexture-od-joinsession.bt b/regression_tests/bifs/bifs-media-movietexture-od-joinsession.bt new file mode 100644 index 0000000..c83ead6 --- /dev/null +++ b/regression_tests/bifs/bifs-media-movietexture-od-joinsession.bt @@ -0,0 +1,93 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 180 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows MovieTexture nodes" "using the same OD and looping" "with different start and stop times" "one movieTexture joins the session of the other" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "MovieTexture Test" + } + Transform2D { + translation -100 0 + children [ + Shape { + appearance DEF APP Appearance { + texture MovieTexture { + loop TRUE + startTime 4 + url [od:10] + } + } + geometry Circle { + radius 50 + } + } + ] + } + Transform2D { + translation 100 0 + children [ + Shape { + appearance Appearance { + texture MovieTexture { + loop TRUE + stopTime -1 + url [od:10] + } + } + geometry Rectangle { + size 100 50 + } + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-movietexture-od-leave-session.bt b/regression_tests/bifs/bifs-media-movietexture-od-leave-session.bt new file mode 100644 index 0000000..51c5c7f --- /dev/null +++ b/regression_tests/bifs/bifs-media-movietexture-od-leave-session.bt @@ -0,0 +1,93 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 180 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows MovieTexture nodes" "using the same OD and looping" "with different start and stop times" "one movieTexture leaves the session of the other" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "MovieTexture Test" + } + Transform2D { + translation -100 0 + children [ + Shape { + appearance DEF APP Appearance { + texture MovieTexture { + loop TRUE + stopTime -1 + url [od:10] + } + } + geometry Circle { + radius 50 + } + } + ] + } + Transform2D { + translation 100 0 + children [ + Shape { + appearance Appearance { + texture MovieTexture { + loop TRUE + stopTime 8 + url [od:10] + } + } + geometry Rectangle { + size 100 50 + } + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-movietexture-owns-OCR.bt b/regression_tests/bifs/bifs-media-movietexture-owns-OCR.bt new file mode 100644 index 0000000..bfde18e --- /dev/null +++ b/regression_tests/bifs/bifs-media-movietexture-owns-OCR.bt @@ -0,0 +1,75 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 180 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows MovieTexture node on bitmap" "looping (visual object de-synchronized from BIFS)" "Video shall restart when done playing" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "MovieTexture Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture MovieTexture { + loop TRUE + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap {} + + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-movietexture-shares-OCR.bt b/regression_tests/bifs/bifs-media-movietexture-shares-OCR.bt new file mode 100644 index 0000000..620c91a --- /dev/null +++ b/regression_tests/bifs/bifs-media-movietexture-shares-OCR.bt @@ -0,0 +1,74 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 180 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows MovieTexture node on bitmap" "looping (visual object synchronized on BIFS)" "results at end of video are undefined" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "MovieTexture Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture MovieTexture { + loop TRUE + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap {} + + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-movietexture-url-change.bt b/regression_tests/bifs/bifs-media-movietexture-url-change.bt new file mode 100644 index 0000000..565685e --- /dev/null +++ b/regression_tests/bifs/bifs-media-movietexture-url-change.bt @@ -0,0 +1,158 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 255 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 180 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows dynamic URL change of MovieTexture" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.5 $" "(C) 2002-2004 GPAC Team"] + title "MovieTexture Test" + } + Transform2D { + children [ + DEF TR Transform2D { + translation 0 30 + children [ + Shape { + appearance Appearance { + texture DEF MT MovieTexture { + loop TRUE + url [od:20] + } + } + geometry Bitmap {} + + } + ] + } + ] + } + Transform2D { + translation -50 -70 + children [ + DEF TS1 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 80 30 + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Movie 1"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE MT.url BY ["od:20"] + } + } + Transform2D { + translation 50 -70 + children [ + DEF TS2 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 80 30 + } + } + Shape { + appearance USE APP + geometry Text { + string ["Movie 2"] + fontStyle USE FS + } + } + ] + } + DEF C2 Conditional { + buffer { + REPLACE MT.url BY ["od:10"] + } + } + ] +} + +ROUTE TS1.isActive TO C1.activate +ROUTE TS2.isActive TO C2.activate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 20 + esDescr [ + ES_Descriptor { + ES_ID 21 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-sound-spatialize.bt b/regression_tests/bifs/bifs-media-sound-spatialize.bt new file mode 100644 index 0000000..2635510 --- /dev/null +++ b/regression_tests/bifs/bifs-media-sound-spatialize.bt @@ -0,0 +1,77 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0x01 + sceneProfileLevelIndication 0x01 + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFE + graphicsProfileLevelIndication 0x01 + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric FALSE + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "Sound Test" + info ["This shows Sound node" "with distance volume control and spatialization on" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + + Sound { + location 0 0 1 + spatialize TRUE + source AudioClip { + url [ "od:10" ] + loop TRUE + } + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1 0 0 } + } + geometry Box { size 2 2 2} + } + ] + } + ] +} + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "./../auxiliary_files/count_spanish.mp3" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-media-sound.bt b/regression_tests/bifs/bifs-media-sound.bt new file mode 100644 index 0000000..64742b9 --- /dev/null +++ b/regression_tests/bifs/bifs-media-sound.bt @@ -0,0 +1,77 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0x01 + sceneProfileLevelIndication 0x01 + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFE + graphicsProfileLevelIndication 0x01 + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric FALSE + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + es_id 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +Group { + children [ + + WorldInfo { + title "Sound Test" + info ["This shows Sound node" "with distance volume control" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + + Sound { + location 0 0 1 + spatialize FALSE + source AudioClip { + url [ "od:10" ] + loop TRUE + } + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1 0 0 } + } + geometry Box { size 2 2 2} + } + ] + } + ] +} + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "./../auxiliary_files/count_english.mp3" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-misc-UTF16-input.bt b/regression_tests/bifs/bifs-misc-UTF16-input.bt new file mode 100644 index 0000000..0edf895 --- /dev/null +++ b/regression_tests/bifs/bifs-misc-UTF16-input.bt @@ -0,0 +1,55 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 260 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows non ASCII Text characters" "Input BT file is in UTF-16 Little Endian format" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "MP4Box Test" + } + Transform2D { + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Non-Ansi:" "" "é à è ù ü ä ë ï ö ü ÿ" "" "" "XML escapes:" "" "& ' \\" > <"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 26 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-misc-cyclic-graph.bt b/regression_tests/bifs/bifs-misc-cyclic-graph.bt new file mode 100644 index 0000000..e6e9722 --- /dev/null +++ b/regression_tests/bifs/bifs-misc-cyclic-graph.bt @@ -0,0 +1,55 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows a cyclic scene graph" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2005 GPAC Team"] + title "Cyclic Scene Graph Test" + } + DEF TR Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D {emissiveColor 1 0 0 filled TRUE } + } + geometry Circle { radius 60 } + } + Transform2D { + scale 0.98 0.98 + translation 1 0 + children [ + ColorTransform { + mrr 0.95 + children [ USE TR ] + } + ] + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-misc-hc-proto-pathextrusion.bt b/regression_tests/bifs/bifs-misc-hc-proto-pathextrusion.bt new file mode 100644 index 0000000..b812fa5 --- /dev/null +++ b/regression_tests/bifs/bifs-misc-hc-proto-pathextrusion.bt @@ -0,0 +1,103 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + + +EXTERNPROTO PathExtrusion [ + exposedField SFNode geometry NULL + exposedField MFVec3f spine [] + exposedField SFBool beginCap TRUE + exposedField SFBool endCap TRUE + exposedField SFFloat creaseAngle 1.0 + exposedField MFRotation orientation [] + exposedField MFVec2f scale [] + exposedField SFBool txAlongSpine FALSE +] +[ "urn:inet:gpac:builtin:PathExtrusion"] + + + +Group { + children [ + + WorldInfo { + info ["This shows GPAC PathExtrusion HardcodedProto" "The text is extruded along a spline to get a solid text in 3D" "GPAC Regression Tests" "$Date: 2008-05-19 15:28:18 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "PathExtrusion HardcodedProto" + } + NavigationInfo { type ["EXAMINE", "ANY"] headlight FALSE} + Background2D {backColor 0 0 0 url "./../auxiliary_files/logo.jpg"} + DEF VIEWPOINT Viewpoint { + description "one" + position 0 0 10 + } + + DirectionalLight { + direction -1 -1 -1 + } + +Shape { + appearance Appearance { + material Material { + diffuseColor 1.0 0.8 0.0 +# specularColor 1 1 1 +# shininess 0.3 + } +# texture ImageTexture { url "../../../auxiliary_files/logo.jpg"} + } + + geometry PathExtrusion { +# geometry Curve2D { fineness 1.0 point Coordinate2D { point [0 0, 0.25 1, 0.75 1, 1 0, 1.5 0, 0.8 -2, 0 0] } type [2 0 3] } +# geometry Rectangle { size 0.5 1.0 } + + geometry Text { + string ["G"] + fontStyle FontStyle { + size 2.0 + justify ["MIDDLE", "MIDDLE"] + } + } + + creaseAngle 0.5 + endCap FALSE + beginCap TRUE + txAlongSpine FALSE + spine [ + # Straight-line + 0.0 0.0 0.0, 0.0 1 0, +# 0.0 0.0 -0.8, 0.0 0.0 -1.2, +# 0.0 0.0 -1.6, 0.0 0.0 -2.0 + ] +# scale [ +# 1.8 1.8, 1.95 1.95, +# 2.0 2.0, 1.95 1.95 +# 1.8 1.8, 1.5 1.5 +# 1.2 1.2, 1.05 1.05, +# 1.0 1.0, 1.05 1.05, +# 1.15 1.15, +# ] + } +} + +] +} + diff --git a/regression_tests/bifs/bifs-misc-hc-proto-planarextrusion.bt b/regression_tests/bifs/bifs-misc-hc-proto-planarextrusion.bt new file mode 100644 index 0000000..17c2638 --- /dev/null +++ b/regression_tests/bifs/bifs-misc-hc-proto-planarextrusion.bt @@ -0,0 +1,87 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + + +EXTERNPROTO PlanarExtrusion [ + exposedField SFNode geometry NULL + exposedField SFNode spine NULL + exposedField SFBool beginCap TRUE + exposedField SFBool endCap TRUE + exposedField SFFloat creaseAngle 1.0 + exposedField MFFloat orientationKeys [] + exposedField MFRotation orientation [] + exposedField MFFloat scaleKeys [] + exposedField MFVec2f scale [] + exposedField SFBool txAlongSpine FALSE +] +[ "urn:inet:gpac:builtin:PlanarExtrusion"] + + + +Group { + children [ + WorldInfo { + info ["This shows GPAC PlanarExtrusion HardcodedProto" "A circle is extruded along another circle to get a nice 3D torus" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "PlanarExtrusion HardcodedProto" + } + + Background2D { backColor 1 1 1} + DEF VIEWPOINT Viewpoint { + description "one" + position 0 0 10 + } + + +Shape { + appearance Appearance { + material Material { + diffuseColor 1.0 0.8 0.0 + } +# texture ImageTexture { url "../../../auxiliary_files/logo.jpg"} + } + + geometry PlanarExtrusion { + geometry Circle { radius 1} +# geometry Curve2D { +# type [2] +# point Coordinate2D { +# point [0 0 0.75 2 1.5 0 2 2] +# } +# } + spine Circle {radius 5} +# spine Rectangle {size 20 10} + creaseAngle 1 + endCap FALSE + beginCap FALSE +# scaleKeys [0 0.1 0.25 0.5 0.75 0.9 1] +# scale [0 0, 0 0, 1 1, 2 2.5, 1 1, 0 0, 0 0] +# orientationKeys [0 0.25 0.5 0.75 1] +# orientation [0 1 0 0, 0 1 1 0.25, 0 0 1 0.25, 0 1 1 0.25, 0 1 0 0] + txAlongSpine TRUE + } +} + +] +} + diff --git a/regression_tests/bifs/bifs-misc-hc-proto-planeclipper.bt b/regression_tests/bifs/bifs-misc-hc-proto-planeclipper.bt new file mode 100644 index 0000000..49f0a7f --- /dev/null +++ b/regression_tests/bifs/bifs-misc-hc-proto-planeclipper.bt @@ -0,0 +1,69 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + ODProfileLevelIndication 0xFF + sceneProfileLevelIndication 0xFE + audioProfileLevelIndication 0xFF + visualProfileLevelIndication 0xFF + graphicsProfileLevelIndication 0xFE + + esdescr [ + ES_Descriptor { + es_id 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric false + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + + +EXTERNPROTO PlaneClipper [ + exposedField SFVec3f plane_normal 1 0 0 + exposedField SFFloat plane_distance 0.0 + exposedField MFNode children [] +] +[ "urn:inet:gpac:builtin:PlaneClipper"] + + + +Group { + children [ + WorldInfo { + info ["This shows GPAC PlaneClipper HardcodedProto" "The plane clipper normal and distance are interpolated to cut the mesh at different places" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "PlaneClipper HardcodedProto" + } + Background2D { backColor 1 1 0} + DEF VIEWPOINT Viewpoint { + description "one" + position 0 0 10 + } + DEF PC PlaneClipper { + children [ + Inline { url "./../auxiliary_files/nefertiti.wrl" } + ] + } + DEF TS TimeSensor { cycleInterval 4.0 loop TRUE} + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [-3 3 -3] + } + DEF TS2 TimeSensor { cycleInterval 12.0 loop TRUE} + DEF PI PositionInterpolator { +# key [0 0.333 0.334 0.666 0.667 1] +# keyValue [1 0 0 1 0 0 0 1 0 0 1 0 0 0 -1 0 0 -1] + key [0 0.33 0.666 1] + keyValue [1 0 0, 0 1 0, 0 0 -1, 1 1 0] + } + ] +} + +ROUTE TS.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO PC.plane_distance +ROUTE TS2.fraction_changed TO PI.set_fraction +ROUTE PI.value_changed TO PC.plane_normal diff --git a/regression_tests/bifs/bifs-misc-non-linear-parsing-conditional.bt b/regression_tests/bifs/bifs-misc-non-linear-parsing-conditional.bt new file mode 100644 index 0000000..99148cd --- /dev/null +++ b/regression_tests/bifs/bifs-misc-non-linear-parsing-conditional.bt @@ -0,0 +1,69 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This tests encoding of non-linear declared nodes used in conditionals" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Non-linear conditional test" + } + DEF N0 Conditional { + buffer { + REPLACE N1.point BY [-75 0 -40 75 40 75 75 0 40 -75 -40 -75] + } + } + DEF N2 Conditional { + buffer { + REPLACE N1.point BY [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + DELETE ROUTE R0 + DELETE ROUTE R1 + } + } + Transform2D { + scale 0.5 0.5 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF N1 Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + DEF N3 TouchSensor {} + ] + } + ] +} + +DEF R0 ROUTE N3.isActive TO N0.activate +DEF R1 ROUTE N3.isActive TO N2.reverseActivate + diff --git a/regression_tests/bifs/bifs-misc-non-linear-parsing-use.bt b/regression_tests/bifs/bifs-misc-non-linear-parsing-use.bt new file mode 100644 index 0000000..63a557b --- /dev/null +++ b/regression_tests/bifs/bifs-misc-non-linear-parsing-use.bt @@ -0,0 +1,60 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + info ["This tests encoding of non-linear declared nodes used in file" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Non-linear USE test" + } + DEF BACK Background2D { + backColor 1 1 1 + } + DEF TR Transform2D { + scale 0.5 0.5 + children [ + Transform2D { + translation 150 100 + children [ + USE S1 + ] + } + DEF S1 Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + coord DEF COORD Coordinate2D { + point [-100 0 -50 100 50 100 100 0 50 -100 -50 -100] + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-misc-srt-import-3gpp-control-share-ocr.bt b/regression_tests/bifs/bifs-misc-srt-import-3gpp-control-share-ocr.bt new file mode 100644 index 0000000..9378e80 --- /dev/null +++ b/regression_tests/bifs/bifs-misc-srt-import-3gpp-control-share-ocr.bt @@ -0,0 +1,64 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 0 1 + } + WorldInfo { + info ["This shows usage of SRT importer" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "SRT importing Test" + } + AnimationStream { + url [od:5] + startTime 5 + stopTime 10 + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 4 + OCR_ES_ID 1 + muxInfo MuxInfo { + fileName "../auxiliary_files/subtitle.srt" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-misc-srt-import-3gpp-control.bt b/regression_tests/bifs/bifs-misc-srt-import-3gpp-control.bt new file mode 100644 index 0000000..1585645 --- /dev/null +++ b/regression_tests/bifs/bifs-misc-srt-import-3gpp-control.bt @@ -0,0 +1,64 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 0 1 + } + WorldInfo { + info ["This shows usage of SRT importer" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "SRT importing Test" + } + AnimationStream { + url [od:5] + startTime 5 + stopTime 10 + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 4 + OCR_ES_ID 4 + muxInfo MuxInfo { + fileName "../auxiliary_files/subtitle.srt" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-misc-srt-import-3gpp.bt b/regression_tests/bifs/bifs-misc-srt-import-3gpp.bt new file mode 100644 index 0000000..e7ba46b --- /dev/null +++ b/regression_tests/bifs/bifs-misc-srt-import-3gpp.bt @@ -0,0 +1,64 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 0 1 + } + WorldInfo { + info ["This shows usage of SRT importer" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "SRT importing Test" + } + AnimationStream { + url [od:5] + startTime 0 + stopTime 0 + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 4 + OCR_ES_ID 1 + muxInfo MuxInfo { + fileName "../auxiliary_files/subtitle.srt" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-misc-srt-import.bt b/regression_tests/bifs/bifs-misc-srt-import.bt new file mode 100644 index 0000000..b1d92ad --- /dev/null +++ b/regression_tests/bifs/bifs-misc-srt-import.bt @@ -0,0 +1,75 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 240 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of SRT importer" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "SRT importing Test" + } + Shape { + appearance Appearance { + material Material2D {emissiveColor 0 0 0 filled TRUE } + } + geometry DEF TXT Text { + fontStyle DEF FONT FontStyle { + justify ["MIDDLE"] + size 30 + } + } + } + AnimationStream { + url [od:5] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 5 + esDescr [ + ES_Descriptor { + ES_ID 4 + OCR_ES_ID 1 + muxInfo MuxInfo { + fileName "../auxiliary_files/subtitle.srt" + textNode "TXT" + fontNode "FONT" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-od-remove-esd.bt b/regression_tests/bifs/bifs-od-remove-esd.bt new file mode 100644 index 0000000..bda7e89 --- /dev/null +++ b/regression_tests/bifs/bifs-od-remove-esd.bt @@ -0,0 +1,78 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This tests ESDRemove command" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "ESD Remove" + } + Transform2D { + children [ + Shape { + appearance DEF APP Appearance { + texture ImageTexture { + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry Circle { + radius 100 + } + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + +AT 2000 { + REMOVE ESD FROM 10 [20] +} + diff --git a/regression_tests/bifs/bifs-od-remove-od.bt b/regression_tests/bifs/bifs-od-remove-od.bt new file mode 100644 index 0000000..a2967ac --- /dev/null +++ b/regression_tests/bifs/bifs-od-remove-od.bt @@ -0,0 +1,78 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This tests ODRemove command" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "OD Remove test" + } + Transform2D { + children [ + Shape { + appearance DEF APP Appearance { + texture ImageTexture { + url [od:10] + repeatS FALSE + repeatT FALSE + } + } + geometry Circle { + radius 100 + } + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + +AT 2000 { + REMOVE OD [10] +} + diff --git a/regression_tests/bifs/bifs-od-update-od.bt b/regression_tests/bifs/bifs-od-update-od.bt new file mode 100644 index 0000000..fe5865c --- /dev/null +++ b/regression_tests/bifs/bifs-od-update-od.bt @@ -0,0 +1,89 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This tests ODUpdate command" "by sending a new OD with the same ID" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "OD Update" + } + Transform2D { + translation -150 0 + children [ + Shape { + appearance Appearance { + texture ImageTexture { + url [od:10] + } + } + geometry Circle { + radius 100 + } + } + ] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 3 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + +AT 2000 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 4 + muxInfo MuxInfo { + fileName "../auxiliary_files/sky.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-proto-conditional.bt b/regression_tests/bifs/bifs-proto-conditional.bt new file mode 100644 index 0000000..3fe9704 --- /dev/null +++ b/regression_tests/bifs/bifs-proto-conditional.bt @@ -0,0 +1,107 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + eventIn SFBool act + eventIn SFBool reverseAct + exposedField SFVec2f translation 0 0 + exposedField SFFloat rotation 0 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] { + DEF TR Transform2D { + rotationAngle IS rotation + scale 2 1 + translation IS translation + children [ + DEF S Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + ] + } + DEF C Conditional { + activate IS act + buffer { + REPLACE TR.scale BY 1 1 + } + } + DEF RC Conditional { + reverseActivate IS reverseAct + buffer { + REPLACE TR.scale BY 2 1 + } + } +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of a conditional inside a proto" "getting events outside the proto" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Simple proto Test" + } + DEF PT1 GEOMETRY_PROTO { + translation 100 0 + rotation 0.78 + Color 1 0 1 + transparency 0.75 + lineColor 1 0 0 + lineWidth 2 + obj Circle { + radius 75 + } + } + DEF PT2 Transform2D { + translation -100 0 + children [ + GEOMETRY_PROTO { + Color 1 0 0 + obj Rectangle { + size 50 50 + } + } + DEF TS TouchSensor {} + ] + } + ] +} + +ROUTE TS.isActive TO PT1.act +ROUTE TS.isActive TO PT1.reverseAct + diff --git a/regression_tests/bifs/bifs-proto-delete-def.bt b/regression_tests/bifs/bifs-proto-delete-def.bt new file mode 100644 index 0000000..8b525e8 --- /dev/null +++ b/regression_tests/bifs/bifs-proto-delete-def.bt @@ -0,0 +1,91 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] { + Transform2D { + rotationAngle IS rotation + scale IS scale + translation IS translation + children [ + DEF S Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + Transform2D { + translation -100 0 + children [ + USE S + ] + } + ] + } +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows deleteion of a proto instance by ID" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Simple proto Test" + } + DEF G GEOMETRY_PROTO { + translation 200 0 + scale 1 1.5 + rotation 0.78 + Color 1 0 1 + transparency 0.75 + lineColor 1 0 0 + lineWidth 2 + obj Circle { + radius 75 + } + } + ] +} + + +AT 2000 { + REPLACE G BY NULL +} + diff --git a/regression_tests/bifs/bifs-proto-delete-index.bt b/regression_tests/bifs/bifs-proto-delete-index.bt new file mode 100644 index 0000000..0cba2f3 --- /dev/null +++ b/regression_tests/bifs/bifs-proto-delete-index.bt @@ -0,0 +1,95 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] { + Transform2D { + rotationAngle IS rotation + scale IS scale + translation IS translation + children [ + DEF S Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + Transform2D { + translation -100 0 + children [ + USE S + ] + } + ] + } +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows deleteion of a proto instance by index" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Proto Delete Test" + } + DEF TR Transform2D { + children [ + DEF G GEOMETRY_PROTO { + translation 200 0 + scale 1 1.5 + rotation 0.78 + Color 1 0 1 + transparency 0.75 + lineColor 1 0 0 + lineWidth 2 + obj Circle { + radius 75 + } + } + ] + } + ] +} + + +AT 2000 { + REPLACE TR.children[0] BY NULL +} + diff --git a/regression_tests/bifs/bifs-proto-forestgump.bt b/regression_tests/bifs/bifs-proto-forestgump.bt new file mode 100644 index 0000000..1ace6ed --- /dev/null +++ b/regression_tests/bifs/bifs-proto-forestgump.bt @@ -0,0 +1,478 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 250 + pixelHeight 250 + } + } + } + ] +} + +PROTO FORESTGUMP [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFFloat lineWidth 3 + exposedField SFColor lineColor 0.121569 0.101961 0.0901961 + exposedField SFTime runTime 1 + exposedField SFBool loop TRUE + exposedField SFTime start 0 +] { + Transform2D { + rotationAngle IS rotation + scale IS scale + translation IS translation + children [ + DEF MYSWITCH Switch { + whichChoice 0 + choice [ + Transform2D { + scale 0.0899561 0.0900365 + translation 260.243 42.9024 + children [ + Transform2D { + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + geometry Curve2D { + type [1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-2827 -11 -2864 -2 -2864 -2 -2883 -2 -2883 -2 -2892 -2 -2901 -11 -2911 -11 -2920 -11 -2929 -20 -2939 -29 -2939 -29 -2957 -48 -2957 -48 -2966 -57 -2957 -57 -2966 -76 -2966 -85 -2976 -95 -2976 -104 -2976 -104 -2976 -132 -2976 -132 -2976 -132 -2976 -160 -2976 -160 -2966 -178 -2957 -188 -2957 -188 -2957 -188 -2939 -197 -2939 -197 -2939 -197 -2920 -197 -2920 -197 -2920 -197 -2911 -206 -2911 -206 -2911 -206 -2892 -206 -2892 -206 -2892 -206 -2873 -206 -2873 -206 -2873 -206 -2855 -215 -2855 -215 -2855 -215 -2836 -215 -2836 -215 -2836 -215 -2827 -206 -2827 -206 -2827 -206 -2808 -197 -2808 -197 -2799 -188 -2799 -188 -2790 -178 -2790 -178 -2790 -169 -2790 -169 -2780 -160 -2780 -160 -2771 -150 -2771 -150 -2771 -141 -2771 -141 -2771 -132 -2771 -132 -2771 -122 -2771 -122 -2771 -113 -2771 -113 -2771 -104 -2771 -104 -2771 -95 -2771 -95 -2771 -85 -2771 -85 -2771 -76 -2780 -57 -2780 -48 -2780 -48 -2790 -29 -2790 -29 -2790 -29 -2808 -20 -2808 -20 -2808 -20 -2818 -11 -2818 -11 -2827 -2 -2827 -2 -2836 -2 -2836 -2 -2846 -2 -2855 -2 -2873 -2 -2883 -2] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 2 1 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-2883 -225 -2883 -262 -2883 -262 -2883 -281 -2883 -281 -2883 -290 -2883 -299 -2883 -308 -2883 -327 -2883 -327 -2892 -336 -2892 -336 -2892 -336 -2892 -383 -2892 -392 -2892 -401 -2892 -429 -2892 -439 -2892 -439 -2892 -467 -2892 -467 -2892 -467 -2892 -485 -2892 -485 -2901 -485 -2901 -485 -2901 -494 -2901 -494 -2901 -504 -2901 -513 -2901 -532 -2901 -541] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-3004 -755 -2994 -727 -2985 -708 -2976 -690 -2976 -680 -2976 -643 -2976 -643 -2957 -625 -3004 -653 -3004 -653 -3004 -653 -3115 -718 -3115 -708 -3115 -662 -3032 -541 -2957 -541 -2939 -541 -2901 -522 -2883 -541 -2883 -541 -2855 -560 -2855 -560 -2846 -569 -2818 -587 -2818 -606 -2818 -625 -2790 -662 -2790 -708 -2790 -773 -2799 -848 -2799 -913 -2799 -931 -2808 -931 -2808 -950 -2808 -959 -2790 -931 -2790 -931 -2780 -904 -2743 -857 -2734 -829 -2734 -820 -2697 -773 -2706 -773] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-2985 -346 -2994 -346 -3022 -374 -3032 -374 -3041 -374 -3050 -383 -3050 -392 -3050 -392 -3134 -392 -3143 -392 -3152 -392 -3134 -364 -3134 -364 -3134 -364 -3106 -346 -3106 -346 -3097 -336 -2985 -253 -2957 -253 -2939 -253 -2920 -271 -2911 -271 -2901 -271 -2873 -281 -2864 -281 -2836 -271 -2790 -234 -2771 -225 -2762 -225 -2734 -206 -2725 -197 -2715 -188 -2669 -160 -2669 -160 -2660 -160 -2660 -150 -2660 -169 -2660 -206 -2641 -262 -2641 -299] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0900093 0.0899546 + translation 190.415 42.8184 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-2083 -20 -2120 -20 -2120 -20 -2130 -20 -2130 -20 -2139 -20 -2139 -20 -2148 -20 -2148 -20 -2148 -20 -2167 -20 -2167 -20 -2167 -20 -2195 -30 -2195 -30 -2195 -30 -2204 -48 -2213 -58 -2213 -58 -2232 -67 -2241 -76 -2241 -76 -2241 -113 -2241 -113 -2241 -113 -2250 -132 -2250 -141 -2250 -151 -2241 -169 -2241 -169 -2241 -179 -2223 -188 -2223 -188 -2223 -188 -2213 -216 -2204 -216 -2195 -216 -2195 -225 -2185 -225 -2185 -225 -2157 -225 -2157 -225 -2157 -225 -2139 -225 -2139 -225 -2139 -225 -2120 -225 -2120 -225 -2120 -225 -2111 -216 -2111 -216 -2111 -216 -2092 -216 -2092 -216 -2092 -216 -2074 -206 -2074 -206 -2074 -206 -2064 -197 -2064 -197 -2064 -197 -2055 -179 -2055 -179 -2046 -179 -2046 -179 -2046 -169 -2046 -169 -2037 -160 -2037 -160 -2037 -151 -2037 -151 -2037 -141 -2037 -141 -2037 -132 -2037 -132 -2037 -123 -2037 -123 -2037 -113 -2037 -113 -2037 -104 -2037 -104 -2037 -95 -2037 -95 -2037 -95 -2037 -76 -2037 -76 -2037 -76 -2055 -39 -2055 -39 -2055 -39 -2074 -30 -2074 -30 -2074 -30 -2092 -20 -2092 -20 -2092 -20 -2102 -11 -2102 -11 -2111 -11 -2111 -11 -2120 -11 -2120 -11 -2120 -2 -2120 -2 -2157 -2 -2157 -2] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-2130 -244 -2130 -290 -2130 -318 -2130 -355 -2130 -383 -2130 -402 -2139 -420 -2139 -439 -2139 -448 -2139 -476 -2139 -485 -2139 -495 -2139 -504 -2139 -513 -2139 -523 -2139 -523 -2139 -532 -2139 -532 -2139 -541 -2139 -541 -2130 -551 -2130 -551] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-2306 -792 -2269 -764 -2232 -718 -2204 -690 -2195 -681 -2204 -690 -2213 -690 -2241 -681 -2325 -671 -2343 -653 -2343 -653 -2362 -644 -2362 -644 -2371 -634 -2278 -569 -2278 -569 -2241 -560 -2213 -551 -2176 -551 -2139 -551 -2027 -578 -2027 -616 -2027 -625 -2018 -625 -2018 -634 -1999 -671 -1999 -709 -1999 -755 -1999 -811 -2074 -904 -2111 -922 -2148 -941 -2139 -950 -2102 -950 -2064 -950 -2009 -950 -1971 -950] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-2223 -402 -2260 -420 -2325 -439 -2353 -411 -2371 -392 -2381 -374 -2381 -355 -2381 -318 -2371 -290 -2343 -281 -2306 -262 -2232 -244 -2185 -244 -2176 -244 -2139 -225 -2130 -225 -2120 -225 -2046 -234 -2027 -234 -1981 -234 -1897 -253 -1878 -299 -1869 -318 -1851 -346 -1851 -383 -1851 -411 -1860 -448 -1860 -467] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0899291 0.0900198 + translation 123.698 44.4248 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 1 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-1283 -11 -1320 -11 -1320 -11 -1330 -11 -1330 -11 -1339 -11 -1339 -11 -1348 -11 -1348 -11 -1348 -11 -1367 -11 -1367 -11 -1367 -20 -1367 -20 -1376 -20 -1376 -20 -1376 -20 -1413 -39 -1413 -39 -1413 -39 -1432 -76 -1432 -76 -1432 -85 -1441 -104 -1441 -113 -1441 -123 -1451 -141 -1451 -151 -1451 -169 -1451 -160 -1441 -169 -1441 -169 -1432 -188 -1432 -188 -1432 -188 -1423 -206 -1423 -206 -1423 -206 -1404 -216 -1404 -216 -1395 -216 -1386 -225 -1376 -225 -1376 -225 -1348 -225 -1348 -225 -1348 -225 -1330 -225 -1330 -225 -1330 -225 -1311 -225 -1311 -225 -1311 -225 -1293 -216 -1293 -216 -1293 -216 -1283 -206 -1283 -206 -1283 -206 -1265 -197 -1265 -197 -1265 -197 -1255 -188 -1255 -188 -1255 -188 -1246 -169 -1246 -169 -1237 -169 -1237 -169 -1237 -160 -1237 -160 -1237 -151 -1237 -151 -1237 -141 -1237 -141 -1237 -132 -1237 -132 -1237 -123 -1237 -123 -1237 -113 -1237 -113 -1237 -104 -1237 -104 -1237 -95 -1237 -95 -1237 -85 -1237 -85 -1237 -85 -1237 -67 -1237 -67 -1237 -67 -1255 -48 -1255 -39 -1255 -39 -1265 -20 -1265 -20 -1265 -20 -1283 -11 -1283 -11 -1283 -11 -1302 -2 -1302 -2 -1311 -2 -1311 -2 -1320 -2 -1320 -2 -1330 -2 -1339 -2 -1358 -2 -1367 -2] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [1 2 1 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [-1311 -234 -1311 -271 -1311 -271 -1311 -281 -1311 -281 -1311 -299 -1311 -318 -1311 -355 -1311 -374 -1311 -392 -1311 -430 -1311 -448 -1311 -457 -1311 -485 -1311 -495 -1311 -495 -1311 -513 -1311 -513 -1311 -523 -1311 -523 -1311 -532 -1311 -532 -1311 -541 -1311 -560 -1311 -578 -1311 -560] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-1572 -662 -1534 -709 -1469 -755 -1441 -783 -1423 -802 -1451 -764 -1451 -764 -1460 -736 -1506 -578 -1469 -560 -1451 -550 -1330 -597 -1320 -597 -1293 -606 -1274 -616 -1274 -662 -1274 -690 -1274 -727 -1283 -746 -1283 -755 -1293 -792 -1302 -811 -1339 -885 -1274 -904 -1274 -987] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2] + point Coordinate2D { + point [-1609 -541 -1618 -467 -1599 -504 -1590 -448 -1562 -309 -1423 -253 -1283 -253 -1237 -253 -1144 -281 -1144 -327 -1144 -346 -1135 -355 -1144 -374 -1153 -392 -1227 -467 -1227 -485] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0899947 0.0899257 + translation 62.0964 37.7238 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 1 2 1 2 1] + point Coordinate2D { + point [-511 -30 -549 -30 -567 -30 -577 -30 -586 -30 -604 -48 -604 -48 -614 -48 -623 -67 -623 -76 -623 -86 -642 -76 -642 -95 -642 -95 -642 -123 -642 -123 -642 -132 -642 -141 -642 -151 -642 -160 -623 -179 -623 -179 -623 -179 -614 -188 -614 -188 -614 -188 -595 -188 -595 -188 -595 -188 -586 -197 -586 -197 -586 -197 -567 -197 -567 -197 -567 -197 -549 -207 -549 -207 -549 -207 -539 -197 -539 -197 -539 -197 -521 -197 -521 -197 -521 -197 -502 -188 -502 -188 -493 -179 -493 -179 -484 -169 -484 -169 -474 -169 -474 -169 -474 -160 -474 -160 -465 -160 -465 -160 -465 -151 -465 -151 -465 -141 -465 -141 -465 -132 -465 -132 -456 -132 -456 -132 -456 -114 -456 -114 -456 -86 -465 -86 -465 -86 -465 -86 -474 -67 -474 -58 -474 -48 -484 -48 -484 -39 -484 -39 -493 -21 -493 -21 -502 -21 -502 -21 -511 -11 -511 -11 -521 -2 -521 -2 -558 -2 -511 -30 -521 -2] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 1 2 2] + point Coordinate2D { + point [-539 -225 -539 -262 -549 -281 -549 -318 -549 -337 -558 -355 -558 -374 -558 -383 -558 -411 -558 -430 -558 -439 -558 -448 -558 -467 -558 -476 -558 -504 -567 -513 -558 -523] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 1 2 2 2 2 2] + point Coordinate2D { + point [-865 -551 -865 -569 -846 -653 -846 -672 -846 -690 -837 -699 -837 -709 -837 -718 -828 -718 -828 -709 -828 -681 -763 -606 -735 -588 -716 -579 -651 -541 -632 -541 -577 -541 -521 -532 -465 -560 -446 -569 -400 -616 -381 -634 -381 -634 -353 -699 -372 -699 -400 -699 -428 -672 -428 -672 -437 -672 -437 -672 -474 -653 -474 -653 -484 -653 -493 -662 -493 -672 -493 -690 -502 -755 -502 -774 -502 -783 -502 -792 -493 -811 -484 -830 -474 -848 -474 -830] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2] + point Coordinate2D { + point [-1023 -365 -976 -318 -930 -300 -874 -272 -865 -272 -837 -253 -828 -253 -716 -216 -577 -262 -456 -262 -428 -262 -335 -318 -363 -346 -372 -355 -437 -346 -456 -346 -456 -346 -511 -337 -511 -337 -530 -337 -539 -318 -549 -318] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0899962 0.0899977 + translation -16.1993 42.7489 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [279 -20 260 -20 232 -1 223 -1 214 -1 205 -20 195 -20 186 -20 167 -29 167 -39 167 -48 149 -66 149 -76 139 -94 139 -94 139 -113 139 -132 130 -141 130 -159 130 -169 139 -178 139 -187 139 -187 149 -206 149 -206 149 -206 158 -225 158 -225 158 -225 177 -234 177 -234 177 -234 195 -234 195 -234 195 -234 214 -234 214 -234 214 -234 232 -234 232 -234 242 -234 251 -225 260 -225 270 -225 270 -225 279 -215 279 -215 288 -215 288 -215 298 -206 298 -206 307 -197 307 -197 316 -187 316 -187 316 -178 316 -178 325 -169 325 -169 335 -159 335 -159 335 -141 335 -141 335 -132 335 -122 335 -113 335 -94 325 -85 325 -76 325 -76 325 -48 325 -48 325 -48 316 -29 316 -29 316 -29 298 -20 298 -20 288 -11 288 -11 279 -11 279 -11 270 -11 260 -11 232 -11 223 -11] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 1 2 1 2] + point Coordinate2D { + point [232 -252 232 -280 214 -327 214 -345 214 -364 205 -411 205 -429 205 -438 205 -466 205 -476 205 -494 205 -494 205 -513 205 -513 195 -531 195 -531 195 -569 195 -569] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 1 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [56 -848 65 -857 130 -913 149 -931 158 -941 186 -968 149 -913 149 -913 130 -866 130 -773 130 -717 130 -680 112 -662 112 -624 112 -578 139 -522 195 -522 260 -522 409 -531 409 -615 409 -615 428 -634 400 -634 372 -634 298 -615 279 -624 260 -634 279 -736 279 -755] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [-56 -327 -46 -290 -37 -243 -28 -197 -28 -187 0 -159 9 -141 9 -132 19 -141 19 -150 28 -169 112 -243 149 -243 167 -243 214 -262 251 -262 279 -262 298 -252 316 -271 325 -280 353 -299 353 -299 353 -299 381 -327 391 -327 446 -355 325 -373 316 -373 279 -383 205 -373 177 -345] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0900707 0.0899924 + translation -85.7923 41.9814 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [1060 -20 1060 -20 1014 -2 1004 -2 995 -2 986 -11 976 -11 976 -11 949 -20 949 -20 939 -20 921 -48 921 -58 921 -58 902 -86 902 -86 902 -86 902 -104 902 -104 902 -113 902 -123 902 -132 902 -132 911 -151 911 -151 911 -151 921 -169 921 -169 921 -169 939 -188 939 -188 939 -188 949 -197 949 -197 949 -197 967 -206 967 -206 967 -206 986 -206 995 -206 1004 -206 1004 -206 1014 -206 1014 -206 1023 -206 1023 -206 1032 -206 1032 -206 1051 -197 1051 -197 1060 -197 1060 -197 1069 -188 1069 -188 1079 -179 1079 -179 1079 -169 1079 -169 1088 -169 1088 -169 1088 -169 1088 -151 1088 -151 1088 -141 1097 -123 1097 -104 1097 -86 1097 -86 1088 -67 1088 -67 1079 -48 1079 -48 1079 -48 1069 -39 1069 -39 1060 -30 1060 -30 1051 -30 1051 -30 1042 -20 1032 -20 1014 -11 1004 -11] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 1 2 1 2] + point Coordinate2D { + point [995 -225 995 -253 1014 -318 1014 -346 1014 -365 1014 -411 1014 -430 1014 -439 1014 -467 1014 -476 1014 -485 1014 -485 1014 -504 1014 -504 1014 -513 1014 -523 1014 -541 1023 -541] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 1 2 2 2 2 2 2] + point Coordinate2D { + point [809 -932 846 -932 893 -913 921 -913 958 -913 930 -895 930 -895 921 -895 893 -895 865 -774 865 -764 837 -699 921 -569 976 -541 1014 -523 1088 -578 1097 -588 1107 -597 1144 -625 1153 -634 1209 -690 1069 -644 1051 -662 1032 -681 1116 -792 1153 -792] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2] + point Coordinate2D { + point [688 -532 688 -485 716 -374 753 -355 800 -327 883 -262 939 -262 976 -262 1032 -281 1069 -262 1125 -234 1190 -309 1209 -327 1237 -355 1181 -383 1162 -402 1144 -420 1107 -448 1107 -476] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.0899064 0.08998 + translation -164.619 43.1904 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 2 1 2 2 2 2 2 1 2 1 2] + point Coordinate2D { + point [1878 -20 1851 -11 1841 -1 1813 -1 1804 -1 1804 -11 1795 -11 1785 -11 1767 -39 1767 -48 1758 -57 1739 -66 1739 -85 1739 -85 1739 -113 1739 -113 1739 -122 1748 -132 1748 -141 1748 -141 1758 -159 1758 -169 1758 -169 1767 -187 1767 -187 1767 -187 1776 -206 1776 -206 1776 -206 1785 -215 1785 -215 1785 -215 1804 -225 1804 -225 1804 -225 1823 -225 1823 -225 1823 -225 1841 -225 1841 -225 1841 -225 1860 -215 1860 -215 1869 -215 1869 -215 1878 -206 1878 -206 1888 -197 1888 -197 1897 -187 1897 -187 1906 -178 1906 -178 1916 -169 1916 -169 1916 -159 1916 -159 1925 -150 1925 -150 1925 -150 1925 -132 1925 -132 1925 -122 1925 -122 1934 -113 1934 -113 1934 -113 1934 -85 1925 -76 1925 -76 1906 -66 1906 -57 1906 -48 1906 -39 1897 -29 1897 -29 1878 -20 1878 -20 1869 -20 1869 -20 1860 -11 1860 -11 1851 -11 1841 -11 1823 -1 1804 -1] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 1 2 1 2] + point Coordinate2D { + point [1832 -234 1832 -271 1841 -327 1841 -364 1841 -383 1841 -411 1841 -429 1841 -429 1841 -466 1841 -466 1841 -466 1841 -485 1841 -485 1851 -485 1851 -485 1851 -494 1851 -494 1841 -494 1841 -494 1841 -531 1841 -531] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [1758 -959 1767 -931 1804 -894 1813 -866 1813 -857 1851 -792 1851 -792 1851 -792 1851 -792 1851 -792 1851 -792 1841 -801 1841 -801 1813 -829 1776 -708 1776 -699 1776 -662 1767 -606 1776 -578 1776 -578 1776 -550 1776 -550 1776 -550 1785 -559 1795 -559 1841 -559 1916 -550 1953 -513 1962 -504 1999 -485 1999 -485 1999 -485 2018 -466 2018 -466 2018 -466 2037 -457 2037 -457 2037 -457 2027 -457 2027 -457 2009 -476 1944 -606 1944 -652 1944 -652 1934 -680 1934 -680 1934 -680 1962 -662 1962 -662 1971 -652 2018 -615 2037 -606 2037 -606 2092 -597 2074 -597] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2] + point Coordinate2D { + point [1674 -476 1646 -448 1618 -411 1590 -383 1581 -373 1572 -345 1572 -345 1553 -327 1692 -262 1730 -252 1776 -243 1767 -225 1804 -243 1813 -243 1897 -243 1906 -243 1944 -243 1990 -271 1999 -280 2027 -308 2092 -383 2092 -411] + } + } + } + ] + } + ] + } + Transform2D { + scale 0.089974 0.090028 + translation -247.069 37.0465 + children [ + Transform2D { + children [ + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 2 1 2 1 2 1 2 2 2 2 2 2 1 2 1 2 1] + point Coordinate2D { + point [2715 -4 2687 -4 2660 -13 2641 -13 2641 -13 2622 -23 2622 -23 2613 -32 2585 -69 2585 -69 2585 -78 2576 -106 2576 -116 2576 -134 2567 -125 2576 -143 2576 -143 2576 -171 2576 -171 2576 -171 2594 -190 2594 -190 2594 -190 2604 -209 2604 -209 2604 -209 2613 -218 2613 -218 2613 -218 2632 -218 2632 -218 2632 -218 2650 -218 2650 -218 2650 -218 2669 -218 2669 -218 2669 -218 2687 -209 2687 -209 2687 -209 2706 -209 2706 -209 2715 -199 2715 -199 2725 -199 2725 -199 2734 -199 2734 -199 2743 -190 2743 -190 2753 -190 2753 -190 2762 -181 2762 -181 2762 -171 2762 -171 2771 -171 2771 -171 2771 -162 2771 -162 2780 -153 2780 -153 2780 -153 2780 -134 2780 -134 2780 -125 2780 -97 2780 -88 2780 -78 2771 -69 2771 -60 2771 -60 2762 -50 2762 -50 2762 -50 2753 -32 2753 -32 2753 -23 2753 -23 2743 -13 2743 -13 2734 -13 2734 -13 2715 5 2715 -4 2734 -13] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 1 2 1 2] + point Coordinate2D { + point [2660 -255 2660 -274 2660 -311 2660 -329 2660 -348 2660 -376 2660 -395 2660 -413 2660 -413 2660 -432 2660 -432 2660 -450 2660 -460 2660 -497 2660 -506] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2 2 2 2 2 2 2 2] + point Coordinate2D { + point [2464 -822 2483 -794 2520 -748 2539 -720 2539 -711 2576 -683 2567 -683 2529 -683 2483 -711 2446 -711 2427 -711 2474 -636 2474 -636 2492 -608 2539 -571 2567 -553 2576 -553 2585 -534 2594 -534 2622 -525 2641 -506 2669 -506 2697 -506 2734 -506 2762 -506 2780 -506 2873 -553 2883 -571 2883 -571 2892 -590 2892 -599 2892 -599 2901 -627 2901 -627 2901 -627 2911 -608 2911 -608 2920 -581 2957 -534 2957 -506] + } + } + } + Shape { + appearance USE APP + geometry Curve2D { + type [2 2 2 2 2 2] + point Coordinate2D { + point [2641 -292 2585 -311 2529 -320 2464 -320 2427 -320 2483 -274 2483 -274 2529 -227 2687 -227 2799 -227 2836 -227 2920 -227 2948 -236 2966 -246 3004 -264 3004 -274 3013 -292 3050 -320 3050 -329] + } + } + } + ] + } + ] + } + ] + } + ] + } + DEF TS TimeSensor { + cycleInterval IS runTime + loop IS loop + startTime IS start + } + DEF VAL Valuator { + Factor1 8 + } + DEF R1 ROUTE TS.fraction_changed TO VAL.inSFFloat + ROUTE VAL.outSFInt32 TO MYSWITCH.whichChoice +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["Each animated logo is an instance of a single proto" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Complexe proto Test" + } + FORESTGUMP { + translation -75 -75 + scale 1.1 1.1 + rotation 0.75 + runTime 0.5 + } + FORESTGUMP { + translation -100 50 + scale 1 1.5 + runTime 0.75 + start 2 + } + FORESTGUMP { + translation 0 10 + scale 1.8 1.8 + start 4 + } + DEF ANIM FORESTGUMP { + translation 75 -75 + rotation -1.25 + runTime 0.8 + start 6 + } + DEF TIMER TimeSensor { + cycleInterval 2 + loop TRUE + startTime 6 + } + DEF SI ScalarInterpolator { + key [0 1] + keyValue [0 6.283] + } + ] +} + +ROUTE TIMER.fraction_changed TO SI.set_fraction +ROUTE SI.value_changed TO ANIM.rotation + diff --git a/regression_tests/bifs/bifs-proto-mfurl.bt b/regression_tests/bifs/bifs-proto-mfurl.bt new file mode 100644 index 0000000..85cabfc --- /dev/null +++ b/regression_tests/bifs/bifs-proto-mfurl.bt @@ -0,0 +1,78 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +PROTO testURL [ + exposedField MFString theURL [""] +] { + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF MYTEXT ImageTexture { + url IS theURL + } + } + geometry Bitmap {} + + } + ] + } +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This is a proto with an MF URL ISed field" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Proto with URL Test" + } + DEF testInstance testURL { + theURL ["10"] + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/logo.jpg" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-proto-multiple.bt b/regression_tests/bifs/bifs-proto-multiple.bt new file mode 100644 index 0000000..67f895a --- /dev/null +++ b/regression_tests/bifs/bifs-proto-multiple.bt @@ -0,0 +1,180 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +PROTO PaletteElement [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFColor color 0 0 0 + exposedField SFFloat proto_ident 0 + eventOut SFBool isOver + eventOut SFInt32 active_proto +] { + Transform2D { + scale IS scale + translation IS translation + children [ + DEF TS TouchSensor { + isOver IS isOver + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor IS color + filled TRUE + lineProps LineProperties { + width 3 + } + } + } + geometry IndexedFaceSet2D { + coordIndex [0 1 2 3 4 5 -1] + coord Coordinate2D { + point [100 0 50 86.6 -50 86.6 -100 0 -50 -86.6 50 -86.6] + } + } + } + ] + } + DEF V Valuator { + outSFInt32 IS active_proto + Factor1 0 + Factor2 0 + Factor3 0 + Factor4 0 + Offset1 IS proto_ident + } + ROUTE TS.isActive TO V.inSFBool +} +PROTO Palette [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + eventOut SFColor selectedColor + eventOut MFString active +] { + DEF TR Transform2D { + scale IS scale + translation IS translation + children [ + DEF RedPaletteElement PaletteElement { + color 1 0 0 + proto_ident 1 + } + DEF GreenPaletteElement PaletteElement { + translation 150 86.6 + color 0 1 0 + proto_ident 2 + } + DEF BluePaletteElement PaletteElement { + translation -150 86.6 + color 0 0 1 + proto_ident 3 + } + ] + } + DEF ColorValuator Valuator { + outSFColor IS selectedColor + } + DEF RConditional Conditional { + buffer { + REPLACE ColorValuator.inSFColor BY 1 0 0 + } + } + DEF GConditional Conditional { + buffer { + REPLACE ColorValuator.inSFColor BY 0 1 0 + } + } + DEF BConditional Conditional { + buffer { + REPLACE ColorValuator.inSFColor BY 0 0 1 + } + } + DEF V2 Valuator { + outMFString IS active + } + ROUTE RedPaletteElement.isOver TO RConditional.activate + ROUTE GreenPaletteElement.isOver TO GConditional.activate + ROUTE BluePaletteElement.isOver TO BConditional.activate + ROUTE RedPaletteElement.active_proto TO V2.inSFInt32 + ROUTE GreenPaletteElement.active_proto TO V2.inSFInt32 + ROUTE BluePaletteElement.active_proto TO V2.inSFInt32 +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows a Proto using Protos" "Each palette element is a proto" "The whole palette is another proto" "with routes and conditionals" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Nested Proto test" + } + Transform2D { + translation 0 100 + children [ + Shape { + appearance Appearance { + material DEF Material2DNode Material2D { + filled TRUE + lineProps LineProperties { + width 3 + } + } + } + geometry Rectangle { + size 10 10 + } + } + ] + } + Transform2D { + scale 0.5 0.5 + translation 0 -50 + children [ + DEF P Palette {} + ] + } + Transform2D { + translation 0 50 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + string ["Active Palette"] + fontStyle FontStyle { + size 20 + } + } + } + ] + } + ] +} + +ROUTE P.selectedColor TO Material2DNode.emissiveColor +ROUTE P.active TO TXT.string + diff --git a/regression_tests/bifs/bifs-proto-nested.bt b/regression_tests/bifs/bifs-proto-nested.bt new file mode 100644 index 0000000..2d656a8 --- /dev/null +++ b/regression_tests/bifs/bifs-proto-nested.bt @@ -0,0 +1,132 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +PROTO Palette [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + eventOut SFColor selectedColor +] { + PROTO PaletteElement [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFColor color 0 0 0 + eventOut SFBool isOver + ] { + Transform2D { + scale IS scale + translation IS translation + children [ + TouchSensor { + isOver IS isOver + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor IS color + filled TRUE + lineProps LineProperties { + width 3 + } + } + } + geometry IndexedFaceSet2D { + coordIndex [0 1 2 3 4 5 -1] + coord Coordinate2D { + point [100 0 50 86.6 -50 86.6 -100 0 -50 -86.6 50 -86.6] + } + } + } + ] + } + } + DEF TR Transform2D { + scale IS scale + translation IS translation + children [ + DEF RedPaletteElement PaletteElement { + color 1 0 0 + } + ] + } + DEF ColorValuator Valuator { + outSFColor IS selectedColor + } + DEF RConditional Conditional { + buffer { + REPLACE ColorValuator.inSFColor BY 1 0 0 + } + } + DEF Conditional Conditional { + buffer { + REPLACE ColorValuator.inSFColor BY 0.8 0.8 0.8 + } + } + ROUTE RedPaletteElement.isOver TO RConditional.activate + ROUTE RedPaletteElement.isOver TO Conditional.reverseActivate +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows a Proto using DEF/USE Protos" "declared inside the proto itself" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Nested Proto test" + } + Transform2D { + translation 0 100 + children [ + Shape { + appearance Appearance { + material DEF Material2DNode Material2D { + filled TRUE + lineProps LineProperties { + width 3 + } + } + } + geometry Rectangle { + size 10 10 + } + } + ] + } + Transform2D { + scale 0.5 0.5 + translation -100 -50 + children [ + DEF P Palette {} + ] + } + Transform2D { + scale 0.5 0.5 + translation 50 -50 + children [ + Palette {} + ] + } + ] +} + +ROUTE P.selectedColor TO Material2DNode.emissiveColor + diff --git a/regression_tests/bifs/bifs-proto-route.bt b/regression_tests/bifs/bifs-proto-route.bt new file mode 100644 index 0000000..8b0d45a --- /dev/null +++ b/regression_tests/bifs/bifs-proto-route.bt @@ -0,0 +1,110 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] { + Transform2D { + rotationAngle IS rotation + scale IS scale + translation IS translation + children [ + DEF S Shape { + geometry IS obj + appearance Appearance { + material DEF M Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + DEF TOUCH TouchSensor {} + ] + } + DEF TS TimeSensor { + loop TRUE + } + DEF C Conditional { + buffer { + DELETE ROUTE RTS + } + } + DEF RC Conditional { + buffer { + INSERT ROUTE DEF RTS TS.fraction_changed TO M.transparency + } + } + DEF RTS ROUTE TS.fraction_changed TO M.transparency + ROUTE TOUCH.isActive TO C.activate + ROUTE TOUCH.isActive TO RC.reverseActivate +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of ROUTES inside a proto" "with deletion/insertion through conditionals" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Simple proto Test" + } + GEOMETRY_PROTO { + translation 200 0 + scale 1 1.5 + rotation 0.78 + Color 1 0 1 + transparency 0.75 + lineColor 1 0 0 + lineWidth 2 + obj DEF C Circle { + radius 75 + } + } + Transform2D { + translation -300 0 + children [ + GEOMETRY_PROTO { + translation 200 0 + scale 1 1.5 + rotation 0.78 + Color 0 0 1 + obj USE C + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-proto-sftime-protocode.bt b/regression_tests/bifs/bifs-proto-sftime-protocode.bt new file mode 100644 index 0000000..9c8c3f0 --- /dev/null +++ b/regression_tests/bifs/bifs-proto-sftime-protocode.bt @@ -0,0 +1,99 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] { + DEF TR Transform2D { + scale IS scale + translation IS translation + children [ + Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + DEF TS TimeSensor { + cycleInterval 4 + loop TRUE + } + ] + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1.76 0] + } + ROUTE TS.fraction_changed TO SI.set_fraction + ROUTE SI.value_changed TO TR.rotationAngle +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["The animation start time embedded in proto body" "Animation shall begin at node creation time" "if objects rotations are in sync the player is broken" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Proto SFTime Test" + } + DEF ROOT Transform2D { + children [ + GEOMETRY_PROTO { + translation -120 0 + Color 0 1 1 + obj Rectangle { + size 200 100 + } + } + ] + } + ] +} + + +AT 2000 { + APPEND TO ROOT.children GEOMETRY_PROTO { + translation 120 0 + Color 1 0 1 + lineColor 1 0 0 + obj Rectangle { + size 200 100 + } + } +} + diff --git a/regression_tests/bifs/bifs-proto-sftime-protointerface.bt b/regression_tests/bifs/bifs-proto-sftime-protointerface.bt new file mode 100644 index 0000000..6e1d2e0 --- /dev/null +++ b/regression_tests/bifs/bifs-proto-sftime-protointerface.bt @@ -0,0 +1,104 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFTime start 0 + exposedField SFNode obj NULL +] { + DEF TR Transform2D { + scale IS scale + translation IS translation + children [ + Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + DEF TS TimeSensor { + cycleInterval 4 + loop TRUE + startTime IS start + } + ] + } + DEF SI ScalarInterpolator { + key [0 0.5 1] + keyValue [0 1.5708 0] + } + ROUTE TS.fraction_changed TO SI.set_fraction + ROUTE SI.value_changed TO TR.rotationAngle +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["The animation start time is part of proto interface" "Second object appears at 2 sec and starts moving at 4 sec(2+2)" "If objects rotations are not in sync the player is broken" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Proto SFTime Test" + } + DEF ROOT Transform2D { + children [ + GEOMETRY_PROTO { + translation -120 0 + Color 0 1 1 + obj Rectangle { + size 200 100 + } + } + ] + } + ] +} + + +AT 2000 { + APPEND TO ROOT.children GEOMETRY_PROTO { + translation 120 0 + Color 1 0 1 + transparency 0.75 + lineColor 1 0 0 + lineWidth 2 + start 2 + obj Rectangle { + size 200 100 + } + } +} + diff --git a/regression_tests/bifs/bifs-proto-simple.bt b/regression_tests/bifs/bifs-proto-simple.bt new file mode 100644 index 0000000..fb02fb4 --- /dev/null +++ b/regression_tests/bifs/bifs-proto-simple.bt @@ -0,0 +1,88 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] { + Transform2D { + rotationAngle IS rotation + scale IS scale + translation IS translation + children [ + Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + ] + } +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows simple proto usage" "The shapes are all instances of a single proto" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Simple proto Test" + } + GEOMETRY_PROTO { + translation -100 0 + Color 0 1 1 + obj Rectangle { + size 100 100 + } + } + GEOMETRY_PROTO { + translation 100 0 + scale 1 1.5 + rotation 0.78 + Color 1 0 1 + transparency 0.75 + lineColor 1 0 0 + lineWidth 2 + obj Circle { + radius 75 + } + } + ] +} + + diff --git a/regression_tests/bifs/bifs-proto-use.bt b/regression_tests/bifs/bifs-proto-use.bt new file mode 100644 index 0000000..24f4ef9 --- /dev/null +++ b/regression_tests/bifs/bifs-proto-use.bt @@ -0,0 +1,93 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +PROTO GEOMETRY_PROTO [ + exposedField SFVec2f translation 0 0 + exposedField SFVec2f scale 1 1 + exposedField SFFloat rotation 0 + exposedField SFColor Color 1 1 1 + exposedField SFBool filled TRUE + exposedField SFFloat transparency 0 + exposedField SFColor lineColor 0 0 0 + exposedField SFFloat lineWidth 0 + exposedField SFNode obj NULL +] { + Transform2D { + rotationAngle IS rotation + scale IS scale + translation IS translation + children [ + DEF S Shape { + geometry IS obj + appearance Appearance { + material Material2D { + emissiveColor IS Color + filled IS filled + transparency IS transparency + lineProps LineProperties { + lineColor IS lineColor + width IS lineWidth + } + } + } + } + Transform2D { + translation -100 0 + children [ + USE S + ] + } + ] + } +} +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of DEF/USE inside a proto" "and DEF/USE of a proto" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Simple proto Test" + } + DEF G GEOMETRY_PROTO { + translation 200 0 + scale 1 1.5 + rotation 0.78 + Color 1 0 1 + transparency 0.75 + lineColor 1 0 0 + lineWidth 2 + obj Circle { + radius 75 + } + } + Transform2D { + translation -300 0 + children [ + USE G + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-script-char-to-int.bt b/regression_tests/bifs/bifs-script-char-to-int.bt new file mode 100644 index 0000000..a31658f --- /dev/null +++ b/regression_tests/bifs/bifs-script-char-to-int.bt @@ -0,0 +1,87 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows script sending eventOuts" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Script eventOut test" + } + Transform2D { + translation -150 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TEXT Text { + string ["What"] + fontStyle FontStyle { + justify ["BEGIN" "BEGIN"] + size 20 + } + } + } + ] + } + Transform2D { + translation 150 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TEXT_TEST Text { + string ["T"] + fontStyle FontStyle { + justify ["BEGIN" "BEGIN"] + size 20 + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 0.1 + loop TRUE + } + DEF SCRIPT Script { + eventIn SFTime act + field SFInt32 int_val 0 + field SFNode txt USE TEXT + field SFNode txt2 USE TEXT_TEST + url ["javascript: function initialize(value, timestamp) {int_val = txt.string[0].charCodeAt(0);txt2.string[0] = 'char val: ' + String.fromCharCode(int_val) + ' ' + int_val;}" ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-script-child-create.bt b/regression_tests/bifs/bifs-script-child-create.bt new file mode 100644 index 0000000..389462d --- /dev/null +++ b/regression_tests/bifs/bifs-script-child-create.bt @@ -0,0 +1,61 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows script creating a new node in an MF field" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Script Node Creation test" + } + Transform2D { + children [ + DEF TS TouchSensor {} + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + ] + } + DEF TR Transform2D { + translation -150 -120 + } + DEF SCRIPT Script { + eventIn SFBool act + field SFNode t USE TR + url ["javascript: function act(value, timestamp) {if (!value) return;t.children[0] = new SFNode('Shape');t.children[0].geometry = new SFNode('Rectangle');t.children[0].geometry.size = new SFVec2f(100, 50);t.children[0].appearance = new SFNode('Appearance');t.children[0].appearance.material = new SFNode('Material2D');t.children[0].appearance.material.filled = true;t.children[0].appearance.material.emissiveColor = new SFColor(0, 0, 1);}" ] + } + ] +} + +ROUTE TS.isActive TO SCRIPT.act + diff --git a/regression_tests/bifs/bifs-script-date.bt b/regression_tests/bifs/bifs-script-date.bt new file mode 100644 index 0000000..da0c0f5 --- /dev/null +++ b/regression_tests/bifs/bifs-script-date.bt @@ -0,0 +1,64 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 260 + pixelHeight 70 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows script used to retrieve system time" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Script Date() test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + string ["MPEG4 time on your system"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + DEF TIMER TimeSensor { + loop TRUE + } + DEF SC Script { + eventIn SFTime set_time + field SFNode str USE TXT + url ["javascript:function set_time(value, text) {today = new Date();the_day = today.getDate();the_weekday = today.getDay();the_month = today.getMonth();the_year = today.getYear();the_hour = today.getHours();the_minute = today.getMinutes();the_second = today.getSeconds();am_pm = 0;the_initials = 'a.m.';if (the_year < 1900) the_year = the_year + 1900;if ((the_hour >=2) && (the_hour <=11)) {am_pm = the_hour;the_initials = 'a.m.';} else if (the_hour == 0) {am_pm = 12;the_initials = 'a.m.';} else if (the_hour == 12) {am_pm = 12;the_initials = 'p.m.';} else if (the_hour >=13) {am_pm = the_hour - 12;the_initials = 'p.m.';}if (the_minute <=9) the_minute = '0' + (the_minute);if (the_second <=9) the_second = '0' + (the_second);if (the_month == '0') the_month = 'January';else if (the_month == '1') the_month = 'February';else if (the_month == '2') the_month = 'March';else if (the_month == '3') the_month = 'April';else if (the_month == '4') the_month = 'May';else if (the_month == '5') the_month = 'June';else if (the_month == '6') the_month = 'July';else if (the_month == '7') the_month = 'August';else if (the_month == '8') the_month = 'September';else if (the_month == '9') the_month = 'October';else if (the_month == '10') the_month = 'November';else if (the_month == '11') the_month = 'December';if (the_weekday == '0') the_weekday = 'Sunday';else if (the_weekday == '1') the_weekday = 'Monday';else if (the_weekday == '2') the_weekday = 'Tuesday';else if (the_weekday == '3') the_weekday = 'Wednesday';else if (the_weekday == '4') the_weekday = 'Thursday';else if (the_weekday == '5') the_weekday = 'Friday';else if (the_weekday == '6') the_weekday = 'Saturday';if (the_day == '1') the_day = '1st';else if (the_day == '2') the_day = '2nd';else if (the_day == '3') the_day = '3rd';else if (the_day == '4') the_day = '4th';else if (the_day == '21') the_day = '21st';else if (the_day == '22') the_day = '23rd';else if (the_day == '31') the_day = '31st';else the_day = the_day + 'th';str.string[1] = the_weekday + ' ' + the_day + ' ' + the_month + ', ' + the_year;str.string[2] = am_pm + ':' + the_minute + ':' + the_second + ' ' + the_initials;}function initialize() {set_time(0, 0);}" ] + } + ] +} + +ROUTE TIMER.cycleTime TO SC.set_time + diff --git a/regression_tests/bifs/bifs-script-event-out.bt b/regression_tests/bifs/bifs-script-event-out.bt new file mode 100644 index 0000000..46cd32f --- /dev/null +++ b/regression_tests/bifs/bifs-script-event-out.bt @@ -0,0 +1,85 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows script sending eventOuts" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Script eventOut test" + } + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry DEF IFS IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 4 5] + coord Coordinate2D { + point [-120 0 -50 100 50 100 120 0 50 -100 -50 -100] + } + } + } + Transform2D { + translation -150 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TEXT Text { + string [""] + fontStyle FontStyle { + justify ["BEGIN" "BEGIN"] + size 20 + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 0.1 + loop TRUE + } + DEF SCRIPT Script { + eventIn SFTime act + field SFInt32 count 0 + eventOut SFFloat transp + eventOut MFString txt + url ["javascript: function act(value, timestamp) {count++;if (count>= 20) count = 0;transp = count / 20;txt[0] = 'transparency: ' + transp; }" ] + } + ] +} + +ROUTE TS.cycleTime TO SCRIPT.act +ROUTE SCRIPT.transp TO MAT.transparency +ROUTE SCRIPT.txt TO TEXT.string + diff --git a/regression_tests/bifs/bifs-script-initialize.bt b/regression_tests/bifs/bifs-script-initialize.bt new file mode 100644 index 0000000..7740a94 --- /dev/null +++ b/regression_tests/bifs/bifs-script-initialize.bt @@ -0,0 +1,86 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows script Initialize usage" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Script initialize test" + } + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry DEF IFS IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 4 5] + coord Coordinate2D { + point [-120 0 -50 100 50 100 120 0 50 -100 -50 -100] + } + } + } + Transform2D { + translation -150 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TEXT Text { + string [""] + fontStyle FontStyle { + family ["SANS"] + justify ["BEGIN" "BEGIN"] + size 20 + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 0.2 + loop TRUE + } + DEF SCRIPT Script { + eventIn SFTime act + field SFInt32 count 0 + eventOut SFFloat transp + eventOut MFString txt + url ["javascript: function initialize(value, timestamp) {my_global_string = 'global int = ';my_global_int = 10;}function act(value, timestamp) {count++;if (count>= 20) count = 0;transp = count / 20;txt[0] = 'transparency: ' + transp; txt[1] = my_global_string + my_global_int; }" ] + } + ] +} + +ROUTE TS.cycleTime TO SCRIPT.act +ROUTE SCRIPT.transp TO MAT.transparency +ROUTE SCRIPT.txt TO TEXT.string + diff --git a/regression_tests/bifs/bifs-script-load-url.bt b/regression_tests/bifs/bifs-script-load-url.bt new file mode 100644 index 0000000..3add453 --- /dev/null +++ b/regression_tests/bifs/bifs-script-load-url.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows script loading URL" "" "GPAC Regression Tests" "$Date: 2008-07-18 17:27:50 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Script URL loading" + } + Transform2D { + children [ + DEF TS TouchSensor {} + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + ] + } + DEF TR Transform2D { + translation -150 -120 + } + DEF SCRIPT Script { + eventIn SFBool act + field SFNode t USE TR + url ["javascript: + function act(value, timestamp) { + if (!value) return; + str = new MFString('http://gpac.sourceforge.net'); + Browser.loadURL(str) ; + } + " ] + } + ] +} + +ROUTE TS.isActive TO SCRIPT.act + diff --git a/regression_tests/bifs/bifs-script-node-access.bt b/regression_tests/bifs/bifs-script-node-access.bt new file mode 100644 index 0000000..e34f3ba --- /dev/null +++ b/regression_tests/bifs/bifs-script-node-access.bt @@ -0,0 +1,86 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows script modifying nodes directly" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Node Modification Script test" + } + Shape { + appearance Appearance { + material DEF MAT Material2D { + filled TRUE + } + } + geometry DEF IFS IndexedFaceSet2D { + colorIndex [0 1 2 3 4 5] + coordIndex [0 1 2 3 4 5] + color Color { + color [0 0 1 0 1 0 1 0 0 1 1 0 1 0 1 0 1 1] + } + coord Coordinate2D { + point [-120 0 -50 100 50 100 120 0 50 -100 -50 -100] + } + } + } + DEF TS TimeSensor { + loop TRUE + } + Transform2D { + translation -150 -120 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TEXT Text { + string [""] + fontStyle FontStyle { + family ["SANS"] + justify ["BEGIN" "BEGIN"] + size 20 + } + } + } + ] + } + DEF SCRIPT Script { + eventIn SFTime act + field SFNode n USE IFS + field SFNode t USE TS + field SFNode txt USE TEXT + field SFInt32 roll 0 + url ["javascript: function act(value, timestamp) {roll++;count = n.colorIndex.length;first = n.colorIndex[0];for (i=0; i<count; i++) {if (i+1==count) {n.colorIndex[i] = first;} else {n.colorIndex[i] = n.colorIndex[i+1];}}txt.string[0] = 'ColorIndexes: ' + n.colorIndex.toSource();txt.string[2] = 'Current Cycle length: ' + (count * t.cycleInterval) + ' seconds';txt.string[1] = 'Running for ' + timestamp + ' seconds';switch (roll) {case 6:t.enabled = FALSE;t.cycleInterval = 0.5;t.enabled = TRUE;break;case 18:t.enabled = FALSE;t.cycleInterval = 0.1;t.enabled = TRUE;break;case 78:t.enabled = FALSE;t.cycleInterval = 0.05;t.enabled = TRUE;break;case 198:roll = 0;t.enabled = FALSE;t.cycleInterval = 1;t.enabled = TRUE;break;}}" ] + } + ] +} + +ROUTE TS.cycleTime TO SCRIPT.act + diff --git a/regression_tests/bifs/bifs-script-node-create.bt b/regression_tests/bifs/bifs-script-node-create.bt new file mode 100644 index 0000000..a48aafb --- /dev/null +++ b/regression_tests/bifs/bifs-script-node-create.bt @@ -0,0 +1,80 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows script creating a new node at an SF field" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Script Node Creation test" + } + Transform2D { + children [ + DEF TS TouchSensor {} + Shape { + appearance Appearance { + material DEF MAT Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 50 50 + } + } + ] + } + Transform2D { + translation -150 -120 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TEXT Text { + string ["test node create"] + fontStyle FontStyle { + family ["SANS"] + justify ["BEGIN" "BEGIN"] + size 40 + style "BOLDITALIC" + } + } + } + ] + } + DEF SCRIPT Script { + eventIn SFBool act + field SFNode ap USE APP + url ["javascript: function act(value, timestamp) {mat = new SFNode('Material2D');if (value) {mat.emissiveColor = new SFColor(1, 0, 0);mat.filled = TRUE;} else {mat.emissiveColor = new SFColor(0, 0, 0);mat.filled = TRUE;}ap.material = mat;}" ] + } + ] +} + +ROUTE TS.isActive TO SCRIPT.act + diff --git a/regression_tests/bifs/bifs-script-proto.bt b/regression_tests/bifs/bifs-script-proto.bt new file mode 100644 index 0000000..f62035c --- /dev/null +++ b/regression_tests/bifs/bifs-script-proto.bt @@ -0,0 +1,223 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ] +} + +PROTO P0 [ + field SFVec2f trans 0 0 +] { + Transform2D { + translation IS trans + children [ + DEF TS TouchSensor {} + DEF TR1 Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps DEF LP LineProperties { + lineColor 0.2 0.5 0.8 + width 0 + } + } + } + geometry Circle { + radius 8 + } + } + ] + } + DEF TIMER TimeSensor { + cycleInterval 0.5 + startTime -1 + } + ] + } + DEF SC Script { + eventIn SFBool set_over + eventIn SFFloat set_fraction + eventIn SFBool set_active + field SFNode tim USE TIMER + field SFNode line USE LP + eventOut SFFloat frac_changed + url ["javascript: + function set_active(value, timestamp) { + line.width = value ? 2 : 0; + } + function set_over(value, timestamp) { + is_over = value; + if (!tim.isActive) tim.startTime = timestamp; + } + function set_fraction(value, timestamp) { + if (is_over) { + frac_changed = value; + } else { + frac_changed = 1 - value; + } + } + " ] + } + DEF PI PositionInterpolator2D { + key [0 1] + keyValue [1 1 4 4] + } + ROUTE TS.isOver TO SC.set_over + ROUTE TIMER.isActive TO SC.set_active + ROUTE TIMER.fraction_changed TO SC.set_fraction + ROUTE SC.frac_changed TO PI.set_fraction + ROUTE PI.value_changed TO TR1.scale +} +PROTO P1 [ + field SFVec2f trans 0 0 +] { + Transform2D { + translation IS trans + children [ + P0 { + trans -180 0 + } + P0 { + trans -160 0 + } + P0 { + trans -140 0 + } + P0 { + trans -120 0 + } + P0 { + trans -100 0 + } + P0 { + trans -80 0 + } + P0 { + trans -60 0 + } + P0 { + trans -40 0 + } + P0 { + trans -20 0 + } + P0 {} + P0 { + trans 20 0 + } + P0 { + trans 40 0 + } + P0 { + trans 60 0 + } + P0 { + trans 80 0 + } + P0 { + trans 100 0 + } + P0 { + trans 120 0 + } + P0 { + trans 140 0 + } + P0 { + trans 160 0 + } + P0 { + trans 180 0 + } + ] + } +} +OrderedGroup { + children [ + Background2D { + backColor 0.2 0.4 0.7 + } + WorldInfo { + info ["This shows script used in proto for a bubble-like effect" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Script and Proto test" + } + Transform2D { + children [ + P1 { + trans 0 180 + } + P1 { + trans 0 160 + } + P1 { + trans 0 140 + } + P1 { + trans 0 120 + } + P1 { + trans 0 100 + } + P1 { + trans 0 80 + } + P1 { + trans 0 60 + } + P1 { + trans 0 40 + } + P1 { + trans 0 20 + } + P1 {} + P1 { + trans 0 -20 + } + P1 { + trans 0 -40 + } + P1 { + trans 0 -60 + } + P1 { + trans 0 -80 + } + P1 { + trans 0 -100 + } + P1 { + trans 0 -120 + } + P1 { + trans 0 -140 + } + P1 { + trans 0 -160 + } + P1 { + trans 0 -180 + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-script-timestamp.bt b/regression_tests/bifs/bifs-script-timestamp.bt new file mode 100644 index 0000000..3756b24 --- /dev/null +++ b/regression_tests/bifs/bifs-script-timestamp.bt @@ -0,0 +1,67 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows script timestamp value" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Script timing test" + } + Transform2D { + translation -150 0 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TEXT Text { + string [""] + fontStyle FontStyle { + family ["SANS"] + justify ["BEGIN" "MIDDLE"] + size 20 + } + } + } + ] + } + DEF TS TimeSensor { + cycleInterval 0.2 + loop TRUE + } + 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);}" ] + } + ] +} + +ROUTE TS.cycleTime TO SCRIPT.act + diff --git a/regression_tests/bifs/bifs-stream-text-switch.bt b/regression_tests/bifs/bifs-stream-text-switch.bt new file mode 100644 index 0000000..e378e16 --- /dev/null +++ b/regression_tests/bifs/bifs-stream-text-switch.bt @@ -0,0 +1,143 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + includeInlineProfileLevelFlag true + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 0 1 0 + } + WorldInfo { + info ["This shows an AnimationStream node" "controling a 3GPP text stream" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2005 GPAC Team"] + title "3GPP Text Switch" + } + + Transform2D { + translation -50 0 + children [ + DEF TS1 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 75 50 + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["English"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + Transform2D { + translation 50 0 + children [ + DEF TS2 TouchSensor {} + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Rectangle { + size 75 50 + } + } + Shape { + appearance USE APP + geometry Text { + string ["French"] + fontStyle USE FS + } + } + ] + } + + DEF AS AnimationStream { + loop TRUE + url [od:20] + } + DEF C1 Conditional { buffer { + REPLACE AS.stopTime BY 0 + REPLACE AS.url BY ["od:10"] + REPLACE AS.startTime BY 0 + } + } + DEF C2 Conditional { buffer { + REPLACE AS.stopTime BY 0 + REPLACE AS.url BY ["od:20"] + REPLACE AS.startTime BY 0 + } } + ] +} + +ROUTE TS1.isActive TO C1.activate +ROUTE TS2.isActive TO C2.activate + + +RAP AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 5 + OCR_ES_ID 5 + muxInfo MuxInfo { fileName "../auxiliary_files/subtitle.srt" } + } + ] + } + ObjectDescriptor { + objectDescriptorID 20 + esDescr [ + ES_Descriptor { + ES_ID 6 + OCR_ES_ID 6 + muxInfo MuxInfo { fileName "../auxiliary_files/subtitle_fr.srt" } + } + ] + } + ] +} diff --git a/regression_tests/bifs/bifs-text-align-horiz1.bt b/regression_tests/bifs/bifs-text-align-horiz1.bt new file mode 100644 index 0000000..0bb4a71 --- /dev/null +++ b/regression_tests/bifs/bifs-text-align-horiz1.bt @@ -0,0 +1,304 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text alignment for horizontal text" "top to bottom = TRUE" "left to right = TRUE" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Horizontal Text alignment" + } + Transform2D { + translation -180 180 + children [ + DEF LINES Shape { + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1] + coord Coordinate2D { + point [-50 0 50 0 0 -50 0 50] + } + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["M:Begin" "m:Begin"] + fontStyle FontStyle { + justify ["BEGIN" "BEGIN"] + size 20 + } + } + } + ] + } + Transform2D { + translation -80 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:Middle"] + fontStyle FontStyle { + justify ["BEGIN" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 20 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:End"] + fontStyle FontStyle { + justify ["BEGIN" "END"] + size 20 + } + } + } + ] + } + Transform2D { + translation 120 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:First"] + fontStyle FontStyle { + justify ["BEGIN" "FIRST"] + size 20 + } + } + } + ] + } + Transform2D { + translation -180 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:Begin"] + fontStyle FontStyle { + justify ["MIDDLE" "BEGIN"] + size 20 + } + } + } + ] + } + Transform2D { + translation -80 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:Middle"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 20 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:End"] + fontStyle FontStyle { + justify ["MIDDLE" "END"] + size 20 + } + } + } + ] + } + Transform2D { + translation 120 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:First"] + fontStyle FontStyle { + justify ["MIDDLE" "FIRST"] + size 20 + } + } + } + ] + } + Transform2D { + translation -180 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:Begin"] + fontStyle FontStyle { + justify ["END" "BEGIN"] + size 20 + } + } + } + ] + } + Transform2D { + translation -80 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:Middle"] + fontStyle FontStyle { + justify ["END" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 20 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:End"] + fontStyle FontStyle { + justify ["END" "END"] + size 20 + } + } + } + ] + } + Transform2D { + translation 120 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:First"] + fontStyle FontStyle { + justify ["END" "FIRST"] + size 20 + } + } + } + ] + } + Transform2D { + translation -180 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:Begin"] + fontStyle FontStyle { + justify ["FIRST" "BEGIN"] + size 20 + } + } + } + ] + } + Transform2D { + translation -80 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:Middle"] + fontStyle FontStyle { + justify ["FIRST" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 20 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:End"] + fontStyle FontStyle { + justify ["FIRST" "END"] + size 20 + } + } + } + ] + } + Transform2D { + translation 120 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:First"] + fontStyle FontStyle { + justify ["FIRST" "FIRST"] + size 20 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-align-horiz2.bt b/regression_tests/bifs/bifs-text-align-horiz2.bt new file mode 100644 index 0000000..3bb6aa6 --- /dev/null +++ b/regression_tests/bifs/bifs-text-align-horiz2.bt @@ -0,0 +1,320 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text alignment for horizontal text" "top to bottom = FALSE" "left to right = TRUE" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Horizontal Text alignment" + } + Transform2D { + translation -180 180 + children [ + DEF LINES Shape { + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1] + coord Coordinate2D { + point [-50 0 50 0 0 -50 0 50] + } + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["M:Begin" "m:Begin"] + fontStyle FontStyle { + justify ["BEGIN" "BEGIN"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -80 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:Middle"] + fontStyle FontStyle { + justify ["BEGIN" "MIDDLE"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 20 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:End"] + fontStyle FontStyle { + justify ["BEGIN" "END"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 120 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:First"] + fontStyle FontStyle { + justify ["BEGIN" "FIRST"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -180 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:Begin"] + fontStyle FontStyle { + justify ["MIDDLE" "BEGIN"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -80 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:Middle"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 20 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:End"] + fontStyle FontStyle { + justify ["MIDDLE" "END"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 120 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:First"] + fontStyle FontStyle { + justify ["MIDDLE" "FIRST"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -180 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:Begin"] + fontStyle FontStyle { + justify ["END" "BEGIN"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -80 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:Middle"] + fontStyle FontStyle { + justify ["END" "MIDDLE"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 20 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:End"] + fontStyle FontStyle { + justify ["END" "END"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 120 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:First"] + fontStyle FontStyle { + justify ["END" "FIRST"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -180 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:Begin"] + fontStyle FontStyle { + justify ["FIRST" "BEGIN"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -80 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:Middle"] + fontStyle FontStyle { + justify ["FIRST" "MIDDLE"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 20 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:End"] + fontStyle FontStyle { + justify ["FIRST" "END"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 120 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:First"] + fontStyle FontStyle { + justify ["FIRST" "FIRST"] + size 20 + topToBottom FALSE + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-align-horiz3.bt b/regression_tests/bifs/bifs-text-align-horiz3.bt new file mode 100644 index 0000000..ecbebba --- /dev/null +++ b/regression_tests/bifs/bifs-text-align-horiz3.bt @@ -0,0 +1,320 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text alignment for horizontal text" "top to bottom = TRUE" "left to right = FALSE" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Horizontal Text alignment" + } + Transform2D { + translation -180 180 + children [ + DEF LINES Shape { + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1] + coord Coordinate2D { + point [-50 0 50 0 0 -50 0 50] + } + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["M:Begin" "m:Begin"] + fontStyle FontStyle { + justify ["BEGIN" "BEGIN"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation -80 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:Middle"] + fontStyle FontStyle { + justify ["BEGIN" "MIDDLE"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 20 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:End"] + fontStyle FontStyle { + justify ["BEGIN" "END"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 120 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:First"] + fontStyle FontStyle { + justify ["BEGIN" "FIRST"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation -180 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:Begin"] + fontStyle FontStyle { + justify ["MIDDLE" "BEGIN"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation -80 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:Middle"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 20 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:End"] + fontStyle FontStyle { + justify ["MIDDLE" "END"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 120 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:First"] + fontStyle FontStyle { + justify ["MIDDLE" "FIRST"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation -180 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:Begin"] + fontStyle FontStyle { + justify ["END" "BEGIN"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation -80 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:Middle"] + fontStyle FontStyle { + justify ["END" "MIDDLE"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 20 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:End"] + fontStyle FontStyle { + justify ["END" "END"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 120 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:First"] + fontStyle FontStyle { + justify ["END" "FIRST"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation -180 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:Begin"] + fontStyle FontStyle { + justify ["FIRST" "BEGIN"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation -80 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:Middle"] + fontStyle FontStyle { + justify ["FIRST" "MIDDLE"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 20 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:End"] + fontStyle FontStyle { + justify ["FIRST" "END"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 120 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:First"] + fontStyle FontStyle { + justify ["FIRST" "FIRST"] + leftToRight FALSE + size 20 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-align-horiz4.bt b/regression_tests/bifs/bifs-text-align-horiz4.bt new file mode 100644 index 0000000..6f46f6f --- /dev/null +++ b/regression_tests/bifs/bifs-text-align-horiz4.bt @@ -0,0 +1,336 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text alignment for horizontal text" "top to bottom = FALSE" "left to right = FALSE" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Horizontal Text alignment" + } + Transform2D { + translation -180 180 + children [ + DEF LINES Shape { + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1] + coord Coordinate2D { + point [-50 0 50 0 0 -50 0 50] + } + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["M:Begin" "m:Begin"] + fontStyle FontStyle { + justify ["BEGIN" "BEGIN"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -80 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:Middle"] + fontStyle FontStyle { + justify ["BEGIN" "MIDDLE"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 20 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:End"] + fontStyle FontStyle { + justify ["BEGIN" "END"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 120 180 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Begin" "m:First"] + fontStyle FontStyle { + justify ["BEGIN" "FIRST"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -180 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:Begin"] + fontStyle FontStyle { + justify ["MIDDLE" "BEGIN"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -80 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:Middle"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 20 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:End"] + fontStyle FontStyle { + justify ["MIDDLE" "END"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 120 50 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:Middle" "m:First"] + fontStyle FontStyle { + justify ["MIDDLE" "FIRST"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -180 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:Begin"] + fontStyle FontStyle { + justify ["END" "BEGIN"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -80 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:Middle"] + fontStyle FontStyle { + justify ["END" "MIDDLE"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 20 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:End"] + fontStyle FontStyle { + justify ["END" "END"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 120 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:End" "m:First"] + fontStyle FontStyle { + justify ["END" "FIRST"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -180 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:Begin"] + fontStyle FontStyle { + justify ["FIRST" "BEGIN"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -80 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:Middle"] + fontStyle FontStyle { + justify ["FIRST" "MIDDLE"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 20 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:End"] + fontStyle FontStyle { + justify ["FIRST" "END"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 120 -160 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["M:First" "m:First"] + fontStyle FontStyle { + justify ["FIRST" "FIRST"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-align-vert1.bt b/regression_tests/bifs/bifs-text-align-vert1.bt new file mode 100644 index 0000000..eb408fd --- /dev/null +++ b/regression_tests/bifs/bifs-text-align-vert1.bt @@ -0,0 +1,200 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text alignment for vertical text" "top to bottom = TRUE" "left to right = TRUE" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Vertical Text alignment" + } + Transform2D { + translation -150 220 + children [ + DEF LINES Shape { + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1] + coord Coordinate2D { + point [-50 0 50 0 0 -50 0 50] + } + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["MBegin" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "BEGIN"] + size 20 + } + } + } + ] + } + Transform2D { + translation -150 70 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MBegin" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -150 -90 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MBegin" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "END"] + size 20 + } + } + } + ] + } + Transform2D { + translation 0 150 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + size 20 + } + } + } + ] + } + Transform2D { + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 0 -150 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "END"] + size 20 + } + } + } + ] + } + Transform2D { + translation 150 100 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "BEGIN"] + size 20 + } + } + } + ] + } + Transform2D { + translation 150 -80 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 150 -200 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "END"] + size 20 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-align-vert2.bt b/regression_tests/bifs/bifs-text-align-vert2.bt new file mode 100644 index 0000000..09b820e --- /dev/null +++ b/regression_tests/bifs/bifs-text-align-vert2.bt @@ -0,0 +1,209 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text alignment for vertical text" "top to bottom = FALSE" "left to right = TRUE" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Vertical Text alignment" + } + Transform2D { + translation -150 100 + children [ + DEF LINES Shape { + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1] + coord Coordinate2D { + point [-50 0 50 0 0 -50 0 50] + } + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["MBegin" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "BEGIN"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -150 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MBegin" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -150 -200 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MBegin" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "END"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 0 150 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 0 -150 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "END"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 150 200 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "BEGIN"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 150 60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "MIDDLE"] + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 150 -120 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "END"] + size 20 + topToBottom FALSE + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-align-vert3.bt b/regression_tests/bifs/bifs-text-align-vert3.bt new file mode 100644 index 0000000..76723cf --- /dev/null +++ b/regression_tests/bifs/bifs-text-align-vert3.bt @@ -0,0 +1,209 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text alignment for vertical text" "top to bottom = TRUE" "left to right = FALSE" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Vertical Text alignment" + } + Transform2D { + translation -150 220 + children [ + DEF LINES Shape { + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1] + coord Coordinate2D { + point [-50 0 50 0 0 -50 0 50] + } + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["MBegin" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "BEGIN"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation -150 70 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MBegin" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation -150 -90 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MBegin" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "END"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 0 150 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 0 -150 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "END"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 150 100 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "BEGIN"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 150 -80 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "MIDDLE"] + leftToRight FALSE + size 20 + } + } + } + ] + } + Transform2D { + translation 150 -200 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "END"] + leftToRight FALSE + size 20 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-align-vert4.bt b/regression_tests/bifs/bifs-text-align-vert4.bt new file mode 100644 index 0000000..3c9a026 --- /dev/null +++ b/regression_tests/bifs/bifs-text-align-vert4.bt @@ -0,0 +1,218 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text alignment for vertical text" "top to bottom = FALSE" "left to right = FALSE" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Vertical Text alignment" + } + Transform2D { + translation -150 100 + children [ + DEF LINES Shape { + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1] + coord Coordinate2D { + point [-50 0 50 0 0 -50 0 50] + } + } + } + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["MBegin" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "BEGIN"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -150 -60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MBegin" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "MIDDLE"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation -150 -200 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MBegin" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["BEGIN" "END"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 0 150 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "BEGIN"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 0 -150 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MMiddle" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "END"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 150 200 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mBegin"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "BEGIN"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 150 60 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mMiddle"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "MIDDLE"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + Transform2D { + translation 150 -120 + children [ + USE LINES + Shape { + appearance USE APP + geometry Text { + string ["MEnd" "mEnd"] + fontStyle FontStyle { + horizontal FALSE + justify ["END" "END"] + leftToRight FALSE + size 20 + topToBottom FALSE + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-glyph-advance.bt b/regression_tests/bifs/bifs-text-glyph-advance.bt new file mode 100644 index 0000000..f304dd5 --- /dev/null +++ b/regression_tests/bifs/bifs-text-glyph-advance.bt @@ -0,0 +1,436 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSv2Config { + isCommandStream true + pixelMetric true + pixelWidth 480 + pixelHeight 360 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { backColor 1 1 1 } + WorldInfo { + info ["This test shows glyphs, along with their bounding boxes, the font baseline, the word bounding box and the two-lines text bounding box" "If the Arial font is found and used, bounding-boxes should be properly positioned" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2006 GPAC Team"] + title "Text bounding boxes test" + } + Transform2D { + translation -140 80 + children [ + Transform2D { + scale 0.048828125 0.048828125 + children [ + # Em Box Y Axis + Shape { + appearance DEF A1 Appearance { + material Material2D { + filled FALSE + lineProps LineProperties { + width 1 + lineColor 0 0 0 + } + } + } + geometry IndexedLineSet2D { + coord Coordinate2D { + point [ 0 -4000 0 1491 ] + } + } + } + + # Baseline + DEF BASELINE Shape { + appearance USE A1 + geometry IndexedLineSet2D { + coord Coordinate2D { + point [ 0 0 8000 0 ] + } + } + } + + # bounding box for glyph a + Transform2D { + translation 0 0 + children [ + Shape { + appearance DEF A2 Appearance { + material Material2D { + filled FALSE + lineProps LineProperties { + width 1 + lineColor 1 0 0 + } + } + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 74 -24 1052 -24 1052 1086 74 1086 ] + } + } + } + ] + } + + # bounding box for glyph b + Transform2D { + translation 1139 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 134 -24 1055 -24 1055 1466 134 1466 ] + } + } + } + ] + } + + # bounding box for glyph c + Transform2D { + translation 2278 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 80 -24 + 1005 -24 + 1005 1086 + 80 1086 ] + } + } + } + ] + } + + # bounding box for glyph d + Transform2D { + translation 3302 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 70 -24 + 991 -24 + 991 1466 + 70 1466 ] + } + } + } + ] + } + + # bounding box for glyph e + Transform2D { + translation 4441 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 75 -24 + 1054 -24 + 1054 1086 + 75 1086 ] + } + } + } + ] + } + + # bounding box for glyph f + Transform2D { + translation 5580 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 19 0 + 640 0 + 640 1491 + 19 1491 ] + } + } + } + ] + } + + # bounding box for glyph g + Transform2D { + translation 6149 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 66 -431 + 1002 -431 + 1002 1086 + 66 1086 ] + } + } + } + ] + } + + # bounding box for the first line + Transform2D { + translation 0 0 + children [ + Shape { + appearance DEF A3 Appearance { + material Material2D { + filled FALSE + lineProps LineProperties { + width 1 + lineColor 0 0.5 0 + } + } + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 74 -431 + 74 1491 + 7151 1491 + 7151 -431 ] + } + } + } + ] + } + Transform2D { + translation 0 -2048 + children [ + USE BASELINE + # bounding box for glyph h + Transform2D { + translation 0 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 135 0 + 1000 0 + 1000 1466 + 135 1466 ] + } + } + } + ] + } + + # bounding box for glyph i + Transform2D { + translation 1139 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 136 0 + 316 0 + 316 1466 + 136 1466 ] + } + } + } + ] + } + + # bounding box for glyph j + Transform2D { + translation 1594 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ -94 -431 + 314 -431 + 314 1466 + -94 1466 ] + } + } + } + ] + } + + # bounding box for glyph k + Transform2D { + translation 2049 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 136 0 + 1016 0 + 1016 1466 + 136 1466 ] + } + } + } + ] + } + + # bounding box for glyph l + Transform2D { + translation 3087 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 131 0 + 311 0 + 311 1466 + 131 1466 ] + } + } + } + ] + } + + # bounding box for glyph m + Transform2D { + translation 3542 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 135 0 + 1574 0 + 1574 1086 + 135 1086 ] + } + } + } + ] + } + + # bounding box for glyph n + Transform2D { + translation 5248 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 135 0 + 998 0 + 998 1086 + 135 1086 ] + } + } + } + ] + } + + # bounding box for glyph o + Transform2D { + translation 6387 0 + children [ + Shape { + appearance USE A2 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 68 -24 + 1063 -24 + 1063 1086 + 68 1086 ] + } + } + } + ] + } + + # bounding box for the second line + Transform2D { + translation 0 0 + children [ + Shape { + appearance USE A3 + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 135 -431 + 135 1466 + 7436 1466 + 7436 -431 ] + } + } + } + ] + } + + ] + } + + # bounding box for the whole text + Transform2D { + translation 0 0 + children [ + Shape { + appearance Appearance { + material Material2D { + filled FALSE + lineProps LineProperties { + width 1 + lineColor 1 1 0 + } + } + } + geometry IndexedFaceSet2D { + coord Coordinate2D { + point [ 74 1491 + 7436 1491 + 7436 -2479 + 74 -2479 ] + } + } + } + ] + } + + ] + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string [ "abcdefg" "hijklmno"] + fontStyle FontStyle { + family ["Arial"] + justify ["BEGIN" "FIRST"] + size 100 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-length.bt b/regression_tests/bifs/bifs-text-length.bt new file mode 100644 index 0000000..fbd4f39 --- /dev/null +++ b/regression_tests/bifs/bifs-text-length.bt @@ -0,0 +1,230 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 450 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text with and without length fields" "All texts use the same font and size" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Text length Test" + } + Transform2D { + translation -75 0 + children [ + Shape { + geometry IndexedLineSet2D { + coord Coordinate2D { + point [0 200 0 -120] + } + } + } + ] + } + Transform2D { + translation 75 0 + children [ + Shape { + geometry IndexedLineSet2D { + coord Coordinate2D { + point [0 200 0 -120] + } + } + } + ] + } + Transform2D { + translation 0 150 + children [ + Shape { + geometry IndexedLineSet2D { + coord Coordinate2D { + point [200 0 -200 0] + } + } + } + ] + } + Transform2D { + translation -150 180 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["No length"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE"] + size 24 + } + } + } + ] + } + Transform2D { + translation 0 180 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Length on " "longest line"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 150 180 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Length on" "all lines"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -150 100 + children [ + DEF SQUARE Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Rectangle { + size 100 80 + } + } + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Text" "to test length"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 0 100 + children [ + USE SQUARE + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Text" "to test length"] + length [-1 100] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 150 100 + children [ + USE SQUARE + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Text" "to test length"] + length [100 100] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -150 -50 + children [ + DEF VSQUARE Shape { + appearance USE APP + geometry Rectangle { + size 80 100 + } + } + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Length" "Test"] + fontStyle DEF FS2 FontStyle { + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + size 24 + } + } + } + ] + } + Transform2D { + translation 0 -50 + children [ + USE VSQUARE + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Length" "Test"] + length [100 -1] + fontStyle USE FS2 + } + } + ] + } + Transform2D { + translation 150 -50 + children [ + USE VSQUARE + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Length" "Test"] + length [100 100] + fontStyle USE FS2 + } + } + ] + } + Transform2D { + scale 0.8 0.8 + translation 0 -160 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Horizontal Rectangles are 100x80 pixels" "Vertical Rectangles are 80x100 pixels" "Length is set to longest dimension of the rectangle"] + fontStyle USE FS + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-maxextend.bt b/regression_tests/bifs/bifs-text-maxextend.bt new file mode 100644 index 0000000..ded22fd --- /dev/null +++ b/regression_tests/bifs/bifs-text-maxextend.bt @@ -0,0 +1,176 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 350 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text with and without max Extent" "All texts use the same font and size" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Text maxExtend Test" + } + Shape { + geometry IndexedLineSet2D { + coord Coordinate2D { + point [0 200 0 -160] + } + } + } + Transform2D { + translation -80 160 + children [ + Shape { + appearance DEF TEXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["maxExtent off"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 80 160 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["maxExtent on"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -80 100 + children [ + DEF SQUARE Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 1 1 0 + filled TRUE + } + } + geometry Rectangle { + size 90 80 + } + } + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Some Text" "to test extent"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 80 100 + children [ + USE SQUARE + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Some Text" "to test extent"] + maxExtent 90 + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -80 -60 + children [ + DEF VSQUARE Shape { + appearance USE APP + geometry Rectangle { + size 80 100 + } + } + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Extent" "Text"] + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 80 -60 + children [ + USE VSQUARE + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Extent" "Text"] + maxExtent 100 + fontStyle FontStyle { + horizontal FALSE + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 0 -180 + children [ + Shape { + appearance USE TEXTAPP + geometry Text { + string ["Horizontal Rectangles: 100x80 pixels" "Vertical Rectangles: 80x100 pixels" "MaxExtent: longest dimension"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-style.bt b/regression_tests/bifs/bifs-text-style.bt new file mode 100644 index 0000000..78df9b4 --- /dev/null +++ b/regression_tests/bifs/bifs-text-style.bt @@ -0,0 +1,184 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 260 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows Text with different styles" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Font Style Test" + } + Transform2D { + translation 0 180 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Plain Text"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation 0 140 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Bold Text"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + style "BOLD" + } + } + } + ] + } + Transform2D { + translation 0 100 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Italic Text"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + style "ITALIC" + } + } + } + ] + } + Transform2D { + translation 0 60 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Bold Italic Text"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + style "BOLDITALIC" + } + } + } + ] + } + Transform2D { + translation 0 20 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Underlined Text"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + style "UNDERLINED" + } + } + } + ] + } + Transform2D { + translation 0 -20 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Underlined Italic Text"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + style "ITALIC UNDERLINED" + } + } + } + ] + } + Transform2D { + translation 0 -60 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Underlined Bold Text"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + style "BOLD UNDERLINED" + } + } + } + ] + } + Transform2D { + translation 0 -100 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Underlined Bold" "Italic Text"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + style "BOLDITALIC UNDERLINED" + } + } + } + ] + } + Transform2D { + translation 0 -160 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Strikeout Text" "(Not Normative)"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 20 + style "STRIKEOUT" + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-unicode.bt b/regression_tests/bifs/bifs-text-unicode.bt new file mode 100644 index 0000000..2d05891 --- /dev/null +++ b/regression_tests/bifs/bifs-text-unicode.bt @@ -0,0 +1,55 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 260 + pixelHeight 450 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows non ASCII Text characters" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "Font Style Test" + } + Transform2D { + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Non-Ansi:" "" "é à è ù ü ä ë ï ö ü ÿ" "" "" "XML escapes:" "" "& ' \\" > <"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 26 + } + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-text-vrml-alignment.bt b/regression_tests/bifs/bifs-text-vrml-alignment.bt new file mode 100644 index 0000000..d4ed40e --- /dev/null +++ b/regression_tests/bifs/bifs-text-vrml-alignment.bt @@ -0,0 +1,161 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 1 + visualProfileLevelIndication 1 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSv2Config { + isCommandStream true + pixelMetric true + pixelWidth 480 + pixelHeight 360 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows VRML text basline alignment" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "VRML Text alignmentSRT importing Test" + } + Transform2D { + translation -200 150 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Conformance Test"] + fontStyle FontStyle { + family ["Courier"] + justify ["BEGIN" "MIDDLE"] + size 15 + style "BOLD" + } + } + } + ] + } + Transform2D { + translation -200 40 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Sample from VRML 97 Spec (Section 6.20.1)" "FontStyle Parameters:" " family \"Courier\"" " size 20" " spacing 1.5" " justify [ \"BEGIN\" \"FIRST\" ]" "Text Position is (0,0)" "Thin lines are drawn at Y = 20, Y = -10, Y =-40." "Thick lines are drawn at Y = 0, Y = -30, Y =-60." "According to VRML, thick lines should match baseline."] + fontStyle FontStyle { + family ["Courier"] + justify ["BEGIN" "MIDDLE"] + size 15 + } + } + } + ] + } + Transform2D { + translation -215 -80 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Text { + string ["(0,0)"] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 15 + } + } + } + ] + } + Transform2D { + translation -200 -80 + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + width 2 + } + } + } + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1 4 5 -1] + coord Coordinate2D { + point [0 0 400 0 0 -30 400 -30 0 -60 400 -60] + } + } + } + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties {} + + } + } + geometry IndexedLineSet2D { + coordIndex [0 1 -1 2 3 -1 4 5 -1 6 7 -1 8 9 -1] + coord Coordinate2D { + point [0 20 400 20 0 -10 400 -10 0 -40 400 -40 0 20 0 -60 400 20 400 -60] + } + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Text { + string ["This is a line of text." "This is the 2nd line of text." "This is the third."] + fontStyle FontStyle { + family ["Courier"] + justify ["BEGIN" "FIRST"] + size 20 + spacing 1.5 + } + } + } + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Circle { + radius 2 + } + } + ] + } + ] +} + + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-OCR.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-OCR.bt new file mode 100644 index 0000000..9248d82 --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-OCR.bt @@ -0,0 +1,245 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 400 + pixelHeight 400 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows media streams synchronized to an empty OCR stream" "and mediaControl controling the OCR playback" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Animation Stream" + } + Transform2D { + translation 0 160 + children [ + Shape { + appearance DEF TXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Click on video to switch streams"] + fontStyle DEF TXTFT FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 16 + } + } + } + ] + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF MT MovieTexture { + url [od:12] + } + } + geometry Bitmap {} + + } + DEF TS TouchSensor {} + ] + } + Transform2D { + translation -120 -160 + children [ + Shape { + appearance Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 40 20 + } + } + Shape { + appearance USE TXTAPP + geometry DEF TXT Text { + string ["Stop"] + fontStyle USE TXTFT + } + } + DEF TS2 TouchSensor {} + ] + } + Transform2D { + translation 40 -160 + children [ + Transform2D { + translation -30 0 + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["OCR Time:"] + fontStyle USE TXTFT + } + } + ] + } + Transform2D { + translation 60 0 + children [ + Shape { + appearance USE TXTAPP + geometry DEF OCR_TIME Text { + string ["Stop"] + fontStyle USE TXTFT + } + } + ] + } + ] + } + Transform2D { + translation 40 -180 + children [ + Transform2D { + translation -30 0 + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["OCR Duration:"] + fontStyle USE TXTFT + } + } + ] + } + Transform2D { + translation 60 0 + children [ + Shape { + appearance USE TXTAPP + geometry DEF OCR_DUR Text { + string ["Stop"] + fontStyle USE TXTFT + } + } + ] + } + ] + } + DEF C Conditional { + buffer { + REPLACE MT.url BY ["od:12"] + REPLACE ROUTE R1 BY TS.isActive TO RC.activate + } + } + DEF RC Conditional { + buffer { + REPLACE MT.url BY ["od:10"] + REPLACE ROUTE R1 BY TS.isActive TO C.activate + } + } + DEF MC MediaControl { + url [od:8] + loop TRUE + preRoll FALSE + } + DEF MS MediaSensor { + url [od:8] + } + DEF VMS Valuator {} + DEF VMS2 Valuator {} + DEF C2 Conditional { + buffer { + REPLACE MC.mediaSpeed BY 0 + REPLACE TXT.string BY ["Play"] + REPLACE ROUTE R2 BY TS2.isActive TO RC2.activate + } + } + DEF RC2 Conditional { + buffer { + REPLACE MC.mediaSpeed BY 1 + REPLACE TXT.string BY ["Stop"] + REPLACE ROUTE R2 BY TS2.isActive TO C2.activate + } + } + ] +} + +DEF R1 ROUTE TS.isActive TO C.activate +DEF R2 ROUTE TS2.isActive TO C2.activate +ROUTE MS.mediaCurrentTime TO VMS.inSFTime +ROUTE VMS.outMFString TO OCR_TIME.string +ROUTE MS.mediaDuration TO VMS2.inSFTime +ROUTE VMS2.outMFString TO OCR_DUR.string + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 8 + OCR_ES_ID 8 + decConfigDescr DecoderConfigDescriptor { + objectTypeIndication 1 + streamType 2 + } + muxInfo MuxInfo { + duration 10000 + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 5 + OCR_ES_ID 8 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 12 + esDescr [ + ES_Descriptor { + ES_ID 4 + OCR_ES_ID 8 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-audio-speed.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-audio-speed.bt new file mode 100644 index 0000000..a4174a9 --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-audio-speed.bt @@ -0,0 +1,214 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows MediaControl" "controling audio playback speed" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + Sound2D { + source AudioSource { + url [od:10] + stopTime -1 + numChan 2 + } + } + DEF MC MediaControl { + url [od:10] + loop TRUE + } + Transform2D { + translation -100 0 + children [ + DEF TS1 TouchSensor {} + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Circle { + radius 30 + } + } + Transform2D { + children [ + Shape { + appearance DEF TXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT_FAST Text { + string ["Faster" "x 2"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] + } + Transform2D { + translation 100 0 + children [ + DEF TS2 TouchSensor {} + Shape { + appearance Appearance { + material DEF M2 Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Circle { + radius 30 + } + } + Transform2D { + children [ + Shape { + appearance USE TXTAPP + geometry DEF TXT_SLOW Text { + string ["Slower" "x 0.5"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + children [ + DEF TS3 TouchSensor {} + Shape { + appearance Appearance { + material DEF M3 Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 30 + } + } + Transform2D { + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["Mute"] + fontStyle USE FS + } + } + ] + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE MC.mediaSpeed BY 2 + REPLACE TXT_FAST.string BY ["Faster", "x 2"] + REPLACE M1.emissiveColor BY 1 0.5 0.5 + } + } + DEF AC1 Conditional { + buffer { + REPLACE MC.mediaSpeed BY 4 + REPLACE TXT_FAST.string BY ["Faster", "x 4"] + REPLACE M1.emissiveColor BY 1 0.5 0.5 + } + } + DEF C2 Conditional { + buffer { + REPLACE MC.mediaSpeed BY 0.5 + REPLACE TXT_SLOW.string BY ["Slower", "x 0.5"] + REPLACE M2.emissiveColor BY 0.5 0.5 1 + } + } + DEF AC2 Conditional { + buffer { + REPLACE MC.mediaSpeed BY 0.25 + REPLACE TXT_SLOW.string BY ["Slower", "x 0.25"] + REPLACE M2.emissiveColor BY 0.5 0.5 1 + } + } + DEF C3 Conditional { + buffer { + REPLACE MC.mute BY TRUE + REPLACE M3.emissiveColor BY 0.5 1 0.5 + } + } + DEF RESET Conditional { + buffer { + REPLACE MC.mediaSpeed BY 1 + REPLACE MC.mute BY FALSE + REPLACE M1.emissiveColor BY 1 0 0 + REPLACE M2.emissiveColor BY 0 0 1 + REPLACE M3.emissiveColor BY 0 1 0 + } + } + ] +} + +ROUTE TS1.isOver TO C1.activate +ROUTE TS1.isOver TO RESET.reverseActivate +ROUTE TS1.isActive TO AC1.activate +ROUTE TS1.isActive TO C1.reverseActivate +ROUTE TS2.isOver TO C2.activate +ROUTE TS2.isOver TO RESET.reverseActivate +ROUTE TS2.isActive TO AC2.activate +ROUTE TS2.isActive TO C2.reverseActivate +ROUTE TS3.isOver TO C3.activate +ROUTE TS3.isOver TO RESET.reverseActivate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_english.mp3" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-audio.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-audio.bt new file mode 100644 index 0000000..655edbc --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-audio.bt @@ -0,0 +1,352 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows complex scripting and MediaControl" "providing complete control of the media" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + Sound2D { + source AudioSource { + url [od:10] + stopTime -1 + } + } + DEF MC MediaControl { + url [od:10] + preRoll FALSE + } + DEF MS MediaSensor { + url [od:10] + } + DEF PANEL Transform2D { + translation 0 80 + children [ + DEF TRPAUSE Transform2D { + translation -100 0 + children [ + DEF PAUSE TouchSensor {} + DEF WHICHBUT Switch { + whichChoice 0 + choice [ + Shape { + appearance DEF BUTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] + } + } + } + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coord Coordinate2D { + point [-8 7.5 -8 -7.5 5 0] + } + } + } + ] + } + ] + } + DEF TRSTOP Transform2D { + translation -60 0 + children [ + DEF STOP TouchSensor {} + Shape { + appearance USE BUTAPP + geometry Rectangle { + size 15 15 + } + } + ] + } + DEF TRFF Transform2D { + translation -20 0 + children [ + DEF FASTF TouchSensor {} + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] + } + } + } + ] + } + DEF TRLOOP Transform2D { + translation 20 0 + children [ + DEF LOOP TouchSensor {} + Shape { + appearance Appearance { + material DEF MAT_LOOP Material2D { + emissiveColor 0 0 0 + } + } + geometry Circle { + radius 6 + } + } + ] + } + Transform2D { + translation 0 -160 + children [ + DEF TS TouchSensor {} + Transform2D { + children [ + Shape { + appearance USE BUTAPP + geometry DEF PROGBAR Rectangle { + size 200 15 + } + } + ] + } + DEF CURS Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + width 4 + } + } + } + geometry Rectangle { + size 6 15 + } + } + ] + } + ] + } + DEF TIMER Transform2D { + translation 80 0 + children [ + DEF RTIME TouchSensor {} + Shape { + appearance USE BUTAPP + geometry DEF TIME Text { + string [""] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] + } + DEF SC Script { + eventIn SFTime set_cursor + eventIn SFVec3f set_seek + eventIn SFBool restart + eventIn SFBool rev_time + eventIn SFBool pause + eventIn SFBool stop + eventIn SFBool set_loop + eventIn SFBool set_ff + eventIn SFTime set_duration + field SFNode loop USE MAT_LOOP + field SFNode app USE CURS + field SFNode ctrl USE MC + field SFNode bar USE PROGBAR + field SFNode txt USE TIME + field SFNode but USE WHICHBUT + field SFNode pan USE PANEL + field SFTime curSeek 0 + field SFInt32 isDown 0 + field SFBool reverse FALSE + field SFBool isPaused FALSE + field SFBool isLooping FALSE + field SFTime duration -1 + eventOut SFFloat fraction_changed + url ["javascript: + function set_duration(value, timestamp) { + duration = value; + } + function set_loop(value, timestamp) { + if (!value) return; + isLooping = !isLooping; + loop.filled = isLooping; + ctrl.loop = isLooping; + } + function pause(value, timestamp) { + if (!value) return; + if (isPaused) { + ctrl.mediaSpeed = 1; + but.whichChoice = 0; + } else { + ctrl.mediaSpeed = 0; + but.whichChoice = 1; + ctrl.mediaStartTime = -1; + } + isPaused = !isPaused; + } + function stop(value, timestamp) { + if (!value) return; + txt.string[0] = ''; + app.translation.x = - bar.size.x / 2; + ctrl.mediaStartTime = 0; + ctrl.mediaSpeed = 0; + but.whichChoice = 1; + isPaused = 1; + } + function rev_time(value, timestamp) { + if (value) reverse = !reverse; + } + function set_time(value, timestamp) { + timing = new String(''); + if (duration>=0) { + if (!isLooping && value + 0.1 >=duration) { + stop(true, timestamp); + return; + } + } + if (isPaused) return; + if (duration>=0 && reverse) { + value = duration - value; + if (value<0) value=0; + timing += '-'; + } else { + timing += ' '; + } + hours = 0;mins = 0;secs = 0; + if (value) { + hours = Math.floor(value/3600); + value -= hours*3600; + mins = Math.floor(value / 60); + value -= mins*60; + secs = Math.floor(value); + } + if (hours<10) timing += '0'; + timing += hours + ':'; + if (mins<10) timing += '0'; + timing += mins + ':'; + if (secs<10) timing += '0'; + timing += secs; + txt.string[0] = timing; + } + function set_cursor(value, timestamp) { + set_time(value, timestamp); + if (duration<0) return; + if (ctrl.mediaSpeed && isDown != 1) { + if (value>duration) value = duration; + pos = value; + pos /= duration; + app.translation.x = bar.size.x * (pos - 0.5); + fraction_changed = pos; + } + } + function set_seek(myval, timestamp) { + if (duration<0) return; + pos = myval[0]; + pos /= bar.size.x; + pos += 0.5; + if (pos>1) pos = 0; + curSeek = duration; + curSeek *= pos; + if (isDown == 1) { + app.translation.x = bar.size.x*(pos - 0.5); + } else if (isDown==2) { + isDown = 0; + } + } + function restart(myval, timestamp) { + if (myval) { + ctrl.mediaSpeed = 0; + isDown = 1; + } else if (isDown == 1) { + ctrl.mediaStartTime = curSeek; + ctrl.mediaSpeed = 1; + isDown = 2; + but.whichChoice = 0; + isPaused = FALSE; + } + } + function set_ff(value, timestamp) { + ctrl.mediaStartTime = -1; + if (value) { + ctrl.mediaSpeed = 2; + } else { + ctrl.mediaSpeed = 1; + } + } + " ] + } + ] +} + +ROUTE MS.mediaCurrentTime TO SC.set_cursor +ROUTE TS.hitPoint_changed TO SC.set_seek +ROUTE TS.isActive TO SC.restart +ROUTE RTIME.isActive TO SC.rev_time +ROUTE PAUSE.isActive TO SC.pause +ROUTE STOP.isActive TO SC.stop +ROUTE LOOP.isActive TO SC.set_loop +ROUTE FASTF.isActive TO SC.set_ff +ROUTE MS.mediaDuration TO SC.set_duration +ROUTE FASTF.isActive TO SC.set_ff + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_audio.aac" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-complete.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-complete.bt new file mode 100644 index 0000000..c0ea099 --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-complete.bt @@ -0,0 +1,266 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 240 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows complex scripting and MediaControl" "providing complete control of the media" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF MT MovieTexture { + url [od:8] + } + } + geometry Bitmap {} + + } + ] + } + Sound2D { + source AudioSource { + url [od:10] + stopTime -1 + } + } + DEF MC MediaControl { + url [od:10] + preRoll FALSE + } + DEF MS MediaSensor { + url [od:8] + } + DEF PANEL Transform2D { + translation 0 85 + children [ + DEF TRPAUSE Transform2D { + translation -100 0 + children [ + DEF PAUSE TouchSensor {} + DEF WHICHBUT Switch { + whichChoice 0 + choice [ + Shape { + appearance DEF BUTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] + } + } + } + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coord Coordinate2D { + point [-8 7.5 -8 -7.5 5 0] + } + } + } + ] + } + ] + } + DEF TRSTOP Transform2D { + translation -60 0 + children [ + DEF STOP TouchSensor {} + Shape { + appearance USE BUTAPP + geometry Rectangle { + size 15 15 + } + } + ] + } + DEF TRFF Transform2D { + translation -20 0 + children [ + DEF FASTF TouchSensor {} + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] + } + } + } + ] + } + DEF TRLOOP Transform2D { + translation 20 0 + children [ + DEF LOOP TouchSensor {} + Shape { + appearance Appearance { + material DEF MAT_LOOP Material2D { + emissiveColor 0 0 0 + } + } + geometry Circle { + radius 6 + } + } + ] + } + Transform2D { + translation 0 -170 + children [ + DEF TS TouchSensor {} + Transform2D { + children [ + Shape { + appearance USE BUTAPP + geometry DEF PROGBAR Rectangle { + size 200 15 + } + } + ] + } + DEF CURS Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + width 4 + } + } + } + geometry Rectangle { + size 6 15 + } + } + ] + } + ] + } + DEF TIMER Transform2D { + translation 80 0 + children [ + DEF RTIME TouchSensor {} + Shape { + appearance USE BUTAPP + geometry DEF TIME Text { + string [""] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] + } + DEF SC Script { + eventIn SFTime set_cursor + eventIn SFVec3f set_seek + eventIn SFBool restart + eventIn SFBool rev_time + eventIn SFBool pause + eventIn SFBool stop + eventIn SFBool set_loop + eventIn SFBool set_ff + eventIn SFTime set_duration + field SFNode loop USE MAT_LOOP + field SFNode app USE CURS + field SFNode ctrl USE MC + field SFNode bar USE PROGBAR + field SFNode txt USE TIME + field SFNode but USE WHICHBUT + field SFNode pan USE PANEL + field SFTime curSeek 0 + field SFInt32 isDown 0 + field SFBool reverse FALSE + field SFBool isPaused FALSE + field SFBool isLooping FALSE + field SFTime duration -1 + eventOut SFFloat fraction_changed + url ["javascript:function set_duration(value, timestamp) {duration = value;}function set_loop(value, timestamp) {if (!value) return;isLooping = !isLooping;loop.filled = isLooping;ctrl.loop = isLooping;}function pause(value, timestamp) {if (!value) return;if (isPaused) {ctrl.mediaSpeed = 1;but.whichChoice = 0;} else {ctrl.mediaSpeed = 0;but.whichChoice = 1;ctrl.mediaStartTime = -1;}isPaused = !isPaused;}function stop(value, timestamp) {if (!value) return;txt.string[0] = '';app.translation.x = - bar.size.x / 2;ctrl.mediaStartTime = 0;ctrl.mediaSpeed = 0;but.whichChoice = 1;isPaused = 1;}function rev_time(value, timestamp) {if (value) reverse = !reverse;}function set_time(value, timestamp) {timing = new String('');if (duration>=0) { if (!isLooping && value + 0.1 >=duration) {stop(true, timestamp);return;}}if (isPaused) return;if (duration>=0 && reverse) {value = duration - value;if (value<0) value=0;timing += '-';} else {timing += ' ';}hours = 0;mins = 0;secs = 0;if (value) {hours = Math.floor(value/3600);value -= hours*3600;mins = Math.floor(value / 60);value -= mins*60;secs = Math.floor(value);}if (hours<10) timing += '0';timing += hours + ':';if (mins<10) timing += '0';timing += mins + ':';if (secs<10) timing += '0';timing += secs;txt.string[0] = timing;}function set_cursor(value, timestamp) {set_time(value, timestamp);if (duration<0) return;if (ctrl.mediaSpeed && isDown != 1) {if (value>duration) value = duration;pos = value;pos /= duration;app.translation.x = bar.size.x * (pos - 0.5);fraction_changed = pos;} }function set_seek(myval, timestamp) {if (duration<0) return;pos = myval[0]; pos /= bar.size.x;pos += 0.5;if (pos>1) pos = 0;curSeek = duration;curSeek *= pos;if (isDown == 1) {app.translation.x = bar.size.x*(pos - 0.5);} else if (isDown==2) {isDown = 0;}}function restart(myval, timestamp) {if (myval) {ctrl.mediaSpeed = 0;isDown = 1;} else if (isDown == 1) {ctrl.mediaStartTime = curSeek;ctrl.mediaSpeed = 1;isDown = 2;but.whichChoice = 0;isPaused = FALSE;}}function set_ff(value, timestamp) {ctrl.mediaStartTime = -1;if (value) {ctrl.mediaSpeed = 4;} else {ctrl.mediaSpeed = 1;}}" ] + } + ] +} + +ROUTE MS.mediaCurrentTime TO SC.set_cursor +ROUTE TS.hitPoint_changed TO SC.set_seek +ROUTE TS.isActive TO SC.restart +ROUTE RTIME.isActive TO SC.rev_time +ROUTE PAUSE.isActive TO SC.pause +ROUTE STOP.isActive TO SC.stop +ROUTE LOOP.isActive TO SC.set_loop +ROUTE FASTF.isActive TO SC.set_ff +ROUTE MS.mediaDuration TO SC.set_duration +ROUTE FASTF.isActive TO SC.set_ff + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 21 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_audio.aac" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-deactivation.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-deactivation.bt new file mode 100644 index 0000000..6a47b08 --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-deactivation.bt @@ -0,0 +1,105 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 240 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows MediaControl and mediaSensor" "used to watch deactivation of a node" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF MT MovieTexture { + url [od:8] + } + } + geometry Bitmap {} + + } + DEF TS TouchSensor {} + ] + } + DEF MC MediaControl { + url [od:8] + mediaStartTime 2 + mediaStopTime 4 + preRoll FALSE + } + DEF MS MediaSensor { + url [od:8] + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + string [""] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + DEF V Valuator {} + ] +} + +ROUTE MS.isActive TO V.inSFBool +ROUTE V.outMFString TO TXT.string + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 21 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-inline-av.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-inline-av.bt new file mode 100644 index 0000000..203defd --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-inline-av.bt @@ -0,0 +1,96 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + OCR_ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + title "Simple Audio-video scene" + info [ + "This simple scene contains an audio stream and a video stream." + "It is used by other regression tests." + "" + "GPAC Regression Tests" + "$Date: 2007-07-31 13:12:35 $ - $Revision: 1.4 $" + "(C) 2002-2004 GPAC Team" + ] + } + Background2D {} + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF MT MovieTexture { + url [od:8] + } + } + geometry Bitmap {} + + } + ] + } + Sound2D { + source AudioSource { + url [od:10] + stopTime -1 + } + } + ] +} + + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 1 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_audio.aac" + } + } + ] + } + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 21 + OCR_ES_ID 1 + muxInfo MuxInfo { + fileName "../auxiliary_files/enst_video.h264" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-inline-segments.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-inline-segments.bt new file mode 100644 index 0000000..95f8f35 --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-inline-segments.bt @@ -0,0 +1,66 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + OCR_ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + objectTypeIndication 1 + streamType 3 + decSpecificInfo BIFSConfig { + nodeIDbits 10 + routeIDbits 10 + isCommandStream true + pixelMetric true + pixelWidth 600 + pixelHeight 400 + } + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows inline scene with segments" "and mediaControl on each of the inline segments" "" "GPAC Regression Tests" "$Date: 2008-08-21 17:05:41 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] + title "MediaControl and Inline" + } + Inline { + url ["bifs-timeline-mediacontrol-seg-inline.mp4"] + } + MediaSensor { + url ["bifs-timeline-mediacontrol-seg-inline.mp4"] + } + MediaControl { + url ["bifs-timeline-mediacontrol-seg-inline.mp4#red" "bifs-timeline-mediacontrol-seg-inline.mp4#blue" "bifs-timeline-mediacontrol-seg-inline.mp4#green"] + loop TRUE + } + Transform2D { + translation 0 -100 + children [ + Shape { + appearance Appearance { + material Material2D { + filled TRUE + emissiveColor 0 0 0 + } + } + geometry Text { + string ["Colors should alternate between" "red, blue and green in order"] + fontStyle FontStyle { + justify ["MIDDLE"] + size 30 + } + } + } + ] + } + + ] +} + + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-inline.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-inline.bt new file mode 100644 index 0000000..626b49b --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-inline.bt @@ -0,0 +1,231 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 240 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows complex scripting and MediaControl" "providing complete control of an inline scene" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + Inline { + url [od:8] + } + DEF MC MediaControl { + url [od:8] + preRoll FALSE + } + DEF MS MediaSensor { + url [od:8] + } + DEF PANEL Transform2D { + translation 0 80 + children [ + DEF TRPAUSE Transform2D { + translation -100 0 + children [ + DEF PAUSE TouchSensor {} + DEF WHICHBUT Switch { + whichChoice 0 + choice [ + Shape { + appearance DEF BUTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] + } + } + } + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coord Coordinate2D { + point [-8 7.5 -8 -7.5 5 0] + } + } + } + ] + } + ] + } + DEF TRSTOP Transform2D { + translation -60 0 + children [ + DEF STOP TouchSensor {} + Shape { + appearance USE BUTAPP + geometry Rectangle { + size 15 15 + } + } + ] + } + DEF TRFF Transform2D { + translation -20 0 + children [ + DEF FASTF TouchSensor {} + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] + } + } + } + ] + } + DEF TRLOOP Transform2D { + translation 20 0 + children [ + DEF LOOP TouchSensor {} + Shape { + appearance Appearance { + material DEF MAT_LOOP Material2D { + emissiveColor 0 0 0 + } + } + geometry Circle { + radius 6 + } + } + ] + } + Transform2D { + translation 0 -160 + children [ + DEF TS TouchSensor {} + Transform2D { + children [ + Shape { + appearance USE BUTAPP + geometry DEF PROGBAR Rectangle { + size 200 15 + } + } + ] + } + DEF CURS Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + width 4 + } + } + } + geometry Rectangle { + size 6 15 + } + } + ] + } + ] + } + DEF TIMER Transform2D { + translation 80 0 + children [ + DEF RTIME TouchSensor {} + Shape { + appearance USE BUTAPP + geometry DEF TIME Text { + string [""] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] + } + DEF SC Script { + eventIn SFTime set_cursor + eventIn SFVec3f set_seek + eventIn SFBool restart + eventIn SFBool rev_time + eventIn SFBool pause + eventIn SFBool stop + eventIn SFBool set_loop + eventIn SFBool set_ff + eventIn SFTime set_duration + field SFNode loop USE MAT_LOOP + field SFNode app USE CURS + field SFNode ctrl USE MC + field SFNode bar USE PROGBAR + field SFNode txt USE TIME + field SFNode but USE WHICHBUT + field SFNode pan USE PANEL + field SFTime curSeek 0 + field SFInt32 isDown 0 + field SFBool reverse FALSE + field SFBool isPaused FALSE + field SFBool isLooping FALSE + field SFTime duration -1 + field SFBool reset_startTime FALSE + eventOut SFFloat fraction_changed + url ["javascript:function set_duration(value, timestamp) {duration = value;}function set_loop(value, timestamp) {if (!value) return;isLooping = !isLooping;loop.filled = isLooping;ctrl.loop = isLooping;}function pause(value, timestamp) {if (!value) return;if (isPaused) {ctrl.mediaSpeed = 1;but.whichChoice = 0;if (ctrl.mediaStartTime == 0) reset_startTime = TRUE;} else {ctrl.mediaSpeed = 0;but.whichChoice = 1;ctrl.mediaStartTime = -1;}isPaused = !isPaused;}function stop(value, timestamp) {if (!value || isPaused) return;txt.string[0] = '';app.translation.x = - bar.size.x / 2;ctrl.mediaStartTime = 0;ctrl.mediaSpeed = 0;but.whichChoice = 1;isPaused = 1;}function rev_time(value, timestamp) {if (value) reverse = !reverse;}function set_time(value, timestamp) {timing = new String('');if (isPaused) return;if (duration>=0) { if (value + 0.1 >=duration) {if (!isLooping) {stop(true, timestamp);} else {ctrl.mediaStartTime = 0;reset_startTime = TRUE;}return;}}if (reset_startTime) {ctrl.mediaStartTime = -1;reset_startTime = FALSE;}if (duration>=0 && reverse) {value = duration - value;if (value<0) value=0;timing += '-';} else {timing += ' ';}hours = 0;mins = 0;secs = 0;if (value) {hours = Math.floor(value/3600);value -= hours*3600;mins = Math.floor(value / 60);value -= mins*60;secs = Math.floor(value);}if (hours<10) timing += '0';timing += hours + ':';if (mins<10) timing += '0';timing += mins + ':';if (secs<10) timing += '0';timing += secs;txt.string[0] = timing;}function set_cursor(value, timestamp) {set_time(value, timestamp);if (duration<0) return;if (ctrl.mediaSpeed && isDown != 1) {if (value>duration) value = duration;pos = value;pos /= duration;app.translation.x = bar.size.x * (pos - 0.5);fraction_changed = pos;} }function set_seek(myval, timestamp) {if (duration<0) return;pos = myval[0]; pos /= bar.size.x;pos += 0.5;if (pos>1) pos = 0;curSeek = duration;curSeek *= pos;if (isDown == 1) {app.translation.x = bar.size.x*(pos - 0.5);} else if (isDown==2) {isDown = 0;}}function restart(myval, timestamp) {if (myval) {ctrl.mediaSpeed = 0;isDown = 1;} else if (isDown == 1) {ctrl.mediaStartTime = curSeek;ctrl.mediaSpeed = 1;isDown = 2;but.whichChoice = 0;isPaused = FALSE;}}function set_ff(value, timestamp) {ctrl.mediaStartTime = -1;if (value) {ctrl.mediaSpeed = 8;} else {ctrl.mediaSpeed = 1;}}" ] + } + ] +} + +ROUTE MS.mediaCurrentTime TO SC.set_cursor +ROUTE TS.hitPoint_changed TO SC.set_seek +ROUTE TS.isActive TO SC.restart +ROUTE RTIME.isActive TO SC.rev_time +ROUTE PAUSE.isActive TO SC.pause +ROUTE STOP.isActive TO SC.stop +ROUTE LOOP.isActive TO SC.set_loop +ROUTE FASTF.isActive TO SC.set_ff +ROUTE MS.mediaDuration TO SC.set_duration +ROUTE FASTF.isActive TO SC.set_ff + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + URLstring "bifs-timeline-mediacontrol-inline-av.mp4" + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-rtsp.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-rtsp.bt new file mode 100644 index 0000000..c0a157c --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-rtsp.bt @@ -0,0 +1,340 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 320 + pixelHeight 220 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows complex scripting and MediaControl" "providing complete control of an inline scene" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + Inline { + url [od:8] + } + DEF MC MediaControl { + url [od:8] + preRoll FALSE + } + DEF MS MediaSensor { + url [od:8] + } + DEF PANEL Transform2D { + translation 0 100 + children [ + DEF TRPAUSE Transform2D { + translation -100 0 + children [ + DEF PAUSE TouchSensor {} + DEF WHICHBUT Switch { + whichChoice 0 + choice [ + Shape { + appearance DEF BUTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] + } + } + } + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coord Coordinate2D { + point [-8 7.5 -8 -7.5 5 0] + } + } + } + ] + } + ] + } + DEF TRSTOP Transform2D { + translation -60 0 + children [ + DEF STOP TouchSensor {} + Shape { + appearance USE BUTAPP + geometry Rectangle { + size 15 15 + } + } + ] + } + DEF TRFF Transform2D { + translation -20 0 + children [ + DEF FASTF TouchSensor {} + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] + } + } + } + ] + } + DEF TRLOOP Transform2D { + translation 20 0 + children [ + DEF LOOP TouchSensor {} + Shape { + appearance Appearance { + material DEF MAT_LOOP Material2D { + emissiveColor 0 0 0 + } + } + geometry Circle { + radius 6 + } + } + ] + } + Transform2D { + translation 0 -200 + children [ + DEF TS TouchSensor {} + Transform2D { + children [ + Shape { + appearance USE BUTAPP + geometry DEF PROGBAR Rectangle { + size 200 15 + } + } + ] + } + DEF CURS Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + width 4 + } + } + } + geometry Rectangle { + size 6 15 + } + } + ] + } + ] + } + DEF TIMER Transform2D { + translation 80 0 + children [ + DEF RTIME TouchSensor {} + Shape { + appearance USE BUTAPP + geometry DEF TIME Text { + string [""] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] + } + DEF SC Script { + eventIn SFTime set_cursor + eventIn SFVec3f set_seek + eventIn SFBool restart + eventIn SFBool rev_time + eventIn SFBool pause + eventIn SFBool stop + eventIn SFBool set_loop + eventIn SFBool set_ff + eventIn SFTime set_duration + field SFNode loop USE MAT_LOOP + field SFNode app USE CURS + field SFNode ctrl USE MC + field SFNode bar USE PROGBAR + field SFNode txt USE TIME + field SFNode but USE WHICHBUT + field SFNode pan USE PANEL + field SFTime curSeek 0 + field SFInt32 isDown 0 + field SFBool reverse FALSE + field SFBool isPaused FALSE + field SFBool isLooping FALSE + field SFTime duration -1 + field SFBool reset_startTime FALSE + eventOut SFFloat fraction_changed + url ["javascript: + function set_duration(value, timestamp) { + duration = value; + } + function set_loop(value, timestamp) { + if (!value) return; + isLooping = !isLooping; + loop.filled = isLooping; + ctrl.loop = isLooping; + } + function pause(value, timestamp) { + if (!value) return; + if (isPaused) { + ctrl.mediaSpeed = 1; + but.whichChoice = 0; + if (ctrl.mediaStartTime == 0) reset_startTime = TRUE; + } else { + ctrl.mediaSpeed = 0; + but.whichChoice = 1; + ctrl.mediaStartTime = -1; + } + isPaused = !isPaused; + } + function stop(value, timestamp) { + if (!value || isPaused) return; + txt.string[0] = ''; + app.translation.x = - bar.size.x / 2; + ctrl.mediaStartTime = 0; + ctrl.mediaSpeed = 0; + but.whichChoice = 1; + isPaused = 1; + } + function rev_time(value, timestamp) {if (value) reverse = !reverse;} + function set_time(value, timestamp) { + timing = new String(''); + if (isPaused) return; + if (duration>=0.1) { + if (value + 0.1 >=duration) { + if (!isLooping) { + stop(true, timestamp); + } else { + ctrl.mediaStartTime = 0; + reset_startTime = TRUE; + } + return; + } + } + if (reset_startTime) { + ctrl.mediaStartTime = -1; + reset_startTime = FALSE; + } + if (duration>=0 && reverse) { + value = duration - value; + if (value<0) value=0; + timing += '-'; + } else { + timing += ' '; + } + hours = 0; + mins = 0; + secs = 0; + if (value) { + hours = Math.floor(value/3600);value -= hours*3600;mins = Math.floor(value / 60); + value -= mins*60;secs = Math.floor(value); + } + if (hours<10) timing += '0';timing += hours + ':';if (mins<10) timing += '0';timing += mins + ':';if (secs<10) timing += '0';timing += secs;txt.string[0] = timing; + } + function set_cursor(value, timestamp) { + set_time(value, timestamp); + if (duration<0) return; + if (ctrl.mediaSpeed && isDown != 1) { + if (value>duration) value = duration; + pos = value; + pos /= duration; + app.translation.x = bar.size.x * (pos - 0.5);fraction_changed = pos; + } + } + function set_seek(myval, timestamp) { + if (duration<0) return; + pos = myval[0]; + pos /= bar.size.x;pos += 0.5; + if (pos>1) pos = 0; + curSeek = duration; + curSeek *= pos; + if (isDown == 1) { + app.translation.x = bar.size.x*(pos - 0.5); + } else if (isDown==2) {isDown = 0;} + } + function restart(myval, timestamp) { + if (myval) { + ctrl.mediaSpeed = 0; + isDown = 1; + } else if (isDown == 1) { + ctrl.mediaStartTime = curSeek; + ctrl.mediaSpeed = 1; + isDown = 2; + but.whichChoice = 0; + isPaused = FALSE; + } + } + function set_ff(value, timestamp) { + ctrl.mediaStartTime = -1; + if (value) { + ctrl.mediaSpeed = 8; + } else { + ctrl.mediaSpeed = 1; + } + } + " + ] + } + ] +} + +ROUTE MS.mediaCurrentTime TO SC.set_cursor +ROUTE TS.hitPoint_changed TO SC.set_seek +ROUTE TS.isActive TO SC.restart +ROUTE RTIME.isActive TO SC.rev_time +ROUTE PAUSE.isActive TO SC.pause +ROUTE STOP.isActive TO SC.stop +ROUTE LOOP.isActive TO SC.set_loop +ROUTE FASTF.isActive TO SC.set_ff +ROUTE MS.mediaDuration TO SC.set_duration +ROUTE FASTF.isActive TO SC.set_ff + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + URLstring "rtsp://a1749.q.kamai.net/7/1749/1416/3c964c64/neo.qtv.apple.com/secure/may/preview/civ3_700.mp4" + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-seg-inline.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-seg-inline.bt new file mode 100644 index 0000000..1d8ff78 --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-seg-inline.bt @@ -0,0 +1,81 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 254 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 254 + graphicsProfileLevelIndication 254 + ODProfileLevelIndication 254 + includeInlineProfileLevelFlag true + esDescr [ + ES_Descriptor { + ES_ID 5 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 576 + pixelHeight 432 + } + } + } + ] + ociDescr [ + SegmentDescriptor { + startTime 0 + duration 3 + name "red" + } + SegmentDescriptor { + startTime 3 + duration 3 + name "green" + } + SegmentDescriptor { + startTime 6 + duration 3 + name "blue" + } + ] +} + +OrderedGroup { + children [ + WorldInfo { + title "Simple BIFS stream with chapters" + info [ + "This simple scene contains a BIFS stream with the definition of 3 segments." + "It is used by other regression tests." + "" + "GPAC Regression Tests" + "$Date: 2007-07-31 13:12:35 $ - $Revision: 1.3 $" + "(C) 2002-2004 GPAC Team" + ] + } + Shape { + appearance Appearance { + material DEF M Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Rectangle { + size 200 100 + } + } + ] +} + + +AT 3000 { + REPLACE M.emissiveColor BY 0 1 0 +} + +AT 6000 { + REPLACE M.emissiveColor BY 0 0 1 +} + +AT 9000 { + REPLACE M.emissiveColor BY 0 0 1 +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-segments.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-segments.bt new file mode 100644 index 0000000..14fa42f --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-segments.bt @@ -0,0 +1,154 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 240 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows chapter selection" "through segment switching in MediaControl" "" "GPAC Regression Tests" "$Date: 2008-08-28 16:17:57 $ - $Revision: 1.4 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF MT MovieTexture { + url [od:8] + } + } + geometry Bitmap {} + + } + DEF TS TouchSensor {} + ] + } +#if 0 + Sound2D { + source DEF ASRC AudioSource { + url [od:10] + } + } +#endif + DEF MC MediaControl { + url ["od:8#Begin" "od:8#End"] + loop TRUE + preRoll FALSE + } + DEF MS MediaSensor { + url [od:8] + } + Transform2D { + translation 0 -80 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + string [""] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + DEF V Valuator {} + DEF C Conditional { + buffer { + REPLACE MC.url BY ["od:8#Middle"] + } + } + DEF RC Conditional { + buffer { + REPLACE MC.url BY ["od:8#Begin" "od:8#End"] + } + } + ] +} + +ROUTE MS.mediaCurrentTime TO V.inSFTime +ROUTE V.outMFString TO TXT.string +ROUTE TS.isOver TO C.activate +ROUTE TS.isOver TO RC.reverseActivate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 21 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + ociDescr [ + SegmentDescriptor { + startTime 0 + duration 4 + name "Begin" + } + SegmentDescriptor { + startTime 4 + duration 2 + name "Middle" + } + SegmentDescriptor { + startTime 6 + duration 4 + name "End" + } + ] + } +#if 0 + ObjectDescriptor { + objectDescriptorID 10 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_english.mp3" + } + } + ] + } +#endif + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-video.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-video.bt new file mode 100644 index 0000000..edbe93c --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-video.bt @@ -0,0 +1,258 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 240 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows complete control of media" "through scripting and MediaControl" "" "GPAC Regression Tests" "$Date: 2009-12-07 13:19:33 $ - $Revision: 1.5 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + Transform2D { + children [ + Shape { + appearance Appearance { + texture DEF MT MovieTexture { + url [od:8] + } + } + geometry Bitmap {} + + } + ] + } + DEF MC MediaControl { + url [od:8] + preRoll FALSE + } + DEF MS MediaSensor { + url [od:8] + } + DEF PANEL Transform2D { + translation 0 80 + children [ + DEF TRPAUSE Transform2D { + translation -100 0 + children [ + DEF PAUSE TouchSensor {} + DEF WHICHBUT Switch { + whichChoice 0 + choice [ + Shape { + appearance DEF BUTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -3 7.5 -3 -7.5 -8 -7.5 0 7.5 5 7.5 5 -7.5 0 -7.5] + } + } + } + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coord Coordinate2D { + point [-8 7.5 -8 -7.5 5 0] + } + } + } + ] + } + ] + } + DEF TRSTOP Transform2D { + translation -60 0 + children [ + DEF STOP TouchSensor {} + Shape { + appearance USE BUTAPP + geometry Rectangle { + size 15 15 + } + } + ] + } + DEF TRFF Transform2D { + translation -20 0 + children [ + DEF FASTF TouchSensor {} + Shape { + appearance USE BUTAPP + geometry IndexedFaceSet2D { + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 4 5 6 7 -1] + coord Coordinate2D { + point [-8 7.5 -5 0 -8 -7.5 2 0 -2 7.5 1 0 -2 -7.5 8 0] + } + } + } + ] + } + DEF TRLOOP Transform2D { + translation 20 0 + children [ + DEF LOOP TouchSensor {} + Shape { + appearance Appearance { + material DEF MAT_LOOP Material2D { + emissiveColor 0 0 0 + } + } + geometry Circle { + radius 6 + } + } + ] + } + Transform2D { + translation 0 -160 + children [ + DEF TS TouchSensor {} + Transform2D { + children [ + Shape { + appearance USE BUTAPP + geometry DEF PROGBAR Rectangle { + size 200 15 + } + } + ] + } + DEF CURS Transform2D { + children [ + Shape { + appearance Appearance { + material Material2D { + lineProps LineProperties { + lineColor 0 0 1 + width 4 + } + } + } + geometry Rectangle { + size 6 15 + } + } + ] + } + ] + } + DEF TIMER Transform2D { + translation 80 0 + children [ + DEF RTIME TouchSensor {} + Shape { + appearance USE BUTAPP + geometry DEF TIME Text { + string [""] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] + } + DEF SC Script { + eventIn SFTime set_cursor + eventIn SFVec3f set_seek + eventIn SFBool restart + eventIn SFBool rev_time + eventIn SFBool pause + eventIn SFBool stop + eventIn SFBool set_loop + eventIn SFBool set_ff + eventIn SFTime set_duration + field SFNode loop USE MAT_LOOP + field SFNode app USE CURS + field SFNode ctrl USE MC + field SFNode bar USE PROGBAR + field SFNode txt USE TIME + field SFNode but USE WHICHBUT + field SFNode pan USE PANEL + field SFTime curSeek 0 + field SFInt32 isDown 0 + field SFBool reverse FALSE + field SFBool isPaused FALSE + field SFBool isLooping FALSE + field SFTime duration -1 + eventOut SFFloat fraction_changed + url ["javascript: +function set_duration(value, timestamp) {duration = value;} +function set_loop(value, timestamp) {if (!value) return;isLooping = !isLooping;loop.filled = isLooping;ctrl.loop = isLooping;} +function pause(value, timestamp) {if (!value) return;if (isPaused) {ctrl.mediaSpeed = 1;but.whichChoice = 0;} else {ctrl.mediaSpeed = 0;but.whichChoice = 1;ctrl.mediaStartTime = -1;}isPaused = !isPaused;} +function stop(value, timestamp) {if (!value) return;txt.string[0] = '';app.translation.x = - bar.size.x / 2;ctrl.mediaStartTime = 0;ctrl.mediaSpeed = 0;but.whichChoice = 1;isPaused = 1;} +function rev_time(value, timestamp) {if (value) reverse = !reverse;} +function set_time(value, timestamp) {timing = new String('');if (duration>=0) { if (!isLooping && value + 0.1 >=duration) {stop(true, timestamp);print('script stop ' + value + ' ' + duration);return;}}if (isPaused) return;if (duration>=0 && reverse) {value = duration - value;if (value<0) value=0;timing += '-';} else {timing += ' ';}hours = 0;mins = 0;secs = 0;if (value) {hours = Math.floor(value/3600);value -= hours*3600;mins = Math.floor(value / 60);value -= mins*60;secs = Math.floor(value);}if (hours<10) timing += '0';timing += hours + ':';if (mins<10) timing += '0';timing += mins + ':';if (secs<10) timing += '0';timing += secs;txt.string[0] = timing;} +function set_cursor(value, timestamp) {set_time(value, timestamp); if (duration<0) return;if (ctrl.mediaSpeed && isDown != 1) {if (value>duration) value = duration;pos = value;pos /= duration;app.translation.x = bar.size.x * (pos - 0.5);fraction_changed = pos;} } +function set_seek(myval, timestamp) {if (duration<0) return;pos = myval[0]; pos /= bar.size.x;pos += 0.5;if (pos>1) pos = 0;curSeek = duration;curSeek *= pos;if (isDown == 1) {app.translation.x = bar.size.x*(pos - 0.5);} else if (isDown==2) {isDown = 0;}} +function restart(myval, timestamp) {if (myval) {ctrl.mediaSpeed = 0;isDown = 1;} else if (isDown == 1) {ctrl.mediaStartTime = curSeek;ctrl.mediaSpeed = 1;isDown = 2;but.whichChoice = 0;isPaused = FALSE;}} +function set_ff(value, timestamp) {ctrl.mediaStartTime = -1;if (value) {ctrl.mediaSpeed = 4;} else {ctrl.mediaSpeed = 1;}}" ] + } + ] +} + +ROUTE MS.mediaCurrentTime TO SC.set_cursor +ROUTE TS.hitPoint_changed TO SC.set_seek +ROUTE TS.isActive TO SC.restart +ROUTE RTIME.isActive TO SC.rev_time +ROUTE PAUSE.isActive TO SC.pause +ROUTE STOP.isActive TO SC.stop +ROUTE LOOP.isActive TO SC.set_loop +ROUTE FASTF.isActive TO SC.set_ff +ROUTE MS.mediaDuration TO SC.set_duration +ROUTE FASTF.isActive TO SC.set_ff + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 21 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediacontrol-videospeed.bt b/regression_tests/bifs/bifs-timeline-mediacontrol-videospeed.bt new file mode 100644 index 0000000..b440fc7 --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediacontrol-videospeed.bt @@ -0,0 +1,202 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 200 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows MediaControl" "controling video playback speed" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Control Test" + } + DEF MC MediaControl { + url [od:8] + loop TRUE + } + Transform2D { + translation -100 -65 + children [ + DEF TS1 TouchSensor {} + Shape { + appearance Appearance { + material DEF M1 Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry Circle { + radius 30 + } + } + Transform2D { + children [ + Shape { + appearance DEF TXTAPP Appearance { + material Material2D { + emissiveColor 0 0 0 + filled TRUE + } + } + geometry Text { + string ["Speed" "x4"] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 18 + } + } + } + ] + } + ] + } + Transform2D { + translation 100 -65 + children [ + DEF TS2 TouchSensor {} + Shape { + appearance Appearance { + material DEF M2 Material2D { + emissiveColor 0 0 1 + filled TRUE + } + } + geometry Circle { + radius 30 + } + } + Transform2D { + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["Speed" "x0.5"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 -65 + children [ + DEF TS3 TouchSensor {} + Shape { + appearance Appearance { + material DEF M3 Material2D { + emissiveColor 0 1 0 + filled TRUE + } + } + geometry Circle { + radius 30 + } + } + Transform2D { + children [ + Shape { + appearance USE TXTAPP + geometry Text { + string ["Mute"] + fontStyle USE FS + } + } + ] + } + ] + } + Transform2D { + translation 0 30 + children [ + Shape { + appearance Appearance { + texture MovieTexture { + url [od:8] + } + } + geometry Bitmap {} + + } + ] + } + DEF C1 Conditional { + buffer { + REPLACE MC.mediaSpeed BY 4 + REPLACE M1.emissiveColor BY 1 0.5 0.5 + } + } + DEF C2 Conditional { + buffer { + REPLACE MC.mediaSpeed BY 0.5 + REPLACE M2.emissiveColor BY 0.5 0.5 1 + } + } + DEF C3 Conditional { + buffer { + REPLACE MC.mute BY TRUE + REPLACE M3.emissiveColor BY 0.5 1 0.5 + } + } + DEF RESET Conditional { + buffer { + REPLACE MC.mediaSpeed BY 1 + REPLACE MC.mute BY FALSE + REPLACE M1.emissiveColor BY 1 0 0 + REPLACE M2.emissiveColor BY 0 0 1 + REPLACE M3.emissiveColor BY 0 1 0 + } + } + ] +} + +ROUTE TS1.isOver TO C1.activate +ROUTE TS1.isOver TO RESET.reverseActivate +ROUTE TS2.isOver TO C2.activate +ROUTE TS2.isOver TO RESET.reverseActivate +ROUTE TS3.isOver TO C3.activate +ROUTE TS3.isOver TO RESET.reverseActivate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 21 + OCR_ES_ID 21 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediasensor-segment-switch.bt b/regression_tests/bifs/bifs-timeline-mediasensor-segment-switch.bt new file mode 100644 index 0000000..6761ac5 --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediasensor-segment-switch.bt @@ -0,0 +1,226 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of MediaSensor" "with media segments defined" "and dynamic changes of watched segments" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Sensor Test #3" + } + Shape { + appearance Appearance { + texture DEF MOV MovieTexture { + loop TRUE + stopTime -1 + url [od:8] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap {} + + } + DEF MS MediaSensor { + url [od:8] + } + DEF MSALL MediaSensor { + url [od:8] + } + DEF VAL Valuator {} + DEF VAL2 Valuator {} + Transform2D { + translation 50 -90 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + string [""] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -50 -90 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Media Time:"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -60 -120 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Segment Start Time:"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 70 -120 + children [ + Shape { + appearance USE APP + geometry DEF START Text { + string [""] + fontStyle USE FS + } + } + ] + } + DEF VAL3 Valuator {} + Transform2D { + translation -50 120 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Segment Name:"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 50 120 + children [ + Shape { + appearance USE APP + geometry DEF NAME Text { + string [""] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -70 90 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Segment Duration: "] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 60 90 + children [ + Shape { + appearance USE APP + geometry DEF TXT2 Text { + string [""] + fontStyle USE FS + } + } + ] + } + DEF S Script { + eventIn SFBool switch_seg + field SFNode ms_node USE MS + field SFInt32 num_seg 0 + url ["javascript:function switch_seg(value, timestamp) {if (value) return;switch (num_seg) {case 0:ms_node.url[0] = '8#End';break;case 1:ms_node.url[0] = '8#Middle';break;case 2:ms_node.url[0] = '8#Begin';break;case 3:ms_node.url = new MFString('8#Begin', '8#Middle');break;case 4:ms_node.url = new MFString('8#Begin', '8#End');break;case 5:ms_node.url = new MFString('8#Middle', '8#End');break;}num_seg++;}" ] + } + DEF C Conditional { + buffer { + REPLACE TXT.string BY [""] + REPLACE TXT2.string BY [""] + REPLACE NAME.string BY [""] + REPLACE START.string BY [""] + } + } + ] +} + +ROUTE MS.mediaCurrentTime TO VAL.inSFTime +ROUTE VAL.outMFString TO TXT.string +ROUTE MS.mediaDuration TO VAL2.inSFTime +ROUTE VAL2.outMFString TO TXT2.string +ROUTE MS.info TO NAME.string +ROUTE MS.streamObjectStartTime TO VAL3.inSFTime +ROUTE VAL3.outMFString TO START.string +ROUTE MS.isActive TO C.reverseActivate +ROUTE MSALL.isActive TO S.switch_seg + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + duration 8930 + } + } + ] + ociDescr [ + SegmentDescriptor { + startTime 0 + duration 4 + name "Begin" + } + SegmentDescriptor { + startTime 4 + duration 2 + name "Middle" + } + SegmentDescriptor { + startTime 6 + duration 4 + name "End" + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediasensor-segment.bt b/regression_tests/bifs/bifs-timeline-mediasensor-segment.bt new file mode 100644 index 0000000..4f090fd --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediasensor-segment.bt @@ -0,0 +1,215 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of MediaSensor" "with media segments defined" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Sensor Test #2" + } + Shape { + appearance Appearance { + texture DEF MOV MovieTexture { + loop TRUE + stopTime -1 + url [od:8] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap {} + + } + DEF MS MediaSensor { + url ["od:8#Begin" "od:8#End"] + } + DEF VAL Valuator {} + DEF VAL2 Valuator {} + Transform2D { + translation 50 -90 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + string [""] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -50 -90 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Media Time:"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -60 -120 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Segment Start Time:"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 70 -120 + children [ + Shape { + appearance USE APP + geometry DEF START Text { + string [""] + fontStyle USE FS + } + } + ] + } + DEF VAL3 Valuator {} + Transform2D { + translation -50 120 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Segment Name:"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 50 120 + children [ + Shape { + appearance USE APP + geometry DEF NAME Text { + string [""] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -70 90 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Segment Duration: "] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 60 90 + children [ + Shape { + appearance USE APP + geometry DEF TXT2 Text { + string [""] + fontStyle USE FS + } + } + ] + } + DEF C Conditional { + buffer { + REPLACE TXT.string BY [""] + REPLACE TXT2.string BY [""] + REPLACE NAME.string BY [""] + REPLACE START.string BY [""] + } + } + ] +} + +ROUTE MS.mediaCurrentTime TO VAL.inSFTime +ROUTE VAL.outMFString TO TXT.string +ROUTE MS.mediaDuration TO VAL2.inSFTime +ROUTE VAL2.outMFString TO TXT2.string +ROUTE MS.info TO NAME.string +ROUTE MS.streamObjectStartTime TO VAL3.inSFTime +ROUTE VAL3.outMFString TO START.string +ROUTE MS.isActive TO C.reverseActivate + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + ociDescr [ + SegmentDescriptor { + startTime 0 + duration 4 + name "Begin" + } + SegmentDescriptor { + startTime 4 + duration 2 + name "Middle" + } + SegmentDescriptor { + startTime 6 + duration 4 + name "End" + } + ] + } + ] +} + diff --git a/regression_tests/bifs/bifs-timeline-mediasensor.bt b/regression_tests/bifs/bifs-timeline-mediasensor.bt new file mode 100644 index 0000000..7054ca5 --- /dev/null +++ b/regression_tests/bifs/bifs-timeline-mediasensor.bt @@ -0,0 +1,137 @@ +InitialObjectDescriptor { + objectDescriptorID 1 + audioProfileLevelIndication 255 + visualProfileLevelIndication 254 + sceneProfileLevelIndication 1 + graphicsProfileLevelIndication 1 + ODProfileLevelIndication 1 + esDescr [ + ES_Descriptor { + ES_ID 1 + decConfigDescr DecoderConfigDescriptor { + streamType 3 + decSpecificInfo BIFSConfig { + isCommandStream true + pixelMetric true + pixelWidth 300 + pixelHeight 300 + } + } + } + ES_Descriptor { + ES_ID 2 + decConfigDescr DecoderConfigDescriptor { + streamType 1 + } + } + ] +} + +OrderedGroup { + children [ + Background2D { + backColor 1 1 1 + } + WorldInfo { + info ["This shows usage of MediaSensor" "without media segments defined" "" "GPAC Regression Tests" "$Date: 2007-07-27 09:46:10 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + title "Media Sensor Test #1" + } + Shape { + appearance Appearance { + texture DEF MOV MovieTexture { + loop TRUE + stopTime -1 + url [od:8] + repeatS FALSE + repeatT FALSE + } + } + geometry Bitmap {} + + } + DEF MS MediaSensor { + url [od:8] + } + DEF VAL Valuator {} + DEF VAL2 Valuator {} + Transform2D { + translation 50 -90 + children [ + Shape { + appearance DEF APP Appearance { + material Material2D { + emissiveColor 1 0 0 + filled TRUE + } + } + geometry DEF TXT Text { + string [""] + fontStyle DEF FS FontStyle { + justify ["MIDDLE" "MIDDLE"] + size 20 + } + } + } + ] + } + Transform2D { + translation -50 -90 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Media Time:"] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation -60 90 + children [ + Shape { + appearance USE APP + geometry Text { + string ["Media Duration: "] + fontStyle USE FS + } + } + ] + } + Transform2D { + translation 60 90 + children [ + Shape { + appearance USE APP + geometry DEF TXT2 Text { + string [""] + fontStyle USE FS + } + } + ] + } + ] +} + +ROUTE MS.mediaCurrentTime TO VAL.inSFTime +ROUTE VAL.outMFString TO TXT.string +ROUTE MS.mediaDuration TO VAL2.inSFTime +ROUTE VAL2.outMFString TO TXT2.string + +AT 0 { + UPDATE OD [ + ObjectDescriptor { + objectDescriptorID 8 + esDescr [ + ES_Descriptor { + ES_ID 20 + OCR_ES_ID 20 + muxInfo MuxInfo { + fileName "../auxiliary_files/count_video.cmp" + } + } + ] + } + ] +} + diff --git a/regression_tests/svg/all_syntaxes_1.1F2.svg b/regression_tests/svg/all_syntaxes_1.1F2.svg new file mode 100644 index 0000000..a04560b --- /dev/null +++ b/regression_tests/svg/all_syntaxes_1.1F2.svg @@ -0,0 +1,498 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg version="1.2" baseProfile="test" + xmlns="http://www.w3.org/2000/svg" + xmlns:ev="http://www.w3.org/2001/xml-events" + xmlns:xlink="http://www.w3.org/1999/xlink" + width="100%" + height="100%" + viewBox="0 0 800 600" + contentScriptType="application/x-myscripttype" + contentStyleType="text/x-mystyletype" + preserveAspectRatio="none" + > + + <g id="MyId" + class="toto" + externalResourcesRequired="true" + requiredExtensions="http://example.org/SomeSVGextensions" + requiredFeatures="SomeSVGFeatureString" + style="aStyle" + xml:base="someurl" + xml:lang="ita" + xml:space="default" + + alignment-baseline="baseline" + baseline-shift="sub" + clip-path="none" + clip-rule="evenodd" + clip="auto" + color-interpolation-filters="sRGB" + color-interpolation="linearRGB" + color-profile="inherit" + color-rendering="optimizeSpeed" + color="inherit" + cursor="crosshair" + direction="ltr" + display="block" + dominant-baseline="use-script" + enable-background="accumulate" + fill-opacity="0.467" + fill-rule="nonzero" + fill="red" + filter="none" + flood-color="currentColor" + flood-opacity="0.5" + font-family="monospace, Times New Roman" + font-size-adjust="none" + font-size="10%" + font-stretch="condensed" + font-style="italic" + font-variant="small-caps" + font-weight="600" + glyph-orientation-horizontal="45" + glyph-orientation-vertical="auto" + image-rendering="optimizeQuality" + kerning="2em" + letter-spacing="2cm" + lighting-color="inherit" + marker-end="none" + marker-mid="inherit" + marker-start="none" + mask="none" + opacity="inherit" + overflow="hidden" + pointer-events="visiblePainted" + shape-rendering="crispEdges" + stop-color="currentColor" + stop-opacity=".9" + stroke-dasharray="30 45 5" + stroke-dashoffset="34%" + stroke-linecap="butt" + stroke-linejoin="miter" + stroke-miterlimit="4" + stroke-opacity="1" + stroke-width="34mm" + stroke="#000" + text-anchor="middle" + text-decoration="line-through" + text-rendering="optimizeLegibility" + unicode-bidi="embed" + visibility="collapse" + word-spacing="34pt" + writing-mode="rl-tb" + /> + + <clipPath clipPathUnits="objectBoundingBox" + /> + + <set to="34" + /> + + <circle cx="4" + cy="1.5" + r="1234.5667" + /> + + <ellipse cx="4" + cy="1.5" + rx="34.5e-34" + rx="-345" + /> + + <marker markerHeight="1234" + markerWidth="6789" + markerUnits="strokeWidth" + orient="auto" + refX=".654654" + refY="12e4" + viewBox="0 0 2 2" + /> + + <view viewTarget="aTargetObject" + zoomAndPan="disable" + /> + + <radialGradient cx="4" + cy="1.5" + fx="0" + fy="0" + r="000.0002" + gradientTransform="translate(0, 0)" + gradientUnits="userSpaceOnUse" + spreadMethod="repeat" + xlink:href="Somref" + /> + + <line x1="45.6" + x2="000" + y1="345" + y2="556" + /> + + <linearGradient gradientTransform="scale(0, 0)" + gradientUnits="objectBoudingBox" + spreadMethod="pad" + xlink:href="Somref" + x1="45.6" + x2="000" + y1="345" + y2="556" + /> + + <hkern g1="name1, name2 , name3" + k="123" + u1="U+0045, U+0067, U+0-7FFFFFFF" + /> + + <vkern g2="name1, name2 , name3" + u2="U+0-7FFFFFFF, U+0045, U+0067" + /> + + <path d="M100,0L300,5z" + pathLength="34.56" + /> + + <font horiz-adv-x="323" + horiz-orig-x="456" + horiz-orig-y="789" + vert-adv-y="323" + vert-orig-x="456" + vert-orig-y="789" + + /> + + <font-face-name name="MyFont" + /> + + <font-face-uri xlink:href="Someref" + /> + + <font-face-format string="aFontFormat" + /> + + <font-face accent-height="100" + font-family="Arial, serif" + font-style="all" + font-variant="normal" + font-weight="all" + font-stretch="all" + font-size="all" + unicode-range="U+0-7FFFFFFF, U+0-7FFFFFFF" + units-per-em="2048" + panose-1="0 1 2 3 4 5 6 7 8 9" + stemv="100" + stemh="100" + slope="50" + cap-height="20" + x-height="60" + ascent="50" + descent="100" + alphabetic="0" + bbox="10, 0, 30, 100" + hanging="450" + ideographic="123" + mathematical="456" + overline-position="123" + overline-thickness="6578" + strikethrough-position="345" + strikethrough-thickness="900" + underline-position="12" + underline-thickness="9840" + v-alphabetic="42" + v-hanging="342" + v-ideographic="890" + v-mathematical="54657" + widths="U+0-7FFFFFFF 0 0 0, U+0-7FFFFFFF 0 0 0" + /> + + <animate xlink:href="Somref" + attributeName="width" + begin="2" + by="10" + calcMode="discrete" + attributeType="XML" + accumulate="none" + additive="replace" + dur="indefinite" + end="indefinite" + fill="freeze" + from="0" + keySplines="0 0 0 0 0" + keyTimes="0 0 0 0 0" + max="10" + min="12" + repeatCount="indefinite" + repeatDur="124" + restart="always" + to="345" + /> + + <animateTransform type="translate" + values="0,0 34.56 78 4535 677" + /> + + <style media="print" + title="aTitle" + type="text/css" + /> + + <textPath method="align" + spacing="exact" + startOffset="432" + textLength="-0" + xlink:href="Somref" + /> + + <animateMotion keyPoints="0,0 0" + origin="default" + path="z" + rotate="auto-reverse" + /> + + <glyph glyph-name="name1, name2, name3" + arabic-form="initial" + d="M100,0L300,5z" + horiz-adv-x="340" + lang="fre" + orientation="h" + unicode="ffl" + vert-adv-y="323" + vert-orig-x="456" + vert-orig-y="789" + /> + + <missing-glyph d="M100,0L300,5z" + /> + + <altGlyph xlink:actuate="onRequest" + xlink:show="SomeWord" + xlink:href="someref" + string="ttttt" + dx="100 0 0 0 0 0" + dy="-2 4" + format="MyFormat" + rotate="0 0 0 0 34.5" + x="213" + y="213" + /> + + <cursor x="213" + y="213" + xlink:href="someref" + /> + + <glyphRef x="0.0" + y="0.0" + string="xxxxxx" + dx="100" + format="embedded-opentype" + xlink:href="Somref" + /> + + <text lengthAdjust="spacing" + dx="100 4 5 6" + dy="0 0 3" + rotate="0 0 0 " + textLength="2134" + x="0 0 0 0" + y="0 0" + /> + + <tspan dx="100 4 5 6" + /> + + <tref xlink:href="Somref" + x="45" + y="5" + dy="4 5 6 7" + rotate="324 54356 6757.78 21" + /> + + <filter filterRes="40 0" + filterUnits="userSpaceOnUse" + height="300" + primitiveUnits="objectBoundingBox" + width="345" + x="0987654.76543e2" + y="76543e2" + xlink:href="someref" + /> + + <foreignObject height="30" + width="345" + x="456.654e-2" + y="-2" + /> + + <image x="345" + y="134" + height="100" + width="345" + xlink:href="Somref" + /> + + <use height="50" + width="345" + x="0.0" + y="0.0" + xlink:href="Somref" + /> + + <rect height="30" + rx="3432.67" + ry="0" + width="345" + x="34" + y="45" + /> + + <pattern x="1234567" + x="23234567" + height="100" + patternUnits="objectBoundingBox" + patternContentUnits="userSpaceOnUse" + patternTransform="skewX(50)" + /> + + <polygon points="0 0 0 0" + /> + + <polyline points=".0 0. 0.0 0000.00000" + /> + + <feFuncA amplitude="100" + slope="000" + tableValues="4 5 6 7 8" + /> + + <feFuncB exponent="100" + type="identity" + /> + + <feFuncG intercept="100" + /> + + <feFuncR offset="14" + /> + + <feDistantLight azimuth="100" + /> + + <feTurbulence baseFrequency="100 , 100" + numOctaves="3" + seed="546788" + stitchTiles="noStitch" + type="fractalNoise" + /> + + <script type="application/ecmascript" + xlink:href="Somref" + /> + + <stop offset="2%" + /> + + <feConvolveMatrix bias="100" + divisor="3" + edgeMode="duplicate" + kernelMatrix="123 54356 76576 879" + kernelUnitLength="12 434" + order="12 0" + preserveAlpha="false" + targetX="0" + targetY="1" + /> + + <feDiffuseLighting diffuseConstant="1e2" + kernelUnitLength="0 0" + surfaceScale="4536.788" + /> + + <feSpecularLighting kernelUnitLength="0 0" + specularConstant="3.14" + specularExponent="0.1235689" + surfaceScale="+0.0" + /> + + <a xlink:actuate="onRequest" + xlink:arcrole="SomeRole" + xlink:role="SomeRole" + xlink:title="SomeTitle" + xlink:type="SomeType" + xlink:show="SomeWord" + xlink:href="someref" + systemLanguage="eng" + target="_replace" + transform="matrix(0,0,0,0,0,0)" + /> + + <feOffset dx="5" + /> + + <feBlend x="456.789" + y="456.789" + height="400" + width="345" + in="SourceGraphic" + in2="SourceAlpha" + mode="normal" + result="AFilterReference" + /> + + <feComposite in2="BackgroundImage" + k1="25" + k2="54647" + k3="1.34325" + k4="-1245.0987E12" + operator="over" + /> + + <feImage xlink:href="someref" + /> + + <feDisplacementMap in2="BackgroundAlpha" + scale="4324234" + xChannelSelector="R" + yChannelSelector="G" + /> + + <feMorphology operator="erode" + radius="2313.5567" + /> + + <feSpotLight limitingConeAngle="1234" + pointsAtX="324.566" + pointsAtY="1324.566" + pointsAtZ="3524.566" + specularExponent="0.1235689" + x="345.678932" + y="678932" + z="434" + /> + + <fePointLight x="043245" + y="245" + z="5" + /> + + <feGaussianBlur stdDeviation="344 5566" + /> + + <feColorMatrix type="saturate" + values="0 345.56 -34.667" + /> + + <color-profile local="AnICCUniqueID" + xlink:href="someref" + name="aColorName" + rendering-intent="auto" + /> + + <mask x="3456" + x="7890" + height="340" + width="345" + maskContentUnits="userSpaceOnUse" + maskUnits="objectBoundingBox" + /> +</svg> diff --git a/regression_tests/svg/createanim-by-script.svg b/regression_tests/svg/createanim-by-script.svg new file mode 100644 index 0000000..0618c57 --- /dev/null +++ b/regression_tests/svg/createanim-by-script.svg @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" + width="100%" height="100%" viewBox="0 0 800 600" > + <rect id="Ranimate" x="100" y="100" width="100" height="50" fill="blue"/> + <rect id="Rset" x="100" y="160" width="100" height="50" fill="blue"/> + <rect id="RanimateTransform" x="100" y="220" width="100" height="50" fill="blue"/> + <rect id="RanimateMotion" x="100" y="280" width="100" height="50" fill="blue"/> + <rect id="RanimateColor" x="100" y="340" width="100" height="50" fill="blue"/> + <!--path id="aMotionPath" d="M0,0L400,0"/--> + <script> +<![CDATA[ + var svgNS = "http://www.w3.org/2000/svg"; + var xlinkNS = "http://www.w3.org/1999/xlink"; + + var rect = document.getElementById("Ranimate"); + var animate = document.createElementNS(svgNS, "animate"); + animate.setAttribute("begin", "2"); + animate.setAttribute("attributeName", "width"); + animate.setAttribute("from", "100"); + animate.setAttribute("to", "500"); + animate.setAttribute("dur", "2"); + animate.setAttribute("fill", "freeze"); + rect.appendChild(animate); + + var rect = document.getElementById("Rset"); + var set = document.createElementNS(svgNS, "set"); + set.setAttribute("begin", "2"); + set.setAttribute("attributeName", "width"); + set.setAttribute("to", "500"); + set.setAttribute("dur", "2"); + set.setAttribute("fill", "freeze"); + rect.appendChild(set); + + var rect = document.getElementById("RanimateTransform"); + var aT = document.createElementNS(svgNS, "animateTransform"); + aT.setAttribute("begin", "2"); + aT.setAttribute("attributeName", "transform"); + aT.setAttribute("type", "translate"); + aT.setAttribute("from", "0,0"); + aT.setAttribute("to", "400,0"); + aT.setAttribute("dur", "2"); + aT.setAttribute("fill", "freeze"); + rect.appendChild(aT); + + var rect = document.getElementById("RanimateMotion"); + var aM = document.createElementNS(svgNS, "animateMotion"); + aM.setAttribute("begin", "2"); + aM.setAttribute("dur", "2"); + aM.setAttribute("fill", "freeze"); + + var path = document.createElementNS(svgNS, "path"); + path.setAttribute("d","M0,0L400,0"); + path.setAttribute("id", "aMotionPath"); + document.documentElement.appendChild(path); + + var mpath = document.createElementNS(svgNS, "mpath"); + mpath.setAttributeNS(xlinkNS, "href", "#aMotionPath"); + aM.appendChild(mpath); + + rect.appendChild(aM); + + var rect = document.getElementById("RanimateColor"); + var aC = document.createElementNS(svgNS, "animateColor"); + aC.setAttribute("begin", "2"); + aC.setAttribute("attributeName", "fill"); + aC.setAttribute("dur", "2"); + aC.setAttribute("fill", "freeze"); + aC.setAttribute("to", "red"); + rect.appendChild(aC); + + ]]> + </script> +</svg> diff --git a/regression_tests/svg/createimage-by-script.svg b/regression_tests/svg/createimage-by-script.svg new file mode 100644 index 0000000..7ddec45 --- /dev/null +++ b/regression_tests/svg/createimage-by-script.svg @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<svg version="1.2" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" + width="100%" height="100%" viewBox="0 0 800 600" > + <script> +<![CDATA[ + var svgNS = "http://www.w3.org/2000/svg"; + var xlinkNS = "http://www.w3.org/1999/xlink"; + + var image = document.createElementNS(svgNS, "image"); + image.setAttribute("width", "100"); + image.setAttribute("height", "100"); + image.setAttributeNS(xlinkNS, "href", "http://www.telecom-paristech.fr/fileadmin/maquette/images/logo-haut-droit.png"); + document.documentElement.appendChild(image); + ]]> + </script> +</svg> diff --git a/regression_tests/svg/utfscript.svg b/regression_tests/svg/utfscript.svg new file mode 100644 index 0000000..7849941 --- /dev/null +++ b/regression_tests/svg/utfscript.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- SVG Scene Dump - GPAC version 0.4.5-DEV (build 32) --> +<svg id="svg-root" version="1.1" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewport-fill="#CC3B38" font-family="Arial" > + <text id="from" x="5" y="10">Léa</text> + <text id="to" x="5" y="40"></text> + <script> +<![CDATA[ + from = document.getElementById('from'); +// alert('from: '+from.textContent); + to = document.getElementById('to'); + to.textContent = from.textContent; +// alert('to: '+to.textContent); + ]]> + </script> +</svg> diff --git a/regression_tests/utfscript.svg b/regression_tests/utfscript.svg new file mode 100644 index 0000000..7849941 --- /dev/null +++ b/regression_tests/utfscript.svg @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- SVG Scene Dump - GPAC version 0.4.5-DEV (build 32) --> +<svg id="svg-root" version="1.1" baseProfile="tiny" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewport-fill="#CC3B38" font-family="Arial" > + <text id="from" x="5" y="10">Léa</text> + <text id="to" x="5" y="40"></text> + <script> +<![CDATA[ + from = document.getElementById('from'); +// alert('from: '+from.textContent); + to = document.getElementById('to'); + to.textContent = from.textContent; +// alert('to: '+to.textContent); + ]]> + </script> +</svg> diff --git a/regression_tests/x3d-2D-Arc2d.x3dv b/regression_tests/x3d-2D-Arc2d.x3dv deleted file mode 100644 index 3ef3961..0000000 --- a/regression_tests/x3d-2D-Arc2d.x3dv +++ /dev/null @@ -1,23 +0,0 @@ -#X3D V3.0 - -Group { - children [ - WorldInfo { - title "Arc2D X3D test" - info ["This shows an Arc2D" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Arc2D { - radius 1 - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-2D-ArcClose2d.x3dv b/regression_tests/x3d-2D-ArcClose2d.x3dv deleted file mode 100644 index 80d3ee5..0000000 --- a/regression_tests/x3d-2D-ArcClose2d.x3dv +++ /dev/null @@ -1,24 +0,0 @@ -#X3D V3.0 - -Group { - children [ - WorldInfo { - title "ArcClose2D X3D test" - info ["This shows a ArcClose2D" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry ArcClose2D { - radius 1 - closureType "CHORD" - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-2D-Disk2d.x3dv b/regression_tests/x3d-2D-Disk2d.x3dv deleted file mode 100644 index 6ef901e..0000000 --- a/regression_tests/x3d-2D-Disk2d.x3dv +++ /dev/null @@ -1,24 +0,0 @@ -#X3D V3.0 - -Group { - children [ - WorldInfo { - title "Disk2D X3D test" - info ["This shows a a Disk2D" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Disk2D { - outerRadius 1 - innerRadius 0.4 - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-2D-Polyline2d.x3dv b/regression_tests/x3d-2D-Polyline2d.x3dv deleted file mode 100644 index 39d8584..0000000 --- a/regression_tests/x3d-2D-Polyline2d.x3dv +++ /dev/null @@ -1,23 +0,0 @@ -#X3D V3.0 - -Group { - children [ - WorldInfo { - title "Polyline2D X3D test" - info ["This shows a Polyline2D" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Polyline2D { - lineSegments [0 0, 0.2 0.2, 0.4 0, 0.6 0.2, 0.8 0, 1 0.2] - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-2D-Polypoint2d.x3dv b/regression_tests/x3d-2D-Polypoint2d.x3dv deleted file mode 100644 index 1962c3f..0000000 --- a/regression_tests/x3d-2D-Polypoint2d.x3dv +++ /dev/null @@ -1,23 +0,0 @@ -#X3D V3.0 - -Group { - children [ - WorldInfo { - title "Polypoint2D X3D test" - info ["This shows a Polypoint2D" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry Polypoint2D { - point [0 0, 0.2 0.2, 0.4 0, 0.6 0.2, 0.8 0, 1 0.2] - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-2D-TriangleSet2d.x3dv b/regression_tests/x3d-2D-TriangleSet2d.x3dv deleted file mode 100644 index c208b23..0000000 --- a/regression_tests/x3d-2D-TriangleSet2d.x3dv +++ /dev/null @@ -1,24 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Viewpoint { position 0 0 2} - WorldInfo { - title "TriangleSet2D X3D test" - info ["This shows a TriangleSet2D" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry TriangleSet2D { - vertices [0 0, 0.2 0.2, 0.4 0, 0.6 0.2, 0.8 0, 1 0.2] - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-3D-IndexedTriangleFanSet.x3dv b/regression_tests/x3d-3D-IndexedTriangleFanSet.x3dv deleted file mode 100644 index 608dc9f..0000000 --- a/regression_tests/x3d-3D-IndexedTriangleFanSet.x3dv +++ /dev/null @@ -1,28 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Viewpoint { position 0 0 2} - WorldInfo { - title "IndexedTriangleFanSet X3D test" - info ["This shows a IndexedTriangleFanSet" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry IndexedTriangleFanSet { - color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 1 1 0, 1 1 1] } - coord Coordinate { point [0 0 0, 0 0.5 0, 0.1 0.4 -0.5, 0.2 0.3 0, 0.3 0.2 -0.5, 0.4 0.1 0, 0.5 0 -0.5] } - solid FALSE - ccw FALSE - index [0 1 2 3 -1 0 4 5 6] - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-3D-IndexedTriangleSet.x3dv b/regression_tests/x3d-3D-IndexedTriangleSet.x3dv deleted file mode 100644 index a84eb7a..0000000 --- a/regression_tests/x3d-3D-IndexedTriangleSet.x3dv +++ /dev/null @@ -1,27 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Viewpoint { position 0 0 2} - WorldInfo { - title "IndexedTriangleSet X3D test" - info ["This shows a IndexedTriangleSet" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry IndexedTriangleSet { - color Color { color [1 0 0, 0 1 0, 0 0 1, 0 0 1, 0 1 0, 1 0 0] } - coord Coordinate { point [0 0 0, 0.2 0.2 0.2, 0.4 0 0, 0.6 0.2 0.2, 0.8 0 0, 1 0.2 0.2] } - solid FALSE - index [0 1 2 1 2 3 2 3 4 3 4 5] - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-3D-IndexedTriangleStripSet.x3dv b/regression_tests/x3d-3D-IndexedTriangleStripSet.x3dv deleted file mode 100644 index d0f24ee..0000000 --- a/regression_tests/x3d-3D-IndexedTriangleStripSet.x3dv +++ /dev/null @@ -1,28 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Viewpoint { position 0 0 2} - WorldInfo { - title "IndexedTriangleStripSet X3D test" - info ["This shows a IndexedTriangleStripSet" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry IndexedTriangleStripSet { - color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 0 1 1, 1 1 1, 0.5 0.5 0] } - coord Coordinate { point [0 0 0, 0 0.5 0, 0.3 0 0, 0.3 0.5 -0.5, 0.6 0.0 0, 0.6 0.5 0, 0.6 0.5 -0.5, 0.8 0.0 0] } - solid FALSE - ccw FALSE - index [0 1 2 3 -1 4 5 6 7] - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-3D-LineSet.x3dv b/regression_tests/x3d-3D-LineSet.x3dv deleted file mode 100644 index 23925ec..0000000 --- a/regression_tests/x3d-3D-LineSet.x3dv +++ /dev/null @@ -1,27 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Viewpoint { position 0 0 2} - WorldInfo { - title "LineSet X3D test" - info ["This shows a LineSet" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry LineSet { - color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 1 1 0, 1 1 1] } - coord Coordinate { point [0 0 0, 0 0.5 0, 0.1 0.4 -0.5, 0.2 0.3 0, 0.3 0.2 -0.5, 0.4 0.1 0, 0.5 0 -0.5] } - #vertexCount [7] - vertexCount [3 4] - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-3D-TriangleFanSet.x3dv b/regression_tests/x3d-3D-TriangleFanSet.x3dv deleted file mode 100644 index db2414e..0000000 --- a/regression_tests/x3d-3D-TriangleFanSet.x3dv +++ /dev/null @@ -1,28 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Viewpoint { position 0 0 2} - WorldInfo { - title "TriangleFanSet X3D test" - info ["This shows a TriangleFanSet" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry TriangleFanSet { - fanCount [7] - color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 1 1 0, 1 1 1] } - coord Coordinate { point [0 0 0, 0 0.5 0, 0.1 0.4 -0.5, 0.2 0.3 0, 0.3 0.2 -0.5, 0.4 0.1 0, 0.5 0 -0.5] } - solid FALSE - ccw FALSE - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-3D-TriangleSet.x3dv b/regression_tests/x3d-3D-TriangleSet.x3dv deleted file mode 100644 index 8e415fb..0000000 --- a/regression_tests/x3d-3D-TriangleSet.x3dv +++ /dev/null @@ -1,26 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Viewpoint { position 0 0 2} - WorldInfo { - title "TriangleSet test" - info ["This shows a box" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry TriangleSet { - color Color { color [1 0 0, 0 1 0, 0 0 1, 0 0 1, 0 1 0, 1 0 0] } - coord Coordinate { point [0 0 0, 0.2 0.2 0.2, 0.4 0 0, 0.6 0.2 0.2, 0.8 0 0, 1 0.2 0.2] } - solid FALSE - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-3D-TriangleStripSet.x3dv b/regression_tests/x3d-3D-TriangleStripSet.x3dv deleted file mode 100644 index 7dfbf89..0000000 --- a/regression_tests/x3d-3D-TriangleStripSet.x3dv +++ /dev/null @@ -1,28 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Viewpoint { position 0 0 2} - WorldInfo { - title "TriangleStripSet X3D test" - info ["This shows a TriangleStripSet" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - } - geometry TriangleStripSet { - stripCount [6] - color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 1 1 0] } - coord Coordinate { point [0 0 0, 0 0.5 0, 0.3 0 0, 0.3 0.5 -0.5, 0.6 0.0 0, 0.6 0.5 0] } - solid FALSE - ccw FALSE - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-misc-ColorRGBA.x3dv b/regression_tests/x3d-misc-ColorRGBA.x3dv deleted file mode 100644 index 58b12c4..0000000 --- a/regression_tests/x3d-misc-ColorRGBA.x3dv +++ /dev/null @@ -1,42 +0,0 @@ -#X3D V3.0 - -Group { - children [ - WorldInfo { - info ["This shows IndexedFaceSets" "with RGBA color per vertex" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - title "ColorRGBA X3D Test test" - } - Transform { - translation -1.5 0 0 - children [ - Shape { - geometry IndexedFaceSet { - coordIndex [0 1 2 3 -1 1 7 4 2 -1 7 6 5 4 -1 0 3 5 6 -1 3 2 4 5 -1 6 7 1 0 -1] - color DEF COL ColorRGBA { - color [1 0 0 1, 0 1 0 0.2, 0 0 1 1, 1 1 0 0.5, 1 0 1 0.8, 0 1 1 0.2, 1 0.5 0.5 0.4, 0.5 0.5 1 0.7] - } - coord DEF COORD Coordinate { - point [-1 -1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1 -1 1 -1 -1 -1 -1 1 -1 -1] - } - } - } - ] - } - Transform { - translation 1.5 0 0 - children [ - Shape { - geometry IndexedFaceSet { - colorIndex [0 1 2 3 4 5 6 7] - colorPerVertex FALSE - coordIndex [0 1 2 3 -1 1 7 4 2 -1 7 6 5 4 -1 0 3 5 6 -1 3 2 4 5 -1 6 7 1 0 -1] - color USE COL - coord USE COORD - } - } - ] - } - ] -} - - diff --git a/regression_tests/x3d-misc-HatchStyle.x3dv b/regression_tests/x3d-misc-HatchStyle.x3dv deleted file mode 100644 index cc7503b..0000000 --- a/regression_tests/x3d-misc-HatchStyle.x3dv +++ /dev/null @@ -1,31 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Background2D { backColor 1 1 1} - WorldInfo { - title "HatchStyle X3D test" - info ["This shows a box" "with hatching properties" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] - } - - Transform { - children [ - Shape { - appearance Appearance { - material Material { diffuseColor 1.0 0.0 0.0 } - fillProperties FillProperties { - filled TRUE - hatchStyle 5 - hatchColor 0 0 1 - } - } - geometry Box { - size 1 1 0.5 - bboxCenter 0 0 0 - bboxSize 1 1 1 - } - } - ] - } - ] -} diff --git a/regression_tests/x3d-misc-KeySensor.x3dv b/regression_tests/x3d-misc-KeySensor.x3dv deleted file mode 100644 index 6eb8b4f..0000000 --- a/regression_tests/x3d-misc-KeySensor.x3dv +++ /dev/null @@ -1,73 +0,0 @@ -#X3D V3.0 - -Group { - children [ - Group { - children [ - Group { - children [ - WorldInfo { - info ["This shows usage of X3D KeySensor" "and triggering of events" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2003 ENST"] - title "KeySensor X3D Test" - } - Shape { - appearance Appearance { - material Material { - diffuseColor 1 1 1 - } - } - geometry DEF TEXT Text { - string ["Hit any key", ""] - fontStyle FontStyle { - justify ["MIDDLE" "MIDDLE"] - } - } - } - DEF SC Script { - inputOnly SFString keyUp - inputOnly SFString keyDown - inputOnly SFInt32 sysKeyUp - inputOnly SFInt32 sysKeyDown - inputOnly SFBool altKey - inputOnly SFBool ctrlKey - inputOnly SFBool shiftKey - initializeOnly SFNode txt USE TEXT - url ["javascript: - function keyUp(value) { - txt.string[0] = 'Key up: ' + value; - } - function keyDown(value) { - txt.string[0] = 'Key down: ' + value; - } - function sysKeyUp(value) { - txt.string[0] = 'System Key up: ' + value; - } - function sysKeyDown(value) { - txt.string[0] = 'System Key down: ' + value; - } - function altKey(value) { - txt.string[1] = value ? 'ALT key pressed' : ''; - } - function shiftKey(value) { - txt.string[1] = value ? 'SHIFT key pressed' : ''; - } - function ctrlKey(value) { - txt.string[1] = value ? 'CTRL key pressed' : ''; - } - " - ] - } - DEF KS KeySensor {} - ] - } - ] - } - ] -} -ROUTE KS.keyPress TO SC.keyDown -ROUTE KS.keyRelease TO SC.keyUp -ROUTE KS.actionKeyPress TO SC.sysKeyDown -ROUTE KS.actionKeyRelease TO SC.sysKeyUp -ROUTE KS.altKey TO SC.altKey -ROUTE KS.controlKey TO SC.ctrlKey -ROUTE KS.shiftKey TO SC.shiftKey diff --git a/regression_tests/x3d-misc-StringSensor.x3dv b/regression_tests/x3d-misc-StringSensor.x3dv deleted file mode 100644 index 4c5d099..0000000 --- a/regression_tests/x3d-misc-StringSensor.x3dv +++ /dev/null @@ -1,83 +0,0 @@ -#X3D V3.0 - -Group { - children [ - WorldInfo { - title "StringSensor X3D Test" - info ["This shows usage of X3D StringSensor" "" "GPAC Regression Tests" "$Date: 2007/07/27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002 ENST"] - } - - Transform { - translation 0 1 0 - children [ - Shape { - appearance DEF APP Appearance { - material Material { - diffuseColor 1 1 1 - } - } - geometry Text { - string [ "StringSensor" ] - fontStyle DEF FS FontStyle { - justify [ "MIDDLE" "MIDDLE" ] - } - } - } - ] - } - Transform { - translation -4 -1 0 - children [ - Shape { - appearance USE APP - geometry Text { - string [ "Edit:" ] - fontStyle USE FS - } - } - ] - } - Transform { - translation 1.8 -1 0 - children [ - Shape { - appearance USE APP - geometry DEF N3 Text { - string [""] - fontStyle USE FS - } - } - ] - } - Transform { - translation -4 -2.2 0 - children [ - Shape { - appearance USE APP - geometry Text { - string [ "Final:" ] - fontStyle USE FS - } - } - ] - } - Transform { - translation 1.8 -2.2 0 - children [ - Shape { - appearance USE APP - geometry DEF N2 Text { - string [""] - fontStyle USE FS - } - } - ] - } - DEF STR StringSensor { - } - ] -} - -ROUTE STR.enteredText TO N3.string -ROUTE STR.finalText TO N2.string - diff --git a/regression_tests/x3d/x3d-2D-Arc2d.x3dv b/regression_tests/x3d/x3d-2D-Arc2d.x3dv new file mode 100644 index 0000000..4e2dde2 --- /dev/null +++ b/regression_tests/x3d/x3d-2D-Arc2d.x3dv @@ -0,0 +1,23 @@ +#X3D V3.0 + +Group { + children [ + WorldInfo { + title "Arc2D X3D test" + info ["This shows an Arc2D" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Arc2D { + radius 1 + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-2D-ArcClose2d.x3dv b/regression_tests/x3d/x3d-2D-ArcClose2d.x3dv new file mode 100644 index 0000000..5960250 --- /dev/null +++ b/regression_tests/x3d/x3d-2D-ArcClose2d.x3dv @@ -0,0 +1,24 @@ +#X3D V3.0 + +Group { + children [ + WorldInfo { + title "ArcClose2D X3D test" + info ["This shows a ArcClose2D" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry ArcClose2D { + radius 1 + closureType "CHORD" + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-2D-Disk2d.x3dv b/regression_tests/x3d/x3d-2D-Disk2d.x3dv new file mode 100644 index 0000000..0445a6f --- /dev/null +++ b/regression_tests/x3d/x3d-2D-Disk2d.x3dv @@ -0,0 +1,24 @@ +#X3D V3.0 + +Group { + children [ + WorldInfo { + title "Disk2D X3D test" + info ["This shows a a Disk2D" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Disk2D { + outerRadius 1 + innerRadius 0.4 + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-2D-Polyline2d.x3dv b/regression_tests/x3d/x3d-2D-Polyline2d.x3dv new file mode 100644 index 0000000..3e27e35 --- /dev/null +++ b/regression_tests/x3d/x3d-2D-Polyline2d.x3dv @@ -0,0 +1,23 @@ +#X3D V3.0 + +Group { + children [ + WorldInfo { + title "Polyline2D X3D test" + info ["This shows a Polyline2D" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.3 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Polyline2D { + lineSegments [0 0, 0.2 0.2, 0.4 0, 0.6 0.2, 0.8 0, 1 0.2] + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-2D-Polypoint2d.x3dv b/regression_tests/x3d/x3d-2D-Polypoint2d.x3dv new file mode 100644 index 0000000..9e66f70 --- /dev/null +++ b/regression_tests/x3d/x3d-2D-Polypoint2d.x3dv @@ -0,0 +1,23 @@ +#X3D V3.0 + +Group { + children [ + WorldInfo { + title "Polypoint2D X3D test" + info ["This shows a Polypoint2D" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry Polypoint2D { + point [0 0, 0.2 0.2, 0.4 0, 0.6 0.2, 0.8 0, 1 0.2] + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-2D-TriangleSet2d.x3dv b/regression_tests/x3d/x3d-2D-TriangleSet2d.x3dv new file mode 100644 index 0000000..168e5b3 --- /dev/null +++ b/regression_tests/x3d/x3d-2D-TriangleSet2d.x3dv @@ -0,0 +1,24 @@ +#X3D V3.0 + +Group { + children [ + Viewpoint { position 0 0 2} + WorldInfo { + title "TriangleSet2D X3D test" + info ["This shows a TriangleSet2D" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry TriangleSet2D { + vertices [0 0, 0.2 0.2, 0.4 0, 0.6 0.2, 0.8 0, 1 0.2] + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-3D-IndexedTriangleFanSet.x3dv b/regression_tests/x3d/x3d-3D-IndexedTriangleFanSet.x3dv new file mode 100644 index 0000000..449c534 --- /dev/null +++ b/regression_tests/x3d/x3d-3D-IndexedTriangleFanSet.x3dv @@ -0,0 +1,28 @@ +#X3D V3.0 + +Group { + children [ + Viewpoint { position 0 0 2} + WorldInfo { + title "IndexedTriangleFanSet X3D test" + info ["This shows a IndexedTriangleFanSet" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry IndexedTriangleFanSet { + color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 1 1 0, 1 1 1] } + coord Coordinate { point [0 0 0, 0 0.5 0, 0.1 0.4 -0.5, 0.2 0.3 0, 0.3 0.2 -0.5, 0.4 0.1 0, 0.5 0 -0.5] } + solid FALSE + ccw FALSE + index [0 1 2 3 -1 0 4 5 6] + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-3D-IndexedTriangleSet.x3dv b/regression_tests/x3d/x3d-3D-IndexedTriangleSet.x3dv new file mode 100644 index 0000000..a983865 --- /dev/null +++ b/regression_tests/x3d/x3d-3D-IndexedTriangleSet.x3dv @@ -0,0 +1,27 @@ +#X3D V3.0 + +Group { + children [ + Viewpoint { position 0 0 2} + WorldInfo { + title "IndexedTriangleSet X3D test" + info ["This shows a IndexedTriangleSet" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry IndexedTriangleSet { + color Color { color [1 0 0, 0 1 0, 0 0 1, 0 0 1, 0 1 0, 1 0 0] } + coord Coordinate { point [0 0 0, 0.2 0.2 0.2, 0.4 0 0, 0.6 0.2 0.2, 0.8 0 0, 1 0.2 0.2] } + solid FALSE + index [0 1 2 1 2 3 2 3 4 3 4 5] + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-3D-IndexedTriangleStripSet.x3dv b/regression_tests/x3d/x3d-3D-IndexedTriangleStripSet.x3dv new file mode 100644 index 0000000..581d695 --- /dev/null +++ b/regression_tests/x3d/x3d-3D-IndexedTriangleStripSet.x3dv @@ -0,0 +1,28 @@ +#X3D V3.0 + +Group { + children [ + Viewpoint { position 0 0 2} + WorldInfo { + title "IndexedTriangleStripSet X3D test" + info ["This shows a IndexedTriangleStripSet" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry IndexedTriangleStripSet { + color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 0 1 1, 1 1 1, 0.5 0.5 0] } + coord Coordinate { point [0 0 0, 0 0.5 0, 0.3 0 0, 0.3 0.5 -0.5, 0.6 0.0 0, 0.6 0.5 0, 0.6 0.5 -0.5, 0.8 0.0 0] } + solid FALSE + ccw FALSE + index [0 1 2 3 -1 4 5 6 7] + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-3D-LineSet.x3dv b/regression_tests/x3d/x3d-3D-LineSet.x3dv new file mode 100644 index 0000000..eafd0a4 --- /dev/null +++ b/regression_tests/x3d/x3d-3D-LineSet.x3dv @@ -0,0 +1,27 @@ +#X3D V3.0 + +Group { + children [ + Viewpoint { position 0 0 2} + WorldInfo { + title "LineSet X3D test" + info ["This shows a LineSet" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry LineSet { + color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 1 1 0, 1 1 1] } + coord Coordinate { point [0 0 0, 0 0.5 0, 0.1 0.4 -0.5, 0.2 0.3 0, 0.3 0.2 -0.5, 0.4 0.1 0, 0.5 0 -0.5] } + #vertexCount [7] + vertexCount [3 4] + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-3D-TriangleFanSet.x3dv b/regression_tests/x3d/x3d-3D-TriangleFanSet.x3dv new file mode 100644 index 0000000..59f1a1b --- /dev/null +++ b/regression_tests/x3d/x3d-3D-TriangleFanSet.x3dv @@ -0,0 +1,28 @@ +#X3D V3.0 + +Group { + children [ + Viewpoint { position 0 0 2} + WorldInfo { + title "TriangleFanSet X3D test" + info ["This shows a TriangleFanSet" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry TriangleFanSet { + fanCount [7] + color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 1 1 0, 1 1 1] } + coord Coordinate { point [0 0 0, 0 0.5 0, 0.1 0.4 -0.5, 0.2 0.3 0, 0.3 0.2 -0.5, 0.4 0.1 0, 0.5 0 -0.5] } + solid FALSE + ccw FALSE + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-3D-TriangleSet.x3dv b/regression_tests/x3d/x3d-3D-TriangleSet.x3dv new file mode 100644 index 0000000..8307f63 --- /dev/null +++ b/regression_tests/x3d/x3d-3D-TriangleSet.x3dv @@ -0,0 +1,26 @@ +#X3D V3.0 + +Group { + children [ + Viewpoint { position 0 0 2} + WorldInfo { + title "TriangleSet test" + info ["This shows a box" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry TriangleSet { + color Color { color [1 0 0, 0 1 0, 0 0 1, 0 0 1, 0 1 0, 1 0 0] } + coord Coordinate { point [0 0 0, 0.2 0.2 0.2, 0.4 0 0, 0.6 0.2 0.2, 0.8 0 0, 1 0.2 0.2] } + solid FALSE + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-3D-TriangleStripSet.x3dv b/regression_tests/x3d/x3d-3D-TriangleStripSet.x3dv new file mode 100644 index 0000000..c1de189 --- /dev/null +++ b/regression_tests/x3d/x3d-3D-TriangleStripSet.x3dv @@ -0,0 +1,28 @@ +#X3D V3.0 + +Group { + children [ + Viewpoint { position 0 0 2} + WorldInfo { + title "TriangleStripSet X3D test" + info ["This shows a TriangleStripSet" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + } + geometry TriangleStripSet { + stripCount [6] + color Color { color [1 0 0, 0 1 0, 0 0 1, 1 1 0, 1 0 1, 1 1 0] } + coord Coordinate { point [0 0 0, 0 0.5 0, 0.3 0 0, 0.3 0.5 -0.5, 0.6 0.0 0, 0.6 0.5 0] } + solid FALSE + ccw FALSE + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-misc-ColorRGBA.x3dv b/regression_tests/x3d/x3d-misc-ColorRGBA.x3dv new file mode 100644 index 0000000..20e54b6 --- /dev/null +++ b/regression_tests/x3d/x3d-misc-ColorRGBA.x3dv @@ -0,0 +1,42 @@ +#X3D V3.0 + +Group { + children [ + WorldInfo { + info ["This shows IndexedFaceSets" "with RGBA color per vertex" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + title "ColorRGBA X3D Test test" + } + Transform { + translation -1.5 0 0 + children [ + Shape { + geometry IndexedFaceSet { + coordIndex [0 1 2 3 -1 1 7 4 2 -1 7 6 5 4 -1 0 3 5 6 -1 3 2 4 5 -1 6 7 1 0 -1] + color DEF COL ColorRGBA { + color [1 0 0 1, 0 1 0 0.2, 0 0 1 1, 1 1 0 0.5, 1 0 1 0.8, 0 1 1 0.2, 1 0.5 0.5 0.4, 0.5 0.5 1 0.7] + } + coord DEF COORD Coordinate { + point [-1 -1 1 1 -1 1 1 1 1 -1 1 1 1 1 -1 -1 1 -1 -1 -1 -1 1 -1 -1] + } + } + } + ] + } + Transform { + translation 1.5 0 0 + children [ + Shape { + geometry IndexedFaceSet { + colorIndex [0 1 2 3 4 5 6 7] + colorPerVertex FALSE + coordIndex [0 1 2 3 -1 1 7 4 2 -1 7 6 5 4 -1 0 3 5 6 -1 3 2 4 5 -1 6 7 1 0 -1] + color USE COL + coord USE COORD + } + } + ] + } + ] +} + + diff --git a/regression_tests/x3d/x3d-misc-HatchStyle.x3dv b/regression_tests/x3d/x3d-misc-HatchStyle.x3dv new file mode 100644 index 0000000..c06edb0 --- /dev/null +++ b/regression_tests/x3d/x3d-misc-HatchStyle.x3dv @@ -0,0 +1,31 @@ +#X3D V3.0 + +Group { + children [ + Background2D { backColor 1 1 1} + WorldInfo { + title "HatchStyle X3D test" + info ["This shows a box" "with hatching properties" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2004 GPAC Team"] + } + + Transform { + children [ + Shape { + appearance Appearance { + material Material { diffuseColor 1.0 0.0 0.0 } + fillProperties FillProperties { + filled TRUE + hatchStyle 5 + hatchColor 0 0 1 + } + } + geometry Box { + size 1 1 0.5 + bboxCenter 0 0 0 + bboxSize 1 1 1 + } + } + ] + } + ] +} diff --git a/regression_tests/x3d/x3d-misc-KeySensor.x3dv b/regression_tests/x3d/x3d-misc-KeySensor.x3dv new file mode 100644 index 0000000..8485ae0 --- /dev/null +++ b/regression_tests/x3d/x3d-misc-KeySensor.x3dv @@ -0,0 +1,73 @@ +#X3D V3.0 + +Group { + children [ + Group { + children [ + Group { + children [ + WorldInfo { + info ["This shows usage of X3D KeySensor" "and triggering of events" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002-2003 ENST"] + title "KeySensor X3D Test" + } + Shape { + appearance Appearance { + material Material { + diffuseColor 1 1 1 + } + } + geometry DEF TEXT Text { + string ["Hit any key", ""] + fontStyle FontStyle { + justify ["MIDDLE" "MIDDLE"] + } + } + } + DEF SC Script { + inputOnly SFString keyUp + inputOnly SFString keyDown + inputOnly SFInt32 sysKeyUp + inputOnly SFInt32 sysKeyDown + inputOnly SFBool altKey + inputOnly SFBool ctrlKey + inputOnly SFBool shiftKey + initializeOnly SFNode txt USE TEXT + url ["javascript: + function keyUp(value) { + txt.string[0] = 'Key up: ' + value; + } + function keyDown(value) { + txt.string[0] = 'Key down: ' + value; + } + function sysKeyUp(value) { + txt.string[0] = 'System Key up: ' + value; + } + function sysKeyDown(value) { + txt.string[0] = 'System Key down: ' + value; + } + function altKey(value) { + txt.string[1] = value ? 'ALT key pressed' : ''; + } + function shiftKey(value) { + txt.string[1] = value ? 'SHIFT key pressed' : ''; + } + function ctrlKey(value) { + txt.string[1] = value ? 'CTRL key pressed' : ''; + } + " + ] + } + DEF KS KeySensor {} + ] + } + ] + } + ] +} +ROUTE KS.keyPress TO SC.keyDown +ROUTE KS.keyRelease TO SC.keyUp +ROUTE KS.actionKeyPress TO SC.sysKeyDown +ROUTE KS.actionKeyRelease TO SC.sysKeyUp +ROUTE KS.altKey TO SC.altKey +ROUTE KS.controlKey TO SC.ctrlKey +ROUTE KS.shiftKey TO SC.shiftKey diff --git a/regression_tests/x3d/x3d-misc-StringSensor.x3dv b/regression_tests/x3d/x3d-misc-StringSensor.x3dv new file mode 100644 index 0000000..7d4d924 --- /dev/null +++ b/regression_tests/x3d/x3d-misc-StringSensor.x3dv @@ -0,0 +1,83 @@ +#X3D V3.0 + +Group { + children [ + WorldInfo { + title "StringSensor X3D Test" + info ["This shows usage of X3D StringSensor" "" "GPAC Regression Tests" "$Date: 2007-07-27 11:30:48 $ - $Revision: 1.2 $" "(C) 2002 ENST"] + } + + Transform { + translation 0 1 0 + children [ + Shape { + appearance DEF APP Appearance { + material Material { + diffuseColor 1 1 1 + } + } + geometry Text { + string [ "StringSensor" ] + fontStyle DEF FS FontStyle { + justify [ "MIDDLE" "MIDDLE" ] + } + } + } + ] + } + Transform { + translation -4 -1 0 + children [ + Shape { + appearance USE APP + geometry Text { + string [ "Edit:" ] + fontStyle USE FS + } + } + ] + } + Transform { + translation 1.8 -1 0 + children [ + Shape { + appearance USE APP + geometry DEF N3 Text { + string [""] + fontStyle USE FS + } + } + ] + } + Transform { + translation -4 -2.2 0 + children [ + Shape { + appearance USE APP + geometry Text { + string [ "Final:" ] + fontStyle USE FS + } + } + ] + } + Transform { + translation 1.8 -2.2 0 + children [ + Shape { + appearance USE APP + geometry DEF N2 Text { + string [""] + fontStyle USE FS + } + } + ] + } + DEF STR StringSensor { + } + ] +} + +ROUTE STR.enteredText TO N3.string +ROUTE STR.finalText TO N2.string + diff --git a/src/Makefile b/src/Makefile index de6533b..f2eadd6 100644 --- a/src/Makefile +++ b/src/Makefile @@ -15,10 +15,10 @@ 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/list.o utils/base_encoding.o utils/bitstream.o utils/color.o utils/configfile.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 +LIBGPAC_UTILS=utils/os_divers.o utils/os_net.o utils/os_module.o utils/os_thread.o utils/list.o utils/base_encoding.o utils/bitstream.o utils/color.o utils/configfile.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/dlmalloc.o ## libgpac objects gathering: src/ietf -LIBGPAC_IETF=ietf/rtcp.o ietf/rtp.o ietf/rtp_packetizer.o ietf/rtp_pck_3gpp.o ietf/rtp_pck_mpeg12.o ietf/rtp_pck_mpeg4.o ietf/rtsp_command.o ietf/rtsp_common.o ietf/rtsp_response.o ietf/rtsp_session.o ietf/sdp.o ietf/rtp_depacketizer.o +LIBGPAC_IETF=ietf/rtcp.o ietf/rtp.o ietf/rtp_packetizer.o ietf/rtp_pck_3gpp.o ietf/rtp_pck_mpeg12.o ietf/rtp_pck_mpeg4.o ietf/rtsp_command.o ietf/rtsp_common.o ietf/rtsp_response.o ietf/rtsp_session.o ietf/sdp.o ietf/rtp_depacketizer.o ietf/rtp_streamer.o ## libgpac objects gathering: src/bifs LIBGPAC_BIFS=bifs/arith_decoder.o bifs/bifs_codec.o bifs/bifs_node_tables.o bifs/com_dec.o bifs/com_enc.o bifs/conditional.o bifs/field_decode.o bifs/field_encode.o bifs/memory_decoder.o bifs/predictive_mffield.o bifs/quantize.o bifs/script_dec.o bifs/script_enc.o bifs/unquantize.o @@ -36,16 +36,16 @@ LIBGPAC_SCENE=scenegraph/base_scenegraph.o scenegraph/mpeg4_animators.o scenegra LIBGPAC_MCRYPT=mcrypt/cbc.o mcrypt/cfb.o mcrypt/ctr.o mcrypt/des.o mcrypt/ecb.o mcrypt/g_crypt.o mcrypt/ncfb.o mcrypt/nofb.o mcrypt/ofb.o mcrypt/rijndael-128.o mcrypt/rijndael-192.o mcrypt/rijndael-256.o mcrypt/stream.o mcrypt/tripledes.o mcrypt/sha1.o ## libgpac objects gathering: src/media tools -LIBGPAC_MEDIATOOLS=media_tools/av_parsers.o media_tools/avilib.o media_tools/gpac_ogg.o media_tools/img.o media_tools/ismacryp.o media_tools/isom_hinter.o media_tools/isom_tools.o media_tools/media_export.o media_tools/media_import.o media_tools/mpeg2_ps.o media_tools/text_import.o media_tools/saf.o media_tools/mpegts.o media_tools/vobsub.o +LIBGPAC_MEDIATOOLS=media_tools/av_parsers.o media_tools/avilib.o media_tools/filestreamer.o media_tools/gpac_ogg.o media_tools/img.o media_tools/ismacryp.o media_tools/isom_hinter.o media_tools/isom_tools.o media_tools/media_export.o media_tools/media_import.o media_tools/mpeg2_ps.o media_tools/text_import.o media_tools/saf.o media_tools/mpegts.o media_tools/dvb_mpe.o media_tools/reedsolomon.o media_tools/vobsub.o media_tools/m2ts_mux.o ## libgpac objects gathering: src/scene_manager -LIBGPAC_SCENEMANAGER=scene_manager/loader_bt.o scene_manager/loader_isom.o scene_manager/loader_qt.o scene_manager/loader_xmt.o scene_manager/scene_dump.o scene_manager/scene_manager.o scene_manager/scene_stats.o scene_manager/swf_parse.o scene_manager/swf_bifs.o scene_manager/text_to_bifs.o scene_manager/encode_cbk.o scene_manager/encode_isom.o scene_manager/loader_svg.o +LIBGPAC_SCENEMANAGER=scene_manager/loader_bt.o scene_manager/loader_isom.o scene_manager/loader_qt.o scene_manager/loader_xmt.o scene_manager/scene_dump.o scene_manager/scene_manager.o scene_manager/scene_stats.o scene_manager/swf_parse.o scene_manager/swf_bifs.o scene_manager/text_to_bifs.o scene_manager/scene_engine.o scene_manager/encode_isom.o scene_manager/loader_svg.o ## libgpac objects gathering: src/terminal -LIBGPAC_TERMINAL=terminal/channel.o terminal/clock.o terminal/decoder.o terminal/term_node_init.o terminal/inline.o terminal/input_sensor.o terminal/media_control.o terminal/media_manager.o terminal/media_memory.o terminal/media_object.o terminal/media_sensor.o terminal/network_service.o terminal/object_browser.o terminal/object_manager.o terminal/terminal.o terminal/svg_external.o +LIBGPAC_TERMINAL=terminal/channel.o terminal/clock.o terminal/decoder.o terminal/term_node_init.o terminal/input_sensor.o terminal/media_control.o terminal/media_manager.o terminal/media_memory.o terminal/media_object.o terminal/media_sensor.o terminal/mpeg4_inline.o terminal/network_service.o terminal/object_browser.o terminal/object_manager.o terminal/scene.o terminal/terminal.o terminal/svg_external.o ## libgpac objects gathering: src/compositor -LIBGPAC_COMPOSITOR=compositor/audio_input.o compositor/audio_mixer.o compositor/audio_render.o compositor/bindable.o compositor/camera.o compositor/compositor.o compositor/compositor_2d.o compositor/compositor_3d.o compositor/compositor_node_init.o compositor/drawable.o compositor/events.o compositor/font_engine.o compositor/hardcoded_protos.o compositor/mesh.o compositor/mesh_collide.o compositor/mesh_tesselate.o compositor/mpeg4_animstream.o compositor/mpeg4_audio.o compositor/mpeg4_background.o compositor/mpeg4_background2d.o compositor/mpeg4_bitmap.o compositor/mpeg4_composite.o compositor/mpeg4_form.o compositor/mpeg4_geometry_2d.o compositor/mpeg4_geometry_3d.o compositor/mpeg4_geometry_ifs2d.o compositor/mpeg4_geometry_ils2d.o compositor/mpeg4_gradients.o compositor/mpeg4_grouping.o compositor/mpeg4_grouping_2d.o compositor/mpeg4_grouping_3d.o compositor/mpeg4_layer_2d.o compositor/mpeg4_layer_3d.o compositor/mpeg4_layout.o compositor/mpeg4_lighting.o compositor/mpeg4_path_layout.o compositor/mpeg4_sensors.o compositor/mpeg4_sound.o compositor/mpeg4_text.o compositor/mpeg4_textures.o compositor/mpeg4_timesensor.o compositor/mpeg4_viewport.o compositor/navigate.o compositor/offscreen_cache.o compositor/svg_base.o compositor/svg_font.o compositor/svg_geometry.o compositor/svg_grouping.o compositor/svg_media.o compositor/svg_paint_servers.o compositor/svg_text.o compositor/texturing.o compositor/texturing_gl.o compositor/visual_manager.o compositor/visual_manager_2d.o compositor/visual_manager_2d_draw.o compositor/visual_manager_3d.o compositor/visual_manager_3d_gl.o compositor/x3d_geometry.o +LIBGPAC_COMPOSITOR=compositor/audio_input.o compositor/audio_mixer.o compositor/audio_render.o compositor/bindable.o compositor/camera.o compositor/compositor.o compositor/compositor_2d.o compositor/compositor_3d.o compositor/compositor_node_init.o compositor/drawable.o compositor/events.o compositor/font_engine.o compositor/hc_flash_shape.o compositor/hardcoded_protos.o compositor/mesh.o compositor/mesh_collide.o compositor/mesh_tesselate.o compositor/mpeg4_animstream.o compositor/mpeg4_audio.o compositor/mpeg4_background.o compositor/mpeg4_background2d.o compositor/mpeg4_bitmap.o compositor/mpeg4_composite.o compositor/mpeg4_form.o compositor/mpeg4_geometry_2d.o compositor/mpeg4_geometry_3d.o compositor/mpeg4_geometry_ifs2d.o compositor/mpeg4_geometry_ils2d.o compositor/mpeg4_gradients.o compositor/mpeg4_grouping.o compositor/mpeg4_grouping_2d.o compositor/mpeg4_grouping_3d.o compositor/mpeg4_layer_2d.o compositor/mpeg4_layer_3d.o compositor/mpeg4_layout.o compositor/mpeg4_lighting.o compositor/mpeg4_path_layout.o compositor/mpeg4_sensors.o compositor/mpeg4_sound.o compositor/mpeg4_text.o compositor/mpeg4_textures.o compositor/mpeg4_timesensor.o compositor/mpeg4_viewport.o compositor/navigate.o compositor/offscreen_cache.o compositor/svg_base.o compositor/svg_filters.o compositor/svg_font.o compositor/svg_geometry.o compositor/svg_grouping.o compositor/svg_media.o compositor/svg_paint_servers.o compositor/svg_text.o compositor/texturing.o compositor/texturing_gl.o compositor/visual_manager.o compositor/visual_manager_2d.o compositor/visual_manager_2d_draw.o compositor/visual_manager_3d.o compositor/visual_manager_3d_gl.o compositor/x3d_geometry.o ## libgpac objects gathering: src/laser LIBGPAC_LASER= @@ -56,7 +56,6 @@ endif ## libgpac objects gathering: la totale ... OBJS=$(LIBGPAC_UTILS) $(LIBGPAC_MCRYPT) $(LIBGPAC_SCENE) $(LIBGPAC_IETF) $(LIBGPAC_BIFS) $(LIBGPAC_ISOM) $(LIBGPAC_ODF) $(LIBGPAC_MEDIATOOLS) $(LIBGPAC_SCENEMANAGER) $(LIBGPAC_TERMINAL) $(LIBGPAC_COMPOSITOR) $(LIBGPAC_LASER) -CFLAGS+=-I../ -DGPAC_HAVE_CONFIG_H NEED_LOCAL_LIB="no" LINKLIBS= SCENEGRAPH_CFLAGS= @@ -95,6 +94,7 @@ MEDIATOOLS_CFLAGS+=-I$(LOCAL_INC_PATH)/jpeg endif endif + #5 - PNG support ifeq ($(CONFIG_PNG), no) else @@ -106,14 +106,6 @@ endif endif -ifneq ($(prefix), /usr/local) -EXTRALIBS+=-L$(prefix)/lib -else -ifneq ($(prefix), /usr) -EXTRALIBS+=-L$(prefix)/lib -endif -endif - ## libgpac compositor compilation options COMPOSITOR_CFLAGS= ## SVG disabled @@ -121,25 +113,31 @@ ifeq ($(DISABLE_SVG), yes) COMPOSITOR_CFLAGS+=-DGPAC_DISABLE_SVG endif -# OpenGL support +## OpenGL available ifeq ($(HAS_OPENGL),yes) EXTRALIBS+= $(OGL_LIBS) COMPOSITOR_CFLAGS+=$(OGL_INCLS) endif -ifeq ($(TRISCOPE_MODE), yes) -COMPOSITOR_CFLAGS+=-DGPAC_TRISCOPE_MODE -EXTRALIBS+= -Lcompositor/triscope_renoir -#EXTRALIBS+= -lViRen_linux -lViRenDrivers_linux -lToolTraceManager -lToolMemoryManager -lOsalRealtime -lOsalFile -lOsalUriHandler -lOsalCharStar -lOsalMath -EXTRALIBS+= -lViRen_linux -lViRenDrivers_linux -lEmulRen_linux -lToolTraceManager -lToolMemoryManager -lOsalRealtime -lOsalFile -lOsalUriHandler -lOsalCharStar -lOsalMath -LIBGPAC_COMPOSITOR+=compositor/triscope_renoir/triscope_renoir.o compositor/chrono.o -#special malloc for renoir memory -LIBGPAC_COMPOSITOR+=compositor/triscope_renoir/gltx_malloc.o +ifeq ($(NEED_LOCAL_LIB), "yes") +EXTRALIBS+=-L../extra_lib/lib/gcc +endif +EXTRALIBS+=$(LINKLIBS) + +ifneq ($(prefix), /usr/local) +EXTRALIBS+=-L$(prefix)/lib +else +ifneq ($(prefix), /usr) +EXTRALIBS+=-L$(prefix)/lib +endif endif ifeq ($(GPAC_USE_TINYGL), yes) -COMPOSITOR_CFLAGS+=-I$(SRC_PATH)/../../TinyGL/include +COMPOSITOR_CFLAGS+=-I$(SRC_PATH)/../TinyGL/include +else +COMPOSITOR_CFLAGS+=-DGPAC_HAS_GLU endif + ifeq ($(ENABLE_JOYSTICK), yes) COMPOSITOR_CFLAGS+=-DENABLE_JOYSTICK endif @@ -150,14 +148,11 @@ ifeq ($(GPACREADONLY), yes) MEDIATOOLS_CFLAGS=-DGPAC_READ_ONLY endif -ifeq ($(NEED_LOCAL_LIB), "yes") -EXTRALIBS+=-L../extra_lib/lib/gcc -endif -EXTRALIBS+=$(LINKLIBS) ifeq ($(GPAC_ENST), yes) OBJS+=$(LIBGPAC_ENST) EXTRALIBS+=-liconv +MEDIATOOLS_CFLAGS+=-DGPAC_ENST_PRIVATE endif @@ -173,17 +168,14 @@ endif EXTRALIBS+=$(GPAC_SH_FLAGS) endif -ifeq ($(WANT_PIC),yes) -OBJSPIC=$(OBJS:.o=.opic) -else -OBJSPIC=$(OBJS) -endif - LD_SONAME="-Wl,-soname,$(LIB)" ifeq ($(CONFIG_DARWIN), yes) -LD_SONAME="" +LD_SONAME= endif +ifeq ($(CONFIG_SUNOS), yes) +LD_SONAME="-Wl,-h,$(LIB)" +endif SRCS := $(OBJS:.o=.c) @@ -208,10 +200,16 @@ compositor: $(LIBGPAC_COMPOSITOR) $(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 $(OBJSPIC) +$(LIB): $(LIBGPAC_UTILS) $(LIBGPAC_IETF) $(LIBGPAC_BIFS) $(LIBGPAC_ODF) $(LIBGPAC_LASER) $(LIBGPAC_ISOM) $(LIBGPAC_SCENEMANAGER) $(LIBGPAC_TERMINAL) compositor scenegraph mediatools mcrypt $(OBJS) +ifeq ($(CONFIG_DARWIN),yes) + 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 - $(CC) $(SHFLAGS) $(LD_SONAME) $(LDFLAGS) -o ../bin/gcc/$@ $(OBJSPIC) $(EXTRALIBS) + $(CC) $(SHFLAGS) $(LD_SONAME) $(LDFLAGS) -o ../bin/gcc/$@ $(OBJS) $(EXTRALIBS) +endif dep: depend @@ -220,7 +218,7 @@ depend: $(CC) -MM $(CFLAGS) $(SRCS) 1>.depend clean: - rm -f $(OBJS) $(LIB) + rm -f $(OBJS) ../bin/gcc/$(LIB) rm -rf ../bin/gcc/libgpac_static.a distclean: clean diff --git a/src/bifs/arith_decoder.c b/src/bifs/arith_decoder.c index 99dd17f..b838bb4 100644 --- a/src/bifs/arith_decoder.c +++ b/src/bifs/arith_decoder.c @@ -10,19 +10,21 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ -#include "quant.h" +#include "quant.h" + +#ifdef GPAC_ENABLE_BIFS_PMF /* Adaptive Arithmethic Decoder from Annex G (Normative) @@ -54,7 +56,7 @@ #define AAM_Q1 16384 #define AAM_Q2 32768 #define AAM_Q3 49152 -#define AAM_TOP 65535 +#define AAM_TOP 65535 #define AAM_ZEROMAX 22 #define AAM_MAX_FREQ 16383 @@ -64,7 +66,7 @@ struct _aamodel s32 *cumul_freq; s32 *freq; }; - + struct _aadecoder { u32 low, high, code_value; @@ -88,19 +90,19 @@ GF_AAModel *gp_bifs_aa_model_new() void gp_bifs_aa_model_del(GF_AAModel *model) { - if (model->cumul_freq) free(model->cumul_freq); - if (model->freq) free(model->freq); - free(model); + if (model->cumul_freq) gf_free(model->cumul_freq); + if (model->freq) gf_free(model->freq); + gf_free(model); } void gp_bifs_aa_model_init(GF_AAModel *model, u32 nbBits) { s32 i; model->nb_symb = 1<<nbBits; - if (model->cumul_freq) free(model->cumul_freq); - if (model->freq) free(model->freq); - model->freq = (s32*)malloc(sizeof(s32) * model->nb_symb); - model->cumul_freq = (s32*)malloc(sizeof(s32) * (model->nb_symb+1)); + if (model->cumul_freq) gf_free(model->cumul_freq); + if (model->freq) gf_free(model->freq); + model->freq = (s32*)gf_malloc(sizeof(s32) * model->nb_symb); + model->cumul_freq = (s32*)gf_malloc(sizeof(s32) * (model->nb_symb+1)); for(i=0; i<model->nb_symb; i++) { model->freq[i]=1; @@ -140,7 +142,7 @@ GF_AADecoder *gp_bifs_aa_dec_new(GF_BitStream *bs) } void gp_bifs_aa_dec_del(GF_AADecoder *dec) { - free(dec); + gf_free(dec); } static Bool bit_out_psc_layer(GF_AADecoder *dec) @@ -163,12 +165,12 @@ static Bool bit_out_psc_layer(GF_AADecoder *dec) } dec->Bit = v; dec->needs_flush = 1; - + if (!dec->Bit) dec->zero_run++; - else + else dec->zero_run = 0; - + return 1; } @@ -180,7 +182,7 @@ void gp_bifs_aa_dec_resync(GF_AADecoder *dec) /*magic number from IM1 (spec is wrong there)*/ rewind = 14; if (dec->skip_bits < rewind) gf_bs_rewind_bits(dec->bs, rewind - dec->skip_bits); - + dec->needs_flush = 0; dec->code_value = 0; dec->low = 0; @@ -203,7 +205,7 @@ void gp_bifs_aa_dec_flush(GF_AADecoder *dec) void gp_bifs_aa_dec_resync_bit(GF_AADecoder *dec) { - if (dec->needs_flush && (dec->skip_bits < 16)) + if (dec->needs_flush && (dec->skip_bits < 16)) gf_bs_rewind_bits(dec->bs, 16 - dec->skip_bits); dec->needs_flush = 0; @@ -241,12 +243,12 @@ static s32 AADec_Dec(GF_AADecoder *dec, GF_AAModel *model) len = dec->high - dec->low + 1; sum = (-1 + (dec->code_value - dec->low + 1) * model->cumul_freq[0]) / len; - + for (sac_index = 1; model->cumul_freq[sac_index] > sum; sac_index++) { } dec->high = dec->low - 1 + (len * model->cumul_freq[sac_index-1]) / model->cumul_freq[0]; dec->low += (len * model->cumul_freq[sac_index]) / model->cumul_freq[0]; - + for ( ; ; ) { if (dec->high < AAM_Q2) { } else if (dec->low >= AAM_Q2) { @@ -261,7 +263,7 @@ static s32 AADec_Dec(GF_AADecoder *dec, GF_AAModel *model) } else { break; } - + dec->low *= 2; dec->high = 2 * dec->high + 1; if (!bit_out_psc_layer(dec)) return -1; @@ -279,3 +281,5 @@ s32 gp_bifs_aa_decode(GF_AADecoder *dec, GF_AAModel *model) return v; } +#endif /*GPAC_ENABLE_BIFS_PMF*/ + diff --git a/src/bifs/bifs_codec.c b/src/bifs/bifs_codec.c index 61f6f04..e44b428 100644 --- a/src/bifs/bifs_codec.c +++ b/src/bifs/bifs_codec.c @@ -25,12 +25,18 @@ #include <gpac/internal/bifs_dev.h> #include <gpac/mpeg4_odf.h> +#include <gpac/nodes_x3d.h> + +#ifndef GPAC_DISABLE_BIFS static GF_Err ParseConfig(GF_BitStream *bs, BIFSStreamInfo *info, u32 version) { Bool hasSize, cmd_stream; + if (info->config.elementaryMasks) gf_list_del(info->config.elementaryMasks); + info->config.elementaryMasks = NULL ; + if (version==2) { info->config.Use3DMeshCoding = gf_bs_read_int(bs, 1); info->config.UsePredictiveMFField = gf_bs_read_int(bs, 1); @@ -73,9 +79,9 @@ static void bifs_info_del(BIFSStreamInfo *info) BIFSElementaryMask *em = (BIFSElementaryMask *)gf_list_last(info->config.elementaryMasks); if (!em) break; gf_list_rem_last(info->config.elementaryMasks); - free(em); + gf_free(em); } - free(info); + gf_free(info); } GF_EXPORT @@ -151,7 +157,7 @@ GF_Err gf_bifs_decoder_configure_stream(GF_BifsDecoder * codec, u16 ESID, char * } if (e && (e != GF_ODF_INVALID_DESCRIPTOR)) { - free(pInfo); + gf_free(pInfo); gf_bs_del(bs); return GF_BIFS_UNKNOWN_VERSION; } @@ -183,7 +189,7 @@ GF_Err gf_bifs_decoder_remove_stream(GF_BifsDecoder *codec, u16 ESID) i=0; while ((ptr = (BIFSStreamInfo*)gf_list_enum(codec->streamInfo, &i))) { if(ptr->ESID==ESID) { - free(ptr); + gf_free(ptr); gf_list_rem(codec->streamInfo, i-1); return GF_OK; } @@ -207,13 +213,15 @@ void gf_bifs_decoder_del(GF_BifsDecoder *codec) while (gf_list_count(codec->command_buffers)) { CommandBufferItem *cbi = (CommandBufferItem *)gf_list_get(codec->command_buffers, 0); - free(cbi); + gf_free(cbi); gf_list_rem(codec->command_buffers, 0); } gf_list_del(codec->command_buffers); + if (codec->extraction_path) gf_free(codec->extraction_path); + if (codec->service_url) gf_free(codec->service_url); // gf_mx_del(codec->mx); - free(codec); + gf_free(codec); } @@ -264,6 +272,9 @@ void gf_bifs_decoder_set_time_offset(GF_BifsDecoder *codec, Double ts) codec->cts_offset = ts; } + +#ifndef GPAC_DISABLE_BIFS_ENC + GF_Node *gf_bifs_enc_find_node(GF_BifsEncoder *codec, u32 nodeID) { if (codec->current_proto_graph) return gf_sg_find_node(codec->current_proto_graph, nodeID); @@ -312,7 +323,7 @@ void gf_bifs_encoder_del(GF_BifsEncoder *codec) gf_list_del(codec->streamInfo); gf_list_del(codec->encoded_nodes); // gf_mx_del(codec->mx); - free(codec); + gf_free(codec); } GF_EXPORT @@ -452,4 +463,53 @@ u8 gf_bifs_encoder_get_version(GF_BifsEncoder *codec, u16 ESID) // gf_mx_v(codec->mx); return ret; } +#endif /*GPAC_DISABLE_BIFS_ENC*/ + + +u32 gf_bifs_get_child_table(GF_Node *Node) +{ + assert(Node); + return gf_sg_mpeg4_node_get_child_ndt(Node); +} + + +GF_Err gf_bifs_get_field_index(GF_Node *Node, u32 inField, u8 IndexMode, u32 *allField) +{ + assert(Node); + switch (Node->sgprivate->tag) { + case TAG_ProtoNode: + return gf_sg_proto_get_field_ind_static(Node, inField, IndexMode, allField); + case TAG_MPEG4_Script: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Script: +#endif + return gf_sg_script_get_field_index(Node, inField, IndexMode, allField); + default: + return gf_sg_mpeg4_node_get_field_index(Node, inField, IndexMode, allField); + } +} + + +/* QUANTIZATION AND BIFS_Anim Info */ +GF_EXPORT +Bool gf_bifs_get_aq_info(GF_Node *Node, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (Node->sgprivate->tag) { + case TAG_ProtoNode: return gf_sg_proto_get_aq_info(Node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + default: return gf_sg_mpeg4_node_get_aq_info(Node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + } +} + +GF_EXPORT +void gf_bifs_decoder_set_extraction_path(GF_BifsDecoder *codec, const char *path, const char *service_url) +{ + if (!codec) return; + if (codec->extraction_path) gf_free(codec->extraction_path); + codec->extraction_path = path ? gf_strdup(path) : NULL; + if (codec->service_url) gf_free(codec->service_url); + codec->service_url = service_url ? gf_strdup(service_url) : NULL; + +} + +#endif /*GPAC_DISABLE_BIFS*/ diff --git a/src/bifs/bifs_node_tables.c b/src/bifs/bifs_node_tables.c index 9664a76..709f524 100644 --- a/src/bifs/bifs_node_tables.c +++ b/src/bifs/bifs_node_tables.c @@ -24,9 +24,9 @@ /* - DO NOT MOFIFY - File generated on GMT Thu Aug 07 11:43:26 2008 + DO NOT MOFIFY - File generated on GMT Mon Jan 18 12:27:12 2010 - BY MPEG4Gen for GPAC Version 0.4.5-DEV + BY MPEG4Gen for GPAC Version 0.4.6-DEV */ @@ -34,6 +34,9 @@ #include <gpac/internal/bifs_tables.h> +#ifndef GPAC_DISABLE_BIFS + + u32 ALL_GetNodeType(const u32 *table, const u32 count, u32 NodeTag, u32 Version) { u32 i = 0; @@ -801,6 +804,264 @@ u32 NDT_V6_GetNodeType(u32 NDT_Tag, u32 NodeTag) + +u32 NDT_V7_GetNodeTag(u32 Context_NDT_Tag, u32 NodeType) +{ + if (!NodeType) return 0; + /* adjust according to the table version */ + /* v7: 0 reserved for extensions */ + NodeType -= 1; + switch (Context_NDT_Tag) { + case NDT_SFWorldNode: + if (NodeType >= SFWorldNode_V7_Count) return 0; + return SFWorldNode_V7_TypeToTag[NodeType]; + case NDT_SF3DNode: + if (NodeType >= SF3DNode_V7_Count) return 0; + return SF3DNode_V7_TypeToTag[NodeType]; + case NDT_SF2DNode: + if (NodeType >= SF2DNode_V7_Count) return 0; + return SF2DNode_V7_TypeToTag[NodeType]; + case NDT_SFAudioNode: + if (NodeType >= SFAudioNode_V7_Count) return 0; + return SFAudioNode_V7_TypeToTag[NodeType]; + case NDT_SFTextureNode: + if (NodeType >= SFTextureNode_V7_Count) return 0; + return SFTextureNode_V7_TypeToTag[NodeType]; + case NDT_SFDepthImageNode: + if (NodeType >= SFDepthImageNode_V7_Count) return 0; + return SFDepthImageNode_V7_TypeToTag[NodeType]; + case NDT_SFDepthTextureNode: + if (NodeType >= SFDepthTextureNode_V7_Count) return 0; + return SFDepthTextureNode_V7_TypeToTag[NodeType]; + default: + return 0; + } +} + + +u32 NDT_V7_GetNumBits(u32 NDT_Tag) +{ + switch (NDT_Tag) { + case NDT_SFWorldNode: + return SFWorldNode_V7_NUMBITS; + case NDT_SF3DNode: + return SF3DNode_V7_NUMBITS; + case NDT_SF2DNode: + return SF2DNode_V7_NUMBITS; + case NDT_SFAudioNode: + return SFAudioNode_V7_NUMBITS; + case NDT_SFTextureNode: + return SFTextureNode_V7_NUMBITS; + case NDT_SFDepthImageNode: + return SFDepthImageNode_V7_NUMBITS; + case NDT_SFDepthTextureNode: + return SFDepthTextureNode_V7_NUMBITS; + default: + return 0; + } +} + +u32 NDT_V7_GetNodeType(u32 NDT_Tag, u32 NodeTag) +{ + if(!NDT_Tag || !NodeTag) return 0; + switch(NDT_Tag) { + case NDT_SFWorldNode: + return ALL_GetNodeType(SFWorldNode_V7_TypeToTag, SFWorldNode_V7_Count, NodeTag, GF_BIFS_V7); + case NDT_SF3DNode: + return ALL_GetNodeType(SF3DNode_V7_TypeToTag, SF3DNode_V7_Count, NodeTag, GF_BIFS_V7); + case NDT_SF2DNode: + return ALL_GetNodeType(SF2DNode_V7_TypeToTag, SF2DNode_V7_Count, NodeTag, GF_BIFS_V7); + case NDT_SFAudioNode: + return ALL_GetNodeType(SFAudioNode_V7_TypeToTag, SFAudioNode_V7_Count, NodeTag, GF_BIFS_V7); + case NDT_SFTextureNode: + return ALL_GetNodeType(SFTextureNode_V7_TypeToTag, SFTextureNode_V7_Count, NodeTag, GF_BIFS_V7); + case NDT_SFDepthImageNode: + return ALL_GetNodeType(SFDepthImageNode_V7_TypeToTag, SFDepthImageNode_V7_Count, NodeTag, GF_BIFS_V7); + case NDT_SFDepthTextureNode: + return ALL_GetNodeType(SFDepthTextureNode_V7_TypeToTag, SFDepthTextureNode_V7_Count, NodeTag, GF_BIFS_V7); + default: + return 0; + } +} + + + + +u32 NDT_V8_GetNodeTag(u32 Context_NDT_Tag, u32 NodeType) +{ + if (!NodeType) return 0; + /* adjust according to the table version */ + /* v8: 0 reserved for extensions */ + NodeType -= 1; + switch (Context_NDT_Tag) { + case NDT_SFWorldNode: + if (NodeType >= SFWorldNode_V8_Count) return 0; + return SFWorldNode_V8_TypeToTag[NodeType]; + case NDT_SF3DNode: + if (NodeType >= SF3DNode_V8_Count) return 0; + return SF3DNode_V8_TypeToTag[NodeType]; + case NDT_SF2DNode: + if (NodeType >= SF2DNode_V8_Count) return 0; + return SF2DNode_V8_TypeToTag[NodeType]; + case NDT_SFMusicScoreNode: + if (NodeType >= SFMusicScoreNode_V8_Count) return 0; + return SFMusicScoreNode_V8_TypeToTag[NodeType]; + default: + return 0; + } +} + + +u32 NDT_V8_GetNumBits(u32 NDT_Tag) +{ + switch (NDT_Tag) { + case NDT_SFWorldNode: + return SFWorldNode_V8_NUMBITS; + case NDT_SF3DNode: + return SF3DNode_V8_NUMBITS; + case NDT_SF2DNode: + return SF2DNode_V8_NUMBITS; + case NDT_SFMusicScoreNode: + return SFMusicScoreNode_V8_NUMBITS; + default: + return 0; + } +} + +u32 NDT_V8_GetNodeType(u32 NDT_Tag, u32 NodeTag) +{ + if(!NDT_Tag || !NodeTag) return 0; + switch(NDT_Tag) { + case NDT_SFWorldNode: + return ALL_GetNodeType(SFWorldNode_V8_TypeToTag, SFWorldNode_V8_Count, NodeTag, GF_BIFS_V8); + case NDT_SF3DNode: + return ALL_GetNodeType(SF3DNode_V8_TypeToTag, SF3DNode_V8_Count, NodeTag, GF_BIFS_V8); + case NDT_SF2DNode: + return ALL_GetNodeType(SF2DNode_V8_TypeToTag, SF2DNode_V8_Count, NodeTag, GF_BIFS_V8); + case NDT_SFMusicScoreNode: + return ALL_GetNodeType(SFMusicScoreNode_V8_TypeToTag, SFMusicScoreNode_V8_Count, NodeTag, GF_BIFS_V8); + default: + return 0; + } +} + + + + +u32 NDT_V9_GetNodeTag(u32 Context_NDT_Tag, u32 NodeType) +{ + if (!NodeType) return 0; + /* adjust according to the table version */ + /* v9: 0 reserved for extensions */ + NodeType -= 1; + switch (Context_NDT_Tag) { + case NDT_SFWorldNode: + if (NodeType >= SFWorldNode_V9_Count) return 0; + return SFWorldNode_V9_TypeToTag[NodeType]; + case NDT_SF3DNode: + if (NodeType >= SF3DNode_V9_Count) return 0; + return SF3DNode_V9_TypeToTag[NodeType]; + case NDT_SFGeometryNode: + if (NodeType >= SFGeometryNode_V9_Count) return 0; + return SFGeometryNode_V9_TypeToTag[NodeType]; + default: + return 0; + } +} + + +u32 NDT_V9_GetNumBits(u32 NDT_Tag) +{ + switch (NDT_Tag) { + case NDT_SFWorldNode: + return SFWorldNode_V9_NUMBITS; + case NDT_SF3DNode: + return SF3DNode_V9_NUMBITS; + case NDT_SFGeometryNode: + return SFGeometryNode_V9_NUMBITS; + default: + return 0; + } +} + +u32 NDT_V9_GetNodeType(u32 NDT_Tag, u32 NodeTag) +{ + if(!NDT_Tag || !NodeTag) return 0; + switch(NDT_Tag) { + case NDT_SFWorldNode: + return ALL_GetNodeType(SFWorldNode_V9_TypeToTag, SFWorldNode_V9_Count, NodeTag, GF_BIFS_V9); + case NDT_SF3DNode: + return ALL_GetNodeType(SF3DNode_V9_TypeToTag, SF3DNode_V9_Count, NodeTag, GF_BIFS_V9); + case NDT_SFGeometryNode: + return ALL_GetNodeType(SFGeometryNode_V9_TypeToTag, SFGeometryNode_V9_Count, NodeTag, GF_BIFS_V9); + default: + return 0; + } +} + + + + +u32 NDT_V10_GetNodeTag(u32 Context_NDT_Tag, u32 NodeType) +{ + if (!NodeType) return 0; + /* adjust according to the table version */ + /* v10: 0 reserved for extensions */ + NodeType -= 1; + switch (Context_NDT_Tag) { + case NDT_SFWorldNode: + if (NodeType >= SFWorldNode_V10_Count) return 0; + return SFWorldNode_V10_TypeToTag[NodeType]; + case NDT_SF3DNode: + if (NodeType >= SF3DNode_V10_Count) return 0; + return SF3DNode_V10_TypeToTag[NodeType]; + case NDT_SF2DNode: + if (NodeType >= SF2DNode_V10_Count) return 0; + return SF2DNode_V10_TypeToTag[NodeType]; + case NDT_SFTextureNode: + if (NodeType >= SFTextureNode_V10_Count) return 0; + return SFTextureNode_V10_TypeToTag[NodeType]; + default: + return 0; + } +} + + +u32 NDT_V10_GetNumBits(u32 NDT_Tag) +{ + switch (NDT_Tag) { + case NDT_SFWorldNode: + return SFWorldNode_V10_NUMBITS; + case NDT_SF3DNode: + return SF3DNode_V10_NUMBITS; + case NDT_SF2DNode: + return SF2DNode_V10_NUMBITS; + case NDT_SFTextureNode: + return SFTextureNode_V10_NUMBITS; + default: + return 0; + } +} + +u32 NDT_V10_GetNodeType(u32 NDT_Tag, u32 NodeTag) +{ + if(!NDT_Tag || !NodeTag) return 0; + switch(NDT_Tag) { + case NDT_SFWorldNode: + return ALL_GetNodeType(SFWorldNode_V10_TypeToTag, SFWorldNode_V10_Count, NodeTag, GF_BIFS_V10); + case NDT_SF3DNode: + return ALL_GetNodeType(SF3DNode_V10_TypeToTag, SF3DNode_V10_Count, NodeTag, GF_BIFS_V10); + case NDT_SF2DNode: + return ALL_GetNodeType(SF2DNode_V10_TypeToTag, SF2DNode_V10_Count, NodeTag, GF_BIFS_V10); + case NDT_SFTextureNode: + return ALL_GetNodeType(SFTextureNode_V10_TypeToTag, SFTextureNode_V10_Count, NodeTag, GF_BIFS_V10); + default: + return 0; + } +} + + + u32 gf_bifs_ndt_get_node_type(u32 NDT_Tag, u32 NodeType, u32 Version) { switch (Version) { @@ -816,6 +1077,14 @@ u32 gf_bifs_ndt_get_node_type(u32 NDT_Tag, u32 NodeType, u32 Version) return NDT_V5_GetNodeTag(NDT_Tag, NodeType); case GF_BIFS_V6: return NDT_V6_GetNodeTag(NDT_Tag, NodeType); + case GF_BIFS_V7: + return NDT_V7_GetNodeTag(NDT_Tag, NodeType); + case GF_BIFS_V8: + return NDT_V8_GetNodeTag(NDT_Tag, NodeType); + case GF_BIFS_V9: + return NDT_V9_GetNodeTag(NDT_Tag, NodeType); + case GF_BIFS_V10: + return NDT_V10_GetNodeTag(NDT_Tag, NodeType); default: return 0; } @@ -836,6 +1105,14 @@ u32 gf_bifs_get_ndt_bits(u32 NDT_Tag, u32 Version) return NDT_V5_GetNumBits(NDT_Tag); case GF_BIFS_V6: return NDT_V6_GetNumBits(NDT_Tag); + case GF_BIFS_V7: + return NDT_V7_GetNumBits(NDT_Tag); + case GF_BIFS_V8: + return NDT_V8_GetNumBits(NDT_Tag); + case GF_BIFS_V9: + return NDT_V9_GetNumBits(NDT_Tag); + case GF_BIFS_V10: + return NDT_V10_GetNumBits(NDT_Tag); default: return 0; } @@ -856,6 +1133,14 @@ u32 gf_bifs_get_node_type(u32 NDT_Tag, u32 NodeTag, u32 Version) return NDT_V5_GetNodeType(NDT_Tag, NodeTag); case GF_BIFS_V6: return NDT_V6_GetNodeType(NDT_Tag, NodeTag); + case GF_BIFS_V7: + return NDT_V7_GetNodeType(NDT_Tag, NodeTag); + case GF_BIFS_V8: + return NDT_V8_GetNodeType(NDT_Tag, NodeTag); + case GF_BIFS_V9: + return NDT_V9_GetNodeType(NDT_Tag, NodeTag); + case GF_BIFS_V10: + return NDT_V10_GetNodeType(NDT_Tag, NodeTag); default: return 0; } @@ -905,6 +1190,14 @@ u32 gf_bifs_get_node_type(u32 NDT_Tag, u32 NodeTag, u32 Version) return NDT_SF3DNode; case TAG_MPEG4_TemporalGroup: return NDT_SFTemporalNode; + case TAG_MPEG4_FFD: + return NDT_SF3DNode; + case TAG_MPEG4_SBBone: + return NDT_SF3DNode; + case TAG_MPEG4_SBSegment: + return NDT_SF3DNode; + case TAG_MPEG4_SBSite: + return NDT_SF3DNode; case TAG_MPEG4_Clipper2D: return NDT_SF2DNode; case TAG_MPEG4_ColorTransform: @@ -913,8 +1206,24 @@ u32 gf_bifs_get_node_type(u32 NDT_Tag, u32 NodeTag, u32 Version) return NDT_SF2DNode; case TAG_MPEG4_TransformMatrix2D: return NDT_SF2DNode; + case TAG_MPEG4_AdvancedAudioBuffer: + return NDT_SFAudioNode; + case TAG_MPEG4_AudioChannelConfig: + return NDT_SFAudioNode; + case TAG_MPEG4_Transform3DAudio: + return NDT_SF3DNode; + case TAG_MPEG4_FootPrintSetNode: + return NDT_SFGeometryNode; + case TAG_MPEG4_Shadow: + return NDT_SF3DNode; + case TAG_MPEG4_SpacePartition: + return NDT_SF3DNode; default: return 0; } } + + +#endif /*GPAC_DISABLE_BIFS*/ + diff --git a/src/bifs/com_dec.c b/src/bifs/com_dec.c index d41d1fe..2e04998 100644 --- a/src/bifs/com_dec.c +++ b/src/bifs/com_dec.c @@ -26,6 +26,9 @@ #include <gpac/internal/bifs_dev.h> #include "quant.h" +#ifndef GPAC_DISABLE_BIFS + + GF_Err BD_DecMFFieldList(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field); GF_Err BD_DecMFFieldVec(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field); @@ -41,6 +44,215 @@ void gf_bifs_dec_name(GF_BitStream *bs, char *name) } } + +static GF_Err BD_XReplace(GF_BifsDecoder * codec, GF_BitStream *bs) +{ + GF_FieldInfo targetField, fromField; + GF_Node *target, *n, *fromNode; + s32 pos = -2; + void *slot_ptr; + u32 id, nbBits, ind, aind; + GF_Err e; + + + id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); + target = gf_sg_find_node(codec->current_graph, id); + if (!target) return GF_SG_UNKNOWN_NODE; + + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1); + ind = gf_bs_read_int(bs, nbBits); + e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind); + if (e) return e; + e = gf_node_get_field(target, aind, &targetField); + if (e) return e; + + if (!gf_sg_vrml_is_sf_field(targetField.fieldType)) { + /*this is indexed replacement*/ + if (gf_bs_read_int(bs, 1)) { + /*index is dynamic*/ + if (gf_bs_read_int(bs, 1)) { + id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); + n = gf_sg_find_node(codec->current_graph, id); + if (!n) return GF_SG_UNKNOWN_NODE; + + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); + ind = gf_bs_read_int(bs, nbBits); + e = gf_bifs_get_field_index(n, ind, GF_SG_FIELD_CODING_DEF, &aind); + if (e) return e; + e = gf_node_get_field(n, aind, &fromField); + if (e) return e; + + pos = 0; + switch (fromField.fieldType) { + case GF_SG_VRML_SFBOOL: + if (*(SFBool*)fromField.far_ptr) pos = 1; + break; + case GF_SG_VRML_SFINT32: + if (*(SFInt32*)fromField.far_ptr >=0) pos = *(SFInt32*)fromField.far_ptr; + break; + case GF_SG_VRML_SFFLOAT: + if ( (*(SFFloat *)fromField.far_ptr) >=0) pos = (s32) floor( FIX2FLT(*(SFFloat*)fromField.far_ptr) ); + break; + case GF_SG_VRML_SFTIME: + if ( (*(SFTime *)fromField.far_ptr) >=0) pos = (s32) floor( (*(SFTime *)fromField.far_ptr) ); + break; + } + } else { + u32 type = gf_bs_read_int(bs, 2); + switch (type) { + case 0: + pos = gf_bs_read_int(bs, 16); + break; + case 2: + pos = 0; + break; + case 3: + pos = -1; + break; + } + } + } + + if (targetField.fieldType==GF_SG_VRML_MFNODE) { + if (gf_bs_read_int(bs, 1)) { + target = gf_node_list_get_child(*(GF_ChildNodeItem **)targetField.far_ptr, pos); + if (!target) return GF_SG_UNKNOWN_NODE; + + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1); + ind = gf_bs_read_int(bs, nbBits); + e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind); + if (e) return e; + e = gf_node_get_field(target, aind, &targetField); + if (e) return e; + pos = -2; + } + } + } + + fromNode = NULL; + if (gf_bs_read_int(bs, 1)) { + id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); + fromNode = gf_sg_find_node(codec->current_graph, id); + if (!fromNode) return GF_SG_UNKNOWN_NODE; + + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(fromNode, GF_SG_FIELD_CODING_DEF)-1); + ind = gf_bs_read_int(bs, nbBits); + e = gf_bifs_get_field_index(fromNode, ind, GF_SG_FIELD_CODING_DEF, &aind); + if (e) return e; + e = gf_node_get_field(fromNode, aind, &fromField); + if (e) return e; + } + + /*indexed replacement*/ + if (pos>=-1) { + /*if MFNode remove the child and set new node*/ + if (targetField.fieldType == GF_SG_VRML_MFNODE) { + GF_Node *newnode; + if (fromNode) { + newnode = *(GF_Node**)fromField.far_ptr; + } else { + newnode = gf_bifs_dec_node(codec, bs, targetField.NDTtype); + } + gf_node_replace_child(target, (GF_ChildNodeItem**) targetField.far_ptr, pos, newnode); + if (newnode) gf_node_register(newnode, NULL); + } + /*erase the field item*/ + else { + u32 sftype; + if ((pos < 0) || ((u32) pos >= ((GenMFField *) targetField.far_ptr)->count) ) { + pos = ((GenMFField *)targetField.far_ptr)->count - 1; + /*may happen with text and default value*/ + if (pos < 0) { + pos = 0; + gf_sg_vrml_mf_alloc(targetField.far_ptr, targetField.fieldType, 1); + } + } + e = gf_sg_vrml_mf_get_item(targetField.far_ptr, targetField.fieldType, & slot_ptr, pos); + if (e) return e; + sftype = gf_sg_vrml_get_sf_type(targetField.fieldType); + + if (fromNode) { + if (sftype==fromField.fieldType) + gf_sg_vrml_field_copy(slot_ptr, fromField.far_ptr, sftype); + } else { + GF_FieldInfo sffield; + memcpy(&sffield, &targetField, sizeof(GF_FieldInfo)); + sffield.fieldType = sftype; + sffield.far_ptr = slot_ptr; + gf_bifs_dec_sf_field(codec, bs, target, &sffield); + } + } + gf_bifs_check_field_change(target, &targetField); + return GF_OK; + } + switch (targetField.fieldType) { + case GF_SG_VRML_SFNODE: + { + GF_Node *newnode; + if (fromNode) { + newnode = *(GF_Node**)fromField.far_ptr; + } else { + newnode = gf_bifs_dec_node(codec, bs, targetField.NDTtype); + } + + n = *((GF_Node **) targetField.far_ptr); + + *((GF_Node **) targetField.far_ptr) = newnode; + if (newnode) gf_node_register(newnode, target); + + if (n) gf_node_unregister(n, target); + + break; + } + case GF_SG_VRML_MFNODE: + { + GF_ChildNodeItem *previous = * (GF_ChildNodeItem **) targetField.far_ptr; + * ((GF_ChildNodeItem **) targetField.far_ptr) = NULL; + + if (fromNode) { + GF_ChildNodeItem *list, *prev, *cur; + list = * ((GF_ChildNodeItem **) targetField.far_ptr); + prev=NULL; + while (list) { + cur = gf_malloc(sizeof(GF_ChildNodeItem)); + cur->next = NULL; + cur->node = list->node; + if (prev) { + prev->next = cur; + } else { + * ((GF_ChildNodeItem **) targetField.far_ptr) = cur; + } + gf_node_register(list->node, target); + prev = cur; + list = list->next; + } + } else { + e = gf_bifs_dec_field(codec, bs, target, &targetField); + if (e) return e; + } + if (previous) + gf_node_unregister_children(target, previous); + + break; + } + default: + if (!gf_sg_vrml_is_sf_field(targetField.fieldType)) { + e = gf_sg_vrml_mf_reset(targetField.far_ptr, targetField.fieldType); + } + if (e) return e; + + if (fromNode) { + if (fromField.fieldType == targetField.fieldType) + gf_sg_vrml_field_clone(targetField.far_ptr, fromField.far_ptr, targetField.fieldType, codec->current_graph); + } else { + e = gf_bifs_dec_field(codec, bs, target, &targetField); + } + break; + } + gf_bifs_check_field_change(target, &targetField); + return GF_OK; +} + static GF_Err BD_DecProtoDelete(GF_BifsDecoder * codec, GF_BitStream *bs) { u32 ID, flag, count; @@ -308,7 +520,7 @@ static GF_Err BD_DecExtendedUpdate(GF_BifsDecoder * codec, GF_BitStream *bs) case 6: return BD_DecNodeDeleteEx(codec, bs); case 7: - return BD_DecOperandReplace(codec, bs); + return BD_XReplace(codec, bs); default: return GF_BIFS_UNKNOWN_VERSION; } @@ -1160,3 +1372,4 @@ GF_Err gf_bifs_dec_command(GF_BifsDecoder * codec, GF_BitStream *bs) return GF_OK; } +#endif /*GPAC_DISABLE_BIFS*/ diff --git a/src/bifs/com_enc.c b/src/bifs/com_enc.c index f7a8748..cb4a5a0 100644 --- a/src/bifs/com_enc.c +++ b/src/bifs/com_enc.c @@ -26,6 +26,8 @@ #include <gpac/internal/bifs_dev.h> #include "quant.h" +#ifndef GPAC_DISABLE_BIFS_ENC + GF_Err BE_EncProtoList(GF_BifsEncoder *codec, GF_List *protoList, GF_BitStream *bs); @@ -40,6 +42,90 @@ void gf_bifs_enc_name(GF_BifsEncoder *codec, GF_BitStream *bs, char *name) GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] DEF\t\t%d\t\t%s\n", 8*i, name)); } +static GF_Err BE_XReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) +{ + u32 i,nbBits; + GF_FieldInfo field; + GF_Err e; + GF_CommandField *inf; + if (!gf_list_count(com->command_fields)) return GF_BAD_PARAM; + inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); + + + gf_bs_write_int(bs, gf_node_get_id(com->node)-1, codec->info->config.NodeIDBits); + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(com->node, GF_SG_FIELD_CODING_IN)-1); + gf_bifs_field_index_by_mode(com->node, inf->fieldIndex, GF_SG_FIELD_CODING_IN, &i); + GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "field", NULL); + + gf_node_get_field(com->node, inf->fieldIndex, &field); + if (!gf_sg_vrml_is_sf_field(field.fieldType)) { + if ((inf->pos != -2) || com->toNodeID) { + GF_BIFS_WRITE_INT(codec, bs, 1, 1, "indexedReplacement", NULL); + if (com->toNodeID) { + GF_Node *n = gf_bifs_enc_find_node(codec, com->toNodeID); + GF_BIFS_WRITE_INT(codec, bs, 1, 1, "dynamicIndex", NULL); + GF_BIFS_WRITE_INT(codec, bs, com->toNodeID-1, codec->info->config.NodeIDBits, "idxNodeID", NULL); + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); + gf_bifs_field_index_by_mode(n, com->toFieldIndex, GF_SG_FIELD_CODING_DEF, &i); + GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "idxField", NULL); + } else { + GF_BIFS_WRITE_INT(codec, bs, 0, 1, "dynamicIndex", NULL); + if (inf->pos==-1) { + GF_BIFS_WRITE_INT(codec, bs, 3, 2, "replacementPosition", NULL); + } else if (inf->pos==0) { + GF_BIFS_WRITE_INT(codec, bs, 2, 2, "replacementPosition", NULL); + } else { + GF_BIFS_WRITE_INT(codec, bs, 0, 2, "replacementPosition", NULL); + GF_BIFS_WRITE_INT(codec, bs, inf->pos, 16, "position", NULL); + } + } + } else { + GF_BIFS_WRITE_INT(codec, bs, 0, 1, "indexedReplacement", NULL); + } + } + if (field.fieldType==GF_SG_VRML_MFNODE) { + if (com->ChildNodeTag) { + GF_Node *n; + if (com->ChildNodeTag>0) { + n = gf_node_new(codec->scene_graph, com->ChildNodeTag); + } else { + GF_Proto *proto = gf_sg_find_proto(codec->scene_graph, -com->ChildNodeTag , NULL); + if (!proto) return GF_SG_UNKNOWN_NODE; + n = gf_sg_proto_create_instance(codec->scene_graph, proto); + } + if (!n) return GF_SG_UNKNOWN_NODE; + gf_node_register(n, NULL); + + GF_BIFS_WRITE_INT(codec, bs, 1, 1, "childField", NULL); + + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_IN)-1); + gf_bifs_field_index_by_mode(n, com->child_field, GF_SG_FIELD_CODING_IN, &i); + GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "childField", NULL); + gf_node_unregister(n, NULL); + } else { + GF_BIFS_WRITE_INT(codec, bs, 0, 1, "childField", NULL); + } + } + if (com->fromNodeID) { + GF_Node *n = gf_bifs_enc_find_node(codec, com->fromNodeID); + GF_BIFS_WRITE_INT(codec, bs, 1, 1, "valueFromNode", NULL); + + GF_BIFS_WRITE_INT(codec, bs, com->fromNodeID-1, codec->info->config.NodeIDBits, "sourceNodeID", NULL); + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); + gf_bifs_field_index_by_mode(n, com->fromFieldIndex, GF_SG_FIELD_CODING_DEF, &i); + GF_BIFS_WRITE_INT(codec, bs, i, nbBits, "sourceField", NULL); + + return GF_OK; + } + + GF_BIFS_WRITE_INT(codec, bs, 0, 1, "valueFromNode", NULL); + + field.far_ptr = inf->field_ptr; + field.fieldType = inf->fieldType; + e = gf_bifs_enc_field(codec, bs, com->node, &field); + return e; +} + static GF_Err BE_MultipleIndexedReplace(GF_BifsEncoder * codec, GF_Command *com, GF_BitStream *bs) { u32 i,nbBits, count, maxPos, nbBitsPos; @@ -202,6 +288,9 @@ static GF_Err BE_ExtendedUpdate(GF_BifsEncoder * codec, GF_Command *com, GF_BitS GF_BIFS_WRITE_INT(codec, bs, 6, 8, "MultipleReplace", NULL); GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(com->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); return GF_OK; + case GF_SG_XREPLACE: + GF_BIFS_WRITE_INT(codec, bs, 7, 8, "XReplace", NULL); + return BE_XReplace(codec, com, bs); default: return GF_BAD_PARAM; } @@ -780,7 +869,7 @@ GF_Err gf_bifs_enc_commands(GF_BifsEncoder *codec, GF_List *comList, GF_BitStrea while (gf_list_count(routes)) { GF_Route *r = (GF_Route*)gf_list_get(routes, 0); gf_list_rem(routes, 0); - free(r); + gf_free(r); } gf_list_del(routes); } else { @@ -883,3 +972,4 @@ GF_Err gf_bifs_encoder_get_rap(GF_BifsEncoder *codec, char **out_data, u32 *out_ return e; } +#endif /*GPAC_DISABLE_BIFS_ENC*/ diff --git a/src/bifs/conditional.c b/src/bifs/conditional.c index 5ecd527..2de3b9a 100644 --- a/src/bifs/conditional.c +++ b/src/bifs/conditional.c @@ -26,6 +26,9 @@ #include <gpac/internal/bifs_dev.h> + +#ifndef GPAC_DISABLE_BIFS + /*private stack for conditional*/ typedef struct { @@ -39,7 +42,7 @@ void Conditional_PreDestroy(GF_Node *n, void *eff, Bool is_destroy) { if (is_destroy) { ConditionalStack *priv = (ConditionalStack*)gf_node_get_private(n); - if (priv) free(priv); + if (priv) gf_free(priv); } } @@ -99,7 +102,7 @@ static void Conditional_execute(M_Conditional *node) } #endif if (node->buffer.buffer) { - free(buffer); + gf_free(buffer); } else { node->buffer.buffer = buffer; node->buffer.bufferSize = len; @@ -112,14 +115,14 @@ static void Conditional_execute(M_Conditional *node) codec->current_graph = prev_graph; } -void Conditional_OnActivate(GF_Node *n) +void Conditional_OnActivate(GF_Node *n, GF_Route *route) { M_Conditional *node = (M_Conditional *)n; if (! node->activate) return; Conditional_execute(node); } -void Conditional_OnReverseActivate(GF_Node *n) +void Conditional_OnReverseActivate(GF_Node *n, GF_Route *route) { M_Conditional *node = (M_Conditional *)n; if (node->reverseActivate) return; @@ -130,7 +133,7 @@ void SetupConditional(GF_BifsDecoder *codec, GF_Node *node) { ConditionalStack *priv; if (gf_node_get_tag(node) != TAG_MPEG4_Conditional) return; - priv = (ConditionalStack*)malloc(sizeof(ConditionalStack)); + priv = (ConditionalStack*)gf_malloc(sizeof(ConditionalStack)); /*needed when initializing extern protos*/ if (!codec->info) codec->info = (BIFSStreamInfo*)gf_list_get(codec->streamInfo, 0); @@ -144,15 +147,24 @@ void SetupConditional(GF_BifsDecoder *codec, GF_Node *node) ((M_Conditional *)node)->on_reverseActivate = Conditional_OnReverseActivate; } +#endif /*GPAC_DISABLE_BIFS*/ + + /*this is ugly but we have no choice, we need to clone the conditional stack because of externProto*/ void BIFS_SetupConditionalClone(GF_Node *node, GF_Node *orig) { +#ifndef GPAC_DISABLE_BIFS M_Conditional *ptr; - u32 i; ConditionalStack *priv_orig, *priv; priv_orig = (ConditionalStack*)gf_node_get_private(orig); /*looks we're not in BIFS*/ if (!priv_orig) { +#else + { +#endif + +#ifndef GPAC_DISABLE_VRML + u32 i; GF_Command *ori_com; M_Conditional *c_orig, *c_dest; c_orig = (M_Conditional *)orig; @@ -161,12 +173,15 @@ void BIFS_SetupConditionalClone(GF_Node *node, GF_Node *orig) /*and clone all commands*/ i=0; while ((ori_com = (GF_Command*)gf_list_enum(c_orig->buffer.commandList, &i))) { - GF_Command *dest_com = gf_sg_command_clone(ori_com, gf_node_get_graph(node), 1); + GF_Command *dest_com = gf_sg_vrml_command_clone(ori_com, gf_node_get_graph(node), 1); if (dest_com) gf_list_add(c_dest->buffer.commandList, dest_com); } +#endif return; } - priv = (ConditionalStack*)malloc(sizeof(ConditionalStack)); + +#ifndef GPAC_DISABLE_BIFS + priv = (ConditionalStack*)gf_malloc(sizeof(ConditionalStack)); priv->codec = priv_orig->codec; priv->info = priv_orig->info; gf_node_set_callback_function(node, Conditional_PreDestroy); @@ -174,4 +189,6 @@ void BIFS_SetupConditionalClone(GF_Node *node, GF_Node *orig) ptr = (M_Conditional *)node; ptr->on_activate = Conditional_OnActivate; ptr->on_reverseActivate = Conditional_OnReverseActivate; +#endif + } diff --git a/src/bifs/field_decode.c b/src/bifs/field_decode.c index c59b324..7c3da7e 100644 --- a/src/bifs/field_decode.c +++ b/src/bifs/field_decode.c @@ -25,9 +25,11 @@ #include <gpac/internal/bifs_dev.h> +#include <gpac/crypt.h> #include "quant.h" #include "script.h" +#ifndef GPAC_DISABLE_BIFS void SFCommandBufferChanged(GF_BifsDecoder * codec, GF_Node *node) { @@ -121,11 +123,62 @@ GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *n length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; - if ( ((SFString *)field->far_ptr)->buffer ) free( ((SFString *)field->far_ptr)->buffer); - ((SFString *)field->far_ptr)->buffer = (char *)malloc(sizeof(char)*(length+1)); - memset(((SFString *)field->far_ptr)->buffer , 0, length+1); - for (i=0; i<length; i++) { - ((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8); + if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) { + char *name; + FILE *f; + M_CacheTexture *ct = (M_CacheTexture *) node; + char *buf = gf_malloc(sizeof(char)*length); + gf_bs_read_data(bs, buf, length); + if (ct->cacheURL.buffer) { + name = gf_strdup(ct->cacheURL.buffer); + } else { + char szImg[100], *ext; + switch (ct->objectTypeIndication) { + case GPAC_OTI_IMAGE_JPEG: ext = "jpg"; break; + case GPAC_OTI_IMAGE_PNG: ext = "png"; break; + case GPAC_OTI_IMAGE_JPEG_2000: ext = "jp2"; break; + default: ext = "img"; + } + sprintf(szImg, "%p%p.%s", codec, ct, ext); + name = gf_strdup(szImg); + } + + if (codec->extraction_path) { + char *path; + u32 len = strlen(name)+strlen(codec->extraction_path)+2; + if (codec->service_url) len += 41; + path = gf_malloc(sizeof(char)*len); + if (codec->service_url) { + u8 hash[20]; + u32 i; + gf_sha1_csum(codec->service_url, strlen(codec->service_url), hash); + sprintf(path, "%s/", codec->extraction_path); + for (i=0; i<20; i++) { + char t[3]; + t[2] = 0; + sprintf(t, "%02X", hash[i]); + strcat(path, t); + } + strcat(path, "_"); + strcat(path, name); + } else { + sprintf(path, "%s/%s", codec->extraction_path, name); + } + gf_free(name); + name = path; + } + + ((SFString *)field->far_ptr)->buffer = name; + f = gf_f64_open(name, "wb"); + fwrite(buf, 1, length, f); + fclose(f); + } else { + if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer); + ((SFString *)field->far_ptr)->buffer = (char *)gf_malloc(sizeof(char)*(length+1)); + memset(((SFString *)field->far_ptr)->buffer , 0, length+1); + for (i=0; i<length; i++) { + ((SFString *)field->far_ptr)->buffer[i] = gf_bs_read_int(bs, 8); + } } break; case GF_SG_VRML_SFURL: @@ -133,7 +186,7 @@ GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *n SFURL *url = (SFURL *) field->far_ptr; size = gf_bs_read_int(bs, 1); if (size) { - if (url->url) free(url->url ); + if (url->url) gf_free(url->url ); url->url = NULL; length = gf_bs_read_int(bs, 10); url->OD_ID = length; @@ -144,23 +197,23 @@ GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *n if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; buffer = NULL; if (length) { - buffer = (char *)malloc(sizeof(char)*(length+1)); + buffer = (char *)gf_malloc(sizeof(char)*(length+1)); memset(buffer, 0, length+1); for (i=0; i<length; i++) buffer[i] = gf_bs_read_int(bs, 8); } - if (url->url) free( url->url); + if (url->url) gf_free( url->url); /*if URL is empty set it to NULL*/ if (buffer && strlen(buffer)) { url->url = buffer; } else { - free(buffer); + gf_free(buffer); url->url = NULL; } } } break; case GF_SG_VRML_SFIMAGE: - if (((SFImage *)field->far_ptr)->pixels) free(((SFImage *)field->far_ptr)->pixels); + if (((SFImage *)field->far_ptr)->pixels) gf_free(((SFImage *)field->far_ptr)->pixels); w = gf_bs_read_int(bs, 12); h = gf_bs_read_int(bs, 12); length = gf_bs_read_int(bs, 2); @@ -172,7 +225,7 @@ GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *n ((SFImage *)field->far_ptr)->width = w; ((SFImage *)field->far_ptr)->height = h; ((SFImage *)field->far_ptr)->numComponents = length; - ((SFImage *)field->far_ptr)->pixels = (unsigned char *)malloc(sizeof(char)*size); + ((SFImage *)field->far_ptr)->pixels = (unsigned char *)gf_malloc(sizeof(char)*size); //WARNING: Buffers are NOT ALIGNED IN THE BITSTREAM for (i=0; i<size; i++) { ((SFImage *)field->far_ptr)->pixels[i] = gf_bs_read_int(bs, 8); @@ -182,7 +235,7 @@ GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *n { SFCommandBuffer *sfcb = (SFCommandBuffer *)field->far_ptr; if (sfcb->buffer) { - free(sfcb->buffer); + gf_free(sfcb->buffer); sfcb->buffer = NULL; } while (gf_list_count(sfcb->commandList)) { @@ -197,7 +250,7 @@ GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *n sfcb->bufferSize = length; if (length) { - sfcb->buffer = (unsigned char *)malloc(sizeof(char)*(length)); + sfcb->buffer = (unsigned char *)gf_malloc(sizeof(char)*(length)); //WARNING Buffers are NOT ALIGNED IN THE BITSTREAM for (i=0; i<length; i++) { sfcb->buffer[i] = gf_bs_read_int(bs, 8); @@ -212,7 +265,7 @@ GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *n 2 - InputSensor only works on decompressed commands */ if (codec->dec_memory_mode || (node->sgprivate->tag==TAG_MPEG4_InputSensor)) { - CommandBufferItem *cbi = (CommandBufferItem *)malloc(sizeof(CommandBufferItem)); + CommandBufferItem *cbi = (CommandBufferItem *)gf_malloc(sizeof(CommandBufferItem)); cbi->node = node; cbi->cb = sfcb; gf_list_add(codec->command_buffers, cbi); @@ -230,7 +283,25 @@ GF_Err gf_bifs_dec_sf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *n *((GF_Node **) field->far_ptr) = new_node; break; case GF_SG_VRML_SFSCRIPT: +#ifdef GPAC_HAS_SPIDERMONKEY codec->LastError = SFScript_Parse(codec, (SFScript*)field->far_ptr, bs, node); +#else + return GF_NOT_SUPPORTED; +#endif + break; + case GF_SG_VRML_SFATTRREF: + { + SFAttrRef *ar = (SFAttrRef *)field->far_ptr; + u32 nodeID = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); + ar->node = gf_sg_find_node(codec->current_graph, nodeID); + if (!ar->node) { + + } else { + u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1); + u32 field_ref = gf_bs_read_int(bs, nbBitsDEF); + codec->LastError = gf_bifs_get_field_index(ar->node, field_ref, GF_SG_FIELD_CODING_DEF, &ar->fieldIndex); + } + } break; default: return GF_NON_COMPLIANT_BITSTREAM; @@ -258,7 +329,7 @@ GF_Err BD_DecMFFieldList(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node initial_qp = codec->ActiveQP ? 1 : 0; endFlag = gf_bs_read_int(bs, 1); - while (!endFlag) { + while (!endFlag && (codec->LastError>=0)) { e = GF_OK;; if (field->fieldType != GF_SG_VRML_MFNODE) { e = gf_sg_vrml_mf_append(field->far_ptr, field->fieldType, & sffield.far_ptr); @@ -430,7 +501,7 @@ void gf_bifs_check_field_change(GF_Node *node, GF_FieldInfo *field) gf_node_event_out(node, field->fieldIndex); /*and propagate eventIn if any*/ if (field->on_event_in) { - field->on_event_in(node); + field->on_event_in(node, NULL); } else if ((gf_node_get_tag(node) == TAG_MPEG4_Script) && (field->eventType==GF_SG_EVENT_IN)) { gf_sg_script_event_in(node, field); } @@ -465,7 +536,13 @@ GF_Err gf_bifs_dec_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node /*predictiveMFField*/ if (codec->info->config.UsePredictiveMFField) { flag = gf_bs_read_int(bs, 1); - if (flag) return gf_bifs_dec_pred_mf_field(codec, bs, node, field); + if (flag) +#ifdef GPAC_ENABLE_BIFS_PMF + return gf_bifs_dec_pred_mf_field(codec, bs, node, field); +#else + return GF_NOT_SUPPORTED; +#endif + } /*reserved*/ @@ -519,7 +596,7 @@ GF_Err gf_bifs_dec_node_list(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node * numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1); flag = gf_bs_read_int(bs, 1); - while (!flag) { + while (!flag && (codec->LastError>=0)) { if (codec->pCurrentProto) { //IS'ed flag flag = gf_bs_read_int(bs, 1); @@ -892,3 +969,4 @@ GF_Node *gf_bifs_dec_node(GF_BifsDecoder * codec, GF_BitStream *bs, u32 NDT_Tag) return new_node; } +#endif /*GPAC_DISABLE_BIFS*/ diff --git a/src/bifs/field_encode.c b/src/bifs/field_encode.c index 44f34bb..1d3c095 100644 --- a/src/bifs/field_encode.c +++ b/src/bifs/field_encode.c @@ -29,6 +29,7 @@ #include "quant.h" #include "script.h" +#ifndef GPAC_DISABLE_BIFS_ENC GF_Err gf_bifs_field_index_by_mode(GF_Node *node, u32 all_ind, u8 indexMode, u32 *outField) { @@ -89,16 +90,32 @@ GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *no break; case GF_SG_VRML_SFSTRING: - { - u32 i; - char *str = (char *) ((SFString*)field->far_ptr)->buffer; - u32 len = str ? strlen(str) : 0; - u32 val = gf_get_bit_size(len); - GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL); - GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL); - for (i=0; i<len; i++) gf_bs_write_int(bs, str[i], 8); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\n", 8*len, str) ); - } + if (node && (node->sgprivate->tag==TAG_MPEG4_CacheTexture) && (field->fieldIndex<=2)) { + u32 size, val; + char buf[4096]; + FILE *f = gf_f64_open(((SFString*)field->far_ptr)->buffer, "rb"); + if (!f) return GF_URL_ERROR; + gf_f64_seek(f, 0, SEEK_END); + size = (u32) gf_f64_tell(f); + val = gf_get_bit_size(size); + GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL); + GF_BIFS_WRITE_INT(codec, bs, size, val, "length", NULL); + gf_f64_seek(f, 0, SEEK_SET); + while (size) { + u32 read = fread(buf, 1, 4096, f); + gf_bs_write_data(bs, buf, read); + size -= read; + } + } else { + u32 i; + char *str = (char *) ((SFString*)field->far_ptr)->buffer; + u32 len = str ? strlen(str) : 0; + u32 val = gf_get_bit_size(len); + GF_BIFS_WRITE_INT(codec, bs, val, 5, "nbBits", NULL); + GF_BIFS_WRITE_INT(codec, bs, len, val, "length", NULL); + for (i=0; i<len; i++) gf_bs_write_int(bs, str[i], 8); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[BIFS] string\t\t%d\t\t%s\n", 8*len, str) ); + } break; case GF_SG_VRML_SFTIME: @@ -150,7 +167,7 @@ GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *no case GF_SG_VRML_SFCOMMANDBUFFER: { SFCommandBuffer *cb = (SFCommandBuffer *) field->far_ptr; - if (cb->buffer) free(cb->buffer); + if (cb->buffer) gf_free(cb->buffer); cb->buffer = NULL; cb->bufferSize = 0; if (gf_list_count(cb->commandList)) { @@ -178,10 +195,25 @@ GF_Err gf_bifs_enc_sf_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node *no return gf_bifs_enc_node(codec, *((GF_Node **)field->far_ptr), field->NDTtype, bs); case GF_SG_VRML_SFSCRIPT: +#ifdef GPAC_HAS_SPIDERMONKEY codec->LastError = SFScript_Encode(codec, (SFScript *)field->far_ptr, bs, node); +#else + return GF_NOT_SUPPORTED; +#endif + break; + case GF_SG_VRML_SFATTRREF: + { + u32 idx=0; + SFAttrRef *ar = (SFAttrRef *)field->far_ptr; + u32 nbBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(ar->node, GF_SG_FIELD_CODING_DEF) - 1); + GF_BIFS_WRITE_INT(codec, bs, gf_node_get_id(ar->node) - 1, codec->info->config.NodeIDBits, "NodeID", NULL); + + gf_bifs_field_index_by_mode(ar->node, ar->fieldIndex, GF_SG_FIELD_CODING_DEF, &idx); + GF_BIFS_WRITE_INT(codec, bs, idx, nbBitsDEF, "field", NULL); + } break; default: - return GF_NON_COMPLIANT_BITSTREAM; + return GF_NOT_SUPPORTED; } return codec->LastError; } @@ -361,7 +393,7 @@ GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node) numBitsDEF = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF) - 1); - enc_fields = (s32*)malloc(sizeof(s32) * count); + enc_fields = (s32*)gf_malloc(sizeof(s32) * count); nbFinal = 0; for (i=0; i<count; i++) { enc_fields[i] = -1; @@ -481,7 +513,7 @@ GF_Err EncNodeFields(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node) /*end flag*/ if (use_list) GF_BIFS_WRITE_INT(codec, bs, 1, 1, "end", NULL); exit: - free(enc_fields); + gf_free(enc_fields); return e; } @@ -600,3 +632,4 @@ GF_Err gf_bifs_enc_node(GF_BifsEncoder * codec, GF_Node *node, u32 NDT_Tag, GF_B } +#endif /*GPAC_DISABLE_BIFS_ENC*/ diff --git a/src/bifs/memory_decoder.c b/src/bifs/memory_decoder.c index 8bdf187..012781a 100644 --- a/src/bifs/memory_decoder.c +++ b/src/bifs/memory_decoder.c @@ -26,6 +26,9 @@ #include <gpac/internal/bifs_dev.h> #include "quant.h" + +#ifndef GPAC_DISABLE_BIFS + GF_Err ParseMFFieldList(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field); GF_Err ParseMFFieldVec(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field); @@ -73,7 +76,7 @@ static GF_Err BM_ParseMultipleIndexedReplace(GF_BifsDecoder *codec, GF_BitStream inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype); if (codec->LastError) goto err; inf->field_ptr = &inf->new_node; - gf_node_register(inf->new_node, node); + gf_node_register(inf->new_node, NULL); } else { field.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); e = gf_bifs_dec_sf_field(codec, bs, node, &field); @@ -129,7 +132,7 @@ static GF_Err BM_ParseMultipleReplace(GF_BifsDecoder *codec, GF_BitStream *bs, G } else { flag = gf_bs_read_int(bs, 1); nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_DEF)-1); - while (!flag) { + while (!flag && (codec->LastError>=0)) { field_ref = gf_bs_read_int(bs, nbBits); e = gf_bifs_get_field_index(node, field_ref, GF_SG_FIELD_CODING_DEF, &fieldind); if (e) goto exit; @@ -203,7 +206,7 @@ static GF_Err BM_ParseProtoDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Li count = 0; flag = gf_bs_read_int(bs, 1); while (flag) { - com->del_proto_list = (u32*)realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size+1)); + com->del_proto_list = (u32*)gf_realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size+1)); com->del_proto_list[count] = gf_bs_read_int(bs, codec->info->config.ProtoIDBits); com->del_proto_list_size++; flag = gf_bs_read_int(bs, 1); @@ -211,7 +214,7 @@ static GF_Err BM_ParseProtoDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Li } else { flag = gf_bs_read_int(bs, 5); com->del_proto_list_size = gf_bs_read_int(bs, flag); - com->del_proto_list = (u32*)realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size)); + com->del_proto_list = (u32*)gf_realloc(com->del_proto_list, sizeof(u32) * (com->del_proto_list_size)); flag = 0; while (flag<com->del_proto_list_size) { com->del_proto_list[flag] = gf_bs_read_int(bs, codec->info->config.ProtoIDBits); @@ -222,6 +225,131 @@ static GF_Err BM_ParseProtoDelete(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Li return GF_OK; } +static GF_Err BM_XReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) +{ + GF_FieldInfo targetField, fromField, decfield; + GF_Node *target, *n, *fromNode; + s32 pos = -2; + u32 id, nbBits, ind, aind; + GF_Err e; + GF_Command *com; + GF_CommandField *inf; + + id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); + target = gf_sg_find_node(codec->current_graph, id); + if (!target) return GF_SG_UNKNOWN_NODE; + + e = GF_OK; + com = gf_sg_command_new(codec->current_graph, GF_SG_XREPLACE); + BM_SetCommandNode(com, target); + + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1); + ind = gf_bs_read_int(bs, nbBits); + e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind); + if (e) return e; + e = gf_node_get_field(target, aind, &targetField); + if (e) return e; + + inf = gf_sg_command_field_new(com); + inf->fieldIndex = aind; + + if (!gf_sg_vrml_is_sf_field(targetField.fieldType)) { + /*this is indexed replacement*/ + if (gf_bs_read_int(bs, 1)) { + /*index is dynamic*/ + if (gf_bs_read_int(bs, 1)) { + id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); + n = gf_sg_find_node(codec->current_graph, id); + if (!n) return GF_SG_UNKNOWN_NODE; + com->toNodeID = id; + + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(n, GF_SG_FIELD_CODING_DEF)-1); + ind = gf_bs_read_int(bs, nbBits); + e = gf_bifs_get_field_index(n, ind, GF_SG_FIELD_CODING_DEF, &aind); + if (e) return e; + e = gf_node_get_field(n, aind, &fromField); + if (e) return e; + com->toFieldIndex = aind; + } else { + u32 type = gf_bs_read_int(bs, 2); + switch (type) { + case 0: + pos = gf_bs_read_int(bs, 16); + break; + case 2: + pos = 0; + break; + case 3: + pos = -1; + break; + } + } + } + if (targetField.fieldType==GF_SG_VRML_MFNODE) { + if (gf_bs_read_int(bs, 1)) { + target = gf_node_list_get_child(*(GF_ChildNodeItem **)targetField.far_ptr, pos); + if (!target) return GF_SG_UNKNOWN_NODE; + + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(target, GF_SG_FIELD_CODING_IN)-1); + ind = gf_bs_read_int(bs, nbBits); + e = gf_bifs_get_field_index(target, ind, GF_SG_FIELD_CODING_IN, &aind); + if (e) return e; + e = gf_node_get_field(target, aind, &targetField); + if (e) return e; + pos = -2; + com->child_field = aind; + com->ChildNodeTag = gf_node_get_tag(target); + if (com->ChildNodeTag == TAG_ProtoNode) { + s32 p_id = gf_sg_proto_get_id(gf_node_get_proto(target)); + com->ChildNodeTag = -p_id; + } + } + } + inf->pos = pos; + } + + fromNode = NULL; + if (gf_bs_read_int(bs, 1)) { + id = 1 + gf_bs_read_int(bs, codec->info->config.NodeIDBits); + fromNode = gf_sg_find_node(codec->current_graph, id); + if (!fromNode) return GF_SG_UNKNOWN_NODE; + com->fromNodeID = id; + + nbBits = gf_get_bit_size(gf_node_get_num_fields_in_mode(fromNode, GF_SG_FIELD_CODING_DEF)-1); + ind = gf_bs_read_int(bs, nbBits); + e = gf_bifs_get_field_index(fromNode, ind, GF_SG_FIELD_CODING_DEF, &aind); + if (e) return e; + e = gf_node_get_field(fromNode, aind, &fromField); + if (e) return e; + com->fromFieldIndex = aind; + + return GF_OK; + } + + + if (pos>= -1) { + inf->fieldType = gf_sg_vrml_get_sf_type(targetField.fieldType); + } else { + inf->fieldType = targetField.fieldType; + } + decfield.fieldIndex = inf->fieldIndex; + decfield.fieldType = inf->fieldType; + + if (inf->fieldType==GF_SG_VRML_SFNODE) { + decfield.far_ptr = inf->field_ptr = &inf->new_node; + } else if (inf->fieldType==GF_SG_VRML_MFNODE) { + decfield.far_ptr = inf->field_ptr = &inf->node_list; + } else { + decfield.far_ptr = inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); + } + e = gf_bifs_dec_sf_field(codec, bs, target, &decfield); + if (e) return e; + + gf_list_add(com_list, com); + + return GF_OK; +} + static GF_Err BM_ParseExtendedUpdates(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_list) { u32 type = gf_bs_read_int(bs, 8); @@ -260,6 +388,9 @@ static GF_Err BM_ParseExtendedUpdates(GF_BifsDecoder *codec, GF_BitStream *bs, G gf_list_add(com_list, com); } return GF_OK; + case 7: + return BM_XReplace(codec, bs, com_list); + default: return GF_BIFS_UNKNOWN_VERSION; } @@ -306,7 +437,7 @@ GF_Err BM_ParseNodeInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_ inf->fieldType = GF_SG_VRML_SFNODE; gf_list_add(com_list, com); /*register*/ - gf_node_register(node, def); + gf_node_register(node, NULL); } return codec->LastError; } @@ -370,7 +501,7 @@ GF_Err BM_ParseIndexInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com inf->field_ptr = &inf->new_node; gf_list_add(com_list, com); /*register*/ - gf_node_register(node, def); + gf_node_register(node, NULL); } } else { com = gf_sg_command_new(codec->current_graph, GF_SG_INDEXED_INSERT); @@ -427,7 +558,7 @@ GF_Err BM_ParseRouteInsert(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com com = gf_sg_command_new(codec->current_graph, GF_SG_ROUTE_INSERT); com->RouteID = RouteID; - if (codec->UseName) com->def_name = strdup( name); + if (codec->UseName) com->def_name = gf_strdup( name); com->fromNodeID = gf_node_get_id(OutNode); com->fromFieldIndex = outField; com->toNodeID = gf_node_get_id(InNode); @@ -594,18 +725,6 @@ GF_Err BM_ParseFieldReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *co /*parse the field*/ codec->LastError = gf_bifs_dec_field(codec, bs, node, &field); - /*register nodes*/ -#if 0 - if (inf->fieldType == GF_SG_VRML_SFNODE) { - gf_node_register(inf->new_node, com->node); - } else if (inf->fieldType == GF_SG_VRML_MFNODE) { - GF_Node *p; - u32 i=0; - while ((p = gf_list_enum(inf->node_list, &i))) { - gf_node_register(p, com->node); - } - } -#endif gf_list_add(com_list, com); return codec->LastError; } @@ -658,7 +777,7 @@ GF_Err BM_ParseIndexValueReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Lis inf->fieldType = GF_SG_VRML_SFNODE; inf->new_node = gf_bifs_dec_node(codec, bs, field.NDTtype); inf->field_ptr = &inf->new_node; - if (inf->new_node) gf_node_register(inf->new_node, com->node); + if (inf->new_node) gf_node_register(inf->new_node, NULL); } else { memcpy(&sffield, &field, sizeof(GF_FieldInfo)); sffield.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); @@ -757,7 +876,7 @@ GF_Err BM_SceneReplace(GF_BifsDecoder *codec, GF_BitStream *bs, GF_List *com_lis ri->toFieldIndex = r->ToField.fieldIndex; ri->toNodeID = gf_node_get_id(r->ToNode); if (r->ID) ri->RouteID = r->ID; - ri->def_name = r->name ? strdup(r->name) : NULL; + ri->def_name = r->name ? gf_strdup(r->name) : NULL; gf_list_add(com_list, ri); gf_sg_route_del(r); } @@ -834,7 +953,7 @@ GF_Err gf_bifs_flush_command_list(GF_BifsDecoder *codec) gf_bs_del(bs); } if (!e) { - free(cbi); + gf_free(cbi); continue; } /*this may be an error or a dependency pb - reset coimmand list and move to next pass*/ @@ -848,7 +967,7 @@ GF_Err gf_bifs_flush_command_list(GF_BifsDecoder *codec) for (i=0; i<gf_list_count(codec->command_buffers); i++) { CommandBufferItem *cbi2 = (CommandBufferItem *)gf_list_get(codec->command_buffers, i); if (cbi2->cb == cf->field_ptr) { - free(cbi2); + gf_free(cbi2); gf_list_rem(codec->command_buffers, i); i--; } @@ -905,7 +1024,7 @@ GF_Err gf_bifs_decode_command_list(GF_BifsDecoder *codec, u16 ESID, char *data, /*if err or not reset conditionals*/ while (gf_list_count(codec->command_buffers)) { CommandBufferItem *cbi = (CommandBufferItem *)gf_list_get(codec->command_buffers, 0); - free(cbi); + gf_free(cbi); gf_list_rem(codec->command_buffers, 0); } @@ -918,3 +1037,6 @@ GF_Err gf_bifs_decode_command_list(GF_BifsDecoder *codec, u16 ESID, char *data, // gf_mx_v(codec->mx); return e; } + +#endif /*GPAC_DISABLE_BIFS*/ + diff --git a/src/bifs/predictive_mffield.c b/src/bifs/predictive_mffield.c index f4e82f6..0e32773 100644 --- a/src/bifs/predictive_mffield.c +++ b/src/bifs/predictive_mffield.c @@ -24,6 +24,7 @@ #include "quant.h" +#ifdef GPAC_ENABLE_BIFS_PMF u32 gf_bifs_dec_qp14_get_bits(GF_BifsDecoder *codec); @@ -446,3 +447,4 @@ err_exit: return e; } +#endif /*GPAC_ENABLE_BIFS_PMF*/ diff --git a/src/bifs/quant.h b/src/bifs/quant.h index a0eaf95..b7dd1bc 100644 --- a/src/bifs/quant.h +++ b/src/bifs/quant.h @@ -28,7 +28,7 @@ #include <gpac/internal/bifs_dev.h> -//#define QP_PI 3.1415926535897932384626433832795 +#ifndef GPAC_DISABLE_BIFS /*Quantization Categories*/ enum @@ -52,7 +52,9 @@ enum QC_NOTDEF = 16, }; +#ifdef GPAC_ENABLE_BIFS_PMF GF_Err gf_bifs_dec_pred_mf_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field); +#endif Bool Q_IsTypeOn(M_QuantizationParameter *qp, u32 q_type, u32 *NbBits, SFVec3f *b_min, SFVec3f *b_max); @@ -69,6 +71,8 @@ GF_Err gf_bifs_dec_qp_remove(GF_BifsDecoder *codec, Bool ActivatePrev); SFFloat gf_bifs_dec_mantissa_float(GF_BifsDecoder * codec, GF_BitStream *bs); GF_Err gf_bifs_dec_unquant_field(GF_BifsDecoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field); +#ifndef GPAC_DISABLE_BIFS_ENC + /*QP14 encode*/ u32 gf_bifs_enc_qp14_get_bits(GF_BifsEncoder *codec); void gf_bifs_enc_qp14_enter(GF_BifsEncoder *codec, Bool Enter); @@ -80,7 +84,9 @@ GF_Err gf_bifs_enc_qp_remove(GF_BifsEncoder *codec, Bool ActivatePrev); void gf_bifs_enc_mantissa_float(GF_BifsEncoder * codec, SFFloat val, GF_BitStream *bs); GF_Err gf_bifs_enc_quant_field(GF_BifsEncoder * codec, GF_BitStream *bs, GF_Node *node, GF_FieldInfo *field); +#endif /*GPAC_DISABLE_BIFS_ENC*/ +#ifdef GPAC_ENABLE_BIFS_PMF /* Predictive MFField decode - mainly IM1 code (GPL H263 AA coder used) @@ -107,4 +113,9 @@ s32 gp_bifs_aa_decode(GF_AADecoder *dec, GF_AAModel *model); void gp_bifs_aa_dec_reset(GF_AADecoder *dec); +#endif /*GPAC_ENABLE_BIFS_PMF*/ + + +#endif /*GPAC_DISABLE_BIFS*/ + #endif diff --git a/src/bifs/quantize.c b/src/bifs/quantize.c index f14507b..ece1182 100644 --- a/src/bifs/quantize.c +++ b/src/bifs/quantize.c @@ -24,6 +24,7 @@ #include "quant.h" +#ifndef GPAC_DISABLE_BIFS_ENC GF_Err gf_bifs_enc_qp_set(GF_BifsEncoder *codec, GF_Node *qp) { @@ -331,3 +332,5 @@ GF_Err gf_bifs_enc_quant_field(GF_BifsEncoder *codec, GF_BitStream *bs, GF_Node } return e; } + +#endif /*GPAC_DISABLE_BIFS_ENC*/ diff --git a/src/bifs/script.h b/src/bifs/script.h index fdf6d69..7796087 100644 --- a/src/bifs/script.h +++ b/src/bifs/script.h @@ -27,6 +27,8 @@ #include <gpac/internal/bifs_dev.h> +#if !defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_SPIDERMONKEY) + #define NUMBITS_STATEMENT 3 #define NUMBITS_EXPR_TYPE 6 #define MAX_NUM_EXPR 100 @@ -102,4 +104,6 @@ enum GF_Err SFScript_Parse(GF_BifsDecoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n); GF_Err SFScript_Encode(GF_BifsEncoder *codec, SFScript *script_field, GF_BitStream *bs, GF_Node *n); +#endif /* !defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_SPIDERMONKEY) */ + #endif diff --git a/src/bifs/script_dec.c b/src/bifs/script_dec.c index 4494e6f..e86426a 100644 --- a/src/bifs/script_dec.c +++ b/src/bifs/script_dec.c @@ -10,24 +10,26 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "script.h" +#if !defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_SPIDERMONKEY) + #define BINOP_MINVAL ET_EQ -typedef struct +typedef struct { GF_Node *script; GF_BifsDecoder *codec; @@ -70,9 +72,9 @@ static void SFS_AddString(ScriptParser *parser, char *str) if (!str) return; if (strlen(parser->string) + strlen(str) >= parser->length) { parser->length += PARSER_STEP_ALLOC; - new_str = (char *)malloc(sizeof(char)*parser->length); + new_str = (char *)gf_malloc(sizeof(char)*parser->length); strcpy(new_str, parser->string); - free(parser->string); + gf_free(parser->string); parser->string = new_str; } strcat(parser->string, str); @@ -107,7 +109,7 @@ GF_Err ParseScriptField(ScriptParser *parser) if (!field) return GF_NON_COMPLIANT_BITSTREAM; //save the name in the list of identifiers - gf_list_add(parser->identifiers, strdup(name)); + gf_list_add(parser->identifiers, gf_strdup(name)); if (parser->codec->pCurrentProto) { Bool isISfield = gf_bs_read_int(parser->bs, 1); @@ -136,14 +138,14 @@ GF_Err ParseScriptField(ScriptParser *parser) static void SFS_IncIndent(ScriptParser *pars) { pars->indent++; } static void SFS_DecIndent(ScriptParser *pars) { pars->indent--; } static void SFS_Space(ScriptParser *pars) { if (pars->new_line) SFS_AddString(pars, " ");} -static void SFS_Indent(ScriptParser *pars) +static void SFS_Indent(ScriptParser *pars) { u32 i; if (pars->new_line) { for (i=0; i<pars->indent; i++) SFS_AddString(pars, " "); } } -static GFINLINE void SFS_Line(ScriptParser *parser) +static GFINLINE void SFS_Line(ScriptParser *parser) { if (parser->new_line) { SFS_AddString(parser, parser->new_line); @@ -165,7 +167,7 @@ GF_Err SFScript_Parse(GF_BifsDecoder *codec, SFScript *script_field, GF_BitStrea parser.script = n; parser.bs = bs; parser.length = 500; - parser.string = (char *) malloc(sizeof(char)* parser.length); + parser.string = (char *) gf_malloc(sizeof(char)* parser.length); parser.string[0] = 0; parser.identifiers = gf_list_new(); parser.new_line = (char *) (codec->dec_memory_mode ? "\n" : NULL); @@ -207,18 +209,18 @@ GF_Err SFScript_Parse(GF_BifsDecoder *codec, SFScript *script_field, GF_BitStrea SFS_Line(&parser); - if (script_field->script_text) free(script_field->script_text); - script_field->script_text = (unsigned char *) strdup(parser.string); + if (script_field->script_text) gf_free(script_field->script_text); + script_field->script_text = (unsigned char *) gf_strdup(parser.string); exit: //clean up while (gf_list_count(parser.identifiers)) { ptr = (char *)gf_list_get(parser.identifiers, 0); - free(ptr); + gf_free(ptr); gf_list_rem(parser.identifiers, 0); } gf_list_del(parser.identifiers); - if (parser.string) free(parser.string); + if (parser.string) gf_free(parser.string); return e; } @@ -239,7 +241,7 @@ void SFS_Identifier(ScriptParser *parser) //parse else{ gf_bifs_dec_name(parser->bs, name); - gf_list_add(parser->identifiers, strdup(name)); + gf_list_add(parser->identifiers, gf_strdup(name)); SFS_AddString(parser, name); } } @@ -249,7 +251,7 @@ void SFS_Arguments(ScriptParser *parser, Bool is_var) u32 val; if (parser->codec->LastError) return; if (!is_var) SFS_AddString(parser, "("); - + val = gf_bs_read_int(parser->bs, 1); while (val) { SFS_Identifier(parser); @@ -488,7 +490,7 @@ void SFS_Expression(ScriptParser *parser) case ET_NEW: SFS_NewObject(parser); break; - case ET_OBJECT_MEMBER_ACCESS: + case ET_OBJECT_MEMBER_ACCESS: SFS_ObjectMemberAccess(parser); break; case ET_OBJECT_METHOD_CALL: @@ -653,7 +655,7 @@ void SFS_Expression(ScriptParser *parser) SFS_AddString(parser, "|="); SFS_Expression(parser); break; - case ET_BOOLEAN: + case ET_BOOLEAN: SFS_GetBoolean(parser); break; case ET_VAR: @@ -737,16 +739,16 @@ void SFS_GetNumber(ScriptParser *parser) if (parser->codec->LastError) return; // integer - if (gf_bs_read_int(parser->bs, 1)) { + if (gf_bs_read_int(parser->bs, 1)) { nbBits = gf_bs_read_int(parser->bs, 5); val = gf_bs_read_int(parser->bs, nbBits); SFS_AddInt(parser, val); return; - } + } // real number val = gf_bs_read_int(parser->bs, 4); while ( val != 15) { - if (val>=0 && val<=9) { + if (val<=9) { SFS_AddChar(parser, (char) (val + '0') ); } else if (val==10) { SFS_AddChar(parser, '.'); @@ -776,3 +778,5 @@ void SFS_GetBoolean(ScriptParser *parser) SFS_AddString(parser, "false"); } } + +#endif /*!defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_SPIDERMONKEY)*/ diff --git a/src/bifs/script_enc.c b/src/bifs/script_enc.c index 5c48006..c6733e5 100644 --- a/src/bifs/script_enc.c +++ b/src/bifs/script_enc.c @@ -30,6 +30,8 @@ #include <gpac/internal/scenegraph_dev.h> +#if !defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_SPIDERMONKEY) + typedef struct { GF_Node *script; @@ -100,7 +102,7 @@ static GF_Err EncScriptFields(ScriptEnc *sc_enc) GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, info.fieldType, 6, "fieldType", NULL); gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, (char *) info.name); /*this is an identifier for script*/ - gf_list_add(sc_enc->identifiers, strdup(info.name)); + gf_list_add(sc_enc->identifiers, gf_strdup(info.name)); if (sc_enc->codec->encoding_proto) { GF_Route *isedField = gf_bifs_enc_is_field_ised(sc_enc->codec, sc_enc->script, i+3); @@ -592,7 +594,7 @@ void SFE_PutIdentifier(ScriptEnc *sc_enc, char *id) return; } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "received", id); - gf_list_add(sc_enc->identifiers, strdup(id)); + gf_list_add(sc_enc->identifiers, gf_strdup(id)); gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, id); } @@ -659,7 +661,7 @@ u32 SFE_LoadExpression(ScriptEnc *sc_enc, u32 *expr_sep) case TOK_NUMBER: case TOK_STRING: case TOK_BOOLEAN: - gf_list_add(sc_enc->id_buf, strdup(sc_enc->token)); + gf_list_add(sc_enc->id_buf, gf_strdup(sc_enc->token)); break; case TOK_FUNCTION: goto break_loop; @@ -688,7 +690,7 @@ u32 SFE_LoadExpression(ScriptEnc *sc_enc, u32 *expr_sep) SFE_NextToken(sc_enc); if ((sc_enc->token_code == TOK_IDENTIFIER) || (sc_enc->token_code == TOK_NUMBER) || (sc_enc->token_code == TOK_STRING) || (sc_enc->token_code == TOK_BOOLEAN) ) { - gf_list_add(sc_enc->id_buf, strdup(sc_enc->token)); + gf_list_add(sc_enc->id_buf, gf_strdup(sc_enc->token)); } sc_enc->expr_toks[sc_enc->expr_toks_len] = sc_enc->token_code; sc_enc->expr_toks_len++; @@ -707,7 +709,7 @@ break_loop: expr_sep[nbExpr] = sc_enc->expr_toks_len; if ((sc_enc->token_code == TOK_IDENTIFIER) || (sc_enc->token_code == TOK_NUMBER) || (sc_enc->token_code == TOK_STRING) || (sc_enc->token_code == TOK_BOOLEAN) ) { - gf_list_add(sc_enc->id_buf, strdup(sc_enc->token)); + gf_list_add(sc_enc->id_buf, gf_strdup(sc_enc->token)); } if ((sc_enc->token_code != TOK_CONDSEP) && (sc_enc->token_code != TOK_RIGHT_BRACE) && (sc_enc->expr_toks[0] != TOK_VAR)) { @@ -1092,14 +1094,14 @@ GF_Err SFScript_Encode(GF_BifsEncoder *codec, SFScript *script_field, GF_BitStre while (gf_list_count(sc_enc.identifiers)) { ptr = (char *)gf_list_get(sc_enc.identifiers, 0); gf_list_rem(sc_enc.identifiers, 0); - free(ptr); + gf_free(ptr); } gf_list_del(sc_enc.identifiers); /*in case of error this is needed*/ while (gf_list_count(sc_enc.id_buf)) { ptr = (char *)gf_list_get(sc_enc.id_buf, 0); gf_list_rem(sc_enc.id_buf, 0); - free(ptr); + gf_free(ptr); } gf_list_del(sc_enc.id_buf); @@ -1576,19 +1578,19 @@ skip_token: if (memberAccess) { } SFE_PutIdentifier(sc_enc, str); - free(str); + gf_free(str); break; case ET_NUMBER: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutNumber(sc_enc, str); - free(str); + gf_free(str); break; case ET_BOOLEAN: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutBoolean(sc_enc, str); - free(str); + gf_free(str); break; case ET_VAR: while (1) { @@ -1597,7 +1599,7 @@ skip_token: gf_list_rem(sc_enc->id_buf, 0); GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 1, 1, "hasArgument", NULL); SFE_PutIdentifier(sc_enc, str); - free(str); + gf_free(str); } GF_BIFS_WRITE_INT(sc_enc->codec, sc_enc->bs, 0, 1, "hasArgument", NULL); break; @@ -1605,7 +1607,7 @@ skip_token: str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); if (!sc_enc->emul) gf_bifs_enc_name(sc_enc->codec, sc_enc->bs, str); - free(str); + gf_free(str); break; case ET_NEGATIVE: case ET_INCREMENT: @@ -1666,7 +1668,7 @@ void SFE_FunctionCall(ScriptEnc *sc_enc, u32 start, u32 end) str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutIdentifier(sc_enc, str); - free(str); + gf_free(str); curTok = sc_enc->expr_toks[start++]; CHECK_TOK(TOK_LEFT_CURVE); SFE_Params(sc_enc, start, end-1); @@ -1687,7 +1689,7 @@ void SFE_ObjectMemberAccess(ScriptEnc *sc_enc, u32 start, u32 op, u32 end) str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutIdentifier(sc_enc, str); - free(str); + gf_free(str); } void SFE_ObjectMethodCall(ScriptEnc *sc_enc, u32 start, u32 op, u32 end) @@ -1703,7 +1705,7 @@ void SFE_ObjectMethodCall(ScriptEnc *sc_enc, u32 start, u32 op, u32 end) str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutIdentifier(sc_enc, str); - free(str); + gf_free(str); curTok = sc_enc->expr_toks[op+2]; CHECK_TOK(TOK_LEFT_CURVE); SFE_Params(sc_enc, op+3, end-1); @@ -1735,7 +1737,7 @@ void SFE_ObjectConstruct(ScriptEnc *sc_enc, u32 start, u32 op, u32 end) str = (char *)gf_list_get(sc_enc->id_buf, 0); gf_list_rem(sc_enc->id_buf, 0); SFE_PutIdentifier(sc_enc, str); - free(str); + gf_free(str); curTok = sc_enc->expr_toks[start++]; CHECK_TOK(TOK_LEFT_CURVE); SFE_Params(sc_enc, start, end-1); @@ -1771,3 +1773,4 @@ void SFE_Params(ScriptEnc *sc_enc, u32 start, u32 end) } } +#endif /* !defined(GPAC_DISABLE_BIFS) && defined(GPAC_HAS_SPIDERMONKEY) */ diff --git a/src/bifs/unquantize.c b/src/bifs/unquantize.c index f17dcc9..c2b5a36 100644 --- a/src/bifs/unquantize.c +++ b/src/bifs/unquantize.c @@ -10,24 +10,27 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "quant.h" +#ifndef GPAC_DISABLE_BIFS + + u32 gf_bifs_dec_qp14_get_bits(GF_BifsDecoder *codec) { if (!codec->ActiveQP || !codec->coord_stored) return 0; - return (u32) ceil(log(codec->NumCoord+1) / log(2) ); + return (u32) ceil(log(codec->NumCoord+1) / log(2) ); } void gf_bifs_dec_qp14_enter(GF_BifsDecoder * codec, Bool Enter) @@ -58,9 +61,9 @@ GF_Err gf_bifs_dec_qp_set(GF_BifsDecoder *codec, GF_Node *qp) assert(gf_node_get_tag(qp) == TAG_MPEG4_QuantizationParameter); /*if we have an active QP, push it into the stack*/ - if (codec->ActiveQP && ((GF_Node*)codec->ActiveQP != codec->scenegraph->global_qp) ) + if (codec->ActiveQP && ((GF_Node*)codec->ActiveQP != codec->scenegraph->global_qp) ) gf_list_insert(codec->QPs, codec->ActiveQP, 0); - + codec->ActiveQP = (M_QuantizationParameter *)qp; return GF_OK; } @@ -88,7 +91,7 @@ Fixed gf_bifs_dec_mantissa_float(GF_BifsDecoder *codec, GF_BitStream *bs) u32 mantLength, expLength, mantSign, mantissa, expSign, exponent; unsigned char exp; - union { + union { Float f; long l; } ft_value; @@ -235,7 +238,7 @@ GF_Err Q_DecFloat(GF_BifsDecoder *codec, GF_BitStream *bs, u32 FieldType, SFVec3 case GF_SG_VRML_SFINT32: return GF_NON_COMPLIANT_BITSTREAM; case GF_SG_VRML_SFFLOAT: - *((SFFloat *)field_ptr) = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits)); + *((SFFloat *)field_ptr) = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits)); return GF_OK; case GF_SG_VRML_SFVEC2F: ((SFVec2f *)field_ptr)->x = Q_InverseQuantize(BMin.x, BMax.x, NbBits, gf_bs_read_int(bs, NbBits)); @@ -274,11 +277,12 @@ GF_Err Q_DecInt(GF_BifsDecoder *codec, GF_BitStream *bs, u32 QType, SFInt32 b_mi } } -//SFRotation and SFVec3f are quantized as normalized vectors ,mapped on a cube +//SFRotation and SFVec3f are quantized as normalized vectors ,mapped on a cube //in the UnitSphere (R=1.0) GF_Err Q_DecCoordOnUnitSphere(GF_BifsDecoder *codec, GF_BitStream *bs, u32 NbBits, u32 NbComp, Fixed *m_ft) { - u32 i, orient, value, sign; + u32 i, orient, sign; + s32 value; Fixed tang[4], delta; s32 dir; @@ -289,7 +293,7 @@ GF_Err Q_DecCoordOnUnitSphere(GF_BifsDecoder *codec, GF_BitStream *bs, u32 NbBit if(NbComp == 2) dir -= 2 * gf_bs_read_int(bs, 1); orient = gf_bs_read_int(bs, 2); - + for(i=0; i<NbComp; i++) { value = gf_bs_read_int(bs, NbBits) - (1 << (NbBits-1) ); sign = (value >= 0) ? 1 : -1; @@ -304,7 +308,7 @@ GF_Err Q_DecCoordOnUnitSphere(GF_BifsDecoder *codec, GF_BitStream *bs, u32 NbBit m_ft[orient] = delta; for (i=0; i<NbComp; i++) { - m_ft[ (orient + i+1) % (NbComp+1) ] = gf_mulfix(tang[i], delta); + m_ft[ (orient + i+1) % (NbComp+1) ] = gf_mulfix(tang[i], delta); } return GF_OK; } @@ -375,7 +379,7 @@ GF_Err gf_bifs_dec_unquant_field(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Nod default: return GF_EOS; } - + /*check NDT*/ HasQ = gf_bifs_get_aq_info(node, field->fieldIndex, &QType, &AType, &b_min, &b_max, &NbBits); if (!HasQ || !QType) return GF_EOS; @@ -432,3 +436,4 @@ GF_Err gf_bifs_dec_unquant_field(GF_BifsDecoder *codec, GF_BitStream *bs, GF_Nod return GF_OK; } +#endif /*GPAC_DISABLE_BIFS*/ diff --git a/src/compositor/audio_input.c b/src/compositor/audio_input.c index ad2e7bf..74fd9e4 100644 --- a/src/compositor/audio_input.c +++ b/src/compositor/audio_input.c @@ -24,13 +24,37 @@ #include <gpac/internal/compositor_dev.h> +#define ENABLE_EARLY_FRAME_DETECTION #define MIN_RESYNC_TIME 500 +/*diff time in ms to consider an audio frame too early and insert silence*/ +#define MIN_RESYNC_TIME 500 +/*diff time in ms to consider an audio frame too late and drop it*/ +#define MAX_RESYNC_TIME 500 + +struct __audiofilteritem +{ + GF_AudioInterface input; + GF_AudioInterface *src; + + u32 out_chan, out_ch_cfg; + + u32 nb_used, nb_filled; + + GF_AudioFilterChain filter_chain; +}; + + +GF_AudioFilterItem *gf_af_new(GF_Compositor *compositor, GF_AudioInterface *src, char *filter_name); +void gf_af_del(GF_AudioFilterItem *af); +void gf_af_reset(GF_AudioFilterItem *af); + static char *gf_audio_input_fetch_frame(void *callback, u32 *size, u32 audio_delay_ms) { char *frame; u32 obj_time, ts; - s32 drift; + s32 drift, resync_delay; + 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*/ if (!ai->stream) return NULL; @@ -41,35 +65,40 @@ static char *gf_audio_input_fetch_frame(void *callback, u32 *size, u32 audio_del /*no more data or not enough data, reset syncro drift*/ if (!frame) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Audio Input] No data in audio object (eos %d)\n", ai->stream_finished)); + GF_LOG(GF_LOG_INFO, GF_LOG_AUDIO, ("[Audio Input] No data in audio object (eos %d)\n", ai->stream_finished)); gf_mo_adjust_clock(ai->stream, 0); return NULL; } 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; drift = (s32)obj_time; drift -= (s32)ts; +#ifdef ENABLE_EARLY_FRAME_DETECTION /*too early (silence insertions), skip*/ - if (drift + (s32) (audio_delay_ms + ai->is_open) < 0) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Audio Input] audio too early %d (CTS %d)\n", drift + audio_delay_ms + MIN_RESYNC_TIME, ts)); + 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)); ai->need_release = 0; gf_mo_release_data(ai->stream, 0, 0); return NULL; } +#endif /*adjust drift*/ if (audio_delay_ms) { + 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>500) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Audio Input] Audio data too late (drift %d ms) - resync forced\n", drift)); + 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)); gf_mo_release_data(ai->stream, *size, 2); ai->need_release = 0; return gf_audio_input_fetch_frame(callback, size, audio_delay_ms); } - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Audio Input] Audio clock: delay %d - obj time %d - CTS %d - adjust drift %d\n", audio_delay_ms, obj_time - audio_delay_ms, ts, drift)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[Audio Input] Audio clock: delay %d - obj time %d - CTS %d - adjust drift %d\n", audio_delay_ms, obj_time - audio_delay_ms, ts, drift)); gf_mo_adjust_clock(ai->stream, drift); } return frame; @@ -81,14 +110,14 @@ 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 resynbc tolerance*/ + /*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) { GF_AudioInput *ai = (GF_AudioInput *) callback; - return gf_mo_get_speed(ai->stream, ai->speed); + return gf_mo_get_current_speed(ai->stream); } static Bool gf_audio_input_get_volume(void *callback, Fixed *vol) @@ -148,29 +177,45 @@ void gf_sc_audio_setup(GF_AudioInput *ai, GF_Compositor *compositor, GF_Node *no ai->intensity = FIX_ONE; ai->speed = FIX_ONE; + } +void gf_sc_audio_predestroy(GF_AudioInput *ai) +{ + gf_sc_audio_stop(ai); + gf_sc_audio_unregister(ai); + if (ai->filter) gf_af_del(ai->filter); +} GF_EXPORT GF_Err gf_sc_audio_open(GF_AudioInput *ai, MFURL *url, Double clipBegin, Double clipEnd) { + u32 i; if (ai->is_open) return GF_BAD_PARAM; /*get media object*/ - ai->stream = gf_mo_register(ai->owner, url, 0); + ai->stream = gf_mo_register(ai->owner, url, 0, 0); /*bad URL*/ if (!ai->stream) return GF_NOT_SUPPORTED; - /*store url*/ - gf_sg_vrml_field_copy(&ai->url, url, GF_SG_VRML_MFURL); - /*request play*/ gf_mo_play(ai->stream, clipBegin, clipEnd, 0); ai->stream_finished = 0; ai->is_open = 1; gf_mo_set_flag(ai->stream, GF_MO_IS_INIT, 0); + + if (ai->filter) gf_af_del(ai->filter); + ai->filter = NULL; + + for (i=0; i<url->count; i++) { + if (url->vals[i].url && !strnicmp(url->vals[i].url, "#filter=", 8)) { + ai->filter = gf_af_new(ai->compositor, &ai->input_ifce, url->vals[i].url+8); + if (ai->filter) + break; + } + } return GF_OK; } @@ -185,11 +230,13 @@ void gf_sc_audio_stop(GF_AudioInput *ai) assert(!ai->need_release); gf_mo_stop(ai->stream); - gf_sg_vrml_mf_reset(&ai->url, GF_SG_VRML_MFURL); ai->is_open = 0; gf_mo_unregister(ai->owner, ai->stream); ai->stream = NULL; + if (ai->filter) gf_af_del(ai->filter); + ai->filter = NULL; + gf_mixer_lock(ai->compositor->audio_renderer->mixer, 0); } @@ -201,6 +248,7 @@ void gf_sc_audio_restart(GF_AudioInput *ai) if (ai->need_release) gf_mo_release_data(ai->stream, 0xFFFFFFFF, 2); ai->need_release = 0; ai->stream_finished = 0; + if (ai->filter) gf_af_reset(ai->filter); gf_mo_restart(ai->stream); } @@ -214,6 +262,8 @@ Bool gf_sc_audio_check_url(GF_AudioInput *ai, MFURL *url) GF_EXPORT void gf_sc_audio_register(GF_AudioInput *ai, GF_TraverseState *tr_state) { + GF_AudioInterface *aifce; + /*check interface is valid*/ if (!ai->input_ifce.FetchFrame || !ai->input_ifce.GetChannelVolume @@ -223,11 +273,14 @@ void gf_sc_audio_register(GF_AudioInput *ai, GF_TraverseState *tr_state) || !ai->input_ifce.ReleaseFrame ) return; + aifce = &ai->input_ifce; + if (ai->filter) aifce = &ai->filter->input; + if (tr_state->audio_parent) { /*this assume only one parent may use an audio node*/ if (ai->register_with_parent) return; if (ai->register_with_renderer) { - gf_sc_ar_remove_src(ai->compositor->audio_renderer, &ai->input_ifce); + gf_sc_ar_remove_src(ai->compositor->audio_renderer, aifce); ai->register_with_renderer = 0; } tr_state->audio_parent->add_source(tr_state->audio_parent, ai); @@ -241,7 +294,7 @@ void gf_sc_audio_register(GF_AudioInput *ai, GF_TraverseState *tr_state) gf_sc_invalidate(ai->compositor, NULL); } - gf_sc_ar_add_src(ai->compositor->audio_renderer, &ai->input_ifce); + gf_sc_ar_add_src(ai->compositor->audio_renderer, aifce); ai->register_with_renderer = 1; ai->snd = tr_state->sound_holder; } @@ -250,9 +303,12 @@ void gf_sc_audio_register(GF_AudioInput *ai, GF_TraverseState *tr_state) GF_EXPORT void gf_sc_audio_unregister(GF_AudioInput *ai) { + GF_AudioInterface *aifce = &ai->input_ifce; + if (ai->filter) aifce = &ai->filter->input; + if (ai->register_with_renderer) { ai->register_with_renderer = 0; - gf_sc_ar_remove_src(ai->compositor->audio_renderer, &ai->input_ifce); + gf_sc_ar_remove_src(ai->compositor->audio_renderer, aifce); } else { /*if used in a parent audio group, do a complete traverse to rebuild the group*/ gf_sc_invalidate(ai->compositor, NULL); @@ -260,3 +316,113 @@ void gf_sc_audio_unregister(GF_AudioInput *ai) } +static char *gf_af_fetch_frame(void *callback, u32 *size, u32 audio_delay_ms) +{ + GF_AudioFilterItem *af = (GF_AudioFilterItem *)callback; + + *size = 0; + if (!af->nb_used) { + /*force filling the filter chain output until no data is available, otherwise we may end up + with data in input and no data as output because of block framing of the filter chain*/ + while (!af->nb_filled) { + u32 nb_bytes; + char *data = af->src->FetchFrame(af->src->callback, &nb_bytes, audio_delay_ms + af->filter_chain.delay_ms); + /*no input data*/ + if (!data || !nb_bytes) + return NULL; + + if (nb_bytes > af->filter_chain.min_block_size) nb_bytes = af->filter_chain.min_block_size; + memcpy(af->filter_chain.tmp_block1, data, nb_bytes); + af->src->ReleaseFrame(af->src->callback, nb_bytes); + + af->nb_filled = gf_afc_process(&af->filter_chain, nb_bytes); + } + } + + *size = af->nb_filled - af->nb_used; + return af->filter_chain.tmp_block1 + af->nb_used; +} +static void gf_af_release_frame(void *callback, u32 nb_bytes) +{ + GF_AudioFilterItem *af = (GF_AudioFilterItem *)callback; + /*mark used bytes of filter output*/ + af->nb_used += nb_bytes; + if (af->nb_used==af->nb_filled) { + af->nb_used = 0; + af->nb_filled = 0; + } +} + +static Fixed gf_af_get_speed(void *callback) +{ + GF_AudioFilterItem *af = (GF_AudioFilterItem *)callback; + return af->src->GetSpeed(af->src->callback); +} +static Bool gf_af_get_channel_volume(void *callback, Fixed *vol) +{ + GF_AudioFilterItem *af = (GF_AudioFilterItem *)callback; + return af->src->GetChannelVolume(af->src->callback, vol); +} + +static Bool gf_af_is_muted(void *callback) +{ + GF_AudioFilterItem *af = (GF_AudioFilterItem *)callback; + return af->src->IsMuted(af->src->callback); +} + +static Bool gf_af_get_config(GF_AudioInterface *ai, Bool for_reconf) +{ + GF_AudioFilterItem *af = (GF_AudioFilterItem *)ai->callback; + + Bool res = af->src->GetConfig(af->src, for_reconf); + if (!res) return 0; + if (!for_reconf) return 1; + + + af->input.bps = af->src->bps; + af->input.samplerate = af->src->samplerate; + + af->input.ch_cfg = af->src->ch_cfg; + af->input.chan = af->src->chan; + + if (gf_afc_setup(&af->filter_chain, af->input.bps, af->input.samplerate, af->src->chan, af->src->ch_cfg, &af->input.chan, &af->input.ch_cfg)!=GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_AUDIO, ("[Audio Input] Failed to configure audio filter chain\n")); + + return 0; + } + return 1; +} + +GF_AudioFilterItem *gf_af_new(GF_Compositor *compositor, GF_AudioInterface *src, char *filter_name) +{ + GF_AudioFilterItem *filter; + GF_AudioFilter *filter_module = NULL; + if (!src || !filter_name) return NULL; + + GF_SAFEALLOC(filter, GF_AudioFilterItem); + + filter->src = src; + filter->input.FetchFrame = gf_af_fetch_frame; + filter->input.ReleaseFrame = gf_af_release_frame; + filter->input.GetSpeed = gf_af_get_speed; + filter->input.GetChannelVolume = gf_af_get_channel_volume; + filter->input.IsMuted = gf_af_is_muted; + filter->input.GetConfig = gf_af_get_config; + filter->input.callback = filter; + + gf_afc_load(&filter->filter_chain, compositor->user, filter_name); + return filter; +} + +void gf_af_del(GF_AudioFilterItem *af) +{ + gf_afc_unload(&af->filter_chain); + gf_free(af); +} + +void gf_af_reset(GF_AudioFilterItem *af) +{ + gf_afc_reset(&af->filter_chain); + + af->nb_filled = af->nb_used = 0; +} diff --git a/src/compositor/audio_mixer.c b/src/compositor/audio_mixer.c index 5a35211..2be4037 100644 --- a/src/compositor/audio_mixer.c +++ b/src/compositor/audio_mixer.c @@ -78,7 +78,7 @@ struct __audiomix GF_AudioMixer *gf_mixer_new(struct _audio_render *ar) { GF_AudioMixer *am; - am = (GF_AudioMixer *) malloc(sizeof(GF_AudioMixer)); + am = (GF_AudioMixer *) gf_malloc(sizeof(GF_AudioMixer)); if (!am) return NULL; memset(am, 0, sizeof(GF_AudioMixer)); am->mx = gf_mx_new("AudioMix"); @@ -102,8 +102,8 @@ void gf_mixer_del(GF_AudioMixer *am) { gf_list_del(am->sources); gf_mx_del(am->mx); - if (am->output) free(am->output); - free(am); + if (am->output) gf_free(am->output); + gf_free(am); } void gf_mixer_remove_all(GF_AudioMixer *am) @@ -114,9 +114,9 @@ void gf_mixer_remove_all(GF_AudioMixer *am) MixerInput *in = (MixerInput *)gf_list_get(am->sources, 0); gf_list_rem(am->sources, 0); for (j=0; j<GF_SR_MAX_CHANNELS; j++) { - if (in->ch_buf[j]) free(in->ch_buf[j]); + if (in->ch_buf[j]) gf_free(in->ch_buf[j]); } - free(in); + gf_free(in); } am->isEmpty = 1, gf_mixer_lock(am, 0); @@ -186,9 +186,9 @@ void gf_mixer_remove_input(GF_AudioMixer *am, GF_AudioInterface *src) if (in->src != src) continue; gf_list_rem(am->sources, i); for (j=0; j<GF_SR_MAX_CHANNELS; j++) { - if (in->ch_buf[j]) free(in->ch_buf[j]); + if (in->ch_buf[j]) gf_free(in->ch_buf[j]); } - free(in); + gf_free(in); break; } am->isEmpty = gf_list_count(am->sources) ? 0 : 1; @@ -478,13 +478,14 @@ static void gf_mixer_fetch_input(GF_AudioMixer *am, MixerInput *in, u32 audio_de i = 0; next = prev = 0; while (1) { - prev = (u32) (i*ratio + 1) / 255; + prev = (u32) (i*ratio) / 255; if (prev>=src_samp) break; next = prev+1; frac = (i*ratio) - 255*prev; if (frac && (next==src_samp)) break; - if (use_prev && prev) use_prev = 0; + if (use_prev && prev) + use_prev = 0; if (in_s16) { for (j=0; j<in_ch; j++) { @@ -529,7 +530,12 @@ static void gf_mixer_fetch_input(GF_AudioMixer *am, MixerInput *in, u32 audio_de in->in_bytes_used = src_size; for (j=0; j<in_ch; j++) in->last_channels[j] = inChanNext[j]; } else { - for (j=0; j<in_ch; j++) in->last_channels[j] = in_s16 ? in_s16[in_ch*prev + j] : in_s8[in_ch*prev + j]; + u32 idx; + idx = (prev>=src_samp) ? in_ch*(src_samp-1) : in_ch*prev; + for (j=0; j<in_ch; j++) { + assert(idx + j < src_size/2); + in->last_channels[j] = in_s16 ? in_s16[idx + j] : in_s8[idx + j]; + } } } } @@ -538,12 +544,12 @@ static void gf_mixer_fetch_input(GF_AudioMixer *am, MixerInput *in, u32 audio_de } -u32 gf_mixer_get_output(GF_AudioMixer *am, void *buffer, u32 buffer_size) +u32 gf_mixer_get_output(GF_AudioMixer *am, void *buffer, u32 buffer_size, u32 delay) { MixerInput *in, *single_source; Fixed pan[6]; Bool is_muted; - u32 i, j, count, size, in_size, nb_samples, delay, nb_written; + u32 i, j, count, size, in_size, nb_samples, nb_written; s32 *out_mix, nb_act_src; char *data, *ptr; @@ -557,8 +563,6 @@ u32 gf_mixer_get_output(GF_AudioMixer *am, void *buffer, u32 buffer_size) gf_mixer_lock(am, 0); return 0; } - delay = 0; - if (am->ar && !am->ar->disable_resync) delay = am->ar->audio_delay; single_source = NULL; if (count!=1) goto do_mix; @@ -572,6 +576,7 @@ u32 gf_mixer_get_output(GF_AudioMixer *am, void *buffer, u32 buffer_size) gf_mixer_lock(am, 0); return 0; } + /*this happens if input SR cannot be mapped to output audio hardware*/ if (single_source->src->samplerate != am->sample_rate) goto do_mix; /*note we don't check output cfg: if the number of channel is the same then the channel cfg is the @@ -605,7 +610,7 @@ single_source_mix: /*not completely filled*/ if (buffer_size) { if (!data) { - GF_LOG(GF_LOG_WARNING, GF_LOG_COMPOSE, ("[AudioMixer] not enough input data (%d still to fill)\n", buffer_size)); + GF_LOG(GF_LOG_WARNING, GF_LOG_AUDIO, ("[AudioMixer] not enough input data (%d still to fill)\n", buffer_size)); } memset(ptr, 0, buffer_size); } @@ -617,8 +622,8 @@ do_mix: nb_samples = buffer_size / (am->nb_channels * am->bits_per_sample / 8); /*step 1, cfg*/ if (am->output_size<buffer_size) { - if (am->output) free(am->output); - am->output = (s32*)malloc(sizeof(s32) * buffer_size); + if (am->output) gf_free(am->output); + am->output = (s32*)gf_malloc(sizeof(s32) * buffer_size); am->output_size = buffer_size; } @@ -629,8 +634,8 @@ do_mix: if (in->buffer_size < nb_samples) { for (j=0; j<GF_SR_MAX_CHANNELS; j++) { - if (in->ch_buf[j]) free(in->ch_buf[j]); - in->ch_buf[j] = (s32 *) malloc(sizeof(s32) * nb_samples); + if (in->ch_buf[j]) gf_free(in->ch_buf[j]); + in->ch_buf[j] = (s32 *) gf_malloc(sizeof(s32) * nb_samples); } in->buffer_size = nb_samples; } diff --git a/src/compositor/audio_render.c b/src/compositor/audio_render.c index 793f1bc..53e5f52 100644 --- a/src/compositor/audio_render.c +++ b/src/compositor/audio_render.c @@ -24,17 +24,242 @@ #include <gpac/internal/compositor_dev.h> +GF_Err gf_afc_load(GF_AudioFilterChain *afc, GF_User *user, char *filterstring) +{ + struct _audiofilterentry *prev_filter = NULL; + + while (filterstring) { + u32 i, count; + GF_AudioFilter *filter; + char *sep = strstr(filterstring, ";;"); + if (sep) sep[0] = 0; + + count = gf_modules_get_count(user->modules); + filter = NULL; + for (i=0; i<count; i++) { + filter = (GF_AudioFilter *)gf_modules_load_interface(user->modules, i, GF_AUDIO_FILTER_INTERFACE); + if (filter) { + if (filter->SetFilter + && filter->Configure + && filter->Process + && filter->Reset + && filter->SetOption + && filter->GetOption + && filter->SetFilter(filter, filterstring) + ) + break; + + gf_modules_close_interface((GF_BaseInterface *)filter); + } + filter = NULL; + } + if (filter) { + struct _audiofilterentry *entry; + GF_SAFEALLOC(entry, struct _audiofilterentry); + entry->filter = filter; + if (prev_filter) prev_filter->next = entry; + else afc->filters = entry; + prev_filter = entry; + } + if (sep) { + sep[0] = ';'; + filterstring = sep + 2; + } else { + break; + } + } + return GF_OK; +} + +GF_Err gf_afc_setup(GF_AudioFilterChain *afc, u32 bps, u32 sr, u32 chan, u32 ch_cfg, u32 *ch_out, u32 *ch_cfg_out) +{ + struct _audiofilterentry *entry; + u32 block_len; + u32 och, ocfg, in_ch; + Bool not_in_place; + + if (afc->tmp_block1) gf_free(afc->tmp_block1); + afc->tmp_block1 = NULL; + if (afc->tmp_block2) gf_free(afc->tmp_block2); + afc->tmp_block2 = NULL; + + in_ch = chan; + afc->min_block_size = 0; + afc->max_block_size = 0; + afc->delay_ms = 0; + + not_in_place = 0; + + entry = afc->filters; + while (entry) { + if (entry->in_block) { + gf_free(entry->in_block); + entry->in_block = NULL; + } + + if (entry->filter->Configure(entry->filter, sr, bps, chan, ch_cfg, &och, &ocfg, &block_len, &entry->delay_ms, &entry->in_place)==GF_OK) { + u32 out_block_size; + entry->in_block_size = chan * bps * block_len / 8; + if (!afc->min_block_size || (afc->min_block_size > entry->in_block_size)) + afc->min_block_size = entry->in_block_size; + + out_block_size = och * bps * block_len / 8; + if (afc->max_block_size < out_block_size) afc->max_block_size = out_block_size; + + entry->enable = 1; + chan = och; + ch_cfg = ocfg; + + if (!entry->in_place) not_in_place = 1; + + afc->delay_ms += entry->delay_ms; + } else { + entry->enable = 0; + } + entry = entry->next; + } + + if (!afc->max_block_size) afc->max_block_size = 1000; + if (!afc->min_block_size) afc->min_block_size = afc->max_block_size * in_ch / chan; + afc->tmp_block1 = gf_malloc(sizeof(char) * afc->max_block_size * 2); + if (!afc->tmp_block1) return GF_OUT_OF_MEM; + if (not_in_place) { + afc->tmp_block2 = gf_malloc(sizeof(char) * afc->max_block_size * 2); + if (!afc->tmp_block2) return GF_OUT_OF_MEM; + } + + /*alloc buffers*/ + entry = afc->filters; + while (entry) { + if (entry->enable && entry->in_block_size) { + entry->in_block = gf_malloc(sizeof(char) * (entry->in_block_size + afc->max_block_size) ); + if (!entry->in_block) return GF_OUT_OF_MEM; + } + entry = entry->next; + } + *ch_out = chan; + *ch_cfg_out = ch_cfg; + afc->enable_filters = 1; + return GF_OK; +} + +u32 gf_afc_process(GF_AudioFilterChain *afc, u32 nb_bytes) +{ + struct _audiofilterentry *entry = afc->filters; + + while (entry) { + char *inptr, *outptr; + if (!nb_bytes || !entry->enable) { + entry = entry->next; + continue; + } + inptr = afc->tmp_block1; + outptr = entry->in_place ? afc->tmp_block1 : afc->tmp_block2; + + /*sample-based input, process directly the data*/ + if (!entry->in_block) { + entry->filter->Process(entry->filter, inptr, nb_bytes, outptr, &nb_bytes); + } else { + u32 processed = 0; + u32 nb_bytes_out = 0; + + assert(nb_bytes + entry->nb_bytes <= entry->in_block_size + afc->max_block_size); + /*copy bytes in input*/ + memcpy(entry->in_block + entry->nb_bytes, inptr, nb_bytes); + entry->nb_bytes += nb_bytes; + + /*and process*/ + while (entry->nb_bytes >= entry->in_block_size) { + u32 done; + entry->filter->Process(entry->filter, entry->in_block + processed, entry->in_block_size, outptr + nb_bytes_out, &done); + done = entry->in_block_size; + nb_bytes_out += done; + entry->nb_bytes -= entry->in_block_size; + processed += entry->in_block_size; + } + /*move remaining data at the begining of the buffer*/ + if (processed && entry->nb_bytes) + memmove(entry->in_block, entry->in_block+processed, entry->nb_bytes); + + nb_bytes = nb_bytes_out; + } + + /*swap ptr so that input data of next step (filter, output write) is always in tmp_block1*/ + if (inptr != outptr) { + afc->tmp_block1 = outptr; + afc->tmp_block2 = inptr; + } + entry = entry->next; + } + return nb_bytes; +} + +void gf_afc_unload(GF_AudioFilterChain *afc) +{ + while (afc->filters) { + struct _audiofilterentry *tmp = afc->filters; + afc->filters = tmp->next; + gf_modules_close_interface((GF_BaseInterface *)tmp->filter); + if (tmp->in_block) gf_free(tmp->in_block); + gf_free(tmp); + } + if (afc->tmp_block1) gf_free(afc->tmp_block1); + if (afc->tmp_block2) gf_free(afc->tmp_block2); + memset(afc, 0, sizeof(GF_AudioFilterChain)); +} + +void gf_afc_reset(GF_AudioFilterChain *afc) +{ + struct _audiofilterentry *filter = afc->filters; + while (filter) { + filter->filter->Reset(filter->filter); + filter->nb_bytes = 0; + + filter = filter->next; + } +} + static GF_Err gf_ar_setup_output_format(GF_AudioRenderer *ar) { GF_Err e; u32 freq, nb_bits, nb_chan, ch_cfg; + u32 in_ch, in_cfg, in_bps, in_freq; + gf_mixer_get_config(ar->mixer, &freq, &nb_chan, &nb_bits, &ch_cfg); /*user disabled multichannel audio*/ if (ar->disable_multichannel && (nb_chan>2) ) nb_chan = 2; - e = ar->audio_out->ConfigureOutput(ar->audio_out, &freq, &nb_chan, &nb_bits, ch_cfg); + in_ch = nb_chan; + in_cfg = ch_cfg; + in_bps = nb_bits; + in_freq = freq; + + if (ar->filter_chain.filters) { + u32 osr, obps, och, ocfg; + + e = gf_afc_setup(&ar->filter_chain, nb_bits, freq, nb_chan, ch_cfg, &och, &ocfg); + osr = freq; + obps = nb_bits; + nb_chan = och; + + /*try to reconfigure audio output*/ + if (!e) + e = ar->audio_out->ConfigureOutput(ar->audio_out, &osr, &och, &obps, ocfg); + + /*output module cannot support filter output, disable it ...*/ + if (e || (osr != freq) || (och != nb_chan) || (obps != nb_bits)) { + nb_bits = in_bps; + freq = in_freq; + nb_chan = in_ch; + ar->filter_chain.enable_filters = 0; + e = ar->audio_out->ConfigureOutput(ar->audio_out, &freq, &nb_chan, &nb_bits, ch_cfg); + } + } else { + e = ar->audio_out->ConfigureOutput(ar->audio_out, &freq, &nb_chan, &nb_bits, ch_cfg); + } + if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[AudioRender] reconfigure error %e\n", e)); if (nb_chan>2) { @@ -43,20 +268,75 @@ static GF_Err gf_ar_setup_output_format(GF_AudioRenderer *ar) } if (e) return e; } - gf_mixer_set_config(ar->mixer, freq, nb_chan, nb_bits, ch_cfg); + gf_mixer_set_config(ar->mixer, in_freq, in_ch, in_bps, in_cfg); ar->audio_delay = ar->audio_out->GetAudioDelay(ar->audio_out); ar->audio_out->SetVolume(ar->audio_out, ar->volume); ar->audio_out->SetPan(ar->audio_out, ar->pan); + + if (ar->audio_listeners) { + u32 k=0; + GF_AudioListener *l; + while ((l = gf_list_enum(ar->audio_listeners, &k))) { + l->on_audio_reconfig(l->udta, in_freq, in_bps, in_ch, in_cfg); + } + } return GF_OK; } + + static u32 gf_ar_fill_output(void *ptr, char *buffer, u32 buffer_size) { + u32 written; GF_AudioRenderer *ar = (GF_AudioRenderer *) ptr; if (!ar->need_reconfig) { - return gf_mixer_get_output(ar->mixer, buffer, buffer_size); + u32 delay_ms = ar->disable_resync ? 0 : ar->audio_delay; + + if (ar->filter_chain.enable_filters) { + char *ptr = buffer; + u32 res = buffer_size; + written = 0; + delay_ms += ar->filter_chain.delay_ms; + + while (buffer_size) { + u32 to_copy; + if (!ar->nb_used) { + u32 nb_bytes; + + /*fill input block*/ + nb_bytes = gf_mixer_get_output(ar->mixer, ar->filter_chain.tmp_block1, ar->filter_chain.min_block_size, delay_ms); + if (!nb_bytes) + return written; + + /*delay used to check for late frames - we only use it on the first call to gf_mixer_get_output()*/ + delay_ms = 0; + + ar->nb_filled = gf_afc_process(&ar->filter_chain, nb_bytes); + if (!ar->nb_filled) continue; + } + to_copy = ar->nb_filled - ar->nb_used; + if (to_copy>buffer_size) to_copy = buffer_size; + memcpy(ptr, ar->filter_chain.tmp_block1 + ar->nb_used, to_copy); + ptr += to_copy; + buffer_size -= to_copy; + written += to_copy; + ar->nb_used += to_copy; + if (ar->nb_used==ar->nb_filled) ar->nb_used = 0; + } + assert(res==written); + } else { + written = gf_mixer_get_output(ar->mixer, buffer, buffer_size, delay_ms); + } + if (ar->audio_listeners) { + u32 k=0; + GF_AudioListener *l; + while ((l = gf_list_enum(ar->audio_listeners, &k))) { + l->on_audio_frame(l->udta, buffer, written, gf_sc_ar_get_clock(ar), delay_ms); + } + } + return written; } return 0; } @@ -75,7 +355,7 @@ u32 gf_ar_proc(void *p) gf_mixer_lock(ar->mixer, 0); while (ar->audio_th_state == 1) { - //GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[AudioRender] Audio simulation step\n")); + //GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Audio simulation step\n")); /*THIS IS NEEDED FOR SYMBIAN - if no yield here, the audio module always grabs the main mixer mutex and it takes forever before it can be grabed by another thread, @@ -92,7 +372,7 @@ u32 gf_ar_proc(void *p) gf_mixer_lock(ar->mixer, 0); } } - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[AudioRender] Exiting audio thread\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Exiting audio thread\n")); ar->audio_out->Shutdown(ar->audio_out); ar->audio_th_state = 3; return 0; @@ -106,7 +386,7 @@ GF_AudioRenderer *gf_sc_ar_load(GF_User *user) u32 num_buffers, total_duration; GF_Err e; GF_AudioRenderer *ar; - ar = (GF_AudioRenderer *) malloc(sizeof(GF_AudioRenderer)); + ar = (GF_AudioRenderer *) gf_malloc(sizeof(GF_AudioRenderer)); memset(ar, 0, sizeof(GF_AudioRenderer)); num_buffers = total_duration = 0; @@ -147,7 +427,7 @@ GF_AudioRenderer *gf_sc_ar_load(GF_User *user) for (i=0; i<count; i++) { ar->audio_out = (GF_AudioOutput *) gf_modules_load_interface(ar->user->modules, i, GF_AUDIO_OUTPUT_INTERFACE); if (!ar->audio_out) continue; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[AudioRender] Audio output module %s loaded\n", ar->audio_out->module_name)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Audio output module %s loaded\n", ar->audio_out->module_name)); /*check that's a valid audio compositor*/ if (ar->audio_out->SelfThreaded) { if (ar->audio_out->SetPriority) break; @@ -161,13 +441,17 @@ GF_AudioRenderer *gf_sc_ar_load(GF_User *user) /*if not init we run with a NULL audio compositor*/ if (ar->audio_out) { + struct _audiofilterentry *prev_filter=NULL; + ar->audio_out->FillBuffer = gf_ar_fill_output; ar->audio_out->audio_renderer = ar; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[AudioRender] Setting up audio module %s\n", ar->audio_out->module_name)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Setting up audio module %s\n", ar->audio_out->module_name)); e = ar->audio_out->Setup(ar->audio_out, ar->user->os_window_handler, num_buffers, total_duration); - /*if audio module is not threaded, reconfigure it from our own thread*/ -// if (e==GF_OK) e = gf_ar_setup_output_format(ar); + + /*load main audio filter*/ + gf_afc_load(&ar->filter_chain, user, (char*)gf_cfg_get_key(user->config, "Audio", "Filter")); + if (e != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("Could not setup audio out %s\n", ar->audio_out->module_name)); @@ -197,21 +481,21 @@ void gf_sc_ar_del(GF_AudioRenderer *ar) { if (!ar) return; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[AudioRender] Destroying compositor\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Destroying compositor\n")); /*resume if paused (might cause deadlock otherwise)*/ if (ar->Frozen) gf_sc_ar_control(ar, 1); /*stop and shutdown*/ if (ar->audio_out) { /*kill audio thread*/ if (!ar->audio_out->SelfThreaded) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[AudioRender] stoping audio thread\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] stoping audio thread\n")); ar->audio_th_state = 2; while (ar->audio_th_state != 3) { gf_sleep(33); } - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[AudioRender] audio thread stopped\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] audio thread stopped\n")); gf_th_del(ar->th); - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[AudioRender] audio thread destroyed\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] audio thread destroyed\n")); } /*lock access before shutdown and emulate a reconfig (avoids mixer lock from self-threaded modules)*/ ar->need_reconfig = 1; @@ -221,8 +505,11 @@ void gf_sc_ar_del(GF_AudioRenderer *ar) gf_mixer_lock(ar->mixer, 0); } gf_mixer_del(ar->mixer); - free(ar); - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[AudioRender] Renderer destroyed\n")); + + if (ar->audio_listeners) gf_list_del(ar->audio_listeners); + gf_afc_unload(&ar->filter_chain); + gf_free(ar); + GF_LOG(GF_LOG_DEBUG, GF_LOG_AUDIO, ("[AudioRender] Renderer destroyed\n")); } @@ -266,6 +553,15 @@ void gf_sc_ar_set_volume(GF_AudioRenderer *ar, u32 Volume) gf_mixer_lock(ar->mixer, 0); } + +void gf_sc_ar_mute(GF_AudioRenderer *ar, Bool mute) +{ + gf_mixer_lock(ar->mixer, 1); + ar->mute = mute; + if (ar->audio_out) ar->audio_out->SetVolume(ar->audio_out, mute ? 0 : ar->volume); + gf_mixer_lock(ar->mixer, 0); +} + void gf_sc_ar_set_pan(GF_AudioRenderer *ar, u32 Balance) { gf_mixer_lock(ar->mixer, 1); @@ -318,10 +614,8 @@ void gf_sc_ar_reconfig(GF_AudioRenderer *ar) gf_mixer_lock(ar->mixer, 1); gf_ar_freeze_intern(ar, 1, 1, 0); - - ar->need_reconfig = 0; + ar->need_reconfig = 0; gf_ar_setup_output_format(ar); - gf_ar_freeze_intern(ar, 0, 1, 0); /*unlock mixer*/ @@ -339,3 +633,48 @@ u32 gf_sc_ar_get_clock(GF_AudioRenderer *ar) if (ar->Frozen) return ar->FreezeTime - ar->startTime; return gf_sys_clock() - ar->startTime; } +void gf_sc_reload_audio_filters(GF_Compositor *compositor) +{ + GF_AudioRenderer *ar = compositor->audio_renderer; + if (!ar) return; + + gf_mixer_lock(ar->mixer, 1); + + gf_afc_unload(&ar->filter_chain); + gf_afc_load(&ar->filter_chain, ar->user, (char*)gf_cfg_get_key(ar->user->config, "Audio", "Filter")); + + gf_ar_freeze_intern(ar, 1, 1, 0); + ar->need_reconfig = 0; + gf_ar_setup_output_format(ar); + gf_ar_freeze_intern(ar, 0, 1, 0); + + gf_mixer_lock(ar->mixer, 0); +} + + +GF_Err gf_sc_add_audio_listener(GF_Compositor *compositor, GF_AudioListener *al) +{ + if (!compositor || !al || !al->on_audio_frame || !al->on_audio_reconfig) return GF_BAD_PARAM; + if (!compositor->audio_renderer) return GF_NOT_SUPPORTED; + + gf_mixer_lock(compositor->audio_renderer->mixer, 1); + if (!compositor->audio_renderer->audio_listeners) compositor->audio_renderer->audio_listeners = gf_list_new(); + gf_list_add(compositor->audio_renderer->audio_listeners, al); + gf_mixer_lock(compositor->audio_renderer->mixer, 0); + return GF_OK; +} + +GF_Err gf_sc_remove_audio_listener(GF_Compositor *compositor, GF_AudioListener *al) +{ + if (!compositor || !al) return GF_BAD_PARAM; + if (!compositor->audio_renderer) return GF_NOT_SUPPORTED; + + gf_mixer_lock(compositor->audio_renderer->mixer, 1); + gf_list_del_item(compositor->audio_renderer->audio_listeners, al); + if (!gf_list_count(compositor->audio_renderer->audio_listeners)) { + gf_list_del(compositor->audio_renderer->audio_listeners); + compositor->audio_renderer->audio_listeners = NULL; + } + gf_mixer_lock(compositor->audio_renderer->mixer, 0); + return GF_OK; +} diff --git a/src/compositor/bindable.c b/src/compositor/bindable.c index c48983a..5bdf431 100644 --- a/src/compositor/bindable.c +++ b/src/compositor/bindable.c @@ -24,6 +24,8 @@ #include "nodes_stacks.h" +#ifndef GPAC_DISABLE_VRML + GF_List *Bindable_GetStack(GF_Node *bindable) { void *st; @@ -33,12 +35,22 @@ GF_List *Bindable_GetStack(GF_Node *bindable) case TAG_MPEG4_Background2D: return ((Background2DStack*)st)->reg_stacks; case TAG_MPEG4_Viewport: case TAG_MPEG4_NavigationInfo: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_NavigationInfo: +#endif return ((ViewStack*)st)->reg_stacks; #ifndef GPAC_DISABLE_3D - case TAG_MPEG4_Background: case TAG_X3D_Background: return ((BackgroundStack*)st)->reg_stacks; - case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: - case TAG_MPEG4_Fog: case TAG_X3D_Fog: + case TAG_MPEG4_Background: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Background: +#endif + return ((BackgroundStack*)st)->reg_stacks; + case TAG_MPEG4_Viewpoint: + case TAG_MPEG4_Fog: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Viewpoint: + case TAG_X3D_Fog: +#endif return ((ViewStack*)st)->reg_stacks; #endif default: return NULL; @@ -51,10 +63,26 @@ Bool Bindable_GetIsBound(GF_Node *bindable) switch (gf_node_get_tag(bindable)) { case TAG_MPEG4_Background2D: return ((M_Background2D*)bindable)->isBound; case TAG_MPEG4_Viewport: return ((M_Viewport*)bindable)->isBound; - case TAG_MPEG4_Background: case TAG_X3D_Background: return ((M_Background*)bindable)->isBound; - case TAG_MPEG4_NavigationInfo: case TAG_X3D_NavigationInfo: return ((M_NavigationInfo*)bindable)->isBound; - case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: return ((M_Viewpoint*)bindable)->isBound; - case TAG_MPEG4_Fog: case TAG_X3D_Fog: return ((M_Fog*)bindable)->isBound; + case TAG_MPEG4_Background: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Background: +#endif + return ((M_Background*)bindable)->isBound; + case TAG_MPEG4_NavigationInfo: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_NavigationInfo: +#endif + return ((M_NavigationInfo*)bindable)->isBound; + case TAG_MPEG4_Viewpoint: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Viewpoint: +#endif + return ((M_Viewpoint*)bindable)->isBound; + case TAG_MPEG4_Fog: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Fog: +#endif + return ((M_Fog*)bindable)->isBound; default: return 0; } } @@ -74,38 +102,47 @@ void Bindable_SetIsBound(GF_Node *bindable, Bool val) ((M_Viewport*)bindable)->bindTime = gf_node_get_scene_time(bindable); has_bind_time = 1; break; +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Background: if ( ((X_Background*)bindable)->isBound == val) return; ((X_Background*)bindable)->isBound = val; ((X_Background*)bindable)->bindTime = gf_node_get_scene_time(bindable); has_bind_time = 1; break; +#endif case TAG_MPEG4_Background: if ( ((M_Background*)bindable)->isBound == val) return; ((M_Background*)bindable)->isBound = val; break; +#ifndef GPAC_DISABLE_X3D case TAG_X3D_NavigationInfo: if ( ((X_NavigationInfo*)bindable)->isBound == val) return; ((X_NavigationInfo*)bindable)->isBound = val; ((X_NavigationInfo*)bindable)->bindTime = gf_node_get_scene_time(bindable); has_bind_time = 1; break; +#endif case TAG_MPEG4_NavigationInfo: if ( ((M_NavigationInfo*)bindable)->isBound == val) return; ((M_NavigationInfo*)bindable)->isBound = val; break; - case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: + case TAG_MPEG4_Viewpoint: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Viewpoint: +#endif if ( ((M_Viewpoint*)bindable)->isBound == val) return; ((M_Viewpoint*)bindable)->isBound = val; ((M_Viewpoint*)bindable)->bindTime = gf_node_get_scene_time(bindable); has_bind_time = 1; break; +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Fog: if ( ((X_Fog*)bindable)->isBound == val) return; ((X_Fog*)bindable)->isBound = val; ((X_Fog*)bindable)->bindTime = gf_node_get_scene_time(bindable); has_bind_time = 1; break; +#endif case TAG_MPEG4_Fog: if ( ((M_Fog*)bindable)->isBound == val) return; ((M_Fog*)bindable)->isBound = val; @@ -126,47 +163,79 @@ Bool Bindable_GetSetBind(GF_Node *bindable) switch (gf_node_get_tag(bindable)) { case TAG_MPEG4_Background2D: return ((M_Background2D*)bindable)->set_bind; case TAG_MPEG4_Viewport: return ((M_Viewport*)bindable)->set_bind; - case TAG_MPEG4_Background: case TAG_X3D_Background: return ((M_Background*)bindable)->set_bind; - case TAG_MPEG4_NavigationInfo: case TAG_X3D_NavigationInfo: return ((M_NavigationInfo*)bindable)->set_bind; - case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: return ((M_Viewpoint*)bindable)->set_bind; - case TAG_MPEG4_Fog: case TAG_X3D_Fog: return ((M_Fog*)bindable)->set_bind; + case TAG_MPEG4_Background: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Background: +#endif + return ((M_Background*)bindable)->set_bind; + case TAG_MPEG4_NavigationInfo: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_NavigationInfo: +#endif + return ((M_NavigationInfo*)bindable)->set_bind; + case TAG_MPEG4_Viewpoint: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Viewpoint: +#endif + return ((M_Viewpoint*)bindable)->set_bind; + case TAG_MPEG4_Fog: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Fog: +#endif + return ((M_Fog*)bindable)->set_bind; default: return 0; } } -void Bindable_SetSetBind(GF_Node *bindable, Bool val) +void Bindable_SetSetBindEx(GF_Node *bindable, Bool val, GF_List *stack) { if (!bindable) return; switch (gf_node_get_tag(bindable)) { case TAG_MPEG4_Background2D: ((M_Background2D*)bindable)->set_bind = val; - ((M_Background2D*)bindable)->on_set_bind(bindable); + ((M_Background2D*)bindable)->on_set_bind(bindable, NULL); break; case TAG_MPEG4_Viewport: ((M_Viewport*)bindable)->set_bind = val; - ((M_Viewport*)bindable)->on_set_bind(bindable); + ((M_Viewport*)bindable)->on_set_bind(bindable, (GF_Route*)stack); break; - case TAG_MPEG4_Background: case TAG_X3D_Background: + case TAG_MPEG4_Background: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Background: +#endif ((M_Background*)bindable)->set_bind = val; - ((M_Background*)bindable)->on_set_bind(bindable); + ((M_Background*)bindable)->on_set_bind(bindable, NULL); break; - case TAG_MPEG4_NavigationInfo: case TAG_X3D_NavigationInfo: + case TAG_MPEG4_NavigationInfo: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_NavigationInfo: +#endif ((M_NavigationInfo*)bindable)->set_bind = val; - ((M_NavigationInfo*)bindable)->on_set_bind(bindable); + ((M_NavigationInfo*)bindable)->on_set_bind(bindable, NULL); break; - case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: + case TAG_MPEG4_Viewpoint: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Viewpoint: +#endif ((M_Viewpoint*)bindable)->set_bind = val; - ((M_Viewpoint*)bindable)->on_set_bind(bindable); + ((M_Viewpoint*)bindable)->on_set_bind(bindable, NULL); break; - case TAG_MPEG4_Fog: case TAG_X3D_Fog: + case TAG_MPEG4_Fog: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Fog: +#endif ((M_Fog*)bindable)->set_bind = val; - ((M_Fog*)bindable)->on_set_bind(bindable); + ((M_Fog*)bindable)->on_set_bind(bindable, NULL); break; default: return; } } +void Bindable_SetSetBind(GF_Node *bindable, Bool val) +{ + Bindable_SetSetBindEx(bindable, val, NULL); +} -void Bindable_OnSetBind(GF_Node *bindable, GF_List *stack_list) +void Bindable_OnSetBind(GF_Node *bindable, GF_List *stack_list, GF_List *for_stack) { u32 i; Bool on_top, is_bound, set_bind; @@ -181,6 +250,8 @@ void Bindable_OnSetBind(GF_Node *bindable, GF_List *stack_list) i=0; while ((stack = (GF_List*)gf_list_enum(stack_list, &i))) { + if (for_stack && (for_stack!=stack)) continue; + on_top = (gf_list_get(stack, 0)==bindable) ? 1 : 0; if (!set_bind) { @@ -242,3 +313,4 @@ void PreDestroyBindable(GF_Node *bindable, GF_List *stack_list) } } +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/camera.c b/src/compositor/camera.c index 2e6165f..d280ed0 100644 --- a/src/compositor/camera.c +++ b/src/compositor/camera.c @@ -37,7 +37,7 @@ GF_Camera *new_camera() } void delete_camera(GF_Camera *cam) { - if (cam) free(cam); + if (cam) gf_free(cam); } void camera_invalidate(GF_Camera *cam) diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c index 009aff2..8ed97c9 100644 --- a/src/compositor/compositor.c +++ b/src/compositor/compositor.c @@ -28,59 +28,34 @@ #include <gpac/options.h> #include <gpac/utf.h> -#ifdef GPAC_TRISCOPE_MODE -#include "../src/compositor/triscope_renoir/triscope_renoir.h" -#endif - #include "nodes_stacks.h" #include "visual_manager.h" #include "texturing.h" -#ifdef TRISCOPE_TEST_FRAMERATE -#include "chrono.h" -#endif - #define SC_DEF_WIDTH 320 #define SC_DEF_HEIGHT 240 -/*macro for size event format/send*/ -#define GF_USER_SETSIZE(_user, _w, _h) \ - { \ - GF_Event evt; \ - if (_user->EventProc) { \ - evt.type = GF_EVENT_SIZE; \ - evt.size.width = _w; \ - evt.size.height = _h; \ - _user->EventProc(_user->opaque, &evt); \ - } \ - } - void gf_sc_simulation_tick(GF_Compositor *compositor); -GF_Err gf_sc_set_output_size(GF_Compositor *compositor, u32 Width, u32 Height) +void gf_sc_next_frame_state(GF_Compositor *compositor, u32 state) { - gf_sc_lock(compositor, 1); - /*FIXME: need to check for max resolution*/ - compositor->display_width = Width; - compositor->display_height = Height; - compositor->recompute_ar = 1; - compositor->draw_next_frame = 1; - gf_sc_lock(compositor, 0); - return GF_OK; + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Forcing frame redraw state: %d\n", state)); + compositor->frame_draw_type = state; } + static void gf_sc_set_fullscreen(GF_Compositor *compositor) { GF_Err e; if (!compositor->video_out->SetFullScreen) return; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Switching fullscreen %s\n", compositor->fullscreen ? "off" : "on")); + GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Compositor] Switching fullscreen %s\n", compositor->fullscreen ? "off" : "on")); /*move to FS*/ compositor->fullscreen = !compositor->fullscreen; - if (compositor->fullscreen && (compositor->scene_width>compositor->scene_height) + if (compositor->fullscreen && (compositor->scene_width>=compositor->scene_height) #ifndef GPAC_DISABLE_3D && !compositor->visual->type_3d #endif @@ -89,12 +64,18 @@ static void gf_sc_set_fullscreen(GF_Compositor *compositor) } else { e = compositor->video_out->SetFullScreen(compositor->video_out, compositor->fullscreen, &compositor->display_width, &compositor->display_height); } + if (e) { - GF_USER_MESSAGE(compositor->user, "Compositor", "Cannot switch to fullscreen", e); + GF_Event evt; + evt.type = GF_EVENT_MESSAGE; + evt.message.service = ""; + evt.message.message = "Cannot switch to fullscreen"; + evt.message.error = e; + gf_term_send_event(compositor->term, &evt); compositor->fullscreen = 0; e = compositor->video_out->SetFullScreen(compositor->video_out, 0, &compositor->display_width, &compositor->display_height); } - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] recomputing aspect ratio\n")); + GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Compositor] recomputing aspect ratio\n")); compositor->recompute_ar = 1; /*force signaling graphics reset*/ compositor->reset_graphics = 1; @@ -110,6 +91,7 @@ thread accessing the HW ressources static void gf_sc_reconfig_task(GF_Compositor *compositor) { GF_Event evt; + Bool notif_size=0; u32 width,height; /*reconfig audio if needed (non-threaded compositors)*/ @@ -121,6 +103,8 @@ static void gf_sc_reconfig_task(GF_Compositor *compositor) /*scene size has been overriden*/ if (compositor->msg_type & GF_SR_CFG_OVERRIDE_SIZE) { + GF_Event evt; + assert(!(compositor->override_size_flags & 2)); compositor->msg_type &= ~GF_SR_CFG_OVERRIDE_SIZE; compositor->override_size_flags |= 2; @@ -128,7 +112,11 @@ static void gf_sc_reconfig_task(GF_Compositor *compositor) height = compositor->scene_height; compositor->has_size_info = 1; gf_sc_set_size(compositor, width, height); - GF_USER_SETSIZE(compositor->user, width, height); + + evt.type = GF_EVENT_SIZE; + evt.size.width = width; + evt.size.height = height; + gf_term_send_event(compositor->term, &evt); } /*size changed from scene cfg: resize window first*/ if (compositor->msg_type & GF_SR_CFG_SET_SIZE) { @@ -136,7 +124,7 @@ static void gf_sc_reconfig_task(GF_Compositor *compositor) Bool restore_fs = compositor->fullscreen; compositor->msg_type &= ~GF_SR_CFG_SET_SIZE; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Changing display size to %d x %d\n", compositor->new_width, compositor->new_height)); + GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Compositor] Changing display size to %d x %d\n", compositor->new_width, compositor->new_height)); fs_width = fs_height = 0; if (restore_fs) { fs_width = compositor->display_width; @@ -158,9 +146,13 @@ static void gf_sc_reconfig_task(GF_Compositor *compositor) compositor->display_height = fs_height; compositor->recompute_ar = 1; } else { - gf_sc_set_output_size(compositor, evt.size.width, evt.size.height); + compositor->display_width = evt.size.width; + compositor->display_height = evt.size.height; + compositor->recompute_ar = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); } compositor->reset_graphics = 1; + notif_size=1; } /*aspect ratio modif*/ @@ -172,10 +164,18 @@ static void gf_sc_reconfig_task(GF_Compositor *compositor) if (compositor->msg_type & GF_SR_CFG_FULLSCREEN) { compositor->msg_type &= ~GF_SR_CFG_FULLSCREEN; gf_sc_set_fullscreen(compositor); - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); + notif_size=1; } compositor->msg_type &= ~GF_SR_IN_RECONFIG; } + if (notif_size && compositor->video_listeners) { + u32 k=0; + GF_VideoListener *l; + while ((l = gf_list_enum(compositor->video_listeners, &k))) { + l->on_video_reconfig(l->udta, compositor->display_width, compositor->display_height); + } + } /*3D driver changed message, recheck extensions*/ if (compositor->reset_graphics) { @@ -183,7 +183,7 @@ static void gf_sc_reconfig_task(GF_Compositor *compositor) compositor->offscreen_width = compositor->offscreen_height = 0; #endif evt.type = GF_EVENT_SYS_COLORS; - if (compositor->user->EventProc && compositor->user->EventProc(compositor->user->opaque, &evt) ) { + if (gf_term_send_event(compositor->term, &evt) ) { u32 i; for (i=0; i<28; i++) { compositor->sys_colors[i] = evt.sys_cols.sys_colors[i] & 0x00FFFFFF; @@ -195,38 +195,12 @@ static void gf_sc_reconfig_task(GF_Compositor *compositor) Bool gf_sc_draw_frame(GF_Compositor *compositor) { gf_sc_simulation_tick(compositor); - return compositor->draw_next_frame; + if (compositor->frame_draw_type) return 1; + if (compositor->fonts_pending) return 1; + return 0; } -static u32 gf_sc_proc(void *par) -{ - GF_Compositor *compositor = (GF_Compositor *) par; - compositor->video_th_state = 1; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Compositor] Entering thread ID %d\n", gf_th_id() )); - - - -#ifdef GPAC_TRISCOPE_MODE -/* scene creation*/ - compositor->RenoirHandler = CreateRenoirScene(); -#endif - - while (compositor->video_th_state == 1) { - if (compositor->is_hidden) - gf_sleep(compositor->frame_duration); - else - - gf_sc_simulation_tick(compositor); - } - /*destroy video out here if w're using openGL, to avoid threading issues*/ - compositor->video_out->Shutdown(compositor->video_out); - gf_modules_close_interface((GF_BaseInterface *)compositor->video_out); - compositor->video_out = NULL; - compositor->video_th_state = 3; - return 0; -} /*forces graphics redraw*/ GF_EXPORT @@ -248,7 +222,7 @@ static void gf_sc_reset_framerate(GF_Compositor *compositor) static Bool gf_sc_on_event(void *cbck, GF_Event *event); -static Bool gf_sc_set_check_raster2d(GF_Raster2D *ifce) +static Bool gf_sc_set_check_raster2d(GF_Compositor *compositor, GF_Raster2D *ifce) { /*check base*/ if (!ifce->stencil_new || !ifce->surface_new) return 0; @@ -259,7 +233,6 @@ static Bool gf_sc_set_check_raster2d(GF_Raster2D *ifce) return 0; } - static GF_Err gf_sc_load(GF_Compositor *compositor) { compositor->strike_bank = gf_list_new(); @@ -274,14 +247,22 @@ static GF_Err gf_sc_load(GF_Compositor *compositor) compositor->prev_hit_use_stack = gf_list_new(); compositor->focus_ancestors = gf_list_new(); compositor->focus_use_stack = gf_list_new(); + + compositor->env_tests = gf_list_new(); /*setup main visual*/ compositor->visual = visual_new(compositor); compositor->visual->GetSurfaceAccess = compositor_2d_get_video_access; compositor->visual->ReleaseSurfaceAccess = compositor_2d_release_video_access; + if (compositor->video_out->FlushRectangles) + compositor->visual->direct_flush = 1; - compositor->visual->DrawBitmap = compositor_2d_draw_bitmap; + compositor_2d_init_callbacks(compositor); + // default value for depth gain is not zero +#ifdef GF_SR_USE_DEPTH + compositor->traverse_state->depth_gain = FIX_ONE; +#endif gf_list_add(compositor->visuals, compositor->visual); @@ -309,163 +290,195 @@ static GF_Err gf_sc_load(GF_Compositor *compositor) } -static GF_Compositor *gf_sc_create(GF_User *user) +static GF_Err gf_sc_create(GF_Compositor *compositor) { const char *sOpt; - GF_Compositor *tmp; - - GF_SAFEALLOC(tmp, GF_Compositor); - if (!tmp) return NULL; - tmp->user = user; /*load video out*/ - sOpt = gf_cfg_get_key(user->config, "Video", "DriverName"); + sOpt = gf_cfg_get_key(compositor->user->config, "Video", "DriverName"); if (sOpt) { - tmp->video_out = (GF_VideoOutput *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_VIDEO_OUTPUT_INTERFACE); - if (tmp->video_out) { - tmp->video_out->evt_cbk_hdl = tmp; - tmp->video_out->on_event = gf_sc_on_event; + compositor->video_out = (GF_VideoOutput *) gf_modules_load_interface_by_name(compositor->user->modules, sOpt, GF_VIDEO_OUTPUT_INTERFACE); + if (compositor->video_out) { + compositor->video_out->evt_cbk_hdl = compositor; + compositor->video_out->on_event = gf_sc_on_event; /*init hw*/ - if (tmp->video_out->Setup(tmp->video_out, user->os_window_handler, user->os_display, user->init_flags) != GF_OK) { - gf_modules_close_interface((GF_BaseInterface *)tmp->video_out); - tmp->video_out = NULL; + if (compositor->video_out->Setup(compositor->video_out, compositor->user->os_window_handler, compositor->user->os_display, compositor->user->init_flags) != GF_OK) { + gf_modules_close_interface((GF_BaseInterface *)compositor->video_out); + compositor->video_out = NULL; } } else { sOpt = NULL; } } - if (!tmp->video_out) { + if (!compositor->video_out) { u32 i, count; - count = gf_modules_get_count(user->modules); + count = gf_modules_get_count(compositor->user->modules); for (i=0; i<count; i++) { - tmp->video_out = (GF_VideoOutput *) gf_modules_load_interface(user->modules, i, GF_VIDEO_OUTPUT_INTERFACE); - if (!tmp->video_out) continue; - tmp->video_out->evt_cbk_hdl = tmp; - tmp->video_out->on_event = gf_sc_on_event; + compositor->video_out = (GF_VideoOutput *) gf_modules_load_interface(compositor->user->modules, i, GF_VIDEO_OUTPUT_INTERFACE); + if (!compositor->video_out) continue; + compositor->video_out->evt_cbk_hdl = compositor; + compositor->video_out->on_event = gf_sc_on_event; /*init hw*/ - if (tmp->video_out->Setup(tmp->video_out, user->os_window_handler, user->os_display, user->init_flags)==GF_OK) { - gf_cfg_set_key(user->config, "Video", "DriverName", tmp->video_out->module_name); + if (compositor->video_out->Setup(compositor->video_out, compositor->user->os_window_handler, compositor->user->os_display, compositor->user->init_flags)==GF_OK) { + gf_cfg_set_key(compositor->user->config, "Video", "DriverName", compositor->video_out->module_name); break; } - gf_modules_close_interface((GF_BaseInterface *)tmp->video_out); - tmp->video_out = NULL; + gf_modules_close_interface((GF_BaseInterface *)compositor->video_out); + compositor->video_out = NULL; } } - if (!tmp->video_out ) { - free(tmp); - return NULL; + if (!compositor->video_out ) { + return GF_IO_ERR; } -#ifdef ENABLE_JOYSTICK - sOpt = gf_cfg_get_key(user->config, "General", "JoystickCenteredMode"); - if (sOpt) { - if (!stricmp(sOpt, "no")) tmp->video_out->centered_mode=0; - else tmp->video_out->centered_mode=1; - } else tmp->video_out->centered_mode=1; -#endif - /*try to load a raster driver*/ - sOpt = gf_cfg_get_key(user->config, "Compositor", "Raster2D"); + sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "Raster2D"); if (sOpt) { - tmp->rasterizer = (GF_Raster2D *) gf_modules_load_interface_by_name(user->modules, sOpt, GF_RASTER_2D_INTERFACE); - if (!tmp->rasterizer) { + compositor->rasterizer = (GF_Raster2D *) gf_modules_load_interface_by_name(compositor->user->modules, sOpt, GF_RASTER_2D_INTERFACE); + if (!compositor->rasterizer) { sOpt = NULL; - } else if (!gf_sc_set_check_raster2d(tmp->rasterizer)) { - gf_modules_close_interface((GF_BaseInterface *)tmp->rasterizer); - tmp->rasterizer = NULL; + } else if (!gf_sc_set_check_raster2d(compositor, compositor->rasterizer)) { + gf_modules_close_interface((GF_BaseInterface *)compositor->rasterizer); + compositor->rasterizer = NULL; sOpt = NULL; } } - if (!tmp->rasterizer) { + if (!compositor->rasterizer) { u32 i, count; - count = gf_modules_get_count(user->modules); + count = gf_modules_get_count(compositor->user->modules); for (i=0; i<count; i++) { - tmp->rasterizer = (GF_Raster2D *) gf_modules_load_interface(user->modules, i, GF_RASTER_2D_INTERFACE); - if (!tmp->rasterizer) continue; - if (gf_sc_set_check_raster2d(tmp->rasterizer)) break; - gf_modules_close_interface((GF_BaseInterface *)tmp->rasterizer); - tmp->rasterizer = NULL; + compositor->rasterizer = (GF_Raster2D *) gf_modules_load_interface(compositor->user->modules, i, GF_RASTER_2D_INTERFACE); + if (!compositor->rasterizer) continue; + if (gf_sc_set_check_raster2d(compositor, compositor->rasterizer)) break; + gf_modules_close_interface((GF_BaseInterface *)compositor->rasterizer); + compositor->rasterizer = NULL; } - if (tmp->rasterizer) gf_cfg_set_key(user->config, "Compositor", "Raster2D", tmp->rasterizer->module_name); + if (compositor->rasterizer) gf_cfg_set_key(compositor->user->config, "Compositor", "Raster2D", compositor->rasterizer->module_name); } - if (!tmp->rasterizer) { - tmp->video_out->Shutdown(tmp->video_out); - gf_modules_close_interface((GF_BaseInterface *)tmp->video_out); - free(tmp); - return NULL; + if (!compositor->rasterizer) { + compositor->video_out->Shutdown(compositor->video_out); + gf_modules_close_interface((GF_BaseInterface *)compositor->video_out); + compositor->video_out = NULL; + return GF_IO_ERR; } /*and init*/ - if (gf_sc_load(tmp) != GF_OK) { - gf_modules_close_interface((GF_BaseInterface *)tmp->rasterizer); - tmp->video_out->Shutdown(tmp->video_out); - gf_modules_close_interface((GF_BaseInterface *)tmp->video_out); - free(tmp); - return NULL; + if (gf_sc_load(compositor) != GF_OK) { + gf_modules_close_interface((GF_BaseInterface *)compositor->rasterizer); + compositor->rasterizer = NULL; + compositor->video_out->Shutdown(compositor->video_out); + gf_modules_close_interface((GF_BaseInterface *)compositor->video_out); + compositor->video_out = NULL; + return GF_IO_ERR; } - tmp->mx = gf_mx_new("Compositor"); - tmp->textures = gf_list_new(); - tmp->frame_rate = 30.0; - tmp->frame_duration = 33; - tmp->time_nodes = gf_list_new(); + compositor->textures = gf_list_new(); + compositor->frame_rate = 30.0; + compositor->frame_duration = 33; + compositor->time_nodes = gf_list_new(); #ifdef GF_SR_EVENT_QUEUE - tmp->events = gf_list_new(); - tmp->ev_mx = gf_mx_new("EventQueue"); + compositor->events = gf_list_new(); + compositor->ev_mx = gf_mx_new("EventQueue"); #endif #ifdef GF_SR_USE_VIDEO_CACHE - tmp->cached_groups = gf_list_new(); - tmp->cached_groups_queue = gf_list_new(); + compositor->cached_groups = gf_list_new(); + compositor->cached_groups_queue = gf_list_new(); #endif - gf_sc_reset_framerate(tmp); - tmp->font_manager = gf_font_manager_new(user); + /*load audio renderer*/ + compositor->audio_renderer = gf_sc_ar_load(compositor->user); + + gf_sc_reset_framerate(compositor); + compositor->font_manager = gf_font_manager_new(compositor->user); - tmp->extra_scenes = gf_list_new(); - tmp->interaction_level = GF_INTERACT_NORMAL | GF_INTERACT_INPUT_SENSOR | GF_INTERACT_NAVIGATION; - return tmp; + compositor->extra_scenes = gf_list_new(); + compositor->interaction_level = GF_INTERACT_NORMAL | GF_INTERACT_INPUT_SENSOR | GF_INTERACT_NAVIGATION; + + return GF_OK; +} + +enum +{ + GF_COMPOSITOR_THREAD_START = 0, + GF_COMPOSITOR_THREAD_RUN, + GF_COMPOSITOR_THREAD_ABORTING, + GF_COMPOSITOR_THREAD_DONE, + GF_COMPOSITOR_THREAD_INIT_FAILED, +}; + +static u32 gf_sc_proc(void *par) +{ + GF_Err e; + GF_Compositor *compositor = (GF_Compositor *) par; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Compositor] Entering thread ID %d\n", gf_th_id() )); + + compositor->video_th_state = GF_COMPOSITOR_THREAD_START; + e = gf_sc_create(compositor); + if (e != GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Compositor] Failed to initialize compositor: %s\n", gf_error_to_string(e) )); + compositor->video_th_state = GF_COMPOSITOR_THREAD_INIT_FAILED; + return 1; + } + + compositor->video_th_state = GF_COMPOSITOR_THREAD_RUN; + while (compositor->video_th_state == GF_COMPOSITOR_THREAD_RUN) { + if (compositor->is_hidden) + gf_sleep(compositor->frame_duration); + else + gf_sc_simulation_tick(compositor); + } + /*destroy video out here if w're using openGL, to avoid threading issues*/ + compositor->video_out->Shutdown(compositor->video_out); + gf_modules_close_interface((GF_BaseInterface *)compositor->video_out); + compositor->video_out = NULL; + compositor->video_th_state = GF_COMPOSITOR_THREAD_DONE; + return 0; } GF_Compositor *gf_sc_new(GF_User *user, Bool self_threaded, GF_Terminal *term) { - GF_Compositor *tmp = gf_sc_create(user); + GF_Err e; + GF_Compositor *tmp; + + + GF_SAFEALLOC(tmp, GF_Compositor); if (!tmp) return NULL; + tmp->user = user; tmp->term = term; + tmp->mx = gf_mx_new("Compositor"); + - /**/ - tmp->audio_renderer = gf_sc_ar_load(user); - if (!tmp->audio_renderer) GF_USER_MESSAGE(user, "", "NO AUDIO RENDERER", GF_OK); - - gf_mx_p(tmp->mx); - - /*run threaded*/ if (self_threaded) { + tmp->VisualThread = gf_th_new("Compositor"); gf_th_run(tmp->VisualThread, gf_sc_proc, tmp); - while (tmp->video_th_state!=1) { - gf_sleep(10); - if (tmp->video_th_state==3) { - gf_mx_v(tmp->mx); - gf_sc_del(tmp); - return NULL; - } + + /*wait until init is done*/ + while (tmp->video_th_state < GF_COMPOSITOR_THREAD_RUN) { + gf_sleep(0); + } + /*init failure*/ + if (tmp->video_th_state == GF_COMPOSITOR_THREAD_INIT_FAILED) { + gf_sc_del(tmp); + return NULL; } } else { -#ifdef GPAC_TRISCOPE_MODE -/* scene creation*/ - tmp->RenoirHandler = CreateRenoirScene(); -#endif - } + e = gf_sc_create(tmp); + if (e) { + gf_sc_del(tmp); + return NULL; + } + } + /*set default size if owning output*/ if (!tmp->user->os_window_handler) { gf_sc_set_size(tmp, SC_DEF_WIDTH, SC_DEF_HEIGHT); } - gf_mx_v(tmp->mx); - GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI]\tCompositor Cycle Log\tNetworks\tDecoders\tFrame\tDirect Draw\tVisual Config\tEvent\tRoute\tSMIL Timing\tTime node\tTexture\tSMIL Anim\tTraverse setup\tTraverse (and direct Draw)\tTraverse (and direct Draw) without anim\tIndirect Draw\tTraverse And Draw (Indirect or Not)\tFlush\tCycle\n")); return tmp; @@ -480,8 +493,14 @@ void gf_sc_del(GF_Compositor *compositor) gf_sc_lock(compositor, 1); if (compositor->VisualThread) { - compositor->video_th_state = 2; - while (compositor->video_th_state!=3) gf_sleep(10); + if (compositor->video_th_state == GF_COMPOSITOR_THREAD_RUN) { + compositor->video_th_state = GF_COMPOSITOR_THREAD_ABORTING; + while (compositor->video_th_state != GF_COMPOSITOR_THREAD_DONE) { + gf_sc_lock(compositor, 0); + gf_sleep(1); + gf_sc_lock(compositor, 1); + } + } gf_th_del(compositor->VisualThread); } if (compositor->video_out) { @@ -491,27 +510,29 @@ void gf_sc_del(GF_Compositor *compositor) } GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Closing visual compositor\n")); - gf_node_unregister(compositor->focus_highlight->node, NULL); - drawable_del_ex(compositor->focus_highlight, compositor); - - if (compositor->selected_text) free(compositor->selected_text); - if (compositor->sel_buffer) free(compositor->sel_buffer); - - visual_del(compositor->visual); - gf_list_del(compositor->sensors); - gf_list_del(compositor->previous_sensors); - gf_list_del(compositor->visuals); - gf_list_del(compositor->strike_bank); - gf_list_del(compositor->hit_use_stack); - gf_list_del(compositor->prev_hit_use_stack); - gf_list_del(compositor->focus_ancestors); - gf_list_del(compositor->focus_use_stack); - - - gf_list_del(compositor->traverse_state->vrml_sensors); - gf_list_del(compositor->traverse_state->use_stack); - free(compositor->traverse_state); - + if (compositor->focus_highlight) { + gf_node_unregister(compositor->focus_highlight->node, NULL); + drawable_del_ex(compositor->focus_highlight, compositor); + } + if (compositor->selected_text) gf_free(compositor->selected_text); + if (compositor->sel_buffer) gf_free(compositor->sel_buffer); + + if (compositor->visual) visual_del(compositor->visual); + if (compositor->sensors) gf_list_del(compositor->sensors); + if (compositor->previous_sensors) gf_list_del(compositor->previous_sensors); + if (compositor->visuals) gf_list_del(compositor->visuals); + if (compositor->strike_bank) gf_list_del(compositor->strike_bank); + if (compositor->hit_use_stack) gf_list_del(compositor->hit_use_stack); + if (compositor->prev_hit_use_stack) gf_list_del(compositor->prev_hit_use_stack); + if (compositor->focus_ancestors) gf_list_del(compositor->focus_ancestors); + if (compositor->focus_use_stack) gf_list_del(compositor->focus_use_stack); + if (compositor->env_tests) gf_list_del(compositor->env_tests); + + if (compositor->traverse_state) { + gf_list_del(compositor->traverse_state->vrml_sensors); + gf_list_del(compositor->traverse_state->use_stack); + gf_free(compositor->traverse_state); + } #ifndef GPAC_DISABLE_3D if (compositor->unit_bbox) mesh_free(compositor->unit_bbox); #endif @@ -525,7 +546,7 @@ void gf_sc_del(GF_Compositor *compositor) while (gf_list_count(compositor->events)) { GF_Event *ev = (GF_Event *)gf_list_get(compositor->events, 0); gf_list_rem(compositor->events, 0); - free(ev); + gf_free(ev); } gf_mx_v(compositor->ev_mx); gf_mx_del(compositor->ev_mx); @@ -539,12 +560,14 @@ void gf_sc_del(GF_Compositor *compositor) gf_list_del(compositor->cached_groups_queue); #endif - gf_list_del(compositor->textures); - gf_list_del(compositor->time_nodes); - gf_list_del(compositor->extra_scenes); + if (compositor->textures) gf_list_del(compositor->textures); + if (compositor->time_nodes) gf_list_del(compositor->time_nodes); + if (compositor->extra_scenes) gf_list_del(compositor->extra_scenes); + if (compositor->video_listeners) gf_list_del(compositor->video_listeners); + gf_sc_lock(compositor, 0); gf_mx_del(compositor->mx); - free(compositor); + gf_free(compositor); GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Destroyed\n")); } @@ -564,7 +587,7 @@ u32 gf_sc_get_audio_buffer_length(GF_Compositor *compositor) } -static void gf_sc_pause(GF_Compositor *compositor, u32 PlayState) +static void gf_sc_set_play_state(GF_Compositor *compositor, u32 PlayState) { if (!compositor || !compositor->audio_renderer) return; if (!compositor->paused && !PlayState) return; @@ -573,9 +596,12 @@ static void gf_sc_pause(GF_Compositor *compositor, u32 PlayState) /*step mode*/ if (PlayState==GF_STATE_STEP_PAUSE) { compositor->step_mode = 1; - /*resume for next step*/ - if (compositor->paused && compositor->term) gf_term_set_option(compositor->term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + if (!compositor->paused) + gf_term_set_option(compositor->term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + else + gf_term_step_clocks(compositor->term, compositor->frame_duration); } else { + compositor->step_mode = 0; if (compositor->audio_renderer) gf_sc_ar_control(compositor->audio_renderer, (compositor->paused && (PlayState==0xFF)) ? 2 : compositor->paused); compositor->paused = (PlayState==GF_STATE_PAUSED) ? 1 : 0; } @@ -595,8 +621,8 @@ static GF_Err gf_sc_set_scene_size(GF_Compositor *compositor, u32 Width, u32 Hei compositor->scene_width = SC_DEF_WIDTH; } else { /*use current res*/ - compositor->scene_width = compositor->display_width ? compositor->display_width : compositor->new_width; - compositor->scene_height = compositor->display_height ? compositor->display_height : compositor->new_height; + compositor->scene_width = compositor->new_width ? compositor->new_width : compositor->display_width; + compositor->scene_height = compositor->new_height ? compositor->new_height : compositor->display_height; } } else { compositor->scene_height = Height; @@ -649,22 +675,21 @@ Fixed gf_sc_svg_convert_length_to_display(GF_Compositor *compositor, SVG_Length } #endif - void compositor_set_ar_scale(GF_Compositor *compositor, Fixed scaleX, Fixed scaleY) { compositor->trans_x = gf_muldiv(compositor->trans_x, scaleX, compositor->scale_x); compositor->trans_y = gf_muldiv(compositor->trans_y, scaleY, compositor->scale_y); + compositor->zoom_changed = 1; compositor->scale_x = scaleX; compositor->scale_y = scaleY; - compositor->zoom_changed = 1; compositor_2d_set_user_transform(compositor, compositor->zoom, compositor->trans_x, compositor->trans_y, 1); } static void gf_sc_reset(GF_Compositor *compositor) { - Bool direct_draw; + Bool draw_mode; GF_VisualManager *visual; u32 i=0; @@ -675,7 +700,7 @@ static void gf_sc_reset(GF_Compositor *compositor) while (visual->prev_nodes) { struct _drawable_store *cur = visual->prev_nodes; visual->prev_nodes = cur->next; - free(cur); + gf_free(cur); } visual->last_prev_entry = NULL; visual->to_redraw.count = 0; @@ -689,7 +714,7 @@ static void gf_sc_reset(GF_Compositor *compositor) gf_list_reset(compositor->previous_sensors); /*reset traverse state*/ - direct_draw = compositor->traverse_state->direct_draw; + draw_mode = compositor->traverse_state->immediate_draw; gf_list_del(compositor->traverse_state->vrml_sensors); gf_list_del(compositor->traverse_state->use_stack); memset(compositor->traverse_state, 0, sizeof(GF_TraverseState)); @@ -697,7 +722,12 @@ static void gf_sc_reset(GF_Compositor *compositor) compositor->traverse_state->use_stack = gf_list_new(); gf_mx2d_init(compositor->traverse_state->transform); gf_cmx_init(&compositor->traverse_state->color_mat); - compositor->traverse_state->direct_draw = direct_draw; + compositor->traverse_state->immediate_draw = draw_mode; + +#ifdef GF_SR_USE_DEPTH + compositor->traverse_state->depth_gain = FIX_ONE; + compositor->traverse_state->depth_offset = 0; +#endif assert(!compositor->visual->overlays); @@ -734,7 +764,7 @@ GF_Err gf_sc_set_scene(GF_Compositor *compositor, GF_SceneGraph *scene_graph) if (!compositor) return GF_BAD_PARAM; gf_sc_lock(compositor, 1); - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, (scene_graph ? "[Compositor] Attaching new scene\n" : "[Compositor] Detaching scene\n")); + GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, (scene_graph ? "[Compositor] Attaching new scene\n" : "[Compositor] Detaching scene\n")); if (compositor->audio_renderer && (compositor->scene != scene_graph)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Reseting audio compositor\n")); @@ -747,7 +777,7 @@ GF_Err gf_sc_set_scene(GF_Compositor *compositor, GF_SceneGraph *scene_graph) while (gf_list_count(compositor->events)) { GF_Event *ev = (GF_Event*)gf_list_get(compositor->events, 0); gf_list_rem(compositor->events, 0); - free(ev); + gf_free(ev); } #endif @@ -761,6 +791,7 @@ GF_Err gf_sc_set_scene(GF_Compositor *compositor, GF_SceneGraph *scene_graph) if (scene_graph) { #ifndef GPAC_DISABLE_SVG SVG_Length *w, *h; + SVG_ViewBox *vb; Bool is_svg = 0; #endif const char *opt; @@ -781,6 +812,7 @@ GF_Err gf_sc_set_scene(GF_Compositor *compositor, GF_SceneGraph *scene_graph) #ifndef GPAC_DISABLE_SVG w = h = NULL; + vb = NULL; if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) { GF_FieldInfo info; is_svg = 1; @@ -788,29 +820,43 @@ GF_Err gf_sc_set_scene(GF_Compositor *compositor, GF_SceneGraph *scene_graph) w = info.far_ptr; if (gf_node_get_attribute_by_tag(top_node, TAG_SVG_ATT_height, 0, 0, &info)==GF_OK) h = info.far_ptr; + if (gf_node_get_attribute_by_tag(top_node, TAG_SVG_ATT_viewBox, 0, 0, &info)==GF_OK) + vb = info.far_ptr; } /*default back color is white*/ if (is_svg && ! (compositor->user->init_flags & GF_TERM_WINDOWLESS)) compositor->back_color = 0xFFFFFFFF; /*hack for SVG where size is set in % - negotiate a canvas size*/ - if (!compositor->has_size_info && w && h) { + if (!compositor->has_size_info && w && h && vb) { do_notif = 1; if (w->type!=SVG_NUMBER_PERCENTAGE) { width = FIX2INT(gf_sc_svg_convert_length_to_display(compositor, w) ); + } else if ((u32) FIX2INT(vb->width)<compositor->video_out->max_screen_width) { + width = FIX2INT(vb->width); } else { width = SC_DEF_WIDTH; do_notif = 0; } if (h->type!=SVG_NUMBER_PERCENTAGE) { height = FIX2INT(gf_sc_svg_convert_length_to_display(compositor, h) ); + } else if ((u32) FIX2INT(vb->height)<compositor->video_out->max_screen_height) { + height = FIX2INT(vb->height); } else { height = SC_DEF_HEIGHT; do_notif = 0; } } /*we consider that SVG has no size onfo per say, everything is handled by the viewBox if any*/ - if (is_svg) compositor->has_size_info = 0; + if (is_svg) { + compositor->has_size_info = 0; + gf_sc_focus_switch_ring(compositor, 0); + } else #endif + { + GF_Node *keynav = gf_scene_get_keynav(compositor->scene, NULL); + if (keynav) gf_sc_change_key_navigator(compositor, keynav); + } + /*default back color is key color*/ if (compositor->user->init_flags & GF_TERM_WINDOWLESS) { opt = gf_cfg_get_key(compositor->user->config, "Compositor", "ColorKey"); @@ -855,19 +901,20 @@ GF_Err gf_sc_set_scene(GF_Compositor *compositor, GF_SceneGraph *scene_graph) gf_sc_lock(compositor, 0); if (scene_graph) - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); + /*here's a nasty trick: the app may respond to this by calling a gf_sc_set_size from a different thread, but in an atomic way (typically happen on Win32 when changing the window size). WE MUST NOTIFY THE SIZE CHANGE AFTER RELEASING THE RENDERER MUTEX*/ - if (do_notif && compositor->user->EventProc) { + if (do_notif) { GF_Event evt; /*wait for user ack*/ - compositor->draw_next_frame = 0; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_NONE); evt.type = GF_EVENT_SCENE_SIZE; evt.size.width = width; evt.size.height = height; - compositor->user->EventProc(compositor->user->opaque, &evt); + gf_term_send_event(compositor->term, &evt); } return GF_OK; } @@ -906,9 +953,11 @@ GF_Err gf_sc_set_size(GF_Compositor *compositor, u32 NewWidth, u32 NewHeight) compositor->msg_type |= GF_SR_CFG_SET_SIZE; /*if same size only request for video setup */ - if ((compositor->display_width == NewWidth) && (compositor->display_height == NewHeight) ) + compositor->msg_type &= ~GF_SR_CFG_WINDOWSIZE_NOTIF; + if ((compositor->display_width == NewWidth) && (compositor->display_height == NewHeight) ) { compositor->msg_type |= GF_SR_CFG_WINDOWSIZE_NOTIF; - + } + if (lock_ok) gf_sc_lock(compositor, 0); return GF_OK; @@ -918,6 +967,7 @@ void gf_sc_reload_config(GF_Compositor *compositor) { const char *sOpt; + /*changing drivers needs exclusive access*/ gf_sc_lock(compositor, 1); @@ -951,11 +1001,19 @@ void gf_sc_reload_config(GF_Compositor *compositor) if (!compositor->text_sel_color) compositor->text_sel_color = 0xFFAAAAFF; /*load options*/ - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "DirectDraw"); - if (sOpt && ! stricmp(sOpt, "yes")) - compositor->traverse_state->direct_draw = 1; - else - compositor->traverse_state->direct_draw = 0; + if (compositor->video_out->hw_caps & GF_VIDEO_HW_DIRECT_ONLY) { + compositor->traverse_state->immediate_draw = 1; + } else { + sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "DrawMode"); + if (!sOpt) { sOpt = "defer"; gf_cfg_set_key(compositor->user->config, "Compositor", "DrawMode", sOpt); } + + if (!strcmp(sOpt, "immediate")) compositor->traverse_state->immediate_draw = 1; + else if (!strcmp(sOpt, "defer-debug")) { + compositor->traverse_state->immediate_draw = 0; + compositor->debug_defer = 1; + } + else compositor->traverse_state->immediate_draw = 0; + } sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "ScalableZoom"); compositor->scalable_zoom = (!sOpt || !stricmp(sOpt, "yes") ) ? 1 : 0; @@ -1012,14 +1070,19 @@ void gf_sc_reload_config(GF_Compositor *compositor) sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "ForceOpenGL"); compositor->force_opengl_2d = (sOpt && !strcmp(sOpt, "yes")) ? 1 : 0; +#ifdef OPENGL_RASTER + compositor->opengl_raster = (sOpt && !strcmp(sOpt, "raster")) ? 1 : 0; +#endif + +#ifdef GPAC_HAS_GLU + sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "RasterOutlines"); + compositor->raster_outlines = (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0; +#endif /*currently: - - no tesselator for GL-ES, so use raster outlines. - no support for npow2 textures, and no support for DrawPixels */ #ifndef GPAC_USE_OGL_ES - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "RasterOutlines"); - compositor->raster_outlines = (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0; sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "EmulatePOW2"); compositor->emul_pow2 = (sOpt && !stricmp(sOpt, "yes") ) ? 1 : 0; sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "BitmapCopyPixels"); @@ -1062,24 +1125,25 @@ void gf_sc_reload_config(GF_Compositor *compositor) #endif -#ifdef GPAC_TRISCOPE_MODE - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "3dsDepthBuffGain"); - if (sOpt) sscanf(sOpt, "%f", &((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthGain); else ((GF_RenoirHandler *) compositor->RenoirHandler)->MapDepthGain = 1; - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "3dsDepthBuffOffset"); - if (sOpt) sscanf(sOpt, "%f", &((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthOffset); else ((GF_RenoirHandler *) compositor->RenoirHandler)->MapDepthOffset = 0; - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "FlatDepthBuffGain"); - if (sOpt) sscanf(sOpt, "%f", &((GF_RenoirHandler *)compositor->RenoirHandler)->FlatDepthGain); else ((GF_RenoirHandler *) compositor->RenoirHandler)->FlatDepthGain = 1.0; - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "OGLDepthBuffGain"); - if (sOpt) sscanf(sOpt, "%f", &compositor->OGLDepthGain); else compositor->OGLDepthGain = 1.0; - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "OGLDepthBuffOffset"); - if (sOpt) sscanf(sOpt, "%f", &compositor->OGLDepthOffset); else compositor->OGLDepthOffset = 0; +#ifdef GF_SR_USE_DEPTH + sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "AutoStereoCalibration"); + compositor->auto_calibration = (!sOpt || !strcmp(sOpt, "yes")) ? 1 : 0; + + sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "DisplayDepth"); + compositor->display_depth = sOpt ? (!strcmp(sOpt, "auto") ? -1 : atoi(sOpt)) : 0; + + if (!compositor->video_out->view_distance) { + Float v; + sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "ViewDistance"); + v = sOpt ? (Float) atof(sOpt) : 50.0f; + compositor->video_out->view_distance = FLT2FIX(v * 0.3937f * compositor->video_out->dpi_x); + } #endif - /*RECT texture support - we must reload HW*/ compositor->reset_graphics = 1; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); gf_sc_lock(compositor, 0); } @@ -1092,32 +1156,39 @@ GF_Err gf_sc_set_option(GF_Compositor *compositor, u32 type, u32 value) e = GF_OK; switch (type) { case GF_OPT_PLAY_STATE: - gf_sc_pause(compositor, value); + gf_sc_set_play_state(compositor, value); + break; + case GF_OPT_AUDIO_VOLUME: + gf_sc_ar_set_volume(compositor->audio_renderer, value); + break; + case GF_OPT_AUDIO_PAN: + gf_sc_ar_set_pan(compositor->audio_renderer, value); + break; + case GF_OPT_AUDIO_MUTE: + gf_sc_ar_mute(compositor->audio_renderer, value); break; - case GF_OPT_AUDIO_VOLUME: gf_sc_ar_set_volume(compositor->audio_renderer, value); break; - case GF_OPT_AUDIO_PAN: gf_sc_ar_set_pan(compositor->audio_renderer, value); break; case GF_OPT_OVERRIDE_SIZE: compositor->override_size_flags = value ? 1 : 0; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; case GF_OPT_STRESS_MODE: compositor->stress_mode = value; break; case GF_OPT_ANTIALIAS: compositor->antiAlias = value; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; case GF_OPT_HIGHSPEED: compositor->high_speed = value; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; case GF_OPT_DRAW_BOUNDS: compositor->draw_bvol = value; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; case GF_OPT_TEXTURE_TEXT: compositor->texture_text_mode = value; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; case GF_OPT_ASPECT_RATIO: compositor->aspect_ratio = value; @@ -1125,14 +1196,14 @@ GF_Err gf_sc_set_option(GF_Compositor *compositor, u32 type, u32 value) break; case GF_OPT_INTERACTION_LEVEL: compositor->interaction_level = value; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; case GF_OPT_REFRESH: compositor->reset_graphics = value; break; case GF_OPT_FULLSCREEN: if (compositor->fullscreen != value) compositor->msg_type |= GF_SR_CFG_FULLSCREEN; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; case GF_OPT_ORIGINAL_VIEW: compositor_2d_set_user_transform(compositor, FIX_ONE, 0, 0, 0); @@ -1146,20 +1217,23 @@ GF_Err gf_sc_set_option(GF_Compositor *compositor, u32 type, u32 value) evt.show.show_type = value ? 1 : 0; e = compositor->video_out->ProcessEvent(compositor->video_out, &evt); } - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; case GF_OPT_FREEZE_DISPLAY: compositor->freeze_display = value; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; case GF_OPT_RELOAD_CONFIG: gf_sc_reload_config(compositor); - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; - case GF_OPT_DIRECT_DRAW: - compositor->traverse_state->direct_draw = value ? 1 : 0; - /*force redraw*/ - compositor->draw_next_frame = 1; + case GF_OPT_DRAW_MODE: + if (!(compositor->video_out->hw_caps & GF_VIDEO_HW_DIRECT_ONLY)) { + compositor->traverse_state->immediate_draw = (value==GF_DRAW_MODE_IMMEDIATE) ? 1 : 0; + compositor->debug_defer = (value==GF_DRAW_MODE_DEFER_DEBUG) ? 1 : 0; + /*force redraw*/ + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); + } break; case GF_OPT_SCALABLE_ZOOM: compositor->scalable_zoom = value; @@ -1174,7 +1248,7 @@ GF_Err gf_sc_set_option(GF_Compositor *compositor, u32 type, u32 value) /*force texture setup when switching to OpenGL*/ if (value) compositor->reset_graphics = 1; /*force redraw*/ - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); } break; case GF_OPT_YUV_HARDWARE: @@ -1196,13 +1270,19 @@ GF_Err gf_sc_set_option(GF_Compositor *compositor, u32 type, u32 value) if (cam->navigation_flags & NAV_ANY) { /*if not specifying mode, try to (un)bind top*/ if (!value) { +#ifndef GPAC_DISABLE_VRML if (compositor->active_layer) { compositor_layer3d_bind_camera(compositor->active_layer, 0, value); } else { GF_Node *n = (GF_Node*)gf_list_get(compositor->visual->navigation_stack, 0); - if (n) Bindable_SetSetBind(n, 0); - else cam->navigate_mode = value; + if (n) + Bindable_SetSetBind(n, 0); + else + cam->navigate_mode = value; } +#else + cam->navigate_mode = value; +#endif } else { cam->navigate_mode = value; } @@ -1244,7 +1324,7 @@ GF_Err gf_sc_set_option(GF_Compositor *compositor, u32 type, u32 value) case GF_OPT_BACK_CULL: compositor->backcull = value; break; case GF_OPT_WIREFRAME: compositor->wiremode = value; break; case GF_OPT_NORMALS: compositor->draw_normals = value; break; -#ifndef GPAC_USE_OGL_ES +#ifdef GPAC_HAS_GLU case GF_OPT_RASTER_OUTLINES: compositor->raster_outlines = value; break; #endif @@ -1263,7 +1343,7 @@ GF_Err gf_sc_set_option(GF_Compositor *compositor, u32 type, u32 value) compositor->gravity_on = value; /*force collision pass*/ cam->last_pos.z -= 1; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); } break; #endif @@ -1290,14 +1370,50 @@ u32 gf_sc_get_option(GF_Compositor *compositor, u32 type) case GF_OPT_PLAY_STATE: return compositor->paused ? 1 : 0; case GF_OPT_OVERRIDE_SIZE: return (compositor->override_size_flags & 1) ? 1 : 0; case GF_OPT_IS_FINISHED: - { if (compositor->interaction_sensors) return 0; - if (gf_list_count(compositor->time_nodes)) return 0; - return 1; + case GF_OPT_IS_OVER: + { + u32 i, count; + count = gf_list_count(compositor->time_nodes); + for (i=0; i<count; i++) { + GF_TimeNode *tn = (GF_TimeNode *)gf_list_get(compositor->time_nodes, i); + if (tn->needs_unregister) continue; + switch (gf_node_get_tag((GF_Node *)tn->udta)) { +#ifndef GPAC_DISABLE_VRML + case TAG_MPEG4_TimeSensor: +#endif +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_TimeSensor: +#endif + return 0; + +#ifndef GPAC_DISABLE_VRML + case TAG_MPEG4_MovieTexture: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_MovieTexture: +#endif + if (((M_MovieTexture *)tn->udta)->loop) return 0; + break; + case TAG_MPEG4_AudioClip: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_AudioClip: +#endif + if (((M_AudioClip*)tn->udta)->loop) return 0; + break; + case TAG_MPEG4_AnimationStream: + if (((M_AnimationStream*)tn->udta)->loop) return 0; + break; +#endif + } + } } + /*FIXME - this does not work with SVG/SMIL*/ + return 1; case GF_OPT_STRESS_MODE: return compositor->stress_mode; case GF_OPT_AUDIO_VOLUME: return compositor->audio_renderer->volume; case GF_OPT_AUDIO_PAN: return compositor->audio_renderer->pan; + case GF_OPT_AUDIO_MUTE: return compositor->audio_renderer->mute; + case GF_OPT_ANTIALIAS: return compositor->antiAlias; case GF_OPT_HIGHSPEED: return compositor->high_speed; case GF_OPT_ASPECT_RATIO: return compositor->aspect_ratio; @@ -1308,12 +1424,16 @@ u32 gf_sc_get_option(GF_Compositor *compositor, u32 type) case GF_OPT_TEXTURE_TEXT: return compositor->texture_text_mode; case GF_OPT_USE_OPENGL: return compositor->force_opengl_2d; - case GF_OPT_DIRECT_DRAW: return compositor->traverse_state->direct_draw ? 1 : 0; + case GF_OPT_DRAW_MODE: + if (compositor->traverse_state->immediate_draw) return GF_DRAW_MODE_IMMEDIATE; + if (compositor->debug_defer) return GF_DRAW_MODE_DEFER_DEBUG; + return GF_DRAW_MODE_DEFER; case GF_OPT_SCALABLE_ZOOM: return compositor->scalable_zoom; case GF_OPT_YUV_HARDWARE: return compositor->enable_yuv_hw; case GF_OPT_YUV_FORMAT: return compositor->enable_yuv_hw ? compositor->video_out->yuv_pixel_format : 0; case GF_OPT_NAVIGATION_TYPE: #ifndef GPAC_DISABLE_3D + if (compositor->navigation_disabled) return GF_NAVIGATE_TYPE_NONE; if (compositor->visual->type_3d || compositor->active_layer) { GF_Camera *cam = compositor_3d_get_camera(compositor); if (!(cam->navigation_flags & NAV_ANY)) return GF_NAVIGATE_TYPE_NONE; @@ -1321,7 +1441,7 @@ u32 gf_sc_get_option(GF_Compositor *compositor, u32 type) } else #endif { - return compositor->navigation_disabled ? GF_NAVIGATE_TYPE_NONE : GF_NAVIGATE_TYPE_2D; + return GF_NAVIGATE_TYPE_2D; } case GF_OPT_NAVIGATION: #ifndef GPAC_DISABLE_3D @@ -1439,9 +1559,10 @@ GF_Node *gf_sc_pick_node(GF_Compositor *compositor, s32 X, s32 Y) return NULL; } -static void gf_sc_forward_event(GF_Compositor *compositor, GF_Event *ev) +static void gf_sc_forward_event(GF_Compositor *compositor, GF_Event *ev, Bool consumed) { - GF_USER_SENDEVENT(compositor->user, ev); + gf_term_forward_event(compositor->term, ev, consumed); + if (consumed) return; if ((ev->type==GF_EVENT_MOUSEUP) && (ev->mouse.button==GF_MOUSE_LEFT)) { u32 now; @@ -1453,15 +1574,17 @@ static void gf_sc_forward_event(GF_Compositor *compositor, GF_Event *ev) event.mouse.key_states = compositor->key_states; event.mouse.x = ev->mouse.x; event.mouse.y = ev->mouse.y; - GF_USER_SENDEVENT(compositor->user, &event); + gf_term_send_event(compositor->term, &event); } compositor->last_click_time = now; } } + static void gf_sc_setup_root_visual(GF_Compositor *compositor, GF_Node *top_node) { if (top_node && !compositor->root_visual_setup) { + GF_SceneGraph *scene = compositor->scene; u32 node_tag; #ifndef GPAC_DISABLE_3D Bool was_3d = compositor->visual->type_3d; @@ -1474,13 +1597,24 @@ static void gf_sc_setup_root_visual(GF_Compositor *compositor, GF_Node *top_node node_tag = gf_node_get_tag(top_node); switch (node_tag) { + +#ifndef GPAC_DISABLE_VRML case TAG_MPEG4_OrderedGroup: case TAG_MPEG4_Layer2D: #ifndef GPAC_DISABLE_3D - compositor->visual->type_3d = 0; - compositor->visual->camera.is_3D = 0; + /*move to perspective 3D when simulating depth*/ +#ifdef GF_SR_USE_DEPTH + if (compositor->display_depth) { + compositor->visual->type_3d = 2; + compositor->visual->camera.is_3D = 1; + } else +#endif + { + compositor->visual->type_3d = 0; + compositor->visual->camera.is_3D = 0; + } #endif - compositor->traverse_state->pixel_metrics = gf_sg_use_pixel_metrics(compositor->scene); + compositor->traverse_state->pixel_metrics = gf_sg_use_pixel_metrics(scene); break; case TAG_MPEG4_Group: case TAG_MPEG4_Layer3D: @@ -1488,24 +1622,39 @@ static void gf_sc_setup_root_visual(GF_Compositor *compositor, GF_Node *top_node compositor->visual->type_3d = 2; compositor->visual->camera.is_3D = 1; #endif - compositor->traverse_state->pixel_metrics = gf_sg_use_pixel_metrics(compositor->scene); + compositor->traverse_state->pixel_metrics = gf_sg_use_pixel_metrics(scene); break; +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Group: #ifndef GPAC_DISABLE_3D compositor->visual->type_3d = 3; #endif - compositor->traverse_state->pixel_metrics = gf_sg_use_pixel_metrics(compositor->scene); + compositor->traverse_state->pixel_metrics = gf_sg_use_pixel_metrics(scene); break; +#endif /*GPAC_DISABLE_X3D*/ + + + +#endif /*GPAC_DISABLE_VRML*/ + #ifndef GPAC_DISABLE_SVG case TAG_SVG_svg: #ifndef GPAC_DISABLE_3D - compositor->visual->type_3d = 0; - compositor->visual->camera.is_3D = 0; +#ifdef GF_SR_USE_DEPTH + if (compositor->display_depth) { + compositor->visual->type_3d = 2; + compositor->visual->camera.is_3D = 1; + } else +#endif + { + compositor->visual->type_3d = 0; + compositor->visual->camera.is_3D = 0; + } #endif compositor->visual->center_coords = 0; compositor->root_visual_setup = 2; break; -#endif +#endif /*GPAC_DISABLE_SVG*/ } /*!! by default we don't set the focus on the content - this is conform to SVG and avoids displaying the @@ -1513,9 +1662,15 @@ static void gf_sc_setup_root_visual(GF_Compositor *compositor, GF_Node *top_node /*setup OpenGL & camera mode*/ #ifndef GPAC_DISABLE_3D + if (compositor->inherit_type_3d && !compositor->visual->type_3d) { + compositor->visual->type_3d = 2; + compositor->visual->camera.is_3D = 1; + } /*request for OpenGL drawing in 2D*/ - if (compositor->force_opengl_2d && !compositor->visual->type_3d) + else if (compositor->force_opengl_2d && !compositor->visual->type_3d) { compositor->visual->type_3d = 1; + compositor->visual->camera.is_3D = 0; + } if (! (compositor->video_out->hw_caps & GF_VIDEO_HW_OPENGL)) { compositor->visual->type_3d = 0; @@ -1525,7 +1680,7 @@ static void gf_sc_setup_root_visual(GF_Compositor *compositor, GF_Node *top_node camera_invalidate(&compositor->visual->camera); #endif - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Main scene setup - pixel metrics %d - center coords %d\n", compositor->traverse_state->pixel_metrics, compositor->visual->center_coords)); + GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Compositor] Main scene setup - pixel metrics %d - center coords %d\n", compositor->traverse_state->pixel_metrics, compositor->visual->center_coords)); #ifndef GPAC_DISABLE_3D /*change in 2D/3D config, force AR recompute/video restup*/ @@ -1554,15 +1709,19 @@ static void gf_sc_setup_root_visual(GF_Compositor *compositor, GF_Node *top_node } else #endif + { compositor_2d_set_aspect_ratio(compositor); + } - compositor->draw_next_frame = 0; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_NONE); #ifndef GPAC_DISABLE_LOG if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RTI)) { compositor->visual_config_time = gf_sys_clock() - time; } #endif + + compositor_evaluate_envtests(compositor, 0); } } @@ -1584,25 +1743,20 @@ static void gf_sc_draw_scene(GF_Compositor *compositor) compositor->traverse_state->in_group_cache = 1; #endif - flags = compositor->traverse_state->direct_draw; - + flags = compositor->traverse_state->immediate_draw; visual_draw_frame(compositor->visual, top_node, compositor->traverse_state, 1); -#ifdef GPAC_TRISCOPE_MODE - /*here comes renoir rendering*/ - RenderRenoirScene (compositor->RenoirHandler); -#endif - compositor->traverse_state->direct_draw = flags; + compositor->traverse_state->immediate_draw = flags; #ifdef GF_SR_USE_VIDEO_CACHE gf_list_reset(compositor->cached_groups_queue); #endif - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Drawing done\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Frame %d - drawing done\n", compositor->frame_number)); /*only send the resize notification once the frame has been dra*/ if (compositor->recompute_ar) { - compositor_send_resize_event(compositor, 0, 0, 0, 1); + compositor_send_resize_event(compositor, NULL, 0, 0, 0, 1); compositor->recompute_ar = 0; } compositor->zoom_changed = 0; @@ -1616,21 +1770,19 @@ extern u32 time_spent_in_anim; void gf_sc_simulation_tick(GF_Compositor *compositor) { GF_SceneGraph *sg; - u32 in_time, end_time, i, count; + u32 in_time, end_time, i, count, sim_time; Bool frame_drawn; #ifndef GPAC_DISABLE_LOG - s32 event_time, route_time, smil_timing_time, time_node_time, texture_time, traverse_time, flush_time; -#endif -#ifdef TRISCOPE_TEST_FRAMERATE - double drawing_time; - static u32 timer_count=0; + s32 event_time, route_time, smil_timing_time=0, time_node_time, texture_time, traverse_time, flush_time; #endif + /*lock compositor for the whole cycle*/ gf_sc_lock(compositor, 1); /*first thing to do, let the video output handle user event if it is not threaded*/ compositor->video_out->ProcessEvent(compositor->video_out, NULL); + if (compositor->freeze_display) { gf_sc_lock(compositor, 0); gf_sleep(compositor->frame_duration); @@ -1648,11 +1800,9 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) } in_time = gf_sys_clock(); -#ifdef TRISCOPE_TEST_FRAMERATE - TIMER_START; -#endif + if (compositor->reset_graphics) - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); #ifdef GF_SR_EVENT_QUEUE /*process pending user events*/ @@ -1661,41 +1811,47 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) #endif gf_mx_p(compositor->ev_mx); while (gf_list_count(compositor->events)) { + Bool ret; GF_Event *ev = (GF_Event*)gf_list_get(compositor->events, 0); gf_list_rem(compositor->events, 0); - if (!gf_sc_exec_event(compositor, ev)) { - gf_sc_forward_event(compositor, ev); - } - free(ev); + ret = gf_sc_exec_event(compositor, ev); + gf_sc_forward_event(compositor, ev, ret); + gf_free(ev); } gf_mx_v(compositor->ev_mx); #ifndef GPAC_DISABLE_LOG event_time = gf_sys_clock() - event_time; #endif -#else +#elif !defined(GPAC_DISABLE_LOG) event_time = 0; #endif - - gf_term_sample_clocks(compositor->term); - /*setup root visual before triggering animations in case they in turn use the viewport*/ -// if (!compositor->root_visual_setup) -// gf_sc_setup_root_visual(compositor, gf_sg_get_root_node(compositor->scene)); + sim_time = gf_term_sample_clocks(compositor->term); +#ifndef GPAC_DISABLE_VRML + /*execute all routes before updating textures, otherwise nodes inside composite texture may never see their dirty flag set*/ #ifndef GPAC_DISABLE_LOG route_time = gf_sys_clock(); #endif - /*execute all routes before updating textures, otherwise nodes inside composite texture may never see their - dirty flag set*/ + gf_sg_activate_routes(compositor->scene); i = 0; while ((sg = (GF_SceneGraph*)gf_list_enum(compositor->extra_scenes, &i))) { gf_sg_activate_routes(sg); } + #ifndef GPAC_DISABLE_LOG route_time = gf_sys_clock() - route_time; #endif +#else +#ifndef GPAC_DISABLE_LOG + route_time = 0; +#endif +#endif /*GPAC_DISABLE_VRML*/ + + + #ifndef GPAC_DISABLE_SVG #if SVG_FIXME { /* Experimental (Not SVG compliant system events (i.e. battery, cpu ...) triggered to the root node)*/ @@ -1716,7 +1872,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) } } else if (l->event.type == GF_EVENT_BATTERY) { //&& l->observer.target == (SVG_SA_Element *)node) { evt.type = GF_EVENT_BATTERY; - gf_sys_get_battery_state(&evt.onBattery, &evt.batteryState, &evt.batteryLevel); + gf_sys_get_battery_state(&evt.onBattery, &evt.batteryState, &evt.batteryLevel, NULL, NULL); gf_dom_event_fire(root, NULL, &evt); } } @@ -1728,12 +1884,12 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) smil_timing_time = gf_sys_clock(); #endif if (gf_smil_notify_timed_elements(compositor->scene)) { - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); } i = 0; while ((sg = (GF_SceneGraph*)gf_list_enum(compositor->extra_scenes, &i))) { if (gf_smil_notify_timed_elements(sg)) { - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); } } @@ -1742,6 +1898,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) #endif #endif + #ifndef GPAC_DISABLE_LOG time_node_time = gf_sys_clock(); @@ -1771,6 +1928,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) count = gf_list_count(compositor->textures); for (i=0; i<count; i++) { GF_TextureHandler *txh = (GF_TextureHandler *)gf_list_get(compositor->textures, i); + if (!txh) break; /*signal graphics reset before updating*/ if (compositor->reset_graphics && txh->tx_io) gf_sc_texture_reset(txh); txh->update_texture_fcnt(txh); @@ -1781,11 +1939,16 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) texture_time = gf_sys_clock() - texture_time; #endif + if (compositor->force_next_frame_redraw) { + compositor->force_next_frame_redraw=0; + compositor->frame_draw_type=GF_SC_DRAW_FRAME; + } + - frame_drawn = (compositor->draw_next_frame==1) ? 1 : 0; + frame_drawn = (compositor->frame_draw_type==GF_SC_DRAW_FRAME) ? 1 : 0; /*if invalidated, draw*/ - if (compositor->draw_next_frame) { + if (compositor->frame_draw_type) { GF_Window rc; #ifndef GPAC_DISABLE_LOG traverse_time = gf_sys_clock(); @@ -1793,15 +1956,24 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) #endif /*video flush only*/ - if (compositor->draw_next_frame==2) { - compositor->draw_next_frame = 0; + if (compositor->frame_draw_type==GF_SC_DRAW_FLUSH) { + compositor->frame_draw_type = 0; } else { - compositor->draw_next_frame = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Redrawing scene\n")); + compositor->frame_draw_type = 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] Redrawing scene - OTB %d\n", sim_time)); gf_sc_draw_scene(compositor); #ifndef GPAC_DISABLE_LOG traverse_time = gf_sys_clock() - traverse_time; #endif + + if (compositor->video_listeners && !compositor->skip_flush) { + u32 k=0; + GF_VideoListener *l; + while ((l = gf_list_enum(compositor->video_listeners, &k))) { + l->on_video_frame(l->udta, gf_sc_ar_get_clock(compositor->audio_renderer) ); + } + } + } /*and flush*/ #ifndef GPAC_DISABLE_LOG @@ -1826,7 +1998,7 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) compositor->last_had_overlays = compositor->visual->has_overlays; if (compositor->stress_mode) { - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); compositor->reset_graphics = 1; } compositor->reset_fonts = 0; @@ -1854,19 +2026,11 @@ void gf_sc_simulation_tick(GF_Compositor *compositor) end_time = gf_sys_clock() - in_time; -#ifdef TRISCOPE_TEST_FRAMERATE -TIMER_STOP; -drawing_time=TIMER_ELAPSED; -printf("frame: %d ", timer_count) ; -printf(" %f sec\n", drawing_time/1000000.0) ; -timer_count++; -#endif - GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI, ("[RTI]\tCompositor Cycle Log\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", compositor->networks_time, compositor->decoders_time, compositor->frame_number, - compositor->traverse_state->direct_draw, + compositor->traverse_state->immediate_draw, compositor->visual_config_time, event_time, route_time, @@ -1882,27 +2046,37 @@ timer_count++; flush_time, end_time)); - gf_sc_lock(compositor, 0); - - compositor->current_frame = (compositor->current_frame+1) % GF_SR_FPS_COMPUTE_SIZE; - compositor->frame_time[compositor->current_frame] = end_time; + if (frame_drawn) { + compositor->current_frame = (compositor->current_frame+1) % GF_SR_FPS_COMPUTE_SIZE; + compositor->frame_time[compositor->current_frame] = end_time; + compositor->frame_number++; + } - compositor->frame_number++; + gf_sc_lock(compositor, 0); +#if 0 /*step mode on, pause and return*/ - if (compositor->step_mode) { + if (frame_drawn && compositor->step_mode) { compositor->step_mode = 0; if (compositor->term) gf_term_set_option(compositor->term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); return; } +#else + if (frame_drawn) compositor->step_mode = 0; +#endif + /*not threaded, let the owner decide*/ - if ((compositor->user->init_flags & GF_TERM_NO_VISUAL_THREAD) || !compositor->frame_duration) return; + if ((compositor->user->init_flags & GF_TERM_NO_THREAD) || !compositor->frame_duration) return; - /*compute sleep time till next frame, otherwise we'll kill the CPU*/ - i = end_time / compositor->frame_duration + 1; -// while (i * compositor->frame_duration < end_time) i++; - in_time = i * compositor->frame_duration - end_time; - gf_sleep(in_time); + /*TO CHECK - THERE WAS A BUG HERE WITH TRISCOPE@SHIX*/ + if (end_time > compositor->frame_duration) { + gf_sleep(0); + return; + } + + /*compute sleep time till next frame*/ + end_time %= compositor->frame_duration; + gf_sleep(compositor->frame_duration - end_time); } Bool gf_sc_visual_is_registered(GF_Compositor *compositor, GF_VisualManager *visual) @@ -1928,16 +2102,27 @@ void gf_sc_visual_unregister(GF_Compositor *compositor, GF_VisualManager *visual void gf_sc_traverse_subscene(GF_Compositor *compositor, GF_Node *inline_parent, GF_SceneGraph *subscene, void *rs) { - Fixed min_hsize; + Fixed min_hsize, vp_scale; Bool use_pm, prev_pm, prev_coord; SFVec2f prev_vp; s32 flip_coords; u32 h, w, tag; GF_Matrix2D transf; GF_SceneGraph *in_scene; - GF_Node *inline_root = gf_sg_get_root_node(subscene); + GF_Node *inline_root; GF_TraverseState *tr_state = (GF_TraverseState *)rs; - if (!inline_root) return; + + /*we don't traverse subscenes until the root one is setup*/ + if (!compositor->root_visual_setup) return; + + if (!gf_scene_lock(subscene, 1)) + return; + + inline_root = gf_sg_get_root_node(subscene); + if (!inline_root) { + gf_scene_lock(subscene, 0); + return; + } flip_coords = 0; in_scene = gf_node_get_graph(inline_root); @@ -1948,6 +2133,7 @@ void gf_sc_traverse_subscene(GF_Compositor *compositor, GF_Node *inline_parent, /*check child doc*/ tag = gf_node_get_tag(inline_root); if (tag < GF_NODE_RANGE_LAST_VRML) { +#ifndef GPAC_DISABLE_VRML u32 new_tag = 0; use_pm = gf_sg_use_pixel_metrics(in_scene); if (gf_node_get_tag(inline_parent)>GF_NODE_RANGE_LAST_VRML) { @@ -1958,7 +2144,11 @@ void gf_sc_traverse_subscene(GF_Compositor *compositor, GF_Node *inline_parent, of bindable stacks and gives us free 2D/3D integration*/ if (tag==TAG_MPEG4_OrderedGroup) { new_tag = TAG_MPEG4_Layer2D; - } else if ((tag==TAG_MPEG4_Group) || (tag==TAG_X3D_Group)) { + } else if ((tag==TAG_MPEG4_Group) +#ifndef GPAC_DISABLE_X3D + || (tag==TAG_X3D_Group) +#endif + ) { new_tag = TAG_MPEG4_Layer3D; } } @@ -1983,7 +2173,10 @@ void gf_sc_traverse_subscene(GF_Compositor *compositor, GF_Node *inline_parent, gf_node_init(new_root); } +#endif /*GPAC_DISABLE_VRML*/ + gf_sg_get_scene_size_info(in_scene, &w, &h); + } else { use_pm = 1; if (gf_node_get_tag(inline_parent)<GF_NODE_RANGE_LAST_VRML) { @@ -1996,6 +2189,7 @@ void gf_sc_traverse_subscene(GF_Compositor *compositor, GF_Node *inline_parent, prev_pm = tr_state->pixel_metrics; prev_vp = tr_state->vp_size; prev_coord = tr_state->fliped_coords; + vp_scale = FIX_ONE; gf_mx2d_init(transf); /*compute center<->top-left transform*/ @@ -2003,8 +2197,12 @@ void gf_sc_traverse_subscene(GF_Compositor *compositor, GF_Node *inline_parent, gf_mx2d_add_scale(&transf, FIX_ONE, -FIX_ONE); /*if scene size is given in the child document, scale to fit the entire vp*/ - if (w && h) - gf_mx2d_add_scale(&transf, tr_state->vp_size.x/w, tr_state->vp_size.y/h); + if (w && h) { + Fixed scale_w = tr_state->vp_size.x/w; + Fixed scale_h = tr_state->vp_size.y/h; + vp_scale = MIN(scale_w, scale_h); + gf_mx2d_add_scale(&transf, vp_scale, vp_scale); + } if (flip_coords) { gf_mx2d_add_translation(&transf, flip_coords * tr_state->vp_size.x/2, tr_state->vp_size.y/2); tr_state->fliped_coords = !tr_state->fliped_coords; @@ -2013,8 +2211,8 @@ void gf_sc_traverse_subscene(GF_Compositor *compositor, GF_Node *inline_parent, /*if scene size is given in the child document, scale back vp to take into account the above scale otherwise the scene won't be properly clipped*/ if (w && h) { - tr_state->vp_size.x = INT2FIX(w); - tr_state->vp_size.y = INT2FIX(h); + tr_state->vp_size.x = gf_divfix(tr_state->vp_size.x, vp_scale); + tr_state->vp_size.y = gf_divfix(tr_state->vp_size.y, vp_scale); } @@ -2038,12 +2236,11 @@ void gf_sc_traverse_subscene(GF_Compositor *compositor, GF_Node *inline_parent, if (tr_state->visual->type_3d) { GF_Matrix mx_bck, mx; gf_mx_copy(mx_bck, tr_state->model_matrix); + gf_mx_from_mx2d(&mx, &transf); /*copy over z scale*/ mx.m[10] = mx.m[5]; - gf_mx_add_matrix(&mx, &tr_state->model_matrix); - gf_mx_copy(tr_state->model_matrix, mx); - + gf_mx_add_matrix(&tr_state->model_matrix, &mx); if (tr_state->traversing_mode==TRAVERSE_SORT) { visual_3d_matrix_push(tr_state->visual); visual_3d_matrix_add(tr_state->visual, mx.m); @@ -2068,6 +2265,8 @@ void gf_sc_traverse_subscene(GF_Compositor *compositor, GF_Node *inline_parent, tr_state->min_hsize = min_hsize; tr_state->vp_size = prev_vp; tr_state->fliped_coords = prev_coord; + + gf_scene_lock(subscene, 0); } @@ -2077,6 +2276,7 @@ static Bool gf_sc_handle_event_intern(GF_Compositor *compositor, GF_Event *event GF_Event *ev; #else Bool ret; + u32 retry; #endif if (compositor->term && (compositor->interaction_level & GF_INTERACT_INPUT_SENSOR) && (event->type<=GF_EVENT_MOUSEWHEEL)) { @@ -2109,7 +2309,7 @@ static Bool gf_sc_handle_event_intern(GF_Compositor *compositor, GF_Event *event gf_mx_v(compositor->ev_mx); } default: - ev = (GF_Event *)malloc(sizeof(GF_Event)); + ev = (GF_Event *)gf_malloc(sizeof(GF_Event)); ev->type = event->type; if (event->type<=GF_EVENT_MOUSEWHEEL) { ev->mouse = event->mouse; @@ -2125,11 +2325,22 @@ static Bool gf_sc_handle_event_intern(GF_Compositor *compositor, GF_Event *event } return 0; #else - gf_sc_lock(compositor, 1); + + retry = 100; + while (retry) { + if (gf_mx_try_lock(compositor->mx)) + break; + retry--; + gf_sleep(1); + if (!retry) { + return 0; + } + } ret = gf_sc_exec_event(compositor, event); gf_sc_lock(compositor, 0); - if (!ret && !from_user) { - gf_sc_forward_event(compositor, event); + + if (!from_user) { + gf_sc_forward_event(compositor, event, ret); } return ret; #endif @@ -2146,18 +2357,18 @@ static Bool gf_sc_on_event_ex(GF_Compositor *compositor , GF_Event *event, Bool switch (event->type) { case GF_EVENT_MOVE: case GF_EVENT_REFRESH: - if (!compositor->draw_next_frame) { + if (!compositor->frame_draw_type) { /*when refreshing the window in 3D or with overlays we redraw the scene */ if (compositor->last_had_overlays #ifndef GPAC_DISABLE_3D || compositor->visual->type_3d #endif ) { - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); } /*reflush only*/ else - compositor->draw_next_frame = 2; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FLUSH); } break; case GF_EVENT_VIDEO_SETUP: @@ -2169,15 +2380,17 @@ static Bool gf_sc_on_event_ex(GF_Compositor *compositor , GF_Event *event, Bool /*EXTRA CARE HERE: the caller (video output) is likely a different thread than the compositor one, and the compositor may be locked on the video output (flush or whatever)!! */ - Bool lock_ok = gf_mx_try_lock(compositor->mx); - compositor->new_width = event->size.width; - compositor->new_height = event->size.height; - compositor->msg_type |= GF_SR_CFG_SET_SIZE; - if (lock_ok) gf_sc_lock(compositor, 0); + if ((compositor->display_width!=event->size.width) || (compositor->display_height!=event->size.height)) { + Bool lock_ok = gf_mx_try_lock(compositor->mx); + compositor->new_width = event->size.width; + compositor->new_height = event->size.height; + compositor->msg_type |= GF_SR_CFG_SET_SIZE; + if (lock_ok) gf_sc_lock(compositor, 0); + } } /*otherwise let the user decide*/ else { - return GF_USER_SENDEVENT(compositor->user, event); + return gf_term_send_event(compositor->term, event); } break; @@ -2206,57 +2419,6 @@ static Bool gf_sc_on_event_ex(GF_Compositor *compositor , GF_Event *event, Bool } break; -#ifdef GPAC_TRISCOPE_MODE - case GF_KEY_JOYSTICK: - if (event->type==GF_EVENT_KEYUP) { - const char *sOpt; - switch (event->key.hw_code) { - case 4: - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "3dsDepthBuffGain"); - if (sOpt) sscanf(sOpt, "%f", &((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthGain); else ((GF_RenoirHandler *) compositor->RenoirHandler)->MapDepthGain = 1; - ((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthGain -= 5; - sprintf(sOpt, "%f", ((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthGain); - gf_cfg_set_key(compositor->user->config, "Compositor", "3dsDepthBuffGain", sOpt); - /*we'll change it also for flat objects, thus both will be the same*/ - gf_cfg_set_key(compositor->user->config, "Compositor", "FlatDepthBuffGain", sOpt); - gf_cfg_save(compositor->user->config); - return 0; - - case 5: - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "3dsDepthBuffOffset"); - if (sOpt) sscanf(sOpt, "%f", &((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthOffset); else ((GF_RenoirHandler *) compositor->RenoirHandler)->MapDepthOffset = 0; - ((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthOffset -= 5; - sprintf(sOpt, "%f", ((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthOffset); - gf_cfg_set_key(compositor->user->config, "Compositor", "3dsDepthBuffOffset", sOpt); - gf_cfg_save(compositor->user->config); - return 0; - - case 6: - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "3dsDepthBuffGain"); - if (sOpt) sscanf(sOpt, "%f", &((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthGain); else ((GF_RenoirHandler *) compositor->RenoirHandler)->MapDepthGain = 1; - ((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthGain += 5; - sprintf(sOpt, "%f", ((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthGain); - gf_cfg_set_key(compositor->user->config, "Compositor", "3dsDepthBuffGain", sOpt); - /*we'll change it also for flat objects, thus both will be the same*/ - gf_cfg_set_key(compositor->user->config, "Compositor", "FlatDepthBuffGain", sOpt); - gf_cfg_save(compositor->user->config); - return 0; - - case 7: - sOpt = gf_cfg_get_key(compositor->user->config, "Compositor", "3dsDepthBuffOffset"); - if (sOpt) sscanf(sOpt, "%f", &((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthOffset); else ((GF_RenoirHandler *) compositor->RenoirHandler)->MapDepthOffset = 0; - ((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthOffset += 5; - sprintf(sOpt, "%f", ((GF_RenoirHandler *)compositor->RenoirHandler)->MapDepthOffset); - gf_cfg_set_key(compositor->user->config, "Compositor", "3dsDepthBuffOffset", sOpt); - gf_cfg_save(compositor->user->config); - return 0; - - default: - break; - } - } - break; -#endif } event->key.flags |= compositor->key_states; @@ -2291,7 +2453,7 @@ static Bool gf_sc_on_event_ex(GF_Compositor *compositor , GF_Event *event, Bool /*when we process events we don't forward them to the user*/ default: - return GF_USER_SENDEVENT(compositor->user, event); + return gf_term_send_event(compositor->term, event); } /*if we get here, event has been consumed*/ return 1; @@ -2368,17 +2530,21 @@ Bool gf_sc_script_action(GF_Compositor *compositor, u32 type, GF_Node *n, GF_JSA tr_state.vp_size = compositor->traverse_state->vp_size; tr_state.for_node = n; tr_state.ignore_strike = 1; + tr_state.min_hsize = compositor->traverse_state->min_hsize; + tr_state.pixel_metrics = compositor->traverse_state->pixel_metrics; gf_mx2d_init(tr_state.transform); gf_mx2d_init(tr_state.mx_at_node); if (type==GF_JSAPI_OP_GET_LOCAL_BBOX) { +#ifndef GPAC_DISABLE_SVG GF_SAFEALLOC(tr_state.svg_props, SVGPropertiesPointers); gf_svg_properties_init_pointers(tr_state.svg_props); tr_state.abort_bounds_traverse=1; gf_node_traverse(n, &tr_state); gf_svg_properties_reset_pointers(tr_state.svg_props); - free(tr_state.svg_props); + gf_free(tr_state.svg_props); +#endif } else { gf_node_traverse(gf_sg_get_root_node(compositor->scene), &tr_state); } @@ -2400,15 +2566,17 @@ Bool gf_sc_script_action(GF_Compositor *compositor, u32 type, GF_Node *n, GF_JSA return 1; case GF_JSAPI_OP_LOAD_URL: { +#ifndef GPAC_DISABLE_VRML GF_Node *target; char *sub_url = strrchr(param->uri.url, '#'); if (!sub_url) return 0; target = gf_sg_find_node_by_name(gf_node_get_graph(n), sub_url+1); if (target && (gf_node_get_tag(target)==TAG_MPEG4_Viewport) ) { ((M_Viewport *)target)->set_bind = 1; - ((M_Viewport *)target)->on_set_bind(n); + ((M_Viewport *)target)->on_set_bind(n, NULL); return 1; } +#endif return 0; } case GF_JSAPI_OP_GET_FPS: @@ -2423,7 +2591,7 @@ Bool gf_sc_script_action(GF_Compositor *compositor, u32 type, GF_Node *n, GF_JSA #endif return 1; case GF_JSAPI_OP_PAUSE_SVG: - { + if (n) { u32 tag = gf_node_get_tag(n); switch(tag) { #ifndef GPAC_DISABLE_SVG @@ -2432,6 +2600,8 @@ Bool gf_sc_script_action(GF_Compositor *compositor, u32 type, GF_Node *n, GF_JSA case TAG_SVG_animation: svg_pause_animation(n, 1); break; #endif } + } else { + return 0; } return 1; case GF_JSAPI_OP_RESUME_SVG: @@ -2446,6 +2616,12 @@ Bool gf_sc_script_action(GF_Compositor *compositor, u32 type, GF_Node *n, GF_JSA } } return 1; + case GF_JSAPI_OP_GET_DPI_X: + param->opt = compositor->video_out->dpi_x; + return 1; + case GF_JSAPI_OP_GET_DPI_Y: + param->opt = compositor->video_out->dpi_y; + return 1; } return 0; } @@ -2496,7 +2672,7 @@ const char *gf_sc_get_selected_text(GF_Compositor *compositor) compositor->traverse_state->traversing_mode = TRAVERSE_GET_TEXT; if (compositor->sel_buffer) { - free(compositor->sel_buffer); + gf_free(compositor->sel_buffer); compositor->sel_buffer = NULL; } compositor->sel_buffer_len = 0; @@ -2505,8 +2681,8 @@ const char *gf_sc_get_selected_text(GF_Compositor *compositor) compositor->traverse_state->traversing_mode = 0; compositor->sel_buffer[compositor->sel_buffer_len]=0; srcp = compositor->sel_buffer; - if (compositor->selected_text) free(compositor->selected_text); - compositor->selected_text = malloc(sizeof(char)*2*compositor->sel_buffer_len); + if (compositor->selected_text) gf_free(compositor->selected_text); + compositor->selected_text = gf_malloc(sizeof(char)*2*compositor->sel_buffer_len); len = gf_utf8_wcstombs(compositor->selected_text, 2*compositor->sel_buffer_len, &srcp); if ((s32)len<0) len = 0; compositor->selected_text[len] = 0; @@ -2519,12 +2695,40 @@ const char *gf_sc_get_selected_text(GF_Compositor *compositor) void gf_sc_check_focus_upon_destroy(GF_Node *n) { GF_Compositor *compositor = gf_sc_get_compositor(n); - if (compositor && (compositor->focus_node==n)) { + if (!compositor) return; + + if (compositor->focus_node==n) { compositor->focus_node = NULL; compositor->focus_text_type = 0; compositor->focus_uses_dom_events = 0; gf_list_reset(compositor->focus_ancestors); gf_list_reset(compositor->focus_use_stack); } + if (compositor->hit_node==n) compositor->hit_node = NULL; + if (compositor->hit_text==n) compositor->hit_text = NULL; } +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; + + gf_sc_lock(sc, 1); + if (!sc->video_listeners) sc->video_listeners = gf_list_new(); + gf_list_add(sc->video_listeners, vl); + gf_sc_lock(sc, 0); + return GF_OK; +} + +GF_Err gf_sc_remove_video_listener(GF_Compositor *sc, GF_VideoListener *vl) +{ + if (!sc|| !vl) return GF_BAD_PARAM; + + gf_sc_lock(sc, 1); + gf_list_del_item(sc->video_listeners, vl); + if (!gf_list_count(sc->video_listeners)) { + gf_list_del(sc->video_listeners); + sc->video_listeners = NULL; + } + gf_sc_lock(sc, 0); + return GF_OK; +} diff --git a/src/compositor/compositor_2d.c b/src/compositor/compositor_2d.c index 6f5d664..44caeef 100644 --- a/src/compositor/compositor_2d.c +++ b/src/compositor/compositor_2d.c @@ -28,8 +28,143 @@ #include "nodes_stacks.h" #include <gpac/options.h> -#ifdef GPAC_TRISCOPE_MODE -#include "../src/compositor/triscope_renoir/triscope_renoir.h" +#ifdef OPENGL_RASTER +#include "gl_inc.h" +#include "texturing.h" + +static void c2d_gl_fill_no_alpha(void *cbk, u32 x, u32 y, u32 run_h_len, GF_Color color) +{ +#if defined(GPAC_USE_OGL_ES) + GLfloat line[4]; + + line[0] = FIX2FLT(x); + line[1] = FIX2FLT(y); + line[2] = FIX2FLT(x+run_h_len); + line[3] = line[1]; + + glColor4ub(GF_COL_R(color), GF_COL_G(color), GF_COL_B(color), 0xFF); + glVertexPointer(2, GL_FLOAT, 0, line); + glEnableClientState(GL_VERTEX_ARRAY); + glDrawArrays(GL_LINES, 0, 2); + glDisableClientState(GL_VERTEX_ARRAY); + +#else + glBegin(GL_LINES); + glColor3ub(GF_COL_R(color), GF_COL_G(color), GF_COL_B(color)); +// glColor3f(GF_COL_R(color)/255, GF_COL_G(color)/255, GF_COL_B(color)/255); + glVertex2i(x,y); + glVertex2i(x+run_h_len,y); + glEnd(); +#endif +} + +static void c2d_gl_fill_alpha(void *cbk, u32 x, u32 y, u32 run_h_len, GF_Color color, u8 alpha) +{ +#if defined(GPAC_USE_OGL_ES) + GLfloat line[4]; + + line[0] = FIX2FLT(x); + line[1] = FIX2FLT(y); + line[2] = FIX2FLT(x+run_h_len); + line[3] = line[1]; + + glEnable(GL_BLEND); + glColor4ub(GF_COL_R(color), GF_COL_G(color), GF_COL_B(color), (u8) alpha); + + glVertexPointer(2, GL_FLOAT, 0, line); + glEnableClientState(GL_VERTEX_ARRAY); + glDrawArrays(GL_LINES, 0, 2); + glDisableClientState(GL_VERTEX_ARRAY); + + glDisable(GL_BLEND); +#else + glEnable(GL_BLEND); + glColor4ub(GF_COL_R(color), GF_COL_G(color), GF_COL_B(color), (u8) alpha); + glBegin(GL_LINES); + glVertex2i(x,y); + glVertex2i(x+run_h_len,y); + glEnd(); + glDisable(GL_BLEND); +#endif +} + +static void c2d_gl_fill_rect(void *cbk, u32 x, u32 y, u32 width, u32 height, GF_Color color) +{ +#if defined(GPAC_USE_OGL_ES) + GLfloat line[8]; + + line[0] = FIX2FLT(x); + line[1] = FIX2FLT(y); + line[2] = FIX2FLT(x+width); + line[3] = FIX2FLT(y); + line[4] = FIX2FLT(x+width); + line[5] = FIX2FLT(y+height); + line[6] = FIX2FLT(x); + line[7] = FIX2FLT(y+height); + + glEnable(GL_BLEND); + glColor4ub(GF_COL_R(color), GF_COL_G(color), GF_COL_B(color), GF_COL_A(color)); + + glVertexPointer(4, GL_FLOAT, 0, line); + glEnableClientState(GL_VERTEX_ARRAY); + glDrawArrays(GL_TRIANGLE_FAN, 0, 2); + glDisableClientState(GL_VERTEX_ARRAY); + + glDisable(GL_BLEND); +#else + glEnable(GL_BLEND); + glColor4ub(GF_COL_R(color), GF_COL_G(color), GF_COL_B(color), GF_COL_A(color)); + glBegin(GL_TRIANGLES); + glVertex2i(x,y); + glVertex2i(x+width,y); + glVertex2i(x+width,y+height); + glEnd(); + glBegin(GL_TRIANGLES); + glVertex2i(x,y); + glVertex2i(x+width,y+height); + glVertex2i(x,y+height); + glEnd(); + glDisable(GL_BLEND); +#endif +} + + +Bool c2d_gl_draw_bitmap(GF_VisualManager *visual, GF_TraverseState *tr_state, DrawableContext *ctx, GF_ColorKey *col_key) +{ + u8 alpha = GF_COL_A(ctx->aspect.fill_color); + + if (ctx->transform.m[1] || ctx->transform.m[3]) return 0; + + visual_3d_set_state(visual, V3D_STATE_LIGHT, 0); + visual_3d_enable_antialias(visual, 0); + if (alpha && (alpha != 0xFF)) { + visual_3d_set_material_2d_argb(visual, ctx->aspect.fill_color); + gf_sc_texture_set_blend_mode(ctx->aspect.fill_texture, TX_MODULATE); + } else if (gf_sc_texture_is_transparent(ctx->aspect.fill_texture)) { + gf_sc_texture_set_blend_mode(ctx->aspect.fill_texture, TX_REPLACE); + } else { + visual_3d_set_state(visual, V3D_STATE_BLEND, 0); + } + /*ignore texture transform for bitmap*/ + tr_state->mesh_num_textures = gf_sc_texture_enable(ctx->aspect.fill_texture, tr_state->appear ? ((M_Appearance *)tr_state->appear)->textureTransform : NULL); + if (tr_state->mesh_num_textures) { + SFVec2f size, orig; + GF_Mesh *mesh; + size.x = ctx->bi->unclip.width; + size.y = ctx->bi->unclip.height; + orig.x = ctx->bi->unclip.x + INT2FIX(visual->compositor->vp_width)/2; + orig.y = INT2FIX(visual->compositor->vp_height)/2 - ctx->bi->unclip.y + ctx->bi->unclip.height; + + mesh = new_mesh(); + mesh_new_rectangle(mesh, size, &orig, 1); + visual_3d_mesh_paint(tr_state, mesh); + mesh_free(mesh); + gf_sc_texture_disable(ctx->aspect.fill_texture); + tr_state->mesh_num_textures = 0; + return 1; + } + return 0; +} #endif GF_Err compositor_2d_get_video_access(GF_VisualManager *visual) @@ -37,12 +172,80 @@ GF_Err compositor_2d_get_video_access(GF_VisualManager *visual) GF_Err e; GF_Compositor *compositor = visual->compositor; + if (!visual->raster_surface) return GF_BAD_PARAM; + +#ifdef OPENGL_RASTER + if (compositor->opengl_raster && compositor->rasterizer->surface_attach_to_callbacks) { + GLenum err; + GF_RasterCallback callbacks; + callbacks.cbk = visual; + callbacks.fill_run_alpha = c2d_gl_fill_alpha; + callbacks.fill_run_no_alpha = c2d_gl_fill_no_alpha; + callbacks.fill_rect = c2d_gl_fill_rect; + + visual->DrawBitmap = c2d_gl_draw_bitmap; + + e = compositor->rasterizer->surface_attach_to_callbacks(visual->raster_surface, &callbacks, compositor->vp_width, compositor->vp_height); + if (e==GF_OK) { + GF_Matrix mx; + Fixed hh, hw; + visual->is_attached = 2; + + visual_3d_setup(visual); + glClear(GL_DEPTH_BUFFER_BIT); + glViewport(0, 0, compositor->vp_width, compositor->vp_height); + + glClear(GL_COLOR_BUFFER_BIT); + + glLineWidth(1.0f); + +#ifndef GPAC_USE_OGL_ES + glDisable(GL_POLYGON_SMOOTH); +#endif + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); + + glDisable(GL_NORMALIZE); + glDisable(GL_LINE_SMOOTH); + glDisable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthFunc(GL_LEQUAL); + + hw = INT2FIX(compositor->vp_width)/2; + hh = INT2FIX(compositor->vp_height)/2; + gf_mx_ortho(&mx, -hw, hw, -hh, hh, 50, -50); + glMatrixMode(GL_PROJECTION); +#ifdef GPAC_USE_OGL_ES + glLoadMatrixx(mx.m); +#else + glLoadMatrixf(mx.m); +#endif + err = glGetError(); + glMatrixMode(GL_MODELVIEW); + gf_mx_init(mx); + gf_mx_add_scale(&mx, 1, -1, 1); + gf_mx_add_translation(&mx, -hw, -hh, 0); +#ifdef GPAC_USE_OGL_ES + glLoadMatrixx(mx.m); +#else + glLoadMatrixf(mx.m); +#endif + err = glGetError(); + return GF_OK; + } + } +#endif + + compositor->hw_locked = 0; e = GF_IO_ERR; - /*try from device*/ - if (compositor->rasterizer->surface_attach_to_device && compositor->video_out->LockOSContext) { + /*try from video memory handle (WIN32) if supported*/ + if ((compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_HWND_HDC) + && compositor->rasterizer->surface_attach_to_device + && compositor->video_out->LockOSContext + ) { compositor->hw_context = compositor->video_out->LockOSContext(compositor->video_out, 1); if (compositor->hw_context) { e = compositor->rasterizer->surface_attach_to_device(visual->raster_surface, compositor->hw_context, compositor->vp_width, compositor->vp_height); @@ -55,27 +258,37 @@ GF_Err compositor_2d_get_video_access(GF_VisualManager *visual) GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor2D] Cannot attach video surface handle to raster: %s\n", gf_error_to_string(e) )); } } + + if (compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_LINE_BLIT) { + e = compositor->rasterizer->surface_attach_to_callbacks(visual->raster_surface, &compositor->raster_callbacks, compositor->vp_width, compositor->vp_height); + if (!e) { + visual->is_attached = 1; + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor2D] Video surface callbacks attached to raster\n")); + return GF_OK; + } + GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor2D] Failed to attach video surface callbacks to raster\n")); + } - /*TODO - collect hw accelerated blit routines if any*/ + e = GF_NOT_SUPPORTED; if (compositor->video_out->LockBackBuffer(compositor->video_out, &compositor->hw_surface, 1)==GF_OK) { compositor->hw_locked = 1; + e = compositor->rasterizer->surface_attach_to_buffer(visual->raster_surface, compositor->hw_surface.video_buffer, compositor->hw_surface.width, compositor->hw_surface.height, - compositor->hw_surface.pitch, + compositor->hw_surface.pitch_x, + compositor->hw_surface.pitch_y, (GF_PixelFormat) compositor->hw_surface.pixel_format); if (!e) { visual->is_attached = 1; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor2D] Video surface memory attached to raster\n")); -#ifdef GPAC_TRISCOPE_MODE - /*CALL SNOUTPUT FOR RENOIR*/ - SetRenoirOutput(compositor); -#endif + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor2D] Video surface memory attached to raster - w=%d h=%d pitch_x=%d pitch_y=%d\n", compositor->hw_surface.width, compositor->hw_surface.height, compositor->hw_surface.pitch_x, compositor->hw_surface.pitch_y)); return GF_OK; } GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor2D] Cannot attach video surface memory to raster: %s\n", gf_error_to_string(e) )); compositor->video_out->LockBackBuffer(compositor->video_out, &compositor->hw_surface, 0); + } else { + e = GF_OK; } compositor->hw_locked = 0; visual->is_attached = 0; @@ -104,7 +317,7 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan GF_VideoSurface video_src; Fixed w_scale, h_scale, tmp; GF_Err e; - Bool use_soft_stretch, use_blit, flush_video; + Bool use_soft_stretch, use_blit, flush_video, is_attached; u32 overlay_type; GF_Window src_wnd, dst_wnd; u32 output_width, output_height, hw_caps; @@ -182,12 +395,20 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan #ifdef GPAC_FIXED_POINT #define ROUND_FIX(_v) \ _v = FIX2INT(tmp); +#define CEILING(_v) \ + _v = FIX2INT(tmp); \ + if (INT2FIX(_v)!=tmp) _v++; #else #define ROUND_FIX(_v) \ _v = FIX2INT(tmp); \ tmp -= INT2FIX(_v); \ if (tmp>99*FIX_ONE/100) { _v++; tmp = 0; } \ if (ABS(tmp) > FIX_EPSILON) use_blit = 0; +#define CEILING(_v) \ + _v = FIX2INT(tmp); \ + tmp -= INT2FIX(_v); \ + if (tmp>0) { _v++; tmp = 0; } \ + if (ABS(tmp) > FIX_EPSILON) use_blit = 0; #endif use_blit = 1; @@ -195,11 +416,11 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan src_wnd.x = src_wnd.y = 0; tmp = gf_divfix(INT2FIX(clipped_final.x) - final.x, w_scale); if (tmp<0) tmp=0; - ROUND_FIX(src_wnd.x); + CEILING(src_wnd.x); tmp = gf_divfix(INT2FIX(clipped_final.y) - final.y, h_scale); if (tmp<0) tmp=0; - ROUND_FIX(src_wnd.y); + CEILING(src_wnd.y); tmp = gf_divfix(INT2FIX(clip->width), w_scale); ROUND_FIX(src_wnd.w); @@ -217,6 +438,8 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan if (src_wnd.x + src_wnd.w>txh->width) src_wnd.w = txh->width - src_wnd.x; if (src_wnd.y + src_wnd.h>txh->height) src_wnd.h = txh->height - src_wnd.y; + if (!src_wnd.w || !src_wnd.h) return 0; + /*can we use hardware blitter ?*/ hw_caps = visual->compositor->video_out->hw_caps; overlay_type = 0; @@ -232,11 +455,21 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan switch (txh->pixelformat) { case GF_PIXEL_RGB_24: case GF_PIXEL_BGR_24: - use_soft_stretch = 0; + case GF_PIXEL_RGB_555: + case GF_PIXEL_RGB_565: + if (hw_caps & GF_VIDEO_HW_HAS_RGB) + use_soft_stretch = 0; + break; + case GF_PIXEL_ARGB: + case GF_PIXEL_RGBA: + case GF_PIXEL_RGBDS: + if (hw_caps & GF_VIDEO_HW_HAS_RGBA) + use_soft_stretch = 0; break; case GF_PIXEL_YV12: case GF_PIXEL_IYUV: case GF_PIXEL_I420: + case GF_PIXEL_YUVD: if (hw_caps & GF_VIDEO_HW_HAS_YUV) use_soft_stretch = 0; else if (hw_caps & GF_VIDEO_HW_HAS_YUV_OVERLAY) overlay_type = 1; break; @@ -267,7 +500,7 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan overlay_type = 0; } /*direct draw or not last context: we must queue the overlay*/ - else if (tr_state->direct_draw || (ctx->next && ctx->next->drawable)) { + else if (tr_state->immediate_draw || (ctx->next && ctx->next->drawable)) { overlay_type = 2; } /*OK we can overlay this video - if full display, don't flush*/ @@ -286,10 +519,15 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan video_src.height = txh->height; video_src.width = txh->width; - video_src.pitch = txh->stride; + video_src.pitch_x = 0; + video_src.pitch_y = txh->stride; video_src.pixel_format = txh->pixelformat; +#ifdef GF_SR_USE_DEPTH + if (txh->pixelformat==GF_PIXEL_YUVD) video_src.pixel_format = GF_PIXEL_YV12; +#endif video_src.video_buffer = txh->data; if (overlay_type) { + if (overlay_type==2) { GF_IRect o_rc; GF_OverlayStack *ol, *first; @@ -312,18 +550,19 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan o_rc.y = output_height/2- dst_wnd.y; } else { o_rc.x = dst_wnd.x; - o_rc.y = dst_wnd.y; + o_rc.y = dst_wnd.y + dst_wnd.h; } + o_rc.width = dst_wnd.w; o_rc.height = dst_wnd.h; - visual_2d_clear(visual, &o_rc, visual->compositor->video_out->overlay_color_key); + visual->ClearSurface(visual, &o_rc, visual->compositor->video_out->overlay_color_key); visual->has_overlays = 1; /*mark drawable as overlay*/ ctx->drawable->flags |= DRAWABLE_IS_OVERLAY; /*prevents this context from being removed in direct draw mode by requesting a new one but not allocating it*/ - if (tr_state->direct_draw) + if (tr_state->immediate_draw) visual_2d_get_drawable_context(visual); return 1; } @@ -350,20 +589,25 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor2D] Error during overlay blit - trying with soft one\n")); visual->compositor->skip_flush = 0; } - + /*most graphic cards can't perform bliting on locked surface - force unlock by releasing the hardware*/ - visual_2d_release_raster(visual); + is_attached = visual->is_attached; + if (is_attached) visual_2d_release_raster(visual); if (!use_soft_stretch) { e = visual->compositor->video_out->Blit(visual->compositor->video_out, &video_src, &src_wnd, &dst_wnd, 0); /*HW pb, try soft*/ if (e) { - GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor2D] Error during hardware blit - trying with soft one\n")); use_soft_stretch = 1; - if (!visual->compositor->video_memory) { - GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Compositor2D] Reconfiguring video output to use video memory\n")); + if (visual->compositor->video_memory) { + GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor2D] Error during hardware blit - trying with soft one\n")); + visual->compositor->video_memory = 2; + } + /*force a reconfigure of video output*/ + else { visual->compositor->video_memory = 1; visual->compositor->root_visual_setup = 0; + gf_sc_next_frame_state(visual->compositor, GF_SC_DRAW_FRAME); } } } @@ -371,14 +615,20 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan GF_VideoSurface backbuffer; e = visual->compositor->video_out->LockBackBuffer(visual->compositor->video_out, &backbuffer, 1); if (!e) { - gf_stretch_bits(&backbuffer, &video_src, &dst_wnd, &src_wnd, 0, alpha, 0, col_key, ctx->col_mat); + gf_stretch_bits(&backbuffer, &video_src, &dst_wnd, &src_wnd, alpha, 0, col_key, ctx->col_mat); e = visual->compositor->video_out->LockBackBuffer(visual->compositor->video_out, &backbuffer, 0); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Compositor2D] Cannot lock back buffer - Error %s\n", gf_error_to_string(e) )); } + if (!visual->compositor->video_memory) { + GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Compositor2D] Reconfiguring video output to use video memory\n")); + visual->compositor->video_memory = 1; + visual->compositor->root_visual_setup = 0; + gf_sc_next_frame_state(visual->compositor, GF_SC_DRAW_FRAME); + } } visual->has_modif = 1; - visual_2d_init_raster(visual); + if (is_attached) visual_2d_init_raster(visual); return 1; } @@ -387,7 +637,6 @@ static Bool compositor_2d_draw_bitmap_ex(GF_VisualManager *visual, GF_TextureHan Bool compositor_2d_draw_bitmap(GF_VisualManager *visual, GF_TraverseState *tr_state, DrawableContext *ctx, GF_ColorKey *col_key) { u8 alpha = 0xFF; - if (!ctx->aspect.fill_texture) return 1; /*check if texture is ready*/ @@ -401,14 +650,15 @@ Bool compositor_2d_draw_bitmap(GF_VisualManager *visual, GF_TraverseState *tr_st if (ctx->flags & CTX_FLIPED_COORDS) return 0; } if (ctx->transform.m[1] || ctx->transform.m[3]) return 0; +#ifndef GPAC_DISABLE_VRML if ((ctx->flags & CTX_HAS_APPEARANCE) && ctx->appear && ((M_Appearance*)ctx->appear)->textureTransform) return 0; +#endif alpha = GF_COL_A(ctx->aspect.fill_color); /*THIS IS A HACK, will not work when setting filled=0, transparency and XLineProps*/ if (!alpha) alpha = GF_COL_A(ctx->aspect.line_color); - ctx->aspect.fill_texture->flags |= GF_SR_TEXTURE_USED; if (!alpha) return 1; switch (ctx->aspect.fill_texture->pixelformat) { @@ -422,9 +672,9 @@ Bool compositor_2d_draw_bitmap(GF_VisualManager *visual, GF_TraverseState *tr_st case GF_PIXEL_IYUV: case GF_PIXEL_I420: case GF_PIXEL_YUVA: -#ifdef GPAC_TRISCOPE_MODE - case GF_PIXEL_RGBDS: -#endif + case GF_PIXEL_YUVD: + case GF_PIXEL_RGBD: + case GF_PIXEL_RGBDS: break; /*the rest has to be displayed through brush for now, we only use YUV and RGB pool*/ default: @@ -432,19 +682,20 @@ Bool compositor_2d_draw_bitmap(GF_VisualManager *visual, GF_TraverseState *tr_st } /*direct drawing, no clippers */ - if (tr_state->direct_draw) { - -#ifdef GPAC_TRISCOPE_MODE -#ifdef TRISCOPE_DEBUG - printf("\nEntering SetRenoirTexture...\n"); -#endif - return SetRenoirTexture(visual, ctx->aspect.fill_texture, ctx, &ctx->bi->clip, &ctx->bi->unclip, alpha, col_key, tr_state, 0); - -#else - return compositor_2d_draw_bitmap_ex(visual, ctx->aspect.fill_texture, ctx, &ctx->bi->clip, &ctx->bi->unclip, alpha, col_key, tr_state, 0); - + if (tr_state->immediate_draw) { + if (visual->compositor->video_out->BlitTexture) { + if (! visual->compositor->video_out->BlitTexture(visual->compositor->video_out, ctx->aspect.fill_texture, &ctx->transform, &ctx->bi->clip, alpha, col_key +#ifdef GF_SR_USE_DEPTH + , ctx->depth_offset, ctx->depth_gain +#else + , 0, 0 #endif - + )) + return 0; + } else { + if (!compositor_2d_draw_bitmap_ex(visual, ctx->aspect.fill_texture, ctx, &ctx->bi->clip, &ctx->bi->unclip, alpha, col_key, tr_state, 0)) + return 0; + } } /*draw bitmap for all dirty rects*/ else { @@ -458,11 +709,22 @@ Bool compositor_2d_draw_bitmap(GF_VisualManager *visual, GF_TraverseState *tr_st clip = ctx->bi->clip; gf_irect_intersect(&clip, &tr_state->visual->to_redraw.list[i]); if (clip.width && clip.height) { - if (!compositor_2d_draw_bitmap_ex(visual, ctx->aspect.fill_texture, ctx, &clip, &ctx->bi->unclip, alpha, col_key, tr_state, 0)) + if (visual->compositor->video_out->BlitTexture) { + if (!visual->compositor->video_out->BlitTexture(visual->compositor->video_out, ctx->aspect.fill_texture, &ctx->transform, &ctx->bi->clip, alpha, col_key +#ifdef GF_SR_USE_DEPTH + , ctx->depth_offset, ctx->depth_gain +#else + , 0, 0 +#endif + )) + return 0; + } else if (!compositor_2d_draw_bitmap_ex(visual, ctx->aspect.fill_texture, ctx, &clip, &ctx->bi->unclip, alpha, col_key, tr_state, 0)) { return 0; + } } } } + ctx->aspect.fill_texture->flags |= GF_SR_TEXTURE_USED; return 1; } @@ -488,8 +750,13 @@ GF_Err compositor_2d_set_aspect_ratio(GF_Compositor *compositor) compositor->vp_width = compositor->visual->width = compositor->output_width; compositor->vp_height = compositor->visual->height = compositor->output_height; } else { - compositor->vp_width = compositor->display_width; - compositor->vp_height = compositor->display_height; + if (compositor->rotate_mode % 2) { + compositor->vp_height = compositor->display_width; + compositor->vp_width = compositor->display_height; + } else { + compositor->vp_width = compositor->display_width; + compositor->vp_height = compositor->display_height; + } switch (compositor->aspect_ratio) { case GF_ASPECT_RATIO_FILL_SCREEN: @@ -560,8 +827,15 @@ GF_Err compositor_2d_set_aspect_ratio(GF_Compositor *compositor) evt.setup.width = compositor->vp_width; evt.setup.height = compositor->vp_height; evt.setup.opengl_mode = 0; - evt.setup.system_memory = compositor->video_memory ? 0 : 1; + evt.setup.system_memory = (compositor->video_memory==1) ? 0 : 1; +#ifdef OPENGL_RASTER + if (compositor->opengl_raster) { + evt.setup.opengl_mode = 1; + evt.setup.system_memory = 0; + evt.setup.back_buffer = 1; + } +#endif e = compositor->video_out->ProcessEvent(compositor->video_out, &evt); if (e) return e; @@ -577,40 +851,50 @@ GF_Err compositor_2d_set_aspect_ratio(GF_Compositor *compositor) return GF_OK; } -void compositor_send_resize_event(GF_Compositor *compositor, Fixed old_z, Fixed old_tx, Fixed old_ty, Bool is_resize) +void compositor_send_resize_event(GF_Compositor *compositor, GF_SceneGraph *subscene, Fixed old_z, Fixed old_tx, Fixed old_ty, Bool is_resize) { #ifndef GPAC_DISABLE_SVG - GF_Node *root; - root = gf_sg_get_root_node(compositor->scene); - /*if root node is DOM, sent a resize event*/ - if (root /* && (gf_node_get_tag(root) >= GF_NODE_FIRST_DOM_NODE_TAG) */) { - GF_DOM_Event evt; - memset(&evt, 0, sizeof(GF_DOM_Event)); - evt.prev_scale = compositor->scale_x*old_z; - evt.new_scale = compositor->scale_x*compositor->zoom; - evt.bubbles = 1; - - if (is_resize) { - evt.type = GF_EVENT_RESIZE; + GF_DOM_Event evt; + GF_SceneGraph *scene = (subscene ? subscene : compositor->scene); + GF_Node *root = gf_sg_get_root_node(scene); + /*if root node is not DOM, sent a resize event (for VRML/BIFS). Otherwise this must be handled + by the composition code of the node*/ + if (!root || (gf_node_get_tag(root) > GF_NODE_RANGE_LAST_VRML) ) + return; + + memset(&evt, 0, sizeof(GF_DOM_Event)); + evt.prev_scale = compositor->scale_x*old_z; + evt.new_scale = compositor->scale_x*compositor->zoom; + evt.bubbles = 1; + + if (is_resize) { + evt.type = GF_EVENT_RESIZE; + if (subscene == NULL) { evt.screen_rect.width = INT2FIX(compositor->display_width); evt.screen_rect.height = INT2FIX(compositor->display_height); - } else if (evt.prev_scale == evt.new_scale) { - /*cannot get params for scroll events*/ - evt.type = GF_EVENT_SCROLL; } else { - evt.screen_rect.x = INT2FIX(compositor->vp_x); - evt.screen_rect.y = INT2FIX(compositor->vp_y); - evt.screen_rect.width = INT2FIX(compositor->output_width); - evt.screen_rect.height = INT2FIX(compositor->output_height); - evt.prev_translate.x = old_tx; - evt.prev_translate.y = old_ty; - evt.new_translate.x = compositor->trans_x; - evt.new_translate.y = compositor->trans_y; - evt.type = GF_EVENT_ZOOM; - evt.bubbles = 0; - } - gf_dom_event_fire(gf_sg_get_root_node(compositor->scene), &evt); + u32 w, h; + gf_sg_get_scene_size_info(scene, &w, &h); + evt.screen_rect.width = INT2FIX(w); + evt.screen_rect.height = INT2FIX(h); + } + } else if (evt.prev_scale == evt.new_scale) { + /*cannot get params for scroll events*/ + evt.type = GF_EVENT_SCROLL; + } else { + evt.screen_rect.x = INT2FIX(compositor->vp_x); + evt.screen_rect.y = INT2FIX(compositor->vp_y); + evt.screen_rect.width = INT2FIX(compositor->output_width); + evt.screen_rect.height = INT2FIX(compositor->output_height); + evt.prev_translate.x = old_tx; + evt.prev_translate.y = old_ty; + evt.new_translate.x = compositor->trans_x; + evt.new_translate.y = compositor->trans_y; + evt.type = GF_EVENT_ZOOM; + evt.bubbles = 0; } + gf_dom_event_fire(gf_sg_get_root_node(scene), &evt); + #endif } void compositor_2d_set_user_transform(GF_Compositor *compositor, Fixed zoom, Fixed tx, Fixed ty, Bool is_resize) @@ -646,6 +930,19 @@ void compositor_2d_set_user_transform(GF_Compositor *compositor, Fixed zoom, Fix } } gf_mx2d_init(compositor->traverse_state->transform); + + switch (compositor->rotate_mode) { + case 1: + gf_mx2d_add_rotation(&compositor->traverse_state->transform, 0, 0, -GF_PI/2); + break; + case 2: + gf_mx2d_add_scale(&compositor->traverse_state->transform, -1, -1); + break; + case 3: + gf_mx2d_add_rotation(&compositor->traverse_state->transform, 0, 0, GF_PI/2); + break; + } + gf_mx2d_add_scale(&compositor->traverse_state->transform, gf_mulfix(compositor->zoom,compositor->scale_x), gf_mulfix(compositor->zoom,compositor->scale_y)); gf_mx2d_add_translation(&compositor->traverse_state->transform, compositor->trans_x, compositor->trans_y); @@ -658,12 +955,12 @@ void compositor_2d_set_user_transform(GF_Compositor *compositor, Fixed zoom, Fix GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor2D] Changing Zoom (%g) and Pan (%g %g)\n", FIX2FLT(compositor->zoom), FIX2FLT(compositor->trans_x) , FIX2FLT(compositor->trans_y))); - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); compositor->traverse_state->invalidate_all = 1; /*for zoom&pan, send the event right away. For resize/scroll, wait for the frame to be drawn before sending it otherwise viewport info of SVG nodes won't be correct*/ - if (!is_resize) compositor_send_resize_event(compositor, old_z, old_tx, old_ty, 0); + if (!is_resize) compositor_send_resize_event(compositor, NULL, old_z, old_tx, old_ty, 0); gf_sc_lock(compositor, 0); } @@ -844,7 +1141,8 @@ void visual_2d_draw_overlays(GF_VisualManager *visual) txh = ol->ctx->aspect.fill_texture; video_src.height = txh->height; video_src.width = txh->width; - video_src.pitch = txh->stride; + video_src.pitch_x = 0; + video_src.pitch_y = txh->stride; video_src.pixel_format = txh->pixelformat; video_src.video_buffer = txh->data; @@ -852,7 +1150,18 @@ void visual_2d_draw_overlays(GF_VisualManager *visual) if (e) GF_LOG(GF_LOG_ERROR, GF_LOG_COMPOSE, ("[Visual2D] Error %s during overlay update\n", gf_error_to_string(e) )); ra_del(&ol->ra); - free(ol); + gf_free(ol); } } + +void compositor_2d_init_callbacks(GF_Compositor *compositor) +{ + compositor->visual->DrawBitmap = compositor_2d_draw_bitmap; + if (compositor->video_out->hw_caps & GF_VIDEO_HW_HAS_LINE_BLIT) { + compositor->raster_callbacks.cbk = compositor->video_out; + compositor->raster_callbacks.fill_run_alpha = (raster_cbk_fill_run_alpha) compositor->video_out->DrawHLineAlpha; + compositor->raster_callbacks.fill_run_no_alpha = (raster_cbk_fill_run_no_alpha) compositor->video_out->DrawHLine; + compositor->raster_callbacks.fill_rect = (raster_cbk_fill_rect) compositor->video_out->DrawRectangle; + } +} diff --git a/src/compositor/compositor_3d.c b/src/compositor/compositor_3d.c index 7fe828a..2afaa89 100644 --- a/src/compositor/compositor_3d.c +++ b/src/compositor/compositor_3d.c @@ -32,8 +32,7 @@ #ifndef GPAC_DISABLE_3D #ifdef GPAC_USE_TINYGL -#include "../../TinyGL/include/GL/oscontext.h" -//#include <GL/oscontext.h> +#include <GL/oscontext.h> #endif GF_Err compositor_3d_set_aspect_ratio(GF_Compositor *compositor) @@ -111,35 +110,42 @@ GF_Err compositor_3d_set_aspect_ratio(GF_Compositor *compositor) #else evt.setup.opengl_mode = 1; #endif - compositor->video_out->ProcessEvent(compositor->video_out, &evt); -#ifdef GPAC_USE_TINYGL + if (compositor->video_out->ProcessEvent(compositor->video_out, &evt)<0) { + compositor->reset_graphics=1; + return GF_OK; + } + +#if defined(GPAC_USE_TINYGL) { u32 bpp; GF_VideoSurface bb; GF_Err e = compositor->video_out->LockBackBuffer(compositor->video_out, &bb, 1); - if (e) return e; - switch (bb.pixel_format) { - case GF_PIXEL_RGB_32: - case GF_PIXEL_ARGB: - bpp = 32; - break; - case GF_PIXEL_RGB_24: - case GF_PIXEL_BGR_24: - bpp = 24; - break; - case GF_PIXEL_RGB_565: - case GF_PIXEL_RGB_555: - bpp = 16; - break; - default: - e = GF_NOT_SUPPORTED; - bpp = 0; - break; + if (e==GF_OK) { + switch (bb.pixel_format) { + case GF_PIXEL_RGB_32: + case GF_PIXEL_ARGB: + bpp = 32; + break; + case GF_PIXEL_RGB_24: + case GF_PIXEL_BGR_24: + bpp = 24; + break; + case GF_PIXEL_RGB_565: + case GF_PIXEL_RGB_555: + bpp = 16; + break; + default: + e = GF_NOT_SUPPORTED; + bpp = 0; + break; + } + if (e==GF_OK) { + compositor->tgl_ctx = ostgl_create_context(bb.width, bb.height, bpp, &bb.video_buffer, 1); + if (compositor->tgl_ctx) ostgl_make_current(compositor->tgl_ctx, 0); + } + compositor->video_out->LockBackBuffer(compositor->video_out, &bb, 0); } - compositor->tgl_ctx = ostgl_create_context(bb.width, bb.height, bpp, &bb.video_buffer, 1); - if (compositor->tgl_ctx) ostgl_make_current(compositor->tgl_ctx, 0); - compositor->video_out->LockBackBuffer(compositor->video_out, &bb, 0); } #endif @@ -150,11 +156,14 @@ GF_Err compositor_3d_set_aspect_ratio(GF_Compositor *compositor) GF_Camera *compositor_3d_get_camera(GF_Compositor *compositor) { +#ifndef GPAC_DISABLE_VRML if (compositor->active_layer) { return compositor_layer3d_get_camera(compositor->active_layer); - } else { - return &compositor->visual->camera; } +#endif + if (compositor->visual->type_3d) + return &compositor->visual->camera; + return NULL; } void compositor_3d_reset_camera(GF_Compositor *compositor) @@ -162,6 +171,7 @@ void compositor_3d_reset_camera(GF_Compositor *compositor) GF_Camera *cam = compositor_3d_get_camera(compositor); camera_reset_viewpoint(cam, 1); gf_sc_invalidate(compositor, NULL); + if (compositor->active_layer) gf_node_dirty_set(compositor->active_layer, 0, 1); } void compositor_3d_draw_bitmap(Drawable *stack, DrawAspect2D *asp, GF_TraverseState *tr_state, Fixed width, Fixed height, Fixed bmp_scale_x, Fixed bmp_scale_y) @@ -182,12 +192,19 @@ void compositor_3d_draw_bitmap(Drawable *stack, DrawAspect2D *asp, GF_TraverseSt if (!txh || !txh->tx_io || !txh->width || !txh->height) return; alpha = GF_COL_A(asp->fill_color); + /*THIS IS A HACK, will not work when setting filled=0, transparency and XLineProps*/ + if (!alpha) alpha = GF_COL_A(asp->line_color); + /*texture is available in hw, use it - if blending, force using texture*/ - if (!gf_sc_texture_needs_reload(txh) || (alpha != 0xFF) || !compositor->bitmap_use_pixels) { + if (!gf_sc_texture_needs_reload(txh) || (alpha != 0xFF) || !compositor->bitmap_use_pixels +#ifdef GF_SR_USE_DEPTH + || tr_state->depth_offset +#endif + ) { visual_3d_set_state(tr_state->visual, V3D_STATE_LIGHT, 0); visual_3d_enable_antialias(tr_state->visual, 0); if (alpha && (alpha != 0xFF)) { - visual_3d_set_material_2d_argb(tr_state->visual, asp->fill_color); + visual_3d_set_material_2d_argb(tr_state->visual, GF_COL_ARGB(alpha, 0xFF, 0xFF, 0xFF)); gf_sc_texture_set_blend_mode(txh, TX_MODULATE); } else if (gf_sc_texture_is_transparent(txh)) { gf_sc_texture_set_blend_mode(txh, TX_REPLACE); @@ -205,11 +222,35 @@ void compositor_3d_draw_bitmap(Drawable *stack, DrawAspect2D *asp, GF_TraverseSt size.y = height; stack->mesh = new_mesh(); - mesh_new_rectangle(stack->mesh, size); + mesh_new_rectangle(stack->mesh, size, NULL, 0); } } if (stack->mesh) { - visual_3d_mesh_paint(tr_state, stack->mesh); +#ifdef GF_SR_USE_DEPTH + if (tr_state->depth_offset) { + GF_Matrix mx; + Fixed offset; + Fixed disp_depth = (compositor->display_depth<0) ? INT2FIX(tr_state->visual->height) : INT2FIX(compositor->display_depth); + if (disp_depth) { + if (!tr_state->pixel_metrics) disp_depth = gf_divfix(disp_depth, tr_state->min_hsize); + gf_mx_init(mx); + /*add recalibration by the scene*/ + offset = tr_state->depth_offset; + if (tr_state->visual->depth_vp_range) { + offset = gf_divfix(offset, tr_state->visual->depth_vp_range/2); + } + gf_mx_add_translation(&mx, 0, 0, gf_mulfix(offset, disp_depth/2) ); + + visual_3d_matrix_push(tr_state->visual); + visual_3d_matrix_add(tr_state->visual, mx.m); + visual_3d_mesh_paint(tr_state, stack->mesh); + visual_3d_matrix_pop(tr_state->visual); + } else { + visual_3d_mesh_paint(tr_state, stack->mesh); + } + } else +#endif + visual_3d_mesh_paint(tr_state, stack->mesh); } gf_sc_texture_disable(txh); tr_state->mesh_num_textures = 0; @@ -230,7 +271,9 @@ void compositor_3d_draw_bitmap(Drawable *stack, DrawAspect2D *asp, GF_TraverseSt sx = bmp_scale_x; if (sx<0) sx = FIX_ONE; sy = bmp_scale_y; if (sy<0) sy = FIX_ONE; +#ifndef GPAC_DISABLE_VRML compositor_adjust_scale(txh->owner, &sx, &sy); +#endif /*add top level scale if any*/ sx = gf_mulfix(sx, compositor->scale_x); diff --git a/src/compositor/compositor_node_init.c b/src/compositor/compositor_node_init.c index f9a3f69..c541197 100644 --- a/src/compositor/compositor_node_init.c +++ b/src/compositor/compositor_node_init.c @@ -30,14 +30,37 @@ void gf_sc_on_node_init(GF_Compositor *compositor, GF_Node *node) { switch (gf_node_get_tag(node)) { +#ifndef GPAC_DISABLE_VRML case TAG_MPEG4_AnimationStream: compositor_init_animationstream(compositor, node); break; case TAG_MPEG4_AudioBuffer: compositor_init_audiobuffer(compositor, node); break; case TAG_MPEG4_AudioSource: compositor_init_audiosource(compositor, node); break; - case TAG_MPEG4_AudioClip: case TAG_X3D_AudioClip: compositor_init_audioclip(compositor, node); break; - case TAG_MPEG4_TimeSensor: case TAG_X3D_TimeSensor: compositor_init_timesensor(compositor, node); break; - case TAG_MPEG4_ImageTexture: case TAG_X3D_ImageTexture: compositor_init_imagetexture(compositor, node); break; - case TAG_MPEG4_PixelTexture: case TAG_X3D_PixelTexture: compositor_init_pixeltexture(compositor, node); break; - case TAG_MPEG4_MovieTexture: case TAG_X3D_MovieTexture: compositor_init_movietexture(compositor, node); break; + case TAG_MPEG4_AudioClip: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_AudioClip: +#endif + compositor_init_audioclip(compositor, node); break; + case TAG_MPEG4_TimeSensor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_TimeSensor: +#endif + compositor_init_timesensor(compositor, node); break; + case TAG_MPEG4_ImageTexture: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_ImageTexture: +#endif + case TAG_MPEG4_CacheTexture: + compositor_init_imagetexture(compositor, node); break; + + case TAG_MPEG4_PixelTexture: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_PixelTexture: +#endif + compositor_init_pixeltexture(compositor, node); break; + case TAG_MPEG4_MovieTexture: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_MovieTexture: +#endif + compositor_init_movietexture(compositor, node); break; case TAG_MPEG4_Background2D: compositor_init_background2d(compositor, node); break; case TAG_MPEG4_Bitmap: compositor_init_bitmap(compositor, node); break; @@ -72,61 +95,224 @@ void gf_sc_on_node_init(GF_Compositor *compositor, GF_Node *node) /*sensors*/ - case TAG_MPEG4_Anchor: case TAG_X3D_Anchor: compositor_init_anchor(compositor, node); break; + case TAG_MPEG4_Anchor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Anchor: +#endif + compositor_init_anchor(compositor, node); break; case TAG_MPEG4_DiscSensor: compositor_init_disc_sensor(compositor, node); break; case TAG_MPEG4_PlaneSensor2D: compositor_init_plane_sensor2d(compositor, node); break; case TAG_MPEG4_ProximitySensor2D: compositor_init_proximity_sensor2d(compositor, node); break; - case TAG_MPEG4_TouchSensor: case TAG_X3D_TouchSensor: compositor_init_touch_sensor(compositor, node); break; + case TAG_MPEG4_TouchSensor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_TouchSensor: +#endif + compositor_init_touch_sensor(compositor, node); break; - case TAG_MPEG4_Group: case TAG_X3D_Group: compositor_init_group(compositor, node); break; - case TAG_MPEG4_Rectangle: case TAG_X3D_Rectangle2D: compositor_init_rectangle(compositor, node); break; - case TAG_MPEG4_Shape: case TAG_X3D_Shape: compositor_init_shape(compositor, node); break; - case TAG_MPEG4_Switch: case TAG_X3D_Switch: compositor_init_switch(compositor, node); break; + case TAG_MPEG4_Group: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Group: +#endif + compositor_init_group(compositor, node); break; + case TAG_MPEG4_Rectangle: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Rectangle2D: +#endif + compositor_init_rectangle(compositor, node); break; + case TAG_MPEG4_Shape: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Shape: +#endif + compositor_init_shape(compositor, node); break; + case TAG_MPEG4_Switch: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Switch: +#endif + compositor_init_switch(compositor, node); break; - case TAG_MPEG4_Text: case TAG_X3D_Text: compositor_init_text(compositor, node); break; + case TAG_MPEG4_Text: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Text: +#endif + compositor_init_text(compositor, node); break; #ifndef GPAC_DISABLE_3D - case TAG_MPEG4_Background: case TAG_X3D_Background: compositor_init_background(compositor, node); break; - - case TAG_MPEG4_CylinderSensor: case TAG_X3D_CylinderSensor: compositor_init_cylinder_sensor(compositor, node); break; - case TAG_MPEG4_PlaneSensor: case TAG_X3D_PlaneSensor: compositor_init_plane_sensor(compositor, node); break; - case TAG_MPEG4_ProximitySensor: case TAG_X3D_ProximitySensor: compositor_init_proximity_sensor(compositor, node); break; - case TAG_MPEG4_SphereSensor: case TAG_X3D_SphereSensor: compositor_init_sphere_sensor(compositor, node); break; - case TAG_MPEG4_VisibilitySensor: case TAG_X3D_VisibilitySensor: compositor_init_visibility_sensor(compositor, node); break; - - case TAG_MPEG4_Box: case TAG_X3D_Box: compositor_init_box(compositor, node); break; - case TAG_MPEG4_Cone: case TAG_X3D_Cone: compositor_init_cone(compositor, node); break; - case TAG_MPEG4_Cylinder: case TAG_X3D_Cylinder: compositor_init_cylinder(compositor, node); break; - case TAG_MPEG4_ElevationGrid: case TAG_X3D_ElevationGrid: compositor_init_elevation_grid(compositor, node); break; - case TAG_MPEG4_Extrusion: case TAG_X3D_Extrusion: compositor_init_extrusion(compositor, node); break; - case TAG_MPEG4_IndexedFaceSet: case TAG_X3D_IndexedFaceSet: compositor_init_ifs(compositor, node); break; - case TAG_MPEG4_IndexedLineSet: case TAG_X3D_IndexedLineSet: compositor_init_ils(compositor, node); break; - case TAG_MPEG4_PointSet: case TAG_X3D_PointSet: compositor_init_point_set(compositor, node); break; - case TAG_MPEG4_Sphere: case TAG_X3D_Sphere: compositor_init_sphere(compositor, node); break; - - case TAG_MPEG4_Billboard: case TAG_X3D_Billboard: compositor_init_billboard(compositor, node); break; - case TAG_MPEG4_Collision: case TAG_X3D_Collision: compositor_init_collision(compositor, node); break; - case TAG_MPEG4_LOD: case TAG_X3D_LOD: compositor_init_lod(compositor, node); break; - case TAG_MPEG4_Transform: case TAG_X3D_Transform: compositor_init_transform(compositor, node); break; - - case TAG_MPEG4_Sound: case TAG_X3D_Sound: compositor_init_sound(compositor, node); break; - - case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: compositor_init_viewpoint(compositor, node); break; - case TAG_MPEG4_NavigationInfo: case TAG_X3D_NavigationInfo: compositor_init_navigation_info(compositor, node); break; - case TAG_MPEG4_Fog: case TAG_X3D_Fog: compositor_init_fog(compositor, node); break; + case TAG_MPEG4_Background: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Background: +#endif + compositor_init_background(compositor, node); + break; + case TAG_MPEG4_CylinderSensor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_CylinderSensor: +#endif + compositor_init_cylinder_sensor(compositor, node); + break; + case TAG_MPEG4_PlaneSensor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_PlaneSensor: +#endif + compositor_init_plane_sensor(compositor, node); + break; + case TAG_MPEG4_ProximitySensor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_ProximitySensor: +#endif + compositor_init_proximity_sensor(compositor, node); + break; + case TAG_MPEG4_SphereSensor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_SphereSensor: +#endif + compositor_init_sphere_sensor(compositor, node); + break; + case TAG_MPEG4_VisibilitySensor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_VisibilitySensor: +#endif + compositor_init_visibility_sensor(compositor, node); + break; + case TAG_MPEG4_Box: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Box: +#endif + compositor_init_box(compositor, node); + break; + case TAG_MPEG4_Cone: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Cone: +#endif + compositor_init_cone(compositor, node); + break; + case TAG_MPEG4_Cylinder: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Cylinder: +#endif + compositor_init_cylinder(compositor, node); + break; + case TAG_MPEG4_ElevationGrid: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_ElevationGrid: +#endif + compositor_init_elevation_grid(compositor, node); + break; + case TAG_MPEG4_Extrusion: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Extrusion: +#endif + compositor_init_extrusion(compositor, node); + break; + case TAG_MPEG4_IndexedFaceSet: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_IndexedFaceSet: +#endif + compositor_init_ifs(compositor, node); + break; + case TAG_MPEG4_IndexedLineSet: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_IndexedLineSet: +#endif + compositor_init_ils(compositor, node); + break; + case TAG_MPEG4_PointSet: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_PointSet: +#endif + compositor_init_point_set(compositor, node); + break; + case TAG_MPEG4_Sphere: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Sphere: +#endif + compositor_init_sphere(compositor, node); + break; + case TAG_MPEG4_Billboard: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Billboard: +#endif + compositor_init_billboard(compositor, node); + break; + case TAG_MPEG4_Collision: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Collision: +#endif + compositor_init_collision(compositor, node); + break; + case TAG_MPEG4_LOD: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_LOD: +#endif + compositor_init_lod(compositor, node); + break; + case TAG_MPEG4_Transform: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Transform: +#endif + compositor_init_transform(compositor, node); + break; + case TAG_MPEG4_Sound: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Sound: +#endif + compositor_init_sound(compositor, node); + break; + case TAG_MPEG4_Viewpoint: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Viewpoint: +#endif + compositor_init_viewpoint(compositor, node); + break; + case TAG_MPEG4_NavigationInfo: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_NavigationInfo: +#endif + compositor_init_navigation_info(compositor, node); + break; + case TAG_MPEG4_Fog: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Fog: +#endif + compositor_init_fog(compositor, node); + break; + case TAG_MPEG4_DirectionalLight: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_DirectionalLight: +#endif + compositor_init_directional_light(compositor, node); + break; + case TAG_MPEG4_PointLight: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_PointLight: +#endif + compositor_init_point_light(compositor, node); + break; + case TAG_MPEG4_SpotLight: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_SpotLight: +#endif + compositor_init_spot_light(compositor, node); + break; - case TAG_MPEG4_DirectionalLight: case TAG_X3D_DirectionalLight: compositor_init_directional_light(compositor, node); break; - case TAG_MPEG4_PointLight: case TAG_X3D_PointLight: compositor_init_point_light(compositor, node); break; - case TAG_MPEG4_SpotLight: case TAG_X3D_SpotLight: compositor_init_spot_light(compositor, node); break; + case TAG_MPEG4_NonLinearDeformer: + compositor_init_non_linear_deformer(compositor, node); + break; - case TAG_MPEG4_NonLinearDeformer: compositor_init_non_linear_deformer(compositor, node); break; + case TAG_MPEG4_Layer3D: + compositor_init_layer3d(compositor, node); + break; + case TAG_MPEG4_CompositeTexture3D: + compositor_init_compositetexture3d(compositor, node); + break; - case TAG_MPEG4_Layer3D: compositor_init_layer3d(compositor, node); break; - case TAG_MPEG4_CompositeTexture3D: compositor_init_compositetexture3d(compositor, node); break; + case TAG_MPEG4_EnvironmentTest: + compositor_init_envtest(compositor, node); + break; #endif /*X3D nodes*/ +#ifndef GPAC_DISABLE_X3D case TAG_X3D_StaticGroup: compositor_init_static_group(compositor, node); break; case TAG_X3D_Disk2D: compositor_init_disk2d(compositor, node); break; case TAG_X3D_Arc2D: case TAG_X3D_ArcClose2D: compositor_init_arc2d(compositor, node); break; @@ -144,6 +330,11 @@ void gf_sc_on_node_init(GF_Compositor *compositor, GF_Node *node) case TAG_X3D_IndexedTriangleSet: compositor_init_indexed_triangle_set(compositor, node); break; #endif +#endif /*GPAC_DISABLE_X3D*/ + + case TAG_ProtoNode: compositor_init_hardcoded_proto(compositor, node); break; + +#endif /*GPAC_DISABLE_VRML*/ #ifndef GPAC_DISABLE_SVG /* SVG Part */ @@ -185,12 +376,12 @@ void gf_sc_on_node_init(GF_Compositor *compositor, GF_Node *node) case TAG_SVG_use: compositor_init_svg_use(compositor, node); break; case TAG_SVG_animation: compositor_init_svg_animation(compositor, node); break; case TAG_SVG_foreignObject: compositor_init_svg_foreign_object(compositor, node); break; -#endif - case TAG_ProtoNode: compositor_init_hardcoded_proto(compositor, node); break; + case TAG_SVG_filter: compositor_init_svg_filter(compositor, node); break; +#endif default: - GF_LOG(GF_LOG_WARNING, GF_LOG_COMPOSE, ("[Compositor] node %s will not be rendered\n", gf_node_get_class_name(node))); + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor] node %s will not be rendered\n", gf_node_get_class_name(node))); break; } } @@ -200,29 +391,55 @@ void gf_sc_invalidate(GF_Compositor *compositor, GF_Node *byObj) { if (!byObj) { - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); return; } switch (gf_node_get_tag(byObj)) { +#ifndef GPAC_DISABLE_VRML case TAG_MPEG4_AnimationStream: compositor_animationstream_modified(byObj); break; case TAG_MPEG4_AudioBuffer: compositor_audiobuffer_modified(byObj); break; case TAG_MPEG4_AudioSource: compositor_audiosource_modified(byObj); break; - case TAG_MPEG4_AudioClip: case TAG_X3D_AudioClip: compositor_audioclip_modified(byObj); break; - case TAG_MPEG4_TimeSensor: case TAG_X3D_TimeSensor: compositor_timesensor_modified(byObj); break; - case TAG_MPEG4_ImageTexture: case TAG_X3D_ImageTexture: compositor_imagetexture_modified(byObj); break; - case TAG_MPEG4_MovieTexture: case TAG_X3D_MovieTexture: compositor_movietexture_modified(byObj); break; + case TAG_MPEG4_AudioClip: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_AudioClip: +#endif + compositor_audioclip_modified(byObj); break; + case TAG_MPEG4_TimeSensor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_TimeSensor: +#endif + compositor_timesensor_modified(byObj); break; + case TAG_MPEG4_ImageTexture: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_ImageTexture: +#endif + case TAG_MPEG4_CacheTexture: + compositor_imagetexture_modified(byObj); break; + + case TAG_MPEG4_MovieTexture: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_MovieTexture: +#endif + compositor_movietexture_modified(byObj); break; case TAG_MPEG4_Background2D: compositor_background2d_modified(byObj); break; #ifndef GPAC_DISABLE_3D - case TAG_MPEG4_Background: case TAG_X3D_Background: compositor_background_modified(byObj); break; + case TAG_MPEG4_Background: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Background: +#endif + compositor_background_modified(byObj); break; #endif case TAG_MPEG4_Layout: compositor_layout_modified(compositor, byObj); break; + case TAG_MPEG4_EnvironmentTest: compositor_envtest_modified(byObj); break; + +#endif /*GPAC_DISABLE_VRML*/ default: /*for all nodes, invalidate parent graph - note we do that for sensors as well to force recomputing sensor list cached at grouping node level*/ gf_node_dirty_set(byObj, 0, 1); - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); break; } } diff --git a/src/compositor/drawable.c b/src/compositor/drawable.c index 4d60815..177e24d 100644 --- a/src/compositor/drawable.c +++ b/src/compositor/drawable.c @@ -36,7 +36,8 @@ void drawable_draw(Drawable *drawable, GF_TraverseState *tr_state) } /*default point_over routine*/ -void drawable_pick(Drawable *drawable, GF_TraverseState *tr_state) +#ifndef GPAC_DISABLE_VRML +void vrml_drawable_pick(Drawable *drawable, GF_TraverseState *tr_state) { DrawAspect2D asp; GF_Matrix2D inv_2d; @@ -47,7 +48,7 @@ void drawable_pick(Drawable *drawable, GF_TraverseState *tr_state) #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { - visual_3d_drawable_pick(drawable->node, tr_state, NULL, drawable->path); + visual_3d_vrml_drawable_pick(drawable->node, tr_state, NULL, drawable); return; } #endif @@ -93,11 +94,15 @@ picked: compositor->hit_texcoords.x = gf_divfix(x - drawable->path->bbox.x, drawable->path->bbox.width); compositor->hit_texcoords.y = FIX_ONE - gf_divfix(drawable->path->bbox.y - y, drawable->path->bbox.height); +#ifndef GPAC_DISABLE_VRML if (compositor_is_composite_texture(tr_state->appear)) { compositor->hit_appear = tr_state->appear; - } else { + } else +#endif + { compositor->hit_appear = NULL; } + compositor->hit_text = NULL; gf_list_reset(tr_state->visual->compositor->sensors); count = gf_list_count(tr_state->vrml_sensors); @@ -105,6 +110,7 @@ picked: gf_list_add(tr_state->visual->compositor->sensors, gf_list_get(tr_state->vrml_sensors, i)); } } +#endif /*GPAC_DISABLE_VRML*/ Drawable *drawable_new() { @@ -134,7 +140,7 @@ void drawable_reset_bounds(Drawable *dr, GF_VisualManager *visual) while (bi) { _cur = bi; bi = bi->next; - free(_cur); + gf_free(_cur); } dri->previous_bounds = NULL; return; @@ -156,23 +162,27 @@ void drawable_del_ex(Drawable *dr, GF_Compositor *compositor) bi = dri->current_bounds; while (bi) { _cur = bi; - if (is_reg) ra_add(&dri->visual->to_redraw, &bi->clip); + if (is_reg && bi->clip.width) { + ra_add(&dri->visual->to_redraw, &bi->clip); + } bi = bi->next; - free(_cur); + gf_free(_cur); } bi = dri->previous_bounds; while (bi) { _cur = bi; - if (is_reg) ra_add(&dri->visual->to_redraw, &bi->clip); + if (is_reg && bi->clip.width) { + ra_add(&dri->visual->to_redraw, &bi->clip); + } bi = bi->next; - free(_cur); + gf_free(_cur); } if (is_reg) visual_2d_drawable_delete(dri->visual, dr); cur = dri; dri = dri->next; - free(cur); + gf_free(cur); } - if (compositor) compositor->draw_next_frame = 1; + if (compositor) gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); /*remove path object*/ if (dr->path) gf_path_del(dr->path); @@ -189,7 +199,7 @@ void drawable_del_ex(Drawable *dr, GF_Compositor *compositor) delete_strikeinfo2d(si); si = next; } - free(dr); + gf_free(dr); } void drawable_del(Drawable *dr) @@ -307,7 +317,7 @@ Bool drawable_flush_bounds(Drawable *drawable, GF_VisualManager *on_visual, u32 while (dri->previous_bounds) { BoundInfo *bi = dri->previous_bounds; dri->previous_bounds = bi->next; - free(bi); + gf_free(bi); } } } @@ -403,12 +413,12 @@ DrawableContext *NewDrawableContext() void DeleteDrawableContext(DrawableContext *ctx) { drawctx_reset(ctx); - free(ctx); + gf_free(ctx); } void drawctx_reset(DrawableContext *ctx) { DrawableContext *next = ctx->next; - if (ctx->col_mat) free(ctx->col_mat); + if (ctx->col_mat) gf_free(ctx->col_mat); memset(ctx, 0, sizeof(DrawableContext)); ctx->next = next; @@ -450,13 +460,30 @@ void drawctx_update_info(DrawableContext *ctx, GF_VisualManager *visual) moved = !drawable_has_same_bounds(ctx, visual); } - if (need_redraw || moved) ctx->flags |= CTX_REDRAW_MASK; + if (need_redraw || moved) + ctx->flags |= CTX_REDRAW_MASK; } /*in all cases reset dirty flag of appearance and its sub-nodes*/ //if (ctx->flags & CTX_HAS_APPEARANCE) gf_node_dirty_reset(ctx->appear); } +#ifndef GPAC_DISABLE_VRML +static Bool drawable_lineprops_dirty(GF_Node *node) +{ + LinePropStack *st = (LinePropStack *)gf_node_get_private(node); + if (!st) return 0; + + if (st->compositor->current_frame == st->last_mod_time) return st->is_dirty; + if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { + gf_node_dirty_clear(node, 0); + st->is_dirty = 1; + } else { + st->is_dirty = 0; + } + st->last_mod_time = st->compositor->current_frame; + return st->is_dirty; +} u32 drawable_get_aspect_2d_mpeg4(GF_Node *node, DrawAspect2D *asp, GF_TraverseState *tr_state) { @@ -478,6 +505,7 @@ u32 drawable_get_aspect_2d_mpeg4(GF_Node *node, DrawAspect2D *asp, GF_TraverseSt asp->fill_texture = gf_sc_texture_get_handler( ((M_Appearance *) tr_state->appear)->texture ); } + m = (M_Material2D *) ((M_Appearance *)tr_state->appear)->material; if ( m == NULL) { asp->fill_color &= 0x00FFFFFF; @@ -487,8 +515,10 @@ u32 drawable_get_aspect_2d_mpeg4(GF_Node *node, DrawAspect2D *asp, GF_TraverseSt case TAG_MPEG4_Material2D: break; case TAG_MPEG4_Material: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Material: - { +#endif + { M_Material *mat = (M_Material *)m; asp->pen_props.width = 0; asp->fill_color = GF_COL_ARGB_FIXED(FIX_ONE, mat->diffuseColor.red, mat->diffuseColor.green, mat->diffuseColor.blue); @@ -545,7 +575,7 @@ check_default: asp->pen_props.width = 0; return 0; } - if (m->lineProps && gf_node_dirty_get(m->lineProps)) + if (m->lineProps && drawable_lineprops_dirty(m->lineProps)) ret = CTX_APP_DIRTY; if (LP) { @@ -581,6 +611,8 @@ check_default: asp->line_texture = gf_sc_texture_get_handler(XLP->texture); return ret; } +#endif /*GPAC_DISABLE_VRML*/ + static Bool check_transparent_skip(DrawableContext *ctx, Bool skipFill) { @@ -595,6 +627,7 @@ static Bool check_transparent_skip(DrawableContext *ctx, Bool skipFill) } +#ifndef GPAC_DISABLE_VRML DrawableContext *drawable_init_context_mpeg4(Drawable *drawable, GF_TraverseState *tr_state) { DrawableContext *ctx; @@ -614,7 +647,8 @@ DrawableContext *drawable_init_context_mpeg4(Drawable *drawable, GF_TraverseStat ctx->drawable = drawable; /*usually set by colorTransform or changes in OrderedGroup*/ - if (tr_state->invalidate_all) ctx->flags |= CTX_APP_DIRTY; + if (tr_state->invalidate_all) + ctx->flags |= CTX_APP_DIRTY; ctx->aspect.fill_texture = NULL; if (tr_state->appear) { @@ -634,9 +668,11 @@ DrawableContext *drawable_init_context_mpeg4(Drawable *drawable, GF_TraverseStat skipFill = 0; ctx->aspect.fill_texture = NULL; switch (gf_node_get_tag(ctx->drawable->node) ) { +#ifndef GPAC_DISABLE_VRML case TAG_MPEG4_IndexedLineSet2D: skipFill = 1; break; +#endif default: break; } @@ -645,6 +681,7 @@ DrawableContext *drawable_init_context_mpeg4(Drawable *drawable, GF_TraverseStat /*Update texture info - draw even if texture not created (this may happen if the media is removed)*/ if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->needs_refresh) ctx->flags |= CTX_TEXTURE_DIRTY; + else if (ctx->aspect.line_texture && ctx->aspect.line_texture->needs_refresh) ctx->flags |= CTX_TEXTURE_DIRTY; /*not clear in the spec: what happens when a transparent node is in form/layout ?? this may completely break layout of children. We consider the node should be drawn*/ @@ -659,16 +696,19 @@ DrawableContext *drawable_init_context_mpeg4(Drawable *drawable, GF_TraverseStat if (tr_state->fliped_coords) ctx->flags |= CTX_FLIPED_COORDS; -#ifdef GPAC_TRISCOPE_MODE - ctx->depth = tr_state->depth; +#ifdef GF_SR_USE_DEPTH + ctx->depth_gain=tr_state->depth_gain; + ctx->depth_offset=tr_state->depth_offset; #endif + return ctx; } +#endif static Bool drawable_finalize_end(struct _drawable_context *ctx, GF_TraverseState *tr_state) { /*if direct draw we can remove the context*/ - Bool res = tr_state->direct_draw; + Bool res = tr_state->immediate_draw ? 1 : 0; /*copy final transform, once all parent layout is done*/ gf_mx2d_copy(ctx->transform, tr_state->transform); @@ -755,6 +795,7 @@ void drawable_finalize_sort_ex(DrawableContext *ctx, GF_TraverseState *tr_state, Fixed pw; GF_Rect unclip, store_orig_bounds; + drawable_check_bounds(ctx, tr_state->visual); if (orig_bounds) { @@ -762,6 +803,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 ); ctx->bi->unclip = store_orig_bounds; gf_mx2d_apply_rect(&tr_state->transform, &ctx->bi->unclip); @@ -811,6 +853,7 @@ void drawable_finalize_sort_ex(DrawableContext *ctx, GF_TraverseState *tr_state, ctx->bi->clip.width = 0; } + can_remove = drawable_finalize_end(ctx, tr_state); if (ctx->drawable && !skip_focus) drawable_check_focus_highlight(ctx->drawable->node, tr_state, &store_orig_bounds); @@ -837,6 +880,9 @@ void drawable_check_focus_highlight(GF_Node *node, GF_TraverseState *tr_state, G GF_Compositor *compositor = tr_state->visual->compositor; if (compositor->focus_node!=node) return; + /*if key navigator, don't draw a focus highlight*/ + if (compositor->keynav_node) return; + if (compositor->focus_used) { u32 count = gf_list_count(tr_state->use_stack); if (!count || (gf_list_get(tr_state->use_stack, count-1)!=compositor->focus_used) ) @@ -892,7 +938,7 @@ void drawable_check_focus_highlight(GF_Node *node, GF_TraverseState *tr_state, G #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { gf_mx2d_copy(hl_ctx->transform, tr_state->transform); - visual_3d_draw_2d_with_aspect(hl_ctx->drawable, tr_state, &hl_ctx->aspect, 1); + visual_3d_draw_2d_with_aspect(hl_ctx->drawable, tr_state, &hl_ctx->aspect); return; } #endif @@ -916,33 +962,25 @@ void delete_strikeinfo2d(StrikeInfo2D *info) #ifndef GPAC_DISABLE_3D if (info->mesh_outline) mesh_free(info->mesh_outline); #endif - free(info); + gf_free(info); } -static u32 drawable_get_lineprops_last_update_time(GF_Node *node) -{ - LinePropStack *st = (LinePropStack *)gf_node_get_private(node); - if (!st) return 0; - if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { - st->last_mod_time ++; - gf_node_dirty_clear(node, 0); - } - return st->last_mod_time; -} StrikeInfo2D *drawable_get_strikeinfo(GF_Compositor *compositor, Drawable *drawable, DrawAspect2D *asp, GF_Node *appear, GF_Path *path, u32 svg_flags, GF_TraverseState *tr_state) { StrikeInfo2D *si, *prev; GF_Node *lp; - u32 now; + Bool dirty; if (!asp->pen_props.width) return NULL; if (path && !path->n_points) return NULL; lp = NULL; +#ifndef GPAC_DISABLE_VRML if (appear && (gf_node_get_tag(appear) < GF_NODE_RANGE_LAST_X3D) ) { lp = ((M_Appearance *)appear)->material; if (lp) lp = ((M_Material2D *) lp)->lineProps; } +#endif prev = NULL; si = drawable->outline; @@ -957,7 +995,7 @@ StrikeInfo2D *drawable_get_strikeinfo(GF_Compositor *compositor, Drawable *drawa #endif if (prev) prev->next = si->next; else drawable->outline = si->next; - free(si); + gf_free(si); si = prev ? prev->next : drawable->outline; continue; } @@ -991,12 +1029,16 @@ StrikeInfo2D *drawable_get_strikeinfo(GF_Compositor *compositor, Drawable *drawa if (!asp->line_scale) return si; /*node changed or outline not build*/ - now = lp ? drawable_get_lineprops_last_update_time(lp) : si->last_update_time; - if (!si->outline || (now!=si->last_update_time) || (si->line_scale != asp->line_scale) || (si->path_length != asp->pen_props.path_length) || (svg_flags & CTX_SVG_OUTLINE_GEOMETRY_DIRTY)) { +#ifndef GPAC_DISABLE_VRML + dirty = lp ? drawable_lineprops_dirty(lp) : 0; +#else + dirty = 0; +#endif + + if (!si->outline || dirty || (si->line_scale != asp->line_scale) || (si->path_length != asp->pen_props.path_length) || (svg_flags & CTX_SVG_OUTLINE_GEOMETRY_DIRTY)) { u32 i; Fixed w = asp->pen_props.width; Fixed dash_o = asp->pen_props.dash_offset; - si->last_update_time = now; si->line_scale = asp->line_scale; if (si->outline) gf_path_del(si->outline); #ifndef GPAC_DISABLE_3D @@ -1068,6 +1110,7 @@ void drawable_reset_path(Drawable *st) #endif } +#ifndef GPAC_DISABLE_VRML static void DestroyLineProps(GF_Node *n, void *rs, Bool is_destroy) { @@ -1103,19 +1146,22 @@ static void DestroyLineProps(GF_Node *n, void *rs, Bool is_destroy) } } - free(st); + gf_free(st); } void compositor_init_lineprops(GF_Compositor *compositor, GF_Node *node) { - LinePropStack *st = (LinePropStack *)malloc(sizeof(LinePropStack)); + LinePropStack *st = (LinePropStack *)gf_malloc(sizeof(LinePropStack)); st->compositor = compositor; - st->last_mod_time = 1; + st->last_mod_time = 0; gf_node_set_private(node, st); gf_node_set_callback_function(node, DestroyLineProps); } +#endif /*GPAC_DISABLE_VRML*/ + + #ifdef GPAC_DISABLE_SVG Bool drawable_get_aspect_2d_svg(GF_Node *node, DrawAspect2D *asp, GF_TraverseState *tr_state) @@ -1153,7 +1199,7 @@ Bool drawable_get_aspect_2d_svg(GF_Node *node, DrawAspect2D *asp, GF_TraverseSta iri->type = XMLRI_ELEMENTID; iri->target = n; gf_node_register_iri(sg, iri); - free(iri->string); + gf_free(iri->string); iri->string = NULL; } } @@ -1168,8 +1214,7 @@ Bool drawable_get_aspect_2d_svg(GF_Node *node, DrawAspect2D *asp, GF_TraverseSta gf_node_traverse(props->fill->iri.target, tr_state); - if (gf_node_dirty_get(props->fill->iri.target)) - ret = 1; + ret += compositor_svg_solid_color_dirty(tr_state->visual->compositor, props->fill->iri.target); if (all_atts.solid_color) { if (all_atts.solid_opacity) { @@ -1215,7 +1260,7 @@ Bool drawable_get_aspect_2d_svg(GF_Node *node, DrawAspect2D *asp, GF_TraverseSta iri->type = XMLRI_ELEMENTID; iri->target = n; gf_node_register_iri(sg, iri); - free(iri->string); + gf_free(iri->string); iri->string = NULL; } } @@ -1229,8 +1274,7 @@ Bool drawable_get_aspect_2d_svg(GF_Node *node, DrawAspect2D *asp, GF_TraverseSta gf_node_traverse(props->stroke->iri.target, tr_state); - if (gf_node_dirty_get(props->stroke->iri.target)) - ret = 1; + ret += compositor_svg_solid_color_dirty(tr_state->visual->compositor, props->stroke->iri.target); if (all_atts.solid_color) { if (all_atts.solid_opacity) { @@ -1282,7 +1326,7 @@ Bool drawable_get_aspect_2d_svg(GF_Node *node, DrawAspect2D *asp, GF_TraverseSta static Bool svg_appearance_flag_dirty(u32 flags) { -#if 0 +#if 1 /* fill-related */ if (flags & GF_SG_SVG_FILL_DIRTY) return 1; if (flags & GF_SG_SVG_FILLOPACITY_DIRTY) return 1; @@ -1330,14 +1374,18 @@ DrawableContext *drawable_init_context_svg(Drawable *drawable, GF_TraverseState ctx->drawable = drawable; - if (tr_state->invalidate_all || svg_appearance_flag_dirty(tr_state->svg_flags)) ctx->flags |= CTX_APP_DIRTY; + if (tr_state->invalidate_all || svg_appearance_flag_dirty(tr_state->svg_flags)) { + ctx->flags |= CTX_APP_DIRTY; + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("Node %s dirty - invalidating\n", gf_node_get_log_name(drawable->node) )); + } if (tr_state->svg_flags & (GF_SG_SVG_STROKEDASHARRAY_DIRTY | - GF_SG_SVG_STROKEDASHOFFSET_DIRTY | - GF_SG_SVG_STROKELINECAP_DIRTY | - GF_SG_SVG_STROKELINEJOIN_DIRTY | - GF_SG_SVG_STROKEMITERLIMIT_DIRTY | - GF_SG_SVG_STROKEWIDTH_DIRTY | - GF_SG_SVG_VECTOREFFECT_DIRTY )) ctx->flags |= CTX_SVG_OUTLINE_GEOMETRY_DIRTY; + GF_SG_SVG_STROKEDASHOFFSET_DIRTY | + GF_SG_SVG_STROKELINECAP_DIRTY | + GF_SG_SVG_STROKELINEJOIN_DIRTY | + GF_SG_SVG_STROKEMITERLIMIT_DIRTY | + GF_SG_SVG_STROKEWIDTH_DIRTY | + GF_SG_SVG_VECTOREFFECT_DIRTY )) + ctx->flags |= CTX_SVG_OUTLINE_GEOMETRY_DIRTY; ctx->aspect.fill_texture = NULL; @@ -1371,11 +1419,19 @@ DrawableContext *drawable_init_context_svg(Drawable *drawable, GF_TraverseState } /*Update texture info - draw even if texture not created (this may happen if the media is removed)*/ - if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->needs_refresh) ctx->flags |= CTX_TEXTURE_DIRTY; + if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->needs_refresh) + ctx->flags |= CTX_TEXTURE_DIRTY; /*we are drawing on a centered coord surface, remember to flip the texture*/ if (tr_state->fliped_coords) ctx->flags |= CTX_FLIPED_COORDS; + + +#ifdef GF_SR_USE_DEPTH + ctx->depth_gain=tr_state->depth_gain; + ctx->depth_offset=tr_state->depth_offset; +#endif + return ctx; } diff --git a/src/compositor/drawable.h b/src/compositor/drawable.h index 53b03e5..c24ed76 100644 --- a/src/compositor/drawable.h +++ b/src/compositor/drawable.h @@ -218,6 +218,8 @@ enum CTX_FLIPED_COORDS = 1<<10, }; +#define CTX_3DTYPE_MASK 0x7800 + #define CTX_REDRAW_MASK 0x00000003 struct _drawable_context @@ -249,9 +251,9 @@ struct _drawable_context */ GF_Node *appear; - /*depth z-axis info for 2d scenes in triscope mode*/ -#ifdef GPAC_TRISCOPE_MODE - Fixed depth; +#ifdef GF_SR_USE_DEPTH + //local gain and offset + Fixed depth_gain, depth_offset; #endif }; @@ -261,8 +263,11 @@ void DeleteDrawableContext(DrawableContext *); void drawctx_reset(DrawableContext *ctx); void drawctx_update_info(DrawableContext *ctx, GF_VisualManager *visual); +#ifndef GPAC_DISABLE_VRML /*inits context - may return NULL if the node doesn't have to be drawn*/ DrawableContext *drawable_init_context_mpeg4(Drawable *node, GF_TraverseState *tr_state); +#endif + /*inits context for SVG - may return NULL if the node doesn't have to be drawn*/ DrawableContext *drawable_init_context_svg(Drawable *drawable, GF_TraverseState *tr_state); @@ -271,8 +276,8 @@ DrawableContext *drawable_init_context_svg(Drawable *drawable, GF_TraverseState */ void drawable_draw(Drawable *drawable, GF_TraverseState *tr_state); -/*base picking function*/ -void drawable_pick(Drawable *drawable, GF_TraverseState *tr_state); +/*picking function for VRML-based scene graphs*/ +void vrml_drawable_pick(Drawable *drawable, GF_TraverseState *tr_state); /*SVG picking function (uses SVG pointrer events)*/ void svg_drawable_pick(GF_Node *node, Drawable *drawable, GF_TraverseState *tr_state); @@ -287,8 +292,6 @@ typedef struct _strikeinfo2d Drawable *drawable; /*lineprops used to build outline (MPEG-4 only)*/ GF_Node *lineProps; - /*last modif time of the lineprops node*/ - u32 last_update_time; /*user+world->local scaling for non-scalable outlines*/ Fixed line_scale; /*SVG path length*/ diff --git a/src/compositor/events.c b/src/compositor/events.c index 473df43..76822f4 100644 --- a/src/compositor/events.c +++ b/src/compositor/events.c @@ -49,11 +49,11 @@ static Bool exec_text_selection(GF_Compositor *compositor, GF_Event *event) if (compositor->edited_text) return 0; - if (compositor->text_selection) - return 1; + if (compositor->text_selection ) + return compositor->hit_text ? 1 : 0; switch (event->type) { case GF_EVENT_MOUSEMOVE: - if (compositor->text_selection) + if (compositor->text_selection && compositor->hit_text) return 1; break; case GF_EVENT_MOUSEDOWN: @@ -80,27 +80,33 @@ static void flush_text_node_edit(GF_Compositor *compositor, Bool final_flush) } if (*compositor->edited_text) { - free(*compositor->edited_text); + gf_free(*compositor->edited_text); *compositor->edited_text = NULL; } if (compositor->sel_buffer_len) { const u16 *lptr; - txt = malloc(sizeof(char)*2*compositor->sel_buffer_len); + txt = gf_malloc(sizeof(char)*2*compositor->sel_buffer_len); lptr = compositor->sel_buffer; len = gf_utf8_wcstombs(txt, 2*compositor->sel_buffer_len, &lptr); txt[len] = 0; - *compositor->edited_text = strdup(txt); - free(txt); + *compositor->edited_text = gf_strdup(txt); + gf_free(txt); } gf_node_dirty_set(compositor->focus_node, 0, (compositor->focus_text_type==2)); gf_node_set_private(compositor->focus_highlight->node, NULL); - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); if (final_flush) { - if (compositor->sel_buffer) free(compositor->sel_buffer); + GF_FieldInfo info; + if (compositor->sel_buffer) gf_free(compositor->sel_buffer); compositor->sel_buffer = NULL; compositor->sel_buffer_len = compositor->sel_buffer_alloc = 0; compositor->edited_text = NULL; + + memset(&info, 0, sizeof(GF_FieldInfo)); + info.fieldIndex = (u32) -1; + gf_node_changed(compositor->focus_node, &info); + } } @@ -116,17 +122,17 @@ GF_Err gf_sc_paste_text(GF_Compositor *compositor, const char *text) gf_sc_lock(compositor, 1); - conv_buf = malloc(sizeof(u16)*len); + conv_buf = gf_malloc(sizeof(u16)*len); len = gf_utf8_mbstowcs(conv_buf, len, &text); compositor->sel_buffer_alloc += len; if (compositor->sel_buffer_len == compositor->sel_buffer_alloc) compositor->sel_buffer_alloc++; - compositor->sel_buffer = realloc(compositor->sel_buffer, sizeof(u16)*compositor->sel_buffer_alloc); + compositor->sel_buffer = gf_realloc(compositor->sel_buffer, sizeof(u16)*compositor->sel_buffer_alloc); memmove(&compositor->sel_buffer[compositor->caret_pos+len], &compositor->sel_buffer[compositor->caret_pos], sizeof(u16)*(compositor->sel_buffer_len-compositor->caret_pos)); memcpy(&compositor->sel_buffer[compositor->caret_pos], conv_buf, sizeof(u16)*len); - free(conv_buf); + gf_free(conv_buf); compositor->sel_buffer_len += len; compositor->caret_pos += len; compositor->sel_buffer[compositor->sel_buffer_len]=0; @@ -174,6 +180,7 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) compositor->dom_text_pos = 0; +#ifndef GPAC_DISABLE_VRML if (compositor->focus_text_type==3) { MFString *mf = &((M_Text*)compositor->focus_node)->string; @@ -189,7 +196,10 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) return 0; } res = &mf->vals[compositor->dom_text_pos-1]; - } else { + } else +#endif /*GPAC_DISABLE_VRML*/ + + { #ifndef GPAC_DISABLE_SVG GF_ChildNodeItem *child = ((GF_ParentNode *) compositor->focus_node)->children; @@ -206,7 +216,7 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) else if (pos==compositor->dom_text_pos) { if (append) { u16 end; - u16 *srcp; + const u16 *srcp; u32 len; GF_DOMText *cur, *ntext; GF_ChildNodeItem *children = ((GF_ParentNode *) compositor->focus_node)->children; @@ -230,11 +240,11 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) cur = (GF_DOMText*) child->node; - free(cur->textContent); + gf_free(cur->textContent); end = compositor->sel_buffer[compositor->caret_pos]; compositor->sel_buffer[compositor->caret_pos] = 0; len = gf_utf8_wcslen(compositor->sel_buffer); - cur->textContent = malloc(sizeof(char)*(len+1)); + cur->textContent = gf_malloc(sizeof(char)*(len+1)); srcp = compositor->sel_buffer; len = gf_utf8_wcstombs(cur->textContent, len, &srcp); cur->textContent[len] = 0; @@ -242,12 +252,12 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) if (compositor->caret_pos+1<compositor->sel_buffer_len) { len = gf_utf8_wcslen(compositor->sel_buffer + compositor->caret_pos + 1); - ntext->textContent = malloc(sizeof(char)*(len+1)); + ntext->textContent = gf_malloc(sizeof(char)*(len+1)); srcp = compositor->sel_buffer + compositor->caret_pos + 1; len = gf_utf8_wcstombs(ntext->textContent, len, &srcp); ntext->textContent[len] = 0; } else { - ntext->textContent = strdup(""); + ntext->textContent = gf_strdup(""); } res = &ntext->textContent; compositor->dom_text_pos ++; @@ -269,7 +279,7 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) } caret_pos = strlen(n1->textContent); if (n2->textContent) { - n1->textContent = realloc(n1->textContent, sizeof(char)*(strlen(n1->textContent)+strlen(n2->textContent)+1)); + n1->textContent = gf_realloc(n1->textContent, sizeof(char)*(strlen(n1->textContent)+strlen(n2->textContent)+1)); strcat(n1->textContent, n2->textContent); } gf_node_list_del_child(&children, (GF_Node*)n2); @@ -298,7 +308,7 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) } /*load of an empty text*/ if (!res && !cmd_type) { - GF_DOMText *t = gf_dom_add_text_node(compositor->focus_node, strdup("")); + GF_DOMText *t = gf_dom_add_text_node(compositor->focus_node, gf_strdup("")); res = &t->textContent; } @@ -316,7 +326,7 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) if (*res) { const char *src = *res; compositor->sel_buffer_alloc = 2+strlen(src); - compositor->sel_buffer = realloc(compositor->sel_buffer, sizeof(u16)*compositor->sel_buffer_alloc); + compositor->sel_buffer = gf_realloc(compositor->sel_buffer, sizeof(u16)*compositor->sel_buffer_alloc); if (caret_pos>=0) { compositor->sel_buffer_len = gf_utf8_mbstowcs(compositor->sel_buffer, compositor->sel_buffer_alloc, &src); @@ -333,7 +343,7 @@ static Bool load_text_node(GF_Compositor *compositor, u32 cmd_type) compositor->sel_buffer[compositor->sel_buffer_len]=0; } else { compositor->sel_buffer_alloc = 2; - compositor->sel_buffer = malloc(sizeof(u16)*2); + compositor->sel_buffer = gf_malloc(sizeof(u16)*2); compositor->sel_buffer[0] = '|'; compositor->sel_buffer[1] = 0; compositor->caret_pos = 0; @@ -359,17 +369,36 @@ static void exec_text_input(GF_Compositor *compositor, GF_Event *event) case '\b': return; default: + { +#ifndef GPAC_DISABLE_SVG + GF_DOM_Event evt; + GF_Node *target; + /*send text input event*/ + memset(&evt, 0, sizeof(GF_DOM_Event)); + evt.key_flags = event->key.flags; + evt.bubbles = 1; + evt.cancelable = 1; + evt.type = event->type; + evt.detail = event->character.unicode_char; + target = compositor->focus_node; + if (!target) target = gf_sg_get_root_node(compositor->scene); + gf_dom_event_fire(target, &evt); + /*event has been cancelled*/ + if (evt.event_phase & GF_DOM_EVENT_CANCEL_MASK) return; + if (compositor->sel_buffer_len + 1 == compositor->sel_buffer_alloc) { compositor->sel_buffer_alloc += 10; - compositor->sel_buffer = realloc(compositor->sel_buffer, sizeof(u16)*compositor->sel_buffer_alloc); + compositor->sel_buffer = gf_realloc(compositor->sel_buffer, sizeof(u16)*compositor->sel_buffer_alloc); } memmove(&compositor->sel_buffer[compositor->caret_pos+1], &compositor->sel_buffer[compositor->caret_pos], sizeof(u16)*(compositor->sel_buffer_len-compositor->caret_pos)); compositor->sel_buffer[compositor->caret_pos] = event->character.unicode_char; compositor->sel_buffer_len++; compositor->caret_pos++; compositor->sel_buffer[compositor->sel_buffer_len] = 0; +#endif break; } + } } else if (event->type==GF_EVENT_KEYDOWN) { u32 prev_caret = compositor->caret_pos; switch (event->key.key_code) { @@ -468,16 +497,24 @@ static Bool hit_node_editable(GF_Compositor *compositor, Bool check_focus_node) if (compositor->hit_node==compositor->focus_node) return compositor->focus_text_type ? 1 : 0; tag = gf_node_get_tag(text); - if ( (tag==TAG_MPEG4_Text) || (tag==TAG_X3D_Text)) { + +#ifndef GPAC_DISABLE_VRML + if ( (tag==TAG_MPEG4_Text) +#ifndef GPAC_DISABLE_X3D + || (tag==TAG_X3D_Text) +#endif + ) { M_FontStyle *fs = (M_FontStyle *) ((M_Text *)text)->fontStyle; - if (!fs) return 0; + if (!fs || !fs->style.buffer) return 0; if (!strstr(fs->style.buffer, "editable") && !strstr(fs->style.buffer, "EDITABLE")) return 0; compositor->focus_text_type = 3; compositor->focus_node = text; return 1; } -#ifndef GPAC_DISABLE_SVG +#endif /*GPAC_DISABLE_VRML*/ + if (tag <= GF_NODE_FIRST_DOM_NODE_TAG) return 0; +#ifndef GPAC_DISABLE_SVG gf_svg_flatten_attributes((SVG_Element *)text, &atts); if (!atts.editable || !*atts.editable) return 0; switch (tag) { @@ -547,6 +584,12 @@ static Bool exec_event_dom(GF_Compositor *compositor, GF_Event *event) ) { Fixed X = compositor->hit_world_point.x; Fixed Y = compositor->hit_world_point.y; + /*flip back to origin at top-left*/ + if (compositor->visual->center_coords) { + X += INT2FIX(compositor->visual->width)/2; + Y = INT2FIX(compositor->visual->height)/2 - Y; + } + if (compositor->hit_node) { GF_Node *focus; Bool hit_changed = 0; @@ -609,7 +652,11 @@ static Bool exec_event_dom(GF_Compositor *compositor, GF_Event *event) evt.button = event->mouse.button; evt.detail = compositor->num_clicks; ret += gf_dom_event_fire_ex(compositor->grab_node, &evt, compositor->hit_use_stack); - if ((compositor->grab_x == X) && (compositor->grab_y == Y)) { + +#if !defined(_WIN32_WCE) + if ((compositor->grab_x == X) && (compositor->grab_y == Y)) +#endif + { evt.type = GF_EVENT_CLICK; ret += gf_dom_event_fire_ex(compositor->grab_node, &evt, compositor->hit_use_stack); } @@ -709,18 +756,38 @@ static Bool exec_event_dom(GF_Compositor *compositor, GF_Event *event) #endif } -static Bool exec_event_vrml(GF_Compositor *compositor, GF_Event *ev) +#ifndef GPAC_DISABLE_VRML + +Bool gf_sc_exec_event_vrml(GF_Compositor *compositor, GF_Event *ev) { GF_SensorHandler *hs, *hs_grabbed; GF_List *tmp; u32 i, count, stype; + /*reset previous composite texture*/ + if (compositor->prev_hit_appear != compositor->hit_appear) { + if (compositor->prev_hit_appear) { + compositor_compositetexture_handle_event(compositor, compositor->prev_hit_appear, ev, 1); + compositor->prev_hit_appear = NULL; + } + } + /*composite texture*/ - if (!gf_list_count(compositor->sensors) && compositor->hit_appear) - return compositor_compositetexture_handle_event(compositor, ev); + if (compositor->hit_appear) { + GF_Node *appear = compositor->hit_appear; + if (compositor_compositetexture_handle_event(compositor, compositor->hit_appear, ev, 0)) { + compositor->prev_hit_appear = appear; + return 1; + } + compositor->prev_hit_appear = NULL; + } + hs_grabbed = NULL; - stype = GF_CURSOR_NORMAL; + /*if we have a hit node at the compositor level, use "touch" as default cursor - this avoid + resetting the cursor when the picked node is a DOM node in a composite texture*/ + stype = (compositor->hit_node!=NULL) ? GF_CURSOR_TOUCH : GF_CURSOR_NORMAL; + count = gf_list_count(compositor->previous_sensors); for (i=0; i<count; i++) { hs = (GF_SensorHandler*)gf_list_get(compositor->previous_sensors, i); @@ -735,11 +802,18 @@ static Bool exec_event_vrml(GF_Compositor *compositor, GF_Event *ev) } count = gf_list_count(compositor->sensors); - for (i=0; i<count; i++) { - hs = (GF_SensorHandler*)gf_list_get(compositor->sensors, i); - hs->OnUserEvent(hs, 1, ev, compositor); - stype = gf_node_get_tag(hs->sensor); - if (hs==hs_grabbed) hs_grabbed = NULL; + if (!count) stype = GF_CURSOR_NORMAL; + else { + for (i=0; i<count; i++) { + GF_Node *keynav; + hs = (GF_SensorHandler*)gf_list_get(compositor->sensors, i); + hs->OnUserEvent(hs, ((hs==hs_grabbed) || !hs_grabbed) ? 1 : 0, ev, compositor); + stype = gf_node_get_tag(hs->sensor); + if (hs==hs_grabbed) hs_grabbed = NULL; + + keynav = gf_scene_get_keynav(gf_node_get_graph(hs->sensor), hs->sensor); + if (keynav) gf_sc_change_key_navigator(compositor, keynav); + } } /*switch sensors*/ tmp = compositor->sensors; @@ -758,26 +832,43 @@ static Bool exec_event_vrml(GF_Compositor *compositor, GF_Event *ev) if (compositor->sensor_type != GF_CURSOR_COLLIDE) { switch (stype) { case TAG_MPEG4_Anchor: - case TAG_X3D_Anchor: stype = GF_CURSOR_ANCHOR; break; case TAG_MPEG4_PlaneSensor2D: case TAG_MPEG4_PlaneSensor: - case TAG_X3D_PlaneSensor: - stype = GF_CURSOR_PLANE; break; + stype = GF_CURSOR_PLANE; + break; case TAG_MPEG4_CylinderSensor: - case TAG_X3D_CylinderSensor: case TAG_MPEG4_DiscSensor: case TAG_MPEG4_SphereSensor: - case TAG_X3D_SphereSensor: - stype = GF_CURSOR_ROTATE; break; + stype = GF_CURSOR_ROTATE; + break; case TAG_MPEG4_ProximitySensor2D: case TAG_MPEG4_ProximitySensor: - case TAG_X3D_ProximitySensor: - stype = GF_CURSOR_PROXIMITY; break; + stype = GF_CURSOR_PROXIMITY; + break; case TAG_MPEG4_TouchSensor: + stype = GF_CURSOR_TOUCH; + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Anchor: + stype = GF_CURSOR_ANCHOR; + break; + case TAG_X3D_PlaneSensor: + stype = GF_CURSOR_PLANE; + break; + case TAG_X3D_CylinderSensor: + case TAG_X3D_SphereSensor: + stype = GF_CURSOR_ROTATE; + break; + case TAG_X3D_ProximitySensor: + stype = GF_CURSOR_PROXIMITY; + break; case TAG_X3D_TouchSensor: - stype = GF_CURSOR_TOUCH; break; + stype = GF_CURSOR_TOUCH; + break; +#endif + default: stype = GF_CURSOR_NORMAL; break; } if ((stype != GF_CURSOR_NORMAL) || (compositor->sensor_type != stype)) { @@ -790,7 +881,21 @@ static Bool exec_event_vrml(GF_Compositor *compositor, GF_Event *ev) } else { gf_sc_reset_collide_cursor(compositor); } - return count ? 1 : 0; + if (count) { +#if 1 + GF_SceneGraph *sg; + /*apply event cascade - this is needed for cases where several events are processed inbetween + 2 simultaion tick. If we don't flush the routes stack, the result will likely be wrong + */ + gf_sg_activate_routes(compositor->scene); + i = 0; + while ((sg = (GF_SceneGraph*)gf_list_enum(compositor->extra_scenes, &i))) { + gf_sg_activate_routes(sg); + } +#endif + return 1; + } + return 0; } @@ -804,15 +909,20 @@ static Bool exec_vrml_key_event(GF_Compositor *compositor, GF_Node *node, GF_Eve switch (gf_node_get_tag(node)) { case TAG_MPEG4_Text: - case TAG_X3D_Text: return 0; case TAG_MPEG4_Layout: hdl = compositor_mpeg4_layout_get_sensor_handler(node); break; case TAG_MPEG4_Anchor: + hdl = compositor_mpeg4_get_sensor_handler(node); + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Text: + return 0; case TAG_X3D_Anchor: hdl = compositor_mpeg4_get_sensor_handler(node); break; +#endif } child = ((GF_ParentNode*)node)->children; if (hdl) { @@ -831,7 +941,7 @@ static Bool exec_vrml_key_event(GF_Compositor *compositor, GF_Node *node, GF_Eve return ret ? 1 : 0; } - +#endif /*GPAC_DISABLE_VRML*/ Bool visual_execute_event(GF_VisualManager *visual, GF_TraverseState *tr_state, GF_Event *ev, GF_ChildNodeItem *children) { @@ -878,18 +988,17 @@ Bool visual_execute_event(GF_VisualManager *visual, GF_TraverseState *tr_state, compositor->store_text_state = GF_SC_TSEL_RELEASED; compositor->text_selection = NULL; - if (compositor->selected_text) free(compositor->selected_text); + if (compositor->selected_text) gf_free(compositor->selected_text); compositor->selected_text = NULL; - if (compositor->sel_buffer) free(compositor->sel_buffer); + if (compositor->sel_buffer) gf_free(compositor->sel_buffer); compositor->sel_buffer = NULL; compositor->sel_buffer_alloc = 0; compositor->sel_buffer_len = 0; - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); } else if (compositor->store_text_state == GF_SC_TSEL_RELEASED) { compositor->store_text_state = GF_SC_TSEL_NONE; } - } /*pick node*/ @@ -899,6 +1008,10 @@ Bool visual_execute_event(GF_VisualManager *visual, GF_TraverseState *tr_state, compositor->prev_hit_use_stack = compositor->hit_use_stack; compositor->hit_use_stack = temp_stack; + tr_state->pick_x = ev->mouse.x; + tr_state->pick_y = ev->mouse.y; + + #ifndef GPAC_DISABLE_3D if (visual->type_3d) visual_3d_pick_node(visual, tr_state, ev, children); @@ -917,7 +1030,11 @@ Bool visual_execute_event(GF_VisualManager *visual, GF_TraverseState *tr_state, /*no vrml sensors above*/ if (!gf_list_count(compositor->sensors) && !gf_list_count(compositor->previous_sensors)) return 0; } - return exec_event_vrml(compositor, ev); +#ifndef GPAC_DISABLE_VRML + return gf_sc_exec_event_vrml(compositor, ev); +#else + return 0; +#endif } u32 gf_sc_svg_focus_navigate(GF_Compositor *compositor, u32 key_code) @@ -986,10 +1103,18 @@ static Bool is_focus_target(GF_Node *elt) switch (tag) { #ifndef GPAC_DISABLE_SVG case TAG_SVG_a: + return 1; #endif + +#ifndef GPAC_DISABLE_VRML case TAG_MPEG4_Anchor: + return 1; +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Anchor: return 1; +#endif +#endif + default: break; } @@ -1005,6 +1130,10 @@ static Bool is_focus_target(GF_Node *elt) case GF_EVENT_FOCUSIN: case GF_EVENT_FOCUSOUT: case GF_EVENT_ACTIVATE: + /*although this is not in the SVGT1.2 spec, we also enable focus switching if key events are listened on the element*/ + case GF_EVENT_KEYDOWN: + case GF_EVENT_KEYUP: + case GF_EVENT_LONGKEYPRESS: return 1; } } @@ -1016,8 +1145,12 @@ static Bool is_focus_target(GF_Node *elt) #define CALL_SET_FOCUS(__child) { \ gf_list_add(compositor->focus_ancestors, elt); \ n = set_focus(compositor, __child, current_focus, prev_focus); \ - if (n) return n; \ + if (n) { \ + gf_node_set_cyclic_traverse_flag(elt, 0); \ + return n; \ + } \ gf_list_rem_last(compositor->focus_ancestors); \ + gf_node_set_cyclic_traverse_flag(elt, 0);\ return NULL; \ } \ @@ -1042,15 +1175,21 @@ static GF_Node *set_focus(GF_Compositor *compositor, GF_Node *elt, Bool current_ GF_Node *n; if (!elt) return NULL; + + /*all return in this function shall be preceeded with gf_node_set_cyclic_traverse_flag(elt, 0) + this ensures that we don't go into cyclic references when moving focus, hence stack overflow*/ + if (! gf_node_set_cyclic_traverse_flag(elt, 1)) return NULL; tag = gf_node_get_tag(elt); if (tag <= GF_NODE_FIRST_DOM_NODE_TAG) { switch (tag) { - case TAG_MPEG4_Group: case TAG_X3D_Group: - case TAG_MPEG4_Transform: case TAG_X3D_Transform: - case TAG_MPEG4_Billboard: case TAG_X3D_Billboard: - case TAG_MPEG4_Collision: case TAG_X3D_Collision: - case TAG_MPEG4_LOD: case TAG_X3D_LOD: +#ifndef GPAC_DISABLE_VRML + + case TAG_MPEG4_Group: + case TAG_MPEG4_Transform: + case TAG_MPEG4_Billboard: + case TAG_MPEG4_Collision: + case TAG_MPEG4_LOD: case TAG_MPEG4_OrderedGroup: case TAG_MPEG4_Transform2D: case TAG_MPEG4_TransformMatrix2D: @@ -1059,107 +1198,184 @@ static GF_Node *set_focus(GF_Compositor *compositor, GF_Node *elt, Bool current_ case TAG_MPEG4_Layer2D: case TAG_MPEG4_PathLayout: case TAG_MPEG4_Form: - case TAG_MPEG4_Anchor: case TAG_X3D_Anchor: + case TAG_MPEG4_Anchor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Group: + case TAG_X3D_Transform: + case TAG_X3D_Billboard: + case TAG_X3D_Collision: + case TAG_X3D_LOD: + case TAG_X3D_Anchor: +#endif if (!current_focus) { /*get the base grouping stack (*/ BaseGroupingStack *grp = (BaseGroupingStack*)gf_node_get_private(elt); - if (grp && (grp->flags & (GROUP_HAS_SENSORS | GROUP_IS_ANCHOR) )) + if (grp && (grp->flags & (GROUP_HAS_SENSORS | GROUP_IS_ANCHOR) )) { + gf_node_set_cyclic_traverse_flag(elt, 0); return elt; + } } break; - case TAG_MPEG4_Switch: case TAG_X3D_Switch: - { + case TAG_MPEG4_Switch: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Switch: +#endif + { s32 i, wc; GF_ChildNodeItem *child; +#ifndef GPAC_DISABLE_X3D if (tag==TAG_X3D_Switch) { child = ((X_Switch*)elt)->children; wc = ((X_Switch*)elt)->whichChoice; - } else { + } else +#endif + { child = ((M_Switch*)elt)->choice; wc = ((M_Switch*)elt)->whichChoice; } - if (wc==-1) return NULL; + if (wc==-1) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return NULL; + } i=0; while (child) { if (i==wc) CALL_SET_FOCUS(child->node); child = child->next; } + gf_node_set_cyclic_traverse_flag(elt, 0); return NULL; } - case TAG_MPEG4_Text: case TAG_X3D_Text: + case TAG_MPEG4_Text: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Text: +#endif + gf_node_set_cyclic_traverse_flag(elt, 0); + if (!current_focus) { M_FontStyle *fs = (M_FontStyle *) ((M_Text *)elt)->fontStyle; - if (!fs) return NULL; + + if (!fs || !fs->style.buffer) return NULL; if (!strstr(fs->style.buffer, "editable") && !strstr(fs->style.buffer, "EDITABLE")) return NULL; compositor->focus_text_type = 3; return elt; } return NULL; case TAG_MPEG4_Layout: - if (!current_focus && (compositor_mpeg4_layout_get_sensor_handler(elt)!=NULL)) + if (!current_focus && (compositor_mpeg4_layout_get_sensor_handler(elt)!=NULL)) { + gf_node_set_cyclic_traverse_flag(elt, 0); return elt; + } break; case TAG_ProtoNode: - CALL_SET_FOCUS(gf_node_get_proto_root(elt)); + /*hardcoded proto acting as a grouping node*/ + if (gf_node_proto_is_grouping(elt)) { + GF_FieldInfo info; + if (!current_focus) { + /*get the base grouping stack (*/ + BaseGroupingStack *grp = (BaseGroupingStack*)gf_node_get_private(elt); + if (grp && (grp->flags & (GROUP_HAS_SENSORS | GROUP_IS_ANCHOR) )) + gf_node_set_cyclic_traverse_flag(elt, 0); + return elt; + } + if ( (gf_node_get_field_by_name(elt, "children", &info) != GF_OK) || (info.fieldType != GF_SG_VRML_MFNODE)) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return NULL; + } + child = *(GF_ChildNodeItem **) info.far_ptr; + } else { + CALL_SET_FOCUS(gf_node_get_proto_root(elt)); + } + break; - case TAG_MPEG4_Inline: case TAG_X3D_Inline: - CALL_SET_FOCUS(gf_inline_get_subscene_root(elt)); + case TAG_MPEG4_Inline: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Inline: +#endif + CALL_SET_FOCUS(gf_scene_get_subscene_root(elt)); + + case TAG_MPEG4_Shape: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Shape: +#endif - case TAG_MPEG4_Shape: case TAG_X3D_Shape: gf_list_add(compositor->focus_ancestors, elt); n = set_focus(compositor, ((M_Shape*)elt)->geometry, current_focus, prev_focus); - if (n) return n; - n = set_focus(compositor, ((M_Shape*)elt)->appearance, current_focus, prev_focus); - if (n) return n; + if (!n) n = set_focus(compositor, ((M_Shape*)elt)->appearance, current_focus, prev_focus); + if (n) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return n; + } gf_list_rem_last(compositor->focus_ancestors); + gf_node_set_cyclic_traverse_flag(elt, 0); return NULL; - case TAG_MPEG4_Appearance: case TAG_X3D_Appearance: + case TAG_MPEG4_Appearance: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Appearance: +#endif CALL_SET_FOCUS(((M_Appearance*)elt)->texture); - case TAG_MPEG4_CompositeTexture2D: case TAG_MPEG4_CompositeTexture3D: + case TAG_MPEG4_CompositeTexture2D: + case TAG_MPEG4_CompositeTexture3D: /*CompositeTextures are not grouping nodes per say*/ child = ((GF_ParentNode*)elt)->children; while (child) { - if (compositor_mpeg4_get_sensor_handler(child->node) != NULL) + if (compositor_mpeg4_get_sensor_handler(child->node) != NULL) { + gf_node_set_cyclic_traverse_flag(elt, 0); return elt; + } child = child->next; } break; +#endif /*GPAC_DISABLE_VRML*/ + default: + gf_node_set_cyclic_traverse_flag(elt, 0); return NULL; } - - child = ((GF_ParentNode*)elt)->children; + if (!child) + child = ((GF_ParentNode*)elt)->children; } else { #ifndef GPAC_DISABLE_SVG SVGAllAttributes atts; - if (tag==TAG_SVG_defs) return NULL; - + if (tag==TAG_SVG_defs) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return NULL; + } gf_svg_flatten_attributes((SVG_Element *)elt, &atts); - if (atts.display && (*atts.display==SVG_DISPLAY_NONE)) return NULL; - + if (atts.display && (*atts.display==SVG_DISPLAY_NONE)) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return NULL; + } if (!current_focus) { Bool is_auto = 1; if (atts.focusable) { - if (*atts.focusable==SVG_FOCUSABLE_TRUE) return elt; + if (*atts.focusable==SVG_FOCUSABLE_TRUE) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return elt; + } if (*atts.focusable==SVG_FOCUSABLE_FALSE) is_auto = 0; } - if (is_auto && is_focus_target(elt)) return elt; + if (is_auto && is_focus_target(elt)) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return elt; + } if (atts.editable && *atts.editable) { switch (tag) { case TAG_SVG_text: case TAG_SVG_textArea: compositor->focus_text_type = 1; + gf_node_set_cyclic_traverse_flag(elt, 0); return elt; case TAG_SVG_tspan: compositor->focus_text_type = 2; + gf_node_set_cyclic_traverse_flag(elt, 0); return elt; default: break; @@ -1172,14 +1388,19 @@ static GF_Node *set_focus(GF_Compositor *compositor, GF_Node *elt, Bool current_ switch (atts.nav_prev->type) { case SVG_FOCUS_SELF: /*focus locked on element*/ + gf_node_set_cyclic_traverse_flag(elt, 0); return elt; case SVG_FOCUS_IRI: if (!atts.nav_prev->target.target) { - if (!atts.nav_prev->target.string) return NULL; + if (!atts.nav_prev->target.string) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return NULL; + } atts.nav_prev->target.target = gf_sg_find_node_by_name(compositor->scene, atts.nav_prev->target.string+1); } if (atts.nav_prev->target.target) { rebuild_focus_ancestor(compositor, atts.nav_prev->target.target); + gf_node_set_cyclic_traverse_flag(elt, 0); return atts.nav_prev->target.target; } default: @@ -1192,14 +1413,19 @@ static GF_Node *set_focus(GF_Compositor *compositor, GF_Node *elt, Bool current_ switch (atts.nav_next->type) { case SVG_FOCUS_SELF: /*focus locked on element*/ + gf_node_set_cyclic_traverse_flag(elt, 0); return elt; case SVG_FOCUS_IRI: if (!atts.nav_next->target.target) { - if (!atts.nav_next->target.string) return NULL; + if (!atts.nav_next->target.string) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return NULL; + } atts.nav_next->target.target = gf_sg_find_node_by_name(compositor->scene, atts.nav_next->target.string+1); } if (atts.nav_next->target.target) { rebuild_focus_ancestor(compositor, atts.nav_next->target.target); + gf_node_set_cyclic_traverse_flag(elt, 0); return atts.nav_next->target.target; } default: @@ -1224,14 +1450,20 @@ static GF_Node *set_focus(GF_Compositor *compositor, GF_Node *elt, Bool current_ if (prev_focus) { u32 count, i; /*check all children except if current focus*/ - if (current_focus) return NULL; + if (current_focus) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return NULL; + } gf_list_add(compositor->focus_ancestors, elt); count = gf_node_list_get_count(child); for (i=count; i>0; i--) { /*get in the subtree*/ n = gf_node_list_get_child( ((GF_ParentNode *)elt)->children, i-1); n = set_focus(compositor, n, 0, 1); - if (n) return n; + if (n) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return n; + } } } else { /*check all children */ @@ -1239,7 +1471,10 @@ static GF_Node *set_focus(GF_Compositor *compositor, GF_Node *elt, Bool current_ while (child) { /*get in the subtree*/ n = set_focus(compositor, child->node, 0, 0); - if (n) return n; + if (n) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return n; + } child = child->next; } } @@ -1249,17 +1484,21 @@ static GF_Node *set_focus(GF_Compositor *compositor, GF_Node *elt, Bool current_ n = set_focus(compositor, use_node, 0, 0); if (n) { compositor->focus_used = elt; + gf_node_set_cyclic_traverse_flag(elt, 0); return n; } gf_list_rem_last(compositor->focus_use_stack); gf_list_rem_last(compositor->focus_use_stack); } else if (anim_node) { n = set_focus(compositor, anim_node, 0, 0); - if (n) return n; + if (n) { + gf_node_set_cyclic_traverse_flag(elt, 0); + return n; + } } gf_list_rem_last(compositor->focus_ancestors); - + gf_node_set_cyclic_traverse_flag(elt, 0); return NULL; } @@ -1277,11 +1516,12 @@ static GF_Node *browse_parent_for_focus(GF_Compositor *compositor, GF_Node *elt, tag = gf_node_get_tag(par); if (tag <= GF_NODE_FIRST_DOM_NODE_TAG) { switch (tag) { - case TAG_MPEG4_Group: case TAG_X3D_Group: - case TAG_MPEG4_Transform: case TAG_X3D_Transform: - case TAG_MPEG4_Billboard: case TAG_X3D_Billboard: - case TAG_MPEG4_Collision: case TAG_X3D_Collision: - case TAG_MPEG4_LOD: case TAG_X3D_LOD: +#ifndef GPAC_DISABLE_VRML + case TAG_MPEG4_Group: + case TAG_MPEG4_Transform: + case TAG_MPEG4_Billboard: + case TAG_MPEG4_Collision: + case TAG_MPEG4_LOD: case TAG_MPEG4_OrderedGroup: case TAG_MPEG4_Transform2D: case TAG_MPEG4_TransformMatrix2D: @@ -1291,10 +1531,33 @@ static GF_Node *browse_parent_for_focus(GF_Compositor *compositor, GF_Node *elt, case TAG_MPEG4_Layout: case TAG_MPEG4_PathLayout: case TAG_MPEG4_Form: - case TAG_MPEG4_Anchor: case TAG_X3D_Anchor: + case TAG_MPEG4_Anchor: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Anchor: + case TAG_X3D_Group: + case TAG_X3D_Transform: + case TAG_X3D_Billboard: + case TAG_X3D_Collision: + case TAG_X3D_LOD: +#endif case TAG_MPEG4_CompositeTexture2D: case TAG_MPEG4_CompositeTexture3D: child = ((GF_ParentNode*)par)->children; break; + case TAG_ProtoNode: + /*hardcoded proto acting as a grouping node*/ + if (gf_node_proto_is_grouping(par)) { + GF_FieldInfo info; + if ((gf_node_get_field_by_name(par, "children", &info) == GF_OK) + && (info.fieldType == GF_SG_VRML_MFNODE) + ) { + child = *(GF_ChildNodeItem **) info.far_ptr; + break; + } + } + /*fall through*/ + +#endif /*GPAC_DISABLE_VRML*/ + /*for all other node, locate parent*/ default: gf_list_rem_last(compositor->focus_ancestors); @@ -1402,8 +1665,6 @@ u32 gf_sc_focus_switch_ring_ex(GF_Compositor *compositor, Bool move_prev, GF_Nod if ((prev != compositor->focus_node) || (prev_use != compositor->focus_used)) { GF_DOM_Event evt; GF_Event ev; - /*the event is already handled, even though no listeners may be present*/ - ret = 1; memset(&evt, 0, sizeof(GF_DOM_Event)); memset(&ev, 0, sizeof(GF_Event)); ev.type = GF_EVENT_KEYDOWN; @@ -1414,18 +1675,26 @@ u32 gf_sc_focus_switch_ring_ex(GF_Compositor *compositor, Bool move_prev, GF_Nod evt.bubbles = 1; evt.type = GF_EVENT_FOCUSOUT; gf_dom_event_fire_ex(prev, &evt, cloned_use); - } else { + } +#ifndef GPAC_DISABLE_VRML + else { exec_vrml_key_event(compositor, prev, &ev, 1); } +#endif } if (compositor->focus_node) { + /*the event is already handled, even though no listeners may be present*/ + ret = 1; if (compositor->focus_uses_dom_events) { evt.bubbles = 1; evt.type = GF_EVENT_FOCUSIN; gf_dom_event_fire_ex(compositor->focus_node, &evt, compositor->focus_use_stack); - } else { + } +#ifndef GPAC_DISABLE_VRML + else { exec_vrml_key_event(compositor, NULL, &ev, 0); } +#endif } /*invalidate in case we draw focus rect*/ gf_sc_invalidate(compositor, NULL); @@ -1453,14 +1722,16 @@ Bool gf_sc_execute_event(GF_Compositor *compositor, GF_TraverseState *tr_state, /*send text edit*/ if (compositor->edited_text) { exec_text_input(compositor, ev); - return 1; + if (compositor->edited_text) return 1; + /*if text is no longer edited, this is focus change so process as usual*/ } /*FIXME - this is not working for mixed docs*/ if (compositor->focus_uses_dom_events) ret = exec_event_dom(compositor, ev); +#ifndef GPAC_DISABLE_VRML else ret = exec_vrml_key_event(compositor, compositor->focus_node, ev, 0); - +#endif if (ev->type==GF_EVENT_KEYDOWN) { switch (ev->key.key_code) { @@ -1468,7 +1739,12 @@ Bool gf_sc_execute_event(GF_Compositor *compositor, GF_TraverseState *tr_state, if (0&&compositor->focus_text_type) { exec_text_input(compositor, NULL); ret = 1; - } +#ifndef GPAC_DISABLE_VRML + } else if (compositor->keynav_node && ((M_KeyNavigator*)compositor->keynav_node)->select) { + gf_sc_change_key_navigator(compositor, ((M_KeyNavigator*)compositor->keynav_node)->select); + ret=1; +#endif + } break; case GF_KEY_TAB: ret += gf_sc_focus_switch_ring(compositor, (ev->key.flags & GF_KEY_MOD_SHIFT) ? 1 : 0); @@ -1477,7 +1753,23 @@ Bool gf_sc_execute_event(GF_Compositor *compositor, GF_TraverseState *tr_state, case GF_KEY_DOWN: case GF_KEY_LEFT: case GF_KEY_RIGHT: - ret += gf_sc_svg_focus_navigate(compositor, ev->key.key_code); + if (compositor->focus_uses_dom_events) { + ret += gf_sc_svg_focus_navigate(compositor, ev->key.key_code); + } else if (compositor->keynav_node) { + GF_Node *next_nav = NULL; +#ifndef GPAC_DISABLE_VRML + switch (ev->key.key_code) { + case GF_KEY_UP: next_nav = ((M_KeyNavigator*)compositor->keynav_node)->up; break; + case GF_KEY_DOWN: next_nav = ((M_KeyNavigator*)compositor->keynav_node)->down; break; + case GF_KEY_LEFT: next_nav = ((M_KeyNavigator*)compositor->keynav_node)->left; break; + case GF_KEY_RIGHT: next_nav = ((M_KeyNavigator*)compositor->keynav_node)->right; break; + } +#endif + if (next_nav) { + gf_sc_change_key_navigator(compositor, next_nav); + ret=1; + } + } break; } } @@ -1489,25 +1781,72 @@ Bool gf_sc_execute_event(GF_Compositor *compositor, GF_TraverseState *tr_state, Bool gf_sc_exec_event(GF_Compositor *compositor, GF_Event *evt) { + Bool switch_coords=0; + Bool ret=0; if (evt->type<=GF_EVENT_MOUSEWHEEL) { if (compositor->visual->center_coords) { evt->mouse.x = evt->mouse.x - compositor->display_width/2; evt->mouse.y = compositor->display_height/2 - evt->mouse.y; + switch_coords=1; } } /*process regular events except if navigation is grabbed*/ if ( (compositor->navigation_state<2) && (compositor->interaction_level & GF_INTERACT_NORMAL) && gf_sc_execute_event(compositor, compositor->traverse_state, evt, NULL)) { compositor->navigation_state = 0; - return 1; + ret = 1; } + + if (!ret) { #ifndef GPAC_DISABLE_3D - /*remember active layer on mouse click - may be NULL*/ - if ((evt->type==GF_EVENT_MOUSEDOWN) && (evt->mouse.button==GF_MOUSE_LEFT)) compositor->active_layer = compositor->traverse_state->layer3d; + /*remember active layer on mouse click - may be NULL*/ + if ((evt->type==GF_EVENT_MOUSEDOWN) && (evt->mouse.button==GF_MOUSE_LEFT)) compositor->active_layer = compositor->traverse_state->layer3d; #endif - /*process navigation events*/ - if (compositor->interaction_level & GF_INTERACT_NAVIGATION) return compositor_handle_navigation(compositor, evt); - return 0; + /*process navigation events*/ + if (compositor->interaction_level & GF_INTERACT_NAVIGATION) + ret = compositor_handle_navigation(compositor, evt); + } + + if (switch_coords) { + evt->mouse.x += compositor->display_width/2; + evt->mouse.y = compositor->display_height/2 - evt->mouse.y; + } + return ret; } +#ifndef GPAC_DISABLE_VRML +void gf_sc_change_key_navigator(GF_Compositor *sr, GF_Node *n) +{ + GF_Node *par; + M_KeyNavigator *kn; + + gf_list_reset(sr->focus_ancestors); + + if (sr->keynav_node) { + kn = (M_KeyNavigator*)sr->keynav_node; + kn->focusSet = 0; + gf_node_event_out_str(sr->keynav_node, "focusSet"); + } + sr->keynav_node = n; + kn = (M_KeyNavigator*)n; + if (n) { + kn->focusSet = 1; + gf_node_event_out_str(sr->keynav_node, "focusSet"); + } + + par = n ? kn->sensor : NULL; + if (par) par = gf_node_get_parent(par, 0); + + gf_sc_focus_switch_ring_ex(sr, 0, par, 1); +} +#endif + +void gf_sc_key_navigator_del(GF_Compositor *sr, GF_Node *n) +{ + if (sr->keynav_node==n) { + sr->keynav_node = NULL; + } +} + + diff --git a/src/compositor/font_engine.c b/src/compositor/font_engine.c index 6343ed7..3fbb34b 100644 --- a/src/compositor/font_engine.c +++ b/src/compositor/font_engine.c @@ -81,7 +81,7 @@ GF_FontManager *gf_font_manager_new(GF_User *user) GF_SAFEALLOC(font_mgr, GF_FontManager); font_mgr->reader = ifce; font_mgr->id_buffer_size = 20; - font_mgr->id_buffer = malloc(sizeof(u32)*font_mgr->id_buffer_size); + font_mgr->id_buffer = gf_malloc(sizeof(u32)*font_mgr->id_buffer_size); gf_font_manager_set_font(font_mgr, &def_font, 1, 0); font_mgr->default_font = font_mgr->font; @@ -117,12 +117,12 @@ void gf_font_del(GF_Font *font) while (glyph) { GF_Glyph *next = glyph->next; gf_path_del(glyph->path); - free(glyph); + gf_free(glyph); glyph = next; } } - free(font->name); - free(font); + gf_free(font->name); + gf_free(font); } @@ -140,9 +140,9 @@ void gf_font_manager_del(GF_FontManager *fm) gf_font_del(font); font = next; } - free(fm->id_buffer); + gf_free(fm->id_buffer); gf_path_del(fm->line_path); - free(fm); + gf_free(fm); } GF_Err gf_font_manager_register_font(GF_FontManager *fm, GF_Font *font) @@ -190,11 +190,28 @@ GF_Font *gf_font_manager_set_font_ex(GF_FontManager *fm, char **alt_fonts, u32 n GF_Font *the_font = NULL; for (i=0; i<nb_fonts; i++) { + char *font_name; + const char *opt; u32 weight_diff = 0xFFFFFFFF; GF_Font *best_font = NULL; GF_Font *font = fm->font; + font_name = alt_fonts[i]; + + if (!stricmp(font_name, "SERIF")) { + opt = gf_modules_get_option((GF_BaseInterface *)fm->reader, "FontEngine", "FontSerif"); + if (opt) font_name = (char*)opt; + } + else if (!stricmp(font_name, "SANS") || !stricmp(font_name, "sans-serif")) { + opt = gf_modules_get_option((GF_BaseInterface *)fm->reader, "FontEngine", "FontSans"); + if (opt) font_name = (char*)opt; + } + else if (!stricmp(font_name, "TYPEWRITER") || !stricmp(font_name, "monospace")) { + opt = gf_modules_get_option((GF_BaseInterface *)fm->reader, "FontEngine", "FontFixed"); + if (opt) font_name = (char*)opt; + } + while (font) { - if ((check_only || !font->not_loaded) && font->name && !stricmp(font->name, alt_fonts[i])) { + if ((check_only || !font->not_loaded) && font->name && !stricmp(font->name, font_name)) { s32 fw; s32 w; u32 diff; @@ -254,12 +271,12 @@ GF_Font *gf_font_manager_set_font_ex(GF_FontManager *fm, char **alt_fonts, u32 n } if (the_font) break; if (fm->reader) { - e = fm->reader->set_font(fm->reader, alt_fonts[i], styles); + e = fm->reader->set_font(fm->reader, font_name, styles); if (!e) { GF_SAFEALLOC(the_font, GF_Font); fm->reader->get_font_info(fm->reader, &the_font->name, &the_font->em_size, &the_font->ascent, &the_font->descent, &the_font->underline, &the_font->line_spacing, &the_font->max_advance_h, &the_font->max_advance_v); the_font->styles = styles; - if (!the_font->name) the_font->name = strdup(alt_fonts[i]); + if (!the_font->name) the_font->name = gf_strdup(font_name); if (fm->font) { font = fm->font; @@ -341,7 +358,7 @@ GF_TextSpan *gf_font_manager_create_span(GF_FontManager *fm, GF_Font *font, char u32 len, i; GF_TextSpan *span; - if (!user || !strlen(text)) return NULL; + if (!strlen(text)) return NULL; len = fm->id_buffer_size; if (font->get_glyphs) @@ -351,7 +368,7 @@ GF_TextSpan *gf_font_manager_create_span(GF_FontManager *fm, GF_Font *font, char if (e==GF_BUFFER_TOO_SMALL) { fm->id_buffer_size = len; - fm->id_buffer = realloc(fm->id_buffer, sizeof(u32) * len); + fm->id_buffer = gf_realloc(fm->id_buffer, sizeof(u32) * len); if (!fm->id_buffer) return NULL; if (font->get_glyphs) @@ -371,17 +388,17 @@ GF_TextSpan *gf_font_manager_create_span(GF_FontManager *fm, GF_Font *font, char if (fliped_text) span->flags |= GF_TEXT_SPAN_FLIP; if (styles & GF_FONT_UNDERLINED) span->flags |= GF_TEXT_SPAN_UNDERLINE; span->nb_glyphs = len; - span->glyphs = malloc(sizeof(void *)*len); + span->glyphs = gf_malloc(sizeof(void *)*len); if (needs_x_offset) { - span->dx = malloc(sizeof(Fixed)*len); + span->dx = gf_malloc(sizeof(Fixed)*len); memset(span->dx, 0, sizeof(Fixed)*len); } if (needs_y_offset) { - span->dy = malloc(sizeof(Fixed)*len); + span->dy = gf_malloc(sizeof(Fixed)*len); memset(span->dy, 0, sizeof(Fixed)*len); } if (needs_rotate) { - span->rot = malloc(sizeof(Fixed)*len); + span->rot = gf_malloc(sizeof(Fixed)*len); memset(span->rot, 0, sizeof(Fixed)*len); } @@ -421,10 +438,10 @@ void gf_font_manager_delete_span(GF_FontManager *fm, GF_TextSpan *span) { if (span->user && span->font->spans) gf_list_del_item(span->font->spans, span); - free(span->glyphs); - if (span->dx) free(span->dx); - if (span->dy) free(span->dy); - if (span->rot) free(span->rot); + gf_free(span->glyphs); + if (span->dx) gf_free(span->dx); + if (span->dy) gf_free(span->dy); + if (span->rot) gf_free(span->rot); if (span->ext) { if (span->ext->path) gf_path_del(span->ext->path); @@ -435,12 +452,12 @@ void gf_font_manager_delete_span(GF_FontManager *fm, GF_TextSpan *span) #endif if (span->ext->txh) { gf_sc_texture_destroy(span->ext->txh); - if (span->ext->txh->data) free(span->ext->txh->data); - free(span->ext->txh); + if (span->ext->txh->data) gf_free(span->ext->txh->data); + gf_free(span->ext->txh); } - free(span->ext); + gf_free(span->ext); } - free(span); + gf_free(span); } void gf_font_manager_refresh_span_bounds(GF_TextSpan *span) @@ -485,7 +502,7 @@ void gf_font_manager_refresh_span_bounds(GF_TextSpan *span) /*compute glyph size*/ if (!span->glyphs[i]) g_width = span->font->max_advance_h * span->font_scale; /*if last glyph of the span, increase by width only*/ - else if (i+1==span->nb_glyphs) g_width = span->glyphs[i]->width * span->font_scale; +// else if (i+1==span->nb_glyphs) g_width = span->glyphs[i]->width * span->font_scale; /*otherwise increase by the horizontal advance*/ else g_width = span->glyphs[i]->horiz_advance * span->font_scale; @@ -675,8 +692,8 @@ static Bool span_setup_texture(GF_Compositor *compositor, GF_TextSpan *span, Boo if (span->ext->txh) { gf_sc_texture_destroy(span->ext->txh); - if (span->ext->txh->data) free(span->ext->txh->data); - free(span->ext->txh); + if (span->ext->txh->data) gf_free(span->ext->txh->data); + gf_free(span->ext->txh); } GF_SAFEALLOC(span->ext->txh, GF_TextureHandler); gf_sc_texture_setup(span->ext->txh, compositor, NULL); @@ -697,7 +714,7 @@ static Bool span_setup_texture(GF_Compositor *compositor, GF_TextSpan *span, Boo gf_sc_texture_release(span->ext->txh); return 0; } - span->ext->txh->data = (char *) malloc(sizeof(char)*span->ext->txh->stride*span->ext->txh->height); + span->ext->txh->data = (char *) gf_malloc(sizeof(char)*span->ext->txh->stride*span->ext->txh->height); memset(span->ext->txh->data, 0, sizeof(char)*span->ext->txh->stride*span->ext->txh->height); raster->stencil_set_texture(stencil, span->ext->txh->data, span->ext->txh->width, span->ext->txh->height, span->ext->txh->stride, span->ext->txh->pixelformat, span->ext->txh->pixelformat, 1); @@ -768,16 +785,15 @@ static void span_strike_3d(GF_TextSpan *span, GF_TraverseState *tr_state, DrawAs if (!span->ext->outline) { GF_Path *path = gf_font_span_create_path(span); span->ext->outline = new_mesh(); -#ifndef GPAC_USE_OGL_ES +#ifdef GPAC_HAS_GLU if (vect_outline) { GF_Path *outline = gf_path_get_outline(path, asp->pen_props); - TesselatePath(span->ext->outline, outline, asp->line_texture ? 2 : 1); + gf_mesh_tesselate_path(span->ext->outline, outline, asp->line_texture ? 2 : 1); gf_path_del(outline); } else { mesh_get_outline(span->ext->outline, path); } #else - /*VECTORIAL TEXT OUTLINE NOT SUPPORTED ON OGL-ES AT CURRENT TIME*/ vect_outline = 0; mesh_get_outline(span->ext->outline, path); #endif @@ -818,6 +834,7 @@ void gf_font_spans_draw_3d(GF_List *spans, GF_TraverseState *tr_state, DrawAspec which is too onerous (and not supported anyway) */ if (text_hl == 0x00FFFFFF) { if (!asp) { +#ifndef GPAC_DISABLE_VRML if (tr_state->appear) { SFColor c, rc; c = ((M_Material *) ((M_Appearance *) tr_state->appear)->material)->diffuseColor; @@ -830,7 +847,9 @@ void gf_font_spans_draw_3d(GF_List *spans, GF_TraverseState *tr_state, DrawAspec ((M_Material *) ((M_Appearance *) tr_state->appear)->material)->diffuseColor = rc; visual_3d_setup_appearance(tr_state); ((M_Material *) ((M_Appearance *) tr_state->appear)->material)->diffuseColor = c; - } else { + } else +#endif /*GPAC_DISABLE_VRML*/ + { hl_color.red = hl_color.green = hl_color.blue = 0; hl_color.alpha = FIX_ONE; } @@ -1172,6 +1191,7 @@ static void gf_font_spans_select(GF_TextSpan *span, GF_TraverseState *tr_state, */ has_selection = 1; if (ctx) { + g_rc.width+=2; if (span->rot) { gf_mx2d_init(ctx->transform); gf_mx2d_add_rotation(&ctx->transform, g_rc.x , g_rc.y, span->rot[i]); @@ -1184,7 +1204,7 @@ static void gf_font_spans_select(GF_TextSpan *span, GF_TraverseState *tr_state, if (!compositor->sel_buffer_alloc || compositor->sel_buffer_len == compositor->sel_buffer_alloc) { if (!compositor->sel_buffer_alloc) compositor->sel_buffer_alloc ++; compositor->sel_buffer_alloc = 2*compositor->sel_buffer_alloc; - compositor->sel_buffer = realloc(compositor->sel_buffer, sizeof(u16)*compositor->sel_buffer_alloc); + compositor->sel_buffer = gf_realloc(compositor->sel_buffer, sizeof(u16)*compositor->sel_buffer_alloc); } compositor->sel_buffer[compositor->sel_buffer_len] = span->glyphs[i]->utf_name; compositor->sel_buffer_len++; @@ -1339,6 +1359,15 @@ void gf_font_spans_pick(GF_Node *node, GF_List *spans, GF_TraverseState *tr_stat dy = span->off_y; for (j=0; j<span->nb_glyphs; j++) { GF_Rect rc; + if (!span->glyphs[j]) { + if (span->flags & GF_TEXT_SPAN_HORIZONTAL) { + dx += span->font_scale * span->font->max_advance_h; + } else { + dy -= span->font_scale * span->font->max_advance_v; + } + continue; + } + loc_x = x - (span->dx ? span->dx[j] : dx); loc_y = y - (span->dy ? span->dy[j] : dy); loc_x = gf_divfix(loc_x, span->font_scale); @@ -1396,7 +1425,8 @@ picked: compositor->end_sel.x = compositor->hit_world_point.x; compositor->end_sel.y = compositor->hit_world_point.y; if (compositor->text_selection) { - compositor->draw_next_frame = 1; + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); + if (tr_state->visual->offscreen) gf_node_dirty_set(tr_state->visual->offscreen, GF_SG_CHILD_DIRTY, 0); span->flags |= GF_TEXT_SPAN_SELECTED; } else { compositor->start_sel = compositor->end_sel; @@ -1408,9 +1438,12 @@ picked: compositor->hit_texcoords.x = gf_divfix(x, node_bounds->width) + FIX_ONE/2; compositor->hit_texcoords.y = gf_divfix(y, node_bounds->height) + FIX_ONE/2; +#ifndef GPAC_DISABLE_VRML if (compositor_is_composite_texture(tr_state->appear)) { compositor->hit_appear = tr_state->appear; - } else { + } else +#endif /*GPAC_DISABLE_VRML*/ + { compositor->hit_appear = NULL; } diff --git a/src/compositor/gl_inc.h b/src/compositor/gl_inc.h index 2e54ef6..eff9b43 100644 --- a/src/compositor/gl_inc.h +++ b/src/compositor/gl_inc.h @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -30,30 +30,42 @@ #endif #ifndef GPAC_DISABLE_3D +#include <gpac/internal/compositor_dev.h> #ifdef GPAC_USE_OGL_ES #ifndef GPAC_FIXED_POINT #error "OpenGL ES defined without fixed-point support - unsupported." #endif -#include "GLES/egl.h" +#ifdef ANDROID +#include "GLES/gl.h" #else +#include "GLES/egl.h" +#endif +#ifdef GPAC_HAS_GLU +/*WARNING - this is NOT a standard include, GLU is not supported by GLES*/ +#include <GLES/glu.h> +#endif + +#elif defined (CONFIG_DARWIN_GL) + +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> -#ifndef GPAC_USE_TINYGL -#include <GL/gl.h> #else -#include "../../../TinyGL/include/GL/gl.h" -#endif +#include <GL/gl.h> + #ifdef GPAC_HAS_GLU #include <GL/glu.h> #endif #endif + /*redefine all ext needed*/ /*BGRA pixel format*/ @@ -87,6 +99,10 @@ #define UNSIGNED_SHORT_8_8_REV_MESA 0x85BB /* same as Apple's */ #endif +/* for triscope - not conformant*/ +#ifndef GL_RGBDS +#define GL_RGBDS 0x1910 +#endif #ifndef GL_TEXTURE0_ARB @@ -164,9 +180,15 @@ #define GL_OPERAND0_ALPHA_EXT 0x8598 #define GL_OPERAND1_ALPHA_EXT 0x8599 #define GL_OPERAND2_ALPHA_EXT 0x859A + +#endif + +#ifndef GL_LOGIC_OP #define GL_LOGIC_OP GL_INDEX_LOGIC_OP -#define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT +#endif +#ifndef GL_TEXTURE_COMPONENTS +#define GL_TEXTURE_COMPONENTS GL_TEXTURE_INTERNAL_FORMAT #endif #ifndef COMBINE_RGB_ARB @@ -186,10 +208,16 @@ #define GL_ADD_SIGNED_ARB 0x8574 #define GL_SUBTRACT_ARB 0x84E7 #define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE2_ALPHA_ARB 0x858A +#define GL_SOURCE1_ALPHA_ARB 0x8589 +#define GL_SOURCE2_ALPHA_ARB 0x858A #endif +#ifndef GL_NV_texture_rectangle +#define GL_TEXTURE_RECTANGLE_NV 0x84F5 +#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 +#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 +#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 +#endif #endif /*GPAC_DISABLE_3D*/ diff --git a/src/compositor/hardcoded_protos.c b/src/compositor/hardcoded_protos.c index ddb1ac0..5461520 100644 --- a/src/compositor/hardcoded_protos.c +++ b/src/compositor/hardcoded_protos.c @@ -28,6 +28,8 @@ #include "offscreen_cache.h" #include "mpeg4_grouping.h" +#ifndef GPAC_DISABLE_VRML + #ifndef GPAC_DISABLE_3D /*PathExtrusion hardcoded proto*/ @@ -440,6 +442,7 @@ void compositor_init_plane_clipper(GF_Compositor *compositor, GF_Node *node) gf_node_dirty_set(node, GF_SG_CHILD_DIRTY, 0); stack->pc = pc; + gf_node_proto_set_grouping(node); } } @@ -452,13 +455,13 @@ typedef struct BASE_NODE CHILDREN - Bool offscreen; + Bool offscreen; Fixed opacity; } OffscreenGroup; typedef struct { - GROUPING_NODE_STACK_2D + GROUPING_MPEG4_STACK_2D #ifndef GF_SR_USE_VIDEO_CACHE struct _group_cache *cache; @@ -495,7 +498,7 @@ static void TraverseOffscreenGroup(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { if (stack->cache) group_cache_del(stack->cache); - free(stack); + gf_free(stack); return; } @@ -519,8 +522,21 @@ static void TraverseOffscreenGroup(GF_Node *node, void *rs, Bool is_destroy) /*flag is not set for PROTO*/ gf_node_dirty_set(node, GF_SG_CHILD_DIRTY, 0); } + if (stack->cache) { + group_cache_traverse((GF_Node *)&stack->og, stack->cache, tr_state, stack->cache->force_recompute, 1); + gf_node_dirty_clear(node, GF_SG_CHILD_DIRTY); + } else { + group_2d_traverse((GF_Node *)&stack->og, (GroupingNode2D*)stack, tr_state); + } + } + /*draw mode*/ + else if (stack->cache && (tr_state->traversing_mode == TRAVERSE_DRAW_2D)) { + /*draw it*/ + group_cache_draw(stack->cache, tr_state); + gf_node_dirty_clear(node, GF_SG_CHILD_DIRTY); + } else { + group_2d_traverse((GF_Node *)&stack->og, (GroupingNode2D*)stack, tr_state); } - group_2d_traverse((GF_Node *)&stack->og, (GroupingNode2D*)stack, tr_state); } void compositor_init_offscreen_group(GF_Compositor *compositor, GF_Node *node) @@ -533,6 +549,7 @@ void compositor_init_offscreen_group(GF_Compositor *compositor, GF_Node *node) gf_node_set_callback_function(node, TraverseOffscreenGroup); stack->og = og; if (og.offscreen) stack->flags |= GROUP_IS_CACHED; + gf_node_proto_set_grouping(node); } } @@ -543,12 +560,13 @@ typedef struct BASE_NODE CHILDREN - Fixed depth; + Fixed depth_gain, depth_offset; + } DepthGroup; typedef struct { - GROUPING_NODE_STACK_2D + GROUPING_MPEG4_STACK_2D DepthGroup dg; } DepthGroupStack; @@ -563,36 +581,88 @@ static Bool DepthGroup_GetNode(GF_Node *node, DepthGroup *dg) dg->children = *(GF_ChildNodeItem **) field.far_ptr; if (gf_node_get_field(node, 1, &field) != GF_OK) return 0; + if (field.fieldType != GF_SG_VRML_SFINT32) return 0; + + if (gf_node_get_field(node, 2, &field) != GF_OK) return 0; if (field.fieldType != GF_SG_VRML_SFFLOAT) return 0; - dg->depth = * (SFFloat *) field.far_ptr; + dg->depth_gain = * (SFFloat *) field.far_ptr; + + if (gf_node_get_field(node, 3, &field) != GF_OK) return 0; + if (field.fieldType != GF_SG_VRML_SFFLOAT) return 0; + dg->depth_offset = * (SFFloat *) field.far_ptr; + return 1; } static void TraverseDepthGroup(GF_Node *node, void *rs, Bool is_destroy) { - Fixed depth; +#ifdef GF_SR_USE_DEPTH + Fixed depth_gain, depth_offset; +#endif + DepthGroupStack *stack = (DepthGroupStack *)gf_node_get_private(node); GF_TraverseState *tr_state = (GF_TraverseState *) rs; if (is_destroy) { - free(stack); + gf_free(stack); return; } if (tr_state->traversing_mode==TRAVERSE_SORT) { if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { - //DepthGroup_GetNode(node, &stack->dg); /*lets place it below*/ + gf_node_dirty_clear(node, GF_SG_NODE_DIRTY); /*flag is not set for PROTO*/ gf_node_dirty_set(node, GF_SG_CHILD_DIRTY, 0); } } DepthGroup_GetNode(node, &stack->dg); - depth = tr_state->depth; - tr_state->depth += stack->dg.depth; - group_2d_traverse((GF_Node *)&stack->dg, (GroupingNode2D*)stack, tr_state); - tr_state->depth = depth; + + +#ifdef GF_SR_USE_DEPTH + depth_gain = tr_state->depth_gain; + depth_offset = tr_state->depth_offset; + + // new offset is multiplied by parent gain and added to parent offset + tr_state->depth_offset = gf_mulfix(stack->dg.depth_offset, tr_state->depth_gain) + tr_state->depth_offset; + + // gain is multiplied by parent gain + tr_state->depth_gain = gf_mulfix(tr_state->depth_gain, stack->dg.depth_gain); +#endif + +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->type_3d) { + GF_Matrix mx_bckup, mx; + + gf_mx_copy(mx_bckup, tr_state->model_matrix); + gf_mx_init(mx); + mx.m[14] = stack->dg.depth_offset; + gf_mx_add_matrix(&tr_state->model_matrix, &mx); + + if (tr_state->traversing_mode == TRAVERSE_SORT) { + visual_3d_matrix_push(tr_state->visual); + visual_3d_matrix_add(tr_state->visual, mx.m); + + group_2d_traverse((GF_Node *)&stack->dg, (GroupingNode2D*)stack, tr_state); + + visual_3d_matrix_pop(tr_state->visual); + } else { + group_2d_traverse((GF_Node *)&stack->dg, (GroupingNode2D*)stack, tr_state); + } + gf_mx_copy(tr_state->model_matrix, mx_bckup); + + } else +#endif + { + + group_2d_traverse((GF_Node *)&stack->dg, (GroupingNode2D*)stack, tr_state); + } + +#ifdef GF_SR_USE_DEPTH + tr_state->depth_gain = depth_gain; + tr_state->depth_offset = depth_offset; +#endif } void compositor_init_depth_group(GF_Compositor *compositor, GF_Node *node) @@ -604,12 +674,53 @@ void compositor_init_depth_group(GF_Compositor *compositor, GF_Node *node) gf_node_set_private(node, stack); gf_node_set_callback_function(node, TraverseDepthGroup); stack->dg = dg; - } + gf_node_proto_set_grouping(node); + } else GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Compositor2D] Unable to initialize depth group \n")); + } +#ifdef GF_SR_USE_DEPTH +static void TraverseDepthViewPoint(GF_Node *node, void *rs, Bool is_destroy) +{ + if (!is_destroy && gf_node_dirty_get(node)) { + GF_TraverseState *tr_state = (GF_TraverseState *) rs; + GF_FieldInfo field; + gf_node_dirty_clear(node, 0); + tr_state->visual->depth_vp_position = 0; + tr_state->visual->depth_vp_range = 0; +#ifndef GPAC_DISABLE_3D + if (!tr_state->camera) return; + tr_state->camera->flags |= CAM_IS_DIRTY; +#endif -/*PathExtrusion hardcoded proto*/ + if (gf_node_get_field(node, 0, &field) != GF_OK) return; + if (field.fieldType != GF_SG_VRML_SFBOOL) return; + + if ( *(SFBool *) field.far_ptr) { + if (gf_node_get_field(node, 1, &field) != GF_OK) return; + if (field.fieldType != GF_SG_VRML_SFFLOAT) return; + tr_state->visual->depth_vp_position = *(SFFloat *) field.far_ptr; + if (gf_node_get_field(node, 2, &field) != GF_OK) return; + if (field.fieldType != GF_SG_VRML_SFFLOAT) return; + tr_state->visual->depth_vp_range = *(SFFloat *) field.far_ptr; + } +#ifndef GPAC_DISABLE_3D + if (tr_state->layer3d) gf_node_dirty_set(tr_state->layer3d, GF_SG_NODE_DIRTY, 0); +#endif + gf_sc_invalidate(tr_state->visual->compositor, NULL); + } +} +#endif + +static void compositor_init_depth_viewpoint(GF_Compositor *compositor, GF_Node *node) +{ +#ifdef GF_SR_USE_DEPTH + gf_node_set_callback_function(node, TraverseDepthViewPoint); +#endif +} + +/*IndexedCurve2D hardcoded proto*/ typedef struct { @@ -677,7 +788,7 @@ static void TraverseIndexedCurve2D(GF_Node *node, void *rs, Bool is_destroy) return; #endif case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_GET_BOUNDS: gf_path_get_bounds(stack->path, &tr_state->bounds); @@ -700,6 +811,144 @@ static void compositor_init_idx_curve2d(GF_Compositor *compositor, GF_Node *node } + + + +/*TransformRef hardcoded proto*/ +typedef struct +{ + BASE_NODE + CHILDREN +} Untransform; + +typedef struct +{ + GROUPING_MPEG4_STACK_2D + Untransform untr; +} UntransformStack; + +static Bool Untransform_GetNode(GF_Node *node, Untransform *tr) +{ + GF_FieldInfo field; + memset(tr, 0, sizeof(Untransform)); + tr->sgprivate = node->sgprivate; + + if (gf_node_get_field(node, 0, &field) != GF_OK) return 0; + if (field.fieldType != GF_SG_VRML_MFNODE) return 0; + tr->children = *(GF_ChildNodeItem **) field.far_ptr; + + return 1; +} + + +static void TraverseUntransform(GF_Node *node, void *rs, Bool is_destroy) +{ + UntransformStack *stack = (UntransformStack *)gf_node_get_private(node); + GF_TraverseState *tr_state = (GF_TraverseState *) rs; + + if (is_destroy) { + gf_free(stack); + return; + } + + if (tr_state->traversing_mode==TRAVERSE_SORT) { + if (gf_node_dirty_get(node)) { + Untransform_GetNode(node, &stack->untr); /*lets place it below*/ + gf_node_dirty_clear(node, GF_SG_NODE_DIRTY); + } + } + +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->type_3d) { + GF_Matrix mx_model; + GF_Camera backup_cam; + + gf_mx_copy(mx_model, tr_state->model_matrix); + gf_mx_init(tr_state->model_matrix); + + memcpy(&backup_cam, tr_state->camera, sizeof(GF_Camera)); + + + camera_invalidate(tr_state->camera); + tr_state->camera->is_3D=0; + camera_update(tr_state->camera, NULL, 1); + + + if (tr_state->traversing_mode == TRAVERSE_SORT) { + visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_PROJECTION); + visual_3d_matrix_load(tr_state->visual, tr_state->camera->projection.m); + visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_MODELVIEW); + visual_3d_matrix_load(tr_state->visual, tr_state->camera->modelview.m); + + visual_3d_set_viewport(tr_state->visual, tr_state->camera->vp); + + gf_node_traverse_children((GF_Node *)&stack->untr, tr_state); + + gf_mx_copy(tr_state->model_matrix, mx_model); + memcpy(tr_state->camera, &backup_cam, sizeof(GF_Camera)); + + visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_PROJECTION); + visual_3d_matrix_load(tr_state->visual, tr_state->camera->projection.m); + visual_3d_set_matrix_mode(tr_state->visual, V3D_MATRIX_MODELVIEW); + visual_3d_matrix_load(tr_state->visual, tr_state->camera->modelview.m); + + visual_3d_set_viewport(tr_state->visual, tr_state->camera->vp); + } else if (tr_state->traversing_mode == TRAVERSE_PICK) { + Fixed prev_dist = tr_state->visual->compositor->hit_square_dist; + GF_Ray r = tr_state->ray; + tr_state->ray.orig.x = INT2FIX(tr_state->pick_x); + tr_state->ray.orig.y = INT2FIX(tr_state->pick_y); + tr_state->ray.orig.z = 0; + tr_state->ray.dir.x = 0; + tr_state->ray.dir.y = 0; + tr_state->ray.dir.z = -FIX_ONE; + tr_state->visual->compositor->hit_square_dist=0; + + gf_node_traverse_children((GF_Node *)&stack->untr, tr_state); + + gf_mx_copy(tr_state->model_matrix, mx_model); + memcpy(tr_state->camera, &backup_cam, sizeof(GF_Camera)); + tr_state->ray = r; + + /*nothing picked, restore previous pick*/ + if (!tr_state->visual->compositor->hit_square_dist) + tr_state->visual->compositor->hit_square_dist = prev_dist; + + } else { + gf_node_traverse_children((GF_Node *)&stack->untr, tr_state); + + gf_mx_copy(tr_state->model_matrix, mx_model); + memcpy(tr_state->camera, &backup_cam, sizeof(GF_Camera)); + } + + } else +#endif + { + GF_Matrix2D mx2d_backup; + gf_mx2d_copy(mx2d_backup, tr_state->transform); + gf_mx2d_init(tr_state->transform); + + group_2d_traverse((GF_Node *)&stack->untr, (GroupingNode2D *)stack, tr_state); + + gf_mx2d_copy(tr_state->transform, mx2d_backup); + + + } +} + +void compositor_init_untransform(GF_Compositor *compositor, GF_Node *node) +{ + Untransform tr; + if (Untransform_GetNode(node, &tr)) { + UntransformStack *stack; + GF_SAFEALLOC(stack, UntransformStack); + gf_node_set_private(node, stack); + gf_node_set_callback_function(node, TraverseUntransform); + stack->untr = tr; + gf_node_proto_set_grouping(node); + } +} + /*hardcoded proto loading - this is mainly used for module development and testing...*/ void compositor_init_hardcoded_proto(GF_Compositor *compositor, GF_Node *node) { @@ -739,11 +988,24 @@ void compositor_init_hardcoded_proto(GF_Compositor *compositor, GF_Node *node) compositor_init_depth_group(compositor, node); return; } + if (!strcmp(url, "urn:inet:gpac:builtin:DepthViewPoint")) { + compositor_init_depth_viewpoint(compositor, node); + return; + } if (!strcmp(url, "urn:inet:gpac:builtin:IndexedCurve2D")) { compositor_init_idx_curve2d(compositor, node); return; } + if (!strcmp(url, "urn:inet:gpac:builtin:Untransform")) { + compositor_init_untransform(compositor, node); + return; + } + if (!strcmp(url, "urn:inet:gpac:builtin:FlashShape")) { + compositor_init_hc_flashshape(compositor, node); + return; + } } } +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/hc_flash_shape.c b/src/compositor/hc_flash_shape.c new file mode 100644 index 0000000..09e0a1d --- /dev/null +++ b/src/compositor/hc_flash_shape.c @@ -0,0 +1,466 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * All rights reserved + * + * This file is part of GPAC / Scene Compositor 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 "nodes_stacks.h" + +#include "visual_manager.h" + +#ifndef GPAC_DISABLE_3D +#include <gpac/internal/mesh.h> +#endif + +typedef struct +{ + GF_Path *path; + Fixed width; + u32 fill_col, line_col; +#ifndef GPAC_DISABLE_3D + GF_Mesh *mesh; +#endif +} FSItem; + + +typedef struct +{ + GF_Compositor *compositor; + Drawable *drawable; + GF_Rect bounds; + GF_List *items; + Fixed max_width; +} FSStack; + + +static void clean_paths(FSStack *stack) +{ + /*delete all path objects*/ + while (gf_list_count(stack->items)) { + FSItem *it = gf_list_get(stack->items, 0); + gf_list_rem(stack->items, 0); + if (it->path) gf_path_del(it->path); +#ifndef GPAC_DISABLE_3D + if (it->mesh) mesh_free(it->mesh); +#endif + gf_free(it); + } +} + +static FSItem *new_fs_item(FSStack *st, u32 line_col, u32 fill_col, Fixed width) +{ + FSItem *item; + GF_SAFEALLOC(item, FSItem); + gf_list_add(st->items, item); + item->fill_col = fill_col; + item->width = width; + item->line_col = line_col; + item->path = gf_path_new(); + return item; +} + +#define SFCOL_MAKE_ARGB(c) GF_COL_ARGB_FIXED(FIX_ONE, c.red, c.green, c.blue); + +static void build_shape(FSStack *st, GF_Node *node) +{ + GF_FieldInfo field; + MFVec2f *coords; + MFInt32 *com, *widthIndex, *lineIndex, *fillIndex, *coordIndex; + MFFloat *widths; + MFColor *colors; + u32 wi, li, fi, ci, command, i, has_ci; + FSItem *fill_item, *line_item; + Fixed w; + SFVec2f cur, pt, ct1, ct2, *pts; + GF_Rect rc; + u32 line_col, fill_col; + Bool need_line, need_fill; + + /*get all fields*/ + gf_node_get_field(node, 0, &field); + coords = field.far_ptr; + gf_node_get_field(node, 1, &field); + com = field.far_ptr; + gf_node_get_field(node, 2, &field); + widths = field.far_ptr; + gf_node_get_field(node, 3, &field); + colors = field.far_ptr; + gf_node_get_field(node, 4, &field); + widthIndex = field.far_ptr; + gf_node_get_field(node, 5, &field); + lineIndex = field.far_ptr; + gf_node_get_field(node, 6, &field); + fillIndex = field.far_ptr; + gf_node_get_field(node, 7, &field); + coordIndex = field.far_ptr; + + wi = li = fi = ci = 0; + w = 0; + + st->max_width = 0; + cur.x = cur.y = 0; + fill_item = line_item = NULL; + need_line = need_fill = 0; + cur.x = cur.y = 0; + has_ci = coordIndex->count ? 1 : 0; + pts = coords->vals; + line_col = fill_col = 0; + + /*implicit commands: 0 1 2 3*/ + +/* + if (widthIndex->count) { + w = (widthIndex->vals[wi]==-1) ? 0 : widths->vals[widthIndex->vals[wi]]; + if (!w) { + need_line = 0; + line_item = NULL; + } else { + need_line = 1; + if (st->max_width<w) st->max_width = w; + } + wi++; + } + if (lineIndex->count) { + if (w) { + line_col = SFCOL_MAKE_ARGB(colors->vals[lineIndex->vals[li]]); + need_line = 1; + } + li++; + } + if (fillIndex->count) { + if (fillIndex->vals[fi]==-1) { + fill_col = 0; + fill_item = NULL; + } else { + fill_col = SFCOL_MAKE_ARGB(colors->vals[fillIndex->vals[fi]]); + need_fill = 1; + } + fi++; + } + if (!coordIndex->count) return; + cur = coords->vals[coordIndex->vals[ci]]; + ci++; +*/ + + for (command=0; command<com->count; command++) { + switch (com->vals[command]) { + /*set line width*/ + case 0: + if (wi >= widthIndex->count) return; + w = (widthIndex->vals[wi]==-1) ? 0 : widths->vals[widthIndex->vals[wi]]; + if (!w) + line_item = NULL; + else { + need_line = 1; + if (st->max_width<w) st->max_width = w; + } + wi++; + break; + /*set line color*/ + case 1: + if (li > lineIndex->count) return; + if (w) { + line_col = SFCOL_MAKE_ARGB(colors->vals[lineIndex->vals[li]]); + need_line = 1; + } + li++; + break; + /*set fill color*/ + case 2: + if (fi >= fillIndex->count) return; + if (fillIndex->vals[fi]==-1) { + fill_col = 0; + fill_item = NULL; + } else { + fill_col = SFCOL_MAKE_ARGB(colors->vals[fillIndex->vals[fi]]); + need_fill = 1; + } + fi++; + break; + /*moveTo*/ + case 3: + if ((has_ci && ci >= coordIndex->count) || (!has_ci && ci >= coords->count) ) return; + if (need_fill) { + fill_item = new_fs_item(st, 0, fill_col, 0); + need_fill = 0; + } + if (need_line) { + line_item = new_fs_item(st, line_col, 0, w); + need_line = 0; + } + if (has_ci) { + pt = pts[coordIndex->vals[ci]]; + } else { + pt = pts[ci]; + } + if (fill_item) gf_path_add_move_to(fill_item->path, pt.x, pt.y); + if (line_item) gf_path_add_move_to(line_item->path, pt.x, pt.y); + ct1 = pt; + cur = pt; + ci++; + break; + /*lineTo*/ + case 4: + if ((has_ci && ci >= coordIndex->count) || (!has_ci && ci >= coords->count) ) return; + if (need_fill) { + fill_item = new_fs_item(st, 0, fill_col, 0); + gf_path_add_move_to(fill_item->path, cur.x, cur.y); + need_fill = 0; + } + if (need_line) { + line_item = new_fs_item(st, line_col, 0, w); + gf_path_add_move_to(line_item->path, cur.x, cur.y); + need_line = 0; + } + if (has_ci) { + pt = pts[coordIndex->vals[ci]]; + } else { + pt = pts[ci]; + } + if (fill_item) gf_path_add_line_to(fill_item->path, pt.x, pt.y); + if (line_item) gf_path_add_line_to(line_item->path, pt.x, pt.y); + cur = pt; + ci++; + break; + /*cubic curveTo*/ + case 5: + if ((has_ci && ci + 2 >= coordIndex->count) || (!has_ci && ci + 2>= coords->count) ) return; + if (need_fill) { + fill_item = new_fs_item(st, 0, fill_col, 0); + gf_path_add_move_to(fill_item->path, cur.x, cur.y); + need_fill = 0; + } + if (need_line) { + line_item = new_fs_item(st, line_col, 0, w); + gf_path_add_move_to(line_item->path, cur.x, cur.y); + need_line = 0; + } + if (has_ci) { + ct1 = pts[coordIndex->vals[ci]]; + ct2 = pts[coordIndex->vals[ci+1]]; + pt = pts[coordIndex->vals[ci+2]]; + } else { + ct1 = pts[ci]; + ct2 = pts[ci+1]; + pt = pts[ci+2]; + } + if (fill_item) gf_path_add_cubic_to(fill_item->path, ct1.x, ct1.y, ct2.x, ct2.y, pt.x, pt.y); + if (line_item) gf_path_add_cubic_to(line_item->path, ct1.x, ct1.y, ct2.x, ct2.y, pt.x, pt.y); + ct1 = ct2; + cur = pt; + ci += 3; + break; + /*cubic nextCurveTo*/ + case 6: + if ((has_ci && ci + 1 >= coordIndex->count) || (!has_ci && ci + 1>= coords->count) ) return; + if (need_fill) { + fill_item = new_fs_item(st, 0, fill_col, 0); + gf_path_add_move_to(fill_item->path, cur.x, cur.y); + need_fill = 0; + } + if (need_line) { + line_item = new_fs_item(st, line_col, 0, w); + gf_path_add_move_to(line_item->path, cur.x, cur.y); + need_line = 0; + } + ct1.x = 2*cur.x - ct1.x; + ct1.y = 2*cur.y - ct1.y; + if (has_ci) { + ct2 = pts[coordIndex->vals[ci]]; + pt = pts[coordIndex->vals[ci+1]]; + } else { + ct2 = pts[ci]; + pt = pts[ci+1]; + } + if (fill_item) gf_path_add_cubic_to(fill_item->path, ct1.x, ct1.y, ct2.x, ct2.y, pt.x, pt.y); + if (line_item) gf_path_add_cubic_to(line_item->path, ct1.x, ct1.y, ct2.x, ct2.y, pt.x, pt.y); + ct1 = ct2; + cur = pt; + ci += 2; + break; + /*quadratic CurveTo*/ + case 7: + if ((has_ci && ci + 1 >= coordIndex->count) || (!has_ci && ci + 1>= coords->count) ) return; + if (need_fill) { + fill_item = new_fs_item(st, 0, fill_col, 0); + gf_path_add_move_to(fill_item->path, cur.x, cur.y); + need_fill = 0; + } + if (need_line) { + line_item = new_fs_item(st, line_col, 0, w); + gf_path_add_move_to(line_item->path, cur.x, cur.y); + need_line = 0; + } + if (has_ci) { + ct1 = pts[coordIndex->vals[ci]]; + pt = pts[coordIndex->vals[ci+1]]; + } else { + ct1 = pts[ci]; + pt = pts[ci+1]; + } + if (fill_item) gf_path_add_quadratic_to(fill_item->path, ct1.x, ct1.y, pt.x, pt.y); + if (line_item) gf_path_add_quadratic_to(line_item->path, ct1.x, ct1.y, pt.x, pt.y); + cur = pt; + ci += 2; + break; + /*quadratic nextCurveTo*/ + case 8: + if ((has_ci && ci >= coordIndex->count) || (!has_ci && ci >= coords->count) ) return; + if (need_fill) { + fill_item = new_fs_item(st, 0, fill_col, 0); + gf_path_add_move_to(fill_item->path, cur.x, cur.y); + need_fill = 0; + } + if (need_line) { + line_item = new_fs_item(st, line_col, 0, w); + gf_path_add_move_to(line_item->path, cur.x, cur.y); + need_line = 0; + } + ct1.x = 2*cur.x - ct1.x; + ct1.y = 2*cur.y - ct1.y; + if (has_ci) { + pt = pts[coordIndex->vals[ci]]; + } else { + pt = pts[ci]; + } + if (fill_item) gf_path_add_quadratic_to(fill_item->path, ct1.x, ct1.y, pt.x, pt.y); + if (line_item) gf_path_add_quadratic_to(line_item->path, ct1.x, ct1.y, pt.x, pt.y); + cur = pt; + ci += 2; + break; + /*close*/ + case 9: + if (fill_item) gf_path_close(fill_item->path); + if (line_item) gf_path_close(line_item->path); + break; + } + } + + /*compute bounds*/ + st->bounds.width = st->bounds.height = 0; + for (i=0; i<gf_list_count(st->items); i++) { + line_item = gf_list_get(st->items, i); + gf_path_get_bounds(line_item->path, &rc); + gf_rect_union(&st->bounds, &rc); + } +} + +static void fs_traverse(GF_Node *node, void *rs, Bool is_destroy) +{ + u32 i; + DrawableContext *ctx; + FSStack *st = (FSStack *) gf_node_get_private(node); + GF_TraverseState *tr_state = (GF_TraverseState*)rs; + + if (is_destroy) { + clean_paths(st); + drawable_del(st->drawable); + gf_list_del(st->items); + gf_free(st); + return; + } + /*check for geometry change*/ + if (gf_node_dirty_get(node)) { + gf_node_dirty_clear(node, 0); + /*build*/ + clean_paths(st); + build_shape(st, node); + } + + switch (tr_state->traversing_mode) { + case TRAVERSE_DRAW_2D: + ctx = tr_state->ctx; + for (i=0; i<gf_list_count(st->items); i++) { + FSItem *item = gf_list_get(st->items, i); + ctx->flags &= ~(CTX_PATH_FILLED | CTX_PATH_STROKE); + memset(&ctx->aspect, 0, sizeof(DrawAspect2D)); + if (item->fill_col) { + ctx->aspect.fill_color = item->fill_col; + } + if (item->width) { + ctx->aspect.line_color = item->line_col; + ctx->aspect.pen_props.width = item->width; + } + visual_2d_draw_path(tr_state->visual, item->path, ctx, NULL, NULL, tr_state); + } + return; + +#ifndef GPAC_DISABLE_3D + case TRAVERSE_DRAW_3D: + ctx = tr_state->ctx; + for (i=0; i<gf_list_count(st->items); i++) { + FSItem *item = gf_list_get(st->items, i); + memset(&ctx->aspect, 0, sizeof(DrawAspect2D)); + if (item->fill_col) { + ctx->aspect.fill_color = item->fill_col; + } + if (item->width) { + ctx->aspect.line_color = item->line_col; + ctx->aspect.pen_props.width = item->width; + } + if (!item->mesh) { + item->mesh = new_mesh(); + mesh_from_path(item->mesh, item->path); + } + st->drawable->mesh = item->mesh; + visual_3d_draw_2d_with_aspect(st->drawable, tr_state, &ctx->aspect); + st->drawable->mesh = NULL; + } + return; +#endif + case TRAVERSE_PICK: + /*todo*/ + return; + case TRAVERSE_GET_BOUNDS: + tr_state->bounds = st->bounds; + return; + case TRAVERSE_SORT: +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->type_3d) return; +#endif + /*finalize*/ + ctx = drawable_init_context_mpeg4(st->drawable, tr_state); + if (!ctx) return; + + /*force width to max width used for clipper compute*/ + if (st->max_width) { + ctx->aspect.pen_props.width = st->max_width; + } + drawable_finalize_sort(ctx, tr_state, &st->bounds); + break; + } +} + + +void compositor_init_hc_flashshape(GF_Compositor *compositor, GF_Node *node) +{ + FSStack *stack; + + GF_SAFEALLOC(stack, FSStack); + stack->drawable = drawable_new(); + stack->drawable->node = node; + stack->drawable->flags = DRAWABLE_USE_TRAVERSE_DRAW; + stack->items = gf_list_new(); + + gf_node_set_private(node, stack); + gf_node_set_callback_function(node, fs_traverse); +} + diff --git a/src/compositor/mesh.c b/src/compositor/mesh.c index f8cf13f..4776380 100644 --- a/src/compositor/mesh.c +++ b/src/compositor/mesh.c @@ -29,6 +29,8 @@ #include <gpac/color.h> #ifndef GPAC_DISABLE_3D + + /*for GPAC_HAS_GLU*/ #include "gl_inc.h" @@ -36,19 +38,19 @@ #define HIGH_SPEED_RATIO 2 -/*size alloc for meshes doubles memory at each realloc rather than using a fix-size increment +/*size alloc for meshes doubles memory at each gf_realloc rather than using a fix-size increment (this really speeds up large meshes constructing). Final memory usage is adjusted when updating mesh bounds */ #define MESH_CHECK_VERTEX(m) \ if (m->v_count == m->v_alloc) { \ m->v_alloc *= 2; \ - m->vertices = (GF_Vertex *)realloc(m->vertices, sizeof(GF_Vertex)*m->v_alloc); \ + m->vertices = (GF_Vertex *)gf_realloc(m->vertices, sizeof(GF_Vertex)*m->v_alloc); \ } \ #define MESH_CHECK_IDX(m) \ if (m->i_count == m->i_alloc) { \ m->i_alloc *= 2; \ - m->indices = (IDX_TYPE*)realloc(m->indices, sizeof(IDX_TYPE)*m->i_alloc); \ + m->indices = (IDX_TYPE*)gf_realloc(m->indices, sizeof(IDX_TYPE)*m->i_alloc); \ } \ @@ -57,7 +59,7 @@ static void del_aabb_node(AABBNode *node) { if (node->pos) del_aabb_node(node->pos); if (node->neg) del_aabb_node(node->neg); - free(node); + gf_free(node); } void mesh_reset(GF_Mesh *mesh) @@ -70,29 +72,29 @@ void mesh_reset(GF_Mesh *mesh) memset(&mesh->bounds.max_edge, 0, sizeof(SFVec3f)); if (mesh->aabb_root) del_aabb_node(mesh->aabb_root); mesh->aabb_root = NULL; - if (mesh->aabb_indices) free(mesh->aabb_indices); + if (mesh->aabb_indices) gf_free(mesh->aabb_indices); mesh->aabb_indices = NULL; } void mesh_free(GF_Mesh *mesh) { - if (mesh->vertices) free(mesh->vertices); - if (mesh->indices) free(mesh->indices); + if (mesh->vertices) gf_free(mesh->vertices); + if (mesh->indices) gf_free(mesh->indices); if (mesh->aabb_root) del_aabb_node(mesh->aabb_root); mesh->aabb_root = NULL; - if (mesh->aabb_indices) free(mesh->aabb_indices); - free(mesh); + if (mesh->aabb_indices) gf_free(mesh->aabb_indices); + gf_free(mesh); } GF_Mesh *new_mesh() { - GF_Mesh *mesh = (GF_Mesh *)malloc(sizeof(GF_Mesh)); + GF_Mesh *mesh = (GF_Mesh *)gf_malloc(sizeof(GF_Mesh)); if (mesh) { memset(mesh, 0, sizeof(GF_Mesh)); mesh->v_alloc = 8; - mesh->vertices = (GF_Vertex*)malloc(sizeof(GF_Vertex)*mesh->v_alloc); + mesh->vertices = (GF_Vertex*)gf_malloc(sizeof(GF_Vertex)*mesh->v_alloc); mesh->i_alloc = 8; - mesh->indices = (IDX_TYPE*)malloc(sizeof(IDX_TYPE)*mesh->i_alloc); + mesh->indices = (IDX_TYPE*)gf_malloc(sizeof(IDX_TYPE)*mesh->i_alloc); } return mesh; } @@ -101,11 +103,11 @@ static void mesh_fit_alloc(GF_Mesh *m) { if (m->v_count && (m->v_count < m->v_alloc)) { m->v_alloc = m->v_count; - m->vertices = (GF_Vertex *)realloc(m->vertices, sizeof(GF_Vertex)*m->v_alloc); + m->vertices = (GF_Vertex *)gf_realloc(m->vertices, sizeof(GF_Vertex)*m->v_alloc); } if (m->i_count && (m->i_count < m->i_alloc)) { m->i_alloc = m->i_count; - m->indices = (IDX_TYPE*)realloc(m->indices, sizeof(IDX_TYPE)*m->i_alloc); + m->indices = (IDX_TYPE*)gf_realloc(m->indices, sizeof(IDX_TYPE)*m->i_alloc); } } @@ -137,14 +139,14 @@ void mesh_clone(GF_Mesh *dest, GF_Mesh *orig) { if (dest->v_alloc<orig->v_alloc) { dest->v_alloc = orig->v_alloc; - dest->vertices = (GF_Vertex *)realloc(dest->vertices, sizeof(GF_Vertex)*dest->v_alloc); + dest->vertices = (GF_Vertex *)gf_realloc(dest->vertices, sizeof(GF_Vertex)*dest->v_alloc); } dest->v_count = orig->v_count; memcpy(dest->vertices, orig->vertices, sizeof(GF_Vertex)*dest->v_count); if (dest->i_alloc < orig->i_alloc) { dest->i_alloc = orig->i_alloc; - dest->indices = (IDX_TYPE*)realloc(dest->indices, sizeof(IDX_TYPE)*dest->i_alloc); + dest->indices = (IDX_TYPE*)gf_realloc(dest->indices, sizeof(IDX_TYPE)*dest->i_alloc); } dest->i_count = orig->i_count; memcpy(dest->indices, orig->indices, sizeof(IDX_TYPE)*dest->i_count); @@ -155,7 +157,7 @@ void mesh_clone(GF_Mesh *dest, GF_Mesh *orig) /*and reset AABB*/ if (dest->aabb_root) del_aabb_node(dest->aabb_root); dest->aabb_root = NULL; - if (dest->aabb_indices) free(dest->aabb_indices); + if (dest->aabb_indices) gf_free(dest->aabb_indices); dest->aabb_indices = NULL; } @@ -247,6 +249,7 @@ void mesh_recompute_normals(GF_Mesh *mesh) } } +#ifndef GPAC_DISABLE_VRML void mesh_generate_tex_coords(GF_Mesh *mesh, GF_Node *__texCoords) { u32 i; @@ -267,6 +270,7 @@ void mesh_generate_tex_coords(GF_Mesh *mesh, GF_Node *__texCoords) } } } +#endif /*GPAC_DISABLE_VRML*/ void mesh_new_box(GF_Mesh *mesh, SFVec3f size) @@ -377,8 +381,8 @@ void mesh_new_cylinder(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, B nfacets = CYLINDER_SUBDIV; if (low_res) nfacets /= HIGH_SPEED_RATIO; - coords = (SFVec3f*) malloc(sizeof(SFVec3f) * nfacets); - texcoords = (SFVec2f*)malloc(sizeof(SFVec2f) * nfacets); + coords = (SFVec3f*) gf_malloc(sizeof(SFVec3f) * nfacets); + texcoords = (SFVec2f*)gf_malloc(sizeof(SFVec2f) * nfacets); compute_cylinder(height, radius, nfacets, coords, texcoords); @@ -453,8 +457,8 @@ void mesh_new_cylinder(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, B (FIX_ONE + gf_sin(angle))/2, FIX_ONE - (FIX_ONE + gf_cos(angle))/2); mesh_set_triangle(mesh, c_idx, mesh->v_count-2, mesh->v_count-1); } - free(texcoords); - free(coords); + gf_free(texcoords); + gf_free(coords); if (top && bottom && side) mesh->flags |= MESH_IS_SOLID; @@ -479,8 +483,8 @@ void mesh_new_cone(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, Bool nfacets = CONE_SUBDIV; if (low_res) nfacets /= HIGH_SPEED_RATIO; - coords = (SFVec3f*)malloc(sizeof(SFVec3f) * nfacets); - texcoords = (SFVec2f*)malloc(sizeof(SFVec2f) * nfacets); + coords = (SFVec3f*)gf_malloc(sizeof(SFVec3f) * nfacets); + texcoords = (SFVec2f*)gf_malloc(sizeof(SFVec2f) * nfacets); compute_cylinder(height, radius, nfacets, coords, texcoords); @@ -530,8 +534,8 @@ void mesh_new_cone(GF_Mesh *mesh, Fixed height, Fixed radius, Bool bottom, Bool (FIX_ONE + gf_sin(angle))/2, FIX_ONE - (FIX_ONE + gf_cos(angle))/2); mesh_set_triangle(mesh, c_idx, mesh->v_count-2, mesh->v_count-1); } - free(texcoords); - free(coords); + gf_free(texcoords); + gf_free(coords); if (bottom && side) mesh->flags |= MESH_IS_SOLID; @@ -578,8 +582,8 @@ void mesh_new_sphere(GF_Mesh *mesh, Fixed radius, Bool low_res) if (low_res) num_steps /= 2; npts = num_steps * num_steps; - coords = (SFVec3f*)malloc(sizeof(SFVec3f)*npts); - texcoords = (SFVec2f*)malloc(sizeof(SFVec2f)*npts); + coords = (SFVec3f*)gf_malloc(sizeof(SFVec3f)*npts); + texcoords = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*npts); compute_sphere(radius, coords, texcoords, num_steps); for (i=0; i<num_steps-1; i++) { @@ -610,8 +614,8 @@ void mesh_new_sphere(GF_Mesh *mesh, Fixed radius, Bool low_res) mesh_set_triangle(mesh, mesh->v_count-3, mesh->v_count-2, mesh->v_count-1); } - free(coords); - free(texcoords); + gf_free(coords); + gf_free(texcoords); mesh->flags |= MESH_IS_SOLID; mesh->bounds.min_edge.x = mesh->bounds.min_edge.y = mesh->bounds.min_edge.z = -radius; @@ -622,22 +626,31 @@ void mesh_new_sphere(GF_Mesh *mesh, Fixed radius, Bool low_res) } -void mesh_new_rectangle(GF_Mesh *mesh, SFVec2f size) +void mesh_new_rectangle(GF_Mesh *mesh, SFVec2f size, SFVec2f *orig, Bool flip) { - Fixed hx = size.x / 2; - Fixed hy = size.y / 2; + Fixed tmin, tmax; + Fixed x = - size.x / 2; + Fixed y = size.y / 2; + if (orig) { + x = orig->x; + y = orig->y; + } mesh_reset(mesh); - mesh_set_vertex(mesh, -hx, -hy, 0, 0, 0, FIX_ONE, 0, 0); - mesh_set_vertex(mesh, hx, -hy, 0, 0, 0, FIX_ONE, FIX_ONE, 0); - mesh_set_vertex(mesh, hx, hy, 0, 0, 0, FIX_ONE, FIX_ONE, FIX_ONE); - mesh_set_vertex(mesh, -hx, hy, 0, 0, 0, FIX_ONE, 0, FIX_ONE); + tmin = flip ? FIX_ONE : 0; + tmax = flip ? 0 : FIX_ONE; + + mesh_set_vertex(mesh, x, y-size.y, 0, 0, 0, FIX_ONE, 0, tmin); + mesh_set_vertex(mesh, x+size.x, y-size.y, 0, 0, 0, FIX_ONE, FIX_ONE, tmin); + mesh_set_vertex(mesh, x+size.x, y, 0, 0, 0, FIX_ONE, FIX_ONE, tmax); + mesh_set_vertex(mesh, x, y, 0, 0, 0, FIX_ONE, 0, tmax); + mesh_set_triangle(mesh, 0, 1, 2); mesh_set_triangle(mesh, 0, 2, 3); mesh->flags |= MESH_IS_2D; - mesh->bounds.min_edge.x = -hx; mesh->bounds.min_edge.y = -hy; mesh->bounds.min_edge.z = 0; - mesh->bounds.max_edge.x = hx; mesh->bounds.max_edge.y = hy; mesh->bounds.max_edge.z = 0; + mesh->bounds.min_edge.x = x; mesh->bounds.min_edge.y = y-size.y; mesh->bounds.min_edge.z = 0; + mesh->bounds.max_edge.x = x+size.x; mesh->bounds.max_edge.y = y; mesh->bounds.max_edge.z = 0; gf_bbox_refresh(&mesh->bounds); } @@ -728,8 +741,8 @@ void mesh_from_path_intern(GF_Mesh *mesh, GF_Path *path, Bool make_ccw) } } /*we need to tesselate the path*/ -#ifndef GPAC_USE_OGL_ES - TesselatePath(mesh, path, 0); +#ifdef GPAC_HAS_GLU + gf_mesh_tesselate_path(mesh, path, 0); #endif } @@ -762,6 +775,10 @@ void mesh_get_outline(GF_Mesh *mesh, GF_Path *path) mesh_update_bounds(mesh); } + +#ifndef GPAC_DISABLE_VRML + + #define COL_TO_RGBA(res, col) { res.red = col.red; res.green = col.green; res.blue = col.blue; res.alpha = FIX_ONE; } @@ -959,7 +976,7 @@ void register_point_in_face(struct face_info *fi, u32 pt_index) { if (fi->idx_count==fi->idx_alloc) { fi->idx_alloc += 10; - fi->idx = (u32*)realloc(fi->idx, sizeof(u32)*fi->idx_alloc); + fi->idx = (u32*)gf_realloc(fi->idx, sizeof(u32)*fi->idx_alloc); } fi->idx[fi->idx_count] = pt_index; fi->idx_count++; @@ -969,7 +986,7 @@ void register_face_in_point(struct pt_info *pi, u32 face_index) { if (pi->face_count==pi->face_alloc) { pi->face_alloc += 10; - pi->faces = (u32*)realloc(pi->faces, sizeof(u32)*pi->face_alloc); + pi->faces = (u32*)gf_realloc(pi->faces, sizeof(u32)*pi->face_alloc); } pi->faces[pi->face_count] = face_index; pi->face_count++; @@ -1138,7 +1155,7 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, if (coordIndex->vals[count-1] != -1) face_count++; } - faces = (GF_Mesh**)malloc(sizeof(GF_Mesh *)*face_count); + faces = (GF_Mesh**)gf_malloc(sizeof(GF_Mesh *)*face_count); for (i=0; i<face_count; i++) { faces[i] = new_mesh(); if (coord2D) faces[i]->flags = MESH_IS_2D; @@ -1148,9 +1165,9 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, /*alloc face & normals tables*/ if (smooth_normals) { - faces_info = (struct face_info*)malloc(sizeof(struct face_info)*face_count); + faces_info = (struct face_info*)gf_malloc(sizeof(struct face_info)*face_count); memset(faces_info, 0, sizeof(struct face_info)*face_count); - pts_info = (struct pt_info*)malloc(sizeof(struct pt_info)*c_count); + pts_info = (struct pt_info*)gf_malloc(sizeof(struct pt_info)*c_count); memset(pts_info, 0, sizeof(struct pt_info)*c_count); } @@ -1249,12 +1266,12 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, } } if (faces_info) { - for (i=0; i<face_count; i++) if (faces_info[i].idx) free(faces_info[i].idx); - free(faces_info); + for (i=0; i<face_count; i++) if (faces_info[i].idx) gf_free(faces_info[i].idx); + gf_free(faces_info); } if (pts_info) { - for (i=0; i<c_count; i++) if (pts_info[i].faces) free(pts_info[i].faces); - free(pts_info); + for (i=0; i<c_count; i++) if (pts_info[i].faces) gf_free(pts_info[i].faces); + gf_free(pts_info); } mesh->flags |= MESH_IS_SMOOTHED; } else { @@ -1279,7 +1296,7 @@ void mesh_new_ifs_intern(GF_Mesh *mesh, GF_Node *__coord, MFInt32 *coordIndex, if (faces[i]->v_count) TesselateFaceMesh(mesh, faces[i]); mesh_free(faces[i]); } - free(faces); + gf_free(faces); mesh_update_bounds(mesh); if (!coord2D) gf_mesh_build_aabbtree(mesh); @@ -1394,10 +1411,10 @@ void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *node) /*alloc face & normals tables*/ if (smooth_normals) { - faces = (GF_Mesh **)malloc(sizeof(GF_Mesh *)*face_count); - faces_info = (struct face_info*)malloc(sizeof(struct face_info)*face_count); + faces = (GF_Mesh **)gf_malloc(sizeof(GF_Mesh *)*face_count); + faces_info = (struct face_info*)gf_malloc(sizeof(struct face_info)*face_count); memset(faces_info, 0, sizeof(struct face_info)*face_count); - pts_info = (struct pt_info*)malloc(sizeof(struct pt_info)*pt_count); + pts_info = (struct pt_info*)gf_malloc(sizeof(struct pt_info)*pt_count); memset(pts_info, 0, sizeof(struct pt_info)*pt_count); faces[cur_face] = new_mesh(); } @@ -1504,12 +1521,12 @@ void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *node) } } if (faces_info) { - for (i=0; i<face_count; i++) if (faces_info[i].idx) free(faces_info[i].idx); - free(faces_info); + for (i=0; i<face_count; i++) if (faces_info[i].idx) gf_free(faces_info[i].idx); + gf_free(faces_info); } if (pts_info) { - for (i=0; i<pt_count; i++) if (pts_info[i].faces) free(pts_info[i].faces); - free(pts_info); + for (i=0; i<pt_count; i++) if (pts_info[i].faces) gf_free(pts_info[i].faces); + gf_free(pts_info); } mesh->flags |= MESH_IS_SMOOTHED; @@ -1531,7 +1548,7 @@ void mesh_new_elevation_grid(GF_Mesh *mesh, GF_Node *node) } /*destroy faces*/ - free(faces); + gf_free(faces); } mesh->mesh_type = MESH_TRIANGLES; @@ -1624,25 +1641,25 @@ static void mesh_extrude_path_intern(GF_Mesh *mesh, GF_Path *path, MFVec3f *thes pt_count = pts_per_cross * thespine->count; smooth_normals = NEAR_ZERO(creaseAngle) ? 0 : 1; - faces = (GF_Mesh**)malloc(sizeof(GF_Mesh *)*face_count); + faces = (GF_Mesh**)gf_malloc(sizeof(GF_Mesh *)*face_count); for (i=0; i<face_count; i++) faces[i] = new_mesh(); faces_info = NULL; pts_info = NULL; /*alloc face & normals tables*/ if (smooth_normals) { - faces_info = (struct face_info*)malloc(sizeof(struct face_info)*face_count); + faces_info = (struct face_info*)gf_malloc(sizeof(struct face_info)*face_count); memset(faces_info, 0, sizeof(struct face_info)*face_count); - pts_info = (struct pt_info*)malloc(sizeof(struct pt_info)*pt_count); + pts_info = (struct pt_info*)gf_malloc(sizeof(struct pt_info)*pt_count); memset(pts_info, 0, sizeof(struct pt_info)*pt_count); } spine = thespine->vals; nb_spine = thespine->count; - SCPs = (SCP *)malloc(sizeof(SCP) * nb_spine); + SCPs = (SCP *)gf_malloc(sizeof(SCP) * nb_spine); memset(SCPs, 0, sizeof(SCP) * nb_spine); - SCPi = (SCPInfo *) malloc(sizeof(SCPInfo) * nb_spine); + SCPi = (SCPInfo *) gf_malloc(sizeof(SCPInfo) * nb_spine); memset(SCPi, 0, sizeof(SCPInfo) * nb_spine); /*collect all # SCPs: @@ -1811,7 +1828,7 @@ static void mesh_extrude_path_intern(GF_Mesh *mesh, GF_Path *path, MFVec3f *thes } } } - free(SCPi); + gf_free(SCPi); SCPbegin = SCPs[0]; SCPend = SCPs[nb_spine-1]; @@ -2079,12 +2096,12 @@ static void mesh_extrude_path_intern(GF_Mesh *mesh, GF_Path *path, MFVec3f *thes } } if (faces_info) { - for (i=0; i<face_count; i++) if (faces_info[i].idx) free(faces_info[i].idx); - free(faces_info); + for (i=0; i<face_count; i++) if (faces_info[i].idx) gf_free(faces_info[i].idx); + gf_free(faces_info); } if (pts_info) { - for (i=0; i<pt_count; i++) if (pts_info[i].faces) free(pts_info[i].faces); - free(pts_info); + for (i=0; i<pt_count; i++) if (pts_info[i].faces) gf_free(pts_info[i].faces); + gf_free(pts_info); } mesh->flags |= MESH_IS_SMOOTHED; } @@ -2109,7 +2126,7 @@ static void mesh_extrude_path_intern(GF_Mesh *mesh, GF_Path *path, MFVec3f *thes if (begin_face) { if (path->n_contours>1) { #ifdef GPAC_HAS_GLU - u32 *ptsPerFace = malloc(sizeof(u32)*path->n_contours); + u32 *ptsPerFace = gf_malloc(sizeof(u32)*path->n_contours); /*we reversed begin cap!!!*/ cur = 0; for (i=0; i<path->n_contours; i++) { @@ -2118,7 +2135,7 @@ static void mesh_extrude_path_intern(GF_Mesh *mesh, GF_Path *path, MFVec3f *thes ptsPerFace[i] = nb_pts; } TesselateFaceMeshComplex(mesh, faces[begin_face], path->n_contours, ptsPerFace); - free(ptsPerFace); + gf_free(ptsPerFace); #endif } else { TesselateFaceMesh(mesh, faces[begin_face]); @@ -2128,7 +2145,7 @@ static void mesh_extrude_path_intern(GF_Mesh *mesh, GF_Path *path, MFVec3f *thes if (end_face) { if (path->n_contours>1) { #ifdef GPAC_HAS_GLU - u32 *ptsPerFace = malloc(sizeof(u32)*path->n_contours); + u32 *ptsPerFace = gf_malloc(sizeof(u32)*path->n_contours); cur = 0; for (i=0; i<path->n_contours; i++) { nb_pts = 1+path->contours[i] - cur; @@ -2136,15 +2153,15 @@ static void mesh_extrude_path_intern(GF_Mesh *mesh, GF_Path *path, MFVec3f *thes ptsPerFace[i] = nb_pts; } TesselateFaceMeshComplex(mesh, faces[end_face], path->n_contours, ptsPerFace); - free(ptsPerFace); + gf_free(ptsPerFace); #endif } else { TesselateFaceMesh(mesh, faces[end_face]); } mesh_free(faces[end_face]); } - free(faces); - free(SCPs); + gf_free(faces); + gf_free(SCPs); /*FIXME: this is correct except we need to handle path cw/ccw - until then no possibility to get correct lighting*/ @@ -2193,3 +2210,4 @@ void mesh_new_extrusion(GF_Mesh *mesh, GF_Node *node) #endif /* GPAC_DISABLE_3D*/ +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mesh_collide.c b/src/compositor/mesh_collide.c index 673dbae..248ecb1 100644 --- a/src/compositor/mesh_collide.c +++ b/src/compositor/mesh_collide.c @@ -241,7 +241,7 @@ void gf_mesh_build_aabbtree(GF_Mesh *mesh) if (mesh->i_count <= pars.min_tri_limit) return; nb_idx = mesh->i_count / 3; - mesh->aabb_indices = (IDX_TYPE*)malloc(sizeof(IDX_TYPE) * nb_idx); + mesh->aabb_indices = (IDX_TYPE*)gf_malloc(sizeof(IDX_TYPE) * nb_idx); for (i=0; i<nb_idx; i++) mesh->aabb_indices[i] = i; GF_SAFEALLOC(mesh->aabb_root, AABBNode); diff --git a/src/compositor/mesh_tesselate.c b/src/compositor/mesh_tesselate.c index 8078149..bb6f3ea 100644 --- a/src/compositor/mesh_tesselate.c +++ b/src/compositor/mesh_tesselate.c @@ -117,14 +117,14 @@ static void CALLBACK mesh_tess_combine(GLdouble coords[3], void* vertex_data[4], } } - new_idx = (u32 *) malloc(sizeof(u32)); + new_idx = (u32 *) gf_malloc(sizeof(u32)); gf_list_add(tess->vertex_index, new_idx); *new_idx = tess->mesh->v_count; mesh_set_vertex(tess->mesh, FLT2FIX( (Float) coords[0]), FLT2FIX( (Float) coords[1]), FLT2FIX( (Float) coords[2]), n.x, n.y, n.z, tx.x, tx.y); *out_data = new_idx; } -void TesselatePath(GF_Mesh *mesh, GF_Path *path, u32 outline_style) +void gf_mesh_tesselate_path(GF_Mesh *mesh, GF_Path *path, u32 outline_style) { u32 i, j, cur, nb_pts; u32 *idx; @@ -133,12 +133,12 @@ void TesselatePath(GF_Mesh *mesh, GF_Path *path, u32 outline_style) GLdouble vertex[3]; MeshTess *tess; if (!mesh || !path || !path->n_contours) return; - tess = malloc(sizeof(MeshTess)); + tess = gf_malloc(sizeof(MeshTess)); if (!tess) return; memset(tess, 0, sizeof(MeshTess)); tess->tess_obj = gluNewTess(); if (!tess->tess_obj) { - free(tess); + gf_free(tess); return; } tess->vertex_index = gf_list_new(); @@ -179,7 +179,7 @@ void TesselatePath(GF_Mesh *mesh, GF_Path *path, u32 outline_style) Fixed u = gf_divfix(pt.x - rc.x, w); Fixed v = gf_divfix(pt.y - min_y, h); - idx = (u32 *) malloc(sizeof(u32)); + idx = (u32 *) gf_malloc(sizeof(u32)); *idx = mesh->v_count; gf_list_add(tess->vertex_index, idx); mesh_set_vertex(mesh, pt.x, pt.y, 0, 0, 0, FIX_ONE, u, v); @@ -199,10 +199,10 @@ void TesselatePath(GF_Mesh *mesh, GF_Path *path, u32 outline_style) while (gf_list_count(tess->vertex_index)) { u32 *idx = gf_list_get(tess->vertex_index, 0); gf_list_rem(tess->vertex_index, 0); - free(idx); + gf_free(idx); } gf_list_del(tess->vertex_index); - free(tess); + gf_free(tess); mesh->bounds.min_edge.x = rc.x; mesh->bounds.min_edge.y = rc.y-rc.height; @@ -214,7 +214,7 @@ void TesselatePath(GF_Mesh *mesh, GF_Path *path, u32 outline_style) #else -void TesselatePath(GF_Mesh *mesh, GF_Path *path, u32 outline_style) { } +void gf_mesh_tesselate_path(GF_Mesh *mesh, GF_Path *path, u32 outline_style) { } #endif @@ -364,12 +364,12 @@ void TesselateFaceMesh(GF_Mesh *dest, GF_Mesh *orig) #ifdef GPAC_HAS_GLU /*tesselate it*/ - tess = malloc(sizeof(MeshTess)); + tess = gf_malloc(sizeof(MeshTess)); if (!tess) return; memset(tess, 0, sizeof(MeshTess)); tess->tess_obj = gluNewTess(); if (!tess->tess_obj) { - free(tess); + gf_free(tess); return; } tess->vertex_index = gf_list_new(); @@ -387,7 +387,7 @@ void TesselateFaceMesh(GF_Mesh *dest, GF_Mesh *orig) for (i=0; i<orig->v_count; i++) { - idx = (u32 *) malloc(sizeof(u32)); + idx = (u32 *) gf_malloc(sizeof(u32)); *idx = dest->v_count; gf_list_add(tess->vertex_index, idx); mesh_set_vertex_vx(dest, &orig->vertices[i]); @@ -405,10 +405,10 @@ void TesselateFaceMesh(GF_Mesh *dest, GF_Mesh *orig) while (gf_list_count(tess->vertex_index)) { u32 *idx = gf_list_get(tess->vertex_index, 0); gf_list_rem(tess->vertex_index, 0); - free(idx); + gf_free(idx); } gf_list_del(tess->vertex_index); - free(tess); + gf_free(tess); #endif } @@ -424,12 +424,12 @@ void TesselateFaceMeshComplex(GF_Mesh *dest, GF_Mesh *orig, u32 nbFaces, u32 *pt MeshTess *tess; /*tesselate it*/ - tess = malloc(sizeof(MeshTess)); + tess = gf_malloc(sizeof(MeshTess)); if (!tess) return; memset(tess, 0, sizeof(MeshTess)); tess->tess_obj = gluNewTess(); if (!tess->tess_obj) { - free(tess); + gf_free(tess); return; } tess->vertex_index = gf_list_new(); @@ -458,7 +458,7 @@ void TesselateFaceMeshComplex(GF_Mesh *dest, GF_Mesh *orig, u32 nbFaces, u32 *pt gluTessBeginContour(tess->tess_obj); } - idx = (u32 *) malloc(sizeof(u32)); + idx = (u32 *) gf_malloc(sizeof(u32)); *idx = dest->v_count; gf_list_add(tess->vertex_index, idx); mesh_set_vertex_vx(dest, &orig->vertices[i]); @@ -476,14 +476,12 @@ void TesselateFaceMeshComplex(GF_Mesh *dest, GF_Mesh *orig, u32 nbFaces, u32 *pt while (gf_list_count(tess->vertex_index)) { u32 *idx = gf_list_get(tess->vertex_index, 0); gf_list_rem(tess->vertex_index, 0); - free(idx); + gf_free(idx); } gf_list_del(tess->vertex_index); - free(tess); + gf_free(tess); } #endif #endif /*GPAC_DISABLE_3D*/ - - diff --git a/src/compositor/mpeg4_animstream.c b/src/compositor/mpeg4_animstream.c index 3b9e4a4..2610899 100644 --- a/src/compositor/mpeg4_animstream.c +++ b/src/compositor/mpeg4_animstream.c @@ -26,6 +26,8 @@ #include <gpac/nodes_mpeg4.h> +#ifndef GPAC_DISABLE_VRML + typedef struct { GF_Compositor *compositor; @@ -49,7 +51,7 @@ static void animationstream_destroy(GF_Node *node, void *rs, Bool is_destroy) gf_mo_stop(st->stream); } gf_sg_vrml_mf_reset(&st->current_url, GF_SG_VRML_MFURL); - free(st); + gf_free(st); } } @@ -59,7 +61,7 @@ static void animationstream_check_url(AnimationStreamStack *stack, M_AnimationSt if (!stack->stream) { gf_sg_vrml_mf_reset(&stack->current_url, GF_SG_VRML_MFURL); gf_sg_vrml_field_copy(&stack->current_url, &as->url, GF_SG_VRML_MFURL); - stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0); + stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0, 0); gf_sc_invalidate(stack->compositor, NULL); /*if changed while playing trigger*/ @@ -80,7 +82,7 @@ static void animationstream_check_url(AnimationStreamStack *stack, M_AnimationSt } gf_mo_unregister((GF_Node *)as, stack->stream); - stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0); + stack->stream = gf_mo_register((GF_Node *)as, &as->url, 0, 0); /*if changed while playing play new source*/ if (as->isActive) { gf_mo_play(stack->stream, 0, -1, 0); @@ -194,3 +196,5 @@ void compositor_animationstream_modified(GF_Node *node) else st->time_handle.needs_unregister = 0; } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_audio.c b/src/compositor/mpeg4_audio.c index 1a1773e..827066a 100644 --- a/src/compositor/mpeg4_audio.c +++ b/src/compositor/mpeg4_audio.c @@ -25,6 +25,8 @@ #include "nodes_stacks.h" +#ifndef GPAC_DISABLE_VRML + typedef struct { GF_AudioInput input; @@ -64,12 +66,11 @@ static void audioclip_traverse(GF_Node *node, void *rs, Bool is_destroy) AudioClipStack *st = (AudioClipStack *)gf_node_get_private(node); if (is_destroy) { - gf_sc_audio_stop(&st->input); - gf_sc_audio_unregister(&st->input); + gf_sc_audio_predestroy(&st->input); if (st->time_handle.is_registered) { gf_sc_unregister_time_node(st->input.compositor, &st->time_handle); } - free(st); + gf_free(st); return; } if (st->failure) return; @@ -203,12 +204,11 @@ static void audiosource_traverse(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { - gf_sc_audio_stop(&st->input); - gf_sc_audio_unregister(&st->input); + gf_sc_audio_predestroy(&st->input); if (st->time_handle.is_registered) { gf_sc_unregister_time_node(st->input.compositor, &st->time_handle); } - free(st); + gf_free(st); return; } @@ -341,9 +341,9 @@ static void audiobuffer_traverse(GF_Node *node, void *rs, Bool is_destroy) gf_sc_unregister_time_node(st->output.compositor, &st->time_handle); gf_mixer_del(st->am); - if (st->buffer) free(st->buffer); + if (st->buffer) gf_free(st->buffer); gf_list_del(st->new_inputs); - free(st); + gf_free(st); return; } parent = tr_state->audio_parent; @@ -454,7 +454,7 @@ static char *audiobuffer_fetch_frame(void *callback, u32 *size, u32 audio_delay_ blockAlign = gf_mixer_get_block_align(st->am); /*BLOCK ALIGN*/ while (st->buffer_size%blockAlign) st->buffer_size++; - st->buffer = (char*)malloc(sizeof(char) * st->buffer_size); + st->buffer = (char*)gf_malloc(sizeof(char) * st->buffer_size); memset(st->buffer, 0, sizeof(char) * st->buffer_size); st->read_pos = st->write_pos = 0; } @@ -465,7 +465,7 @@ static char *audiobuffer_fetch_frame(void *callback, u32 *size, u32 audio_delay_ u32 written; while (1) { /*just try to completely fill it*/ - written = gf_mixer_get_output(st->am, st->buffer + st->write_pos, st->buffer_size - st->write_pos); + written = gf_mixer_get_output(st->am, st->buffer + st->write_pos, st->buffer_size - st->write_pos, 0); if (!written) break; st->write_pos += written; assert(st->write_pos<=st->buffer_size); @@ -527,7 +527,7 @@ static Bool audiobuffer_get_config(GF_AudioInterface *aifc, Bool for_reconf) if (gf_mixer_must_reconfig(st->am)) { if (gf_mixer_reconfig(st->am)) { - if (st->buffer) free(st->buffer); + if (st->buffer) gf_free(st->buffer); st->buffer = NULL; st->buffer_size = 0; } @@ -608,3 +608,4 @@ void compositor_audiobuffer_modified(GF_Node *node) st->time_handle.needs_unregister = 0; } +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_background.c b/src/compositor/mpeg4_background.c index 043ae7b..96ff0d2 100644 --- a/src/compositor/mpeg4_background.c +++ b/src/compositor/mpeg4_background.c @@ -26,6 +26,8 @@ #include "nodes_stacks.h" +#ifndef GPAC_DISABLE_VRML + #ifndef GPAC_DISABLE_3D #include "texturing.h" @@ -108,7 +110,7 @@ static void DestroyBackground(GF_Node *node) gf_sc_texture_destroy(&ptr->txh_left); gf_sc_texture_destroy(&ptr->txh_right); - free(ptr); + gf_free(ptr); } #define COL_TO_RGBA(res, col) { res.red = col.red; res.green = col.green; res.blue = col.blue; res.alpha = FIX_ONE; } @@ -412,10 +414,10 @@ static void TraverseBackground(GF_Node *node, void *rs, Bool is_destroy) } -static void back_set_bind(GF_Node *node) +static void back_set_bind(GF_Node *node, GF_Route *route) { BackgroundStack *st = (BackgroundStack *)gf_node_get_private(node); - Bindable_OnSetBind(node, st->reg_stacks); + Bindable_OnSetBind(node, st->reg_stacks, NULL); /*and redraw scene*/ gf_sc_invalidate(st->compositor, NULL); } @@ -535,3 +537,5 @@ void compositor_background_modified(GF_Node *node) } #endif /*GPAC_DISABLE_3D*/ + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_background2d.c b/src/compositor/mpeg4_background2d.c index 131f58f..4947695 100644 --- a/src/compositor/mpeg4_background2d.c +++ b/src/compositor/mpeg4_background2d.c @@ -28,6 +28,8 @@ #include "texturing.h" #include "nodes_stacks.h" +#ifndef GPAC_DISABLE_VRML + #define B2D_PLANE_HSIZE FLT2FIX(0.5025f) @@ -47,7 +49,7 @@ static void DestroyBackground2D(GF_Node *node) while (gf_list_count(stack->status_stack)) { BackgroundStatus *status = (BackgroundStatus *)gf_list_get(stack->status_stack, 0); gf_list_rem(stack->status_stack, 0); - free(status); + gf_free(status); } gf_list_del(stack->status_stack); @@ -56,7 +58,7 @@ static void DestroyBackground2D(GF_Node *node) #ifndef GPAC_DISABLE_3D if (stack->mesh) mesh_free(stack->mesh); #endif - free(stack); + gf_free(stack); } static void b2D_new_status(Background2DStack *bck, M_Background2D*back) @@ -99,11 +101,12 @@ static Bool back_use_texture(M_Background2D *bck) static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state) { + Background2DStack *stack = (Background2DStack *) gf_node_get_private(ctx->drawable->node); if (!ctx->bi->clip.width || !ctx->bi->clip.height) return; - ctx->flags &= ~CTX_PATH_FILLED; + stack->flags &= ~CTX_PATH_FILLED; if (back_use_texture((M_Background2D *)ctx->drawable->node)) { @@ -118,15 +121,13 @@ static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state /*draw texture*/ visual_2d_texture_path(tr_state->visual, stack->drawable->path, ctx, tr_state); } - /*if (stack->txh.hwtx) ctx->flags |= CTX_APP_DIRTY; - else */ - ctx->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY); + stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY); } else { /*direct drawing, draw without clippers */ - if (tr_state->direct_draw) { + if (tr_state->immediate_draw) { /*directly clear with specified color*/ - visual_2d_clear(tr_state->visual, &ctx->bi->clip, ctx->aspect.fill_color); + tr_state->visual->ClearSurface(tr_state->visual, &ctx->bi->clip, ctx->aspect.fill_color); } else { u32 i; GF_IRect clip; @@ -138,11 +139,11 @@ static void DrawBackground2D_2D(DrawableContext *ctx, GF_TraverseState *tr_state clip = ctx->bi->clip; gf_irect_intersect(&clip, &tr_state->visual->to_redraw.list[i]); if (clip.width && clip.height) { - visual_2d_clear(tr_state->visual, &clip, ctx->aspect.fill_color); + tr_state->visual->ClearSurface(tr_state->visual, &clip, ctx->aspect.fill_color); } } } - ctx->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY); + stack->flags &= ~(CTX_APP_DIRTY | CTX_TEXTURE_DIRTY); } tr_state->visual->has_modif = 1; } @@ -266,11 +267,12 @@ static void TraverseBackground2D(GF_Node *node, void *rs, Bool is_destroy) /*special case for background in Layer2D: the background is seen as a regular drawable, so RENDER_BINDABLE is not used*/ - if (tr_state->traversing_mode==TRAVERSE_DRAW_2D) { + switch (tr_state->traversing_mode) { + case TRAVERSE_DRAW_2D: DrawBackground2D_2D(tr_state->ctx, tr_state); return; - } - else if (tr_state->traversing_mode==TRAVERSE_PICK) { + case TRAVERSE_PICK: + case TRAVERSE_GET_BOUNDS: return; } @@ -299,21 +301,22 @@ static void TraverseBackground2D(GF_Node *node, void *rs, Bool is_destroy) if (!status) return; if (gf_node_dirty_get(node)) { - status->ctx.flags |= CTX_APP_DIRTY; + stack->flags |= CTX_APP_DIRTY; gf_node_dirty_clear(node, 0); col = GF_COL_ARGB_FIXED(FIX_ONE, bck->backColor.red, bck->backColor.green, bck->backColor.blue); if (col != status->ctx.aspect.fill_color) { status->ctx.aspect.fill_color = col; - status->ctx.flags |= CTX_APP_DIRTY; + stack->flags |= CTX_APP_DIRTY; } } if (back_use_texture(bck) ) { if (stack->txh.tx_io && !(status->ctx.flags & CTX_APP_DIRTY) && stack->txh.needs_refresh) - status->ctx.flags |= CTX_TEXTURE_DIRTY; + stack->flags |= CTX_TEXTURE_DIRTY; } + status->ctx.flags = stack->flags; if (tr_state->traversing_mode != TRAVERSE_BINDABLE) return; @@ -328,10 +331,16 @@ static void TraverseBackground2D(GF_Node *node, void *rs, Bool is_destroy) } -static void b2D_set_bind(GF_Node *node) +static void b2D_set_bind(GF_Node *node, GF_Route *route) { Background2DStack *stack = (Background2DStack *)gf_node_get_private(node); - Bindable_OnSetBind(node, stack->reg_stacks); + Bindable_OnSetBind(node, stack->reg_stacks, NULL); + + if (stack->drawable->flags & DRAWABLE_IS_OVERLAY) { + stack->txh.compositor->video_out->Blit(stack->txh.compositor->video_out, NULL, NULL, NULL, 1); + } + stack->flags |= CTX_APP_DIRTY; + } DrawableContext *b2d_get_context(M_Background2D *node, GF_List *from_stack) @@ -371,6 +380,7 @@ void compositor_init_background2d(GF_Compositor *compositor, GF_Node *node) gf_sc_texture_setup(&ptr->txh, compositor, node); ptr->txh.update_texture_fcnt = UpdateBackgroundTexture; ptr->txh.flags = GF_SR_TEXTURE_REPEAT_S | GF_SR_TEXTURE_REPEAT_T; + ptr->flags = CTX_IS_BACKGROUND; gf_node_set_private(node, ptr); gf_node_set_callback_function(node, TraverseBackground2D); @@ -411,3 +421,5 @@ Bool compositor_background_transparent(GF_Node *node) /*consider all other background nodes transparent*/ return 1; } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_bitmap.c b/src/compositor/mpeg4_bitmap.c index 76eb2a6..44c0ea7 100644 --- a/src/compositor/mpeg4_bitmap.c +++ b/src/compositor/mpeg4_bitmap.c @@ -28,6 +28,8 @@ #include "visual_manager.h" #include "texturing.h" +#ifndef GPAC_DISABLE_VRML + typedef struct _bitmap_stack { Drawable *graph; @@ -60,6 +62,7 @@ static void Bitmap_BuildGraph(GF_Node *node, BitmapStack *st, GF_TraverseState * *out_rc = st->rc; return; } + st->prev_tx_w = txh->width; st->prev_tx_h = txh->height; @@ -174,7 +177,7 @@ static void TraverseBitmap(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { drawable_del(st->graph); - free(st); + gf_free(st); return; } @@ -188,7 +191,8 @@ static void TraverseBitmap(GF_Node *node, void *rs, Bool is_destroy) return; #endif case TRAVERSE_PICK: - drawable_pick(st->graph, tr_state); + //drawable_pick(st->graph, tr_state); + vrml_drawable_pick(st->graph, tr_state); return; case TRAVERSE_GET_BOUNDS: Bitmap_BuildGraph(node, st, tr_state, &tr_state->bounds, @@ -218,6 +222,7 @@ static void TraverseBitmap(GF_Node *node, void *rs, Bool is_destroy) return; } + /*even if set this is not true*/ ctx->aspect.pen_props.width = 0; ctx->flags |= CTX_NO_ANTIALIAS; @@ -264,3 +269,4 @@ void compositor_init_bitmap(GF_Compositor *compositor, GF_Node *node) gf_node_set_callback_function(node, TraverseBitmap); } +#endif \ No newline at end of file diff --git a/src/compositor/mpeg4_composite.c b/src/compositor/mpeg4_composite.c index a08e0bf..1c1c71f 100644 --- a/src/compositor/mpeg4_composite.c +++ b/src/compositor/mpeg4_composite.c @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -28,17 +28,12 @@ #include "visual_manager.h" #include "texturing.h" -#ifdef GPAC_USE_TINYGL -//#include <GL/oscontext.h> -#include "../../TinyGL/include/GL/oscontext.h" -#endif +#ifndef GPAC_DISABLE_VRML -#ifdef TRISCOPE_TEST_MALLOC -#include "gltx_malloc.h" +#ifdef GPAC_USE_TINYGL +#include <GL/oscontext.h> #endif - - typedef struct { GF_TextureHandler txh; @@ -46,7 +41,9 @@ typedef struct /*the visual object handling the texture*/ GF_VisualManager *visual; Bool first, unsupported; - + GF_List *sensors, *previous_sensors; + GF_Node *prev_hit_appear; + #ifdef GPAC_USE_TINYGL ostgl_context *tgl_ctx; #endif @@ -55,22 +52,39 @@ typedef struct static void composite_traverse(GF_Node *node, void *rs, Bool is_destroy) { if (is_destroy) { + u32 i=0; + GF_VisualManager *a_visual; CompositeTextureStack *st = (CompositeTextureStack *) gf_node_get_private(node); /*unregister visual*/ gf_sc_visual_unregister(st->visual->compositor, st->visual); + + /*We must make sure we don't keep pointers to this composite in the different visuals. + - we must track Appearance nodes at the compositor level to undo the textureTransform while picking + - but we clearly don't want to track destruction of all appearance nodes just to solve this texture delete + => remove the entire compositeTexture appearance state - this may lead to small bugs in interaction logics, however they should + not be too damageable + */ + st->visual->compositor->hit_appear = NULL; + st->visual->compositor->prev_hit_appear = NULL; + + while ( (a_visual = gf_list_enum(st->visual->compositor->visuals, &i))) { + if (a_visual->offscreen) { + CompositeTextureStack *a_st = (CompositeTextureStack *) gf_node_get_private(a_visual->offscreen); + a_st->prev_hit_appear = NULL; + } + } + visual_del(st->visual); -#ifndef TRISCOPE_TEST_MALLOC - if (st->txh.data) free(st->txh.data); -#else - if (st->txh.data) gltx_free(st->txh.data); - printf("Renoir object texture freed: Total %d Max %d\n",gltx_total_mem(),gltx_max_alloc()) ; -#endif + if (st->txh.data) gf_free(st->txh.data); /*destroy texture*/ gf_sc_texture_destroy(&st->txh); #ifdef GPAC_USE_TINYGL if (st->tgl_ctx) ostgl_delete_context(st->tgl_ctx); #endif - free(st); + gf_list_del(st->sensors); + gf_list_del(st->previous_sensors); + + gf_free(st); } else { gf_node_traverse_children(node, rs); } @@ -82,43 +96,43 @@ static Bool composite_do_bindable(GF_Node *n, GF_TraverseState *tr_state, Bool f Bool ret = 0; switch (gf_node_get_tag(n)) { #ifndef GPAC_DISABLE_3D - case TAG_MPEG4_CompositeTexture3D: + case TAG_MPEG4_CompositeTexture3D: { M_CompositeTexture3D*c3d = (M_CompositeTexture3D*)n; if (force_check || gf_node_dirty_get(c3d->background)) { gf_node_traverse(c3d->background, tr_state); ret = 1; } btop = (GF_Node*)gf_list_get(tr_state->backgrounds, 0); - if (btop != c3d->background) { + if (btop != c3d->background) { gf_node_unregister(c3d->background, n); - gf_node_register(btop, n); + gf_node_register(btop, n); c3d->background = btop; gf_node_event_out_str(n, "background"); - ret = 1; + ret = 1; } if (force_check || gf_node_dirty_get(c3d->viewpoint)) { gf_node_traverse(c3d->viewpoint, tr_state); ret = 1; } btop = (GF_Node*)gf_list_get(tr_state->viewpoints, 0); - if (btop != c3d->viewpoint) { + if (btop != c3d->viewpoint) { gf_node_unregister(c3d->viewpoint, n); - gf_node_register(btop, n); - c3d->viewpoint = btop; + gf_node_register(btop, n); + c3d->viewpoint = btop; gf_node_event_out_str(n, "viewpoint"); - ret = 1; + ret = 1; } - + if (force_check || gf_node_dirty_get(c3d->fog)) { gf_node_traverse(c3d->fog, tr_state); ret = 1; } btop = (GF_Node*)gf_list_get(tr_state->fogs, 0); if (btop != c3d->fog) { gf_node_unregister(c3d->fog, n); - gf_node_register(btop, n); + gf_node_register(btop, n); c3d->fog = btop; gf_node_event_out_str(n, "fog"); ret = 1; } - + if (force_check || gf_node_dirty_get(c3d->navigationInfo)) { gf_node_traverse(c3d->navigationInfo, tr_state); ret = 1; } btop = (GF_Node*)gf_list_get(tr_state->navigations, 0); if (btop != c3d->navigationInfo) { gf_node_unregister(c3d->navigationInfo, n); - gf_node_register(btop, n); + gf_node_register(btop, n); c3d->navigationInfo = btop; gf_node_event_out_str(n, "navigationInfo"); ret = 1; @@ -126,14 +140,14 @@ static Bool composite_do_bindable(GF_Node *n, GF_TraverseState *tr_state, Bool f return ret; } #endif - case TAG_MPEG4_CompositeTexture2D: + case TAG_MPEG4_CompositeTexture2D: { M_CompositeTexture2D *c2d = (M_CompositeTexture2D*)n; if (force_check || gf_node_dirty_get(c2d->background)) { gf_node_traverse(c2d->background, tr_state); ret = 1; } btop = (GF_Node*)gf_list_get(tr_state->backgrounds, 0); if (btop != c2d->background) { gf_node_unregister(c2d->background, n); - gf_node_register(btop, n); + gf_node_register(btop, n); c2d->background = btop; gf_node_event_out_str(n, "background"); ret = 1; @@ -141,14 +155,14 @@ static Bool composite_do_bindable(GF_Node *n, GF_TraverseState *tr_state, Bool f if (force_check || gf_node_dirty_get(c2d->viewport)) { gf_node_traverse(c2d->viewport, tr_state); ret = 1; } btop = (GF_Node*)gf_list_get(tr_state->viewpoints, 0); - if (btop != c2d->viewport) { + if (btop != c2d->viewport) { gf_node_unregister(c2d->viewport, n); - gf_node_register(btop, n); + gf_node_register(btop, n); c2d->viewport = btop; gf_node_event_out_str(n, "viewport"); ret = 1; } - + return ret; } } @@ -159,7 +173,6 @@ static void composite_update(GF_TextureHandler *txh) { s32 w, h; GF_STENCIL stencil; - GF_Err e; M_Background2D *back; GF_TraverseState *tr_state; Bool invalidate_all; @@ -187,36 +200,38 @@ static void composite_update(GF_TextureHandler *txh) back = gf_list_get(st->visual->back_stack, 0); if (back && back->isBound) new_pixel_format = GF_PIXEL_RGB_24; else new_pixel_format = GF_PIXEL_RGBA; - + #ifdef GPAC_USE_TINYGL /*TinyGL pixel format is fixed at compile time, we cannot override it !*/ - new_pixel_format = GF_PIXEL_RGBA; + if (st->visual->type_3d) new_pixel_format = GF_PIXEL_RGBA; #else +#ifndef GPAC_DISABLE_3D + /*no alpha support in offscreen rendering*/ + if ( (st->visual->type_3d) && !(compositor->video_out->hw_caps & GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA)) + new_pixel_format = GF_PIXEL_RGB_24; +#endif + /*in OpenGL_ES, only RGBA can be safelly used with glReadPixels*/ #ifdef GPAC_USE_OGL_ES new_pixel_format = GF_PIXEL_RGBA; -#else - /*no alpha support in offscreen rendering*/ - if (!(compositor->video_out->hw_caps & GF_VIDEO_HW_OPENGL_OFFSCREEN_ALPHA)) - new_pixel_format = GF_PIXEL_RGB_24; #endif #endif - /*in triscope all our images are RGB+Depth+bitshape*/ -#ifdef GPAC_TRISCOPE_MODE + /*FIXME - we assume RGB+Depth+bitshape, we should check with the video out module*/ +#if defined(GF_SR_USE_DEPTH) && !defined(GPAC_DISABLE_3D) if (st->visual->type_3d) new_pixel_format = GF_PIXEL_RGBDS; #endif - + #ifndef GPAC_DISABLE_3D if (st->visual->type_3d>1) { w = ((M_CompositeTexture3D*)txh->owner)->pixelWidth; h = ((M_CompositeTexture3D*)txh->owner)->pixelHeight; - } else + } else #endif { w = ((M_CompositeTexture2D*)txh->owner)->pixelWidth; @@ -225,12 +240,23 @@ static void composite_update(GF_TextureHandler *txh) if (w<0) w = 0; if (h<0) h = 0; - if (!w || !h) return; + if (!w || !h) { + if (txh->tx_io) { +#ifdef GPAC_USE_TINYGL + if (st->tgl_ctx) ostgl_delete_context(st->tgl_ctx); +#endif + gf_sc_texture_release(txh); + if (txh->data) gf_free(txh->data); + txh->data = NULL; + txh->width = txh->height = txh->stride = 0; + } + return; + } invalidate_all = 0; /*rebuild stencil*/ - if (!txh->tx_io - || (w != (s32) txh->width) || ( h != (s32) txh->height) + if (!txh->tx_io + || (w != (s32) txh->width) || ( h != (s32) txh->height) || (new_pixel_format != txh->pixelformat) ) { @@ -240,14 +266,15 @@ static void composite_update(GF_TextureHandler *txh) if (st->tgl_ctx) ostgl_delete_context(st->tgl_ctx); #endif gf_sc_texture_release(txh); - if (txh->data) free(txh->data); + if (txh->data) + gf_free(txh->data); txh->data = NULL; } /*we don't use rect ext because of no support for texture transforms*/ - if (1 + if (1 #ifndef GPAC_DISABLE_3D - || compositor->gl_caps.npot_texture + || compositor->gl_caps.npot_texture #endif ) { st->txh.width = w; @@ -271,11 +298,9 @@ static void composite_update(GF_TextureHandler *txh) } else if (new_pixel_format==GF_PIXEL_RGB_565) { txh->stride = txh->width * 2; txh->transparent = 0; -#ifdef GPAC_TRISCOPE_MODE } else if (new_pixel_format==GF_PIXEL_RGBDS) { txh->stride = txh->width * 4; - txh->transparent = 1; -#endif + txh->transparent = 1; } /*RGB24*/ else { @@ -296,6 +321,7 @@ static void composite_update(GF_TextureHandler *txh) /*create an offscreen window for OpenGL rendering*/ if ((compositor->offscreen_width < st->txh.width) || (compositor->offscreen_height < st->txh.height)) { #ifndef GPAC_USE_TINYGL + GF_Err e; GF_Event evt; compositor->offscreen_width = MAX(compositor->offscreen_width, st->txh.width); compositor->offscreen_height = MAX(compositor->offscreen_height, st->txh.height); @@ -318,28 +344,15 @@ static void composite_update(GF_TextureHandler *txh) } } #endif - + if (needs_stencil) { -#ifndef TRISCOPE_TEST_MALLOC - txh->data = (char*)malloc(sizeof(unsigned char) * txh->stride * txh->height); -#else - if ( txh->data = (char*)gltx_malloc(sizeof(unsigned char) * txh->stride * txh->height) ) { - printf("\nRenoir object texture allocation: %d bytes\n", sizeof(unsigned char) * txh->stride * txh->height ) ; - printf("Renoir object texture allocated: Total %d Max %d\n",gltx_total_mem(),gltx_max_alloc()) ; - } else printf( "Renoir object texture could not be allocated!"); -#endif + txh->data = (char*)gf_malloc(sizeof(unsigned char) * txh->stride * txh->height); memset(txh->data, 0, sizeof(unsigned char) * txh->stride * txh->height); - e = raster->stencil_set_texture(stencil, txh->data, txh->width, txh->height, txh->stride, txh->pixelformat, txh->pixelformat, 0); -#ifdef GPAC_TRISCOPE_MODE - e = GF_OK; -#endif - if (e) { - raster->stencil_delete(stencil); - gf_sc_texture_release(txh); - free(txh->data); - txh->data = NULL; - return; - } + + /*set stencil texture - we don't check error as an image could not be supported by the rasterizer + but still supported by the blitter (case of RGBD/RGBDS)*/ + raster->stencil_set_texture(stencil, txh->data, txh->width, txh->height, txh->stride, txh->pixelformat, txh->pixelformat, 0); + #ifdef GPAC_USE_TINYGL if (st->visual->type_3d && !compositor->visual->type_3d) { st->tgl_ctx = ostgl_create_context(txh->width, txh->height, txh->transparent ? 32 : 24, &txh->data, 1); @@ -352,7 +365,7 @@ static void composite_update(GF_TextureHandler *txh) gf_sc_texture_set_stencil(txh, stencil); } if (!txh->tx_io) return; - + stencil = gf_sc_texture_get_stencil(txh); if (!stencil) return; @@ -365,9 +378,7 @@ static void composite_update(GF_TextureHandler *txh) tr_state->visual = st->visual; tr_state->invalidate_all = invalidate_all; - if (st->visual->compositor->traverse_state->direct_draw) { - tr_state->direct_draw = 1; - } + tr_state->immediate_draw = st->visual->compositor->traverse_state->immediate_draw; gf_mx2d_init(tr_state->transform); gf_cmx_init(&tr_state->color_mat); @@ -381,13 +392,16 @@ static void composite_update(GF_TextureHandler *txh) composite_do_bindable(st->txh.owner, tr_state, st->first); st->first = 0; - + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[CompositeTexture] Entering draw cycle\n")); txh->needs_refresh = visual_draw_frame(st->visual, st->txh.owner, tr_state, 0); - + txh->transparent = (st->visual->last_had_back==2) ? 0 : 1; + /*remove any GL_FLIP flag*/ + txh->flags &= ~GF_SR_TEXTURE_NO_GL_FLIP; + /*set active viewport in image coordinates top-left=(0, 0), not in BIFS*/ - if (gf_list_count(st->visual->view_stack)) { + if (0 && gf_list_count(st->visual->view_stack)) { M_Viewport *vp = (M_Viewport *)gf_list_get(st->visual->view_stack, 0); if (vp->isBound) { @@ -397,10 +411,9 @@ static void composite_update(GF_TextureHandler *txh) txh->needs_refresh = 1; } } - } + } if (txh->needs_refresh) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[CompositeTexture] First 4 pixel %x %x %x %x\n", txh->data[0], txh->data[4], txh->data[8], txh->data[12])); #ifndef GPAC_DISABLE_3D if (st->visual->camera.is_3D) { if (st->visual->compositor->visual->type_3d) { @@ -411,31 +424,30 @@ static void composite_update(GF_TextureHandler *txh) gf_sc_texture_push_image(&st->txh, 0, 0); #endif } else { - + #ifndef GPAC_USE_TINYGL gf_sc_copy_to_stencil(&st->txh); - -#else -#ifdef GPAC_TRISCOPE_MODE - if (txh->pixelformat==GF_PIXEL_RGBDS) gf_get_tinygl_depth(&st->txh); -#endif + +#else + + if (txh->pixelformat==GF_PIXEL_RGBDS) gf_get_tinygl_depth(&st->txh); #endif } - } else + } else #endif { - if (raster->stencil_texture_modified) raster->stencil_texture_modified(stencil); + if (raster->stencil_texture_modified) raster->stencil_texture_modified(stencil); gf_sc_texture_set_stencil(txh, stencil); } gf_sc_invalidate(st->txh.compositor, NULL); } gf_list_del(tr_state->vrml_sensors); - free(tr_state); + gf_free(tr_state); GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[CompositeTexture] Leaving draw cycle\n")); } -static GF_Err composite_get_video_access(GF_VisualManager *visual) +GF_Err composite_get_video_access(GF_VisualManager *visual) { GF_STENCIL stencil; GF_Err e; @@ -449,7 +461,7 @@ static GF_Err composite_get_video_access(GF_VisualManager *visual) return e; } -static void composite_release_video_access(GF_VisualManager *visual) +void composite_release_video_access(GF_VisualManager *visual) { visual->compositor->rasterizer->surface_detach(visual->raster_surface); } @@ -459,10 +471,15 @@ void compositor_init_compositetexture2d(GF_Compositor *compositor, GF_Node *node M_CompositeTexture2D *c2d = (M_CompositeTexture2D *)node; CompositeTextureStack *st; GF_SAFEALLOC(st, CompositeTextureStack); + st->sensors = gf_list_new(); + st->previous_sensors = gf_list_new(); gf_sc_texture_setup(&st->txh, compositor, node); + /*remove texture from compositor and add it at the end, so that any sub-textures are handled before*/ + gf_list_del_item(compositor->textures, &st->txh); + gf_list_add(compositor->textures, &st->txh); + st->txh.update_texture_fcnt = composite_update; -// st->txh.flags = GF_SR_TEXTURE_NO_GL_FLIP; if ((c2d->repeatSandT==1) || (c2d->repeatSandT==3) ) st->txh.flags |= GF_SR_TEXTURE_REPEAT_S; if (c2d->repeatSandT>1) st->txh.flags |= GF_SR_TEXTURE_REPEAT_T; @@ -487,10 +504,15 @@ void compositor_init_compositetexture3d(GF_Compositor *compositor, GF_Node *node M_CompositeTexture3D *c3d = (M_CompositeTexture3D *)node; CompositeTextureStack *st; GF_SAFEALLOC(st, CompositeTextureStack); + st->sensors = gf_list_new(); + st->previous_sensors = gf_list_new(); gf_sc_texture_setup(&st->txh, compositor, node); + /*remove texture from compositor and add it at the end, so that any sub-textures are handled before*/ + gf_list_del_item(compositor->textures, &st->txh); + gf_list_add(compositor->textures, &st->txh); + st->txh.update_texture_fcnt = composite_update; -// st->txh.flags = GF_SR_TEXTURE_NO_GL_FLIP; if (c3d->repeatS) st->txh.flags |= GF_SR_TEXTURE_REPEAT_S; if (c3d->repeatT) st->txh.flags |= GF_SR_TEXTURE_REPEAT_T; @@ -528,8 +550,11 @@ GF_TextureHandler *compositor_get_composite_texture(GF_Node *node) return &st->txh; } -Bool compositor_compositetexture_handle_event(GF_Compositor *compositor, GF_Event *ev) +Bool compositor_compositetexture_handle_event(GF_Compositor *compositor, GF_Node *composite_appear, GF_Event *ev, Bool is_flush) { + SFVec3f point; + GF_Ray ray; + Fixed dist; GF_Matrix mx; GF_TraverseState *tr_state; GF_ChildNodeItem *children, *l; @@ -537,57 +562,112 @@ Bool compositor_compositetexture_handle_event(GF_Compositor *compositor, GF_Even u32 flags; SFVec3f txcoord; CompositeTextureStack *stack; - M_Appearance *ap = (M_Appearance *)compositor->hit_appear; + GF_List *tmp1, *tmp2; + GF_Node *appear, *prev_appear; + M_Appearance *ap = (M_Appearance *)composite_appear; assert(ap && ap->texture); if (ev->type > GF_EVENT_MOUSEMOVE) return 0; - stack = gf_node_get_private(ap->texture); + if (!stack->txh.tx_io) return 0; + + tr_state = NULL; + children = NULL; + + if (!is_flush) { + txcoord.x = compositor->hit_texcoords.x; + txcoord.y = compositor->hit_texcoords.y; + txcoord.z = 0; + flags = stack->txh.flags; + stack->txh.flags |= GF_SR_TEXTURE_NO_GL_FLIP; + if (gf_sc_texture_get_transform(&stack->txh, ap->textureTransform, &mx)) { + /*tx coords are inverted when mapping, thus applying directly the matrix will give us the + untransformed coords*/ + gf_mx_apply_vec(&mx, &txcoord); + while (txcoord.x<0) txcoord.x += FIX_ONE; while (txcoord.x>FIX_ONE) txcoord.x -= FIX_ONE; + while (txcoord.y<0) txcoord.y += FIX_ONE; while (txcoord.y>FIX_ONE) txcoord.y -= FIX_ONE; + } + stack->txh.flags = flags; + /*convert to tx space*/ + ev->mouse.x = FIX2INT( (txcoord.x - FIX_ONE/2) * stack->visual->width + FIX_ONE/2); + ev->mouse.y = FIX2INT( (txcoord.y - FIX_ONE/2) * stack->visual->height + FIX_ONE/2); + + + GF_SAFEALLOC(tr_state, GF_TraverseState); + tr_state->vrml_sensors = gf_list_new(); + tr_state->visual = stack->visual; + tr_state->traversing_mode = TRAVERSE_PICK; + tr_state->pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(ap->texture)); + tr_state->vp_size.x = INT2FIX(stack->txh.width); + tr_state->vp_size.y = INT2FIX(stack->txh.height); + tr_state->color_mat.identity = 1; + + gf_mx2d_init(tr_state->transform); +#ifndef GPAC_DISABLE_3D + gf_mx_init(tr_state->model_matrix); +#endif + /*collect sensors*/ + l = children = ((M_CompositeTexture2D*)ap->texture)->children; + while (l) { + GF_SensorHandler *hsens = compositor_mpeg4_get_sensor_handler(l->node); + if (hsens) gf_list_add(tr_state->vrml_sensors, hsens); + l = l->next; + } + } - txcoord.x = compositor->hit_texcoords.x; - txcoord.y = compositor->hit_texcoords.y; - txcoord.z = 0; - flags = stack->txh.flags; - stack->txh.flags |= GF_SR_TEXTURE_NO_GL_FLIP; - if (gf_sc_texture_get_transform(&stack->txh, ap->textureTransform, &mx)) { - /*tx coords are inverted when mapping, thus applying directly the matrix will give us the - untransformed coords*/ - gf_mx_apply_vec(&mx, &txcoord); - while (txcoord.x<0) txcoord.x += FIX_ONE; while (txcoord.x>FIX_ONE) txcoord.x -= FIX_ONE; - while (txcoord.y<0) txcoord.y += FIX_ONE; while (txcoord.y>FIX_ONE) txcoord.y -= FIX_ONE; + tmp1 = compositor->sensors; + tmp2 = compositor->previous_sensors; + compositor->sensors = stack->sensors; + compositor->previous_sensors = stack->previous_sensors; + + point = compositor->hit_world_point; + ray = compositor->hit_world_ray; + dist = compositor->hit_square_dist; + prev_appear = compositor->prev_hit_appear; + compositor->prev_hit_appear = stack->prev_hit_appear; + appear = compositor->hit_appear; + compositor->hit_appear = NULL; + + if (is_flush) { + res = 0; + gf_list_reset(stack->sensors); + gf_sc_exec_event_vrml(compositor, ev); + } else { + res = visual_execute_event(stack->visual, tr_state, ev, children); } - stack->txh.flags = flags; - /*convert to tx space*/ - ev->mouse.x = FIX2INT( (txcoord.x - FIX_ONE/2) * stack->visual->width); - ev->mouse.y = FIX2INT( (txcoord.y - FIX_ONE/2) * stack->visual->height); + stack->prev_hit_appear = compositor->prev_hit_appear; + compositor->prev_hit_appear = prev_appear; + compositor->hit_appear = appear; - GF_SAFEALLOC(tr_state, GF_TraverseState); - tr_state->vrml_sensors = gf_list_new(); - tr_state->visual = stack->visual; - tr_state->traversing_mode = TRAVERSE_PICK; - tr_state->pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(ap->texture)); - tr_state->vp_size.x = INT2FIX(stack->txh.width); - tr_state->vp_size.y = INT2FIX(stack->txh.height); + compositor->hit_world_point = point; + compositor->hit_world_ray = ray; + compositor->hit_square_dist = dist; - gf_mx2d_init(tr_state->transform); + stack->sensors = compositor->sensors; + stack->previous_sensors = compositor->previous_sensors; + compositor->sensors = tmp1; + compositor->previous_sensors = tmp2; + + + if (!is_flush) { + gf_list_del(tr_state->vrml_sensors); #ifndef GPAC_DISABLE_3D - gf_mx_init(tr_state->model_matrix); + if (tr_state->layer3d) compositor->traverse_state->layer3d = tr_state->layer3d; #endif - /*collect sensors*/ - l = children = ((M_CompositeTexture2D*)ap->texture)->children; - while (l) { - GF_SensorHandler *hsens = compositor_mpeg4_get_sensor_handler(l->node); - if (hsens) gf_list_add(tr_state->vrml_sensors, hsens); - l = l->next; + gf_free(tr_state); } - - res = visual_execute_event(stack->visual, tr_state, ev, children); - gf_list_del(tr_state->vrml_sensors); - free(tr_state); return res; } +void compositor_compositetexture_sensor_delete(GF_Node *composite_appear, GF_SensorHandler *hdl) +{ + CompositeTextureStack *stack = gf_node_get_private(composite_appear); + gf_list_del_item(stack->previous_sensors, hdl); + gf_list_del_item(stack->sensors, hdl); +} + + void compositor_adjust_scale(GF_Node *node, Fixed *sx, Fixed *sy) { switch (gf_node_get_tag(node)) { @@ -609,7 +689,11 @@ Bool compositor_is_composite_texture(GF_Node *appear) u32 tag; if (!appear) return 0; tag = gf_node_get_tag(appear); - if ((tag==TAG_MPEG4_Appearance) || (tag==TAG_X3D_Appearance)) { + if ((tag==TAG_MPEG4_Appearance) +#ifndef GPAC_DISABLE_X3D + || (tag==TAG_X3D_Appearance) +#endif + ) { M_Appearance *ap = (M_Appearance *)appear; if (!ap->texture) return 0; switch (gf_node_get_tag(((M_Appearance *)appear)->texture)) { @@ -620,3 +704,5 @@ Bool compositor_is_composite_texture(GF_Node *appear) } return 0; } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_form.c b/src/compositor/mpeg4_form.c index 7212613..d669440 100644 --- a/src/compositor/mpeg4_form.c +++ b/src/compositor/mpeg4_form.c @@ -28,9 +28,12 @@ #include "mpeg4_grouping.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + + typedef struct { - PARENT_NODE_STACK_2D + PARENT_MPEG4_STACK_2D GF_List *grouplist; GF_Rect clip; @@ -50,7 +53,7 @@ static void form_reset(FormStack *st) FormGroup * fg = (FormGroup *) gf_list_get(st->grouplist, 0); gf_list_rem(st->grouplist, 0); gf_list_del(fg->children); - free(fg); + gf_free(fg); } } @@ -217,7 +220,7 @@ static void TraverseForm(GF_Node *n, void *rs, Bool is_destroy) form_reset(st); gf_list_del(st->grouplist); parent_node_predestroy((ParentNode2D *)st); - free(st); + gf_free(st); return; } /*update cliper*/ @@ -233,7 +236,7 @@ static void TraverseForm(GF_Node *n, void *rs, Bool is_destroy) if (gf_node_dirty_get(n)) recompute_form = 1; #if FORM_CLIPS - if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { + if ((tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) && !tr_state->for_node) { tr_state->bounds = st->clip; #ifndef GPAC_DISABLE_3D gf_bbox_from_rect(&tr_state->bbox, &st->clip); @@ -324,7 +327,7 @@ static void TraverseForm(GF_Node *n, void *rs, Bool is_destroy) return; #if !FORM_CLIPS - if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { + if ((tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) && !tr_state->for_node) { tr_state->bounds = st->clip; gf_bbox_from_rect(&tr_state->bbox, &st->clip); return; @@ -672,3 +675,5 @@ static void av_apply(FormStack *st, u32 *group_idx, u32 count) fg_update_bounds(form_get_group(st, group_idx[i])); } } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_geometry_2d.c b/src/compositor/mpeg4_geometry_2d.c index bb07cfc..2850f3b 100644 --- a/src/compositor/mpeg4_geometry_2d.c +++ b/src/compositor/mpeg4_geometry_2d.c @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -47,8 +47,10 @@ Bool compositor_get_2d_plane_intersection(GF_Ray *ray, SFVec3f *res) return 1; } +#ifndef GPAC_DISABLE_VRML + /* - Shape + Shape */ static void TraverseShape(GF_Node *node, void *rs, Bool is_destroy) { @@ -67,12 +69,12 @@ static void TraverseShape(GF_Node *node, void *rs, Bool is_destroy) /*reset this node dirty flag (because bitmap may trigger bounds invalidation on the fly)*/ gf_node_dirty_clear(node, 0); - + /*check traverse mode, and take care of switch-off flag*/ if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { GF_Node *m; tr_state->appear = (GF_Node *) shape->appearance; - + /*this is done regardless of switch flag*/ gf_node_traverse((GF_Node *) shape->geometry, tr_state); @@ -125,11 +127,11 @@ static void TraverseShape(GF_Node *node, void *rs, Bool is_destroy) break; #ifndef GPAC_DISABLE_3D /*if we're here we passed culler already*/ - case TRAVERSE_DRAW_3D: + case TRAVERSE_DRAW_3D: gf_node_traverse((GF_Node *) shape->geometry, tr_state); break; case TRAVERSE_COLLIDE: - visual_3d_drawable_collide(shape->geometry, tr_state); + visual_3d_vrml_drawable_collide(shape->geometry, tr_state); break; #endif } @@ -181,7 +183,7 @@ static void TraverseCircle(GF_Node *node, void *rs, Bool is_destroy) gf_path_get_bounds(stack->path, &tr_state->bounds); return; case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_SORT: #ifndef GPAC_DISABLE_3D @@ -233,7 +235,7 @@ static void TraverseEllipse(GF_Node *node, void *rs, Bool is_destroy) return; #endif case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_GET_BOUNDS: gf_path_get_bounds(stack->path, &tr_state->bounds); @@ -259,11 +261,11 @@ static void compositor_2d_draw_rectangle(GF_TraverseState *tr_state) { DrawableContext *ctx = tr_state->ctx; - if (ctx->aspect.fill_texture) { + if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->data) { Bool res; - /*get image size WITHOUT line size*/ - if (ctx->aspect.pen_props.width) { + /*get image size WITHOUT line size or antialias margin*/ + if ( !(ctx->flags & CTX_NO_ANTIALIAS) ) { GF_Rect orig_unclip; GF_IRect orig_clip; orig_unclip = ctx->bi->unclip; @@ -288,7 +290,7 @@ static void compositor_2d_draw_rectangle(GF_TraverseState *tr_state) } /*if failure retry with raster*/ if (res) return; - } + } visual_2d_texture_path(tr_state->visual, ctx->drawable->path, ctx, tr_state); visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state); @@ -326,13 +328,13 @@ static void TraverseRectangle(GF_Node *node, void *rs, Bool is_destroy) case TRAVERSE_DRAW_3D: if (!stack->mesh) { stack->mesh = new_mesh(); - mesh_new_rectangle(stack->mesh, ((M_Rectangle *) node)->size); + mesh_new_rectangle(stack->mesh, ((M_Rectangle *) node)->size, NULL, 0); } visual_3d_draw_2d(stack, tr_state); return; #endif case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_GET_BOUNDS: gf_path_get_bounds(stack->path, &tr_state->bounds); @@ -349,21 +351,26 @@ static void TraverseRectangle(GF_Node *node, void *rs, Bool is_destroy) ctx = drawable_init_context_mpeg4(stack, tr_state); if (!ctx) return; - /*if alpha or not filled, transparent*/ - if (GF_COL_A(ctx->aspect.fill_color) != 0xFF) { - } - /*if texture transparent, transparent*/ - else if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->transparent) { - } - /*if rotated, transparent (doesn't fill bounds)*/ - else if (ctx->transform.m[1] || ctx->transform.m[3]) { - } - /*TODO check matrix for alpha*/ - else if (!tr_state->color_mat.identity) { + /*if rotated, object is transparent (doesn't fill bounds) and antialias must be used*/ + if (tr_state->transform.m[1] || tr_state->transform.m[3]) { } - /*otherwsie, not transparent*/ else { - ctx->flags &= ~CTX_IS_TRANSPARENT; + + /*if alpha or not filled, transparent*/ + if (ctx->aspect.fill_color && (GF_COL_A(ctx->aspect.fill_color) != 0xFF)) { + } + /*if texture transparent, transparent*/ + else if (ctx->aspect.fill_texture && ctx->aspect.fill_texture->transparent) { + } + /*TODO check matrix for alpha*/ + else if (!tr_state->color_mat.identity) { + } + /*otherwise, not transparent*/ + else { + ctx->flags &= ~CTX_IS_TRANSPARENT; + } + /*if no line width, we skip antialiasing*/ + if (!ctx->aspect.pen_props.width) ctx->flags |= CTX_NO_ANTIALIAS; } drawable_finalize_sort(ctx, tr_state, NULL); } @@ -378,7 +385,7 @@ void compositor_init_rectangle(GF_Compositor *compositor, GF_Node *node) #define CHECK_VALID_C2D(nbPts) if (!idx && cur_index+nbPts>=pt_count) { gf_path_reset(stack->path); return; } //#define CHECK_VALID_C2D(nbPts) -#define GET_IDX(_i) ((idx && idx->count>_i) ? idx->vals[_i] : _i) +#define GET_IDX(_i) ((idx && (idx->count>_i) && (idx->vals[_i]>=0) ) ? (u32) idx->vals[_i] : _i) void curve2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state, MFInt32 *idx) { @@ -398,7 +405,7 @@ void curve2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_ pts = coord->point.vals; - if (!pts) + if (!pts) return; cur_index = c2D->type.count ? 1 : 0; @@ -454,7 +461,7 @@ void curve2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_ ct_orig = ct_end; orig = end; break; - + /*all XCurve2D specific*/ /*CW and CCW ArcTo*/ @@ -496,7 +503,7 @@ void curve2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_ if (remain>1) gf_path_add_bezier(stack->path, &pts[cur_index], remain); } - + gf_node_dirty_clear(node, 0); drawable_mark_modified(stack, tr_state); } @@ -526,7 +533,7 @@ static void TraverseCurve2D(GF_Node *node, void *rs, Bool is_destroy) return; #endif case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_GET_BOUNDS: gf_path_get_bounds(stack->path, &tr_state->bounds); @@ -551,7 +558,7 @@ void compositor_init_curve2d(GF_Compositor *compositor, GF_Node *node) /* - Note on point set 2D: this is a very bad node and should be avoided in DEF/USE, since the size + Note on point set 2D: this is a very bad node and should be avoided in DEF/USE, since the size of the rectangle representing the pixel shall always be 1 pixel w/h, therefore the path object is likely not the same depending on transformation context... @@ -578,11 +585,11 @@ static void pointset2d_check_changes(GF_Node *node, Drawable *stack, GF_Traverse get_point_size(&tr_state->transform, &w, &h); /*for PS2D don't add to avoid too much antialiasing, just try to fill the given pixel*/ - for (i=0; i < coord->point.count; i++) + for (i=0; i < coord->point.count; i++) gf_path_add_rect(stack->path, coord->point.vals[i].x, coord->point.vals[i].y, w, h); stack->path->flags |= GF_PATH_FILL_ZERO_NONZERO; - + gf_node_dirty_clear(node, 0); drawable_mark_modified(stack, tr_state); } @@ -627,7 +634,7 @@ static void TraversePointSet2D(GF_Node *node, void *rs, Bool is_destroy) M_PointSet2D *ps2D = (M_PointSet2D *)node; Drawable *stack = (Drawable *)gf_node_get_private(node); GF_TraverseState *tr_state = (GF_TraverseState *)rs; - + if (is_destroy) { drawable_node_del(node); return; @@ -654,7 +661,7 @@ static void TraversePointSet2D(GF_Node *node, void *rs, Bool is_destroy) visual_3d_set_material_2d_argb(tr_state->visual, asp.fill_color); visual_3d_mesh_paint(tr_state, stack->mesh); return; - } + } #endif case TRAVERSE_GET_BOUNDS: gf_path_get_bounds(stack->path, &tr_state->bounds); @@ -681,3 +688,5 @@ void compositor_init_pointset2d(GF_Compositor *compositor, GF_Node *node) stack->flags = DRAWABLE_USE_TRAVERSE_DRAW; gf_node_set_callback_function(node, TraversePointSet2D); } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_geometry_3d.c b/src/compositor/mpeg4_geometry_3d.c index ac4163f..a2689ac 100644 --- a/src/compositor/mpeg4_geometry_3d.c +++ b/src/compositor/mpeg4_geometry_3d.c @@ -26,6 +26,9 @@ #include "visual_manager.h" #include "nodes_stacks.h" + +#ifndef GPAC_DISABLE_VRML + #ifndef GPAC_DISABLE_3D #include <gpac/options.h> @@ -55,7 +58,7 @@ void drawable_3d_base_traverse(GF_Node *n, void *rs, Bool is_destroy, void (*bui tr_state->bbox = stack->mesh->bounds; break; case TRAVERSE_PICK: - visual_3d_drawable_pick(n, tr_state, stack->mesh, NULL); + visual_3d_vrml_drawable_pick(n, tr_state, stack->mesh, NULL); return; } } @@ -152,28 +155,28 @@ static void TraverseIFS(GF_Node *n, void *rs, Bool is_destroy) drawable_3d_base_traverse(n, rs, is_destroy, build_shape_ifs); } -static void IFS_SetColorIndex(GF_Node *node) +static void IFS_SetColorIndex(GF_Node *node, GF_Route *route) { M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node; gf_sg_vrml_field_copy(&ifs->colorIndex, &ifs->set_colorIndex, GF_SG_VRML_MFINT32); gf_sg_vrml_mf_reset(&ifs->set_colorIndex, GF_SG_VRML_MFINT32); } -static void IFS_SetCoordIndex(GF_Node *node) +static void IFS_SetCoordIndex(GF_Node *node, GF_Route *route) { M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node; gf_sg_vrml_field_copy(&ifs->coordIndex, &ifs->set_coordIndex, GF_SG_VRML_MFINT32); gf_sg_vrml_mf_reset(&ifs->set_coordIndex, GF_SG_VRML_MFINT32); } -static void IFS_SetNormalIndex(GF_Node *node) +static void IFS_SetNormalIndex(GF_Node *node, GF_Route *route) { M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node; gf_sg_vrml_field_copy(&ifs->normalIndex, &ifs->set_normalIndex, GF_SG_VRML_MFINT32); gf_sg_vrml_mf_reset(&ifs->set_normalIndex, GF_SG_VRML_MFINT32); } -static void IFS_SetTexCoordIndex(GF_Node *node) +static void IFS_SetTexCoordIndex(GF_Node *node, GF_Route *route) { M_IndexedFaceSet *ifs = (M_IndexedFaceSet *)node; gf_sg_vrml_field_copy(&ifs->texCoordIndex, &ifs->set_texCoordIndex, GF_SG_VRML_MFINT32); @@ -202,14 +205,14 @@ static void TraverseILS(GF_Node *n, void *rs, Bool is_destroy) drawable_3d_base_traverse(n, rs, is_destroy, build_shape_ils); } -static void ILS_SetColorIndex(GF_Node *node) +static void ILS_SetColorIndex(GF_Node *node, GF_Route *route) { M_IndexedLineSet *ils = (M_IndexedLineSet *)node; gf_sg_vrml_field_copy(&ils->colorIndex, &ils->set_colorIndex, GF_SG_VRML_MFINT32); gf_sg_vrml_mf_reset(&ils->set_colorIndex, GF_SG_VRML_MFINT32); } -static void ILS_SetCoordIndex(GF_Node *node) +static void ILS_SetCoordIndex(GF_Node *node, GF_Route *route) { M_IndexedLineSet *ils = (M_IndexedLineSet *)node; gf_sg_vrml_field_copy(&ils->coordIndex, &ils->set_coordIndex, GF_SG_VRML_MFINT32); @@ -236,7 +239,7 @@ static void TraverseElevationGrid(GF_Node *n, void *rs, Bool is_destroy) drawable_3d_base_traverse(n, rs, is_destroy, build_shape_elevation_grid); } -static void ElevationGrid_SetHeight(GF_Node *node) +static void ElevationGrid_SetHeight(GF_Node *node, GF_Route *route) { M_ElevationGrid *eg = (M_ElevationGrid *)node; gf_sg_vrml_field_copy(&eg->height, &eg->set_height, GF_SG_VRML_MFFLOAT); @@ -261,25 +264,25 @@ static void TraverseExtrusion(GF_Node *n, void *rs, Bool is_destroy) drawable_3d_base_traverse(n, rs, is_destroy, build_shape_extrusion); } -static void Extrusion_SetCrossSection(GF_Node *node) +static void Extrusion_SetCrossSection(GF_Node *node, GF_Route *route) { M_Extrusion *eg = (M_Extrusion *)node; gf_sg_vrml_field_copy(&eg->crossSection, &eg->set_crossSection, GF_SG_VRML_MFVEC2F); gf_sg_vrml_mf_reset(&eg->set_crossSection, GF_SG_VRML_MFVEC2F); } -static void Extrusion_SetOrientation(GF_Node *node) +static void Extrusion_SetOrientation(GF_Node *node, GF_Route *route) { M_Extrusion *eg = (M_Extrusion *)node; gf_sg_vrml_field_copy(&eg->orientation, &eg->set_orientation, GF_SG_VRML_MFROTATION); gf_sg_vrml_mf_reset(&eg->set_orientation, GF_SG_VRML_MFROTATION); } -static void Extrusion_SetScale(GF_Node *node) +static void Extrusion_SetScale(GF_Node *node, GF_Route *route) { M_Extrusion *eg = (M_Extrusion *)node; gf_sg_vrml_field_copy(&eg->scale, &eg->set_scale, GF_SG_VRML_MFVEC2F); gf_sg_vrml_mf_reset(&eg->set_scale, GF_SG_VRML_MFVEC2F); } -static void Extrusion_SetSpine(GF_Node *node) +static void Extrusion_SetSpine(GF_Node *node, GF_Route *route) { M_Extrusion *eg = (M_Extrusion *)node; gf_sg_vrml_field_copy(&eg->spine, &eg->set_spine, GF_SG_VRML_MFVEC3F); @@ -521,3 +524,5 @@ void compositor_init_non_linear_deformer(GF_Compositor *compositor, GF_Node *nod } #endif /*GPAC_DISABLE_3D*/ + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_geometry_ifs2d.c b/src/compositor/mpeg4_geometry_ifs2d.c index 58e44cc..95d1760 100644 --- a/src/compositor/mpeg4_geometry_ifs2d.c +++ b/src/compositor/mpeg4_geometry_ifs2d.c @@ -27,6 +27,8 @@ #include "nodes_stacks.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + static void ifs2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state) { u32 i; @@ -199,7 +201,7 @@ static void IFS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) alpha = INT2FIX(GF_COL_A(ctx->aspect.fill_color) ) / 255; - colors = (u32*)malloc(sizeof(u32) * num_col); + colors = (u32*)gf_malloc(sizeof(u32) * num_col); col_cen.blue = col_cen.red = col_cen.green = 0; for (j=0; j<num_col-1; j++) { if (ifs2D->colorIndex.count > ind_col + j) { @@ -226,7 +228,7 @@ static void IFS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) raster->stencil_set_vertex_path(grad, path); raster->stencil_set_vertex_colors(grad, colors, num_col); - free(colors); + gf_free(colors); col_cen.blue /= num_col; col_cen.green /= num_col; @@ -293,13 +295,13 @@ static void TraverseIFS2D(GF_Node *node, void *rs, Bool is_destroy) } visual_3d_mesh_strike(tr_state, si->mesh_outline, asp.pen_props.width, asp.line_scale, asp.pen_props.dash); } else { - visual_3d_draw_2d_with_aspect(stack, tr_state, &asp, 0); + visual_3d_draw_2d_with_aspect(stack, tr_state, &asp); } return; } #endif case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_GET_BOUNDS: gf_path_get_bounds(stack->path, &tr_state->bounds); @@ -316,14 +318,14 @@ static void TraverseIFS2D(GF_Node *node, void *rs, Bool is_destroy) } } -static void IFS2D_SetColorIndex(GF_Node *node) +static void IFS2D_SetColorIndex(GF_Node *node, GF_Route *route) { M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node; gf_sg_vrml_field_copy(&ifs2D->colorIndex, &ifs2D->set_colorIndex, GF_SG_VRML_MFINT32); gf_sg_vrml_mf_reset(&ifs2D->set_colorIndex, GF_SG_VRML_MFINT32); } -static void IFS2D_SetCoordIndex(GF_Node *node) +static void IFS2D_SetCoordIndex(GF_Node *node, GF_Route *route) { M_IndexedFaceSet2D *ifs2D = (M_IndexedFaceSet2D *)node; gf_sg_vrml_field_copy(&ifs2D->coordIndex, &ifs2D->set_coordIndex, GF_SG_VRML_MFINT32); @@ -340,3 +342,4 @@ void compositor_init_indexed_face_set2d(GF_Compositor *compositor, GF_Node *node ifs2D->on_set_coordIndex = IFS2D_SetCoordIndex; } +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_geometry_ils2d.c b/src/compositor/mpeg4_geometry_ils2d.c index 136e776..26ba0a3 100644 --- a/src/compositor/mpeg4_geometry_ils2d.c +++ b/src/compositor/mpeg4_geometry_ils2d.c @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -27,6 +27,8 @@ #include "nodes_stacks.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + static void ils2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state) { u32 i; @@ -36,7 +38,7 @@ static void ils2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState M_Coordinate2D *coord; if (! gf_node_dirty_get(node)) return; - + drawable_reset_path(stack); gf_node_dirty_clear(node, 0); drawable_mark_modified(stack, tr_state); @@ -92,7 +94,7 @@ static void ILS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) visual_2d_draw_path(tr_state->visual, ctx->drawable->path, ctx, NULL, NULL, tr_state); return; } - + alpha = INT2FIX(GF_COL_A(ctx->aspect.line_color)) / 255; pts = coord->point.vals; @@ -109,7 +111,7 @@ static void ILS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) if ((i==end_at) || (ils2D->coordIndex.count && ils2D->coordIndex.vals[i] == -1)) { /*draw current*/ - col_ind = (ils2D->colorIndex.count) ? ils2D->colorIndex.vals[count] : count; + col_ind = (ils2D->colorIndex.count && (ils2D->colorIndex.vals[count]>=0) ) ? (u32) ils2D->colorIndex.vals[count] : count; if (col_ind>=color->color.count) col_ind=color->color.count-1; col = color->color.vals[col_ind]; ctx->aspect.line_color = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); @@ -120,20 +122,20 @@ static void ILS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) if (i>=end_at) break; gf_path_reset(path); - ind = ils2D->coordIndex.count ? ils2D->coordIndex.vals[i] : i; + ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0)) ? (u32) ils2D->coordIndex.vals[i] : i; gf_path_add_move_to(path, pts[ind].x, pts[ind].y); if (ils2D->coordIndex.count) count++; continue; } else { - ind = ils2D->coordIndex.count ? ils2D->coordIndex.vals[i] : i; + ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0) ) ? (u32) ils2D->coordIndex.vals[i] : i; gf_path_add_line_to(path, pts[ind].x, pts[ind].y); } } gf_path_del(path); return; } - + raster = NULL; end_at = ils2D->coordIndex.count; if (!end_at) end_at = coord->point.count; @@ -144,7 +146,7 @@ static void ILS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) path = gf_path_new(); while (1) { gf_path_reset(path); - ind = ils2D->coordIndex.count ? ils2D->coordIndex.vals[i] : i; + ind = (ils2D->coordIndex.count && (ils2D->coordIndex.vals[i]>=0)) ? (u32) ils2D->coordIndex.vals[i] : i; start = pts[ind]; num_col = 1; i++; @@ -196,7 +198,7 @@ static void ILS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) if (grad) { raster->stencil_set_vertex_path(grad, path); - colors = (u32*)malloc(sizeof(u32) * num_col); + colors = (u32*)gf_malloc(sizeof(u32) * num_col); for (j=0; j<num_col; j++) { if (ils2D->colorIndex.count>0) { col = color->color.vals[ils2D->colorIndex.vals[col_ind+j]]; @@ -208,7 +210,7 @@ static void ILS2D_Draw(GF_Node *node, GF_TraverseState *tr_state) colors[j] = GF_COL_ARGB_FIXED(alpha, col.red, col.green, col.blue); } raster->stencil_set_vertex_colors(grad, colors, num_col); - free(colors); + gf_free(colors); } } raster->stencil_set_matrix(grad, &ctx->transform); @@ -262,7 +264,7 @@ static void TraverseILS2D(GF_Node *node, void *rs, Bool is_destroy) return; #endif case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_GET_BOUNDS: gf_path_get_bounds(stack->path, &tr_state->bounds); @@ -283,14 +285,14 @@ static void TraverseILS2D(GF_Node *node, void *rs, Bool is_destroy) } } -static void ILS2D_SetColorIndex(GF_Node *node) +static void ILS2D_SetColorIndex(GF_Node *node, GF_Route *route) { M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node; gf_sg_vrml_field_copy(&ils2D->colorIndex, &ils2D->set_colorIndex, GF_SG_VRML_MFINT32); gf_sg_vrml_mf_reset(&ils2D->set_colorIndex, GF_SG_VRML_MFINT32); } -static void ILS2D_SetCoordIndex(GF_Node *node) +static void ILS2D_SetCoordIndex(GF_Node *node, GF_Route *route) { M_IndexedLineSet2D *ils2D = (M_IndexedLineSet2D *)node; gf_sg_vrml_field_copy(&ils2D->coordIndex, &ils2D->set_coordIndex, GF_SG_VRML_MFINT32); @@ -306,3 +308,5 @@ void compositor_init_indexed_line_set2d(GF_Compositor *compositor, GF_Node *node ils2D->on_set_colorIndex = ILS2D_SetColorIndex; ils2D->on_set_coordIndex = ILS2D_SetCoordIndex; } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_gradients.c b/src/compositor/mpeg4_gradients.c index b0c7de9..27374de 100644 --- a/src/compositor/mpeg4_gradients.c +++ b/src/compositor/mpeg4_gradients.c @@ -25,17 +25,24 @@ #include "nodes_stacks.h" #include "texturing.h" +#ifndef GPAC_DISABLE_VRML + #define GRAD_TEXTURE_SIZE 128 #define GRAD_TEXTURE_HSIZE 64 +enum +{ + GF_SR_TEXTURE_GRAD_REGISTERED = 1<<6, + GF_SR_TEXTURE_GRAD_NO_RGB = 1<<7, +}; + /*linear/radial gradient*/ typedef struct { GF_TextureHandler txh; char *tx_data; - Bool transparent; - Bool no_rgb_support; +// Bool no_rgb_support; } GradientStack; void GradientGetMatrix(GF_Node *transform, GF_Matrix2D *mat) @@ -70,8 +77,8 @@ static void DestroyGradient(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { GradientStack *st = (GradientStack *) gf_node_get_private(node); gf_sc_texture_destroy(&st->txh); - if (st->tx_data) free(st->tx_data); - free(st); + if (st->tx_data) gf_free(st->tx_data); + gf_free(st); } } @@ -90,7 +97,11 @@ static void UpdateLinearGradient(GF_TextureHandler *txh) } if (lg->key.count > lg->keyValue.count) return; - if (!txh->tx_io) gf_sc_texture_allocate(txh); + if (!txh->tx_io) { + gf_node_dirty_set(gf_node_get_parent(txh->owner, 0), 0, 1); + gf_node_dirty_set(txh->owner, 0, 1); + gf_sc_texture_allocate(txh); + } stencil = gf_sc_texture_get_stencil(txh); if (!stencil) stencil = txh->compositor->rasterizer->stencil_new(txh->compositor->rasterizer, GF_STENCIL_LINEAR_GRADIENT); @@ -102,14 +113,14 @@ static void UpdateLinearGradient(GF_TextureHandler *txh) st->txh.transparent = 0; const_a = (lg->opacity.count == 1) ? 1 : 0; - cols = (u32*)malloc(sizeof(u32) * lg->key.count); + cols = (u32*)gf_malloc(sizeof(u32) * lg->key.count); for (i=0; i<lg->key.count; i++) { a = (const_a ? lg->opacity.vals[0] : lg->opacity.vals[i]); cols[i] = GF_COL_ARGB_FIXED(a, lg->keyValue.vals[i].red, lg->keyValue.vals[i].green, lg->keyValue.vals[i].blue); if (a != FIX_ONE) txh->transparent = 1; } txh->compositor->rasterizer->stencil_set_gradient_interpolation(stencil, lg->key.vals, cols, lg->key.count); - free(cols); + gf_free(cols); txh->compositor->rasterizer->stencil_set_gradient_mode(stencil, (GF_GradientMode) lg->spreadMethod); } @@ -159,9 +170,14 @@ static void BuildLinearGradientTexture(GF_TextureHandler *txh) if (!txh->tx_io) return; + if (!(txh->flags & GF_SR_TEXTURE_GRAD_REGISTERED)) { + txh->flags |= GF_SR_TEXTURE_GRAD_REGISTERED; + if (gf_list_find(txh->compositor->textures, txh)<0) + gf_list_insert(txh->compositor->textures, txh, 0); + } if (st->tx_data) { - free(st->tx_data); + gf_free(st->tx_data); st->tx_data = NULL; } @@ -182,38 +198,38 @@ static void BuildLinearGradientTexture(GF_TextureHandler *txh) return; } - if (st->no_rgb_support) transparent = 1; - if (st->tx_data && (st->transparent != transparent)) { - free(st->tx_data); + if (st->txh.flags & GF_SR_TEXTURE_GRAD_NO_RGB) transparent = 1; + if (st->tx_data && (st->txh.transparent != transparent)) { + gf_free(st->tx_data); st->tx_data = NULL; } if (transparent) { if (!st->tx_data) { - st->tx_data = (char *) malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); + st->tx_data = (char *) gf_malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); } else { memset(st->tx_data, 0, sizeof(char)*txh->stride*txh->height); } e = raster->stencil_set_texture(texture2D, st->tx_data, GRAD_TEXTURE_SIZE, GRAD_TEXTURE_SIZE, 4*GRAD_TEXTURE_SIZE, GF_PIXEL_ARGB, GF_PIXEL_ARGB, 1); } else { if (!st->tx_data) { - st->tx_data = (char *) malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*3); + st->tx_data = (char *) gf_malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*3); } e = raster->stencil_set_texture(texture2D, st->tx_data, GRAD_TEXTURE_SIZE, GRAD_TEXTURE_SIZE, 3*GRAD_TEXTURE_SIZE, GF_PIXEL_RGB_24, GF_PIXEL_RGB_24, 1); /*try with ARGB (it actually is needed for GDIplus module since GDIplus cannot handle native RGB texture (it works in BGR)*/ if (e) { /*remember for later use*/ - st->no_rgb_support = 1; + st->txh.flags |= GF_SR_TEXTURE_GRAD_NO_RGB; transparent = 1; - free(st->tx_data); - st->tx_data = (char *) malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); + gf_free(st->tx_data); + st->tx_data = (char *) gf_malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); e = raster->stencil_set_texture(texture2D, st->tx_data, GRAD_TEXTURE_SIZE, GRAD_TEXTURE_SIZE, 4*GRAD_TEXTURE_SIZE, GF_PIXEL_ARGB, GF_PIXEL_ARGB, 1); } } - st->transparent = transparent; + st->txh.transparent = transparent; if (e) { - free(st->tx_data); + gf_free(st->tx_data); raster->stencil_delete(texture2D); raster->surface_delete(surface); return; @@ -239,13 +255,13 @@ static void BuildLinearGradientTexture(GF_TextureHandler *txh) end.y *= GRAD_TEXTURE_SIZE; raster->stencil_set_linear_gradient(stenc, start.x, start.y, end.x, end.y); const_a = (lg->opacity.count == 1) ? 1 : 0; - cols = (u32*)malloc(sizeof(u32) * lg->key.count); + cols = (u32*)gf_malloc(sizeof(u32) * lg->key.count); for (i=0; i<lg->key.count; i++) { a = (const_a ? lg->opacity.vals[0] : lg->opacity.vals[i]); cols[i] = GF_COL_ARGB_FIXED(a, lg->keyValue.vals[i].red, lg->keyValue.vals[i].green, lg->keyValue.vals[i].blue); } raster->stencil_set_gradient_interpolation(stenc, lg->key.vals, cols, lg->key.count); - free(cols); + gf_free(cols); raster->stencil_set_gradient_mode(stenc, (GF_GradientMode)lg->spreadMethod); /*fill surface*/ @@ -309,7 +325,11 @@ void compositor_init_linear_gradient(GF_Compositor *compositor, GF_Node *node) GradientStack *st; GF_SAFEALLOC(st, GradientStack); - gf_sc_texture_setup(&st->txh, compositor, node); + /*!!! Gradients are textures but are not registered as textures with the compositor in order to avoid updating + too many textures each frame - gradients are only registered with the compositor when they are used in OpenGL, in order + to release associated HW resource when no longer used*/ + st->txh.owner = node; + st->txh.compositor = compositor; st->txh.update_texture_fcnt = UpdateLinearGradient; st->txh.compute_gradient_matrix = LG_ComputeMatrix; @@ -339,8 +359,14 @@ static void BuildRadialGradientTexture(GF_TextureHandler *txh) if (!txh->tx_io) return; + if (!(txh->flags & GF_SR_TEXTURE_GRAD_REGISTERED)) { + txh->flags |= GF_SR_TEXTURE_GRAD_REGISTERED; + if (gf_list_find(txh->compositor->textures, txh)<0) + gf_list_insert(txh->compositor->textures, txh, 0); + } + if (st->tx_data) { - free(st->tx_data); + gf_free(st->tx_data); st->tx_data = NULL; } @@ -358,38 +384,38 @@ static void BuildRadialGradientTexture(GF_TextureHandler *txh) return; } - if (st->no_rgb_support) transparent = 1; - if (st->tx_data && (st->transparent != transparent)) { - free(st->tx_data); + if (st->txh.flags & GF_SR_TEXTURE_GRAD_NO_RGB) transparent = 1; + if (st->tx_data && (st->txh.transparent != transparent)) { + gf_free(st->tx_data); st->tx_data = NULL; } if (transparent) { if (!st->tx_data) { - st->tx_data = (char *) malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); + st->tx_data = (char *) gf_malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); } else { memset(st->tx_data, 0, sizeof(char)*txh->stride*txh->height); } e = raster->stencil_set_texture(texture2D, st->tx_data, GRAD_TEXTURE_SIZE, GRAD_TEXTURE_SIZE, 4*GRAD_TEXTURE_SIZE, GF_PIXEL_ARGB, GF_PIXEL_ARGB, 1); } else { if (!st->tx_data) { - st->tx_data = (char *) malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*3); + st->tx_data = (char *) gf_malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*3); } e = raster->stencil_set_texture(texture2D, st->tx_data, GRAD_TEXTURE_SIZE, GRAD_TEXTURE_SIZE, 3*GRAD_TEXTURE_SIZE, GF_PIXEL_RGB_24, GF_PIXEL_RGB_24, 1); /*try with ARGB (it actually is needed for GDIplus module since GDIplus cannot handle native RGB texture (it works in BGR)*/ if (e) { /*remember for later use*/ - st->no_rgb_support = 1; + st->txh.flags |= GF_SR_TEXTURE_GRAD_NO_RGB; transparent = 1; - free(st->tx_data); - st->tx_data = (char *) malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); + gf_free(st->tx_data); + st->tx_data = (char *) gf_malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); e = raster->stencil_set_texture(texture2D, st->tx_data, GRAD_TEXTURE_SIZE, GRAD_TEXTURE_SIZE, 4*GRAD_TEXTURE_SIZE, GF_PIXEL_ARGB, GF_PIXEL_ARGB, 1); } } - st->transparent = transparent; + st->txh.transparent = transparent; if (e) { - free(st->tx_data); + gf_free(st->tx_data); raster->stencil_delete(texture2D); raster->surface_delete(surface); return; @@ -422,13 +448,13 @@ static void BuildRadialGradientTexture(GF_TextureHandler *txh) raster->stencil_set_radial_gradient(stenc, center.x, center.y, focal.x, focal.y, radius, radius); const_a = (rg->opacity.count == 1) ? 1 : 0; - cols = (u32*) malloc(sizeof(u32) * rg->key.count); + cols = (u32*) gf_malloc(sizeof(u32) * rg->key.count); for (i=0; i<rg->key.count; i++) { a = (const_a ? rg->opacity.vals[0] : rg->opacity.vals[i]); cols[i] = GF_COL_ARGB_FIXED(a, rg->keyValue.vals[i].red, rg->keyValue.vals[i].green, rg->keyValue.vals[i].blue); } raster->stencil_set_gradient_interpolation(stenc, rg->key.vals, cols, rg->key.count); - free(cols); + gf_free(cols); raster->stencil_set_gradient_mode(stenc, (GF_GradientMode)rg->spreadMethod); /*fill surface*/ @@ -522,13 +548,13 @@ static void UpdateRadialGradient(GF_TextureHandler *txh) } const_a = (rg->opacity.count == 1) ? 1 : 0; - cols = (u32*)malloc(sizeof(u32) * rg->key.count); + cols = (u32*)gf_malloc(sizeof(u32) * rg->key.count); for (i=0; i<rg->key.count; i++) { a = (const_a ? rg->opacity.vals[0] : rg->opacity.vals[i]); cols[i] = GF_COL_ARGB_FIXED(a, rg->keyValue.vals[i].red, rg->keyValue.vals[i].green, rg->keyValue.vals[i].blue); } txh->compositor->rasterizer->stencil_set_gradient_interpolation(stencil, rg->key.vals, cols, rg->key.count); - free(cols); + gf_free(cols); txh->compositor->rasterizer->stencil_set_gradient_mode(stencil, (GF_GradientMode) rg->spreadMethod); @@ -563,7 +589,11 @@ void compositor_init_radial_gradient(GF_Compositor *compositor, GF_Node *node) GradientStack *st; GF_SAFEALLOC(st, GradientStack); - gf_sc_texture_setup(&st->txh, compositor, node); + /*!!! Gradients are textures but are not registered as textures with the compositor in order to avoid updating + too many textures each frame - gradients are only registered with the compositor when they are used in OpenGL, in order + to release associated HW resource when no longer used*/ + st->txh.owner = node; + st->txh.compositor = compositor; st->txh.update_texture_fcnt = UpdateRadialGradient; st->txh.compute_gradient_matrix = RG_ComputeMatrix; @@ -574,18 +604,24 @@ void compositor_init_radial_gradient(GF_Compositor *compositor, GF_Node *node) GF_TextureHandler *compositor_mpeg4_get_gradient_texture(GF_Node *node) { GradientStack *st = (GradientStack*) gf_node_get_private(node); + st->txh.update_texture_fcnt(&st->txh); return &st->txh; } +#endif /*GPAC_DISABLE_VRML*/ + void compositor_gradient_update(GF_TextureHandler *txh) { switch (gf_node_get_tag(txh->owner) ) { +#ifndef GPAC_DISABLE_VRML case TAG_MPEG4_RadialGradient: BuildRadialGradientTexture(txh); break; case TAG_MPEG4_LinearGradient: BuildLinearGradientTexture(txh); break; +#endif + #ifndef GPAC_DISABLE_SVG case TAG_SVG_linearGradient: case TAG_SVG_radialGradient: diff --git a/src/compositor/mpeg4_grouping.c b/src/compositor/mpeg4_grouping.c index ba44156..9c19300 100644 --- a/src/compositor/mpeg4_grouping.c +++ b/src/compositor/mpeg4_grouping.c @@ -27,6 +27,8 @@ #include "mpeg4_grouping.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + /*This is the generic routine for child traversing*/ void group_2d_traverse(GF_Node *node, GroupingNode2D *group, GF_TraverseState *tr_state) { @@ -39,29 +41,45 @@ void group_2d_traverse(GF_Node *node, GroupingNode2D *group, GF_TraverseState *t backup = gf_node_dirty_get(node); if (backup & GF_SG_CHILD_DIRTY) { + GF_SensorHandler *hsens; u32 ntag = gf_node_get_tag(node); group->flags &= ~GROUP_HAS_SENSORS; + if (group->sensors) gf_list_reset(group->sensors); + drawable_reset_group_highlight(tr_state, node); /*never performs bounds recompute on the fly in 2D since we don't cull 2D groups but still mark the group as empty*/ group->bounds.width = 0; /*special case for anchor which is a parent node acting as a sensor*/ - if ((ntag==TAG_MPEG4_Anchor) || (ntag==TAG_X3D_Anchor)) { - group->flags |= GROUP_HAS_SENSORS | GROUP_IS_ANCHOR; + if ((ntag==TAG_MPEG4_Anchor) +#ifndef GPAC_DISABLE_X3D + || (ntag==TAG_X3D_Anchor) +#endif + ) { + GF_SensorHandler *gf_sc_anchor_get_handler(GF_Node *n); + + hsens = gf_sc_anchor_get_handler(node); + if (hsens) { + if (!group->sensors) group->sensors = gf_list_new(); + gf_list_add(group->sensors, hsens); + group->flags |= GROUP_HAS_SENSORS | GROUP_IS_ANCHOR; + } } else { child = ((GF_ParentNode *)node)->children; while (child) { - if (compositor_mpeg4_is_sensor_node(child->node)) { + hsens = compositor_mpeg4_get_sensor_handler(child->node); + if (hsens) { + if (!group->sensors) group->sensors = gf_list_new(); + gf_list_add(group->sensors, hsens); group->flags |= GROUP_HAS_SENSORS; - break; } child = child->next; } } } /*sub-tree not dirty and getting bounds, direct copy */ - else if ((tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) && group->bounds.width) { + else if ((tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) && !tr_state->for_node && group->bounds.width) { tr_state->bounds = group->bounds; return; } @@ -87,25 +105,10 @@ void group_2d_traverse(GF_Node *node, GroupingNode2D *group, GF_TraverseState *t /*picking: collect sensors*/ sensor_backup = NULL; if ((tr_state->traversing_mode==TRAVERSE_PICK) && (group->flags & GROUP_HAS_SENSORS) ) { - GF_SensorHandler *hsens; /*reset sensor stack if any sensors at this level*/ sensor_backup = tr_state->vrml_sensors; - tr_state->vrml_sensors = gf_list_new(); - - if (group->flags & GROUP_IS_ANCHOR) { - GF_SensorHandler *gf_sc_anchor_get_handler(GF_Node *n); - - hsens = gf_sc_anchor_get_handler(node); - if (hsens) gf_list_add(tr_state->vrml_sensors, hsens); - } else { - /*add sensor(s) to traversing state*/ - child = ((GF_ParentNode *)node)->children; - while (child) { - hsens = compositor_mpeg4_get_sensor_handler(child->node); - if (hsens) gf_list_add(tr_state->vrml_sensors, hsens); - child = child->next; - } - } + assert(group->sensors); + tr_state->vrml_sensors = group->sensors; } @@ -187,8 +190,6 @@ void group_2d_traverse(GF_Node *node, GroupingNode2D *group, GF_TraverseState *t drawable_check_focus_highlight(node, tr_state, NULL); } else { - if (!strcmp(gf_node_get_log_name(node), "CLIP219_DL")) - child = ((GF_ParentNode *)node)->children; child = ((GF_ParentNode *)node)->children; while (child) { gf_node_traverse(child->node, tr_state); @@ -198,11 +199,9 @@ void group_2d_traverse(GF_Node *node, GroupingNode2D *group, GF_TraverseState *t } if (sensor_backup) { - /*destroy current traversing state sensors and restore previous*/ - gf_list_del(tr_state->vrml_sensors); + /*restore previous traversing state sensors */ tr_state->vrml_sensors = sensor_backup; } - } /*This is the routine for OrderedGroup child traversing*/ @@ -219,22 +218,35 @@ void group_2d_traverse_with_order(GF_Node *node, GroupingNode2D *group, GF_Trave backup = gf_node_dirty_get(node); if (backup & GF_SG_CHILD_DIRTY) { + GF_SensorHandler *hsens; /*never trigger bounds recompute in 2D since we don't cull 2D groups*/ u32 ntag = gf_node_get_tag(node); group->flags &= ~GROUP_HAS_SENSORS; drawable_reset_group_highlight(tr_state, node); /*special case for anchor which is a parent node acting as a sensor*/ - if ((ntag==TAG_MPEG4_Anchor) || (ntag==TAG_X3D_Anchor)) { - group->flags |= GROUP_HAS_SENSORS | GROUP_IS_ANCHOR; + if ((ntag==TAG_MPEG4_Anchor) +#ifndef GPAC_DISABLE_X3D + || (ntag==TAG_X3D_Anchor) +#endif + ) { + GF_SensorHandler *gf_sc_anchor_get_handler(GF_Node *n); + + hsens = gf_sc_anchor_get_handler(node); + if (hsens) { + if (!group->sensors) group->sensors = gf_list_new(); + gf_list_add(group->sensors, hsens); + group->flags |= GROUP_HAS_SENSORS | GROUP_IS_ANCHOR; + } } else { list = ((GF_ParentNode *)node)->children; - count = gf_node_list_get_count(list); - for (i=0; i<count; i++) { - child = gf_node_list_get_child(list, positions[i]); - if (compositor_mpeg4_is_sensor_node(child)) { + while (list) { + hsens = compositor_mpeg4_get_sensor_handler(list->node); + if (hsens) { + if (!group->sensors) group->sensors = gf_list_new(); + gf_list_add(group->sensors, hsens); group->flags |= GROUP_HAS_SENSORS; - break; } + list = list->next; } } } @@ -262,20 +274,9 @@ void group_2d_traverse_with_order(GF_Node *node, GroupingNode2D *group, GF_Trave /*picking: collect sensors*/ sensor_backup = NULL; if ((tr_state->traversing_mode==TRAVERSE_PICK) && (group->flags & GROUP_HAS_SENSORS) ) { - GF_SensorHandler *hsens; /*reset sensor stack if any sensors at this level*/ sensor_backup = tr_state->vrml_sensors; - tr_state->vrml_sensors = gf_list_new(); - - - /*add sensor(s) to traversing state*/ - list = ((GF_ParentNode *)node)->children; - count = gf_node_list_get_count(list); - for (i=0; i<count; i++) { - child = gf_node_list_get_child(list, positions[i]); - hsens = compositor_mpeg4_get_sensor_handler(child); - if (hsens) gf_list_add(tr_state->vrml_sensors, hsens); - } + tr_state->vrml_sensors = group->sensors; } if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { @@ -364,8 +365,7 @@ void group_2d_traverse_with_order(GF_Node *node, GroupingNode2D *group, GF_Trave } if (sensor_backup) { - /*destroy current traversing state sensors and restore previous*/ - gf_list_del(tr_state->vrml_sensors); + /*restore previous traversing state sensors*/ tr_state->vrml_sensors = sensor_backup; } } @@ -385,7 +385,7 @@ void group_3d_delete(GF_Node *node) { GroupingNode *group = (GroupingNode *)gf_node_get_private(node); - free(group); + gf_free(group); } GroupingNode *group_3d_new(GF_Node *node) @@ -401,7 +401,9 @@ static u32 get_light_type(GF_Node *n) { switch (gf_node_get_tag(n)) { case TAG_MPEG4_DirectionalLight: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_DirectionalLight: +#endif return 2; case TAG_MPEG4_PointLight: case TAG_MPEG4_SpotLight: @@ -435,7 +437,11 @@ void group_3d_traverse(GF_Node *node, GroupingNode *group, GF_TraverseState *tr_ group->flags &= ~(GROUP_HAS_SENSORS | GROUP_HAS_LIGHTS); /*special case for anchor which is a parent node acting as a sensor*/ - if ((ntag==TAG_MPEG4_Anchor) || (ntag==TAG_X3D_Anchor)) group->flags |= GROUP_HAS_SENSORS; + if ((ntag==TAG_MPEG4_Anchor) +#ifndef GPAC_DISABLE_X3D + || (ntag==TAG_X3D_Anchor) +#endif + ) group->flags |= GROUP_HAS_SENSORS; l = ((GF_ParentNode*)node)->children; while (l) { @@ -518,7 +524,7 @@ void group_3d_traverse(GF_Node *node, GroupingNode *group, GF_TraverseState *tr_ while (l) { if (get_light_type(l->node)==1) { /*store lights for alpha draw*/ - dl = (DirectionalLightContext*)malloc(sizeof(DirectionalLightContext)); + dl = (DirectionalLightContext*)gf_malloc(sizeof(DirectionalLightContext)); dl->dlight = l->node; memcpy(&dl->light_matrix, &tr_state->model_matrix, sizeof(GF_Matrix)); gf_list_add(tr_state->local_lights, dl); @@ -589,7 +595,7 @@ void group_3d_traverse(GF_Node *node, GroupingNode *group, GF_TraverseState *tr_ dl = (DirectionalLightContext*)gf_list_get(tr_state->local_lights, lcount-1); gf_list_rem(tr_state->local_lights, lcount-1); gf_node_traverse(dl->dlight, tr_state); - free(dl); + gf_free(dl); } /*and back to sort mode*/ tr_state->traversing_mode = TRAVERSE_SORT; @@ -622,7 +628,7 @@ void parent_node_reset(ParentNode2D *group) while (gf_list_count(group->groups)) { ChildGroup *cg = (ChildGroup *)gf_list_get(group->groups, 0); gf_list_rem(group->groups, 0); - free(cg); + gf_free(cg); } } @@ -673,7 +679,11 @@ void parent_node_traverse(GF_Node *node, ParentNode2D *group, GF_TraverseState * u32 ntag = gf_node_get_tag(node); group->flags &= ~GROUP_HAS_SENSORS; /*special case for anchor which is a parent node acting as a sensor*/ - if ((ntag==TAG_MPEG4_Anchor) || (ntag==TAG_X3D_Anchor)) { + if ((ntag==TAG_MPEG4_Anchor) +#ifndef GPAC_DISABLE_X3D + || (ntag==TAG_X3D_Anchor) +#endif + ) { group->flags |= GROUP_HAS_SENSORS | GROUP_IS_ANCHOR; } else { l = ((GF_ParentNode *)node)->children; @@ -824,3 +834,5 @@ void parent_node_child_traverse_matrix(ChildGroup *cg, GF_TraverseState *tr_stat } tr_state->text_split_idx = 0; } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_grouping.h b/src/compositor/mpeg4_grouping.h index 8f979b8..2fa30aa 100644 --- a/src/compositor/mpeg4_grouping.h +++ b/src/compositor/mpeg4_grouping.h @@ -74,9 +74,13 @@ typedef struct #endif +#define GROUPING_MPEG4_STACK_2D \ + GROUPING_NODE_STACK_2D \ + GF_List *sensors; \ + typedef struct _mpeg4_group2d { - GROUPING_NODE_STACK_2D + GROUPING_MPEG4_STACK_2D } GroupingNode2D; /*traverse all children of the node */ @@ -95,6 +99,9 @@ void group_2d_cache_evaluate(GF_Node *node, GroupingNode2D *group, GF_TraverseSt void group_2d_destroy(GF_Node *node, GroupingNode2D *group); +/*for SVG <g> only when using offscreen group caches*/ +void group_2d_destroy_svg(GF_Node *node, GroupingNode2D *group); + #ifndef GPAC_DISABLE_3D /* @@ -149,15 +156,15 @@ typedef struct -#define PARENT_NODE_STACK_2D \ - GROUPING_NODE_STACK_2D \ +#define PARENT_MPEG4_STACK_2D \ + GROUPING_MPEG4_STACK_2D \ /*list of ChildGroup drawn (can be fully transparents) - used for post placement*/ \ GF_List *groups; typedef struct _parent_node_2d { - PARENT_NODE_STACK_2D + PARENT_MPEG4_STACK_2D } ParentNode2D; /*performs stack init (allocate all base stuff of stack)*/ diff --git a/src/compositor/mpeg4_grouping_2d.c b/src/compositor/mpeg4_grouping_2d.c index 2cc137a..7a30017 100644 --- a/src/compositor/mpeg4_grouping_2d.c +++ b/src/compositor/mpeg4_grouping_2d.c @@ -26,6 +26,8 @@ #include "mpeg4_grouping.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + typedef struct { s32 last_switch; @@ -45,7 +47,7 @@ static void TraverseSwitch(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { gf_sc_check_focus_upon_destroy(node); - free(st); + gf_free(st); return; } @@ -54,12 +56,17 @@ static void TraverseSwitch(GF_Node *node, void *rs, Bool is_destroy) node = node; } /*WARNING: X3D/MPEG4 NOT COMPATIBLE*/ - if (gf_node_get_tag(node)==TAG_MPEG4_Switch) { + switch (gf_node_get_tag(node)) { + case TAG_MPEG4_Switch: children = ((M_Switch *)node)->choice; whichChoice = ((M_Switch *)node)->whichChoice; - } else { + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Switch: children = ((X_Switch *)node)->children; whichChoice = ((X_Switch *)node)->whichChoice; + break; +#endif } if (tr_state->traversing_mode!=TRAVERSE_GET_BOUNDS) { @@ -97,7 +104,7 @@ static void TraverseSwitch(GF_Node *node, void *rs, Bool is_destroy) void compositor_init_switch(GF_Compositor *compositor, GF_Node *node) { - SwitchStack *st = (SwitchStack *)malloc(sizeof(SwitchStack)); + SwitchStack *st = (SwitchStack *)gf_malloc(sizeof(SwitchStack)); st->last_switch = -1; gf_node_set_private(node, st); gf_node_set_callback_function(node, TraverseSwitch); @@ -107,13 +114,16 @@ void compositor_init_switch(GF_Compositor *compositor, GF_Node *node) /*transform2D*/ typedef struct { - GROUPING_NODE_STACK_2D + GROUPING_MPEG4_STACK_2D GF_Matrix2D mat; - Bool is_identity; + u8 is_identity; + u8 is_null; } Transform2DStack; static void traverse_transform(GF_Node *node, Transform2DStack *stack, GF_TraverseState *tr_state) { + if (stack->is_null) return; + /*note we don't clear dirty flag, this is done in traversing*/ if (stack->is_identity) { group_2d_traverse(node, (GroupingNode2D *)stack, tr_state); @@ -164,7 +174,7 @@ static void TraverseTransform2D(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { gf_sc_check_focus_upon_destroy(node); group_2d_destroy(node, (GroupingNode2D*)ptr); - free(ptr); + gf_free(ptr); return; } @@ -186,6 +196,7 @@ static void TraverseTransform2D(GF_Node *node, void *rs, Bool is_destroy) gf_mx2d_add_translation(&ptr->mat, tr->translation.x, tr->translation.y); } gf_node_dirty_clear(node, GF_SG_NODE_DIRTY); + ptr->is_null = (!tr->scale.x || !tr->scale.y) ? 1 : 0; } traverse_transform(node, ptr, tr_state); } @@ -223,7 +234,7 @@ static void TraverseTransformMatrix2D(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { gf_sc_check_focus_upon_destroy(node); group_2d_destroy(node, (GroupingNode2D*)ptr); - free(ptr); + gf_free(ptr); return; } @@ -235,6 +246,8 @@ static void TraverseTransformMatrix2D(GF_Node *node, void *rs, Bool is_destroy) ptr->is_identity = 1; else ptr->is_identity = 0; + + ptr->is_null = (!ptr->mat.m[0] || !ptr->mat.m[4]) ? 1 : 0; gf_node_dirty_clear(node, GF_SG_NODE_DIRTY); } traverse_transform(node, ptr, tr_state); @@ -254,7 +267,7 @@ void compositor_init_transformmatrix2d(GF_Compositor *compositor, GF_Node *node) typedef struct { - GROUPING_NODE_STACK_2D + GROUPING_MPEG4_STACK_2D GF_ColorMatrix cmat; } ColorTransformStack; @@ -270,7 +283,7 @@ static void TraverseColorTransform(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { gf_sc_check_focus_upon_destroy(node); group_2d_destroy(node, (GroupingNode2D*)ptr); - free(ptr); + gf_free(ptr); return; } if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { @@ -331,7 +344,7 @@ struct og_pos }; typedef struct { - GROUPING_NODE_STACK_2D + GROUPING_MPEG4_STACK_2D u32 *positions; } OrderedGroupStack; @@ -359,8 +372,8 @@ static void TraverseOrderedGroup(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { gf_sc_check_focus_upon_destroy(node); group_2d_destroy(node, (GroupingNode2D*)stack); - if (stack->positions) free(stack->positions); - free(stack); + if (stack->positions) gf_free(stack->positions); + gf_free(stack); return; } @@ -372,18 +385,18 @@ static void TraverseOrderedGroup(GF_Node *node, void *rs, Bool is_destroy) invalidate_backup = tr_state->invalidate_all; /*check whether the OrderedGroup node has changed*/ if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { - if (stack->positions) free(stack->positions); + if (stack->positions) gf_free(stack->positions); count = gf_node_list_get_count(og->children); - priorities = (struct og_pos*)malloc(sizeof(struct og_pos)*count); + priorities = (struct og_pos*)gf_malloc(sizeof(struct og_pos)*count); for (i=0; i<count; i++) { priorities[i].position = i; priorities[i].priority = (i<og->order.count) ? og->order.vals[i] : 0; } qsort(priorities, count, sizeof(struct og_pos), compare_priority); - stack->positions = (u32*)malloc(sizeof(u32) * count); + stack->positions = (u32*)gf_malloc(sizeof(u32) * count); for (i=0; i<count; i++) stack->positions[i] = priorities[i].position; - free(priorities); + gf_free(priorities); tr_state->invalidate_all = 1; gf_node_dirty_clear(node, GF_SG_NODE_DIRTY); @@ -399,3 +412,6 @@ void compositor_init_orderedgroup(GF_Compositor *compositor, GF_Node *node) gf_node_set_private(node, ptr); gf_node_set_callback_function(node, TraverseOrderedGroup); } + +#endif /*GPAC_DISABLE_VRML*/ + diff --git a/src/compositor/mpeg4_grouping_3d.c b/src/compositor/mpeg4_grouping_3d.c index a4d0497..db8b1c0 100644 --- a/src/compositor/mpeg4_grouping_3d.c +++ b/src/compositor/mpeg4_grouping_3d.c @@ -29,6 +29,9 @@ #include "mpeg4_grouping.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + + #ifdef GPAC_DISABLE_3D static void TraverseGroup(GF_Node *node, void *rs, Bool is_destroy) @@ -36,7 +39,7 @@ static void TraverseGroup(GF_Node *node, void *rs, Bool is_destroy) GroupingNode2D *group = (GroupingNode2D *) gf_node_get_private(node); if (is_destroy) { gf_sc_check_focus_upon_destroy(node); - free(group); + gf_free(group); } else { group_2d_traverse(node, group, (GF_TraverseState*)rs); } @@ -148,7 +151,8 @@ void compositor_init_collision(GF_Compositor *compositor, GF_Node *node) typedef struct { GROUPING_NODE_STACK_3D - GF_Matrix mx; + + GF_Matrix mx; Bool has_scale; } TransformStack; @@ -156,7 +160,7 @@ static void DestroyTransform(GF_Node *n) { TransformStack *ptr = (TransformStack *)gf_node_get_private(n); gf_sc_check_focus_upon_destroy(n); - free(ptr); + gf_free(ptr); } static void NewTransformStack(GF_Compositor *compositor, GF_Node *node, GF_ChildNodeItem **children) @@ -339,7 +343,7 @@ static void TraverseLOD(GF_Node *node, void *rs, Bool is_destroy) s32 *prev_child = (s32 *)gf_node_get_private(node); if (is_destroy) { - free(prev_child); + gf_free(prev_child); gf_sc_check_focus_upon_destroy(node); return; } @@ -351,10 +355,12 @@ static void TraverseLOD(GF_Node *node, void *rs, Bool is_destroy) children = ((M_LOD *) node)->level; ranges = &((M_LOD *) node)->range; center = ((M_LOD *) node)->center; +#ifndef GPAC_DISABLE_X3D } else { children = ((X_LOD *) node)->children; ranges = &((X_LOD *) node)->range; center = ((X_LOD *) node)->center; +#endif } if (!children) return; @@ -400,10 +406,13 @@ static void TraverseLOD(GF_Node *node, void *rs, Bool is_destroy) void compositor_init_lod(GF_Compositor *compositor, GF_Node *node) { - s32 *stack = (s32*)malloc(sizeof(s32)); + s32 *stack = (s32*)gf_malloc(sizeof(s32)); *stack = -1; gf_node_set_callback_function(node, TraverseLOD); gf_node_set_private(node, stack); } #endif /*GPAC_DISABLE_3D*/ + + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_layer_2d.c b/src/compositor/mpeg4_layer_2d.c index a885339..3f6c19a 100644 --- a/src/compositor/mpeg4_layer_2d.c +++ b/src/compositor/mpeg4_layer_2d.c @@ -28,10 +28,12 @@ #include "mpeg4_grouping.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + typedef struct { - GROUPING_NODE_STACK_2D + GROUPING_MPEG4_STACK_2D GF_List *backs; GF_List *views; Bool first; @@ -113,7 +115,7 @@ static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy) gf_list_del(st->backs); gf_list_del(st->views); group_2d_destroy(node, (GroupingNode2D*)st); - free(st); + gf_free(st); return; } @@ -141,7 +143,7 @@ static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy) viewport = (GF_Node*)gf_list_get(st->views, 0); - if (tr_state->traversing_mode == TRAVERSE_SORT) { + if ((tr_state->traversing_mode == TRAVERSE_SORT) || (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS)) { /*override group bounds*/ visual_get_size_info(tr_state, &st->clip.width, &st->clip.height); /*setup bounds in local coord system*/ @@ -240,53 +242,55 @@ static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy) tr_state->visual->top_clipper = gf_rect_pixelize(&rc); gf_irect_intersect(&tr_state->visual->top_clipper, &prev_clip); - tr_state->traversing_mode = TRAVERSE_SORT; - if (back && Bindable_GetIsBound(back) ) { - DrawableContext *ctx; - - ctx = b2d_get_context((M_Background2D*) back, st->backs); - gf_mx2d_init(ctx->transform); - ctx->bi->clip = tr_state->visual->top_clipper; - ctx->bi->unclip = rc; - - if (tr_state->direct_draw) { - tr_state->ctx = ctx; - tr_state->traversing_mode = TRAVERSE_DRAW_2D; - gf_node_traverse(back, tr_state); - tr_state->traversing_mode = TRAVERSE_SORT; - tr_state->ctx = NULL; - } else { - DrawableContext *back_ctx = visual_2d_get_drawable_context(tr_state->visual); - - gf_node_traverse(back, tr_state); - - back_ctx->flags = ctx->flags; - back_ctx->flags &= ~CTX_IS_TRANSPARENT; - back_ctx->flags |= CTX_IS_BACKGROUND; - back_ctx->aspect = ctx->aspect; - back_ctx->drawable = ctx->drawable; - drawable_check_bounds(back_ctx, tr_state->visual); - back_ctx->bi->clip = ctx->bi->clip; - back_ctx->bi->unclip = ctx->bi->unclip; - } - /*keep track of node drawn*/ - if (!(ctx->drawable->flags & DRAWABLE_REGISTERED_WITH_VISUAL) ) { - struct _drawable_store *it; - GF_SAFEALLOC(it, struct _drawable_store); - it->drawable = ctx->drawable; - if (tr_state->visual->last_prev_entry) { - tr_state->visual->last_prev_entry->next = it; - tr_state->visual->last_prev_entry = it; + + if (tr_state->visual->top_clipper.width && tr_state->visual->top_clipper.height) { + if (back && Bindable_GetIsBound(back) ) { + DrawableContext *ctx; + + ctx = b2d_get_context((M_Background2D*) back, st->backs); + gf_mx2d_init(ctx->transform); + ctx->bi->clip = tr_state->visual->top_clipper; + ctx->bi->unclip = rc; + + if (tr_state->immediate_draw) { + tr_state->ctx = ctx; + tr_state->traversing_mode = TRAVERSE_DRAW_2D; + gf_node_traverse(back, tr_state); + tr_state->traversing_mode = TRAVERSE_SORT; + tr_state->ctx = NULL; } else { - tr_state->visual->prev_nodes = tr_state->visual->last_prev_entry = it; + DrawableContext *back_ctx = visual_2d_get_drawable_context(tr_state->visual); + + gf_node_traverse(back, tr_state); + + back_ctx->flags = ctx->flags; + back_ctx->flags &= ~CTX_IS_TRANSPARENT; + back_ctx->flags |= CTX_IS_BACKGROUND; + back_ctx->aspect = ctx->aspect; + back_ctx->drawable = ctx->drawable; + drawable_check_bounds(back_ctx, tr_state->visual); + back_ctx->bi->clip = ctx->bi->clip; + back_ctx->bi->unclip = ctx->bi->unclip; + } + /*keep track of node drawn*/ + if (!(ctx->drawable->flags & DRAWABLE_REGISTERED_WITH_VISUAL) ) { + struct _drawable_store *it; + GF_SAFEALLOC(it, struct _drawable_store); + it->drawable = ctx->drawable; + if (tr_state->visual->last_prev_entry) { + tr_state->visual->last_prev_entry->next = it; + tr_state->visual->last_prev_entry = it; + } else { + tr_state->visual->prev_nodes = tr_state->visual->last_prev_entry = it; + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Layer2D] Registering new drawn node %s on visual\n", gf_node_get_class_name(it->drawable->node))); + ctx->drawable->flags |= DRAWABLE_REGISTERED_WITH_VISUAL; } - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Layer2D] Registering new drawn node %s on visual\n", gf_node_get_class_name(it->drawable->node))); - ctx->drawable->flags |= DRAWABLE_REGISTERED_WITH_VISUAL; } - } - group_2d_traverse(node, (GroupingNode2D *)st, tr_state); + group_2d_traverse(node, (GroupingNode2D *)st, tr_state); + } tr_state->visual->top_clipper = prev_clip; gf_mx2d_copy(tr_state->transform, backup); } @@ -328,10 +332,14 @@ static void TraverseLayer2D(GF_Node *node, void *rs, Bool is_destroy) } break; case TRAVERSE_GET_BOUNDS: - tr_state->bounds = st->clip; + if (tr_state->for_node) { + group_2d_traverse(node, (GroupingNode2D *)st, tr_state); + } else { + tr_state->bounds = st->clip; #ifndef GPAC_DISABLE_3D - gf_bbox_from_rect(&tr_state->bbox, &st->clip); + gf_bbox_from_rect(&tr_state->bbox, &st->clip); #endif + } break; case TRAVERSE_DRAW_2D: @@ -377,3 +385,4 @@ void compositor_init_layer2d(GF_Compositor *compositor, GF_Node *node) } +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_layer_3d.c b/src/compositor/mpeg4_layer_3d.c index bb62559..86e18b2 100644 --- a/src/compositor/mpeg4_layer_3d.c +++ b/src/compositor/mpeg4_layer_3d.c @@ -29,12 +29,12 @@ #include "texturing.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + #ifndef GPAC_DISABLE_3D #ifdef GPAC_USE_TINYGL -//#include <GL/oscontext.h> -#include "../../TinyGL/include/GL/oscontext.h" - +#include <GL/oscontext.h> #endif typedef struct @@ -65,7 +65,7 @@ static void DestroyLayer3D(GF_Node *node) if (st->tgl_ctx) ostgl_delete_context(st->tgl_ctx); #endif - if (st->txh.data) free(st->txh.data); + if (st->txh.data) gf_free(st->txh.data); /*destroy texture*/ gf_sc_texture_destroy(&st->txh); @@ -81,7 +81,7 @@ static void DestroyLayer3D(GF_Node *node) if (compositor && compositor->active_layer == node) compositor->active_layer = NULL; - free(st); + gf_free(st); } static void l3d_CheckBindables(GF_Node *n, GF_TraverseState *tr_state, Bool force_traverse) @@ -132,7 +132,6 @@ static void l3d_CheckBindables(GF_Node *n, GF_TraverseState *tr_state, Bool forc u32 layer3d_setup_offscreen(GF_Node *node, Layer3DStack *st, GF_TraverseState *tr_state, Fixed width, Fixed height) { - GF_Err e; GF_STENCIL stencil; u32 new_pixel_format, w, h; GF_Compositor *compositor = (GF_Compositor *)st->visual->compositor; @@ -170,7 +169,8 @@ u32 layer3d_setup_offscreen(GF_Node *node, Layer3DStack *st, GF_TraverseState *t #endif -#ifdef GPAC_TRISCOPE_MODE + /*FIXME - we assume RGB+Depth+bitshape, we should check with the video out module*/ +#ifdef GF_SR_USE_DEPTH new_pixel_format = GF_PIXEL_RGBDS; #endif @@ -201,7 +201,7 @@ u32 layer3d_setup_offscreen(GF_Node *node, Layer3DStack *st, GF_TraverseState *t if (st->tgl_ctx) ostgl_delete_context(st->tgl_ctx); #endif gf_sc_texture_release(&st->txh); - if (st->txh.data) free(st->txh.data); + if (st->txh.data) gf_free(st->txh.data); st->txh.data = NULL; } @@ -216,16 +216,15 @@ u32 layer3d_setup_offscreen(GF_Node *node, Layer3DStack *st, GF_TraverseState *t if (new_pixel_format==GF_PIXEL_RGBA) { st->txh.stride = w * 4; st->txh.transparent = 1; - } else { + } + else if (new_pixel_format==GF_PIXEL_RGBDS) { + st->txh.stride = w * 4; + st->txh.transparent = 1; + } + else { st->txh.stride = w * 3; st->txh.transparent = 0; } -#ifdef GPAC_TRISCOPE_MODE - if (new_pixel_format==GF_PIXEL_RGBDS) { - st->txh.stride = w * 4; - st->txh.transparent = 0; - } -#endif st->visual->width = w; st->visual->height = h; @@ -254,19 +253,13 @@ u32 layer3d_setup_offscreen(GF_Node *node, Layer3DStack *st, GF_TraverseState *t } } #endif - st->txh.data = (char*)malloc(sizeof(unsigned char) * st->txh.stride * st->txh.height); + st->txh.data = (char*)gf_malloc(sizeof(unsigned char) * st->txh.stride * st->txh.height); memset(st->txh.data, 0, sizeof(unsigned char) * st->txh.stride * st->txh.height); - e = compositor->rasterizer->stencil_set_texture(stencil, st->txh.data, st->txh.width, st->txh.height, st->txh.stride, st->txh.pixelformat, st->txh.pixelformat, 0); -#ifdef GPAC_TRISCOPE_MODE - e = GF_OK; -#endif + + /*set stencil texture - we don't check error as an image could not be supported by the rasterizer + but still supported by the blitter (case of RGBD/RGBDS)*/ + compositor->rasterizer->stencil_set_texture(stencil, st->txh.data, st->txh.width, st->txh.height, st->txh.stride, st->txh.pixelformat, st->txh.pixelformat, 0); - if (e) { - compositor->rasterizer->stencil_delete(stencil); - gf_sc_texture_release(&st->txh); - free(st->txh.data); - st->txh.data = NULL; - } #ifdef GPAC_USE_TINYGL /*create TinyGL offscreen context*/ st->tgl_ctx = ostgl_create_context(st->txh.width, st->txh.height, st->txh.transparent ? 32 : 24, &st->txh.data, 1); @@ -378,9 +371,11 @@ static void TraverseLayer3D(GF_Node *node, void *rs, Bool is_destroy) switch (tr_state->traversing_mode) { case TRAVERSE_GET_BOUNDS: - tr_state->bounds = st->clip; - gf_bbox_from_rect(&tr_state->bbox, &st->clip); - return; + if (!tr_state->for_node) { + tr_state->bounds = st->clip; + gf_bbox_from_rect(&tr_state->bbox, &st->clip); + return; + } case TRAVERSE_PICK: case TRAVERSE_SORT: /*layers can only be used in a 2D context*/ @@ -545,10 +540,8 @@ static void TraverseLayer3D(GF_Node *node, void *rs, Bool is_destroy) #ifndef GPAC_USE_TINYGL gf_sc_copy_to_stencil(&st->txh); #else -/*with TinyGL, need to recover depth for triscope*/ -#ifdef GPAC_TRISCOPE_MODE - if (st->txh.pixelformat==GF_PIXEL_RGBDS) gf_get_tinygl_depth(&st->txh); -#endif + if (st->txh.pixelformat==GF_PIXEL_RGBDS) + gf_get_tinygl_depth(&st->txh); #endif if (tr_state->visual->compositor->rasterizer->stencil_texture_modified) @@ -708,3 +701,5 @@ void compositor_layer3d_bind_camera(GF_Node *node, Bool do_bind, u32 nav_value) } #endif /*GPAC_DISABLE_3D*/ + +#endif /*GPAC_DISABLE_VRML*/ \ No newline at end of file diff --git a/src/compositor/mpeg4_layout.c b/src/compositor/mpeg4_layout.c index 9fa23d8..80bec73 100644 --- a/src/compositor/mpeg4_layout.c +++ b/src/compositor/mpeg4_layout.c @@ -26,9 +26,11 @@ #include "mpeg4_grouping.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + typedef struct { - PARENT_NODE_STACK_2D + PARENT_MPEG4_STACK_2D Bool is_scrolling; u32 start_scroll_type; @@ -53,7 +55,7 @@ static void layout_reset_lines(LayoutStack *st) while (gf_list_count(st->lines)) { LineInfo *li = (LineInfo *)gf_list_get(st->lines, 0); gf_list_rem(st->lines, 0); - free(li); + gf_free(li); } } @@ -594,7 +596,7 @@ static void layout_scroll(GF_TraverseState *tr_state, LayoutStack *st, M_Layout } /*draw next frame*/ if (!stop_anim) { - gf_sc_invalidate(tr_state->visual->compositor, NULL); + tr_state->visual->compositor->force_next_frame_redraw = 1; return; } @@ -624,7 +626,7 @@ static void TraverseLayout(GF_Node *node, void *rs, Bool is_destroy) layout_reset_lines(st); parent_node_predestroy((ParentNode2D *)st); gf_list_del(st->lines); - free(st); + gf_free(st); return; } @@ -651,7 +653,7 @@ static void TraverseLayout(GF_Node *node, void *rs, Bool is_destroy) if ((tr_state->traversing_mode==TRAVERSE_PICK) && !gf_sc_pick_in_clipper(tr_state, &st->clip)) goto layout_exit; - if (tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) { + if ((tr_state->traversing_mode==TRAVERSE_GET_BOUNDS) && !tr_state->for_node) { tr_state->bounds = st->clip; #ifndef GPAC_DISABLE_3D gf_bbox_from_rect(&tr_state->bbox, &st->clip); @@ -804,3 +806,5 @@ GF_SensorHandler *compositor_mpeg4_layout_get_sensor_handler(GF_Node *node) return &st->hdl; } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_lighting.c b/src/compositor/mpeg4_lighting.c index fbfd592..e43d7f4 100644 --- a/src/compositor/mpeg4_lighting.c +++ b/src/compositor/mpeg4_lighting.c @@ -26,6 +26,8 @@ #include "nodes_stacks.h" +#ifndef GPAC_DISABLE_VRML + #ifndef GPAC_DISABLE_3D #include "visual_manager.h" @@ -106,7 +108,7 @@ static void TraverseDirectionalLight(GF_Node *n, void *rs, Bool is_destroy) GF_TraverseState *tr_state = (GF_TraverseState *) rs; if (is_destroy) { - free(stack); + gf_free(stack); return; } if (tr_state->switched_off || !dl->on) return; @@ -126,10 +128,12 @@ static void TraverseDirectionalLight(GF_Node *n, void *rs, Bool is_destroy) void compositor_init_directional_light(GF_Compositor *compositor, GF_Node *node) { /*our stack is just a boolean used to store whether the light was turned on successfully*/ - Bool *stack = (Bool*)malloc(sizeof(Bool)); + Bool *stack = (Bool*)gf_malloc(sizeof(Bool)); *stack = 0; gf_node_set_private(node, stack); gf_node_set_callback_function(node, TraverseDirectionalLight); } #endif /*GPAC_DISABLE_3D*/ + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_path_layout.c b/src/compositor/mpeg4_path_layout.c index d88c29f..dd1b856 100644 --- a/src/compositor/mpeg4_path_layout.c +++ b/src/compositor/mpeg4_path_layout.c @@ -26,9 +26,11 @@ #include "mpeg4_grouping.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + typedef struct { - PARENT_NODE_STACK_2D + PARENT_MPEG4_STACK_2D GF_Node *last_geom; GF_PathIterator *iter; @@ -56,7 +58,7 @@ static void TraversePathLayout(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { parent_node_predestroy((ParentNode2D *)gr); if (gr->iter) gf_path_iterator_del(gr->iter); - free(gr); + gf_free(gr); return; } if (!pl->geometry) return; @@ -105,10 +107,12 @@ static void TraversePathLayout(GF_Node *node, void *rs, Bool is_destroy) case TAG_MPEG4_IndexedLineSet2D: case TAG_MPEG4_IndexedFaceSet2D: case TAG_MPEG4_Rectangle: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Disk2D: case TAG_X3D_Arc2D: case TAG_X3D_Polyline2D: case TAG_X3D_TriangleSet2D: +#endif dr = (Drawable *) gf_node_get_private( (GF_Node *) pl->geometry); break; default: @@ -270,3 +274,4 @@ void compositor_init_path_layout(GF_Compositor *compositor, GF_Node *node) gf_node_set_callback_function(node, TraversePathLayout); } +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_sensors.c b/src/compositor/mpeg4_sensors.c index ff70bec..ead75b0 100644 --- a/src/compositor/mpeg4_sensors.c +++ b/src/compositor/mpeg4_sensors.c @@ -31,6 +31,8 @@ /*for anchor processing, which needs to be filtered at the inline scene level*/ #include <gpac/internal/terminal_dev.h> +#ifndef GPAC_DISABLE_VRML + /*for event DOM filtering type ...*/ #include <gpac/scenegraph_svg.h> @@ -39,8 +41,15 @@ static void mpeg4_sensor_deleted(GF_Node *node, GF_SensorHandler *hdl) { GF_Compositor *compositor = gf_sc_get_compositor(node); if (compositor) { + GF_VisualManager *visual; + u32 i=0; gf_list_del_item(compositor->previous_sensors, hdl); if (compositor->interaction_sensors) compositor->interaction_sensors--; + while ( (visual=gf_list_enum(compositor->visuals, &i)) ) { + if (visual->offscreen) + compositor_compositetexture_sensor_delete(visual->offscreen, hdl); + } + #ifndef GPAC_DISABLE_SVG gf_sg_unregister_event_type(gf_node_get_graph(node), GF_DOM_EVENT_MOUSE|GF_DOM_EVENT_KEY); #endif @@ -58,7 +67,7 @@ static void mpeg4_sensor_created(GF_Compositor *compositor, GF_Node *node) typedef struct { - GROUPING_NODE_STACK_2D + GROUPING_MPEG4_STACK_2D Bool enabled, active, over; GF_SensorHandler hdl; @@ -73,16 +82,21 @@ static void TraverseAnchor(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { mpeg4_sensor_deleted(node, &st->hdl); gf_sc_check_focus_upon_destroy(node); - free(st); + gf_free(st); return; } if (gf_node_dirty_get(node) & GF_SG_NODE_DIRTY) { MFURL *url; - if (gf_node_get_tag(node)==TAG_MPEG4_Anchor) { + switch (gf_node_get_tag(node)) { + case TAG_MPEG4_Anchor: url = & ((M_Anchor *)node)->url; - } else { + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Anchor: url = & ((X_Anchor *)node)->url; + break; +#endif } st->enabled = 0; if (url->count && url->vals[0].url && strlen(url->vals[0].url) ) @@ -102,14 +116,19 @@ static void anchor_activation(GF_Node *node, AnchorStack *st, GF_Compositor *com GF_Event evt; MFURL *url; u32 i; - if (gf_node_get_tag(node)==TAG_MPEG4_Anchor) { + switch (gf_node_get_tag(node)) { + case TAG_MPEG4_Anchor: url = & ((M_Anchor *)node)->url; evt.navigate.param_count = ((M_Anchor *)node)->parameter.count; evt.navigate.parameters = (const char **) ((M_Anchor *)node)->parameter.vals; - } else { + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Anchor: url = & ((X_Anchor *)node)->url; evt.navigate.param_count = ((X_Anchor *)node)->parameter.count; evt.navigate.parameters = (const char **) ((X_Anchor *)node)->parameter.vals; + break; +#endif } evt.type = GF_EVENT_NAVIGATE; i=0; @@ -126,11 +145,10 @@ static void anchor_activation(GF_Node *node, AnchorStack *st, GF_Compositor *com break; } } else if (compositor->term) { - if (gf_inline_process_anchor(node, &evt)) - break; - } else if (compositor->user->EventProc) { - if (compositor->user->EventProc(compositor->user->opaque, &evt)) + if (gf_scene_process_anchor(node, &evt)) break; + } else if (gf_term_send_event(compositor->term, &evt)) { + break; } i++; } @@ -153,15 +171,20 @@ static void OnAnchor(GF_SensorHandler *sh, Bool is_over, GF_Event *ev, GF_Compos st->over = 1; if (compositor->user->EventProc) { evt.type = GF_EVENT_NAVIGATE_INFO; - if (gf_node_get_tag(sh->sensor)==TAG_MPEG4_Anchor) { + switch (gf_node_get_tag(sh->sensor)) { + case TAG_MPEG4_Anchor: evt.navigate.to_url = ((M_Anchor *)sh->sensor)->description.buffer; url = & ((M_Anchor *)sh->sensor)->url; - } else { + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Anchor: evt.navigate.to_url = ((X_Anchor *)sh->sensor)->description.buffer; url = & ((X_Anchor *)sh->sensor)->url; + break; +#endif } if (!evt.navigate.to_url || !strlen(evt.navigate.to_url)) evt.navigate.to_url = url->vals[0].url; - compositor->user->EventProc(compositor->user->opaque, &evt); + gf_term_send_event(compositor->term, &evt); } } else if (!is_over) { st->over = 0; @@ -174,7 +197,7 @@ static Bool anchor_is_enabled(GF_Node *node) return st->enabled; } -static void on_activate_anchor(GF_Node *node) +static void on_activate_anchor(GF_Node *node, GF_Route *route) { AnchorStack *st = (AnchorStack *) gf_node_get_private(node); if (!((M_Anchor *)node)->on_activate) return; @@ -220,7 +243,7 @@ static void DestroyDiscSensor(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { DiscSensorStack *st = (DiscSensorStack *) gf_node_get_private(node); mpeg4_sensor_deleted(node, &st->hdl); - free(st); + gf_free(st); } } @@ -349,7 +372,7 @@ static void DestroyPlaneSensor2D(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { PS2DStack *st = (PS2DStack *) gf_node_get_private(node); mpeg4_sensor_deleted(node, &st->hdl); - free(st); + gf_free(st); } } @@ -375,6 +398,7 @@ static void OnPlaneSensor2D(GF_SensorHandler *sh, Bool is_over, GF_Event *ev, GF ps->offset = ps->translation_changed; gf_node_event_out_str(sh->sensor, "offset"); } + ps->isActive = 0; gf_node_event_out_str(sh->sensor, "isActive"); compositor->grabbed_sensor = 0; @@ -405,12 +429,16 @@ static void OnPlaneSensor2D(GF_SensorHandler *sh, Bool is_over, GF_Event *ev, GF if (res.x > ps->maxPosition.x) res.x = ps->maxPosition.x; } if (ps->minPosition.y <= ps->maxPosition.y) { - if (res.y < ps->minPosition.y) res.y = ps->minPosition.y; - if (res.y > ps->maxPosition.y) res.y = ps->maxPosition.y; + if (res.y < ps->minPosition.y) + res.y = ps->minPosition.y; + if (res.y > ps->maxPosition.y) + res.y = ps->maxPosition.y; } ps->translation_changed.x = res.x; ps->translation_changed.y = res.y; gf_node_event_out_str(sh->sensor, "translation_changed"); + + compositor->grabbed_sensor = 1; } } else { if (!ps->isActive && is_over && (ev->type==GF_EVENT_KEYDOWN) && (ev->key.key_code==GF_KEY_ENTER)) { @@ -481,7 +509,7 @@ static void DestroyProximitySensor2D(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { Prox2DStack *st = (Prox2DStack *) gf_node_get_private(node); mpeg4_sensor_deleted(node, &st->hdl); - free(st); + gf_free(st); } } @@ -564,7 +592,7 @@ static void DestroyTouchSensor(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { TouchSensorStack *st = (TouchSensorStack *) gf_node_get_private(node); mpeg4_sensor_deleted(node, &st->hdl); - free(st); + gf_free(st); } } @@ -731,7 +759,7 @@ static void DestroyPlaneSensor(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { PSStack *st = (PSStack *) gf_node_get_private(node); mpeg4_sensor_deleted(node, &st->hdl); - free(st); + gf_free(st); } } @@ -865,7 +893,7 @@ static void DestroyCylinderSensor(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { CylinderSensorStack *st = (CylinderSensorStack *) gf_node_get_private(node); mpeg4_sensor_deleted(node, &st->hdl); - free(st); + gf_free(st); } } @@ -1043,7 +1071,7 @@ static void DestroySphereSensor(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { SphereSensorStack *st = (SphereSensorStack *) gf_node_get_private(node); mpeg4_sensor_deleted(node, &st->hdl); - free(st); + gf_free(st); } } @@ -1244,9 +1272,13 @@ GF_SensorHandler *compositor_mpeg4_get_sensor_handler(GF_Node *n) switch (gf_node_get_tag(n)) { /*anchor is not considered as a child sensor node when picking sensors*/ case TAG_MPEG4_Anchor: + hs = gf_sc_anchor_get_handler(n); + break; +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Anchor: hs = gf_sc_anchor_get_handler(n); break; +#endif case TAG_MPEG4_DiscSensor: hs = disc_sensor_get_handler(n); break; @@ -1257,23 +1289,35 @@ GF_SensorHandler *compositor_mpeg4_get_sensor_handler(GF_Node *n) hs = proximity_sensor2d_get_handler(n); break; case TAG_MPEG4_TouchSensor: + hs = touch_sensor_get_handler(n); + break; +#ifndef GPAC_DISABLE_X3D case TAG_X3D_TouchSensor: hs = touch_sensor_get_handler(n); break; +#endif #ifndef GPAC_DISABLE_3D case TAG_MPEG4_CylinderSensor: - case TAG_X3D_CylinderSensor: hs = cylinder_sensor_get_handler(n); break; case TAG_MPEG4_PlaneSensor: - case TAG_X3D_PlaneSensor: hs = plane_sensor_get_handler(n); break; case TAG_MPEG4_SphereSensor: + hs = sphere_get_handler(n); + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_CylinderSensor: + hs = cylinder_sensor_get_handler(n); + break; + case TAG_X3D_PlaneSensor: + hs = plane_sensor_get_handler(n); + break; case TAG_X3D_SphereSensor: hs = sphere_get_handler(n); break; #endif +#endif /*GPAC_DISABLE_3D*/ default: return NULL; } if (hs && hs->IsEnabled(n)) return hs; @@ -1286,3 +1330,173 @@ Bool compositor_mpeg4_is_sensor_node(GF_Node *node) if (sh && sh->IsEnabled(node)) return 1; return 0; } + +static void traverse_envtest(GF_Node *node, void *rs, Bool is_destroy) +{ + if (is_destroy) { + GF_Compositor *compositor = gf_node_get_private(node); + gf_list_del_item(compositor->env_tests, node); + } +} + +void envtest_evaluate(GF_Node *node, GF_Route *_route) +{ + Bool smaller, larger, equal; + Float ar, arft; + u32 par; + char par_value[50]; + const char *opt; + M_EnvironmentTest *envtest = (M_EnvironmentTest *)node; + GF_Compositor *compositor = (GF_Compositor *)gf_node_get_private(node); + + if (envtest->parameterValue.buffer) gf_free(envtest->parameterValue.buffer); + envtest->parameterValue.buffer=NULL; + + smaller = larger = equal = 0; + switch (envtest->parameter) { + /*screen aspect ratio*/ + case 0: + if (compositor->display_width>compositor->display_height) { + ar = (Float) compositor->display_width; + ar /= compositor->display_height; + } else { + ar = (Float) compositor->display_height; + ar /= compositor->display_width; + } + if (envtest->compareValue.buffer && (sscanf(envtest->compareValue.buffer, "%f", &arft)==1)) { + if (ar==arft) equal=1; + else if (ar>arft) smaller=1; + else larger=1; + } + sprintf(par_value, "%f", ar); + break; + /*screen is portrait */ + case 1: + equal = (compositor->display_width < compositor->display_height) ? 1 : 2; + strcpy(par_value, (equal==1) ? "TRUE" : "FALSE"); + break; + /*screen width */ + case 2: + if (envtest->compareValue.buffer && (sscanf(envtest->compareValue.buffer, "%u", &par)==1)) { + if (compositor->display_width==par) equal=1; + else if (compositor->display_width>par) smaller=1; + else larger=1; + } + sprintf(par_value, "%u", compositor->display_width); + break; + /*screen width */ + case 3: + if (envtest->compareValue.buffer && (sscanf(envtest->compareValue.buffer, "%u", &par)==1)) { + if (compositor->display_height==par) equal=1; + else if (compositor->display_height>par) smaller=1; + else larger=1; + } + sprintf(par_value, "%u", compositor->display_height); + break; + /*screen dpi horizontal */ + case 4: + if (envtest->compareValue.buffer && (sscanf(envtest->compareValue.buffer, "%u", &par)==1)) { + if (compositor->video_out->dpi_x==par) equal=1; + else if (compositor->video_out->dpi_x>par) smaller=1; + else larger=1; + } + sprintf(par_value, "%u", compositor->video_out->dpi_x); + break; + /*screen dpi vertical*/ + case 5: + if (envtest->compareValue.buffer && (sscanf(envtest->compareValue.buffer, "%u", &par)==1)) { + if (compositor->video_out->dpi_y==par) equal=1; + else if (compositor->video_out->dpi_y>par) smaller=1; + else larger=1; + } + sprintf(par_value, "%u", compositor->video_out->dpi_y); + break; + /*automotive situation - fixme we should use a profile doc ?*/ + case 6: + opt = gf_cfg_get_key(compositor->user->config, "Profile", "Automotive"); + equal = (opt && !strcmp(opt, "yes")) ? 1 : 2; + strcpy(par_value, (equal==1) ? "TRUE" : "FALSE"); + break; + /*visually challenged - fixme we should use a profile doc ?*/ + case 7: + opt = gf_cfg_get_key(compositor->user->config, "Profile", "VisuallyChallenged"); + equal = (opt && !strcmp(opt, "yes")) ? 1 : 2; + strcpy(par_value, (equal==1) ? "TRUE" : "FALSE"); + break; + /*has touch - fixme we should find out by ourselves*/ + case 8: + opt = gf_cfg_get_key(compositor->user->config, "Profile", "HasTouchScreen"); + equal = (!opt || !strcmp(opt, "yes")) ? 1 : 2; + strcpy(par_value, (equal==1) ? "TRUE" : "FALSE"); + break; + /*has key - fixme we should find out by ourselves*/ + case 9: + opt = gf_cfg_get_key(compositor->user->config, "Profile", "HasKeyPad"); + equal = (!opt || !strcmp(opt, "yes")) ? 1 : 2; + strcpy(par_value, (equal==1) ? "TRUE" : "FALSE"); + break; + } + + if (equal) { + envtest->valueEqual=(equal==1) ? 1 : 0; + gf_node_event_out_str(node, "valueEqual"); + } + else if (smaller) { + envtest->valueSmaller=1; + gf_node_event_out_str(node, "valueSmaller"); + } + else if (larger) { + envtest->valueLarger=1; + gf_node_event_out_str(node, "valueLarger"); + } + envtest->parameterValue.buffer = gf_strdup(par_value); + gf_node_event_out_str(node, "parameterValue"); +} + +void compositor_evaluate_envtests(GF_Compositor *compositor, u32 param_type) +{ + u32 i, count; + count = gf_list_count(compositor->env_tests); + for (i=0;i<count;i++) { + GF_Node *envtest = gf_list_get(compositor->env_tests, i); + if (!((M_EnvironmentTest *)envtest)->evaluateOnChange) continue; + + switch (((M_EnvironmentTest *)envtest)->parameter) { + /*screen-size related*/ + case 0: + case 1: + case 2: + case 3: + if (param_type==0) envtest_evaluate(envtest, NULL); + break; + /*DPI related*/ + case 4: + case 5: + if (param_type==1) envtest_evaluate(envtest, NULL); + break; + /*automotive situation*/ + case 6: + if (param_type==2) envtest_evaluate(envtest, NULL); + break; + /*the rest are static events*/ + } + } +} + +void compositor_init_envtest(GF_Compositor *compositor, GF_Node *node) +{ + M_EnvironmentTest *envtest = (M_EnvironmentTest *)node; + gf_list_add(compositor->env_tests, node); + gf_node_set_private(node, compositor); + gf_node_set_callback_function(node, traverse_envtest); + + envtest->on_evaluate = envtest_evaluate; +} + +void compositor_envtest_modified(GF_Node *node) +{ + envtest_evaluate(node, NULL); +} + + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_sound.c b/src/compositor/mpeg4_sound.c index 24d4202..576b8c2 100644 --- a/src/compositor/mpeg4_sound.c +++ b/src/compositor/mpeg4_sound.c @@ -27,6 +27,8 @@ #include "nodes_stacks.h" #include "visual_manager.h" +#ifndef GPAC_DISABLE_VRML + typedef struct { GF_SoundInterface snd_ifce; @@ -41,7 +43,7 @@ static void TraverseSound2D(GF_Node *node, void *rs, Bool is_destroy) Sound2DStack *st = (Sound2DStack *)gf_node_get_private(node); if (is_destroy) { - free(st); + gf_free(st); return; } if (!snd->source) return; @@ -172,7 +174,7 @@ static void TraverseSound(GF_Node *node, void *rs, Bool is_destroy) SoundStack *st = (SoundStack *)gf_node_get_private(node); if (is_destroy) { - free(st); + gf_free(st); return; } if (!snd->source) return; @@ -279,5 +281,6 @@ void compositor_init_sound(GF_Compositor *compositor, GF_Node *node) gf_node_set_callback_function(node, TraverseSound); } -#endif +#endif /*GPAC_DISABLE_3D*/ +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_text.c b/src/compositor/mpeg4_text.c index 0b06cdb..6cc0a8d 100644 --- a/src/compositor/mpeg4_text.c +++ b/src/compositor/mpeg4_text.c @@ -22,8 +22,6 @@ * */ - - #include "nodes_stacks.h" #include "visual_manager.h" #include "mpeg4_grouping.h" @@ -31,6 +29,8 @@ #include <gpac/utf.h> #include <gpac/options.h> +#ifndef GPAC_DISABLE_VRML + /*default value when no fontStyle*/ #define FSFAMILY (fs && fs->family.count) ? (const char *)fs->family.vals[0] : "" @@ -140,12 +140,12 @@ static void build_text_split(TextStack *st, M_Text *txt, GF_TraverseState *tr_st if (split_words && (j+1!=len) && !is_space) continue; - span = (GF_TextSpan*) malloc(sizeof(GF_TextSpan)); + span = (GF_TextSpan*) gf_malloc(sizeof(GF_TextSpan)); memcpy(span, tspan, sizeof(GF_TextSpan)); span->nb_glyphs = split_words ? (j - first_char) : 1; if (split_words && !is_space) span->nb_glyphs++; - span->glyphs = malloc(sizeof(void *)*span->nb_glyphs); + span->glyphs = gf_malloc(sizeof(void *)*span->nb_glyphs); span->bounds.height = st->ascent + st->descent; span->bounds.y = start_y; @@ -172,10 +172,10 @@ static void build_text_split(TextStack *st, M_Text *txt, GF_TraverseState *tr_st parent_node_end_text_group(tr_state->parent, &span->bounds, st->ascent, st->descent, idx); if (is_space && split_words) { - span = (GF_TextSpan*) malloc(sizeof(GF_TextSpan)); + span = (GF_TextSpan*) gf_malloc(sizeof(GF_TextSpan)); memcpy(span, tspan, sizeof(GF_TextSpan)); span->nb_glyphs = 1; - span->glyphs = malloc(sizeof(void *)); + span->glyphs = gf_malloc(sizeof(void *)); gf_list_add(st->spans, span); span->bounds.height = st->ascent + st->descent; @@ -198,9 +198,11 @@ static void build_text_split(TextStack *st, M_Text *txt, GF_TraverseState *tr_st static void build_text(TextStack *st, M_Text *txt, GF_TraverseState *tr_state) { u32 i, j, int_major, k, styles, count; - Fixed fontSize, start_x, start_y, line_spacing, tot_width, tot_height, max_scale, space; + Fixed fontSize, start_x, start_y, line_spacing, tot_width, tot_height, max_scale, space, maxExtent; + u32 size, trim_size; GF_Font *font; Bool horizontal; + GF_TextSpan *trim_tspan = NULL; GF_FontManager *ft_mgr = tr_state->visual->compositor->font_manager; M_FontStyle *fs = (M_FontStyle *)txt->fontStyle; @@ -228,10 +230,23 @@ static void build_text(TextStack *st, M_Text *txt, GF_TraverseState *tr_state) space = gf_muldiv(fontSize, INT2FIX(font->line_spacing), INT2FIX(font->em_size)) ; line_spacing = gf_mulfix(FSSPACE, fontSize); + maxExtent = txt->maxExtent; + trim_size = 0; + + if (maxExtent<0) { + trim_tspan = gf_font_manager_create_span(ft_mgr, font, "...", fontSize, 0, 0, 0, NULL, 0, styles, (GF_Node*)txt); + for (i=0; i<trim_tspan->nb_glyphs; i++) { + if (horizontal) { + trim_size += trim_tspan->glyphs[i] ? trim_tspan->glyphs[i]->horiz_advance : trim_tspan->font->max_advance_h; + } else { + trim_size += trim_tspan->glyphs[i] ? trim_tspan->glyphs[i]->vert_advance : trim_tspan->font->max_advance_v; + } + } + } + tot_width = tot_height = 0; for (i=0; i < txt->string.count; i++) { GF_TextSpan *tspan; - u32 size; char *str = txt->string.vals[i]; if (!str) continue; @@ -240,6 +255,36 @@ static void build_text(TextStack *st, M_Text *txt, GF_TraverseState *tr_state) if (horizontal) tspan->flags |= GF_TEXT_SPAN_HORIZONTAL; + size = 0; + if (trim_size) { + for (j=0; j<tspan->nb_glyphs; j++) { + if (horizontal) { + size += tspan->glyphs[j] ? tspan->glyphs[j]->horiz_advance : tspan->font->max_advance_h; + } else { + size += tspan->glyphs[j] ? tspan->glyphs[j]->vert_advance : tspan->font->max_advance_v; + } + /*word is bigger than allowed extent, rewrite 3 previous chars*/ + if ((s32)size*tspan->font_scale >= -maxExtent) { + u32 k; + u32 nb_chars = (j<2) ? j : 3; + + for (k=0; k<nb_chars; k++) { + u32 idx = nb_chars-k-1; + if (horizontal) { + size -= tspan->glyphs[j-k] ? tspan->glyphs[j-k]->horiz_advance : tspan->font->max_advance_h; + size += trim_tspan->glyphs[idx] ? trim_tspan->glyphs[idx]->horiz_advance : tspan->font->max_advance_h; + } else { + size -= tspan->glyphs[j-k] ? tspan->glyphs[j-k]->vert_advance : tspan->font->max_advance_v; + size += trim_tspan->glyphs[idx] ? trim_tspan->glyphs[idx]->vert_advance : tspan->font->max_advance_v; + } + tspan->glyphs[j-k] = trim_tspan->glyphs[idx]; + } + tspan->nb_glyphs = j+1; + break; + } + } + } + if ((horizontal && !FSLTR) || (!horizontal && !FSTTB)) { for (k=0; k<tspan->nb_glyphs/2; k++) { GF_Glyph *g = tspan->glyphs[k]; @@ -248,12 +293,13 @@ static void build_text(TextStack *st, M_Text *txt, GF_TraverseState *tr_state) } } - size = 0; - for (j=0; j<tspan->nb_glyphs; j++) { - if (horizontal) { - size += tspan->glyphs[j] ? tspan->glyphs[j]->horiz_advance : tspan->font->max_advance_h; - } else { - size += tspan->glyphs[j] ? tspan->glyphs[j]->vert_advance : tspan->font->max_advance_v; + if (!size) { + for (j=0; j<tspan->nb_glyphs; j++) { + if (horizontal) { + size += tspan->glyphs[j] ? tspan->glyphs[j]->horiz_advance : tspan->font->max_advance_h; + } else { + size += tspan->glyphs[j] ? tspan->glyphs[j]->vert_advance : tspan->font->max_advance_v; + } } } gf_list_add(st->spans, tspan); @@ -277,12 +323,14 @@ static void build_text(TextStack *st, M_Text *txt, GF_TraverseState *tr_state) if (tot_height < tspan->bounds.height) tot_height = tspan->bounds.height; } } + if (trim_tspan) gf_font_manager_delete_span(ft_mgr, trim_tspan); + max_scale = FIX_ONE; if (horizontal) { - if ((txt->maxExtent > 0) && (tot_width>txt->maxExtent)) { - max_scale = gf_divfix(txt->maxExtent, tot_width); - tot_width = txt->maxExtent; + if ((maxExtent > 0) && (tot_width>maxExtent)) { + max_scale = gf_divfix(maxExtent, tot_width); + tot_width = maxExtent; } tot_height = (txt->string.count-1) * line_spacing + (st->ascent + st->descent); st->bounds.height = tot_height; @@ -320,9 +368,9 @@ static void build_text(TextStack *st, M_Text *txt, GF_TraverseState *tr_state) st->bounds.y = FSTTB ? start_y : (tot_height - st->descent); } } else { - if ((txt->maxExtent > 0) && (tot_height>txt->maxExtent) ) { - max_scale = gf_divfix(txt->maxExtent, tot_height); - tot_height = txt->maxExtent; + if ((maxExtent > 0) && (tot_height>maxExtent) ) { + max_scale = gf_divfix(maxExtent, tot_height); + tot_height = maxExtent; } tot_width = txt->string.count * line_spacing; st->bounds.width = tot_width; @@ -425,7 +473,7 @@ static void build_text(TextStack *st, M_Text *txt, GF_TraverseState *tr_state) } } -static void text_get_draw_opt(GF_Node *node, TextStack *st, Bool *force_texture, u32 *hl_color) +static void text_get_draw_opt(GF_Node *node, TextStack *st, Bool *force_texture, u32 *hl_color, DrawAspect2D *asp) { const char *fs_style; char *hlight; @@ -447,6 +495,14 @@ static void text_get_draw_opt(GF_Node *node, TextStack *st, Bool *force_texture, } *force_texture = st->texture_text_flag; if (strstr(fs_style, "TEXTURED")) *force_texture = 1; + if (strstr(fs_style, "OUTLINED")) { + if (!asp->pen_props.width) { + asp->pen_props.width = FIX_ONE/2; + asp->pen_props.align = GF_PATH_LINE_OUTSIDE; + asp->line_scale=FIX_ONE; + asp->line_color = 0xFF000000; + } + } } @@ -476,7 +532,7 @@ static void text_draw_3d(GF_TraverseState *tr_state, GF_Node *node, TextStack *s asp = &the_asp; drawable_get_aspect_2d_mpeg4(node, asp, tr_state); } - text_get_draw_opt(node, st, &force_texture, &hl_color); + text_get_draw_opt(node, st, &force_texture, &hl_color, asp); gf_font_spans_draw_3d(st->spans, tr_state, asp, hl_color, force_texture); } @@ -493,7 +549,7 @@ void text_draw_2d(GF_Node *node, GF_TraverseState *tr_state) if (!GF_COL_A(tr_state->ctx->aspect.fill_color) && !tr_state->ctx->aspect.pen_props.width) return; - text_get_draw_opt(node, st, &force_texture, &hl_color); + text_get_draw_opt(node, st, &force_texture, &hl_color, &tr_state->ctx->aspect); tr_state->text_parent = node; gf_font_spans_draw_2d(st->spans, tr_state, hl_color, force_texture, &st->bounds); @@ -524,7 +580,7 @@ static void Text_Traverse(GF_Node *n, void *rs, Bool is_destroy) text_clean_paths(gf_sc_get_compositor(n), st); drawable_del(st->graph); gf_list_del(st->spans); - free(st); + gf_free(st); return; } @@ -584,7 +640,7 @@ static void Text_Traverse(GF_Node *n, void *rs, Bool is_destroy) /*if text selection mode, we must force redraw of the entire text span because we don't if glyphs have been (un)selected*/ - if (!tr_state->direct_draw && + if (!tr_state->immediate_draw && /*text selection on*/ (tr_state->visual->compositor->text_selection /*text sel release*/ @@ -612,7 +668,7 @@ static void Text_Traverse(GF_Node *n, void *rs, Bool is_destroy) void compositor_init_text(GF_Compositor *compositor, GF_Node *node) { - TextStack *stack = (TextStack *)malloc(sizeof(TextStack)); + TextStack *stack = (TextStack *)gf_malloc(sizeof(TextStack)); stack->graph = drawable_new(); stack->graph->node = node; stack->graph->flags = DRAWABLE_USE_TRAVERSE_DRAW; @@ -686,7 +742,9 @@ void compositor_extrude_text(GF_Node *node, GF_TraverseState *tr_state, GF_Mesh gf_mesh_build_aabbtree(mesh); } -#endif +#endif /*GPAC_DISABLE_3D*/ + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_textures.c b/src/compositor/mpeg4_textures.c index 7fdb186..8e4d91a 100644 --- a/src/compositor/mpeg4_textures.c +++ b/src/compositor/mpeg4_textures.c @@ -25,16 +25,18 @@ #include "texturing.h" //#include "nodes_stacks.h" +#include <gpac/network.h> #include <gpac/nodes_mpeg4.h> #include <gpac/nodes_x3d.h> +#ifndef GPAC_DISABLE_VRML typedef struct { GF_TextureHandler txh; GF_TimeNode time_handle; - Bool fetch_first_frame, first_frame_fetched, is_vrml; + Bool fetch_first_frame, first_frame_fetched, is_x3d; Double start_time; } MovieTextureStack; @@ -44,7 +46,7 @@ static void movietexture_destroy(GF_Node *node, void *rs, Bool is_destroy) MovieTextureStack *st = (MovieTextureStack *) gf_node_get_private(node); gf_sc_texture_destroy(&st->txh); if (st->time_handle.is_registered) gf_sc_unregister_time_node(st->txh.compositor, &st->time_handle); - free(st); + gf_free(st); } } static Fixed movietexture_get_speed(MovieTextureStack *stack, M_MovieTexture *mt) @@ -130,7 +132,7 @@ static void movietexture_update_time(GF_TimeNode *st) if (time < stack->start_time || /*special case if we're getting active AFTER stoptime */ (!mt->isActive && (mt->stopTime > stack->start_time) && (time>=mt->stopTime)) - || (!stack->start_time && stack->is_vrml && !mt->loop) +// || (!stack->start_time && !stack->is_x3d && !mt->loop) ) { /*opens stream only at first access to fetch first frame*/ if (stack->fetch_first_frame) { @@ -169,7 +171,9 @@ void compositor_init_movietexture(GF_Compositor *compositor, GF_Node *node) if (((M_MovieTexture*)node)->repeatS) st->txh.flags |= GF_SR_TEXTURE_REPEAT_S; if (((M_MovieTexture*)node)->repeatT) st->txh.flags |= GF_SR_TEXTURE_REPEAT_T; - st->is_vrml = (gf_node_get_tag(node)==TAG_X3D_MovieTexture) ? 1 : 0; +#ifndef GPAC_DISABLE_X3D + st->is_x3d = (gf_node_get_tag(node)==TAG_X3D_MovieTexture) ? 1 : 0; +#endif gf_node_set_private(node, st); gf_node_set_callback_function(node, movietexture_destroy); @@ -204,27 +208,54 @@ void compositor_movietexture_modified(GF_Node *node) if (!st->time_handle.is_registered) gf_sc_register_time_node(st->txh.compositor, &st->time_handle); } -typedef struct -{ - GF_TextureHandler txh; -} ImageTextureStack; - static void imagetexture_destroy(GF_Node *node, void *rs, Bool is_destroy) { if (is_destroy) { - ImageTextureStack *st = (ImageTextureStack *) gf_node_get_private(node); - gf_sc_texture_destroy(&st->txh); - free(st); + GF_TextureHandler *txh = (GF_TextureHandler *) gf_node_get_private(node); + + /*cleanup cache if needed*/ + if (gf_node_get_tag(node)==TAG_MPEG4_CacheTexture) { + char section[16]; + const char *opt, *file; + Bool delete_file = 1; + M_CacheTexture *ct = (M_CacheTexture*)node; + + sprintf(section, "@cache=%08X", (u32) ct); + file = gf_cfg_get_key(txh->compositor->user->config, section, "cacheFile"); + opt = gf_cfg_get_key(txh->compositor->user->config, section, "expireAfterNTP"); + + if (opt) { + u32 sec, frac, exp; + sscanf(opt, "%u", &exp); + gf_net_get_ntp(&sec, &frac); + if (!exp || (exp>sec)) delete_file=0; + } + if (delete_file) { + gf_delete_file((char*)file); + gf_cfg_del_section(txh->compositor->user->config, section); + } + } + gf_sc_texture_destroy(txh); + gf_free(txh); } } static void imagetexture_update(GF_TextureHandler *txh) { - M_ImageTexture *txnode = (M_ImageTexture *) txh->owner; - + MFURL url; + SFURL sfurl; + if (gf_node_get_tag(txh->owner)!=TAG_MPEG4_CacheTexture) { + url = ((M_ImageTexture *) txh->owner)->url; + } else { + url.count = 1; + sfurl.OD_ID=GF_MEDIA_EXTERNAL_ID; + sfurl.url = ((M_CacheTexture *) txh->owner)->image.buffer; + url.vals = &sfurl; + } + /*setup texture if needed*/ - if (!txh->is_open && txnode->url.count) { - gf_sc_texture_play(txh, &txnode->url); + if (!txh->is_open && url.count) { + gf_sc_texture_play(txh, &url); } gf_sc_texture_update_frame(txh, 0); @@ -241,38 +272,97 @@ static void imagetexture_update(GF_TextureHandler *txh) void compositor_init_imagetexture(GF_Compositor *compositor, GF_Node *node) { - ImageTextureStack *st; - GF_SAFEALLOC(st, ImageTextureStack); - gf_sc_texture_setup(&st->txh, compositor, node); - st->txh.update_texture_fcnt = imagetexture_update; - gf_node_set_private(node, st); + GF_TextureHandler *txh; + GF_SAFEALLOC(txh, GF_TextureHandler); + gf_sc_texture_setup(txh, compositor, node); + txh->update_texture_fcnt = imagetexture_update; + gf_node_set_private(node, txh); gf_node_set_callback_function(node, imagetexture_destroy); - st->txh.flags = 0; - if (((M_ImageTexture*)node)->repeatS) st->txh.flags |= GF_SR_TEXTURE_REPEAT_S; - if (((M_ImageTexture*)node)->repeatT) st->txh.flags |= GF_SR_TEXTURE_REPEAT_T; + txh->flags = 0; + + if (gf_node_get_tag(txh->owner)!=TAG_MPEG4_CacheTexture) { + if (((M_ImageTexture*)node)->repeatS) txh->flags |= GF_SR_TEXTURE_REPEAT_S; + if (((M_ImageTexture*)node)->repeatT) txh->flags |= GF_SR_TEXTURE_REPEAT_T; + } else { + char section[16]; + const char *url; + u32 i, count; + M_CacheTexture*ct = (M_CacheTexture*)node; + if (!ct->image.buffer) return; + + if (ct->repeatS) txh->flags |= GF_SR_TEXTURE_REPEAT_S; + if (ct->repeatT) txh->flags |= GF_SR_TEXTURE_REPEAT_T; + + /*locate existing cache*/ + url = gf_scene_get_service_url( gf_node_get_graph(node) ); + count = gf_cfg_get_section_count(compositor->user->config); + for (i=0; i<count; i++) { + const char *opt; + const char *name = gf_cfg_get_section_name(compositor->user->config, i); + if (strncmp(name, "@cache=", 7)) continue; + opt = gf_cfg_get_key(compositor->user->config, name, "serviceURL"); + if (!opt || stricmp(opt, url)) continue; + opt = gf_cfg_get_key(compositor->user->config, name, "cacheName"); + if (opt && ct->cacheURL.buffer && !stricmp(opt, ct->cacheURL.buffer)) { + opt = gf_cfg_get_key(compositor->user->config, name, "cacheFile"); + if (opt) gf_delete_file((char*)opt); + gf_cfg_del_section(compositor->user->config, name); + break; + } + } + + sprintf(section, "@cache=%08X", (u32) ct); + gf_cfg_set_key(compositor->user->config, section, "serviceURL", url); + gf_cfg_set_key(compositor->user->config, section, "cacheFile", ct->image.buffer); + + /*setup cache if needed*/ + if (ct->cacheURL.buffer && (ct->expirationDate!=0) ) { + char exp[50]; + u32 sec, frac; + gf_cfg_set_key(compositor->user->config, section, "cacheName", ct->cacheURL.buffer); + + if (ct->expirationDate>0) { + gf_net_get_ntp(&sec, &frac); + sec += ct->expirationDate; + sprintf(exp, "%u", sec); + } else { + strcpy(exp, "0"); + } + gf_cfg_set_key(compositor->user->config, section, "expireAfterNTP", exp); + } + } } GF_TextureHandler *it_get_texture(GF_Node *node) { - ImageTextureStack *st = (ImageTextureStack *) gf_node_get_private(node); - return &st->txh; + return gf_node_get_private(node); } void compositor_imagetexture_modified(GF_Node *node) { - M_ImageTexture *im = (M_ImageTexture *)node; - ImageTextureStack *st = (ImageTextureStack *) gf_node_get_private(node); - if (!st) return; + MFURL url; + SFURL sfurl; + GF_TextureHandler *txh = (GF_TextureHandler *) gf_node_get_private(node); + if (!txh) return; + + if (gf_node_get_tag(node)!=TAG_MPEG4_CacheTexture) { + url = ((M_ImageTexture *) node)->url; + } else { + url.count = 1; + sfurl.OD_ID=GF_MEDIA_EXTERNAL_ID; + sfurl.url = ((M_CacheTexture *) node)->image.buffer; + url.vals = &sfurl; + } /*if open and changed, stop and play*/ - if (st->txh.is_open) { - if (! gf_sc_texture_check_url_change(&st->txh, &im->url)) return; - gf_sc_texture_stop(&st->txh); - gf_sc_texture_play(&st->txh, &im->url); + if (txh->is_open) { + if (! gf_sc_texture_check_url_change(txh, &url)) return; + gf_sc_texture_stop(txh); + gf_sc_texture_play(txh, &url); return; } /*if not open and changed play*/ - if (im->url.count) - gf_sc_texture_play(&st->txh, &im->url); + if (url.count) + gf_sc_texture_play(txh, &url); } @@ -287,9 +377,9 @@ static void pixeltexture_destroy(GF_Node *node, void *rs, Bool is_destroy) { if (is_destroy) { PixelTextureStack *st = (PixelTextureStack *) gf_node_get_private(node); - if (st->pixels) free(st->pixels); + if (st->pixels) gf_free(st->pixels); gf_sc_texture_destroy(&st->txh); - free(st); + gf_free(st); } } static void pixeltexture_update(GF_TextureHandler *txh) @@ -335,8 +425,8 @@ static void pixeltexture_update(GF_TextureHandler *txh) if (!txh->tx_io) return; } - if (st->pixels) free(st->pixels); - st->pixels = (char*)malloc(sizeof(char) * stride * pt->image.height); + if (st->pixels) gf_free(st->pixels); + st->pixels = (char*)gf_malloc(sizeof(char) * stride * pt->image.height); /*FIXME FOR OPENGL !!*/ if (0) { for (i=0; i<pt->image.height; i++) { @@ -387,11 +477,13 @@ static void matte_update(GF_TextureHandler *txh) void compositor_init_mattetexture(GF_Compositor *compositor, GF_Node *node) { - ImageTextureStack *st; - GF_SAFEALLOC(st, ImageTextureStack); - gf_sc_texture_setup(&st->txh, compositor, node); - st->txh.flags = GF_SR_TEXTURE_MATTE; - st->txh.update_texture_fcnt = matte_update; - gf_node_set_private(node, st); + GF_TextureHandler *txh; + GF_SAFEALLOC(txh, GF_TextureHandler); + gf_sc_texture_setup(txh, compositor, node); + txh->flags = GF_SR_TEXTURE_MATTE; + txh->update_texture_fcnt = matte_update; + gf_node_set_private(node, txh); gf_node_set_callback_function(node, imagetexture_destroy); } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_timesensor.c b/src/compositor/mpeg4_timesensor.c index ce700c6..e123df4 100644 --- a/src/compositor/mpeg4_timesensor.c +++ b/src/compositor/mpeg4_timesensor.c @@ -27,6 +27,9 @@ #include <gpac/nodes_mpeg4.h> #include <gpac/nodes_x3d.h> + +#ifndef GPAC_DISABLE_VRML + typedef struct { GF_TimeNode time_handle; @@ -34,7 +37,9 @@ typedef struct Double start_time, cycle_interval; u32 num_cycles; GF_Compositor *compositor; +#ifndef GPAC_DISABLE_X3D Bool is_x3d; +#endif } TimeSensorStack; static void timesensor_destroy(GF_Node *ts, void *rs, Bool is_destroy) @@ -44,7 +49,7 @@ static void timesensor_destroy(GF_Node *ts, void *rs, Bool is_destroy) if (st->time_handle.is_registered) { gf_sc_unregister_time_node(st->compositor, &st->time_handle); } - free(st); + gf_free(st); } } @@ -91,10 +96,12 @@ void timesensor_update_time(GF_TimeNode *st) stack->time_handle.needs_unregister = 1; return; } +#ifndef GPAC_DISABLE_X3D if (stack->is_x3d && !TS->loop) { if (!stack->start_time) return; if (currentTime >= TS->startTime+stack->cycle_interval) return; } +#endif } cycleTime = currentTime - stack->start_time - stack->num_cycles * stack->cycle_interval; @@ -165,7 +172,9 @@ void compositor_init_timesensor(GF_Compositor *compositor, GF_Node *node) st->time_handle.udta = node; st->store_info = 1; st->compositor = compositor; +#ifndef GPAC_DISABLE_X3D st->is_x3d = (gf_node_get_tag(node)==TAG_X3D_TimeSensor) ? 1 : 0; +#endif gf_node_set_private(node, st); gf_node_set_callback_function(node, timesensor_destroy); /*time sensor needs to be run only if def'ed, otherwise it doesn't impact scene*/ @@ -191,3 +200,5 @@ void compositor_timesensor_modified(GF_Node *t) } } } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/mpeg4_viewport.c b/src/compositor/mpeg4_viewport.c index 93d3237..2a8065c 100644 --- a/src/compositor/mpeg4_viewport.c +++ b/src/compositor/mpeg4_viewport.c @@ -29,9 +29,9 @@ #include <gpac/options.h> - GF_Err gf_sc_get_viewpoint(GF_Compositor *compositor, u32 viewpoint_idx, const char **outName, Bool *is_bound) { +#ifndef GPAC_DISABLE_VRML u32 count; GF_Node *n; if (!compositor->visual) return GF_BAD_PARAM; @@ -42,13 +42,22 @@ GF_Err gf_sc_get_viewpoint(GF_Compositor *compositor, u32 viewpoint_idx, const c n = (GF_Node*)gf_list_get(compositor->visual->view_stack, viewpoint_idx-1); switch (gf_node_get_tag(n)) { case TAG_MPEG4_Viewport: *outName = ((M_Viewport*)n)->description.buffer; *is_bound = ((M_Viewport*)n)->isBound;return GF_OK; - case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: *outName = ((M_Viewpoint*)n)->description.buffer; *is_bound = ((M_Viewpoint*)n)->isBound; return GF_OK; + case TAG_MPEG4_Viewpoint: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Viewpoint: +#endif + *outName = ((M_Viewpoint*)n)->description.buffer; *is_bound = ((M_Viewpoint*)n)->isBound; + return GF_OK; default: *outName = NULL; return GF_OK; } +#else + return GF_NOT_SUPPORTED; +#endif } GF_Err gf_sc_set_viewpoint(GF_Compositor *compositor, u32 viewpoint_idx, const char *viewpoint_name) { +#ifndef GPAC_DISABLE_VRML u32 count, i; GF_Node *n; if (!compositor->visual) return GF_BAD_PARAM; @@ -67,8 +76,17 @@ GF_Err gf_sc_set_viewpoint(GF_Compositor *compositor, u32 viewpoint_idx, const c char *name = NULL; n = (GF_Node*)gf_list_get(compositor->visual->view_stack, viewpoint_idx-1); switch (gf_node_get_tag(n)) { - case TAG_MPEG4_Viewport: name = ((M_Viewport*)n)->description.buffer; break; - case TAG_MPEG4_Viewpoint: case TAG_X3D_Viewpoint: name = ((M_Viewpoint*)n)->description.buffer; break; + case TAG_MPEG4_Viewport: + name = ((M_Viewport*)n)->description.buffer; + break; + case TAG_MPEG4_Viewpoint: + name = ((M_Viewpoint*)n)->description.buffer; + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Viewpoint: + name = ((M_Viewpoint*)n)->description.buffer; + break; +#endif default: break; } if (name && !stricmp(name, viewpoint_name)) { @@ -78,9 +96,15 @@ GF_Err gf_sc_set_viewpoint(GF_Compositor *compositor, u32 viewpoint_idx, const c } } return GF_BAD_PARAM; +#else + return GF_NOT_SUPPORTED; +#endif } -#define VPCHANGED(__rend) { GF_Event evt; evt.type = GF_EVENT_VIEWPOINTS; GF_USER_SENDEVENT(__rend->user, &evt); } +#ifndef GPAC_DISABLE_VRML + + +#define VPCHANGED(__rend) { GF_Event evt; evt.type = GF_EVENT_VIEWPOINTS; gf_term_send_event(__rend->term, &evt); } static void DestroyViewStack(GF_Node *node) @@ -89,14 +113,14 @@ static void DestroyViewStack(GF_Node *node) PreDestroyBindable(node, st->reg_stacks); gf_list_del(st->reg_stacks); VPCHANGED(gf_sc_get_compositor(node)); - free(st); + gf_free(st); } -static void viewport_set_bind(GF_Node *node) +static void viewport_set_bind(GF_Node *node, GF_Route *route) { GF_Compositor *rend = gf_sc_get_compositor(node); ViewStack *st = (ViewStack *) gf_node_get_private(node); - Bindable_OnSetBind(node, st->reg_stacks); + Bindable_OnSetBind(node, st->reg_stacks, NULL); gf_sc_invalidate(rend, NULL); /*notify change of vp stack*/ @@ -136,7 +160,7 @@ static void TraverseViewport(GF_Node *node, void *rs, Bool is_destroy) if (gf_list_get(tr_state->viewpoints, 0) == vp) { if (!vp->isBound) Bindable_SetIsBound(node, 1); } else { - if (gf_inline_default_scene_viewpoint(node)) Bindable_SetSetBind(node, 1); + if (gf_inline_is_default_viewpoint(node)) Bindable_SetSetBindEx(node, 1, tr_state->viewpoints); } VPCHANGED(tr_state->visual->compositor); /*in any case don't draw the first time (since the viewport could have been declared last)*/ @@ -147,6 +171,9 @@ static void TraverseViewport(GF_Node *node, void *rs, Bool is_destroy) if (tr_state->traversing_mode != TRAVERSE_BINDABLE) return; if (!vp->isBound) return; + if (gf_list_get(tr_state->viewpoints, 0) != vp) + return; + #ifndef GPAC_DISABLE_3D if (tr_state->visual->type_3d) { w = tr_state->bbox.max_edge.x - tr_state->bbox.min_edge.x; @@ -170,7 +197,9 @@ static void TraverseViewport(GF_Node *node, void *rs, Bool is_destroy) gf_mx2d_add_rotation(&mat, 0, 0, vp->orientation); //compute scaling ratio - rc = gf_rect_center(vp->size.x, vp->size.y); + sx = (vp->size.x>=0) ? vp->size.x : w; + sy = (vp->size.y>=0) ? vp->size.y : h; + rc = gf_rect_center(sx, sy); ar = gf_divfix(h, w); rc_bckup = rc; @@ -229,7 +258,12 @@ static void TraverseViewport(GF_Node *node, void *rs, Bool is_destroy) } gf_mx2d_init(mat); - gf_mx2d_add_scale(&mat, sx, sy); + if (tr_state->pixel_metrics) { + gf_mx2d_add_scale(&mat, sx, sy); + } else { + /*if we are not in pixelMetrics, undo the meterMetrics->pixelMetrics transformation*/ + gf_mx2d_add_scale(&mat, gf_divfix(sx, tr_state->min_hsize), gf_divfix(sy, tr_state->min_hsize) ); + } gf_mx2d_add_translation(&mat, tx, ty); gf_mx2d_add_translation(&mat, -gf_mulfix(vp->position.x,sx), -gf_mulfix(vp->position.y,sy) ); @@ -271,14 +305,14 @@ void compositor_init_viewport(GF_Compositor *compositor, GF_Node *node) #ifndef GPAC_DISABLE_3D -static void viewpoint_set_bind(GF_Node *node) +static void viewpoint_set_bind(GF_Node *node, GF_Route *route) { GF_Compositor *rend = gf_sc_get_compositor(node); ViewStack *st = (ViewStack *) gf_node_get_private(node); if (!((M_Viewpoint*)node)->isBound ) st->prev_was_bound = 0; - Bindable_OnSetBind(node, st->reg_stacks); + Bindable_OnSetBind(node, st->reg_stacks, NULL); gf_sc_invalidate(rend, NULL); /*notify change of vp stack*/ VPCHANGED(rend); @@ -312,7 +346,7 @@ static void TraverseViewpoint(GF_Node *node, void *rs, Bool is_destroy) if (gf_list_get(tr_state->viewpoints, 0) == vp) { if (!vp->isBound) Bindable_SetIsBound(node, 1); } else { - if (gf_inline_default_scene_viewpoint(node)) Bindable_SetSetBind(node, 1); + if (gf_inline_is_default_viewpoint(node)) Bindable_SetSetBind(node, 1); } VPCHANGED(tr_state->visual->compositor); /*in any case don't draw the first time (since the viewport could have been declared last)*/ @@ -347,8 +381,10 @@ static void TraverseViewpoint(GF_Node *node, void *rs, Bool is_destroy) gf_mx_decompose(&mx, &pos, &v1, &ori, &v2); /*get center*/ v1.x = v1.y = v1.z = 0; +#ifndef GPAC_DISABLE_X3D /*X3D specifies examine center*/ if (gf_node_get_tag(node)==TAG_X3D_Viewpoint) v1 = ((X_Viewpoint *)node)->centerOfRotation; +#endif gf_mx_apply_vec(&st->world_view_mx, &v1); /*set frustrum param - animate only if not bound last frame and jump false*/ visual_3d_viewpoint_change(tr_state, node, (!st->prev_was_bound && !vp->jump) ? 1 : 0, vp->fieldOfView, pos, ori, v1); @@ -369,10 +405,10 @@ void compositor_init_viewpoint(GF_Compositor *compositor, GF_Node *node) #endif -static void navinfo_set_bind(GF_Node *node) +static void navinfo_set_bind(GF_Node *node, GF_Route *route) { ViewStack *st = (ViewStack *) gf_node_get_private(node); - Bindable_OnSetBind(node, st->reg_stacks); + Bindable_OnSetBind(node, st->reg_stacks, NULL); gf_sc_invalidate( gf_sc_get_compositor(node), NULL); } @@ -487,10 +523,10 @@ void compositor_init_navigation_info(GF_Compositor *compositor, GF_Node *node) #ifndef GPAC_DISABLE_3D -static void fog_set_bind(GF_Node *node) +static void fog_set_bind(GF_Node *node, GF_Route *route) { ViewStack *st = (ViewStack *) gf_node_get_private(node); - Bindable_OnSetBind(node, st->reg_stacks); + Bindable_OnSetBind(node, st->reg_stacks, NULL); gf_sc_invalidate(gf_sc_get_compositor(node), NULL); } @@ -565,4 +601,6 @@ void compositor_init_fog(GF_Compositor *compositor, GF_Node *node) ((M_Fog*)node)->on_set_bind = fog_set_bind; } -#endif +#endif /*GPAC_DISABLE_3D*/ + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/compositor/navigate.c b/src/compositor/navigate.c index 05ad6d8..2a2b20c 100644 --- a/src/compositor/navigate.c +++ b/src/compositor/navigate.c @@ -33,6 +33,7 @@ static void camera_changed(GF_Compositor *compositor, GF_Camera *cam) { cam->flags |= CAM_IS_DIRTY; gf_sc_invalidate(compositor, NULL); + if (compositor->active_layer) gf_node_dirty_set(compositor->active_layer, 0, 1); } /*shortcut*/ @@ -183,8 +184,10 @@ static void nav_fit_screen(GF_Compositor *compositor) GF_Camera *cam; GF_Node *top; +#ifndef GPAC_DISABLE_VRML if (gf_list_count(compositor->visual->back_stack)) return; if (gf_list_count(compositor->visual->view_stack)) return; +#endif gf_mx_p(compositor->mx); top = gf_sg_get_root_node(compositor->scene); @@ -239,9 +242,12 @@ static Bool compositor_handle_navigation_3d(GF_Compositor *compositor, GF_Event cam = NULL; if (compositor->active_layer) { +#ifndef GPAC_DISABLE_VRML cam = compositor_layer3d_get_camera(compositor->active_layer); is_pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(compositor->active_layer)); +#endif } + if (!cam) { cam = &compositor->visual->camera; assert(compositor); @@ -261,6 +267,9 @@ static Bool compositor_handle_navigation_3d(GF_Compositor *compositor, GF_Event dx = (x - compositor->grab_x); dy = (y - compositor->grab_y); + if (!compositor->visual->center_coords) dy = -dy; + + /* trans_scale = is_pixel_metrics ? cam->width/2 : INT2FIX(10); key_trans = is_pixel_metrics ? INT2FIX(10) : cam->avatar_size.x; */ @@ -596,6 +605,11 @@ static Bool compositor_handle_navigation_2d(GF_VisualManager *visual, GF_Event * case GF_NAVIGATE_EXAMINE: { Fixed sin = gf_mulfix(GF_PI, dy) / visual->height; + //truncate in [-1;1] for arcsin() + if (sin < -FIX_ONE) + sin = -FIX_ONE; + if (sin > FIX_ONE) + sin = FIX_ONE; visual->compositor->rotation += gf_asin(sin); nav_set_zoom_trans_2d(visual, zoom, 0, 0); } @@ -650,14 +664,12 @@ static Bool compositor_handle_navigation_2d(GF_VisualManager *visual, GF_Event * return 0; } - Bool compositor_handle_navigation(GF_Compositor *compositor, GF_Event *ev) { if (!compositor->scene) return 0; #ifndef GPAC_DISABLE_3D - if ( (compositor->visual->type_3d>1) || compositor->active_layer) { + if ( (compositor->visual->type_3d>1) || compositor->active_layer) return compositor_handle_navigation_3d(compositor, ev); - } #endif return compositor_handle_navigation_2d(compositor->visual, ev); } diff --git a/src/compositor/nodes_stacks.h b/src/compositor/nodes_stacks.h index cffc6e2..f8bd2d7 100644 --- a/src/compositor/nodes_stacks.h +++ b/src/compositor/nodes_stacks.h @@ -36,24 +36,32 @@ #include "drawable.h" +#ifndef GPAC_DISABLE_VRML + void compositor_init_audiosource(GF_Compositor *compositor, GF_Node *node); void compositor_audiosource_modified(GF_Node *node); + void compositor_init_audioclip(GF_Compositor *compositor, GF_Node *node); void compositor_audioclip_modified(GF_Node *node); + void compositor_init_audiobuffer(GF_Compositor *compositor, GF_Node *node); void compositor_audiobuffer_modified(GF_Node *node); + void compositor_init_animationstream(GF_Compositor *compositor, GF_Node *node); void compositor_animationstream_modified(GF_Node *node); + void compositor_init_timesensor(GF_Compositor *compositor, GF_Node *node); void compositor_timesensor_modified(GF_Node *node); + void compositor_init_imagetexture(GF_Compositor *compositor, GF_Node *node); void compositor_imagetexture_modified(GF_Node *node); +GF_TextureHandler *it_get_texture(GF_Node *node); + void compositor_init_movietexture(GF_Compositor *compositor, GF_Node *node); void compositor_movietexture_modified(GF_Node *node); -void compositor_init_pixeltexture(GF_Compositor *compositor, GF_Node *node); - -GF_TextureHandler *it_get_texture(GF_Node *node); GF_TextureHandler *mt_get_texture(GF_Node *node); + +void compositor_init_pixeltexture(GF_Compositor *compositor, GF_Node *node); GF_TextureHandler *pt_get_texture(GF_Node *node); @@ -64,12 +72,17 @@ Bool Bindable_GetIsBound(GF_Node *bindable); /*sets isBound*/ void Bindable_SetIsBound(GF_Node *bindable, Bool val); /*generic on_set_bind for all bindables*/ -void Bindable_OnSetBind(GF_Node *bindable, GF_List *stack_list); +void Bindable_OnSetBind(GF_Node *bindable, GF_List *stack_list, GF_List *for_stack); /*remove all bindable references to this stack and destroy chain*/ void BindableStackDelete(GF_List *stack); /*for user-modif of viewport/viewpoint*/ void Bindable_SetSetBind(GF_Node *bindable, Bool val); +/*special user-modif of viewport/viewpoint: + if stack is not NULL, binding is only performed in this stack + otherwise, binding is performed on all stack*/ +void Bindable_SetSetBindEx(GF_Node *bindable, Bool val, GF_List *stack); + /*Viewport/Viewpoint/NavigationInfo/Fog stack - exported for generic bindable handling*/ typedef struct @@ -95,7 +108,7 @@ typedef struct GF_Mesh *mesh; GF_BBox prev_bounds; #endif - + u32 flags; } Background2DStack; #ifndef GPAC_DISABLE_3D @@ -118,6 +131,7 @@ typedef struct { GF_Compositor *compositor; u32 last_mod_time; + Bool is_dirty; } LinePropStack; void compositor_init_lineprops(GF_Compositor *compositor, GF_Node *node); @@ -176,8 +190,8 @@ void compositor_init_compositetexture3d(GF_Compositor *compositor, GF_Node *node GF_TextureHandler *compositor_get_composite_texture(GF_Node *node); void compositor_adjust_scale(GF_Node *node, Fixed *sx, Fixed *sy); Bool compositor_is_composite_texture(GF_Node *appear); -Bool compositor_compositetexture_handle_event(GF_Compositor *compositor, GF_Event *ev); -Bool compositor_handle_navigation(GF_Compositor *compositor, GF_Event *ev); +Bool compositor_compositetexture_handle_event(GF_Compositor *compositor, GF_Node *composite_appear, GF_Event *ev, Bool is_flush); +void compositor_compositetexture_sensor_delete(GF_Node *composite_appear, GF_SensorHandler *hdl); void compositor_init_text(GF_Compositor *compositor, GF_Node *node); @@ -239,6 +253,25 @@ void compositor_init_triangle_fan_set(GF_Compositor *compositor, GF_Node *node); void compositor_init_indexed_triangle_fan_set(GF_Compositor *compositor, GF_Node *node); #endif +GF_TextureHandler *compositor_mpeg4_get_gradient_texture(GF_Node *node); + +/*hardcoded protos*/ +void compositor_init_hardcoded_proto(GF_Compositor *compositor, GF_Node *node); + +#ifndef GPAC_DISABLE_3D +void compositor_extrude_text(GF_Node *node, GF_TraverseState *tr_state, GF_Mesh *mesh, MFVec3f *thespine, Fixed creaseAngle, Bool begin_cap, Bool end_cap, MFRotation *spine_ori, MFVec2f *spine_scale, Bool txAlongSpine); +#endif + +void compositor_init_texture_text(GF_Compositor *compositor, GF_Node *node); + +void compositor_init_envtest(GF_Compositor *compositor, GF_Node *node); +void compositor_envtest_modified(GF_Node *node); +void compositor_evaluate_envtests(GF_Compositor *compositor, u32 param_type); + +void compositor_init_hc_flashshape(GF_Compositor *compositor, GF_Node *node); + +#endif /*GPAC_DISABLE_VRML*/ + #ifndef GPAC_DISABLE_SVG void compositor_init_svg_svg(GF_Compositor *compositor, GF_Node *node); @@ -255,6 +288,7 @@ void compositor_init_svg_a(GF_Compositor *compositor, GF_Node *node); void compositor_init_svg_linearGradient(GF_Compositor *compositor, GF_Node *node); void compositor_init_svg_radialGradient(GF_Compositor *compositor, GF_Node *node); void compositor_init_svg_solidColor(GF_Compositor *compositor, GF_Node *node); +Bool compositor_svg_solid_color_dirty(GF_Compositor *compositor, GF_Node *node); void compositor_init_svg_stop(GF_Compositor *compositor, GF_Node *node); void compositor_init_svg_image(GF_Compositor *compositor, GF_Node *node); @@ -274,6 +308,9 @@ void compositor_init_svg_font(GF_Compositor *compositor, GF_Node *node); void compositor_init_svg_glyph(GF_Compositor *compositor, GF_Node *node); void compositor_init_svg_font_face_uri(GF_Compositor *compositor, GF_Node *node); +void compositor_init_svg_filter(GF_Compositor *compositor, GF_Node *node); +void svg_draw_filter(GF_Node *filter, GF_Node *node, GF_TraverseState *tr_state); + GF_TextureHandler *compositor_svg_get_gradient_texture(GF_Node *node); GF_TextureHandler *compositor_svg_get_image_texture(GF_Node *node); @@ -284,17 +321,6 @@ void svg_pause_video(GF_Node *n, Bool pause); #endif -GF_TextureHandler *compositor_mpeg4_get_gradient_texture(GF_Node *node); - -/*hardcoded protos*/ -void compositor_init_hardcoded_proto(GF_Compositor *compositor, GF_Node *node); - -#ifndef GPAC_DISABLE_3D -void compositor_extrude_text(GF_Node *node, GF_TraverseState *tr_state, GF_Mesh *mesh, MFVec3f *thespine, Fixed creaseAngle, Bool begin_cap, Bool end_cap, MFRotation *spine_ori, MFVec2f *spine_scale, Bool txAlongSpine); -#endif - -void compositor_init_texture_text(GF_Compositor *compositor, GF_Node *node); - #endif /*NODES_STACKS_H*/ diff --git a/src/compositor/offscreen_cache.c b/src/compositor/offscreen_cache.c index 80ebd85..c3c157d 100644 --- a/src/compositor/offscreen_cache.c +++ b/src/compositor/offscreen_cache.c @@ -65,11 +65,11 @@ GroupCache *group_cache_new(GF_Compositor *compositor, GF_Node *node) void group_cache_del(GroupCache *cache) { - drawable_del_ex(cache->drawable, cache->txh.compositor); - if (cache->txh.data) free(cache->txh.data); + drawable_del(cache->drawable); + if (cache->txh.data) gf_free(cache->txh.data); gf_sc_texture_release(&cache->txh); gf_sc_texture_destroy(&cache->txh); - free(cache); + gf_free(cache); } void group_cache_setup(GroupCache *cache, GF_Rect *path_bounds, GF_IRect *pix_bounds, GF_Compositor *compositor, Bool for_gl) @@ -83,14 +83,14 @@ void group_cache_setup(GroupCache *cache, GF_Rect *path_bounds, GF_IRect *pix_bo cache->txh.pixelformat = for_gl ? GF_PIXEL_RGBA : GF_PIXEL_ARGB; cache->txh.transparent = 1; - if (cache->txh.data) free(cache->txh.data); + if (cache->txh.data) gf_free(cache->txh.data); #ifdef CACHE_DEBUG_ALPHA cache->txh.stride = pix_bounds->width * 3; cache->txh.pixelformat = GF_PIXEL_RGB_24; cache->txh.transparent = 0; #endif - cache->txh.data = (u8 *) malloc (sizeof(char) * cache->txh.stride * cache->txh.height); + cache->txh.data = (u8 *) gf_malloc (sizeof(char) * cache->txh.stride * cache->txh.height); memset(cache->txh.data, 0x0, sizeof(char) * cache->txh.stride * cache->txh.height); /*the path of drawable_cache is a rectangle one that is the the bound of the object*/ gf_path_reset(cache->drawable->path); @@ -104,7 +104,7 @@ void group_cache_setup(GroupCache *cache, GF_Rect *path_bounds, GF_IRect *pix_bo path_bounds->width, path_bounds->height); } -Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr_state, Bool force_recompute) +Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr_state, Bool force_recompute, Bool is_mpeg4) { DrawableContext *group_ctx = NULL; GF_ChildNodeItem *l; @@ -132,9 +132,10 @@ Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr DrawableContext *child_ctx; Fixed temp_x, temp_y, scale_x, scale_y; + GF_LOG(GF_LOG_INFO, GF_LOG_COMPOSE, ("[Compositor] Recomputing cache for subtree %s\n", gf_node_get_log_name(node))); /*step 1 : store current state and indicate children should not be cached*/ tr_state->in_group_cache = 1; - prev_flags = tr_state->direct_draw; + prev_flags = tr_state->immediate_draw; /*store the current transform matrix, create a new one for group_cache*/ gf_mx2d_copy(backup, tr_state->transform); gf_mx2d_init(tr_state->transform); @@ -160,7 +161,7 @@ Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr if (!cache_bounds.width || !cache_bounds.height) { tr_state->in_group_cache = 0; - tr_state->direct_draw = prev_flags; + tr_state->immediate_draw = prev_flags; gf_mx2d_copy(tr_state->transform, backup); #ifndef GPAC_DISABLE_3D tr_state->visual->type_3d = type_3d; @@ -169,7 +170,16 @@ Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr } /*step 3: insert a DrawableContext for this group in the display list*/ - group_ctx = drawable_init_context_mpeg4(cache->drawable, tr_state); + if (is_mpeg4) { +#ifndef GPAC_DISABLE_VRML + group_ctx = drawable_init_context_mpeg4(cache->drawable, tr_state); +#endif + } else { +#ifndef GPAC_DISABLE_SVG + group_ctx = drawable_init_context_svg(cache->drawable, tr_state); +#endif + } + if (!group_ctx) return 0; /*step 4: now we have the bounds: allocate the offscreen memory @@ -211,6 +221,7 @@ Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr r2d->surface_attach_to_buffer(offscreen_surface, cache->txh.data, cache->txh.width, cache->txh.height, + 0, cache->txh.stride, cache->txh.pixelformat); @@ -250,7 +261,7 @@ Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr /*step 5: traverse subtree in direct draw mode*/ - tr_state->direct_draw = 1; + tr_state->immediate_draw = 1; group_ctx->flags &= ~CTX_NO_ANTIALIAS; l = ((GF_ParentNode*)node)->children; @@ -272,7 +283,7 @@ Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr /*restore state and destroy whatever needs to be cleaned*/ gf_mx2d_copy(tr_state->transform, backup); tr_state->in_group_cache = 0; - tr_state->direct_draw = prev_flags; + tr_state->immediate_draw = prev_flags; r2d->surface_delete(offscreen_surface); tr_state->visual->raster_surface = old_surf; tr_state->traversing_mode = TRAVERSE_SORT; @@ -285,16 +296,28 @@ Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr /*update texture*/ cache->txh.transparent = 1; + cache->txh.flags |= GF_SR_TEXTURE_NO_GL_FLIP; gf_sc_texture_set_data(&cache->txh); gf_sc_texture_push_image(&cache->txh, 0, type_3d ? 0 : 1); } /*just setup the context*/ else { - group_ctx = drawable_init_context_mpeg4(cache->drawable, tr_state); + if (is_mpeg4) { +#ifndef GPAC_DISABLE_VRML + group_ctx = drawable_init_context_mpeg4(cache->drawable, tr_state); +#endif + } else { +#ifndef GPAC_DISABLE_SVG + group_ctx = drawable_init_context_svg(cache->drawable, tr_state); +#endif + } } - assert(group_ctx); + if (!group_ctx) return 0; group_ctx->flags |= CTX_NO_ANTIALIAS; - group_ctx->aspect.fill_color = GF_COL_ARGB_FIXED(cache->opacity, FIX_ONE, FIX_ONE, FIX_ONE); + if (cache->opacity != FIX_ONE) + group_ctx->aspect.fill_color = GF_COL_ARGB_FIXED(cache->opacity, FIX_ONE, FIX_ONE, FIX_ONE); + else + group_ctx->aspect.fill_color = 0; group_ctx->aspect.fill_texture = &cache->txh; if (!cache->opacity) { @@ -553,7 +576,7 @@ Bool group_2d_cache_traverse(GF_Node *node, GroupingNode2D *group, GF_TraverseSt } /*cache has been modified due to node changes, reset stats*/ - group_cache_traverse(node, group->cache, tr_state, needs_recompute); + group_cache_traverse(node, group->cache, tr_state, needs_recompute, 1); return 1; } @@ -791,7 +814,7 @@ void compositor_set_cache_memory(GF_Compositor *compositor, u32 memory) #endif /*GF_SR_USE_VIDEO_CACHE*/ -void group_2d_destroy(GF_Node *node, GroupingNode2D *group) +void group_2d_destroy_svg(GF_Node *node, GroupingNode2D *group) { #ifdef GF_SR_USE_VIDEO_CACHE GF_Compositor *compositor = gf_sc_get_compositor(node); @@ -803,3 +826,10 @@ void group_2d_destroy(GF_Node *node, GroupingNode2D *group) if (group->cache) group_cache_del(group->cache); #endif } + +void group_2d_destroy(GF_Node *node, GroupingNode2D *group) +{ + group_2d_destroy_svg(node, group); + if (group->sensors) gf_list_del(group->sensors); +} + diff --git a/src/compositor/offscreen_cache.h b/src/compositor/offscreen_cache.h index 8216cce..4ae7bcd 100644 --- a/src/compositor/offscreen_cache.h +++ b/src/compositor/offscreen_cache.h @@ -47,7 +47,7 @@ GroupCache *group_cache_new(GF_Compositor *compositor, GF_Node *node); void group_cache_del(GroupCache *cache); /*returns 1 if cache is being recomputed due to dirty subtree*/ -Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr_state, Bool force_recompute); +Bool group_cache_traverse(GF_Node *node, GroupCache *cache, GF_TraverseState *tr_state, Bool force_recompute, Bool is_mpeg4); void group_cache_draw(GroupCache *cache, GF_TraverseState *tr_state); Fixed group_cache_check_coverage_increase(GF_Rect *ctx, GF_Rect *grp_bounds, DrawableContext *curr, DrawableContext* first_child); diff --git a/src/compositor/svg_base.c b/src/compositor/svg_base.c index 63a0b8d..5fe0c39 100644 --- a/src/compositor/svg_base.c +++ b/src/compositor/svg_base.c @@ -355,7 +355,7 @@ Bool compositor_svg_evaluate_conditional(GF_Compositor *compositor, SVGAllAttrib Bool compositor_svg_traverse_base(GF_Node *node, SVGAllAttributes *atts, GF_TraverseState *tr_state, SVGPropertiesPointers *backup_props, u32 *backup_flags) { - u32 inherited_flags_mask; + u32 inherited_flags_mask, flags; if (atts->requiredFeatures || atts->requiredExtensions || atts->systemLanguage || atts->requiredFonts || atts->requiredFormats) { @@ -378,7 +378,8 @@ Bool compositor_svg_traverse_base(GF_Node *node, SVGAllAttributes *atts, GF_Trav // inherited_flags_mask = 0xFFFFFFFF; #endif tr_state->svg_flags &= inherited_flags_mask; - tr_state->svg_flags |= gf_node_dirty_get(node); + flags = gf_node_dirty_get(node); + tr_state->svg_flags |= flags; return 1; } diff --git a/src/compositor/svg_filters.c b/src/compositor/svg_filters.c new file mode 100644 index 0000000..cc6587e --- /dev/null +++ b/src/compositor/svg_filters.c @@ -0,0 +1,425 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Jean le Feuvre + * Copyright (c) 2010-200X ENST + * All rights reserved + * + * This file is part of GPAC / Scene Compositor 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 "visual_manager.h" + +#ifndef GPAC_DISABLE_SVG +#include "nodes_stacks.h" +#include "texturing.h" + +typedef struct +{ + GF_TextureHandler txh; + Drawable *drawable; + u8 *data; + u32 alloc_size; +} GF_FilterStack; + + + +void apply_feComponentTransfer(GF_Node *node, GF_TextureHandler *source, GF_Rect *region) +{ + GF_ChildNodeItem *l = ((GF_ParentNode*)node)->children; + while (l) { + SVG_Filter_TransferType type = SVG_FILTER_TRANSFER_IDENTITY; + u32 i, j; + GF_List *table = NULL; + Fixed slope = FIX_ONE; + Fixed intercept = 0; + Fixed amplitude = 1; + Fixed exponent = 1; + Fixed offset = 0; + u8 *ptr; + u32 tag = gf_node_get_tag(l->node); + GF_DOMAttribute *att = ((SVG_Element *)l->node)->attributes; + + while (att) { + switch (att->tag) { + case TAG_SVG_ATT_filter_transfer_type: type = *(u8*)att->data; break; + case TAG_SVG_ATT_filter_table_values: table = *(GF_List **)att->data; break; + case TAG_SVG_ATT_slope: slope = ((SVG_Number *)att->data)->value; break; + case TAG_SVG_ATT_filter_intercept: intercept = ((SVG_Number *)att->data)->value; break; + case TAG_SVG_ATT_filter_amplitude: amplitude = ((SVG_Number *)att->data)->value; break; + case TAG_SVG_ATT_filter_exponent: exponent = ((SVG_Number *)att->data)->value; break; + case TAG_SVG_ATT_offset: offset = ((SVG_Number *)att->data)->value; break; + } + att = att->next; + } + if (type==SVG_FILTER_TRANSFER_IDENTITY) { + l = l->next; + continue; + } + switch (gf_node_get_tag(l->node)) { + case TAG_SVG_feFuncR: + if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data; + else ptr = source->data+2; + break; + case TAG_SVG_feFuncG: + if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data+1; + else ptr = source->data+1; + break; + case TAG_SVG_feFuncB: + if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data+2; + else ptr = source->data; + break; + case TAG_SVG_feFuncA: + if (source->pixelformat==GF_PIXEL_RGBA) ptr = source->data+3; + else ptr = source->data+3; + break; + } + + if ((type==SVG_FILTER_TRANSFER_LINEAR) && (intercept || (slope!=FIX_ONE)) ) { + intercept *= 255; + for (i=0; i<source->height; i++) { + for (j=0; j<source->width; j++) { + Fixed p = (*ptr) * slope + intercept; + ptr[0] = (u8) MIN(MAX(0, p), 255); + ptr += 4; + } + } + } else if (type==SVG_FILTER_TRANSFER_GAMMA) { + for (i=0; i<source->height; i++) { + for (j=0; j<source->width; j++) { + Fixed p = 255 * gf_mulfix(amplitude, FLT2FIX( pow( INT2FIX(*ptr)/255, FIX2FLT(exponent) ) ) ) + offset; + ptr[0] = (u8) MIN(MAX(0, p), 255); + ptr += 4; + } + } + } else if ((type==SVG_FILTER_TRANSFER_TABLE) && table && (gf_list_count(table)>=2) ) { + u32 count = gf_list_count(table); + u32 N = count-1; + for (i=0; i<source->height; i++) { + for (j=0; j<source->width; j++) { + SVG_Number *vk, *vk1; + Fixed p = INT2FIX(ptr[0]) / 255; + Fixed pN = p*N; + u32 k = FIX2INT(p*N); + if (k==N) k--; + vk = gf_list_get(table, k); + vk1 = gf_list_get(table, k+1); + p = 255 * ( vk->value + gf_mulfix( pN - INT2FIX(k), (vk1->value - vk->value)) ); + ptr[0] = (u8) MIN(MAX(0, p), 255); + ptr += 4; + } + } + } else if ((type==SVG_FILTER_TRANSFER_DISCRETE) && table && gf_list_count(table) ) { + u32 count = gf_list_count(table); + for (i=0; i<source->height; i++) { + for (j=0; j<source->width; j++) { + SVG_Number *vk; + Fixed p = INT2FIX(ptr[0]) / 255; + Fixed pN = p*count; + u32 k = 0; + while (k<count) { + if ((s32)k+1>pN) break; + k++; + } + if (k) k--; + vk = gf_list_get(table, k); + p = 255 * vk->value; + ptr[0] = (u8) MIN(MAX(0, p), 255); + ptr += 4; + } + } + } + l = l->next; + } +} + +void svg_filter_apply(GF_Node *node, GF_TextureHandler *source, GF_Rect *region) +{ + GF_ChildNodeItem *l = ((GF_ParentNode*)node)->children; + + while (l) { + switch (gf_node_get_tag(l->node)) { + case TAG_SVG_feComponentTransfer: + apply_feComponentTransfer(l->node, source, region); + break; + } + l = l->next; + } +} + +/* + This is a crude draft implementation of filter. The main drawback is that we don't cache any data. + We should be able to check for changes in the sub-group or in the filter +*/ +void svg_draw_filter(GF_Node *filter, GF_Node *node, GF_TraverseState *tr_state) +{ + GF_IRect rc1, rc2; + +#ifndef GPAC_DISABLE_3D + u32 type_3d; +#endif + u32 prev_flags; + GF_IRect txrc; + Fixed scale_x, scale_y, temp_x, temp_y; + DrawableContext *ctx, *child_ctx; + GF_SURFACE offscreen_surface, old_surf; + GF_Rect bounds, local_bounds, rc; + GF_Matrix2D backup; + SVGAllAttributes all_atts; + GF_FilterStack *st = gf_node_get_private(filter); + assert(tr_state->traversing_mode==TRAVERSE_SORT); + + /*store the current transform matrix, create a new one for group_cache*/ + gf_mx2d_copy(backup, tr_state->transform); + gf_mx2d_init(tr_state->transform); + + gf_node_allow_cyclic_traverse(node); + tr_state->traversing_mode = TRAVERSE_GET_BOUNDS; + tr_state->bounds.width = tr_state->bounds.height = 0; + gf_node_traverse(node, tr_state); + + local_bounds = bounds = tr_state->bounds; + /*compute bounds in final coordinate system - this ensures that the cache has the correct anti aliasing*/ + gf_mx2d_apply_rect(&backup, &bounds); + txrc = gf_rect_pixelize(&bounds); + if (txrc.width%2) txrc.width++; + if (txrc.height%2) txrc.height++; + bounds = gf_rect_ft(&txrc); + + tr_state->traversing_mode = TRAVERSE_SORT; + + gf_mx2d_copy(tr_state->transform, backup); + + if (!bounds.width || !bounds.height) { + return; + } + + /*create a context */ + ctx = drawable_init_context_svg(st->drawable, tr_state); + if (!ctx) return; + + /*setup texture */ + st->txh.height = txrc.height; + st->txh.width = txrc.width; + + st->txh.stride = txrc.width * 4; + st->txh.pixelformat = GF_PIXEL_ARGB; +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->type_3d) st->txh.pixelformat = GF_PIXEL_RGBA; +#endif + st->txh.transparent = 1; + + if (st->txh.stride * st->txh.height > st->alloc_size) { + st->alloc_size = st->txh.stride * st->txh.height; + st->data = realloc(st->data, sizeof(u8) * st->alloc_size); + } + memset(st->data, 0x0, sizeof(char) * st->txh.stride * st->txh.height); + st->txh.data = st->data; + /*setup geometry (rectangle matching the bounds of the object) + Warning, we want to center the cached bitmap at the center of the screen (main visual)*/ + gf_path_reset(st->drawable->path); + + gf_path_add_rect_center(st->drawable->path, + bounds.x + bounds.width/2, + bounds.y - bounds.height/2, + bounds.width, + bounds.height); + + + old_surf = tr_state->visual->raster_surface; + offscreen_surface = tr_state->visual->compositor->rasterizer->surface_new(tr_state->visual->compositor->rasterizer, tr_state->visual->center_coords); + tr_state->visual->raster_surface = offscreen_surface; + + gf_mx2d_copy(backup, tr_state->transform); + gf_mx2d_init(tr_state->transform); + + /*attach the buffer to visual*/ + tr_state->visual->compositor->rasterizer->surface_attach_to_buffer(offscreen_surface, st->txh.data, + st->txh.width, + st->txh.height, + 0, + st->txh.stride, + st->txh.pixelformat); + + prev_flags = tr_state->immediate_draw; + tr_state->immediate_draw = 1; + tr_state->traversing_mode = TRAVERSE_SORT; + tr_state->in_svg_filter = 1; + + /*recompute the bounds with the final scaling used*/ + scale_x = gf_divfix(bounds.width, local_bounds.width); + scale_y = gf_divfix(bounds.height, local_bounds.height); + gf_mx2d_init(tr_state->transform); + gf_mx2d_add_scale(&tr_state->transform, scale_x, scale_y); + + rc = local_bounds; + gf_mx2d_apply_rect(&tr_state->transform, &rc); + + /*centered the bitmap on the visual*/ + if (tr_state->visual->center_coords) { + temp_x = -rc.x - rc.width/2; + temp_y = rc.height/2 - rc.y; + } else { + temp_x = -rc.x; + temp_y = rc.height - rc.y; + } + gf_mx2d_add_translation(&tr_state->transform, temp_x, temp_y); + + + rc1 = tr_state->visual->surf_rect; + rc2 = tr_state->visual->top_clipper; + tr_state->visual->surf_rect.width = st->txh.width; + tr_state->visual->surf_rect.height = st->txh.height; + if (tr_state->visual->center_coords) { + tr_state->visual->surf_rect.y = st->txh.height/2; + tr_state->visual->surf_rect.x = -1 * (s32) st->txh.width/2; + } else { + tr_state->visual->surf_rect.y = st->txh.height; + tr_state->visual->surf_rect.x = 0; + } + tr_state->visual->top_clipper = tr_state->visual->surf_rect; + + +#ifndef GPAC_DISABLE_3D + type_3d = tr_state->visual->type_3d; + tr_state->visual->type_3d=0; +#endif + + if (prev_flags) gf_node_allow_cyclic_traverse(node); + gf_node_traverse(node, tr_state); + + child_ctx = ctx->next; + while (child_ctx && child_ctx->drawable) { + drawable_reset_bounds(child_ctx->drawable, tr_state->visual); + child_ctx->drawable = NULL; + child_ctx = child_ctx->next; + } + tr_state->visual->cur_context = ctx; + + + /*restore state and destroy whatever needs to be cleaned*/ + tr_state->in_svg_filter = 0; + tr_state->immediate_draw = prev_flags; + tr_state->visual->compositor->rasterizer->surface_delete(offscreen_surface); + tr_state->visual->raster_surface = old_surf; + tr_state->traversing_mode = TRAVERSE_SORT; + tr_state->visual->surf_rect = rc1; + tr_state->visual->top_clipper = rc2; +#ifndef GPAC_DISABLE_3D + tr_state->visual->type_3d = type_3d ; +#endif + + /*update texture*/ + st->txh.transparent = 1; + st->txh.flags |= GF_SR_TEXTURE_NO_GL_FLIP; + gf_sc_texture_set_data(&st->txh); +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->type_3d) + gf_sc_texture_push_image(&st->txh, 0, 0); + else +#endif + gf_sc_texture_push_image(&st->txh, 0, 1); + + ctx->flags |= CTX_NO_ANTIALIAS; + ctx->aspect.fill_color = 0; + ctx->aspect.line_color = 0xFF000000; + ctx->aspect.fill_texture = &st->txh; + ctx->flags |= CTX_TEXTURE_DIRTY; + + /*get the filter region*/ + bounds = local_bounds; + gf_svg_flatten_attributes((SVG_Element *)filter, &all_atts); + if (!all_atts.filterUnits || (*all_atts.filterUnits==SVG_GRADIENTUNITS_OBJECT)) { + Fixed v; + v = all_atts.x ? all_atts.x->value : INT2FIX(-10); + bounds.x += gf_mulfix(v, bounds.width); + v = all_atts.y ? all_atts.y->value : INT2FIX(-10); + bounds.y += gf_mulfix(v, bounds.height); + v = all_atts.width ? all_atts.width->value : INT2FIX(120); + bounds.width = gf_mulfix(v, bounds.width); + v = all_atts.height ? all_atts.height->value : INT2FIX(120); + bounds.height = gf_mulfix(v, bounds.height); + } else { + bounds.x = all_atts.x ? all_atts.x->value : 0; + bounds.y = all_atts.y ? all_atts.y->value : 0; + bounds.width = all_atts.width ? all_atts.x->value : bounds.width; + bounds.height = all_atts.x ? all_atts.x->value : 120; + } + gf_mx2d_apply_rect(&backup, &bounds); + + svg_filter_apply(filter, &st->txh, &bounds); + + +#ifndef GPAC_DISABLE_3D + if (tr_state->visual->type_3d) { + if (!st->drawable->mesh) { + st->drawable->mesh = new_mesh(); + mesh_from_path(st->drawable->mesh, st->drawable->path); + } + visual_3d_draw_from_context(tr_state->ctx, tr_state); + ctx->drawable = NULL; + return; + } +#endif + + /*we computed the texture in final screen coordinate, so use the identity matrix for the context*/ + gf_mx2d_init(tr_state->transform); + drawable_finalize_sort(ctx, tr_state, NULL); + gf_mx2d_copy(tr_state->transform, backup); +} + +static void svg_traverse_filter(GF_Node *node, void *rs, Bool is_destroy) +{ + GF_TraverseState *tr_state = (GF_TraverseState *)rs; + GF_FilterStack *st = gf_node_get_private(node); + if (is_destroy) { + drawable_del(st->drawable); + if (st->data) gf_free(st->data); + st->txh.data = NULL; + gf_sc_texture_release(&st->txh); + gf_sc_texture_destroy(&st->txh); + free(st); + return; + } + + if (tr_state->traversing_mode==TRAVERSE_DRAW_2D) { + if (! tr_state->visual->DrawBitmap(tr_state->visual, tr_state, tr_state->ctx, NULL)) { + visual_2d_texture_path(tr_state->visual, st->drawable->path, tr_state->ctx, tr_state); + } + } +} + +void compositor_init_svg_filter(GF_Compositor *compositor, GF_Node *node) +{ + GF_FilterStack *stack; + GF_SAFEALLOC(stack, GF_FilterStack); + gf_node_set_private(node, stack); + gf_node_set_callback_function(node, svg_traverse_filter); + + + gf_sc_texture_setup(&stack->txh, compositor, node); + stack->drawable = drawable_new(); + /*draw the cache through traverse callback*/ + stack->drawable->flags |= DRAWABLE_USE_TRAVERSE_DRAW; + stack->drawable->node = node; + gf_sc_texture_allocate(&stack->txh); +} + +#endif + + diff --git a/src/compositor/svg_font.c b/src/compositor/svg_font.c index 7e16c92..48d0012 100644 --- a/src/compositor/svg_font.c +++ b/src/compositor/svg_font.c @@ -187,8 +187,8 @@ static void svg_traverse_font(GF_Node *node, void *rs, Bool is_destroy) GF_Font *font = gf_node_get_private(node); if (font) { gf_font_manager_unregister_font(font->ft_mgr, font); - if (font->name) free(font->name); - free(font); + if (font->name) gf_free(font->name); + gf_free(font); } } } @@ -205,8 +205,8 @@ static void svg_font_on_load(GF_Node *handler, GF_DOM_Event *event, GF_Node *obs /*brute-force signaling that all fonts have changed and texts must be recomputed*/ compositor->reset_fonts = 1; - compositor->draw_next_frame = 1; - + gf_sc_next_frame_state(compositor, GF_SC_DRAW_FRAME); + compositor->fonts_pending--; } void compositor_init_svg_font(GF_Compositor *compositor, GF_Node *node) @@ -227,7 +227,7 @@ void compositor_init_svg_font(GF_Compositor *compositor, GF_Node *node) GF_SAFEALLOC(font, GF_Font); e = gf_font_manager_register_font(compositor->font_manager, font); if (e) { - free(font); + gf_free(font); return; } font->ft_mgr = compositor->font_manager; @@ -237,7 +237,7 @@ void compositor_init_svg_font(GF_Compositor *compositor, GF_Node *node) font->udta = node_font; gf_node_set_private(node_font, font); gf_node_set_callback_function(node_font, svg_traverse_font); - font->name = strdup(atts.font_family->value); + font->name = gf_strdup(atts.font_family->value); font->em_size = atts.units_per_em ? FIX2INT( gf_ceil(atts.units_per_em->value) ) : 1000; /*Inconsistency between SVG 1.2 and 1.1 @@ -299,7 +299,7 @@ static void svg_traverse_glyph(GF_Node *node, void *rs, Bool is_destroy) GF_Font *font; GF_Glyph *prev_glyph, *a_glyph; SVG_GlyphStack *st = gf_node_get_private(node); - if (st->unicode) free(st->unicode); + if (st->unicode) gf_free(st->unicode); font = st->font; prev_glyph = NULL; @@ -314,7 +314,7 @@ static void svg_traverse_glyph(GF_Node *node, void *rs, Bool is_destroy) } else { font->glyph = st->glyph.next; } - free(st); + gf_free(st); } } @@ -354,7 +354,7 @@ void compositor_init_svg_glyph(GF_Compositor *compositor, GF_Node *node) st->uni_len = 1; } else { st->glyph.utf_name = (u32) st; - st->unicode = malloc(sizeof(u16)*len); + st->unicode = gf_malloc(sizeof(u16)*len); st->uni_len = len; memcpy(st->unicode, utf_name, sizeof(u16)*len); } @@ -456,10 +456,10 @@ static void svg_traverse_font_face_uri(GF_Node *node, void *rs, Bool is_destroy) FontURIStack *st = gf_node_get_private(node); if (st) { gf_font_manager_unregister_font(st->font->ft_mgr, st->font); - if (st->font->name) free(st->font->name); - free(st->font); + if (st->font->name) gf_free(st->font->name); + gf_free(st->font); if (st->mo) gf_mo_unload_xlink_resource(node, st->mo); - free(st); + gf_free(st); } } } @@ -495,7 +495,7 @@ void compositor_init_svg_font_face_uri(GF_Compositor *compositor, GF_Node *node) GF_SAFEALLOC(font, GF_Font); e = gf_font_manager_register_font(compositor->font_manager, font); if (e) { - free(font); + gf_free(font); return; } GF_SAFEALLOC(stack, FontURIStack); @@ -508,11 +508,12 @@ void compositor_init_svg_font_face_uri(GF_Compositor *compositor, GF_Node *node) font->load_glyph = svg_font_uri_load_glyph; font->get_alias = svg_font_uri_get_alias; font->udta = node; - font->name = strdup(atts.font_family->value); + font->name = gf_strdup(atts.font_family->value); gf_node_set_private(node, stack); gf_node_set_callback_function(node, svg_traverse_font_face_uri); font->not_loaded = 1; + compositor->fonts_pending++; svg_font_uri_check(node, stack); } diff --git a/src/compositor/svg_geometry.c b/src/compositor/svg_geometry.c index 4ec7c31..2d0a666 100644 --- a/src/compositor/svg_geometry.c +++ b/src/compositor/svg_geometry.c @@ -251,6 +251,7 @@ void svg_drawable_3d_pick(Drawable *drawable, GF_TraverseState *tr_state, DrawAs /*not use in SVG patterns*/ compositor->hit_appear = NULL; compositor->hit_node = drawable->node; + compositor->hit_text = NULL; compositor->hit_use_dom_events = 1; GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[SVG Picking] node %s (def %s) is under mouse - hit %g %g %g\n", gf_node_get_class_name(drawable->node), gf_node_get_name(drawable->node), @@ -409,6 +410,8 @@ static void svg_drawable_traverse(GF_Node *node, void *rs, Bool is_destroy, compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, NULL); } } else if (tr_state->traversing_mode == TRAVERSE_SORT) { + /*reset our flags - this may break reuse of nodes and change-detection in dirty-rect algo */ + gf_node_dirty_clear(node, 0); if (!compositor_svg_is_display_off(tr_state->svg_props) && ( *(tr_state->svg_props->visibility) != SVG_VISIBILITY_HIDDEN) ) { @@ -423,6 +426,8 @@ static void svg_drawable_traverse(GF_Node *node, void *rs, Bool is_destroy, else if (ctx->transform.m[1] || ctx->transform.m[3]) {} else { ctx->flags &= ~CTX_IS_TRANSPARENT; + if (!ctx->aspect.pen_props.width) + ctx->flags |= CTX_NO_ANTIALIAS; } } @@ -433,7 +438,7 @@ static void svg_drawable_traverse(GF_Node *node, void *rs, Bool is_destroy, if (tr_state->visual->type_3d) { if (!drawable->mesh) { drawable->mesh = new_mesh(); - mesh_from_path(drawable->mesh, drawable->path); + if (drawable->path) mesh_from_path(drawable->mesh, drawable->path); } visual_3d_draw_from_context(ctx, tr_state); ctx->drawable = NULL; @@ -488,6 +493,7 @@ static void svg_rect_rebuild(GF_Node *node, Drawable *stack, SVGAllAttributes *a Fixed height = (atts->height ? atts->height->value : 0); drawable_reset_path(stack); + if (!width || !height) return; /*we follow SVG 1.1 and not 1.2 !!*/ if (rx || ry) { diff --git a/src/compositor/svg_grouping.c b/src/compositor/svg_grouping.c index 609db97..a6128e7 100644 --- a/src/compositor/svg_grouping.c +++ b/src/compositor/svg_grouping.c @@ -30,6 +30,7 @@ #include "offscreen_cache.h" #include <gpac/internal/terminal_dev.h> +#include <gpac/internal/scenegraph_dev.h> #include <gpac/mediaobject.h> #include <gpac/nodes_svg.h> @@ -50,6 +51,7 @@ typedef struct SFVec2f parent_vp; /*current VP size used by all children*/ SFVec2f vp; + Fixed dx, dy, vpw, vph; } SVGsvgStack; @@ -89,7 +91,7 @@ static void svg_recompute_viewport_transformation(GF_Node *node, SVGsvgStack *st gf_mx2d_init(mx); if (stack->root_svg) { - const char *frag_uri = gf_inline_get_fragment_uri(node); + const char *frag_uri = gf_scene_get_fragment_uri(node); if (frag_uri) { /*SVGView*/ if (!strncmp(frag_uri, "svgView", 7)) { @@ -104,7 +106,10 @@ static void svg_recompute_viewport_transformation(GF_Node *node, SVGsvgStack *st vb = &ext_vb; } else if (!strncmp(frag_uri, "svgView(transform(", 18)) { - gf_svg_parse_transformlist(&mx, (char *) frag_uri+18); + Bool ret = gf_svg_parse_transformlist(&mx, (char *) frag_uri+18); + if (!ret) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error parsing SVG View transform component: %s\n", frag_uri+18)); + } } } /*fragID*/ @@ -244,6 +249,10 @@ static void svg_recompute_viewport_transformation(GF_Node *node, SVGsvgStack *st break; } gf_mx2d_add_translation(&stack->viewbox_mx, dx, dy); + stack->dx = dx; + stack->dy = dy; + stack->vpw = vp_w; + stack->vph = vp_h; /*we need a clipper*/ if (stack->root_svg && !tr_state->parent_anim_atts && (par.meetOrSlice==SVG_MEETORSLICE_SLICE)) { @@ -266,7 +275,7 @@ static void svg_recompute_viewport_transformation(GF_Node *node, SVGsvgStack *st static void svg_traverse_svg(GF_Node *node, void *rs, Bool is_destroy) { - Bool rootmost_svg; + Bool rootmost_svg, send_resize; u32 viewport_color; SVGsvgStack *stack; GF_Matrix2D backup_matrix, vb_bck; @@ -287,11 +296,11 @@ static void svg_traverse_svg(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { if (stack->svg_props) { gf_svg_properties_reset_pointers(stack->svg_props); - free(stack->svg_props); + gf_free(stack->svg_props); } gf_sc_check_focus_upon_destroy(node); if (stack->vp_fill) drawable_del(stack->vp_fill); - free(stack); + gf_free(stack); return; } @@ -329,14 +338,18 @@ static void svg_traverse_svg(GF_Node *node, void *rs, Bool is_destroy) invalidate_flag = tr_state->invalidate_all; is_dirty = gf_node_dirty_get(node); - if (is_dirty &GF_SG_CHILD_DIRTY) drawable_reset_group_highlight(tr_state, node); + if (is_dirty & GF_SG_CHILD_DIRTY) drawable_reset_group_highlight(tr_state, node); gf_node_dirty_clear(node, 0); - if ((stack->parent_vp.x != tr_state->vp_size.x) || (stack->parent_vp.y != tr_state->vp_size.y)) + send_resize = 0; + if ((stack->parent_vp.x != tr_state->vp_size.x) || (stack->parent_vp.y != tr_state->vp_size.y)) { is_dirty = 1; + send_resize = 1; + } - if (is_dirty || tr_state->visual->compositor->recompute_ar) + if (is_dirty || tr_state->visual->compositor->recompute_ar) { svg_recompute_viewport_transformation(node, stack, tr_state, &all_atts); + } gf_mx2d_copy(tr_state->vb_transform, stack->viewbox_mx); @@ -419,6 +432,33 @@ static void svg_traverse_svg(GF_Node *node, void *rs, Bool is_destroy) prev_vp = tr_state->vp_size; tr_state->vp_size = stack->vp; + /*the event may trigger scripts which may delete nodes / modify the scene. We therefore send the resize event + before traversing the scene*/ + if (send_resize) { + GF_DOM_Event evt; + memset(&evt, 0, sizeof(GF_DOM_Event)); + evt.bubbles = 1; + evt.type = GF_EVENT_RESIZE; + gf_dom_event_fire(node, &evt); + } + if ((stack->vp.x != prev_vp.x) || (stack->vp.y != prev_vp.y)) { + GF_Scene *scene = node->sgprivate->scenegraph->userpriv; + + if (scene) { + GF_DOM_Event evt; + memset(&evt, 0, sizeof(GF_DOM_Event)); + evt.bubbles = 0; + evt.screen_rect.width = stack->vpw; + evt.screen_rect.height = stack->vph; + evt.screen_rect.x = stack->dx; + evt.screen_rect.y = stack->dy; + evt.prev_translate.x = stack->vp.x; + evt.prev_translate.y = stack->vp.y; + evt.type = GF_EVENT_VP_RESIZE; + gf_scene_notify_event(scene, 0, NULL, &evt); + } + } + if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) { gf_sc_get_nodes_bounds(node, ((SVG_Element *)node)->children, tr_state, NULL); } else { @@ -498,11 +538,11 @@ static void svg_traverse_g(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { SVGgStack *group = gf_node_get_private(node); #ifdef GF_SR_USE_VIDEO_CACHE - group_2d_destroy(node, group); + group_2d_destroy_svg(node, group); #else if (group->cache) group_cache_del(group->cache); #endif - free(group); + gf_free(group); gf_sc_check_focus_upon_destroy(node); return; } @@ -533,8 +573,18 @@ static void svg_traverse_g(GF_Node *node, void *rs, Bool is_destroy) if (tr_state->traversing_mode == TRAVERSE_GET_BOUNDS) { gf_sc_get_nodes_bounds(node, ((SVG_Element *)node)->children, tr_state, NULL); } else if (tr_state->traversing_mode == TRAVERSE_SORT) { +#ifdef GF_SR_USE_DEPTH + Fixed scale, offset, dscale, doffset; +#endif Fixed opacity = FIX_ONE; - SVGgStack *group = gf_node_get_private(node); + Bool clear = 0; + SVGgStack *group; + + if (!tr_state->in_svg_filter && all_atts.filter && all_atts.filter->iri.target) { + svg_draw_filter(all_atts.filter->iri.target, node, tr_state); + return; + } + group = gf_node_get_private(node); if (tr_state->parent_use_opacity) { opacity = tr_state->parent_use_opacity->value; @@ -543,7 +593,23 @@ static void svg_traverse_g(GF_Node *node, void *rs, Bool is_destroy) if (all_atts.opacity) { opacity = gf_mulfix(opacity, all_atts.opacity->value); } - if (gf_node_dirty_get(node)&GF_SG_CHILD_DIRTY) drawable_reset_group_highlight(tr_state, node); + if (gf_node_dirty_get(node)&GF_SG_CHILD_DIRTY) { + drawable_reset_group_highlight(tr_state, node); + clear=1; + } + +#ifdef GF_SR_USE_DEPTH + dscale = FIX_ONE; + doffset=0; + if (all_atts.gpac_depthGain && all_atts.gpac_depthGain->type==SVG_NUMBER_VALUE) dscale = all_atts.gpac_depthGain->value; + if (all_atts.gpac_depthOffset && all_atts.gpac_depthOffset->type==SVG_NUMBER_VALUE) doffset = all_atts.gpac_depthOffset->value; + scale = tr_state->depth_gain; + offset = tr_state->depth_offset; + // new offset is multiplied by parent gain and added to parent offset + tr_state->depth_offset = gf_mulfix(doffset, scale) + offset; + // gain is multiplied by parent gain + tr_state->depth_gain = gf_mulfix(scale, dscale); +#endif if (opacity < FIX_ONE) { if (!group->cache) { @@ -557,10 +623,8 @@ static void svg_traverse_g(GF_Node *node, void *rs, Bool is_destroy) #ifdef GF_SR_USE_VIDEO_CACHE group_2d_cache_traverse(node, group, tr_state); #else - group_cache_traverse(node, group->cache, tr_state, group->cache->force_recompute); + group_cache_traverse(node, group->cache, tr_state, group->cache->force_recompute, 0); #endif - gf_node_dirty_clear(node, 0); - } else { #ifdef GF_SR_USE_VIDEO_CACHE Bool group_cached; @@ -599,7 +663,14 @@ static void svg_traverse_g(GF_Node *node, void *rs, Bool is_destroy) compositor_svg_traverse_children(((SVG_Element *)node)->children, tr_state); #endif } + if (clear) gf_node_dirty_clear(node, 0); + drawable_check_focus_highlight(node, tr_state, NULL); + +#ifdef GF_SR_USE_DEPTH + tr_state->depth_gain = scale; + tr_state->depth_offset = offset; +#endif } else { compositor_svg_traverse_children(((SVG_Element *)node)->children, tr_state); } @@ -668,7 +739,7 @@ static void svg_traverse_switch(GF_Node *node, void *rs, Bool is_destroy) GF_TraverseState *tr_state = (GF_TraverseState *) rs; if (is_destroy) { - free(selected_idx); + gf_free(selected_idx); gf_sc_check_focus_upon_destroy(node); return; } @@ -708,6 +779,8 @@ static void svg_traverse_switch(GF_Node *node, void *rs, Bool is_destroy) } else if (*selected_idx >= 0) { GF_Node *child = gf_node_list_get_child(((SVG_Element *)node)->children, *selected_idx); gf_node_traverse(child, tr_state); + + drawable_check_focus_highlight(node, tr_state, NULL); } compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d); } @@ -761,6 +834,8 @@ static void svg_traverse_a(GF_Node *node, void *rs, Bool is_destroy) gf_sc_get_nodes_bounds(node, ((SVG_Element *)node)->children, tr_state, NULL); } else { compositor_svg_traverse_children(((SVG_Element *)node)->children, tr_state); + if (tr_state->traversing_mode==TRAVERSE_SORT) + drawable_check_focus_highlight(node, tr_state, NULL); } compositor_svg_restore_parent_transformation(tr_state, &backup_matrix, &mx_3d); memcpy(tr_state->svg_props, &backup_props, styling_size); @@ -787,7 +862,7 @@ static Bool is_timing_target(GF_Node *n) static void svg_a_set_view(GF_Node *handler, GF_Compositor *compositor, const char *url) { - gf_inline_set_fragment_uri(handler, url); + gf_scene_set_fragment_uri(handler, url); /*force recompute viewbox of root SVG - FIXME in full this should be the parent svg*/ gf_node_dirty_set(gf_sg_get_root_node(gf_node_get_graph(handler)), 0, 0); @@ -826,7 +901,7 @@ static void svg_a_handle_event(GF_Node *handler, GF_DOM_Event *event, GF_Node *o if (!evt.navigate.to_url) evt.navigate.to_url = "document internal link"; } - compositor->user->EventProc(compositor->user->opaque, &evt); + gf_term_send_event(compositor->term, &evt); return; } @@ -845,20 +920,20 @@ static void svg_a_handle_event(GF_Node *handler, GF_DOM_Event *event, GF_Node *o if (evt.navigate.to_url[0] != '#') { if (compositor->term) { - gf_inline_process_anchor(handler, &evt); + gf_scene_process_anchor(handler, &evt); } else { - compositor->user->EventProc(compositor->user->opaque, &evt); + gf_term_send_event(compositor->term, &evt); } - free((char *)evt.navigate.to_url); + gf_free((char *)evt.navigate.to_url); return; } all_atts.xlink_href->target = gf_sg_find_node_by_name(gf_node_get_graph(handler), (char *) evt.navigate.to_url+1); if (all_atts.xlink_href->target) { all_atts.xlink_href->type = XMLRI_ELEMENTID; - free((char *)evt.navigate.to_url); + gf_free((char *)evt.navigate.to_url); } else { svg_a_set_view(handler, compositor, evt.navigate.to_url + 1); - free((char *)evt.navigate.to_url); + gf_free((char *)evt.navigate.to_url); return; } } @@ -929,7 +1004,7 @@ static void svg_traverse_resource(GF_Node *node, void *rs, Bool is_destroy, Bool if (is_destroy) { if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource); - free(stack); + gf_free(stack); return; } @@ -1031,7 +1106,11 @@ static void svg_traverse_resource(GF_Node *node, void *rs, Bool is_destroy, Bool drawable_check_focus_highlight(node, tr_state, NULL); if (is_fragment) { - gf_node_traverse(used_node, tr_state); + /*we must have exclusive access to the fragment*/ + if (gf_scene_lock(stack->inline_sg, 1)) { + gf_node_traverse(used_node, tr_state); + gf_scene_lock(stack->inline_sg, 0); + } } else { gf_sc_traverse_subscene(tr_state->visual->compositor, node, stack->inline_sg, tr_state); } @@ -1086,8 +1165,9 @@ static void svg_animation_smil_update(GF_Node *node, SVGlinkStack *stack, Fixed if (stack->needs_play) { gf_mo_play(stack->resource, clipBegin, clipEnd, 0); stack->needs_play = 0; - } else { - new_res = gf_mo_load_xlink_resource(node, 1, clipBegin, clipEnd); + } else { + Bool primary = all_atts.gpac_useAsPrimary ? *all_atts.gpac_useAsPrimary : 1; + new_res = gf_mo_load_xlink_resource(node, primary, clipBegin, clipEnd); if (new_res != stack->resource) { if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource); if (all_atts.xlink_href) all_atts.xlink_href->target = NULL; @@ -1161,12 +1241,14 @@ static void svg_traverse_animation(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { if (stack->resource) gf_mo_unload_xlink_resource(node, stack->resource); - free(stack); + gf_free(stack); return; } + gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); + + if (!stack->inline_sg && !stack->resource) { if (!stack->init_vis_state) { - gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (all_atts.initialVisibility && (*all_atts.initialVisibility==SVG_INITIALVISIBILTY_ALWAYS)) { stack->init_vis_state = 2; svg_animation_smil_update(node, stack, 0); @@ -1178,7 +1260,6 @@ static void svg_traverse_animation(GF_Node *node, void *rs, Bool is_destroy) return; } - gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); if (!all_atts.width || !all_atts.height) return; if (!all_atts.width->value || !all_atts.height->value) return; @@ -1233,8 +1314,9 @@ static void svg_traverse_animation(GF_Node *node, void *rs, Bool is_destroy) clip = gf_rect_pixelize(&rc); // gf_irect_intersect(&tr_state->visual->top_clipper, &clip); - if (!stack->inline_sg && stack->resource) + if (!stack->inline_sg && stack->resource) { stack->inline_sg = gf_mo_get_scenegraph(stack->resource); + } if (stack->inline_sg) { gf_sc_traverse_subscene(tr_state->visual->compositor, node, stack->inline_sg, tr_state); @@ -1304,7 +1386,7 @@ GF_Node *compositor_svg_get_xlink_resource_node(GF_Node *node, XMLRI *xlink) return gf_sg_get_root_node(stack->inline_sg); case TAG_SVG_use: stack = gf_node_get_private(node); - if (stack->fragment_id) + if (stack && stack->fragment_id) return gf_sg_find_node_by_name(stack->inline_sg, (char *) stack->fragment_id+1); return xlink ? xlink->target : NULL; } diff --git a/src/compositor/svg_media.c b/src/compositor/svg_media.c index e3c01b7..81da172 100644 --- a/src/compositor/svg_media.c +++ b/src/compositor/svg_media.c @@ -254,7 +254,7 @@ static void svg_traverse_bitmap(GF_Node *node, void *rs, Bool is_destroy) if (stack->audio) { gf_node_unregister(stack->audio, NULL); } - free(stack); + gf_free(stack); return; } @@ -286,7 +286,7 @@ static void svg_traverse_bitmap(GF_Node *node, void *rs, Bool is_destroy) stack->audio_dirty = 1; } - svg_play_texture(stack, &all_atts); + if (stack->txurl.count) svg_play_texture(stack, &all_atts); gf_node_dirty_clear(node, GF_SG_SVG_XLINK_HREF_DIRTY); } @@ -395,8 +395,11 @@ static void SVG_Update_image(GF_TextureHandler *txh) gf_sc_texture_update_frame(txh, 0); /*URL is present but not opened - redraw till fetch*/ - if (txh->stream && (!txh->tx_io || txh->needs_refresh) ) + if (txh->stream && (!txh->tx_io || txh->needs_refresh) ) { + /*mark all subtrees using this image as dirty*/ + gf_node_dirty_parents(txh->owner); gf_sc_invalidate(txh->compositor, NULL); + } } static void svg_traverse_image(GF_Node *node, void *rs, Bool is_destroy) @@ -414,7 +417,7 @@ void compositor_init_svg_image(GF_Compositor *compositor, GF_Node *node) gf_sc_texture_setup(&stack->txh, compositor, node); stack->txh.update_texture_fcnt = SVG_Update_image; - stack->txh.flags = 0; + stack->txh.flags = GF_SR_TEXTURE_SVG; /*force first processing of xlink-href*/ gf_node_dirty_set(node, GF_SG_SVG_XLINK_HREF_DIRTY, 0); @@ -483,6 +486,7 @@ static void SVG_Update_video(GF_TextureHandler *txh) /*we have no choice but retraversing the graph until we're inactive since the movie framerate and the compositor framerate are likely to be different */ if (!txh->stream_finished) + if (txh->needs_refresh) gf_sc_invalidate(txh->compositor, NULL); if (stack->stop_requested) { @@ -498,7 +502,7 @@ static void svg_video_smil_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_scene switch (status) { case SMIL_TIMING_EVAL_UPDATE: if (!stack->txh.is_open) { - svg_play_texture((SVG_video_stack*)stack, NULL); + if (stack->txurl.count) svg_play_texture((SVG_video_stack*)stack, NULL); } else if (stack->txh.stream_finished && (gf_smil_get_media_duration(rti)<0) ) { Double dur = gf_mo_get_duration(stack->txh.stream); @@ -535,7 +539,7 @@ void compositor_init_svg_video(GF_Compositor *compositor, GF_Node *node) gf_sc_texture_setup(&stack->txh, compositor, node); stack->txh.update_texture_fcnt = SVG_Update_video; - stack->txh.flags = 0; + stack->txh.flags = GF_SR_TEXTURE_SVG; /*force first processing of xlink-href*/ gf_node_dirty_set(node, GF_SG_SVG_XLINK_HREF_DIRTY, 0); @@ -577,15 +581,17 @@ static void svg_audio_smil_evaluate_ex(SMIL_Timing_RTI *rti, Fixed normalized_sc switch (status) { case SMIL_TIMING_EVAL_UPDATE: if (!stack->is_active) { - SVGAllAttributes atts; - gf_svg_flatten_attributes((SVG_Element*) (video ? video : audio), &atts); - - if (gf_sc_audio_open(&stack->input, &stack->aurl, - atts.clipBegin ? (*atts.clipBegin) : 0.0, - atts.clipEnd ? (*atts.clipEnd) : -1.0) == GF_OK) - { - gf_mo_set_speed(stack->input.stream, FIX_ONE); - stack->is_active = 1; + if (stack->aurl.count) { + SVGAllAttributes atts; + gf_svg_flatten_attributes((SVG_Element*) (video ? video : audio), &atts); + + if (gf_sc_audio_open(&stack->input, &stack->aurl, + atts.clipBegin ? (*atts.clipBegin) : 0.0, + atts.clipEnd ? (*atts.clipEnd) : -1.0) == GF_OK) + { + gf_mo_set_speed(stack->input.stream, FIX_ONE); + stack->is_active = 1; + } } } else if (!slave_audio && stack->input.stream_finished && (gf_smil_get_media_duration(rti) < 0) ) { @@ -634,10 +640,9 @@ static void svg_traverse_audio_ex(GF_Node *node, void *rs, Bool is_destroy, SVGP SVG_audio_stack *stack = (SVG_audio_stack *)gf_node_get_private(node); if (is_destroy) { - gf_sc_audio_stop(&stack->input); - gf_sc_audio_unregister(&stack->input); + gf_sc_audio_predestroy(&stack->input); gf_sg_mfurl_del(stack->aurl); - free(stack); + gf_free(stack); return; } if (stack->is_active) { @@ -654,8 +659,26 @@ static void svg_traverse_audio_ex(GF_Node *node, void *rs, Bool is_destroy, SVGP } if (gf_node_dirty_get(node) & GF_SG_SVG_XLINK_HREF_DIRTY) { - gf_term_get_mfurl_from_xlink(node, &(stack->aurl)); + SVGAllAttributes atts; + if (stack->is_active) + gf_sc_audio_stop(&stack->input); + gf_node_dirty_clear(node, GF_SG_SVG_XLINK_HREF_DIRTY); + gf_term_get_mfurl_from_xlink(node, &(stack->aurl)); + + gf_svg_flatten_attributes((SVG_Element*) node, &atts); + + if (stack->aurl.count && (gf_sc_audio_open(&stack->input, &stack->aurl, + atts.clipBegin ? (*atts.clipBegin) : 0.0, + atts.clipEnd ? (*atts.clipEnd) : -1.0) == GF_OK) + + ) { + gf_mo_set_speed(stack->input.stream, FIX_ONE); + stack->is_active = 1; + } else if (stack->is_active) { + gf_sc_audio_unregister(&stack->input); + stack->is_active = 0; + } } /*store mute flag*/ diff --git a/src/compositor/svg_paint_servers.c b/src/compositor/svg_paint_servers.c index 7dcdffb..832031f 100644 --- a/src/compositor/svg_paint_servers.c +++ b/src/compositor/svg_paint_servers.c @@ -30,15 +30,20 @@ #include "texturing.h" +enum +{ + GF_SR_TEXTURE_GRAD_REGISTERED = 1<<6, + GF_SR_TEXTURE_GRAD_NO_RGB = 1<<7, +}; typedef struct { GF_TextureHandler txh; - Bool no_rgb_support; Bool linear; Bool animated; Fixed *keys; u32 *cols; + u32 current_frame; } SVG_GradientStack; @@ -46,10 +51,10 @@ static void SVG_DestroyPaintServer(GF_Node *node) { SVG_GradientStack *st = (SVG_GradientStack *) gf_node_get_private(node); if (st) { - if (st->cols) free(st->cols); - if (st->keys) free(st->keys); + if (st->cols) gf_free(st->cols); + if (st->keys) gf_free(st->keys); gf_sc_texture_destroy(&st->txh); - free(st); + gf_free(st); } } @@ -72,7 +77,7 @@ static GF_Node *svg_copy_gradient_attributes_from(GF_Node *node, SVGAllAttribute iri->type = XMLRI_ELEMENTID; iri->target = n; gf_node_register_iri(sg, iri); - free(iri->string); + gf_free(iri->string); iri->string = NULL; } else { break; @@ -136,9 +141,9 @@ static void svg_gradient_traverse(GF_Node *node, GF_TraverseState *tr_state, Boo if (gf_node_dirty_get(node)) { is_dirty = all_dirty = 1; gf_node_dirty_clear(node, 0); - if (st->cols) free(st->cols); + if (st->cols) gf_free(st->cols); st->cols = NULL; - if (st->keys) free(st->keys); + if (st->keys) gf_free(st->keys); st->keys = NULL; st->animated = gf_node_animation_count(node) ? 1 : 0; @@ -151,8 +156,8 @@ static void svg_gradient_traverse(GF_Node *node, GF_TraverseState *tr_state, Boo if (!st->cols) { count = gf_node_list_get_count(children); - st->cols = (u32*)malloc(sizeof(u32)*count); - st->keys = (Fixed*)malloc(sizeof(Fixed)*count); + st->cols = (u32*)gf_malloc(sizeof(u32)*count); + st->keys = (Fixed*)gf_malloc(sizeof(Fixed)*count); } nb_col = 0; max_offset = 0; @@ -236,6 +241,7 @@ static void svg_gradient_traverse(GF_Node *node, GF_TraverseState *tr_state, Boo tr_state->svg_flags = backup_flags_1; } + static void svg_update_gradient(SVG_GradientStack *st, GF_ChildNodeItem *children, Bool linear) { SVGPropertiesPointers *svgp; @@ -243,18 +249,25 @@ static void svg_update_gradient(SVG_GradientStack *st, GF_ChildNodeItem *childre GF_TraverseState *tr_state = st->txh.compositor->traverse_state; if (!gf_node_dirty_get(node)) { - if (!st->animated) return; + if (st->current_frame==st->txh.compositor->current_frame) return; + st->current_frame = st->txh.compositor->current_frame; + st->txh.needs_refresh = 0; +// if (!st->animated) return; } - GF_SAFEALLOC(svgp, SVGPropertiesPointers); - gf_svg_properties_init_pointers(svgp); - tr_state->svg_props = svgp; + if (!tr_state->svg_props) { + GF_SAFEALLOC(svgp, SVGPropertiesPointers); + gf_svg_properties_init_pointers(svgp); + tr_state->svg_props = svgp; - svg_gradient_traverse(node, tr_state, 0); + svg_gradient_traverse(node, tr_state, 0); - gf_svg_properties_reset_pointers(svgp); - free(svgp); - tr_state->svg_props = NULL; + gf_svg_properties_reset_pointers(svgp); + gf_free(svgp); + tr_state->svg_props = NULL; + } else { + svg_gradient_traverse(node, tr_state, 0); + } } @@ -341,9 +354,14 @@ void compositor_svg_build_gradient_texture(GF_TextureHandler *txh) if (!txh->tx_io) return; + if (!(txh->flags & GF_SR_TEXTURE_GRAD_REGISTERED)) { + txh->flags |= GF_SR_TEXTURE_GRAD_REGISTERED; + if (gf_list_find(txh->compositor->textures, txh)<0) + gf_list_insert(txh->compositor->textures, txh, 0); + } if (txh->data) { - free(txh->data); + gf_free(txh->data); txh->data = NULL; } stencil = gf_sc_texture_get_stencil(txh); @@ -359,33 +377,33 @@ void compositor_svg_build_gradient_texture(GF_TextureHandler *txh) } transparent = st->txh.transparent; - if (st->no_rgb_support) transparent = 1; + if (st->txh.flags & GF_SR_TEXTURE_GRAD_NO_RGB) transparent = 1; if (transparent) { if (!txh->data) { - txh->data = (char *) malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); + txh->data = (char *) gf_malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); } else { memset(txh->data, 0, sizeof(char)*txh->stride*txh->height); } e = raster->stencil_set_texture(texture2D, txh->data, GRAD_TEXTURE_SIZE, GRAD_TEXTURE_SIZE, 4*GRAD_TEXTURE_SIZE, GF_PIXEL_ARGB, GF_PIXEL_ARGB, 1); } else { if (!txh->data) { - txh->data = (char *) malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*3); + txh->data = (char *) gf_malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*3); } e = raster->stencil_set_texture(texture2D, txh->data, GRAD_TEXTURE_SIZE, GRAD_TEXTURE_SIZE, 3*GRAD_TEXTURE_SIZE, GF_PIXEL_RGB_24, GF_PIXEL_RGB_24, 1); /*try with ARGB (it actually is needed for GDIplus module since GDIplus cannot handle native RGB texture (it works in BGR)*/ if (e) { /*remember for later use*/ - st->no_rgb_support = 1; + st->txh.flags |= GF_SR_TEXTURE_GRAD_NO_RGB; transparent = 1; - free(txh->data); - txh->data = (char *) malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); + gf_free(txh->data); + txh->data = (char *) gf_malloc(sizeof(char)*GRAD_TEXTURE_SIZE*GRAD_TEXTURE_SIZE*4); e = raster->stencil_set_texture(texture2D, txh->data, GRAD_TEXTURE_SIZE, GRAD_TEXTURE_SIZE, 4*GRAD_TEXTURE_SIZE, GF_PIXEL_ARGB, GF_PIXEL_ARGB, 1); } } if (e) { - free(txh->data); + gf_free(txh->data); txh->data = NULL; raster->stencil_delete(texture2D); raster->surface_delete(surface); @@ -480,11 +498,15 @@ static void SVG_LG_ComputeMatrix(GF_TextureHandler *txh, GF_Rect *bounds, GF_Mat GF_STENCIL stencil; SFVec2f start, end; SVGAllAttributes all_atts; + SVG_Element *lg = (SVG_Element *) txh->owner; + SVG_GradientStack *st = (SVG_GradientStack *) gf_node_get_private(txh->owner); if (!txh->tx_io) return; stencil = gf_sc_texture_get_stencil(txh); if (!stencil) return; + svg_update_gradient(st, lg->children, 1); + gf_svg_flatten_attributes((SVG_Element*)txh->owner, &all_atts); /*get "transfered" attributed from xlink:href if any*/ @@ -549,8 +571,14 @@ void compositor_init_svg_linearGradient(GF_Compositor *compositor, GF_Node *node SVG_GradientStack *st; GF_SAFEALLOC(st, SVG_GradientStack); - gf_sc_texture_setup(&st->txh, compositor, node); + /*!!! Gradients are textures but are not registered as textures with the compositor in order to avoid updating + too many textures each frame - gradients are only registered with the compositor when they are used in OpenGL, in order + to release associated HW resource when no longer used*/ + st->txh.owner = node; + st->txh.compositor = compositor; st->txh.update_texture_fcnt = SVG_UpdateLinearGradient; + st->txh.flags = GF_SR_TEXTURE_SVG; + st->txh.compute_gradient_matrix = SVG_LG_ComputeMatrix; st->linear = 1; gf_node_set_private(node, st); @@ -573,12 +601,17 @@ static void SVG_RG_ComputeMatrix(GF_TextureHandler *txh, GF_Rect *bounds, GF_Mat SFVec2f center, focal; Fixed radius; SVGAllAttributes all_atts; + SVG_Element *rg = (SVG_Element *) txh->owner; + SVG_GradientStack *st = (SVG_GradientStack *) gf_node_get_private(txh->owner); + /*create gradient brush if needed*/ if (!txh->tx_io) return; stencil = gf_sc_texture_get_stencil(txh); if (!stencil) return; + svg_update_gradient(st, rg->children, 0); + gf_svg_flatten_attributes((SVG_Element*)txh->owner, &all_atts); /*get "transfered" attributed from xlink:href if any*/ @@ -651,7 +684,13 @@ void compositor_init_svg_radialGradient(GF_Compositor *compositor, GF_Node *node SVG_GradientStack *st; GF_SAFEALLOC(st, SVG_GradientStack); - gf_sc_texture_setup(&st->txh, compositor, node); + /*!!! Gradients are textures but are not registered as textures with the compositor in order to avoid updating + too many textures each frame - gradients are only registered with the compositor when they are used in OpenGL, in order + to release associated HW resource when no longer used*/ + st->txh.owner = node; + st->txh.compositor = compositor; + st->txh.flags = GF_SR_TEXTURE_SVG; + st->txh.update_texture_fcnt = SVG_UpdateRadialGradient; st->txh.compute_gradient_matrix = SVG_RG_ComputeMatrix; gf_node_set_private(node, st); @@ -659,7 +698,7 @@ void compositor_init_svg_radialGradient(GF_Compositor *compositor, GF_Node *node } -static void svg_traverse_PaintServer(GF_Node *node, void *rs, Bool is_destroy) +static void svg_traverse_PaintServer(GF_Node *node, void *rs, Bool is_destroy, Bool is_solid_color) { SVGPropertiesPointers backup_props; SVGAllAttributes all_atts; @@ -669,7 +708,8 @@ static void svg_traverse_PaintServer(GF_Node *node, void *rs, Bool is_destroy) GF_TraverseState *tr_state = (GF_TraverseState *) rs; if (is_destroy) { - SVG_DestroyPaintServer(node); + if (!is_solid_color) + SVG_DestroyPaintServer(node); return; } @@ -684,19 +724,56 @@ static void svg_traverse_PaintServer(GF_Node *node, void *rs, Bool is_destroy) memcpy(tr_state->svg_props, &backup_props, styling_size); tr_state->svg_flags = backup_flags; } + +typedef struct +{ + u32 current_frame; + Bool is_dirty; +} GF_SolidColorStack; + +Bool compositor_svg_solid_color_dirty(GF_Compositor *compositor, GF_Node *node) +{ + GF_SolidColorStack *st = gf_node_get_private(node); + if (st->current_frame==compositor->current_frame) return st->is_dirty; + st->current_frame = compositor->current_frame; + st->is_dirty = gf_node_dirty_get(node) ? 1 : 0; + gf_node_dirty_clear(node, 0); + return st->is_dirty; +} + +static void svg_traverse_solidColor(GF_Node *node, void *rs, Bool is_destroy) +{ + if (is_destroy) { + GF_SolidColorStack *st = gf_node_get_private(node); + gf_free(st); + return; + } + svg_traverse_PaintServer(node, rs, is_destroy, 1); +} + + void compositor_init_svg_solidColor(GF_Compositor *compositor, GF_Node *node) { - gf_node_set_callback_function(node, svg_traverse_PaintServer); + GF_SolidColorStack *st; + GF_SAFEALLOC(st, GF_SolidColorStack); + gf_node_set_private(node, st); + gf_node_set_callback_function(node, svg_traverse_solidColor); +} + +static void svg_traverse_stop(GF_Node *node, void *rs, Bool is_destroy) +{ + svg_traverse_PaintServer(node, rs, is_destroy, 1); } void compositor_init_svg_stop(GF_Compositor *compositor, GF_Node *node) { - gf_node_set_callback_function(node, svg_traverse_PaintServer); + gf_node_set_callback_function(node, svg_traverse_stop); } GF_TextureHandler *compositor_svg_get_gradient_texture(GF_Node *node) { SVG_GradientStack *st = (SVG_GradientStack*) gf_node_get_private((GF_Node *)node); + st->txh.update_texture_fcnt(&st->txh); return &st->txh; } diff --git a/src/compositor/svg_text.c b/src/compositor/svg_text.c index 379b635..e21ff83 100644 --- a/src/compositor/svg_text.c +++ b/src/compositor/svg_text.c @@ -74,7 +74,7 @@ static void svg_finalize_sort(DrawableContext *ctx, SVG_TextStack *st, GF_Traver #endif /*if text selection mode, we must force redraw of the entire text span because we don't if glyphs have been (un)selected*/ - if (!tr_state->direct_draw && + if (!tr_state->immediate_draw && /*text selection on*/ (tr_state->visual->compositor->text_selection /*text sel release*/ @@ -145,7 +145,7 @@ GF_Font *gf_compositor_svg_set_font(GF_FontManager *fm, char *a_font, u32 styles char *sep_end = strchr(a_font+1, '\''); if (sep_end) sep_end[0] = 0; a_font++; - fonts[nb_fonts] = strdup(a_font); + fonts[nb_fonts] = gf_strdup(a_font); nb_fonts++; if (sep_end) sep_end[0] = '\''; } else { @@ -153,7 +153,7 @@ GF_Font *gf_compositor_svg_set_font(GF_FontManager *fm, char *a_font, u32 styles skip = 0; while (a_font[len-skip] == ' ') skip++; if (skip) a_font[len-skip+1] = 0; - fonts[nb_fonts] = strdup(a_font); + fonts[nb_fonts] = gf_strdup(a_font); nb_fonts++; if (skip) a_font[len-skip] = ' '; } @@ -168,7 +168,7 @@ GF_Font *gf_compositor_svg_set_font(GF_FontManager *fm, char *a_font, u32 styles } font = gf_font_manager_set_font_ex(fm, fonts, nb_fonts, styles, check_only); while (nb_fonts) { - free(fonts[nb_fonts-1]); + gf_free(fonts[nb_fonts-1]); nb_fonts--; } return font; @@ -216,7 +216,7 @@ static GF_TextSpan *svg_get_text_span(GF_FontManager *fm, GF_Font *font, Fixed f Bool preserve = (atts->xml_space && (*atts->xml_space==XML_SPACE_PRESERVE)) ? 1 : 0; len = strlen(textContent); - dup_text = malloc(len+1); + dup_text = gf_malloc(len+1); switch (tr_state->last_char_type) { case 2: @@ -278,7 +278,7 @@ static GF_TextSpan *svg_get_text_span(GF_FontManager *fm, GF_Font *font, Fixed f else tr_state->last_char_type = (dup_text[j-1]==' ') ? 1 : 2; /*SVG text is fliped by default (text y-axis is the inverse of SVG y-axis*/ span = gf_font_manager_create_span(fm, font, dup_text, font_size, x_offsets, y_offsets, rotate, lang, 1, 0, tr_state->text_parent); - free(dup_text); + gf_free(dup_text); if (span) span->flags |= GF_TEXT_SPAN_HORIZONTAL; return span; } @@ -321,7 +321,7 @@ static void svg_text_area_reset_state(GF_TraverseState *tr_state) } tr_state->refresh_children_bounds = 1; } - free(st); + gf_free(st); } gf_list_reset(tr_state->x_anchors); } @@ -338,7 +338,7 @@ static void svg_text_area_queue_state(GF_TraverseState *tr_state, GF_TextSpan *s return; } } - st = malloc(sizeof(textArea_state)); + st = gf_malloc(sizeof(textArea_state)); st->first_glyph = first_glyph; st->last_glyph = last_glyph; st->span = span; @@ -421,9 +421,12 @@ static void svg_traverse_dom_text_area(GF_Node *node, SVGAllAttributes *atts, GF break; } word_size += glyph_size; + } else { + // no glyph; + word_size += font->max_advance_h * span->font_scale; } i++; - } + } /* word doesn't fit on line, escape*/ if (!word_size && !last_char_size) break; @@ -503,7 +506,7 @@ static void get_domtext_width(GF_Node *node, SVGAllAttributes *atts, GF_Traverse block_width = (span->glyphs[i] ? span->glyphs[i]->horiz_advance : font->max_advance_h) * span->font_scale; //store width in tr_state->x_anchors - entry = (Fixed*)malloc(sizeof(Fixed)); + entry = (Fixed*)gf_malloc(sizeof(Fixed)); if (span->flags & GF_TEXT_SPAN_RIGHT_TO_LEFT) *entry = -block_width; else *entry = block_width; @@ -524,7 +527,7 @@ static void get_domtext_width(GF_Node *node, SVGAllAttributes *atts, GF_Traverse //if last indicated position, create a new item if ((tr_state->count_x==1)||(tr_state->count_y==1) || !gf_list_count(tr_state->x_anchors) ) { - entry = (Fixed*)malloc(sizeof(Fixed)); + entry = (Fixed*)gf_malloc(sizeof(Fixed)); *entry = block_width; if (span->flags & GF_TEXT_SPAN_RIGHT_TO_LEFT) *entry = -block_width; @@ -811,7 +814,7 @@ static void svg_traverse_text(GF_Node *node, void *rs, Bool is_destroy) drawable_del(st->drawable); svg_reset_text_stack(st); gf_list_del(st->spans); - free(st); + gf_free(st); return; } @@ -962,7 +965,7 @@ static void svg_traverse_text(GF_Node *node, void *rs, Bool is_destroy) while (gf_list_count(tr_state->x_anchors)) { Fixed *f = gf_list_last(tr_state->x_anchors); gf_list_rem_last(tr_state->x_anchors); - free(f); + gf_free(f); } gf_list_del(tr_state->x_anchors); tr_state->x_anchors = NULL; @@ -1034,7 +1037,7 @@ static void svg_traverse_tspan(GF_Node *node, void *rs, Bool is_destroy) drawable_del(st->drawable); svg_reset_text_stack(st); gf_list_del(st->spans); - free(st); + gf_free(st); return; } if (tr_state->traversing_mode==TRAVERSE_DRAW_2D) { @@ -1218,7 +1221,7 @@ static void svg_traverse_textArea(GF_Node *node, void *rs, Bool is_destroy) drawable_del(st->drawable); svg_reset_text_stack(st); gf_list_del(st->spans); - free(st); + gf_free(st); return; } diff --git a/src/compositor/texturing.c b/src/compositor/texturing.c index 6c223ba..251f8d1 100644 --- a/src/compositor/texturing.c +++ b/src/compositor/texturing.c @@ -27,10 +27,6 @@ #include <gpac/options.h> #include "nodes_stacks.h" -#ifdef GPAC_TRISCOPE_MODE -#include "../src/compositor/triscope_renoir/triscope_renoir.h" -#endif - static void update_texture_void(GF_TextureHandler *txh) { @@ -55,12 +51,8 @@ void gf_sc_texture_destroy(GF_TextureHandler *txh) GF_Compositor *compositor = txh->compositor; gf_mx_p(compositor->mx); - if (txh->tx_io) gf_sc_texture_release(txh); + gf_sc_texture_release(txh); if (txh->is_open) gf_sc_texture_stop(txh); -#ifdef GPAC_TRISCOPE_MODE - /*Destroy the renoir object associated to this texture*/ - if (txh->RenoirObject) DestroyRenoirObject (txh->RenoirObject, (GF_RenoirHandler *) txh->compositor->RenoirHandler); -#endif gf_list_del_item(txh->compositor->textures, txh); gf_mx_v(compositor->mx); @@ -81,18 +73,15 @@ GF_Err gf_sc_texture_play_from_to(GF_TextureHandler *txh, MFURL *url, Double sta /*if existing texture in cache destroy it - we don't destroy it on stop to handle MovieTexture*/ if (txh->tx_io) gf_sc_texture_release(txh); - /*store url*/ - gf_sg_vrml_field_copy(&txh->current_url, url, GF_SG_VRML_MFURL); - /*get media object*/ - txh->stream = gf_mo_register(txh->owner, url, lock_scene_timeline); + txh->stream = gf_mo_register(txh->owner, url, lock_scene_timeline, 0); /*bad/Empty URL*/ if (!txh->stream) return GF_NOT_SUPPORTED; /*request play*/ gf_mo_play(txh->stream, start_offset, end_offset, can_loop); txh->last_frame_time = (u32) (-1); - gf_sc_invalidate(txh->compositor, NULL); + //gf_sc_invalidate(txh->compositor, NULL); txh->is_open = 1; return GF_OK; } @@ -104,7 +93,7 @@ GF_Err gf_sc_texture_play(GF_TextureHandler *txh, MFURL *url) Bool loop = 0; if (txh->compositor->term && (txh->compositor->term->play_state!=GF_STATE_PLAYING)) { offset = gf_node_get_scene_time(txh->owner); - loop = /*gf_mo_get_loop(gf_mo_register(txh->owner, url, 0), 0)*/ 1; + loop = /*gf_mo_get_loop(gf_mo_register(txh->owner, url, 0, 0), 0)*/ 1; } return gf_sc_texture_play_from_to(txh, url, offset, -1, loop, 0); } @@ -121,7 +110,6 @@ void gf_sc_texture_stop(GF_TextureHandler *txh) } gf_sc_invalidate(txh->compositor, NULL); gf_mo_stop(txh->stream); - gf_sg_vrml_mf_reset(&txh->current_url, GF_SG_VRML_MFURL); txh->is_open = 0; /*and deassociate object*/ @@ -193,6 +181,7 @@ void gf_sc_texture_update_frame(GF_TextureHandler *txh, Bool disable_resync) case GF_PIXEL_ARGB: case GF_PIXEL_RGBA: case GF_PIXEL_YUVA: + case GF_PIXEL_RGBDS: txh->transparent = 1; break; } @@ -224,9 +213,12 @@ GF_TextureHandler *gf_sc_texture_get_handler(GF_Node *n) { if (!n) return NULL; switch (gf_node_get_tag(n)) { - case TAG_MPEG4_ImageTexture: case TAG_X3D_ImageTexture: return it_get_texture(n); - case TAG_MPEG4_MovieTexture: case TAG_X3D_MovieTexture: return mt_get_texture(n); - case TAG_MPEG4_PixelTexture: case TAG_X3D_PixelTexture: return pt_get_texture(n); +#ifndef GPAC_DISABLE_VRML + case TAG_MPEG4_ImageTexture: + case TAG_MPEG4_CacheTexture: + return it_get_texture(n); + case TAG_MPEG4_MovieTexture: return mt_get_texture(n); + case TAG_MPEG4_PixelTexture: return pt_get_texture(n); case TAG_MPEG4_CompositeTexture2D: case TAG_MPEG4_CompositeTexture3D: @@ -241,6 +233,14 @@ GF_TextureHandler *gf_sc_texture_get_handler(GF_Node *n) if (hdl) hdl->matteTexture = n; return hdl; } +#endif /*GPAC_DISABLE_VRML*/ + +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_ImageTexture: return it_get_texture(n); + case TAG_X3D_MovieTexture: return mt_get_texture(n); + case TAG_X3D_PixelTexture: return pt_get_texture(n); +#endif + #ifndef GPAC_DISABLE_SVG case TAG_SVG_linearGradient: diff --git a/src/compositor/texturing_gl.c b/src/compositor/texturing_gl.c index b4fd8f2..92ee113 100644 --- a/src/compositor/texturing_gl.c +++ b/src/compositor/texturing_gl.c @@ -83,7 +83,7 @@ struct __texture_wrapper /*gl textures vars (gl_type: 2D texture or rectangle (NV ext) )*/ u32 nb_comp, gl_format, gl_type, gl_dtype; #endif -#ifdef GPAC_TRISCOPE_MODE +#ifdef GF_SR_USE_DEPTH char *depth_data; #endif @@ -99,6 +99,11 @@ GF_Err gf_sc_texture_allocate(GF_TextureHandler *txh) void gf_sc_texture_release(GF_TextureHandler *txh) { + if (txh->vout_udta && txh->compositor->video_out->ReleaseTexture) { + txh->compositor->video_out->ReleaseTexture(txh->compositor->video_out, txh); + txh->vout_udta = NULL; + } + if (!txh->tx_io) return; if (txh->tx_io->tx_raster) { txh->compositor->rasterizer->stencil_delete(txh->tx_io->tx_raster); @@ -107,14 +112,15 @@ void gf_sc_texture_release(GF_TextureHandler *txh) #ifndef GPAC_DISABLE_3D if (txh->tx_io->id) glDeleteTextures(1, &txh->tx_io->id); - if (txh->tx_io->scale_data) free(txh->tx_io->scale_data); - if (txh->tx_io->conv_data) free(txh->tx_io->conv_data); + if (txh->tx_io->scale_data) gf_free(txh->tx_io->scale_data); + if (txh->tx_io->conv_data) gf_free(txh->tx_io->conv_data); #endif -#ifdef GPAC_TRISCOPE_MODE - if (txh->tx_io->depth_data) free(txh->tx_io->depth_data); +#ifdef GF_SR_USE_DEPTH + if (txh->tx_io->depth_data) gf_free(txh->tx_io->depth_data); #endif - free(txh->tx_io); + + gf_free(txh->tx_io); txh->tx_io = NULL; } @@ -135,19 +141,18 @@ void gf_sc_texture_reset(GF_TextureHandler *txh) } txh->tx_io->flags |= TX_NEEDS_HW_LOAD; #endif -#ifdef GPAC_TRISCOPE_MODE - /* remove renoir texture from the display list */ - if (txh->RenoirObject) { - DestroyRenoirObject(txh->RenoirObject, txh->compositor->RenoirHandler); - if (txh->tx_io->depth_data) { - free(txh->tx_io->depth_data); - txh->tx_io->depth_data = NULL; - } - txh->RenoirObject = NULL; + +#ifdef GF_SR_USE_DEPTH + if (txh->tx_io->depth_data) { + gf_free(txh->tx_io->depth_data); + txh->tx_io->depth_data = NULL; } - #endif - + + if (txh->vout_udta && txh->compositor->video_out->ReleaseTexture) { + txh->compositor->video_out->ReleaseTexture(txh->compositor->video_out, txh); + txh->vout_udta = NULL; + } } #ifndef GPAC_DISABLE_3D @@ -209,7 +214,9 @@ void gf_sc_texture_disable(GF_TextureHandler *txh) Bool tx_can_use_rect_ext(GF_Compositor *compositor, GF_TextureHandler *txh) { +#ifndef GPAC_DISABLE_VRML u32 i, count; +#endif // compositor->gl_caps.yuv_texture = 0; if (!compositor->gl_caps.rect_texture) return 0; @@ -217,6 +224,7 @@ Bool tx_can_use_rect_ext(GF_Compositor *compositor, GF_TextureHandler *txh) /*this happens ONLY with text texturing*/ if (!txh->owner) return 0; +#ifndef GPAC_DISABLE_VRML count = gf_node_get_parent_count(txh->owner); /*background 2D can use RECT ext without pb*/ @@ -232,6 +240,7 @@ Bool tx_can_use_rect_ext(GF_Compositor *compositor, GF_TextureHandler *txh) } } } +#endif /*GPAC_DISABLE_VRML*/ return 0; } @@ -312,7 +321,7 @@ static Bool tx_setup_format(GF_TextureHandler *txh) } /*note we don't free the data if existing, since this only happen when re-setting up after context loss (same size)*/ if ((txh->tx_io->flags == TX_MUST_SCALE) & !txh->tx_io->scale_data) { - txh->tx_io->scale_data = (char*)malloc(sizeof(char) * txh->tx_io->nb_comp*txh->tx_io->rescale_width*txh->tx_io->rescale_height); + txh->tx_io->scale_data = (char*)gf_malloc(sizeof(char) * txh->tx_io->nb_comp*txh->tx_io->rescale_width*txh->tx_io->rescale_height); memset(txh->tx_io->scale_data , 0, sizeof(char) * txh->tx_io->nb_comp*txh->tx_io->rescale_width*txh->tx_io->rescale_height); } @@ -368,7 +377,7 @@ void txh_unpack_yuv(GF_TextureHandler *txh) u32 i, j; u8 *dst, *y, *u, *v, *p_y, *p_u, *p_v; if (!txh->tx_io->conv_data) { - txh->tx_io->conv_data = (char*)malloc(sizeof(char) * 2 * txh->width * txh->height); + txh->tx_io->conv_data = (char*)gf_malloc(sizeof(char) * 2 * txh->width * txh->height); } p_y = txh->data; p_u = txh->data + txh->stride*txh->height; @@ -406,7 +415,8 @@ hence is never flipped. Otherwise all textures attached to stream are flipped in Bool tx_convert(GF_TextureHandler *txh) { GF_VideoSurface src, dst; - u32 out_stride; + u32 out_stride, i, hy; + char *tmp; GF_Compositor *compositor = (GF_Compositor *)txh->compositor; switch (txh->pixelformat) { @@ -419,6 +429,21 @@ Bool tx_convert(GF_TextureHandler *txh) case GF_PIXEL_RGBA: txh->tx_io->conv_format = txh->pixelformat; txh->tx_io->flags |= TX_NEEDS_HW_LOAD; + + if (!(txh->tx_io->flags & TX_IS_RECT)) return 1; + if (txh->flags & GF_SR_TEXTURE_NO_GL_FLIP) return 1; + + /*if texture is using RECT extension, flip image manually because + texture transforms are not supported in this case ...*/ + tmp = (char*)gf_malloc(sizeof(char)*txh->stride); + hy = txh->height/2; + for (i=0; i<hy; i++) { + memcpy(tmp, txh->data + i*txh->stride, txh->stride); + memcpy(txh->data + i*txh->stride, txh->data + (txh->height - 1 - i) * txh->stride, txh->stride); + memcpy(txh->data + (txh->height - 1 - i) * txh->stride, tmp, txh->stride); + } + gf_free(tmp); + txh->flags |= GF_SR_TEXTURE_NO_GL_FLIP; return 1; case GF_PIXEL_YV12: if (txh->tx_io->gl_format == compositor->gl_caps.yuv_texture) { @@ -437,12 +462,12 @@ Bool tx_convert(GF_TextureHandler *txh) /*convert video to a po of 2 WITHOUT SCALING VIDEO*/ txh->tx_io->conv_w = gf_get_next_pow2(txh->width); txh->tx_io->conv_h = gf_get_next_pow2(txh->height); - txh->tx_io->conv_data = (char*)malloc(sizeof(char) * 3 * txh->tx_io->conv_w * txh->tx_io->conv_h); + txh->tx_io->conv_data = (char*)gf_malloc(sizeof(char) * 3 * txh->tx_io->conv_w * txh->tx_io->conv_h); memset(txh->tx_io->conv_data , 0, sizeof(char) * 3 * txh->tx_io->conv_w * txh->tx_io->conv_h); txh->tx_io->conv_wscale = INT2FIX(txh->width) / txh->tx_io->conv_w; txh->tx_io->conv_hscale = INT2FIX(txh->height) / txh->tx_io->conv_h; } else { - txh->tx_io->conv_data = (char*)malloc(sizeof(char) * 3 * txh->width * txh->height); + txh->tx_io->conv_data = (char*)gf_malloc(sizeof(char) * 3 * txh->width * txh->height); } } out_stride = 3 * ((txh->tx_io->flags & TX_EMULE_POW2) ? txh->tx_io->conv_w : txh->width); @@ -451,16 +476,18 @@ Bool tx_convert(GF_TextureHandler *txh) dst.height = src.height = txh->height; dst.is_hardware_memory = src.is_hardware_memory = 0; - src.pitch = txh->stride; + src.pitch_x = 0; + src.pitch_y = txh->stride; src.pixel_format = txh->pixelformat; src.video_buffer = txh->data; - dst.pitch = out_stride; + dst.pitch_x = 0; + dst.pitch_y = out_stride; txh->tx_io->conv_format = dst.pixel_format = GF_PIXEL_RGB_24; dst.video_buffer = txh->tx_io->conv_data; /*stretch and flip*/ - gf_stretch_bits(&dst, &src, NULL, NULL, 0, 0xFF, 1, NULL, NULL); + gf_stretch_bits(&dst, &src, NULL, NULL, 0xFF, 1, NULL, NULL); txh->tx_io->flags |= TX_NEEDS_HW_LOAD; txh->flags |= GF_SR_TEXTURE_NO_GL_FLIP; return 1; @@ -480,6 +507,7 @@ Bool gf_sc_texture_push_image(GF_TextureHandler *txh, Bool generate_mipmaps, Boo if (for2d) { Bool load_tx = 0; + if (!txh->data) return 0; if (!txh->tx_io->tx_raster) { txh->tx_io->tx_raster = txh->compositor->rasterizer->stencil_new(txh->compositor->rasterizer, GF_STENCIL_TEXTURE); if (!txh->tx_io->tx_raster) return 0; @@ -563,17 +591,19 @@ Bool gf_sc_texture_push_image(GF_TextureHandler *txh, Bool generate_mipmaps, Boo GF_VideoSurface src, dst; src.width = txh->width; src.height = txh->height; - src.pitch = txh->stride; + src.pitch_x = 0; + src.pitch_y = txh->stride; src.pixel_format = txh->pixelformat; src.video_buffer = txh->data; dst.width = txh->tx_io->rescale_width; dst.height = txh->tx_io->rescale_height; - dst.pitch = txh->tx_io->rescale_width*txh->tx_io->nb_comp; + dst.pitch_x = 0; + dst.pitch_y = txh->tx_io->rescale_width*txh->tx_io->nb_comp; dst.pixel_format = txh->pixelformat; dst.video_buffer = txh->tx_io->scale_data; - gf_stretch_bits(&dst, &src, NULL, NULL, 0, 0xFF, 0, NULL, NULL); + gf_stretch_bits(&dst, &src, NULL, NULL, 0xFF, 0, NULL, NULL); } if (first_load) { @@ -618,10 +648,6 @@ void gf_sc_copy_to_stencil(GF_TextureHandler *txh) { u32 i, hy; char *tmp=NULL; -#ifdef GPAC_TRISCOPE_MODE - const char *sOpt; - float OGL_depthGain; -#endif /*in case the ID has been lost, resetup*/ if (!txh->data || !txh->tx_io->tx_raster) return; @@ -632,9 +658,9 @@ void gf_sc_copy_to_stencil(GF_TextureHandler *txh) glReadPixels(0, 0, txh->width, txh->height, GL_RGBA, GL_UNSIGNED_BYTE, txh->data); } else if (txh->pixelformat==GF_PIXEL_RGB_24) { glReadPixels(0, 0, txh->width, txh->height, GL_RGB, GL_UNSIGNED_BYTE, txh->data); - -#ifdef GPAC_TRISCOPE_MODE - } else if (txh->pixelformat==GF_PIXEL_RGBDS) { + } +#ifdef GF_SR_USE_DEPTH + else if (txh->pixelformat==GF_PIXEL_RGBDS) { /*we'll work with one alpha bit (=shape). we'll take the heaviest weighted as this threshold*/ glReadPixels(0, 0, txh->width, txh->height, GL_RGBA, GL_UNSIGNED_BYTE, txh->data); @@ -647,48 +673,52 @@ void gf_sc_copy_to_stencil(GF_TextureHandler *txh) * i.e. z' = G*z - (G - 1), the offset so that z still belongs to [0..1]* */ - glPixelTransferf(GL_DEPTH_SCALE, txh->compositor->OGLDepthGain); - glPixelTransferf(GL_DEPTH_BIAS, txh->compositor->OGLDepthOffset); + //glPixelTransferf(GL_DEPTH_SCALE, txh->compositor->OGLDepthGain); + //glPixelTransferf(GL_DEPTH_BIAS, txh->compositor->OGLDepthOffset); - /*obtain depthmap*/ /*NOTE: could txt width, height change once allocated?*/ - if (!txh->tx_io->depth_data) txh->tx_io->depth_data = (char*)malloc(sizeof(char)*txh->width*txh->height); +#ifndef GPAC_USE_OGL_ES + /*obtain depthmap*/ + if (!txh->tx_io->depth_data) txh->tx_io->depth_data = (char*)gf_malloc(sizeof(char)*txh->width*txh->height); glReadPixels(0, 0, txh->width, txh->height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, txh->tx_io->depth_data); /* depth = alpha & 0xfe shape = plan alpha & 0x01 */ - /*at the moment RENOIR WORKS WITH DSRGB - need to recombine components*/ -#if 1 /*this corresponds to the RGBDS ordering*/ + /*this corresponds to the RGBDS ordering*/ for (i=0; i<txh->height*txh->width; i++) { - u8 ds; - /* erase lowest-weighted depth bit */ - u8 depth = txh->tx_io->depth_data[i] & 0xfe; + u8 alpha; + //inversion + u8 ds = (char) (255 - (int)txh->tx_io->depth_data[i]); /*get alpha*/ - ds = (txh->data[i*4 + 3]); + alpha = (txh->data[i*4 + 3]); + /* if heaviest-weighted alpha bit is set (>128) , turn on shape bit*/ - if (ds & 0x80) depth |= 0x01; - txh->data[i*4+3] = depth; /*insert depth onto alpha*/ + //if (ds & 0x80) depth |= 0x01; + if (alpha & 0x80) ds = (ds >> 1) | 0x80; + else ds = 0x0; + txh->data[i*4+3] = ds; /*insert depth onto alpha*/ } - -#endif #endif + } +#endif /*GF_SR_USE_DEPTH*/ + /*flip image because of openGL*/ - tmp = (char*)malloc(sizeof(char)*txh->stride); + tmp = (char*)gf_malloc(sizeof(char)*txh->stride); hy = txh->height/2; for (i=0; i<hy; i++) { memcpy(tmp, txh->data + i*txh->stride, txh->stride); memcpy(txh->data + i*txh->stride, txh->data + (txh->height - 1 - i) * txh->stride, txh->stride); memcpy(txh->data + (txh->height - 1 - i) * txh->stride, tmp, txh->stride); } - free(tmp); + gf_free(tmp); + //dump depth and rgbds texture } #else -void gf_get_tinygl_depth(GF_TextureHandler *txh) { - +void gf_get_tinygl_depth(GF_TextureHandler *txh) +{ glReadPixels(0, 0, txh->width, txh->height, GL_RGBDS, GL_UNSIGNED_BYTE, txh->data); - } #endif @@ -696,7 +726,6 @@ void gf_get_tinygl_depth(GF_TextureHandler *txh) { Bool gf_sc_texture_get_transform(GF_TextureHandler *txh, GF_Node *tx_transform, GF_Matrix *mx) { - GF_Matrix tmp; Bool ret = 0; gf_mx_init(*mx); @@ -712,6 +741,7 @@ Bool gf_sc_texture_get_transform(GF_TextureHandler *txh, GF_Node *tx_transform, /*WATCHOUT: GL_TEXTURE_RECTANGLE coords are w, h not 1.0, 1.0*/ if (txh->tx_io->flags & TX_IS_RECT) { +// gf_mx_add_translation(mx, 0, -INT2FIX(txh->height), FIX_ONE); gf_mx_add_scale(mx, INT2FIX(txh->width), INT2FIX(txh->height), FIX_ONE); /*disable any texture transforms when using RECT textures (no repeat) ??*/ /*tx_transform = NULL;*/ @@ -726,7 +756,9 @@ Bool gf_sc_texture_get_transform(GF_TextureHandler *txh, GF_Node *tx_transform, #endif } +#ifndef GPAC_DISABLE_X3D if (tx_transform) { + GF_Matrix tmp; switch (gf_node_get_tag(tx_transform)) { case TAG_MPEG4_TextureTransform: case TAG_X3D_TextureTransform: @@ -772,14 +804,14 @@ Bool gf_sc_texture_get_transform(GF_TextureHandler *txh, GF_Node *tx_transform, break; } } +#endif /*GPAC_DISABLE_X3D*/ return ret; } +#if !defined(GPAC_DISABLE_3D) && !defined(GPAC_DISABLE_VRML) + static Bool gf_sc_texture_enable_matte_texture(GF_Node *n) { -#ifdef GPAC_DISABLE_3D - return 0; -#else GF_TextureHandler *b_surf; #ifndef GPAC_USE_TINYGL GF_TextureHandler *matte_hdl; @@ -1098,12 +1130,15 @@ static Bool gf_sc_texture_enable_matte_texture(GF_Node *n) #endif /*GPAC_USE_TINYGL*/ #undef GLTEXPARAM -#endif } +#endif /* !defined(GPAC_DISABLE_3D) && !defined(GPAC_DISABLE_VRML) */ Bool gf_sc_texture_is_transparent(GF_TextureHandler *txh) { +#ifdef GPAC_DISABLE_VRML + return txh->transparent; +#else M_MatteTexture *matte; if (!txh->matteTexture) return txh->transparent; matte = (M_MatteTexture *)txh->matteTexture; @@ -1111,6 +1146,7 @@ Bool gf_sc_texture_is_transparent(GF_TextureHandler *txh) if (matte->alphaSurface) return 1; if (!strcmp(matte->operation.buffer, "COLOR_MATRIX")) return 1; return txh->transparent; +#endif } #ifndef GPAC_DISABLE_3D @@ -1120,6 +1156,7 @@ u32 gf_sc_texture_enable_ex(GF_TextureHandler *txh, GF_Node *tx_transform, GF_Re GF_Matrix mx; GF_Compositor *compositor = (GF_Compositor *)txh->compositor; +#ifndef GPAC_DISABLE_VRML if (txh->matteTexture) { u32 ret = gf_sc_texture_enable_matte_texture(txh->matteTexture); if (!ret) return 0; @@ -1131,6 +1168,7 @@ u32 gf_sc_texture_enable_ex(GF_TextureHandler *txh, GF_Node *tx_transform, GF_Re visual_3d_set_matrix_mode(compositor->visual, V3D_MATRIX_MODELVIEW); return ret; } +#endif if (!txh || !txh->tx_io) return 0; if (txh->compute_gradient_matrix && gf_sc_texture_needs_reload(txh) ) { diff --git a/src/compositor/visual_manager.c b/src/compositor/visual_manager.c index d2b22d9..56f07fe 100644 --- a/src/compositor/visual_manager.c +++ b/src/compositor/visual_manager.c @@ -23,6 +23,7 @@ */ #include "visual_manager.h" +#include "nodes_stacks.h" #include <gpac/nodes_mpeg4.h> #ifndef GPAC_DISABLE_SVG #include <gpac/nodes_svg.h> @@ -33,6 +34,7 @@ static Bool visual_draw_bitmap_stub(GF_VisualManager *visual, GF_TraverseState * return 0; } + GF_VisualManager *visual_new(GF_Compositor *compositor) { GF_VisualManager *tmp; @@ -41,15 +43,21 @@ GF_VisualManager *visual_new(GF_Compositor *compositor) tmp->center_coords = 1; tmp->compositor = compositor; ra_init(&tmp->to_redraw); +#ifndef GPAC_DISABLE_VRML tmp->back_stack = gf_list_new(); tmp->view_stack = gf_list_new(); +#endif + tmp->raster_brush = compositor->rasterizer->stencil_new(compositor->rasterizer, GF_STENCIL_SOLID); tmp->DrawBitmap = visual_draw_bitmap_stub; + tmp->ClearSurface = visual_2d_clear_surface; #ifndef GPAC_DISABLE_3D +#ifndef GPAC_DISABLE_VRML tmp->navigation_stack = gf_list_new(); tmp->fog_stack = gf_list_new(); +#endif /*GPAC_DISABLE_VRML*/ tmp->alpha_nodes_to_draw = gf_list_new(); #endif @@ -73,18 +81,24 @@ void visual_del(GF_VisualManager *visual) while (visual->prev_nodes) { struct _drawable_store *cur = visual->prev_nodes; visual->prev_nodes = cur->next; - free(cur); + gf_free(cur); } - if (visual->back_stack) gf_list_del(visual->back_stack); - if (visual->view_stack) gf_list_del(visual->view_stack); +#ifndef GPAC_DISABLE_VRML + if (visual->back_stack) BindableStackDelete(visual->back_stack); + if (visual->view_stack) BindableStackDelete(visual->view_stack); +#endif /*GPAC_DISABLE_VRML*/ #ifndef GPAC_DISABLE_3D - if (visual->navigation_stack) gf_list_del(visual->navigation_stack); - if (visual->fog_stack) gf_list_del(visual->fog_stack); + +#ifndef GPAC_DISABLE_VRML + if (visual->navigation_stack) BindableStackDelete(visual->navigation_stack); + if (visual->fog_stack) BindableStackDelete(visual->fog_stack); +#endif /*GPAC_DISABLE_VRML*/ + gf_list_del(visual->alpha_nodes_to_draw); #endif - free(visual); + gf_free(visual); } Bool visual_get_size_info(GF_TraverseState *tr_state, Fixed *surf_width, Fixed *surf_height) @@ -129,6 +143,7 @@ void visual_clean_contexts(GF_VisualManager *visual) ctx->drawable->flags &= ~DRAWABLE_REGISTERED_WITH_VISUAL; if (is_root_visual && (ctx->flags & CTX_HAS_APPEARANCE)) gf_node_dirty_reset(ctx->appear); + ctx = ctx->next; } @@ -145,6 +160,8 @@ void visual_clean_contexts(GF_VisualManager *visual) while (ctx && ctx->drawable) { if (ctx->flags & CTX_HAS_APPEARANCE) gf_node_dirty_reset(ctx->appear); + + ctx->drawable = NULL; ctx = ctx->next; } } @@ -181,11 +198,13 @@ void gf_sc_get_nodes_bounds(GF_Node *self, GF_ChildNodeItem *children, GF_Traver if (!children) return; size.x = size.y = -FIX_ONE; +#ifndef GPAC_DISABLE_VRML switch (gf_node_get_tag(self)) { case TAG_MPEG4_Layer2D: size = ((M_Layer2D *)self)->size; break; case TAG_MPEG4_Layer3D: size = ((M_Layer3D *)self)->size; break; case TAG_MPEG4_Form: size = ((M_Form *)self)->size; break; } +#endif if ((size.x>=0) && (size.y>=0)) { tr_state->bounds = gf_rect_center(size.x, size.y); return; diff --git a/src/compositor/visual_manager.h b/src/compositor/visual_manager.h index 5c90e1e..c441f7c 100644 --- a/src/compositor/visual_manager.h +++ b/src/compositor/visual_manager.h @@ -36,6 +36,7 @@ struct _visual_manager { GF_Compositor *compositor; + Bool direct_flush; #ifndef GPAC_DISABLE_3D /*3D type for the visual: @@ -48,15 +49,17 @@ struct _visual_manager #endif +#ifndef GPAC_DISABLE_VRML /*background stack*/ GF_List *back_stack; /*viewport stack*/ GF_List *view_stack; +#endif + /*size in pixels*/ u32 width, height; - /* * Visual Manager part for 2D drawing and dirty rect */ @@ -92,6 +95,12 @@ struct _visual_manager /*release graphics handle*/ void (*ReleaseSurfaceAccess)(GF_VisualManager *); + /*clear given rect or all visual if no rect specified - clear color depends on visual's type: + BackColor for background nodes + 0x00000000 for composite, + compositor clear color otherwise + */ + void (*ClearSurface)(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor); /*draws specified texture as flat bitmap*/ Bool (*DrawBitmap)(GF_VisualManager *visual, GF_TraverseState *tr_state, DrawableContext *ctx, GF_ColorKey *col_key); @@ -116,10 +125,13 @@ struct _visual_manager * Visual Manager part for 3D drawing */ +#ifndef GPAC_DISABLE_VRML /*navigation stack*/ GF_List *navigation_stack; /*fog stack*/ GF_List *fog_stack; +#endif + /*the one and only camera associated with the visual*/ GF_Camera camera; @@ -135,6 +147,10 @@ struct _visual_manager u32 max_clips; #endif +#ifdef GF_SR_USE_DEPTH + Fixed depth_vp_position, depth_vp_range; +#endif + }; /*constructor/destructor*/ diff --git a/src/compositor/visual_manager_2d.c b/src/compositor/visual_manager_2d.c index daa2876..b661b57 100644 --- a/src/compositor/visual_manager_2d.c +++ b/src/compositor/visual_manager_2d.c @@ -111,7 +111,7 @@ DrawableContext *visual_2d_get_drawable_context(GF_VisualManager *visual) u32 i; DrawableContext *last = visual->cur_context; for (i=0; i<50; i++) { - last->next = malloc(sizeof(DrawableContext)); + last->next = gf_malloc(sizeof(DrawableContext)); last = last->next; last->drawable = NULL; last->col_mat = NULL; @@ -128,13 +128,13 @@ void visual_2d_remove_last_context(GF_VisualManager *visual) } -void visual_2d_drawable_delete(GF_VisualManager *visual, struct _drawable *node) +void visual_2d_drawable_delete(GF_VisualManager *visual, struct _drawable *drawable) { /*remove drawable from visual list*/ struct _drawable_store *it = visual->prev_nodes; struct _drawable_store *prev = NULL; while (it) { - if (it->drawable != node) { + if (it->drawable != drawable) { prev = it; it = prev->next; continue; @@ -142,18 +142,23 @@ void visual_2d_drawable_delete(GF_VisualManager *visual, struct _drawable *node) if (prev) prev->next = it->next; else visual->prev_nodes = it->next; if (!it->next) visual->last_prev_entry = prev; - free(it); + gf_free(it); break; } + if (drawable->flags & DRAWABLE_IS_OVERLAY) { + visual->compositor->video_out->Blit(visual->compositor->video_out, NULL, NULL, NULL, 1); + } /*check node isn't being tracked*/ - if (visual->compositor->grab_node==node->node) + if (visual->compositor->grab_node==drawable->node) visual->compositor->grab_node = NULL; - if (visual->compositor->focus_node==node->node) { + if (visual->compositor->focus_node==drawable->node) { visual->compositor->focus_node = NULL; visual->compositor->focus_text_type = 0; } + if (visual->compositor->hit_node==drawable->node) visual->compositor->hit_node = NULL; + if (visual->compositor->hit_text==drawable->node) visual->compositor->hit_text = NULL; } Bool visual_2d_node_cull(GF_TraverseState *tr_state, GF_Rect *bounds) @@ -172,8 +177,10 @@ void visual_2d_setup_projection(GF_VisualManager *visual, GF_TraverseState *tr_s GF_Rect rc; tr_state->visual = visual; +#ifndef GPAC_DISABLE_VRML tr_state->backgrounds = visual->back_stack; tr_state->viewpoints = visual->view_stack; +#endif /*setup clipper*/ if (visual->center_coords) { @@ -195,7 +202,7 @@ void visual_2d_setup_projection(GF_VisualManager *visual, GF_TraverseState *tr_s visual->surf_rect = gf_rect_pixelize(&rc); - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] output rectangle setup - width %d height %d\n", visual->surf_rect.width, visual->surf_rect.height)); +// GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] output rectangle setup - width %d height %d\n", visual->surf_rect.width, visual->surf_rect.height)); /*setup top clipper*/ if (visual->center_coords) { @@ -212,15 +219,17 @@ void visual_2d_setup_projection(GF_VisualManager *visual, GF_TraverseState *tr_s } /*setup viewport*/ +#ifndef GPAC_DISABLE_VRML if (gf_list_count(visual->view_stack)) { tr_state->traversing_mode = TRAVERSE_BINDABLE; tr_state->bounds = rc; gf_node_traverse((GF_Node *) gf_list_get(visual->view_stack, 0), tr_state); } +#endif visual->top_clipper = gf_rect_pixelize(&rc); tr_state->clipper = rc; - GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Cliper setup - %d:%d@%dx%d\n", visual->top_clipper.x, visual->top_clipper.y, visual->top_clipper.width, visual->top_clipper.height)); +// GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Cliper setup - %d:%d@%dx%d\n", visual->top_clipper.x, visual->top_clipper.y, visual->top_clipper.width, visual->top_clipper.height)); } GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) @@ -228,8 +237,10 @@ GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) GF_Err e; u32 rem, count; struct _drawable_store *it, *prev; +#ifndef GPAC_DISABLE_VRML DrawableContext *ctx; M_Background2D *bck; +#endif u32 draw_mode; u32 time; @@ -240,6 +251,8 @@ GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) visual->has_overlays = 0; visual_2d_setup_projection(visual, tr_state); + if (!visual->top_clipper.width || !visual->top_clipper.height) + return GF_OK; tr_state->traversing_mode = TRAVERSE_SORT; visual->num_nodes_current_frame = 0; @@ -250,10 +263,10 @@ GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) return e; draw_mode = 0; - if (tr_state->direct_draw) draw_mode = 1; + if (tr_state->immediate_draw) draw_mode = 1; /*if we're requested to invalidate everything, switch to direct drawing but don't reset bounds*/ else if (tr_state->invalidate_all) { - tr_state->direct_draw = 1; + tr_state->immediate_draw = 1; draw_mode = 2; } tr_state->invalidate_all = 0; @@ -275,7 +288,7 @@ GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) else visual->prev_nodes = it->next; if (!it->next) visual->last_prev_entry = prev; rem++; - free(it); + gf_free(it); it = prev ? prev->next : visual->prev_nodes; } else { /*mark drawable as already registered with visual*/ @@ -288,6 +301,7 @@ GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Top visual initialized - %d nodes registered and %d removed - using %s rendering\n", count, rem, draw_mode ? "direct" : "dirty-rect")); if (!draw_mode) return GF_OK; +#ifndef GPAC_DISABLE_VRML /*direct mode, draw background*/ bck = (M_Background2D*) gf_list_get(visual->back_stack, 0); if (bck && bck->isBound) { @@ -305,10 +319,12 @@ GF_Err visual_2d_init_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) gf_node_traverse((GF_Node *) bck, tr_state); tr_state->traversing_mode = TRAVERSE_SORT; } else { - visual_2d_clear(visual, NULL, 0); + visual->ClearSurface(visual, NULL, 0); } - } else { - visual_2d_clear(visual, NULL, 0); + } else +#endif + { + visual->ClearSurface(visual, NULL, 0); } return GF_OK; } @@ -324,69 +340,6 @@ Bool gf_irect_inside(GF_IRect *rc1, GF_IRect *rc2) return 0; } -#ifdef TRACK_OPAQUE_REGIONS - -#define CHECK_UNCHANGED 0 - -static void mark_opaque_areas(GF_VisualManager *visual) -{ - u32 i, k; -#if CHECK_UNCHANGED - Bool remove; -#endif - GF_RectArray *ra = &visual->to_redraw; - if (!ra->count) return; - ra->opaque_node_index = (u32*)realloc(ra->opaque_node_index, sizeof(u32) * ra->count); - - for (k=0; k<ra->count; k++) { -#if CHECK_UNCHANGED - remove = 1; -#endif - ra->opaque_node_index[k] = 0; - - for (i=visual->num_contexts; i>0; i--) { - DrawableContext *ctx = visual->contexts[i-1]; - - if (!gf_irect_inside(&ctx->bi->clip, &ra->list[k]) ) { -#if CHECK_UNCHANGED - if (remove && gf_rect_overlaps(&ctx->bi->clip, ra->list[k])) { - if (ctx->need_redraw) remove = 0; - } -#endif - continue; - } - - /*which opaquely covers the given area */ - if (! (ctx->flags & CTX_IS_TRANSPARENT) ) { -#if CHECK_UNCHANGED - /*the opaque area has nothing changed above, remove the dirty rect*/ - if (remove && !ctx->need_redraw) { - u32 j = ra->count - k - 1; - if (j) { - memmove(&ra->list[j], &ra->list[j+1], sizeof(GF_IRect)*j); - memmove(&ra->opaque_node_index[j], &ra->opaque_node_index[j+1], sizeof(u32)*j); - } - ra->count--; - k--; - } - /*opaque area has something changed above, mark index */ - else -#endif - { - ra->opaque_node_index[k] = i; - } - break; -#if CHECK_UNCHANGED - } else { - if (ctx->need_redraw) remove = 0; -#endif - } - } - } -} -#endif - - /*clears list*/ #define ra_clear(ra) { (ra)->count = 0; } @@ -411,11 +364,14 @@ void gf_irect_union(GF_IRect *rc1, GF_IRect *rc2) if (rc2->y - rc2->height < rc1->y - rc1->height) rc1->height = rc1->y - rc2->y + rc2->height; } + /*adds rectangle to the list performing union test*/ void ra_union_rect(GF_RectArray *ra, GF_IRect *rc) { u32 i; + assert(rc->width && rc->height); + for (i=0; i<ra->count; i++) { if (gf_irect_overlaps(&ra->list[i], rc)) { gf_irect_union(&ra->list[i], rc); @@ -425,55 +381,189 @@ void ra_union_rect(GF_RectArray *ra, GF_IRect *rc) ra_add(ra, rc); } +/*returns relation between rc1 and rc2: + 0: rectangles are disjoint + 1: rectangles overlap + 2: rc2 completely covers rc1 + +*/ +static u32 gf_irect_relation(GF_IRect *rc1, GF_IRect *rc2) +{ + if (! rc2->height || !rc2->width || !rc1->height || !rc1->width) return 0; + if (rc2->x+rc2->width<=rc1->x) return 0; + if (rc2->x>=rc1->x+rc1->width) return 0; + if (rc2->y-rc2->height>=rc1->y) return 0; + if (rc2->y<=rc1->y-rc1->height) return 0; + + if ( (rc2->x <= rc1->x) && (rc2->y >= rc1->y) && (rc2->x + rc2->width >= rc1->x + rc1->width) && (rc2->y - rc2->height <= rc1->y - rc1->height) ) + return 2; + + return 1; +} + /*refreshes the content of the array to have only non-overlapping rects*/ void ra_refresh(GF_RectArray *ra) { u32 i, j, k; for (i=0; i<ra->count; i++) { for (j=i+1; j<ra->count; j++) { - if (gf_irect_overlaps(&ra->list[i], &ra->list[j])) { - gf_irect_union(&ra->list[i], &ra->list[j]); + switch (gf_irect_relation(&ra->list[j], &ra->list[i])) { + /*both rectangles overlap, merge them and remove opaque node info*/ + case 1: + gf_irect_union(&ra->list[i], &ra->list[j]); +#ifdef TRACK_OPAQUE_REGIONS + /*current dirty rect is no longer opaque*/ + ra->opaque_node_index[i] = 0; +#endif + /*FALLTHROUGH*/ + /*first rectangle covers second, just remove*/ + case 2: /*remove rect*/ k = ra->count - j - 1; - if (k) memmove(&ra->list[j], & ra->list[j+1], sizeof(GF_IRect)*k); + if (k) { + memmove(&ra->list[j], & ra->list[j+1], sizeof(GF_IRect)*k); +#ifdef TRACK_OPAQUE_REGIONS + memmove(&ra->opaque_node_index[j], & ra->opaque_node_index[j+1], sizeof(u32)*k); +#endif + } ra->count--; - - ra_refresh(ra); + if (ra->count>=2) + ra_refresh(ra); return; + default: + break; + } + } + } +} + +static Bool register_context_rect(GF_RectArray *ra, DrawableContext *ctx, u32 ctx_idx, DrawableContext **first_opaque) +{ + u32 i; + Bool is_transparent, needs_redraw; + GF_IRect *rc = &ctx->bi->clip; + assert(rc->width && rc->height); + + /*node is modified*/ + needs_redraw = (ctx->flags & CTX_REDRAW_MASK) ? 1 : 0; + + /*node is transparent*/ + is_transparent = 1; + if ((ctx->flags & CTX_NO_ANTIALIAS) && !(ctx->flags & CTX_IS_TRANSPARENT) ) { + is_transparent = 0; + + if ((*first_opaque==NULL) && needs_redraw) *first_opaque = ctx; + } + + for (i=0; i<ra->count; i++) { + if (needs_redraw) { + switch (gf_irect_relation(&ra->list[i], rc)) { + /*context intersects an existing rectangle, merge them and remove opaque idx info*/ + case 1: + gf_irect_union(&ra->list[i], rc); +#ifdef TRACK_OPAQUE_REGIONS + ra->opaque_node_index[i]= 0; +#endif + return needs_redraw; + /*context covers an existing rectangle, replace rect and add opaque idx info*/ + case 2: + ra->list[i]= *rc; +#ifdef TRACK_OPAQUE_REGIONS + ra->opaque_node_index[i]= is_transparent ? 0 : ctx_idx; +#endif + return needs_redraw; } } +#ifdef TRACK_OPAQUE_REGIONS + /*context unchanged coverring an entire area*/ + else if (!is_transparent && gf_irect_inside(rc, &ra->list[i])) { + /*remove rect*/ + u32 k = ra->count - i - 1; + if (k) { + memmove(&ra->list[i], & ra->list[i+1], sizeof(GF_IRect)*k); + memmove(&ra->opaque_node_index[i], & ra->opaque_node_index[i+1], sizeof(u32)*k); + } + ra->count--; + i--; + } +#endif } + /*not found, add rect*/ + if (needs_redraw) { + ra_add(ra, rc); +#ifdef TRACK_OPAQUE_REGIONS + if (!ra->opaque_node_index) + ra->opaque_node_index = gf_malloc(sizeof(u32)*ra->alloc); + + ra->opaque_node_index[ra->count-1] = is_transparent ? 0 : ctx_idx; +#endif + } + return needs_redraw; } -/*this defines a partition of the display area in small squares of the given width. If the number of nodes -to redraw exceeds the possible number of squares on the visual, the entire area is redrawn - this avoids computing -dirty rects algo when a lot of small shapes are moving*/ -#define MIN_BBOX_SIZE 16 +static void register_dirty_rect(GF_RectArray *ra, GF_IRect *rc) +{ + /*technically this is correct however the gain is not that big*/ #if 0 -#define CHECK_MAX_NODE if (visual->to_redraw.count > max_nodes_allowed) redraw_all = 1; + +#ifdef TRACK_OPAQUE_REGIONS + u32 i; + for (i=0; i<ra->count; i++) { + switch (gf_irect_relation(rc, &ra->list[i])) { + /*dirty area intersects this dirty rectangle, merge them and remove opaque idx info*/ + case 1: + gf_irect_union(&ra->list[i], rc); + ra->opaque_node_index[i]= 0; + return; + /*dirty area is covered by this dirty rectangle, nothing to do*/ + case 2: + return; + } + } +#endif + /*not found, add rect*/ + ra_add(ra, rc); +#ifdef TRACK_OPAQUE_REGIONS + if (!ra->opaque_node_index) + ra->opaque_node_index = gf_malloc(sizeof(u32)*ra->alloc); + + ra->opaque_node_index[ra->count-1] = 0; +#endif + #else -#define CHECK_MAX_NODE + + ra_add(ra, rc); + +#ifdef TRACK_OPAQUE_REGIONS + if (!ra->opaque_node_index) + ra->opaque_node_index = gf_malloc(sizeof(u32)*ra->alloc); + + ra->opaque_node_index[ra->count-1] = 0; #endif +#endif +} + Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_state) { - u32 k, i, count, max_nodes_allowed, num_nodes, num_changed; - GF_IRect refreshRect, *check_rect; + u32 k, i, count, num_nodes, num_changed; + GF_IRect refreshRect; Bool redraw_all; - M_Background2D *bck; - DrawableContext *bck_ctx, *ctx; +#ifndef GPAC_DISABLE_VRML + M_Background2D *bck = NULL; + DrawableContext *bck_ctx = NULL; +#endif + DrawableContext *ctx; struct _drawable_store *it, *prev; -#ifndef TRACK_OPAQUE_REGIONS DrawableContext *first_opaque = NULL; -#endif Bool has_clear = 0; Bool has_changed = 0; /*in direct mode the visual is always redrawn*/ - if (tr_state->direct_draw) { + if (tr_state->immediate_draw) { /*flush pending contexts due to overlays*/ visual_2d_flush_overlay_areas(visual, tr_state); @@ -489,9 +579,7 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta redraw_all = tr_state->invalidate_all; /*check for background changes for transparent nodes*/ - bck = NULL; - bck_ctx = NULL; - +#ifndef GPAC_DISABLE_VRML bck = (M_Background2D*)gf_list_get(visual->back_stack, 0); if (bck) { if (!bck->isBound) { @@ -499,34 +587,29 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta visual->last_had_back = 0; } else { if (!visual->last_had_back) redraw_all = 1; - visual->last_had_back = 1; bck_ctx = b2d_get_context(bck, visual->back_stack); if (bck_ctx->flags & CTX_REDRAW_MASK) redraw_all = 1; + visual->last_had_back = (bck_ctx->aspect.fill_texture && !bck_ctx->aspect.fill_texture->transparent) ? 2 : 1; } - } else if (visual->last_had_back) { + } else +#endif + if (visual->last_had_back) { visual->last_had_back = 0; redraw_all = 1; } - max_nodes_allowed = (u32) ((visual->top_clipper.width / MIN_BBOX_SIZE) * (visual->top_clipper.height / MIN_BBOX_SIZE)); num_nodes = 0; ctx = visual->context; while (ctx && ctx->drawable) { num_nodes++; drawctx_update_info(ctx, visual); - if (ctx->flags & CTX_REDRAW_MASK) { - num_changed ++; - -#ifndef TRACK_OPAQUE_REGIONS - if (!first_opaque && !(ctx->flags & CTX_IS_TRANSPARENT) && (ctx->flags & CTX_NO_ANTIALIAS)) - first_opaque = ctx; -#endif - /*node has changed, add to redraw area*/ - if (!redraw_all) { - ra_union_rect(&visual->to_redraw, &ctx->bi->clip); -// CHECK_MAX_NODE + if (!redraw_all) { + assert( gf_irect_inside(&visual->top_clipper, &ctx->bi->clip) ); + if (register_context_rect(&visual->to_redraw, ctx, num_nodes, &first_opaque)) { + num_changed ++; } + } ctx = ctx->next; } @@ -539,8 +622,9 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta while (it) { while (drawable_get_previous_bound(it->drawable, &refreshRect, visual)) { if (!redraw_all) { - ra_union_rect(&visual->to_redraw, &refreshRect); -// CHECK_MAX_NODE + //assert( gf_irect_inside(&visual->top_clipper, &refreshRect) ); + gf_irect_intersect(&refreshRect, &visual->top_clipper); + register_dirty_rect(&visual->to_redraw, &refreshRect); has_clear=1; } } @@ -553,11 +637,14 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta it->drawable->flags &= ~DRAWABLE_REGISTERED_WITH_VISUAL; + if (it->drawable->flags & DRAWABLE_IS_OVERLAY) { + visual->compositor->video_out->Blit(visual->compositor->video_out, NULL, NULL, NULL, 1); + } if (prev) prev->next = it->next; else visual->prev_nodes = it->next; if (!it->next) visual->last_prev_entry = prev; - free(it); + gf_free(it); it = prev ? prev->next : visual->prev_nodes; } else { prev = it; @@ -567,19 +654,24 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta /*no visual */ //if (!visual->compositor->output_width && !visual->compositor->output_height) goto exit; -// CHECK_MAX_NODE - if (redraw_all) { ra_clear(&visual->to_redraw); ra_add(&visual->to_redraw, &visual->surf_rect); +#ifdef TRACK_OPAQUE_REGIONS + if (!visual->to_redraw.opaque_node_index) visual->to_redraw.opaque_node_index = gf_malloc(sizeof(u32)*visual->to_redraw.alloc); + visual->to_redraw.opaque_node_index[0]=0; +#endif } else { ra_refresh(&visual->to_redraw); + + if (visual->compositor->debug_defer) { + visual->ClearSurface(visual, &visual->top_clipper, 0); + } } #ifdef TRACK_OPAQUE_REGIONS - /*mark opaque areas to speed up*/ - mark_opaque_areas(visual); + assert(!visual->to_redraw.count || (visual->to_redraw.opaque_node_index != NULL)); #endif - + /*nothing to redraw*/ if (ra_is_empty(&visual->to_redraw) ) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] No changes found since last frame - skipping redraw\n")); @@ -588,14 +680,13 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta has_changed = 1; tr_state->traversing_mode = TRAVERSE_DRAW_2D; -#ifndef TRACK_OPAQUE_REGIONS if (first_opaque && (visual->to_redraw.count==1) && gf_rect_equal(first_opaque->bi->clip, visual->to_redraw.list[0])) { visual->has_modif=0; goto skip_background; } -#endif /*redraw everything*/ +#ifndef GPAC_DISABLE_VRML if (bck_ctx) { drawable_check_bounds(bck_ctx, visual); tr_state->ctx = bck_ctx; @@ -610,8 +701,11 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta bck_ctx->bi->clip = visual->surf_rect; } bck_ctx->bi->unclip = gf_rect_ft(&bck_ctx->bi->clip); + bck_ctx->next = visual->context; gf_node_traverse(bck_ctx->drawable->node, tr_state); - } else { + } else +#endif /*GPAC_DISABLE_VRML*/ + { count = visual->to_redraw.count; for (k=0; k<count; k++) { GF_IRect rc; @@ -620,52 +714,61 @@ Bool visual_2d_terminate_draw(GF_VisualManager *visual, GF_TraverseState *tr_sta if (visual->to_redraw.opaque_node_index[k] > 0) continue; #endif rc = visual->to_redraw.list[k]; - visual_2d_clear(visual, &rc, 0); + visual->ClearSurface(visual, &rc, 0); } } if (!redraw_all && !has_clear) visual->has_modif=0; -#ifndef TRACK_OPAQUE_REGIONS skip_background: -#endif #ifndef GPAC_DISABLE_LOG if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_COMPOSE)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redraw %d / %d nodes (all: %s)", num_changed, num_nodes, redraw_all ? "yes" : "no")); if (visual->to_redraw.count>1) GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("\n")); - for (i=0; i<visual->to_redraw.count; i++) + for (i=0; i<visual->to_redraw.count; i++) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("\tDirtyRect #%d: %d:%d@%dx%d\n", i+1, visual->to_redraw.list[i].x, visual->to_redraw.list[i].y, visual->to_redraw.list[i].width, visual->to_redraw.list[i].height)); + assert(visual->to_redraw.list[i].width); + } } #endif #ifdef TRACK_OPAQUE_REGIONS - i=0; + visual->draw_node_index = 0; #endif - check_rect = (visual->to_redraw.count>1) ? NULL : &visual->to_redraw.list[0]; + ctx = visual->context; while (ctx && ctx->drawable) { - if (!check_rect || gf_irect_overlaps(&ctx->bi->clip, check_rect)) { + #ifdef TRACK_OPAQUE_REGIONS - i++; - visual->draw_node_index = i; + visual->draw_node_index ++; #endif - tr_state->ctx = ctx; + tr_state->ctx = ctx; - /*if overlay we cannot remove the context and cannot draw directly*/ - if (! visual_2d_overlaps_overlay(tr_state->visual, ctx, tr_state)) { + /*if overlay we cannot remove the context and cannot draw directly*/ + if (! visual_2d_overlaps_overlay(tr_state->visual, ctx, tr_state)) { - if (ctx->drawable->flags & DRAWABLE_USE_TRAVERSE_DRAW) { - gf_node_traverse(ctx->drawable->node, tr_state); - } else { - drawable_draw(ctx->drawable, tr_state); - } + if (ctx->drawable->flags & DRAWABLE_USE_TRAVERSE_DRAW) { + gf_node_traverse(ctx->drawable->node, tr_state); + } else { + drawable_draw(ctx->drawable, tr_state); } } ctx = ctx->next; } /*flush pending contexts due to overlays*/ visual_2d_flush_overlay_areas(visual, tr_state); +#ifndef GPAC_DISABLE_VRML + if (bck_ctx) bck_ctx->next = NULL; +#endif + + if (visual->direct_flush) { + GF_DirtyRectangles dr; + dr.count = visual->to_redraw.count; + dr.list = visual->to_redraw.list; + visual->compositor->video_out->FlushRectangles(visual->compositor->video_out, &dr); + visual->compositor->skip_flush=1; + } exit: /*clear dirty rects*/ @@ -725,7 +828,7 @@ Bool visual_2d_draw_frame(GF_VisualManager *visual, GF_Node *root, GF_TraverseSt e = visual_2d_terminate_draw(visual, tr_state); #ifndef GPAC_DISABLE_LOG - if (!tr_state->direct_draw) { + if (!tr_state->immediate_draw) { visual->compositor->indirect_draw_time = gf_sys_clock() - time; } #endif diff --git a/src/compositor/visual_manager_2d.h b/src/compositor/visual_manager_2d.h index 7252d25..62d8580 100644 --- a/src/compositor/visual_manager_2d.h +++ b/src/compositor/visual_manager_2d.h @@ -53,20 +53,34 @@ typedef struct #ifdef TRACK_OPAQUE_REGIONS /*inits structure - called as a constructor*/ -#define ra_init(ra) { (ra)->count = 0; (ra)->alloc = 1; (ra)->list = (GF_IRect*)malloc(sizeof(GF_IRect)); (ra)->opaque_node_index = NULL;} +#define ra_init(ra) { (ra)->count = 0; (ra)->alloc = RA_DEFAULT_STEP; (ra)->list = (GF_IRect*)gf_malloc(sizeof(GF_IRect)*(ra)->alloc); (ra)->opaque_node_index = NULL;} /*deletes structure - called as a destructor*/ -#define ra_del(ra) { free((ra)->list); if ((ra)->opaque_node_index) free((ra)->opaque_node_index); } +#define ra_del(ra) { gf_free((ra)->list); if ((ra)->opaque_node_index) { gf_free((ra)->opaque_node_index); (ra)->opaque_node_index = NULL; } } + + +/*adds rect to list - expand if needed*/ +#define ra_add(ra, rc) { \ + if ((ra)->count==(ra)->alloc) { \ + (ra)->alloc += RA_DEFAULT_STEP; \ + (ra)->list = (GF_IRect*)gf_realloc((ra)->list, sizeof(GF_IRect) * (ra)->alloc); \ + if ( (ra)->opaque_node_index) (ra)->opaque_node_index = (u32*)gf_realloc((ra)->opaque_node_index, sizeof(u32) * (ra)->alloc); \ + } \ + (ra)->list[(ra)->count] = *rc; (ra)->count++; } + #else -#define ra_init(ra) { (ra)->count = 0; (ra)->alloc = 1; (ra)->list = (GF_IRect*)malloc(sizeof(GF_IRect));} +#define ra_init(ra) { (ra)->count = 0; (ra)->alloc = RA_DEFAULT_STEP; (ra)->list = (GF_IRect*)gf_malloc(sizeof(GF_IRect)*(ra)->alloc);} /*deletes structure - called as a destructor*/ -#define ra_del(ra) { free((ra)->list); } -#endif +#define ra_del(ra) { gf_free((ra)->list); } + /*adds rect to list - expand if needed*/ #define ra_add(ra, rc) { \ - if ((ra)->count==(ra)->alloc) { (ra)->alloc += RA_DEFAULT_STEP; (ra)->list = (GF_IRect*)realloc((ra)->list, sizeof(GF_IRect) * (ra)->alloc); } \ + if ((ra)->count==(ra)->alloc) { \ + (ra)->alloc += RA_DEFAULT_STEP; \ + (ra)->list = (GF_IRect*)gf_realloc((ra)->list, sizeof(GF_IRect) * (ra)->alloc); \ + } \ (ra)->list[(ra)->count] = *rc; (ra)->count++; } - +#endif /*adds rectangle to the list performing union test*/ @@ -93,6 +107,8 @@ Bool visual_2d_node_cull(GF_TraverseState *tr_state, GF_Rect *bounds); void visual_2d_pick_node(GF_VisualManager *visual, GF_TraverseState *tr_state, GF_Event *ev, GF_ChildNodeItem *children); +void visual_2d_clear_surface(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor); + /*gets a drawable context on this visual*/ DrawableContext *visual_2d_get_drawable_context(GF_VisualManager *visual); /*remove last drawable context*/ @@ -105,12 +121,6 @@ GF_Err visual_2d_init_raster(GF_VisualManager *visual); /*releases raster surface handler */ void visual_2d_release_raster(GF_VisualManager *visual); -/*clear given rect or all visual if no rect specified - clear color depends on visual's type: - BackColor for background nodes - 0x00000000 for composite, - compositor clear color otherwise -*/ -void visual_2d_clear(GF_VisualManager *visual, GF_IRect *clear, u32 BackColor); /*texture the path with the given context info*/ void visual_2d_texture_path(GF_VisualManager *visual, GF_Path *path, DrawableContext *ctx, GF_TraverseState *tr_state); /*draw the path (fill and strike) - if brushes are NULL they are created if needed based on the context aspect diff --git a/src/compositor/visual_manager_2d_draw.c b/src/compositor/visual_manager_2d_draw.c index 57fd801..05013b3 100644 --- a/src/compositor/visual_manager_2d_draw.c +++ b/src/compositor/visual_manager_2d_draw.c @@ -51,12 +51,12 @@ void visual_2d_release_raster(GF_VisualManager *visual) } -void visual_2d_clear(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor) +void visual_2d_clear_surface(GF_VisualManager *visual, GF_IRect *rc, u32 BackColor) { #ifdef SKIP_DRAW return; #endif - if (!visual->raster_surface) return; + if (!visual->is_attached) return; if (!BackColor && !visual->offscreen) BackColor = visual->compositor->back_color; @@ -92,9 +92,9 @@ static void visual_2d_fill_path(GF_VisualManager *visual, DrawableContext *ctx, GF_Raster2D *raster = visual->compositor->rasterizer; /*background & direct drawing : use ctx clip*/ - if ((ctx->flags & CTX_IS_BACKGROUND) || tr_state->direct_draw) { + if ((ctx->flags & CTX_IS_BACKGROUND) || tr_state->immediate_draw) { if (ctx->bi->clip.width && ctx->bi->clip.height) { - //GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s (direct draw)\n", gf_node_get_log_name(ctx->drawable->node) )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s (direct draw)\n", gf_node_get_log_name(ctx->drawable->node) )); raster->surface_set_clipper(visual->raster_surface, &ctx->bi->clip); raster->surface_fill(visual->raster_surface, stencil); @@ -112,7 +112,7 @@ static void visual_2d_fill_path(GF_VisualManager *visual, DrawableContext *ctx, clip = ctx->bi->clip; gf_irect_intersect(&clip, &visual->to_redraw.list[i]); if (clip.width && clip.height) { - //GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s (indirect draw)\n", gf_node_get_log_name(ctx->drawable->node) )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Visual2D] Redrawing node %s (indirect draw @ dirty rect idx %d)\n", gf_node_get_log_name(ctx->drawable->node), i)); raster->surface_set_clipper(visual->raster_surface, &clip); raster->surface_fill(visual->raster_surface, stencil); @@ -126,7 +126,7 @@ static void visual_2d_set_options(GF_Compositor *compositor, GF_SURFACE rend, Bo { GF_Raster2D *raster = compositor->rasterizer; if (no_antialias) { - raster->surface_set_raster_level(rend, compositor->high_speed ? GF_RASTER_HIGH_SPEED : GF_RASTER_MID); + raster->surface_set_raster_level(rend, GF_RASTER_HIGH_SPEED); } else { switch (compositor->antiAlias) { case GF_ANTIALIAS_NONE: @@ -148,6 +148,7 @@ static void visual_2d_set_options(GF_Compositor *compositor, GF_SURFACE rend, Bo } +#ifndef GPAC_DISABLE_VRML static void visual_2d_get_texture_transform(GF_Node *__appear, GF_TextureHandler *txh, GF_Matrix2D *mat, Bool line_texture, Fixed final_width, Fixed final_height) { u32 node_tag; @@ -197,13 +198,13 @@ static void visual_2d_get_texture_transform(GF_Node *__appear, GF_TextureHandler return; } } - +#endif /*GPAC_DISABLE_VRML*/ static void visual_2d_draw_gradient(GF_VisualManager *visual, GF_Path *path, GF_TextureHandler *txh, struct _drawable_context *ctx, GF_TraverseState *tr_state, GF_Matrix2D *ext_mx, GF_Rect *orig_bounds) { GF_Rect rc; GF_STENCIL stencil; - GF_Matrix2D g_mat, txt_mat; + GF_Matrix2D g_mat; GF_Raster2D *raster = visual->compositor->rasterizer; if (!txh) txh = ctx->aspect.fill_texture; @@ -219,10 +220,14 @@ static void visual_2d_draw_gradient(GF_VisualManager *visual, GF_Path *path, GF_ stencil = gf_sc_texture_get_stencil(txh); if (!stencil) return; +#ifndef GPAC_DISABLE_VRML if (ctx->flags & CTX_HAS_APPEARANCE) { + GF_Matrix2D txt_mat; visual_2d_get_texture_transform(ctx->appear, txh, &txt_mat, (txh == ctx->aspect.fill_texture) ? 0 : 1, INT2FIX(txh->width), INT2FIX(txh->height)); gf_mx2d_add_matrix(&g_mat, &txt_mat); } +#endif + /*move to bottom-left corner of bounds */ if (ext_mx) gf_mx2d_add_matrix(&g_mat, ext_mx); if (orig_bounds) gf_mx2d_add_translation(&g_mat, (orig_bounds->x), (orig_bounds->y - orig_bounds->height)); @@ -319,12 +324,18 @@ void visual_2d_texture_path_extended(GF_VisualManager *visual, GF_Path *path, GF Fixed sS, sT; u32 tx_tile; GF_STENCIL tx_raster; - GF_Matrix2D mx_texture, tex_trans; + GF_Matrix2D mx_texture; GF_Rect rc, orig_rc; GF_Raster2D *raster = visual->compositor->rasterizer; if (!txh) txh = ctx->aspect.fill_texture; - if (!txh || !txh->tx_io) return; + if (!txh) return; + if (!txh->tx_io) { + gf_node_dirty_set(txh->owner, 0, 1); + + txh->needs_refresh=1; + return; + } /*this is gradient draw*/ @@ -357,11 +368,14 @@ void visual_2d_texture_path_extended(GF_VisualManager *visual, GF_Path *path, GF gf_mx2d_init(mx_texture); gf_mx2d_add_scale(&mx_texture, sS, sT); +#ifndef GPAC_DISABLE_VRML /*apply texture transform*/ if (ctx->flags & CTX_HAS_APPEARANCE) { + GF_Matrix2D tex_trans; visual_2d_get_texture_transform(ctx->appear, txh, &tex_trans, (txh == ctx->aspect.fill_texture) ? 0 : 1, txh->width * sS, txh->height * sT); gf_mx2d_add_matrix(&mx_texture, &tex_trans); } +#endif /*move to bottom-left corner of bounds */ gf_mx2d_add_translation(&mx_texture, (orig_rc.x), (orig_rc.y - orig_rc.height)); @@ -371,7 +385,7 @@ void visual_2d_texture_path_extended(GF_VisualManager *visual, GF_Path *path, GF /*move to final coordinate system (except background which is built directly in final coord system)*/ if (!(ctx->flags & CTX_IS_BACKGROUND) ) gf_mx2d_add_matrix(&mx_texture, &ctx->transform); - /*set path transform, except for background2D node which is directly build in the final coord system*/ + /*set path transform*/ raster->stencil_set_matrix(tx_raster, &mx_texture); @@ -442,7 +456,8 @@ void visual_2d_draw_path_extended(GF_VisualManager *visual, GF_Path *path, Drawa return; } - if (! (ctx->flags & CTX_IS_BACKGROUND) ) visual_2d_set_options(visual->compositor, visual->raster_surface, ctx->flags & CTX_IS_TEXT, 0); + if (! (ctx->flags & CTX_IS_BACKGROUND) ) + visual_2d_set_options(visual->compositor, visual->raster_surface, ctx->flags & CTX_IS_TEXT, ctx->flags & CTX_NO_ANTIALIAS); dofill = dostrike = 0; if (!(ctx->flags & CTX_PATH_FILLED) && GF_COL_A(ctx->aspect.fill_color) ) { @@ -579,3 +594,62 @@ void visual_2d_fill_rect(GF_VisualManager *visual, DrawableContext *ctx, GF_Rect gf_path_del(path); } + +void visual_2d_fill_irect(GF_VisualManager *visual, GF_IRect *rc, u32 fill, u32 strike) +{ + GF_Path *path; + GF_Path *outline; + GF_PenSettings pen; + GF_Raster2D *raster = visual->compositor->rasterizer; +#ifdef SKIP_DRAW + return; +#endif + + if (!rc) return; + if (!visual->raster_surface) return; + if (!fill && !strike ) return; + + /*no aa*/ + visual_2d_set_options(visual->compositor, visual->raster_surface, 0, 1); + raster->surface_set_matrix(visual->raster_surface, NULL); + + raster->surface_set_raster_level(visual->raster_surface, GF_RASTER_HIGH_SPEED); + raster->surface_set_matrix(visual->raster_surface, NULL); + + path = gf_path_new(); + gf_path_add_move_to(path, INT2FIX(rc->x-1), INT2FIX(rc->y+2-rc->height)); + gf_path_add_line_to(path, INT2FIX(rc->x+rc->width-2), INT2FIX(rc->y+2-rc->height)); + gf_path_add_line_to(path, INT2FIX(rc->x+rc->width), INT2FIX(rc->y)); + gf_path_add_line_to(path, INT2FIX(rc->x), INT2FIX(rc->y)); + gf_path_close(path); + + if (fill) { + raster->surface_set_path(visual->raster_surface, path); + raster->stencil_set_brush_color(visual->raster_brush, fill); + + raster->surface_set_clipper(visual->raster_surface, rc); + raster->surface_fill(visual->raster_surface, visual->raster_brush); + + raster->surface_set_path(visual->raster_surface, NULL); + } + + if (strike) { + memset(&pen, 0, sizeof(GF_PenSettings)); + pen.width = 2; + pen.align = GF_PATH_LINE_INSIDE; + pen.join = GF_LINE_JOIN_BEVEL; + outline = gf_path_get_outline(path, pen); + outline->flags &= ~GF_PATH_FILL_ZERO_NONZERO; + + raster->surface_set_path(visual->raster_surface, outline); + raster->stencil_set_brush_color(visual->raster_brush, strike); + + raster->surface_set_clipper(visual->raster_surface, rc); + raster->surface_fill(visual->raster_surface, visual->raster_brush); + + raster->surface_set_path(visual->raster_surface, NULL); + gf_path_del(outline); + } + + gf_path_del(path); +} diff --git a/src/compositor/visual_manager_3d.c b/src/compositor/visual_manager_3d.c index c374c65..3bd2934 100644 --- a/src/compositor/visual_manager_3d.c +++ b/src/compositor/visual_manager_3d.c @@ -47,7 +47,7 @@ void drawable_3d_del(GF_Node *n) Drawable3D *d = (Drawable3D *)gf_node_get_private(n); if (d) { if (d->mesh) mesh_free(d->mesh); - free(d); + gf_free(d); } gf_sc_check_focus_upon_destroy(n); } @@ -100,10 +100,12 @@ static void visual_3d_setup_traversing_state(GF_VisualManager *visual, GF_Traver { tr_state->visual = visual; tr_state->camera = &visual->camera; +#ifndef GPAC_DISABLE_VRML tr_state->backgrounds = visual->back_stack; tr_state->viewpoints = visual->view_stack; tr_state->fogs = visual->fog_stack; tr_state->navigations = visual->navigation_stack; +#endif tr_state->color_mat.identity = 1; tr_state->camera->vp.x = tr_state->camera->vp.y = 0; tr_state->min_hsize = INT2FIX(MIN(visual->width, visual->height) / 2); @@ -119,12 +121,12 @@ static void visual_3d_setup_traversing_state(GF_VisualManager *visual, GF_Traver tr_state->camera->vp.height = INT2FIX(tr_state->visual->compositor->vp_height); /*2D ortho, scale is already present in the root user transform*/ - if (visual->type_3d==1) { - tr_state->camera->width = INT2FIX(tr_state->visual->compositor->vp_width); - tr_state->camera->height = INT2FIX(tr_state->visual->compositor->vp_height); - } else { + if (visual->type_3d==0) { tr_state->camera->width = INT2FIX(tr_state->visual->width); tr_state->camera->height = INT2FIX(tr_state->visual->height); + } else { + tr_state->camera->width = INT2FIX(tr_state->visual->compositor->vp_width); + tr_state->camera->height = INT2FIX(tr_state->visual->compositor->vp_height); } } else { Fixed sw, sh; @@ -224,10 +226,50 @@ void visual_3d_viewpoint_change(GF_TraverseState *tr_state, GF_Node *vp, Bool an else if (tr_state->pixel_metrics) { position.z = gf_divfix(tr_state->camera->width, 2*gf_tan(fieldOfView/2) ); + } +#ifdef GF_SR_USE_DEPTH + /* 3D world calibration for stereoscopic screen */ + if (tr_state->visual->compositor->auto_calibration && tr_state->visual->compositor->video_out->view_distance) { + Fixed view_distance, disparity; + + view_distance = INT2FIX(tr_state->visual->compositor->video_out->view_distance); + disparity = INT2FIX(tr_state->visual->compositor->video_out->disparity); + + if (tr_state->visual->depth_vp_range) { + position.z = view_distance; + tr_state->camera->z_near = view_distance - tr_state->visual->depth_vp_position + tr_state->visual->depth_vp_range/2; + tr_state->camera->z_far = view_distance - tr_state->visual->depth_vp_position - tr_state->visual->depth_vp_range/2; + } + else if (disparity) { + /*3,4 cm = 1,3386 inch -> pixels*/ + Fixed half_interocular_dist_pixel = FLT2FIX(1.3386) * tr_state->visual->compositor->video_out->dpi_x; + //frustum placed to match user's real viewpoint + position.z = view_distance; + + //near plane will match front side of the display's stereoscopic box + //-> n=D- (dD)/(e+d) + tr_state->camera->z_near = view_distance - + gf_divfix( gf_mulfix(disparity,view_distance), (half_interocular_dist_pixel + disparity)); + } + else if (tr_state->visual->compositor->display_depth) { + Fixed dist = INT2FIX(tr_state->visual->compositor->display_depth); + if (dist<0) dist = INT2FIX(tr_state->visual->height); + +#if 1 + view_distance = gf_divfix(tr_state->visual->height, 2*gf_tan(fieldOfView/2) ); +#else + view_distance = gf_muldiv(view_distance, tr_state->visual->height, tr_state->visual->compositor->video_out->max_screen_height); + fieldOfView = 2*gf_atan2(tr_state->visual->height/2, view_distance); +#endif + + //frustum placed to match user's real viewpoint + position.z = view_distance; + tr_state->camera->z_near = view_distance - 2*dist/3; + tr_state->camera->z_far = view_distance + dist/2; + } } - /*HACK, LET'S PUSH NEAR PLANE TO CENTER OF COORDINATES*/ -// tr_state->camera->z_near = position.z ; +#endif gf_vec_diff(d, position, local_center); dist = gf_vec_len(d); @@ -253,20 +295,33 @@ void visual_3d_viewpoint_change(GF_TraverseState *tr_state, GF_Node *vp, Bool an void visual_3d_setup_projection(GF_TraverseState *tr_state) { +#ifndef GPAC_DISABLE_VRML GF_Node *bindable; +#endif u32 mode = tr_state->traversing_mode; tr_state->traversing_mode = TRAVERSE_BINDABLE; /*setup viewpoint (this directly modifies the frustum)*/ +#ifndef GPAC_DISABLE_VRML bindable = (GF_Node*)gf_list_get(tr_state->viewpoints, 0); if (Bindable_GetIsBound(bindable)) { gf_node_traverse(bindable, tr_state); tr_state->camera->had_viewpoint = 1; - } else if (tr_state->camera->had_viewpoint) { + } else +#endif + if (tr_state->camera->had_viewpoint) { if (tr_state->camera->is_3D) { SFVec3f pos, center; SFRotation r; Fixed fov = GF_PI/4; +#ifdef GF_SR_USE_DEPTH + /* 3D world calibration for stereoscopic screen */ + if (tr_state->visual->compositor->auto_calibration && tr_state->visual->compositor->video_out->view_distance) { + fov = 2*gf_atan2( INT2FIX(tr_state->visual->compositor->video_out->max_screen_width)/2, + INT2FIX(tr_state->visual->compositor->video_out->view_distance)); + } +#endif + /*default viewpoint*/ pos.x = pos.y = 0; pos.z = 10 * FIX_ONE; center.x = center.y = center.z = 0; @@ -295,21 +350,30 @@ void visual_3d_setup_projection(GF_TraverseState *tr_state) gf_mx_init(tr_state->model_matrix); tr_state->traversing_mode = mode; +#ifdef GF_SR_USE_DEPTH + tr_state->depth_offset = 0; + tr_state->depth_gain = FIX_ONE; +#endif } void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) { u32 mode; +#ifndef GPAC_DISABLE_VRML GF_Node *bindable; +#endif /*if not in layer, traverse navigation node FIXME: we should update the nav info according to the world transform at the current viewpoint (vrml)*/ tr_state->traversing_mode = TRAVERSE_BINDABLE; +#ifndef GPAC_DISABLE_VRML bindable = tr_state->navigations ? (GF_Node*) gf_list_get(tr_state->navigations, 0) : NULL; if (Bindable_GetIsBound(bindable)) { gf_node_traverse(bindable, tr_state); tr_state->camera->had_nav_info = 1; - } else if (tr_state->camera->had_nav_info) { + } else +#endif + if (tr_state->camera->had_nav_info) { /*if no navigation specified, use default VRML one*/ tr_state->camera->avatar_size.x = FLT2FIX(0.25f); tr_state->camera->avatar_size.y = FLT2FIX(1.6f); tr_state->camera->avatar_size.z = FLT2FIX(0.75f); tr_state->camera->visibility = 0; @@ -323,6 +387,11 @@ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) if (tr_state->camera->is_3D) { /*X3D is by default examine, VRML/MPEG4 is WALK*/ tr_state->camera->navigate_mode = (tr_state->visual->type_3d==3) ? GF_NAVIGATE_EXAMINE : GF_NAVIGATE_WALK; + +#ifdef GF_SR_USE_DEPTH + if (tr_state->visual->compositor->display_depth) + tr_state->camera->navigate_mode = GF_NAVIGATE_NONE; +#endif } else { tr_state->camera->navigate_mode = GF_NAVIGATE_NONE; } @@ -338,8 +407,10 @@ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) } /*animate current camera - if returns TRUE draw next frame*/ - if (camera_animate(tr_state->camera)) + if (camera_animate(tr_state->camera)) { + if (tr_state->visual->compositor->active_layer) gf_node_dirty_set(tr_state->visual->compositor->active_layer, 0, 1); gf_sc_invalidate(tr_state->visual->compositor, NULL); + } visual_3d_set_viewport(tr_state->visual, tr_state->camera->vp); @@ -355,7 +426,6 @@ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) /*setup background*/ mode = tr_state->traversing_mode; tr_state->traversing_mode = TRAVERSE_BINDABLE; - bindable = (GF_Node*) gf_list_get(tr_state->backgrounds, 0); /*if in layer clear z buffer (even if background)*/ if (layer_type) visual_3d_clear_depth(tr_state->visual); @@ -369,11 +439,15 @@ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) visual_3d_clear(tr_state->visual, col, 0); } +#ifndef GPAC_DISABLE_VRML + bindable = (GF_Node*) gf_list_get(tr_state->backgrounds, 0); if (Bindable_GetIsBound(bindable)) { gf_node_traverse(bindable, tr_state); } /*clear if not in layer*/ - else if (!layer_type) { + else +#endif + if (!layer_type) { SFColor col; col.red = INT2FIX((tr_state->visual->compositor->back_color>>16)&0xFF) / 255; col.green = INT2FIX((tr_state->visual->compositor->back_color>>8)&0xFF) / 255; @@ -387,31 +461,36 @@ void visual_3d_init_draw(GF_TraverseState *tr_state, u32 layer_type) static GFINLINE Bool visual_3d_has_alpha(GF_TraverseState *tr_state, GF_Node *geom) { - u32 tag; Bool is_mat3D; Drawable3D *stack; - GF_Node *mat = tr_state->appear ? ((M_Appearance *)tr_state->appear)->material : NULL; + is_mat3D = 0; - if (mat) { - tag = gf_node_get_tag(mat); - switch (tag) { - /*for M2D: if filled & transparent we're transparent - otherwise we must check texture*/ - case TAG_MPEG4_Material2D: - if (((M_Material2D *)mat)->filled && ((M_Material2D *)mat)->transparency) return 1; - break; - case TAG_MPEG4_Material: - case TAG_X3D_Material: - is_mat3D = 1; - if ( ((M_Material *)mat)->transparency) return 1; - break; - case TAG_MPEG4_MaterialKey: - return 1; - break; +#ifndef GPAC_DISABLE_VRML + if (tr_state->appear) { + GF_Node *mat = ((M_Appearance *)tr_state->appear)->material; + if (mat) { + u32 tag = gf_node_get_tag(mat); + switch (tag) { + /*for M2D: if filled & transparent we're transparent - otherwise we must check texture*/ + case TAG_MPEG4_Material2D: + if (((M_Material2D *)mat)->filled && ((M_Material2D *)mat)->transparency) return 1; + break; + case TAG_MPEG4_Material: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Material: +#endif + is_mat3D = 1; + if ( ((M_Material *)mat)->transparency) return 1; + break; + case TAG_MPEG4_MaterialKey: + return 1; + break; + } + } else if (tr_state->camera->is_3D) { + GF_TextureHandler *txh = gf_sc_texture_get_handler(((M_Appearance *)tr_state->appear)->texture); + if (txh && txh->transparent) return 1; } - } else if (tr_state->camera->is_3D && tr_state->appear) { - GF_TextureHandler *txh = gf_sc_texture_get_handler(((M_Appearance *)tr_state->appear)->texture); - if (txh && txh->transparent) return 1; } /*check alpha texture in3D or with bitmap*/ @@ -419,6 +498,9 @@ static GFINLINE Bool visual_3d_has_alpha(GF_TraverseState *tr_state, GF_Node *ge GF_TextureHandler *txh = gf_sc_texture_get_handler(((M_Appearance *)tr_state->appear)->texture); if (txh && txh->transparent) return 1; } + +#endif /*GPAC_DISABLE_VRML*/ + /*TODO - FIXME check alpha only...*/ if (!tr_state->color_mat.identity) return 1; @@ -474,7 +556,7 @@ void visual_3d_register_context(GF_TraverseState *tr_state, GF_Node *geometry) i=0; while ((ol = (DirectionalLightContext*)gf_list_enum(tr_state->local_lights, &i))) { - nl = (DirectionalLightContext*)malloc(sizeof(DirectionalLightContext)); + nl = (DirectionalLightContext*)gf_malloc(sizeof(DirectionalLightContext)); memcpy(nl, ol, sizeof(DirectionalLightContext)); gf_list_add(ctx->directional_lights, nl); } @@ -491,6 +573,9 @@ void visual_3d_register_context(GF_TraverseState *tr_state, GF_Node *geometry) gf_mx_apply_bbox(&ctx->model_matrix, &tr_state->bbox); gf_mx_apply_bbox(&tr_state->camera->modelview, &tr_state->bbox); ctx->zmax = tr_state->bbox.max_edge.z; +#ifdef GF_SR_USE_DEPTH + ctx->depth_offset=tr_state->depth_offset; +#endif /*we don't need an exact sorting, as long as we keep transparent nodes above -note that for speed purposes we store in reverse-z transparent nodes*/ @@ -552,6 +637,9 @@ void visual_3d_flush_contexts(GF_VisualManager *visual, GF_TraverseState *tr_sta tr_state->cull_flag = ctx->cull_flag; tr_state->appear = ctx->appearance; +#ifdef GF_SR_USE_DEPTH + tr_state->depth_offset = ctx->depth_offset; +#endif gf_node_traverse(ctx->geometry, tr_state); tr_state->appear = NULL; @@ -560,7 +648,7 @@ void visual_3d_flush_contexts(GF_VisualManager *visual, GF_TraverseState *tr_sta for (i=gf_list_count(ctx->directional_lights); i>0; i--) { DirectionalLightContext *dl = (DirectionalLightContext*)gf_list_get(ctx->directional_lights, i-1); gf_node_traverse(dl->dlight, tr_state); - free(dl); + gf_free(dl); } if (ctx->has_clipper) visual_3d_reset_clipper_2d(visual); @@ -570,14 +658,16 @@ void visual_3d_flush_contexts(GF_VisualManager *visual, GF_TraverseState *tr_sta /*and destroy*/ gf_list_del(ctx->directional_lights); - free(ctx); + gf_free(ctx); } tr_state->pixel_metrics = pixel_metrics; gf_list_reset(tr_state->visual->alpha_nodes_to_draw); } static void visual_3d_draw_node(GF_TraverseState *tr_state, GF_Node *root_node) { +#ifndef GPAC_DISABLE_VRML GF_Node *fog; +#endif if (!tr_state->camera || !tr_state->visual) return; visual_3d_init_draw(tr_state, 0); @@ -586,10 +676,12 @@ static void visual_3d_draw_node(GF_TraverseState *tr_state, GF_Node *root_node) if ((tr_state->visual==tr_state->visual->compositor->visual) && tr_state->camera->is_3D) visual_3d_check_collisions(tr_state, NULL); +#ifndef GPAC_DISABLE_VRML /*setup fog*/ fog = (GF_Node*) gf_list_get(tr_state->visual->fog_stack, 0); tr_state->traversing_mode = TRAVERSE_BINDABLE; if (Bindable_GetIsBound(fog)) gf_node_traverse(fog, tr_state); +#endif /*turn global lights on*/ if (tr_state->visual->type_3d>1) { @@ -965,7 +1057,8 @@ void visual_3d_pick_node(GF_VisualManager *visual, GF_TraverseState *tr_state, G } -void visual_3d_drawable_pick(GF_Node *n, GF_TraverseState *tr_state, GF_Mesh *mesh, GF_Path *path) +#ifndef GPAC_DISABLE_VRML +void visual_3d_vrml_drawable_pick(GF_Node *n, GF_TraverseState *tr_state, GF_Mesh *mesh, Drawable *drawable) { SFVec3f local_pt, world_pt, vdiff; SFVec3f hit_normal; @@ -978,7 +1071,7 @@ void visual_3d_drawable_pick(GF_Node *n, GF_TraverseState *tr_state, GF_Mesh *me GF_Ray r; u32 cull_bckup = tr_state->cull_flag; - if (!mesh && !path) return; + if (!mesh && !drawable) return; count = gf_list_count(tr_state->vrml_sensors); compositor = tr_state->visual->compositor; @@ -1009,22 +1102,34 @@ void visual_3d_drawable_pick(GF_Node *n, GF_TraverseState *tr_state, GF_Mesh *me if (mesh) box = mesh->bounds; else - gf_bbox_from_rect(&box, &path->bbox); + gf_bbox_from_rect(&box, &drawable->path->bbox); if (gf_bbox_plane_relation(&box, &p) == GF_BBOX_FRONT) { GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Picking] bounding box of node %s (DEF %s) below current hit point - skipping\n", gf_node_get_class_name(n), gf_node_get_name(n))); return; } } - if (path) { + if (drawable) { + DrawAspect2D asp; node_is_over = 0; if (compositor_get_2d_plane_intersection(&r, &local_pt)) { - if (gf_path_point_over(path, local_pt.x, local_pt.y)) { + if (gf_path_point_over(drawable->path, local_pt.x, local_pt.y)) { hit_normal.x = hit_normal.y = 0; hit_normal.z = FIX_ONE; - text_coords.x = gf_divfix(local_pt.x, path->bbox.width) + FIX_ONE/2; - text_coords.y = gf_divfix(local_pt.y, path->bbox.height) + FIX_ONE/2; + text_coords.x = gf_divfix(local_pt.x, drawable->path->bbox.width) + FIX_ONE/2; + text_coords.y = gf_divfix(local_pt.y, drawable->path->bbox.height) + FIX_ONE/2; node_is_over = 1; } + memset(&asp, 0, sizeof(DrawAspect2D)); + drawable_get_aspect_2d_mpeg4(drawable->node, &asp, tr_state); + if (asp.pen_props.width || asp.line_texture ) { + StrikeInfo2D *si = drawable_get_strikeinfo(tr_state->visual->compositor, drawable, &asp, tr_state->appear, NULL, 0, NULL); + if (si && si->outline && gf_path_point_over(si->outline, local_pt.x, local_pt.y)) { + hit_normal.x = hit_normal.y = 0; hit_normal.z = FIX_ONE; + text_coords.x = gf_divfix(local_pt.x, si->outline->bbox.width) + FIX_ONE/2; + text_coords.y = gf_divfix(local_pt.y, si->outline->bbox.height) + FIX_ONE/2; + node_is_over = 1; + } + } } } else { node_is_over = gf_mesh_intersect_ray(mesh, &r, &local_pt, &hit_normal, &text_coords); @@ -1066,30 +1171,39 @@ void visual_3d_drawable_pick(GF_Node *n, GF_TraverseState *tr_state, GF_Mesh *me if (compositor_is_composite_texture(tr_state->appear)) { compositor->hit_appear = tr_state->appear; - } else { + } else + { compositor->hit_appear = NULL; } compositor->hit_node = n; + compositor->hit_use_dom_events = 0; GF_LOG(GF_LOG_DEBUG, GF_LOG_COMPOSE, ("[Picking] node %s (def %s) is under mouse - hit %g %g %g\n", gf_node_get_class_name(n), gf_node_get_name(n), FIX2FLT(world_pt.x), FIX2FLT(world_pt.y), FIX2FLT(world_pt.z))); } -void visual_3d_drawable_collide(GF_Node *node, GF_TraverseState *tr_state) +void visual_3d_vrml_drawable_collide(GF_Node *node, GF_TraverseState *tr_state) { SFVec3f pos, v1, v2, collide_pt, last_pos; Fixed dist, m_dist; GF_Matrix mx; - u32 ntag, cull_backup; + u32 cull_backup; Drawable3D *st = (Drawable3D *)gf_node_get_private(node); if (!st || !st->mesh) return; /*no collision with lines & points*/ if (st->mesh->mesh_type != MESH_TRIANGLES) return; - /*no collision with text (vrml)*/ - ntag = gf_node_get_tag(node); - if ((ntag==TAG_MPEG4_Text) || (ntag==TAG_X3D_Text)) return; +#ifndef GPAC_DISABLE_VRML + /*no collision with text (vrml)*/ + switch (gf_node_get_tag(node)) { + case TAG_MPEG4_Text: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Text: +#endif + return; + } +#endif /*cull but don't use near plane to detect objects behind us*/ cull_backup = tr_state->cull_flag; @@ -1179,7 +1293,10 @@ void visual_3d_drawable_collide(GF_Node *node, GF_TraverseState *tr_state) } } -static GF_TextureHandler *visual_3d_setup_texture_2d(GF_TraverseState *tr_state, DrawAspect2D *asp, Bool is_svg, GF_Mesh *mesh) +#endif /*GPAC_DISABLE_VRML*/ + + +static GF_TextureHandler *visual_3d_setup_texture_2d(GF_TraverseState *tr_state, DrawAspect2D *asp, GF_Mesh *mesh) { if (!asp->fill_texture) return NULL; @@ -1191,12 +1308,14 @@ static GF_TextureHandler *visual_3d_setup_texture_2d(GF_TraverseState *tr_state, gf_sc_texture_set_blend_mode(asp->fill_texture, TX_REPLACE); } - if (is_svg) { + if (asp->fill_texture->flags & GF_SR_TEXTURE_SVG) { GF_Rect rc; gf_rect_from_bbox(&rc, &mesh->bounds); tr_state->mesh_num_textures = gf_sc_texture_enable_ex(asp->fill_texture, NULL, &rc); } else { - tr_state->mesh_num_textures = gf_sc_texture_enable(asp->fill_texture, ((M_Appearance *)tr_state->appear)->textureTransform); +#ifndef GPAC_DISABLE_VRML + tr_state->mesh_num_textures = gf_sc_texture_enable(asp->fill_texture, tr_state->appear ? ((M_Appearance *)tr_state->appear)->textureTransform : NULL); +#endif } if (tr_state->mesh_num_textures) return asp->fill_texture; return NULL; @@ -1225,12 +1344,12 @@ void visual_3d_set_2d_strike(GF_TraverseState *tr_state, DrawAspect2D *asp) } -void visual_3d_draw_2d_with_aspect(Drawable *st, GF_TraverseState *tr_state, DrawAspect2D *asp, Bool is_svg) +void visual_3d_draw_2d_with_aspect(Drawable *st, GF_TraverseState *tr_state, DrawAspect2D *asp) { StrikeInfo2D *si; GF_TextureHandler *fill_txh; - fill_txh = visual_3d_setup_texture_2d(tr_state, asp, is_svg, st->mesh); + fill_txh = visual_3d_setup_texture_2d(tr_state, asp, st->mesh); /*fill path*/ if (fill_txh || (GF_COL_A(asp->fill_color)) ) { @@ -1248,7 +1367,7 @@ void visual_3d_draw_2d_with_aspect(Drawable *st, GF_TraverseState *tr_state, Dra } /*strike path*/ - if (!asp->pen_props.width) return; + if (!asp->pen_props.width || !GF_COL_A(asp->line_color)) return; si = drawable_get_strikeinfo(tr_state->visual->compositor, st, asp, tr_state->appear, NULL, 0, tr_state); if (!si) return; @@ -1256,9 +1375,9 @@ void visual_3d_draw_2d_with_aspect(Drawable *st, GF_TraverseState *tr_state, Dra if (!si->mesh_outline) { si->is_vectorial = !tr_state->visual->compositor->raster_outlines; si->mesh_outline = new_mesh(); -#ifndef GPAC_USE_OGL_ES +#ifdef GPAC_HAS_GLU if (si->is_vectorial) { - TesselatePath(si->mesh_outline, si->outline, asp->line_texture ? 2 : 1); + gf_mesh_tesselate_path(si->mesh_outline, si->outline, asp->line_texture ? 2 : 1); } else #endif mesh_get_outline(si->mesh_outline, st->path); @@ -1278,19 +1397,22 @@ void visual_3d_draw_2d_with_aspect(Drawable *st, GF_TraverseState *tr_state, Dra } } +#ifndef GPAC_DISABLE_VRML void visual_3d_draw_2d(Drawable *st, GF_TraverseState *tr_state) { DrawAspect2D asp; memset(&asp, 0, sizeof(DrawAspect2D)); drawable_get_aspect_2d_mpeg4(st->node, &asp, tr_state); - visual_3d_draw_2d_with_aspect(st, tr_state, &asp, 0); + visual_3d_draw_2d_with_aspect(st, tr_state, &asp); } +#endif + void visual_3d_draw_from_context(DrawableContext *ctx, GF_TraverseState *tr_state) { GF_Rect rc; gf_path_get_bounds(ctx->drawable->path, &rc); - visual_3d_draw_2d_with_aspect(ctx->drawable, tr_state, &ctx->aspect, 1); + visual_3d_draw_2d_with_aspect(ctx->drawable, tr_state, &ctx->aspect); drawable_check_focus_highlight(ctx->drawable->node, tr_state, &rc); } @@ -1298,8 +1420,10 @@ void visual_3d_draw_from_context(DrawableContext *ctx, GF_TraverseState *tr_stat static GFINLINE Bool visual_3d_setup_material(GF_TraverseState *tr_state, u32 mesh_type, Fixed *diffuse_alpha) { - SFColor def; +#ifndef GPAC_DISABLE_VRML GF_Node *__mat; +#endif + SFColor def; def.red = def.green = def.blue = FIX_ONE; /*store diffuse alpha*/ if (diffuse_alpha) *diffuse_alpha = FIX_ONE; @@ -1310,10 +1434,13 @@ static GFINLINE Bool visual_3d_setup_material(GF_TraverseState *tr_state, u32 me return 1; } +#ifndef GPAC_DISABLE_VRML +#ifndef GPAC_DISABLE_X3D if (gf_node_get_tag(tr_state->appear)==TAG_X3D_Appearance) { X_FillProperties *fp = (X_FillProperties *) ((X_Appearance*)tr_state->appear)->fillProperties; if (fp && !fp->filled) return 0; } +#endif __mat = ((M_Appearance *)tr_state->appear)->material; if (!__mat) { @@ -1324,7 +1451,9 @@ static GFINLINE Bool visual_3d_setup_material(GF_TraverseState *tr_state, u32 me switch (gf_node_get_tag((GF_Node *)__mat)) { case TAG_MPEG4_Material: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Material: +#endif { SFColor diff, spec, emi; Fixed diff_a, spec_a, emi_a; @@ -1434,10 +1563,14 @@ static GFINLINE Bool visual_3d_setup_material(GF_TraverseState *tr_state, u32 me break; } return 1; +#else + return 0; +#endif /*GPAC_DISABLE_VRML*/ } Bool visual_3d_setup_texture(GF_TraverseState *tr_state, Fixed diffuse_alpha) { +#ifndef GPAC_DISABLE_VRML GF_TextureHandler *txh; tr_state->mesh_num_textures = 0; if (!tr_state->appear) return 0; @@ -1470,13 +1603,16 @@ Bool visual_3d_setup_texture(GF_TraverseState *tr_state, Fixed diffuse_alpha) } return tr_state->mesh_num_textures; } +#endif /*GPAC_DISABLE_VRML*/ return 0; } void visual_3d_disable_texture(GF_TraverseState *tr_state) { if (tr_state->mesh_num_textures) { +#ifndef GPAC_DISABLE_VRML gf_sc_texture_disable(gf_sc_texture_get_handler( ((M_Appearance *)tr_state->appear)->texture) ); +#endif tr_state->mesh_num_textures = 0; } } @@ -1502,7 +1638,7 @@ void visual_3d_draw(GF_TraverseState *tr_state, GF_Mesh *mesh) visual_3d_mesh_paint(tr_state, mesh); visual_3d_disable_texture(tr_state); -#if !defined(GPAC_USE_OGL_ES) && !defined(GPAC_USE_TINYGL) +#if !defined(GPAC_DISABLE_VRML) && !defined(GPAC_USE_OGL_ES) && !defined(GPAC_USE_TINYGL) && !defined(GPAC_DISABLE_X3D) if (tr_state->appear && gf_node_get_tag(tr_state->appear)==TAG_X3D_Appearance) { X_Appearance *ap = (X_Appearance *)tr_state->appear; X_FillProperties *fp = ap->fillProperties ? (X_FillProperties *) ap->fillProperties : NULL; diff --git a/src/compositor/visual_manager_3d.h b/src/compositor/visual_manager_3d.h index 97ee1d5..c5651c9 100644 --- a/src/compositor/visual_manager_3d.h +++ b/src/compositor/visual_manager_3d.h @@ -46,11 +46,13 @@ Bool visual_3d_node_cull(GF_TraverseState *tr_state, GF_BBox *bbox, Bool skip_ne /*modify a viewpoint*/ void visual_3d_viewpoint_change(GF_TraverseState *tr_state, GF_Node *vp, Bool animate_change, Fixed fieldOfView, SFVec3f position, SFRotation orientation, SFVec3f local_center); - +#ifndef GPAC_DISABLE_VRML /*checks if a 3D mesh or a 2D path is under the current ray. Updates hit info if so.*/ -void visual_3d_drawable_pick(GF_Node *n, GF_TraverseState *tr_state, GF_Mesh *mesh, GF_Path *path) ; +void visual_3d_vrml_drawable_pick(GF_Node *n, GF_TraverseState *tr_state, GF_Mesh *mesh, Drawable *drawable) ; /*performs collision on the given node (2D or 3D object)*/ -void visual_3d_drawable_collide(GF_Node *node, GF_TraverseState *tr_state); +void visual_3d_vrml_drawable_collide(GF_Node *node, GF_TraverseState *tr_state); +#endif + /*register a geomery node for drawing. If the node is transparent, stacks it for later draw, otherwise draw it directly*/ void visual_3d_register_context(GF_TraverseState *tr_state, GF_Node *node_to_draw); @@ -60,13 +62,16 @@ void visual_3d_flush_contexts(GF_VisualManager *visual, GF_TraverseState *tr_sta /*draws a 3D object, setting up material and texture*/ void visual_3d_draw(GF_TraverseState *tr_state, GF_Mesh *mesh); -/*draws a 2D object, setting up material and texture*/ -void visual_3d_draw_2d(Drawable *st, GF_TraverseState *tr_state); /*draws a 2D object, setting up material and texture with specified 2D aspect*/ -void visual_3d_draw_2d_with_aspect(Drawable *st, GF_TraverseState *tr_state, DrawAspect2D *asp, Bool is_svg); +void visual_3d_draw_2d_with_aspect(Drawable *st, GF_TraverseState *tr_state, DrawAspect2D *asp); /*draws a 2D SVG object - the DrawableContext MUST be set in the traversing state*/ void visual_3d_draw_from_context(DrawableContext *ctx, GF_TraverseState *tr_state); +#ifndef GPAC_DISABLE_VRML +/*draws a 2D VRML object, setting up material and texture*/ +void visual_3d_draw_2d(Drawable *st, GF_TraverseState *tr_state); +#endif + /*sets 2D strike aspect - exported for text drawing*/ @@ -149,6 +154,10 @@ typedef struct /*clip planes in world coords*/ GF_Plane clip_planes[MAX_USER_CLIP_PLANES]; u32 num_clip_planes; + +#ifdef GF_SR_USE_DEPTH + Fixed depth_offset; +#endif } Drawable3DContext; /* diff --git a/src/compositor/visual_manager_3d_gl.c b/src/compositor/visual_manager_3d_gl.c index 0c50485..978f0df 100644 --- a/src/compositor/visual_manager_3d_gl.c +++ b/src/compositor/visual_manager_3d_gl.c @@ -46,8 +46,12 @@ # else # pragma comment(lib, "opengl32") -# pragma comment(lib, "glu32") # endif + +#ifdef GPAC_HAS_GLU +# pragma comment(lib, "glu32") +#endif + #endif /*!! HORRIBLE HACK, but on my test devices, it seems that glClipPlanex is missing on the device but not in the SDK lib !!*/ @@ -69,6 +73,8 @@ void gf_sc_load_opengl_extensions(GF_Compositor *compositor) #define GET_GLFUN(__name) (PFNGLARBMULTITEXTUREPROC) eglGetProcAddress(__name) #elif defined (WIN32) #define GET_GLFUN(__name) (PFNGLARBMULTITEXTUREPROC) wglGetProcAddress(__name) +#elif defined(CONFIG_DARWIN_GL) +#define GET_GLFUN(__name) (PFNGLARBMULTITEXTUREPROC) glutGetProcAddress(__name) #else #define GET_GLFUN(__name) (PFNGLARBMULTITEXTUREPROC) glXGetProcAddress(__name) #endif @@ -78,7 +84,8 @@ void gf_sc_load_opengl_extensions(GF_Compositor *compositor) ext = (const char *) glGetString(GL_EXTENSIONS); /*store OGL extension to config for app usage*/ - gf_cfg_set_key(compositor->user->config, "Compositor", "OpenGLExtensions", ext ? ext : "None"); + if (gf_cfg_get_key(compositor->user->config, "Compositor", "OpenGLExtensions")==NULL) + gf_cfg_set_key(compositor->user->config, "Compositor", "OpenGLExtensions", ext ? ext : "None"); if (!ext) return; memset(&compositor->gl_caps, 0, sizeof(GLCaps)); @@ -155,6 +162,7 @@ void visual_3d_setup(GF_VisualManager *visual) glClearDepthx(FIX_ONE); glLightModelx(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); glMaterialx(GL_FRONT_AND_BACK, GL_SHININESS, FLT2FIX(0.2f * 128) ); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); #else glClearDepth(1.0f); glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_FALSE); @@ -350,7 +358,7 @@ void VS3D_DrawMeshIntern(GF_TraverseState *tr_state, GF_Mesh *mesh) we must thus rebuild a dedicated array...*/ if (mesh->flags & MESH_HAS_ALPHA) { u32 i; - color_array = malloc(sizeof(Float)*4*mesh->v_count); + color_array = gf_malloc(sizeof(Float)*4*mesh->v_count); for (i=0; i<mesh->v_count; i++) { color_array[4*i] = FIX2FLT(mesh->vertices[i].color.red); color_array[4*i+1] = FIX2FLT(mesh->vertices[i].color.green); @@ -361,7 +369,7 @@ void VS3D_DrawMeshIntern(GF_TraverseState *tr_state, GF_Mesh *mesh) glColorPointer(4, GL_FLOAT, 4*sizeof(Float), color_array); tr_state->mesh_is_transparent = 1; } else { - color_array = malloc(sizeof(Float)*3*mesh->v_count); + color_array = gf_malloc(sizeof(Float)*3*mesh->v_count); for (i=0; i<mesh->v_count; i++) { color_array[3*i] = FIX2FLT(mesh->vertices[i].color.red); color_array[3*i+1] = FIX2FLT(mesh->vertices[i].color.green); @@ -515,7 +523,7 @@ void VS3D_DrawMeshIntern(GF_TraverseState *tr_state, GF_Mesh *mesh) if (has_norm) glDisableClientState(GL_NORMAL_ARRAY); #if defined(GPAC_FIXED_POINT) && !defined(GPAC_USE_OGL_ES) - if (color_array) free(color_array); + if (color_array) gf_free(color_array); if (!mesh->mesh_type && !(mesh->flags & MESH_NO_TEXTURE)) { glMatrixMode(GL_TEXTURE); glPopMatrix(); @@ -1539,8 +1547,11 @@ void visual_3d_fill_rect(GF_VisualManager *visual, GF_Rect rc, SFColorRGBA color GF_Err compositor_3d_get_screen_buffer(GF_Compositor *compositor, GF_VideoSurface *fb, u32 depth_dump_mode) { /*FIXME*/ - u32 i, hy; - char *tmp; + u32 i; +#ifndef GPAC_USE_TINYGL + char*tmp; + u32 hy; +#endif //GPAC_USE_TINYGL fb->width = compositor->vp_width; fb->height = compositor->vp_height; @@ -1552,39 +1563,21 @@ GF_Err compositor_3d_get_screen_buffer(GF_Compositor *compositor, GF_VideoSurfac return GF_NOT_SUPPORTED; #else - fb->pitch = compositor->vp_width; /* multiply by 4 if float depthbuffer */ - -#ifndef GPAC_USE_TINYGL - fb->video_buffer = (char*)malloc(sizeof(char)* fb->pitch * fb->height); -#else - fb->video_buffer = (char*)malloc(sizeof(char)* 2 * fb->pitch * fb->height); -#endif + fb->pitch_x = 0; + fb->pitch_y = compositor->vp_width; /* multiply by 4 if float depthbuffer */ + fb->video_buffer = (char*)gf_malloc(sizeof(char)* fb->pitch_y * fb->height); fb->pixel_format = GF_PIXEL_GREYSCALE; + #ifndef GPAC_USE_TINYGL - glPixelTransferf(GL_DEPTH_SCALE, compositor->OGLDepthGain); - glPixelTransferf(GL_DEPTH_BIAS, compositor->OGLDepthOffset); + //glPixelTransferf(GL_DEPTH_SCALE, FIX2FLT(compositor->OGLDepthGain) ); + //glPixelTransferf(GL_DEPTH_BIAS, FIX2FLT(compositor->OGLDepthOffset) ); #endif - /*the following is the inverse z-transform of OpenGL*/ -#if 0 - /* GL_FLOAT for float depthbuffer */ - glReadPixels(compositor->vp_x, compositor->vp_y, fb->width, fb->height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, fb->video_buffer); -#else - { - float *buff = (float *) malloc(sizeof(float)* fb->width * fb->height); - Fixed n = compositor->traverse_state->camera->z_near; - Fixed f = compositor->traverse_state->camera->z_far; - - glReadPixels(compositor->vp_x, compositor->vp_y, fb->width, fb->height, GL_DEPTH_COMPONENT, GL_FLOAT, buff); + glReadPixels(compositor->vp_x, compositor->vp_y, fb->width, fb->height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, fb->video_buffer); + //inversion - to check for (i=0; i<fb->height*fb->width; i++) - fb->video_buffer[i] = (char) (255 * (1.0 - buff[i]) / (1 - buff[i]*(1-(n/f)))); - - free(buff); - - } - -#endif + fb->video_buffer[i] = (char)(255 - (int) fb->video_buffer[i]) ; #endif /*GPAC_USE_OGL_ES*/ } @@ -1596,12 +1589,13 @@ GF_Err compositor_3d_get_screen_buffer(GF_Compositor *compositor, GF_VideoSurfac return GF_NOT_SUPPORTED; #else char *depth_data=NULL; - fb->pitch = compositor->vp_width*4; /* 4 bytes for each rgbds pixel */ + fb->pitch_x = 4; + fb->pitch_y = compositor->vp_width*4; /* 4 bytes for each rgbds pixel */ #ifndef GPAC_USE_TINYGL - fb->video_buffer = (char*)malloc(sizeof(char)* fb->pitch * fb->height); + fb->video_buffer = (char*)gf_malloc(sizeof(char)* fb->pitch_y * fb->height); #else - fb->video_buffer = (char*)malloc(sizeof(char)* 2 * fb->pitch * fb->height); + fb->video_buffer = (char*)gf_malloc(sizeof(char)* 2 * fb->pitch_y * fb->height); #endif @@ -1610,10 +1604,12 @@ GF_Err compositor_3d_get_screen_buffer(GF_Compositor *compositor, GF_VideoSurfac glReadPixels(0, 0, fb->width, fb->height, GL_RGBA, GL_UNSIGNED_BYTE, fb->video_buffer); - glPixelTransferf(GL_DEPTH_SCALE, compositor->OGLDepthGain); - glPixelTransferf(GL_DEPTH_BIAS, compositor->OGLDepthOffset); - - depth_data = (char*) malloc(sizeof(char)*fb->width*fb->height); + /* + glPixelTransferf(GL_DEPTH_SCALE, FIX2FLT(compositor->OGLDepthGain)); + glPixelTransferf(GL_DEPTH_BIAS, FIX2FLT(compositor->OGLDepthOffset)); + */ + + depth_data = (char*) gf_malloc(sizeof(char)*fb->width*fb->height); glReadPixels(0, 0, fb->width, fb->height, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, depth_data); if (depth_dump_mode==2) { @@ -1646,28 +1642,31 @@ GF_Err compositor_3d_get_screen_buffer(GF_Compositor *compositor, GF_VideoSurfac #endif /*GPAC_USE_OGL_ES*/ } else { - fb->pitch = 3*compositor->vp_width; - fb->video_buffer = (char*)malloc(sizeof(char) * fb->pitch * fb->height); + fb->pitch_x = 3; + fb->pitch_y = 3*compositor->vp_width; + fb->video_buffer = (char*)gf_malloc(sizeof(char) * fb->pitch_y * fb->height); fb->pixel_format = GF_PIXEL_RGB_24; glReadPixels(compositor->vp_x, compositor->vp_y, fb->width, fb->height, GL_RGB, GL_UNSIGNED_BYTE, fb->video_buffer); } +#ifndef GPAC_USE_TINYGL /*flip image (openGL always handle image data bottom to top) */ - tmp = (char*)malloc(sizeof(char)*fb->pitch); + tmp = (char*)gf_malloc(sizeof(char)*fb->pitch_y); hy = fb->height/2; for (i=0; i<hy; i++) { - memcpy(tmp, fb->video_buffer+ i*fb->pitch, fb->pitch); - memcpy(fb->video_buffer + i*fb->pitch, fb->video_buffer + (fb->height - 1 - i) * fb->pitch, fb->pitch); - memcpy(fb->video_buffer + (fb->height - 1 - i) * fb->pitch, tmp, fb->pitch); + memcpy(tmp, fb->video_buffer+ i*fb->pitch_y, fb->pitch_y); + memcpy(fb->video_buffer + i*fb->pitch_y, fb->video_buffer + (fb->height - 1 - i) * fb->pitch_y, fb->pitch_y); + memcpy(fb->video_buffer + (fb->height - 1 - i) * fb->pitch_y, tmp, fb->pitch_y); } - free(tmp); + gf_free(tmp); +#endif return GF_OK; } GF_Err compositor_3d_release_screen_buffer(GF_Compositor *compositor, GF_VideoSurface *framebuffer) { - free(framebuffer->video_buffer); + gf_free(framebuffer->video_buffer); framebuffer->video_buffer = 0; return GF_OK; } diff --git a/src/compositor/x3d_geometry.c b/src/compositor/x3d_geometry.c index 2b12c40..c30a6d7 100644 --- a/src/compositor/x3d_geometry.c +++ b/src/compositor/x3d_geometry.c @@ -27,6 +27,8 @@ #include "visual_manager.h" #include "drawable.h" +#ifndef GPAC_DISABLE_X3D + static void disk2d_check_changes(GF_Node *node, Drawable *stack, GF_TraverseState *tr_state) { if (gf_node_dirty_get(node)) { @@ -68,7 +70,7 @@ static void TraverseDisk2D(GF_Node *node, void *rs, Bool is_destroy) gf_path_get_bounds(stack->path, &tr_state->bounds); return; case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_SORT: #ifndef GPAC_DISABLE_3D @@ -136,7 +138,7 @@ static void TraverseArc2D(GF_Node *node, void *rs, Bool is_destroy) #endif return; case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_SORT: #ifndef GPAC_DISABLE_3D @@ -199,7 +201,7 @@ static void TraversePolyline2D(GF_Node *node, void *rs, Bool is_destroy) gf_path_get_bounds(stack->path, &tr_state->bounds); return; case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_SORT: #ifndef GPAC_DISABLE_3D @@ -299,7 +301,7 @@ static void TraverseTriangleSet2D(GF_Node *node, void *rs, Bool is_destroy) gf_path_get_bounds(stack->path, &tr_state->bounds); return; case TRAVERSE_PICK: - drawable_pick(stack, tr_state); + vrml_drawable_pick(stack, tr_state); return; case TRAVERSE_SORT: #ifndef GPAC_DISABLE_3D @@ -535,7 +537,7 @@ static void TraverseIndexedTriangleSet(GF_Node *node, void *rs, Bool is_destroy) drawable_3d_base_traverse(node, rs, is_destroy, build_indexed_triangle_set); } -static void ITS_SetIndex(GF_Node *node) +static void ITS_SetIndex(GF_Node *node, GF_Route *route) { X_IndexedTriangleSet *its = (X_IndexedTriangleSet*)node; gf_sg_vrml_field_copy(&its->index, &its->set_index, GF_SG_VRML_MFINT32); @@ -779,7 +781,7 @@ static void TraverseIndexedTriangleStripSet(GF_Node *node, void *rs, Bool is_des drawable_3d_base_traverse(node, rs, is_destroy, build_indexed_triangle_strip_set); } -static void ITSS_SetIndex(GF_Node *node) +static void ITSS_SetIndex(GF_Node *node, GF_Route *route) { X_IndexedTriangleStripSet *itss = (X_IndexedTriangleStripSet*)node; gf_sg_vrml_field_copy(&itss->index, &itss->set_index, GF_SG_VRML_MFINT32); @@ -995,7 +997,7 @@ static void TraverseIndexedTriangleFanSet(GF_Node *node, void *rs, Bool is_destr drawable_3d_base_traverse(node, rs, is_destroy, build_indexed_triangle_fan_set); } -static void ITFS_SetIndex(GF_Node *node) +static void ITFS_SetIndex(GF_Node *node, GF_Route *route) { X_IndexedTriangleFanSet *itfs = (X_IndexedTriangleFanSet *)node; gf_sg_vrml_field_copy(&itfs->index, &itfs->set_index, GF_SG_VRML_MFINT32); @@ -1011,3 +1013,5 @@ void compositor_init_indexed_triangle_fan_set(GF_Compositor *compositor, GF_Node } #endif /*GPAC_DISABLE_3D*/ + +#endif /*GPAC_DISABLE_X3D*/ diff --git a/src/export.cpp b/src/export.cpp new file mode 100644 index 0000000..4fb6300 --- /dev/null +++ b/src/export.cpp @@ -0,0 +1,1510 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * Copyright (c) ENST 2008 - + * 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. + * + */ + +/*this file is only used with Win32&MSVC to export the symbols from libgpac(static) to libgpac(dynamic) based on the GPAC configuration*/ +#include <gpac/setup.h> + +#ifdef _WIN32_WCE +#define EXPORT_SYMBOL(a) "/export:"#a +#else +#define EXPORT_SYMBOL(a) "/export:_"#a +#endif + +#ifdef _WIN32_WCE +#pragma comment (linker, EXPORT_SYMBOL(CE_Assert) ) +#pragma comment (linker, EXPORT_SYMBOL(CE_CharToWide) ) +#pragma comment (linker, EXPORT_SYMBOL(CE_WideToChar) ) +#endif + + +#pragma comment (linker, EXPORT_SYMBOL(gpac_features) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sys_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sys_close) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sleep) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sys_clock) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sys_get_rti) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sys_get_battery_state) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_4cc_to_str) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_error_to_string) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rand_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rand) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_get_user_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_enum_directory) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log_get_tools) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log_get_level) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log_set_level) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log_set_tools) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log_set_callback) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log_parse_level) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log_parse_tools) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_log_lt) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_set_progress) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_set_progress_callback) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_delete_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_move_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_temp_file_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_file_modification_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_f64_open) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_f64_seek) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_f64_tell) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_prompt_has_input) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_prompt_get_char) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_prompt_set_echo_off) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_crc_32) ) + +/* Font */ +#pragma comment (linker, EXPORT_SYMBOL(gf_font_manager_new) ) + +#ifdef GPAC_MEMORY_TRACKING +#pragma comment (linker, EXPORT_SYMBOL(gf_mem_malloc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mem_calloc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mem_realloc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mem_free) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mem_strdup) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_memory_print) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_memory_size) ) +#else +#pragma comment (linker, EXPORT_SYMBOL(gf_malloc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_calloc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_realloc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_free) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_strdup) ) +#endif /*GPAC_MEMORY_TRACKING*/ + +#pragma comment (linker, EXPORT_SYMBOL(gf_list_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_add) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_insert) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_rem) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_get) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_enum) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_find) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_del_item) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_last) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_list_rem_last) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_from_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_bit) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_int) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_long_int) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_u8) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_u16) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_u24) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_u32) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_u64) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_float) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_double) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_read_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_int) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_long_int) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_u8) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_u16) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_u24) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_u32) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_u64) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_float) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_double) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_write_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_set_eos_callback) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_align) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_available) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_get_content) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_skip_bytes) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_seek) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bs_peek_bits) ) +#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_th_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_th_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_th_run) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_th_stop) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_th_status) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_th_set_priority) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_th_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_v) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_p) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_try_lock) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sema_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sema_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sema_notify) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sema_wait) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sema_wait_for) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_set_buffer_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_set_block_mode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_get_handle) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_bind) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_connect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_send) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_receive) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_listen) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_accept) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_server_mode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_get_host_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_get_local_ip) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_get_local_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_get_remote_address) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_send_to) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_setup_multicast) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_is_multicast_address) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_send_wait) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sk_receive_wait) ) +#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_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_net_is_ipv6) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_net_mobileip_set_callback) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_base64_encode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_base64_decode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_base16_encode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_base16_decode) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_token_get) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_token_get_line) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_token_find) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_save) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_get_key) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_get_sub_key) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_set_key) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_get_section_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_get_section_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_get_key_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_get_key_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_insert_key) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cfg_del_section) ) + + +#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_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_modules_get_file_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_module_get_file_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_modules_load_interface) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_modules_load_interface_by_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_modules_close_interface) ) +#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) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_utf8_wcstombs) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_utf8_mbstowcs) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_utf8_wcslen) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_utf8_is_right_to_left) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_utf8_reorder_bidi) ) + +#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_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_process) ) +#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_dm_sess_last_error) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_dash_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_set_range) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_setup_from_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_get_resource_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_sess_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dm_del) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_parse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_suspend) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_parse_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_get_line) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_get_file_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_get_file_pos) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_peek_node) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_binary_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_get_error) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_get_root_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_get_node_start_pos) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_sax_get_node_end_pos) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_dom_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_dom_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_dom_parse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_dom_get_root) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_dom_get_error) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_dom_get_line) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_dom_serialize) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_dom_node_del) ) + +#ifndef GPAC_DISABLE_SVG +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_get_key_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_get_key_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_event_get_name) ) +#endif + +#ifdef GPAC_FIXED_POINT +#pragma comment (linker, EXPORT_SYMBOL(gf_invfix) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mulfix) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_muldiv) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_divfix) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cos) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sin) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_tan) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_atan2) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sqrt) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ceil) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_floor) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_acos) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_asin) ) +#endif /*GPAC_FIXED_POINT*/ + +#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_rect_union) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rect_center) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rect_overlaps) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rect_equal) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rect_pixelize) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_add_matrix) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_pre_multiply) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_add_translation) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_add_rotation) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_add_scale) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_add_scale_at) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_add_skew) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_add_skew_x) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_add_skew_y) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_inverse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_apply_coords) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_apply_point) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_apply_rect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_get_bit_size) ) + +/*exported for 3D tools*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_vec_len) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_vec_lensq) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_vec_dot) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_vec_norm) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_vec_scale) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_vec_cross) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_quat_to_rotation) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_quat_from_matrix) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_quat_from_rotation) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_quat_get_inv) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_quat_multiply) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_quat_rotate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_quat_from_axis_cos) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_quat_slerp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bbox_refresh) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bbox_from_rect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rect_from_bbox) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bbox_grow_point) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bbox_union) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bbox_equal) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bbox_point_inside) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bbox_get_vertices) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_from_mx2d) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_equal) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_add_translation) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_add_scale) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_add_rotation) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_add_matrix) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_add_matrix_2d) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_inverse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_apply_vec) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_apply_rect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_ortho) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_perspective) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_lookat) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_apply_bbox) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_add_matrix_4x4) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_inverse_4x4) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_apply_vec_4x4) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_decompose) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_rotate_vector) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_rotation_matrix_from_vectors) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx2d_from_mx) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_apply_plane) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_plane_get_distance) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_plane_intersect_line) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_closest_point_to_line) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_plane_get_p_vertex_idx) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bbox_plane_relation) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mx_apply_ray) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ray) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ray_hit_box) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ray_hit_sphere) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ray_hit_triangle) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ray_hit_triangle_backcull) ) + +/*color.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_stretch_bits) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cmx_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cmx_set) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cmx_set_all) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cmx_copy) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cmx_multiply) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cmx_apply) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_cmx_apply_fixed) ) + +/*path2d.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_path_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_close) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_move_to) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_move_to_vec) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_line_to) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_line_to_vec) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_cubic_to) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_cubic_to_vec) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_quadratic_to) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_quadratic_to_vec) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_rect_center) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_rect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_ellipse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_bezier) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_arc_to) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_svg_arc_to) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_add_arc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_get_control_bounds) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_get_bounds) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_flatten) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_get_flatten) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_iterator_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_iterator_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_iterator_get_length) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_iterator_get_transform) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_polygone2d_get_convexity) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_get_outline) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_path_point_over) ) + +/*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_odf_desc_esd_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_parse_descriptor) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_write_descriptor) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_read) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_copy) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_codec_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_codec_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_codec_add_com) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_codec_encode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_codec_get_au) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_codec_set_au) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_codec_decode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_codec_get_com) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_com_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_com_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_avc_cfg_del) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_slc_set_pref) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_get_bifs_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_get_text_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_get_ui_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_get_laser_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_encode_ui_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sl_depacketize) ) + +#ifndef GPAC_MINIMAL_ODF +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_write) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_add_desc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_list_read) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_list_write) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_list_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_desc_list_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_stream_type_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_stream_type_by_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_qos_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_qos_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_qos_add_qualif) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_set_start_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_set_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_add_desc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_get_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_get_start_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_get_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_get_desc_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_get_desc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_event_rem_desc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_codec_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_codec_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_codec_add_event) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_codec_encode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_codec_decode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_codec_get_event) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_avc_cfg_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_avc_cfg_read) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_avc_cfg_write) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sl_packetize) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sl_get_header_size) ) +#endif /*GPAC_MINIMAL_ODF*/ + +/*isomedia.h exports*/ +#ifndef GPAC_DISABLE_ISOM +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_sample_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_sample_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_last_error) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_probe_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_open) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_close) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_delete) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_mode) ) +#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_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_refresh_fragmented) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_timescale) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_creation_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_by_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_track_enabled) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_track_encrypted) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_media_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_media_subtype) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_mpeg4_subtype) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_media_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_description_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_description_index) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_self_contained) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_media_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_media_timescale) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_max_chunk_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_handler_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_media_language) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_check_data_reference) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_data_reference) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_sample_padding) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_for_media_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_for_movie_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_dts) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_edit_segment_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_edit_segment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_copyright_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_copyright) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_watermark) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_sync_points) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_time_offset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sync_point_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_root_od) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_root_od) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_track_in_root_od) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_esd) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_decoder_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_reference_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_reference) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_filename) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_brand_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_alternate_brand) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_padding_bits) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_visual_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_pixel_aspect_ratio) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_audio_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_chapter_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_chapter) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_user_data_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_user_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_generic_sample_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_fragment_defaults) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_fragment_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_sample_fragment_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_default_sync_track) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_3gp_config_get) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_ac3_config_get) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_set_streaming_mode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_layout_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_matrix) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_pl_indication) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_media_encrypted) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_ismacryp_info) ) +#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_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_item_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_meta_item_by_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_meta_item_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_meta_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_meta_xml) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_movie) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_segment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_single_av) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_guess_specification) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_sync_shadows) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_has_sample_dependency) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_find_od_for_track) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_apple_get_tag) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_media_data_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_omadrm_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_omadrm_media) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_dims_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_switch_group_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_switch_parameter) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_next_alternate_group_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_meta_primary_item_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_JPEG2000) ) + +# ifndef GPAC_DISABLE_ISOM_DUMP +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_dump) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_dump) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_dump_ismacryp_protection) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_dump_ismacryp_sample) ) +#endif + +#ifndef GPAC_DISABLE_ISOM_HINTING +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_payt_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_payt_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_reset_hint_reader) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_next_hint_packet) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_sdp_get) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_sdp_track_get) ) +# ifndef GPAC_DISABLE_ISOM_DUMP +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_dump_hint_sample) ) +#endif +#endif + +#ifndef GPAC_DISABLE_ISOM_WRITE +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_timescale) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_new_track) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_track) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_creation_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_creation_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_enabled) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_sample_shadow) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_append_sample_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_refresh_size_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_sample_reference) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_last_sample_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_reference) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_track_reference) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_update_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_update_sample_reference) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_final_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_storage_mode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_storage_mode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_interleave_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_interleave_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_copyright) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_media_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_media_subtype) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_copyright) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_watermark) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_edit_segment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_modify_edit_segment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_append_edit_segment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_edit_segments) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_edit_segment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_media_language) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_handler_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_user_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_user_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_user_data_item) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_use_compact_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_brand_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_modify_alternate_brand) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_sample_padding_bits) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_visual_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_pixel_aspect_ratio) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_layout_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_matrix) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_audio_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_cts_packing) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_modify_cts_offset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_cts_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_pl_indication) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_root_od_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_root_od_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_root_od) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_desc_to_root_od) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_track_to_root_od) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_track_from_root_od) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_new_mpeg4_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_change_mpeg4_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_desc_to_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_new_generic_sample_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_change_generic_sample_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_sample_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_clone_sample_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_clone_track) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_clone_pl_indications) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_clone_root_od) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_is_same_sample_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_chapter) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_chapter) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_sync_shadows) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_sync_shadow) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_group) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_priority_in_group) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_max_samples_per_chunk) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_extraction_slc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_extraction_slc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_group) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_track_priority_in_group) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_store_movie_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_load_movie_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_make_interleave) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_3gp_config_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_3gp_config_update) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_new_text_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_new_text_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_delete_text_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_add_text) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_add_style) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_add_highlight) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_set_highlight_color) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_add_karaoke) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_set_karaoke_segment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_set_scroll_delay) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_add_hyperlink) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_set_box) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_add_blink) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_set_wrap) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_text_to_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_ismacryp_protection) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_ismacryp_protection) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_change_ismacryp_protection) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_avc_config_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_avc_config_update) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_svc_config_update) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_3gp_config_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_3gp_config_update) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_media_timescale) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_estimate_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_meta_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_meta_item) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_meta_item) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_meta_primary_item) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_meta_xml) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_meta_xml) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_extract_meta_xml) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_extract_meta_item) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_apple_set_tag) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_get_next_alternate_group_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_ipod_compatible) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_reset_switch_parameters) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_reset_track_switch_parameter) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_track_switch_parameter) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_alternate_group_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_new_dims_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_update_dims_description) ) +#ifndef GPAC_DISABLE_ISOM_HINTING +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_setup_hint_track) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_new_hint_description) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_begin_hint_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_end_hint_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_hint_blank_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_hint_direct_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_hint_sample_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_hint_sample_description_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_rtp_packet_begin) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_rtp_packet_set_flags) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_rtp_packet_set_offset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_rtp_set_timescale) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_rtp_set_time_offset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_rtp_set_time_sequence_offset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_sdp_add_track_line) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_sdp_clean_track) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_sdp_add_line) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_sdp_clean) ) +#endif /*GPAC_DISABLE_ISOM_HINTING*/ + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_add_sample_fragment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_remove_sample_fragment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_setup_track_fragment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_finalize_for_fragment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_start_fragment) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_set_fragment_option) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_fragment_add_sample) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_fragment_append_data) ) +#endif + +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +/*isomedia_dev.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_parse_texte_sample) ) + +#ifndef GPAC_DISABLE_STREAMING +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_new_extended) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_append_sdp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_append_sdp_extended) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_send_au) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_send_au_with_sn) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_send_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_format_sdp_header) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_disable_auto_rtcp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_streamer_send_rtcp) ) + + +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_streamer_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_streamer_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_streamer_write_sdp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_streamer_get_sdp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_streamer_send_next_packet) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_isom_streamer_reset) ) +#endif + +#pragma comment (linker, EXPORT_SYMBOL(gf_media_map_esd) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_media_get_file_hash) ) + +#endif /*GPAC_DISABLE_ISOM*/ + + +/*plugin_network.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_term_on_message) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_on_connect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_on_disconnect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_on_command) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_on_sl_packet) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_service_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_add_media) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_service_interface) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_register_mime_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_check_extension) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_download_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_download_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_download_update_stats) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_scene_update) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_process_step) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_screen_buffer) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_release_screen_buffer) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_process_shortcut) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_set_speed) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_relocate_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_register_event_filter) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_unregister_event_filter) ) + +/*ietf.h exports*/ +#ifndef GPAC_DISABLE_STREAMING +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_nc_to_string) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_range_parse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_range_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_range_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_transport_clone) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_transport_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_command_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_command_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_command_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_response_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_response_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_response_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_session_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_session_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_set_mobile_ip) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_set_buffer_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_session_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_is_my_session) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_last_session_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_server_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_service_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_response) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_session_state) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_last_request) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_reset_aggregation) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_send_command) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_set_interleave_callback) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_session_read) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_register_interleave) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_unregister_interleave) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_session_new_server) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_command) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_load_service_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_generate_session_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_send_response) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_session_ip) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_next_interleave_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_remote_address) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtsp_get_session_port) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_setup_transport) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_set_ports) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_setup_payload) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_enable_nat_keepalive) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_initialize) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_set_info_rtp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_get_current_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_reset_buffers) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_read_rtp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_read_rtcp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_decode_rtp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_decode_rtcp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_send_rtcp_report) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_send_bye) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_send_packet) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_set_info_rtcp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_is_unicast) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_is_interleaved) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_get_clockrate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_is_active) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_get_low_interleave_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_get_hight_interleave_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_get_transport) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_get_local_ssrc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_get_loss) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_get_tcp_bytes_sent) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_get_ports) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_info_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_info_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_info_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_info_parse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_info_check) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_info_write) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_media_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_media_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_conn_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_conn_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_fmtp_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sdp_fmtp_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_builder_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_builder_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_builder_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_builder_process) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_builder_format_sdp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_builder_get_payload_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_depacketizer_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_depacketizer_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_depacketizer_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_depacketizer_process) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_rtp_depacketizer_get_slconfig) ) +#endif /*GPAC_DISABLE_STREAMING*/ + + + +#ifndef GPAC_DISABLE_AVILIB +/*avilib exports*/ +#pragma comment (linker, EXPORT_SYMBOL(AVI_open_output_file) ) +#pragma comment (linker, EXPORT_SYMBOL(AVI_close) ) +#pragma comment (linker, EXPORT_SYMBOL(AVI_set_video) ) +#pragma comment (linker, EXPORT_SYMBOL(AVI_write_frame) ) +#pragma comment (linker, EXPORT_SYMBOL(AVI_set_audio) ) +#pragma comment (linker, EXPORT_SYMBOL(AVI_write_audio) ) + +#endif /*GPAC_DISABLE_AVILIB*/ + +/*media.h exports*/ +#ifndef GPAC_DISABLE_ISOM_HINTING +#pragma comment (linker, EXPORT_SYMBOL(gf_hinter_track_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_hinter_track_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_hinter_track_process) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_hinter_track_finalize) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_hinter_finalize) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_hinter_track_get_bandwidth) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_hinter_track_get_flags) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_hinter_track_get_payload_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_hinter_can_embbed_data) ) +#endif + +#ifndef GPAC_DISABLE_MEDIA_IMPORT +#pragma comment (linker, EXPORT_SYMBOL(gf_media_make_isma) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_media_make_3gpp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_media_make_psp) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_media_import) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_media_import_chapters) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_media_change_par) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_media_change_pl) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_media_fragment_file) ) +#endif /*GPAC_DISABLE_MEDIA_IMPORT*/ + + +#ifndef GPAC_DISABLE_AV_PARSERS +#pragma comment (linker, EXPORT_SYMBOL(gf_avc_get_sps_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_avc_get_profile_name) ) +#endif /*GPAC_DISABLE_AV_PARSERS*/ + + +#ifndef GPAC_DISABLE_MEDIA_EXPORT +#pragma comment (linker, EXPORT_SYMBOL(gf_media_export) ) +#endif /*GPAC_DISABLE_MEDIA_EXPORT*/ + +/*mcrypt exports*/ +#ifndef GPAC_DISABLE_MCRYPT +#pragma comment (linker, EXPORT_SYMBOL(gf_crypt_open) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_crypt_close) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_crypt_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_crypt_decrypt) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_crypt_encrypt) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_crypt_set_state) ) +#endif GPAC_DISABLE_MCRYPT +#pragma comment (linker, EXPORT_SYMBOL(gf_sha1_csum) ) + +#ifndef GPAC_DISABLE_AV_PARSERS +#pragma comment (linker, EXPORT_SYMBOL(gf_m4v_parser_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4v_parser_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4v_parse_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4v_parse_frame) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4v_get_object_start) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4v_is_valid_object_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4v_get_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4v_rewrite_pl) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_num_channels) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_sampling_rate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_window_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_object_type_indication) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_layer) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_frame_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_get_next_header) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_get_next_header_mem) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4a_get_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4a_write_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4a_write_config_bs) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_ac3_parser_bs) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ac3_get_channels) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ac3_get_bitrate) ) +#ifndef GPAC_DISABLE_OGG +#pragma comment (linker, EXPORT_SYMBOL(gf_vorbis_parse_header) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_vorbis_check_frame) ) +#endif + +#endif + +#pragma comment (linker, EXPORT_SYMBOL(gf_img_parse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_img_jpeg_dec) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_img_png_dec) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_img_png_file_dec) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_img_png_enc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4v_get_profile_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_version) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mp3_version_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4a_object_type_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m4a_get_profile_name) ) + +#if !defined(GPAC_DISABLE_MCRYPT) && !defined(GPAC_DISABLE_ISOM_WRITE) +/*ismacryp.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_ismacryp_crypt_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ismacryp_decrypt_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ismacryp_encrypt_track) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ismacryp_decrypt_track) ) +#endif + +#pragma comment (linker, EXPORT_SYMBOL(gf_ismacryp_gpac_get_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_ismacryp_mpeg4ip_get_info) ) + +/*scene_manager.h exports*/ +#ifndef GPAC_DISABLE_SCENE_STATS +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stats_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stats_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stats_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stats_get) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stats_for_graph) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stats_for_scene) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stats_for_command) ) +#endif + +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stream_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stream_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_stream_au_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_aggregate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_load_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_load_done) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_load_string) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_load_run) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_load_suspend) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_import_bifs_subtitle) ) + +#ifndef GPAC_DISABLE_SCENE_ENCODER +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_encode_to_file) ) +#endif + +#ifndef GPAC_DISABLE_SCENE_DUMP +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_dumper_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_dumper_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_dump) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_dump_command_list) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sm_dump_graph) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_dump_au) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_dump_com) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_dump_desc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odf_dump_com_list) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_dump_event) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_oci_dump_au) ) +#endif + +#ifndef GPAC_DISABLE_SENG +/*bifsengine exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_init_from_string) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_init_from_context) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_get_stream_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_get_stream_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_encode_context) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_encode_from_file) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_encode_from_string) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_encode_from_commands) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_save_context) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_enable_aggregation) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_aggregate_context) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_get_base64_iod) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_get_iod) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_terminate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_get_stream_carousel_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_seng_dump_rap_on) ) +#endif + +/*bifs.h exports*/ +#ifndef GPAC_DISABLE_BIFS +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_decoder_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_decoder_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_decoder_set_extraction_path) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_decoder_ignore_size_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_decoder_configure_stream) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_decoder_remove_stream) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_decode_au) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_decode_command_list) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_get_aq_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_get_node_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_proto_field_set_aq_info) ) +#ifndef GPAC_DISABLE_BIFS_ENC +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_encoder_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_encoder_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_encoder_new_stream) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_encode_au) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_encoder_get_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_encoder_get_version) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_bifs_encoder_get_rap) ) +#endif +#endif /*GPAC_DISABLE_BIFS*/ + + +/*scenegraph.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_tag) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_set_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_name_and_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_private) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_set_private) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_set_callback_function) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_register) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_unregister) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_replace) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_unregister_children) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_allow_cyclic_traverse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_traverse) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_traverse_children) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_parent_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_parent) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_parent_of) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_class_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_dirty_set) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_dirty_clear) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_dirty_get) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_dirty_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_field) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_field_by_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_graph) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_scene_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_new_subscene) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_set_scene_time_callback) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_set_node_callback) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_set_private) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_get_private) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_set_scene_size_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_use_pixel_metrics) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_get_scene_size_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_get_root_node) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_set_root_node) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_find_node) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_find_node_by_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_add_namespace) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_changed) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_clone) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_has_scripting) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_command_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_command_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_command_apply) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_command_apply_list) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_command_field_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_get_next_available_node_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_get_max_node_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_field_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_list_add_child) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_list_add_child_last) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_list_insert_child) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_list_del_child) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_list_find_child) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_list_get_child) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_list_get_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_list_del_child_idx) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_node_dump_attribute) ) + +#ifndef GPAC_DISABLE_SVG +#pragma comment (linker, EXPORT_SYMBOL(gf_node_dom_listener_add) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_event_type_by_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_event_fire) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_add_text_node) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_set_textContent) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_flatten_textContent) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_attribute_by_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_listener_build) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dom_listener_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_handle_dom_event) ) + +#pragma comment (linker, EXPORT_SYMBOL(gf_svg_parse_attribute) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_svg_parse_style) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_attribute_by_tag) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_svg_create_attribute_value) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_svg_flatten_attributes) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_svg_apply_inheritance) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_svg_properties_init_pointers) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_svg_properties_reset_pointers) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_register_iri) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_unregister_iri) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_svg_parse_element_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_svg_is_animation_tag) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_xml_get_element_tag) ) + + +#endif + + +#ifdef GPAC_HAS_SPIDERMONKEY +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_js_get_node) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_js_add_root) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_js_add_named_root) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_js_remove_root) ) +#ifndef GPAC_DISABLE_SVG +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_js_event_add_listener) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_js_event_remove_listener) ) +#endif +#endif + +/* scenegraph_vrml.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_node_replace_child) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_sfrotation_interpolate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_mfurl_del) ) +#ifndef GPAC_DISABLE_VRML +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_num_fields_in_mode) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_insert_child) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_remove_child) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_event_out) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_event_out_str) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_get_event_type_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_get_field_type_by_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_field_pointer_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_field_pointer_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_is_sf_field) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_get_sf_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_mf_insert) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_mf_append) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_mf_remove) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_mf_alloc) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_mf_get_item) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_mf_reset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_field_copy) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_vrml_field_equal) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_route_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_route_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_route_del_by_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_route_find) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_route_find_by_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_route_set_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_route_get_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_route_set_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_route_get_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_activate_routes) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_set_in_graph) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_get_graph) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_set_private) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_get_private) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_get_extern_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_add_node_code) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_get_field_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_field_find_by_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_field_find) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_field_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_field_set_ised) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_field_set_private) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_field_get_private) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_field_get_field) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_create_instance) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_load_code) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_find_proto) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_delete_all_protos) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_get_proto) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_get_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_get_class_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_field_is_sftime_offset) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_proto_instance_set_ised) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_script_field_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_script_field_get_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_script_load) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_script_event_in) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_node_mpeg4_type_by_class_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_get_next_available_route_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_set_max_defined_route_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_get_next_available_proto_id) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_set_proto_loader) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_sfcolor_to_rgba) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_lock_javascript) ) + +#ifndef GPAC_DISABLE_X3D +#pragma comment (linker, EXPORT_SYMBOL(gf_node_x3d_type_by_class_name) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_x3d_get_node_type) ) +#endif + +#ifdef GPAC_HAS_SPIDERMONKEY +#ifndef GPAC_DISABLE_SVG +#pragma comment (linker, EXPORT_SYMBOL(gf_sg_handle_dom_event_for_vrml) ) +#endif +#endif + +#endif /*GPAC_DISABLE_VRML*/ + + +/*terminal.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_term_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_connect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_disconnect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_navigate_to) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_play_from_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_set_option) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_option) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_framerate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_time_in_ms) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_viewpoint) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_set_viewpoint) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_root_object) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_object_count) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_object) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_object_subscene_type) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_select_object) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_object_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_download_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_channel_net_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_world_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_dump_scene) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_set_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_user_event) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_mouse_input) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_keyboard_input) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_string_input) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_connect_from_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_add_object) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_is_supported_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_attach_service) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_set_simulation_frame_rate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_simulation_frame_rate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_step_clocks) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_process_flush) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_service_interface) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_service_info) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_text_selection) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_paste_text) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_get_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_relocate_url) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_connect_with_path) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mo_register) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mo_unregister) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_mo_get_scenegraph) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_send_event) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_lock_compositor) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_switch_quality) ) + + +/*compositor.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_set_fps) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_set_scene) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_draw_frame) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_on_node_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_invalidate) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_get_clock) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_lock) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_user_event) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_map_point) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_set_option) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_get_option) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_get_fps) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_get_screen_buffer) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_release_screen_buffer) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_simulation_tick) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_reset_graphics) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_pick_node) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_get_viewpoint) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_set_viewpoint) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_set_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_register_extra_graph) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_get_compositor) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_reload_audio_filters) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_add_video_listener) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_remove_video_listener) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_add_audio_listener) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_remove_audio_listener) ) + + +#ifndef GPAC_DISABLE_SVG +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_svg_convert_length_to_display) ) +#endif + +/*compositor_dev.h exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_register_time_node) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_unregister_time_node) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_setup) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_destroy) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_get_handler) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_check_url_change) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_play) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_play_from_to) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_stop) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_restart) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_update_frame) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_texture_release_stream) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_audio_register) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_audio_unregister) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_audio_setup) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_audio_open) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_audio_stop) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_sc_audio_restart) ) + +/*terminal_dev exports*/ +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_get_time) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_attach_to_compositor) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_find_odm) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_set_duration) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_setup_object) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_register_extra_graph) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_force_size) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_process_anchor) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_scene_disconnect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odm_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odm_setup_object) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odm_disconnect) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odm_setup_es) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_odm_remove_es) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_node_callback) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_term_message) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_clock_time) ) + +/*mpegts.h exports*/ +#ifndef GPAC_DISABLE_MPEG2TS +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_get_esd) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_demux_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_demux_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_process_data) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_reset_parsers) ) +#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) ) + +#ifndef GPAC_DISABLE_MPEG2TS_MUX +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_program_add) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_program_stream_add) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_update_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_mux_process) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_get_sys_clock) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_get_ts_clock) ) +#endif /*GPAC_DISABLE_MPEG2TS_MUX*/ +#endif /*GPAC_DISABLE_MPEG2TS*/ + +/*laser.h exports*/ +#ifndef GPAC_DISABLE_LASER +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_decoder_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_decoder_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_decoder_set_clock) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_decoder_configure_stream) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_decoder_remove_stream) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_decode_au) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_decode_command_list) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_encoder_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_encoder_del) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_encoder_new_stream) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_encode_au) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_encoder_get_config) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_laser_encoder_get_rap) ) +#endif /*GPAC_DISABLE_LASER*/ + +#pragma comment (linker, EXPORT_SYMBOL(gf_font_manager_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_font_manager_set_font) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_font_manager_create_span) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_font_manager_refresh_span_bounds) ) + +/* 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_init) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dvb_mpe_section_new) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_dvb_mpe_shutdown) ) +#pragma comment (linker, EXPORT_SYMBOL(gf_m2ts_print_mpe_info) ) +#endif diff --git a/src/ietf/rtcp.c b/src/ietf/rtcp.c index 66a178d..d52bdab 100644 --- a/src/ietf/rtcp.c +++ b/src/ietf/rtcp.c @@ -24,6 +24,9 @@ #include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/bitstream.h> #ifndef _WIN32_WCE @@ -45,13 +48,15 @@ u32 gf_rtp_read_rtcp(GF_RTPChannel *ch, char *buffer, u32 buffer_size) } GF_EXPORT -GF_Err gf_rtp_decode_rtcp(GF_RTPChannel *ch, char *pck, u32 pck_size) +GF_Err gf_rtp_decode_rtcp(GF_RTPChannel *ch, char *pck, u32 pck_size, Bool *has_sr) { GF_RTCPHeader rtcp_hdr; GF_BitStream *bs; char sdes_buffer[300]; u32 i, sender_ssrc, cur_ssrc, val, sdes_type, sdes_len, res, first, nb_bytes, nb_pck; GF_Err e = GF_OK; + + if (has_sr) *has_sr=0; //bad RTCP packet if (pck_size < 4 ) return GF_NON_COMPLIANT_BITSTREAM; @@ -114,16 +119,17 @@ GF_Err gf_rtp_decode_rtcp(GF_RTPChannel *ch, char *pck, u32 pck_size) nb_bytes = gf_bs_read_u32(bs); rtcp_hdr.Length -= 5; + if (has_sr) *has_sr=1; #ifndef GPAC_DISABLE_LOG - if ((gf_log_get_level() >= (GF_LOG_DEBUG)) && (gf_log_get_tools() & (GF_LOG_RTP))) { + if ((gf_log_get_level() >= (GF_LOG_INFO)) && (gf_log_get_tools() & (GF_LOG_RTP))) { #ifndef _WIN32_WCE time_t gtime = ch->last_SR_NTP_sec - GF_NTP_SEC_1900_TO_1970; const char *ascTime = asctime(gmtime(>ime)); #else const char *ascTime = "Not Available"; #endif - GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP] RTCP-SR\t%d\t%d\t%d\t%d\t%s\n", + GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] RTCP SR: SSRC %d - RTP Time %d - Nb Pck %d - Nb Bytes %d - Time %s\n", ch->SenderSSRC, ch->last_SR_rtp_time, ch->total_pck, @@ -143,6 +149,8 @@ GF_Err gf_rtp_decode_rtcp(GF_RTPChannel *ch, char *pck, u32 pck_size) rtcp_hdr.Length -= 1; process_reports: + +#if 0 //process all reports - we actually don't since we do not handle sources //to add for (i=0; i<rtcp_hdr.Count; i++) { @@ -164,10 +172,7 @@ process_reports: rtcp_hdr.Length -= 6; } //remaining bytes? we skip (this includes padding and crypto - not supported) - while (rtcp_hdr.Length) { - gf_bs_read_u32(bs); - rtcp_hdr.Length -= 1; - } +#endif break; //SDES @@ -474,7 +479,7 @@ GF_Err gf_rtp_send_bye(GF_RTPChannel *ch, else e = GF_BAD_PARAM; } - free(report_buf); + gf_free(report_buf); return e; } @@ -521,7 +526,7 @@ GF_Err gf_rtp_send_rtcp_report(GF_RTPChannel *ch, ch->rtcp_bytes_sent += report_size; - free(report_buf); + gf_free(report_buf); if (!e) { //Update the channel record if no error - otherwise next RTCP will triger an RR @@ -533,7 +538,7 @@ GF_Err gf_rtp_send_rtcp_report(GF_RTPChannel *ch, -#define RTCP_SAFE_FREE(p) if (p) free(p); \ +#define RTCP_SAFE_FREE(p) if (p) gf_free(p); \ p = NULL; GF_EXPORT @@ -544,34 +549,36 @@ GF_Err gf_rtp_set_info_rtcp(GF_RTPChannel *ch, u32 InfoCode, char *info_string) switch (InfoCode) { case GF_RTCP_INFO_NAME: RTCP_SAFE_FREE(ch->s_name); - if (info_string) ch->s_name = strdup(info_string); + if (info_string) ch->s_name = gf_strdup(info_string); break; case GF_RTCP_INFO_EMAIL: RTCP_SAFE_FREE(ch->s_email); - if (info_string) ch->s_email = strdup(info_string); + if (info_string) ch->s_email = gf_strdup(info_string); break; case GF_RTCP_INFO_PHONE: RTCP_SAFE_FREE(ch->s_phone); - if (info_string) ch->s_phone = strdup(info_string); + if (info_string) ch->s_phone = gf_strdup(info_string); break; case GF_RTCP_INFO_LOCATION: RTCP_SAFE_FREE(ch->s_location); - if (info_string) ch->s_location = strdup(info_string); + if (info_string) ch->s_location = gf_strdup(info_string); break; case GF_RTCP_INFO_TOOL: RTCP_SAFE_FREE(ch->s_tool); - if (info_string) ch->s_tool = strdup(info_string); + if (info_string) ch->s_tool = gf_strdup(info_string); break; case GF_RTCP_INFO_NOTE: RTCP_SAFE_FREE(ch->s_note); - if (info_string) ch->s_note = strdup(info_string); + if (info_string) ch->s_note = gf_strdup(info_string); break; case GF_RTCP_INFO_PRIV: RTCP_SAFE_FREE(ch->s_priv); - if (info_string) ch->s_name = strdup(info_string); + if (info_string) ch->s_name = gf_strdup(info_string); break; default: return GF_BAD_PARAM; } return GF_OK; } + +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/ietf/rtp.c b/src/ietf/rtp.c index 090e9b8..6cd44c3 100644 --- a/src/ietf/rtp.c +++ b/src/ietf/rtp.c @@ -23,7 +23,8 @@ */ #include <gpac/internal/ietf_dev.h> -#include <gpac/bitstream.h> + +#ifndef GPAC_DISABLE_STREAMING #define MAX_RTP_SN 0x10000 @@ -45,54 +46,54 @@ void gf_rtp_del(GF_RTPChannel *ch) if (!ch) return; if (ch->rtp) gf_sk_del(ch->rtp); if (ch->rtcp) gf_sk_del(ch->rtcp); - if (ch->net_info.source) free(ch->net_info.source); - if (ch->net_info.destination) free(ch->net_info.destination); - if (ch->net_info.Profile) free(ch->net_info.Profile); + if (ch->net_info.source) gf_free(ch->net_info.source); + if (ch->net_info.destination) gf_free(ch->net_info.destination); + if (ch->net_info.Profile) gf_free(ch->net_info.Profile); if (ch->po) gf_rtp_reorderer_del(ch->po); - if (ch->send_buffer) free(ch->send_buffer); + if (ch->send_buffer) gf_free(ch->send_buffer); - if (ch->CName) free(ch->CName); - if (ch->s_name) free(ch->s_name); - if (ch->s_email) free(ch->s_email); - if (ch->s_location) free(ch->s_location); - if (ch->s_phone) free(ch->s_phone); - if (ch->s_tool) free(ch->s_tool); - if (ch->s_note) free(ch->s_note); - if (ch->s_priv) free(ch->s_priv); - free(ch); + if (ch->CName) gf_free(ch->CName); + if (ch->s_name) gf_free(ch->s_name); + if (ch->s_email) gf_free(ch->s_email); + if (ch->s_location) gf_free(ch->s_location); + if (ch->s_phone) gf_free(ch->s_phone); + if (ch->s_tool) gf_free(ch->s_tool); + if (ch->s_note) gf_free(ch->s_note); + if (ch->s_priv) gf_free(ch->s_priv); + gf_free(ch); } GF_EXPORT -GF_Err gf_rtp_setup_transport(GF_RTPChannel *ch, GF_RTSPTransport *trans_info, char *remote_address) +GF_Err gf_rtp_setup_transport(GF_RTPChannel *ch, GF_RTSPTransport *trans_info, const char *remote_address) { if (!ch || !trans_info) return GF_BAD_PARAM; //assert we have at least ONE source ID if (!trans_info->source && !remote_address) return GF_BAD_PARAM; - if (ch->net_info.destination) free(ch->net_info.destination); - if (ch->net_info.Profile) free(ch->net_info.Profile); - if (ch->net_info.source) free(ch->net_info.source); + if (ch->net_info.destination) gf_free(ch->net_info.destination); + if (ch->net_info.Profile) gf_free(ch->net_info.Profile); + if (ch->net_info.source) gf_free(ch->net_info.source); memcpy(&ch->net_info, trans_info, sizeof(GF_RTSPTransport)); if (trans_info->destination) - ch->net_info.destination = strdup(trans_info->destination); + ch->net_info.destination = gf_strdup(trans_info->destination); if (trans_info->Profile) - ch->net_info.Profile = strdup(trans_info->Profile); + ch->net_info.Profile = gf_strdup(trans_info->Profile); if (!ch->net_info.IsUnicast && trans_info->destination) { - ch->net_info.source = strdup(trans_info->destination); + ch->net_info.source = gf_strdup(trans_info->destination); if (ch->net_info.client_port_first) { ch->net_info.port_first = ch->net_info.client_port_first; ch->net_info.port_last = ch->net_info.client_port_last; } - ch->net_info.source = strdup(trans_info->destination); + ch->net_info.source = gf_strdup(trans_info->destination); } else if (trans_info->source) { - ch->net_info.source = strdup(trans_info->source); + ch->net_info.source = gf_strdup(trans_info->source); } else { - ch->net_info.source = strdup(remote_address); + ch->net_info.source = gf_strdup(remote_address); } if (trans_info->SSRC) ch->SenderSSRC = trans_info->SSRC; @@ -144,6 +145,7 @@ GF_Err gf_rtp_set_info_rtp(GF_RTPChannel *ch, u32 seq_num, u32 rtp_time, u32 ssr GF_EXPORT GF_Err gf_rtp_initialize(GF_RTPChannel *ch, u32 UDPBufferSize, Bool IsSource, u32 PathMTU, u32 ReorederingSize, u32 MaxReorderDelay, char *local_ip) { + u16 port; GF_Err e; if (IsSource && !PathMTU) return GF_BAD_PARAM; @@ -165,6 +167,18 @@ GF_Err gf_rtp_initialize(GF_RTPChannel *ch, u32 UDPBufferSize, Bool IsSource, u3 //destination MUST be specified for unicast if (IsSource && ch->net_info.IsUnicast && !ch->net_info.destination) return GF_BAD_PARAM; + /* forcing unicast when the address is not a multicast */ + if (!ch->net_info.IsUnicast) { + if (IsSource){ + if (ch->net_info.destination && !gf_sk_is_multicast_address(ch->net_info.destination)) { + ch->net_info.IsUnicast = 1; + } + } else { + if (ch->net_info.source && !gf_sk_is_multicast_address(ch->net_info.source)) { + ch->net_info.IsUnicast = 1; + } + } + } // // RTP // @@ -173,7 +187,12 @@ GF_Err gf_rtp_initialize(GF_RTPChannel *ch, u32 UDPBufferSize, Bool IsSource, u3 if (ch->net_info.IsUnicast) { //if client, bind and connect the socket if (!IsSource) { - e = gf_sk_bind(ch->rtp, local_ip, ch->net_info.client_port_first, ch->net_info.source, ch->net_info.port_first, GF_SOCK_REUSE_PORT); + port = ch->net_info.port_first; + if (!port) port = ch->net_info.client_port_first; + /*if a destination adress was given (rtsd) use it*/ + if (!local_ip && ch->net_info.destination) local_ip = ch->net_info.destination; + + e = gf_sk_bind(ch->rtp, local_ip, ch->net_info.client_port_first, ch->net_info.source, port, GF_SOCK_REUSE_PORT); if (e) return e; } //else bind and set remote destination @@ -188,15 +207,12 @@ GF_Err gf_rtp_initialize(GF_RTPChannel *ch, u32 UDPBufferSize, Bool IsSource, u3 //don't like that on local loop ... e = gf_sk_setup_multicast(ch->rtp, ch->net_info.source, ch->net_info.port_first, ch->net_info.TTL, (IsSource==2), local_ip); if (e) return e; - - //destination is used for multicast interface addressing - TO DO - } if (UDPBufferSize) gf_sk_set_buffer_size(ch->rtp, IsSource, UDPBufferSize); if (IsSource) { - if (ch->send_buffer) free(ch->send_buffer); - ch->send_buffer = (char *) malloc(sizeof(char) * PathMTU); + if (ch->send_buffer) gf_free(ch->send_buffer); + ch->send_buffer = (char *) gf_malloc(sizeof(char) * PathMTU); ch->send_buffer_size = PathMTU; } @@ -214,7 +230,12 @@ GF_Err gf_rtp_initialize(GF_RTPChannel *ch, u32 UDPBufferSize, Bool IsSource, u3 if (!ch->rtcp) return GF_IP_NETWORK_FAILURE; if (ch->net_info.IsUnicast) { if (!IsSource) { - e = gf_sk_bind(ch->rtcp, local_ip, ch->net_info.client_port_last, ch->net_info.source, ch->net_info.port_last, GF_SOCK_REUSE_PORT); + port = ch->net_info.port_last; + if (!port) port = ch->net_info.client_port_last; + /*if a destination adress was given (rtsd) use it*/ + if (!local_ip && ch->net_info.destination) local_ip = ch->net_info.destination; + + e = gf_sk_bind(ch->rtcp, local_ip, ch->net_info.client_port_last, ch->net_info.source, port, GF_SOCK_REUSE_PORT); if (e) return e; } else { e = gf_sk_bind(ch->rtcp, local_ip, ch->net_info.port_last, ch->net_info.destination, ch->net_info.client_port_last, GF_SOCK_REUSE_PORT); @@ -225,7 +246,6 @@ GF_Err gf_rtp_initialize(GF_RTPChannel *ch, u32 UDPBufferSize, Bool IsSource, u3 //Bind to multicast (auto-join the group) e = gf_sk_setup_multicast(ch->rtcp, ch->net_info.source, ch->net_info.port_last, ch->net_info.TTL, (IsSource==2), local_ip); if (e) return e; - //destination is used for multicast interface addressing - TO DO } } @@ -233,7 +253,7 @@ GF_Err gf_rtp_initialize(GF_RTPChannel *ch, u32 UDPBufferSize, Bool IsSource, u3 if (!ch->CName) { //this is the real CName setup if (!ch->rtp) { - ch->CName = strdup("mpeg4rtp"); + ch->CName = gf_strdup("mpeg4rtp"); } else { char name[GF_MAX_IP_NAME_LEN]; @@ -243,7 +263,7 @@ GF_Err gf_rtp_initialize(GF_RTPChannel *ch, u32 UDPBufferSize, Bool IsSource, u3 start = strlen(name); //get host IP or loopback if error if (gf_sk_get_local_ip(ch->rtp, name+start) != GF_OK) strcpy(name+start, "127.0.0.1"); - ch->CName = strdup(name); + ch->CName = gf_strdup(name); } } @@ -313,7 +333,7 @@ u32 gf_rtp_read_rtp(GF_RTPChannel *ch, char *buffer, u32 buffer_size) pck = (char *) gf_rtp_reorderer_get(ch->po, &res); if (pck) { memcpy(buffer, pck, res); - free(pck); + gf_free(pck); } } /*monitor keep-alive period*/ @@ -390,6 +410,11 @@ GF_Err gf_rtp_decode_rtp(GF_RTPChannel *ch, char *pck, u32 pck_size, GF_RTPHeade ch->rtp_first_SN = rtp_hdr->SequenceNumber; ch->num_sn_loops = 0; } + if (ch->first_SR && !ch->SenderSSRC && rtp_hdr->SSRC) { + ch->SenderSSRC = rtp_hdr->SSRC; + GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] Assigning SSRC %d because none has been signaled\n", ch->SenderSSRC)); + } + if (!ch->ntp_init && ch->SenderSSRC && (ch->SenderSSRC != rtp_hdr->SSRC) ) { GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] SSRC mismatch: %d vs %d\n", rtp_hdr->SSRC, ch->SenderSSRC)); @@ -419,6 +444,7 @@ GF_Err gf_rtp_decode_rtp(GF_RTPChannel *ch, char *pck, u32 pck_size, GF_RTPHeade lost = 0; LastSeq = ch->last_pck_sn; CurrSeq = (u32) rtp_hdr->SequenceNumber; + ch->packet_loss = 0; /*next sequential pck*/ if ( ( (LastSeq + 1) & 0xffff ) == CurrSeq ) { ch->last_num_pck_rcv += 1; @@ -439,6 +465,7 @@ GF_Err gf_rtp_decode_rtp(GF_RTPChannel *ch, char *pck, u32 pck_size, GF_RTPHeade ch->last_num_pck_expected += lost; ch->last_num_pck_rcv += 1; ch->last_num_pck_loss += lost; + ch->packet_loss = 1; } ch->last_pck_sn = CurrSeq; @@ -447,7 +474,7 @@ GF_Err gf_rtp_decode_rtp(GF_RTPChannel *ch, char *pck, u32 pck_size, GF_RTPHeade ch->total_pck++; ch->total_bytes += pck_size-12; - GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP]\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("[RTP]\t%d\t%d\t%u\t%d\t%d\t%d\t%d\t%d\t%d\n", ch->SenderSSRC, rtp_hdr->SequenceNumber, rtp_hdr->TimeStamp, @@ -487,10 +514,12 @@ Double gf_rtp_get_current_time(GF_RTPChannel *ch) GF_EXPORT -GF_Err gf_rtp_send_packet(GF_RTPChannel *ch, GF_RTPHeader *rtp_hdr, char *extra_header, u32 extra_header_size, char *pck, u32 pck_size) +GF_Err gf_rtp_send_packet(GF_RTPChannel *ch, GF_RTPHeader *rtp_hdr, char *pck, u32 pck_size, Bool fast_send) { GF_Err e; - u32 Start, i; + u32 i, Start; + char *hdr = NULL; + GF_BitStream *bs; if (!ch || !rtp_hdr @@ -499,13 +528,16 @@ GF_Err gf_rtp_send_packet(GF_RTPChannel *ch, GF_RTPHeader *rtp_hdr, char *extra_ || (rtp_hdr->CSRCCount && !rtp_hdr->CSRC) || (rtp_hdr->CSRCCount > 15)) return GF_BAD_PARAM; - if (12 + extra_header_size + pck_size + 4*rtp_hdr->CSRCCount > ch->send_buffer_size) return GF_IO_ERR; + if (rtp_hdr->CSRCCount) fast_send=0; - //we don't support multiple CSRC now. Only one source (the server) is allowed - if (rtp_hdr->CSRCCount) return GF_NOT_SUPPORTED; + if (12 + pck_size + 4*rtp_hdr->CSRCCount > ch->send_buffer_size) return GF_IO_ERR; - bs = gf_bs_new(ch->send_buffer, ch->send_buffer_size, GF_BITSTREAM_WRITE); - + if (fast_send) { + hdr = pck - 12; + bs = gf_bs_new(hdr, 12, GF_BITSTREAM_WRITE); + } else { + bs = gf_bs_new(ch->send_buffer, ch->send_buffer_size, GF_BITSTREAM_WRITE); + } //write header gf_bs_write_int(bs, rtp_hdr->Version, 2); gf_bs_write_int(bs, rtp_hdr->Padding, 1); @@ -515,7 +547,7 @@ GF_Err gf_rtp_send_packet(GF_RTPChannel *ch, GF_RTPHeader *rtp_hdr, char *extra_ gf_bs_write_int(bs, rtp_hdr->PayloadType, 7); gf_bs_write_u16(bs, rtp_hdr->SequenceNumber); gf_bs_write_u32(bs, rtp_hdr->TimeStamp); - gf_bs_write_u32(bs, rtp_hdr->SSRC); + gf_bs_write_u32(bs, ch->SSRC); for (i=0; i<rtp_hdr->CSRCCount; i++) { gf_bs_write_u32(bs, rtp_hdr->CSRC[i]); @@ -524,14 +556,13 @@ GF_Err gf_rtp_send_packet(GF_RTPChannel *ch, GF_RTPHeader *rtp_hdr, char *extra_ Start = (u32) gf_bs_get_position(bs); gf_bs_del(bs); - //extra header - if (extra_header_size) { - memcpy(ch->send_buffer + Start, extra_header, extra_header_size); - Start += extra_header_size; + //copy payload + if (fast_send) { + e = gf_sk_send(ch->rtp, hdr, pck_size+12); + } else { + memcpy(ch->send_buffer + Start, pck, pck_size); + e = gf_sk_send(ch->rtp, ch->send_buffer, Start + pck_size); } - //payload - memcpy(ch->send_buffer + Start, pck, pck_size); - e = gf_sk_send(ch->rtp, ch->send_buffer, Start + pck_size); if (e) return e; //Update RTCP for sender reports @@ -544,11 +575,13 @@ GF_Err gf_rtp_send_packet(GF_RTPChannel *ch, GF_RTPHeader *rtp_hdr, char *extra_ ch->first_SR = 0; } - ch->num_payload_bytes += pck_size + extra_header_size; + ch->num_payload_bytes += pck_size; ch->num_pck_sent += 1; //store timing ch->last_pck_ts = rtp_hdr->TimeStamp; gf_net_get_ntp(&ch->last_pck_ntp_sec, &ch->last_pck_ntp_frac); + + if (!ch->no_auto_rtcp) gf_rtp_send_rtcp_report(ch, NULL, NULL); return GF_OK; } @@ -686,8 +719,13 @@ u32 gf_rtp_get_tcp_bytes_sent(GF_RTPChannel *ch) GF_EXPORT void gf_rtp_get_ports(GF_RTPChannel *ch, u16 *rtp_port, u16 *rtcp_port) { - *rtp_port = ch->net_info.client_port_first; - *rtcp_port = ch->net_info.client_port_last; + if (ch->net_info.client_port_first) { + if (rtp_port) *rtp_port = ch->net_info.client_port_first; + if (rtcp_port) *rtcp_port = ch->net_info.client_port_last; + } else { + if (rtp_port) *rtp_port = ch->net_info.port_first; + if (rtcp_port) *rtcp_port = ch->net_info.port_last; + } } @@ -713,8 +751,8 @@ static void DelItem(GF_POItem *it) { if (it) { if (it->next) DelItem(it->next); - free(it->pck); - free(it); + gf_free(it->pck); + gf_free(it); } } @@ -722,7 +760,7 @@ static void DelItem(GF_POItem *it) void gf_rtp_reorderer_del(GF_RTPReorder *po) { if (po->in) DelItem(po->in); - free(po); + gf_free(po); } void gf_rtp_reorderer_reset(GF_RTPReorder *po) @@ -743,11 +781,11 @@ GF_Err gf_rtp_reorderer_add(GF_RTPReorder *po, void *pck, u32 pck_size, u32 pck_ if (!po) return GF_BAD_PARAM; - it = (GF_POItem *) malloc(sizeof(GF_POItem)); + it = (GF_POItem *) gf_malloc(sizeof(GF_POItem)); it->pck_seq_num = pck_seqnum; it->next = NULL; it->size = pck_size; - it->pck = malloc(pck_size); + it->pck = gf_malloc(pck_size); memcpy(it->pck, pck, pck_size); /*reset timeout*/ po->LastTime = 0; @@ -825,8 +863,8 @@ GF_Err gf_rtp_reorderer_add(GF_RTPReorder *po, void *pck, u32 pck_size, u32 pck_ discard: - free(it->pck); - free(it); + gf_free(it->pck); + gf_free(it); GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[rtp] Packet Reorderer: Dropping packet %d", pck_seqnum)); return GF_OK; } @@ -896,6 +934,9 @@ send_it: po->Count -= 1; //release the item ret = t->pck; - free(t); + gf_free(t); return ret; } + +#endif /*GPAC_DISABLE_STREAMING*/ + diff --git a/src/ietf/rtp_depacketizer.c b/src/ietf/rtp_depacketizer.c index d18ffc6..1ee91b5 100644 --- a/src/ietf/rtp_depacketizer.c +++ b/src/ietf/rtp_depacketizer.c @@ -23,6 +23,9 @@ */ #include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/esi.h> #include <gpac/base_coding.h> #include <gpac/constants.h> @@ -33,7 +36,8 @@ static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size) { - u32 aux_size, au_size, first_idx, au_hdr_size, pay_start, num_au; + u32 aux_size, first_idx, au_hdr_size, num_au; + u64 pay_start, au_size; s32 au_idx; GF_BitStream *hdr_bs, *aux_bs; @@ -57,7 +61,7 @@ static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char gf_bs_read_int(aux_bs, aux_size); gf_bs_align(aux_bs); } - pay_start = (u32) gf_bs_get_position(aux_bs); + pay_start = gf_bs_get_position(aux_bs); gf_bs_del(aux_bs); first_idx = 0; @@ -133,7 +137,7 @@ static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char au_idx = first_idx = gf_bs_read_int(hdr_bs, rtp->sl_map.IndexLength); au_hdr_size -= rtp->sl_map.IndexLength; } else { - au_idx += 1 + (s32) gf_bs_read_int(hdr_bs, rtp->sl_map.IndexDeltaLength); + au_idx += 1 + (u32) gf_bs_read_int(hdr_bs, rtp->sl_map.IndexDeltaLength); au_hdr_size -= rtp->sl_map.IndexDeltaLength; } /*CTS flag*/ @@ -151,7 +155,7 @@ static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char /*CTS in-band*/ if (rtp->sl_hdr.compositionTimeStampFlag) { - rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp + (s32) gf_bs_read_int(hdr_bs, rtp->sl_map.CTSDeltaLength); + rtp->sl_hdr.compositionTimeStamp = hdr->TimeStamp + (u32) gf_bs_read_int(hdr_bs, rtp->sl_map.CTSDeltaLength); au_hdr_size -= rtp->sl_map.CTSDeltaLength; } /*DTS flag is always present (needed for reconstruction of TSs in case of packet loss)*/ @@ -179,8 +183,6 @@ static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char if (rtp->sl_map.StreamStateIndication) { rtp->sl_hdr.AU_sequenceNumber = gf_bs_read_int(hdr_bs, rtp->sl_map.StreamStateIndication); au_hdr_size -= rtp->sl_map.StreamStateIndication; - } else { - rtp->sl_hdr.AU_sequenceNumber = au_idx; } } /*no header present, update CTS/DTS - note we're sure there's no interleaving*/ @@ -213,7 +215,7 @@ static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char rtp->sl_hdr.randomAccessPointFlag = is_rap ? 1 : 0; } - rtp->on_sl_packet(rtp->udta, payload + pay_start, au_size, &rtp->sl_hdr, GF_OK); + rtp->on_sl_packet(rtp->udta, payload + pay_start, (u32) au_size, &rtp->sl_hdr, GF_OK); rtp->sl_hdr.compositionTimeStampFlag = 0; @@ -224,7 +226,7 @@ static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char if (pay_start >= size) break; num_au ++; } - assert(!au_hdr_size); +// assert(!au_hdr_size); if (hdr->Marker) rtp->flags |= GF_RTP_NEW_AU; @@ -234,6 +236,7 @@ static void gf_rtp_parse_mpeg4(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char gf_bs_del(hdr_bs); } +#ifndef GPAC_DISABLE_AV_PARSERS static void gf_rtp_parse_mpeg12_audio(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size) { @@ -294,6 +297,8 @@ static void gf_rtp_parse_mpeg12_audio(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr rtp->flags |= GF_RTP_NEW_AU; } +#endif + static void gf_rtp_parse_mpeg12_video(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size) { u8 pic_type; @@ -376,7 +381,8 @@ static void gf_rtp_parse_h263(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char * { GF_BitStream *bs; Bool P_bit, V_bit; - u32 plen, plen_bits, offset; + u32 plen, plen_bits; + u64 offset; char blank[2]; bs = gf_bs_new(payload, size, GF_BITSTREAM_READ); @@ -395,7 +401,7 @@ static void gf_rtp_parse_h263(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char * if (plen) { gf_bs_skip_bytes(bs, plen); } - offset = (u32) gf_bs_get_position(bs); + offset = gf_bs_get_position(bs); gf_bs_del(bs); blank[0] = blank[1] = 0; @@ -419,11 +425,11 @@ static void gf_rtp_parse_h263(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char * /*if M bit set, end of frame*/ rtp->sl_hdr.accessUnitEndFlag = hdr->Marker; - rtp->on_sl_packet(rtp->udta, payload + offset, size - offset, &rtp->sl_hdr, GF_OK); + rtp->on_sl_packet(rtp->udta, payload + offset, (u32) (size - offset), &rtp->sl_hdr, GF_OK); } else { /*middle/end of frames - if M bit set, end of frame*/ rtp->sl_hdr.accessUnitEndFlag = hdr->Marker; - rtp->on_sl_packet(rtp->udta, payload + offset, size - offset, &rtp->sl_hdr, GF_OK); + rtp->on_sl_packet(rtp->udta, payload + offset, (u32) (size - offset), &rtp->sl_hdr, GF_OK); } } @@ -453,12 +459,12 @@ static void gf_rtp_ttxt_flush(GF_RTPDepacketizer *rtp, u32 ts) gf_bs_del(bs); rtp->on_sl_packet(rtp->udta, data, data_size, &rtp->sl_hdr, GF_OK); - free(data); + gf_free(data); rtp->sl_hdr.accessUnitStartFlag = 0; rtp->sl_hdr.accessUnitEndFlag = 1; gf_bs_get_content(rtp->inter_bs, &data, &data_size); rtp->on_sl_packet(rtp->udta, data, data_size, &rtp->sl_hdr, GF_OK); - free(data); + gf_free(data); gf_bs_del(rtp->inter_bs); rtp->inter_bs = NULL; @@ -468,15 +474,16 @@ static void gf_rtp_ttxt_flush(GF_RTPDepacketizer *rtp, u32 ts) static void gf_rtp_parse_ttxt(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size) { Bool is_utf_16; - u32 type, ttu_len, pay_start, duration, ts, sidx, txt_size; + u32 type, ttu_len, duration, ts, sidx, txt_size; u32 nb_frag, cur_frag; + u64 pay_start; GF_BitStream *bs; ts = hdr->TimeStamp; bs = gf_bs_new(payload, size, GF_BITSTREAM_READ); while (gf_bs_available(bs)) { - pay_start = (u32) gf_bs_get_position(bs); + pay_start = gf_bs_get_position(bs); is_utf_16 = gf_bs_read_int(bs, 1); gf_bs_read_int(bs, 4); type = gf_bs_read_int(bs, 3); @@ -543,13 +550,17 @@ static void gf_rtp_parse_ttxt(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char * rtp->sl_hdr.au_duration = duration; /*done*/ if (hdr->Marker) { - rtp->txt_len = (u32) gf_bs_get_position(rtp->inter_bs); + assert(gf_bs_get_position(rtp->inter_bs) < 1<<7); + rtp->txt_len = (u8) gf_bs_get_position(rtp->inter_bs); gf_rtp_ttxt_flush(rtp, ts); } } else if ((type==3) || (type==4)) { if (!rtp->inter_bs) rtp->inter_bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*first modifier, store effective written text*/ - if (type==3) rtp->txt_len = (u32) gf_bs_get_position(rtp->inter_bs); + if (type==3) { + assert(gf_bs_get_position(rtp->inter_bs) < 1<<7); + rtp->txt_len = (u8) gf_bs_get_position(rtp->inter_bs); + } if (ttu_len<6) break; nb_frag = gf_bs_read_int(bs, 4); @@ -594,7 +605,7 @@ static void gf_rtp_h264_flush(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, Bool m rtp->on_sl_packet(rtp->udta, data, data_size, &rtp->sl_hdr, GF_OK); rtp->sl_hdr.accessUnitStartFlag = 0; rtp->sl_hdr.randomAccessPointFlag = 0; - free(data); + gf_free(data); } void gf_rtp_parse_h264(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size) @@ -799,13 +810,14 @@ static void gf_rtp_parse_3gpp_dims(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, c rtp->sl_hdr.accessUnitEndFlag = hdr->Marker; rtp->on_sl_packet(rtp->udta, data, dsize, &rtp->sl_hdr, GF_OK); - free(data); + gf_free(data); return; } } } +#ifndef GPAC_DISABLE_AV_PARSERS static void gf_rtp_parse_ac3(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *payload, u32 size) { @@ -848,6 +860,7 @@ static void gf_rtp_parse_ac3(GF_RTPDepacketizer *rtp, GF_RTPHeader *hdr, char *p rtp->on_sl_packet(rtp->udta, payload, size, &rtp->sl_hdr, GF_OK); } } +#endif /*GPAC_DISABLE_AV_PARSERS*/ static u32 gf_rtp_get_payload_type(GF_RTPMap *map, GF_SDPMedia *media) { @@ -858,8 +871,8 @@ static u32 gf_rtp_get_payload_type(GF_RTPMap *map, GF_SDPMedia *media) else if (!stricmp(map->payload_name, "enc-mpeg4-generic")) return GF_RTP_PAYT_MPEG4; /*optibase mm400 card hack*/ else if (!stricmp(map->payload_name, "enc-generic-mp4") ) { - free(map->payload_name); - map->payload_name = strdup("enc-mpeg4-generic"); + gf_free(map->payload_name); + map->payload_name = gf_strdup("enc-mpeg4-generic"); return GF_RTP_PAYT_MPEG4; } @@ -921,7 +934,7 @@ static GF_Err payt_set_param(GF_RTPDepacketizer *rtp, char *param_name, char *pa sscanf(valS, "%x", &val); gf_bs_write_u8(bs, val); } - if (rtp->sl_map.config) free(rtp->sl_map.config); + if (rtp->sl_map.config) gf_free(rtp->sl_map.config); rtp->sl_map.config = NULL; gf_bs_get_content(bs, &rtp->sl_map.config, &rtp->sl_map.configSize); gf_bs_del(bs); @@ -947,12 +960,12 @@ static GF_Err payt_set_param(GF_RTPDepacketizer *rtp, char *param_name, char *pa /*in case no IOD and no streamType/OTI in the file*/ if (!stricmp(param_val, "AAC-hbr") || !stricmp(param_val, "AAC-lbr") || !stricmp(param_val, "CELP-vbr") || !stricmp(param_val, "CELP-cbr")) { rtp->sl_map.StreamType = GF_STREAM_AUDIO; - rtp->sl_map.ObjectTypeIndication = 0x40; + rtp->sl_map.ObjectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; } /*in case no IOD and no streamType/OTI in the file*/ else if (!stricmp(param_val, "avc-video") ) { rtp->sl_map.StreamType = GF_STREAM_VISUAL; - rtp->sl_map.ObjectTypeIndication = 0x21; + rtp->sl_map.ObjectTypeIndication = GPAC_OTI_VIDEO_AVC; } } @@ -969,9 +982,10 @@ static GF_Err payt_set_param(GF_RTPDepacketizer *rtp, char *param_name, char *pa else if (!stricmp(param_name, "packetization-mode")) rtp->h264_pck_mode = 1; /*AMR config*/ - else if (!stricmp(param_name, "octet-align")) - rtp->flags |= GF_RTP_AMR_ALIGN; - /*ISMACryp config*/ + else if (!stricmp(param_name, "octet-align")) { + if (!stricmp(param_val, "1")) + rtp->flags |= GF_RTP_AMR_ALIGN; + } /*ISMACryp config*/ else if (!stricmp(param_name, "ISMACrypCryptoSuite")) { if (!stricmp(param_val, "AES_CTR_128")) rtp->isma_scheme = GF_4CC('i','A','E','C'); @@ -997,7 +1011,7 @@ static GF_Err payt_set_param(GF_RTPDepacketizer *rtp, char *param_name, char *pa rtp->flags &= ~GF_RTP_ISMA_HAS_KEY_IDX; } else if (!stricmp(param_name, "ISMACrypKey")) - rtp->key = strdup(param_val); + rtp->key = gf_strdup(param_val); return GF_OK; } @@ -1025,6 +1039,7 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM } switch (rtp->payt) { +#ifndef GPAC_DISABLE_AV_PARSERS case GF_RTP_PAYT_LATM: { u32 AudioMuxVersion, AllStreamsSameTime, numSubFrames, numPrograms, numLayers; @@ -1050,7 +1065,11 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM cfg.base_sr = GF_M4ASampleRates[cfg.base_sr_index]; } cfg.nb_chan = gf_bs_read_int(bs, 4); - if (cfg.base_object_type==5) { + if (cfg.base_object_type==5 || cfg.base_object_type==29) { + if (cfg.base_object_type==29) { + cfg.has_ps = 1; + cfg.nb_chan = 1; + } cfg.has_sbr = 1; cfg.sbr_sr_index = gf_bs_read_int(bs, 4); if (cfg.sbr_sr_index == 0x0F) { @@ -1061,7 +1080,7 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM cfg.sbr_object_type = gf_bs_read_int(bs, 5); } gf_bs_del(bs); - free(rtp->sl_map.config); + gf_free(rtp->sl_map.config); bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*write as regular AAC*/ gf_bs_write_int(bs, cfg.base_object_type, 5); @@ -1071,12 +1090,13 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM gf_bs_get_content(bs, &rtp->sl_map.config, &rtp->sl_map.configSize); gf_bs_del(bs); rtp->sl_map.StreamType = GF_STREAM_AUDIO; - rtp->sl_map.ObjectTypeIndication = 0x40; + rtp->sl_map.ObjectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; /*assign depacketizer*/ rtp->depacketize = gf_rtp_parse_latm; } break; +#endif case GF_RTP_PAYT_MPEG4: /*mark if AU header is present*/ rtp->sl_map.auh_first_min_len = 0; @@ -1098,31 +1118,55 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM /*RFC3016 flags*/ if (!stricmp(map->payload_name, "MP4V-ES")) { rtp->sl_map.StreamType = GF_STREAM_VISUAL; - rtp->sl_map.ObjectTypeIndication = 0x20; + rtp->sl_map.ObjectTypeIndication = GPAC_OTI_VIDEO_MPEG4_PART2; + } + else if (!strnicmp(map->payload_name, "AAC", 3)) { + rtp->sl_map.StreamType = GF_STREAM_AUDIO; + rtp->sl_map.ObjectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; } else if (!stricmp(map->payload_name, "MP4A-LATM")) { rtp->sl_map.StreamType = GF_STREAM_AUDIO; - rtp->sl_map.ObjectTypeIndication = 0x40; + rtp->sl_map.ObjectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; } /*MPEG-4 video, check RAPs if not indicated*/ - if ((rtp->sl_map.StreamType == GF_STREAM_VISUAL) && (rtp->sl_map.ObjectTypeIndication == 0x20) && !rtp->sl_map.RandomAccessIndication) { + if ((rtp->sl_map.StreamType == GF_STREAM_VISUAL) && (rtp->sl_map.ObjectTypeIndication == GPAC_OTI_VIDEO_MPEG4_PART2) && !rtp->sl_map.RandomAccessIndication) { rtp->flags |= GF_RTP_M4V_CHECK_RAP; } +#ifndef GPAC_DISABLE_AV_PARSERS + if ((rtp->sl_map.ObjectTypeIndication == GPAC_OTI_AUDIO_AAC_MPEG4) && !rtp->sl_map.config) { + GF_M4ADecSpecInfo cfg; + GF_RTPMap*map = (GF_RTPMap*)gf_list_get(media->RTPMaps, 0); + + memset(&cfg, 0, sizeof(GF_M4ADecSpecInfo)); + cfg.audioPL = rtp->sl_map.PL_ID; + cfg.nb_chan = map->AudioChannels; + cfg.nb_chan = 1; + cfg.base_sr = map->ClockRate/2; + cfg.sbr_sr = map->ClockRate; + cfg.base_object_type = GF_M4A_AAC_LC; + cfg.base_object_type = 5; + cfg.sbr_object_type = GF_M4A_AAC_MAIN; + gf_m4a_write_config(&cfg, &rtp->sl_map.config, &rtp->sl_map.configSize); + } +#endif /*assign depacketizer*/ rtp->depacketize = gf_rtp_parse_mpeg4; break; +#ifndef GPAC_DISABLE_AV_PARSERS case GF_RTP_PAYT_MPEG12_AUDIO: rtp->sl_map.StreamType = GF_STREAM_AUDIO; - rtp->sl_map.ObjectTypeIndication = 0x69; + rtp->sl_map.ObjectTypeIndication = GPAC_OTI_AUDIO_MPEG2_PART3; /*assign depacketizer*/ rtp->depacketize = gf_rtp_parse_mpeg12_audio; break; +#endif /*GPAC_DISABLE_AV_PARSERS*/ + case GF_RTP_PAYT_MPEG12_VIDEO: /*we signal RAPs*/ rtp->sl_map.RandomAccessIndication = 1; rtp->sl_map.StreamType = GF_STREAM_VISUAL; /*FIXME: how to differentiate MPEG1 from MPEG2 video before any frame is received??*/ - rtp->sl_map.ObjectTypeIndication = 0x6A; + rtp->sl_map.ObjectTypeIndication = GPAC_OTI_VIDEO_MPEG1; /*assign depacketizer*/ rtp->depacketize = gf_rtp_parse_mpeg12_video; break; @@ -1265,6 +1309,7 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM rtp->depacketize = gf_rtp_parse_ttxt; } break; +#ifndef GPAC_DISABLE_AV_PARSERS case GF_RTP_PAYT_H264_AVC: { GF_SDP_FMTP *fmtp; @@ -1275,7 +1320,7 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM avcc->configurationVersion = 1; avcc->nal_unit_size = 4; rtp->sl_map.StreamType = 4; - rtp->sl_map.ObjectTypeIndication = 0x21; + rtp->sl_map.ObjectTypeIndication = GPAC_OTI_VIDEO_AVC; /*we will signal RAPs*/ rtp->sl_map.RandomAccessIndication = 1; /*rewrite sps and pps*/ @@ -1297,15 +1342,15 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM if (sep) sep[0] = 0; b64size = strlen(nal_ptr); - b64_d = (char*)malloc(sizeof(char)*b64size); + b64_d = (char*)gf_malloc(sizeof(char)*b64size); ret = gf_base64_decode(nal_ptr, b64size, b64_d, b64size); b64_d[ret] = 0; nalt = b64_d[0] & 0x1F; if (/*SPS*/(nalt==0x07) || /*PPS*/(nalt==0x08)) { - GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)malloc(sizeof(GF_AVCConfigSlot)); + GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_malloc(sizeof(GF_AVCConfigSlot)); sl->size = ret; - sl->data = (char*)malloc(sizeof(char)*sl->size); + sl->data = (char*)gf_malloc(sizeof(char)*sl->size); memcpy(sl->data, b64_d, sizeof(char)*sl->size); if (nalt==0x07) { gf_list_add(avcc->sequenceParameterSets, sl); @@ -1313,7 +1358,7 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM gf_list_add(avcc->pictureParameterSets, sl); } } - free(b64_d); + gf_free(b64_d); if (sep) { sep[0] = ','; @@ -1330,6 +1375,8 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM /*assign depacketizer*/ rtp->depacketize = gf_rtp_parse_h264; break; +#endif /*GPAC_DISABLE_AV_PARSERS*/ + /*todo - rewrite DIMS config*/ case GF_RTP_PAYT_3GPP_DIMS: rtp->sl_map.StreamType = GF_STREAM_SCENE; @@ -1342,6 +1389,7 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM /*assign depacketizer*/ rtp->depacketize = gf_rtp_parse_3gpp_dims; break; +#ifndef GPAC_DISABLE_AV_PARSERS case GF_RTP_PAYT_AC3: rtp->sl_map.StreamType = GF_STREAM_AUDIO; rtp->sl_map.ObjectTypeIndication = 0xA5; @@ -1349,6 +1397,7 @@ static GF_Err gf_rtp_payt_setup(GF_RTPDepacketizer *rtp, GF_RTPMap *map, GF_SDPM /*assign depacketizer*/ rtp->depacketize = gf_rtp_parse_ac3; break; +#endif /*GPAC_DISABLE_AV_PARSERS*/ default: return GF_NOT_SUPPORTED; } @@ -1377,7 +1426,7 @@ GF_RTPDepacketizer *gf_rtp_depacketizer_new(GF_SDPMedia *media, void (*sl_packet e = gf_rtp_payt_setup(tmp, map, media); if (e) { - free(tmp); + gf_free(tmp); return NULL; } assert(tmp->depacketize); @@ -1407,9 +1456,9 @@ void gf_rtp_depacketizer_del(GF_RTPDepacketizer *rtp) { if (rtp) { gf_rtp_depacketizer_reset(rtp, 0); - if (rtp->sl_map.config) free(rtp->sl_map.config); - if (rtp->key) free(rtp->key); - free(rtp); + if (rtp->sl_map.config) gf_free(rtp->sl_map.config); + if (rtp->key) gf_free(rtp->key); + gf_free(rtp); } } @@ -1434,8 +1483,10 @@ void gf_rtp_depacketizer_get_slconfig(GF_RTPDepacketizer *rtp, GF_SLConfig *slc) } else { slc->CUDuration = slc->AUDuration = rtp->sl_hdr.au_duration; } + /*AUSeqNum is only signaled if streamState is used (eg for carrouselling); otherwise we ignore it*/ slc->AUSeqNumLength = rtp->sl_map.StreamStateIndication; + /*RTP SN is on 16 bits*/ slc->packetSeqNumLength = 0; /*RTP TS is on 32 bits*/ @@ -1446,16 +1497,22 @@ void gf_rtp_depacketizer_get_slconfig(GF_RTPDepacketizer *rtp, GF_SLConfig *slc) /*we override these flags because we emulate the flags through the marker bit */ slc->useAccessUnitEndFlag = slc->useAccessUnitStartFlag = 1; slc->useRandomAccessPointFlag = rtp->sl_map.RandomAccessIndication; - /*by default all packets are RAP if not signaled. This is true for audio - shoud NEVER be seen with systems streams and is overriden for video (cf below)*/ - slc->hasRandomAccessUnitsOnlyFlag = rtp->sl_map.RandomAccessIndication ? 0 : 1; /*checking RAP for video*/ if (rtp->flags & GF_RTP_M4V_CHECK_RAP) { slc->useRandomAccessPointFlag = 1; slc->hasRandomAccessUnitsOnlyFlag = 0; } - /*should work for simple carsousel without streamState indicated*/ - slc->AUSeqNumLength = rtp->sl_map.IndexLength; + /*try to signal caroussel if not set in StreamState*/ + if (!slc->AUSeqNumLength && rtp->sl_map.RandomAccessIndication) { + switch (rtp->sl_map.StreamType) { + case GF_STREAM_OD: + case GF_STREAM_SCENE: + slc->AUSeqNumLength = rtp->sl_map.IndexLength; + break; + } + } } + +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/ietf/rtp_packetizer.c b/src/ietf/rtp_packetizer.c index 466f5be..80940da 100644 --- a/src/ietf/rtp_packetizer.c +++ b/src/ietf/rtp_packetizer.c @@ -23,6 +23,9 @@ */ #include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/constants.h> #include <gpac/math.h> @@ -42,7 +45,7 @@ GP_RTPPacketizer *gf_rtp_builder_new(u32 rtp_payt, GF_SLConfig *slc, u32 flags, { GP_RTPPacketizer *tmp; if (!rtp_payt || !cbk_obj | !OnPacketDone) return NULL; - + GF_SAFEALLOC(tmp, GP_RTPPacketizer); if (!tmp) return NULL; @@ -76,7 +79,7 @@ void gf_rtp_builder_del(GP_RTPPacketizer *builder) if (builder->payload) gf_bs_del(builder->payload); if (builder->pck_hdr) gf_bs_del(builder->pck_hdr); - free(builder); + gf_free(builder); } GF_EXPORT @@ -87,8 +90,10 @@ GF_Err gf_rtp_builder_process(GP_RTPPacketizer *builder, char *data, u32 data_si switch (builder->rtp_payt) { case GF_RTP_PAYT_MPEG4: return gp_rtp_builder_do_mpeg4(builder, data, data_size, IsAUEnd, FullAUSize); +#ifndef GPAC_DISABLE_AV_PARSERS case GF_RTP_PAYT_MPEG12_VIDEO: return gp_rtp_builder_do_mpeg12_video(builder, data, data_size, IsAUEnd, FullAUSize); +#endif case GF_RTP_PAYT_MPEG12_AUDIO: return gp_rtp_builder_do_mpeg12_audio(builder, data, data_size, IsAUEnd, FullAUSize); case GF_RTP_PAYT_H263: @@ -111,7 +116,7 @@ GF_Err gf_rtp_builder_process(GP_RTPPacketizer *builder, char *data, u32 data_si case GF_RTP_PAYT_AC3: return gp_rtp_builder_do_ac3(builder, data, data_size, IsAUEnd, FullAUSize); default: - return GF_BAD_PARAM; + return GF_NOT_SUPPORTED; } } @@ -195,9 +200,15 @@ void gf_rtp_builder_init(GP_RTPPacketizer *builder, u8 PayloadType, u32 PathMTU, default: /*remove all MPEG-4 and ISMA flags */ builder->flags &= 0x07; - /*disable aggregation for visual streams*/ - if (StreamType==GF_STREAM_VISUAL) builder->flags &= ~GP_RTP_PCK_USE_MULTI; - else if (avgSize && (PathMTU <= avgSize) ) builder->flags &= ~GP_RTP_PCK_USE_MULTI; + /*disable aggregation for visual streams, except for AVC where STAP/MTAP can be used*/ + if (StreamType==GF_STREAM_VISUAL) { + if (OTI != GPAC_OTI_VIDEO_AVC) { + builder->flags &= ~GP_RTP_PCK_USE_MULTI; + } + } + else if (avgSize && (PathMTU <= avgSize) ) { + builder->flags &= ~GP_RTP_PCK_USE_MULTI; + } return; } @@ -211,7 +222,8 @@ void gf_rtp_builder_init(GP_RTPPacketizer *builder, u8 PayloadType, u32 PathMTU, /*mode setup*/ if (!strnicmp(builder->slMap.mode, "AAC", 3)) { builder->flags = GP_RTP_PCK_USE_MULTI | GP_RTP_PCK_SIGNAL_SIZE | GP_RTP_PCK_SIGNAL_AU_IDX | ismacrypt_flags; - if (builder->flags & GP_RTP_PCK_USE_INTERLEAVING) builder->slMap.ConstantDuration = avgTS; + /*if (builder->flags & GP_RTP_PCK_USE_INTERLEAVING) */ + builder->slMap.ConstantDuration = avgTS; /*AAC LBR*/ if (maxSize < 63) { @@ -241,7 +253,7 @@ void gf_rtp_builder_init(GP_RTPPacketizer *builder, u8 PayloadType, u32 PathMTU, strcpy(builder->slMap.mode, "CELP-vbr"); builder->slMap.IndexLength = builder->slMap.IndexDeltaLength = 2; builder->slMap.SizeLength = 6; - if (builder->flags & GP_RTP_PCK_USE_INTERLEAVING) builder->slMap.ConstantDuration = avgTS; + /*if (builder->flags & GP_RTP_PCK_USE_INTERLEAVING) */builder->slMap.ConstantDuration = avgTS; builder->flags = GP_RTP_PCK_USE_MULTI | GP_RTP_PCK_SIGNAL_SIZE | GP_RTP_PCK_SIGNAL_AU_IDX | ismacrypt_flags; } goto check_header; @@ -292,7 +304,12 @@ void gf_rtp_builder_init(GP_RTPPacketizer *builder, u8 PayloadType, u32 PathMTU, } else { builder->slMap.RandomAccessIndication = 0; } - /*TODO: stream state*/ + + /*stream state*/ + if (builder->flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) { + if (!builder->sl_config.AUSeqNumLength) builder->sl_config.AUSeqNumLength = 4; + builder->slMap.StreamStateIndication = builder->sl_config.AUSeqNumLength; + } goto check_header; } @@ -337,6 +354,10 @@ void gf_rtp_builder_init(GP_RTPPacketizer *builder, u8 PayloadType, u32 PathMTU, /*and k-1 AUs in Delta*/ builder->slMap.IndexDeltaLength = (builder->flags & GP_RTP_PCK_USE_INTERLEAVING) ? gf_get_bit_size(k-1) : 0; } + else if (builder->flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) { + if (!builder->sl_config.AUSeqNumLength) builder->sl_config.AUSeqNumLength = 4; + builder->slMap.StreamStateIndication = builder->sl_config.AUSeqNumLength; + } /*RAP*/ if (builder->sl_config.useRandomAccessPointFlag && (builder->flags & GP_RTP_PCK_SIGNAL_RAP)) { @@ -352,7 +373,7 @@ check_header: builder->slMap.IV_delta_length = gf_get_bit_size(maxSize); } /*ISMACryp video mode*/ - if ((builder->slMap.StreamType==GF_STREAM_VISUAL) && (builder->slMap.ObjectTypeIndication==0x20) + if ((builder->slMap.StreamType==GF_STREAM_VISUAL) && (builder->slMap.ObjectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) && (builder->flags & GP_RTP_PCK_SIGNAL_RAP) && builder->slMap.IV_length && !(builder->flags & GP_RTP_PCK_SIGNAL_AU_IDX) && !(builder->flags & GP_RTP_PCK_SIGNAL_SIZE) /*shall have SignalTS*/ @@ -361,7 +382,7 @@ check_header: strcpy(builder->slMap.mode, "mpeg4-video"); } /*ISMACryp AVC video mode*/ - else if ((builder->slMap.StreamType==GF_STREAM_VISUAL) && (builder->slMap.ObjectTypeIndication==0x21) + else if ((builder->slMap.StreamType==GF_STREAM_VISUAL) && (builder->slMap.ObjectTypeIndication==GPAC_OTI_VIDEO_AVC) && (builder->flags & GP_RTP_PCK_SIGNAL_RAP) && builder->slMap.IV_length && !(builder->flags & GP_RTP_PCK_SIGNAL_AU_IDX) && !(builder->flags & GP_RTP_PCK_SIGNAL_SIZE) /*shall have SignalTS*/ @@ -392,7 +413,7 @@ void gp_rtp_builder_set_cryp_info(GP_RTPPacketizer *builder, u64 IV, char *key_i if (builder->key_indicator) { /*force flush if no provision for keyIndicator per AU*/ builder->force_flush = (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU) ? 0 : 1; - free(builder->key_indicator); + gf_free(builder->key_indicator); builder->key_indicator = NULL; } } else if (!builder->key_indicator @@ -402,7 +423,7 @@ void gp_rtp_builder_set_cryp_info(GP_RTPPacketizer *builder, u64 IV, char *key_i /*force flush if no provision for keyIndicator per AU*/ builder->force_flush = (builder->flags & GP_RTP_PCK_KEY_IDX_PER_AU) ? 0 : 1; - if (!builder->key_indicator) builder->key_indicator = (char *) malloc(sizeof(char)*builder->slMap.KI_length); + if (!builder->key_indicator) builder->key_indicator = (char *) gf_malloc(sizeof(char)*builder->slMap.KI_length); memcpy(builder->key_indicator, key_indicator, sizeof(char)*builder->slMap.KI_length); } if (builder->IV != IV) { @@ -422,7 +443,7 @@ Bool gf_rtp_builder_get_payload_name(GP_RTPPacketizer *rtpb, char *szPayloadName switch (rtpb->rtp_payt) { case GF_RTP_PAYT_MPEG4: - if ((rtpb->slMap.StreamType==GF_STREAM_VISUAL) && (rtpb->slMap.ObjectTypeIndication==0x20)) { + if ((rtpb->slMap.StreamType==GF_STREAM_VISUAL) && (rtpb->slMap.ObjectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2)) { strcpy(szMediaName, "video"); /*ISMACryp video*/ if ( (flags & GP_RTP_PCK_SIGNAL_RAP) && rtpb->slMap.IV_length @@ -573,3 +594,4 @@ GF_Err gf_rtp_builder_format_sdp(GP_RTPPacketizer *builder, char *payload_name, return GF_OK; } +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/ietf/rtp_pck_3gpp.c b/src/ietf/rtp_pck_3gpp.c index 554048b..d7eb761 100644 --- a/src/ietf/rtp_pck_3gpp.c +++ b/src/ietf/rtp_pck_3gpp.c @@ -23,6 +23,9 @@ */ #include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/constants.h> static void rtp_amr_flush(GP_RTPPacketizer *builder) @@ -36,7 +39,7 @@ static void rtp_amr_flush(GP_RTPPacketizer *builder) /*overwrite last frame F bit*/ hdr[builder->last_au_sn] &= 0x7F; builder->OnData(builder->cbk_obj, hdr, hdr_size, 1); - free(hdr); + gf_free(hdr); builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; builder->last_au_sn = 0; @@ -202,7 +205,7 @@ static void rtp_evrc_smv_flush(GP_RTPPacketizer *builder) hdr[0] = 0; hdr[1] = builder->last_au_sn-1;/*MMM + frameCount-1*/ builder->OnData(builder->cbk_obj, hdr, hdr_size, 1); - free(hdr); + gf_free(hdr); } builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); builder->bytesInPacket = 0; @@ -390,7 +393,7 @@ GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, char *data, u32 data_si gf_bs_del(bs); builder->OnData(builder->cbk_obj, (char *) hdr, hdr_size, 0); builder->bytesInPacket += hdr_size; - free(hdr); + gf_free(hdr); if (txt_size) { if (builder->OnDataReference) { @@ -458,7 +461,7 @@ GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, char *data, u32 data_si gf_bs_del(bs); builder->OnData(builder->cbk_obj, (char *) hdr, hdr_size, 0); builder->bytesInPacket += hdr_size; - free(hdr); + gf_free(hdr); if (builder->OnDataReference) { builder->OnDataReference(builder->cbk_obj, size, pay_start + txt_done); @@ -512,7 +515,7 @@ GF_Err gp_rtp_builder_do_tx3g(GP_RTPPacketizer *builder, char *data, u32 data_si gf_bs_del(bs); builder->OnData(builder->cbk_obj, (char *) hdr, hdr_size, 0); builder->bytesInPacket += hdr_size; - free(hdr); + gf_free(hdr); if (builder->OnDataReference) { builder->OnDataReference(builder->cbk_obj, size, pay_start + txt_done); @@ -768,3 +771,5 @@ GF_Err gp_rtp_builder_do_ac3(GP_RTPPacketizer *builder, char *data, u32 data_siz return GF_OK; } +#endif /*GPAC_DISABLE_STREAMING*/ + diff --git a/src/ietf/rtp_pck_mpeg12.c b/src/ietf/rtp_pck_mpeg12.c index a6d21ef..660133c 100644 --- a/src/ietf/rtp_pck_mpeg12.c +++ b/src/ietf/rtp_pck_mpeg12.c @@ -23,7 +23,11 @@ */ #include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/constants.h> +#include <gpac/avparse.h> static void mpa12_do_flush(GP_RTPPacketizer *builder, Bool start_new) { @@ -33,12 +37,12 @@ static void mpa12_do_flush(GP_RTPPacketizer *builder, Bool start_new) if (builder->pck_hdr) { gf_bs_get_content(builder->pck_hdr, &tmp, &tmp_size); builder->OnData(builder->cbk_obj, tmp, tmp_size, 1); - free(tmp); + gf_free(tmp); if (gf_bs_get_size(builder->payload)) { gf_bs_get_content(builder->payload, &tmp, &tmp_size); builder->OnData(builder->cbk_obj, tmp, tmp_size, 0); - free(tmp); + gf_free(tmp); } builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); @@ -104,8 +108,7 @@ GF_Err gp_rtp_builder_do_mpeg12_audio(GP_RTPPacketizer *builder, char *data, u32 return GF_OK; } -s32 MPEG12_FindNextSliceStart(unsigned char *pbuffer, u32 startoffset, u32 buflen, u32 *slice_offset); -s32 MPEG12_FindNextStartCode(unsigned char *pbuffer, u32 buflen, u32 *optr, u32 *scode); +#ifndef GPAC_DISABLE_AV_PARSERS #define MPEG12_PICTURE_START_CODE 0x00000100 #define MPEG12_SEQUENCE_START_CODE 0x000001b3 @@ -126,7 +129,7 @@ GF_Err gp_rtp_builder_do_mpeg12_video(GP_RTPPacketizer *builder, char *data, u32 while (1) { u32 oldoffset; oldoffset = offset; - if (MPEG12_FindNextStartCode((unsigned char *) data + offset, data_size - offset, &offset, &startcode) < 0) + if (gf_mv12_next_start_code((unsigned char *) data + offset, data_size - offset, &offset, &startcode) < 0) break; offset += oldoffset; @@ -161,7 +164,7 @@ GF_Err gp_rtp_builder_do_mpeg12_video(GP_RTPPacketizer *builder, char *data, u32 buffer = data; prev_slice = 0; - start_with_slice = (MPEG12_FindNextSliceStart((unsigned char *)buffer, offset, data_size, &next_slice) >= 0) ? 1 : 0; + start_with_slice = (gf_mv12_next_slice_start((unsigned char *)buffer, offset, data_size, &next_slice) >= 0) ? 1 : 0; offset = 0; slices_done = 0; got_slice = start_with_slice; @@ -182,7 +185,7 @@ GF_Err gp_rtp_builder_do_mpeg12_video(GP_RTPPacketizer *builder, char *data, u32 while (!slices_done && (next_slice <= max_pck_size)) { prev_slice = next_slice; - if (MPEG12_FindNextSliceStart((unsigned char *)buffer, next_slice + 4, data_size, &next_slice) >= 0) { + if (gf_mv12_next_slice_start((unsigned char *)buffer, next_slice + 4, data_size, &next_slice) >= 0) { got_slice = 1; } else { slices_done = 1; @@ -231,3 +234,7 @@ GF_Err gp_rtp_builder_do_mpeg12_video(GP_RTPPacketizer *builder, char *data, u32 } return GF_OK; } + +#endif + +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/ietf/rtp_pck_mpeg4.c b/src/ietf/rtp_pck_mpeg4.c index a5952de..08a3dbd 100644 --- a/src/ietf/rtp_pck_mpeg4.c +++ b/src/ietf/rtp_pck_mpeg4.c @@ -23,6 +23,9 @@ */ #include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/constants.h> //get the size of the RSLH section given the GF_SLHeader and the SLMap @@ -188,6 +191,12 @@ u32 gf_rtp_build_au_hdr_write(GP_RTPPacketizer *builder, u32 PayloadSize, u32 RT gf_bs_write_int(builder->pck_hdr, builder->sl_header.randomAccessPointFlag, 1); nbBits ++; } + /*stream state - write AUSeqNum*/ + if (builder->slMap.StreamStateIndication) { + gf_bs_write_int(builder->pck_hdr, builder->sl_header.AU_sequenceNumber, builder->slMap.StreamStateIndication); + nbBits += builder->slMap.StreamStateIndication; + } + return nbBits; } @@ -196,7 +205,8 @@ GF_Err gp_rtp_builder_do_mpeg4(GP_RTPPacketizer *builder, char *data, u32 data_s { char *sl_buffer, *payl_buffer; u32 sl_buffer_size, payl_buffer_size; - u32 auh_size_tmp, rslh_tmp, bytesLeftInPacket, infoSize, pckSize, pos; + u32 auh_size_tmp, rslh_tmp, bytesLeftInPacket, infoSize, pckSize; + u64 pos; u8 flush_pck, no_split; flush_pck = 0; @@ -349,7 +359,7 @@ flush_packet: } /*rewrite the size header*/ if (builder->has_AU_header) { - pos = (u32) gf_bs_get_position(builder->pck_hdr); + pos = gf_bs_get_position(builder->pck_hdr); gf_bs_seek(builder->pck_hdr, 0); builder->auh_size -= 16; gf_bs_write_int(builder->pck_hdr, builder->auh_size, 16); @@ -375,11 +385,11 @@ flush_packet: /*notify payload*/ if (payl_buffer) { builder->OnData(builder->cbk_obj, payl_buffer, payl_buffer_size, 0); - free(payl_buffer); + gf_free(payl_buffer); } /*flush packet*/ builder->OnPacketDone(builder->cbk_obj, &builder->rtp_header); - free(sl_buffer); + gf_free(sl_buffer); } //packet is done, update AU markers if (IsAUEnd) { @@ -441,7 +451,7 @@ GF_Err gp_rtp_builder_do_avc(GP_RTPPacketizer *builder, char *nalu, u32 nalu_siz /*pb: we don't know if next NALU from this AU will be small enough to fit in the packet, so we always go for stap...*/ if (builder->bytesInPacket+nalu_size<builder->Path_MTU) { - Bool use_stap = 0; + Bool use_stap = 1; /*if this is the AU end and no NALU in packet, go for single mode*/ if (IsAUEnd && !builder->bytesInPacket) use_stap = 0; @@ -585,14 +595,14 @@ GF_Err gp_rtp_builder_do_latm(GP_RTPPacketizer *builder, char *data, u32 data_si /* compute AudioMuxUnit header */ latm_hdr_size = (size / 255) + 1; - latm_hdr = (unsigned char *)malloc( sizeof(char) * latm_hdr_size); + latm_hdr = (unsigned char *)gf_malloc( sizeof(char) * latm_hdr_size); for (i=0; i<latm_hdr_size-1; i++) latm_hdr[i] = 255; latm_hdr[latm_hdr_size-1] = size % 255; /*add LATM header IN ORDER in case we aggregate audioMuxElements in RTP*/ builder->OnData(builder->cbk_obj, (char*) latm_hdr, latm_hdr_size, 0); builder->bytesInPacket += latm_hdr_size; - free(latm_hdr); + gf_free(latm_hdr); /*add payload*/ if (builder->OnDataReference) { @@ -613,3 +623,5 @@ GF_Err gp_rtp_builder_do_latm(GP_RTPPacketizer *builder, char *data, u32 data_si return GF_OK; } + +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/ietf/rtp_streamer.c b/src/ietf/rtp_streamer.c new file mode 100644 index 0000000..2de89cb --- /dev/null +++ b/src/ietf/rtp_streamer.c @@ -0,0 +1,735 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * All rights reserved + * + * This file is part of GPAC / IETF RTP/RTSP/SDP 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/rtp_streamer.h> +#include <gpac/constants.h> +#include <gpac/base_coding.h> +#ifndef GPAC_DISABLE_AV_PARSERS +#include <gpac/avparse.h> +#endif +#include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + +struct __rtp_streamer +{ + GP_RTPPacketizer *packetizer; + GF_RTPChannel *channel; + + /* The current packet being formed */ + char *buffer; + u32 payload_len, buffer_alloc; + + Double ts_scale; +}; + + +/*callbacks from packetizer to channel*/ + +static void rtp_stream_on_new_packet(void *cbk, GF_RTPHeader *header) +{ +} + +static void rtp_stream_on_packet_done(void *cbk, GF_RTPHeader *header) +{ + GF_RTPStreamer *rtp = cbk; + GF_Err e = gf_rtp_send_packet(rtp->channel, header, rtp->buffer+12, rtp->payload_len, 1); + +#ifndef GPAC_DISABLE_LOG + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("Error %s sending RTP packet\n", gf_error_to_string(e))); + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("RTP SN %u - TS %u - M %u - Size %u\n", header->SequenceNumber, header->TimeStamp, header->Marker, rtp->payload_len + 12)); + } +#endif + rtp->payload_len = 0; +} + +static void rtp_stream_on_data(void *cbk, char *data, u32 data_size, Bool is_head) +{ + GF_RTPStreamer *rtp = cbk; + if (!data ||!data_size) return; + + if (rtp->payload_len+data_size+12 > rtp->buffer_alloc) { + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[RTP] Packet size %d bigger than MTU size %d - discarding\n", rtp->payload_len+data_size+12, rtp->buffer_alloc)); + rtp->payload_len += data_size; + return; + } + if (!is_head) { + memcpy(rtp->buffer + rtp->payload_len + 12, data, data_size); + } else { + memmove(rtp->buffer + data_size + 12, rtp->buffer + 12, rtp->payload_len); + memcpy(rtp->buffer + 12, data, data_size); + } + rtp->payload_len += data_size; +} + +static GF_Err rtp_stream_init_channel(GF_RTPStreamer *rtp, u32 path_mtu, const char * dest, int port, int ttl, const char *ifce_addr) +{ + GF_RTSPTransport tr; + GF_Err res; + + rtp->channel = gf_rtp_new(); + gf_rtp_set_ports(rtp->channel, 0); + memset(&tr, 0, sizeof(GF_RTSPTransport)); + + tr.IsUnicast = gf_sk_is_multicast_address(dest) ? 0 : 1; + tr.Profile="RTP/AVP"; + tr.destination = (char *)dest; + tr.source = "0.0.0.0"; + tr.IsRecord = 0; + tr.Append = 0; + tr.SSRC = rand(); + tr.TTL = ttl; + + tr.port_first = port; + tr.port_last = port+1; + if (tr.IsUnicast) { + tr.client_port_first = port; + tr.client_port_last = port+1; + } else { + tr.source = (char *)dest; + } + + res = gf_rtp_setup_transport(rtp->channel, &tr, dest); + if (res !=0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("Cannot setup RTP transport info: %s\n", gf_error_to_string(res) )); + return res; + } + + res = gf_rtp_initialize(rtp->channel, 0, 1, path_mtu, 0, 0, (char *)ifce_addr); + if (res !=0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("Cannot initialize RTP sockets: %s\n", gf_error_to_string(res) )); + return res; + } + return GF_OK; +} + +GF_RTPStreamer *gf_rtp_streamer_new_extended(u32 streamType, u32 oti, u32 timeScale, + const char *ip_dest, u16 port, u32 MTU, u8 TTL, const char *ifce_addr, + u32 flags, char *dsi, u32 dsi_len, + + u32 PayloadType, u32 sample_rate, u32 nb_ch, + Bool is_crypted, u32 IV_length, u32 KI_length, + u32 MinSize, u32 MaxSize, u32 avgTS, u32 maxDTSDelta, u32 const_dur, u32 bandwidth, u32 max_ptime, + u32 au_sn_len + ) +{ + GF_SLConfig slc; + GF_RTPStreamer *stream; + u32 rtp_type, default_rtp_rate; + u8 OfficialPayloadType; + u32 required_rate, force_dts_delta, PL_ID; + char *mpeg4mode; + Bool has_mpeg4_mapping; + GF_Err e; + + if (!timeScale) timeScale = 1000; + + GF_SAFEALLOC(stream, GF_RTPStreamer); + + + /*by default NO PL signaled*/ + PL_ID = 0; + OfficialPayloadType = 0; + force_dts_delta = 0; + mpeg4mode = NULL; + required_rate = 0; + nb_ch = 0; + has_mpeg4_mapping = 1; + rtp_type = 0; + + /*for max compatibility with QT*/ + default_rtp_rate = 90000; + + /*timed-text is a bit special, we support multiple stream descriptions & co*/ + switch (streamType) { + case GF_STREAM_TEXT: + if (oti!=GPAC_OTI_TEXT_MPEG4) + return NULL; + + rtp_type = GF_RTP_PAYT_3GPP_TEXT; + /*fixme - this works cos there's only one PL for text in mpeg4 at the current time*/ + PL_ID = 0x10; + break; + case GF_STREAM_AUDIO: + required_rate = sample_rate; + switch (oti) { + /*AAC*/ + 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: + PL_ID = 0x01; + mpeg4mode = "AAC"; + rtp_type = GF_RTP_PAYT_MPEG4; + required_rate = sample_rate; + +#ifndef GPAC_DISABLE_AV_PARSERS + if (dsi) { + GF_M4ADecSpecInfo a_cfg; + gf_m4a_get_config(dsi, dsi_len, &a_cfg); + nb_ch = a_cfg.nb_chan; + sample_rate = a_cfg.base_sr; + PL_ID = a_cfg.audioPL; + switch (a_cfg.base_object_type) { + case GF_M4A_AAC_MAIN: + case GF_M4A_AAC_LC: + if (flags & GP_RTP_PCK_USE_LATM_AAC) { + rtp_type = GF_RTP_PAYT_LATM; + break; + } + case GF_M4A_AAC_SBR: + case GF_M4A_AAC_PS: + case GF_M4A_AAC_LTP: + case GF_M4A_AAC_SCALABLE: + case GF_M4A_ER_AAC_LC: + case GF_M4A_ER_AAC_LTP: + case GF_M4A_ER_AAC_SCALABLE: + mpeg4mode = "AAC"; + break; + case GF_M4A_CELP: + case GF_M4A_ER_CELP: + mpeg4mode = "CELP"; + break; + } + } +#endif + break; + + /*MPEG1/2 audio*/ + case GPAC_OTI_AUDIO_MPEG2_PART3: + case GPAC_OTI_AUDIO_MPEG1: + if (!is_crypted) { + rtp_type = GF_RTP_PAYT_MPEG12_AUDIO; + /*use official RTP/AVP payload type*/ + OfficialPayloadType = 14; + required_rate = 90000; + } + /*encrypted MP3 must be sent through MPEG-4 generic to signal all ISMACryp stuff*/ + else { + rtp_type = GF_RTP_PAYT_MPEG4; + } + break; + + /*QCELP audio*/ + case GPAC_OTI_AUDIO_13K_VOICE: + rtp_type = GF_RTP_PAYT_QCELP; + OfficialPayloadType = 12; + required_rate = 8000; + nb_ch = 1; + break; + + /*EVRC/SVM audio*/ + case GPAC_OTI_AUDIO_EVRC_VOICE: + case GPAC_OTI_AUDIO_SMV_VOICE: + rtp_type = GF_RTP_PAYT_EVRC_SMV; + required_rate = 8000; + nb_ch = 1; + } + + break; + + case GF_STREAM_VISUAL: + rtp_type = GF_RTP_PAYT_MPEG4; + required_rate = default_rtp_rate; + if (is_crypted) { + /*that's another pain with ISMACryp, even if no B-frames the DTS is signaled...*/ + if (oti==GPAC_OTI_VIDEO_MPEG4_PART2) force_dts_delta = 22; + flags |= GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_SIGNAL_TS; + } + + switch (oti) { + /*ISO/IEC 14496-2*/ + case GPAC_OTI_VIDEO_MPEG4_PART2: + PL_ID = 1; +#ifndef GPAC_DISABLE_AV_PARSERS + if (dsi) { + GF_M4VDecSpecInfo vhdr; + gf_m4v_get_config(dsi, dsi_len, &vhdr); + PL_ID = vhdr.VideoPL; + } +#endif + break; + + /*MPEG1/2 video*/ + case GPAC_OTI_VIDEO_MPEG1: + case GPAC_OTI_VIDEO_MPEG2_SIMPLE: + case GPAC_OTI_VIDEO_MPEG2_MAIN: + case GPAC_OTI_VIDEO_MPEG2_SNR: + case GPAC_OTI_VIDEO_MPEG2_SPATIAL: + case GPAC_OTI_VIDEO_MPEG2_HIGH: + case GPAC_OTI_VIDEO_MPEG2_422: + if (!is_crypted) { + rtp_type = GF_RTP_PAYT_MPEG12_VIDEO; + OfficialPayloadType = 32; + } + break; + /*AVC/H.264*/ + case GPAC_OTI_VIDEO_AVC: + required_rate = 90000; /* "90 kHz clock rate MUST be used"*/ + rtp_type = GF_RTP_PAYT_H264_AVC; + PL_ID = 0x0F; + break; + } + break; + + case GF_STREAM_SCENE: + case GF_STREAM_OD: + if (oti == GPAC_OTI_SCENE_DIMS) { + rtp_type = GF_RTP_PAYT_3GPP_DIMS; + has_mpeg4_mapping = 0; + } else { + rtp_type = GF_RTP_PAYT_MPEG4; + } + break; + + + case GF_STREAM_4CC: + switch (oti) { + case GF_ISOM_SUBTYPE_3GP_H263: + rtp_type = GF_RTP_PAYT_H263; + required_rate = 90000; + streamType = GF_STREAM_VISUAL; + OfficialPayloadType = 34; + /*not 100% compliant (short header is missing) but should still work*/ + oti = GPAC_OTI_VIDEO_MPEG4_PART2; + PL_ID = 0x01; + break; + case GF_ISOM_SUBTYPE_3GP_AMR: + required_rate = 8000; + rtp_type = GF_RTP_PAYT_AMR; + streamType = GF_STREAM_AUDIO; + has_mpeg4_mapping = 0; + nb_ch = 1; + break; + case GF_ISOM_SUBTYPE_3GP_AMR_WB: + required_rate = 16000; + rtp_type = GF_RTP_PAYT_AMR_WB; + streamType = GF_STREAM_AUDIO; + has_mpeg4_mapping = 0; + nb_ch = 1; + break; + case GF_ISOM_SUBTYPE_AC3: + rtp_type = GF_RTP_PAYT_AC3; + streamType = GF_STREAM_AUDIO; + has_mpeg4_mapping = 1; + nb_ch = 1; + break; + case GF_ISOM_SUBTYPE_AVC_H264: + case GF_ISOM_SUBTYPE_AVC2_H264: + case GF_ISOM_SUBTYPE_SVC_H264: + { + required_rate = 90000; /* "90 kHz clock rate MUST be used"*/ + rtp_type = GF_RTP_PAYT_H264_AVC; + streamType = GF_STREAM_VISUAL; + oti = GPAC_OTI_VIDEO_AVC; + PL_ID = 0x0F; + } + break; + case GF_ISOM_SUBTYPE_3GP_QCELP: + required_rate = 8000; + rtp_type = GF_RTP_PAYT_QCELP; + streamType = GF_STREAM_AUDIO; + oti = GPAC_OTI_AUDIO_13K_VOICE; + OfficialPayloadType = 12; + nb_ch = 1; + break; + case GF_ISOM_SUBTYPE_3GP_EVRC: + case GF_ISOM_SUBTYPE_3GP_SMV: + required_rate = 8000; + rtp_type = GF_RTP_PAYT_EVRC_SMV; + streamType = GF_STREAM_AUDIO; + oti = (oti==GF_ISOM_SUBTYPE_3GP_EVRC) ? GPAC_OTI_AUDIO_EVRC_VOICE : GPAC_OTI_AUDIO_SMV_VOICE; + nb_ch = 1; + break; + } + break; + + default: + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[RTP Packetizer] Unsupported stream type %x\n", streamType)); + return NULL; + } + + /*not supported*/ + if (!rtp_type) return NULL; + + /*override hinter type if requested and possible*/ + if (has_mpeg4_mapping && (flags & GP_RTP_PCK_FORCE_MPEG4)) { + rtp_type = GF_RTP_PAYT_MPEG4; + } + /*use static payload ID if enabled*/ + else if (OfficialPayloadType && (flags & GP_RTP_PCK_USE_STATIC_ID) ) { + PayloadType = OfficialPayloadType; + } + + /*systems carousel: we need at least IDX and RAP signaling*/ + if (flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) { + flags |= GP_RTP_PCK_SIGNAL_RAP; + } + + /*update flags in MultiSL*/ + if (flags & GP_RTP_PCK_USE_MULTI) { + if (MinSize != MaxSize) flags |= GP_RTP_PCK_SIGNAL_SIZE; + if (!const_dur) flags |= GP_RTP_PCK_SIGNAL_TS; + } + + /*default SL for RTP */ + memset(&slc, 0, sizeof(GF_SLConfig)); + slc.tag = GF_ODF_SLC_TAG; + slc.useTimestampsFlag = 1; + slc.timestampLength = 32; + slc.timestampResolution = timeScale; + + /*override clockrate if set*/ + if (required_rate) { + Double sc = required_rate; + sc /= slc.timestampResolution; + maxDTSDelta = (u32) (maxDTSDelta*sc); + slc.timestampResolution = required_rate; + } + /*switch to RTP TS*/ + max_ptime = (u32) (max_ptime * slc.timestampResolution / 1000); + + slc.AUSeqNumLength = au_sn_len; + slc.CUDuration = const_dur; + + if (flags & GP_RTP_PCK_SIGNAL_RAP) { + slc.useRandomAccessPointFlag = 1; + } else { + slc.useRandomAccessPointFlag = 0; + slc.hasRandomAccessUnitsOnlyFlag = 1; + } + + stream->packetizer = gf_rtp_builder_new(rtp_type, &slc, flags, + stream, + rtp_stream_on_new_packet, rtp_stream_on_packet_done, + NULL, rtp_stream_on_data); + + if (!stream->packetizer) { + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[RTP Packetizer] Failed to create packetizer\n")); + gf_free(stream); + return NULL; + } + + gf_rtp_builder_init(stream->packetizer, PayloadType, MTU, max_ptime, + streamType, oti, PL_ID, MinSize, MaxSize, avgTS, maxDTSDelta, IV_length, KI_length, mpeg4mode); + + + e = rtp_stream_init_channel(stream, MTU + 12, ip_dest, port, TTL, ifce_addr); + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[RTP Packetizer] Failed to create RTP channel - error %s\n", gf_error_to_string(e) )); + gf_free(stream); + return NULL; + } + stream->ts_scale = slc.timestampResolution; + stream->ts_scale /= timeScale; + + stream->buffer_alloc = MTU+12; + stream->buffer = gf_malloc(sizeof(char) * stream->buffer_alloc); + + return stream; +} + + +GF_RTPStreamer *gf_rtp_streamer_new(u32 streamType, u32 oti, u32 timeScale, + const char *ip_dest, u16 port, u32 MTU, u8 TTL, const char *ifce_addr, + u32 flags, char *dsi, u32 dsi_len) +{ + return gf_rtp_streamer_new_extended(streamType, oti, timeScale, ip_dest, port, MTU, TTL, ifce_addr, flags, dsi, dsi_len, + + 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + +} + +void gf_rtp_streamer_del(GF_RTPStreamer *streamer) +{ + if (streamer) { + if (streamer->channel) gf_rtp_del(streamer->channel); + if (streamer->packetizer) gf_rtp_builder_del(streamer->packetizer); + if (streamer->buffer) gf_free(streamer->buffer); + gf_free(streamer); + } +} + +#if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_STREAMING) + +void gf_media_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, GF_ISOFile *file, u32 track) +{ + char buffer[2000]; + u32 w, h, i, m_w, m_h; + s32 tx, ty; + s16 l; + sprintf(sdpLine, "a=fmtp:%d sver=60; ", builder->PayloadType); + gf_isom_get_track_layout_info(file, track, &w, &h, &tx, &ty, &l); + sprintf(buffer, "width=%d; height=%d; tx=%d; ty=%d; layer=%d; ", w, h, tx, ty, l); + strcat(sdpLine, buffer); + m_w = w; + m_h = h; + for (i=0; i<gf_isom_get_track_count(file); i++) { + switch (gf_isom_get_media_type(file, i+1)) { + case GF_ISOM_MEDIA_SCENE: + case GF_ISOM_MEDIA_VISUAL: + gf_isom_get_track_layout_info(file, i+1, &w, &h, &tx, &ty, &l); + if (w>m_w) m_w = w; + if (h>m_h) m_h = h; + break; + default: + break; + } + } + sprintf(buffer, "max-w=%d; max-h=%d", m_w, m_h); + strcat(sdpLine, buffer); + + strcat(sdpLine, "; tx3g="); + for (i=0; i<gf_isom_get_sample_description_count(file, track); i++) { + char *tx3g; + u32 tx3g_len, len; + gf_isom_text_get_encoded_tx3g(file, track, i+1, GF_RTP_TX3G_SIDX_OFFSET, &tx3g, &tx3g_len); + len = gf_base64_encode(tx3g, tx3g_len, buffer, 2000); + gf_free(tx3g); + buffer[len] = 0; + if (i) strcat(sdpLine, ", "); + strcat(sdpLine, buffer); + } +} + +#endif /*!defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_STREAMING)*/ + + +GF_Err gf_rtp_streamer_append_sdp_extended(GF_RTPStreamer *rtp, u16 ESID, char *dsi, u32 dsi_len, GF_ISOFile *isofile, u32 isotrack, char *KMS_URI, u32 width, u32 height, char **out_sdp_buffer) +{ + u32 size; + u16 port; + char mediaName[30], payloadName[30]; + char sdp[20000], sdpLine[10000]; + + if (!out_sdp_buffer) return GF_BAD_PARAM; + + gf_rtp_builder_get_payload_name(rtp->packetizer, payloadName, mediaName); + gf_rtp_get_ports(rtp->channel, &port, NULL); + + sprintf(sdp, "m=%s %d RTP/%s %d\n", mediaName, port, rtp->packetizer->slMap.IV_length ? "SAVP" : "AVP", rtp->packetizer->PayloadType); + sprintf(sdpLine, "a=rtpmap:%d %s/%d\n", rtp->packetizer->PayloadType, payloadName, rtp->packetizer->sl_config.timestampResolution); + strcat(sdp, sdpLine); + if (ESID && (rtp->packetizer->rtp_payt != GF_RTP_PAYT_3GPP_DIMS)) { + sprintf(sdpLine, "a=mpeg4-esid:%d\n", ESID); + strcat(sdp, sdpLine); + } + + if (width && height) { + if (rtp->packetizer->rtp_payt == GF_RTP_PAYT_H263) { + sprintf(sdpLine, "a=cliprect:0,0,%d,%d\n", height, width); + strcat(sdp, sdpLine); + } + /*extensions for some mobile phones*/ + sprintf(sdpLine, "a=framesize:%d %d-%d\n", rtp->packetizer->PayloadType, width, height); + strcat(sdp, sdpLine); + } + + strcpy(sdpLine, ""); + + /*AMR*/ + if ((rtp->packetizer->rtp_payt == GF_RTP_PAYT_AMR) || (rtp->packetizer->rtp_payt == GF_RTP_PAYT_AMR_WB)) { + sprintf(sdpLine, "a=fmtp:%d octet-align=1\n", rtp->packetizer->PayloadType); + } + /*Text*/ + else if (rtp->packetizer->rtp_payt == GF_RTP_PAYT_3GPP_TEXT) { + gf_media_format_ttxt_sdp(rtp->packetizer, payloadName, sdpLine, isofile, isotrack); + strcat(sdpLine, "\n"); + } + /*EVRC/SMV in non header-free mode*/ + else if ((rtp->packetizer->rtp_payt == GF_RTP_PAYT_EVRC_SMV) && (rtp->packetizer->auh_size>1)) { + sprintf(sdpLine, "a=fmtp:%d maxptime=%d\n", rtp->packetizer->PayloadType, rtp->packetizer->auh_size*20); + } + /*H264/AVC*/ + else if (rtp->packetizer->rtp_payt == GF_RTP_PAYT_H264_AVC) { + GF_AVCConfig *avcc = dsi ? gf_odf_avc_cfg_read(dsi, dsi_len) : NULL; + + if (avcc) { + sprintf(sdpLine, "a=fmtp:%d profile-level-id=%02X%02X%02X; packetization-mode=1", rtp->packetizer->PayloadType, avcc->AVCProfileIndication, avcc->profile_compatibility, avcc->AVCLevelIndication); + if (gf_list_count(avcc->pictureParameterSets) || gf_list_count(avcc->sequenceParameterSets)) { + u32 i, count, b64s; + char b64[200]; + strcat(sdpLine, "; sprop-parameter-sets="); + count = gf_list_count(avcc->sequenceParameterSets); + for (i=0; i<count; i++) { + GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(avcc->sequenceParameterSets, i); + b64s = gf_base64_encode(sl->data, sl->size, b64, 200); + b64[b64s]=0; + strcat(sdpLine, b64); + if (i+1<count) strcat(sdpLine, ","); + } + if (i) strcat(sdpLine, ","); + count = gf_list_count(avcc->pictureParameterSets); + for (i=0; i<count; i++) { + GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(avcc->pictureParameterSets, i); + b64s = gf_base64_encode(sl->data, sl->size, b64, 200); + b64[b64s]=0; + strcat(sdpLine, b64); + if (i+1<count) strcat(sdpLine, ","); + } + } + gf_odf_avc_cfg_del(avcc); + strcat(sdpLine, "\n"); + } + } + /*MPEG-4 decoder config*/ + else if (rtp->packetizer->rtp_payt==GF_RTP_PAYT_MPEG4) { + gf_rtp_builder_format_sdp(rtp->packetizer, payloadName, sdpLine, dsi, dsi_len); + strcat(sdpLine, "\n"); + + if (rtp->packetizer->slMap.IV_length && KMS_URI) { + if (!strnicmp(KMS_URI, "(key)", 5) || !strnicmp(KMS_URI, "(ipmp)", 6) || !strnicmp(KMS_URI, "(uri)", 5)) { + strcat(sdpLine, "; ISMACrypKey="); + } else { + strcat(sdpLine, "; ISMACrypKey=(uri)"); + } + strcat(sdpLine, KMS_URI); + strcat(sdpLine, "\n"); + } + } + /*DIMS decoder config*/ + else if (rtp->packetizer->rtp_payt==GF_RTP_PAYT_3GPP_DIMS) { + sprintf(sdpLine, "a=fmtp:%d Version-profile=%d", rtp->packetizer->PayloadType, 10); + if (rtp->packetizer->flags & GP_RTP_DIMS_COMPRESSED) { + strcat(sdpLine, ";content-coding=deflate"); + } + strcat(sdpLine, "\n"); + } + /*MPEG-4 Audio LATM*/ + else if (rtp->packetizer->rtp_payt==GF_RTP_PAYT_LATM) { + GF_BitStream *bs; + char *config_bytes; + u32 config_size; + + /* form config string */ + bs = gf_bs_new(NULL, 32, GF_BITSTREAM_WRITE); + gf_bs_write_int(bs, 0, 1); /* AudioMuxVersion */ + gf_bs_write_int(bs, 1, 1); /* all streams same time */ + gf_bs_write_int(bs, 0, 6); /* numSubFrames */ + gf_bs_write_int(bs, 0, 4); /* numPrograms */ + gf_bs_write_int(bs, 0, 3); /* numLayer */ + + /* audio-specific config - PacketVideo patch: don't signal SBR and PS stuff, not allowed in LATM with audioMuxVersion=0*/ + if (dsi) gf_bs_write_data(bs, dsi, MIN(dsi_len, 2) ); + + /* other data */ + gf_bs_write_int(bs, 0, 3); /* frameLengthType */ + gf_bs_write_int(bs, 0xff, 8); /* latmBufferFullness */ + gf_bs_write_int(bs, 0, 1); /* otherDataPresent */ + gf_bs_write_int(bs, 0, 1); /* crcCheckPresent */ + gf_bs_get_content(bs, &config_bytes, &config_size); + gf_bs_del(bs); + + gf_rtp_builder_format_sdp(rtp->packetizer, payloadName, sdpLine, config_bytes, config_size); + gf_free(config_bytes); + strcat(sdpLine, "\n"); + } + + strcat(sdp, sdpLine); + + size = strlen(sdp) + (*out_sdp_buffer ? strlen(*out_sdp_buffer) : 0) + 1; + if ( !*out_sdp_buffer) { + *out_sdp_buffer = gf_malloc(sizeof(char)*size); + if (! *out_sdp_buffer) return GF_OUT_OF_MEM; + strcpy(*out_sdp_buffer, sdp); + } else { + *out_sdp_buffer = gf_realloc(*out_sdp_buffer, sizeof(char)*size); + if (! *out_sdp_buffer) return GF_OUT_OF_MEM; + strcat(*out_sdp_buffer, sdp); + } + return GF_OK; +} + +char *gf_rtp_streamer_format_sdp_header(char *app_name, char *ip_dest, char *session_name, char *iod64) +{ + u64 size; + char *sdp; + FILE *tmp = gf_temp_file_new(); + if (!tmp) return NULL; + + /* write SDP header*/ + fprintf(tmp, "v=0\n"); + fprintf(tmp, "o=%s 3326096807 1117107880000 IN IP%d %s\n", app_name, gf_net_is_ipv6(ip_dest) ? 6 : 4, ip_dest); + fprintf(tmp, "s=%s\n", (session_name ? session_name : "GPAC Scene Streaming Session")); + fprintf(tmp, "c=IN IP%d %s\n", gf_net_is_ipv6(ip_dest) ? 6 : 4, ip_dest); + fprintf(tmp, "t=0 0\n"); + + if (iod64) fprintf(tmp, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"\n", iod64); + + gf_f64_seek(tmp, 0, SEEK_END); + size = gf_f64_tell(tmp); + gf_f64_seek(tmp, 0, SEEK_SET); + sdp = gf_malloc(sizeof(char) * (size_t)(size+1)); + size = fread(sdp, 1, (size_t)size, tmp); + sdp[size] = 0; + fclose(tmp); + return sdp; +} + +GF_Err gf_rtp_streamer_append_sdp(GF_RTPStreamer *rtp, u16 ESID, char *dsi, u32 dsi_len, char *KMS_URI, char **out_sdp_buffer) +{ + return gf_rtp_streamer_append_sdp_extended(rtp, ESID, dsi, dsi_len, NULL, 0, KMS_URI, 0, 0, out_sdp_buffer); +} + +GF_Err gf_rtp_streamer_send_data(GF_RTPStreamer *rtp, char *data, u32 size, u32 fullsize, u64 cts, u64 dts, Bool is_rap, Bool au_start, Bool au_end, u32 au_sn, u32 sampleDuration, u32 sampleDescIndex) +{ + rtp->packetizer->sl_header.compositionTimeStamp = (u64) (cts*rtp->ts_scale); + rtp->packetizer->sl_header.decodingTimeStamp = (u64) (dts*rtp->ts_scale); + rtp->packetizer->sl_header.randomAccessPointFlag = is_rap; + rtp->packetizer->sl_header.accessUnitStartFlag = au_start; + rtp->packetizer->sl_header.accessUnitEndFlag = au_end; + rtp->packetizer->sl_header.randomAccessPointFlag = is_rap; + rtp->packetizer->sl_header.AU_sequenceNumber = au_sn; + sampleDuration = (u32) (sampleDuration * rtp->ts_scale); + + return gf_rtp_builder_process(rtp->packetizer, data, size, (u8) au_end, fullsize, sampleDuration, sampleDescIndex); +} + +GF_Err gf_rtp_streamer_send_au(GF_RTPStreamer *rtp, char *data, u32 size, u64 cts, u64 dts, Bool is_rap) +{ + return gf_rtp_streamer_send_data(rtp, data, size, size, cts, dts, is_rap, 1, 1, 0, 0, 0); +} + +GF_Err gf_rtp_streamer_send_au_with_sn(GF_RTPStreamer *rtp, char *data, u32 size, u64 cts, u64 dts, Bool is_rap, Bool inc_au_sn) +{ + if (inc_au_sn) rtp->packetizer->sl_header.AU_sequenceNumber++; + return gf_rtp_streamer_send_data(rtp, data, size, size, cts, dts, is_rap, 1, 1, rtp->packetizer->sl_header.AU_sequenceNumber, 0, 0); +} + +void gf_rtp_streamer_disable_auto_rtcp(GF_RTPStreamer *streamer) +{ + streamer->channel->no_auto_rtcp = 1; +} + +GF_Err gf_rtp_streamer_send_rtcp(GF_RTPStreamer *streamer, Bool force_ts, u32 rtp_ts) +{ + if (force_ts) streamer->channel->last_pck_ts = rtp_ts; + return gf_rtp_send_rtcp_report(streamer->channel, NULL, NULL); +} + +#endif /*GPAC_DISABLE_STREAMING*/ + diff --git a/src/ietf/rtsp_command.c b/src/ietf/rtsp_command.c index ea8048a..ba5ee4d 100644 --- a/src/ietf/rtsp_command.c +++ b/src/ietf/rtsp_command.c @@ -24,6 +24,9 @@ #include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/token.h> GF_EXPORT @@ -37,7 +40,7 @@ GF_RTSPCommand *gf_rtsp_command_new() } -#define COM_FREE_CLEAN(hdr) if (com->hdr) free(com->hdr); \ +#define COM_FREE_CLEAN(hdr) if (com->hdr) gf_free(com->hdr); \ com->hdr = NULL; GF_EXPORT @@ -74,7 +77,7 @@ void gf_rtsp_command_reset(GF_RTSPCommand *com) com->Bandwidth = com->Blocksize = com->Content_Length = com->CSeq = 0; com->Scale = com->Speed = 0.0; - if (com->Range) free(com->Range); + if (com->Range) gf_free(com->Range); com->Range = NULL; while (gf_list_count(com->Transports)) { @@ -85,9 +88,9 @@ void gf_rtsp_command_reset(GF_RTSPCommand *com) while (gf_list_count(com->Xtensions)) { att = (GF_X_Attribute*)gf_list_get(com->Xtensions, 0); gf_list_rem(com->Xtensions, 0); - free(att->Name); - free(att->Value); - free(att); + gf_free(att->Name); + gf_free(att->Value); + gf_free(att); } } @@ -98,7 +101,7 @@ void gf_rtsp_command_del(GF_RTSPCommand *com) gf_rtsp_command_reset(com); gf_list_del(com->Xtensions); gf_list_del(com->Transports); - free(com); + gf_free(com); } @@ -113,7 +116,7 @@ GF_Err RTSP_WriteCommand(GF_RTSPSession *sess, GF_RTSPCommand *com, unsigned cha *out_buffer = NULL; size = RTSP_WRITE_STEPALLOC; - buffer = (char *) malloc(size); + buffer = (char *) gf_malloc(size); cur_pos = 0; //request @@ -140,7 +143,7 @@ GF_Err RTSP_WriteCommand(GF_RTSPSession *sess, GF_RTSPCommand *com, unsigned cha //if we have a body write the content length if (com->body) { RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Content-Length: "); - RTSP_WRITE_INT(buffer, size, cur_pos, strlen(com->body), 0); + RTSP_WRITE_INT(buffer, size, cur_pos, (u32) strlen(com->body), 0); RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n"); } //write the CSeq - use the SESSION CSeq @@ -209,7 +212,7 @@ GF_Err RTSP_WriteCommand(GF_RTSPSession *sess, GF_RTSPCommand *com, unsigned cha } } if (trans->port_first) { - RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, trans->IsUnicast ? ";server_port=" : ";port="); + RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, (trans->IsUnicast ? ";server_port=" : ";port=")); RTSP_WRITE_INT(buffer, size, cur_pos, trans->port_first, 0); RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-"); RTSP_WRITE_INT(buffer, size, cur_pos, trans->port_last, 0); @@ -384,7 +387,7 @@ GF_Err gf_rtsp_send_command(GF_RTSPSession *sess, GF_RTSPCommand *com) strcpy(sess->RTSPLastRequest, com->method); exit: - if (result) free(result); + if (result) gf_free(result); return e; } @@ -396,26 +399,26 @@ void gf_rtsp_set_command_value(GF_RTSPCommand *com, char *Header, char *Value) GF_RTSPTransport *trans; GF_X_Attribute *x_Att; - if (!stricmp(Header, "Accept")) com->Accept = strdup(Value); - else if (!stricmp(Header, "Accept-Encoding")) com->Accept_Encoding = strdup(Value); - else if (!stricmp(Header, "Accept-Language")) com->Accept_Language = strdup(Value); - else if (!stricmp(Header, "Authorization")) com->Authorization = strdup(Value); + if (!stricmp(Header, "Accept")) com->Accept = gf_strdup(Value); + else if (!stricmp(Header, "Accept-Encoding")) com->Accept_Encoding = gf_strdup(Value); + else if (!stricmp(Header, "Accept-Language")) com->Accept_Language = gf_strdup(Value); + else if (!stricmp(Header, "Authorization")) com->Authorization = gf_strdup(Value); else if (!stricmp(Header, "Bandwidth")) sscanf(Value, "%d", &com->Bandwidth); else if (!stricmp(Header, "Blocksize")) sscanf(Value, "%d", &com->Blocksize); - else if (!stricmp(Header, "Cache-Control")) com->Cache_Control = strdup(Value); - else if (!stricmp(Header, "Conference")) com->Conference = strdup(Value); - else if (!stricmp(Header, "Connection")) com->Connection = strdup(Value); + else if (!stricmp(Header, "Cache-Control")) com->Cache_Control = gf_strdup(Value); + else if (!stricmp(Header, "Conference")) com->Conference = gf_strdup(Value); + else if (!stricmp(Header, "Connection")) com->Connection = gf_strdup(Value); else if (!stricmp(Header, "Content-Length")) sscanf(Value, "%d", &com->Content_Length); else if (!stricmp(Header, "CSeq")) sscanf(Value, "%d", &com->CSeq); - else if (!stricmp(Header, "From")) com->From = strdup(Value); - else if (!stricmp(Header, "Proxy_Authorization")) com->Proxy_Authorization = strdup(Value); - else if (!stricmp(Header, "Proxy_Require")) com->Proxy_Require = strdup(Value); + else if (!stricmp(Header, "From")) com->From = gf_strdup(Value); + else if (!stricmp(Header, "Proxy_Authorization")) com->Proxy_Authorization = gf_strdup(Value); + else if (!stricmp(Header, "Proxy_Require")) com->Proxy_Require = gf_strdup(Value); else if (!stricmp(Header, "Range")) com->Range = gf_rtsp_range_parse(Value); - else if (!stricmp(Header, "Referer")) com->Referer = strdup(Value); + else if (!stricmp(Header, "Referer")) com->Referer = gf_strdup(Value); else if (!stricmp(Header, "Scale")) sscanf(Value, "%lf", &com->Scale); - else if (!stricmp(Header, "Session")) com->Session = strdup(Value); + else if (!stricmp(Header, "Session")) com->Session = gf_strdup(Value); else if (!stricmp(Header, "Speed")) sscanf(Value, "%lf", &com->Speed); - else if (!stricmp(Header, "User_Agent")) com->User_Agent = strdup(Value); + else if (!stricmp(Header, "User_Agent")) com->User_Agent = gf_strdup(Value); //Transports else if (!stricmp(Header, "Transport")) { LinePos = 0; @@ -428,10 +431,10 @@ void gf_rtsp_set_command_value(GF_RTSPCommand *com, char *Header, char *Value) } //eXtensions attributes else if (!strnicmp(Header, "x-", 2)) { - x_Att = (GF_X_Attribute*)malloc(sizeof(GF_X_Attribute)); - x_Att->Name = strdup(Header+2); + x_Att = (GF_X_Attribute*)gf_malloc(sizeof(GF_X_Attribute)); + x_Att->Name = gf_strdup(Header+2); x_Att->Value = NULL; - if (Value && strlen(Value)) x_Att->Value = strdup(Value); + if (Value && strlen(Value)) x_Att->Value = gf_strdup(Value); gf_list_add(com->Xtensions, x_Att); } //the rest is ignored @@ -458,12 +461,12 @@ GF_Err RTSP_ParseCommandHeader(GF_RTSPSession *sess, GF_RTSPCommand *com, u32 Bo //method Pos = gf_token_get(LineBuffer, 0, " \t\r\n", ValBuf, 1024); if (Pos <= 0) return GF_OK; - com->method = strdup((const char *) ValBuf); + com->method = gf_strdup((const char *) ValBuf); //URL Pos = gf_token_get(LineBuffer, Pos, " \t\r\n", ValBuf, 1024); if (Pos <= 0) return GF_OK; - com->service_name = strdup(ValBuf); + com->service_name = gf_strdup(ValBuf); //RTSP version Pos = gf_token_get(LineBuffer, Pos, "\t\r\n", ValBuf, 1024); @@ -511,7 +514,7 @@ GF_Err gf_rtsp_get_command(GF_RTSPSession *sess, GF_RTSPCommand *com) //copy the body if any if (!e && com->Content_Length) { - com->body = (char *) malloc(sizeof(char) * (com->Content_Length)); + com->body = (char *) gf_malloc(sizeof(char) * (com->Content_Length)); memcpy(com->body, sess->TCPBuffer+sess->CurrentPos + BodyStart, com->Content_Length); } //reset TCP buffer @@ -564,16 +567,4 @@ exit: return e; } - - - - - - - - - - - - - +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/ietf/rtsp_common.c b/src/ietf/rtsp_common.c index f86166b..44e6a48 100644 --- a/src/ietf/rtsp_common.c +++ b/src/ietf/rtsp_common.c @@ -23,6 +23,9 @@ */ #include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/token.h> @@ -99,10 +102,10 @@ GF_Err gf_rtsp_refill_buffer(GF_RTSPSession *sess) // printf("Forcing reading\n"); - ptr = (char *)malloc(sizeof(char) * res); + ptr = (char *)gf_malloc(sizeof(char) * res); memcpy(ptr, sess->TCPBuffer+sess->CurrentPos, res); memcpy(sess->TCPBuffer, ptr, res); - free(ptr); + gf_free(ptr); sess->CurrentPos = 0; sess->CurrentSize = res; @@ -162,18 +165,18 @@ GF_RTSPTransport *gf_rtsp_transport_parse(char *buffer) //very first param is the profile if (IsFirst) { - tmp->Profile = strdup(param_name); + tmp->Profile = gf_strdup(param_name); IsFirst = 0; continue; } if (!stricmp(param_name, "destination")) { - if (tmp->destination) free(tmp->destination); - tmp->destination = strdup(param_val); + if (tmp->destination) gf_free(tmp->destination); + tmp->destination = gf_strdup(param_val); } else if (!stricmp(param_name, "source")) { - if (tmp->source) free(tmp->source); - tmp->source = strdup(param_val); + if (tmp->source) gf_free(tmp->source); + tmp->source = gf_strdup(param_val); } else if (!stricmp(param_name, "unicast")) tmp->IsUnicast = 1; else if (!stricmp(param_name, "RECORD")) tmp->IsRecord = 1; @@ -365,3 +368,5 @@ const char *gf_rtsp_nc_to_string(u32 ErrCode) return "Not Implemented"; } } + +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/ietf/rtsp_response.c b/src/ietf/rtsp_response.c index 5eba471..b8e4ee2 100644 --- a/src/ietf/rtsp_response.c +++ b/src/ietf/rtsp_response.c @@ -23,6 +23,9 @@ */ #include <gpac/internal/ietf_dev.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/token.h> @@ -38,7 +41,7 @@ GF_RTSPResponse *gf_rtsp_response_new() } -#define RSP_FREE_CLEAN(hdr) if (rsp->hdr) free(rsp->hdr); \ +#define RSP_FREE_CLEAN(hdr) if (rsp->hdr) gf_free(rsp->hdr); \ rsp->hdr = NULL; GF_EXPORT @@ -92,7 +95,7 @@ void gf_rtsp_response_reset(GF_RTSPResponse *rsp) rsp->Bandwidth = rsp->Blocksize = rsp->ResponseCode = rsp->Content_Length = rsp->CSeq = 0; rsp->Scale = rsp->Speed = 0.0; - if (rsp->Range) free(rsp->Range); + if (rsp->Range) gf_free(rsp->Range); rsp->Range = NULL; rsp->SessionTimeOut = 0; @@ -106,15 +109,15 @@ void gf_rtsp_response_reset(GF_RTSPResponse *rsp) while (gf_list_count(rsp->RTP_Infos)) { inf = (GF_RTPInfo*) gf_list_get(rsp->RTP_Infos, 0); gf_list_rem(rsp->RTP_Infos, 0); - if (inf->url) free(inf->url); - free(inf); + if (inf->url) gf_free(inf->url); + gf_free(inf); } while (gf_list_count(rsp->Xtensions)) { att = (GF_X_Attribute*)gf_list_get(rsp->Xtensions, 0); gf_list_rem(rsp->Xtensions, 0); - free(att->Name); - free(att->Value); - free(att); + gf_free(att->Name); + gf_free(att->Value); + gf_free(att); } } @@ -127,7 +130,7 @@ void gf_rtsp_response_del(GF_RTSPResponse *rsp) gf_list_del(rsp->RTP_Infos); gf_list_del(rsp->Xtensions); gf_list_del(rsp->Transports); - free(rsp); + gf_free(rsp); } @@ -151,10 +154,10 @@ GF_EXPORT void gf_rtsp_transport_del(GF_RTSPTransport *transp) { if (!transp) return; - if (transp->destination) free(transp->destination); - if (transp->Profile) free(transp->Profile); - if (transp->source) free(transp->source); - free(transp); + if (transp->destination) gf_free(transp->destination); + if (transp->Profile) gf_free(transp->Profile); + if (transp->source) gf_free(transp->source); + gf_free(transp); } GF_EXPORT @@ -164,12 +167,12 @@ GF_RTSPTransport *gf_rtsp_transport_clone(GF_RTSPTransport *original) if (!original) return NULL; - tr = (GF_RTSPTransport*) malloc(sizeof(GF_RTSPTransport)); + tr = (GF_RTSPTransport*) gf_malloc(sizeof(GF_RTSPTransport)); memcpy(tr, original, sizeof(GF_RTSPTransport)); tr->destination = tr->source = tr->Profile = NULL; - if (original->destination) tr->destination = strdup(original->destination); - if (original->source) tr->source = strdup(original->source); - if (original->Profile) tr->Profile = strdup(original->Profile); + if (original->destination) tr->destination = gf_strdup(original->destination); + if (original->source) tr->source = gf_strdup(original->source); + if (original->Profile) tr->Profile = gf_strdup(original->Profile); return tr; } @@ -185,57 +188,57 @@ GF_EXPORT void gf_rtsp_range_del(GF_RTSPRange *range) { if (!range) return; - free(range); + gf_free(range); } void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value) { - char LineBuffer[400], buf[100], param_name[100], param_val[100]; + char LineBuffer[400], buf[1000], param_name[100], param_val[1000]; s32 LinePos, Pos, nPos, s_val; GF_RTPInfo *info; GF_RTSPTransport *trans; GF_X_Attribute *x_Att; - if (!stricmp(Header, "Accept")) rsp->Accept = strdup(Value); - else if (!stricmp(Header, "Accept-Encoding")) rsp->Accept_Encoding = strdup(Value); - else if (!stricmp(Header, "Accept-Language")) rsp->Accept_Language = strdup(Value); - else if (!stricmp(Header, "Allow")) rsp->Allow = strdup(Value); - else if (!stricmp(Header, "Authorization")) rsp->Authorization = strdup(Value); + if (!stricmp(Header, "Accept")) rsp->Accept = gf_strdup(Value); + else if (!stricmp(Header, "Accept-Encoding")) rsp->Accept_Encoding = gf_strdup(Value); + else if (!stricmp(Header, "Accept-Language")) rsp->Accept_Language = gf_strdup(Value); + else if (!stricmp(Header, "Allow")) rsp->Allow = gf_strdup(Value); + else if (!stricmp(Header, "Authorization")) rsp->Authorization = gf_strdup(Value); else if (!stricmp(Header, "Bandwidth")) sscanf(Value, "%d", &rsp->Bandwidth); else if (!stricmp(Header, "Blocksize")) sscanf(Value, "%d", &rsp->Blocksize); - else if (!stricmp(Header, "Cache-Control")) rsp->Cache_Control = strdup(Value); - else if (!stricmp(Header, "Conference")) rsp->Conference = strdup(Value); - else if (!stricmp(Header, "Connection")) rsp->Connection = strdup(Value); - else if (!stricmp(Header, "Content-Base")) rsp->Content_Base = strdup(Value); - else if (!stricmp(Header, "Content-Encoding")) rsp->Content_Encoding = strdup(Value); + else if (!stricmp(Header, "Cache-Control")) rsp->Cache_Control = gf_strdup(Value); + else if (!stricmp(Header, "Conference")) rsp->Conference = gf_strdup(Value); + else if (!stricmp(Header, "Connection")) rsp->Connection = gf_strdup(Value); + else if (!stricmp(Header, "Content-Base")) rsp->Content_Base = gf_strdup(Value); + else if (!stricmp(Header, "Content-Encoding")) rsp->Content_Encoding = gf_strdup(Value); else if (!stricmp(Header, "Content-Length")) sscanf(Value, "%d", &rsp->Content_Length); - else if (!stricmp(Header, "Content-Language")) rsp->Content_Language = strdup(Value); - else if (!stricmp(Header, "Content-Location")) rsp->Content_Location = strdup(Value); - else if (!stricmp(Header, "Content-Type")) rsp->Content_Type = strdup(Value); + else if (!stricmp(Header, "Content-Language")) rsp->Content_Language = gf_strdup(Value); + else if (!stricmp(Header, "Content-Location")) rsp->Content_Location = gf_strdup(Value); + else if (!stricmp(Header, "Content-Type")) rsp->Content_Type = gf_strdup(Value); else if (!stricmp(Header, "CSeq")) sscanf(Value, "%d", &rsp->CSeq); - else if (!stricmp(Header, "Date")) rsp->Date = strdup(Value); - else if (!stricmp(Header, "Expires")) rsp->Expires = strdup(Value); - else if (!stricmp(Header, "From")) rsp->From = strdup(Value); - else if (!stricmp(Header, "Host")) rsp->Host = strdup(Value); - else if (!stricmp(Header, "If-Match")) rsp->If_Match = strdup(Value); - else if (!stricmp(Header, "If-Modified-Since")) rsp->If_Modified_Since = strdup(Value); - else if (!stricmp(Header, "Last-Modified")) rsp->Last_Modified = strdup(Value); - else if (!stricmp(Header, "Location")) rsp->Location = strdup(Value); - else if (!stricmp(Header, "Proxy-Authenticate")) rsp->Proxy_Authenticate = strdup(Value); - else if (!stricmp(Header, "Proxy-Require")) rsp->Proxy_Require = strdup(Value); - else if (!stricmp(Header, "Public")) rsp->Public = strdup(Value); - else if (!stricmp(Header, "Referer")) rsp->Referer = strdup(Value); - else if (!stricmp(Header, "Require")) rsp->Require = strdup(Value); - else if (!stricmp(Header, "Retry-After")) rsp->Retry_After = strdup(Value); + else if (!stricmp(Header, "Date")) rsp->Date = gf_strdup(Value); + else if (!stricmp(Header, "Expires")) rsp->Expires = gf_strdup(Value); + else if (!stricmp(Header, "From")) rsp->From = gf_strdup(Value); + else if (!stricmp(Header, "Host")) rsp->Host = gf_strdup(Value); + else if (!stricmp(Header, "If-Match")) rsp->If_Match = gf_strdup(Value); + else if (!stricmp(Header, "If-Modified-Since")) rsp->If_Modified_Since = gf_strdup(Value); + else if (!stricmp(Header, "Last-Modified")) rsp->Last_Modified = gf_strdup(Value); + else if (!stricmp(Header, "Location")) rsp->Location = gf_strdup(Value); + else if (!stricmp(Header, "Proxy-Authenticate")) rsp->Proxy_Authenticate = gf_strdup(Value); + else if (!stricmp(Header, "Proxy-Require")) rsp->Proxy_Require = gf_strdup(Value); + else if (!stricmp(Header, "Public")) rsp->Public = gf_strdup(Value); + else if (!stricmp(Header, "Referer")) rsp->Referer = gf_strdup(Value); + else if (!stricmp(Header, "Require")) rsp->Require = gf_strdup(Value); + else if (!stricmp(Header, "Retry-After")) rsp->Retry_After = gf_strdup(Value); else if (!stricmp(Header, "Scale")) sscanf(Value, "%lf", &rsp->Scale); - else if (!stricmp(Header, "Server")) rsp->Server = strdup(Value); + else if (!stricmp(Header, "Server")) rsp->Server = gf_strdup(Value); else if (!stricmp(Header, "Speed")) sscanf(Value, "%lf", &rsp->Speed); - else if (!stricmp(Header, "Timestamp")) rsp->Timestamp = strdup(Value); - else if (!stricmp(Header, "Unsupported")) rsp->Unsupported = strdup(Value); - else if (!stricmp(Header, "User-Agent")) rsp->User_Agent = strdup(Value); - else if (!stricmp(Header, "Vary")) rsp->Vary = strdup(Value); - else if (!stricmp(Header, "Via")) rsp->Vary = strdup(Value); - else if (!stricmp(Header, "WWW_Authenticate")) rsp->Vary = strdup(Value); + else if (!stricmp(Header, "Timestamp")) rsp->Timestamp = gf_strdup(Value); + else if (!stricmp(Header, "Unsupported")) rsp->Unsupported = gf_strdup(Value); + else if (!stricmp(Header, "User-Agent")) rsp->User_Agent = gf_strdup(Value); + else if (!stricmp(Header, "Vary")) rsp->Vary = gf_strdup(Value); + else if (!stricmp(Header, "Via")) rsp->Vary = gf_strdup(Value); + else if (!stricmp(Header, "WWW_Authenticate")) rsp->Vary = gf_strdup(Value); else if (!stricmp(Header, "Transport")) { LinePos = 0; while (1) { @@ -248,7 +251,7 @@ void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value) //Session else if (!stricmp(Header, "Session")) { LinePos = gf_token_get(Value, 0, ";\r\n", LineBuffer, 400); - rsp->Session = strdup(LineBuffer); + rsp->Session = gf_strdup(LineBuffer); //get timeout if any if (Value[LinePos] == ';') { LinePos += 1; @@ -271,16 +274,16 @@ void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value) GF_SAFEALLOC(info, GF_RTPInfo); Pos = 0; while (1) { - Pos = gf_token_get(LineBuffer, Pos, " ;", buf, 100); + Pos = gf_token_get(LineBuffer, Pos, " ;", buf, 1000); if (Pos <= 0) break; if (strstr(buf, "=")) { nPos = gf_token_get(buf, 0, "=", param_name, 100); nPos += 1; - nPos = gf_token_get(buf, nPos, "", param_val, 100); + nPos = gf_token_get(buf, nPos, "", param_val, 1000); } else { strcpy(param_name, buf); } - if (!stricmp(param_name, "url")) info->url = strdup(param_val); + if (!stricmp(param_name, "url")) info->url = gf_strdup(param_val); else if (!stricmp(param_name, "seq")) sscanf(param_val, "%d", &info->seq); else if (!stricmp(param_name, "rtptime")) { sscanf(param_val, "%i", &s_val); @@ -296,10 +299,10 @@ void gf_rtsp_set_response_value(GF_RTSPResponse *rsp, char *Header, char *Value) } //check for extended attributes else if (!strnicmp(Header, "x-", 2)) { - x_Att = (GF_X_Attribute*)malloc(sizeof(GF_X_Attribute)); - x_Att->Name = strdup(Header+2); + x_Att = (GF_X_Attribute*)gf_malloc(sizeof(GF_X_Attribute)); + x_Att->Name = gf_strdup(Header+2); x_Att->Value = NULL; - if (Value && strlen(Value)) x_Att->Value = strdup(Value); + if (Value && strlen(Value)) x_Att->Value = gf_strdup(Value); gf_list_add(rsp->Xtensions, x_Att); } //unknown field - skip it @@ -332,7 +335,7 @@ GF_Err RTSP_ParseResponseHeader(GF_RTSPSession *sess, GF_RTSPResponse *rsp, u32 rsp->ResponseCode = atoi(ValBuf); //string info Pos = gf_token_get(LineBuffer, Pos, "\t\r\n", ValBuf, 400); - if (Pos > 0) rsp->ResponseInfo = strdup(ValBuf); + if (Pos > 0) rsp->ResponseInfo = gf_strdup(ValBuf); return gf_rtsp_parse_header(buffer + ret, Size - ret, BodyStart, NULL, rsp); } @@ -391,7 +394,7 @@ GF_Err gf_rtsp_get_response(GF_RTSPSession *sess, GF_RTSPResponse *rsp) //copy the body if any if (!e && rsp->Content_Length) { - rsp->body = (char *)malloc(sizeof(char) * (rsp->Content_Length)); + rsp->body = (char *)gf_malloc(sizeof(char) * (rsp->Content_Length)); memcpy(rsp->body, sess->TCPBuffer+sess->CurrentPos + BodyStart, rsp->Content_Length); } @@ -483,7 +486,7 @@ GF_Err RTSP_WriteResponse(GF_RTSPSession *sess, GF_RTSPResponse *rsp, *out_buffer = NULL; size = RTSP_WRITE_STEPALLOC; - buffer = (char *) malloc(size); + buffer = (char *) gf_malloc(size); cur_pos = 0; //RTSP line @@ -519,7 +522,7 @@ GF_Err RTSP_WriteResponse(GF_RTSPSession *sess, GF_RTSPResponse *rsp, //if we have a body write the content length if (rsp->body) { RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "Content-Length: "); - RTSP_WRITE_INT(buffer, size, cur_pos, strlen(rsp->body), 0); + RTSP_WRITE_INT(buffer, size, cur_pos, (u32) strlen(rsp->body), 0); RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "\r\n"); } RTSP_WRITE_HEADER(buffer, size, cur_pos, "Content-Location", rsp->Content_Location); @@ -637,7 +640,7 @@ GF_Err RTSP_WriteResponse(GF_RTSPSession *sess, GF_RTSPResponse *rsp, } } if (trans->port_first) { - RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, trans->IsUnicast ? ";server_port=" : ";port="); + RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, (const char *) (trans->IsUnicast ? ";server_port=" : ";port=")); RTSP_WRITE_INT(buffer, size, cur_pos, trans->port_first, 0); RTSP_WRITE_ALLOC_STR(buffer, size, cur_pos, "-"); RTSP_WRITE_INT(buffer, size, cur_pos, trans->port_last, 0); @@ -702,7 +705,8 @@ GF_Err gf_rtsp_send_response(GF_RTSPSession *sess, GF_RTSPResponse *rsp) // printf("RTSP Send Response\n\n%s\n\n", buffer); exit: - if (buffer) free(buffer); + if (buffer) gf_free(buffer); return e; } +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/ietf/rtsp_session.c b/src/ietf/rtsp_session.c index 322963e..5667b28 100644 --- a/src/ietf/rtsp_session.c +++ b/src/ietf/rtsp_session.c @@ -25,11 +25,8 @@ #include <gpac/internal/ietf_dev.h> #include <gpac/base_coding.h> -#ifdef _WIN32_WCE -#define RTSP_TRACE 0 -#else -#define RTSP_TRACE 1 -#endif + +#ifndef GPAC_DISABLE_STREAMING GF_Err RTSP_UnpackURL(char *sURL, char *Server, u16 *Port, char *Service, Bool *useTCP) @@ -136,8 +133,8 @@ GF_RTSPSession *gf_rtsp_session_new(char *sURL, u16 DefaultPort) sess->HasTunnel = 1; } - sess->Server = strdup(server); - sess->Service = strdup(service); + sess->Server = gf_strdup(server); + sess->Service = gf_strdup(service); sess->mx = gf_mx_new("RTSPSession"); sess->TCPChannels = gf_list_new(); gf_rtsp_session_reset(sess, 0); @@ -170,7 +167,7 @@ void RemoveTCPChannels(GF_RTSPSession *sess) GF_TCPChan *ch; while (gf_list_count(sess->TCPChannels)) { ch = (GF_TCPChan*)gf_list_get(sess->TCPChannels, 0); - free(ch); + gf_free(ch); gf_list_rem(sess->TCPChannels, 0); } } @@ -212,13 +209,13 @@ void gf_rtsp_session_del(GF_RTSPSession *sess) if (sess->connection) gf_sk_del(sess->connection); if (sess->http) gf_sk_del(sess->http); - if (sess->Server) free(sess->Server); - if (sess->Service) free(sess->Service); + if (sess->Server) gf_free(sess->Server); + if (sess->Service) gf_free(sess->Service); gf_list_del(sess->TCPChannels); - if (sess->rtsp_pck_buf) free(sess->rtsp_pck_buf); - if (sess->MobileIP) free(sess->MobileIP); + if (sess->rtsp_pck_buf) gf_free(sess->rtsp_pck_buf); + if (sess->MobileIP) gf_free(sess->MobileIP); gf_mx_del(sess->mx); - free(sess); + gf_free(sess); } GF_EXPORT @@ -236,9 +233,9 @@ u32 gf_rtsp_get_session_state(GF_RTSPSession *sess) GF_EXPORT void gf_rtsp_set_mobile_ip(GF_RTSPSession *sess, char *MobileIP) { - if (sess->MobileIP) free(sess->MobileIP); + if (sess->MobileIP) gf_free(sess->MobileIP); sess->MobileIP = NULL; - if (MobileIP) sess->MobileIP = strdup(MobileIP); + if (MobileIP) sess->MobileIP = gf_strdup(MobileIP); } @@ -409,7 +406,7 @@ GF_Err gf_rtsp_set_deinterleave(GF_RTSPSession *sess) sess->payloadSize = paySize; sess->pck_start = Size-4; if (sess->rtsp_pck_size < paySize) { - sess->rtsp_pck_buf = (char *)realloc(sess->rtsp_pck_buf, sizeof(char)*paySize); + sess->rtsp_pck_buf = (char *)gf_realloc(sess->rtsp_pck_buf, sizeof(char)*paySize); sess->rtsp_pck_size = paySize; } memcpy(sess->rtsp_pck_buf, buffer+4, Size-4); @@ -499,7 +496,7 @@ u32 gf_rtsp_unregister_interleave(GF_RTSPSession *sess, u8 LowInterID) gf_mx_p(sess->mx); ptr = GetTCPChannel(sess, LowInterID, LowInterID, 1); - if (ptr) free(ptr); + if (ptr) gf_free(ptr); gf_mx_v(sess->mx); return gf_list_count(sess->TCPChannels); } @@ -515,7 +512,7 @@ GF_Err gf_rtsp_register_interleave(GF_RTSPSession *sess, void *the_ch, u8 LowInt //do NOT register twice ptr = GetTCPChannel(sess, LowInterID, HighInterID, 0); if (!ptr) { - ptr = (GF_TCPChan *)malloc(sizeof(GF_TCPChan)); + ptr = (GF_TCPChan *)gf_malloc(sizeof(GF_TCPChan)); ptr->ch_ptr = the_ch; ptr->rtpID = LowInterID; ptr->rtcpID = HighInterID; @@ -538,13 +535,13 @@ GF_Err gf_rtsp_set_interleave_callback(GF_RTSPSession *sess, //only if existing if (SignalData) sess->RTSP_SignalData = SignalData; - //realloc or alloc + //gf_realloc or alloc if (sess->rtsp_pck_buf && sess->rtsp_pck_size != RTSP_PCK_SIZE) { sess->rtsp_pck_size = RTSP_PCK_SIZE; - sess->rtsp_pck_buf = (char *)realloc(sess->rtsp_pck_buf, sizeof(char)*sess->rtsp_pck_size); + sess->rtsp_pck_buf = (char *)gf_realloc(sess->rtsp_pck_buf, sizeof(char)*sess->rtsp_pck_size); } else if (!sess->rtsp_pck_buf) { sess->rtsp_pck_size = RTSP_PCK_SIZE; - sess->rtsp_pck_buf = (char *)realloc(sess->rtsp_pck_buf, sizeof(char)*sess->rtsp_pck_size); + sess->rtsp_pck_buf = (char *)gf_realloc(sess->rtsp_pck_buf, sizeof(char)*sess->rtsp_pck_size); sess->pck_start = 0; } gf_mx_v(sess->mx); @@ -691,7 +688,7 @@ GF_RTSPSession *gf_rtsp_session_new_server(GF_Socket *rtsp_listener) sess->Port = port; sess->ConnectionType = fam; gf_sk_get_host_name(name); - sess->Server = strdup(name); + sess->Server = gf_strdup(name); sess->TCPChannels = gf_list_new(); return sess; @@ -717,8 +714,8 @@ GF_Err gf_rtsp_load_service_name(GF_RTSPSession *sess, char *URL) if (sess->Port != Port) return GF_URL_ERROR; //ok - sess->Server = strdup(server); - sess->Service = strdup(service); + sess->Server = gf_strdup(server); + sess->Service = gf_strdup(service); return GF_OK; } @@ -726,7 +723,7 @@ GF_Err gf_rtsp_load_service_name(GF_RTSPSession *sess, char *URL) GF_EXPORT char *gf_rtsp_generate_session_id(GF_RTSPSession *sess) { - u32 one, two; + u32 one; u64 res; char buffer[30]; @@ -737,13 +734,11 @@ char *gf_rtsp_generate_session_id(GF_RTSPSession *sess) gf_rand_init(0); } one = gf_rand(); - //try to be as random as possible. if we had some global stats that'd be better - two = (u32) sess + sess->CurrentPos + sess->CurrentSize; res = one; res <<= 32; - res += two; + res += (u64) sess + sess->CurrentPos + sess->CurrentSize; sprintf(buffer, LLU, res); - return strdup(buffer); + return gf_strdup(buffer); } @@ -778,3 +773,5 @@ GF_Err gf_rtsp_get_remote_address(GF_RTSPSession *sess, char *buf) if (!sess || !sess->connection) return GF_BAD_PARAM; return gf_sk_get_remote_address(sess->connection, buf); } + +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/ietf/sdp.c b/src/ietf/sdp.c index 5135146..0aba723 100644 --- a/src/ietf/sdp.c +++ b/src/ietf/sdp.c @@ -25,15 +25,19 @@ #include <gpac/ietf.h> + +#ifndef GPAC_DISABLE_STREAMING + #include <gpac/token.h> + #define SDP_WRITE_STEPALLOC 2048 GF_EXPORT GF_SDP_FMTP *gf_sdp_fmtp_new() { - GF_SDP_FMTP *tmp = (GF_SDP_FMTP*)malloc(sizeof(GF_SDP_FMTP)); + GF_SDP_FMTP *tmp = (GF_SDP_FMTP*)gf_malloc(sizeof(GF_SDP_FMTP)); tmp->PayloadType = 0; tmp->Attributes = gf_list_new(); return tmp; @@ -47,12 +51,12 @@ void gf_sdp_fmtp_del(GF_SDP_FMTP *fmtp) while (gf_list_count(fmtp->Attributes)) { att = (GF_X_Attribute*)gf_list_get(fmtp->Attributes, 0); gf_list_rem(fmtp->Attributes, 0); - if (att->Name) free(att->Name); - if (att->Value) free(att->Value); - free(att); + if (att->Name) gf_free(att->Name); + if (att->Value) gf_free(att->Value); + gf_free(att); } gf_list_del(fmtp->Attributes); - free(fmtp); + gf_free(fmtp); } GF_SDP_FMTP *SDP_GetFMTPForPayload(GF_SDPMedia *media, u32 PayloadType) @@ -81,19 +85,19 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) if (!strcmp(comp, "cat")) { if (media) return; pos = gf_token_get(buffer, pos, ":\t\r\n", comp, 3000); - sdp->a_cat = strdup(comp); + sdp->a_cat = gf_strdup(comp); return; } if (!strcmp(comp, "keywds")) { if (media) return; pos = gf_token_get(buffer, pos, ":\t\r\n", comp, 3000); - sdp->a_keywds = strdup(comp); + sdp->a_keywds = gf_strdup(comp); return; } if (!strcmp(comp, "tool")) { if (media) return; pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000); - sdp->a_tool = strdup(comp); + sdp->a_tool = gf_strdup(comp); return; } @@ -130,36 +134,36 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) if (!strcmp(comp, "orient")) { if (!media || media->Type) return; pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000); - media->orientation = strdup(comp); + media->orientation = gf_strdup(comp); return; } if (!strcmp(comp, "type")) { if (media) return; pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000); - sdp->a_type = strdup(comp); + sdp->a_type = gf_strdup(comp); return; } if (!strcmp(comp, "charset")) { if (media) return; pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000); - sdp->a_charset = strdup(comp); + sdp->a_charset = gf_strdup(comp); return; } if (!strcmp(comp, "sdplang")) { pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000); if (media) { - media->sdplang = strdup(comp); + media->sdplang = gf_strdup(comp); } else { - sdp->a_sdplang = strdup(comp); + sdp->a_sdplang = gf_strdup(comp); } return; } if (!strcmp(comp, "lang")) { pos = gf_token_get(buffer, pos, ":\r\n", comp, 3000); if (media) { - media->lang = strdup(comp); + media->lang = gf_strdup(comp); } else { - sdp->a_lang = strdup(comp); + sdp->a_lang = gf_strdup(comp); } return; } @@ -178,11 +182,11 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) } if (!strcmp(comp, "rtpmap")) { if (!media) return; - map = (GF_RTPMap*)malloc(sizeof(GF_RTPMap)); + map = (GF_RTPMap*)gf_malloc(sizeof(GF_RTPMap)); pos = gf_token_get(buffer, pos, ": \r\n", comp, 3000); map->PayloadType = atoi(comp); pos = gf_token_get(buffer, pos, " /\r\n", comp, 3000); - map->payload_name = strdup(comp); + map->payload_name = gf_strdup(comp); pos = gf_token_get(buffer, pos, " /\r\n", comp, 3000); map->ClockRate = atoi(comp); pos = gf_token_get(buffer, pos, " /\r\n", comp, 3000); @@ -204,12 +208,12 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) while (1) { pos = gf_token_get(buffer, pos, "; =\r\n", comp, 3000); if (pos <= 0) break; - att = (GF_X_Attribute*)malloc(sizeof(GF_X_Attribute)); - att->Name = strdup(comp); + att = (GF_X_Attribute*)gf_malloc(sizeof(GF_X_Attribute)); + att->Name = gf_strdup(comp); att->Value = NULL; pos ++; pos = gf_token_get(buffer, pos, ";\r\n", comp, 3000); - if (pos > 0) att->Value = strdup(comp); + if (pos > 0) att->Value = gf_strdup(comp); gf_list_add(fmtp->Attributes, att); } return; @@ -219,13 +223,13 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) //a= <attribute> || <attribute>:<value> //we add <attribute> <value> in case ... pos = gf_token_get(buffer, 0, " :\r\n", comp, 3000); - att = (GF_X_Attribute*)malloc(sizeof(GF_X_Attribute)); - att->Name = strdup(comp); + att = (GF_X_Attribute*)gf_malloc(sizeof(GF_X_Attribute)); + att->Name = gf_strdup(comp); att->Value = NULL; pos += 1; if (buffer[pos] == ' ') pos += 1; pos = gf_token_get(buffer, pos, "\r\n", comp, 3000); - if (pos > 0) att->Value = strdup(comp); + if (pos > 0) att->Value = gf_strdup(comp); if (media) { gf_list_add(media->Attributes, att); @@ -236,7 +240,7 @@ void SDP_ParseAttribute(GF_SDPInfo *sdp, char *buffer, GF_SDPMedia *media) -#define SDPM_DESTROY(p) if (media->p) free(media->p) +#define SDPM_DESTROY(p) if (media->p) gf_free(media->p) GF_EXPORT void gf_sdp_media_del(GF_SDPMedia *media) { @@ -257,16 +261,16 @@ void gf_sdp_media_del(GF_SDPMedia *media) while (gf_list_count(media->Attributes)) { att = (GF_X_Attribute*)gf_list_get(media->Attributes, 0); gf_list_rem(media->Attributes, 0); - if (att->Name) free(att->Name); - if (att->Value) free(att->Value); - free(att); + if (att->Name) gf_free(att->Name); + if (att->Value) gf_free(att->Value); + gf_free(att); } gf_list_del(media->Attributes); while (gf_list_count(media->RTPMaps)) { map = (GF_RTPMap*)gf_list_get(media->RTPMaps, 0); - free(map->payload_name); - free(map); + gf_free(map->payload_name); + gf_free(map); gf_list_rem(media->RTPMaps, 0); } gf_list_del(media->RTPMaps); @@ -281,8 +285,8 @@ void gf_sdp_media_del(GF_SDPMedia *media) while (gf_list_count(media->Bandwidths)) { bw = (GF_SDPBandwidth*)gf_list_get(media->Bandwidths, 0); gf_list_rem(media->Bandwidths, 0); - if (bw->name) free(bw->name); - free(bw); + if (bw->name) gf_free(bw->name); + gf_free(bw); } gf_list_del(media->Bandwidths); @@ -293,7 +297,7 @@ void gf_sdp_media_del(GF_SDPMedia *media) SDPM_DESTROY(fmt_list); SDPM_DESTROY(k_method); SDPM_DESTROY(k_key); - free(media); + gf_free(media); } @@ -309,10 +313,10 @@ GF_SDPConnection *gf_sdp_conn_new() GF_EXPORT void gf_sdp_conn_del(GF_SDPConnection *conn) { - if (conn->add_type) free(conn->add_type); - if (conn->host) free(conn->host); - if (conn->net_type) free(conn->net_type); - free(conn); + if (conn->add_type) gf_free(conn->add_type); + if (conn->host) gf_free(conn->host); + if (conn->net_type) gf_free(conn->net_type); + gf_free(conn); } GF_EXPORT @@ -342,7 +346,7 @@ GF_SDPInfo *gf_sdp_info_new() } #define SDP_DESTROY(p) if (sdp->p) \ - free(sdp->p); \ + gf_free(sdp->p); \ sdp->p = NULL; @@ -364,20 +368,20 @@ void gf_sdp_info_reset(GF_SDPInfo *sdp) while (gf_list_count(sdp->Attributes)) { att = (GF_X_Attribute*)gf_list_get(sdp->Attributes, 0); gf_list_rem(sdp->Attributes, 0); - if (att->Name) free(att->Name); - if (att->Value) free(att->Value); - free(att); + if (att->Name) gf_free(att->Name); + if (att->Value) gf_free(att->Value); + gf_free(att); } while (gf_list_count(sdp->b_bandwidth)) { bw = (GF_SDPBandwidth*)gf_list_get(sdp->b_bandwidth, 0); gf_list_rem(sdp->b_bandwidth, 0); - if (bw->name) free(bw->name); - free(bw); + if (bw->name) gf_free(bw->name); + gf_free(bw); } while (gf_list_count(sdp->Timing)) { timing = (GF_SDPTiming*)gf_list_get(sdp->Timing, 0); gf_list_rem(sdp->Timing, 0); - free(timing); + gf_free(timing); } //then delete all info ... @@ -418,7 +422,7 @@ void gf_sdp_info_del(GF_SDPInfo *sdp) gf_list_del(sdp->Attributes); gf_list_del(sdp->b_bandwidth); gf_list_del(sdp->Timing); - free(sdp); + gf_free(sdp); } @@ -498,40 +502,40 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) break; case 'o': pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000); - sdp->o_username = strdup(comp); + sdp->o_username = gf_strdup(comp); pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); - sdp->o_session_id = strdup(comp); + sdp->o_session_id = gf_strdup(comp); pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); - sdp->o_version = strdup(comp); + sdp->o_version = gf_strdup(comp); pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); - sdp->o_net_type = strdup(comp); + sdp->o_net_type = gf_strdup(comp); pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); - sdp->o_add_type = strdup(comp); + sdp->o_add_type = gf_strdup(comp); pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); - sdp->o_address = strdup(comp); + sdp->o_address = gf_strdup(comp); break; case 's': pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); - sdp->s_session_name = strdup(comp); + sdp->s_session_name = gf_strdup(comp); break; case 'i': pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); - sdp->i_description = strdup(comp); + sdp->i_description = gf_strdup(comp); break; case 'u': pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); - sdp->u_uri = strdup(comp); + sdp->u_uri = gf_strdup(comp); break; case 'e': pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); - sdp->e_email = strdup(comp); + sdp->e_email = gf_strdup(comp); break; case 'p': pos = gf_token_get(LineBuf, 2, "\t\r\n", comp, 3000); - sdp->p_phone = strdup(comp); + sdp->p_phone = gf_strdup(comp); break; case 'c': //if at session level, only 1 is allowed for all SDP @@ -540,23 +544,21 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) conn = gf_sdp_conn_new(); pos = gf_token_get(LineBuf, 2, " \t\r\n", comp, 3000); - conn->net_type = strdup(comp); + conn->net_type = gf_strdup(comp); pos = gf_token_get(LineBuf, pos, " \t\r\n", comp, 3000); - conn->add_type = strdup(comp); + conn->add_type = gf_strdup(comp); pos = gf_token_get(LineBuf, pos, " /\r\n", comp, 3000); - conn->host = strdup(comp); + conn->host = gf_strdup(comp); if (gf_sk_is_multicast_address(conn->host)) { //a valid SDP will have TTL if address is multicast pos = gf_token_get(LineBuf, pos, "/\r\n", comp, 3000); - if (pos <= 0) { - gf_sdp_conn_del(conn); - break; + if (pos > 0) { + conn->TTL = atoi(comp); + //multiple address indication is only valid for media + pos = gf_token_get(LineBuf, pos, "/\r\n", comp, 3000); } - conn->TTL = atoi(comp); - //multiple address indication is only valid for media - pos = gf_token_get(LineBuf, pos, "/\r\n", comp, 3000); if (pos > 0) { if (!media) { gf_sdp_conn_del(conn); @@ -575,8 +577,8 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) pos = gf_token_get(LineBuf, 2, ":\r\n", comp, 3000); if (strcmp(comp, "CT") && strcmp(comp, "AS") && (comp[0] != 'X')) break; - bw = (GF_SDPBandwidth*)malloc(sizeof(GF_SDPBandwidth)); - bw->name = strdup(comp); + bw = (GF_SDPBandwidth*)gf_malloc(sizeof(GF_SDPBandwidth)); + bw->name = gf_strdup(comp); pos = gf_token_get(LineBuf, pos, ":\r\n", comp, 3000); bw->value = atoi(comp); if (media) { @@ -624,16 +626,16 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) case 'k': pos = gf_token_get(LineBuf, 2, ":\t\r\n", comp, 3000); if (media) { - media->k_method = strdup(comp); + media->k_method = gf_strdup(comp); } else { - sdp->k_method = strdup(comp); + sdp->k_method = gf_strdup(comp); } pos = gf_token_get(LineBuf, pos, ":\r\n", comp, 3000); if (pos > 0) { if (media) { - media->k_key = strdup(comp); + media->k_key = gf_strdup(comp); } else { - sdp->k_key = strdup(comp); + sdp->k_key = gf_strdup(comp); } } break; @@ -672,9 +674,9 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) } //transport Profile pos = gf_token_get(LineBuf, pos, " \r\n", comp, 3000); - media->Profile = strdup(comp); + media->Profile = gf_strdup(comp); pos = gf_token_get(LineBuf, pos, " \r\n", comp, 3000); - media->fmt_list = strdup(comp); + media->fmt_list = gf_strdup(comp); gf_list_add(sdp->media_desc, media); break; @@ -699,10 +701,10 @@ GF_Err gf_sdp_info_parse(GF_SDPInfo *sdp, char *sdp_text, u32 text_size) } strcat(LineBuf, comp); } - free(media->fmt_list); + gf_free(media->fmt_list); media->fmt_list = NULL; if (strlen(LineBuf)) { - media->fmt_list = strdup(LineBuf); + media->fmt_list = gf_strdup(LineBuf); } } } @@ -745,7 +747,8 @@ GF_Err gf_sdp_info_check(GF_SDPInfo *sdp) if (!sdp->o_add_type || !sdp->o_address || !sdp->o_username || !sdp->o_session_id || !sdp->o_version) return GF_REMOTE_SERVICE_ERROR; //s= - if (!sdp->s_session_name) return GF_REMOTE_SERVICE_ERROR; + //commented for intermedia demos +// if (!sdp->s_session_name) return GF_REMOTE_SERVICE_ERROR; //t= // if () return GF_REMOTE_SERVICE_ERROR; //c= @@ -807,7 +810,7 @@ GF_Err gf_sdp_info_check(GF_SDPInfo *sdp) if (str) { \ if (strlen(str)+pos + (space ? 1 : 0) >= buf_size) { \ buf_size += SDP_WRITE_STEPALLOC; \ - buf = (char*)realloc(buf, sizeof(char)*buf_size); \ + buf = (char*)gf_realloc(buf, sizeof(char)*buf_size); \ } \ strcpy(buf+pos, str); \ pos += strlen(str); \ @@ -873,7 +876,7 @@ GF_Err gf_sdp_info_write(GF_SDPInfo *sdp, char **out_str_buf) e = gf_sdp_info_check(sdp); if (e) return e; - buf = (char *)malloc(SDP_WRITE_STEPALLOC); + buf = (char *)gf_malloc(SDP_WRITE_STEPALLOC); buf_size = SDP_WRITE_STEPALLOC; pos = 0; @@ -1143,11 +1146,12 @@ GF_Err gf_sdp_info_write(GF_SDPInfo *sdp, char **out_str_buf) } } - //finally realloc + //finally gf_realloc //finall NULL char pos += 1; - buf = (char *)realloc(buf, pos); + buf = (char *)gf_realloc(buf, pos); *out_str_buf = buf; return GF_OK; } +#endif /*GPAC_DISABLE_STREAMING*/ diff --git a/src/isomedia/avc_ext.c b/src/isomedia/avc_ext.c index 2eeb0f5..6119265 100644 --- a/src/isomedia/avc_ext.c +++ b/src/isomedia/avc_ext.c @@ -25,14 +25,51 @@ #include <gpac/internal/isomedia_dev.h> #include <gpac/constants.h> +#ifndef GPAC_DISABLE_ISOM + +static GF_AVCConfig *AVC_DuplicateConfig(GF_AVCConfig *cfg) +{ + u32 i, count; + GF_AVCConfigSlot *p1, *p2; + GF_AVCConfig *cfg_new = gf_odf_avc_cfg_new(); + cfg_new->AVCLevelIndication = cfg->AVCLevelIndication; + cfg_new->AVCProfileIndication = cfg->AVCProfileIndication; + cfg_new->configurationVersion = cfg->configurationVersion; + cfg_new->nal_unit_size = cfg->nal_unit_size; + cfg_new->profile_compatibility = cfg->profile_compatibility; + cfg_new->complete_representation = cfg->complete_representation; + + count = gf_list_count(cfg->sequenceParameterSets); + for (i=0; i<count; i++) { + p1 = (GF_AVCConfigSlot*)gf_list_get(cfg->sequenceParameterSets, 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->sequenceParameterSets, p2); + } + + count = gf_list_count(cfg->pictureParameterSets); + for (i=0; i<count; i++) { + p1 = (GF_AVCConfigSlot*)gf_list_get(cfg->pictureParameterSets, 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->pictureParameterSets, p2); + } + return cfg_new; +} + void AVC_RewriteESDescriptor(GF_MPEGVisualSampleEntryBox *avc) { + GF_AVCConfig *avcc, *svcc; if (avc->emul_esd) gf_odf_desc_del((GF_Descriptor *)avc->emul_esd); avc->emul_esd = gf_odf_desc_esd_new(2); avc->emul_esd->decoderConfig->streamType = GF_STREAM_VISUAL; /*AVC OTI is 0x21, AVC parameter set stream OTI (not supported in gpac) is 0x22*/ - avc->emul_esd->decoderConfig->objectTypeIndication = 0x21; + avc->emul_esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_AVC; if (avc->bitrate) { avc->emul_esd->decoderConfig->bufferSizeDB = avc->bitrate->bufferSizeDB; avc->emul_esd->decoderConfig->avgBitrate = avc->bitrate->avgBitrate; @@ -49,8 +86,31 @@ void AVC_RewriteESDescriptor(GF_MPEGVisualSampleEntryBox *avc) gf_odf_desc_del(clone); } } - if (avc->avc_config && avc->avc_config->config) { - gf_odf_avc_cfg_write(avc->avc_config->config, &avc->emul_esd->decoderConfig->decoderSpecificInfo->data, &avc->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); + if (avc->avc_config) { + avcc = avc->avc_config->config ? AVC_DuplicateConfig(avc->avc_config->config) : NULL; + /*merge SVC config*/ + if (avc->svc_config) { + svcc = AVC_DuplicateConfig(avc->svc_config->config); + while (gf_list_count(svcc->sequenceParameterSets)) { + GF_AVCConfigSlot *p = (GF_AVCConfigSlot*)gf_list_get(svcc->sequenceParameterSets, 0); + gf_list_rem(svcc->sequenceParameterSets, 0); + gf_list_add(avcc->sequenceParameterSets, p); + } + while (gf_list_count(svcc->pictureParameterSets)) { + GF_AVCConfigSlot *p = (GF_AVCConfigSlot*)gf_list_get(svcc->pictureParameterSets, 0); + gf_list_rem(svcc->pictureParameterSets, 0); + gf_list_add(avcc->pictureParameterSets, p); + } + gf_odf_avc_cfg_del(svcc); + } + if (avcc) { + gf_odf_avc_cfg_write(avcc, &avc->emul_esd->decoderConfig->decoderSpecificInfo->data, &avc->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); + gf_odf_avc_cfg_del(avcc); + } + } else { + svcc = AVC_DuplicateConfig(avc->svc_config->config); + gf_odf_avc_cfg_write(svcc, &avc->emul_esd->decoderConfig->decoderSpecificInfo->data, &avc->emul_esd->decoderConfig->decoderSpecificInfo->dataLength); + gf_odf_avc_cfg_del(svcc); } } @@ -96,50 +156,20 @@ GF_Err AVC_UpdateESD(GF_MPEGVisualSampleEntryBox *avc, GF_ESD *esd) } /*update GF_AVCConfig*/ - if (!avc->avc_config) avc->avc_config = (GF_AVCConfigurationBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_AVCC); - if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { - if (avc->avc_config->config) gf_odf_avc_cfg_del(avc->avc_config->config); - avc->avc_config->config = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + if (!avc->svc_config) { + if (!avc->avc_config) avc->avc_config = (GF_AVCConfigurationBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_AVCC); + if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { + if (avc->avc_config->config) gf_odf_avc_cfg_del(avc->avc_config->config); + avc->avc_config->config = gf_odf_avc_cfg_read(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); + } + gf_odf_desc_del((GF_Descriptor *)esd); } - gf_odf_desc_del((GF_Descriptor *)esd); AVC_RewriteESDescriptor(avc); return GF_OK; } -static GF_AVCConfig *AVC_DuplicateConfig(GF_AVCConfig *cfg) -{ - u32 i, count; - GF_AVCConfigSlot *p1, *p2; - GF_AVCConfig *cfg_new = gf_odf_avc_cfg_new(); - cfg_new->AVCLevelIndication = cfg->AVCLevelIndication; - cfg_new->AVCProfileIndication = cfg->AVCProfileIndication; - cfg_new->configurationVersion = cfg->configurationVersion; - cfg_new->nal_unit_size = cfg->nal_unit_size; - cfg_new->profile_compatibility = cfg->profile_compatibility; - - count = gf_list_count(cfg->sequenceParameterSets); - for (i=0; i<count; i++) { - p1 = (GF_AVCConfigSlot*)gf_list_get(cfg->sequenceParameterSets, i); - p2 = (GF_AVCConfigSlot*)malloc(sizeof(GF_AVCConfigSlot)); - p2->size = p1->size; - p2->data = (char *)malloc(sizeof(char)*p1->size); - memcpy(p2->data, p1->data, sizeof(char)*p1->size); - gf_list_add(cfg_new->sequenceParameterSets, p2); - } - - count = gf_list_count(cfg->pictureParameterSets); - for (i=0; i<count; i++) { - p1 = (GF_AVCConfigSlot*)gf_list_get(cfg->pictureParameterSets, i); - p2 = (GF_AVCConfigSlot*)malloc(sizeof(GF_AVCConfigSlot)); - p2->size = p1->size; - p2->data = (char*)malloc(sizeof(char)*p1->size); - memcpy(p2->data, p1->data, sizeof(char)*p1->size); - gf_list_add(cfg_new->pictureParameterSets, p2); - } - return cfg_new; -} -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_avc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfig *cfg, char *URLname, char *URNname, u32 *outDescriptionIndex) { GF_TrackBox *trak; @@ -174,7 +204,7 @@ GF_Err gf_isom_avc_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AVCConfi return e; } -GF_Err gf_isom_avc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg) +static GF_Err gf_isom_avc_config_update_ex(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg, u32 op_type) { GF_TrackBox *trak; GF_Err e; @@ -186,14 +216,56 @@ GF_Err gf_isom_avc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 Desc if (!trak || !trak->Media || !cfg || !DescriptionIndex) return GF_BAD_PARAM; entry = (GF_MPEGVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1); if (!entry) return GF_BAD_PARAM; - if (entry->type != GF_ISOM_BOX_TYPE_AVC1) 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->avc_config->config) gf_odf_avc_cfg_del(entry->avc_config->config); - entry->avc_config->config = AVC_DuplicateConfig(cfg); + switch (op_type) { + /*AVCC replacement*/ + case 0: + if (!entry->avc_config) entry->avc_config = (GF_AVCConfigurationBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_AVCC); + if (entry->avc_config->config) gf_odf_avc_cfg_del(entry->avc_config->config); + entry->avc_config->config = AVC_DuplicateConfig(cfg); + entry->type = GF_ISOM_BOX_TYPE_AVC1; + break; + /*SVCC replacement*/ + case 1: + if (!entry->svc_config) entry->svc_config = (GF_AVCConfigurationBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_SVCC); + if (entry->svc_config->config) gf_odf_avc_cfg_del(entry->svc_config->config); + entry->svc_config->config = AVC_DuplicateConfig(cfg); + entry->type = GF_ISOM_BOX_TYPE_AVC1; + break; + /*SVCC replacement and AVC removal*/ + case 2: + if (entry->avc_config) { + gf_isom_box_del((GF_Box*)entry->avc_config); + entry->avc_config = NULL; + } + if (!entry->svc_config) entry->svc_config = (GF_AVCConfigurationBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_SVCC); + if (entry->svc_config->config) gf_odf_avc_cfg_del(entry->svc_config->config); + entry->svc_config->config = AVC_DuplicateConfig(cfg); + entry->type = GF_ISOM_BOX_TYPE_SVC1; + break; + } AVC_RewriteESDescriptor(entry); return GF_OK; } +GF_Err gf_isom_avc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg) +{ + return gf_isom_avc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, 0); +} + +GF_Err gf_isom_svc_config_update(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex, GF_AVCConfig *cfg, Bool is_add) +{ + return gf_isom_avc_config_update_ex(the_file, trackNumber, DescriptionIndex, cfg, is_add ? 1 : 2); +} + GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber) { static const u8 ipod_ext[][16] = { { 0x6B, 0x68, 0x40, 0xF2, 0x5F, 0x24, 0x4F, 0xC5, 0xBA, 0x39, 0xA5, 0x1B, 0xCF, 0x03, 0x23, 0xF3} }; @@ -207,7 +279,14 @@ GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber) if (!trak || !trak->Media) return GF_BAD_PARAM; entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 0); if (!entry) return GF_OK; - if (entry->type != GF_ISOM_BOX_TYPE_AVC1) return GF_OK; + 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_OK; + } if (!entry->ipod_ext) entry->ipod_ext = (GF_UnknownUUIDBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_UUID); memcpy(entry->ipod_ext->uuid, ipod_ext, sizeof(u8)*16); @@ -215,7 +294,7 @@ GF_Err gf_isom_set_ipod_compatible(GF_ISOFile *the_file, u32 trackNumber) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_EXPORT GF_AVCConfig *gf_isom_avc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 DescriptionIndex) @@ -231,10 +310,23 @@ GF_AVCConfig *gf_isom_avc_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 return AVC_DuplicateConfig(entry->avc_config->config); } +GF_EXPORT +GF_AVCConfig *gf_isom_svc_config_get(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 NULL; + entry = (GF_MPEGVisualSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, DescriptionIndex-1); + if (!entry) return NULL; + if (!entry->svc_config) return NULL; + return AVC_DuplicateConfig(entry->svc_config->config); +} + void btrt_del(GF_Box *s) { GF_MPEG4BitRateBox *ptr = (GF_MPEG4BitRateBox *)s; - if (ptr) free(ptr); + if (ptr) gf_free(ptr); } GF_Err btrt_Read(GF_Box *s, GF_BitStream *bs) { @@ -246,14 +338,14 @@ GF_Err btrt_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *btrt_New() { - GF_MPEG4BitRateBox *tmp = (GF_MPEG4BitRateBox *) malloc(sizeof(GF_MPEG4BitRateBox)); + GF_MPEG4BitRateBox *tmp = (GF_MPEG4BitRateBox *) gf_malloc(sizeof(GF_MPEG4BitRateBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_MPEG4BitRateBox)); tmp->type = GF_ISOM_BOX_TYPE_BTRT; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err btrt_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -274,7 +366,7 @@ GF_Err btrt_Size(GF_Box *s) ptr->size += 12; return e; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -283,7 +375,7 @@ void m4ds_del(GF_Box *s) GF_MPEG4ExtensionDescriptorsBox *ptr = (GF_MPEG4ExtensionDescriptorsBox *)s; gf_odf_desc_list_del(ptr->descriptors); gf_list_del(ptr->descriptors); - free(ptr); + gf_free(ptr); } GF_Err m4ds_Read(GF_Box *s, GF_BitStream *bs) { @@ -292,15 +384,15 @@ GF_Err m4ds_Read(GF_Box *s, GF_BitStream *bs) GF_MPEG4ExtensionDescriptorsBox *ptr = (GF_MPEG4ExtensionDescriptorsBox *)s; u32 od_size = (u32) ptr->size; if (!od_size) return GF_OK; - enc_od = (char *)malloc(sizeof(char) * od_size); + enc_od = (char *)gf_malloc(sizeof(char) * od_size); gf_bs_read_data(bs, enc_od, od_size); e = gf_odf_desc_list_read((char *)enc_od, od_size, ptr->descriptors); - free(enc_od); + gf_free(enc_od); return e; } GF_Box *m4ds_New() { - GF_MPEG4ExtensionDescriptorsBox *tmp = (GF_MPEG4ExtensionDescriptorsBox *) malloc(sizeof(GF_MPEG4ExtensionDescriptorsBox)); + GF_MPEG4ExtensionDescriptorsBox *tmp = (GF_MPEG4ExtensionDescriptorsBox *) gf_malloc(sizeof(GF_MPEG4ExtensionDescriptorsBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_MPEG4ExtensionDescriptorsBox)); tmp->type = GF_ISOM_BOX_TYPE_M4DS; @@ -308,7 +400,7 @@ GF_Box *m4ds_New() return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err m4ds_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -324,7 +416,7 @@ GF_Err m4ds_Write(GF_Box *s, GF_BitStream *bs) if (e) return e; if (enc_od_size) { gf_bs_write_data(bs, enc_ods, enc_od_size); - free(enc_ods); + gf_free(enc_ods); } return GF_OK; } @@ -338,7 +430,7 @@ GF_Err m4ds_Size(GF_Box *s) ptr->size += descSize; return e; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -346,7 +438,7 @@ void avcc_del(GF_Box *s) { GF_AVCConfigurationBox *ptr = (GF_AVCConfigurationBox *)s; if (ptr->config) gf_odf_avc_cfg_del(ptr->config); - free(ptr); + gf_free(ptr); } GF_Err avcc_Read(GF_Box *s, GF_BitStream *bs) { @@ -359,24 +451,29 @@ GF_Err avcc_Read(GF_Box *s, GF_BitStream *bs) ptr->config->AVCProfileIndication = gf_bs_read_u8(bs); ptr->config->profile_compatibility = gf_bs_read_u8(bs); ptr->config->AVCLevelIndication = gf_bs_read_u8(bs); - gf_bs_read_int(bs, 6); + if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) { + gf_bs_read_int(bs, 6); + } else { + ptr->config->complete_representation = gf_bs_read_int(bs, 1); + gf_bs_read_int(bs, 5); + } ptr->config->nal_unit_size = 1 + gf_bs_read_int(bs, 2); gf_bs_read_int(bs, 3); count = gf_bs_read_int(bs, 5); for (i=0; i<count; i++) { - GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *) malloc(sizeof(GF_AVCConfigSlot)); + GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *) gf_malloc(sizeof(GF_AVCConfigSlot)); sl->size = gf_bs_read_u16(bs); - sl->data = (char *)malloc(sizeof(char) * sl->size); + 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); } count = gf_bs_read_u8(bs); for (i=0; i<count; i++) { - GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)malloc(sizeof(GF_AVCConfigSlot)); + GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_malloc(sizeof(GF_AVCConfigSlot)); sl->size = gf_bs_read_u16(bs); - sl->data = (char *)malloc(sizeof(char) * sl->size); + 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); } @@ -384,14 +481,14 @@ GF_Err avcc_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *avcc_New() { - GF_AVCConfigurationBox *tmp = (GF_AVCConfigurationBox *) malloc(sizeof(GF_MPEG4BitRateBox)); + GF_AVCConfigurationBox *tmp = (GF_AVCConfigurationBox *) gf_malloc(sizeof(GF_AVCConfigurationBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_AVCConfigurationBox)); tmp->type = GF_ISOM_BOX_TYPE_AVCC; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err avcc_Write(GF_Box *s, GF_BitStream *bs) { u32 i, count; @@ -406,7 +503,12 @@ GF_Err avcc_Write(GF_Box *s, GF_BitStream *bs) gf_bs_write_u8(bs, ptr->config->AVCProfileIndication); gf_bs_write_u8(bs, ptr->config->profile_compatibility); gf_bs_write_u8(bs, ptr->config->AVCLevelIndication); - gf_bs_write_int(bs, 0x3F, 6); + if (ptr->type==GF_ISOM_BOX_TYPE_AVCC) { + gf_bs_write_int(bs, 0x3F, 6); + } else { + gf_bs_write_int(bs, ptr->config->complete_representation, 1); + gf_bs_write_int(bs, 0x1F, 5); + } gf_bs_write_int(bs, ptr->config->nal_unit_size - 1, 2); gf_bs_write_int(bs, 0x7, 3); count = gf_list_count(ptr->config->sequenceParameterSets); @@ -444,6 +546,7 @@ GF_Err avcc_Size(GF_Box *s) for (i=0; i<count; i++) ptr->size += 2 + ((GF_AVCConfigSlot *)gf_list_get(ptr->config->pictureParameterSets, i))->size; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/box_code_3gpp.c b/src/isomedia/box_code_3gpp.c index 9394f89..27d5fef 100644 --- a/src/isomedia/box_code_3gpp.c +++ b/src/isomedia/box_code_3gpp.c @@ -24,13 +24,15 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + void gppa_del(GF_Box *s) { GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s; if (ptr == NULL) return; if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info); if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info); - free(ptr); + gf_free(ptr); } @@ -56,8 +58,7 @@ GF_Box *gppa_New(u32 type) return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gppa_Write(GF_Box *s, GF_BitStream *bs) { @@ -83,7 +84,7 @@ GF_Err gppa_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *gppv_New(u32 type) @@ -101,7 +102,7 @@ void gppv_del(GF_Box *s) if (ptr == NULL) return; if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info); if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info); - free(ptr); + gf_free(ptr); } GF_Err gppv_Read(GF_Box *s, GF_BitStream *bs) @@ -115,8 +116,7 @@ GF_Err gppv_Read(GF_Box *s, GF_BitStream *bs) return e; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gppv_Write(GF_Box *s, GF_BitStream *bs) { @@ -143,12 +143,12 @@ GF_Err gppv_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *gppc_New(u32 type) { - GF_3GPPConfigBox *tmp = (GF_3GPPConfigBox *) malloc(sizeof(GF_3GPPConfigBox)); + GF_3GPPConfigBox *tmp = (GF_3GPPConfigBox *) gf_malloc(sizeof(GF_3GPPConfigBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_3GPPConfigBox)); tmp->type = type; @@ -159,7 +159,7 @@ void gppc_del(GF_Box *s) { GF_3GPPConfigBox *ptr = (GF_3GPPConfigBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } @@ -191,8 +191,7 @@ GF_Err gppc_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gppc_Write(GF_Box *s, GF_BitStream *bs) { @@ -248,7 +247,7 @@ GF_Err gppc_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *ftab_New() @@ -265,23 +264,23 @@ void ftab_del(GF_Box *s) if (ptr->fonts) { u32 i; for (i=0; i<ptr->entry_count; i++) - if (ptr->fonts[i].fontName) free(ptr->fonts[i].fontName); - free(ptr->fonts); + if (ptr->fonts[i].fontName) gf_free(ptr->fonts[i].fontName); + gf_free(ptr->fonts); } - free(ptr); + gf_free(ptr); } GF_Err ftab_Read(GF_Box *s, GF_BitStream *bs) { u32 i; GF_FontTableBox *ptr = (GF_FontTableBox *)s; ptr->entry_count = gf_bs_read_u16(bs); - ptr->fonts = (GF_FontRecord *) malloc(sizeof(GF_FontRecord)*ptr->entry_count); + ptr->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord)*ptr->entry_count); for (i=0; i<ptr->entry_count; i++) { u32 len; ptr->fonts[i].fontID = gf_bs_read_u16(bs); len = gf_bs_read_u8(bs); if (len) { - ptr->fonts[i].fontName = (char *)malloc(sizeof(char)*(len+1)); + ptr->fonts[i].fontName = (char *)gf_malloc(sizeof(char)*(len+1)); gf_bs_read_data(bs, ptr->fonts[i].fontName, len); ptr->fonts[i].fontName[len] = 0; } @@ -289,7 +288,7 @@ GF_Err ftab_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ftab_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -324,25 +323,44 @@ GF_Err ftab_Size(GF_Box *s) return GF_OK; } -#endif - +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -GF_Box *tx3g_New() +GF_Box *text_New() { GF_TextSampleEntryBox *tmp; GF_SAFEALLOC(tmp, GF_TextSampleEntryBox); - if (!tmp) return NULL; + if (!tmp) + return NULL; + tmp->type = GF_ISOM_BOX_TYPE_TEXT; + return (GF_Box *) tmp; +} + +void text_del(GF_Box *s) +{ + GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; + if (ptr->textName) + gf_free(ptr->textName); + gf_free(ptr); +} + +GF_Box *tx3g_New() +{ + GF_Tx3gSampleEntryBox *tmp; + GF_SAFEALLOC(tmp, GF_Tx3gSampleEntryBox); + if (!tmp) + return NULL; tmp->type = GF_ISOM_BOX_TYPE_TX3G; return (GF_Box *) tmp; } void tx3g_del(GF_Box *s) { - GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; - if (ptr->font_table) gf_isom_box_del((GF_Box *)ptr->font_table); - free(ptr); + GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; + if (ptr->font_table) + gf_isom_box_del((GF_Box *)ptr->font_table); + gf_free(ptr); } static u32 gpp_read_rgba(GF_BitStream *bs) @@ -384,7 +402,7 @@ GF_Err tx3g_Read(GF_Box *s, GF_BitStream *bs) { GF_Err e; GF_Box *a; - GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; + GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; if (ptr->size < 18 + GPP_BOX_SIZE + GPP_STYLE_SIZE) return GF_ISOM_INVALID_FILE; @@ -413,6 +431,47 @@ GF_Err tx3g_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } +/*this is a quicktime specific box - see apple documentation*/ +GF_Err text_Read(GF_Box *s, GF_BitStream *bs) +{ + u16 pSize; + GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; + gf_bs_read_data(bs, ptr->reserved, 6); + ptr->dataReferenceIndex = gf_bs_read_u16(bs); + + ptr->displayFlags = gf_bs_read_u32(bs); /*Display flags*/ + ptr->textJustification = gf_bs_read_u32(bs); /*Text justification*/ + gf_bs_read_data(bs, ptr->background_color, 6); /*Background color*/ + gpp_read_box(bs, &ptr->default_box); /*Default text box*/ + gf_bs_read_data(bs, ptr->reserved1, 8); /*Reserved*/ + ptr->fontNumber = gf_bs_read_u16(bs); /*Font number*/ + ptr->fontFace = gf_bs_read_u16(bs); /*Font face*/ + ptr->reserved2 = gf_bs_read_u8(bs); /*Reserved*/ + ptr->reserved3 = gf_bs_read_u16(bs); /*Reserved*/ + gf_bs_read_data(bs, ptr->foreground_color, 6); /*Foreground color*/ + if (ptr->size < 51) + return GF_ISOM_INVALID_FILE; + ptr->size -= 51; + if (!ptr->size) + return GF_OK; /*ffmpeg compatibility with iPod streams: no pascal string*/ + + pSize = gf_bs_read_u8(bs); /*a Pascal string begins with its size: get textName size*/ + ptr->size -= 1; + if (ptr->size < pSize) + return GF_ISOM_INVALID_FILE; + if (pSize) { + ptr->textName = (char*) gf_malloc(pSize+1 * sizeof(char)); + if (gf_bs_read_data(bs, ptr->textName, pSize) != pSize) { + gf_free(ptr->textName); + ptr->textName = NULL; + return GF_ISOM_INVALID_FILE; + } + ptr->textName[pSize] = '\0'; /*Font name*/ + } + ptr->size -= pSize; + + return GF_OK; +} void gpp_write_rgba(GF_BitStream *bs, u32 col) { @@ -441,12 +500,12 @@ void gpp_write_style(GF_BitStream *bs, GF_StyleRecord *rec) gpp_write_rgba(bs, rec->text_color); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tx3g_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; - GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; + GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; e = gf_isom_box_write_header(s, bs); if (e) return e; @@ -461,9 +520,38 @@ GF_Err tx3g_Write(GF_Box *s, GF_BitStream *bs) return gf_isom_box_write((GF_Box *) ptr->font_table, bs); } -GF_Err tx3g_Size(GF_Box *s) +GF_Err text_Write(GF_Box *s, GF_BitStream *bs) { + GF_Err e; + u16 pSize; GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; + + e = gf_isom_box_write_header(s, bs); + if (e) return e; + gf_bs_write_data(bs, ptr->reserved, 6); + gf_bs_write_u16(bs, ptr->dataReferenceIndex); + gf_bs_write_u32(bs, ptr->displayFlags); /*Display flags*/ + gf_bs_write_u32(bs, ptr->textJustification); /*Text justification*/ + gf_bs_write_data(bs, ptr->background_color, 6); /*Background color*/ + gpp_write_box(bs, &ptr->default_box); /*Default text box*/ + gf_bs_write_data(bs, ptr->reserved1, 8); /*Reserved*/ + gf_bs_write_u16(bs, ptr->fontNumber); /*Font number*/ + gf_bs_write_u16(bs, ptr->fontFace); /*Font face*/ + gf_bs_write_u8(bs, ptr->reserved2); /*Reserved*/ + gf_bs_write_u16(bs, ptr->reserved3); /*Reserved*/ + gf_bs_write_data(bs, ptr->foreground_color, 6); /*Foreground color*/ + if (ptr->textName && (pSize=strlen(ptr->textName))) { + gf_bs_write_u8(bs, pSize); /*a Pascal string begins with its size*/ + gf_bs_write_data(bs, ptr->textName, pSize); /*Font name*/ + } else { + gf_bs_write_u8(bs, 0); + } + return GF_OK; +} + +GF_Err tx3g_Size(GF_Box *s) +{ + GF_Tx3gSampleEntryBox *ptr = (GF_Tx3gSampleEntryBox*)s; GF_Err e = gf_isom_box_get_size(s); if (e) return e; /*base + this + box + style*/ @@ -476,6 +564,18 @@ GF_Err tx3g_Size(GF_Box *s) return GF_OK; } +GF_Err text_Size(GF_Box *s) +{ + GF_TextSampleEntryBox *ptr = (GF_TextSampleEntryBox*)s; + GF_Err e = gf_isom_box_get_size(s); + if (e) return e; + /*base + this + string length*/ + s->size += 51 + 1; + if (ptr->textName) + s->size += strlen(ptr->textName); + return GF_OK; +} + #endif GF_Box *styl_New() @@ -490,8 +590,8 @@ GF_Box *styl_New() void styl_del(GF_Box *s) { GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; - if (ptr->styles) free(ptr->styles); - free(ptr); + if (ptr->styles) gf_free(ptr->styles); + gf_free(ptr); } GF_Err styl_Read(GF_Box *s, GF_BitStream *bs) @@ -500,7 +600,7 @@ GF_Err styl_Read(GF_Box *s, GF_BitStream *bs) GF_TextStyleBox*ptr = (GF_TextStyleBox*)s; ptr->entry_count = gf_bs_read_u16(bs); if (ptr->entry_count) { - ptr->styles = (GF_StyleRecord*)malloc(sizeof(GF_StyleRecord)*ptr->entry_count); + ptr->styles = (GF_StyleRecord*)gf_malloc(sizeof(GF_StyleRecord)*ptr->entry_count); for (i=0; i<ptr->entry_count; i++) { gpp_read_style(bs, &ptr->styles[i]); } @@ -508,7 +608,7 @@ GF_Err styl_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err styl_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -530,7 +630,7 @@ GF_Err styl_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *hlit_New() { @@ -543,7 +643,7 @@ GF_Box *hlit_New() void hlit_del(GF_Box *s) { - free(s); + gf_free(s); } GF_Err hlit_Read(GF_Box *s, GF_BitStream *bs) @@ -554,7 +654,7 @@ GF_Err hlit_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err hlit_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -574,7 +674,7 @@ GF_Err hlit_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *hclr_New() { @@ -587,7 +687,7 @@ GF_Box *hclr_New() void hclr_del(GF_Box *s) { - free(s); + gf_free(s); } GF_Err hclr_Read(GF_Box *s, GF_BitStream *bs) @@ -597,7 +697,7 @@ GF_Err hclr_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err hclr_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -616,7 +716,7 @@ GF_Err hclr_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *krok_New() { @@ -630,8 +730,8 @@ GF_Box *krok_New() void krok_del(GF_Box *s) { GF_TextKaraokeBox*ptr = (GF_TextKaraokeBox*)s; - if (ptr->records) free(ptr->records); - free(ptr); + if (ptr->records) gf_free(ptr->records); + gf_free(ptr); } GF_Err krok_Read(GF_Box *s, GF_BitStream *bs) @@ -642,7 +742,7 @@ GF_Err krok_Read(GF_Box *s, GF_BitStream *bs) ptr->nb_entries = gf_bs_read_u16(bs); if (ptr->nb_entries) { u32 i; - ptr->records = (KaraokeRecord*)malloc(sizeof(KaraokeRecord)*ptr->nb_entries); + ptr->records = (KaraokeRecord*)gf_malloc(sizeof(KaraokeRecord)*ptr->nb_entries); for (i=0; i<ptr->nb_entries; i++) { ptr->records[i].highlight_endtime = gf_bs_read_u32(bs); ptr->records[i].start_charoffset = gf_bs_read_u16(bs); @@ -652,7 +752,7 @@ GF_Err krok_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err krok_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -680,7 +780,7 @@ GF_Err krok_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *dlay_New() { @@ -693,7 +793,7 @@ GF_Box *dlay_New() void dlay_del(GF_Box *s) { - free(s); + gf_free(s); } GF_Err dlay_Read(GF_Box *s, GF_BitStream *bs) @@ -703,7 +803,7 @@ GF_Err dlay_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err dlay_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -722,7 +822,7 @@ GF_Err dlay_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *href_New() { @@ -736,9 +836,9 @@ GF_Box *href_New() void href_del(GF_Box *s) { GF_TextHyperTextBox*ptr = (GF_TextHyperTextBox*)s; - if (ptr->URL) free(ptr->URL); - if (ptr->URL_hint) free(ptr->URL_hint); - free(ptr); + if (ptr->URL) gf_free(ptr->URL); + if (ptr->URL_hint) gf_free(ptr->URL_hint); + gf_free(ptr); } GF_Err href_Read(GF_Box *s, GF_BitStream *bs) @@ -749,20 +849,20 @@ GF_Err href_Read(GF_Box *s, GF_BitStream *bs) ptr->endcharoffset = gf_bs_read_u16(bs); len = gf_bs_read_u8(bs); if (len) { - ptr->URL = (char *) malloc(sizeof(char) * (len+1)); + ptr->URL = (char *) gf_malloc(sizeof(char) * (len+1)); gf_bs_read_data(bs, ptr->URL, len); ptr->URL[len] = 0; } len = gf_bs_read_u8(bs); if (len) { - ptr->URL_hint = (char *) malloc(sizeof(char) * (len+1)); + ptr->URL_hint = (char *) gf_malloc(sizeof(char) * (len+1)); gf_bs_read_data(bs, ptr->URL_hint, len); ptr->URL_hint[len]= 0; } return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err href_Write(GF_Box *s, GF_BitStream *bs) { u32 len; @@ -801,7 +901,7 @@ GF_Err href_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *tbox_New() @@ -815,7 +915,7 @@ GF_Box *tbox_New() void tbox_del(GF_Box *s) { - free(s); + gf_free(s); } GF_Err tbox_Read(GF_Box *s, GF_BitStream *bs) @@ -825,7 +925,7 @@ GF_Err tbox_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tbox_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -844,7 +944,7 @@ GF_Err tbox_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *blnk_New() @@ -858,7 +958,7 @@ GF_Box *blnk_New() void blnk_del(GF_Box *s) { - free(s); + gf_free(s); } GF_Err blnk_Read(GF_Box *s, GF_BitStream *bs) @@ -869,7 +969,7 @@ GF_Err blnk_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err blnk_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -889,7 +989,7 @@ GF_Err blnk_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *twrp_New() { @@ -902,7 +1002,7 @@ GF_Box *twrp_New() void twrp_del(GF_Box *s) { - free(s); + gf_free(s); } GF_Err twrp_Read(GF_Box *s, GF_BitStream *bs) @@ -912,7 +1012,7 @@ GF_Err twrp_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err twrp_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -930,15 +1030,15 @@ GF_Err twrp_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void tsel_del(GF_Box *s) { GF_TrackSelectionBox *ptr; ptr = (GF_TrackSelectionBox *) s; if (ptr == NULL) return; - if (ptr->attributeList) free(ptr->attributeList); - free(ptr); + if (ptr->attributeList) gf_free(ptr->attributeList); + gf_free(ptr); } GF_Err tsel_Read(GF_Box *s,GF_BitStream *bs) @@ -952,7 +1052,7 @@ GF_Err tsel_Read(GF_Box *s,GF_BitStream *bs) ptr->size -= 4; if (ptr->size % 4) return GF_ISOM_INVALID_FILE; ptr->attributeListCount = (u32)ptr->size/4; - ptr->attributeList = malloc(ptr->attributeListCount*sizeof(u32)); + ptr->attributeList = gf_malloc(ptr->attributeListCount*sizeof(u32)); if (ptr->attributeList == NULL) return GF_OUT_OF_MEM; for (i=0; i< ptr->attributeListCount; i++) { @@ -965,7 +1065,7 @@ GF_Box *tsel_New() { GF_TrackSelectionBox *tmp; - tmp = (GF_TrackSelectionBox *) malloc(sizeof(GF_TrackSelectionBox)); + tmp = (GF_TrackSelectionBox *) gf_malloc(sizeof(GF_TrackSelectionBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_TrackSelectionBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -974,8 +1074,7 @@ GF_Box *tsel_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tsel_Write(GF_Box *s, GF_BitStream *bs) { @@ -1004,8 +1103,7 @@ GF_Err tsel_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY - +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *dimC_New() @@ -1021,9 +1119,9 @@ GF_Box *dimC_New() void dimC_del(GF_Box *s) { GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; - if (p->contentEncoding) free(p->contentEncoding); - if (p->textEncoding) free(p->textEncoding); - free(p); + if (p->contentEncoding) gf_free(p->contentEncoding); + if (p->textEncoding) gf_free(p->textEncoding); + gf_free(p); } GF_Err dimC_Read(GF_Box *s, GF_BitStream *bs) @@ -1051,7 +1149,7 @@ GF_Err dimC_Read(GF_Box *s, GF_BitStream *bs) } if (s->size < i) return GF_ISOM_INVALID_FILE; s->size -= i; - p->textEncoding = strdup(str); + p->textEncoding = gf_strdup(str); i=0; str[0]=0; @@ -1062,11 +1160,11 @@ GF_Err dimC_Read(GF_Box *s, GF_BitStream *bs) } if (s->size < i) return GF_ISOM_INVALID_FILE; s->size -= i; - p->contentEncoding = strdup(str); + p->contentEncoding = gf_strdup(str); return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err dimC_Write(GF_Box *s, GF_BitStream *bs) { GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)s; @@ -1090,7 +1188,7 @@ GF_Err dimC_Size(GF_Box *s) s->size += 3 + 1 + strlen(p->textEncoding) + 1 + strlen(p->contentEncoding); return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -1106,8 +1204,8 @@ GF_Box *diST_New() void diST_del(GF_Box *s) { GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; - if (p->content_script_types) free(p->content_script_types); - free(p); + if (p->content_script_types) gf_free(p->content_script_types); + gf_free(p); } GF_Err diST_Read(GF_Box *s, GF_BitStream *bs) @@ -1125,11 +1223,11 @@ GF_Err diST_Read(GF_Box *s, GF_BitStream *bs) } if (s->size < i) return GF_ISOM_INVALID_FILE; s->size -= i; - p->content_script_types = strdup(str); + p->content_script_types = gf_strdup(str); return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err diST_Write(GF_Box *s, GF_BitStream *bs) { GF_DIMSScriptTypesBox *p = (GF_DIMSScriptTypesBox *)s; @@ -1149,7 +1247,7 @@ GF_Err diST_Size(GF_Box *s) s->size += p->content_script_types ? (strlen(p->content_script_types)+1) : 1; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *dims_New() @@ -1166,7 +1264,7 @@ void dims_del(GF_Box *s) 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); - free(p); + gf_free(p); } static GF_Err dims_AddBox(GF_Box *s, GF_Box *a) @@ -1204,7 +1302,7 @@ GF_Err dims_Read(GF_Box *s, GF_BitStream *bs) return gf_isom_read_box_list(s, bs, dims_AddBox); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err dims_Write(GF_Box *s, GF_BitStream *bs) { GF_DIMSSampleEntryBox *p = (GF_DIMSSampleEntryBox *)s; @@ -1260,4 +1358,6 @@ GF_Err dims_Size(GF_Box *s) } return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/box_code_apple.c b/src/isomedia/box_code_apple.c index 550b621..7a92d5e 100644 --- a/src/isomedia/box_code_apple.c +++ b/src/isomedia/box_code_apple.c @@ -10,12 +10,14 @@ License: see License.txt in the top level directory. #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + void ilst_del(GF_Box *s) { GF_ItemListBox *ptr = (GF_ItemListBox *)s; if (ptr == NULL) return; gf_isom_box_array_del(ptr->tags); - free(ptr); + gf_free(ptr); } GF_Err ilst_Read(GF_Box *s, GF_BitStream *bs) @@ -43,7 +45,7 @@ GF_Err ilst_Read(GF_Box *s, GF_BitStream *bs) GF_Box *ilst_New() { - GF_ItemListBox *tmp = (GF_ItemListBox *) malloc(sizeof(GF_ItemListBox)); + 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; @@ -51,8 +53,7 @@ GF_Box *ilst_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ilst_Write(GF_Box *s, GF_BitStream *bs) { @@ -77,17 +78,17 @@ GF_Err ilst_Size(GF_Box *s) return gf_isom_box_array_size(s, ptr->tags); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void ListItem_del(GF_Box *s) { GF_ListItemBox *ptr = (GF_ListItemBox *) s; if (ptr == NULL) return; if (ptr->data != NULL) { - if (ptr->data->data) free(ptr->data->data); - free(ptr->data); + if (ptr->data->data) gf_free(ptr->data->data); + gf_free(ptr->data); } - free(ptr); + gf_free(ptr); } GF_Err ListItem_Read(GF_Box *s,GF_BitStream *bs) @@ -113,7 +114,7 @@ GF_Err ListItem_Read(GF_Box *s,GF_BitStream *bs) ptr->data->type = 0; ptr->data->dataSize = gf_bs_read_u16(bs); gf_bs_read_u16(bs); - ptr->data->data = (char *) malloc(sizeof(char)*(ptr->data->dataSize + 1)); + ptr->data->data = (char *) gf_malloc(sizeof(char)*(ptr->data->dataSize + 1)); gf_bs_read_data(bs, ptr->data->data, ptr->data->dataSize); ptr->data->data[ptr->data->dataSize] = 0; ptr->size -= ptr->data->dataSize; @@ -125,7 +126,7 @@ GF_Box *ListItem_New(u32 type) { GF_ListItemBox *tmp; - tmp = (GF_ListItemBox *) malloc(sizeof(GF_ListItemBox)); + tmp = (GF_ListItemBox *) gf_malloc(sizeof(GF_ListItemBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ListItemBox)); @@ -134,15 +135,14 @@ GF_Box *ListItem_New(u32 type) tmp->data = (GF_DataBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_DATA); if (tmp->data == NULL){ - free(tmp); + gf_free(tmp); return NULL; } return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ListItem_Write(GF_Box *s, GF_BitStream *bs) { @@ -182,15 +182,15 @@ GF_Err ListItem_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void data_del(GF_Box *s) { GF_DataBox *ptr = (GF_DataBox *) s; if (ptr == NULL) return; if (ptr->data) - free(ptr->data); - free(ptr); + gf_free(ptr->data); + gf_free(ptr); } @@ -205,7 +205,7 @@ GF_Err data_Read(GF_Box *s,GF_BitStream *bs) ptr->size -= 4; if (ptr->size) { ptr->dataSize = (u32) ptr->size; - ptr->data = (char*)malloc(ptr->dataSize * sizeof(ptr->data[0]) + 1); + ptr->data = (char*)gf_malloc(ptr->dataSize * sizeof(ptr->data[0]) + 1); if (ptr->data == NULL) return GF_OUT_OF_MEM; ptr->data[ptr->dataSize] = 0; gf_bs_read_data(bs, ptr->data, ptr->dataSize); @@ -218,7 +218,7 @@ GF_Box *data_New() { GF_DataBox *tmp; - tmp = (GF_DataBox *) malloc(sizeof(GF_DataBox)); + tmp = (GF_DataBox *) gf_malloc(sizeof(GF_DataBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_DataBox)); @@ -228,8 +228,7 @@ GF_Box *data_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err data_Write(GF_Box *s, GF_BitStream *bs) { @@ -258,7 +257,7 @@ GF_Err data_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_MetaBox *gf_isom_apple_get_meta_extensions(GF_ISOFile *mov) { @@ -281,7 +280,7 @@ GF_MetaBox *gf_isom_apple_get_meta_extensions(GF_ISOFile *mov) return NULL; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_MetaBox *gf_isom_apple_create_meta_extensions(GF_ISOFile *mov) { GF_Err e; @@ -320,5 +319,7 @@ GF_MetaBox *gf_isom_apple_create_meta_extensions(GF_ISOFile *mov) return meta; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/box_code_base.c b/src/isomedia/box_code_base.c index 236e213..b861640 100644 --- a/src/isomedia/box_code_base.c +++ b/src/isomedia/box_code_base.c @@ -24,13 +24,15 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + void co64_del(GF_Box *s) { GF_ChunkLargeOffsetBox *ptr; ptr = (GF_ChunkLargeOffsetBox *) s; if (ptr == NULL) return; - if (ptr->offsets) free(ptr->offsets); - free(ptr); + if (ptr->offsets) gf_free(ptr->offsets); + gf_free(ptr); } GF_Err co64_Read(GF_Box *s,GF_BitStream *bs) @@ -41,7 +43,7 @@ GF_Err co64_Read(GF_Box *s,GF_BitStream *bs) e = gf_isom_full_box_read(s, bs); if (e) return e; ptr->nb_entries = gf_bs_read_u32(bs); - ptr->offsets = (u64 *) malloc(ptr->nb_entries * sizeof(u64) ); + ptr->offsets = (u64 *) gf_malloc(ptr->nb_entries * sizeof(u64) ); if (ptr->offsets == NULL) return GF_OUT_OF_MEM; ptr->alloc_size = ptr->nb_entries; for (entries = 0; entries < ptr->nb_entries; entries++) { @@ -54,7 +56,7 @@ GF_Box *co64_New() { GF_ChunkLargeOffsetBox *tmp; - tmp = (GF_ChunkLargeOffsetBox *) malloc(sizeof(GF_ChunkLargeOffsetBox)); + tmp = (GF_ChunkLargeOffsetBox *) gf_malloc(sizeof(GF_ChunkLargeOffsetBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ChunkLargeOffsetBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -63,8 +65,7 @@ GF_Box *co64_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err co64_Write(GF_Box *s, GF_BitStream *bs) { @@ -91,15 +92,15 @@ GF_Err co64_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void cprt_del(GF_Box *s) { GF_CopyrightBox *ptr = (GF_CopyrightBox *) s; if (ptr == NULL) return; if (ptr->notice) - free(ptr->notice); - free(ptr); + gf_free(ptr->notice); + gf_free(ptr); } @@ -107,9 +108,9 @@ GF_Box *chpl_New() { GF_ChapterListBox *tmp; - tmp = (GF_ChapterListBox *) malloc(sizeof(GF_ChapterListBox)); + tmp = (GF_ChapterListBox *) gf_malloc(sizeof(GF_ChapterListBox)); if (tmp == NULL) return NULL; - memset(tmp, 0, sizeof(GF_CopyrightBox)); + memset(tmp, 0, sizeof(GF_ChapterListBox)); tmp->list = gf_list_new(); gf_isom_full_box_init((GF_Box *)tmp); tmp->type = GF_ISOM_BOX_TYPE_CHPL; @@ -123,12 +124,12 @@ void chpl_del(GF_Box *s) if (ptr == NULL) return; while (gf_list_count(ptr->list)) { GF_ChapterEntry *ce = (GF_ChapterEntry *)gf_list_get(ptr->list, 0); - if (ce->name) free(ce->name); - free(ce); + if (ce->name) gf_free(ce->name); + gf_free(ce); gf_list_rem(ptr->list, 0); } gf_list_del(ptr->list); - free(ptr); + gf_free(ptr); } /*this is using chpl format according to some NeroRecode samples*/ @@ -152,11 +153,11 @@ GF_Err chpl_Read(GF_Box *s,GF_BitStream *bs) ce->start_time = gf_bs_read_u64(bs); len = gf_bs_read_u8(bs); if (len) { - ce->name = (char *)malloc(sizeof(char)*(len+1)); + ce->name = (char *)gf_malloc(sizeof(char)*(len+1)); gf_bs_read_data(bs, ce->name, len); ce->name[len] = 0; } else { - ce->name = strdup(""); + ce->name = gf_strdup(""); } for (i=0;i<count; i++) { @@ -174,7 +175,7 @@ GF_Err chpl_Read(GF_Box *s,GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err chpl_Write(GF_Box *s, GF_BitStream *bs) { @@ -220,7 +221,7 @@ GF_Err chpl_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Err cprt_Read(GF_Box *s,GF_BitStream *bs) @@ -248,7 +249,7 @@ GF_Err cprt_Read(GF_Box *s,GF_BitStream *bs) } if (ptr->size) { u32 bytesToRead = (u32) ptr->size; - ptr->notice = (char*)malloc(bytesToRead * sizeof(char)); + ptr->notice = (char*)gf_malloc(bytesToRead * sizeof(char)); if (ptr->notice == NULL) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ptr->notice, bytesToRead); } @@ -259,7 +260,7 @@ GF_Box *cprt_New() { GF_CopyrightBox *tmp; - tmp = (GF_CopyrightBox *) malloc(sizeof(GF_CopyrightBox)); + tmp = (GF_CopyrightBox *) gf_malloc(sizeof(GF_CopyrightBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_CopyrightBox)); @@ -272,8 +273,7 @@ GF_Box *cprt_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err cprt_Write(GF_Box *s, GF_BitStream *bs) { @@ -308,13 +308,13 @@ GF_Err cprt_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void ctts_del(GF_Box *s) { GF_CompositionOffsetBox *ptr = (GF_CompositionOffsetBox *)s; - if (ptr->entries) free(ptr->entries); - free(ptr); + if (ptr->entries) gf_free(ptr->entries); + gf_free(ptr); } @@ -330,7 +330,7 @@ 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 = malloc(sizeof(GF_DttsEntry)*ptr->alloc_size); + ptr->entries = 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++) { @@ -338,7 +338,7 @@ GF_Err ctts_Read(GF_Box *s, GF_BitStream *bs) ptr->entries[i].decodingOffset = gf_bs_read_u32(bs); sampleCount += ptr->entries[i].sampleCount; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE ptr->w_LastSampleNumber = sampleCount; #endif return GF_OK; @@ -348,7 +348,7 @@ GF_Box *ctts_New() { GF_CompositionOffsetBox *tmp; - tmp = (GF_CompositionOffsetBox *) malloc(sizeof(GF_CompositionOffsetBox)); + tmp = (GF_CompositionOffsetBox *) gf_malloc(sizeof(GF_CompositionOffsetBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_CompositionOffsetBox)); @@ -359,8 +359,7 @@ GF_Box *ctts_New() -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ctts_Write(GF_Box *s, GF_BitStream *bs) { @@ -389,14 +388,14 @@ GF_Err ctts_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void url_del(GF_Box *s) { GF_DataEntryURLBox *ptr = (GF_DataEntryURLBox *)s; if (ptr == NULL) return; - if (ptr->location) free(ptr->location); - free(ptr); + if (ptr->location) gf_free(ptr->location); + gf_free(ptr); return; } @@ -409,7 +408,7 @@ GF_Err url_Read(GF_Box *s, GF_BitStream *bs) e = gf_isom_full_box_read(s, bs); if (e) return e; if (ptr->size) { - ptr->location = (char*)malloc((u32) ptr->size); + ptr->location = (char*)gf_malloc((u32) ptr->size); if (! ptr->location) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ptr->location, (u32)ptr->size); } @@ -418,7 +417,7 @@ GF_Err url_Read(GF_Box *s, GF_BitStream *bs) GF_Box *url_New() { - GF_DataEntryURLBox *tmp = (GF_DataEntryURLBox *) malloc(sizeof(GF_DataEntryURLBox)); + GF_DataEntryURLBox *tmp = (GF_DataEntryURLBox *) gf_malloc(sizeof(GF_DataEntryURLBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_DataEntryURLBox)); @@ -427,8 +426,7 @@ GF_Box *url_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err url_Write(GF_Box *s, GF_BitStream *bs) { @@ -459,15 +457,15 @@ GF_Err url_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void urn_del(GF_Box *s) { GF_DataEntryURNBox *ptr = (GF_DataEntryURNBox *)s; if (ptr == NULL) return; - if (ptr->location) free(ptr->location); - if (ptr->nameURN) free(ptr->nameURN); - free(ptr); + if (ptr->location) gf_free(ptr->location); + if (ptr->nameURN) gf_free(ptr->nameURN); + gf_free(ptr); } @@ -483,7 +481,7 @@ GF_Err urn_Read(GF_Box *s, GF_BitStream *bs) //here we have to handle that in a clever way to_read = (u32) ptr->size; - tmpName = (char*)malloc(sizeof(char) * to_read); + tmpName = (char*)gf_malloc(sizeof(char) * to_read); if (!tmpName) return GF_OUT_OF_MEM; //get the data gf_bs_read_data(bs, tmpName, to_read); @@ -495,7 +493,7 @@ GF_Err urn_Read(GF_Box *s, GF_BitStream *bs) } //check the data is consistent if (i == to_read) { - free(tmpName); + gf_free(tmpName); return GF_ISOM_INVALID_FILE; } //no NULL char, URL is not specified @@ -505,27 +503,27 @@ GF_Err urn_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } //OK, this has both URN and URL - ptr->nameURN = (char*)malloc(sizeof(char) * (i+1)); + ptr->nameURN = (char*)gf_malloc(sizeof(char) * (i+1)); if (!ptr->nameURN) { - free(tmpName); + gf_free(tmpName); return GF_OUT_OF_MEM; } - ptr->location = (char*)malloc(sizeof(char) * (to_read - i - 1)); + ptr->location = (char*)gf_malloc(sizeof(char) * (to_read - i - 1)); if (!ptr->location) { - free(tmpName); - free(ptr->nameURN); + gf_free(tmpName); + gf_free(ptr->nameURN); ptr->nameURN = NULL; return GF_OUT_OF_MEM; } memcpy(ptr->nameURN, tmpName, i + 1); memcpy(ptr->location, tmpName + i + 1, (to_read - i - 1)); - free(tmpName); + gf_free(tmpName); return GF_OK; } GF_Box *urn_New() { - GF_DataEntryURNBox *tmp = (GF_DataEntryURNBox *) malloc(sizeof(GF_DataEntryURNBox)); + GF_DataEntryURNBox *tmp = (GF_DataEntryURNBox *) gf_malloc(sizeof(GF_DataEntryURNBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_DataEntryURNBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -533,8 +531,7 @@ GF_Box *urn_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err urn_Write(GF_Box *s, GF_BitStream *bs) @@ -571,14 +568,14 @@ GF_Err urn_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void defa_del(GF_Box *s) { GF_UnknownBox *ptr = (GF_UnknownBox *) s; if (!s) return; - if (ptr->data) free(ptr->data); - free(ptr); + if (ptr->data) gf_free(ptr->data); + gf_free(ptr); } @@ -590,7 +587,7 @@ GF_Err defa_Read(GF_Box *s, GF_BitStream *bs) bytesToRead = (u32) (ptr->size); if (bytesToRead) { - ptr->data = (char*)malloc(bytesToRead); + ptr->data = (char*)gf_malloc(bytesToRead); if (ptr->data == NULL ) return GF_OUT_OF_MEM; ptr->dataSize = bytesToRead; gf_bs_read_data(bs, ptr->data, ptr->dataSize); @@ -601,13 +598,12 @@ 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 *) malloc(sizeof(GF_UnknownBox)); + GF_UnknownBox *tmp = (GF_UnknownBox *) gf_malloc(sizeof(GF_UnknownBox)); memset(tmp, 0, sizeof(GF_UnknownBox)); return (GF_Box *) tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err defa_Write(GF_Box *s, GF_BitStream *bs) { @@ -633,15 +629,15 @@ GF_Err defa_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void uuid_del(GF_Box *s) { GF_UnknownUUIDBox *ptr = (GF_UnknownUUIDBox *) s; if (!s) return; - if (ptr->data) free(ptr->data); - free(ptr); + if (ptr->data) gf_free(ptr->data); + gf_free(ptr); } @@ -653,7 +649,7 @@ GF_Err uuid_Read(GF_Box *s, GF_BitStream *bs) bytesToRead = (u32) (ptr->size); if (bytesToRead) { - ptr->data = (char*)malloc(bytesToRead); + ptr->data = (char*)gf_malloc(bytesToRead); if (ptr->data == NULL ) return GF_OUT_OF_MEM; ptr->dataSize = bytesToRead; gf_bs_read_data(bs, ptr->data, ptr->dataSize); @@ -664,14 +660,13 @@ GF_Err uuid_Read(GF_Box *s, GF_BitStream *bs) //warning: we don't have any boxType, trick has to be done while creating.. GF_Box *uuid_New() { - GF_UnknownUUIDBox *tmp = (GF_UnknownUUIDBox *) malloc(sizeof(GF_UnknownUUIDBox)); + GF_UnknownUUIDBox *tmp = (GF_UnknownUUIDBox *) gf_malloc(sizeof(GF_UnknownUUIDBox)); memset(tmp, 0, sizeof(GF_UnknownUUIDBox)); tmp->type = GF_ISOM_BOX_TYPE_UUID; return (GF_Box *) tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err uuid_Write(GF_Box *s, GF_BitStream *bs) { @@ -697,7 +692,7 @@ GF_Err uuid_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void dinf_del(GF_Box *s) @@ -705,7 +700,7 @@ void dinf_del(GF_Box *s) GF_DataInformationBox *ptr = (GF_DataInformationBox *)s; if (ptr == NULL) return; gf_isom_box_del((GF_Box *)ptr->dref); - free(ptr); + gf_free(ptr); } @@ -730,15 +725,14 @@ GF_Err dinf_Read(GF_Box *s, GF_BitStream *bs) GF_Box *dinf_New() { - GF_DataInformationBox *tmp = (GF_DataInformationBox *) malloc(sizeof(GF_DataInformationBox)); + 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; return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err dinf_Write(GF_Box *s, GF_BitStream *bs) { @@ -767,14 +761,14 @@ GF_Err dinf_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void dref_del(GF_Box *s) { GF_DataReferenceBox *ptr = (GF_DataReferenceBox *) s; if (ptr == NULL) return; gf_isom_box_array_del(ptr->boxList); - free(ptr); + gf_free(ptr); } @@ -808,14 +802,14 @@ GF_Err dref_Read(GF_Box *s, GF_BitStream *bs) GF_Box *dref_New() { - GF_DataReferenceBox *tmp = (GF_DataReferenceBox *) malloc(sizeof(GF_DataReferenceBox)); + GF_DataReferenceBox *tmp = (GF_DataReferenceBox *) gf_malloc(sizeof(GF_DataReferenceBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_DataReferenceBox)); gf_isom_full_box_init((GF_Box *) tmp); tmp->boxList = gf_list_new(); if (!tmp->boxList) { - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_DREF; @@ -823,8 +817,7 @@ GF_Box *dref_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err dref_Write(GF_Box *s, GF_BitStream *bs) { @@ -854,13 +847,13 @@ GF_Err dref_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void edts_del(GF_Box *s) { GF_EditBox *ptr = (GF_EditBox *) s; gf_isom_box_del((GF_Box *)ptr->editList); - free(ptr); + gf_free(ptr); } @@ -891,8 +884,7 @@ GF_Box *edts_New() return (GF_Box *) tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err edts_Write(GF_Box *s, GF_BitStream *bs) { @@ -927,7 +919,7 @@ GF_Err edts_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void elst_del(GF_Box *s) { @@ -941,10 +933,10 @@ void elst_del(GF_Box *s) nb_entries = gf_list_count(ptr->entryList); for (i = 0; i < nb_entries; i++) { p = (GF_EdtsEntry*)gf_list_get(ptr->entryList, i); - if (p) free(p); + if (p) gf_free(p); } gf_list_del(ptr->entryList); - free(ptr); + gf_free(ptr); } @@ -964,7 +956,7 @@ GF_Err elst_Read(GF_Box *s, GF_BitStream *bs) nb_entries = gf_bs_read_u32(bs); for (entries = 0; entries < nb_entries; entries++ ) { - p = (GF_EdtsEntry *) malloc(sizeof(GF_EdtsEntry)); + p = (GF_EdtsEntry *) gf_malloc(sizeof(GF_EdtsEntry)); if (!p) return GF_OUT_OF_MEM; if (ptr->version == 1) { p->segmentDuration = gf_bs_read_u64(bs); @@ -985,22 +977,21 @@ GF_Box *elst_New() { GF_EditListBox *tmp; - tmp = (GF_EditListBox *) malloc(sizeof(GF_EditListBox)); + tmp = (GF_EditListBox *) gf_malloc(sizeof(GF_EditListBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_EditListBox)); gf_isom_full_box_init((GF_Box *)tmp); tmp->entryList = gf_list_new(); if (!tmp->entryList) { - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_ELST; return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err elst_Write(GF_Box *s, GF_BitStream *bs) { @@ -1056,14 +1047,14 @@ GF_Err elst_Size(GF_Box *s) } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void esds_del(GF_Box *s) { GF_ESDBox *ptr = (GF_ESDBox *)s; if (ptr == NULL) return; if (ptr->desc) gf_odf_desc_del((GF_Descriptor *)ptr->desc); - free(ptr); + gf_free(ptr); } @@ -1080,14 +1071,14 @@ GF_Err esds_Read(GF_Box *s, GF_BitStream *bs) descSize = (u32) (ptr->size); if (descSize) { - enc_desc = (char*)malloc(sizeof(char) * descSize); + enc_desc = (char*)gf_malloc(sizeof(char) * descSize); if (!enc_desc) return GF_OUT_OF_MEM; //get the payload gf_bs_read_data(bs, enc_desc, descSize); //send it to the OD Codec e = gf_odf_desc_read(enc_desc, descSize, (GF_Descriptor **) &ptr->desc); //OK, free our desc - free(enc_desc); + gf_free(enc_desc); //we do not abbort on error, but skip the descritpor if (e) { ptr->desc = NULL; @@ -1109,7 +1100,7 @@ GF_Err esds_Read(GF_Box *s, GF_BitStream *bs) GF_Box *esds_New() { - GF_ESDBox *tmp = (GF_ESDBox *) malloc(sizeof(GF_ESDBox)); + GF_ESDBox *tmp = (GF_ESDBox *) gf_malloc(sizeof(GF_ESDBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ESDBox)); @@ -1120,8 +1111,7 @@ GF_Box *esds_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err esds_Write(GF_Box *s, GF_BitStream *bs) { @@ -1136,7 +1126,7 @@ GF_Err esds_Write(GF_Box *s, GF_BitStream *bs) if (e) return e; gf_bs_write_data(bs, enc_desc, descSize); //free our buffer - free(enc_desc); + gf_free(enc_desc); return GF_OK; } @@ -1152,13 +1142,13 @@ GF_Err esds_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void free_del(GF_Box *s) { GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s; - if (ptr->data) free(ptr->data); - free(ptr); + if (ptr->data) gf_free(ptr->data); + gf_free(ptr); } @@ -1172,7 +1162,7 @@ GF_Err free_Read(GF_Box *s, GF_BitStream *bs) bytesToRead = (u32) (ptr->size); if (bytesToRead) { - ptr->data = (char*)malloc(bytesToRead * sizeof(char)); + ptr->data = (char*)gf_malloc(bytesToRead * sizeof(char)); gf_bs_read_data(bs, ptr->data, bytesToRead); ptr->dataSize = bytesToRead; } @@ -1181,15 +1171,14 @@ GF_Err free_Read(GF_Box *s, GF_BitStream *bs) GF_Box *free_New() { - GF_FreeSpaceBox *tmp = (GF_FreeSpaceBox *) malloc(sizeof(GF_FreeSpaceBox)); + 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; return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err free_Write(GF_Box *s, GF_BitStream *bs) { @@ -1197,7 +1186,17 @@ GF_Err free_Write(GF_Box *s, GF_BitStream *bs) GF_FreeSpaceBox *ptr = (GF_FreeSpaceBox *)s; e = gf_isom_box_write_header(s, bs); if (e) return e; - if (ptr->dataSize) gf_bs_write_data(bs, ptr->data, ptr->dataSize); + if (ptr->dataSize) { + if (ptr->data) { + gf_bs_write_data(bs, ptr->data, ptr->dataSize); + } else { + u32 i = 0; + while (i<ptr->dataSize) { + gf_bs_write_u8(bs, 0); + i++; + } + } + } return GF_OK; } @@ -1211,20 +1210,20 @@ GF_Err free_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void ftyp_del(GF_Box *s) { GF_FileTypeBox *ptr = (GF_FileTypeBox *) s; - if (ptr->altBrand) free(ptr->altBrand); - free(ptr); + if (ptr->altBrand) gf_free(ptr->altBrand); + gf_free(ptr); } GF_Box *ftyp_New() { GF_FileTypeBox *tmp; - tmp = (GF_FileTypeBox *) malloc(sizeof(GF_FileTypeBox)); + tmp = (GF_FileTypeBox *) gf_malloc(sizeof(GF_FileTypeBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_FileTypeBox)); @@ -1245,7 +1244,7 @@ GF_Err ftyp_Read(GF_Box *s,GF_BitStream *bs) if (!ptr->altCount) return GF_OK; if (ptr->altCount * 4 != (u32) (ptr->size)) return GF_ISOM_INVALID_FILE; - ptr->altBrand = (u32*)malloc(sizeof(u32)*ptr->altCount); + ptr->altBrand = (u32*)gf_malloc(sizeof(u32)*ptr->altCount); for (i = 0; i<ptr->altCount; i++) { ptr->altBrand[i] = gf_bs_read_u32(bs); } @@ -1254,8 +1253,7 @@ GF_Err ftyp_Read(GF_Box *s,GF_BitStream *bs) -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ftyp_Write(GF_Box *s, GF_BitStream *bs) { @@ -1284,20 +1282,20 @@ GF_Err ftyp_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void gnrm_del(GF_Box *s) { GF_GenericSampleEntryBox *ptr = (GF_GenericSampleEntryBox *)s; - if (ptr->data) free(ptr->data); - free(ptr); + if (ptr->data) gf_free(ptr->data); + gf_free(ptr); } GF_Box *gnrm_New() { - GF_GenericSampleEntryBox *tmp = (GF_GenericSampleEntryBox *) malloc(sizeof(GF_GenericSampleEntryBox)); + 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; @@ -1305,8 +1303,7 @@ GF_Box *gnrm_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gnrm_Write(GF_Box *s, GF_BitStream *bs) { @@ -1336,19 +1333,19 @@ GF_Err gnrm_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void gnrv_del(GF_Box *s) { GF_GenericVisualSampleEntryBox *ptr = (GF_GenericVisualSampleEntryBox *)s; - if (ptr->data) free(ptr->data); - free(ptr); + if (ptr->data) gf_free(ptr->data); + gf_free(ptr); } GF_Box *gnrv_New() { - GF_GenericVisualSampleEntryBox *tmp = (GF_GenericVisualSampleEntryBox *) malloc(sizeof(GF_GenericVisualSampleEntryBox)); + 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; @@ -1357,8 +1354,7 @@ GF_Box *gnrv_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gnrv_Write(GF_Box *s, GF_BitStream *bs) { @@ -1389,20 +1385,20 @@ GF_Err gnrv_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void gnra_del(GF_Box *s) { GF_GenericAudioSampleEntryBox *ptr = (GF_GenericAudioSampleEntryBox *)s; - if (ptr->data) free(ptr->data); - free(ptr); + if (ptr->data) gf_free(ptr->data); + gf_free(ptr); } GF_Box *gnra_New() { - GF_GenericAudioSampleEntryBox *tmp = (GF_GenericAudioSampleEntryBox *) malloc(sizeof(GF_GenericAudioSampleEntryBox)); + 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; @@ -1411,8 +1407,7 @@ GF_Box *gnra_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gnra_Write(GF_Box *s, GF_BitStream *bs) { @@ -1443,14 +1438,14 @@ GF_Err gnra_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void hdlr_del(GF_Box *s) { GF_HandlerBox *ptr = (GF_HandlerBox *)s; if (ptr == NULL) return; - if (ptr->nameUTF8) free(ptr->nameUTF8); - free(ptr); + if (ptr->nameUTF8) gf_free(ptr->nameUTF8); + gf_free(ptr); } @@ -1466,15 +1461,15 @@ GF_Err hdlr_Read(GF_Box *s, GF_BitStream *bs) gf_bs_read_data(bs, (char*)ptr->reserved2, 12); ptr->size -= 20; if (ptr->size) { - ptr->nameUTF8 = (char*)malloc((u32) ptr->size); + ptr->nameUTF8 = (char*)gf_malloc((u32) ptr->size); if (ptr->nameUTF8 == NULL) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ptr->nameUTF8, (u32) ptr->size); /*safety check in case the string is not null-terminated*/ if (ptr->nameUTF8[ptr->size-1]) { - char *str = (char*)malloc((u32) ptr->size + 1); + char *str = (char*)gf_malloc((u32) ptr->size + 1); memcpy(str, ptr->nameUTF8, (u32) ptr->size); str[ptr->size] = 0; - free(ptr->nameUTF8); + gf_free(ptr->nameUTF8); ptr->nameUTF8 = str; } } @@ -1483,7 +1478,7 @@ GF_Err hdlr_Read(GF_Box *s, GF_BitStream *bs) GF_Box *hdlr_New() { - GF_HandlerBox *tmp = (GF_HandlerBox *) malloc(sizeof(GF_HandlerBox)); + GF_HandlerBox *tmp = (GF_HandlerBox *) gf_malloc(sizeof(GF_HandlerBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_HandlerBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -1492,8 +1487,7 @@ GF_Box *hdlr_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err hdlr_Write(GF_Box *s, GF_BitStream *bs) { @@ -1521,7 +1515,7 @@ GF_Err hdlr_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void hinf_del(GF_Box *s) @@ -1529,24 +1523,24 @@ void hinf_del(GF_Box *s) GF_HintInfoBox *hinf = (GF_HintInfoBox *)s; gf_isom_box_array_del(hinf->boxList); gf_list_del(hinf->dataRates); - free(hinf); + gf_free(hinf); } GF_Box *hinf_New() { - GF_HintInfoBox *tmp = (GF_HintInfoBox *)malloc(sizeof(GF_HintInfoBox)); + GF_HintInfoBox *tmp = (GF_HintInfoBox *)gf_malloc(sizeof(GF_HintInfoBox)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_HintInfoBox)); tmp->boxList = gf_list_new(); if (!tmp->boxList) { - free(tmp); + gf_free(tmp); return NULL; } tmp->dataRates = gf_list_new(); if (!tmp->dataRates) { gf_list_del(tmp->boxList); - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_HINF; @@ -1578,7 +1572,7 @@ GF_Err hinf_Read(GF_Box *s, GF_BitStream *bs) return gf_isom_read_box_list(s, bs, hinf_AddBox); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err hinf_Write(GF_Box *s, GF_BitStream *bs) { @@ -1598,13 +1592,13 @@ GF_Err hinf_Size(GF_Box *s) if (e) return e; return gf_isom_box_array_size(s, ptr->boxList); } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void hmhd_del(GF_Box *s) { GF_HintMediaHeaderBox *ptr = (GF_HintMediaHeaderBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } @@ -1625,7 +1619,7 @@ GF_Err hmhd_Read(GF_Box *s,GF_BitStream *bs) GF_Box *hmhd_New() { - GF_HintMediaHeaderBox *tmp = (GF_HintMediaHeaderBox *) malloc(sizeof(GF_HintMediaHeaderBox)); + GF_HintMediaHeaderBox *tmp = (GF_HintMediaHeaderBox *) gf_malloc(sizeof(GF_HintMediaHeaderBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_HintMediaHeaderBox)); @@ -1636,8 +1630,7 @@ GF_Box *hmhd_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err hmhd_Write(GF_Box *s, GF_BitStream *bs) { @@ -1664,16 +1657,16 @@ GF_Err hmhd_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *hnti_New() { - GF_HintTrackInfoBox *tmp = (GF_HintTrackInfoBox *)malloc(sizeof(GF_HintTrackInfoBox)); + 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) { - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_HNTI; @@ -1691,13 +1684,13 @@ void hnti_del(GF_Box *a) gf_isom_box_del(t); } else { rtp = (GF_RTPBox *)t; - if (rtp->sdpText) free(rtp->sdpText); - free(rtp); + if (rtp->sdpText) gf_free(rtp->sdpText); + gf_free(rtp); } gf_list_rem(ptr->boxList, 0); } gf_list_del(ptr->boxList); - free(ptr); + gf_free(ptr); } GF_Err hnti_AddBox(GF_HintTrackInfoBox *hnti, GF_Box *a) @@ -1744,7 +1737,7 @@ GF_Err hnti_Read(GF_Box *s, GF_BitStream *bs) ptr->size-=a->size; } else { u32 sr; - rtp = (GF_RTPBox*)malloc(sizeof(GF_RTPBox)); + rtp = (GF_RTPBox*)gf_malloc(sizeof(GF_RTPBox)); if (!rtp) return GF_OUT_OF_MEM; rtp->size = gf_bs_read_u32(bs); rtp->type = gf_bs_read_u32(bs); @@ -1757,9 +1750,9 @@ GF_Err hnti_Read(GF_Box *s, GF_BitStream *bs) if (rtp->subType != GF_ISOM_BOX_TYPE_SDP) return GF_NOT_SUPPORTED; if (rtp->size < sr) return GF_ISOM_INVALID_FILE; length = (u32) (rtp->size - sr); - rtp->sdpText = (char*)malloc(sizeof(char) * (length + 1)); + rtp->sdpText = (char*)gf_malloc(sizeof(char) * (length + 1)); if (!rtp->sdpText) { - free(rtp); + gf_free(rtp); return GF_OUT_OF_MEM; } gf_bs_read_data(bs, rtp->sdpText, length); @@ -1774,7 +1767,7 @@ GF_Err hnti_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err hnti_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -1839,7 +1832,7 @@ GF_Err hnti_Size(GF_Box *s) } return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** GF_SDPBox @@ -1848,8 +1841,8 @@ GF_Err hnti_Size(GF_Box *s) void sdp_del(GF_Box *s) { GF_SDPBox *ptr = (GF_SDPBox *)s; - if (ptr->sdpText) free(ptr->sdpText); - free(ptr); + if (ptr->sdpText) gf_free(ptr->sdpText); + gf_free(ptr); } GF_Err sdp_Read(GF_Box *s, GF_BitStream *bs) @@ -1860,7 +1853,7 @@ GF_Err sdp_Read(GF_Box *s, GF_BitStream *bs) length = (u32) (ptr->size); //sdp text has no delimiter !!! - ptr->sdpText = (char*)malloc(sizeof(char) * (length+1)); + ptr->sdpText = (char*)gf_malloc(sizeof(char) * (length+1)); if (!ptr->sdpText) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ptr->sdpText, length); @@ -1869,13 +1862,13 @@ GF_Err sdp_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *sdp_New() { - GF_SDPBox *tmp = (GF_SDPBox *) malloc(sizeof(GF_SDPBox)); + 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; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err sdp_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -1898,7 +1891,7 @@ GF_Err sdp_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -1907,7 +1900,7 @@ GF_Err sdp_Size(GF_Box *s) void trpy_del(GF_Box *s) { - free((GF_TRPYBox *)s); + gf_free((GF_TRPYBox *)s); } GF_Err trpy_Read(GF_Box *s, GF_BitStream *bs) { @@ -1917,13 +1910,13 @@ GF_Err trpy_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *trpy_New() { - GF_TRPYBox *tmp = (GF_TRPYBox *) malloc(sizeof(GF_TRPYBox)); + GF_TRPYBox *tmp = (GF_TRPYBox *) gf_malloc(sizeof(GF_TRPYBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_TRPY; tmp->nbBytes = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err trpy_Write(GF_Box *s, GF_BitStream *bs) { @@ -1944,7 +1937,7 @@ GF_Err trpy_Size(GF_Box *s) s->size += 8; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** TOTL GF_Box @@ -1952,7 +1945,7 @@ GF_Err trpy_Size(GF_Box *s) void totl_del(GF_Box *s) { - free((GF_TRPYBox *)s); + gf_free((GF_TRPYBox *)s); } GF_Err totl_Read(GF_Box *s, GF_BitStream *bs) { @@ -1962,14 +1955,14 @@ GF_Err totl_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *totl_New() { - GF_TOTLBox *tmp = (GF_TOTLBox *) malloc(sizeof(GF_TOTLBox)); + GF_TOTLBox *tmp = (GF_TOTLBox *) gf_malloc(sizeof(GF_TOTLBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_TOTL; tmp->nbBytes = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err totl_Write(GF_Box *s, GF_BitStream *bs) { @@ -1989,7 +1982,7 @@ GF_Err totl_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -1998,7 +1991,7 @@ GF_Err totl_Size(GF_Box *s) void nump_del(GF_Box *s) { - free((GF_NUMPBox *)s); + gf_free((GF_NUMPBox *)s); } GF_Err nump_Read(GF_Box *s, GF_BitStream *bs) { @@ -2008,14 +2001,14 @@ GF_Err nump_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *nump_New() { - GF_NUMPBox *tmp = (GF_NUMPBox *) malloc(sizeof(GF_NUMPBox)); + GF_NUMPBox *tmp = (GF_NUMPBox *) gf_malloc(sizeof(GF_NUMPBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_NUMP; tmp->nbPackets = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err nump_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2034,7 +2027,7 @@ GF_Err nump_Size(GF_Box *s) s->size += 8; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -2043,7 +2036,7 @@ GF_Err nump_Size(GF_Box *s) void npck_del(GF_Box *s) { - free((GF_NPCKBox *)s); + gf_free((GF_NPCKBox *)s); } GF_Err npck_Read(GF_Box *s, GF_BitStream *bs) { @@ -2053,13 +2046,13 @@ GF_Err npck_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *npck_New() { - GF_NPCKBox *tmp = (GF_NPCKBox *) malloc(sizeof(GF_NPCKBox)); + GF_NPCKBox *tmp = (GF_NPCKBox *) gf_malloc(sizeof(GF_NPCKBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_NPCK; tmp->nbPackets = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err npck_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2078,7 +2071,7 @@ GF_Err npck_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -2087,7 +2080,7 @@ GF_Err npck_Size(GF_Box *s) void tpyl_del(GF_Box *s) { - free((GF_NTYLBox *)s); + gf_free((GF_NTYLBox *)s); } GF_Err tpyl_Read(GF_Box *s, GF_BitStream *bs) { @@ -2098,13 +2091,13 @@ GF_Err tpyl_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *tpyl_New() { - GF_NTYLBox *tmp = (GF_NTYLBox *) malloc(sizeof(GF_NTYLBox)); + GF_NTYLBox *tmp = (GF_NTYLBox *) gf_malloc(sizeof(GF_NTYLBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_TPYL; tmp->nbBytes = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tpyl_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2123,7 +2116,7 @@ GF_Err tpyl_Size(GF_Box *s) s->size += 8; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** TPAY GF_Box @@ -2131,7 +2124,7 @@ GF_Err tpyl_Size(GF_Box *s) void tpay_del(GF_Box *s) { - free((GF_TPAYBox *)s); + gf_free((GF_TPAYBox *)s); } GF_Err tpay_Read(GF_Box *s, GF_BitStream *bs) { @@ -2141,13 +2134,13 @@ GF_Err tpay_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *tpay_New() { - GF_TPAYBox *tmp = (GF_TPAYBox *) malloc(sizeof(GF_TPAYBox)); + GF_TPAYBox *tmp = (GF_TPAYBox *) gf_malloc(sizeof(GF_TPAYBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_TPAY; tmp->nbBytes = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tpay_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2166,7 +2159,7 @@ GF_Err tpay_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -2175,7 +2168,7 @@ GF_Err tpay_Size(GF_Box *s) void maxr_del(GF_Box *s) { - free((GF_MAXRBox *)s); + gf_free((GF_MAXRBox *)s); } GF_Err maxr_Read(GF_Box *s, GF_BitStream *bs) { @@ -2187,13 +2180,13 @@ GF_Err maxr_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *maxr_New() { - GF_MAXRBox *tmp = (GF_MAXRBox *) malloc(sizeof(GF_MAXRBox)); + 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; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err maxr_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2213,7 +2206,7 @@ GF_Err maxr_Size(GF_Box *s) s->size += 8; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -2222,7 +2215,7 @@ GF_Err maxr_Size(GF_Box *s) void dmed_del(GF_Box *s) { - free((GF_DMEDBox *)s); + gf_free((GF_DMEDBox *)s); } GF_Err dmed_Read(GF_Box *s, GF_BitStream *bs) { @@ -2232,13 +2225,13 @@ GF_Err dmed_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *dmed_New() { - GF_DMEDBox *tmp = (GF_DMEDBox *) malloc(sizeof(GF_DMEDBox)); + GF_DMEDBox *tmp = (GF_DMEDBox *) gf_malloc(sizeof(GF_DMEDBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_DMED; tmp->nbBytes = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err dmed_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2257,7 +2250,7 @@ GF_Err dmed_Size(GF_Box *s) s->size += 8; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** DIMM GF_Box @@ -2265,7 +2258,7 @@ GF_Err dmed_Size(GF_Box *s) void dimm_del(GF_Box *s) { - free((GF_DIMMBox *)s); + gf_free((GF_DIMMBox *)s); } GF_Err dimm_Read(GF_Box *s, GF_BitStream *bs) { @@ -2275,13 +2268,13 @@ GF_Err dimm_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *dimm_New() { - GF_DIMMBox *tmp = (GF_DIMMBox *) malloc(sizeof(GF_DIMMBox)); + GF_DIMMBox *tmp = (GF_DIMMBox *) gf_malloc(sizeof(GF_DIMMBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_DIMM; tmp->nbBytes = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err dimm_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2300,7 +2293,7 @@ GF_Err dimm_Size(GF_Box *s) s->size += 8; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** DREP GF_Box @@ -2308,7 +2301,7 @@ GF_Err dimm_Size(GF_Box *s) void drep_del(GF_Box *s) { - free((GF_DREPBox *)s); + gf_free((GF_DREPBox *)s); } GF_Err drep_Read(GF_Box *s, GF_BitStream *bs) { @@ -2318,13 +2311,13 @@ GF_Err drep_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *drep_New() { - GF_DREPBox *tmp = (GF_DREPBox *) malloc(sizeof(GF_DREPBox)); + GF_DREPBox *tmp = (GF_DREPBox *) gf_malloc(sizeof(GF_DREPBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_DREP; tmp->nbBytes = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err drep_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2343,7 +2336,7 @@ GF_Err drep_Size(GF_Box *s) s->size += 8; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -2353,7 +2346,7 @@ GF_Err drep_Size(GF_Box *s) void tmin_del(GF_Box *s) { - free((GF_TMINBox *)s); + gf_free((GF_TMINBox *)s); } GF_Err tmin_Read(GF_Box *s, GF_BitStream *bs) { @@ -2363,13 +2356,13 @@ GF_Err tmin_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *tmin_New() { - GF_TMINBox *tmp = (GF_TMINBox *) malloc(sizeof(GF_TMINBox)); + GF_TMINBox *tmp = (GF_TMINBox *) gf_malloc(sizeof(GF_TMINBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_TMIN; tmp->minTime = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tmin_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2388,7 +2381,7 @@ GF_Err tmin_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -2397,7 +2390,7 @@ GF_Err tmin_Size(GF_Box *s) void tmax_del(GF_Box *s) { - free((GF_TMAXBox *)s); + gf_free((GF_TMAXBox *)s); } GF_Err tmax_Read(GF_Box *s, GF_BitStream *bs) { @@ -2407,13 +2400,13 @@ GF_Err tmax_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *tmax_New() { - GF_TMAXBox *tmp = (GF_TMAXBox *) malloc(sizeof(GF_TMAXBox)); + GF_TMAXBox *tmp = (GF_TMAXBox *) gf_malloc(sizeof(GF_TMAXBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_TMAX; tmp->maxTime = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tmax_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2432,7 +2425,7 @@ GF_Err tmax_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -2441,7 +2434,7 @@ GF_Err tmax_Size(GF_Box *s) void pmax_del(GF_Box *s) { - free((GF_PMAXBox *)s); + gf_free((GF_PMAXBox *)s); } GF_Err pmax_Read(GF_Box *s, GF_BitStream *bs) { @@ -2451,13 +2444,13 @@ GF_Err pmax_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *pmax_New() { - GF_PMAXBox *tmp = (GF_PMAXBox *) malloc(sizeof(GF_PMAXBox)); + GF_PMAXBox *tmp = (GF_PMAXBox *) gf_malloc(sizeof(GF_PMAXBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_PMAX; tmp->maxSize = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err pmax_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2476,7 +2469,7 @@ GF_Err pmax_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -2485,7 +2478,7 @@ GF_Err pmax_Size(GF_Box *s) void dmax_del(GF_Box *s) { - free((GF_DMAXBox *)s); + gf_free((GF_DMAXBox *)s); } GF_Err dmax_Read(GF_Box *s, GF_BitStream *bs) { @@ -2495,13 +2488,13 @@ GF_Err dmax_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *dmax_New() { - GF_DMAXBox *tmp = (GF_DMAXBox *) malloc(sizeof(GF_DMAXBox)); + GF_DMAXBox *tmp = (GF_DMAXBox *) gf_malloc(sizeof(GF_DMAXBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_DMAX; tmp->maxDur = 0; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err dmax_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2520,7 +2513,7 @@ GF_Err dmax_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -2530,8 +2523,8 @@ GF_Err dmax_Size(GF_Box *s) void payt_del(GF_Box *s) { GF_PAYTBox *payt = (GF_PAYTBox *)s; - if (payt->payloadString) free(payt->payloadString); - free(payt); + if (payt->payloadString) gf_free(payt->payloadString); + gf_free(payt); } GF_Err payt_Read(GF_Box *s, GF_BitStream *bs) { @@ -2540,7 +2533,7 @@ GF_Err payt_Read(GF_Box *s, GF_BitStream *bs) ptr->payloadCode = gf_bs_read_u32(bs); length = gf_bs_read_u8(bs); - ptr->payloadString = (char*)malloc(sizeof(char) * (length+1) ); + ptr->payloadString = (char*)gf_malloc(sizeof(char) * (length+1) ); if (! ptr->payloadString) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ptr->payloadString, length); ptr->payloadString[length] = 0; @@ -2549,14 +2542,14 @@ GF_Err payt_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *payt_New() { - GF_PAYTBox *tmp = (GF_PAYTBox *) malloc(sizeof(GF_PAYTBox)); + 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; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err payt_Write(GF_Box *s, GF_BitStream *bs) { u32 len; @@ -2581,7 +2574,7 @@ GF_Err payt_Size(GF_Box *s) if (ptr->payloadString) ptr->size += strlen(ptr->payloadString) + 1; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /********************************************************** @@ -2591,8 +2584,8 @@ GF_Err payt_Size(GF_Box *s) void name_del(GF_Box *s) { GF_NameBox *name = (GF_NameBox *)s; - if (name->string) free(name->string); - free(name); + if (name->string) gf_free(name->string); + gf_free(name); } GF_Err name_Read(GF_Box *s, GF_BitStream *bs) { @@ -2600,7 +2593,7 @@ GF_Err name_Read(GF_Box *s, GF_BitStream *bs) GF_NameBox *ptr = (GF_NameBox *)s; length = (u32) (ptr->size); - ptr->string = (char*)malloc(sizeof(char) * length); + ptr->string = (char*)gf_malloc(sizeof(char) * length); if (! ptr->string) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ptr->string, length); @@ -2608,13 +2601,13 @@ GF_Err name_Read(GF_Box *s, GF_BitStream *bs) } GF_Box *name_New() { - GF_NameBox *tmp = (GF_NameBox *) malloc(sizeof(GF_NameBox)); + GF_NameBox *tmp = (GF_NameBox *) gf_malloc(sizeof(GF_NameBox)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_NAME; tmp->string = NULL; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err name_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -2636,14 +2629,14 @@ GF_Err name_Size(GF_Box *s) if (ptr->string) ptr->size += strlen(ptr->string) + 1; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void iods_del(GF_Box *s) { GF_ObjectDescriptorBox *ptr = (GF_ObjectDescriptorBox *)s; if (ptr == NULL) return; if (ptr->descriptor) gf_odf_desc_del(ptr->descriptor); - free(ptr); + gf_free(ptr); } @@ -2658,17 +2651,17 @@ GF_Err iods_Read(GF_Box *s, GF_BitStream *bs) if (e) return e; //use the OD codec... descSize = (u32) (ptr->size); - desc = (char*)malloc(sizeof(char) * descSize); + desc = (char*)gf_malloc(sizeof(char) * descSize); gf_bs_read_data(bs, desc, descSize); e = gf_odf_desc_read(desc, descSize, &ptr->descriptor); //OK, free our desc - free(desc); + gf_free(desc); return GF_OK; } GF_Box *iods_New() { - GF_ObjectDescriptorBox *tmp = (GF_ObjectDescriptorBox *) malloc(sizeof(GF_ObjectDescriptorBox)); + GF_ObjectDescriptorBox *tmp = (GF_ObjectDescriptorBox *) gf_malloc(sizeof(GF_ObjectDescriptorBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ObjectDescriptorBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -2678,8 +2671,7 @@ GF_Box *iods_New() -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err iods_Write(GF_Box *s, GF_BitStream *bs) { @@ -2694,7 +2686,7 @@ GF_Err iods_Write(GF_Box *s, GF_BitStream *bs) if (e) return e; gf_bs_write_data(bs, desc, descSize); //and free our stuff maybe!! - free(desc); + gf_free(desc); return GF_OK; } @@ -2708,15 +2700,15 @@ GF_Err iods_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void mdat_del(GF_Box *s) { GF_MediaDataBox *ptr = (GF_MediaDataBox *)s; if (!s) return; - if (ptr->data) free(ptr->data); - free(ptr); + if (ptr->data) gf_free(ptr->data); + gf_free(ptr); } @@ -2733,15 +2725,14 @@ GF_Err mdat_Read(GF_Box *s, GF_BitStream *bs) GF_Box *mdat_New() { - GF_MediaDataBox *tmp = (GF_MediaDataBox *) malloc(sizeof(GF_MediaDataBox)); + 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; return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mdat_Write(GF_Box *s, GF_BitStream *bs) { @@ -2769,13 +2760,13 @@ GF_Err mdat_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void mdhd_del(GF_Box *s) { GF_MediaHeaderBox *ptr = (GF_MediaHeaderBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } GF_Err mdhd_Read(GF_Box *s, GF_BitStream *bs) @@ -2818,7 +2809,7 @@ GF_Err mdhd_Read(GF_Box *s, GF_BitStream *bs) GF_Box *mdhd_New() { - GF_MediaHeaderBox *tmp = (GF_MediaHeaderBox *) malloc(sizeof(GF_MediaHeaderBox)); + GF_MediaHeaderBox *tmp = (GF_MediaHeaderBox *) gf_malloc(sizeof(GF_MediaHeaderBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_MediaHeaderBox)); @@ -2832,8 +2823,7 @@ GF_Box *mdhd_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mdhd_Write(GF_Box *s, GF_BitStream *bs) { @@ -2873,7 +2863,7 @@ GF_Err mdhd_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void mdia_del(GF_Box *s) @@ -2883,7 +2873,7 @@ void mdia_del(GF_Box *s) if (ptr->mediaHeader) gf_isom_box_del((GF_Box *)ptr->mediaHeader); if (ptr->information) gf_isom_box_del((GF_Box *)ptr->information); if (ptr->handler) gf_isom_box_del((GF_Box *)ptr->handler); - free(ptr); + gf_free(ptr); } @@ -2918,15 +2908,14 @@ GF_Err mdia_Read(GF_Box *s, GF_BitStream *bs) GF_Box *mdia_New() { - GF_MediaBox *tmp = (GF_MediaBox *) malloc(sizeof(GF_MediaBox)); + 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; return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mdia_Write(GF_Box *s, GF_BitStream *bs) { @@ -2976,16 +2965,16 @@ GF_Err mdia_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS void mfhd_del(GF_Box *s) { GF_MovieFragmentHeaderBox *ptr = (GF_MovieFragmentHeaderBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } GF_Err mfhd_Read(GF_Box *s, GF_BitStream *bs) @@ -2995,13 +2984,12 @@ GF_Err mfhd_Read(GF_Box *s, GF_BitStream *bs) e = gf_isom_full_box_read(s, bs); if (e) return e; ptr->sequence_number = gf_bs_read_u32(bs); - if (!ptr->sequence_number) return GF_ISOM_INVALID_FILE; return GF_OK; } GF_Box *mfhd_New() { - GF_MovieFragmentHeaderBox *tmp = (GF_MovieFragmentHeaderBox *) malloc(sizeof(GF_MovieFragmentHeaderBox)); + 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; @@ -3009,8 +2997,7 @@ GF_Box *mfhd_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mfhd_Write(GF_Box *s, GF_BitStream *bs) @@ -3037,9 +3024,9 @@ GF_Err mfhd_Size(GF_Box *s) -#endif /*GPAC_READ_ONLY*/ +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#endif /*GPAC_ISOM_NO_FRAGMENTS*/ +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ void minf_del(GF_Box *s) @@ -3055,7 +3042,7 @@ void minf_del(GF_Box *s) 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); - free(ptr); + gf_free(ptr); } GF_Err minf_AddBox(GF_Box *s, GF_Box *a) @@ -3094,7 +3081,7 @@ GF_Err minf_Read(GF_Box *s, GF_BitStream *bs) GF_Box *minf_New() { - GF_MediaInformationBox *tmp = (GF_MediaInformationBox *) malloc(sizeof(GF_MediaInformationBox)); + 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; @@ -3103,8 +3090,7 @@ GF_Box *minf_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err minf_Write(GF_Box *s, GF_BitStream *bs) { @@ -3158,9 +3144,9 @@ GF_Err minf_Size(GF_Box *s) return gf_isom_box_array_size(s, ptr->boxes); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS void moof_del(GF_Box *s) { @@ -3169,7 +3155,8 @@ void moof_del(GF_Box *s) if (ptr->mfhd) gf_isom_box_del((GF_Box *) ptr->mfhd); gf_isom_box_array_del(ptr->TrackList); - free(ptr); + if (ptr->mdat) gf_free(ptr->mdat); + gf_free(ptr); } GF_Err moof_AddBox(GF_Box *s, GF_Box *a) @@ -3194,7 +3181,7 @@ GF_Err moof_Read(GF_Box *s, GF_BitStream *bs) GF_Box *moof_New() { - GF_MovieFragmentBox *tmp = (GF_MovieFragmentBox *) malloc(sizeof(GF_MovieFragmentBox)); + 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; @@ -3203,8 +3190,7 @@ GF_Box *moof_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err moof_Write(GF_Box *s, GF_BitStream *bs) { @@ -3241,10 +3227,9 @@ GF_Err moof_Size(GF_Box *s) -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ - -#endif +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ void moov_del(GF_Box *s) { @@ -3255,13 +3240,13 @@ void moov_del(GF_Box *s) if (ptr->meta) gf_isom_box_del((GF_Box *)ptr->meta); if (ptr->iods) gf_isom_box_del((GF_Box *)ptr->iods); if (ptr->udta) gf_isom_box_del((GF_Box *)ptr->udta); -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS if (ptr->mvex) gf_isom_box_del((GF_Box *)ptr->mvex); #endif gf_isom_box_array_del(ptr->trackList); gf_isom_box_array_del(ptr->boxes); - free(ptr); + gf_free(ptr); } @@ -3289,7 +3274,7 @@ GF_Err moov_AddBox(GF_Box *s, GF_Box *a) ptr->udta = (GF_UserDataBox *)a; return GF_OK; -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS case GF_ISOM_BOX_TYPE_MVEX: if (ptr->mvex) return GF_ISOM_INVALID_FILE; ptr->mvex = (GF_MovieExtendsBox *)a; @@ -3320,18 +3305,18 @@ GF_Err moov_Read(GF_Box *s, GF_BitStream *bs) GF_Box *moov_New() { - GF_MovieBox *tmp = (GF_MovieBox *) malloc(sizeof(GF_MovieBox)); + GF_MovieBox *tmp = (GF_MovieBox *) gf_malloc(sizeof(GF_MovieBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_MovieBox)); tmp->trackList = gf_list_new(); if (!tmp->trackList) { - free(tmp); + gf_free(tmp); return NULL; } tmp->boxes = gf_list_new(); if (!tmp->boxes) { gf_list_del(tmp->trackList); - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_MOOV; @@ -3339,8 +3324,8 @@ GF_Box *moov_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err moov_Write(GF_Box *s, GF_BitStream *bs) @@ -3363,7 +3348,7 @@ GF_Err moov_Write(GF_Box *s, GF_BitStream *bs) e = gf_isom_box_write((GF_Box *) ptr->meta, bs); if (e) return e; } -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS if (ptr->mvex) { e = gf_isom_box_write((GF_Box *) ptr->mvex, bs); if (e) return e; @@ -3407,7 +3392,7 @@ GF_Err moov_Size(GF_Box *s) if (e) return e; ptr->size += ptr->meta->size; } -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS if (ptr->mvex) { e = gf_isom_box_size((GF_Box *) ptr->mvex); if (e) return e; @@ -3420,7 +3405,7 @@ GF_Err moov_Size(GF_Box *s) return gf_isom_box_array_size(s, ptr->boxes); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void mp4a_del(GF_Box *s) { @@ -3429,7 +3414,7 @@ void mp4a_del(GF_Box *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); - free(ptr); + gf_free(ptr); } GF_Err mp4a_AddBox(GF_Box *s, GF_Box *a) @@ -3490,7 +3475,7 @@ GF_Err mp4a_Read(GF_Box *s, GF_BitStream *bs) /*hack for some weird files (possibly recorded with live.com tools, needs further investigations)*/ ptr = (GF_MPEGAudioSampleEntryBox *)s; gf_bs_seek(bs, pos); - data = (char*)malloc(sizeof(char) * size); + data = (char*)gf_malloc(sizeof(char) * size); gf_bs_read_data(bs, data, size); for (i=0; i<size-8; i++) { if (GF_4CC(data[i+4], data[i+5], data[i+6], data[i+7]) == GF_ISOM_BOX_TYPE_ESDS) { @@ -3500,13 +3485,13 @@ GF_Err mp4a_Read(GF_Box *s, GF_BitStream *bs) break; } } - free(data); + gf_free(data); return e; } GF_Box *mp4a_New() { - GF_MPEGAudioSampleEntryBox *tmp = (GF_MPEGAudioSampleEntryBox *)malloc(sizeof(GF_MPEGAudioSampleEntryBox)); + 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; @@ -3521,8 +3506,8 @@ GF_Box *enca_New() return tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mp4a_Write(GF_Box *s, GF_BitStream *bs) { @@ -3560,7 +3545,7 @@ GF_Err mp4a_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void mp4s_del(GF_Box *s) @@ -3570,7 +3555,7 @@ void mp4s_del(GF_Box *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); - free(ptr); + gf_free(ptr); } GF_Err mp4s_AddBox(GF_Box *s, GF_Box *a) @@ -3603,7 +3588,7 @@ GF_Err mp4s_Read(GF_Box *s, GF_BitStream *bs) GF_Box *mp4s_New() { - GF_MPEGSampleEntryBox *tmp = (GF_MPEGSampleEntryBox *) malloc(sizeof(GF_MPEGSampleEntryBox)); + GF_MPEGSampleEntryBox *tmp = (GF_MPEGSampleEntryBox *) gf_malloc(sizeof(GF_MPEGSampleEntryBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_MPEGSampleEntryBox)); @@ -3618,8 +3603,8 @@ GF_Box *encs_New() return tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mp4s_Write(GF_Box *s, GF_BitStream *bs) { @@ -3657,7 +3642,7 @@ GF_Err mp4s_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void mp4v_del(GF_Box *s) { @@ -3666,6 +3651,7 @@ void mp4v_del(GF_Box *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); + if (ptr->svc_config) gf_isom_box_del((GF_Box *) ptr->svc_config); if (ptr->bitrate) gf_isom_box_del((GF_Box *) ptr->bitrate); if (ptr->descr) gf_isom_box_del((GF_Box *) ptr->descr); if (ptr->ipod_ext) gf_isom_box_del((GF_Box *)ptr->ipod_ext); @@ -3675,7 +3661,7 @@ void mp4v_del(GF_Box *s) if (ptr->pasp) gf_isom_box_del((GF_Box *)ptr->pasp); if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info); - free(ptr); + gf_free(ptr); } GF_Err mp4v_AddBox(GF_Box *s, GF_Box *a) @@ -3694,6 +3680,10 @@ GF_Err mp4v_AddBox(GF_Box *s, GF_Box *a) if (ptr->avc_config) return GF_ISOM_INVALID_FILE; ptr->avc_config = (GF_AVCConfigurationBox *)a; break; + case GF_ISOM_BOX_TYPE_SVCC: + if (ptr->svc_config) return GF_ISOM_INVALID_FILE; + ptr->svc_config = (GF_AVCConfigurationBox *)a; + break; case GF_ISOM_BOX_TYPE_BTRT: if (ptr->bitrate) return GF_ISOM_INVALID_FILE; ptr->bitrate = (GF_MPEG4BitRateBox *)a; @@ -3726,7 +3716,7 @@ GF_Err mp4v_Read(GF_Box *s, GF_BitStream *bs) e = gf_isom_read_box_list(s, bs, mp4v_AddBox); if (e) return e; /*this is an AVC sample desc*/ - if (mp4v->avc_config) AVC_RewriteESDescriptor(mp4v); + if (mp4v->avc_config || mp4v->svc_config) AVC_RewriteESDescriptor(mp4v); return GF_OK; } @@ -3750,13 +3740,23 @@ GF_Box *avc1_New() return mp4v_encv_avc1_new(GF_ISOM_BOX_TYPE_AVC1); } +GF_Box *avc2_New() +{ + return mp4v_encv_avc1_new(GF_ISOM_BOX_TYPE_AVC2); +} + +GF_Box *svc1_New() +{ + return mp4v_encv_avc1_new(GF_ISOM_BOX_TYPE_SVC1); +} + GF_Box *encv_New() { return mp4v_encv_avc1_new(GF_ISOM_BOX_TYPE_ENCV); } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mp4v_Write(GF_Box *s, GF_BitStream *bs) { @@ -3794,6 +3794,10 @@ GF_Err mp4v_Write(GF_Box *s, GF_BitStream *bs) e = gf_isom_box_write((GF_Box *) ptr->descr, bs); if (e) return e; } + if (ptr->svc_config && ptr->svc_config->config) { + e = gf_isom_box_write((GF_Box *) ptr->svc_config, 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); @@ -3815,12 +3819,20 @@ GF_Err mp4v_Size(GF_Box *s) e = gf_isom_box_size((GF_Box *)ptr->esd); if (e) return e; ptr->size += ptr->esd->size; - } else if (ptr->avc_config) { + } else { + if (!ptr->avc_config && !ptr->svc_config) + return GF_ISOM_INVALID_FILE; + if (ptr->avc_config && ptr->avc_config->config) { e = gf_isom_box_size((GF_Box *) ptr->avc_config); if (e) return e; ptr->size += ptr->avc_config->size; } + if (ptr->svc_config && ptr->svc_config->config) { + e = gf_isom_box_size((GF_Box *) ptr->svc_config); + if (e) return e; + ptr->size += ptr->svc_config->size; + } if (ptr->ipod_ext) { e = gf_isom_box_size((GF_Box *) ptr->ipod_ext); if (e) return e; @@ -3836,8 +3848,6 @@ GF_Err mp4v_Size(GF_Box *s) if (e) return e; ptr->size += ptr->descr->size; } - } else { - return GF_ISOM_INVALID_FILE; } if (ptr->pasp) { e = gf_isom_box_size((GF_Box *)ptr->pasp); @@ -3852,11 +3862,11 @@ GF_Err mp4v_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS void mvex_del(GF_Box *s) { @@ -3864,7 +3874,7 @@ void mvex_del(GF_Box *s) if (ptr == NULL) return; if (ptr->mehd) gf_isom_box_del((GF_Box*)ptr->mehd); gf_isom_box_array_del(ptr->TrackExList); - free(ptr); + gf_free(ptr); } @@ -3893,12 +3903,12 @@ GF_Err mvex_Read(GF_Box *s, GF_BitStream *bs) GF_Box *mvex_New() { - GF_MovieExtendsBox *tmp = (GF_MovieExtendsBox *) malloc(sizeof(GF_MovieExtendsBox)); + GF_MovieExtendsBox *tmp = (GF_MovieExtendsBox *) gf_malloc(sizeof(GF_MovieExtendsBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_MovieExtendsBox)); tmp->TrackExList = gf_list_new(); if (!tmp->TrackExList) { - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_MVEX; @@ -3906,8 +3916,8 @@ GF_Box *mvex_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mvex_Write(GF_Box *s, GF_BitStream *bs) @@ -3931,7 +3941,7 @@ GF_Err mvex_Size(GF_Box *s) -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *mehd_New() { @@ -3943,7 +3953,7 @@ GF_Box *mehd_New() } void mehd_del(GF_Box *s) { - free(s); + gf_free(s); } GF_Err mehd_Read(GF_Box *s, GF_BitStream *bs) { @@ -3959,7 +3969,7 @@ GF_Err mehd_Read(GF_Box *s, GF_BitStream *bs) } return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mehd_Write(GF_Box *s, GF_BitStream *bs) { GF_MovieExtendsHeaderBox *ptr = (GF_MovieExtendsHeaderBox *)s; @@ -3981,16 +3991,16 @@ GF_Err mehd_Size(GF_Box *s) s->size += (ptr->version == 1) ? 8 : 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#endif +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ void mvhd_del(GF_Box *s) { GF_MovieHeaderBox *ptr = (GF_MovieHeaderBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } @@ -4036,7 +4046,7 @@ GF_Err mvhd_Read(GF_Box *s, GF_BitStream *bs) GF_Box *mvhd_New() { - GF_MovieHeaderBox *tmp = (GF_MovieHeaderBox *) malloc(sizeof(GF_MovieHeaderBox)); + GF_MovieHeaderBox *tmp = (GF_MovieHeaderBox *) gf_malloc(sizeof(GF_MovieHeaderBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_MovieHeaderBox)); @@ -4054,8 +4064,8 @@ GF_Box *mvhd_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mvhd_Write(GF_Box *s, GF_BitStream *bs) { @@ -4108,14 +4118,14 @@ GF_Err mvhd_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void nmhd_del(GF_Box *s) { GF_MPEGMediaHeaderBox *ptr = (GF_MPEGMediaHeaderBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } @@ -4129,15 +4139,15 @@ GF_Err nmhd_Read(GF_Box *s, GF_BitStream *bs) GF_Box *nmhd_New() { - GF_MPEGMediaHeaderBox *tmp = (GF_MPEGMediaHeaderBox *) malloc(sizeof(GF_MPEGMediaHeaderBox)); + GF_MPEGMediaHeaderBox *tmp = (GF_MPEGMediaHeaderBox *) gf_malloc(sizeof(GF_MPEGMediaHeaderBox)); if (tmp == NULL) return NULL; gf_isom_full_box_init((GF_Box *) tmp); tmp->type = GF_ISOM_BOX_TYPE_NMHD; return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err nmhd_Write(GF_Box *s, GF_BitStream *bs) { @@ -4149,7 +4159,7 @@ GF_Err nmhd_Size(GF_Box *s) return gf_isom_full_box_get_size(s); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -4157,8 +4167,8 @@ void padb_del(GF_Box *s) { GF_PaddingBitsBox *ptr = (GF_PaddingBitsBox *) s; if (ptr == NULL) return; - if (ptr->padbits) free(ptr->padbits); - free(ptr); + if (ptr->padbits) gf_free(ptr->padbits); + gf_free(ptr); } @@ -4173,7 +4183,7 @@ GF_Err padb_Read(GF_Box *s,GF_BitStream *bs) ptr->SampleCount = gf_bs_read_u32(bs); - ptr->padbits = (u8 *)malloc(sizeof(u8)*ptr->SampleCount); + ptr->padbits = (u8 *)gf_malloc(sizeof(u8)*ptr->SampleCount); for (i=0; i<ptr->SampleCount; i += 2) { gf_bs_read_int(bs, 1); if (i+1 < ptr->SampleCount) { @@ -4191,7 +4201,7 @@ GF_Box *padb_New() { GF_PaddingBitsBox *tmp; - tmp = (GF_PaddingBitsBox *) malloc(sizeof(GF_PaddingBitsBox)); + tmp = (GF_PaddingBitsBox *) gf_malloc(sizeof(GF_PaddingBitsBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_PaddingBitsBox)); @@ -4201,8 +4211,8 @@ GF_Box *padb_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err padb_Write(GF_Box *s, GF_BitStream *bs) { @@ -4240,13 +4250,13 @@ GF_Err padb_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void rely_del(GF_Box *s) { GF_RelyHintBox *rely = (GF_RelyHintBox *)s; - free(rely); + gf_free(rely); } GF_Err rely_Read(GF_Box *s, GF_BitStream *bs) @@ -4260,7 +4270,7 @@ GF_Err rely_Read(GF_Box *s, GF_BitStream *bs) GF_Box *rely_New() { - GF_RelyHintBox *tmp = (GF_RelyHintBox *)malloc(sizeof(GF_RelyHintBox)); + 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; @@ -4269,7 +4279,7 @@ GF_Box *rely_New() } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err rely_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -4291,13 +4301,13 @@ GF_Err rely_Size(GF_Box *s) s->size += 1; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void rtpo_del(GF_Box *s) { GF_RTPOBox *rtpo = (GF_RTPOBox *)s; - free(rtpo); + gf_free(rtpo); } GF_Err rtpo_Read(GF_Box *s, GF_BitStream *bs) @@ -4309,13 +4319,13 @@ GF_Err rtpo_Read(GF_Box *s, GF_BitStream *bs) GF_Box *rtpo_New() { - GF_RTPOBox *tmp = (GF_RTPOBox *) malloc(sizeof(GF_RTPOBox)); + 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; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err rtpo_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -4338,13 +4348,13 @@ GF_Err rtpo_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void smhd_del(GF_Box *s) { GF_SoundMediaHeaderBox *ptr = (GF_SoundMediaHeaderBox *)s; if (ptr == NULL ) return; - free(ptr); + gf_free(ptr); } @@ -4360,7 +4370,7 @@ GF_Err smhd_Read(GF_Box *s, GF_BitStream *bs) GF_Box *smhd_New() { - GF_SoundMediaHeaderBox *tmp = (GF_SoundMediaHeaderBox *) malloc(sizeof(GF_SoundMediaHeaderBox)); + GF_SoundMediaHeaderBox *tmp = (GF_SoundMediaHeaderBox *) gf_malloc(sizeof(GF_SoundMediaHeaderBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_SoundMediaHeaderBox)); gf_isom_full_box_init((GF_Box *) tmp); @@ -4368,8 +4378,8 @@ GF_Box *smhd_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err smhd_Write(GF_Box *s, GF_BitStream *bs) { @@ -4392,14 +4402,14 @@ GF_Err smhd_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void snro_del(GF_Box *s) { GF_SeqOffHintEntryBox *snro = (GF_SeqOffHintEntryBox *)s; - free(snro); + gf_free(snro); } GF_Err snro_Read(GF_Box *s, GF_BitStream *bs) @@ -4411,7 +4421,7 @@ GF_Err snro_Read(GF_Box *s, GF_BitStream *bs) GF_Box *snro_New() { - GF_SeqOffHintEntryBox *tmp = (GF_SeqOffHintEntryBox *) malloc(sizeof(GF_SeqOffHintEntryBox)); + 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; @@ -4419,7 +4429,7 @@ GF_Box *snro_New() } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err snro_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -4440,7 +4450,7 @@ GF_Err snro_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ #define WRITE_SAMPLE_FRAGMENTS 1 @@ -4463,7 +4473,7 @@ void stbl_del(GF_Box *s) if (ptr->PaddingBits) gf_isom_box_del((GF_Box *) ptr->PaddingBits); if (ptr->Fragments) gf_isom_box_del((GF_Box *) ptr->Fragments); - free(ptr); + gf_free(ptr); } GF_Err stbl_AddBox(GF_SampleTableBox *ptr, GF_Box *a) @@ -4581,7 +4591,7 @@ GF_Err stbl_Read(GF_Box *s, GF_BitStream *bs) GF_Box *stbl_New() { - GF_SampleTableBox *tmp = (GF_SampleTableBox *) malloc(sizeof(GF_SampleTableBox)); + GF_SampleTableBox *tmp = (GF_SampleTableBox *) gf_malloc(sizeof(GF_SampleTableBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_SampleTableBox)); @@ -4593,8 +4603,8 @@ GF_Box *stbl_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stbl_Write(GF_Box *s, GF_BitStream *bs) { @@ -4737,15 +4747,15 @@ GF_Err stbl_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void stco_del(GF_Box *s) { GF_ChunkOffsetBox *ptr = (GF_ChunkOffsetBox *)s; if (ptr == NULL) return; - if (ptr->offsets) free(ptr->offsets); - free(ptr); + if (ptr->offsets) gf_free(ptr->offsets); + gf_free(ptr); } @@ -4760,7 +4770,7 @@ GF_Err stco_Read(GF_Box *s, GF_BitStream *bs) ptr->nb_entries = gf_bs_read_u32(bs); if (ptr->nb_entries) { - ptr->offsets = (u32 *) malloc(ptr->nb_entries * sizeof(u32) ); + ptr->offsets = (u32 *) gf_malloc(ptr->nb_entries * sizeof(u32) ); if (ptr->offsets == NULL) return GF_OUT_OF_MEM; ptr->alloc_size = ptr->nb_entries; @@ -4773,7 +4783,7 @@ GF_Err stco_Read(GF_Box *s, GF_BitStream *bs) GF_Box *stco_New() { - GF_ChunkOffsetBox *tmp = (GF_ChunkOffsetBox *) malloc(sizeof(GF_ChunkOffsetBox)); + GF_ChunkOffsetBox *tmp = (GF_ChunkOffsetBox *) gf_malloc(sizeof(GF_ChunkOffsetBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ChunkOffsetBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -4782,8 +4792,8 @@ GF_Box *stco_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stco_Write(GF_Box *s, GF_BitStream *bs) { @@ -4810,7 +4820,7 @@ GF_Err stco_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -4818,8 +4828,8 @@ void stdp_del(GF_Box *s) { GF_DegradationPriorityBox *ptr = (GF_DegradationPriorityBox *)s; if (ptr == NULL ) return; - if (ptr->priorities) free(ptr->priorities); - free(ptr); + if (ptr->priorities) gf_free(ptr->priorities); + gf_free(ptr); } //this is called through stbl_read... @@ -4833,7 +4843,7 @@ GF_Err stdp_Read(GF_Box *s, GF_BitStream *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; - ptr->priorities = (u16 *) malloc(ptr->nb_entries * sizeof(u16)); + 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 @@ -4845,7 +4855,7 @@ GF_Err stdp_Read(GF_Box *s, GF_BitStream *bs) GF_Box *stdp_New() { - GF_DegradationPriorityBox *tmp = (GF_DegradationPriorityBox *) malloc(sizeof(GF_DegradationPriorityBox)); + GF_DegradationPriorityBox *tmp = (GF_DegradationPriorityBox *) gf_malloc(sizeof(GF_DegradationPriorityBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_DegradationPriorityBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -4853,8 +4863,8 @@ GF_Box *stdp_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stdp_Write(GF_Box *s, GF_BitStream *bs) { @@ -4881,15 +4891,15 @@ GF_Err stdp_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void stsc_del(GF_Box *s) { GF_SampleToChunkBox *ptr = (GF_SampleToChunkBox *)s; if (ptr == NULL) return; - if (ptr->entries) free(ptr->entries); - free(ptr); + if (ptr->entries) gf_free(ptr->entries); + gf_free(ptr); } @@ -4903,7 +4913,7 @@ GF_Err stsc_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 = malloc(sizeof(GF_StscEntry)*ptr->alloc_size); + ptr->entries = gf_malloc(sizeof(GF_StscEntry)*ptr->alloc_size); if (!ptr->entries) return GF_OUT_OF_MEM; for (i = 0; i < ptr->nb_entries; i++) { @@ -4925,7 +4935,7 @@ GF_Err stsc_Read(GF_Box *s, GF_BitStream *bs) GF_Box *stsc_New() { - GF_SampleToChunkBox *tmp = (GF_SampleToChunkBox *) malloc(sizeof(GF_SampleToChunkBox)); + GF_SampleToChunkBox *tmp = (GF_SampleToChunkBox *) gf_malloc(sizeof(GF_SampleToChunkBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_SampleToChunkBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -4933,8 +4943,8 @@ GF_Box *stsc_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stsc_Write(GF_Box *s, GF_BitStream *bs) { @@ -4963,14 +4973,14 @@ GF_Err stsc_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void stsd_del(GF_Box *s) { GF_SampleDescriptionBox *ptr = (GF_SampleDescriptionBox *)s; if (ptr == NULL) return; gf_isom_box_array_del(ptr->boxList); - free(ptr); + gf_free(ptr); } GF_Err stsd_AddBox(GF_SampleDescriptionBox *ptr, GF_Box *a) @@ -4988,12 +4998,16 @@ GF_Err stsd_AddBox(GF_SampleDescriptionBox *ptr, GF_Box *a) case GF_ISOM_BOX_TYPE_GHNT: case GF_ISOM_BOX_TYPE_RTP_STSD: case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: case GF_ISOM_BOX_TYPE_TX3G: + case GF_ISOM_BOX_TYPE_TEXT: case GF_ISOM_BOX_TYPE_ENCT: case GF_ISOM_BOX_TYPE_METX: case GF_ISOM_BOX_TYPE_METT: 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); /*for 3GP config, we must set the type*/ case GF_ISOM_SUBTYPE_3GP_AMR: @@ -5047,21 +5061,21 @@ GF_Err stsd_Read(GF_Box *s, GF_BitStream *bs) GF_Box *stsd_New() { - GF_SampleDescriptionBox *tmp = (GF_SampleDescriptionBox *) malloc(sizeof(GF_SampleDescriptionBox)); + GF_SampleDescriptionBox *tmp = (GF_SampleDescriptionBox *) gf_malloc(sizeof(GF_SampleDescriptionBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_SampleDescriptionBox)); gf_isom_full_box_init((GF_Box *)tmp); tmp->boxList = gf_list_new(); if (! tmp->boxList) { - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_STSD; return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stsd_Write(GF_Box *s, GF_BitStream *bs) { @@ -5086,7 +5100,7 @@ GF_Err stsd_Size(GF_Box *s) return gf_isom_box_array_size(s, ptr->boxList); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void stsf_del(GF_Box *s) { @@ -5100,12 +5114,12 @@ void stsf_del(GF_Box *s) nb_entries = gf_list_count(ptr->entryList); for ( i = 0; i < nb_entries; i++ ) { pe = (GF_StsfEntry*)gf_list_get(ptr->entryList, i); - if (pe->fragmentSizes) free(pe->fragmentSizes); - free(pe); + if (pe->fragmentSizes) gf_free(pe->fragmentSizes); + gf_free(pe); } gf_list_del(ptr->entryList); } - free(ptr); + gf_free(ptr); } @@ -5126,17 +5140,17 @@ GF_Err stsf_Read(GF_Box *s, GF_BitStream *bs) p = NULL; for ( entries = 0; entries < nb_entries; entries++ ) { - p = (GF_StsfEntry *) malloc(sizeof(GF_StsfEntry)); + p = (GF_StsfEntry *) gf_malloc(sizeof(GF_StsfEntry)); if (!p) return GF_OUT_OF_MEM; p->SampleNumber = gf_bs_read_u32(bs); p->fragmentCount = gf_bs_read_u32(bs); - p->fragmentSizes = (u16*)malloc(sizeof(GF_StsfEntry) * p->fragmentCount); + p->fragmentSizes = (u16*)gf_malloc(sizeof(GF_StsfEntry) * p->fragmentCount); for (i=0; i<p->fragmentCount; i++) { p->fragmentSizes[i] = gf_bs_read_u16(bs); } gf_list_add(ptr->entryList, p); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE ptr->w_currentEntry = p; ptr->w_currentEntryIndex = nb_entries-1; #endif @@ -5147,14 +5161,14 @@ GF_Box *stsf_New() { GF_SampleFragmentBox *tmp; - tmp = (GF_SampleFragmentBox *) malloc(sizeof(GF_SampleFragmentBox)); + tmp = (GF_SampleFragmentBox *) gf_malloc(sizeof(GF_SampleFragmentBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_SampleFragmentBox)); gf_isom_full_box_init((GF_Box *) tmp); tmp->entryList = gf_list_new(); if (! tmp->entryList) { - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_STSF; @@ -5163,8 +5177,8 @@ GF_Box *stsf_New() -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stsf_Write(GF_Box *s, GF_BitStream *bs) { @@ -5207,7 +5221,7 @@ GF_Err stsf_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void stsh_del(GF_Box *s) { @@ -5216,10 +5230,10 @@ void stsh_del(GF_Box *s) GF_ShadowSyncBox *ptr = (GF_ShadowSyncBox *)s; if (ptr == NULL) return; while ( (ent = (GF_StshEntry *)gf_list_enum(ptr->entries, &i)) ) { - free(ent); + gf_free(ent); } gf_list_del(ptr->entries); - free(ptr); + gf_free(ptr); } @@ -5236,7 +5250,7 @@ GF_Err stsh_Read(GF_Box *s, GF_BitStream *bs) count = gf_bs_read_u32(bs); for (i = 0; i < count; i++) { - ent = (GF_StshEntry *) malloc(sizeof(GF_StshEntry)); + ent = (GF_StshEntry *) gf_malloc(sizeof(GF_StshEntry)); if (!ent) return GF_OUT_OF_MEM; ent->shadowedSampleNumber = gf_bs_read_u32(bs); ent->syncSampleNumber = gf_bs_read_u32(bs); @@ -5248,21 +5262,21 @@ GF_Err stsh_Read(GF_Box *s, GF_BitStream *bs) GF_Box *stsh_New() { - GF_ShadowSyncBox *tmp = (GF_ShadowSyncBox *) malloc(sizeof(GF_ShadowSyncBox)); + GF_ShadowSyncBox *tmp = (GF_ShadowSyncBox *) gf_malloc(sizeof(GF_ShadowSyncBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ShadowSyncBox)); gf_isom_full_box_init((GF_Box *)tmp); tmp->entries = gf_list_new(); if (!tmp->entries) { - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_STSH; return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stsh_Write(GF_Box *s, GF_BitStream *bs) { @@ -5292,7 +5306,7 @@ GF_Err stsh_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -5300,8 +5314,8 @@ void stss_del(GF_Box *s) { GF_SyncSampleBox *ptr = (GF_SyncSampleBox *)s; if (ptr == NULL) return; - if (ptr->sampleNumbers) free(ptr->sampleNumbers); - free(ptr); + if (ptr->sampleNumbers) gf_free(ptr->sampleNumbers); + gf_free(ptr); } GF_Err stss_Read(GF_Box *s, GF_BitStream *bs) @@ -5314,7 +5328,7 @@ GF_Err stss_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->sampleNumbers = (u32 *) malloc( ptr->alloc_size * sizeof(u32)); + ptr->sampleNumbers = (u32 *) gf_malloc( ptr->alloc_size * sizeof(u32)); if (ptr->sampleNumbers == NULL) return GF_OUT_OF_MEM; for (i = 0; i < ptr->nb_entries; i++) { @@ -5325,7 +5339,7 @@ GF_Err stss_Read(GF_Box *s, GF_BitStream *bs) GF_Box *stss_New() { - GF_SyncSampleBox *tmp = (GF_SyncSampleBox *) malloc(sizeof(GF_SyncSampleBox)); + GF_SyncSampleBox *tmp = (GF_SyncSampleBox *) gf_malloc(sizeof(GF_SyncSampleBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_SyncSampleBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -5333,8 +5347,8 @@ GF_Box *stss_New() return (GF_Box*)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stss_Write(GF_Box *s, GF_BitStream *bs) { @@ -5361,15 +5375,15 @@ GF_Err stss_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void stsz_del(GF_Box *s) { GF_SampleSizeBox *ptr = (GF_SampleSizeBox *)s; if (ptr == NULL) return; - if (ptr->sizes) free(ptr->sizes); - free(ptr); + if (ptr->sizes) gf_free(ptr->sizes); + gf_free(ptr); } @@ -5419,7 +5433,8 @@ GF_Err stsz_Read(GF_Box *s, GF_BitStream *bs) } if (s->type == GF_ISOM_BOX_TYPE_STSZ) { if (! ptr->sampleSize && ptr->sampleCount) { - ptr->sizes = (u32 *) malloc(ptr->sampleCount * sizeof(u32)); + ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32)); + ptr->alloc_size = ptr->sampleCount; if (! ptr->sizes) return GF_OUT_OF_MEM; for (i = 0; i < ptr->sampleCount; i++) { ptr->sizes[i] = gf_bs_read_u32(bs); @@ -5429,8 +5444,9 @@ GF_Err stsz_Read(GF_Box *s, GF_BitStream *bs) //note we could optimize the mem usage by keeping the table compact //in memory. But that would complicate both caching and editing //we therefore keep all sizes as u32 and uncompress the table - ptr->sizes = (u32 *) malloc(ptr->sampleCount * sizeof(u32)); + ptr->sizes = (u32 *) gf_malloc(ptr->sampleCount * sizeof(u32)); if (! ptr->sizes) return GF_OUT_OF_MEM; + ptr->alloc_size = ptr->sampleCount; for (i = 0; i < ptr->sampleCount; ) { switch (ptr->sampleSize) { @@ -5456,7 +5472,7 @@ GF_Err stsz_Read(GF_Box *s, GF_BitStream *bs) GF_Box *stsz_New() { - GF_SampleSizeBox *tmp = (GF_SampleSizeBox *) malloc(sizeof(GF_SampleSizeBox)); + GF_SampleSizeBox *tmp = (GF_SampleSizeBox *) gf_malloc(sizeof(GF_SampleSizeBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_SampleSizeBox)); @@ -5465,8 +5481,8 @@ GF_Box *stsz_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stsz_Write(GF_Box *s, GF_BitStream *bs) { @@ -5557,7 +5573,7 @@ GF_Err stsz_Size(GF_Box *s) if (size) { ptr->type = GF_ISOM_BOX_TYPE_STSZ; ptr->sampleSize = size; - free(ptr->sizes); + gf_free(ptr->sizes); ptr->sizes = NULL; } @@ -5580,14 +5596,14 @@ GF_Err stsz_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void stts_del(GF_Box *s) { GF_TimeToSampleBox *ptr = (GF_TimeToSampleBox *)s; - if (ptr->entries) free(ptr->entries); - free(ptr); + if (ptr->entries) gf_free(ptr->entries); + gf_free(ptr); } @@ -5600,23 +5616,23 @@ GF_Err stts_Read(GF_Box *s, GF_BitStream *bs) e = gf_isom_full_box_read(s, bs); if (e) return e; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE ptr->w_LastDTS = 0; #endif ptr->nb_entries = gf_bs_read_u32(bs); ptr->alloc_size = ptr->nb_entries; - ptr->entries = malloc(sizeof(GF_SttsEntry)*ptr->alloc_size); + ptr->entries = gf_malloc(sizeof(GF_SttsEntry)*ptr->alloc_size); if (!ptr->entries) return GF_OUT_OF_MEM; for (i=0; i<ptr->nb_entries; i++) { ptr->entries[i].sampleCount = gf_bs_read_u32(bs); ptr->entries[i].sampleDelta = gf_bs_read_u32(bs); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE ptr->w_currentSampleNum += ptr->entries[i].sampleCount; ptr->w_LastDTS += ptr->entries[i].sampleCount * ptr->entries[i].sampleDelta; #endif } //remove the last sample delta. -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE if (ptr->nb_entries) ptr->w_LastDTS -= ptr->entries[ptr->nb_entries-1].sampleDelta; #endif return GF_OK; @@ -5624,7 +5640,7 @@ GF_Err stts_Read(GF_Box *s, GF_BitStream *bs) GF_Box *stts_New() { - GF_TimeToSampleBox *tmp = (GF_TimeToSampleBox *) malloc(sizeof(GF_TimeToSampleBox)); + GF_TimeToSampleBox *tmp = (GF_TimeToSampleBox *) gf_malloc(sizeof(GF_TimeToSampleBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_TimeToSampleBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -5632,8 +5648,8 @@ GF_Box *stts_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err stts_Write(GF_Box *s, GF_BitStream *bs) { @@ -5662,16 +5678,16 @@ GF_Err stts_Size(GF_Box *s) } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS void tfhd_del(GF_Box *s) { GF_TrackFragmentHeaderBox *ptr = (GF_TrackFragmentHeaderBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } GF_Err tfhd_Read(GF_Box *s, GF_BitStream *bs) @@ -5705,7 +5721,7 @@ GF_Err tfhd_Read(GF_Box *s, GF_BitStream *bs) GF_Box *tfhd_New() { - GF_TrackFragmentHeaderBox *tmp = (GF_TrackFragmentHeaderBox *) malloc(sizeof(GF_TrackFragmentHeaderBox)); + 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; @@ -5714,8 +5730,8 @@ GF_Box *tfhd_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tfhd_Write(GF_Box *s, GF_BitStream *bs) @@ -5766,14 +5782,14 @@ GF_Err tfhd_Size(GF_Box *s) -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#endif +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ void tims_del(GF_Box *s) { GF_TSHintEntryBox *tims = (GF_TSHintEntryBox *)s; - free(tims); + gf_free(tims); } GF_Err tims_Read(GF_Box *s, GF_BitStream *bs) @@ -5785,14 +5801,14 @@ GF_Err tims_Read(GF_Box *s, GF_BitStream *bs) GF_Box *tims_New() { - GF_TSHintEntryBox *tmp = (GF_TSHintEntryBox *) malloc(sizeof(GF_TSHintEntryBox)); + 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; return (GF_Box *)tmp; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tims_Write(GF_Box *s, GF_BitStream *bs) { @@ -5814,14 +5830,14 @@ GF_Err tims_Size(GF_Box *s) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void tkhd_del(GF_Box *s) { GF_TrackHeaderBox *ptr = (GF_TrackHeaderBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); return; } @@ -5867,7 +5883,7 @@ GF_Err tkhd_Read(GF_Box *s, GF_BitStream *bs) GF_Box *tkhd_New() { - GF_TrackHeaderBox *tmp = (GF_TrackHeaderBox *) malloc(sizeof(GF_TrackHeaderBox)); + GF_TrackHeaderBox *tmp = (GF_TrackHeaderBox *) gf_malloc(sizeof(GF_TrackHeaderBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_TrackHeaderBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -5879,8 +5895,8 @@ GF_Box *tkhd_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tkhd_Write(GF_Box *s, GF_BitStream *bs) { @@ -5934,19 +5950,20 @@ GF_Err tkhd_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS void traf_del(GF_Box *s) { GF_TrackFragmentBox *ptr = (GF_TrackFragmentBox *)s; if (ptr == NULL) return; if (ptr->tfhd) gf_isom_box_del((GF_Box *) ptr->tfhd); + if (ptr->sdtp) gf_isom_box_del((GF_Box *) ptr->sdtp); gf_isom_box_array_del(ptr->TrackRuns); - free(ptr); + gf_free(ptr); } GF_Err traf_AddBox(GF_Box *s, GF_Box *a) @@ -5960,7 +5977,14 @@ GF_Err traf_AddBox(GF_Box *s, GF_Box *a) return GF_OK; case GF_ISOM_BOX_TYPE_TRUN: return gf_list_add(ptr->TrackRuns, a); - + case GF_ISOM_BOX_TYPE_SDTP: + if (ptr->sdtp) return GF_ISOM_INVALID_FILE; + ptr->sdtp = (GF_SampleDependencyTypeBox *)a; + return GF_OK; + case GF_ISOM_BOX_TYPE_TFAD: + if (ptr->tfad) return GF_ISOM_INVALID_FILE; + ptr->tfad = a; + return GF_OK; default: return GF_ISOM_INVALID_FILE; } @@ -5969,12 +5993,13 @@ GF_Err traf_AddBox(GF_Box *s, GF_Box *a) GF_Err traf_Read(GF_Box *s, GF_BitStream *bs) { - return gf_isom_read_box_list(s, bs, traf_AddBox); + GF_Err e = gf_isom_read_box_list(s, bs, traf_AddBox); + return e; } GF_Box *traf_New() { - GF_TrackFragmentBox *tmp = (GF_TrackFragmentBox *) malloc(sizeof(GF_TrackFragmentBox)); + GF_TrackFragmentBox *tmp = (GF_TrackFragmentBox *) gf_malloc(sizeof(GF_TrackFragmentBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_TrackFragmentBox)); tmp->type = GF_ISOM_BOX_TYPE_TRAF; @@ -5983,8 +6008,8 @@ GF_Box *traf_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err traf_Write(GF_Box *s, GF_BitStream *bs) @@ -6001,7 +6026,12 @@ GF_Err traf_Write(GF_Box *s, GF_BitStream *bs) e = gf_isom_box_write((GF_Box *) ptr->tfhd, bs); if (e) return e; } - return gf_isom_box_array_write(s, ptr->TrackRuns, bs); + e = gf_isom_box_array_write(s, ptr->TrackRuns, bs); + if (e) return e; + if (ptr->sdtp) { + e = gf_isom_box_write((GF_Box *) ptr->sdtp, bs); + } + return e; } GF_Err traf_Size(GF_Box *s) @@ -6016,14 +6046,20 @@ GF_Err traf_Size(GF_Box *s) if (e) return e; ptr->size += ptr->tfhd->size; } + if (ptr->sdtp) { + e = gf_isom_box_size((GF_Box *) ptr->sdtp); + if (e) return e; + ptr->size += ptr->sdtp->size; + } return gf_isom_box_array_size(s, ptr->TrackRuns); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#endif +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ + void trak_del(GF_Box *s) { @@ -6037,8 +6073,8 @@ void trak_del(GF_Box *s) 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) free(ptr->name); - free(ptr); + if (ptr->name) gf_free(ptr->name); + gf_free(ptr); } static void gf_isom_check_sample_desc(GF_TrackBox *trak) @@ -6069,10 +6105,16 @@ static void gf_isom_check_sample_desc(GF_TrackBox *trak) case GF_ISOM_BOX_TYPE_GHNT: case GF_ISOM_BOX_TYPE_RTP_STSD: case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_METX: + case GF_ISOM_BOX_TYPE_METT: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: case GF_ISOM_BOX_TYPE_TX3G: + case GF_ISOM_BOX_TYPE_TEXT: case GF_ISOM_BOX_TYPE_ENCT: case GF_ISOM_BOX_TYPE_DIMS: case GF_ISOM_BOX_TYPE_AC3: + case GF_ISOM_BOX_TYPE_LSR1: continue; default: break; @@ -6088,7 +6130,7 @@ static void gf_isom_check_sample_desc(GF_TrackBox *trak) gf_isom_video_sample_entry_read((GF_VisualSampleEntryBox *) genv, bs); genv->data_size = (u32) gf_bs_available(bs); if (genv->data_size) { - genv->data = (char*)malloc(sizeof(char) * genv->data_size); + genv->data = (char*)gf_malloc(sizeof(char) * genv->data_size); gf_bs_read_data(bs, genv->data, genv->data_size); } gf_bs_del(bs); @@ -6106,7 +6148,7 @@ static void gf_isom_check_sample_desc(GF_TrackBox *trak) gf_isom_audio_sample_entry_read((GF_AudioSampleEntryBox *) gena, bs); gena->data_size = (u32) gf_bs_available(bs); if (gena->data_size) { - gena->data = (char*)malloc(sizeof(char) * gena->data_size); + gena->data = (char*)gf_malloc(sizeof(char) * gena->data_size); gf_bs_read_data(bs, gena->data, gena->data_size); } gf_bs_del(bs); @@ -6127,7 +6169,7 @@ static void gf_isom_check_sample_desc(GF_TrackBox *trak) genm->dataReferenceIndex = gf_bs_read_u16(bs); genm->data_size = (u32) gf_bs_available(bs); if (genm->data_size) { - genm->data = (char*)malloc(sizeof(char) * genm->data_size); + genm->data = (char*)gf_malloc(sizeof(char) * genm->data_size); gf_bs_read_data(bs, genm->data, genm->data_size); } gf_bs_del(bs); @@ -6192,7 +6234,7 @@ GF_Err trak_Read(GF_Box *s, GF_BitStream *bs) GF_Box *trak_New() { - GF_TrackBox *tmp = (GF_TrackBox *) malloc(sizeof(GF_TrackBox)); + 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; @@ -6200,8 +6242,8 @@ GF_Box *trak_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err trak_Write(GF_Box *s, GF_BitStream *bs) { @@ -6278,7 +6320,7 @@ GF_Err trak_Size(GF_Box *s) return gf_isom_box_array_size(s, ptr->boxes); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void tref_del(GF_Box *s) @@ -6286,7 +6328,7 @@ void tref_del(GF_Box *s) GF_TrackReferenceBox *ptr = (GF_TrackReferenceBox *)s; if (ptr == NULL) return; gf_isom_box_array_del(ptr->boxList); - free(ptr); + gf_free(ptr); } @@ -6303,12 +6345,12 @@ GF_Err tref_Read(GF_Box *s, GF_BitStream *bs) GF_Box *tref_New() { - GF_TrackReferenceBox *tmp = (GF_TrackReferenceBox *) malloc(sizeof(GF_TrackReferenceBox)); + 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) { - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_TREF; @@ -6316,8 +6358,8 @@ GF_Box *tref_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tref_Write(GF_Box *s, GF_BitStream *bs) { @@ -6337,14 +6379,14 @@ GF_Err tref_Size(GF_Box *s) return gf_isom_box_array_size(s, ptr->boxList); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void reftype_del(GF_Box *s) { GF_TrackReferenceTypeBox *ptr = (GF_TrackReferenceTypeBox *)s; if (!ptr) return; - if (ptr->trackIDs) free(ptr->trackIDs); - free(ptr); + if (ptr->trackIDs) gf_free(ptr->trackIDs); + gf_free(ptr); } @@ -6358,7 +6400,7 @@ GF_Err reftype_Read(GF_Box *s, GF_BitStream *bs) if (!bytesToRead) return GF_OK; ptr->trackIDCount = (u32) (bytesToRead) / sizeof(u32); - ptr->trackIDs = (u32 *) malloc(ptr->trackIDCount * sizeof(u32)); + ptr->trackIDs = (u32 *) gf_malloc(ptr->trackIDCount * sizeof(u32)); if (!ptr->trackIDs) return GF_OUT_OF_MEM; for (i = 0; i < ptr->trackIDCount; i++) { @@ -6369,7 +6411,7 @@ GF_Err reftype_Read(GF_Box *s, GF_BitStream *bs) GF_Box *reftype_New() { - GF_TrackReferenceTypeBox *tmp = (GF_TrackReferenceTypeBox *) malloc(sizeof(GF_TrackReferenceTypeBox)); + 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; @@ -6391,7 +6433,7 @@ GF_Err reftype_AddRefTrack(GF_TrackReferenceTypeBox *ref, u32 trackID, u16 *outR } } - ref->trackIDs = (u32 *) realloc(ref->trackIDs, (ref->trackIDCount + 1) * sizeof(u32) ); + ref->trackIDs = (u32 *) gf_realloc(ref->trackIDs, (ref->trackIDCount + 1) * sizeof(u32) ); if (!ref->trackIDs) return GF_OUT_OF_MEM; ref->trackIDs[ref->trackIDCount] = trackID; ref->trackIDCount++; @@ -6400,8 +6442,8 @@ GF_Err reftype_AddRefTrack(GF_TrackReferenceTypeBox *ref, u32 trackID, u16 *outR } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err reftype_Write(GF_Box *s, GF_BitStream *bs) { @@ -6429,17 +6471,17 @@ GF_Err reftype_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS void trex_del(GF_Box *s) { GF_TrackExtendsBox *ptr = (GF_TrackExtendsBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } @@ -6461,7 +6503,7 @@ GF_Err trex_Read(GF_Box *s, GF_BitStream *bs) GF_Box *trex_New() { - GF_TrackExtendsBox *tmp = (GF_TrackExtendsBox *) malloc(sizeof(GF_TrackExtendsBox)); + 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; @@ -6469,8 +6511,8 @@ GF_Box *trex_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err trex_Write(GF_Box *s, GF_BitStream *bs) @@ -6501,12 +6543,13 @@ GF_Err trex_Size(GF_Box *s) -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ -#endif -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS void trun_del(GF_Box *s) { @@ -6517,11 +6560,11 @@ void trun_del(GF_Box *s) while (gf_list_count(ptr->entries)) { p = (GF_TrunEntry*)gf_list_get(ptr->entries, 0); gf_list_rem(ptr->entries, 0); - free(p); + gf_free(p); } gf_list_del(ptr->entries); if (ptr->cache) gf_bs_del(ptr->cache); - free(ptr); + gf_free(ptr); } GF_Err trun_Read(GF_Box *s, GF_BitStream *bs) @@ -6553,7 +6596,7 @@ GF_Err trun_Read(GF_Box *s, GF_BitStream *bs) //read each entry (even though nothing may be written) for (i=0; i<ptr->sample_count; i++) { u32 trun_size = 0; - p = (GF_TrunEntry *) malloc(sizeof(GF_TrunEntry)); + p = (GF_TrunEntry *) gf_malloc(sizeof(GF_TrunEntry)); memset(p, 0, sizeof(GF_TrunEntry)); if (ptr->flags & GF_ISOM_TRUN_DURATION) { @@ -6581,7 +6624,7 @@ GF_Err trun_Read(GF_Box *s, GF_BitStream *bs) GF_Box *trun_New() { - GF_TrackFragmentRunBox *tmp = (GF_TrackFragmentRunBox *) malloc(sizeof(GF_TrackFragmentRunBox)); + 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; @@ -6591,8 +6634,8 @@ GF_Box *trun_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err trun_Write(GF_Box *s, GF_BitStream *bs) @@ -6669,14 +6712,15 @@ GF_Err trun_Size(GF_Box *s) -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ -#endif +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ + void tsro_del(GF_Box *s) { GF_TimeOffHintEntryBox *tsro = (GF_TimeOffHintEntryBox *)s; - free(tsro); + gf_free(tsro); } GF_Err tsro_Read(GF_Box *s, GF_BitStream *bs) @@ -6688,7 +6732,7 @@ GF_Err tsro_Read(GF_Box *s, GF_BitStream *bs) GF_Box *tsro_New() { - GF_TimeOffHintEntryBox *tmp = (GF_TimeOffHintEntryBox *) malloc(sizeof(GF_TimeOffHintEntryBox)); + 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; @@ -6696,7 +6740,7 @@ GF_Box *tsro_New() } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err tsro_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -6717,7 +6761,7 @@ GF_Err tsro_Size(GF_Box *s) s->size += 4; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void udta_del(GF_Box *s) @@ -6729,10 +6773,10 @@ void udta_del(GF_Box *s) i=0; while ((map = (GF_UserDataMap *)gf_list_enum(ptr->recordList, &i))) { gf_isom_box_array_del(map->boxList); - free(map); + gf_free(map); } gf_list_del(ptr->recordList); - free(ptr); + gf_free(ptr); } GF_UserDataMap *udta_getEntry(GF_UserDataBox *ptr, u32 box_type, bin128 *uuid) @@ -6758,7 +6802,7 @@ GF_Err udta_AddBox(GF_UserDataBox *ptr, GF_Box *a) map = udta_getEntry(ptr, a->type, (a->type==GF_ISOM_BOX_TYPE_UUID) ? & ((GF_UUIDBox *)a)->uuid : NULL); if (map == NULL) { - map = (GF_UserDataMap *) malloc(sizeof(GF_UserDataMap)); + map = (GF_UserDataMap *) gf_malloc(sizeof(GF_UserDataMap)); if (map == NULL) return GF_OUT_OF_MEM; memset(map, 0, sizeof(GF_UserDataMap)); @@ -6767,7 +6811,7 @@ GF_Err udta_AddBox(GF_UserDataBox *ptr, GF_Box *a) memcpy(map->uuid, ((GF_UUIDBox *)a)->uuid, 16); map->boxList = gf_list_new(); if (!map->boxList) { - free(map); + gf_free(map); return GF_OUT_OF_MEM; } e = gf_list_add(ptr->recordList, map); @@ -6803,20 +6847,20 @@ GF_Err udta_Read(GF_Box *s, GF_BitStream *bs) GF_Box *udta_New() { - GF_UserDataBox *tmp = (GF_UserDataBox *) malloc(sizeof(GF_UserDataBox)); + GF_UserDataBox *tmp = (GF_UserDataBox *) gf_malloc(sizeof(GF_UserDataBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_UserDataBox)); tmp->recordList = gf_list_new(); if (!tmp->recordList) { - free(tmp); + gf_free(tmp); return NULL; } tmp->type = GF_ISOM_BOX_TYPE_UDTA; return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err udta_Write(GF_Box *s, GF_BitStream *bs) { @@ -6856,14 +6900,14 @@ GF_Err udta_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void vmhd_del(GF_Box *s) { GF_VideoMediaHeaderBox *ptr = (GF_VideoMediaHeaderBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } @@ -6879,7 +6923,7 @@ GF_Err vmhd_Read(GF_Box *s, GF_BitStream *bs) GF_Box *vmhd_New() { - GF_VideoMediaHeaderBox *tmp = (GF_VideoMediaHeaderBox *) malloc(sizeof(GF_VideoMediaHeaderBox)); + GF_VideoMediaHeaderBox *tmp = (GF_VideoMediaHeaderBox *) gf_malloc(sizeof(GF_VideoMediaHeaderBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_VideoMediaHeaderBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -6889,8 +6933,8 @@ GF_Box *vmhd_New() } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err vmhd_Write(GF_Box *s, GF_BitStream *bs) { @@ -6913,12 +6957,12 @@ GF_Err vmhd_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ void void_del(GF_Box *s) { - free(s); + gf_free(s); } @@ -6930,14 +6974,14 @@ GF_Err void_Read(GF_Box *s, GF_BitStream *bs) GF_Box *void_New() { - GF_Box *tmp = (GF_Box *) malloc(sizeof(GF_Box)); + GF_Box *tmp = (GF_Box *) gf_malloc(sizeof(GF_Box)); if (!tmp) return NULL; tmp->type = GF_ISOM_BOX_TYPE_VOID; return tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err void_Write(GF_Box *s, GF_BitStream *bs) { @@ -6951,13 +6995,13 @@ GF_Err void_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *pdin_New() { - GF_ProgressiveDownloadBox *tmp = (GF_ProgressiveDownloadBox*) malloc(sizeof(GF_ProgressiveDownloadBox)); + GF_ProgressiveDownloadBox *tmp = (GF_ProgressiveDownloadBox*) gf_malloc(sizeof(GF_ProgressiveDownloadBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ProgressiveDownloadBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -6971,9 +7015,9 @@ void pdin_del(GF_Box *s) { GF_ProgressiveDownloadBox *ptr = (GF_ProgressiveDownloadBox*)s; if (ptr == NULL) return; - if (ptr->rates) free(ptr->rates); - if (ptr->times) free(ptr->times); - free(ptr); + if (ptr->rates) gf_free(ptr->rates); + if (ptr->times) gf_free(ptr->times); + gf_free(ptr); } @@ -6987,8 +7031,8 @@ GF_Err pdin_Read(GF_Box *s, GF_BitStream *bs) if (e) return e; ptr->count = (u32) (ptr->size) / 8; - ptr->rates = (u32*)malloc(sizeof(u32)*ptr->count); - ptr->times = (u32*)malloc(sizeof(u32)*ptr->count); + ptr->rates = (u32*)gf_malloc(sizeof(u32)*ptr->count); + ptr->times = (u32*)gf_malloc(sizeof(u32)*ptr->count); for (i=0; i<ptr->count; i++) { ptr->rates[i] = gf_bs_read_u32(bs); ptr->times[i] = gf_bs_read_u32(bs); @@ -6996,8 +7040,8 @@ GF_Err pdin_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err pdin_Write(GF_Box *s, GF_BitStream *bs) { @@ -7023,14 +7067,14 @@ GF_Err pdin_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *sdtp_New() { - GF_SampleDependencyTypeBox *tmp = (GF_SampleDependencyTypeBox*) malloc(sizeof(GF_SampleDependencyTypeBox)); + GF_SampleDependencyTypeBox *tmp = (GF_SampleDependencyTypeBox*) gf_malloc(sizeof(GF_SampleDependencyTypeBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_SampleDependencyTypeBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -7044,8 +7088,8 @@ void sdtp_del(GF_Box *s) { GF_SampleDependencyTypeBox *ptr = (GF_SampleDependencyTypeBox*)s; if (ptr == NULL) return; - if (ptr->sample_info) free(ptr->sample_info); - free(ptr); + if (ptr->sample_info) gf_free(ptr->sample_info); + gf_free(ptr); } @@ -7058,14 +7102,14 @@ GF_Err sdtp_Read(GF_Box *s, GF_BitStream *bs) if (e) return e; /*out-of-order sdtp, assume no padding at the end*/ if (!ptr->sampleCount) ptr->sampleCount = (u32) (ptr->size - 8); - ptr->sample_info = (u8 *) malloc(sizeof(u8)*ptr->sampleCount); + ptr->sample_info = (u8 *) gf_malloc(sizeof(u8)*ptr->sampleCount); gf_bs_read_data(bs, (char*)ptr->sample_info, ptr->sampleCount); ptr->size -= ptr->sampleCount; return GF_OK; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err sdtp_Write(GF_Box *s, GF_BitStream *bs) { @@ -7087,7 +7131,7 @@ GF_Err sdtp_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *pasp_New() @@ -7104,7 +7148,7 @@ void pasp_del(GF_Box *s) { GF_PixelAspectRatioBox *ptr = (GF_PixelAspectRatioBox*)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } @@ -7117,8 +7161,8 @@ GF_Err pasp_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err pasp_Write(GF_Box *s, GF_BitStream *bs) { @@ -7138,7 +7182,7 @@ GF_Err pasp_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -7157,11 +7201,11 @@ void metx_del(GF_Box *s) { GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s; if (ptr == NULL) return; - if (ptr->content_encoding) free(ptr->content_encoding); - if (ptr->mime_type_or_namespace) free(ptr->mime_type_or_namespace); - if (ptr->xml_schema_loc) free(ptr->xml_schema_loc); + 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); if (ptr->bitrate) gf_isom_box_del((GF_Box *) ptr->bitrate); - free(ptr); + gf_free(ptr); } @@ -7189,45 +7233,52 @@ GF_Err metx_Read(GF_Box *s, GF_BitStream *bs) u32 size, i; char *str; GF_MetaDataSampleEntryBox *ptr = (GF_MetaDataSampleEntryBox*)s; - size = (u32) ptr->size; - str = malloc(sizeof(char)*size); + + gf_bs_read_data(bs, ptr->reserved, 6); + ptr->dataReferenceIndex = gf_bs_read_u16(bs); + + size = (u32) ptr->size - 8; + str = gf_malloc(sizeof(char)*size); + i=0; - while (i<size) { + + while (size) { str[i] = gf_bs_read_u8(bs); size--; if (!str[i]) break; i++; } - if (i) ptr->content_encoding = strdup(str); + if (i) ptr->content_encoding = gf_strdup(str); i=0; - while (i<size) { + while (size) { str[i] = gf_bs_read_u8(bs); size--; if (!str[i]) break; i++; } - if (i) ptr->mime_type_or_namespace = strdup(str); + if (i) ptr->mime_type_or_namespace = gf_strdup(str); if (ptr->type==GF_ISOM_BOX_TYPE_METX) { i=0; - while (i<size) { + while (size) { str[i] = gf_bs_read_u8(bs); size--; if (!str[i]) break; i++; } - if (i) ptr->xml_schema_loc = strdup(str); + if (i) ptr->xml_schema_loc = gf_strdup(str); } ptr->size = size; + gf_free(str); return gf_isom_read_box_list(s, bs, metx_AddBox); } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err metx_Write(GF_Box *s, GF_BitStream *bs) { @@ -7291,13 +7342,13 @@ GF_Err metx_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *dac3_New() { - GF_AC3ConfigBox *tmp = (GF_AC3ConfigBox *) malloc(sizeof(GF_AC3ConfigBox)); + 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; @@ -7307,7 +7358,7 @@ GF_Box *dac3_New() void dac3_del(GF_Box *s) { GF_AC3ConfigBox *ptr = (GF_AC3ConfigBox *)s; - free(ptr); + gf_free(ptr); } @@ -7326,8 +7377,8 @@ GF_Err dac3_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err dac3_Write(GF_Box *s, GF_BitStream *bs) { @@ -7355,7 +7406,7 @@ GF_Err dac3_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -7365,7 +7416,7 @@ void ac3_del(GF_Box *s) if (ptr == NULL) return; if (ptr->info) gf_isom_box_del((GF_Box *)ptr->info); if (ptr->protection_info) gf_isom_box_del((GF_Box *)ptr->protection_info); - free(ptr); + gf_free(ptr); } @@ -7390,13 +7441,13 @@ GF_Box *ac3_New() return (GF_Box *)tmp; } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ac3_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; - GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s; + GF_AC3SampleEntryBox *ptr = (GF_AC3SampleEntryBox *)s; e = gf_isom_box_write_header(s, bs); if (e) return e; gf_isom_audio_sample_entry_write((GF_AudioSampleEntryBox*)s, bs); @@ -7406,7 +7457,7 @@ GF_Err ac3_Write(GF_Box *s, GF_BitStream *bs) GF_Err ac3_Size(GF_Box *s) { GF_Err e; - GF_3GPPAudioSampleEntryBox *ptr = (GF_3GPPAudioSampleEntryBox *)s; + GF_AC3SampleEntryBox *ptr = (GF_AC3SampleEntryBox *)s; e = gf_isom_box_get_size(s); if (e) return e; gf_isom_audio_sample_entry_size((GF_AudioSampleEntryBox*)s); @@ -7416,4 +7467,279 @@ GF_Err ac3_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + + +void lsrc_del(GF_Box *s) +{ + GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s; + if (ptr == NULL) return; + if (ptr->hdr) gf_free(ptr->hdr); + gf_free(ptr); +} + + +GF_Err lsrc_Read(GF_Box *s, GF_BitStream *bs) +{ + GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s; + ptr->hdr_size = (u32) ptr->size; + ptr->hdr = gf_malloc(sizeof(char)*ptr->hdr_size); + gf_bs_read_data(bs, ptr->hdr, ptr->hdr_size); + return GF_OK; +} + +GF_Box *lsrc_New() +{ + GF_LASERConfigurationBox *tmp; + GF_SAFEALLOC(tmp, GF_LASERConfigurationBox); + if (tmp == NULL) return NULL; + tmp->type = GF_ISOM_BOX_TYPE_LSRC; + return (GF_Box *)tmp; +} + + +#ifndef GPAC_DISABLE_ISOM_WRITE + +GF_Err lsrc_Write(GF_Box *s, GF_BitStream *bs) +{ + GF_Err e; + GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s; + e = gf_isom_box_write_header(s, bs); + if (e) return e; + gf_bs_write_data(bs, ptr->hdr, ptr->hdr_size); + return GF_OK; +} + +GF_Err lsrc_Size(GF_Box *s) +{ + GF_Err e; + GF_LASERConfigurationBox *ptr = (GF_LASERConfigurationBox *)s; + e = gf_isom_box_get_size(s); + if (e) return e; + ptr->size += ptr->hdr_size; + return GF_OK; +} + +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + + +void lsr1_del(GF_Box *s) +{ + GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s; + if (ptr == NULL) return; + 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); + if (ptr->descr) gf_isom_box_del((GF_Box *) ptr->descr); + gf_free(ptr); +} + +GF_Err lsr1_AddBox(GF_Box *s, GF_Box *a) +{ + GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s; + switch (a->type) { + case GF_ISOM_BOX_TYPE_LSRC: + if (ptr->lsr_config) return GF_ISOM_INVALID_FILE; + ptr->lsr_config = (GF_LASERConfigurationBox *)a; + break; + case GF_ISOM_BOX_TYPE_BTRT: + if (ptr->bitrate) return GF_ISOM_INVALID_FILE; + ptr->bitrate = (GF_MPEG4BitRateBox *)a; + break; + case GF_ISOM_BOX_TYPE_M4DS: + if (ptr->descr) return GF_ISOM_INVALID_FILE; + ptr->descr = (GF_MPEG4ExtensionDescriptorsBox *)a; + break; + default: + gf_isom_box_del(a); + break; + } + return GF_OK; +} + +GF_Err lsr1_Read(GF_Box *s, GF_BitStream *bs) +{ + GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox*)s; + gf_bs_read_data(bs, ptr->reserved, 6); + ptr->dataReferenceIndex = gf_bs_read_u16(bs); + ptr->size -= 8; + return gf_isom_read_box_list(s, bs, lsr1_AddBox); +} + +GF_Box *lsr1_New() +{ + GF_LASeRSampleEntryBox *tmp; + GF_SAFEALLOC(tmp, GF_LASeRSampleEntryBox); + if (tmp == NULL) return NULL; + tmp->type = GF_ISOM_BOX_TYPE_LSR1; + return (GF_Box *)tmp; +} + + +#ifndef GPAC_DISABLE_ISOM_WRITE + + +GF_Err lsr1_Write(GF_Box *s, GF_BitStream *bs) +{ + GF_Err e; + GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s; + e = gf_isom_box_write_header(s, bs); + if (e) return e; + + gf_bs_write_data(bs, ptr->reserved, 6); + gf_bs_write_u16(bs, ptr->dataReferenceIndex); + if (ptr->lsr_config) { + e = gf_isom_box_write((GF_Box *)ptr->lsr_config, bs); + if (e) return e; + } + if (ptr->descr) { + e = gf_isom_box_write((GF_Box *)ptr->descr, bs); + if (e) return e; + } + if (ptr->bitrate) { + e = gf_isom_box_write((GF_Box *)ptr->bitrate, bs); + if (e) return e; + } + return e; +} + +GF_Err lsr1_Size(GF_Box *s) +{ + GF_Err e; + GF_LASeRSampleEntryBox *ptr = (GF_LASeRSampleEntryBox *)s; + e = gf_isom_box_get_size(s); + if (e) return e; + s->size += 8; + if (ptr->lsr_config) { + e = gf_isom_box_size((GF_Box *)ptr->lsr_config); + if (e) return e; + ptr->size += ptr->lsr_config->size; + } + if (ptr->bitrate) { + e = gf_isom_box_size((GF_Box *)ptr->bitrate); + if (e) return e; + ptr->size += ptr->bitrate->size; + } + if (ptr->descr) { + e = gf_isom_box_size((GF_Box *)ptr->bitrate); + if (e) return e; + ptr->size += ptr->bitrate->size; + } + return GF_OK; +} + +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + +void sidx_del(GF_Box *s) +{ + GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox *) s; + if (ptr == NULL) return; + if (ptr->tracks_times) gf_free(ptr->tracks_times); + if (ptr->refs) gf_free(ptr->refs); + gf_free(ptr); +} + +GF_Err sidx_Read(GF_Box *s,GF_BitStream *bs) +{ + GF_Err e; + u32 i; + GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s; + e = gf_isom_full_box_read(s, bs); + if (e) return e; + ptr->reference_track_ID = gf_bs_read_u32(bs); + ptr->nb_track_times = gf_bs_read_u16(bs); + ptr->nb_refs = gf_bs_read_u16(bs); + ptr->size -= 8; + ptr->tracks_times = gf_malloc(sizeof(GF_SIDXTrackTimes)*ptr->nb_track_times); + ptr->refs = gf_malloc(sizeof(GF_SIDXReference)*ptr->nb_refs); + for (i=0; i<ptr->nb_track_times; i++) { + ptr->tracks_times[i].track_ID = gf_bs_read_u32(bs); + ptr->size -= 8; + if (ptr->version==0) { + ptr->tracks_times[i].decoding_time = gf_bs_read_u32(bs); + } else { + ptr->tracks_times[i].decoding_time = gf_bs_read_u64(bs); + ptr->size -= 4; + } + } + + for (i=0; i<ptr->nb_refs; i++) { + ptr->refs[i].reference_type = gf_bs_read_int(bs, 1); + ptr->refs[i].reference_offset = gf_bs_read_int(bs, 31); + ptr->refs[i].subsegment_duration = gf_bs_read_u32(bs); + ptr->refs[i].contains_RAP = gf_bs_read_int(bs, 1); + ptr->refs[i].RAP_delta_time = gf_bs_read_int(bs, 31); + ptr->size -= 12; + } + return GF_OK; +} + +GF_Box *sidx_New() +{ + GF_SegmentIndexBox *tmp; + + GF_SAFEALLOC(tmp, GF_SegmentIndexBox); + if (tmp == NULL) return NULL; + gf_isom_full_box_init((GF_Box *)tmp); + tmp->type = GF_ISOM_BOX_TYPE_SIDX; + return (GF_Box *)tmp; +} + + +#ifndef GPAC_DISABLE_ISOM_WRITE + +GF_Err sidx_Write(GF_Box *s, GF_BitStream *bs) +{ + GF_Err e; + u32 i; + GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s; + + e = gf_isom_full_box_write(s, bs); + if (e) return e; + + gf_bs_write_u32(bs, ptr->reference_track_ID); + gf_bs_write_u16(bs, ptr->nb_track_times); + gf_bs_write_u16(bs, ptr->nb_refs); + + for (i=0; i<ptr->nb_track_times; i++ ) { + gf_bs_write_u32(bs, ptr->tracks_times[i].track_ID); + if (ptr->version==0) { + gf_bs_write_u32(bs, (u32) ptr->tracks_times[i].decoding_time); + } else { + gf_bs_write_u64(bs, ptr->tracks_times[i].decoding_time); + } + } + for (i=0; i<ptr->nb_refs; i++ ) { + gf_bs_write_int(bs, ptr->refs[i].reference_type, 1); + gf_bs_write_int(bs, ptr->refs[i].reference_offset, 31); + gf_bs_write_u32(bs, ptr->refs[i].subsegment_duration); + gf_bs_write_int(bs, ptr->refs[i].contains_RAP, 1); + gf_bs_write_int(bs, ptr->refs[i].RAP_delta_time, 31); + } + return GF_OK; +} + +GF_Err sidx_Size(GF_Box *s) +{ + GF_Err e; + GF_SegmentIndexBox *ptr = (GF_SegmentIndexBox*) s; + e = gf_isom_full_box_get_size(s); + if (e) return e; + + ptr->size += 8; + if (ptr->version==0) { + ptr->size += ptr->nb_track_times * 8; + } else { + ptr->size += ptr->nb_track_times * 12; + } + ptr->size += ptr->nb_refs * 12; + return GF_OK; +} + +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS*/ + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/box_code_isma.c b/src/isomedia/box_code_isma.c index 3f0498e..3b0ca62 100644 --- a/src/isomedia/box_code_isma.c +++ b/src/isomedia/box_code_isma.c @@ -24,10 +24,12 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + /* ProtectionInfo Box */ GF_Box *sinf_New() { - GF_ProtectionInfoBox *tmp = (GF_ProtectionInfoBox *) malloc(sizeof(GF_ProtectionInfoBox)); + 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; @@ -41,7 +43,7 @@ void sinf_del(GF_Box *s) 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); - free(ptr); + gf_free(ptr); } GF_Err sinf_AddBox(GF_Box *s, GF_Box *a) @@ -72,7 +74,7 @@ GF_Err sinf_Read(GF_Box *s, GF_BitStream *bs) return gf_isom_read_box_list(s, bs, sinf_AddBox); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err sinf_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -110,12 +112,12 @@ GF_Err sinf_Size(GF_Box *s) ptr->size += ptr->info->size; return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /* OriginalFormat Box */ GF_Box *frma_New() { - GF_OriginalFormatBox *tmp = (GF_OriginalFormatBox *) malloc(sizeof(GF_OriginalFormatBox)); + 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; @@ -126,7 +128,7 @@ void frma_del(GF_Box *s) { GF_OriginalFormatBox *ptr = (GF_OriginalFormatBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } GF_Err frma_Read(GF_Box *s, GF_BitStream *bs) @@ -136,7 +138,7 @@ GF_Err frma_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err frma_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -158,12 +160,12 @@ GF_Err frma_Size(GF_Box *s) ptr->size += 4; return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /* SchemeType Box */ GF_Box *schm_New() { - GF_SchemeTypeBox *tmp = (GF_SchemeTypeBox *) malloc(sizeof(GF_SchemeTypeBox)); + 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); @@ -175,8 +177,8 @@ void schm_del(GF_Box *s) { GF_SchemeTypeBox *ptr = (GF_SchemeTypeBox *)s; if (ptr == NULL) return; - if (ptr->URI) free(ptr->URI); - free(ptr); + if (ptr->URI) gf_free(ptr->URI); + gf_free(ptr); } GF_Err schm_Read(GF_Box *s, GF_BitStream *bs) @@ -190,14 +192,14 @@ GF_Err schm_Read(GF_Box *s, GF_BitStream *bs) ptr->size -= 8; if (ptr->size && (ptr->flags & 0x000001)) { u32 len = (u32) (ptr->size); - ptr->URI = (char*)malloc(sizeof(char)*len); + 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_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err schm_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -221,12 +223,12 @@ GF_Err schm_Size(GF_Box *s) if (ptr->flags & 0x000001) ptr->size += strlen(ptr->URI)+1; return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /* SchemeInformation Box */ GF_Box *schi_New() { - GF_SchemeInformationBox *tmp = (GF_SchemeInformationBox *) malloc(sizeof(GF_SchemeInformationBox)); + 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; @@ -239,7 +241,7 @@ void schi_del(GF_Box *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); - free(ptr); + gf_free(ptr); } GF_Err schi_AddBox(GF_Box *s, GF_Box *a) @@ -269,7 +271,7 @@ GF_Err schi_Read(GF_Box *s, GF_BitStream *bs) return gf_isom_read_box_list(s, bs, schi_AddBox); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err schi_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -319,12 +321,12 @@ GF_Err schi_Size(GF_Box *s) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /* ISMAKMS Box */ GF_Box *iKMS_New() { - GF_ISMAKMSBox *tmp = (GF_ISMAKMSBox *) malloc(sizeof(GF_ISMAKMSBox)); + 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); @@ -336,8 +338,8 @@ void iKMS_del(GF_Box *s) { GF_ISMAKMSBox *ptr = (GF_ISMAKMSBox *)s; if (ptr == NULL) return; - if (ptr->URI) free(ptr->URI); - free(ptr); + if (ptr->URI) gf_free(ptr->URI); + gf_free(ptr); } GF_Err iKMS_Read(GF_Box *s, GF_BitStream *bs) @@ -349,13 +351,13 @@ GF_Err iKMS_Read(GF_Box *s, GF_BitStream *bs) e = gf_isom_full_box_read(s, bs); if (e) return e; len = (u32) (ptr->size); - ptr->URI = (char*) malloc(sizeof(char)*len); + 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_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err iKMS_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -377,12 +379,12 @@ GF_Err iKMS_Size(GF_Box *s) ptr->size += strlen(ptr->URI)+1; return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /* ISMASampleFormat Box */ GF_Box *iSFM_New() { - GF_ISMASampleFormatBox *tmp = (GF_ISMASampleFormatBox *) malloc(sizeof(GF_ISMASampleFormatBox)); + 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); @@ -394,7 +396,7 @@ void iSFM_del(GF_Box *s) { GF_ISMASampleFormatBox *ptr = (GF_ISMASampleFormatBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } @@ -412,7 +414,7 @@ GF_Err iSFM_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err iSFM_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -437,7 +439,7 @@ GF_Err iSFM_Size(GF_Box *s) ptr->size += 3; return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -458,10 +460,10 @@ 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) free(ptr->ContentID); - if (ptr->RightsIssuerURL) free(ptr->RightsIssuerURL); - if (ptr->TextualHeaders) free(ptr->TextualHeaders); - free(ptr); + 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) @@ -488,19 +490,19 @@ GF_Err ohdr_Read(GF_Box *s, GF_BitStream *bs) if (ptr->size<cid_len+ri_len+ptr->TextualHeadersLen) return GF_ISOM_INVALID_FILE; if (cid_len) { - ptr->ContentID = (char *)malloc(sizeof(char)*(cid_len+1)); + 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 *)malloc(sizeof(char)*(ri_len+1)); + 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 *)malloc(sizeof(char)*(ptr->TextualHeadersLen+1)); + ptr->TextualHeaders = (char *)gf_malloc(sizeof(char)*(ptr->TextualHeadersLen+1)); gf_bs_read_data(bs, ptr->TextualHeaders, ptr->TextualHeadersLen); ptr->TextualHeaders[ptr->TextualHeadersLen] = 0; } @@ -510,7 +512,7 @@ GF_Err ohdr_Read(GF_Box *s, GF_BitStream *bs) return gf_isom_read_box_list(s, bs, ohdr_AddBox); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ohdr_Write(GF_Box *s, GF_BitStream *bs) { u16 cid_len, ri_len; @@ -549,7 +551,7 @@ GF_Err ohdr_Size(GF_Box *s) if (ptr->TextualHeadersLen) ptr->size += ptr->TextualHeadersLen; return gf_isom_box_array_size(s, ptr->ExtendedHeaders); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /* OMADRMGroupID Box */ @@ -567,9 +569,9 @@ void grpi_del(GF_Box *s) { GF_OMADRMGroupIDBox *ptr = (GF_OMADRMGroupIDBox *)s; if (ptr == NULL) return; - if (ptr->GroupID) free(ptr->GroupID); - if (ptr->GroupKey) free(ptr->GroupKey); - free(ptr); + 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) @@ -587,17 +589,17 @@ GF_Err grpi_Read(GF_Box *s, GF_BitStream *bs) ptr->size -= 1+2+2; if (ptr->size<gid_len+ptr->GKLength) return GF_ISOM_INVALID_FILE; - ptr->GroupID = malloc(sizeof(char)*(gid_len+1)); + 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 *)malloc(sizeof(char)*ptr->GKLength); + 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_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err grpi_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -626,7 +628,7 @@ GF_Err grpi_Size(GF_Box *s) if (ptr->GroupID) ptr->size += strlen(ptr->GroupID); return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -647,7 +649,7 @@ void mdri_del(GF_Box *s) GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s; if (ptr == NULL) return; gf_isom_box_array_del(ptr->boxes); - free(ptr); + gf_free(ptr); } GF_Err mdri_AddBox(GF_Box *s, GF_Box *a) @@ -661,7 +663,7 @@ GF_Err mdri_Read(GF_Box *s, GF_BitStream *bs) return gf_isom_read_box_list(s, bs, mdri_AddBox); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err mdri_Write(GF_Box *s, GF_BitStream *bs) { GF_OMADRMMutableInformationBox*ptr = (GF_OMADRMMutableInformationBox*)s; @@ -680,7 +682,7 @@ GF_Err mdri_Size(GF_Box *s) return gf_isom_box_array_size(s, ptr->boxes); } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ /* OMADRMTransactionTracking Box */ @@ -697,7 +699,7 @@ GF_Box *odtt_New() void odtt_del(GF_Box *s) { GF_OMADRMTransactionTrackingBox *ptr = (GF_OMADRMTransactionTrackingBox*)s; - free(ptr); + gf_free(ptr); } GF_Err odtt_Read(GF_Box *s, GF_BitStream *bs) @@ -712,7 +714,7 @@ GF_Err odtt_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err odtt_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -733,7 +735,7 @@ GF_Err odtt_Size(GF_Box *s) s->size += 16; return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -751,8 +753,8 @@ GF_Box *odrb_New() void odrb_del(GF_Box *s) { GF_OMADRMRightsObjectBox *ptr = (GF_OMADRMRightsObjectBox*)s; - if (ptr->oma_ro) free(ptr->oma_ro); - free(ptr); + if (ptr->oma_ro) gf_free(ptr->oma_ro); + gf_free(ptr); } GF_Err odrb_Read(GF_Box *s, GF_BitStream *bs) @@ -763,13 +765,13 @@ GF_Err odrb_Read(GF_Box *s, GF_BitStream *bs) e = gf_isom_full_box_read(s, bs); if (e) return e; ptr->oma_ro_size = (u32) ptr->size; - ptr->oma_ro = (char*) malloc(sizeof(char)*ptr->oma_ro_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_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err odrb_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -791,7 +793,7 @@ GF_Err odrb_Size(GF_Box *s) s->size += ptr->oma_ro_size; return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -812,7 +814,7 @@ 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); - free(ptr); + gf_free(ptr); } GF_Err odkm_Add(GF_Box *s, GF_Box *a) @@ -842,7 +844,7 @@ GF_Err odkm_Read(GF_Box *s, GF_BitStream *bs) return gf_isom_read_box_list(s, bs, odkm_Add); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err odkm_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -880,6 +882,7 @@ GF_Err odkm_Size(GF_Box *s) } return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/box_code_meta.c b/src/isomedia/box_code_meta.c index 3b7f701..824e9dc 100644 --- a/src/isomedia/box_code_meta.c +++ b/src/isomedia/box_code_meta.c @@ -24,9 +24,11 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + GF_Box *meta_New() { - GF_MetaBox *tmp = (GF_MetaBox *) malloc(sizeof(GF_MetaBox)); + GF_MetaBox *tmp = (GF_MetaBox *) gf_malloc(sizeof(GF_MetaBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_MetaBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -53,7 +55,7 @@ void meta_del(GF_Box *s) gf_isom_box_del(a); } gf_list_del(ptr->other_boxes); - free(ptr); + gf_free(ptr); } GF_Err meta_AddBox(GF_Box *s, GF_Box *a) @@ -108,7 +110,7 @@ GF_Err meta_Read(GF_Box *s, GF_BitStream *bs) return gf_isom_read_box_list(s, bs, meta_AddBox); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err meta_Write(GF_Box *s, GF_BitStream *bs) { u32 count, i; @@ -204,11 +206,11 @@ GF_Err meta_Size(GF_Box *s) } return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *xml_New() { - GF_XMLBox *tmp = (GF_XMLBox *) malloc(sizeof(GF_XMLBox)); + GF_XMLBox *tmp = (GF_XMLBox *) gf_malloc(sizeof(GF_XMLBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_XMLBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -220,8 +222,8 @@ void xml_del(GF_Box *s) { GF_XMLBox *ptr = (GF_XMLBox *)s; if (ptr == NULL) return; - if (ptr->xml_length && ptr->xml) free(ptr->xml); - free(ptr); + if (ptr->xml_length && ptr->xml) gf_free(ptr->xml); + gf_free(ptr); } GF_Err xml_Read(GF_Box *s, GF_BitStream *bs) @@ -232,13 +234,13 @@ GF_Err xml_Read(GF_Box *s, GF_BitStream *bs) e = gf_isom_full_box_read(s, bs); if (e) return e; ptr->xml_length = (u32)(ptr->size); - ptr->xml = (char *)malloc(sizeof(char)*ptr->xml_length); + ptr->xml = (char *)gf_malloc(sizeof(char)*ptr->xml_length); if (!ptr->xml) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ptr->xml, ptr->xml_length); return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err xml_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -260,11 +262,11 @@ GF_Err xml_Size(GF_Box *s) ptr->size += ptr->xml_length; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *bxml_New() { - GF_BinaryXMLBox *tmp = (GF_BinaryXMLBox *) malloc(sizeof(GF_BinaryXMLBox)); + GF_BinaryXMLBox *tmp = (GF_BinaryXMLBox *) gf_malloc(sizeof(GF_BinaryXMLBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_BinaryXMLBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -276,8 +278,8 @@ void bxml_del(GF_Box *s) { GF_BinaryXMLBox *ptr = (GF_BinaryXMLBox *)s; if (ptr == NULL) return; - if (ptr->data_length && ptr->data) free(ptr->data); - free(ptr); + if (ptr->data_length && ptr->data) gf_free(ptr->data); + gf_free(ptr); } GF_Err bxml_Read(GF_Box *s, GF_BitStream *bs) @@ -287,13 +289,13 @@ GF_Err bxml_Read(GF_Box *s, GF_BitStream *bs) e = gf_isom_full_box_read(s, bs); if (e) return e; ptr->data_length = (u32)(ptr->size); - ptr->data = (char*)malloc(sizeof(char)*ptr->data_length); + ptr->data = (char*)gf_malloc(sizeof(char)*ptr->data_length); if (!ptr->data) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ptr->data, ptr->data_length); return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err bxml_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -315,11 +317,11 @@ GF_Err bxml_Size(GF_Box *s) ptr->size += ptr->data_length; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *iloc_New() { - GF_ItemLocationBox *tmp = (GF_ItemLocationBox *) malloc(sizeof(GF_ItemLocationBox)); + GF_ItemLocationBox *tmp = (GF_ItemLocationBox *) gf_malloc(sizeof(GF_ItemLocationBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ItemLocationBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -340,14 +342,14 @@ void iloc_del(GF_Box *s) extent_count = gf_list_count(location->extent_entries); for (j = 0; j < extent_count; j++) { GF_ItemExtentEntry *extent = (GF_ItemExtentEntry *)gf_list_get(location->extent_entries, j); - free(extent); + gf_free(extent); } gf_list_del(location->extent_entries); - free(location); + gf_free(location); } gf_list_del(ptr->location_entries); } - free(ptr); + gf_free(ptr); } GF_Err iloc_Read(GF_Box *s, GF_BitStream *bs) @@ -363,23 +365,23 @@ GF_Err iloc_Read(GF_Box *s, GF_BitStream *bs) gf_bs_read_int(bs, 4); item_count = gf_bs_read_u16(bs); for (i = 0; i < item_count; i++) { - GF_ItemLocationEntry *location_entry = (GF_ItemLocationEntry *)malloc(sizeof(GF_ItemLocationEntry)); + GF_ItemLocationEntry *location_entry = (GF_ItemLocationEntry *)gf_malloc(sizeof(GF_ItemLocationEntry)); gf_list_add(ptr->location_entries, location_entry); location_entry->item_ID = gf_bs_read_u16(bs); location_entry->data_reference_index = gf_bs_read_u16(bs); location_entry->base_offset = gf_bs_read_int(bs, 8*ptr->base_offset_size); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE location_entry->original_base_offset = location_entry->base_offset; #endif extent_count = gf_bs_read_u16(bs); location_entry->extent_entries = gf_list_new(); for (j = 0; j < extent_count; j++) { - GF_ItemExtentEntry *extent_entry = (GF_ItemExtentEntry *)malloc(sizeof(GF_ItemExtentEntry)); + GF_ItemExtentEntry *extent_entry = (GF_ItemExtentEntry *)gf_malloc(sizeof(GF_ItemExtentEntry)); gf_list_add(location_entry->extent_entries, extent_entry); extent_entry->extent_offset = gf_bs_read_int(bs, 8*ptr->offset_size); extent_entry->extent_length = gf_bs_read_int(bs, 8*ptr->length_size); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE extent_entry->original_extent_offset = extent_entry->extent_offset; #endif } @@ -387,7 +389,7 @@ GF_Err iloc_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err iloc_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -435,11 +437,11 @@ GF_Err iloc_Size(GF_Box *s) } return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *pitm_New() { - GF_PrimaryItemBox *tmp = (GF_PrimaryItemBox *) malloc(sizeof(GF_PrimaryItemBox)); + GF_PrimaryItemBox *tmp = (GF_PrimaryItemBox *) gf_malloc(sizeof(GF_PrimaryItemBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_PrimaryItemBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -451,7 +453,7 @@ void pitm_del(GF_Box *s) { GF_PrimaryItemBox *ptr = (GF_PrimaryItemBox *)s; if (ptr == NULL) return; - free(ptr); + gf_free(ptr); } GF_Err pitm_Read(GF_Box *s, GF_BitStream *bs) @@ -464,7 +466,7 @@ GF_Err pitm_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err pitm_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -486,11 +488,11 @@ GF_Err pitm_Size(GF_Box *s) ptr->size += 16; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *ipro_New() { - GF_ItemProtectionBox *tmp = (GF_ItemProtectionBox *) malloc(sizeof(GF_ItemProtectionBox)); + GF_ItemProtectionBox *tmp = (GF_ItemProtectionBox *) gf_malloc(sizeof(GF_ItemProtectionBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ItemProtectionBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -510,7 +512,7 @@ void ipro_del(GF_Box *s) gf_isom_box_del(a); } gf_list_del(ptr->protection_information); - free(ptr); + gf_free(ptr); } GF_Err ipro_AddBox(GF_Box *s, GF_Box *a) @@ -530,7 +532,7 @@ GF_Err ipro_Read(GF_Box *s, GF_BitStream *bs) return gf_isom_read_box_list(s, bs, ipro_AddBox); } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ipro_Write(GF_Box *s, GF_BitStream *bs) { u32 count, i; @@ -570,11 +572,11 @@ GF_Err ipro_Size(GF_Box *s) } return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *infe_New() { - GF_ItemInfoEntryBox *tmp = (GF_ItemInfoEntryBox *) malloc(sizeof(GF_ItemInfoEntryBox)); + GF_ItemInfoEntryBox *tmp = (GF_ItemInfoEntryBox *) gf_malloc(sizeof(GF_ItemInfoEntryBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ItemInfoEntryBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -586,11 +588,11 @@ void infe_del(GF_Box *s) { GF_ItemInfoEntryBox *ptr = (GF_ItemInfoEntryBox *)s; if (ptr == NULL) return; - if (ptr->item_name) free(ptr->item_name); - if (ptr->full_path) free(ptr->full_path); - if (ptr->content_type) free(ptr->content_type); - if (ptr->content_encoding) free(ptr->content_encoding); - free(ptr); + if (ptr->item_name) gf_free(ptr->item_name); + if (ptr->full_path) gf_free(ptr->full_path); + if (ptr->content_type) gf_free(ptr->content_type); + if (ptr->content_encoding) gf_free(ptr->content_encoding); + gf_free(ptr); } GF_Err infe_Read(GF_Box *s, GF_BitStream *bs) @@ -607,9 +609,9 @@ GF_Err infe_Read(GF_Box *s, GF_BitStream *bs) ptr->item_protection_index = gf_bs_read_u16(bs); ptr->size -= 4; buf_len = (u32) (ptr->size); - buf = (char*)malloc(buf_len); + buf = (char*)gf_malloc(buf_len); if (buf_len != gf_bs_read_data(bs, buf, buf_len)) { - free(buf); + gf_free(buf); return GF_ISOM_INVALID_FILE; } string_len = 1; @@ -617,13 +619,13 @@ GF_Err infe_Read(GF_Box *s, GF_BitStream *bs) for (i = 0; i < buf_len; i++) { if (buf[i] == 0) { if (!ptr->item_name) { - ptr->item_name = (char*)malloc(sizeof(char)*string_len); + ptr->item_name = (char*)gf_malloc(sizeof(char)*string_len); memcpy(ptr->item_name, buf+string_start, string_len); } else if (!ptr->content_type) { - ptr->content_type = (char*)malloc(sizeof(char)*string_len); + ptr->content_type = (char*)gf_malloc(sizeof(char)*string_len); memcpy(ptr->content_type, buf+string_start, string_len); } else { - ptr->content_encoding = (char*)malloc(sizeof(char)*string_len); + ptr->content_encoding = (char*)gf_malloc(sizeof(char)*string_len); memcpy(ptr->content_encoding, buf+string_start, string_len); } string_start += string_len; @@ -631,12 +633,12 @@ GF_Err infe_Read(GF_Box *s, GF_BitStream *bs) } string_len++; } - free(buf); + gf_free(buf); if (!ptr->item_name || !ptr->content_type) return GF_ISOM_INVALID_FILE; return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err infe_Write(GF_Box *s, GF_BitStream *bs) { GF_Err e; @@ -675,11 +677,11 @@ GF_Err infe_Size(GF_Box *s) if (ptr->content_encoding) ptr->size += strlen(ptr->content_encoding)+1; return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *iinf_New() { - GF_ItemInfoBox *tmp = (GF_ItemInfoBox *) malloc(sizeof(GF_ItemInfoBox)); + GF_ItemInfoBox *tmp = (GF_ItemInfoBox *) gf_malloc(sizeof(GF_ItemInfoBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_ItemInfoBox)); gf_isom_full_box_init((GF_Box *)tmp); @@ -699,7 +701,7 @@ void iinf_del(GF_Box *s) gf_isom_box_del(a); } gf_list_del(ptr->item_infos); - free(ptr); + gf_free(ptr); } GF_Err iinf_Read(GF_Box *s, GF_BitStream *bs) @@ -727,7 +729,7 @@ GF_Err iinf_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err iinf_Write(GF_Box *s, GF_BitStream *bs) { u32 count, i; @@ -767,7 +769,8 @@ GF_Err iinf_Size(GF_Box *s) } return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/box_dump.c b/src/isomedia/box_dump.c index 6de107e..8402e1b 100644 --- a/src/isomedia/box_dump.c +++ b/src/isomedia/box_dump.c @@ -1,7 +1,7 @@ /* * GPAC - Multimedia Framework C SDK * - * Copyright (c) Jean Le Feuvre 2000-2005 + * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / ISO Media File Format sub-project @@ -10,21 +10,23 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <gpac/internal/isomedia_dev.h> #include <gpac/utf.h> +#ifndef GPAC_DISABLE_ISOM_DUMP + static GF_Err apple_tag_dump(GF_Box *a, FILE * trace); void NullBoxErr(FILE * trace) @@ -84,154 +86,272 @@ GF_Err gf_box_dump(void *ptr, FILE * trace) case GF_ISOM_BOX_TYPE_FREE: case GF_ISOM_BOX_TYPE_SKIP: return free_dump(a, trace); - case GF_ISOM_BOX_TYPE_MDAT: return mdat_dump(a, trace); - case GF_ISOM_BOX_TYPE_MOOV: return moov_dump(a, trace); - case GF_ISOM_BOX_TYPE_MVHD: return mvhd_dump(a, trace); - case GF_ISOM_BOX_TYPE_MDHD: return mdhd_dump(a, trace); - case GF_ISOM_BOX_TYPE_VMHD: return vmhd_dump(a, trace); - case GF_ISOM_BOX_TYPE_SMHD: return smhd_dump(a, trace); - case GF_ISOM_BOX_TYPE_HMHD: return hmhd_dump(a, trace); + case GF_ISOM_BOX_TYPE_MDAT: + return mdat_dump(a, trace); + case GF_ISOM_BOX_TYPE_MOOV: + return moov_dump(a, trace); + case GF_ISOM_BOX_TYPE_MVHD: + return mvhd_dump(a, trace); + case GF_ISOM_BOX_TYPE_MDHD: + return mdhd_dump(a, trace); + case GF_ISOM_BOX_TYPE_VMHD: + return vmhd_dump(a, trace); + case GF_ISOM_BOX_TYPE_SMHD: + return smhd_dump(a, trace); + case GF_ISOM_BOX_TYPE_HMHD: + return hmhd_dump(a, trace); //the same box is used for all MPEG4 systems streams case GF_ISOM_BOX_TYPE_ODHD: case GF_ISOM_BOX_TYPE_CRHD: case GF_ISOM_BOX_TYPE_SDHD: case GF_ISOM_BOX_TYPE_NMHD: return nmhd_dump(a, trace); - case GF_ISOM_BOX_TYPE_STBL: return stbl_dump(a, trace); - case GF_ISOM_BOX_TYPE_DINF: return dinf_dump(a, trace); - case GF_ISOM_BOX_TYPE_URL: return url_dump(a, trace); - case GF_ISOM_BOX_TYPE_URN: return urn_dump(a, trace); - case GF_ISOM_BOX_TYPE_CPRT: return cprt_dump(a, trace); - case GF_ISOM_BOX_TYPE_HDLR: return hdlr_dump(a, trace); - case GF_ISOM_BOX_TYPE_IODS: return iods_dump(a, trace); - case GF_ISOM_BOX_TYPE_TRAK: return trak_dump(a, trace); - case GF_ISOM_BOX_TYPE_MP4S: return mp4s_dump(a, trace); - case GF_ISOM_BOX_TYPE_MP4V: return mp4v_dump(a, trace); - case GF_ISOM_BOX_TYPE_MP4A: return mp4a_dump(a, trace); - case GF_ISOM_BOX_TYPE_GNRM: return gnrm_dump(a, trace); - case GF_ISOM_BOX_TYPE_GNRV: return gnrv_dump(a, trace); - case GF_ISOM_BOX_TYPE_GNRA: return gnra_dump(a, trace); - case GF_ISOM_BOX_TYPE_EDTS: return edts_dump(a, trace); - case GF_ISOM_BOX_TYPE_UDTA: return udta_dump(a, trace); - case GF_ISOM_BOX_TYPE_DREF: return dref_dump(a, trace); - case GF_ISOM_BOX_TYPE_STSD: return stsd_dump(a, trace); - case GF_ISOM_BOX_TYPE_STTS: return stts_dump(a, trace); - case GF_ISOM_BOX_TYPE_CTTS: return ctts_dump(a, trace); - case GF_ISOM_BOX_TYPE_STSH: return stsh_dump(a, trace); - case GF_ISOM_BOX_TYPE_ELST: return elst_dump(a, trace); - case GF_ISOM_BOX_TYPE_STSC: return stsc_dump(a, trace); + case GF_ISOM_BOX_TYPE_STBL: + return stbl_dump(a, trace); + case GF_ISOM_BOX_TYPE_DINF: + return dinf_dump(a, trace); + case GF_ISOM_BOX_TYPE_URL: + return url_dump(a, trace); + case GF_ISOM_BOX_TYPE_URN: + return urn_dump(a, trace); + case GF_ISOM_BOX_TYPE_CPRT: + return cprt_dump(a, trace); + case GF_ISOM_BOX_TYPE_HDLR: + return hdlr_dump(a, trace); + case GF_ISOM_BOX_TYPE_IODS: + return iods_dump(a, trace); + case GF_ISOM_BOX_TYPE_TRAK: + return trak_dump(a, trace); + case GF_ISOM_BOX_TYPE_MP4S: + return mp4s_dump(a, trace); + case GF_ISOM_BOX_TYPE_MP4V: + return mp4v_dump(a, trace); + case GF_ISOM_BOX_TYPE_MP4A: + return mp4a_dump(a, trace); + case GF_ISOM_BOX_TYPE_GNRM: + return gnrm_dump(a, trace); + case GF_ISOM_BOX_TYPE_GNRV: + return gnrv_dump(a, trace); + case GF_ISOM_BOX_TYPE_GNRA: + return gnra_dump(a, trace); + case GF_ISOM_BOX_TYPE_EDTS: + return edts_dump(a, trace); + case GF_ISOM_BOX_TYPE_UDTA: + return udta_dump(a, trace); + case GF_ISOM_BOX_TYPE_DREF: + return dref_dump(a, trace); + case GF_ISOM_BOX_TYPE_STSD: + return stsd_dump(a, trace); + case GF_ISOM_BOX_TYPE_STTS: + return stts_dump(a, trace); + case GF_ISOM_BOX_TYPE_CTTS: + return ctts_dump(a, trace); + case GF_ISOM_BOX_TYPE_STSH: + return stsh_dump(a, trace); + case GF_ISOM_BOX_TYPE_ELST: + return elst_dump(a, trace); + case GF_ISOM_BOX_TYPE_STSC: + return stsc_dump(a, trace); case GF_ISOM_BOX_TYPE_STZ2: case GF_ISOM_BOX_TYPE_STSZ: return stsz_dump(a, trace); - case GF_ISOM_BOX_TYPE_STCO: return stco_dump(a, trace); - case GF_ISOM_BOX_TYPE_STSS: return stss_dump(a, trace); - case GF_ISOM_BOX_TYPE_STDP: return stdp_dump(a, trace); - case GF_ISOM_BOX_TYPE_SDTP: return sdtp_dump(a, trace); - case GF_ISOM_BOX_TYPE_CO64: return co64_dump(a, trace); - case GF_ISOM_BOX_TYPE_ESDS: return esds_dump(a, trace); - case GF_ISOM_BOX_TYPE_MINF: return minf_dump(a, trace); - case GF_ISOM_BOX_TYPE_TKHD: return tkhd_dump(a, trace); - case GF_ISOM_BOX_TYPE_TREF: return tref_dump(a, trace); - case GF_ISOM_BOX_TYPE_MDIA: return mdia_dump(a, trace); - case GF_ISOM_BOX_TYPE_CHPL: return chpl_dump(a, trace); - case GF_ISOM_BOX_TYPE_PDIN: return dpin_dump(a, trace); - - case GF_ISOM_BOX_TYPE_RTP_STSD: return ghnt_dump(a, trace); - case GF_ISOM_BOX_TYPE_RTPO: return rtpo_dump(a, trace); - case GF_ISOM_BOX_TYPE_HNTI: return hnti_dump(a, trace); - case GF_ISOM_BOX_TYPE_SDP: return sdp_dump(a, trace); - case GF_ISOM_BOX_TYPE_HINF: return hinf_dump(a, trace); - case GF_ISOM_BOX_TYPE_RELY: return rely_dump(a, trace); - case GF_ISOM_BOX_TYPE_TIMS: return tims_dump(a, trace); - case GF_ISOM_BOX_TYPE_TSRO: return tsro_dump(a, trace); - case GF_ISOM_BOX_TYPE_SNRO: return snro_dump(a, trace); - case GF_ISOM_BOX_TYPE_TRPY: return trpy_dump(a, trace); - case GF_ISOM_BOX_TYPE_NUMP: return nump_dump(a, trace); - case GF_ISOM_BOX_TYPE_TOTL: return totl_dump(a, trace); - case GF_ISOM_BOX_TYPE_NPCK: return npck_dump(a, trace); - case GF_ISOM_BOX_TYPE_TPYL: return tpyl_dump(a, trace); - case GF_ISOM_BOX_TYPE_TPAY: return tpay_dump(a, trace); - case GF_ISOM_BOX_TYPE_MAXR: return maxr_dump(a, trace); - case GF_ISOM_BOX_TYPE_DMED: return dmed_dump(a, trace); - case GF_ISOM_BOX_TYPE_DIMM: return dimm_dump(a, trace); - case GF_ISOM_BOX_TYPE_DREP: return drep_dump(a, trace); - case GF_ISOM_BOX_TYPE_TMIN: return tmin_dump(a, trace); - case GF_ISOM_BOX_TYPE_TMAX: return tmax_dump(a, trace); - case GF_ISOM_BOX_TYPE_PMAX: return pmax_dump(a, trace); - case GF_ISOM_BOX_TYPE_DMAX: return dmax_dump(a, trace); - case GF_ISOM_BOX_TYPE_PAYT: return payt_dump(a, trace); - case GF_ISOM_BOX_TYPE_NAME: return name_dump(a, trace); - - case GF_ISOM_BOX_TYPE_FTYP: return ftyp_dump(a, trace); - case GF_ISOM_BOX_TYPE_FADB: return padb_dump(a, trace); - -#ifndef GPAC_ISOM_NO_FRAGMENTS - case GF_ISOM_BOX_TYPE_MVEX: return mvex_dump(a, trace); - case GF_ISOM_BOX_TYPE_MEHD: return mehd_dump(a, trace); - case GF_ISOM_BOX_TYPE_TREX: return trex_dump(a, trace); - case GF_ISOM_BOX_TYPE_MOOF: return moof_dump(a, trace); - case GF_ISOM_BOX_TYPE_MFHD: return mfhd_dump(a, trace); - case GF_ISOM_BOX_TYPE_TRAF: return traf_dump(a, trace); - case GF_ISOM_BOX_TYPE_TFHD: return tfhd_dump(a, trace); - case GF_ISOM_BOX_TYPE_TRUN: return trun_dump(a, trace); + case GF_ISOM_BOX_TYPE_STCO: + return stco_dump(a, trace); + case GF_ISOM_BOX_TYPE_STSS: + return stss_dump(a, trace); + case GF_ISOM_BOX_TYPE_STDP: + return stdp_dump(a, trace); + case GF_ISOM_BOX_TYPE_SDTP: + return sdtp_dump(a, trace); + case GF_ISOM_BOX_TYPE_CO64: + return co64_dump(a, trace); + case GF_ISOM_BOX_TYPE_ESDS: + return esds_dump(a, trace); + case GF_ISOM_BOX_TYPE_MINF: + return minf_dump(a, trace); + case GF_ISOM_BOX_TYPE_TKHD: + return tkhd_dump(a, trace); + case GF_ISOM_BOX_TYPE_TREF: + return tref_dump(a, trace); + case GF_ISOM_BOX_TYPE_MDIA: + return mdia_dump(a, trace); + case GF_ISOM_BOX_TYPE_CHPL: + return chpl_dump(a, trace); + case GF_ISOM_BOX_TYPE_PDIN: + return dpin_dump(a, trace); + + case GF_ISOM_BOX_TYPE_RTP_STSD: + return ghnt_dump(a, trace); + case GF_ISOM_BOX_TYPE_RTPO: + return rtpo_dump(a, trace); + case GF_ISOM_BOX_TYPE_HNTI: + return hnti_dump(a, trace); + case GF_ISOM_BOX_TYPE_SDP: + return sdp_dump(a, trace); + case GF_ISOM_BOX_TYPE_HINF: + return hinf_dump(a, trace); + case GF_ISOM_BOX_TYPE_RELY: + return rely_dump(a, trace); + case GF_ISOM_BOX_TYPE_TIMS: + return tims_dump(a, trace); + case GF_ISOM_BOX_TYPE_TSRO: + return tsro_dump(a, trace); + case GF_ISOM_BOX_TYPE_SNRO: + return snro_dump(a, trace); + case GF_ISOM_BOX_TYPE_TRPY: + return trpy_dump(a, trace); + case GF_ISOM_BOX_TYPE_NUMP: + return nump_dump(a, trace); + case GF_ISOM_BOX_TYPE_TOTL: + return totl_dump(a, trace); + case GF_ISOM_BOX_TYPE_NPCK: + return npck_dump(a, trace); + case GF_ISOM_BOX_TYPE_TPYL: + return tpyl_dump(a, trace); + case GF_ISOM_BOX_TYPE_TPAY: + return tpay_dump(a, trace); + case GF_ISOM_BOX_TYPE_MAXR: + return maxr_dump(a, trace); + case GF_ISOM_BOX_TYPE_DMED: + return dmed_dump(a, trace); + case GF_ISOM_BOX_TYPE_DIMM: + return dimm_dump(a, trace); + case GF_ISOM_BOX_TYPE_DREP: + return drep_dump(a, trace); + case GF_ISOM_BOX_TYPE_TMIN: + return tmin_dump(a, trace); + case GF_ISOM_BOX_TYPE_TMAX: + return tmax_dump(a, trace); + case GF_ISOM_BOX_TYPE_PMAX: + return pmax_dump(a, trace); + case GF_ISOM_BOX_TYPE_DMAX: + return dmax_dump(a, trace); + case GF_ISOM_BOX_TYPE_PAYT: + return payt_dump(a, trace); + case GF_ISOM_BOX_TYPE_NAME: + return name_dump(a, trace); + + case GF_ISOM_BOX_TYPE_FTYP: + case GF_ISOM_BOX_TYPE_STYP: + return ftyp_dump(a, trace); + case GF_ISOM_BOX_TYPE_FADB: + return padb_dump(a, trace); + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + case GF_ISOM_BOX_TYPE_MVEX: + return mvex_dump(a, trace); + case GF_ISOM_BOX_TYPE_MEHD: + return mehd_dump(a, trace); + case GF_ISOM_BOX_TYPE_TREX: + return trex_dump(a, trace); + case GF_ISOM_BOX_TYPE_MOOF: + return moof_dump(a, trace); + case GF_ISOM_BOX_TYPE_MFHD: + return mfhd_dump(a, trace); + case GF_ISOM_BOX_TYPE_TRAF: + return traf_dump(a, trace); + case GF_ISOM_BOX_TYPE_TFHD: + return tfhd_dump(a, trace); + case GF_ISOM_BOX_TYPE_TRUN: + return trun_dump(a, trace); #endif - - case GF_ISOM_BOX_TYPE_VOID: return void_dump(a, trace); - case GF_ISOM_BOX_TYPE_STSF: return stsf_dump(a, trace); - - case GF_ISOM_SUBTYPE_3GP_AMR: - case GF_ISOM_SUBTYPE_3GP_AMR_WB: - case GF_ISOM_SUBTYPE_3GP_QCELP: - case GF_ISOM_SUBTYPE_3GP_EVRC: - case GF_ISOM_SUBTYPE_3GP_SMV: + + case GF_ISOM_BOX_TYPE_VOID: + return void_dump(a, trace); + case GF_ISOM_BOX_TYPE_STSF: + return stsf_dump(a, trace); + + case GF_ISOM_SUBTYPE_3GP_AMR: + case GF_ISOM_SUBTYPE_3GP_AMR_WB: + case GF_ISOM_SUBTYPE_3GP_QCELP: + case GF_ISOM_SUBTYPE_3GP_EVRC: + case GF_ISOM_SUBTYPE_3GP_SMV: return gppa_dump(a, trace); - case GF_ISOM_SUBTYPE_3GP_H263: + case GF_ISOM_SUBTYPE_3GP_H263: return gppv_dump(a, trace); - case GF_ISOM_BOX_TYPE_DAMR: - case GF_ISOM_BOX_TYPE_DEVC: + 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_D263: + case GF_ISOM_BOX_TYPE_D263: return gppc_dump(a, trace); - case GF_ISOM_BOX_TYPE_AVCC: return avcc_dump(a, trace); - case GF_ISOM_BOX_TYPE_BTRT: return btrt_dump(a, trace); - case GF_ISOM_BOX_TYPE_M4DS: return m4ds_dump(a, trace); - case GF_ISOM_BOX_TYPE_AVC1: return mp4v_dump(a, trace); - case GF_ISOM_BOX_TYPE_PASP: return pasp_dump(a, trace); - - case GF_ISOM_BOX_TYPE_FTAB: return ftab_dump(a, trace); - case GF_ISOM_BOX_TYPE_TX3G: return tx3g_dump(a, trace); - case GF_ISOM_BOX_TYPE_STYL: return styl_dump(a, trace); - case GF_ISOM_BOX_TYPE_HLIT: return hlit_dump(a, trace); - case GF_ISOM_BOX_TYPE_HCLR: return hclr_dump(a, trace); - case GF_ISOM_BOX_TYPE_KROK: return krok_dump(a, trace); - case GF_ISOM_BOX_TYPE_DLAY: return dlay_dump(a, trace); - case GF_ISOM_BOX_TYPE_HREF: return href_dump(a, trace); - case GF_ISOM_BOX_TYPE_TBOX: return tbox_dump(a, trace); - case GF_ISOM_BOX_TYPE_BLNK: return blnk_dump(a, trace); - case GF_ISOM_BOX_TYPE_TWRP: return twrp_dump(a, trace); + case GF_ISOM_BOX_TYPE_AVCC: + case GF_ISOM_BOX_TYPE_SVCC: + return avcc_dump(a, trace); + case GF_ISOM_BOX_TYPE_BTRT: + return btrt_dump(a, trace); + case GF_ISOM_BOX_TYPE_M4DS: + return m4ds_dump(a, trace); + case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: + return mp4v_dump(a, trace); + case GF_ISOM_BOX_TYPE_PASP: + return pasp_dump(a, trace); + + case GF_ISOM_BOX_TYPE_FTAB: + return ftab_dump(a, trace); + case GF_ISOM_BOX_TYPE_TX3G: + return tx3g_dump(a, trace); + case GF_ISOM_BOX_TYPE_TEXT: + return text_dump(a, trace); + case GF_ISOM_BOX_TYPE_STYL: + return styl_dump(a, trace); + case GF_ISOM_BOX_TYPE_HLIT: + return hlit_dump(a, trace); + case GF_ISOM_BOX_TYPE_HCLR: + return hclr_dump(a, trace); + case GF_ISOM_BOX_TYPE_KROK: + return krok_dump(a, trace); + case GF_ISOM_BOX_TYPE_DLAY: + return dlay_dump(a, trace); + case GF_ISOM_BOX_TYPE_HREF: + return href_dump(a, trace); + case GF_ISOM_BOX_TYPE_TBOX: + return tbox_dump(a, trace); + case GF_ISOM_BOX_TYPE_BLNK: + return blnk_dump(a, trace); + case GF_ISOM_BOX_TYPE_TWRP: + return twrp_dump(a, trace); /* ISMA 1.0 Encryption and Authentication V 1.0 */ - case GF_ISOM_BOX_TYPE_IKMS: return iKMS_dump(a, trace); - case GF_ISOM_BOX_TYPE_ISFM: return iSFM_dump(a, trace); + case GF_ISOM_BOX_TYPE_IKMS: + return iKMS_dump(a, trace); + case GF_ISOM_BOX_TYPE_ISFM: + return iSFM_dump(a, trace); /*MPEG-21 extensions*/ - case GF_ISOM_BOX_TYPE_META: return meta_dump(a, trace); - case GF_ISOM_BOX_TYPE_XML: return xml_dump(a, trace); - case GF_ISOM_BOX_TYPE_BXML: return bxml_dump(a, trace); - case GF_ISOM_BOX_TYPE_ILOC: return iloc_dump(a, trace); - case GF_ISOM_BOX_TYPE_PITM: return pitm_dump(a, trace); - case GF_ISOM_BOX_TYPE_IPRO: return ipro_dump(a, trace); - case GF_ISOM_BOX_TYPE_INFE: return infe_dump(a, trace); - case GF_ISOM_BOX_TYPE_IINF: return iinf_dump(a, trace); - case GF_ISOM_BOX_TYPE_SINF: return sinf_dump(a, trace); - case GF_ISOM_BOX_TYPE_FRMA: return frma_dump(a, trace); - case GF_ISOM_BOX_TYPE_SCHM: return schm_dump(a, trace); - case GF_ISOM_BOX_TYPE_SCHI: return schi_dump(a, trace); - case GF_ISOM_BOX_TYPE_ENCA: return mp4a_dump(a, trace); - case GF_ISOM_BOX_TYPE_ENCV: return mp4v_dump(a, trace); - case GF_ISOM_BOX_TYPE_ENCS: return mp4s_dump(a, trace); + case GF_ISOM_BOX_TYPE_META: + return meta_dump(a, trace); + case GF_ISOM_BOX_TYPE_XML: + return xml_dump(a, trace); + case GF_ISOM_BOX_TYPE_BXML: + return bxml_dump(a, trace); + case GF_ISOM_BOX_TYPE_ILOC: + return iloc_dump(a, trace); + case GF_ISOM_BOX_TYPE_PITM: + return pitm_dump(a, trace); + case GF_ISOM_BOX_TYPE_IPRO: + return ipro_dump(a, trace); + case GF_ISOM_BOX_TYPE_INFE: + return infe_dump(a, trace); + case GF_ISOM_BOX_TYPE_IINF: + return iinf_dump(a, trace); + case GF_ISOM_BOX_TYPE_SINF: + return sinf_dump(a, trace); + case GF_ISOM_BOX_TYPE_FRMA: + return frma_dump(a, trace); + case GF_ISOM_BOX_TYPE_SCHM: + return schm_dump(a, trace); + case GF_ISOM_BOX_TYPE_SCHI: + return schi_dump(a, trace); + case GF_ISOM_BOX_TYPE_ENCA: + return mp4a_dump(a, trace); + case GF_ISOM_BOX_TYPE_ENCV: + return mp4v_dump(a, trace); + case GF_ISOM_BOX_TYPE_ENCS: + return mp4s_dump(a, trace); case GF_ISOM_BOX_TYPE_0xA9NAM: @@ -256,26 +376,49 @@ GF_Err gf_box_dump(void *ptr, FILE * trace) case GF_ISOM_BOX_TYPE_iTunesSpecificInfo: return apple_tag_dump(a, trace); /*Apple extensions*/ - case GF_ISOM_BOX_TYPE_ILST: return ilst_dump(a, trace); - - case GF_ISOM_BOX_TYPE_OHDR: return ohdr_dump(a, trace); - case GF_ISOM_BOX_TYPE_GRPI: return grpi_dump(a, trace); - case GF_ISOM_BOX_TYPE_MDRI: return mdri_dump(a, trace); - case GF_ISOM_BOX_TYPE_ODTT: return odtt_dump(a, trace); - case GF_ISOM_BOX_TYPE_ODRB: return odrb_dump(a, trace); - case GF_ISOM_BOX_TYPE_ODKM: return odkm_dump(a, trace); - case GF_ISOM_BOX_TYPE_ODAF: return iSFM_dump(a, trace); - - case GF_ISOM_BOX_TYPE_TSEL: return tsel_dump(a, trace); - case GF_ISOM_BOX_TYPE_METX: return metx_dump(a, trace); - case GF_ISOM_BOX_TYPE_METT: return metx_dump(a, trace); - - case GF_ISOM_BOX_TYPE_DIMS: return dims_dump(a, trace); - case GF_ISOM_BOX_TYPE_DIMC: return dimC_dump(a, trace); - case GF_ISOM_BOX_TYPE_DIST: return diST_dump(a, trace); - - case GF_ISOM_BOX_TYPE_AC3: return ac3_dump(a, trace); - case GF_ISOM_BOX_TYPE_DAC3: return dac3_dump(a, trace); + case GF_ISOM_BOX_TYPE_ILST: + return ilst_dump(a, trace); + + case GF_ISOM_BOX_TYPE_OHDR: + return ohdr_dump(a, trace); + case GF_ISOM_BOX_TYPE_GRPI: + return grpi_dump(a, trace); + case GF_ISOM_BOX_TYPE_MDRI: + return mdri_dump(a, trace); + case GF_ISOM_BOX_TYPE_ODTT: + return odtt_dump(a, trace); + case GF_ISOM_BOX_TYPE_ODRB: + return odrb_dump(a, trace); + case GF_ISOM_BOX_TYPE_ODKM: + return odkm_dump(a, trace); + case GF_ISOM_BOX_TYPE_ODAF: + return iSFM_dump(a, trace); + + case GF_ISOM_BOX_TYPE_TSEL: + return tsel_dump(a, trace); + case GF_ISOM_BOX_TYPE_METX: + return metx_dump(a, trace); + case GF_ISOM_BOX_TYPE_METT: + return metx_dump(a, trace); + + case GF_ISOM_BOX_TYPE_DIMS: + return dims_dump(a, trace); + case GF_ISOM_BOX_TYPE_DIMC: + return dimC_dump(a, trace); + case GF_ISOM_BOX_TYPE_DIST: + return diST_dump(a, trace); + + case GF_ISOM_BOX_TYPE_AC3: + return ac3_dump(a, trace); + case GF_ISOM_BOX_TYPE_DAC3: + return dac3_dump(a, trace); + + case GF_ISOM_BOX_TYPE_LSR1: + return lsr1_dump(a, trace); + case GF_ISOM_BOX_TYPE_LSRC: + return lsrc_dump(a, trace); + case GF_ISOM_BOX_TYPE_SIDX: + return sidx_dump(a, trace); default: return defa_dump(a, trace); } @@ -319,8 +462,10 @@ GF_Err gf_isom_dump(GF_ISOFile *mov, FILE * trace) case GF_ISOM_BOX_TYPE_FREE: case GF_ISOM_BOX_TYPE_META: case GF_ISOM_BOX_TYPE_SKIP: -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS case GF_ISOM_BOX_TYPE_MOOF: + case GF_ISOM_BOX_TYPE_STYP: + case GF_ISOM_BOX_TYPE_SIDX: #endif break; @@ -406,7 +551,7 @@ GF_Err moov_dump(GF_Box *a, FILE * trace) if (p->meta) gf_box_dump(p->meta, trace); gf_box_dump(p->mvhd, trace); -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS if (p->mvex) gf_box_dump(p->mvex, trace); #endif @@ -429,7 +574,7 @@ GF_Err mvhd_dump(GF_Box *a, FILE * trace) fprintf(trace, "TimeScale=\"%d\" ", p->timeScale); fprintf(trace, "Duration=\""LLD"\" ", LLD_CAST p->duration); fprintf(trace, "NextTrackID=\"%d\">\n", p->nextTrackID); - + DumpBox(a, trace); gf_full_box_dump(a, trace); @@ -440,7 +585,7 @@ GF_Err mvhd_dump(GF_Box *a, FILE * trace) GF_Err mdhd_dump(GF_Box *a, FILE * trace) { GF_MediaHeaderBox *p; - + p = (GF_MediaHeaderBox *)a; fprintf(trace, "<MediaHeaderBox "); @@ -486,7 +631,7 @@ GF_Err hmhd_dump(GF_Box *a, FILE * trace) fprintf(trace, "AveragePDUSize=\"%d\" ", p->avgPDUSize); fprintf(trace, "MaxBitRate=\"%d\" ", p->maxBitrate); fprintf(trace, "AverageBitRate=\"%d\">\n", p->avgBitrate); - + DumpBox(a, trace); gf_full_box_dump(a, trace); fprintf(trace, "</HintMediaHeaderBox>\n"); @@ -552,7 +697,7 @@ GF_Err url_dump(GF_Box *a, FILE * trace) } else { fprintf(trace, "<!--Data is contained in the movie file-->\n"); } - } + } DumpBox(a, trace); gf_full_box_dump(a, trace); fprintf(trace, "</URLDataEntryBox>\n"); @@ -666,7 +811,11 @@ GF_Err iods_dump(GF_Box *a, FILE * trace) gf_full_box_dump(a, trace); if (p->descriptor) { +#ifndef GPAC_DISABLE_OD_DUMP gf_odf_dump_desc(p->descriptor, trace, 1, 1); +#else + fprintf(trace, "<!-- Object Descriptor Dumping disabled in this build of GPAC -->\n"); +#endif } else { fprintf(trace, "<!--WARNING: Object Descriptor not present-->\n"); } @@ -690,7 +839,7 @@ GF_Err trak_dump(GF_Box *a, FILE * trace) if (p->meta) gf_box_dump(p->meta, 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); + if (p->udta) gf_box_dump(p->udta, trace); gf_box_array_dump(p->boxes, trace); fprintf(trace, "</TrackBox>\n"); return GF_OK; @@ -738,13 +887,12 @@ GF_Err mp4v_dump(GF_Box *a, FILE * trace) if (p->esd) { gf_box_dump(p->esd, trace); - } else if (p->avc_config) { + } else { if (p->avc_config) gf_box_dump(p->avc_config, trace); if (p->ipod_ext) gf_box_dump(p->ipod_ext, trace); if (p->descr) gf_box_dump(p->descr, trace); if (p->bitrate) gf_box_dump(p->bitrate, trace); - } else { - fprintf(trace, "<!--INVALID MP4 FILE: ESDBox not present in MPEG Sample Description or corrupted-->\n"); + 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); @@ -800,7 +948,7 @@ GF_Err gnrm_dump(GF_Box *a, FILE * trace) 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", + 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); a->type = p->EntryType; DumpBox(a, trace); @@ -812,7 +960,7 @@ GF_Err gnrv_dump(GF_Box *a, FILE * trace) GF_Err gnra_dump(GF_Box *a, FILE * trace) { GF_GenericAudioSampleEntryBox *p = (GF_GenericAudioSampleEntryBox *)a; - fprintf(trace, "<AudioSampleDescriptionBox DataReferenceIndex=\"%d\" Version=\"%d\" Revision=\"%d\" Vendor=\"%d\" ChannelCount=\"%d\" BitsPerSample=\"%d\" Samplerate=\"%d\">\n", + fprintf(trace, "<AudioSampleDescriptionBox DataReferenceIndex=\"%d\" Version=\"%d\" Revision=\"%d\" Vendor=\"%d\" ChannelCount=\"%d\" BitsPerSample=\"%d\" Samplerate=\"%d\">\n", p->dataReferenceIndex, p->version, p->revision, p->vendor, p->channel_count, p->bitspersample, p->samplerate_hi); a->type = p->EntryType; DumpBox(a, trace); @@ -942,7 +1090,7 @@ GF_Err elst_dump(GF_Box *a, FILE * trace) i=0; while ((t = (GF_EdtsEntry *)gf_list_enum(p->entryList, &i))) { - fprintf(trace, "<EditListEntry Duration=\""LLD"\" MediaTime=\""LLD"\" MediaRate=\"%d\"/>\n", LLD_CAST t->segmentDuration, LLD_CAST t->mediaTime, t->mediaRate); + fprintf(trace, "<EditListEntry Duration=\""LLD"\" MediaTime=\""LLD"\" MediaRate=\"%u\"/>\n", LLD_CAST t->segmentDuration, LLD_CAST t->mediaTime, t->mediaRate); } fprintf(trace, "</EditListBox>\n"); return GF_OK; @@ -1114,7 +1262,7 @@ GF_Err co64_dump(GF_Box *a, FILE * trace) if (!p->offsets) { fprintf(trace, "<Warning: No Chunk Offsets indications/>\n"); } else { - for (i=0; i<p->nb_entries; i++) + for (i=0; i<p->nb_entries; i++) fprintf(trace, "<ChunkOffsetEntry offset=\""LLD"\"/>\n", LLD_CAST p->offsets[i]); } fprintf(trace, "</ChunkLargeOffsetBox>\n"); @@ -1131,7 +1279,11 @@ GF_Err esds_dump(GF_Box *a, FILE * trace) gf_full_box_dump(a, trace); if (p->desc) { +#ifndef GPAC_DISABLE_OD_DUMP gf_odf_dump_desc(p->desc, trace, 1, 1); +#else + fprintf(trace, "<!-- Object Descriptor Dumping disabled in this build of GPAC -->\n"); +#endif } else { fprintf(trace, "<!--INVALID MP4 FILE: ESD not present in MPEG Sample Description or corrupted-->\n"); } @@ -1147,9 +1299,9 @@ GF_Err minf_dump(GF_Box *a, FILE * trace) fprintf(trace, "<MediaInformationBox>\n"); DumpBox(a, trace); - gf_box_dump(p->InfoHeader, trace); - gf_box_dump(p->dataInformation, trace); - gf_box_dump(p->sampleTable, trace); + gf_box_dump(p->InfoHeader, trace); + gf_box_dump(p->dataInformation, trace); + gf_box_dump(p->sampleTable, trace); fprintf(trace, "</MediaInformationBox>\n"); return GF_OK; } @@ -1160,16 +1312,15 @@ GF_Err tkhd_dump(GF_Box *a, FILE * trace) p = (GF_TrackHeaderBox *)a; fprintf(trace, "<TrackHeaderBox "); - fprintf(trace, "CreationTime=\""LLD"\" ModificationTime=\""LLD"\" TrackID=\"%d\" Duration=\""LLD"\"", + fprintf(trace, "CreationTime=\""LLD"\" ModificationTime=\""LLD"\" TrackID=\"%u\" Duration=\""LLD"\"", LLD_CAST p->creationTime, LLD_CAST p->modificationTime, p->trackID, LLD_CAST p->duration); - + if (p->alternate_group) fprintf(trace, " AlternateGroupID=\"%d\"", p->alternate_group); if (p->volume) { fprintf(trace, " Volume=\"%.2f\"", (Float)p->volume / 256); } else if (p->width || p->height) { fprintf(trace, " Width=\"%.2f\" Height=\"%.2f\"", (Float)p->width / 65536, (Float)p->height / 65536); if (p->layer) fprintf(trace, " Layer=\"%d\"", p->layer); - if (p->alternate_group) fprintf(trace, " AlternateGroup=\"%d\"", p->alternate_group); } fprintf(trace, ">\n"); if (p->width || p->height) { @@ -1233,13 +1384,13 @@ GF_Err ftyp_dump(GF_Box *a, FILE * trace) u32 i; p = (GF_FileTypeBox *)a; - fprintf(trace, "<FileTypeBox MajorBrand=\"%s\" MinorVersion=\"%d\">\n", gf_4cc_to_str(p->majorBrand), p->minorVersion); + fprintf(trace, "<%s MajorBrand=\"%s\" MinorVersion=\"%d\">\n", (a->type == GF_ISOM_BOX_TYPE_FTYP ? "FileTypeBox" : "SegmentTypeBox"), gf_4cc_to_str(p->majorBrand), p->minorVersion); DumpBox(a, trace); for (i=0; i<p->altCount; i++) { fprintf(trace, "<BrandEntry AlternateBrand=\"%s\"/>\n", gf_4cc_to_str(p->altBrand[i])); } - fprintf(trace, "</FileTypeBox>\n"); + fprintf(trace, "</%s>\n",(a->type == GF_ISOM_BOX_TYPE_FTYP ? "FileTypeBox" : "SegmentTypeBox")); return GF_OK; } @@ -1247,7 +1398,7 @@ GF_Err padb_dump(GF_Box *a, FILE * trace) { GF_PaddingBitsBox *p; u32 i; - + p = (GF_PaddingBitsBox *)a; fprintf(trace, "<PaddingBitsBox EntryCount=\"%d\">\n", p->SampleCount); DumpBox(a, trace); @@ -1264,7 +1415,7 @@ GF_Err stsf_dump(GF_Box *a, FILE * trace) GF_StsfEntry *ent; u32 i, j, count; - + p = (GF_SampleFragmentBox *)a; count = gf_list_count(p->entryList); fprintf(trace, "<SampleFragmentBox EntryCount=\"%d\">\n", count); @@ -1365,7 +1516,7 @@ GF_Err gppc_dump(GF_Box *a, FILE * trace) DumpBox(a, trace); fprintf(trace, "</H263ConfigurationBox>\n"); break; - default: + default: break; } return GF_OK; @@ -1376,29 +1527,34 @@ GF_Err avcc_dump(GF_Box *a, FILE * trace) { u32 i, count; GF_AVCConfigurationBox *p = (GF_AVCConfigurationBox *) a; - fprintf(trace, "<AVCConfigurationBox>\n"); + const char *name = (p->type==GF_ISOM_BOX_TYPE_SVCC) ? "SVC" : "AVC"; + fprintf(trace, "<%sConfigurationBox>\n", name); - fprintf(trace, "<AVCDecoderConfigurationRecord configurationVersion=\"%d\" AVCProfileIndication=\"%d\" profile_compatibility=\"%d\" AVCLevelIndication=\"%d\" nal_unit_size=\"%d\">\n", - p->config->configurationVersion, p->config->AVCProfileIndication, p->config->profile_compatibility, p->config->AVCLevelIndication, p->config->nal_unit_size); + fprintf(trace, "<%sDecoderConfigurationRecord configurationVersion=\"%d\" AVCProfileIndication=\"%d\" profile_compatibility=\"%d\" AVCLevelIndication=\"%d\" nal_unit_size=\"%d\"", + name, p->config->configurationVersion, p->config->AVCProfileIndication, p->config->profile_compatibility, p->config->AVCLevelIndication, p->config->nal_unit_size); + + if (p->type==GF_ISOM_BOX_TYPE_SVCC) + fprintf(trace, " complete_representation=\"%d\"", p->config->complete_representation); + 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, "<sequenceParameterSets 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, "<pictureParameterSets size=\"%d\" content=\"", c->size); + fprintf(trace, "<pictureParameterSet size=\"%d\" content=\"", c->size); DumpData(trace, c->data, c->size); fprintf(trace, "\"/>\n"); } - fprintf(trace, "</AVCDecoderConfigurationRecord>\n"); + fprintf(trace, "</%sDecoderConfigurationRecord>\n", name); DumpBox(a, trace); - fprintf(trace, "</AVCConfigurationBox>\n"); + fprintf(trace, "</%sConfigurationBox>\n", name); return GF_OK; } @@ -1411,7 +1567,11 @@ GF_Err m4ds_dump(GF_Box *a, FILE * trace) i=0; while ((desc = (GF_Descriptor *)gf_list_enum(p->descriptors, &i))) { +#ifndef GPAC_DISABLE_OD_DUMP gf_odf_dump_desc(desc, trace, 1, 1); +#else + fprintf(trace, "<!-- Object Descriptor Dumping disabled in this build of GPAC -->\n"); +#endif } DumpBox(a, trace); fprintf(trace, "</MPEG4ExtensionDescriptorsBox>\n"); @@ -1440,10 +1600,14 @@ GF_Err ftab_dump(GF_Box *a, FILE * trace) return GF_OK; } -static void gpp_dump_rgba(FILE * trace, char *name, u32 col) +static void gpp_dump_rgba8(FILE * trace, char *name, u32 col) { fprintf(trace, "%s=\"%x %x %x %x\"", name, (col>>16)&0xFF, (col>>8)&0xFF, (col)&0xFF, (col>>24)&0xFF); } +static void gpp_dump_rgb16(FILE * trace, char *name, char col[6]) +{ + fprintf(trace, "%s=\"%x %x %x\"", name, *((u16*)col), *((u16*)(col+1)), *((u16*)(col+2))); +} static void gpp_dump_box(FILE * trace, GF_BoxRecord *rec) { fprintf(trace, "<BoxRecord top=\"%d\" left=\"%d\" bottom=\"%d\" right=\"%d\"/>\n", rec->top, rec->left, rec->bottom, rec->right); @@ -1459,17 +1623,17 @@ static void gpp_dump_style(FILE * trace, GF_StyleRecord *rec) if (rec->style_flags & 4) fprintf(trace, "Underlined "); } fprintf(trace, "\" fontSize=\"%d\" ", rec->font_size); - gpp_dump_rgba(trace, "text-color", rec->text_color); + gpp_dump_rgba8(trace, "text-color", rec->text_color); fprintf(trace, "/>\n"); } GF_Err tx3g_dump(GF_Box *a, FILE * trace) { - GF_TextSampleEntryBox *p = (GF_TextSampleEntryBox *)a; - fprintf(trace, "<TextSampleEntryBox dataReferenceIndex=\"%d\" displayFlags=\"%x\" horizontal-justification=\"%d\" vertical-justification=\"%d\" ", + GF_Tx3gSampleEntryBox *p = (GF_Tx3gSampleEntryBox *)a; + fprintf(trace, "<Tx3gSampleEntryBox dataReferenceIndex=\"%d\" displayFlags=\"%x\" horizontal-justification=\"%d\" vertical-justification=\"%d\" ", p->dataReferenceIndex, p->displayFlags, p->horizontal_justification, p->vertical_justification); - gpp_dump_rgba(trace, "background-color", p->back_color); + gpp_dump_rgba8(trace, "background-color", p->back_color); fprintf(trace, ">\n"); DumpBox(a, trace); @@ -1480,9 +1644,29 @@ GF_Err tx3g_dump(GF_Box *a, FILE * trace) gpp_dump_style(trace, &p->default_style); fprintf(trace, "</DefaultStyle>\n"); gf_box_dump(p->font_table, trace); + fprintf(trace, "</Tx3gSampleEntryBox>\n"); + return GF_OK; +} + +GF_Err text_dump(GF_Box *a, FILE * trace) +{ + GF_TextSampleEntryBox *p = (GF_TextSampleEntryBox *)a; + fprintf(trace, "<TextSampleEntryBox dataReferenceIndex=\"%d\" displayFlags=\"%x\" textJustification=\"%d\" ", + p->dataReferenceIndex, p->displayFlags, p->textJustification); + if (p->textName) + fprintf(trace, "textName=%s ", p->textName); + gpp_dump_rgb16(trace, "background-color", p->background_color); + gpp_dump_rgb16(trace, "foreground-color", p->foreground_color); + fprintf(trace, ">\n"); + DumpBox(a, trace); + + fprintf(trace, "<DefaultBox>\n"); + gpp_dump_box(trace, &p->default_box); + fprintf(trace, "</DefaultBox>\n"); fprintf(trace, "</TextSampleEntryBox>\n"); return GF_OK; } + GF_Err styl_dump(GF_Box *a, FILE * trace) { u32 i; @@ -1505,7 +1689,7 @@ GF_Err hclr_dump(GF_Box *a, FILE * trace) { GF_TextHighlightColorBox*p = (GF_TextHighlightColorBox*)a; fprintf(trace, "<TextHighlightBox "); - gpp_dump_rgba(trace, "highlight_color", p->hil_color); + gpp_dump_rgba8(trace, "highlight_color", p->hil_color); fprintf(trace, ">\n"); DumpBox(a, trace); fprintf(trace, "</TextHighlightBox>\n"); @@ -1915,9 +2099,9 @@ GF_Err ghnt_dump(GF_Box *a, FILE * trace) GF_HintSampleEntryBox *p; p = (GF_HintSampleEntryBox *)a; - fprintf(trace, "<GenericHintSampleEntryBox EntrySubType=\"%s\" DataReferenceIndex=\"%d\" HintTrackVersion=\"%d\" LastCompatibleVersion=\"%d\" MaxPacketSize=\"%d\">\n", - gf_4cc_to_str(p->type), p->dataReferenceIndex, p->HintTrackVersion, p->LastCompatibleVersion, p->MaxPacketSize); - + fprintf(trace, "<GenericHintSampleEntryBox EntrySubType=\"%s\" DataReferenceIndex=\"%d\" HintTrackVersion=\"%d\" LastCompatibleVersion=\"%d\" MaxPacketSize=\"%d\">\n", + gf_4cc_to_str(p->type), p->dataReferenceIndex, p->HintTrackVersion, p->LastCompatibleVersion, p->MaxPacketSize); + DumpBox(a, trace); gf_box_array_dump(p->HintDataTable, trace); fprintf(trace, "</GenericHintSampleEntryBox>\n"); @@ -1975,7 +2159,7 @@ GF_Err rtpo_dump(GF_Box *a, FILE * trace) -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS GF_Err mvex_dump(GF_Box *a, FILE * trace) { @@ -2008,7 +2192,7 @@ GF_Err trex_dump(GF_Box *a, FILE * trace) fprintf(trace, "<TrackExtendsBox TrackID=\"%d\"", p->trackID); fprintf(trace, " SampleDescriptionIndex=\"%d\" SampleDuration=\"%d\" SampleSize=\"%d\"", p->def_sample_desc_index, p->def_sample_duration, p->def_sample_size); - fprintf(trace, " SamplePadding=\"%d\" SampleSync=\"%d\" SampleDegradationPriority=\"%d\"", + fprintf(trace, " SamplePadding=\"%d\" SampleSync=\"%d\" SampleDegradationPriority=\"%d\"", GF_ISOM_GET_FRAG_PAD(p->def_sample_flags), GF_ISOM_GET_FRAG_SYNC(p->def_sample_flags), GF_ISOM_GET_FRAG_DEG(p->def_sample_flags)); fprintf(trace, ">\n"); @@ -2053,6 +2237,7 @@ GF_Err traf_dump(GF_Box *a, FILE * trace) DumpBox(a, trace); if (p->tfhd) gf_box_dump(p->tfhd, trace); gf_box_array_dump(p->TrackRuns, trace); + if (p->sdtp) gf_box_dump(p->sdtp, trace); fprintf(trace, "</TrackFragmentBox>\n"); return GF_OK; } @@ -2067,17 +2252,17 @@ GF_Err tfhd_dump(GF_Box *a, FILE * trace) if (p->flags & GF_ISOM_TRAF_BASE_OFFSET) { fprintf(trace, " BaseDataOffset=\""LLD"\"", LLD_CAST p->base_data_offset); } - if (p->flags & GF_ISOM_TRAF_SAMPLE_DESC) + if (p->flags & GF_ISOM_TRAF_SAMPLE_DESC) fprintf(trace, "SampleDescriptionIndex=\"%d\"", p->sample_desc_index); - if (p->flags & GF_ISOM_TRAF_SAMPLE_DUR) + if (p->flags & GF_ISOM_TRAF_SAMPLE_DUR) fprintf(trace, " SampleDuration=\"%d\"", p->def_sample_duration); - if (p->flags & GF_ISOM_TRAF_SAMPLE_SIZE) + if (p->flags & GF_ISOM_TRAF_SAMPLE_SIZE) fprintf(trace, " SampleSize=\"%d\"", p->def_sample_size); if (p->flags & GF_ISOM_TRAF_SAMPLE_FLAGS) { fprintf(trace, " SamplePadding=\"%d\"", GF_ISOM_GET_FRAG_PAD(p->def_sample_flags)); 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); @@ -2095,7 +2280,7 @@ GF_Err trun_dump(GF_Box *a, FILE * trace) p = (GF_TrackFragmentRunBox *)a; fprintf(trace, "<TrackRunBox SampleCount=\"%d\"", p->sample_count); - if (p->flags & GF_ISOM_TRUN_DATA_OFFSET) + if (p->flags & GF_ISOM_TRUN_DATA_OFFSET) fprintf(trace, " DataOffset=\"%d\"", p->data_offset); if (p->flags & GF_ISOM_TRUN_FIRST_FLAG) { fprintf(trace, " FirstSamplePadding=\"%d\" FirstSampleSync=\"%d\" FirstSampleDegradationPriority=\"%d\"", GF_ISOM_GET_FRAG_PAD(p->first_sample_flags), GF_ISOM_GET_FRAG_SYNC(p->first_sample_flags), GF_ISOM_GET_FRAG_DEG(p->first_sample_flags)); @@ -2112,15 +2297,15 @@ GF_Err trun_dump(GF_Box *a, FILE * trace) if (p->flags & GF_ISOM_TRUN_DURATION) fprintf(trace, " Duration=\"%d\"", ent->Duration); - if (p->flags & GF_ISOM_TRUN_SIZE) - fprintf(trace, " Size=\"%d\"", ent->size); + if (p->flags & GF_ISOM_TRUN_SIZE) + fprintf(trace, " Size=\"%d\"", ent->size); if (p->flags & GF_ISOM_TRUN_CTS_OFFSET) fprintf(trace, " CTSOffset=\"%d\"", ent->CTS_Offset); if (p->flags & GF_ISOM_TRUN_FLAGS) { - fprintf(trace, " SamplePadding=\"%d\" Sync=\"%d\" DegradationPriority=\"%d\"", + fprintf(trace, " SamplePadding=\"%d\" Sync=\"%d\" DegradationPriority=\"%d\"", GF_ISOM_GET_FRAG_PAD(ent->flags), GF_ISOM_GET_FRAG_SYNC(ent->flags), GF_ISOM_GET_FRAG_DEG(ent->flags)); - } + } fprintf(trace, "/>\n"); } } else { @@ -2130,9 +2315,10 @@ GF_Err trun_dump(GF_Box *a, FILE * trace) return GF_OK; } - #endif +#ifndef GPAC_DISABLE_ISOM_HINTING + GF_Err DTE_Dump(GF_List *dte, FILE * trace) { GF_GenericDTE *p; @@ -2154,12 +2340,12 @@ GF_Err DTE_Dump(GF_List *dte, FILE * trace) break; case 2: s_p = (GF_SampleDTE *) p; - fprintf(trace, "<SampleDataEntry DataSize=\"%d\" SampleOffset=\"%d\" SampleNumber=\"%d\" TrackReference=\"%d\"/>\n", + fprintf(trace, "<SampleDataEntry DataSize=\"%d\" SampleOffset=\"%d\" SampleNumber=\"%d\" TrackReference=\"%d\"/>\n", s_p->dataLength, s_p->byteOffset, s_p->sampleNumber, s_p->trackRefIndex); break; case 3: sd_p = (GF_StreamDescDTE *) p; - fprintf(trace, "<SampleDescriptionEntry DataSize=\"%d\" DescriptionOffset=\"%d\" StreamDescriptionindex=\"%d\" TrackReference=\"%d\"/>\n", + fprintf(trace, "<SampleDescriptionEntry DataSize=\"%d\" DescriptionOffset=\"%d\" StreamDescriptionindex=\"%d\" TrackReference=\"%d\"/>\n", sd_p->dataLength, sd_p->byteOffset, sd_p->streamDescIndex, sd_p->trackRefIndex); break; default: @@ -2185,7 +2371,7 @@ GF_Err gf_isom_dump_hint_sample(GF_ISOFile *the_file, u32 trackNumber, u32 Sampl trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak || !IsHintTrack(trak)) return GF_BAD_PARAM; - + tmp = gf_isom_get_sample(the_file, trackNumber, SampleNum, &descIndex); if (!tmp) return GF_BAD_PARAM; @@ -2211,18 +2397,18 @@ GF_Err gf_isom_dump_hint_sample(GF_ISOFile *the_file, u32 trackNumber, u32 Sampl count = gf_list_count(s->packetTable); - fprintf(trace, "<RTPHintSample SampleNumber=\"%d\" DecodingTime=\""LLD"\" RandomAccessPoint=\"%d\" PacketCount=\"%d\">\n", SampleNum, LLD_CAST tmp->DTS, tmp->IsRAP, count); + fprintf(trace, "<RTPHintSample SampleNumber=\"%d\" DecodingTime=\""LLD"\" RandomAccessPoint=\"%d\" PacketCount=\"%u\">\n", SampleNum, LLD_CAST tmp->DTS, tmp->IsRAP, count); for (i=0; i<count; i++) { pck = (GF_RTPPacket *)gf_list_get(s->packetTable, i); - fprintf(trace, "<RTPHintPacket PacketNumber=\"%d\" P=\"%d\" X=\"%d\" M=\"%d\" PayloadType=\"%d\"", + fprintf(trace, "<RTPHintPacket PacketNumber=\"%d\" P=\"%d\" X=\"%d\" M=\"%d\" PayloadType=\"%d\"", i+1, pck->P_bit, pck->X_bit, pck->M_bit, pck->payloadType); - fprintf(trace, " SequenceNumber=\"%d\" RepeatedPacket=\"%d\" DropablePacket=\"%d\" RelativeTransmissionTime=\"%d\" FullPacketSize=\"%d\">\n", + fprintf(trace, " SequenceNumber=\"%d\" RepeatedPacket=\"%d\" DropablePacket=\"%d\" RelativeTransmissionTime=\"%d\" FullPacketSize=\"%d\">\n", pck->SequenceNumber, pck->R_bit, pck->B_bit, pck->relativeTransTime, gf_isom_hint_rtp_length(pck)); - + //TLV is made of Boxes count2 = gf_list_count(pck->TLV); if (count2) { @@ -2246,6 +2432,7 @@ GF_Err gf_isom_dump_hint_sample(GF_ISOFile *the_file, u32 trackNumber, u32 Sampl return GF_OK; } +#endif /*GPAC_DISABLE_ISOM_HINTING*/ static void gpp_dump_box_nobox(FILE * trace, GF_BoxRecord *rec) { @@ -2275,7 +2462,7 @@ static void gpp_print_char_offsets(FILE * trace, u32 start, u32 end, u32 *shift_ static void gpp_dump_style_nobox(FILE * trace, GF_StyleRecord *rec, u32 *shift_offset, u32 so_count) { fprintf(trace, "<Style "); - if (rec->startCharOffset || rec->endCharOffset) + if (rec->startCharOffset || rec->endCharOffset) gpp_print_char_offsets(trace, rec->startCharOffset, rec->endCharOffset, shift_offset, so_count); fprintf(trace, "styles=\""); @@ -2287,14 +2474,14 @@ static void gpp_dump_style_nobox(FILE * trace, GF_StyleRecord *rec, u32 *shift_o if (rec->style_flags & 4) fprintf(trace, "Underlined "); } fprintf(trace, "\" fontID=\"%d\" fontSize=\"%d\" ", rec->fontID, rec->font_size); - gpp_dump_rgba(trace, "color", rec->text_color); + gpp_dump_rgba8(trace, "color", rec->text_color); fprintf(trace, "/>\n"); } static char *ttd_format_time(u64 ts, u32 timescale, char *szDur, Bool is_srt) { u32 h, m, s, ms; - ts = (u32) (( ((Double) (s64) ts)/timescale)*1000.0); + ts = (u32) (ts*1000 / timescale); h = (u32) (ts / 3600000); m = (u32) (ts/ 60000) - h*60; s = (u32) (ts/1000) - h*3600 - m*60; @@ -2316,13 +2503,26 @@ static GF_Err gf_isom_dump_ttxt_track(GF_ISOFile *the_file, u32 track, FILE *dum GF_Box *a; Bool has_scroll; char szDur[100]; - GF_TextSampleEntryBox *txt; + GF_Tx3gSampleEntryBox *txt; GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, track); - if (!trak || (trak->Media->handler->handlerType != GF_ISOM_MEDIA_TEXT)) return GF_BAD_PARAM; - - txt = (GF_TextSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 0); - if (txt->type != GF_ISOM_BOX_TYPE_TX3G) return GF_BAD_PARAM; + if (!trak) return GF_BAD_PARAM; + switch (trak->Media->handler->handlerType) { + case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: + break; + default: + return GF_BAD_PARAM; + } + + txt = (GF_Tx3gSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 0); + switch (txt->type) { + case GF_ISOM_BOX_TYPE_TX3G: + break; + case GF_ISOM_BOX_TYPE_TEXT: + default: + return GF_BAD_PARAM; + } fprintf(dump, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"); fprintf(dump, "<!-- GPAC 3GPP Text Stream -->\n"); @@ -2336,7 +2536,7 @@ static GF_Err gf_isom_dump_ttxt_track(GF_ISOFile *the_file, u32 track, FILE *dum nb_descs = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList); for (i=0; i<nb_descs; i++) { - GF_TextSampleEntryBox *txt = (GF_TextSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, i); + GF_Tx3gSampleEntryBox *txt = (GF_Tx3gSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, i); fprintf(dump, "<TextSampleDescription horizontalJustification=\""); switch (txt->horizontal_justification) { @@ -2351,7 +2551,7 @@ static GF_Err gf_isom_dump_ttxt_track(GF_ISOFile *the_file, u32 track, FILE *dum default: fprintf(dump, "top"); break; } fprintf(dump, "\" "); - gpp_dump_rgba(dump, "backColor", txt->back_color); + gpp_dump_rgba8(dump, "backColor", txt->back_color); fprintf(dump, " verticalText=\"%s\"", (txt->displayFlags & GF_TXT_VERTICAL) ? "yes" : "no"); fprintf(dump, " fillTextRegion=\"%s\"", (txt->displayFlags & GF_TXT_FILL_REGION) ? "yes" : "no"); fprintf(dump, " continuousKaraoke=\"%s\"", (txt->displayFlags & GF_TXT_KARAOKE) ? "yes" : "no"); @@ -2381,7 +2581,7 @@ static GF_Err gf_isom_dump_ttxt_track(GF_ISOFile *the_file, u32 track, FILE *dum if (txt->font_table) { for (j=0; j<txt->font_table->entry_count; j++) { fprintf(dump, "<FontTableEntry fontName=\"%s\" fontID=\"%d\"/>\n", txt->font_table->fonts[j].fontName, txt->font_table->fonts[j].fontID); - + } } fprintf(dump, "</FontTable>\n"); @@ -2414,7 +2614,7 @@ static GF_Err gf_isom_dump_ttxt_track(GF_ISOFile *the_file, u32 track, FILE *dum if (txt->highlight_color) { fprintf(dump, " "); - gpp_dump_rgba(dump, "highlightColor", txt->highlight_color->hil_color); + gpp_dump_rgba8(dump, "highlightColor", txt->highlight_color->hil_color); } if (txt->scroll_delay) { Double delay = txt->scroll_delay->scroll_delay; @@ -2463,7 +2663,7 @@ static GF_Err gf_isom_dump_ttxt_track(GF_ISOFile *the_file, u32 track, FILE *dum so_count++; j++; } - } + } else { switch (utf16Line[j]) { case '\'': fprintf(dump, "'"); break; @@ -2523,7 +2723,7 @@ static GF_Err gf_isom_dump_ttxt_track(GF_ISOFile *the_file, u32 track, FILE *dum fprintf(dump, "/>\n"); break; case GF_ISOM_BOX_TYPE_KROK: - { + { u32 k; Double t; GF_TextKaraokeBox *krok = (GF_TextKaraokeBox *)a; @@ -2561,12 +2761,19 @@ static GF_Err gf_isom_dump_srt_track(GF_ISOFile *the_file, u32 track, FILE *dump { u32 i, j, k, count, di, len, ts, cur_frame; u64 start, end; - GF_TextSampleEntryBox *txtd; + GF_Tx3gSampleEntryBox *txtd; GF_BitStream *bs; char szDur[100]; GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, track); - if (!trak || (trak->Media->handler->handlerType != GF_ISOM_MEDIA_TEXT)) return GF_BAD_PARAM; + if (!trak) return GF_BAD_PARAM; + switch (trak->Media->handler->handlerType) { + case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: + break; + default: + return GF_BAD_PARAM; + } ts = trak->Media->mediaHeader->timeScale; cur_frame = 0; @@ -2601,11 +2808,12 @@ 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_TextSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, di-1); + txtd = (GF_Tx3gSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, di-1); if (!txt->len) { fprintf(dump, "\n"); }else { + u32 styles, char_num, new_styles; u16 utf16Line[10000]; /*UTF16*/ @@ -2615,77 +2823,75 @@ static GF_Err gf_isom_dump_srt_track(GF_ISOFile *the_file, u32 track, FILE *dump len = txt->len; } else { u8 *str = (u8 *) (txt->text); - len = gf_utf8_mbstowcs(utf16Line, 10000, (const char **) &str); + s32 res = gf_utf8_mbstowcs(utf16Line, 10000, (const char **) &str); + if (res<0) return GF_NON_COMPLIANT_BITSTREAM; + len = (u32) res; utf16Line[len] = 0; } - if (len>=0) { - u32 styles, char_num, new_styles; - char_num = 0; - styles = 0; - new_styles = txtd->default_style.style_flags; - for (j=0; j<len; j++) { - Bool is_new_line; - - if (txt->styles) { - new_styles = txtd->default_style.style_flags; - for (k=0; k<txt->styles->entry_count; k++) { - if (txt->styles->styles[k].startCharOffset>char_num) continue; - if (txt->styles->styles[k].endCharOffset<char_num+1) continue; - - if (txt->styles->styles[k].style_flags & (GF_TXT_STYLE_ITALIC | GF_TXT_STYLE_BOLD | GF_TXT_STYLE_UNDERLINED)) { - new_styles = txt->styles->styles[k].style_flags; - break; - } - } - } - if (new_styles != styles) { - if ((new_styles & GF_TXT_STYLE_BOLD) && !(styles & GF_TXT_STYLE_BOLD)) fprintf(dump, "<b>"); - if ((new_styles & GF_TXT_STYLE_ITALIC) && !(styles & GF_TXT_STYLE_ITALIC)) fprintf(dump, "<i>"); - if ((new_styles & GF_TXT_STYLE_UNDERLINED) && !(styles & GF_TXT_STYLE_UNDERLINED)) fprintf(dump, "<u>"); - - if ((styles & GF_TXT_STYLE_BOLD) && !(new_styles & GF_TXT_STYLE_BOLD)) fprintf(dump, "</b>"); - if ((styles & GF_TXT_STYLE_ITALIC) && !(new_styles & GF_TXT_STYLE_ITALIC)) fprintf(dump, "</i>"); - if ((styles & GF_TXT_STYLE_UNDERLINED) && !(new_styles & GF_TXT_STYLE_UNDERLINED)) fprintf(dump, "</u>"); - - styles = new_styles; - } - - /*not sure if styles must be reseted at line breaks in srt...*/ - is_new_line = 0; - if ((utf16Line[j]=='\n') || (utf16Line[j]=='\r') ) { - if ((utf16Line[j]=='\r') && (utf16Line[j+1]=='\n')) j++; - fprintf(dump, "\n"); - is_new_line = 1; - } - - if (!is_new_line) { - u32 sl; - char szChar[30]; - s16 swT[2], *swz; - swT[0] = utf16Line[j]; - swT[1] = 0; - swz= (s16 *)swT; - sl = gf_utf8_wcstombs(szChar, 30, (const unsigned short **) &swz); - szChar[sl]=0; - fprintf(dump, "%s", szChar); - } - char_num++; - } - new_styles = 0; - if (new_styles != styles) { - if ((new_styles & GF_TXT_STYLE_BOLD) && !(styles & GF_TXT_STYLE_BOLD)) fprintf(dump, "<b>"); - if ((new_styles & GF_TXT_STYLE_ITALIC) && !(styles & GF_TXT_STYLE_ITALIC)) fprintf(dump, "<i>"); - if ((new_styles & GF_TXT_STYLE_UNDERLINED) && !(styles & GF_TXT_STYLE_UNDERLINED)) fprintf(dump, "<u>"); - - if ((styles & GF_TXT_STYLE_BOLD) && !(new_styles & GF_TXT_STYLE_BOLD)) fprintf(dump, "</b>"); - if ((styles & GF_TXT_STYLE_ITALIC) && !(new_styles & GF_TXT_STYLE_ITALIC)) fprintf(dump, "</i>"); - if ((styles & GF_TXT_STYLE_UNDERLINED) && !(new_styles & GF_TXT_STYLE_UNDERLINED)) fprintf(dump, "</u>"); - - styles = new_styles; - } - - fprintf(dump, "\n"); - } + char_num = 0; + styles = 0; + new_styles = txtd->default_style.style_flags; + for (j=0; j<len; j++) { + Bool is_new_line; + + if (txt->styles) { + new_styles = txtd->default_style.style_flags; + for (k=0; k<txt->styles->entry_count; k++) { + if (txt->styles->styles[k].startCharOffset>char_num) continue; + if (txt->styles->styles[k].endCharOffset<char_num+1) continue; + + if (txt->styles->styles[k].style_flags & (GF_TXT_STYLE_ITALIC | GF_TXT_STYLE_BOLD | GF_TXT_STYLE_UNDERLINED)) { + new_styles = txt->styles->styles[k].style_flags; + break; + } + } + } + if (new_styles != styles) { + if ((new_styles & GF_TXT_STYLE_BOLD) && !(styles & GF_TXT_STYLE_BOLD)) fprintf(dump, "<b>"); + if ((new_styles & GF_TXT_STYLE_ITALIC) && !(styles & GF_TXT_STYLE_ITALIC)) fprintf(dump, "<i>"); + if ((new_styles & GF_TXT_STYLE_UNDERLINED) && !(styles & GF_TXT_STYLE_UNDERLINED)) fprintf(dump, "<u>"); + + if ((styles & GF_TXT_STYLE_BOLD) && !(new_styles & GF_TXT_STYLE_BOLD)) fprintf(dump, "</b>"); + if ((styles & GF_TXT_STYLE_ITALIC) && !(new_styles & GF_TXT_STYLE_ITALIC)) fprintf(dump, "</i>"); + if ((styles & GF_TXT_STYLE_UNDERLINED) && !(new_styles & GF_TXT_STYLE_UNDERLINED)) fprintf(dump, "</u>"); + + styles = new_styles; + } + + /*not sure if styles must be reseted at line breaks in srt...*/ + is_new_line = 0; + if ((utf16Line[j]=='\n') || (utf16Line[j]=='\r') ) { + if ((utf16Line[j]=='\r') && (utf16Line[j+1]=='\n')) j++; + fprintf(dump, "\n"); + is_new_line = 1; + } + + if (!is_new_line) { + u32 sl; + char szChar[30]; + s16 swT[2], *swz; + swT[0] = utf16Line[j]; + swT[1] = 0; + swz= (s16 *)swT; + sl = gf_utf8_wcstombs(szChar, 30, (const unsigned short **) &swz); + szChar[sl]=0; + fprintf(dump, "%s", szChar); + } + char_num++; + } + new_styles = 0; + if (new_styles != styles) { + if ((new_styles & GF_TXT_STYLE_BOLD) && !(styles & GF_TXT_STYLE_BOLD)) fprintf(dump, "<b>"); + if ((new_styles & GF_TXT_STYLE_ITALIC) && !(styles & GF_TXT_STYLE_ITALIC)) fprintf(dump, "<i>"); + if ((new_styles & GF_TXT_STYLE_UNDERLINED) && !(styles & GF_TXT_STYLE_UNDERLINED)) fprintf(dump, "<u>"); + + if ((styles & GF_TXT_STYLE_BOLD) && !(new_styles & GF_TXT_STYLE_BOLD)) fprintf(dump, "</b>"); + if ((styles & GF_TXT_STYLE_ITALIC) && !(new_styles & GF_TXT_STYLE_ITALIC)) fprintf(dump, "</i>"); + if ((styles & GF_TXT_STYLE_UNDERLINED) && !(new_styles & GF_TXT_STYLE_UNDERLINED)) fprintf(dump, "</u>"); + + styles = new_styles; + } + fprintf(dump, "\n"); } gf_isom_sample_del(&s); gf_isom_delete_text_sample(txt); @@ -2705,11 +2911,18 @@ static GF_Err gf_isom_dump_svg_track(GF_ISOFile *the_file, u32 track, FILE *dump GF_BitStream *bs; GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, track); - if (!trak || (trak->Media->handler->handlerType != GF_ISOM_MEDIA_TEXT)) return GF_BAD_PARAM; + if (!trak) return GF_BAD_PARAM; + switch (trak->Media->handler->handlerType) { + case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: + break; + default: + return GF_BAD_PARAM; + } strcpy(nhmlFileName, the_file->fileName); strcat(nhmlFileName, ".nhml"); - nhmlFile = fopen(nhmlFileName, "wt"); + nhmlFile = gf_f64_open(nhmlFileName, "wt"); fprintf(nhmlFile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); fprintf(nhmlFile, "<NHNTStream streamType=\"3\" objectTypeIndication=\"10\" timeScale=\"%d\" baseMediaFile=\"file.svg\" inRootOD=\"yes\">\n", trak->Media->mediaHeader->timeScale); fprintf(nhmlFile, "<NHNTSample isRAP=\"yes\" DTS=\"0\" xmlFrom=\"doc.start\" xmlTo=\"text_1.start\"/>\n"); @@ -2762,7 +2975,7 @@ static GF_Err gf_isom_dump_svg_track(GF_ISOFile *the_file, u32 track, FILE *dump } else { fprintf(nhmlFile, "<NHNTSample isRAP=\"no\" DTS=\"%f\" xmlFrom=\"text_%d.start\" xmlTo=\"text_%d.start\"/>\n", ((s64)start*1.0), cur_frame, cur_frame+1); } - + } fprintf(dump, "</g>\n"); fprintf(dump, "</svg>\n"); @@ -2883,7 +3096,7 @@ GF_Err gf_isom_dump_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, F trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return GF_BAD_PARAM; - + fprintf(trace, "<ISMACrypSampleDescriptions>\n"); count = gf_isom_get_sample_description_count(the_file, trackNumber); @@ -2961,7 +3174,7 @@ static GF_Err apple_tag_dump(GF_Box *a, FILE * trace) case GF_ISOM_BOX_TYPE_0xA9CPY: name = "Copyright"; break; case GF_ISOM_BOX_TYPE_0xA9DES: name = "Description"; break; case GF_ISOM_BOX_TYPE_0xA9GEN: - case GF_ISOM_BOX_TYPE_GNRE: + case GF_ISOM_BOX_TYPE_GNRE: name = "Genre"; break; case GF_ISOM_BOX_TYPE_aART: name = "AlbumArtist"; break; case GF_ISOM_BOX_TYPE_PGAP: name = "Gapeless"; break; @@ -3066,7 +3279,7 @@ GF_Err data_dump(GF_Box *a, FILE * trace) GF_Err ohdr_dump(GF_Box *a, FILE * trace) { GF_OMADRMCommonHeaderBox *ptr = (GF_OMADRMCommonHeaderBox *)a; - fprintf(trace, "<OMADRMCommonHeaderBox EncryptionMethod=\"%d\" PaddingScheme=\"%d\" PlaintextLength=\""LLD"\" ", + fprintf(trace, "<OMADRMCommonHeaderBox EncryptionMethod=\"%d\" PaddingScheme=\"%d\" PlaintextLength=\""LLD"\" ", ptr->EncryptionMethod, ptr->PaddingScheme, ptr->PlaintextLength); if (ptr->RightsIssuerURL) fprintf(trace, "RightsIssuerURL=\"%s\" ", ptr->RightsIssuerURL); if (ptr->ContentID) fprintf(trace, "ContentID=\"%s\" ", ptr->ContentID); @@ -3218,7 +3431,7 @@ GF_Err dimC_dump(GF_Box *a, FILE * trace) { GF_DIMSSceneConfigBox *p = (GF_DIMSSceneConfigBox *)a; - fprintf(trace, "<DIMSSceneConfigBox profile=\"%d\" level=\"%d\" pathComponents=\"%d\" useFullRequestHosts=\"%d\" streamType=\"%d\" containsRedundant=\"%d\" textEncoding=\"%s\" contentEncoding=\"%s\" >\n", + 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"); @@ -3230,7 +3443,7 @@ 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", + 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"); @@ -3243,9 +3456,51 @@ GF_Err ac3_dump(GF_Box *a, FILE * trace) fprintf(trace, "<AC3SampleEntry"); base_audio_entry_dump((GF_AudioSampleEntryBox *)p, trace); fprintf(trace, ">\n"); - gf_box_dump(p->info, trace); DumpBox(a, trace); + gf_box_dump(p->info, trace); fprintf(trace, "</AC3SampleEntry>\n"); return GF_OK; } +GF_Err lsrc_dump(GF_Box *a, FILE * trace) +{ + GF_LASERConfigurationBox *p = (GF_LASERConfigurationBox *)a; + + fprintf(trace, "<LASeRConfigurationBox "); + dump_data(trace, "LASeRHeader", p->hdr, p->hdr_size); + fprintf(trace, ">"); + DumpBox(a, trace); + fprintf(trace, "</LASeRConfigurationBox>"); + 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); + 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"); + return GF_OK; +} + +GF_Err sidx_dump(GF_Box *a, FILE * trace) +{ + u32 i; + GF_SegmentIndexBox *p = (GF_SegmentIndexBox *)a; + fprintf(trace, "<SegmentIndexBox reference_track_ID=\"%d\">\n", p->reference_track_ID); + DumpBox(a, trace); + gf_full_box_dump(a, trace); + + for (i=0; i<p->nb_track_times; i++) { + fprintf(trace, "<TrackTiming trackID=\"%d\" duration=\""LLD"\" />\n", p->tracks_times[i].track_ID, p->tracks_times[i].decoding_time); + } + for (i=0; i<p->nb_refs; i++) { + fprintf(trace, "<Reference type=\"%d\" offset=\"%d\" SubSegmentDuration=\"%d\" hasRAP=\"%d\" RAPDeltaTime=\"%d\"/>\n", p->refs[i].reference_type, p->refs[i].reference_offset, p->refs[i].subsegment_duration, p->refs[i].contains_RAP, p->refs[i].RAP_delta_time); + } + fprintf(trace, "</SegmentIndexBox>\n"); + return GF_OK; +} +#endif /*GPAC_DISABLE_ISOM_DUMP*/ diff --git a/src/isomedia/box_funcs.c b/src/isomedia/box_funcs.c index 711be7f..2ee32fa 100644 --- a/src/isomedia/box_funcs.c +++ b/src/isomedia/box_funcs.c @@ -24,6 +24,8 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + //Add this funct to handle incomplete files... //bytesExpected is 0 most of the time. If the file is incomplete, bytesExpected //is the number of bytes missing to parse the box... @@ -129,6 +131,7 @@ proceed_box: if (size - hdr_size > end ) { newBox->size = size - hdr_size - end; *outBox = newBox; + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[iso file] Incomplete box %s\n", gf_4cc_to_str(newBox->type) )); return GF_ISOM_INCOMPLETE_FILE; } //we need a special reading for these boxes... @@ -230,8 +233,7 @@ GF_Err gf_isom_read_box_list(GF_Box *parent, GF_BitStream *bs, GF_Err (*add_box) return gf_isom_read_box_list_ex(parent, bs, add_box, 0); } -//from here, for write/edit versions -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_box_get_size(GF_Box *ptr) { @@ -320,7 +322,7 @@ GF_Err gf_isom_box_array_size(GF_Box *parent, GF_List *list) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_Box *gf_isom_box_new(u32 boxType) { @@ -387,12 +389,17 @@ GF_Box *gf_isom_box_new(u32 boxType) case GF_ISOM_BOX_TYPE_TREF: return tref_New(); case GF_ISOM_BOX_TYPE_MDIA: return mdia_New(); - case GF_ISOM_BOX_TYPE_FTYP: return ftyp_New(); + case GF_ISOM_BOX_TYPE_FTYP: + case GF_ISOM_BOX_TYPE_STYP: + a = ftyp_New(); + if (a) a->type = boxType; + return a; case GF_ISOM_BOX_TYPE_FADB: 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(); +#ifndef GPAC_DISABLE_ISOM_HINTING case GF_ISOM_BOX_TYPE_RTP_STSD: a = ghnt_New(); if (a) a->type = boxType; @@ -421,8 +428,9 @@ GF_Box *gf_isom_box_new(u32 boxType) case GF_ISOM_BOX_TYPE_DMAX: return dmax_New(); case GF_ISOM_BOX_TYPE_PAYT: return payt_New(); case GF_ISOM_BOX_TYPE_NAME: return name_New(); - -#ifndef GPAC_ISOM_NO_FRAGMENTS +#endif /*GPAC_DISABLE_ISOM_HINTING*/ + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS case GF_ISOM_BOX_TYPE_MVEX: return mvex_New(); case GF_ISOM_BOX_TYPE_MEHD: return mehd_New(); case GF_ISOM_BOX_TYPE_TREX: return trex_New(); @@ -450,14 +458,22 @@ GF_Box *gf_isom_box_new(u32 boxType) return gppc_New(boxType); /*AVC boxes*/ - case GF_ISOM_BOX_TYPE_AVCC: return avcc_New(); + case GF_ISOM_BOX_TYPE_AVCC: + case GF_ISOM_BOX_TYPE_SVCC: + a = avcc_New(); + if (a) a->type = boxType; + return a; + case GF_ISOM_BOX_TYPE_BTRT: return btrt_New(); case GF_ISOM_BOX_TYPE_M4DS: return m4ds_New(); case GF_ISOM_BOX_TYPE_AVC1: return avc1_New(); + case GF_ISOM_BOX_TYPE_AVC2: return avc2_New(); + case GF_ISOM_BOX_TYPE_SVC1: return svc1_New(); /*3GPP streaming text*/ case GF_ISOM_BOX_TYPE_FTAB: return ftab_New(); case GF_ISOM_BOX_TYPE_TX3G: return tx3g_New(); + case GF_ISOM_BOX_TYPE_TEXT: return text_New(); case GF_ISOM_BOX_TYPE_STYL: return styl_New(); case GF_ISOM_BOX_TYPE_HLIT: return hlit_New(); case GF_ISOM_BOX_TYPE_HCLR: return hclr_New(); @@ -543,6 +559,11 @@ GF_Box *gf_isom_box_new(u32 boxType) case GF_ISOM_BOX_TYPE_AC3: return ac3_New(); case GF_ISOM_BOX_TYPE_DAC3: return dac3_New(); + case GF_ISOM_BOX_TYPE_LSRC: return lsrc_New(); + case GF_ISOM_BOX_TYPE_LSR1: return lsr1_New(); + + case GF_ISOM_BOX_TYPE_SIDX: return sidx_New(); + default: a = defa_New(); if (a) a->type = boxType; @@ -616,12 +637,16 @@ void gf_isom_box_del(GF_Box *a) case GF_ISOM_BOX_TYPE_TKHD: tkhd_del(a); return; case GF_ISOM_BOX_TYPE_TREF: tref_del(a); return; case GF_ISOM_BOX_TYPE_MDIA: mdia_del(a); return; - case GF_ISOM_BOX_TYPE_FTYP: ftyp_del(a); return; + case GF_ISOM_BOX_TYPE_FTYP: + 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_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; +#ifndef GPAC_DISABLE_ISOM_HINTING case GF_ISOM_BOX_TYPE_RTP_STSD: ghnt_del(a); return; case GF_ISOM_BOX_TYPE_RTPO: rtpo_del(a); return; case GF_ISOM_BOX_TYPE_HNTI: hnti_del(a); return; @@ -647,8 +672,9 @@ void gf_isom_box_del(GF_Box *a) case GF_ISOM_BOX_TYPE_DMAX: dmax_del(a); return; case GF_ISOM_BOX_TYPE_PAYT: payt_del(a); return; case GF_ISOM_BOX_TYPE_NAME: name_del(a); return; +#endif /*GPAC_DISABLE_ISOM_HINTING*/ -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS case GF_ISOM_BOX_TYPE_MVEX: mvex_del(a); return; case GF_ISOM_BOX_TYPE_MEHD: mehd_del(a); return; case GF_ISOM_BOX_TYPE_TREX: trex_del(a); return; @@ -675,14 +701,20 @@ void gf_isom_box_del(GF_Box *a) gppc_del(a); return; /*AVC boxes*/ - case GF_ISOM_BOX_TYPE_AVCC: avcc_del(a); return; + case GF_ISOM_BOX_TYPE_AVCC: + case GF_ISOM_BOX_TYPE_SVCC: + avcc_del(a); return; case GF_ISOM_BOX_TYPE_BTRT: btrt_del(a); return; case GF_ISOM_BOX_TYPE_M4DS: m4ds_del(a); return; - case GF_ISOM_BOX_TYPE_AVC1: mp4v_del(a); return; + case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: + mp4v_del(a); return; /*3GPP streaming text*/ case GF_ISOM_BOX_TYPE_FTAB: ftab_del(a); return; case GF_ISOM_BOX_TYPE_TX3G: tx3g_del(a); return; + case GF_ISOM_BOX_TYPE_TEXT: text_del(a); return; case GF_ISOM_BOX_TYPE_STYL: styl_del(a); return; case GF_ISOM_BOX_TYPE_HLIT: hlit_del(a); return; case GF_ISOM_BOX_TYPE_HCLR: hclr_del(a); return; @@ -772,6 +804,11 @@ void gf_isom_box_del(GF_Box *a) case GF_ISOM_BOX_TYPE_AC3: ac3_del(a); return; case GF_ISOM_BOX_TYPE_DAC3: dac3_del(a); return; + case GF_ISOM_BOX_TYPE_LSRC: lsrc_del(a); return; + case GF_ISOM_BOX_TYPE_LSR1: lsr1_del(a); return; + + case GF_ISOM_BOX_TYPE_SIDX: sidx_del(a); return; + default: defa_del(a); return; @@ -835,12 +872,15 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_TREF: return tref_Read(a, bs); case GF_ISOM_BOX_TYPE_MDIA: return mdia_Read(a, bs); case GF_ISOM_BOX_TYPE_CHPL: return chpl_Read(a, bs); - case GF_ISOM_BOX_TYPE_FTYP: return ftyp_Read(a, 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_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); +#ifndef GPAC_DISABLE_ISOM_HINTING case GF_ISOM_BOX_TYPE_RTP_STSD: return ghnt_Read(a, bs); case GF_ISOM_BOX_TYPE_RTPO: return rtpo_Read(a, bs); case GF_ISOM_BOX_TYPE_HNTI: return hnti_Read(a, bs); @@ -866,8 +906,9 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_DMAX: return dmax_Read(a, bs); case GF_ISOM_BOX_TYPE_PAYT: return payt_Read(a, bs); case GF_ISOM_BOX_TYPE_NAME: return name_Read(a, bs); +#endif /*GPAC_DISABLE_ISOM_HINTING*/ -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS case GF_ISOM_BOX_TYPE_MVEX: return mvex_Read(a, bs); case GF_ISOM_BOX_TYPE_MEHD: return mehd_Read(a, bs); case GF_ISOM_BOX_TYPE_TREX: return trex_Read(a, bs); @@ -894,13 +935,19 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_D263: return gppc_Read(a, bs); - case GF_ISOM_BOX_TYPE_AVCC: return avcc_Read(a, bs); + case GF_ISOM_BOX_TYPE_AVCC: + case GF_ISOM_BOX_TYPE_SVCC: + return avcc_Read(a, bs); case GF_ISOM_BOX_TYPE_BTRT: return btrt_Read(a, bs); case GF_ISOM_BOX_TYPE_M4DS: return m4ds_Read(a, bs); - case GF_ISOM_BOX_TYPE_AVC1: return mp4v_Read(a, bs); + case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: + return mp4v_Read(a, bs); /*3GPP streaming text*/ case GF_ISOM_BOX_TYPE_FTAB: return ftab_Read(a, bs); + case GF_ISOM_BOX_TYPE_TEXT: return text_Read(a, bs); case GF_ISOM_BOX_TYPE_TX3G: return tx3g_Read(a, bs); case GF_ISOM_BOX_TYPE_STYL: return styl_Read(a, bs); case GF_ISOM_BOX_TYPE_HLIT: return hlit_Read(a, bs); @@ -984,13 +1031,17 @@ GF_Err gf_isom_box_read(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_AC3: return ac3_Read(a, bs); case GF_ISOM_BOX_TYPE_DAC3: return dac3_Read(a, bs); + case GF_ISOM_BOX_TYPE_LSRC: return lsrc_Read(a, bs); + case GF_ISOM_BOX_TYPE_LSR1: return lsr1_Read(a, bs); + + case GF_ISOM_BOX_TYPE_SIDX: return sidx_Read(a, bs); + default: return defa_Read(a, bs); } } -/*from here, for write/edit versions*/ -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs) { @@ -1049,12 +1100,15 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_TKHD: return tkhd_Write(a, bs); case GF_ISOM_BOX_TYPE_TREF: return tref_Write(a, bs); case GF_ISOM_BOX_TYPE_MDIA: return mdia_Write(a, bs); - case GF_ISOM_BOX_TYPE_FTYP: return ftyp_Write(a, 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_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); +#ifndef GPAC_DISABLE_ISOM_HINTING case GF_ISOM_BOX_TYPE_RTP_STSD: return ghnt_Write(a, bs); case GF_ISOM_BOX_TYPE_RTPO: return rtpo_Write(a, bs); case GF_ISOM_BOX_TYPE_HNTI: return hnti_Write(a, bs); @@ -1080,8 +1134,9 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_DMAX: return dmax_Write(a, bs); case GF_ISOM_BOX_TYPE_PAYT: return payt_Write(a, bs); case GF_ISOM_BOX_TYPE_NAME: return name_Write(a, bs); - -#ifndef GPAC_ISOM_NO_FRAGMENTS +#endif /*GPAC_DISABLE_ISOM_HINTING*/ + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS case GF_ISOM_BOX_TYPE_MVEX: return mvex_Write(a, bs); case GF_ISOM_BOX_TYPE_MEHD: return mehd_Write(a, bs); case GF_ISOM_BOX_TYPE_TREX: return trex_Write(a, bs); @@ -1108,14 +1163,20 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_D263: return gppc_Write(a, bs); - case GF_ISOM_BOX_TYPE_AVCC: return avcc_Write(a, bs); + case GF_ISOM_BOX_TYPE_AVCC: + case GF_ISOM_BOX_TYPE_SVCC: + return avcc_Write(a, bs); case GF_ISOM_BOX_TYPE_BTRT: return btrt_Write(a, bs); case GF_ISOM_BOX_TYPE_M4DS: return m4ds_Write(a, bs); - case GF_ISOM_BOX_TYPE_AVC1: return mp4v_Write(a, bs); + case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: + return mp4v_Write(a, bs); /*3GPP streaming text*/ case GF_ISOM_BOX_TYPE_FTAB: return ftab_Write(a, bs); - case GF_ISOM_BOX_TYPE_TX3G: return tx3g_Write(a, bs); + case GF_ISOM_BOX_TYPE_TX3G: return tx3g_Write(a, bs); + case GF_ISOM_BOX_TYPE_TEXT: return text_Write(a, bs); case GF_ISOM_BOX_TYPE_STYL: return styl_Write(a, bs); case GF_ISOM_BOX_TYPE_HLIT: return hlit_Write(a, bs); case GF_ISOM_BOX_TYPE_HCLR: return hclr_Write(a, bs); @@ -1198,6 +1259,11 @@ GF_Err gf_isom_box_write(GF_Box *a, GF_BitStream *bs) case GF_ISOM_BOX_TYPE_AC3: return ac3_Write(a, bs); case GF_ISOM_BOX_TYPE_DAC3: return dac3_Write(a, bs); + case GF_ISOM_BOX_TYPE_LSRC: return lsrc_Write(a, bs); + case GF_ISOM_BOX_TYPE_LSR1: return lsr1_Write(a, bs); + + case GF_ISOM_BOX_TYPE_SIDX: return sidx_Write(a, bs); + default: return defa_Write(a, bs); } @@ -1260,12 +1326,15 @@ GF_Err gf_isom_box_size(GF_Box *a) case GF_ISOM_BOX_TYPE_TKHD: return tkhd_Size(a); case GF_ISOM_BOX_TYPE_TREF: return tref_Size(a); case GF_ISOM_BOX_TYPE_MDIA: return mdia_Size(a); - case GF_ISOM_BOX_TYPE_FTYP: return ftyp_Size(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_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); +#ifndef GPAC_DISABLE_ISOM_HINTING case GF_ISOM_BOX_TYPE_RTP_STSD: return ghnt_Size(a); case GF_ISOM_BOX_TYPE_RTPO: return rtpo_Size(a); case GF_ISOM_BOX_TYPE_HNTI: return hnti_Size(a); @@ -1291,8 +1360,10 @@ GF_Err gf_isom_box_size(GF_Box *a) case GF_ISOM_BOX_TYPE_DMAX: return dmax_Size(a); case GF_ISOM_BOX_TYPE_PAYT: return payt_Size(a); case GF_ISOM_BOX_TYPE_NAME: return name_Size(a); - -#ifndef GPAC_ISOM_NO_FRAGMENTS +#endif /*GPAC_DISABLE_ISOM_HINTING*/ + + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS case GF_ISOM_BOX_TYPE_MVEX: return mvex_Size(a); case GF_ISOM_BOX_TYPE_MEHD: return mehd_Size(a); case GF_ISOM_BOX_TYPE_TREX: return trex_Size(a); @@ -1318,14 +1389,20 @@ GF_Err gf_isom_box_size(GF_Box *a) case GF_ISOM_BOX_TYPE_D263: return gppc_Size(a); - case GF_ISOM_BOX_TYPE_AVCC: return avcc_Size(a); + case GF_ISOM_BOX_TYPE_AVCC: + case GF_ISOM_BOX_TYPE_SVCC: + return avcc_Size(a); case GF_ISOM_BOX_TYPE_BTRT: return btrt_Size(a); case GF_ISOM_BOX_TYPE_M4DS: return m4ds_Size(a); - case GF_ISOM_BOX_TYPE_AVC1: return mp4v_Size(a); + case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: + return mp4v_Size(a); /*3GPP streaming text*/ case GF_ISOM_BOX_TYPE_FTAB: return ftab_Size(a); case GF_ISOM_BOX_TYPE_TX3G: return tx3g_Size(a); + case GF_ISOM_BOX_TYPE_TEXT: return text_Size(a); case GF_ISOM_BOX_TYPE_STYL: return styl_Size(a); case GF_ISOM_BOX_TYPE_HLIT: return hlit_Size(a); case GF_ISOM_BOX_TYPE_HCLR: return hclr_Size(a); @@ -1408,9 +1485,15 @@ GF_Err gf_isom_box_size(GF_Box *a) case GF_ISOM_BOX_TYPE_AC3: return ac3_Size(a); case GF_ISOM_BOX_TYPE_DAC3: return dac3_Size(a); + case GF_ISOM_BOX_TYPE_LSRC: return lsrc_Size(a); + case GF_ISOM_BOX_TYPE_LSR1: return lsr1_Size(a); + + case GF_ISOM_BOX_TYPE_SIDX: return sidx_Size(a); + default: return defa_Size(a); } } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/data_map.c b/src/isomedia/data_map.c index 04433f6..5f981d9 100644 --- a/src/isomedia/data_map.c +++ b/src/isomedia/data_map.c @@ -25,6 +25,8 @@ #include <gpac/internal/isomedia_dev.h> #include <gpac/network.h> +#ifndef GPAC_DISABLE_ISOM + void gf_isom_datamap_del(GF_DataMap *ptr) { if (!ptr) return; @@ -105,7 +107,7 @@ GF_Err gf_isom_datamap_new(const char *location, const char *parentPath, u8 mode } //we need a temp file ... if (!strcmp(location, "mp4_tmp_edit")) { -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE *outDataMap = gf_isom_fdm_new_temp(parentPath); if (! (*outDataMap)) return GF_IO_ERR; return GF_OK; @@ -146,7 +148,7 @@ GF_Err gf_isom_datamap_new(const char *location, const char *parentPath, u8 mode *outDataMap = gf_isom_fdm_new(sPath, mode); } - free(sPath); + gf_free(sPath); if (! (*outDataMap)) return GF_URL_ERROR; return GF_OK; } @@ -196,7 +198,7 @@ GF_Err gf_isom_datamap_open(GF_MediaBox *mdia, u32 dataRefIndex, u8 Edit) if (mdia->mediaTrack->moov->mov->movieFileMap == NULL) return GF_ISOM_INVALID_FILE; minf->dataHandler = mdia->mediaTrack->moov->mov->movieFileMap; } else { -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE if (mdia->mediaTrack->moov->mov->editFileMap == NULL) return GF_ISOM_INVALID_FILE; minf->dataHandler = mdia->mediaTrack->moov->mov->editFileMap; #else @@ -232,7 +234,7 @@ u32 gf_isom_datamap_get_data(GF_DataMap *map, char *buffer, u32 bufferLength, u6 } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE u64 FDM_GetTotalOffset(GF_FileDataMap *ptr); GF_Err FDM_AddData(GF_FileDataMap *ptr, char *data, u32 dataSize); @@ -263,13 +265,9 @@ GF_Err gf_isom_datamap_add_data(GF_DataMap *ptr, char *data, u32 dataSize) } } -#endif - - -#ifndef GPAC_READ_ONLY GF_DataMap *gf_isom_fdm_new_temp(const char *sPath) { - GF_FileDataMap *tmp = (GF_FileDataMap *) malloc(sizeof(GF_FileDataMap)); + GF_FileDataMap *tmp = (GF_FileDataMap *) gf_malloc(sizeof(GF_FileDataMap)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_FileDataMap)); tmp->type = GF_ISOM_DATA_FILE; @@ -280,40 +278,40 @@ GF_DataMap *gf_isom_fdm_new_temp(const char *sPath) } else { char szPath[GF_MAX_PATH]; if ((sPath[strlen(sPath)-1] != '\\') && (sPath[strlen(sPath)-1] != '/')) { - sprintf(szPath, "%s%c%d_isotmp", sPath, GF_PATH_SEPARATOR, (u32) tmp); + sprintf(szPath, "%s%c%d_isotmp", sPath, GF_PATH_SEPARATOR, (u32) (u64) tmp); } else { - sprintf(szPath, "%s%d_isotmp", sPath, (u32) tmp); + sprintf(szPath, "%s%d_isotmp", sPath, (u32) (u64) tmp); } tmp->stream = gf_f64_open(szPath, "w+b"); - tmp->temp_file = strdup(szPath); + tmp->temp_file = gf_strdup(szPath); } if (!tmp->stream) { - if (tmp->temp_file) free(tmp->temp_file); - free(tmp); + if (tmp->temp_file) gf_free(tmp->temp_file); + gf_free(tmp); return NULL; } tmp->bs = gf_bs_from_file(tmp->stream, GF_BITSTREAM_READ); if (!tmp->bs) { fclose(tmp->stream); - free(tmp); + gf_free(tmp); return NULL; } return (GF_DataMap *)tmp; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_DataMap *gf_isom_fdm_new(const char *sPath, u8 mode) { u8 bs_mode; - GF_FileDataMap *tmp = (GF_FileDataMap *) malloc(sizeof(GF_FileDataMap)); + GF_FileDataMap *tmp = (GF_FileDataMap *) gf_malloc(sizeof(GF_FileDataMap)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_FileDataMap)); tmp->type = GF_ISOM_DATA_FILE; tmp->mode = mode; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE //open a temp file if (!strcmp(sPath, "mp4_tmp_edit")) { //create a temp file (that only occurs in EDIT/WRITE mode) @@ -334,17 +332,17 @@ GF_DataMap *gf_isom_fdm_new(const char *sPath, u8 mode) bs_mode = GF_BITSTREAM_WRITE; break; default: - free(tmp); + gf_free(tmp); return NULL; } if (!tmp->stream) { - free(tmp); + gf_free(tmp); return NULL; } tmp->bs = gf_bs_from_file(tmp->stream, bs_mode); if (!tmp->bs) { fclose(tmp->stream); - free(tmp); + gf_free(tmp); return NULL; } return (GF_DataMap *)tmp; @@ -356,13 +354,13 @@ void gf_isom_fdm_del(GF_FileDataMap *ptr) if (ptr->bs) gf_bs_del(ptr->bs); if (ptr->stream) fclose(ptr->stream); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE if (ptr->temp_file) { gf_delete_file(ptr->temp_file); - free(ptr->temp_file); + gf_free(ptr->temp_file); } #endif - free(ptr); + gf_free(ptr); } @@ -397,7 +395,7 @@ u32 gf_isom_fdm_get_data(GF_FileDataMap *ptr, char *buffer, u32 bufferLength, u6 -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE u64 FDM_GetTotalOffset(GF_FileDataMap *ptr) @@ -438,7 +436,7 @@ GF_Err FDM_AddData(GF_FileDataMap *ptr, char *data, u32 dataSize) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ #ifdef WIN32 @@ -458,12 +456,12 @@ GF_DataMap *gf_isom_fmo_new(const char *sPath, u8 mode) //only in read only if (mode != GF_ISOM_DATA_MAP_READ) return NULL; - tmp = (GF_FileMappingDataMap *) malloc(sizeof(GF_FileMappingDataMap)); + tmp = (GF_FileMappingDataMap *) gf_malloc(sizeof(GF_FileMappingDataMap)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_FileMappingDataMap)); tmp->type = GF_ISOM_DATA_FILE_MAPPING; tmp->mode = mode; - tmp->name = _strdup(sPath); + tmp->name = gf_strdup(sPath); // // Open the file @@ -481,16 +479,16 @@ GF_DataMap *gf_isom_fmo_new(const char *sPath, u8 mode) if (fileH == INVALID_HANDLE_VALUE) { - free(tmp->name); - free(tmp); + gf_free(tmp->name); + gf_free(tmp); return NULL; } tmp->file_size = GetFileSize(fileH, NULL); if (tmp->file_size == 0xFFFFFFFF) { CloseHandle(fileH); - free(tmp->name); - free(tmp); + gf_free(tmp->name); + gf_free(tmp); return NULL; } @@ -500,8 +498,8 @@ GF_DataMap *gf_isom_fmo_new(const char *sPath, u8 mode) fileMapH = CreateFileMapping(fileH, NULL, PAGE_READONLY, 0, 0, NULL); if (fileMapH == NULL) { CloseHandle(fileH); - free(tmp->name); - free(tmp); + gf_free(tmp->name); + gf_free(tmp); err = GetLastError(); return NULL; } @@ -510,8 +508,8 @@ GF_DataMap *gf_isom_fmo_new(const char *sPath, u8 mode) if (tmp->byte_map == NULL) { CloseHandle(fileMapH); CloseHandle(fileH); - free(tmp->name); - free(tmp); + gf_free(tmp->name); + gf_free(tmp); return NULL; } @@ -529,8 +527,8 @@ void gf_isom_fmo_del(GF_FileMappingDataMap *ptr) if (ptr->bs) gf_bs_del(ptr->bs); if (ptr->byte_map) UnmapViewOfFile(ptr->byte_map); - free(ptr->name); - free(ptr); + gf_free(ptr->name); + gf_free(ptr); } @@ -558,5 +556,6 @@ u32 gf_isom_fmo_get_data(GF_FileMappingDataMap *ptr, char *buffer, u32 bufferLen #endif +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/hint_track.c b/src/isomedia/hint_track.c index 6266b2c..3ce477d 100644 --- a/src/isomedia/hint_track.c +++ b/src/isomedia/hint_track.c @@ -24,6 +24,8 @@ #include <gpac/internal/isomedia_dev.h> +#if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_HINTING) + Bool IsHintTrack(GF_TrackBox *trak) { if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_HINT) return 0; @@ -52,7 +54,7 @@ Bool CheckHintFormat(GF_TrackBox *trak, u32 HintType) return 1; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err AdjustHintInfo(GF_HintSampleEntryBox *entry, u32 HintSampleNumber) { @@ -493,7 +495,7 @@ GF_Err gf_isom_hint_sample_data(GF_ISOFile *the_file, u32 trackNumber, u32 Sourc if (!SampleNumber || (SampleNumber == trak->Media->information->sampleTable->SampleSize->sampleCount + 1)) { //we adding some stuff in the current sample ... dte->byteOffset += entry->hint_sample->dataLength; - entry->hint_sample->AdditionalData = (char*)realloc(entry->hint_sample->AdditionalData, sizeof(char) * (entry->hint_sample->dataLength + DataLength)); + entry->hint_sample->AdditionalData = (char*)gf_realloc(entry->hint_sample->AdditionalData, sizeof(char) * (entry->hint_sample->dataLength + DataLength)); if (AtBegin) { if (entry->hint_sample->dataLength) memmove(entry->hint_sample->AdditionalData + DataLength, entry->hint_sample->AdditionalData, entry->hint_sample->dataLength); @@ -551,9 +553,6 @@ GF_Err gf_isom_hint_sample_description_data(GF_ISOFile *the_file, u32 trackNumbe return gf_isom_hint_pck_add_dte(entry->hint_sample->HintType, pck, (GF_GenericDTE *)dte, AtBegin); } -#endif //GPAC_READ_ONLY - -#ifndef GPAC_READ_ONLY GF_Err gf_isom_rtp_packet_set_flags(GF_ISOFile *the_file, u32 trackNumber, u8 PackingBit, @@ -691,12 +690,12 @@ static void ReorderSDP(char *sdp_text, Bool is_movie_sdp) assert(st); st += 2; if (!st[0]) { - AddSDPLine(lines, strdup(cur), is_movie_sdp); + AddSDPLine(lines, gf_strdup(cur), is_movie_sdp); break; } b = st[0]; st[0] = 0; - AddSDPLine(lines, strdup(cur), is_movie_sdp); + AddSDPLine(lines, gf_strdup(cur), is_movie_sdp); st[0] = b; cur = st; } @@ -705,7 +704,7 @@ static void ReorderSDP(char *sdp_text, Bool is_movie_sdp) char *cur = (char *)gf_list_get(lines, 0); gf_list_rem(lines, 0); strcat(sdp_text, cur); - free(cur); + gf_free(cur); } gf_list_del(lines); } @@ -740,16 +739,16 @@ GF_Err gf_isom_sdp_add_track_line(GF_ISOFile *the_file, u32 trackNumber, const c sdp = (GF_SDPBox *) hnti->SDP; if (!sdp->sdpText) { - sdp->sdpText = (char *)malloc(sizeof(char) * (strlen(text) + 3)); + sdp->sdpText = (char *)gf_malloc(sizeof(char) * (strlen(text) + 3)); strcpy(sdp->sdpText, text); strcat(sdp->sdpText, "\r\n"); return GF_OK; } - buf = (char *)malloc(sizeof(char) * (strlen(sdp->sdpText) + strlen(text) + 3)); + buf = (char *)gf_malloc(sizeof(char) * (strlen(sdp->sdpText) + strlen(text) + 3)); strcpy(buf, sdp->sdpText); strcat(buf, text); strcat(buf, "\r\n"); - free(sdp->sdpText); + gf_free(sdp->sdpText); ReorderSDP(buf, 0); sdp->sdpText = buf; return GF_OK; @@ -777,7 +776,7 @@ GF_Err gf_isom_sdp_clean_track(GF_ISOFile *the_file, u32 trackNumber) hnti = (GF_HintTrackInfoBox *)gf_list_get(map->boxList, 0); if (!hnti->SDP) return GF_OK; //and free the SDP - free(((GF_SDPBox *)hnti->SDP)->sdpText); + gf_free(((GF_SDPBox *)hnti->SDP)->sdpText); ((GF_SDPBox *)hnti->SDP)->sdpText = NULL; return GF_OK; } @@ -820,7 +819,7 @@ GF_Err gf_isom_sdp_add_line(GF_ISOFile *movie, const char *text) if (!hnti->SDP) { //we have to create it by hand, as we have a duplication of box type //(GF_RTPSampleEntryBox and GF_RTPBox have the same type...) - rtp = (GF_RTPBox *) malloc(sizeof(GF_RTPBox)); + rtp = (GF_RTPBox *) gf_malloc(sizeof(GF_RTPBox)); rtp->subType = GF_ISOM_BOX_TYPE_SDP; rtp->type = GF_ISOM_BOX_TYPE_RTP; rtp->sdpText = NULL; @@ -829,16 +828,16 @@ GF_Err gf_isom_sdp_add_line(GF_ISOFile *movie, const char *text) rtp = (GF_RTPBox *) hnti->SDP; if (!rtp->sdpText) { - rtp->sdpText = (char*)malloc(sizeof(char) * (strlen(text) + 3)); + rtp->sdpText = (char*)gf_malloc(sizeof(char) * (strlen(text) + 3)); strcpy(rtp->sdpText, text); strcat(rtp->sdpText, "\r\n"); return GF_OK; } - buf = (char*)malloc(sizeof(char) * (strlen(rtp->sdpText) + strlen(text) + 3)); + buf = (char*)gf_malloc(sizeof(char) * (strlen(rtp->sdpText) + strlen(text) + 3)); strcpy(buf, rtp->sdpText); strcat(buf, text); strcat(buf, "\r\n"); - free(rtp->sdpText); + gf_free(rtp->sdpText); ReorderSDP(buf, 1); rtp->sdpText = buf; return GF_OK; @@ -868,7 +867,7 @@ GF_Err gf_isom_sdp_clean(GF_ISOFile *movie) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_EXPORT GF_Err gf_isom_sdp_get(GF_ISOFile *movie, const char **sdp, u32 *length) @@ -987,3 +986,5 @@ const char *gf_isom_get_payt_info(GF_ISOFile *the_file, u32 trackNumber, u32 ind return NULL; } +#endif /*!defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_HINTING)*/ + diff --git a/src/isomedia/hinting.c b/src/isomedia/hinting.c index 2b88ea0..6106f53 100644 --- a/src/isomedia/hinting.c +++ b/src/isomedia/hinting.c @@ -24,15 +24,16 @@ #include <gpac/internal/isomedia_dev.h> +#if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_HINTING) GF_Box *ghnt_New() { - GF_HintSampleEntryBox *tmp = (GF_HintSampleEntryBox *) malloc(sizeof(GF_HintSampleEntryBox)); + GF_HintSampleEntryBox *tmp = (GF_HintSampleEntryBox *) gf_malloc(sizeof(GF_HintSampleEntryBox)); if (tmp == NULL) return NULL; memset(tmp, 0, sizeof(GF_HintSampleEntryBox)); tmp->HintDataTable = gf_list_new(); if (!tmp->HintDataTable) { - free(tmp); + gf_free(tmp); return NULL; } //this type is used internally for protocols that share the same base entry @@ -50,7 +51,7 @@ void ghnt_del(GF_Box *s) ptr = (GF_HintSampleEntryBox *)s; gf_isom_box_array_del(ptr->HintDataTable); if (ptr->hint_sample) gf_isom_hint_sample_del(ptr->hint_sample); - free(ptr); + gf_free(ptr); } GF_Err ghnt_Read(GF_Box *s, GF_BitStream *bs) @@ -79,7 +80,7 @@ GF_Err ghnt_Read(GF_Box *s, GF_BitStream *bs) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err ghnt_Write(GF_Box *s, GF_BitStream *bs) { @@ -110,7 +111,7 @@ GF_Err ghnt_Size(GF_Box *s) } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_HintSample *gf_isom_hint_sample_new(u32 ProtocolType) @@ -141,18 +142,18 @@ void gf_isom_hint_sample_del(GF_HintSample *ptr) gf_list_rem(ptr->packetTable, 0); } gf_list_del(ptr->packetTable); - if (ptr->AdditionalData) free(ptr->AdditionalData); + if (ptr->AdditionalData) gf_free(ptr->AdditionalData); if (ptr->sample_cache) { while (gf_list_count(ptr->sample_cache)) { GF_HintDataCache *hdc = (GF_HintDataCache *)gf_list_get(ptr->sample_cache, 0); gf_list_rem(ptr->sample_cache, 0); if (hdc->samp) gf_isom_sample_del(&hdc->samp); - free(hdc); + gf_free(hdc); } gf_list_del(ptr->sample_cache); } - free(ptr); + gf_free(ptr); } GF_Err gf_isom_hint_sample_read(GF_HintSample *ptr, GF_BitStream *bs, u32 sampleSize) @@ -179,14 +180,14 @@ GF_Err gf_isom_hint_sample_read(GF_HintSample *ptr, GF_BitStream *bs, u32 sample //do we have some more data after the packets ?? if ((u32)sizeOut < sampleSize) { ptr->dataLength = sampleSize - (u32)sizeOut; - ptr->AdditionalData = (char*)malloc(sizeof(char) * ptr->dataLength); + ptr->AdditionalData = (char*)gf_malloc(sizeof(char) * ptr->dataLength); gf_bs_read_data(bs, ptr->AdditionalData, ptr->dataLength); } return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_hint_sample_write(GF_HintSample *ptr, GF_BitStream *bs) { @@ -226,7 +227,7 @@ u32 gf_isom_hint_sample_size(GF_HintSample *ptr) return size; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -261,7 +262,7 @@ GF_Err gf_isom_hint_pck_read(u8 HintType, GF_HintPacket *ptr, GF_BitStream *bs) } } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_hint_pck_write(u8 HintType, GF_HintPacket *ptr, GF_BitStream *bs) { @@ -318,7 +319,7 @@ u32 gf_isom_hint_pck_length(u8 HintType, GF_HintPacket *ptr) } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -328,14 +329,14 @@ u32 gf_isom_hint_pck_length(u8 HintType, GF_HintPacket *ptr) GF_GenericDTE *New_EmptyDTE() { - GF_EmptyDTE *dte = (GF_EmptyDTE *)malloc(sizeof(GF_EmptyDTE)); + GF_EmptyDTE *dte = (GF_EmptyDTE *)gf_malloc(sizeof(GF_EmptyDTE)); dte->source = 0; return (GF_GenericDTE *)dte; } GF_GenericDTE *New_ImmediateDTE() { - GF_ImmediateDTE *dte = (GF_ImmediateDTE *)malloc(sizeof(GF_ImmediateDTE)); + GF_ImmediateDTE *dte = (GF_ImmediateDTE *)gf_malloc(sizeof(GF_ImmediateDTE)); dte->source = 1; memset(dte->data, 0, 14); dte->dataLength = 0; @@ -344,7 +345,7 @@ GF_GenericDTE *New_ImmediateDTE() GF_GenericDTE *New_SampleDTE() { - GF_SampleDTE *dte = (GF_SampleDTE *)malloc(sizeof(GF_SampleDTE)); + GF_SampleDTE *dte = (GF_SampleDTE *)gf_malloc(sizeof(GF_SampleDTE)); dte->source = 2; //can be -1 in QT , so init at -2 dte->trackRefIndex = (s8) -2; @@ -358,7 +359,7 @@ GF_GenericDTE *New_SampleDTE() GF_GenericDTE *New_StreamDescDTE() { - GF_StreamDescDTE *dte = (GF_StreamDescDTE *)malloc(sizeof(GF_StreamDescDTE)); + GF_StreamDescDTE *dte = (GF_StreamDescDTE *)gf_malloc(sizeof(GF_StreamDescDTE)); dte->source = 3; dte->byteOffset = 0; dte->dataLength = 0; @@ -390,16 +391,16 @@ GF_GenericDTE *NewDTE(u8 type) Deletion of DataTable entries in the RTP sample ********************************************************************/ void Del_EmptyDTE(GF_EmptyDTE *dte) -{ free(dte); } +{ gf_free(dte); } void Del_ImmediateDTE(GF_ImmediateDTE *dte) -{ free(dte); } +{ gf_free(dte); } void Del_SampleDTE(GF_SampleDTE *dte) -{ free(dte); } +{ gf_free(dte); } void Del_StreamDescDTE(GF_StreamDescDTE *dte) -{ free(dte); } +{ gf_free(dte); } //deletion of DTEs void DelDTE(GF_GenericDTE *dte) @@ -569,7 +570,7 @@ GF_Err OffsetDTE(GF_GenericDTE *dte, u32 offset, u32 HintSampleNumber) GF_RTPPacket *gf_isom_hint_rtp_new() { - GF_RTPPacket *tmp = (GF_RTPPacket *)malloc(sizeof(GF_RTPPacket)); + GF_RTPPacket *tmp = (GF_RTPPacket *)gf_malloc(sizeof(GF_RTPPacket)); tmp->TLV = gf_list_new(); tmp->DataTable = gf_list_new(); tmp->B_bit = tmp->M_bit = tmp->P_bit = tmp->payloadType = tmp->payloadType = tmp->R_bit = tmp->X_bit = 0; @@ -590,7 +591,7 @@ void gf_isom_hint_rtp_del(GF_RTPPacket *ptr) gf_list_del(ptr->DataTable); //the TLV gf_isom_box_array_del(ptr->TLV); - free(ptr); + gf_free(ptr); } GF_Err gf_isom_hint_rtp_read(GF_RTPPacket *ptr, GF_BitStream *bs) @@ -706,7 +707,7 @@ u32 gf_isom_hint_rtp_length(GF_RTPPacket *ptr) } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE u32 gf_isom_hint_rtp_size(GF_RTPPacket *ptr) { @@ -775,7 +776,7 @@ GF_Err gf_isom_hint_rtp_write(GF_RTPPacket *ptr, GF_BitStream *bs) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_EXPORT GF_Err gf_isom_reset_hint_reader(GF_ISOFile *the_file, u32 trackNumber, u32 sample_start, u32 ts_offset, u32 sn_offset, u32 ssrc) @@ -980,3 +981,5 @@ GF_Err gf_isom_next_hint_packet(GF_ISOFile *the_file, u32 trackNumber, char **pc } return GF_OK; } + +#endif /* !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_HINTING)*/ diff --git a/src/isomedia/isma_sample.c b/src/isomedia/isma_sample.c index ef7c0f0..af64dd5 100644 --- a/src/isomedia/isma_sample.c +++ b/src/isomedia/isma_sample.c @@ -24,9 +24,11 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + GF_ISMASample *gf_isom_ismacryp_new_sample() { - GF_ISMASample *tmp = (GF_ISMASample *) malloc(sizeof(GF_ISMASample)); + GF_ISMASample *tmp = (GF_ISMASample *) gf_malloc(sizeof(GF_ISMASample)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_ISMASample)); return tmp; @@ -35,9 +37,9 @@ GF_EXPORT void gf_isom_ismacryp_delete_sample(GF_ISMASample *samp) { if (!samp) return; - if (samp->data && samp->dataLength) free(samp->data); - if (samp->key_indicator) free(samp->key_indicator); - free(samp); + if (samp->data && samp->dataLength) gf_free(samp->data); + if (samp->key_indicator) gf_free(samp->key_indicator); + gf_free(samp); } @@ -78,12 +80,12 @@ GF_ISMASample *gf_isom_ismacryp_sample_from_data(char *data, u32 dataLength, Boo } if (KI_length) { if (s->dataLength < KI_length) goto exit; - s->key_indicator = (u8 *)malloc(KI_length); + 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*)malloc(sizeof(char)*s->dataLength); + s->data = (char*)gf_malloc(sizeof(char)*s->dataLength); gf_bs_read_data(bs, s->data, s->dataLength); gf_bs_del(bs); return s; @@ -109,7 +111,7 @@ GF_Err gf_isom_ismacryp_sample_to_sample(GF_ISMASample *s, GF_ISOSample *dest) 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) free(dest->data); + if (dest->data) gf_free(dest->data); dest->data = NULL; dest->dataLength = 0; gf_bs_get_content(bs, &dest->data, &dest->dataLength); @@ -305,7 +307,7 @@ GF_Err gf_isom_get_omadrm_info(GF_ISOFile *the_file, u32 trackNumber, u32 sample return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_remove_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex) { @@ -349,12 +351,12 @@ GF_Err gf_isom_change_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, if (!sea->protection_info->scheme_type || !sea->protection_info->original_format) return GF_NON_COMPLIANT_BITSTREAM; if (scheme_uri) { - free(sea->protection_info->scheme_type->URI); - sea->protection_info->scheme_type->URI = strdup(scheme_uri); + gf_free(sea->protection_info->scheme_type->URI); + sea->protection_info->scheme_type->URI = gf_strdup(scheme_uri); } if (kms_uri) { - free(sea->protection_info->info->ikms->URI); - sea->protection_info->info->ikms->URI = strdup(kms_uri); + gf_free(sea->protection_info->info->ikms->URI); + sea->protection_info->info->ikms->URI = gf_strdup(kms_uri); } return GF_OK; } @@ -380,6 +382,7 @@ GF_Err gf_isom_set_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u3 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; @@ -390,10 +393,13 @@ GF_Err gf_isom_set_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u3 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; @@ -407,14 +413,14 @@ GF_Err gf_isom_set_ismacryp_protection(GF_ISOFile *the_file, u32 trackNumber, u3 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 = strdup(scheme_uri); + 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 = strdup(kms_URI); + 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; @@ -448,11 +454,14 @@ GF_Err gf_isom_set_oma_protection(GF_ISOFile *the_file, u32 trackNumber, u32 des 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; @@ -479,14 +488,17 @@ GF_Err gf_isom_set_oma_protection(GF_ISOFile *the_file, u32 trackNumber, u32 des 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 = strdup(contentID); - if (kms_URI) sea->protection_info->info->okms->hdr->RightsIssuerURL = strdup(kms_URI); + 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 = malloc(sizeof(char)*textual_headers_len); + 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 +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/isom_intern.c b/src/isomedia/isom_intern.c index 23bae52..bde581d 100644 --- a/src/isomedia/isom_intern.c +++ b/src/isomedia/isom_intern.c @@ -25,12 +25,14 @@ #include <gpac/internal/isomedia_dev.h> #include <gpac/network.h> +#ifndef GPAC_DISABLE_ISOM + /************************************************************** Some Local functions for movie creation **************************************************************/ GF_Err gf_isom_parse_root_box(GF_Box **outBox, GF_BitStream *bs, u64 *bytesExpected); -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov) { @@ -46,7 +48,7 @@ GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov) //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 + 1 != moof->mfhd->sequence_number) return GF_ISOM_INVALID_FILE; + if (mov->NextMoofNumber && (mov->NextMoofNumber >= moof->mfhd->sequence_number)) return GF_ISOM_INVALID_FILE; i=0; while ((traf = (GF_TrackFragmentBox*)gf_list_enum(moof->TrackList, &i))) { @@ -73,7 +75,7 @@ GF_Err MergeFragment(GF_MovieFragmentBox *moof, GF_ISOFile *mov) MaxDur = trak->Header->duration; } - mov->NextMoofNumber += 1; + mov->NextMoofNumber = moof->mfhd->sequence_number; //update movie duration if (mov->moov->mvhd->duration < MaxDur) mov->moov->mvhd->duration = MaxDur; return GF_OK; @@ -91,8 +93,8 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) totSize = 0; -#ifndef GPAC_ISOM_NO_FRAGMENTS - /*restart from where we stoped last*/ +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + /*restart from where we stopped last*/ totSize = mov->current_top_box_start; gf_bs_seek(mov->movieFileMap->bs, mov->current_top_box_start); #endif @@ -101,7 +103,7 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) /*while we have some data, parse our boxes*/ while (gf_bs_available(mov->movieFileMap->bs)) { *bytesMissing = 0; -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS mov->current_top_box_start = gf_bs_get_position(mov->movieFileMap->bs); #endif @@ -126,7 +128,10 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) mov->moov = (GF_MovieBox *)a; /*set our pointer to the movie*/ mov->moov->mov = mov; - e = gf_list_add(mov->TopBoxes, a); +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + if (mov->moov->mvex) mov->moov->mvex->mov = mov; +#endif + e = gf_list_add(mov->TopBoxes, a); if (e) return e; totSize += a->size; break; @@ -149,7 +154,7 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) e = gf_list_add(mov->TopBoxes, mov->mdat); if (e) return e; } -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS else if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) gf_list_add(mov->TopBoxes, a); #endif else gf_isom_box_del(a); @@ -189,14 +194,25 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) break; -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + case GF_ISOM_BOX_TYPE_STYP: + case GF_ISOM_BOX_TYPE_SIDX: + totSize += a->size; + if (mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) { + e = gf_list_add(mov->TopBoxes, a); + } else { + gf_isom_box_del(a); + } + break; + case GF_ISOM_BOX_TYPE_MOOF: ((GF_MovieFragmentBox *)a)->mov = mov; totSize += a->size; + 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); + gf_list_add(mov->TopBoxes, a); } else { /*merge all info*/ e = MergeFragment((GF_MovieFragmentBox *)a, mov); @@ -221,32 +237,40 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) e = gf_list_add(mov->TopBoxes, a); break; } + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + mov->current_top_box_start = gf_bs_get_position(mov->movieFileMap->bs); +#endif } /*we need at least moov or meta*/ - if (!mov->moov && !mov->meta) return GF_ISOM_INVALID_FILE; + if (!mov->moov && !mov->meta +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + && !mov->moof +#endif + ) return GF_ISOM_INVALID_FILE; /*we MUST have movie header*/ if (mov->moov && !mov->moov->mvhd) return GF_ISOM_INVALID_FILE; /*we MUST have meta handler*/ if (mov->meta && !mov->meta->handler) return GF_ISOM_INVALID_FILE; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE if (mov->moov) { /*set the default interleaving time*/ mov->interleavingTime = mov->moov->mvhd->timeScale; -#ifndef GPAC_ISOM_NO_FRAGMENTS - /*not in open mode and successfully loaded the entire file, destroy all fragment - FIXME: we may need to keet it when trying http streaming of fragments...*/ - if (!(mov->FragmentsFlags & GF_ISOM_FRAG_READ_DEBUG) && mov->moov->mvex) { +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + /*in edit mode with successfully loaded fragments, delete all fragment signaling since + file is no longer fragmented*/ + if ((mov->openMode > GF_ISOM_OPEN_READ) && mov->moov->mvex) { gf_isom_box_del((GF_Box *)mov->moov->mvex); mov->moov->mvex = NULL; } #endif } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ return GF_OK; } @@ -254,7 +278,7 @@ GF_Err gf_isom_parse_movie_boxes(GF_ISOFile *mov, u64 *bytesMissing) GF_ISOFile *gf_isom_new_movie() { - GF_ISOFile *mov = (GF_ISOFile*)malloc(sizeof(GF_ISOFile)); + GF_ISOFile *mov = (GF_ISOFile*)gf_malloc(sizeof(GF_ISOFile)); if (mov == NULL) { gf_isom_set_last_error(NULL, GF_OUT_OF_MEM); return NULL; @@ -265,7 +289,7 @@ GF_ISOFile *gf_isom_new_movie() mov->TopBoxes = gf_list_new(); if (!mov->TopBoxes) { gf_isom_set_last_error(NULL, GF_OUT_OF_MEM); - free(mov); + gf_free(mov); return NULL; } @@ -282,7 +306,7 @@ GF_ISOFile *gf_isom_open_file(const char *fileName, u32 OpenMode, const char *tm GF_ISOFile *mov = gf_isom_new_movie(); if (! mov) return NULL; - mov->fileName = strdup(fileName); + mov->fileName = gf_strdup(fileName); mov->openMode = OpenMode; if ( (OpenMode == GF_ISOM_OPEN_READ) || (OpenMode == GF_ISOM_OPEN_READ_DUMP) ) { @@ -302,13 +326,13 @@ GF_ISOFile *gf_isom_open_file(const char *fileName, u32 OpenMode, const char *tm return NULL; } -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS if (OpenMode == GF_ISOM_OPEN_READ_DUMP) mov->FragmentsFlags |= GF_ISOM_FRAG_READ_DEBUG; #endif } else { -#ifdef GPAC_READ_ONLY +#ifdef GPAC_DISABLE_ISOM_WRITE //not allowed for READ_ONLY lib gf_isom_delete_movie(mov); gf_isom_set_last_error(NULL, GF_ISOM_INVALID_MODE); @@ -317,7 +341,7 @@ GF_ISOFile *gf_isom_open_file(const char *fileName, u32 OpenMode, const char *tm #else //set a default output name for edited file - mov->finalName = (char*)malloc(strlen(fileName) + 5); + mov->finalName = (char*)gf_malloc(strlen(fileName) + 5); if (!mov->finalName) { gf_isom_set_last_error(NULL, GF_OUT_OF_MEM); gf_isom_delete_movie(mov); @@ -372,17 +396,19 @@ void gf_isom_delete_movie(GF_ISOFile *mov) //these are our two main files if (mov->movieFileMap) gf_isom_datamap_del(mov->movieFileMap); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE if (mov->editFileMap) { gf_isom_datamap_del(mov->editFileMap); } - if (mov->finalName) free(mov->finalName); + if (mov->finalName) gf_free(mov->finalName); #endif gf_isom_box_array_del(mov->TopBoxes); + gf_isom_box_array_del(mov->moof_list); - if (mov->fileName) free(mov->fileName); - free(mov); + + if (mov->fileName) gf_free(mov->fileName); + gf_free(mov); } GF_TrackBox *gf_isom_get_track_from_id(GF_MovieBox *moov, u32 trackID) @@ -412,14 +438,16 @@ GF_TrackBox *gf_isom_get_track_from_file(GF_ISOFile *movie, u32 trackNumber) //WARNING: MOVIETIME IS EXPRESSED IN MEDIA TS GF_Err GetMediaTime(GF_TrackBox *trak, u64 movieTime, u64 *MediaTime, s64 *SegmentStartTime, s64 *MediaOffset, u8 *useEdit) { +#if 0 GF_Err e; + u32 sampleNumber, prevSampleNumber; + u64 firstDTS; +#endif u32 i; u64 time, lastSampleTime, m_time; s64 mtime; GF_EdtsEntry *ent; Double scale_ts; - u32 sampleNumber, prevSampleNumber; - u64 firstDTS; GF_SampleTableBox *stbl = trak->Media->information->sampleTable; *useEdit = 1; @@ -449,7 +477,7 @@ GF_Err GetMediaTime(GF_TrackBox *trak, u64 movieTime, u64 *MediaTime, s64 *Segme //browse the edit list and get the time scale_ts = trak->moov->mvhd->timeScale; scale_ts /= trak->Media->mediaHeader->timeScale; - scale_ts *= ((s64)movieTime + 1); + scale_ts *= ((s64)movieTime ); m_time = (u64) (scale_ts); time = 0; @@ -496,6 +524,7 @@ ent_found: mtime = ent->mediaTime + movieTime - (time * trak->Media->mediaHeader->timeScale / trak->moov->mvhd->timeScale); if (mtime<0) mtime = 0; *MediaTime = (u64) mtime; + *MediaOffset = ent->mediaTime; #if 0 // @@ -517,10 +546,9 @@ ent_found: stbl_GetSampleDTS(stbl->TimeToSample, sampleNumber, &DTS); CTS = 0; if (stbl->CompositionOffset) stbl_GetSampleCTS(stbl->CompositionOffset, sampleNumber, &CTS); -#endif //now get the entry sample (the entry time gives the CTS, and we need the DTS - e = findEntryForTime(stbl, (u32) ent->mediaTime, 1, &sampleNumber, &prevSampleNumber); + e = findEntryForTime(stbl, (u32) ent->mediaTime, 0, &sampleNumber, &prevSampleNumber); if (e) return e; //oops, the mediaTime indicates a sample that is not in our media ! @@ -535,7 +563,8 @@ ent_found: //and store the "time offset" of the desired sample in this segment //this is weird, used to rebuild the timeStamp when reading from the track, not the //media ... - *MediaOffset = firstDTS; + *MediaOffset = firstDTS; +#endif return GF_OK; } @@ -598,7 +627,7 @@ GF_Err GetPrevMediaTime(GF_TrackBox *trak, u64 movieTime, u64 *OutMovieTime) return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE void gf_isom_insert_moov(GF_ISOFile *file) { @@ -640,7 +669,7 @@ GF_ISOFile *gf_isom_create_movie(const char *fileName, u32 OpenMode, const char if (OpenMode == GF_ISOM_OPEN_WRITE) { //THIS IS NOT A TEMP FILE, WRITE mode is used for "live capture" //this file will be the final file... - mov->fileName = strdup(fileName); + mov->fileName = gf_strdup(fileName); e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_WRITE, & mov->editFileMap); if (e) goto err_exit; @@ -648,7 +677,7 @@ GF_ISOFile *gf_isom_create_movie(const char *fileName, u32 OpenMode, const char gf_isom_set_brand_info( (GF_ISOFile *) mov, GF_ISOM_BRAND_ISOM, 1); } else { //we are in EDIT mode but we are creating the file -> temp file - mov->finalName = (char*)malloc(strlen(fileName) + 1); + mov->finalName = (char*)gf_malloc(strlen(fileName) + 1); strcpy(mov->finalName, fileName); e = gf_isom_datamap_new("mp4_tmp_edit", tmp_dir, GF_ISOM_DATA_MAP_WRITE, & mov->editFileMap); if (e) { @@ -678,7 +707,7 @@ GF_EdtsEntry *CreateEditEntry(u64 EditDuration, u64 MediaTime, u8 EditMode) { GF_EdtsEntry *ent; - ent = (GF_EdtsEntry*)malloc(sizeof(GF_EdtsEntry)); + ent = (GF_EdtsEntry*)gf_malloc(sizeof(GF_EdtsEntry)); if (!ent) return NULL; switch (EditMode) { @@ -700,5 +729,6 @@ GF_EdtsEntry *CreateEditEntry(u64 EditDuration, u64 MediaTime, u8 EditMode) return ent; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/isom_read.c b/src/isomedia/isom_read.c index b1f68db..91796dd 100644 --- a/src/isomedia/isom_read.c +++ b/src/isomedia/isom_read.c @@ -1,7 +1,7 @@ /* * GPAC - Multimedia Framework C SDK * - * Copyright (c) Jean Le Feuvre 2000-2005 + * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / ISO Media File Format sub-project @@ -10,20 +10,23 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <gpac/internal/isomedia_dev.h> +#include <gpac/constants.h> + +#ifndef GPAC_DISABLE_ISOM //the only static var. Used to store any error happening while opening a movie static GF_Err MP4_API_IO_Err; @@ -71,8 +74,8 @@ GF_EXPORT void gf_isom_sample_del(GF_ISOSample **samp) { if (! *samp) return; - if ((*samp)->data && (*samp)->dataLength) free((*samp)->data); - free(*samp); + if ((*samp)->data && (*samp)->dataLength) gf_free((*samp)->data); + gf_free(*samp); *samp = NULL; } @@ -81,7 +84,7 @@ Bool gf_isom_probe_file(const char *fileName) { unsigned char data[4]; u32 type; - FILE *f = fopen(fileName, "rb"); + FILE *f = gf_f64_open(fileName, "rb"); if (!f) return 0; type = 0; if (fread(data, 1, 4, f) == 4) { @@ -123,7 +126,7 @@ GF_Err gf_isom_open_progressive(const char *fileName, GF_ISOFile **the_file, u64 movie = gf_isom_new_movie(); if (!movie) return GF_OUT_OF_MEM; - movie->fileName = strdup(fileName); + movie->fileName = gf_strdup(fileName); movie->openMode = GF_ISOM_OPEN_READ; //do NOT use FileMapping on incomplete files e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_READ, &movie->movieFileMap); @@ -132,10 +135,10 @@ GF_Err gf_isom_open_progressive(const char *fileName, GF_ISOFile **the_file, u64 return e; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE movie->editFileMap = NULL; movie->finalName = NULL; -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ e = gf_isom_parse_movie_boxes(movie, BytesMissing); if (e == GF_ISOM_INCOMPLETE_FILE) { @@ -166,15 +169,15 @@ GF_ISOFile *gf_isom_open(const char *fileName, u32 OpenMode, const char *tmp_dir { GF_ISOFile *movie; MP4_API_IO_Err = GF_OK; - + switch (OpenMode & 0xFF) { case GF_ISOM_OPEN_READ_DUMP: case GF_ISOM_OPEN_READ: movie = gf_isom_open_file(fileName, OpenMode, NULL); break; -#ifndef GPAC_READ_ONLY - +#ifndef GPAC_DISABLE_ISOM_WRITE + case GF_ISOM_OPEN_WRITE: movie = gf_isom_create_movie(fileName, OpenMode, tmp_dir); break; @@ -185,8 +188,8 @@ GF_ISOFile *gf_isom_open(const char *fileName, u32 OpenMode, const char *tmp_dir movie = gf_isom_create_movie(fileName, OpenMode, tmp_dir); break; -#endif //GPAC_READ_ONLY - +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + default: return NULL; } @@ -200,21 +203,22 @@ GF_Err gf_isom_close(GF_ISOFile *movie) if (movie == NULL) return GF_ISOM_INVALID_FILE; e = GF_OK; -#ifndef GPAC_READ_ONLY - +#ifndef GPAC_DISABLE_ISOM_WRITE + //write our movie to the file if (movie->openMode != GF_ISOM_OPEN_READ) { gf_isom_get_duration(movie); -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS //movie fragment mode, just store the fragment if ( (movie->openMode == GF_ISOM_OPEN_WRITE) && (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY) ) { - e = StoreFragment(movie); - } else + e = gf_isom_close_fragments(movie); + if (e) return e; + } else #endif e = WriteToFile(movie); } - -#endif //GPAC_READ_ONLY + +#endif /*GPAC_DISABLE_ISOM_WRITE*/ //free and return; gf_isom_delete_movie(movie); @@ -251,13 +255,13 @@ GF_Descriptor *gf_isom_get_root_od(GF_ISOFile *movie) switch (movie->moov->iods->descriptor->tag) { case GF_ODF_ISOM_OD_TAG: - od = (GF_ObjectDescriptor*)malloc(sizeof(GF_ObjectDescriptor)); + od = (GF_ObjectDescriptor*)gf_malloc(sizeof(GF_ObjectDescriptor)); memset(od, 0, sizeof(GF_ObjectDescriptor)); od->ESDescriptors = gf_list_new(); useIOD = 0; break; case GF_ODF_ISOM_IOD_TAG: - iod = (GF_InitialObjectDescriptor*)malloc(sizeof(GF_InitialObjectDescriptor)); + iod = (GF_InitialObjectDescriptor*)gf_malloc(sizeof(GF_InitialObjectDescriptor)); memset(iod, 0, sizeof(GF_InitialObjectDescriptor)); iod->ESDescriptors = gf_list_new(); useIOD = 1; @@ -265,7 +269,7 @@ GF_Descriptor *gf_isom_get_root_od(GF_ISOFile *movie) default: return NULL; } - + //duplicate our descriptor movie->LastError = gf_odf_desc_copy((GF_Descriptor *) movie->moov->iods->descriptor, &desc); if (movie->LastError) return NULL; @@ -324,7 +328,7 @@ GF_Descriptor *gf_isom_get_root_od(GF_ISOFile *movie) if (!movie->LastError) movie->LastError = gf_list_add(iod->ESDescriptors, esd); if (movie->LastError) { gf_odf_desc_del(desc); - gf_odf_desc_del((GF_Descriptor *) &iod); + gf_odf_desc_del((GF_Descriptor *) iod); return NULL; } } @@ -365,7 +369,7 @@ u32 gf_isom_get_track_by_id(GF_ISOFile *the_file, u32 trackID) u32 count; u32 i; if (the_file == NULL) return 0; - + count = gf_isom_get_track_count(the_file); if (!count) return 0; for (i = 0; i < count; i++) { @@ -384,6 +388,29 @@ Bool gf_isom_has_movie(GF_ISOFile *file) return 0; } +#ifndef GPAC_DISABLE_ISOM +GF_EXPORT +Bool gf_isom_has_segment(GF_ISOFile *file, u32 *brand, u32 *version) +{ +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + u32 i; + GF_Box *a; + i = 0; + while (a = gf_list_enum(file->TopBoxes, &i)) { +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + if (a->type == GF_ISOM_BOX_TYPE_STYP) { + GF_SegmentTypeBox *styp = (GF_SegmentTypeBox *)a; + *brand = styp->majorBrand; + *version = styp->minorVersion; + return 1; + } +#endif + } +#endif + return 0; +} +#endif + //return the timescale of the movie, 0 if error GF_EXPORT u32 gf_isom_get_timescale(GF_ISOFile *movie) @@ -396,7 +423,7 @@ u32 gf_isom_get_timescale(GF_ISOFile *movie) GF_EXPORT u64 gf_isom_get_duration(GF_ISOFile *movie) { -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE u32 i; u64 maxDur; GF_TrackBox *trak; @@ -407,7 +434,7 @@ u64 gf_isom_get_duration(GF_ISOFile *movie) //if file was open in Write or Edit mode, recompute the duration //the duration of a movie is the MaxDuration of all the tracks... -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE if (movie->openMode != GF_ISOM_OPEN_READ) { maxDur = 0; @@ -420,7 +447,7 @@ u64 gf_isom_get_duration(GF_ISOFile *movie) movie->moov->mvhd->duration = maxDur; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ return movie->moov->mvhd->duration; } @@ -430,7 +457,7 @@ GF_EXPORT GF_Err gf_isom_get_creation_time(GF_ISOFile *movie, u64 *creationTime, u64 *modificationTime) { if (!movie || !movie->moov) return GF_BAD_PARAM; - + if (creationTime) *creationTime = movie->moov->mvhd->creationTime; if (creationTime) *modificationTime = movie->moov->mvhd->modificationTime; return GF_OK; @@ -494,7 +521,7 @@ u64 gf_isom_get_track_duration(GF_ISOFile *movie, u32 trackNumber) trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return 0; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*in all modes except dump recompute duration in case headers are wrong*/ if (movie->openMode != GF_ISOM_OPEN_READ_DUMP) { SetTrackDuration(trak); @@ -528,7 +555,7 @@ s32 gf_isom_get_reference_count(GF_ISOFile *movie, u32 trackNumber, u32 referenc movie->LastError = GF_ISOM_INVALID_MODE; return -1; } - + dpnd = NULL; if ( (movie->LastError = Track_FindRef(trak, referenceType, &dpnd)) ) return -1; if (!dpnd) return 0; @@ -549,7 +576,7 @@ GF_Err gf_isom_get_reference(GF_ISOFile *movie, u32 trackNumber, u32 referenceTy *refTrack = 0; if (!trak || !trak->References) return GF_BAD_PARAM; - + dpnd = NULL; e = Track_FindRef(trak, referenceType, &dpnd); if (e) return e; @@ -557,7 +584,7 @@ GF_Err gf_isom_get_reference(GF_ISOFile *movie, u32 trackNumber, u32 referenceTy if (referenceIndex > dpnd->trackIDCount) return GF_BAD_PARAM; - //the spec allows a NULL reference + //the spec allows a NULL reference //(ex, to force desync of a track, set a sync ref with ID = 0) if (dpnd->trackIDs[referenceIndex - 1] == 0) return GF_OK; @@ -658,7 +685,7 @@ u64 gf_isom_get_media_duration(GF_ISOFile *movie, u32 trackNumber) if (!trak) return 0; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE /*except in dump mode always recompute the duration*/ if (movie->openMode != GF_ISOM_OPEN_READ_DUMP) { @@ -696,7 +723,7 @@ GF_Err gf_isom_get_copyright(GF_ISOFile *mov, u32 Index, const char **threeCharC { GF_UserDataMap *map; GF_CopyrightBox *cprt; - + if (!mov || !mov->moov || !Index) return GF_BAD_PARAM; if (!mov->moov->udta) return GF_OK; @@ -719,14 +746,14 @@ GF_Err gf_isom_get_watermark(GF_ISOFile *mov, bin128 UUID, u8** data, u32* lengt if (!mov) return GF_BAD_PARAM; if (!mov->moov || !mov->moov->udta) return GF_NOT_SUPPORTED; - + 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); if (!wm) return GF_NOT_SUPPORTED; - *data = (u8 *) malloc(sizeof(char)*wm->dataSize); + *data = (u8 *) gf_malloc(sizeof(char)*wm->dataSize); memcpy(*data, wm->data, wm->dataSize); *length = wm->dataSize; return GF_OK; @@ -780,7 +807,7 @@ GF_Err gf_isom_get_chapter(GF_ISOFile *movie, u32 trackNumber, u32 Index, u64 *c if (!map) return GF_BAD_PARAM; lst = (GF_ChapterListBox *)gf_list_get(map->boxList, 0); if (!lst) return GF_BAD_PARAM; - + ce = (GF_ChapterEntry *)gf_list_get(lst->list, Index-1); if (!ce) return GF_BAD_PARAM; if (chapter_time) { @@ -882,7 +909,7 @@ u32 gf_isom_get_mpeg4_subtype(GF_ISOFile *the_file, u32 trackNumber, u32 Descrip return entry->type; } -//Get the HandlerDescription name. +//Get the HandlerDescription name. GF_EXPORT GF_Err gf_isom_get_handler_name(GF_ISOFile *the_file, u32 trackNumber, const char **outName) { @@ -921,6 +948,8 @@ GF_Err gf_isom_get_data_reference(GF_ISOFile *the_file, u32 trackNumber, u32 Str u32 drefIndex; GF_Err e; + *outURL = *outURN = NULL; + if (!StreamDescriptionIndex || !trackNumber) return GF_BAD_PARAM; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return GF_BAD_PARAM; @@ -1018,6 +1047,12 @@ GF_ISOSample *gf_isom_get_sample(GF_ISOFile *the_file, u32 trackNumber, u32 samp if (!sampleNumber) return NULL; samp = gf_isom_sample_new(); if (!samp) return NULL; + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + if (sampleNumber<=trak->sample_count_at_seg_start) return NULL; + sampleNumber -= trak->sample_count_at_seg_start; +#endif + e = Media_GetSample(trak->Media, sampleNumber, &samp, &descIndex, 0, NULL); if (e) { gf_isom_set_last_error(the_file, e); @@ -1025,7 +1060,10 @@ GF_ISOSample *gf_isom_get_sample(GF_ISOFile *the_file, u32 trackNumber, u32 samp return NULL; } if (sampleDescriptionIndex) *sampleDescriptionIndex = descIndex; - +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + if (samp) samp->DTS += trak->dts_at_seg_start; +#endif + return samp; } @@ -1040,8 +1078,8 @@ u32 gf_isom_get_sample_duration(GF_ISOFile *the_file, u32 trackNumber, u32 sampl stbl_GetSampleDTS(trak->Media->information->sampleTable->TimeToSample, sampleNumber, &dur); if (sampleNumber == trak->Media->information->sampleTable->SampleSize->sampleCount) { return (u32) (trak->Media->mediaHeader->duration - dur); - } - + } + stbl_GetSampleDTS(trak->Media->information->sampleTable->TimeToSample, sampleNumber+1, &dts); return (u32) (dts - dur); } @@ -1104,7 +1142,7 @@ u32 gf_isom_get_sample_from_dts(GF_ISOFile *the_file, u32 trackNumber, u64 dts) if (!trak) return 0; stbl = trak->Media->information->sampleTable; - + e = findEntryForTime(stbl, dts, 1, &sampleNumber, &prevSampleNumber); if (e) return 0; return sampleNumber; @@ -1133,8 +1171,13 @@ GF_Err gf_isom_get_sample_for_media_time(GF_ISOFile *the_file, u32 trackNumber, if (!trak) return GF_BAD_PARAM; stbl = trak->Media->information->sampleTable; - - e = findEntryForTime(stbl, desiredTime, 1, &sampleNumber, &prevSampleNumber); + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + if (desiredTime < trak->dts_at_seg_start) return GF_BAD_PARAM; + desiredTime -= trak->dts_at_seg_start; +#endif + + e = findEntryForTime(stbl, desiredTime, 0, &sampleNumber, &prevSampleNumber); if (e) return e; //if no shadow table, reset to sync only @@ -1209,7 +1252,7 @@ GF_Err gf_isom_get_sample_for_media_time(GF_ISOFile *the_file, u32 trackNumber, //OK sampleNumber is exactly the sample we need (except for shadow) - + *sample = gf_isom_sample_new(); if (*sample == NULL) return GF_OUT_OF_MEM; @@ -1235,7 +1278,12 @@ GF_Err gf_isom_get_sample_for_media_time(GF_ISOFile *the_file, u32 trackNumber, return e; } //optionally get the sample number - if (SampleNum) *SampleNum = sampleNumber; + if (SampleNum) { + *SampleNum = sampleNumber; +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + *SampleNum += trak->sample_count_at_seg_start; +#endif + } //in shadow mode, we only get the data of the shadowing sample ! if (useShadow) { @@ -1245,7 +1293,7 @@ GF_Err gf_isom_get_sample_for_media_time(GF_ISOFile *the_file, u32 trackNumber, //if no sample, the shadowSync is broken, return the sample if (!shadow) return GF_OK; (*sample)->IsRAP = 1; - free((*sample)->data); + gf_free((*sample)->data); (*sample)->dataLength = shadow->dataLength; (*sample)->data = shadow->data; //set data length to 0 to keep the buffer alive... @@ -1296,7 +1344,7 @@ GF_Err gf_isom_get_sample_for_movie_time(GF_ISOFile *the_file, u32 trackNumber, if (useEdit && mediaOffset == -1) { if ((SearchMode==GF_ISOM_SEARCH_FORWARD) || (SearchMode==GF_ISOM_SEARCH_BACKWARD)) { /*get next sample time in MOVIE timescale*/ - if (SearchMode==GF_ISOM_SEARCH_FORWARD) + if (SearchMode==GF_ISOM_SEARCH_FORWARD) e = GetNextMediaTime(trak, movieTime, &mediaTime); else e = GetPrevMediaTime(trak, movieTime, &mediaTime); @@ -1313,7 +1361,7 @@ GF_Err gf_isom_get_sample_for_movie_time(GF_ISOFile *the_file, u32 trackNumber, if (useEdit==2) { if ((SearchMode==GF_ISOM_SEARCH_FORWARD) || (SearchMode==GF_ISOM_SEARCH_BACKWARD)) { /*get next sample time in MOVIE timescale*/ - if (SearchMode==GF_ISOM_SEARCH_FORWARD) + if (SearchMode==GF_ISOM_SEARCH_FORWARD) e = GetNextMediaTime(trak, movieTime, &mediaTime); else e = GetPrevMediaTime(trak, movieTime, &mediaTime); @@ -1326,8 +1374,8 @@ GF_Err gf_isom_get_sample_for_movie_time(GF_ISOFile *the_file, u32 trackNumber, e = gf_isom_get_sample_for_media_time(the_file, trackNumber, mediaTime, StreamDescriptionIndex, SearchMode, sample, &sampNum); if (e) return e; - //OK, now the trick: we have to rebuild the time stamps, according - //to the media time scale (used by SLConfig) - add the edit start time but stay in + //OK, now the trick: we have to rebuild the time stamps, according + //to the media time scale (used by SLConfig) - add the edit start time but stay in //the track TS if (useEdit) { u64 _ts = segStartTime; @@ -1395,9 +1443,9 @@ GF_Err gf_isom_get_edit_segment(GF_ISOFile *the_file, u32 trackNumber, u32 Segme trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return GF_BAD_PARAM; - if (!trak || !trak->editBox || - !trak->editBox->editList || - (SegmentIndex > gf_list_count(trak->editBox->editList->entryList)) || + if (!trak || !trak->editBox || + !trak->editBox->editList || + (SegmentIndex > gf_list_count(trak->editBox->editList->entryList)) || !SegmentIndex) return GF_BAD_PARAM; @@ -1433,7 +1481,7 @@ u8 gf_isom_has_sync_points(GF_ISOFile *the_file, u32 trackNumber) trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return 0; if (trak->Media->information->sampleTable->SyncSample) { - if (!trak->Media->information->sampleTable->SyncSample->nb_entries) return 2; + if (!trak->Media->information->sampleTable->SyncSample->nb_entries) return 2; return 1; } return 0; @@ -1447,7 +1495,7 @@ u32 gf_isom_get_sync_point_count(GF_ISOFile *the_file, u32 trackNumber) trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return 0; if (trak->Media->information->sampleTable->SyncSample) { - return trak->Media->information->sampleTable->SyncSample->nb_entries; + return trak->Media->information->sampleTable->SyncSample->nb_entries; } return 0; } @@ -1488,7 +1536,7 @@ GF_Err gf_isom_get_sample_padding_bits(GF_ISOFile *the_file, u32 trackNumber, u3 //Padding info - return stbl_GetPaddingBits(trak->Media->information->sampleTable->PaddingBits, + return stbl_GetPaddingBits(trak->Media->information->sampleTable->PaddingBits, sampleNumber, NbBits); } @@ -1517,10 +1565,10 @@ u32 gf_isom_get_user_data_count(GF_ISOFile *movie, u32 trackNumber, u32 UserData u32 i, count; if (!movie || !movie->moov) return 0; - + if (UserDataType == GF_ISOM_BOX_TYPE_UUID) UserDataType = 0; memset(t, 1, 16); - + if (trackNumber) { trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return 0; @@ -1551,7 +1599,7 @@ GF_Err gf_isom_get_user_data(GF_ISOFile *movie, u32 trackNumber, u32 UserDataTyp GF_UserDataBox *udta; if (!movie || !movie->moov) return GF_BAD_PARAM; - + if (trackNumber) { trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak) return GF_BAD_PARAM; @@ -1571,7 +1619,7 @@ GF_Err gf_isom_get_user_data(GF_ISOFile *movie, u32 trackNumber, u32 UserDataTyp while ((map = (GF_UserDataMap*)gf_list_enum(udta->recordList, &i))) { if ((map->boxType == GF_ISOM_BOX_TYPE_UUID) && !memcmp(map->uuid, UUID, 16)) goto found; else if (map->boxType == UserDataType) goto found; - + } return GF_BAD_PARAM; @@ -1581,10 +1629,10 @@ found: ptr = (GF_UnknownBox*)gf_list_get(map->boxList, UserDataIndex-1); //ok alloc the data - *userData = (char *)malloc(sizeof(char)*ptr->dataSize); + *userData = (char *)gf_malloc(sizeof(char)*ptr->dataSize); if (!*userData) return GF_OUT_OF_MEM; memcpy(*userData, ptr->data, sizeof(char)*ptr->dataSize); - *userDataSize = ptr->dataSize; + *userDataSize = ptr->dataSize; return GF_OK; } @@ -1617,7 +1665,7 @@ u32 gf_isom_get_max_chunk_duration(GF_ISOFile *movie, u32 trackNumber) for (i=0; i<stts->nb_entries; i++) { if (stts->entries[i].sampleDelta > sample_dur) sample_dur = stts->entries[i].sampleDelta; } - + //rescale to ms i = 1000 * sample_dur * sample_per_chunk / trak->Media->mediaHeader->timeScale; return i; @@ -1647,7 +1695,7 @@ u16 gf_isom_get_sample_fragment_size(GF_ISOFile *the_file, u32 trackNumber, u32 GF_EXPORT -GF_Err gf_isom_get_fragment_defaults(GF_ISOFile *the_file, u32 trackNumber, +GF_Err gf_isom_get_fragment_defaults(GF_ISOFile *the_file, u32 trackNumber, u32 *defaultDuration, u32 *defaultSize, u32 *defaultDescriptionIndex, u32 *defaultRandomAccess, u8 *defaultPadding, u16 *defaultDegradationPriority) { @@ -1691,7 +1739,7 @@ GF_Err gf_isom_get_fragment_defaults(GF_ISOFile *the_file, u32 trackNumber, if (defaultRandomAccess) { //no sync table is ALL RAP *defaultRandomAccess = stbl->SyncSample ? 0 : 1; - if (stbl->SyncSample + if (stbl->SyncSample && (stbl->SyncSample->nb_entries >= stbl->SampleSize->sampleCount/2)) { *defaultRandomAccess = 1; } @@ -1741,17 +1789,99 @@ GF_Err gf_isom_get_fragment_defaults(GF_ISOFile *the_file, u32 trackNumber, GF_EXPORT GF_Err gf_isom_refresh_fragmented(GF_ISOFile *movie, u64 *MissingBytes) { -#ifdef GPAC_ISOM_NO_FRAGMENTS + u64 prevsize, size; +#ifdef GPAC_DISABLE_ISOM_FRAGMENTS return GF_NOT_SUPPORTED; #else if (!movie || !movie->moov || !movie->moov->mvex) return GF_BAD_PARAM; if (movie->openMode != GF_ISOM_OPEN_READ) return GF_BAD_PARAM; + /*refresh size*/ + size = gf_bs_get_size(movie->movieFileMap->bs); + prevsize = gf_bs_get_refreshed_size(movie->movieFileMap->bs); + if (prevsize==size) return GF_OK; + //ok parse root boxes return gf_isom_parse_movie_boxes(movie, MissingBytes); #endif } +GF_EXPORT +GF_Err gf_isom_release_segment(GF_ISOFile *movie, Bool reset_tables) +{ +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS + u32 i; + if (!movie || !movie->moov || !movie->moov->mvex) return GF_BAD_PARAM; + + for (i=0; i<gf_list_count(movie->moov->trackList); i++) { + GF_TrackBox *trak = gf_list_get(movie->moov->trackList, i); + if (trak->Media->information->dataHandler == movie->movieFileMap) { + trak->Media->information->dataHandler = NULL; + } + if (reset_tables) { + u32 type; + u64 dts; + GF_SampleTableBox *stbl = trak->Media->information->sampleTable; + trak->sample_count_at_seg_start += stbl->SampleSize->sampleCount; + stbl_GetSampleDTS(stbl->TimeToSample, stbl->SampleSize->sampleCount, &dts); + trak->dts_at_seg_start += dts; + +#define RECREATE_BOX(_a, __cast) \ + if (_a) { \ + type = _a->type;\ + gf_isom_box_del((GF_Box *)_a);\ + _a = __cast gf_isom_box_new(type);\ + }\ + + RECREATE_BOX(stbl->ChunkOffset, (GF_Box *)); + RECREATE_BOX(stbl->CompositionOffset, (GF_CompositionOffsetBox *)); + RECREATE_BOX(stbl->DegradationPriority, (GF_DegradationPriorityBox *)); + RECREATE_BOX(stbl->PaddingBits, (GF_PaddingBitsBox *)); + RECREATE_BOX(stbl->SampleDep, (GF_SampleDependencyTypeBox *)); + RECREATE_BOX(stbl->SampleSize, (GF_SampleSizeBox *)); + RECREATE_BOX(stbl->SampleToChunk, (GF_SampleToChunkBox *)); + RECREATE_BOX(stbl->ShadowSync, (GF_ShadowSyncBox *)); + RECREATE_BOX(stbl->SyncSample, (GF_SyncSampleBox *)); + RECREATE_BOX(stbl->TimeToSample, (GF_TimeToSampleBox *)); + } + } + + gf_isom_datamap_del(movie->movieFileMap); + movie->movieFileMap = NULL; +#endif + return GF_OK; +} + +GF_Err gf_isom_open_segment(GF_ISOFile *movie, const char *fileName) +{ +#ifdef GPAC_DISABLE_ISOM_FRAGMENTS + return GF_NOT_SUPPORTED; +#else + u64 MissingBytes; + GF_Err e; + u32 i; + if (!movie || !movie->moov || !movie->moov->mvex) return GF_BAD_PARAM; + if (movie->openMode != GF_ISOM_OPEN_READ) return GF_BAD_PARAM; + + if (movie->movieFileMap) + gf_isom_release_segment(movie, 0); + + e = gf_isom_datamap_new(fileName, NULL, GF_ISOM_DATA_MAP_READ_ONLY, &movie->movieFileMap); + if (e) return e; + + for (i=0; i<gf_list_count(movie->moov->trackList); i++) { + GF_TrackBox *trak = gf_list_get(movie->moov->trackList, i); + if (trak->Media->information->dataHandler == NULL) { + trak->Media->information->dataHandler = movie->movieFileMap; + } + } + + movie->current_top_box_start = 0; + //ok parse root boxes + return gf_isom_parse_movie_boxes(movie, &MissingBytes); +#endif +} + GF_EXPORT GF_Err gf_isom_text_set_streaming_mode(GF_ISOFile *movie, Bool do_convert) @@ -1774,7 +1904,7 @@ GF_GenericSampleDescription *gf_isom_get_generic_sample_description(GF_ISOFile * if (!trak || !StreamDescriptionIndex) return NULL; entry = (GF_GenericVisualSampleEntryBox *)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex-1); - //no entry or MPEG entry: + //no entry or MPEG entry: if (!entry || IsMP4Description(entry->type) ) return NULL; //if we handle the description return false switch (entry->type) { @@ -1806,7 +1936,7 @@ GF_GenericSampleDescription *gf_isom_get_generic_sample_description(GF_ISOFile * udesc->color_table_index = entry->color_table_index; if (entry->data_size) { udesc->extension_buf_size = entry->data_size; - udesc->extension_buf = (char*)malloc(sizeof(char) * entry->data_size); + udesc->extension_buf = (char*)gf_malloc(sizeof(char) * entry->data_size); memcpy(udesc->extension_buf, entry->data, entry->data_size); } return udesc; @@ -1826,7 +1956,7 @@ GF_GenericSampleDescription *gf_isom_get_generic_sample_description(GF_ISOFile * udesc->nb_channels = gena->channel_count; if (gena->data_size) { udesc->extension_buf_size = gena->data_size; - udesc->extension_buf = (char*)malloc(sizeof(char) * gena->data_size); + udesc->extension_buf = (char*)gf_malloc(sizeof(char) * gena->data_size); memcpy(udesc->extension_buf, gena->data, gena->data_size); } return udesc; @@ -1840,7 +1970,7 @@ GF_GenericSampleDescription *gf_isom_get_generic_sample_description(GF_ISOFile * } if (genm->data_size) { udesc->extension_buf_size = genm->data_size; - udesc->extension_buf = (char*)malloc(sizeof(char) * genm->data_size); + udesc->extension_buf = (char*)gf_malloc(sizeof(char) * genm->data_size); memcpy(udesc->extension_buf, genm->data, genm->data_size); } return udesc; @@ -1865,13 +1995,15 @@ GF_Err gf_isom_get_visual_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDes entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1); //no support for generic sample entries (eg, no MPEG4 descriptor) if (entry == NULL) return GF_BAD_PARAM; - + //valid for MPEG visual, JPG and 3GPP H263 switch (entry->type) { case GF_ISOM_BOX_TYPE_ENCV: case GF_ISOM_BOX_TYPE_MP4V: case GF_ISOM_SUBTYPE_3GP_H263: case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: case GF_ISOM_BOX_TYPE_GNRV: *Width = ((GF_VisualSampleEntryBox*)entry)->Width; *Height = ((GF_VisualSampleEntryBox*)entry)->Height; @@ -1903,7 +2035,7 @@ GF_Err gf_isom_get_audio_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDesc entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, 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; @@ -1940,13 +2072,15 @@ GF_Err gf_isom_get_pixel_aspect_ratio(GF_ISOFile *movie, u32 trackNumber, u32 St entry = (GF_SampleEntryBox *)gf_list_get(stsd->boxList, StreamDescriptionIndex - 1); //no support for generic sample entries (eg, no MPEG4 descriptor) if (entry == NULL) return GF_BAD_PARAM; - + //valid for MPEG visual, JPG and 3GPP H263 switch (entry->type) { case GF_ISOM_BOX_TYPE_ENCV: case GF_ISOM_BOX_TYPE_MP4V: case GF_ISOM_SUBTYPE_3GP_H263: case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: case GF_ISOM_BOX_TYPE_GNRV: *hSpacing = ((GF_VisualSampleEntryBox*)entry)->pasp ? ((GF_VisualSampleEntryBox*)entry)->pasp->hSpacing : 0; *vSpacing = ((GF_VisualSampleEntryBox*)entry)->pasp ? ((GF_VisualSampleEntryBox*)entry)->pasp->vSpacing : 0; @@ -1960,7 +2094,7 @@ GF_EXPORT const char *gf_isom_get_filename(GF_ISOFile *movie) { if (!movie) return NULL; -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE if (movie->finalName && !movie->fileName) return movie->finalName; #endif return movie->fileName; @@ -1989,6 +2123,14 @@ u8 gf_isom_get_pl_indication(GF_ISOFile *movie, u8 PL_Code) } } +GF_EXPORT +GF_Err gf_isom_get_track_matrix(GF_ISOFile *the_file, u32 trackNumber, u32 matrix[9]) +{ + GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber); + if (!trak || !trak->Header) return GF_BAD_PARAM; + memcpy(matrix, trak->Header->matrix, sizeof(trak->Header->matrix)); + return GF_OK; +} GF_EXPORT GF_Err gf_isom_get_track_layout_info(GF_ISOFile *movie, u32 trackNumber, u32 *width, u32 *height, s32 *translation_x, s32 *translation_y, s16 *layer) @@ -2038,21 +2180,31 @@ Bool gf_isom_is_single_av(GF_ISOFile *file) count = gf_isom_get_track_count(file); for (i=0; i<count; i++) { u32 mtype = gf_isom_get_media_type(file, i+1); - if (mtype==GF_ISOM_MEDIA_SCENE) { + switch (mtype) { + case GF_ISOM_MEDIA_SCENE: if (gf_isom_get_sample_count(file, i+1)>1) nb_any++; else nb_scene++; - } else if (mtype==GF_ISOM_MEDIA_OD) { + break; + case GF_ISOM_MEDIA_OD: if (gf_isom_get_sample_count(file, i+1)>1) nb_any++; else nb_od++; - } - else if (mtype==GF_ISOM_MEDIA_TEXT) nb_text++; - else if (mtype==GF_ISOM_MEDIA_AUDIO) nb_a++; - else if (mtype==GF_ISOM_MEDIA_VISUAL) { + break; + case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: + nb_text++; + break; + case GF_ISOM_MEDIA_AUDIO: + nb_a++; + break; + case GF_ISOM_MEDIA_VISUAL: /*discard file with images*/ if (gf_isom_get_sample_count(file, i+1)==1) nb_any++; else nb_v++; + break; + default: + nb_any++; + break; } - else nb_any++; } if (nb_any) return 0; if ((nb_scene<=1) && (nb_od<=1) && (nb_a<=1) && (nb_v<=1) && (nb_text<=1) ) return 1; @@ -2095,7 +2247,7 @@ u32 gf_isom_guess_specification(GF_ISOFile *file) /*forces non-isma*/ if (gf_isom_get_sample_count(file, i+1)>1) nb_m4s++; } - else if (mtype==GF_ISOM_MEDIA_TEXT) nb_text++; + else if ((mtype==GF_ISOM_MEDIA_TEXT) || (mtype==GF_ISOM_MEDIA_SUBT)) nb_text++; else if ((mtype==GF_ISOM_MEDIA_AUDIO) || (mtype==GF_ISOM_MEDIA_VISUAL)) { switch (mstype) { case GF_ISOM_SUBTYPE_3GP_AMR: @@ -2107,23 +2259,33 @@ u32 gf_isom_guess_specification(GF_ISOFile *file) case GF_ISOM_SUBTYPE_3GP_QCELP: nb_qcelp++; break; case GF_ISOM_SUBTYPE_3GP_SMV: nb_smv++; break; case GF_ISOM_SUBTYPE_AVC_H264: nb_avc++; break; + case GF_ISOM_SUBTYPE_AVC2_H264: nb_avc++; break; + case GF_ISOM_SUBTYPE_SVC_H264: nb_avc++; break; case GF_ISOM_SUBTYPE_MPEG4: case GF_ISOM_SUBTYPE_MPEG4_CRYP: { GF_DecoderConfig *dcd = gf_isom_get_decoder_config(file, i+1, 1); switch (dcd->streamType) { - case 0x04: - if (dcd->objectTypeIndication==0x20) nb_m4v++; - else if (dcd->objectTypeIndication==0x21) nb_avc++; + case GF_STREAM_VISUAL: + if (dcd->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) nb_m4v++; + else if (dcd->objectTypeIndication==GPAC_OTI_VIDEO_AVC) nb_avc++; else nb_v++; break; - case 0x05: + case GF_STREAM_AUDIO: switch (dcd->objectTypeIndication) { - case 0x66: case 0x67: case 0x68: case 0x40: nb_aac++; break; - case 0x69: case 0x6B: nb_mp3++; break; - case 0xA0: nb_evrc++; break; - case 0xA1: nb_smv++; break; - case 0xE1: nb_qcelp++; break; + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: + case GPAC_OTI_AUDIO_AAC_MPEG4: + nb_aac++; + break; + case GPAC_OTI_AUDIO_MPEG2_PART3: + case GPAC_OTI_AUDIO_MPEG1: + nb_mp3++; + break; + case GPAC_OTI_AUDIO_EVRC_VOICE: nb_evrc++; break; + case GPAC_OTI_AUDIO_SMV_VOICE: nb_smv++; break; + case GPAC_OTI_AUDIO_13K_VOICE: nb_qcelp++; break; default: nb_a++; break; } break; @@ -2154,7 +2316,7 @@ u32 gf_isom_guess_specification(GF_ISOFile *file) nb_v = nb_m4v + nb_avc + nb_h263; nb_a = nb_mp3 + nb_aac + nb_amr; - + /*avc file: whatever has AVC and no systems*/ if (nb_avc) { if (!nb_scene && !nb_od) return GF_ISOM_BRAND_AVC1; @@ -2207,7 +2369,7 @@ GF_Err gf_isom_apple_get_tag(GF_ISOFile *mov, u32 tag, const char **data, u32 *d GF_ListItemBox *info; GF_ItemListBox *ilst; GF_MetaBox *meta; - + *data = NULL; *data_len = 0; @@ -2216,14 +2378,14 @@ GF_Err gf_isom_apple_get_tag(GF_ISOFile *mov, u32 tag, const char **data, u32 *d ilst = gf_ismo_locate_box(meta->other_boxes, GF_ISOM_BOX_TYPE_ILST, NULL); if (!ilst) return GF_URL_ERROR; - + if (tag==GF_ISOM_ITUNE_PROBE) return GF_OK; i=0; while ( (info=gf_list_enum(ilst->tags, &i))) { if (info->type==tag) break; /*special cases*/ - if ((tag==GF_ISOM_ITUNE_GENRE) && (info->type==GF_ISOM_BOX_TYPE_0xA9GEN)) break; + if ((tag==GF_ISOM_ITUNE_GENRE) && (info->type==(u32) GF_ISOM_BOX_TYPE_0xA9GEN)) break; info = NULL; } if (!info || !info->data || !info->data->data) return GF_URL_ERROR; @@ -2307,7 +2469,7 @@ GF_Err gf_isom_get_timed_meta_data_info(GF_ISOFile *file, u32 track, u32 sampleD u32 gf_isom_get_next_alternate_group_id(GF_ISOFile *movie) { u32 id = 0; - u32 i=0; + u32 i=0; while (i< gf_isom_get_track_count(movie) ) { GF_TrackBox *trak = gf_isom_get_track_from_file(movie, i+1); @@ -2318,3 +2480,5 @@ u32 gf_isom_get_next_alternate_group_id(GF_ISOFile *movie) return id+1; } + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/isom_store.c b/src/isomedia/isom_store.c index a14d2c4..a7e1763 100644 --- a/src/isomedia/isom_store.c +++ b/src/isomedia/isom_store.c @@ -25,7 +25,7 @@ #include <gpac/internal/isomedia_dev.h> -#ifndef GPAC_READ_ONLY +#if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_WRITE) #define GPAC_ISOM_CPRT_NOTICE "IsoMedia File Produced with GPAC "GPAC_FULL_VERSION @@ -41,8 +41,8 @@ static GF_Err gf_isom_insert_copyright(GF_ISOFile *movie) if (_free->dataSize) { if (!strcmp(_free->data, GPAC_ISOM_CPRT_NOTICE)) return GF_OK; if (strstr(_free->data, "File Produced with GPAC")) { - free(_free->data); - _free->data = strdup(GPAC_ISOM_CPRT_NOTICE); + gf_free(_free->data); + _free->data = gf_strdup(GPAC_ISOM_CPRT_NOTICE); _free->dataSize = strlen(_free->data); return GF_OK; } @@ -53,7 +53,7 @@ static GF_Err gf_isom_insert_copyright(GF_ISOFile *movie) if (!a) return GF_OUT_OF_MEM; _free = (GF_FreeSpaceBox *)a; _free->dataSize = strlen(GPAC_ISOM_CPRT_NOTICE) + 1; - _free->data = strdup(GPAC_ISOM_CPRT_NOTICE); + _free->data = gf_strdup(GPAC_ISOM_CPRT_NOTICE); if (!_free->data) return GF_OUT_OF_MEM; return gf_list_add(movie->TopBoxes, _free); } @@ -92,7 +92,7 @@ void CleanWriters(GF_List *writers) writer = (TrackWriter*)gf_list_get(writers, 0); gf_isom_box_del(writer->stco); gf_isom_box_del((GF_Box *)writer->stsc); - free(writer); + gf_free(writer); gf_list_rem(writers, 0); } } @@ -110,12 +110,12 @@ void ResetWriters(GF_List *writers) gf_isom_box_del((GF_Box *)writer->stsc); writer->stsc = (GF_SampleToChunkBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSC); if (writer->stco->type == GF_ISOM_BOX_TYPE_STCO) { - free(((GF_ChunkOffsetBox *)writer->stco)->offsets); + gf_free(((GF_ChunkOffsetBox *)writer->stco)->offsets); ((GF_ChunkOffsetBox *)writer->stco)->offsets = NULL; ((GF_ChunkOffsetBox *)writer->stco)->nb_entries = 0; ((GF_ChunkOffsetBox *)writer->stco)->alloc_size = 0; } else { - free(((GF_ChunkLargeOffsetBox *)writer->stco)->offsets); + gf_free(((GF_ChunkLargeOffsetBox *)writer->stco)->offsets); ((GF_ChunkLargeOffsetBox *)writer->stco)->offsets = NULL; ((GF_ChunkLargeOffsetBox *)writer->stco)->nb_entries = 0; ((GF_ChunkLargeOffsetBox *)writer->stco)->alloc_size = 0; @@ -225,7 +225,7 @@ static GF_Err ShiftOffset(GF_ISOFile *file, GF_List *writers, u64 offset) co64 = (GF_ChunkLargeOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CO64); if (!co64) return GF_OUT_OF_MEM; co64->nb_entries = stco->nb_entries; - co64->offsets = (u64*)malloc(co64->nb_entries * sizeof(u64)); + co64->offsets = (u64*)gf_malloc(co64->nb_entries * sizeof(u64)); if (!co64) { gf_isom_box_del((GF_Box *)co64); return GF_OUT_OF_MEM; @@ -348,7 +348,7 @@ GF_Err WriteSample(MovieWriter *mw, u32 size, u64 offset, u8 isEdited, GF_BitStr u32 bytes; if (size>mw->size) { - mw->buffer = (char*)realloc(mw->buffer, size); + mw->buffer = (char*)gf_realloc(mw->buffer, size); mw->size = size; } @@ -432,7 +432,7 @@ GF_Err DoWriteMeta(GF_ISOFile *file, GF_MetaBox *meta, GF_BitStream *bs, Bool Em u64 remain = entry->extent_length; while (remain) { u32 size_cache = (remain>4096) ? 4096 : (u32) remain; - fread(cache_data, 1, size_cache, src); + size_cache = fread(cache_data, sizeof(char), size_cache, src); gf_bs_write_data(bs, cache_data, size_cache); remain -= size_cache; } @@ -795,7 +795,7 @@ exit: return e; } -GF_Err DoFullInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emulation, u32 StartOffset) +GF_Err DoFullInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emulation, u64 StartOffset) { u32 i, tracksDone; @@ -922,7 +922,7 @@ GF_Err DoFullInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 /*uncomment the following to easily test large file generation. This will prepend 4096*1MByte of 0 before the media data*/ //#define TEST_LARGE_FILES -GF_Err DoInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emulation, u32 StartOffset, Bool drift_inter) +GF_Err DoInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emulation, u64 StartOffset, Bool drift_inter) { u32 i, tracksDone; TrackWriter *tmp, *curWriter; @@ -943,7 +943,7 @@ GF_Err DoInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emul char *blank; u32 count, i; i = count = 0; - blank = malloc(sizeof(char)*1024*1024); + blank = gf_malloc(sizeof(char)*1024*1024); memset(blank, 0, sizeof(char)*1024*1024); count = 4096; memset(blank, 0, sizeof(char)*1024*1024); @@ -953,7 +953,7 @@ GF_Err DoInterleave(MovieWriter *mw, GF_List *writers, GF_BitStream *bs, u8 Emul i++; fprintf(stdout, "writing blank block: %.02f done - %d/%d \r", (100.0*i)/count , i, count); } - free(blank); + gf_free(blank); } mdatSize = 4096*1024; mdatSize *= 1024; @@ -1160,7 +1160,7 @@ static GF_Err WriteInterleaved(MovieWriter *mw, GF_BitStream *bs, Bool drift_int if (e) goto exit; } - e = DoInterleave(mw, writers, bs, 1, (u32) gf_bs_get_position(bs), drift_inter); + e = DoInterleave(mw, writers, bs, 1, gf_bs_get_position(bs), drift_inter); if (e) goto exit; firstSize = GetMoovAndMetaSize(movie, writers); @@ -1272,7 +1272,7 @@ GF_Err WriteToFile(GF_ISOFile *movie) gf_bs_del(bs); fclose(stream); } - if (mw.buffer) free(mw.buffer); + if (mw.buffer) gf_free(mw.buffer); if (mw.nb_done<mw.total_samples) { gf_set_progress("ISO File Writing", mw.total_samples, mw.total_samples); } @@ -1281,5 +1281,4 @@ GF_Err WriteToFile(GF_ISOFile *movie) -#endif //GPAC_READ_ONLY - +#endif /*!defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_WRITE)*/ diff --git a/src/isomedia/isom_write.c b/src/isomedia/isom_write.c index 9444c89..6cddaad 100644 --- a/src/isomedia/isom_write.c +++ b/src/isomedia/isom_write.c @@ -24,14 +24,14 @@ #include <gpac/internal/isomedia_dev.h> -#ifndef GPAC_READ_ONLY +#if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_WRITE) GF_Err CanAccessMovie(GF_ISOFile *movie, u32 Mode) { if (!movie) return GF_BAD_PARAM; if (movie->openMode < Mode) return GF_ISOM_INVALID_MODE; -#ifndef GF_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS if (movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY) return GF_ISOM_INVALID_MODE; #endif return GF_OK; @@ -189,6 +189,28 @@ GF_Err gf_isom_remove_track_from_root_od(GF_ISOFile *movie, u32 trackNumber) return GF_OK; } +GF_EXPORT +GF_Err gf_isom_set_creation_time(GF_ISOFile *movie, u64 time) +{ + if (!movie || !movie->moov) return GF_BAD_PARAM; + movie->moov->mvhd->creationTime = time; + movie->moov->mvhd->modificationTime = time; + return GF_OK; +} + +GF_EXPORT +GF_Err gf_isom_set_track_creation_time(GF_ISOFile *movie,u32 trackNumber, u64 time) +{ + GF_TrackBox *trak; + trak = gf_isom_get_track_from_file(movie, trackNumber); + if (!trak) return GF_BAD_PARAM; + + trak->Header->creationTime = time; + trak->Header->modificationTime = time; + return GF_OK; +} + + //sets the enable flag of a track GF_EXPORT GF_Err gf_isom_set_track_enabled(GF_ISOFile *movie, u32 trackNumber, u8 enableTrack) @@ -236,7 +258,7 @@ static void gf_isom_set_root_iod(GF_ISOFile *movie) //if OD, switch to IOD if (movie->moov->iods->descriptor->tag == GF_ODF_ISOM_IOD_TAG) return; od = (GF_IsomObjectDescriptor *) movie->moov->iods->descriptor; - iod = (GF_IsomInitialObjectDescriptor*)malloc(sizeof(GF_IsomInitialObjectDescriptor)); + iod = (GF_IsomInitialObjectDescriptor*)gf_malloc(sizeof(GF_IsomInitialObjectDescriptor)); memset(iod, 0, sizeof(GF_IsomInitialObjectDescriptor)); iod->ES_ID_IncDescriptors = od->ES_ID_IncDescriptors; @@ -370,12 +392,12 @@ GF_Err gf_isom_set_root_od_url(GF_ISOFile *movie, char *url_string) if (!movie->moov->iods) AddMovieIOD(movie->moov, 0); switch (movie->moov->iods->descriptor->tag) { case GF_ODF_ISOM_OD_TAG: - if (((GF_IsomObjectDescriptor *)movie->moov->iods->descriptor)->URLString) free(((GF_IsomObjectDescriptor *)movie->moov->iods->descriptor)->URLString); - ((GF_IsomObjectDescriptor *)movie->moov->iods->descriptor)->URLString = url_string ? strdup(url_string) : NULL; + if (((GF_IsomObjectDescriptor *)movie->moov->iods->descriptor)->URLString) gf_free(((GF_IsomObjectDescriptor *)movie->moov->iods->descriptor)->URLString); + ((GF_IsomObjectDescriptor *)movie->moov->iods->descriptor)->URLString = url_string ? gf_strdup(url_string) : NULL; break; case GF_ODF_ISOM_IOD_TAG: - if (((GF_IsomInitialObjectDescriptor *)movie->moov->iods->descriptor)->URLString) free(((GF_IsomInitialObjectDescriptor *)movie->moov->iods->descriptor)->URLString); - ((GF_IsomInitialObjectDescriptor *)movie->moov->iods->descriptor)->URLString = url_string ? strdup(url_string) : NULL; + if (((GF_IsomInitialObjectDescriptor *)movie->moov->iods->descriptor)->URLString) gf_free(((GF_IsomInitialObjectDescriptor *)movie->moov->iods->descriptor)->URLString); + ((GF_IsomInitialObjectDescriptor *)movie->moov->iods->descriptor)->URLString = url_string ? gf_strdup(url_string) : NULL; break; default: return GF_ISOM_INVALID_FILE; @@ -480,6 +502,7 @@ u32 gf_isom_new_track(GF_ISOFile *movie, u32 trakID, u32 MediaType, u32 TimeScal case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_SCENE: case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: /*320-240 pix in 16.16*/ tkhd->width = 0x01400000; tkhd->height = 0x00F00000; @@ -826,7 +849,7 @@ GF_Err gf_isom_set_last_sample_duration(GF_ISOFile *movie, u32 trackNumber, u32 if (stts->nb_entries==stts->alloc_size) { stts->alloc_size++; - stts->entries = realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); + stts->entries = gf_realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); if (!stts->entries) return GF_OUT_OF_MEM; } stts->entries[stts->nb_entries].sampleCount = 1; @@ -977,8 +1000,8 @@ GF_Err gf_isom_set_final_name(GF_ISOFile *movie, char *filename) if ( (movie->openMode == GF_ISOM_OPEN_EDIT) && movie->fileName && !strcmp(filename, movie->fileName)) return GF_BAD_PARAM; - if (movie->finalName) free(movie->finalName); - movie->finalName = strdup(filename); + if (movie->finalName) gf_free(movie->finalName); + movie->finalName = gf_strdup(filename); if (!movie->finalName) return GF_OUT_OF_MEM; } return GF_OK; @@ -1124,6 +1147,8 @@ GF_Err gf_isom_set_visual_info(GF_ISOFile *movie, u32 trackNumber, u32 StreamDes case GF_ISOM_BOX_TYPE_MP4V: case GF_ISOM_SUBTYPE_3GP_H263: case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: ((GF_VisualSampleEntryBox*)entry)->Width = Width; ((GF_VisualSampleEntryBox*)entry)->Height = Height; trak->Header->width = Width<<16; @@ -1166,6 +1191,8 @@ GF_Err gf_isom_set_pixel_aspect_ratio(GF_ISOFile *movie, u32 trackNumber, u32 St case GF_ISOM_BOX_TYPE_MP4V: case GF_ISOM_SUBTYPE_3GP_H263: case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: break; default: return GF_BAD_PARAM; @@ -1354,7 +1381,7 @@ GF_Err gf_isom_remove_edit_segments(GF_ISOFile *movie, u32 trackNumber) while (gf_list_count(trak->editBox->editList->entryList)) { ent = (GF_EdtsEntry*)gf_list_get(trak->editBox->editList->entryList, 0); - free(ent); + gf_free(ent); e = gf_list_rem(trak->editBox->editList->entryList, 0); if (e) return e; } @@ -1384,7 +1411,7 @@ GF_Err gf_isom_remove_edit_segment(GF_ISOFile *movie, u32 trackNumber, u32 seg_i gf_list_rem(trak->editBox->editList->entryList, seg_index-1); next_ent = (GF_EdtsEntry *)gf_list_get(trak->editBox->editList->entryList, seg_index-1); if (next_ent) next_ent->segmentDuration += ent->segmentDuration; - free(ent); + gf_free(ent); return SetTrackDuration(trak); } @@ -1409,7 +1436,7 @@ GF_Err gf_isom_append_edit_segment(GF_ISOFile *movie, u32 trackNumber, u64 EditD if (!elst) return GF_OUT_OF_MEM; edts_AddBox((GF_Box*)trak->editBox, (GF_Box *)elst); } - ent = (GF_EdtsEntry *)malloc(sizeof(GF_EdtsEntry)); + ent = (GF_EdtsEntry *)gf_malloc(sizeof(GF_EdtsEntry)); if (!ent) return GF_OUT_OF_MEM; ent->segmentDuration = EditDuration; @@ -1547,7 +1574,7 @@ GF_Err gf_isom_remove_track(GF_ISOFile *movie, u32 trackNumber) j--; gf_list_rem(trak->References->boxList, j); } else { - newRefs = (u32*)malloc(sizeof(u32) * (tref->trackIDCount - found)); + newRefs = (u32*)gf_malloc(sizeof(u32) * (tref->trackIDCount - found)); found = 0; for (k = 0; k < tref->trackIDCount; k++) { if (tref->trackIDs[k] != the_trak->Header->trackID) { @@ -1556,7 +1583,7 @@ GF_Err gf_isom_remove_track(GF_ISOFile *movie, u32 trackNumber) found++; } } - free(tref->trackIDs); + gf_free(tref->trackIDs); tref->trackIDs = newRefs; tref->trackIDCount -= found; } @@ -1608,8 +1635,8 @@ GF_Err gf_isom_set_copyright(GF_ISOFile *movie, const char *threeCharCode, char for (i=0; i<count; i++) { ptr = (GF_CopyrightBox*)gf_list_get(map->boxList, i); if (!strcmp(threeCharCode, (const char *) ptr->packedLanguageCode)) { - free(ptr->notice); - ptr->notice = (char*)malloc(sizeof(char) * (strlen(notice) + 1)); + gf_free(ptr->notice); + ptr->notice = (char*)gf_malloc(sizeof(char) * (strlen(notice) + 1)); strcpy(ptr->notice, notice); return GF_OK; } @@ -1619,7 +1646,7 @@ GF_Err gf_isom_set_copyright(GF_ISOFile *movie, const char *threeCharCode, char ptr = (GF_CopyrightBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_CPRT); memcpy(ptr->packedLanguageCode, threeCharCode, 4); - ptr->notice = (char*)malloc(sizeof(char) * (strlen(notice)+1)); + ptr->notice = (char*)gf_malloc(sizeof(char) * (strlen(notice)+1)); strcpy(ptr->notice, notice); return udta_AddBox(movie->moov->udta, (GF_Box *) ptr); } @@ -1671,16 +1698,16 @@ GF_Err gf_isom_add_chapter(GF_ISOFile *movie, u32 trackNumber, u64 timestamp, ch GF_SAFEALLOC(ce, GF_ChapterEntry); ce->start_time = timestamp * 10000L; - ce->name = name ? strdup(name) : NULL; + ce->name = name ? gf_strdup(name) : NULL; /*insert in order*/ count = gf_list_count(ptr->list); for (i=0; i<count; i++) { GF_ChapterEntry *ace = (GF_ChapterEntry *)gf_list_get(ptr->list, i); if (ace->start_time == ce->start_time) { - if (ace->name) free(ace->name); + if (ace->name) gf_free(ace->name); ace->name = ce->name; - free(ce); + gf_free(ce); return GF_OK; } if (ace->start_time >= ce->start_time) @@ -1726,21 +1753,21 @@ GF_Err gf_isom_remove_chapter(GF_ISOFile *movie, u32 trackNumber, u32 index) if (index) { ce = (GF_ChapterEntry *)gf_list_get(ptr->list, index-1); if (!ce) return GF_BAD_PARAM; - if (ce->name) free(ce->name); - free(ce); + if (ce->name) gf_free(ce->name); + gf_free(ce); gf_list_rem(ptr->list, index-1); } else { while (gf_list_count(ptr->list)) { ce = (GF_ChapterEntry *)gf_list_get(ptr->list, 0); - if (ce->name) free(ce->name); - free(ce); + if (ce->name) gf_free(ce->name); + gf_free(ce); gf_list_rem(ptr->list, 0); } } if (!gf_list_count(ptr->list)) { gf_list_del_item(udta->recordList, map); gf_isom_box_array_del(map->boxList); - free(map); + gf_free(map); } return GF_OK; } @@ -1768,14 +1795,14 @@ GF_Err gf_isom_remove_copyright(GF_ISOFile *movie, u32 index) ptr = (GF_CopyrightBox*)gf_list_get(map->boxList, index-1); if (ptr) { gf_list_rem(map->boxList, index-1); - if (ptr->notice) free(ptr->notice); - free(ptr); + if (ptr->notice) gf_free(ptr->notice); + gf_free(ptr); } /*last copyright, remove*/ if (!gf_list_count(map->boxList)) { gf_list_del_item(movie->moov->udta->recordList, map); gf_list_del(map->boxList); - free(map); + gf_free(map); } return GF_OK; } @@ -1801,8 +1828,8 @@ GF_Err gf_isom_set_watermark(GF_ISOFile *movie, bin128 UUID, u8* data, u32 lengt if (map) { ptr = (GF_UnknownUUIDBox *)gf_list_get(map->boxList, 0); if (ptr) { - free(ptr->data); - ptr->data = (char*)malloc(length); + gf_free(ptr->data); + ptr->data = (char*)gf_malloc(length); memcpy(ptr->data, data, length); ptr->dataSize = length; return GF_OK; @@ -1811,7 +1838,7 @@ GF_Err gf_isom_set_watermark(GF_ISOFile *movie, bin128 UUID, u8* data, u32 lengt //nope, create one ptr = (GF_UnknownUUIDBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_UUID); memcpy(ptr->uuid, UUID, 16); - ptr->data = (char*)malloc(length); + ptr->data = (char*)gf_malloc(length); memcpy(ptr->data, data, length); ptr->dataSize = length; return udta_AddBox(movie->moov->udta, (GF_Box *) ptr); @@ -1884,7 +1911,7 @@ GF_Err gf_isom_use_compact_size(GF_ISOFile *movie, u32 trackNumber, u8 Compactio } } if (size) { - free(stsz->sizes); + gf_free(stsz->sizes); stsz->sizes = NULL; stsz->sampleSize = size; } @@ -1898,8 +1925,8 @@ GF_Err gf_isom_use_compact_size(GF_ISOFile *movie, u32 trackNumber, u8 Compactio //at write time if all samples are of same size if (stsz->sampleSize) { //this is a weird table indeed ;) - if (stsz->sizes) free(stsz->sizes); - stsz->sizes = (u32*) malloc(sizeof(u32)*stsz->sampleCount); + if (stsz->sizes) gf_free(stsz->sizes); + stsz->sizes = (u32*) gf_malloc(sizeof(u32)*stsz->sampleCount); memset(stsz->sizes, stsz->sampleSize, sizeof(u32)); } //set the SampleSize to 0 while the file is open @@ -1933,7 +1960,7 @@ GF_Err gf_isom_set_brand_info(GF_ISOFile *movie, u32 MajorBrand, u32 MinorVersio movie->brand->minorVersion = MinorVersion; if (!movie->brand->altBrand) { - movie->brand->altBrand = (u32*)malloc(sizeof(u32)); + movie->brand->altBrand = (u32*)gf_malloc(sizeof(u32)); movie->brand->altBrand[0] = MajorBrand; movie->brand->altCount = 1; return GF_OK; @@ -1943,12 +1970,12 @@ GF_Err gf_isom_set_brand_info(GF_ISOFile *movie, u32 MajorBrand, u32 MinorVersio for (i=0; i<movie->brand->altCount; i++) { if (movie->brand->altBrand[i] == MajorBrand) return GF_OK; } - p = (u32*)malloc(sizeof(u32)*(movie->brand->altCount + 1)); + p = (u32*)gf_malloc(sizeof(u32)*(movie->brand->altCount + 1)); if (!p) return GF_OUT_OF_MEM; memcpy(p, movie->brand->altBrand, sizeof(u32)*movie->brand->altCount); p[movie->brand->altCount] = MajorBrand; movie->brand->altCount += 1; - free(movie->brand->altBrand); + gf_free(movie->brand->altBrand); movie->brand->altBrand = p; return GF_OK; } @@ -1986,12 +2013,12 @@ GF_Err gf_isom_modify_alternate_brand(GF_ISOFile *movie, u32 Brand, u8 AddIt) //Not found if (!AddIt) return GF_OK; //add it - p = (u32*)malloc(sizeof(u32)*(movie->brand->altCount + 1)); + p = (u32*)gf_malloc(sizeof(u32)*(movie->brand->altCount + 1)); if (!p) return GF_OUT_OF_MEM; memcpy(p, movie->brand->altBrand, sizeof(u32)*movie->brand->altCount); p[movie->brand->altCount] = Brand; movie->brand->altCount += 1; - free(movie->brand->altBrand); + gf_free(movie->brand->altBrand); movie->brand->altBrand = p; return GF_OK; @@ -2002,7 +2029,7 @@ found: assert(movie->brand->altCount>1); //remove it - p = (u32*)malloc(sizeof(u32)*(movie->brand->altCount - 1)); + p = (u32*)gf_malloc(sizeof(u32)*(movie->brand->altCount - 1)); if (!p) return GF_OUT_OF_MEM; k = 0; for (i=0; i<movie->brand->altCount; i++) { @@ -2013,7 +2040,7 @@ found: } } movie->brand->altCount -= 1; - free(movie->brand->altBrand); + gf_free(movie->brand->altBrand); movie->brand->altBrand = p; return GF_OK; } @@ -2034,11 +2061,11 @@ GF_Err gf_isom_reset_alt_brands(GF_ISOFile *movie) movie->brand = (GF_FileTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FTYP); gf_list_add(movie->TopBoxes, movie->brand); } - p = (u32*)malloc(sizeof(u32)); + p = (u32*)gf_malloc(sizeof(u32)); if (!p) return GF_OUT_OF_MEM; p[0] = movie->brand->majorBrand; movie->brand->altCount = 1; - free(movie->brand->altBrand); + gf_free(movie->brand->altBrand); movie->brand->altBrand = p; return GF_OK; } @@ -2106,7 +2133,7 @@ found: if (!gf_list_count(map->boxList)) { gf_list_rem(udta->recordList, i-1); gf_isom_box_array_del(map->boxList); - free(map); + gf_free(map); } //but we keep the UDTA no matter what return GF_OK; @@ -2148,7 +2175,7 @@ found: gf_list_rem(udta->recordList, i-1); gf_isom_box_array_del(map->boxList); - free(map); + gf_free(map); //but we keep the UDTA no matter what return GF_OK; @@ -2185,7 +2212,7 @@ GF_Err gf_isom_add_user_data(GF_ISOFile *movie, u32 trackNumber, u32 UserDataTyp memcpy( ((GF_UUIDBox*)a)->uuid, UUID, 16); } - a->data = (char*)malloc(sizeof(char)*DataLength); + a->data = (char*)gf_malloc(sizeof(char)*DataLength); memcpy(a->data, data, DataLength); a->dataSize = DataLength; @@ -2264,6 +2291,76 @@ 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 e; + char *data; + u32 data_size; + GF_BitStream *bs; + + if (*dst) { + gf_isom_box_del(*dst); + *dst=NULL; + } + bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + if (!bs) return GF_OUT_OF_MEM; + e = gf_isom_box_size( (GF_Box *) src); + if (!e) e = gf_isom_box_write((GF_Box *) src, bs); + gf_bs_get_content(bs, &data, &data_size); + gf_bs_del(bs); + if (e) return e; + bs = gf_bs_new(data, data_size, GF_BITSTREAM_READ); + if (!bs) return GF_OUT_OF_MEM; + e = gf_isom_parse_box(dst, bs); + gf_bs_del(bs); + gf_free(data); + return e; +} +GF_Err gf_isom_clone_movie(GF_ISOFile *orig_file, GF_ISOFile *dest_file, Bool clone_tracks, Bool keep_hint_tracks) +{ + GF_Err e; + + e = CanAccessMovie(dest_file, GF_ISOM_OPEN_WRITE); + if (e) return e; + + if (orig_file->brand) + clone_box((GF_Box *)orig_file->brand, (GF_Box **)&dest_file->brand); + + if (orig_file->meta) { + /*fixme - check imports*/ + clone_box((GF_Box *)orig_file->meta, (GF_Box **)dest_file->meta); + } + if (orig_file->moov) { + u32 i, dstTrack; + GF_Box *iods; + GF_List *tracks = gf_list_new(); + GF_List *old_tracks = orig_file->moov->trackList; + 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); + orig_file->moov->trackList = old_tracks; + gf_list_del(tracks); + orig_file->moov->iods = (GF_ObjectDescriptorBox*)iods; + if (clone_tracks) { + for (i=0; i<gf_list_count(orig_file->moov->trackList); i++) { + GF_TrackBox *trak = gf_list_get( orig_file->moov->trackList, i); + if (!trak) continue; + if (keep_hint_tracks || (trak->Media->handler->handlerType != GF_ISOM_MEDIA_HINT)) { + e = gf_isom_clone_track(orig_file, i+1, dest_file, 1, &dstTrack); + if (e) return e; + } + } + if (iods) + 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); + } + } + return GF_OK; +} + GF_Err gf_isom_clone_track(GF_ISOFile *orig_file, u32 orig_track, GF_ISOFile *dest_file, Bool keep_data_ref, u32 *dest_track) @@ -2299,7 +2396,7 @@ GF_Err gf_isom_clone_track(GF_ISOFile *orig_file, u32 orig_track, GF_ISOFile *de bs = gf_bs_new(data, data_size, GF_BITSTREAM_READ); e = gf_isom_parse_box((GF_Box **) &new_tk, bs); gf_bs_del(bs); - free(data); + gf_free(data); trak->Media->information->sampleTable = stbl; stbl_temp->SampleDescription = NULL; @@ -2326,6 +2423,7 @@ GF_Err gf_isom_clone_track(GF_ISOFile *orig_file, u32 orig_track, GF_ISOFile *de moov_AddBox((GF_Box*)dest_file->moov, (GF_Box *)new_tk); + /*rewrite edit list segmentDuration to new movie timescale*/ ts_scale = dest_file->moov->mvhd->timeScale; ts_scale /= orig_file->moov->mvhd->timeScale; new_tk->Header->duration = (u64) (s64) ((s64) new_tk->Header->duration * ts_scale); @@ -2334,7 +2432,6 @@ GF_Err gf_isom_clone_track(GF_ISOFile *orig_file, u32 orig_track, GF_ISOFile *de for (i=0; i<count; i++) { GF_EdtsEntry *ent = (GF_EdtsEntry *)gf_list_get(new_tk->editBox->editList->entryList, i); ent->segmentDuration = (u64) (s64) ((s64) ent->segmentDuration * ts_scale); - ent->mediaTime = (s64) (ent->mediaTime * ts_scale); } } @@ -2389,7 +2486,7 @@ GF_Err gf_isom_clone_sample_description(GF_ISOFile *the_file, u32 trackNumber, G bs = gf_bs_new(data, data_size, GF_BITSTREAM_READ); e = gf_isom_parse_box(&entry, bs); gf_bs_del(bs); - free(data); + gf_free(data); if (e) return e; /*get new track and insert clone*/ @@ -2469,7 +2566,7 @@ GF_Err gf_isom_new_generic_sample_description(GF_ISOFile *movie, u32 trackNumber entry->vert_res = udesc->v_res ? udesc->v_res : 0x00480000; entry->bit_depth = udesc->depth ? udesc->depth : 0x18; if (udesc->extension_buf && udesc->extension_buf_size) { - entry->data = (char*)malloc(sizeof(char) * udesc->extension_buf_size); + entry->data = (char*)gf_malloc(sizeof(char) * udesc->extension_buf_size); if (!entry->data) { gf_isom_box_del((GF_Box *) entry); return GF_OUT_OF_MEM; @@ -2501,7 +2598,7 @@ GF_Err gf_isom_new_generic_sample_description(GF_ISOFile *movie, u32 trackNumber gena->samplerate_lo = udesc->samplerate & 0xFF; if (udesc->extension_buf && udesc->extension_buf_size) { - gena->data = (char*)malloc(sizeof(char) * udesc->extension_buf_size); + gena->data = (char*)gf_malloc(sizeof(char) * udesc->extension_buf_size); if (!gena->data) { gf_isom_box_del((GF_Box *) gena); return GF_OUT_OF_MEM; @@ -2525,7 +2622,7 @@ GF_Err gf_isom_new_generic_sample_description(GF_ISOFile *movie, u32 trackNumber } genm->dataReferenceIndex = dataRefIndex; if (udesc->extension_buf && udesc->extension_buf_size) { - genm->data = (char*)malloc(sizeof(char) * udesc->extension_buf_size); + genm->data = (char*)gf_malloc(sizeof(char) * udesc->extension_buf_size); if (!genm->data) { gf_isom_box_del((GF_Box *) genm); return GF_OUT_OF_MEM; @@ -2569,11 +2666,11 @@ GF_Err gf_isom_change_generic_sample_description(GF_ISOFile *movie, u32 trackNum entry->horiz_res = udesc->h_res ? udesc->h_res : 0x00480000; entry->vert_res = udesc->v_res ? udesc->v_res : 0x00480000; entry->bit_depth = udesc->depth ? udesc->depth : 0x18; - if (entry->data) free(entry->data); + if (entry->data) gf_free(entry->data); entry->data = NULL; entry->data_size = 0; if (udesc->extension_buf && udesc->extension_buf_size) { - entry->data = (char*)malloc(sizeof(char) * udesc->extension_buf_size); + entry->data = (char*)gf_malloc(sizeof(char) * udesc->extension_buf_size); if (!entry->data) { gf_isom_box_del((GF_Box *) entry); return GF_OUT_OF_MEM; @@ -2591,12 +2688,12 @@ GF_Err gf_isom_change_generic_sample_description(GF_ISOFile *movie, u32 trackNum gena->channel_count = udesc->nb_channels ? udesc->nb_channels : 2; gena->samplerate_hi = udesc->samplerate>>16; gena->samplerate_lo = udesc->samplerate & 0xFF; - if (gena->data) free(gena->data); + if (gena->data) gf_free(gena->data); gena->data = NULL; gena->data_size = 0; if (udesc->extension_buf && udesc->extension_buf_size) { - gena->data = (char*)malloc(sizeof(char) * udesc->extension_buf_size); + gena->data = (char*)gf_malloc(sizeof(char) * udesc->extension_buf_size); if (!gena->data) { gf_isom_box_del((GF_Box *) gena); return GF_OUT_OF_MEM; @@ -2607,12 +2704,12 @@ GF_Err gf_isom_change_generic_sample_description(GF_ISOFile *movie, u32 trackNum return GF_OK; } else if (entry->type == GF_ISOM_BOX_TYPE_GNRM) { GF_GenericSampleEntryBox *genm = (GF_GenericSampleEntryBox *)entry; - if (genm->data) free(genm->data); + if (genm->data) gf_free(genm->data); genm->data = NULL; genm->data_size = 0; if (udesc->extension_buf && udesc->extension_buf_size) { - genm->data = (char*)malloc(sizeof(char) * udesc->extension_buf_size); + genm->data = (char*)gf_malloc(sizeof(char) * udesc->extension_buf_size); if (!genm->data) { gf_isom_box_del((GF_Box *) genm); return GF_OUT_OF_MEM; @@ -2705,14 +2802,14 @@ GF_Err gf_isom_remove_track_reference(GF_ISOFile *the_file, u32 trackNumber, u32 } } k = 0; - newIDs = (u32*)malloc(sizeof(u32)*(dpnd->trackIDCount-1)); + newIDs = (u32*)gf_malloc(sizeof(u32)*(dpnd->trackIDCount-1)); for (i=0; i<dpnd->trackIDCount; i++) { if (i+1 != ReferenceIndex) { newIDs[k] = dpnd->trackIDs[i]; k++; } } - free(dpnd->trackIDs); + gf_free(dpnd->trackIDs); dpnd->trackIDCount -= 1; dpnd->trackIDs = newIDs; return GF_OK; @@ -2805,6 +2902,15 @@ GF_Err gf_isom_set_cts_packing(GF_ISOFile *the_file, u32 trackNumber, Bool unpac return SetTrackDuration(trak); } +GF_EXPORT +GF_Err gf_isom_set_track_matrix(GF_ISOFile *the_file, u32 trackNumber, u32 matrix[9]) +{ + GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber); + if (!trak || !trak->Header) return GF_BAD_PARAM; + memcpy(trak->Header->matrix, matrix, sizeof(trak->Header->matrix)); + return GF_OK; +} + GF_Err gf_isom_set_track_layout_info(GF_ISOFile *the_file, u32 trackNumber, u32 width, u32 height, s32 translation_x, s32 translation_y, s16 layer) { GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber); @@ -2821,9 +2927,9 @@ GF_Err gf_isom_set_track_name(GF_ISOFile *the_file, u32 trackNumber, char *name) { GF_TrackBox *trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return GF_BAD_PARAM; - if (trak->name) free (trak->name); + if (trak->name) gf_free(trak->name); trak->name = NULL; - if (name) trak->name = strdup(name); + if (name) trak->name = gf_strdup(name); return GF_OK; } const char *gf_isom_get_track_name(GF_ISOFile *the_file, u32 trackNumber) @@ -2856,7 +2962,7 @@ GF_Err gf_isom_store_movie_config(GF_ISOFile *movie, Bool remove_all) gf_bs_get_content(bs, &data, &len); gf_bs_del(bs); gf_isom_add_user_data(movie, 0, GF_4CC('G','P','A','C'), binID, data, len); - free(data); + gf_free(data); /*update tracks: interleaving group/priority and track edit name*/ for (i=0; i<count; i++) { u32 j; @@ -2871,7 +2977,7 @@ GF_Err gf_isom_store_movie_config(GF_ISOFile *movie, Bool remove_all) gf_bs_get_content(bs, &data, &len); gf_bs_del(bs); gf_isom_add_user_data(movie, i+1, GF_4CC('G','P','A','C'), binID, data, len); - free(data); + gf_free(data); } return GF_OK; } @@ -2895,7 +3001,7 @@ GF_Err gf_isom_load_movie_config(GF_ISOFile *movie) if (!data) continue; /*check marker*/ if ((unsigned char) data[0] != 0xFE) { - free(data); + gf_free(data); continue; } bs = gf_bs_new(data, len, GF_BITSTREAM_READ); @@ -2903,7 +3009,7 @@ GF_Err gf_isom_load_movie_config(GF_ISOFile *movie) movie->storageMode = gf_bs_read_u8(bs); movie->interleavingTime = gf_bs_read_u32(bs); gf_bs_del(bs); - free(data); + gf_free(data); found_cfg = 1; break; } @@ -2918,7 +3024,7 @@ GF_Err gf_isom_load_movie_config(GF_ISOFile *movie) if (!data) continue; /*check marker*/ if ((unsigned char) data[0] != 0xFE) { - free(data); + gf_free(data); continue; } bs = gf_bs_new(data, len, GF_BITSTREAM_READ); @@ -2928,12 +3034,12 @@ GF_Err gf_isom_load_movie_config(GF_ISOFile *movie) len = gf_bs_read_u32(bs); if (len) { u32 k; - trak->name = (char*)malloc(sizeof(char)*(len+1)); + trak->name = (char*)gf_malloc(sizeof(char)*(len+1)); for (k=0;k<len;k++) trak->name[k] = gf_bs_read_u8(bs); trak->name[k] = 0; } gf_bs_del(bs); - free(data); + gf_free(data); found_cfg = 1; break; } @@ -3011,6 +3117,8 @@ Bool gf_isom_is_same_sample_description(GF_ISOFile *f1, u32 tk1, GF_ISOFile *f2, if (memcmp(esd1->decoderConfig->decoderSpecificInfo->data, esd2->decoderConfig->decoderSpecificInfo->data, sizeof(char)*esd1->decoderConfig->decoderSpecificInfo->dataLength)!=0) return 0; break; case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: { GF_MPEGVisualSampleEntryBox *avc1 = (GF_MPEGVisualSampleEntryBox *)ent1; GF_MPEGVisualSampleEntryBox *avc2 = (GF_MPEGVisualSampleEntryBox *)ent2; @@ -3034,11 +3142,25 @@ Bool gf_isom_is_same_sample_description(GF_ISOFile *f1, u32 tk1, GF_ISOFile *f2, if (data1_size == data2_size) { ret = (memcmp(data1, data2, sizeof(char)*data1_size)==0) ? 1 : 0; } - free(data1); - free(data2); + gf_free(data1); + gf_free(data2); return ret; } break; + case GF_ISOM_BOX_TYPE_LSR1: + { + GF_LASeRSampleEntryBox *lsr1 = (GF_LASeRSampleEntryBox *)ent1; + GF_LASeRSampleEntryBox *lsr2 = (GF_LASeRSampleEntryBox *)ent2; + if (lsr1->lsr_config && lsr2->lsr_config + && lsr1->lsr_config->hdr && lsr2->lsr_config->hdr + && (lsr1->lsr_config->hdr_size==lsr2->lsr_config->hdr_size) + && !memcmp(lsr1->lsr_config->hdr, lsr2->lsr_config->hdr, lsr2->lsr_config->hdr_size) + ) { + return 1; + } + return 0; + } + break; } } if (!need_memcmp) return 1; @@ -3063,8 +3185,8 @@ Bool gf_isom_is_same_sample_description(GF_ISOFile *f1, u32 tk1, GF_ISOFile *f2, if (data1_size == data2_size) { ret = (memcmp(data1, data2, sizeof(char)*data1_size)==0) ? 1 : 0; } - free(data1); - free(data2); + gf_free(data1); + gf_free(data2); return ret; } @@ -3298,29 +3420,32 @@ GF_Err gf_isom_set_handler_name(GF_ISOFile *the_file, u32 trackNumber, const cha GF_TrackBox *trak; trak = gf_isom_get_track_from_file(the_file, trackNumber); if (!trak) return GF_BAD_PARAM; - if (trak->Media->handler->nameUTF8) free(trak->Media->handler->nameUTF8); + if (trak->Media->handler->nameUTF8) gf_free(trak->Media->handler->nameUTF8); trak->Media->handler->nameUTF8 = NULL; if (!nameUTF8) return GF_OK; if (!strnicmp(nameUTF8, "file://", 7)) { u8 BOM[4]; - FILE *f = fopen(nameUTF8+7, "rb"); - u32 size; + FILE *f = gf_f64_open(nameUTF8+7, "rb"); + u64 size; if (!f) return GF_URL_ERROR; - fseek(f, 0, SEEK_END); - size = ftell(f); - fseek(f, 0, SEEK_SET); - fread(BOM, 1, 3, f); + gf_f64_seek(f, 0, SEEK_END); + size = gf_f64_tell(f); + gf_f64_seek(f, 0, SEEK_SET); + if (3!=fread(BOM, sizeof(char), 3, f)){ + fclose(f); + return GF_CORRUPTED_DATA; + } /*skip BOM if any*/ if ((BOM[0]==0xEF) && (BOM[1]==0xBB) && (BOM[2]==0xBF)) size -= 3; else if ((BOM[0]==0xEF) || (BOM[0]==0xFF)) { fclose(f); return GF_BAD_PARAM; } - else fseek(f, 0, SEEK_SET); - trak->Media->handler->nameUTF8 = (char*)malloc(sizeof(char)*(size+1)); - fread(trak->Media->handler->nameUTF8, 1, size, f); + else gf_f64_seek(f, 0, SEEK_SET); + trak->Media->handler->nameUTF8 = (char*)gf_malloc(sizeof(char)*(size_t)(size+1)); + size = fread(trak->Media->handler->nameUTF8, sizeof(char), (size_t)size, f); trak->Media->handler->nameUTF8[size] = 0; fclose(f); } else { @@ -3357,7 +3482,7 @@ GF_Err gf_isom_set_handler_name(GF_ISOFile *the_file, u32 trackNumber, const cha j++; } szLine[j] = 0; - trak->Media->handler->nameUTF8 = strdup(szLine); + trak->Media->handler->nameUTF8 = gf_strdup(szLine); } return GF_OK; } @@ -3399,6 +3524,28 @@ GF_Err gf_isom_clone_root_od(GF_ISOFile *input, GF_ISOFile *output) return GF_OK; } +GF_EXPORT +GF_Err gf_isom_set_media_type(GF_ISOFile *movie, u32 trackNumber, u32 new_type) +{ + GF_TrackBox *trak = gf_isom_get_track_from_file(movie, trackNumber); + if (!trak || !new_type) return GF_BAD_PARAM; + trak->Media->handler->handlerType = new_type; + return GF_OK; +} + +GF_EXPORT +GF_Err gf_isom_set_media_subtype(GF_ISOFile *movie, u32 trackNumber, u32 sampleDescriptionIndex, u32 new_type) +{ + GF_SampleEntryBox*entry; + 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); + if (!entry) return GF_BAD_PARAM; + entry->type = new_type; + return GF_OK; +} + GF_EXPORT GF_Err gf_isom_set_JPEG2000(GF_ISOFile *mov, Bool set_on) @@ -3462,7 +3609,7 @@ GF_Err gf_isom_add_uuid(GF_ISOFile *movie, u32 trackNumber, bin128 UUID, char *d uuid->type = GF_ISOM_BOX_TYPE_UUID; memcpy(uuid->uuid, UUID, sizeof(bin128)); uuid->dataSize = data_size; - uuid->data = (char*)malloc(sizeof(char)*data_size); + uuid->data = (char*)gf_malloc(sizeof(char)*data_size); memcpy(uuid->data, data, sizeof(char)*data_size); gf_list_add(list, uuid); return GF_OK; @@ -3530,7 +3677,7 @@ GF_Err gf_isom_apple_set_tag(GF_ISOFile *mov, u32 tag, const char *data, u32 dat } } info->data->dataSize = data_len; - info->data->data = (char*)malloc(sizeof(char)*data_len); + info->data->data = (char*)gf_malloc(sizeof(char)*data_len); memcpy(info->data->data , data, sizeof(char)*data_len); } else if (data_len && (tag==GF_ISOM_ITUNE_GENRE)) { @@ -3544,7 +3691,7 @@ GF_Err gf_isom_apple_set_tag(GF_ISOFile *mov, u32 tag, const char *data, u32 dat } else if (data_len && (tag==GF_ISOM_ITUNE_COMPILATION)) { info = (GF_ListItemBox *)gf_isom_box_new(btype); if (info == NULL) return GF_OUT_OF_MEM; - info->data->data = (char*)malloc(sizeof(char)); + info->data->data = (char*)gf_malloc(sizeof(char)); info->data->data[0] = 1; info->data->dataSize = 1; info->data->flags = 21; @@ -3569,6 +3716,7 @@ GF_Err gf_isom_set_alternate_group_id(GF_ISOFile *movie, u32 trackNumber, u32 gr return GF_OK; } + GF_EXPORT GF_Err gf_isom_set_track_switch_parameter(GF_ISOFile *movie, u32 trackNumber, u32 trackRefGroup, Bool is_switch_group, u32 *switchGroupID, u32 *criteriaList, u32 criteriaListCount) { @@ -3658,8 +3806,8 @@ GF_Err gf_isom_set_track_switch_parameter(GF_ISOFile *movie, u32 trackNumber, u3 tsel->switchGroup = *switchGroupID; tsel->attributeListCount = criteriaListCount; - if (tsel->attributeList) free(tsel->attributeList); - tsel->attributeList = malloc(sizeof(u32)*criteriaListCount); + if (tsel->attributeList) gf_free(tsel->attributeList); + tsel->attributeList = gf_malloc(sizeof(u32)*criteriaListCount); memcpy(tsel->attributeList, criteriaList, sizeof(u32)*criteriaListCount); } return GF_OK; @@ -3673,7 +3821,7 @@ void reset_tsel_box(GF_TrackBox *trak) if (map) { gf_list_del_item(trak->udta->recordList, map); gf_isom_box_array_del(map->boxList); - free(map); + gf_free(map); } } @@ -3747,15 +3895,15 @@ GF_Err gf_isom_timed_meta_data_config_new(GF_ISOFile *movie, u32 trackNumber, Bo if (!metad) return GF_OUT_OF_MEM; metad->dataReferenceIndex = dataRefIndex; - metad->mime_type_or_namespace = strdup(mime_or_namespace); - if (content_encoding) metad->content_encoding = strdup(content_encoding); - if (schema_loc) metad->xml_schema_loc = strdup(schema_loc); + metad->mime_type_or_namespace = gf_strdup(mime_or_namespace); + 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); return e; } -#endif //GPAC_READ_ONLY +#endif /*!defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_ISOM_WRITE)*/ diff --git a/src/isomedia/media.c b/src/isomedia/media.c index 89888b0..39f7f53 100644 --- a/src/isomedia/media.c +++ b/src/isomedia/media.c @@ -23,6 +23,9 @@ */ #include <gpac/internal/isomedia_dev.h> +#include <gpac/constants.h> + +#ifndef GPAC_DISABLE_ISOM GF_Err Media_GetSampleDesc(GF_MediaBox *mdia, u32 SampleDescIndex, GF_SampleEntryBox **out_entry, u32 *dataRefIndex) { @@ -72,11 +75,11 @@ static GF_Err gf_isom_get_3gpp_audio_esd(GF_SampleTableBox *stbl, GF_GenericAudi char szName[80]; (*out_esd) = gf_odf_desc_esd_new(2); - (*out_esd)->decoderConfig->streamType = 0x05; + (*out_esd)->decoderConfig->streamType = GF_STREAM_AUDIO; /*official mapping to MPEG-4*/ switch (entry->type) { case GF_ISOM_SUBTYPE_3GP_EVRC: - (*out_esd)->decoderConfig->objectTypeIndication = 0xA0; + (*out_esd)->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_EVRC_VOICE; return GF_OK; case GF_ISOM_SUBTYPE_3GP_QCELP: { @@ -84,7 +87,7 @@ static GF_Err gf_isom_get_3gpp_audio_esd(GF_SampleTableBox *stbl, GF_GenericAudi GF_SttsEntry *ent; /*only map CBR*/ sample_size = stbl->SampleSize->sampleSize; - (*out_esd)->decoderConfig->objectTypeIndication = 0xE1; + (*out_esd)->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_13K_VOICE; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_data(bs, "QLCMfmt ", 8); gf_bs_write_u32_le(bs, 150);/*fmt chunk size*/ @@ -123,13 +126,13 @@ static GF_Err gf_isom_get_3gpp_audio_esd(GF_SampleTableBox *stbl, GF_GenericAudi } return GF_OK; case GF_ISOM_SUBTYPE_3GP_SMV: - (*out_esd)->decoderConfig->objectTypeIndication = 0xA1; + (*out_esd)->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_SMV_VOICE; return GF_OK; default: break; } /*this is a user-reserved used in gpac - we need a std OTI for AMR/AMRWB*/ - (*out_esd)->decoderConfig->objectTypeIndication = 0x80; + (*out_esd)->decoderConfig->objectTypeIndication = GPAC_OTI_MEDIA_GENERIC; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, entry->type); gf_bs_write_u16(bs, entry->samplerate_hi); @@ -168,6 +171,8 @@ GF_Err Media_GetESD(GF_MediaBox *mdia, u32 sampleDescIndex, GF_ESD **out_esd, Bo else esd = ((GF_MPEGVisualSampleEntryBox*) entry)->emul_esd; break; case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: esd = ((GF_MPEGVisualSampleEntryBox*) entry)->emul_esd; break; case GF_ISOM_BOX_TYPE_MP4A: @@ -181,6 +186,7 @@ GF_Err Media_GetESD(GF_MediaBox *mdia, u32 sampleDescIndex, GF_ESD **out_esd, Bo if (ESDa) esd = (GF_ESD *) ESDa->desc; break; case GF_ISOM_BOX_TYPE_TX3G: + case GF_ISOM_BOX_TYPE_TEXT: if (!true_desc_only && mdia->mediaTrack->moov->mov->convert_streaming_text) { GF_Err e = gf_isom_get_ttxt_esd(mdia, out_esd); if (e) return e; @@ -206,8 +212,8 @@ GF_Err Media_GetESD(GF_MediaBox *mdia, u32 sampleDescIndex, GF_ESD **out_esd, Bo GF_BitStream *bs; esd = gf_odf_desc_esd_new(2); *out_esd = esd; - esd->decoderConfig->streamType = 0x04; - esd->decoderConfig->objectTypeIndication = 0x80; + esd->decoderConfig->streamType = GF_STREAM_VISUAL; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_MEDIA_GENERIC; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_u32(bs, entry->type); gf_bs_write_u16(bs, ((GF_MPEGVisualSampleEntryBox*)entry)->Width); @@ -217,6 +223,21 @@ GF_Err Media_GetESD(GF_MediaBox *mdia, u32 sampleDescIndex, GF_ESD **out_esd, Bo return GF_OK; } + case GF_ISOM_SUBTYPE_LSR1: + if (true_desc_only) { + return GF_ISOM_INVALID_MEDIA; + } else { + GF_LASeRSampleEntryBox*ptr = (GF_LASeRSampleEntryBox*)entry; + esd = gf_odf_desc_esd_new(2); + *out_esd = esd; + esd->decoderConfig->streamType = GF_STREAM_SCENE; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_SCENE_LASER; + esd->decoderConfig->decoderSpecificInfo->dataLength = ptr->lsr_config->hdr_size; + esd->decoderConfig->decoderSpecificInfo->data = gf_malloc(sizeof(char)*ptr->lsr_config->hdr_size); + memcpy(esd->decoderConfig->decoderSpecificInfo->data, ptr->lsr_config->hdr, sizeof(char)*ptr->lsr_config->hdr_size); + return GF_OK; + } + default: return GF_ISOM_INVALID_MEDIA; } @@ -325,7 +346,7 @@ GF_Err Media_GetSample(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSample **samp, if (no_data) return GF_OK; /*and finally get the data, include padding if needed*/ - (*samp)->data = (char *) malloc(sizeof(char) * ( (*samp)->dataLength + mdia->mediaTrack->padding_bytes) ); + (*samp)->data = (char *) gf_malloc(sizeof(char) * ( (*samp)->dataLength + mdia->mediaTrack->padding_bytes) ); if (mdia->mediaTrack->padding_bytes) memset((*samp)->data + (*samp)->dataLength, 0, sizeof(char) * mdia->mediaTrack->padding_bytes); @@ -352,7 +373,8 @@ GF_Err Media_GetSample(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSample **samp, if (e) return e; } else if (mdia->mediaTrack->moov->mov->convert_streaming_text - && (mdia->handler->handlerType == GF_ISOM_MEDIA_TEXT) ) { + && ((mdia->handler->handlerType == GF_ISOM_MEDIA_TEXT) || (mdia->handler->handlerType == GF_ISOM_MEDIA_SUBT)) + ) { u64 dur; if (sampleNumber == mdia->information->sampleTable->SampleSize->sampleCount) { dur = mdia->mediaHeader->duration - (*samp)->DTS; @@ -519,7 +541,7 @@ GF_Err Media_SetDuration(GF_TrackBox *trak) stbl_GetSampleDTS(trak->Media->information->sampleTable->TimeToSample, nbSamp-1, &DTSprev); trak->Media->mediaHeader->duration += (DTS - DTSprev); } else { -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE if (trak->moov->mov->editFileMap && trak->Media->information->sampleTable->CompositionOffset) { u32 count, i; u64 max_ts; @@ -550,7 +572,7 @@ GF_Err Media_SetDuration(GF_TrackBox *trak) } } } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ trak->Media->mediaHeader->duration += ent->sampleDelta; } #endif @@ -561,7 +583,7 @@ GF_Err Media_SetDuration(GF_TrackBox *trak) -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err Media_CreateDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNname, u32 *dataRefIndex) @@ -585,7 +607,7 @@ GF_Err Media_CreateDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNna //THIS IS URL entry = (GF_DataEntryURLBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_URL); entry->flags = 0; - entry->location = (char*)malloc(strlen(URLname)+1); + entry->location = (char*)gf_malloc(strlen(URLname)+1); if (! entry->location) { gf_isom_box_del((GF_Box *)entry); return GF_OUT_OF_MEM; @@ -599,7 +621,7 @@ GF_Err Media_CreateDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNna //THIS IS URN entry = (GF_DataEntryURLBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_URN); ((GF_DataEntryURNBox *)entry)->flags = 0; - ((GF_DataEntryURNBox *)entry)->nameURN = (char*)malloc(strlen(URNname)+1); + ((GF_DataEntryURNBox *)entry)->nameURN = (char*)gf_malloc(strlen(URNname)+1); if (! ((GF_DataEntryURNBox *)entry)->nameURN) { gf_isom_box_del((GF_Box *)entry); return GF_OUT_OF_MEM; @@ -607,7 +629,7 @@ GF_Err Media_CreateDataRef(GF_DataReferenceBox *dref, char *URLname, char *URNna strcpy(((GF_DataEntryURNBox *)entry)->nameURN, URNname); //check for URL if (URLname) { - ((GF_DataEntryURNBox *)entry)->location = (char*)malloc(strlen(URLname)+1); + ((GF_DataEntryURNBox *)entry)->location = (char*)gf_malloc(strlen(URLname)+1); if (! ((GF_DataEntryURNBox *)entry)->location) { gf_isom_box_del((GF_Box *)entry); return GF_OUT_OF_MEM; @@ -806,4 +828,6 @@ GF_Err Media_UpdateSampleReference(GF_MediaBox *mdia, u32 sampleNumber, GF_ISOSa } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/media_odf.c b/src/isomedia/media_odf.c index 1597b54..2c0f554 100644 --- a/src/isomedia/media_odf.c +++ b/src/isomedia/media_odf.c @@ -24,6 +24,8 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + // Rewrite the good dependancies when an OD AU is extracted from the file GF_Err Media_RewriteODFrame(GF_MediaBox *mdia, GF_ISOSample *sample) { @@ -92,9 +94,9 @@ GF_Err Media_RewriteODFrame(GF_MediaBox *mdia, GF_ISOSample *sample) //create our OD... if (desc->tag == GF_ODF_ISOM_IOD_TAG) { - od = (GF_ObjectDescriptor *) malloc(sizeof(GF_InitialObjectDescriptor)); + od = (GF_ObjectDescriptor *) gf_malloc(sizeof(GF_InitialObjectDescriptor)); } else { - od = (GF_ObjectDescriptor *) malloc(sizeof(GF_ObjectDescriptor)); + od = (GF_ObjectDescriptor *) gf_malloc(sizeof(GF_ObjectDescriptor)); } if (!od) { e = GF_OUT_OF_MEM; @@ -176,7 +178,7 @@ GF_Err Media_RewriteODFrame(GF_MediaBox *mdia, GF_ISOSample *sample) esdR2->ODID = esdR->ODID; esdR2->NbESDs = esdR->NbESDs; //alloc our stuff - esdR2->ES_ID = (unsigned short*)malloc(sizeof(u32) * esdR->NbESDs); + esdR2->ES_ID = (unsigned short*)gf_malloc(sizeof(u32) * esdR->NbESDs); if (!esdR2->ES_ID) { e = GF_OUT_OF_MEM; goto err_exit; @@ -192,10 +194,10 @@ GF_Err Media_RewriteODFrame(GF_MediaBox *mdia, GF_ISOSample *sample) esdR2->ES_ID[i - skipped] = mpod->trackIDs[esdR->ES_ID[i] - 1]; } } - //realloc... + //gf_realloc... if (skipped && (skipped != esdR2->NbESDs) ) { esdR2->NbESDs -= skipped; - esdR2->ES_ID = (unsigned short*)realloc(esdR2->ES_ID, sizeof(u32) * esdR2->NbESDs); + esdR2->ES_ID = (unsigned short*)gf_realloc(esdR2->ES_ID, sizeof(u32) * esdR2->NbESDs); } gf_odf_com_del((GF_ODCom **)&esdR); gf_odf_codec_add_com(ODencode, (GF_ODCom *)esdR2); @@ -211,7 +213,7 @@ GF_Err Media_RewriteODFrame(GF_MediaBox *mdia, GF_ISOSample *sample) if (e) goto err_exit; //and set the buffer in the sample - free(sample->data); + gf_free(sample->data); sample->data = NULL; sample->dataLength = 0; e = gf_odf_codec_get_au(ODencode, &sample->data, &sample->dataLength); @@ -303,10 +305,10 @@ GF_Err Media_ParseODFrame(GF_MediaBox *mdia, GF_ISOSample *sample, GF_ISOSample e = gf_odf_desc_copy(desc, (GF_Descriptor **)&od); if (e) goto err_exit; if (desc->tag == GF_ODF_OD_TAG) { - isom_od = (GF_IsomObjectDescriptor *) malloc(sizeof(GF_IsomObjectDescriptor)); + isom_od = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomObjectDescriptor)); isom_od->tag = GF_ODF_ISOM_OD_TAG; } else { - isom_od = (GF_IsomObjectDescriptor *) malloc(sizeof(GF_IsomInitialObjectDescriptor)); + isom_od = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomInitialObjectDescriptor)); isom_od->tag = GF_ODF_ISOM_IOD_TAG; //copy PL ((GF_IsomInitialObjectDescriptor *)isom_od)->inlineProfileFlag = ((GF_InitialObjectDescriptor *)od)->inlineProfileFlag; @@ -380,7 +382,7 @@ GF_Err Media_ParseODFrame(GF_MediaBox *mdia, GF_ISOSample *sample, GF_ISOSample esdR2->NbESDs = esdR->NbESDs; if (esdR->NbESDs) { //alloc our stuff - esdR2->ES_ID = (unsigned short*)malloc(sizeof(u32) * esdR->NbESDs); + esdR2->ES_ID = (unsigned short*)gf_malloc(sizeof(u32) * esdR->NbESDs); if (!esdR2->ES_ID) { e = GF_OUT_OF_MEM; goto err_exit; @@ -514,3 +516,5 @@ u32 gf_isom_find_od_for_track(GF_ISOFile *file, u32 track) } return 0; } + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/meta.c b/src/isomedia/meta.c index c51b920..16da699 100644 --- a/src/isomedia/meta.c +++ b/src/isomedia/meta.c @@ -26,6 +26,7 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM GF_MetaBox *gf_isom_get_meta(GF_ISOFile *file, Bool root_meta, u32 track_num) { @@ -140,7 +141,11 @@ GF_Err gf_isom_get_meta_item_info(GF_ISOFile *file, Bool root_meta, u32 track_nu break; } else if (is_self_reference && !iloc->base_offset) { GF_ItemExtentEntry *entry = (GF_ItemExtentEntry *)gf_list_get(iloc->extent_entries, 0); - if (!entry->extent_length && !entry->original_extent_offset) + if (!entry->extent_length +#ifndef GPAC_DISABLE_ISOM_WRITE + && !entry->original_extent_offset +#endif + ) *is_self_reference = 1; } } @@ -209,7 +214,11 @@ GF_Err gf_isom_extract_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num count = gf_list_count(location_entry->extent_entries); if (!location_entry->base_offset && (count==1)) { extent_entry = (GF_ItemExtentEntry *)gf_list_get(location_entry->extent_entries, 0); - if (!extent_entry->extent_length && !extent_entry->original_extent_offset) return GF_BAD_PARAM; + if (!extent_entry->extent_length +#ifndef GPAC_DISABLE_ISOM_WRITE + && !extent_entry->original_extent_offset +#endif + ) return GF_BAD_PARAM; } if (dump_file_name) { @@ -224,7 +233,7 @@ GF_Err gf_isom_extract_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num char buf_cache[4096]; u64 remain; GF_ItemExtentEntry *extent_entry = (GF_ItemExtentEntry *)gf_list_get(location_entry->extent_entries, i); - gf_bs_seek(file->movieFileMap->bs, /*location_entry->base_offset +*/ extent_entry->extent_offset); + gf_bs_seek(file->movieFileMap->bs, location_entry->base_offset + extent_entry->extent_offset); remain = extent_entry->extent_length; while (remain) { @@ -246,7 +255,7 @@ u32 gf_isom_get_meta_primary_item_id(GF_ISOFile *file, Bool root_meta, u32 track } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_set_meta_type(GF_ISOFile *file, Bool root_meta, u32 track_num, u32 metaType) @@ -299,10 +308,10 @@ GF_Err gf_isom_set_meta_type(GF_ISOFile *file, Bool root_meta, u32 track_num, u3 if (!meta->handler) meta->handler = (GF_HandlerBox *)hdlr_New(); - if (meta->handler->nameUTF8) free(meta->handler->nameUTF8); + if (meta->handler->nameUTF8) gf_free(meta->handler->nameUTF8); meta->handler->handlerType = metaType; sprintf(szName, "GPAC %s Handler", gf_4cc_to_str(metaType)); - meta->handler->nameUTF8 = strdup(szName); + meta->handler->nameUTF8 = gf_strdup(szName); return GF_OK; } @@ -348,15 +357,16 @@ GF_Err gf_isom_set_meta_xml(GF_ISOFile *file, Bool root_meta, u32 track_num, cha /*assume 32bit max size = 4Go should be sufficient for a DID!!*/ - xmlfile = fopen(XMLFileName, "rb"); + xmlfile = gf_f64_open(XMLFileName, "rb"); if (!xmlfile) return GF_URL_ERROR; - fseek(xmlfile, 0, SEEK_END); - xml->xml_length = ftell(xmlfile); - fseek(xmlfile, 0, SEEK_SET); - xml->xml = (char*)malloc(sizeof(unsigned char)*xml->xml_length); + gf_f64_seek(xmlfile, 0, SEEK_END); + assert(gf_f64_tell(xmlfile) < 1<<31); + xml->xml_length = (u32) gf_f64_tell(xmlfile); + gf_f64_seek(xmlfile, 0, SEEK_SET); + xml->xml = (char*)gf_malloc(sizeof(unsigned char)*xml->xml_length); xml->xml_length = fread(xml->xml, 1, sizeof(unsigned char)*xml->xml_length, xmlfile); if (ferror(xmlfile)) { - free(xml->xml); + gf_free(xml->xml); xml->xml = NULL; return GF_BAD_PARAM; } @@ -384,7 +394,7 @@ GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bo /*check file exists */ if (!URN && !URL && !self_reference) { - FILE *src = fopen(resource_path, "rb"); + FILE *src = gf_f64_open(resource_path, "rb"); if (!src) return GF_URL_ERROR; fclose(src); } @@ -403,24 +413,24 @@ GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bo /*get relative name*/ if (item_name) { - infe->item_name = strdup(item_name); + infe->item_name = gf_strdup(item_name); } else if (resource_path) { if (strrchr(resource_path, GF_PATH_SEPARATOR)) { - infe->item_name = strdup(strrchr(resource_path, GF_PATH_SEPARATOR) + 1); + infe->item_name = gf_strdup(strrchr(resource_path, GF_PATH_SEPARATOR) + 1); } else { - infe->item_name = strdup(resource_path); + infe->item_name = gf_strdup(resource_path); } } if (mime_type) { - infe->content_type = strdup(mime_type); + infe->content_type = gf_strdup(mime_type); } else { - infe->content_type = strdup("application/octet-stream"); + infe->content_type = gf_strdup("application/octet-stream"); } - if (content_encoding) infe->content_encoding = strdup(content_encoding); + if (content_encoding) infe->content_encoding = gf_strdup(content_encoding); /*Creation of the ItemLocation */ - location_entry = (GF_ItemLocationEntry*)malloc(sizeof(GF_ItemLocationEntry)); + location_entry = (GF_ItemLocationEntry*)gf_malloc(sizeof(GF_ItemLocationEntry)); if (!location_entry) { gf_isom_box_del((GF_Box *)infe); return GF_OUT_OF_MEM; @@ -449,7 +459,7 @@ GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bo GF_ItemExtentEntry *entry; GF_SAFEALLOC(entry, GF_ItemExtentEntry); gf_list_add(location_entry->extent_entries, entry); - if (!infe->item_name) infe->item_name = strdup(""); + if (!infe->item_name) infe->item_name = gf_strdup(""); return GF_OK; } @@ -494,7 +504,7 @@ GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bo remain = entry->extent_length; while (remain) { u32 size_cache = (remain>4096) ? 4096 : (u32) remain; - fread(cache_data, 1, size_cache, src); + size_cache = fread(cache_data, 1, size_cache, src); gf_bs_write_data(file->editFileMap->bs, cache_data, size_cache); remain -= size_cache; } @@ -507,7 +517,7 @@ GF_Err gf_isom_add_meta_item(GF_ISOFile *file, Bool root_meta, u32 track_num, Bo } /*store full path for info*/ else if (!location_entry->data_reference_index) { - infe->full_path = strdup(resource_path); + infe->full_path = gf_strdup(resource_path); } return GF_OK; } @@ -556,6 +566,8 @@ GF_Err gf_isom_set_meta_primary_item(GF_ISOFile *file, Bool root_meta, u32 track } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/movie_fragments.c b/src/isomedia/movie_fragments.c index b6099aa..fe623ea 100644 --- a/src/isomedia/movie_fragments.c +++ b/src/isomedia/movie_fragments.c @@ -24,7 +24,9 @@ #include <gpac/internal/isomedia_dev.h> -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM + +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS GF_TrackExtendsBox *GetTrex(GF_MovieBox *moov, u32 TrackID) { @@ -38,7 +40,7 @@ GF_TrackExtendsBox *GetTrex(GF_MovieBox *moov, u32 TrackID) } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_TrackFragmentBox *GetTraf(GF_ISOFile *mov, u32 TrackID) { @@ -54,7 +56,7 @@ GF_TrackFragmentBox *GetTraf(GF_ISOFile *mov, u32 TrackID) return NULL; } -GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie) +GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie, Bool use_segments) { GF_Err e; u32 i; @@ -91,6 +93,11 @@ GF_Err gf_isom_finalize_for_fragment(GF_ISOFile *movie) //ok we are fine - note the data map is created at the begining if (i) movie->FragmentsFlags |= GF_ISOM_FRAG_WRITE_READY; movie->NextMoofNumber = 1; + + if (use_segments) { + movie->use_segments = 1; + movie->moof_list = gf_list_new(); + } return GF_OK; } @@ -267,8 +274,31 @@ GF_Err gf_isom_set_fragment_option(GF_ISOFile *movie, u32 TrackID, u32 Code, u32 return GF_OK; } +//#define USE_BASE_DATA_OFFSET + +void update_trun_offsets(GF_ISOFile *movie, s32 offset) +{ +#ifndef USE_BASE_DATA_OFFSET + GF_TrackFragmentRunBox *trun; + u32 i, j; + GF_TrackFragmentBox *traf; + i=0; + while ((traf = gf_list_enum(movie->moof->TrackList, &i))) { + /*remove base data*/ + traf->tfhd->base_data_offset = 0; + j=0; + while ((trun = gf_list_enum(traf->TrackRuns, &j))) { + if (j==1) { + trun->data_offset += offset; + } else { + trun->data_offset = 0; + } + } + } +#endif +} -u32 UpdateRuns(GF_TrackFragmentBox *traf) +u32 UpdateRuns(GF_ISOFile *movie, GF_TrackFragmentBox *traf) { u32 sampleCount, i, j, RunSize, UseDefaultSize, RunDur, UseDefaultDur, RunFlags, NeedFlags, UseDefaultFlag, UseCTS, count; GF_TrackFragmentRunBox *trun; @@ -276,13 +306,14 @@ u32 UpdateRuns(GF_TrackFragmentBox *traf) sampleCount = 0; - - //traf data offset - we ALWAYS use data offset indication when writting otherwise - //we would need to have one TRUN max in a TRAF for offset reconstruction or store - //all TRUN in memory before writting :( Anyway it is much safer to indicate the - //base offset of each traf rather than using offset aggregation rules specified - //in the std - traf->tfhd->flags = GF_ISOM_TRAF_BASE_OFFSET; +#ifndef USE_BASE_DATA_OFFSET + if (movie->use_segments) { + traf->tfhd->flags = 0; + } else +#endif + { + traf->tfhd->flags = GF_ISOM_TRAF_BASE_OFFSET; + } //empty runs if (traf->tfhd->EmptyDuration) { @@ -419,13 +450,72 @@ u32 UpdateRuns(GF_TrackFragmentBox *traf) return sampleCount; } +Bool moof_get_rap_time_offset(GF_MovieFragmentBox *moof, u32 refTrackID, u32 *rap_delta) +{ + u32 i, j, delta; + GF_TrunEntry *ent; + GF_TrackFragmentBox *traf; + GF_TrackFragmentRunBox *trun; + *rap_delta = 0; + for (i=0; i<gf_list_count(moof->TrackList); i++) { + traf = gf_list_get(moof->TrackList, i); + if (traf->tfhd->trackID==refTrackID) break; + traf=NULL; + } + if (!traf) return 0; + delta = 0; + i=0; + while ((trun = gf_list_enum(traf->TrackRuns, &i))) { + if (trun->flags & GF_ISOM_TRUN_FIRST_FLAG) { + if (GF_ISOM_GET_FRAG_SYNC(trun->flags)) { + ent = gf_list_get(trun->entries, 0); + *rap_delta = delta + ent->CTS_Offset; + return 1; + } + } + j=0; + while ((ent = gf_list_enum(trun->entries, &j))) { + if (GF_ISOM_GET_FRAG_SYNC(ent->flags)) { + *rap_delta = delta + ent->CTS_Offset; + return 1; + } + delta += ent->Duration; + } + } + return 0; +} -GF_Err StoreFragment(GF_ISOFile *movie) +u32 moof_get_duration(GF_MovieFragmentBox *moof, u32 refTrackID) +{ + u32 i, j, duration; + GF_TrunEntry *ent; + GF_TrackFragmentBox *traf; + GF_TrackFragmentRunBox *trun; + for (i=0; i<gf_list_count(moof->TrackList); i++) { + traf = gf_list_get(moof->TrackList, i); + if (traf->tfhd->trackID==refTrackID) break; + traf=NULL; + } + if (!traf) return 0; + + duration = 0; + i=0; + while ((trun = gf_list_enum(traf->TrackRuns, &i))) { + j=0; + while ((ent = gf_list_enum(trun->entries, &j))) { + duration += ent->Duration; + } + } + return duration; +} + +GF_Err StoreFragment(GF_ISOFile *movie, Bool load_mdat_only, s32 data_offset_diff, u32 *moof_size) { GF_Err e; u64 moof_start; - u32 size, i, s_count; + u32 size, i, s_count, mdat_size; + s32 offset; char *buffer; GF_TrackFragmentBox *traf; GF_TrackFragmentRunBox *trun; @@ -433,8 +523,9 @@ GF_Err StoreFragment(GF_ISOFile *movie) if (!movie->moof) return GF_OK; bs = movie->editFileMap->bs; + if (!movie->moof_first) load_mdat_only = 0; - //1- flush all caches + //1 - flush all caches i=0; while ((traf = (GF_TrackFragmentBox*)gf_list_enum(movie->moof->TrackList, &i))) { if (!traf->DataCache) continue; @@ -444,24 +535,55 @@ GF_Err StoreFragment(GF_ISOFile *movie) if (!trun->cache || !trun->sample_count) continue; //update offset - trun->data_offset = (u32) (gf_bs_get_position(movie->editFileMap->bs) - movie->current_top_box_start - 8); + trun->data_offset = (u32) (gf_bs_get_position(bs) - movie->moof->fragment_offset - 8); //write cache gf_bs_get_content(trun->cache, &buffer, &size); - gf_bs_write_data(movie->editFileMap->bs, buffer, size); + gf_bs_write_data(bs, buffer, size); gf_bs_del(trun->cache); - free(buffer); + gf_free(buffer); trun->cache = NULL; + traf->DataCache=0; } - //2- update MOOF MDAT header + + if (load_mdat_only) { + u64 pos = gf_bs_get_position(bs); + //we assume we never write large MDATs in fragment mode which should always be true + movie->moof->mdat_size = (u32) (pos - movie->moof->fragment_offset); + movie->moof->mdat = gf_malloc(sizeof(char) * movie->moof->mdat_size); + if (!movie->moof->mdat) return GF_OUT_OF_MEM; + gf_bs_seek(bs, movie->segment_start); + /*write mdat size*/ + gf_bs_write_u32(bs, (u32) movie->moof->mdat_size); + gf_bs_seek(bs, movie->segment_start); + gf_bs_read_data(bs, movie->moof->mdat, movie->moof->mdat_size); + gf_bs_seek(bs, movie->segment_start); + gf_bs_truncate(bs); + return GF_OK; + } + + moof_start = gf_bs_get_position(bs); + //2- update MOOF MDAT header + if (!movie->moof->mdat) { + gf_bs_seek(bs, movie->moof->fragment_offset); + //we assume we never write large MDATs in fragment mode which should always be true + mdat_size = (u32) (moof_start - movie->moof->fragment_offset); + gf_bs_write_u32(bs, (u32) mdat_size); + gf_bs_write_u32(bs, GF_ISOM_BOX_TYPE_MDAT); + gf_bs_seek(bs, moof_start); + } - //start of MDAT - gf_bs_seek(bs, movie->current_top_box_start); - //we assume we never write large MDATs in fragment mode which should always be true - size = (u32) (moof_start - movie->current_top_box_start); - gf_bs_write_u32(bs, (u32) size); - gf_bs_write_u32(bs, GF_ISOM_BOX_TYPE_MDAT); - gf_bs_seek(bs, moof_start); + /*estimate moof size and shift trun offsets*/ +#ifndef USE_BASE_DATA_OFFSET + offset = 0; + if (movie->use_segments) { + e = gf_isom_box_size((GF_Box *) movie->moof); + offset = (s32) movie->moof->size; + /*mdat size & type*/ + offset += 8; + update_trun_offsets(movie, offset); + } +#endif //3- clean our traf's i=0; @@ -469,7 +591,7 @@ GF_Err StoreFragment(GF_ISOFile *movie) //compute default settings for the TRAF ComputeFragmentDefaults(traf); //updates all trun and set all flags, INCLUDING TRAF FLAGS (durations, ...) - s_count = UpdateRuns(traf); + s_count = UpdateRuns(movie, traf); //empty fragment destroy it if (!traf->tfhd->EmptyDuration && !s_count) { i--; @@ -479,21 +601,205 @@ GF_Err StoreFragment(GF_ISOFile *movie) } } + buffer = NULL; + /*rewind bitstream and load mdat in memory */ + if (movie->moof_first && !movie->moof->mdat) { + buffer = gf_malloc(sizeof(char)*mdat_size); + gf_bs_seek(bs, movie->moof->fragment_offset); + gf_bs_read_data(bs, buffer, mdat_size); + /*back to mdat start and erase with moov*/ + gf_bs_seek(bs, movie->moof->fragment_offset); + gf_bs_truncate(bs); + } + //4- Write moof e = gf_isom_box_size((GF_Box *) movie->moof); if (e) return e; + /*moof first, update traf headers - THIS WILL IMPACT THE MOOF SIZE IF WE + DECIDE NOT TO USE THE DATA-OFFSET FLAG*/ + if (movie->moof_first +#ifndef USE_BASE_DATA_OFFSET + && !movie->use_segments +#endif + ) { + i=0; + while ((traf = (GF_TrackFragmentBox*)gf_list_enum(movie->moof->TrackList, &i))) { + /*offset increases by moof size*/ + traf->tfhd->base_data_offset += movie->moof->size; + traf->tfhd->base_data_offset += data_offset_diff; + } + } +#ifndef USE_BASE_DATA_OFFSET + else if (movie->use_segments) { + if (offset != (movie->moof->size+8)) { + offset = (s32) (movie->moof->size + 8 - offset); + update_trun_offsets(movie, offset); + e = gf_isom_box_size((GF_Box *) movie->moof); + } + } +#endif + e = gf_isom_box_write((GF_Box *) movie->moof, bs); if (e) return e; + + //rewrite mdat after moof + if (movie->moof->mdat) { + gf_bs_write_data(bs, movie->moof->mdat, movie->moof->mdat_size); + gf_free(movie->moof->mdat); + movie->moof->mdat = NULL; + } else if (buffer) { + gf_bs_write_data(bs, buffer, mdat_size); + gf_free(buffer); + } + + if (moof_size) *moof_size = (u32) movie->moof->size; + + if (!movie->use_segments) { + gf_isom_box_del((GF_Box *) movie->moof); + movie->moof = NULL; + } + return GF_OK; +} + + + +GF_Err gf_isom_close_segment(GF_ISOFile *movie, u32 frags_per_sidx, u32 referenceTrackID, GF_SIDXTrackTimes *tracks_times, u32 nb_times, Bool daisy_chain_sidx) +{ + GF_SegmentIndexBox *sidx=NULL; + u64 sidx_start, sidx_end; + u32 count, nb_subsegs, idx; + GF_Err e; + //and only at setup + if (!movie || !(movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY) ) return GF_BAD_PARAM; + if (movie->openMode != GF_ISOM_OPEN_WRITE) return GF_ISOM_INVALID_MODE; + + count = gf_list_count(movie->moov->mvex->TrackExList); + if (!count) return GF_BAD_PARAM; + + count = gf_list_count(movie->moof_list); + if (!count) return GF_OK; + /*store fragment*/ + if (movie->moof) { + e = StoreFragment(movie, 1, 0, NULL); + if (e) return e; + } + gf_bs_seek(movie->editFileMap->bs, movie->segment_start); + gf_bs_truncate(movie->editFileMap->bs); + + + /*write STYP*/ + movie->brand->type = GF_ISOM_BOX_TYPE_STYP; + e = gf_isom_box_size((GF_Box *) movie->brand); + if (e) return e; + e = gf_isom_box_write((GF_Box *) movie->brand, movie->editFileMap->bs); + if (e) return e; + + /*prepare SIDX*/ + if (referenceTrackID) { + sidx = (GF_SegmentIndexBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_SIDX); + sidx->reference_track_ID = referenceTrackID; + sidx->nb_track_times = nb_times; + sidx->tracks_times = tracks_times; + + if (!frags_per_sidx) nb_subsegs = 1; + else nb_subsegs = count/frags_per_sidx; + if (!nb_subsegs) nb_subsegs=1; + sidx->nb_refs = nb_subsegs; + sidx->refs = gf_malloc(sizeof(GF_SIDXReference)*nb_subsegs); + memset(sidx->refs, 0, sizeof(GF_SIDXReference)*nb_subsegs); + + /*remember start of sidx*/ + sidx_start = gf_bs_get_position(movie->editFileMap->bs); + + e = gf_isom_box_size((GF_Box *) sidx); + if (e) return e; + e = gf_isom_box_write((GF_Box *) sidx, movie->editFileMap->bs); + if (e) return e; + + sidx_end = gf_bs_get_position(movie->editFileMap->bs); - //5- destroy our moof - gf_isom_box_del((GF_Box *) movie->moof); - movie->moof = NULL; - movie->NextMoofNumber ++; + count = idx = 0; + } + + + /*write all moofs*/ + e = GF_OK; + while (gf_list_count(movie->moof_list)) { + s32 offset_diff; + u32 moof_size; + movie->moof = gf_list_get(movie->moof_list, 0); + gf_list_rem(movie->moof_list, 0); + offset_diff = (s32) (gf_bs_get_position(movie->editFileMap->bs) - movie->moof->fragment_offset); + movie->moof->fragment_offset = gf_bs_get_position(movie->editFileMap->bs); + if (!e) { + if (sidx && !count) { + /*we refer to next moof*/ + sidx->refs[idx].reference_type = 0; + sidx->refs[idx].contains_RAP = moof_get_rap_time_offset(movie->moof, referenceTrackID, & sidx->refs[idx].RAP_delta_time); + sidx->refs[idx].subsegment_duration += moof_get_duration(movie->moof, referenceTrackID); + /*reference offset is startof the moof we're about to write*/ + sidx->refs[idx].reference_offset = (u32) ( gf_bs_get_position(movie->editFileMap->bs) - sidx_end) ; + } + e = StoreFragment(movie, 0, offset_diff, &moof_size); + + if (sidx) { + count++; + if (count==frags_per_sidx) { + count = 0; + idx++; + } + } + } + gf_isom_box_del((GF_Box *) movie->moof); + movie->moof = NULL; + } + + if (sidx) { + u64 pos = gf_bs_get_position(movie->editFileMap->bs); + /*write sidx*/ + gf_bs_seek(movie->editFileMap->bs, sidx_start); + e = gf_isom_box_write((GF_Box *) sidx, movie->editFileMap->bs); + gf_bs_seek(movie->editFileMap->bs, pos); + + sidx->tracks_times=NULL; + sidx->nb_track_times=0; + gf_isom_box_del((GF_Box*)sidx); + } + return e; +} + +GF_Err gf_isom_close_fragments(GF_ISOFile *movie) +{ + if (movie->use_segments) { + return gf_isom_close_segment(movie, 0, 0, NULL, 0, 0); + } else { + return StoreFragment(movie, 0, 0, NULL); + } +} + +GF_Err gf_isom_start_segment(GF_ISOFile *movie, char *SegName) +{ + GF_Err e; + //and only at setup + if (!movie || !(movie->FragmentsFlags & GF_ISOM_FRAG_WRITE_READY) ) return GF_BAD_PARAM; + if (movie->openMode != GF_ISOM_OPEN_WRITE) return GF_ISOM_INVALID_MODE; + + if (gf_list_count(movie->moof_list)) return GF_BAD_PARAM; + + /*update segment file*/ + if (SegName) { + gf_isom_datamap_del(movie->editFileMap); + e = gf_isom_datamap_new(SegName, NULL, GF_ISOM_DATA_MAP_WRITE, & movie->editFileMap); + movie->segment_start = 0; + return e; + } + assert(gf_list_count(movie->moof_list) == 0); + movie->segment_start = gf_bs_get_position(movie->editFileMap->bs); return GF_OK; } -GF_Err gf_isom_start_fragment(GF_ISOFile *movie) +GF_Err gf_isom_start_fragment(GF_ISOFile *movie, Bool moof_first) { u32 i, count; GF_TrackExtendsBox *trex; @@ -506,21 +812,44 @@ GF_Err gf_isom_start_fragment(GF_ISOFile *movie) count = gf_list_count(movie->moov->mvex->TrackExList); if (!count) return GF_BAD_PARAM; - //store fragment + /*always force cached mode when writing movie segments*/ + if (movie->use_segments) moof_first = 1; + movie->moof_first = moof_first; + + //store existing fragment if (movie->moof) { - e = StoreFragment(movie); + e = StoreFragment(movie, movie->use_segments ? 1 : 0, 0, NULL); if (e) return e; } - //format MDAT - movie->current_top_box_start = gf_bs_get_position(movie->editFileMap->bs); - gf_bs_write_u32(movie->editFileMap->bs, 0); - gf_bs_write_u32(movie->editFileMap->bs, GF_ISOM_BOX_TYPE_MDAT); + /* Inserting free data for testing HTTP streaming */ +#if 0 + if (0) { + GF_FreeSpaceBox *fb = (GF_FreeSpaceBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_FREE); + fb->dataSize = free_data_insert_size; + //gf_list_add(movie->TopBoxes, fb); + e = gf_isom_box_size((GF_Box *) fb); + if (e) return e; + e = gf_isom_box_write((GF_Box *) fb, movie->editFileMap->bs); + if (e) return e; + gf_isom_box_del((GF_Box *)fb); + } +#endif //create new fragment movie->moof = (GF_MovieFragmentBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MOOF); movie->moof->mfhd = (GF_MovieFragmentHeaderBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MFHD); movie->moof->mfhd->sequence_number = movie->NextMoofNumber; + movie->NextMoofNumber ++; + if (movie->use_segments) + gf_list_add(movie->moof_list, movie->moof); + + + /*remember segment offset*/ + movie->moof->fragment_offset = gf_bs_get_position(movie->editFileMap->bs); + /*prepare MDAT*/ + gf_bs_write_u32(movie->editFileMap->bs, 0); + gf_bs_write_u32(movie->editFileMap->bs, GF_ISOM_BOX_TYPE_MDAT); //we create a TRAF for each setup track, unused ones will be removed at store time for (i=0; i<count; i++) { @@ -530,7 +859,7 @@ GF_Err gf_isom_start_fragment(GF_ISOFile *movie) traf->tfhd = (GF_TrackFragmentHeaderBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TFHD); traf->tfhd->trackID = trex->trackID; //add 8 bytes (MDAT size+type) to avoid the data_offset in the first trun - traf->tfhd->base_data_offset = movie->current_top_box_start + 8; + traf->tfhd->base_data_offset = movie->moof->fragment_offset + 8; gf_list_add(movie->moof->TrackList, traf); } return GF_OK; @@ -577,12 +906,12 @@ GF_Err gf_isom_fragment_add_sample(GF_ISOFile *movie, u32 TrackID, GF_ISOSample count = gf_list_count(traf->TrackRuns); if (count) { trun = (GF_TrackFragmentRunBox *)gf_list_get(traf->TrackRuns, count-1); - trun->data_offset = (u32) (pos - movie->current_top_box_start - 8); + trun->data_offset = (u32) (pos - movie->moof->fragment_offset - 8); gf_bs_get_content(trun->cache, &buffer, &buffer_size); gf_bs_write_data(movie->editFileMap->bs, buffer, buffer_size); gf_bs_del(trun->cache); trun->cache = NULL; - free(buffer); + gf_free(buffer); } } traf_2 = (GF_TrackFragmentBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TRAF); @@ -590,7 +919,7 @@ GF_Err gf_isom_fragment_add_sample(GF_ISOFile *movie, u32 TrackID, GF_ISOSample traf_2->tfhd = (GF_TrackFragmentHeaderBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TFHD); traf_2->tfhd->trackID = traf->tfhd->trackID; //keep the same offset - traf_2->tfhd->base_data_offset = movie->current_top_box_start + 8; + traf_2->tfhd->base_data_offset = movie->moof->fragment_offset + 8; gf_list_add(movie->moof->TrackList, traf_2); //duplicate infos @@ -603,12 +932,13 @@ GF_Err gf_isom_fragment_add_sample(GF_ISOFile *movie, u32 TrackID, GF_ISOSample } + pos = gf_bs_get_position(movie->editFileMap->bs); //add TRUN entry count = gf_list_count(traf->TrackRuns); if (count) { trun = (GF_TrackFragmentRunBox *)gf_list_get(traf->TrackRuns, count-1); //check data offset when no caching as trun entries shall ALWAYS be contiguous samples - if (!traf->DataCache && (movie->current_top_box_start + 8 + trun->data_offset + GetRunSize(trun) != pos) ) + if (!traf->DataCache && (movie->moof->fragment_offset + 8 + trun->data_offset + GetRunSize(trun) != pos) ) count = 0; //check I-frame detection @@ -620,12 +950,12 @@ GF_Err gf_isom_fragment_add_sample(GF_ISOFile *movie, u32 TrackID, GF_ISOSample //if data cache is on and we're changing TRUN, store the cache and update data offset if (!count && traf->DataCache) { - trun->data_offset = (u32) (pos - movie->current_top_box_start - 8); + trun->data_offset = (u32) (pos - movie->moof->fragment_offset - 8); gf_bs_get_content(trun->cache, &buffer, &buffer_size); gf_bs_write_data(movie->editFileMap->bs, buffer, buffer_size); gf_bs_del(trun->cache); trun->cache = NULL; - free(buffer); + gf_free(buffer); } } @@ -633,7 +963,7 @@ GF_Err gf_isom_fragment_add_sample(GF_ISOFile *movie, u32 TrackID, GF_ISOSample if (!count) { trun = (GF_TrackFragmentRunBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TRUN); //store data offset (we have the 8 btyes offset of the MDAT) - trun->data_offset = (u32) (pos - movie->current_top_box_start - 8); + trun->data_offset = (u32) (pos - movie->moof->fragment_offset - 8); gf_list_add(traf->TrackRuns, trun); //if we use data caching, create a bitstream @@ -710,7 +1040,7 @@ GF_Err gf_isom_fragment_append_data(GF_ISOFile *movie, u32 TrackID, char *data, } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_EXPORT u32 gf_isom_is_track_fragmented(GF_ISOFile *movie, u32 TrackID) @@ -723,8 +1053,12 @@ GF_EXPORT u32 gf_isom_is_fragmented(GF_ISOFile *movie) { if (!movie || !movie->moov) return 0; + /* By default if the Moov has an mvex, the file is fragmented */ + if (movie->moov->mvex) return 1; + /* deprecated old code */ /*only check moof number (in read mode, mvex can be deleted on the fly)*/ - return movie->NextMoofNumber ? 1 : 0; + //return movie->NextMoofNumber ? 1 : 0; + return 0; } #else @@ -750,7 +1084,7 @@ GF_Err gf_isom_set_fragment_option(GF_ISOFile *the_file, u32 TrackID, u32 Code, return GF_NOT_SUPPORTED; } -GF_Err gf_isom_start_fragment(GF_ISOFile *the_file) +GF_Err gf_isom_start_fragment(GF_ISOFile *the_file, u32 free_data_insert_size) { return GF_NOT_SUPPORTED; } @@ -775,4 +1109,6 @@ u32 gf_isom_is_fragmented(GF_ISOFile *the_file) return 0; } -#endif +#endif /*GPAC_DISABLE_ISOM_FRAGMENTS)*/ + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/sample_descs.c b/src/isomedia/sample_descs.c index f6644cc..5d1c21e 100644 --- a/src/isomedia/sample_descs.c +++ b/src/isomedia/sample_descs.c @@ -24,6 +24,8 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + void gf_isom_video_sample_entry_init(GF_VisualSampleEntryBox *ent) { ent->horiz_res = ent->vert_res = 0x00480000; @@ -56,7 +58,7 @@ GF_Err gf_isom_video_sample_entry_read(GF_VisualSampleEntryBox *ptr, GF_BitStrea return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE void gf_isom_video_sample_entry_write(GF_VisualSampleEntryBox *ptr, GF_BitStream *bs) { @@ -84,8 +86,7 @@ void gf_isom_video_sample_entry_size(GF_VisualSampleEntryBox *ent) ent->size += 78; } - -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -124,7 +125,7 @@ GF_Err gf_isom_audio_sample_entry_read(GF_AudioSampleEntryBox *ptr, GF_BitStream return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE void gf_isom_audio_sample_entry_write(GF_AudioSampleEntryBox *ptr, GF_BitStream *bs) { @@ -148,7 +149,7 @@ void gf_isom_audio_sample_entry_size(GF_AudioSampleEntryBox *ptr) } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -182,12 +183,29 @@ GF_3GPConfig *gf_isom_3gp_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 } if (!config) return NULL; - res = (GF_3GPConfig*)malloc(sizeof(GF_3GPConfig)); + res = (GF_3GPConfig*)gf_malloc(sizeof(GF_3GPConfig)); memcpy(res, config, sizeof(GF_3GPConfig)); return res; } -#ifndef GPAC_READ_ONLY +GF_EXPORT +GF_AC3Config *gf_isom_ac3_config_get(GF_ISOFile *the_file, u32 trackNumber, u32 StreamDescriptionIndex) +{ + GF_AC3Config *res; + GF_TrackBox *trak; + GF_AC3SampleEntryBox *entry; + 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); + 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)); + memcpy(res, &entry->info->cfg, sizeof(GF_AC3Config)); + return res; +} + +#ifndef GPAC_DISABLE_ISOM_WRITE GF_EXPORT GF_Err gf_isom_3gp_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_3GPConfig *cfg, char *URLname, char *URNname, u32 *outDescriptionIndex) @@ -351,7 +369,7 @@ GF_Err gf_isom_ac3_config_new(GF_ISOFile *the_file, u32 trackNumber, GF_AC3Confi *outDescriptionIndex = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList); return e; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -384,7 +402,7 @@ GF_Err gf_isom_get_dims_description(GF_ISOFile *movie, u32 trackNumber, u32 desc return GF_OK; } -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_new_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DIMSDescription *desc, char *URLname, char *URNname, u32 *outDescriptionIndex) { GF_TrackBox *trak; @@ -422,12 +440,12 @@ GF_Err gf_isom_new_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DIMSD dims->config->containsRedundant = desc->containsRedundant; if (!dims->config->containsRedundant) dims->config->containsRedundant = 1; dims->config->streamType = desc->streamType; - dims->config->textEncoding = strdup(desc->textEncoding ? desc->textEncoding : ""); - dims->config->contentEncoding = strdup(desc->contentEncoding ? desc->contentEncoding : ""); + dims->config->textEncoding = gf_strdup(desc->textEncoding ? desc->textEncoding : ""); + dims->config->contentEncoding = gf_strdup(desc->contentEncoding ? desc->contentEncoding : ""); if (desc->content_script_types) { dims->scripts = (GF_DIMSScriptTypesBox*) gf_isom_box_new(GF_ISOM_BOX_TYPE_DIST); - dims->scripts->content_script_types = strdup(desc->content_script_types); + dims->scripts->content_script_types = gf_strdup(desc->content_script_types); } return e; } @@ -460,22 +478,78 @@ GF_Err gf_isom_update_dims_description(GF_ISOFile *movie, u32 trackNumber, GF_DI dims->config->containsRedundant = desc->containsRedundant; dims->config->streamType = desc->streamType; - if (dims->config->textEncoding) free(dims->config->textEncoding); - dims->config->textEncoding = strdup(desc->textEncoding ? desc->textEncoding : ""); + if (dims->config->textEncoding) gf_free(dims->config->textEncoding); + dims->config->textEncoding = gf_strdup(desc->textEncoding ? desc->textEncoding : ""); - if (dims->config->contentEncoding) free(dims->config->contentEncoding); - dims->config->contentEncoding = strdup(desc->contentEncoding ? desc->contentEncoding : ""); + if (dims->config->contentEncoding) gf_free(dims->config->contentEncoding); + dims->config->contentEncoding = gf_strdup(desc->contentEncoding ? desc->contentEncoding : ""); if (desc->content_script_types) { if (!dims->scripts) dims->scripts = (GF_DIMSScriptTypesBox*) gf_isom_box_new(GF_ISOM_BOX_TYPE_DIST); - if (dims->scripts->content_script_types) free(dims->scripts->content_script_types); - dims->scripts->content_script_types = strdup(desc->content_script_types ? desc->content_script_types :""); + if (dims->scripts->content_script_types) gf_free(dims->scripts->content_script_types); + dims->scripts->content_script_types = gf_strdup(desc->content_script_types ? desc->content_script_types :""); } else if (dims->scripts) { gf_isom_box_del((GF_Box *) dims->scripts); dims->scripts = NULL; } return e; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + + + +GF_Err LSR_UpdateESD(GF_LASeRSampleEntryBox *lsr, GF_ESD *esd) +{ + if (!lsr->bitrate) lsr->bitrate = (GF_MPEG4BitRateBox*)gf_isom_box_new(GF_ISOM_BOX_TYPE_BTRT); + if (lsr->descr) gf_isom_box_del((GF_Box *) lsr->descr); + lsr->descr = NULL; + lsr->bitrate->avgBitrate = esd->decoderConfig->avgBitrate; + lsr->bitrate->maxBitrate = esd->decoderConfig->maxBitrate; + lsr->bitrate->bufferSizeDB = esd->decoderConfig->bufferSizeDB; + + if (gf_list_count(esd->IPIDataSet) + || gf_list_count(esd->IPMPDescriptorPointers) + || esd->langDesc + || gf_list_count(esd->extensionDescriptors) + || esd->ipiPtr || esd->qos || esd->RegDescriptor) { + + lsr->descr = (GF_MPEG4ExtensionDescriptorsBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_M4DS); + if (esd->RegDescriptor) { gf_list_add(lsr->descr->descriptors, esd->RegDescriptor); esd->RegDescriptor = NULL; } + if (esd->qos) { gf_list_add(lsr->descr->descriptors, esd->qos); esd->qos = NULL; } + if (esd->ipiPtr) { gf_list_add(lsr->descr->descriptors, esd->ipiPtr); esd->ipiPtr= NULL; } + + while (gf_list_count(esd->IPIDataSet)) { + GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->IPIDataSet, 0); + gf_list_rem(esd->IPIDataSet, 0); + gf_list_add(lsr->descr->descriptors, desc); + } + while (gf_list_count(esd->IPMPDescriptorPointers)) { + GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->IPMPDescriptorPointers, 0); + gf_list_rem(esd->IPMPDescriptorPointers, 0); + gf_list_add(lsr->descr->descriptors, desc); + } + if (esd->langDesc) { + gf_list_add(lsr->descr->descriptors, esd->langDesc); + esd->langDesc = NULL; + } + while (gf_list_count(esd->extensionDescriptors)) { + GF_Descriptor *desc = (GF_Descriptor *)gf_list_get(esd->extensionDescriptors, 0); + gf_list_rem(esd->extensionDescriptors, 0); + gf_list_add(lsr->descr->descriptors, desc); + } + } + + /*update GF_AVCConfig*/ + if (!lsr->lsr_config) lsr->lsr_config = (GF_LASERConfigurationBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_LSRC); + if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { + lsr->lsr_config->hdr = gf_realloc(lsr->lsr_config->hdr, sizeof(char) * esd->decoderConfig->decoderSpecificInfo->dataLength); + lsr->lsr_config->hdr_size = esd->decoderConfig->decoderSpecificInfo->dataLength; + memcpy(lsr->lsr_config->hdr, esd->decoderConfig->decoderSpecificInfo->data, sizeof(char)*esd->decoderConfig->decoderSpecificInfo->dataLength); + } + gf_odf_desc_del((GF_Descriptor *)esd); + return GF_OK; +} + +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/stbl_read.c b/src/isomedia/stbl_read.c index ad4c478..7902612 100644 --- a/src/isomedia/stbl_read.c +++ b/src/isomedia/stbl_read.c @@ -24,6 +24,8 @@ #include <gpac/internal/isomedia_dev.h> +#ifndef GPAC_DISABLE_ISOM + //Get the sample number GF_Err findEntryForTime(GF_SampleTableBox *stbl, u64 DTS, u8 useCTS, u32 *sampleNumber, u32 *prevSampleNumber) { @@ -511,3 +513,4 @@ u32 stbl_GetSampleFragmentSize(GF_SampleFragmentBox *stsf, u32 sampleNumber, u32 return 0; } +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/stbl_write.c b/src/isomedia/stbl_write.c index 89acfec..77e8dcf 100644 --- a/src/isomedia/stbl_write.c +++ b/src/isomedia/stbl_write.c @@ -24,11 +24,13 @@ #include <gpac/internal/isomedia_dev.h> -/*macro used for table realloc - we allocate much more than needed in order to keep the number of -realloc low, which greatly impacts performances for large files*/ +#ifndef GPAC_DISABLE_ISOM + +/*macro used for table gf_realloc - we allocate much more than needed in order to keep the number of +gf_realloc low, which greatly impacts performances for large files*/ #define ALLOC_INC(a) a = ((a<10) ? 100 : (a*3)/2); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE //adds a DTS in the table and get the sample number of this new sample //we could return an error if a sample with the same DTS already exists @@ -53,7 +55,7 @@ GF_Err stbl_AddDTS(GF_SampleTableBox *stbl, u64 DTS, u32 *sampleNumber, u32 Last if (DTS) return GF_BAD_PARAM; stts->alloc_size = 1; stts->nb_entries = 1; - stts->entries = malloc(sizeof(GF_SttsEntry)); + stts->entries = gf_malloc(sizeof(GF_SttsEntry)); if (!stts->entries) return GF_OUT_OF_MEM; stts->entries[0].sampleCount = 1; stts->entries[0].sampleDelta = LastAUDefDuration; @@ -86,7 +88,7 @@ GF_Err stbl_AddDTS(GF_SampleTableBox *stbl, u64 DTS, u32 *sampleNumber, u32 Last ent->sampleCount --; if (stts->alloc_size==stts->nb_entries) { ALLOC_INC(stts->alloc_size); - stts->entries = realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); + stts->entries = gf_realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); if (!stts->entries) return GF_OUT_OF_MEM; } ent = &stts->entries[stts->nb_entries]; @@ -102,7 +104,7 @@ GF_Err stbl_AddDTS(GF_SampleTableBox *stbl, u64 DTS, u32 *sampleNumber, u32 Last //unpack the DTSs and locate new sample... - DTSs = (u64*)malloc(sizeof(u64) * (stbl->SampleSize->sampleCount+2) ); + DTSs = (u64*)gf_malloc(sizeof(u64) * (stbl->SampleSize->sampleCount+2) ); if (!DTSs) return GF_OUT_OF_MEM; curDTS = 0; sampNum = 0; @@ -123,14 +125,14 @@ GF_Err stbl_AddDTS(GF_SampleTableBox *stbl, u64 DTS, u32 *sampleNumber, u32 Last } } if (!inserted) { - free(DTSs); + gf_free(DTSs); return GF_BAD_PARAM; } /*we will at most insert 2 new entries*/ if (stts->nb_entries+2 >= stts->alloc_size) { stts->alloc_size += 2; - stts->entries = realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); + stts->entries = gf_realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); if (!stts->entries) return GF_OUT_OF_MEM; } @@ -152,7 +154,7 @@ GF_Err stbl_AddDTS(GF_SampleTableBox *stbl, u64 DTS, u32 *sampleNumber, u32 Last stts->entries[j].sampleDelta = (u32) (DTSs[i+1] - DTSs[i]); } } - free(DTSs); + gf_free(DTSs); //reset the cache to the end stts->w_currentSampleNum = stbl->SampleSize->sampleCount + 1; @@ -168,7 +170,7 @@ GF_Err AddCompositionOffset(GF_CompositionOffsetBox *ctts, u32 offset) } else { if (ctts->alloc_size==ctts->nb_entries) { ALLOC_INC(ctts->alloc_size); - ctts->entries = realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); if (!ctts->entries) return GF_OUT_OF_MEM; } ctts->entries[ctts->nb_entries].decodingOffset = offset; @@ -190,7 +192,7 @@ GF_Err stbl_AddCTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 CTSoffset) if (ctts->unpack_mode) { if (ctts->nb_entries==ctts->alloc_size) { ALLOC_INC(ctts->alloc_size); - ctts->entries = realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); if (!ctts->entries) return GF_OUT_OF_MEM; } ctts->entries[ctts->nb_entries].decodingOffset = CTSoffset; @@ -208,7 +210,7 @@ GF_Err stbl_AddCTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 CTSoffset) } //NOPE we are inserting a sample... - CTSs = (u32*)malloc(sizeof(u32) * (stbl->SampleSize->sampleCount+1) ); + CTSs = (u32*)gf_malloc(sizeof(u32) * (stbl->SampleSize->sampleCount+1) ); if (!CTSs) return GF_OUT_OF_MEM; sampNum = 0; for (i=0; i<ctts->nb_entries; i++) { @@ -225,7 +227,7 @@ GF_Err stbl_AddCTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 CTSoffset) /*we will at most add 2 new entries (spliting of an existing one)*/ if (ctts->nb_entries+2>=ctts->alloc_size) { ctts->alloc_size += 2; - ctts->entries = realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); } ctts->entries[0].sampleCount = 1; @@ -242,7 +244,7 @@ GF_Err stbl_AddCTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 CTSoffset) ctts->entries[j].decodingOffset = CTSs[i]; } } - free(CTSs); + gf_free(CTSs); /*we've inserted a sample, therefore the last sample (n) has now number n+1 we cannot use SampleCount because we have probably skipped some samples @@ -269,7 +271,7 @@ GF_Err stbl_repackCTS(GF_CompositionOffsetBox *ctts) } } ctts->nb_entries=j+1; - /*note we don't realloc*/ + /*note we don't gf_realloc*/ return GF_OK; } @@ -291,20 +293,20 @@ GF_Err stbl_unpackCTS(GF_SampleTableBox *stbl) for (j=0; j<packed[i].sampleCount; j++) { if (ctts->nb_entries == ctts->alloc_size) { ALLOC_INC(ctts->alloc_size); - ctts->entries = realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); } ctts->entries[ctts->nb_entries].decodingOffset = packed[i].decodingOffset; ctts->entries[ctts->nb_entries].sampleCount = 1; ctts->nb_entries++; } } - free(packed); + gf_free(packed); remain = stbl->SampleSize->sampleCount - ctts->nb_entries; while (remain) { if (ctts->nb_entries == ctts->alloc_size) { ALLOC_INC(ctts->alloc_size); - ctts->entries = realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); } ctts->entries[ctts->nb_entries].decodingOffset = 0; ctts->entries[ctts->nb_entries].sampleCount = 1; @@ -337,7 +339,7 @@ GF_Err stbl_AddSize(GF_SampleSizeBox *stsz, u32 sampleNumber, u32 size) return GF_OK; } //3- no, need to alloc a size table - stsz->sizes = (u32*)malloc(sizeof(u32) * (stsz->sampleCount + 1)); + stsz->sizes = (u32*)gf_malloc(sizeof(u32) * (stsz->sampleCount + 1)); if (!stsz->sizes) return GF_OUT_OF_MEM; stsz->alloc_size = stsz->sampleCount + 1; @@ -364,12 +366,12 @@ GF_Err stbl_AddSize(GF_SampleSizeBox *stsz, u32 sampleNumber, u32 size) if (!stsz->alloc_size) stsz->alloc_size = stsz->sampleCount; if (stsz->sampleCount == stsz->alloc_size) { ALLOC_INC(stsz->alloc_size); - stsz->sizes = realloc(stsz->sizes, sizeof(u32)*(stsz->alloc_size) ); + stsz->sizes = gf_realloc(stsz->sizes, sizeof(u32)*(stsz->alloc_size) ); if (!stsz->sizes) return GF_OUT_OF_MEM; } stsz->sizes[stsz->sampleCount] = size; } else { - newSizes = (u32*)malloc(sizeof(u32)*(1 + stsz->sampleCount) ); + newSizes = (u32*)gf_malloc(sizeof(u32)*(1 + stsz->sampleCount) ); if (!newSizes) return GF_OUT_OF_MEM; k = 0; for (i = 0; i < stsz->sampleCount; i++) { @@ -379,7 +381,7 @@ GF_Err stbl_AddSize(GF_SampleSizeBox *stsz, u32 sampleNumber, u32 size) } newSizes[i + k] = stsz->sizes[i]; } - free(stsz->sizes); + gf_free(stsz->sizes); stsz->sizes = newSizes; stsz->alloc_size = 1 + stsz->sampleCount; } @@ -397,7 +399,7 @@ GF_Err stbl_AddRAP(GF_SyncSampleBox *stss, u32 sampleNumber) if (stss->sampleNumbers == NULL) { ALLOC_INC(stss->alloc_size); - stss->sampleNumbers = (u32*)malloc(sizeof(u32)*stss->alloc_size); + stss->sampleNumbers = (u32*)gf_malloc(sizeof(u32)*stss->alloc_size); if (!stss->sampleNumbers) return GF_OUT_OF_MEM; stss->sampleNumbers[0] = sampleNumber; stss->nb_entries = 1; @@ -407,12 +409,12 @@ GF_Err stbl_AddRAP(GF_SyncSampleBox *stss, u32 sampleNumber) if (stss->sampleNumbers[stss->nb_entries-1] < sampleNumber) { if (stss->nb_entries==stss->alloc_size) { ALLOC_INC(stss->alloc_size); - stss->sampleNumbers = realloc(stss->sampleNumbers, sizeof(u32) * stss->alloc_size); + stss->sampleNumbers = gf_realloc(stss->sampleNumbers, sizeof(u32) * stss->alloc_size); if (!stss->sampleNumbers) return GF_OUT_OF_MEM; } stss->sampleNumbers[stss->nb_entries] = sampleNumber; } else { - newNumbers = (u32*)malloc(sizeof(u32) * (stss->nb_entries + 1)); + newNumbers = (u32*)gf_malloc(sizeof(u32) * (stss->nb_entries + 1)); if (!newNumbers) return GF_OUT_OF_MEM; //the table is in increasing order of sampleNumber k = 0; @@ -423,7 +425,7 @@ GF_Err stbl_AddRAP(GF_SyncSampleBox *stss, u32 sampleNumber) } newNumbers[i + k] = stss->sampleNumbers[i] + k; } - free(stss->sampleNumbers); + gf_free(stss->sampleNumbers); stss->sampleNumbers = newNumbers; stss->alloc_size = stss->nb_entries+1; } @@ -443,7 +445,7 @@ GF_Err stbl_AddRedundant(GF_SampleTableBox *stbl, u32 sampleNumber) sdtp = stbl->SampleDep; if (sdtp->sampleCount + 1 < sampleNumber) { u32 missed = sampleNumber-1 - sdtp->sampleCount; - sdtp->sample_info = (u8*) realloc(sdtp->sample_info, sizeof(u8) * (sdtp->sampleCount+missed) ); + sdtp->sample_info = (u8*) gf_realloc(sdtp->sample_info, sizeof(u8) * (sdtp->sampleCount+missed) ); while (missed) { u8 isRAP; if (stbl->SyncSample) stbl_GetSampleRAP(stbl->SyncSample, sdtp->sampleCount+1, &isRAP, NULL, NULL); @@ -454,7 +456,7 @@ GF_Err stbl_AddRedundant(GF_SampleTableBox *stbl, u32 sampleNumber) } } - sdtp->sample_info = (u8*) realloc(sdtp->sample_info, sizeof(u8) * (sdtp->sampleCount + 1)); + sdtp->sample_info = (u8*) gf_realloc(sdtp->sample_info, sizeof(u8) * (sdtp->sampleCount + 1)); if (!sdtp->sample_info) return GF_OUT_OF_MEM; if (sdtp->sampleCount < sampleNumber) { sdtp->sample_info[sdtp->sampleCount] = 0x29; @@ -481,7 +483,7 @@ GF_Err stbl_AddShadow(GF_ShadowSyncBox *stsh, u32 sampleNumber, u32 shadowNumber return GF_OK; } else if (ent->shadowedSampleNumber > shadowNumber) break; } - ent = (GF_StshEntry*)malloc(sizeof(GF_StshEntry)); + ent = (GF_StshEntry*)gf_malloc(sizeof(GF_StshEntry)); if (!ent) return GF_OUT_OF_MEM; ent->shadowedSampleNumber = shadowNumber; ent->syncSampleNumber = sampleNumber; @@ -516,7 +518,8 @@ GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIn if (offset > 0xFFFFFFFF) { co64 = (GF_ChunkLargeOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CO64); co64->nb_entries = stco->nb_entries + 1; - co64->offsets = (u64*)malloc(sizeof(u64) * co64->nb_entries); + co64->alloc_size = co64->nb_entries; + co64->offsets = (u64*)gf_malloc(sizeof(u64) * co64->nb_entries); if (!co64->offsets) return GF_OUT_OF_MEM; k = 0; for (i=0;i<stco->nb_entries; i++) { @@ -535,14 +538,14 @@ GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIn if (!stco->alloc_size) stco->alloc_size = stco->nb_entries; if (stco->nb_entries == stco->alloc_size) { ALLOC_INC(stco->alloc_size); - stco->offsets = (u32*)realloc(stco->offsets, sizeof(u32) * stco->alloc_size); + stco->offsets = (u32*)gf_realloc(stco->offsets, sizeof(u32) * stco->alloc_size); if (!stco->offsets) return GF_OUT_OF_MEM; } stco->offsets[stco->nb_entries] = (u32) offset; stco->nb_entries += 1; } else { //nope. we're inserting - newOff = (u32*)malloc(sizeof(u32) * (stco->nb_entries + 1)); + newOff = (u32*)gf_malloc(sizeof(u32) * (stco->nb_entries + 1)); if (!newOff) return GF_OUT_OF_MEM; k=0; for (i=0; i<stco->nb_entries; i++) { @@ -552,7 +555,7 @@ GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIn } newOff[i+k] = stco->offsets[i]; } - free(stco->offsets); + gf_free(stco->offsets); stco->offsets = newOff; stco->nb_entries ++; stco->alloc_size = stco->nb_entries; @@ -565,14 +568,14 @@ GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIn if (!co64->alloc_size) co64->alloc_size = co64->nb_entries; if (co64->nb_entries == co64->alloc_size) { ALLOC_INC(co64->alloc_size); - co64->offsets = (u64*)realloc(co64->offsets, sizeof(u64) * co64->alloc_size); + co64->offsets = (u64*)gf_realloc(co64->offsets, sizeof(u64) * co64->alloc_size); if (!co64->offsets) return GF_OUT_OF_MEM; } co64->offsets[co64->nb_entries] = offset; co64->nb_entries += 1; } else { //nope. we're inserting - newLarge = (u64*)malloc(sizeof(u64) * (co64->nb_entries + 1)); + newLarge = (u64*)gf_malloc(sizeof(u64) * (co64->nb_entries + 1)); if (!newLarge) return GF_OUT_OF_MEM; k=0; for (i=0; i<co64->nb_entries; i++) { @@ -582,7 +585,7 @@ GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIn } newLarge[i+k] = co64->offsets[i]; } - free(co64->offsets); + gf_free(co64->offsets); co64->offsets = newLarge; co64->nb_entries++; co64->alloc_size++; @@ -591,13 +594,13 @@ GF_Err stbl_AddChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u32 StreamDescIn if (stsc->nb_entries==stsc->alloc_size) { ALLOC_INC(stsc->alloc_size); - stsc->entries = realloc(stsc->entries, sizeof(GF_StscEntry)*stsc->alloc_size); + stsc->entries = gf_realloc(stsc->entries, sizeof(GF_StscEntry)*stsc->alloc_size); if (!stsc->entries) return GF_OUT_OF_MEM; } if (sampleNumber == stsc->nb_entries + 1) { ent = &stsc->entries[stsc->nb_entries]; } else { - memmove(&stsc->entries[sampleNumber-1], &stsc->entries[sampleNumber], sizeof(GF_StscEntry)*(stsc->nb_entries+1-sampleNumber)); + memmove(&stsc->entries[sampleNumber], &stsc->entries[sampleNumber-1], sizeof(GF_StscEntry)*(stsc->nb_entries+1-sampleNumber)); ent = &stsc->entries[sampleNumber-1]; } ent->isEdited = 0; @@ -652,7 +655,8 @@ GF_Err stbl_SetChunkOffset(GF_MediaBox *mdia, u32 sampleNumber, u64 offset) if (offset > 0xFFFFFFFF) { co64 = (GF_ChunkLargeOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CO64); co64->nb_entries = ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->nb_entries; - co64->offsets = (u64*)malloc(sizeof(u64)*co64->nb_entries); + co64->alloc_size = co64->nb_entries; + co64->offsets = (u64*)gf_malloc(sizeof(u64)*co64->nb_entries); if (!co64->offsets) return GF_OUT_OF_MEM; for (i=0;i<co64->nb_entries; i++) { co64->offsets[i] = (u64) ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets[i]; @@ -700,7 +704,7 @@ GF_Err stbl_SetSampleSize(GF_SampleSizeBox *stsz, u32 SampleNumber, u32 size) return GF_OK; } //nope, we have to rewrite a table - stsz->sizes = (u32*)malloc(sizeof(u32)*stsz->sampleCount); + stsz->sizes = (u32*)gf_malloc(sizeof(u32)*stsz->sampleCount); if (!stsz->sizes) return GF_OUT_OF_MEM; for (i=0; i<stsz->sampleCount; i++) stsz->sizes[i] = stsz->sampleSize; stsz->sampleSize = 0; @@ -733,7 +737,7 @@ GF_Err stbl_SetSampleRAP(GF_SyncSampleBox *stss, u32 SampleNumber, u8 isRAP) if (!isRAP) return GF_OK; if (stss->nb_entries==stss->alloc_size) { ALLOC_INC(stss->alloc_size); - stss->sampleNumbers = realloc(stss->sampleNumbers, sizeof(u32)*stss->alloc_size); + stss->sampleNumbers = gf_realloc(stss->sampleNumbers, sizeof(u32)*stss->alloc_size); if (!stss->sampleNumbers) return GF_OUT_OF_MEM; } @@ -769,7 +773,7 @@ GF_Err stbl_SetSyncShadow(GF_ShadowSyncBox *stsh, u32 sampleNumber, u32 syncSamp if (ent->shadowedSampleNumber > sampleNumber) break; } //we need a new one... - ent = (GF_StshEntry*)malloc(sizeof(GF_StshEntry)); + ent = (GF_StshEntry*)gf_malloc(sizeof(GF_StshEntry)); if (!ent) return GF_OUT_OF_MEM; ent->shadowedSampleNumber = sampleNumber; ent->syncSampleNumber = syncSample; @@ -810,7 +814,7 @@ GF_Err stbl_RemoveDTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 LastAUDefDu if (!ent->sampleCount) stts->nb_entries--; } else { //unpack the DTSs... - DTSs = (u64*)malloc(sizeof(u64) * (stbl->SampleSize->sampleCount - 1)); + DTSs = (u64*)gf_malloc(sizeof(u64) * (stbl->SampleSize->sampleCount - 1)); if (!DTSs) return GF_OUT_OF_MEM; curDTS = 0; sampNum = 0; @@ -850,7 +854,7 @@ GF_Err stbl_RemoveDTS(GF_SampleTableBox *stbl, u32 sampleNumber, u32 LastAUDefDu } } stts->w_LastDTS = DTSs[stbl->SampleSize->sampleCount - 2]; - free(DTSs); + gf_free(DTSs); } //reset write the cache to the end @@ -891,7 +895,7 @@ GF_Err stbl_RemoveSize(GF_SampleSizeBox *stsz, u32 sampleNumber) { //last sample if (stsz->sampleCount == 1) { - if (stsz->sizes) free(stsz->sizes); + if (stsz->sizes) gf_free(stsz->sizes); stsz->sizes = NULL; stsz->sampleCount = 0; return GF_OK; @@ -931,16 +935,16 @@ GF_Err stbl_RemoveChunk(GF_SampleTableBox *stbl, u32 sampleNumber) stbl->SampleToChunk->currentChunk = 1; stbl->SampleToChunk->ghostNumber = 1; - //realloc the chunk offset + //gf_realloc the chunk offset if (stbl->ChunkOffset->type == GF_ISOM_BOX_TYPE_STCO) { if (!stbl->SampleSize->sampleCount) { - free(((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets); + gf_free(((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets); ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets = NULL; ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->nb_entries = 0; ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->alloc_size = 0; return GF_OK; } - offsets = (u32*)malloc(sizeof(u32) * (stbl->SampleSize->sampleCount)); + offsets = (u32*)gf_malloc(sizeof(u32) * (stbl->SampleSize->sampleCount)); if (!offsets) return GF_OUT_OF_MEM; k=0; for (i=0; i<stbl->SampleSize->sampleCount+1; i++) { @@ -950,20 +954,20 @@ GF_Err stbl_RemoveChunk(GF_SampleTableBox *stbl, u32 sampleNumber) offsets[i-k] = ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets[i]; } } - free(((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets); + gf_free(((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets); ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->offsets = offsets; ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->alloc_size = stbl->SampleSize->sampleCount; ((GF_ChunkOffsetBox *)stbl->ChunkOffset)->nb_entries -= 1; } else { if (!stbl->SampleSize->sampleCount) { - free(((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->offsets); + gf_free(((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->offsets); ((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->offsets = NULL; ((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->nb_entries = 0; ((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->alloc_size = 0; return GF_OK; } - Loffsets = (u64*)malloc(sizeof(u64) * (stbl->SampleSize->sampleCount)); + Loffsets = (u64*)gf_malloc(sizeof(u64) * (stbl->SampleSize->sampleCount)); if (!Loffsets) return GF_OUT_OF_MEM; k=0; for (i=0; i<stbl->SampleSize->sampleCount+1; i++) { @@ -973,7 +977,7 @@ GF_Err stbl_RemoveChunk(GF_SampleTableBox *stbl, u32 sampleNumber) Loffsets[i-k] = ((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->offsets[i]; } } - free(((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->offsets); + gf_free(((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->offsets); ((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->offsets = Loffsets; ((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->alloc_size = stbl->SampleSize->sampleCount; ((GF_ChunkLargeOffsetBox *)stbl->ChunkOffset)->nb_entries -= 1; @@ -991,7 +995,7 @@ GF_Err stbl_RemoveRAP(GF_SampleTableBox *stbl, u32 sampleNumber) if (stss->nb_entries == 1) { if (stss->sampleNumbers[0] != sampleNumber) return GF_OK; //free our numbers but don't delete (all samples are NON-sync - free(stss->sampleNumbers); + gf_free(stss->sampleNumbers); stss->sampleNumbers = NULL; stss->r_LastSampleIndex = stss->r_LastSyncSample = 0; stss->alloc_size = stss->nb_entries = 0; @@ -1023,7 +1027,7 @@ GF_Err stbl_RemoveRedundant(GF_SampleTableBox *stbl, u32 SampleNumber) i = stbl->SampleDep->sampleCount - SampleNumber; if (i) memmove(&stbl->SampleDep->sample_info[SampleNumber-1], & stbl->SampleDep->sample_info[SampleNumber], sizeof(u8)*i); - stbl->SampleDep->sample_info = (u8*)realloc(stbl->SampleDep->sample_info, sizeof(u8) * (stbl->SampleDep->sampleCount-1)); + stbl->SampleDep->sample_info = (u8*)gf_realloc(stbl->SampleDep->sample_info, sizeof(u8) * (stbl->SampleDep->sampleCount-1)); stbl->SampleDep->sampleCount-=1; return GF_OK; } @@ -1061,19 +1065,19 @@ GF_Err stbl_SetPaddingBits(GF_SampleTableBox *stbl, u32 SampleNumber, u8 bits) //alloc if (!stbl->PaddingBits->padbits || !stbl->PaddingBits->SampleCount) { stbl->PaddingBits->SampleCount = stbl->SampleSize->sampleCount; - stbl->PaddingBits->padbits = (u8*)malloc(sizeof(u8)*stbl->PaddingBits->SampleCount); + stbl->PaddingBits->padbits = (u8*)gf_malloc(sizeof(u8)*stbl->PaddingBits->SampleCount); if (!stbl->PaddingBits->padbits) return GF_OUT_OF_MEM; memset(stbl->PaddingBits->padbits, 0, sizeof(u8)*stbl->PaddingBits->SampleCount); } - //realloc (this is needed in case n out of k samples get padding added) + //gf_realloc (this is needed in case n out of k samples get padding added) if (stbl->PaddingBits->SampleCount < stbl->SampleSize->sampleCount) { - p = (u8*)malloc(sizeof(u8) * stbl->SampleSize->sampleCount); + p = (u8*)gf_malloc(sizeof(u8) * stbl->SampleSize->sampleCount); if (!p) return GF_OUT_OF_MEM; //set everything to 0 memset(p, 0, stbl->SampleSize->sampleCount); //copy our previous table memcpy(p, stbl->PaddingBits->padbits, stbl->PaddingBits->SampleCount); - free(stbl->PaddingBits->padbits); + gf_free(stbl->PaddingBits->padbits); stbl->PaddingBits->padbits = p; stbl->PaddingBits->SampleCount = stbl->SampleSize->sampleCount; } @@ -1097,7 +1101,7 @@ GF_Err stbl_RemovePaddingBits(GF_SampleTableBox *stbl, u32 SampleNumber) } //reallocate and check size by the way... - p = (u8 *)malloc(sizeof(u8) * (stbl->PaddingBits->SampleCount - 1)); + p = (u8 *)gf_malloc(sizeof(u8) * (stbl->PaddingBits->SampleCount - 1)); if (!p) return GF_OUT_OF_MEM; k=0; @@ -1109,7 +1113,7 @@ GF_Err stbl_RemovePaddingBits(GF_SampleTableBox *stbl, u32 SampleNumber) } stbl->PaddingBits->SampleCount -= 1; - free(stbl->PaddingBits->padbits); + gf_free(stbl->PaddingBits->padbits); stbl->PaddingBits->padbits = p; return GF_OK; } @@ -1142,7 +1146,7 @@ GF_Err stbl_AddSampleFragment(GF_SampleTableBox *stbl, u32 sampleNumber, u16 siz for (; i<count; i++) { ent = (GF_StsfEntry *)gf_list_get(stsf->entryList, i); if (ent->SampleNumber > sampleNumber) { - ent = (GF_StsfEntry *)malloc(sizeof(GF_StsfEntry)); + ent = (GF_StsfEntry *)gf_malloc(sizeof(GF_StsfEntry)); if (!ent) return GF_OUT_OF_MEM; memset(ent, 0, sizeof(GF_StsfEntry)); ent->SampleNumber = sampleNumber; @@ -1167,12 +1171,12 @@ GF_Err stbl_AddSampleFragment(GF_SampleTableBox *stbl, u32 sampleNumber, u16 siz ent_found: if (!ent->fragmentCount) { ent->fragmentCount = 1; - ent->fragmentSizes = (u16*)malloc(sizeof(u16)); + ent->fragmentSizes = (u16*)gf_malloc(sizeof(u16)); if (!ent->fragmentSizes) return GF_OUT_OF_MEM; ent->fragmentSizes[0] = size; return GF_OK; } - ent->fragmentSizes = (u16*)realloc(ent->fragmentSizes, sizeof(u16) * (ent->fragmentCount+1)); + ent->fragmentSizes = (u16*)gf_realloc(ent->fragmentSizes, sizeof(u16) * (ent->fragmentCount+1)); if (!ent->fragmentSizes) return GF_OUT_OF_MEM; ent->fragmentSizes[ent->fragmentCount] = size; ent->fragmentCount += 1; @@ -1190,8 +1194,8 @@ GF_Err stbl_RemoveSampleFragments(GF_SampleTableBox *stbl, u32 sampleNumber) while ((ent = (GF_StsfEntry *)gf_list_enum(stsf->entryList, &i))) { if (ent->SampleNumber == sampleNumber) { gf_list_rem(stsf->entryList, i-1); - if (ent->fragmentSizes) free(ent->fragmentSizes); - free(ent); + if (ent->fragmentSizes) gf_free(ent->fragmentSizes); + gf_free(ent); goto exit; } } @@ -1209,9 +1213,9 @@ GF_Err stbl_SampleSizeAppend(GF_SampleSizeBox *stsz, u32 data_size) u32 i; if (!stsz || !stsz->sampleCount) return GF_BAD_PARAM; - //we must realloc our table + //we must gf_realloc our table if (stsz->sampleSize) { - stsz->sizes = (u32*)malloc(sizeof(u32)*stsz->sampleCount); + stsz->sizes = (u32*)gf_malloc(sizeof(u32)*stsz->sampleCount); if (!stsz->sizes) return GF_OUT_OF_MEM; for (i=0; i<stsz->sampleCount; i++) stsz->sizes[i] = stsz->sampleSize; stsz->sampleSize = 0; @@ -1220,7 +1224,7 @@ GF_Err stbl_SampleSizeAppend(GF_SampleSizeBox *stsz, u32 data_size) return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ @@ -1236,7 +1240,7 @@ void stbl_AppendTime(GF_SampleTableBox *stbl, u32 duration) } if (stts->nb_entries==stts->alloc_size) { ALLOC_INC(stts->alloc_size); - stts->entries = realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); + stts->entries = gf_realloc(stts->entries, sizeof(GF_SttsEntry)*stts->alloc_size); if (!stts->entries) return; } stts->entries[stts->nb_entries].sampleCount = 1; @@ -1260,7 +1264,7 @@ void stbl_AppendSize(GF_SampleTableBox *stbl, u32 size) if (!stbl->SampleSize->sizes || (stbl->SampleSize->sampleCount==stbl->SampleSize->alloc_size)) { Bool init_table = (stbl->SampleSize->sizes==NULL) ? 1 : 0; ALLOC_INC(stbl->SampleSize->alloc_size); - stbl->SampleSize->sizes = (u32 *)realloc(stbl->SampleSize->sizes, sizeof(u32)*stbl->SampleSize->alloc_size); + stbl->SampleSize->sizes = (u32 *)gf_realloc(stbl->SampleSize->sizes, sizeof(u32)*stbl->SampleSize->alloc_size); if (!stbl->SampleSize->sizes) return; if (init_table) { @@ -1287,7 +1291,8 @@ void stbl_AppendChunk(GF_SampleTableBox *stbl, u64 offset) if (offset>0xFFFFFFFF) { co64 = (GF_ChunkLargeOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CO64); co64->nb_entries = stco->nb_entries + 1; - co64->offsets = (u64*)malloc(sizeof(u64) * co64->nb_entries); + co64->alloc_size = co64->nb_entries; + co64->offsets = (u64*)gf_malloc(sizeof(u64) * co64->nb_entries); if (!co64->offsets) return; for (i=0; i<stco->nb_entries; i++) co64->offsets[i] = stco->offsets[i]; co64->offsets[i] = offset; @@ -1296,11 +1301,11 @@ void stbl_AppendChunk(GF_SampleTableBox *stbl, u64 offset) return; } //we're fine - new_offsets = (u32*)malloc(sizeof(u32)*(stco->nb_entries+1)); + new_offsets = (u32*)gf_malloc(sizeof(u32)*(stco->nb_entries+1)); if (!new_offsets) return; for (i=0; i<stco->nb_entries; i++) new_offsets[i] = stco->offsets[i]; new_offsets[i] = (u32) offset; - if (stco->offsets) free(stco->offsets); + if (stco->offsets) gf_free(stco->offsets); stco->offsets = new_offsets; stco->nb_entries += 1; stco->alloc_size = stco->nb_entries; @@ -1308,11 +1313,11 @@ void stbl_AppendChunk(GF_SampleTableBox *stbl, u64 offset) //large offsets else { co64 = (GF_ChunkLargeOffsetBox *)stbl->ChunkOffset; - off_64 = (u64*)malloc(sizeof(u32)*(co64->nb_entries+1)); + off_64 = (u64*)gf_malloc(sizeof(u32)*(co64->nb_entries+1)); if (!off_64) return; for (i=0; i<co64->nb_entries; i++) off_64[i] = co64->offsets[i]; off_64[i] = offset; - if (co64->offsets) free(co64->offsets); + if (co64->offsets) gf_free(co64->offsets); co64->offsets = off_64; co64->nb_entries += 1; co64->alloc_size = co64->nb_entries; @@ -1338,7 +1343,7 @@ void stbl_AppendSampleToChunk(GF_SampleTableBox *stbl, u32 DescIndex, u32 sample } if (stsc->nb_entries==stsc->alloc_size) { ALLOC_INC(stsc->alloc_size); - stsc->entries = realloc(stsc->entries, sizeof(GF_StscEntry)*stsc->alloc_size); + stsc->entries = gf_realloc(stsc->entries, sizeof(GF_StscEntry)*stsc->alloc_size); if (!stsc->entries) return; } //ok we need a new entry - this assumes this function is called AFTER AppendChunk @@ -1363,7 +1368,7 @@ void stbl_AppendRAP(GF_SampleTableBox *stbl, u8 isRap) //nope, create one stbl->SyncSample = (GF_SyncSampleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSS); if (stbl->SampleSize->sampleCount > 1) { - stbl->SyncSample->sampleNumbers = (u32*)malloc(sizeof(u32) * (stbl->SampleSize->sampleCount-1)); + stbl->SyncSample->sampleNumbers = (u32*)gf_malloc(sizeof(u32) * (stbl->SampleSize->sampleCount-1)); if (!stbl->SyncSample->sampleNumbers) return; for (i=0; i<stbl->SampleSize->sampleCount-1; i++) stbl->SyncSample->sampleNumbers[i] = i+1; @@ -1377,7 +1382,7 @@ void stbl_AppendRAP(GF_SampleTableBox *stbl, u8 isRap) if (stbl->SyncSample->alloc_size == stbl->SyncSample->nb_entries) { ALLOC_INC(stbl->SyncSample->alloc_size); - stbl->SyncSample->sampleNumbers = (u32*) realloc(stbl->SyncSample->sampleNumbers, sizeof(u32) * stbl->SyncSample->alloc_size); + stbl->SyncSample->sampleNumbers = (u32*) gf_realloc(stbl->SyncSample->sampleNumbers, sizeof(u32) * stbl->SyncSample->alloc_size); if (!stbl->SyncSample->sampleNumbers) return; } stbl->SyncSample->sampleNumbers[stbl->SyncSample->nb_entries] = stbl->SampleSize->sampleCount; @@ -1390,13 +1395,13 @@ void stbl_AppendPadding(GF_SampleTableBox *stbl, u8 padding) u8 *pad_bits; if (!stbl->PaddingBits) stbl->PaddingBits = (GF_PaddingBitsBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_FADB); - pad_bits = (u8*)malloc(sizeof(u8) * stbl->SampleSize->sampleCount); + pad_bits = (u8*)gf_malloc(sizeof(u8) * stbl->SampleSize->sampleCount); if (!pad_bits) return; memset(pad_bits, 0, sizeof(pad_bits)); // for (i=0; i<stbl->SampleSize->sampleCount; i++) pad_bits[i] = 0; for (i=0; i<stbl->PaddingBits->SampleCount; i++) pad_bits[i] = stbl->PaddingBits->padbits[i]; pad_bits[stbl->SampleSize->sampleCount-1] = padding; - if (stbl->PaddingBits->padbits) free(stbl->PaddingBits->padbits); + if (stbl->PaddingBits->padbits) gf_free(stbl->PaddingBits->padbits); stbl->PaddingBits->padbits = pad_bits; stbl->PaddingBits->SampleCount = stbl->SampleSize->sampleCount; } @@ -1415,7 +1420,7 @@ void stbl_AppendCTSOffset(GF_SampleTableBox *stbl, u32 CTSOffset) } if (ctts->nb_entries==ctts->alloc_size) { ALLOC_INC(ctts->alloc_size); - ctts->entries = realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); + ctts->entries = gf_realloc(ctts->entries, sizeof(GF_DttsEntry)*ctts->alloc_size); } ctts->entries[ctts->nb_entries].decodingOffset = CTSOffset; ctts->entries[ctts->nb_entries].sampleCount = 1; @@ -1426,7 +1431,7 @@ void stbl_AppendDegradation(GF_SampleTableBox *stbl, u16 DegradationPriority) { if (!stbl->DegradationPriority) stbl->DegradationPriority = (GF_DegradationPriorityBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STDP); - stbl->DegradationPriority->priorities = (u16 *)realloc(stbl->DegradationPriority->priorities, sizeof(u16) * stbl->SampleSize->sampleCount); + stbl->DegradationPriority->priorities = (u16 *)gf_realloc(stbl->DegradationPriority->priorities, sizeof(u16) * stbl->SampleSize->sampleCount); stbl->DegradationPriority->priorities[stbl->SampleSize->sampleCount-1] = DegradationPriority; stbl->DegradationPriority->nb_entries = stbl->SampleSize->sampleCount; } @@ -1434,7 +1439,7 @@ void stbl_AppendDegradation(GF_SampleTableBox *stbl, u16 DegradationPriority) void stbl_AppendDepType(GF_SampleTableBox *stbl, u32 DepType) { if (!stbl->SampleDep) stbl->SampleDep= (GF_SampleDependencyTypeBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_SDTP); - stbl->SampleDep->sample_info = (u8*)realloc(stbl->SampleDep->sample_info, sizeof(u8)*stbl->SampleSize->sampleCount ); + stbl->SampleDep->sample_info = (u8*)gf_realloc(stbl->SampleDep->sample_info, sizeof(u8)*stbl->SampleSize->sampleCount ); stbl->SampleDep->sample_info[stbl->SampleDep->sampleCount] = DepType; stbl->SampleDep->sampleCount = stbl->SampleSize->sampleCount; @@ -1476,7 +1481,7 @@ GF_Err stbl_UnpackOffsets(GF_SampleTableBox *stbl) stco_tmp = (GF_ChunkOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STCO); if (!stco_tmp) return GF_OUT_OF_MEM; stco_tmp->nb_entries = stbl->SampleSize->sampleCount; - stco_tmp->offsets = (u32*)malloc(stco_tmp->nb_entries * sizeof(u32)); + stco_tmp->offsets = (u32*)gf_malloc(stco_tmp->nb_entries * sizeof(u32)); if (!stco_tmp->offsets) { gf_isom_box_del((GF_Box*)stco_tmp); return GF_OUT_OF_MEM; @@ -1487,7 +1492,7 @@ GF_Err stbl_UnpackOffsets(GF_SampleTableBox *stbl) co64_tmp = (GF_ChunkLargeOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CO64); if (!co64_tmp) return GF_OUT_OF_MEM; co64_tmp->nb_entries = stbl->SampleSize->sampleCount; - co64_tmp->offsets = (u64*)malloc(co64_tmp->nb_entries * sizeof(u64)); + co64_tmp->offsets = (u64*)gf_malloc(co64_tmp->nb_entries * sizeof(u64)); if (!co64_tmp->offsets) { gf_isom_box_del((GF_Box*)co64_tmp); return GF_OUT_OF_MEM; @@ -1501,7 +1506,7 @@ GF_Err stbl_UnpackOffsets(GF_SampleTableBox *stbl) stsc_tmp = (GF_SampleToChunkBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STSC); stsc_tmp->nb_entries = stsc_tmp->alloc_size = stbl->SampleSize->sampleCount; - stsc_tmp->entries = malloc(sizeof(GF_StscEntry)*stsc_tmp->nb_entries); + stsc_tmp->entries = gf_malloc(sizeof(GF_StscEntry)*stsc_tmp->nb_entries); if (!stsc_tmp->entries) return GF_OUT_OF_MEM; //OK write our two tables... @@ -1549,9 +1554,7 @@ err_exit: return e; } -#ifndef GPAC_READ_ONLY - - +#ifndef GPAC_DISABLE_ISOM_WRITE static GFINLINE GF_Err stbl_AddOffset(GF_Box **a, u64 offset) { @@ -1566,7 +1569,8 @@ static GFINLINE GF_Err stbl_AddOffset(GF_Box **a, u64 offset) co64 = (GF_ChunkLargeOffsetBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_CO64); if (!co64) return GF_OUT_OF_MEM; co64->nb_entries = stco->nb_entries + 1; - co64->offsets = (u64*)malloc(co64->nb_entries * sizeof(u64)); + co64->alloc_size = co64->nb_entries; + co64->offsets = (u64*)gf_malloc(co64->nb_entries * sizeof(u64)); if (!co64->offsets) { gf_isom_box_del((GF_Box *)co64); return GF_OUT_OF_MEM; @@ -1583,7 +1587,7 @@ static GFINLINE GF_Err stbl_AddOffset(GF_Box **a, u64 offset) //OK, stick with regular... if (stco->nb_entries==stco->alloc_size) { ALLOC_INC(stco->alloc_size); - stco->offsets = (u32*)realloc(stco->offsets, stco->alloc_size * sizeof(u32)); + stco->offsets = (u32*)gf_realloc(stco->offsets, stco->alloc_size * sizeof(u32)); if (!stco->offsets) return GF_OUT_OF_MEM; } @@ -1594,7 +1598,7 @@ static GFINLINE GF_Err stbl_AddOffset(GF_Box **a, u64 offset) co64 = (GF_ChunkLargeOffsetBox *) *a; if (co64->nb_entries==co64->alloc_size) { ALLOC_INC(co64->alloc_size); - co64->offsets = (u64*)realloc(co64->offsets, co64->alloc_size * sizeof(u64)); + co64->offsets = (u64*)gf_realloc(co64->offsets, co64->alloc_size * sizeof(u64)); if (!co64->offsets) return GF_OUT_OF_MEM; } co64->offsets[co64->nb_entries] = offset; @@ -1662,7 +1666,7 @@ GF_Err stbl_SetChunkAndOffset(GF_SampleTableBox *stbl, u32 sampleNumber, u32 Str if (the_stsc->nb_entries==the_stsc->alloc_size) { ALLOC_INC(the_stsc->alloc_size); - the_stsc->entries = realloc(the_stsc->entries, sizeof(GF_StscEntry)*the_stsc->alloc_size); + the_stsc->entries = gf_realloc(the_stsc->entries, sizeof(GF_StscEntry)*the_stsc->alloc_size); if (!the_stsc->entries) return GF_OUT_OF_MEM; } //create a new entry (could be the first one, BTW) @@ -1704,12 +1708,13 @@ GF_Err gf_isom_refresh_size_info(GF_ISOFile *file, u32 trackNumber) } } if (size) { - free(stsz->sizes); + gf_free(stsz->sizes); stsz->sizes = NULL; stsz->sampleSize = size; } return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/track.c b/src/isomedia/track.c index ec80e9e..951130e 100644 --- a/src/isomedia/track.c +++ b/src/isomedia/track.c @@ -23,6 +23,9 @@ */ #include <gpac/internal/isomedia_dev.h> +#include <gpac/constants.h> + +#ifndef GPAC_DISABLE_ISOM GF_TrackBox *GetTrackbyID(GF_MovieBox *moov, u32 TrackID) { @@ -201,11 +204,9 @@ default_sync: esd->slConfig->timestampResolution = trak->Media->mediaHeader->timeScale; //NO OCR from MP4File streams (eg, constant OC Res one) esd->slConfig->OCRLength = 0; - if (OCRTrack) { - esd->slConfig->OCRResolution = OCRTrack->Media->mediaHeader->timeScale; - } else { - esd->slConfig->OCRResolution = 0; - } + esd->slConfig->OCRResolution = 0; +// if (OCRTrack) esd->slConfig->OCRResolution = OCRTrack->Media->mediaHeader->timeScale; + stbl = trak->Media->information->sampleTable; // a little optimization here: if all our samples are sync, //set the RAPOnly to true... for external users... @@ -329,7 +330,7 @@ GF_Err SetTrackDuration(GF_TrackBox *trak) } } else { //assert the timeScales are non-NULL - if (!trak->moov->mvhd->timeScale && !trak->Media->mediaHeader->timeScale) return GF_ISOM_INVALID_FILE; + if (!trak->moov->mvhd->timeScale || !trak->Media->mediaHeader->timeScale) return GF_ISOM_INVALID_FILE; trackDuration = (trak->Media->mediaHeader->duration * trak->moov->mvhd->timeScale) / trak->Media->mediaHeader->timeScale; } trak->Header->duration = trackDuration; @@ -338,14 +339,14 @@ GF_Err SetTrackDuration(GF_TrackBox *trak) } -#ifndef GPAC_ISOM_NO_FRAGMENTS +#ifndef GPAC_DISABLE_ISOM_FRAGMENTS GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 *moof_offset) { u32 i, j, chunk_size; u64 base_offset, data_offset; u32 def_duration, DescIndex, def_size, def_flags; - u32 duration, size, flags, cts_offset; + u32 duration, size, flags, cts_offset, prev_trun_data_offset; u8 pad, sync; u16 degr; GF_TrackFragmentRunBox *trun; @@ -360,6 +361,7 @@ GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 *moof_offset void stbl_AppendPadding(GF_SampleTableBox *stbl, u8 padding); void stbl_AppendDegradation(GF_SampleTableBox *stbl, u16 DegradationPriority); + if (trak->Header->trackID != traf->tfhd->trackID) return GF_OK; //setup all our defaults DescIndex = (traf->tfhd->flags & GF_ISOM_TRAF_SAMPLE_DESC) ? traf->tfhd->sample_desc_index : traf->trex->def_sample_desc_index; @@ -371,6 +373,7 @@ GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 *moof_offset base_offset = (traf->tfhd->flags & GF_ISOM_TRAF_BASE_OFFSET) ? traf->tfhd->base_data_offset : *moof_offset; chunk_size = 0; + prev_trun_data_offset = 0; i=0; while ((trun = (GF_TrackFragmentRunBox *)gf_list_enum(traf->TrackRuns, &i))) { @@ -400,8 +403,16 @@ GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 *moof_offset //aggregated offset if (!(traf->tfhd->flags & GF_ISOM_TRAF_BASE_OFFSET)) data_offset += chunk_size; - if (trun->flags & GF_ISOM_TRUN_DATA_OFFSET) data_offset += trun->data_offset; - + if (trun->flags & GF_ISOM_TRUN_DATA_OFFSET) { + data_offset += trun->data_offset; + /*reset chunk size since data is now relative to this trun*/ + chunk_size = 0; + /*remember this data offset for following trun*/ + prev_trun_data_offset = trun->data_offset; + } else { + /*data offset is previous chunk size plus previous offset of the trun*/ + data_offset += prev_trun_data_offset; + } stbl_AppendChunk(trak->Media->information->sampleTable, data_offset); //then sampleToChunk stbl_AppendSampleToChunk(trak->Media->information->sampleTable, @@ -431,7 +442,7 @@ GF_Err MergeTrack(GF_TrackBox *trak, GF_TrackFragmentBox *traf, u64 *moof_offset #endif -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE //used to check if a TrackID is available u8 RequestTrack(GF_MovieBox *moov, u32 TrackID) @@ -545,6 +556,7 @@ GF_Err NewMedia(GF_MediaBox **mdia, u32 MediaType, u32 TimeScale) str = "GPAC MPEG-4 MPEG-J Handler"; break; case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: mediaInfo = gf_isom_box_new(GF_ISOM_BOX_TYPE_NMHD); str = "GPAC Streaming Text Handler"; break; @@ -563,7 +575,7 @@ GF_Err NewMedia(GF_MediaBox **mdia, u32 MediaType, u32 TimeScale) mdhd->timeScale = TimeScale; hdlr->handlerType = MediaType; - hdlr->nameUTF8 = strdup(str); + hdlr->nameUTF8 = gf_strdup(str); //first set-up the sample table... stbl = (GF_SampleTableBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STBL); @@ -593,7 +605,7 @@ err_exit: if (mdhd) gf_isom_box_del((GF_Box *)mdhd); if (minf) gf_isom_box_del((GF_Box *)minf); if (hdlr) { - if (hdlr->nameUTF8) free(hdlr->nameUTF8); + if (hdlr->nameUTF8) gf_free(hdlr->nameUTF8); gf_isom_box_del((GF_Box *)hdlr); } return e; @@ -729,9 +741,16 @@ GF_Err Track_SetStreamDescriptor(GF_TrackBox *trak, u32 StreamDescriptionIndex, entry_a->esd->desc = esd; break; case GF_ISOM_BOX_TYPE_AVC1: + case GF_ISOM_BOX_TYPE_AVC2: + case GF_ISOM_BOX_TYPE_SVC1: e = AVC_UpdateESD((GF_MPEGVisualSampleEntryBox*)entry, esd); if (e) return e; break; + case GF_ISOM_BOX_TYPE_LSR1: + e = LSR_UpdateESD((GF_LASeRSampleEntryBox*)entry, esd); + if (e) return e; + break; + default: gf_odf_desc_del((GF_Descriptor *) esd); break; @@ -742,13 +761,13 @@ GF_Err Track_SetStreamDescriptor(GF_TrackBox *trak, u32 StreamDescriptionIndex, if (StreamDescriptionIndex) { entry = (GF_MPEGSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, StreamDescriptionIndex - 1); if (!entry) return GF_ISOM_INVALID_FILE; - if (entry->esd->desc->URLString) return GF_BAD_PARAM; + if (entry->esd && entry->esd->desc->URLString) return GF_BAD_PARAM; } //OK, check the handler and create the entry switch (trak->Media->handler->handlerType) { case GF_ISOM_MEDIA_VISUAL: - if (esd->decoderConfig->objectTypeIndication==0x21) { + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) { entry_v = (GF_MPEGVisualSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_AVC1); if (!entry_v) return GF_OUT_OF_MEM; e = AVC_UpdateESD((GF_MPEGVisualSampleEntryBox*)entry_v, esd); @@ -772,9 +791,15 @@ GF_Err Track_SetStreamDescriptor(GF_TrackBox *trak, u32 StreamDescriptionIndex, entry = (GF_MPEGSampleEntryBox*) entry_a; break; default: - entry = (GF_MPEGSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MP4S); - entry->esd = (GF_ESDBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_ESDS); - entry->esd->desc = esd; + if ((esd->decoderConfig->streamType==0x03) && (esd->decoderConfig->objectTypeIndication==0x09)) { + entry = (GF_MPEGSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_LSR1); + if (!entry) return GF_OUT_OF_MEM; + e = LSR_UpdateESD((GF_LASeRSampleEntryBox*)entry, esd); + } else { + entry = (GF_MPEGSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_MP4S); + entry->esd = (GF_ESDBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_ESDS); + entry->esd->desc = esd; + } break; } entry->dataReferenceIndex = DataReferenceIndex; @@ -787,5 +812,6 @@ GF_Err Track_SetStreamDescriptor(GF_TrackBox *trak, u32 StreamDescriptionIndex, return GF_OK; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/isomedia/tx3g.c b/src/isomedia/tx3g.c index 3683d15..0ee6dfe 100644 --- a/src/isomedia/tx3g.c +++ b/src/isomedia/tx3g.c @@ -25,15 +25,16 @@ #include <gpac/internal/isomedia_dev.h> #include <gpac/constants.h> +#ifndef GPAC_DISABLE_ISOM -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE GF_Err gf_isom_update_text_description(GF_ISOFile *movie, u32 trackNumber, u32 descriptionIndex, GF_TextSampleDescriptor *desc) { GF_TrackBox *trak; GF_Err e; u32 i; - GF_TextSampleEntryBox *txt; + GF_Tx3gSampleEntryBox *txt; if (!descriptionIndex || !desc) return GF_BAD_PARAM; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); @@ -42,11 +43,23 @@ GF_Err gf_isom_update_text_description(GF_ISOFile *movie, u32 trackNumber, u32 d trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || !trak->Media || !desc->font_count) return GF_BAD_PARAM; - if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_TEXT) return GF_BAD_PARAM; + switch (trak->Media->handler->handlerType) { + case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: + break; + default: + return GF_BAD_PARAM; + } - txt = (GF_TextSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, descriptionIndex - 1); + txt = (GF_Tx3gSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, descriptionIndex - 1); if (!txt) return GF_BAD_PARAM; - if (txt->type != GF_ISOM_BOX_TYPE_TX3G) return GF_BAD_PARAM; + switch (txt->type) { + case GF_ISOM_BOX_TYPE_TX3G: + case GF_ISOM_BOX_TYPE_TEXT: + break; + default: + return GF_BAD_PARAM; + } trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); @@ -60,10 +73,10 @@ GF_Err gf_isom_update_text_description(GF_ISOFile *movie, u32 trackNumber, u32 d txt->font_table = (GF_FontTableBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_FTAB); txt->font_table->entry_count = desc->font_count; - txt->font_table->fonts = (GF_FontRecord *) malloc(sizeof(GF_FontRecord) * desc->font_count); + txt->font_table->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord) * desc->font_count); for (i=0; i<desc->font_count; i++) { txt->font_table->fonts[i].fontID = desc->fonts[i].fontID; - if (desc->fonts[i].fontName) txt->font_table->fonts[i].fontName = strdup(desc->fonts[i].fontName); + if (desc->fonts[i].fontName) txt->font_table->fonts[i].fontName = gf_strdup(desc->fonts[i].fontName); } return e; } @@ -73,7 +86,7 @@ GF_Err gf_isom_new_text_description(GF_ISOFile *movie, u32 trackNumber, GF_TextS GF_TrackBox *trak; GF_Err e; u32 dataRefIndex, i; - GF_TextSampleEntryBox *txt; + GF_Tx3gSampleEntryBox *txt; e = CanAccessMovie(movie, GF_ISOM_OPEN_WRITE); if (e) return e; @@ -81,7 +94,13 @@ GF_Err gf_isom_new_text_description(GF_ISOFile *movie, u32 trackNumber, GF_TextS trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || !trak->Media || !desc->font_count) return GF_BAD_PARAM; - if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_TEXT) return GF_BAD_PARAM; + switch (trak->Media->handler->handlerType) { + case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: + break; + default: + return GF_BAD_PARAM; + } //get or create the data ref e = Media_FindDataRef(trak->Media->information->dataInformation->dref, URLname, URNname, &dataRefIndex); @@ -92,7 +111,7 @@ GF_Err gf_isom_new_text_description(GF_ISOFile *movie, u32 trackNumber, GF_TextS } trak->Media->mediaHeader->modificationTime = gf_isom_get_mp4time(); - txt = (GF_TextSampleEntryBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_TX3G); + 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); @@ -106,10 +125,10 @@ GF_Err gf_isom_new_text_description(GF_ISOFile *movie, u32 trackNumber, GF_TextS txt->font_table = (GF_FontTableBox *)gf_isom_box_new(GF_ISOM_BOX_TYPE_FTAB); txt->font_table->entry_count = desc->font_count; - txt->font_table->fonts = (GF_FontRecord *) malloc(sizeof(GF_FontRecord) * desc->font_count); + txt->font_table->fonts = (GF_FontRecord *) gf_malloc(sizeof(GF_FontRecord) * desc->font_count); for (i=0; i<desc->font_count; i++) { txt->font_table->fonts[i].fontID = desc->fonts[i].fontID; - if (desc->fonts[i].fontName) txt->font_table->fonts[i].fontName = strdup(desc->fonts[i].fontName); + if (desc->fonts[i].fontName) txt->font_table->fonts[i].fontName = gf_strdup(desc->fonts[i].fontName); } return e; } @@ -121,7 +140,7 @@ GF_Err gf_isom_text_add_text(GF_TextSample *samp, char *text_data, u32 text_len) { if (!samp) return GF_BAD_PARAM; if (!text_len) return GF_OK; - samp->text = (char*)realloc(samp->text, sizeof(char) * (samp->len + text_len) ); + samp->text = (char*)gf_realloc(samp->text, sizeof(char) * (samp->len + text_len) ); memcpy(samp->text + samp->len, text_data, sizeof(char) * text_len); samp->len += text_len; return GF_OK; @@ -131,7 +150,7 @@ GF_Err gf_isom_text_set_utf16_marker(GF_TextSample *samp) { /*we MUST have an empty sample*/ if (!samp || samp->text) return GF_BAD_PARAM; - samp->text = (char*)malloc(sizeof(char) * 2); + samp->text = (char*)gf_malloc(sizeof(char) * 2); samp->text[0] = (char) 0xFE; samp->text[1] = (char) 0xFF; samp->len = 2; @@ -146,7 +165,7 @@ GF_Err gf_isom_text_add_style(GF_TextSample *samp, GF_StyleRecord *rec) samp->styles = (GF_TextStyleBox *) gf_isom_box_new(GF_ISOM_BOX_TYPE_STYL); if (!samp->styles) return GF_OUT_OF_MEM; } - samp->styles->styles = (GF_StyleRecord*)realloc(samp->styles->styles, sizeof(GF_StyleRecord)*(samp->styles->entry_count+1)); + samp->styles->styles = (GF_StyleRecord*)gf_realloc(samp->styles->styles, sizeof(GF_StyleRecord)*(samp->styles->entry_count+1)); if (!samp->styles->styles) return GF_OUT_OF_MEM; samp->styles->styles[samp->styles->entry_count] = *rec; samp->styles->entry_count++; @@ -206,7 +225,7 @@ GF_Err gf_isom_text_add_karaoke(GF_TextSample *samp, u32 start_time) GF_Err gf_isom_text_set_karaoke_segment(GF_TextSample *samp, u32 end_time, u16 start_char, u16 end_char) { if (!samp || !samp->cur_karaoke) return GF_BAD_PARAM; - samp->cur_karaoke->records = (KaraokeRecord*)realloc(samp->cur_karaoke->records, sizeof(KaraokeRecord)*(samp->cur_karaoke->nb_entries+1)); + samp->cur_karaoke->records = (KaraokeRecord*)gf_realloc(samp->cur_karaoke->records, sizeof(KaraokeRecord)*(samp->cur_karaoke->nb_entries+1)); if (!samp->cur_karaoke->records) return GF_OUT_OF_MEM; samp->cur_karaoke->records[samp->cur_karaoke->nb_entries].end_charoffset = end_char; samp->cur_karaoke->records[samp->cur_karaoke->nb_entries].start_charoffset = start_char; @@ -235,8 +254,8 @@ GF_Err gf_isom_text_add_hyperlink(GF_TextSample *samp, char *URL, char *altStrin if (!a) return GF_OUT_OF_MEM; a->startcharoffset = start_char; a->endcharoffset = end_char; - a->URL = URL ? strdup(URL) : NULL; - a->URL_hint = altString ? strdup(altString) : NULL; + a->URL = URL ? gf_strdup(URL) : NULL; + a->URL_hint = altString ? gf_strdup(altString) : NULL; return gf_list_add(samp->others, a); } @@ -331,7 +350,7 @@ GF_Err gf_isom_text_has_similar_description(GF_ISOFile *movie, u32 trackNumber, GF_TrackBox *trak; GF_Err e; u32 i, j, count; - GF_TextSampleEntryBox *txt; + GF_Tx3gSampleEntryBox *txt; *same_box = *same_styles = 0; *outDescIdx = 0; @@ -343,13 +362,20 @@ GF_Err gf_isom_text_has_similar_description(GF_ISOFile *movie, u32 trackNumber, trak = gf_isom_get_track_from_file(movie, trackNumber); if (!trak || !trak->Media || !desc->font_count) return GF_BAD_PARAM; - if (trak->Media->handler->handlerType != GF_ISOM_MEDIA_TEXT) return GF_BAD_PARAM; + switch (trak->Media->handler->handlerType) { + case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: + break; + default: + return GF_BAD_PARAM; + } count = gf_list_count(trak->Media->information->sampleTable->SampleDescription->boxList); for (i=0; i<count; i++) { Bool same_fonts; - txt = (GF_TextSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, i); - if (!txt|| (txt->type != GF_ISOM_BOX_TYPE_TX3G)) continue; + txt = (GF_Tx3gSampleEntryBox*)gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 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; if (txt->displayFlags != desc->displayFlags) continue; if (txt->vertical_justification != desc->vert_justif) continue; @@ -371,7 +397,7 @@ GF_Err gf_isom_text_has_similar_description(GF_ISOFile *movie, u32 trackNumber, return GF_OK; } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_TextSample *gf_isom_new_text_sample() { @@ -407,7 +433,7 @@ GF_Err gf_isom_text_reset_styles(GF_TextSample *samp) GF_Err gf_isom_text_reset(GF_TextSample *samp) { if (!samp) return GF_BAD_PARAM; - if (samp->text) free(samp->text); + if (samp->text) gf_free(samp->text); samp->text = NULL; samp->len = 0; return gf_isom_text_reset_styles(samp); @@ -418,7 +444,7 @@ void gf_isom_delete_text_sample(GF_TextSample * tx_samp) { gf_isom_text_reset(tx_samp); gf_list_del(tx_samp->others); - free(tx_samp); + gf_free(tx_samp); } GF_EXPORT @@ -433,7 +459,7 @@ GF_TextSample *gf_isom_parse_texte_sample(GF_BitStream *bs) if (s->len) { /*2 extra bytes for UTF-16 term char just in case (we don't know if a BOM marker is present or not since this may be a sample carried over RTP*/ - s->text = (char *) malloc(sizeof(char)*(s->len+2) ); + s->text = (char *) gf_malloc(sizeof(char)*(s->len+2) ); s->text[s->len] = 0; s->text[s->len+1] = 0; gf_bs_read_data(bs, s->text, s->len); } @@ -450,7 +476,7 @@ GF_TextSample *gf_isom_parse_texte_sample(GF_BitStream *bs) gf_isom_box_del((GF_Box*)s->styles); s->styles = st2; } else { - s->styles->styles = (GF_StyleRecord*)realloc(s->styles->styles, sizeof(GF_StyleRecord) * (s->styles->entry_count + st2->entry_count)); + s->styles->styles = (GF_StyleRecord*)gf_realloc(s->styles->styles, sizeof(GF_StyleRecord) * (s->styles->entry_count + st2->entry_count)); memcpy(&s->styles->styles[s->styles->entry_count], st2->styles, sizeof(GF_StyleRecord) * st2->entry_count); s->styles->entry_count += st2->entry_count; gf_isom_box_del(a); @@ -511,7 +537,7 @@ GF_TextSample *gf_isom_parse_texte_sample_from_data(char *data, u32 dataLength) #define SAMPLE_INDEX_OFFSET 129 -static void gf_isom_write_tx3g(GF_TextSampleEntryBox *a, GF_BitStream *bs, u32 sidx, u32 sidx_offset) +static void gf_isom_write_tx3g(GF_Tx3gSampleEntryBox *a, GF_BitStream *bs, u32 sidx, u32 sidx_offset) { u32 size, j; void gpp_write_rgba(GF_BitStream *bs, u32 col); @@ -530,7 +556,7 @@ static void gf_isom_write_tx3g(GF_TextSampleEntryBox *a, GF_BitStream *bs, u32 s } /*write TextSampleEntry box*/ gf_bs_write_u32(bs, size); - gf_bs_write_u32(bs, GF_ISOM_BOX_TYPE_TX3G); + gf_bs_write_u32(bs, a->type); gf_bs_write_data(bs, a->reserved, 6); gf_bs_write_u16(bs, a->dataReferenceIndex); gf_bs_write_u32(bs, a->displayFlags); @@ -606,9 +632,9 @@ GF_Err gf_isom_get_ttxt_esd(GF_MediaBox *mdia, GF_ESD **out_esd) /*write desc*/ gf_bs_write_u8(bs, count); for (i=0; i<count; i++) { - GF_TextSampleEntryBox *a; - a = (GF_TextSampleEntryBox *) gf_list_get(sampleDesc, i); - if (a->type != GF_ISOM_BOX_TYPE_TX3G) continue; + GF_Tx3gSampleEntryBox *a; + a = (GF_Tx3gSampleEntryBox *) gf_list_get(sampleDesc, i); + if ((a->type != GF_ISOM_BOX_TYPE_TX3G) && (a->type != GF_ISOM_BOX_TYPE_TEXT) ) continue; gf_isom_write_tx3g(a, bs, i+1, SAMPLE_INDEX_OFFSET); } if (has_v_info) { @@ -662,7 +688,7 @@ GF_Err gf_isom_rewrite_text_sample(GF_ISOSample *samp, u32 sampleDescriptionInde gf_bs_write_u16(bs, txt_size); if (txt_size) gf_bs_write_data(bs, samp->data + pay_start, samp->dataLength - pay_start); - free(samp->data); + gf_free(samp->data); samp->data = NULL; gf_bs_get_content(bs, &samp->data, &samp->dataLength); gf_bs_del(bs); @@ -674,13 +700,14 @@ GF_Err gf_isom_text_get_encoded_tx3g(GF_ISOFile *file, u32 track, u32 sidx, u32 { GF_BitStream *bs; GF_TrackBox *trak; - GF_TextSampleEntryBox *a; + GF_Tx3gSampleEntryBox *a; trak = gf_isom_get_track_from_file(file, track); if (!trak) return GF_BAD_PARAM; - a = (GF_TextSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, sidx-1); - if (!a || (a->type != GF_ISOM_BOX_TYPE_TX3G)) return GF_BAD_PARAM; + a = (GF_Tx3gSampleEntryBox *) gf_list_get(trak->Media->information->sampleTable->SampleDescription->boxList, 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; bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_isom_write_tx3g(a, bs, sidx, sidx_offset); @@ -691,3 +718,4 @@ GF_Err gf_isom_text_get_encoded_tx3g(GF_ISOFile *file, u32 track, u32 sidx, u32 return GF_OK; } +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/laser/lsr_dec.c b/src/laser/lsr_dec.c index 76cae28..e452a69 100644 --- a/src/laser/lsr_dec.c +++ b/src/laser/lsr_dec.c @@ -11,15 +11,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -29,7 +29,7 @@ #include <gpac/math.h> #include <gpac/events.h> -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER #define GF_LSR_READ_INT(_codec, _val, _nbBits, _str) {\ @@ -64,18 +64,18 @@ GF_LASeRCodec *gf_laser_decoder_new(GF_SceneGraph *graph) GF_EXPORT void gf_laser_decoder_del(GF_LASeRCodec *codec) -{ +{ /*destroy all config*/ while (gf_list_count(codec->streamInfo)) { LASeRStreamInfo *p = (LASeRStreamInfo *)gf_list_last(codec->streamInfo); - free(p); + gf_free(p); gf_list_rem_last(codec->streamInfo); } gf_list_del(codec->streamInfo); - if (codec->col_table) free(codec->col_table); + if (codec->col_table) gf_free(codec->col_table); while (gf_list_count(codec->font_table)) { char *ft = (char *)gf_list_last(codec->font_table); - free(ft); + gf_free(ft); gf_list_rem_last(codec->font_table); } gf_list_del(codec->font_table); @@ -83,7 +83,7 @@ void gf_laser_decoder_del(GF_LASeRCodec *codec) while (gf_list_count(codec->defered_hrefs)) { XMLRI *iri = (XMLRI *)gf_list_last(codec->defered_hrefs); gf_list_rem_last(codec->defered_hrefs); - if (iri->string) free(iri->string); + if (iri->string) gf_free(iri->string); iri->string = NULL; } #endif @@ -91,7 +91,7 @@ void gf_laser_decoder_del(GF_LASeRCodec *codec) gf_list_del(codec->defered_anims); gf_list_del(codec->defered_listeners); gf_list_del(codec->unresolved_commands); - free(codec); + gf_free(codec); } static LASeRStreamInfo *lsr_get_stream(GF_LASeRCodec *codec, u16 ESID) @@ -149,7 +149,7 @@ GF_Err gf_laser_decoder_remove_stream(GF_LASeRCodec *codec, u16 ESID) for (i=0;i<count;i++) { LASeRStreamInfo *ptr = (LASeRStreamInfo *) gf_list_get(codec->streamInfo, i); if (ptr->ESID==ESID) { - free(ptr); + gf_free(ptr); gf_list_rem(codec->streamInfo, i); return GF_OK; } @@ -180,7 +180,7 @@ GF_Err gf_laser_decode_au(GF_LASeRCodec *codec, u16 ESID, char *data, u32 data_l codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1; if (codec->info->cfg.resolution >= 0) codec->res_factor = INT2FIX(1<<codec->info->cfg.resolution); - else + else codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1 << (-codec->info->cfg.resolution)) ); codec->bs = gf_bs_new(data, data_len, GF_BITSTREAM_READ); @@ -206,7 +206,7 @@ GF_Err gf_laser_decode_command_list(GF_LASeRCodec *codec, u16 ESID, char *data, codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1; if (codec->info->cfg.resolution >= 0) codec->res_factor = INT2FIX(1<<codec->info->cfg.resolution); - else + else codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1 << (-codec->info->cfg.resolution)) ); codec->bs = gf_bs_new(data, data_len, GF_BITSTREAM_READ); @@ -271,7 +271,7 @@ static void lsr_read_extension(GF_LASeRCodec *lsr, const char *name) { u32 len = lsr_read_vluimsbf5(lsr, name); #if 0 - *out_data = malloc(sizeof(char)*len); + *out_data = gf_malloc(sizeof(char)*len); gf_bs_read_data(lsr->bs, *out_data, len); *out_len = len; #else @@ -332,7 +332,7 @@ static void lsr_read_private_attribute_container(GF_LASeRCodec *lsr) return; } gf_bs_skip_bytes(lsr->bs, skip_len); -#else +#else switch (val) { /*private data of type "anyXML"*/ case 0: @@ -395,8 +395,8 @@ static void lsr_read_codec_IDREF(GF_LASeRCodec *lsr, XMLRI *href, const char *na if (!n) { char NodeID[1024]; sprintf(NodeID, "N%d", nID-1); - href->string = strdup(NodeID); - if (href->type!=0xFF) + href->string = gf_strdup(NodeID); + if (href->type!=0xFF) gf_list_add(lsr->defered_hrefs, href); href->type = XMLRI_ELEMENTID; return; @@ -484,14 +484,14 @@ static void lsr_read_byte_align_string(GF_LASeRCodec *lsr, char **str, const cha gf_bs_align(lsr->bs); len = lsr_read_vluimsbf8(lsr, "len"); if (str) { - if (*str) free(*str); + if (*str) gf_free(*str); *str = NULL; if (len) { if (len > gf_bs_available(lsr->bs) ) { lsr->last_error = GF_NON_COMPLIANT_BITSTREAM; return; } - *str = (char*)malloc(sizeof(char)*(len+1)); + *str = (char*)gf_malloc(sizeof(char)*(len+1)); gf_bs_read_data(lsr->bs, *str, len); (*str) [len] = 0; } @@ -516,7 +516,7 @@ static void lsr_read_byte_align_string_list(GF_LASeRCodec *lsr, GF_List *l, cons while (gf_list_count(l)) { char *str = (char *)gf_list_last(l); gf_list_rem_last(l); - free(str); + gf_free(str); } text = NULL; lsr_read_byte_align_string(lsr, &text, name); @@ -526,11 +526,11 @@ static void lsr_read_byte_align_string_list(GF_LASeRCodec *lsr, GF_List *l, cons if (!sep) { if (is_iri) { GF_SAFEALLOC(iri, XMLRI); - iri->string = strdup(cur); + iri->string = gf_strdup(cur); iri->type = XMLRI_STRING; gf_list_add(l, iri); } else { - gf_list_add(l, strdup(cur)); + gf_list_add(l, gf_strdup(cur)); } break; } @@ -538,27 +538,27 @@ static void lsr_read_byte_align_string_list(GF_LASeRCodec *lsr, GF_List *l, cons if (!sep2) { if (is_iri) { GF_SAFEALLOC(iri, XMLRI); - iri->string = strdup(cur); + iri->string = gf_strdup(cur); iri->type = XMLRI_STRING; gf_list_add(l, iri); } else { - gf_list_add(l, strdup(cur)); + gf_list_add(l, gf_strdup(cur)); } break; } sep2[0] = 0; if (is_iri) { GF_SAFEALLOC(iri, XMLRI); - iri->string = strdup(sep+1); + iri->string = gf_strdup(sep+1); iri->type = XMLRI_STRING; gf_list_add(l, iri); } else { - gf_list_add(l, strdup(sep+1)); + gf_list_add(l, gf_strdup(sep+1)); } sep2[0] = '\''; cur = sep2 + 1; } - free(text); + gf_free(text); } static void lsr_read_any_uri(GF_LASeRCodec *lsr, XMLRI *iri, const char *name) @@ -569,7 +569,7 @@ static void lsr_read_any_uri(GF_LASeRCodec *lsr, XMLRI *iri, const char *name) char *s = NULL; iri->type=XMLRI_STRING; if (iri->string) { - free(iri->string); + gf_free(iri->string); iri->string = NULL; } lsr_read_byte_align_string(lsr, &s, "uri"); @@ -580,11 +580,11 @@ static void lsr_read_any_uri(GF_LASeRCodec *lsr, XMLRI *iri, const char *name) u32 len_rad, len; len = lsr_read_vluimsbf5(lsr, "len"); len_rad = s ? strlen(s) : 0; - iri->string = (char*)malloc(sizeof(char)*(len_rad+1+len+1)); + iri->string = (char*)gf_malloc(sizeof(char)*(len_rad+1+len+1)); iri->string[0] = 0; if (s) { strcpy(iri->string, s); - free(s); + gf_free(s); } strcat(iri->string, ","); gf_bs_read_data(lsr->bs, iri->string + len_rad + 1, len); @@ -651,7 +651,7 @@ static void lsr_read_paint(GF_LASeRCodec *lsr, SVG_Paint *paint, const char *nam if (sysPaint) { paint->type = SVG_PAINT_COLOR; paint->color.type = gf_svg_get_system_paint_server_type(sysPaint); - free(sysPaint); + gf_free(sysPaint); } } break; @@ -679,7 +679,7 @@ static void lsr_read_id(GF_LASeRCodec *lsr, GF_Node *n) char *name; GF_LSR_READ_INT(lsr, val, 1, "has_id"); if (!val) return; - + name = NULL; id = 1+lsr_read_vluimsbf5(lsr, "ID"); gf_node_set_id(n, id, name); @@ -701,7 +701,7 @@ static void lsr_read_id(GF_LASeRCodec *lsr, GF_Node *n) str_id++; if (id == (1 + (u32) atoi(str_id))) { href->target = (SVG_Element*) n; - free(href->string); + gf_free(href->string); href->string = NULL; gf_list_rem(lsr->defered_hrefs, i); i--; @@ -737,7 +737,7 @@ static void lsr_read_id(GF_LASeRCodec *lsr, GF_Node *n) /*all non-UI get attched to root*/ if (ev && (ev->type>GF_EVENT_MOUSEWHEEL)) { par = (GF_Node*) lsr->current_root; - } + } } } @@ -766,11 +766,11 @@ static Fixed lsr_translate_coords(GF_LASeRCodec *lsr, u32 val, u32 nb_bits) #ifdef GPAC_FIXED_POINT if (val >> (nb_bits-1) ) { s32 neg = (s32) val - (1<<nb_bits); - if (neg < -FIX_ONE / 2) + if (neg < -FIX_ONE / 2) return 2 * gf_divfix(INT2FIX(neg/2), lsr->res_factor); return gf_divfix(INT2FIX(neg), lsr->res_factor); } else { - if (val > FIX_ONE / 2) + if (val > FIX_ONE / 2) return 2 * gf_divfix(INT2FIX(val/2), lsr->res_factor); return gf_divfix(INT2FIX(val), lsr->res_factor); } @@ -850,9 +850,9 @@ static Fixed lsr_read_fixed_clamp(GF_LASeRCodec *lsr, const char *name) static void lsr_read_focus(GF_LASeRCodec *lsr, SVG_Focus *foc, const char *name) { u32 flag; - + if (foc->target.string) { - free(foc->target.string); + gf_free(foc->target.string); foc->target.string = NULL; } if (foc->target.target) foc->target.target = NULL; @@ -883,46 +883,46 @@ static void lsr_restore_base(GF_LASeRCodec *lsr, SVG_Element *elt, SVG_Element * case TAG_SVG_ATT_fill: is_fill = 1; break; - case TAG_SVG_ATT_stroke: + case TAG_SVG_ATT_stroke: is_stroke = 1; break; - case TAG_SVG_ATT_audio_level: - case TAG_SVG_ATT_color: - case TAG_SVG_ATT_color_rendering: - case TAG_SVG_ATT_display: - case TAG_SVG_ATT_display_align: - case TAG_SVG_ATT_fill_opacity: - case TAG_SVG_ATT_fill_rule: - case TAG_SVG_ATT_font_family: - case TAG_SVG_ATT_font_size: - case TAG_SVG_ATT_font_style: - case TAG_SVG_ATT_font_variant: - case TAG_SVG_ATT_font_weight: - case TAG_SVG_ATT_image_rendering: - case TAG_SVG_ATT_line_increment: - case TAG_SVG_ATT_opacity: - case TAG_SVG_ATT_pointer_events: - case TAG_SVG_ATT_shape_rendering: - case TAG_SVG_ATT_solid_color: - case TAG_SVG_ATT_solid_opacity: - case TAG_SVG_ATT_stop_color: - case TAG_SVG_ATT_stop_opacity: - case TAG_SVG_ATT_stroke_dasharray: - case TAG_SVG_ATT_stroke_dashoffset: - case TAG_SVG_ATT_stroke_linecap: - case TAG_SVG_ATT_stroke_linejoin: - case TAG_SVG_ATT_stroke_miterlimit: - case TAG_SVG_ATT_stroke_opacity: - case TAG_SVG_ATT_stroke_width: - case TAG_SVG_ATT_text_align: - case TAG_SVG_ATT_text_anchor: - case TAG_SVG_ATT_text_rendering: - case TAG_SVG_ATT_vector_effect: - case TAG_SVG_ATT_viewport_fill: - case TAG_SVG_ATT_viewport_fill_opacity: - case TAG_SVG_ATT_visibility: + case TAG_SVG_ATT_audio_level: + case TAG_SVG_ATT_color: + case TAG_SVG_ATT_color_rendering: + case TAG_SVG_ATT_display: + case TAG_SVG_ATT_display_align: + case TAG_SVG_ATT_fill_opacity: + case TAG_SVG_ATT_fill_rule: + case TAG_SVG_ATT_font_family: + case TAG_SVG_ATT_font_size: + case TAG_SVG_ATT_font_style: + case TAG_SVG_ATT_font_variant: + case TAG_SVG_ATT_font_weight: + case TAG_SVG_ATT_image_rendering: + case TAG_SVG_ATT_line_increment: + case TAG_SVG_ATT_opacity: + case TAG_SVG_ATT_pointer_events: + case TAG_SVG_ATT_shape_rendering: + case TAG_SVG_ATT_solid_color: + case TAG_SVG_ATT_solid_opacity: + case TAG_SVG_ATT_stop_color: + case TAG_SVG_ATT_stop_opacity: + case TAG_SVG_ATT_stroke_dasharray: + case TAG_SVG_ATT_stroke_dashoffset: + case TAG_SVG_ATT_stroke_linecap: + case TAG_SVG_ATT_stroke_linejoin: + case TAG_SVG_ATT_stroke_miterlimit: + case TAG_SVG_ATT_stroke_opacity: + case TAG_SVG_ATT_stroke_width: + case TAG_SVG_ATT_text_align: + case TAG_SVG_ATT_text_anchor: + case TAG_SVG_ATT_text_rendering: + case TAG_SVG_ATT_vector_effect: + case TAG_SVG_ATT_viewport_fill: + case TAG_SVG_ATT_viewport_fill_opacity: + case TAG_SVG_ATT_visibility: /*and xml:_class*/ - case TAG_SVG_ATT__class: + case TAG_SVG_ATT__class: case TAG_SVG_ATT_externalResourcesRequired: break; @@ -970,12 +970,12 @@ static void lsr_restore_base(GF_LASeRCodec *lsr, SVG_Element *elt, SVG_Element * if (is_fill && reset_fill) { SVG_Paint*p = (SVG_Paint*)f_clone.far_ptr; - if (p->iri.string) free(p->iri.string); + if (p->iri.string) gf_free(p->iri.string); memset(p, 0, sizeof(SVG_Paint)); } if (is_stroke && reset_stroke) { SVG_Paint*p = (SVG_Paint*)f_clone.far_ptr; - if (p->iri.string) free(p->iri.string); + if (p->iri.string) gf_free(p->iri.string); memset(p, 0, sizeof(SVG_Paint)); } att = att->next; @@ -1044,7 +1044,7 @@ static void lsr_read_event_type(GF_LASeRCodec *lsr, XMLEV_Event *evtType) } else { evtType->type = gf_dom_event_type_by_name(evtName); } - free(evtName); + gf_free(evtName); } } else { evtType->parameter = 0; @@ -1159,8 +1159,8 @@ static void lsr_read_smil_times(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SMIL_Ti while (gf_list_count(*times)) { v = (SMIL_Time *)gf_list_last(*times); gf_list_rem_last(*times); - if (v->element_id) free(v->element_id); - free(v); + if (v->element_id) gf_free(v->element_id); + gf_free(v); } GF_LSR_READ_INT(lsr, val, 1, "choice"); @@ -1174,7 +1174,7 @@ static void lsr_read_smil_times(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SMIL_Ti for (i=0; i<count; i++) { v = lsr_read_smil_time(lsr, n); gf_list_add(*times, v); - } + } } static void lsr_read_duration_ex(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SMIL_Duration *smil, const char *name, Bool skipable) @@ -1203,7 +1203,7 @@ static void lsr_read_duration_ex(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SMIL_D now = lsr_read_vluimsbf5(lsr, "value"); smil->clock_value = now; smil->clock_value /= lsr->time_resolution; - if (sign) smil->clock_value *= -1; + if (sign) smil->clock_value *= -1; smil->type = SMIL_DURATION_DEFINED; } } @@ -1275,58 +1275,58 @@ static void lsr_read_rare_full(GF_LASeRCodec *lsr, GF_Node *n) if (lsr->last_error) return; switch (field_tag) { - case TAG_SVG_ATT__class: - lsr_read_byte_align_string(lsr, info.far_ptr, "class"); + case TAG_SVG_ATT__class: + lsr_read_byte_align_string(lsr, info.far_ptr, "class"); break; /*properties*/ - case TAG_SVG_ATT_audio_level: - ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "audio-level"); + case TAG_SVG_ATT_audio_level: + ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "audio-level"); break; - case TAG_SVG_ATT_color: - lsr_read_paint(lsr, (SVG_Paint *)info.far_ptr, "color"); + case TAG_SVG_ATT_color: + lsr_read_paint(lsr, (SVG_Paint *)info.far_ptr, "color"); break; - case TAG_SVG_ATT_color_rendering: - GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 2, "color-rendering"); + case TAG_SVG_ATT_color_rendering: + GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 2, "color-rendering"); break; - case TAG_SVG_ATT_display: - GF_LSR_READ_INT(lsr, *(SVG_Display*)info.far_ptr, 5, "display"); + case TAG_SVG_ATT_display: + GF_LSR_READ_INT(lsr, *(SVG_Display*)info.far_ptr, 5, "display"); break; - case TAG_SVG_ATT_display_align: + case TAG_SVG_ATT_display_align: GF_LSR_READ_INT(lsr, *(SVG_DisplayAlign*)info.far_ptr, 3, "display-align"); break; - case TAG_SVG_ATT_fill_opacity: - ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; - ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "fill-opacity"); + case TAG_SVG_ATT_fill_opacity: + ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; + ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "fill-opacity"); break; - case TAG_SVG_ATT_fill_rule: - GF_LSR_READ_INT(lsr, *(SVG_FillRule*)info.far_ptr, 2, "fill-rule"); + case TAG_SVG_ATT_fill_rule: + GF_LSR_READ_INT(lsr, *(SVG_FillRule*)info.far_ptr, 2, "fill-rule"); break; - case TAG_SVG_ATT_image_rendering: - GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 2, "image-rendering"); + case TAG_SVG_ATT_image_rendering: + GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 2, "image-rendering"); break; - case TAG_SVG_ATT_line_increment: - lsr_read_line_increment_type(lsr, info.far_ptr, "line-increment"); + case TAG_SVG_ATT_line_increment: + lsr_read_line_increment_type(lsr, info.far_ptr, "line-increment"); break; - case TAG_SVG_ATT_pointer_events: - GF_LSR_READ_INT(lsr, *(SVG_PointerEvents*)info.far_ptr, 4, "pointer-events"); + case TAG_SVG_ATT_pointer_events: + GF_LSR_READ_INT(lsr, *(SVG_PointerEvents*)info.far_ptr, 4, "pointer-events"); break; - case TAG_SVG_ATT_shape_rendering: - GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 3, "shape-rendering"); + case TAG_SVG_ATT_shape_rendering: + GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 3, "shape-rendering"); break; - case TAG_SVG_ATT_solid_color: - lsr_read_paint(lsr, info.far_ptr, "solid-color"); + case TAG_SVG_ATT_solid_color: + lsr_read_paint(lsr, info.far_ptr, "solid-color"); break; - case TAG_SVG_ATT_solid_opacity: - ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; - ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "solid-opacity"); + case TAG_SVG_ATT_solid_opacity: + ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; + ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "solid-opacity"); break; - case TAG_SVG_ATT_stop_color: - lsr_read_paint(lsr, info.far_ptr, "stop-color"); + case TAG_SVG_ATT_stop_color: + lsr_read_paint(lsr, info.far_ptr, "stop-color"); break; - case TAG_SVG_ATT_stop_opacity: - ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; - ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "stop-opacity"); + case TAG_SVG_ATT_stop_opacity: + ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; + ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "stop-opacity"); break; - case TAG_SVG_ATT_stroke_dasharray: + case TAG_SVG_ATT_stroke_dasharray: { u32 j, flag; SVG_StrokeDashArray *da = (SVG_StrokeDashArray *)info.far_ptr; @@ -1336,7 +1336,7 @@ static void lsr_read_rare_full(GF_LASeRCodec *lsr, GF_Node *n) } else { da->type=SVG_STROKEDASHARRAY_ARRAY; da->array.count = lsr_read_vluimsbf5(lsr, "len"); - da->array.vals = (Fixed*)malloc(sizeof(Fixed)*da->array.count); + da->array.vals = (Fixed*)gf_malloc(sizeof(Fixed)*da->array.count); for (j=0; j<da->array.count; j++) { da->array.vals[j] = lsr_read_fixed_16_8(lsr, "dash"); } @@ -1344,49 +1344,49 @@ static void lsr_read_rare_full(GF_LASeRCodec *lsr, GF_Node *n) } break; case TAG_SVG_ATT_stroke_dashoffset: - lsr_read_fixed_16_8i(lsr, info.far_ptr, "dashOffset"); + lsr_read_fixed_16_8i(lsr, info.far_ptr, "dashOffset"); break; - case TAG_SVG_ATT_stroke_linecap: - GF_LSR_READ_INT(lsr, *(SVG_StrokeLineCap*)info.far_ptr, 2, "stroke-linecap"); + case TAG_SVG_ATT_stroke_linecap: + GF_LSR_READ_INT(lsr, *(SVG_StrokeLineCap*)info.far_ptr, 2, "stroke-linecap"); break; - case TAG_SVG_ATT_stroke_linejoin: - GF_LSR_READ_INT(lsr, *(SVG_StrokeLineJoin*)info.far_ptr, 2, "stroke-linejoin"); + case TAG_SVG_ATT_stroke_linejoin: + GF_LSR_READ_INT(lsr, *(SVG_StrokeLineJoin*)info.far_ptr, 2, "stroke-linejoin"); break; - case TAG_SVG_ATT_stroke_miterlimit: - lsr_read_fixed_16_8i(lsr, info.far_ptr, "miterLimit"); + case TAG_SVG_ATT_stroke_miterlimit: + lsr_read_fixed_16_8i(lsr, info.far_ptr, "miterLimit"); break; - case TAG_SVG_ATT_stroke_opacity: - ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; - ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "stroke-opacity"); + case TAG_SVG_ATT_stroke_opacity: + ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; + ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "stroke-opacity"); break; - case TAG_SVG_ATT_stroke_width: - lsr_read_fixed_16_8i(lsr, info.far_ptr, "strokeWidth"); + case TAG_SVG_ATT_stroke_width: + lsr_read_fixed_16_8i(lsr, info.far_ptr, "strokeWidth"); break; - case TAG_SVG_ATT_text_anchor: - GF_LSR_READ_INT(lsr, *(SVG_TextAnchor*)info.far_ptr, 2, "text-achor"); + case TAG_SVG_ATT_text_anchor: + GF_LSR_READ_INT(lsr, *(SVG_TextAnchor*)info.far_ptr, 2, "text-achor"); break; - case TAG_SVG_ATT_text_rendering: - GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 3, "text-rendering"); + case TAG_SVG_ATT_text_rendering: + GF_LSR_READ_INT(lsr, *(SVG_RenderingHint*)info.far_ptr, 3, "text-rendering"); break; - case TAG_SVG_ATT_viewport_fill: - lsr_read_paint(lsr, info.far_ptr, "viewport-fill"); + case TAG_SVG_ATT_viewport_fill: + lsr_read_paint(lsr, info.far_ptr, "viewport-fill"); break; - case TAG_SVG_ATT_viewport_fill_opacity: - ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; - ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "viewport-fill-opacity"); + case TAG_SVG_ATT_viewport_fill_opacity: + ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; + ((SVG_Number*)info.far_ptr)->value = lsr_read_fixed_clamp(lsr, "viewport-fill-opacity"); break; - case TAG_SVG_ATT_vector_effect: - GF_LSR_READ_INT(lsr, *(SVG_VectorEffect*)info.far_ptr, 4, "vector-effect"); + case TAG_SVG_ATT_vector_effect: + GF_LSR_READ_INT(lsr, *(SVG_VectorEffect*)info.far_ptr, 4, "vector-effect"); break; - case TAG_SVG_ATT_visibility: - GF_LSR_READ_INT(lsr, *(SVG_Visibility*)info.far_ptr, 2, "visibility"); + case TAG_SVG_ATT_visibility: + GF_LSR_READ_INT(lsr, *(SVG_Visibility*)info.far_ptr, 2, "visibility"); break; - case TAG_SVG_ATT_requiredExtensions: - lsr_read_byte_align_string_list(lsr, *(GF_List**)info.far_ptr, "requiredExtensions", 1); + case TAG_SVG_ATT_requiredExtensions: + lsr_read_byte_align_string_list(lsr, *(GF_List**)info.far_ptr, "requiredExtensions", 1); break; - case TAG_SVG_ATT_requiredFormats: - lsr_read_byte_align_string_list(lsr, *(GF_List**)info.far_ptr, "requiredFormats", 0); + case TAG_SVG_ATT_requiredFormats: + lsr_read_byte_align_string_list(lsr, *(GF_List**)info.far_ptr, "requiredFormats", 0); break; case TAG_SVG_ATT_requiredFeatures: { @@ -1397,55 +1397,55 @@ static void lsr_read_rare_full(GF_LASeRCodec *lsr, GF_Node *n) } } break; - case TAG_SVG_ATT_systemLanguage: - lsr_read_byte_align_string_list(lsr, *(GF_List**)info.far_ptr, "systemLanguage", 0); + case TAG_SVG_ATT_systemLanguage: + lsr_read_byte_align_string_list(lsr, *(GF_List**)info.far_ptr, "systemLanguage", 0); break; - case TAG_XML_ATT_base: - lsr_read_byte_align_string(lsr, &((XMLRI*)info.far_ptr)->string, "xml:base"); + case TAG_XML_ATT_base: + lsr_read_byte_align_string(lsr, &((XMLRI*)info.far_ptr)->string, "xml:base"); ((XMLRI*)info.far_ptr)->type = XMLRI_STRING; break; - case TAG_XML_ATT_lang: - lsr_read_byte_align_string(lsr, info.far_ptr, "xml:lang"); + case TAG_XML_ATT_lang: + lsr_read_byte_align_string(lsr, info.far_ptr, "xml:lang"); break; - case TAG_XML_ATT_space: - GF_LSR_READ_INT(lsr, *(XML_Space*)info.far_ptr, 1, "xml:space"); + case TAG_XML_ATT_space: + GF_LSR_READ_INT(lsr, *(XML_Space*)info.far_ptr, 1, "xml:space"); break; /*focusable*/ - case TAG_SVG_ATT_nav_next: + case TAG_SVG_ATT_nav_next: lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusNext"); break; - case TAG_SVG_ATT_nav_up: + case TAG_SVG_ATT_nav_up: lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusNorth"); break; - case TAG_SVG_ATT_nav_up_left: + case TAG_SVG_ATT_nav_up_left: lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusNorthEast"); break; - case TAG_SVG_ATT_nav_up_right: + case TAG_SVG_ATT_nav_up_right: lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusNorthWest"); break; - case TAG_SVG_ATT_nav_prev: + case TAG_SVG_ATT_nav_prev: lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusPrev"); break; - case TAG_SVG_ATT_nav_down: + case TAG_SVG_ATT_nav_down: lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusSouth"); break; - case TAG_SVG_ATT_nav_down_left: + case TAG_SVG_ATT_nav_down_left: lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusSouthEast"); break; - case TAG_SVG_ATT_nav_down_right: + case TAG_SVG_ATT_nav_down_right: lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusSouthWest"); break; - case TAG_SVG_ATT_nav_left: + case TAG_SVG_ATT_nav_left: lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusEast"); break; case TAG_SVG_ATT_focusable: /*wrong !!*/ - GF_LSR_READ_INT(lsr, *(SVG_Focusable*)info.far_ptr, 2, "focusable"); + GF_LSR_READ_INT(lsr, *(SVG_Focusable*)info.far_ptr, 2, "focusable"); break; - case TAG_SVG_ATT_nav_right: - lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusWest"); + case TAG_SVG_ATT_nav_right: + lsr_read_focus(lsr, (SVG_Focus*)info.far_ptr, "focusWest"); break; - case TAG_SVG_ATT_transform: + case TAG_SVG_ATT_transform: lsr_read_matrix(lsr, info.far_ptr); break; - case TAG_SVG_ATT_text_decoration: + case TAG_SVG_ATT_text_decoration: /*FIXME ASAP*/ assert(0); break; case TAG_SVG_ATT_font_variant: - GF_LSR_READ_INT(lsr, *(SVG_FontVariant*)info.far_ptr, 2, "font-variant"); + GF_LSR_READ_INT(lsr, *(SVG_FontVariant*)info.far_ptr, 2, "font-variant"); break; case TAG_SVG_ATT_font_family: { @@ -1458,42 +1458,42 @@ static void lsr_read_rare_full(GF_LASeRCodec *lsr, GF_Node *n) ((SVG_FontFamily*)info.far_ptr)->type = SVG_FONTFAMILY_VALUE; GF_LSR_READ_INT(lsr, flag, lsr->fontIndexBits, "fontIndex"); ft = (char*)gf_list_get(lsr->font_table, flag); - if (ft) ((SVG_FontFamily*)info.far_ptr)->value = strdup(ft); + if (ft) ((SVG_FontFamily*)info.far_ptr)->value = gf_strdup(ft); } } break; case TAG_SVG_ATT_font_size: - lsr_read_fixed_16_8i(lsr, info.far_ptr, "fontSize"); + lsr_read_fixed_16_8i(lsr, info.far_ptr, "fontSize"); break; - case TAG_SVG_ATT_font_style: - GF_LSR_READ_INT(lsr, *(SVG_FontStyle*)info.far_ptr, 3, "fontStyle"); + case TAG_SVG_ATT_font_style: + GF_LSR_READ_INT(lsr, *(SVG_FontStyle*)info.far_ptr, 3, "fontStyle"); break; - case TAG_SVG_ATT_font_weight: - GF_LSR_READ_INT(lsr, *(SVG_FontWeight*)info.far_ptr, 4, "fontWeight"); + case TAG_SVG_ATT_font_weight: + GF_LSR_READ_INT(lsr, *(SVG_FontWeight*)info.far_ptr, 4, "fontWeight"); break; - case TAG_XLINK_ATT_title: - lsr_read_byte_align_string(lsr, info.far_ptr, "xlink:title"); - break; - case TAG_XLINK_ATT_type: + case TAG_XLINK_ATT_title: + lsr_read_byte_align_string(lsr, info.far_ptr, "xlink:title"); + break; + case TAG_XLINK_ATT_type: /*TODO FIXME*/ - GF_LSR_READ_INT(lsr, field_rare, 3, "xlink:type"); + GF_LSR_READ_INT(lsr, field_rare, 3, "xlink:type"); break; - case TAG_XLINK_ATT_role: - lsr_read_any_uri(lsr, info.far_ptr, "xlink:role"); + case TAG_XLINK_ATT_role: + lsr_read_any_uri(lsr, info.far_ptr, "xlink:role"); break; - case TAG_XLINK_ATT_arcrole: - lsr_read_any_uri(lsr, info.far_ptr, "xlink:arcrole"); + case TAG_XLINK_ATT_arcrole: + lsr_read_any_uri(lsr, info.far_ptr, "xlink:arcrole"); break; - case TAG_XLINK_ATT_actuate: + case TAG_XLINK_ATT_actuate: /*TODO FIXME*/ - GF_LSR_READ_INT(lsr, field_rare, 2, "xlink:actuate"); + GF_LSR_READ_INT(lsr, field_rare, 2, "xlink:actuate"); break; - case TAG_XLINK_ATT_show: + case TAG_XLINK_ATT_show: /*TODO FIXME*/ - GF_LSR_READ_INT(lsr, field_rare, 3, "xlink:show"); + GF_LSR_READ_INT(lsr, field_rare, 3, "xlink:show"); break; - case TAG_SVG_ATT_end: - lsr_read_smil_times(lsr, NULL, 0, info.far_ptr, "end", 0); + case TAG_SVG_ATT_end: + lsr_read_smil_times(lsr, NULL, 0, info.far_ptr, "end", 0); break; case TAG_SVG_ATT_max: lsr_read_duration_ex(lsr, NULL, 0, info.far_ptr, "min", 0); break; case TAG_SVG_ATT_min: lsr_read_duration_ex(lsr, NULL, 0, info.far_ptr, "min", 0); break; @@ -1609,11 +1609,11 @@ static void lsr_translate_anim_value(SMIL_AnimateValue *val, u32 coded_type) da->type = SVG_STROKEDASHARRAY_INHERIT; } else { da->type = SVG_STROKEDASHARRAY_ARRAY; - da->array.vals = (Fixed *) malloc(sizeof(Fixed)*da->array.count); + da->array.vals = (Fixed *) gf_malloc(sizeof(Fixed)*da->array.count); for (i=0; i<da->array.count; i++) { Fixed *v = (Fixed *)gf_list_get(l, i); da->array.vals[i] = *v; - free(v); + gf_free(v); } gf_list_del(l); val->value = da; @@ -1633,7 +1633,7 @@ static void lsr_translate_anim_value(SMIL_AnimateValue *val, u32 coded_type) } while (gf_list_count(l)) { Fixed *v = (Fixed *)gf_list_last(l); - free(v); + gf_free(v); gf_list_rem_last(l); } gf_list_del(l); @@ -1647,7 +1647,7 @@ static void lsr_translate_anim_value(SMIL_AnimateValue *val, u32 coded_type) GF_List *l = gf_list_new(); /*allocated value is already an SVG number*/ gf_list_add(l, val->value); - coords = (SVG_Coordinates*)malloc(sizeof(SVG_Coordinates)); + coords = (SVG_Coordinates*)gf_malloc(sizeof(SVG_Coordinates)); *coords = l; val->value = coords; } else if (coded_type==8) { @@ -1656,14 +1656,14 @@ static void lsr_translate_anim_value(SMIL_AnimateValue *val, u32 coded_type) for (i=0; i<count; i++) { SVG_Coordinate *c; Fixed *v = (Fixed *)gf_list_get(l, i); - c = (SVG_Coordinate*)malloc(sizeof(SVG_Coordinate)); + c = (SVG_Coordinate*)gf_malloc(sizeof(SVG_Coordinate)); c->type = SVG_NUMBER_VALUE; c->value = *v; - free(v); + gf_free(v); gf_list_rem(l, i); gf_list_insert(l, c, i); } - coords = (SVG_Coordinates*)malloc(sizeof(SVG_Coordinates)); + coords = (SVG_Coordinates*)gf_malloc(sizeof(SVG_Coordinates)); *coords = (GF_List *) val->value; val->value = coords; } @@ -1677,7 +1677,7 @@ static void lsr_translate_anim_value(SMIL_AnimateValue *val, u32 coded_type) gf_mx2d_init(*mat); mat->m[2] = pt->x; mat->m[5] = pt->y; - free(pt); + gf_free(pt); val->value = mat; } break; @@ -1701,11 +1701,11 @@ static void lsr_translate_anim_values(SMIL_AnimateValues *val, u32 coded_type) da->type = SVG_STROKEDASHARRAY_INHERIT; } else { da->type = SVG_STROKEDASHARRAY_ARRAY; - da->array.vals = (Fixed *)malloc(sizeof(Fixed)*da->array.count); + da->array.vals = (Fixed *)gf_malloc(sizeof(Fixed)*da->array.count); for (j=0; j<da->array.count; j++) { Fixed *v = (Fixed *)gf_list_get(l, j); da->array.vals[j] = *v; - free(v); + gf_free(v); } gf_list_del(l); gf_list_rem(list, i); @@ -1726,7 +1726,7 @@ static void lsr_translate_anim_values(SMIL_AnimateValues *val, u32 coded_type) } while (gf_list_count(l)) { Fixed *v=(Fixed *)gf_list_last(l); - free(v); + gf_free(v); gf_list_rem_last(l); } gf_list_del(l); @@ -1741,16 +1741,16 @@ static void lsr_translate_anim_values(SMIL_AnimateValues *val, u32 coded_type) u32 j, count2; count2 = gf_list_count(l); for (j=0; j<count2; j++) { - SVG_Coordinate *c = (SVG_Coordinate *)malloc(sizeof(SVG_Coordinate)); + SVG_Coordinate *c = (SVG_Coordinate *)gf_malloc(sizeof(SVG_Coordinate)); Fixed *v = (Fixed *)gf_list_get(l, j); c->type = SVG_NUMBER_VALUE; c->value = *v; gf_list_rem(l, j); gf_list_insert(l, c, j); - free(v); + gf_free(v); } - - coords = (SVG_Coordinates*)malloc(sizeof(SVG_Coordinates)); + + coords = (SVG_Coordinates*)gf_malloc(sizeof(SVG_Coordinates)); *coords = l; gf_list_rem(list, i); gf_list_insert(list, coords, i); @@ -1759,14 +1759,14 @@ static void lsr_translate_anim_values(SMIL_AnimateValues *val, u32 coded_type) case SVG_Motion_datatype: if (coded_type==9) { - GF_Matrix2D *m = (GF_Matrix2D *)malloc(sizeof(GF_Matrix2D )); + GF_Matrix2D *m = (GF_Matrix2D *)gf_malloc(sizeof(GF_Matrix2D )); GF_Point2D *pt = (GF_Point2D *)gf_list_get(list, i); gf_mx2d_init(*m); m->m[2] = pt->x; m->m[5] = pt->y; gf_list_rem(list, i); gf_list_insert(list, m, i); - free(pt); + gf_free(pt); } break; } @@ -1788,9 +1788,9 @@ static Bool lsr_init_smil_times(GF_LASeRCodec *lsr, SVG_Element *anim, GF_List * t->element = gf_sg_find_node_by_name(lsr->sg, t->element_id); } if (!t->element) return 0; - free(t->element_id); + gf_free(t->element_id); t->element_id = NULL; - } + } else if (!t->element) { if (t->event.parameter && (t->event.type==GF_EVENT_KEYDOWN) ) { t->element = lsr->sg->RootNode ? lsr->sg->RootNode : lsr->current_root; @@ -1818,7 +1818,7 @@ static Bool lsr_setup_smil_anim(GF_LASeRCodec *lsr, SVG_Element *anim, SVG_Eleme if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_begin, 0, 0, &info)==GF_OK) { if (!lsr_init_smil_times(lsr, anim, *(GF_List**)info.far_ptr, anim_parent)) not_res++; } - + if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_end, 0, 0, &info)==GF_OK) { if (!lsr_init_smil_times(lsr, anim, *(GF_List**)info.far_ptr, anim_parent)) not_res++; } @@ -1834,7 +1834,7 @@ static Bool lsr_setup_smil_anim(GF_LASeRCodec *lsr, SVG_Element *anim, SVG_Eleme if (!xlink || !xlink->target) { /*target not received*/ if (xlink && (xlink->type == XMLRI_ELEMENTID)) return 0; - + if (!xlink) { /*target is parent, initialize xlink (needed by anim module)*/ if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_XLINK_ATT_href, 1, 0, &info)==GF_OK) { @@ -1843,7 +1843,7 @@ static Bool lsr_setup_smil_anim(GF_LASeRCodec *lsr, SVG_Element *anim, SVG_Eleme return 0; } } - + xlink->type = XMLRI_ELEMENTID; xlink->target = anim_parent; gf_node_register_iri(lsr->sg, xlink); @@ -1877,7 +1877,7 @@ static Bool lsr_setup_smil_anim(GF_LASeRCodec *lsr, SVG_Element *anim, SVG_Eleme /*browse all anim types and retranslate anim values. This must be done in 2 steps since we may not have received the target node when parsing the animation node*/ translate_vals: - + /*and setup anim values*/ if (gf_node_get_attribute_by_tag((GF_Node *)anim, TAG_SVG_ATT_from, 0, 0, &info)==GF_OK) { if (is_animateTransform) { @@ -1997,51 +1997,51 @@ static void *lsr_read_an_anim_value(GF_LASeRCodec *lsr, u32 coded_type, const ch if (escapeFlag) GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum"); switch (coded_type) { - case 0: + case 0: string = NULL; - lsr_read_byte_align_string(lsr, &string, name); + lsr_read_byte_align_string(lsr, &string, name); return string; - case 1: - num = (SVG_Number*)malloc(sizeof(SVG_Number)); + case 1: + num = (SVG_Number*)gf_malloc(sizeof(SVG_Number)); if (escapeFlag) { - num->type = escape_val; + num->type = escape_val; } else { num->type = SVG_NUMBER_VALUE; - num->value = lsr_read_fixed_16_8(lsr, name); + num->value = lsr_read_fixed_16_8(lsr, name); } return num; case 2: { SVG_PathData *pd = (SVG_PathData *)gf_svg_create_attribute_value(SVG_PathData_datatype); - lsr_read_path_type(lsr, NULL, 0, pd, name); + lsr_read_path_type(lsr, NULL, 0, pd, name); return pd; } - case 3: + case 3: { SVG_Points *pts = (SVG_Points *)gf_svg_create_attribute_value(SVG_Points_datatype); - lsr_read_point_sequence(lsr, *pts, name); + lsr_read_point_sequence(lsr, *pts, name); return pts; } case 4: - num = (SVG_Number*)malloc(sizeof(SVG_Number)); + num = (SVG_Number*)gf_malloc(sizeof(SVG_Number)); if (escapeFlag) { - num->type = escape_val; + num->type = escape_val; } else { num->type = SVG_NUMBER_VALUE; - num->value = lsr_read_fixed_clamp(lsr, name); + num->value = lsr_read_fixed_clamp(lsr, name); } return num; - case 5: + case 5: GF_SAFEALLOC(paint, SVG_Paint); if (escapeFlag) { paint->type = SVG_PAINT_INHERIT; } else { - lsr_read_paint(lsr, paint, name); + lsr_read_paint(lsr, paint, name); } return paint; - case 6: - enum_val = (u8*)malloc(sizeof(u8)); - *enum_val = lsr_read_vluimsbf5(lsr, name); + case 6: + enum_val = (u8*)gf_malloc(sizeof(u8)); + *enum_val = lsr_read_vluimsbf5(lsr, name); return enum_val; /*TODO check this is correct*/ case 7: @@ -2050,7 +2050,7 @@ static void *lsr_read_an_anim_value(GF_LASeRCodec *lsr, u32 coded_type, const ch u32 i, count; count = lsr_read_vluimsbf5(lsr, "count"); for (i=0; i<count; i++) { - u8 *v = (u8 *)malloc(sizeof(u8)); + u8 *v = (u8 *)gf_malloc(sizeof(u8)); *v = lsr_read_vluimsbf5(lsr, "val"); gf_list_add(l, v); } @@ -2063,7 +2063,7 @@ static void *lsr_read_an_anim_value(GF_LASeRCodec *lsr, u32 coded_type, const ch u32 i, count; count = lsr_read_vluimsbf5(lsr, "count"); for (i=0; i<count; i++) { - Fixed *v = (Fixed *)malloc(sizeof(Fixed)); + Fixed *v = (Fixed *)gf_malloc(sizeof(Fixed)); *v = lsr_read_fixed_16_8(lsr, "val"); gf_list_add(l, v); } @@ -2072,15 +2072,15 @@ static void *lsr_read_an_anim_value(GF_LASeRCodec *lsr, u32 coded_type, const ch /*point */ case 9: - pt = (SVG_Point*)malloc(sizeof(SVG_Point)); + pt = (SVG_Point*)gf_malloc(sizeof(SVG_Point)); GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "valX"); pt->x = lsr_translate_coords(lsr, flag, lsr->coord_bits); GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, "valY"); pt->y = lsr_translate_coords(lsr, flag, lsr->coord_bits); return pt; - case 10: - id_val = (u32*)malloc(sizeof(u32)); - *id_val = lsr_read_vluimsbf5(lsr, name); + case 10: + id_val = (u32*)gf_malloc(sizeof(u32)); + *id_val = lsr_read_vluimsbf5(lsr, name); return id_val; case 11: { @@ -2093,13 +2093,13 @@ static void *lsr_read_an_anim_value(GF_LASeRCodec *lsr, u32 coded_type, const ch idx = lsr_read_vluimsbf5(lsr, name); ft->type = SVG_FONTFAMILY_VALUE; ft->value = (char*)gf_list_get(lsr->font_table, idx); - if (ft->value) ft->value = strdup(ft->value); + if (ft->value) ft->value = gf_strdup(ft->value); } return ft; } - case 12: + case 12: GF_SAFEALLOC(iri, XMLRI); - lsr_read_any_uri(lsr, iri, name); + lsr_read_any_uri(lsr, iri, name); return iri; default: lsr_read_extension(lsr, name); @@ -2140,20 +2140,20 @@ static void lsr_translate_anim_trans_value(SMIL_AnimateValue *val, u32 transform if (!val->value) return; switch (transform_type) { case SVG_TRANSFORM_ROTATE: - p = (SVG_Point_Angle*)malloc(sizeof(SVG_Point_Angle)); + p = (SVG_Point_Angle*)gf_malloc(sizeof(SVG_Point_Angle)); p->x = p->y = 0; if (coded_type==8) { GF_List *l = (GF_List *)val->value; f = (Fixed*)gf_list_get(l, 0); - if (f) { p->angle = *f; free(f); } + if (f) { p->angle = *f; gf_free(f); } f = (Fixed*)gf_list_get(l, 1); - if (f) { p->x = *f; free(f); } + if (f) { p->x = *f; gf_free(f); } f = (Fixed*)gf_list_get(l, 2); - if (f) { p->y = *f; free(f); } + if (f) { p->y = *f; gf_free(f); } gf_list_del(l); } else { p->angle = ((SVG_Number *)val->value)->value; - free(val->value); + gf_free(val->value); } p->angle = gf_muldiv(p->angle, GF_PI, INT2FIX(180) ); val->value = p; @@ -2164,9 +2164,9 @@ static void lsr_translate_anim_trans_value(SMIL_AnimateValue *val, u32 transform GF_List *l = (GF_List *)val->value; GF_SAFEALLOC(pt , SVG_Point); f = (Fixed*)gf_list_get(l, 0); - if (f) { pt->x = *f; free(f); } + if (f) { pt->x = *f; gf_free(f); } f = (Fixed*)gf_list_get(l, 1); - if (f) { pt->y = *f; free(f); } + if (f) { pt->y = *f; gf_free(f); } else pt->y = pt->x; gf_list_del(l); val->value = pt; @@ -2174,9 +2174,9 @@ static void lsr_translate_anim_trans_value(SMIL_AnimateValue *val, u32 transform break; case SVG_TRANSFORM_SKEWX: case SVG_TRANSFORM_SKEWY: - f = (Fixed*)malloc(sizeof(Fixed)); + f = (Fixed*)gf_malloc(sizeof(Fixed)); *f = ((SVG_Number *)val->value)->value; - free(val->value); + gf_free(val->value); val->value = f; break; } @@ -2217,7 +2217,7 @@ static void lsr_translate_anim_trans_values(SMIL_AnimateValues *val, u32 transfo count = gf_list_count(val->values); if (!count) return; - if (transform_type==SVG_TRANSFORM_TRANSLATE) + if (transform_type==SVG_TRANSFORM_TRANSLATE) return; for (i=0;i<count; i++) { @@ -2237,12 +2237,12 @@ static void lsr_translate_anim_trans_values(SMIL_AnimateValues *val, u32 transfo while (gf_list_count(l)) { f = (Fixed*)gf_list_last(l); gf_list_rem_last(l); - free(f); + gf_free(f); } gf_list_del(l); } else if (coded_type==1) { p->angle = ((SVG_Number *)a_val)->value; - free(a_val); + gf_free(a_val); } p->angle = gf_muldiv(p->angle, GF_PI, INT2FIX(180) ); gf_list_rem(val->values, i); @@ -2250,14 +2250,14 @@ static void lsr_translate_anim_trans_values(SMIL_AnimateValues *val, u32 transfo break; case SVG_TRANSFORM_SKEWX: case SVG_TRANSFORM_SKEWY: - f = (Fixed*)malloc(sizeof(Fixed)); + f = (Fixed*)gf_malloc(sizeof(Fixed)); *f = ((SVG_Number *)a_val)->value; - free(a_val); + gf_free(a_val); gf_list_rem(val->values, i); gf_list_insert(val->values, f, i); break; case SVG_TRANSFORM_SCALE: - pt = (SVG_Point*)malloc(sizeof(SVG_Point)); + pt = (SVG_Point*)gf_malloc(sizeof(SVG_Point)); l = (GF_List*)a_val; f = (Fixed*)gf_list_get(l, 0); if (f) pt->x = *f; @@ -2267,7 +2267,7 @@ static void lsr_translate_anim_trans_values(SMIL_AnimateValues *val, u32 transfo while (gf_list_count(l)) { f = (Fixed*)gf_list_last(l); gf_list_rem_last(l); - free(f); + gf_free(f); } gf_list_del(l); gf_list_rem(val->values, i); @@ -2287,7 +2287,7 @@ static void lsr_read_anim_value_ex(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, cons if (val) { GF_FieldInfo info; lsr->last_error = gf_node_get_attribute_by_tag(n, tag, 1, 0, &info); - + GF_LSR_READ_INT(lsr, coded_type, 4, "type"); ((SMIL_AnimateValue*)info.far_ptr)->value = lsr_read_an_anim_value(lsr, coded_type, name); ((SMIL_AnimateValue*)info.far_ptr)->type = coded_type; @@ -2304,13 +2304,13 @@ static void lsr_read_anim_values_ex(GF_LASeRCodec *lsr, GF_Node *n, u32 *tr_type u32 coded_type; GF_FieldInfo info; SMIL_AnimateValues *values; - + GF_LSR_READ_INT(lsr, flag, 1, "values"); if (!flag) return; lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_values, 1, 0, &info); values = (SMIL_AnimateValues *)info.far_ptr; - + GF_LSR_READ_INT(lsr, coded_type, 4, "type"); values->type = coded_type; count = lsr_read_vluimsbf5(lsr, "count"); @@ -2372,12 +2372,12 @@ static void lsr_read_float_list(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_Coo while (gf_list_count(*coords)) { Fixed *v = (Fixed *)gf_list_last(*coords); gf_list_rem_last(*coords); - free(v); + gf_free(v); } } count = lsr_read_vluimsbf5(lsr, "count"); for (i=0;i<count;i++) { - Fixed *v = (Fixed *)malloc(sizeof(Fixed)); + Fixed *v = (Fixed *)gf_malloc(sizeof(Fixed)); *v = lsr_read_fixed_16_8(lsr, "val"); gf_list_add(*coords, v); } @@ -2386,11 +2386,11 @@ static void lsr_read_float_list(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_Coo static void lsr_read_point_sequence(GF_LASeRCodec *lsr, GF_List *pts, const char *name) { u32 flag, i, count; - + while (gf_list_count(pts)) { SVG_Point *v = (SVG_Point *)gf_list_last(pts); gf_list_rem_last(pts); - free(v); + gf_free(v); } count = lsr_read_vluimsbf5(lsr, "nbPoints"); if (!count) return; @@ -2401,7 +2401,7 @@ static void lsr_read_point_sequence(GF_LASeRCodec *lsr, GF_List *pts, const char u32 nb_bits, v; GF_LSR_READ_INT(lsr, nb_bits, 5, "bits"); for (i=0; i<count; i++) { - SVG_Point *pt = (SVG_Point *)malloc(sizeof(SVG_Point)); + SVG_Point *pt = (SVG_Point *)gf_malloc(sizeof(SVG_Point)); gf_list_add(pts, pt); GF_LSR_READ_INT(lsr, v, nb_bits, "x"); pt->x = lsr_translate_coords(lsr, v, nb_bits); @@ -2411,9 +2411,9 @@ static void lsr_read_point_sequence(GF_LASeRCodec *lsr, GF_List *pts, const char } else { u32 nb_dx, nb_dy, k; Fixed x, y; - SVG_Point *pt = (SVG_Point *)malloc(sizeof(SVG_Point)); + SVG_Point *pt = (SVG_Point *)gf_malloc(sizeof(SVG_Point)); gf_list_add(pts, pt); - + GF_LSR_READ_INT(lsr, nb_dx, 5, "bits"); GF_LSR_READ_INT(lsr, k, nb_dx, "x"); x = pt->x = lsr_translate_coords(lsr, k, nb_dx); @@ -2423,12 +2423,12 @@ static void lsr_read_point_sequence(GF_LASeRCodec *lsr, GF_List *pts, const char GF_LSR_READ_INT(lsr, nb_dx, 5, "bitsx"); GF_LSR_READ_INT(lsr, nb_dy, 5, "bitsy"); for (i=1; i<count; i++) { - SVG_Point *pt = (SVG_Point *)malloc(sizeof(SVG_Point)); + SVG_Point *pt = (SVG_Point *)gf_malloc(sizeof(SVG_Point)); gf_list_add(pts, pt); - GF_LSR_READ_INT(lsr, k, nb_dx, "dx"); + GF_LSR_READ_INT(lsr, k, nb_dx, "dx"); pt->x = x + lsr_translate_coords(lsr, k, nb_dx); x = pt->x; - GF_LSR_READ_INT(lsr, k, nb_dy, "dy"); + GF_LSR_READ_INT(lsr, k, nb_dy, "dy"); pt->y = y + lsr_translate_coords(lsr, k, nb_dy); y = pt->y; } @@ -2437,7 +2437,7 @@ static void lsr_read_point_sequence(GF_LASeRCodec *lsr, GF_List *pts, const char } static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_PathData *path, const char *name) { -#if USE_GF_PATH +#if USE_GF_PATH GF_Point2D *pt, *ct1, *ct2, *end; GF_Point2D orig, ct_orig; u32 i, count, cur_pt, type; @@ -2459,15 +2459,15 @@ static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_Path return; } ct_orig = orig = *pt; - + gf_path_add_move_to_vec(path, pt); cur_pt = 1; count = lsr_read_vluimsbf5(lsr, "nbOfTypes"); for (i=0; i<count; i++) { GF_LSR_READ_INT(lsr, type, 5, name); switch (type) { - case LSR_PATH_COM_h: - case LSR_PATH_COM_l: + case LSR_PATH_COM_h: + case LSR_PATH_COM_l: case LSR_PATH_COM_v: case LSR_PATH_COM_H: case LSR_PATH_COM_V: @@ -2484,8 +2484,8 @@ static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_Path gf_path_add_move_to_vec(path, pt); cur_pt++; break; - case LSR_PATH_COM_q: - case LSR_PATH_COM_Q: + case LSR_PATH_COM_q: + case LSR_PATH_COM_Q: ct1 = gf_list_get(pts, cur_pt); end = gf_list_get(pts, cur_pt+1); if (!ct1 || !end) goto err_exit; @@ -2493,8 +2493,8 @@ static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_Path orig = *end; cur_pt+=2; break; - case LSR_PATH_COM_c: - case LSR_PATH_COM_C: + case LSR_PATH_COM_c: + case LSR_PATH_COM_C: ct1 = gf_list_get(pts, cur_pt); ct2 = gf_list_get(pts, cur_pt+1); end = gf_list_get(pts, cur_pt+2); @@ -2504,8 +2504,8 @@ static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_Path ct_orig = *ct2; orig = *end; break; - case LSR_PATH_COM_s: - case LSR_PATH_COM_S: + case LSR_PATH_COM_s: + case LSR_PATH_COM_S: ct_orig.x = 2*orig.x - ct_orig.x; ct_orig.y = 2*orig.y - ct_orig.y; ct2 = gf_list_get(pts, cur_pt); @@ -2517,7 +2517,7 @@ static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_Path cur_pt+=2; break; case LSR_PATH_COM_t: - case LSR_PATH_COM_T: + case LSR_PATH_COM_T: ct_orig.x = 2*orig.x - ct_orig.x; ct_orig.y = 2*orig.y - ct_orig.y; end = gf_list_get(pts, cur_pt); @@ -2526,7 +2526,7 @@ static void lsr_read_path_type(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, SVG_Path orig = *end; break; case LSR_PATH_COM_z: - case LSR_PATH_COM_Z: + case LSR_PATH_COM_Z: gf_path_close(path); break; } @@ -2540,7 +2540,7 @@ exit: while (gf_list_count(pts)) { end = gf_list_get(pts, 0); gf_list_rem(pts, 0); - free(end); + gf_free(end); } gf_list_del(pts); @@ -2551,46 +2551,46 @@ exit: while (gf_list_count(path->commands)) { u8 *v = (u8 *)gf_list_last(path->commands); gf_list_rem_last(path->commands); - free(v); + gf_free(v); } count = lsr_read_vluimsbf5(lsr, "nbOfTypes"); for (i=0; i<count; i++) { - type = (u8 *)malloc(sizeof(u8)); + type = (u8 *)gf_malloc(sizeof(u8)); GF_LSR_READ_INT(lsr, c, 5, name); switch (c) { - case LSR_PATH_COM_h: - case LSR_PATH_COM_l: + case LSR_PATH_COM_h: + case LSR_PATH_COM_l: case LSR_PATH_COM_v: case LSR_PATH_COM_H: case LSR_PATH_COM_V: case LSR_PATH_COM_L: - *type=SVG_PATHCOMMAND_L; + *type=SVG_PATHCOMMAND_L; break; case LSR_PATH_COM_m: case LSR_PATH_COM_M: - *type=SVG_PATHCOMMAND_M; + *type=SVG_PATHCOMMAND_M; break; - case LSR_PATH_COM_q: - case LSR_PATH_COM_Q: - *type=SVG_PATHCOMMAND_Q; + case LSR_PATH_COM_q: + case LSR_PATH_COM_Q: + *type=SVG_PATHCOMMAND_Q; break; - case LSR_PATH_COM_c: - case LSR_PATH_COM_C: - *type=SVG_PATHCOMMAND_C; + case LSR_PATH_COM_c: + case LSR_PATH_COM_C: + *type=SVG_PATHCOMMAND_C; break; - case LSR_PATH_COM_s: - case LSR_PATH_COM_S: - *type=SVG_PATHCOMMAND_S; + case LSR_PATH_COM_s: + case LSR_PATH_COM_S: + *type=SVG_PATHCOMMAND_S; break; case LSR_PATH_COM_t: - case LSR_PATH_COM_T: - *type=SVG_PATHCOMMAND_T; + case LSR_PATH_COM_T: + *type=SVG_PATHCOMMAND_T; break; case LSR_PATH_COM_z: - case LSR_PATH_COM_Z: - *type=SVG_PATHCOMMAND_Z; + case LSR_PATH_COM_Z: + *type=SVG_PATHCOMMAND_Z; break; } gf_list_add(path->commands, type); @@ -2606,7 +2606,7 @@ static void lsr_read_rotate_type(GF_LASeRCodec *lsr, GF_Node *n) GF_FieldInfo info; lsr->last_error = gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_rotate, 1, 0, &info); GF_LSR_READ_INT(lsr, flag, 1, "choice"); - + if (flag) { GF_LSR_READ_INT(lsr, flag, 1, "rotate"); ((SVG_Number *)info.far_ptr)->type = flag ? SVG_NUMBER_AUTO_REVERSE : SVG_NUMBER_AUTO; @@ -2664,7 +2664,7 @@ static void lsr_read_coordinate(GF_LASeRCodec *lsr, SVG_Number *coord, Bool skip //coord->value = 0; return; } - } + } coord->type = SVG_NUMBER_VALUE; GF_LSR_READ_INT(lsr, flag, lsr->coord_bits, name); coord->value = lsr_translate_coords(lsr, flag, lsr->coord_bits); @@ -2676,7 +2676,7 @@ static void lsr_read_coordinate_ptr(GF_LASeRCodec *lsr, GF_Node *n, u32 tag, Boo if (skipable) { GF_LSR_READ_INT(lsr, flag, 1, name); if (!flag) return; - } + } lsr->last_error = gf_node_get_attribute_by_tag(n, tag, 1, 0, &info); ((SVG_Number*)info.far_ptr)->type = SVG_NUMBER_VALUE; @@ -2741,8 +2741,8 @@ static void lsr_read_script_type(GF_LASeRCodec *lsr, GF_Node *n) if (flag) { GF_LSR_READ_INT(lsr, flag, 1, "script"); switch (flag) { - case 0: *(SVG_String*)info.far_ptr = strdup("application/ecmascript"); break; - case 1: *(SVG_String*)info.far_ptr = strdup("application/jar-archive"); break; + case 0: *(SVG_String*)info.far_ptr = gf_strdup("application/ecmascript"); break; + case 1: *(SVG_String*)info.far_ptr = gf_strdup("application/jar-archive"); break; default: break; } } else { @@ -3702,7 +3702,7 @@ static GF_Node *lsr_read_video(GF_LASeRCodec *lsr, SVG_Element *parent) } else { char *str = NULL; lsr_read_byte_align_string(lsr, & str, "overlayExt"); - if (str) free(str); + if (str) gf_free(str); } } lsr_read_preserve_aspect_ratio(lsr, elt); @@ -3812,7 +3812,7 @@ static GF_Node *lsr_read_listener(GF_LASeRCodec *lsr, SVG_Element *parent) /*all non-UI get attched to root*/ if (ev && (ev->type>GF_EVENT_MOUSEWHEEL)) { par = (SVG_Element*) lsr->current_root; - } + } else if (parent) par = parent; else par = (SVG_Element*) lsr->current_root; } @@ -3832,7 +3832,7 @@ static GF_Node *lsr_read_scene_content_model(GF_LASeRCodec *lsr, SVG_Element *pa { GF_Node *n; u32 ntype; - GF_LSR_READ_INT(lsr, ntype, 6, "ch4"); + GF_LSR_READ_INT(lsr, ntype, 6, "ch4"); n = NULL; switch (ntype) { case LSR_SCENE_CONTENT_MODEL_a: n = lsr_read_a(lsr); break; @@ -3906,15 +3906,15 @@ static GF_Node *lsr_read_update_content_model(GF_LASeRCodec *lsr, SVG_Element *p { u32 flag; GF_Node *n=NULL; - GF_LSR_READ_INT(lsr, flag, 1, "ch4"); + GF_LSR_READ_INT(lsr, flag, 1, "ch4"); if (flag) { - GF_LSR_READ_INT(lsr, flag, 3, "ch61"); + GF_LSR_READ_INT(lsr, flag, 3, "ch61"); switch (flag) { - case LSR_UPDATE_CONTENT_MODEL2_conditional: + case LSR_UPDATE_CONTENT_MODEL2_conditional: n = lsr_read_conditional(lsr); break; case LSR_UPDATE_CONTENT_MODEL2_cursorManager: n = lsr_read_cursorManager(lsr); break; - case LSR_UPDATE_CONTENT_MODEL2_extend: + case LSR_UPDATE_CONTENT_MODEL2_extend: lsr_read_extend_class(lsr, NULL, 0, "extend"); return NULL; case LSR_UPDATE_CONTENT_MODEL2_private: @@ -3981,7 +3981,7 @@ static void lsr_read_group_content(GF_LASeRCodec *lsr, GF_Node *elt, Bool skip_o if (!skip_object_content) lsr_read_object_content(lsr, (SVG_Element*)elt); - + /*node attributes are all parsed*/ gf_node_init(elt); @@ -4038,7 +4038,7 @@ static void *lsr_read_update_value_indexed(GF_LASeRCodec *lsr, GF_Node*node, u32 switch (fieldType) { case SVG_Points_datatype/*ITYPE_point*/: - pt = (SVG_Point*)malloc(sizeof(SVG_Point)); + pt = (SVG_Point*)gf_malloc(sizeof(SVG_Point)); lsr_read_coordinate(lsr, &num, 0, "coordX"); pt->x = num.value; lsr_read_coordinate(lsr, &num, 0, "coordY"); @@ -4047,16 +4047,16 @@ static void *lsr_read_update_value_indexed(GF_LASeRCodec *lsr, GF_Node*node, u32 case SMIL_KeySplines_datatype/*ITYPE_float*/: case SVG_StrokeDashArray_datatype: case SVG_ViewBox_datatype: - f_val = (Fixed*)malloc(sizeof(u8)); + f_val = (Fixed*)gf_malloc(sizeof(u8)); *f_val = lsr_read_fixed_16_8(lsr, "floatValue"); return f_val; case SMIL_KeyTimes_datatype/*ITYPE_keyTime*/: f_val = lsr_read_fraction_12_item(lsr); break; case SMIL_KeyPoints_datatype/*ITYPE_0to1 - keyPoints*/: - pt = (SVG_Point*)malloc(sizeof(SVG_Point)); + pt = (SVG_Point*)gf_malloc(sizeof(SVG_Point)); pt->x = lsr_read_fixed_clamp(lsr, "valueX"); - f_val = (Fixed*)malloc(sizeof(Fixed)); + f_val = (Fixed*)gf_malloc(sizeof(Fixed)); pt->y = lsr_read_fixed_clamp(lsr, "valueY"); return pt; case SMIL_Times_datatype/*ITYPE_smil_time*/: @@ -4077,16 +4077,16 @@ static void lsr_read_update_value(GF_LASeRCodec *lsr, GF_Node *node, u32 att_tag switch (fieldType) { case SVG_Boolean_datatype: - GF_LSR_READ_INT(lsr, *(SVG_Boolean*)val, 1, "val"); + GF_LSR_READ_INT(lsr, *(SVG_Boolean*)val, 1, "val"); break; case SVG_Paint_datatype: paint = (SVG_Paint *)val; - lsr_read_paint(lsr, (SVG_Paint*)val, "val"); + lsr_read_paint(lsr, (SVG_Paint*)val, "val"); break; /* case SVG_AudioLevel_datatype: n = val; - GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); + GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); if (is_default) n->type=SVG_NUMBER_INHERIT; else { n->type = SVG_NUMBER_VALUE; @@ -4106,12 +4106,12 @@ static void lsr_read_update_value(GF_LASeRCodec *lsr, GF_Node *node, u32 att_tag ((SVG_Point *)val)->y = num.value; break; case SVG_Transform_Rotate_datatype: - GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); + GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); if (is_default) ((SVG_Point_Angle*)val)->angle = 0; else { - GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag"); + GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag"); if (has_escape) { - GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum"); + GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum"); ((SVG_Point_Angle*)val)->angle = 0; } else { @@ -4136,7 +4136,7 @@ static void lsr_read_update_value(GF_LASeRCodec *lsr, GF_Node *node, u32 att_tag case TAG_SVG_ATT_stop_opacity: case TAG_SVG_ATT_stroke_opacity: case TAG_SVG_ATT_viewport_fill_opacity: - GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); + GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); if (is_default) n->type=SVG_NUMBER_INHERIT; else { n->type = SVG_NUMBER_VALUE; @@ -4152,12 +4152,12 @@ static void lsr_read_update_value(GF_LASeRCodec *lsr, GF_Node *node, u32 att_tag } break; default: - GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); + GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); if (is_default) n->type=SVG_NUMBER_INHERIT; else { - GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag"); + GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag"); if (has_escape) { - GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum"); + GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum"); n->type = SVG_NUMBER_AUTO;//only lineIncrement } else { n->type = SVG_NUMBER_VALUE; @@ -4175,12 +4175,12 @@ static void lsr_read_update_value(GF_LASeRCodec *lsr, GF_Node *node, u32 att_tag case SVG_Rotate_datatype: n = (SVG_Number*)val; - GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); + GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); if (is_default) n->type=SVG_NUMBER_INHERIT; else { - GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag"); + GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag"); if (has_escape) { - GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum"); + GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum"); n->type = escape_val ? SVG_NUMBER_AUTO_REVERSE : SVG_NUMBER_AUTO; } else { n->type = SVG_NUMBER_VALUE; @@ -4272,11 +4272,11 @@ static void lsr_read_update_value(GF_LASeRCodec *lsr, GF_Node *node, u32 att_tag char *ft; GF_LSR_READ_INT(lsr, idx, 1, "escapeFlag"); idx = lsr_read_vluimsbf5(lsr, "index"); - if (ff->value) free(ff->value); + if (ff->value) gf_free(ff->value); ff->value = NULL; ft = (char*)gf_list_get(lsr->font_table, idx); if (ft) { - ff->value = strdup(ft); + ff->value = gf_strdup(ft); ff->type = SVG_FONTFAMILY_VALUE; } } @@ -4284,23 +4284,23 @@ static void lsr_read_update_value(GF_LASeRCodec *lsr, GF_Node *node, u32 att_tag break; break; case LASeR_Choice_datatype: - GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); + GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); if (is_default) ((LASeR_Choice *)val)->type = LASeR_CHOICE_ALL; else { - GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag"); + GF_LSR_READ_INT(lsr, has_escape, 1, "escapeFlag"); if (has_escape) { - GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum"); + GF_LSR_READ_INT(lsr, escape_val, 2, "escapeEnum"); ((LASeR_Choice *)val)->type = escape_val ? LASeR_CHOICE_NONE : LASeR_CHOICE_ALL; } else { ((LASeR_Choice *)val)->type = LASeR_CHOICE_N; - ((LASeR_Choice *)val)->choice_index = lsr_read_vluimsbf5(lsr, "value"); + ((LASeR_Choice *)val)->choice_index = lsr_read_vluimsbf5(lsr, "value"); } } break; default: if ((fieldType>=SVG_FillRule_datatype) && (fieldType<=SVG_LAST_U8_PROPERTY)) { /*TODO fixme, check inherit values*/ - GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); + GF_LSR_READ_INT(lsr, is_default, 1, "isDefaultValue"); if (is_default) *(u8 *)val = 0; else *(u8 *)val = lsr_read_vluimsbf5(lsr, "val"); } else { @@ -4341,9 +4341,9 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, operandNode = NULL; att_type = op_att_type = -1; - + att_type = lsr_get_attribute_name(lsr); - + idx = -1; if (com_type) { GF_LSR_READ_INT(lsr, type, 1, "has_index"); @@ -4356,7 +4356,7 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, if (type) { op_idref = lsr_read_codec_IDREF_command(lsr, "operandElementId"); operandNode = gf_sg_find_node(lsr->sg, op_idref); - if (!operandNode) + if (!operandNode) return GF_NON_COMPLIANT_BITSTREAM; } } @@ -4377,14 +4377,14 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, } else if (att_type<0) { GF_Node *new_node; - if (!com_type) + if (!com_type) return GF_NON_COMPLIANT_BITSTREAM; GF_LSR_READ_INT(lsr, type, 1, "isInherit"); - if (type) + if (type) return GF_NON_COMPLIANT_BITSTREAM; if (idx==-1) { GF_LSR_READ_INT(lsr, type, 1, "escapeFlag"); - if (type) + if (type) return GF_NON_COMPLIANT_BITSTREAM; } @@ -4500,14 +4500,14 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, text_content = 1; break; /*matrix.translation, scale or rotate*/ - case LSR_UPDATE_TYPE_SCALE: - info.far_ptr = (void *)&matrix_tmp; field_type = SVG_Transform_Scale_datatype; is_lsr_transform = 1; + case LSR_UPDATE_TYPE_SCALE: + info.far_ptr = (void *)&matrix_tmp; field_type = SVG_Transform_Scale_datatype; is_lsr_transform = 1; break; - case LSR_UPDATE_TYPE_ROTATE: - info.far_ptr = (void *)&matrix_tmp_rot; field_type = SVG_Transform_Rotate_datatype; is_lsr_transform = 1; + case LSR_UPDATE_TYPE_ROTATE: + info.far_ptr = (void *)&matrix_tmp_rot; field_type = SVG_Transform_Rotate_datatype; is_lsr_transform = 1; break; case LSR_UPDATE_TYPE_TRANSLATION: - info.far_ptr = (void *)&matrix_tmp; field_type = SVG_Transform_Translate_datatype; is_lsr_transform = 1; + info.far_ptr = (void *)&matrix_tmp; field_type = SVG_Transform_Translate_datatype; is_lsr_transform = 1; break; default: fieldIndex = gf_lsr_anim_type_to_attribute(att_type); @@ -4539,7 +4539,7 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, gf_mx2d_add_rotation(&dest->mat, 0, 0, rotate.angle); gf_mx2d_add_translation(&dest->mat, translate.x, translate.y); } - } + } else if (att_type==LSR_UPDATE_TYPE_SCALE) gf_mx2d_add_scale(&dest->mat, matrix_tmp.x, matrix_tmp.y); else if (att_type==LSR_UPDATE_TYPE_TRANSLATION) gf_mx2d_add_translation(&dest->mat, matrix_tmp.x, matrix_tmp.y); else if (att_type==LSR_UPDATE_TYPE_ROTATE) gf_mx2d_add_rotation(&dest->mat, 0, 0, matrix_tmp_rot.angle); @@ -4551,7 +4551,7 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, GF_DOMText *t = NULL; if (idx>=0) { if (com_type==LSR_UPDATE_INSERT) { - t = gf_dom_new_text_node(n->sgprivate->scenegraph); + t = gf_dom_new_text_node(n->sgprivate->scenegraph); gf_node_register((GF_Node *)t, n); gf_node_list_insert_child(&((GF_ParentNode *)n)->children, (GF_Node*)t, idx); } else { @@ -4561,7 +4561,7 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, } else { /*this is a replace, reset ALL node content*/ gf_sg_parent_reset(n); - t = gf_dom_add_text_node(n, NULL); + t = gf_dom_add_text_node(n, NULL); } lsr_read_byte_align_string(lsr, t ? &t->textContent : NULL, "textContent"); gf_node_changed(n, NULL); @@ -4583,7 +4583,7 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, gf_list_insert(*(SVG_Coordinates*)info.far_ptr, tmp, idx); } else { prev = gf_list_get(*(SVG_Coordinates*)info.far_ptr, idx); - free(prev); + gf_free(prev); gf_list_rem(*(SVG_Coordinates*)info.far_ptr, idx); gf_list_insert(*(SVG_Coordinates*)info.far_ptr, tmp, idx); } @@ -4592,21 +4592,21 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, /*list of floats - to check when implementing it...*/ case SMIL_KeyPoints_datatype/*ITYPE_0to1 - keyPoints*/: pt = (SVG_Point*)tmp; - v1 = (Fixed *) malloc(sizeof(Fixed)); + v1 = (Fixed *) gf_malloc(sizeof(Fixed)); *v1 = pt->x; - v2 = (Fixed *) malloc(sizeof(Fixed)); + v2 = (Fixed *) gf_malloc(sizeof(Fixed)); *v2 = pt->y; - free(pt); + gf_free(pt); if (com_type==LSR_UPDATE_INSERT) { gf_list_insert(*(SVG_Coordinates*)info.far_ptr, v1, idx); gf_list_insert(*(SVG_Coordinates*)info.far_ptr, v2, idx+1); } else { prev = gf_list_get(*(SVG_Coordinates*)info.far_ptr, idx); - free(prev); + gf_free(prev); gf_list_rem(*(SVG_Coordinates*)info.far_ptr, idx); prev = gf_list_get(*(SVG_Coordinates*)info.far_ptr, idx); - free(prev); + gf_free(prev); gf_list_rem(*(SVG_Coordinates*)info.far_ptr, idx); gf_list_insert(*(SVG_Coordinates*)info.far_ptr, v1, idx); gf_list_insert(*(SVG_Coordinates*)info.far_ptr, v2, idx); @@ -4621,7 +4621,7 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, case 2: ((SVG_ViewBox*)info.far_ptr)->width = *v1; break; case 3: ((SVG_ViewBox*)info.far_ptr)->height = *v1; break; } - free(tmp); + gf_free(tmp); gf_node_changed((GF_Node*)n, NULL); break; case SVG_StrokeDashArray_datatype: @@ -4635,11 +4635,11 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, SVG_StrokeDashArray*da = (SVG_StrokeDashArray*)info.far_ptr; if (idx<(s32)da->array.count) da->array.vals[idx] = *v1; } - free(tmp); + gf_free(tmp); gf_node_changed((GF_Node*)n, NULL); break; default: - free(tmp); + gf_free(tmp); break; } } @@ -4656,7 +4656,7 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, gf_svg_delete_attribute_value(info.fieldType, tmp.far_ptr, gf_node_get_graph(n)); } } - } + } /*copy from node*/ else if (operandNode && (op_att_type>=0)) { u32 opFieldIndex = gf_lsr_anim_type_to_attribute(op_att_type); @@ -4692,7 +4692,7 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, /*list replacement*/ GF_LSR_READ_INT(lsr, type, 1, "opt_group"); if (type) { - if (!com_type /*|| (idx!=-1) */) + if (!com_type /*|| (idx!=-1) */) return GF_NON_COMPLIANT_BITSTREAM; if (com_list) { @@ -4708,12 +4708,12 @@ static GF_Err lsr_read_add_replace_insert(GF_LASeRCodec *lsr, GF_List *com_list, gf_node_register(com->node, NULL); field = gf_sg_command_field_new(com); field->pos = idx; - + if (!count && (att_type==LSR_UPDATE_TYPE_TEXT_CONTENT)) { field->fieldIndex = -1; } else if (count==1) { field->new_node = lsr_read_update_content_model(lsr, (SVG_Element *) n); - gf_node_register(field->new_node, n); + gf_node_register(field->new_node, NULL); if (att_type>=0) field->fieldIndex = gf_lsr_anim_type_to_attribute(att_type); } else { field->field_ptr = &field->node_list; @@ -4804,7 +4804,7 @@ static GF_Err lsr_read_delete(GF_LASeRCodec *lsr, GF_List *com_list) } else { s32 fieldIndex = -1; SVG_Element *elt = (SVG_Element *) gf_sg_find_node(lsr->sg, idref); - if (!elt) + if (!elt) return GF_NON_COMPLIANT_BITSTREAM; if (att_type>=0) { @@ -4816,7 +4816,7 @@ static GF_Err lsr_read_delete(GF_LASeRCodec *lsr, GF_List *com_list) else if (idx>=0) { GF_Node *c = (GF_Node *)gf_node_list_get_child(elt->children, idx); if (c) { - if (!gf_node_list_del_child( & elt->children, c)) + if (!gf_node_list_del_child( & elt->children, c)) return GF_IO_ERR; gf_node_unregister(c, (GF_Node*)elt); } @@ -4871,7 +4871,7 @@ static GF_Err lsr_read_send_event(GF_LASeRCodec *lsr, GF_List *com_list) memset(&evt, 0, sizeof(GF_DOM_Event)); evt.type = event.type; - evt.detail = detail ? detail : event.parameter; + evt.detail = detail ? detail : (s32) event.parameter; evt.clientX = FIX2INT(x.value); evt.clientY = FIX2INT(y.value); gf_dom_event_fire(target, &evt); @@ -4886,7 +4886,7 @@ static GF_Err lsr_read_send_event(GF_LASeRCodec *lsr, GF_List *com_list) } else { gf_node_register(com->node, NULL); } - com->send_event_integer = detail ? detail : event.parameter; + com->send_event_integer = detail ? detail : (s32) event.parameter; com->send_event_name = event.type; com->send_event_x = FIX2INT(x.value); com->send_event_y = FIX2INT(y.value); @@ -4933,7 +4933,7 @@ void lsr_exec_command_list(GF_Node *node, void *par, Bool is_destroy) codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1; if (codec->info->cfg.resolution >= 0) codec->res_factor = INT2FIX(1<<codec->info->cfg.resolution); - else + else codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1 << (-codec->info->cfg.resolution)) ); codec->bs = gf_bs_new(up->data, up->data_size, GF_BITSTREAM_READ); @@ -4962,7 +4962,7 @@ static GF_Err lsr_read_command_list(GF_LASeRCodec *lsr, GF_List *com_list, SVG_E if (!lsr->memory_dec) { com_list = NULL; up->data_size = s_len; - up->data = (char*)malloc(sizeof(char)*s_len); + up->data = (char*)gf_malloc(sizeof(char)*s_len); gf_bs_read_data(lsr->bs, up->data, s_len); goto exit; } @@ -4991,7 +4991,7 @@ static GF_Err lsr_read_command_list(GF_LASeRCodec *lsr, GF_List *com_list, SVG_E lsr_read_any_attribute(lsr, NULL, 1); if (com_list) { n = lsr_read_svg(lsr, 0); - if (!n) + if (!n) return (lsr->last_error = GF_NON_COMPLIANT_BITSTREAM); gf_node_register(n, NULL); com = gf_sg_command_new(lsr->sg, (type==5) ? GF_SG_LSR_REFRESH_SCENE : GF_SG_LSR_NEW_SCENE); @@ -5001,7 +5001,7 @@ static GF_Err lsr_read_command_list(GF_LASeRCodec *lsr, GF_List *com_list, SVG_E gf_sg_reset(lsr->sg); gf_sg_set_scene_size_info(lsr->sg, 0, 0, 1); n = lsr_read_svg(lsr, 1); - if (!n) + if (!n) return (lsr->last_error = GF_NON_COMPLIANT_BITSTREAM); } break; @@ -5080,7 +5080,7 @@ static GF_Err lsr_read_command_list(GF_LASeRCodec *lsr, GF_List *com_list, SVG_E lsr->prev_use = NULL; } - if (lsr->last_error) + if (lsr->last_error) return lsr->last_error; } exit: @@ -5117,11 +5117,11 @@ static GF_Err lsr_decode_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list) /*clean all tables*/ if (reset_encoding_context) { lsr->nb_cols = 0; - if (lsr->col_table) free(lsr->col_table); + if (lsr->col_table) gf_free(lsr->col_table); lsr->col_table = NULL; while (gf_list_count(lsr->font_table)) { char *ft = (char *)gf_list_last(lsr->font_table); - free(ft); + gf_free(ft); gf_list_rem_last(lsr->font_table); } lsr->privateData_id_index = lsr->privateTag_index = 0; @@ -5138,7 +5138,7 @@ static GF_Err lsr_decode_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list) count = 0; if (flag) { count = lsr_read_vluimsbf5(lsr, "count"); - lsr->col_table = (LSRCol*)realloc(lsr->col_table, sizeof(LSRCol)*(lsr->nb_cols+count)); + lsr->col_table = (LSRCol*)gf_realloc(lsr->col_table, sizeof(LSRCol)*(lsr->nb_cols+count)); for (i=0; i<count; i++) { LSRCol c; GF_LSR_READ_INT(lsr, c.r, lsr->info->cfg.colorComponentBits, "red"); @@ -5232,4 +5232,4 @@ static GF_Err lsr_decode_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list) return e; } -#endif /*GPAC_DISABLE_SVG*/ +#endif /*GPAC_DISABLE_LASER*/ diff --git a/src/laser/lsr_enc.c b/src/laser/lsr_enc.c index 06fba27..785e803 100644 --- a/src/laser/lsr_enc.c +++ b/src/laser/lsr_enc.c @@ -11,15 +11,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -28,7 +28,7 @@ #include <gpac/bitstream.h> #include <gpac/math.h> -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER #include <gpac/events.h> @@ -57,22 +57,22 @@ GF_LASeRCodec *gf_laser_encoder_new(GF_SceneGraph *graph) } void gf_laser_encoder_del(GF_LASeRCodec *codec) -{ +{ /*destroy all config*/ while (gf_list_count(codec->streamInfo)) { LASeRStreamInfo *p = (LASeRStreamInfo *)gf_list_last(codec->streamInfo); - free(p); + gf_free(p); gf_list_rem_last(codec->streamInfo); } gf_list_del(codec->streamInfo); - if (codec->col_table) free(codec->col_table); + if (codec->col_table) gf_free(codec->col_table); while (gf_list_count(codec->font_table)) { char *ft = (char *)gf_list_last(codec->font_table); - free(ft); + gf_free(ft); gf_list_rem_last(codec->font_table); } gf_list_del(codec->font_table); - free(codec); + gf_free(codec); } @@ -126,7 +126,7 @@ GF_Err gf_laser_encoder_get_config(GF_LASeRCodec *codec, u16 ESID, char **out_da gf_bs_write_int(bs, 0, 1); } gf_bs_write_int(bs, codec->info->cfg.colorComponentBits - 1, 4); - if (codec->info->cfg.resolution<0) + if (codec->info->cfg.resolution<0) gf_bs_write_int(bs, 16 + codec->info->cfg.resolution, 4); else gf_bs_write_int(bs, codec->info->cfg.resolution, 4); @@ -159,7 +159,7 @@ GF_Err gf_laser_encode_au(GF_LASeRCodec *codec, u16 ESID, GF_List *command_list, codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1; if (codec->info->cfg.resolution>=0) codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1<<codec->info->cfg.resolution) ); - else + else codec->res_factor = INT2FIX(1 << (-codec->info->cfg.resolution)); codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); @@ -183,7 +183,7 @@ GF_Err gf_laser_encoder_get_rap(GF_LASeRCodec *codec, char **out_data, u32 *out_ codec->color_scale = (1<<codec->info->cfg.colorComponentBits) - 1; if (codec->info->cfg.resolution>=0) codec->res_factor = gf_divfix(FIX_ONE, INT2FIX(1<<codec->info->cfg.resolution) ); - else + else codec->res_factor = INT2FIX(1 << (-codec->info->cfg.resolution)); codec->bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); @@ -300,7 +300,7 @@ static void lsr_write_codec_IDREF_Node(GF_LASeRCodec *lsr, GF_Node *href, const static u32 lsr_get_IDREF_nb_bits(GF_LASeRCodec *lsr, GF_Node *href) { u32 nb_bits, nb_words, nID; - + nID = gf_node_get_id(href); assert(nID); @@ -445,7 +445,7 @@ static void lsr_write_any_uri(GF_LASeRCodec *lsr, XMLRI *iri, const char *name) if (iri->type==XMLRI_ELEMENTID) lsr_write_codec_IDREF(lsr, iri, "idref"); GF_LSR_WRITE_INT(lsr, (iri->type==XMLRI_STREAMID) ? 1 : 0, 1, "hasID"); - if (iri->type==XMLRI_STREAMID) + if (iri->type==XMLRI_STREAMID) lsr_write_codec_IDREF(lsr, iri, "ref"); } @@ -455,27 +455,27 @@ static void lsr_write_paint(GF_LASeRCodec *lsr, SVG_Paint *paint, const char *na s32 idx; GF_LSR_WRITE_INT(lsr, 1, 1, "hasIndex"); idx = lsr_get_col_index(lsr, &paint->color); - if (idx<0) { - idx = 0; - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] color not in colorTable\n")); + if (idx<0) { + idx = 0; + GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[LASeR] color not in colorTable\n")); } GF_LSR_WRITE_INT(lsr, (u32) idx, lsr->colorIndexBits, name); } else { GF_LSR_WRITE_INT(lsr, 0, 1, "hasIndex"); switch (paint->type) { - case SVG_PAINT_INHERIT: + case SVG_PAINT_INHERIT: GF_LSR_WRITE_INT(lsr, 0, 2, "enum"); - GF_LSR_WRITE_INT(lsr, 0, 2, "choice"); + GF_LSR_WRITE_INT(lsr, 0, 2, "choice"); break; - case SVG_PAINT_NONE: + case SVG_PAINT_NONE: GF_LSR_WRITE_INT(lsr, 0, 2, "enum"); - GF_LSR_WRITE_INT(lsr, 2, 2, "choice"); + GF_LSR_WRITE_INT(lsr, 2, 2, "choice"); break; - case SVG_PAINT_COLOR: + case SVG_PAINT_COLOR: if (paint->color.type == SVG_COLOR_CURRENTCOLOR) { GF_LSR_WRITE_INT(lsr, 0, 2, "enum"); - GF_LSR_WRITE_INT(lsr, 1, 2, "choice"); + GF_LSR_WRITE_INT(lsr, 1, 2, "choice"); } else { GF_LSR_WRITE_INT(lsr, 2, 2, "enum"); lsr_write_byte_align_string(lsr, (char*)gf_svg_get_system_paint_server_name(paint->color.type), "systemsPaint"); @@ -491,7 +491,7 @@ static void lsr_write_paint(GF_LASeRCodec *lsr, SVG_Paint *paint, const char *na lsr_write_extension(lsr, "ERROR", 5, "colorExType0"); break; } - } + } } static void lsr_write_private_element_container(GF_LASeRCodec *lsr) @@ -522,7 +522,7 @@ static void lsr_write_any_attribute(GF_LASeRCodec *lsr, SVG_Element *node, Bool GF_LSR_WRITE_INT(lsr, 0, lsr->info->cfg.extensionIDBits, "reserved"); lsr_write_vluimsbf5(lsr, 0, "len");//len in BITS GF_LSR_WRITE_INT(lsr, 0, 0, "reserved_val"); - } while () + } while () */ } } @@ -551,12 +551,12 @@ static void lsr_write_id(GF_LASeRCodec *lsr, GF_Node *n) if (id) { GF_LSR_WRITE_INT(lsr, 1, 1, "has_id"); lsr_write_vluimsbf5(lsr, id-1, "ID"); -#if TODO_LASER_EXTENSIONS +#if TODO_LASER_EXTENSIONS if (0) { GF_LSR_WRITE_INT(lsr, 1, 1, "reserved"); lsr_write_vluimsbf5(lsr, reserved_len, "len"); GF_LSR_WRITE_INT(lsr, 0, reserved_len, "reserved"); - } else + } else #endif GF_LSR_WRITE_INT(lsr, 0, 1, "reserved"); } else { @@ -690,11 +690,11 @@ u32 dom_to_lsr_key(u32 dom_k) return 13; case GF_KEY_ESCAPE: return 15; - case GF_KEY_NUMBER: + case GF_KEY_NUMBER: return 17; - case GF_KEY_CELL_SOFT1: + case GF_KEY_CELL_SOFT1: return 18; - case GF_KEY_CELL_SOFT2: + case GF_KEY_CELL_SOFT2: return 19; default: return 100; @@ -735,73 +735,73 @@ static void lsr_write_event_type(GF_LASeRCodec *lsr, u32 evtType, u32 evtParam) } else { GF_LSR_WRITE_INT(lsr, 1, 1, "choice"); switch (evtType) { - case GF_EVENT_ABORT: + case GF_EVENT_ABORT: GF_LSR_WRITE_INT(lsr, LSR_EVT_abort, 6, "event"); break; - case GF_EVENT_ACTIVATE: + case GF_EVENT_ACTIVATE: GF_LSR_WRITE_INT(lsr, LSR_EVT_activate, 6, "event"); break; - case GF_EVENT_ACTIVATED: + case GF_EVENT_ACTIVATED: GF_LSR_WRITE_INT(lsr, LSR_EVT_activatedEvent, 6, "event"); break; - case GF_EVENT_BEGIN:/*SPEC IS BROKEN, CANNOT ENCODE elt.begin !! */ - case GF_EVENT_BEGIN_EVENT: + case GF_EVENT_BEGIN:/*SPEC IS BROKEN, CANNOT ENCODE elt.begin !! */ + case GF_EVENT_BEGIN_EVENT: GF_LSR_WRITE_INT(lsr, LSR_EVT_beginEvent, 6, "event"); break; - case GF_EVENT_CLICK: + case GF_EVENT_CLICK: GF_LSR_WRITE_INT(lsr, LSR_EVT_click, 6, "event"); break; - case GF_EVENT_DEACTIVATED: + case GF_EVENT_DEACTIVATED: GF_LSR_WRITE_INT(lsr, LSR_EVT_deactivatedEvent, 6, "event"); break; - case GF_EVENT_END:/*SPEC IS BROKEN, CANNOT ENCODE elt.end !! */ - case GF_EVENT_END_EVENT: + case GF_EVENT_END:/*SPEC IS BROKEN, CANNOT ENCODE elt.end !! */ + case GF_EVENT_END_EVENT: GF_LSR_WRITE_INT(lsr, LSR_EVT_endEvent, 6, "event"); break; - case GF_EVENT_ERROR: + case GF_EVENT_ERROR: GF_LSR_WRITE_INT(lsr, LSR_EVT_error, 6, "event"); break; - case GF_EVENT_EXECUTION_TIME: + case GF_EVENT_EXECUTION_TIME: GF_LSR_WRITE_INT(lsr, LSR_EVT_executionTime, 6, "event"); break; - case GF_EVENT_FOCUSIN: + case GF_EVENT_FOCUSIN: GF_LSR_WRITE_INT(lsr, LSR_EVT_focusin, 6, "event"); break; - case GF_EVENT_FOCUSOUT: + case GF_EVENT_FOCUSOUT: GF_LSR_WRITE_INT(lsr, LSR_EVT_focusout, 6, "event"); break; - case GF_EVENT_KEYDOWN: + case GF_EVENT_KEYDOWN: /*encode as accessKey() if param*/ - GF_LSR_WRITE_INT(lsr, evtParam ? LSR_EVT_accessKey : LSR_EVT_keydown, 6, "event"); + GF_LSR_WRITE_INT(lsr, evtParam ? LSR_EVT_accessKey : LSR_EVT_keydown, 6, "event"); break; - case GF_EVENT_KEYUP: + case GF_EVENT_KEYUP: GF_LSR_WRITE_INT(lsr, LSR_EVT_keyup, 6, "event"); break; - case GF_EVENT_LOAD: + case GF_EVENT_LOAD: GF_LSR_WRITE_INT(lsr, LSR_EVT_load, 6, "event"); break; - case GF_EVENT_LONGKEYPRESS: + case GF_EVENT_LONGKEYPRESS: GF_LSR_WRITE_INT(lsr, LSR_EVT_longAccessKey, 6, "event"); break; - case GF_EVENT_MOUSEDOWN: + case GF_EVENT_MOUSEDOWN: GF_LSR_WRITE_INT(lsr, LSR_EVT_mousedown, 6, "event"); break; - case GF_EVENT_MOUSEMOVE: - GF_LSR_WRITE_INT(lsr, LSR_EVT_mousemove, 6, "event"); break; - case GF_EVENT_MOUSEOUT: + case GF_EVENT_MOUSEMOVE: + GF_LSR_WRITE_INT(lsr, LSR_EVT_mousemove, 6, "event"); break; + case GF_EVENT_MOUSEOUT: GF_LSR_WRITE_INT(lsr, LSR_EVT_mouseout, 6, "event"); break; - case GF_EVENT_MOUSEOVER: + case GF_EVENT_MOUSEOVER: GF_LSR_WRITE_INT(lsr, LSR_EVT_mouseover, 6, "event"); break; - case GF_EVENT_MOUSEUP: + case GF_EVENT_MOUSEUP: GF_LSR_WRITE_INT(lsr, LSR_EVT_mouseup, 6, "event"); break; - case GF_EVENT_PAUSE: + case GF_EVENT_PAUSE: GF_LSR_WRITE_INT(lsr, LSR_EVT_pause, 6, "event"); break; - case GF_EVENT_PAUSED_EVENT: + case GF_EVENT_PAUSED_EVENT: GF_LSR_WRITE_INT(lsr, LSR_EVT_pausedEvent, 6, "event"); break; - case GF_EVENT_PLAY: + case GF_EVENT_PLAY: GF_LSR_WRITE_INT(lsr, LSR_EVT_play, 6, "event"); break; - case GF_EVENT_REPEAT_EVENT: + case GF_EVENT_REPEAT_EVENT: GF_LSR_WRITE_INT(lsr, LSR_EVT_repeatEvent, 6, "event"); break; - case GF_EVENT_REPEAT_KEY: + case GF_EVENT_REPEAT_KEY: GF_LSR_WRITE_INT(lsr, LSR_EVT_repeatKey, 6, "event"); break; - case GF_EVENT_RESIZE: + case GF_EVENT_RESIZE: GF_LSR_WRITE_INT(lsr, LSR_EVT_resize, 6, "event"); break; - case GF_EVENT_RESUME_EVENT: + case GF_EVENT_RESUME_EVENT: GF_LSR_WRITE_INT(lsr, LSR_EVT_resumedEvent, 6, "event"); break; - case GF_EVENT_SCROLL: + case GF_EVENT_SCROLL: GF_LSR_WRITE_INT(lsr, LSR_EVT_scroll, 6, "event"); break; - case GF_EVENT_SHORT_ACCESSKEY: + case GF_EVENT_SHORT_ACCESSKEY: GF_LSR_WRITE_INT(lsr, LSR_EVT_shortAccessKey, 6, "event"); break; - case GF_EVENT_TEXTINPUT: + case GF_EVENT_TEXTINPUT: GF_LSR_WRITE_INT(lsr, LSR_EVT_textinput, 6, "event"); break; - case GF_EVENT_UNLOAD: + case GF_EVENT_UNLOAD: GF_LSR_WRITE_INT(lsr, LSR_EVT_unload, 6, "event"); break; - case GF_EVENT_ZOOM: + case GF_EVENT_ZOOM: GF_LSR_WRITE_INT(lsr, LSR_EVT_zoom, 6, "event"); break; default: GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] Unsupported LASER event %d\n", evtType) ); @@ -965,7 +965,7 @@ static Bool lsr_elt_has_same_base(GF_LASeRCodec *lsr, SVGAllAttributes *atts, SV info.far_ptr = atts->rx; base_info.far_ptr = base_atts.rx; if (!gf_svg_attributes_equal(&info, &base_info)) return 0; - + info.fieldType = base_info.fieldType = SVG_Length_datatype; info.far_ptr = atts->ry; base_info.far_ptr = base_atts.ry; @@ -977,7 +977,7 @@ static Bool lsr_elt_has_same_base(GF_LASeRCodec *lsr, SVGAllAttributes *atts, SV info.far_ptr = atts->x; base_info.far_ptr = base_atts.x; if (!gf_svg_attributes_equal(&info, &base_info)) return 0; - + info.fieldType = base_info.fieldType = SVG_Coordinate_datatype; info.far_ptr = atts->y; base_info.far_ptr = base_atts.y; @@ -1045,7 +1045,7 @@ static void lsr_write_rare(GF_LASeRCodec *lsr, GF_Node *n) u32 len = 2+3; switch (att->tag) { case TAG_SVG_ATT_syncMaster: len +=1; break; - case TAG_SVG_ATT_requiredFonts: + case TAG_SVG_ATT_requiredFonts: len += 8*strlen(*(SVG_String*)att->data); /*get vluimsbf5 field size with one extra word (4 bits, enough to code string alignment)*/ size = lsr_get_vluimsbf5_size(len, 1); @@ -1067,25 +1067,25 @@ static void lsr_write_rare(GF_LASeRCodec *lsr, GF_Node *n) lsr_write_vluimsbf5(lsr, len, "len"); } GF_LSR_WRITE_INT(lsr, 1, 2, "nbOfAttributes"); - + switch (att->tag) { - case TAG_SVG_ATT_syncMaster: + case TAG_SVG_ATT_syncMaster: GF_LSR_WRITE_INT(lsr, 0, 3, "attributeRARE"); GF_LSR_WRITE_INT(lsr, *(SVG_Boolean *)att->data ? 1 : 0, 1, "syncMaster"); break; - case TAG_SVG_ATT_focusHighlight: + case TAG_SVG_ATT_focusHighlight: GF_LSR_WRITE_INT(lsr, 1, 3, "attributeRARE"); GF_LSR_WRITE_INT(lsr, *(SVG_FocusHighlight*)att->data, 2, "focusHighlight"); break; - case TAG_SVG_ATT_initialVisibility: + case TAG_SVG_ATT_initialVisibility: GF_LSR_WRITE_INT(lsr, 2, 3, "attributeRARE"); GF_LSR_WRITE_INT(lsr, *(SVG_InitialVisibility*)att->data, 2, "initialVisibility"); break; - case TAG_SVG_ATT_fullscreen: + case TAG_SVG_ATT_fullscreen: GF_LSR_WRITE_INT(lsr, 3, 3, "attributeRARE"); GF_LSR_WRITE_INT(lsr, *(SVG_Boolean *)att->data ? 1 : 0, 2, "fullscreen"); break; - case TAG_SVG_ATT_requiredFonts: + case TAG_SVG_ATT_requiredFonts: GF_LSR_WRITE_INT(lsr, 4, 3, "attributeRARE"); lsr_write_byte_align_string(lsr, *(SVG_String*)att->data, "requiredFonts"); break; @@ -1094,7 +1094,7 @@ static void lsr_write_rare(GF_LASeRCodec *lsr, GF_Node *n) att = att->next; continue; } - + GF_LSR_WRITE_INT(lsr, (u32)field_rare, 6, "attributeRARE"); switch (att->tag) { case TAG_SVG_ATT__class: lsr_write_byte_align_string(lsr, *(SVG_String *)att->data, "class"); break; @@ -1114,7 +1114,7 @@ static void lsr_write_rare(GF_LASeRCodec *lsr, GF_Node *n) case TAG_SVG_ATT_solid_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "solid-opacity"); break; case TAG_SVG_ATT_stop_color: lsr_write_paint(lsr, (SVG_Paint*)att->data, "stop-color"); break; case TAG_SVG_ATT_stop_opacity: lsr_write_fixed_clamp(lsr, ((SVG_Number *)att->data)->value, "stop-opacity"); break; - case TAG_SVG_ATT_stroke_dasharray: + case TAG_SVG_ATT_stroke_dasharray: { u32 j; SVG_StrokeDashArray *da = (SVG_StrokeDashArray*)att->data; @@ -1129,7 +1129,7 @@ static void lsr_write_rare(GF_LASeRCodec *lsr, GF_Node *n) } } break; - case TAG_SVG_ATT_stroke_dashoffset: + case TAG_SVG_ATT_stroke_dashoffset: lsr_write_fixed_16_8i(lsr, (SVG_Number*)att->data, "dashOffset"); break; case TAG_SVG_ATT_stroke_linecap: GF_LSR_WRITE_INT(lsr, *(SVG_StrokeLineCap*)att->data, 2, "stroke-linecap"); break; @@ -1145,11 +1145,11 @@ static void lsr_write_rare(GF_LASeRCodec *lsr, GF_Node *n) case TAG_SVG_ATT_visibility: GF_LSR_WRITE_INT(lsr, *(SVG_PointerEvents*)att->data, 2, "visibility"); break; case TAG_SVG_ATT_requiredExtensions: lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "requiredExtensions", 1); break; case TAG_SVG_ATT_requiredFormats: lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "requiredFormats", 0); break; - case TAG_SVG_ATT_requiredFeatures: + case TAG_SVG_ATT_requiredFeatures: { GF_List *l = *(GF_List **)att->data; u32 j, tot_count, count = gf_list_count(l); - u8 *vals = (u8*)malloc(sizeof(u8)*count); + u8 *vals = (u8*)gf_malloc(sizeof(u8)*count); tot_count = 0; for (i=0; i<count; i++) { char *ext; @@ -1196,12 +1196,12 @@ static void lsr_write_rare(GF_LASeRCodec *lsr, GF_Node *n) for (j=0; j<tot_count; j++) { GF_LSR_WRITE_INT(lsr, vals[j], 6, "feature"); } - free(vals); + gf_free(vals); } break; - case TAG_SVG_ATT_systemLanguage: - lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "systemLanguage", 0); + case TAG_SVG_ATT_systemLanguage: + lsr_write_byte_align_string_list(lsr, *(GF_List **)att->data, "systemLanguage", 0); break; case TAG_XML_ATT_base: lsr_write_byte_align_string(lsr, ((XMLRI*)att->data)->string, "xml:base"); break; case TAG_XML_ATT_lang: lsr_write_byte_align_string(lsr, *(SVG_String *)att->data, "xml:lang"); break; @@ -1277,7 +1277,7 @@ static void lsr_write_href(GF_LASeRCodec *lsr, XMLRI *iri) if (iri->type==XMLRI_ELEMENTID) { if (!iri->target && iri->string) iri->target = (SVG_Element *)gf_sg_find_node_by_name(lsr->sg, iri->string+1); if (!iri->target || !gf_node_get_id((GF_Node *)iri->target)) has_href = 0; - } + } else if (iri->type==XMLRI_STREAMID) { if (!iri->lsr_stream_id) has_href = 0; } @@ -1382,10 +1382,10 @@ static u32 svg_type_to_lsr_anim(u32 svg_type, u32 transform_type, GF_List *vals, case SVG_Length_datatype: case SVG_Coordinate_datatype: return 1; - case SVG_PathData_datatype: + case SVG_PathData_datatype: return 2; /*list of points*/ - case SMIL_KeyPoints_datatype: + case SMIL_KeyPoints_datatype: case SVG_Points_datatype: return 3; /*all 0 - 1 types*/ @@ -1395,7 +1395,7 @@ static u32 svg_type_to_lsr_anim(u32 svg_type, u32 transform_type, GF_List *vals, */ case SVG_Paint_datatype: return 5; - /*all enums (u8) types*/ + /*all enums (u8) types*/ case SVG_FillRule_datatype: case SVG_StrokeLineJoin_datatype: case SVG_StrokeLineCap_datatype: @@ -1433,7 +1433,7 @@ static u32 svg_type_to_lsr_anim(u32 svg_type, u32 transform_type, GF_List *vals, /*ARG LOOKS LIKE THE SPEC IS BROKEN HERE*/ case SVG_Transform_Translate_datatype: return 9; case SVG_Transform_Scale_datatype: return 8; - case SVG_Transform_Rotate_datatype: + case SVG_Transform_Rotate_datatype: if (vals) { u32 i=0; SVG_Point_Angle *pt; @@ -1448,7 +1448,7 @@ static u32 svg_type_to_lsr_anim(u32 svg_type, u32 transform_type, GF_List *vals, case SVG_Transform_SkewX_datatype: return 1; case SVG_Transform_SkewY_datatype: return 1; //case SVG_Transform_datatype: return; - /*FALL THROUH*/ + /*FALL THROUH*/ default: return 255; } @@ -1510,15 +1510,15 @@ static void lsr_write_an_anim_value(GF_LASeRCodec *lsr, void *val, u32 lsr_type, switch(lsr_type) { case 0: lsr_write_byte_align_string(lsr, *(DOM_String *)val, name); break; - case 1: + case 1: if (svg_type==SVG_Transform_Rotate_datatype) { Fixed angle = ((SVG_Point_Angle *) val)->angle; angle = gf_muldiv(angle, INT2FIX(180), GF_PI); - lsr_write_fixed_16_8(lsr, angle, name); + lsr_write_fixed_16_8(lsr, angle, name); } else if ((svg_type==SVG_Transform_SkewX_datatype) || (svg_type==SVG_Transform_SkewY_datatype)) { - lsr_write_fixed_16_8(lsr, *(Fixed *)val, name); + lsr_write_fixed_16_8(lsr, *(Fixed *)val, name); } else { - lsr_write_fixed_16_8(lsr, ((SVG_Number *) val)->value, name); + lsr_write_fixed_16_8(lsr, ((SVG_Number *) val)->value, name); } break; case 12: lsr_write_any_uri(lsr, (XMLRI*)val, name); break; @@ -1528,7 +1528,7 @@ static void lsr_write_an_anim_value(GF_LASeRCodec *lsr, void *val, u32 lsr_type, case 5: lsr_write_paint(lsr, (SVG_Paint*)val, name); break; case 6: lsr_write_vluimsbf5(lsr, (u32) *(u8 *) val, name); break; case 10: lsr_write_vluimsbf5(lsr, *(u32 *) val, name); break; - case 11: + case 11: { s32 idx = lsr_get_font_index(lsr, (SVG_FontFamily*)val); if (idx<0) { @@ -1694,7 +1694,7 @@ static void lsr_write_float_list(GF_LASeRCodec *lsr, GF_List **l, const char *na } } -static u32 lsr_get_bit_size(GF_LASeRCodec *lsr, Fixed v) +static u32 lsr_get_bit_size(GF_LASeRCodec *lsr, Fixed v) { u32 val; v = gf_divfix(v, lsr->res_factor); @@ -1767,7 +1767,7 @@ static void lsr_write_point_sequence(GF_LASeRCodec *lsr, GF_List **pts, const ch } static void lsr_write_path_type(GF_LASeRCodec *lsr, SVG_PathData *path, const char *name) { -#if USE_GF_PATH +#if USE_GF_PATH u32 i, *contour, nb_types; GF_List *pts = gf_list_new(); @@ -2287,17 +2287,17 @@ static void lsr_write_g(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag) gf_svg_flatten_attributes(elt, &atts); - if (!ommit_tag + if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_g, &same_fill, NULL, 0) && same_fill ) { /*samegType*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sameg, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sameg, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); is_same = 1; } else { /*gType*/ - if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_g, 6, "ch4"); + if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_g, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_rare(lsr, (GF_Node *) elt); @@ -2347,12 +2347,12 @@ static void lsr_write_line(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag) && same_fill ) { /*samelineType*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sameline, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sameline, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); is_same = 1; } else { /*lineType*/ - if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_line, 6, "ch4"); + if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_line, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_rare(lsr, (GF_Node *) elt); @@ -2409,18 +2409,18 @@ static void lsr_write_path(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag) is_same = 1; if (!same_fill) { /*samepathfillType*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samepathfill, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samepathfill, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_fill(lsr, elt, &atts); } else { /*samepathType*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samepath, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samepath, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); } lsr_write_path_type(lsr, atts.d, "d"); } else { /*pathType*/ - if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_path, 6, "ch4"); + if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_path, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_rare(lsr, (GF_Node *) elt); @@ -2446,7 +2446,7 @@ static void lsr_write_polygon(GF_LASeRCodec *lsr, SVG_Element *elt, Bool is_poly SVGAllAttributes atts; gf_svg_flatten_attributes(elt, &atts); - if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_polygon, &same_fill, &same_stroke, 1) + if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_polygon, &same_fill, &same_stroke, 1) ) { if (same_fill && same_stroke) same_type = 1; else if (same_fill) same_type = 3; @@ -2461,14 +2461,14 @@ static void lsr_write_polygon(GF_LASeRCodec *lsr, SVG_Element *elt, Bool is_poly /*samepolylinestrokeType / samepolygonstrokeType*/ else if (same_type==3) type = is_polyline ? LSR_SCENE_CONTENT_MODEL_samepolylinestroke : LSR_SCENE_CONTENT_MODEL_samepolygonstroke; - GF_LSR_WRITE_INT(lsr, type, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, type, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); if (same_type==2) lsr_write_fill(lsr, elt, &atts); else if (same_type==3) lsr_write_stroke(lsr, elt, &atts); lsr_write_point_sequence(lsr, atts.points, "points"); } else { /*polyline/polygon*/ - if (!ommit_tag) GF_LSR_WRITE_INT(lsr, is_polyline ? LSR_SCENE_CONTENT_MODEL_polyline : LSR_SCENE_CONTENT_MODEL_polygon, 6, "ch4"); + if (!ommit_tag) GF_LSR_WRITE_INT(lsr, is_polyline ? LSR_SCENE_CONTENT_MODEL_polyline : LSR_SCENE_CONTENT_MODEL_polygon, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_rare(lsr, (GF_Node *) elt); @@ -2503,16 +2503,16 @@ static void lsr_write_rect(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag) SVGAllAttributes atts; gf_svg_flatten_attributes(elt, &atts); - if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_rect, &same_fill, NULL, 0) + if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_rect, &same_fill, NULL, 0) ) { if (!same_fill) { same_type = 2; /*samerectfillType*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samerectfill, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samerectfill, 6, "ch4"); } else { same_type = 1; /*samerectType*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samerect, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_samerect, 6, "ch4"); } lsr_write_id(lsr, (GF_Node *) elt); if (same_type==2) lsr_write_fill(lsr, elt, &atts); @@ -2522,7 +2522,7 @@ static void lsr_write_rect(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag) lsr_write_coordinate_ptr(lsr, atts.y, 1, "y"); } else { /*rectType*/ - if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_rect, 6, "ch4"); + if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_rect, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_rare(lsr, (GF_Node *) elt); lsr_write_fill(lsr, elt, &atts); @@ -2711,7 +2711,7 @@ static void lsr_write_svg(GF_LASeRCodec *lsr, SVG_Element *elt) GF_LSR_WRITE_INT(lsr, atts.zoomAndPan ? 1 : 0, 1, "hasZoomAndPan"); if (atts.zoomAndPan) { - GF_LSR_WRITE_INT(lsr, (*atts.zoomAndPan==SVG_ZOOMANDPAN_MAGNIFY) ? 1 : 0, 1, "zoomAndPan"); + GF_LSR_WRITE_INT(lsr, (*atts.zoomAndPan==SVG_ZOOMANDPAN_MAGNIFY) ? 1 : 0, 1, "zoomAndPan"); } lsr_write_any_attribute(lsr, elt, 1); lsr_write_group_content(lsr, elt, 0); @@ -2741,12 +2741,12 @@ static void lsr_write_text(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag) if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_text, &same_fill, NULL, 0) ) { if (!same_fill) { /*sametextfillType*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sametextfill, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sametextfill, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_fill(lsr, elt, &atts); } else { /*sametextType*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sametext, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sametext, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); } lsr_write_coord_list(lsr, atts.text_x, "x"); @@ -2754,7 +2754,7 @@ static void lsr_write_text(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag) same_type = 1; } else { /*textType*/ - if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_text, 6, "ch4"); + if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_text, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_rare(lsr, (GF_Node *) elt); lsr_write_fill(lsr, (SVG_Element*)elt, &atts); @@ -2789,17 +2789,17 @@ static void lsr_write_use(GF_LASeRCodec *lsr, SVG_Element *elt, Bool ommit_tag) Bool is_same = 0; gf_svg_flatten_attributes(elt, &atts); - if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_use, NULL, NULL, 0) + if (!ommit_tag && lsr_elt_has_same_base(lsr, &atts, lsr->prev_use, NULL, NULL, 0) /*TODO check overflow*/ ) { is_same = 1; /*sameuseType*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sameuse, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_sameuse, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_href(lsr, atts.xlink_href); } else { /*useType*/ - if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_use, 6, "ch4"); + if (!ommit_tag) GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_use, 6, "ch4"); lsr_write_id(lsr, (GF_Node *) elt); lsr_write_rare(lsr, (GF_Node *) elt); lsr_write_fill(lsr, (SVG_Element*)elt, &atts); @@ -2865,7 +2865,7 @@ static void lsr_write_video(GF_LASeRCodec *lsr, SVG_Element *elt) GF_LSR_WRITE_INT(lsr, atts.syncReference ? 1 : 0, 1, "hasSyncReference"); if (atts.syncReference) lsr_write_any_uri(lsr, atts.syncReference, "syncReference"); - + lsr_write_any_attribute(lsr, elt, 1); lsr_write_group_content(lsr, elt, 0); } @@ -2925,172 +2925,172 @@ static void lsr_write_scene_content_model(GF_LASeRCodec *lsr, SVG_Element *paren u32 tag = gf_node_get_tag((GF_Node*)node); switch(tag) { - case TAG_SVG_a: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_a, 6, "ch4"); - lsr_write_a(lsr, node); + case TAG_SVG_a: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_a, 6, "ch4"); + lsr_write_a(lsr, node); break; - case TAG_SVG_animate: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animate, 6, "ch4"); - lsr_write_animate(lsr, node, parent); + case TAG_SVG_animate: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animate, 6, "ch4"); + lsr_write_animate(lsr, node, parent); break; - case TAG_SVG_animateColor: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animateColor, 6, "ch4"); - lsr_write_animate(lsr, node, parent); + case TAG_SVG_animateColor: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animateColor, 6, "ch4"); + lsr_write_animate(lsr, node, parent); break; - case TAG_SVG_animateMotion: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animateMotion, 6, "ch4"); - lsr_write_animateMotion(lsr, node, parent); + case TAG_SVG_animateMotion: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animateMotion, 6, "ch4"); + lsr_write_animateMotion(lsr, node, parent); break; - case TAG_SVG_animateTransform: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animateTransform, 6, "ch4"); - lsr_write_animateTransform(lsr, node, parent); + case TAG_SVG_animateTransform: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_animateTransform, 6, "ch4"); + lsr_write_animateTransform(lsr, node, parent); break; - case TAG_SVG_audio: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_audio, 6, "ch4"); - lsr_write_audio(lsr, node); + case TAG_SVG_audio: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_audio, 6, "ch4"); + lsr_write_audio(lsr, node); break; - case TAG_SVG_circle: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_circle, 6, "ch4"); - lsr_write_circle(lsr, node); + case TAG_SVG_circle: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_circle, 6, "ch4"); + lsr_write_circle(lsr, node); break; - case TAG_LSR_cursorManager: GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_cursorManager, 6, "ch4"); - lsr_write_cursorManager(lsr, node); + case TAG_LSR_cursorManager: GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_cursorManager, 6, "ch4"); + lsr_write_cursorManager(lsr, node); break; - case TAG_SVG_defs: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_defs, 6, "ch4"); - lsr_write_defs(lsr, node); + case TAG_SVG_defs: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_defs, 6, "ch4"); + lsr_write_defs(lsr, node); break; - case TAG_SVG_desc: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_desc, 6, "ch4"); - lsr_write_data(lsr, node); + case TAG_SVG_desc: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_desc, 6, "ch4"); + lsr_write_data(lsr, node); break; - case TAG_SVG_ellipse: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_ellipse, 6, "ch4"); - lsr_write_ellipse(lsr, node); + case TAG_SVG_ellipse: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_ellipse, 6, "ch4"); + lsr_write_ellipse(lsr, node); break; - case TAG_SVG_foreignObject: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_foreignObject, 6, "ch4"); - lsr_write_foreignObject(lsr, node); + case TAG_SVG_foreignObject: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_foreignObject, 6, "ch4"); + lsr_write_foreignObject(lsr, node); break; - + case TAG_SVG_g: /*type is written in encoding fct for sameg handling*/ - lsr_write_g(lsr, node, 0); + lsr_write_g(lsr, node, 0); break; - case TAG_SVG_image: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_image, 6, "ch4"); - lsr_write_image(lsr, node); + case TAG_SVG_image: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_image, 6, "ch4"); + lsr_write_image(lsr, node); break; - case TAG_SVG_line: + case TAG_SVG_line: /*type is written in encoding fct for sameline handling*/ - lsr_write_line(lsr, node, 0); + lsr_write_line(lsr, node, 0); break; - case TAG_SVG_linearGradient: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_linearGradient, 6, "ch4"); - lsr_write_linearGradient(lsr, node); + case TAG_SVG_linearGradient: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_linearGradient, 6, "ch4"); + lsr_write_linearGradient(lsr, node); break; - case TAG_SVG_metadata: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_metadata, 6, "ch4"); - lsr_write_data(lsr, node); + case TAG_SVG_metadata: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_metadata, 6, "ch4"); + lsr_write_data(lsr, node); break; - case TAG_SVG_mpath: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_mpath, 6, "ch4"); - lsr_write_mpath(lsr, node); + case TAG_SVG_mpath: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_mpath, 6, "ch4"); + lsr_write_mpath(lsr, node); break; - case TAG_SVG_path: + case TAG_SVG_path: /*type is written in encoding fct for samepath handling*/ - lsr_write_path(lsr, node, 0); + lsr_write_path(lsr, node, 0); break; - case TAG_SVG_polygon: + case TAG_SVG_polygon: /*type is written in encoding fct for samepolygon handling*/ - lsr_write_polygon(lsr, node, 0, 0); + lsr_write_polygon(lsr, node, 0, 0); break; - case TAG_SVG_polyline: + case TAG_SVG_polyline: /*type is written in encoding fct for samepolyline handling*/ - lsr_write_polygon(lsr, node, 1, 0); + lsr_write_polygon(lsr, node, 1, 0); break; - case TAG_SVG_radialGradient: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_radialGradient, 6, "ch4"); - lsr_write_radialGradient(lsr, node); + case TAG_SVG_radialGradient: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_radialGradient, 6, "ch4"); + lsr_write_radialGradient(lsr, node); break; case TAG_SVG_rect: /*type is written in encoding fct for samepolyline handling*/ - lsr_write_rect(lsr, node, 0); + lsr_write_rect(lsr, node, 0); break; - case TAG_SVG_script: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_script, 6, "ch4"); - lsr_write_script(lsr, node); + case TAG_SVG_script: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_script, 6, "ch4"); + lsr_write_script(lsr, node); break; - case TAG_SVG_set: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_set, 6, "ch4"); - lsr_write_set(lsr, node, parent); + case TAG_SVG_set: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_set, 6, "ch4"); + lsr_write_set(lsr, node, parent); break; - case TAG_SVG_stop: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_stop, 6, "ch4"); - lsr_write_stop(lsr, node); + case TAG_SVG_stop: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_stop, 6, "ch4"); + lsr_write_stop(lsr, node); break; - case TAG_SVG_switch: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_switch, 6, "ch4"); - lsr_write_switch(lsr, node); + case TAG_SVG_switch: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_switch, 6, "ch4"); + lsr_write_switch(lsr, node); break; case TAG_SVG_text: /*type is written in encoding fct for sametext handling*/ - lsr_write_text(lsr, node, 0); + lsr_write_text(lsr, node, 0); break; - case TAG_SVG_title: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_title, 6, "ch4"); - lsr_write_data(lsr, node); + case TAG_SVG_title: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_title, 6, "ch4"); + lsr_write_data(lsr, node); break; - case TAG_SVG_tspan: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_tspan, 6, "ch4"); - lsr_write_tspan(lsr, node); + case TAG_SVG_tspan: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_tspan, 6, "ch4"); + lsr_write_tspan(lsr, node); break; - case TAG_SVG_use: + case TAG_SVG_use: /*type is written in encoding fct for sameuse handling*/ - lsr_write_use(lsr, node, 0); + lsr_write_use(lsr, node, 0); break; - case TAG_SVG_video: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_video, 6, "ch4"); - lsr_write_video(lsr, node); + case TAG_SVG_video: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_video, 6, "ch4"); + lsr_write_video(lsr, node); break; - case TAG_SVG_listener: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_listener, 6, "ch4"); - lsr_write_listener(lsr, node); + case TAG_SVG_listener: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_listener, 6, "ch4"); + lsr_write_listener(lsr, node); break; - case TAG_LSR_conditional: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_conditional, 6, "ch4"); - lsr_write_conditional(lsr, node); + case TAG_LSR_conditional: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_conditional, 6, "ch4"); + lsr_write_conditional(lsr, node); break; - case TAG_LSR_rectClip: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_rectClip, 6, "ch4"); - lsr_write_rectClip(lsr, node); + case TAG_LSR_rectClip: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_rectClip, 6, "ch4"); + lsr_write_rectClip(lsr, node); break; - case TAG_LSR_selector: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_selector, 6, "ch4"); - lsr_write_selector(lsr, node); + case TAG_LSR_selector: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_selector, 6, "ch4"); + lsr_write_selector(lsr, node); break; - case TAG_LSR_simpleLayout: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_simpleLayout, 6, "ch4"); - lsr_write_simpleLayout(lsr, node); + case TAG_LSR_simpleLayout: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_simpleLayout, 6, "ch4"); + lsr_write_simpleLayout(lsr, node); break; #if 0 /*case privateElement*/ - case TAG_SVG_extendElement: - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_privateContainer, 6, "ch4"); - lsr_write_private_element_container(lsr); + case TAG_SVG_extendElement: + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_privateContainer, 6, "ch4"); + lsr_write_private_element_container(lsr); break; #endif default: #if 0 /*case extend*/ - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_element_any, 6, "ch4"); - lsr_write_extend_class(lsr, NULL, 0, node); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_element_any, 6, "ch4"); + lsr_write_extend_class(lsr, NULL, 0, node); break; #else /*hack for encoding - needs cleaning*/ GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] node %s not part of LASeR children nodes - skipping\n", gf_node_get_class_name((GF_Node*)node))); - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_textContent, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_textContent, 6, "ch4"); lsr_write_byte_align_string(lsr, "", "textContent"); break; #endif @@ -3100,29 +3100,29 @@ static void lsr_write_scene_content_model(GF_LASeRCodec *lsr, SVG_Element *paren static void lsr_write_update_content_model(GF_LASeRCodec *lsr, SVG_Element *parent, void *node) { u32 tag = gf_node_get_tag((GF_Node*)node); - + if (tag==TAG_LSR_conditional) { - GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); - GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_conditional, 3, "ch61"); + GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_conditional, 3, "ch61"); lsr_write_conditional(lsr, node); } else if (tag==TAG_LSR_cursorManager) { - GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); - GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_cursorManager, 3, "ch61"); + GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_cursorManager, 3, "ch61"); lsr_write_cursorManager(lsr, node); } else if (tag==TAG_LSR_rectClip) { - GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); - GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_rectClip, 3, "ch61"); + GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_rectClip, 3, "ch61"); lsr_write_rectClip(lsr, node); } else if (tag==TAG_LSR_selector) { - GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); - GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_selector, 3, "ch61"); + GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_selector, 3, "ch61"); lsr_write_selector(lsr, node); } else if (tag==TAG_LSR_simpleLayout) { - GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); - GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_simpleLayout, 3, "ch61"); + GF_LSR_WRITE_INT(lsr, 1, 1, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL2_simpleLayout, 3, "ch61"); lsr_write_simpleLayout(lsr, node); } else { - GF_LSR_WRITE_INT(lsr, 0, 1, "ch4"); + GF_LSR_WRITE_INT(lsr, 0, 1, "ch4"); switch(tag) { case TAG_SVG_a: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_a, 6, "ch6"); lsr_write_a(lsr, node); break; case TAG_SVG_animate: GF_LSR_WRITE_INT(lsr, LSR_UPDATE_CONTENT_MODEL_animate, 6, "ch6"); lsr_write_animate(lsr, node, parent); break; @@ -3180,7 +3180,7 @@ static void lsr_write_group_content(GF_LASeRCodec *lsr, SVG_Element *elt, Bool s while (l) { if (gf_node_get_tag(l->node)==TAG_DOMText) { GF_DOMText *txt = (GF_DOMText *)l->node; - GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_textContent, 6, "ch4"); + GF_LSR_WRITE_INT(lsr, LSR_SCENE_CONTENT_MODEL_textContent, 6, "ch4"); lsr_write_byte_align_string(lsr, txt->textContent, "textContent"); } else { lsr_write_scene_content_model(lsr, elt, l->node); @@ -3226,10 +3226,10 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie Fixed *v = gf_list_get(*(GF_List **)val, 0); Fixed f = *v; if ((f==0) || (f==FIX_ONE)) { - GF_LSR_WRITE_INT(lsr, 1, 1, "hasShort"); - GF_LSR_WRITE_INT(lsr, (f==0) ? 0 : 1, 1, "isZero"); + GF_LSR_WRITE_INT(lsr, 1, 1, "hasShort"); + GF_LSR_WRITE_INT(lsr, (f==0) ? 0 : 1, 1, "isZero"); } else { - GF_LSR_WRITE_INT(lsr, 0, 1, "hasShort"); + GF_LSR_WRITE_INT(lsr, 0, 1, "hasShort"); lsr_write_fixed_clamp(lsr, f, "timevalue"); } } @@ -3246,10 +3246,10 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie } else { switch (fieldType) { case SVG_Boolean_datatype: - GF_LSR_WRITE_INT(lsr, *(SVG_Boolean*)val ? 1 : 0, 1, "val"); + GF_LSR_WRITE_INT(lsr, *(SVG_Boolean*)val ? 1 : 0, 1, "val"); break; case SVG_Paint_datatype: - lsr_write_paint(lsr, (SVG_Paint *)val, "val"); + lsr_write_paint(lsr, (SVG_Paint *)val, "val"); break; case SVG_Transform_datatype: lsr_write_matrix(lsr, (SVG_Transform*)val); @@ -3264,8 +3264,8 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie lsr_write_coordinate(lsr, ((SVG_Point *)val)->y, 0, "translation_y"); break; case SVG_Transform_Rotate_datatype: - GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); - GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); + GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); lsr_write_fixed_16_8(lsr, ((SVG_Point_Angle*)val)->angle, "rotate"); break; case SVG_Number_datatype: @@ -3283,9 +3283,9 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie case TAG_SVG_ATT_stroke_opacity: case TAG_SVG_ATT_viewport_fill_opacity: if (n->type==SVG_NUMBER_INHERIT) { - GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue"); } else { - GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); lsr_write_fixed_clamp(lsr, n->value, "val"); } break; @@ -3299,10 +3299,10 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie break; default: if (n->type==SVG_NUMBER_INHERIT) { - GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue"); } else { - GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); - GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); + GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); lsr_write_fixed_16_8(lsr, n->value, "val"); } } @@ -3327,8 +3327,8 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie lsr_write_coordinate(lsr, n->value, 0, "val"); break; case SVG_Coordinates_datatype: - GF_LSR_WRITE_INT(lsr, 0, 1, "isInherit"); - GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); + GF_LSR_WRITE_INT(lsr, 0, 1, "isInherit"); + GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); lsr_write_float_list(lsr, (GF_List **)val, "val"); break; case XMLRI_datatype: @@ -3374,13 +3374,13 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie case LASeR_Choice_datatype: { LASeR_Choice *ch = (LASeR_Choice *)val; - GF_LSR_WRITE_INT(lsr, (ch->type==LASeR_CHOICE_ALL) ? 1 : 0, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, (ch->type==LASeR_CHOICE_ALL) ? 1 : 0, 1, "isDefaultValue"); if (ch->type!=LASeR_CHOICE_ALL) { - GF_LSR_WRITE_INT(lsr, (ch->type==LASeR_CHOICE_NONE) ? 1 : 0, 1, "escapeFlag"); + GF_LSR_WRITE_INT(lsr, (ch->type==LASeR_CHOICE_NONE) ? 1 : 0, 1, "escapeFlag"); if (ch->type==LASeR_CHOICE_NONE) { - GF_LSR_WRITE_INT(lsr, LASeR_CHOICE_NONE, 2, "escapeEnum"); + GF_LSR_WRITE_INT(lsr, LASeR_CHOICE_NONE, 2, "escapeEnum"); } else { - lsr_write_vluimsbf5(lsr, ((LASeR_Choice *)val)->choice_index, "value"); + lsr_write_vluimsbf5(lsr, ((LASeR_Choice *)val)->choice_index, "value"); } } } @@ -3388,8 +3388,8 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie case SVG_ViewBox_datatype: { SVG_ViewBox *b = (SVG_ViewBox *)val; - GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); - GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); + GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); lsr_write_vluimsbf5(lsr, 4, "nb1"); lsr_write_fixed_16_8(lsr, b->x, "x"); lsr_write_fixed_16_8(lsr, b->y, "y"); @@ -3400,15 +3400,15 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie case SVG_FontFamily_datatype: { SVG_FontFamily *ff = (SVG_FontFamily *)val; - GF_LSR_WRITE_INT(lsr, (ff->type == SVG_FONTFAMILY_INHERIT) ? 1 : 0, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, (ff->type == SVG_FONTFAMILY_INHERIT) ? 1 : 0, 1, "isDefaultValue"); if (ff->type != SVG_FONTFAMILY_INHERIT) { - u32 idx = lsr_get_font_index(lsr, ff); + s32 idx = lsr_get_font_index(lsr, ff); if (idx==-1) { GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[LASeR] corrupted font table while encoding update value\n")); idx=0; } - GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); - lsr_write_vluimsbf5(lsr, idx, "nb1"); + GF_LSR_WRITE_INT(lsr, 0, 1, "escapeFlag"); + lsr_write_vluimsbf5(lsr, (u32) idx, "nb1"); } } break; @@ -3417,9 +3417,9 @@ static void lsr_write_update_value(GF_LASeRCodec *lsr, SVG_Element *elt, u32 fie u8 v = *(u8 *)val; /*TODO fixme, check inherit/default values*/ if (!v) { - GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, 1, 1, "isDefaultValue"); } else { - GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); + GF_LSR_WRITE_INT(lsr, 0, 1, "isDefaultValue"); lsr_write_vluimsbf5(lsr, v, "val"); } } else { @@ -3672,17 +3672,17 @@ exit: gf_bs_del(lsr->bs); lsr->bs = old_bs; lsr_write_vluimsbf5(lsr, data_size, NULL/*"encoding-length" - don't log to avoid corrupting the log order!!*/); - /*script is aligned*/ + /*script is aligned*/ gf_bs_align(lsr->bs); gf_bs_write_data(lsr->bs, data, data_size); - free(data); + gf_free(data); } return lsr->last_error; } static void lsr_add_color(GF_LASeRCodec *lsr, SVG_Color *color) { - lsr->col_table = (LSRCol*)realloc(lsr->col_table, sizeof(LSRCol)*(lsr->nb_cols+1)); + lsr->col_table = (LSRCol*)gf_realloc(lsr->col_table, sizeof(LSRCol)*(lsr->nb_cols+1)); lsr->col_table[lsr->nb_cols].r = FIX2INT(color->red*lsr->color_scale); lsr->col_table[lsr->nb_cols].g = FIX2INT(color->green*lsr->color_scale); lsr->col_table[lsr->nb_cols].b = FIX2INT(color->blue*lsr->color_scale); @@ -3715,7 +3715,7 @@ static void lsr_check_font_index(GF_LASeRCodec *lsr, SVG_FontFamily *font) break; } } - if (!found) gf_list_add(lsr->font_table, strdup(font->value)); + if (!found) gf_list_add(lsr->font_table, gf_strdup(font->value)); } } @@ -3744,8 +3744,8 @@ static void lsr_check_font_and_color(GF_LASeRCodec *lsr, SVG_Element *elt) SMIL_AttributeName *an = (SMIL_AttributeName*)att->data; if (an->name) { if (!strcmp(an->name, "fill")) check_anim_col = 1; /*we're sure this is not SMIL fill, it is not animatable*/ - else if (!strcmp(an->name, "stroke")) check_anim_col = 1; - else if (!strcmp(an->name, "color")) check_anim_col = 1; + else if (!strcmp(an->name, "stroke")) check_anim_col = 1; + else if (!strcmp(an->name, "color")) check_anim_col = 1; else if (!strcmp(an->name, "solid-olor")) check_anim_col = 2; else if (!strcmp(an->name, "stop-color")) check_anim_col = 2; else if (!strcmp(an->name, "font-family")) check_anim_font = 1; @@ -3839,11 +3839,11 @@ static GF_Err lsr_write_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list, Bool r /*clean all tables*/ if (reset_encoding_context) { lsr->nb_cols = 0; - if (lsr->col_table) free(lsr->col_table); + if (lsr->col_table) gf_free(lsr->col_table); lsr->col_table = NULL; while (gf_list_count(lsr->font_table)) { char *ft = (char *)gf_list_last(lsr->font_table); - free(ft); + gf_free(ft); gf_list_rem_last(lsr->font_table); } } @@ -3941,4 +3941,4 @@ static GF_Err lsr_write_laser_unit(GF_LASeRCodec *lsr, GF_List *com_list, Bool r return GF_OK; } -#endif /*GPAC_DISABLE_SVG*/ +#endif /*GPAC_DISABLE_LASER*/ diff --git a/src/laser/lsr_tables.c b/src/laser/lsr_tables.c index 99a59b9..accca3f 100644 --- a/src/laser/lsr_tables.c +++ b/src/laser/lsr_tables.c @@ -32,7 +32,7 @@ #include <gpac/internal/laser_dev.h> - +#ifndef GPAC_DISABLE_LASER s32 gf_lsr_anim_type_from_attribute(u32 tag) { switch(tag) { @@ -847,3 +847,5 @@ u32 gf_lsr_same_rare(SVGAllAttributes *elt_atts, SVGAllAttributes *base_atts) return 1; } +#endif /*GPAC_DISABLE_LASER*/ + diff --git a/src/libgpac.def b/src/libgpac.def deleted file mode 100644 index ecd1c32..0000000 --- a/src/libgpac.def +++ /dev/null @@ -1,1235 +0,0 @@ -LIBRARY libgpac.dll - -;Note: the APIs and headers are likely to change a lot until 0.5.0 is reached, until all symbols needed -;by different scene decoders (SVG, X3D, etc) are identified - -EXPORTS -;tools.h exports - gf_sys_init - gf_sys_close - gf_sleep - gf_sys_clock - gf_sys_get_rti - gf_sys_get_battery_state - gf_4cc_to_str - gf_error_to_string - gf_rand_init - gf_rand - gf_get_user_name - gf_enum_directory - gf_log_get_tools - gf_log_get_level - gf_log_set_level - gf_log_set_tools - gf_log_set_callback - gf_log - gf_log_lt - gf_set_progress - gf_set_progress_callback - gf_temp_file_new - gf_delete_file - gf_f64_open - gf_f64_seek - gf_f64_tell - gf_prompt_has_input - gf_prompt_get_char - gf_prompt_set_echo_off - gf_crc_32 - - -; gf_mulfix -; gf_divfix -; gf_muldiv -; gf_atan2 -; gf_invfix -; gf_sqrt - gf_malloc - gf_realloc - gf_free - gf_strdup - -;array.h exports - gf_list_new - gf_list_del - gf_list_count - gf_list_add - gf_list_insert - gf_list_rem - gf_list_get - gf_list_enum - gf_list_find - gf_list_del_item - gf_list_reset - gf_list_last - gf_list_rem_last - -;bitstream.h exports - gf_bs_new - gf_bs_from_file - gf_bs_del - gf_bs_read_bit - gf_bs_read_int - gf_bs_read_long_int - gf_bs_read_u8 - gf_bs_read_u16 - gf_bs_read_u24 - gf_bs_read_u32 - gf_bs_read_u64 - gf_bs_read_float - gf_bs_read_double - gf_bs_read_data - gf_bs_write_int - gf_bs_write_long_int - gf_bs_write_u8 - gf_bs_write_u16 - gf_bs_write_u24 - gf_bs_write_u32 - gf_bs_write_u64 - gf_bs_write_float - gf_bs_write_double - gf_bs_write_data - gf_bs_set_eos_callback - gf_bs_align - gf_bs_available - gf_bs_get_content - gf_bs_skip_bytes - gf_bs_seek - gf_bs_peek_bits - gf_bs_get_position - gf_bs_get_size - gf_bs_get_refreshed_size - -;thread.h exports - gf_th_new - gf_th_del - gf_th_run - gf_th_stop - gf_th_status - gf_th_set_priority - gf_th_id - gf_mx_new - gf_mx_del - gf_mx_v - gf_mx_p - gf_mx_try_lock - gf_sema_new - gf_sema_del - gf_sema_notify - gf_sema_wait - gf_sema_wait_for - -;net.h exports - gf_sk_new - gf_sk_del - gf_sk_reset - gf_sk_set_buffer_size - gf_sk_set_block_mode - gf_sk_get_handle - gf_sk_bind - gf_sk_connect - gf_sk_send - gf_sk_receive - gf_sk_listen - gf_sk_accept - gf_sk_server_mode - gf_sk_get_host_name - gf_sk_get_local_ip - gf_sk_get_local_info - gf_sk_get_remote_address - gf_sk_send_to - gf_sk_setup_multicast - gf_sk_is_multicast_address - gf_sk_send_wait - gf_sk_receive_wait - gf_url_is_local - gf_url_get_absolute_path - gf_url_concatenate - gf_utc_time_since_1970 - gf_net_get_ntp - gf_net_has_ipv6 - gf_net_is_ipv6 - gf_net_mobileip_set_callback - - -;base_coding.h exports - gf_base64_encode - gf_base64_decode - gf_base16_encode - gf_base16_decode - -;token.h exports - gf_token_get - gf_token_get_line - gf_token_find - -;config.h exports - gf_cfg_new - gf_cfg_del - gf_cfg_save - gf_cfg_get_key - gf_cfg_set_key - gf_cfg_get_section_count - gf_cfg_get_section_name - gf_cfg_get_key_count - gf_cfg_get_key_name - gf_cfg_insert_key - -;module.h exports - gf_modules_new - gf_modules_del - gf_modules_refresh - gf_modules_get_count - gf_modules_get_file_name - gf_modules_load_interface - gf_modules_load_interface_by_name - gf_modules_close_interface - gf_modules_get_option - gf_modules_set_option - gf_modules_get_config - -;utf.h exports - gf_utf8_wcstombs - gf_utf8_mbstowcs - gf_utf8_wcslen - gf_utf8_reorder_bidi - -;download.h exports - gf_dm_sess_get_cache_name - gf_dm_sess_get_stats - gf_dm_sess_fetch_data - -;xml.h exports - gf_xml_sax_new - gf_xml_sax_del - gf_xml_sax_init - gf_xml_sax_parse - gf_xml_sax_suspend - gf_xml_sax_parse_file - gf_xml_sax_get_line - gf_xml_sax_get_file_size - gf_xml_sax_get_file_pos - gf_xml_sax_peek_node - gf_xml_sax_binary_file - gf_xml_sax_get_error - gf_xml_get_root_type - gf_xml_sax_get_node_start_pos - gf_xml_sax_get_node_end_pos - gf_xml_dom_new - gf_xml_dom_del - gf_xml_dom_parse - gf_xml_dom_get_root - gf_xml_dom_get_error - gf_xml_dom_get_line - -;math.h exports -; gf_mulfix -; gf_muldiv -; gf_divfix -; gf_invfix -; gf_cos -; gf_sin -; gf_tan -; gf_atan2 -; gf_sqrt -; gf_ceil -; gf_floor -; gf_acos -; gf_asin - - gf_angle_diff - gf_v2d_len - gf_v2d_from_polar - gf_rect_union - gf_rect_center - gf_rect_overlaps - gf_rect_equal - gf_rect_pixelize - gf_mx2d_add_matrix - gf_mx2d_pre_multiply - gf_mx2d_add_translation - gf_mx2d_add_rotation - gf_mx2d_add_scale - gf_mx2d_add_scale_at - gf_mx2d_add_skew - gf_mx2d_add_skew_x - gf_mx2d_add_skew_y - gf_mx2d_inverse - gf_mx2d_apply_coords - gf_mx2d_apply_point - gf_mx2d_apply_rect - gf_vec_len - gf_vec_lensq - gf_vec_dot - gf_vec_norm - gf_vec_scale - gf_vec_cross - gf_quat_to_rotation - gf_quat_from_matrix - gf_quat_from_rotation - gf_quat_get_inv - gf_quat_multiply - gf_quat_rotate - gf_quat_from_axis_cos - gf_quat_slerp - gf_bbox_refresh - gf_bbox_from_rect - gf_rect_from_bbox - gf_bbox_grow_point - gf_bbox_union - gf_bbox_equal - gf_bbox_point_inside - gf_bbox_get_vertices - gf_mx_from_mx2d - gf_mx_equal - gf_mx_add_translation - gf_mx_add_scale - gf_mx_add_rotation - gf_mx_add_matrix - gf_mx_add_matrix_2d - gf_mx_inverse - gf_mx_apply_vec - gf_mx_apply_rect - gf_mx_ortho - gf_mx_perspective - gf_mx_lookat - gf_mx_apply_bbox - gf_mx_add_matrix_4x4 - gf_mx_inverse_4x4 - gf_mx_apply_vec_4x4 - gf_mx_decompose - gf_mx_rotate_vector - gf_mx_rotation_matrix_from_vectors - gf_mx2d_from_mx - gf_mx_apply_plane - gf_plane_get_distance - gf_plane_intersect_line - gf_closest_point_to_line - gf_plane_get_p_vertex_idx - gf_bbox_plane_relation - gf_mx_apply_ray - gf_ray - gf_ray_hit_box - gf_ray_hit_sphere - gf_ray_hit_triangle - gf_ray_hit_triangle_backcull - -;color.h exports - gf_stretch_bits - gf_cmx_init - gf_cmx_set - gf_cmx_set_all - gf_cmx_copy - gf_cmx_multiply - gf_cmx_apply - gf_cmx_apply_fixed - - -;path2d.h exports - gf_path_new - gf_path_del - gf_path_reset - gf_path_close - gf_path_add_move_to - gf_path_add_move_to_vec - gf_path_add_line_to - gf_path_add_line_to_vec - gf_path_add_cubic_to - gf_path_add_cubic_to_vec - gf_path_add_quadratic_to - gf_path_add_quadratic_to_vec - gf_path_add_rect_center - gf_path_add_rect - gf_path_add_ellipse - gf_path_add_bezier - gf_path_add_arc_to - gf_path_add_svg_arc_to - gf_path_add_arc - gf_path_get_control_bounds - gf_path_get_bounds - gf_path_flatten - gf_path_get_flatten - gf_path_iterator_new - gf_path_iterator_del - gf_path_iterator_get_length - gf_path_iterator_get_transform - gf_polygone2d_get_convexity - gf_path_get_outline - gf_path_point_over - -;mpeg4_odf.h exports - gf_odf_slc_set_pref - gf_odf_get_bifs_config - gf_odf_get_text_config - gf_odf_get_ui_config - gf_odf_get_laser_config - gf_odf_encode_ui_config - gf_odf_codec_new - gf_odf_codec_del - gf_odf_codec_add_com - gf_odf_codec_encode - gf_odf_codec_get_au - gf_odf_codec_set_au - gf_odf_codec_decode - gf_odf_codec_get_com - gf_odf_com_new - gf_odf_com_del - gf_odf_desc_new - gf_odf_desc_del - gf_odf_desc_read - gf_odf_desc_write - gf_odf_desc_size - gf_odf_desc_copy - gf_odf_desc_add_desc - gf_odf_desc_esd_new - gf_odf_desc_list_read - gf_odf_desc_list_write - gf_odf_desc_list_size - gf_odf_desc_list_del - gf_odf_stream_type_name - gf_odf_stream_type_by_name - gf_odf_qos_new - gf_odf_qos_del - gf_odf_qos_add_qualif - gf_oci_event_new - gf_oci_event_del - gf_oci_event_set_start_time - gf_oci_event_set_duration - gf_oci_event_add_desc - gf_oci_event_get_id - gf_oci_event_get_start_time - gf_oci_event_get_duration - gf_oci_event_get_desc_count - gf_oci_event_get_desc - gf_oci_event_rem_desc - gf_oci_codec_new - gf_oci_codec_del - gf_oci_codec_add_event - gf_oci_codec_encode - gf_oci_codec_decode - gf_oci_codec_get_event - gf_odf_dump_au - gf_odf_dump_com - gf_odf_dump_desc - gf_odf_dump_com_list - gf_oci_dump_event - gf_oci_dump_au - gf_odf_avc_cfg_new - gf_odf_avc_cfg_del - gf_odf_avc_cfg_read - gf_odf_avc_cfg_write - gf_sl_packetize - gf_sl_get_header_size - gf_sl_depacketize -; for MPEG-2 plugin - gf_odf_parse_descriptor - gf_odf_write_descriptor - -;isomedia.h exports - gf_isom_sample_new - gf_isom_sample_del - gf_isom_last_error - gf_isom_probe_file - gf_isom_open - gf_isom_close - gf_isom_delete - gf_isom_get_mode - gf_isom_open_progressive - gf_isom_get_missing_bytes - gf_isom_is_fragmented - gf_isom_is_track_fragmented - gf_isom_refresh_fragmented - gf_isom_get_track_count - gf_isom_get_timescale - gf_isom_get_duration - gf_isom_get_creation_time - gf_isom_get_track_id - gf_isom_get_track_by_id - gf_isom_is_track_enabled - gf_isom_is_track_encrypted - gf_isom_get_track_duration - gf_isom_get_media_type - gf_isom_get_media_subtype - gf_isom_get_mpeg4_subtype - gf_isom_get_media_time - gf_isom_get_sample_description_count - gf_isom_get_sample_description_index - gf_isom_is_self_contained - gf_isom_get_media_duration - gf_isom_get_media_timescale - gf_isom_get_max_chunk_duration - gf_isom_get_handler_name - gf_isom_get_media_language - gf_isom_check_data_reference - gf_isom_get_data_reference - gf_isom_get_sample_count - gf_isom_set_sample_padding - gf_isom_get_sample - gf_isom_get_sample_info - gf_isom_get_sample_for_media_time - gf_isom_get_sample_for_movie_time - gf_isom_get_sample_dts - gf_isom_get_sample_duration - gf_isom_get_edit_segment_count - gf_isom_get_edit_segment - gf_isom_get_copyright_count - gf_isom_get_copyright - gf_isom_get_watermark - gf_isom_has_sync_points - gf_isom_has_time_offset - gf_isom_get_sync_point_count - gf_isom_has_root_od - gf_isom_get_root_od - gf_isom_is_track_in_root_od - gf_isom_get_esd - gf_isom_get_decoder_config - gf_isom_get_reference_count - gf_isom_get_reference - gf_isom_get_filename - gf_isom_get_brand_info - gf_isom_get_alternate_brand - gf_isom_has_padding_bits - gf_isom_get_visual_info - gf_isom_get_pixel_aspect_ratio - gf_isom_get_audio_info - gf_isom_get_chapter_count - gf_isom_get_chapter - gf_isom_get_user_data_count - gf_isom_get_user_data - gf_isom_get_generic_sample_description - gf_isom_get_fragment_defaults - gf_isom_get_sample_fragment_count - gf_isom_get_sample_fragment_size - gf_isom_sdp_get - gf_isom_sdp_track_get - gf_isom_set_default_sync_track - gf_isom_dump - gf_isom_dump_hint_sample - gf_isom_3gp_config_get - gf_isom_text_set_streaming_mode - gf_isom_text_dump - gf_isom_get_track_layout_info - gf_isom_get_pl_indication - gf_isom_is_media_encrypted - gf_isom_get_ismacryp_info - gf_isom_is_ismacryp_media - gf_isom_ismacryp_delete_sample - gf_isom_get_ismacryp_sample - gf_isom_avc_config_get - gf_isom_3gp_config_get - gf_isom_get_meta_item_count - gf_isom_get_meta_item_by_id - gf_isom_get_meta_item_info - gf_isom_get_meta_type - gf_isom_has_meta_xml - gf_isom_has_movie - gf_isom_is_single_av - gf_isom_guess_specification - gf_isom_reset_hint_reader - gf_isom_next_hint_packet - gf_isom_has_sync_shadows - gf_isom_has_sample_dependency - gf_isom_find_od_for_track - gf_isom_apple_get_tag - gf_isom_get_media_data_size - gf_isom_get_omadrm_info - gf_isom_is_omadrm_media - gf_isom_get_dims_description - gf_isom_new_dims_description - gf_isom_update_dims_description - gf_isom_get_track_switch_group_count - gf_isom_get_track_switch_parameter - gf_isom_get_next_alternate_group_id - gf_isom_get_payt_count - gf_isom_get_payt_info - gf_isom_get_meta_primary_item_id - gf_isom_is_JPEG2000 - - -;NON-READ-ONLY exports - gf_isom_set_timescale - gf_isom_new_track - gf_isom_remove_track - gf_isom_set_track_enabled - gf_isom_set_track_id - gf_isom_add_sample - gf_isom_add_sample_shadow - gf_isom_append_sample_data - gf_isom_refresh_size_info - gf_isom_add_sample_reference - gf_isom_set_last_sample_duration - gf_isom_set_track_reference - gf_isom_remove_track_reference - gf_isom_update_sample - gf_isom_update_sample_reference - gf_isom_remove_sample - gf_isom_set_final_name - gf_isom_set_storage_mode - gf_isom_get_storage_mode - gf_isom_set_interleave_time - gf_isom_get_interleave_time - gf_isom_set_copyright - gf_isom_remove_copyright - gf_isom_set_watermark - gf_isom_set_edit_segment - gf_isom_modify_edit_segment - gf_isom_append_edit_segment - gf_isom_remove_edit_segments - gf_isom_remove_edit_segment - gf_isom_set_media_language - gf_isom_set_handler_name - gf_isom_add_user_data - gf_isom_remove_user_data - gf_isom_remove_user_data_item - gf_isom_use_compact_size - gf_isom_set_brand_info - gf_isom_modify_alternate_brand - gf_isom_set_sample_padding_bits - gf_isom_set_visual_info - gf_isom_set_pixel_aspect_ratio - gf_isom_set_track_layout_info - gf_isom_set_audio_info - gf_isom_add_sample_fragment - gf_isom_remove_sample_fragment - gf_isom_set_cts_packing - gf_isom_modify_cts_offset - gf_isom_remove_cts_info - gf_isom_set_track_name - gf_isom_get_track_name - gf_isom_set_pl_indication - gf_isom_set_root_od_id - gf_isom_set_root_od_url - gf_isom_remove_root_od - gf_isom_add_desc_to_root_od - gf_isom_add_track_to_root_od - gf_isom_remove_track_from_root_od - gf_isom_new_mpeg4_description - gf_isom_change_mpeg4_description - gf_isom_add_desc_to_description - gf_isom_new_generic_sample_description - gf_isom_change_generic_sample_description - gf_isom_remove_sample_description - gf_isom_clone_sample_description - gf_isom_clone_track - gf_isom_clone_pl_indications - gf_isom_clone_root_od - gf_isom_is_same_sample_description - gf_isom_add_chapter - gf_isom_remove_chapter - gf_isom_setup_track_fragment - gf_isom_finalize_for_fragment - gf_isom_start_fragment - gf_isom_set_fragment_option - gf_isom_fragment_add_sample - gf_isom_fragment_append_data - gf_isom_remove_sync_shadows - gf_isom_set_sync_shadow - gf_isom_set_track_group - gf_isom_set_track_priority_in_group - gf_isom_set_max_samples_per_chunk - gf_isom_set_extraction_slc - gf_isom_get_extraction_slc - gf_isom_get_track_group - gf_isom_get_track_priority_in_group - gf_isom_store_movie_config - gf_isom_load_movie_config - gf_isom_make_interleave - gf_isom_setup_hint_track - gf_isom_new_hint_description - gf_isom_begin_hint_sample - gf_isom_end_hint_sample - gf_isom_hint_blank_data - gf_isom_hint_direct_data - gf_isom_hint_sample_data - gf_isom_hint_sample_description_data - gf_isom_rtp_packet_begin - gf_isom_rtp_packet_set_flags - gf_isom_rtp_packet_set_offset - gf_isom_rtp_set_timescale - gf_isom_rtp_set_time_offset - gf_isom_rtp_set_time_sequence_offset - gf_isom_sdp_add_track_line - gf_isom_sdp_clean_track - gf_isom_sdp_add_line - gf_isom_sdp_clean - gf_isom_3gp_config_new - gf_isom_3gp_config_update - gf_isom_new_text_description - gf_isom_new_text_sample - gf_isom_delete_text_sample - gf_isom_text_reset - gf_isom_text_add_text - gf_isom_text_add_style - gf_isom_text_add_highlight - gf_isom_text_set_highlight_color - gf_isom_text_add_karaoke - gf_isom_text_set_karaoke_segment - gf_isom_text_set_scroll_delay - gf_isom_text_add_hyperlink - gf_isom_text_set_box - gf_isom_text_add_blink - gf_isom_text_set_wrap - gf_isom_text_to_sample - gf_isom_remove_ismacryp_protection - gf_isom_set_ismacryp_protection - gf_isom_change_ismacryp_protection - gf_isom_dump_ismacryp_protection - gf_isom_dump_ismacryp_sample - gf_isom_avc_config_new - gf_isom_avc_config_update - gf_isom_3gp_config_new - gf_isom_3gp_config_update - gf_isom_set_media_timescale - gf_isom_estimate_size - gf_isom_set_meta_type - gf_isom_add_meta_item - gf_isom_remove_meta_item - gf_isom_set_meta_primary_item - gf_isom_set_meta_xml - gf_isom_remove_meta_xml - gf_isom_extract_meta_xml - gf_isom_extract_meta_item - gf_isom_apple_set_tag - gf_isom_get_next_alternate_group_id - gf_isom_set_ipod_compatible - gf_media_make_psp - gf_isom_reset_switch_parameters - gf_isom_reset_track_switch_parameter - gf_isom_set_track_switch_parameter - gf_isom_set_alternate_group_id -;end GPAC_READ_ONLY - -;isomedia_dev.h exports - gf_isom_parse_texte_sample - -;plugin_network.h exports - gf_term_on_message - gf_term_on_connect - gf_term_on_disconnect - gf_term_on_command - gf_term_on_sl_packet - gf_term_get_service_url - gf_term_add_media - gf_term_register_mime_type - gf_term_check_extension - gf_term_download_new - gf_term_download_del - gf_term_download_update_stats - gf_term_scene_update - gf_term_get_screen_buffer - gf_term_release_screen_buffer - -;ietf.h exports - gf_rtsp_nc_to_string - gf_rtsp_range_parse - gf_rtsp_range_new - gf_rtsp_range_del - gf_rtsp_transport_clone - gf_rtsp_transport_del - gf_rtsp_command_new - gf_rtsp_command_del - gf_rtsp_command_reset - gf_rtsp_response_new - gf_rtsp_response_del - gf_rtsp_response_reset - gf_rtsp_session_new - gf_rtsp_session_del - gf_rtsp_set_buffer_size - gf_rtsp_set_mobile_ip - gf_rtsp_session_reset - gf_rtsp_is_my_session - gf_rtsp_get_last_session_id - gf_rtsp_get_server_name - gf_rtsp_get_service_name - gf_rtsp_get_response - gf_rtsp_get_session_state - gf_rtsp_get_last_request - gf_rtsp_reset_aggregation - gf_rtsp_send_command - gf_rtsp_set_interleave_callback - gf_rtsp_session_read - gf_rtsp_register_interleave - gf_rtsp_unregister_interleave - gf_rtsp_session_new_server - gf_rtsp_get_command - gf_rtsp_load_service_name - gf_rtsp_generate_session_id - gf_rtsp_send_response - gf_rtsp_get_session_ip - gf_rtsp_get_next_interleave_id - gf_rtsp_get_remote_address - gf_rtsp_get_session_port - gf_rtp_new - gf_rtp_del - gf_rtp_setup_transport - gf_rtp_set_ports - gf_rtp_setup_payload - gf_rtp_enable_nat_keepalive - gf_rtp_initialize - gf_rtp_set_info_rtp - gf_rtp_get_current_time - gf_rtp_reset_buffers - gf_rtp_read_rtp - gf_rtp_read_rtcp - gf_rtp_decode_rtp - gf_rtp_decode_rtcp - gf_rtp_send_rtcp_report - gf_rtp_send_bye - gf_rtp_send_packet - gf_rtp_set_info_rtcp - gf_rtp_is_unicast - gf_rtp_is_interleaved - gf_rtp_get_clockrate - gf_rtp_is_active - gf_rtp_get_low_interleave_id - gf_rtp_get_hight_interleave_id - gf_rtp_get_transport - gf_rtp_get_local_ssrc - gf_rtp_get_loss - gf_rtp_get_tcp_bytes_sent - gf_rtp_get_ports - gf_sdp_info_new - gf_sdp_info_del - gf_sdp_info_reset - gf_sdp_info_parse - gf_sdp_info_check - gf_sdp_info_write - gf_sdp_media_new - gf_sdp_media_del - gf_sdp_conn_new - gf_sdp_conn_del - gf_sdp_fmtp_new - gf_sdp_fmtp_del - gf_rtp_builder_new - gf_rtp_builder_del - gf_rtp_builder_init - gf_rtp_builder_process - gf_rtp_builder_format_sdp - gf_rtp_builder_get_payload_name - gf_rtp_depacketizer_new - gf_rtp_depacketizer_del - gf_rtp_depacketizer_reset - gf_rtp_depacketizer_process - gf_rtp_depacketizer_get_slconfig - -;avilib exports - AVI_write_frame - AVI_close - AVI_open_output_file - AVI_set_video - -;media.h exports - gf_hinter_track_new - gf_hinter_track_del - gf_hinter_track_process - gf_hinter_track_finalize - gf_hinter_finalize - gf_hinter_track_get_bandwidth - gf_hinter_track_get_flags - gf_hinter_track_get_payload_name - gf_hinter_can_embbed_data - gf_hinter_format_ttxt_sdp - gf_media_make_isma - gf_media_make_3gpp - gf_media_map_esd - gf_media_import - gf_media_export - gf_media_fragment_file - gf_media_import_chapters - gf_media_change_par - gf_media_get_file_hash - gf_rtp_packetizer_create_and_init_from_file - - -;mcrypt exports - gf_crypt_open - gf_crypt_close - gf_crypt_init - gf_crypt_decrypt - gf_crypt_encrypt - gf_crypt_set_state - -;parsers_av.h exports - gf_m4v_parser_new - gf_m4v_parser_del - gf_m4v_parse_config - gf_m4v_parse_frame - gf_m4v_get_object_start - gf_m4v_is_valid_object_type - gf_m4v_get_profile_name - gf_m4v_get_config - gf_m4v_rewrite_pl - gf_mp3_num_channels - gf_mp3_sampling_rate - gf_mp3_window_size - gf_mp3_object_type_indication - gf_mp3_layer - gf_mp3_version - gf_mp3_version_name - gf_mp3_frame_size - gf_mp3_get_next_header - gf_mp3_get_next_header_mem - gf_m4a_get_config - gf_m4a_write_config - gf_m4a_object_type_name - gf_m4a_get_profile_name - gf_vorbis_parse_header - gf_vorbis_check_frame - gf_avc_get_sps_info - gf_avc_get_profile_name - gf_img_parse - gf_img_jpeg_dec - gf_img_png_dec - gf_img_png_enc - gf_ac3_parser_bs - - -;ismacryp.h exports - gf_ismacryp_crypt_file - gf_ismacryp_decrypt_file - gf_ismacryp_encrypt_track - gf_ismacryp_decrypt_track - gf_ismacryp_gpac_get_info - gf_ismacryp_mpeg4ip_get_info - -;scene_manager.h exports - gf_sm_new - gf_sm_del - gf_sm_stream_new - gf_sm_stream_del - gf_sm_stream_au_new - gf_sm_make_random_access - gf_sm_reset - gf_sm_load_init - gf_sm_load_done - gf_sm_load_string - gf_sm_load_run - gf_sm_import_bifs_subtitle - gf_sm_dump - gf_sm_encode_to_file - gf_sm_dumper_new - gf_sm_dumper_del - gf_sm_dump_command_list - gf_sm_dump_graph - gf_sm_stats_new - gf_sm_stats_del - gf_sm_stats_reset - gf_sm_stats_get - gf_sm_stats_for_graph - gf_sm_stats_for_scene - gf_sm_stats_for_command - -;bifsengine exports - gf_beng_init - gf_beng_init_from_string - gf_beng_init_from_context - gf_beng_get_stream_config - gf_beng_encode_context - gf_beng_encode_from_file - gf_beng_encode_from_string - gf_beng_save_context - gf_beng_aggregate_context - gf_beng_terminate - -;bifs.h exports - gf_bifs_decoder_new - gf_bifs_decoder_del - gf_bifs_decoder_ignore_size_info - gf_bifs_decoder_configure_stream - gf_bifs_decoder_remove_stream - gf_bifs_decode_au - gf_bifs_decode_command_list - gf_bifs_encoder_new - gf_bifs_encoder_del - gf_bifs_encoder_new_stream - gf_bifs_encode_au - gf_bifs_encoder_get_config - gf_bifs_encoder_get_version - gf_bifs_encoder_get_rap - gf_bifs_get_aq_info - gf_bifs_get_node_type - - -;scenegraph.h and scenegraph_vrml.h exports - gf_node_get_tag - gf_node_set_id - gf_node_get_name - gf_node_get_id - gf_node_get_name_and_id - gf_node_get_private - gf_node_set_private - gf_node_set_callback_function - gf_node_register - gf_node_unregister - gf_node_replace - gf_node_unregister_children - gf_node_insert_child - gf_node_remove_child - gf_node_replace_child - gf_node_event_out - gf_node_event_out_str - gf_node_allow_cyclic_traverse - gf_node_traverse - gf_node_traverse_children - gf_node_get_parent_count - gf_node_get_parent - gf_node_get_class_name - gf_node_dirty_set - gf_node_dirty_clear - gf_node_dirty_get - gf_node_dirty_reset - gf_node_get_field - gf_node_get_field_by_name - gf_node_get_graph - gf_node_init - gf_node_get_scene_time - gf_sg_new - gf_sg_new_subscene - gf_sg_set_scene_time_callback - gf_sg_set_node_callback - gf_sg_set_proto_loader - gf_sg_del - gf_sg_set_private - gf_sg_get_private - gf_sg_set_scene_size_info - gf_sg_use_pixel_metrics - gf_sg_get_scene_size_info - gf_sg_reset - gf_sg_get_root_node - gf_sg_set_root_node - gf_sg_find_node - gf_sg_find_node_by_name - gf_node_changed - gf_node_new - gf_node_clone - gf_sg_vrml_get_event_type_name - gf_sg_vrml_get_field_type_by_name - gf_sg_vrml_field_pointer_new - gf_sg_vrml_field_pointer_del - gf_sg_vrml_is_sf_field - gf_sg_vrml_get_sf_type - gf_sg_vrml_mf_insert - gf_sg_vrml_mf_append - gf_sg_vrml_mf_remove - gf_sg_vrml_mf_alloc - gf_sg_vrml_mf_get_item - gf_sg_vrml_mf_reset - gf_sg_vrml_field_copy - gf_sg_vrml_field_equal - gf_sg_route_new - gf_sg_route_del - gf_sg_route_del_by_id - gf_sg_route_find - gf_sg_route_find_by_name - gf_sg_route_set_id - gf_sg_route_get_id - gf_sg_route_set_name - gf_sg_route_get_name - gf_sg_activate_routes - gf_sg_proto_new - gf_sg_proto_del - gf_sg_proto_set_in_graph - gf_sg_proto_get_graph - gf_sg_proto_set_private - gf_sg_proto_get_private - gf_sg_proto_get_extern_url - gf_sg_proto_add_node_code - gf_sg_proto_get_field_count - gf_sg_proto_field_find_by_name - gf_sg_proto_field_find - gf_sg_proto_field_new - gf_sg_proto_field_set_ised - gf_sg_proto_field_set_private - gf_sg_proto_field_get_private - gf_sg_proto_field_get_field - gf_sg_proto_create_instance - gf_sg_proto_load_code - gf_sg_find_proto - gf_sg_delete_all_protos - gf_node_get_proto - gf_sg_proto_get_id - gf_sg_proto_get_class_name - gf_sg_proto_field_is_sftime_offset - gf_sg_proto_instance_set_ised - gf_sg_script_field_new - gf_sg_script_field_get_info - gf_sg_script_load - gf_sg_script_event_in - gf_sg_has_scripting - gf_bifs_proto_field_set_aq_info - gf_node_get_num_fields_in_mode - gf_sg_command_new - gf_sg_command_del - gf_sg_command_apply - gf_sg_command_apply_list - gf_sg_command_field_new - gf_sg_command_clone - gf_sg_get_next_available_node_id - gf_sg_get_max_node_id - gf_sg_get_next_available_route_id - gf_sg_set_max_defined_route_id - gf_sg_get_next_available_proto_id - gf_sg_sfrotation_interpolate - gf_node_get_field_count - gf_node_mpeg4_type_by_class_name - gf_node_x3d_type_by_class_name - gf_x3d_get_node_type - gf_sg_mfurl_del - gf_sg_sfcolor_to_rgba - gf_node_list_add_child - gf_node_list_insert_child - gf_node_list_del_child - gf_node_list_find_child - gf_node_list_get_child - gf_node_list_get_count - gf_node_list_del_child_idx - -;terminal.h exports - gf_term_new - gf_term_del - gf_term_connect - gf_term_disconnect - gf_term_navigate_to - gf_term_play_from_time - gf_term_set_option - gf_term_get_option - gf_term_get_framerate - gf_term_get_time_in_ms - gf_term_get_viewpoint - gf_term_set_viewpoint - gf_term_get_root_object - gf_term_get_object_count - gf_term_get_object - gf_term_object_subscene_type - gf_term_select_object - gf_term_get_object_info - gf_term_get_download_info - gf_term_get_channel_net_info - gf_term_get_world_info - gf_term_dump_scene - gf_term_set_size - gf_term_user_event - gf_term_mouse_input - gf_term_keyboard_input - gf_term_string_input - gf_term_connect_from_time - gf_term_add_object - gf_term_is_supported_url - gf_term_attach_service - gf_term_set_simulation_frame_rate - gf_term_get_simulation_frame_rate - gf_term_step_clocks - gf_term_process_flush - gf_term_process_step - gf_term_get_service_interface - gf_term_get_service_info - gf_term_get_text_selection - gf_term_paste_text - gf_term_get_url - -;compositor.h exports - gf_sc_new - gf_sc_del - gf_sc_set_fps - gf_sc_set_scene - gf_sc_draw_frame - gf_sc_on_node_init - gf_sc_invalidate - gf_sc_get_clock - gf_sc_lock - gf_sc_user_event - gf_sc_map_point - gf_sc_set_option - gf_sc_get_option - gf_sc_get_fps - gf_sc_get_screen_buffer - gf_sc_release_screen_buffer - gf_sc_simulation_tick - gf_sc_reset_graphics - gf_sc_pick_node - gf_sc_get_viewpoint - gf_sc_set_viewpoint - gf_sc_set_size - gf_sc_register_extra_graph - -;render_dev.h exports - gf_sc_register_time_node - gf_sc_unregister_time_node - gf_sc_texture_setup - gf_sc_texture_destroy - gf_sc_texture_get_handler - gf_sc_texture_check_url_change - gf_sc_texture_play - gf_sc_texture_play_from_to - gf_sc_texture_stop - gf_sc_texture_restart - gf_sc_texture_update_frame - gf_sc_texture_release_stream - gf_sc_audio_register - gf_sc_audio_unregister - gf_sc_audio_setup - gf_sc_audio_open - gf_sc_audio_stop - gf_sc_audio_restart - gf_sc_get_compositor - - -;terminal_dev exports - gf_inline_new - gf_inline_del - gf_inline_get_time - gf_inline_attach_to_compositor - gf_inline_find_odm - gf_inline_set_duration - gf_inline_setup_object - gf_inline_default_scene_viewpoint - gf_inline_register_extra_graph - gf_inline_force_scene_size - gf_inline_get_proto_lib - gf_inline_process_anchor - gf_inline_disconnect - gf_odm_new - gf_odm_setup_object - gf_odm_disconnect - gf_odm_setup_es - gf_odm_remove_es - gf_term_message - gf_term_node_callback - gf_clock_time - -;mpegts.h exports - gf_m2ts_demux_new - gf_m2ts_demux_del - gf_m2ts_process_data - gf_m2ts_reset_parsers - gf_m2ts_set_pes_framing - gf_m2ts_get_stream_name - gf_m2ts_crc32_check - gf_m2ts_decode_mjd_date - -;laser.h exports - gf_laser_decoder_new - gf_laser_decoder_del - gf_laser_decoder_set_clock - gf_laser_decoder_configure_stream - gf_laser_decoder_remove_stream - gf_laser_decode_au - gf_laser_decode_command_list - gf_laser_encoder_new - gf_laser_encoder_del - gf_laser_encoder_new_stream - gf_laser_encode_au - gf_laser_encoder_get_config - gf_laser_encoder_get_rap - - -;SVG exports for SVG->BIFS - gf_svg_parse_attribute - gf_svg_parse_style - gf_node_get_attribute_by_tag - gf_svg_flatten_attributes - gf_svg_apply_inheritance - gf_svg_properties_init_pointers - gf_svg_properties_reset_pointers - gf_node_register_iri - gf_node_unregister_iri - diff --git a/src/libgpac_ce.def b/src/libgpac_ce.def deleted file mode 100644 index 07c3812..0000000 --- a/src/libgpac_ce.def +++ /dev/null @@ -1,1207 +0,0 @@ -LIBRARY libgpac.dll - -;Note: the APIs and headers are likely to change a lot until 0.5.0 is reached, until all symbols needed -;by different scene decoders (SVG, X3D, etc) are identified - -EXPORTS -;setup.h exports, winCE only - CE_Assert - CE_WideToChar - CE_CharToWide - -;tools.h exports - gf_sleep - gf_sys_init - gf_sys_close - gf_sys_clock - gf_sys_get_rti - gf_sys_get_battery_state - gf_4cc_to_str - gf_error_to_string - gf_rand_init - gf_rand - gf_utc_time_since_1970 - gf_get_user_name - gf_enum_directory - gf_log_get_tools - gf_log_get_level - gf_log_set_level - gf_log_set_tools - gf_log_set_callback - gf_log - gf_log_lt - gf_set_progress - gf_set_progress_callback - gf_malloc - gf_realloc - gf_free - gf_strdup - gf_crc_32 - - -;array.h exports - gf_list_new - gf_list_del - gf_list_count - gf_list_add - gf_list_insert - gf_list_rem - gf_list_get - gf_list_enum - gf_list_find - gf_list_del_item - gf_list_reset - gf_list_last - gf_list_rem_last - -;bitstream.h exports - gf_bs_new - gf_bs_from_file - gf_bs_del - gf_bs_read_bit - gf_bs_read_int - gf_bs_read_long_int - gf_bs_read_u8 - gf_bs_read_u16 - gf_bs_read_u24 - gf_bs_read_u32 - gf_bs_read_u64 - gf_bs_read_float - gf_bs_read_double - gf_bs_read_data - gf_bs_write_int - gf_bs_write_long_int - gf_bs_write_u8 - gf_bs_write_u16 - gf_bs_write_u24 - gf_bs_write_u32 - gf_bs_write_u64 - gf_bs_write_float - gf_bs_write_double - gf_bs_write_data - gf_bs_set_eos_callback - gf_bs_align - gf_bs_available - gf_bs_get_content - gf_bs_skip_bytes - gf_bs_seek - gf_bs_peek_bits - gf_bs_get_position - gf_bs_get_size - gf_bs_get_refreshed_size - gf_delete_file - ;gf_temp_file_new - -;thread.h exports - gf_th_new - gf_th_del - gf_th_run - gf_th_stop - gf_th_status - gf_th_set_priority - gf_th_id - gf_mx_new - gf_mx_del - gf_mx_v - gf_mx_p - gf_mx_try_lock - gf_sema_new - gf_sema_del - gf_sema_notify - gf_sema_wait - gf_sema_wait_for - -;net.h exports - gf_sk_new - gf_sk_del - gf_sk_reset - gf_sk_set_buffer_size - gf_sk_set_block_mode - gf_sk_get_handle - gf_sk_bind - gf_sk_connect - gf_sk_send - gf_sk_receive - gf_sk_listen - gf_sk_accept - gf_sk_server_mode - gf_sk_get_host_name - gf_sk_get_local_ip - gf_sk_get_local_info - gf_sk_get_remote_address - gf_sk_send_to - gf_sk_setup_multicast - gf_sk_is_multicast_address - gf_sk_send_wait - gf_sk_receive_wait - gf_net_get_ntp - gf_net_has_ipv6 - gf_net_is_ipv6 - - gf_url_is_local - gf_url_get_absolute_path - gf_url_concatenate - -;base_coding.h exports - gf_base64_encode - gf_base64_decode - gf_base16_encode - gf_base16_decode - -;token.h exports - gf_token_get - gf_token_get_line - gf_token_find - -;config.h exports - gf_cfg_new - gf_cfg_del - gf_cfg_get_key - gf_cfg_set_key - gf_cfg_get_section_count - gf_cfg_get_section_name - gf_cfg_get_key_count - gf_cfg_get_key_name - gf_cfg_insert_key - -;module.h exports - gf_modules_new - gf_modules_del - gf_modules_refresh - gf_modules_get_count - gf_modules_get_file_name - gf_modules_load_interface - gf_modules_load_interface_by_name - gf_modules_close_interface - gf_modules_get_option - gf_modules_set_option - gf_modules_get_config - -;utf.h exports - gf_utf8_wcstombs - gf_utf8_mbstowcs - gf_utf8_wcslen - gf_utf8_is_right_to_left - gf_utf8_reorder_bidi - -;download.h exports - gf_dm_sess_get_cache_name - gf_dm_sess_get_stats - gf_dm_sess_fetch_data - gf_dm_sess_last_error - -;xml.h exports - gf_xml_sax_new - gf_xml_sax_del - gf_xml_sax_init - gf_xml_sax_parse - gf_xml_sax_suspend - gf_xml_sax_parse_file - gf_xml_sax_get_line - gf_xml_sax_get_file_size - gf_xml_sax_get_file_pos - gf_xml_sax_peek_node - gf_xml_sax_binary_file - gf_xml_sax_get_error - gf_xml_get_root_type - gf_xml_sax_get_node_start_pos - gf_xml_sax_get_node_end_pos - gf_xml_dom_new - gf_xml_dom_del - gf_xml_dom_parse - gf_xml_dom_get_root - gf_xml_dom_get_error - gf_xml_dom_get_line - -;math.h exports - gf_invfix - gf_mulfix - gf_muldiv - gf_divfix - gf_cos - gf_sin - gf_tan - gf_atan2 - gf_sqrt - gf_ceil - gf_floor - gf_acos - gf_asin - - gf_angle_diff - gf_v2d_len - gf_v2d_from_polar - gf_rect_union - gf_rect_center - gf_rect_overlaps - gf_rect_equal - gf_rect_pixelize - gf_mx2d_add_matrix - gf_mx2d_pre_multiply - gf_mx2d_add_translation - gf_mx2d_add_rotation - gf_mx2d_add_scale - gf_mx2d_add_scale_at - gf_mx2d_add_skew - gf_mx2d_add_skew_x - gf_mx2d_add_skew_y - gf_mx2d_inverse - gf_mx2d_apply_coords - gf_mx2d_apply_point - gf_mx2d_apply_rect - -;exported for 3D tools - gf_vec_len - gf_vec_lensq - gf_vec_dot - gf_vec_norm - gf_vec_scale - gf_vec_cross - gf_quat_to_rotation - gf_quat_from_matrix - gf_quat_from_rotation - gf_quat_get_inv - gf_quat_multiply - gf_quat_rotate - gf_quat_from_axis_cos - gf_quat_slerp - gf_bbox_refresh - gf_bbox_from_rect - gf_rect_from_bbox - gf_bbox_grow_point - gf_bbox_union - gf_bbox_equal - gf_bbox_point_inside - gf_bbox_get_vertices - gf_mx_from_mx2d - gf_mx_equal - gf_mx_add_translation - gf_mx_add_scale - gf_mx_add_rotation - gf_mx_add_matrix - gf_mx_inverse - gf_mx_apply_vec - gf_mx_apply_rect - gf_mx_ortho - gf_mx_perspective - gf_mx_lookat - gf_mx_apply_bbox - gf_mx_add_matrix_4x4 - gf_mx_inverse_4x4 - gf_mx_apply_vec_4x4 - gf_mx_decompose - gf_mx_rotate_vector - gf_mx_rotation_matrix_from_vectors - gf_mx2d_from_mx - gf_mx_apply_plane - gf_mx_add_matrix_2d - gf_plane_get_distance - gf_plane_intersect_line - gf_closest_point_to_line - gf_plane_get_p_vertex_idx - gf_bbox_plane_relation - gf_mx_apply_ray - gf_ray - gf_ray_hit_box - gf_ray_hit_sphere - gf_ray_hit_triangle - gf_ray_hit_triangle_backcull - -;path2d.h exports - gf_path_new - gf_path_del - gf_path_reset - gf_path_close - gf_path_add_move_to - gf_path_add_move_to_vec - gf_path_add_line_to - gf_path_add_line_to_vec - gf_path_add_cubic_to - gf_path_add_cubic_to_vec - gf_path_add_quadratic_to - gf_path_add_quadratic_to_vec - gf_path_add_rect_center - gf_path_add_rect - gf_path_add_ellipse - gf_path_add_bezier - gf_path_add_arc_to - gf_path_add_svg_arc_to - gf_path_add_arc - gf_path_get_control_bounds - gf_path_get_bounds - gf_path_flatten - gf_path_get_flatten - gf_path_iterator_new - gf_path_iterator_del - gf_path_iterator_get_length - gf_path_iterator_get_transform - gf_polygone2d_get_convexity - gf_path_get_outline - gf_path_point_over - -;yuv.h exports - gf_cmx_init - gf_cmx_set - gf_cmx_set_all - gf_cmx_copy - gf_cmx_multiply - gf_cmx_apply - gf_cmx_apply_fixed - gf_stretch_bits - -;mpeg4_odf.h exports - gf_odf_slc_set_pref - gf_odf_get_bifs_config - gf_odf_get_text_config - gf_odf_get_ui_config - gf_odf_encode_ui_config - gf_odf_codec_new - gf_odf_codec_del - gf_odf_codec_add_com - gf_odf_codec_encode - gf_odf_codec_get_au - gf_odf_codec_set_au - gf_odf_codec_decode - gf_odf_codec_get_com - gf_odf_com_new - gf_odf_com_del - gf_odf_desc_new - gf_odf_desc_del - gf_odf_desc_read - gf_odf_desc_write - gf_odf_desc_size - gf_odf_desc_copy - gf_odf_desc_add_desc - gf_odf_desc_esd_new - gf_odf_desc_list_read - gf_odf_desc_list_write - gf_odf_desc_list_size - gf_odf_desc_list_del - gf_odf_stream_type_name - gf_odf_stream_type_by_name - gf_odf_qos_new - gf_odf_qos_del - gf_odf_qos_add_qualif - gf_oci_event_new - gf_oci_event_del - gf_oci_event_set_start_time - gf_oci_event_set_duration - gf_oci_event_add_desc - gf_oci_event_get_id - gf_oci_event_get_start_time - gf_oci_event_get_duration - gf_oci_event_get_desc_count - gf_oci_event_get_desc - gf_oci_event_rem_desc - gf_oci_codec_new - gf_oci_codec_del - gf_oci_codec_add_event - gf_oci_codec_encode - gf_oci_codec_decode - gf_oci_codec_get_event -; gf_odf_dump_au -; gf_odf_dump_com -; gf_odf_dump_desc -; gf_odf_dump_com_list -; gf_oci_dump_event -; gf_oci_dump_au -; gf_sl_packetize - gf_sl_depacketize - gf_odf_avc_cfg_new - gf_odf_avc_cfg_del - gf_odf_avc_cfg_read - gf_odf_avc_cfg_write - -;isomedia.h exports - gf_isom_sample_new - gf_isom_sample_del - gf_isom_last_error - gf_isom_probe_file - gf_isom_open - gf_isom_close - gf_isom_delete - gf_isom_get_mode - gf_isom_open_progressive - gf_isom_get_missing_bytes - gf_isom_is_fragmented - gf_isom_is_track_fragmented - gf_isom_refresh_fragmented - gf_isom_get_track_count - gf_isom_get_timescale - gf_isom_get_duration - gf_isom_get_creation_time - gf_isom_get_track_id - gf_isom_get_track_by_id - gf_isom_is_track_enabled - gf_isom_is_track_encrypted - gf_isom_get_track_duration - gf_isom_get_media_type - gf_isom_get_media_subtype - gf_isom_get_mpeg4_subtype - gf_isom_get_media_time - gf_isom_get_sample_description_count - gf_isom_get_sample_description_index - gf_isom_is_self_contained - gf_isom_get_media_duration - gf_isom_get_media_timescale - gf_isom_get_max_chunk_duration - gf_isom_get_handler_name - gf_isom_get_media_language - gf_isom_check_data_reference - gf_isom_get_data_reference - gf_isom_get_sample_count - gf_isom_set_sample_padding - gf_isom_get_sample - gf_isom_get_sample_info - gf_isom_get_sample_for_media_time - gf_isom_get_sample_for_movie_time - gf_isom_get_sample_dts - gf_isom_get_edit_segment_count - gf_isom_get_edit_segment - gf_isom_get_copyright_count - gf_isom_get_copyright - gf_isom_get_watermark - gf_isom_has_sync_points - gf_isom_has_time_offset - gf_isom_get_sync_point_count - gf_isom_has_root_od - gf_isom_get_root_od - gf_isom_is_track_in_root_od - gf_isom_get_esd - gf_isom_get_decoder_config - gf_isom_get_reference_count - gf_isom_get_reference - gf_isom_get_filename - gf_isom_get_brand_info - gf_isom_get_alternate_brand - gf_isom_has_padding_bits - gf_isom_get_visual_info - gf_isom_get_audio_info - gf_isom_get_chapter_count - gf_isom_get_chapter - gf_isom_get_user_data_count - gf_isom_get_user_data - gf_isom_get_generic_sample_description - gf_isom_get_fragment_defaults - gf_isom_get_sample_fragment_count - gf_isom_get_sample_fragment_size - gf_isom_sdp_get - gf_isom_sdp_track_get - gf_isom_set_default_sync_track -; gf_isom_dump -; gf_isom_dump_hint_sample - gf_isom_3gp_config_get - gf_isom_text_set_streaming_mode -; gf_isom_text_dump - gf_isom_get_track_layout_info - gf_isom_get_pl_indication - gf_isom_is_media_encrypted - gf_isom_get_ismacryp_info - gf_isom_is_ismacryp_media - gf_isom_ismacryp_delete_sample - gf_isom_get_ismacryp_sample - gf_isom_avc_config_get - gf_isom_3gp_config_get - gf_isom_get_meta_item_count - gf_isom_get_meta_item_by_id - gf_isom_get_meta_item_info - gf_isom_get_meta_type - gf_isom_has_meta_xml - gf_isom_has_movie - gf_isom_is_single_av - gf_isom_guess_specification - gf_isom_delete_text_sample - gf_isom_has_sync_shadows - gf_isom_apple_get_tag - gf_isom_get_omadrm_info - gf_isom_is_omadrm_media - gf_isom_get_pixel_aspect_ratio - -;NON-READ-ONLY exports -; gf_isom_set_timescale -; gf_isom_new_track -; gf_isom_remove_track -; gf_isom_set_track_enabled -; gf_isom_set_track_id -; gf_isom_add_sample -; gf_isom_add_sample_shadow -; gf_isom_append_sample_data -; gf_isom_add_sample_reference -; gf_isom_set_last_sample_duration -; gf_isom_set_track_reference -; gf_isom_remove_track_reference -; gf_isom_update_sample -; gf_isom_update_sample_reference -; gf_isom_remove_sample -; gf_isom_set_final_name -; gf_isom_set_storage_mode -; gf_isom_get_storage_mode -; gf_isom_set_interleave_time -; gf_isom_get_interleave_time -; gf_isom_set_copyright -; gf_isom_remove_copyright -; gf_isom_set_watermark -; gf_isom_set_edit_segment -; gf_isom_modify_edit_segment -; gf_isom_append_edit_segment -; gf_isom_remove_edit_segments -; gf_isom_remove_edit_segment -; gf_isom_set_media_language -; gf_isom_add_user_data -; gf_isom_remove_user_data -; gf_isom_remove_user_data_item -; gf_isom_use_compact_size -; gf_isom_set_brand_info -; gf_isom_modify_alternate_brand -; gf_isom_set_sample_padding_bits -; gf_isom_set_visual_info -; gf_isom_set_track_layout_info -; gf_isom_set_audio_info -; gf_isom_add_sample_fragment -; gf_isom_remove_sample_fragment -; gf_isom_set_cts_packing -; gf_isom_modify_cts_offset -; gf_isom_remove_cts_info -; gf_isom_set_track_name -; gf_isom_get_track_name -; gf_isom_set_pl_indication -; gf_isom_set_root_od_id -; gf_isom_set_root_od_url -; gf_isom_remove_root_od -; gf_isom_add_desc_to_root_od -; gf_isom_add_track_to_root_od -; gf_isom_remove_track_from_root_od -; gf_isom_new_mpeg4_description -; gf_isom_change_mpeg4_description -; gf_isom_add_desc_to_description -; gf_isom_new_generic_sample_description -; gf_isom_change_generic_sample_description -; gf_isom_remove_sample_description -; gf_isom_clone_sample_description -; gf_isom_clone_track -; gf_isom_clone_pl_indications -; gf_isom_is_same_sample_description -; gf_isom_add_chapter -; gf_isom_remove_chapter -; gf_isom_setup_track_fragment -; gf_isom_finalize_for_fragment -; gf_isom_start_fragment -; gf_isom_set_fragment_option -; gf_isom_fragment_add_sample -; gf_isom_fragment_append_data -; gf_isom_remove_sync_shadows -; gf_isom_set_sync_shadow -; gf_isom_set_track_group -; gf_isom_set_track_priority_in_group -; gf_isom_set_max_samples_per_chunk -; gf_isom_set_extraction_slc -; gf_isom_get_extraction_slc -; gf_isom_get_track_group -; gf_isom_get_track_priority_in_group -; gf_isom_store_movie_config -; gf_isom_load_movie_config -; gf_isom_make_interleave -; gf_isom_setup_hint_track -; gf_isom_new_hint_description -; gf_isom_begin_hint_sample -; gf_isom_end_hint_sample -; gf_isom_hint_blank_data -; gf_isom_hint_direct_data -; gf_isom_hint_sample_data -; gf_isom_hint_sample_description_data -; gf_isom_rtp_packet_begin -; gf_isom_rtp_packet_set_flags -; gf_isom_rtp_packet_set_offset -; gf_isom_rtp_set_timescale -; gf_isom_rtp_set_time_offset -; gf_isom_rtp_set_time_sequence_offset -; gf_isom_sdp_add_track_line -; gf_isom_sdp_clean_track -; gf_isom_sdp_add_line -; gf_isom_sdp_clean -; gf_isom_3gp_config_new -; gf_isom_3gp_config_update -; gf_isom_new_text_description -; gf_isom_new_text_sample -; gf_isom_text_reset -; gf_isom_text_add_text -; gf_isom_text_add_style -; gf_isom_text_add_highlight -; gf_isom_text_set_highlight_color -; gf_isom_text_add_karaoke -; gf_isom_text_set_karaoke_segment -; gf_isom_text_set_scroll_delay -; gf_isom_text_add_hyperlink -; gf_isom_text_set_box -; gf_isom_text_add_blink -; gf_isom_text_set_wrap -; gf_isom_text_to_sample -; gf_isom_remove_ismacryp_protection -; gf_isom_set_ismacryp_protection -; gf_isom_change_ismacryp_protection -; gf_isom_dump_ismacryp_protection -; gf_isom_dump_ismacryp_sample -; gf_isom_avc_config_new -; gf_isom_avc_config_update -; gf_isom_3gp_config_new -; gf_isom_3gp_config_update -; gf_isom_set_media_timescale -; gf_isom_estimate_size -; gf_isom_set_meta_type -; gf_isom_add_meta_item -; gf_isom_remove_meta_item -; gf_isom_set_meta_primary_item -; gf_isom_set_meta_xml -; gf_isom_remove_meta_xml -; gf_isom_extract_meta_xml -; gf_isom_extract_meta_item -; gf_isom_apple_set_tag - -;end GPAC_READ_ONLY - -;isomedia_dev.h exports - gf_isom_parse_texte_sample - -;plugin_network.h exports - gf_term_on_message - gf_term_on_connect - gf_term_on_disconnect - gf_term_on_command - gf_term_on_sl_packet - gf_term_get_service_url - gf_term_get_service_interface - gf_term_register_mime_type - gf_term_check_extension - gf_term_download_new - gf_term_download_del - gf_term_download_update_stats - gf_term_add_media - gf_term_scene_update - gf_term_process_step - -;ietf.h exports - gf_rtsp_nc_to_string - gf_rtsp_range_parse - gf_rtsp_range_new - gf_rtsp_range_del - gf_rtsp_transport_clone - gf_rtsp_transport_del - gf_rtsp_command_new - gf_rtsp_command_del - gf_rtsp_command_reset - gf_rtsp_response_new - gf_rtsp_response_del - gf_rtsp_response_reset - gf_rtsp_session_new - gf_rtsp_session_del - gf_rtsp_set_mobile_ip - gf_rtsp_set_buffer_size - gf_rtsp_session_reset - gf_rtsp_is_my_session - gf_rtsp_get_server_name - gf_rtsp_get_service_name - gf_rtsp_get_response - gf_rtsp_get_session_state - gf_rtsp_get_last_request - gf_rtsp_reset_aggregation - gf_rtsp_send_command - gf_rtsp_set_interleave_callback - gf_rtsp_session_read - gf_rtsp_register_interleave - gf_rtsp_unregister_interleave - gf_rtsp_session_new_server - gf_rtsp_get_command - gf_rtsp_load_service_name - gf_rtsp_send_response - gf_rtsp_get_session_ip - gf_rtsp_get_next_interleave_id - gf_rtsp_get_remote_address - gf_rtsp_get_session_port - gf_rtp_new - gf_rtp_del - gf_rtp_setup_transport - gf_rtp_set_ports - gf_rtp_setup_payload - gf_rtp_enable_nat_keepalive - gf_rtp_initialize - gf_rtp_set_info_rtp - gf_rtp_get_current_time - gf_rtp_reset_buffers - gf_rtp_read_rtp - gf_rtp_read_rtcp - gf_rtp_decode_rtp - gf_rtp_decode_rtcp - gf_rtp_send_rtcp_report - gf_rtp_send_bye - gf_rtp_send_packet - gf_rtp_set_info_rtcp - gf_rtp_is_unicast - gf_rtp_is_interleaved - gf_rtp_get_clockrate - gf_rtp_is_active - gf_rtp_get_low_interleave_id - gf_rtp_get_hight_interleave_id - gf_rtp_get_transport - gf_rtp_get_local_ssrc - gf_rtp_get_loss - gf_rtp_get_tcp_bytes_sent - gf_rtp_get_ports - gf_sdp_info_new - gf_sdp_info_del - gf_sdp_info_reset - gf_sdp_info_parse - gf_sdp_info_check - gf_sdp_info_write - gf_sdp_media_new - gf_sdp_media_del - gf_sdp_conn_new - gf_sdp_conn_del - gf_sdp_fmtp_new - gf_sdp_fmtp_del - gf_rtp_builder_new - gf_rtp_builder_del - gf_rtp_builder_init - gf_rtp_builder_process - gf_rtp_builder_format_sdp - gf_rtp_depacketizer_new - gf_rtp_depacketizer_del - gf_rtp_depacketizer_reset - gf_rtp_depacketizer_process - gf_rtp_depacketizer_get_slconfig - -;avilib exports -; AVI_write_frame -; AVI_close -; AVI_open_output_file -; AVI_set_video - -;media.h exports -; gf_hinter_track_new -; gf_hinter_track_del -; gf_hinter_track_process -; gf_hinter_track_finalize -; gf_hinter_finalize -; gf_hinter_track_get_bandwidth -; gf_hinter_track_get_flags -; gf_hinter_track_get_payload_name -; gf_hinter_can_embbed_data -; gf_media_make_isma -; gf_media_make_3gpp - gf_media_map_esd - gf_media_get_file_hash -; gf_media_import -; gf_media_export -; gf_media_fragment_file -; gf_media_import_chapters - -;mcrypt exports - gf_crypt_open - gf_crypt_close - gf_crypt_init - gf_crypt_decrypt - gf_crypt_encrypt - gf_crypt_set_state - -;parsers_av.h exports - gf_m4v_parser_new - gf_m4v_parser_del - gf_m4v_parse_config - gf_m4v_parse_frame - gf_m4v_get_object_start - gf_m4v_is_valid_object_type - gf_m4v_get_profile_name - gf_m4v_get_config - gf_m4v_rewrite_pl - gf_mp3_num_channels - gf_mp3_sampling_rate - gf_mp3_window_size - gf_mp3_object_type_indication - gf_mp3_layer - gf_mp3_version - gf_mp3_version_name - gf_mp3_frame_size - gf_mp3_get_next_header - gf_mp3_get_next_header_mem - gf_m4a_get_config - gf_m4a_object_type_name - gf_m4a_get_profile_name - gf_m4a_write_config - gf_vorbis_parse_header - gf_vorbis_check_frame - gf_img_parse - gf_img_jpeg_dec - gf_img_png_dec - gf_img_png_enc - gf_ac3_parser_bs - -;ismacryp.h exports -; gf_ismacryp_crypt_file -; gf_ismacryp_decrypt_file -; gf_ismacryp_encrypt_track -; gf_ismacryp_decrypt_track - gf_ismacryp_gpac_get_info - gf_ismacryp_mpeg4ip_get_info - -;scene_manager.h exports - gf_sm_new - gf_sm_del - gf_sm_stream_new - gf_sm_stream_del - gf_sm_stream_au_new - gf_sm_make_random_access - gf_sm_load_init - gf_sm_load_done - gf_sm_load_run - gf_sm_load_string - gf_sm_import_bifs_subtitle -; gf_sm_dump -; gf_sm_encode_to_file -; gf_sm_dumper_new -; gf_sm_dumper_del -; gf_sm_dump_command_list -; gf_sm_dump_graph -; gf_sm_stats_new -; gf_sm_stats_del -; gf_sm_stats_reset -; gf_sm_stats_get -; gf_sm_stats_for_graph -; gf_sm_stats_for_scene -; gf_sm_stats_for_command - -;bifsengine exports -; gf_beng_init -; gf_beng_get_stream_config -; gf_beng_encode_context -; gf_beng_encode_from_file -; gf_beng_encode_from_string -; gf_beng_save_context -; gf_beng_aggregate_context -; gf_beng_terminate - -;bifs.h exports - gf_bifs_decoder_new - gf_bifs_decoder_del - gf_bifs_decoder_ignore_size_info - gf_bifs_decoder_configure_stream - gf_bifs_decoder_remove_stream - gf_bifs_decode_au - gf_bifs_decode_command_list -; gf_bifs_encoder_new -; gf_bifs_encoder_del -; gf_bifs_encoder_new_stream -; gf_bifs_encode_au -; gf_bifs_encoder_get_config -; gf_bifs_encoder_get_version -; gf_bifs_encoder_get_rap -; gf_bifs_encoder_set_trace -; gf_bifs_get_aq_info - - -;scenegraph.h and scenegraph_vrml.h exports - gf_node_list_add_child - gf_node_list_insert_child - gf_node_list_del_child - gf_node_list_find_child - gf_node_list_get_child - gf_node_list_get_count - gf_node_get_tag - gf_node_set_id - gf_node_get_name - gf_node_get_id - gf_node_get_private - gf_node_set_private - gf_node_set_callback_function - gf_node_register - gf_node_unregister - gf_node_replace - gf_node_unregister_children - gf_node_insert_child - gf_node_remove_child - gf_node_replace_child - gf_node_event_out - gf_node_event_out_str - gf_node_traverse - gf_node_traverse_children - gf_node_get_parent_count - gf_node_get_parent - gf_node_get_class_name - gf_node_dirty_set - gf_node_dirty_clear - gf_node_dirty_get - gf_node_dirty_reset - gf_node_get_field - gf_node_get_field_by_name - gf_node_get_graph - gf_node_init - gf_node_get_scene_time - gf_node_list_get_child - gf_node_list_get_count - gf_node_list_add_child - gf_node_list_del_child - gf_node_list_insert_child - gf_sg_new - gf_sg_new_subscene - gf_sg_set_scene_time_callback - gf_sg_set_node_callback - gf_sg_set_proto_loader - gf_sg_del - gf_sg_set_private - gf_sg_get_private - gf_sg_set_scene_size_info - gf_sg_use_pixel_metrics - gf_sg_get_scene_size_info - gf_sg_reset - gf_sg_get_root_node - gf_sg_set_root_node - gf_sg_find_node - gf_sg_find_node_by_name - gf_node_changed - gf_node_new - gf_node_clone - gf_node_allow_cyclic_traverse - gf_sg_vrml_get_event_type_name - gf_sg_vrml_get_field_type_by_name - gf_sg_vrml_field_pointer_new - gf_sg_vrml_field_pointer_del - gf_sg_vrml_is_sf_field - gf_sg_vrml_get_sf_type - gf_sg_vrml_mf_insert - gf_sg_vrml_mf_append - gf_sg_vrml_mf_remove - gf_sg_vrml_mf_alloc - gf_sg_vrml_mf_get_item - gf_sg_vrml_mf_reset - gf_sg_vrml_field_copy - gf_sg_vrml_field_equal - gf_sg_route_new - gf_sg_route_del - gf_sg_route_del_by_id - gf_sg_route_find - gf_sg_route_find_by_name - gf_sg_route_set_id - gf_sg_route_get_id - gf_sg_route_set_name - gf_sg_route_get_name - gf_sg_activate_routes - gf_sg_proto_new - gf_sg_proto_del - gf_sg_proto_set_in_graph - gf_sg_proto_get_graph - gf_sg_proto_set_private - gf_sg_proto_get_private - gf_sg_proto_get_extern_url - gf_sg_proto_add_node_code - gf_sg_proto_get_field_count - gf_sg_proto_field_find_by_name - gf_sg_proto_field_find - gf_sg_proto_field_new - gf_sg_proto_field_set_ised - gf_sg_proto_field_set_private - gf_sg_proto_field_get_private - gf_sg_proto_field_get_field - gf_sg_proto_create_instance - gf_sg_proto_load_code - gf_sg_find_proto - gf_sg_delete_all_protos - gf_node_get_proto - gf_sg_proto_get_id - gf_sg_proto_get_class_name - gf_sg_proto_field_is_sftime_offset - gf_sg_proto_instance_set_ised - gf_sg_script_field_new - gf_sg_script_field_get_info - gf_sg_script_load - gf_sg_script_event_in - gf_sg_has_scripting - gf_bifs_proto_field_set_aq_info - gf_node_get_num_fields_in_mode - gf_sg_command_new - gf_sg_command_del - gf_sg_command_apply - gf_sg_command_apply_list - gf_sg_command_field_new - gf_sg_command_clone - gf_sg_get_next_available_node_id - gf_sg_get_max_node_id - gf_sg_get_next_available_route_id - gf_sg_set_max_defined_route_id - gf_sg_get_next_available_proto_id - gf_sg_sfrotation_interpolate - gf_node_get_field_count - gf_node_mpeg4_type_by_class_name - gf_node_x3d_type_by_class_name - gf_sg_mfurl_del - gf_sg_sfcolor_to_rgba - -;terminal.h exports - gf_term_new - gf_term_del - gf_term_connect - gf_term_disconnect - gf_term_navigate_to - gf_term_play_from_time - gf_term_set_option - gf_term_get_option - gf_term_get_framerate - gf_term_get_time_in_ms - gf_term_get_viewpoint - gf_term_set_viewpoint - gf_term_get_root_object - gf_term_get_object_count - gf_term_get_object - gf_term_object_subscene_type - gf_term_select_object - gf_term_get_object_info - gf_term_get_download_info - gf_term_get_channel_net_info - gf_term_get_world_info -; gf_term_dump_scene - gf_term_set_size - gf_term_user_event - gf_term_mouse_input - gf_term_keyboard_input - gf_term_string_input - gf_term_connect_from_time - gf_term_add_object - gf_term_is_supported_url - gf_term_attach_service - gf_term_set_simulation_frame_rate - gf_term_get_simulation_frame_rate - gf_term_get_service_interface - gf_term_get_text_selection - gf_term_paste_text - gf_term_get_service_info - gf_term_get_url - -;renderer.h exports - gf_sc_new - gf_sc_del - gf_sc_set_fps - gf_sc_set_scene - gf_sc_draw_frame - gf_sc_on_node_init - gf_sc_invalidate - gf_sc_get_clock - gf_sc_lock - gf_sc_user_event - gf_sc_map_point - gf_sc_set_option - gf_sc_get_option - gf_sc_get_fps - gf_sc_get_screen_buffer - gf_sc_release_screen_buffer - gf_sc_simulation_tick - gf_sc_reset_graphics - gf_sc_pick_node - gf_sc_get_viewpoint - gf_sc_set_viewpoint - gf_sc_set_size - gf_sc_register_extra_graph - gf_sc_get_compositor - gf_sc_svg_convert_length_to_display - -;render_dev.h exports - gf_sc_register_time_node - gf_sc_unregister_time_node - gf_sc_texture_setup - gf_sc_texture_destroy - gf_sc_texture_get_handler - gf_sc_texture_check_url_change - gf_sc_texture_play - gf_sc_texture_play_from_to - gf_sc_texture_stop - gf_sc_texture_restart - gf_sc_texture_update_frame - gf_sc_texture_release_stream - gf_sc_audio_register - gf_sc_audio_unregister - gf_sc_audio_setup - gf_sc_audio_open - gf_sc_audio_stop - gf_sc_audio_restart - -;terminal_dev exports - gf_inline_new - gf_inline_del - gf_inline_get_time - gf_inline_attach_to_compositor - gf_inline_find_odm - gf_inline_set_duration - gf_inline_setup_object - gf_inline_default_scene_viewpoint - gf_inline_register_extra_graph - gf_inline_force_scene_size - gf_inline_get_proto_lib - gf_inline_process_anchor - gf_inline_disconnect - gf_odm_new - gf_odm_setup_object - gf_odm_disconnect - gf_odm_setup_es - gf_odm_remove_es - gf_term_node_callback - gf_term_message - gf_mo_get_loop - gf_mo_get_duration - gf_mo_set_speed - gf_mo_set_flag - gf_mo_get_flags - gf_mo_has_audio - gf_mo_get_last_frame_time - gf_clock_time - - -;laser.h exports - gf_laser_decoder_new - gf_laser_decoder_del - gf_laser_decoder_set_clock - gf_laser_decoder_configure_stream - gf_laser_decoder_remove_stream - gf_laser_decode_au - gf_laser_decode_command_list -; gf_laser_encoder_new -; gf_laser_encoder_del -; gf_laser_encoder_new_stream -; gf_laser_encode_au -; gf_laser_encoder_get_config -; gf_laser_encoder_get_rap -; gf_laser_set_trace - -;SVG exports - gf_svg_create_attribute_value - gf_svg_delete_attribute_value - gf_svg_attributes_equal - gf_svg_attributes_copy - gf_svg_attributes_add - gf_svg_attributes_interpolate - gf_svg_attributes_muladd - gf_svg_parse_attribute - gf_svg_parse_style - gf_svg_properties_init_pointers - gf_svg_properties_reset_pointers - gf_svg_apply_animations - gf_svg_path_build - - gf_svg_flatten_attributes - gf_svg_apply_inheritance - - gf_smil_timing_init_runtime_info - gf_smil_timing_get_normalized_simple_time - gf_smil_timing_is_active - gf_smil_timing_insert_clock - gf_smil_set_media_duration - gf_smil_notify_timed_elements - - gf_node_get_attribute_by_tag - gf_node_store_embedded_data - gf_node_register_iri - gf_node_unregister_iri - - gf_dom_listener_build - gf_dom_listener_add - gf_dom_listener_del - gf_dom_listener_count - gf_dom_listener_get - gf_dom_event_fire - gf_dom_event_type_by_name - gf_dom_event_get_name diff --git a/src/mcrypt/cbc.c b/src/mcrypt/cbc.c index abb30cb..7a32c81 100644 --- a/src/mcrypt/cbc.c +++ b/src/mcrypt/cbc.c @@ -19,7 +19,7 @@ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) typedef struct cbc_buf { u32 *previous_ciphertext; @@ -38,8 +38,8 @@ static GF_Err _init_mcrypt( CBC_BUFFER* buf,void *key, int lenofkey, void *IV, i buf->blocksize = size; - buf->previous_ciphertext = malloc( size); - buf->previous_cipher = malloc( size); + buf->previous_ciphertext = gf_malloc( size); + buf->previous_cipher = gf_malloc( size); if (buf->previous_ciphertext==NULL || buf->previous_cipher==NULL) goto freeall; @@ -53,8 +53,8 @@ static GF_Err _init_mcrypt( CBC_BUFFER* buf,void *key, int lenofkey, void *IV, i return GF_OK; freeall: - if (buf->previous_ciphertext) free(buf->previous_ciphertext); - if (buf->previous_cipher) free(buf->previous_cipher); + if (buf->previous_ciphertext) gf_free(buf->previous_ciphertext); + if (buf->previous_cipher) gf_free(buf->previous_cipher); return GF_OUT_OF_MEM; } @@ -83,8 +83,8 @@ static GF_Err _mcrypt_get_state( CBC_BUFFER* buf, void *IV, int *size) static void _end_mcrypt( CBC_BUFFER* buf) { - free(buf->previous_ciphertext); - free(buf->previous_cipher); + gf_free(buf->previous_ciphertext); + gf_free(buf->previous_cipher); } static GF_Err _mcrypt( CBC_BUFFER* buf, void *plaintext, int len, int blocksize, void* akey, void (*func)(void*,void*), void (*func2)(void*,void*)) @@ -164,4 +164,4 @@ void gf_crypt_register_cbc(GF_Crypt *td) td->mode_version = 20010801; } -#endif +#endif /*!defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/cfb.c b/src/mcrypt/cfb.c index 0853b72..fd4c228 100644 --- a/src/mcrypt/cfb.c +++ b/src/mcrypt/cfb.c @@ -19,7 +19,7 @@ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) typedef struct cfb_buf { u8* s_register; @@ -36,10 +36,10 @@ static GF_Err _init_mcrypt( CFB_BUFFER* buf, void *key, int lenofkey, void *IV, buf->blocksize = size; /* For cfb */ - buf->s_register=malloc( size); + buf->s_register=gf_malloc( size); if (buf->s_register==NULL) goto freeall; - buf->enc_s_register=malloc( size); + buf->enc_s_register=gf_malloc( size); if (buf->enc_s_register==NULL) goto freeall; if (IV!=NULL) { @@ -51,8 +51,8 @@ static GF_Err _init_mcrypt( CFB_BUFFER* buf, void *key, int lenofkey, void *IV, return GF_OK; freeall: - if (buf->s_register) free(buf->s_register); - if (buf->enc_s_register) free(buf->enc_s_register); + if (buf->s_register) gf_free(buf->s_register); + if (buf->enc_s_register) gf_free(buf->enc_s_register); return GF_OUT_OF_MEM; } @@ -80,8 +80,8 @@ static GF_Err _mcrypt_get_state( CFB_BUFFER* buf, u8 *IV, int *size) static void _end_mcrypt( CFB_BUFFER* buf) { - free(buf->s_register); - free(buf->enc_s_register); + gf_free(buf->s_register); + gf_free(buf->enc_s_register); } static GF_Err _mcrypt( CFB_BUFFER* buf, void *plaintext, int len, int blocksize, void* akey, void (*func)(void*,void*), void (*func2)(void*,void*)) @@ -156,5 +156,5 @@ void gf_crypt_register_cfb(GF_Crypt *td) td->mode_version = 20020310; } -#endif +#endif /* !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) */ diff --git a/src/mcrypt/ctr.c b/src/mcrypt/ctr.c index 75de12c..467db0f 100644 --- a/src/mcrypt/ctr.c +++ b/src/mcrypt/ctr.c @@ -19,6 +19,8 @@ #include <gpac/internal/crypt_dev.h> +#if !defined(GPAC_DISABLE_MCRYPT) + typedef struct ctr_buf { u8* enc_counter; u8* c_counter; @@ -59,10 +61,10 @@ GF_Err _init_mcrypt( void *buf, void *key, int lenofkey, void *IV, int size) ((CTR_BUFFER* )buf)->c_counter_pos = 0; ((CTR_BUFFER* )buf)->blocksize = size; - ((CTR_BUFFER* )buf)->c_counter = (u8 *)malloc(size); + ((CTR_BUFFER* )buf)->c_counter = (u8 *)gf_malloc(size); if (((CTR_BUFFER* )buf)->c_counter==NULL) goto freeall; - ((CTR_BUFFER* )buf)->enc_counter = (u8 *)malloc(size); + ((CTR_BUFFER* )buf)->enc_counter = (u8 *)gf_malloc(size); if (((CTR_BUFFER* )buf)->enc_counter==NULL) goto freeall; if (IV!=NULL) { @@ -74,8 +76,8 @@ GF_Err _init_mcrypt( void *buf, void *key, int lenofkey, void *IV, int size) return GF_OK; freeall: - free(((CTR_BUFFER* )buf)->c_counter); - free(((CTR_BUFFER* )buf)->enc_counter); + gf_free(((CTR_BUFFER* )buf)->c_counter); + gf_free(((CTR_BUFFER* )buf)->enc_counter); return GF_OUT_OF_MEM; } @@ -105,8 +107,8 @@ GF_Err _mcrypt_get_state(void *buf, void *IV, int *size) void _end_mcrypt(void *buf) { - free(((CTR_BUFFER* )buf)->c_counter); - free(((CTR_BUFFER* )buf)->enc_counter); + gf_free(((CTR_BUFFER* )buf)->c_counter); + gf_free(((CTR_BUFFER* )buf)->enc_counter); } static GFINLINE @@ -232,3 +234,4 @@ void gf_crypt_register_ctr(GF_Crypt *td) td->mode_size = sizeof(CTR_BUFFER); td->mode_version = 20020307; } +#endif /*!defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/des.c b/src/mcrypt/des.c index c53277c..ea65564 100644 --- a/src/mcrypt/des.c +++ b/src/mcrypt/des.c @@ -5,7 +5,7 @@ * Modified for additional speed - 6 December 1988 Phil Karn * Modified for parameterized key schedules - Jan 1991 Phil Karn * Callers now allocate a key schedule as follows: - * kn = (char (*)[8])malloc(sizeof(char) * 8 * 16); + * kn = (char (*)[8])gf_malloc(sizeof(char) * 8 * 16); * or * char kn[16][8]; */ @@ -14,11 +14,11 @@ * All modifications are placed under the license of libmcrypt. */ -/* $Id: des.c,v 1.1.1.1 2005/07/13 14:36:35 jeanlf Exp $ */ +/* $Id: des.c,v 1.3 2010-02-23 16:24:20 jeanlf Exp $ */ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) typedef struct des_key { char kn[16][8]; @@ -577,4 +577,4 @@ void gf_crypt_register_des(GF_Crypt *td) td->algo_size = sizeof(DES_KEY); } -#endif +#endif /*!defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/ecb.c b/src/mcrypt/ecb.c index 6700837..68c888e 100644 --- a/src/mcrypt/ecb.c +++ b/src/mcrypt/ecb.c @@ -19,7 +19,7 @@ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) static GF_Err _init_mcrypt( void* ign, void *key, int lenofkey, void *IV, int size) { @@ -81,5 +81,4 @@ void gf_crypt_register_ecb(GF_Crypt *td) td->mode_version = 20010801; } -#endif - +#endif /*!defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) */ diff --git a/src/mcrypt/g_crypt.c b/src/mcrypt/g_crypt.c index 64ea5a6..a7ef71b 100644 --- a/src/mcrypt/g_crypt.c +++ b/src/mcrypt/g_crypt.c @@ -26,6 +26,7 @@ #include <gpac/internal/crypt_dev.h> +#if !defined(GPAC_DISABLE_MCRYPT) static Bool gf_crypt_assign_algo(GF_Crypt *td, const char *algorithm) { @@ -63,23 +64,23 @@ static GF_Crypt *gf_crypt_open_intern(const char *algorithm, const char *mode, B if (algorithm && !gf_crypt_assign_algo(td, algorithm)) { - free(td); + gf_free(td); return NULL; } if (mode && !gf_crypt_assign_mode(td, mode)) { - free(td); + gf_free(td); return NULL; } if (is_check) return td; if (td->is_block_algo != td->is_block_algo_mode) { - free(td); + gf_free(td); return NULL; } if (!td->_mcrypt || !td->_mdecrypt || !td->_mcrypt_set_state || !td->a_decrypt || !td->a_encrypt || !td->a_set_key) { - free(td); + gf_free(td); return NULL; } return td; @@ -88,16 +89,16 @@ static GF_Crypt *gf_crypt_open_intern(const char *algorithm, const char *mode, B static void internal_end_mcrypt(GF_Crypt *td) { if (!td || !td->keyword_given) return; - free(td->keyword_given); + gf_free(td->keyword_given); td->keyword_given = NULL; if (td->akey) { - free(td->akey); + gf_free(td->akey); td->akey = NULL; } if (td->abuf) { td->_end_mcrypt(td->abuf); - free(td->abuf); + gf_free(td->abuf); td->abuf = NULL; } } @@ -113,7 +114,7 @@ GF_EXPORT void gf_crypt_close(GF_Crypt *td) { internal_end_mcrypt(td); - free(td); + gf_free(td); } GF_Err gf_crypt_set_key(GF_Crypt *td, void *key, u32 keysize, const void *IV) @@ -213,29 +214,29 @@ GF_Err gf_crypt_init(GF_Crypt *td, void *key, u32 lenofkey, const void *IV) key_size = lenofkey; } - td->keyword_given = (char*)malloc(sizeof(char)*gf_crypt_get_key_size(td)); + td->keyword_given = (char*)gf_malloc(sizeof(char)*gf_crypt_get_key_size(td)); if (td->keyword_given==NULL) return GF_OUT_OF_MEM; memmove(td->keyword_given, key, lenofkey); - td->akey = (char*)malloc(sizeof(char)*td->algo_size); + td->akey = (char*)gf_malloc(sizeof(char)*td->algo_size); if (td->akey==NULL) { - free(td->keyword_given); + gf_free(td->keyword_given); return GF_OUT_OF_MEM; } if (td->mode_size > 0) { - td->abuf = (char*)malloc(sizeof(char)*td->mode_size); + td->abuf = (char*)gf_malloc(sizeof(char)*td->mode_size); if (td->abuf==NULL) { - free(td->keyword_given); - free(td->akey); + gf_free(td->keyword_given); + gf_free(td->akey); return GF_OUT_OF_MEM; } } e = td->_init_mcrypt(td->abuf, (void *) key, key_size, (void *) IV, gf_crypt_get_block_size(td)); if (e!=GF_OK) { - free(td->keyword_given); - free(td->akey); - free(td->abuf); + gf_free(td->keyword_given); + gf_free(td->akey); + gf_free(td->abuf); return e; } @@ -330,3 +331,4 @@ u32 gf_crypt_str_get_algo_supported_key_sizes(const char *algorithm, int *keys) return ret; } +#endif /*!defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/ncfb.c b/src/mcrypt/ncfb.c index 436b80c..1e3f48a 100644 --- a/src/mcrypt/ncfb.c +++ b/src/mcrypt/ncfb.c @@ -19,7 +19,7 @@ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) typedef struct ncfb_buf { u8* enc_s_register; @@ -38,10 +38,10 @@ static GF_Err _init_mcrypt( nCFB_BUFFER* buf, void *key, int lenofkey, void *IV, buf->blocksize = size; /* For cfb */ - buf->enc_s_register=malloc( size); + buf->enc_s_register=gf_malloc( size); if (buf->enc_s_register==NULL) goto freeall; - buf->s_register=malloc( size); + buf->s_register=gf_malloc( size); if (buf->s_register==NULL) goto freeall; if (IV!=NULL) { @@ -56,8 +56,8 @@ static GF_Err _init_mcrypt( nCFB_BUFFER* buf, void *key, int lenofkey, void *IV, return GF_OK; freeall: - if (buf->enc_s_register) free(buf->enc_s_register); - if (buf->s_register) free(buf->s_register); + if (buf->enc_s_register) gf_free(buf->enc_s_register); + if (buf->s_register) gf_free(buf->s_register); return GF_BAD_PARAM; } @@ -85,8 +85,8 @@ static GF_Err _mcrypt_get_state( nCFB_BUFFER* buf, u8 *IV, int *size) } static void _end_mcrypt( nCFB_BUFFER* buf) { - free(buf->enc_s_register); - free(buf->s_register); + gf_free(buf->enc_s_register); + gf_free(buf->s_register); } GFINLINE static @@ -317,5 +317,4 @@ void gf_crypt_register_ncfb(GF_Crypt *td) td->mode_version = 20020307; } -#endif - +#endif /*!defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/nofb.c b/src/mcrypt/nofb.c index 2c3dc1a..1a04930 100644 --- a/src/mcrypt/nofb.c +++ b/src/mcrypt/nofb.c @@ -19,7 +19,7 @@ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) typedef struct ncfb_buf { u8* enc_s_register; @@ -37,10 +37,10 @@ static GF_Err _init_mcrypt( nOFB_BUFFER* buf, void *key, int lenofkey, void *IV, buf->blocksize = size; /* For ofb */ - buf->enc_s_register=malloc( size); + buf->enc_s_register=gf_malloc( size); if (buf->enc_s_register==NULL) goto freeall; - buf->s_register=malloc( size); + buf->s_register=gf_malloc( size); if (buf->s_register==NULL) goto freeall; if (IV!=NULL) { @@ -55,8 +55,8 @@ static GF_Err _init_mcrypt( nOFB_BUFFER* buf, void *key, int lenofkey, void *IV, return GF_OK; freeall: - if (buf->enc_s_register) free(buf->enc_s_register); - if (buf->s_register) free(buf->s_register); + if (buf->enc_s_register) gf_free(buf->enc_s_register); + if (buf->s_register) gf_free(buf->s_register); return GF_OUT_OF_MEM; } @@ -85,8 +85,8 @@ static GF_Err _mcrypt_get_state( nOFB_BUFFER* buf, u8 *IV, int *size) static void _end_mcrypt( nOFB_BUFFER* buf) { - free(buf->s_register); - free(buf->enc_s_register); + gf_free(buf->s_register); + gf_free(buf->enc_s_register); } GFINLINE static @@ -208,5 +208,4 @@ void gf_crypt_register_nofb(GF_Crypt *td) td->mode_version = 20020307; } -#endif - +#endif /*!defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/ofb.c b/src/mcrypt/ofb.c index dbaffc2..3daf363 100644 --- a/src/mcrypt/ofb.c +++ b/src/mcrypt/ofb.c @@ -19,7 +19,7 @@ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) typedef struct ofb_buf { u8* s_register; @@ -38,10 +38,10 @@ static GF_Err _init_mcrypt( OFB_BUFFER* buf, void *key, int lenofkey, void *IV, buf->blocksize = size; /* For ofb */ - buf->s_register=malloc( size); + buf->s_register=gf_malloc( size); if (buf->s_register==NULL) goto freeall; - buf->enc_s_register=malloc( size); + buf->enc_s_register=gf_malloc( size); if (buf->enc_s_register==NULL) goto freeall; if (IV!=NULL) { @@ -54,8 +54,8 @@ static GF_Err _init_mcrypt( OFB_BUFFER* buf, void *key, int lenofkey, void *IV, return GF_OK; freeall: - if (buf->s_register) free(buf->s_register); - if (buf->enc_s_register) free(buf->enc_s_register); + if (buf->s_register) gf_free(buf->s_register); + if (buf->enc_s_register) gf_free(buf->enc_s_register); return GF_OUT_OF_MEM; } @@ -82,8 +82,8 @@ static GF_Err _mcrypt_set_state( OFB_BUFFER* buf, void *IV, int size) static void _end_mcrypt( OFB_BUFFER* buf) { - free(buf->s_register); - free(buf->enc_s_register); + gf_free(buf->s_register); + gf_free(buf->enc_s_register); } @@ -159,5 +159,5 @@ void gf_crypt_register_ofb(GF_Crypt *td) td->mode_version = 20010310; } -#endif +#endif /*!defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/rijndael-128.c b/src/mcrypt/rijndael-128.c index 547a47c..2efdc32 100644 --- a/src/mcrypt/rijndael-128.c +++ b/src/mcrypt/rijndael-128.c @@ -19,10 +19,12 @@ * All modifications are placed under the license of libmcrypt. */ -/* $Id: rijndael-128.c,v 1.2 2006/11/13 18:07:07 jeanlf Exp $ */ +/* $Id: rijndael-128.c,v 1.3 2009-07-31 07:37:43 jeanlf Exp $ */ #include <gpac/internal/crypt_dev.h> +#if !defined(GPAC_DISABLE_MCRYPT) + typedef struct rijndael_instance { int Nk,Nb,Nr; u8 fi[24],ri[24]; @@ -412,3 +414,4 @@ void gf_crypt_register_rijndael_128(GF_Crypt *td) td->algo_size = sizeof(RI); } +#endif /*!defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/rijndael-192.c b/src/mcrypt/rijndael-192.c index 50487d2..e930541 100644 --- a/src/mcrypt/rijndael-192.c +++ b/src/mcrypt/rijndael-192.c @@ -20,11 +20,11 @@ */ -/* $Id: rijndael-192.c,v 1.1.1.1 2005/07/13 14:36:35 jeanlf Exp $ */ +/* $Id: rijndael-192.c,v 1.2 2009-07-31 07:37:43 jeanlf Exp $ */ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) typedef struct rijndael_instance { int Nk,Nb,Nr; @@ -414,5 +414,5 @@ void gf_crypt_register_rijndael_192(GF_Crypt *td) td->algo_size = sizeof(RI); } -#endif +#endif /* !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/rijndael-256.c b/src/mcrypt/rijndael-256.c index 356e833..41aee2e 100644 --- a/src/mcrypt/rijndael-256.c +++ b/src/mcrypt/rijndael-256.c @@ -19,11 +19,11 @@ * All modifications are placed under the license of libmcrypt. */ -/* $Id: rijndael-256.c,v 1.1.1.1 2005/07/13 14:36:35 jeanlf Exp $ */ +/* $Id: rijndael-256.c,v 1.2 2009-07-31 07:37:43 jeanlf Exp $ */ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) typedef struct rijndael_instance { int Nk,Nb,Nr; @@ -413,4 +413,4 @@ void gf_crypt_register_rijndael_256(GF_Crypt *td) td->algo_size = sizeof(RI); } -#endif +#endif /* !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/mcrypt/sha1.c b/src/mcrypt/sha1.c index 6e07e9e..b9dc1e4 100644 --- a/src/mcrypt/sha1.c +++ b/src/mcrypt/sha1.c @@ -313,7 +313,7 @@ s32 gf_sha1_file( char *path, u8 output[20] ) GF_SHA1Context ctx; u8 buf[1024]; - if( ( f = fopen( path, "rb" ) ) == NULL ) + if( ( f = gf_f64_open( path, "rb" ) ) == NULL ) return( 1 ); gf_sha1_starts( &ctx ); diff --git a/src/mcrypt/stream.c b/src/mcrypt/stream.c index fd04d10..b98a61a 100644 --- a/src/mcrypt/stream.c +++ b/src/mcrypt/stream.c @@ -19,7 +19,7 @@ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) static GF_Err _init_mcrypt( void* ign, void *key, int lenofkey, void *IV, int size) { return GF_OK; } @@ -65,5 +65,4 @@ void gf_crypt_register_stream(GF_Crypt *td) td->mode_version = 20010801; } -#endif - +#endif /* !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT)*// diff --git a/src/mcrypt/tripledes.c b/src/mcrypt/tripledes.c index e18668c..df1ab6b 100644 --- a/src/mcrypt/tripledes.c +++ b/src/mcrypt/tripledes.c @@ -7,7 +7,7 @@ * Modified modified such that will operate in EDE 3DES - 1999 Nikos Mavroyanopoulos * * Callers now allocate a key schedule as follows: - * kn = (char (*)[8])malloc(sizeof(char) * 8 * 16); + * kn = (char (*)[8])gf_malloc(sizeof(char) * 8 * 16); * or * char kn[16][8]; */ @@ -16,11 +16,11 @@ * All modifications are placed under the license of libmcrypt. */ -/* $Id: tripledes.c,v 1.1.1.1 2005/07/13 14:36:36 jeanlf Exp $ */ +/* $Id: tripledes.c,v 1.3 2010-02-23 16:24:20 jeanlf Exp $ */ #include <gpac/internal/crypt_dev.h> -#ifndef GPAC_CRYPT_ISMA_ONLY +#if !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT) typedef struct triple_des_key { char kn[3][16][8]; @@ -756,5 +756,4 @@ void gf_crypt_register_3des(GF_Crypt *td) td->algo_size = sizeof(TRIPLEDES_KEY); } -#endif - +#endif /* !defined(GPAC_CRYPT_ISMA_ONLY) && !defined(GPAC_DISABLE_MCRYPT)*/ diff --git a/src/media_tools/av_parsers.c b/src/media_tools/av_parsers.c index 8561c99..3e68ce4 100644 --- a/src/media_tools/av_parsers.c +++ b/src/media_tools/av_parsers.c @@ -27,6 +27,127 @@ #include <gpac/constants.h> #include <gpac/math.h> + +GF_EXPORT +const char *gf_m4v_get_profile_name(u8 video_pl) +{ + switch (video_pl) { + case 0x00: return "Reserved (0x00) Profile"; + case 0x01: return "Simple Profile @ Level 1"; + case 0x02: return "Simple Profile @ Level 2"; + case 0x03: return "Simple Profile @ Level 3"; + case 0x08: return "Simple Profile @ Level 0"; + case 0x10: return "Simple Scalable Profile @ Level 0"; + case 0x11: return "Simple Scalable Profile @ Level 1"; + case 0x12: return "Simple Scalable Profile @ Level 2"; + case 0x15: return "AVC/H264 Profile"; + case 0x21: return "Core Profile @ Level 1"; + case 0x22: return "Core Profile @ Level 2"; + case 0x32: return "Main Profile @ Level 2"; + case 0x33: return "Main Profile @ Level 3"; + case 0x34: return "Main Profile @ Level 4"; + case 0x42: return "N-bit Profile @ Level 2"; + case 0x51: return "Scalable Texture Profile @ Level 1"; + case 0x61: return "Simple Face Animation Profile @ Level 1"; + case 0x62: return "Simple Face Animation Profile @ Level 2"; + case 0x63: return "Simple FBA Profile @ Level 1"; + case 0x64: return "Simple FBA Profile @ Level 2"; + case 0x71: return "Basic Animated Texture Profile @ Level 1"; + case 0x72: return "Basic Animated Texture Profile @ Level 2"; + case 0x81: return "Hybrid Profile @ Level 1"; + case 0x82: return "Hybrid Profile @ Level 2"; + case 0x91: return "Advanced Real Time Simple Profile @ Level 1"; + case 0x92: return "Advanced Real Time Simple Profile @ Level 2"; + case 0x93: return "Advanced Real Time Simple Profile @ Level 3"; + case 0x94: return "Advanced Real Time Simple Profile @ Level 4"; + case 0xA1: return "Core Scalable Profile @ Level1"; + case 0xA2: return "Core Scalable Profile @ Level2"; + case 0xA3: return "Core Scalable Profile @ Level3"; + case 0xB1: return "Advanced Coding Efficiency Profile @ Level 1"; + case 0xB2: return "Advanced Coding Efficiency Profile @ Level 2"; + case 0xB3: return "Advanced Coding Efficiency Profile @ Level 3"; + case 0xB4: return "Advanced Coding Efficiency Profile @ Level 4"; + case 0xC1: return "Advanced Core Profile @ Level 1"; + case 0xC2: return "Advanced Core Profile @ Level 2"; + case 0xD1: return "Advanced Scalable Texture @ Level1"; + case 0xD2: return "Advanced Scalable Texture @ Level2"; + case 0xE1: return "Simple Studio Profile @ Level 1"; + case 0xE2: return "Simple Studio Profile @ Level 2"; + case 0xE3: return "Simple Studio Profile @ Level 3"; + case 0xE4: return "Simple Studio Profile @ Level 4"; + case 0xE5: return "Core Studio Profile @ Level 1"; + case 0xE6: return "Core Studio Profile @ Level 2"; + case 0xE7: return "Core Studio Profile @ Level 3"; + case 0xE8: return "Core Studio Profile @ Level 4"; + case 0xF0: return "Advanced Simple Profile @ Level 0"; + case 0xF1: return "Advanced Simple Profile @ Level 1"; + case 0xF2: return "Advanced Simple Profile @ Level 2"; + case 0xF3: return "Advanced Simple Profile @ Level 3"; + case 0xF4: return "Advanced Simple Profile @ Level 4"; + case 0xF5: return "Advanced Simple Profile @ Level 5"; + case 0xF7: return "Advanced Simple Profile @ Level 3b"; + case 0xF8: return "Fine Granularity Scalable Profile @ Level 0"; + case 0xF9: return "Fine Granularity Scalable Profile @ Level 1"; + case 0xFA: return "Fine Granularity Scalable Profile @ Level 2"; + case 0xFB: return "Fine Granularity Scalable Profile @ Level 3"; + case 0xFC: return "Fine Granularity Scalable Profile @ Level 4"; + case 0xFD: return "Fine Granularity Scalable Profile @ Level 5"; + case 0xFE: return "Not part of MPEG-4 Visual profiles"; + case 0xFF: return "No visual capability required"; + default: return "ISO Reserved Profile"; + } +} + + +#ifndef GPAC_DISABLE_AV_PARSERS + +#define MPEG12_START_CODE_PREFIX 0x000001 +#define MPEG12_PICTURE_START_CODE 0x00000100 +#define MPEG12_SLICE_MIN_START 0x00000101 +#define MPEG12_SLICE_MAX_START 0x000001af +#define MPEG12_USER_DATA_START_CODE 0x000001b2 +#define MPEG12_SEQUENCE_START_CODE 0x000001b3 +#define MPEG12_SEQUENCE_ERR_START_CODE 0x000001b4 +#define MPEG12_EXT_START_CODE 0x000001b5 +#define MPEG12_SEQUENCE_END_START_CODE 0x000001b7 +#define MPEG12_GOP_START_CODE 0x000001b8 + +s32 gf_mv12_next_start_code(unsigned char *pbuffer, u32 buflen, u32 *optr, u32 *scode) +{ + u32 value; + u32 offset; + + if (buflen < 4) return -1; + for (offset = 0; offset < buflen - 3; offset++, pbuffer++) { +#ifdef GPAC_BIG_ENDIAN + value = *(u32 *)pbuffer >> 8; +#else + value = (pbuffer[0] << 16) | (pbuffer[1] << 8) | (pbuffer[2] << 0); +#endif + + if (value == MPEG12_START_CODE_PREFIX) { + *optr = offset; + *scode = (value << 8) | pbuffer[3]; + return 0; + } + } + return -1; +} + +s32 gf_mv12_next_slice_start(unsigned char *pbuffer, u32 startoffset, u32 buflen, u32 *slice_offset) +{ + u32 slicestart, code; + while (gf_mv12_next_start_code(pbuffer + startoffset, buflen - startoffset, &slicestart, &code) >= 0) { + if ((code >= MPEG12_SLICE_MIN_START) && (code <= MPEG12_SLICE_MAX_START)) { + *slice_offset = slicestart + startoffset; + return 0; + } + startoffset += slicestart + 4; + } + return -1; +} + + /* MPEG-4 video (14496-2) */ @@ -50,12 +171,12 @@ struct __tag_m4v_parser GF_BitStream *bs; Bool mpeg12; u32 current_object_type; - u32 current_object_start; + u64 current_object_start; u32 tc_dec, prev_tc_dec, tc_disp, prev_tc_disp; }; GF_EXPORT -GF_M4VParser *gf_m4v_parser_new(char *data, u32 data_size, Bool mpeg12video) +GF_M4VParser *gf_m4v_parser_new(char *data, u64 data_size, Bool mpeg12video) { GF_M4VParser *tmp; if (!data || !data_size) return NULL; @@ -78,7 +199,7 @@ GF_EXPORT void gf_m4v_parser_del(GF_M4VParser *m4v) { gf_bs_del(m4v->bs); - free(m4v); + gf_free(m4v); } @@ -114,81 +235,12 @@ s32 M4V_LoadObject(GF_M4VParser *m4v) } } if (!found) return -1; - m4v->current_object_start = (u32) end; + m4v->current_object_start = end; gf_bs_seek(m4v->bs, end+3); m4v->current_object_type = gf_bs_read_u8(m4v->bs); return (s32) m4v->current_object_type; } -GF_EXPORT -const char *gf_m4v_get_profile_name(u8 video_pl) -{ - switch (video_pl) { - case 0x00: return "Reserved (0x00) Profile"; - case 0x01: return "Simple Profile @ Level 1"; - case 0x02: return "Simple Profile @ Level 2"; - case 0x03: return "Simple Profile @ Level 3"; - case 0x08: return "Simple Profile @ Level 0"; - case 0x10: return "Simple Scalable Profile @ Level 0"; - case 0x11: return "Simple Scalable Profile @ Level 1"; - case 0x12: return "Simple Scalable Profile @ Level 2"; - case 0x15: return "AVC/H264 Profile"; - case 0x21: return "Core Profile @ Level 1"; - case 0x22: return "Core Profile @ Level 2"; - case 0x32: return "Main Profile @ Level 2"; - case 0x33: return "Main Profile @ Level 3"; - case 0x34: return "Main Profile @ Level 4"; - case 0x42: return "N-bit Profile @ Level 2"; - case 0x51: return "Scalable Texture Profile @ Level 1"; - case 0x61: return "Simple Face Animation Profile @ Level 1"; - case 0x62: return "Simple Face Animation Profile @ Level 2"; - case 0x63: return "Simple FBA Profile @ Level 1"; - case 0x64: return "Simple FBA Profile @ Level 2"; - case 0x71: return "Basic Animated Texture Profile @ Level 1"; - case 0x72: return "Basic Animated Texture Profile @ Level 2"; - case 0x81: return "Hybrid Profile @ Level 1"; - case 0x82: return "Hybrid Profile @ Level 2"; - case 0x91: return "Advanced Real Time Simple Profile @ Level 1"; - case 0x92: return "Advanced Real Time Simple Profile @ Level 2"; - case 0x93: return "Advanced Real Time Simple Profile @ Level 3"; - case 0x94: return "Advanced Real Time Simple Profile @ Level 4"; - case 0xA1: return "Core Scalable Profile @ Level1"; - case 0xA2: return "Core Scalable Profile @ Level2"; - case 0xA3: return "Core Scalable Profile @ Level3"; - case 0xB1: return "Advanced Coding Efficiency Profile @ Level 1"; - case 0xB2: return "Advanced Coding Efficiency Profile @ Level 2"; - case 0xB3: return "Advanced Coding Efficiency Profile @ Level 3"; - case 0xB4: return "Advanced Coding Efficiency Profile @ Level 4"; - case 0xC1: return "Advanced Core Profile @ Level 1"; - case 0xC2: return "Advanced Core Profile @ Level 2"; - case 0xD1: return "Advanced Scalable Texture @ Level1"; - case 0xD2: return "Advanced Scalable Texture @ Level2"; - case 0xE1: return "Simple Studio Profile @ Level 1"; - case 0xE2: return "Simple Studio Profile @ Level 2"; - case 0xE3: return "Simple Studio Profile @ Level 3"; - case 0xE4: return "Simple Studio Profile @ Level 4"; - case 0xE5: return "Core Studio Profile @ Level 1"; - case 0xE6: return "Core Studio Profile @ Level 2"; - case 0xE7: return "Core Studio Profile @ Level 3"; - case 0xE8: return "Core Studio Profile @ Level 4"; - case 0xF0: return "Advanced Simple Profile @ Level 0"; - case 0xF1: return "Advanced Simple Profile @ Level 1"; - case 0xF2: return "Advanced Simple Profile @ Level 2"; - case 0xF3: return "Advanced Simple Profile @ Level 3"; - case 0xF4: return "Advanced Simple Profile @ Level 4"; - case 0xF5: return "Advanced Simple Profile @ Level 5"; - case 0xF7: return "Advanced Simple Profile @ Level 3b"; - case 0xF8: return "Fine Granularity Scalable Profile @ Level 0"; - case 0xF9: return "Fine Granularity Scalable Profile @ Level 1"; - case 0xFA: return "Fine Granularity Scalable Profile @ Level 2"; - case 0xFB: return "Fine Granularity Scalable Profile @ Level 3"; - case 0xFC: return "Fine Granularity Scalable Profile @ Level 4"; - case 0xFD: return "Fine Granularity Scalable Profile @ Level 5"; - case 0xFE: return "Not part of MPEG-4 Visual profiles"; - case 0xFF: return "No visual capability required"; - default: return "ISO Reserved Profile"; - } -} GF_EXPORT void gf_m4v_rewrite_pl(char **o_data, u32 *o_dataLen, u8 PL) @@ -205,21 +257,22 @@ void gf_m4v_rewrite_pl(char **o_data, u32 *o_dataLen, u8 PL) pos ++; } /*emulate VOS at beggining*/ - (*o_data) = (char *)malloc(sizeof(char)*(dataLen+5)); + (*o_data) = (char *)gf_malloc(sizeof(char)*(dataLen+5)); (*o_data)[0] = 0; (*o_data)[1] = 0; (*o_data)[2] = 1; (*o_data)[3] = (char) M4V_VOS_START_CODE; (*o_data)[4] = PL; memcpy( (*o_data + 5), data, sizeof(char)*dataLen); - free(data); + gf_free(data); (*o_dataLen) = dataLen + 5; } -static GF_Err M4V_Reset(GF_M4VParser *m4v, u32 start) +static GF_Err M4V_Reset(GF_M4VParser *m4v, u64 start) { gf_bs_seek(m4v->bs, start); - m4v->current_object_start = start; + assert(start < 1<<31); + m4v->current_object_start = (u32) start; m4v->current_object_type = 0; return GF_OK; } @@ -247,7 +300,7 @@ static GF_Err gf_m4v_parse_config_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo *d dsi->width = (p[0] << 4) | ((p[1] >> 4) & 0xf); dsi->height = ((p[1] & 0xf) << 8) | p[2]; - dsi->VideoPL = 0x6A; + dsi->VideoPL = GPAC_OTI_VIDEO_MPEG1; par = (p[3] >> 4) & 0xf; switch (par) { case 2: dsi->par_num = dsi->height/3; dsi->par_den = dsi->width/4; break; @@ -289,7 +342,7 @@ static GF_Err gf_m4v_parse_config_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo *d /*EOS*/ case -1: go = 0; - m4v->current_object_start = (u32) gf_bs_get_position(m4v->bs); + m4v->current_object_start = gf_bs_get_position(m4v->bs); break; } } @@ -391,7 +444,7 @@ static GF_Err gf_m4v_parse_config_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo *ds /*EOS*/ case -1: go = 0; - m4v->current_object_start = (u32) gf_bs_get_position(m4v->bs); + m4v->current_object_start = gf_bs_get_position(m4v->bs); break; /*don't interest us*/ case M4V_UDTA_START_CODE: @@ -412,7 +465,7 @@ GF_Err gf_m4v_parse_config(GF_M4VParser *m4v, GF_M4VDecSpecInfo *dsi) } } -static GF_Err gf_m4v_parse_frame_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u32 *size, u32 *start, Bool *is_coded) +static GF_Err gf_m4v_parse_frame_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded) { u8 go, hasVOP, firstObj, val; s32 o_type; @@ -474,7 +527,7 @@ static GF_Err gf_m4v_parse_frame_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi break; case -1: - *size = (u32) gf_bs_get_position(m4v->bs) - *start; + *size = gf_bs_get_position(m4v->bs) - *start; return GF_EOS; } } @@ -482,7 +535,7 @@ static GF_Err gf_m4v_parse_frame_mpeg12(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi return GF_OK; } -static GF_Err gf_m4v_parse_frame_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u32 *size, u32 *start, Bool *is_coded) +static GF_Err gf_m4v_parse_frame_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded) { u8 go, hasVOP, firstObj, secs; s32 o_type; @@ -564,7 +617,7 @@ static GF_Err gf_m4v_parse_frame_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, break; case -1: - *size = (u32) gf_bs_get_position(m4v->bs) - *start; + *size = gf_bs_get_position(m4v->bs) - *start; return GF_EOS; } } @@ -573,7 +626,7 @@ static GF_Err gf_m4v_parse_frame_mpeg4(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, } GF_EXPORT -GF_Err gf_m4v_parse_frame(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u32 *size, u32 *start, Bool *is_coded) +GF_Err gf_m4v_parse_frame(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_type, u32 *time_inc, u64 *size, u64 *start, Bool *is_coded) { if (m4v->mpeg12) { return gf_m4v_parse_frame_mpeg12(m4v, dsi, frame_type, time_inc, size, start, is_coded); @@ -584,7 +637,7 @@ GF_Err gf_m4v_parse_frame(GF_M4VParser *m4v, GF_M4VDecSpecInfo dsi, u8 *frame_ty GF_Err gf_m4v_rewrite_par(char **o_data, u32 *o_dataLen, s32 par_n, s32 par_d) { - u32 start, end, size; + u64 start, end, size; GF_BitStream *mod; GF_M4VParser *m4v; Bool go = 1; @@ -596,11 +649,12 @@ GF_Err gf_m4v_rewrite_par(char **o_data, u32 *o_dataLen, s32 par_n, s32 par_d) while (go) { u32 type = M4V_LoadObject(m4v); - end = (u32) gf_bs_get_position(m4v->bs) - 4; + end = gf_bs_get_position(m4v->bs) - 4; size = end - start; /*store previous object*/ if (size) { - if (size) gf_bs_write_data(mod, *o_data + start, size); + assert (size < 1<<31); + if (size) gf_bs_write_data(mod, *o_data + start, (u32) size); start = end; } @@ -613,7 +667,7 @@ GF_Err gf_m4v_rewrite_par(char **o_data, u32 *o_dataLen, s32 par_n, s32 par_d) gf_bs_write_int(mod, gf_bs_read_int(m4v->bs, 1), 1); gf_bs_write_int(mod, gf_bs_read_int(m4v->bs, 8), 8); start = gf_bs_read_int(m4v->bs, 1); - gf_bs_write_int(mod, start, 1); + gf_bs_write_int(mod, (u32) start, 1); if (start) { gf_bs_write_int(mod, gf_bs_read_int(m4v->bs, 7), 7); } @@ -645,14 +699,14 @@ GF_Err gf_m4v_rewrite_par(char **o_data, u32 *o_dataLen, s32 par_n, s32 par_d) } gf_m4v_parser_del(m4v); - free(*o_data); + gf_free(*o_data); gf_bs_get_content(mod, o_data, o_dataLen); gf_bs_del(mod); return GF_OK; } GF_EXPORT -u32 gf_m4v_get_object_start(GF_M4VParser *m4v) +u64 gf_m4v_get_object_start(GF_M4VParser *m4v) { return m4v->current_object_start; } @@ -675,6 +729,8 @@ GF_Err gf_m4v_get_config(char *rawdsi, u32 rawdsi_size, GF_M4VDecSpecInfo *dsi) gf_m4v_parser_del(vparse); return e; } +#endif + /* AAC parser @@ -783,13 +839,16 @@ const char *gf_m4a_get_profile_name(u8 audio_pl) } } +#ifndef GPAC_DISABLE_AV_PARSERS + u32 gf_m4a_get_profile(GF_M4ADecSpecInfo *cfg) { switch (cfg->base_object_type) { case 2: /*AAC LC*/ if (cfg->nb_chan<=2) return (cfg->base_sr<=24000) ? 0x28 : 0x29; /*LC@L1 or LC@L2*/ return (cfg->base_sr<=48000) ? 0x2A : 0x2B; /*LC@L4 or LC@L5*/ - case 5: /*HE-AAC*/ + case 5: /*HE-AAC - SBR*/ + case 29: /*HE-AAC - SBR+PS*/ if (cfg->nb_chan<=2) return (cfg->base_sr<=24000) ? 0x2C : 0x2D; /*HE@L2 or HE@L3*/ return (cfg->base_sr<=48000) ? 0x2E : 0x2F; /*HE@L4 or HE@L5*/ /*default to HQ*/ @@ -820,7 +879,11 @@ GF_Err gf_m4a_parse_config(GF_BitStream *bs, GF_M4ADecSpecInfo *cfg, Bool size_k /*this is 7+1 channels*/ if (cfg->nb_chan==7) cfg->nb_chan=8; - if (cfg->base_object_type==5) { + if (cfg->base_object_type==5 || cfg->base_object_type==29) { + if (cfg->base_object_type==29) { + cfg->has_ps = 1; + cfg->nb_chan = 1; + } cfg->has_sbr = 1; cfg->sbr_sr_index = gf_bs_read_int(bs, 4); if (cfg->sbr_sr_index == 0x0F) { @@ -902,19 +965,28 @@ GF_Err gf_m4a_parse_config(GF_BitStream *bs, GF_M4ADecSpecInfo *cfg, Bool size_k break; } - if (size_known && (cfg->base_object_type != 5) && gf_bs_available(bs)>=2) { - u32 sync = gf_bs_peek_bits(bs, 11, 0); - if (sync==0x2b7) { - gf_bs_read_int(bs, 11); - cfg->sbr_object_type = gf_bs_read_int(bs, 5); - cfg->has_sbr = gf_bs_read_int(bs, 1); - if (cfg->has_sbr) { - cfg->sbr_sr_index = gf_bs_read_int(bs, 4); - if (cfg->sbr_sr_index == 0x0F) { - cfg->sbr_sr = gf_bs_read_int(bs, 24); - } else { - cfg->sbr_sr = GF_M4ASampleRates[cfg->sbr_sr_index]; + if (size_known && (cfg->base_object_type != 5) && (cfg->base_object_type != 29) ) { + while (gf_bs_available(bs)>=2) { + u32 sync = gf_bs_peek_bits(bs, 11, 0); + if (sync==0x2b7) { + gf_bs_read_int(bs, 11); + cfg->sbr_object_type = gf_bs_read_int(bs, 5); + cfg->has_sbr = gf_bs_read_int(bs, 1); + if (cfg->has_sbr) { + cfg->sbr_sr_index = gf_bs_read_int(bs, 4); + if (cfg->sbr_sr_index == 0x0F) { + cfg->sbr_sr = gf_bs_read_int(bs, 24); + } else { + cfg->sbr_sr = GF_M4ASampleRates[cfg->sbr_sr_index]; + } } + } else if (sync == 0x548) { + gf_bs_read_int(bs, 11); + cfg->has_ps = gf_bs_read_int(bs, 1); + if (cfg->has_ps) + cfg->nb_chan = 1; + } else { + break; } } } @@ -933,12 +1005,24 @@ GF_Err gf_m4a_get_config(char *dsi, u32 dsi_size, GF_M4ADecSpecInfo *cfg) return GF_OK; } - GF_EXPORT -GF_Err gf_m4a_write_config(GF_M4ADecSpecInfo *cfg, char **dsi, u32 *dsi_size) +GF_Err gf_m4a_write_config_bs(GF_BitStream *bs, GF_M4ADecSpecInfo *cfg) { - GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - + if (!cfg->base_sr_index) { + if (!cfg->base_sr) return GF_BAD_PARAM; + while (GF_M4ASampleRates[cfg->base_sr_index]) { + if (GF_M4ASampleRates[cfg->base_sr_index]==cfg->base_sr) + break; + cfg->base_sr_index++; + } + } + if (cfg->sbr_sr && !cfg->sbr_sr_index) { + while (GF_M4ASampleRates[cfg->sbr_sr_index]) { + if (GF_M4ASampleRates[cfg->sbr_sr_index]==cfg->sbr_sr) + break; + cfg->sbr_sr_index++; + } + } /*extended object type*/ if (cfg->base_object_type>=32) { gf_bs_write_int(bs, 31, 5); @@ -956,7 +1040,11 @@ GF_Err gf_m4a_write_config(GF_M4ADecSpecInfo *cfg, char **dsi, u32 *dsi_size) gf_bs_write_int(bs, cfg->nb_chan, 4); } - if (cfg->base_object_type==5) { + if (cfg->base_object_type==5 || cfg->base_object_type==29) { + if (cfg->base_object_type == 29) { + cfg->has_ps = 1; + cfg->nb_chan = 1; + } cfg->has_sbr = 1; gf_bs_write_int(bs, cfg->sbr_sr_index, 4); if (cfg->sbr_sr_index == 0x0F) { @@ -995,7 +1083,7 @@ GF_Err gf_m4a_write_config(GF_M4ADecSpecInfo *cfg, char **dsi, u32 *dsi_size) /*ER cfg - not supported*/ /*implicit sbr - not used yet*/ - if (0 && (cfg->base_object_type != 5) ) { + if (0 && (cfg->base_object_type != 5) && (cfg->base_object_type != 29) ) { gf_bs_write_int(bs, 0x2b7, 11); cfg->sbr_object_type = gf_bs_read_int(bs, 5); cfg->has_sbr = gf_bs_read_int(bs, 1); @@ -1008,22 +1096,43 @@ GF_Err gf_m4a_write_config(GF_M4ADecSpecInfo *cfg, char **dsi, u32 *dsi_size) } } } + return GF_OK; +} + +GF_EXPORT +GF_Err gf_m4a_write_config(GF_M4ADecSpecInfo *cfg, char **dsi, u32 *dsi_size) +{ + GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + gf_m4a_write_config_bs(bs, cfg); gf_bs_get_content(bs, dsi, dsi_size); gf_bs_del(bs); return GF_OK; } +#endif /*GPAC_DISABLE_AV_PARSERS*/ -/* - MP3 parser - credits go to CISCO - MPEG4IP -*/ GF_EXPORT u8 gf_mp3_version(u32 hdr) { return ((hdr >> 19) & 0x3); } +GF_EXPORT +const char *gf_mp3_version_name(u32 hdr) +{ + u32 v = gf_mp3_version(hdr); + switch (v) { + case 0: return "MPEG-2.5"; + case 1: return "Reserved"; + case 2: return "MPEG-2"; + case 3: return "MPEG-1"; + default: return "Unknown"; + } +} + +#ifndef GPAC_DISABLE_AV_PARSERS + + static u8 MP3_GetLayerV(u32 hdr) { return ((hdr >> 17) & 0x3); @@ -1104,28 +1213,15 @@ u8 gf_mp3_object_type_indication(u32 hdr) { switch (gf_mp3_version(hdr)) { case 3: - return 0x6B; - break; + return GPAC_OTI_AUDIO_MPEG1; case 2: case 0: - return 0x69; + return GPAC_OTI_AUDIO_MPEG2_PART3; default: return 0x00; } } -GF_EXPORT -const char *gf_mp3_version_name(u32 hdr) -{ - u32 v = gf_mp3_version(hdr); - switch (v) { - case 0: return "MPEG-2.5"; - case 1: return "Reserved"; - case 2: return "MPEG-2"; - case 3: return "MPEG-1"; - default: return "Unknown"; - } -} static GFINLINE u32 get_MP3BitRates(u32 idx1, u32 idx2) { @@ -1410,14 +1506,29 @@ u32 gf_mp3_get_next_header_mem(char *buffer, u32 size, u32 *pos) return 0; } -#ifndef GPAC_READ_ONLY +#endif /*GPAC_DISABLE_AV_PARSERS*/ -/* - MPEG-4 AVC/H264 parser - Inspired from ffmpeg (LGPL) and MPEG4IP (MPL) -*/ +GF_EXPORT +const char *gf_avc_get_profile_name(u8 video_prof) +{ + switch (video_prof) { + case 0x42: return "Baseline"; + case 0x4D: return "Main"; + case 0x53: return "Scalable Baseline"; + case 0x56: return "Scalable High"; + case 0x58: return "Extended"; + case 0x64: return "High"; + case 0x6E: return "High 10"; + case 0x7A: return "High 4:2:2"; + case 0x90: return "High 4:4:4"; + default: return "Unknown"; + } +} + +#ifndef GPAC_DISABLE_AV_PARSERS + static u8 avc_golomb_bits[256] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, @@ -1516,12 +1627,6 @@ u32 AVC_NextStartCode(GF_BitStream *bs) return (u32) (end-start); } - -Bool AVC_NALUIsSlice(u8 type) -{ - return ((type >= GF_AVC_NALU_NON_IDR_SLICE) && (type <= GF_AVC_NALU_IDR_SLICE)) ? 1 : 0; -} - Bool AVC_SliceIsIDR(AVCState *avc) { if (avc->sei.recovery_point.valid) @@ -1543,34 +1648,208 @@ Bool AVC_SliceIsIDR(AVCState *avc) static const struct { u32 w, h; } avc_sar[14] = { - { 0, 0 }, { 1, 1 }, { 12, 11 }, { 10, 11 }, - { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 }, - { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 }, - { 64, 33 }, { 160,99 }, + { 0, 0 }, { 1, 1 }, { 12, 11 }, { 10, 11 }, + { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 }, + { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 }, + { 64, 33 }, { 160,99 }, }; -s32 AVC_ReadSeqInfo(GF_BitStream *bs, AVCState *avc, u32 *vui_flag_pos) +/*ISO 14496-10 (N11084) E.1.2*/ +static void avc_parse_hrd_parameters(GF_BitStream *bs, AVC_HRD *hrd) +{ + int i, cpb_cnt_minus1; + + cpb_cnt_minus1 = avc_get_ue(bs); /*cpb_cnt_minus1*/ + gf_bs_read_int(bs, 4); /*bit_rate_scale*/ + gf_bs_read_int(bs, 4); /*cpb_size_scale*/ + + /*for( SchedSelIdx = 0; SchedSelIdx <= cpb_cnt_minus1; SchedSelIdx++ ) {*/ + for (i=0; i<=cpb_cnt_minus1; i++) { + avc_get_ue(bs); /*bit_rate_value_minus1[ SchedSelIdx ]*/ + avc_get_ue(bs); /*cpb_size_value_minus1[ SchedSelIdx ]*/ + gf_bs_read_int(bs, 1); /*cbr_flag[ SchedSelIdx ]*/ + } + gf_bs_read_int(bs, 5); /*initial_cpb_removal_delay_length_minus1*/ + hrd->cpb_removal_delay_length_minus1 = gf_bs_read_int(bs, 5); /*cpb_removal_delay_length_minus1*/ + hrd->dpb_output_delay_length_minus1 = gf_bs_read_int(bs, 5); /*dpb_output_delay_length_minus1*/ + gf_bs_read_int(bs, 5); /*time_offset_length*/ + + return; +} + +/*returns the nal_size without emulation prevention bytes*/ +static u32 avc_emulation_bytes_add_count(unsigned char *buffer, u32 nal_size) +{ + u32 i = 0, emulation_bytes_count = 0; + u8 num_zero = 0; + + while (i < nal_size) { + /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003 + other than the following sequences shall not occur at any byte-aligned position: + – 0x00000300 + – 0x00000301 + – 0x00000302 + – 0x00000303" + */ + if (num_zero == 2 && buffer[i] < 0x04) { + /*emulation code found*/ + num_zero = 0; + emulation_bytes_count++; + } else { + if (!buffer[i]) + num_zero++; + else + num_zero = 0; + } + i++; + } + return emulation_bytes_count; +} + +static u32 avc_add_emulation_bytes(const unsigned char *buffer_src, unsigned char *buffer_dst, u32 nal_size) +{ + + u32 i = 0, emulation_bytes_count = 0; + u8 num_zero = 0; + + while (i < nal_size) { + /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003 + other than the following sequences shall not occur at any byte-aligned position: + 0x00000300 + 0x00000301 + 0x00000302 + 0x00000303" + */ + if (num_zero == 2 && buffer_src[i] < 0x04) { + /*add emulation code*/ + num_zero = 0; + buffer_dst[i+emulation_bytes_count] = 0x03; + emulation_bytes_count++; + } else { + if (!buffer_src[i]) + num_zero++; + else + num_zero = 0; + } + buffer_dst[i+emulation_bytes_count] = buffer_src[i]; + i++; + } + return nal_size+emulation_bytes_count; +} + +/*returns the nal_size without emulation prevention bytes*/ +static u32 avc_emulation_bytes_remove_count(unsigned char *buffer, u32 nal_size) +{ + u32 i = 0, emulation_bytes_count = 0; + u8 num_zero = 0; + + while (i < nal_size) + { + /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003 + other than the following sequences shall not occur at any byte-aligned position: + – 0x00000300 + – 0x00000301 + – 0x00000302 + – 0x00000303" + */ + if (num_zero == 2 + && buffer[i] == 0x03 + && i+1 < nal_size /*next byte is readable*/ + && buffer[i+1] < 0x04) + { + /*emulation code found*/ + num_zero = 0; + emulation_bytes_count++; + i++; + } + + if (!buffer[i]) + num_zero++; + else + num_zero = 0; + + i++; + } + + return emulation_bytes_count; +} + + +/*nal_size is updated to allow better error detection*/ +static u32 avc_remove_emulation_bytes(const unsigned char *buffer_src, unsigned char *buffer_dst, u32 nal_size) +{ + u32 i = 0, emulation_bytes_count = 0; + u8 num_zero = 0; + + while (i < nal_size) + { + /*ISO 14496-10: "Within the NAL unit, any four-byte sequence that starts with 0x000003 + other than the following sequences shall not occur at any byte-aligned position: + 0x00000300 + 0x00000301 + 0x00000302 + 0x00000303" + */ + if (num_zero == 2 + && buffer_src[i] == 0x03 + && i+1 < nal_size /*next byte is readable*/ + && buffer_src[i+1] < 0x04) + { + /*emulation code found*/ + num_zero = 0; + emulation_bytes_count++; + i++; + } + + buffer_dst[i-emulation_bytes_count] = buffer_src[i]; + + if (!buffer_src[i]) + num_zero++; + else + num_zero = 0; + + i++; + } + + return nal_size-emulation_bytes_count; +} + +s32 AVC_ReadSeqInfo(char *sps_data, u32 sps_size, AVCState *avc, u32 subseq_sps, u32 *vui_flag_pos) { AVC_SPS *sps; s32 mb_width, mb_height; u32 sps_id, profile_idc, level_idc, pcomp, i, chroma_format_idc, cl, cr, ct, cb; + GF_BitStream *bs; + char *sps_data_without_emulation_bytes = NULL; + u32 sps_data_without_emulation_bytes_size = 0; + + /*SPS still contains emulation bytes*/ + sps_data_without_emulation_bytes = gf_malloc(sps_size*sizeof(char)); + sps_data_without_emulation_bytes_size = avc_remove_emulation_bytes(sps_data, sps_data_without_emulation_bytes, sps_size); + bs = gf_bs_new(sps_data_without_emulation_bytes, sps_data_without_emulation_bytes_size, GF_BITSTREAM_READ); if (vui_flag_pos) *vui_flag_pos = 0; profile_idc = gf_bs_read_int(bs, 8); pcomp = gf_bs_read_int(bs, 8); level_idc = gf_bs_read_int(bs, 8); - sps_id = avc_get_ue(bs); + /*SubsetSps is used to be sure that AVC SPS are not going to be scratched + by subset SPS. According to the SVC standard, subset SPS can have the same sps_id + than its base layer, but it does not refer to the same SPS. */ + sps_id = avc_get_ue(bs) + 16 * subseq_sps; sps = &avc->sps[sps_id]; - if (!sps->status) sps->status = 1; + sps->state |= subseq_sps ? AVC_SUBSPS_PARSED : AVC_SPS_PARSED; - /*High Profile cfg stuff*/ + /*High Profile and SVC*/ switch (profile_idc) { case 100: case 110: case 122: - case 144: + case 244: + case 44: + case 83: + case 86: chroma_format_idc = avc_get_ue(bs); if (chroma_format_idc == 3) /*residual_colour_transform_flag = */ gf_bs_read_int(bs, 1); /*bit_depth_luma_minus8 = */ avc_get_ue(bs); @@ -1599,162 +1878,262 @@ s32 AVC_ReadSeqInfo(GF_BitStream *bs, AVCState *avc, u32 *vui_flag_pos) sps->profile_idc = profile_idc; sps->level_idc = level_idc; sps->prof_compat = pcomp; - sps->log2_max_frame_num = avc_get_ue(bs) + 4; - sps->poc_type = avc_get_ue(bs); - - if (sps->poc_type == 0) { - sps->log2_max_poc_lsb = avc_get_ue(bs) + 4; - } else if(sps->poc_type == 1) { - sps->delta_pic_order_always_zero_flag = gf_bs_read_int(bs, 1); - sps->offset_for_non_ref_pic = avc_get_se(bs); - sps->offset_for_top_to_bottom_field = avc_get_se(bs); - sps->poc_cycle_length = avc_get_ue(bs); - for(i=0; i<sps->poc_cycle_length; i++) sps->offset_for_ref_frame[i] = avc_get_se(bs); - } - if (sps->poc_type > 2) return -1; - avc_get_ue(bs); /*ref_frame_count*/ - gf_bs_read_int(bs, 1); /*gaps_in_frame_num_allowed_flag*/ - mb_width = avc_get_ue(bs) + 1; - mb_height= avc_get_ue(bs) + 1; - - sps->frame_mbs_only_flag = gf_bs_read_int(bs, 1); - - sps->width = mb_width * 16; - sps->height = (2-sps->frame_mbs_only_flag) * mb_height * 16; + sps->log2_max_frame_num = avc_get_ue(bs) + 4; + sps->poc_type = avc_get_ue(bs); + + if (sps->poc_type == 0) { + sps->log2_max_poc_lsb = avc_get_ue(bs) + 4; + } else if(sps->poc_type == 1) { + sps->delta_pic_order_always_zero_flag = gf_bs_read_int(bs, 1); + sps->offset_for_non_ref_pic = avc_get_se(bs); + sps->offset_for_top_to_bottom_field = avc_get_se(bs); + sps->poc_cycle_length = avc_get_ue(bs); + for(i=0; i<sps->poc_cycle_length; i++) sps->offset_for_ref_frame[i] = avc_get_se(bs); + } + if (sps->poc_type > 2) { + gf_free(sps_data_without_emulation_bytes); + return -1; + } + avc_get_ue(bs); /*ref_frame_count*/ + gf_bs_read_int(bs, 1); /*gaps_in_frame_num_allowed_flag*/ + mb_width = avc_get_ue(bs) + 1; + mb_height= avc_get_ue(bs) + 1; + + sps->frame_mbs_only_flag = gf_bs_read_int(bs, 1); + + sps->width = mb_width * 16; + sps->height = (2-sps->frame_mbs_only_flag) * mb_height * 16; /*mb_adaptive_frame_field_flag*/ if (!sps->frame_mbs_only_flag) gf_bs_read_int(bs, 1); - gf_bs_read_int(bs, 1); /*direct_8x8_inference_flag*/ + gf_bs_read_int(bs, 1); /*direct_8x8_inference_flag*/ cl = cr = ct = cb = 0; - if (gf_bs_read_int(bs, 1)) /*crop*/ { - cl = avc_get_ue(bs); /*crop_left*/ - cr = avc_get_ue(bs); /*crop_right*/ - ct = avc_get_ue(bs); /*crop_top*/ - cb = avc_get_ue(bs); /*crop_bottom*/ + if (gf_bs_read_int(bs, 1)) /*crop*/ { + cl = avc_get_ue(bs); /*crop_left*/ + cr = avc_get_ue(bs); /*crop_right*/ + ct = avc_get_ue(bs); /*crop_top*/ + cb = avc_get_ue(bs); /*crop_bottom*/ sps->width = 16*mb_width - 2*(cl + cr); sps->height -= (2-sps->frame_mbs_only_flag)*2*(ct + cb); - } + } if (vui_flag_pos) { *vui_flag_pos = (u32) gf_bs_get_bit_offset(bs); } - /*vui_parameters_present_flag*/ - if (gf_bs_read_int(bs, 1)) { + /*vui_parameters_present_flag*/ + if (gf_bs_read_int(bs, 1)) { /*aspect_ratio_info_present_flag*/ if (gf_bs_read_int(bs, 1)) { s32 aspect_ratio_idc = gf_bs_read_int(bs, 8); if (aspect_ratio_idc == 255) { - sps->par_num = gf_bs_read_int(bs, 16); /*AR num*/ - sps->par_den = gf_bs_read_int(bs, 16); /*AR den*/ + sps->vui.par_num = gf_bs_read_int(bs, 16); /*AR num*/ + sps->vui.par_den = gf_bs_read_int(bs, 16); /*AR den*/ } else if (aspect_ratio_idc<14) { - sps->par_num = avc_sar[aspect_ratio_idc].w; - sps->par_den = avc_sar[aspect_ratio_idc].h; + sps->vui.par_num = avc_sar[aspect_ratio_idc].w; + sps->vui.par_den = avc_sar[aspect_ratio_idc].h; } } - if(gf_bs_read_int(bs, 1)) /* overscan_info_present_flag */ - gf_bs_read_int(bs, 1); /* overscan_appropriate_flag */ + if(gf_bs_read_int(bs, 1)) /* overscan_info_present_flag */ + gf_bs_read_int(bs, 1); /* overscan_appropriate_flag */ - if (gf_bs_read_int(bs, 1)){ /* video_signal_type_present_flag */ - gf_bs_read_int(bs, 3); /* video_format */ - gf_bs_read_int(bs, 1); /* video_full_range_flag */ - if (gf_bs_read_int(bs, 1)){ /* colour_description_present_flag */ - gf_bs_read_int(bs, 8); /* colour_primaries */ - gf_bs_read_int(bs, 8); /* transfer_characteristics */ - gf_bs_read_int(bs, 8); /* matrix_coefficients */ + if (gf_bs_read_int(bs, 1)){ /* video_signal_type_present_flag */ + gf_bs_read_int(bs, 3); /* video_format */ + gf_bs_read_int(bs, 1); /* video_full_range_flag */ + if (gf_bs_read_int(bs, 1)){ /* colour_description_present_flag */ + gf_bs_read_int(bs, 8); /* colour_primaries */ + gf_bs_read_int(bs, 8); /* transfer_characteristics */ + gf_bs_read_int(bs, 8); /* matrix_coefficients */ } } - if (gf_bs_read_int(bs, 1)) { /* chroma_location_info_present_flag */ - avc_get_ue(bs); /* chroma_sample_location_type_top_field */ - avc_get_ue(bs); /* chroma_sample_location_type_bottom_field */ + if (gf_bs_read_int(bs, 1)) { /* chroma_location_info_present_flag */ + avc_get_ue(bs); /* chroma_sample_location_type_top_field */ + avc_get_ue(bs); /* chroma_sample_location_type_bottom_field */ } - sps->timing_info_present_flag = gf_bs_read_int(bs, 1); - if (sps->timing_info_present_flag) { - sps->num_units_in_tick = gf_bs_read_int(bs, 32); - sps->time_scale = gf_bs_read_int(bs, 32); - sps->fixed_frame_rate_flag = gf_bs_read_int(bs, 1); + sps->vui.timing_info_present_flag = gf_bs_read_int(bs, 1); + if (sps->vui.timing_info_present_flag) { + sps->vui.num_units_in_tick = gf_bs_read_int(bs, 32); + sps->vui.time_scale = gf_bs_read_int(bs, 32); + sps->vui.fixed_frame_rate_flag = gf_bs_read_int(bs, 1); } + + sps->vui.nal_hrd_parameters_present_flag = gf_bs_read_int(bs, 1); + if (sps->vui.nal_hrd_parameters_present_flag) + avc_parse_hrd_parameters(bs, &sps->vui.hrd); + + sps->vui.vcl_hrd_parameters_present_flag = gf_bs_read_int(bs, 1); + if (sps->vui.vcl_hrd_parameters_present_flag) + avc_parse_hrd_parameters(bs, &sps->vui.hrd); + + if (sps->vui.nal_hrd_parameters_present_flag || sps->vui.vcl_hrd_parameters_present_flag) + gf_bs_read_int(bs, 1); /*low_delay_hrd_flag*/ + + sps->vui.pic_struct_present_flag = gf_bs_read_int(bs, 1); } - return sps_id; + + gf_free(sps_data_without_emulation_bytes); + return sps_id; } -s32 AVC_ReadPictParamSet(GF_BitStream *bs, AVCState *avc) +s32 AVC_ReadPictParamSet(char *pps_data, u32 pps_size, AVCState *avc) { - s32 pps_id = avc_get_ue(bs); - AVC_PPS *pps= &avc->pps[pps_id]; + GF_BitStream *bs; + char *pps_data_without_emulation_bytes = NULL; + u32 pps_data_without_emulation_bytes_size = 0; + s32 pps_id; + AVC_PPS *pps; + + /*PPS still contains emulation bytes*/ + pps_data_without_emulation_bytes = gf_malloc(pps_size*sizeof(char)); + pps_data_without_emulation_bytes_size = avc_remove_emulation_bytes(pps_data, pps_data_without_emulation_bytes, pps_size); + bs = gf_bs_new(pps_data_without_emulation_bytes, pps_data_without_emulation_bytes_size, GF_BITSTREAM_READ); + pps_id = avc_get_ue(bs); + pps = &avc->pps[pps_id]; if (!pps->status) pps->status = 1; - pps->sps_id= avc_get_ue(bs); - /*pps->cabac = */gf_bs_read_int(bs, 1); - /*pps->pic_order_present= */gf_bs_read_int(bs, 1); - pps->slice_group_count= avc_get_ue(bs) + 1; - if (pps->slice_group_count > 1 ) /*pps->mb_slice_group_map_type = */avc_get_ue(bs); - /*pps->ref_count[0]= */avc_get_ue(bs) /*+ 1*/; - /*pps->ref_count[1]= */avc_get_ue(bs) /*+ 1*/; - /* + pps->sps_id = avc_get_ue(bs); + if (!avc->sps[pps->sps_id].state) { + pps_id = -1; + goto exit; + } + avc->sps_active_idx = pps->sps_id; /*set active sps*/ + /*pps->cabac = */gf_bs_read_int(bs, 1); + pps->pic_order_present= gf_bs_read_int(bs, 1); + pps->slice_group_count= avc_get_ue(bs) + 1; + if (pps->slice_group_count > 1 ) /*pps->mb_slice_group_map_type = */avc_get_ue(bs); + /*pps->ref_count[0]= */avc_get_ue(bs) /*+ 1*/; + /*pps->ref_count[1]= */avc_get_ue(bs) /*+ 1*/; + /* if ((pps->ref_count[0] > 32) || (pps->ref_count[1] > 32)) return -1; */ - - /*pps->weighted_pred = */gf_bs_read_int(bs, 1); - /*pps->weighted_bipred_idc = */gf_bs_read_int(bs, 2); - /*pps->init_qp = */avc_get_se(bs) /*+ 26*/; - /*pps->init_qs= */avc_get_se(bs) /*+ 26*/; - /*pps->chroma_qp_index_offset = */avc_get_se(bs); - /*pps->deblocking_filter_parameters_present = */gf_bs_read_int(bs, 1); - /*pps->constrained_intra_pred = */gf_bs_read_int(bs, 1); - pps->redundant_pic_cnt_present = gf_bs_read_int(bs, 1); - return pps_id; + + /*pps->weighted_pred = */gf_bs_read_int(bs, 1); + /*pps->weighted_bipred_idc = */gf_bs_read_int(bs, 2); + /*pps->init_qp = */avc_get_se(bs) /*+ 26*/; + /*pps->init_qs= */avc_get_se(bs) /*+ 26*/; + /*pps->chroma_qp_index_offset = */avc_get_se(bs); + /*pps->deblocking_filter_parameters_present = */gf_bs_read_int(bs, 1); + /*pps->constrained_intra_pred = */gf_bs_read_int(bs, 1); + pps->redundant_pic_cnt_present = gf_bs_read_int(bs, 1); + +exit: + gf_free(pps_data_without_emulation_bytes); + return pps_id; +} + +static s32 SVC_ReadNal_header_extension(GF_BitStream *bs, SVC_NALUHeader *NalHeader) +{ + gf_bs_read_int(bs, 1); //reserved_one_bits + NalHeader->idr_pic_flag = gf_bs_read_int(bs, 1); //idr_flag + gf_bs_read_int(bs, 6); //priority_id + gf_bs_read_int(bs, 1); //no_inter_layer_pred_flag + gf_bs_read_int(bs, 3); //DependencyId + gf_bs_read_int(bs, 4); //quality_id + NalHeader->temporal_id = gf_bs_read_int(bs, 3); //temporal_id + gf_bs_read_int(bs, 1); //use_ref_base_pic_flag + gf_bs_read_int(bs, 1); //discardable_flag + gf_bs_read_int(bs, 1); //output_flag + gf_bs_read_int(bs, 2); //reserved_three_2bits + return 1; } -static s32 avc_parse_slice(GF_BitStream *bs, AVCState *avc, AVCSliceInfo *si) +static s32 avc_parse_slice(GF_BitStream *bs, AVCState *avc, Bool svc_idr_flag, AVCSliceInfo *si) { - s32 first_mb_in_slice, pps_id; + s32 first_mb_in_slice, pps_id; - /*s->current_picture.reference= h->nal_ref_idc != 0;*/ - first_mb_in_slice = avc_get_ue(bs); - si->slice_type = avc_get_ue(bs); - if (si->slice_type > 9) return -1; + /*s->current_picture.reference= h->nal_ref_idc != 0;*/ + first_mb_in_slice = avc_get_ue(bs); + si->slice_type = avc_get_ue(bs); + if (si->slice_type > 9) return -1; - pps_id = avc_get_ue(bs); - if (pps_id>255) return -1; - si->pps = &avc->pps[pps_id]; - if (!si->pps->slice_group_count) return -2; - si->sps = &avc->sps[si->pps->sps_id]; - if (!si->sps->log2_max_frame_num) return -2; + pps_id = avc_get_ue(bs); + if (pps_id>255) return -1; + si->pps = &avc->pps[pps_id]; + if (!si->pps->slice_group_count) return -2; + si->sps = &avc->sps[si->pps->sps_id]; + if (!si->sps->log2_max_frame_num) return -2; - si->frame_num = gf_bs_read_int(bs, si->sps->log2_max_frame_num); + si->frame_num = gf_bs_read_int(bs, si->sps->log2_max_frame_num); si->field_pic_flag = 0; si->bottom_field_flag = 0; - if (si->sps->frame_mbs_only_flag) { - /*s->picture_structure= PICT_FRAME;*/ - } else { + if (!si->sps->frame_mbs_only_flag) { si->field_pic_flag = gf_bs_read_int(bs, 1); - if (si->field_pic_flag) + if (si->field_pic_flag) si->bottom_field_flag = gf_bs_read_int(bs, 1); - } - if (si->nal_unit_type==GF_AVC_NALU_IDR_SLICE) + } + if ((si->nal_unit_type==GF_AVC_NALU_IDR_SLICE) || svc_idr_flag) si->idr_pic_id = avc_get_ue(bs); - if (si->sps->poc_type==0) { + if (si->sps->poc_type==0) { si->poc_lsb = gf_bs_read_int(bs, si->sps->log2_max_poc_lsb); if (si->pps->pic_order_present && !si->field_pic_flag) { si->delta_poc_bottom = avc_get_se(bs); } } else if ((si->sps->poc_type==1) && !si->sps->delta_pic_order_always_zero_flag) { - si->delta_poc[0] = avc_get_se(bs); - if ((si->pps->pic_order_present==1) && !si->field_pic_flag) - si->delta_poc[1] = avc_get_se(bs); - } - if (si->pps->redundant_pic_cnt_present) { - si->redundant_pic_cnt = avc_get_ue(bs); - } + si->delta_poc[0] = avc_get_se(bs); + if ((si->pps->pic_order_present==1) && !si->field_pic_flag) + si->delta_poc[1] = avc_get_se(bs); + } + if (si->pps->redundant_pic_cnt_present) { + si->redundant_pic_cnt = avc_get_ue(bs); + } return 0; } + +static s32 svc_parse_slice(GF_BitStream *bs, AVCState *avc, AVCSliceInfo *si) +{ + s32 first_mb_in_slice, pps_id; + + /*s->current_picture.reference= h->nal_ref_idc != 0;*/ + first_mb_in_slice = avc_get_ue(bs); + si->slice_type = avc_get_ue(bs); + if (si->slice_type > 9) return -1; + + pps_id = avc_get_ue(bs); + if (pps_id>255) + return -1; + si->pps = &avc->pps[pps_id]; + si->pps->id = pps_id; + if (!si->pps->slice_group_count) + return -2; + si->sps = &avc->sps[si->pps->sps_id + 16]; + if (!si->sps->log2_max_frame_num) + return -2; + + si->frame_num = gf_bs_read_int(bs, si->sps->log2_max_frame_num); + + si->field_pic_flag = 0; + if (si->sps->frame_mbs_only_flag) { + /*s->picture_structure= PICT_FRAME;*/ + } else { + si->field_pic_flag = gf_bs_read_int(bs, 1); + if (si->field_pic_flag) si->bottom_field_flag = gf_bs_read_int(bs, 1); + } + if (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE || si ->NalHeader.idr_pic_flag) + si->idr_pic_id = avc_get_ue(bs); + + if (si->sps->poc_type==0) { + si->poc_lsb = gf_bs_read_int(bs, si->sps->log2_max_poc_lsb); + if (si->pps->pic_order_present && !si->field_pic_flag) { + si->delta_poc_bottom = avc_get_se(bs); + } + } else if ((si->sps->poc_type==1) && !si->sps->delta_pic_order_always_zero_flag) { + si->delta_poc[0] = avc_get_se(bs); + if ((si->pps->pic_order_present==1) && !si->field_pic_flag) + si->delta_poc[1] = avc_get_se(bs); + } + if (si->pps->redundant_pic_cnt_present) { + si->redundant_pic_cnt = avc_get_ue(bs); + } + return 0; +} + + static s32 avc_parse_recovery_point_sei(GF_BitStream *bs, AVCState *avc) { AVCSeiRecoveryPoint *rp = &avc->sei.recovery_point; @@ -1768,6 +2147,43 @@ static s32 avc_parse_recovery_point_sei(GF_BitStream *bs, AVCState *avc) return 0; } +/*for interpretation see ISO 14496-10 N.11084, table D-1*/ +static s32 avc_parse_pic_timing_sei(GF_BitStream *bs, AVCState *avc) +{ + int i; + int sps_id = avc->sps_active_idx; + const char NumClockTS[] = {1, 1, 1, 2, 2, 3, 3, 2, 3}; + AVCSeiPicTiming *pt = &avc->sei.pic_timing; + + if (sps_id < 0) { + /*sps_active_idx equals -1 when no sps has been detected. In this case SEI should not be decoded.*/ + assert(0); + return 1; + } + if (avc->sps[sps_id].vui.nal_hrd_parameters_present_flag || avc->sps[sps_id].vui.vcl_hrd_parameters_present_flag) { /*CpbDpbDelaysPresentFlag, see 14496-10(2003) E.11*/ + gf_bs_read_int(bs, 1+avc->sps[sps_id].vui.hrd.cpb_removal_delay_length_minus1); /*cpb_removal_delay*/ + gf_bs_read_int(bs, 1+avc->sps[sps_id].vui.hrd.dpb_output_delay_length_minus1); /*dpb_output_delay*/ + } + + /*ISO 14496-10 (2003), D.8.2: we need to get pic_struct in order to know if we display top field first or bottom field first*/ + if (avc->sps[sps_id].vui.pic_struct_present_flag) { + pt->pic_struct = gf_bs_read_int(bs, 4); + if (pt->pic_struct > 8) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[avc-h264] invalid pic_struct value %d\n", pt->pic_struct)); + return 1; + } + + for (i=0; i<NumClockTS[pt->pic_struct]; i++) { + if (gf_bs_read_int(bs, 1)) {/*clock_timestamp_flag[i]*/ + GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[avc-h264] not implemented pic_timing part\n", pt->pic_struct)); + assert(0); + } + } + } + + return 0; +} + static void avc_compute_poc(AVCSliceInfo *si) { @@ -1796,9 +2212,12 @@ static void avc_compute_poc(AVCSliceInfo *si) si->frame_num_offset = si->frame_num_offset_prev; } - if (si->sps->poc_type==0) { + /*ISO 14496-10 N.11084 8.2.1.1*/ + if (si->sps->poc_type==0) + { const u32 max_poc_lsb = 1 << (si->sps->log2_max_poc_lsb); + /*ISO 14496-10 N.11084 eq (8-3)*/ if ((si->poc_lsb < si->poc_lsb_prev) && (si->poc_lsb_prev - si->poc_lsb >= max_poc_lsb / 2) ) si->poc_msb = si->poc_msb_prev + max_poc_lsb; @@ -1808,9 +2227,21 @@ static void avc_compute_poc(AVCSliceInfo *si) else si->poc_msb = si->poc_msb_prev; - field_poc[0] = field_poc[1] = si->poc_msb + si->poc_lsb; - if (pic_type == AVC_PIC_FRAME) field_poc[1] += si->delta_poc_bottom; - } else if (si->sps->poc_type==1) { + /*ISO 14496-10 N.11084 eq (8-4)*/ + if (pic_type != AVC_PIC_FIELD_BOTTOM) + field_poc[0] = si->poc_msb + si->poc_lsb; + + /*ISO 14496-10 N.11084 eq (8-5)*/ + if (pic_type != AVC_PIC_FIELD_TOP) { + if (!si->field_pic_flag) + field_poc[1] = field_poc[0] + si->delta_poc_bottom; + else + field_poc[1] = si->poc_msb + si->poc_lsb; + } + } + /*ISO 14496-10 N.11084 8.2.1.2*/ + else if (si->sps->poc_type==1) + { u32 i; s32 abs_frame_num, expected_delta_per_poc_cycle, expected_poc; @@ -1841,7 +2272,10 @@ static void avc_compute_poc(AVCSliceInfo *si) field_poc[0] = expected_poc + si->delta_poc[0]; field_poc[1] = field_poc[0] + si->sps->offset_for_top_to_bottom_field; if (pic_type == AVC_PIC_FRAME) field_poc[1] += si->delta_poc[1]; - } else if (si->sps->poc_type== 2) { + } + /*ISO 14496-10 N.11084 8.2.1.3*/ + else if (si->sps->poc_type== 2) + { int poc; if (si->nal_unit_type == GF_AVC_NALU_IDR_SLICE) { poc = 0; @@ -1853,6 +2287,8 @@ static void avc_compute_poc(AVCSliceInfo *si) field_poc[0] = poc; field_poc[1] = poc; } + + /*ISO 14496-10 N.11084 eq (8-1)*/ if (pic_type == AVC_PIC_FRAME) si->poc = MIN(field_poc[0], field_poc[1] ); else if (pic_type == AVC_PIC_FIELD_TOP) @@ -1863,22 +2299,51 @@ static void avc_compute_poc(AVCSliceInfo *si) s32 AVC_ParseNALU(GF_BitStream *bs, u32 nal_hdr, AVCState *avc) { - u8 temp; + u8 idr_flag; s32 slice, ret; AVCSliceInfo n_state; slice = 0; memcpy(&n_state, &avc->s_info, sizeof(AVCSliceInfo)); - temp = n_state.nal_unit_type = nal_hdr & 0x1F; + n_state.nal_unit_type = nal_hdr & 0x1F; n_state.nal_ref_idc = (nal_hdr>>5) & 0x3; + idr_flag = 0; ret = 0; - switch (temp) { + switch (n_state.nal_unit_type) { case GF_AVC_NALU_ACCESS_UNIT: case GF_AVC_NALU_END_OF_SEQ: case GF_AVC_NALU_END_OF_STREAM: ret = 1; break; + + case GF_AVC_NALU_SVC_SLICE: + SVC_ReadNal_header_extension(bs, &n_state.NalHeader); + slice = 1; + // slice buffer - read the info and compare. + ret = svc_parse_slice(bs, avc, &n_state); + if (avc->s_info.nal_ref_idc) { + n_state.poc_lsb_prev = avc->s_info.poc_lsb; + n_state.poc_msb_prev = avc->s_info.poc_msb; + } + if (slice) + avc_compute_poc(&n_state); + + if (avc->s_info.poc != n_state.poc) { + memcpy(&avc -> s_info, &n_state, sizeof(AVCSliceInfo)); + return 1; + } + memcpy(&avc -> s_info, &n_state, sizeof(AVCSliceInfo)); + return 0; + + case GF_AVC_NALU_SVC_PREFIX_NALU: + SVC_ReadNal_header_extension(bs, &n_state.NalHeader); + + if (avc->s_info.nal_unit_type == GF_AVC_NALU_SVC_SLICE) { + return 1; + } + return 0; + case GF_AVC_NALU_NON_IDR_SLICE: case GF_AVC_NALU_DP_A_SLICE: case GF_AVC_NALU_DP_B_SLICE: @@ -1886,11 +2351,13 @@ s32 AVC_ParseNALU(GF_BitStream *bs, u32 nal_hdr, AVCState *avc) case GF_AVC_NALU_IDR_SLICE: slice = 1; /* slice buffer - read the info and compare.*/ - ret = avc_parse_slice(bs, avc, &n_state); + ret = avc_parse_slice(bs, avc, idr_flag, &n_state); if (ret<0) return ret; ret = 0; - if ((avc->s_info.nal_unit_type > GF_AVC_NALU_IDR_SLICE) - || (avc->s_info.nal_unit_type < GF_AVC_NALU_NON_IDR_SLICE)) { + if ( + ((avc->s_info.nal_unit_type > GF_AVC_NALU_IDR_SLICE) || (avc->s_info.nal_unit_type < GF_AVC_NALU_NON_IDR_SLICE)) + && (avc->s_info.nal_unit_type != GF_AVC_NALU_SVC_SLICE) + ) { break; } if (avc->s_info.frame_num != n_state.frame_num) { ret = 1; break; } @@ -1924,9 +2391,13 @@ s32 AVC_ParseNALU(GF_BitStream *bs, u32 nal_hdr, AVCState *avc) } } } - if ((avc->s_info.nal_unit_type == GF_AVC_NALU_IDR_SLICE) - && (n_state.nal_unit_type == GF_AVC_NALU_IDR_SLICE)) { - if (avc->s_info.idr_pic_id != n_state.idr_pic_id) { + + if (n_state.nal_unit_type == GF_AVC_NALU_IDR_SLICE) { + if (avc->s_info.nal_unit_type != GF_AVC_NALU_IDR_SLICE) { /*IdrPicFlag differs in value*/ + ret = 1; + break; + } + else if (avc->s_info.idr_pic_id != n_state.idr_pic_id) { /*both IDR and idr_pic_id differs*/ ret = 1; break; } @@ -1937,7 +2408,13 @@ s32 AVC_ParseNALU(GF_BitStream *bs, u32 nal_hdr, AVCState *avc) return 0; default: if (avc->s_info.nal_unit_type <= GF_AVC_NALU_IDR_SLICE) ret = 1; - else ret = 0; + //To detect change of AU when multiple sps and pps in stream + else if ((nal_hdr & 0x1F) == GF_AVC_NALU_SEI && avc -> s_info .nal_unit_type == GF_AVC_NALU_SVC_SLICE) + ret = 1; + else if ((nal_hdr & 0x1F) == GF_AVC_NALU_SEQ_PARAM && avc -> s_info .nal_unit_type == GF_AVC_NALU_SVC_SLICE) + ret = 1; + else + ret = 0; break; } @@ -1958,16 +2435,24 @@ s32 AVC_ParseNALU(GF_BitStream *bs, u32 nal_hdr, AVCState *avc) u32 AVC_ReformatSEI_NALU(char *buffer, u32 nal_size, AVCState *avc) { - u32 ptype, psize, hdr, written, start, var, num_zero, size_fix, i; + u32 ptype, psize, hdr, written, var; + u64 start; char *new_buffer; GF_BitStream *bs; + char *sei_without_emulation_bytes = NULL; + u32 sei_without_emulation_bytes_size = 0; + hdr = buffer[0]; if ((hdr & 0x1F) != GF_AVC_NALU_SEI) return 0; - - bs = gf_bs_new(buffer, nal_size, GF_BITSTREAM_READ); + + /*PPS still contains emulation bytes*/ + sei_without_emulation_bytes = gf_malloc(nal_size*sizeof(char)); + sei_without_emulation_bytes_size = avc_remove_emulation_bytes(buffer, sei_without_emulation_bytes, nal_size); + + bs = gf_bs_new(sei_without_emulation_bytes, sei_without_emulation_bytes_size, GF_BITSTREAM_READ); gf_bs_read_int(bs, 8); - new_buffer = (char*)malloc(sizeof(char)*nal_size); + new_buffer = (char*)gf_malloc(sizeof(char)*nal_size); new_buffer[0] = (char) hdr; written = 1; @@ -1987,7 +2472,7 @@ u32 AVC_ReformatSEI_NALU(char *buffer, u32 nal_size, AVCState *avc) } psize += gf_bs_read_int(bs, 8); - start = (u32) gf_bs_get_position(bs); + start = gf_bs_get_position(bs); do_copy = 1; switch (ptype) { /*remove SEI messages forbidden in MP4*/ @@ -1999,26 +2484,32 @@ u32 AVC_ReformatSEI_NALU(char *buffer, u32 nal_size, AVCState *avc) break; case 5: /*user unregistered */ { - u8 prev = buffer[start+2+psize]; - buffer[start+2+psize] = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[avc-h264] SEI user message %s\n", buffer+start+2)); - buffer[start+2+psize] = prev; + u8 prev = sei_without_emulation_bytes[start+2+psize]; + sei_without_emulation_bytes[start+2+psize] = 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_CODING, ("[avc-h264] SEI user message %s\n", sei_without_emulation_bytes+start+2)); + sei_without_emulation_bytes[start+2+psize] = prev; } break; case 6: /*recovery point*/ { - GF_BitStream *rp_bs = gf_bs_new(buffer + start, psize, GF_BITSTREAM_READ); + GF_BitStream *rp_bs = gf_bs_new(sei_without_emulation_bytes + start, psize, GF_BITSTREAM_READ); avc_parse_recovery_point_sei(rp_bs, avc); gf_bs_del(rp_bs); } break; - case 0: /*buffering period*/ case 1: /*pic_timing*/ + { + GF_BitStream *pt_bs = gf_bs_new(sei_without_emulation_bytes + start, psize, GF_BITSTREAM_READ); + avc_parse_pic_timing_sei(pt_bs, avc); + gf_bs_del(pt_bs); + } + break; + + case 0: /*buffering period*/ case 2: /*pan scan rect*/ case 4: /*user registered ITU t35*/ - case 7: /*def_rec_pic_marking_repetition*/ case 8: /*spare_pic*/ case 9: /*scene info*/ @@ -2028,52 +2519,55 @@ 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*/ - default:/*reserved*/ + default: /*reserved*/ break; } - /*fix payload size due to emulation prevention bytes*/ - size_fix = 0; - num_zero = 0; - if (psize%255 == 0) num_zero = 1; - - for (i = 0; i < psize + size_fix; i++) - { - if (!buffer[start + i]) - num_zero++; - else - { - if ((num_zero == 2) && (buffer[start + i] == 3)) - size_fix++; - num_zero = 0; - } - } - if (do_copy) { var = ptype; - while (var>=255) { new_buffer[written] = (char) 0xff; written++; var-=255;} - new_buffer[written] = (char) var; written++; + while (var>=255) { + new_buffer[written] = (char) 0xff; + written++; + var-=255; + } + new_buffer[written] = (char) var; + written++; var = psize; - while (var>=255) { new_buffer[written] = (char) 0xff; written++; var-=255;} - new_buffer[written] = (char) var; written++; - memcpy(new_buffer+written, buffer+start, sizeof(char)* (psize + size_fix)); - written += psize + size_fix; + while (var>=255) { + new_buffer[written] = (char) 0xff; + written++; var-=255; + } + new_buffer[written] = (char) var; + written++; + memcpy(new_buffer+written, sei_without_emulation_bytes+start, sizeof(char) * psize); + written += psize; } - gf_bs_skip_bytes(bs, (u64) (psize + size_fix)); + gf_bs_skip_bytes(bs, (u64) psize); gf_bs_align(bs); - if (gf_bs_available(bs)<2) { + if (gf_bs_available(bs)<=2) { if (gf_bs_peek_bits(bs, 8, 0)==0x80) { new_buffer[written] = (char) 0x80; written += 1; - break; } + break; } } gf_bs_del(bs); - assert(written<=nal_size); - if (written) memcpy(buffer, new_buffer, sizeof(char)*written); - free(new_buffer); + gf_free(sei_without_emulation_bytes); + + 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); + } else { + assert(written<=nal_size); + memcpy(buffer, new_buffer, sizeof(char)*written); + } + } + gf_free(new_buffer); + /*if only hdr written ignore*/ return (written>1) ? written : 0; } @@ -2087,6 +2581,7 @@ static u8 avc_get_sar_idx(u32 w, u32 h) return 0xFF; } +#ifndef GPAC_DISABLE_ISOM GF_Err AVC_ChangePAR(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d) { GF_BitStream *orig, *mod; @@ -2096,19 +2591,19 @@ GF_Err AVC_ChangePAR(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d) GF_AVCConfigSlot *slc; memset(&avc, 0, sizeof(AVCState)); + avc.sps_active_idx = -1; i=0; while ((slc = (GF_AVCConfigSlot *)gf_list_enum(avcc->sequenceParameterSets, &i))) { orig = gf_bs_new(slc->data, slc->size, GF_BITSTREAM_READ); - /*skip NALU type*/ - gf_bs_read_int(orig, 8); - idx = AVC_ReadSeqInfo(orig, &avc, &bit_offset); + idx = AVC_ReadSeqInfo(slc->data+1/*skip NALU type*/, slc->size-1, &avc, 0, &bit_offset); if (idx<0) { gf_bs_del(orig); continue; } - mod = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + gf_bs_read_data(orig, slc->data, slc->size); gf_bs_seek(orig, 0); + mod = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); /*copy over till vui flag*/ while (bit_offset) { @@ -2144,9 +2639,9 @@ GF_Err AVC_ChangePAR(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d) } /*no VUI in input bitstream, set all vui flags to 0*/ if (!flag) { - gf_bs_write_int(mod, 0, 1); /*overscan_info_present_flag */ - gf_bs_write_int(mod, 0, 1); /*video_signal_type_present_flag */ - gf_bs_write_int(mod, 0, 1); /*chroma_location_info_present_flag */ + gf_bs_write_int(mod, 0, 1); /*overscan_info_present_flag */ + gf_bs_write_int(mod, 0, 1); /*video_signal_type_present_flag */ + gf_bs_write_int(mod, 0, 1); /*chroma_location_info_present_flag */ gf_bs_write_int(mod, 0, 1); /*timing_info_present_flag*/ gf_bs_write_int(mod, 0, 1); /*nal_hrd_parameters_present*/ gf_bs_write_int(mod, 0, 1); /*vcl_hrd_parameters_present*/ @@ -2160,7 +2655,7 @@ GF_Err AVC_ChangePAR(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d) gf_bs_write_int(mod, flag, 1); } gf_bs_del(orig); - free(slc->data); + gf_free(slc->data); slc->data = NULL; gf_bs_get_content(mod, (char **) &slc->data, &flag); slc->size = flag; @@ -2168,45 +2663,34 @@ GF_Err AVC_ChangePAR(GF_AVCConfig *avcc, s32 ar_n, s32 ar_d) } return GF_OK; } +#endif GF_EXPORT GF_Err gf_avc_get_sps_info(char *sps_data, u32 sps_size, u32 *width, u32 *height, s32 *par_n, s32 *par_d) { - GF_BitStream *bs; AVCState avc; s32 idx; memset(&avc, 0, sizeof(AVCState)); + avc.sps_active_idx = -1; - bs = gf_bs_new(sps_data, sps_size, GF_BITSTREAM_READ); - /*skip NALU type*/ - gf_bs_read_int(bs, 8); - idx = AVC_ReadSeqInfo(bs, &avc, NULL); - gf_bs_del(bs); - if (idx<0) return GF_NON_COMPLIANT_BITSTREAM; + idx = AVC_ReadSeqInfo(sps_data+1/*skip NALU type*/, sps_size-1, &avc, 0, NULL); + if (idx<0) { + return GF_NON_COMPLIANT_BITSTREAM; + } if (width) *width = avc.sps[idx].width; if (height) *height = avc.sps[idx].height; - if (par_n) *par_n = avc.sps[idx].par_num ? avc.sps[idx].par_num : (u32) -1; - if (par_d) *par_d = avc.sps[idx].par_den ? avc.sps[idx].par_den : (u32) -1; + if (par_n) *par_n = avc.sps[idx].vui.par_num ? avc.sps[idx].vui.par_num : (u32) -1; + if (par_d) *par_d = avc.sps[idx].vui.par_den ? avc.sps[idx].vui.par_den : (u32) -1; + return GF_OK; } -#endif +#endif /*GPAC_DISABLE_AV_PARSERS*/ + -GF_EXPORT -const char *gf_avc_get_profile_name(u8 video_prof) -{ - switch (video_prof) { - case 0x42: return "Baseline"; - case 0x4D: return "Main"; - case 0x58: return "Extended"; - case 0x64: return "High"; - case 0x6E: return "High 10"; - case 0x7A: return "High 4:2:2"; - case 0x90: return "High 4:4:4"; - default: return "Unknown"; - } -} + +#ifndef GPAC_DISABLE_AV_PARSERS static u32 AC3_FindSyncCode(u8 *buf, u32 buflen) { @@ -2225,8 +2709,8 @@ static u32 AC3_FindSyncCode(u8 *buf, u32 buflen) static Bool AC3_FindSyncCodeBS(GF_BitStream *bs) { u8 b1; - u32 pos = (u32) gf_bs_get_position(bs); - u32 end = (u32) gf_bs_get_size(bs) - 6; + u64 pos = gf_bs_get_position(bs); + u64 end = gf_bs_get_size(bs) - 6; pos += 1; b1 = gf_bs_read_u8(bs); @@ -2265,6 +2749,18 @@ static const u32 ac3_mod_to_chans[] = { 2, 1, 2, 3, 3, 4, 4, 5 }; +u32 gf_ac3_get_channels(u32 acmod) +{ + u32 nb_ch; + nb_ch = ac3_mod_to_chans[acmod]; + return nb_ch; +} + +u32 gf_ac3_get_bitrate(u32 brcode) +{ + return ac3_sizecod_to_bitrate[brcode]; +} + Bool gf_ac3_parser(u8 *buf, u32 buflen, u32 *pos, GF_AC3Header *hdr, Bool full_parse) { u32 fscod, frmsizecod, bsid, ac3_mod, freq, framesize; @@ -2299,7 +2795,7 @@ Bool gf_ac3_parser(u8 *buf, u32 buflen, u32 *pos, GF_AC3Header *hdr, Bool full_p framesize = ac3_sizecod2_to_framesize[frmsizecod / 2] * 2; break; default: - return 0; + return 0; } if (hdr) { u16 maskbit, b67; @@ -2320,11 +2816,12 @@ Bool gf_ac3_parser(u8 *buf, u32 buflen, u32 *pos, GF_AC3Header *hdr, Bool full_p Bool gf_ac3_parser_bs(GF_BitStream *bs, GF_AC3Header *hdr, Bool full_parse) { - u32 fscod, frmsizecod, bsid, ac3_mod, freq, framesize, pos, bsmod; + u32 fscod, frmsizecod, bsid, ac3_mod, freq, framesize, bsmod; + u64 pos; if (!hdr || (gf_bs_available(bs) < 6)) return 0; if (!AC3_FindSyncCodeBS(bs)) return 0; - pos = (u32) gf_bs_get_position(bs); + pos = gf_bs_get_position(bs); gf_bs_read_u32(bs); fscod = gf_bs_read_int(bs, 2); frmsizecod = gf_bs_read_int(bs, 6); @@ -2353,7 +2850,7 @@ Bool gf_ac3_parser_bs(GF_BitStream *bs, GF_AC3Header *hdr, Bool full_parse) framesize = ac3_sizecod2_to_framesize[frmsizecod / 2] * 2; break; default: - return 0; + return 0; } hdr->sample_rate = freq; hdr->framesize = framesize; @@ -2364,7 +2861,7 @@ Bool gf_ac3_parser_bs(GF_BitStream *bs, GF_AC3Header *hdr, Bool full_parse) hdr->acmod = ac3_mod; hdr->lfon = 0; hdr->fscod = fscod; - hdr->brcode = hdr->bitrate/1000; + hdr->brcode = frmsizecod / 2; } hdr->channels = ac3_mod_to_chans[ac3_mod]; @@ -2382,8 +2879,11 @@ Bool gf_ac3_parser_bs(GF_BitStream *bs, GF_AC3Header *hdr, Bool full_parse) return 1; } +#endif /*GPAC_DISABLE_AV_PARSERS*/ +#if !defined(GPAC_DISABLE_AV_PARSERS) && !defined (GPAC_DISABLE_OGG) + /* Vorbis parser */ @@ -2537,12 +3037,12 @@ Bool gf_vorbis_parse_header(GF_VorbisParser *vp, char *data, u32 data_len) u32 *parts, *class_dims, count, rangebits; u32 max_class = 0; nb_part = oggpack_read(&opb, 5); - parts = (u32*)malloc(sizeof(u32) * nb_part); + parts = (u32*)gf_malloc(sizeof(u32) * nb_part); for (j=0;j<nb_part;j++) { parts[j] = oggpack_read(&opb, 4); if (max_class<parts[j]) max_class = parts[j]; } - class_dims = (u32*)malloc(sizeof(u32) * (max_class+1)); + class_dims = (u32*)gf_malloc(sizeof(u32) * (max_class+1)); for (j=0; j<max_class+1;j++) { u32 class_sub; class_dims[j] = oggpack_read(&opb, 3) + 1; @@ -2557,8 +3057,8 @@ Bool gf_vorbis_parse_header(GF_VorbisParser *vp, char *data, u32 data_len) count+=class_dims[parts[j]]; for (;k<count;k++) oggpack_read(&opb, rangebits); } - free(parts); - free(class_dims); + gf_free(parts); + gf_free(class_dims); } else { u32 j, nb_books; oggpack_read(&opb, 8+16+16+6+8); @@ -2634,3 +3134,6 @@ u32 gf_vorbis_check_frame(GF_VorbisParser *vp, char *data, u32 data_length) if (block_size == -1) return 0; return ((vp->mode_flag[block_size]) ? vp->max_block : vp->min_block) / (2); } + +#endif /*!defined(GPAC_DISABLE_AV_PARSERS) && !defined (GPAC_DISABLE_OGG)*/ + diff --git a/src/media_tools/avilib.c b/src/media_tools/avilib.c index 21c01db..f220bdd 100644 --- a/src/media_tools/avilib.c +++ b/src/media_tools/avilib.c @@ -2,33 +2,34 @@ * avilib.c * * Copyright (C) Thomas Östreich - June 2001 - * multiple audio track support Copyright (C) 2002 Thomas Östreich + * multiple audio track support Copyright (C) 2002 Thomas Östreich * * Original code: - * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de> + * Copyright (C) 1999 Rainer Johanni <Rainer@Johanni.de> * * This file is part of transcode, a linux video stream processing tool - * + * * transcode 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. - * + * * transcode 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <gpac/setup.h> -#include <gpac/internal/avilib.h> -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_AVILIB + +#include <gpac/internal/avilib.h> #define PACKAGE "GPAC/avilib" @@ -65,7 +66,7 @@ static char id_str[MAX_INFO_STRLEN]; static u32 avi_read(FILE *fd, char *buf, u32 len) { - u32 n = 0; + s32 n = 0; u32 r = 0; while (r < len) { @@ -80,14 +81,14 @@ static u32 avi_read(FILE *fd, char *buf, u32 len) static u32 avi_write (FILE *fd, char *buf, u32 len) { - u32 n = 0; + s32 n = 0; u32 r = 0; while (r < len) { n = fwrite (buf + r, 1, len - r, fd); if (n < 0) return n; - + r += n; } return r; @@ -171,7 +172,7 @@ static int avi_sampsize(avi_t *AVI, int j) int s; s = ((AVI->track[j].a_bits+7)/8)*AVI->track[j].a_chans; // if(s==0) s=1; /* avoid possible zero divisions */ - if(s<4) s=4; /* avoid possible zero divisions */ + if(s<4) s=4; /* avoid possible zero divisions */ return s; } @@ -182,7 +183,7 @@ static int avi_add_chunk(avi_t *AVI, unsigned char *tag, unsigned char *data, u3 { unsigned char c[8]; char p=0; - + /* Copy tag and length int c, so that we need only 1 write system call for these two values */ @@ -216,12 +217,12 @@ static int avi_add_chunk(avi_t *AVI, unsigned char *tag, unsigned char *data, u3 #define OUTS(s) memcpy(ix00+bl,s,4); bl+=4 // this does the physical writeout of the ix## structure -static int avi_ixnn_entry(avi_t *AVI, avistdindex_chunk *ch, avisuperindex_entry *en) +static int avi_ixnn_entry(avi_t *AVI, avistdindex_chunk *ch, avisuperindex_entry *en) { int bl; u32 k; unsigned int max = ch->nEntriesInUse * sizeof (u32) * ch->wLongsPerEntry + 24; // header - char *ix00 = (char *)malloc (max); + char *ix00 = (char *)gf_malloc (max); char dfcc[5]; memcpy (dfcc, ch->fcc, 4); dfcc[4] = 0; @@ -256,7 +257,7 @@ static int avi_ixnn_entry(avi_t *AVI, avistdindex_chunk *ch, avisuperindex_entry } avi_add_chunk (AVI, (unsigned char*)ch->fcc, (unsigned char*)ix00, max); - free(ix00); + gf_free(ix00); return 0; } @@ -272,7 +273,7 @@ static int avi_init_super_index(avi_t *AVI, unsigned char *idxtag, avisuperindex avisuperindex_chunk *sil = NULL; - if ((sil = (avisuperindex_chunk *) malloc (sizeof (avisuperindex_chunk))) == NULL) { + if ((sil = (avisuperindex_chunk *) gf_malloc (sizeof (avisuperindex_chunk))) == NULL) { AVI_errno = AVI_ERR_NO_MEM; return -1; } @@ -286,20 +287,20 @@ static int avi_init_super_index(avi_t *AVI, unsigned char *idxtag, avisuperindex memset (sil->dwReserved, 0, sizeof (sil->dwReserved)); // NR_IXNN_CHUNKS == allow 32 indices which means 32 GB files -- arbitrary - sil->aIndex = (avisuperindex_entry *) malloc (sil->wLongsPerEntry * NR_IXNN_CHUNKS * sizeof (void*)); + sil->aIndex = (avisuperindex_entry *) gf_malloc (sil->wLongsPerEntry * NR_IXNN_CHUNKS * sizeof (void*)); if (!sil->aIndex) { AVI_errno = AVI_ERR_NO_MEM; return -1; } memset (sil->aIndex, 0, sil->wLongsPerEntry * NR_IXNN_CHUNKS * sizeof (u32)); - sil->stdindex = (avistdindex_chunk **)malloc (NR_IXNN_CHUNKS * sizeof (avistdindex_chunk *)); + sil->stdindex = (avistdindex_chunk **)gf_malloc (NR_IXNN_CHUNKS * sizeof (avistdindex_chunk *)); if (!sil->stdindex) { AVI_errno = AVI_ERR_NO_MEM; return -1; } for (k = 0; k < NR_IXNN_CHUNKS; k++) { - sil->stdindex[k] = (avistdindex_chunk *) malloc (sizeof (avistdindex_chunk)); + sil->stdindex[k] = (avistdindex_chunk *) gf_malloc (sizeof (avistdindex_chunk)); // gets rewritten later sil->stdindex[k]->qwBaseOffset = (u64)k * NEW_RIFF_THRES; sil->stdindex[k]->aIndex = NULL; @@ -315,7 +316,7 @@ static int avi_add_std_index(avi_t *AVI, unsigned char *idxtag, unsigned char *s avistdindex_chunk *stdil) { - memcpy (stdil->fcc, idxtag, 4); + memcpy (stdil->fcc, idxtag, 4); stdil->dwSize = 4096; stdil->wLongsPerEntry = 2; //sizeof(avistdindex_entry)/sizeof(u32); stdil->bIndexSubType = 0; @@ -327,7 +328,7 @@ static int avi_add_std_index(avi_t *AVI, unsigned char *idxtag, unsigned char *s //stdil->qwBaseOffset = AVI->video_superindex->aIndex[ cur_std_idx ]->qwOffset; - stdil->aIndex = (avistdindex_entry *)malloc(stdil->dwSize * sizeof (u32) * stdil->wLongsPerEntry); + stdil->aIndex = (avistdindex_entry *)gf_malloc(stdil->dwSize * sizeof (u32) * stdil->wLongsPerEntry); if (!stdil->aIndex) { AVI_errno = AVI_ERR_NO_MEM; @@ -338,7 +339,7 @@ static int avi_add_std_index(avi_t *AVI, unsigned char *idxtag, unsigned char *s return 0; } -static int avi_add_odml_index_entry_core(avi_t *AVI, long flags, u64 pos, unsigned long len, avistdindex_chunk *si) +static int avi_add_odml_index_entry_core(avi_t *AVI, long flags, u64 pos, unsigned long len, avistdindex_chunk *si) { u32 cur_chunk_idx; // put new chunk into index @@ -348,7 +349,7 @@ static int avi_add_odml_index_entry_core(avi_t *AVI, long flags, u64 pos, unsign // need to fetch more memory if (cur_chunk_idx >= si->dwSize) { si->dwSize += 4096; - si->aIndex = (avistdindex_entry *)realloc ( si->aIndex, si->dwSize * sizeof (u32) * si->wLongsPerEntry); + si->aIndex = (avistdindex_entry *)gf_realloc ( si->aIndex, si->dwSize * sizeof (u32) * si->wLongsPerEntry); } if(len>AVI->max_len) AVI->max_len=len; @@ -366,7 +367,7 @@ static int avi_add_odml_index_entry_core(avi_t *AVI, long flags, u64 pos, unsign return 0; } -static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, u64 pos, unsigned long len) +static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, u64 pos, unsigned long len) { char fcc[5]; @@ -384,7 +385,7 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, AVI->video_superindex->nEntriesInUse++; cur_std_idx = AVI->video_superindex->nEntriesInUse-1; - if (avi_add_std_index (AVI, (unsigned char *)"ix00", (unsigned char *)"00db", AVI->video_superindex->stdindex[ cur_std_idx ]) < 0) + if (avi_add_std_index (AVI, (unsigned char *)"ix00", (unsigned char *)"00db", AVI->video_superindex->stdindex[ cur_std_idx ]) < 0) return -1; } // init @@ -404,7 +405,7 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, AVI->track[AVI->aptr].audio_superindex->nEntriesInUse++; sprintf(fcc, "ix%02d", AVI->aptr+1); - if (avi_add_std_index (AVI, (unsigned char *)fcc, tag, AVI->track[AVI->aptr].audio_superindex->stdindex[ + if (avi_add_std_index (AVI, (unsigned char *)fcc, tag, AVI->track[AVI->aptr].audio_superindex->stdindex[ AVI->track[AVI->aptr].audio_superindex->nEntriesInUse - 1 ]) < 0 ) return -1; } // init @@ -415,7 +416,7 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, if (AVI->video_superindex) { cur_std_idx = AVI->video_superindex->nEntriesInUse-1; - towrite += AVI->video_superindex->stdindex[cur_std_idx]->nEntriesInUse*8 + towrite += AVI->video_superindex->stdindex[cur_std_idx]->nEntriesInUse*8 + 4+4+2+1+1+4+4+8+4; if (cur_std_idx == 0) { towrite += AVI->n_idx*16 + 8; @@ -426,15 +427,15 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, for (audtr=0; audtr<AVI->anum; audtr++) { if (AVI->track[audtr].audio_superindex) { cur_std_idx = AVI->track[audtr].audio_superindex->nEntriesInUse-1; - towrite += AVI->track[audtr].audio_superindex->stdindex[cur_std_idx]->nEntriesInUse*8 + towrite += AVI->track[audtr].audio_superindex->stdindex[cur_std_idx]->nEntriesInUse*8 + 4+4+2+1+1+4+4+8+4; } } towrite += len + (len&1) + 8; - //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] ODML: towrite = 0x%llX = %lld\n", towrite, towrite)); + //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] ODML: towrite = 0x%llX = %"LLD"\n", towrite, towrite)); - if (AVI->video_superindex && + if (AVI->video_superindex && (s64)(AVI->pos+towrite) > (s64)((s64)NEW_RIFF_THRES*AVI->video_superindex->nEntriesInUse)) { GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] Adding a new RIFF chunk: %d\n", AVI->video_superindex->nEntriesInUse)); @@ -446,12 +447,12 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, if (AVI->video_superindex->nEntriesInUse > NR_IXNN_CHUNKS) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Internal error in avilib - redefine NR_IXNN_CHUNKS\n")); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] cur_std_idx=%d NR_IXNN_CHUNKS=%d" - "POS=%lld towrite=%lld\n", + "POS=%"LLD" towrite=%"LLD"\n", cur_std_idx,NR_IXNN_CHUNKS, AVI->pos, towrite)); return -1; } - if (avi_add_std_index (AVI, (unsigned char *)"ix00", (unsigned char *)"00db", AVI->video_superindex->stdindex[ cur_std_idx ]) < 0) + if (avi_add_std_index (AVI, (unsigned char *)"ix00", (unsigned char *)"00db", AVI->video_superindex->stdindex[ cur_std_idx ]) < 0) return -1; for (audtr = 0; audtr < AVI->anum; audtr++) { @@ -464,7 +465,7 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, sprintf(fcc, "ix%02d", audtr+1); sprintf(aud, "0%01dwb", audtr+1); - if (avi_add_std_index (AVI, (unsigned char *)fcc, (unsigned char *)aud, AVI->track[audtr].audio_superindex->stdindex[ + if (avi_add_std_index (AVI, (unsigned char *)fcc, (unsigned char *)aud, AVI->track[audtr].audio_superindex->stdindex[ AVI->track[audtr].audio_superindex->nEntriesInUse - 1 ]) < 0 ) return -1; } @@ -473,9 +474,9 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, if (cur_std_idx > 0) { // dump the _previous_ == already finished index - avi_ixnn_entry (AVI, AVI->video_superindex->stdindex[cur_std_idx - 1], + avi_ixnn_entry (AVI, AVI->video_superindex->stdindex[cur_std_idx - 1], &AVI->video_superindex->aIndex[cur_std_idx - 1]); - AVI->video_superindex->aIndex[cur_std_idx - 1].dwDuration = + AVI->video_superindex->aIndex[cur_std_idx - 1].dwDuration = AVI->video_superindex->stdindex[cur_std_idx - 1]->nEntriesInUse - 1; for (audtr = 0; audtr < AVI->anum; audtr++) { @@ -484,13 +485,13 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, // not initialized -> no index continue; } - avi_ixnn_entry (AVI, AVI->track[audtr].audio_superindex->stdindex[cur_std_idx - 1], + avi_ixnn_entry (AVI, AVI->track[audtr].audio_superindex->stdindex[cur_std_idx - 1], &AVI->track[audtr].audio_superindex->aIndex[cur_std_idx - 1]); - AVI->track[audtr].audio_superindex->aIndex[cur_std_idx - 1].dwDuration = + AVI->track[audtr].audio_superindex->aIndex[cur_std_idx - 1].dwDuration = AVI->track[audtr].audio_superindex->stdindex[cur_std_idx - 1]->nEntriesInUse - 1; if (AVI->track[audtr].a_fmt == 0x1) { - AVI->track[audtr].audio_superindex->aIndex[cur_std_idx - 1].dwDuration *= + AVI->track[audtr].audio_superindex->aIndex[cur_std_idx - 1].dwDuration *= AVI->track[audtr].a_bits*AVI->track[audtr].a_rate*AVI->track[audtr].a_chans/800; } } @@ -510,9 +511,9 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, for (audtr = 0; audtr < AVI->anum; audtr++) { if (AVI->track[audtr].audio_superindex) - AVI->track[audtr].audio_superindex->stdindex[ cur_std_idx ]->qwBaseOffset = + AVI->track[audtr].audio_superindex->stdindex[ cur_std_idx ]->qwBaseOffset = AVI->pos -16 -8; - + } // now we can be sure @@ -523,15 +524,15 @@ static int avi_add_odml_index_entry(avi_t *AVI, unsigned char *tag, long flags, if (video) { - avi_add_odml_index_entry_core(AVI, flags, AVI->pos, len, + avi_add_odml_index_entry_core(AVI, flags, AVI->pos, len, AVI->video_superindex->stdindex[ AVI->video_superindex->nEntriesInUse-1 ]); AVI->total_frames++; } // video if (audio) { - avi_add_odml_index_entry_core(AVI, flags, AVI->pos, len, - AVI->track[AVI->aptr].audio_superindex->stdindex[ + avi_add_odml_index_entry_core(AVI, flags, AVI->pos, len, + AVI->track[AVI->aptr].audio_superindex->stdindex[ AVI->track[AVI->aptr].audio_superindex->nEntriesInUse-1 ]); } @@ -546,8 +547,8 @@ static int avi_add_index_entry(avi_t *AVI, unsigned char *tag, long flags, u64 p void *ptr; if(AVI->n_idx>=AVI->max_idx) { - ptr = realloc((void *)AVI->idx,(AVI->max_idx+4096)*16); - + ptr = gf_realloc((void *)AVI->idx,(AVI->max_idx+4096)*16); + if(ptr == 0) { AVI_errno = AVI_ERR_NO_MEM; return -1; @@ -555,7 +556,7 @@ static int avi_add_index_entry(avi_t *AVI, unsigned char *tag, long flags, u64 p AVI->max_idx += 4096; AVI->idx = (unsigned char((*)[16]) ) ptr; } - + /* Add index entry */ // GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] INDEX %s %ld %lu %lu\n", tag, flags, pos, len)); @@ -564,7 +565,7 @@ static int avi_add_index_entry(avi_t *AVI, unsigned char *tag, long flags, u64 p long2str(AVI->idx[AVI->n_idx]+ 4,flags); long2str(AVI->idx[AVI->n_idx]+ 8, (s32) pos); long2str(AVI->idx[AVI->n_idx]+12, (s32) len); - + /* Update counter */ AVI->n_idx++; @@ -579,16 +580,16 @@ int AVI_can_read_audio(avi_t *AVI) { if(AVI->mode==AVI_MODE_WRITE) { return -1; } if(!AVI->video_index) { return -1; } - if(!AVI->track[AVI->aptr].audio_index) { return -1; } + if(!AVI->track[AVI->aptr].audio_index) { return -1; } - // is it -1? the last ones got left out --tibit + // is it -1? the last ones got left out --tibit //if (AVI->track[AVI->aptr].audio_posc>=AVI->track[AVI->aptr].audio_chunks-1) { if (AVI->track[AVI->aptr].audio_posc>=AVI->track[AVI->aptr].audio_chunks) { return 0; } if (AVI->video_pos >= AVI->video_frames) return 1; - + if (AVI->track[AVI->aptr].audio_index[AVI->track[AVI->aptr].audio_posc].pos < AVI->video_index[AVI->video_pos].pos) return 1; else return 0; } @@ -609,7 +610,7 @@ avi_t* AVI_open_output_file(char * filename) /* Allocate the avi_t struct and zero it */ - AVI = (avi_t *) malloc(sizeof(avi_t)); + AVI = (avi_t *) gf_malloc(sizeof(avi_t)); if(AVI==0) { AVI_errno = AVI_ERR_NO_MEM; @@ -621,7 +622,7 @@ avi_t* AVI_open_output_file(char * filename) if (!AVI->fdes ) { AVI_errno = AVI_ERR_OPEN; - free(AVI); + gf_free(AVI); return 0; } @@ -634,7 +635,7 @@ avi_t* AVI_open_output_file(char * filename) { fclose(AVI->fdes); AVI_errno = AVI_ERR_WRITE; - free(AVI); + gf_free(AVI); return 0; } @@ -658,13 +659,13 @@ void AVI_set_video(avi_t *AVI, int width, int height, double fps, char *compress AVI->width = width; AVI->height = height; AVI->fps = fps; - + if(strncmp(compressor, "RGB", 3)==0) { memset(AVI->compressor, 0, 4); } else { memcpy(AVI->compressor,compressor,4); - } - + } + AVI->compressor[4] = 0; avi_update_header(AVI); @@ -777,7 +778,7 @@ int avi_update_header(avi_t *AVI) OUT4CC ("avih"); OUTLONG(56); /* # of bytes to follow */ OUTLONG(ms_per_frame); /* Microseconds per frame */ - //ThOe ->0 + //ThOe ->0 // OUTLONG(10000000); /* MaxBytesPerSec, I hope this will never be used */ OUTLONG(0); OUTLONG(0); /* PaddingGranularity (whatever that might be) */ @@ -860,33 +861,33 @@ int avi_update_header(avi_t *AVI) long2str(AVI_header+strl_start-4,nhb-strl_start); - + /* Start the audio stream list ---------------------------------- */ - + for(j=0; j<AVI->anum; ++j) { - + sampsize = avi_sampsize(AVI, j); - + OUT4CC ("LIST"); OUTLONG(0); /* Length of list in bytes, don't know yet */ strl_start = nhb; /* Store start position */ OUT4CC ("strl"); - + /* The audio stream header */ - + OUT4CC ("strh"); OUTLONG(56); /* # of bytes to follow */ OUT4CC ("auds"); - + // ----------- // ThOe OUTLONG(0); /* Format (Optionally) */ // ----------- - + OUTLONG(0); /* Flags */ OUTLONG(0); /* Reserved, MS says: wPriority, wLanguage */ OUTLONG(0); /* InitialFrames */ - + // ThOe /4 OUTLONG(sampsize/4); /* Scale */ OUTLONG(1000*AVI->track[j].mp3rate/8); @@ -894,17 +895,17 @@ int avi_update_header(avi_t *AVI) OUTLONG(4*AVI->track[j].audio_bytes/sampsize); /* Length */ OUTLONG(0); /* SuggestedBufferSize */ OUTLONG(-1); /* Quality */ - + // ThOe /4 OUTLONG(sampsize/4); /* SampleSize */ - + OUTLONG(0); /* Frame */ OUTLONG(0); /* Frame */ // OUTLONG(0); /* Frame */ //OUTLONG(0); /* Frame */ - + /* The audio stream format */ - + OUT4CC ("strf"); OUTLONG(16); /* # of bytes to follow */ OUTSHRT(AVI->track[j].a_fmt); /* Format */ @@ -913,40 +914,40 @@ int avi_update_header(avi_t *AVI) // ThOe OUTLONG(1000*AVI->track[j].mp3rate/8); //ThOe (/4) - + OUTSHRT(sampsize/4); /* BlockAlign */ - - + + OUTSHRT(AVI->track[j].a_bits); /* BitsPerSample */ - + /* Finish stream list, i.e. put number of bytes in the list to proper pos */ - + long2str(AVI_header+strl_start-4,nhb-strl_start); } - + /* Finish header list */ - + long2str(AVI_header+hdrl_start-4,nhb-hdrl_start); - - + + /* Calculate the needed amount of junk bytes, output junk */ - + njunk = HEADERBYTES - nhb - 8 - 12; - + /* Safety first: if njunk <= 0, somebody has played with HEADERBYTES without knowing what (s)he did. This is a fatal error */ - + if(njunk<=0) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] AVI_close_output_file: # of header bytes too small\n")); exit(1); } - + OUT4CC ("JUNK"); OUTLONG(njunk); memset(AVI_header+nhb,0,njunk); - + nhb += njunk; /* Start the movi list */ @@ -958,10 +959,10 @@ int avi_update_header(avi_t *AVI) /* Output the header, truncate the file to the number of bytes actually written, report an error if someting goes wrong */ - if ( gf_f64_seek(AVI->fdes,0,SEEK_SET)<0 || + if ( (gf_f64_seek(AVI->fdes, 0, SEEK_SET) ==(u64)-1) || avi_write(AVI->fdes,(char *)AVI_header,HEADERBYTES)!=HEADERBYTES || - gf_f64_seek(AVI->fdes,AVI->pos,SEEK_SET)<0) - { + (gf_f64_seek(AVI->fdes,AVI->pos,SEEK_SET)==(u64)-1) + ) { AVI_errno = AVI_ERR_CLOSE; return -1; } @@ -1018,10 +1019,10 @@ static int avi_close_output_file(avi_t *AVI) #ifdef DEBUG_ODML GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] ODML dump the rest indices\n")); #endif - avi_ixnn_entry (AVI, AVI->video_superindex->stdindex[cur_std_idx], + avi_ixnn_entry (AVI, AVI->video_superindex->stdindex[cur_std_idx], &AVI->video_superindex->aIndex[cur_std_idx]); - AVI->video_superindex->aIndex[cur_std_idx].dwDuration = + AVI->video_superindex->aIndex[cur_std_idx].dwDuration = AVI->video_superindex->stdindex[cur_std_idx]->nEntriesInUse - 1; for (audtr = 0; audtr < AVI->anum; audtr++) { @@ -1029,16 +1030,16 @@ static int avi_close_output_file(avi_t *AVI) // not initialized -> no index continue; } - avi_ixnn_entry (AVI, AVI->track[audtr].audio_superindex->stdindex[cur_std_idx], + avi_ixnn_entry (AVI, AVI->track[audtr].audio_superindex->stdindex[cur_std_idx], &AVI->track[audtr].audio_superindex->aIndex[cur_std_idx]); - AVI->track[audtr].audio_superindex->aIndex[cur_std_idx].dwDuration = + AVI->track[audtr].audio_superindex->aIndex[cur_std_idx].dwDuration = AVI->track[audtr].audio_superindex->stdindex[cur_std_idx]->nEntriesInUse - 1; if (AVI->track[audtr].a_fmt == 0x1) { - AVI->track[audtr].audio_superindex->aIndex[cur_std_idx].dwDuration *= + AVI->track[audtr].audio_superindex->aIndex[cur_std_idx].dwDuration *= AVI->track[audtr].a_bits*AVI->track[audtr].a_rate*AVI->track[audtr].a_chans/800; } } - // The AVI->video_superindex->nEntriesInUse contains the offset + // The AVI->video_superindex->nEntriesInUse contains the offset AVI->video_superindex->stdindex[ cur_std_idx+1 ]->qwBaseOffset = AVI->pos; } @@ -1068,7 +1069,7 @@ static int avi_close_output_file(avi_t *AVI) AVI_errno = AVI_ERR_WRITE_INDEX; } } - + /* Calculate Microseconds per frame */ if(AVI->fps < 0.001) { @@ -1115,7 +1116,7 @@ static int avi_close_output_file(avi_t *AVI) OUT4CC ("avih"); OUTLONG(56); /* # of bytes to follow */ OUTLONG(ms_per_frame); /* Microseconds per frame */ - //ThOe ->0 + //ThOe ->0 // OUTLONG(10000000); /* MaxBytesPerSec, I hope this will never be used */ OUTLONG(0); OUTLONG(0); /* PaddingGranularity (whatever that might be) */ @@ -1233,24 +1234,24 @@ static int avi_close_output_file(avi_t *AVI) /* Start the audio stream list ---------------------------------- */ for(j=0; j<AVI->anum; ++j) { - + //if (AVI->track[j].a_chans && AVI->track[j].audio_bytes) { unsigned long nBlockAlign = 0; unsigned long avgbsec = 0; unsigned long scalerate = 0; - + sampsize = avi_sampsize(AVI, j); sampsize = AVI->track[j].a_fmt==0x1?sampsize*4:sampsize; nBlockAlign = (AVI->track[j].a_rate<32000)?576:1152; /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] XXX sampsize (%d) block (%ld) rate (%ld) audio_bytes (%ld) mp3rate(%ld,%ld)\n", - sampsize, nBlockAlign, AVI->track[j].a_rate, - (long int)AVI->track[j].audio_bytes, + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] XXX sampsize (%d) block (%ld) rate (%ld) audio_bytes (%ld) mp3rate(%ld,%ld)\n", + sampsize, nBlockAlign, AVI->track[j].a_rate, + (long int)AVI->track[j].audio_bytes, 1000*AVI->track[j].mp3rate/8, AVI->track[j].mp3rate)); */ - + if (AVI->track[j].a_fmt==0x1) { sampsize = (AVI->track[j].a_chans<2)?sampsize/2:sampsize; avgbsec = AVI->track[j].a_rate*sampsize/4; @@ -1264,23 +1265,23 @@ static int avi_close_output_file(avi_t *AVI) OUTLONG(0); /* Length of list in bytes, don't know yet */ strl_start = nhb; /* Store start position */ OUT4CC ("strl"); - + /* The audio stream header */ - + OUT4CC ("strh"); OUTLONG(56); /* # of bytes to follow */ OUT4CC ("auds"); - + // ----------- // ThOe OUTLONG(0); /* Format (Optionally) */ // ----------- - + OUTLONG(0); /* Flags */ OUTLONG(0); /* Reserved, MS says: wPriority, wLanguage */ OUTLONG(0); /* InitialFrames */ - - // VBR + + // VBR if (AVI->track[j].a_fmt == 0x55 && AVI->track[j].a_vbr) { OUTLONG(nBlockAlign); /* Scale */ OUTLONG(AVI->track[j].a_rate); /* Rate */ @@ -1302,11 +1303,11 @@ static int avi_close_output_file(avi_t *AVI) OUTLONG(0); /* Frame */ OUTLONG(0); /* Frame */ } - + /* The audio stream format */ OUT4CC ("strf"); - + if (AVI->track[j].a_fmt == 0x55 && AVI->track[j].a_vbr) { OUTLONG(30); /* # of bytes to follow */ // mplayer writes 28 @@ -1324,7 +1325,7 @@ static int avi_close_output_file(avi_t *AVI) OUTSHRT(nBlockAlign); /* nBlockSize */ // 2 OUTSHRT(1); /* nFramesPerBlock */ // 2 OUTSHRT(0); /* nCodecDelay */ // 2 - + } else if (AVI->track[j].a_fmt == 0x55 && !AVI->track[j].a_vbr) { OUTLONG(30); /* # of bytes to follow */ @@ -1342,7 +1343,7 @@ static int avi_close_output_file(avi_t *AVI) OUTSHRT(nBlockAlign); /* nBlockSize */ OUTSHRT(1); /* nFramesPerBlock */ OUTSHRT(0); /* nCodecDelay */ - + } else { OUTLONG(18); /* # of bytes to follow */ @@ -1353,13 +1354,13 @@ static int avi_close_output_file(avi_t *AVI) OUTLONG(avgbsec); /* Avg bytes/sec */ OUTSHRT(sampsize/4); /* BlockAlign */ OUTSHRT(AVI->track[j].a_bits); /* BitsPerSample */ - OUTSHRT(0); /* cbSize */ + OUTSHRT(0); /* cbSize */ } } if (AVI->is_opendml) { u32 k; - + if (!AVI->track[j].audio_superindex) { // not initialized -> no index continue; @@ -1379,7 +1380,7 @@ static int avi_close_output_file(avi_t *AVI) u32 s = (u32) ((AVI->track[j].audio_superindex->aIndex[k].qwOffset) & 0xffffffff); /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] AUD[%d] NrEntries %d/%ld (%c%c%c%c) |0x%llX|%ld|%ld| \n", j, k, + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] AUD[%d] NrEntries %d/%ld (%c%c%c%c) |0x%llX|%ld|%ld| \n", j, k, AVI->track[j].audio_superindex->nEntriesInUse, AVI->track[j].audio_superindex->dwChunkId[0], AVI->track[j].audio_superindex->dwChunkId[1], AVI->track[j].audio_superindex->dwChunkId[2], AVI->track[j].audio_superindex->dwChunkId[3], @@ -1407,9 +1408,9 @@ static int avi_close_output_file(avi_t *AVI) OUTLONG(4); OUTLONG(AVI->total_frames); } - + /* Finish header list */ - + long2str(AVI_header+hdrl_start-4,nhb-hdrl_start); @@ -1417,7 +1418,7 @@ static int avi_close_output_file(avi_t *AVI) #ifdef INFO_LIST OUT4CC ("LIST"); - + info_start_pos = nhb; info_len = MAX_INFO_STRLEN + 12; OUTLONG(info_len); // rewritten later @@ -1447,7 +1448,7 @@ static int avi_close_output_file(avi_t *AVI) // OUT4CC ("ICMT"); // OUTLONG(MAX_INFO_STRLEN); -// calptr=time(NULL); +// calptr=time(NULL); // sprintf(id_str, "\t%s %s", ctime(&calptr), ""); // memset(AVI_header+nhb, 0, MAX_INFO_STRLEN); // memcpy(AVI_header+nhb, id_str, 25); @@ -1455,15 +1456,15 @@ static int avi_close_output_file(avi_t *AVI) #endif // ---------------------------- - + /* Calculate the needed amount of junk bytes, output junk */ - + njunk = HEADERBYTES - nhb - 8 - 12; - + /* Safety first: if njunk <= 0, somebody has played with HEADERBYTES without knowing what (s)he did. This is a fatal error */ - + if(njunk<=0) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] AVI_close_output_file: # of header bytes too small\n")); @@ -1473,7 +1474,7 @@ static int avi_close_output_file(avi_t *AVI) OUT4CC ("JUNK"); OUTLONG(njunk); memset(AVI_header+nhb,0,njunk); - + nhb += njunk; /* Start the movi list */ @@ -1485,9 +1486,9 @@ static int avi_close_output_file(avi_t *AVI) /* Output the header, truncate the file to the number of bytes actually written, report an error if someting goes wrong */ - if ( gf_f64_seek(AVI->fdes,0,SEEK_SET)<0 || - avi_write(AVI->fdes,(char *)AVI_header,HEADERBYTES)!=HEADERBYTES -// || ftruncate(AVI->fdes,AVI->pos)<0 + if ( (gf_f64_seek(AVI->fdes,0,SEEK_SET)==(u64)-1) || + avi_write(AVI->fdes,(char *)AVI_header,HEADERBYTES)!=HEADERBYTES +// || ftruncate(AVI->fdes,AVI->pos)<0 ) { AVI_errno = AVI_ERR_CLOSE; @@ -1500,7 +1501,7 @@ static int avi_close_output_file(avi_t *AVI) u32 k; char f[4]; u32 len; - + for (k=1; k<AVI->video_superindex->nEntriesInUse; k++) { // the len of the RIFF Chunk gf_f64_seek(AVI->fdes, AVI->video_superindex->stdindex[k]->qwBaseOffset+4, SEEK_SET); @@ -1537,20 +1538,20 @@ static int avi_write_data(avi_t *AVI, char *data, unsigned long length, int audi int n = 0; unsigned char astr[5]; - - // transcode core itself checks for the size -- unneeded and - // does harm to xvid 2pass encodes where the first pass can get + + // transcode core itself checks for the size -- unneeded and + // does harm to xvid 2pass encodes where the first pass can get // _very_ large -- tibit. - -#if 0 + +#if 0 /* Check for maximum file length */ - + if ( (AVI->pos + 8 + length + 8 + (AVI->n_idx+1)*16) > AVI_MAX_LEN ) { AVI_errno = AVI_ERR_SIZELIM; return -1; } #endif - + /* Add index entry */ //set tag for current audio track @@ -1563,18 +1564,18 @@ static int avi_write_data(avi_t *AVI, char *data, unsigned long length, int audi if (!AVI->is_opendml) n = avi_add_index_entry(AVI,(unsigned char *)"00db",((keyframe)?0x10:0x0),AVI->pos,length); n += avi_add_odml_index_entry(AVI,(unsigned char *)"00db",((keyframe)?0x10:0x0),AVI->pos,length); } - + if(n) return -1; - + /* Output tag and data */ - + if(audio) n = avi_add_chunk(AVI,(unsigned char *)astr, (unsigned char *)data, length); else n = avi_add_chunk(AVI,(unsigned char *)"00db", (unsigned char *)data, length); - + if (n) return -1; - + return 0; } @@ -1582,13 +1583,13 @@ GF_EXPORT int AVI_write_frame(avi_t *AVI, char *data, long bytes, int keyframe) { s64 pos; - + if(AVI->mode==AVI_MODE_READ) { AVI_errno = AVI_ERR_NOT_PERM; return -1; } - + pos = AVI->pos; if(avi_write_data(AVI,data,bytes,0,keyframe)) return -1; - + AVI->last_pos = pos; AVI->last_len = bytes; AVI->video_frames++; @@ -1625,15 +1626,15 @@ int AVI_append_audio(avi_t *AVI, char *data, long bytes) unsigned char c[4]; if(AVI->mode==AVI_MODE_READ) { AVI_errno = AVI_ERR_NOT_PERM; return -1; } - + // update last index entry: - + --AVI->n_idx; length = str2ulong(AVI->idx[AVI->n_idx]+12); pos = str2ulong(AVI->idx[AVI->n_idx]+8); //update; - long2str(AVI->idx[AVI->n_idx]+12,length+bytes); + long2str(AVI->idx[AVI->n_idx]+12,length+bytes); ++AVI->n_idx; @@ -1641,7 +1642,7 @@ int AVI_append_audio(avi_t *AVI, char *data, long bytes) //update chunk header gf_f64_seek(AVI->fdes, pos+4, SEEK_SET); - long2str(c, length+bytes); + long2str(c, length+bytes); avi_write(AVI->fdes, (char *)c, 4); gf_f64_seek(AVI->fdes, pos+8+length, SEEK_SET); @@ -1672,7 +1673,7 @@ u64 AVI_bytes_written(avi_t *AVI) int AVI_set_audio_track(avi_t *AVI, u32 track) { - + if (track + 1 > AVI->anum) return(-1); //this info is not written to file anyway @@ -1719,37 +1720,37 @@ int AVI_close(avi_t *AVI) /* Even if there happened an error, we first clean up */ fclose(AVI->fdes); - if(AVI->idx) free(AVI->idx); - if(AVI->video_index) free(AVI->video_index); + if(AVI->idx) gf_free(AVI->idx); + if(AVI->video_index) gf_free(AVI->video_index); if(AVI->video_superindex) { - if(AVI->video_superindex->aIndex) free(AVI->video_superindex->aIndex); + if(AVI->video_superindex->aIndex) gf_free(AVI->video_superindex->aIndex); if (AVI->video_superindex->stdindex) { for (j=0; j < NR_IXNN_CHUNKS; j++) { if (AVI->video_superindex->stdindex[j]->aIndex) - free(AVI->video_superindex->stdindex[j]->aIndex); - free(AVI->video_superindex->stdindex[j]); + gf_free(AVI->video_superindex->stdindex[j]->aIndex); + gf_free(AVI->video_superindex->stdindex[j]); } - free(AVI->video_superindex->stdindex); + gf_free(AVI->video_superindex->stdindex); } - free(AVI->video_superindex); + gf_free(AVI->video_superindex); } - for (j=0; j<AVI->anum; j++) + for (j=0; j<AVI->anum; j++) { - if(AVI->track[j].audio_index) free(AVI->track[j].audio_index); + if(AVI->track[j].audio_index) gf_free(AVI->track[j].audio_index); if(AVI->track[j].audio_superindex) { - if(AVI->track[j].audio_superindex->aIndex) free(AVI->track[j].audio_superindex->aIndex); - free(AVI->track[j].audio_superindex); + if(AVI->track[j].audio_superindex->aIndex) gf_free(AVI->track[j].audio_superindex->aIndex); + gf_free(AVI->track[j].audio_superindex); } } if (AVI->bitmap_info_header) - free(AVI->bitmap_info_header); + gf_free(AVI->bitmap_info_header); for (j = 0; j < AVI->anum; j++) if (AVI->wave_format_ex[j]) - free(AVI->wave_format_ex[j]); + gf_free(AVI->wave_format_ex[j]); - free(AVI); + gf_free(AVI); AVI=NULL; return ret; @@ -1767,34 +1768,34 @@ int AVI_close(avi_t *AVI) avi_t *AVI_open_input_file(char *filename, int getIndex) { avi_t *AVI=NULL; - + /* Create avi_t structure */ - - AVI = (avi_t *) malloc(sizeof(avi_t)); + + AVI = (avi_t *) gf_malloc(sizeof(avi_t)); if(AVI==NULL) { AVI_errno = AVI_ERR_NO_MEM; return 0; } memset((void *)AVI,0,sizeof(avi_t)); - + AVI->mode = AVI_MODE_READ; /* open for reading */ - + /* Open the file */ - + AVI->fdes = gf_f64_open(filename,"rb"); if(!AVI->fdes ) { AVI_errno = AVI_ERR_OPEN; - free(AVI); + gf_free(AVI); return 0; } - + AVI_errno = 0; avi_parse_input_file(AVI, getIndex); if (AVI != NULL && !AVI_errno) { - AVI->aptr=0; //reset + AVI->aptr=0; //reset } if (AVI_errno) return NULL; @@ -1805,29 +1806,29 @@ avi_t *AVI_open_input_file(char *filename, int getIndex) avi_t *AVI_open_fd(FILE *fd, int getIndex) { avi_t *AVI=NULL; - + /* Create avi_t structure */ - - AVI = (avi_t *) malloc(sizeof(avi_t)); + + AVI = (avi_t *) gf_malloc(sizeof(avi_t)); if(AVI==NULL) { AVI_errno = AVI_ERR_NO_MEM; return 0; } memset((void *)AVI,0,sizeof(avi_t)); - + AVI->mode = AVI_MODE_READ; /* open for reading */ - + // file alread open AVI->fdes = fd; - + AVI_errno = 0; avi_parse_input_file(AVI, getIndex); if (AVI != NULL && !AVI_errno) { AVI->aptr=0; //reset } - + if (AVI_errno) return AVI=NULL; else @@ -1839,7 +1840,8 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) long i, rate, scale, idx_type; s64 n; unsigned char *hdrl_data; - long header_offset=0, hdrl_len=0; + u64 header_offset=0; + long hdrl_len=0; long nvi, nai[AVI_MAX_TRACKS], ioff; u64 tot[AVI_MAX_TRACKS]; u32 j; @@ -1851,7 +1853,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) int num_stream = 0; char data[256]; s64 oldpos=-1, newpos=-1; - + long aud_chunks = 0; /* Read first 12 bytes and check that this is an AVI file */ @@ -1887,13 +1889,13 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) if(strnicmp(data,"hdrl",4) == 0) { hdrl_len = (u32) n; - hdrl_data = (unsigned char *) malloc((u32)n); + hdrl_data = (unsigned char *) gf_malloc((u32)n); if(hdrl_data==0) ERR_EXIT(AVI_ERR_NO_MEM); - - // offset of header - - header_offset = (u32) gf_f64_tell(AVI->fdes); - + + // offset of header + + header_offset = gf_f64_tell(AVI->fdes); + if( avi_read(AVI->fdes,(char *)hdrl_data, (u32) n) != n ) ERR_EXIT(AVI_ERR_READ) } else if(strnicmp(data,"movi",4) == 0) @@ -1910,10 +1912,10 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) break if this is not the case */ AVI->n_idx = AVI->max_idx = (u32) (n/16); - AVI->idx = (unsigned char((*)[16]) ) malloc((u32)n); + AVI->idx = (unsigned char((*)[16]) ) gf_malloc((u32)n); if(AVI->idx==0) ERR_EXIT(AVI_ERR_NO_MEM) if(avi_read(AVI->fdes, (char *) AVI->idx, (u32) n) != n ) { - free ( AVI->idx); AVI->idx=NULL; + gf_free( AVI->idx); AVI->idx=NULL; AVI->n_idx = 0; } } @@ -1973,12 +1975,12 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) //inc audio tracks AVI->aptr=AVI->anum; ++AVI->anum; - + if(AVI->anum > AVI_MAX_TRACKS) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] error - only %d audio tracks supported\n", AVI_MAX_TRACKS)); return(-1); } - + AVI->track[AVI->aptr].audio_bytes = str2ulong(hdrl_data+i+32)*avi_sampsize(AVI, 0); AVI->track[AVI->aptr].audio_strn = num_stream; @@ -1991,10 +1993,10 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) // auds_strh_seen = 1; lasttag = 2; /* auds */ - + // ThOe AVI->track[AVI->aptr].a_codech_off = header_offset + i; - + } else if (strnicmp ((char*)hdrl_data+i,"iavs",4) ==0 && ! auds_strh_seen) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] AVILIB: error - DV AVI Type 1 no supported\n")); @@ -2017,14 +2019,14 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) if(lasttag == 1) { alBITMAPINFOHEADER bih; - + memcpy(&bih, hdrl_data + i, sizeof(alBITMAPINFOHEADER)); AVI->bitmap_info_header = (alBITMAPINFOHEADER *) - malloc(str2ulong((unsigned char *)&bih.bi_size)); + gf_malloc(str2ulong((unsigned char *)&bih.bi_size)); if (AVI->bitmap_info_header != NULL) memcpy(AVI->bitmap_info_header, hdrl_data + i, str2ulong((unsigned char *)&bih.bi_size)); - + AVI->width = str2ulong(hdrl_data+i+4); AVI->height = str2ulong(hdrl_data+i+8); vids_strf_seen = 1; @@ -2040,18 +2042,18 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) alWAVEFORMATEX *wfe; char *nwfe; int wfes; - + if ((u32) (hdrl_len - i) < sizeof(alWAVEFORMATEX)) wfes = hdrl_len - i; else wfes = sizeof(alWAVEFORMATEX); - wfe = (alWAVEFORMATEX *)malloc(sizeof(alWAVEFORMATEX)); + wfe = (alWAVEFORMATEX *)gf_malloc(sizeof(alWAVEFORMATEX)); if (wfe != NULL) { memset(wfe, 0, sizeof(alWAVEFORMATEX)); memcpy(wfe, hdrl_data + i, wfes); if (str2ushort((unsigned char *)&wfe->cb_size) != 0) { nwfe = (char *) - realloc(wfe, sizeof(alWAVEFORMATEX) + + gf_realloc(wfe, sizeof(alWAVEFORMATEX) + str2ushort((unsigned char *)&wfe->cb_size)); if (nwfe != 0) { s64 lpos = gf_f64_tell(AVI->fdes); @@ -2071,7 +2073,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) //ThOe AVI->track[AVI->aptr].a_codecf_off = header_offset + i; - + AVI->track[AVI->aptr].a_chans = str2ushort(hdrl_data+i+2); AVI->track[AVI->aptr].a_rate = str2ulong (hdrl_data+i+4); //ThOe: read mp3bitrate @@ -2085,11 +2087,12 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) char *a; if(lasttag == 1) // V I D E O - { + { a = (char*)hdrl_data+i; - AVI->video_superindex = (avisuperindex_chunk *) malloc (sizeof (avisuperindex_chunk)); + AVI->video_superindex = (avisuperindex_chunk *) gf_malloc (sizeof (avisuperindex_chunk)); + memset(AVI->video_superindex, 0, sizeof (avisuperindex_chunk)); memcpy (AVI->video_superindex->fcc, a, 4); a += 4; AVI->video_superindex->dwSize = str2ulong((unsigned char *)a); a += 4; AVI->video_superindex->wLongsPerEntry = str2ushort((unsigned char *)a); a += 2; @@ -2102,11 +2105,11 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) a += 4; a += 4; a += 4; if (AVI->video_superindex->bIndexSubType != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Invalid Header, bIndexSubType != 0\n")); + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Invalid Header, bIndexSubType != 0\n")); } - + AVI->video_superindex->aIndex = (avisuperindex_entry*) - malloc (AVI->video_superindex->wLongsPerEntry * AVI->video_superindex->nEntriesInUse * sizeof (u32)); + gf_malloc (AVI->video_superindex->wLongsPerEntry * AVI->video_superindex->nEntriesInUse * sizeof (u32)); // position of ix## chunks for (j=0; j<AVI->video_superindex->nEntriesInUse; ++j) { @@ -2115,23 +2118,23 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) AVI->video_superindex->aIndex[j].dwDuration = str2ulong ((unsigned char*)a); a += 4; #ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d] 0x%llx 0x%lx %lu\n", j, + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d] 0x%llx 0x%lx %lu\n", j, (unsigned long long)AVI->video_superindex->aIndex[j].qwOffset, - (unsigned long)AVI->video_superindex->aIndex[j].dwSize, + (unsigned long)AVI->video_superindex->aIndex[j].dwSize, (unsigned long)AVI->video_superindex->aIndex[j].dwDuration)); #endif } #ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] FOURCC \"%c%c%c%c\"\n", AVI->video_superindex->fcc[0], AVI->video_superindex->fcc[1], + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] FOURCC \"%c%c%c%c\"\n", AVI->video_superindex->fcc[0], AVI->video_superindex->fcc[1], AVI->video_superindex->fcc[2], AVI->video_superindex->fcc[3])); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] LEN \"%ld\"\n", (long)AVI->video_superindex->dwSize)); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] wLongsPerEntry \"%d\"\n", AVI->video_superindex->wLongsPerEntry)); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] bIndexSubType \"%d\"\n", AVI->video_superindex->bIndexSubType)); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] bIndexType \"%d\"\n", AVI->video_superindex->bIndexType)); GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] nEntriesInUse \"%ld\"\n", (long)AVI->video_superindex->nEntriesInUse)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] dwChunkId \"%c%c%c%c\"\n", AVI->video_superindex->dwChunkId[0], AVI->video_superindex->dwChunkId[1], + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] dwChunkId \"%c%c%c%c\"\n", AVI->video_superindex->dwChunkId[0], AVI->video_superindex->dwChunkId[1], AVI->video_superindex->dwChunkId[2], AVI->video_superindex->dwChunkId[3])); #endif @@ -2143,7 +2146,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) a = (char*) hdrl_data+i; - AVI->track[AVI->aptr].audio_superindex = (avisuperindex_chunk *) malloc (sizeof (avisuperindex_chunk)); + AVI->track[AVI->aptr].audio_superindex = (avisuperindex_chunk *) gf_malloc (sizeof (avisuperindex_chunk)); memcpy (AVI->track[AVI->aptr].audio_superindex->fcc, a, 4); a += 4; AVI->track[AVI->aptr].audio_superindex->dwSize = str2ulong((unsigned char*)a); a += 4; AVI->track[AVI->aptr].audio_superindex->wLongsPerEntry = str2ushort((unsigned char*)a); a += 2; @@ -2156,11 +2159,11 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) a += 4; a += 4; a += 4; if (AVI->track[AVI->aptr].audio_superindex->bIndexSubType != 0) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Invalid Header, bIndexSubType != 0\n")); + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Invalid Header, bIndexSubType != 0\n")); } - + AVI->track[AVI->aptr].audio_superindex->aIndex = (avisuperindex_entry*) - malloc (AVI->track[AVI->aptr].audio_superindex->wLongsPerEntry * + gf_malloc (AVI->track[AVI->aptr].audio_superindex->wLongsPerEntry * AVI->track[AVI->aptr].audio_superindex->nEntriesInUse * sizeof (u32)); // position of ix## chunks @@ -2170,9 +2173,9 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) AVI->track[AVI->aptr].audio_superindex->aIndex[j].dwDuration = str2ulong ((unsigned char*)a); a += 4; #ifdef DEBUG_ODML - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d] 0x%llx 0x%lx %lu\n", j, + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d] 0x%llx 0x%lx %lu\n", j, (unsigned long long)AVI->track[AVI->aptr].audio_superindex->aIndex[j].qwOffset, - (unsigned long)AVI->track[AVI->aptr].audio_superindex->aIndex[j].dwSize, + (unsigned long)AVI->track[AVI->aptr].audio_superindex->aIndex[j].dwSize, (unsigned long)AVI->track[AVI->aptr].audio_superindex->aIndex[j].dwDuration)); #endif } @@ -2205,7 +2208,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) i += (u32) n; } - free(hdrl_data); + gf_free(hdrl_data); if(!vids_strh_seen || !vids_strf_seen) ERR_EXIT(AVI_ERR_NO_VIDS) @@ -2217,7 +2220,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) /* Audio tag is set to "99wb" if no audio present */ if(!AVI->track[0].a_chans) AVI->track[0].audio_strn = 99; - { + { int i=0; for(j=0; j<AVI->anum+1; ++j) { if (j == AVI->video_strn) continue; @@ -2293,7 +2296,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) } /* Check if we got a tag ##db, ##dc or ##wb */ - + if( ( (data[2]=='d' || data[2]=='D') && (data[3]=='b' || data[3]=='B' || data[3]=='c' || data[3]=='C') ) || ( (data[2]=='w' || data[2]=='W') && @@ -2302,7 +2305,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) u64 __pos = gf_f64_tell(AVI->fdes) - 8; avi_add_index_entry(AVI,(unsigned char *)data,0,__pos,n); } - + gf_f64_seek(AVI->fdes,PAD_EVEN(n),SEEK_CUR); } idx_type = 1; @@ -2333,15 +2336,15 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) for (j=0; j<AVI->video_superindex->nEntriesInUse; j++) { // read from file - chunk_start = en = (char*) malloc ((u32) (AVI->video_superindex->aIndex[j].dwSize+hdrl_len) ); + chunk_start = en = (char*) gf_malloc ((u32) (AVI->video_superindex->aIndex[j].dwSize+hdrl_len) ); if (gf_f64_seek(AVI->fdes, AVI->video_superindex->aIndex[j].qwOffset, SEEK_SET) == (u64)-1) { - free(chunk_start); + gf_free(chunk_start); continue; } if (avi_read(AVI->fdes, en, (u32) (AVI->video_superindex->aIndex[j].dwSize+hdrl_len) ) <= 0) { - free(chunk_start); + gf_free(chunk_start); continue; } @@ -2354,7 +2357,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) // skip header en += hdrl_len; nvi += nrEntries; - AVI->video_index = (video_index_entry *) realloc (AVI->video_index, nvi * sizeof (video_index_entry)); + AVI->video_index = (video_index_entry *) gf_realloc (AVI->video_index, nvi * sizeof (video_index_entry)); if (!AVI->video_index) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] out of mem (size = %ld)\n", nvi * sizeof (video_index_entry))); exit(1); @@ -2374,18 +2377,18 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) #ifdef DEBUG_ODML /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d] POS 0x%llX len=%d key=%s offset (%llx) (%ld)\n", k, - AVI->video_index[k].pos, - (int)AVI->video_index[k].len, - AVI->video_index[k].key?"yes":"no ", offset, - AVI->video_superindex->aIndex[j].dwSize)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d] POS 0x%llX len=%d key=%s offset (%llx) (%ld)\n", k, + AVI->video_index[k].pos, + (int)AVI->video_index[k].len, + AVI->video_index[k].key?"yes":"no ", offset, + AVI->video_superindex->aIndex[j].dwSize)); */ #endif k++; } - free(chunk_start); + gf_free(chunk_start); } AVI->video_frames = nvi; @@ -2394,9 +2397,9 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) AVI->is_opendml=0; goto multiple_riff; } - + // ************************ - // AUDIO + // AUDIO // ************************ for(audtr=0; audtr<AVI->anum; ++audtr) { @@ -2409,15 +2412,15 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) for (j=0; j<AVI->track[audtr].audio_superindex->nEntriesInUse; j++) { // read from file - chunk_start = en = (char*)malloc ((u32) (AVI->track[audtr].audio_superindex->aIndex[j].dwSize+hdrl_len)); + chunk_start = en = (char*)gf_malloc ((u32) (AVI->track[audtr].audio_superindex->aIndex[j].dwSize+hdrl_len)); if (gf_f64_seek(AVI->fdes, AVI->track[audtr].audio_superindex->aIndex[j].qwOffset, SEEK_SET) == (u64)-1) { - free(chunk_start); + gf_free(chunk_start); continue; } if (avi_read(AVI->fdes, en, (u32) (AVI->track[audtr].audio_superindex->aIndex[j].dwSize+hdrl_len)) <= 0) { - free(chunk_start); + gf_free(chunk_start); continue; } @@ -2431,7 +2434,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) // skip header en += hdrl_len; nai[audtr] += nrEntries; - AVI->track[audtr].audio_index = (audio_index_entry *) realloc (AVI->track[audtr].audio_index, nai[audtr] * sizeof (audio_index_entry)); + AVI->track[audtr].audio_index = (audio_index_entry *) gf_realloc (AVI->track[audtr].audio_index, nai[audtr] * sizeof (audio_index_entry)); while (k < nai[audtr]) { @@ -2442,19 +2445,19 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) #ifdef DEBUG_ODML /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d:%d] POS 0x%llX len=%d offset (%llx) (%ld)\n", k, audtr, - AVI->track[audtr].audio_index[k].pos, - (int)AVI->track[audtr].audio_index[k].len, - offset, AVI->track[audtr].audio_superindex->aIndex[j].dwSize)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] [%d:%d] POS 0x%llX len=%d offset (%llx) (%ld)\n", k, audtr, + AVI->track[audtr].audio_index[k].pos, + (int)AVI->track[audtr].audio_index[k].len, + offset, AVI->track[audtr].audio_superindex->aIndex[j].dwSize)); */ #endif ++k; } - free(chunk_start); + gf_free(chunk_start); } - + AVI->track[audtr].audio_chunks = nai[audtr]; AVI->track[audtr].audio_bytes = tot[audtr]; } @@ -2465,7 +2468,7 @@ int avi_parse_input_file(avi_t *AVI, int getIndex) // ********************* // MULTIPLE RIFF CHUNKS (and no index) // ********************* - + multiple_riff: gf_f64_seek(AVI->fdes, AVI->movi_start, SEEK_SET); @@ -2479,17 +2482,17 @@ multiple_riff: nai[0] = AVI->track[0].audio_chunks = AVI->total_frames; for(j=1; j<AVI->anum; ++j) AVI->track[j].audio_chunks = 0; - AVI->video_index = (video_index_entry *) malloc(nvi*sizeof(video_index_entry)); + AVI->video_index = (video_index_entry *) gf_malloc(nvi*sizeof(video_index_entry)); if(AVI->video_index==0) ERR_EXIT(AVI_ERR_NO_MEM); for(j=0; j<AVI->anum; ++j) { if(AVI->track[j].audio_chunks) { - AVI->track[j].audio_index = (audio_index_entry *) malloc((nai[j]+1)*sizeof(audio_index_entry)); + AVI->track[j].audio_index = (audio_index_entry *) gf_malloc((nai[j]+1)*sizeof(audio_index_entry)); memset(AVI->track[j].audio_index, 0, (nai[j]+1)*(sizeof(audio_index_entry))); if(AVI->track[j].audio_index==0) ERR_EXIT(AVI_ERR_NO_MEM); } - } + } nvi = 0; for(j=0; j<AVI->anum; ++j) {nai[j] = 0; tot[j] = 0;} @@ -2508,8 +2511,8 @@ multiple_riff: if (aud_chunks - nai[j] -1 <= 0) { aud_chunks += AVI->total_frames; - AVI->track[j].audio_index = (audio_index_entry *) - realloc( AVI->track[j].audio_index, (aud_chunks+1)*sizeof(audio_index_entry)); + AVI->track[j].audio_index = (audio_index_entry *) + gf_realloc( AVI->track[j].audio_index, (aud_chunks+1)*sizeof(audio_index_entry)); if (!AVI->track[j].audio_index) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] Internal error in avilib -- no mem\n")); AVI_errno = AVI_ERR_NO_MEM; @@ -2518,9 +2521,9 @@ multiple_riff: } /* Check if we got a tag ##db, ##dc or ##wb */ - + // VIDEO - if( + if( (data[0]=='0' || data[1]=='0') && (data[2]=='d' || data[2]=='D') && (data[3]=='b' || data[3]=='B' || data[3]=='c' || data[3]=='C') ) { @@ -2530,15 +2533,15 @@ multiple_riff: AVI->video_index[nvi].len = (u32) n; /* - GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] Frame %ld pos %lld len %lld key %ld\n", + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[avilib] Frame %ld pos %"LLD" len %"LLD" key %ld\n", nvi, AVI->video_index[nvi].pos, AVI->video_index[nvi].len, (long)AVI->video_index[nvi].key)); */ nvi++; gf_f64_seek(AVI->fdes,PAD_EVEN(n),SEEK_CUR); - } + } //AUDIO - else if( + else if( (data[0]=='0' || data[1]=='1') && (data[2]=='w' || data[2]=='W') && (data[3]=='b' || data[3]=='B') ) { @@ -2558,7 +2561,7 @@ multiple_riff: } if (nvi < AVI->total_frames) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[avilib] Uh? Some frames seems missing (%ld/%d)\n", + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[avilib] Uh? Some frames seems missing (%ld/%d)\n", nvi, AVI->total_frames)); } @@ -2578,40 +2581,40 @@ multiple_riff: // ****************** // NO OPENDML // ****************** - + /* Now generate the video index and audio index arrays */ nvi = 0; for(j=0; j<AVI->anum; ++j) nai[j] = 0; for(i=0;i<AVI->n_idx;i++) { - + if(strnicmp((char *)AVI->idx[i],AVI->video_tag,3) == 0) nvi++; - + for(j=0; j<AVI->anum; ++j) if(strnicmp((char *)AVI->idx[i], AVI->track[j].audio_tag,4) == 0) nai[j]++; } - + AVI->video_frames = nvi; for(j=0; j<AVI->anum; ++j) AVI->track[j].audio_chunks = nai[j]; - + if(AVI->video_frames==0) ERR_EXIT(AVI_ERR_NO_VIDS); - AVI->video_index = (video_index_entry *) malloc(nvi*sizeof(video_index_entry)); + AVI->video_index = (video_index_entry *) gf_malloc(nvi*sizeof(video_index_entry)); if(AVI->video_index==0) ERR_EXIT(AVI_ERR_NO_MEM); - + for(j=0; j<AVI->anum; ++j) { if(AVI->track[j].audio_chunks) { - AVI->track[j].audio_index = (audio_index_entry *) malloc((nai[j]+1)*sizeof(audio_index_entry)); + AVI->track[j].audio_index = (audio_index_entry *) gf_malloc((nai[j]+1)*sizeof(audio_index_entry)); memset(AVI->track[j].audio_index, 0, (nai[j]+1)*(sizeof(audio_index_entry))); if(AVI->track[j].audio_index==0) ERR_EXIT(AVI_ERR_NO_MEM); } - } - + } + nvi = 0; for(j=0; j<AVI->anum; ++j) {nai[j] = 0; tot[j] = 0;} - + ioff = idx_type == 1 ? 8 : (u32)AVI->movi_start+4; - + for(i=0;i<AVI->n_idx;i++) { //video @@ -2621,10 +2624,10 @@ multiple_riff: AVI->video_index[nvi].len = str2ulong(AVI->idx[i]+12); nvi++; } - + //audio for(j=0; j<AVI->anum; ++j) { - + if(strnicmp((char *)AVI->idx[i],AVI->track[j].audio_tag,4) == 0) { AVI->track[j].audio_index[nai[j]].pos = str2ulong(AVI->idx[i]+ 8)+ioff; AVI->track[j].audio_index[nai[j]].len = str2ulong(AVI->idx[i]+12); @@ -2634,14 +2637,14 @@ multiple_riff: } } } - - + + for(j=0; j<AVI->anum; ++j) AVI->track[j].audio_bytes = tot[j]; } // is no opendml /* Reposition the file */ - + gf_f64_seek(AVI->fdes,AVI->movi_start,SEEK_SET); AVI->video_pos = 0; @@ -2671,7 +2674,7 @@ char* AVI_video_compressor(avi_t *AVI) long AVI_max_video_chunk(avi_t *AVI) { - return AVI->max_len; + return AVI->max_len; } int AVI_audio_tracks(avi_t *AVI) @@ -2723,7 +2726,7 @@ long AVI_audio_size(avi_t *AVI, long frame) { if(AVI->mode==AVI_MODE_WRITE) { AVI_errno = AVI_ERR_NOT_PERM; return -1; } if(!AVI->track[AVI->aptr].audio_index) { AVI_errno = AVI_ERR_NO_IDX; return -1; } - + if(frame < 0 || frame >= AVI->track[AVI->aptr].audio_chunks) return -1; return (u32) (AVI->track[AVI->aptr].audio_index[frame].len); } @@ -2764,7 +2767,7 @@ int AVI_set_audio_bitrate(avi_t *AVI, long bitrate) AVI->track[AVI->aptr].mp3rate = bitrate; return 0; } - + long AVI_read_frame(avi_t *AVI, char *vidbuf, int *keyframe) { @@ -2882,7 +2885,7 @@ long AVI_read_audio(avi_t *AVI, char *audbuf, long bytes, int *continuous) gf_f64_seek(AVI->fdes, pos, SEEK_SET); if ( (ret = avi_read(AVI->fdes,audbuf+nr,todo)) != todo) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] XXX pos = %lld, ret = %lld, todo = %ld\n", pos, ret, todo)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[avilib] XXX pos = %"LLD", ret = %"LLD", todo = %ld\n", pos, ret, todo)); AVI_errno = AVI_ERR_READ; return -1; } @@ -2915,7 +2918,7 @@ int AVI_read_data(avi_t *AVI, char *vidbuf, long max_vidbuf, s64 n; char data[8]; - + if(AVI->mode==AVI_MODE_WRITE) return 0; while(1) @@ -2969,5 +2972,4 @@ u64 AVI_max_size(void) } -#endif - +#endif /*GPAC_DISABLE_AVILIB*/ diff --git a/src/media_tools/dvb_mpe.c b/src/media_tools/dvb_mpe.c new file mode 100644 index 0000000..a15c648 --- /dev/null +++ b/src/media_tools/dvb_mpe.c @@ -0,0 +1,1246 @@ +#include <gpac/internal/dvb_mpe_dev.h> +#include <gpac/network.h> +#include <string.h> + +static void gf_m2ts_Delete_IpPacket(GF_M2TS_IP_Packet *ip_packet); + + +static void empty_list(GF_List * list) +{ + void *obj; + u32 nb; + + nb = gf_list_count(list); + + while(gf_list_count(list)){ + obj = gf_list_get(list,0); + gf_list_rem(list,0); + gf_free(obj); + obj = NULL; + } + +} + +static void on_dvb_mpe_section(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) +{ + GF_M2TS_SL_PCK *pck = (GF_M2TS_SL_PCK *)par; + unsigned char *data; + u32 u32_data_size; + u32 u32_table_id; + + if (evt_type == GF_M2TS_EVT_DVB_MPE) { + data = pck->data; + u32_data_size = pck->data_len; + u32_table_id = data[0]; + + switch(u32_table_id) { + case GF_M2TS_TABLE_ID_INT: + gf_m2ts_process_int(ts, (GF_M2TS_SECTION_ES *)pck->stream, data, u32_data_size, u32_table_id); + break; + + case GF_M2TS_TABLE_ID_MPE_FEC: + case GF_M2TS_TABLE_ID_DSM_CC_PRIVATE: + if(ts->ip_platform != NULL) { + gf_m2ts_process_mpe(ts, (GF_M2TS_SECTION_MPE*)pck->stream, data, u32_data_size, u32_table_id); + } else { + //printf("Time Slice Parameters for MPE-FEC have not been found yet \n"); + } + break; + default: + return; + } + } +} + +static void on_dvb_mpe_fec_frame(GF_M2TS_Demuxer *ts, MPE_FEC_FRAME *mff) +{ + if (ts->ip_platform != NULL) { + if(ts->dvb_h_demux == 0) { + gf_m2ts_gather_ipdatagram_information(mff,ts); + } else { + gf_m2ts_process_ipdatagram(mff,ts); + } + } +} + +void gf_dvb_mpe_init(GF_M2TS_Demuxer *ts) +{ + if (ts && !ts->on_mpe_event) ts->on_mpe_event = on_dvb_mpe_section; +} + +void gf_dvb_mpe_shutdown(GF_M2TS_Demuxer *ts) +{ + u32 i_streams, i_targets; + GF_M2TS_IP_Stream *ip_stream_buff; + + GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform; + + if (!ip_platform) return; + + i_streams = 0; + i_targets = 0; + while(gf_list_count(ip_platform->ip_streams)){ + ip_stream_buff=gf_list_get(ip_platform->ip_streams, 0); + + while (gf_list_count(ip_stream_buff->targets)){ + GF_M2TS_IP_Target *ip_targets = gf_list_get(ip_stream_buff->targets, 0); + gf_free(ip_targets); + gf_list_rem(ip_stream_buff->targets,0); + } + gf_free(ip_stream_buff); + gf_list_rem(ip_platform->ip_streams,0); + + } + gf_list_del(ip_platform->ip_streams); + while(gf_list_count(ip_platform->socket_struct)){ + GF_SOCK_ENTRY *socket_struct = gf_list_get(ip_platform->socket_struct, 0); + gf_free(socket_struct); + gf_list_rem(ip_platform->socket_struct,0); + } + gf_list_del(ip_platform->socket_struct); + gf_free(ip_platform); +} + +GF_M2TS_ES *gf_dvb_mpe_section_new() +{ + GF_M2TS_ES *es; + + GF_M2TS_SECTION_MPE *ses; + GF_SAFEALLOC(ses, GF_M2TS_SECTION_MPE); + es = (GF_M2TS_ES *)ses; + es->flags = GF_M2TS_ES_IS_SECTION | GF_M2TS_ES_IS_MPE; + return es; +} + +void gf_dvb_mpe_section_del(GF_M2TS_ES *es) +{ + GF_M2TS_SECTION_MPE *ses = (GF_M2TS_SECTION_MPE *)es; + + /*TODO - cleanup MPE FEC frame state & co*/ + if (ses->mff) { + gf_list_del(ses->mff->mpe_holes); + gf_free(ses->mff); + ses->mff=NULL; + } +} + + +/*void print_bytes(u8* data, u32 line_length, u32 length, Bool last_line) +{ + u32 i; + for (i = 0; i < length; i ++) { + if (i%line_length == 0) { + printf("%2d: ", i/line_length); + } else if (i%8 == 0) { + printf(" "); + } + printf("%02x", data[i]); + if ((i+1)%line_length == 0) { + printf("\n"); + } + } + if (last_line) printf("\n"); +} +*/ + +void gf_m2ts_process_mpe(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_MPE *mpe, unsigned char *data, u32 data_size, u8 table_id) +{ + GF_M2TS_IP_Stream *ip_stream_buff; + GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform; + u32 delta_t; + u32 table_boundry_flag; + u32 frame_boundry_flag; + u32 offset; + u32 i_streams,j; + u32 id,section_length, section_number, last_section_number; + s32 len_left = data_size; + + + u32 i = 0; + i_streams = 0; + +// printf("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")); + } + + /*get number of rows of mpe_fec_frame from descriptor*/ + id = data[0]; + section_length = (data[1] & 0xF)<<8|data[2]; + section_number = data[6]; + last_section_number = data[7]; + //printf( "table_id: %x section_length: %d section_number: %d last : %d \n",id, section_length, section_number, last_section_number); + + /*get number of rows of mpe_fec_frame from descriptor*/ + /* Real-Time Parameters */ + delta_t = (data[8]<<4)|(data[9]>>4); + table_boundry_flag = (data[9] >> 3 )& 0x1; + frame_boundry_flag = (data[9] >> 2 )& 0x1; + + offset = ((data[9] & 0x3)<< 16) | (data[10] << 8)| data[11]; + + /* Using MFF structure attached to the MPE Stream */ + if(mpe->mff){ + if(!mpe->mff->mpe_holes){ + mpe->mff->mpe_holes = gf_list_new(); + } + }else if(offset != 0){ + /* If no MFF structure is attached to the MPE Stream, wait for a new IP Datagram before processing data */ + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[IpdcEgine] buffer is not null, waiting for a new IP Datagram before processing data\n")); + return; + }else{ + GF_SAFEALLOC(mpe->mff,MPE_FEC_FRAME); + + i_streams = gf_list_count(ip_platform->ip_streams); + for(j=0;j<i_streams;j++){ + ip_stream_buff=gf_list_get(ip_platform->ip_streams, j); + + if(mpe->program->number == ip_stream_buff->location.service_id){ + switch(ip_stream_buff->time_slice_fec.frame_size){ + case 0: + mpe->mff->rows =256; + break; + case 1: + mpe->mff->rows =512; + break; + case 2: + mpe->mff->rows =768; + break; + case 3: + mpe->mff->rows =1024; + break; + default: + break; + } + break; + } + } + /*initialize the mpe fec frame */ + if (init_frame(mpe->mff, mpe->mff->rows)) { + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("MFF initialization successed \n")); + } else { + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("MFF initialization failed \n")); + return; + } + } + + //fprintf(stderr, "PID: %4d, sec: %2d/%2d, t_id: %2d, d: %3d, tb: %d, fb: %d, add.: %8d\n", mpe->pid, section_number, last_section_number, id, delta_t, table_boundry_flag, frame_boundry_flag, offset); + mpe->mff->PID = mpe->pid; + + while (len_left>0) { + + switch (table_id) { + case GF_M2TS_TABLE_ID_DSM_CC_PRIVATE: /* MPE */ + /* Sets the IP data in the Application Data Table + Remove the first 12 bytes of header (from table id to end of real time parameters + Remove also the last four 4 bytes of the section (CRC 32)*/ + setIpDatagram( mpe->mff, offset, data +12, data_size-(12+4)); + len_left = 0; + break; + case GF_M2TS_TABLE_ID_MPE_FEC: + /* RS data is set by column, one column at a time */ + //setColRS( mpe->mff, offset, data + 12, mpe->mff->rows); + len_left = 0; + //data += (mff->rows +12+4 ); + break; + default: + // printf ("Unknown table id %x \n", table_id ); + len_left = 0; + } + + if(table_boundry_flag == 1) /* end of reception of ADT data or RS data */{ + if(table_id == 0x3E) /* end of ADT */{ + mpe->mff->ADT_done =1; + if(mpe->mff->current_offset_adt+1 != mpe->mff->capacity_total){ + memset( mpe->mff->p_adt+mpe->mff->current_offset_adt,0, mpe->mff->capacity_total-( mpe->mff->current_offset_adt+1)); + } + } + /* end of RS should be catched below by frame_boundary_flag */ + } + + if(frame_boundry_flag == 1){ + if(table_id == 0x78){ + if( mpe->mff->current_offset_rs+1 != mpe->mff->rows*64){ + memset( mpe->mff->p_rs+ mpe->mff->current_offset_rs,0,( mpe->mff->rows*64)-( mpe->mff->current_offset_rs+1)); + } + } + } + + } + + if (frame_boundry_flag && table_boundry_flag && mpe->mff->ADT_done ==1 ) { + //decode_fec(mpe->mff); + on_dvb_mpe_fec_frame(ts, mpe->mff); + resetMFF(mpe->mff); + /*for each IP datagram reconstructed*/ + } + +} + +void gf_m2ts_process_ipdatagram(MPE_FEC_FRAME *mff,GF_M2TS_Demuxer *ts) +{ + GF_M2TS_IP_Packet *ip_packet; + u8* ip_datagram; + u32 i, i_holes; + MPE_Error_Holes *mff_holes; + u32 offset; /* offset to get through the datagram */ + u8 ip_adress_bootstrap[4]; + Bool Boostrap_ip; + + offset =0; + ip_datagram = mff->p_adt; + + GF_SAFEALLOC(ip_packet,GF_M2TS_IP_Packet); + + + while(offset<mff->current_offset_adt) + { + /* Find the parts of the ADT which contain errors and skip them */ + if((mff->p_error_adt+offset)[0] == 0x01010101){ + i_holes = gf_list_count(mff->mpe_holes); + for(i=0;i<i_holes;i++){ + mff_holes=gf_list_get(mff->mpe_holes, i); + if(mff_holes->offset == offset){ + offset += mff_holes->length; + break; + } + } + } + + if(gf_m2ts_ipdatagram_reader(ip_datagram, ip_packet, offset)){ + + + /* update the offset */ + //offset += ip_packet->u32_total_length; + offset += (ip_packet->u32_hdr_length*4) + ip_packet->u32_udp_data_size; + + + /* 224.0.23.14 IP Bosstrap */ + ip_adress_bootstrap[0]=224; + ip_adress_bootstrap[1]=0; + ip_adress_bootstrap[2]=23; + ip_adress_bootstrap[3]=14; + socket_simu(ip_packet,ts); + + if(ip_packet->u8_rx_adr[3] == 8){ + printf("\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"); + } + }else{ + offset += (ip_packet->u32_total_length); + } + + if(ip_packet->data){ + gf_free(ip_packet->data); + } + ip_packet->data = NULL; + + } + + //gf_memory_print(); + //gf_memory_size(); + + empty_list(mff->mpe_holes); + gf_list_del(mff->mpe_holes); + mff->mpe_holes = NULL; + gf_m2ts_Delete_IpPacket(ip_packet); +} + +Bool gf_m2ts_compare_ip(u8 rx_ip_adress[4], u8 ip_adress_bootstrap[4]) +{ + Bool Boostrap_ip; + u8 i; + for (i=0; i<sizeof(rx_ip_adress); i++) + { + if (rx_ip_adress[i] != ip_adress_bootstrap[i]) + return Boostrap_ip = 0; + } + return Boostrap_ip = 1; +} +u32 gf_m2ts_ipdatagram_reader(u8 *datagram,GF_M2TS_IP_Packet *ip_packet, u32 offset) +{ + + ip_packet->u32_version = ((datagram+offset)[0])>>4; + ip_packet->u32_hdr_length =(((datagram+offset)[0])&0xF); + ip_packet->u32_total_length = (datagram+offset)[2]<<8|(datagram+offset)[3]; + ip_packet->u32_id_nb = (datagram+offset)[4]<<8|datagram[5]; + ip_packet->u32_flag = ((datagram+offset)[6])>>5; + ip_packet->u32_frag_offset = ((datagram+offset)[6]&0x1F)<<8|(datagram+offset)[7]; + ip_packet->u32_TTL = (datagram+offset)[8]; + ip_packet->u32_protocol = (datagram+offset)[9]; + ip_packet->u32_crc = (datagram+offset)[10]<<8|(datagram+offset)[11]; + memcpy(ip_packet->u8_tx_adr,(datagram+offset)+12,sizeof(ip_packet->u8_tx_adr)); + memcpy(ip_packet->u8_rx_adr,(datagram+offset)+16,sizeof(ip_packet->u8_rx_adr)); + + ip_packet->u32_tx_udp_port = ((datagram+offset)+(ip_packet->u32_hdr_length*4))[0]<<8|((datagram+offset)+(ip_packet->u32_hdr_length*4))[1]; + if(!ip_packet->u32_tx_udp_port){ + return 0; + } + ip_packet->u32_rx_udp_port = ((datagram+offset)+(ip_packet->u32_hdr_length*4))[2]<<8|((datagram+offset)+(ip_packet->u32_hdr_length*4))[3]; + if(!ip_packet->u32_rx_udp_port){ + return 0; + } + ip_packet->u32_udp_data_size = ((datagram+offset)+(ip_packet->u32_hdr_length*4))[4]<<8|((datagram+offset)+(ip_packet->u32_hdr_length*4))[5]; + if(ip_packet->u32_udp_data_size == 0){ + return 0; + } + ip_packet->u32_udp_chksm = ((datagram+offset)+(ip_packet->u32_hdr_length*4))[6]<<8|((datagram+offset)+(ip_packet->u32_hdr_length*4))[7]; + + + ip_packet->data = gf_malloc((ip_packet->u32_udp_data_size-8)*sizeof(u8)); + memcpy(ip_packet->data,datagram+offset+(ip_packet->u32_hdr_length*4)+8,(ip_packet->u32_udp_data_size-8)*sizeof(u8)); + /*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); + + return 1; + +} + +static void gf_m2ts_Delete_IpPacket(GF_M2TS_IP_Packet *ip_packet) +{ + ip_packet->u32_version = 0; + ip_packet->u32_hdr_length =0; + ip_packet->u32_total_length = 0; + ip_packet->u32_id_nb = 0; + ip_packet->u32_flag = 0; + ip_packet->u32_frag_offset = 0; + ip_packet->u32_TTL = 0; + ip_packet->u32_protocol = 0; + ip_packet->u32_crc = 0; + ip_packet->u32_tx_udp_port = 0; + ip_packet->u32_rx_udp_port = 0; + ip_packet->u32_udp_data_size = 0; + ip_packet->u32_udp_chksm = 0; + + if(ip_packet->data){ + gf_free(ip_packet->data); + } + gf_free(ip_packet); + ip_packet = NULL; +} + + + +void gf_m2ts_process_int(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ip_table, unsigned char *data, u32 data_size, u32 table_id) +{ + + GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform ; +// fprintf(stdout, "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"); + section_DSMCC_INT (ip_platform, data, data_size); + ts->ip_platform = ip_platform; + } + //printf ("processing the INT table \n"); + + + +} + + +/*the following code is copied from dvbsnoop project : http://dvbsnoop.sourceforge.net */ +void section_DSMCC_INT(GF_M2TS_IP_PLATFORM* ip_platform,u8 *data, u32 data_size) +{ + /* EN 301 192 7.x */ + + s32 length,i; + + + length = data_size ; + + data += 12 ; + + i = dsmcc_pto_platform_descriptor_loop(ip_platform,data); + data += i; + length -= i; + + while (length > 4) { + GF_M2TS_IP_Stream *ip_str; + GF_SAFEALLOC(ip_str,GF_M2TS_IP_Stream ); + + i = dsmcc_pto_descriptor_loop(ip_str,data); + data += i; + length -= i; + + i = dsmcc_pto_descriptor_loop(ip_str,data); + data += i; + length -= i; + + + gf_list_add(ip_platform->ip_streams, ip_str); + } + + return ; +} + + +/* Platform Descriptor */ + +u32 dsmcc_pto_platform_descriptor_loop(GF_M2TS_IP_PLATFORM* ip_platform, u8 *data) +{ + u32 loop_length; + s32 length,i; + + + loop_length = ((data[0]) & 0xF ) | data[1]; + length = loop_length; + data += 2; + while (length > 0) { + i = platform_descriptorDSMCC_INT_UNT(ip_platform,data); + data += i; + length -= i; + } + + return (loop_length+2); +} + + +u32 platform_descriptorDSMCC_INT_UNT(GF_M2TS_IP_PLATFORM* ip_platform, u8 *data) + +{ + u32 length; + u32 id; + + + id = data[0]; + length = data[1]+2; + + switch (id) { + + + case GF_M2TS_DVB_IP_MAC_PLATFORM_NAME_DESCRIPTOR: + { + //printf (" 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"); + gf_ip_platform_provider_descriptor(ip_platform, data); + }break; + + default: + break; + } + return length; // (descriptor total length) +} + +void gf_ip_platform_descriptor(GF_M2TS_IP_PLATFORM* ip_platform,u8 * data) +{ + u32 length; + length = data[1]; + /* allocation ofr the name of the platform */ + ip_platform->name = gf_malloc(sizeof(char)*(length-3+1)); + memcpy(ip_platform->name, data+5, length-3); + ip_platform->name[length-3] = 0; + return ; +} + +void gf_ip_platform_provider_descriptor(GF_M2TS_IP_PLATFORM* ip_platform, u8 * data) +{ + u32 length; + length = data[1]; + /* allocation of the name of the platform */ + ip_platform->provider_name = gf_malloc(sizeof(char)*(length-3+1)); + memcpy(ip_platform->provider_name, data+5, length-3); + ip_platform->provider_name[length-3] = 0; + return ; +} + + + +/* IP Stream Descriptors */ +u32 dsmcc_pto_descriptor_loop ( GF_M2TS_IP_Stream *ip_str,u8 *data) +{ + u32 loop_length; + s32 length,i; + + loop_length = ((data[0]) & 0xF ) | data[1]; + + length = loop_length; + data += 2; + while (length > 0) { + i = descriptorDSMCC_INT_UNT(ip_str,data); + data += i; + length -= i; + } + + return (loop_length+2); +} + + +u32 descriptorDSMCC_INT_UNT(GF_M2TS_IP_Stream *ip_str,u8 *data) + +{ + u32 length; + u32 id; + + id = data[0]; + length = data[1] +2; + + switch (id) { + + + case GF_M2TS_DVB_TARGET_IP_SLASH_DESCRIPTOR: + { + + gf_m2ts_target_ip(ip_str,data); + } + break; + + case GF_M2TS_DVB_TIME_SLICE_FEC_DESCRIPTOR: + { + descriptorTime_slice_fec_identifier(ip_str,data); + } + break; + case GF_M2TS_DVB_STREAM_LOCATION_DESCRIPTOR: + { + descriptorLocation(ip_str , data); + }break; + default: + break; + } + + + return length; // (descriptor total length) +} + +void descriptorTime_slice_fec_identifier( GF_M2TS_IP_Stream *ip_str,u8 * data) +{ + + ip_str->time_slice_fec.time_slicing = (data[2] >> 7) & 0x1; + ip_str->time_slice_fec.mpe_fec = (data[2] >> 5 ) & 0x3 ; + ip_str->time_slice_fec.frame_size = data[2] & 0x7 ; + ip_str->time_slice_fec.max_burst_duration = data[3]; + ip_str->time_slice_fec.max_average_rate = (data[4] >> 4) & 0xf ; + ip_str->time_slice_fec.time_slice_fec_id = data[4] & 0xf; + ip_str->time_slice_fec.id_selector = gf_malloc( data[1] - 3 ) ; + memcpy(ip_str->time_slice_fec.id_selector, data + 4, data[1]-3 ); + return ; +} + +void descriptorLocation(GF_M2TS_IP_Stream *ip_str , u8 * data) +{ + ip_str->location.network_id = (data[2]<<8)|data[3]; + ip_str->location.original_network_id = (data[4]<<8)|data[5]; + ip_str->location.transport_stream_id = (data[6]<<8)|data[7]; + ip_str->location.service_id = (data[8]<<8)|data[9]; + ip_str->location.component_tag = data[10]; + return; +} + +void gf_m2ts_target_ip(GF_M2TS_IP_Stream* ip_str, u8 * data) +{ + u32 i,j; + u8 length; + i=j=0; + ip_str->targets = gf_list_new(); + length = data[1]; + for(i=0;i<length;i= i+5) + { + GF_M2TS_IP_Target* ip_data; + GF_SAFEALLOC(ip_data,GF_M2TS_IP_Target); + //ip_data=gf_malloc(sizeof(GF_M2TS_IP_Target)); + ip_data->type = 0; + ip_data->address_mask = 0; + memcpy(ip_data->address, data+2+i, 4); + ip_data->slash_mask=data[2+i+4]; + + gf_list_add(ip_str->targets,ip_data); + } + + return; +} + + +/*generate RS code and fullfill the RS table of MPE_FEC_FRAME*/ +void encode_fec(MPE_FEC_FRAME * mff) +{ +#if 0 + u8 adt_rs_en_buffer [ MPE_ADT_COLS + MPE_RS_COLS ]; + u32 rows = mff->rows; + u32 i = 0; + u32 cols = 0; + + cols = mff->col_adt; + for ( i = 0; i < rows; i ++ ) { + /* read a row from ADT into buffer */ + getRowFromADT(mff, i, adt_rs_en_buffer); + /* ************** */ + /* 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); + /*set a row of RS into RS table*/ + setRowRS ( mff, i , (unsigned char *)(adt_rs_en_buffer + cols) ); + } +#endif +} + +/*decode the MPE_FEC_FRAME*/ +void decode_fec(MPE_FEC_FRAME * mff) +{ + u32 i,ML,offset; + u8 *data; + u8 linebuffer[255]; + + //printf("Starting FEC decoding ...\n"); + + data = gf_malloc((mff->rows*191)*sizeof(char)); + memset(data,0,sizeof(data)); + + initialize_ecc (); + ML = 255; + memset(linebuffer, 0, 255); + offset = 0; + + /*printf("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"); + 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); + print_bytes(mff->p_rs+512+512+512, 32, 1, 1);*/ + + for ( i = 0; i < mff->rows; i ++ ) { + u8 tmp[255]; + + getRowFromADT(mff, i, linebuffer); + getRowFromRS(mff, i, linebuffer + mff->col_adt); + + encode_data(linebuffer, 191, tmp); + + decode_data(linebuffer, ML); + if (check_syndrome () != 0) { + u32 nerasures = 0; + u32 *erasures = NULL; + + /* 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); + } + + /* TODO: replace the current line in MFF */ + } + + memcpy(data+offset,linebuffer,sizeof(data)); + offset += 191; + } + //printf("FEC decoding done.\n"); + memcpy(mff->p_adt,data,sizeof(data)); + //gf_m2ts_ipdatagram_reader(mff->p_adt,ip_datagram); + + +} + + +void gf_m2ts_gather_ipdatagram_information(MPE_FEC_FRAME *mff,GF_M2TS_Demuxer *ts) +{ + GF_M2TS_IP_Packet *ip_packet; + u8* ip_datagram; + u32 i, i_holes,i_streams, i_targets,k,j,l; + MPE_Error_Holes *mff_holes; + u32 offset; /* offset to get through the datagram */ + //GF_TSImport *tsimp = (GF_TSImport *) ts->user; + //GF_MediaImporter *import= (GF_MediaImporter *)tsimp->import; + GF_M2TS_IP_Stream *ip_stream_buff; + GF_M2TS_IP_Target *ip_targets; + GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform; + + + offset =0; + ip_datagram = mff->p_adt; + GF_SAFEALLOC(ip_packet,GF_M2TS_IP_Packet); + GF_SAFEALLOC(mff_holes,MPE_Error_Holes); + + while(offset<mff->current_offset_adt) + { + /* Find the parts of the ADT which contain errors and skip them */ + if((mff->p_error_adt+offset)[0] == 0x01010101) + { + i_holes = gf_list_count(mff->mpe_holes); + for(i=0;i<i_holes;i++) + { + mff_holes=gf_list_get(mff->mpe_holes, i); + if(mff_holes->offset == offset) + { + offset += mff_holes->length; + break; + } + } + + } + + if(gf_m2ts_ipdatagram_reader(ip_datagram, ip_packet, offset)){ + + + /* update the offset */ + //offset += ip_packet->u32_total_length; + offset += (ip_packet->u32_hdr_length*4) + ip_packet->u32_udp_data_size; + + if(ip_platform->all_info_gathered != 1) + { + + i_streams = 0; + i_targets = 0; + + + + i_streams = gf_list_count(ip_platform->ip_streams); + for(k=0;k<i_streams;k++) + { + ip_stream_buff=gf_list_get(ip_platform->ip_streams, k); + + if(ip_stream_buff == NULL || ip_stream_buff->stream_info_gathered ==1) + { + break; + } + else + { + i_targets = gf_list_count(ip_stream_buff->targets); + l=0; + for(j=0;j<i_targets;j++) + { + ip_targets = gf_list_get(ip_stream_buff->targets, j); + + if(gf_m2ts_compare_ip(ip_packet->u8_rx_adr,ip_targets->address)) + { + for(l=0;l<9;l++) + { + if(ip_targets->rx_port[l] == ip_packet->u32_rx_udp_port) goto next; + if(ip_targets->rx_port[l] ==0) break; + } + + ip_targets->rx_port[l] = ip_packet->u32_rx_udp_port; + ip_stream_buff->PID = mff->PID; + goto next; + + + } + + } + } + } + } + }else{ + + offset += (ip_packet->u32_hdr_length*4) + ip_packet->u32_udp_data_size; + } +next :; + + } + empty_list(mff->mpe_holes); + gf_list_del(mff->mpe_holes); + mff->mpe_holes = NULL; + gf_m2ts_Delete_IpPacket(ip_packet); + +} + +void gf_m2ts_print_mpe_info(GF_M2TS_Demuxer *ts) +{ + u32 i_streams, i_targets,i,j,l; + GF_M2TS_IP_Stream *ip_stream_buff; + GF_M2TS_IP_Target *ip_targets; + u8 *ip_adress; + GF_M2TS_IP_PLATFORM * ip_platform = ts->ip_platform; + 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); + + i_streams = 0; + i_targets = 0; + + + i_streams = gf_list_count(ip_platform->ip_streams); + 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"); + /*Print the target IP adress */ + i_targets = gf_list_count(ip_stream_buff->targets); + for(j=0;j<i_targets;j++) + { + ip_targets = gf_list_get(ip_stream_buff->targets, j); + + 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 :"); + while(ip_targets->rx_port[l] != 0) + { + printf(" %d ",ip_targets->rx_port[l]); + l++; + } + printf("\n"); + + + } + + /*Print the time slice fec descriptor */ + printf("Time Slice Fec Descriptor : \n"); + + if(ip_stream_buff->time_slice_fec.time_slicing==0) + { + printf(" No Time Slicing \n"); + }else + { + printf(" Time Slicing\n"); + } + + if(ip_stream_buff->time_slice_fec.mpe_fec==0) + { + printf(" No MPE FEC used \n"); + }else + { + printf(" 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"); + }break; + case 1: + { + printf(" Frame size : 512 rows \n"); + printf(" Max Burst Duration 1024 kbits\n"); + }break; + case 2: + { + printf(" Frame size : 768 rows \n"); + printf(" Max Burst Duration 1536 kbits\n"); + }break; + case 3: + { + printf(" Frame size : 1024 rows \n"); + printf(" 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); + + /* 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); + + + getchar(); // attendre l'appuie d'une touche + } + + + +} + + +void socket_simu(GF_M2TS_IP_Packet *ip_packet, GF_M2TS_Demuxer *ts) +{ + int j = 1; + char name[100]; + u32 ipv4_addr; + GF_Err e; + u8 nb_socket_struct, i; + GF_SOCK_ENTRY *Sock_Struct; + + if(ts->ip_platform->socket_struct == NULL) ts->ip_platform->socket_struct= gf_list_new(); + + + ip_packet->sock = NULL; + ipv4_addr = GF_4CC(ip_packet->u8_rx_adr[0], ip_packet->u8_rx_adr[1], ip_packet->u8_rx_adr[2], ip_packet->u8_rx_adr[3]); + nb_socket_struct = gf_list_count(ts->ip_platform->socket_struct); + for(i=0;i<nb_socket_struct;i++) { + Sock_Struct = gf_list_get(ts->ip_platform->socket_struct,i); + + if ((Sock_Struct->ipv4_addr==ipv4_addr)&& (Sock_Struct->port == (u16) ip_packet->u32_rx_udp_port)) + { + if (Sock_Struct->bind_failure) return; + ip_packet->sock = Sock_Struct->sock; + break; + } + } + if (ip_packet->sock == NULL) { + GF_SAFEALLOC(Sock_Struct, GF_SOCK_ENTRY); + + Sock_Struct->ipv4_addr = ipv4_addr; + Sock_Struct->port = ip_packet->u32_rx_udp_port; + Sock_Struct->sock = gf_sk_new(GF_SOCK_TYPE_UDP); + if (Sock_Struct->sock == NULL) { + gf_free(Sock_Struct); + return; + } + + sprintf(name, "%d.%d.%d.%d", ip_packet->u8_rx_adr[0],ip_packet->u8_rx_adr[1], ip_packet->u8_rx_adr[2],ip_packet->u8_rx_adr[3]); + + + if (gf_sk_is_multicast_address(name) ) { + e = gf_sk_setup_multicast(Sock_Struct->sock, name, ip_packet->u32_rx_udp_port, 1/*TTL - FIXME this should be in a cfg file*/, 0, NULL/*FIXME this should be in a cfg file*/); + } else { + /* + binding of the socket to send data to port 4600 on the local machine + the first adress / port parameters are NULL or 0 because there are not needed for sending UDP datagrams + the second adress is "localhost" and the port is the destination port on localhost + */ + e = gf_sk_bind(Sock_Struct->sock, "127.0.0.1", ip_packet->u32_rx_udp_port,/*name*/"127.0.0.1", ip_packet->u32_rx_udp_port, 0); + } + + if (e != GF_OK) { + fprintf(stderr, "Server Bind Error: %s\n", gf_error_to_string(e)); + Sock_Struct->bind_failure = 1; + } + + ip_packet->sock = Sock_Struct->sock; + gf_list_add(ts->ip_platform->socket_struct, Sock_Struct); + } + + // ******************************************************** + // Envoi des données + // ******************************************************** + + e = gf_sk_send(ip_packet->sock, ip_packet->data, ip_packet->u32_udp_data_size - 8); + if (e != GF_OK){ + fprintf(stdout, "Error sending to \n"); + } + gf_sleep(10); + +} + +/*void gf_sock_shutdown() +{ + gf_sk_del(sock); +}*/ + +/* allocate the necessary memory space*/ +Bool init_frame(MPE_FEC_FRAME * mff, u32 rows) +{ + assert (mff != NULL); + if (rows != 256 && rows != 512 && rows != 768 && rows != 1024) return 0; + mff->rows = rows ; + mff->col_adt = MPE_ADT_COLS; + mff->col_rs = MPE_RS_COLS; + mff->p_adt = (u8 *)gf_calloc(MPE_ADT_COLS*rows,sizeof(u8)); + mff->p_rs = (u8 *)gf_calloc(MPE_RS_COLS*rows,sizeof(u8)); + + + printf("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)); + mff->p_error_rs = (u32 *)gf_calloc(mff->col_rs*rows,sizeof(u32)); + mff->current_offset_adt = 0; + 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 ); + mff->mpe_holes = gf_list_new(); + mff->initialized = 1; + return 1; +} + +void resetMFF(MPE_FEC_FRAME * mff) +{ + mff->current_offset_adt = 0; + mff->current_offset_rs = 0; + memset(mff->p_error_adt, 0, mff->col_adt * mff->rows*sizeof(u32)); + memset(mff->p_error_rs, 0, mff->col_rs * mff->rows*sizeof(u32)); + memset(mff->p_adt, 0, MPE_ADT_COLS* mff->rows*sizeof(u8)); + memset(mff->p_rs, 0, MPE_RS_COLS* mff->rows*sizeof(u8)); + mff->ADT_done = 0; + mff->PID = 0; + if(mff->mpe_holes){ + empty_list(mff->mpe_holes); + //gf_list_del(mff->mpe_holes); + } + +} + +/* return a row of appplicatio data table*/ +void getRowFromADT(MPE_FEC_FRAME * mff, u32 index, u8* adt_row) +{ + u32 i = 0 ; + u32 base = 0; + //assert ( sizeof ( adt_row ) >= MPE_ADT_COLS ); + for ( i = 0; i < mff->col_adt ; i ++ ) { + adt_row [ i ] = mff -> p_adt [ index + base ]; + base += mff-> rows ; + } +} + +/*return a row of RS table*/ +void getRowFromRS (MPE_FEC_FRAME * mff, u32 index, u8* rs_row) +{ + u32 i = 0 ; + u32 base = 0; + assert (rs_row != NULL ); + //assert (sizeof ( rs_row ) >= MPE_ADT_COLS ); + for ( i = 0; i < mff->col_rs ; i ++ ) { + rs_row [ i ] = mff -> p_rs [ index + base ]; + base += mff -> rows ; + } +} + +void setRowRS(MPE_FEC_FRAME *mff, u32 index, u8 *p_rs) +{ + u32 i = 0; + u32 base = 0; + assert ( p_rs != NULL ); + //assert ( sizeof (p_rs ) >= MPE_RS_COLS ) ; + for ( i = 0; i < mff -> col_rs; i ++ ) { + mff -> p_rs [ base + index ] = p_rs [ i]; + base += mff -> rows; + } + +} +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 ); + for ( i = offset ; i <mff->capacity_total; i ++ ) + mff -> p_adt [i] = 0xff ; +} + +static void print_bytes2(u8 * data, u32 length ) /*print_bytes2 */ +{ + u32 i = 0; + u32 row_num = 0; + u32 k = 0; + for ( i = 0; i < length ; i ++ ) { + if (k == 0) { + printf("%x0 : ", row_num); + k = 0; + } + printf("%#x ", data[i]); + k++; + if (k == 16) { + printf("\n"); + k = 0; + row_num ++; + } + } +} + +/*add a ip datagram into mpe fec frame, and indicate error positions*/ +void setIpDatagram(MPE_FEC_FRAME * mff, u32 offset, u8* dgram, u32 length ) +{ + MPE_Error_Holes *mpe_error_holes; + + GF_SAFEALLOC(mpe_error_holes,MPE_Error_Holes); + + + if (offset >= mff->capacity_total) { + printf ("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 ); + } + 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); + 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); + } + setErrorIndicator( mff->p_error_adt , mff->current_offset_adt , (offset - mff->current_offset_adt)*sizeof(u32) ) ; + mpe_error_holes->offset = mff->current_offset_adt; + mpe_error_holes->length = offset - mff->current_offset_adt; + gf_list_add(mff->mpe_holes,mpe_error_holes); + mff->current_offset_adt = offset ; // update the offset + } + + memcpy(mff->p_adt+mff->current_offset_adt,dgram, length); + mff->current_offset_adt = offset+length ; // update the offset + +} +/*set RS data into mpe fec frame*/ +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 ); + mff->current_offset_rs = offset; + setErrorIndicator( mff->p_error_rs , mff->current_offset_rs , (offset - mff->current_offset_rs)*sizeof(u32)); + } + assert(mff->rows == length); + memcpy(mff->p_rs + mff->current_offset_rs , pds, length*sizeof(u8) ); + mff->current_offset_rs = offset + length ; + +} + +void getColRS(MPE_FEC_FRAME * mff, u32 offset, u8 * pds, u32 length) +{ + + memcpy(pds,mff->p_rs + offset, length); + +} + +void getErrorPositions(MPE_FEC_FRAME *mff, u32 row, u32 * errPositions) +{ + u32 i = 0 ; + u32 base = row; + /*get error from adt*/ + for ( i = 0; i < mff->col_adt ; i ++ ) { + errPositions [i] = mff->p_error_adt[base ]; + base += mff->rows; + } + base = row; + for ( i = mff->col_adt ; i < mff->col_adt + mff-> col_rs ; i ++ ) { + errPositions [i] = mff->p_error_rs [ base ]; + base += mff->rows ; + } +} + +u32 getErrasurePositions( MPE_FEC_FRAME *mff , u32 row, u32 *errasures) +{ + u32 i = 0; + u32 base = row; + u32 nb = 0; + u32 k =0; + for ( i = 0 ; i < mff-> col_rs ; i ++ ) { + if ( mff->p_error_rs[base] == 1 ) { + errasures [k++] = mff->p_error_rs [ base ]; + nb ++; + } + base += mff->rows ; + } + printf (" the erasure locations is:\n"); + for ( i = 0; i < nb ; i ++ ) + printf("%d ", errasures[i]); + return nb; +} + +void setErrorIndicator(u32 * data , u32 offset,u32 length) +{ +// printf("setting the error indication \n"); + memset(data+offset, 1, length); +} + + +/*void descriptor_PRIVATE (u8 *b, DTAG_SCOPE tag_scope){ + printf ("private descriptor \n"); + return ; +}*/ diff --git a/src/media_tools/filestreamer.c b/src/media_tools/filestreamer.c new file mode 100644 index 0000000..86fe291 --- /dev/null +++ b/src/media_tools/filestreamer.c @@ -0,0 +1,523 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Cyril Concolato / Jean Le Feuvre 2000-2005 + * All rights reserved + * + * This file is part of GPAC / mp4 simple streamer application + * + * 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/isomedia.h> +#include <gpac/ietf.h> +#include <gpac/config_file.h> +#include <gpac/base_coding.h> +#include <gpac/internal/media_dev.h> +#include <gpac/filestreamer.h> +#include <gpac/rtp_streamer.h> +#include <gpac/constants.h> +#include <gpac/math.h> + +#if !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_STREAMING) + + +typedef struct __tag_rtp_track +{ + struct __tag_rtp_track *next; + + GF_RTPStreamer *rtp; + u16 port; + + /*scale from TimeStamps in media timescales to TimeStamps in microseconds*/ + Double microsec_ts_scale; + + /*NALU size for H264/AVC parsing*/ + u32 avc_nalu_size; + + /*track info*/ + u32 track_num; + u32 timescale; + u32 nb_aus; + + /*loaded AU info*/ + GF_ISOSample *au; + u32 current_au; + u32 sample_duration; + u32 sample_desc_index; + /*normalized DTS in micro-sec*/ + u64 microsec_dts; + + /*offset of CTS/DTS in media timescale, used when looping the track*/ + u32 ts_offset; + /*offset of CTS/DTS in microseconds, used when looping the track*/ + u32 microsec_ts_offset; +} GF_RTPTrack; + + +struct __isom_rtp_streamer +{ + GF_ISOFile *isom; + char *dest_ip; + Bool loop; + Bool force_mpeg4_generic; + /*timeline origin of our session (all tracks) in microseconds*/ + u32 timelineOrigin; + /*list of streams in session*/ + GF_RTPTrack *stream; + + /*to sync looping sessions with tracks of # length*/ + u32 duration_ms; +}; + + + +static GF_Err gf_isom_streamer_setup_sdp(GF_ISOMRTPStreamer *streamer, char*sdpfilename, char **out_sdp_buffer) +{ + GF_RTPTrack *track; + FILE *sdp_out; + char filename[GF_MAX_PATH]; + char sdpLine[20000]; + + strcpy(filename, sdpfilename ? sdpfilename : "videosession.sdp"); + sdp_out = gf_f64_open(filename, "wt"); + if (!sdp_out) return GF_IO_ERR; + + if (!out_sdp_buffer) { + sprintf(sdpLine, "v=0"); + fprintf(sdp_out, "%s\n", sdpLine); + sprintf(sdpLine, "o=MP4Streamer 3357474383 1148485440000 IN IP%d %s", gf_net_is_ipv6(streamer->dest_ip) ? 6 : 4, streamer->dest_ip); + fprintf(sdp_out, "%s\n", sdpLine); + sprintf(sdpLine, "s=livesession"); + fprintf(sdp_out, "%s\n", sdpLine); + sprintf(sdpLine, "i=This is an MP4 time-sliced Streaming demo"); + fprintf(sdp_out, "%s\n", sdpLine); + sprintf(sdpLine, "u=http://gpac.sourceforge.net"); + fprintf(sdp_out, "%s\n", sdpLine); + sprintf(sdpLine, "e=admin@"); + fprintf(sdp_out, "%s\n", sdpLine); + sprintf(sdpLine, "c=IN IP%d %s", gf_net_is_ipv6(streamer->dest_ip) ? 6 : 4, streamer->dest_ip); + fprintf(sdp_out, "%s\n", sdpLine); + sprintf(sdpLine, "t=0 0"); + fprintf(sdp_out, "%s\n", sdpLine); + sprintf(sdpLine, "a=x-copyright: Streamed with GPAC (C)2000-200X - http://gpac.sourceforge.net\n"); + fprintf(sdp_out, "%s\n", sdpLine); + } + + track = streamer->stream; + while (track) { + char *sdp_media=NULL; + const char *KMS = NULL; + char *dsi = NULL; + u32 w, h; + u32 dsi_len = 0; + GF_DecoderConfig *dcd = gf_isom_get_decoder_config(streamer->isom, track->track_num, 1); + + if (dcd && dcd->decoderSpecificInfo) { + dsi = dcd->decoderSpecificInfo->data; + dsi_len = dcd->decoderSpecificInfo->dataLength; + } + w = h = 0; + if (gf_isom_get_media_type(streamer->isom, track->track_num) == GF_ISOM_MEDIA_VISUAL) { + gf_isom_get_visual_info(streamer->isom, track->track_num, 1, &w, &h); + } + + gf_isom_get_ismacryp_info(streamer->isom, track->track_num, 1, NULL, NULL, NULL, NULL, &KMS, NULL, NULL, NULL); + + /*TODO retrieve DIMS content encoding from track to set the flags */ + gf_rtp_streamer_append_sdp_extended(track->rtp, gf_isom_get_track_id(streamer->isom, track->track_num), dsi, dsi_len, streamer->isom, track->track_num, (char *)KMS, w, h, &sdp_media); + if (sdp_media) { + fprintf(sdp_out, "%s", sdp_media); + gf_free(sdp_media); + } + + if (dcd) gf_odf_desc_del((GF_Descriptor *)dcd); + + track = track->next; + } + fprintf(sdp_out, "\n"); + + fclose(sdp_out); + if (out_sdp_buffer) { + u64 size; + sdp_out = gf_f64_open(filename, "r"); + gf_f64_seek(sdp_out, 0, SEEK_END); + size = gf_f64_tell(sdp_out); + gf_f64_seek(sdp_out, 0, SEEK_SET); + if (*out_sdp_buffer) gf_free(*out_sdp_buffer); + *out_sdp_buffer = gf_malloc(sizeof(char)*(size_t)(size+1)); + size = fread(*out_sdp_buffer, 1, (size_t)size, sdp_out); + fclose(sdp_out); + (*out_sdp_buffer)[size]=0; + } + + return GF_OK; +} + +GF_Err gf_isom_streamer_write_sdp(GF_ISOMRTPStreamer *streamer, char*sdpfilename) +{ + return gf_isom_streamer_setup_sdp(streamer, sdpfilename, NULL); +} + +GF_Err gf_isom_streamer_get_sdp(GF_ISOMRTPStreamer *streamer, char **out_sdp_buffer) +{ + return gf_isom_streamer_setup_sdp(streamer, NULL, out_sdp_buffer); +} + + +void gf_isom_streamer_reset(GF_ISOMRTPStreamer *streamer, Bool is_loop) +{ + GF_RTPTrack *track; + if (!streamer) return; + track = streamer->stream; + while (track) { + if (is_loop) { + Double scale = track->timescale/1000.0; + track->ts_offset += (u32) (streamer->duration_ms * scale); + track->microsec_ts_offset = (u32) (track->ts_offset*(1000000.0/track->timescale)) + streamer->timelineOrigin; + } else { + track->ts_offset += 0; + track->microsec_ts_offset = 0; + } + track->current_au = 0; + track = track->next; + } + if (is_loop) streamer->timelineOrigin = 0; +} + +GF_Err gf_isom_streamer_send_next_packet(GF_ISOMRTPStreamer *streamer, s32 send_ahead_delay, s32 max_sleep_time) +{ + GF_Err e = GF_OK; + GF_RTPTrack *track, *to_send; + u32 time, duration; + s32 diff; + u64 min_ts, dts, cts; + + if (!streamer) return GF_BAD_PARAM; + + /*browse all sessions and locate most mature stream*/ + to_send = NULL; + min_ts = (u64) -1; + + time = gf_sys_clock(); + + /*init session timeline - all sessions are sync'ed for packet scheduling purposes*/ + if (!streamer->timelineOrigin) + streamer->timelineOrigin = time*1000; + + track = streamer->stream; + while (track) { + /*load next AU*/ + if (!track->au) { + if (track->current_au >= track->nb_aus) { + Double scale; + if (!streamer->loop) { + track = track->next; + continue; + } + /*increment ts offset*/ + scale = track->timescale/1000.0; + track->ts_offset += (u32) (streamer->duration_ms * scale); + track->microsec_ts_offset = (u32) (track->ts_offset*(1000000.0/track->timescale)) + streamer->timelineOrigin; + track->current_au = 0; + } + + track->au = gf_isom_get_sample(streamer->isom, track->track_num, track->current_au + 1, &track->sample_desc_index); + track->current_au ++; + if (track->au) { + track->microsec_dts = (u64) (track->microsec_ts_scale * (s64) (track->au->DTS)) + track->microsec_ts_offset + streamer->timelineOrigin; + } + } + + /*check timing*/ + if (track->au) { + if (min_ts > track->microsec_dts) { + min_ts = track->microsec_dts; + to_send = track; + } + } + + track = track->next; + } + + /*no input data ...*/ + if( !to_send) return GF_EOS; + min_ts /= 1000; + + if (max_sleep_time) { + diff = ((u32) min_ts) - gf_sys_clock(); + if (diff>max_sleep_time) + return GF_OK; + } + + /*sleep until TS is mature*/ + while (1) { + diff = ((u32) min_ts) - gf_sys_clock(); + + if (diff > send_ahead_delay) { + gf_sleep(1); + } else { + if (diff<10) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTP, ("WARNING: RTP session %s stream %d - sending packet %d ms too late\n", gf_isom_get_filename(streamer->isom), to_send->track_num, -diff)); + } + break; + } + } + + /*send packets*/ + + dts = to_send->au->DTS + to_send->ts_offset; + cts = to_send->au->DTS + to_send->au->CTS_Offset + to_send->ts_offset; + duration = gf_isom_get_sample_duration(streamer->isom, to_send->track_num, to_send->current_au); + + /*unpack nal units*/ + if (to_send->avc_nalu_size) { + Bool au_start, au_end; + u32 v, size; + u32 remain = to_send->au->dataLength; + char *ptr = to_send->au->data; + + au_start = 1; + au_end = 0; + while (remain) { + size = 0; + v = to_send->avc_nalu_size; + while (v) { + size |= (u8) *ptr; + ptr++; + remain--; + v-=1; + if (v) size<<=8; + } + remain -= size; + au_end = remain ? 0 : 1; + + e = gf_rtp_streamer_send_data(to_send->rtp, ptr, size, to_send->au->dataLength, cts, dts, to_send->au->IsRAP, au_start, au_end, to_send->current_au, duration, to_send->sample_desc_index); + ptr += size; + au_start = 0; + } + } else { + e = gf_rtp_streamer_send_data(to_send->rtp, to_send->au->data, to_send->au->dataLength, to_send->au->dataLength, cts, dts, to_send->au->IsRAP, 1, 1, to_send->current_au, duration, to_send->sample_desc_index); + } + /*delete sample*/ + gf_isom_sample_del(&to_send->au); + + return e; +} + +static u16 check_next_port(GF_ISOMRTPStreamer *streamer, u16 first_port) +{ + GF_RTPTrack *track = streamer->stream; + while (track) { + if (track->port==first_port) { + return check_next_port(streamer, (u16) (first_port+2) ); + } + track = track->next; + } + return first_port; +} + +GF_ISOMRTPStreamer *gf_isom_streamer_new(const char *file_name, const char *ip_dest, u16 port, Bool loop, Bool force_mpeg4, u32 path_mtu, u32 ttl, char *ifce_addr) +{ + GF_ISOMRTPStreamer *streamer; + GF_Err e = GF_OK; + const char *opt = NULL; + const char *dest_ip; + GF_Config *configFile = NULL; + u32 i, max_ptime, au_sn_len; + u8 payt; + GF_ISOFile *file; + GF_RTPTrack *track, *prev_track; + u16 first_port; + u32 nb_tracks; + u32 sess_data_size; + + if (!ip_dest) ip_dest = "127.0.0.1"; + if (!port) port = 7000; + if (!path_mtu) path_mtu = 1450; + + GF_SAFEALLOC(streamer, GF_ISOMRTPStreamer); + streamer->dest_ip = gf_strdup(ip_dest); + + dest_ip = ip_dest; + payt = 96; + max_ptime = au_sn_len = 0; + + file = gf_isom_open(file_name, GF_ISOM_OPEN_READ, NULL); + if (!file) { + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("Error opening file %s: %s\n", opt, gf_error_to_string(gf_isom_last_error(NULL)))); + return NULL; + } + + streamer->isom = file; + streamer->loop = loop; + streamer->force_mpeg4_generic = force_mpeg4; + first_port = port; + + sess_data_size = 0; + prev_track = NULL; + + nb_tracks = gf_isom_get_track_count(streamer->isom); + for (i=0; i<nb_tracks; i++) { + u32 mediaSize, mediaDuration, flags, MinSize, MaxSize, avgTS, streamType, oti, const_dur, nb_ch, samplerate, maxDTSDelta, TrackMediaSubType, TrackMediaType, bandwidth, IV_length, KI_length, dsi_len; + const char *url, *urn; + char *dsi; + Bool is_crypted; + + dsi_len = samplerate = streamType = oti = nb_ch = IV_length = KI_length = 0; + is_crypted = 0; + dsi = NULL; + + flags = 0; + + /*we only support self-contained files for hinting*/ + gf_isom_get_data_reference(streamer->isom, i+1, 1, &url, &urn); + if (url || urn) continue; + + TrackMediaType = gf_isom_get_media_type(streamer->isom, i+1); + TrackMediaSubType = gf_isom_get_media_subtype(streamer->isom, i+1, 1); + + switch (TrackMediaType) { + case GF_ISOM_MEDIA_TEXT: + break; + case GF_ISOM_MEDIA_VISUAL: + case GF_ISOM_MEDIA_AUDIO: + case GF_ISOM_MEDIA_SUBT: + case GF_ISOM_MEDIA_OD: + case GF_ISOM_MEDIA_SCENE: + if (gf_isom_get_sample_description_count(streamer->isom, i+1) > 1) continue; + break; + default: + continue; + } + + GF_SAFEALLOC(track, GF_RTPTrack); + if (prev_track) prev_track->next = track; + else streamer->stream = track; + prev_track = track; + + track->track_num = i+1; + + track->nb_aus = gf_isom_get_sample_count(streamer->isom, track->track_num); + track->timescale = gf_isom_get_media_timescale(streamer->isom, track->track_num); + mediaDuration = (u32)(gf_isom_get_media_duration(streamer->isom, track->track_num)*1000/track->timescale); // ms + mediaSize = (u32)gf_isom_get_media_data_size(streamer->isom, track->track_num); + + sess_data_size += mediaSize; + if (mediaDuration > streamer->duration_ms) streamer->duration_ms = mediaDuration; + + track->port = check_next_port(streamer, first_port); + first_port = track->port+2; + + /*init packetizer*/ + if (streamer->force_mpeg4_generic) flags = GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_FORCE_MPEG4; + + + switch (TrackMediaSubType) { + case GF_ISOM_SUBTYPE_MPEG4_CRYP: + is_crypted = 1; + case GF_ISOM_SUBTYPE_MPEG4: + { + GF_ESD *esd = gf_isom_get_esd(streamer->isom, track->track_num, 1); + if (esd) { + streamType = esd->decoderConfig->streamType; + oti = esd->decoderConfig->objectTypeIndication; + + /*systems streams*/ + if (streamType==GF_STREAM_AUDIO) { + gf_isom_get_audio_info(streamer->isom, track->track_num, 1, &samplerate, &nb_ch, NULL); + } + /*systems streams*/ + else if (streamType==GF_STREAM_SCENE) { + if (gf_isom_has_sync_shadows(streamer->isom, track->track_num) || gf_isom_has_sample_dependency(streamer->isom, track->track_num)) + flags |= GP_RTP_PCK_SYSTEMS_CAROUSEL; + } + + if (esd->decoderConfig->decoderSpecificInfo) { + dsi = esd->decoderConfig->decoderSpecificInfo->data; + dsi_len = esd->decoderConfig->decoderSpecificInfo->dataLength; + esd->decoderConfig->decoderSpecificInfo->data = NULL; + esd->decoderConfig->decoderSpecificInfo->dataLength = 0; + } + gf_odf_desc_del((GF_Descriptor*)esd); + } + } + break; + case GF_ISOM_SUBTYPE_AVC_H264: + case GF_ISOM_SUBTYPE_AVC2_H264: + case GF_ISOM_SUBTYPE_SVC_H264: + { + GF_AVCConfig *avcc = gf_isom_avc_config_get(streamer->isom, track->track_num, 1); + track->avc_nalu_size = avcc->nal_unit_size; + gf_odf_avc_cfg_del(avcc); + streamType = GF_STREAM_VISUAL; + oti = GPAC_OTI_VIDEO_AVC; + } + break; + default: + streamType = GF_STREAM_4CC; + oti = TrackMediaSubType; + break; + } + + /*get sample info*/ + gf_media_get_sample_average_infos(streamer->isom, track->track_num, &MinSize, &MaxSize, &avgTS, &maxDTSDelta, &const_dur, &bandwidth); + + if (is_crypted) { + Bool use_sel_enc; + gf_isom_get_ismacryp_info(streamer->isom, track->track_num, 1, NULL, NULL, NULL, NULL, NULL, &use_sel_enc, &IV_length, &KI_length); + if (use_sel_enc) flags |= GP_RTP_PCK_SELECTIVE_ENCRYPTION; + } + + track->rtp = gf_rtp_streamer_new_extended(streamType, oti, track->timescale, + (char *) streamer->dest_ip, track->port, path_mtu, ttl, ifce_addr, + flags, dsi, dsi_len, + payt, samplerate, nb_ch, + is_crypted, IV_length, KI_length, + MinSize, MaxSize, avgTS, maxDTSDelta, const_dur, bandwidth, max_ptime, au_sn_len); + + if (!track->rtp) { + GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("Could not initialize RTP streamer: %s\n", gf_error_to_string(e))); + goto exit; + } + + payt++; + track->microsec_ts_scale = 1000000; + track->microsec_ts_scale /= gf_isom_get_media_timescale(streamer->isom, track->track_num); + } + return streamer; + +exit: + gf_free(streamer); + return NULL; +} + +void gf_isom_streamer_del(GF_ISOMRTPStreamer *streamer) +{ + GF_RTPTrack *track = streamer->stream; + while (track) { + GF_RTPTrack *tmp = track; + if (track->au) gf_isom_sample_del(&track->au); + if (track->rtp) gf_rtp_streamer_del(track->rtp); + track = track->next; + gf_free(tmp); + } + if (streamer->isom) gf_isom_close(streamer->isom); + gf_free(streamer->dest_ip); + gf_free(streamer); +} + +#endif /* !defined(GPAC_DISABLE_ISOM) && !defined(GPAC_DISABLE_STREAMING) */ diff --git a/src/media_tools/gpac_ogg.c b/src/media_tools/gpac_ogg.c index 9d860e5..967d2bc 100644 --- a/src/media_tools/gpac_ogg.c +++ b/src/media_tools/gpac_ogg.c @@ -24,6 +24,7 @@ #include <gpac/internal/ogg.h> +#ifndef GPAC_DISABLE_OGG #define BUFFER_INCREMENT 256 @@ -41,7 +42,7 @@ static u32 mask8B[]= void oggpack_writeinit(oggpack_buffer *b){ memset(b,0,sizeof(*b)); - b->ptr = b->buffer = (unsigned char *)malloc(BUFFER_INCREMENT); + b->ptr = b->buffer = (unsigned char *)gf_malloc(BUFFER_INCREMENT); b->buffer[0]='\0'; b->storage=BUFFER_INCREMENT; } @@ -71,7 +72,7 @@ void oggpackB_writetrunc(oggpack_buffer *b,s32 bits){ /* Takes only up to 32 bits. */ void oggpack_write(oggpack_buffer *b,u32 value,s32 bits){ if(b->endbyte+4>=b->storage){ - b->buffer = (unsigned char *)realloc(b->buffer,b->storage+BUFFER_INCREMENT); + b->buffer = (unsigned char *)gf_realloc(b->buffer,b->storage+BUFFER_INCREMENT); b->storage+=BUFFER_INCREMENT; b->ptr=b->buffer+b->endbyte; } @@ -105,7 +106,7 @@ void oggpack_write(oggpack_buffer *b,u32 value,s32 bits){ /* Takes only up to 32 bits. */ void oggpackB_write(oggpack_buffer *b,u32 value,s32 bits){ if(b->endbyte+4>=b->storage){ - b->buffer = (unsigned char *)realloc(b->buffer,b->storage+BUFFER_INCREMENT); + b->buffer = (unsigned char *)gf_realloc(b->buffer,b->storage+BUFFER_INCREMENT); b->storage+=BUFFER_INCREMENT; b->ptr=b->buffer+b->endbyte; } @@ -169,7 +170,7 @@ static void oggpack_writecopy_helper(oggpack_buffer *b, /* aligned block copy */ if(b->endbyte+bytes+1>=b->storage){ b->storage=b->endbyte+bytes+BUFFER_INCREMENT; - b->buffer = (unsigned char *)realloc(b->buffer,b->storage); + b->buffer = (unsigned char *)gf_realloc(b->buffer,b->storage); b->ptr=b->buffer+b->endbyte; } @@ -206,7 +207,7 @@ void oggpackB_reset(oggpack_buffer *b){ } void oggpack_writeclear(oggpack_buffer *b){ - free(b->buffer); + gf_free(b->buffer); memset(b,0,sizeof(*b)); } @@ -618,11 +619,11 @@ s32 ogg_stream_init(ogg_stream_state *os,s32 serialno){ if(os){ memset(os,0,sizeof(*os)); os->body_storage=16*1024; - os->body_data = (unsigned char *)malloc(os->body_storage*sizeof(*os->body_data)); + os->body_data = (unsigned char *)gf_malloc(os->body_storage*sizeof(*os->body_data)); os->lacing_storage=1024; - os->lacing_vals=(s32 *)malloc(os->lacing_storage*sizeof(*os->lacing_vals)); - os->granule_vals=(s64*)malloc(os->lacing_storage*sizeof(*os->granule_vals)); + os->lacing_vals=(s32 *)gf_malloc(os->lacing_storage*sizeof(*os->lacing_vals)); + os->granule_vals=(s64*)gf_malloc(os->lacing_storage*sizeof(*os->granule_vals)); os->serialno=serialno; @@ -634,9 +635,9 @@ s32 ogg_stream_init(ogg_stream_state *os,s32 serialno){ /* _clear does not free os, only the non-flat storage within */ s32 ogg_stream_clear(ogg_stream_state *os){ if(os){ - if(os->body_data)free(os->body_data); - if(os->lacing_vals)free(os->lacing_vals); - if(os->granule_vals)free(os->granule_vals); + if(os->body_data)gf_free(os->body_data); + if(os->lacing_vals)gf_free(os->lacing_vals); + if(os->granule_vals)gf_free(os->granule_vals); memset(os,0,sizeof(*os)); } @@ -646,7 +647,7 @@ s32 ogg_stream_clear(ogg_stream_state *os){ s32 ogg_stream_destroy(ogg_stream_state *os){ if(os){ ogg_stream_clear(os); - free(os); + gf_free(os); } return(0); } @@ -657,15 +658,15 @@ s32 ogg_stream_destroy(ogg_stream_state *os){ static void _os_body_expand(ogg_stream_state *os,s32 needed){ if(os->body_storage<=os->body_fill+needed){ os->body_storage+=(needed+1024); - os->body_data = (unsigned char *)realloc(os->body_data,os->body_storage*sizeof(*os->body_data)); + os->body_data = (unsigned char *)gf_realloc(os->body_data,os->body_storage*sizeof(*os->body_data)); } } static void _os_lacing_expand(ogg_stream_state *os,s32 needed){ if(os->lacing_storage<=os->lacing_fill+needed){ os->lacing_storage+=(needed+32); - os->lacing_vals=(s32*)realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals)); - os->granule_vals=(s64*)realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals)); + os->lacing_vals=(s32*)gf_realloc(os->lacing_vals,os->lacing_storage*sizeof(*os->lacing_vals)); + os->granule_vals=(s64*)gf_realloc(os->granule_vals,os->lacing_storage*sizeof(*os->granule_vals)); } } @@ -917,7 +918,7 @@ s32 ogg_sync_init(ogg_sync_state *oy){ /* clear non-flat storage within */ s32 ogg_sync_clear(ogg_sync_state *oy){ if(oy){ - if(oy->data)free(oy->data); + if(oy->data)gf_free(oy->data); ogg_sync_init(oy); } return(0); @@ -926,7 +927,7 @@ s32 ogg_sync_clear(ogg_sync_state *oy){ s32 ogg_sync_destroy(ogg_sync_state *oy){ if(oy){ ogg_sync_clear(oy); - free(oy); + gf_free(oy); } return(0); } @@ -946,9 +947,9 @@ char *ogg_sync_buffer(ogg_sync_state *oy, s32 size){ s32 newsize=size+oy->fill+4096; /* an extra page to be nice */ if(oy->data) - oy->data = (unsigned char *)realloc(oy->data,newsize); + oy->data = (unsigned char *)gf_realloc(oy->data,newsize); else - oy->data = (unsigned char *)malloc(newsize); + oy->data = (unsigned char *)gf_malloc(newsize); oy->storage=newsize; } @@ -1320,7 +1321,8 @@ s32 ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op){ } void ogg_packet_clear(ogg_packet *op) { - free(op->packet); + gf_free(op->packet); memset(op, 0, sizeof(*op)); } +#endif /*GPAC_DISABLE_OGG*/ diff --git a/src/media_tools/img.c b/src/media_tools/img.c index eab16da..5a7fe6d 100644 --- a/src/media_tools/img.c +++ b/src/media_tools/img.c @@ -1,7 +1,7 @@ /* * GPAC - Multimedia Framework C SDK * - * Copyright (c) Jean Le Feuvre 2000-2005 + * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / Media Tools sub-project @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -56,7 +56,7 @@ void gf_img_parse(GF_BitStream *bs, u8 *OTI, u32 *mtype, u32 *width, u32 *height u64 pos; pos = gf_bs_get_position(bs); gf_bs_seek(bs, 0); - + *mtype = *width = *height = 0; *OTI = 0; if (dsi) { @@ -110,7 +110,7 @@ void gf_img_parse(GF_BitStream *bs, u8 *OTI, u32 *mtype, u32 *width, u32 *height break; } } - *OTI = 0x6C; + *OTI = GPAC_OTI_IMAGE_JPEG; *mtype = GF_4CC('j','p','e','g'); if (dsi) { GF_BitStream *bs_dsi = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); @@ -125,16 +125,16 @@ void gf_img_parse(GF_BitStream *bs, u8 *OTI, u32 *mtype, u32 *width, u32 *height /*PNG*/ else if ((b1==0x89) && (b2==0x50) && (b3==0x4E)) { /*check for PNG sig*/ - if ( (gf_bs_read_u8(bs) != 0x47) || (gf_bs_read_u8(bs) != 0x0D) || (gf_bs_read_u8(bs) != 0x0A) + if ( (gf_bs_read_u8(bs) != 0x47) || (gf_bs_read_u8(bs) != 0x0D) || (gf_bs_read_u8(bs) != 0x0A) || (gf_bs_read_u8(bs) != 0x1A) || (gf_bs_read_u8(bs) != 0x0A) ) goto exit; gf_bs_read_u32(bs); /*check for PNG IHDR*/ - if ( (gf_bs_read_u8(bs) != 'I') || (gf_bs_read_u8(bs) != 'H') + if ( (gf_bs_read_u8(bs) != 'I') || (gf_bs_read_u8(bs) != 'H') || (gf_bs_read_u8(bs) != 'D') || (gf_bs_read_u8(bs) != 'R')) goto exit; *width = gf_bs_read_u32(bs); *height = gf_bs_read_u32(bs); - *OTI = 0x6D; + *OTI = GPAC_OTI_IMAGE_PNG; *mtype = GF_4CC('p','n','g',' '); } size = gf_bs_read_u8(bs); @@ -143,7 +143,7 @@ void gf_img_parse(GF_BitStream *bs, u8 *OTI, u32 *mtype, u32 *width, u32 *height || (type==GF_4CC('j','p','2','h') ) ) { if (type==GF_4CC('j','p','2','h')) { - *OTI = 0x6E; + *OTI = GPAC_OTI_IMAGE_JPEG_2000; *mtype = GF_4CC('j','p','2',' '); goto j2k_restart; } @@ -151,7 +151,7 @@ void gf_img_parse(GF_BitStream *bs, u8 *OTI, u32 *mtype, u32 *width, u32 *height type = gf_bs_read_u32(bs); if (type!=0x0D0A870A) goto exit; - *OTI = 0x6E; + *OTI = GPAC_OTI_IMAGE_JPEG_2000; *mtype = GF_4CC('j','p','2',' '); while (gf_bs_available(bs)) { @@ -220,7 +220,7 @@ typedef struct struct jpeg_decompress_struct cinfo; } JPGCtx; -void _fatal_error(j_common_ptr cinfo) +void _fatal_error(j_common_ptr cinfo) { JPGErr *err = (JPGErr *) cinfo->err; longjmp(err->jmpbuf, 1); @@ -317,18 +317,18 @@ GF_Err gf_img_jpeg_dec(char *jpg, u32 jpg_size, u32 *width, u32 *height, u32 *pi jpx.cinfo.do_fancy_upsampling = FALSE; jpx.cinfo.do_block_smoothing = FALSE; if (!jpeg_start_decompress(&jpx.cinfo)) { - if (scan_line) free(scan_line); + if (scan_line) gf_free(scan_line); jpeg_destroy_decompress(&jpx.cinfo); return GF_NON_COMPLIANT_BITSTREAM; } if (jpx.cinfo.rec_outbuf_height>JPEG_MAX_SCAN_BLOCK_HEIGHT) { - if (scan_line) free(scan_line); + if (scan_line) gf_free(scan_line); jpeg_destroy_decompress(&jpx.cinfo); return GF_IO_ERR; } /*read scanlines (the scan is not one line by one line so alloc a placeholder for block scaning) */ - scan_line = malloc(sizeof(char) * stride * jpx.cinfo.rec_outbuf_height); + scan_line = gf_malloc(sizeof(char) * stride * jpx.cinfo.rec_outbuf_height); for (i = 0; i<jpx.cinfo.rec_outbuf_height;i++) { lines[i] = scan_line + i * stride; } @@ -362,7 +362,7 @@ GF_Err gf_img_jpeg_dec(char *jpg, u32 jpg_size, u32 *width, u32 *height, u32 *pi jpeg_finish_decompress(&jpx.cinfo); jpeg_destroy_decompress(&jpx.cinfo); - free(scan_line); + gf_free(scan_line); return GF_OK; } @@ -402,6 +402,31 @@ static void user_error_fn(png_structp png_ptr,png_const_charp error_msg) longjmp(png_ptr->jmpbuf, 1); } +GF_Err gf_img_png_file_dec(char *png_filename, u32 *width, u32 *height, u32 *pixel_format, char **dst, u32 *dst_size) +{ + u32 fsize; + FILE *f; + char *data; + GF_Err e; + f = fopen(png_filename, "rb"); + if (!f) return GF_URL_ERROR; + + fseek(f, 0, SEEK_END); + fsize = (u32)ftell(f); + fseek(f, 0, SEEK_SET); + data = gf_malloc(fsize); + fread(data, fsize, 1, f); + + *dst_size = 0; + e = gf_img_png_dec(data, fsize, width, height, pixel_format, NULL, dst_size); + if (*dst_size) { + *dst = gf_malloc(*dst_size); + return gf_img_png_dec(data, fsize, width, height, pixel_format, *dst, dst_size); + } else { + return e; + } +} + GF_EXPORT GF_Err gf_img_png_dec(char *png, u32 png_size, u32 *width, u32 *height, u32 *pixel_format, char *dst, u32 *dst_size) { @@ -479,13 +504,13 @@ GF_Err gf_img_png_dec(char *png, u32 png_size, u32 *width, u32 *height, u32 *pix /*read*/ stride = png_get_rowbytes(png_ptr, info_ptr); - rows = (png_bytepp) malloc(sizeof(png_bytep) * info_ptr->height); + rows = (png_bytepp) gf_malloc(sizeof(png_bytep) * info_ptr->height); for (i=0; i<info_ptr->height; i++) { rows[i] = dst + i*stride; } png_read_image(png_ptr, rows); png_read_end(png_ptr, NULL); - free(rows); + gf_free(rows); png_destroy_info_struct(png_ptr,(png_infopp) & info_ptr); png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); @@ -499,62 +524,62 @@ void my_png_write(png_structp png, png_bytep data, png_size_t size) memcpy(p->buffer+p->pos, data, sizeof(char)*size); p->pos += size; } -void my_png_flush(png_structp png) +void my_png_flush(png_structp png) { } /* write a png file */ -GF_Err gf_img_png_enc(char *data, u32 width, u32 height, u32 pixel_format, char *dst, u32 *dst_size) +GF_Err gf_img_png_enc(char *data, u32 width, u32 height, s32 stride, u32 pixel_format, char *dst, u32 *dst_size) { GFpng udta; png_color_8 sig_bit; - png_uint_32 k; - u32 type, nb_comp; + png_int_32 k; png_bytep *row_pointers; png_structp png_ptr; png_infop info_ptr; + u32 type, nb_comp; type = 0; nb_comp = 0; switch (pixel_format) { - case GF_PIXEL_GREYSCALE: + case GF_PIXEL_GREYSCALE: nb_comp = 1; - type = PNG_COLOR_TYPE_GRAY; + type = PNG_COLOR_TYPE_GRAY; break; - case GF_PIXEL_ALPHAGREY: + case GF_PIXEL_ALPHAGREY: nb_comp = 1; - type = PNG_COLOR_TYPE_GRAY_ALPHA; + type = PNG_COLOR_TYPE_GRAY_ALPHA; break; - case GF_PIXEL_RGB_24: - case GF_PIXEL_BGR_24: - case GF_PIXEL_RGB_32: - case GF_PIXEL_BGR_32: + case GF_PIXEL_RGB_24: + case GF_PIXEL_BGR_24: + case GF_PIXEL_RGB_32: + case GF_PIXEL_BGR_32: nb_comp = 3; - type = PNG_COLOR_TYPE_RGB; + type = PNG_COLOR_TYPE_RGB; break; - case GF_PIXEL_RGBA: - case GF_PIXEL_ARGB: + case GF_PIXEL_RGBA: + case GF_PIXEL_ARGB: nb_comp = 4; - type = PNG_COLOR_TYPE_RGB_ALPHA; + type = PNG_COLOR_TYPE_RGB_ALPHA; break; default: return GF_NOT_SUPPORTED; } if (*dst_size < width*height*nb_comp) return GF_BUFFER_TOO_SMALL; - + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); // png_voidp user_error_ptr, user_error_fn, user_warning_fn); - + if (png_ptr == NULL) return GF_IO_ERR; /* Allocate/initialize the image information data. REQUIRED */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { - png_destroy_write_struct(&png_ptr, png_infopp_NULL); + png_destroy_write_struct(&png_ptr, NULL); return GF_IO_ERR; } - + /* Set error handling. REQUIRED if you aren't supplying your own * error handling functions in the png_create_write_struct() call. */ @@ -562,7 +587,7 @@ GF_Err gf_img_png_enc(char *data, u32 width, u32 height, u32 pixel_format, char png_destroy_write_struct(&png_ptr, &info_ptr); return GF_NON_COMPLIANT_BITSTREAM; } - + udta.buffer = dst; udta.pos = 0; png_set_write_fn(png_ptr, &udta, my_png_write, my_png_flush); @@ -597,31 +622,37 @@ GF_Err gf_img_png_enc(char *data, u32 width, u32 height, u32 pixel_format, char #endif png_write_info(png_ptr, info_ptr); - + /* Shift the pixels up to a legal bit depth and fill in * as appropriate to correctly scale the image. */ png_set_shift(png_ptr, &sig_bit); - + /* pack pixels into bytes */ png_set_packing(png_ptr); if (pixel_format==GF_PIXEL_ARGB) png_set_swap_alpha(png_ptr); - if ((pixel_format==GF_PIXEL_RGB_32) || (pixel_format==GF_PIXEL_BGR_32)) - png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); - - if ((pixel_format==GF_PIXEL_BGR_24) || (pixel_format==GF_PIXEL_BGR_32)) + switch (pixel_format) { + case GF_PIXEL_RGB_32: + png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); png_set_bgr(png_ptr); - - row_pointers = malloc(sizeof(png_bytep)*height); - for (k = 0; k < height; k++) - row_pointers[k] = data + k*width*nb_comp; + break; + case GF_PIXEL_BGR_32: + png_set_filler(png_ptr, 0, PNG_FILLER_AFTER); + break; + case GF_PIXEL_BGR_24: + png_set_bgr(png_ptr); + break; + } + row_pointers = gf_malloc(sizeof(png_bytep)*height); + for (k = 0; k < (s32)height; k++) + row_pointers[k] = data + k*stride; png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, info_ptr); - free(row_pointers); + gf_free(row_pointers); /* clean up after the write, and free any memory allocated */ png_destroy_write_struct(&png_ptr, &info_ptr); @@ -636,7 +667,7 @@ GF_Err gf_img_png_dec(char *png, u32 png_size, u32 *width, u32 *height, u32 *pix return GF_NOT_SUPPORTED; } GF_EXPORT -GF_Err gf_img_png_enc(char *data, u32 width, u32 height, u32 pixel_format, char *dst, u32 *dst_size) +GF_Err gf_img_png_enc(char *data, u32 width, u32 height, s32 stride, u32 pixel_format, char *dst, u32 *dst_size) { return GF_NOT_SUPPORTED; } diff --git a/src/media_tools/ismacryp.c b/src/media_tools/ismacryp.c index 5d667c3..32d431d 100644 --- a/src/media_tools/ismacryp.c +++ b/src/media_tools/ismacryp.c @@ -176,10 +176,10 @@ static void del_crypt_info(ISMACrypInfo *info) while (gf_list_count(info->tcis)) { GF_TrackCryptInfo *tci = (GF_TrackCryptInfo *)gf_list_last(info->tcis); gf_list_rem_last(info->tcis); - free(tci); + gf_free(tci); } gf_list_del(info->tcis); - free(info); + gf_free(info); } static ISMACrypInfo *load_crypt_file(const char *file) @@ -235,7 +235,7 @@ Bool gf_ismacryp_mpeg4ip_get_info(char *kms_uri, char *key, char *salt) strcpy(szPath, getenv("HOME")); strcat(szPath , "/.kms_data"); got_it = 0; - kms = fopen(szPath, "r"); + kms = gf_f64_open(szPath, "r"); while (kms && !feof(kms)) { if (!fgets(szPath, 1024, kms)) break; szPath[strlen(szPath) - 1] = 0; @@ -257,7 +257,7 @@ Bool gf_ismacryp_mpeg4ip_get_info(char *kms_uri, char *key, char *salt) return 0; } -#ifndef GPAC_READ_ONLY +#if !defined(GPAC_DISABLE_MCRYPT) && !defined(GPAC_DISABLE_ISOM_WRITE) static GFINLINE void resync_IV(GF_Crypt *mc, u64 BSO, char *salt) { @@ -284,7 +284,7 @@ static GFINLINE void resync_IV(GF_Crypt *mc, u64 BSO, char *salt) } GF_EXPORT -GF_Err gf_ismacryp_decrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (*progress)(void *cbk, u32 done, u32 total), void *cbk) +GF_Err gf_ismacryp_decrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (*progress)(void *cbk, u64 done, u64 total), void *cbk) { GF_Err e; Bool use_sel_enc; @@ -327,7 +327,7 @@ GF_Err gf_ismacryp_decrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void ( samp = gf_isom_get_sample(mp4, track, i+1, &si); ismasamp = gf_isom_get_ismacryp_sample(mp4, track, samp, si); - free(samp->data); + gf_free(samp->data); samp->data = ismasamp->data; samp->dataLength = ismasamp->dataLength; ismasamp->data = NULL; @@ -412,7 +412,7 @@ GF_Err gf_ismacryp_decrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void ( j--; gf_odf_com_del((GF_ODCom **)&com); } - free(samp->data); + gf_free(samp->data); samp->data = NULL; samp->dataLength = 0; gf_odf_codec_encode(cod, 1); @@ -516,7 +516,7 @@ GF_Err gf_ismacryp_decrypt_file(GF_ISOFile *mp4, const char *drm_file) } } else if (!drm_file) { FILE *test = NULL; - if (!stricmp(scheme_URI, "urn:gpac:isma:encryption_scheme")) test = fopen(KMS_URI, "rt"); + if (!stricmp(scheme_URI, "urn:gpac:isma:encryption_scheme")) test = gf_f64_open(KMS_URI, "rt"); if (!test) { GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[ISMA E&A] TrackID %d does not contain decryption keys - skipping\n", trackID)); @@ -530,7 +530,7 @@ GF_Err gf_ismacryp_decrypt_file(GF_ISOFile *mp4, const char *drm_file) } if (KMS_URI && strlen(tci.KMS_URI) && strcmp(KMS_URI, tci.KMS_URI) ) - GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISMA E&A] KMS URI for trackID %d Mismatch\n", trackID)); + GF_LOG(GF_LOG_WARNING, GF_LOG_AUTHOR, ("[ISMA E&A] KMS URI for TrackID %d Mismatch: \"%s\" in file vs \"%s\" in licence\n", trackID, KMS_URI, tci.KMS_URI)); if (drm_file || (KMS_URI && strncmp(KMS_URI, "(key)", 5)) ) { strcpy(tci.KMS_URI, KMS_URI ? KMS_URI : ""); @@ -549,7 +549,7 @@ GF_Err gf_ismacryp_decrypt_file(GF_ISOFile *mp4, const char *drm_file) } GF_EXPORT -GF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (*progress)(void *cbk, u32 done, u32 total), void *cbk) +GF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void (*progress)(void *cbk, u64 done, u64 total), void *cbk) { char IV[16]; GF_ISOSample *samp; @@ -578,7 +578,7 @@ GF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void ( return GF_NOT_SUPPORTED; } if (esd) { - if (esd->decoderConfig->objectTypeIndication==0x21) avc_size_length = 1; + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) avc_size_length = 1; gf_odf_desc_del((GF_Descriptor*) esd); } if (avc_size_length) { @@ -804,7 +804,7 @@ GF_Err gf_ismacryp_encrypt_track(GF_ISOFile *mp4, GF_TrackCryptInfo *tci, void ( gf_odf_codec_set_au(cod, samp->data, samp->dataLength); gf_odf_codec_decode(cod); gf_odf_codec_add_com(cod, (GF_ODCom *) ipmpdU); - free(samp->data); + gf_free(samp->data); samp->data = NULL; samp->dataLength = 0; gf_odf_codec_encode(cod, 1); @@ -889,7 +889,7 @@ GF_Err gf_ismacryp_crypt_file(GF_ISOFile *mp4, const char *drm_file) return e; } -#endif +#endif /*!defined(GPAC_DISABLE_MCRYPT) && !defined(GPAC_DISABLE_ISOM_WRITE)*/ GF_EXPORT GF_Err gf_media_get_file_hash(const char *file, u8 hash[20]) @@ -898,20 +898,25 @@ GF_Err gf_media_get_file_hash(const char *file, u8 hash[20]) u32 read; u64 size, tot; FILE *in; - GF_BitStream *bs = NULL; GF_SHA1Context ctx; +#ifndef GPAC_DISABLE_ISOM + GF_BitStream *bs = NULL; Bool is_isom = gf_isom_probe_file(file); +#endif - in = fopen(file, "rb"); + in = gf_f64_open(file, "rb"); gf_f64_seek(in, 0, SEEK_END); size = gf_f64_tell(in); gf_f64_seek(in, 0, SEEK_SET); gf_sha1_starts(&ctx); tot = 0; +#ifndef GPAC_DISABLE_ISOM if (is_isom) bs = gf_bs_from_file(in, GF_BITSTREAM_READ); +#endif while (tot<size) { +#ifndef GPAC_DISABLE_ISOM if (is_isom) { u64 box_size = gf_bs_peek_bits(bs, 32, 0); u32 box_type = gf_bs_peek_bits(bs, 32, 4); @@ -935,14 +940,18 @@ GF_Err gf_media_get_file_hash(const char *file, u8 hash[20]) } tot += box_size; } - } else { + } else +#endif + { read = fread(block, 1, 1024, in); gf_sha1_update(&ctx, block, read); tot += read; } } gf_sha1_finish(&ctx, hash); +#ifndef GPAC_DISABLE_ISOM if (bs) gf_bs_del(bs); +#endif fclose(in); return GF_OK; } diff --git a/src/media_tools/isom_hinter.c b/src/media_tools/isom_hinter.c index 55ed80c..81ffe11 100644 --- a/src/media_tools/isom_hinter.c +++ b/src/media_tools/isom_hinter.c @@ -22,14 +22,69 @@ * */ -#include <gpac/media_tools.h> +#include <gpac/internal/media_dev.h> #include <gpac/base_coding.h> #include <gpac/mpeg4_odf.h> #include <gpac/constants.h> #include <gpac/math.h> #include <gpac/ietf.h> -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM + +void gf_media_get_sample_average_infos(GF_ISOFile *file, u32 Track, u32 *avgSize, u32 *MaxSize, u32 *TimeDelta, u32 *maxCTSDelta, u32 *const_duration, u32 *bandwidth) +{ + u32 i, count, ts_diff; + u64 prevTS, DTS, tdelta; + Double bw; + GF_ISOSample *samp; + + *avgSize = *MaxSize = 0; + *TimeDelta = 0; + *maxCTSDelta = 0; + bw = 0; + prevTS = 0; + DTS = 0; + tdelta = 0; + + count = gf_isom_get_sample_count(file, Track); + *const_duration = 0; + + for (i=0; i<count; i++) { + samp = gf_isom_get_sample_info(file, Track, i+1, NULL, NULL); + //get the size + *avgSize += samp->dataLength; + if (*MaxSize < samp->dataLength) *MaxSize = samp->dataLength; + ts_diff = (u32) (samp->DTS+samp->CTS_Offset - prevTS); + //get the time + tdelta += ts_diff; + + if (i==1) { + *const_duration = ts_diff; + } else if ( (i<count-1) && (*const_duration != ts_diff) ) { + *const_duration = 0; + } + + prevTS = samp->DTS+samp->CTS_Offset; + bw += 8*samp->dataLength; + + //get the CTS delta + if (samp->CTS_Offset > *maxCTSDelta) *maxCTSDelta = samp->CTS_Offset; + gf_isom_sample_del(&samp); + } + if (count>1) *TimeDelta = (u32) (tdelta/ (count-1) ); + else *TimeDelta = (u32) tdelta; + *avgSize /= count; + bw *= gf_isom_get_media_timescale(file, Track); + bw /= (s64) gf_isom_get_media_duration(file, Track); + bw /= 1000; + (*bandwidth) = (u32) (bw+0.5); + + //delta is NOT an average, we need to know exactly how many bits are + //needed to encode CTS-DTS for ANY samples +} + + +#ifndef GPAC_DISABLE_ISOM_HINTING /*RTP track hinter*/ struct __tag_isom_hinter @@ -74,7 +129,7 @@ void MP4T_DumpSDP(GF_ISOFile *file, const char *name) u32 size, i; FILE *f; - f = fopen(name, "wt"); + f = gf_f64_open(name, "wt"); //get the movie SDP gf_isom_sdp_get(file, &sdp, &size); fwrite(sdp, size, 1, f); @@ -90,61 +145,6 @@ void MP4T_DumpSDP(GF_ISOFile *file, const char *name) } -/*out-of-band sample desc (128 and 255 reserved in RFC)*/ -#define SIDX_OFFSET_3GPP 129 - -void GetAvgSampleInfos(GF_ISOFile *file, u32 Track, u32 *avgSize, u32 *MaxSize, u32 *TimeDelta, u32 *maxCTSDelta, u32 *const_duration, u32 *bandwidth) -{ - u32 i, count, ts_diff; - u64 prevTS, DTS, tdelta; - Double bw; - GF_ISOSample *samp; - - *avgSize = *MaxSize = 0; - *TimeDelta = 0; - *maxCTSDelta = 0; - bw = 0; - prevTS = 0; - DTS = 0; - tdelta = 0; - - count = gf_isom_get_sample_count(file, Track); - *const_duration = 0; - - for (i=0; i<count; i++) { - samp = gf_isom_get_sample_info(file, Track, i+1, NULL, NULL); - //get the size - *avgSize += samp->dataLength; - if (*MaxSize < samp->dataLength) *MaxSize = samp->dataLength; - ts_diff = (u32) (samp->DTS+samp->CTS_Offset - prevTS); - //get the time - tdelta += ts_diff; - - if (i==1) { - *const_duration = ts_diff; - } else if ( (i<count-1) && (*const_duration != ts_diff) ) { - *const_duration = 0; - } - - prevTS = samp->DTS+samp->CTS_Offset; - bw += 8*samp->dataLength; - - //get the CTS delta - if (samp->CTS_Offset > *maxCTSDelta) *maxCTSDelta = samp->CTS_Offset; - gf_isom_sample_del(&samp); - } - if (count>1) *TimeDelta = (u32) (tdelta/ (count-1) ); - else *TimeDelta = (u32) tdelta; - *avgSize /= count; - bw *= gf_isom_get_media_timescale(file, Track); - bw /= (s64) gf_isom_get_media_duration(file, Track); - bw /= 1000; - (*bandwidth) = (u32) (bw+0.5); - - //delta is NOT an average, we need to know exactly how many bits are - //needed to encode CTS-DTS for ANY samples -} - void InitSL_RTP(GF_SLConfig *slc) { memset(slc, 0, sizeof(GF_SLConfig)); @@ -235,319 +235,6 @@ void MP4T_OnNewPacket(void *cbk, GF_RTPHeader *header) if (res) gf_isom_rtp_packet_set_offset(tkHint->file, tkHint->HintTrack, res); } -GP_RTPPacketizer *gf_rtp_packetizer_create_and_init_from_file(GF_ISOFile *file, - u32 TrackNum, - void *cbk_obj, - void (*OnNewPacket)(void *cbk, GF_RTPHeader *header), - void (*OnPacketDone)(void *cbk, GF_RTPHeader *header), - void (*OnDataReference)(void *cbk, u32 payload_size, u32 offset_from_orig), - void (*OnData)(void *cbk, char *data, u32 data_size, Bool is_head), - u32 Path_MTU, - u32 max_ptime, - u32 default_rtp_rate, - u32 flags, - u8 PayloadID, - Bool copy_media, - u32 InterleaveGroupID, - u8 InterleaveGroupPriority) -{ - GF_SLConfig my_sl; - u32 MinSize, MaxSize, avgTS, streamType, oti, const_dur, nb_ch, maxDTSDelta; - u8 OfficialPayloadID; - u32 TrackMediaSubType, TrackMediaType, hintType, required_rate, force_dts_delta, avc_nalu_size, PL_ID, bandwidth, IV_length, KI_length; - const char *url, *urn; - char *mpeg4mode; - Bool is_crypted, has_mpeg4_mapping; - GF_ESD *esd; - GP_RTPPacketizer *rtp_packetizer = NULL; - - /*by default NO PL signaled*/ - PL_ID = 0; - OfficialPayloadID = 0; - force_dts_delta = 0; - streamType = oti = 0; - mpeg4mode = NULL; - required_rate = 0; - is_crypted = 0; - IV_length = KI_length = 0; - oti = 0; - nb_ch = 0; - avc_nalu_size = 0; - has_mpeg4_mapping = 1; - TrackMediaType = gf_isom_get_media_type(file, TrackNum); - TrackMediaSubType = gf_isom_get_media_subtype(file, TrackNum, 1); - - /*for max compatibility with QT*/ - if (!default_rtp_rate) default_rtp_rate = 90000; - - /*timed-text is a bit special, we support multiple stream descriptions & co*/ - if (TrackMediaType==GF_ISOM_MEDIA_TEXT) { - hintType = GF_RTP_PAYT_3GPP_TEXT; - oti = 0x08; - streamType = GF_STREAM_TEXT; - /*fixme - this works cos there's only one PL for text in mpeg4 at the current time*/ - PL_ID = 0x10; - } else { - if (gf_isom_get_sample_description_count(file, TrackNum) > 1) return NULL; - - TrackMediaSubType = gf_isom_get_media_subtype(file, TrackNum, 1); - switch (TrackMediaSubType) { - case GF_ISOM_SUBTYPE_MPEG4_CRYP: - is_crypted = 1; - case GF_ISOM_SUBTYPE_MPEG4: - esd = gf_isom_get_esd(file, TrackNum, 1); - hintType = GF_RTP_PAYT_MPEG4; - if (esd) { - streamType = esd->decoderConfig->streamType; - oti = esd->decoderConfig->objectTypeIndication; - if (esd->URLString) hintType = 0; - /*AAC*/ - if ((streamType==GF_STREAM_AUDIO) && esd->decoderConfig->decoderSpecificInfo - /*(nb: we use mpeg4 for MPEG-2 AAC)*/ - && ((oti==0x40) || (oti==0x40) || (oti==0x66) || (oti==0x67) || (oti==0x68)) ) { - - u32 sample_rate; - GF_M4ADecSpecInfo a_cfg; - gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &a_cfg); - nb_ch = a_cfg.nb_chan; - sample_rate = a_cfg.base_sr; - PL_ID = a_cfg.audioPL; - switch (a_cfg.base_object_type) { - case GF_M4A_AAC_MAIN: - case GF_M4A_AAC_LC: - if (flags & GP_RTP_PCK_USE_LATM_AAC) { - hintType = GF_RTP_PAYT_LATM; - break; - } - case GF_M4A_AAC_SBR: - case GF_M4A_AAC_LTP: - case GF_M4A_AAC_SCALABLE: - case GF_M4A_ER_AAC_LC: - case GF_M4A_ER_AAC_LTP: - case GF_M4A_ER_AAC_SCALABLE: - mpeg4mode = "AAC"; - break; - case GF_M4A_CELP: - case GF_M4A_ER_CELP: - mpeg4mode = "CELP"; - break; - } - required_rate = sample_rate; - } - /*MPEG1/2 audio*/ - else if ((streamType==GF_STREAM_AUDIO) && ((oti==0x69) || (oti==0x6B))) { - u32 sample_rate; - if (!is_crypted) { - GF_ISOSample *samp = gf_isom_get_sample(file, TrackNum, 1, NULL); - u32 hdr = GF_4CC((u8)samp->data[0], (u8)samp->data[1], (u8)samp->data[2], (u8)samp->data[3]); - nb_ch = gf_mp3_num_channels(hdr); - sample_rate = gf_mp3_sampling_rate(hdr); - gf_isom_sample_del(&samp); - hintType = GF_RTP_PAYT_MPEG12_AUDIO; - /*use official RTP/AVP payload type*/ - OfficialPayloadID = 14; - required_rate = 90000; - } - /*encrypted MP3 must be sent through MPEG-4 generic to signal all ISMACryp stuff*/ - else { - u8 bps; - gf_isom_get_audio_info(file, TrackNum, 1, &sample_rate, &nb_ch, &bps); - required_rate = sample_rate; - } - } - /*QCELP audio*/ - else if ((streamType==GF_STREAM_AUDIO) && (oti==0xE1)) { - hintType = GF_RTP_PAYT_QCELP; - OfficialPayloadID = 12; - required_rate = 8000; - streamType = GF_STREAM_AUDIO; - nb_ch = 1; - } - /*EVRC/SVM audio*/ - else if ((streamType==GF_STREAM_AUDIO) && ((oti==0xA0) || (oti==0xA1)) ) { - hintType = GF_RTP_PAYT_EVRC_SMV; - required_rate = 8000; - streamType = GF_STREAM_AUDIO; - nb_ch = 1; - } - /*visual streams*/ - else if (streamType==GF_STREAM_VISUAL) { - if (oti==0x20) { - GF_M4VDecSpecInfo dsi; - gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); - PL_ID = dsi.VideoPL; - } - /*MPEG1/2 video*/ - if ( ((oti>=0x60) && (oti<=0x65)) || (oti==0x6A)) { - if (!is_crypted) { - hintType = GF_RTP_PAYT_MPEG12_VIDEO; - OfficialPayloadID = 32; - } - } - /*for ISMA*/ - if (is_crypted) { - /*that's another pain with ISMACryp, even if no B-frames the DTS is signaled...*/ - if (oti==0x20) force_dts_delta = 22; - flags |= GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_SIGNAL_TS; - } - - required_rate = default_rtp_rate; - } - /*systems streams*/ - else if (gf_isom_has_sync_shadows(file, TrackNum) || gf_isom_has_sample_dependency(file, TrackNum)) { - flags |= GP_RTP_PCK_AUTO_CAROUSEL; - } - gf_odf_desc_del((GF_Descriptor*)esd); - } - break; - case GF_ISOM_SUBTYPE_3GP_H263: - hintType = GF_RTP_PAYT_H263; - required_rate = 90000; - streamType = GF_STREAM_VISUAL; - OfficialPayloadID = 34; - /*not 100% compliant (short header is missing) but should still work*/ - oti = 0x20; - PL_ID = 0x01; - break; - case GF_ISOM_SUBTYPE_3GP_AMR: - required_rate = 8000; - hintType = GF_RTP_PAYT_AMR; - streamType = GF_STREAM_AUDIO; - has_mpeg4_mapping = 0; - nb_ch = 1; - break; - case GF_ISOM_SUBTYPE_3GP_AMR_WB: - required_rate = 16000; - hintType = GF_RTP_PAYT_AMR_WB; - streamType = GF_STREAM_AUDIO; - has_mpeg4_mapping = 0; - nb_ch = 1; - break; - case GF_ISOM_SUBTYPE_AC3: - hintType = GF_RTP_PAYT_AC3; - streamType = GF_STREAM_AUDIO; - has_mpeg4_mapping = 1; - nb_ch = 1; - break; - case GF_ISOM_SUBTYPE_AVC_H264: - { - GF_AVCConfig *avcc = gf_isom_avc_config_get(file, TrackNum, 1); - required_rate = 90000; /* "90 kHz clock rate MUST be used"*/ - hintType = GF_RTP_PAYT_H264_AVC; - streamType = GF_STREAM_VISUAL; - avc_nalu_size = avcc->nal_unit_size; - oti = 0x21; - PL_ID = 0x0F; - gf_odf_avc_cfg_del(avcc); - } - break; - case GF_ISOM_SUBTYPE_3GP_QCELP: - required_rate = 8000; - hintType = GF_RTP_PAYT_QCELP; - streamType = GF_STREAM_AUDIO; - oti = 0xE1; - OfficialPayloadID = 12; - nb_ch = 1; - break; - case GF_ISOM_SUBTYPE_3GP_EVRC: - case GF_ISOM_SUBTYPE_3GP_SMV: - required_rate = 8000; - hintType = GF_RTP_PAYT_EVRC_SMV; - streamType = GF_STREAM_AUDIO; - oti = (TrackMediaSubType==GF_ISOM_SUBTYPE_3GP_EVRC) ? 0xA0 : 0xA1; - nb_ch = 1; - break; - default: - /*ERROR*/ - hintType = 0; - break; - } - } - - /*not hintable*/ - if (!hintType) return NULL; - /*we only support self-contained files for hinting*/ - gf_isom_get_data_reference(file, TrackNum, 1, &url, &urn); - if (url || urn) return NULL; - - /*override hinter type if requested and possible*/ - if (has_mpeg4_mapping && (flags & GP_RTP_PCK_FORCE_MPEG4)) { - hintType = GF_RTP_PAYT_MPEG4; - avc_nalu_size = 0; - } - /*use static payload ID if enabled*/ - else if (OfficialPayloadID && (flags & GP_RTP_PCK_USE_STATIC_ID) ) { - PayloadID = OfficialPayloadID; - } - -#if 0 - tmp->file = file; - tmp->TrackNum = TrackNum; - tmp->avc_nalu_size = avc_nalu_size; - tmp->nb_chan = nb_ch; - - /*spatial scalability check*/ - tmp->has_ctts = gf_isom_has_time_offset(file, TrackNum); -#endif - - /*get sample info*/ - GetAvgSampleInfos(file, TrackNum, &MinSize, &MaxSize, &avgTS, &maxDTSDelta, &const_dur, &bandwidth); - - /*systems carousel: we need at least IDX and RAP signaling*/ - if (flags & GP_RTP_PCK_AUTO_CAROUSEL) { - flags |= GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_SIGNAL_AU_IDX; - } - - /*update flags in MultiSL*/ - if (flags & GP_RTP_PCK_USE_MULTI) { - if (MinSize != MaxSize) flags |= GP_RTP_PCK_SIGNAL_SIZE; - if (!const_dur) flags |= GP_RTP_PCK_SIGNAL_TS; - } -#if 0 - if (tmp->has_ctts) flags |= GP_RTP_PCK_SIGNAL_TS; -#endif - - /*default SL for RTP */ - InitSL_RTP(&my_sl); - - my_sl.timestampResolution = gf_isom_get_media_timescale(file, TrackNum); - /*override clockrate if set*/ - if (required_rate) { - Double sc = required_rate; - sc /= my_sl.timestampResolution; - maxDTSDelta = (u32) (maxDTSDelta*sc); - my_sl.timestampResolution = required_rate; - } - /*switch to RTP TS*/ - max_ptime = (u32) (max_ptime * my_sl.timestampResolution / 1000); - - my_sl.AUSeqNumLength = gf_get_bit_size(gf_isom_get_sample_count(file, TrackNum)); - my_sl.CUDuration = const_dur; - - if (gf_isom_has_sync_points(file, TrackNum)) { - my_sl.useRandomAccessPointFlag = 1; - } else { - my_sl.useRandomAccessPointFlag = 0; - my_sl.hasRandomAccessUnitsOnlyFlag = 1; - } - - if (is_crypted) { - Bool use_sel_enc; - gf_isom_get_ismacryp_info(file, TrackNum, 1, NULL, NULL, NULL, NULL, NULL, &use_sel_enc, &IV_length, &KI_length); - if (use_sel_enc) flags |= GP_RTP_PCK_SELECTIVE_ENCRYPTION; - } - - rtp_packetizer = gf_rtp_builder_new(hintType, &my_sl, flags, cbk_obj, - OnNewPacket, OnPacketDone, - /*if copy, no data ref*/ - copy_media ? NULL : OnDataReference, - OnData); - - gf_rtp_builder_init(rtp_packetizer, PayloadID, Path_MTU, max_ptime, - streamType, oti, PL_ID, MinSize, MaxSize, avgTS, maxDTSDelta, IV_length, KI_length, mpeg4mode); - - return rtp_packetizer; -} GF_EXPORT GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, @@ -607,9 +294,9 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, if (!default_rtp_rate) default_rtp_rate = 90000; /*timed-text is a bit special, we support multiple stream descriptions & co*/ - if (TrackMediaType==GF_ISOM_MEDIA_TEXT) { + if ( (TrackMediaType==GF_ISOM_MEDIA_TEXT) || (TrackMediaType==GF_ISOM_MEDIA_SUBT)) { hintType = GF_RTP_PAYT_3GPP_TEXT; - oti = 0x08; + oti = GPAC_OTI_TEXT_MPEG4; streamType = GF_STREAM_TEXT; /*fixme - this works cos there's only one PL for text in mpeg4 at the current time*/ PL_ID = 0x10; @@ -630,7 +317,7 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, /*AAC*/ if ((streamType==GF_STREAM_AUDIO) && esd->decoderConfig->decoderSpecificInfo /*(nb: we use mpeg4 for MPEG-2 AAC)*/ - && ((oti==0x40) || (oti==0x40) || (oti==0x66) || (oti==0x67) || (oti==0x68)) ) { + && ((oti==GPAC_OTI_AUDIO_AAC_MPEG4) || (oti==GPAC_OTI_AUDIO_AAC_MPEG4) || (oti==GPAC_OTI_AUDIO_AAC_MPEG2_MP) || (oti==GPAC_OTI_AUDIO_AAC_MPEG2_LCP) || (oti==GPAC_OTI_AUDIO_AAC_MPEG2_SSRP)) ) { u32 sample_rate; GF_M4ADecSpecInfo a_cfg; @@ -646,6 +333,7 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, break; } case GF_M4A_AAC_SBR: + case GF_M4A_AAC_PS: case GF_M4A_AAC_LTP: case GF_M4A_AAC_SCALABLE: case GF_M4A_ER_AAC_LC: @@ -661,7 +349,7 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, required_rate = sample_rate; } /*MPEG1/2 audio*/ - else if ((streamType==GF_STREAM_AUDIO) && ((oti==0x69) || (oti==0x6B))) { + else if ((streamType==GF_STREAM_AUDIO) && ((oti==GPAC_OTI_AUDIO_MPEG2_PART3) || (oti==GPAC_OTI_AUDIO_MPEG1))) { u32 sample_rate; if (!is_crypted) { GF_ISOSample *samp = gf_isom_get_sample(file, TrackNum, 1, NULL); @@ -682,7 +370,7 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, } } /*QCELP audio*/ - else if ((streamType==GF_STREAM_AUDIO) && (oti==0xE1)) { + else if ((streamType==GF_STREAM_AUDIO) && (oti==GPAC_OTI_AUDIO_13K_VOICE)) { hintType = GF_RTP_PAYT_QCELP; OfficialPayloadID = 12; required_rate = 8000; @@ -690,7 +378,7 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, nb_ch = 1; } /*EVRC/SVM audio*/ - else if ((streamType==GF_STREAM_AUDIO) && ((oti==0xA0) || (oti==0xA1)) ) { + else if ((streamType==GF_STREAM_AUDIO) && ((oti==GPAC_OTI_AUDIO_EVRC_VOICE) || (oti==GPAC_OTI_AUDIO_SMV_VOICE)) ) { hintType = GF_RTP_PAYT_EVRC_SMV; required_rate = 8000; streamType = GF_STREAM_AUDIO; @@ -698,13 +386,13 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, } /*visual streams*/ else if (streamType==GF_STREAM_VISUAL) { - if (oti==0x20) { + if (oti==GPAC_OTI_VIDEO_MPEG4_PART2) { GF_M4VDecSpecInfo dsi; gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); PL_ID = dsi.VideoPL; } /*MPEG1/2 video*/ - if ( ((oti>=0x60) && (oti<=0x65)) || (oti==0x6A)) { + if ( ((oti>=GPAC_OTI_VIDEO_MPEG2_SIMPLE) && (oti<=GPAC_OTI_VIDEO_MPEG2_422)) || (oti==GPAC_OTI_VIDEO_MPEG1)) { if (!is_crypted) { hintType = GF_RTP_PAYT_MPEG12_VIDEO; OfficialPayloadID = 32; @@ -713,8 +401,8 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, /*for ISMA*/ if (is_crypted) { /*that's another pain with ISMACryp, even if no B-frames the DTS is signaled...*/ - if (oti==0x20) force_dts_delta = 22; - else if (oti==0x21) { + if (oti==GPAC_OTI_VIDEO_MPEG4_PART2) force_dts_delta = 22; + else if (oti==GPAC_OTI_VIDEO_AVC) { flags &= ~GP_RTP_PCK_USE_MULTI; force_dts_delta = 22; } @@ -725,7 +413,7 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, } /*systems streams*/ else if (gf_isom_has_sync_shadows(file, TrackNum) || gf_isom_has_sample_dependency(file, TrackNum)) { - flags |= GP_RTP_PCK_AUTO_CAROUSEL; + flags |= GP_RTP_PCK_SYSTEMS_CAROUSEL; } gf_odf_desc_del((GF_Descriptor*)esd); } @@ -736,7 +424,7 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, streamType = GF_STREAM_VISUAL; OfficialPayloadID = 34; /*not 100% compliant (short header is missing) but should still work*/ - oti = 0x20; + oti = GPAC_OTI_VIDEO_MPEG4_PART2; PL_ID = 0x01; break; case GF_ISOM_SUBTYPE_3GP_AMR: @@ -754,13 +442,15 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, nb_ch = 1; break; case GF_ISOM_SUBTYPE_AVC_H264: + case GF_ISOM_SUBTYPE_AVC2_H264: + case GF_ISOM_SUBTYPE_SVC_H264: { GF_AVCConfig *avcc = gf_isom_avc_config_get(file, TrackNum, 1); required_rate = 90000; /* "90 kHz clock rate MUST be used"*/ hintType = GF_RTP_PAYT_H264_AVC; streamType = GF_STREAM_VISUAL; avc_nalu_size = avcc->nal_unit_size; - oti = 0x21; + oti = GPAC_OTI_VIDEO_AVC; PL_ID = 0x0F; gf_odf_avc_cfg_del(avcc); } @@ -769,7 +459,7 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, required_rate = 8000; hintType = GF_RTP_PAYT_QCELP; streamType = GF_STREAM_AUDIO; - oti = 0xE1; + oti = GPAC_OTI_AUDIO_13K_VOICE; OfficialPayloadID = 12; nb_ch = 1; break; @@ -778,7 +468,7 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, required_rate = 8000; hintType = GF_RTP_PAYT_EVRC_SMV; streamType = GF_STREAM_AUDIO; - oti = (TrackMediaSubType==GF_ISOM_SUBTYPE_3GP_EVRC) ? 0xA0 : 0xA1; + oti = (TrackMediaSubType==GF_ISOM_SUBTYPE_3GP_EVRC) ? GPAC_OTI_AUDIO_EVRC_VOICE : GPAC_OTI_AUDIO_SMV_VOICE; nb_ch = 1; break; case GF_ISOM_SUBTYPE_3GP_DIMS: @@ -826,11 +516,11 @@ GF_RTPHinter *gf_hinter_track_new(GF_ISOFile *file, u32 TrackNum, tmp->has_ctts = gf_isom_has_time_offset(file, TrackNum); /*get sample info*/ - GetAvgSampleInfos(file, TrackNum, &MinSize, &MaxSize, &avgTS, &maxDTSDelta, &const_dur, &bandwidth); + gf_media_get_sample_average_infos(file, TrackNum, &MinSize, &MaxSize, &avgTS, &maxDTSDelta, &const_dur, &bandwidth); /*systems carousel: we need at least IDX and RAP signaling*/ - if (flags & GP_RTP_PCK_AUTO_CAROUSEL) { - flags |= GP_RTP_PCK_SIGNAL_RAP | GP_RTP_PCK_SIGNAL_AU_IDX; + if (flags & GP_RTP_PCK_SYSTEMS_CAROUSEL) { + flags |= GP_RTP_PCK_SIGNAL_RAP; } /*update flags in MultiSL*/ @@ -951,7 +641,7 @@ void gf_hinter_track_del(GF_RTPHinter *tkHinter) if (!tkHinter) return; if (tkHinter->rtp_p) gf_rtp_builder_del(tkHinter->rtp_p); - free(tkHinter); + gf_free(tkHinter); } GF_EXPORT @@ -999,7 +689,7 @@ GF_Err gf_hinter_track_process(GF_RTPHinter *tkHint) /*one byte take for selective_enc flag*/ if (s->flags & GF_ISOM_ISMA_USE_SEL_ENC) tkHint->base_offset_in_sample += 1; if (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) tkHint->base_offset_in_sample += s->IV_length + s->KI_length; - free(samp->data); + gf_free(samp->data); samp->data = s->data; samp->dataLength = s->dataLength; gp_rtp_builder_set_cryp_info(tkHint->rtp_p, s->IV, (char*)s->key_indicator, (s->flags & GF_ISOM_ISMA_IS_ENCRYPTED) ? 1 : 0); @@ -1039,12 +729,12 @@ GF_Err gf_hinter_track_process(GF_RTPHinter *tkHint) tkHint->base_offset_in_sample = samp->dataLength-remain; remain -= size; tkHint->rtp_p->sl_header.accessUnitEndFlag = remain ? 0 : 1; - e = gf_rtp_builder_process(tkHint->rtp_p, ptr, size, (u8) !remain, samp->dataLength, duration, (u8) (descIndex + SIDX_OFFSET_3GPP) ); + e = gf_rtp_builder_process(tkHint->rtp_p, ptr, size, (u8) !remain, samp->dataLength, duration, (u8) (descIndex + GF_RTP_TX3G_SIDX_OFFSET) ); ptr += size; tkHint->rtp_p->sl_header.accessUnitStartFlag = 0; } } else { - e = gf_rtp_builder_process(tkHint->rtp_p, samp->data, samp->dataLength, 1, samp->dataLength, duration, (u8) (descIndex + SIDX_OFFSET_3GPP) ); + e = gf_rtp_builder_process(tkHint->rtp_p, samp->data, samp->dataLength, 1, samp->dataLength, duration, (u8) (descIndex + GF_RTP_TX3G_SIDX_OFFSET) ); } tkHint->rtp_p->sl_header.packetSequenceNumber += 1; @@ -1064,45 +754,7 @@ GF_Err gf_hinter_track_process(GF_RTPHinter *tkHint) return GF_OK; } -void gf_hinter_format_ttxt_sdp(GP_RTPPacketizer *builder, char *payload_name, char *sdpLine, GF_ISOFile *file, u32 track) -{ - char buffer[2000]; - u32 w, h, i, m_w, m_h; - s32 tx, ty; - s16 l; - sprintf(sdpLine, "a=fmtp:%d sver=60; ", builder->PayloadType); - gf_isom_get_track_layout_info(file, track, &w, &h, &tx, &ty, &l); - sprintf(buffer, "width=%d; height=%d; tx=%d; ty=%d; layer=%d; ", w, h, tx, ty, l); - strcat(sdpLine, buffer); - m_w = w; - m_h = h; - for (i=0; i<gf_isom_get_track_count(file); i++) { - switch (gf_isom_get_media_type(file, i+1)) { - case GF_ISOM_MEDIA_SCENE: - case GF_ISOM_MEDIA_VISUAL: - gf_isom_get_track_layout_info(file, i+1, &w, &h, &tx, &ty, &l); - if (w>m_w) m_w = w; - if (h>m_h) m_h = h; - break; - default: - break; - } - } - sprintf(buffer, "max-w=%d; max-h=%d", m_w, m_h); - strcat(sdpLine, buffer); - - strcat(sdpLine, "; tx3g="); - for (i=0; i<gf_isom_get_sample_description_count(file, track); i++) { - char *tx3g; - u32 tx3g_len, len; - gf_isom_text_get_encoded_tx3g(file, track, i+1, SIDX_OFFSET_3GPP, &tx3g, &tx3g_len); - len = gf_base64_encode(tx3g, tx3g_len, buffer, 2000); - free(tx3g); - buffer[len] = 0; - if (i) strcat(sdpLine, ", "); - strcat(sdpLine, buffer); - } -} + GF_EXPORT GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) @@ -1148,12 +800,12 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) } /*AMR*/ else if ((tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_AMR) || (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_AMR_WB)) { - sprintf(sdpLine, "a=fmtp:%d octet-align", tkHint->rtp_p->PayloadType); + sprintf(sdpLine, "a=fmtp:%d octet-align=1", tkHint->rtp_p->PayloadType); gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); } /*Text*/ else if (tkHint->rtp_p->rtp_payt == GF_RTP_PAYT_3GPP_TEXT) { - gf_hinter_format_ttxt_sdp(tkHint->rtp_p, payloadName, sdpLine, tkHint->file, tkHint->TrackNum); + gf_media_format_ttxt_sdp(tkHint->rtp_p, payloadName, sdpLine, tkHint->file, tkHint->TrackNum); gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); } /*EVRC/SMV in non header-free mode*/ @@ -1231,7 +883,8 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) /* audio-specific config */ dcd = gf_isom_get_decoder_config(tkHint->file, tkHint->TrackNum, 1); if (dcd) { - gf_bs_write_data(bs, dcd->decoderSpecificInfo->data, dcd->decoderSpecificInfo->dataLength); + /*PacketVideo patch: don't signal SBR and PS stuff, not allowed in LATM with audioMuxVersion=0*/ + gf_bs_write_data(bs, dcd->decoderSpecificInfo->data, MIN(dcd->decoderSpecificInfo->dataLength, 2) ); gf_odf_desc_del((GF_Descriptor *)dcd); } @@ -1245,7 +898,7 @@ GF_Err gf_hinter_track_finalize(GF_RTPHinter *tkHint, Bool AddSystemInfo) gf_rtp_builder_format_sdp(tkHint->rtp_p, payloadName, sdpLine, config_bytes, config_size); gf_isom_sdp_add_track_line(tkHint->file, tkHint->HintTrack, sdpLine); - free(config_bytes); + gf_free(config_bytes); } /*3GPP DIMS*/ else if (tkHint->rtp_p->rtp_payt==GF_RTP_PAYT_3GPP_DIMS) { @@ -1397,7 +1050,7 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, u32 IOD_Profile, u32 bandwidth) esd->decoderConfig->bufferSizeDB = samp->dataLength; esd->decoderConfig->maxBitrate = 0; size64 = strlen(sdpLine)+1; - esd->URLString = (char*)malloc(sizeof(char) * size64); + esd->URLString = (char*)gf_malloc(sizeof(char) * size64); strcpy(esd->URLString, sdpLine); } else { GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[rtp hinter] OD sample too large to be embedded in IOD - ISMA disabled\n")); @@ -1431,7 +1084,7 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, u32 IOD_Profile, u32 bandwidth) esd->decoderConfig->avgBitrate = 0; esd->decoderConfig->bufferSizeDB = samp->dataLength; esd->decoderConfig->maxBitrate = 0; - esd->URLString = (char*)malloc(sizeof(char) * (strlen(sdpLine)+1)); + esd->URLString = (char*)gf_malloc(sizeof(char) * (strlen(sdpLine)+1)); strcpy(esd->URLString, sdpLine); } else { GF_LOG(GF_LOG_ERROR, GF_LOG_RTP, ("[rtp hinter] Scene description sample too large to be embedded in IOD - ISMA disabled\n")); @@ -1451,10 +1104,10 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, u32 IOD_Profile, u32 bandwidth) esd = gf_isom_get_esd(file, i+1, 1); if (!esd) continue; if (esd->decoderConfig->streamType==GF_STREAM_VISUAL) { - if (esd->decoderConfig->objectTypeIndication==0x20) has_i_v ++; + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) has_i_v ++; else has_v++; } else if (esd->decoderConfig->streamType==GF_STREAM_AUDIO) { - if (esd->decoderConfig->objectTypeIndication==0x40) has_i_a ++; + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_AUDIO_AAC_MPEG4) has_i_a ++; else has_a++; } gf_odf_desc_del((GF_Descriptor *)esd); @@ -1476,7 +1129,7 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, u32 IOD_Profile, u32 bandwidth) //encode in Base64 the iod size64 = gf_base64_encode(buffer, size, buf64, 2000); buf64[size64] = 0; - free(buffer); + gf_free(buffer); sprintf(sdpLine, "a=mpeg4-iod:\"data:application/mpeg4-iod;base64,%s\"", buf64); gf_isom_sdp_add_line(file, sdpLine); @@ -1485,5 +1138,6 @@ GF_Err gf_hinter_finalize(GF_ISOFile *file, u32 IOD_Profile, u32 bandwidth) } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_HINTING*/ +#endif /*GPAC_DISABLE_ISOM*/ diff --git a/src/media_tools/isom_tools.c b/src/media_tools/isom_tools.c index 6908c4f..a94f564 100644 --- a/src/media_tools/isom_tools.c +++ b/src/media_tools/isom_tools.c @@ -1,7 +1,7 @@ /* * GPAC - Multimedia Framework C SDK * - * Copyright (c) Jean Le Feuvre 2000-2005 + * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / Media Tools sub-project @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -27,7 +27,9 @@ #include <gpac/media_tools.h> #include <gpac/constants.h> -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM + +#ifndef GPAC_DISABLE_ISOM_WRITE static const u32 ISMA_VIDEO_OD_ID = 20; static const u32 ISMA_AUDIO_OD_ID = 10; @@ -38,32 +40,32 @@ static const u32 ISMA_AUDIO_ES_ID = 101; static const char ISMA_BIFS_CONFIG[] = {0x00, 0x00, 0x60 }; /*ISMA audio*/ -static const u8 ISMA_BIFS_AUDIO[] = +static const u8 ISMA_BIFS_AUDIO[] = { 0xC0, 0x10, 0x12, 0x81, 0x30, 0x2A, 0x05, 0x7C }; /*ISMA video*/ -static const u8 ISMA_GF_BIFS_VIDEO[] = +static const u8 ISMA_GF_BIFS_VIDEO[] = { 0xC0, 0x10, 0x12, 0x60, 0x42, 0x82, 0x28, 0x29, 0xD0, 0x4F, 0x00 }; /*ISMA audio-video*/ -static const u8 ISMA_BIFS_AV[] = +static const u8 ISMA_BIFS_AV[] = { - 0xC0, 0x10, 0x12, 0x81, 0x30, 0x2A, 0x05, 0x72, + 0xC0, 0x10, 0x12, 0x81, 0x30, 0x2A, 0x05, 0x72, 0x60, 0x42, 0x82, 0x28, 0x29, 0xD0, 0x4F, 0x00 }; /*image only - uses same visual OD ID as video*/ -static const u8 ISMA_BIFS_IMAGE[] = +static const u8 ISMA_BIFS_IMAGE[] = { - 0xC0, 0x11, 0xA4, 0xCD, 0x53, 0x6A, 0x0A, 0x44, + 0xC0, 0x11, 0xA4, 0xCD, 0x53, 0x6A, 0x0A, 0x44, 0x13, 0x00 }; /*ISMA audio-image*/ -static const u8 ISMA_BIFS_AI[] = +static const u8 ISMA_BIFS_AI[] = { 0xC0, 0x11, 0xA5, 0x02, 0x60, 0x54, 0x0A, 0xE4, 0xCD, 0x53, 0x6A, 0x0A, 0x44, 0x13, 0x00 @@ -84,7 +86,7 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B GF_ISOSample *samp; GF_BitStream *bs; u8 audioPL, visualPL; - + switch (gf_isom_get_mode(mp4file)) { case GF_ISOM_OPEN_EDIT: case GF_ISOM_OPEN_WRITE: @@ -109,7 +111,7 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B switch (mType) { case GF_ISOM_MEDIA_VISUAL: image_track = 0; - if (esd && ((esd->decoderConfig->objectTypeIndication==0x6C) || (esd->decoderConfig->objectTypeIndication==0x6D)) ) + if (esd && ((esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_JPEG) || (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_PNG)) ) image_track = 1; /*remove image tracks if wanted*/ @@ -169,7 +171,7 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B //create the OD AU bifs = 0; odU = (GF_ODUpdate *) gf_odf_com_new(GF_ODF_OD_UPDATE_TAG); - + a_esd = v_esd = NULL; update_vid_esd = 0; @@ -187,7 +189,7 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B VideoTrack = gf_isom_get_track_by_id(mp4file, VID); AudioTrack = gf_isom_get_track_by_id(mp4file, AID); - + w = h = 0; if (VideoTrack) { bifs = 1; @@ -209,7 +211,8 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B gf_isom_get_track_layout_info(mp4file, VideoTrack, &w, &h, NULL, NULL, NULL); if (!w || !h) { gf_isom_get_visual_info(mp4file, VideoTrack, 1, &w, &h); - if ((v_esd->decoderConfig->objectTypeIndication==0x20) && (v_esd->decoderConfig->streamType==GF_STREAM_VISUAL)) { +#ifndef GPAC_DISABLE_AV_PARSERS + if ((v_esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) && (v_esd->decoderConfig->streamType==GF_STREAM_VISUAL)) { GF_M4VDecSpecInfo dsi; gf_m4v_get_config(v_esd->decoderConfig->decoderSpecificInfo->data, v_esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); if (!is_image && (!w || !h)) { @@ -224,6 +227,7 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B } if (dsi.VideoPL) visualPL = dsi.VideoPL; } +#endif } } } @@ -249,11 +253,13 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B bifs = 2; } - if (a_esd->decoderConfig->objectTypeIndication == 0x40) { +#ifndef GPAC_DISABLE_AV_PARSERS + if (a_esd->decoderConfig->objectTypeIndication == GPAC_OTI_AUDIO_AAC_MPEG4) { GF_M4ADecSpecInfo cfg; gf_m4a_get_config(a_esd->decoderConfig->decoderSpecificInfo->data, a_esd->decoderConfig->decoderSpecificInfo->dataLength, &cfg); audioPL = cfg.audioPL; } +#endif } } @@ -274,14 +280,14 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B samp->CTS_Offset = 0; samp->DTS = 0; samp->IsRAP = 1; - + /*create the OD track*/ odT = gf_isom_new_track(mp4file, odID, GF_ISOM_MEDIA_OD, gf_isom_get_timescale(mp4file)); if (!odT) return gf_isom_last_error(mp4file); _esd = gf_odf_desc_esd_new(SLPredef_MP4); _esd->decoderConfig->bufferSizeDB = samp->dataLength; - _esd->decoderConfig->objectTypeIndication = 0x01; + _esd->decoderConfig->objectTypeIndication = GPAC_OTI_OD_V1; _esd->decoderConfig->streamType = GF_STREAM_OD; _esd->ESID = odID; _esd->OCRESID = no_ocr ? 0 : bifsID; @@ -298,7 +304,7 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B _esd = gf_odf_desc_esd_new(SLPredef_MP4); _esd->decoderConfig->bufferSizeDB = sizeof(ISMA_BIFS_CONFIG); - _esd->decoderConfig->objectTypeIndication = 0x02; + _esd->decoderConfig->objectTypeIndication = GPAC_OTI_SCENE_BIFS_V2; _esd->decoderConfig->streamType = GF_STREAM_SCENE; _esd->ESID = bifsID; _esd->OCRESID = 0; @@ -321,7 +327,7 @@ GF_Err gf_media_make_isma(GF_ISOFile *mp4file, Bool keepESIDs, Bool keepImage, B gf_odf_desc_del((GF_Descriptor *)_esd); gf_bs_del(bs); gf_isom_set_visual_info(mp4file, bifsT, descIndex, w, h); - + samp = gf_isom_sample_new(); samp->CTS_Offset = 0; samp->DTS = 0; @@ -414,6 +420,8 @@ GF_Err gf_media_make_3gpp(GF_ISOFile *mp4file) nb_non_mp4 ++; break; case GF_ISOM_SUBTYPE_AVC_H264: + case GF_ISOM_SUBTYPE_AVC2_H264: + case GF_ISOM_SUBTYPE_SVC_H264: nb_vid++; nb_avc++; break; @@ -421,7 +429,7 @@ GF_Err gf_media_make_3gpp(GF_ISOFile *mp4file) { GF_ESD *esd = gf_isom_get_esd(mp4file, i+1, 1); /*both MPEG4-Video and H264/AVC are supported*/ - if ((esd->decoderConfig->objectTypeIndication==0x20) || (esd->decoderConfig->objectTypeIndication==0x21) ) { + if ((esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) || (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) ) { nb_vid++; } else { GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Video format not supported by 3GP - removing track ID %d\n", gf_isom_get_track_id(mp4file, i+1) )); @@ -453,11 +461,11 @@ GF_Err gf_media_make_3gpp(GF_ISOFile *mp4file) { GF_ESD *esd = gf_isom_get_esd(mp4file, i+1, 1); switch (esd->decoderConfig->objectTypeIndication) { - case 0xE1: - case 0xA0: - case 0xA1: + case GPAC_OTI_AUDIO_13K_VOICE: + case GPAC_OTI_AUDIO_EVRC_VOICE: + case GPAC_OTI_AUDIO_SMV_VOICE: is_3g2 = 1; - case 0x40: + case GPAC_OTI_AUDIO_AAC_MPEG4: nb_aud++; break; default: @@ -472,14 +480,18 @@ GF_Err gf_media_make_3gpp(GF_ISOFile *mp4file) goto remove_track; } break; + + case GF_ISOM_MEDIA_SUBT: + gf_isom_set_media_type(mp4file, i+1, GF_ISOM_MEDIA_TEXT); case GF_ISOM_MEDIA_TEXT: nb_txt++; break; + case GF_ISOM_MEDIA_SCENE: if (stype == GF_ISOM_MEDIA_DIMS) { nb_dims++; break; - } + } /*clean file*/ default: if (mType==GF_ISOM_MEDIA_HINT) { @@ -514,7 +526,7 @@ remove_track: gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP5, 0); gf_isom_modify_alternate_brand(mp4file, GF_ISOM_BRAND_3GP4, 0); GF_LOG(GF_LOG_INFO, GF_LOG_AUTHOR, ("[3GPP convert] Setting major brand to 3GPP Generic file\n")); - } + } /*commented for QT compatibility, although this is correct (qt doesn't understand 3GP6 brand)*/ else if (nb_txt && 0) { gf_isom_set_brand_info(mp4file, GF_ISOM_BRAND_3GP6, 1024); @@ -558,10 +570,10 @@ GF_Err gf_media_make_psp(GF_ISOFile *mp4) for (i=0; i<count; i++) { switch (gf_isom_get_media_type(mp4, i+1)) { case GF_ISOM_MEDIA_VISUAL: - nb_v++; + nb_v++; break; case GF_ISOM_MEDIA_AUDIO: - nb_a++; + nb_a++; break; } } @@ -606,74 +618,71 @@ typedef struct GF_EXPORT -GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_duration) +GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_duration_sec, u32 dash_mode, Double dash_duration_sec, char *seg_rad_name, u32 fragments_per_sidx, Bool daisy_chain_sidx) { u8 NbBits; - u32 i, TrackNum, descIndex, j, count; + u32 i, TrackNum, descIndex, j, count, nb_sync, ref_track_id; u32 defaultDuration, defaultSize, defaultDescriptionIndex, defaultRandomAccess, nb_samp, nb_done; u8 defaultPadding; u16 defaultDegradationPriority; GF_Err e; - const char *tag; - u32 tag_len; + u32 cur_seg; GF_ISOFile *output; GF_ISOSample *sample, *next; GF_List *fragmenters; u32 MaxFragmentDuration; - TrackFragmenter *tf; - - //create output file - output = gf_isom_open(output_file, GF_ISOM_OPEN_WRITE, NULL); - if (!output) return gf_isom_last_error(NULL); - - - nb_samp = 0; - fragmenters = gf_list_new(); + u32 MaxSegmentDuration; + u32 SegmentDuration, maxFragDurationOverSegment; + Bool switch_segment = 0; + Bool split_seg_at_rap = (dash_mode==2) ? 1 : 0; + Bool split_at_rap = 0; + Bool next_sample_rap = 0; + TrackFragmenter *tf, *tfref; + FILE *mpd = NULL; + char *SegName = NULL; - /*FIXME - ALL THESE SHOULD GO DO A clone_movie item !!*/ - e = gf_isom_set_brand_info(output, GF_ISOM_BRAND_MP42, 1); - if (e) goto err_exit; - e = gf_isom_modify_alternate_brand(output, GF_ISOM_BRAND_ISOM, 1); - if (e) goto err_exit; - - //copy movie desc - gf_isom_clone_root_od(input, output); - //clone copyright - count = gf_isom_get_copyright_count(input); - if (count) { - const char *lang, *note; - for (i=0; i<count; i++) { - gf_isom_get_copyright(input, i+1, &lang, ¬e); - gf_isom_set_copyright(output, (char *)lang, (char *)note); - } - } - count = gf_isom_get_chapter_count(input, 0); - if (count) { - const char *name; - u64 time; - for (i=0; i<count; i++) { - gf_isom_get_chapter(input, 0, i+1, &time, &name); - gf_isom_add_chapter(output, 0, time, (char *)name); + //create output file + if (dash_mode) { + u32 len = strlen(output_file); + len += 100; + SegName = gf_malloc(sizeof(char)*len); + if (!SegName) return GF_OUT_OF_MEM; + 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; } + strcpy(SegName, output_file); + strcat(SegName, ".mpd"); + mpd = fopen(SegName, "wt"); + } 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 (gf_isom_apple_get_tag(input, 0, &tag, &tag_len) == GF_OK) { - for (i=GF_ISOM_ITUNE_ALBUM; i<GF_ISOM_ITUNE_WRITER; i++) { - if (gf_isom_apple_get_tag(input, GF_ISOM_ITUNE_NAME, &tag, &tag_len)==GF_OK) - gf_isom_apple_set_tag(output, GF_ISOM_ITUNE_NAME, tag, tag_len); - } - } + 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); + tfref = NULL; - MaxFragmentDuration = (u32) (max_duration * 1000); //duplicates all tracks for (i=0; i<gf_isom_get_track_count(input); i++) { + if (gf_isom_get_media_type(input, i+1) == GF_ISOM_MEDIA_HINT) continue; + e = gf_isom_clone_track(input, i+1, output, 0, &TrackNum); if (e) goto err_exit; - //if few samples don't fragment track + //if only one sample, don't fragment track count = gf_isom_get_sample_count(input, i+1); - if (count<=2) { + if (count<=1) { for (j=0; j<count; j++) { sample = gf_isom_get_sample(input, i+1, j+1, &descIndex); e = gf_isom_add_sample(output, TrackNum, 1, sample); @@ -683,12 +692,12 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d } //otherwise setup fragmented else { - gf_isom_get_fragment_defaults(input, i+1, + gf_isom_get_fragment_defaults(input, i+1, &defaultDuration, &defaultSize, &defaultDescriptionIndex, &defaultRandomAccess, &defaultPadding, &defaultDegradationPriority); //otherwise setup fragmentation - e = gf_isom_setup_track_fragment(output, gf_isom_get_track_id(output, TrackNum), - defaultDescriptionIndex, defaultDuration, - defaultSize, (u8) defaultRandomAccess, + 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; @@ -699,41 +708,82 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d 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); + } + gf_list_add(fragmenters, tf); nb_samp += count; } if (gf_isom_is_track_in_root_od(input, i+1)) gf_isom_add_track_to_root_od(output, TrackNum); - //copy user data ? } + if (!tfref) tfref = gf_list_get(fragmenters, 0); + ref_track_id = tfref->TrackID; //flush movie - e = gf_isom_finalize_for_fragment(output); + e = gf_isom_finalize_for_fragment(output, dash_mode ? 1 : 0); if (e) goto err_exit; + if (dash_mode) { + fprintf(mpd, "<MPD type=\"OnDemand\" xmlns=\"urn:3GPP:ns:PSS:AdaptiveHTTPStreamingMPD:2009\">\n"); + fprintf(mpd, " <ProgramInformation moreInformationURL=\"http://gpac.sourceforge.net\">\n"); + fprintf(mpd, " <Title>Media Presentation Description for file %s generated with GPAC \n", gf_isom_get_filename(input)); + fprintf(mpd, " \n"); + fprintf(mpd, " \n"); + fprintf(mpd, " \n"); + fprintf(mpd, " \n", dash_duration_sec); + fprintf(mpd, " \n", output_file); + } + nb_done = 0; + cur_seg=1; + maxFragDurationOverSegment=0; + if (dash_mode) switch_segment=1; while ( (count = gf_list_count(fragmenters)) ) { - e = gf_isom_start_fragment(output); - if (e) goto err_exit; - //setup some default - for (i=0; iMediaType == GF_ISOM_MEDIA_VISUAL) { - e = gf_isom_set_fragment_option(output, tf->TrackID, GF_ISOM_TRAF_RANDOM_ACCESS, 1); - if (e) goto err_exit; + if (switch_segment) { + SegmentDuration = 0; + switch_segment = 0; + if (seg_rad_name) { + sprintf(SegName, "%s_seg%d.mp4", seg_rad_name, cur_seg); + e = gf_isom_start_segment(output, SegName); + if (dash_mode) fprintf(mpd, " \n", SegName); + } else { + e = gf_isom_start_segment(output, NULL); } - } + cur_seg++; + if (e) goto err_exit; + } + + maxFragDurationOverSegment=0; + e = gf_isom_start_fragment(output, 1); + if (e) goto err_exit; sample = NULL; - + //process track by track for (i=0; iOriginalTrack, tf->SampleNum + 1, &descIndex); } @@ -746,7 +796,7 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d defaultDuration = tf->DefaultDuration; } - e = gf_isom_fragment_add_sample(output, tf->TrackID, sample, descIndex, + e = gf_isom_fragment_add_sample(output, tf->TrackID, sample, descIndex, defaultDuration, NbBits, 0); if (e) goto err_exit; @@ -758,16 +808,54 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d tf->FragmentLength += defaultDuration; tf->SampleNum += 1; + if (split_seg_at_rap && (tf==tfref) && next && next->IsRAP) { + next_sample_rap = 1; + if ((tf->FragmentLength+2*defaultDuration)*1000 >= MaxFragmentDuration*tf->TimeScale) + split_at_rap = 1; + + if (split_at_rap) { + stop_frag = 1; + /*override fragment duration for the rest of this fragment*/ + MaxFragmentDuration = tf->FragmentLength*1000/tf->TimeScale; + } + } + else next_sample_rap = 0; + //end of track fragment or track - if ((tf->SampleNum==tf->SampleCount) || (tf->FragmentLength*1000 > MaxFragmentDuration*tf->TimeScale)) { + if (stop_frag || + (tf->SampleNum==tf->SampleCount) || + /* TODO: should probably test the time position (not only duration) to avoid drift */ + (tf->FragmentLength*1000 >= MaxFragmentDuration*tf->TimeScale)) { gf_isom_sample_del(&next); sample = next = NULL; + if (maxFragDurationOverSegment<=tf->FragmentLength*1000/tf->TimeScale) { + maxFragDurationOverSegment = tf->FragmentLength*1000/tf->TimeScale; + } tf->FragmentLength = 0; break; } } + if (dash_mode) { + SegmentDuration += maxFragDurationOverSegment; + + if ((SegmentDuration >= MaxSegmentDuration) && (!split_seg_at_rap || next_sample_rap)) { + switch_segment=1; + maxFragDurationOverSegment=0; + SegmentDuration=0; + split_at_rap = 0; + /*restore fragment duration*/ + MaxFragmentDuration = (u32) (max_duration_sec * 1000); + + gf_isom_close_segment(output, fragments_per_sidx, ref_track_id, NULL, 0, daisy_chain_sidx); + } + /*next fragment will exceed segment length, abort fragment at next rap*/ + if (split_seg_at_rap && (SegmentDuration + MaxFragmentDuration >= MaxSegmentDuration)) { + split_at_rap = 1; + } + } + if (tf->SampleNum==tf->SampleCount) { - free(tf); + gf_free(tf); gf_list_rem(fragmenters, i); i--; count --; @@ -775,35 +863,94 @@ GF_Err gf_media_fragment_file(GF_ISOFile *input, char *output_file, Double max_d } } + if (dash_mode) { + gf_isom_close_segment(output, fragments_per_sidx, ref_track_id, NULL, 0, daisy_chain_sidx); + fprintf(mpd, " \n"); + fprintf(mpd, " \n"); + fprintf(mpd, " \n"); + fprintf(mpd, ""); + } + err_exit: while (gf_list_count(fragmenters)) { tf = (TrackFragmenter *)gf_list_get(fragmenters, 0); - free(tf); + 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); return e; } 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; + u32 state, unicode_type, offset; u32 cur_chap; u64 ts; - u32 h, m, s, ms, fr, fps; + u32 i, h, m, s, ms, fr, fps; char line[1024]; char szTitle[1024]; - FILE *f = fopen(chap_file, "rt"); + 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; + } + unicode_type = 2; + offset = 2; + } else if ((line[0]==(char)(0xFE)) && (line[1]==(char)(0xFF))) { + if (!line[2] && !line[3]){ + e = GF_NOT_SUPPORTED; + goto err_exit; + } + unicode_type = 1; + offset = 2; + } else if ((line[0]==(char)(0xEF)) && (line[1]==(char)(0xBB)) && (line[2]==(char)(0xBF))) { + /*we handle UTF8 as asci*/ + unicode_type = 0; + offset = 3; + } else { + unicode_type = 0; + 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; iDTS; + 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 (%d:%d)\n", import_fps, ts, inc)); + break; + } + + cur_chap = 0; ts = 0; state = 0; @@ -847,9 +994,9 @@ GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import sscanf(sL, "AddChapterByTime(%d,%d,%d,%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, ','); + 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*/ @@ -858,7 +1005,7 @@ GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import if (strlen(sL)==8) { sscanf(sL, "%02d:%02d:%02d", &h, &m, &s); ts = (h*3600 + m*60+s)*1000; - } + } else { char szTS[20], *tok; strncpy(szTS, sL, 18); @@ -890,7 +1037,7 @@ GF_Err gf_media_import_chapters(GF_ISOFile *file, char *chap_file, Double import ts = (h*3600 + m*60+s) * 1000; } } - } + } /*CHAPTERX= and CHAPTERXNAME=*/ else if (!strnicmp(sL, "CHAPTER", 7)) { u32 idx; @@ -952,7 +1099,7 @@ err_exit: return e; } -#endif //GPAC_READ_ONLY +#endif /*GPAC_DISABLE_ISOM_WRITE*/ GF_EXPORT GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track) @@ -968,14 +1115,19 @@ GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track) case GF_ISOM_SUBTYPE_MPEG4: case GF_ISOM_SUBTYPE_MPEG4_CRYP: case GF_ISOM_SUBTYPE_AVC_H264: + case GF_ISOM_SUBTYPE_AVC2_H264: + case GF_ISOM_SUBTYPE_SVC_H264: case GF_ISOM_SUBTYPE_3GP_EVRC: case GF_ISOM_SUBTYPE_3GP_QCELP: case GF_ISOM_SUBTYPE_3GP_SMV: return gf_isom_get_esd(mp4, track, 1); } - if (gf_isom_get_media_type(mp4, track) == GF_ISOM_MEDIA_TEXT) + switch (gf_isom_get_media_type(mp4, track)) { + case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: return gf_isom_get_esd(mp4, track, 1); + } if ((subtype == GF_ISOM_SUBTYPE_3GP_AMR) || (subtype == GF_ISOM_SUBTYPE_3GP_AMR_WB)) { GF_3GPConfig *gpc = gf_isom_3gp_config_get(mp4, track, 1); @@ -994,7 +1146,7 @@ GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track) gf_bs_write_u16(bs, (subtype == GF_ISOM_SUBTYPE_3GP_AMR) ? 160 : 320); gf_bs_write_u8(bs, 16); gf_bs_write_u8(bs, gpc ? gpc->frames_per_sample : 0); - if (gpc) free(gpc); + if (gpc) gf_free(gpc); gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); return esd; @@ -1026,7 +1178,7 @@ GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track) esd->ESID = gf_isom_get_track_id(mp4, track); esd->OCRESID = esd->ESID; esd->decoderConfig->streamType = GF_STREAM_AUDIO; - esd->decoderConfig->objectTypeIndication = 0xA5; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AC3; gf_odf_desc_del((GF_Descriptor*)esd->decoderConfig->decoderSpecificInfo); esd->decoderConfig->decoderSpecificInfo = NULL; return esd; @@ -1083,10 +1235,13 @@ GF_ESD *gf_media_map_esd(GF_ISOFile *mp4, u32 track) } if (udesc && udesc->extension_buf_size) { gf_bs_write_data(bs, udesc->extension_buf, udesc->extension_buf_size); - free(udesc->extension_buf); + gf_free(udesc->extension_buf); } - if (udesc) free(udesc); + if (udesc) gf_free(udesc); gf_bs_get_content(bs, &esd->decoderConfig->decoderSpecificInfo->data, &esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(bs); return esd; } + +#endif /*GPAC_DISABLE_ISOM*/ + diff --git a/src/media_tools/m2ts_mux.c b/src/media_tools/m2ts_mux.c new file mode 100644 index 0000000..a47fd53 --- /dev/null +++ b/src/media_tools/m2ts_mux.c @@ -0,0 +1,1501 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c)2008-200X Telecom ParisTech - All rights reserved + * Authors: Jean Le Feuvre + * + * This file is part of GPAC / MPEG2-TS 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 +#include +#include + +#ifndef GPAC_DISABLE_MPEG2TS_MUX + + +static GFINLINE Bool gf_m2ts_time_less(GF_M2TS_Time *a, GF_M2TS_Time *b) { + if (a->sec>b->sec) return 0; + if (a->sec==b->sec) return (a->nanosecnanosec) ? 1 : 0; + return 1; +} +static GFINLINE Bool gf_m2ts_time_less_or_equal(GF_M2TS_Time *a, GF_M2TS_Time *b) { + if (a->sec>b->sec) return 0; + if (a->sec==b->sec) return (a->nanosec>b->nanosec) ? 0 : 1; + return 1; +} + +static GFINLINE void gf_m2ts_time_inc(GF_M2TS_Time *time, u32 delta_inc_num, u32 delta_inc_den) +{ + u64 n_sec; + u32 sec; + + /*couldn't compute bitrate - we need to have more info*/ + if (!delta_inc_den) return; + + sec = delta_inc_num / delta_inc_den; + + if (sec) { + time->sec += sec; + sec *= delta_inc_den; + delta_inc_num = delta_inc_num % sec; + } + /*move to nanosec - 0x3B9ACA00 = 1000*1000*1000 */ + n_sec = delta_inc_num; + n_sec *= 0x3B9ACA00; + n_sec /= delta_inc_den; + time->nanosec += (u32) n_sec; + while (time->nanosec >= 0x3B9ACA00) { + time->nanosec -= 0x3B9ACA00; + time->sec ++; + } +} + +/************************************ + * Section-related functions + ************************************/ +void gf_m2ts_mux_table_update(GF_M2TS_Mux_Stream *stream, u8 table_id, u16 table_id_extension, + u8 *table_payload, u32 table_payload_length, + Bool use_syntax_indicator, Bool private_indicator, + Bool use_checksum) +{ + u32 overhead_size; + u32 offset; + u32 section_number, nb_sections; + GF_M2TS_Mux_Table *table, *prev_table; + u32 maxSectionLength; + GF_M2TS_Mux_Section *section, *prev_sec; + GF_BitStream *bs; + + /* check if there is already a table with that id */ + prev_table = NULL; + table = stream->tables; + while (table) { + if (table->table_id == table_id) { + /* if yes, we need to flush the table and increase the version number */ + GF_M2TS_Mux_Section *sec = table->section; + while (sec) { + GF_M2TS_Mux_Section *sec2 = sec->next; + gf_free(sec->data); + gf_free(sec); + sec = sec2; + } + table->version_number = (table->version_number + 1)%0x1F; + break; + } + prev_table = table; + table = table->next; + } + + if (!table) { + /* if no, the table is created */ + GF_SAFEALLOC(table, GF_M2TS_Mux_Table); + table->table_id = table_id; + if (prev_table) prev_table->next = table; + else stream->tables = table; + } + + if (!table_payload_length) return; + + switch (table_id) { + case GF_M2TS_TABLE_ID_PMT: + case GF_M2TS_TABLE_ID_PAT: + case GF_M2TS_TABLE_ID_SDT_ACTUAL: + case GF_M2TS_TABLE_ID_SDT_OTHER: + case GF_M2TS_TABLE_ID_BAT: + maxSectionLength = 1024; + break; + case GF_M2TS_TABLE_ID_MPEG4_BIFS: + case GF_M2TS_TABLE_ID_MPEG4_OD: + maxSectionLength = 4096; + break; + default: + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Cannot create sections for table id %d\n", stream->pid, table_id)); + return; + } + + overhead_size = SECTION_HEADER_LENGTH; + if (use_syntax_indicator) overhead_size += SECTION_ADDITIONAL_HEADER_LENGTH + CRC_LENGTH; + + section_number = 0; + nb_sections = 1; + while (nb_sections*(maxSectionLength - overhead_size) 1) + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] last section number for PMT shall be 0\n")); + break; + default: + break; + } + + prev_sec = NULL; + offset = 0; + while (offset < table_payload_length) { + u32 remain; + GF_SAFEALLOC(section, GF_M2TS_Mux_Section); + + remain = table_payload_length - offset; + if (remain > maxSectionLength - overhead_size) { + section->length = maxSectionLength; + } else { + section->length = remain + overhead_size; + } + + bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); + + /* first header (not included in section length */ + gf_bs_write_int(bs, table_id, 8); + gf_bs_write_int(bs, use_syntax_indicator, 1); + gf_bs_write_int(bs, private_indicator, 1); + gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */ + gf_bs_write_int(bs, section->length - SECTION_HEADER_LENGTH, 12); + + if (use_syntax_indicator) { + /* second header */ + gf_bs_write_int(bs, table_id_extension, 16); + gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */ + gf_bs_write_int(bs, table->version_number, 5); + gf_bs_write_int(bs, 1, 1); /* current_next_indicator = 1: we don't send version in advance */ + gf_bs_write_int(bs, section_number, 8); + section_number++; + gf_bs_write_int(bs, nb_sections-1, 8); + } + + gf_bs_write_data(bs, table_payload + offset, section->length - overhead_size); + offset += section->length - overhead_size; + + if (use_syntax_indicator) { + /* place holder for CRC */ + gf_bs_write_u32(bs, 0); + } + + gf_bs_get_content(bs, (char**) §ion->data, §ion->length); + gf_bs_del(bs); + + if (use_syntax_indicator) { + u32 CRC; + CRC = gf_crc_32(section->data,section->length-CRC_LENGTH); + section->data[section->length-4] = (CRC >> 24) & 0xFF; + section->data[section->length-3] = (CRC >> 16) & 0xFF; + section->data[section->length-2] = (CRC >> 8) & 0xFF; + section->data[section->length-1] = CRC & 0xFF; + } + + if (prev_sec) prev_sec->next = section; + else table->section = section; + prev_sec = section; + } + stream->current_table = stream->tables; + stream->current_section = stream->current_table->section; + stream->current_section_offset = 0; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Generating %d sections for table id %d - version number %d - extension ID %d\n", stream->pid, nb_sections, table_id, table->version_number, table_id_extension)); +} + +void gf_m2ts_mux_table_update_bitrate(GF_M2TS_Mux *mux, GF_M2TS_Mux_Stream *stream) +{ + GF_M2TS_Mux_Table *table; + + /*update PMT*/ + if (stream->table_needs_update) + stream->process(mux, stream); + + stream->bit_rate = 0; + table = stream->tables; + while (table) { + GF_M2TS_Mux_Section *section = table->section; + while (section) { + stream->bit_rate += section->length; + section = section->next; + } + table = table->next; + } + stream->bit_rate *= 8; + if (!stream->refresh_rate_ms) stream->refresh_rate_ms = 500; + stream->bit_rate *= 1000; + stream->bit_rate /= stream->refresh_rate_ms; +} + +void gf_m2ts_mux_table_update_mpeg4(GF_M2TS_Mux_Stream *stream, u8 table_id, u16 table_id_extension, + u8 *table_payload, u32 table_payload_length, + Bool use_syntax_indicator, Bool private_indicator, + Bool increment_version_number, Bool use_checksum) +{ + GF_SLHeader hdr; + u32 overhead_size; + u32 offset, sl_size; + u32 section_number, nb_sections; + GF_M2TS_Mux_Table *table, *prev_table; + /*max section length for MPEG-4 BIFS and OD*/ + u32 maxSectionLength = 4096; + GF_M2TS_Mux_Section *section, *prev_sec; + GF_BitStream *bs; + + /* check if there is already a table with that id */ + prev_table = NULL; + table = stream->tables; + while (table) { + if (table->table_id == table_id) { + /* if yes, we need to flush the table and increase the version number */ + GF_M2TS_Mux_Section *sec = table->section; + while (sec) { + GF_M2TS_Mux_Section *sec2 = sec->next; + gf_free(sec->data); + gf_free(sec); + sec = sec2; + } + if (increment_version_number) + table->version_number = (table->version_number + 1)%0x1F; + break; + } + prev_table = table; + table = table->next; + } + + if (!table) { + /* if no, the table is created */ + GF_SAFEALLOC(table, GF_M2TS_Mux_Table); + table->table_id = table_id; + if (prev_table) prev_table->next = table; + else stream->tables = table; + } + + if (!table_payload_length) return; + + overhead_size = SECTION_HEADER_LENGTH; + if (use_syntax_indicator) overhead_size += SECTION_ADDITIONAL_HEADER_LENGTH + CRC_LENGTH; + + section_number = 0; + nb_sections = 1; + hdr = stream->sl_header; + sl_size = gf_sl_get_header_size(&stream->sl_config, &hdr); + /*SL-packetized data doesn't fit in one section, we must repacketize*/ + if (sl_size + table_payload_length > maxSectionLength - overhead_size) { + nb_sections = 0; + offset = 0; + hdr.accessUnitEndFlag = 0; + while (offsetsl_config, &hdr); + /*remove start flag*/ + hdr.accessUnitStartFlag = 0; + /*fill each section but beware of last packet*/ + offset += maxSectionLength - overhead_size - sl_size; + nb_sections++; + } + } + prev_sec = NULL; + offset = 0; + hdr = stream->sl_header; + while (offset < table_payload_length) { + u32 remain; + char *slhdr; + u32 slhdr_size; + GF_SAFEALLOC(section, GF_M2TS_Mux_Section); + + hdr.accessUnitEndFlag = (section_number+1==nb_sections) ? stream->sl_header.accessUnitEndFlag : 0; + gf_sl_packetize(&stream->sl_config, &hdr, NULL, 0, &slhdr, &slhdr_size); + hdr.accessUnitStartFlag = 0; + + remain = table_payload_length - offset; + if (remain > maxSectionLength - overhead_size - slhdr_size) { + section->length = maxSectionLength; + } else { + section->length = remain + overhead_size + slhdr_size; + } + sl_size = section->length - overhead_size - slhdr_size; + + bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); + + /* first header (not included in section length */ + gf_bs_write_int(bs, table_id, 8); + gf_bs_write_int(bs, use_syntax_indicator, 1); + gf_bs_write_int(bs, private_indicator, 1); + gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */ + gf_bs_write_int(bs, section->length - SECTION_HEADER_LENGTH, 12); + + if (use_syntax_indicator) { + /* second header */ + gf_bs_write_int(bs, table_id_extension, 16); + gf_bs_write_int(bs, 3, 2); /* reserved bits are all set */ + gf_bs_write_int(bs, table->version_number, 5); + gf_bs_write_int(bs, 1, 1); /* current_next_indicator = 1: we don't send version in advance */ + gf_bs_write_int(bs, section_number, 8); + section_number++; + gf_bs_write_int(bs, nb_sections-1, 8); + } + + /*write sl header*/ + gf_bs_write_data(bs, slhdr, slhdr_size); + gf_free(slhdr); + /*write sl data*/ + gf_bs_write_data(bs, table_payload + offset, sl_size); + offset += sl_size; + + if (use_syntax_indicator) { + /* place holder for CRC */ + gf_bs_write_u32(bs, 0); + } + + gf_bs_get_content(bs, (char**) §ion->data, §ion->length); + gf_bs_del(bs); + + if (use_syntax_indicator) { + u32 CRC; + CRC = gf_crc_32(section->data,section->length-CRC_LENGTH); + section->data[section->length-4] = (CRC >> 24) & 0xFF; + section->data[section->length-3] = (CRC >> 16) & 0xFF; + section->data[section->length-2] = (CRC >> 8) & 0xFF; + section->data[section->length-1] = CRC & 0xFF; + } + + if (prev_sec) prev_sec->next = section; + else table->section = section; + prev_sec = section; + } + stream->current_table = stream->tables; + stream->current_section = stream->current_table->section; + stream->current_section_offset = 0; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Generating %d sections for MPEG-4 SL packet - version number %d - extension ID %d\n", stream->pid, nb_sections, table->version_number, table_id_extension)); + + { + /*discard first packet*/ + GF_M2TS_Packet *pck; + gf_mx_p(stream->mx); + assert(stream->pck_first); + pck = stream->pck_first; + stream->pck_first = pck->next; + gf_mx_v(stream->mx); + gf_free(pck->data); + gf_free(pck); + } + + if (stream->ifce->repeat_rate) { + stream->refresh_rate_ms = stream->ifce->repeat_rate; + gf_m2ts_mux_table_update_bitrate(stream->program->mux, stream); + } else { + gf_m2ts_mux_table_update_bitrate(stream->program->mux, stream); + stream->refresh_rate_ms=0; + } +} + +/* length of adaptation_field_length; */ +#define ADAPTATION_LENGTH_LENGTH 1 +/* discontinuty flag, random access flag ... */ +#define ADAPTATION_FLAGS_LENGTH 1 +/* length of encoded pcr */ +#define PCR_LENGTH 6 + +static u32 gf_m2ts_add_adaptation(GF_BitStream *bs, u16 pid, + Bool has_pcr, u64 pcr_time, + Bool is_rap, + u32 padding_length) +{ + u32 adaptation_length; + + adaptation_length = ADAPTATION_FLAGS_LENGTH + (has_pcr?PCR_LENGTH:0) + padding_length; + + gf_bs_write_int(bs, adaptation_length, 8); + gf_bs_write_int(bs, 0, 1); // discontinuity indicator + gf_bs_write_int(bs, is_rap, 1); // random access indicator + gf_bs_write_int(bs, 0, 1); // es priority indicator + gf_bs_write_int(bs, has_pcr, 1); // PCR_flag + gf_bs_write_int(bs, 0, 1); // OPCR flag + gf_bs_write_int(bs, 0, 1); // splicing point flag + gf_bs_write_int(bs, 0, 1); // transport private data flag + gf_bs_write_int(bs, 0, 1); // adaptation field extension flag + if (has_pcr) { + u64 PCR_base, PCR_ext; + PCR_base = pcr_time/300; + gf_bs_write_long_int(bs, PCR_base, 33); + gf_bs_write_int(bs, 0, 6); // reserved + PCR_ext = pcr_time - PCR_base*300; + gf_bs_write_long_int(bs, PCR_ext, 9); + + +#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)); + } 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 + + } + + while (padding_length) { + gf_bs_write_u8(bs, 0xff); // stuffing byte + padding_length--; + } + + return adaptation_length + ADAPTATION_LENGTH_LENGTH; +} + +void gf_m2ts_mux_table_get_next_packet(GF_M2TS_Mux_Stream *stream, u8 *packet) +{ + GF_BitStream *bs; + GF_M2TS_Mux_Table *table; + GF_M2TS_Mux_Section *section; + u32 payload_length, padding_length; + u8 adaptation_field_control; + + table = stream->current_table; + assert(table); + + section = stream->current_section; + assert(section); + + bs = gf_bs_new(packet, 188, GF_BITSTREAM_WRITE); + + gf_bs_write_int(bs, 0x47, 8); // sync + gf_bs_write_int(bs, 0, 1); // error indicator + if (stream->current_section_offset == 0) { + gf_bs_write_int(bs, 1, 1); // payload start indicator + } else { + /* No section concatenation yet!!!*/ + gf_bs_write_int(bs, 0, 1); // payload start indicator + } + + if (!stream->current_section_offset) payload_length = 183; + else payload_length = 184; + + if (section->length - stream->current_section_offset >= payload_length) { + padding_length = 0; + adaptation_field_control = GF_M2TS_ADAPTATION_NONE; + } else { + /* in all the following cases, we write an adaptation field */ + adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD; + /* we need at least 2 bytes for adaptation field headers (no pcr) */ + payload_length -= 2; + if (section->length - stream->current_section_offset >= payload_length) { + padding_length = 0; + } else { + padding_length = payload_length - section->length + stream->current_section_offset; + payload_length -= padding_length; + } + } + assert(payload_length + stream->current_section_offset <= section->length); + + gf_bs_write_int(bs, 0, 1); /*priority indicator*/ + gf_bs_write_int(bs, stream->pid, 13); /*pid*/ + gf_bs_write_int(bs, 0, 2); /*scrambling indicator*/ + gf_bs_write_int(bs, adaptation_field_control, 2); /*we do not use adaptation field for sections */ + gf_bs_write_int(bs, stream->continuity_counter, 4); /*continuity counter*/ + if (stream->continuity_counter < 15) stream->continuity_counter++; + 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); + + /*pointer field*/ + if (!stream->current_section_offset) { + /* no concatenations of sections in ts packets, so start address is 0 */ + gf_bs_write_u8(bs, 0); + } + gf_bs_del(bs); + + memcpy(packet+188-payload_length, section->data + stream->current_section_offset, payload_length); + stream->current_section_offset += payload_length; + + if (stream->current_section_offset == section->length) { + stream->current_section_offset = 0; + stream->current_section = stream->current_section->next; + if (!stream->current_section) { + stream->current_table = stream->current_table->next; + /*carousel table*/ + if (!stream->current_table) { + if (stream->ifce) stream->refresh_rate_ms = stream->ifce->repeat_rate; + if (stream->refresh_rate_ms) { + stream->current_table = stream->tables; + /*update ES time*/ + gf_m2ts_time_inc(&stream->time, stream->refresh_rate_ms, 1000); + } + } + if (stream->current_table) stream->current_section = stream->current_table->section; + } + } + +} + + + +Bool gf_m2ts_stream_process_pat(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) +{ + if (stream->table_needs_update) { /* generate table payload */ + GF_M2TS_Mux_Program *prog; + GF_BitStream *bs; + u8 *payload; + u32 size; + + bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + prog = muxer->programs; + while (prog) { + gf_bs_write_u16(bs, prog->number); + gf_bs_write_int(bs, 0x7, 3); /*reserved*/ + gf_bs_write_int(bs, prog->pmt->pid, 13); /*reserved*/ + prog = prog->next; + } + gf_bs_get_content(bs, (char**)&payload, &size); + gf_bs_del(bs); + gf_m2ts_mux_table_update(stream, GF_M2TS_TABLE_ID_PAT, muxer->ts_id, payload, size, 1, 0, 0); + stream->table_needs_update = 0; + gf_free(payload); + } + return 1; +} + +Bool gf_m2ts_stream_process_pmt(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) +{ + if (stream->table_needs_update) { /* generate table payload */ + GF_M2TS_Mux_Stream *es; + u8 *payload; + u32 length, nb_streams=0; + GF_BitStream *bs; + + bs = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); + gf_bs_write_int(bs, 0x7, 3); // reserved + gf_bs_write_int(bs, stream->program->pcr->pid, 13); + gf_bs_write_int(bs, 0xF, 4); // reserved + + if (!stream->program->iod) { + gf_bs_write_int(bs, 0, 12); // program info length =0 + } else { + u32 len, i; + GF_ESD *esd; + GF_BitStream *bs_iod; + char *iod_data; + u32 iod_data_len; + + /*rewrite SL config in IOD streams*/ + i=0; + while (esd = gf_list_enum(((GF_ObjectDescriptor*)stream->program->iod)->ESDescriptors, &i)) { + GF_M2TS_Mux_Stream *es_stream = stream->program->streams; + while (es_stream) { + if (es_stream->ifce && (es_stream->ifce->stream_id==esd->ESID)) { + memcpy(esd->slConfig, &es_stream->sl_config, sizeof(GF_SLConfig)); + break; + } + es_stream = es_stream->next; + } + } + + bs_iod = gf_bs_new(NULL,0,GF_BITSTREAM_WRITE); + gf_odf_write_descriptor(bs_iod, stream->program->iod); + gf_bs_get_content(bs_iod, &iod_data, &iod_data_len); + gf_bs_del(bs_iod); + + len = iod_data_len + 4; + gf_bs_write_int(bs, len, 12); // program info length + + gf_bs_write_int(bs, GF_M2TS_MPEG4_IOD_DESCRIPTOR, 8); + len = iod_data_len + 2; + gf_bs_write_int(bs, len, 8); + + /* Scope_of_IOD_label : + 0x10 iod unique a l'int�rieur de programme + 0x11 iod unoque dans le flux ts */ + gf_bs_write_int(bs, 2, 8); + + gf_bs_write_int(bs, 2, 8); // IOD_label + + gf_bs_write_data(bs, iod_data, iod_data_len); + gf_free(iod_data); + } + es = stream->program->streams; + while (es) { + nb_streams++; + gf_bs_write_int(bs, es->mpeg2_stream_type, 8); + gf_bs_write_int(bs, 0x7, 3); // reserved + gf_bs_write_int(bs, es->pid, 13); + gf_bs_write_int(bs, 0xF, 4); // reserved + + /* Second Loop Descriptor */ + if (stream->program->iod) { + gf_bs_write_int(bs, 4, 12); // ES info length = 4 :only SL Descriptor + gf_bs_write_int(bs, GF_M2TS_MPEG4_SL_DESCRIPTOR, 8); + gf_bs_write_int(bs, 2, 8); + gf_bs_write_int(bs, es->ifce->stream_id, 16); // mpeg4_esid + } else { + gf_bs_write_int(bs, 0, 12); + } + es = es->next; + } + + gf_bs_get_content(bs, (char**)&payload, &length); + gf_bs_del(bs); + + gf_m2ts_mux_table_update(stream, GF_M2TS_TABLE_ID_PMT, stream->program->number, payload, length, 1, 0, 0); + stream->table_needs_update = 0; + gf_free(payload); + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Updating PMT - Program Number %d - %d streams - size %d%s\n", stream->pid, stream->program->number, nb_streams, length, stream->program->iod ? " - MPEG-4 Systems detected":"")); + } + return 1; +} + +static u32 gf_m2ts_stream_get_pes_header_length(GF_M2TS_Mux_Stream *stream) +{ + u32 hdr_len; + /*not the AU start*/ + if (stream->pck_offset || !(stream->pck.flags & GF_ESI_DATA_AU_START) ) return 0; + hdr_len = 9; + if (stream->pck.flags & GF_ESI_DATA_HAS_CTS) hdr_len += 5; + if (stream->pck.flags & GF_ESI_DATA_HAS_DTS) hdr_len += 5; + return hdr_len; +} + +Bool gf_m2ts_stream_process_stream(GF_M2TS_Mux *muxer, GF_M2TS_Mux_Stream *stream) +{ + u64 pcr_offset; + u32 next_time; + Bool ret = 0; + + if (stream->mpeg2_stream_type==GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { + /*section is not completely sent yet or this is not the first section of the table*/ + if (stream->current_section && (stream->current_section_offset || stream->current_section!=stream->current_table->section)) + return 1; + if (stream->ifce->repeat_rate && stream->tables) + ret = 1; + } + else if (stream->pck_offset < stream->pck.data_len) { + /*PES packet not completely sent yet*/ + return 1; + } + + /*PULL mode*/ + if (stream->ifce->caps & GF_ESI_AU_PULL_CAP) { + if (stream->pck.data_len) { + /*discard packet data if we use SL over PES*/ + if (stream->mpeg2_stream_type==GF_M2TS_SYSTEMS_MPEG4_PES) gf_free(stream->pck.data); + /*release data*/ + stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_RELEASE, NULL); + } + stream->pck_offset = 0; + stream->pck.data_len = 0; + + /*EOS*/ + if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) return 0; + stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_PULL, &stream->pck); + } else { + GF_M2TS_Packet *pck; + /*flush input pipe*/ + stream->ifce->input_ctrl(stream->ifce, GF_ESI_INPUT_DATA_FLUSH, NULL); + gf_mx_p(stream->mx); + + stream->pck_offset = 0; + stream->pck.data_len = 0; + + /*fill pck*/ + pck = stream->pck_first; + if (!pck) { + gf_mx_v(stream->mx); + return ret; + } + stream->pck.cts = pck->cts; + stream->pck.data = pck->data; + stream->pck.data_len = pck->data_len; + stream->pck.dts = pck->dts; + stream->pck.flags = pck->flags; + gf_mx_v(stream->mx); + } + if (!(stream->pck.flags & GF_ESI_DATA_HAS_DTS)) + stream->pck.dts = stream->pck.cts; + + /*Rescale our timestamps and express them in PCR*/ + if (stream->ts_scale) { + stream->pck.cts = (u64) (stream->ts_scale * (s64) stream->pck.cts); + stream->pck.dts = (u64) (stream->ts_scale * (s64) stream->pck.dts); + } + + /*initializing the PCR*/ + if (!stream->program->pcr_init_time) { + if (stream==stream->program->pcr) { + while (!stream->program->pcr_init_time) + stream->program->pcr_init_time = gf_rand(); + + stream->program->pcr_init_time=1; + + stream->program->ts_time_at_pcr_init = muxer->time; + stream->program->num_pck_at_pcr_init = muxer->tot_pck_sent; + + GF_LOG(GF_LOG_INFO, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Initializing PCR for program number %d: PCR %d - mux time %d:%09d\n", stream->pid, stream->program->number, stream->program->pcr_init_time, muxer->time.sec, muxer->time.nanosec)); + } else { + /*don't send until PCR is initialized*/ + return 0; + } + } + if (!stream->initial_ts) { + u32 nb_bits = (u32) (muxer->tot_pck_sent - stream->program->num_pck_at_pcr_init) * 1504; + u32 nb_ticks = 90000*nb_bits / muxer->bit_rate; + stream->initial_ts = stream->pck.dts; + if (stream->initial_ts > nb_ticks) + stream->initial_ts -= nb_ticks; + else + stream->initial_ts = 0; + } + + /*SL-encapsultaion*/ + switch (stream->mpeg2_stream_type) { + case GF_M2TS_SYSTEMS_MPEG4_SECTIONS: + /*update SL config*/ + stream->sl_header.accessUnitStartFlag = (stream->pck.flags & GF_ESI_DATA_AU_START) ? 1 : 0; + stream->sl_header.accessUnitEndFlag = (stream->pck.flags & GF_ESI_DATA_AU_END) ? 1 : 0; + stream->sl_header.accessUnitLength += stream->pck.data_len; + stream->sl_header.randomAccessPointFlag = (stream->pck.flags & GF_ESI_DATA_AU_RAP) ? 1: 0; + stream->sl_header.compositionTimeStampFlag = (stream->pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0; + stream->sl_header.compositionTimeStamp = stream->pck.cts; + stream->sl_header.decodingTimeStampFlag = (stream->pck.flags & GF_ESI_DATA_HAS_DTS) ? 1: 0; + stream->sl_header.decodingTimeStamp = stream->pck.dts; + + gf_m2ts_mux_table_update_mpeg4(stream, stream->table_id, muxer->ts_id, stream->pck.data, stream->pck.data_len, 1, 0, (stream->pck.flags & GF_ESI_DATA_REPEAT) ? 0 : 1, 0); + break; + case GF_M2TS_SYSTEMS_MPEG4_PES: + { + char *src_data; + u32 src_data_len; + + /*update SL config*/ + stream->sl_header.accessUnitStartFlag = (stream->pck.flags & GF_ESI_DATA_AU_START) ? 1 : 0; + stream->sl_header.accessUnitEndFlag = (stream->pck.flags & GF_ESI_DATA_AU_END) ? 1 : 0; + stream->sl_header.accessUnitLength += stream->pck.data_len; + stream->sl_header.randomAccessPointFlag = (stream->pck.flags & GF_ESI_DATA_AU_RAP) ? 1: 0; + stream->sl_header.compositionTimeStampFlag = (stream->pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0; + stream->sl_header.compositionTimeStamp = stream->pck.cts; + stream->sl_header.decodingTimeStampFlag = (stream->pck.flags & GF_ESI_DATA_HAS_DTS) ? 1: 0; + stream->sl_header.decodingTimeStamp = stream->pck.dts; + + src_data = stream->pck.data; + src_data_len = stream->pck.data_len; + stream->pck.data_len = 0; + stream->pck.data = NULL; + + gf_sl_packetize(&stream->sl_config, &stream->sl_header, src_data, src_data_len, &stream->pck.data, &stream->pck.data_len); + + /*discard src data*/ + if (!(stream->ifce->caps & GF_ESI_AU_PULL_CAP)) { + gf_free(src_data); + stream->pck_first->data = stream->pck.data; + stream->pck_first->data_len = stream->pck.data_len; + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Encapsulating MPEG-4 SL Data on PES - SL Header size\n", stream->pid, stream->pck.data_len - src_data_len)); + } + break; + /*perform LATM encapsulation*/ + case GF_M2TS_AUDIO_LATM_AAC: + { + u32 size; + GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + gf_bs_write_int(bs, 0x2B7, 11); + gf_bs_write_int(bs, 0, 13); + + /*same mux config = 0 (refresh aac config)*/ + next_time = gf_sys_clock(); + if (stream->ifce->decoder_config && (stream->last_aac_time + stream->ifce->repeat_rate < next_time)) { + GF_M4ADecSpecInfo cfg; + stream->last_aac_time = next_time; + + gf_bs_write_int(bs, 0, 1); + /*mux config */ + gf_bs_write_int(bs, 0, 1);/*audio mux version = 0*/ + gf_bs_write_int(bs, 1, 1);/*allStreamsSameTimeFraming*/ + gf_bs_write_int(bs, 0, 6);/*numSubFrames*/ + gf_bs_write_int(bs, 0, 4);/*numProgram*/ + gf_bs_write_int(bs, 0, 3);/*numLayer prog 1*/ + + gf_m4a_get_config(stream->ifce->decoder_config, stream->ifce->decoder_config_size, &cfg); + gf_m4a_write_config_bs(bs, &cfg); + + gf_bs_write_int(bs, 0, 3);/*frameLengthType*/ + gf_bs_write_int(bs, 0, 8);/*latmBufferFullness*/ + gf_bs_write_int(bs, 0, 1);/*other data present*/ + gf_bs_write_int(bs, 0, 1);/*crcCheckPresent*/ + } else { + gf_bs_write_int(bs, 1, 1); + } + /*write payloadLengthInfo*/ + size = stream->pck.data_len; + while (1) { + if (size>=255) { + gf_bs_write_int(bs, 255, 8); + size -= 255; + } else { + gf_bs_write_int(bs, size, 8); + break; + } + } + gf_bs_write_data(bs, stream->pck.data, stream->pck.data_len); + gf_bs_align(bs); + gf_bs_get_content(bs, &stream->pck.data, &stream->pck.data_len); + gf_bs_del(bs); + + /*rewrite LATM frame header*/ + size = stream->pck.data_len - 2; + stream->pck.data[1] |= (size>>8) & 0x1F; + stream->pck.data[2] = (size) & 0xFF; + } + break; + } + + + /*compute next interesting time in TS unit: this will be DTS of next packet*/ + next_time = (u32) (stream->pck.dts - stream->initial_ts); + /*we need to take into account transmission time, eg nb packets to send the data*/ + if (next_time) { + u32 nb_pck, bytes, nb_bits, nb_ticks; + bytes = 184 - ADAPTATION_LENGTH_LENGTH - ADAPTATION_FLAGS_LENGTH - PCR_LENGTH; + bytes -= gf_m2ts_stream_get_pes_header_length(stream); + nb_pck=1; + while (bytespck.data_len) { + bytes+=184; + nb_pck++; + } + nb_bits = nb_pck * 1504; + nb_ticks = 90000*nb_bits / muxer->bit_rate; + if (next_time>nb_ticks) + next_time -= nb_ticks; + else + next_time = 0; + } + + stream->time = stream->program->ts_time_at_pcr_init; + gf_m2ts_time_inc(&stream->time, next_time, 90000); + + /*PCR offset, in 90000 hz not in 270000000*/ + pcr_offset = stream->program->pcr_init_time/300; + stream->pck.cts = stream->pck.cts - stream->initial_ts + pcr_offset; + stream->pck.dts = stream->pck.dts - stream->initial_ts + pcr_offset; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS Muxer] PID %d: Next data schedule for %d:%09d - mux time %d:%09d\n", stream->pid, stream->time.sec, stream->time.nanosec, muxer->time.sec, muxer->time.nanosec)); + + + + + /*compute bitrate if needed*/ + if (!stream->bit_rate) { + if (!stream->last_br_time) { + stream->last_br_time = stream->pck.dts + 1; + stream->bytes_since_last_time = stream->pck.data_len; + } else { + if (stream->pck.dts - stream->last_br_time - 1 >= 90000) { + u64 r = 8*stream->bytes_since_last_time; + r*=90000; + stream->bit_rate = (u32) (r / (stream->pck.dts - stream->last_br_time - 1)); + stream->program->mux->needs_reconfig = 1; + } else { + stream->bytes_since_last_time += stream->pck.data_len; + } + } + } + return 1; +} + +static GFINLINE u64 gf_m2ts_get_pcr(GF_M2TS_Mux_Program *program) +{ + u32 nb_pck = (u32) (program->mux->tot_pck_sent - program->num_pck_at_pcr_init); + u64 pcr = 27000000; + pcr *= nb_pck*1504; + pcr /= program->mux->bit_rate; + pcr += program->pcr_init_time; + return pcr; +} + +u32 gf_m2ts_stream_add_pes_header(GF_BitStream *bs, GF_M2TS_Mux_Stream *stream) +{ + u64 t; + u32 pes_len; + Bool use_pts, use_dts; + + gf_bs_write_int(bs, 0x1, 24);//packet start code + gf_bs_write_u8(bs, stream->mpeg2_stream_id);// stream id + + use_pts = (stream->pck.flags & GF_ESI_DATA_HAS_CTS) ? 1 : 0; + use_dts = (stream->pck.flags & GF_ESI_DATA_HAS_DTS) ? 1 : 0; + + pes_len = stream->pck.data_len + 3; // 3 = header size + if (use_pts) pes_len += 5; + if (use_dts) pes_len += 5; + gf_bs_write_int(bs, pes_len, 16); // pes packet length + + 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, 0x0, 1); // copyright + gf_bs_write_int(bs, 0x0, 1); // original or copy + + gf_bs_write_int(bs, use_pts, 1); + gf_bs_write_int(bs, use_dts, 1); + gf_bs_write_int(bs, 0x0, 6); //6 flags = 0 (ESCR, ES_rate, DSM_trick, additional_copy, PES_CRC, PES_extension) + + gf_bs_write_int(bs, use_dts*5+use_pts*5, 8); + + if (use_pts) { + gf_bs_write_int(bs, use_dts ? 0x3 : 0x2, 4); // reserved '0011' || '0010' + t = ((stream->pck.cts >> 30) & 0x7); + gf_bs_write_long_int(bs, t, 3); + gf_bs_write_int(bs, 1, 1); // marker bit + t = ((stream->pck.cts >> 15) & 0x7fff); + gf_bs_write_long_int(bs, t, 15); + gf_bs_write_int(bs, 1, 1); // marker bit + t = stream->pck.cts & 0x7fff; + gf_bs_write_long_int(bs, t, 15); + gf_bs_write_int(bs, 1, 1); // marker bit + } + + if (use_dts) { + gf_bs_write_int(bs, 0x1, 4); // reserved '0001' + t = ((stream->pck.dts >> 30) & 0x7); + gf_bs_write_long_int(bs, t, 3); + gf_bs_write_int(bs, 1, 1); // marker bit + t = ((stream->pck.dts >> 15) & 0x7fff); + gf_bs_write_long_int(bs, t, 15); + gf_bs_write_int(bs, 1, 1); // marker bit + t = stream->pck.dts & 0x7fff; + 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, stream->pck.cts, use_dts, stream->pck.dts)); + + return pes_len+4; // 4 = start code + stream_id +} + +#define PCR_UPDATE_MS 200 + +void gf_m2ts_mux_pes_get_next_packet(GF_M2TS_Mux_Stream *stream, u8 *packet) +{ + GF_BitStream *bs; + Bool is_rap, needs_pcr; + u32 remain, adaptation_field_control, payload_length, padding_length, hdr_len; + u32 now = gf_sys_clock(); + + assert(stream->pid); + bs = gf_bs_new(packet, 188, GF_BITSTREAM_WRITE); + + hdr_len = gf_m2ts_stream_get_pes_header_length(stream); + remain = stream->pck.data_len - stream->pck_offset; + + needs_pcr = 0; + if (hdr_len && (stream==stream->program->pcr) ) { + if (now > stream->program->last_sys_clock + PCR_UPDATE_MS) + needs_pcr = 1; + } + adaptation_field_control = GF_M2TS_ADAPTATION_NONE; + payload_length = 184 - hdr_len; + padding_length = 0; + + if (needs_pcr) { + adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD; + /*AF headers + PCR*/ + payload_length -= 8; + } else if (remain<184) { + /*AF headers*/ + payload_length -= 2; + adaptation_field_control = GF_M2TS_ADAPTATION_AND_PAYLOAD; + } + if (remain>=payload_length) { + padding_length = 0; + } else { + padding_length = payload_length - remain; + payload_length -= padding_length; + } + + gf_bs_write_int(bs, 0x47, 8); // sync byte + gf_bs_write_int(bs, 0, 1); // error indicator + gf_bs_write_int(bs, hdr_len ? 1 : 0, 1); // start ind + gf_bs_write_int(bs, 0, 1); // transport priority + gf_bs_write_int(bs, stream->pid, 13); // pid + gf_bs_write_int(bs, 0, 2); // scrambling + gf_bs_write_int(bs, adaptation_field_control, 2); // we do not use adaptation field for sections + gf_bs_write_int(bs, stream->continuity_counter, 4); // continuity counter + if (stream->continuity_counter < 15) stream->continuity_counter++; + else stream->continuity_counter=0; + + is_rap = (hdr_len && (stream->pck.flags & GF_ESI_DATA_AU_RAP) ) ? 1 : 0; + + if (adaptation_field_control != GF_M2TS_ADAPTATION_NONE) { + u64 pcr = 0; + if (needs_pcr) { + /*compute PCR*/ + u32 now = gf_sys_clock(); + pcr = gf_m2ts_get_pcr(stream->program); + +// fprintf(stdout, "PCR Diff in ms %d - sys clock diff in ms %d\n", (u32) (pcr - stream->program->last_pcr) / 27000, now - stream->program->last_sys_clock); + + stream->program->last_pcr = pcr; + stream->program->last_sys_clock = now; + } + gf_m2ts_add_adaptation(bs, stream->pid, needs_pcr, pcr, is_rap, padding_length); + } + + if (hdr_len) gf_m2ts_stream_add_pes_header(bs, stream); + + gf_bs_del(bs); + + memcpy(packet+188-payload_length, stream->pck.data + stream->pck_offset, payload_length); + stream->pck_offset += payload_length; + + if (stream->pck_offset == stream->pck.data_len) { + GF_M2TS_Packet *pck; + /*discard first packet*/ + gf_mx_p(stream->mx); + assert(stream->pck_first); + pck = stream->pck_first; + stream->pck_first = pck->next; + gf_mx_v(stream->mx); + gf_free(pck->data); + gf_free(pck); + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Done sending PES (%d bytes) from PID %d at stream time %d:%d (DTS %d - PCR %d)\n", stream->pck.data_len, stream->pid, stream->time.sec, stream->time.nanosec, stream->pck.dts, gf_m2ts_get_pcr(stream->program)/300)); + } +} + + +GF_M2TS_Mux_Stream *gf_m2ts_stream_new(u32 pid) { + GF_M2TS_Mux_Stream *stream; + + GF_SAFEALLOC(stream, GF_M2TS_Mux_Stream); + stream->pid = pid; + stream->process = gf_m2ts_stream_process_stream; + + return stream; +} + +GF_Err gf_m2ts_output_ctrl(GF_ESInterface *_self, u32 ctrl_type, void *param) +{ + GF_ESIPacket *esi_pck; + + GF_M2TS_Mux_Stream *stream = (GF_M2TS_Mux_Stream *)_self->output_udta; + switch (ctrl_type) { + case GF_ESI_OUTPUT_DATA_DISPATCH: + esi_pck = (GF_ESIPacket *)param; + + if (stream->force_new || (esi_pck->flags & GF_ESI_DATA_AU_START)) { + if (stream->pck_reassembler) { + gf_mx_p(stream->mx); + if (!stream->pck_first) { + stream->pck_first = stream->pck_last = stream->pck_reassembler; + } else { + stream->pck_last->next = stream->pck_reassembler; + stream->pck_last = stream->pck_reassembler; + } + gf_mx_v(stream->mx); + stream->pck_reassembler = NULL; + } + } + if (!stream->pck_reassembler) { + GF_SAFEALLOC(stream->pck_reassembler, GF_M2TS_Packet); + stream->pck_reassembler->cts = esi_pck->cts; + stream->pck_reassembler->dts = esi_pck->dts; + } + + stream->force_new = esi_pck->flags & GF_ESI_DATA_AU_END ? 1 : 0; + + stream->pck_reassembler->data = gf_realloc(stream->pck_reassembler->data , sizeof(char)*(stream->pck_reassembler->data_len+esi_pck->data_len) ); + memcpy(stream->pck_reassembler->data + stream->pck_reassembler->data_len, esi_pck->data, esi_pck->data_len); + stream->pck_reassembler->data_len += esi_pck->data_len; + + stream->pck_reassembler->flags |= esi_pck->flags; + if (stream->force_new) { + gf_mx_p(stream->mx); + if (!stream->pck_first) { + stream->pck_first = stream->pck_last = stream->pck_reassembler; + } else { + stream->pck_last->next = stream->pck_reassembler; + stream->pck_last = stream->pck_reassembler; + } + gf_mx_v(stream->mx); + stream->pck_reassembler = NULL; + } + break; + } + return GF_OK; +} + +static void gf_m2ts_stream_setup_slconfig(GF_M2TS_Mux_Stream *stream) +{ + stream->sl_config.tag = GF_ODF_SLC_TAG; + stream->sl_config.useAccessUnitStartFlag = 1; + stream->sl_config.useAccessUnitEndFlag = 1; + stream->sl_config.useRandomAccessPointFlag = 1; + stream->sl_config.useTimestampsFlag = 1; +} + +GF_M2TS_Mux_Stream *gf_m2ts_program_stream_add(GF_M2TS_Mux_Program *program, struct __elementary_stream_ifce *ifce, u32 pid, Bool is_pcr) +{ + GF_M2TS_Mux_Stream *stream, *st; + + stream = gf_m2ts_stream_new(pid); + stream->ifce = ifce; + stream->pid = pid; + stream->program = program; + if (is_pcr) program->pcr = stream; + if (program->streams) { + st = program->streams; + while (st->next) st = st->next; + st->next = stream; + } else { + program->streams = stream; + } + if (program->pmt) program->pmt->table_needs_update = 1; + stream->bit_rate = ifce->bit_rate; + + switch (ifce->stream_type) { + case GF_STREAM_VISUAL: + /*just pick first valid stream_id in visual range*/ + stream->mpeg2_stream_id = 0xE0; + switch (ifce->object_type_indication) { + case GPAC_OTI_VIDEO_MPEG4_PART2: + stream->mpeg2_stream_type = GF_M2TS_VIDEO_MPEG4; + break; + case GPAC_OTI_VIDEO_AVC: + stream->mpeg2_stream_type = GF_M2TS_VIDEO_H264; + break; + case GPAC_OTI_VIDEO_MPEG1: + stream->mpeg2_stream_type = GF_M2TS_VIDEO_MPEG1; + break; + case GPAC_OTI_VIDEO_MPEG2_SIMPLE: + case GPAC_OTI_VIDEO_MPEG2_MAIN: + case GPAC_OTI_VIDEO_MPEG2_SNR: + case GPAC_OTI_VIDEO_MPEG2_SPATIAL: + case GPAC_OTI_VIDEO_MPEG2_HIGH: + case GPAC_OTI_VIDEO_MPEG2_422: + stream->mpeg2_stream_type = GF_M2TS_VIDEO_MPEG2; + break; + /*JPEG/PNG carried in MPEG-4 PES*/ + case GPAC_OTI_IMAGE_JPEG: + case GPAC_OTI_IMAGE_PNG: + stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES; + stream->mpeg2_stream_id = 0xFA; + gf_m2ts_stream_setup_slconfig(stream); + break; + default: + break; + } + break; + case GF_STREAM_AUDIO: + switch (ifce->object_type_indication) { + case GPAC_OTI_AUDIO_MPEG1: + stream->mpeg2_stream_type = GF_M2TS_AUDIO_MPEG1; + break; + case GPAC_OTI_AUDIO_MPEG2_PART3: + stream->mpeg2_stream_type = GF_M2TS_AUDIO_MPEG2; + break; + case GPAC_OTI_AUDIO_AAC_MPEG4: + stream->mpeg2_stream_type = GF_M2TS_AUDIO_LATM_AAC; + if (!ifce->repeat_rate) ifce->repeat_rate = 500; + break; + } + /*just pick first valid stream_id in audio range*/ + stream->mpeg2_stream_id = 0xC0; + break; + case GF_STREAM_SCENE: + case GF_STREAM_OD: + stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_SECTIONS; + stream->mpeg2_stream_id = 0xFA; + stream->table_id = (ifce->stream_type==GF_STREAM_OD) ? GF_M2TS_TABLE_ID_MPEG4_OD : GF_M2TS_TABLE_ID_MPEG4_BIFS; + gf_m2ts_stream_setup_slconfig(stream); + break; + } + + /*override signaling for all streams except BIFS/OD, to use MPEG-4 PES*/ + if (program->mux->mpeg4_signaling) { + if (stream->mpeg2_stream_type != GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { + stream->mpeg2_stream_type = GF_M2TS_SYSTEMS_MPEG4_PES; + stream->mpeg2_stream_id = 0xFA;/*ISO/IEC14496-1_SL-packetized_stream*/ + gf_m2ts_stream_setup_slconfig(stream); + } + } + + stream->ifce->output_ctrl = gf_m2ts_output_ctrl; + stream->ifce->output_udta = stream; + stream->mx = gf_mx_new("M2TS PID"); + if (ifce->timescale != 90000) stream->ts_scale = 90000.0 / ifce->timescale; + return stream; +} + +#define GF_M2TS_PSI_REFRESH_RATE 200 + +GF_M2TS_Mux_Program *gf_m2ts_mux_program_add(GF_M2TS_Mux *muxer, u32 program_number, u32 pmt_pid) +{ + GF_M2TS_Mux_Program *program; + + GF_SAFEALLOC(program, GF_M2TS_Mux_Program); + program->mux = muxer; + program->number = program_number; + if (muxer->programs) { + GF_M2TS_Mux_Program *p = muxer->programs; + while (p->next) p = p->next; + p->next = program; + } else { + muxer->programs = program; + } + program->pmt = gf_m2ts_stream_new(pmt_pid); + program->pmt->program = program; + muxer->pat->table_needs_update = 1; + program->pmt->process = gf_m2ts_stream_process_pmt; + program->pmt->refresh_rate_ms = GF_M2TS_PSI_REFRESH_RATE; + return program; +} + +GF_M2TS_Mux *gf_m2ts_mux_new(u32 mux_rate, Bool real_time) +{ + GF_BitStream *bs; + GF_M2TS_Mux *muxer; + GF_SAFEALLOC(muxer, GF_M2TS_Mux); + muxer->pat = gf_m2ts_stream_new(GF_M2TS_PID_PAT); + muxer->pat->process = gf_m2ts_stream_process_pat; + muxer->pat->refresh_rate_ms = GF_M2TS_PSI_REFRESH_RATE; + muxer->real_time = real_time; + muxer->bit_rate = mux_rate; + if (mux_rate) muxer->fixed_rate = 1; + + /*format NULL packet*/ + bs = gf_bs_new(muxer->null_pck, 188, GF_BITSTREAM_WRITE); + gf_bs_write_int(bs, 0x47, 8); + gf_bs_write_int(bs, 0, 1); + gf_bs_write_int(bs, 0, 1); + gf_bs_write_int(bs, 0, 1); + gf_bs_write_int(bs, 0x1FFF, 13); + gf_bs_write_int(bs, 0, 2); + gf_bs_write_int(bs, 1, 2); + gf_bs_write_int(bs, 0, 4); + gf_bs_del(bs); + gf_rand_init(0); + return muxer; +} + +void gf_m2ts_mux_stream_del(GF_M2TS_Mux_Stream *st) +{ + while (st->tables) { + GF_M2TS_Mux_Table *tab = st->tables->next; + while (st->tables->section) { + GF_M2TS_Mux_Section *sec = st->tables->section->next; + gf_free(st->tables->section->data); + gf_free(st->tables->section); + st->tables->section = sec; + } + gf_free(st->tables); + st->tables = tab; + } + while (st->pck_first) { + GF_M2TS_Packet *pck = st->pck_first; + st->pck_first = pck->next; + gf_free(pck->data); + gf_free(pck); + } + if (st->mx) gf_mx_del(st->mx); + gf_free(st); +} + +void gf_m2ts_mux_program_del(GF_M2TS_Mux_Program *prog) +{ + while (prog->streams) { + GF_M2TS_Mux_Stream *st = prog->streams->next; + gf_m2ts_mux_stream_del(prog->streams); + prog->streams = st; + } + gf_m2ts_mux_stream_del(prog->pmt); + gf_free(prog); +} + +void gf_m2ts_mux_del(GF_M2TS_Mux *mux) +{ + while (mux->programs) { + GF_M2TS_Mux_Program *p = mux->programs->next; + gf_m2ts_mux_program_del(mux->programs); + mux->programs = p; + } + gf_m2ts_mux_stream_del(mux->pat); + gf_free(mux); +} + +void gf_m2ts_mux_update_config(GF_M2TS_Mux *mux, Bool reset_time) +{ + GF_M2TS_Mux_Program *prog; + + if (!mux->fixed_rate) { + mux->bit_rate = 0; + + /*get PAT bitrate*/ + gf_m2ts_mux_table_update_bitrate(mux, mux->pat); + mux->bit_rate += mux->pat->bit_rate; + } + + prog = mux->programs; + while (prog) { + GF_M2TS_Mux_Stream *stream = prog->streams; + while (stream) { + /*!! WATCHOUT - this is raw bitrate without PES header overhead !!*/ + if (!mux->fixed_rate) { + mux->bit_rate += stream->bit_rate; + /*update PCR every 100ms - we need at least 8 bytes without padding*/ + if (stream == prog->pcr) mux->bit_rate += 8*8*10; + } + + /*reset mux time*/ + if (reset_time) stream->time.sec = stream->time.nanosec = 0; + stream = stream->next; + } + /*get PMT bitrate*/ + if (!mux->fixed_rate) { + gf_m2ts_mux_table_update_bitrate(mux, prog->pmt); + mux->bit_rate += prog->pmt->bit_rate; + } + prog = prog->next; + } + /*reset mux time*/ + if (reset_time) { + mux->time.sec = mux->time.nanosec = 0; + mux->init_sys_time = 0; + } +} + +u32 gf_m2ts_get_sys_clock(GF_M2TS_Mux *muxer) +{ + return gf_sys_clock() - muxer->init_sys_time; +} + +u32 gf_m2ts_get_ts_clock(GF_M2TS_Mux *muxer) +{ + u32 now, init; + init = muxer->init_ts_time.sec*1000 + muxer->init_ts_time.nanosec/1000000; + now = muxer->time.sec*1000 + muxer->time.nanosec/1000000; + return now-init; +} + + +const char *gf_m2ts_mux_process(GF_M2TS_Mux *muxer, u32 *status) +{ + GF_M2TS_Mux_Program *program; + GF_M2TS_Mux_Stream *stream, *stream_to_process; + GF_M2TS_Time time; + u32 now, nb_streams, nb_streams_done; + char *ret; + Bool res; + + nb_streams = nb_streams_done = 0; + *status = GF_M2TS_STATE_IDLE; + + now = gf_sys_clock(); + + if (muxer->real_time) { + if (!muxer->init_sys_time) { + muxer->init_sys_time = now; + muxer->init_ts_time = muxer->time; + } else { + u32 diff = now - muxer->init_sys_time; + GF_M2TS_Time now = muxer->init_ts_time; + gf_m2ts_time_inc(&now, diff, 1000); + if (gf_m2ts_time_less(&now, &muxer->time)) + return NULL; + } + } + + stream_to_process = NULL; + time = muxer->time; + + if (muxer->needs_reconfig) { + gf_m2ts_mux_update_config(muxer, 0); + muxer->needs_reconfig = 0; + } + + res = muxer->pat->process(muxer, muxer->pat); + if (res && gf_m2ts_time_less_or_equal(&muxer->pat->time, &time) ) { + time = muxer->pat->time; + stream_to_process = muxer->pat; + /*force sending the PAT regardless of other streams*/ + goto send_pck; + } + + program = muxer->programs; + while (program) { + res = program->pmt->process(muxer, program->pmt); + if (res && gf_m2ts_time_less(&program->pmt->time, &time) ) { + time = program->pmt->time; + stream_to_process = program->pmt; + /*force sending the PMT regardless of other streams*/ + goto send_pck; + } + stream = program->streams; + while (stream) { + nb_streams++; + res = stream->process(muxer, stream); + if (res) { + if (gf_m2ts_time_less(&stream->time, &time)) { + time = stream->time; + stream_to_process = stream; + } + } else { + if (stream->ifce->caps & GF_ESI_STREAM_IS_OVER) nb_streams_done ++; + } + stream = stream->next; + } + program = program->next; + } + +send_pck: + + ret = NULL; + if (!stream_to_process) { + if (nb_streams && (nb_streams==nb_streams_done)) { + *status = GF_M2TS_STATE_EOS; + } else { + *status = GF_M2TS_STATE_PADDING; + } + /* padding packets ?? */ + if (muxer->fixed_rate) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Inserting empty packet at %d:%d\n", time.sec, time.nanosec)); + ret = muxer->null_pck; + muxer->tot_pad_sent++; + } + /*we still need to increase the mux time, even though we're not fixed-rate*/ + else { + gf_m2ts_time_inc(&muxer->time, 1504/*188*8*/, muxer->bit_rate); + } + } else { + if (stream_to_process->tables) { + gf_m2ts_mux_table_get_next_packet(stream_to_process, muxer->dst_pck); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Send table from PID %d at %d:%09d - mux time %d:%09d\n", stream_to_process->pid, time.sec, time.nanosec, muxer->time.sec, muxer->time.nanosec)); + } else { + gf_m2ts_mux_pes_get_next_packet(stream_to_process, muxer->dst_pck); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG2-TS Muxer] Send PES from PID %d at %d:%09d - mux time %d:%09d\n", stream_to_process->pid, time.sec, time.nanosec, muxer->time.sec, muxer->time.nanosec)); + } + ret = muxer->dst_pck; + *status = GF_M2TS_STATE_DATA; + } + if (ret) { + muxer->tot_pck_sent++; + /*increment time*/ + gf_m2ts_time_inc(&muxer->time, 1504/*188*8*/, muxer->bit_rate); + + if (muxer->real_time) { + muxer->pck_sent_over_br_window++; + if (now - muxer->last_br_time > 500) { + u64 size = 8*188*muxer->pck_sent_over_br_window*1000; + muxer->avg_br = (u32) (size/(now - muxer->last_br_time)); + muxer->last_br_time = now; + muxer->pck_sent_over_br_window=0; + } + } + } + return ret; +} + +#endif /*GPAC_DISABLE_MPEG2TS_MUX*/ + diff --git a/src/media_tools/media_export.c b/src/media_tools/media_export.c index b34404b..e2db0ec 100644 --- a/src/media_tools/media_export.c +++ b/src/media_tools/media_export.c @@ -27,7 +27,7 @@ #include #include -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_MEDIA_EXPORT #include #include @@ -52,10 +52,12 @@ static GF_Err gf_export_message(GF_MediaExporter *dumper, GF_Err e, char *format #endif return e; } - /*that's very very crude, we only support vorbis & theora in MP4 - this will need cleanup as soon as possible*/ static GF_Err gf_dump_to_ogg(GF_MediaExporter *dumper, char *szName, u32 track) { +#ifdef GPAC_DISABLE_OGG + return GF_NOT_SUPPORTED; +#else FILE *out; ogg_stream_state os; ogg_packet op; @@ -81,7 +83,7 @@ static GF_Err gf_dump_to_ogg(GF_MediaExporter *dumper, char *szName, u32 track) bs = gf_bs_new(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, GF_BITSTREAM_READ); while (gf_bs_available(bs)) { op.bytes = gf_bs_read_u16(bs); - op.packet = (unsigned char*)malloc(sizeof(char) * op.bytes); + op.packet = (unsigned char*)gf_malloc(sizeof(char) * op.bytes); gf_bs_read_data(bs, (char*)op.packet, op.bytes); ogg_stream_packetin(&os, &op); @@ -91,7 +93,7 @@ static GF_Err gf_dump_to_ogg(GF_MediaExporter *dumper, char *szName, u32 track) fwrite(og.body, 1, og.body_len, out); op.b_o_s = 0; - if (esd->decoderConfig->objectTypeIndication==0xDF) { + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_MEDIA_THEORA) { u32 kff; GF_BitStream *vbs = gf_bs_new((char*)op.packet, op.bytes, GF_BITSTREAM_READ); gf_bs_skip_bytes(vbs, 40); @@ -107,7 +109,7 @@ static GF_Err gf_dump_to_ogg(GF_MediaExporter *dumper, char *szName, u32 track) } } } - free(op.packet); + gf_free(op.packet); op.packetno ++; } gf_bs_del(bs); @@ -168,10 +170,12 @@ static GF_Err gf_dump_to_ogg(GF_MediaExporter *dumper, char *szName, u32 track) ogg_stream_clear(&os); fclose(out); return GF_OK; +#endif } GF_Err gf_export_hint(GF_MediaExporter *dumper) { +#ifndef GPAC_DISABLE_ISOM_HINTING GF_Err e; char szName[1000], szType[5]; char *pck; @@ -194,21 +198,24 @@ GF_Err gf_export_hint(GF_MediaExporter *dumper) e = gf_isom_next_hint_packet(dumper->file, track, &pck, &size, NULL, NULL, NULL, &sn); if (e==GF_EOS) break; if (dumper->sample_num && (dumper->sample_num != sn)) { - free(pck); + gf_free(pck); break; } if (e) return gf_export_message(dumper, e, "Error fetching hint packet %d", i); sprintf(szName, "%s_pck_%04d.%s", dumper->out_name, i, gf_4cc_to_str(m_stype)); - out = fopen(szName, "wb"); + out = gf_f64_open(szName, "wb"); fwrite(pck, size, 1, out); fclose(out); - free(pck); + gf_free(pck); i++; if (count) gf_set_progress("Hint Export", sn, count); } if (count) gf_set_progress("Hint Export", count, count); return GF_OK; +#else + return GF_NOT_SUPPORTED; +#endif } static void write_jp2_file(GF_BitStream *bs, char *data, u32 data_size, char *dsi, u32 dsi_size) @@ -256,23 +263,23 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper) switch (dcfg->streamType) { case GF_STREAM_VISUAL: switch (dcfg->objectTypeIndication) { - case 0x20: + case GPAC_OTI_VIDEO_MPEG4_PART2: strcpy(szEXT, ".cmp"); gf_export_message(dumper, GF_OK, "Dumping MPEG-4 Visual sample%s", szNum); break; - case 0x21: + case GPAC_OTI_VIDEO_AVC: strcpy(szEXT, ".h264"); gf_export_message(dumper, GF_OK, "Dumping MPEG-4 AVC-H264 Visual sample%s", szNum); break; - case 0x6C: + case GPAC_OTI_IMAGE_JPEG: strcpy(szEXT, ".jpg"); gf_export_message(dumper, GF_OK, "Dumping JPEG image%s", szNum); break; - case 0x6D: + case GPAC_OTI_IMAGE_PNG: strcpy(szEXT, ".png"); gf_export_message(dumper, GF_OK, "Dumping PNG image%s", szNum); break; - case 0x6E: + case GPAC_OTI_IMAGE_JPEG_2000: strcpy(szEXT, ".jp2"); gf_export_message(dumper, GF_OK, "Dumping JPEG 2000 image%s", szNum); break; @@ -288,15 +295,15 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper) break; case GF_STREAM_AUDIO: switch (dcfg->objectTypeIndication) { - case 0x66: - case 0x67: - case 0x68: - case 0x40: + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: + case GPAC_OTI_AUDIO_AAC_MPEG4: strcpy(szEXT, ".aac"); - gf_export_message(dumper, GF_OK, "Dumping MPEG-%d AAC sample%s", (dcfg->objectTypeIndication==0x40) ? 4 : 2, szNum); + gf_export_message(dumper, GF_OK, "Dumping MPEG-%d AAC sample%s", (dcfg->objectTypeIndication==GPAC_OTI_AUDIO_AAC_MPEG4) ? 4 : 2, szNum); break; - case 0x69: - case 0x6B: + case GPAC_OTI_AUDIO_MPEG2_PART3: + case GPAC_OTI_AUDIO_MPEG1: strcpy(szEXT, ".mp3"); gf_export_message(dumper, GF_OK, "Dumping MPEG-1/2 Audio (MP3) sample%s", szNum); break; @@ -348,7 +355,7 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper) } else if (m_stype==GF_ISOM_SUBTYPE_AC3) { gf_export_message(dumper, GF_OK, "Extracting AC3 sample%s", szNum); strcpy(szEXT, ".ac3"); - } else if (m_stype==GF_ISOM_SUBTYPE_AVC_H264) { + } else if ((m_stype==GF_ISOM_SUBTYPE_AVC_H264) || (m_stype==GF_ISOM_SUBTYPE_AVC2_H264) || (m_stype==GF_ISOM_SUBTYPE_SVC_H264) ) { strcpy(szEXT, ".h264"); gf_export_message(dumper, GF_OK, "Dumping MPEG-4 AVC-H264 Visual sample%s", szNum); } else if (m_type==GF_ISOM_MEDIA_FLASH) { @@ -362,7 +369,7 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper) udesc = gf_isom_get_generic_sample_description(dumper->file, track, 1); dsi = udesc->extension_buf; dsi_size = udesc->extension_buf_size; - free(udesc); + gf_free(udesc); is_mj2k = 1; } else { strcpy(szEXT, "."); @@ -375,8 +382,8 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper) gf_export_message(dumper, GF_OK, "Extracting \'%s\' Track (type '%s') - Compressor %s sample%s", szEXT, gf_4cc_to_str(m_type), udesc ? udesc->compressor_name : "Unknown", szNum); break; } - if (udesc->extension_buf) free(udesc->extension_buf); - if (udesc) free(udesc); + if (udesc->extension_buf) gf_free(udesc->extension_buf); + if (udesc) gf_free(udesc); } if (dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_OK; @@ -384,7 +391,7 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper) 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 = fopen(szName, "wb"); + out = 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); @@ -393,7 +400,7 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper) gf_isom_sample_del(&samp); gf_bs_del(bs); fclose(out); - if (dsi) free(dsi); + if (dsi) gf_free(dsi); return GF_OK; } @@ -407,7 +414,7 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper) } else { sprintf(szName, "%s_%03d%s", dumper->out_name, i+1, szEXT); } - out = fopen(szName, "wb"); + out = 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) @@ -420,7 +427,7 @@ GF_Err gf_media_export_samples(GF_MediaExporter *dumper) fclose(out); if (dumper->flags & GF_EXPORT_DO_ABORT) break; } - if (dsi) free(dsi); + if (dsi) gf_free(dsi); return GF_OK; } @@ -551,6 +558,9 @@ static const char *QCP_SMV_GUID = "\x75\x2B\x7C\x8D\x97\xA7\x46\xED\x98\x5E\xD5\ GF_Err gf_media_export_native(GF_MediaExporter *dumper) { +#ifdef GPAC_DISABLE_AV_PARSERS + return GF_NOT_SUPPORTED; +#else GF_DecoderConfig *dcfg; GF_GenericSampleDescription *udesc; char szName[1000], szEXT[5], GUID[16]; @@ -588,31 +598,36 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) switch (dcfg->streamType) { case GF_STREAM_VISUAL: switch (dcfg->objectTypeIndication) { - case 0x20: + case GPAC_OTI_VIDEO_MPEG4_PART2: dsi = dcfg->decoderSpecificInfo->data; dcfg->decoderSpecificInfo->data = NULL; dsi_size = dcfg->decoderSpecificInfo->dataLength; strcat(szName, ".cmp"); gf_export_message(dumper, GF_OK, "Extracting MPEG-4 Visual stream to cmp"); break; - case 0x21: + case GPAC_OTI_VIDEO_AVC: avccfg = gf_isom_avc_config_get(dumper->file, track, 1); strcat(szName, ".h264"); gf_export_message(dumper, GF_OK, "Extracting MPEG-4 AVC-H264 stream to h264"); break; - case 0x6A: + case GPAC_OTI_VIDEO_MPEG1: strcat(szName, ".m1v"); gf_export_message(dumper, GF_OK, "Extracting MPEG-1 Visual stream to m1v"); break; - case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: + case GPAC_OTI_VIDEO_MPEG2_SIMPLE: + case GPAC_OTI_VIDEO_MPEG2_MAIN: + case GPAC_OTI_VIDEO_MPEG2_SNR: + case GPAC_OTI_VIDEO_MPEG2_SPATIAL: + case GPAC_OTI_VIDEO_MPEG2_HIGH: + case GPAC_OTI_VIDEO_MPEG2_422: strcat(szName, ".m2v"); gf_export_message(dumper, GF_OK, "Extracting MPEG-2 Visual stream to m2v"); break; - case 0x6C: + case GPAC_OTI_IMAGE_JPEG: strcat(szName, ".jpg"); gf_export_message(dumper, GF_OK, "Extracting JPEG image"); break; - case 0x6D: + case GPAC_OTI_IMAGE_PNG: strcat(szName, ".png"); gf_export_message(dumper, GF_OK, "Extracting PNG image"); break; @@ -628,18 +643,18 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) break; case GF_STREAM_AUDIO: switch (dcfg->objectTypeIndication) { - case 0x66: - case 0x67: - case 0x68: + case GPAC_OTI_AUDIO_AAC_MPEG2_MP: + case GPAC_OTI_AUDIO_AAC_MPEG2_LCP: + case GPAC_OTI_AUDIO_AAC_MPEG2_SSRP: dsi = dcfg->decoderSpecificInfo->data; dcfg->decoderSpecificInfo->data = NULL; dsi_size = dcfg->decoderSpecificInfo->dataLength; strcat(szName, ".aac"); is_aac = 1; - aac_type = dcfg->objectTypeIndication - 0x66; + aac_type = dcfg->objectTypeIndication - GPAC_OTI_AUDIO_AAC_MPEG2_MP; gf_export_message(dumper, GF_OK, "Extracting MPEG-2 AAC"); break; - case 0x40: + case GPAC_OTI_AUDIO_AAC_MPEG4: dsi = dcfg->decoderSpecificInfo->data; dcfg->decoderSpecificInfo->data = NULL; dsi_size = dcfg->decoderSpecificInfo->dataLength; @@ -647,8 +662,8 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) strcat(szName, ".aac"); gf_export_message(dumper, GF_OK, "Extracting MPEG-4 AAC"); break; - case 0x69: - case 0x6B: + case GPAC_OTI_AUDIO_MPEG2_PART3: + case GPAC_OTI_AUDIO_MPEG1: strcat(szName, ".mp3"); gf_export_message(dumper, GF_OK, "Extracting MPEG-1/2 Audio (MP3)"); break; @@ -657,17 +672,17 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) is_ogg = 1; gf_export_message(dumper, GF_OK, "Extracting Ogg audio"); break; - case 0xE1: + case GPAC_OTI_AUDIO_13K_VOICE: 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; - case 0xA0: + case GPAC_OTI_AUDIO_EVRC_VOICE: memcpy(GUID, QCP_EVRC_GUID, sizeof(char)*16); qcp_type = 3; if (dumper->flags & GF_EXPORT_PROBE_ONLY) dumper->flags |= GF_EXPORT_USE_QCP; break; - case 0xA1: + case GPAC_OTI_AUDIO_SMV_VOICE: qcp_type = 2; memcpy(GUID, QCP_SMV_GUID, sizeof(char)*16); if (dumper->flags & GF_EXPORT_PROBE_ONLY) dumper->flags |= GF_EXPORT_USE_QCP; @@ -689,7 +704,7 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) case GF_STREAM_ND_SUBPIC: switch (dcfg->objectTypeIndication) { - case 0xe0: + case GPAC_OTI_MEDIA_SUBPIC: is_vobsub = 1; dsi = dcfg->decoderSpecificInfo->data; dcfg->decoderSpecificInfo->data = NULL; @@ -731,7 +746,7 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) 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) { + } 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"); gf_export_message(dumper, GF_OK, "Extracting MPEG-4 AVC-H264 stream to h264"); @@ -756,11 +771,11 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) gf_export_message(dumper, GF_OK, "Extracting \'%s\' Track (type '%s') - Compressor %s", szEXT, gf_4cc_to_str(m_type), udesc ? udesc->compressor_name : "Unknown"); break; } - if (udesc) free(udesc); + if (udesc) gf_free(udesc); } } if (dumper->flags & GF_EXPORT_PROBE_ONLY) { - if (dsi) free(dsi); + if (dsi) gf_free(dsi); if (avccfg) gf_odf_avc_cfg_del(avccfg); return GF_OK; } @@ -786,10 +801,10 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) out = gf_f64_open(dumper->out_name, "a+b"); if (out) gf_f64_seek(out, 0, SEEK_END); } else { - out = fopen(szName, "wb"); + out = gf_f64_open(szName, "wb"); } if (!out) { - if (dsi) free(dsi); + if (dsi) gf_free(dsi); if (avccfg) gf_odf_avc_cfg_del(avccfg); return gf_export_message(dumper, GF_IO_ERR, "Error opening %s for writing - check disk access & permissions", szName); } @@ -798,12 +813,12 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) if (is_aac) { gf_m4a_get_config(dsi, dsi_size, &a_cfg); if (is_aac==2) aac_type = a_cfg.base_object_type - 1; - free(dsi); + gf_free(dsi); dsi = NULL; } if (dsi) { gf_bs_write_data(bs, dsi, dsi_size); - free(dsi); + gf_free(dsi); } if (avccfg) { count = gf_list_count(avccfg->sequenceParameterSets); @@ -844,7 +859,7 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) agg_samp = 1; if (gpc) { agg_samp = gpc->frames_per_sample; - free(gpc); + gf_free(gpc); } if (qcp_type==1) { @@ -936,6 +951,7 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) remain = samp->dataLength; while (remain) { nal_size = 0; + assert(remain>avccfg->nal_unit_size); for (j=0; jnal_unit_size; j++) { nal_size |= ((u8) *ptr); if (j+1nal_unit_size) nal_size<<=8; @@ -984,9 +1000,11 @@ GF_Err gf_media_export_native(GF_MediaExporter *dumper) gf_bs_del(bs); fclose(out); return GF_OK; +#endif /*GPAC_DISABLE_AV_PARSERS*/ } -GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper) +#ifndef GPAC_DISABLE_AVILIB +static GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper) { GF_Err e; u32 max_size, tot_size, num_samples, i; @@ -1023,7 +1041,7 @@ 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 = fopen(szOutFile, "wb"); + fout = gf_f64_open(szOutFile, "wb"); max_size = 0; frame = NULL; @@ -1035,14 +1053,14 @@ GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper) continue; } if ((u32) size > max_size) { - frame = (char*)realloc(frame, sizeof(char) * size); + frame = (char*)gf_realloc(frame, sizeof(char) * size); max_size = size; } AVI_read_frame(in, frame, (int*)&key); if ((u32) size>4) fwrite(frame, 1, size, fout); gf_set_progress("AVI Extract", i+1, num_samples); } - free(frame); + gf_free(frame); fclose(fout); fout = NULL; goto exit; @@ -1054,7 +1072,7 @@ GF_Err gf_media_export_avi_track(GF_MediaExporter *dumper) tot_size += size; i++; } - frame = (char*)malloc(sizeof(char) * max_size); + frame = (char*)gf_malloc(sizeof(char) * max_size); AVI_seek_start(in); AVI_set_audio_position(in, 0); @@ -1078,7 +1096,7 @@ 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 = fopen(szOutFile, "wb"); + fout = gf_f64_open(szOutFile, "wb"); num_samples = 0; while (1) { Bool continuous; @@ -1096,6 +1114,7 @@ exit: AVI_close(in); return e; } +#endif /*GPAC_DISABLE_AVILIB*/ GF_Err gf_media_export_nhnt(GF_MediaExporter *dumper) { @@ -1123,7 +1142,7 @@ GF_Err gf_media_export_nhnt(GF_MediaExporter *dumper) } sprintf(szName, "%s.nhnt", dumper->out_name); - out_nhnt = fopen(szName, "wb"); + out_nhnt = gf_f64_open(szName, "wb"); if (!out_nhnt) { fclose(out_med); gf_odf_desc_del((GF_Descriptor *) esd); @@ -1135,7 +1154,7 @@ GF_Err gf_media_export_nhnt(GF_MediaExporter *dumper) if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { sprintf(szName, "%s.info", dumper->out_name); - out_inf = fopen(szName, "wb"); + out_inf = gf_f64_open(szName, "wb"); if (out_inf) fwrite(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, 1, out_inf); fclose(out_inf); } @@ -1204,6 +1223,7 @@ GF_Err gf_media_export_nhnt(GF_MediaExporter *dumper) return GF_OK; } +#ifndef GPAC_DISABLE_ISOM_WRITE static GF_Err MP4T_CopyTrack(GF_MediaExporter *dumper, GF_ISOFile *infile, u32 inTrackNum, GF_ISOFile *outfile, Bool ResetDependancies, Bool AddToIOD) { GF_ESD *esd; @@ -1241,16 +1261,18 @@ static GF_Err MP4T_CopyTrack(GF_MediaExporter *dumper, GF_ISOFile *infile, u32 i if ((esd->decoderConfig->streamType == GF_STREAM_VISUAL) || (esd->decoderConfig->streamType == GF_STREAM_SCENE)) { u32 w, h; gf_isom_get_visual_info(infile, inTrackNum, 1, &w, &h); +#ifndef GPAC_DISABLE_AV_PARSERS /*this is because so many files have reserved values of 320x240 from v1 ... */ - if ((esd->decoderConfig->objectTypeIndication == 0x20) ) { + if ((esd->decoderConfig->objectTypeIndication == GPAC_OTI_VIDEO_MPEG4_PART2) ) { GF_M4VDecSpecInfo dsi; gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); w = dsi.width; h = dsi.height; } +#endif gf_isom_set_visual_info(outfile, newTk, 1, w, h); } - else if ((esd->decoderConfig->streamType == GF_STREAM_ND_SUBPIC) && (esd->decoderConfig->objectTypeIndication == 0xe0)) { + else if ((esd->decoderConfig->streamType == GF_STREAM_ND_SUBPIC) && (esd->decoderConfig->objectTypeIndication == GPAC_OTI_MEDIA_SUBPIC)) { u32 w, h; s32 trans_x, trans_y; s16 layer; @@ -1287,7 +1309,7 @@ static GF_Err MP4T_CopyTrack(GF_MediaExporter *dumper, GF_ISOFile *infile, u32 i if (msubtype == GF_ISOM_SUBTYPE_MPEG4_CRYP) { esd = gf_isom_get_esd(infile, inTrackNum, 1); - } else if (msubtype == GF_ISOM_SUBTYPE_AVC_H264) { + } else if ((msubtype == GF_ISOM_SUBTYPE_AVC_H264) || (msubtype == GF_ISOM_SUBTYPE_AVC2_H264) ) { return gf_isom_set_pl_indication(outfile, GF_ISOM_PL_VISUAL, 0x0F); } /*likely 3gp or any non-MPEG-4 isomedia file*/ @@ -1306,7 +1328,7 @@ static GF_Err MP4T_CopyTrack(GF_MediaExporter *dumper, GF_ISOFile *infile, u32 i if (iod && (iod->tag==GF_ODF_IOD_TAG)) { gf_isom_set_pl_indication(outfile, GF_ISOM_PL_SCENE, iod->scene_profileAndLevel); gf_isom_set_pl_indication(outfile, GF_ISOM_PL_GRAPHICS, iod->graphics_profileAndLevel); - } else if (esd->decoderConfig->objectTypeIndication==0x20) { + } else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { gf_export_message(dumper, GF_OK, "Warning: Scene PLs not found in original MP4 - defaulting to No Profile Specified"); gf_isom_set_pl_indication(outfile, GF_ISOM_PL_SCENE, 0xFE); gf_isom_set_pl_indication(outfile, GF_ISOM_PL_GRAPHICS, 0xFE); @@ -1315,11 +1337,15 @@ static GF_Err MP4T_CopyTrack(GF_MediaExporter *dumper, GF_ISOFile *infile, u32 i case GF_STREAM_VISUAL: if (iod && (iod->tag==GF_ODF_IOD_TAG)) { gf_isom_set_pl_indication(outfile, GF_ISOM_PL_VISUAL, iod->visual_profileAndLevel); - } else if (esd->decoderConfig->objectTypeIndication==0x20) { + } +#ifndef GPAC_DISABLE_AV_PARSERS + else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { GF_M4VDecSpecInfo dsi; gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); gf_isom_set_pl_indication(outfile, GF_ISOM_PL_VISUAL, dsi.VideoPL); - } else { + } +#endif + else { gf_export_message(dumper, GF_OK, "Warning: Visual PLs not found in original MP4 - defaulting to No Profile Specified"); gf_isom_set_pl_indication(outfile, GF_ISOM_PL_VISUAL, 0xFE); } @@ -1327,11 +1353,15 @@ static GF_Err MP4T_CopyTrack(GF_MediaExporter *dumper, GF_ISOFile *infile, u32 i case GF_STREAM_AUDIO: if (iod && (iod->tag==GF_ODF_IOD_TAG)) { gf_isom_set_pl_indication(outfile, GF_ISOM_PL_AUDIO, iod->audio_profileAndLevel); - } else if (esd->decoderConfig->objectTypeIndication==0x40) { + } +#ifndef GPAC_DISABLE_AV_PARSERS + else if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_AUDIO_AAC_MPEG4) { GF_M4ADecSpecInfo cfg; gf_m4a_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &cfg); gf_isom_set_pl_indication(outfile, GF_ISOM_PL_AUDIO, cfg.audioPL); - } else { + } +#endif + else { gf_export_message(dumper, GF_OK, "Warning: Audio PLs not found in original MP4 - defaulting to No Profile Specified"); gf_isom_set_pl_indication(outfile, GF_ISOM_PL_AUDIO, 0xFE); } @@ -1346,6 +1376,7 @@ static GF_Err MP4T_CopyTrack(GF_MediaExporter *dumper, GF_ISOFile *infile, u32 i return GF_OK; } + GF_Err gf_media_export_isom(GF_MediaExporter *dumper) { GF_ISOFile *outfile; @@ -1371,7 +1402,7 @@ GF_Err gf_media_export_isom(GF_MediaExporter *dumper) add_to_iod = 1; mode = GF_ISOM_WRITE_EDIT; if (dumper->flags & GF_EXPORT_MERGE) { - FILE *t = fopen(szName, "rb"); + FILE *t = gf_f64_open(szName, "rb"); if (t) { add_to_iod = 0; mode = GF_ISOM_OPEN_EDIT; @@ -1401,6 +1432,11 @@ GF_Err gf_media_export_isom(GF_MediaExporter *dumper) return e; } +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + + + +#ifndef GPAC_DISABLE_AVILIB GF_Err gf_media_export_avi(GF_MediaExporter *dumper) { @@ -1418,7 +1454,7 @@ GF_Err gf_media_export_avi(GF_MediaExporter *dumper) if (!esd) return gf_export_message(dumper, GF_NON_COMPLIANT_BITSTREAM, "Invalid MPEG-4 stream in track ID %d", dumper->trackID); if ((esd->decoderConfig->streamType!=GF_STREAM_VISUAL) || - ( (esd->decoderConfig->objectTypeIndication!=0x20) && (esd->decoderConfig->objectTypeIndication!=0x21)) ) { + ( (esd->decoderConfig->objectTypeIndication!=GPAC_OTI_VIDEO_MPEG4_PART2) && (esd->decoderConfig->objectTypeIndication!=GPAC_OTI_VIDEO_AVC)) ) { gf_odf_desc_del((GF_Descriptor*)esd); return gf_export_message(dumper, GF_NON_COMPLIANT_BITSTREAM, "Track ID %d is not MPEG-4 Visual - cannot extract to AVI", dumper->trackID); } @@ -1445,7 +1481,7 @@ GF_Err gf_media_export_avi(GF_MediaExporter *dumper) frame_d = 0; /*AVC - FIXME dump format is probably wrong...*/ - if (esd->decoderConfig->objectTypeIndication==0x21) { + if (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_AVC) { gf_isom_get_visual_info(dumper->file, track, 1, &w, &h); v4CC = "h264"; } @@ -1489,12 +1525,12 @@ GF_Err gf_media_export_avi(GF_MediaExporter *dumper) if (!samp) break; /*add DSI before each I-frame in MPEG-4 SP*/ - if (samp->IsRAP && (esd->decoderConfig->objectTypeIndication==0x20)) { - char *data = (char*) malloc(sizeof(char) * (samp->dataLength + esd->decoderConfig->decoderSpecificInfo->dataLength)); + if (samp->IsRAP && (esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2)) { + char *data = (char*) gf_malloc(sizeof(char) * (samp->dataLength + esd->decoderConfig->decoderSpecificInfo->dataLength)); memcpy(data, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); memcpy(data + esd->decoderConfig->decoderSpecificInfo->dataLength, samp->data, samp->dataLength); AVI_write_frame(avi_out, data, samp->dataLength + esd->decoderConfig->decoderSpecificInfo->dataLength, 1); - free(data); + gf_free(data); } else { AVI_write_frame(avi_out, samp->data, samp->dataLength, samp->IsRAP); } @@ -1511,6 +1547,8 @@ GF_Err gf_media_export_avi(GF_MediaExporter *dumper) AVI_close(avi_out); return GF_OK; } +#endif /*GPAC_DISABLE_AVILIB*/ + GF_Err gf_media_export_nhml(GF_MediaExporter *dumper, Bool dims_doc) { @@ -1549,7 +1587,7 @@ GF_Err gf_media_export_nhml(GF_MediaExporter *dumper, Bool dims_doc) szRootName = "NHNTStream"; szSampleName = "NHNTSample"; } - nhml = fopen(szName, "wt"); + nhml = gf_f64_open(szName, "wt"); if (!nhml) { fclose(med); if (esd) gf_odf_desc_del((GF_Descriptor *) esd); @@ -1565,7 +1603,7 @@ GF_Err gf_media_export_nhml(GF_MediaExporter *dumper, Bool dims_doc) fprintf(nhml, "streamType=\"%d\" objectTypeIndication=\"%d\" ", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); if (esd->decoderConfig->decoderSpecificInfo && esd->decoderConfig->decoderSpecificInfo->data) { sprintf(szName, "%s.info", dumper->out_name); - inf = fopen(szName, "wb"); + inf = gf_f64_open(szName, "wb"); if (inf) fwrite(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, 1, inf); fclose(inf); fprintf(nhml, "specificInfoFile=\"%s\" ", szName); @@ -1598,13 +1636,13 @@ GF_Err gf_media_export_nhml(GF_MediaExporter *dumper, Bool dims_doc) } if (sdesc->extension_buf) { sprintf(szName, "%s.info", dumper->out_name); - inf = fopen(szName, "wb"); + inf = gf_f64_open(szName, "wb"); if (inf) fwrite(sdesc->extension_buf, sdesc->extension_buf_size, 1, inf); fclose(inf); fprintf(nhml, "specificInfoFile=\"%s\" ", szName); - free(sdesc->extension_buf); + gf_free(sdesc->extension_buf); } - free(sdesc); + gf_free(sdesc); } } @@ -1651,7 +1689,7 @@ GF_Err gf_media_export_nhml(GF_MediaExporter *dumper, Bool dims_doc) GF_BitStream *bs = gf_bs_new(samp->data, samp->dataLength, GF_BITSTREAM_READ); while (gf_bs_available(bs)) { - u32 pos = (u32) gf_bs_get_position(bs); + u64 pos = gf_bs_get_position(bs); u16 size = gf_bs_read_u16(bs); u8 flags = gf_bs_read_u8(bs); u8 prev; @@ -1691,7 +1729,7 @@ GF_Err gf_media_export_nhml(GF_MediaExporter *dumper, Bool dims_doc) err = inflate(&d_stream, Z_NO_FLUSH); if (err < Z_OK) break; svg_data[d_stream.total_out - done] = 0; - fprintf(nhml, svg_data); + fprintf(nhml, "%s", svg_data); if (err== Z_STREAM_END) break; done = d_stream.total_out; d_stream.avail_out = 2048; @@ -1806,7 +1844,7 @@ GF_Err gf_media_export_saf(GF_MediaExporter *dumper) strcpy(out_file, dumper->out_name); strcat(out_file, ".saf"); - saf_f = fopen(out_file, "wb"); + saf_f = gf_f64_open(out_file, "wb"); samp_done = 0; while (samp_donefile, safs[i].track_num, safs[i].last_sample + 1, &di); gf_saf_mux_add_au(mux, safs[i].stream_id, (u32) (samp->DTS+samp->CTS_Offset), samp->data, samp->dataLength, samp->IsRAP); /*data is kept by muxer!!*/ - free(samp); + gf_free(samp); safs[i].last_sample++; samp_done ++; } @@ -1824,7 +1862,7 @@ GF_Err gf_media_export_saf(GF_MediaExporter *dumper) gf_saf_mux_for_time(mux, (u32) -1, 0, &data, &size); if (!data) break; fwrite(data, size, 1, saf_f); - free(data); + gf_free(data); } gf_set_progress("SAF Export", samp_done, tot_samp); if (dumper->flags & GF_EXPORT_DO_ABORT) break; @@ -1832,7 +1870,7 @@ GF_Err gf_media_export_saf(GF_MediaExporter *dumper) gf_saf_mux_for_time(mux, (u32) -1, 1, &data, &size); if (data) { fwrite(data, size, 1, saf_f); - free(data); + gf_free(data); } fclose(saf_f); @@ -1840,6 +1878,8 @@ GF_Err gf_media_export_saf(GF_MediaExporter *dumper) return GF_OK; } +#ifndef GPAC_DISABLE_MPEG2TS + void m2ts_export_check(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) { if (evt_type == GF_M2TS_EVT_PAT_REPEAT) ts->user = NULL; @@ -1862,18 +1902,19 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper) { char data[188], szFile[GF_MAX_PATH]; GF_M2TS_PES *stream; - u32 i, size, fsize, fdone; + u32 i; + u64 size, fsize, fdone; GF_M2TS_Demuxer *ts; FILE *src, *dst; if (dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_OK; - src = fopen(dumper->in_name, "rb"); + src = gf_f64_open(dumper->in_name, "rb"); if (!src) return gf_export_message(dumper, GF_CODEC_NOT_FOUND, "Error opening %s", dumper->in_name); - fseek(src, 0, SEEK_END); - fsize = ftell(src); - fseek(src, 0, SEEK_SET); + gf_f64_seek(src, 0, SEEK_END); + fsize = gf_f64_tell(src); + gf_f64_seek(src, 0, SEEK_SET); ts = gf_m2ts_demux_new(); ts->on_event = m2ts_export_check; @@ -1882,7 +1923,8 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper) while (!feof(src)) { size = fread(data, 1, 188, src); if (size<188) break; - gf_m2ts_process_data(ts, data, size); + assert(size == 188); + gf_m2ts_process_data(ts, data, (u32)size); if (!ts->user) break; } if (ts->user) { @@ -1897,7 +1939,7 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper) if (!pes || (pes->pid==pes->program->pmt_pid)) continue; if (pes->pid == dumper->trackID) { stream = pes; - gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_RAW); + gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_DEFAULT); break; } else { gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_SKIP); @@ -1945,7 +1987,7 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper) gf_export_message(dumper, GF_OK, "Extracting Unknown stream to raw"); break; } - dst = fopen(szFile, "wb"); + dst = gf_f64_open(szFile, "wb"); if (!dst) { fclose(src); gf_m2ts_demux_del(ts); @@ -1959,7 +2001,8 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper) while (!feof(src)) { size = fread(data, 1, 188, src); if (size<188) break; - gf_m2ts_process_data(ts, data, size); + assert(size == 188); + gf_m2ts_process_data(ts, data, (u32)size); fdone += size; gf_set_progress("MPEG-2 TS Extract", fdone, fsize); if (dumper->flags & GF_EXPORT_DO_ABORT) break; @@ -1971,6 +2014,8 @@ GF_Err gf_media_export_ts_native(GF_MediaExporter *dumper) return GF_OK; } +#endif /*GPAC_DISABLE_MPEG2TS*/ + GF_EXPORT GF_Err gf_media_export(GF_MediaExporter *dumper) { @@ -1978,23 +2023,30 @@ GF_Err gf_media_export(GF_MediaExporter *dumper) if (!dumper->out_name && !dumper->flags & GF_EXPORT_PROBE_ONLY) return GF_BAD_PARAM; if (dumper->flags & GF_EXPORT_NATIVE) { +#ifndef GPAC_DISABLE_MPEG2TS if (dumper->in_name) { char *ext = strrchr(dumper->in_name, '.'); if (ext && (!strnicmp(ext, ".ts", 3) || !strnicmp(ext, ".m2t", 4)) ) { return gf_media_export_ts_native(dumper); } } +#endif /*GPAC_DISABLE_MPEG2TS*/ return gf_media_export_native(dumper); } else if (dumper->flags & GF_EXPORT_RAW_SAMPLES) return gf_media_export_samples(dumper); else if (dumper->flags & GF_EXPORT_NHNT) return gf_media_export_nhnt(dumper); - else if (dumper->flags & GF_EXPORT_AVI) return gf_media_export_avi(dumper); +#ifndef GPAC_DISABLE_ISOM_WRITE else if (dumper->flags & GF_EXPORT_MP4) return gf_media_export_isom(dumper); +#endif /*GPAC_DISABLE_ISOM_WRITE*/ + +#ifndef GPAC_DISABLE_AVILIB + else if (dumper->flags & GF_EXPORT_AVI) return gf_media_export_avi(dumper); else if (dumper->flags & GF_EXPORT_AVI_NATIVE) return gf_media_export_avi_track(dumper); +#endif /*GPAC_DISABLE_AVILIB*/ else if (dumper->flags & GF_EXPORT_NHML) return gf_media_export_nhml(dumper, 0); else if (dumper->flags & GF_EXPORT_SAF) return gf_media_export_saf(dumper); - else return GF_BAD_PARAM; + else return GF_NOT_SUPPORTED; } -#endif +#endif /*GPAC_DISABLE_MEDIA_EXPORT*/ diff --git a/src/media_tools/media_import.c b/src/media_tools/media_import.c index 2d1bc93..0ae54ea 100644 --- a/src/media_tools/media_import.c +++ b/src/media_tools/media_import.c @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -34,7 +34,7 @@ /*since 0.2.2, we use zlib for xmt/x3d reading to handle gz files*/ #include -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_MEDIA_IMPORT #define GF_IMPORT_DEFAULT_FPS 25.0 @@ -54,8 +54,10 @@ GF_Err gf_import_message(GF_MediaImporter *import, GF_Err e, char *format, ...) return e; } + static GF_Err gf_media_update_par(GF_ISOFile *file, u32 track) { +#ifndef GPAC_DISABLE_AV_PARSERS u32 tk_w, tk_h, stype; GF_Err e; @@ -63,7 +65,7 @@ static GF_Err gf_media_update_par(GF_ISOFile *file, u32 track) if (e) return e; stype = gf_isom_get_media_subtype(file, track, 1); - if (stype==GF_ISOM_SUBTYPE_AVC_H264) { + if ((stype==GF_ISOM_SUBTYPE_AVC_H264) || (stype==GF_ISOM_SUBTYPE_AVC2_H264) ) { s32 par_n, par_d; GF_AVCConfig *avcc = gf_isom_avc_config_get(file, track, 1); GF_AVCConfigSlot *slc = (GF_AVCConfigSlot *)gf_list_get(avcc->sequenceParameterSets, 0); @@ -71,29 +73,34 @@ static GF_Err gf_media_update_par(GF_ISOFile *file, u32 track) if (slc) gf_avc_get_sps_info(slc->data, slc->size, NULL, NULL, &par_n, &par_d); gf_odf_avc_cfg_del(avcc); - if ((par_n>1) && (par_d>1)) + if ((par_n>1) && (par_d>1)) tk_w = tk_w * par_n / par_d; - } + } else if ((stype==GF_ISOM_SUBTYPE_MPEG4) || (stype==GF_ISOM_SUBTYPE_MPEG4_CRYP) ) { GF_M4VDecSpecInfo dsi; GF_ESD *esd = gf_isom_get_esd(file, track, 1); - if (!esd || !esd->decoderConfig || (esd->decoderConfig->streamType!=4) || (esd->decoderConfig->objectTypeIndication!=0x20)) { + if (!esd || !esd->decoderConfig || (esd->decoderConfig->streamType!=4) || (esd->decoderConfig->objectTypeIndication!=GPAC_OTI_VIDEO_MPEG4_PART2)) { if (esd) gf_odf_desc_del((GF_Descriptor *) esd); return GF_NOT_SUPPORTED; } gf_m4v_get_config(esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); if (esd) gf_odf_desc_del((GF_Descriptor *) esd); - if ((dsi.par_num>1) && (dsi.par_num>1)) + if ((dsi.par_num>1) && (dsi.par_num>1)) tk_w = dsi.width * dsi.par_num / dsi.par_den; } else { return GF_OK; } return gf_isom_set_track_layout_info(file, track, tk_w<<16, tk_h<<16, 0, 0, 0); +#else + return GF_OK; +#endif /*GPAC_DISABLE_AV_PARSERS*/ } + static void MP4T_RecomputeBitRate(GF_ISOFile *file, u32 track) { +#ifndef GPAC_DISABLE_ISOM_WRITE u32 i, count, timescale; u64 time_wnd, rate, max_rate, avg_rate; Double br; @@ -110,7 +117,7 @@ static void MP4T_RecomputeBitRate(GF_ISOFile *file, u32 track) count = gf_isom_get_sample_count(file, track); for (i=0; idataLength>esd->decoderConfig->bufferSizeDB) esd->decoderConfig->bufferSizeDB = samp->dataLength; if (esd->decoderConfig->bufferSizeDB < samp->dataLength) esd->decoderConfig->bufferSizeDB = samp->dataLength; @@ -124,7 +131,7 @@ static void MP4T_RecomputeBitRate(GF_ISOFile *file, u32 track) gf_isom_sample_del(&samp); } - + br = (Double) (s64) gf_isom_get_media_duration(file, track); br /= timescale; esd->decoderConfig->avgBitrate = (u32) ((Double) (s64)avg_rate / br); @@ -134,6 +141,7 @@ static void MP4T_RecomputeBitRate(GF_ISOFile *file, u32 track) gf_isom_change_mpeg4_description(file, track, 1, esd); gf_odf_desc_del((GF_Descriptor *)esd); +#endif } static void get_video_timing(Double fps, u32 *timescale, u32 *dts_inc) @@ -159,7 +167,7 @@ static void get_video_timing(Double fps, u32 *timescale, u32 *dts_inc) -static GF_Err gf_import_still_image(GF_MediaImporter *import) +static GF_Err gf_import_still_image(GF_MediaImporter *import, Bool mult_desc_allowed) { GF_BitStream *bs; GF_Err e; @@ -171,14 +179,14 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import) FILE *src; - src = fopen(import->in_name, "rb"); + src = gf_f64_open(import->in_name, "rb"); if (!src) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name); - fseek(src, 0, SEEK_END); - size = ftell(src); - fseek(src, 0, SEEK_SET); - data = (char*)malloc(sizeof(char)*size); - fread(data, sizeof(char)*size, 1, src); + gf_f64_seek(src, 0, SEEK_END); + size = (u32) gf_f64_tell(src); + gf_f64_seek(src, 0, SEEK_SET); + data = (char*)gf_malloc(sizeof(char)*size); + size = fread(data, sizeof(char), size, src); fclose(src); /*get image size*/ @@ -187,14 +195,14 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import) gf_bs_del(bs); if (!OTI) { - free(data); + gf_free(data); return gf_import_message(import, GF_NOT_SUPPORTED, "Unrecognized file %s", import->in_name); } if (!w || !h) { - free(data); - if (dsi) free(dsi); - return gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Invalid %s file", (OTI==0x6C) ? "JPEG" : (OTI==0x6D) ? "PNG" : "JPEG2000"); + gf_free(data); + if (dsi) gf_free(dsi); + return gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Invalid %s file", (OTI==GPAC_OTI_IMAGE_JPEG) ? "JPEG" : (OTI==GPAC_OTI_IMAGE_PNG) ? "PNG" : "JPEG2000"); } @@ -206,7 +214,7 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import) import->tk_info[0].video_info.width = w; import->tk_info[0].video_info.height = h; import->nb_tracks = 1; - if (dsi) free(dsi); + if (dsi) gf_free(dsi); return GF_OK; } @@ -228,12 +236,17 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import) if (dsi) { if (!import->esd->decoderConfig->decoderSpecificInfo) import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - if (import->esd->decoderConfig->decoderSpecificInfo->data) free(import->esd->decoderConfig->decoderSpecificInfo->data); + if (import->esd->decoderConfig->decoderSpecificInfo->data) gf_free(import->esd->decoderConfig->decoderSpecificInfo->data); import->esd->decoderConfig->decoderSpecificInfo->data = dsi; import->esd->decoderConfig->decoderSpecificInfo->dataLength = dsi_len; } - - track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_VISUAL, 1000); + + + track = 0; + if (mult_desc_allowed) + track = gf_isom_get_track_by_id(import->dest, import->esd->ESID); + if (!track) + track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_VISUAL, 1000); if (!track) { e = gf_isom_last_error(import->dest); goto exit; @@ -248,8 +261,15 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import) samp = gf_isom_sample_new(); samp->IsRAP = 1; samp->dataLength = size; + if (import->initial_time_offset) samp->DTS = (u64) (import->initial_time_offset*1000); - gf_import_message(import, GF_OK, "%s import - size %d x %d", (OTI==0x6C) ? "JPEG" : (OTI==0x6D) ? "PNG" : "JPEG2000", w, h); + gf_import_message(import, GF_OK, "%s import %s - size %d x %d", (OTI==GPAC_OTI_IMAGE_JPEG) ? "JPEG" : (OTI==GPAC_OTI_IMAGE_PNG) ? "PNG" : "JPEG2000", import->in_name, w, h); + + /*we must start a track from DTS = 0*/ + if (!gf_isom_get_sample_count(import->dest, track) && samp->DTS) { + /*todo - we could add an edit list*/ + samp->DTS=0; + } gf_set_progress("Importing Image", 0, 1); if (import->flags & GF_IMPORT_USE_DATAREF) { @@ -264,7 +284,7 @@ static GF_Err gf_import_still_image(GF_MediaImporter *import) gf_isom_sample_del(&samp); exit: - free(data); + gf_free(data); if (import->esd && destroy_esd) { gf_odf_desc_del((GF_Descriptor *) import->esd); import->esd = NULL; @@ -272,6 +292,7 @@ exit: return e; } +#ifndef GPAC_DISABLE_AV_PARSERS GF_Err gf_import_mp3(GF_MediaImporter *import) { @@ -281,7 +302,8 @@ GF_Err gf_import_mp3(GF_MediaImporter *import) u16 sr; u32 nb_chan; FILE *in; - u32 hdr, size, max_size, track, di, tot_size, done, offset, duration; + u32 hdr, size, max_size, track, di, duration; + u64 done, tot_size, offset; GF_ISOSample *samp; in = gf_f64_open(import->in_name, "rb"); @@ -327,7 +349,7 @@ GF_Err gf_import_mp3(GF_MediaImporter *import) samp = NULL; nb_chan = gf_mp3_num_channels(hdr); - gf_import_message(import, GF_OK, "MP3 import - sample rate %d - %s audio - %d channel%s", sr, (oti==0x6B) ? "MPEG-1" : "MPEG-2", nb_chan, (nb_chan>1) ? "s" : ""); + gf_import_message(import, GF_OK, "MP3 import - sample rate %d - %s audio - %d channel%s", sr, (oti==GPAC_OTI_AUDIO_MPEG1) ? "MPEG-1" : "MPEG-2", nb_chan, (nb_chan>1) ? "s" : ""); track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_AUDIO, sr); if (!track) { @@ -342,9 +364,9 @@ GF_Err gf_import_mp3(GF_MediaImporter *import) gf_isom_new_mpeg4_description(import->dest, track, import->esd, (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); - fseek(in, 0, SEEK_END); - tot_size = ftell(in); - fseek(in, 0, SEEK_SET); + gf_f64_seek(in, 0, SEEK_END); + tot_size = gf_f64_tell(in); + gf_f64_seek(in, 0, SEEK_SET); e = GF_OK; samp = gf_isom_sample_new(); @@ -361,11 +383,11 @@ GF_Err gf_import_mp3(GF_MediaImporter *import) /*MP3 stream truncated*/ if (!hdr) break; - offset = ftell(in) - 4; + offset = gf_f64_tell(in) - 4; size = gf_mp3_frame_size(hdr); assert(size); if (size>max_size) { - samp->data = (char*)realloc(samp->data, sizeof(char) * size); + samp->data = (char*)gf_realloc(samp->data, sizeof(char) * size); max_size = size; } samp->data[0] = (hdr >> 24) & 0xFF; @@ -404,6 +426,10 @@ exit: return e; } +#endif /*GPAC_DISABLE_AV_PARSERS*/ + +#ifndef GPAC_DISABLE_AV_PARSERS + typedef struct { Bool is_mp2, no_crc; @@ -412,7 +438,8 @@ typedef struct static Bool ADTS_SyncFrame(GF_BitStream *bs, ADTSHeader *hdr) { - u32 val, hdr_size, pos; + u32 val, hdr_size; + u64 pos; while (gf_bs_available(bs)) { val = gf_bs_read_u8(bs); if (val!=0xFF) continue; @@ -424,7 +451,7 @@ static Bool ADTS_SyncFrame(GF_BitStream *bs, ADTSHeader *hdr) hdr->is_mp2 = gf_bs_read_int(bs, 1); gf_bs_read_int(bs, 2); hdr->no_crc = gf_bs_read_int(bs, 1); - pos = (u32) gf_bs_get_position(bs) - 2; + pos = gf_bs_get_position(bs) - 2; hdr->profile = 1 + gf_bs_read_int(bs, 2); hdr->sr_idx = gf_bs_read_int(bs, 4); @@ -468,12 +495,13 @@ GF_Err gf_import_aac_adts(GF_MediaImporter *import) GF_Err e; Bool sync_frame; u16 sr, sbr_sr, sbr_sr_idx, dts_inc; + u32 timescale; GF_BitStream *bs, *dsi; ADTSHeader hdr; GF_M4ADecSpecInfo acfg; FILE *in; - u64 offset; - u32 max_size, track, di, tot_size, done, duration, prof, i; + u64 offset, tot_size, done; + u32 max_size, track, di, duration, prof, i; GF_ISOSample *samp; in = gf_f64_open(import->in_name, "rb"); @@ -490,13 +518,13 @@ GF_Err gf_import_aac_adts(GF_MediaImporter *import) if (import->flags & GF_IMPORT_FORCE_MPEG4) hdr.is_mp2 = 0; /*keep MPEG-2 AAC OTI even for HE-SBR (that's correct according to latest MPEG-4 audio spec)*/ - oti = hdr.is_mp2 ? hdr.profile+0x66-1 : 0x40; - sr = GF_M4ASampleRates[hdr.sr_idx]; + oti = hdr.is_mp2 ? hdr.profile+GPAC_OTI_AUDIO_AAC_MPEG2_MP-1 : GPAC_OTI_AUDIO_AAC_MPEG4; + timescale = sr = GF_M4ASampleRates[hdr.sr_idx]; if (import->flags & GF_IMPORT_PROBE_ONLY) { import->tk_info[0].track_num = 1; import->tk_info[0].type = GF_ISOM_MEDIA_AUDIO; - import->tk_info[0].flags = GF_IMPORT_USE_DATAREF | GF_IMPORT_SBR_IMPLICIT | GF_IMPORT_SBR_EXPLICIT | GF_IMPORT_FORCE_MPEG4; + import->tk_info[0].flags = GF_IMPORT_USE_DATAREF | GF_IMPORT_SBR_IMPLICIT | GF_IMPORT_SBR_EXPLICIT | GF_IMPORT_PS_IMPLICIT | GF_IMPORT_PS_EXPLICIT | GF_IMPORT_FORCE_MPEG4; import->nb_tracks = 1; import->tk_info[0].audio_info.sample_rate = sr; import->tk_info[0].audio_info.nb_channels = hdr.nb_ch; @@ -509,19 +537,35 @@ GF_Err gf_import_aac_adts(GF_MediaImporter *import) sbr_sr = sr; sbr_sr_idx = hdr.sr_idx; - for (i=0; i<16; i++) { - if (GF_M4ASampleRates[i] == (u32) 2*sr) { - sbr_sr_idx = i; - sbr_sr = 2*sr; - break; + if ((import->flags & GF_IMPORT_OVSBR) == 0) { + for (i=0; i<16; i++) { + if (GF_M4ASampleRates[i] == (u32) 2*sr) { + sbr_sr_idx = i; + sbr_sr = 2*sr; + break; + } } } + + if (import->flags & GF_IMPORT_OVSBR) + timescale = 2*sr; + + if (import->flags & GF_IMPORT_PS_EXPLICIT) { + import->flags &= ~GF_IMPORT_PS_IMPLICIT; + import->flags |= GF_IMPORT_SBR_EXPLICIT; + import->flags &= ~GF_IMPORT_SBR_IMPLICIT; + } + /*no provision for explicit indication of MPEG-2 AAC through MPEG-4 PLs, so force implicit*/ if (hdr.is_mp2) { if (import->flags & GF_IMPORT_SBR_EXPLICIT) { import->flags &= ~GF_IMPORT_SBR_EXPLICIT; import->flags |= GF_IMPORT_SBR_IMPLICIT; } + if (import->flags & GF_IMPORT_PS_EXPLICIT) { + import->flags &= ~GF_IMPORT_PS_EXPLICIT; + import->flags |= GF_IMPORT_PS_IMPLICIT; + } } dts_inc = 1024; @@ -542,9 +586,24 @@ GF_Err gf_import_aac_adts(GF_MediaImporter *import) } else if (import->flags & GF_IMPORT_SBR_IMPLICIT) { acfg.has_sbr = 1; } + if (import->flags & GF_IMPORT_PS_EXPLICIT) { + acfg.has_ps = 1; + acfg.base_object_type = 29; + } else if (import->flags & GF_IMPORT_PS_IMPLICIT) { + acfg.has_ps = 1; + } + acfg.audioPL = gf_m4a_get_profile(&acfg); + /*explicit SBR or PS signal (non backward-compatible)*/ + if (import->flags & GF_IMPORT_PS_EXPLICIT) { + gf_bs_write_int(dsi, 29, 5); + gf_bs_write_int(dsi, hdr.sr_idx, 4); + gf_bs_write_int(dsi, hdr.nb_ch, 4); + gf_bs_write_int(dsi, sbr_sr ? sbr_sr_idx : hdr.sr_idx, 4); + gf_bs_write_int(dsi, hdr.profile, 5); + } /*explicit SBR signal (non backward-compatible)*/ - if (import->flags & GF_IMPORT_SBR_EXPLICIT) { + else if (import->flags & GF_IMPORT_SBR_EXPLICIT) { gf_bs_write_int(dsi, 5, 5); gf_bs_write_int(dsi, hdr.sr_idx, 4); gf_bs_write_int(dsi, hdr.nb_ch, 4); @@ -563,6 +622,10 @@ GF_Err gf_import_aac_adts(GF_MediaImporter *import) gf_bs_write_int(dsi, 1, 1); /*SBR present flag*/ gf_bs_write_int(dsi, sbr_sr_idx, 4); } + if (import->flags & GF_IMPORT_PS_IMPLICIT) { + gf_bs_write_int(dsi, 0x548, 11); /*sync extension type*/ + gf_bs_write_int(dsi, 1, 1); /* PS present flag */ + } } /*not MPEG4 tool*/ if (0 && hdr.is_mp2) acfg.audioPL = 0xFE; @@ -581,16 +644,23 @@ GF_Err gf_import_aac_adts(GF_MediaImporter *import) import->esd->decoderConfig->streamType = GF_STREAM_AUDIO; import->esd->decoderConfig->objectTypeIndication = oti; import->esd->decoderConfig->bufferSizeDB = 20; - import->esd->slConfig->timestampResolution = sr; + import->esd->slConfig->timestampResolution = timescale; if (!import->esd->decoderConfig->decoderSpecificInfo) import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - if (import->esd->decoderConfig->decoderSpecificInfo->data) free(import->esd->decoderConfig->decoderSpecificInfo->data); + if (import->esd->decoderConfig->decoderSpecificInfo->data) gf_free(import->esd->decoderConfig->decoderSpecificInfo->data); gf_bs_get_content(dsi, &import->esd->decoderConfig->decoderSpecificInfo->data, &import->esd->decoderConfig->decoderSpecificInfo->dataLength); gf_bs_del(dsi); samp = NULL; - gf_import_message(import, GF_OK, "AAC import %s- sample rate %d - %s audio - %d channel%s", (import->flags & GF_IMPORT_SBR_IMPLICIT) ? "SBR (implicit) " : ((import->flags & GF_IMPORT_SBR_EXPLICIT) ? "SBR (explicit) " : ""), sr, (oti==0x40) ? "MPEG-4" : "MPEG-2", hdr.nb_ch, (hdr.nb_ch>1) ? "s" : ""); - - track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_AUDIO, sr); + gf_import_message(import, GF_OK, "AAC import %s%s%s- sample rate %d - %s audio - %d channel%s", + (import->flags & (GF_IMPORT_SBR_IMPLICIT|GF_IMPORT_SBR_EXPLICIT)) ? "SBR" : "", + (import->flags & (GF_IMPORT_PS_IMPLICIT|GF_IMPORT_PS_EXPLICIT)) ? "+PS" : "", + ((import->flags & (GF_IMPORT_SBR_EXPLICIT|GF_IMPORT_PS_EXPLICIT)) ? " (explicit) " : " "), + sr, + (oti==0x40) ? "MPEG-4" : "MPEG-2", + hdr.nb_ch, + (hdr.nb_ch>1) ? "s" : ""); + + track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_AUDIO, timescale); if (!track) { e = gf_isom_last_error(import->dest); goto exit; @@ -599,14 +669,14 @@ GF_Err gf_import_aac_adts(GF_MediaImporter *import) if (!import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track); import->final_trackID = import->esd->ESID; gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di); - gf_isom_set_audio_info(import->dest, track, di, sr, (hdr.nb_ch>2) ? 2 : hdr.nb_ch, 16); + gf_isom_set_audio_info(import->dest, track, di, timescale, (hdr.nb_ch>2) ? 2 : hdr.nb_ch, 16); e = GF_OK; /*add first sample*/ samp = gf_isom_sample_new(); samp->IsRAP = 1; max_size = samp->dataLength = hdr.frame_size; - samp->data = (char*)malloc(sizeof(char)*hdr.frame_size); + samp->data = (char*)gf_malloc(sizeof(char)*hdr.frame_size); offset = gf_bs_get_position(bs); gf_bs_read_data(bs, samp->data, hdr.frame_size); @@ -621,13 +691,13 @@ GF_Err gf_import_aac_adts(GF_MediaImporter *import) duration = import->duration*sr; duration /= 1000; - tot_size = (u32) gf_bs_get_size(bs); + tot_size = gf_bs_get_size(bs); done = 0; while (gf_bs_available(bs) ) { sync_frame = ADTS_SyncFrame(bs, &hdr); if (!sync_frame) break; if (hdr.frame_size>max_size) { - samp->data = (char*)realloc(samp->data, sizeof(char) * hdr.frame_size); + samp->data = (char*)gf_realloc(samp->data, sizeof(char) * hdr.frame_size); max_size = hdr.frame_size; } samp->dataLength = hdr.frame_size; @@ -662,19 +732,23 @@ exit: return e; } +#endif /*GPAC_DISABLE_AV_PARSERS*/ + + +#ifndef GPAC_DISABLE_AV_PARSERS + static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) { GF_Err e; Double FPS; FILE *mdia; GF_ISOSample *samp; - u32 nb_samp, i, timescale, max_size, samp_offset, track, di, PL, max_b, nbI, nbP, nbB, nbNotCoded, tot_size, done_size, dts_inc, ref_frame, b_frames; Bool is_vfr, enable_vfr, erase_pl, has_cts_offset, is_packed, destroy_esd, do_vfr, forced_packed; + u32 nb_samp, i, timescale, max_size, track, di, PL, max_b, nbI, nbP, nbB, nbNotCoded, dts_inc, ref_frame, b_frames, duration; + u64 pos, tot_size, done_size, samp_offset; GF_M4VDecSpecInfo dsi; GF_M4VParser *vparse; GF_BitStream *bs; - u64 pos; - u32 duration; destroy_esd = forced_packed = 0; mdia = gf_f64_open(import->in_name, "rb"); @@ -689,7 +763,7 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) goto exit; } - tot_size = (u32) gf_bs_get_size(bs); + tot_size = gf_bs_get_size(bs); done_size = 0; destroy_esd = 0; FPS = mpeg12 ? dsi.fps : GF_IMPORT_DEFAULT_FPS; @@ -705,7 +779,7 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) if (import->flags & GF_IMPORT_PROBE_ONLY) { import->tk_info[0].track_num = 1; import->tk_info[0].type = GF_ISOM_MEDIA_VISUAL; - import->tk_info[0].media_type = mpeg12 ? ((dsi.VideoPL==0x6A) ? GF_4CC('M','P','G','1') : GF_4CC('M','P','G','2') ) : GF_4CC('M','P','4','V') ; + import->tk_info[0].media_type = mpeg12 ? ((dsi.VideoPL==GPAC_OTI_VIDEO_MPEG1) ? GF_4CC('M','P','G','1') : GF_4CC('M','P','G','2') ) : GF_4CC('M','P','4','V') ; import->tk_info[0].flags = GF_IMPORT_USE_DATAREF | GF_IMPORT_OVERRIDE_FPS; if (!mpeg12) import->tk_info[0].flags |= GF_IMPORT_NO_FRAME_DROP | GF_IMPORT_FORCE_PACKED; import->tk_info[0].video_info.width = dsi.width; @@ -717,7 +791,7 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) samp = gf_isom_sample_new(); max_size = 4096; - samp->data = (char*)malloc(sizeof(char)*max_size); + samp->data = (char*)gf_malloc(sizeof(char)*max_size); /*no auto frame-rate detection*/ if (import->video_fps == 10000.0) import->video_fps = 25.0; @@ -751,14 +825,16 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) if (mpeg12) { import->esd->decoderConfig->objectTypeIndication = dsi.VideoPL; } else { - import->esd->decoderConfig->objectTypeIndication = 0x20; + import->esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_MPEG4_PART2; } if (samp_offset) { - import->esd->decoderConfig->decoderSpecificInfo->data = (char*)malloc(sizeof(char) * samp_offset); - import->esd->decoderConfig->decoderSpecificInfo->dataLength = samp_offset; + import->esd->decoderConfig->decoderSpecificInfo->data = (char*)gf_malloc(sizeof(char) * (size_t)samp_offset); + assert(samp_offset < 1<<31); + import->esd->decoderConfig->decoderSpecificInfo->dataLength = (u32) samp_offset; pos = gf_bs_get_position(bs); gf_bs_seek(bs, 0); - gf_bs_read_data(bs, import->esd->decoderConfig->decoderSpecificInfo->data, samp_offset); + assert(samp_offset < 1<<31); + gf_bs_read_data(bs, import->esd->decoderConfig->decoderSpecificInfo->data, (u32)samp_offset); gf_bs_seek(bs, pos); /*remove packed flag if any (VOSH user data)*/ @@ -790,7 +866,7 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) if (e) goto exit; gf_isom_set_visual_info(import->dest, track, di, dsi.width, dsi.height); if (mpeg12) { - gf_import_message(import, GF_OK, "MPEG-%d Video import - %d x %d @ %02.4f FPS", (dsi.VideoPL==0x6A) ? 1 : 2, dsi.width, dsi.height, FPS); + gf_import_message(import, GF_OK, "MPEG-%d Video import - %d x %d @ %02.4f FPS", (dsi.VideoPL==GPAC_OTI_VIDEO_MPEG1) ? 1 : 2, dsi.width, dsi.height, FPS); } else { gf_import_message(import, GF_OK, "MPEG-4 Video import - %d x %d @ %02.4f FPS\nIndicated Profile: %s", dsi.width, dsi.height, FPS, gf_m4v_get_profile_name((u8) PL)); } @@ -803,10 +879,13 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) while (gf_bs_available(bs)) { u8 ftype; - u32 tinc, frame_start; + u32 tinc; + u64 frame_start, sample_size; Bool is_coded; pos = gf_m4v_get_object_start(vparse); - e = gf_m4v_parse_frame(vparse, dsi, &ftype, &tinc, &samp->dataLength, &frame_start, &is_coded); + e = gf_m4v_parse_frame(vparse, dsi, &ftype, &tinc, &sample_size, &frame_start, &is_coded); + assert(sample_size < 1<<31); + samp->dataLength = (u32) sample_size; if (e==GF_EOS) e = GF_OK; if (e) goto exit; @@ -824,7 +903,7 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) continue; } /*policy is to keep non coded frame (constant frame rate), add*/ - } + } samp->IsRAP = 0; if (ftype==2) { @@ -846,7 +925,7 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) nbP++; } /*even if no out-of-order frames we MUST adjust CTS if cts_offset is present is */ - if (ref_frame && has_cts_offset) + if (ref_frame && has_cts_offset) gf_isom_modify_cts_offset(import->dest, track, ref_frame, (1+b_frames)*dts_inc); ref_frame = nb_samp+1; @@ -861,7 +940,7 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) } else { if (samp->dataLength>max_size) { max_size = samp->dataLength; - samp->data = (char*)realloc(samp->data, sizeof(char)*max_size); + samp->data = (char*)gf_realloc(samp->data, sizeof(char)*max_size); } gf_bs_seek(bs, frame_start); gf_bs_read_data(bs, samp->data, samp->dataLength); @@ -877,14 +956,14 @@ static GF_Err gf_import_cmp(GF_MediaImporter *import, Bool mpeg12) } /*final flush*/ - if (ref_frame && has_cts_offset) + if (ref_frame && has_cts_offset) gf_isom_modify_cts_offset(import->dest, track, ref_frame, (1+b_frames)*dts_inc); gf_set_progress("Importing M4V", nb_samp, nb_samp); if (has_cts_offset) { gf_import_message(import, GF_OK, "Has B-Frames (%d max consecutive B-VOPs)", max_b); gf_isom_set_cts_packing(import->dest, track, 0); - /*this is plain ugly but since some encoders (divx) don't use the video PL correctly + /*this is plain ugly but since some encoders (divx) don't use the video PL correctly we force the system video_pl to ASP@L5 since we have I, P, B in base layer*/ if (PL<=3) { PL = 0xF5; @@ -929,13 +1008,19 @@ exit: return e; } -GF_Err gf_import_avi_video(GF_MediaImporter *import) +#endif /*GPAC_DISABLE_AV_PARSERS*/ + + +#ifndef GPAC_DISABLE_AVILIB + +static GF_Err gf_import_avi_video(GF_MediaImporter *import) { GF_Err e; Double FPS; FILE *test; GF_ISOSample *samp; - u32 i, num_samples, timescale, size, max_size, samp_offset, track, di, PL, max_b, nb_f, ref_frame, b_frames; + u32 i, num_samples, timescale, track, di, PL, max_b, nb_f, ref_frame, b_frames; + u64 samp_offset, size, max_size; u32 nbI, nbP, nbB, nbDummy, nbNotCoded, dts_inc, cur_samp; Bool is_vfr, enable_vfr, erase_pl; GF_M4VDecSpecInfo dsi; @@ -948,7 +1033,7 @@ GF_Err gf_import_avi_video(GF_MediaImporter *import) if (import->trackID>1) return GF_OK; - test = fopen(import->in_name, "rb"); + 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); in = AVI_open_input_file(import->in_name, 1); @@ -1052,7 +1137,7 @@ GF_Err gf_import_avi_video(GF_MediaImporter *import) } if (size > max_size) { - frame = (char*)realloc(frame, sizeof(char) * size); + frame = (char*)gf_realloc(frame, sizeof(char) * (size_t)size); max_size = size; } AVI_read_frame(in, frame, &key); @@ -1068,6 +1153,7 @@ GF_Err gf_import_avi_video(GF_MediaImporter *import) erase_pl = 1; } samp_offset = gf_m4v_get_object_start(vparse); + assert(samp_offset < 1<<31); gf_m4v_parser_del(vparse); if (e) { gf_import_message(import, e, "Cannot import decoder config in first frame"); @@ -1086,7 +1172,7 @@ GF_Err gf_import_avi_video(GF_MediaImporter *import) gf_isom_set_track_enabled(import->dest, track, 1); if (!import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, track); import->final_trackID = gf_isom_get_track_id(import->dest, track); - + if (!import->esd->slConfig) import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); import->esd->slConfig->timestampResolution = timescale; @@ -1094,10 +1180,10 @@ GF_Err gf_import_avi_video(GF_MediaImporter *import) if (import->esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) import->esd->decoderConfig->decoderSpecificInfo); import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); import->esd->decoderConfig->streamType = GF_STREAM_VISUAL; - import->esd->decoderConfig->objectTypeIndication = 0x20; - import->esd->decoderConfig->decoderSpecificInfo->data = (char *) malloc(sizeof(char) * samp_offset); - memcpy(import->esd->decoderConfig->decoderSpecificInfo->data, frame, sizeof(char) * samp_offset); - import->esd->decoderConfig->decoderSpecificInfo->dataLength = samp_offset; + import->esd->decoderConfig->objectTypeIndication = GPAC_OTI_VIDEO_MPEG4_PART2; + import->esd->decoderConfig->decoderSpecificInfo->data = (char *) gf_malloc(sizeof(char) * (size_t)samp_offset); + memcpy(import->esd->decoderConfig->decoderSpecificInfo->data, frame, sizeof(char) * (size_t)samp_offset); + import->esd->decoderConfig->decoderSpecificInfo->dataLength = (u32) samp_offset; gf_isom_set_cts_packing(import->dest, track, 1); @@ -1117,7 +1203,7 @@ GF_Err gf_import_avi_video(GF_MediaImporter *import) break; } i = 0; - + e = gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name: NULL, NULL, &di); if (e) goto exit; gf_isom_set_visual_info(import->dest, track, di, dsi.width, dsi.height); @@ -1129,7 +1215,8 @@ GF_Err gf_import_avi_video(GF_MediaImporter *import) if (size > samp_offset) { u8 ftype; - u32 tinc, framesize, frame_start; + u32 tinc; + u64 framesize, frame_start; u64 file_offset; Bool is_coded; @@ -1188,7 +1275,7 @@ proceed: nbP++; } /*even if no out-of-order frames we MUST adjust CTS if cts_offset is present is */ - if (ref_frame && has_cts_offset) + if (ref_frame && has_cts_offset) gf_isom_modify_cts_offset(import->dest, track, ref_frame, (1+b_frames)*dts_inc); ref_frame = cur_samp+1; @@ -1197,7 +1284,8 @@ proceed: } /*frame_start indicates start of VOP (eg we always remove VOL from each I)*/ samp->data = frame + samp_offset + frame_start; - samp->dataLength = framesize; + assert(framesize < 1<<31); + samp->dataLength = (u32) framesize; if (import->flags & GF_IMPORT_USE_DATAREF) { samp->data = NULL; @@ -1220,12 +1308,12 @@ proceed: samp_offset = 0; gf_set_progress("Importing AVI Video", i, num_samples); if (duration && (samp->DTS > duration)) break; - if (import->flags & GF_IMPORT_DO_ABORT) + if (import->flags & GF_IMPORT_DO_ABORT) break; } /*final flush*/ - if (ref_frame && has_cts_offset) + if (ref_frame && has_cts_offset) gf_isom_modify_cts_offset(import->dest, track, ref_frame, (1+b_frames)*dts_inc); gf_set_progress("Importing AVI Video", num_samples, num_samples); @@ -1236,7 +1324,7 @@ proceed: gf_import_message(import, GF_OK, "Has B-Frames (%d max consecutive B-VOPs%s)", max_b, is_packed ? " - packed bitstream" : ""); /*repack CTS tables and adjust offsets for B-frames*/ gf_isom_set_cts_packing(import->dest, track, 0); - /*this is plain ugly but since some encoders (divx) don't use the video PL correctly + /*this is plain ugly but since some encoders (divx) don't use the video PL correctly we force the system video_pl to ASP@L5 since we have I, P, B in base layer*/ if (PL<=3) { PL = 0xF5; @@ -1280,15 +1368,11 @@ exit: gf_odf_desc_del((GF_Descriptor *) import->esd); import->esd = NULL; } - if (frame) free(frame); + if (frame) gf_free(frame); AVI_close(in); return e; } - - - -/*credits to CISCO MPEG4/IP for MP3 parsing*/ GF_Err gf_import_avi_audio(GF_MediaImporter *import) { GF_Err e; @@ -1312,7 +1396,7 @@ GF_Err gf_import_avi_audio(GF_MediaImporter *import) /*video only, ignore*/ if (import->trackID==1) return GF_OK; - test = fopen(import->in_name, "rb"); + 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); in = AVI_open_input_file(import->in_name, 1); @@ -1340,7 +1424,7 @@ GF_Err gf_import_avi_audio(GF_MediaImporter *import) AVI_close(in); return gf_import_message(import, GF_NOT_SUPPORTED, "Error: invalid MPEG Audio track"); } - + frame = NULL; destroy_esd = 0; if (!import->esd) { @@ -1363,7 +1447,7 @@ GF_Err gf_import_avi_audio(GF_MediaImporter *import) e = gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di); if (e) goto exit; - gf_import_message(import, GF_OK, "AVI Audio import - sample rate %d - %s audio - %d channel%s", sampleRate, (oti==0x6B) ? "MPEG-1" : "MPEG-2", gf_mp3_num_channels(hdr), (gf_mp3_num_channels(hdr)>1) ? "s" : ""); + gf_import_message(import, GF_OK, "AVI Audio import - sample rate %d - %s audio - %d channel%s", sampleRate, (oti==GPAC_OTI_AUDIO_MPEG1) ? "MPEG-1" : "MPEG-2", gf_mp3_num_channels(hdr), (gf_mp3_num_channels(hdr)>1) ? "s" : ""); AVI_seek_start(in); AVI_set_audio_position(in, 0); @@ -1376,7 +1460,7 @@ GF_Err gf_import_avi_audio(GF_MediaImporter *import) i++; } - frame = (char*)malloc(sizeof(char) * max_size); + frame = (char*)gf_malloc(sizeof(char) * max_size); AVI_seek_start(in); AVI_set_audio_position(in, 0); @@ -1395,7 +1479,7 @@ GF_Err gf_import_avi_audio(GF_MediaImporter *import) size = gf_mp3_frame_size(hdr); if (size>max_size) { - frame = (char*)realloc(frame, sizeof(char) * size); + frame = (char*)gf_realloc(frame, sizeof(char) * size); if (max_size) is_cbr = 0; max_size = size; } @@ -1423,7 +1507,7 @@ GF_Err gf_import_avi_audio(GF_MediaImporter *import) if (duration && (samp->DTS > duration) ) break; if (import->flags & GF_IMPORT_DO_ABORT) break; } - + gf_set_progress("Importing AVI Audio", tot_size, tot_size); gf_import_message(import, GF_OK, "Import done - %s bit rate MP3 detected", is_cbr ? "constant" : "variable"); @@ -1434,16 +1518,18 @@ GF_Err gf_import_avi_audio(GF_MediaImporter *import) gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_AUDIO, 0xFE); - + exit: if (import->esd && destroy_esd) { gf_odf_desc_del((GF_Descriptor *) import->esd); import->esd = NULL; } - if (frame) free(frame); + if (frame) gf_free(frame); AVI_close(in); return e; } +#endif /*GPAC_DISABLE_AVILIB*/ + GF_Err gf_import_isomedia(GF_MediaImporter *import) { @@ -1455,7 +1541,7 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) u8 bps; char lang[4]; const char *url, *urn; - Bool sbr, is_clone; + Bool sbr, ps, is_clone; GF_ISOSample *samp; GF_ESD *origin_esd; GF_InitialObjectDescriptor *iod; @@ -1493,6 +1579,7 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) origin_esd->OCRESID = import->esd->OCRESID; /*there may be other things to import...*/ } + ps = 0; sbr = 0; sbr_sr = 0; iod = (GF_InitialObjectDescriptor *) gf_isom_get_root_od(import->orig); @@ -1505,14 +1592,16 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) u8 PL = iod ? iod->visual_profileAndLevel : 0xFE; w = h = 0; gf_isom_get_visual_info(import->orig, track_in, 1, &w, &h); +#ifndef GPAC_DISABLE_AV_PARSERS /*for MPEG-4 visual, always check size (don't trust input file)*/ - if (origin_esd && (origin_esd->decoderConfig->objectTypeIndication==0x20)) { + if (origin_esd && (origin_esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2)) { GF_M4VDecSpecInfo dsi; gf_m4v_get_config(origin_esd->decoderConfig->decoderSpecificInfo->data, origin_esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); w = dsi.width; h = dsi.height; PL = dsi.VideoPL; } +#endif gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_VISUAL, PL); } else if (mtype==GF_ISOM_MEDIA_AUDIO) { @@ -1520,33 +1609,37 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) bps = 16; sr = ch = sbr_sr = 0; sbr = 0; + ps = 0; gf_isom_get_audio_info(import->orig, track_in, 1, &sr, &ch, &bps); - if (origin_esd && (origin_esd->decoderConfig->objectTypeIndication==0x40)) { +#ifndef GPAC_DISABLE_AV_PARSERS + if (origin_esd && (origin_esd->decoderConfig->objectTypeIndication==GPAC_OTI_AUDIO_AAC_MPEG4)) { GF_M4ADecSpecInfo dsi; gf_m4a_get_config(origin_esd->decoderConfig->decoderSpecificInfo->data, origin_esd->decoderConfig->decoderSpecificInfo->dataLength, &dsi); sr = dsi.base_sr; if (dsi.has_sbr) sbr_sr = dsi.sbr_sr; ch = dsi.nb_chan; PL = dsi.audioPL; - sbr = dsi.has_sbr ? ((dsi.base_object_type==GF_M4A_AAC_SBR) ? 2 : 1) : 0; + sbr = dsi.has_sbr ? ((dsi.base_object_type==GF_M4A_AAC_SBR || dsi.base_object_type==GF_M4A_AAC_PS) ? 2 : 1) : 0; + ps = dsi.has_ps; } +#endif gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_AUDIO, PL); - } + } else if (mtype==GF_ISOM_MEDIA_SUBPIC) { w = h = 0; trans_x = trans_y = 0; layer = 0; - if (origin_esd && origin_esd->decoderConfig->objectTypeIndication == 0xe0) { + if (origin_esd && origin_esd->decoderConfig->objectTypeIndication == GPAC_OTI_MEDIA_SUBPIC) { gf_isom_get_track_layout_info(import->orig, track_in, &w, &h, &trans_x, &trans_y, &layer); } } gf_odf_desc_del((GF_Descriptor *) iod); - - /*check if MPEG-4 or not*/ + + /*check if MPEG-4 or not - if crypted use clone track */ is_clone = 0; stype = gf_isom_get_media_subtype(import->orig, track_in, 1); - if ((stype==GF_ISOM_SUBTYPE_MPEG4) || (stype==GF_ISOM_SUBTYPE_MPEG4_CRYP)) { + if ((stype==GF_ISOM_SUBTYPE_MPEG4) /*|| (stype==GF_ISOM_SUBTYPE_MPEG4_CRYP)*/) { track = gf_isom_new_track(import->dest, import->esd ? import->esd->ESID : 0, gf_isom_get_media_type(import->orig, track_in), gf_isom_get_media_timescale(import->orig, track_in)); if (!track) { e = gf_isom_last_error(import->dest); @@ -1577,6 +1670,8 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) case GF_ISOM_SUBTYPE_MPEG4: case GF_ISOM_SUBTYPE_MPEG4_CRYP: case GF_ISOM_SUBTYPE_AVC_H264: + case GF_ISOM_SUBTYPE_AVC2_H264: + case GF_ISOM_SUBTYPE_SVC_H264: case GF_ISOM_SUBTYPE_3GP_H263: case GF_ISOM_SUBTYPE_3GP_AMR: case GF_ISOM_SUBTYPE_3GP_AMR_WB: @@ -1588,6 +1683,7 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) switch (mtype) { case GF_ISOM_MEDIA_HINT: case GF_ISOM_MEDIA_TEXT: + case GF_ISOM_MEDIA_SUBT: break; default: return gf_import_message(import, GF_OK, "IsoMedia import - skipping track ID %d (unknown type \'%s\')", trackID, gf_4cc_to_str(mstype)); @@ -1599,6 +1695,11 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) is_clone = 1; di = 1; if (e) goto exit; + + if (import->esd && import->esd->ESID) { + e = gf_isom_set_track_id(import->dest, track, import->esd->ESID); + if (e) goto exit; + } } if (e) goto exit; import->final_trackID = gf_isom_get_track_id(import->dest, track); @@ -1614,7 +1715,9 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) case GF_ISOM_MEDIA_AUDIO: { if (!is_clone) gf_isom_set_audio_info(import->dest, track, di, (sbr==2) ? sbr_sr : sr, (ch>1) ? 2 : 1, bps); - if (sbr) { + if (ps) { + gf_import_message(import, GF_OK, "IsoMedia import - track ID %d - HE-AACv2 (SR %d - SBR-SR %d - %d channels)", trackID, sr, sbr_sr, ch); + } else if (sbr) { gf_import_message(import, GF_OK, "IsoMedia import - track ID %d - HE-AAC (SR %d - SBR-SR %d - %d channels)", trackID, sr, sbr_sr, ch); } else { gf_import_message(import, GF_OK, "IsoMedia import - track ID %d - Audio (SR %d - %d channels)", trackID, sr, ch); @@ -1633,7 +1736,7 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) mstype = gf_isom_get_mpeg4_subtype(import->orig, track_in, di); if (!mstype) mstype = gf_isom_get_media_subtype(import->orig, track_in, di); strcpy(szT, gf_4cc_to_str(mtype)); - gf_import_message(import, GF_OK, "IsoMedia import - track ID %d - media type \"%s:%s\"", + gf_import_message(import, GF_OK, "IsoMedia import - track ID %d - media type \"%s:%s\"", trackID, szT, gf_4cc_to_str(mstype)); } break; @@ -1652,6 +1755,10 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) e = gf_isom_add_sample_reference(import->dest, track, di, samp, offset); } else { samp = gf_isom_get_sample(import->orig, track_in, i+1, &di); + if (!samp) { + /*couldn't get the sample, but still move on*/ + goto exit; + } e = gf_isom_add_sample(import->dest, track, di, samp); } sampDTS = samp->DTS; @@ -1671,7 +1778,7 @@ GF_Err gf_import_isomedia(GF_MediaImporter *import) import->esd->decoderConfig = origin_esd ? origin_esd->decoderConfig : NULL; if (origin_esd) origin_esd->decoderConfig = NULL; } - } + } MP4T_RecomputeBitRate(import->dest, track); @@ -1680,6 +1787,8 @@ exit: return e; } +#ifndef GPAC_DISABLE_MPEG2PS + #include "mpeg2_ps.h" GF_Err gf_import_mpeg_ps_video(GF_MediaImporter *import) @@ -1689,10 +1798,11 @@ GF_Err gf_import_mpeg_ps_video(GF_MediaImporter *import) Double FPS; char *buf; u8 ftype; - u32 track, di, streamID, mtype, w, h, ar, nb_streams, buf_len, frames, ref_frame, timescale, duration, file_size, dts_inc, last_pos; + u32 track, di, streamID, mtype, w, h, ar, nb_streams, buf_len, frames, ref_frame, timescale, duration, dts_inc, last_pos; + u64 file_size; Bool destroy_esd; - if (import->flags & GF_IMPORT_USE_DATAREF) + if (import->flags & GF_IMPORT_USE_DATAREF) return gf_import_message(import, GF_NOT_SUPPORTED, "Cannot use data referencing with MPEG-1/2 files"); /*no auto frame-rate detection*/ @@ -1759,7 +1869,7 @@ GF_Err gf_import_mpeg_ps_video(GF_MediaImporter *import) w = mpeg2ps_get_video_stream_width(ps, streamID); h = mpeg2ps_get_video_stream_height(ps, streamID); ar = mpeg2ps_get_video_stream_aspect_ratio(ps, streamID); - mtype = (mpeg2ps_get_video_stream_type(ps, streamID) == MPEG_VIDEO_MPEG2) ? 0x61 : 0x6A; + mtype = (mpeg2ps_get_video_stream_type(ps, streamID) == MPEG_VIDEO_MPEG2) ? GPAC_OTI_VIDEO_MPEG2_MAIN : GPAC_OTI_VIDEO_MPEG1; FPS = mpeg2ps_get_video_stream_framerate(ps, streamID); if (import->video_fps) FPS = (Double) import->video_fps; get_video_timing(FPS, ×cale, &dts_inc); @@ -1789,12 +1899,12 @@ GF_Err gf_import_mpeg_ps_video(GF_MediaImporter *import) e = gf_isom_new_mpeg4_description(import->dest, track, import->esd, NULL, NULL, &di); if (e) goto exit; - gf_import_message(import, GF_OK, "%s Video import - Resolution %d x %d @ %02.4f FPS", (mtype==0x6A) ? "MPEG-1" : "MPEG-2", w, h, FPS); + gf_import_message(import, GF_OK, "%s Video import - Resolution %d x %d @ %02.4f FPS", (mtype==GPAC_OTI_VIDEO_MPEG1) ? "MPEG-1" : "MPEG-2", w, h, FPS); gf_isom_set_visual_info(import->dest, track, di, w, h); gf_isom_set_cts_packing(import->dest, track, 1); - file_size = (u32) mpeg2ps_get_ps_size(ps); + file_size = mpeg2ps_get_ps_size(ps); last_pos = 0; frames = 1; ref_frame = 1; @@ -1844,13 +1954,14 @@ GF_Err gf_import_mpeg_ps_audio(GF_MediaImporter *import) GF_Err e; mpeg2ps_t *ps; char *buf; - u32 track, di, streamID, mtype, sr, nb_ch, nb_streams, buf_len, frames, hdr, duration, file_size, last_pos; + u32 track, di, streamID, mtype, sr, nb_ch, nb_streams, buf_len, frames, hdr, duration, last_pos; + u64 file_size; Bool destroy_esd; GF_ISOSample *samp; if (import->flags & GF_IMPORT_PROBE_ONLY) return GF_OK; - if (import->flags & GF_IMPORT_USE_DATAREF) + if (import->flags & GF_IMPORT_USE_DATAREF) return gf_import_message(import, GF_NOT_SUPPORTED, "Cannot use data referencing with MPEG-1/2 files"); ps = mpeg2ps_init(import->in_name); @@ -1878,7 +1989,7 @@ GF_Err gf_import_mpeg_ps_audio(GF_MediaImporter *import) mpeg2ps_close(ps); return gf_import_message(import, GF_BAD_PARAM, "Desired audio track not found in MPEG file (%d audio streams)", nb_streams); } - + mtype = mpeg2ps_get_audio_stream_type(ps, streamID); if (mtype != MPEG_AUDIO_MPEG) { mpeg2ps_close(ps); @@ -1889,7 +2000,7 @@ GF_Err gf_import_mpeg_ps_audio(GF_MediaImporter *import) mpeg2ps_close(ps); return gf_import_message(import, GF_IO_ERR, "Cannot fetch audio frame from MPEG file"); } - + hdr = GF_4CC((u8)buf[0],(u8)buf[1],(u8)buf[2],(u8)buf[3]); mtype = gf_mp3_object_type_indication(hdr); sr = gf_mp3_sampling_rate(hdr); @@ -1918,7 +2029,7 @@ GF_Err gf_import_mpeg_ps_audio(GF_MediaImporter *import) if (e) goto exit; gf_isom_set_audio_info(import->dest, track, di, sr, nb_ch, 16); - gf_import_message(import, GF_OK, "%s Audio import - sample rate %d - %d channel%s", (mtype==0x6B) ? "MPEG-1" : "MPEG-2", sr, nb_ch, (nb_ch>1) ? "s" : ""); + gf_import_message(import, GF_OK, "%s Audio import - sample rate %d - %d channel%s", (mtype==GPAC_OTI_AUDIO_MPEG1) ? "MPEG-1" : "MPEG-2", sr, nb_ch, (nb_ch>1) ? "s" : ""); duration = (u32) ((Double)import->duration/1000.0 * sr); @@ -1927,7 +2038,7 @@ GF_Err gf_import_mpeg_ps_audio(GF_MediaImporter *import) samp->IsRAP = 1; samp->DTS = 0; - file_size = (u32) mpeg2ps_get_ps_size(ps); + file_size = mpeg2ps_get_ps_size(ps); last_pos = 0; frames = 0; do { @@ -1956,6 +2067,8 @@ exit: mpeg2ps_close(ps); return e; } +#endif /*GPAC_DISABLE_MPEG2PS*/ + GF_Err gf_import_nhnt(GF_MediaImporter *import) { @@ -1983,7 +2096,7 @@ GF_Err gf_import_nhnt(GF_MediaImporter *import) strcpy(szMedia, szName); strcat(szMedia, ".nhnt"); - nhnt = fopen(szMedia, "rb"); + nhnt = gf_f64_open(szMedia, "rb"); if (!nhnt) return gf_import_message(import, GF_URL_ERROR, "Cannot find NHNT file %s", szMedia); strcpy(szMedia, szName); @@ -1993,7 +2106,7 @@ GF_Err gf_import_nhnt(GF_MediaImporter *import) fclose(nhnt); return gf_import_message(import, GF_URL_ERROR, "Cannot find MEDIA file %s", szMedia); } - + e = GF_OK; destroy_esd = 0; @@ -2008,16 +2121,19 @@ GF_Err gf_import_nhnt(GF_MediaImporter *import) strcpy(szNhnt, szName); strcat(szNhnt, ".info"); - info = fopen(szNhnt, "rb"); + info = gf_f64_open(szNhnt, "rb"); if (info) { if (import->esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) import->esd->decoderConfig->decoderSpecificInfo); import->esd->decoderConfig->decoderSpecificInfo = NULL; import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - fseek(info, 0, SEEK_END); - import->esd->decoderConfig->decoderSpecificInfo->dataLength = (u32) ftell(info); - import->esd->decoderConfig->decoderSpecificInfo->data = (char*)malloc(sizeof(char) * import->esd->decoderConfig->decoderSpecificInfo->dataLength); - fseek(info, 0, SEEK_SET); - fread(import->esd->decoderConfig->decoderSpecificInfo->data, import->esd->decoderConfig->decoderSpecificInfo->dataLength, 1, info); + gf_f64_seek(info, 0, SEEK_END); + import->esd->decoderConfig->decoderSpecificInfo->dataLength = (u32) gf_f64_tell(info); + import->esd->decoderConfig->decoderSpecificInfo->data = (char*)gf_malloc(sizeof(char) * import->esd->decoderConfig->decoderSpecificInfo->dataLength); + gf_f64_seek(info, 0, SEEK_SET); + if (0==fread(import->esd->decoderConfig->decoderSpecificInfo->data, import->esd->decoderConfig->decoderSpecificInfo->dataLength, 1, info)){ + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, + ("[NHML import] Failed to read dataLength\n")); + } fclose(info); } /*keep parsed dsi (if any) if no .info file exists*/ @@ -2040,7 +2156,7 @@ GF_Err gf_import_nhnt(GF_MediaImporter *import) import->esd->decoderConfig->avgBitrate = gf_bs_read_u32(bs); import->esd->decoderConfig->maxBitrate = gf_bs_read_u32(bs); import->esd->slConfig->timestampResolution = gf_bs_read_u32(bs); - + w = h = 0; switch (import->esd->decoderConfig->streamType) { case GF_STREAM_SCENE: @@ -2051,7 +2167,8 @@ GF_Err gf_import_nhnt(GF_MediaImporter *import) break; case GF_STREAM_VISUAL: mtype = GF_ISOM_MEDIA_VISUAL; - if (import->esd->decoderConfig->objectTypeIndication==0x20) { +#ifndef GPAC_DISABLE_AV_PARSERS + if (import->esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { GF_M4VDecSpecInfo dsi; if (!import->esd->decoderConfig->decoderSpecificInfo) { e = GF_NON_COMPLIANT_BITSTREAM; @@ -2062,6 +2179,7 @@ GF_Err gf_import_nhnt(GF_MediaImporter *import) w = dsi.width; h = dsi.height; } +#endif break; case GF_STREAM_AUDIO: mtype = GF_ISOM_MEDIA_AUDIO; @@ -2110,7 +2228,7 @@ GF_Err gf_import_nhnt(GF_MediaImporter *import) duration = (u32) ( ((Double) import->duration)/ 1000 * import->esd->slConfig->timestampResolution); samp = gf_isom_sample_new(); - samp->data = (char*)malloc(sizeof(char) * 1024); + samp->data = (char*)gf_malloc(sizeof(char) * 1024); max_size = 1024; count = 0; gf_f64_seek(mdia, 0, SEEK_END); @@ -2150,16 +2268,18 @@ GF_Err gf_import_nhnt(GF_MediaImporter *import) if (import->flags & GF_IMPORT_USE_DATAREF) { if (!is_start) { e = gf_import_message(import, GF_NOT_SUPPORTED, "Fragmented NHNT file detected - cannot use data referencing"); - goto exit; + goto exit; } e = gf_isom_add_sample_reference(import->dest, track, di, samp, offset); } else { if (samp->dataLength>max_size) { - samp->data = (char*)realloc(samp->data, sizeof(char) * samp->dataLength); + samp->data = (char*)gf_realloc(samp->data, sizeof(char) * samp->dataLength); max_size = samp->dataLength; } gf_f64_seek(mdia, offset, SEEK_SET); - fread( samp->data, samp->dataLength, 1, mdia); + if (0==fread( samp->data, samp->dataLength, 1, mdia)){ + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("Failed to read samp->dataLength\n")); + } if (is_start) { e = gf_isom_add_sample(import->dest, track, di, samp); } else { @@ -2174,7 +2294,7 @@ GF_Err gf_import_nhnt(GF_MediaImporter *import) if (import->flags & GF_IMPORT_DO_ABORT) break; } if (media_done!=media_size) gf_set_progress("Importing NHNT", (u32) (media_size/1024), (u32) (media_size/1024)); - gf_isom_sample_del(&samp); + gf_isom_sample_del(&samp); MP4T_RecomputeBitRate(import->dest, track); exit: @@ -2192,7 +2312,7 @@ exit: typedef struct { Bool from_is_start, from_is_end, to_is_start, to_is_end; - u32 from_pos, to_pos; + u64 from_pos, to_pos; char *from_id, *to_id; GF_List *id_stack; GF_SAXParser *sax; @@ -2209,11 +2329,11 @@ static void nhml_node_start(void *sax_cbck, const char *node_name, const char *n for (i=0; iname, "DEF") && stricmp(att->name, "id")) continue; - node_id = strdup(att->value); + node_id = gf_strdup(att->value); break; } if (!node_id) { - node_id = strdup("__nhml__none"); + node_id = gf_strdup("__nhml__none"); gf_list_add(breaker->id_stack, node_id); return; } @@ -2246,7 +2366,7 @@ static void nhml_node_end(void *sax_cbck, const char *node_name, const char *nam breaker->to_pos = gf_xml_sax_get_node_end_pos(breaker->sax); breaker->to_is_end = 0; } - free(node_id); + gf_free(node_id); if (!breaker->to_is_start && !breaker->from_is_start && !breaker->to_is_end && !breaker->from_is_end) { gf_xml_sax_suspend(breaker->sax, 1); } @@ -2264,7 +2384,7 @@ GF_Err gf_import_sample_from_xml(GF_MediaImporter *import, GF_ISOSample *samp, c memset(&breaker, 0, sizeof(XMLBreaker)); - xml = fopen(xml_file, "rb"); + xml = gf_f64_open(xml_file, "rb"); if (!xml) { e = gf_import_message(import, GF_BAD_PARAM, "NHML import failure: file %s not found", xml_file); goto exit; @@ -2277,7 +2397,7 @@ GF_Err gf_import_sample_from_xml(GF_MediaImporter *import, GF_ISOSample *samp, c else breaker.from_is_end = 1; tmp = strchr(xmlFrom, '.'); *tmp = 0; - if (stricmp(xmlFrom, "doc")) breaker.from_id = strdup(xmlFrom); + if (stricmp(xmlFrom, "doc")) breaker.from_id = gf_strdup(xmlFrom); /*doc start pos is 0, no need to look for it*/ else if (breaker.from_is_start) breaker.from_is_start = 0; *tmp = '.'; @@ -2286,7 +2406,7 @@ GF_Err gf_import_sample_from_xml(GF_MediaImporter *import, GF_ISOSample *samp, c else breaker.to_is_end = 1; tmp = strchr(xmlTo, '.'); *tmp = 0; - if (stricmp(xmlTo, "doc")) breaker.to_id = strdup(xmlTo); + if (stricmp(xmlTo, "doc")) breaker.to_id = gf_strdup(xmlTo); /*doc end pos is file size, no need to look for it*/ else if (breaker.to_is_end) breaker.to_is_end = 0; *tmp = '.'; @@ -2298,9 +2418,9 @@ GF_Err gf_import_sample_from_xml(GF_MediaImporter *import, GF_ISOSample *samp, c e = GF_OK; if (!breaker.to_id) { - fseek(xml, 0, SEEK_END); - breaker.to_pos = ftell(xml); - fseek(xml, 0, SEEK_SET); + gf_f64_seek(xml, 0, SEEK_END); + breaker.to_pos = gf_f64_tell(xml); + gf_f64_seek(xml, 0, SEEK_SET); } if(breaker.to_pos < breaker.from_pos) { e = gf_import_message(import, GF_BAD_PARAM, "NHML import failure: xmlFrom %s is located after xmlTo %s", xmlFrom, xmlTo); @@ -2309,24 +2429,26 @@ GF_Err gf_import_sample_from_xml(GF_MediaImporter *import, GF_ISOSample *samp, c assert(breaker.to_pos > breaker.from_pos); - samp->dataLength = breaker.to_pos - breaker.from_pos; + samp->dataLength = (u32) (breaker.to_pos - breaker.from_pos); if (*max_size < samp->dataLength) { *max_size = samp->dataLength; - samp->data = (char*)realloc(samp->data, sizeof(char)*samp->dataLength); + samp->data = (char*)gf_realloc(samp->data, sizeof(char)*samp->dataLength); + } + gf_f64_seek(xml, breaker.from_pos, SEEK_SET); + if (0==fread(samp->data, samp->dataLength, 1, xml)){ + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("Failed to read samp->dataLength\n")); } - fseek(xml, breaker.from_pos, SEEK_SET); - fread(samp->data, 1, samp->dataLength, xml); exit: if (xml) fclose(xml); while (gf_list_count(breaker.id_stack)) { char *id = (char *)gf_list_last(breaker.id_stack); gf_list_rem_last(breaker.id_stack); - free(id); + gf_free(id); } gf_list_del(breaker.id_stack); - if (breaker.from_id) free(breaker.from_id); - if (breaker.to_id) free(breaker.to_id); + if (breaker.from_id) gf_free(breaker.from_id); + if (breaker.to_id) gf_free(breaker.to_id); return e; } @@ -2334,20 +2456,20 @@ exit: static GF_Err compress_sample_data(GF_ISOSample *samp, u32 *max_size, char **dict, u32 offset) { - z_stream stream; - int err; - char *dest = (char *)malloc(sizeof(char)*samp->dataLength*ZLIB_COMPRESS_SAFE); - stream.next_in = (Bytef*)samp->data + offset; - stream.avail_in = (uInt)samp->dataLength - offset; - stream.next_out = ( Bytef*)dest; - stream.avail_out = (uInt)samp->dataLength*ZLIB_COMPRESS_SAFE; - stream.zalloc = (alloc_func)NULL; - stream.zfree = (free_func)NULL; - stream.opaque = (voidpf)NULL; - - err = deflateInit(&stream, 9); - if (err != Z_OK) { - free(dest); + z_stream stream; + int err; + char *dest = (char *)gf_malloc(sizeof(char)*samp->dataLength*ZLIB_COMPRESS_SAFE); + stream.next_in = (Bytef*)samp->data + offset; + stream.avail_in = (uInt)samp->dataLength - offset; + stream.next_out = ( Bytef*)dest; + stream.avail_out = (uInt)samp->dataLength*ZLIB_COMPRESS_SAFE; + stream.zalloc = (alloc_func)NULL; + stream.zfree = (free_func)NULL; + stream.opaque = (voidpf)NULL; + + err = deflateInit(&stream, 9); + if (err != Z_OK) { + gf_free(dest); return GF_IO_ERR; } if (dict && *dict) { @@ -2355,38 +2477,38 @@ static GF_Err compress_sample_data(GF_ISOSample *samp, u32 *max_size, char **dic if (err != Z_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[NHML import] Error assigning dictionary\n")); deflateEnd(&stream); - free(dest); + gf_free(dest); return GF_IO_ERR; } } - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - free(dest); - return GF_IO_ERR; - } - if (samp->dataLength - offsetdataLength - offsetdataLength - offset)); } if (dict) { - if (*dict) free(*dict); - *dict = (char*)malloc(sizeof(char)*samp->dataLength); + if (*dict) gf_free(*dict); + *dict = (char*)gf_malloc(sizeof(char)*samp->dataLength); memcpy(*dict, samp->data, samp->dataLength); } if (*max_size < stream.total_out) { *max_size = samp->dataLength*ZLIB_COMPRESS_SAFE; - samp->data = realloc(samp->data, *max_size * sizeof(char)); - } + samp->data = gf_realloc(samp->data, *max_size * sizeof(char)); + } memcpy(samp->data + offset, dest, sizeof(char)*stream.total_out); samp->dataLength = offset + stream.total_out; - free(dest); + gf_free(dest); - deflateEnd(&stream); - return GF_OK; + deflateEnd(&stream); + return GF_OK; } -static void nhml_on_progress(void *cbk, u32 done, u32 tot) +static void nhml_on_progress(void *cbk, u64 done, u64 tot) { gf_set_progress("NHML Loading", done, tot); } @@ -2420,7 +2542,7 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) import->tk_info[0].flags = GF_IMPORT_USE_DATAREF; return GF_OK; } - nhml = fopen(import->in_name, "rt"); + nhml = gf_f64_open(import->in_name, "rt"); if (!nhml) return gf_import_message(import, GF_URL_ERROR, "Cannot find %s file %s", szImpName, szMedia); strcpy(szName, import->in_name); @@ -2455,9 +2577,9 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) dims.streamType = 1; dims.containsRedundant = 1; - if (stricmp(root->name, szRootName)) { + if (stricmp(root->name, szRootName)) { e = gf_import_message(import, GF_BAD_PARAM, "Error parsing %s file - \"%s\" root expected, got \"%s\"", szImpName, szRootName, root->name); - goto exit; + goto exit; } dictionary = NULL; use_dict = 0; @@ -2488,18 +2610,18 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) else if (!stricmp(att->name, "DTS_increment")) dts_inc = atoi(att->value); else if (!stricmp(att->name, "gzipSamples")) do_compress = (!stricmp(att->value, "yes")) ? 1 : 0; else if (!stricmp(att->name, "gzipDictionary")) { - u32 d_size; + u64 d_size; if (stricmp(att->value, "self")) { - FILE *d = fopen(att->value, "rb"); + FILE *d = gf_f64_open(att->value, "rb"); if (!d) { gf_import_message(import, GF_IO_ERR, "Cannot open dictionary file %s", att->value); continue; } - fseek(d, 0, SEEK_END); - d_size = ftell(d); - dictionary = (char*)malloc(sizeof(char)*(d_size+1)); - fseek(d, 0, SEEK_SET); - fread(dictionary, 1, d_size, d); + gf_f64_seek(d, 0, SEEK_END); + d_size = gf_f64_tell(d); + dictionary = (char*)gf_malloc(sizeof(char)*(size_t)(d_size+1)); + gf_f64_seek(d, 0, SEEK_SET); + d_size = fread(dictionary, sizeof(char), (size_t)d_size, d); dictionary[d_size]=0; } use_dict = 1; @@ -2537,7 +2659,7 @@ 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; - + } if (sdesc.samplerate && !timescale) timescale = sdesc.samplerate; if (!sdesc.bits_per_sample) sdesc.bits_per_sample = 16; @@ -2555,16 +2677,16 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) specInfoSize = 0; if (!streamType && !mtype && !sdesc.codec_tag) { e = gf_import_message(import, GF_NOT_SUPPORTED, "Error parsing %s file - StreamType or MediaType not specified", szImpName); - goto exit; + goto exit; } - info = fopen(szInfo, "rb"); + info = gf_f64_open(szInfo, "rb"); if (info) { - fseek(info, 0, SEEK_END); - specInfoSize = (u32) ftell(info); - specInfo = (char*)malloc(sizeof(char) * specInfoSize); - fseek(info, 0, SEEK_SET); - fread(specInfo, specInfoSize, 1, info); + gf_f64_seek(info, 0, SEEK_END); + specInfoSize = (u32) gf_f64_tell(info); + specInfo = (char*)gf_malloc(sizeof(char) * specInfoSize); + gf_f64_seek(info, 0, SEEK_SET); + specInfoSize = fread(specInfo, sizeof(char), specInfoSize, info); fclose(info); } /*compressing samples, remove data ref*/ @@ -2591,13 +2713,14 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) specInfo = NULL; specInfoSize = 0; import->esd->slConfig->timestampResolution = timescale; - - + + switch (import->esd->decoderConfig->streamType) { case GF_STREAM_SCENE: mtype = GF_ISOM_MEDIA_SCENE; break; case GF_STREAM_VISUAL: mtype = GF_ISOM_MEDIA_VISUAL; - if (import->esd->decoderConfig->objectTypeIndication==0x20) { +#ifndef GPAC_DISABLE_AV_PARSERS + if (import->esd->decoderConfig->objectTypeIndication==GPAC_OTI_VIDEO_MPEG4_PART2) { GF_M4VDecSpecInfo dsi; if (!import->esd->decoderConfig->decoderSpecificInfo) { e = GF_NON_COMPLIANT_BITSTREAM; @@ -2608,9 +2731,10 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) sdesc.height = dsi.height; if (e) goto exit; } +#endif break; - case GF_STREAM_AUDIO: - mtype = GF_ISOM_MEDIA_AUDIO; + case GF_STREAM_AUDIO: + mtype = GF_ISOM_MEDIA_AUDIO; if (!sdesc.samplerate) sdesc.samplerate = 44100; if (!sdesc.nb_channels) sdesc.nb_channels = 2; break; @@ -2657,7 +2781,7 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) gf_isom_set_track_enabled(import->dest, track, 1); import->final_trackID = gf_isom_get_track_id(import->dest, track); if (import->esd && !import->esd->ESID) import->esd->ESID = import->final_trackID; - + if (sdesc.width && sdesc.height) { gf_isom_set_visual_info(import->dest, track, di, sdesc.width, sdesc.height); if (par_den && par_num) { @@ -2673,7 +2797,7 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) duration = (u32) ( ((Double) import->duration)/ 1000 * timescale); samp = gf_isom_sample_new(); - samp->data = (char*)malloc(sizeof(char) * 1024); + samp->data = (char*)gf_malloc(sizeof(char) * 1024); max_size = 1024; count = 0; media_size = 0; @@ -2732,15 +2856,15 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) } else if (!stricmp(att->name, "is-redundant") && !stricmp(att->value, "yes")) dims_flags |= GF_DIMS_UNIT_I; - else if (!stricmp(att->name, "redundant-exit") && !stricmp(att->value, "yes")) + else if (!stricmp(att->name, "redundant-exit") && !stricmp(att->value, "yes")) dims_flags |= GF_DIMS_UNIT_D; - else if (!stricmp(att->name, "priority") && !stricmp(att->value, "high")) + else if (!stricmp(att->name, "priority") && !stricmp(att->value, "high")) dims_flags |= GF_DIMS_UNIT_P; - else if (!stricmp(att->name, "compress") && !stricmp(att->value, "yes")) + else if (!stricmp(att->name, "compress") && !stricmp(att->value, "yes")) dims_flags |= GF_DIMS_UNIT_C; } - if (samp->IsRAP==1) + if (samp->IsRAP==1) dims_flags |= GF_DIMS_UNIT_M; if (!count && samp->DTS) samp->DTS = 0; @@ -2763,7 +2887,7 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) samp->dataLength = 3 + strlen(content); if (samp->dataLength>max_size) { - samp->data = (char*)realloc(samp->data, sizeof(char) * samp->dataLength); + samp->data = (char*)gf_realloc(samp->data, sizeof(char) * samp->dataLength); max_size = samp->dataLength; } @@ -2771,12 +2895,12 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) gf_bs_write_u16(bs, samp->dataLength-2); gf_bs_write_u8(bs, (u8) dims_flags); gf_bs_write_data(bs, content, (samp->dataLength-3)); - free(content); + gf_free(content); gf_bs_del(bs); /*same DIMS unit*/ if (gf_isom_get_sample_from_dts(import->dest, track, samp->DTS)) append = 1; - + } else { Bool close = 0; FILE *f = mdia; @@ -2795,6 +2919,7 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) if (!samp->dataLength) { u64 cur_pos = gf_f64_tell(f); gf_f64_seek(f, 0, SEEK_END); + assert(gf_f64_tell(f) < 1<<31); samp->dataLength = (u32) gf_f64_tell(f); gf_f64_seek(f, cur_pos, SEEK_SET); } @@ -2803,14 +2928,16 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) if (is_dims) { GF_BitStream *bs; if (samp->dataLength+3>max_size) { - samp->data = (char*)realloc(samp->data, sizeof(char) * (samp->dataLength+3)); + samp->data = (char*)gf_realloc(samp->data, sizeof(char) * (samp->dataLength+3)); max_size = samp->dataLength+3; } bs = gf_bs_new(samp->data, samp->dataLength+3, GF_BITSTREAM_WRITE); gf_bs_write_u16(bs, samp->dataLength+1); gf_bs_write_u8(bs, (u8) dims_flags); - fread( samp->data+3, samp->dataLength, 1, f); - gf_bs_del(bs); + if (samp->dataLength != fread( samp->data+3, sizeof(char), samp->dataLength, f)){ + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[NHML import dims] Failed to fully read samp->dataLength\n")); + } + gf_bs_del(bs); samp->dataLength+=3; /*same DIMS unit*/ @@ -2818,10 +2945,12 @@ GF_Err gf_import_nhml_dims(GF_MediaImporter *import, Bool dims_doc) append = 1; } else { if (samp->dataLength>max_size) { - samp->data = (char*)realloc(samp->data, sizeof(char) * samp->dataLength); + samp->data = (char*)gf_realloc(samp->data, sizeof(char) * samp->dataLength); max_size = samp->dataLength; } - fread( samp->data, samp->dataLength, 1, f); + if (samp->dataLength != fread( samp->data, sizeof(char), samp->dataLength, f)){ + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[NHML import dims] Failed to fully read samp->dataLength\n")); + } } if (close) fclose(f); } @@ -2873,7 +3002,7 @@ exit: fclose(nhml); if (samp) { samp->dataLength = 1; - gf_isom_sample_del(&samp); + gf_isom_sample_del(&samp); } if (mdia) fclose(mdia); if (import->esd && destroy_esd) { @@ -2881,8 +3010,8 @@ exit: import->esd = NULL; } gf_xml_dom_del(parser); - if (specInfo) free(specInfo); - if (dictionary) free(dictionary); + if (specInfo) gf_free(specInfo); + if (dictionary) gf_free(dictionary); return e; } @@ -2890,11 +3019,12 @@ exit: GF_Err gf_import_amr_evrc_smv(GF_MediaImporter *import) { GF_Err e; - u32 track, trackID, di, max_size, duration, sample_rate, block_size, i; + u32 track, trackID, di, max_size, duration, sample_rate, block_size, i, readen; GF_ISOSample *samp; char magic[20], *msg; Bool delete_esd, update_gpp_cfg; - u32 media_size, media_done, offset, mtype, oti, nb_frames; + u32 media_done, mtype, oti, nb_frames; + u64 offset, media_size; GF_3GPConfig gpp_cfg; FILE *mdia; msg = NULL; @@ -2907,33 +3037,37 @@ GF_Err gf_import_amr_evrc_smv(GF_MediaImporter *import) return GF_OK; } - mdia = fopen(import->in_name, "rb"); + mdia = gf_f64_open(import->in_name, "rb"); if (!mdia) return gf_import_message(import, GF_URL_ERROR, "Cannot find file %s", import->in_name); - + update_gpp_cfg = 0; oti = mtype = 0; sample_rate = 8000; block_size = 160; - fread(magic, 1, 20, mdia); + if (6 > fread(magic, sizeof(char), 20, mdia)){ + fclose(mdia); + return gf_import_message(import, GF_URL_ERROR, "Cannot guess type for file %s, size lower than 6", import->in_name); + + } if (!strnicmp(magic, "#!AMR\n", 6)) { gf_import_message(import, GF_OK, "Importing AMR Audio"); - fseek(mdia, 6, SEEK_SET); + gf_f64_seek(mdia, 6, SEEK_SET); mtype = GF_ISOM_SUBTYPE_3GP_AMR; update_gpp_cfg = 1; msg = "Importing AMR"; } else if (!strnicmp(magic, "#!EVRC\n", 7)) { gf_import_message(import, GF_OK, "Importing EVRC Audio"); - fseek(mdia, 7, SEEK_SET); + gf_f64_seek(mdia, 7, SEEK_SET); mtype = GF_ISOM_SUBTYPE_3GP_EVRC; - oti = 0xA0; + oti = GPAC_OTI_AUDIO_EVRC_VOICE; msg = "Importing EVRC"; } else if (!strnicmp(magic, "#!SMV\n", 6)) { gf_import_message(import, GF_OK, "Importing SMV Audio"); - fseek(mdia, 6, SEEK_SET); + gf_f64_seek(mdia, 6, SEEK_SET); mtype = GF_ISOM_SUBTYPE_3GP_SMV; - oti = 0xA1; + oti = GPAC_OTI_AUDIO_SMV_VOICE; msg = "Importing SMV"; } else if (!strnicmp(magic, "#!AMR_MC1.0\n", 12)) { @@ -2942,7 +3076,7 @@ GF_Err gf_import_amr_evrc_smv(GF_MediaImporter *import) } else if (!strnicmp(magic, "#!AMR-WB\n", 9)) { gf_import_message(import, GF_OK, "Importing AMR WideBand Audio"); - fseek(mdia, 9, SEEK_SET); + gf_f64_seek(mdia, 9, SEEK_SET); mtype = GF_ISOM_SUBTYPE_3GP_AMR_WB; sample_rate = 16000; block_size = 320; @@ -2956,14 +3090,14 @@ GF_Err gf_import_amr_evrc_smv(GF_MediaImporter *import) else { char *ext = strrchr(import->in_name, '.'); if (ext && !stricmp(ext, ".amr")) { mtype = GF_ISOM_SUBTYPE_3GP_AMR; update_gpp_cfg = 1; ext = "AMR"; msg = "Importing AMR";} - else if (ext && !stricmp(ext, ".evc")) { mtype = GF_ISOM_SUBTYPE_3GP_EVRC; oti = 0xA0; ext = "EVRC"; msg = "Importing EVRC";} - else if (ext && !stricmp(ext, ".smv")) { mtype = GF_ISOM_SUBTYPE_3GP_SMV; oti = 0xA1; ext = "SMV"; msg = "Importing SMV";} + else if (ext && !stricmp(ext, ".evc")) { mtype = GF_ISOM_SUBTYPE_3GP_EVRC; oti = GPAC_OTI_AUDIO_EVRC_VOICE; ext = "EVRC"; msg = "Importing EVRC";} + else if (ext && !stricmp(ext, ".smv")) { mtype = GF_ISOM_SUBTYPE_3GP_SMV; oti = GPAC_OTI_AUDIO_SMV_VOICE; ext = "SMV"; msg = "Importing SMV";} else { fclose(mdia); return gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Corrupted AMR/SMV/EVRC file header"); } - - fseek(mdia, 0, SEEK_SET); + + gf_f64_seek(mdia, 0, SEEK_SET); gf_import_message(import, GF_OK, "Importing %s Audio (File header corrupted, missing \"#!%s\\n\")", ext, ext); } @@ -2986,7 +3120,7 @@ GF_Err gf_import_amr_evrc_smv(GF_MediaImporter *import) gpp_cfg.frames_per_sample = import->frames_per_sample; if (!gpp_cfg.frames_per_sample) gpp_cfg.frames_per_sample = 1; else if (gpp_cfg.frames_per_sample >15) gpp_cfg.frames_per_sample = 15; - + if (import->flags & GF_IMPORT_USE_DATAREF) gpp_cfg.frames_per_sample = 1; @@ -3011,21 +3145,21 @@ GF_Err gf_import_amr_evrc_smv(GF_MediaImporter *import) duration /= 1000; samp = gf_isom_sample_new(); - samp->data = (char*)malloc(sizeof(char) * 200); + samp->data = (char*)gf_malloc(sizeof(char) * 200); samp->IsRAP = 1; max_size = 200; - offset = ftell(mdia); - fseek(mdia, 0, SEEK_END); - media_size = ftell(mdia) - offset; - fseek(mdia, offset, SEEK_SET); + offset = gf_f64_tell(mdia); + gf_f64_seek(mdia, 0, SEEK_END); + media_size = gf_f64_tell(mdia) - offset; + gf_f64_seek(mdia, offset, SEEK_SET); media_done = 0; nb_frames = 0; while (!feof(mdia)) { u8 ft, toc; - - offset = ftell(mdia); + + offset = gf_f64_tell(mdia); toc = fgetc(mdia); switch (gpp_cfg.type) { case GF_ISOM_SUBTYPE_3GP_AMR: @@ -3057,9 +3191,10 @@ GF_Err gf_import_amr_evrc_smv(GF_MediaImporter *import) break; } - if (samp->dataLength) - fread( samp->data + 1, samp->dataLength, 1, mdia); - + if (samp->dataLength){ + readen = fread( samp->data + 1, sizeof(char), samp->dataLength, mdia); + assert(readen == samp->dataLength); + } samp->dataLength += 1; /*if last frame is "no data", abort - this happens in many files with constant mode (ie constant files), where adding this last frame will result in a non-compact version of the stsz table, hence a bigger file*/ @@ -3084,7 +3219,7 @@ GF_Err gf_import_amr_evrc_smv(GF_MediaImporter *import) if (duration && (samp->DTS > duration)) break; if (import->flags & GF_IMPORT_DO_ABORT) break; } - gf_isom_sample_del(&samp); + gf_isom_sample_del(&samp); gf_isom_refresh_size_info(import->dest, track); if (import->flags & GF_IMPORT_FORCE_MPEG4) MP4T_RecomputeBitRate(import->dest, track); @@ -3109,11 +3244,13 @@ static const char *QCP_SMV_GUID = "\x75\x2B\x7C\x8D\x97\xA7\x46\xED\x98\x5E\xD5\ GF_Err gf_import_qcp(GF_MediaImporter *import) { GF_Err e; - u32 track, trackID, di, i, nb_pck, max_size, duration, riff_size, chunk_size, major, minor, version, avg_bps, pck_size, block_size, bps, samplerate, vrat_rate_flag, size_in_packets, nb_frames; + u32 track, trackID, di, i, nb_pck, duration, riff_size, chunk_size, major, minor, version, avg_bps, pck_size, block_size, bps, samplerate, vrat_rate_flag, size_in_packets, nb_frames; + u64 max_size; GF_BitStream *bs; GF_ISOSample *samp; char magic[12], GUID[16], name[81], fmt[162]; - u32 media_size, media_done, offset, rtable_cnt; + u32 rtable_cnt; + u64 offset, media_size, media_done; Bool has_pad; QCPRateTable rtable[8]; Bool delete_esd; @@ -3133,7 +3270,7 @@ GF_Err gf_import_qcp(GF_MediaImporter *import) mdia = gf_f64_open(import->in_name, "rb"); if (!mdia) return gf_import_message(import, GF_URL_ERROR, "Cannot find file %s", import->in_name); - + bs = gf_bs_from_file(mdia, GF_BITSTREAM_READ); gf_bs_read_data(bs, magic, 4); if (strnicmp(magic, "RIFF", 4)) { @@ -3148,7 +3285,7 @@ GF_Err gf_import_qcp(GF_MediaImporter *import) e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Broken QCP file: QLCM header not found"); goto exit; } - max_size = (u32) gf_bs_get_size(bs); + max_size = gf_bs_get_size(bs); if (max_size != riff_size+8) { e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Broken QCP file: Expecting RIFF-Size %d got %d", max_size-8, riff_size); goto exit; @@ -3241,22 +3378,22 @@ GF_Err gf_import_qcp(GF_MediaImporter *import) delete_esd = 1; } if (!import->esd->decoderConfig) import->esd->decoderConfig = (GF_DecoderConfig*)gf_odf_desc_new(GF_ODF_DCD_TAG); - import->esd->decoderConfig->streamType = 0x05; + import->esd->decoderConfig->streamType = GF_STREAM_AUDIO; switch (gpp_cfg.type) { case GF_ISOM_SUBTYPE_3GP_QCELP: - import->esd->decoderConfig->objectTypeIndication = 0xE1; + import->esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_13K_VOICE; /*DSI is fmt*/ if (!import->esd->decoderConfig->decoderSpecificInfo) import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - if (import->esd->decoderConfig->decoderSpecificInfo->data) free(import->esd->decoderConfig->decoderSpecificInfo->data); + if (import->esd->decoderConfig->decoderSpecificInfo->data) gf_free(import->esd->decoderConfig->decoderSpecificInfo->data); import->esd->decoderConfig->decoderSpecificInfo->dataLength = 162; - import->esd->decoderConfig->decoderSpecificInfo->data = (char*)malloc(sizeof(char)*162); + import->esd->decoderConfig->decoderSpecificInfo->data = (char*)gf_malloc(sizeof(char)*162); memcpy(import->esd->decoderConfig->decoderSpecificInfo->data, fmt, 162); break; case GF_ISOM_SUBTYPE_3GP_EVRC: - import->esd->decoderConfig->objectTypeIndication = 0xA0; + import->esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_EVRC_VOICE; break; case GF_ISOM_SUBTYPE_3GP_SMV: - import->esd->decoderConfig->objectTypeIndication = 0xA1; + import->esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_SMV_VOICE; break; } e = gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di); @@ -3274,13 +3411,13 @@ GF_Err gf_import_qcp(GF_MediaImporter *import) duration /= 1000; samp = gf_isom_sample_new(); - samp->data = (char*)malloc(sizeof(char) * 200); + samp->data = (char*)gf_malloc(sizeof(char) * 200); samp->IsRAP = 1; max_size = 200; - offset = ftell(mdia); - fseek(mdia, 0, SEEK_END); - media_size = ftell(mdia) - offset; - fseek(mdia, offset, SEEK_SET); + offset = gf_f64_tell(mdia); + gf_f64_seek(mdia, 0, SEEK_END); + media_size = gf_f64_tell(mdia) - offset; + gf_f64_seek(mdia, offset, SEEK_SET); nb_pck = 0; media_done = 0; @@ -3296,7 +3433,7 @@ GF_Err gf_import_qcp(GF_MediaImporter *import) u32 idx = 0; u32 size = 0; - offset = (u32) gf_bs_get_position(bs); + offset = gf_bs_get_position(bs); /*get frame rate idx*/ if (vrat_rate_flag) { idx = gf_bs_read_u8(bs); @@ -3310,7 +3447,7 @@ GF_Err gf_import_qcp(GF_MediaImporter *import) samp->dataLength = size; } if (max_sizedataLength) { - samp->data = (char*)realloc(samp->data, sizeof(char)*samp->dataLength); + samp->data = (char*)gf_realloc(samp->data, sizeof(char)*samp->dataLength); max_size=samp->dataLength; } if (import->flags & GF_IMPORT_USE_DATAREF) { @@ -3352,7 +3489,7 @@ GF_Err gf_import_qcp(GF_MediaImporter *import) gf_bs_skip_bytes(bs, chunk_size); if (has_pad) gf_bs_read_u8(bs); } - gf_isom_sample_del(&samp); + gf_isom_sample_del(&samp); gf_isom_set_brand_info(import->dest, GF_ISOM_BRAND_3G2A, 65536); if (import->flags & GF_IMPORT_FORCE_MPEG4) MP4T_RecomputeBitRate(import->dest, track); gf_set_progress("Importing QCP", size_in_packets, size_in_packets); @@ -3383,7 +3520,7 @@ u32 H263_NextStartCode(GF_BitStream *bs) unsigned char h263_cache[H263_CACHE_SIZE]; u64 end, cache_start, load_size; u64 start = gf_bs_get_position(bs); - + /*skip 16b header*/ gf_bs_read_u16(bs); bpos = 0; @@ -3403,7 +3540,7 @@ u32 H263_NextStartCode(GF_BitStream *bs) } v = (v<<8) | h263_cache[bpos]; bpos++; - if ((v >> (32-22)) == 0x20) end = cache_start+bpos-4; + if ((v >> (32-22)) == 0x20) end = cache_start+bpos-4; } gf_bs_seek(bs, start); if (!end) end = gf_bs_get_size(bs); @@ -3413,22 +3550,21 @@ static void h263_get_pic_size(GF_BitStream *bs, u32 fmt, u32 *w, u32 *h) { switch (fmt) { case 1: *w = 128; *h = 96; break; - case 2: *w = 176; *h = 144; break; - case 3: *w = 352; *h = 288; break; - case 4: *w = 704; *h = 576; break; - case 5: *w = 1409; *h = 1152 ; break; - default: *w = *h = 0; break; - } + case 2: *w = 176; *h = 144; break; + case 3: *w = 352; *h = 288; break; + case 4: *w = 704; *h = 576; break; + case 5: *w = 1409; *h = 1152 ; break; + default: *w = *h = 0; break; + } } GF_Err gf_import_h263(GF_MediaImporter *import) { GF_Err e; u32 track, trackID, di, max_size, timescale, duration, w, h, fmt, nb_samp, dts_inc; - u64 offset; + u64 offset, media_size, media_done; GF_ISOSample *samp; char *samp_data; - u32 media_size, media_done; GF_3GPConfig gpp_cfg; Double FPS; FILE *mdia; @@ -3502,18 +3638,19 @@ GF_Err gf_import_h263(GF_MediaImporter *import) samp = gf_isom_sample_new(); duration = (u32) ( ((Double)import->duration) * timescale / 1000.0); - media_size = (u32) gf_bs_get_size(bs); - nb_samp = media_done = 0; + media_size = gf_bs_get_size(bs); + nb_samp = 0; + media_done = 0; max_size = 4096; - samp_data = (char*)malloc(sizeof(char)*max_size); + samp_data = (char*)gf_malloc(sizeof(char)*max_size); gf_bs_seek(bs, 0); offset = 0; while (gf_bs_available(bs)) { samp->dataLength = H263_NextStartCode(bs); if (samp->dataLength>max_size) { max_size = samp->dataLength; - samp_data = (char*)realloc(samp_data, sizeof(char)*max_size); + samp_data = (char*)gf_realloc(samp_data, sizeof(char)*max_size); } gf_bs_read_data(bs, samp_data, samp->dataLength); /*we ignore pict number and import at const FPS*/ @@ -3536,7 +3673,7 @@ GF_Err gf_import_h263(GF_MediaImporter *import) break; } } - free(samp_data); + gf_free(samp_data); gf_isom_sample_del(&samp); gf_set_progress("Importing H263", nb_samp, nb_samp); gf_isom_modify_alternate_brand(import->dest, GF_4CC('3','g','g','6'), 1); @@ -3553,7 +3690,7 @@ static void avc_rewrite_samples(GF_ISOFile *file, u32 track, u32 prev_size, u32 char *buffer; msize = 4096; - buffer = (char*)malloc(sizeof(char)*msize); + buffer = (char*)gf_malloc(sizeof(char)*msize); count = gf_isom_get_sample_count(file, track); for (i=0; imsize) { msize = size; - buffer = (char*)realloc(buffer, sizeof(char)*msize); + buffer = (char*)gf_realloc(buffer, sizeof(char)*msize); } gf_bs_read_data(oldbs, buffer, size); gf_bs_write_data(newbs, buffer, size); remain -= size; } gf_bs_del(oldbs); - free(samp->data); + gf_free(samp->data); samp->data = NULL; samp->dataLength = 0; gf_bs_get_content(newbs, &samp->data, &samp->dataLength); @@ -3581,25 +3718,30 @@ static void avc_rewrite_samples(GF_ISOFile *file, u32 track, u32 prev_size, u32 gf_isom_update_sample(file, track, i+1, samp, 1); gf_isom_sample_del(&samp); } - free(buffer); + gf_free(buffer); } +#ifndef GPAC_DISABLE_AV_PARSERS + GF_Err gf_import_h264(GF_MediaImporter *import) { u64 nal_start, nal_end, total_size; - u32 nal_size, track, trackID, di, cur_samp, nb_i, nb_idr, nb_p, nb_b, nb_sp, nb_si, nb_sei, max_w, max_h, duration, max_delay, max_total_delay; + u32 nal_size, track, trackID, di, cur_samp, nb_i, nb_idr, nb_p, nb_b, nb_sp, nb_si, nb_sei, max_w, max_h, duration, max_total_delay, nb_ei, nb_ep, nb_eb; s32 idx; u8 nal_type; GF_Err e; FILE *mdia; AVCState avc; GF_AVCConfigSlot *slc; - GF_AVCConfig *avccfg; + GF_AVCConfig *avccfg, *svccfg, *dstcfg; GF_BitStream *bs; GF_BitStream *sample_data; Bool flush_sample, sample_is_rap, first_nal, slice_is_ref, has_cts_offset, detect_fps, is_paff; - u32 b_frames, ref_frame, pred_frame, timescale, copy_size, size_length, dts_inc; + u32 ref_frame, pred_frame, timescale, copy_size, size_length, dts_inc; s32 last_poc, max_last_poc, max_last_b_poc, poc_diff, prev_last_poc, min_poc, poc_shift; + Bool first_avc; + u32 last_svc_sps; + Bool prev_is_nalu_prefix; Double FPS; char *buffer; u32 max_size = 4096; @@ -3615,22 +3757,27 @@ GF_Err gf_import_h264(GF_MediaImporter *import) mdia = gf_f64_open(import->in_name, "rb"); if (!mdia) return gf_import_message(import, GF_URL_ERROR, "Cannot find file %s", import->in_name); - detect_fps = 0; + detect_fps = 1; if (import->video_fps == 10000.0) { import->video_fps = 25.0; - detect_fps = 1; } - + FPS = (Double) import->video_fps; if (!FPS) FPS = GF_IMPORT_DEFAULT_FPS; get_video_timing(FPS, ×cale, &dts_inc); -restart_import: +restart_import: memset(&avc, 0, sizeof(AVCState)); + avc.sps_active_idx = -1; avccfg = gf_odf_avc_cfg_new(); - buffer = (char*)malloc(sizeof(char) * max_size); + svccfg = gf_odf_avc_cfg_new(); + /*we don't handle split import (one track / layer)*/ + svccfg->complete_representation = 1; + buffer = (char*)gf_malloc(sizeof(char) * max_size); sample_data = NULL; + first_avc = 1; + last_svc_sps = 0, bs = gf_bs_from_file(mdia, GF_BITSTREAM_READ); if (!AVC_IsStartCode(bs)) { @@ -3643,7 +3790,7 @@ restart_import: /*if import in edit mode, use smallest NAL size and adjust on the fly*/ else if (gf_isom_get_mode(import->dest)!=GF_ISOM_OPEN_WRITE) size_length = 8; else size_length = 32; - + trackID = 0; e = GF_OK; if (import->esd) trackID = import->esd->ESID; @@ -3667,36 +3814,45 @@ restart_import: total_size = gf_bs_get_size(bs); nal_start = gf_bs_get_position(bs); duration = (u32) ( ((Double)import->duration) * timescale / 1000.0); - - nb_i = nb_idr = nb_p = nb_b = nb_sp = nb_si = nb_sei = 0; + + nb_i = nb_idr = nb_p = nb_b = nb_sp = nb_si = nb_sei = nb_ei = nb_ep = nb_eb = 0; max_w = max_h = 0; first_nal = 1; - b_frames = ref_frame = pred_frame = 0; + ref_frame = pred_frame = 0; last_poc = max_last_poc = max_last_b_poc = prev_last_poc = 0; - max_total_delay = max_delay = 0; + max_total_delay = 0; gf_isom_set_cts_packing(import->dest, track, 1); has_cts_offset = 0; poc_diff = 0; min_poc = 0; poc_shift = 0; + prev_is_nalu_prefix = 0; while (gf_bs_available(bs)) { - u8 nal_hdr, skip_nal; + u8 nal_hdr, skip_nal, is_subseq, add_sps; nal_size = AVC_NextStartCode(bs); if (nal_size>max_size) { - buffer = (char*)realloc(buffer, sizeof(char)*nal_size); + buffer = (char*)gf_realloc(buffer, sizeof(char)*nal_size); max_size = nal_size; } + + /*read the file, and work on a memory buffer*/ gf_bs_read_data(bs, buffer, nal_size); - gf_bs_seek(bs, nal_start); + gf_bs_seek(bs, nal_start); nal_hdr = gf_bs_read_u8(bs); nal_type = nal_hdr & 0x1F; + is_subseq = 0; skip_nal = 0; copy_size = flush_sample = 0; + + if (nal_type == GF_AVC_NALU_SVC_SUBSEQ_PARAM || nal_type == GF_AVC_NALU_SVC_PREFIX_NALU || nal_type == GF_AVC_NALU_SVC_SLICE){ + avc.is_svc = 1; + } + switch (AVC_ParseNALU(bs, nal_hdr, &avc)) { case 1: flush_sample = 1; @@ -3711,97 +3867,217 @@ restart_import: default: break; } - - if (AVC_NALUIsSlice(nal_type)) { - if (! skip_nal) { - copy_size = nal_size; - switch (avc.s_info.slice_type) { - case GF_AVC_TYPE_P: case GF_AVC_TYPE2_P: nb_p++; break; - case GF_AVC_TYPE_I: case GF_AVC_TYPE2_I: nb_i++; break; - case GF_AVC_TYPE_B: case GF_AVC_TYPE2_B: nb_b++; break; - case GF_AVC_TYPE_SP: case GF_AVC_TYPE2_SP: nb_sp++; break; - case GF_AVC_TYPE_SI: case GF_AVC_TYPE2_SI: nb_si++; break; - } - } - } else { - switch (nal_type) { - case GF_AVC_NALU_SEQ_PARAM: - idx = AVC_ReadSeqInfo(bs, &avc, NULL); - if (idx<0) { + if (prev_is_nalu_prefix) flush_sample = 0; + prev_is_nalu_prefix=0; + + 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); + if (idx<0) { + if (avc.sps[0].profile_idc) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("Error parsing SeqInfo")); + } else { e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Error parsing SeqInfo"); goto exit; } - if (avc.sps[idx].status==1) { - avc.sps[idx].status = 2; - avccfg->configurationVersion = 1; - avccfg->profile_compatibility = avc.sps[idx].prof_compat; - avccfg->AVCProfileIndication = avc.sps[idx].profile_idc; - avccfg->AVCLevelIndication = avc.sps[idx].level_idc; - slc = (GF_AVCConfigSlot*)malloc(sizeof(GF_AVCConfigSlot)); - slc->size = nal_size; - slc->data = (char*)malloc(sizeof(char)*slc->size); - memcpy(slc->data, buffer, sizeof(char)*slc->size); - gf_list_add(avccfg->sequenceParameterSets, slc); - /*disable frame rate scan, most bitstreams have wrong values there*/ - if (detect_fps && avc.sps[idx].timing_info_present_flag && avc.sps[idx].fixed_frame_rate_flag - /*if detected FPS is greater than 50, assume wrong timing info*/ - && (avc.sps[idx].time_scale <= 50*avc.sps[idx].num_units_in_tick) - ) { - timescale = avc.sps[idx].time_scale; - dts_inc = avc.sps[idx].num_units_in_tick; - FPS = (Double)timescale / dts_inc; - detect_fps = 0; - gf_isom_remove_track(import->dest, track); - if (sample_data) gf_bs_del(sample_data); - gf_odf_avc_cfg_del(avccfg); - avccfg = NULL; - free(buffer); - buffer = NULL; - gf_bs_del(bs); - bs = NULL; - gf_f64_seek(mdia, 0, SEEK_SET); - goto restart_import; + } + add_sps = 0; + dstcfg = (import->flags & GF_IMPORT_SVC_EXPLICIT) ? svccfg : avccfg; + if (is_subseq) { + if ((avc.sps[idx].state & AVC_SUBSPS_PARSED) && !(avc.sps[idx].state & AVC_SUBSPS_DECLARED)) { + avc.sps[idx].state |= AVC_SUBSPS_DECLARED; + add_sps = 1; + } + dstcfg = svccfg; + } else { + if ((avc.sps[idx].state & AVC_SPS_PARSED) && !(avc.sps[idx].state & AVC_SPS_DECLARED)) { + avc.sps[idx].state |= AVC_SPS_DECLARED; + add_sps = 1; + } + } + /*some streams are not really nice and reuse sps idx with differnet parameters (typically + 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 (add_sps) { + dstcfg->configurationVersion = 1; + dstcfg->profile_compatibility = avc.sps[idx].prof_compat; + dstcfg->AVCProfileIndication = avc.sps[idx].profile_idc; + dstcfg->AVCLevelIndication = avc.sps[idx].level_idc; + 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); + 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) + ) { + /*ISO/IEC 14496-10 n11084 Table E-6*/ + u8 DeltaTfiDivisorTable[] = {1,1,1,2,2,2,2,3,3,4,6}; + u8 DeltaTfiDivisorIdx; + if (!avc.sps[idx].vui.pic_struct_present_flag) { + DeltaTfiDivisorIdx = 1 + (1-avc.s_info.field_pic_flag); + } else { + if (!avc.sei.pic_timing.pic_struct) + DeltaTfiDivisorIdx = 2; + else if (avc.sei.pic_timing.pic_struct == 8) + DeltaTfiDivisorIdx = 6; + else + DeltaTfiDivisorIdx = (avc.sei.pic_timing.pic_struct+1) / 2; } - if (!idx) { - gf_import_message(import, GF_OK, "AVC-H264 import - frame size %d x %d at %02.3f FPS", avc.sps[idx].width, avc.sps[idx].height, FPS); + timescale = 2 * avc.sps[idx].vui.time_scale; + dts_inc = 2 * avc.sps[idx].vui.num_units_in_tick * DeltaTfiDivisorIdx; + FPS = (Double)timescale / dts_inc; + detect_fps = 0; + gf_isom_remove_track(import->dest, track); + if (sample_data) gf_bs_del(sample_data); + gf_odf_avc_cfg_del(avccfg); + avccfg = NULL; + gf_odf_avc_cfg_del(svccfg); + svccfg = NULL; + gf_free(buffer); + buffer = NULL; + gf_bs_del(bs); + bs = NULL; + gf_f64_seek(mdia, 0, SEEK_SET); + goto restart_import; + } + + if (is_subseq) { + if (last_svc_sps<(u32) idx) { + if (import->flags & GF_IMPORT_SVC_EXPLICIT) { + gf_import_message(import, GF_OK, "SVC-H264 import - frame size %d x %d at %02.3f FPS", avc.sps[idx].width, avc.sps[idx].height, FPS); + } else { + gf_import_message(import, GF_OK, "SVC Detected - frame size %d x %d", avc.sps[idx].width, avc.sps[idx].height); + } + last_svc_sps = idx; } + } else { + if (first_avc) { + first_avc = 0; + if (!(import->flags & GF_IMPORT_SVC_EXPLICIT)) { + gf_import_message(import, GF_OK, "AVC-H264 import - frame size %d x %d at %02.3f FPS", avc.sps[idx].width, avc.sps[idx].height, FPS); + } + } + } + if (!is_subseq || (import->flags & GF_IMPORT_SVC_EXPLICIT)) { if ((max_w <= avc.sps[idx].width) && (max_h <= avc.sps[idx].height)) { max_w = avc.sps[idx].width; max_h = avc.sps[idx].height; } } - break; - case GF_AVC_NALU_PIC_PARAM: - idx = AVC_ReadPictParamSet(bs, &avc); - if (idx<0) { - e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Error parsing Picture Param"); - goto exit; + } + break; + case GF_AVC_NALU_PIC_PARAM: + idx = AVC_ReadPictParamSet(buffer+1/*skip NALU type*/, nal_size-1, &avc); + if (idx<0) { + e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Error parsing Picture Param"); + goto exit; + } + /*some streams are not really nice and reuse sps idx with differnet parameters (typically + 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.pps[idx].status == 2) { + copy_size = nal_size; + } + + if (avc.pps[idx].status==1) { + avc.pps[idx].status = 2; + 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); + dstcfg = (import->flags & GF_IMPORT_SVC_EXPLICIT) ? svccfg : avccfg; + + /* by default, we put all PPS in the base AVC layer, + they will be moved to the SVC layer upon analysis of SVC slice. */ + dstcfg = avccfg; + + gf_list_add(dstcfg->pictureParameterSets, slc); + } + break; + case GF_AVC_NALU_SEI: + if (avc.sps_active_idx != -1) { + copy_size = AVC_ReformatSEI_NALU(buffer, nal_size, &avc); + if (copy_size) { + nal_size = copy_size; /*nal_size has been modified in memory*/ + nb_sei++; } - if (avc.pps[idx].status==1) { - avc.pps[idx].status = 2; - slc = (GF_AVCConfigSlot*)malloc(sizeof(GF_AVCConfigSlot)); - slc->size = nal_size; - slc->data = (char*)malloc(sizeof(char)*slc->size); - memcpy(slc->data, buffer, sizeof(char)*slc->size); - gf_list_add(avccfg->pictureParameterSets, slc); + } + break; + + case GF_AVC_NALU_NON_IDR_SLICE: + case GF_AVC_NALU_DP_A_SLICE: + case GF_AVC_NALU_DP_B_SLICE: + case GF_AVC_NALU_DP_C_SLICE: + case GF_AVC_NALU_IDR_SLICE: + if (! skip_nal) { + copy_size = nal_size; + switch (avc.s_info.slice_type) { + case GF_AVC_TYPE_P: case GF_AVC_TYPE2_P: nb_p++; break; + case GF_AVC_TYPE_I: case GF_AVC_TYPE2_I: nb_i++; break; + case GF_AVC_TYPE_B: case GF_AVC_TYPE2_B: nb_b++; break; + case GF_AVC_TYPE_SP: case GF_AVC_TYPE2_SP: nb_sp++; break; + case GF_AVC_TYPE_SI: case GF_AVC_TYPE2_SI: nb_si++; break; } - break; - case GF_AVC_NALU_SEI: - copy_size = AVC_ReformatSEI_NALU(buffer, nal_size, &avc); - if (copy_size) nb_sei++; - break; - /*remove*/ - case GF_AVC_NALU_ACCESS_UNIT: - case GF_AVC_NALU_FILLER_DATA: - case GF_AVC_NALU_END_OF_SEQ: - case GF_AVC_NALU_END_OF_STREAM: - break; - default: - gf_import_message(import, GF_OK, "WARNING: NAL Unit type %d not handled - adding", nal_type); + } + break; + + /*remove*/ + case GF_AVC_NALU_ACCESS_UNIT: + case GF_AVC_NALU_FILLER_DATA: + case GF_AVC_NALU_END_OF_SEQ: + case GF_AVC_NALU_END_OF_STREAM: + break; + + case GF_AVC_NALU_SVC_PREFIX_NALU: + if (import->flags & GF_IMPORT_SVC_NONE) break; + copy_size = nal_size; + prev_is_nalu_prefix = 1; + break; + case GF_AVC_NALU_SVC_SLICE: + { + u32 i; + for (i = 0; i < gf_list_count(avccfg->pictureParameterSets); i ++) { + slc = gf_list_get(avccfg->pictureParameterSets, i); + if (avc.s_info.pps->id == slc->id) { + /* This PPS is used by an SVC NAL unit, it should be moved to the SVC Config Record) */ + gf_list_rem(avccfg->pictureParameterSets, i); + i--; + gf_list_add(svccfg->pictureParameterSets, slc); + } + } + } + if (import->flags & GF_IMPORT_SVC_NONE) break; + if (! skip_nal) { copy_size = nal_size; - break; + switch (avc.s_info.slice_type) { + case GF_AVC_TYPE_P: case GF_AVC_TYPE2_P: nb_ep++; break; + case GF_AVC_TYPE_I: case GF_AVC_TYPE2_I: nb_ei++; break; + case GF_AVC_TYPE_B: case GF_AVC_TYPE2_B: nb_eb++; break; + } } + break; + + case GF_AVC_NALU_SEQ_PARAM_EXT: + case GF_AVC_NALU_SLICE_AUX: + + default: + gf_import_message(import, GF_OK, "WARNING: NAL Unit type %d not handled - adding", nal_type); + copy_size = nal_size; + break; } + if (!nal_size) break; if (flush_sample && sample_data) { @@ -3811,10 +4087,10 @@ restart_import: gf_bs_get_content(sample_data, &samp->data, &samp->dataLength); gf_bs_del(sample_data); sample_data = NULL; - /*CTS recomuting is much trickier than with MPEG-4 ASP due to b-slice used as references - we therefore - store the poc as the CTS offset and update the whole table at the end*/ + /*CTS recomuting is much trickier than with MPEG-4 ASP due to b-slice used as references - we therefore + store the POC as the CTS offset and update the whole table at the end*/ samp->CTS_Offset = last_poc - poc_shift; - assert(samp->CTS_Offset>=0); + assert(last_poc >= poc_shift); e = gf_isom_add_sample(import->dest, track, di, samp); if (e) goto exit; @@ -3823,7 +4099,7 @@ restart_import: gf_set_progress("Importing AVC-H264", (u32) (nal_start/1024), (u32) (total_size/1024) ); first_nal = 1; - if (min_poc > last_poc) + if (min_poc > last_poc) min_poc = last_poc; } @@ -3836,7 +4112,7 @@ restart_import: gf_import_message(import, GF_OK, "Adjusting AVC SizeLength to %d bits", size_length+diff_size); avc_rewrite_samples(import->dest, track, size_length, size_length+diff_size); - + /*rewrite current sample*/ if (sample_data) { char *sd; @@ -3850,13 +4126,13 @@ restart_import: char *buf; u32 s = gf_bs_read_int(prev_sd, size_length); gf_bs_write_int(sample_data, s, size_length+diff_size); - buf = (char*)malloc(sizeof(char)*s); + buf = (char*)gf_malloc(sizeof(char)*s); gf_bs_read_data(prev_sd, buf, s); gf_bs_write_data(sample_data, buf, s); - free(buf); + gf_free(buf); } gf_bs_del(prev_sd); - free(sd); + gf_free(sd); } size_length+=diff_size; @@ -3864,7 +4140,15 @@ restart_import: if (!sample_data) sample_data = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); gf_bs_write_int(sample_data, copy_size, size_length); gf_bs_write_data(sample_data, buffer, copy_size); - if (AVC_NALUIsSlice(nal_type) ) { + + switch (nal_type) { + case GF_AVC_NALU_NON_IDR_SLICE: + case GF_AVC_NALU_DP_A_SLICE: + case GF_AVC_NALU_DP_B_SLICE: + case GF_AVC_NALU_DP_C_SLICE: + case GF_AVC_NALU_IDR_SLICE: + case GF_AVC_NALU_SLICE_AUX: +// case GF_AVC_NALU_SVC_SLICE: if (!is_paff && avc.s_info.bottom_field_flag) is_paff = 1; @@ -3896,8 +4180,8 @@ restart_import: /*if #pics, compute smallest POC increase*/ if (avc.s_info.poc != last_poc) { - if (!poc_diff || (poc_diff > abs(avc.s_info.poc-last_poc))) - poc_diff = abs(avc.s_info.poc-last_poc); + if (!poc_diff || (poc_diff > abs(avc.s_info.poc-last_poc))) + poc_diff = abs(avc.s_info.poc-last_poc); /*ideally we would need to start the parsing again as poc_diff helps computing max_total_delay*/ last_poc = avc.s_info.poc; } /*ref slice, reset poc*/ @@ -3905,51 +4189,47 @@ restart_import: ref_frame = cur_samp+1; max_last_poc = last_poc = max_last_b_poc = 0; pred_frame = 0; - b_frames = 0; - max_delay = 0; poc_shift = 0; } /*strictly less - this is a new P slice*/ else if (max_last_poclast_poc) { /*need to store TS offsets*/ has_cts_offset = 1; switch (avc.s_info.slice_type) { - case GF_AVC_TYPE_B: + case GF_AVC_TYPE_B: case GF_AVC_TYPE2_B: if (!max_last_b_poc) { - b_frames ++; max_last_b_poc = last_poc; } - /*we had a B-slice reference*/ - else if (last_pocmax_last_b_poc) { + max_last_b_poc = last_poc; + } + /*otherwise we had a B-slice reference: do nothing*/ - max_last_b_poc = last_poc; break; } } + + /*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) { + max_total_delay = cur_samp - (ref_frame-1) - last_poc/poc_diff; + } } } gf_bs_align(bs); nal_end = gf_bs_get_position(bs); - if (nal_end != nal_start + nal_size) gf_bs_seek(bs, nal_start + nal_size); + assert(nal_start <= nal_end); + assert(nal_end <= nal_start + nal_size); + if (nal_end != nal_start + nal_size) + gf_bs_seek(bs, nal_start + nal_size); if (!gf_bs_available(bs)) break; if (duration && (dts_inc*cur_samp > duration)) break; @@ -3966,6 +4246,7 @@ restart_import: GF_ISOSample *samp = gf_isom_sample_new(); samp->DTS = dts_inc*cur_samp; samp->IsRAP = sample_is_rap; + /*we store the frame order (based on the POC) as the CTS offset and update the whole table at the end*/ samp->CTS_Offset = last_poc - poc_shift; gf_bs_get_content(sample_data, &samp->data, &samp->dataLength); gf_bs_del(sample_data); @@ -3998,10 +4279,11 @@ restart_import: /*not using descIdx and data_offset will only fecth DTS, CTS and RAP which is all we need*/ GF_ISOSample *samp = gf_isom_get_sample_info(import->dest, track, i+1, NULL, NULL); /*poc re-init (RAP and POC to 0, otherwise that's SEI recovery), update base DTS*/ - if (samp->IsRAP /*&& !samp->CTS_Offset*/) last_dts = samp->DTS; + if (samp->IsRAP /*&& !samp->CTS_Offset*/) + last_dts = samp->DTS * (1+is_paff); /*CTS offset is frame POC (refers to last IDR)*/ - cts = (min_poc + (s32) samp->CTS_Offset) * dts_inc/poc_diff + (u32) (last_dts + max_total_delay*dts_inc); + cts = (min_poc + (s32) samp->CTS_Offset) * dts_inc/poc_diff + (u32) last_dts; /*if PAFF, 2 pictures (eg poc) <=> 1 aggregated frame (eg sample), divide by 2*/ if (is_paff) { @@ -4011,6 +4293,10 @@ restart_import: cts = ((cts/dts_inc)+1)*dts_inc; } } + + /*B-frames offset*/ + cts += (u32) (max_total_delay*dts_inc); + samp->CTS_Offset = (u32) (cts - samp->DTS); if (max_cts < samp->DTS + samp->CTS_Offset) { @@ -4052,7 +4338,16 @@ restart_import: gf_isom_set_visual_info(import->dest, track, di, max_w, max_h); avccfg->nal_unit_size = size_length/8; - gf_isom_avc_config_update(import->dest, track, 1, avccfg); + svccfg->nal_unit_size = size_length/8; + + if (gf_list_count(avccfg->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); + } + } else { + gf_isom_svc_config_update(import->dest, track, 1, svccfg, 0); + } gf_media_update_par(import->dest, track); MP4T_RecomputeBitRate(import->dest, track); @@ -4060,13 +4355,16 @@ restart_import: gf_isom_modify_alternate_brand(import->dest, GF_ISOM_BRAND_AVC1, 1); if (nb_sp || nb_si) { - gf_import_message(import, GF_OK, "Import results: %d samples - Slices: %d I %d P %d B %d SP %d SI - %d SEI - %d IDR", + gf_import_message(import, GF_OK, "Import results: %d samples - Slices: %d I %d P %d B %d SP %d SI - %d SEI - %d IDR", cur_samp, nb_i, nb_p, nb_b, nb_sp, nb_si, nb_sei, nb_idr); } else { - gf_import_message(import, GF_OK, "Import results: %d samples - Slices: %d I %d P %d B - %d SEI - %d IDR", + gf_import_message(import, GF_OK, "Import results: %d samples - Slices: %d I %d P %d B - %d SEI - %d IDR", cur_samp, nb_i, nb_p, nb_b, nb_sei, nb_idr); } + if (nb_ei || nb_ep) + gf_import_message(import, GF_OK, "SVC Import results: Slices: %d I %d P %d B", nb_ei, nb_ep, nb_eb); + if (max_total_delay>1) { gf_import_message(import, GF_OK, "\tStream uses B-slice references - max frame delay %d", max_total_delay); } @@ -4084,11 +4382,17 @@ restart_import: exit: if (sample_data) gf_bs_del(sample_data); gf_odf_avc_cfg_del(avccfg); - free(buffer); + gf_odf_avc_cfg_del(svccfg); + gf_free(buffer); gf_bs_del(bs); fclose(mdia); return e; } + +#endif /*GPAC_DISABLE_AV_PARSERS*/ + +#ifndef GPAC_DISABLE_OGG + #define OGG_BUFFER_SIZE 4096 Bool OGG_ReadPage(FILE *f_in, ogg_sync_state *oy, ogg_page *oggpage) @@ -4096,7 +4400,7 @@ Bool OGG_ReadPage(FILE *f_in, ogg_sync_state *oy, ogg_page *oggpage) if (feof(f_in)) return 0; while (ogg_sync_pageout(oy, oggpage ) != 1 ) { char *buffer = ogg_sync_buffer(oy, OGG_BUFFER_SIZE); - u32 bytes = fread(buffer, 1, OGG_BUFFER_SIZE, f_in); + u32 bytes = fread(buffer, sizeof(char), OGG_BUFFER_SIZE, f_in); ogg_sync_wrote(oy, bytes); if (feof(f_in)) return 1; } @@ -4105,7 +4409,7 @@ Bool OGG_ReadPage(FILE *f_in, ogg_sync_state *oy, ogg_page *oggpage) static u32 get_ogg_serial_no_for_stream(char *fileName, u32 stream_num, Bool is_video) { - ogg_sync_state oy; + ogg_sync_state oy; u32 track, serial_no; ogg_page oggpage; ogg_packet oggpacket; @@ -4133,11 +4437,11 @@ static u32 get_ogg_serial_no_for_stream(char *fileName, u32 stream_num, Bool is_ ogg_stream_packetpeek(&os, &oggpacket); if (is_video && (oggpacket.bytes >= 7) && !strncmp((char *)&oggpacket.packet[1], "theora", 6)) { - ogg_stream_clear(&os); + ogg_stream_clear(&os); break; } if (!is_video && (oggpacket.bytes >= 7) && !strncmp((char *)&oggpacket.packet[1], "vorbis", 6)) { - ogg_stream_clear(&os); + ogg_stream_clear(&os); break; } ogg_stream_clear(&os); @@ -4151,7 +4455,7 @@ static u32 get_ogg_serial_no_for_stream(char *fileName, u32 stream_num, Bool is_ GF_Err gf_import_ogg_video(GF_MediaImporter *import) { GF_Err e; - ogg_sync_state oy; + ogg_sync_state oy; u32 di, track, duration; u64 tot_size, done; u32 w, h, fps_num, fps_den, keyframe_freq_force, theora_kgs, flag, dts_inc, timescale; @@ -4175,7 +4479,7 @@ GF_Err gf_import_ogg_video(GF_MediaImporter *import) import->nb_tracks = 0; go = 1; - ogg_sync_init(&oy); + ogg_sync_init(&oy); while (go) { if (!OGG_ReadPage(f_in, &oy, &oggpage)) break; @@ -4211,7 +4515,7 @@ GF_Err gf_import_ogg_video(GF_MediaImporter *import) ogg_stream_clear(&os); import->nb_tracks++; } - ogg_sync_clear(&oy); + ogg_sync_clear(&oy); fclose(f_in); return GF_OK; } @@ -4234,13 +4538,13 @@ GF_Err gf_import_ogg_video(GF_MediaImporter *import) destroy_esd = 0; samp = gf_isom_sample_new(); - + /*avoids gcc warnings*/ duration = 0; FPS = 0; num_headers = w = h = track = 0; - ogg_sync_init(&oy); + ogg_sync_init(&oy); bs = NULL; serial_no = 0; @@ -4285,7 +4589,7 @@ GF_Err gf_import_ogg_video(GF_MediaImporter *import) } gf_bs_del(bs); - FPS = ((Double)fps_num) / fps_den; + FPS = ((Double)fps_num) / fps_den; /*note that we don't rewrite theora headers (just like in MPEG-4 video, systems timing overrides stream one)*/ if (import->video_fps) FPS = import->video_fps; @@ -4298,8 +4602,8 @@ GF_Err gf_import_ogg_video(GF_MediaImporter *import) /*FIXME - check end of stream for concatenated files?*/ /*not our stream*/ - if (ogg_stream_pagein(&os, &oggpage) != 0) continue; - + if (ogg_stream_pagein(&os, &oggpage) != 0) continue; + while (ogg_stream_packetout(&os, &oggpacket ) > 0 ) { @@ -4346,11 +4650,11 @@ GF_Err gf_import_ogg_video(GF_MediaImporter *import) duration = (u32) d; } } - + continue; } - - /*we don't need adedicated parser for theora, just check it's a theora frame and get its key type + + /*we don't need adedicated parser for theora, just check it's a theora frame and get its key type WATCHOUT theora bitsteram is in BE*/ oggpackB_readinit(&opb, oggpacket.packet, oggpacket.bytes); flag = oggpackB_read(&opb, 1); @@ -4381,12 +4685,12 @@ GF_Err gf_import_ogg_video(GF_MediaImporter *import) gf_isom_set_pl_indication(import->dest, GF_ISOM_PL_VISUAL, 0xFE); } - + exit: if (bs) gf_bs_del(bs); samp->data = NULL; gf_isom_sample_del(&samp); - ogg_sync_clear(&oy); + ogg_sync_clear(&oy); if (serial_no) ogg_stream_clear(&os); if (import->esd && destroy_esd) { gf_odf_desc_del((GF_Descriptor *) import->esd); @@ -4398,8 +4702,12 @@ exit: GF_Err gf_import_ogg_audio(GF_MediaImporter *import) { +#if defined(GPAC_DISABLE_AV_PARSERS) + return GF_NOT_SUPPORTED; +#else + GF_Err e; - ogg_sync_state oy; + ogg_sync_state oy; u32 di, track, duration; u64 done, tot_size; s32 block_size; @@ -4436,7 +4744,7 @@ GF_Err gf_import_ogg_audio(GF_MediaImporter *import) /*avoids gcc warnings*/ track = num_headers = duration = 0; - ogg_sync_init(&oy); + ogg_sync_init(&oy); vbs = NULL; serial_no = 0; @@ -4469,15 +4777,15 @@ GF_Err gf_import_ogg_audio(GF_MediaImporter *import) /*FIXME - check end of stream for concatenated files?*/ /*not our stream*/ - if (ogg_stream_pagein(&os, &oggpage) != 0) continue; - + if (ogg_stream_pagein(&os, &oggpage) != 0) continue; + while (ogg_stream_packetout(&os, &oggpacket ) > 0 ) { if (num_headers<3) { if (!gf_vorbis_parse_header(&vp, (char*)oggpacket.packet, oggpacket.bytes)) { e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Corrupted OGG Vorbis header"); - goto exit; + goto exit; } /*copy headers*/ @@ -4489,7 +4797,7 @@ GF_Err gf_import_ogg_audio(GF_MediaImporter *import) if (num_headers==3) { if (!vp.is_init) { e = gf_import_message(import, GF_NON_COMPLIANT_BITSTREAM, "Corrupted OGG Vorbis headers found"); - goto exit; + goto exit; } gf_import_message(import, GF_OK, "OGG Vorbis import - sample rate %d - %d channel%s", vp.sample_rate, vp.channels, (vp.channels>1) ? "s" : ""); @@ -4528,7 +4836,7 @@ GF_Err gf_import_ogg_audio(GF_MediaImporter *import) } continue; } - + block_size = gf_vorbis_check_frame(&vp, (char *)oggpacket.packet, oggpacket.bytes); if (!block_size) continue; @@ -4559,25 +4867,29 @@ GF_Err gf_import_ogg_audio(GF_MediaImporter *import) MP4T_RecomputeBitRate(import->dest, track); } - + exit: gf_isom_sample_del(&samp); if (vbs) gf_bs_del(vbs); if (serial_no) ogg_stream_clear(&os); - ogg_sync_clear(&oy); + ogg_sync_clear(&oy); if (import->esd && destroy_esd) { gf_odf_desc_del((GF_Descriptor *) import->esd); import->esd = NULL; } fclose(f_in); return e; +#endif /*defined(GPAC_DISABLE_AV_PARSERS) */ } +#endif /*GPAC_DISABLE_OGG*/ + + GF_Err gf_import_raw_unit(GF_MediaImporter *import) { GF_Err e; GF_ISOSample *samp; - u32 mtype, track, di, timescale; + u32 mtype, track, di, timescale, readen; FILE *src; if (import->flags & GF_IMPORT_PROBE_ONLY) { @@ -4589,7 +4901,7 @@ GF_Err gf_import_raw_unit(GF_MediaImporter *import) return gf_import_message(import, GF_BAD_PARAM, "Raw stream needs ESD and DecoderConfig for import"); } - src = fopen(import->in_name, "rb"); + src = gf_f64_open(import->in_name, "rb"); if (!src) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name); switch (import->esd->decoderConfig->streamType) { @@ -4623,12 +4935,14 @@ GF_Err gf_import_raw_unit(GF_MediaImporter *import) gf_import_message(import, GF_OK, "Raw Access Unit import (StreamType %s)", gf_odf_stream_type_name(import->esd->decoderConfig->streamType)); samp = gf_isom_sample_new(); - fseek(src, 0, SEEK_END); - samp->dataLength = ftell(src); - fseek(src, 0, SEEK_SET); + gf_f64_seek(src, 0, SEEK_END); + assert(gf_f64_tell(src) < 1<<31); + samp->dataLength = (u32) gf_f64_tell(src); + gf_f64_seek(src, 0, SEEK_SET); samp->IsRAP = 1; - samp->data = (char *)malloc(sizeof(char)*samp->dataLength); - fread(samp->data, samp->dataLength, 1, src); + samp->data = (char *)gf_malloc(sizeof(char)*samp->dataLength); + readen = fread(samp->data, sizeof(char), samp->dataLength, src); + assert( readen == samp->dataLength ); e = gf_isom_add_sample(import->dest, track, di, samp); gf_isom_sample_del(&samp); MP4T_RecomputeBitRate(import->dest, track); @@ -4639,22 +4953,23 @@ exit: GF_Err gf_import_saf(GF_MediaImporter *import) -{ +{ GF_Err e; - u32 track, tot; + u32 track; + u64 tot; FILE *saf; GF_BitStream *bs; if (import->flags & GF_IMPORT_PROBE_ONLY) { import->flags |= GF_IMPORT_USE_DATAREF; } - saf = fopen(import->in_name, "rb"); + saf = gf_f64_open(import->in_name, "rb"); if (!saf) return gf_import_message(import, GF_URL_ERROR, "Opening file %s failed", import->in_name); track = 0; bs = gf_bs_from_file(saf, GF_BITSTREAM_READ); - tot = (u32) gf_bs_get_size(bs); + tot = gf_bs_get_size(bs); while (gf_bs_available(bs)) { Bool is_rap; @@ -4673,7 +4988,7 @@ GF_Err gf_import_saf(GF_MediaImporter *import) stream_id = gf_bs_read_int(bs, 12); au_size-=2; if (!stream_id) stream_id = 1000; - + if ((type==1) || (type==2) || (type==7)) { Bool in_root_od = 0; u32 mtype, stype; @@ -4689,31 +5004,37 @@ GF_Err gf_import_saf(GF_MediaImporter *import) au_size -= 7; - mtype = GF_ISOM_MEDIA_ESM; + mtype = GF_ISOM_MEDIA_ESM; stype = 0; - if (st==GF_STREAM_SCENE) { - mtype = GF_ISOM_MEDIA_SCENE; - name = (char *) ( (oti==0x09) ? "LASeR Scene" : "BIFS Scene" ); - stype = (oti==0x09) ? GF_4CC('L','A','S','R') : GF_4CC('B','I','F','S'); + if (st==GF_STREAM_SCENE) { + mtype = GF_ISOM_MEDIA_SCENE; + name = (char *) ( (oti==GPAC_OTI_SCENE_LASER) ? "LASeR Scene" : "BIFS Scene" ); + stype = (oti==GPAC_OTI_SCENE_LASER) ? GF_4CC('L','A','S','R') : GF_4CC('B','I','F','S'); in_root_od = 1; } - else if (st==GF_STREAM_VISUAL) { - mtype = GF_ISOM_MEDIA_VISUAL; + else if (st==GF_STREAM_VISUAL) { + mtype = GF_ISOM_MEDIA_VISUAL; switch (oti) { - case 0x21: name = "AVC/H264 Video"; stype = GF_4CC('H','2','6','4'); break; - case 0x20: name = "MPEG-4 Video"; stype = GF_4CC('M','P','4','V'); break; - case 0x6A: name = "MPEG-1 Video"; stype = GF_4CC('M','P','1','V'); break; - case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: name = "MPEG-2 Video"; stype = GF_4CC('M','P','2','V'); break; - case 0x6C: name = "JPEG Image"; stype = GF_4CC('J','P','E','G'); break; - case 0x6D: name = "PNG Image"; stype = GF_4CC('P','N','G',' '); break; + case GPAC_OTI_VIDEO_AVC: name = "AVC/H264 Video"; stype = GF_4CC('H','2','6','4'); break; + case GPAC_OTI_VIDEO_MPEG4_PART2: name = "MPEG-4 Video"; stype = GF_4CC('M','P','4','V'); break; + case GPAC_OTI_VIDEO_MPEG1: name = "MPEG-1 Video"; stype = GF_4CC('M','P','1','V'); break; + case GPAC_OTI_VIDEO_MPEG2_SIMPLE: + case GPAC_OTI_VIDEO_MPEG2_MAIN: + case GPAC_OTI_VIDEO_MPEG2_SNR: + case GPAC_OTI_VIDEO_MPEG2_SPATIAL: + case GPAC_OTI_VIDEO_MPEG2_HIGH: + case GPAC_OTI_VIDEO_MPEG2_422: + name = "MPEG-2 Video"; stype = GF_4CC('M','P','2','V'); break; + case GPAC_OTI_IMAGE_JPEG: name = "JPEG Image"; stype = GF_4CC('J','P','E','G'); break; + case GPAC_OTI_IMAGE_PNG: name = "PNG Image"; stype = GF_4CC('P','N','G',' '); break; } } - else if (st==GF_STREAM_AUDIO) { + else if (st==GF_STREAM_AUDIO) { mtype = GF_ISOM_MEDIA_AUDIO; switch (oti) { - case 0x69: name = "MPEG-2 Audio"; stype = GF_4CC('M','P','2','A'); break; - case 0x6B: name = "MPEG-1 Audio"; stype = GF_4CC('M','P','1','A'); break; - case 0x40: name = "MPEG-4 Audio"; stype = GF_4CC('M','P','4','A'); break; + case GPAC_OTI_AUDIO_MPEG2_PART3: name = "MPEG-2 Audio"; stype = GF_4CC('M','P','2','A'); break; + case GPAC_OTI_AUDIO_MPEG1: name = "MPEG-1 Audio"; stype = GF_4CC('M','P','1','A'); break; + case GPAC_OTI_AUDIO_AAC_MPEG4: name = "MPEG-4 Audio"; stype = GF_4CC('M','P','4','A'); break; } } @@ -4736,7 +5057,7 @@ GF_Err gf_import_saf(GF_MediaImporter *import) if (!import->esd) { import->esd = gf_odf_desc_esd_new(0); delete_esd = 1; - if (import->esd->URLString) free(import->esd->URLString); + if (import->esd->URLString) gf_free(import->esd->URLString); import->esd->URLString = NULL; } import->esd->decoderConfig->streamType = st; @@ -4747,16 +5068,16 @@ GF_Err gf_import_saf(GF_MediaImporter *import) } if (type==7) { u32 url_len = gf_bs_read_u16(bs); - import->esd->URLString = (char *)malloc(sizeof(char)*(url_len+1)); + import->esd->URLString = (char *)gf_malloc(sizeof(char)*(url_len+1)); gf_bs_read_data(bs, import->esd->URLString, url_len); import->esd->URLString[url_len] = 0; au_size-=2+url_len; } if (au_size) { if (!import->esd->decoderConfig->decoderSpecificInfo) import->esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - if (import->esd->decoderConfig->decoderSpecificInfo->data ) free(import->esd->decoderConfig->decoderSpecificInfo->data); + if (import->esd->decoderConfig->decoderSpecificInfo->data ) gf_free(import->esd->decoderConfig->decoderSpecificInfo->data); import->esd->decoderConfig->decoderSpecificInfo->dataLength = au_size; - import->esd->decoderConfig->decoderSpecificInfo->data = (char *)malloc(sizeof(char)*au_size); + import->esd->decoderConfig->decoderSpecificInfo->data = (char *)gf_malloc(sizeof(char)*au_size); gf_bs_read_data(bs, import->esd->decoderConfig->decoderSpecificInfo->data, au_size); au_size = 0; } @@ -4781,7 +5102,7 @@ GF_Err gf_import_saf(GF_MediaImporter *import) if (import->flags & GF_IMPORT_USE_DATAREF) { e = gf_isom_add_sample_reference(import->dest, track, 1, samp, gf_bs_get_position(bs) ); } else { - samp->data = (char *)malloc(sizeof(char)*samp->dataLength); + samp->data = (char *)gf_malloc(sizeof(char)*samp->dataLength); gf_bs_read_data(bs, samp->data, samp->dataLength); au_size = 0; e = gf_isom_add_sample(import->dest, track, 1, samp); @@ -4792,7 +5113,7 @@ GF_Err gf_import_saf(GF_MediaImporter *import) fclose(saf); return e; } - gf_set_progress("Importing SAF", (u32) gf_bs_get_position(bs), tot); + gf_set_progress("Importing SAF", gf_bs_get_position(bs), tot); } gf_bs_skip_bytes(bs, au_size); } @@ -4811,16 +5132,20 @@ typedef struct GF_MediaImporter *import; u32 track; u32 nb_i, nb_p, nb_b; + u64 last_dts; +#ifndef GPAC_DISABLE_AV_PARSERS GF_AVCConfig *avccfg; AVCState avc; +#endif Bool force_next_au_start; Bool stream_setup; } GF_TSImport; +#ifndef GPAC_DISABLE_MPEG2TS -/* Determine the ESD corresponding to the current track info based on the PID and sets the additional info +/* Determine the ESD corresponding to the current track info based on the PID and sets the additional info in the track info as described in this esd */ -static void m2ts_set_track_mpeg4_probe_info(GF_ESD *esd, +static void m2ts_set_track_mpeg4_probe_info(GF_M2TS_ES *es, GF_ESD *esd, struct __track_import_info* tk_info) { if (esd && tk_info) { @@ -4856,14 +5181,15 @@ static void m2ts_set_track_mpeg4_probe_info(GF_ESD *esd, tk_info->type = GF_ISOM_MEDIA_ESM; break; } + if (es) tk_info->mpeg4_es_id = es->mpeg4_es_id; } } static void m2ts_set_tracks_mpeg4_probe_info(GF_MediaImporter *import, GF_M2TS_Program *prog, GF_List *ESDescriptors) { - u32 i, k, esd_count, stream_count; - s32 tk_idx; - + u32 i, k, esd_count, stream_count; + s32 tk_idx; + esd_count = gf_list_count(ESDescriptors); stream_count = gf_list_count(prog->streams); for (k = 0; k < esd_count; k++) { @@ -4879,6 +5205,10 @@ static void m2ts_set_tracks_mpeg4_probe_info(GF_MediaImporter *import, GF_M2TS_P } if (es == NULL) continue; + if (esd->decoderConfig->streamType==GF_STREAM_OD) + es->flags |= GF_M2TS_ES_IS_MPEG4_OD; + + tk_idx = -1; for (i = 0; i < import->nb_tracks; i++) { if (import->tk_info[i].track_num == es->pid) { @@ -4890,7 +5220,7 @@ static void m2ts_set_tracks_mpeg4_probe_info(GF_MediaImporter *import, GF_M2TS_P if (tk_idx == -1) continue; if (import->tk_info[tk_idx].type != 0 && import->tk_info[tk_idx].type != GF_ISOM_MEDIA_ESM) continue; - m2ts_set_track_mpeg4_probe_info(esd, &import->tk_info[tk_idx]); + m2ts_set_track_mpeg4_probe_info(es, esd, &import->tk_info[tk_idx]); } } @@ -4898,7 +5228,7 @@ static void m2ts_set_tracks_mpeg4_probe_info(GF_MediaImporter *import, GF_M2TS_P static void m2ts_set_track_mpeg4_creation_info(GF_MediaImporter *import, u32 *mtype, u32 *stype, u32 *oti) { if (import->esd) { - *stype = import->esd->decoderConfig->streamType; + *stype = import->esd->decoderConfig->streamType; *oti = import->esd->decoderConfig->objectTypeIndication; switch (*stype) { case GF_STREAM_SCENE: @@ -4952,7 +5282,7 @@ static void m2ts_create_track(GF_TSImport *tsimp, u32 mtype, u32 stype, u32 oti, import->esd->decoderConfig->streamType = stype; import->esd->decoderConfig->objectTypeIndication = oti; import->esd->slConfig->timestampResolution = 90000; - + gf_isom_set_track_enabled(import->dest, tsimp->track, 1); if (!import->esd->ESID) import->esd->ESID = gf_isom_get_track_id(import->dest, tsimp->track); @@ -4968,41 +5298,7 @@ static void m2ts_create_track(GF_TSImport *tsimp, u32 mtype, u32 stype, u32 oti, } } -static GF_ESD *m2ts_get_esd(GF_M2TS_ES *es) -{ - GF_ESD *esd; - u32 k, esd_count; - - esd = NULL; - if (es->program->pmt_iod && es->program->pmt_iod->ESDescriptors) { - esd_count = gf_list_count(es->program->pmt_iod->ESDescriptors); - for (k = 0; k < esd_count; k++) { - GF_ESD *esd_tmp = (GF_ESD *)gf_list_get(es->program->pmt_iod->ESDescriptors, k); - if (esd_tmp->ESID != es->mpeg4_es_id) continue; - esd = esd_tmp; - break; - } - } - - if (!esd && es->program->additional_ods) { - u32 od_count, od_index; - od_count = gf_list_count(es->program->additional_ods); - for (od_index = 0; od_index < od_count; od_index++) { - GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(es->program->additional_ods, od_index); - esd_count = gf_list_count(od->ESDescriptors); - for (k = 0; k < esd_count; k++) { - GF_ESD *esd_tmp = (GF_ESD *)gf_list_get(od->ESDescriptors, k); - if (esd_tmp->ESID != es->mpeg4_es_id) continue; - esd = esd_tmp; - break; - } - } - } - - return esd; -} - -void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) +void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) { GF_Err e; GF_ISOSample *samp; @@ -5023,25 +5319,31 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) case GF_M2TS_EVT_PMT_REPEAT: /*abort upon first PMT repeat if not using 4on2. Otherwise we must parse the entire bitstream to locate ODs sent in OD updates in order to get their stream types...*/ - if (!ts->has_4on2 && (import->flags & GF_IMPORT_PROBE_ONLY) && !import->trackID) +/* if (!ts->has_4on2 && (import->flags & GF_IMPORT_PROBE_ONLY) && !import->trackID) import->flags |= GF_IMPORT_DO_ABORT; +*/ break; - case GF_M2TS_EVT_SDT_FOUND: + case GF_M2TS_EVT_PMT_UPDATE: + gf_import_message(import, GF_OK, "[MPEG-2 TS] PMT Update found - cannot import any further"); + import->flags |= GF_IMPORT_DO_ABORT; + break; + + /*case GF_M2TS_EVT_SDT_FOUND: import->nb_progs = gf_list_count(ts->SDTs); for (i=0; inb_progs; i++) { GF_M2TS_SDT *sdt = (GF_M2TS_SDT *)gf_list_get(ts->SDTs, i); strcpy(import->pg_info[i].name, sdt->service); import->pg_info[i].number = sdt->service_id; } - if (!ts->has_4on2 && import->flags & GF_IMPORT_PROBE_ONLY) - import->flags |= GF_IMPORT_DO_ABORT; - break; + if (!ts->has_4on2 && import->flags & GF_IMPORT_PROBE_ONLY) + //import->flags |= GF_IMPORT_DO_ABORT; + break;*/ case GF_M2TS_EVT_PMT_FOUND: prog = (GF_M2TS_Program*)par; if (import->flags & GF_IMPORT_PROBE_ONLY) { - /* - we scan all the streams declared in this PMT to fill the tk_info structures + /* + we scan all the streams declared in this PMT to fill the tk_info structures NOTE: in the T-DMB case, we also need to decode ObjectDescriptor Updates see "case GF_M2TS_EVT_SL_PCK" */ count = gf_list_count(prog->streams); @@ -5101,6 +5403,18 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) import->tk_info[idx].lang = pes->lang; import->nb_tracks++; break; + case GF_M2TS_AUDIO_AC3: + import->tk_info[idx].media_type = GF_4CC('D','A','C','3'); + import->tk_info[idx].type = GF_ISOM_MEDIA_AUDIO; + import->tk_info[idx].lang = pes->lang; + import->nb_tracks++; + break; + case GF_M2TS_AUDIO_EC3: + import->tk_info[idx].media_type = GF_4CC('D','E','C','3'); + import->tk_info[idx].type = GF_ISOM_MEDIA_AUDIO; + import->tk_info[idx].lang = pes->lang; + import->nb_tracks++; + break; case GF_M2TS_SYSTEMS_MPEG4_PES: case GF_M2TS_SYSTEMS_MPEG4_SECTIONS: if (es->stream_type == GF_M2TS_SYSTEMS_MPEG4_PES) { @@ -5109,8 +5423,8 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) import->tk_info[idx].media_type = GF_4CC('M','4','S','S'); } if (prog->pmt_iod) { - GF_ESD *esd = m2ts_get_esd(es); - m2ts_set_track_mpeg4_probe_info(esd, &import->tk_info[idx]); + GF_ESD *esd = gf_m2ts_get_esd(es); + m2ts_set_track_mpeg4_probe_info(es, esd, &import->tk_info[idx]); if (esd && esd->decoderConfig->streamType == GF_STREAM_OD) { es->flags |= GF_M2TS_ES_IS_MPEG4_OD; } @@ -5140,21 +5454,30 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) } else { pes = (GF_M2TS_PES *)es; } - esd = m2ts_get_esd(es); + esd = gf_m2ts_get_esd(es); if (esd && esd->decoderConfig->streamType == GF_STREAM_OD) { es->flags |= GF_M2TS_ES_IS_MPEG4_OD; } } /*this PMT is not the one of our stream*/ - if (!found) return; + if (!found || !ts->ess[import->trackID]) return; + + /*make sure all the streams in this programe are in RAW pes framing mode, so that we get notified of the + DTS/PTS*/ + for (i=0; istreams, i); + if (!(es->flags & GF_M2TS_ES_IS_SECTION)) { + gf_m2ts_set_pes_framing((GF_M2TS_PES *)es, GF_M2TS_PES_FRAMING_RAW); + } + } es = ts->ess[import->trackID]; /* import->trackID == pid */ - if (!es) break; - + if (es->flags & GF_M2TS_ES_IS_SECTION) { ses = (GF_M2TS_SECTION_ES *)es; } else { pes = (GF_M2TS_PES *)es; + gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_DEFAULT); } mtype = stype = oti = 0; @@ -5163,38 +5486,44 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) switch (es->stream_type) { case GF_M2TS_VIDEO_MPEG1: mtype = GF_ISOM_MEDIA_VISUAL; - stype = GF_STREAM_VISUAL; oti = 0x6A; + stype = GF_STREAM_VISUAL; + oti = GPAC_OTI_VIDEO_MPEG1; break; case GF_M2TS_VIDEO_MPEG2: mtype = GF_ISOM_MEDIA_VISUAL; - stype = GF_STREAM_VISUAL; oti = 0x65; + stype = GF_STREAM_VISUAL; oti = GPAC_OTI_VIDEO_MPEG2_422; break; case GF_M2TS_VIDEO_MPEG4: mtype = GF_ISOM_MEDIA_VISUAL; - stype = GF_STREAM_VISUAL; oti = 0x20; + stype = GF_STREAM_VISUAL; + oti = GPAC_OTI_VIDEO_MPEG4_PART2; break; case GF_M2TS_VIDEO_H264: mtype = GF_ISOM_MEDIA_VISUAL; - stype = GF_STREAM_VISUAL; oti = 0x21; + stype = GF_STREAM_VISUAL; + oti = GPAC_OTI_VIDEO_AVC; tsimp->avccfg = gf_odf_avc_cfg_new(); break; case GF_M2TS_AUDIO_MPEG1: mtype = GF_ISOM_MEDIA_AUDIO; - stype = GF_STREAM_AUDIO; oti = 0x6B; + stype = GF_STREAM_AUDIO; + oti = GPAC_OTI_AUDIO_MPEG1; break; case GF_M2TS_AUDIO_MPEG2: mtype = GF_ISOM_MEDIA_AUDIO; - stype = GF_STREAM_AUDIO; oti = 0x69; + stype = GF_STREAM_AUDIO; + oti = GPAC_OTI_AUDIO_MPEG2_PART3; break; case GF_M2TS_AUDIO_LATM_AAC: case GF_M2TS_AUDIO_AAC: mtype = GF_ISOM_MEDIA_AUDIO; - stype = GF_STREAM_AUDIO; oti = 0x40; + stype = GF_STREAM_AUDIO; + oti = GPAC_OTI_AUDIO_AAC_MPEG4; break; case GF_M2TS_SYSTEMS_MPEG4_PES: case GF_M2TS_SYSTEMS_MPEG4_SECTIONS: if (prog->pmt_iod && !import->esd) { - import->esd = m2ts_get_esd(es); + import->esd = gf_m2ts_get_esd(es); m2ts_set_track_mpeg4_creation_info(import, &mtype, &stype, &oti); is_in_iod = 1; } @@ -5208,7 +5537,7 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) GF_ESD *esd = gf_isom_get_esd(import->dest, tsimp->track, 1); if (esd) { if (!esd->decoderConfig->decoderSpecificInfo) esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - if (esd->decoderConfig->decoderSpecificInfo->data) free(esd->decoderConfig->decoderSpecificInfo->data); + if (esd->decoderConfig->decoderSpecificInfo->data) gf_free(esd->decoderConfig->decoderSpecificInfo->data); esd->decoderConfig->decoderSpecificInfo->data = ((GF_M2TS_PES_PCK*)par)->data; esd->decoderConfig->decoderSpecificInfo->dataLength = ((GF_M2TS_PES_PCK*)par)->data_len; gf_isom_change_mpeg4_description(import->dest, tsimp->track, 1, esd); @@ -5236,66 +5565,82 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) break; } } - if (!ts->has_4on2 && (import->trackID==pck->stream->pid) && (pck->stream->vid_h || pck->stream->aud_sr) ) - import->flags |= GF_IMPORT_DO_ABORT; + if (!ts->has_4on2 && (import->trackID==pck->stream->pid) && (pck->stream->vid_h || pck->stream->aud_sr) ) + //import->flags |= GF_IMPORT_DO_ABORT; return; } - /* Even if we don't import this stream we need to check the first dts of the program */ + /* Even if we don't import this stream we need to check the first dts of the program */ if (!(pck->stream->flags & GF_M2TS_ES_FIRST_DTS) && is_au_start) { pck->stream->flags |= GF_M2TS_ES_FIRST_DTS; pck->stream->first_dts = (pck->DTS?pck->DTS:pck->PTS); - if (!pck->stream->program->first_dts || - pck->stream->program->first_dts > pck->stream->first_dts) { + if (!pck->stream->program->first_dts || pck->stream->program->first_dts > pck->stream->first_dts) { pck->stream->program->first_dts = pck->stream->first_dts; - } - } + if (pck->stream->pid != import->trackID) { + gf_m2ts_set_pes_framing((GF_M2TS_PES *)pck->stream, GF_M2TS_PES_FRAMING_SKIP); + } + } + } if (pck->stream->pid != import->trackID) return; if (tsimp->avccfg) { GF_AVCConfigSlot *slc; GF_BitStream *bs; s32 idx; + Bool add_sps, is_subseq = 0; u32 nal_type = pck->data[4] & 0x1F; - + switch (nal_type) { + case GF_AVC_NALU_SVC_SUBSEQ_PARAM: + is_subseq = 1; case GF_AVC_NALU_SEQ_PARAM: - bs = gf_bs_new(pck->data+5, pck->data_len-5, GF_BITSTREAM_READ); - idx = AVC_ReadSeqInfo(bs, &tsimp->avc, NULL); - gf_bs_del(bs); - if ((idx>=0) && (tsimp->avc.sps[idx].status==1)) { - tsimp->avc.sps[idx].status = 2; - /*always store nalu size on 4 bytes*/ - tsimp->avccfg->nal_unit_size = 4; - tsimp->avccfg->configurationVersion = 1; - tsimp->avccfg->profile_compatibility = tsimp->avc.sps[idx].prof_compat; - tsimp->avccfg->AVCProfileIndication = tsimp->avc.sps[idx].profile_idc; - tsimp->avccfg->AVCLevelIndication = tsimp->avc.sps[idx].level_idc; - slc = (GF_AVCConfigSlot*)malloc(sizeof(GF_AVCConfigSlot)); - slc->size = pck->data_len-4; - slc->data = (char*)malloc(sizeof(char)*slc->size); - memcpy(slc->data, pck->data+4, sizeof(char)*slc->size); - gf_list_add(tsimp->avccfg->sequenceParameterSets, slc); - - if (pck->stream->vid_w < tsimp->avc.sps[idx].width) - pck->stream->vid_w = tsimp->avc.sps[idx].width; - if (pck->stream->vid_h < tsimp->avc.sps[idx].height) - pck->stream->vid_h = tsimp->avc.sps[idx].height; + idx = AVC_ReadSeqInfo(pck->data+5, pck->data_len-5, &tsimp->avc, is_subseq, NULL); + + add_sps = 0; + if (idx>=0) { + if (is_subseq) { + if ((tsimp->avc.sps[idx].state & AVC_SUBSPS_PARSED) && !(tsimp->avc.sps[idx].state & AVC_SUBSPS_DECLARED)) { + tsimp->avc.sps[idx].state |= AVC_SUBSPS_DECLARED; + add_sps = 1; + } + } else { + if ((tsimp->avc.sps[idx].state & AVC_SPS_PARSED) && !(tsimp->avc.sps[idx].state & AVC_SPS_DECLARED)) { + tsimp->avc.sps[idx].state |= AVC_SPS_DECLARED; + add_sps = 1; + } + } + if (add_sps) { + /*always store nalu size on 4 bytes*/ + tsimp->avccfg->nal_unit_size = 4; + tsimp->avccfg->configurationVersion = 1; + tsimp->avccfg->profile_compatibility = tsimp->avc.sps[idx].prof_compat; + tsimp->avccfg->AVCProfileIndication = tsimp->avc.sps[idx].profile_idc; + tsimp->avccfg->AVCLevelIndication = tsimp->avc.sps[idx].level_idc; + slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); + slc->size = pck->data_len-4; + slc->data = (char*)gf_malloc(sizeof(char)*slc->size); + memcpy(slc->data, pck->data+4, sizeof(char)*slc->size); + gf_list_add(tsimp->avccfg->sequenceParameterSets, slc); + + if (pck->stream->vid_w < tsimp->avc.sps[idx].width) + pck->stream->vid_w = tsimp->avc.sps[idx].width; + if (pck->stream->vid_h < tsimp->avc.sps[idx].height) + pck->stream->vid_h = tsimp->avc.sps[idx].height; + } } return; case GF_AVC_NALU_PIC_PARAM: - bs = gf_bs_new(pck->data+5, pck->data_len-5, GF_BITSTREAM_READ); - idx = AVC_ReadPictParamSet(bs, &tsimp->avc); - gf_bs_del(bs); + idx = AVC_ReadPictParamSet(pck->data+5, pck->data_len-5, &tsimp->avc); if ((idx>=0) && (tsimp->avc.pps[idx].status==1)) { tsimp->avc.pps[idx].status = 2; - slc = (GF_AVCConfigSlot*)malloc(sizeof(GF_AVCConfigSlot)); + slc = (GF_AVCConfigSlot*)gf_malloc(sizeof(GF_AVCConfigSlot)); slc->size = pck->data_len-4; - slc->data = (char*)malloc(sizeof(char)*slc->size); + slc->data = (char*)gf_malloc(sizeof(char)*slc->size); memcpy(slc->data, pck->data+4, sizeof(char)*slc->size); gf_list_add(tsimp->avccfg->pictureParameterSets, slc); } + /*else discard because of invalid PPS*/ return; /*remove*/ case GF_AVC_NALU_ACCESS_UNIT: @@ -5306,8 +5651,11 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) case GF_AVC_NALU_END_OF_STREAM: return; case GF_AVC_NALU_SEI: - idx = AVC_ReformatSEI_NALU(pck->data+4, pck->data_len-4, &tsimp->avc); - if (idx>0) pck->data_len = idx+4; + break; + if (tsimp->avc.sps_active_idx != -1) { + idx = AVC_ReformatSEI_NALU(pck->data+4, pck->data_len-4, &tsimp->avc); + if (idx>0) pck->data_len = idx+4; + } break; } @@ -5336,8 +5684,7 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) samp->DTS = pck->DTS ? pck->DTS : pck->PTS; samp->CTS_Offset = (u32) (pck->PTS - samp->DTS); - if (pck->stream->first_dts == samp->DTS) { - + if (pck->stream->first_dts==samp->DTS) { switch (pck->stream->stream_type) { case GF_M2TS_VIDEO_MPEG1: gf_import_message(import, GF_OK, "MPEG-1 Video import (TS PID %d)", pck->stream->pid); break; case GF_M2TS_VIDEO_MPEG2: gf_import_message(import, GF_OK, "MPEG-2 Video import (TS PID %d)", pck->stream->pid); break; @@ -5375,11 +5722,11 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) e = gf_isom_add_sample(import->dest, tsimp->track, 1, samp); if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Import] Error adding sample: %s\n", gf_error_to_string(e))); - import->flags |= GF_IMPORT_DO_ABORT; + //import->flags |= GF_IMPORT_DO_ABORT; import->last_error = e; } if (import->duration && (import->duration<=(samp->DTS+samp->CTS_Offset)/90)) - import->flags |= GF_IMPORT_DO_ABORT; + //import->flags |= GF_IMPORT_DO_ABORT; if (pck->flags & GF_M2TS_PES_PCK_I_FRAME) tsimp->nb_i++; if (pck->flags & GF_M2TS_PES_PCK_P_FRAME) tsimp->nb_p++; @@ -5406,7 +5753,7 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) if (sl_pck->stream->flags & GF_M2TS_ES_IS_MPEG4_OD) { /* We need to handle OD streams even if this is not the stream we are importing */ - GF_ESD *esd = m2ts_get_esd(sl_pck->stream); + GF_ESD *esd = gf_m2ts_get_esd(sl_pck->stream); if (esd) { GF_SLHeader hdr; u32 hdr_len; @@ -5427,13 +5774,12 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) od_count = gf_list_count(odU->objectDescriptors); for (od_index=0; od_indexobjectDescriptors, od_index); - gf_list_add(sl_pck->stream->program->additional_ods, od); - if (import->flags & GF_IMPORT_PROBE_ONLY) { - /* We need to set the remaining unset track info for the streams declared in this OD */ - m2ts_set_tracks_mpeg4_probe_info(import, sl_pck->stream->program, od->ESDescriptors); - } + gf_list_add(sl_pck->stream->program->additional_ods, od); + + /* We need to set the remaining unset track info for the streams declared in this OD */ + m2ts_set_tracks_mpeg4_probe_info(import, sl_pck->stream->program, od->ESDescriptors); } - gf_list_reset(odU->objectDescriptors); + gf_list_reset(odU->objectDescriptors); } } gf_odf_codec_del(od_codec); @@ -5459,14 +5805,14 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) } return; } - + if (sl_pck->stream->pid != import->trackID) return; /* we create a track for the stream to import only if it was not created */ if (!gf_isom_get_track_by_id(import->dest, (import->esd?import->esd->ESID:import->trackID))) { u32 mtype, stype, oti; mtype = stype = oti = 0; - import->esd = m2ts_get_esd(sl_pck->stream); + import->esd = gf_m2ts_get_esd(sl_pck->stream); m2ts_set_track_mpeg4_creation_info(import, &mtype, &stype, &oti); m2ts_create_track(tsimp, mtype, stype, oti, 0); } @@ -5485,7 +5831,7 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) if (!(sl_pck->stream->flags & GF_M2TS_ES_FIRST_DTS)) { sl_pck->stream->flags |= GF_M2TS_ES_FIRST_DTS; sl_pck->stream->first_dts = (hdr.decodingTimeStamp?hdr.decodingTimeStamp:hdr.compositionTimeStamp); - if (!sl_pck->stream->program->first_dts || + if (!sl_pck->stream->program->first_dts || sl_pck->stream->program->first_dts > sl_pck->stream->first_dts) { sl_pck->stream->program->first_dts = sl_pck->stream->first_dts; } @@ -5498,6 +5844,10 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) samp->DTS -= sl_pck->stream->first_dts; samp->IsRAP = import->esd->slConfig->useRandomAccessPointFlag ? hdr.randomAccessPointFlag: 1; + /*fix for some DMB streams where TSs are not coded*/ + if ((tsimp->last_dts == samp->DTS) && gf_isom_get_sample_count(import->dest, tsimp->track)) + samp->DTS += gf_isom_get_media_timescale(import->dest, tsimp->track); + samp->data = sl_pck->data + hdr_len; samp->dataLength = sl_pck->data_len - hdr_len; @@ -5505,13 +5855,15 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Import] Error adding sample\n")); } - if (import->duration && (import->duration<=(samp->DTS+samp->CTS_Offset)/90)) - import->flags |= GF_IMPORT_DO_ABORT; + if (import->duration && (import->duration<=(samp->DTS+samp->CTS_Offset)/90)) { + //import->flags |= GF_IMPORT_DO_ABORT; + } + tsimp->last_dts = samp->DTS; } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS Import] negative time sample - skipping\n")); sl_pck->stream->first_dts = samp->DTS; - if (!sl_pck->stream->program->first_dts || + if (!sl_pck->stream->program->first_dts || sl_pck->stream->program->first_dts > sl_pck->stream->first_dts) { sl_pck->stream->program->first_dts = sl_pck->stream->first_dts; } @@ -5522,11 +5874,8 @@ void on_m2ts_import_data(GF_M2TS_Demuxer *ts, u32 evt_type, void *par) } } break; - default: - return; } } - /* Warning: we start importing only after finding the PMT */ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) { @@ -5536,10 +5885,11 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) GF_TSImport tsimp; u64 fsize, done; u32 size; + Bool do_import = 1; FILE *mts; char progress[1000]; - - if (import->trackID > GF_M2TS_MAX_STREAMS) + + if (import->trackID > GF_M2TS_MAX_STREAMS) return gf_import_message(import, GF_BAD_PARAM, "Invalid PID %d", import->trackID ); mts = gf_f64_open(import->in_name, "rb"); @@ -5551,21 +5901,31 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) done = 0; memset(&tsimp, 0, sizeof(GF_TSImport)); + tsimp.avc.sps_active_idx = -1; tsimp.import = import; ts = gf_m2ts_demux_new(); ts->on_event = on_m2ts_import_data; ts->user = &tsimp; + ts->dvb_h_demux = (import->flags & GF_IMPORT_MPE_DEMUX) ? 1 : 0; + + if (import->flags & GF_IMPORT_PROBE_ONLY) do_import = 0; + sprintf(progress, "Importing MPEG-2 TS (PID %d)", import->trackID); + if (do_import) gf_import_message(import, GF_OK, progress); + while (!feof(mts)) { - size = fread(data, 1, 188, mts); - if (size<188) break; + size = fread(data, sizeof(char), 188, mts); + if (size<188) + break; gf_m2ts_process_data(ts, data, size); if (import->flags & GF_IMPORT_DO_ABORT) break; done += size; - gf_set_progress(progress, (u32) (done/1024), (u32) (fsize/1024)); + if (do_import) gf_set_progress(progress, (u32) (done/1024), (u32) (fsize/1024)); } + import->flags &= ~GF_IMPORT_DO_ABORT; + if (import->last_error) { GF_Err e = import->last_error; import->last_error = GF_OK; @@ -5575,7 +5935,11 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) return e; } import->esd = NULL; - gf_set_progress(progress, (u32) (fsize/1024), (u32) (fsize/1024)); + if (do_import) gf_set_progress(progress, (u32) (fsize/1024), (u32) (fsize/1024)); + + if (! (import->flags & GF_IMPORT_MPE_DEMUX)) { + gf_m2ts_print_info(ts); + } if (!(import->flags & GF_IMPORT_PROBE_ONLY)) { es = (GF_M2TS_ES *)ts->ess[import->trackID]; @@ -5584,7 +5948,7 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) fclose(mts); return gf_import_message(import, GF_BAD_PARAM, "Unknown PID %d", import->trackID); } - + if (tsimp.avccfg) { u32 w = ((GF_M2TS_PES*)es)->vid_w; u32 h = ((GF_M2TS_PES*)es)->vid_h; @@ -5594,6 +5958,8 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) gf_odf_avc_cfg_del(tsimp.avccfg); } + + MP4T_RecomputeBitRate(import->dest, tsimp.track); /* creation of the edit lists */ if (es->first_dts != es->program->first_dts) { @@ -5604,9 +5970,9 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) assert(es->program->first_dts < es->first_dts); offset = (u32)(es->first_dts - es->program->first_dts) * moov_ts / media_ts; dur = gf_isom_get_media_duration(import->dest, tsimp.track) * moov_ts / media_ts; - gf_isom_set_edit_segment(import->dest, tsimp.track, 0, offset, 0, GF_ISOM_EDIT_EMPTY); - gf_isom_set_edit_segment(import->dest, tsimp.track, offset, dur, 0, GF_ISOM_EDIT_NORMAL); - //gf_import_message(import, GF_OK, "Timeline offset: %d ms", (u32)((pes->first_dts - pes->program->first_dts)/90)); + gf_isom_set_edit_segment(import->dest, tsimp.track, 0, offset, 0, GF_ISOM_EDIT_EMPTY); + gf_isom_set_edit_segment(import->dest, tsimp.track, offset, dur, 0, GF_ISOM_EDIT_NORMAL); + gf_import_message(import, GF_OK, "Timeline offset: %d ms", offset); } if (tsimp.nb_p) { @@ -5622,6 +5988,8 @@ GF_Err gf_import_mpeg_ts(GF_MediaImporter *import) return GF_OK; } +#endif /*GPAC_DISABLE_MPEG2TS*/ + GF_Err gf_import_vobsub(GF_MediaImporter *import) { static u8 null_subpic[] = { 0x00, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0xFF }; @@ -5669,8 +6037,8 @@ GF_Err gf_import_vobsub(GF_MediaImporter *import) for (c = 0; c < 32; c++) { if (vobsub->langs[c].id != 0) { import->tk_info[import->nb_tracks].track_num = c + 1; - import->tk_info[import->nb_tracks].type = GF_ISOM_MEDIA_SUBPIC; - import->tk_info[import->nb_tracks].flags = 0; + import->tk_info[import->nb_tracks].type = GF_ISOM_MEDIA_SUBPIC; + import->tk_info[import->nb_tracks].flags = 0; import->nb_tracks++; } } @@ -5723,10 +6091,10 @@ GF_Err gf_import_vobsub(GF_MediaImporter *import) } import->esd->decoderConfig->streamType = GF_STREAM_ND_SUBPIC; - import->esd->decoderConfig->objectTypeIndication = 0xe0; + import->esd->decoderConfig->objectTypeIndication = GPAC_OTI_MEDIA_SUBPIC; import->esd->decoderConfig->decoderSpecificInfo->dataLength = sizeof(vobsub->palette); - import->esd->decoderConfig->decoderSpecificInfo->data = (char*)&vobsub->palette[0][0]; + import->esd->decoderConfig->decoderSpecificInfo->data = (char*)&vobsub->palette[0][0]; gf_import_message(import, GF_OK, "VobSub import - subpicture stream '%s'", vobsub->langs[trackID].name); @@ -5755,16 +6123,16 @@ GF_Err gf_import_vobsub(GF_MediaImporter *import) err = gf_isom_add_sample(import->dest, track, di, samp); if (err) goto error; - + subpic = vobsub->langs[trackID].subpos; total = gf_list_count(subpic); for (c = 0; c < total; c++) { - u32 i, left, size, psize, dsize, hsize, duration; + u32 i, left, size, psize, dsize, hsize, duration; char *packet; vobsub_pos *pos = (vobsub_pos*)gf_list_get(subpic, c); - + if (import->duration && pos->start > import->duration) { break; } @@ -5775,16 +6143,16 @@ GF_Err gf_import_vobsub(GF_MediaImporter *import) goto error; } - if (fread(buf, 1, sizeof(buf), file) != sizeof(buf)) { + if (!fread(buf, sizeof(buf), 1, file)) { err = gf_import_message(import, GF_IO_ERR, "Could not read from file"); goto error; } if (*(u32*)&buf[0x00] != 0xba010000 || - *(u32*)&buf[0x0e] != 0xbd010000 || - !(buf[0x15] & 0x80) || - (buf[0x17] & 0xf0) != 0x20 || - (buf[buf[0x16] + 0x17] & 0xe0) != 0x20) + *(u32*)&buf[0x0e] != 0xbd010000 || + !(buf[0x15] & 0x80) || + (buf[0x17] & 0xf0) != 0x20 || + (buf[buf[0x16] + 0x17] & 0xe0) != 0x20) { gf_import_message(import, GF_CORRUPTED_DATA, "Corrupted data found in file %s", filename); continue; @@ -5792,7 +6160,7 @@ GF_Err gf_import_vobsub(GF_MediaImporter *import) psize = (buf[buf[0x16] + 0x18] << 8) + buf[buf[0x16] + 0x19]; dsize = (buf[buf[0x16] + 0x1a] << 8) + buf[buf[0x16] + 0x1b]; - packet = (char *) malloc(sizeof(char)*psize); + packet = (char *) gf_malloc(sizeof(char)*psize); if (!packet) { err = gf_import_message(import, GF_OUT_OF_MEM, "Memory allocation failed"); goto error; @@ -5830,7 +6198,7 @@ GF_Err gf_import_vobsub(GF_MediaImporter *import) err = gf_isom_add_sample(import->dest, track, di, samp); if (err) goto error; - free(packet); + gf_free(packet); gf_set_progress("Importing VobSub", c, total); @@ -5866,17 +6234,20 @@ error: return err; } +#ifndef GPAC_DISABLE_AV_PARSERS GF_Err gf_import_ac3(GF_MediaImporter *import) { GF_AC3Header hdr; + GF_AC3Config cfg; Bool destroy_esd; GF_Err e; u16 sr; u32 nb_chan; FILE *in; GF_BitStream *bs; - u32 max_size, track, di, tot_size, done, duration; + u32 max_size, track, di, duration; + u64 tot_size, done; GF_ISOSample *samp; in = gf_f64_open(import->in_name, "rb"); @@ -5913,13 +6284,13 @@ GF_Err gf_import_ac3(GF_MediaImporter *import) if (!import->esd->slConfig) import->esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); /*update stream type/oti*/ import->esd->decoderConfig->streamType = GF_STREAM_AUDIO; - import->esd->decoderConfig->objectTypeIndication = 0xA5; + import->esd->decoderConfig->objectTypeIndication = GPAC_OTI_AUDIO_AC3; import->esd->decoderConfig->bufferSizeDB = 20; import->esd->slConfig->timestampResolution = sr; samp = NULL; nb_chan = hdr.channels; - gf_import_message(import, GF_OK, "AC3 import - sample rate %d - %d channel%s", sr, nb_chan, (nb_chan>1) ? "s" : ""); + gf_import_message(import, GF_OK, "AC3 import - sample rate %d - %d%s channel%s", sr, hdr.lfon ? (nb_chan-1) : nb_chan, hdr.lfon?".1":"", (nb_chan>1) ? "s" : ""); track = gf_isom_new_track(import->dest, import->esd->ESID, GF_ISOM_MEDIA_AUDIO, sr); if (!track) { @@ -5932,22 +6303,18 @@ 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; - if (1) { - GF_AC3Config cfg; - cfg.acmod = hdr.acmod; - cfg.brcode = hdr.brcode; - cfg.bsid = hdr.bsid; - cfg.bsmod = hdr.bsmod; - cfg.fscod = hdr.fscod; - cfg.lfon = hdr.lfon; - gf_isom_ac3_config_new(import->dest, track, &cfg, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di); - } else { - gf_isom_new_mpeg4_description(import->dest, track, import->esd, (import->flags & GF_IMPORT_USE_DATAREF) ? import->in_name : NULL, NULL, &di); - } + cfg.acmod = hdr.acmod; + cfg.brcode = hdr.brcode; + cfg.bsid = hdr.bsid; + cfg.bsmod = hdr.bsmod; + cfg.fscod = hdr.fscod; + cfg.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); gf_bs_seek(bs, 0); - tot_size = (u32) gf_bs_get_size(bs); + tot_size = gf_bs_get_size(bs); e = GF_OK; samp = gf_isom_sample_new(); @@ -5967,7 +6334,7 @@ GF_Err gf_import_ac3(GF_MediaImporter *import) gf_bs_skip_bytes(bs, samp->dataLength); } else { if (samp->dataLength > max_size) { - samp->data = (char*)realloc(samp->data, sizeof(char) * samp->dataLength); + samp->data = (char*)gf_realloc(samp->data, sizeof(char) * samp->dataLength); max_size = samp->dataLength; } gf_bs_read_data(bs, samp->data, samp->dataLength); @@ -5975,7 +6342,7 @@ GF_Err gf_import_ac3(GF_MediaImporter *import) } if (e) goto exit; - gf_set_progress("Importing AAC", done, tot_size); + gf_set_progress("Importing AC3", done, tot_size); samp->DTS += 1536; done += samp->dataLength; @@ -5994,6 +6361,7 @@ exit: fclose(in); return e; } +#endif GF_EXPORT @@ -6007,9 +6375,13 @@ GF_Err gf_media_import(GF_MediaImporter *importer) if (importer->orig) return gf_import_isomedia(importer); - ext = strrchr(importer->in_name, '.'); - if (!ext) ext = ""; - + if (importer->force_ext) { + ext = importer->force_ext; + } else { + ext = strrchr(importer->in_name, '.'); + if (!ext) ext = ""; + } + if (importer->streamFormat) fmt = importer->streamFormat; @@ -6024,90 +6396,104 @@ GF_Err gf_media_import(GF_MediaImporter *importer) } } +#ifndef GPAC_DISABLE_AVILIB /*AVI audio/video*/ if (!strnicmp(ext, ".avi", 4) || !stricmp(fmt, "AVI") ) { e = gf_import_avi_video(importer); if (e) return e; return gf_import_avi_audio(importer); } +#endif + +#ifndef GPAC_DISABLE_OGG /*OGG audio/video*/ if (!strnicmp(ext, ".ogg", 4) || !stricmp(fmt, "OGG")) { e = gf_import_ogg_video(importer); if (e) return e; return gf_import_ogg_audio(importer); } +#endif + +#ifndef GPAC_DISABLE_MPEG2PS /*MPEG PS*/ - if (!strnicmp(ext, ".mpg", 4) || !strnicmp(ext, ".mpeg", 5) + if (!strnicmp(ext, ".mpg", 4) || !strnicmp(ext, ".mpeg", 5) || !strnicmp(ext, ".vob", 4) || !strnicmp(ext, ".vcd", 4) || !strnicmp(ext, ".svcd", 5) - || !stricmp(fmt, "MPEG1") || !stricmp(fmt, "MPEG-PS") || !stricmp(fmt, "MPEG2-PS") + || !stricmp(fmt, "MPEG1") || !stricmp(fmt, "MPEG-PS") || !stricmp(fmt, "MPEG2-PS") ) { e = gf_import_mpeg_ps_video(importer); if (e) return e; return gf_import_mpeg_ps_audio(importer); } +#endif + +#ifndef GPAC_DISABLE_MPEG2TS /*MPEG-2 TS*/ - if (!strnicmp(ext, ".ts", 3) || !strnicmp(ext, ".m2t", 4) - || !stricmp(fmt, "MPEGTS") || !stricmp(fmt, "MPEG-TS") - || !stricmp(fmt, "MPGTS") || !stricmp(fmt, "MPG-TS") - || !stricmp(fmt, "MPEG2TS") || !stricmp(fmt, "MPEG2-TS") - || !stricmp(fmt, "MPG2TS") || !stricmp(fmt, "MPG2-TS") + if (!strnicmp(ext, ".ts", 3) || !strnicmp(ext, ".m2t", 4) + || !stricmp(fmt, "MPEGTS") || !stricmp(fmt, "MPEG-TS") + || !stricmp(fmt, "MPGTS") || !stricmp(fmt, "MPG-TS") + || !stricmp(fmt, "MPEG2TS") || !stricmp(fmt, "MPEG2-TS") + || !stricmp(fmt, "MPG2TS") || !stricmp(fmt, "MPG2-TS") ) { return gf_import_mpeg_ts(importer); } +#endif +#ifndef GPAC_DISABLE_AV_PARSERS /*MPEG1/2 Audio*/ - if (!strnicmp(ext, ".mp2", 4) || !strnicmp(ext, ".mp3", 4) || !strnicmp(ext, ".m1a", 4) || !strnicmp(ext, ".m2a", 4) || !stricmp(fmt, "MP3") || !stricmp(fmt, "MPEG-AUDIO") ) + if (!strnicmp(ext, ".mp2", 4) || !strnicmp(ext, ".mp3", 4) || !strnicmp(ext, ".m1a", 4) || !strnicmp(ext, ".m2a", 4) || !stricmp(fmt, "MP3") || !stricmp(fmt, "MPEG-AUDIO") ) return gf_import_mp3(importer); - /*NHNT*/ - if (!strnicmp(ext, ".media", 5) || !strnicmp(ext, ".info", 5) || !strnicmp(ext, ".nhnt", 5) || !stricmp(fmt, "NHNT") ) - return gf_import_nhnt(importer); - /*NHML*/ - if (!strnicmp(ext, ".nhml", 5) || !stricmp(fmt, "NHML") ) - return gf_import_nhml_dims(importer, 0); - /*jpg & png & jp2*/ - if (!strnicmp(ext, ".jpg", 4) || !strnicmp(ext, ".jpeg", 5) || !strnicmp(ext, ".jp2", 4) || !strnicmp(ext, ".png", 4) || !stricmp(fmt, "JPEG") || !stricmp(fmt, "PNG") || !stricmp(fmt, "JP2") ) - return gf_import_still_image(importer); /*MPEG-2/4 AAC*/ - if (!strnicmp(ext, ".aac", 4) || !stricmp(fmt, "AAC") || !stricmp(fmt, "MPEG4-AUDIO") ) + if (!strnicmp(ext, ".aac", 4) || !stricmp(fmt, "AAC") || !stricmp(fmt, "MPEG4-AUDIO") ) return gf_import_aac_adts(importer); - /*AMR & 3GPP2 speec codecs*/ - if (!strnicmp(ext, ".amr", 4) || !strnicmp(ext, ".awb", 4) || !strnicmp(ext, ".smv", 4) || !strnicmp(ext, ".evc", 4) - || !stricmp(fmt, "AMR") || !stricmp(fmt, "EVRC") || !stricmp(fmt, "SMV") ) - return gf_import_amr_evrc_smv(importer); - /*QCelp & other in QCP file format*/ - if (!strnicmp(ext, ".qcp", 4) || !stricmp(fmt, "QCELP") ) - return gf_import_qcp(importer); /*MPEG-4 video*/ - if (!strnicmp(ext, ".cmp", 4) || !strnicmp(ext, ".m4v", 4) || !stricmp(fmt, "CMP") || !stricmp(fmt, "MPEG4-Video") ) + if (!strnicmp(ext, ".cmp", 4) || !strnicmp(ext, ".m4v", 4) || !stricmp(fmt, "CMP") || !stricmp(fmt, "MPEG4-Video") ) return gf_import_cmp(importer, 0); /*MPEG-1/2 video*/ - if (!strnicmp(ext, ".m2v", 4) || !strnicmp(ext, ".m1v", 4) || !stricmp(fmt, "MPEG2-Video") || !stricmp(fmt, "MPEG1-Video") ) + if (!strnicmp(ext, ".m2v", 4) || !strnicmp(ext, ".m1v", 4) || !stricmp(fmt, "MPEG2-Video") || !stricmp(fmt, "MPEG1-Video") ) return gf_import_cmp(importer, 2); /*H2632 video*/ - if (!strnicmp(ext, ".263", 4) || !strnicmp(ext, ".h263", 5) || !stricmp(fmt, "H263") ) + if (!strnicmp(ext, ".263", 4) || !strnicmp(ext, ".h263", 5) || !stricmp(fmt, "H263") ) return gf_import_h263(importer); /*H264/AVC video*/ if (!strnicmp(ext, ".h264", 5) || !strnicmp(ext, ".264", 4) || !strnicmp(ext, ".x264", 5) || !strnicmp(ext, ".h26L", 5) || !strnicmp(ext, ".26l", 4) - || !stricmp(fmt, "AVC") || !stricmp(fmt, "H264") ) + || !stricmp(fmt, "AVC") || !stricmp(fmt, "H264") ) return gf_import_h264(importer); + /*AC3*/ + if (!strnicmp(ext, ".ac3", 4) || !stricmp(fmt, "AC3") ) + return gf_import_ac3(importer); +#endif + + /*NHNT*/ + if (!strnicmp(ext, ".media", 5) || !strnicmp(ext, ".info", 5) || !strnicmp(ext, ".nhnt", 5) || !stricmp(fmt, "NHNT") ) + return gf_import_nhnt(importer); + /*NHML*/ + if (!strnicmp(ext, ".nhml", 5) || !stricmp(fmt, "NHML") ) + return gf_import_nhml_dims(importer, 0); + /*jpg & png & jp2*/ + if (!strnicmp(ext, ".jpg", 4) || !strnicmp(ext, ".jpeg", 5) || !strnicmp(ext, ".jp2", 4) || !strnicmp(ext, ".png", 4) || !stricmp(fmt, "JPEG") || !stricmp(fmt, "PNG") || !stricmp(fmt, "JP2") ) + return gf_import_still_image(importer, 1); + /*AMR & 3GPP2 speec codecs*/ + if (!strnicmp(ext, ".amr", 4) || !strnicmp(ext, ".awb", 4) || !strnicmp(ext, ".smv", 4) || !strnicmp(ext, ".evc", 4) + || !stricmp(fmt, "AMR") || !stricmp(fmt, "EVRC") || !stricmp(fmt, "SMV") ) + return gf_import_amr_evrc_smv(importer); + /*QCelp & other in QCP file format*/ + if (!strnicmp(ext, ".qcp", 4) || !stricmp(fmt, "QCELP") ) + return gf_import_qcp(importer); /*MPEG-4 SAF multiplex*/ - if (!strnicmp(ext, ".saf", 4) || !strnicmp(ext, ".lsr", 4) || !stricmp(fmt, "SAF") ) + 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) + || !stricmp(fmt, "SRT") || !stricmp(fmt, "SUB") || !stricmp(fmt, "TEXT") ) return gf_import_timed_text(importer); /*VobSub*/ - if (!strnicmp(ext, ".idx", 4) || !stricmp(fmt, "VOBSUB")) + if (!strnicmp(ext, ".idx", 4) || !stricmp(fmt, "VOBSUB")) return gf_import_vobsub(importer); /*raw importer*/ if (!stricmp(fmt, "RAW")) { return gf_import_raw_unit(importer); } - /*AC3*/ - if (!strnicmp(ext, ".ac3", 4) || !stricmp(fmt, "AC3") ) - return gf_import_ac3(importer); /*DIMS*/ if (!strnicmp(ext, ".dml", 4) || !stricmp(fmt, "DIMS") ) return gf_import_nhml_dims(importer, 1); @@ -6116,20 +6502,20 @@ GF_Err gf_media_import(GF_MediaImporter *importer) xml_type = gf_xml_get_root_type(importer->in_name, &e); if (xml_type) { if (!stricmp(xml_type, "TextStream") || !stricmp(xml_type, "text3GTrack") ) { - free(xml_type); + gf_free(xml_type); return gf_import_timed_text(importer); } else if (!stricmp(xml_type, "NHNTStream")) { - free(xml_type); + gf_free(xml_type); return gf_import_nhml_dims(importer, 0); } else if (!stricmp(xml_type, "DIMSStream") ) { - free(xml_type); + gf_free(xml_type); return gf_import_nhml_dims(importer, 1); } - free(xml_type); + gf_free(xml_type); } - + return gf_import_message(importer, e, "Unknown input file type"); } @@ -6143,39 +6529,77 @@ GF_Err gf_media_change_par(GF_ISOFile *file, u32 track, s32 ar_num, s32 ar_den) if (e) return e; stype = gf_isom_get_media_subtype(file, track, 1); - if (stype==GF_ISOM_SUBTYPE_AVC_H264) { + 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; } - if (esd->decoderConfig->objectTypeIndication==0x20) { +#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; } -/* With the removal of the following code, files produced are compatible with Quicktime 7.3 */ -/* + 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; } -*/ - e = gf_isom_set_pixel_aspect_ratio(file, track, 1, ar_num, ar_den); - if (e) return e; + /*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 + +GF_EXPORT +GF_Err gf_media_change_pl(GF_ISOFile *file, u32 track, u32 profile, u32 level) +{ + u32 i, count, stype; + GF_Err e; + GF_AVCConfig *avcc; + + stype = gf_isom_get_media_subtype(file, track, 1); + switch (stype) { + case GF_ISOM_SUBTYPE_AVC_H264: + case GF_ISOM_SUBTYPE_AVC2_H264: + break; + default: + return GF_OK; + } + + avcc = gf_isom_avc_config_get(file, track, 1); + if (level) avcc->AVCLevelIndication = level; + if (profile) avcc->AVCProfileIndication = profile; + count = gf_list_count(avcc->sequenceParameterSets); + for (i=0; isequenceParameterSets, i); + if (profile) slc->data[1] = profile; + if (level) slc->data[3] = level; + } + e = gf_isom_avc_config_update(file, track, 1, avcc); + gf_odf_avc_cfg_del(avcc); + return GF_OK; +} + +#endif /*GPAC_DISABLE_MEDIA_IMPORT*/ diff --git a/src/media_tools/mpeg2_ps.c b/src/media_tools/mpeg2_ps.c index 863fb61..686c74a 100644 --- a/src/media_tools/mpeg2_ps.c +++ b/src/media_tools/mpeg2_ps.c @@ -24,6 +24,8 @@ */ #include "mpeg2_ps.h" +#ifndef GPAC_DISABLE_MPEG2PS + static GFINLINE u16 convert16 (u8 *p) { @@ -70,42 +72,6 @@ typedef struct mpeg2ps_record_pes_t u64 location; } mpeg2ps_record_pes_t; -s32 MPEG12_FindNextStartCode(unsigned char *pbuffer, u32 buflen, u32 *optr, u32 *scode) -{ - u32 value; - u32 offset; - - if (buflen < 4) return -1; - for (offset = 0; offset < buflen - 3; offset++, pbuffer++) { -#ifdef GPAC_BIG_ENDIAN - value = *(u32 *)pbuffer >> 8; -#else - value = (pbuffer[0] << 16) | (pbuffer[1] << 8) | (pbuffer[2] << 0); -#endif - - if (value == MPEG12_START_CODE_PREFIX) { - *optr = offset; - *scode = (value << 8) | pbuffer[3]; - return 0; - } - } - return -1; -} - -s32 MPEG12_FindNextSliceStart(unsigned char *pbuffer, u32 startoffset, u32 buflen, u32 *slice_offset) -{ - u32 slicestart, code; - while (MPEG12_FindNextStartCode(pbuffer + startoffset, buflen - startoffset, &slicestart, &code) >= 0) { - if ((code >= MPEG12_SLICE_MIN_START) && (code <= MPEG12_SLICE_MAX_START)) { - *slice_offset = slicestart + startoffset; - return 0; - } - startoffset += slicestart + 4; - } - return -1; -} - -#ifndef GPAC_READ_ONLY /* * information about reading a stream */ @@ -204,9 +170,9 @@ static void file_skip_bytes (FILE *fd, s32 len) #define file_location(__f) gf_f64_tell(__f) #define file_seek_to(__f, __off) gf_f64_seek(__f, __off, SEEK_SET) -static s64 file_size(FILE *fd) +static u64 file_size(FILE *fd) { - s64 ret; + u64 ret; gf_f64_seek(fd, 0, SEEK_END); ret = gf_f64_tell(fd); gf_f64_seek(fd, 0, SEEK_SET); @@ -405,7 +371,7 @@ static mpeg2ps_stream_t *mpeg2ps_stream_create (u8 stream_id, ptr->m_stream_id = stream_id; ptr->m_substream_id = substream; ptr->is_video = stream_id >= 0xe0; - ptr->pes_buffer = (u8 *)malloc(4*4096); + ptr->pes_buffer = (u8 *)gf_malloc(4*4096); ptr->pes_buffer_size_max = 4 * 4096; return ptr; } @@ -416,14 +382,14 @@ static void mpeg2ps_stream_destroy (mpeg2ps_stream_t *sptr) while (sptr->record_first != NULL) { p = sptr->record_first; sptr->record_first = p->next_rec; - free(p); + gf_free(p); } if (sptr->m_fd != FDNULL) { file_close(sptr->m_fd); sptr->m_fd = FDNULL; } - if (sptr->pes_buffer) free(sptr->pes_buffer); - free(sptr); + if (sptr->pes_buffer) gf_free(sptr->pes_buffer); + gf_free(sptr); } @@ -475,7 +441,7 @@ static Bool find_pack_start (FILE *fd, return 0; } while (1) { - if (MPEG12_FindNextStartCode(buffer + buffer_on, + if (gf_mv12_next_start_code(buffer + buffer_on, sizeof(buffer) - buffer_on, &new_offset, &scode) >= 0) { @@ -533,7 +499,7 @@ static void copy_bytes_to_pes_buffer (mpeg2ps_stream_t *sptr, sptr->pes_buffer_on = 0; //printf("moving %d bytes\n", to_move); if (to_move + pes_len > sptr->pes_buffer_size_max) { - sptr->pes_buffer = (u8 *)realloc(sptr->pes_buffer, + sptr->pes_buffer = (u8 *)gf_realloc(sptr->pes_buffer, to_move + pes_len + 2048); sptr->pes_buffer_size_max = to_move + pes_len + 2048; } @@ -806,7 +772,7 @@ mpeg2ps_stream_find_mpeg_video_frame (mpeg2ps_stream_t *sptr) return 0; } } - while (MPEG12_FindNextStartCode(sptr->pes_buffer + sptr->pes_buffer_on, + while (gf_mv12_next_start_code(sptr->pes_buffer + sptr->pes_buffer_on, sptr->pes_buffer_size - sptr->pes_buffer_on, &offset, &scode) < 0 || @@ -843,7 +809,7 @@ mpeg2ps_stream_find_mpeg_video_frame (mpeg2ps_stream_t *sptr) start = 4 + sptr->pes_buffer_on; while (1) { - if (MPEG12_FindNextStartCode(sptr->pes_buffer + start, + if (gf_mv12_next_start_code(sptr->pes_buffer + start, sptr->pes_buffer_size - start, &offset, &scode) < 0) { @@ -1645,11 +1611,11 @@ mpeg2ps_t *mpeg2ps_init (const char *filename) memset(ps, 0, sizeof(*ps)); ps->fd = file_open(filename); if (file_okay(ps->fd) == 0) { - free(ps); + gf_free(ps); return NULL; } - ps->filename = strdup(filename); + ps->filename = gf_strdup(filename); mpeg2ps_scan_file(ps); if (ps->video_cnt == 0 && ps->audio_cnt == 0) { mpeg2ps_close(ps); @@ -1671,9 +1637,9 @@ void mpeg2ps_close (mpeg2ps_t *ps) ps->audio_streams[ix] = NULL; } - if (ps->filename) free(ps->filename); + if (ps->filename) gf_free(ps->filename); if (ps->fd) file_close(ps->fd); - free(ps); + gf_free(ps); } /* @@ -1789,7 +1755,7 @@ Bool mpeg2ps_get_audio_frame(mpeg2ps_t *ps, u32 streamno, return 1; } -s64 mpeg2ps_get_ps_size(mpeg2ps_t *ps) +u64 mpeg2ps_get_ps_size(mpeg2ps_t *ps) { return file_size(ps->fd); } @@ -1804,5 +1770,4 @@ s64 mpeg2ps_get_audio_pos(mpeg2ps_t *ps, u32 streamno) return gf_f64_tell(ps->audio_streams[streamno]->m_fd); } -#endif - +#endif /*GPAC_DISABLE_MPEG2PS*/ diff --git a/src/media_tools/mpeg2_ps.h b/src/media_tools/mpeg2_ps.h index a1bd3bd..6249edf 100644 --- a/src/media_tools/mpeg2_ps.h +++ b/src/media_tools/mpeg2_ps.h @@ -27,6 +27,9 @@ #include +#ifndef GPAC_DISABLE_MPEG2PS + + #define MPEG2_PS_START 0x00000100 #define MPEG2_PS_START_MASK 0xffffff00 #define MPEG2_PS_PACKSTART 0x000001BA @@ -181,7 +184,7 @@ extern "C" { /* * returns file size */ - s64 mpeg2ps_get_ps_size(mpeg2ps_t *ps); + u64 mpeg2ps_get_ps_size(mpeg2ps_t *ps); /* * returns position in file * ps - handle from above @@ -198,7 +201,11 @@ typedef void (*error_msg_func_t)(int loglevel, void mpeg2ps_set_loglevel(int loglevel); void mpeg2ps_set_error_func(error_msg_func_t func); + +#endif /*GPAC_DISABLE_MPEG2PS*/ + #ifdef __cplusplus } #endif + #endif diff --git a/src/media_tools/mpegts.c b/src/media_tools/mpegts.c index 2c55da6..5f936ab 100644 --- a/src/media_tools/mpegts.c +++ b/src/media_tools/mpegts.c @@ -10,22 +10,32 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include + +#ifndef GPAC_DISABLE_MPEG2TS + #include #include #include +#include + +#define DUMP_MPE_IP_DATAGRAMS + +#ifdef DUMP_MPE_IP_DATAGRAMS +#include +#endif #define DEBUG_TS_PACKET 0 @@ -47,6 +57,8 @@ const char *gf_m2ts_get_stream_name(u32 streamType) case GF_M2TS_SUBTITLE_DVB: return "DVB Subtitle"; case GF_M2TS_SYSTEMS_MPEG4_PES: return "MPEG-4 SL (PES)"; case GF_M2TS_SYSTEMS_MPEG4_SECTIONS: return "MPEG-4 SL (Section)"; + case GF_M2TS_MPE_SECTIONS: return "MPE (Section)"; + default: return "Unknown"; } } @@ -73,14 +85,18 @@ static void gf_m2ts_reframe_default(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 D ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); } - static void gf_m2ts_reframe_avc_h264(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) { + Bool force_new_au=0; Bool start_code_found = 0; + Bool short_start_code = 0; + Bool esc_code_found = 0; u32 nal_type, sc_pos = 0; + GF_M2TS_PES_PCK pck; if (PTS) { + if (pes->PTS != PTS) force_new_au = 1; pes->PTS = PTS; if (DTS) pes->DTS = DTS; else pes->DTS = PTS; @@ -93,69 +109,114 @@ static void gf_m2ts_reframe_avc_h264(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 pck.flags = 0; while (sc_poson_event(ts, GF_M2TS_EVT_PES_PCK, &pck); + if (!esc_code_found) { + pck.data = data; + pck.data_len = sc_pos; + pck.flags = 0; + ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); + } + data += sc_pos; data_len -= sc_pos; - sc_pos = 0; } - start_code_found = 1; + start_code_found = short_start_code ? 2 : 1; + sc_pos=1; } else { - pck.data = data; - pck.data_len = sc_pos; + + if (start_code_found==2) { + pck.data = data-1; + pck.data[0]=0; + pck.data_len = sc_pos+1; + } else { + pck.data = data; + pck.data_len = sc_pos; + } + start_code_found = short_start_code ? 2 : 1; nal_type = pck.data[4] & 0x1F; /*check for SPS and update stream info*/ +#ifndef GPAC_DISABLE_AV_PARSERS if (!pes->vid_w && (nal_type==GF_AVC_NALU_SEQ_PARAM)) { AVCState avc; s32 idx; - GF_BitStream *bs = gf_bs_new(data+5, sc_pos-5, GF_BITSTREAM_READ); memset(&avc, 0, sizeof(AVCState)); - idx = AVC_ReadSeqInfo(bs, &avc, NULL); - gf_bs_del(bs); + avc.sps_active_idx = -1; + idx = AVC_ReadSeqInfo(data+5, sc_pos-5, &avc, 0, NULL); if (idx>=0) { pes->vid_w = avc.sps[idx].width; pes->vid_h = avc.sps[idx].height; } } - +#endif /*check AU start type*/ - if (nal_type==GF_AVC_NALU_ACCESS_UNIT) pck.flags = GF_M2TS_PES_PCK_AU_START; + if (nal_type==GF_AVC_NALU_ACCESS_UNIT) { + pck.flags = GF_M2TS_PES_PCK_AU_START; + force_new_au = 0; + } else pck.flags = 0; ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); data += sc_pos; data_len -= sc_pos; sc_pos = 0; + + if (esc_code_found) { + esc_code_found=0; + start_code_found=0; + } else { + sc_pos = 1; + } } - sc_pos++; } - if (data_len) { + if (data_len && start_code_found) { pck.flags = 0; + pck.data = data; + pck.data_len = data_len; if (start_code_found) { - pck.data = data; - pck.data_len = data_len; + if (start_code_found==2) { + pck.data = data-1; + pck.data[0]=0; + pck.data_len = data_len+1; + } nal_type = pck.data[4] & 0x1F; - if (nal_type==GF_AVC_NALU_ACCESS_UNIT) pck.flags = GF_M2TS_PES_PCK_AU_START; - } else { - pck.data = data; - pck.data_len = data_len; + if (nal_type==GF_AVC_NALU_ACCESS_UNIT) + pck.flags = GF_M2TS_PES_PCK_AU_START; + } + if (force_new_au) { + pck.flags |= GF_M2TS_PES_PCK_AU_START; + force_new_au = 0; } + ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); } } @@ -198,12 +259,12 @@ void gf_m2ts_reframe_mpeg_video(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, } new_au = 1; /*if prev was GOP/SEQ start, this is not a new AU*/ - if (pes->frame_state) + if (pes->frame_state) new_au = 0; pes->frame_state = data[3]; if (new_au) { pck.flags = GF_M2TS_PES_PCK_AU_START; - if (pes->rap) + if (pes->rap) pck.flags |= GF_M2TS_PES_PCK_RAP; } @@ -215,10 +276,13 @@ void gf_m2ts_reframe_mpeg_video(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, pes->vid_par = (p[3] >> 4) & 0xf; switch (pes->vid_par) { - default: pes->vid_par = 0; break; case 2: num = 4; den = 3; break; case 3: num = 16; den = 9; break; case 4: num = 221; den = 100; break; + default: + pes->vid_par = 0; + den = num = 0; + break; } if (den) pes->vid_par = ((pes->vid_h/den)<<16) | (pes->vid_w/num); break; @@ -240,6 +304,8 @@ void gf_m2ts_reframe_mpeg_video(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); } +#ifndef GPAC_DISABLE_AV_PARSERS + static u32 latm_get_value(GF_BitStream *bs) { u32 i, tmp, value = 0; @@ -252,7 +318,105 @@ static u32 latm_get_value(GF_BitStream *bs) return value; } -void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) +typedef struct +{ + Bool is_mp2, no_crc; + u32 profile, sr_idx, nb_ch, frame_size; +} ADTSHeader; + +static void gf_m2ts_reframe_aac_adts(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) +{ + ADTSHeader hdr; + u32 sc_pos = 0; + u32 start = 0; + u32 hdr_size = 0; + GF_M2TS_PES_PCK pck; + + if (PTS) { + pes->PTS = PTS; + if (DTS) pes->DTS = DTS; + else pes->DTS = PTS; + } + /*dispatch frame*/ + pck.stream = pes; + pck.DTS = pes->DTS; + pck.PTS = pes->PTS; + pck.flags = 0; + + while (sc_pos+2PTS; + pck.PTS = pes->PTS; + pck.flags = 0; + pck.data = data+start; + pck.data_len = sc_pos-start; + } + + bs = gf_bs_new(data + sc_pos + 1, 9, GF_BITSTREAM_READ); + gf_bs_read_int(bs, 4); + hdr.is_mp2 = gf_bs_read_int(bs, 1); + gf_bs_read_int(bs, 2); + hdr.no_crc = gf_bs_read_int(bs, 1); + + hdr.profile = 1 + gf_bs_read_int(bs, 2); + hdr.sr_idx = gf_bs_read_int(bs, 4); + gf_bs_read_int(bs, 1); + hdr.nb_ch = gf_bs_read_int(bs, 3); + gf_bs_read_int(bs, 4); + hdr.frame_size = gf_bs_read_int(bs, 13); + gf_bs_read_int(bs, 11); + gf_bs_read_int(bs, 2); + if (!hdr.no_crc) gf_bs_read_int(bs, 16); + hdr_size = hdr.no_crc ? 7 : 9; + + gf_bs_del(bs); + + if (pes->aud_sr != GF_M4ASampleRates[hdr.sr_idx]) { + GF_M4ADecSpecInfo cfg; + pck.stream = pes; + memset(&cfg, 0, sizeof(GF_M4ADecSpecInfo)); + cfg.base_object_type = hdr.profile; + cfg.base_sr = GF_M4ASampleRates[hdr.sr_idx]; + cfg.nb_chan = hdr.nb_ch; + cfg.sbr_object_type = 0; + gf_m4a_write_config(&cfg, &pck.data, &pck.data_len); + ts->on_event(ts, GF_M2TS_EVT_AAC_CFG, &pck); + gf_free(pck.data); + pes->aud_sr = cfg.base_sr; + pes->aud_nb_ch = cfg.nb_chan; + } + + /*dispatch frame*/ + pck.stream = pes; + pck.DTS = pes->PTS; + pck.PTS = pes->PTS; + pck.flags = GF_M2TS_PES_PCK_AU_START | GF_M2TS_PES_PCK_RAP; + pck.data = data + sc_pos + hdr_size; + pck.data_len = hdr.frame_size - hdr_size; + + ts->on_event(ts, GF_M2TS_EVT_PES_PCK, &pck); + sc_pos += hdr.frame_size; + start = sc_pos; + /*update PTS in case we don't get any update*/ + if (pes->aud_sr) { + size = 1024*90000/pes->aud_sr; + pes->PTS += size; + } + } +} + +static void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) { u32 sc_pos = 0; u32 start = 0; @@ -295,7 +459,7 @@ void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u6 /*use same stream mux*/ if (!gf_bs_read_int(bs, 1)) { Bool amux_version, amux_versionA; - + amux_version = gf_bs_read_int(bs, 1); amux_versionA = 0; if (amux_version) amux_versionA = gf_bs_read_int(bs, 1); @@ -323,7 +487,7 @@ void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u6 pck.stream = pes; gf_m4a_write_config(&cfg, &pck.data, &pck.data_len); ts->on_event(ts, GF_M2TS_EVT_AAC_CFG, &pck); - free(pck.data); + gf_free(pck.data); pes->aud_sr = cfg.base_sr; pes->aud_nb_ch = cfg.nb_chan; } @@ -343,6 +507,9 @@ void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u6 if (gf_bs_read_int(bs, 1)) { // u32 k = 0; } + /*CRCcheck present*/ + if (gf_bs_read_int(bs, 1)) { + } } @@ -358,7 +525,7 @@ void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u6 } if (size>pes->buf_len) { pes->buf_len = size; - pes->buf = realloc(pes->buf, sizeof(char)*pes->buf_len); + pes->buf = gf_realloc(pes->buf, sizeof(char)*pes->buf_len); } gf_bs_read_data(bs, pes->buf, size); @@ -384,7 +551,10 @@ void gf_m2ts_reframe_aac_latm(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u6 } } +#endif + +#ifndef GPAC_DISABLE_AV_PARSERS static void gf_m2ts_reframe_mpeg_audio(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) { GF_M2TS_PES_PCK pck; @@ -452,7 +622,7 @@ static void gf_m2ts_reframe_mpeg_audio(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u6 break; } /*resync (ID3 or error)*/ - if (pos) { + if (pos) { data_len -= pos; data += pos; } @@ -466,10 +636,11 @@ static void gf_m2ts_reframe_mpeg_audio(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u6 /*update PTS in case we don't get any update*/ pes->PTS += gf_mp3_window_size(pes->frame_state)*90000/gf_mp3_sampling_rate(pes->frame_state); pes->frame_state = frame_size - data_len; - } else { + } else { pes->frame_state = 0; } } +#endif /*GPAC_DISABLE_AV_PARSERS*/ static u32 gf_m2ts_sync(GF_M2TS_Demuxer *ts, Bool simple_check) { @@ -506,46 +677,55 @@ static GF_M2TS_SectionFilter *gf_m2ts_section_filter_new(gf_m2ts_section_callbac return sec; } -static void gf_m2ts_reset_sections(GF_List *sections) +static void gf_m2ts_reset_sections(GF_List *sections) { u32 count; GF_M2TS_Section *section; + //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Deleting sections\n")); count = gf_list_count(sections); while (count) { section = gf_list_get(sections, 0); gf_list_rem(sections, 0); - if (section->data) free(section->data); - free(section); + if (section->data) gf_free(section->data); + gf_free(section); count--; } } static void gf_m2ts_section_filter_del(GF_M2TS_SectionFilter *sf) { - if (sf->section) free(sf->section); + if (sf->section) gf_free(sf->section); while (sf->table) { GF_M2TS_Table *t = sf->table; sf->table = t->next; gf_m2ts_reset_sections(t->sections); gf_list_del(t->sections); - free(t); + gf_free(t); } - free(sf); + gf_free(sf); } void gf_m2ts_es_del(GF_M2TS_ES *es) { gf_list_del_item(es->program->streams, es); + if (es->flags & GF_M2TS_ES_IS_SECTION) { GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es; if (ses->sec) gf_m2ts_section_filter_del(ses->sec); + +#ifdef DUMP_MPE_IP_DATAGRAMS + if (es->flags & GF_M2TS_ES_IS_MPE) + gf_dvb_mpe_section_del(es); +#endif + } else if (es->pid!=es->program->pmt_pid) { GF_M2TS_PES *pes = (GF_M2TS_PES *)es; - if (pes->data) free(pes->data); - if (pes->buf) free(pes->buf); + if (pes->data) gf_free(pes->data); + if (pes->buf) gf_free(pes->buf); } - free(es); + if (es->slcfg) gf_free(es->slcfg); + gf_free(es); } static void gf_m2ts_reset_sdt(GF_M2TS_Demuxer *ts) @@ -553,24 +733,28 @@ static void gf_m2ts_reset_sdt(GF_M2TS_Demuxer *ts) while (gf_list_count(ts->SDTs)) { GF_M2TS_SDT *sdt = (GF_M2TS_SDT *)gf_list_last(ts->SDTs); gf_list_rem_last(ts->SDTs); - if (sdt->provider) free(sdt->provider); - if (sdt->service) free(sdt->service); - free(sdt); + if (sdt->provider) gf_free(sdt->provider); + if (sdt->service) gf_free(sdt->service); + gf_free(sdt); } } static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter *sec, GF_M2TS_SECTION_ES *ses) { - if (! sec->process_section && !sec->had_error) { - if (ts->on_event) { + if (!sec->process_section) { + 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; + pck.data = sec->section; + pck.stream = (GF_M2TS_ES *)ses; + ts->on_mpe_event(ts, GF_M2TS_EVT_DVB_MPE, &pck); + } + else if (ts->on_event) { GF_M2TS_SL_PCK pck; pck.data_len = sec->length; - pck.data = (unsigned char*)malloc(sizeof(unsigned char)*pck.data_len); - memcpy(pck.data, sec->section, sizeof(unsigned char)*pck.data_len); - //pck.data[pck.data_len] = 0; + pck.data = sec->section; pck.stream = (GF_M2TS_ES *)ses; ts->on_event(ts, GF_M2TS_EVT_DVB_GENERAL, &pck); - free(pck.data); } } else { Bool has_syntax_indicator; @@ -588,15 +772,12 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter /*look for proper table*/ table_id = data[0]; - if ((table_id == GF_M2TS_TABLE_ID_PMT || table_id == GF_M2TS_TABLE_ID_NIT_ACTUAL) && ts->on_event) { + if ((table_id == GF_M2TS_TABLE_ID_PAT || table_id == GF_M2TS_TABLE_ID_SDT_ACTUAL || table_id == GF_M2TS_TABLE_ID_PMT || table_id == GF_M2TS_TABLE_ID_NIT_ACTUAL) && ts->on_event) { GF_M2TS_SL_PCK pck; pck.data_len = sec->length; - pck.data = (unsigned char*)malloc(sizeof(unsigned char)*pck.data_len); - memcpy(pck.data, sec->section, sizeof(unsigned char)*pck.data_len); - //pck.data[pck.data_len] = 0; + pck.data = sec->section; pck.stream = (GF_M2TS_ES *)ses; ts->on_event(ts, GF_M2TS_EVT_DVB_GENERAL, &pck); - free(pck.data); } has_syntax_indicator = (data[1] & 0x80) ? 1 : 0; @@ -617,6 +798,7 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter /*create table*/ if (!t) { GF_SAFEALLOC(t, GF_M2TS_Table); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Creating table %d %d\n", table_id, extended_table_id)); t->table_id = table_id; t->ex_table_id = extended_table_id; t->sections = gf_list_new(); @@ -630,24 +812,33 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter if (gf_m2ts_crc32_check(data, sec->length)) { s32 cur_sec_num; t->version_number = (data[5] >> 1) & 0x1f; + if (t->last_section_number && t->section_number && (t->version_number != t->last_version_number)) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] table transmission interrupted: previous table (v=%d) %d/%d sections - new table (v=%d) %d/%d sections\n", t->last_version_number, t->section_number, t->last_section_number, t->version_number, data[6] + 1, data[7] + 1) ); + gf_m2ts_reset_sections(t->sections); + t->section_number = 0; + } + t->current_next_indicator = (data[5] & 0x1) ? 1 : 0; /*add one to section numbers to detect if we missed or not the first section in the table*/ - cur_sec_num = data[6] + 1; + cur_sec_num = data[6] + 1; t->last_section_number = data[7] + 1; section_start = 8; - section_valid = 1; /*we missed something*/ if (!sec->process_individual && t->section_number + 1 != cur_sec_num) { - /* TODO - Check how to handle sections when the first complete section does + /* TODO - Check how to handle sections when the first complete section does not have its sec num 0 */ section_valid = 0; - GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted table (lost section %d)\n", cur_sec_num ? cur_sec_num-1 : 31) ); + if (t->is_init) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted table (lost section %d)\n", cur_sec_num ? cur_sec_num-1 : 31) ); + } + } else { + section_valid = 1; + t->section_number = cur_sec_num; } - t->section_number = cur_sec_num; } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] corrupted section (CRC32 failed)\n")); } - } else if (!sec->had_error) { + } else { section_valid = 1; section_start = 3; } @@ -656,30 +847,39 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter GF_M2TS_Section *section; GF_SAFEALLOC(section, GF_M2TS_Section); + //GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Creating section\n")); section->data_size = sec->length - section_start; - section->data = (unsigned char*)malloc(sizeof(unsigned char)*section->data_size); + section->data = (unsigned char*)gf_malloc(sizeof(unsigned char)*section->data_size); memcpy(section->data, sec->section + section_start, sizeof(unsigned char)*section->data_size); gf_list_add(t->sections, section); - if (t->section_number == 1) status |= GF_M2TS_TABLE_START; + if (t->section_number == 1) { + status |= GF_M2TS_TABLE_START; + if (t->last_version_number == t->version_number) { + t->is_repeat = 1; + } else { + t->is_repeat = 0; + } + /*only update version number in the first section of the table*/ + t->last_version_number = t->version_number; + } if (t->is_init) { - if (t->last_version_number == t->version_number) { + if (t->is_repeat) { status |= GF_M2TS_TABLE_REPEAT; } else { status |= GF_M2TS_TABLE_UPDATE; - } + } } else { status |= GF_M2TS_TABLE_FOUND; } - t->last_version_number = t->version_number; - if (t->last_section_number == t->section_number) { status |= GF_M2TS_TABLE_END; t->is_init = 1; /*reset section number*/ t->section_number = 0; + t->is_repeat = 0; } if (sec->process_individual) { @@ -698,9 +898,8 @@ static void gf_m2ts_section_complete(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter t->section_number = 0; } } - /*clean-up (including broken sections)*/ - if (sec->section) free(sec->section); + if (sec->section) gf_free(sec->section); sec->section = NULL; sec->length = sec->received = 0; } @@ -714,15 +913,28 @@ static Bool gf_m2ts_is_long_section(u8 table_id) case GF_M2TS_TABLE_ID_EIT_OTHER_PF: case GF_M2TS_TABLE_ID_ST: case GF_M2TS_TABLE_ID_SIT: + case GF_M2TS_TABLE_ID_DSM_CC_PRIVATE: + case GF_M2TS_TABLE_ID_MPE_FEC: return 1; default: - if (table_id >= GF_M2TS_TABLE_ID_EIT_SCHEDULE_MIN && table_id <= GF_M2TS_TABLE_ID_EIT_SCHEDULE_MAX) + if (table_id >= GF_M2TS_TABLE_ID_EIT_SCHEDULE_MIN && table_id <= GF_M2TS_TABLE_ID_EIT_SCHEDULE_MAX) return 1; - else + else return 0; } } +static u32 gf_m2ts_get_section_length(char byte0, char byte1, char byte2) +{ + u32 length; + if (gf_m2ts_is_long_section(byte0)) { + length = 3 + ( ((byte1<<8) | (byte2&0xff)) & 0xfff ); + } else { + length = 3 + ( ((byte1<<8) | (byte2&0xff)) & 0x3ff ); + } + return length; +} + static void gf_m2ts_gather_section(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter *sec, GF_M2TS_SECTION_ES *ses, GF_M2TS_Header *hdr, unsigned char *data, u32 data_size) { u32 payload_size = data_size; @@ -730,9 +942,8 @@ static void gf_m2ts_gather_section(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter *s Bool disc = (expect_cc == hdr->continuity_counter) ? 0 : 1; sec->cc = expect_cc; - if (hdr->error || - (hdr->adaptation_field==2)) /* 2 = no payload in TS packet */ - return; + /*may happen if hdr->adaptation_field=2 no payload in TS packet*/ + if (!data_size) return; if (hdr->payload_start) { u32 ptr_field; @@ -744,9 +955,21 @@ static void gf_m2ts_gather_section(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter *s } /*end of previous section*/ + if (!sec->length && sec->received) { + /* the length of the section could not be determined from the previous TS packet because we had only 1 or 2 bytes */ + if (sec->received == 1) + sec->length = gf_m2ts_get_section_length(sec->section[0], data[1], data[2]); + else /* (sec->received == 2) */ + sec->length = gf_m2ts_get_section_length(sec->section[0], sec->section[1], data[1]); + sec->section = (char*)gf_realloc(sec->section, sizeof(char)*sec->length); + } + if (sec->length && sec->received + ptr_field >= sec->length) { - memcpy(sec->section + sec->received, data, sizeof(char)*ptr_field); - sec->received += ptr_field; + u32 len = sec->length - sec->received; + memcpy(sec->section + sec->received, data+1, sizeof(char)*len); + sec->received += len; + if (ptr_field > len) + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Invalid pointer field (@ptr_field=%d, @remaining=%d)\n", ptr_field, len) ); gf_m2ts_section_complete(ts, sec, ses); } data += ptr_field+1; @@ -755,49 +978,41 @@ static void gf_m2ts_gather_section(GF_M2TS_Demuxer *ts, GF_M2TS_SectionFilter *s aggregated_section: - if (sec->section) free(sec->section); + if (sec->section) gf_free(sec->section); sec->length = sec->received = 0; - sec->section = (char*)malloc(sizeof(char)*data_size); + sec->section = (char*)gf_malloc(sizeof(char)*data_size); memcpy(sec->section, data, sizeof(char)*data_size); sec->received = data_size; - sec->had_error = 0; - } else if (disc || hdr->error) { - if (sec->section) free(sec->section); + } else if (disc) { + if (sec->section) gf_free(sec->section); sec->section = NULL; sec->received = sec->length = 0; return; } else if (!sec->section) { return; } else { - if (sec->received+data_size > sec->length) + if (sec->length && sec->received+data_size > sec->length) data_size = sec->length - sec->received; if (sec->length) { memcpy(sec->section + sec->received, data, sizeof(char)*data_size); } else { - sec->section = (char*)realloc(sec->section, sizeof(char)*(sec->received+data_size)); + sec->section = (char*)gf_realloc(sec->section, sizeof(char)*(sec->received+data_size)); memcpy(sec->section + sec->received, data, sizeof(char)*data_size); } sec->received += data_size; } - if (hdr->error) - sec->had_error = 1; - /*alloc final buffer*/ if (!sec->length && (sec->received >= 3)) { - if (gf_m2ts_is_long_section(sec->section[0])) { - sec->length = 3 + ( ((sec->section[1]<<8) | (sec->section[2]&0xff)) & 0xfff ); - } else { - sec->length = 3 + ( ((sec->section[1]<<8) | (sec->section[2]&0xff)) & 0x3ff ); - } - sec->section = (char*)realloc(sec->section, sizeof(char)*sec->length); + sec->length = gf_m2ts_get_section_length(sec->section[0], sec->section[1], sec->section[2]); + sec->section = (char*)gf_realloc(sec->section, sizeof(char)*sec->length); if (sec->received > sec->length) { data_size -= sec->received - sec->length; sec->received = sec->length; } } - if (sec->received < sec->length) return; + if (!sec->length || sec->received < sec->length) return; /*OK done*/ gf_m2ts_section_complete(ts, sec, ses); @@ -813,6 +1028,98 @@ aggregated_section: } } +static void gf_m2ts_process_sdt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) +{ + u32 orig_net_id, pos, evt_type; + u32 nb_sections; + u32 data_size; + unsigned char *data; + GF_M2TS_Section *section; + + /*wait for the last section */ + if (!(status&GF_M2TS_TABLE_END)) return; + + /*skip if already received*/ + if (status&GF_M2TS_TABLE_REPEAT) { + if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_SDT_REPEAT, NULL); + return; + } + + if (table_id != GF_M2TS_TABLE_ID_SDT_ACTUAL) { + gf_m2ts_reset_sdt(ts); + return; + } + + gf_m2ts_reset_sdt(ts); + + nb_sections = gf_list_count(sections); + if (nb_sections > 1) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("SDT on multiple sections not supported\n")); + } + + section = (GF_M2TS_Section *)gf_list_get(sections, 0); + data = section->data; + data_size = section->data_size; + + orig_net_id = (data[0] << 8) | data[1]; + pos = 3; + while (pos < data_size) { + GF_M2TS_SDT *sdt; + u32 descs_size, d_pos, ulen; + + GF_SAFEALLOC(sdt, GF_M2TS_SDT); + gf_list_add(ts->SDTs, sdt); + + sdt->service_id = (data[pos]<<8) + data[pos+1]; + sdt->EIT_schedule = (data[pos+2] & 0x2) ? 1 : 0; + sdt->EIT_present_following = (data[pos+2] & 0x1); + sdt->running_status = (data[pos+3]>>5) & 0x7; + sdt->free_CA_mode = (data[pos+3]>>4) & 0x1; + descs_size = ((data[pos+3]&0xf)<<8) | data[pos+4]; + pos += 5; + + d_pos = 0; + while (d_pos < descs_size) { + u8 d_tag = data[pos+d_pos]; + u8 d_len = data[pos+d_pos+1]; + + switch (d_tag) { + case GF_M2TS_DVB_SERVICE_DESCRIPTOR: + if (sdt->provider) gf_free(sdt->provider); + sdt->provider = NULL; + if (sdt->service) gf_free(sdt->service); + sdt->service = NULL; + + d_pos+=2; + sdt->service_type = data[pos+d_pos]; + ulen = data[pos+d_pos+1]; + d_pos += 2; + sdt->provider = (char*)gf_malloc(sizeof(char)*(ulen+1)); + memcpy(sdt->provider, data+pos+d_pos, sizeof(char)*ulen); + sdt->provider[ulen] = 0; + d_pos += ulen; + + ulen = data[pos+d_pos]; + d_pos += 1; + sdt->service = (char*)gf_malloc(sizeof(char)*(ulen+1)); + memcpy(sdt->service, data+pos+d_pos, sizeof(char)*ulen); + sdt->service[ulen] = 0; + d_pos += ulen; + break; + + default: + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] Skipping descriptor (0x%x) not supported\n", d_tag)); + d_pos += d_len; + if (d_len == 0) d_pos = descs_size; + break; + } + } + pos += descs_size; + } + evt_type = GF_M2TS_EVT_SDT_FOUND; + if (ts->on_event) ts->on_event(ts, evt_type, NULL); +} + static void gf_m2ts_process_mpeg4section(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) { GF_M2TS_SL_PCK sl_pck; @@ -821,7 +1128,8 @@ static void gf_m2ts_process_mpeg4section(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES /*skip if already received*/ if (status & GF_M2TS_TABLE_REPEAT) - return; + if (!(es->flags & GF_M2TS_ES_SEND_REPEATED_SECTIONS)) + return; GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Sections for PID %d\n", es->pid) ); /*send all sections (eg SL-packets)*/ @@ -831,39 +1139,15 @@ static void gf_m2ts_process_mpeg4section(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES sl_pck.data = section->data; sl_pck.data_len = section->data_size; sl_pck.stream = (GF_M2TS_ES *)es; + sl_pck.version_number = version_number; if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_SL_PCK, &sl_pck); } } -GF_EXPORT -void gf_m2ts_decode_mjd_date(u32 date, u32 *year, u32 *month, u32 *day) +static void gf_m2ts_process_nit(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *nit_es, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) { - u32 yp, mp, k; - yp = (u32)floor((date - 15078.2)/365.25); - mp = (u32)floor((date - 14956.1 - floor(yp * 365.25))/30.6001); - *day = (u32)(date - 14956 - floor(yp * 365.25) - floor(mp * 30.6001)); - if (mp == 14 || mp == 15) k = 1; - else k = 0; - *year = yp + k + 1900; - *month = mp - 1 - k*12; -} -static void gf_m2ts_process_int(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ip_not_table, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) -{ - fprintf(stdout, "Processing IP/MAC Notification table (PID %d) %s\n", ip_not_table->pid, (status&GF_M2TS_TABLE_REPEAT)?"repeated":""); -} -#if 0 -static void gf_m2ts_process_mpe(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *mpe, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) -{ - fprintf(stdout, "Processing MPE Datagram (PID %d)\n", mpe->pid); -} -#endif - -static void gf_m2ts_process_nit(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *nit_es, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) -{ - - } static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF_List *sections, u8 table_id, u16 ex_table_id, u8 version_number, u8 last_section_number, u32 status) @@ -884,7 +1168,9 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_PMT_REPEAT, pmt->program); return; } - + + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PMT Found or updated\n")); + nb_sections = gf_list_count(sections); if (nb_sections > 1) { GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("PMT on multiple sections not supported\n")); @@ -892,7 +1178,7 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF section = (GF_M2TS_Section *)gf_list_get(sections, 0); data = section->data; - data_size = section->data_size; + data_size = section->data_size; pmt->program->pcr_pid = ((data[0] & 0x1f) << 8) | data[1]; @@ -904,8 +1190,8 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF tag = data[4]; len = data[5]; while (info_length > first_loop_len) { - if (tag == GF_M2TS_MPEG4_IOD_DESCRIPTOR) { - u8 scope, label; + if (tag == GF_M2TS_MPEG4_IOD_DESCRIPTOR) { + u8 scope, label; u32 size; GF_BitStream *iod_bs; scope = data[6]; @@ -929,58 +1215,89 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF GF_M2TS_PES *pes = NULL; GF_M2TS_SECTION_ES *ses = NULL; GF_M2TS_ES *es = NULL; - u32 pid, stream_type; - + u32 pid, stream_type, reg_desc_format; + stream_type = data[0]; pid = ((data[1] & 0x1f) << 8) | data[2]; desc_len = ((data[3] & 0xf) << 8) | data[4]; + reg_desc_format = 0; switch (stream_type) { - /* PES */ - case GF_M2TS_VIDEO_MPEG1: - case GF_M2TS_VIDEO_MPEG2: - case GF_M2TS_AUDIO_MPEG1: - case GF_M2TS_AUDIO_MPEG2: - case GF_M2TS_AUDIO_AAC: - case GF_M2TS_AUDIO_LATM_AAC: - case GF_M2TS_VIDEO_MPEG4: - case GF_M2TS_SYSTEMS_MPEG4_PES: - case GF_M2TS_VIDEO_H264: - case GF_M2TS_AUDIO_AC3: - case GF_M2TS_AUDIO_DTS: - case GF_M2TS_SUBTITLE_DVB: - case GF_M2TS_PRIVATE_DATA: - GF_SAFEALLOC(pes, GF_M2TS_PES); - es = (GF_M2TS_ES *)pes; - break; - /* Sections */ - case GF_M2TS_SYSTEMS_MPEG4_SECTIONS: - GF_SAFEALLOC(ses, GF_M2TS_SECTION_ES); - es = (GF_M2TS_ES *)ses; - es->flags |= GF_M2TS_ES_IS_SECTION; - /* carriage of ISO_IEC_14496 data in sections */ - if (stream_type == GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { - /*MPEG-4 sections need to be fully checked: if one section is lost, this means we lost - one SL packet in the AU so we must wait for the complete section again*/ - ses->sec = gf_m2ts_section_filter_new(gf_m2ts_process_mpeg4section, 0); - /*create OD container*/ - if (!pmt->program->additional_ods) { - pmt->program->additional_ods = gf_list_new(); - ts->has_4on2 = 1; - } + /* PES */ + case GF_M2TS_VIDEO_MPEG1: + case GF_M2TS_VIDEO_MPEG2: + case GF_M2TS_AUDIO_MPEG1: + case GF_M2TS_AUDIO_MPEG2: + case GF_M2TS_AUDIO_AAC: + case GF_M2TS_AUDIO_LATM_AAC: + case GF_M2TS_VIDEO_MPEG4: + case GF_M2TS_SYSTEMS_MPEG4_PES: + case GF_M2TS_VIDEO_H264: + case GF_M2TS_AUDIO_AC3: + case GF_M2TS_AUDIO_DTS: + case GF_M2TS_SUBTITLE_DVB: + GF_SAFEALLOC(pes, GF_M2TS_PES); + pes->cc = -1; + es = (GF_M2TS_ES *)pes; + break; + case GF_M2TS_PRIVATE_DATA: + GF_SAFEALLOC(pes, GF_M2TS_PES); + pes->cc = -1; + es = (GF_M2TS_ES *)pes; + break; + /* Sections */ + case GF_M2TS_SYSTEMS_MPEG4_SECTIONS: + GF_SAFEALLOC(ses, GF_M2TS_SECTION_ES); + es = (GF_M2TS_ES *)ses; + es->flags |= GF_M2TS_ES_IS_SECTION; + /* carriage of ISO_IEC_14496 data in sections */ + if (stream_type == GF_M2TS_SYSTEMS_MPEG4_SECTIONS) { + /*MPEG-4 sections need to be fully checked: if one section is lost, this means we lost + one SL packet in the AU so we must wait for the complete section again*/ + ses->sec = gf_m2ts_section_filter_new(gf_m2ts_process_mpeg4section, 0); + /*create OD container*/ + if (!pmt->program->additional_ods) { + pmt->program->additional_ods = gf_list_new(); + ts->has_4on2 = 1; } - break; + } + break; - case GF_M2TS_PRIVATE_SECTION: - default: - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] Stream type (0x%x) for PID %d not supported\n", stream_type, pid ) ); - break; + case GF_M2TS_13818_6_ANNEX_D: + case GF_M2TS_PRIVATE_SECTION: + GF_SAFEALLOC(ses, GF_M2TS_SECTION_ES); + es = (GF_M2TS_ES *)ses; + es->flags |= GF_M2TS_ES_IS_SECTION; + if (stream_type == GF_M2TS_13818_6_ANNEX_D) + printf("stream type DSM CC user private section: pid = %d \n", pid); + else + printf("unknown private section: pid = %d \n", pid); + /* NULL means: trigger the call to on_event with DVB_GENERAL type and the raw section as payload */ + ses->sec = gf_m2ts_section_filter_new(NULL, 1); + break; + + case GF_M2TS_MPE_SECTIONS: + printf("stream type MPE found : pid = %d \n", pid); +#ifdef DUMP_MPE_IP_DATAGRAMS + 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 */ + ((GF_M2TS_SECTION_ES*)es)->sec = gf_m2ts_section_filter_new(NULL, 1); + } +#endif + break; + + default: + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[MPEG-2 TS] Stream type (0x%x) for PID %d not supported\n", stream_type, pid ) ); + //GF_LOG(/*GF_LOG_WARNING*/GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Stream type (0x%x) for PID %d not supported\n", stream_type, pid ) ); + break; } if (es) { - es->stream_type = stream_type; + es->stream_type = (stream_type==GF_M2TS_PRIVATE_DATA) ? 0 : stream_type; es->program = pmt->program; es->pid = pid; + es->component_tag = -1; } pos += 5; @@ -991,32 +1308,59 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF u32 len = data[1]; if (es) { switch (tag) { - case GF_M2TS_ISO_639_LANGUAGE_DESCRIPTOR: + case GF_M2TS_ISO_639_LANGUAGE_DESCRIPTOR: pes->lang = GF_4CC(' ', data[2], data[3], data[4]); break; - case GF_M2TS_MPEG4_SL_DESCRIPTOR: + case GF_M2TS_MPEG4_SL_DESCRIPTOR: es->mpeg4_es_id = ((data[2] & 0x1f) << 8) | data[3]; es->flags |= GF_M2TS_ES_IS_SL; break; - case GF_M2TS_DVB_DATA_BROADCAST_ID_DESCRIPTOR: + case GF_M2TS_REGISTRATION_DESCRIPTOR: + reg_desc_format = GF_4CC(data[2], data[3], data[4], data[5]); + /*cf http://www.smpte-ra.org/mpegreg/mpegreg.html*/ + switch (reg_desc_format) { + case GF_4CC(0x41, 0x43, 0x2D, 0x33): + es->stream_type = GF_M2TS_AUDIO_AC3; + break; + case GF_4CC(0x56, 0x43, 0x2D, 0x31): + es->stream_type = GF_M2TS_VIDEO_VC1; + break; + } + break; + case GF_M2TS_DVB_EAC3_DESCRIPTOR: + es->stream_type = GF_M2TS_AUDIO_EC3; + break; + case GF_M2TS_DVB_DATA_BROADCAST_ID_DESCRIPTOR: { u32 id = data[2]<<8 | data[3]; if (id == 0xB) { ses->sec = gf_m2ts_section_filter_new(NULL, 1); - gf_list_add(ts->ip_mac_not_tables, es); } } break; case GF_M2TS_DVB_SUBTITLING_DESCRIPTOR: + pes->sub.language[0] = data[2]; + pes->sub.language[1] = data[3]; + pes->sub.language[2] = data[4]; + pes->sub.type = data[5]; + pes->sub.composition_page_id = (data[6]<<8) | data[7]; + pes->sub.ancillary_page_id = (data[8]<<8) | data[9]; + + es->stream_type = GF_M2TS_DVB_SUBTITLE; + break; + case GF_M2TS_DVB_STREAM_IDENTIFIER_DESCRIPTOR: { - pes->sub.language[0] = data[2]; - pes->sub.language[1] = data[3]; - pes->sub.language[2] = data[4]; - pes->sub.type = data[5]; - pes->sub.composition_page_id = (data[6]<<8) | data[7]; - pes->sub.ancillary_page_id = (data[8]<<8) | data[9]; + es->component_tag = data[2]; + printf("Component Tag: %d on Program %d\n", es->component_tag, es->program->number); } break; + case GF_M2TS_DVB_TELETEXT_DESCRIPTOR: + es->stream_type = GF_M2TS_DVB_TELETEXT; + break; + case GF_M2TS_DVB_VBI_DATA_DESCRIPTOR: + es->stream_type = GF_M2TS_DVB_VBI; + break; + default: GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] skipping descriptor (0x%x) not supported\n", tag)); break; @@ -1032,31 +1376,36 @@ static void gf_m2ts_process_pmt(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *pmt, GF desc_len-=len+2; } + if (es && !es->stream_type) { + gf_free(es); + es = NULL; + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Private Stream type (0x%x) for PID %d not supported\n", stream_type, pid ) ); + } + if (!es) continue; - /*watchout for pmt update*/ - if (/*(status==GF_M2TS_TABLE_UPDATE) && */ts->ess[pid]) { + /*watchout for pmt update - FIXME this likely won't work in most cases*/ + if (ts->ess[pid]) { GF_M2TS_ES *o_es = ts->ess[es->pid]; - if ((o_es->stream_type == es->stream_type) + if ((o_es->stream_type == es->stream_type) && ((o_es->flags & GF_M2TS_ES_STATIC_FLAGS_MASK) == (es->flags & GF_M2TS_ES_STATIC_FLAGS_MASK)) && (o_es->mpeg4_es_id == es->mpeg4_es_id) && ((o_es->flags & GF_M2TS_ES_IS_SECTION) || ((GF_M2TS_PES *)o_es)->lang == ((GF_M2TS_PES *)es)->lang) ) { - free(es); + gf_free(es); es = NULL; - + } else { + gf_m2ts_es_del(o_es); + ts->ess[es->pid] = NULL; } } if (es) { - es->stream_type = stream_type; - es->program = pmt->program; - es->pid = pid; ts->ess[es->pid] = es; gf_list_add(pmt->program->streams, es); - if (!(es->flags & GF_M2TS_ES_IS_SECTION) ) gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_DEFAULT); + if (!(es->flags & GF_M2TS_ES_IS_SECTION) ) gf_m2ts_set_pes_framing(pes, GF_M2TS_PES_FRAMING_SKIP); nb_es++; } @@ -1089,12 +1438,12 @@ static void gf_m2ts_process_pat(GF_M2TS_Demuxer *ts, GF_M2TS_SECTION_ES *ses, GF nb_sections = gf_list_count(sections); if (nb_sections > 1) { - GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("PMT on multiple sections not supported\n")); + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("PAT on multiple sections not supported\n")); } section = (GF_M2TS_Section *)gf_list_get(sections, 0); data = section->data; - data_size = section->data_size; + data_size = section->data_size; nb_progs = data_size / 4; @@ -1150,8 +1499,8 @@ static void gf_m2ts_pes_header(GF_M2TS_PES *pes, unsigned char *data, u32 data_s pesh->id = data[0]; pesh->pck_len = (data[1]<<8) | data[2]; -/* - 2bits +/* + 2bits scrambling_control = gf_bs_read_int(bs,2); priority = gf_bs_read_int(bs,1); */ @@ -1185,7 +1534,7 @@ static void gf_m2ts_pes_header(GF_M2TS_PES *pes, unsigned char *data, u32 data_s data+=5; len_check += 5; } - if (len_check < pesh->hdr_data_len) { + 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)); } else if (len_check > pesh->hdr_data_len) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d Wrong pes_header_data_length field %d bytes - read %d\n", pes->pid, pesh->hdr_data_len, len_check)); @@ -1196,25 +1545,32 @@ static void gf_m2ts_pes_header(GF_M2TS_PES *pes, unsigned char *data, u32 data_s 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) { Bool flush_pes = 0; - - if (hdr->error) { + +#if 0 + u8 expect_cc = (pes->cc<0) ? hdr->continuity_counter : (pes->cc + 1) & 0xf; + Bool disc = (expect_cc == hdr->continuity_counter) ? 0 : 1; + pes->cc = expect_cc; + + if (disc) { if (pes->data) { - free(pes->data); + gf_free(pes->data); pes->data = NULL; } pes->data_len = 0; pes->pes_len = 0; return; } +#endif + if (!pes->reframe) return; if (hdr->payload_start) { flush_pes = 1; - } 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*)realloc(pes->data, pes->data_len+data_size); - else pes->data = (char*)malloc(data_size); + if (pes->data) pes->data = (char*)gf_realloc(pes->data, pes->data_len+data_size); + else pes->data = (char*)gf_malloc(data_size); memcpy(pes->data+pes->data_len, data, data_size); pes->data_len += data_size; /*force discard*/ @@ -1225,8 +1581,6 @@ 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_PESHeader pesh; - if (pes->pid==25) - pes->pid=25; /*we need at least a full, valid start code !!*/ if ((pes->data_len >= 4) && !pes->data[0] && !pes->data[1] && (pes->data[2]==0x1)) { @@ -1239,15 +1593,14 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H /*OK read header*/ gf_m2ts_pes_header(pes, pes->data+3, pes->data_len-3, &pesh); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d Got PES header PTS %d\n", pes->pid, pesh.PTS)); /*3-byte start-code + 6 bytes header + hdr extensions*/ len = 9 + pesh.hdr_data_len; pes->reframe(ts, pes, pesh.DTS, pesh.PTS, pes->data+len, pes->data_len-len); - } + } /*SL-packetized stream*/ else if ((u8) pes->data[3]==0xfa) { GF_M2TS_SL_PCK sl_pck; - if (pes->pid==25) - pes->pid=25; /*read header*/ gf_m2ts_pes_header(pes, pes->data+3, pes->data_len-3, &pesh); @@ -1263,10 +1616,14 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H } else { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] Bad SL Packet size: (%d indicated < %d header)\n", pes->pid, pes->data_len, len)); } + } else { + GF_LOG(GF_LOG_WARNING, 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)); } if (pes->data) { - free(pes->data); + gf_free(pes->data); pes->data = NULL; pes->data_len = 0; pes->pes_len = 0; @@ -1274,15 +1631,24 @@ static void gf_m2ts_process_pes(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, GF_M2TS_H pes->rap = 0; if (!data_size) return; } - + /*we need to wait for first packet of PES*/ + if (!pes->data_len && !hdr->payload_start) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] PID %d: Waiting for PES header, trashing data\n", hdr->pid)); + return; + } /*reassemble*/ - if (pes->data) pes->data = (char*)realloc(pes->data, pes->data_len+data_size); - else pes->data = (char*)malloc(data_size); + if (pes->data){ + pes->data = (char*)gf_realloc(pes->data, pes->data_len+data_size); + //printf("[MPEG-2 TS] REALLOC \n"); + }else{ + pes->data = (char*)gf_malloc(data_size); + } memcpy(pes->data+pes->data_len, data, data_size); pes->data_len += data_size; - if (paf && paf->random_access_indicator) pes->rap = 1; - if (!pes->pes_len && (pes->data_len>=6)) pes->pes_len = (pes->data[4]<<8) | pes->data[5]; + if (paf && paf->random_access_indicator) pes->rap = 1; + if (hdr->payload_start && !pes->pes_len && (pes->data_len>=6)) pes->pes_len = (pes->data[4]<<8) | pes->data[5]; + } @@ -1311,7 +1677,7 @@ static void gf_m2ts_get_adaptation_field(GF_M2TS_Demuxer *ts, GF_M2TS_Adaptation paf->PCR_base = (PCR << 1) | (data[11] >> 7); paf->PCR_ext = ((data[11] & 1) << 8) | data[12]; } -#endif +#endif } static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data) @@ -1321,7 +1687,7 @@ static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data) GF_M2TS_AdaptationField af, *paf; u32 payload_size, af_size; u32 pos = 0; - + /* read TS packet header*/ hdr.sync = data[0]; hdr.error = (data[1] & 0x80) ? 1 : 0; @@ -1332,16 +1698,20 @@ static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data) hdr.adaptation_field = (data[3] >> 4) & 0x3; hdr.continuity_counter = data[3] & 0xf; -#if DEBUG_TS_PACKET + if (hdr.error) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[MPEG-2 TS] TS Packet has error (PID could be %d)\n", hdr.pid)); + return; + } +//#if DEBUG_TS_PACKET GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Packet PID %d\n", hdr.pid)); -#endif +//#endif paf = NULL; payload_size = 184; pos = 4; switch (hdr.adaptation_field) { /*adaptation+data*/ - case 3: + case 3: af_size = data[4]; if (af_size>183) { //error @@ -1354,7 +1724,7 @@ static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data) payload_size = 183 - af_size; break; /*adaptation only - still process in cas of PCR*/ - case 2: + case 2: af_size = data[4]; if (af_size>183) { //error @@ -1387,28 +1757,32 @@ static void gf_m2ts_process_packet(GF_M2TS_Demuxer *ts, unsigned char *data) return; } else if (hdr.pid == GF_M2TS_PID_NIT_ST) { /*ignore them, unused at application level*/ - if (!hdr.error) gf_m2ts_gather_section(ts, ts->nit, NULL, &hdr, data, payload_size); + gf_m2ts_gather_section(ts, ts->nit, NULL, &hdr, data, payload_size); return; } else if (hdr.pid == GF_M2TS_PID_EIT_ST_CIT) { /* ignore EIT messages for the moment */ - gf_m2ts_gather_section(ts, ts->eit, NULL, &hdr, data, payload_size); + gf_m2ts_gather_section(ts, ts->eit, NULL, &hdr, data, payload_size); return; } else if (hdr.pid == GF_M2TS_PID_TDT_TOT_ST) { - gf_m2ts_gather_section(ts, ts->tdt_tot_st, NULL, &hdr, data, payload_size); + gf_m2ts_gather_section(ts, ts->tdt_tot_st, NULL, &hdr, data, payload_size); + } else { + /* ignore packet */ } } else if (es->flags & GF_M2TS_ES_IS_SECTION) { /* The stream uses sections to carry its payload */ GF_M2TS_SECTION_ES *ses = (GF_M2TS_SECTION_ES *)es; + //fprintf(stderr, "000000000000000000000000000000000000000000000\n\n\n\n\n\n\n\n"); if (ses->sec) gf_m2ts_gather_section(ts, ses->sec, ses, &hdr, data, payload_size); + //fprintf(stderr, "callback: %x %x\n", ses->sec->process_section, gf_m2ts_process_pmt); } else { + GF_M2TS_PES *pes = (GF_M2TS_PES *)es; /* regular stream using PES packets */ - /* let the pes reassembler decide if packets with error shall be discarded*/ - gf_m2ts_process_pes(ts, (GF_M2TS_PES *)es, &hdr, data, payload_size, paf); + if (pes->reframe) gf_m2ts_process_pes(ts, pes, &hdr, data, payload_size, paf); } } - if (paf && paf->PCR_flag) { + if (paf && paf->PCR_flag && es) { GF_M2TS_PES_PCK pck; memset(&pck, 0, sizeof(GF_M2TS_PES_PCK)); - pck.PTS = paf->PCR_base * 300 + paf->PCR_ext; // ??? + pck.PTS = paf->PCR_base * 300 + paf->PCR_ext; pck.stream = (GF_M2TS_PES *)es; if (ts->on_event) ts->on_event(ts, GF_M2TS_EVT_PES_PCR, &pck); } @@ -1422,7 +1796,7 @@ GF_Err gf_m2ts_process_data(GF_M2TS_Demuxer *ts, char *data, u32 data_size) if (ts->buffer) { if (ts->alloc_size < ts->buffer_size+data_size) { ts->alloc_size = ts->buffer_size+data_size; - ts->buffer = (char*)realloc(ts->buffer, sizeof(char)*ts->alloc_size); + ts->buffer = (char*)gf_realloc(ts->buffer, sizeof(char)*ts->alloc_size); } memcpy(ts->buffer + ts->buffer_size, data, sizeof(char)*data_size); ts->buffer_size += data_size; @@ -1436,7 +1810,7 @@ GF_Err gf_m2ts_process_data(GF_M2TS_Demuxer *ts, char *data, u32 data_size) pos = gf_m2ts_sync(ts, is_align); if (pos==ts->buffer_size) { if (is_align) { - ts->buffer = (char*)malloc(sizeof(char)*data_size); + ts->buffer = (char*)gf_malloc(sizeof(char)*data_size); memcpy(ts->buffer, data, sizeof(char)*data_size); ts->alloc_size = ts->buffer_size = data_size; } @@ -1447,13 +1821,13 @@ GF_Err gf_m2ts_process_data(GF_M2TS_Demuxer *ts, char *data, u32 data_size) if (ts->buffer_size - pos < 188) { ts->buffer_size -= pos; if (!ts->buffer_size) { - if (!is_align) free(ts->buffer); + if (!is_align) gf_free(ts->buffer); ts->buffer = NULL; return GF_OK; } if (is_align) { data = ts->buffer+pos; - ts->buffer = (char*)malloc(sizeof(char)*ts->buffer_size); + ts->buffer = (char*)gf_malloc(sizeof(char)*ts->buffer_size); memcpy(ts->buffer, data, sizeof(char)*ts->buffer_size); ts->alloc_size = ts->buffer_size; } else { @@ -1464,10 +1838,44 @@ GF_Err gf_m2ts_process_data(GF_M2TS_Demuxer *ts, char *data, u32 data_size) /*process*/ gf_m2ts_process_packet(ts, ts->buffer+pos); pos += 188; - } + } return GF_OK; } +GF_ESD *gf_m2ts_get_esd(GF_M2TS_ES *es) +{ + GF_ESD *esd; + u32 k, esd_count; + + esd = NULL; + if (es->program->pmt_iod && es->program->pmt_iod->ESDescriptors) { + esd_count = gf_list_count(es->program->pmt_iod->ESDescriptors); + for (k = 0; k < esd_count; k++) { + GF_ESD *esd_tmp = (GF_ESD *)gf_list_get(es->program->pmt_iod->ESDescriptors, k); + if (esd_tmp->ESID != es->mpeg4_es_id) continue; + esd = esd_tmp; + break; + } + } + + if (!esd && es->program->additional_ods) { + u32 od_count, od_index; + od_count = gf_list_count(es->program->additional_ods); + for (od_index = 0; od_index < od_count; od_index++) { + GF_ObjectDescriptor *od = (GF_ObjectDescriptor *)gf_list_get(es->program->additional_ods, od_index); + esd_count = gf_list_count(od->ESDescriptors); + for (k = 0; k < esd_count; k++) { + GF_ESD *esd_tmp = (GF_ESD *)gf_list_get(od->ESDescriptors, k); + if (esd_tmp->ESID != es->mpeg4_es_id) continue; + esd = esd_tmp; + break; + } + } + } + + return esd; +} + void gf_m2ts_reset_parsers(GF_M2TS_Demuxer *ts) { u32 i; @@ -1480,25 +1888,25 @@ void gf_m2ts_reset_parsers(GF_M2TS_Demuxer *ts) ses->sec->cc = -1; ses->sec->length = 0; ses->sec->received = 0; - free(ses->sec->section); + 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); - free(t); + gf_free(t); } } else { GF_M2TS_PES *pes = (GF_M2TS_PES *)es; if (!pes || (pes->pid==pes->program->pmt_pid)) continue; pes->frame_state = 0; - if (pes->data) free(pes->data); + if (pes->data) gf_free(pes->data); pes->data = NULL; pes->data_len = 0; pes->PTS = pes->DTS = 0; } -// free(es); +// gf_free(es); // ts->ess[i] = NULL; } /* @@ -1506,18 +1914,18 @@ void gf_m2ts_reset_parsers(GF_M2TS_Demuxer *ts) ts->pat->cc = -1; ts->pat->length = 0; ts->pat->received = 0; - free(ts->pat->section); + gf_free(ts->pat->section); while (ts->pat->table) { GF_M2TS_Table *t = ts->pat->table; ts->pat->table = t->next; - if (t->data) free(t->data); - free(t); + if (t->data) gf_free(t->data); + gf_free(t); } } */ } -static void gf_m2ts_reframe_skip(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, u64 PTS, unsigned char *data, u32 data_len) +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) { u32 res; res = 0; @@ -1525,8 +1933,18 @@ static void gf_m2ts_reframe_skip(GF_M2TS_Demuxer *ts, GF_M2TS_PES *pes, u64 DTS, GF_Err gf_m2ts_set_pes_framing(GF_M2TS_PES *pes, u32 mode) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[MPEG-2 TS] Setting pes framing mode of PID %d to %d\n", pes->pid, mode) ); /*ignore request for section PIDs*/ - if (pes->flags & GF_M2TS_ES_IS_SECTION) return GF_OK; + if (pes->flags & GF_M2TS_ES_IS_SECTION) { + if (pes->flags & GF_M2TS_ES_IS_SL) { + if (mode==GF_M2TS_PES_FRAMING_DEFAULT) { + ((GF_M2TS_SECTION_ES *)pes)->sec->process_section = gf_m2ts_process_mpeg4section; + } else { + ((GF_M2TS_SECTION_ES *)pes)->sec->process_section = gf_m2ts_process_section_discard; + } + } + return GF_OK; + } if (pes->pid==pes->program->pmt_pid) return GF_BAD_PARAM; @@ -1534,14 +1952,21 @@ GF_Err gf_m2ts_set_pes_framing(GF_M2TS_PES *pes, u32 mode) pes->reframe = gf_m2ts_reframe_default; return GF_OK; } else if (mode==GF_M2TS_PES_FRAMING_SKIP) { - pes->reframe = gf_m2ts_reframe_skip; + if (pes->data) { + gf_free(pes->data); + pes->data = NULL; + } + pes->data_len = 0; + pes->pes_len = 0; + pes->reframe = NULL; return GF_OK; } else { // mode==GF_M2TS_PES_FRAMING_DEFAULT switch (pes->stream_type) { - case GF_M2TS_VIDEO_MPEG1: + case GF_M2TS_VIDEO_MPEG1: case GF_M2TS_VIDEO_MPEG2: pes->reframe = gf_m2ts_reframe_mpeg_video; break; +#ifndef GPAC_DISABLE_AV_PARSERS case GF_M2TS_AUDIO_MPEG1: case GF_M2TS_AUDIO_MPEG2: pes->reframe = gf_m2ts_reframe_mpeg_audio; @@ -1549,9 +1974,14 @@ GF_Err gf_m2ts_set_pes_framing(GF_M2TS_PES *pes, u32 mode) case GF_M2TS_VIDEO_H264: pes->reframe = gf_m2ts_reframe_avc_h264; break; + case GF_M2TS_AUDIO_AAC: + pes->reframe = gf_m2ts_reframe_aac_adts; + break; case GF_M2TS_AUDIO_LATM_AAC: pes->reframe = gf_m2ts_reframe_aac_latm; break; +#endif + case GF_M2TS_PRIVATE_DATA: /* TODO: handle DVB subtitle streams */ default: @@ -1570,10 +2000,15 @@ GF_M2TS_Demuxer *gf_m2ts_demux_new() ts->SDTs = gf_list_new(); ts->pat = gf_m2ts_section_filter_new(gf_m2ts_process_pat, 0); - ts->sdt = gf_m2ts_section_filter_new(NULL/*gf_m2ts_process_sdt*/, 1); + ts->sdt = gf_m2ts_section_filter_new(gf_m2ts_process_sdt, 1); ts->nit = gf_m2ts_section_filter_new(gf_m2ts_process_nit, 0); ts->eit = gf_m2ts_section_filter_new(NULL/*gf_m2ts_process_eit*/, 1); ts->tdt_tot_st = gf_m2ts_section_filter_new(NULL/*gf_m2ts_process_tdt_tot_st*/, 1); + +#ifdef DUMP_MPE_IP_DATAGRAMS + gf_dvb_mpe_init(ts); +#endif + return ts; } @@ -1589,7 +2024,7 @@ void gf_m2ts_demux_del(GF_M2TS_Demuxer *ts) for (i=0; i<8192; i++) { if (ts->ess[i]) gf_m2ts_es_del(ts->ess[i]); } - if (ts->buffer) free(ts->buffer); + if (ts->buffer) gf_free(ts->buffer); while (gf_list_count(ts->programs)) { GF_M2TS_Program *p = (GF_M2TS_Program *)gf_list_last(ts->programs); gf_list_rem_last(ts->programs); @@ -1600,12 +2035,25 @@ void gf_m2ts_demux_del(GF_M2TS_Demuxer *ts) gf_list_del(p->additional_ods); } if (p->pmt_iod) gf_odf_desc_del((GF_Descriptor *)p->pmt_iod); - free(p); + gf_free(p); } gf_list_del(ts->programs); gf_m2ts_reset_sdt(ts); gf_list_del(ts->SDTs); - free(ts); +#ifdef DUMP_MPE_IP_DATAGRAMS + gf_dvb_mpe_shutdown(ts); +#endif + + gf_free(ts); } + +void gf_m2ts_print_info(GF_M2TS_Demuxer *ts) +{ +#ifdef DUMP_MPE_IP_DATAGRAMS + gf_m2ts_print_mpe_info(ts); +#endif +} + +#endif /*GPAC_DISABLE_MPEG2TS*/ diff --git a/src/media_tools/reedsolomon.c b/src/media_tools/reedsolomon.c new file mode 100644 index 0000000..c0b9c6b --- /dev/null +++ b/src/media_tools/reedsolomon.c @@ -0,0 +1,569 @@ +/***************************** + * + * + * Multiplication and Arithmetic on Galois Field GF(256) + * + * From Mee, Daniel, "Magnetic Recording, Volume III", Ch. 5 by Patel. + * + * (c) 1991 Henry Minsky + * + * + ******************************/ + + +#include +#include +#include +#include + +/* 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 */ +/* x^8 + x^4 + x^3 + x^2 + 1 */ +#define PPOLY 0x1D + + +int gexp[512]; +int glog[256]; + + +static void init_exp_table (void); + + +void +init_galois_tables (void) +{ + /* initialize the table of powers of alpha */ + init_exp_table(); +} + + +static void +init_exp_table (void) +{ + int i, z; + int pinit,p1,p2,p3,p4,p5,p6,p7,p8; + + pinit = p2 = p3 = p4 = p5 = p6 = p7 = p8 = 0; + p1 = 1; + + gexp[0] = 1; + gexp[255] = gexp[0]; + glog[0] = 0; /* shouldn't log[0] be an error? */ + + for (i = 1; i < 256; i++) { + pinit = p8; + p8 = p7; + p7 = p6; + p6 = p5; + p5 = p4 ^ pinit; + p4 = p3 ^ pinit; + p3 = p2 ^ pinit; + p2 = p1; + p1 = pinit; + gexp[i] = p1 + p2*2 + p3*4 + p4*8 + p5*16 + p6*32 + p7*64 + p8*128; + gexp[i+255] = gexp[i]; + } + + for (i = 1; i < 256; i++) { + for (z = 0; z < 256; z++) { + if (gexp[z] == i) { + glog[i] = z; + break; + } + } + } +} + +/* multiplication using logarithms */ +int gmult(int a, int b) +{ + int i,j; + if (a==0 || b == 0) return (0); + i = glog[a]; + j = glog[b]; + return (gexp[i+j]); +} + + +int ginv (int elt) +{ + return (gexp[255-glog[elt]]); +} + + + +/*********************************************************************** + * Berlekamp-Peterson and Berlekamp-Massey Algorithms for error-location + * + * From Cain, Clark, "Error-Correction Coding For Digital Communications", pp. 205. + * + * This finds the coefficients of the error locator polynomial. + * + * The roots are then found by looking for the values of a^n + * where evaluating the polynomial yields zero. + * + * Error correction is done using the error-evaluator equation on pp 207. + * + * hqm@ai.mit.edu Henry Minsky + */ + + +/* The Error Locator Polynomial, also known as Lambda or Sigma. Lambda[0] == 1 */ +static int Lambda[MAXDEG]; + +/* The Error Evaluator Polynomial */ +static int Omega[MAXDEG]; + +/* local ANSI declarations */ +static int compute_discrepancy(int lambda[], int S[], int L, int n); +static void init_gamma(int gamma[]); +static void compute_modified_omega (void); +static void mul_z_poly (int src[]); + +/* error locations found using Chien's search*/ +static int ErrorLocs[256]; +static int NErrors; + +/* erasure flags */ +static int ErasureLocs[256]; +static int NErasures; + +/* From Cain, Clark, "Error-Correction Coding For Digital Communications", pp. 216. */ +void +Modified_Berlekamp_Massey (void) +{ + int n, L, L2, k, d, i; + int psi[MAXDEG], psi2[MAXDEG], D[MAXDEG]; + int gamma[MAXDEG]; + + /* initialize Gamma, the erasure locator polynomial */ + init_gamma(gamma); + + /* initialize to z */ + copy_poly(D, gamma); + mul_z_poly(D); + + copy_poly(psi, gamma); + k = -1; L = NErasures; + + for (n = NErasures; n < NPAR; n++) { + + d = compute_discrepancy(psi, synBytes, L, n); + + if (d != 0) { + + /* psi2 = psi - d*D */ + for (i = 0; i < MAXDEG; i++) psi2[i] = psi[i] ^ gmult(d, D[i]); + + + if (L < (n-k)) { + L2 = n-k; + k = n-L; + /* D = scale_poly(ginv(d), psi); */ + for (i = 0; i < MAXDEG; i++) D[i] = gmult(psi[i], ginv(d)); + L = L2; + } + + /* psi = psi2 */ + for (i = 0; i < MAXDEG; i++) psi[i] = psi2[i]; + } + + mul_z_poly(D); + } + + for(i = 0; i < MAXDEG; i++) Lambda[i] = psi[i]; + compute_modified_omega(); + + +} + +/* given Psi (called Lambda in Modified_Berlekamp_Massey) and synBytes, + compute the combined erasure/error evaluator polynomial as + Psi*S mod z^4 + */ +void +compute_modified_omega () +{ + int i; + int product[MAXDEG*2]; + + mult_polys(product, Lambda, synBytes); + zero_poly(Omega); + for(i = 0; i < NPAR; i++) Omega[i] = product[i]; + +} + +/* polynomial multiplication */ +void +mult_polys (int dst[], int p1[], int p2[]) +{ + int i, j; + int tmp1[MAXDEG*2]; + + for (i=0; i < (MAXDEG*2); i++) dst[i] = 0; + + for (i = 0; i < MAXDEG; i++) { + for(j=MAXDEG; j<(MAXDEG*2); j++) tmp1[j]=0; + + /* scale tmp1 by p1[i] */ + for(j=0; j= i; j--) tmp1[j] = tmp1[j-i]; + for (j = 0; j < i; j++) tmp1[j] = 0; + + /* add into partial product */ + for(j=0; j < (MAXDEG*2); j++) dst[j] ^= tmp1[j]; + } +} + + + +/* gamma = product (1-z*a^Ij) for erasure locs Ij */ +void +init_gamma (int gamma[]) +{ + int e, tmp[MAXDEG]; + + zero_poly(gamma); + zero_poly(tmp); + gamma[0] = 1; + + for (e = 0; e < NErasures; e++) { + copy_poly(tmp, gamma); + scale_poly(gexp[ErasureLocs[e]], tmp); + mul_z_poly(tmp); + add_polys(gamma, tmp); + } +} + + + +void +compute_next_omega (int d, int A[], int dst[], int src[]) +{ + int i; + for ( i = 0; i < MAXDEG; i++) { + dst[i] = src[i] ^ gmult(d, A[i]); + } +} + + + +int +compute_discrepancy (int lambda[], int S[], int L, int n) +{ + int i, sum=0; + + for (i = 0; i <= L; i++) + sum ^= gmult(lambda[i], S[n-i]); + return (sum); +} + +/********** polynomial arithmetic *******************/ + +void add_polys (int dst[], int src[]) +{ + int i; + for (i = 0; i < MAXDEG; i++) dst[i] ^= src[i]; +} + +void copy_poly (int dst[], int src[]) +{ + int i; + for (i = 0; i < MAXDEG; i++) dst[i] = src[i]; +} + +void scale_poly (int k, int poly[]) +{ + int i; + for (i = 0; i < MAXDEG; i++) poly[i] = gmult(k, poly[i]); +} + + +void zero_poly (int poly[]) +{ + int i; + for (i = 0; i < MAXDEG; i++) poly[i] = 0; +} + + +/* multiply by z, i.e., shift right by 1 */ +static void mul_z_poly (int src[]) +{ + int i; + for (i = MAXDEG-1; i > 0; i--) src[i] = src[i-1]; + src[0] = 0; +} + + +/* Finds all the roots of an error-locator polynomial with coefficients + * Lambda[j] by evaluating Lambda at successive values of alpha. + * + * This can be tested with the decoder's equations case. + */ + + +void +Find_Roots (void) +{ + int sum, r, k; + NErrors = 0; + + for (r = 1; r < 256; r++) { + sum = 0; + /* evaluate lambda at r */ + for (k = 0; k < NPAR+1; k++) { + sum ^= gmult(gexp[(k*r)%255], Lambda[k]); + } + if (sum == 0) + { + ErrorLocs[NErrors] = (255-r); NErrors++; + if (DEBUG) fprintf(stderr, "Root found at r = %d, (255-r) = %d\n", r, (255-r)); + } + } +} + +/* Combined Erasure And Error Magnitude Computation + * + * Pass in the codeword, its size in bytes, as well as + * an array of any known erasure locations, along the number + * of these erasures. + * + * Evaluate Omega(actually Psi)/Lambda' at the roots + * alpha^(-i) for error locs i. + * + * Returns 1 if everything ok, or 0 if an out-of-bounds error is found + * + */ + +int +correct_errors_erasures (unsigned char codeword[], + int csize, + int nerasures, + int erasures[]) +{ + int r, i, j, err; + + /* If you want to take advantage of erasure correction, be sure to + set NErasures and ErasureLocs[] with the locations of erasures. + */ + NErasures = nerasures; + for (i = 0; i < NErasures; i++) ErasureLocs[i] = erasures[i]; + + Modified_Berlekamp_Massey(); + Find_Roots(); + + + if ((NErrors <= NPAR) && NErrors > 0) { + + /* first check for illegal error locs */ + for (r = 0; r < NErrors; r++) { + if (ErrorLocs[r] >= csize) { + if (DEBUG) fprintf(stderr, "Error loc i=%d outside of codeword length %d\n", i, csize); + return(0); + } + } + + for (r = 0; r < NErrors; r++) { + int num, denom; + i = ErrorLocs[r]; + /* evaluate Omega at alpha^(-i) */ + + num = 0; + for (j = 0; j < MAXDEG; j++) + num ^= gmult(Omega[j], gexp[((255-i)*j)%255]); + + /* evaluate Lambda' (derivative) at alpha^(-i) ; all odd powers disappear */ + denom = 0; + for (j = 1; j < MAXDEG; j += 2) { + denom ^= gmult(Lambda[j], gexp[((255-i)*(j-1)) % 255]); + } + + err = gmult(num, ginv(denom)); + if (DEBUG) fprintf(stderr, "Error magnitude %#x at loc %d\n", err, csize-i); + + codeword[csize-i-1] ^= err; + } + return(1); + } + else { + if (DEBUG && NErrors) fprintf(stderr, "Uncorrectable codeword\n"); + return(0); + } +} + + + + /* + * Reed Solomon Encoder/Decoder + * + * (c) Henry Minsky (hqm@ua.com), Universal Access 1991-1995 + */ + + /* Encoder parity bytes */ + int pBytes[MAXDEG]; + + /* Decoder syndrome bytes */ + int synBytes[MAXDEG]; + + /* generator polynomial */ + int genPoly[MAXDEG*2]; + + int DEBUG = FALSE; + + static void + compute_genpoly (int nbytes, int genpoly[]); + + /* Initialize lookup tables, polynomials, etc. */ + void + initialize_ecc () + { + /* Initialize the galois field arithmetic tables */ + init_galois_tables(); + + /* Compute the encoder generator polynomial */ + compute_genpoly(NPAR, genPoly); + } + + void + zero_fill_from (unsigned char buf[], int from, int to) + { + int i; + for (i = from; i < to; i++) buf[i] = 0; + } + + /* debugging routines */ + void + print_parity (void) + { + int i; + printf("Parity Bytes: "); + for (i = 0; i < NPAR; i++) + printf("[%d]:%x, ",i,pBytes[i]); + printf("\n"); + } + + + void + print_syndrome (void) + { + int i; + printf("Syndrome Bytes: "); + for (i = 0; i < NPAR; i++) + printf("[%d]:%x, ",i,synBytes[i]); + printf("\n"); + } + + /* Append the parity bytes onto the end of the message */ + void + build_codeword (unsigned char msg[], int nbytes, unsigned char dst[]) + { + int i; + + for (i = 0; i < nbytes; i++) dst[i] = msg[i]; + + for (i = 0; i < NPAR; i++) { + dst[i+nbytes] = pBytes[NPAR-1-i]; + } + } + + /********************************************************** + * Reed Solomon Decoder + * + * Computes the syndrome of a codeword. Puts the results + * into the synBytes[] array. + */ + + void + decode_data(unsigned char data[], int nbytes) + { + int i, j, sum; + for (j = 0; j < NPAR; j++) { + sum = 0; + for (i = 0; i < nbytes; i++) { + sum = data[i] ^ gmult(gexp[j+1], sum); + } + synBytes[j] = sum; + } + } + + + /* Check if the syndrome is zero */ + int + check_syndrome (void) + { + int i, nz = 0; + for (i =0 ; i < NPAR; i++) { + if (synBytes[i] != 0) nz = 1; + } + return nz; + } + + + void + debug_check_syndrome (void) + { + int i; + + for (i = 0; i < 3; i++) { + printf(" inv log S[%d]/S[%d] = %d\n", i, i+1, + glog[gmult(synBytes[i], ginv(synBytes[i+1]))]); + } + } + + + /* Create a generator polynomial for an n byte RS code. + * The coefficients are returned in the genPoly arg. + * Make sure that the genPoly array which is passed in is + * at least n+1 bytes long. + */ + + static void + compute_genpoly (int nbytes, int genpoly[]) + { + int i, tp[256], tp1[256]; + + /* multiply (x + a^n) for n = 1 to nbytes */ + + zero_poly(tp1); + tp1[0] = 1; + + for (i = 1; i <= nbytes; i++) { + zero_poly(tp); + tp[0] = gexp[i]; /* set up x+a^n */ + tp[1] = 1; + + mult_polys(genpoly, tp, tp1); + copy_poly(tp1, genpoly); + } + } + + /* Simulate a LFSR with generator polynomial for n byte RS code. + * Pass in a pointer to the data array, and amount of data. + * + * The parity bytes are deposited into pBytes[], and the whole message + * and parity are copied to dest to make a codeword. + * + */ + + void + encode_data (unsigned char msg[], int nbytes, unsigned char dst[]) + { + int i, LFSR[NPAR+1],dbyte, j; + + for(i=0; i < NPAR+1; i++) LFSR[i]=0; + + for (i = 0; i < nbytes; i++) { + dbyte = msg[i] ^ LFSR[NPAR-1]; + for (j = NPAR-1; j > 0; j--) { + LFSR[j] = LFSR[j-1] ^ gmult(genPoly[j], dbyte); + } + LFSR[0] = gmult(genPoly[0], dbyte); + } + + for (i = 0; i < NPAR; i++) + pBytes[i] = LFSR[i]; + + build_codeword(msg, nbytes, dst); + } diff --git a/src/media_tools/saf.c b/src/media_tools/saf.c index a23e01a..c6ea069 100644 --- a/src/media_tools/saf.c +++ b/src/media_tools/saf.c @@ -84,18 +84,18 @@ GF_SAFMuxer *gf_saf_mux_new() static void saf_stream_del(GF_SAFStream *str) { - if (str->mime_type) free(str->mime_type); - if (str->remote_url) free(str->remote_url); - if (str->dsi) free(str->dsi); + if (str->mime_type) gf_free(str->mime_type); + if (str->remote_url) gf_free(str->remote_url); + if (str->dsi) gf_free(str->dsi); while (gf_list_count(str->aus)) { GF_SAFSample *au = (GF_SAFSample *)gf_list_last(str->aus); gf_list_rem_last(str->aus); - if (au->data) free(au->data); - free(au); + if (au->data) gf_free(au->data); + gf_free(au); } gf_list_del(str->aus); - free(str); + gf_free(str); } void gf_saf_mux_del(GF_SAFMuxer *mux) @@ -107,7 +107,7 @@ void gf_saf_mux_del(GF_SAFMuxer *mux) } gf_list_del(mux->streams); gf_mx_del(mux->mx); - free(mux); + gf_free(mux); } static GFINLINE GF_SAFStream *saf_get_stream(GF_SAFMuxer *mux, u32 stream_id) @@ -136,15 +136,15 @@ GF_Err gf_saf_mux_stream_add(GF_SAFMuxer *mux, u32 stream_id, u32 ts_res, u32 bu str->stream_type = stream_type; str->object_type = object_type; if (mime_type) { - str->mime_type = strdup(mime_type); + str->mime_type = gf_strdup(mime_type); str->stream_type = str->object_type = 0xFF; } str->dsi_len = dsi_len; if (dsi_len) { - str->dsi = (char *) malloc(sizeof(char)*dsi_len); + str->dsi = (char *) gf_malloc(sizeof(char)*dsi_len); memcpy(str->dsi, dsi, sizeof(char)*dsi_len); } - if (remote_url) str->remote_url = strdup(remote_url); + if (remote_url) str->remote_url = gf_strdup(remote_url); str->aus = gf_list_new(); mux->state = 0; gf_list_add(mux->streams, str); @@ -249,7 +249,7 @@ GF_Err gf_saf_mux_for_time(GF_SAFMuxer *mux, u32 time_ms, Bool force_end_of_sess gf_bs_write_int(bs, au ? au->ts : 0, 30); gf_bs_write_int(bs, dlen, 16); gf_bs_write_data(bs, data, dlen); - free(data); + gf_free(data); /*mark as signaled*/ str->state |= 1; @@ -287,8 +287,8 @@ GF_Err gf_saf_mux_for_time(GF_SAFMuxer *mux, u32 time_ms, Bool force_end_of_sess src->last_au_sn ++; src->last_au_ts = au->ts; - free(au->data); - free(au); + gf_free(au->data); + gf_free(au); } /*3: write all end of stream*/ diff --git a/src/media_tools/text_import.c b/src/media_tools/text_import.c index e193e9c..a050c01 100644 --- a/src/media_tools/text_import.c +++ b/src/media_tools/text_import.c @@ -31,7 +31,7 @@ #include #include -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_ISOM_WRITE enum { @@ -53,26 +53,29 @@ enum static s32 gf_text_get_utf_type(FILE *in_src) { + u32 readen; unsigned char BOM[5]; - fread(BOM, 5, 1, in_src); + readen = fread(BOM, sizeof(char), 5, in_src); + if (readen < 1) + return -1; if ((BOM[0]==0xFF) && (BOM[1]==0xFE)) { /*UTF32 not supported*/ if (!BOM[2] && !BOM[3]) return -1; - fseek(in_src, 2, SEEK_SET); + gf_f64_seek(in_src, 2, SEEK_SET); return 3; } if ((BOM[0]==0xFE) && (BOM[1]==0xFF)) { /*UTF32 not supported*/ if (!BOM[2] && !BOM[3]) return -1; - fseek(in_src, 2, SEEK_SET); + gf_f64_seek(in_src, 2, SEEK_SET); return 2; } else if ((BOM[0]==0xEF) && (BOM[1]==0xBB) && (BOM[2]==0xBF)) { - fseek(in_src, 3, SEEK_SET); + gf_f64_seek(in_src, 3, SEEK_SET); return 1; } if (BOM[0]<0x80) { - fseek(in_src, 0, SEEK_SET); + gf_f64_seek(in_src, 0, SEEK_SET); return 0; } return -1; @@ -83,7 +86,7 @@ static GF_Err gf_text_guess_format(char *filename, u32 *fmt) char szLine[2048]; u32 val; s32 uni_type; - FILE *test = fopen(filename, "rb"); + FILE *test = gf_f64_open(filename, "rb"); if (!test) return GF_URL_ERROR; uni_type = gf_text_get_utf_type(test); @@ -107,7 +110,10 @@ static GF_Err gf_text_guess_format(char *filename, u32 *fmt) if (!strnicmp(ext, ".ttxt", 5)) *fmt = GF_TEXT_IMPORT_TTXT; ext = strstr(szLine, "?>"); if (ext) ext += 2; - if (!ext[0]) fgets(szLine, 2048, test); + if (!ext[0]){ + if (!fgets(szLine, 2048, test)) + szLine[0] = '\0'; + } if (strstr(szLine, "x-quicktime-tx3g") || strstr(szLine, "text3GTrack")) *fmt = GF_TEXT_IMPORT_TEXML; else if (strstr(szLine, "TextStream")) *fmt = GF_TEXT_IMPORT_TTXT; } @@ -118,6 +124,7 @@ static GF_Err gf_text_guess_format(char *filename, u32 *fmt) return GF_OK; } + #define TTXT_DEFAULT_WIDTH 400 #define TTXT_DEFAULT_HEIGHT 60 #define TTXT_DEFAULT_FONT_SIZE 18 @@ -233,25 +240,24 @@ static char *gf_text_get_utf8_line(char *szLine, u32 lineSize, FILE *txt_in, s32 static GF_Err gf_text_import_srt(GF_MediaImporter *import) { FILE *srt_in; - Double scale; u32 track, timescale, i, count; GF_TextConfig*cfg; GF_Err e; GF_StyleRecord rec; GF_TextSample * samp; GF_ISOSample *s; - u32 sh, sm, ss, sms, eh, em, es, ems, txt_line, char_len, char_line, nb_samp, j, duration, file_size, rem_styles; + u32 sh, sm, ss, sms, eh, em, es, ems, txt_line, char_len, char_line, nb_samp, j, duration, rem_styles; Bool set_start_char, set_end_char, first_samp; - u64 start, end, prev_end; + u64 start, end, prev_end, file_size; u32 state, curLine, line, len, ID, OCR_ES_ID; s32 unicode_type; char szLine[2048], szText[2048], *ptr; unsigned short uniLine[5000], uniText[5000], *sptr; - srt_in = fopen(import->in_name, "rt"); - fseek(srt_in, 0, SEEK_END); - file_size = ftell(srt_in); - fseek(srt_in, 0, SEEK_SET); + srt_in = gf_f64_open(import->in_name, "rt"); + gf_f64_seek(srt_in, 0, SEEK_END); + file_size = gf_f64_tell(srt_in); + gf_f64_seek(srt_in, 0, SEEK_SET); unicode_type = gf_text_get_utf_type(srt_in); if (unicode_type<0) { @@ -303,10 +309,10 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import) for (i=0; isample_descriptions, i); if (!sd->font_count) { - sd->fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord)); + sd->fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)); sd->font_count = 1; sd->fonts[0].fontID = 1; - sd->fonts[0].fontName = strdup("Serif"); + sd->fonts[0].fontName = gf_strdup("Serif"); } if (!sd->default_style.fontID) sd->default_style.fontID = sd->fonts[0].fontID; if (!sd->default_style.font_size) sd->default_style.font_size = 16; @@ -329,10 +335,10 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import) entire display, and with bottom alignment things should be fine...*/ gf_isom_set_track_layout_info(import->dest, track, w<<16, h<<16, 0, 0, 0); sd = (GF_TextSampleDescriptor*)gf_odf_desc_new(GF_ODF_TX3G_TAG); - sd->fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord)); + sd->fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)); sd->font_count = 1; sd->fonts[0].fontID = 1; - sd->fonts[0].fontName = strdup(import->fontName ? import->fontName : "Serif"); + sd->fonts[0].fontName = gf_strdup(import->fontName ? import->fontName : "Serif"); sd->back_color = 0x00000000; /*transparent*/ sd->default_style.fontID = 1; sd->default_style.font_size = import->fontSize ? import->fontSize : TTXT_DEFAULT_FONT_SIZE; @@ -346,8 +352,8 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import) } 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 = w; - sd->default_pos.bottom = h; + sd->default_pos.right = import->twidth ? import->twidth : w; + sd->default_pos.bottom = import->theight ? import->theight : h; } } @@ -372,8 +378,6 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import) nb_samp = 0; samp = gf_isom_new_text_sample(); - scale = timescale; - scale /= 1000; first_samp = 1; while (1) { char *sOK = gf_text_get_utf8_line(szLine, 2048, srt_in, unicode_type); @@ -388,7 +392,7 @@ 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) (scale*(s64)prev_end); + s->DTS = (u64) ((timescale*prev_end)/1000); s->IsRAP = 1; gf_isom_add_sample(import->dest, track, 1, s); gf_isom_sample_del(&s); @@ -396,7 +400,7 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import) } s = gf_isom_text_to_sample(samp); - s->DTS = (u64) (scale*(s64) start); + s->DTS = (u64) ((timescale*start)/1000); s->IsRAP = 1; gf_isom_add_sample(import->dest, track, 1, s); gf_isom_sample_del(&s); @@ -409,7 +413,7 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import) gf_isom_text_reset(samp); //gf_import_progress(import, nb_samp, nb_samp+1); - gf_set_progress("Importing SRT", ftell(srt_in), file_size); + gf_set_progress("Importing SRT", gf_f64_tell(srt_in), file_size); if (duration && (end >= duration)) break; } if (!sOK) break; @@ -566,10 +570,10 @@ static GF_Err gf_text_import_srt(GF_MediaImporter *import) } /*final flush*/ - if (end) { + if (end && !(import->flags & GF_IMPORT_NO_TEXT_FLUSH ) ) { gf_isom_text_reset(samp); s = gf_isom_text_to_sample(samp); - s->DTS = (u64) (scale*(s64)end); + s->DTS = (u64) ((timescale*end)/1000); s->IsRAP = 1; gf_isom_add_sample(import->dest, track, 1, s); gf_isom_sample_del(&s); @@ -589,7 +593,8 @@ exit: static GF_Err gf_text_import_sub(GF_MediaImporter *import) { FILE *sub_in; - u32 track, ID, timescale, i, j, desc_idx, start, end, prev_end, nb_samp, duration, file_size, len, line; + u32 track, ID, timescale, i, j, desc_idx, start, end, prev_end, nb_samp, duration, len, line; + u64 file_size; GF_TextConfig*cfg; GF_Err e; Double FPS; @@ -599,10 +604,10 @@ static GF_Err gf_text_import_sub(GF_MediaImporter *import) char szLine[2048], szTime[20], szText[2048]; GF_ISOSample *s; - sub_in = fopen(import->in_name, "rt"); - fseek(sub_in, 0, SEEK_END); - file_size = ftell(sub_in); - fseek(sub_in, 0, SEEK_SET); + sub_in = gf_f64_open(import->in_name, "rt"); + gf_f64_seek(sub_in, 0, SEEK_END); + file_size = gf_f64_tell(sub_in); + gf_f64_seek(sub_in, 0, SEEK_SET); unicode_type = gf_text_get_utf_type(sub_in); if (unicode_type<0) { @@ -658,10 +663,10 @@ static GF_Err gf_text_import_sub(GF_MediaImporter *import) for (i=0; isample_descriptions, i); if (!sd->font_count) { - sd->fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord)); + sd->fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)); sd->font_count = 1; sd->fonts[0].fontID = 1; - sd->fonts[0].fontName = strdup("Serif"); + sd->fonts[0].fontName = gf_strdup("Serif"); } if (!sd->default_style.fontID) sd->default_style.fontID = sd->fonts[0].fontID; if (!sd->default_style.font_size) sd->default_style.font_size = 16; @@ -682,10 +687,10 @@ static GF_Err gf_text_import_sub(GF_MediaImporter *import) entire display, and with bottom alignment things should be fine...*/ gf_isom_set_track_layout_info(import->dest, track, w<<16, h<<16, 0, 0, 0); sd = (GF_TextSampleDescriptor*)gf_odf_desc_new(GF_ODF_TX3G_TAG); - sd->fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord)); + sd->fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)); sd->font_count = 1; sd->fonts[0].fontID = 1; - sd->fonts[0].fontName = strdup("Serif"); + sd->fonts[0].fontName = gf_strdup("Serif"); sd->back_color = 0x00000000; /*transparent*/ sd->default_style.fontID = 1; sd->default_style.font_size = TTXT_DEFAULT_FONT_SIZE; @@ -699,8 +704,8 @@ static GF_Err gf_text_import_sub(GF_MediaImporter *import) } 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 = w; - sd->default_pos.bottom = h; + sd->default_pos.right = import->twidth ? import->twidth : w; + sd->default_pos.bottom = import->theight ? import->theight : h; } } @@ -797,11 +802,11 @@ static GF_Err gf_text_import_sub(GF_MediaImporter *import) nb_samp++; gf_isom_text_reset(samp); prev_end = end; - gf_set_progress("Importing SUB", ftell(sub_in), file_size); + gf_set_progress("Importing SUB", gf_f64_tell(sub_in), file_size); if (duration && (end >= duration)) break; } /*final flush*/ - if (end) { + if (end && !(import->flags & GF_IMPORT_NO_TEXT_FLUSH ) ) { gf_isom_text_reset(samp); s = gf_isom_text_to_sample(samp); s->DTS = (u64)(FPS*(s64)end); @@ -926,7 +931,7 @@ char *ttxt_parse_string(GF_MediaImporter *import, char *str, Bool strip_lines) return str; } -static void ttxt_import_progress(void *cbk, u32 cur_samp, u32 count) +static void ttxt_import_progress(void *cbk, u64 cur_samp, u64 count) { gf_set_progress("TTXT Loading", cur_samp, count); } @@ -1071,11 +1076,11 @@ static GF_Err gf_text_import_ttxt(GF_MediaImporter *import) u32 m; if (ftable->type || strcmp(ftable->name, "FontTableEntry")) continue; td.font_count += 1; - td.fonts = (GF_FontRecord*)realloc(td.fonts, sizeof(GF_FontRecord)*td.font_count); + td.fonts = (GF_FontRecord*)gf_realloc(td.fonts, sizeof(GF_FontRecord)*td.font_count); m=0; while ( (att=(GF_XMLAttribute *)gf_list_enum(ftable->attributes, &m))) { if (!stricmp(att->name, "fontID")) td.fonts[td.font_count-1].fontID = atoi(att->value); - else if (!stricmp(att->name, "fontName")) td.fonts[td.font_count-1].fontName = strdup(att->value); + else if (!stricmp(att->name, "fontName")) td.fonts[td.font_count-1].fontName = gf_strdup(att->value); } } } @@ -1091,13 +1096,13 @@ static GF_Err gf_text_import_ttxt(GF_MediaImporter *import) } if (!td.fonts) { td.font_count = 1; - td.fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord)); + td.fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)); td.fonts[0].fontID = 1; - td.fonts[0].fontName = strdup("Serif"); + td.fonts[0].fontName = gf_strdup("Serif"); } gf_isom_new_text_description(import->dest, track, &td, NULL, NULL, &idx); - for (k=0; kattributes, &k))) { if (!strcmp(att->name, "fromChar")) start = atoi(att->value); else if (!strcmp(att->name, "toChar")) end = atoi(att->value); - else if (!strcmp(att->name, "URL")) url = strdup(att->value); - else if (!strcmp(att->name, "URLToolTip")) url_tt = strdup(att->value); + else if (!strcmp(att->name, "URL")) url = gf_strdup(att->value); + else if (!strcmp(att->name, "URLToolTip")) url_tt = gf_strdup(att->value); } gf_isom_text_add_hyperlink(samp, url, url_tt, start, end); - if (url) free(url); - if (url_tt) free(url_tt); + if (url) gf_free(url); + if (url_tt) gf_free(url_tt); } else if (!stricmp(ext->name, "Karaoke")) { u32 startTime; @@ -1315,7 +1320,7 @@ typedef struct } -static void texml_import_progress(void *cbk, u32 cur_samp, u32 count) +static void texml_import_progress(void *cbk, u64 cur_samp, u64 count) { gf_set_progress("TeXML Loading", cur_samp, count); } @@ -1471,10 +1476,10 @@ static GF_Err gf_text_import_texml(GF_MediaImporter *import) if (!strcmp(ftable->name, "font")) { u32 n=0; td.font_count += 1; - td.fonts = (GF_FontRecord*)realloc(td.fonts, sizeof(GF_FontRecord)*td.font_count); + td.fonts = (GF_FontRecord*)gf_realloc(td.fonts, sizeof(GF_FontRecord)*td.font_count); while ((att=(GF_XMLAttribute *)gf_list_enum(ftable->attributes, &n))) { if (!stricmp(att->name, "id")) td.fonts[td.font_count-1].fontID = atoi(att->value); - else if (!stricmp(att->name, "name")) td.fonts[td.font_count-1].fontName = strdup(att->value); + else if (!stricmp(att->name, "name")) td.fonts[td.font_count-1].fontName = gf_strdup(att->value); } } } @@ -1532,9 +1537,9 @@ static GF_Err gf_text_import_texml(GF_MediaImporter *import) } if (!td.fonts) { td.font_count = 1; - td.fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord)); + td.fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)); td.fonts[0].fontID = 1; - td.fonts[0].fontName = strdup("Serif"); + td.fonts[0].fontName = gf_strdup("Serif"); } gf_isom_text_has_similar_description(import->dest, track, &td, &descIndex, &same_box, &same_style); if (!descIndex) { @@ -1542,8 +1547,8 @@ static GF_Err gf_text_import_texml(GF_MediaImporter *import) same_style = same_box = 1; } - for (k=0; kname, "sampleData")) { @@ -1631,12 +1636,12 @@ static GF_Err gf_text_import_texml(GF_MediaImporter *import) while ((att=(GF_XMLAttribute *)gf_list_enum(sub->attributes, &m))) { if (!strcmp(att->name, "startMarker")) GET_MARKER_POS(start, 0) else if (!strcmp(att->name, "endMarker")) GET_MARKER_POS(end, 1) - else if (!strcmp(att->name, "URL") || !strcmp(att->name, "href")) url = strdup(att->value); - else if (!strcmp(att->name, "URLToolTip") || !strcmp(att->name, "altString")) url_tt = strdup(att->value); + else if (!strcmp(att->name, "URL") || !strcmp(att->name, "href")) url = gf_strdup(att->value); + else if (!strcmp(att->name, "URLToolTip") || !strcmp(att->name, "altString")) url_tt = gf_strdup(att->value); } gf_isom_text_add_hyperlink(samp, url, url_tt, start, end); - if (url) free(url); - if (url_tt) free(url_tt); + if (url) gf_free(url); + if (url_tt) gf_free(url_tt); } else if (!stricmp(sub->name, "karaoke")) { u32 time = 0; @@ -1709,5 +1714,5 @@ GF_Err gf_import_timed_text(GF_MediaImporter *import) } } -#endif +#endif /*GPAC_DISABLE_ISOM_WRITE*/ diff --git a/src/media_tools/vobsub.c b/src/media_tools/vobsub.c index 5c99223..d44f99a 100644 --- a/src/media_tools/vobsub.c +++ b/src/media_tools/vobsub.c @@ -391,7 +391,7 @@ GF_Err vobsub_read_idx(FILE *file, vobsub_file *vobsub, s32 *version) s32 hh, mm, ss, ms; char *buf = "filepos:"; - vspos = (vobsub_pos*)calloc(1, sizeof(vobsub_pos)); + vspos = (vobsub_pos*)gf_calloc(1, sizeof(vobsub_pos)); if (vspos == NULL) { error = 1; continue; @@ -402,7 +402,7 @@ GF_Err vobsub_read_idx(FILE *file, vobsub_file *vobsub, s32 *version) if (sscanf(str, "%d%c%d%c%d%c%d", &hh, &c, &mm, &c, &ss, &c, &ms) != 7) { - free(vspos); + gf_free(vspos); error = 1; continue; } @@ -412,18 +412,14 @@ GF_Err vobsub_read_idx(FILE *file, vobsub_file *vobsub, s32 *version) pos = strstr(str, buf); if (pos == NULL) { - free(vspos); + gf_free(vspos); error = 1; continue; } -#if defined (WIN32) && !defined(__GNUC__) - if (sscanf(pos + strlen(buf), "%I64x", &vspos->filepos) != 1) -#else - if (sscanf(pos + strlen(buf), "%llx", &vspos->filepos) != 1) -#endif + if (sscanf(pos + strlen(buf), LLX, &vspos->filepos) != 1) { - free(vspos); + gf_free(vspos); error = 1; continue; } @@ -442,7 +438,7 @@ GF_Err vobsub_read_idx(FILE *file, vobsub_file *vobsub, s32 *version) if (gf_list_add(vobsub->langs[id].subpos, vspos) != GF_OK) { - free(vspos); + gf_free(vspos); error = 1; continue; } @@ -472,7 +468,7 @@ void vobsub_free(vobsub_file *vobsub) do { vspos = (vobsub_pos*)gf_list_enum(list, &pos); - free(vspos); + gf_free(vspos); } while (vspos != NULL); } diff --git a/src/odf/desc_private.c b/src/odf/desc_private.c index f6b0f57..85aef08 100644 --- a/src/odf/desc_private.c +++ b/src/odf/desc_private.c @@ -44,6 +44,49 @@ GF_Descriptor *gf_odf_create_descriptor(u8 tag) case GF_ODF_SLC_TAG: //default : we create it without any predefinition... return gf_odf_new_slc(0); + case GF_ODF_MUXINFO_TAG: + return gf_odf_new_muxinfo(); + case GF_ODF_BIFS_CFG_TAG: + return gf_odf_new_bifs_cfg(); + case GF_ODF_UI_CFG_TAG: + return gf_odf_new_ui_cfg(); + case GF_ODF_TEXT_CFG_TAG: + return gf_odf_new_text_cfg(); + case GF_ODF_TX3G_TAG: + return gf_odf_new_tx3g(); + case GF_ODF_ELEM_MASK_TAG: + return gf_odf_New_ElemMask(); + case GF_ODF_LASER_CFG_TAG: + return gf_odf_new_laser_cfg(); + + case GF_ODF_DSI_TAG: + desc = gf_odf_new_default(); + if (!desc) return desc; + desc->tag = GF_ODF_DSI_TAG; + return desc; + + case GF_ODF_AUX_VIDEO_DATA: + return gf_odf_new_auxvid(); + + case GF_ODF_SEGMENT_TAG: + return gf_odf_new_segment(); + case GF_ODF_MEDIATIME_TAG: + return gf_odf_new_mediatime(); + + //File Format Specific + case GF_ODF_ISOM_IOD_TAG: + return gf_odf_new_isom_iod(); + case GF_ODF_ISOM_OD_TAG: + return gf_odf_new_isom_od(); + case GF_ODF_ESD_INC_TAG: + return gf_odf_new_esd_inc(); + case GF_ODF_ESD_REF_TAG: + return gf_odf_new_esd_ref(); + case GF_ODF_LANG_TAG: + return gf_odf_new_lang(); + +#ifndef GPAC_MINIMAL_ODF + case GF_ODF_CI_TAG: return gf_odf_new_ci(); case GF_ODF_SCI_TAG: @@ -71,8 +114,6 @@ GF_Descriptor *gf_odf_create_descriptor(u8 tag) return gf_odf_new_kw(); case GF_ODF_RATING_TAG: return gf_odf_new_rating(); - case GF_ODF_LANG_TAG: - return gf_odf_new_lang(); case GF_ODF_SHORT_TEXT_TAG: return gf_odf_new_short_text(); case GF_ODF_TEXT_TAG: @@ -92,55 +133,15 @@ GF_Descriptor *gf_odf_create_descriptor(u8 tag) case GF_ODF_PL_IDX_TAG: return gf_odf_new_pl_idx(); - //File Format Specific - case GF_ODF_ISOM_IOD_TAG: - return gf_odf_new_isom_iod(); - case GF_ODF_ISOM_OD_TAG: - return gf_odf_new_isom_od(); - case GF_ODF_ESD_INC_TAG: - return gf_odf_new_esd_inc(); - case GF_ODF_ESD_REF_TAG: - return gf_odf_new_esd_ref(); - - case GF_ODF_SEGMENT_TAG: - return gf_odf_new_segment(); - case GF_ODF_MEDIATIME_TAG: - return gf_odf_new_mediatime(); - case GF_ODF_IPMP_TL_TAG: return gf_odf_new_ipmp_tool_list(); case GF_ODF_IPMP_TOOL_TAG: return gf_odf_new_ipmp_tool(); - case GF_ODF_MUXINFO_TAG: - return gf_odf_new_muxinfo(); - case GF_ODF_BIFS_CFG_TAG: - return gf_odf_new_bifs_cfg(); - case GF_ODF_UI_CFG_TAG: - return gf_odf_new_ui_cfg(); - case GF_ODF_TEXT_CFG_TAG: - return gf_odf_new_text_cfg(); - case GF_ODF_TX3G_TAG: - return gf_odf_new_tx3g(); - case GF_ODF_ELEM_MASK_TAG: - return gf_odf_New_ElemMask(); - case GF_ODF_LASER_CFG_TAG: - return gf_odf_new_laser_cfg(); - - //default. The DecSpecInfo is handled as default - //the appropriate decoder (audio, video, bifs...) has to decode the DecSpecInfo alone ! - case GF_ODF_DSI_TAG: - desc = gf_odf_new_default(); - if (!desc) return desc; - desc->tag = GF_ODF_DSI_TAG; - return desc; - - case GF_ODF_AUX_VIDEO_DATA: - return gf_odf_new_auxvid(); - case 0: case 0xFF: return NULL; +#endif /*GPAC_MINIMAL_ODF*/ default: //ISO Reserved if ( (tag >= GF_ODF_ISO_RES_BEGIN_TAG) && @@ -162,12 +163,46 @@ GF_Err gf_odf_delete_descriptor(GF_Descriptor *desc) switch (desc->tag) { case GF_ODF_IOD_TAG : return gf_odf_del_iod((GF_InitialObjectDescriptor *)desc); + case GF_ODF_OD_TAG: + return gf_odf_del_od((GF_ObjectDescriptor *)desc); case GF_ODF_ESD_TAG : return gf_odf_del_esd((GF_ESD *)desc); case GF_ODF_DCD_TAG : return gf_odf_del_dcd((GF_DecoderConfig *)desc); case GF_ODF_SLC_TAG: return gf_odf_del_slc((GF_SLConfig *)desc); + + case GF_ODF_ISOM_IOD_TAG: + return gf_odf_del_isom_iod((GF_IsomInitialObjectDescriptor *)desc); + case GF_ODF_ISOM_OD_TAG: + return gf_odf_del_isom_od((GF_IsomObjectDescriptor *)desc); + + case GF_ODF_SEGMENT_TAG: + return gf_odf_del_segment((GF_Segment *) desc); + case GF_ODF_MEDIATIME_TAG: + return gf_odf_del_mediatime((GF_MediaTime *) desc); + + case GF_ODF_MUXINFO_TAG: + return gf_odf_del_muxinfo((GF_MuxInfo *)desc); + case GF_ODF_BIFS_CFG_TAG: + return gf_odf_del_bifs_cfg((GF_BIFSConfig *)desc); + case GF_ODF_UI_CFG_TAG: + return gf_odf_del_ui_cfg((GF_UIConfig *)desc); + case GF_ODF_TEXT_CFG_TAG: + return gf_odf_del_text_cfg((GF_TextConfig *)desc); + case GF_ODF_TX3G_TAG: + return gf_odf_del_tx3g((GF_TextSampleDescriptor*)desc); + case GF_ODF_LASER_CFG_TAG: + return gf_odf_del_laser_cfg((GF_LASERConfig *)desc); + + case GF_ODF_AUX_VIDEO_DATA: + return gf_odf_del_auxvid((GF_AuxVideoDescriptor *)desc); + + case GF_ODF_LANG_TAG: + return gf_odf_del_lang((GF_Language *)desc); + +#ifndef GPAC_MINIMAL_ODF + case GF_ODF_CC_TAG: return gf_odf_del_cc((GF_CCDescriptor *)desc); case GF_ODF_CC_DATE_TAG: @@ -193,14 +228,6 @@ GF_Err gf_odf_delete_descriptor(GF_Descriptor *desc) return gf_odf_del_ipmp_ptr((GF_IPMPPtr *)desc); case GF_ODF_KW_TAG: return gf_odf_del_kw((GF_KeyWord *)desc); - case GF_ODF_LANG_TAG: - return gf_odf_del_lang((GF_Language *)desc); - case GF_ODF_ISOM_IOD_TAG: - return gf_odf_del_isom_iod((GF_IsomInitialObjectDescriptor *)desc); - case GF_ODF_ISOM_OD_TAG: - return gf_odf_del_isom_od((GF_IsomObjectDescriptor *)desc); - case GF_ODF_OD_TAG: - return gf_odf_del_od((GF_ObjectDescriptor *)desc); case GF_ODF_OCI_DATE_TAG: return gf_odf_del_oci_date((GF_OCI_Data *)desc); case GF_ODF_OCI_NAME_TAG: @@ -220,32 +247,12 @@ GF_Err gf_odf_delete_descriptor(GF_Descriptor *desc) case GF_ODF_SCI_TAG: return gf_odf_del_sup_cid((GF_SCIDesc *)desc); - - case GF_ODF_SEGMENT_TAG: - return gf_odf_del_segment((GF_Segment *) desc); - case GF_ODF_MEDIATIME_TAG: - return gf_odf_del_mediatime((GF_MediaTime *) desc); - case GF_ODF_IPMP_TL_TAG: return gf_odf_del_ipmp_tool_list((GF_IPMP_ToolList *)desc); case GF_ODF_IPMP_TOOL_TAG: return gf_odf_del_ipmp_tool((GF_IPMP_Tool *)desc); - case GF_ODF_MUXINFO_TAG: - return gf_odf_del_muxinfo((GF_MuxInfo *)desc); - case GF_ODF_BIFS_CFG_TAG: - return gf_odf_del_bifs_cfg((GF_BIFSConfig *)desc); - case GF_ODF_UI_CFG_TAG: - return gf_odf_del_ui_cfg((GF_UIConfig *)desc); - case GF_ODF_TEXT_CFG_TAG: - return gf_odf_del_text_cfg((GF_TextConfig *)desc); - case GF_ODF_TX3G_TAG: - return gf_odf_del_tx3g((GF_TextSampleDescriptor*)desc); - case GF_ODF_LASER_CFG_TAG: - return gf_odf_del_laser_cfg((GF_LASERConfig *)desc); - - case GF_ODF_AUX_VIDEO_DATA: - return gf_odf_del_auxvid((GF_AuxVideoDescriptor *)desc); +#endif /*GPAC_MINIMAL_ODF*/ default: return gf_odf_del_default((GF_DefaultDescriptor *)desc); @@ -270,6 +277,38 @@ GF_Err gf_odf_read_descriptor(GF_BitStream *bs, GF_Descriptor *desc, u32 DescSiz return gf_odf_read_dcd(bs, (GF_DecoderConfig *)desc, DescSize); case GF_ODF_SLC_TAG : return gf_odf_read_slc(bs, (GF_SLConfig *)desc, DescSize); + case GF_ODF_OD_TAG: + return gf_odf_read_od(bs, (GF_ObjectDescriptor *)desc, DescSize); + + //MP4 File Format + case GF_ODF_ISOM_IOD_TAG: + return gf_odf_read_isom_iod(bs, (GF_IsomInitialObjectDescriptor *)desc, DescSize); + case GF_ODF_ISOM_OD_TAG: + return gf_odf_read_isom_od(bs, (GF_IsomObjectDescriptor *)desc, DescSize); + case GF_ODF_ESD_INC_TAG: + return gf_odf_read_esd_inc(bs, (GF_ES_ID_Inc *)desc, DescSize); + case GF_ODF_ESD_REF_TAG: + return gf_odf_read_esd_ref(bs, (GF_ES_ID_Ref *)desc, DescSize); + + case GF_ODF_SEGMENT_TAG: + return gf_odf_read_segment(bs, (GF_Segment *) desc, DescSize); + case GF_ODF_MEDIATIME_TAG: + return gf_odf_read_mediatime(bs, (GF_MediaTime *) desc, DescSize); + case GF_ODF_MUXINFO_TAG: + return gf_odf_read_muxinfo(bs, (GF_MuxInfo *) desc, DescSize); + + case GF_ODF_AUX_VIDEO_DATA: + return gf_odf_read_auxvid(bs, (GF_AuxVideoDescriptor *)desc, DescSize); + + case GF_ODF_LANG_TAG: + return gf_odf_read_lang(bs, (GF_Language *)desc, DescSize); + +#ifndef GPAC_MINIMAL_ODF + case GF_ODF_IPMP_TAG: + return gf_odf_read_ipmp(bs, (GF_IPMP_Descriptor *)desc, DescSize); + case GF_ODF_IPMP_PTR_TAG: + return gf_odf_read_ipmp_ptr(bs, (GF_IPMPPtr *)desc, DescSize); + case GF_ODF_CC_TAG: return gf_odf_read_cc(bs, (GF_CCDescriptor *)desc, DescSize); case GF_ODF_CC_DATE_TAG: @@ -285,16 +324,8 @@ GF_Err gf_odf_read_descriptor(GF_BitStream *bs, GF_Descriptor *desc, u32 DescSiz case GF_ODF_IPI_PTR_TAG: case GF_ODF_ISOM_IPI_PTR_TAG: return gf_odf_read_ipi_ptr(bs, (GF_IPIPtr *)desc, DescSize); - case GF_ODF_IPMP_TAG: - return gf_odf_read_ipmp(bs, (GF_IPMP_Descriptor *)desc, DescSize); - case GF_ODF_IPMP_PTR_TAG: - return gf_odf_read_ipmp_ptr(bs, (GF_IPMPPtr *)desc, DescSize); case GF_ODF_KW_TAG: return gf_odf_read_kw(bs, (GF_KeyWord *)desc, DescSize); - case GF_ODF_LANG_TAG: - return gf_odf_read_lang(bs, (GF_Language *)desc, DescSize); - case GF_ODF_OD_TAG: - return gf_odf_read_od(bs, (GF_ObjectDescriptor *)desc, DescSize); case GF_ODF_OCI_DATE_TAG: return gf_odf_read_oci_date(bs, (GF_OCI_Data *)desc, DescSize); case GF_ODF_OCI_NAME_TAG: @@ -313,37 +344,17 @@ GF_Err gf_odf_read_descriptor(GF_BitStream *bs, GF_Descriptor *desc, u32 DescSiz return gf_odf_read_smpte_camera(bs, (GF_SMPTECamera *)desc, DescSize); case GF_ODF_SCI_TAG: return gf_odf_read_sup_cid(bs, (GF_SCIDesc *)desc, DescSize); - //MP4 File Format - case GF_ODF_ISOM_IOD_TAG: - return gf_odf_read_isom_iod(bs, (GF_IsomInitialObjectDescriptor *)desc, DescSize); - case GF_ODF_ISOM_OD_TAG: - return gf_odf_read_isom_od(bs, (GF_IsomObjectDescriptor *)desc, DescSize); - case GF_ODF_ESD_INC_TAG: - return gf_odf_read_esd_inc(bs, (GF_ES_ID_Inc *)desc, DescSize); - case GF_ODF_ESD_REF_TAG: - return gf_odf_read_esd_ref(bs, (GF_ES_ID_Ref *)desc, DescSize); - - case GF_ODF_SEGMENT_TAG: - return gf_odf_read_segment(bs, (GF_Segment *) desc, DescSize); - case GF_ODF_MEDIATIME_TAG: - return gf_odf_read_mediatime(bs, (GF_MediaTime *) desc, DescSize); case GF_ODF_IPMP_TL_TAG: return gf_odf_read_ipmp_tool_list(bs, (GF_IPMP_ToolList *)desc, DescSize); case GF_ODF_IPMP_TOOL_TAG: return gf_odf_read_ipmp_tool(bs, (GF_IPMP_Tool *)desc, DescSize); - case GF_ODF_MUXINFO_TAG: - return gf_odf_read_muxinfo(bs, (GF_MuxInfo *) desc, DescSize); - - case GF_ODF_AUX_VIDEO_DATA: - return gf_odf_read_auxvid(bs, (GF_AuxVideoDescriptor *)desc, DescSize); - +#endif /*GPAC_MINIMAL_ODF*/ //default: case GF_ODF_DSI_TAG: default: return gf_odf_read_default(bs, (GF_DefaultDescriptor *)desc, DescSize); - } return GF_OK; } @@ -366,6 +377,32 @@ GF_Err gf_odf_size_descriptor(GF_Descriptor *desc, u32 *outSize) return gf_odf_size_dcd((GF_DecoderConfig *)desc, outSize); case GF_ODF_SLC_TAG : return gf_odf_size_slc((GF_SLConfig *)desc, outSize); + + case GF_ODF_OD_TAG: + return gf_odf_size_od((GF_ObjectDescriptor *)desc, outSize); + case GF_ODF_ISOM_IOD_TAG: + return gf_odf_size_isom_iod((GF_IsomInitialObjectDescriptor *)desc, outSize); + case GF_ODF_ISOM_OD_TAG: + return gf_odf_size_isom_od((GF_IsomObjectDescriptor *)desc, outSize); + case GF_ODF_ESD_INC_TAG: + return gf_odf_size_esd_inc((GF_ES_ID_Inc *)desc, outSize); + case GF_ODF_ESD_REF_TAG: + return gf_odf_size_esd_ref((GF_ES_ID_Ref *)desc, outSize); + + case GF_ODF_SEGMENT_TAG: + return gf_odf_size_segment((GF_Segment *) desc, outSize); + case GF_ODF_MEDIATIME_TAG: + return gf_odf_size_mediatime((GF_MediaTime *) desc, outSize); + case GF_ODF_MUXINFO_TAG: + return gf_odf_size_muxinfo((GF_MuxInfo *) desc, outSize); + + case GF_ODF_AUX_VIDEO_DATA: + return gf_odf_size_auxvid((GF_AuxVideoDescriptor *)desc, outSize); + + case GF_ODF_LANG_TAG: + return gf_odf_size_lang((GF_Language *)desc, outSize); + +#ifndef GPAC_MINIMAL_ODF case GF_ODF_CC_TAG: return gf_odf_size_cc((GF_CCDescriptor *)desc, outSize); case GF_ODF_CC_DATE_TAG: @@ -387,10 +424,6 @@ GF_Err gf_odf_size_descriptor(GF_Descriptor *desc, u32 *outSize) return gf_odf_size_ipmp_ptr((GF_IPMPPtr *)desc, outSize); case GF_ODF_KW_TAG: return gf_odf_size_kw((GF_KeyWord *)desc, outSize); - case GF_ODF_LANG_TAG: - return gf_odf_size_lang((GF_Language *)desc, outSize); - case GF_ODF_OD_TAG: - return gf_odf_size_od((GF_ObjectDescriptor *)desc, outSize); case GF_ODF_OCI_DATE_TAG: return gf_odf_size_oci_date((GF_OCI_Data *)desc, outSize); case GF_ODF_OCI_NAME_TAG: @@ -409,32 +442,14 @@ GF_Err gf_odf_size_descriptor(GF_Descriptor *desc, u32 *outSize) return gf_odf_size_smpte_camera((GF_SMPTECamera *)desc, outSize); case GF_ODF_SCI_TAG: return gf_odf_size_sup_cid((GF_SCIDesc *)desc, outSize); - //MP4File - case GF_ODF_ISOM_IOD_TAG: - return gf_odf_size_isom_iod((GF_IsomInitialObjectDescriptor *)desc, outSize); - case GF_ODF_ISOM_OD_TAG: - return gf_odf_size_isom_od((GF_IsomObjectDescriptor *)desc, outSize); - case GF_ODF_ESD_INC_TAG: - return gf_odf_size_esd_inc((GF_ES_ID_Inc *)desc, outSize); - case GF_ODF_ESD_REF_TAG: - return gf_odf_size_esd_ref((GF_ES_ID_Ref *)desc, outSize); - case GF_ODF_SEGMENT_TAG: - return gf_odf_size_segment((GF_Segment *) desc, outSize); - case GF_ODF_MEDIATIME_TAG: - return gf_odf_size_mediatime((GF_MediaTime *) desc, outSize); case GF_ODF_IPMP_TL_TAG: return gf_odf_size_ipmp_tool_list((GF_IPMP_ToolList *)desc, outSize); case GF_ODF_IPMP_TOOL_TAG: return gf_odf_size_ipmp_tool((GF_IPMP_Tool *)desc, outSize); - case GF_ODF_MUXINFO_TAG: - return gf_odf_size_muxinfo((GF_MuxInfo *) desc, outSize); - - case GF_ODF_AUX_VIDEO_DATA: - return gf_odf_size_auxvid((GF_AuxVideoDescriptor *)desc, outSize); - +#endif /*GPAC_MINIMAL_ODF*/ default: return gf_odf_size_default((GF_DefaultDescriptor *)desc, outSize); } @@ -456,6 +471,32 @@ GF_Err gf_odf_write_descriptor(GF_BitStream *bs, GF_Descriptor *desc) return gf_odf_write_dcd(bs, (GF_DecoderConfig *)desc); case GF_ODF_SLC_TAG : return gf_odf_write_slc(bs, (GF_SLConfig *)desc); + case GF_ODF_ESD_INC_TAG: + return gf_odf_write_esd_inc(bs, (GF_ES_ID_Inc *)desc); + case GF_ODF_ESD_REF_TAG: + return gf_odf_write_esd_ref(bs, (GF_ES_ID_Ref *)desc); + + + case GF_ODF_ISOM_IOD_TAG: + return gf_odf_write_isom_iod(bs, (GF_IsomInitialObjectDescriptor *)desc); + case GF_ODF_ISOM_OD_TAG: + return gf_odf_write_isom_od(bs, (GF_IsomObjectDescriptor *)desc); + case GF_ODF_OD_TAG: + return gf_odf_write_od(bs, (GF_ObjectDescriptor *)desc); + case GF_ODF_SEGMENT_TAG: + return gf_odf_write_segment(bs, (GF_Segment *) desc); + case GF_ODF_MEDIATIME_TAG: + return gf_odf_write_mediatime(bs, (GF_MediaTime *) desc); + case GF_ODF_MUXINFO_TAG: + return gf_odf_write_muxinfo(bs, (GF_MuxInfo *) desc); + + case GF_ODF_AUX_VIDEO_DATA: + return gf_odf_write_auxvid(bs, (GF_AuxVideoDescriptor *)desc); + + case GF_ODF_LANG_TAG: + return gf_odf_write_lang(bs, (GF_Language *)desc); + +#ifndef GPAC_MINIMAL_ODF case GF_ODF_CC_TAG: return gf_odf_write_cc(bs, (GF_CCDescriptor *)desc); case GF_ODF_CC_DATE_TAG: @@ -465,10 +506,6 @@ GF_Err gf_odf_write_descriptor(GF_BitStream *bs, GF_Descriptor *desc) case GF_ODF_CI_TAG: return gf_odf_write_ci(bs, (GF_CIDesc *)desc); - case GF_ODF_ESD_INC_TAG: - return gf_odf_write_esd_inc(bs, (GF_ES_ID_Inc *)desc); - case GF_ODF_ESD_REF_TAG: - return gf_odf_write_esd_ref(bs, (GF_ES_ID_Ref *)desc); case GF_ODF_TEXT_TAG: return gf_odf_write_exp_text(bs, (GF_ExpandedTextual *)desc); case GF_ODF_EXT_PL_TAG: @@ -482,14 +519,6 @@ GF_Err gf_odf_write_descriptor(GF_BitStream *bs, GF_Descriptor *desc) return gf_odf_write_ipmp_ptr(bs, (GF_IPMPPtr *)desc); case GF_ODF_KW_TAG: return gf_odf_write_kw(bs, (GF_KeyWord *)desc); - case GF_ODF_LANG_TAG: - return gf_odf_write_lang(bs, (GF_Language *)desc); - case GF_ODF_ISOM_IOD_TAG: - return gf_odf_write_isom_iod(bs, (GF_IsomInitialObjectDescriptor *)desc); - case GF_ODF_ISOM_OD_TAG: - return gf_odf_write_isom_od(bs, (GF_IsomObjectDescriptor *)desc); - case GF_ODF_OD_TAG: - return gf_odf_write_od(bs, (GF_ObjectDescriptor *)desc); case GF_ODF_OCI_DATE_TAG: return gf_odf_write_oci_date(bs, (GF_OCI_Data *)desc); case GF_ODF_OCI_NAME_TAG: @@ -509,29 +538,17 @@ GF_Err gf_odf_write_descriptor(GF_BitStream *bs, GF_Descriptor *desc) case GF_ODF_SCI_TAG: return gf_odf_write_sup_cid(bs, (GF_SCIDesc *)desc); - case GF_ODF_SEGMENT_TAG: - return gf_odf_write_segment(bs, (GF_Segment *) desc); - case GF_ODF_MEDIATIME_TAG: - return gf_odf_write_mediatime(bs, (GF_MediaTime *) desc); - case GF_ODF_IPMP_TL_TAG: return gf_odf_write_ipmp_tool_list(bs, (GF_IPMP_ToolList *)desc); case GF_ODF_IPMP_TOOL_TAG: return gf_odf_write_ipmp_tool(bs, (GF_IPMP_Tool *)desc); - - case GF_ODF_MUXINFO_TAG: - return gf_odf_write_muxinfo(bs, (GF_MuxInfo *) desc); - - case GF_ODF_AUX_VIDEO_DATA: - return gf_odf_write_auxvid(bs, (GF_AuxVideoDescriptor *)desc); - +#endif /*GPAC_MINIMAL_ODF*/ default: return gf_odf_write_default(bs, (GF_DefaultDescriptor *)desc); } return GF_OK; } - // // CONSTRUCTORS // @@ -677,4 +694,3 @@ GF_Err gf_odf_write_command(GF_BitStream *bs, GF_ODCom *com) return gf_odf_write_base_command(bs, (GF_BaseODCom *)com); } } - diff --git a/src/odf/descriptors.c b/src/odf/descriptors.c index 6a1a6c5..4082170 100644 --- a/src/odf/descriptors.c +++ b/src/odf/descriptors.c @@ -25,6 +25,47 @@ #include #include + + +GF_EXPORT +const char *gf_odf_stream_type_name(u32 streamType) +{ + switch (streamType) { + case GF_STREAM_OD: return "ObjectDescriptor"; + case GF_STREAM_OCR: return "ClockReference"; + case GF_STREAM_SCENE: return "SceneDescription"; + case GF_STREAM_VISUAL: return "Visual"; + case GF_STREAM_AUDIO: return "Audio"; + case GF_STREAM_MPEG7: return "MPEG7"; + case GF_STREAM_IPMP: return "IPMP"; + case GF_STREAM_OCI: return "OCI"; + case GF_STREAM_MPEGJ: return "MPEGJ"; + case GF_STREAM_INTERACT: return "Interaction"; + case GF_STREAM_TEXT: return "Text"; + case GF_STREAM_ND_SUBPIC: return "NeroDigital Subpicture"; + default: return "Unknown"; + } +} + +GF_EXPORT +u32 gf_odf_stream_type_by_name(const char *streamType) +{ + if (!streamType) return 0; + if (!stricmp(streamType, "ObjectDescriptor")) return GF_STREAM_OD; + if (!stricmp(streamType, "ClockReference")) return GF_STREAM_OCR; + if (!stricmp(streamType, "SceneDescription")) return GF_STREAM_SCENE; + if (!stricmp(streamType, "Visual")) return GF_STREAM_VISUAL; + if (!stricmp(streamType, "Audio")) return GF_STREAM_AUDIO; + if (!stricmp(streamType, "MPEG7")) return GF_STREAM_MPEG7; + if (!stricmp(streamType, "IPMP")) return GF_STREAM_IPMP; + if (!stricmp(streamType, "OCI")) return GF_STREAM_OCI; + if (!stricmp(streamType, "MPEGJ")) return GF_STREAM_MPEGJ; + if (!stricmp(streamType, "Interaction")) return GF_STREAM_INTERACT; + if (!stricmp(streamType, "Text")) return GF_STREAM_TEXT; + return 0; +} + + s32 gf_odf_size_field_size(u32 size_desc) { if (size_desc < 0x00000080) { @@ -80,7 +121,13 @@ GF_Err gf_odf_parse_descriptor(GF_BitStream *bs, GF_Descriptor **desc, u32 *desc else if (!tag || (tag == 0xFF)) { return GF_ODF_INVALID_DESCRIPTOR; } +#ifndef GPAC_MINIMAL_ODF return GF_OUT_OF_MEM; +#else + gf_bs_skip_bytes(bs, size); + *desc_size = size + sizeHeader - gf_odf_size_field_size(*desc_size); + return GF_OK; +#endif } newDesc->tag = tag; @@ -125,30 +172,6 @@ GF_Err gf_odf_delete_descriptor_list(GF_List *descList) return GF_OK; } - - - -GF_Err gf_odf_size_descriptor_list(GF_List *descList, u32 *outSize) -{ - GF_Err e; - GF_Descriptor *tmp; - u32 tmpSize, count, i; - if (! descList) return GF_OK; - - count = gf_list_count(descList); - for ( i = 0; i < count; i++ ) { - tmp = (GF_Descriptor*)gf_list_get(descList, i); - if (tmp) { - e = gf_odf_size_descriptor(tmp, &tmpSize); - if (e) return e; - if (tmpSize) *outSize += tmpSize + gf_odf_size_field_size(tmpSize); - } - } - return GF_OK; -} - - - GF_Err gf_odf_write_base_descriptor(GF_BitStream *bs, u8 tag, u32 size) { u32 length; @@ -186,6 +209,64 @@ GF_Err gf_odf_write_base_descriptor(GF_BitStream *bs, u8 tag, u32 size) return GF_OK; } + +GF_Err gf_odf_size_descriptor_list(GF_List *descList, u32 *outSize) +{ + GF_Err e; + GF_Descriptor *tmp; + u32 tmpSize, count, i; + if (! descList) return GF_OK; + + count = gf_list_count(descList); + for ( i = 0; i < count; i++ ) { + tmp = (GF_Descriptor*)gf_list_get(descList, i); + if (tmp) { + e = gf_odf_size_descriptor(tmp, &tmpSize); + if (e) return e; + if (tmpSize) *outSize += tmpSize + gf_odf_size_field_size(tmpSize); + } + } + return GF_OK; +} + +GF_Err gf_odf_write_descriptor_list(GF_BitStream *bs, GF_List *descList) +{ + GF_Err e; + u32 count, i; + GF_Descriptor *tmp; + + if (! descList) return GF_OK; + count = gf_list_count(descList); + for ( i = 0; i < count; i++ ) { + tmp = (GF_Descriptor*)gf_list_get(descList, i); + if (tmp) { + e = gf_odf_write_descriptor(bs, tmp); + if (e) return e; + } + } + return GF_OK; +} + +GF_Err gf_odf_write_descriptor_list_filter(GF_BitStream *bs, GF_List *descList, u8 only_tag) +{ + GF_Err e; + u32 count, i; + GF_Descriptor *tmp; + + if (! descList) return GF_OK; + count = gf_list_count(descList); + for ( i = 0; i < count; i++ ) { + tmp = (GF_Descriptor*)gf_list_get(descList, i); + if (tmp && (tmp->tag==only_tag) ) { + e = gf_odf_write_descriptor(bs, tmp); + if (e) return e; + } + } + return GF_OK; +} +#ifndef GPAC_DISABLE_ODF + + u32 gf_ipmpx_array_size(GF_BitStream *bs, u32 *array_size) { u32 val, size, io_size; @@ -235,80 +316,7 @@ void gf_ipmpx_write_array(GF_BitStream *bs, char *data, u32 data_len) } -GF_Err gf_odf_write_descriptor_list(GF_BitStream *bs, GF_List *descList) -{ - GF_Err e; - u32 count, i; - GF_Descriptor *tmp; - - if (! descList) return GF_OK; - count = gf_list_count(descList); - for ( i = 0; i < count; i++ ) { - tmp = (GF_Descriptor*)gf_list_get(descList, i); - if (tmp) { - e = gf_odf_write_descriptor(bs, tmp); - if (e) return e; - } - } - return GF_OK; -} - -GF_Err gf_odf_write_descriptor_list_filter(GF_BitStream *bs, GF_List *descList, u8 only_tag) -{ - GF_Err e; - u32 count, i; - GF_Descriptor *tmp; - - if (! descList) return GF_OK; - count = gf_list_count(descList); - for ( i = 0; i < count; i++ ) { - tmp = (GF_Descriptor*)gf_list_get(descList, i); - if (tmp && (tmp->tag==only_tag) ) { - e = gf_odf_write_descriptor(bs, tmp); - if (e) return e; - } - } - return GF_OK; -} - -GF_EXPORT -const char *gf_odf_stream_type_name(u32 streamType) -{ - switch (streamType) { - case GF_STREAM_OD: return "ObjectDescriptor"; - case GF_STREAM_OCR: return "ClockReference"; - case GF_STREAM_SCENE: return "SceneDescription"; - case GF_STREAM_VISUAL: return "Visual"; - case GF_STREAM_AUDIO: return "Audio"; - case GF_STREAM_MPEG7: return "MPEG7"; - case GF_STREAM_IPMP: return "IPMP"; - case GF_STREAM_OCI: return "OCI"; - case GF_STREAM_MPEGJ: return "MPEGJ"; - case GF_STREAM_INTERACT: return "Interaction"; - case GF_STREAM_TEXT: return "Text"; - case GF_STREAM_ND_SUBPIC: return "NeroDigital Subpicture"; - default: return "Unknown"; - } -} - -GF_EXPORT -u32 gf_odf_stream_type_by_name(const char *streamType) -{ - if (!streamType) return 0; - if (!stricmp(streamType, "ObjectDescriptor")) return GF_STREAM_OD; - if (!stricmp(streamType, "ClockReference")) return GF_STREAM_OCR; - if (!stricmp(streamType, "SceneDescription")) return GF_STREAM_SCENE; - if (!stricmp(streamType, "Visual")) return GF_STREAM_VISUAL; - if (!stricmp(streamType, "Audio")) return GF_STREAM_AUDIO; - if (!stricmp(streamType, "MPEG7")) return GF_STREAM_MPEG7; - if (!stricmp(streamType, "IPMP")) return GF_STREAM_IPMP; - if (!stricmp(streamType, "OCI")) return GF_STREAM_OCI; - if (!stricmp(streamType, "MPEGJ")) return GF_STREAM_MPEGJ; - if (!stricmp(streamType, "Interaction")) return GF_STREAM_INTERACT; - if (!stricmp(streamType, "Text")) return GF_STREAM_TEXT; - return 0; -} - +#endif /*GPAC_MINIMAL_ODF*/ /*special authoring functions*/ GF_EXPORT @@ -421,7 +429,7 @@ GF_Err gf_odf_get_ui_config(GF_DefaultDescriptor *dsi, GF_UIConfig *cfg) cfg->tag = GF_ODF_UI_CFG_TAG; bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ); len = gf_bs_read_int(bs, 8); - cfg->deviceName = (char*)malloc(sizeof(char) * (len+1)); + cfg->deviceName = (char*)gf_malloc(sizeof(char) * (len+1)); for (i=0; ideviceName[i] = gf_bs_read_int(bs, 8); cfg->deviceName[i] = 0; @@ -483,18 +491,18 @@ void gf_odf_avc_cfg_del(GF_AVCConfig *cfg) while (gf_list_count(cfg->sequenceParameterSets)) { GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(cfg->sequenceParameterSets, 0); gf_list_rem(cfg->sequenceParameterSets, 0); - if (sl->data) free(sl->data); - free(sl); + if (sl->data) gf_free(sl->data); + gf_free(sl); } gf_list_del(cfg->sequenceParameterSets); while (gf_list_count(cfg->pictureParameterSets)) { GF_AVCConfigSlot *sl = (GF_AVCConfigSlot *)gf_list_get(cfg->pictureParameterSets, 0); gf_list_rem(cfg->pictureParameterSets, 0); - if (sl->data) free(sl->data); - free(sl); + if (sl->data) gf_free(sl->data); + gf_free(sl); } gf_list_del(cfg->pictureParameterSets); - free(cfg); + gf_free(cfg); } GF_EXPORT @@ -546,17 +554,17 @@ GF_AVCConfig *gf_odf_avc_cfg_read(char *dsi, u32 dsi_size) gf_bs_read_int(bs, 3); count = gf_bs_read_int(bs, 5); for (i=0; isize = gf_bs_read_int(bs, 16); - sl->data = (char*)malloc(sizeof(char)*sl->size); + sl->data = (char*)gf_malloc(sizeof(char)*sl->size); gf_bs_read_data(bs, sl->data, sl->size); gf_list_add(avcc->sequenceParameterSets, sl); } count = gf_bs_read_int(bs, 8); for (i=0; isize = gf_bs_read_int(bs, 16); - sl->data = (char*)malloc(sizeof(char)*sl->size); + sl->data = (char*)gf_malloc(sizeof(char)*sl->size); gf_bs_read_data(bs, sl->data, sl->size); gf_list_add(avcc->pictureParameterSets, sl); } @@ -567,7 +575,7 @@ GF_AVCConfig *gf_odf_avc_cfg_read(char *dsi, u32 dsi_size) GF_Descriptor *gf_odf_new_tx3g() { - GF_TextSampleDescriptor *newDesc = (GF_TextSampleDescriptor*) malloc(sizeof(GF_TextSampleDescriptor)); + GF_TextSampleDescriptor *newDesc = (GF_TextSampleDescriptor*) gf_malloc(sizeof(GF_TextSampleDescriptor)); if (!newDesc) return NULL; memset(newDesc, 0, sizeof(GF_TextSampleDescriptor)); newDesc->tag = GF_ODF_TX3G_TAG; @@ -577,16 +585,16 @@ GF_Err gf_odf_del_tx3g(GF_TextSampleDescriptor *sd) { u32 i; for (i=0; ifont_count; i++) - if (sd->fonts[i].fontName) free(sd->fonts[i].fontName); - free(sd->fonts); - free(sd); + if (sd->fonts[i].fontName) gf_free(sd->fonts[i].fontName); + gf_free(sd->fonts); + gf_free(sd); return GF_OK; } /*TextConfig*/ GF_Descriptor *gf_odf_new_text_cfg() { - GF_TextConfig *newDesc = (GF_TextConfig*) malloc(sizeof(GF_TextConfig)); + GF_TextConfig *newDesc = (GF_TextConfig*) gf_malloc(sizeof(GF_TextConfig)); if (!newDesc) return NULL; memset(newDesc, 0, sizeof(GF_TextConfig)); newDesc->tag = GF_ODF_TEXT_CFG_TAG; @@ -616,7 +624,7 @@ GF_Err gf_odf_del_text_cfg(GF_TextConfig *desc) { ResetTextConfig(desc); gf_list_del(desc->sample_descriptions); - free(desc); + gf_free(desc); return GF_OK; } @@ -653,15 +661,16 @@ GF_Err gf_odf_get_text_config(GF_DefaultDescriptor *dsi, u8 oti, GF_TextConfig * cfg->nb_compatible_formats = gf_bs_read_int(bs, 8); for (i=0; inb_compatible_formats; i++) cfg->compatible_formats[i] = gf_bs_read_int(bs, 8); } +#ifndef GPAC_DISABLE_ISOM if (has_sd) { u8 sample_index; GF_TextSampleDescriptor *txdesc; - GF_TextSampleEntryBox *a; - s32 avail; + GF_Tx3gSampleEntryBox *a; + s64 avail; u32 nb_desc = gf_bs_read_int(bs, 8); /*parse TTU[5]s*/ - avail = (s32) gf_bs_available(bs); + avail = (s64) gf_bs_available(bs); for (i=0; isample_index = sample_index; txdesc->displayFlags = a->displayFlags; txdesc->back_color = a->back_color; @@ -683,16 +692,18 @@ GF_Err gf_odf_get_text_config(GF_DefaultDescriptor *dsi, u8 oti, GF_TextConfig * txdesc->horiz_justif = a->horizontal_justification; txdesc->font_count = a->font_table ? a->font_table->entry_count : 0; if (txdesc->font_count) { - txdesc->fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord)*txdesc->font_count); + txdesc->fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)*txdesc->font_count); for (j=0; jfont_count; j++) { txdesc->fonts[j].fontID = a->font_table->fonts[j].fontID; - txdesc->fonts[j].fontName = a->font_table->fonts[j].fontName ? strdup(a->font_table->fonts[j].fontName) : NULL; + txdesc->fonts[j].fontName = a->font_table->fonts[j].fontName ? gf_strdup(a->font_table->fonts[j].fontName) : NULL; } } gf_list_add(cfg->sample_descriptions, txdesc); gf_isom_box_del((GF_Box *)a); } } +#endif + if (cfg->has_vid_info) { cfg->video_width = gf_bs_read_int(bs, 16); cfg->video_height = gf_bs_read_int(bs, 16); diff --git a/src/odf/ipmpx_code.c b/src/odf/ipmpx_code.c index e2bfd8d..145799b 100644 --- a/src/odf/ipmpx_code.c +++ b/src/odf/ipmpx_code.c @@ -24,15 +24,18 @@ #include +#ifndef GPAC_MINIMAL_ODF + + #define GF_IPMPX_DATA_ALLOC(__ptr, __stname, __tag) \ - __ptr = (__stname*)malloc(sizeof(__stname)); \ + __ptr = (__stname*)gf_malloc(sizeof(__stname)); \ if (!__ptr) return NULL; \ memset(__ptr, 0, sizeof(__stname)); \ ((GF_IPMPX_Data *)__ptr)->tag = __tag; \ ((GF_IPMPX_Data *)__ptr)->Version = 0x01; \ -#define GF_IPMPX_DELETE_ARRAY(__ar) if (__ar) { if (__ar->data) free(__ar->data); free(__ar); } +#define GF_IPMPX_DELETE_ARRAY(__ar) if (__ar) { if (__ar->data) gf_free(__ar->data); gf_free(__ar); } u32 get_field_size(u32 size_desc) { @@ -79,8 +82,8 @@ GF_IPMPX_ByteArray *GF_IPMPX_GetByteArray(GF_BitStream *bs) size |= val & 0x7F; } while ( val & 0x80 ); if (!size) return NULL; - ba = (GF_IPMPX_ByteArray*)malloc(sizeof(GF_IPMPX_ByteArray)); - ba->data = (char*)malloc(sizeof(char)*size); + ba = (GF_IPMPX_ByteArray*)gf_malloc(sizeof(GF_IPMPX_ByteArray)); + ba->data = (char*)gf_malloc(sizeof(char)*size); gf_bs_read_data(bs, ba->data, size); ba->length = size; return ba; @@ -111,14 +114,14 @@ void GF_IPMPX_AUTH_Delete(GF_IPMPX_Authentication *auth) GF_IPMPX_AUTH_AlgorithmDescriptor *p = (GF_IPMPX_AUTH_AlgorithmDescriptor *)auth; GF_IPMPX_DELETE_ARRAY(p->specAlgoID); GF_IPMPX_DELETE_ARRAY(p->OpaqueData); - free(p); + gf_free(p); } break; case GF_IPMPX_AUTH_KeyDescr_Tag: { GF_IPMPX_AUTH_KeyDescriptor *p = (GF_IPMPX_AUTH_KeyDescriptor *)auth; - if (p->keyBody) free(p->keyBody); - free(p); + if (p->keyBody) gf_free(p->keyBody); + gf_free(p); } break; } @@ -216,7 +219,7 @@ GF_Err GF_IPMPX_AUTH_Parse(GF_BitStream *bs, GF_IPMPX_Authentication **auth) if (!p) return GF_OUT_OF_MEM; p->tag = tag; p->keyBodyLength = size; - p->keyBody = (char*)malloc(sizeof(char)*size); + p->keyBody = (char*)gf_malloc(sizeof(char)*size); gf_bs_read_data(bs, p->keyBody, size); *auth = (GF_IPMPX_Authentication *)p; return GF_OK; @@ -316,7 +319,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_InitAuthentication() static void DelGF_IPMPX_InitAuthentication(GF_IPMPX_Data *_p) { GF_IPMPX_InitAuthentication *p = (GF_IPMPX_InitAuthentication*)_p; - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_InitAuthentication(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -373,7 +376,7 @@ static void DelGF_IPMPX_MutualAuthentication(GF_IPMPX_Data *_p) GF_IPMPX_DELETE_ARRAY(ba); } gf_list_del(p->certificates); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_MutualAuthentication(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -563,13 +566,13 @@ static void DelGF_IPMPX_TrustSecurityMetadata(GF_IPMPX_Data *_p) GF_IPMPX_TrustSpecification *tts = (GF_IPMPX_TrustSpecification *)gf_list_get(tt->trustSpecifications, 0); gf_list_rem(tt->trustSpecifications, 0); GF_IPMPX_DELETE_ARRAY(tts->CCTrustMetadata); - free(tts); + gf_free(tts); } gf_list_del(tt->trustSpecifications); - free(tt); + gf_free(tt); } gf_list_del(p->TrustedTools); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_TrustSecurityMetadata(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -577,7 +580,7 @@ static GF_Err ReadGF_IPMPX_TrustSecurityMetadata(GF_BitStream *bs, GF_IPMPX_Data GF_IPMPX_TrustSecurityMetadata *p = (GF_IPMPX_TrustSecurityMetadata *)_p; nbTools = gf_bs_read_int(bs, 16); while (nbTools) { - GF_IPMPX_TrustedTool *tt = (GF_IPMPX_TrustedTool *)malloc(sizeof(GF_IPMPX_TrustedTool)); + GF_IPMPX_TrustedTool *tt = (GF_IPMPX_TrustedTool *)gf_malloc(sizeof(GF_IPMPX_TrustedTool)); if (!tt) return GF_OUT_OF_MEM; memset(tt, 0, sizeof(GF_IPMPX_TrustedTool)); tt->tag = GF_IPMPX_TRUSTED_TOOL_TAG; @@ -589,7 +592,7 @@ static GF_Err ReadGF_IPMPX_TrustSecurityMetadata(GF_BitStream *bs, GF_IPMPX_Data nbSpec = gf_bs_read_int(bs, 16); while (nbSpec) { Bool has_cc; - GF_IPMPX_TrustSpecification *tts = (GF_IPMPX_TrustSpecification *)malloc(sizeof(GF_IPMPX_TrustSpecification)); + GF_IPMPX_TrustSpecification *tts = (GF_IPMPX_TrustSpecification *)gf_malloc(sizeof(GF_IPMPX_TrustSpecification)); if (!tts) return GF_OUT_OF_MEM; memset(tts, 0, sizeof(GF_IPMPX_TrustSpecification)); tts->tag = GF_IPMPX_TRUST_SPECIFICATION_TAG; @@ -668,7 +671,7 @@ static void DelGF_IPMPX_SecureContainer(GF_IPMPX_Data *_p) GF_IPMPX_DELETE_ARRAY(p->encryptedData); GF_IPMPX_DELETE_ARRAY(p->MAC); gf_ipmpx_data_del(p->protectedMsg); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_SecureContainer(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -738,7 +741,7 @@ static void DelGF_IPMPX_GetToolsResponse(GF_IPMPX_Data *_p) gf_odf_desc_del((GF_Descriptor*)d); } gf_list_del(p->ipmp_tools); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_GetToolsResponse(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -795,10 +798,10 @@ static void DelGF_IPMPX_ParametricDescription(GF_IPMPX_Data *_p) GF_IPMPX_DELETE_ARRAY(it->typeData); GF_IPMPX_DELETE_ARRAY(it->type); GF_IPMPX_DELETE_ARRAY(it->addedData); - free(it); + gf_free(it); } gf_list_del(p->descriptions); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_ParametricDescription(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -809,7 +812,7 @@ static GF_Err ReadGF_IPMPX_ParametricDescription(GF_BitStream *bs, GF_IPMPX_Data p->minorVersion = gf_bs_read_int(bs, 8); count = gf_bs_read_int(bs, 32); while (count) { - GF_IPMPX_ParametricDescriptionItem *it = (GF_IPMPX_ParametricDescriptionItem *)malloc(sizeof(GF_IPMPX_ParametricDescriptionItem)); + GF_IPMPX_ParametricDescriptionItem *it = (GF_IPMPX_ParametricDescriptionItem *)gf_malloc(sizeof(GF_IPMPX_ParametricDescriptionItem)); gf_list_add(p->descriptions, it); count--; it->main_class = GF_IPMPX_GetByteArray(bs); @@ -865,7 +868,7 @@ static void DelGF_IPMPX_ToolParamCapabilitiesQuery(GF_IPMPX_Data *_p) { GF_IPMPX_ToolParamCapabilitiesQuery *p = (GF_IPMPX_ToolParamCapabilitiesQuery *)_p; gf_ipmpx_data_del((GF_IPMPX_Data *) p->description); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_ToolParamCapabilitiesQuery(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -890,7 +893,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_ToolParamCapabilitiesResponse() } static void DelGF_IPMPX_ToolParamCapabilitiesResponse(GF_IPMPX_Data *_p) { - free(_p); + gf_free(_p); } static GF_Err ReadGF_IPMPX_ToolParamCapabilitiesResponse(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -921,7 +924,7 @@ static void DelGF_IPMPX_ConnectTool(GF_IPMPX_Data *_p) { GF_IPMPX_ConnectTool *p = (GF_IPMPX_ConnectTool*)_p; if (p->toolDescriptor) gf_odf_desc_del((GF_Descriptor *)p->toolDescriptor); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_ConnectTool(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -951,7 +954,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_DisconnectTool() } static void DelGF_IPMPX_DisconnectTool(GF_IPMPX_Data *_p) { - free(_p); + gf_free(_p); } static GF_Err ReadGF_IPMPX_DisconnectTool(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -978,7 +981,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_GetToolContext() } static void DelGF_IPMPX_GetToolContext(GF_IPMPX_Data *_p) { - free(_p); + gf_free(_p); } static GF_Err ReadGF_IPMPX_GetToolContext(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1013,7 +1016,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_GetToolContextResponse() } static void DelGF_IPMPX_GetToolContextResponse(GF_IPMPX_Data *_p) { - free(_p); + gf_free(_p); } static GF_Err ReadGF_IPMPX_GetToolContextResponse(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1051,7 +1054,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_AddToolNotificationListener() } static void DelGF_IPMPX_AddToolNotificationListener(GF_IPMPX_Data *_p) { - free(_p); + gf_free(_p); } static GF_Err ReadGF_IPMPX_AddToolNotificationListener(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1086,7 +1089,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_RemoveToolNotificationListener() } static void DelGF_IPMPX_RemoveToolNotificationListener(GF_IPMPX_Data *_p) { - free(_p); + gf_free(_p); } static GF_Err ReadGF_IPMPX_RemoveToolNotificationListener(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1118,7 +1121,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_NotifyToolEvent() } static void DelGF_IPMPX_NotifyToolEvent(GF_IPMPX_Data *_p) { - free(_p); + gf_free(_p); } static GF_Err ReadGF_IPMPX_NotifyToolEvent(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1162,7 +1165,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_CanProcess() } static void DelGF_IPMPX_CanProcess(GF_IPMPX_Data *_p) { - free(_p); + gf_free(_p); } static GF_Err ReadGF_IPMPX_CanProcess(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1192,7 +1195,7 @@ static void DelGF_IPMPX_OpaqueData(GF_IPMPX_Data *_p) { GF_IPMPX_OpaqueData *p = (GF_IPMPX_OpaqueData*)_p; GF_IPMPX_DELETE_ARRAY(p->opaqueData); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_OpaqueData(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1222,7 +1225,7 @@ static void DelGF_IPMPX_KeyData(GF_IPMPX_Data *_p) GF_IPMPX_KeyData*p = (GF_IPMPX_KeyData*)_p; GF_IPMPX_DELETE_ARRAY(p->keyBody); GF_IPMPX_DELETE_ARRAY(p->OpaqueData); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_KeyData(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1286,19 +1289,19 @@ static void DelGF_IPMPX_SelectiveDecryptionInit(GF_IPMPX_Data *_p) GF_IPMPX_SelEncBuffer *sb = (GF_IPMPX_SelEncBuffer *)gf_list_get(p->SelEncBuffer, 0); gf_list_rem(p->SelEncBuffer, 0); GF_IPMPX_DELETE_ARRAY(sb->Stream_Cipher_Specific_Init_Info); - free(sb); + gf_free(sb); } gf_list_del(p->SelEncBuffer); while (gf_list_count(p->SelEncFields)) { GF_IPMPX_SelEncField*sf = (GF_IPMPX_SelEncField*)gf_list_get(p->SelEncFields, 0); gf_list_rem(p->SelEncFields, 0); GF_IPMPX_DELETE_ARRAY(sf->shuffleSpecificInfo); - if (sf->mappingTable) free(sf->mappingTable); - free(sf); + if (sf->mappingTable) gf_free(sf->mappingTable); + gf_free(sf); } gf_list_del(p->SelEncFields); - if (p->RLE_Data) free(p->RLE_Data); - free(p); + if (p->RLE_Data) gf_free(p->RLE_Data); + gf_free(p); } static GF_Err ReadGF_IPMPX_SelectiveDecryptionInit(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1350,7 +1353,7 @@ static GF_Err ReadGF_IPMPX_SelectiveDecryptionInit(GF_BitStream *bs, GF_IPMPX_Da gf_bs_read_int(bs, 6); if (sendMapTable) { sf->mappingTableSize = gf_bs_read_int(bs, 16); - sf->mappingTable = (u16*)malloc(sizeof(u16) * sf->mappingTableSize); + sf->mappingTable = (u16*)gf_malloc(sizeof(u16) * sf->mappingTableSize); for (i=0; imappingTableSize; i++) sf->mappingTable[i] = gf_bs_read_int(bs, 16); } if (isShuffled) sf->shuffleSpecificInfo = GF_IPMPX_GetByteArray(bs); @@ -1358,7 +1361,7 @@ static GF_Err ReadGF_IPMPX_SelectiveDecryptionInit(GF_BitStream *bs, GF_IPMPX_Da } } else { p->RLE_DataLength = gf_bs_read_int(bs, 16); - p->RLE_Data = (u16*)malloc(sizeof(u16)*p->RLE_DataLength); + p->RLE_Data = (u16*)gf_malloc(sizeof(u16)*p->RLE_DataLength); for (i=0; iRLE_DataLength; i++) p->RLE_Data[i] = gf_bs_read_int(bs, 16); } return GF_OK; @@ -1460,9 +1463,9 @@ static GF_IPMPX_Data *NewGF_IPMPX_WatermarkingInit(u8 tag) static void DelGF_IPMPX_WatermarkingInit(GF_IPMPX_Data *_p) { GF_IPMPX_WatermarkingInit *p = (GF_IPMPX_WatermarkingInit*)_p; - if (p->wmPayload) free(p->wmPayload); - if (p->opaqueData) free(p->opaqueData); - free(p); + if (p->wmPayload) gf_free(p->wmPayload); + if (p->opaqueData) gf_free(p->opaqueData); + gf_free(p); } static GF_Err ReadGF_IPMPX_WatermarkingInit(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1488,7 +1491,7 @@ static GF_Err ReadGF_IPMPX_WatermarkingInit(GF_BitStream *bs, GF_IPMPX_Data *_p, case GF_IPMPX_WM_INSERT: case GF_IPMPX_WM_REMARK: p->wmPayloadLen = gf_bs_read_int(bs, 16); - p->wmPayload = (char*)malloc(sizeof(u8) * p->wmPayloadLen); + p->wmPayload = (char*)gf_malloc(sizeof(u8) * p->wmPayloadLen); gf_bs_read_data(bs, p->wmPayload, p->wmPayloadLen); break; case GF_IPMPX_WM_EXTRACT: @@ -1498,7 +1501,7 @@ static GF_Err ReadGF_IPMPX_WatermarkingInit(GF_BitStream *bs, GF_IPMPX_Data *_p, } if (has_opaque_data) { p->opaqueDataSize = gf_bs_read_int(bs, 16); - p->opaqueData = (char*)malloc(sizeof(u8) * p->wmPayloadLen); + p->opaqueData = (char*)gf_malloc(sizeof(u8) * p->wmPayloadLen); gf_bs_read_data(bs, p->opaqueData, p->opaqueDataSize); } return GF_OK; @@ -1569,7 +1572,7 @@ static void DelGF_IPMPX_SendWatermark(GF_IPMPX_Data *_p) GF_IPMPX_SendWatermark*p = (GF_IPMPX_SendWatermark*)_p; GF_IPMPX_DELETE_ARRAY(p->payload); GF_IPMPX_DELETE_ARRAY(p->opaqueData); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_SendWatermark(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1615,7 +1618,7 @@ static void DelGF_IPMPX_ToolAPI_Config(GF_IPMPX_Data *_p) { GF_IPMPX_ToolAPI_Config*p = (GF_IPMPX_ToolAPI_Config*)_p; GF_IPMPX_DELETE_ARRAY(p->opaqueData); - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_ToolAPI_Config(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1660,7 +1663,7 @@ static GF_IPMPX_Data *NewGF_IPMPX_ISMACryp() static void DelGF_IPMPX_ISMACryp(GF_IPMPX_Data *_p) { GF_IPMPX_ISMACryp*p = (GF_IPMPX_ISMACryp*)_p; - free(p); + gf_free(p); } static GF_Err ReadGF_IPMPX_ISMACryp(GF_BitStream *bs, GF_IPMPX_Data *_p, u32 size) { @@ -1740,7 +1743,7 @@ GF_IPMPX_Data *gf_ipmpx_data_new(u8 tag) case GF_IPMPX_ALGORITHM_DESCRIPTOR_TAG: { - GF_IPMPX_AUTH_AlgorithmDescriptor *p = (GF_IPMPX_AUTH_AlgorithmDescriptor *)malloc(sizeof(GF_IPMPX_AUTH_AlgorithmDescriptor)); + GF_IPMPX_AUTH_AlgorithmDescriptor *p = (GF_IPMPX_AUTH_AlgorithmDescriptor *)gf_malloc(sizeof(GF_IPMPX_AUTH_AlgorithmDescriptor)); if (!p) return NULL; memset(p, 0, sizeof(GF_IPMPX_AUTH_AlgorithmDescriptor)); p->tag = GF_IPMPX_ALGORITHM_DESCRIPTOR_TAG; @@ -1748,7 +1751,7 @@ GF_IPMPX_Data *gf_ipmpx_data_new(u8 tag) } case GF_IPMPX_KEY_DESCRIPTOR_TAG: { - GF_IPMPX_AUTH_KeyDescriptor *p = (GF_IPMPX_AUTH_KeyDescriptor *)malloc(sizeof(GF_IPMPX_AUTH_KeyDescriptor)); + GF_IPMPX_AUTH_KeyDescriptor *p = (GF_IPMPX_AUTH_KeyDescriptor *)gf_malloc(sizeof(GF_IPMPX_AUTH_KeyDescriptor)); if (!p) return NULL; memset(p, 0, sizeof(GF_IPMPX_AUTH_KeyDescriptor)); p->tag = GF_IPMPX_KEY_DESCRIPTOR_TAG; @@ -1757,7 +1760,7 @@ GF_IPMPX_Data *gf_ipmpx_data_new(u8 tag) case GF_IPMPX_PARAM_DESCRIPTOR_ITEM_TAG: { - GF_IPMPX_AUTH_KeyDescriptor *p = (GF_IPMPX_AUTH_KeyDescriptor *)malloc(sizeof(GF_IPMPX_ParametricDescriptionItem)); + GF_IPMPX_AUTH_KeyDescriptor *p = (GF_IPMPX_AUTH_KeyDescriptor *)gf_malloc(sizeof(GF_IPMPX_ParametricDescriptionItem)); if (!p) return NULL; memset(p, 0, sizeof(GF_IPMPX_ParametricDescriptionItem)); p->tag = GF_IPMPX_PARAM_DESCRIPTOR_ITEM_TAG; @@ -1765,7 +1768,7 @@ GF_IPMPX_Data *gf_ipmpx_data_new(u8 tag) } case GF_IPMPX_SEL_ENC_BUFFER_TAG: { - GF_IPMPX_SelEncBuffer*p = (GF_IPMPX_SelEncBuffer*)malloc(sizeof(GF_IPMPX_SelEncBuffer)); + GF_IPMPX_SelEncBuffer*p = (GF_IPMPX_SelEncBuffer*)gf_malloc(sizeof(GF_IPMPX_SelEncBuffer)); if (!p) return NULL; memset(p, 0, sizeof(GF_IPMPX_SelEncBuffer)); p->tag = GF_IPMPX_SEL_ENC_BUFFER_TAG; @@ -1773,7 +1776,7 @@ GF_IPMPX_Data *gf_ipmpx_data_new(u8 tag) } case GF_IPMPX_SEL_ENC_FIELD_TAG: { - GF_IPMPX_SelEncField*p = (GF_IPMPX_SelEncField*)malloc(sizeof(GF_IPMPX_SelEncField)); + GF_IPMPX_SelEncField*p = (GF_IPMPX_SelEncField*)gf_malloc(sizeof(GF_IPMPX_SelEncField)); if (!p) return NULL; memset(p, 0, sizeof(GF_IPMPX_SelEncField)); p->tag = GF_IPMPX_SEL_ENC_FIELD_TAG; @@ -1835,14 +1838,14 @@ void gf_ipmpx_data_del(GF_IPMPX_Data *_p) gf_ipmpx_data_del(ts); } gf_list_del(p->trustSpecifications); - free(p); + gf_free(p); return; } case GF_IPMPX_TRUST_SPECIFICATION_TAG: { GF_IPMPX_TrustSpecification *p = (GF_IPMPX_TrustSpecification *)_p; GF_IPMPX_DELETE_ARRAY(p->CCTrustMetadata); - free(p); + gf_free(p); return; } case GF_IPMPX_PARAM_DESCRIPTOR_ITEM_TAG: @@ -1853,7 +1856,7 @@ void gf_ipmpx_data_del(GF_IPMPX_Data *_p) GF_IPMPX_DELETE_ARRAY(p->typeData); GF_IPMPX_DELETE_ARRAY(p->type); GF_IPMPX_DELETE_ARRAY(p->addedData); - free(p); + gf_free(p); return; } case GF_IPMPX_ALGORITHM_DESCRIPTOR_TAG: @@ -1869,21 +1872,21 @@ void gf_ipmpx_data_del(GF_IPMPX_Data *_p) { GF_IPMPX_SelEncBuffer*p = (GF_IPMPX_SelEncBuffer*)_p; GF_IPMPX_DELETE_ARRAY(p->Stream_Cipher_Specific_Init_Info); - free(p); + gf_free(p); return; } case GF_IPMPX_SEL_ENC_FIELD_TAG: { GF_IPMPX_SelEncField*p = (GF_IPMPX_SelEncField*)_p; GF_IPMPX_DELETE_ARRAY(p->shuffleSpecificInfo); - if (p->mappingTable) free(p->mappingTable); - free(p); + if (p->mappingTable) gf_free(p->mappingTable); + gf_free(p); return; } case GF_IPMPX_GET_TOOLS_TAG: default: - free(_p); + gf_free(_p); return; } } @@ -2015,3 +2018,4 @@ GF_Err gf_ipmpx_data_write(GF_BitStream *bs, GF_IPMPX_Data *_p) } } +#endif /*GPAC_MINIMAL_ODF*/ diff --git a/src/odf/ipmpx_dump.c b/src/odf/ipmpx_dump.c index 5ce6df8..6fbf895 100644 --- a/src/odf/ipmpx_dump.c +++ b/src/odf/ipmpx_dump.c @@ -24,6 +24,7 @@ #include +#ifndef GPAC_DISABLE_OD_DUMP #define GF_IPMPX_MAX_TREE 100 @@ -125,7 +126,7 @@ static void DumpLargeInt(FILE *trace, char *attName, u64 val, u32 indent, Bool { if (!val) return; StartAttribute(trace, attName, indent, XMTDump); - fprintf(trace, LLD, val); + fprintf(trace, LLU, val); EndAttribute(trace, indent, XMTDump); } @@ -693,7 +694,7 @@ GF_Err gf_ipmpx_dump_ToolAPI_Config(GF_IPMPX_Data *_p, FILE *trace, u32 indent, GF_Err gf_ipmpx_dump_WatermarkingInit(GF_IPMPX_Data *_p, FILE *trace, u32 indent, Bool XMTDump) { GF_IPMPX_WatermarkingInit*p = (GF_IPMPX_WatermarkingInit*)_p; - StartElement(trace, (char*) (_p->tag==GF_IPMPX_AUDIO_WM_INIT_TAG) ? "IPMP_AudioWatermarkingInit" : "IPMP_VideoWatermarkingInit", indent, XMTDump); + StartElement(trace, (char*) ( (_p->tag==GF_IPMPX_AUDIO_WM_INIT_TAG) ? "IPMP_AudioWatermarkingInit" : "IPMP_VideoWatermarkingInit"), indent, XMTDump); indent++; DumpInt(trace, "inputFormat", p->inputFormat, indent, XMTDump); DumpInt(trace, "requiredOp", p->requiredOp, indent, XMTDump); @@ -723,13 +724,13 @@ GF_Err gf_ipmpx_dump_WatermarkingInit(GF_IPMPX_Data *_p, FILE *trace, u32 indent EndAttributes(trace, XMTDump, 1); gf_ipmpx_dump_BaseData(_p, trace, indent, XMTDump); indent--; - EndElement(trace, (char*) (_p->tag==GF_IPMPX_AUDIO_WM_INIT_TAG) ? "IPMP_AudioWatermarkingInit" : "IPMP_VideoWatermarkingInit", indent, XMTDump); + EndElement(trace, (char*) ( (_p->tag==GF_IPMPX_AUDIO_WM_INIT_TAG) ? "IPMP_AudioWatermarkingInit" : "IPMP_VideoWatermarkingInit"), indent, XMTDump); return GF_OK; } GF_Err gf_ipmpx_dump_SendWatermark(GF_IPMPX_Data *_p, FILE *trace, u32 indent, Bool XMTDump) { GF_IPMPX_SendWatermark*p = (GF_IPMPX_SendWatermark*)_p; - StartElement(trace, (char*) (_p->tag==GF_IPMPX_AUDIO_WM_SEND_TAG) ? "IPMP_SendAudioWatermark" : "IPMP_SendVideoWatermark", indent, XMTDump); + StartElement(trace, (char*) ((_p->tag==GF_IPMPX_AUDIO_WM_SEND_TAG) ? "IPMP_SendAudioWatermark" : "IPMP_SendVideoWatermark"), indent, XMTDump); indent++; DumpInt(trace, "wmStatus", p->wm_status, indent, XMTDump); DumpInt(trace, "compression_status", p->compression_status, indent, XMTDump); @@ -738,7 +739,7 @@ GF_Err gf_ipmpx_dump_SendWatermark(GF_IPMPX_Data *_p, FILE *trace, u32 indent, B if (p->wm_status==GF_IPMPX_WM_PAYLOAD) gf_ipmpx_dump_ByteArray(p->payload, "payload", trace, indent, XMTDump); if (p->opaqueData) gf_ipmpx_dump_ByteArray(p->opaqueData, "opaqueData", trace, indent, XMTDump); indent--; - EndElement(trace, (char*) (_p->tag==GF_IPMPX_AUDIO_WM_SEND_TAG) ? "IPMP_SendAudioWatermark" : "IPMP_SendVideoWatermark", indent, XMTDump); + EndElement(trace, (char*) ( (_p->tag==GF_IPMPX_AUDIO_WM_SEND_TAG) ? "IPMP_SendAudioWatermark" : "IPMP_SendVideoWatermark"), indent, XMTDump); return GF_OK; } @@ -866,3 +867,5 @@ GF_Err gf_ipmpx_dump_data(GF_IPMPX_Data *_p, FILE *trace, u32 indent, Bool XMTDu default: return GF_BAD_PARAM; } } + +#endif /*GPAC_DISABLE_OD_DUMP*/ diff --git a/src/odf/ipmpx_parse.c b/src/odf/ipmpx_parse.c index 0272f98..35c9371 100644 --- a/src/odf/ipmpx_parse.c +++ b/src/odf/ipmpx_parse.c @@ -25,6 +25,8 @@ #include +#ifndef GPAC_MINIMAL_ODF + void GF_IPMPX_AUTH_Delete(GF_IPMPX_Authentication *auth); @@ -146,7 +148,7 @@ u32 gf_ipmpx_get_field_type(GF_IPMPX_Data *p, char *fieldName) #define GET_BOOL(field) { ret = 1; field = (!stricmp(val, "true") || !stricmp(val, "1")) ? 1 : 0; } #define GET_DOUBLE(field) { Float v; ret = 1; sscanf(val, "%f", &v); field = (Double) v;} -#define GET_STRING(field) { ret = 1; field = strdup(val); if (val[0] == '"') strcpy(field, val+1); if (field[strlen(field)-1] == '"') field[strlen(field)-1] = 0; } +#define GET_STRING(field) { ret = 1; field = gf_strdup(val); if (val[0] == '"') strcpy(field, val+1); if (field[strlen(field)-1] == '"') field[strlen(field)-1] = 0; } void GF_IPMPX_ParseBinData(char *val, char **out_data, u32 *out_data_size) { @@ -155,15 +157,15 @@ void GF_IPMPX_ParseBinData(char *val, char **out_data, u32 *out_data_size) if (val[0] != '%') { len = *out_data_size = strlen(val); - *out_data = (char*)malloc(sizeof(char) * len); + *out_data = (char*)gf_malloc(sizeof(char) * len); memcpy(*out_data, val, sizeof(char) * len); return; } len = strlen(val) / 3; - if (*out_data) free(*out_data); + if (*out_data) gf_free(*out_data); *out_data_size = len; - *out_data = (char*)malloc(sizeof(char) * len); + *out_data = (char*)gf_malloc(sizeof(char) * len); s[2] = 0; for (i=0; ilength = strlen(str); - d->data = (char*)malloc(sizeof(char)*d->length); + d->data = (char*)gf_malloc(sizeof(char)*d->length); memcpy(d->data, str, d->length); dest = NULL; @@ -669,14 +672,17 @@ GF_Err gf_ipmpx_set_byte_array(GF_IPMPX_Data *p, char *field, char *str) break; } if (!dest) { - free(d->data); - free(d); + gf_free(d->data); + gf_free(d); return GF_BAD_PARAM; } if ( (*dest) ) { - if ((*dest)->data) free((*dest)->data); - free((*dest)); + if ((*dest)->data) gf_free((*dest)->data); + gf_free((*dest)); } (*dest) = d; return GF_OK; } + +#endif /*GPAC_MINIMAL_ODF*/ + diff --git a/src/odf/oci_codec.c b/src/odf/oci_codec.c index 2f0ad7a..b84f7a2 100644 --- a/src/odf/oci_codec.c +++ b/src/odf/oci_codec.c @@ -25,6 +25,8 @@ #include +#ifndef GPAC_MINIMAL_ODF + //from OD GF_Err gf_odf_write_descriptor_list(GF_BitStream *bs, GF_List *descList); @@ -62,7 +64,7 @@ OCIEvent *gf_oci_event_new(u16 EventID) { OCIEvent *tmp; if (EventID > MAX_OCIEVENT_ID) return NULL; - tmp = (OCIEvent *)malloc(sizeof(OCIEvent)); + tmp = (OCIEvent *)gf_malloc(sizeof(OCIEvent)); if (!tmp) return NULL; memset(tmp, 0, sizeof(OCIEvent)); tmp->EventID = EventID; @@ -82,7 +84,7 @@ void gf_oci_event_del(OCIEvent *event) gf_odf_delete_descriptor(desc); } gf_list_del(event->OCIDescriptors); - free(event); + gf_free(event); } GF_EXPORT @@ -192,7 +194,7 @@ OCICodec *gf_oci_codec_new(u8 IsEncoder, u8 Version) { OCICodec *tmp; if (Version != 0x01) return NULL; - tmp = (OCICodec *)malloc(sizeof(OCICodec)); + tmp = (OCICodec *)gf_malloc(sizeof(OCICodec)); if (!tmp) return NULL; tmp->Mode = IsEncoder ? 1 : 0; tmp->Version = 0x01; @@ -212,7 +214,7 @@ void gf_oci_codec_del(OCICodec *codec) gf_list_rem(codec->OCIEvents, 0); } gf_list_del(codec->OCIEvents); - free(codec); + gf_free(codec); } GF_EXPORT @@ -420,3 +422,5 @@ OCIEvent *gf_oci_codec_get_event(OCICodec *codec) gf_list_rem(codec->OCIEvents, 0); return ev; } + +#endif /*GPAC_MINIMAL_ODF*/ diff --git a/src/odf/odf_code.c b/src/odf/odf_code.c index 1ad1782..b1aa72e 100644 --- a/src/odf/odf_code.c +++ b/src/odf/odf_code.c @@ -34,7 +34,7 @@ static GFINLINE GF_Err OD_ReadUTF8String(GF_BitStream *bs, char **string, Bool i *read = 1; len = gf_bs_read_int(bs, 8) + 1; if (!isUTF8) len *= 2; - (*string) = (char *) malloc(sizeof(char)*len); + (*string) = (char *) gf_malloc(sizeof(char)*len); if (! (*string) ) return GF_OUT_OF_MEM; gf_bs_read_data(bs, (*string), len); *read += len; @@ -81,7 +81,7 @@ GF_Err gf_odf_read_url_string(GF_BitStream *bs, char **string, u32 *readBytes) } /*we want to use strlen to get rid of "stringLength" => we need an extra 0*/ - (*string) = (char *) malloc(length + 1); + (*string) = (char *) gf_malloc(length + 1); if (! string) return GF_OUT_OF_MEM; gf_bs_read_data(bs, (*string), length); *readBytes += length; @@ -118,7 +118,7 @@ u32 gf_odf_size_url_string(char *string) GF_Descriptor *gf_odf_new_esd() { - GF_ESD *newDesc = (GF_ESD *) malloc(sizeof(GF_ESD)); + GF_ESD *newDesc = (GF_ESD *) gf_malloc(sizeof(GF_ESD)); if (!newDesc) return NULL; memset(newDesc, 0, sizeof(GF_ESD)); newDesc->IPIDataSet = gf_list_new(); @@ -133,7 +133,7 @@ GF_Err gf_odf_del_esd(GF_ESD *esd) { GF_Err e; if (!esd) return GF_BAD_PARAM; - if (esd->URLString) free(esd->URLString); + if (esd->URLString) gf_free(esd->URLString); if (esd->decoderConfig) { e = gf_odf_delete_descriptor((GF_Descriptor *) esd->decoderConfig); @@ -166,7 +166,7 @@ GF_Err gf_odf_del_esd(GF_ESD *esd) if (e) return e; e = gf_odf_delete_descriptor_list(esd->extensionDescriptors); if (e) return e; - free(esd); + gf_free(esd); return GF_OK; } @@ -186,6 +186,16 @@ GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc) esd->slConfig = (GF_SLConfig *) desc; break; + case GF_ODF_MUXINFO_TAG: + gf_list_add(esd->extensionDescriptors, desc); + break; + + case GF_ODF_LANG_TAG: + if (esd->langDesc) return GF_ODF_INVALID_DESCRIPTOR; + esd->langDesc = (GF_Language *) desc; + break; + +#ifndef GPAC_MINIMAL_ODF //the GF_ODF_ISOM_IPI_PTR_TAG is only used in the file format and replaces GF_ODF_IPI_PTR_TAG... case GF_ODF_ISOM_IPI_PTR_TAG: case GF_ODF_IPI_PTR_TAG: @@ -198,11 +208,6 @@ GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc) esd->qos =(GF_QoS_Descriptor *) desc; break; - case GF_ODF_LANG_TAG: - if (esd->langDesc) return GF_ODF_INVALID_DESCRIPTOR; - esd->langDesc = (GF_Language *) desc; - break; - case GF_ODF_CI_TAG: case GF_ODF_SCI_TAG: return gf_list_add(esd->IPIDataSet, desc); @@ -215,10 +220,7 @@ GF_Err AddDescriptorToESD(GF_ESD *esd, GF_Descriptor *desc) if (esd->RegDescriptor) return GF_ODF_INVALID_DESCRIPTOR; esd->RegDescriptor =(GF_Registration *) desc; break; - - case GF_ODF_MUXINFO_TAG: - gf_list_add(esd->extensionDescriptors, desc); - break; +#endif default: if ( (desc->tag >= GF_ODF_EXT_BEGIN_TAG) && @@ -408,7 +410,7 @@ GF_Err gf_odf_write_esd(GF_BitStream *bs, GF_ESD *esd) GF_Descriptor *gf_odf_new_iod() { - GF_InitialObjectDescriptor *newDesc = (GF_InitialObjectDescriptor *) malloc(sizeof(GF_InitialObjectDescriptor)); + GF_InitialObjectDescriptor *newDesc = (GF_InitialObjectDescriptor *) gf_malloc(sizeof(GF_InitialObjectDescriptor)); if (!newDesc) return NULL; memset(newDesc, 0, sizeof(GF_InitialObjectDescriptor)); @@ -425,7 +427,7 @@ GF_Err gf_odf_del_iod(GF_InitialObjectDescriptor *iod) { GF_Err e; if (!iod) return GF_BAD_PARAM; - if (iod->URLString) free(iod->URLString); + if (iod->URLString) gf_free(iod->URLString); e = gf_odf_delete_descriptor_list(iod->ESDescriptors); if (e) return e; e = gf_odf_delete_descriptor_list(iod->OCIDescriptors); @@ -435,7 +437,7 @@ GF_Err gf_odf_del_iod(GF_InitialObjectDescriptor *iod) e = gf_odf_delete_descriptor_list(iod->extensionDescriptors); if (e) return e; if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList); - free(iod); + gf_free(iod); return GF_OK; } @@ -581,7 +583,7 @@ GF_Err gf_odf_write_iod(GF_BitStream *bs, GF_InitialObjectDescriptor *iod) GF_Descriptor *gf_odf_new_od() { - GF_ObjectDescriptor *newDesc = (GF_ObjectDescriptor *) malloc(sizeof(GF_ObjectDescriptor)); + GF_ObjectDescriptor *newDesc = (GF_ObjectDescriptor *) gf_malloc(sizeof(GF_ObjectDescriptor)); if (!newDesc) return NULL; newDesc->URLString = NULL; @@ -598,7 +600,7 @@ GF_Err gf_odf_del_od(GF_ObjectDescriptor *od) { GF_Err e; if (!od) return GF_BAD_PARAM; - if (od->URLString) free(od->URLString); + if (od->URLString) gf_free(od->URLString); e = gf_odf_delete_descriptor_list(od->ESDescriptors); if (e) return e; e = gf_odf_delete_descriptor_list(od->OCIDescriptors); @@ -607,7 +609,7 @@ GF_Err gf_odf_del_od(GF_ObjectDescriptor *od) if (e) return e; e = gf_odf_delete_descriptor_list(od->extensionDescriptors); if (e) return e; - free(od); + gf_free(od); return GF_OK; } @@ -727,7 +729,7 @@ GF_Err gf_odf_write_od(GF_BitStream *bs, GF_ObjectDescriptor *od) GF_Descriptor *gf_odf_new_isom_iod() { - GF_IsomInitialObjectDescriptor *newDesc = (GF_IsomInitialObjectDescriptor *) malloc(sizeof(GF_IsomInitialObjectDescriptor)); + GF_IsomInitialObjectDescriptor *newDesc = (GF_IsomInitialObjectDescriptor *) gf_malloc(sizeof(GF_IsomInitialObjectDescriptor)); if (!newDesc) return NULL; memset(newDesc, 0, sizeof(GF_IsomInitialObjectDescriptor)); @@ -751,7 +753,7 @@ GF_Err gf_odf_del_isom_iod(GF_IsomInitialObjectDescriptor *iod) { GF_Err e; if (!iod) return GF_BAD_PARAM; - if (iod->URLString) free(iod->URLString); + if (iod->URLString) gf_free(iod->URLString); e = gf_odf_delete_descriptor_list(iod->ES_ID_IncDescriptors); if (e) return e; e = gf_odf_delete_descriptor_list(iod->ES_ID_RefDescriptors); @@ -763,7 +765,7 @@ GF_Err gf_odf_del_isom_iod(GF_IsomInitialObjectDescriptor *iod) e = gf_odf_delete_descriptor_list(iod->extensionDescriptors); if (e) return e; if (iod->IPMPToolList) gf_odf_delete_descriptor((GF_Descriptor *) iod->IPMPToolList); - free(iod); + gf_free(iod); return GF_OK; } @@ -921,7 +923,7 @@ GF_Err gf_odf_write_isom_iod(GF_BitStream *bs, GF_IsomInitialObjectDescriptor *i GF_Descriptor *gf_odf_new_isom_od() { - GF_IsomObjectDescriptor *newDesc = (GF_IsomObjectDescriptor *) malloc(sizeof(GF_IsomObjectDescriptor)); + GF_IsomObjectDescriptor *newDesc = (GF_IsomObjectDescriptor *) gf_malloc(sizeof(GF_IsomObjectDescriptor)); if (!newDesc) return NULL; newDesc->URLString = NULL; @@ -939,7 +941,7 @@ GF_Err gf_odf_del_isom_od(GF_IsomObjectDescriptor *od) { GF_Err e; if (!od) return GF_BAD_PARAM; - if (od->URLString) free(od->URLString); + if (od->URLString) gf_free(od->URLString); e = gf_odf_delete_descriptor_list(od->ES_ID_IncDescriptors); if (e) return e; e = gf_odf_delete_descriptor_list(od->ES_ID_RefDescriptors); @@ -950,7 +952,7 @@ GF_Err gf_odf_del_isom_od(GF_IsomObjectDescriptor *od) if (e) return e; e = gf_odf_delete_descriptor_list(od->extensionDescriptors); if (e) return e; - free(od); + gf_free(od); return GF_OK; } @@ -1083,613 +1085,979 @@ GF_Err gf_odf_write_isom_od(GF_BitStream *bs, GF_IsomObjectDescriptor *od) -GF_Descriptor *gf_odf_new_cc() +GF_Descriptor *gf_odf_new_dcd() { - GF_CCDescriptor *newDesc = (GF_CCDescriptor *) malloc(sizeof(GF_CCDescriptor)); + GF_DecoderConfig *newDesc = (GF_DecoderConfig *) gf_malloc(sizeof(GF_DecoderConfig)); if (!newDesc) return NULL; - newDesc->contentClassificationData = NULL; - newDesc->dataLength = 0; - newDesc->classificationEntity = 0; - newDesc->classificationTable = 0; - newDesc->tag = GF_ODF_CC_TAG; + newDesc->avgBitrate = 0; + newDesc->bufferSizeDB = 0; + newDesc->maxBitrate = 0; + newDesc->objectTypeIndication = 0; + newDesc->streamType = 0; + newDesc->upstream = 0; + newDesc->decoderSpecificInfo = NULL; + newDesc->profileLevelIndicationIndexDescriptor = gf_list_new(); + newDesc->tag = GF_ODF_DCD_TAG; return (GF_Descriptor *) newDesc; } -GF_Err gf_odf_del_cc(GF_CCDescriptor *ccd) +GF_Err gf_odf_del_dcd(GF_DecoderConfig *dcd) { - if (!ccd) return GF_BAD_PARAM; - if (ccd->contentClassificationData) free(ccd->contentClassificationData); - free(ccd); + GF_Err e; + if (!dcd) return GF_BAD_PARAM; + + if (dcd->decoderSpecificInfo) { + e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo); + if (e) return e; + } + e = gf_odf_delete_descriptor_list(dcd->profileLevelIndicationIndexDescriptor); + if (e) return e; + gf_free(dcd); return GF_OK; } -GF_Err gf_odf_read_cc(GF_BitStream *bs, GF_CCDescriptor *ccd, u32 DescSize) +GF_Err gf_odf_read_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd, u32 DescSize) { - u32 nbBytes = 0; - if (!ccd) return GF_BAD_PARAM; + GF_Err e; + u32 reserved, tmp_size, nbBytes = 0; + if (! dcd) return GF_BAD_PARAM; - ccd->classificationEntity = gf_bs_read_int(bs, 32); - ccd->classificationTable = gf_bs_read_int(bs, 16); - nbBytes += 6; - ccd->dataLength = DescSize - 6; - ccd->contentClassificationData = (char*)malloc(sizeof(char) * ccd->dataLength); - if (!ccd->contentClassificationData) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, ccd->contentClassificationData, ccd->dataLength); - nbBytes += ccd->dataLength; + dcd->objectTypeIndication = gf_bs_read_int(bs, 8); + dcd->streamType = gf_bs_read_int(bs, 6); + dcd->upstream = gf_bs_read_int(bs, 1); + reserved = gf_bs_read_int(bs, 1); + dcd->bufferSizeDB = gf_bs_read_int(bs, 24); + dcd->maxBitrate = gf_bs_read_int(bs, 32); + dcd->avgBitrate = gf_bs_read_int(bs, 32); + nbBytes += 13; + + while (nbBytes < DescSize) { + GF_Descriptor *tmp = NULL; + e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size); + if (e) return e; + if (!tmp) return GF_ODF_INVALID_DESCRIPTOR; + switch (tmp->tag) { + case GF_ODF_DSI_TAG: + if (dcd->decoderSpecificInfo) { + gf_odf_delete_descriptor(tmp); + return GF_ODF_INVALID_DESCRIPTOR; + } + dcd->decoderSpecificInfo = (GF_DefaultDescriptor *) tmp; + break; + + case GF_ODF_EXT_PL_TAG: + e = gf_list_add(dcd->profileLevelIndicationIndexDescriptor, tmp); + if (e < GF_OK) { + gf_odf_delete_descriptor(tmp); + return e; + } + break; + + /*iPod fix: delete and aborts, this will create an InvalidDescriptor at the ESD level with a loaded DSI, + laoding will abort with a partially valid ESD which is all the matters*/ + case GF_ODF_SLC_TAG: + gf_odf_delete_descriptor(tmp); + return GF_OK; + //what the hell is this descriptor ?? Don't know, so delete it ! + default: + gf_odf_delete_descriptor(tmp); + break; + } + nbBytes += tmp_size + gf_odf_size_field_size(tmp_size); + } if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } -GF_Err gf_odf_size_cc(GF_CCDescriptor *ccd, u32 *outSize) +GF_Err gf_odf_size_dcd(GF_DecoderConfig *dcd, u32 *outSize) { - if (!ccd) return GF_BAD_PARAM; - *outSize = 6 + ccd->dataLength; + GF_Err e; + u32 tmpSize; + if (! dcd) return GF_BAD_PARAM; + + *outSize = 0; + *outSize += 13; + if (dcd->decoderSpecificInfo) { + //warning: we don't know anything about the structure of a generic DecSpecInfo + //we check the tag and size of the descriptor, but we most ofthe time can't parse it + //the decSpecInfo is handle as a defaultDescriptor (opaque data, but same structure....) + e = gf_odf_size_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo , &tmpSize); + if (e) return e; + *outSize += tmpSize + gf_odf_size_field_size(tmpSize); + } + e = gf_odf_size_descriptor_list(dcd->profileLevelIndicationIndexDescriptor, outSize); + if (e) return e; return GF_OK; + } -GF_Err gf_odf_write_cc(GF_BitStream *bs, GF_CCDescriptor *ccd) +GF_Err gf_odf_write_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd) { - u32 size; GF_Err e; - if (!ccd) return GF_BAD_PARAM; + u32 size; + if (! dcd) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)ccd, &size); + e = gf_odf_size_descriptor((GF_Descriptor *)dcd, &size); if (e) return e; - e = gf_odf_write_base_descriptor(bs, ccd->tag, size); + e = gf_odf_write_base_descriptor(bs, dcd->tag, size); if (e) return e; - gf_bs_write_int(bs, ccd->classificationEntity, 32); - gf_bs_write_int(bs, ccd->classificationTable, 16); - gf_bs_write_data(bs, ccd->contentClassificationData, ccd->dataLength); - return GF_OK; + + gf_bs_write_int(bs, dcd->objectTypeIndication, 8); + gf_bs_write_int(bs, dcd->streamType, 6); + gf_bs_write_int(bs, dcd->upstream, 1); + gf_bs_write_int(bs, 1, 1); //reserved field... + gf_bs_write_int(bs, dcd->bufferSizeDB, 24); + gf_bs_write_int(bs, dcd->maxBitrate, 32); + gf_bs_write_int(bs, dcd->avgBitrate, 32); + + if (dcd->decoderSpecificInfo) { + e = gf_odf_write_descriptor(bs, (GF_Descriptor *) dcd->decoderSpecificInfo); + if (e) return e; + } + e = gf_odf_write_descriptor_list(bs, dcd->profileLevelIndicationIndexDescriptor); + return e; } -GF_Descriptor *gf_odf_new_cc_date() + +GF_Descriptor *gf_odf_new_default() { - GF_CC_Date *newDesc = (GF_CC_Date *) malloc(sizeof(GF_CC_Date)); + GF_DefaultDescriptor *newDesc = (GF_DefaultDescriptor *) gf_malloc(sizeof(GF_DefaultDescriptor)); if (!newDesc) return NULL; - memset(newDesc->contentCreationDate, 0, 5); - newDesc->tag = GF_ODF_CC_DATE_TAG; + + newDesc->dataLength = 0; + newDesc->data = NULL; + //set it to the Max allowed + newDesc->tag = GF_ODF_USER_END_TAG; return (GF_Descriptor *) newDesc; } - -GF_Err gf_odf_del_cc_date(GF_CC_Date *cdd) +GF_Err gf_odf_del_default(GF_DefaultDescriptor *dd) { - if (!cdd) return GF_BAD_PARAM; - free(cdd); + if (!dd) return GF_BAD_PARAM; + + if (dd->data) gf_free(dd->data); + gf_free(dd); return GF_OK; } -GF_Err gf_odf_read_cc_date(GF_BitStream *bs, GF_CC_Date *cdd, u32 DescSize) +GF_Err gf_odf_read_default(GF_BitStream *bs, GF_DefaultDescriptor *dd, u32 DescSize) { u32 nbBytes = 0; - if (!cdd) return GF_BAD_PARAM; + if (! dd) return GF_BAD_PARAM; - gf_bs_read_data(bs, cdd->contentCreationDate, DATE_CODING_BIT_LEN); - nbBytes += DATE_CODING_BIT_LEN / 8; - if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR; + dd->dataLength = DescSize; + dd->data = NULL; + if (DescSize) { + dd->data = (char*)gf_malloc(dd->dataLength); + if (! dd->data) return GF_OUT_OF_MEM; + gf_bs_read_data(bs, dd->data, dd->dataLength); + nbBytes += dd->dataLength; + } + if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } -GF_Err gf_odf_size_cc_date(GF_CC_Date *cdd, u32 *outSize) +GF_Err gf_odf_size_default(GF_DefaultDescriptor *dd, u32 *outSize) { - if (!cdd) return GF_BAD_PARAM; - *outSize = (DATE_CODING_BIT_LEN / 8); + if (! dd) return GF_BAD_PARAM; + *outSize = dd->dataLength; return GF_OK; } -GF_Err gf_odf_write_cc_date(GF_BitStream *bs, GF_CC_Date *cdd) +GF_Err gf_odf_write_default(GF_BitStream *bs, GF_DefaultDescriptor *dd) { - u32 size; GF_Err e; - if (!cdd) return GF_BAD_PARAM; + u32 size; + if (! dd) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)cdd, &size); + e = gf_odf_size_descriptor((GF_Descriptor *)dd, &size); if (e) return e; - e = gf_odf_write_base_descriptor(bs, cdd->tag, size); + e = gf_odf_write_base_descriptor(bs, dd->tag, size); if (e) return e; - gf_bs_write_data(bs, cdd->contentCreationDate , DATE_CODING_BIT_LEN); + if (dd->data) { + gf_bs_write_data(bs, dd->data, dd->dataLength); + } return GF_OK; } -GF_Descriptor *gf_odf_new_cc_name() +GF_Descriptor *gf_odf_new_esd_inc() { - GF_CC_Name *newDesc = (GF_CC_Name *) malloc(sizeof(GF_CC_Name)); + GF_ES_ID_Inc *newDesc = (GF_ES_ID_Inc *) gf_malloc(sizeof(GF_ES_ID_Inc)); if (!newDesc) return NULL; - - newDesc->ContentCreators = gf_list_new(); - if (! newDesc->ContentCreators) { - free(newDesc); - return NULL; - } - newDesc->tag = GF_ODF_CC_NAME_TAG; + newDesc->tag = GF_ODF_ESD_INC_TAG; + newDesc->trackID = 0; return (GF_Descriptor *) newDesc; } -GF_Err gf_odf_del_cc_name(GF_CC_Name *cnd) +GF_Err gf_odf_del_esd_inc(GF_ES_ID_Inc *esd_inc) { - u32 i; - GF_ContentCreatorInfo *tmp; - if (!cnd) return GF_BAD_PARAM; - - i=0; - while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) { - if (tmp->contentCreatorName) free(tmp->contentCreatorName); - free(tmp); - } - gf_list_del(cnd->ContentCreators); - free(cnd); + if (!esd_inc) return GF_BAD_PARAM; + gf_free(esd_inc); return GF_OK; } - -GF_Err gf_odf_read_cc_name(GF_BitStream *bs, GF_CC_Name *cnd, u32 DescSize) +GF_Err gf_odf_read_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc, u32 DescSize) { - GF_Err e; - u32 i, aligned, count, len, nbBytes = 0; - if (!cnd) return GF_BAD_PARAM; - - count = gf_bs_read_int(bs, 8); - nbBytes += 1; - for (i = 0; i< count; i++) { - GF_ContentCreatorInfo *tmp = (GF_ContentCreatorInfo*)malloc(sizeof(GF_ContentCreatorInfo)); - if (! tmp) return GF_OUT_OF_MEM; - memset(tmp , 0, sizeof(GF_ContentCreatorInfo)); - tmp->langCode = gf_bs_read_int(bs, 24); - tmp->isUTF8 = gf_bs_read_int(bs, 1); - aligned = gf_bs_read_int(bs, 7); - nbBytes += 4; + u32 nbBytes = 0; + if (! esd_inc) return GF_BAD_PARAM; - e = OD_ReadUTF8String(bs, & tmp->contentCreatorName, tmp->isUTF8, &len); - if (e) return e; - nbBytes += len; - e = gf_list_add(cnd->ContentCreators, tmp); - } - if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR; + esd_inc->trackID = gf_bs_read_int(bs, 32); + nbBytes += 4; + if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } - -GF_Err gf_odf_size_cc_name(GF_CC_Name *cnd, u32 *outSize) +GF_Err gf_odf_size_esd_inc(GF_ES_ID_Inc *esd_inc, u32 *outSize) { - u32 i; - GF_ContentCreatorInfo *tmp; - if (!cnd) return GF_BAD_PARAM; - - *outSize = 1; - i=0; - while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) { - *outSize += 4 + OD_SizeUTF8String(tmp->contentCreatorName, tmp->isUTF8); - } + if (! esd_inc) return GF_BAD_PARAM; + *outSize = 4; return GF_OK; } - -GF_Err gf_odf_write_cc_name(GF_BitStream *bs, GF_CC_Name *cnd) +GF_Err gf_odf_write_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc) { GF_Err e; - GF_ContentCreatorInfo *tmp; - u32 i, size; - if (!cnd) return GF_BAD_PARAM; + u32 size; + if (! esd_inc) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)cnd, &size); + e = gf_odf_size_descriptor((GF_Descriptor *)esd_inc, &size); if (e) return e; - e = gf_odf_write_base_descriptor(bs, cnd->tag, size); + e = gf_odf_write_base_descriptor(bs, esd_inc->tag, size); if (e) return e; - gf_bs_write_int(bs, gf_list_count(cnd->ContentCreators), 8); - - i=0; - while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) { - gf_bs_write_int(bs, tmp->langCode, 24); - gf_bs_write_int(bs, tmp->isUTF8, 1); - gf_bs_write_int(bs, 0, 7); //aligned - OD_WriteUTF8String(bs, tmp->contentCreatorName, tmp->isUTF8); - } + gf_bs_write_int(bs, esd_inc->trackID, 32); return GF_OK; } - -GF_Descriptor *gf_odf_new_ci() +GF_Descriptor *gf_odf_new_esd_ref() { - GF_CIDesc *newDesc = (GF_CIDesc *) malloc(sizeof(GF_CIDesc)); + GF_ES_ID_Ref *newDesc = (GF_ES_ID_Ref *) gf_malloc(sizeof(GF_ES_ID_Ref)); if (!newDesc) return NULL; - - newDesc->compatibility = 0; - newDesc->contentIdentifier = NULL; - newDesc->tag = GF_ODF_CI_TAG; - newDesc->contentIdentifierFlag = 0; - newDesc->contentIdentifierType = 0; - newDesc->contentType = 0; - newDesc->contentTypeFlag = 0; - newDesc->protectedContent = 0; + newDesc->tag = GF_ODF_ESD_REF_TAG; + newDesc->trackRef = 0; return (GF_Descriptor *) newDesc; } - -GF_Err gf_odf_del_ci(GF_CIDesc *cid) +GF_Err gf_odf_del_esd_ref(GF_ES_ID_Ref *esd_ref) { - if (!cid) return GF_BAD_PARAM; - - if (cid->contentIdentifier) free(cid->contentIdentifier); - free(cid); + if (!esd_ref) return GF_BAD_PARAM; + gf_free(esd_ref); return GF_OK; } - - -GF_Err gf_odf_read_ci(GF_BitStream *bs, GF_CIDesc *cid, u32 DescSize) +GF_Err gf_odf_read_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref, u32 DescSize) { - u32 reserved, nbBytes = 0; - if (! cid) return GF_BAD_PARAM; - - cid->compatibility = gf_bs_read_int(bs, 2); //MUST BE NULL - if (cid->compatibility) return GF_ODF_INVALID_DESCRIPTOR; - - cid->contentTypeFlag = gf_bs_read_int(bs, 1); - cid->contentIdentifierFlag = gf_bs_read_int(bs, 1); - cid->protectedContent = gf_bs_read_int(bs, 1); - reserved = gf_bs_read_int(bs, 3); - nbBytes += 1; - - if (cid->contentTypeFlag) { - cid->contentType = gf_bs_read_int(bs, 8); - nbBytes += 1; - } - if (cid->contentIdentifierFlag) { - cid->contentIdentifierType = gf_bs_read_int(bs, 8); - cid->contentIdentifier = (char*)malloc(DescSize - 2 - cid->contentTypeFlag); - if (! cid->contentIdentifier) return GF_OUT_OF_MEM; + u32 nbBytes = 0; + if (! esd_ref) return GF_BAD_PARAM; - gf_bs_read_data(bs, cid->contentIdentifier, DescSize - 2 - cid->contentTypeFlag); - nbBytes += DescSize - 1 - cid->contentTypeFlag; - } + esd_ref->trackRef = gf_bs_read_int(bs, 16); + nbBytes += 2; if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } -GF_Err gf_odf_size_ci(GF_CIDesc *cid, u32 *outSize) +GF_Err gf_odf_size_esd_ref(GF_ES_ID_Ref *esd_ref, u32 *outSize) { - if (! cid) return GF_BAD_PARAM; - - *outSize = 1; - if (cid->contentTypeFlag) *outSize += 1; - - if (cid->contentIdentifierFlag) - *outSize += strlen((const char*)cid->contentIdentifier) - 1 - cid->contentTypeFlag; + if (! esd_ref) return GF_BAD_PARAM; + *outSize = 2; return GF_OK; } - -GF_Err gf_odf_write_ci(GF_BitStream *bs, GF_CIDesc *cid) +GF_Err gf_odf_write_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref) { GF_Err e; u32 size; - if (! cid) return GF_BAD_PARAM; + if (! esd_ref) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)cid, &size); + e = gf_odf_size_descriptor((GF_Descriptor *)esd_ref, &size); if (e) return e; - e = gf_odf_write_base_descriptor(bs, cid->tag, size); + e = gf_odf_write_base_descriptor(bs, esd_ref->tag, size); if (e) return e; - - gf_bs_write_int(bs, cid->compatibility, 2); - gf_bs_write_int(bs, cid->contentTypeFlag, 1); - gf_bs_write_int(bs, cid->contentIdentifierFlag, 1); - gf_bs_write_int(bs, cid->protectedContent, 1); - gf_bs_write_int(bs, 7, 3); //reserved 0b111 = 7 - - if (cid->contentTypeFlag) { - gf_bs_write_int(bs, cid->contentType, 8); - } - - if (cid->contentIdentifierFlag) { - gf_bs_write_int(bs, cid->contentIdentifierType, 8); - gf_bs_write_data(bs, cid->contentIdentifier, size - 2 - cid->contentTypeFlag); - } + + gf_bs_write_int(bs, esd_ref->trackRef, 16); return GF_OK; } -GF_Descriptor *gf_odf_new_dcd() + + +GF_Descriptor *gf_odf_new_segment() { - GF_DecoderConfig *newDesc = (GF_DecoderConfig *) malloc(sizeof(GF_DecoderConfig)); + GF_Segment *newDesc = (GF_Segment *) gf_malloc(sizeof(GF_Segment)); if (!newDesc) return NULL; - newDesc->avgBitrate = 0; - newDesc->bufferSizeDB = 0; - newDesc->maxBitrate = 0; - newDesc->objectTypeIndication = 0; - newDesc->streamType = 0; - newDesc->upstream = 0; - newDesc->decoderSpecificInfo = NULL; - newDesc->profileLevelIndicationIndexDescriptor = gf_list_new(); - newDesc->tag = GF_ODF_DCD_TAG; + memset(newDesc, 0, sizeof(GF_Segment)); + newDesc->tag = GF_ODF_SEGMENT_TAG; return (GF_Descriptor *) newDesc; } -GF_Err gf_odf_del_dcd(GF_DecoderConfig *dcd) +GF_Err gf_odf_del_segment(GF_Segment *sd) { - GF_Err e; - if (!dcd) return GF_BAD_PARAM; + if (!sd) return GF_BAD_PARAM; - if (dcd->decoderSpecificInfo) { - e = gf_odf_delete_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo); - if (e) return e; - } - e = gf_odf_delete_descriptor_list(dcd->profileLevelIndicationIndexDescriptor); - if (e) return e; - free(dcd); + if (sd->SegmentName) gf_free(sd->SegmentName); + gf_free(sd); return GF_OK; } -GF_Err gf_odf_read_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd, u32 DescSize) +GF_Err gf_odf_read_segment(GF_BitStream *bs, GF_Segment *sd, u32 DescSize) { - GF_Err e; - u32 reserved, tmp_size, nbBytes = 0; - if (! dcd) return GF_BAD_PARAM; - - dcd->objectTypeIndication = gf_bs_read_int(bs, 8); - dcd->streamType = gf_bs_read_int(bs, 6); - dcd->upstream = gf_bs_read_int(bs, 1); - reserved = gf_bs_read_int(bs, 1); - dcd->bufferSizeDB = gf_bs_read_int(bs, 24); - dcd->maxBitrate = gf_bs_read_int(bs, 32); - dcd->avgBitrate = gf_bs_read_int(bs, 32); - nbBytes += 13; - - while (nbBytes < DescSize) { - GF_Descriptor *tmp = NULL; - e = gf_odf_parse_descriptor(bs, &tmp, &tmp_size); - if (e) return e; - if (!tmp) return GF_ODF_INVALID_DESCRIPTOR; - switch (tmp->tag) { - case GF_ODF_DSI_TAG: - if (dcd->decoderSpecificInfo) { - gf_odf_delete_descriptor(tmp); - return GF_ODF_INVALID_DESCRIPTOR; - } - dcd->decoderSpecificInfo = (GF_DefaultDescriptor *) tmp; - break; - - case GF_ODF_EXT_PL_TAG: - e = gf_list_add(dcd->profileLevelIndicationIndexDescriptor, tmp); - if (e < GF_OK) { - gf_odf_delete_descriptor(tmp); - return e; - } - break; - - /*iPod fix: delete and aborts, this will create an InvalidDescriptor at the ESD level with a loaded DSI, - laoding will abort with a partially valid ESD which is all the matters*/ - case GF_ODF_SLC_TAG: - gf_odf_delete_descriptor(tmp); - return GF_OK; + u32 size, nbBytes = 0; + if (!sd) return GF_BAD_PARAM; - //what the hell is this descriptor ?? Don't know, so delete it ! - default: - gf_odf_delete_descriptor(tmp); - break; - } - nbBytes += tmp_size + gf_odf_size_field_size(tmp_size); + sd->startTime = gf_bs_read_double(bs); + sd->Duration = gf_bs_read_double(bs); + nbBytes += 16; + size = gf_bs_read_int(bs, 8); + nbBytes += 1; + if (size) { + sd->SegmentName = (char*) gf_malloc(sizeof(char)*(size+1)); + if (!sd->SegmentName) return GF_OUT_OF_MEM; + gf_bs_read_data(bs, sd->SegmentName, size); + sd->SegmentName[size] = 0; + nbBytes += size; } - if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR; + if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } -GF_Err gf_odf_size_dcd(GF_DecoderConfig *dcd, u32 *outSize) +GF_Err gf_odf_size_segment(GF_Segment *sd, u32 *outSize) { - GF_Err e; - u32 tmpSize; - if (! dcd) return GF_BAD_PARAM; - - *outSize = 0; - *outSize += 13; - if (dcd->decoderSpecificInfo) { - //warning: we don't know anything about the structure of a generic DecSpecInfo - //we check the tag and size of the descriptor, but we most ofthe time can't parse it - //the decSpecInfo is handle as a defaultDescriptor (opaque data, but same structure....) - e = gf_odf_size_descriptor((GF_Descriptor *) dcd->decoderSpecificInfo , &tmpSize); - if (e) return e; - *outSize += tmpSize + gf_odf_size_field_size(tmpSize); - } - e = gf_odf_size_descriptor_list(dcd->profileLevelIndicationIndexDescriptor, outSize); - if (e) return e; + if (!sd) return GF_BAD_PARAM; + *outSize = 17; + if (sd->SegmentName) *outSize += strlen(sd->SegmentName); return GF_OK; - } -GF_Err gf_odf_write_dcd(GF_BitStream *bs, GF_DecoderConfig *dcd) +GF_Err gf_odf_write_segment(GF_BitStream *bs, GF_Segment *sd) { GF_Err e; u32 size; - if (! dcd) return GF_BAD_PARAM; - - e = gf_odf_size_descriptor((GF_Descriptor *)dcd, &size); + if (!sd) return GF_BAD_PARAM; + e = gf_odf_size_descriptor((GF_Descriptor *)sd, &size); if (e) return e; - e = gf_odf_write_base_descriptor(bs, dcd->tag, size); + e = gf_odf_write_base_descriptor(bs, sd->tag, size); if (e) return e; + gf_bs_write_double(bs, sd->startTime); + gf_bs_write_double(bs, sd->Duration); + if (sd->SegmentName) { + gf_bs_write_int(bs, strlen(sd->SegmentName), 8); + gf_bs_write_data(bs, sd->SegmentName, strlen(sd->SegmentName)); + } else { + gf_bs_write_int(bs, 0, 8); + } + return GF_OK; +} +GF_Descriptor *gf_odf_new_mediatime() +{ + GF_MediaTime *newDesc = (GF_MediaTime *) gf_malloc(sizeof(GF_MediaTime)); + if (!newDesc) return NULL; - gf_bs_write_int(bs, dcd->objectTypeIndication, 8); - gf_bs_write_int(bs, dcd->streamType, 6); - gf_bs_write_int(bs, dcd->upstream, 1); - gf_bs_write_int(bs, 1, 1); //reserved field... - gf_bs_write_int(bs, dcd->bufferSizeDB, 24); - gf_bs_write_int(bs, dcd->maxBitrate, 32); - gf_bs_write_int(bs, dcd->avgBitrate, 32); + memset(newDesc, 0, sizeof(GF_MediaTime)); + newDesc->tag = GF_ODF_MEDIATIME_TAG; + return (GF_Descriptor *) newDesc; +} +GF_Err gf_odf_del_mediatime(GF_MediaTime *mt) +{ + if (!mt) return GF_BAD_PARAM; + gf_free(mt); + return GF_OK; +} +GF_Err gf_odf_read_mediatime(GF_BitStream *bs, GF_MediaTime *mt, u32 DescSize) +{ + if (!mt) return GF_BAD_PARAM; + mt->mediaTimeStamp = gf_bs_read_double(bs); + return GF_OK; +} +GF_Err gf_odf_size_mediatime(GF_MediaTime *mt, u32 *outSize) +{ + if (!mt) return GF_BAD_PARAM; + *outSize = 8; + return GF_OK; +} +GF_Err gf_odf_write_mediatime(GF_BitStream *bs, GF_MediaTime *mt) +{ + GF_Err e; + u32 size; + if (!mt) return GF_BAD_PARAM; + e = gf_odf_size_descriptor((GF_Descriptor *)mt, &size); + if (e) return e; + e = gf_odf_write_base_descriptor(bs, mt->tag, size); + if (e) return e; + gf_bs_write_double(bs, mt->mediaTimeStamp); + return GF_OK; +} - if (dcd->decoderSpecificInfo) { - e = gf_odf_write_descriptor(bs, (GF_Descriptor *) dcd->decoderSpecificInfo); - if (e) return e; + +GF_Descriptor *gf_odf_new_lang() +{ + GF_Language *newDesc = (GF_Language *) gf_malloc(sizeof(GF_Language)); + if (!newDesc) return NULL; + newDesc->langCode = 0; + newDesc->tag = GF_ODF_LANG_TAG; + return (GF_Descriptor *) newDesc; +} + +GF_Err gf_odf_del_lang(GF_Language *ld) +{ + if (!ld) return GF_BAD_PARAM; + gf_free(ld); + return GF_OK; +} + +GF_Err gf_odf_read_lang(GF_BitStream *bs, GF_Language *ld, u32 DescSize) +{ + u32 nbBytes = 0; + if (!ld) return GF_BAD_PARAM; + + ld->langCode = gf_bs_read_int(bs, 24); + nbBytes += 3; + if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; + return GF_OK; +} + +GF_Err gf_odf_size_lang(GF_Language *ld, u32 *outSize) +{ + if (!ld) return GF_BAD_PARAM; + *outSize = 3; + return GF_OK; +} + +GF_Err gf_odf_write_lang(GF_BitStream *bs, GF_Language *ld) +{ + GF_Err e; + u32 size; + if (!ld) return GF_BAD_PARAM; + + e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size); + if (e) return e; + e = gf_odf_write_base_descriptor(bs, ld->tag, size); + if (e) return e; + gf_bs_write_int(bs, ld->langCode, 24); + return GF_OK; +} + + + +GF_Descriptor *gf_odf_new_auxvid() +{ + GF_AuxVideoDescriptor *newDesc; + GF_SAFEALLOC(newDesc, GF_AuxVideoDescriptor); + if (!newDesc) return NULL; + newDesc->tag = GF_ODF_AUX_VIDEO_DATA; + return (GF_Descriptor *) newDesc; +} + +GF_Err gf_odf_del_auxvid(GF_AuxVideoDescriptor *ld) +{ + if (!ld) return GF_BAD_PARAM; + gf_free(ld); + return GF_OK; +} + +GF_Err gf_odf_read_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld, u32 DescSize) +{ + u32 nbBytes = 0; + if (!ld) return GF_BAD_PARAM; + + ld->aux_video_type = gf_bs_read_int(bs, 8); + ld->position_offset_h = gf_bs_read_int(bs, 8); + ld->position_offset_v = gf_bs_read_int(bs, 8); + nbBytes += 3; + switch (ld->aux_video_type) { + case 0x10: + ld->kfar = gf_bs_read_int(bs, 8); + ld->knear = gf_bs_read_int(bs, 8); + nbBytes += 2; + break; + case 0x11: + ld->parallax_zero = gf_bs_read_int(bs, 16); + ld->parallax_scale = gf_bs_read_int(bs, 16); + ld->dref = gf_bs_read_int(bs, 16); + ld->wref = gf_bs_read_int(bs, 16); + nbBytes += 8; + break; } - e = gf_odf_write_descriptor_list(bs, dcd->profileLevelIndicationIndexDescriptor); - return e; + while (nbBytes < DescSize) { + gf_bs_read_int(bs, 8); + nbBytes ++; + } + return GF_OK; } +GF_Err gf_odf_size_auxvid(GF_AuxVideoDescriptor *ld, u32 *outSize) +{ + if (!ld) return GF_BAD_PARAM; + switch (ld->aux_video_type) { + case 0x10: + *outSize = 5; + break; + case 0x11: + *outSize = 11; + break; + default: + *outSize = 3; + break; + } + return GF_OK; +} -GF_Descriptor *gf_odf_new_default() +GF_Err gf_odf_write_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld) +{ + GF_Err e; + u32 size; + if (!ld) return GF_BAD_PARAM; + e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size); + if (e) return e; + e = gf_odf_write_base_descriptor(bs, ld->tag, size); + if (e) return e; + + gf_bs_write_int(bs, ld->aux_video_type, 8); + gf_bs_write_int(bs, ld->position_offset_h, 8); + gf_bs_write_int(bs, ld->position_offset_v, 8); + switch (ld->aux_video_type) { + case 0x10: + gf_bs_write_int(bs, ld->kfar, 8); + gf_bs_write_int(bs, ld->knear, 8); + break; + case 0x11: + gf_bs_write_int(bs, ld->parallax_zero, 16); + gf_bs_write_int(bs, ld->parallax_scale, 16); + gf_bs_write_int(bs, ld->dref, 16); + gf_bs_write_int(bs, ld->wref, 16); + break; + } + return GF_OK; +} + + + +GF_Descriptor *gf_odf_new_muxinfo() { - GF_DefaultDescriptor *newDesc = (GF_DefaultDescriptor *) malloc(sizeof(GF_DefaultDescriptor)); + GF_MuxInfo *newDesc = (GF_MuxInfo *) gf_malloc(sizeof(GF_MuxInfo)); if (!newDesc) return NULL; + memset(newDesc, 0, sizeof(GF_MuxInfo)); + newDesc->tag = GF_ODF_MUXINFO_TAG; + return (GF_Descriptor *) newDesc; +} - newDesc->dataLength = 0; - newDesc->data = NULL; - //set it to the Max allowed - newDesc->tag = GF_ODF_USER_END_TAG; +GF_Err gf_odf_del_muxinfo(GF_MuxInfo *mi) +{ + if (!mi) return GF_BAD_PARAM; + if (mi->file_name) gf_free(mi->file_name); + if (mi->streamFormat) gf_free(mi->streamFormat); + if (mi->textNode) gf_free(mi->textNode); + if (mi->fontNode) gf_free(mi->fontNode); + gf_free(mi); + return GF_OK; +} + +GF_Err gf_odf_read_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi, u32 DescSize) +{ + return GF_OK; +} +GF_Err gf_odf_size_muxinfo(GF_MuxInfo *mi, u32 *outSize) +{ + *outSize = 0; + return GF_OK; +} +GF_Err gf_odf_write_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi) +{ + return GF_OK; +} + +GF_Descriptor *gf_odf_New_ElemMask() +{ + GF_ElementaryMask *newDesc = (GF_ElementaryMask*) gf_malloc (sizeof(GF_ElementaryMask)); + if (!newDesc) return NULL; + memset(newDesc, 0, sizeof(GF_ElementaryMask)); + newDesc->tag = GF_ODF_ELEM_MASK_TAG; return (GF_Descriptor *) newDesc; } -GF_Err gf_odf_del_default(GF_DefaultDescriptor *dd) +GF_Err gf_odf_del_ElemMask(GF_ElementaryMask *desc) { - if (!dd) return GF_BAD_PARAM; + if (desc->node_name) gf_free(desc->node_name); + gf_free(desc); + return GF_OK; +} - if (dd->data) free(dd->data); - free(dd); +GF_Descriptor *gf_odf_new_bifs_cfg() +{ + GF_BIFSConfig *newDesc = (GF_BIFSConfig *) gf_malloc(sizeof(GF_BIFSConfig)); + if (!newDesc) return NULL; + memset(newDesc, 0, sizeof(GF_BIFSConfig)); + newDesc->tag = GF_ODF_BIFS_CFG_TAG; + return (GF_Descriptor *) newDesc; +} + +GF_Err gf_odf_del_bifs_cfg(GF_BIFSConfig *desc) +{ + if (desc->elementaryMasks) { + u32 i, count = gf_list_count(desc->elementaryMasks); + for (i=0; ielementaryMasks, i); + if (tmp->node_name) gf_free(tmp->node_name); + gf_free(tmp); + } + gf_list_del(desc->elementaryMasks); + } + gf_free(desc); return GF_OK; } -GF_Err gf_odf_read_default(GF_BitStream *bs, GF_DefaultDescriptor *dd, u32 DescSize) +GF_Descriptor *gf_odf_new_laser_cfg() +{ + GF_LASERConfig *newDesc = (GF_LASERConfig *) gf_malloc(sizeof(GF_LASERConfig)); + if (!newDesc) return NULL; + memset(newDesc, 0, sizeof(GF_LASERConfig)); + newDesc->tag = GF_ODF_LASER_CFG_TAG; + return (GF_Descriptor *) newDesc; +} + +GF_Err gf_odf_del_laser_cfg(GF_LASERConfig *desc) +{ + gf_free(desc); + return GF_OK; +} + +GF_Descriptor *gf_odf_new_ui_cfg() +{ + GF_UIConfig *newDesc = (GF_UIConfig *) gf_malloc(sizeof(GF_UIConfig)); + if (!newDesc) return NULL; + memset(newDesc, 0, sizeof(GF_UIConfig)); + newDesc->tag = GF_ODF_UI_CFG_TAG; + return (GF_Descriptor *) newDesc; +} + +GF_Err gf_odf_del_ui_cfg(GF_UIConfig *desc) +{ + if (desc->deviceName) gf_free(desc->deviceName); + if (desc->ui_data) gf_free(desc->ui_data); + gf_free(desc); + return GF_OK; +} + +#ifndef GPAC_MINIMAL_ODF + + + + + + +GF_Descriptor *gf_odf_new_cc() +{ + GF_CCDescriptor *newDesc = (GF_CCDescriptor *) gf_malloc(sizeof(GF_CCDescriptor)); + if (!newDesc) return NULL; + + newDesc->contentClassificationData = NULL; + newDesc->dataLength = 0; + newDesc->classificationEntity = 0; + newDesc->classificationTable = 0; + newDesc->tag = GF_ODF_CC_TAG; + return (GF_Descriptor *) newDesc; +} + +GF_Err gf_odf_del_cc(GF_CCDescriptor *ccd) +{ + if (!ccd) return GF_BAD_PARAM; + if (ccd->contentClassificationData) gf_free(ccd->contentClassificationData); + gf_free(ccd); + return GF_OK; +} + +GF_Err gf_odf_read_cc(GF_BitStream *bs, GF_CCDescriptor *ccd, u32 DescSize) { u32 nbBytes = 0; - if (! dd) return GF_BAD_PARAM; + if (!ccd) return GF_BAD_PARAM; - dd->dataLength = DescSize; - dd->data = NULL; - if (DescSize) { - dd->data = (char*)malloc(dd->dataLength); - if (! dd->data) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, dd->data, dd->dataLength); - nbBytes += dd->dataLength; - } - if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; + ccd->classificationEntity = gf_bs_read_int(bs, 32); + ccd->classificationTable = gf_bs_read_int(bs, 16); + nbBytes += 6; + ccd->dataLength = DescSize - 6; + ccd->contentClassificationData = (char*)gf_malloc(sizeof(char) * ccd->dataLength); + if (!ccd->contentClassificationData) return GF_OUT_OF_MEM; + gf_bs_read_data(bs, ccd->contentClassificationData, ccd->dataLength); + nbBytes += ccd->dataLength; + + if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } -GF_Err gf_odf_size_default(GF_DefaultDescriptor *dd, u32 *outSize) +GF_Err gf_odf_size_cc(GF_CCDescriptor *ccd, u32 *outSize) { - if (! dd) return GF_BAD_PARAM; - *outSize = dd->dataLength; + if (!ccd) return GF_BAD_PARAM; + *outSize = 6 + ccd->dataLength; return GF_OK; } -GF_Err gf_odf_write_default(GF_BitStream *bs, GF_DefaultDescriptor *dd) +GF_Err gf_odf_write_cc(GF_BitStream *bs, GF_CCDescriptor *ccd) { + u32 size; GF_Err e; + if (!ccd) return GF_BAD_PARAM; + + e = gf_odf_size_descriptor((GF_Descriptor *)ccd, &size); + if (e) return e; + e = gf_odf_write_base_descriptor(bs, ccd->tag, size); + if (e) return e; + gf_bs_write_int(bs, ccd->classificationEntity, 32); + gf_bs_write_int(bs, ccd->classificationTable, 16); + gf_bs_write_data(bs, ccd->contentClassificationData, ccd->dataLength); + return GF_OK; +} + +GF_Descriptor *gf_odf_new_cc_date() +{ + GF_CC_Date *newDesc = (GF_CC_Date *) gf_malloc(sizeof(GF_CC_Date)); + if (!newDesc) return NULL; + memset(newDesc->contentCreationDate, 0, 5); + newDesc->tag = GF_ODF_CC_DATE_TAG; + return (GF_Descriptor *) newDesc; +} + + +GF_Err gf_odf_del_cc_date(GF_CC_Date *cdd) +{ + if (!cdd) return GF_BAD_PARAM; + gf_free(cdd); + return GF_OK; +} + +GF_Err gf_odf_read_cc_date(GF_BitStream *bs, GF_CC_Date *cdd, u32 DescSize) +{ + u32 nbBytes = 0; + if (!cdd) return GF_BAD_PARAM; + + gf_bs_read_data(bs, cdd->contentCreationDate, DATE_CODING_BIT_LEN); + nbBytes += DATE_CODING_BIT_LEN / 8; + if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR; + return GF_OK; +} + +GF_Err gf_odf_size_cc_date(GF_CC_Date *cdd, u32 *outSize) +{ + if (!cdd) return GF_BAD_PARAM; + *outSize = (DATE_CODING_BIT_LEN / 8); + return GF_OK; +} + +GF_Err gf_odf_write_cc_date(GF_BitStream *bs, GF_CC_Date *cdd) +{ u32 size; - if (! dd) return GF_BAD_PARAM; + GF_Err e; + if (!cdd) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)dd, &size); + e = gf_odf_size_descriptor((GF_Descriptor *)cdd, &size); if (e) return e; - e = gf_odf_write_base_descriptor(bs, dd->tag, size); + e = gf_odf_write_base_descriptor(bs, cdd->tag, size); if (e) return e; - if (dd->data) { - gf_bs_write_data(bs, dd->data, dd->dataLength); + gf_bs_write_data(bs, cdd->contentCreationDate , DATE_CODING_BIT_LEN); + return GF_OK; +} + +GF_Descriptor *gf_odf_new_cc_name() +{ + GF_CC_Name *newDesc = (GF_CC_Name *) gf_malloc(sizeof(GF_CC_Name)); + if (!newDesc) return NULL; + + newDesc->ContentCreators = gf_list_new(); + if (! newDesc->ContentCreators) { + gf_free(newDesc); + return NULL; + } + newDesc->tag = GF_ODF_CC_NAME_TAG; + return (GF_Descriptor *) newDesc; +} + +GF_Err gf_odf_del_cc_name(GF_CC_Name *cnd) +{ + u32 i; + GF_ContentCreatorInfo *tmp; + if (!cnd) return GF_BAD_PARAM; + + i=0; + while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) { + if (tmp->contentCreatorName) gf_free(tmp->contentCreatorName); + gf_free(tmp); + } + gf_list_del(cnd->ContentCreators); + gf_free(cnd); + return GF_OK; +} + +GF_Err gf_odf_read_cc_name(GF_BitStream *bs, GF_CC_Name *cnd, u32 DescSize) +{ + GF_Err e; + u32 i, aligned, count, len, nbBytes = 0; + if (!cnd) return GF_BAD_PARAM; + + count = gf_bs_read_int(bs, 8); + nbBytes += 1; + for (i = 0; i< count; i++) { + GF_ContentCreatorInfo *tmp = (GF_ContentCreatorInfo*)gf_malloc(sizeof(GF_ContentCreatorInfo)); + if (! tmp) return GF_OUT_OF_MEM; + memset(tmp , 0, sizeof(GF_ContentCreatorInfo)); + tmp->langCode = gf_bs_read_int(bs, 24); + tmp->isUTF8 = gf_bs_read_int(bs, 1); + aligned = gf_bs_read_int(bs, 7); + nbBytes += 4; + + e = OD_ReadUTF8String(bs, & tmp->contentCreatorName, tmp->isUTF8, &len); + if (e) return e; + nbBytes += len; + e = gf_list_add(cnd->ContentCreators, tmp); } + if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } -GF_Descriptor *gf_odf_new_esd_inc() +GF_Err gf_odf_size_cc_name(GF_CC_Name *cnd, u32 *outSize) { - GF_ES_ID_Inc *newDesc = (GF_ES_ID_Inc *) malloc(sizeof(GF_ES_ID_Inc)); - if (!newDesc) return NULL; - newDesc->tag = GF_ODF_ESD_INC_TAG; - newDesc->trackID = 0; - return (GF_Descriptor *) newDesc; -} + u32 i; + GF_ContentCreatorInfo *tmp; + if (!cnd) return GF_BAD_PARAM; -GF_Err gf_odf_del_esd_inc(GF_ES_ID_Inc *esd_inc) -{ - if (!esd_inc) return GF_BAD_PARAM; - free(esd_inc); + *outSize = 1; + i=0; + while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) { + *outSize += 4 + OD_SizeUTF8String(tmp->contentCreatorName, tmp->isUTF8); + } return GF_OK; } -GF_Err gf_odf_read_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc, u32 DescSize) -{ - u32 nbBytes = 0; - if (! esd_inc) return GF_BAD_PARAM; - esd_inc->trackID = gf_bs_read_int(bs, 32); - nbBytes += 4; - if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; - return GF_OK; -} -GF_Err gf_odf_size_esd_inc(GF_ES_ID_Inc *esd_inc, u32 *outSize) -{ - if (! esd_inc) return GF_BAD_PARAM; - *outSize = 4; - return GF_OK; -} -GF_Err gf_odf_write_esd_inc(GF_BitStream *bs, GF_ES_ID_Inc *esd_inc) +GF_Err gf_odf_write_cc_name(GF_BitStream *bs, GF_CC_Name *cnd) { GF_Err e; - u32 size; - if (! esd_inc) return GF_BAD_PARAM; + GF_ContentCreatorInfo *tmp; + u32 i, size; + if (!cnd) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)esd_inc, &size); + e = gf_odf_size_descriptor((GF_Descriptor *)cnd, &size); if (e) return e; - e = gf_odf_write_base_descriptor(bs, esd_inc->tag, size); + e = gf_odf_write_base_descriptor(bs, cnd->tag, size); if (e) return e; - gf_bs_write_int(bs, esd_inc->trackID, 32); + gf_bs_write_int(bs, gf_list_count(cnd->ContentCreators), 8); + + i=0; + while ((tmp = (GF_ContentCreatorInfo *)gf_list_enum(cnd->ContentCreators, &i))) { + gf_bs_write_int(bs, tmp->langCode, 24); + gf_bs_write_int(bs, tmp->isUTF8, 1); + gf_bs_write_int(bs, 0, 7); //aligned + OD_WriteUTF8String(bs, tmp->contentCreatorName, tmp->isUTF8); + } return GF_OK; } + -GF_Descriptor *gf_odf_new_esd_ref() +GF_Descriptor *gf_odf_new_ci() { - GF_ES_ID_Ref *newDesc = (GF_ES_ID_Ref *) malloc(sizeof(GF_ES_ID_Ref)); + GF_CIDesc *newDesc = (GF_CIDesc *) gf_malloc(sizeof(GF_CIDesc)); if (!newDesc) return NULL; - newDesc->tag = GF_ODF_ESD_REF_TAG; - newDesc->trackRef = 0; + + newDesc->compatibility = 0; + newDesc->contentIdentifier = NULL; + newDesc->tag = GF_ODF_CI_TAG; + newDesc->contentIdentifierFlag = 0; + newDesc->contentIdentifierType = 0; + newDesc->contentType = 0; + newDesc->contentTypeFlag = 0; + newDesc->protectedContent = 0; return (GF_Descriptor *) newDesc; } -GF_Err gf_odf_del_esd_ref(GF_ES_ID_Ref *esd_ref) + +GF_Err gf_odf_del_ci(GF_CIDesc *cid) { - if (!esd_ref) return GF_BAD_PARAM; - free(esd_ref); + if (!cid) return GF_BAD_PARAM; + + if (cid->contentIdentifier) gf_free(cid->contentIdentifier); + gf_free(cid); return GF_OK; } -GF_Err gf_odf_read_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref, u32 DescSize) + + +GF_Err gf_odf_read_ci(GF_BitStream *bs, GF_CIDesc *cid, u32 DescSize) { - u32 nbBytes = 0; - if (! esd_ref) return GF_BAD_PARAM; + u32 reserved, nbBytes = 0; + if (! cid) return GF_BAD_PARAM; - esd_ref->trackRef = gf_bs_read_int(bs, 16); - nbBytes += 2; + cid->compatibility = gf_bs_read_int(bs, 2); //MUST BE NULL + if (cid->compatibility) return GF_ODF_INVALID_DESCRIPTOR; + + cid->contentTypeFlag = gf_bs_read_int(bs, 1); + cid->contentIdentifierFlag = gf_bs_read_int(bs, 1); + cid->protectedContent = gf_bs_read_int(bs, 1); + reserved = gf_bs_read_int(bs, 3); + nbBytes += 1; + + if (cid->contentTypeFlag) { + cid->contentType = gf_bs_read_int(bs, 8); + nbBytes += 1; + } + if (cid->contentIdentifierFlag) { + cid->contentIdentifierType = gf_bs_read_int(bs, 8); + cid->contentIdentifier = (char*)gf_malloc(DescSize - 2 - cid->contentTypeFlag); + if (! cid->contentIdentifier) return GF_OUT_OF_MEM; + + gf_bs_read_data(bs, cid->contentIdentifier, DescSize - 2 - cid->contentTypeFlag); + nbBytes += DescSize - 1 - cid->contentTypeFlag; + } if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } -GF_Err gf_odf_size_esd_ref(GF_ES_ID_Ref *esd_ref, u32 *outSize) +GF_Err gf_odf_size_ci(GF_CIDesc *cid, u32 *outSize) { - if (! esd_ref) return GF_BAD_PARAM; - *outSize = 2; + if (! cid) return GF_BAD_PARAM; + + *outSize = 1; + if (cid->contentTypeFlag) *outSize += 1; + + if (cid->contentIdentifierFlag) + *outSize += strlen((const char*)cid->contentIdentifier) - 1 - cid->contentTypeFlag; return GF_OK; } -GF_Err gf_odf_write_esd_ref(GF_BitStream *bs, GF_ES_ID_Ref *esd_ref) + +GF_Err gf_odf_write_ci(GF_BitStream *bs, GF_CIDesc *cid) { GF_Err e; u32 size; - if (! esd_ref) return GF_BAD_PARAM; + if (! cid) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)esd_ref, &size); + e = gf_odf_size_descriptor((GF_Descriptor *)cid, &size); if (e) return e; - e = gf_odf_write_base_descriptor(bs, esd_ref->tag, size); + e = gf_odf_write_base_descriptor(bs, cid->tag, size); if (e) return e; - - gf_bs_write_int(bs, esd_ref->trackRef, 16); + + gf_bs_write_int(bs, cid->compatibility, 2); + gf_bs_write_int(bs, cid->contentTypeFlag, 1); + gf_bs_write_int(bs, cid->contentIdentifierFlag, 1); + gf_bs_write_int(bs, cid->protectedContent, 1); + gf_bs_write_int(bs, 7, 3); //reserved 0b111 = 7 + + if (cid->contentTypeFlag) { + gf_bs_write_int(bs, cid->contentType, 8); + } + + if (cid->contentIdentifierFlag) { + gf_bs_write_int(bs, cid->contentIdentifierType, 8); + gf_bs_write_data(bs, cid->contentIdentifier, size - 2 - cid->contentTypeFlag); + } return GF_OK; } GF_Descriptor *gf_odf_new_exp_text() { - GF_ExpandedTextual *newDesc = (GF_ExpandedTextual *) malloc(sizeof(GF_ExpandedTextual)); + GF_ExpandedTextual *newDesc = (GF_ExpandedTextual *) gf_malloc(sizeof(GF_ExpandedTextual)); if (!newDesc) return NULL; newDesc->itemDescriptionList = gf_list_new(); if (! newDesc->itemDescriptionList) { - free(newDesc); + gf_free(newDesc); return NULL; } newDesc->itemTextList = gf_list_new(); if (! newDesc->itemTextList) { - free(newDesc->itemDescriptionList); - free(newDesc); + gf_free(newDesc->itemDescriptionList); + gf_free(newDesc); return NULL; } newDesc->isUTF8 = 0; @@ -1706,8 +2074,8 @@ GF_Err gf_odf_del_exp_text(GF_ExpandedTextual *etd) while (gf_list_count(etd->itemDescriptionList)) { GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemDescriptionList, 0); if (tmp) { - if (tmp->text) free(tmp->text); - free(tmp); + if (tmp->text) gf_free(tmp->text); + gf_free(tmp); } gf_list_rem(etd->itemDescriptionList, 0); } @@ -1716,15 +2084,15 @@ GF_Err gf_odf_del_exp_text(GF_ExpandedTextual *etd) while (gf_list_count(etd->itemTextList)) { GF_ETD_ItemText *tmp = (GF_ETD_ItemText*)gf_list_get(etd->itemTextList, 0); if (tmp) { - if (tmp->text) free(tmp->text); - free(tmp); + if (tmp->text) gf_free(tmp->text); + gf_free(tmp); } gf_list_rem(etd->itemTextList, 0); } gf_list_del(etd->itemTextList); - if (etd->NonItemText) free(etd->NonItemText); - free(etd); + if (etd->NonItemText) gf_free(etd->NonItemText); + gf_free(etd); return GF_OK; } @@ -1744,7 +2112,7 @@ GF_Err gf_odf_read_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd, u32 DescS for (i = 0; i< count; i++) { //description GF_ETD_ItemText *description, *Text; - description = (GF_ETD_ItemText*)malloc(sizeof(GF_ETD_ItemText)); + description = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText)); if (! description) return GF_OUT_OF_MEM; description->text = NULL; e = OD_ReadUTF8String(bs, & description->text, etd->isUTF8, &len); @@ -1754,7 +2122,7 @@ GF_Err gf_odf_read_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd, u32 DescS nbBytes += len; //text - Text = (GF_ETD_ItemText*)malloc(sizeof(GF_ETD_ItemText)); + Text = (GF_ETD_ItemText*)gf_malloc(sizeof(GF_ETD_ItemText)); if (! Text) return GF_OUT_OF_MEM; Text->text = NULL; e = OD_ReadUTF8String(bs, & Text->text, etd->isUTF8, &len); @@ -1775,7 +2143,7 @@ GF_Err gf_odf_read_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd, u32 DescS if (nonLen) { //here we have no choice but do the job ourselves //because the length is not encoded on 8 bits - etd->NonItemText = (char *) malloc(sizeof(char) * (1+nonLen) * (etd->isUTF8 ? 1 : 2)); + etd->NonItemText = (char *) gf_malloc(sizeof(char) * (1+nonLen) * (etd->isUTF8 ? 1 : 2)); if (! etd->NonItemText) return GF_OUT_OF_MEM; gf_bs_read_data(bs, etd->NonItemText, nonLen * (etd->isUTF8 ? 1 : 2)); nbBytes += nonLen * (etd->isUTF8 ? 1 : 2); @@ -1877,7 +2245,7 @@ GF_Err gf_odf_write_exp_text(GF_BitStream *bs, GF_ExpandedTextual *etd) GF_Descriptor *gf_odf_new_pl_ext() { - GF_PLExt *newDesc = (GF_PLExt *) malloc(sizeof(GF_PLExt)); + GF_PLExt *newDesc = (GF_PLExt *) gf_malloc(sizeof(GF_PLExt)); if (!newDesc) return NULL; newDesc->AudioProfileLevelIndication = 0; newDesc->GraphicsProfileLevelIndication = 0; @@ -1894,7 +2262,7 @@ GF_Err gf_odf_del_pl_ext(GF_PLExt *pld) { if (!pld) return GF_BAD_PARAM; - free(pld); + gf_free(pld); return GF_OK; } @@ -1915,146 +2283,39 @@ GF_Err gf_odf_read_pl_ext(GF_BitStream *bs, GF_PLExt *pld, u32 DescSize) if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; return GF_OK; } - -GF_Err gf_odf_size_pl_ext(GF_PLExt *pld, u32 *outSize) -{ - if (!pld) return GF_BAD_PARAM; - - *outSize = 7; - return GF_OK; -} - -GF_Err gf_odf_write_pl_ext(GF_BitStream *bs, GF_PLExt *pld) -{ - GF_Err e; - u32 size; - if (!pld) return GF_BAD_PARAM; - - e = gf_odf_size_descriptor((GF_Descriptor *)pld, &size); - if (e) return e; - e = gf_odf_write_base_descriptor(bs, pld->tag, size); - if (e) return e; - - gf_bs_write_int(bs, pld->profileLevelIndicationIndex, 8); - gf_bs_write_int(bs, pld->ODProfileLevelIndication, 8); - gf_bs_write_int(bs, pld->SceneProfileLevelIndication, 8); - gf_bs_write_int(bs, pld->AudioProfileLevelIndication, 8); - gf_bs_write_int(bs, pld->VisualProfileLevelIndication, 8); - gf_bs_write_int(bs, pld->GraphicsProfileLevelIndication, 8); - gf_bs_write_int(bs, pld->MPEGJProfileLevelIndication, 8); - return GF_OK; -} - -GF_Descriptor *gf_odf_new_segment() -{ - GF_Segment *newDesc = (GF_Segment *) malloc(sizeof(GF_Segment)); - if (!newDesc) return NULL; - - memset(newDesc, 0, sizeof(GF_Segment)); - newDesc->tag = GF_ODF_SEGMENT_TAG; - return (GF_Descriptor *) newDesc; -} - -GF_Err gf_odf_del_segment(GF_Segment *sd) -{ - if (!sd) return GF_BAD_PARAM; - - if (sd->SegmentName) free(sd->SegmentName); - free(sd); - return GF_OK; -} - -GF_Err gf_odf_read_segment(GF_BitStream *bs, GF_Segment *sd, u32 DescSize) -{ - u32 size, nbBytes = 0; - if (!sd) return GF_BAD_PARAM; - - sd->startTime = gf_bs_read_double(bs); - sd->Duration = gf_bs_read_double(bs); - nbBytes += 16; - size = gf_bs_read_int(bs, 8); - nbBytes += 1; - if (size) { - sd->SegmentName = (char*) malloc(sizeof(char)*(size+1)); - if (!sd->SegmentName) return GF_OUT_OF_MEM; - gf_bs_read_data(bs, sd->SegmentName, size); - sd->SegmentName[size] = 0; - nbBytes += size; - } - if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; - return GF_OK; -} - -GF_Err gf_odf_size_segment(GF_Segment *sd, u32 *outSize) -{ - if (!sd) return GF_BAD_PARAM; - *outSize = 17; - if (sd->SegmentName) *outSize += strlen(sd->SegmentName); - return GF_OK; -} - -GF_Err gf_odf_write_segment(GF_BitStream *bs, GF_Segment *sd) -{ - GF_Err e; - u32 size; - if (!sd) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)sd, &size); - if (e) return e; - e = gf_odf_write_base_descriptor(bs, sd->tag, size); - if (e) return e; - gf_bs_write_double(bs, sd->startTime); - gf_bs_write_double(bs, sd->Duration); - if (sd->SegmentName) { - gf_bs_write_int(bs, strlen(sd->SegmentName), 8); - gf_bs_write_data(bs, sd->SegmentName, strlen(sd->SegmentName)); - } else { - gf_bs_write_int(bs, 0, 8); - } - return GF_OK; -} -GF_Descriptor *gf_odf_new_mediatime() -{ - GF_MediaTime *newDesc = (GF_MediaTime *) malloc(sizeof(GF_MediaTime)); - if (!newDesc) return NULL; - - memset(newDesc, 0, sizeof(GF_MediaTime)); - newDesc->tag = GF_ODF_MEDIATIME_TAG; - return (GF_Descriptor *) newDesc; -} -GF_Err gf_odf_del_mediatime(GF_MediaTime *mt) -{ - if (!mt) return GF_BAD_PARAM; - free(mt); - return GF_OK; -} -GF_Err gf_odf_read_mediatime(GF_BitStream *bs, GF_MediaTime *mt, u32 DescSize) -{ - if (!mt) return GF_BAD_PARAM; - mt->mediaTimeStamp = gf_bs_read_double(bs); - return GF_OK; -} -GF_Err gf_odf_size_mediatime(GF_MediaTime *mt, u32 *outSize) + +GF_Err gf_odf_size_pl_ext(GF_PLExt *pld, u32 *outSize) { - if (!mt) return GF_BAD_PARAM; - *outSize = 8; + if (!pld) return GF_BAD_PARAM; + + *outSize = 7; return GF_OK; } -GF_Err gf_odf_write_mediatime(GF_BitStream *bs, GF_MediaTime *mt) + +GF_Err gf_odf_write_pl_ext(GF_BitStream *bs, GF_PLExt *pld) { GF_Err e; u32 size; - if (!mt) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)mt, &size); + if (!pld) return GF_BAD_PARAM; + + e = gf_odf_size_descriptor((GF_Descriptor *)pld, &size); if (e) return e; - e = gf_odf_write_base_descriptor(bs, mt->tag, size); + e = gf_odf_write_base_descriptor(bs, pld->tag, size); if (e) return e; - gf_bs_write_double(bs, mt->mediaTimeStamp); + + gf_bs_write_int(bs, pld->profileLevelIndicationIndex, 8); + gf_bs_write_int(bs, pld->ODProfileLevelIndication, 8); + gf_bs_write_int(bs, pld->SceneProfileLevelIndication, 8); + gf_bs_write_int(bs, pld->AudioProfileLevelIndication, 8); + gf_bs_write_int(bs, pld->VisualProfileLevelIndication, 8); + gf_bs_write_int(bs, pld->GraphicsProfileLevelIndication, 8); + gf_bs_write_int(bs, pld->MPEGJProfileLevelIndication, 8); return GF_OK; } GF_Descriptor *gf_odf_new_ipi_ptr() { - GF_IPIPtr *newDesc = (GF_IPIPtr *) malloc(sizeof(GF_IPIPtr)); + GF_IPIPtr *newDesc = (GF_IPIPtr *) gf_malloc(sizeof(GF_IPIPtr)); if (!newDesc) return NULL; newDesc->IPI_ES_Id = 0; newDesc->tag = GF_ODF_IPI_PTR_TAG; @@ -2064,7 +2325,7 @@ GF_Descriptor *gf_odf_new_ipi_ptr() GF_Err gf_odf_del_ipi_ptr(GF_IPIPtr *ipid) { if (!ipid) return GF_BAD_PARAM; - free(ipid); + gf_free(ipid); return GF_OK; } @@ -2112,7 +2373,7 @@ GF_Descriptor *gf_odf_new_ipmp() GF_Err gf_odf_del_ipmp(GF_IPMP_Descriptor *ipmp) { if (!ipmp) return GF_BAD_PARAM; - if (ipmp->opaque_data) free(ipmp->opaque_data); + if (ipmp->opaque_data) gf_free(ipmp->opaque_data); /*TODO DELETE IPMPX*/ while (gf_list_count(ipmp->ipmpx_data)) { GF_IPMPX_Data *p = (GF_IPMPX_Data *)gf_list_get(ipmp->ipmpx_data, 0); @@ -2120,13 +2381,14 @@ GF_Err gf_odf_del_ipmp(GF_IPMP_Descriptor *ipmp) gf_ipmpx_data_del(p); } gf_list_del(ipmp->ipmpx_data); - free(ipmp); + gf_free(ipmp); return GF_OK; } GF_Err gf_odf_read_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp, u32 DescSize) { - u32 size, nbBytes = 0; + u32 size; + u64 nbBytes = 0; if (!ipmp) return GF_BAD_PARAM; ipmp->IPMP_DescriptorID = gf_bs_read_int(bs, 8); @@ -2145,19 +2407,19 @@ GF_Err gf_odf_read_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp, u32 DescSize nbBytes += 1; } while (nbBytesipmpx_data, p); - nbBytes += (u32) gf_bs_get_position(bs) - pos; + nbBytes += gf_bs_get_position(bs) - pos; } } /*URL*/ else if (! ipmp->IPMPS_Type) { - ipmp->opaque_data = (char*)malloc(size + 1); + ipmp->opaque_data = (char*)gf_malloc(size + 1); if (! ipmp->opaque_data) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ipmp->opaque_data, size); nbBytes += size; @@ -2168,7 +2430,7 @@ GF_Err gf_odf_read_ipmp(GF_BitStream *bs, GF_IPMP_Descriptor *ipmp, u32 DescSize /*data*/ else { ipmp->opaque_data_size = size; - ipmp->opaque_data = (char*)malloc(size); + ipmp->opaque_data = (char*)gf_malloc(size); if (! ipmp->opaque_data) return GF_OUT_OF_MEM; gf_bs_read_data(bs, ipmp->opaque_data, size); nbBytes += size; @@ -2249,7 +2511,7 @@ GF_Descriptor *gf_odf_new_ipmp_ptr() GF_Err gf_odf_del_ipmp_ptr(GF_IPMPPtr *ipmpd) { if (!ipmpd) return GF_BAD_PARAM; - free(ipmpd); + gf_free(ipmpd); return GF_OK; } @@ -2294,12 +2556,12 @@ GF_Err gf_odf_write_ipmp_ptr(GF_BitStream *bs, GF_IPMPPtr *ipmpd) GF_Descriptor *gf_odf_new_kw() { - GF_KeyWord *newDesc = (GF_KeyWord *) malloc(sizeof(GF_KeyWord)); + GF_KeyWord *newDesc = (GF_KeyWord *) gf_malloc(sizeof(GF_KeyWord)); if (!newDesc) return NULL; newDesc->keyWordsList = gf_list_new(); if (! newDesc->keyWordsList) { - free(newDesc); + gf_free(newDesc); return NULL; } newDesc->isUTF8 = 0; @@ -2315,12 +2577,12 @@ GF_Err gf_odf_del_kw(GF_KeyWord *kwd) while (gf_list_count(kwd->keyWordsList)) { GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_list_get(kwd->keyWordsList, 0); if (tmp) { - if (tmp->keyWord) free(tmp->keyWord); - free(tmp); + if (tmp->keyWord) gf_free(tmp->keyWord); + gf_free(tmp); } } gf_list_del(kwd->keyWordsList); - free(kwd); + gf_free(kwd); return GF_OK; } @@ -2337,7 +2599,7 @@ GF_Err gf_odf_read_kw(GF_BitStream *bs, GF_KeyWord *kwd, u32 DescSize) nbBytes += 5; for (i = 0 ; i < kwcount; i++) { - GF_KeyWordItem *tmp = (GF_KeyWordItem*)malloc(sizeof(GF_KeyWordItem)); + GF_KeyWordItem *tmp = (GF_KeyWordItem*)gf_malloc(sizeof(GF_KeyWordItem)); if (! tmp) return GF_OUT_OF_MEM; e = OD_ReadUTF8String(bs, & tmp->keyWord, kwd->isUTF8, &len); if (e) return e; @@ -2385,151 +2647,9 @@ GF_Err gf_odf_write_kw(GF_BitStream *bs, GF_KeyWord *kwd) return GF_OK; } -GF_Descriptor *gf_odf_new_lang() -{ - GF_Language *newDesc = (GF_Language *) malloc(sizeof(GF_Language)); - if (!newDesc) return NULL; - newDesc->langCode = 0; - newDesc->tag = GF_ODF_LANG_TAG; - return (GF_Descriptor *) newDesc; -} - -GF_Err gf_odf_del_lang(GF_Language *ld) -{ - if (!ld) return GF_BAD_PARAM; - free(ld); - return GF_OK; -} - -GF_Err gf_odf_read_lang(GF_BitStream *bs, GF_Language *ld, u32 DescSize) -{ - u32 nbBytes = 0; - if (!ld) return GF_BAD_PARAM; - - ld->langCode = gf_bs_read_int(bs, 24); - nbBytes += 3; - if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR; - return GF_OK; -} - -GF_Err gf_odf_size_lang(GF_Language *ld, u32 *outSize) -{ - if (!ld) return GF_BAD_PARAM; - *outSize = 3; - return GF_OK; -} - -GF_Err gf_odf_write_lang(GF_BitStream *bs, GF_Language *ld) -{ - GF_Err e; - u32 size; - if (!ld) return GF_BAD_PARAM; - - e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size); - if (e) return e; - e = gf_odf_write_base_descriptor(bs, ld->tag, size); - if (e) return e; - gf_bs_write_int(bs, ld->langCode, 24); - return GF_OK; -} - - - -GF_Descriptor *gf_odf_new_auxvid() -{ - GF_AuxVideoDescriptor *newDesc; - GF_SAFEALLOC(newDesc, GF_AuxVideoDescriptor); - if (!newDesc) return NULL; - newDesc->tag = GF_ODF_AUX_VIDEO_DATA; - return (GF_Descriptor *) newDesc; -} - -GF_Err gf_odf_del_auxvid(GF_AuxVideoDescriptor *ld) -{ - if (!ld) return GF_BAD_PARAM; - free(ld); - return GF_OK; -} - -GF_Err gf_odf_read_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld, u32 DescSize) -{ - u32 nbBytes = 0; - if (!ld) return GF_BAD_PARAM; - - ld->aux_video_type = gf_bs_read_int(bs, 8); - ld->position_offset_h = gf_bs_read_int(bs, 8); - ld->position_offset_v = gf_bs_read_int(bs, 8); - nbBytes += 3; - switch (ld->aux_video_type) { - case 0x10: - ld->kfar = gf_bs_read_int(bs, 8); - ld->knear = gf_bs_read_int(bs, 8); - nbBytes += 2; - break; - case 0x11: - ld->parallax_zero = gf_bs_read_int(bs, 16); - ld->parallax_scale = gf_bs_read_int(bs, 16); - ld->dref = gf_bs_read_int(bs, 16); - ld->wref = gf_bs_read_int(bs, 16); - nbBytes += 8; - break; - } - while (nbBytes < DescSize) { - gf_bs_read_int(bs, 8); - nbBytes ++; - } - return GF_OK; -} - -GF_Err gf_odf_size_auxvid(GF_AuxVideoDescriptor *ld, u32 *outSize) -{ - if (!ld) return GF_BAD_PARAM; - switch (ld->aux_video_type) { - case 0x10: - *outSize = 5; - break; - case 0x11: - *outSize = 11; - break; - default: - *outSize = 3; - break; - } - return GF_OK; -} - -GF_Err gf_odf_write_auxvid(GF_BitStream *bs, GF_AuxVideoDescriptor *ld) -{ - GF_Err e; - u32 size; - if (!ld) return GF_BAD_PARAM; - e = gf_odf_size_descriptor((GF_Descriptor *)ld, &size); - if (e) return e; - e = gf_odf_write_base_descriptor(bs, ld->tag, size); - if (e) return e; - - gf_bs_write_int(bs, ld->aux_video_type, 8); - gf_bs_write_int(bs, ld->position_offset_h, 8); - gf_bs_write_int(bs, ld->position_offset_v, 8); - switch (ld->aux_video_type) { - case 0x10: - gf_bs_write_int(bs, ld->kfar, 8); - gf_bs_write_int(bs, ld->knear, 8); - break; - case 0x11: - gf_bs_write_int(bs, ld->parallax_zero, 16); - gf_bs_write_int(bs, ld->parallax_scale, 16); - gf_bs_write_int(bs, ld->dref, 16); - gf_bs_write_int(bs, ld->wref, 16); - break; - } - return GF_OK; -} - - GF_Descriptor *gf_odf_new_oci_date() { - GF_OCI_Data *newDesc = (GF_OCI_Data *) malloc(sizeof(GF_OCI_Data)); + GF_OCI_Data *newDesc = (GF_OCI_Data *) gf_malloc(sizeof(GF_OCI_Data)); if (!newDesc) return NULL; memset(newDesc->OCICreationDate, 0, 5); newDesc->tag = GF_ODF_OCI_DATE_TAG; @@ -2539,7 +2659,7 @@ GF_Descriptor *gf_odf_new_oci_date() GF_Err gf_odf_del_oci_date(GF_OCI_Data *ocd) { if (!ocd) return GF_BAD_PARAM; - free(ocd); + gf_free(ocd); return GF_OK; } @@ -2577,12 +2697,12 @@ GF_Err gf_odf_write_oci_date(GF_BitStream *bs, GF_OCI_Data *ocd) GF_Descriptor *gf_odf_new_oci_name() { - GF_OCICreators *newDesc = (GF_OCICreators *) malloc(sizeof(GF_OCICreators)); + GF_OCICreators *newDesc = (GF_OCICreators *) gf_malloc(sizeof(GF_OCICreators)); if (!newDesc) return NULL; newDesc->OCICreators = gf_list_new(); if (! newDesc->OCICreators) { - free(newDesc); + gf_free(newDesc); return NULL; } newDesc->tag = GF_ODF_OCI_NAME_TAG; @@ -2596,11 +2716,11 @@ GF_Err gf_odf_del_oci_name(GF_OCICreators *ocn) i=0; while ((tmp = (GF_OCICreator_item *)gf_list_enum(ocn->OCICreators, &i))) { - if (tmp->OCICreatorName) free(tmp->OCICreatorName); - free(tmp); + if (tmp->OCICreatorName) gf_free(tmp->OCICreatorName); + gf_free(tmp); } gf_list_del(ocn->OCICreators); - free(ocn); + gf_free(ocn); return GF_OK; } @@ -2614,7 +2734,7 @@ GF_Err gf_odf_read_oci_name(GF_BitStream *bs, GF_OCICreators *ocn, u32 DescSize) count = gf_bs_read_int(bs, 8); nbBytes += 1; for (i = 0; i< count; i++) { - GF_OCICreator_item *tmp = (GF_OCICreator_item*)malloc(sizeof(GF_OCICreator_item)); + GF_OCICreator_item *tmp = (GF_OCICreator_item*)gf_malloc(sizeof(GF_OCICreator_item)); if (! tmp) return GF_OUT_OF_MEM; tmp->langCode = gf_bs_read_int(bs, 24); tmp->isUTF8 = gf_bs_read_int(bs, 1); @@ -2672,7 +2792,7 @@ GF_Err gf_odf_write_oci_name(GF_BitStream *bs, GF_OCICreators *ocn) GF_Descriptor *gf_odf_new_pl_idx() { - GF_PL_IDX *newDesc = (GF_PL_IDX *) malloc(sizeof(GF_PL_IDX)); + GF_PL_IDX *newDesc = (GF_PL_IDX *) gf_malloc(sizeof(GF_PL_IDX)); if (!newDesc) return NULL; newDesc->profileLevelIndicationIndex = 0; newDesc->tag = GF_ODF_PL_IDX_TAG; @@ -2682,7 +2802,7 @@ GF_Descriptor *gf_odf_new_pl_idx() GF_Err gf_odf_del_pl_idx(GF_PL_IDX *plid) { if (!plid) return GF_BAD_PARAM; - free(plid); + gf_free(plid); return GF_OK; } @@ -2718,7 +2838,7 @@ GF_Err gf_odf_write_pl_idx(GF_BitStream *bs, GF_PL_IDX *plid) GF_Descriptor *gf_odf_new_rating() { - GF_Rating *newDesc = (GF_Rating *) malloc(sizeof(GF_Rating)); + GF_Rating *newDesc = (GF_Rating *) gf_malloc(sizeof(GF_Rating)); if (!newDesc) return NULL; newDesc->infoLength = 0; @@ -2733,8 +2853,8 @@ GF_Err gf_odf_del_rating(GF_Rating *rd) { if (!rd) return GF_BAD_PARAM; - if (rd->ratingInfo) free(rd->ratingInfo); - free(rd); + if (rd->ratingInfo) gf_free(rd->ratingInfo); + gf_free(rd); return GF_OK; } @@ -2748,7 +2868,7 @@ GF_Err gf_odf_read_rating(GF_BitStream *bs, GF_Rating *rd, u32 DescSize) rd->infoLength = DescSize - 6; nbBytes += 6; - rd->ratingInfo = (char*)malloc(rd->infoLength); + rd->ratingInfo = (char*)gf_malloc(rd->infoLength); if (! rd->ratingInfo) return GF_OUT_OF_MEM; gf_bs_read_data(bs, rd->ratingInfo, rd->infoLength); nbBytes += rd->infoLength; @@ -2782,7 +2902,7 @@ GF_Err gf_odf_write_rating(GF_BitStream *bs, GF_Rating *rd) GF_Descriptor *gf_odf_new_reg() { - GF_Registration *newDesc = (GF_Registration *) malloc(sizeof(GF_Registration)); + GF_Registration *newDesc = (GF_Registration *) gf_malloc(sizeof(GF_Registration)); if (!newDesc) return NULL; newDesc->additionalIdentificationInfo = NULL; newDesc->dataLength = 0; @@ -2795,8 +2915,8 @@ GF_Err gf_odf_del_reg(GF_Registration *reg) { if (!reg) return GF_BAD_PARAM; - if (reg->additionalIdentificationInfo) free(reg->additionalIdentificationInfo); - free(reg); + if (reg->additionalIdentificationInfo) gf_free(reg->additionalIdentificationInfo); + gf_free(reg); return GF_OK; } @@ -2807,7 +2927,7 @@ GF_Err gf_odf_read_reg(GF_BitStream *bs, GF_Registration *reg, u32 DescSize) reg->formatIdentifier = gf_bs_read_int(bs, 32); reg->dataLength = DescSize - 4; - reg->additionalIdentificationInfo = (char*)malloc(reg->dataLength); + reg->additionalIdentificationInfo = (char*)gf_malloc(reg->dataLength); if (! reg->additionalIdentificationInfo) return GF_OUT_OF_MEM; gf_bs_read_data(bs, reg->additionalIdentificationInfo, reg->dataLength); nbBytes += reg->dataLength + 4; @@ -2842,7 +2962,7 @@ GF_Err gf_odf_write_reg(GF_BitStream *bs, GF_Registration *reg) GF_Descriptor *gf_odf_new_short_text() { - GF_ShortTextual *newDesc = (GF_ShortTextual *) malloc(sizeof(GF_ShortTextual)); + GF_ShortTextual *newDesc = (GF_ShortTextual *) gf_malloc(sizeof(GF_ShortTextual)); if (!newDesc) return NULL; newDesc->eventName = NULL; @@ -2857,9 +2977,9 @@ GF_Err gf_odf_del_short_text(GF_ShortTextual *std) { if (!std) return GF_BAD_PARAM; - if (std->eventName) free(std->eventName); - if (std->eventText) free(std->eventText); - free(std); + if (std->eventName) gf_free(std->eventName); + if (std->eventText) gf_free(std->eventText); + gf_free(std); return GF_OK; } @@ -2913,12 +3033,12 @@ GF_Err gf_odf_write_short_text(GF_BitStream *bs, GF_ShortTextual *std) GF_Descriptor *gf_odf_new_smpte_camera() { - GF_SMPTECamera *newDesc = (GF_SMPTECamera *) malloc(sizeof(GF_SMPTECamera)); + GF_SMPTECamera *newDesc = (GF_SMPTECamera *) gf_malloc(sizeof(GF_SMPTECamera)); if (!newDesc) return NULL; newDesc->ParamList = gf_list_new(); if (! newDesc->ParamList) { - free(newDesc); + gf_free(newDesc); return NULL; } newDesc->cameraID = 0; @@ -2934,10 +3054,10 @@ GF_Err gf_odf_del_smpte_camera(GF_SMPTECamera *cpd) i=0; while ((tmp = (GF_SmpteParam *)gf_list_enum(cpd->ParamList, &i))) { - free(tmp); + gf_free(tmp); } gf_list_del(cpd->ParamList); - free(cpd); + gf_free(cpd); return GF_OK; } GF_Err gf_odf_read_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd, u32 DescSize) @@ -2951,7 +3071,7 @@ GF_Err gf_odf_read_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd, u32 DescS nbBytes += 2; for (i=0; i< count ; i++) { - GF_SmpteParam *tmp = (GF_SmpteParam*)malloc(sizeof(GF_SmpteParam)); + GF_SmpteParam *tmp = (GF_SmpteParam*)gf_malloc(sizeof(GF_SmpteParam)); if (! tmp) return GF_OUT_OF_MEM; tmp->paramID = gf_bs_read_int(bs, 8); tmp->param = gf_bs_read_int(bs, 32); @@ -2994,7 +3114,7 @@ GF_Err gf_odf_write_smpte_camera(GF_BitStream *bs, GF_SMPTECamera *cpd) GF_Descriptor *gf_odf_new_sup_cid() { - GF_SCIDesc *newDesc = (GF_SCIDesc *) malloc(sizeof(GF_SCIDesc)); + GF_SCIDesc *newDesc = (GF_SCIDesc *) gf_malloc(sizeof(GF_SCIDesc)); if (!newDesc) return NULL; newDesc->supplContentIdentifierTitle = NULL; newDesc->supplContentIdentifierValue =NULL; @@ -3007,9 +3127,9 @@ GF_Err gf_odf_del_sup_cid(GF_SCIDesc *scid) { if (!scid) return GF_BAD_PARAM; - if (scid->supplContentIdentifierTitle) free(scid->supplContentIdentifierTitle); - if (scid->supplContentIdentifierValue) free(scid->supplContentIdentifierValue); - free(scid); + if (scid->supplContentIdentifierTitle) gf_free(scid->supplContentIdentifierTitle); + if (scid->supplContentIdentifierValue) gf_free(scid->supplContentIdentifierValue); + gf_free(scid); return GF_OK; } @@ -3054,117 +3174,10 @@ GF_Err gf_odf_write_sup_cid(GF_BitStream *bs, GF_SCIDesc *scid) } -GF_Descriptor *gf_odf_new_muxinfo() -{ - GF_MuxInfo *newDesc = (GF_MuxInfo *) malloc(sizeof(GF_MuxInfo)); - if (!newDesc) return NULL; - memset(newDesc, 0, sizeof(GF_MuxInfo)); - newDesc->tag = GF_ODF_MUXINFO_TAG; - return (GF_Descriptor *) newDesc; -} - -GF_Err gf_odf_del_muxinfo(GF_MuxInfo *mi) -{ - if (!mi) return GF_BAD_PARAM; - if (mi->file_name) free(mi->file_name); - if (mi->streamFormat) free(mi->streamFormat); - if (mi->textNode) free(mi->textNode); - if (mi->fontNode) free(mi->fontNode); - free(mi); - return GF_OK; -} - -GF_Err gf_odf_read_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi, u32 DescSize) -{ - return GF_OK; -} -GF_Err gf_odf_size_muxinfo(GF_MuxInfo *mi, u32 *outSize) -{ - *outSize = 0; - return GF_OK; -} -GF_Err gf_odf_write_muxinfo(GF_BitStream *bs, GF_MuxInfo *mi) -{ - return GF_OK; -} - -GF_Descriptor *gf_odf_New_ElemMask() -{ - GF_ElementaryMask *newDesc = (GF_ElementaryMask*) malloc (sizeof(GF_ElementaryMask)); - if (!newDesc) return NULL; - memset(newDesc, 0, sizeof(GF_ElementaryMask)); - newDesc->tag = GF_ODF_ELEM_MASK_TAG; - return (GF_Descriptor *) newDesc; -} - -GF_Err gf_odf_del_ElemMask(GF_ElementaryMask *desc) -{ - if (desc->node_name) free(desc->node_name); - free(desc); - return GF_OK; -} - -GF_Descriptor *gf_odf_new_bifs_cfg() -{ - GF_BIFSConfig *newDesc = (GF_BIFSConfig *) malloc(sizeof(GF_BIFSConfig)); - if (!newDesc) return NULL; - memset(newDesc, 0, sizeof(GF_BIFSConfig)); - newDesc->tag = GF_ODF_BIFS_CFG_TAG; - return (GF_Descriptor *) newDesc; -} - -GF_Err gf_odf_del_bifs_cfg(GF_BIFSConfig *desc) -{ - if (desc->elementaryMasks) { - u32 i, count = gf_list_count(desc->elementaryMasks); - for (i=0; ielementaryMasks, i); - if (tmp->node_name) free(tmp->node_name); - free(tmp); - } - gf_list_del(desc->elementaryMasks); - } - free(desc); - return GF_OK; -} - -GF_Descriptor *gf_odf_new_laser_cfg() -{ - GF_LASERConfig *newDesc = (GF_LASERConfig *) malloc(sizeof(GF_LASERConfig)); - if (!newDesc) return NULL; - memset(newDesc, 0, sizeof(GF_LASERConfig)); - newDesc->tag = GF_ODF_LASER_CFG_TAG; - return (GF_Descriptor *) newDesc; -} - -GF_Err gf_odf_del_laser_cfg(GF_LASERConfig *desc) -{ - free(desc); - return GF_OK; -} - -GF_Descriptor *gf_odf_new_ui_cfg() -{ - GF_UIConfig *newDesc = (GF_UIConfig *) malloc(sizeof(GF_UIConfig)); - if (!newDesc) return NULL; - memset(newDesc, 0, sizeof(GF_UIConfig)); - newDesc->tag = GF_ODF_UI_CFG_TAG; - return (GF_Descriptor *) newDesc; -} - -GF_Err gf_odf_del_ui_cfg(GF_UIConfig *desc) -{ - if (desc->deviceName) free(desc->deviceName); - if (desc->ui_data) free(desc->ui_data); - free(desc); - return GF_OK; -} - - /*IPMPX stuff*/ GF_Descriptor *gf_odf_new_ipmp_tool_list() { - GF_IPMP_ToolList*newDesc = (GF_IPMP_ToolList*) malloc(sizeof(GF_IPMP_ToolList)); + GF_IPMP_ToolList*newDesc = (GF_IPMP_ToolList*) gf_malloc(sizeof(GF_IPMP_ToolList)); if (!newDesc) return NULL; newDesc->ipmp_tools = gf_list_new(); newDesc->tag = GF_ODF_IPMP_TL_TAG; @@ -3178,11 +3191,11 @@ GF_Err gf_odf_del_ipmp_tool_list(GF_IPMP_ToolList *ipmptl) while (gf_list_count(ipmptl->ipmp_tools)) { GF_IPMP_Tool *t = (GF_IPMP_Tool *) gf_list_get(ipmptl->ipmp_tools, 0); gf_list_rem(ipmptl->ipmp_tools, 0); - if (t->tool_url) free(t->tool_url); - free(t); + if (t->tool_url) gf_free(t->tool_url); + gf_free(t); } gf_list_del(ipmptl->ipmp_tools); - free(ipmptl); + gf_free(ipmptl); return GF_OK; } @@ -3229,7 +3242,7 @@ GF_Err gf_odf_write_ipmp_tool_list(GF_BitStream *bs, GF_IPMP_ToolList *ipmptl) GF_Descriptor *gf_odf_new_ipmp_tool() { - GF_IPMP_Tool *newDesc = (GF_IPMP_Tool*) malloc(sizeof(GF_IPMP_Tool)); + GF_IPMP_Tool *newDesc = (GF_IPMP_Tool*) gf_malloc(sizeof(GF_IPMP_Tool)); if (!newDesc) return NULL; memset(newDesc, 0, sizeof(GF_IPMP_Tool)); newDesc->tag = GF_ODF_IPMP_TL_TAG; @@ -3239,8 +3252,8 @@ GF_Descriptor *gf_odf_new_ipmp_tool() GF_Err gf_odf_del_ipmp_tool(GF_IPMP_Tool *ipmpt) { if (!ipmpt) return GF_BAD_PARAM; - if (ipmpt->tool_url) free(ipmpt->tool_url); - free(ipmpt); + if (ipmpt->tool_url) gf_free(ipmpt->tool_url); + gf_free(ipmpt); return GF_OK; } @@ -3273,7 +3286,7 @@ GF_Err gf_odf_read_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt, u32 DescSize u32 s; nbBytes += gf_ipmpx_array_size(bs, &s); if (s) { - ipmpt->tool_url = (char*)malloc(sizeof(char)*(s+1)); + ipmpt->tool_url = (char*)gf_malloc(sizeof(char)*(s+1)); gf_bs_read_data(bs, ipmpt->tool_url, s); ipmpt->tool_url[s] = 0; nbBytes += s; @@ -3321,3 +3334,5 @@ GF_Err gf_odf_write_ipmp_tool(GF_BitStream *bs, GF_IPMP_Tool *ipmpt) if (ipmpt->tool_url) gf_ipmpx_write_array(bs, ipmpt->tool_url, strlen(ipmpt->tool_url)); return GF_OK; } + +#endif /*GPAC_MINIMAL_ODF*/ diff --git a/src/odf/odf_codec.c b/src/odf/odf_codec.c index fc4ff9f..e9d2dba 100644 --- a/src/odf/odf_codec.c +++ b/src/odf/odf_codec.c @@ -37,7 +37,7 @@ GF_ODCodec *gf_odf_codec_new() comList = gf_list_new(); if (!comList) return NULL; - codec = (GF_ODCodec *) malloc(sizeof(GF_ODCodec)); + codec = (GF_ODCodec *) gf_malloc(sizeof(GF_ODCodec)); if (!codec) { gf_list_del(comList); return NULL; @@ -60,7 +60,7 @@ void gf_odf_codec_del(GF_ODCodec *codec) } gf_list_del(codec->CommandList); if (codec->bs) gf_bs_del(codec->bs); - free(codec); + gf_free(codec); } @@ -76,7 +76,7 @@ GF_Err gf_odf_codec_add_com(GF_ODCodec *codec, GF_ODCom *command) } GF_EXPORT -GF_Err gf_odf_codec_encode(GF_ODCodec *codec, Bool delete_content) +GF_Err gf_odf_codec_encode(GF_ODCodec *codec, u32 cleanup_type) { GF_ODCom *com; GF_Err e = GF_OK; @@ -104,13 +104,16 @@ err_exit: gf_bs_del(codec->bs); codec->bs = NULL; } - if (delete_content) { + if (cleanup_type==1) { while (gf_list_count(codec->CommandList)) { com = (GF_ODCom *)gf_list_get(codec->CommandList, 0); gf_odf_delete_command(com); gf_list_rem(codec->CommandList, 0); } } + if (cleanup_type==0) { + gf_list_reset(codec->CommandList); + } return e; } @@ -226,7 +229,6 @@ GF_Err gf_odf_com_del(GF_ODCom **com) } - /************************************************************ Object Descriptors Functions ************************************************************/ @@ -248,6 +250,38 @@ void gf_odf_desc_del(GF_Descriptor *desc) if (desc) gf_odf_delete_descriptor(desc); } +//this functions will destroy the descriptors in a list but not the list +GF_EXPORT +GF_Err gf_odf_desc_list_del(GF_List *descList) +{ + GF_Err e; + GF_Descriptor *tmp; + + if (! descList) return GF_BAD_PARAM; + + while (gf_list_count(descList)) { + tmp = (GF_Descriptor*)gf_list_get(descList, 0); + gf_list_rem(descList, 0); + e = gf_odf_delete_descriptor(tmp); + if (e) return e; + } + return GF_OK; +} + + + +GF_EXPORT +GF_ESD *gf_odf_desc_esd_new(u32 sl_predefined) +{ + GF_ESD *esd; + esd = (GF_ESD *) gf_odf_desc_new(GF_ODF_ESD_TAG); + esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); + esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); + esd->slConfig = (GF_SLConfig *) gf_odf_new_slc((u8) sl_predefined); + return esd; +} + + //use this function to decode a standalone descriptor //the desc MUST be formatted with tag and size field!!! GF_EXPORT @@ -334,11 +368,10 @@ GF_Err gf_odf_desc_copy(GF_Descriptor *inDesc, GF_Descriptor **outDesc) e = gf_odf_desc_write(inDesc, &desc, &size); if (e) return e; e = gf_odf_desc_read(desc, size, outDesc); - free(desc); + gf_free(desc); return e; } - /************************************************************ Object Descriptors Edit Functions ************************************************************/ @@ -388,8 +421,6 @@ GF_Err gf_odf_desc_add_desc(GF_Descriptor *parentDesc, GF_Descriptor *newDesc) return gf_list_add(((GF_TextConfig *)parentDesc)->sample_descriptions, newDesc); case GF_ODF_QOS_TAG: - //tricky: the QoS doesnot accept a descriptor but a qualifier. - //We have another function for that... return GF_BAD_PARAM; //MP4 File Format tags @@ -416,52 +447,6 @@ GF_Err gf_odf_desc_add_desc(GF_Descriptor *parentDesc, GF_Descriptor *newDesc) -/************************************************************ - QoSQualifiers Functions -************************************************************/ - -GF_EXPORT -GF_QoS_Default *gf_odf_qos_new(u8 tag) -{ - - GF_QoS_Default *NewQoS(u8 tag); - - GF_QoS_Default *qos; - - qos = NewQoS(tag); - return qos; -} - -GF_EXPORT -GF_Err gf_odf_qos_del(GF_QoS_Default **qos) -{ - if (*qos) gf_odf_delete_qos_qual(*qos); - *qos = NULL; - return GF_OK; -} - - -//same function, but for QoS, as a Qualifier IS NOT a descriptor -GF_EXPORT -GF_Err gf_odf_qos_add_qualif(GF_QoS_Descriptor *desc, GF_QoS_Default *qualif) -{ - u32 i; - GF_QoS_Default *def; - - if (desc->tag != GF_ODF_QOS_TAG) return GF_BAD_PARAM; - if (desc->predefined) return GF_ODF_FORBIDDEN_DESCRIPTOR; - - i=0; - while ((def = (GF_QoS_Default *)gf_list_enum(desc->QoS_Qualifiers, &i))) { - //if same Qualifier, not allowed... - if (def->tag == qualif->tag) return GF_ODF_FORBIDDEN_DESCRIPTOR; - } - return gf_list_add(desc->QoS_Qualifiers, qualif); -} - - - - /***************************************************************************************** Since IPMP V2, we introduce a new set of functions to read / write a list of descriptors that have no containers (a bit like an OD command, but for descriptors) @@ -530,36 +515,6 @@ GF_Err gf_odf_desc_list_size(GF_List *descList, u32 *outSize) return gf_odf_size_descriptor_list(descList, outSize); } -//this functions will destroy the descriptors in a list but not the list -GF_EXPORT -GF_Err gf_odf_desc_list_del(GF_List *descList) -{ - GF_Err e; - GF_Descriptor *tmp; - - if (! descList) return GF_BAD_PARAM; - - while (gf_list_count(descList)) { - tmp = (GF_Descriptor*)gf_list_get(descList, 0); - gf_list_rem(descList, 0); - e = gf_odf_delete_descriptor(tmp); - if (e) return e; - } - return GF_OK; -} - - - -GF_EXPORT -GF_ESD *gf_odf_desc_esd_new(u32 sl_predefined) -{ - GF_ESD *esd; - esd = (GF_ESD *) gf_odf_desc_new(GF_ODF_ESD_TAG); - esd->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); - esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - esd->slConfig = (GF_SLConfig *) gf_odf_new_slc((u8) sl_predefined); - return esd; -} GF_Err gf_odf_codec_apply_com(GF_ODCodec *codec, GF_ODCom *command) @@ -650,4 +605,3 @@ GF_Err gf_odf_codec_apply_com(GF_ODCodec *codec, GF_ODCom *command) } return GF_NOT_SUPPORTED; } - diff --git a/src/odf/odf_command.c b/src/odf/odf_command.c index e6d7cb5..2b62167 100644 --- a/src/odf/odf_command.c +++ b/src/odf/odf_command.c @@ -25,6 +25,7 @@ #include + GF_Err gf_odf_parse_command(GF_BitStream *bs, GF_ODCom **com, u32 *com_size) { u32 val, size, sizeHeader; @@ -73,7 +74,7 @@ GF_Err gf_odf_parse_command(GF_BitStream *bs, GF_ODCom **com, u32 *com_size) GF_ODCom *gf_odf_new_base_command() { - GF_BaseODCom *newCom = (GF_BaseODCom *) malloc(sizeof(GF_BaseODCom)); + GF_BaseODCom *newCom = (GF_BaseODCom *) gf_malloc(sizeof(GF_BaseODCom)); if (!newCom) return NULL; newCom->dataSize = 0; newCom->data = NULL; @@ -82,8 +83,8 @@ GF_ODCom *gf_odf_new_base_command() GF_Err gf_odf_del_base_command(GF_BaseODCom *bcRemove) { if (! bcRemove) return GF_BAD_PARAM; - if (bcRemove->data) free(bcRemove->data); - free(bcRemove); + if (bcRemove->data) gf_free(bcRemove->data); + gf_free(bcRemove); return GF_OK; } @@ -92,7 +93,7 @@ GF_Err gf_odf_read_base_command(GF_BitStream *bs, GF_BaseODCom *bcRem, u32 gf_od if (! bcRem) return GF_BAD_PARAM; bcRem->dataSize = gf_odf_size_command; - bcRem->data = (char *) malloc(sizeof(char) * bcRem->dataSize); + bcRem->data = (char *) gf_malloc(sizeof(char) * bcRem->dataSize); if (! bcRem->data) return GF_OUT_OF_MEM; gf_bs_read_data(bs, bcRem->data, bcRem->dataSize); return GF_OK; @@ -119,7 +120,7 @@ GF_Err gf_odf_write_base_command(GF_BitStream *bs, GF_BaseODCom *bcRem) GF_ODCom *gf_odf_new_od_remove() { - GF_ODRemove *newCom = (GF_ODRemove *) malloc(sizeof(GF_ODRemove)); + GF_ODRemove *newCom = (GF_ODRemove *) gf_malloc(sizeof(GF_ODRemove)); if (!newCom) return NULL; newCom->NbODs = 0; newCom->OD_ID = NULL; @@ -129,8 +130,8 @@ GF_ODCom *gf_odf_new_od_remove() GF_Err gf_odf_del_od_remove(GF_ODRemove *ODRemove) { if (! ODRemove) return GF_BAD_PARAM; - if (ODRemove->OD_ID) free(ODRemove->OD_ID); - free(ODRemove); + if (ODRemove->OD_ID) gf_free(ODRemove->OD_ID); + gf_free(ODRemove); return GF_OK; } GF_Err gf_odf_read_od_remove(GF_BitStream *bs, GF_ODRemove *odRem, u32 gf_odf_size_command) @@ -139,7 +140,7 @@ GF_Err gf_odf_read_od_remove(GF_BitStream *bs, GF_ODRemove *odRem, u32 gf_odf_si if (! odRem) return GF_BAD_PARAM; odRem->NbODs = (u32 ) (gf_odf_size_command * 8) / 10; - odRem->OD_ID = (u16 *) malloc(sizeof(u16) * odRem->NbODs); + odRem->OD_ID = (u16 *) gf_malloc(sizeof(u16) * odRem->NbODs); if (! odRem->OD_ID) return GF_OUT_OF_MEM; for (i = 0; i < odRem->NbODs ; i++) { @@ -185,12 +186,12 @@ GF_Err gf_odf_write_od_remove(GF_BitStream *bs, GF_ODRemove *odRem) GF_ODCom *gf_odf_new_od_update() { - GF_ODUpdate *newCom = (GF_ODUpdate *) malloc(sizeof(GF_ODUpdate)); + GF_ODUpdate *newCom = (GF_ODUpdate *) gf_malloc(sizeof(GF_ODUpdate)); if (!newCom) return NULL; newCom->objectDescriptors = gf_list_new(); if (! newCom->objectDescriptors) { - free(newCom); + gf_free(newCom); return NULL; } newCom->tag = GF_ODF_OD_UPDATE_TAG; @@ -209,7 +210,7 @@ GF_Err gf_odf_del_od_update(GF_ODUpdate *ODUpdate) if (e) return e; } gf_list_del(ODUpdate->objectDescriptors); - free(ODUpdate); + gf_free(ODUpdate); return GF_OK; } @@ -291,12 +292,12 @@ GF_Err gf_odf_write_od_update(GF_BitStream *bs, GF_ODUpdate *odUp) GF_ODCom *gf_odf_new_esd_update() { - GF_ESDUpdate *newCom = (GF_ESDUpdate *) malloc(sizeof(GF_ESDUpdate)); + GF_ESDUpdate *newCom = (GF_ESDUpdate *) gf_malloc(sizeof(GF_ESDUpdate)); if (!newCom) return NULL; newCom->ESDescriptors = gf_list_new(); if (! newCom->ESDescriptors) { - free(newCom); + gf_free(newCom); return NULL; } newCom->tag = GF_ODF_ESD_UPDATE_TAG; @@ -315,7 +316,7 @@ GF_Err gf_odf_del_esd_update(GF_ESDUpdate *ESDUpdate) if (e) return e; } gf_list_del(ESDUpdate->ESDescriptors); - free(ESDUpdate); + gf_free(ESDUpdate); return GF_OK; } @@ -411,7 +412,7 @@ GF_Err gf_odf_write_esd_update(GF_BitStream *bs, GF_ESDUpdate *esdUp) GF_ODCom *gf_odf_new_esd_remove() { - GF_ESDRemove *newCom = (GF_ESDRemove *) malloc(sizeof(GF_ESDRemove)); + GF_ESDRemove *newCom = (GF_ESDRemove *) gf_malloc(sizeof(GF_ESDRemove)); if (!newCom) return NULL; newCom->NbESDs = 0; newCom->ES_ID = NULL; @@ -422,8 +423,8 @@ GF_ODCom *gf_odf_new_esd_remove() GF_Err gf_odf_del_esd_remove(GF_ESDRemove *ESDRemove) { if (! ESDRemove) return GF_BAD_PARAM; - if (ESDRemove->ES_ID) free(ESDRemove->ES_ID); - free(ESDRemove); + if (ESDRemove->ES_ID) gf_free(ESDRemove->ES_ID); + gf_free(ESDRemove); return GF_OK; } @@ -445,7 +446,7 @@ GF_Err gf_odf_read_esd_remove(GF_BitStream *bs, GF_ESDRemove *esdRem, u32 gf_odf return GF_OK; } esdRem->NbESDs = (gf_odf_size_command - 2) / 2; - esdRem->ES_ID = (u16 *) malloc(sizeof(u16) * esdRem->NbESDs); + esdRem->ES_ID = (u16 *) gf_malloc(sizeof(u16) * esdRem->NbESDs); if (! esdRem->ES_ID) return GF_OUT_OF_MEM; for (i = 0; i < esdRem->NbESDs ; i++) { esdRem->ES_ID[i] = gf_bs_read_int(bs, 16); @@ -485,7 +486,7 @@ GF_Err gf_odf_write_esd_remove(GF_BitStream *bs, GF_ESDRemove *esdRem) GF_ODCom *gf_odf_new_ipmp_remove() { - GF_IPMPRemove *newCom = (GF_IPMPRemove *) malloc(sizeof(GF_IPMPRemove)); + GF_IPMPRemove *newCom = (GF_IPMPRemove *) gf_malloc(sizeof(GF_IPMPRemove)); if (!newCom) return NULL; newCom->IPMPDescID =NULL; newCom->NbIPMPDs = 0; @@ -496,8 +497,8 @@ GF_ODCom *gf_odf_new_ipmp_remove() GF_Err gf_odf_del_ipmp_remove(GF_IPMPRemove *IPMPDRemove) { if (! IPMPDRemove) return GF_BAD_PARAM; - if (IPMPDRemove->IPMPDescID) free(IPMPDRemove->IPMPDescID); - free(IPMPDRemove); + if (IPMPDRemove->IPMPDescID) gf_free(IPMPDRemove->IPMPDescID); + gf_free(IPMPDRemove); return GF_OK; } @@ -511,7 +512,7 @@ GF_Err gf_odf_read_ipmp_remove(GF_BitStream *bs, GF_IPMPRemove *ipmpRem, u32 gf_ if (!gf_odf_size_command) return GF_OK; ipmpRem->NbIPMPDs = gf_odf_size_command; - ipmpRem->IPMPDescID = (u8 *) malloc(sizeof(u8) * ipmpRem->NbIPMPDs); + ipmpRem->IPMPDescID = (u8 *) gf_malloc(sizeof(u8) * ipmpRem->NbIPMPDs); if (! ipmpRem->IPMPDescID) return GF_OUT_OF_MEM; for (i = 0; i < ipmpRem->NbIPMPDs; i++) { @@ -550,11 +551,11 @@ GF_Err gf_odf_write_ipmp_remove(GF_BitStream *bs, GF_IPMPRemove *ipmpRem) GF_ODCom *gf_odf_new_ipmp_update() { - GF_IPMPUpdate *newCom = (GF_IPMPUpdate *) malloc(sizeof(GF_IPMPUpdate)); + GF_IPMPUpdate *newCom = (GF_IPMPUpdate *) gf_malloc(sizeof(GF_IPMPUpdate)); if (!newCom) return NULL; newCom->IPMPDescList = gf_list_new(); if (! newCom->IPMPDescList) { - free(newCom); + gf_free(newCom); return NULL; } newCom->tag = GF_ODF_IPMP_UPDATE_TAG; @@ -571,7 +572,7 @@ GF_Err gf_odf_del_ipmp_update(GF_IPMPUpdate *IPMPDUpdate) e = gf_list_rem(IPMPDUpdate->IPMPDescList, 0); } gf_list_del(IPMPDUpdate->IPMPDescList); - free(IPMPDUpdate); + gf_free(IPMPDUpdate); return GF_OK; } diff --git a/src/odf/odf_dump.c b/src/odf/odf_dump.c index e64cb48..37bdda9 100644 --- a/src/odf/odf_dump.c +++ b/src/odf/odf_dump.c @@ -27,6 +27,8 @@ /*for import flags*/ #include +#ifndef GPAC_DISABLE_OD_DUMP + #define OD_MAX_TREE 100 #define OD_FORMAT_INDENT( ind_buf, indent ) \ @@ -328,9 +330,9 @@ static void DumpString(FILE *trace, const char *attName, char *val, u32 indent, EndAttribute(trace, indent, XMTDump); } -static void DumpData(FILE *trace, const char *name, char *data, u32 dataLength, u32 indent, Bool XMTDump) +static void DumpData(FILE *trace, const char *name, char *data, u64 dataLength, u32 indent, Bool XMTDump) { - u32 i; + u64 i; if (!name ||!data) return; StartAttribute(trace, name, indent, XMTDump); if (XMTDump) fprintf(trace, "data:application/octet-string,"); @@ -861,7 +863,8 @@ GF_Err gf_odf_dump_ui_cfg(GF_UIConfig *uid, FILE *trace, u32 indent, Bool XMTDum GF_Err DumpRawUIConfig(GF_DefaultDescriptor *dsi, FILE *trace, u32 indent, Bool XMTDump, u32 oti) { char devName[255]; - u32 i, len; + u32 i; + u64 len; GF_BitStream *bs; bs = gf_bs_new(dsi->data, dsi->dataLength, GF_BITSTREAM_READ); @@ -880,7 +883,7 @@ GF_Err DumpRawUIConfig(GF_DefaultDescriptor *dsi, FILE *trace, u32 indent, Bool devName[0] = gf_bs_read_int(bs, 8); DumpString(trace, "delChar", devName, indent, XMTDump); } - len = (u32) gf_bs_available(bs); + len = gf_bs_available(bs); if (len) { if (!stricmp(devName, "HTKSensor")) { u32 nb_word, nbPhone, c, j; @@ -906,7 +909,7 @@ GF_Err DumpRawUIConfig(GF_DefaultDescriptor *dsi, FILE *trace, u32 indent, Bool EndAttribute(trace, indent, XMTDump); } else { char *data = dsi->data; - data += (u32) gf_bs_get_position(bs); + data += gf_bs_get_position(bs); DumpData(trace, "uiData", data, len, indent, XMTDump); } } @@ -1698,10 +1701,12 @@ GF_Err gf_odf_dump_muxinfo(GF_MuxInfo *mi, FILE *trace, u32 indent, Bool XMTDump if (mi->GroupID) DumpInt(trace, "GroupID", mi->GroupID, indent, 1); if (mi->startTime) DumpInt(trace, "startTime", mi->startTime, indent, 1); if (mi->duration) DumpInt(trace, "duration", mi->duration, indent, 1); +#ifndef GPAC_DISABLE_MEDIA_IMPORT if (mi->import_flags & GF_IMPORT_USE_DATAREF) DumpBool(trace, "useDataReference", 1, indent, 1); if (mi->import_flags & GF_IMPORT_NO_FRAME_DROP) DumpBool(trace, "noFrameDrop", 1, indent, 1); if (mi->import_flags & GF_IMPORT_SBR_IMPLICIT) DumpString(trace, "SBR_Type", "implicit", indent, 1); else if (mi->import_flags & GF_IMPORT_SBR_EXPLICIT) DumpString(trace, "SBR_Type", "explicit", indent, 1); +#endif /*GPAC_DISABLE_MEDIA_IMPORT*/ if (mi->textNode) DumpString(trace, "textNode", mi->textNode, indent, 1); if (mi->fontNode) DumpString(trace, "fontNode", mi->fontNode, indent, 1); @@ -1938,3 +1943,5 @@ GF_Err gf_oci_dump_au(u8 version, char *au, u32 au_length, FILE *trace, u32 inde gf_oci_codec_del(codec); return e; } + +#endif /*GPAC_DISABLE_OD_DUMP*/ diff --git a/src/odf/odf_parse.c b/src/odf/odf_parse.c index bbc1099..fe1c357 100644 --- a/src/odf/odf_parse.c +++ b/src/odf/odf_parse.c @@ -29,6 +29,9 @@ /*for import flags*/ #include + +#if !defined(GPAC_DISABLE_LOADER_BT) && !defined(GPAC_DISABLE_LOADER_XMT) + /* to complete...*/ u32 gf_odf_get_field_type(GF_Descriptor *desc, char *fieldName) @@ -88,6 +91,21 @@ u32 gf_odf_get_tag_by_name(char *descName) if (!stricmp(descName, "DecoderSpecificInfo")) return GF_ODF_DSI_TAG; if (!stricmp(descName, "DecoderSpecificInfoString")) return GF_ODF_DSI_TAG; if (!stricmp(descName, "SLConfigDescriptor")) return GF_ODF_SLC_TAG; + if (!stricmp(descName, "SegmentDescriptor")) return GF_ODF_SEGMENT_TAG; + if (!stricmp(descName, "MediaTimeDescriptor")) return GF_ODF_MEDIATIME_TAG; + if (!stricmp(descName, "MuxInfo")) return GF_ODF_MUXINFO_TAG; + if (!stricmp(descName, "StreamSource")) return GF_ODF_MUXINFO_TAG; + if (!stricmp(descName, "BIFSConfig") || !stricmp(descName, "BIFSv2Config")) return GF_ODF_BIFS_CFG_TAG; + if (!stricmp(descName, "ElementaryMask")) return GF_ODF_ELEM_MASK_TAG; + if (!stricmp(descName, "TextConfig")) return GF_ODF_TEXT_CFG_TAG; + if (!stricmp(descName, "TextSampleDescriptor")) return GF_ODF_TX3G_TAG; + if (!stricmp(descName, "UIConfig")) return GF_ODF_UI_CFG_TAG; + if (!stricmp(descName, "ES_ID_Ref")) return GF_ODF_ESD_REF_TAG; + if (!stricmp(descName, "ES_ID_Inc")) return GF_ODF_ESD_INC_TAG; + if (!stricmp(descName, "AuxiliaryVideoData")) return GF_ODF_AUX_VIDEO_DATA; + if (!stricmp(descName, "DefaultDescriptor")) return GF_ODF_DSI_TAG; + +#ifndef GPAC_MINIMAL_ODF if (!stricmp(descName, "ContentIdentification")) return GF_ODF_CI_TAG; if (!stricmp(descName, "SuppContentIdentification")) return GF_ODF_SCI_TAG; if (!stricmp(descName, "IPIPtr")) return GF_ODF_IPI_PTR_TAG; @@ -110,19 +128,7 @@ u32 gf_odf_get_tag_by_name(char *descName) if (!stricmp(descName, "OCI_CreatorName")) return GF_ODF_OCI_NAME_TAG; if (!stricmp(descName, "OCI_CreationDate")) return GF_ODF_OCI_DATE_TAG; if (!stricmp(descName, "SmpteCameraPosition")) return GF_ODF_SMPTE_TAG; - if (!stricmp(descName, "SegmentDescriptor")) return GF_ODF_SEGMENT_TAG; - if (!stricmp(descName, "MediaTimeDescriptor")) return GF_ODF_MEDIATIME_TAG; - if (!stricmp(descName, "MuxInfo")) return GF_ODF_MUXINFO_TAG; - if (!stricmp(descName, "StreamSource")) return GF_ODF_MUXINFO_TAG; - if (!stricmp(descName, "BIFSConfig") || !stricmp(descName, "BIFSv2Config")) return GF_ODF_BIFS_CFG_TAG; - if (!stricmp(descName, "ElementaryMask")) return GF_ODF_ELEM_MASK_TAG; - if (!stricmp(descName, "TextConfig")) return GF_ODF_TEXT_CFG_TAG; - if (!stricmp(descName, "TextSampleDescriptor")) return GF_ODF_TX3G_TAG; - if (!stricmp(descName, "UIConfig")) return GF_ODF_UI_CFG_TAG; - if (!stricmp(descName, "ES_ID_Ref")) return GF_ODF_ESD_REF_TAG; - if (!stricmp(descName, "ES_ID_Inc")) return GF_ODF_ESD_INC_TAG; - if (!stricmp(descName, "AuxiliaryVideoData")) return GF_ODF_AUX_VIDEO_DATA; - if (!stricmp(descName, "DefaultDescriptor")) return GF_ODF_DSI_TAG; +#endif /*GPAC_MINIMAL_ODF*/ return 0; } @@ -133,16 +139,16 @@ u32 gf_odf_get_tag_by_name(char *descName) #define GET_BOOL(field) { ret = 1; field = (!stricmp(val, "true") || !stricmp(val, "1")) ? 1 : 0; } #define GET_DOUBLE(field) { Float v; ret = 1; sscanf(val, "%f", &v); field = (Double) v;} -#define GET_STRING(field) { ret = 1; field = strdup(val); if (val[0] == '"') strcpy(field, val+1); if (field[strlen(field)-1] == '"') field[strlen(field)-1] = 0; } +#define GET_STRING(field) { ret = 1; field = gf_strdup(val); if (val[0] == '"') strcpy(field, val+1); if (field[strlen(field)-1] == '"') field[strlen(field)-1] = 0; } void OD_ParseBinData(char *val, char **out_data, u32 *out_data_size) { u32 i, c; char s[3]; u32 len = strlen(val) / 3; - if (*out_data) free(*out_data); + if (*out_data) gf_free(*out_data); *out_data_size = len; - *out_data = (char*)malloc(sizeof(char) * len); + *out_data = (char*)gf_malloc(sizeof(char) * len); s[2] = 0; for (i=0; iobjectDescriptorID); else if (!stricmp(fieldName, "URLString")) { - iod->URLString = strdup(val); + iod->URLString = gf_strdup(val); ret = 1; } else if (!stricmp(fieldName, "includeInlineProfileLevelFlag")) { @@ -248,7 +259,7 @@ GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val) GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) desc; if (!stricmp(fieldName, "objectDescriptorID") || !stricmp(fieldName, "binaryID")) ret += sscanf(val, "%hd", &od->objectDescriptorID); else if (!stricmp(fieldName, "URLString")) { - od->URLString = strdup(val); + od->URLString = gf_strdup(val); ret = 1; } } @@ -262,22 +273,22 @@ GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val) if (!ret) { if (!stricmp(val, "MPEG4Systems1")) { dcd->objectTypeIndication = 0x01; ret = 1; } else if (!stricmp(val, "MPEG4Systems2")) { dcd->objectTypeIndication = 0x02; ret = 1; } - else if (!stricmp(val, "MPEG4Visual")) { dcd->objectTypeIndication = 0x20; ret = 1; } - else if (!stricmp(val, "MPEG4Audio")) { dcd->objectTypeIndication = 0x40; ret = 1; } - else if (!stricmp(val, "MPEG2VisualSimple")) { dcd->objectTypeIndication = 0x60; ret = 1; } - else if (!stricmp(val, "MPEG2VisualMain")) { dcd->objectTypeIndication = 0x61; ret = 1; } - else if (!stricmp(val, "MPEG2VisualSNR")) { dcd->objectTypeIndication = 0x62; ret = 1; } - else if (!stricmp(val, "MPEG2VisualSpatial")) { dcd->objectTypeIndication = 0x63; ret = 1; } - else if (!stricmp(val, "MPEG2VisualHigh")) { dcd->objectTypeIndication = 0x64; ret = 1; } - else if (!stricmp(val, "MPEG2Visual422")) { dcd->objectTypeIndication = 0x65; ret = 1; } - else if (!stricmp(val, "MPEG2AudioMain")) { dcd->objectTypeIndication = 0x66; ret = 1; } - else if (!stricmp(val, "MPEG2AudioLowComplexity")) { dcd->objectTypeIndication = 0x67; ret = 1; } - else if (!stricmp(val, "MPEG2AudioScaleableSamplingRate")) { dcd->objectTypeIndication = 0x68; ret = 1; } - else if (!stricmp(val, "MPEG2AudioPart3")) { dcd->objectTypeIndication = 0x69; ret = 1; } - else if (!stricmp(val, "MPEG1Visual")) { dcd->objectTypeIndication = 0x6A; ret = 1; } - else if (!stricmp(val, "MPEG1Audio")) { dcd->objectTypeIndication = 0x6B; ret = 1; } - else if (!stricmp(val, "JPEG")) { dcd->objectTypeIndication = 0x6C; ret = 1; } - else if (!stricmp(val, "PNG")) { dcd->objectTypeIndication = 0x6D; ret = 1; } + else if (!stricmp(val, "MPEG4Visual")) { dcd->objectTypeIndication = GPAC_OTI_VIDEO_MPEG4_PART2; ret = 1; } + else if (!stricmp(val, "MPEG4Audio")) { dcd->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG4; ret = 1; } + else if (!stricmp(val, "MPEG2VisualSimple")) { dcd->objectTypeIndication = GPAC_OTI_VIDEO_MPEG2_SIMPLE; ret = 1; } + else if (!stricmp(val, "MPEG2VisualMain")) { dcd->objectTypeIndication = GPAC_OTI_VIDEO_MPEG2_MAIN; ret = 1; } + else if (!stricmp(val, "MPEG2VisualSNR")) { dcd->objectTypeIndication = GPAC_OTI_VIDEO_MPEG2_SNR; ret = 1; } + else if (!stricmp(val, "MPEG2VisualSpatial")) { dcd->objectTypeIndication = GPAC_OTI_VIDEO_MPEG2_SPATIAL; ret = 1; } + else if (!stricmp(val, "MPEG2VisualHigh")) { dcd->objectTypeIndication = GPAC_OTI_VIDEO_MPEG2_HIGH; ret = 1; } + else if (!stricmp(val, "MPEG2Visual422")) { dcd->objectTypeIndication = GPAC_OTI_VIDEO_MPEG2_422; ret = 1; } + else if (!stricmp(val, "MPEG2AudioMain")) { dcd->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG2_MP; ret = 1; } + else if (!stricmp(val, "MPEG2AudioLowComplexity")) { dcd->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG2_LCP; ret = 1; } + else if (!stricmp(val, "MPEG2AudioScaleableSamplingRate")) { dcd->objectTypeIndication = GPAC_OTI_AUDIO_AAC_MPEG2_SSRP; ret = 1; } + else if (!stricmp(val, "MPEG2AudioPart3")) { dcd->objectTypeIndication = GPAC_OTI_AUDIO_MPEG2_PART3; ret = 1; } + else if (!stricmp(val, "MPEG1Visual")) { dcd->objectTypeIndication = GPAC_OTI_VIDEO_MPEG1; ret = 1; } + else if (!stricmp(val, "MPEG1Audio")) { dcd->objectTypeIndication = GPAC_OTI_AUDIO_MPEG1; ret = 1; } + else if (!stricmp(val, "JPEG")) { dcd->objectTypeIndication = GPAC_OTI_IMAGE_JPEG; ret = 1; } + else if (!stricmp(val, "PNG")) { dcd->objectTypeIndication = GPAC_OTI_IMAGE_PNG; ret = 1; } } } else if (!stricmp(fieldName, "streamType")) { @@ -311,7 +322,7 @@ GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val) else if (!stricmp(fieldName, "dependsOn_ES_ID") || !stricmp(fieldName, "dependsOnESID")) ret += sscanf(val, "%hd", &esd->dependsOnESID); else if (!stricmp(fieldName, "OCR_ES_ID")) ret += sscanf(val, "%hd", &esd->OCRESID); else if (!stricmp(fieldName, "URLstring")) { - esd->URLString = strdup(val); + esd->URLString = gf_strdup(val); ret = 1; } /*ignore*/ @@ -362,7 +373,7 @@ GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val) GF_ElementaryMask* em = (GF_ElementaryMask*)desc; if (!stricmp(fieldName, "atNode")) { GET_U32(em->node_id); - if (!ret || !em->node_id) em->node_name = strdup(val); + if (!ret || !em->node_id) em->node_name = gf_strdup(val); ret = 1; } else if (!stricmp(fieldName, "numDynFields")) ret = 1; @@ -395,6 +406,13 @@ GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val) else if (!stricmp(fieldName, "GroupID")) ret += sscanf(val, "%d", &mi->GroupID); else if (!stricmp(fieldName, "startTime")) ret += sscanf(val, "%d", &mi->startTime); else if (!stricmp(fieldName, "duration")) ret += sscanf(val, "%d", &mi->duration); + else if (!stricmp(fieldName, "carouselPeriod")) { + ret += sscanf(val, "%d", &mi->carousel_period_plus_one); + mi->carousel_period_plus_one += 1; + } + else if (!stricmp(fieldName, "aggregateOnESID")) ret += sscanf(val, "%hd", &mi->aggregate_on_esid); + +#ifndef GPAC_DISABLE_MEDIA_IMPORT else if (!stricmp(fieldName, "compactSize")) { ret = 1; if (!stricmp(val, "true") || !stricmp(val, "1")) mi->import_flags |= GF_IMPORT_USE_COMPACT_SIZE; } else if (!stricmp(fieldName, "useDataReference")) @@ -406,6 +424,7 @@ GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val) if (!stricmp(val, "implicit") || !stricmp(val, "1")) mi->import_flags |= GF_IMPORT_SBR_IMPLICIT; else if (!stricmp(val, "explicit") || !stricmp(val, "2")) mi->import_flags |= GF_IMPORT_SBR_EXPLICIT; } +#endif /*GPAC_DISABLE_MEDIA_IMPORT*/ else if (!stricmp(fieldName, "textNode")) GET_STRING(mi->textNode) else if (!stricmp(fieldName, "fontNode")) GET_STRING(mi->fontNode) @@ -534,7 +553,7 @@ GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val) else if (!stricmp(fieldName, "fontID") || !stricmp(fieldName, "fontName")) { /*check if we need a new entry*/ if (!sd->font_count) { - sd->fonts = (GF_FontRecord*)malloc(sizeof(GF_FontRecord)); + sd->fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord)); sd->font_count = 1; sd->fonts[0].fontID = 0; sd->fonts[0].fontName = NULL; @@ -544,7 +563,7 @@ GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val) else if (!stricmp(fieldName, "fontName") && sd->fonts[sd->font_count-1].fontName) realloc_fonts = 1; if (realloc_fonts) { sd->font_count += 1; - sd->fonts = (GF_FontRecord*)realloc(sd->fonts, sizeof(GF_FontRecord)*sd->font_count); + sd->fonts = (GF_FontRecord*)gf_realloc(sd->fonts, sizeof(GF_FontRecord)*sd->font_count); sd->fonts[sd->font_count-1].fontID = 0; sd->fonts[sd->font_count-1].fontName = NULL; } @@ -620,7 +639,7 @@ Bool OD_ParseUIConfig(char *val, char **out_data, u32 *out_data_size) GF_BitStream *bs; if (!strnicmp(val, "HTK:", 4)) { char szItem[100]; - s32 pos, bs_start, bs_cur; + s64 pos, bs_start, bs_cur; Bool has_word; u32 nb_phonems, nbWords = 0; bs_start = 0; @@ -638,7 +657,7 @@ Bool OD_ParseUIConfig(char *val, char **out_data, u32 *out_data_size) has_word = 1; nbWords++; nb_phonems = 0; - bs_start = (u32) gf_bs_get_position(bs); + bs_start = gf_bs_get_position(bs); /*nb phonems*/ gf_bs_write_int(bs, 0, 8); gf_bs_write_data(bs, szItem, strlen(szItem)); @@ -661,7 +680,7 @@ Bool OD_ParseUIConfig(char *val, char **out_data, u32 *out_data_size) if ((pos<0) || !val[0] || val[0]==';') { if (has_word) { has_word = 0; - bs_cur = (u32) gf_bs_get_position(bs); + bs_cur = gf_bs_get_position(bs); gf_bs_seek(bs, bs_start); gf_bs_write_int(bs, nb_phonems, 8); gf_bs_seek(bs, bs_cur); @@ -672,7 +691,7 @@ Bool OD_ParseUIConfig(char *val, char **out_data, u32 *out_data_size) } } if (nbWords) { - bs_cur = (u32) gf_bs_get_position(bs); + bs_cur = gf_bs_get_position(bs); gf_bs_seek(bs, 0); gf_bs_write_int(bs, nbWords, 8); gf_bs_seek(bs, bs_cur); @@ -684,3 +703,4 @@ Bool OD_ParseUIConfig(char *val, char **out_data, u32 *out_data_size) return 0; } +#endif /* defined(GPAC_DISABLE_LOADER_BT) || defined(GPAC_DISABLE_LOADER_XMT)*/ diff --git a/src/odf/qos.c b/src/odf/qos.c index 5e3cc93..f20702a 100644 --- a/src/odf/qos.c +++ b/src/odf/qos.c @@ -24,6 +24,51 @@ #include +#ifndef GPAC_MINIMAL_ODF + +/************************************************************ + QoSQualifiers Functions +************************************************************/ + +GF_EXPORT +GF_QoS_Default *gf_odf_qos_new(u8 tag) +{ + + GF_QoS_Default *NewQoS(u8 tag); + + GF_QoS_Default *qos; + + qos = NewQoS(tag); + return qos; +} + +GF_EXPORT +GF_Err gf_odf_qos_del(GF_QoS_Default **qos) +{ + if (*qos) gf_odf_delete_qos_qual(*qos); + *qos = NULL; + return GF_OK; +} + + +//same function, but for QoS, as a Qualifier IS NOT a descriptor +GF_EXPORT +GF_Err gf_odf_qos_add_qualif(GF_QoS_Descriptor *desc, GF_QoS_Default *qualif) +{ + u32 i; + GF_QoS_Default *def; + + if (desc->tag != GF_ODF_QOS_TAG) return GF_BAD_PARAM; + if (desc->predefined) return GF_ODF_FORBIDDEN_DESCRIPTOR; + + i=0; + while ((def = (GF_QoS_Default *)gf_list_enum(desc->QoS_Qualifiers, &i))) { + //if same Qualifier, not allowed... + if (def->tag == qualif->tag) return GF_ODF_FORBIDDEN_DESCRIPTOR; + } + return gf_list_add(desc->QoS_Qualifiers, qualif); +} + void gf_odf_delete_qos_qual(GF_QoS_Default *qos) { switch (qos->tag) { @@ -34,13 +79,13 @@ void gf_odf_delete_qos_qual(GF_QoS_Default *qos) case QoSMaxAUSizeTag: case QoSAvgAUSizeTag: case QoSMaxAURateTag: - free(qos); + gf_free(qos); return; default: if ( ((GF_QoS_Private *)qos)->DataLength) - free(((GF_QoS_Private *)qos)->Data); - free( (GF_QoS_Private *) qos); + gf_free(((GF_QoS_Private *)qos)->Data); + gf_free( (GF_QoS_Private *) qos); return; } } @@ -148,43 +193,43 @@ GF_Err gf_odf_parse_qos(GF_BitStream *bs, GF_QoS_Default **qos_qual, u32 *qual_s //Payload switch (tag) { case QoSMaxDelayTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxDelay)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxDelay)); ((GF_QoS_MaxDelay *)newQoS)->MaxDelay = gf_bs_read_int(bs, 32); bytesParsed += 4; break; case QoSPrefMaxDelayTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_PrefMaxDelay)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_PrefMaxDelay)); ((GF_QoS_PrefMaxDelay *)newQoS)->PrefMaxDelay = gf_bs_read_int(bs, 32); bytesParsed += 4; break; case QoSLossProbTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_LossProb)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_LossProb)); ((GF_QoS_LossProb *)newQoS)->LossProb = gf_bs_read_float(bs); bytesParsed += 4; break; case QoSMaxGapLossTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxGapLoss)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxGapLoss)); ((GF_QoS_MaxGapLoss *)newQoS)->MaxGapLoss = gf_bs_read_int(bs, 32); bytesParsed += 4; break; case QoSMaxAUSizeTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxAUSize)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxAUSize)); ((GF_QoS_MaxAUSize *)newQoS)->MaxAUSize = gf_bs_read_int(bs, 32); bytesParsed += 4; break; case QoSAvgAUSizeTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_AvgAUSize)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_AvgAUSize)); ((GF_QoS_AvgAUSize *)newQoS)->AvgAUSize = gf_bs_read_int(bs, 32); bytesParsed += 4; break; case QoSMaxAURateTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxAURate)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxAURate)); ((GF_QoS_MaxAURate *)newQoS)->MaxAURate = gf_bs_read_int(bs, 32); bytesParsed += 4; break; @@ -195,7 +240,7 @@ GF_Err gf_odf_parse_qos(GF_BitStream *bs, GF_QoS_Default **qos_qual, u32 *qual_s default: //we defined the private qos... - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_Private)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_Private)); ((GF_QoS_Private *)newQoS)->DataLength = qos_size; gf_bs_read_data(bs, ((GF_QoS_Private *)newQoS)->Data, ((GF_QoS_Private *)newQoS)->DataLength); bytesParsed += ((GF_QoS_Private *)newQoS)->DataLength; @@ -219,43 +264,43 @@ GF_QoS_Default *NewQoS(u8 tag) switch (tag) { case QoSMaxDelayTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxDelay)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxDelay)); ((GF_QoS_MaxDelay *)newQoS)->MaxDelay = 0; ((GF_QoS_MaxDelay *)newQoS)->size = 4; break; case QoSPrefMaxDelayTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_PrefMaxDelay)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_PrefMaxDelay)); ((GF_QoS_PrefMaxDelay *)newQoS)->PrefMaxDelay = 0; ((GF_QoS_PrefMaxDelay *)newQoS)->size = 4; break; case QoSLossProbTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_LossProb)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_LossProb)); ((GF_QoS_LossProb *)newQoS)->LossProb = 0; ((GF_QoS_LossProb *)newQoS)->size = 4; break; case QoSMaxGapLossTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxGapLoss)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxGapLoss)); ((GF_QoS_MaxGapLoss *)newQoS)->MaxGapLoss = 0; ((GF_QoS_MaxGapLoss *)newQoS)->size = 4; break; case QoSMaxAUSizeTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxAUSize)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxAUSize)); ((GF_QoS_MaxAUSize *)newQoS)->MaxAUSize = 0; ((GF_QoS_MaxAUSize *)newQoS)->size = 0; break; case QoSAvgAUSizeTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_AvgAUSize)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_AvgAUSize)); ((GF_QoS_AvgAUSize *)newQoS)->AvgAUSize = 0; ((GF_QoS_AvgAUSize *)newQoS)->size = 4; break; case QoSMaxAURateTag: - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_MaxAURate)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_MaxAURate)); ((GF_QoS_MaxAURate *)newQoS)->MaxAURate = 0; ((GF_QoS_MaxAURate *)newQoS)->size = 4; break; @@ -266,7 +311,7 @@ GF_QoS_Default *NewQoS(u8 tag) default: //we defined the private qos... - newQoS = (GF_QoS_Default *) malloc(sizeof(GF_QoS_Private)); + newQoS = (GF_QoS_Default *) gf_malloc(sizeof(GF_QoS_Private)); ((GF_QoS_Private *)newQoS)->DataLength = 0; ((GF_QoS_Private *)newQoS)->Data = NULL; break; @@ -280,7 +325,7 @@ GF_QoS_Default *NewQoS(u8 tag) // GF_Descriptor *gf_odf_new_qos() { - GF_QoS_Descriptor *newDesc = (GF_QoS_Descriptor *) malloc(sizeof(GF_QoS_Descriptor)); + GF_QoS_Descriptor *newDesc = (GF_QoS_Descriptor *) gf_malloc(sizeof(GF_QoS_Descriptor)); if (!newDesc) return NULL; newDesc->QoS_Qualifiers = gf_list_new(); newDesc->predefined = 0; @@ -388,3 +433,5 @@ GF_Err gf_odf_write_qos(GF_BitStream *bs, GF_QoS_Descriptor *qos) } +#endif /*GPAC_MINIMAL_ODF*/ + diff --git a/src/odf/slc.c b/src/odf/slc.c index c031107..b4e2863 100644 --- a/src/odf/slc.c +++ b/src/odf/slc.c @@ -30,7 +30,7 @@ // GF_Descriptor *gf_odf_new_slc(u8 predef) { - GF_SLConfig *newDesc = (GF_SLConfig *) malloc(sizeof(GF_SLConfig)); + GF_SLConfig *newDesc = (GF_SLConfig *) gf_malloc(sizeof(GF_SLConfig)); if (!newDesc) return NULL; memset(newDesc, 0, sizeof(GF_SLConfig)); newDesc->tag = GF_ODF_SLC_TAG; @@ -47,7 +47,7 @@ GF_Descriptor *gf_odf_new_slc(u8 predef) GF_Err gf_odf_del_slc(GF_SLConfig *sl) { if (!sl) return GF_BAD_PARAM; - free(sl); + gf_free(sl); return GF_OK; } @@ -426,7 +426,7 @@ void gf_sl_depacketize (GF_SLConfig *slConfig, GF_SLHeader *Header, char *PDU, u Header->degradationPriorityFlag = gf_bs_read_int(bs, 1); if (Header->degradationPriorityFlag) Header->degradationPriority = gf_bs_read_int(bs, slConfig->degradationPriorityLength); } - if (Header->OCRflag) Header->objectClockReference = gf_bs_read_int(bs, slConfig->OCRLength); + if (Header->OCRflag) Header->objectClockReference = gf_bs_read_long_int(bs, slConfig->OCRLength); if (Header->accessUnitStartFlag) { if (slConfig->useRandomAccessPointFlag) Header->randomAccessPointFlag = gf_bs_read_int(bs, 1); if (slConfig->AUSeqNumLength > 0) Header->AU_sequenceNumber = gf_bs_read_int(bs, slConfig->AUSeqNumLength); diff --git a/src/scene_manager/encode_cbk.c b/src/scene_manager/encode_cbk.c deleted file mode 100644 index e2af3eb..0000000 --- a/src/scene_manager/encode_cbk.c +++ /dev/null @@ -1,503 +0,0 @@ -/* - * GPAC Multimedia Framework - * - * Authors: Cyril Concolato - Jean le Feuvre - * Copyright (c) 2005-200X ENST - * 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 - -#ifndef GPAC_READ_ONLY - -#include -#include -#include - -struct __tag_bifs_engine -{ - GF_SceneGraph *sg; - GF_SceneManager *ctx; - GF_SceneLoader load; - void *calling_object; - GF_StreamContext *sc; - Bool owns_context; - GF_BifsEncoder *bifsenc; - u32 stream_ts_res; - /* TODO: maybe the currentAUCount should be a GF_List of u32 - to capture the number of AU per input BIFS stream */ - u32 currentAUCount; - - char encoded_bifs_config[20]; - u32 encoded_bifs_config_size; -}; - -static GF_Err gf_sm_setup_bifsenc(GF_BifsEngine *codec, GF_InitialObjectDescriptor *iod) -{ - GF_Err e; - char *data; - u32 data_len; - u32 j, nbb; - GF_ESD *esd; - Bool is_in_iod, delete_desc, encode_names, delete_bcfg; - GF_BIFSConfig *bcfg; - - e = GF_OK; - codec->bifsenc = gf_bifs_encoder_new(codec->ctx->scene_graph); - - delete_desc = 0; - esd = NULL; - is_in_iod = 1; - if (iod) { - is_in_iod = 0; - j=0; - while ((esd = (GF_ESD*)gf_list_enum(iod->ESDescriptors, &j))) { - if (esd->decoderConfig && esd->decoderConfig->streamType == GF_STREAM_SCENE) { - if (!codec->sc->ESID) codec->sc->ESID = esd->ESID; - if (codec->sc->ESID == esd->ESID) { - is_in_iod = 1; - break; - } - } - /*special BIFS direct import from NHNT*/ - else if (gf_list_count(iod->ESDescriptors)==1) { - codec->sc->ESID = esd->ESID; - is_in_iod = 1; - break; - } - esd = NULL; - } - } - - if (!esd) { - delete_desc = 1; - esd = gf_odf_desc_esd_new(2); - gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo); - esd->decoderConfig->decoderSpecificInfo = NULL; - esd->ESID = codec->sc->ESID; - esd->decoderConfig->streamType = GF_STREAM_SCENE; - } - - delete_bcfg = 0; - - /*should NOT happen (means inputctx is not properly setup)*/ - if (!esd->decoderConfig->decoderSpecificInfo) { - bcfg = (GF_BIFSConfig*)gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG); - bcfg->pixelMetrics = codec->ctx->is_pixel_metrics; - bcfg->pixelWidth = codec->ctx->scene_width; - bcfg->pixelHeight = codec->ctx->scene_height; - delete_bcfg = 1; - } - /*regular retrieve from ctx*/ - else if (esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_BIFS_CFG_TAG) { - bcfg = (GF_BIFSConfig *)esd->decoderConfig->decoderSpecificInfo; - } - /*should not happen either (unless loading from MP4 in which case BIFSc is not decoded)*/ - else { - bcfg = gf_odf_get_bifs_config(esd->decoderConfig->decoderSpecificInfo, esd->decoderConfig->objectTypeIndication); - delete_bcfg = 1; - } - /*NO CHANGE TO BIFSC otherwise the generated update will not match the input context, UNLESS NO NbBits - were specified*/ - nbb = gf_get_bit_size(codec->ctx->max_node_id); - if (!bcfg->nodeIDbits) bcfg->nodeIDbits = nbb; - else if (bcfg->nodeIDbitsnodeIDbits, codec->ctx->max_node_id)); - } - nbb = gf_get_bit_size(codec->ctx->max_route_id); - if (!bcfg->routeIDbits) bcfg->routeIDbits = nbb; - else if (bcfg->routeIDbitsrouteIDbits, codec->ctx->max_route_id)); - } - nbb = gf_get_bit_size(codec->ctx->max_proto_id); - if (!bcfg->protoIDbits) bcfg->protoIDbits=nbb; - else if (bcfg->protoIDbitsprotoIDbits, codec->ctx->max_proto_id)); - } - - /*this is the real pb, not stored in cfg or file level, set at EACH replaceScene*/ - encode_names = 0; - - /* The BIFS Config that is passed here should be the BIFSConfig from the IOD */ - gf_bifs_encoder_new_stream(codec->bifsenc, codec->sc->ESID, bcfg, encode_names, 0); - if (delete_bcfg) gf_odf_desc_del((GF_Descriptor *)bcfg); - - if (!esd->slConfig) esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); - if (codec->sc->timeScale) esd->slConfig->timestampResolution = codec->sc->timeScale; - if (!esd->slConfig->timestampResolution) esd->slConfig->timestampResolution = 1000; - - esd->ESID = codec->sc->ESID; - gf_bifs_encoder_get_config(codec->bifsenc, codec->sc->ESID, &data, &data_len); - - if (esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo); - esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); - esd->decoderConfig->decoderSpecificInfo->data = data; - esd->decoderConfig->decoderSpecificInfo->dataLength = data_len; - - codec->stream_ts_res = esd->slConfig->timestampResolution; - memcpy(codec->encoded_bifs_config, data, data_len); - codec->encoded_bifs_config_size = data_len; - - esd->decoderConfig->objectTypeIndication = gf_bifs_encoder_get_version(codec->bifsenc, codec->sc->ESID); - return GF_OK; -} - -static GF_Err gf_sm_live_setup(GF_BifsEngine *codec) -{ - GF_Err e; - GF_InitialObjectDescriptor *iod; - u32 i, count; - - e = GF_OK; - - iod = (GF_InitialObjectDescriptor *) codec->ctx->root_od; - /*if no iod check we only have one bifs*/ - if (!iod) { - count = 0; - i=0; - while ((codec->sc = (GF_StreamContext*)gf_list_enum(codec->ctx->streams, &i))) { - if (codec->sc->streamType == GF_STREAM_OD) count++; - codec->sc = NULL; - } - if (!iod && count>1) return GF_NOT_SUPPORTED; - } - - codec->sc = NULL; - count = gf_list_count(codec->ctx->streams); - i=0; - while ((codec->sc = (GF_StreamContext*)gf_list_enum(codec->ctx->streams, &i))) { - if (codec->sc->streamType == GF_STREAM_SCENE) break; - } - if (!codec->sc) return GF_NOT_SUPPORTED; - if (!codec->sc->ESID) codec->sc->ESID = 1; - - if (codec->sc->objectType <= GPAC_OTI_SCENE_BIFS_V2) { - return gf_sm_setup_bifsenc(codec, iod); - } else if (codec->sc->objectType == GPAC_OTI_SCENE_DIMS) { - /* TODO */ - return GF_NOT_SUPPORTED; - } - return e; -} - -static GF_Err gf_sm_live_encode_scene_au(GF_BifsEngine *codec, u32 currentAUCount, - GF_Err (*AUCallback)(void *, char *, u32 , u64) - ) -{ - GF_Err e; - u32 j, size, count; - char *data; - GF_AUContext *au; - - if (!AUCallback) return GF_BAD_PARAM; - - e = GF_OK; - count = gf_list_count(codec->sc->AUs); - for (j=currentAUCount; jsc->AUs, j); - /*in case using XMT*/ - if (au->timing_sec) au->timing = (u64) (au->timing_sec * codec->stream_ts_res); - switch(codec->sc->objectType) { - case GPAC_OTI_SCENE_BIFS: - case GPAC_OTI_SCENE_BIFS_V2: - e = gf_bifs_encode_au(codec->bifsenc, codec->sc->ESID, au->commands, &data, &size); - break; - case GPAC_OTI_SCENE_DIMS: - break; - default: - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("Cannot encode AU for Scene OTI %x\n", codec->sc->objectType)); - break; - } - AUCallback(codec->calling_object, data, size, au->timing); - free(data); - data = NULL; - if (e) break; - } - return e; -} - -GF_EXPORT -GF_Err gf_beng_aggregate_context(GF_BifsEngine *codec) -{ - GF_Err e; - - /*make random access for storage*/ - e = gf_sm_make_random_access(codec->ctx); - if (e) return GF_BAD_PARAM; - return GF_OK; -} - -GF_EXPORT -GF_Err gf_beng_save_context(GF_BifsEngine *codec, char * ctxFileName) -{ - u32 d_mode, do_enc; - char szF[GF_MAX_PATH], *ext; - GF_Err e; - - /*check if we dump to BT, XMT or encode to MP4*/ - strcpy(szF, ctxFileName); - ext = strrchr(szF, '.'); - d_mode = GF_SM_DUMP_BT; - do_enc = 0; - if (ext) { - if (!stricmp(ext, ".xmt") || !stricmp(ext, ".xmta")) d_mode = GF_SM_DUMP_XMTA; - else if (!stricmp(ext, ".mp4")) do_enc = 1; - ext[0] = 0; - } - - if (do_enc) { - GF_ISOFile *mp4; - strcat(szF, ".mp4"); - mp4 = gf_isom_open(szF, GF_ISOM_OPEN_WRITE, NULL); - e = gf_sm_encode_to_file(codec->ctx, mp4, NULL); - if (e) gf_isom_delete(mp4); - else gf_isom_close(mp4); - } else { - e = gf_sm_dump(codec->ctx, szF, d_mode); - } - return e; -} - -GF_EXPORT -GF_Err gf_beng_encode_from_string(GF_BifsEngine *codec, char *auString, GF_Err (*AUCallback)(void *, char *, u32 , u64 )) -{ - GF_StreamContext *sc; - u32 i, count; - GF_Err e; - - memset(&(codec->load), 0, sizeof(GF_SceneLoader)); - codec->load.ctx = codec->ctx; - - /* Assumes there is only one BIFS stream in the context - TODO: check how to do it when several BIFS streams are encoded at the same time */ - sc = NULL; - count = gf_list_count(codec->ctx->streams); - i = 0; - while ((sc = (GF_StreamContext*)gf_list_enum(codec->ctx->streams, &i))) { - if (sc->streamType == GF_STREAM_SCENE) break; - sc = NULL; - } - if (!sc) return GF_BAD_PARAM; - codec->currentAUCount = gf_list_count(sc->AUs); - - codec->load.flags = GF_SM_LOAD_MPEG4_STRICT | GF_SM_LOAD_CONTEXT_READY; - codec->load.type = GF_SM_LOAD_BT; - - e = gf_sm_load_string(&codec->load, auString, 0); - if (e) goto exit; - - e = gf_sm_live_encode_scene_au(codec, codec->currentAUCount, AUCallback); -exit: - return e; -} - -GF_EXPORT -GF_Err gf_beng_encode_from_file(GF_BifsEngine *codec, char *auFile, GF_Err (*AUCallback)(void *, char *, u32 , u64 )) -{ - GF_Err e; - GF_StreamContext *sc; - u32 i, count; - - memset(&(codec->load), 0, sizeof(GF_SceneLoader)); - codec->load.fileName = auFile; - codec->load.ctx = codec->ctx; - - /* Assumes there is only one BIFS stream in the context - TODO: check how to do it when several BIFS streams are encoded at the same time */ - sc = NULL; - count = gf_list_count(codec->ctx->streams); - i=0; - while ((sc = (GF_StreamContext*)gf_list_enum(codec->ctx->streams, &i))) { - if (sc->streamType == GF_STREAM_SCENE) break; - sc = NULL; - } - if (!sc) return GF_BAD_PARAM; - codec->currentAUCount = gf_list_count(sc->AUs); - - codec->load.flags = GF_SM_LOAD_MPEG4_STRICT | GF_SM_LOAD_CONTEXT_READY; - e = gf_sm_load_init(&codec->load); - if (!e) e = gf_sm_load_run(&codec->load); - gf_sm_load_done(&codec->load); - if (e) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[BENG] cannot load AU File %s (error %s)\n", auFile, gf_error_to_string(e))); - goto exit; - } - - e = gf_sm_live_encode_scene_au(codec, codec->currentAUCount, AUCallback); - if (e) goto exit; -exit: - return e; -} - -GF_EXPORT -GF_Err gf_beng_encode_context(GF_BifsEngine *codec, GF_Err (*AUCallback)(void *, char *, u32 , u64 )) -{ - return gf_sm_live_encode_scene_au(codec, 0, AUCallback); -} - -GF_EXPORT -void gf_beng_terminate(GF_BifsEngine *codec) -{ - if (codec->bifsenc) gf_bifs_encoder_del(codec->bifsenc); - - if (codec->owns_context) { - if (codec->ctx) gf_sm_del(codec->ctx); - if (codec->sg) gf_sg_del(codec->sg); - } - free(codec); -} - -GF_EXPORT -void gf_beng_get_stream_config(GF_BifsEngine *codec, char **config, u32 *config_len) -{ - *config = codec->encoded_bifs_config; - *config_len = codec->encoded_bifs_config_size; -} - - -GF_EXPORT -GF_BifsEngine *gf_beng_init(void *calling_object, char * inputContext) -{ - GF_BifsEngine *codec; - GF_Err e = GF_OK; - - if (!inputContext) return NULL; - - GF_SAFEALLOC(codec, GF_BifsEngine) - if (!codec) return NULL; - - codec->calling_object = calling_object; - - /*Step 1: create context and load input*/ - codec->sg = gf_sg_new(); - codec->ctx = gf_sm_new(codec->sg); - codec->owns_context = 1; - memset(&(codec->load), 0, sizeof(GF_SceneLoader)); - codec->load.ctx = codec->ctx; - /*since we're encoding in BIFS we must get MPEG-4 nodes only*/ - codec->load.flags = GF_SM_LOAD_MPEG4_STRICT; - - codec->load.fileName = inputContext; - e = gf_sm_load_init(&(codec->load)); - if (!e) e = gf_sm_load_run(&(codec->load)); - gf_sm_load_done(&(codec->load)); - - if (e) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[BENG] Cannot load context from %s (error %s)\n", inputContext, gf_error_to_string(e))); - goto exit; - } - e = gf_sm_live_setup(codec); - if (e!=GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[BENG] cannot init scene encoder for context (error %s)\n", gf_error_to_string(e))); - goto exit; - } - return codec; - -exit: - gf_beng_terminate(codec); - return NULL; -} - -GF_EXPORT -GF_BifsEngine *gf_beng_init_from_context(void *calling_object, GF_SceneManager *ctx) -{ - GF_BifsEngine *codec; - GF_Err e = GF_OK; - - if (!ctx) return NULL; - - GF_SAFEALLOC(codec, GF_BifsEngine) - if (!codec) return NULL; - - codec->calling_object = calling_object; - - /*Step 1: create context and load input*/ - codec->sg = ctx->scene_graph; - codec->ctx = ctx; - codec->owns_context = 0; - - e = gf_sm_live_setup(codec); - if (e!=GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[BENG] cannot init scene encoder for context (error %s)\n", gf_error_to_string(e))); - goto exit; - } - return codec; - -exit: - gf_beng_terminate(codec); - return NULL; -} - -GF_EXPORT -GF_BifsEngine *gf_beng_init_from_string(void *calling_object, char * inputContext, u32 width, u32 height, Bool usePixelMetrics) -{ - GF_BifsEngine *codec; - GF_Err e = GF_OK; - - if (!inputContext) return NULL; - - GF_SAFEALLOC(codec, GF_BifsEngine) - if (!codec) return NULL; - - codec->calling_object = calling_object; - - /*Step 1: create context and load input*/ - codec->sg = gf_sg_new(); - codec->ctx = gf_sm_new(codec->sg); - codec->owns_context = 1; - memset(&(codec->load), 0, sizeof(GF_SceneLoader)); - codec->load.ctx = codec->ctx; - /*since we're encoding in BIFS we must get MPEG-4 nodes only*/ - codec->load.flags = GF_SM_LOAD_MPEG4_STRICT; - - if (inputContext[0] == '<') { - if (strstr(inputContext, "load.type = GF_SM_LOAD_SVG_DA; - else if (strstr(inputContext, "load.type = GF_SM_LOAD_XSR; - else if (strstr(inputContext, "XMT-A") || strstr(inputContext, "X3D")) codec->load.type = GF_SM_LOAD_XMTA; - } else { - codec->load.type = GF_SM_LOAD_BT; - } - e = gf_sm_load_string(&codec->load, inputContext, 0); - - if (e) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[BENG] cannot load context from %s (error %s)\n", inputContext, gf_error_to_string(e))); - goto exit; - } - if (!codec->ctx->root_od) { - codec->ctx->is_pixel_metrics = usePixelMetrics; - codec->ctx->scene_width = width; - codec->ctx->scene_height = height; - } - - e = gf_sm_live_setup(codec); - if (e!=GF_OK) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[BENG] cannot init scene encoder for context (error %s)\n", gf_error_to_string(e))); - goto exit; - } - return codec; - -exit: - gf_beng_terminate(codec); - return NULL; -} - - -#endif - diff --git a/src/scene_manager/encode_isom.c b/src/scene_manager/encode_isom.c index 2becd5a..c40b73a 100644 --- a/src/scene_manager/encode_isom.c +++ b/src/scene_manager/encode_isom.c @@ -26,25 +26,14 @@ #include #include #include -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER #include #include #endif #include -#ifndef GPAC_READ_ONLY - -static GF_MuxInfo *gf_sm_get_mux_info(GF_ESD *src) -{ - u32 i; - GF_MuxInfo *mux; - i=0; - while ((mux = (GF_MuxInfo *)gf_list_enum(src->extensionDescriptors, &i))) { - if (mux->tag == GF_ODF_MUXINFO_TAG) return mux; - } - return NULL; -} +#ifndef GPAC_DISABLE_SCENE_ENCODER static void gf_sm_remove_mux_info(GF_ESD *src) { @@ -60,8 +49,10 @@ static void gf_sm_remove_mux_info(GF_ESD *src) } } + static void gf_sm_finalize_mux(GF_ISOFile *mp4, GF_ESD *src, u32 offset_ts) { +#if !defined (GPAC_DISABLE_ISOM) || !defined(GPAC_DISABLE_ISOM_WRITE) u32 track, mts, ts; GF_MuxInfo *mux = gf_sm_get_mux_info(src); if (!mux && !offset_ts) return; @@ -82,12 +73,15 @@ static void gf_sm_finalize_mux(GF_ISOFile *mp4, GF_ESD *src, u32 offset_ts) /*set track interleaving ID*/ if (mux) { if (mux->GroupID) gf_isom_set_track_group(mp4, track, mux->GroupID); +#ifndef GPAC_DISABLE_MEDIA_IMPORT if (mux->import_flags & GF_IMPORT_USE_COMPACT_SIZE) gf_isom_use_compact_size(mp4, track, 1); +#endif } +#endif } -static GF_Err gf_sm_import_ui_stream(GF_ISOFile *mp4, GF_ESD *src) +static GF_Err gf_sm_import_ui_stream(GF_ISOFile *mp4, GF_ESD *src, Bool rewrite_esd_only) { GF_UIConfig *cfg; u32 len, i; @@ -104,6 +98,8 @@ static GF_Err gf_sm_import_ui_stream(GF_ISOFile *mp4, GF_ESD *src) } else if (src->decoderConfig->decoderSpecificInfo->tag != GF_ODF_DSI_TAG) { return GF_ODF_INVALID_DESCRIPTOR; } + if (rewrite_esd_only) return GF_OK; + /*what's the media type for input sensor ??*/ len = gf_isom_new_track(mp4, src->ESID, GF_ISOM_MEDIA_SCENE, 1000); if (!len) return gf_isom_last_error(mp4); @@ -112,7 +108,8 @@ static GF_Err gf_sm_import_ui_stream(GF_ISOFile *mp4, GF_ESD *src) return gf_isom_new_mpeg4_description(mp4, len, src, NULL, NULL, &i); } -static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD *src, char *mediaSource) + +static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD *src, Double imp_time, char *mediaSource, Bool od_sample_rap) { u32 track, di; GF_Err e; @@ -122,6 +119,15 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD GF_MediaImporter import; GF_MuxInfo *mux = NULL; + if (od_sample_rap && src->ESID && gf_isom_get_track_by_id(mp4, src->ESID) ) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[ISO Import] Detected several import of the same stream %d in OD RAP sample - skipping duplicated imports\n", src->ESID)); + if (src->decoderConfig->decoderSpecificInfo && (src->decoderConfig->decoderSpecificInfo->tag == GF_ODF_UI_CFG_TAG)) { + src->decoderConfig->streamType = GF_STREAM_INTERACT; + return gf_sm_import_ui_stream(mp4, src, 1); + } + return GF_OK; + } + /*no import if URL string*/ if (src->URLString) { u32 mtype, track; @@ -174,7 +180,7 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD /*InputSensor*/ if (src->decoderConfig->decoderSpecificInfo && (src->decoderConfig->decoderSpecificInfo->tag == GF_ODF_UI_CFG_TAG)) src->decoderConfig->streamType = GF_STREAM_INTERACT; - if (src->decoderConfig->streamType == GF_STREAM_INTERACT) return gf_sm_import_ui_stream(mp4, src); + if (src->decoderConfig->streamType == GF_STREAM_INTERACT) return gf_sm_import_ui_stream(mp4, src, 0); } @@ -251,6 +257,7 @@ static GF_Err gf_sm_import_stream(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_ESD import.flags = mux->import_flags; import.video_fps = mux->frame_rate; import.in_name = szName; + import.initial_time_offset = imp_time; e = gf_media_import(&import); if (e) return e; @@ -390,8 +397,10 @@ static GF_Err gf_sm_encode_scene(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEnc GF_ISOSample *samp; GF_StreamContext *sc; GF_ESD *esd; +#ifndef GPAC_DISABLE_BIFS_ENC GF_BifsEncoder *bifs_enc; -#ifndef GPAC_DISABLE_SVG +#endif +#ifndef GPAC_DISABLE_LASER GF_LASeRCodec *lsr_enc; #endif @@ -439,18 +448,21 @@ static GF_Err gf_sm_encode_scene(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEnc if (!j) { GF_Node *n = gf_sg_get_root_node(ctx->scene_graph); if (!n) return GF_OK; -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER if ((scene_type==1) && (gf_node_get_tag(n)!=TAG_SVG_svg) ) return GF_OK; #endif if ((scene_type==0) && (gf_node_get_tag(n)>GF_NODE_RANGE_LAST_X3D) ) return GF_OK; } +#ifndef GPAC_DISABLE_BIFS_ENC bifs_enc = NULL; -#ifndef GPAC_DISABLE_SVG +#endif +#ifndef GPAC_DISABLE_LASER lsr_enc = NULL; #endif if (!scene_type) { +#ifndef GPAC_DISABLE_BIFS_ENC bifs_enc = gf_bifs_encoder_new(ctx->scene_graph); /*no streams defined, encode a RAP*/ if (!j) { @@ -459,10 +471,13 @@ static GF_Err gf_sm_encode_scene(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEnc is_in_iod = 1; goto force_scene_rap; } +#else + return GF_NOT_SUPPORTED; +#endif } if (scene_type==1) { -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER lsr_enc = gf_laser_encoder_new(ctx->scene_graph); /*no streams defined, encode a RAP*/ if (!j) { @@ -512,6 +527,8 @@ static GF_Err gf_sm_encode_scene(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEnc if (!esd && sc->ESID) esd = gf_sm_locate_esd(ctx, sc->ESID); au = NULL; + +#ifndef GPAC_DISABLE_VRML /*special BIFS direct import from NHNT*/ au = (GF_AUContext*)gf_list_get(sc->AUs, 0); if (gf_list_count(sc->AUs) == 1) { @@ -522,6 +539,7 @@ static GF_Err gf_sm_encode_scene(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEnc au = NULL; } } + /*sanity check: remove first command if it is REPLACE SCENE BY NULL*/ if (au && !au->timing && !au->timing_sec && (gf_list_count(au->commands) > 1)) { GF_Command *com = (GF_Command *)gf_list_get(au->commands, 0); @@ -532,10 +550,12 @@ static GF_Err gf_sm_encode_scene(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEnc } } } +#endif + if (!au && !esd->URLString) { /*if not in IOD, the stream will be imported when encoding the OD stream*/ if (!is_in_iod) continue; - e = gf_sm_import_stream(ctx, mp4, esd, NULL); + e = gf_sm_import_stream(ctx, mp4, esd, 0, NULL, 0); if (e) goto exit; gf_sm_finalize_mux(mp4, esd, 0); gf_isom_add_track_to_root_od(mp4, gf_isom_get_track_by_id(mp4, esd->ESID)); @@ -582,6 +602,7 @@ force_scene_rap: /*BIFS setup*/ if (!scene_type) { +#ifndef GPAC_DISABLE_BIFS_ENC GF_BIFSConfig *bcfg; Bool delete_bcfg = 0; @@ -623,9 +644,10 @@ force_scene_rap: esd->decoderConfig->decoderSpecificInfo->data = data; esd->decoderConfig->decoderSpecificInfo->dataLength = data_len; esd->decoderConfig->objectTypeIndication = gf_bifs_encoder_get_version(bifs_enc, esd->ESID); +#endif } /*LASeR setup*/ -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER if (scene_type==1) { GF_LASERConfig lsrcfg; @@ -673,10 +695,13 @@ force_scene_rap: samp = gf_isom_sample_new(); samp->IsRAP = 1; +#ifndef GPAC_DISABLE_BIFS_ENC if (bifs_enc) e = gf_bifs_encoder_get_rap(bifs_enc, &samp->data, &samp->dataLength); -#ifndef GPAC_DISABLE_SVG - else if (lsr_enc) +#endif + +#ifndef GPAC_DISABLE_LASER + if (lsr_enc) e = gf_laser_encoder_get_rap(lsr_enc, &samp->data, &samp->dataLength); #endif if (!e && samp->dataLength) e = gf_isom_add_sample(mp4, track, di, samp); @@ -698,6 +723,7 @@ force_scene_rap: init_offset = 0; j=0; while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) { + u32 samp_size; samp = gf_isom_sample_new(); /*time in sec conversion*/ if (au->timing_sec) au->timing = (u64) (au->timing_sec * esd->slConfig->timestampResolution + 0.0005); @@ -706,50 +732,68 @@ force_scene_rap: samp->DTS = au->timing - init_offset; if ((j>1) && (samp->DTS == prev_dts)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[OD-SL] Same sample time %d for Access Unit %d and %d\n", au->timing, j, j-1)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[OD-SL] Same sample time %d for Access Unit %d and %d\n", au->timing, j, j-1)); e = GF_BAD_PARAM; goto exit; } - samp->IsRAP = au->is_rap; + samp->IsRAP = au->flags & GF_SM_AU_RAP; if (samp->IsRAP) last_rap = au->timing; - /*inband RAP insertion*/ - if (rap_mode==3) { - if (samp->DTS - last_rap < rap_delay) { - /*first encode command*/ - if (bifs_enc) - e = gf_bifs_encode_au(bifs_enc, sc->ESID, au->commands, &samp->data, &samp->dataLength); -#ifndef GPAC_DISABLE_SVG - else if (lsr_enc) - e = gf_laser_encode_au(lsr_enc, sc->ESID, au->commands, 0, &samp->data, &samp->dataLength); + +#ifndef GPAC_DISABLE_BIFS_ENC + if (bifs_enc) + e = gf_bifs_encode_au(bifs_enc, sc->ESID, au->commands, &samp->data, &samp->dataLength); +#endif +#ifndef GPAC_DISABLE_LASER + if (lsr_enc) + e = gf_laser_encode_au(lsr_enc, sc->ESID, au->commands, 0, &samp->data, &samp->dataLength); #endif - /*and apply commands*/ - e = gf_sg_command_apply_list(ctx->scene_graph, au->commands, 0); - } else { - /*first apply commands*/ + samp_size = samp->dataLength; + + /*inband RAP */ + if (rap_mode==3) { + /*current sample before or at the next rep - apply commands*/ + if (samp->DTS <= last_rap + rap_delay) { e = gf_sg_command_apply_list(ctx->scene_graph, au->commands, 0); - /*then get RAP*/ + } + + /*current sample is after or at next rap, insert rap*/ + while (samp->DTS >= last_rap + rap_delay) { + GF_ISOSample *rap_sample = gf_isom_sample_new(); + +#ifndef GPAC_DISABLE_BIFS_ENC if (bifs_enc) - e = gf_bifs_encoder_get_rap(bifs_enc, &samp->data, &samp->dataLength); -#ifndef GPAC_DISABLE_SVG - else if (lsr_enc) - e = gf_laser_encoder_get_rap(lsr_enc, &samp->data, &samp->dataLength); + e = gf_bifs_encoder_get_rap(bifs_enc, &rap_sample->data, &rap_sample->dataLength); #endif - samp->IsRAP = 1; - last_rap = samp->DTS; - } - } else { - if (bifs_enc) - e = gf_bifs_encode_au(bifs_enc, sc->ESID, au->commands, &samp->data, &samp->dataLength); -#ifndef GPAC_DISABLE_SVG - else if (lsr_enc) - e = gf_laser_encode_au(lsr_enc, sc->ESID, au->commands, 0, &samp->data, &samp->dataLength); +#ifndef GPAC_DISABLE_LASER + if (lsr_enc) + e = gf_laser_encoder_get_rap(lsr_enc, &rap_sample->data, &rap_sample->dataLength); #endif + + rap_sample->DTS = last_rap + rap_delay; + rap_sample->IsRAP = 1; + last_rap = rap_sample->DTS; - } + if (!e) e = gf_isom_add_sample(mp4, track, di, rap_sample); + if (samp_size < rap_sample->dataLength) samp_size = rap_sample->dataLength; + + gf_isom_sample_del(&rap_sample); + /*same timing, don't add sample*/ + if (last_rap == samp->DTS) { + if (samp->data) gf_free(samp->data); + samp->data = NULL; + samp->dataLength = 0; + } + } + + /*apply commands */ + if (samp->DTS > last_rap + rap_delay) { + e = gf_sg_command_apply_list(ctx->scene_graph, au->commands, 0); + } + } /*carousel generation*/ if (!e && (rap_mode == 1)) { @@ -758,10 +802,13 @@ force_scene_rap: u64 r_dts = samp->DTS; /*then get RAP*/ +#ifndef GPAC_DISABLE_BIFS_ENC if (bifs_enc) e = gf_bifs_encoder_get_rap(bifs_enc, &car_samp->data, &car_samp->dataLength); -#ifndef GPAC_DISABLE_SVG - else if (lsr_enc) +#endif + +#ifndef GPAC_DISABLE_LASER + if (lsr_enc) e = gf_laser_encoder_get_rap(lsr_enc, &car_samp->data, &car_samp->dataLength); #endif car_samp->IsRAP = 2; @@ -784,16 +831,15 @@ force_scene_rap: } dur = au->timing; - avg_rate += samp->dataLength; - rate += samp->dataLength; - if (esd->decoderConfig->bufferSizeDBdataLength) esd->decoderConfig->bufferSizeDB = samp->dataLength; + avg_rate += samp_size; + rate += samp_size; + if (esd->decoderConfig->bufferSizeDB < samp_size) esd->decoderConfig->bufferSizeDB = samp_size; if (samp->DTS - time_slice > esd->slConfig->timestampResolution) { if (esd->decoderConfig->maxBitrate < rate) esd->decoderConfig->maxBitrate = rate; rate = 0; time_slice = samp->DTS; } - - + prev_dts = samp->DTS; gf_isom_sample_del(&samp); if (e) goto exit; @@ -824,8 +870,10 @@ force_scene_rap: last_rap = samp->DTS = au->timing - init_offset; samp->IsRAP = 1; /*RAP generation*/ +#ifndef GPAC_DISABLE_BIFS_ENC if (bifs_enc) e = gf_bifs_encoder_get_rap(bifs_enc, &samp->data, &samp->dataLength); +#endif if (!e) e = gf_isom_add_sample_shadow(mp4, track, samp); gf_isom_sample_del(&samp); @@ -848,8 +896,10 @@ force_scene_rap: gf_isom_set_pl_indication(mp4, GF_ISOM_PL_GRAPHICS, 1); exit: +#ifndef GPAC_DISABLE_BIFS_ENC if (bifs_enc) gf_bifs_encoder_del(bifs_enc); -#ifndef GPAC_DISABLE_SVG +#endif +#ifndef GPAC_DISABLE_LASER if (lsr_enc) gf_laser_encoder_del(lsr_enc); #endif if (esd && delete_desc) gf_odf_desc_del((GF_Descriptor *) esd); @@ -963,13 +1013,19 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media prev_dts = 0; if (opts) rap_delay = opts->rap_freq * esd->slConfig->timestampResolution / 1000; - /*encode all samples and perform import - FIXME this is destructive...*/ + + /*encode all samples and perform import */ j=0; while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) { - - while (gf_list_count(au->commands) ) { - GF_ODCom *com = (GF_ODCom *) gf_list_get(au->commands, 0); - gf_list_rem(au->commands, 0); + GF_ODCom *com; + u32 k = 0; + Bool rap_aggregated=0; + + if (au->timing_sec) au->timing = (u64) (au->timing_sec * esd->slConfig->timestampResolution + 0.0005); + else au->timing_sec = (double) ((s64) (au->timing / esd->slConfig->timestampResolution)); + + while ((com = gf_list_enum(au->commands, &k))) { + /*only updates commandes need to be parsed for import*/ switch (com->tag) { case GF_ODF_OD_UPDATE_TAG: @@ -983,10 +1039,9 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media while ((imp_esd = (GF_ESD*)gf_list_enum(od->ESDescriptors, &m))) { switch (imp_esd->tag) { case GF_ODF_ESD_TAG: - e = gf_sm_import_stream(ctx, mp4, imp_esd, mediaSource); + e = gf_sm_import_stream(ctx, mp4, imp_esd, au->timing_sec, mediaSource, au->flags & GF_SM_AU_RAP); if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] cannot import stream %d (error %s)\n", imp_esd->ESID, gf_error_to_string(e))); - gf_odf_com_del(&com); goto err_exit; } gf_sm_finalize_mux(mp4, imp_esd, 0); @@ -995,7 +1050,7 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media case GF_ODF_ESD_INC_TAG: break; default: - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[ISO File Encode] Invalid descriptor in OD%d.ESDescr\n", od->objectDescriptorID)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] Invalid descriptor in OD%d.ESDescr\n", od->objectDescriptorID)); e = GF_BAD_PARAM; goto err_exit; break; @@ -1012,7 +1067,7 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media while ((imp_esd = (GF_ESD*)gf_list_enum(esdU->ESDescriptors, &m))) { switch (imp_esd->tag) { case GF_ODF_ESD_TAG: - e = gf_sm_import_stream(ctx, mp4, imp_esd, mediaSource); + e = gf_sm_import_stream(ctx, mp4, imp_esd, au->timing_sec, mediaSource, au->flags & GF_SM_AU_RAP); if (e) { GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] cannot import stream %d (error %s)\n", imp_esd->ESID, gf_error_to_string(e))); gf_odf_com_del(&com); @@ -1024,7 +1079,7 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media case GF_ODF_ESD_INC_TAG: break; default: - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[ISO File Encode] Invalid descriptor in ESDUpdate (OD %d)\n", esdU->ODID)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[ISO File Encode] Invalid descriptor in ESDUpdate (OD %d)\n", esdU->ODID)); e = GF_BAD_PARAM; goto err_exit; break; @@ -1036,47 +1091,74 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media /*add to codec*/ gf_odf_codec_add_com(codec, com); - - if (rap_codec) { - e = gf_odf_codec_apply_com(rap_codec, com); - if (e) goto err_exit; - } } - e = gf_odf_codec_encode(codec, 1); - if (e) goto err_exit; - - /*time in sec conversion*/ - if (au->timing_sec) au->timing = (u64) (au->timing_sec * esd->slConfig->timestampResolution + 0.0005); - if (j==1) init_offset = au->timing; samp = gf_isom_sample_new(); samp->DTS = au->timing - init_offset; - samp->IsRAP = au->is_rap; + samp->IsRAP = au->flags & GF_SM_AU_RAP; + + e = gf_odf_codec_encode(codec, 0); + if (e) goto err_exit; if ((j>1) && (samp->DTS == prev_dts)) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CODING, ("[OD-SL] Same sample time %d for Access Unit %d and %d\n", au->timing, j, j-1)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[OD-SL] Same sample time %d for Access Unit %d and %d\n", au->timing, j, j-1)); e = GF_BAD_PARAM; goto err_exit; } + e = gf_odf_codec_get_au(codec, &samp->data, &samp->dataLength); + last_not_shadow = samp->DTS; + if (samp->IsRAP) { + last_rap = samp->DTS; + } else if (rap_inband) { + while (samp->DTS >= rap_delay + last_rap) { + GF_ISOSample *rap_sample = gf_isom_sample_new(); + rap_sample->DTS = last_rap + rap_delay; + rap_sample->IsRAP = 1; + + if (samp->DTS == last_rap + rap_delay) { + GF_ODCom *com; + u32 k = 0; + while ((com = gf_list_enum(au->commands, &k))) { + e = gf_odf_codec_apply_com(rap_codec, com); + if (e) goto err_exit; + } + rap_aggregated = 1; + } + e = gf_odf_codec_encode(rap_codec, 2); + if (e) goto err_exit; + e = gf_odf_codec_get_au(rap_codec, &rap_sample->data, &rap_sample->dataLength); - last_not_shadow = samp->DTS; + if (!e) e = gf_isom_add_sample(mp4, track, di, rap_sample); + last_rap = rap_sample->DTS; - if (rap_inband && (samp->DTS - last_rap >= rap_delay)) { - last_rap = samp->DTS; - e = gf_odf_codec_encode(rap_codec, 0); - if (e) goto err_exit; - e = gf_odf_codec_get_au(rap_codec, &samp->data, &samp->dataLength); - samp->IsRAP = 1; - } else { - e = gf_odf_codec_get_au(codec, &samp->data, &samp->dataLength); + avg_rate += rap_sample->dataLength; + rate += rap_sample->dataLength; + + if (rap_sample->DTS==samp->DTS) { + if (samp->data) gf_free(samp->data); + samp->data = NULL; + samp->dataLength = 0; + } + gf_isom_sample_del(&rap_sample); + } } + /*manage carousel/rap generation - we must do it after the RAP has been generated*/ + if (rap_codec && !rap_aggregated) { + GF_ODCom *com; + u32 k = 0; + while ((com = gf_list_enum(au->commands, &k))) { + e = gf_odf_codec_apply_com(rap_codec, com); + if (e) goto err_exit; + } + } - if (!e) e = gf_isom_add_sample(mp4, track, di, samp); + + if (!e && samp->dataLength) e = gf_isom_add_sample(mp4, track, di, samp); dur = au->timing - init_offset; avg_rate += samp->dataLength; @@ -1091,9 +1173,9 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media if (rap_shadow && (samp->DTS - last_rap >= rap_delay)) { last_rap = samp->DTS; - e = gf_odf_codec_encode(rap_codec, 0); + e = gf_odf_codec_encode(rap_codec, 2); if (e) goto err_exit; - if (samp->data) free(samp->data); + if (samp->data) gf_free(samp->data); samp->data = NULL; samp->dataLength = 0; e = gf_odf_codec_get_au(rap_codec, &samp->data, &samp->dataLength); @@ -1126,14 +1208,15 @@ static GF_Err gf_sm_encode_od(GF_SceneManager *ctx, GF_ISOFile *mp4, char *media esd = NULL; } esd = NULL; - gf_isom_set_last_sample_duration(mp4, track, 0); + if (gf_isom_get_sample_count(mp4, track)) + gf_isom_set_last_sample_duration(mp4, track, 0); if (rap_codec) { - if (last_not_shadow) { + if (last_not_shadow && rap_shadow) { samp = gf_isom_sample_new(); samp->DTS = last_not_shadow; samp->IsRAP = 1; - e = gf_odf_codec_encode(rap_codec, 0); + e = gf_odf_codec_encode(rap_codec, 2); if (!e) e = gf_odf_codec_get_au(rap_codec, &samp->data, &samp->dataLength); if (!e) e = gf_isom_add_sample_shadow(mp4, track, samp); if (e) goto err_exit; @@ -1162,6 +1245,11 @@ GF_Err gf_sm_encode_to_file(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEncodeOp if (!ctx->scene_graph) return GF_BAD_PARAM; if (ctx->root_od && (ctx->root_od->tag != GF_ODF_IOD_TAG) && (ctx->root_od->tag != GF_ODF_OD_TAG)) return GF_BAD_PARAM; + + /*set MP4 brands*/ + gf_isom_set_brand_info(mp4, GF_ISOM_BRAND_MP42, 1); + gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_MP41, 1); + /*import specials, that is input remapping to BIFS*/ e = gf_sm_import_specials(ctx); if (e) return e; @@ -1212,8 +1300,7 @@ GF_Err gf_sm_encode_to_file(GF_SceneManager *ctx, GF_ISOFile *mp4, GF_SMEncodeOp gf_isom_set_pl_indication(mp4, GF_ISOM_PL_SCENE, 0xFE); gf_isom_set_pl_indication(mp4, GF_ISOM_PL_GRAPHICS, 0xFE); } - return GF_OK; } -#endif +#endif /*GPAC_DISABLE_SCENE_ENCODER*/ diff --git a/src/scene_manager/loader_bt.c b/src/scene_manager/loader_bt.c index f069b3e..aac591a 100644 --- a/src/scene_manager/loader_bt.c +++ b/src/scene_manager/loader_bt.c @@ -1,7 +1,7 @@ /* * GPAC - Multimedia Framework C SDK * - * Copyright (c) Jean Le Feuvre 2000-2005 + * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * * This file is part of GPAC / Scene Management sub-project @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -32,11 +32,15 @@ /*for key codes...*/ #include +#ifndef GPAC_DISABLE_LOADER_BT + +#include + /*since 0.2.2, we use zlib for bt reading to handle wrl.gz files*/ #include -void gf_sm_load_done_bt(GF_SceneLoader *load); +void load_bt_done(GF_SceneLoader *load); #define BT_LINE_SIZE 4000 @@ -49,6 +53,7 @@ typedef struct typedef struct { GF_SceneLoader *load; + Bool initialized; gzFile gz_in; u32 file_size, file_pos; @@ -102,6 +107,8 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis GF_Route *gf_bt_parse_route(GF_BTParser *parser, Bool skip_def, Bool is_insert, GF_Command *com); void gf_bt_resolve_routes(GF_BTParser *parser, Bool clean); +GF_Node *gf_bt_peek_node(GF_BTParser *parser, char *defID); + static GF_Err gf_bt_report(GF_BTParser *parser, GF_Err e, char *format, ...) { #ifndef GPAC_DISABLE_LOG @@ -119,7 +126,7 @@ static GF_Err gf_bt_report(GF_BTParser *parser, GF_Err e, char *format, ...) } -GF_Node *gf_bt_new_node(GF_BTParser *parser, u32 tag) +GF_Node *gf_bt_new_node(GF_BTParser *parser, u32 tag) { GF_Node *n = gf_node_new(parser->load->scene_graph, tag); return n; @@ -217,7 +224,7 @@ next_line: return; } } else { - if ((gzgets(parser->gz_in, parser->line_buffer, BT_LINE_SIZE) == NULL) + if ((gzgets(parser->gz_in, parser->line_buffer, BT_LINE_SIZE) == NULL) || (!strlen(parser->line_buffer) && gzeof(parser->gz_in))) { parser->done = 1; return; @@ -256,7 +263,7 @@ next_line: parser->line_buffer[len-1] = 0; } - + parser->line_size = strlen(parser->line_buffer); parser->line_pos = 0; parser->line++; @@ -271,7 +278,7 @@ next_line: while ((parser->line_buffer[parser->line_pos]==' ') || (parser->line_buffer[parser->line_pos]=='\t')) parser->line_pos++; - if ( (parser->line_buffer[parser->line_pos]=='#') + if ( (parser->line_buffer[parser->line_pos]=='#') || ( (parser->line_buffer[parser->line_pos]=='/') && (parser->line_buffer[parser->line_pos+1]=='/')) ) { if (parser->line==1) { @@ -292,7 +299,7 @@ next_line: } } } - if (!strnicmp(parser->line_buffer+parser->line_pos, "#define ", 8)) { + if (!strnicmp(parser->line_buffer+parser->line_pos, "#define ", 8) && !parser->block_comment) { char *buf, *sep; parser->line_pos+=8; buf = parser->line_buffer+parser->line_pos; @@ -301,25 +308,58 @@ next_line: BTDefSymbol *def; GF_SAFEALLOC(def, BTDefSymbol); sep[0] = 0; - def->name = strdup(buf); + def->name = gf_strdup(buf); sep[0] = ' '; buf = sep+1; while (strchr(" \t", buf[0])) buf++; - def->value = strdup(buf); + def->value = gf_strdup(buf); gf_list_add(parser->def_symbols, def); } } - else if (!strnicmp(parser->line_buffer+parser->line_pos, "#if 0", 5)) { - parser->block_comment++; + else if (!strnicmp(parser->line_buffer+parser->line_pos, "#if ", 4)) { + u32 len = 0; + parser->line_pos+=4; + while (1) { + if (parser->line_pos+(s32)len==parser->line_size) break; + if (strchr(" \n\t", parser->line_buffer[parser->line_pos+len])) + break; + len++; + } + if (len) { + if (len==1) { + if (!strnicmp(parser->line_buffer+parser->line_pos, "0", len)) { + parser->block_comment++; + } + } else { + u32 i, count; + char *keyWord = NULL; + count = gf_list_count(parser->def_symbols); + for (i=0; idef_symbols, i); + if (!strnicmp(parser->line_buffer+parser->line_pos, def->name, len)) { + keyWord = def->value; + break; + } + } + if (keyWord && !strcmp(keyWord, "0")) { + parser->block_comment++; + } + } + } } else if (!strnicmp(parser->line_buffer+parser->line_pos, "#endif", 6)) { - if (parser->block_comment) + if (parser->block_comment) parser->block_comment--; + } + else if (!strnicmp(parser->line_buffer+parser->line_pos, "#else", 5)) { + if (parser->block_comment) parser->block_comment--; + else + parser->block_comment++; } goto next_line; } - if (parser->block_comment) + if (parser->block_comment) goto next_line; /*brute-force replacement of defined symbols (!!FIXME - no mem checking done !!)*/ @@ -404,7 +444,7 @@ char *gf_bt_get_next(GF_BTParser *parser, Bool point_break) break; } if (!go) break; - } + } parser->cur_buffer[i] = parser->line_buffer[parser->line_pos + i]; i++; if (parser->line_pos+i==parser->line_size) break; @@ -421,14 +461,14 @@ char *gf_bt_get_string(GF_BTParser *parser) #define BT_STR_CHECK_ALLOC \ if (i==size) { \ - res = (char*)realloc(res, sizeof(char) * (size+500)); \ + res = (char*)gf_realloc(res, sizeof(char) * (size+500)); \ size += 500; \ } \ - res = (char*)malloc(sizeof(char) * 500); + res = (char*)gf_malloc(sizeof(char) * 500); size = 500; while (parser->line_buffer[parser->line_pos]==' ') parser->line_pos++; - + if (parser->line_pos==parser->line_size) { if (gzeof(parser->gz_in)) return NULL; gf_bt_check_line(parser); @@ -436,7 +476,7 @@ char *gf_bt_get_string(GF_BTParser *parser) i=0; while (1) { - if (parser->line_buffer[parser->line_pos] == '\"') + if (parser->line_buffer[parser->line_pos] == '\"') if (parser->line_buffer[parser->line_pos-1] != '\\') break; BT_STR_CHECK_ALLOC @@ -505,7 +545,7 @@ Bool gf_bt_check_externproto_field(GF_BTParser *parser, char *str) if (!strcmp(str, "") || !strcmp(str, "field") || !strcmp(str, "eventIn") || !strcmp(str, "eventOut") || !strcmp(str, "exposedField")) { parser->last_error = GF_EOS; return 1; - } + } return 0; } @@ -559,10 +599,10 @@ GF_Err gf_bt_parse_float(GF_BTParser *parser, const char *name, Fixed *val) char *str = gf_bt_get_next(parser, 0); if (!str) return parser->last_error = GF_IO_ERR; if (gf_bt_check_externproto_field(parser, str)) return GF_OK; - + if (check_keyword(parser, str, &var)) { - *val = INT2FIX(var); - return GF_OK; + *val = INT2FIX(var); + return GF_OK; } if (sscanf(str, "%g", &f) != 1) { return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name); @@ -586,7 +626,7 @@ GF_Err gf_bt_parse_int(GF_BTParser *parser, const char *name, SFInt32 *val) if (!str) return parser->last_error = GF_IO_ERR; if (gf_bt_check_externproto_field(parser, str)) return GF_OK; - if (check_keyword(parser, str, val)) return GF_OK; + if (check_keyword(parser, str, val)) return GF_OK; /*URL ODID*/ if (!strnicmp(str, "od:", 3)) str += 3; if (sscanf(str, "%d", val) != 1) { @@ -626,7 +666,7 @@ GF_Err gf_bt_parse_color(GF_BTParser *parser, const char *name, SFColor *col) col->green = INT2FIX((val>>8) & 0xFF) / 255; col->blue = INT2FIX(val & 0xFF) / 255; return parser->last_error; - } + } if (sscanf(str, "%f", &f) != 1) { return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name); } @@ -655,7 +695,7 @@ GF_Err gf_bt_parse_colorRGBA(GF_BTParser *parser, const char *name, SFColorRGBA col->blue = INT2FIX((val>>8) & 0xFF) / 255; col->alpha = INT2FIX(val & 0xFF) / 255; return parser->last_error; - } + } if (sscanf(str, "%f", &f) != 1) { return gf_bt_report(parser, GF_BAD_PARAM, "%s: Number expected", name); } @@ -683,7 +723,7 @@ static void gf_bt_check_time_offset(GF_BTParser *parser, GF_Node *n, GF_FieldInf { if (!n || !(parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK)) return; if (gf_node_get_tag(n) != TAG_ProtoNode) { - if (!stricmp(info->name, "startTime") || !stricmp(info->name, "stopTime")) + if (!stricmp(info->name, "startTime") || !stricmp(info->name, "stopTime")) gf_bt_offset_time(parser, (Double *)info->far_ptr); } else if (gf_sg_proto_field_is_sftime_offset(n, info)) { gf_bt_offset_time(parser, (Double *)info->far_ptr); @@ -815,15 +855,15 @@ void gf_bt_sffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n) break; case GF_SG_VRML_SFSTRING: if (gf_bt_check_code(parser, '\"') || gf_bt_check_code(parser, '\'')) { - char *str = gf_bt_get_string(parser); - if (!str) + char *str = gf_bt_get_string(parser); + if (!str) goto err; - if (((SFString *)info->far_ptr)->buffer) free(((SFString *)info->far_ptr)->buffer); + if (((SFString *)info->far_ptr)->buffer) gf_free(((SFString *)info->far_ptr)->buffer); ((SFString *)info->far_ptr)->buffer = NULL; if (strlen(str)) ((SFString *)info->far_ptr)->buffer = str; else - free(str); + gf_free(str); } else { goto err; } @@ -833,7 +873,7 @@ void gf_bt_sffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n) SFURL *url = (SFURL *)info->far_ptr; char *str = gf_bt_get_string(parser); if (!str) goto err; - if (url->url) free(url->url); + if (url->url) gf_free(url->url); url->url = NULL; url->OD_ID = 0; if (strchr(str, '#')) { @@ -841,7 +881,8 @@ void gf_bt_sffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n) } else { u32 id = 0; char *odstr = str; - if (!strnicmp(str, "od:", 3)) odstr += 3; + if (!strnicmp(str, "od://", 5)) odstr += 5; + else if (!strnicmp(str, "od:", 3)) odstr += 3; /*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/ if (sscanf(odstr, "%d", &id) == 1) { char szURL[20]; @@ -850,7 +891,7 @@ void gf_bt_sffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n) } if (id) { url->OD_ID = id; - free(str); + gf_free(str); } else { url->url = str; } @@ -888,8 +929,8 @@ void gf_bt_sffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n) if (parser->last_error) return; img->numComponents = v; size = img->width * img->height * img->numComponents; - if (img->pixels) free(img->pixels); - img->pixels = (unsigned char*)malloc(sizeof(char) * size); + if (img->pixels) gf_free(img->pixels); + img->pixels = (unsigned char*)gf_malloc(sizeof(char) * size); for (i=0; iscript_text = (unsigned char*)gf_bt_get_string(parser); + } + break; + case GF_SG_VRML_SFATTRREF: + { + SFAttrRef *ar = (SFAttrRef*) info->far_ptr; + char *str = gf_bt_get_next(parser, 1); + if (!gf_bt_check_code(parser, '.')) { + gf_bt_report(parser, GF_BAD_PARAM, "'.' expected in SFAttrRef"); + } else { + GF_FieldInfo pinfo; + ar->node = gf_bt_peek_node(parser, str); + str = gf_bt_get_next(parser, 0); + if (gf_node_get_field_by_name(ar->node, str, &pinfo) != GF_OK) { + gf_bt_report(parser, GF_BAD_PARAM, "field %s is not a member of node %s", str, gf_node_get_class_name(ar->node) ); + } else { + ar->fieldIndex = pinfo.fieldIndex; + } + } + } break; default: @@ -934,7 +994,7 @@ void gf_bt_sffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n) break; } - gf_bt_check_code(parser, ','); + gf_bt_check_code(parser, ','); return; err: gf_bt_report(parser, GF_BAD_PARAM, "%s: Invalid field syntax", info->name); @@ -959,7 +1019,7 @@ void gf_bt_mffield(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n) gf_bt_sffield(parser, &sfInfo, n); if (parser->last_error) return; - gf_bt_check_code(parser, ','); + gf_bt_check_code(parser, ','); if (force_single) break; } } @@ -968,7 +1028,9 @@ Bool gf_bt_check_ndt(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *node, GF_ { if (!node) return 1; if (parent->sgprivate->tag == TAG_MPEG4_Script) return 1; +#ifndef GPAC_DISABLE_X3D if (parent->sgprivate->tag == TAG_X3D_Script) return 1; +#endif if (node->sgprivate->tag == TAG_UndefinedNode) return 1; /*this handles undefined nodes*/ @@ -985,7 +1047,7 @@ u32 gf_bt_get_next_node_id(GF_BTParser *parser) GF_SceneGraph *sc = parser->load->scene_graph; if (parser->parsing_proto) sc = gf_sg_proto_get_graph(parser->parsing_proto); ID = gf_sg_get_next_available_node_id(sc); - if (parser->load->ctx && (ID>parser->load->ctx->max_node_id)) + if (parser->load->ctx && (ID>parser->load->ctx->max_node_id)) parser->load->ctx->max_node_id = ID; return ID; } @@ -996,7 +1058,7 @@ u32 gf_bt_get_next_route_id(GF_BTParser *parser) if (parser->parsing_proto) sg = gf_sg_proto_get_graph(parser->parsing_proto); ID = gf_sg_get_next_available_route_id(sg); - if (parser->load->ctx && (ID>parser->load->ctx->max_route_id)) + if (parser->load->ctx && (ID>parser->load->ctx->max_route_id)) parser->load->ctx->max_route_id = ID; return ID; } @@ -1006,7 +1068,7 @@ u32 gf_bt_get_next_proto_id(GF_BTParser *parser) GF_SceneGraph *sc = parser->load->scene_graph; if (parser->parsing_proto) sc = gf_sg_proto_get_graph(parser->parsing_proto); ID = gf_sg_get_next_available_proto_id(sc); - if (parser->load->ctx && (ID>parser->load->ctx->max_node_id)) + if (parser->load->ctx && (ID>parser->load->ctx->max_node_id)) parser->load->ctx->max_proto_id = ID; return ID; } @@ -1063,11 +1125,12 @@ Bool gf_bt_set_field_is(GF_BTParser *parser, GF_FieldInfo *info, GF_Node *n) void gf_bt_check_unresolved_nodes(GF_BTParser *parser) { u32 i, count; - count = gf_list_count(parser->undef_nodes); + count = gf_list_count(parser->undef_nodes); if (!count) return; for (i=0; iundef_nodes, i); gf_bt_report(parser, GF_BAD_PARAM, "Cannot find node %s\n", gf_node_get_name(n) ); + gf_node_unregister(n, NULL); } parser->last_error = GF_BAD_PARAM; } @@ -1083,22 +1146,29 @@ Bool gf_bt_has_been_def(GF_BTParser *parser, char *node_name) return 0; } -u32 gf_bt_get_node_tag(GF_BTParser *parser, char *node_name) +u32 gf_bt_get_node_tag(GF_BTParser *parser, char *node_name) { u32 tag; /*if VRML and allowing non MPEG4 nodes, use X3D*/ if (parser->is_wrl && !(parser->load->flags & GF_SM_LOAD_MPEG4_STRICT)) { +#ifndef GPAC_DISABLE_X3D tag = gf_node_x3d_type_by_class_name(node_name); - if (!tag) tag = gf_node_mpeg4_type_by_class_name(node_name); + if (!tag) +#endif + tag = gf_node_mpeg4_type_by_class_name(node_name); if (tag) return tag; +#ifndef GPAC_DISABLE_X3D if (!strcmp(node_name, "Rectangle")) return TAG_X3D_Rectangle2D; if (!strcmp(node_name, "Circle")) return TAG_X3D_Circle2D; +#endif } else { tag = gf_node_mpeg4_type_by_class_name(node_name); if (!tag) { if (!strcmp(node_name, "Rectangle2D")) return TAG_MPEG4_Rectangle; if (!strcmp(node_name, "Circle2D")) return TAG_MPEG4_Circle; +#ifndef GPAC_DISABLE_X3D if (!(parser->load->flags & GF_SM_LOAD_MPEG4_STRICT)) return gf_node_x3d_type_by_class_name(node_name); +#endif } } return tag; @@ -1132,10 +1202,10 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch if (!strcmp(str, "DEF")) { register_def = 1; str = gf_bt_get_next(parser, 0); - name = strdup(str); + name = gf_strdup(str); str = gf_bt_get_next(parser, 0); } else if (szDEFName) { - name = strdup(szDEFName); + name = gf_strdup(szDEFName); register_def = 1; } if (name) { @@ -1161,8 +1231,9 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch node = gf_bt_new_node(parser, TAG_UndefinedNode); ID = gf_bt_get_def_id(parser, str); gf_node_set_id(node, ID, str); + gf_node_register(node, NULL); gf_list_add(parser->undef_nodes, node); - } + } gf_node_register(node, parent); return node; } @@ -1195,7 +1266,11 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch if (!parser->parsing_proto) init_node = 1; } is_script = 0; - if ((tag==TAG_MPEG4_Script) || (tag==TAG_X3D_Script)) + if ((tag==TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (tag==TAG_X3D_Script) +#endif + ) is_script = 1; if (!node) { @@ -1206,7 +1281,7 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch gf_node_register(node, parent); - /*VRML: "The transformation hierarchy shall be a directed acyclic graph; results are undefined if a node + /*VRML: "The transformation hierarchy shall be a directed acyclic graph; results are undefined if a node in the transformation hierarchy is its own ancestor" that's good, because the scene graph can't handle cyclic graphs (destroy will never be called). However we still have to register the node before parsing it, to update node registry and get correct IDs*/ @@ -1214,7 +1289,7 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch if (!undef_node || replace_prev) { gf_node_set_id(node, ID, name); } - free(name); + gf_free(name); name = NULL; } if (!parser->parsing_proto) gf_bt_update_timenode(parser, node); @@ -1222,7 +1297,7 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch if (gf_bt_check_code(parser, '{')) { while (1) { - if (gf_bt_check_code(parser, '}')) + if (gf_bt_check_code(parser, '}')) break; str = gf_bt_get_next(parser, 0); @@ -1246,7 +1321,7 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch continue; } } - + parser->last_error = gf_node_get_field_by_name(node, str, &info); /*check common VRML fields removed in MPEG4*/ @@ -1261,8 +1336,8 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch } /*we ignore 'description' for MPEG4 sensors*/ else if (!strcmp(str, "description")) { - char *str = gf_bt_get_string(parser); - free(str); + char *str = gf_bt_get_string(parser); + gf_free(str); parser->last_error = GF_OK; continue; } @@ -1283,6 +1358,7 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch } } else { /*remaps old VRML/MPEG4 to X3D if possible*/ +#ifndef GPAC_DISABLE_X3D if ((tag==TAG_X3D_LOD) && !strcmp(str, "level")) { str = "children"; parser->last_error = gf_node_get_field_by_name(node, str, &info); @@ -1291,7 +1367,9 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch str = "children"; parser->last_error = gf_node_get_field_by_name(node, str, &info); } - else if (!strcmp(str, "collide")) { + else +#endif + if (!strcmp(str, "collide")) { Bool b; gf_bt_parse_bool(parser, "enabled", &b); parser->last_error = GF_OK; @@ -1325,12 +1403,12 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch if (parser->parsing_proto && gf_bt_set_field_is(parser, &info, node)) continue; if ((eType == GF_SG_SCRIPT_TYPE_EVENT_IN) || (eType == GF_SG_SCRIPT_TYPE_EVENT_OUT)) continue; } - + if (parser->last_error) { - gf_bt_report(parser, GF_OK, "%s: Unknown field", str); + gf_bt_report(parser, parser->last_error, "%s: Unknown field", str); goto err; } - + if (proto) gf_sg_proto_mark_field_loaded(node, &info); if (parser->parsing_proto && gf_bt_set_field_is(parser, &info, node)) continue; @@ -1400,6 +1478,7 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch /*remove temp node*/ if (replace_prev) { gf_node_replace(undef_node, node, 0); + gf_node_unregister(undef_node, NULL); gf_list_del_item(parser->undef_nodes, undef_node); } @@ -1416,7 +1495,7 @@ GF_Node *gf_bt_sf_node(GF_BTParser *parser, char *node_name, GF_Node *parent, ch err: gf_node_unregister(node, parent); - if (name) free(name); + if (name) gf_free(name); return NULL; } /* @@ -1431,7 +1510,7 @@ GF_Node *gf_bt_peek_node(GF_BTParser *parser, char *defID) char *str, *ret; char nName[1000]; u32 pos, line, line_pos, i, count; - + n = gf_sg_find_node_by_name(parser->load->scene_graph, defID); if (n) return n; @@ -1460,7 +1539,6 @@ GF_Node *gf_bt_peek_node(GF_BTParser *parser, char *defID) if ( (!prev_is_insert && !strcmp(str, "AT")) || !strcmp(str, "PROTO") ) { /*only check in current command (but be aware of conditionals..)*/ if (!the_node && gf_list_find(parser->bifs_au->commands, parser->cur_com)) { - gf_bt_report(parser, GF_BAD_PARAM, "Cannot find node %s\n", nName); break; } continue; @@ -1470,10 +1548,10 @@ GF_Node *gf_bt_peek_node(GF_BTParser *parser, char *defID) if (strcmp(str, "DEF")) continue; str = gf_bt_get_next(parser, 0); - ret = strdup(str); + ret = gf_strdup(str); str = gf_bt_get_next(parser, 0); if (!strcmp(str, "ROUTE")) { - free(ret); + gf_free(ret); continue; } @@ -1490,7 +1568,7 @@ GF_Node *gf_bt_peek_node(GF_BTParser *parser, char *defID) if (!p) { /*locate proto*/ gf_bt_report(parser, GF_BAD_PARAM, "%s: not a valid/supported node", str); - free(ret); + gf_free(ret); return NULL; } n = gf_sg_proto_create_instance(parser->load->scene_graph, p); @@ -1504,11 +1582,11 @@ GF_Node *gf_bt_peek_node(GF_BTParser *parser, char *defID) if (!parser->parsing_proto) gf_node_init(n); if (!strcmp(ret, nName)) the_node = n; } - free(ret); + gf_free(ret); /*NO REGISTER on peek (both scene graph or DEF list) because peek is only used to get node type and fields, never to insert in the graph*/ - + /*go on till end of AU*/ } /*restore context*/ @@ -1519,11 +1597,11 @@ GF_Node *gf_bt_peek_node(GF_BTParser *parser, char *defID) gf_bt_check_line(parser); parser->line = line; parser->line_pos = line_pos; - + return the_node; } -u32 gf_bt_get_route(GF_BTParser *parser, char *name) +u32 gf_bt_get_route(GF_BTParser *parser, char *name) { u32 i; GF_Command *com; @@ -1536,7 +1614,7 @@ u32 gf_bt_get_route(GF_BTParser *parser, char *name) return 0; } -Bool gf_bt_route_id_used(GF_BTParser *parser, u32 ID) +Bool gf_bt_route_id_used(GF_BTParser *parser, u32 ID) { u32 i; GF_Command *com; @@ -1570,14 +1648,14 @@ GF_Err gf_bt_parse_proto(GF_BTParser *parser, char *proto_code, GF_List *proto_l char szDefName[1024]; Bool isDEF; - if (proto_code) + if (proto_code) str = proto_code; else str = gf_bt_get_next(parser, 0); - + externProto = !strcmp(str, "EXTERNPROTO") ? 1 : 0; str = gf_bt_get_next(parser, 0); - name = strdup(str); + name = gf_strdup(str); if (!gf_bt_check_code(parser, '[')) { return gf_bt_report(parser, GF_BAD_PARAM, "[ expected in proto declare"); } @@ -1594,7 +1672,7 @@ GF_Err gf_bt_parse_proto(GF_BTParser *parser, char *proto_code, GF_List *proto_l /*hack for VRML, where externProto default field values are not mandatory*/ parser->is_extern_proto_field = externProto; - free(name); + gf_free(name); /*get all fields*/ while (!parser->last_error && !gf_bt_check_code(parser, ']')) { str = gf_bt_get_next(parser, 0); @@ -1703,13 +1781,13 @@ next_field: sscanf(str, "od:%d", &url->OD_ID); } else { if (!sscanf(str, "%d", &url->OD_ID)) { - url->url = strdup(str); + url->url = gf_strdup(str); } else { char szURL[20]; sprintf(szURL, "%d", url->OD_ID); if (strcmp(szURL, str)) { url->OD_ID = 0; - url->url = strdup(str); + url->url = gf_strdup(str); } } } @@ -1719,7 +1797,7 @@ next_field: } } while (has_urls); return GF_OK; - } + } /*parse proto code */ if (!gf_bt_check_code(parser, '{')) { @@ -1812,7 +1890,7 @@ GF_Route *gf_bt_parse_route(GF_BTParser *parser, Bool skip_def, Bool is_insert, str = gf_bt_get_next(parser, 0); e = gf_node_get_field_by_name(orig, str, &orig_field); /*VRML loosy syntax*/ - if ((e != GF_OK) && parser->is_wrl && !strnicmp(str, "set_", 4)) + if ((e != GF_OK) && parser->is_wrl && !strnicmp(str, "set_", 4)) e = gf_node_get_field_by_name(orig, &str[4], &orig_field); if ((e != GF_OK) && parser->is_wrl && strstr(str, "_changed")) { @@ -1844,9 +1922,9 @@ GF_Route *gf_bt_parse_route(GF_BTParser *parser, Bool skip_def, Bool is_insert, str = gf_bt_get_next(parser, 0); e = gf_node_get_field_by_name(dest, str, &dest_field); /*VRML loosy syntax*/ - if ((e != GF_OK) && parser->is_wrl && !strnicmp(str, "set_", 4)) + if ((e != GF_OK) && parser->is_wrl && !strnicmp(str, "set_", 4)) e = gf_node_get_field_by_name(dest, &str[4], &dest_field); - + if ((e != GF_OK) && parser->is_wrl && strstr(str, "_changed")) { char *s = strstr(str, "_changed"); s[0] = 0; @@ -1864,11 +1942,11 @@ GF_Route *gf_bt_parse_route(GF_BTParser *parser, Bool skip_def, Bool is_insert, com->toFieldIndex = dest_field.fieldIndex; if (rID) { com->RouteID = rID; - com->def_name = strdup(rName); + com->def_name = gf_strdup(rName); /*whenever inserting routes, keep track of max defined ID*/ if (is_insert) { gf_sg_set_max_defined_route_id(parser->load->scene_graph, rID); - if (parser->load->ctx && (rID>parser->load->ctx->max_route_id)) + if (parser->load->ctx && (rID>parser->load->ctx->max_route_id)) parser->load->ctx->max_route_id = rID; } } @@ -1894,7 +1972,7 @@ void gf_bt_resolve_routes(GF_BTParser *parser, Bool clean) case GF_SG_ROUTE_REPLACE: com->RouteID = gf_bt_get_route(parser, com->unres_name); if (!com->RouteID) gf_bt_report(parser, GF_BAD_PARAM, "Cannot resolve Route %s", com->unres_name); - free(com->unres_name); + gf_free(com->unres_name); com->unres_name = NULL; com->unresolved = 0; break; @@ -1916,11 +1994,11 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis { s32 pos; GF_Route *r; - GF_Node *n, *newnode, *opnode; + GF_Node *n, *newnode; GF_Command *com; GF_CommandField *inf; GF_FieldInfo info; - char *str, field[1000], *sep; + char *str, field[1000]; if (!name) { str = gf_bt_get_next(parser, 0); } else { @@ -1930,7 +2008,6 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis pos = -2; /*REPLACE commands*/ if (!strcmp(str, "REPLACE")) { - Bool is_op = 0; str = gf_bt_get_next(parser, 1); if (!strcmp(str, "ROUTE")) { str = gf_bt_get_next(parser, 0); @@ -1944,14 +2021,14 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis if (r) { com->RouteID = r->ID; } else { - com->unres_name = strdup(field); + com->unres_name = gf_strdup(field); com->unresolved = 1; gf_list_add(parser->unresolved_routes, com); } gf_bt_parse_route(parser, 1, 0, com); gf_list_add(cmdList, com); return parser->last_error; - } + } /*scene replace*/ if (!strcmp(str, "SCENE")) { str = gf_bt_get_next(parser, 0); @@ -1991,7 +2068,7 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis strcpy(field, str); if (gf_bt_check_code(parser, '[')) { if ( (parser->last_error = gf_bt_parse_int(parser, "index", &pos)) ) return parser->last_error; - if (!gf_bt_check_code(parser, ']')) + if (!gf_bt_check_code(parser, ']')) return gf_bt_report(parser, GF_BAD_PARAM, "] expected"); } /*node replace*/ @@ -2007,61 +2084,12 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis return parser->last_error; } str = gf_bt_get_next(parser, 0); - if (!strcmp(str, "FROM")) - is_op = 1; - else if (strcmp(str, "BY")) return gf_bt_report(parser, GF_BAD_PARAM, "BY expected got %s", str); + if (strcmp(str, "BY")) return gf_bt_report(parser, GF_BAD_PARAM, "BY expected got %s", str); parser->last_error = gf_node_get_field_by_name(n, field, &info); - if (parser->last_error) + if (parser->last_error) return gf_bt_report(parser, parser->last_error, "%s: Unknown node field", field); - if (is_op) { - u32 op_type; - s32 op_idx = -1; - GF_FieldInfo src; - str = gf_bt_get_next(parser, 0); - sep = strchr(str, '.'); - if (!sep) return gf_bt_report(parser, GF_BAD_PARAM, "\'.\' expected"); - sep[0] = 0; - opnode = gf_bt_peek_node(parser, str); - if (!opnode) return gf_bt_report(parser, GF_BAD_PARAM, "%s: unknown node", str); - sep[0] = '.'; - sep++; - - if (gf_bt_check_code(parser, '[')) { - if ( (parser->last_error = gf_bt_parse_int(parser, "index", &op_idx)) ) return parser->last_error; - if (!gf_bt_check_code(parser, ']')) - return gf_bt_report(parser, GF_BAD_PARAM, "] expected"); - } - parser->last_error = gf_node_get_field_by_name(opnode, sep, &src); - if (parser->last_error) - return gf_bt_report(parser, parser->last_error, "%s: Unknown node field", sep); - - op_type = src.fieldType; - if (op_idx>=0) op_type = gf_sg_vrml_get_sf_type(src.fieldType); - - if (pos>=0) { - if (op_type != gf_sg_vrml_get_sf_type(info.fieldType) ) - return gf_bt_report(parser, parser->last_error, "Field type mismatch between %s and %s", info.name, src.name); - } else { - if (src.fieldType != info.fieldType) - return gf_bt_report(parser, parser->last_error, "Field type mismatch between %s and %s", info.name, src.name); - } - com = gf_sg_command_new(parser->load->scene_graph, GF_SG_FIELD_REPLACE_OP); - bd_set_com_node(com, n); - com->fromNodeID = gf_node_get_id(opnode); - com->fromFieldIndex = src.fieldIndex; - com->send_event_x = op_idx; - - inf = gf_sg_command_field_new(com); - inf->fieldIndex = info.fieldIndex; - inf->fieldType = info.fieldType; - inf->pos = pos; - gf_list_add(cmdList, com); - parser->cur_com = com; - return parser->last_error; - } - /*field replace*/ if (pos==-2) { com = gf_sg_command_new(parser->load->scene_graph, GF_SG_FIELD_REPLACE); @@ -2073,9 +2101,10 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis switch (info.fieldType) { case GF_SG_VRML_SFNODE: - inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL); + newnode = gf_bt_sf_node(parser, NULL, NULL, NULL); + if (!gf_bt_check_ndt(parser, &info, newnode, n)) goto err; + inf->new_node = newnode; inf->field_ptr = &inf->new_node; - if (!gf_bt_check_ndt(parser, &info, inf->new_node, n)) goto err; break; case GF_SG_VRML_MFNODE: { @@ -2120,7 +2149,9 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis inf->fieldType = gf_sg_vrml_get_sf_type(info.fieldType); switch (info.fieldType) { case GF_SG_VRML_MFNODE: - inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL); + newnode = gf_bt_sf_node(parser, NULL, NULL, NULL); + if (!gf_bt_check_ndt(parser, &info, newnode, n)) goto err; + inf->new_node = newnode; inf->field_ptr = &inf->new_node; break; default: @@ -2134,6 +2165,201 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis parser->cur_com = com; return parser->last_error; } + /*XREPLACE commands*/ + if (!strcmp(str, "XREPLACE")) { + u32 j; + Bool force_sf=0; + char csep; + GF_Node *targetNode, *idxNode, *childNode, *fromNode; + GF_FieldInfo targetField, idxField, childField, fromField; + + targetNode = idxNode = childNode = fromNode = NULL; + str = gf_bt_get_next(parser, 1); + /*get source node*/ + strcpy(field, str); + targetNode = gf_bt_peek_node(parser, str); + if (!targetNode) return gf_bt_report(parser, GF_BAD_PARAM, "%s: unknown node", field); + if (!gf_bt_check_code(parser, '.')) { + return gf_bt_report(parser, GF_BAD_PARAM, "XREPLACE: '.' expected"); + } + /*get source field*/ + str = gf_bt_get_next(parser, 0); + strcpy(field, str); + parser->last_error = gf_node_get_field_by_name(targetNode, field, &targetField); + if (parser->last_error) + return gf_bt_report(parser, parser->last_error, "%s: Unknown node field", field); + + if (gf_bt_check_code(parser, '[')) { + pos = -2; + str = gf_bt_get_next(parser, 1); + force_sf = 1; + if (sscanf(str, "%d", &pos) != 1) { + pos = -2; + if (!strcmp(str, "LAST")) pos = -1; + else if (!strcmp(str, "first")) pos = 0; + else { + strcpy(field, str); + /*get idx node*/ + idxNode = gf_bt_peek_node(parser, str); + if (!idxNode) return gf_bt_report(parser, GF_BAD_PARAM, "%s: unknown node", field); + if (!gf_bt_check_code(parser, '.')) + return gf_bt_report(parser, GF_BAD_PARAM, "XREPLACE: '.' expected"); + + /*get idx field*/ + str = gf_bt_get_next(parser, 0); + strcpy(field, str); + parser->last_error = gf_node_get_field_by_name(idxNode, field, &idxField); + if (parser->last_error) + return gf_bt_report(parser, parser->last_error, "%s: Unknown node field", field); + } + } + gf_bt_check_code(parser, ']'); + + /*check if we have a child node*/ + if (gf_bt_check_code(parser, '.')) { + s32 apos = pos; + force_sf = 0; + if (idxNode) { + apos = 0; + switch (idxField.fieldType) { + case GF_SG_VRML_SFBOOL: + if (*(SFBool*)idxField.far_ptr) apos = 1; + break; + case GF_SG_VRML_SFINT32: + if (*(SFInt32*)idxField.far_ptr >=0) apos = *(SFInt32*)idxField.far_ptr; + break; + case GF_SG_VRML_SFFLOAT: + if ( (*(SFFloat *)idxField.far_ptr) >=0) apos = (s32) floor( FIX2FLT(*(SFFloat*)idxField.far_ptr) ); + break; + case GF_SG_VRML_SFTIME: + if ( (*(SFTime *)idxField.far_ptr) >=0) apos = (s32) floor( (*(SFTime *)idxField.far_ptr) ); + break; + } + } + childNode = gf_node_list_get_child(*(GF_ChildNodeItem **)targetField.far_ptr, apos); + if (!childNode) + return gf_bt_report(parser, GF_BAD_PARAM, "Cannot find child node at specified index"); + + str = gf_bt_get_next(parser, 0); + strcpy(field, str); + parser->last_error = gf_node_get_field_by_name(childNode, field, &childField); + if (parser->last_error) + return gf_bt_report(parser, parser->last_error, "%s: Unknown node field", field); + } + } + + str = gf_bt_get_next(parser, 0); + if (strcmp(str, "BY")) return gf_bt_report(parser, GF_BAD_PARAM, "BY expected got %s", str); + + /*peek the next word*/ + j = 0; + while (strchr(" \n\t\0", parser->line_buffer[parser->line_pos + j])) j++; + str = parser->line_buffer + parser->line_pos + j; + j = 0; + while (!strchr(" .\0", str[j])) j++; + csep = str[j]; + str[j]=0; + strcpy(field, str); + str[j] = csep; + fromNode = gf_bt_peek_node(parser, field); + if (fromNode) { + gf_bt_get_next(parser, 1); + + if (!gf_bt_check_code(parser, '.')) { + return gf_bt_report(parser, GF_BAD_PARAM, "XREPLACE: '.' expected"); + } + /*get source field*/ + str = gf_bt_get_next(parser, 0); + strcpy(field, str); + parser->last_error = gf_node_get_field_by_name(fromNode, field, &fromField); + if (parser->last_error) + return gf_bt_report(parser, parser->last_error, "%s: Unknown node field", field); + + } else { + /*regular parsing*/ + } + + com = gf_sg_command_new(parser->load->scene_graph, GF_SG_XREPLACE); + bd_set_com_node(com, targetNode); + if (fromNode) { + com->fromNodeID = gf_node_get_id(fromNode); + com->fromFieldIndex = fromField.fieldIndex; + } + if (idxNode) { + com->toNodeID = gf_node_get_id(idxNode); + com->toFieldIndex = idxField.fieldIndex; + } + if (childNode) { + com->ChildNodeTag = gf_node_get_tag(childNode); + if (com->ChildNodeTag==1) { + com->ChildNodeTag = ((GF_ProtoInstance*)childNode)->proto_interface->ID; + com->ChildNodeTag = -com->ChildNodeTag ; + } + com->child_field = childField.fieldIndex; + } + inf = gf_sg_command_field_new(com); + inf->fieldIndex = targetField.fieldIndex; + inf->pos = pos; + if (force_sf) { + inf->fieldType = gf_sg_vrml_get_sf_type(targetField.fieldType); + } else if (childNode) { + inf->fieldType = childField.fieldType; + } else { + inf->fieldType = targetField.fieldType; + } + if (!fromNode) { + switch (inf->fieldType) { + case GF_SG_VRML_SFNODE: + inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL); + inf->field_ptr = &inf->new_node; + if (childNode) { + if (!gf_bt_check_ndt(parser, &childField, inf->new_node, childNode)) goto err; + } else { + if (!gf_bt_check_ndt(parser, &targetField, inf->new_node, targetNode)) goto err; + } + break; + case GF_SG_VRML_MFNODE: + { + GF_ChildNodeItem *last = NULL; + if (!gf_bt_check_code(parser, '[')) break; + inf->field_ptr = &inf->node_list; + while (!gf_bt_check_code(parser, ']')) { + newnode = gf_bt_sf_node(parser, NULL, NULL, NULL); + if (!newnode) goto err; + if (parser->last_error!=GF_OK) goto err; + + if (childNode) { + if (!gf_bt_check_ndt(parser, &childField, inf->new_node, childNode)) goto err; + } else { + if (!gf_bt_check_ndt(parser, &targetField, inf->new_node, targetNode)) goto err; + } + + gf_node_list_add_child_last(& inf->node_list, newnode, &last); + } + } + break; + default: + inf->field_ptr = gf_sg_vrml_field_pointer_new(inf->fieldType); + info.far_ptr = inf->field_ptr; + info.fieldType = inf->fieldType; + + if (gf_sg_vrml_is_sf_field(inf->fieldType)) { + gf_bt_sffield(parser, &info, childNode ? childNode : targetNode); + } else { + gf_bt_mffield(parser, &info, childNode ? childNode : targetNode); + } + if (parser->last_error) goto err; + break; + } + } + + if (parser->last_error) goto err; + gf_list_add(cmdList, com); + parser->cur_com = com; + return parser->last_error; + } + + /*INSERT commands*/ if (!strcmp(str, "INSERT") || !strcmp(str, "APPEND")) { Bool is_append = !strcmp(str, "APPEND") ? 1 : 0; @@ -2175,19 +2401,23 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis } pos = -1; } + gf_node_get_field_by_name(n, field, &info); if (!strcmp(field, "children")) { + newnode = gf_bt_sf_node(parser, NULL, NULL, NULL); + if (parser->last_error) goto err; + + if (!gf_bt_check_ndt(parser, &info, newnode, n)) goto err; com = gf_sg_command_new(parser->load->scene_graph, GF_SG_NODE_INSERT); bd_set_com_node(com, n); inf = gf_sg_command_field_new(com); inf->pos = pos; - inf->new_node = gf_bt_sf_node(parser, NULL, NULL, NULL); + inf->new_node = newnode; inf->fieldType = GF_SG_VRML_SFNODE; inf->field_ptr = &inf->new_node; if (parser->last_error) goto err; parser->cur_com = com; return gf_list_add(cmdList, com); } - gf_node_get_field_by_name(n, field, &info); if (gf_sg_vrml_is_sf_field(info.fieldType)) { gf_bt_report(parser, GF_BAD_PARAM, "%s: MF type field expected", info.name); goto err; @@ -2223,12 +2453,12 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis com = gf_sg_command_new(parser->load->scene_graph, GF_SG_ROUTE_DELETE); com->RouteID = gf_bt_get_route(parser, str); if (!com->RouteID) { - com->unres_name = strdup(str); + com->unres_name = gf_strdup(str); com->unresolved = 1; gf_list_add(parser->unresolved_routes, com); } /*for bt<->xmt conversions*/ - com->def_name = strdup(str); + com->def_name = gf_strdup(str); return gf_list_add(cmdList, com); } strcpy(field, str); @@ -2247,7 +2477,7 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis } if (gf_bt_check_code(parser, '[')) { gf_bt_parse_int(parser, "index", &pos); - if (!gf_bt_check_code(parser, ']')) + if (!gf_bt_check_code(parser, ']')) return gf_bt_report(parser, GF_BAD_PARAM, "[ expected"); } if (gf_sg_vrml_is_sf_field(info.fieldType)) { @@ -2453,7 +2683,7 @@ GF_Err gf_bt_parse_bifs_command(GF_BTParser *parser, char *name, GF_List *cmdLis gf_bt_report(parser, GF_BAD_PARAM, "%s: Unknown proto", str); goto err; } - com->del_proto_list = (u32*)realloc(com->del_proto_list, sizeof(u32)*(com->del_proto_list_size+1)); + com->del_proto_list = (u32*)gf_realloc(com->del_proto_list, sizeof(u32)*(com->del_proto_list_size+1)); com->del_proto_list[com->del_proto_list_size] = proto->ID; com->del_proto_list_size++; } @@ -2469,6 +2699,7 @@ err: GF_Descriptor *gf_bt_parse_descriptor(GF_BTParser *parser, char *name); +#ifndef GPAC_MINIMAL_ODF GF_IPMPX_Data *gf_bt_parse_ipmpx(GF_BTParser *parser, char *name) { char *str, field[500]; @@ -2609,6 +2840,7 @@ GF_IPMPX_Data *gf_bt_parse_ipmpx(GF_BTParser *parser, char *name) } return desc; } +#endif static void gf_bt_add_desc(GF_BTParser *parser, GF_Descriptor *par, GF_Descriptor *child, char *fieldName) { @@ -2656,6 +2888,7 @@ GF_Descriptor *gf_bt_parse_descriptor(GF_BTParser *parser, char *name) type = gf_odf_get_field_type(desc, str); switch (type) { +#ifndef GPAC_MINIMAL_ODF /*IPMPX list*/ case GF_ODF_FT_IPMPX_LIST: if(desc->tag!=GF_ODF_IPMP_TAG) { @@ -2675,7 +2908,7 @@ GF_Descriptor *gf_bt_parse_descriptor(GF_BTParser *parser, char *name) } } break; - /*IPMPX*/ + /*IPMPX*/ case GF_ODF_FT_IPMPX: if(desc->tag!=GF_ODF_IPMP_TOOL_TAG) { gf_bt_report(parser, GF_BAD_PARAM, "IPMPX_Data only allowed in GF_IPMP_Tool"); @@ -2701,6 +2934,7 @@ GF_Descriptor *gf_bt_parse_descriptor(GF_BTParser *parser, char *name) } } break; +#endif /*descriptor list*/ case GF_ODF_FT_OD_LIST: @@ -2715,7 +2949,7 @@ GF_Descriptor *gf_bt_parse_descriptor(GF_BTParser *parser, char *name) gf_bt_add_desc(parser, desc, subdesc, field); } } - if (is_anim_mask) + if (is_anim_mask) gf_bt_check_code(parser, '}'); break; /*single descriptor*/ @@ -2756,17 +2990,27 @@ GF_Descriptor *gf_bt_parse_descriptor(GF_BTParser *parser, char *name) else if (desc->tag==GF_ODF_ESD_TAG) { GF_ESD *esd =(GF_ESD*)desc; if (esd->decoderConfig) { + GF_StreamContext *sc=NULL; + GF_MuxInfo *mux; /*watchout for default BIFS stream*/ if (parser->bifs_es && !parser->base_bifs_id && (esd->decoderConfig->streamType==GF_STREAM_SCENE)) { parser->bifs_es->ESID = parser->base_bifs_id = esd->ESID; parser->bifs_es->timeScale = esd->slConfig ? esd->slConfig->timestampResolution : 1000; + sc = parser->bifs_es; } else { - GF_StreamContext *sc = gf_sm_stream_new(parser->load->ctx, esd->ESID, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); + sc = gf_sm_stream_new(parser->load->ctx, esd->ESID, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); /*set default timescale for systems tracks (ignored for other)*/ if (sc) sc->timeScale = esd->slConfig ? esd->slConfig->timestampResolution : 1000; /*assign base OD*/ if (!parser->base_od_id && (esd->decoderConfig->streamType==GF_STREAM_OD)) parser->base_od_id = esd->ESID; } + /*assign broadcast parameter tools*/ + mux = gf_sm_get_mux_info(esd); + if (sc && mux) { + sc->aggregate_on_esid = mux->aggregate_on_esid; + if (!mux->carousel_period_plus_one) sc->carousel_period = (u32) -1; + else sc->carousel_period = mux->carousel_period_plus_one - 1; + } } } return desc; @@ -2777,7 +3021,7 @@ void gf_bt_parse_od_command(GF_BTParser *parser, char *name) u32 val; char *str; GF_Descriptor *desc; - + if (!strcmp(name, "UPDATE")) { str = gf_bt_get_next(parser, 0); /*OD update*/ @@ -2831,8 +3075,8 @@ void gf_bt_parse_od_command(GF_BTParser *parser, char *name) while (!parser->done) { str = gf_bt_get_next(parser, 0); if (gf_bt_check_code(parser, ']')) break; - if (strcmp(str, "ESDescriptor")) { - gf_bt_report(parser, GF_BAD_PARAM, "ESDescriptor expected got %s", str); + if (strcmp(str, "ES_Descriptor")) { + gf_bt_report(parser, GF_BAD_PARAM, "ES_Descriptor expected got %s", str); break; } desc = gf_bt_parse_descriptor(parser, str); @@ -2882,7 +3126,7 @@ void gf_bt_parse_od_command(GF_BTParser *parser, char *name) if (gf_bt_check_code(parser, ']')) break; gf_bt_parse_int(parser, "ODID", (SFInt32*)&id); if (parser->last_error) return; - odR->OD_ID = (u16*)realloc(odR->OD_ID, sizeof(u16) * (odR->NbODs+1)); + odR->OD_ID = (u16*)gf_realloc(odR->OD_ID, sizeof(u16) * (odR->NbODs+1)); odR->OD_ID[odR->NbODs] = id; odR->NbODs++; } @@ -2912,7 +3156,7 @@ void gf_bt_parse_od_command(GF_BTParser *parser, char *name) if (gf_bt_check_code(parser, ']')) break; gf_bt_parse_int(parser, "ES_ID", (SFInt32*)&id); if (parser->last_error) return; - esdR->ES_ID = (u16*)realloc(esdR->ES_ID, sizeof(u16) * (esdR->NbESDs+1)); + esdR->ES_ID = (u16*)gf_realloc(esdR->ES_ID, sizeof(u16) * (esdR->NbESDs+1)); esdR->ES_ID[esdR->NbESDs] = id; esdR->NbESDs++; } @@ -2945,7 +3189,11 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i /*create a default root node for all VRML nodes*/ if ((parser->is_wrl && !parser->top_nodes) && !vrml_root_node) { if (initial_run ) { +#ifndef GPAC_DISABLE_X3D vrml_root_node = gf_node_new(parser->load->scene_graph, (parser->load->flags & GF_SM_LOAD_MPEG4_STRICT) ? TAG_MPEG4_Group : TAG_X3D_Group); +#else + vrml_root_node = gf_node_new(parser->load->scene_graph, TAG_MPEG4_Group); +#endif gf_node_register(vrml_root_node, NULL); gf_node_init(vrml_root_node); gf_sg_set_root_node(parser->load->scene_graph, vrml_root_node); @@ -2954,11 +3202,13 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i } } + parser->stream_id = parser->load->force_es_id; + /*parse all top-level items*/ while (!parser->last_error) { str = gf_bt_get_next(parser, 0); if (parser->done) break; - + /*X3D specific things (ignored for now)*/ if (!strcmp(str, "PROFILE")) gf_bt_force_line(parser); else if (!strcmp(str, "COMPONENT")) gf_bt_force_line(parser); @@ -3000,13 +3250,13 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i if (parser->bifs_au && (parser->bifs_au->timing != parser->au_time)) { gf_bt_check_unresolved_nodes(parser); parser->bifs_au = NULL; - } + } parser->stream_id = 0; /*fix for mp4tool bt which doesn't support RAP signaling: assume the first AU is always RAP*/ if (!parser->au_time) parser->au_is_rap = 1; - + in_com = 1; if (!gf_bt_check_code(parser, '{')) { @@ -3048,7 +3298,7 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i if (!rID) rID = gf_bt_get_next_route_id(parser); if (com) { com->RouteID = rID; - com->def_name = strdup(szDEFName); + com->def_name = gf_strdup(szDEFName); gf_sg_set_max_defined_route_id(parser->load->scene_graph, rID); } else if (r) { gf_sg_route_set_id(r, rID); @@ -3076,7 +3326,9 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i /*BIFS commands*/ else if (!strcmp(str, "REPLACE") || !strcmp(str, "INSERT") || !strcmp(str, "APPEND") || !strcmp(str, "DELETE") /*BIFS extended commands*/ - || !strcmp(str, "GLOBALQP") || !strcmp(str, "MULTIPLEREPLACE") || !strcmp(str, "MULTIPLEINDREPLACE") || !strcmp(str, "XDELETE") || !strcmp(str, "DELETEPROTO") || !strcmp(str, "INSERTPROTO") ) { + || !strcmp(str, "GLOBALQP") || !strcmp(str, "MULTIPLEREPLACE") || !strcmp(str, "MULTIPLEINDREPLACE") || !strcmp(str, "XDELETE") || !strcmp(str, "DELETEPROTO") || !strcmp(str, "INSERTPROTO") + || !strcmp(str, "XREPLACE") + ) { Bool is_base_stream = parser->stream_id ? 0 : 1; if (!parser->stream_id) parser->stream_id = parser->base_bifs_id; @@ -3084,7 +3336,7 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i if (parser->bifs_es->ESID != parser->stream_id) { GF_StreamContext *prev = parser->bifs_es; - parser->bifs_es = gf_sm_stream_new(parser->load->ctx, (u16) parser->stream_id, GF_STREAM_SCENE, 0); + parser->bifs_es = gf_sm_stream_new(parser->load->ctx, (u16) parser->stream_id, GF_STREAM_SCENE, GPAC_OTI_SCENE_BIFS); /*force new AU if stream changed*/ if (parser->bifs_es != prev) { gf_bt_check_unresolved_nodes(parser); @@ -3103,13 +3355,13 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i if (is_base_stream) parser->stream_id= 0; } /*implicit BIFS command on SFTopNodes only*/ - else if (!strcmp(str, "OrderedGroup") - || !strcmp(str, "Group") - || !strcmp(str, "Layer2D") + else if (!strcmp(str, "OrderedGroup") + || !strcmp(str, "Group") + || !strcmp(str, "Layer2D") || !strcmp(str, "Layer3D") /* VRML parsing: all nodes are allowed*/ - || parser->is_wrl - ) + || parser->is_wrl + ) { node = gf_bt_sf_node(parser, str, vrml_root_node, has_id ? szDEFName : NULL); @@ -3137,7 +3389,7 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i gf_sg_set_root_node(parser->load->scene_graph, node); } */ - } + } /*if in command, check command end*/ else { @@ -3152,7 +3404,7 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i gf_bt_resolve_routes(parser, 0); gf_bt_check_unresolved_nodes(parser); - /*load scripts*/ + /*load scripts*/ while (gf_list_count(parser->scripts)) { GF_Node *n = (GF_Node *)gf_list_get(parser->scripts, 0); gf_list_rem(parser->scripts, 0); @@ -3161,82 +3413,74 @@ GF_Err gf_bt_loader_run_intern(GF_BTParser *parser, GF_Command *init_com, Bool i return parser->last_error; } -GF_Err gf_sm_load_init_bt(GF_SceneLoader *load) +static GF_Err gf_sm_load_bt_initialize(GF_SceneLoader *load, char *str, Bool input_only) { u32 size; gzFile gzInput; GF_Err e; - GF_BTParser *parser; - GF_Command *com; - FILE *test; unsigned char BOM[5]; + GF_BTParser *parser = load->loader_priv; + + parser->last_error = GF_OK; + + if (load->fileName) { + FILE *test = gf_f64_open(load->fileName, "rb"); + if (!test) return GF_URL_ERROR; + gf_f64_seek(test, 0, SEEK_END); + size = (u32) gf_f64_tell(test); + fclose(test); - if (!load->ctx || !load->fileName) return GF_BAD_PARAM; + gzInput = gzopen(load->fileName, "rb"); + if (!gzInput) return GF_IO_ERR; - test = fopen(load->fileName, "rb"); - if (!test) return GF_URL_ERROR; - fseek(test, 0, SEEK_END); - size = ftell(test); - fclose(test); + parser->line_buffer = (char *) gf_malloc(sizeof(char)*BT_LINE_SIZE); + memset(parser->line_buffer, 0, sizeof(char)*BT_LINE_SIZE); + parser->file_size = size; - gzInput = gzopen(load->fileName, "rb"); - if (!gzInput) return GF_IO_ERR; + parser->line_pos = parser->line_size = 0; + gzgets(gzInput, (char*) BOM, 5); + gzseek(gzInput, 0, SEEK_SET); + parser->gz_in = gzInput; - GF_SAFEALLOC(parser, GF_BTParser); - parser->load = load; - parser->line_buffer = (char *) malloc(sizeof(char)*BT_LINE_SIZE); - memset(parser->line_buffer, 0, sizeof(char)*BT_LINE_SIZE); - parser->file_size = size; - - gzgets(gzInput, (char*) BOM, 5); - gzseek(gzInput, 0, SEEK_SET); + } else { + if (!str || (strlen(str)<5) ) return GF_BAD_PARAM; + strncpy(BOM, str, 5); + } /*0: no unicode, 1: UTF-16BE, 2: UTF-16LE*/ if ((BOM[0]==0xFF) && (BOM[1]==0xFE)) { if (!BOM[2] && !BOM[3]) { gf_bt_report(parser, GF_NOT_SUPPORTED, "UTF-32 Text Files not supported"); - gzclose(gzInput); - free(parser); return GF_NOT_SUPPORTED; } else { parser->unicode_type = 2; - gzseek(gzInput, 2, SEEK_CUR); + if (parser->gz_in) gzseek(parser->gz_in, 2, SEEK_CUR); } } else if ((BOM[0]==0xFE) && (BOM[1]==0xFF)) { if (!BOM[2] && !BOM[3]) { gf_bt_report(parser, GF_NOT_SUPPORTED, "UTF-32 Text Files not supported"); - gzclose(gzInput); - free(parser); return GF_NOT_SUPPORTED; } else { parser->unicode_type = 1; - gzseek(gzInput, 2, SEEK_CUR); + if (parser->gz_in) gzseek(parser->gz_in, 2, SEEK_CUR); } } else if ((BOM[0]==0xEF) && (BOM[1]==0xBB) && (BOM[2]==0xBF)) { /*we handle UTF8 as asci*/ parser->unicode_type = 0; - gzseek(gzInput, 3, SEEK_CUR); + if (parser->gz_in) gzseek(parser->gz_in, 3, SEEK_CUR); } - parser->gz_in = gzInput; - load->loader_priv = parser; - parser->def_symbols = gf_list_new(); + parser->initialized = 1; - parser->unresolved_routes = gf_list_new(); - parser->inserted_routes = gf_list_new(); - parser->undef_nodes = gf_list_new(); - parser->def_nodes = gf_list_new(); - parser->peeked_nodes = gf_list_new(); - parser->scripts = gf_list_new(); + if (input_only) return GF_OK; + + /*initalize default streams in the context*/ /*chunk parsing*/ if (load->flags & GF_SM_LOAD_CONTEXT_READY) { u32 i; GF_StreamContext *sc; - if (!load->ctx) { - gf_sm_load_done_bt(load); - return GF_BAD_PARAM; - } - + if (!load->ctx) return GF_BAD_PARAM; + /*restore context - note that base layer are ALWAYS declared BEFORE enhancement layers with gpac parsers*/ i=0; while ((sc = (GF_StreamContext*)gf_list_enum(load->ctx->streams, &i))) { @@ -3248,44 +3492,49 @@ GF_Err gf_sm_load_init_bt(GF_SceneLoader *load) } /*need at least one scene stream*/ if (!parser->bifs_es) { - gf_sm_load_done_bt(load); - return GF_BAD_PARAM; + parser->bifs_es = gf_sm_stream_new(load->ctx, 0, GF_STREAM_SCENE, GPAC_OTI_SCENE_BIFS); + parser->load->ctx->scene_width = 0; + parser->load->ctx->scene_height = 0; + parser->load->ctx->is_pixel_metrics = 1; } - parser->base_bifs_id = parser->bifs_es->ESID; - if (parser->od_es) parser->base_od_id = parser->od_es->ESID; + else parser->base_bifs_id = parser->bifs_es->ESID; + if (parser->od_es) parser->base_od_id = parser->od_es->ESID; GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("BT: MPEG-4 (BT) Scene Chunk Parsing")); - - /*that's it, nothing else to do*/ - return GF_OK; } + /*context is not initialized - check for VRML*/ + else { + GF_Command *com; - parser->load = NULL; - gf_bt_check_line(parser); - parser->load = load; - /*create at least one empty BIFS stream*/ - if (!parser->is_wrl) { - parser->bifs_es = gf_sm_stream_new(load->ctx, 0, GF_STREAM_SCENE, GPAC_OTI_SCENE_BIFS); - parser->bifs_au = gf_sm_stream_au_new(parser->bifs_es, 0, 0, 1); - parser->load->ctx->is_pixel_metrics = 1; - } + parser->load = NULL; + gf_bt_check_line(parser); + parser->load = load; + + /*create at least one empty BIFS stream*/ + if (!parser->is_wrl) { + parser->bifs_es = gf_sm_stream_new(load->ctx, 0, GF_STREAM_SCENE, GPAC_OTI_SCENE_BIFS); + parser->bifs_au = gf_sm_stream_au_new(parser->bifs_es, 0, 0, 1); + parser->load->ctx->is_pixel_metrics = 1; + } - GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ( ((parser->is_wrl==2) ? "BT: X3D (WRL) Scene Parsing\n" : (parser->is_wrl ? "BT: VRML Scene Parsing\n" : "BT: MPEG-4 Scene Parsing\n")) )); + GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ( ((parser->is_wrl==2) ? "BT: X3D (WRL) Scene Parsing\n" : (parser->is_wrl ? "BT: VRML Scene Parsing\n" : "BT: MPEG-4 Scene Parsing\n")) )); - /*default scene replace - we create it no matter what since it is used to store BIFS config - when parsing IOD.*/ - com = NULL; - if (!parser->is_wrl) { - com = gf_sg_command_new(parser->load->scene_graph, GF_SG_SCENE_REPLACE); - gf_list_add(parser->bifs_au->commands, com); + /*default scene replace - we create it no matter what since it is used to store BIFS config when parsing IOD.*/ + com = NULL; + if (!parser->is_wrl) { + com = gf_sg_command_new(parser->load->scene_graph, GF_SG_SCENE_REPLACE); + gf_list_add(parser->bifs_au->commands, com); + } + + /*and perform initial load*/ + e = gf_bt_loader_run_intern(parser, com, 1); + if (e) return e; } - e = gf_bt_loader_run_intern(parser, com, 1); - if (e) gf_sm_load_done_bt(load); - return e; + return GF_OK; } -void gf_sm_load_done_bt(GF_SceneLoader *load) +void load_bt_done(GF_SceneLoader *load) { GF_BTParser *parser = (GF_BTParser *)load->loader_priv; if (!parser) return; @@ -3297,28 +3546,116 @@ void gf_sm_load_done_bt(GF_SceneLoader *load) while (gf_list_count(parser->def_symbols)) { BTDefSymbol *d = (BTDefSymbol *)gf_list_get(parser->def_symbols, 0); gf_list_rem(parser->def_symbols, 0); - free(d->name); - free(d->value); - free(d); + gf_free(d->name); + gf_free(d->value); + gf_free(d); } gf_list_del(parser->def_symbols); gf_list_del(parser->scripts); - gzclose(parser->gz_in); - free(parser->line_buffer); - free(parser); + if (parser->gz_in) gzclose(parser->gz_in); + if (parser->line_buffer) gf_free(parser->line_buffer); + gf_free(parser); load->loader_priv = NULL; - return; } -GF_Err gf_sm_load_run_bt(GF_SceneLoader *load) +GF_Err load_bt_run(GF_SceneLoader *load) +{ + GF_Err e; + GF_BTParser *parser = (GF_BTParser *)load->loader_priv; + if (!parser) return GF_BAD_PARAM; + + if (!parser->initialized) { + e = gf_sm_load_bt_initialize(load, NULL, 1); + if (e) return e; + } + + e = gf_bt_loader_run_intern(parser, NULL, 0); + + if ((e<0) || parser->done) { + parser->done = 0; + parser->initialized = 0; + if (parser->gz_in) { + gzclose(parser->gz_in); + parser->gz_in = NULL; + } + + if (parser->line_buffer) { + gf_free(parser->line_buffer); + parser->line_buffer = NULL; + } + parser->file_size = 0; + parser->line_pos = parser->line_size = 0; + load->fileName = NULL; + } + return e; +} + + +GF_Err load_bt_parse_string(GF_SceneLoader *load, char *str) { + GF_Err e; GF_BTParser *parser = (GF_BTParser *)load->loader_priv; if (!parser) return GF_BAD_PARAM; - return gf_bt_loader_run_intern(parser, NULL, 0); + + if (parser->done) { + parser->done = 0; + parser->initialized = 0; + parser->file_size = 0; + parser->line_pos = 0; + } + parser->line_buffer = str; + parser->line_size = (s32)strlen(str); + + if (!parser->initialized) { + e = gf_sm_load_bt_initialize(load, str, 0); + if (e) return e; + } + e = gf_bt_loader_run_intern(parser, NULL, 0); + parser->line_buffer = NULL; + parser->line_size = 0; + return e; +} + +GF_Err load_bt_suspend(GF_SceneLoader *load, Bool suspend) +{ + return GF_OK; +} + +GF_Err gf_sm_load_init_bt(GF_SceneLoader *load) +{ + GF_Err e; + GF_BTParser *parser; + + if (!load || (!load->ctx && !load->scene_graph) ) return GF_BAD_PARAM; + if (!load->scene_graph) load->scene_graph = load->ctx->scene_graph; + + GF_SAFEALLOC(parser, GF_BTParser); + parser->load = load; + load->loader_priv = parser; + parser->def_symbols = gf_list_new(); + parser->unresolved_routes = gf_list_new(); + parser->inserted_routes = gf_list_new(); + parser->undef_nodes = gf_list_new(); + parser->def_nodes = gf_list_new(); + parser->peeked_nodes = gf_list_new(); + parser->scripts = gf_list_new(); + + load->process = load_bt_run; + load->done = load_bt_done; + load->suspend = load_bt_suspend; + load->parse_string = load_bt_parse_string; + + e = gf_sm_load_bt_initialize(load, NULL, 0); + if (e) { + load_bt_done(load); + return e; + } + return GF_OK; } + GF_List *gf_sm_load_bt_from_string(GF_SceneGraph *in_scene, char *node_str) { GF_SceneLoader ctx; @@ -3341,9 +3678,9 @@ GF_List *gf_sm_load_bt_from_string(GF_SceneGraph *in_scene, char *node_str) while (gf_list_count(parser.def_symbols)) { BTDefSymbol *d = (BTDefSymbol *)gf_list_get(parser.def_symbols, 0); gf_list_rem(parser.def_symbols, 0); - free(d->name); - free(d->value); - free(d); + gf_free(d->name); + gf_free(d->value); + gf_free(d); } gf_list_del(parser.def_symbols); gf_list_del(parser.scripts); @@ -3351,97 +3688,4 @@ GF_List *gf_sm_load_bt_from_string(GF_SceneGraph *in_scene, char *node_str) return parser.top_nodes; } - - -GF_Err gf_sm_load_done_bt_string(GF_SceneLoader *load) -{ - GF_BTParser *parser = (GF_BTParser *)load->loader_priv; - if (!parser) return GF_OK; - gf_list_del(parser->unresolved_routes); - gf_list_del(parser->inserted_routes); - gf_list_del(parser->undef_nodes); - gf_list_del(parser->def_nodes); - gf_list_del(parser->scripts); - free(parser); - load->loader_priv = NULL; - return GF_OK; -} - -GF_Err gf_sm_load_init_bt_string(GF_SceneLoader *load, char *str) -{ - GF_Err e; - GF_BTParser *parser; - GF_Command *com; - - if (!load || (!load->ctx && !load->scene_graph) || !str) return GF_BAD_PARAM; - if (!load->scene_graph) load->scene_graph = load->ctx->scene_graph; - - parser = (GF_BTParser *)malloc(sizeof(GF_BTParser)); - if (parser) memset(parser, 0, sizeof(GF_BTParser)); - else - return GF_OUT_OF_MEM; - - parser->is_wrl = 0; - parser->load = load; - /*we suppose an ascii string*/ - parser->unicode_type = 0; - - parser->line_buffer = str; - parser->line_size = (s32)strlen(str); - parser->gz_in = NULL; - - load->loader_priv = parser; - - parser->unresolved_routes = gf_list_new(); - parser->inserted_routes = gf_list_new(); - parser->undef_nodes = gf_list_new(); - parser->def_nodes = gf_list_new(); - parser->scripts = gf_list_new(); - - /*chunk parsing*/ - if (load->flags & GF_SM_LOAD_CONTEXT_READY) { - u32 i; - GF_StreamContext *sc; - if (!load->ctx) { - gf_sm_load_done_bt(load); - return GF_BAD_PARAM; - } - - /*restore context - note that base layer are ALWAYS declared BEFORE enhancement layers with gpac parsers*/ - i=0; - while ((sc = (GF_StreamContext*)gf_list_enum(load->ctx->streams, &i))){ - switch (sc->streamType) { - case GF_STREAM_SCENE: - case GF_STREAM_PRIVATE_SCENE: - if (!parser->bifs_es) parser->bifs_es = sc; break; - case GF_STREAM_OD: if (!parser->od_es) parser->od_es = sc; break; - default: break; - } - } - /*scene creation - pick up a size*/ - if (!parser->bifs_es) { - parser->bifs_es = gf_sm_stream_new(load->ctx, 0, GF_STREAM_SCENE, 0); - - parser->load->ctx->scene_width = 0; - parser->load->ctx->scene_height = 0; - parser->load->ctx->is_pixel_metrics = 1; - - } - else parser->base_bifs_id = parser->bifs_es->ESID; - if (parser->od_es) parser->base_od_id = parser->od_es->ESID; - /*that's it, nothing else to do*/ - return GF_OK; - } - - /*create at least one empty BIFS stream*/ - parser->bifs_es = gf_sm_stream_new(load->ctx, 0, GF_STREAM_SCENE, 0); - parser->bifs_au = gf_sm_stream_au_new(parser->bifs_es, 0, 0, 1); - - /*default scene replace - we create it no matter what since it is used to store BIFS config - when parsing IOD.*/ - com = gf_sg_command_new(parser->load->scene_graph, GF_SG_SCENE_REPLACE); - gf_list_add(parser->bifs_au->commands, com); - e = gf_bt_loader_run_intern(parser, com, 1); - if (e) gf_sm_load_done_bt_string(load); - return e; -} +#endif /*GPAC_DISABLE_LOADER_BT*/ diff --git a/src/scene_manager/loader_isom.c b/src/scene_manager/loader_isom.c index a6cc6b5..068558d 100644 --- a/src/scene_manager/loader_isom.c +++ b/src/scene_manager/loader_isom.c @@ -25,13 +25,13 @@ #include #include #include -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER #include #endif -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_LOADER_ISOM static void UpdateODCommand(GF_ISOFile *mp4, GF_ODCom *com) { @@ -71,8 +71,8 @@ static void UpdateODCommand(GF_ISOFile *mp4, GF_ODCom *com) GF_MuxInfo *mi = (GF_MuxInfo *) gf_odf_desc_new(GF_ODF_MUXINFO_TAG); gf_list_add(esd->extensionDescriptors, mi); sprintf(szPath, "%s#%d", szName, esd->ESID); - mi->file_name = strdup(szPath); - mi->streamFormat = strdup("MP4"); + mi->file_name = gf_strdup(szPath); + mi->streamFormat = gf_strdup("MP4"); } break; } @@ -108,8 +108,8 @@ static void UpdateODCommand(GF_ISOFile *mp4, GF_ODCom *com) GF_MuxInfo *mi = (GF_MuxInfo *) gf_odf_desc_new(GF_ODF_MUXINFO_TAG); gf_list_add(esd->extensionDescriptors, mi); sprintf(szPath, "%s#%d", szName, esd->ESID); - mi->file_name = strdup(szPath); - mi->streamFormat = strdup("MP4"); + mi->file_name = gf_strdup(szPath); + mi->streamFormat = gf_strdup("MP4"); } break; } @@ -132,7 +132,7 @@ static void mp4_report(GF_SceneLoader *load, GF_Err e, char *format, ...) #endif } -GF_Err gf_sm_load_run_isom(GF_SceneLoader *load) +static GF_Err gf_sm_load_run_isom(GF_SceneLoader *load) { GF_Err e; FILE *logs; @@ -140,8 +140,10 @@ GF_Err gf_sm_load_run_isom(GF_SceneLoader *load) GF_StreamContext *sc; GF_ESD *esd; GF_ODCodec *od_dec; +#ifndef GPAC_DISABLE_BIFS GF_BifsDecoder *bifs_dec; -#ifndef GPAC_DISABLE_SVG +#endif +#ifndef GPAC_DISABLE_LASER GF_LASeRCodec *lsr_dec; #endif @@ -149,10 +151,13 @@ GF_Err gf_sm_load_run_isom(GF_SceneLoader *load) nbBifs = nbLaser = 0; e = GF_OK; +#ifndef GPAC_DISABLE_BIFS bifs_dec = gf_bifs_decoder_new(load->scene_graph, 1); + gf_bifs_decoder_set_extraction_path(bifs_dec, load->localPath, load->fileName); +#endif od_dec = gf_odf_codec_new(); logs = NULL; -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER lsr_dec = gf_laser_decoder_new(load->scene_graph); #endif esd = NULL; @@ -193,6 +198,7 @@ GF_Err gf_sm_load_run_isom(GF_SceneLoader *load) /*we still need to reconfig the BIFS*/ if (esd->decoderConfig->streamType==GF_STREAM_SCENE) { +#ifndef GPAC_DISABLE_BIFS /*BIFS*/ if (esd->decoderConfig->objectTypeIndication<=2) { if (!esd->dependsOnESID && nbBifs && !i) @@ -206,9 +212,11 @@ GF_Err gf_sm_load_run_isom(GF_SceneLoader *load) if (e) goto exit; nbBifs++; } -#ifndef GPAC_DISABLE_SVG +#endif + +#ifndef GPAC_DISABLE_LASER /*LASER*/ - else if (esd->decoderConfig->objectTypeIndication==0x09) { + if (esd->decoderConfig->objectTypeIndication==0x09) { if (!esd->dependsOnESID && nbBifs && !i) mp4_report(load, GF_OK, "several scene namespaces used or improper scene dependencies in file - import may be incorrect"); e = gf_laser_decoder_configure_stream(lsr_dec, esd->ESID, esd->decoderConfig->decoderSpecificInfo->data, esd->decoderConfig->decoderSpecificInfo->dataLength); @@ -241,10 +249,12 @@ GF_Err gf_sm_load_run_isom(GF_SceneLoader *load) au = gf_sm_stream_au_new(sc, samp->DTS, ((Double)(s64) samp->DTS) / sc->timeScale, samp->IsRAP); if (esd->decoderConfig->streamType==GF_STREAM_SCENE) { +#ifndef GPAC_DISABLE_BIFS if (esd->decoderConfig->objectTypeIndication<=2) e = gf_bifs_decode_command_list(bifs_dec, esd->ESID, samp->data, samp->dataLength, au->commands); -#ifndef GPAC_DISABLE_SVG - else if (esd->decoderConfig->objectTypeIndication==0x09) +#endif +#ifndef GPAC_DISABLE_LASER + if (esd->decoderConfig->objectTypeIndication==0x09) e = gf_laser_decode_command_list(lsr_dec, esd->ESID, samp->data, samp->dataLength, au->commands); #endif } else { @@ -275,9 +285,11 @@ GF_Err gf_sm_load_run_isom(GF_SceneLoader *load) gf_isom_text_set_streaming_mode(load->isom, 0); exit: +#ifndef GPAC_DISABLE_BIFS gf_bifs_decoder_del(bifs_dec); +#endif gf_odf_codec_del(od_dec); -#ifndef GPAC_DISABLE_SVG +#ifndef GPAC_DISABLE_LASER gf_laser_decoder_del(lsr_dec); #endif if (esd) gf_odf_desc_del((GF_Descriptor *) esd); @@ -285,6 +297,16 @@ exit: return e; } +static void gf_sm_load_done_isom(GF_SceneLoader *load) +{ + /*nothing to do the file is not ours*/ +} + +static GF_Err gf_sm_isom_suspend(GF_SceneLoader *loader, Bool suspend) +{ + return GF_OK; +} + GF_Err gf_sm_load_init_isom(GF_SceneLoader *load) { u32 i, track; @@ -356,13 +378,10 @@ GF_Err gf_sm_load_init_isom(GF_SceneLoader *load) gf_odf_desc_del((GF_Descriptor *) esd); esd = NULL; + load->process = gf_sm_load_run_isom; + load->done = gf_sm_load_done_isom; + load->suspend = gf_sm_isom_suspend; return GF_OK; } -void gf_sm_load_done_isom(GF_SceneLoader *load) -{ - /*nothing to do the file is not ours*/ - -} - -#endif +#endif /*GPAC_DISABLE_LOADER_ISOM*/ diff --git a/src/scene_manager/loader_qt.c b/src/scene_manager/loader_qt.c index 0698f79..c7dd13b 100644 --- a/src/scene_manager/loader_qt.c +++ b/src/scene_manager/loader_qt.c @@ -26,11 +26,12 @@ #include #include -#ifndef GPAC_READ_ONLY +#if !defined(GPAC_DISABLE_QTVR) #include + static GF_Err gf_qt_report(GF_SceneLoader *load, GF_Err e, char *format, ...) { #ifndef GPAC_DISABLE_LOG @@ -86,8 +87,8 @@ GF_Err gf_sm_load_init_qt(GF_SceneLoader *load) tk = i+1; nb_samp = gf_isom_get_sample_count(src, i+1); } - if (udesc->extension_buf) free(udesc->extension_buf); - free(udesc); + if (udesc->extension_buf) gf_free(udesc->extension_buf); + gf_free(udesc); } break; case GF_4CC('q','t','v','r'): @@ -142,7 +143,7 @@ GF_Err gf_sm_load_init_qt(GF_SceneLoader *load) gf_node_register((GF_Node *)ni, (GF_Node *)gr); gf_sg_vrml_mf_reset(&ni->type, GF_SG_VRML_MFSTRING); gf_sg_vrml_mf_alloc(&ni->type, GF_SG_VRML_MFSTRING, 1); - ni->type.vals[0] = strdup("QTVR"); + ni->type.vals[0] = gf_strdup("QTVR"); /*create ODs*/ st = gf_sm_stream_new(load->ctx, 2, GF_STREAM_OD, 1); @@ -157,20 +158,20 @@ GF_Err gf_sm_load_init_qt(GF_SceneLoader *load) od->objectDescriptorID = 2+i; esd = gf_odf_desc_esd_new(2); esd->decoderConfig->streamType = GF_STREAM_VISUAL; - esd->decoderConfig->objectTypeIndication = 0x6C; + esd->decoderConfig->objectTypeIndication = GPAC_OTI_IMAGE_JPEG; esd->ESID = 3+i; /*extract image and remember it*/ mi = (GF_MuxInfo *) gf_odf_desc_new(GF_ODF_MUXINFO_TAG); gf_list_add(esd->extensionDescriptors, mi); mi->delete_file = 1; sprintf(szName, "%s_img%d.jpg", load->fileName, esd->ESID); - mi->file_name = strdup(szName); + mi->file_name = gf_strdup(szName); gf_list_add(od->ESDescriptors, esd); gf_list_add(odU->objectDescriptors, od); samp = gf_isom_get_sample(src, tk, i+1, &di); - img = fopen(mi->file_name, "wb"); + img = gf_f64_open(mi->file_name, "wb"); fwrite(samp->data, samp->dataLength, 1, img); fclose(img); gf_isom_sample_del(&samp); @@ -179,12 +180,4 @@ GF_Err gf_sm_load_init_qt(GF_SceneLoader *load) return GF_OK; } -void gf_sm_load_done_qt(GF_SceneLoader *load) -{ -} -GF_Err gf_sm_load_run_qt(GF_SceneLoader *load) -{ - return GF_OK; -} - -#endif +#endif /*GPAC_DISABLE_QTVR*/ diff --git a/src/scene_manager/loader_svg.c b/src/scene_manager/loader_svg.c index c09c41f..ab6ff04 100644 --- a/src/scene_manager/loader_svg.c +++ b/src/scene_manager/loader_svg.c @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -67,7 +68,8 @@ typedef struct GF_StreamContext *laser_es; GF_AUContext *laser_au; GF_Command *command; - /*SAF AU maps to OD AU and is used for each new media declaration*/ + + /*SAF AU maps to OD AU and is used for each new media declaration*/ GF_AUContext *saf_au; GF_StreamContext *saf_es; @@ -136,17 +138,23 @@ static GF_Err svg_report(GF_SVG_Parser *parser, GF_Err e, char *format, ...) GF_LOG((u32) (e ? GF_LOG_ERROR : GF_LOG_WARNING), GF_LOG_PARSER, ("[SVG Parsing] line %d - %s\n", gf_xml_sax_get_line(parser->sax_parser), szMsg)); } #endif - if (e) parser->last_error = e; + if (e) { + parser->last_error = e; + gf_xml_sax_suspend(parser->sax_parser, 1); + } return e; } -static void svg_progress(void *cbk, u32 done, u32 total) +static void svg_progress(void *cbk, u64 done, u64 total) { GF_SVG_Parser *parser = (GF_SVG_Parser *)cbk; - if (parser->load && parser->load->is && parser->load->is->scene_codec && parser->load->is->scene_codec->odm) { - gf_term_service_media_event(parser->load->is->scene_codec->odm, GF_EVENT_MEDIA_DATA_PROGRESS); - if (done == total) - gf_term_service_media_event(parser->load->is->scene_codec->odm, GF_EVENT_MEDIA_END_OF_DATA); + + /*notify MediaEvent*/ + if (parser->load && parser->load->is) { + parser->load->is->on_media_event(parser->load->is, GF_EVENT_MEDIA_DATA_PROGRESS); + if (done == total) { + parser->load->is->on_media_event(parser->load->is, GF_EVENT_MEDIA_END_OF_DATA); + } } gf_set_progress("SVG (Dynamic Attribute List) Parsing", done, total); } @@ -199,14 +207,82 @@ static void svg_lsr_set_v2(GF_SVG_Parser *parser) } -static void svg_process_media_href(GF_SVG_Parser *parser, XMLRI *iri) +static void svg_process_media_href(GF_SVG_Parser *parser, GF_Node *elt, XMLRI *iri) { - SVG_SAFExternalStream *st = svg_saf_get_stream(parser, 0, iri->string+1); - if (st) { - free(iri->string); - iri->string = NULL; - iri->lsr_stream_id = st->id; - iri->type = XMLRI_STREAMID; + u32 tag = gf_node_get_tag(elt); + + if ((tag==TAG_SVG_image) || (tag==TAG_SVG_video) || (tag==TAG_SVG_audio)) { + SVG_SAFExternalStream *st = svg_saf_get_stream(parser, 0, iri->string+1); + if (st) { + gf_free(iri->string); + iri->string = NULL; + iri->lsr_stream_id = st->id; + iri->type = XMLRI_STREAMID; + return; + } + } + if ((parser->load->flags & GF_SM_LOAD_EMBEDS_RES) && (iri->type==XMLRI_STRING) ) { + u64 size; + char *buffer; + FILE *f; + f = gf_f64_open(iri->string, "rb"); + if (!f) { + return; + } + gf_f64_seek(f, 0, SEEK_END); + size = gf_f64_tell(f); + gf_f64_seek(f, 0, SEEK_SET); + + buffer = gf_malloc(sizeof(char) * (size_t)(size+1)); + size = fread(buffer, sizeof(char), (size_t)size, f); + fclose(f); + + + if (tag==TAG_SVG_script) { + GF_DOMText *dtext; + GF_DOMAttribute *att, *prev; + buffer[size]=0; + dtext = gf_dom_add_text_node(elt, buffer); + dtext->type = GF_DOM_TEXT_CDATA; + + gf_free(iri->string); + iri->string=NULL; + + /*delete attribute*/ + att = ((GF_DOMNode*)elt)->attributes; + prev = NULL; + while(att) { + if (att->tag!=TAG_XLINK_ATT_href) { + prev = att; + att = att->next; + continue; + } + gf_svg_delete_attribute_value(att->data_type, att->data, elt->sgprivate->scenegraph); + if (prev) prev->next = att->next; + else ((GF_DOMNode*)elt)->attributes = att->next; + gf_free(att); + break; + } + } else { + char *mtype; + char *buf64; + u64 size64; + char *ext; + buf64 = gf_malloc((size_t)size*2); + size64 = gf_base64_encode(buffer, (u32)size, buf64, (u32)size*2); + buf64[size64] = 0; + mtype = "application/data"; + ext = strchr(iri->string, '.'); + if (ext) { + if (!stricmp(ext, ".png")) mtype = "image/png"; + if (!stricmp(ext, ".jpg") || !stricmp(ext, ".jpeg")) mtype = "image/jpg"; + } + gf_free(iri->string); + iri->string = gf_malloc(sizeof(char)*(40+(size_t)size64)); + sprintf(iri->string, "data:%s;base64,%s", mtype, buf64); + gf_free(buf64); + gf_free(buffer); + } } } @@ -235,7 +311,7 @@ static GF_Node *svg_find_node(GF_SVG_Parser *parser, char *ID) tag = gf_xml_get_element_tag(node_class, parser->current_ns); n = gf_node_new(parser->load->scene_graph, tag); - free(node_class); + gf_free(node_class); if (n) { gf_svg_parse_element_id(n, ID, 0); @@ -263,13 +339,13 @@ static void svg_delete_defered_anim(SVG_DeferedAnimation *anim, GF_List *defered { if (defered_animations) gf_list_del_item(defered_animations, anim); - if (anim->target_id) free(anim->target_id); - if (anim->to) free(anim->to); - if (anim->from) free(anim->from); - if (anim->by) free(anim->by); - if (anim->values) free(anim->values); - if (anim->type) free(anim->type); - free(anim); + if (anim->target_id) gf_free(anim->target_id); + if (anim->to) gf_free(anim->to); + if (anim->from) gf_free(anim->from); + if (anim->by) gf_free(anim->by); + if (anim->values) gf_free(anim->values); + if (anim->type) gf_free(anim->type); + gf_free(anim); } static Bool svg_parse_animation(GF_SVG_Parser *parser, GF_SceneGraph *sg, SVG_DeferedAnimation *anim, const char *nodeID, u32 force_type) @@ -335,8 +411,8 @@ static Bool svg_parse_animation(GF_SVG_Parser *parser, GF_SceneGraph *sg, SVG_De sep[0] = 0; attname->type = gf_sg_get_namespace_code(anim->animation_elt->sgprivate->scenegraph, name); sep[0] = ':'; - name = strdup(sep+1); - free(attname->name); + name = gf_strdup(sep+1); + gf_free(attname->name); attname->name = name; } else { attname->type = parser->current_ns; @@ -443,7 +519,7 @@ static void svg_resolved_refs(GF_SVG_Parser *parser, GF_SceneGraph *sg, const ch iri->type = XMLRI_ELEMENTID; iri->target = targ; gf_node_register_iri(sg, iri); - free(iri->string); + gf_free(iri->string); iri->string = NULL; gf_list_rem(parser->defered_hrefs, i); i--; @@ -526,11 +602,11 @@ static void svg_init_root_element(GF_SVG_Parser *parser, SVG_Element *root_svg) //#define SKIP_ALL //#define SKIP_ATTS +//#define SKIP_ATTS_PARSING //#define SKIP_INIT //#define SKIP_UNKNOWN_NODES - static SVG_Element *svg_parse_element(GF_SVG_Parser *parser, const char *name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes, SVG_NodeStack *parent, Bool *has_ns) { GF_FieldInfo info; @@ -609,7 +685,7 @@ static SVG_Element *svg_parse_element(GF_SVG_Parser *parser, const char *name, c } if (tag == TAG_DOMFullNode) { GF_DOMFullNode *d = (GF_DOMFullNode *)elt; - d->name = strdup(name); + d->name = gf_strdup(name); d->ns = xmlns; } } @@ -683,23 +759,23 @@ static SVG_Element *svg_parse_element(GF_SVG_Parser *parser, const char *name, c } if (anim) { if (!stricmp(att_name, "to")) { - anim->to = strdup(att->value); + anim->to = gf_strdup(att->value); continue; } if (!stricmp(att_name, "from")) { - anim->from = strdup(att->value); + anim->from = gf_strdup(att->value); continue; } if (!stricmp(att_name, "by")) { - anim->by = strdup(att->value); + anim->by = gf_strdup(att->value); continue; } if (!stricmp(att_name, "values")) { - anim->values = strdup(att->value); + anim->values = gf_strdup(att->value); continue; } if ((tag == TAG_SVG_animateTransform) && !stricmp(att_name, "type")) { - anim->type = strdup(att->value); + anim->type = gf_strdup(att->value); continue; } } @@ -707,7 +783,7 @@ static SVG_Element *svg_parse_element(GF_SVG_Parser *parser, const char *name, c if ((ns == GF_XMLNS_XLINK) && !stricmp(att_name, "href") ) { if (gf_svg_is_animation_tag(tag)) { assert(anim); - anim->target_id = strdup(att->value); + anim->target_id = gf_strdup(att->value); /*may be NULL*/ anim->target = (SVG_Element *) gf_sg_find_node_by_name(parser->load->scene_graph, anim->target_id + 1); continue; @@ -717,9 +793,9 @@ static SVG_Element *svg_parse_element(GF_SVG_Parser *parser, const char *name, c if (gf_node_get_attribute_by_tag((GF_Node *)elt, TAG_XLINK_ATT_href, 1, 0, &info)==GF_OK) { gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0); iri = info.far_ptr; - if ((tag==TAG_SVG_image) || (tag==TAG_SVG_video) || (tag==TAG_SVG_audio)) { - svg_process_media_href(parser, iri); - } + + svg_process_media_href(parser, (GF_Node *)elt, iri); + svg_post_process_href(parser, iri); continue; } @@ -762,13 +838,14 @@ static SVG_Element *svg_parse_element(GF_SVG_Parser *parser, const char *name, c u32 evtType = gf_dom_event_type_by_name(att_name + 2); if (evtType != GF_EVENT_UNKNOWN) { SVG_handlerElement *handler = gf_dom_listener_build((GF_Node *) elt, evtType, 0); - gf_dom_add_text_node((GF_Node *)handler, strdup(att->value) ); + gf_dom_add_text_node((GF_Node *)handler, gf_strdup(att->value) ); continue; } svg_report(parser, GF_OK, "Skipping unknown event handler %s on node %s", att->name, name); } if (gf_node_get_attribute_by_name((GF_Node *)elt, att_name, ns, 1, 0, &info)==GF_OK) { +#ifndef SKIP_ATTS_PARSING GF_Err e = gf_svg_parse_attribute((GF_Node *)elt, &info, att->value, 0); if (e) { svg_report(parser, e, "Error parsing attribute %s on node %s", att->name, name); @@ -797,6 +874,7 @@ static SVG_Element *svg_parse_element(GF_SVG_Parser *parser, const char *name, c break; } } +#endif continue; } svg_report(parser, GF_OK, "Skipping attribute %s on node %s", att->name, name); @@ -813,8 +891,10 @@ static SVG_Element *svg_parse_element(GF_SVG_Parser *parser, const char *name, c u32 type; GF_FieldInfo info; listener = (SVG_Element *) gf_node_new(node->sgprivate->scenegraph, TAG_SVG_listener); - /*do not register the listener, this will be done in gf_node_dom_listener_add. We don't want to - insert the implicit listener in the DOM*/ + /*We don't want to insert the implicit listener in the DOM. However remember + the listener at the handler level in case the handler gets destroyed*/ + gf_node_set_private(node, (GF_Node*)listener ); + gf_node_register((GF_Node*)listener, NULL); /* this listener listens to the given type of event */ type = gf_dom_event_type_by_name(ev_event); @@ -1006,7 +1086,7 @@ static GF_Err lsr_parse_command(GF_SVG_Parser *parser, const GF_XMLAttribute *at gf_node_register(parser->command->node, NULL); if (atValue) { field->field_ptr = gf_svg_create_attribute_value(field->fieldType); - *(SVG_String *)field->field_ptr = strdup(atValue); + *(SVG_String *)field->field_ptr = gf_strdup(atValue); } return GF_OK; } @@ -1025,12 +1105,16 @@ static GF_Err lsr_parse_command(GF_SVG_Parser *parser, const GF_XMLAttribute *at } } else { /*FIXME - handle namespace properly here !!*/ - info.fieldIndex = gf_xml_get_attribute_tag(parser->command->node, atAtt, parser->current_ns); + info.fieldIndex = gf_xml_get_attribute_tag(parser->command->node, atAtt, (strchr(atAtt, ':')==NULL) ? parser->current_ns : 0); info.fieldType = gf_xml_get_attribute_type(info.fieldIndex); +#ifndef GPAC_DISABLE_LASER +/* if (gf_lsr_anim_type_from_attribute(info.fieldIndex)<0) { return svg_report(parser, GF_BAD_PARAM, "Attribute %s of element %s is not updatable\n", atAtt, gf_node_get_class_name(parser->command->node)); } +*/ +#endif /*GPAC_DISABLE_LASER*/ } opNode = NULL; @@ -1047,7 +1131,11 @@ static GF_Err lsr_parse_command(GF_SVG_Parser *parser, const GF_XMLAttribute *at GF_FieldInfo nf; nf.fieldType = info.fieldType; field->field_ptr = nf.far_ptr = gf_svg_create_attribute_value(info.fieldType); - if (field->field_ptr) gf_svg_parse_attribute(parser->command->node, &nf, atValue, (u8) info.fieldType); + if (field->field_ptr) { + gf_svg_parse_attribute(parser->command->node, &nf, atValue, (u8) info.fieldType); + if (info.fieldType==XMLRI_datatype) + svg_process_media_href(parser, parser->command->node, (XMLRI*)field->field_ptr); + } } else if (opNode) { parser->command->fromNodeID = gf_node_get_id(opNode); /*FIXME - handle namespace properly here !!*/ @@ -1096,7 +1184,7 @@ static GF_Err lsr_parse_command(GF_SVG_Parser *parser, const GF_XMLAttribute *at if (atString) { u32 key = gf_dom_get_key_type(atString); if (key == GF_KEY_UNIDENTIFIED) { - parser->command->send_event_string = strdup(atString); + parser->command->send_event_string = gf_strdup(atString); } else { parser->command->send_event_integer = key; } @@ -1185,8 +1273,26 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp parent = NULL; } + /* If the loader was created with the DIMS type and this is the root element, restore the stream and AU + context - in DIMS? we only have one stream an dcommands are stacked in the last AU of the stream*/ + if (!parent && (parser->load->type == GF_SM_LOAD_DIMS) && parser->load->ctx) { + + /*if not created, do it now*/ + if (!gf_list_count(parser->load->ctx->streams)) { + parser->laser_es = gf_sm_stream_new(parser->load->ctx, 1, GF_STREAM_SCENE, GPAC_OTI_SCENE_DIMS); + parser->laser_es->timeScale = 1000; + /* Create a default AU to behave as other streams (LASeR, BIFS) + but it is left empty, there is no notion of REPLACE Scene or NEw Scene, + the RAP is the graph */ + parser->laser_au = gf_sm_stream_au_new(parser->laser_es, 0, 0, 1); + } else { + parser->laser_es = gf_list_get(parser->load->ctx->streams, 0); + parser->laser_au = gf_list_last(parser->laser_es->AUs); + } + } + /*saf setup*/ - if ((!parent && (parser->load->type!=GF_SM_LOAD_SVG_DA)) || cond) { + if ((!parent && (parser->load->type!=GF_SM_LOAD_SVG)) || cond) { u32 com_type; /*nothing to do, the context is already created*/ if (!strcmp(name, "SAFSession")) return; @@ -1236,7 +1342,7 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp esd->ESID = 0xFFFE; esd->decoderConfig->streamType = GF_STREAM_OD; esd->decoderConfig->objectTypeIndication = 1; - parser->saf_es = gf_sm_stream_new(parser->load->ctx, esd->ESID, GF_STREAM_OD, 1); + parser->saf_es = gf_sm_stream_new(parser->load->ctx, esd->ESID, GF_STREAM_OD, GPAC_OTI_OD_V1); if (!parser->load->ctx->root_od) parser->load->ctx->root_od = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_IOD_TAG); parser->saf_es->timeScale = 1000; gf_list_add(parser->load->ctx->root_od->ESDescriptors, esd); @@ -1249,7 +1355,7 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp GF_XMLAttribute *att = (GF_XMLAttribute *) &attributes[i]; if (!strcmp(att->name, "time")) time = atoi(att->value); else if (!strcmp(att->name, "rap")) rap = !strcmp(att->value, "yes") ? 1 : 0; - else if (!strcmp(att->name, "url")) url = strdup(att->value); + else if (!strcmp(att->name, "url")) url = gf_strdup(att->value); else if (!strcmp(att->name, "streamID")) ID = att->value; else if (!strcmp(att->name, "objectTypeIndication")) OTI = atoi(att->value); else if (!strcmp(att->name, "streamType")) ST = atoi(att->value); @@ -1261,7 +1367,7 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp /*create new SAF stream*/ st = svg_saf_get_next_available_stream(parser); - st->stream_name = strdup(ID); + st->stream_name = gf_strdup(ID); /*create new SAF unit*/ parser->saf_au = gf_sm_stream_au_new(parser->saf_es, time, 0, 0); @@ -1288,7 +1394,7 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp /*global source for stream, don't use nhml dumping*/ if (src) { - mux->file_name = strdup(src); + mux->file_name = gf_strdup(src); st->nhml_info = NULL; } else { if (parser->load->localPath) { @@ -1298,9 +1404,9 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp strcpy(szName, ID); } strcat(szName, "_temp.nhml"); - mux->file_name = strdup(szName); + mux->file_name = gf_strdup(szName); st->nhml_info = mux->file_name; - nhml = fopen(st->nhml_info, "wt"); + nhml = gf_f64_open(st->nhml_info, "wt"); fprintf(nhml, "\n"); fprintf(nhml, "\n", ts_res, ST, OTI, st->id); fclose(nhml); @@ -1329,7 +1435,7 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp if (!st || !st->nhml_info) { return; } - nhml = fopen(st->nhml_info, "a+t"); + nhml = gf_f64_open(st->nhml_info, "a+t"); fprintf(nhml, "nhml_info) { return; } - nhml = fopen(st->nhml_info, "a+t"); + nhml = gf_f64_open(st->nhml_info, "a+t"); fprintf(nhml, "\n"); fclose(nhml); return; @@ -1362,9 +1468,15 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp if (!strcmp(name, "endOfSAFSession") ) { return; } + if ((parser->load->type==GF_SM_LOAD_XSR) && !parser->laser_au && !cond) { - svg_report(parser, GF_BAD_PARAM, "LASeR Scene unit not defined for command %s", name); - return; + if (parser->load->flags & GF_SM_LOAD_CONTEXT_READY) { + assert(parser->laser_es); + parser->laser_au = gf_sm_stream_au_new(parser->laser_es, 0, 0, 0); + } else { + svg_report(parser, GF_BAD_PARAM, "LASeR sceneUnit not defined for command %s", name); + return; + } } /*command parsing*/ com_type = lsr_get_command_by_name(name); @@ -1372,6 +1484,23 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp SVG_NodeStack *top; GF_Err e; parser->command = gf_sg_command_new(parser->load->scene_graph, com_type); + + /*this is likely a conditional start - update unknown depth level*/ + top = (SVG_NodeStack*)gf_list_last(parser->node_stack); + if (top) { + top->unknown_depth ++; + parser->command_depth++; + } + + e = lsr_parse_command(parser, attributes, nb_attributes); + if (e!= GF_OK) { + parser->command->node = NULL; + gf_sg_command_del(parser->command); + parser->command = NULL; + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[LASeR Parser] Error parsing %s command - skipping\n", (parser->load->type==GF_SM_LOAD_XSR) ? "LASeR" : "DIMS")); + return; + } + if (cond) { GF_DOMUpdates *up = cond->children ? (GF_DOMUpdates *)cond->children->node : NULL; if (!up) { @@ -1385,16 +1514,13 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp } else if (parser->laser_au) { gf_list_add(parser->laser_au->commands, parser->command); } - /*this is likely a conditional start - update unknown depth level*/ - top = (SVG_NodeStack*)gf_list_last(parser->node_stack); - if (top) { - top->unknown_depth ++; - parser->command_depth++; + switch (com_type) { + case GF_SG_LSR_NEW_SCENE: + case GF_SG_LSR_REFRESH_SCENE: + parser->laser_au->flags |= GF_SM_AU_RAP; + break; } - e = lsr_parse_command(parser, attributes, nb_attributes); - if (e!= GF_OK) parser->command->node = NULL; - return; } } @@ -1457,7 +1583,7 @@ static void svg_node_start(void *sax_cbck, const char *name, const char *name_sp } } else if (!parser->has_root ) { gf_list_del_item(parser->node_stack, stack); - free(stack); + gf_free(stack); gf_node_unregister((GF_Node *)elt, NULL); } else if ((parser->has_root==2) && !parser->fragment_root) { parser->fragment_root = (GF_Node *)elt; @@ -1482,7 +1608,7 @@ static void svg_node_end(void *sax_cbck, const char *name, const char *name_spac if (parser->command) { u32 com_type = lsr_get_command_by_name(name); if (com_type == parser->command->tag) { - if (parser->load->type==GF_SM_LOAD_DIMS) { + if (parser->load->type==GF_SM_LOAD_DIMS && parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK) { gf_sg_command_apply(parser->load->scene_graph, parser->command, 0); gf_sg_command_del(parser->command); } @@ -1517,13 +1643,13 @@ static void svg_node_end(void *sax_cbck, const char *name, const char *name_spac top->unknown_depth--; return; } else { - svg_report(parser, GF_BAD_PARAM, "SVG depth mismatch"); + svg_report(parser, GF_BAD_PARAM, "SVG depth mismatch: expecting got ", the_name, name); return; } } parser->current_ns = top->current_ns; if (top->has_ns) gf_xml_pop_namespaces(top->node); - free(top); + gf_free(top); gf_list_rem_last(parser->node_stack); if (parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK) { @@ -1558,8 +1684,7 @@ static void svg_node_end(void *sax_cbck, const char *name, const char *name_spac break; } /*if we have associated event listeners, trigger the onLoad, only in playback mode */ - if ((parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK) && - (node->sgprivate->interact && node->sgprivate->interact->dom_evt)) { + if (node->sgprivate->interact && node->sgprivate->interact->dom_evt) { GF_DOM_Event evt; memset(&evt, 0, sizeof(GF_DOM_Event)); evt.type = GF_EVENT_LOAD; @@ -1622,7 +1747,7 @@ static void svg_text_content(void *sax_cbck, const char *text_content, Bool is_c /*create a text node but don't register it with any node*/ text = gf_dom_new_text_node(parser->load->scene_graph); gf_node_register((GF_Node *)text, NULL); - text->textContent = strdup(text_content); + text->textContent = gf_strdup(text_content); if (field->new_node) { field->field_ptr = &field->node_list; @@ -1665,7 +1790,7 @@ static void svg_text_content(void *sax_cbck, const char *text_content, Bool is_c } if (!skip_text) { - text = gf_dom_add_text_node((GF_Node *)elt, strdup(text_content)); + text = gf_dom_add_text_node((GF_Node *)elt, gf_strdup(text_content)); text->type = is_cdata ? GF_DOM_TEXT_CDATA : GF_DOM_TEXT_REGULAR; gf_node_changed((GF_Node *)text, NULL); } @@ -1678,7 +1803,7 @@ static GF_SVG_Parser *svg_new_parser(GF_SceneLoader *load) case GF_SM_LOAD_XSR: if (!load->ctx) return NULL; break; - case GF_SM_LOAD_SVG_DA: + case GF_SM_LOAD_SVG: case GF_SM_LOAD_DIMS: break; default: @@ -1717,7 +1842,7 @@ static void gf_sm_svg_flush_state(GF_SVG_Parser *parser) while (gf_list_count(parser->node_stack)) { SVG_NodeStack *st = (SVG_NodeStack *)gf_list_last(parser->node_stack); gf_list_rem_last(parser->node_stack); - free(st); + gf_free(st); } /*FIXME - if there still are som defered listeners, we should pass them to the scene graph and wait for the parent to be defined*/ @@ -1730,19 +1855,76 @@ static void gf_sm_svg_flush_state(GF_SVG_Parser *parser) } } -GF_Err gf_sm_load_init_svg(GF_SceneLoader *load) +static GF_Err gf_sm_load_initialize_svg(GF_SceneLoader *load, char *str_data, Bool is_fragment) { GF_Err e; GF_SVG_Parser *parser; - u32 in_time; - if (!load->fileName) return GF_BAD_PARAM; - parser = svg_new_parser(load); - if (!parser) return GF_BAD_PARAM; + if (str_data) { + char BOM[6]; + BOM[0] = str_data[0]; + BOM[1] = str_data[1]; + BOM[2] = str_data[2]; + BOM[3] = str_data[3]; + BOM[4] = BOM[5] = 0; + parser = svg_new_parser(load); + if (!parser) return GF_BAD_PARAM; + + if (is_fragment) parser->has_root = 2; + e = gf_xml_sax_init(parser->sax_parser, (unsigned char*)BOM); + if (e) { + svg_report(parser, e, "Error initializing SAX parser: %s", gf_xml_sax_get_error(parser->sax_parser) ); + return e; + } + str_data += 4; + + } else if (load->fileName) { + parser = svg_new_parser(load); + if (!parser) return GF_BAD_PARAM; + } else { + return GF_BAD_PARAM; + } + /*chunk parsing*/ + if (load->flags & GF_SM_LOAD_CONTEXT_READY) { + u32 i; + GF_StreamContext *sc; + if (!load->ctx) return GF_BAD_PARAM; + + /*restore context - note that base layer are ALWAYS declared BEFORE enhancement layers with gpac parsers*/ + i=0; + while ((sc = (GF_StreamContext*)gf_list_enum(load->ctx->streams, &i))) { + switch (sc->streamType) { + case GF_STREAM_SCENE: if (!parser->laser_es) parser->laser_es = sc; break; + default: break; + } + } + /*need at least one scene stream - FIXME - accept SVG as root? */ + if (!parser->laser_es) return GF_BAD_PARAM; + GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("SVG: MPEG-4 LASeR / DIMS Scene Chunk Parsing")); + } else { + GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("[Parser] %s Scene Parsing: %s\n", ((load->type==GF_SM_LOAD_SVG) ? "SVG" : ((load->type==GF_SM_LOAD_XSR) ? "LASeR" : "DIMS")), load->fileName)); + } - GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("[Parser] %s Scene Parsing: %s\n", ((load->type==GF_SM_LOAD_SVG_DA) ? "SVG" : ((load->type==GF_SM_LOAD_XSR) ? "LASeR" : "DIMS")), load->fileName)); + if (str_data) + return gf_xml_sax_parse(parser->sax_parser, str_data); + return GF_OK; +} + + +GF_Err load_svg_run(GF_SceneLoader *load) +{ + u32 in_time; + GF_Err e; + GF_SVG_Parser *parser = (GF_SVG_Parser *)load->loader_priv; + + if (!parser) { + e = gf_sm_load_initialize_svg(load, NULL, 0); + if (e) return e; + parser = (GF_SVG_Parser *)load->loader_priv; + } + in_time = gf_sys_clock(); e = gf_xml_sax_parse_file(parser->sax_parser, (const char *)load->fileName, svg_progress); if (e<0) return svg_report(parser, e, "Unable to parse file %s: %s", load->fileName, gf_xml_sax_get_error(parser->sax_parser) ); @@ -1750,50 +1932,33 @@ GF_Err gf_sm_load_init_svg(GF_SceneLoader *load) svg_flush_animations(parser); gf_sm_svg_flush_state(parser); + return e; - return parser->last_error; -} - - -GF_Err gf_sm_load_run_svg(GF_SceneLoader *load) -{ - return GF_EOS; } -static GF_Err gf_sm_load_init_svg_string_ex(GF_SceneLoader *load, char *str_data, Bool is_fragment) +GF_Err load_svg_parse_string(GF_SceneLoader *load, char *str) { GF_Err e; GF_SVG_Parser *parser = (GF_SVG_Parser *)load->loader_priv; if (!parser) { - char BOM[6]; - BOM[0] = str_data[0]; - BOM[1] = str_data[1]; - BOM[2] = str_data[2]; - BOM[3] = str_data[3]; - BOM[4] = BOM[5] = 0; - parser = svg_new_parser(load); - if (is_fragment) parser->has_root = 2; - e = gf_xml_sax_init(parser->sax_parser, (unsigned char*)BOM); - if (e) { - svg_report(parser, e, "Error initializing SAX parser: %s", gf_xml_sax_get_error(parser->sax_parser) ); - return e; - } - str_data += 4; + e = gf_sm_load_initialize_svg(load, str, 0); + parser = (GF_SVG_Parser *)load->loader_priv; + } else { + e = gf_xml_sax_parse(parser->sax_parser, str); } - return gf_xml_sax_parse(parser->sax_parser, str_data); -} + if (e<0) return svg_report(parser, e, "Unable to parse chunk: %s", gf_xml_sax_get_error(parser->sax_parser) ); -GF_Err gf_sm_load_init_svg_string(GF_SceneLoader *load, char *str_data) -{ - return gf_sm_load_init_svg_string_ex(load, str_data, 0); + svg_flush_animations(parser); + return e; } -GF_Err gf_sm_load_done_svg(GF_SceneLoader *load) + +static void load_svg_done(GF_SceneLoader *load) { SVG_SAFExternalStream *st; GF_SVG_Parser *parser = (GF_SVG_Parser *)load->loader_priv; - if (!parser) return GF_OK; + if (!parser) return; gf_sm_svg_flush_state(parser); @@ -1809,30 +1974,58 @@ GF_Err gf_sm_load_done_svg(GF_SceneLoader *load) st = parser->streams; while (st) { SVG_SAFExternalStream *next = st->next; - free(st->stream_name); - free(st); + gf_free(st->stream_name); + gf_free(st); st = next; } - free(parser); + gf_free(parser); load->loader_priv = NULL; +} + + +static GF_Err load_svg_suspend(GF_SceneLoader *load, Bool suspend) +{ + GF_SVG_Parser *parser = (GF_SVG_Parser *)load->loader_priv; + if (parser) gf_xml_sax_suspend(parser->sax_parser, suspend); + return GF_OK; +} + + +GF_Err gf_sm_load_init_svg(GF_SceneLoader *load) +{ + load->process = load_svg_run; + load->done = load_svg_done; + load->parse_string = load_svg_parse_string; + load->suspend = load_svg_suspend; return GF_OK; + } GF_Node *gf_sm_load_svg_from_string(GF_SceneGraph *in_scene, char *node_str) { + GF_Err e; GF_SVG_Parser *parser; GF_Node *node; GF_SceneLoader ctx; memset(&ctx, 0, sizeof(GF_SceneLoader)); ctx.scene_graph = in_scene; - ctx.type = GF_SM_LOAD_SVG_DA; - gf_sm_load_init_svg_string_ex(&ctx, node_str, 1); + ctx.type = GF_SM_LOAD_SVG; + + e = gf_sm_load_initialize_svg(&ctx, node_str, 1); parser = (GF_SVG_Parser *)ctx.loader_priv; node = parser->fragment_root; + + if (e != GF_OK) { + if (parser->fragment_root) gf_node_unregister(parser->fragment_root, NULL); + parser->fragment_root=NULL; + load_svg_done(&ctx); + return NULL; + } + /*don't register*/ if (node) node->sgprivate->num_instances--; - gf_sm_load_done_svg(&ctx); + load_svg_done(&ctx); return node; } diff --git a/src/scene_manager/loader_xmt.c b/src/scene_manager/loader_xmt.c index e1170be..3dc3a71 100644 --- a/src/scene_manager/loader_xmt.c +++ b/src/scene_manager/loader_xmt.c @@ -30,6 +30,9 @@ #include #include +#ifndef GPAC_DISABLE_LOADER_XMT + + /*for QP types*/ #include "../bifs/quant.h" @@ -146,7 +149,7 @@ static GF_Err xmt_report(GF_XMTParser *parser, GF_Err e, char *format, ...) if (e) parser->last_error = e; return e; } -static void xmt_progress(void *cbk, u32 done, u32 total) +static void xmt_progress(void *cbk, u64 done, u64 total) { gf_set_progress("XMT Parsing", done, total); } @@ -161,6 +164,17 @@ static Bool xmt_esid_available(GF_XMTParser *parser, u16 ESID) return 1; } +static char *xmt_get_es_name(GF_XMTParser *parser, u16 ESID) +{ + u32 i; + XMT_ESDLink *esdl; + i=0; + while ((esdl = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) { + if (esdl->esd->ESID == ESID) return esdl->desc_name; + } + return NULL; +} + static void xmt_new_od_link(GF_XMTParser *parser, GF_ObjectDescriptor *od, char *name, u32 ID) { u32 i, j, count; @@ -189,7 +203,7 @@ static void xmt_new_od_link(GF_XMTParser *parser, GF_ObjectDescriptor *od, char || (odl->desc_name && name && !strcmp(odl->desc_name, name)) ) { if (!odl->od) odl->od = od; - if (!odl->desc_name && name) odl->desc_name = strdup(name); + if (!odl->desc_name && name) odl->desc_name = gf_strdup(name); if (!od->objectDescriptorID) { od->objectDescriptorID = ID; } else if (ID && (od->objectDescriptorID != ID)) { @@ -201,9 +215,9 @@ static void xmt_new_od_link(GF_XMTParser *parser, GF_ObjectDescriptor *od, char if (l2->od == od) { odl->ID = od->objectDescriptorID = odl->od->objectDescriptorID; gf_list_rem(parser->od_links, j); - if (l2->desc_name) free(l2->desc_name); + if (l2->desc_name) gf_free(l2->desc_name); gf_list_del(l2->mf_urls); - free(l2); + gf_free(l2); break; } } @@ -214,7 +228,7 @@ static void xmt_new_od_link(GF_XMTParser *parser, GF_ObjectDescriptor *od, char odl->mf_urls = gf_list_new(); odl->od = od; if (ID) od->objectDescriptorID = ID; - if (name) odl->desc_name = strdup(name); + if (name) odl->desc_name = gf_strdup(name); gf_list_add(parser->od_links, odl); } @@ -223,6 +237,7 @@ static void xmt_new_od_link_from_node(GF_XMTParser *parser, char *name, MFURL *u u32 i, ID; XMT_ODLink *odl; + /*find OD_ID*/ ID = 0; if (!strnicmp(name, "od", 2)) ID = atoi(name + 2); else if (!strnicmp(name, "iod", 3)) ID = atoi(name + 3); @@ -237,6 +252,12 @@ static void xmt_new_od_link_from_node(GF_XMTParser *parser, char *name, MFURL *u } } else ID = 0; + + /*write OD_ID*/ + assert(url->count); + i = url->count - 1; + url->vals[i].OD_ID = 0; + url->vals->OD_ID = ID; i=0; while ((odl = (XMT_ODLink*)gf_list_enum(parser->od_links, &i))) { @@ -252,7 +273,7 @@ static void xmt_new_od_link_from_node(GF_XMTParser *parser, char *name, MFURL *u odl->mf_urls = gf_list_new(); if (url) gf_list_add(odl->mf_urls, url); if (ID) odl->ID = ID; - else odl->desc_name = strdup(name); + else odl->desc_name = gf_strdup(name); gf_list_add(parser->od_links, odl); } static void xmt_new_esd_link(GF_XMTParser *parser, GF_ESD *esd, char *desc_name, u32 binID) @@ -282,7 +303,7 @@ static void xmt_new_esd_link(GF_XMTParser *parser, GF_ESD *esd, char *desc_name, esdl->ESID = esdl->esd->ESID = binID; } if (desc_name && !esdl->desc_name) { - esdl->desc_name = strdup(desc_name); + esdl->desc_name = gf_strdup(desc_name); if (!esdl->ESID && !strnicmp(desc_name, "es", 2)) esdl->ESID = atoi(&desc_name[2]); } return; @@ -292,7 +313,7 @@ static void xmt_new_esd_link(GF_XMTParser *parser, GF_ESD *esd, char *desc_name, esd->ESID = esdl->ESID = binID; if (desc_name) { if (!esdl->ESID && !strnicmp(desc_name, "es", 2)) esdl->ESID = atoi(&desc_name[2]); - esdl->desc_name = strdup(desc_name); + esdl->desc_name = gf_strdup(desc_name); } if (!esd->ESID) { esd->ESID = 1; @@ -312,9 +333,9 @@ static Bool xmt_set_depend_id(GF_XMTParser *parser, GF_ESD *desc, char *es_name, while ((esdl = (XMT_ESDLink *)gf_list_enum(parser->esd_links, &i))) { if (esdl->esd == desc) { if (is_ocr_dep) - esdl->OCR_Name = strdup(es_name); + esdl->OCR_Name = gf_strdup(es_name); else - esdl->Depends_Name = strdup(es_name); + esdl->Depends_Name = gf_strdup(es_name); return 1; } } @@ -364,12 +385,21 @@ static u32 xmt_locate_stream(GF_XMTParser *parser, char *stream_name) if (!strcmp(szN, stream_name)) return esdl->ESID; } } + if (parser->load->ctx) { + GF_StreamContext *sc; + i=0; + while ((sc = gf_list_enum(parser->load->ctx->streams, &i))) { + if (sc->name && !strcmp(sc->name, stream_name)) return sc->ESID; + sprintf(szN, "%d", sc->ESID); + if (!strcmp(szN, stream_name)) return sc->ESID; + } + } /*create a temp one*/ - esdl = (XMT_ESDLink *)malloc(sizeof(XMT_ESDLink)); + esdl = (XMT_ESDLink *)gf_malloc(sizeof(XMT_ESDLink)); memset(esdl, 0, sizeof(XMT_ESDLink)); esdl->ESID = (u16) ( ((u32) esdl) >> 16) | ( ((u32)esdl) & 0x0000FFFF); if (!strnicmp(stream_name, "es", 2)) esdl->ESID = atoi(&stream_name[2]); - esdl->desc_name = strdup(stream_name); + esdl->desc_name = gf_strdup(stream_name); gf_list_add(parser->esd_links, esdl); return esdl->ESID; } @@ -399,8 +429,8 @@ static void xmt_resolve_od_links(GF_XMTParser *parser) xmt_report(parser, GF_BAD_PARAM, "Stream %s ID %d has no associated ES descriptor\n", esdl->desc_name ? esdl->desc_name : "", esdl->ESID); i--; gf_list_rem(parser->esd_links, i); - if (esdl->desc_name) free(esdl->desc_name); - free(esdl); + if (esdl->desc_name) gf_free(esdl->desc_name); + gf_free(esdl); continue; } if (esdl->ESID) esdl->esd->ESID = esdl->ESID; @@ -440,7 +470,7 @@ static void xmt_resolve_od_links(GF_XMTParser *parser) if (!esdl->esd->OCRESID) { xmt_report(parser, GF_OK, "WARNING: Could not find clock reference %s for ES %s - forcing self-synchronization", esdl->OCR_Name, esdl->desc_name); } - free(esdl->OCR_Name); + gf_free(esdl->OCR_Name); esdl->OCR_Name = NULL; } @@ -473,15 +503,15 @@ static void xmt_resolve_od_links(GF_XMTParser *parser) if (!esdl->esd->dependsOnESID) { xmt_report(parser, GF_OK, "WARNING: Could not find stream dependance %s for ES %s - forcing self-synchronization", esdl->Depends_Name, esdl->desc_name); } - free(esdl->Depends_Name); + gf_free(esdl->Depends_Name); esdl->Depends_Name = NULL; } while (gf_list_count(parser->esd_links)) { esdl = (XMT_ESDLink *)gf_list_get(parser->esd_links, 0); gf_list_rem(parser->esd_links, 0); - if (esdl->desc_name) free(esdl->desc_name); - free(esdl); + if (esdl->desc_name) gf_free(esdl->desc_name); + gf_free(esdl); } i=0; @@ -515,9 +545,9 @@ static void xmt_resolve_od_links(GF_XMTParser *parser) } j--; gf_list_rem(parser->od_links, j); - if (l2->desc_name) free(l2->desc_name); + if (l2->desc_name) gf_free(l2->desc_name); gf_list_del(l2->mf_urls); - free(l2); + gf_free(l2); } } } @@ -544,10 +574,10 @@ static void xmt_resolve_od_links(GF_XMTParser *parser) if (url->url) seg = strstr(url->url, "#"); if (seg) { sprintf(szURL, "od:%d#%s", l->od->objectDescriptorID, seg+1); - free(url->url); - url->url = strdup(szURL); + gf_free(url->url); + url->url = gf_strdup(szURL); } else { - if (url->url) free(url->url); + if (url->url) gf_free(url->url); url->url = NULL; url->OD_ID = l->od->objectDescriptorID; } @@ -555,9 +585,9 @@ static void xmt_resolve_od_links(GF_XMTParser *parser) } } - if (l->desc_name) free(l->desc_name); + if (l->desc_name) gf_free(l->desc_name); gf_list_del(l->mf_urls); - free(l); + gf_free(l); gf_list_rem(parser->od_links, 0); } } @@ -597,12 +627,17 @@ static u32 xmt_get_node_tag(GF_XMTParser *parser, const char *node_name) u32 tag; /*if VRML and allowing non MPEG4 nodes, use X3D*/ if ((parser->doc_type==2) && !(parser->load->flags & GF_SM_LOAD_MPEG4_STRICT)) { +#ifndef GPAC_DISABLE_X3D tag = gf_node_x3d_type_by_class_name(node_name); - if (!tag) tag = gf_node_mpeg4_type_by_class_name(node_name); + if (!tag) +#endif + tag = gf_node_mpeg4_type_by_class_name(node_name); } else { tag = gf_node_mpeg4_type_by_class_name(node_name); /*if allowing non MPEG4 nodes, try X3D*/ +#ifndef GPAC_DISABLE_X3D if (!tag && !(parser->load->flags & GF_SM_LOAD_MPEG4_STRICT)) tag = gf_node_x3d_type_by_class_name(node_name); +#endif } return tag; } @@ -635,7 +670,7 @@ static GF_Node *xmt_find_node(GF_XMTParser *parser, char *ID) } if (!p) { xmt_report(parser, GF_BAD_PARAM, "%s: not a valid/supported proto", node_class); - free(node_class); + gf_free(node_class); return NULL; } n = gf_sg_proto_create_instance(parser->load->scene_graph, p); @@ -643,7 +678,7 @@ static GF_Node *xmt_find_node(GF_XMTParser *parser, char *ID) tag = xmt_get_node_tag(parser, node_class); n = gf_node_new(parser->load->scene_graph, tag); } - free(node_class); + gf_free(node_class); if (n) { u32 nID = xmt_get_node_id(parser, ID); gf_node_set_id(n, nID, ID); @@ -711,9 +746,9 @@ static u32 xmt_parse_string(GF_XMTParser *parser, const char *name, SFString *va /*SF string, no inspection*/ if (!is_mf) { len = strlen(str); - if (val->buffer) free(val->buffer); + if (val->buffer) gf_free(val->buffer); val->buffer = NULL; - if (len) val->buffer = strdup(str); + if (len) val->buffer = gf_strdup(str); return len+1; } @@ -732,15 +767,15 @@ static u32 xmt_parse_string(GF_XMTParser *parser, const char *name, SFString *va /*handle as a single field (old GPAC XMT & any unknown cases...*/ else { len = strlen(str); - if (val->buffer) free(val->buffer); + if (val->buffer) gf_free(val->buffer); val->buffer = NULL; - if (len) val->buffer = strdup(str); + if (len) val->buffer = gf_strdup(str); return len; } k = 0; i += strlen(sep); - value = strdup(str); + value = gf_strdup(str); if (strncmp(&str[i], sep, strlen(sep))) { @@ -758,10 +793,10 @@ static u32 xmt_parse_string(GF_XMTParser *parser, const char *name, SFString *va value[k] = 0; len = strlen(sep) + i; - if (val->buffer) free(val->buffer); + if (val->buffer) gf_free(val->buffer); val->buffer = NULL; - if (strlen(value)) val->buffer = strdup(value); - free(value); + if (strlen(value)) val->buffer = gf_strdup(value); + gf_free(value); return len; } @@ -778,7 +813,7 @@ static u32 xmt_parse_url(GF_XMTParser *parser, const char *name, MFURL *val, GF_ assert(val->count); idx = val->count - 1; - if (val->vals[idx].url) free(val->vals[idx].url); + if (val->vals[idx].url) gf_free(val->vals[idx].url); val->vals[idx].url = sfstr.buffer; val->vals[idx].OD_ID = 0; /*empty*/ @@ -810,7 +845,7 @@ static u32 xmt_parse_script(GF_XMTParser *parser, const char *name, SFScript *va res = xmt_parse_string(parser, name, &sfstr, is_mf, a_value); if (parser->last_error) return res; - if (val->script_text) free(val->script_text); + if (val->script_text) gf_free(val->script_text); val->script_text = (unsigned char*)sfstr.buffer; return res; } @@ -897,8 +932,8 @@ static u32 xmt_parse_sf_field(GF_XMTParser *parser, GF_FieldInfo *info, GF_Node if (parser->last_error) return res; img->numComponents = v; size = img->width * img->height * img->numComponents; - if (img->pixels) free(img->pixels); - img->pixels = (unsigned char*)malloc(sizeof(char) * size); + if (img->pixels) gf_free(img->pixels); + img->pixels = (unsigned char*)gf_malloc(sizeof(char) * size); a_value += res; res = 0; for (k=0; kRouteID) { xmt_report(parser, GF_BAD_PARAM, "Cannot resolve GF_Route DEF %s", com->unres_name); } - free(com->unres_name); + gf_free(com->unres_name); com->unres_name = NULL; com->unresolved = 0; break; @@ -1115,7 +1150,7 @@ static void xmt_parse_route(GF_XMTParser *parser, const GF_XMLAttribute *attribu /*for insert command*/ if (rID) { com->RouteID = rID; - com->def_name = strdup(ID); + com->def_name = gf_strdup(ID); /*whenever not inserting in graph, keep track of max defined ID*/ gf_sg_set_max_defined_route_id(parser->load->scene_graph, rID); if (rID>parser->load->ctx->max_route_id) parser->load->ctx->max_route_id = rID; @@ -1327,6 +1362,7 @@ static void xmt_parse_proto(GF_XMTParser *parser, const GF_XMLAttribute *attribu } static u32 xmt_get_protofield_qp_type(const char *QP_Type) { +#ifndef GPAC_DISABLE_BIFS if (!strcmp(QP_Type, "position3D")) return QC_3DPOS; else if (!strcmp(QP_Type, "position2D")) return QC_2DPOS; else if (!strcmp(QP_Type, "drawingOrder")) return QC_ORDER; @@ -1341,7 +1377,8 @@ static u32 xmt_get_protofield_qp_type(const char *QP_Type) else if (!strcmp(QP_Type, "size2D")) return QC_SIZE_2D; else if (!strcmp(QP_Type, "linear")) return QC_LINEAR_SCALAR; else if (!strcmp(QP_Type, "coordIndex")) return QC_COORD_INDEX; - else return 0; +#endif + return 0; } static GF_Err x3d_get_default_container(GF_Node *par, GF_Node *n, GF_FieldInfo *info) @@ -1384,7 +1421,11 @@ static GF_Node *xmt_parse_element(GF_XMTParser *parser, char *name, const char * } return NULL; } - if (parent && parent->node && ((parent->node->sgprivate->tag==TAG_MPEG4_Script) || (parent->node->sgprivate->tag==TAG_X3D_Script)) ) { + if (parent && parent->node && ((parent->node->sgprivate->tag==TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (parent->node->sgprivate->tag==TAG_X3D_Script) +#endif + ) ) { is_script = 1; if (!strcmp(name, "field")) { xmt_parse_script_field(parser, parent->node, attributes, nb_attributes); @@ -1503,7 +1544,11 @@ static GF_Node *xmt_parse_element(GF_XMTParser *parser, char *name, const char * } if ( (e = gf_node_get_field_by_name(last->node, atField, &nfield)) != GF_OK) { u32 l_tag = gf_node_get_tag(last->node); - if ((l_tag!=TAG_MPEG4_Script) && (l_tag!=TAG_X3D_Script)) { + if ((l_tag!=TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + && (l_tag!=TAG_X3D_Script) +#endif + ) { xmt_report(parser, e, "connect: %s not an field of node %s", atField, gf_node_get_class_name(last->node) ); return NULL; } @@ -1616,6 +1661,31 @@ static GF_Node *xmt_parse_element(GF_XMTParser *parser, char *name, const char * } return NULL; } + if (!strcmp(name, "store") && (parent->container_field.fieldType==GF_SG_VRML_MFATTRREF)) { + GF_FieldInfo pinfo; + GF_Node *atNode = NULL; + char *fieldName = NULL; + for (i=0; ivalue || !strlen(att->value)) continue; + if (!strcmp(att->name, "node")) { + atNode = xmt_find_node(parser, att->value); + if (!atNode) xmt_report(parser, GF_BAD_PARAM, "Cannot locate node %s", att->value); + } + if (!strcmp(att->name, "field")) fieldName = att->value; + } + if (!fieldName || !atNode) { + xmt_report(parser, GF_BAD_PARAM, "Node or field name missing in "); + } else if (gf_node_get_field_by_name(atNode, fieldName, &pinfo) != GF_OK) { + xmt_report(parser, GF_BAD_PARAM, "Field %s not a member of node %s", fieldName, gf_node_get_class_name(node) ); + } else { + SFAttrRef *ptr; + gf_sg_vrml_mf_append(parent->container_field.far_ptr , GF_SG_VRML_MFATTRREF, (void **) &ptr); + ptr->node = atNode; + ptr->fieldIndex = pinfo.fieldIndex; + } + return NULL; + } parent->container_field.far_ptr = NULL; } else if (parser->command && (parser->command->tag == GF_SG_MULTIPLE_REPLACE)) { @@ -1867,16 +1937,21 @@ GF_Descriptor *xmt_parse_descriptor(GF_XMTParser *parser, char *name, const GF_X switch (esd->decoderConfig->streamType) { case GF_STREAM_SCENE: case GF_STREAM_OD: + if (!esd->decoderConfig->objectTypeIndication) esd->decoderConfig->objectTypeIndication = 1; /*watchout for default BIFS stream*/ if (parser->scene_es && !parser->base_scene_id && (esd->decoderConfig->streamType==GF_STREAM_SCENE)) { parser->scene_es->ESID = parser->base_scene_id = esd->ESID; parser->scene_es->timeScale = (esd->slConfig && esd->slConfig->timestampResolution) ? esd->slConfig->timestampResolution : 1000; } else { + char *name; GF_StreamContext *sc = gf_sm_stream_new(parser->load->ctx, esd->ESID, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); /*set default timescale for systems tracks (ignored for other)*/ if (sc) sc->timeScale = (esd->slConfig && esd->slConfig->timestampResolution) ? esd->slConfig->timestampResolution : 1000; if (!parser->base_scene_id && (esd->decoderConfig->streamType==GF_STREAM_SCENE)) parser->base_scene_id = esd->ESID; else if (!parser->base_od_id && (esd->decoderConfig->streamType==GF_STREAM_OD)) parser->base_od_id = esd->ESID; + + name = xmt_get_es_name(parser, esd->ESID); + if (name && !sc->name) sc->name = gf_strdup(name); } break; } @@ -1897,6 +1972,8 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X return; } + parser->stream_id = parser->load->force_es_id; + if (!strcmp(name, "par")) { for (i=0; istream_id) parser->stream_id = parser->base_scene_id; @@ -2042,6 +2125,11 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X else if (!strcmp(att->name, "value")) fieldValue = att->value; else if (!strcmp(att->name, "atRoute")) routeName = att->value; else if (!strcmp(att->name, "extended")) extended = att->value; + else if (!strcmp(att->name, "atIndexNode")) idxNode = att->value; + else if (!strcmp(att->name, "atIndexField")) idxField = att->value; + else if (!strcmp(att->name, "atChildField")) childField = att->value; + else if (!strcmp(att->name, "fromNode")) fromNode = att->value; + else if (!strcmp(att->name, "fromField")) fromField = att->value; else if (!strcmp(att->name, "position")) { if (!strcmp(att->value, "BEGIN")) position = 0; else if (!strcmp(att->value, "END")) position = -1; @@ -2049,6 +2137,10 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X } } + /*if we are parsing in an already loaded context and no time is given, force a time != 0 to create a new command*/ + if (!au_time && (parser->load->flags&GF_SM_LOAD_CONTEXT_READY)) + au_time = 0.001; + atNode = NULL; if (nodeName) { if (fieldName) { @@ -2057,7 +2149,13 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X else if (!strcmp(name, "Insert")) tag = GF_SG_INDEXED_INSERT; else if (!strcmp(name, "Delete")) tag = GF_SG_INDEXED_DELETE; } else { - if (!strcmp(name, "Replace")) tag = GF_SG_FIELD_REPLACE; + if (!strcmp(name, "Replace")) { + if ((idxNode && idxField) || childField || (fromNode && fromField)) { + tag = GF_SG_XREPLACE; + } else { + tag = GF_SG_FIELD_REPLACE; + } + } } } else { if (!strcmp(name, "Replace")) { @@ -2138,7 +2236,7 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X GF_StreamContext *stream = gf_sm_stream_find(parser->load->ctx, (u16) stream_id); if (!stream || (stream->streamType!=GF_STREAM_SCENE)) stream_id = parser->base_scene_id; - parser->scene_es = gf_sm_stream_new(parser->load->ctx, (u16) stream_id, GF_STREAM_SCENE, 0); + parser->scene_es = gf_sm_stream_new(parser->load->ctx, (u16) stream_id, GF_STREAM_SCENE, GPAC_OTI_SCENE_BIFS); parser->scene_au = gf_sm_stream_au_new(parser->scene_es, 0, au_time, au_is_rap); gf_list_add(parser->scene_au->commands, parser->command); } @@ -2153,34 +2251,86 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X if (fieldName) { field = gf_sg_command_field_new(parser->command); field->fieldIndex = info.fieldIndex; - if (gf_sg_vrml_get_sf_type(info.fieldType) != GF_SG_VRML_SFNODE) { - if (position==-2) { - field->fieldType = info.fieldType; - field->field_ptr = gf_sg_vrml_field_pointer_new(info.fieldType); - info.far_ptr = field->field_ptr; - if (gf_sg_vrml_is_sf_field(info.fieldType)) { - xmt_parse_sf_field(parser, &info, atNode, fieldValue); - } else { - xmt_parse_mf_field(parser, &info, atNode, fieldValue); + + if (idxNode && idxField) { + GF_Node *iNode = xmt_find_node(parser, idxNode); + if (iNode) { + GF_FieldInfo idxF; + parser->command->toNodeID = gf_node_get_id(iNode); + gf_node_get_field_by_name(iNode, idxField, &idxF); + parser->command->toFieldIndex = idxF.fieldIndex; + position = 0; + switch (idxF.fieldType) { + case GF_SG_VRML_SFBOOL: + if (*(SFBool*)idxF.far_ptr) position = 1; + break; + case GF_SG_VRML_SFINT32: + if (*(SFInt32*)idxF.far_ptr >=0) position = *(SFInt32*)idxF.far_ptr; + break; + case GF_SG_VRML_SFFLOAT: + if ( (*(SFFloat *)idxF.far_ptr) >=0) position = (s32) floor( FIX2FLT(*(SFFloat*)idxF.far_ptr) ); + break; + case GF_SG_VRML_SFTIME: + if ( (*(SFTime *)idxF.far_ptr) >=0) position = (s32) floor( (*(SFTime *)idxF.far_ptr) ); + break; } - } else { - field->fieldType = info.fieldType = gf_sg_vrml_get_sf_type(info.fieldType); - field->pos = position; - if (tag != GF_SG_INDEXED_DELETE) { + } + } + if (childField) { + GF_Node *child = gf_node_list_get_child( ((GF_ParentNode*)atNode)->children, position); + if (child) { + parser->command->ChildNodeTag = gf_node_get_tag(child); + if (parser->command->ChildNodeTag == TAG_ProtoNode) { + s32 p_id = gf_sg_proto_get_id(gf_node_get_proto(child)); + parser->command->ChildNodeTag = -p_id; + } + /*get field in the info struct for later parsing*/ + gf_node_get_field_by_name(child, childField, &info); + parser->command->child_field = info.fieldIndex; + } + } + /*do not keep position info if index node is used*/ + if (idxNode && idxField) position = -2; + + if (fromNode && fromField) { + GF_Node *fNode = xmt_find_node(parser, fromNode); + if (fNode) { + GF_FieldInfo fField; + parser->command->fromNodeID = gf_node_get_id(fNode); + gf_node_get_field_by_name(fNode, fromField, &fField); + parser->command->fromFieldIndex = fField.fieldIndex; + } + } + if (!fromNode && !fromField) { + if (gf_sg_vrml_get_sf_type(info.fieldType) != GF_SG_VRML_SFNODE) { + if (position==-2) { + field->fieldType = info.fieldType; field->field_ptr = gf_sg_vrml_field_pointer_new(info.fieldType); info.far_ptr = field->field_ptr; - xmt_parse_sf_field(parser, &info, atNode, fieldValue); + if (gf_sg_vrml_is_sf_field(info.fieldType)) { + xmt_parse_sf_field(parser, &info, atNode, fieldValue); + } else { + xmt_parse_mf_field(parser, &info, atNode, fieldValue); + } + } else { + field->fieldType = info.fieldType = gf_sg_vrml_get_sf_type(info.fieldType); + field->pos = position; + if (tag != GF_SG_INDEXED_DELETE) { + field->field_ptr = gf_sg_vrml_field_pointer_new(info.fieldType); + info.far_ptr = field->field_ptr; + xmt_parse_sf_field(parser, &info, atNode, fieldValue); + } } - } - } else { - field->pos = position; - if ((position==-2) && (info.fieldType==GF_SG_VRML_MFNODE)) { - field->fieldType = GF_SG_VRML_MFNODE; } else { - field->fieldType = GF_SG_VRML_SFNODE; - } - parser->state = XMT_STATE_ELEMENTS; - } + field->pos = position; + if ((position==-2) && (info.fieldType==GF_SG_VRML_MFNODE)) { + field->fieldType = GF_SG_VRML_MFNODE; + } else { + field->fieldType = GF_SG_VRML_SFNODE; + } + parser->state = XMT_STATE_ELEMENTS; + } + } } else if (tag==GF_SG_NODE_INSERT) { field = gf_sg_command_field_new(parser->command); field->fieldType = GF_SG_VRML_SFNODE; @@ -2191,13 +2341,13 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X else if (routeName) { u32 rID = xmt_get_route(parser, routeName, 0); if (!rID) { - parser->command->unres_name = strdup(routeName); + parser->command->unres_name = gf_strdup(routeName); parser->command->unresolved = 1; gf_list_add(parser->unresolved_routes, parser->command); } else { parser->command->RouteID = rID; /*for bt<->xmt conversions*/ - parser->command->def_name = strdup(routeName); + parser->command->def_name = gf_strdup(routeName); } } else if (tag == GF_SG_PROTO_DELETE) { @@ -2211,7 +2361,7 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X if (!p) xmt_report(parser, GF_OK, "Warning: Cannot locate proto %s - skipping", fieldValue); else { - parser->command->del_proto_list = (u32*)realloc(parser->command->del_proto_list, sizeof(u32) * (parser->command->del_proto_list_size+1)); + parser->command->del_proto_list = (u32*)gf_realloc(parser->command->del_proto_list, sizeof(u32) * (parser->command->del_proto_list_size+1)); parser->command->del_proto_list[parser->command->del_proto_list_size] = p->ID; parser->command->del_proto_list_size++; } @@ -2248,6 +2398,10 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X else if (!strcmp(att->name, "ES_ID")) es_ids = att->value; } + /*if we are parsing in an already loaded context and no time is given, force a time != 0 to create a new command*/ + if (!au_time && (parser->load->flags&GF_SM_LOAD_CONTEXT_READY)) + au_time = 0.001; + if (!strcmp(name, "ObjectDescriptorUpdate")) tag = GF_ODF_OD_UPDATE_TAG; else if (!strcmp(name, "ES_DescriptorUpdate")) tag = GF_ODF_ESD_UPDATE_TAG; else if (!strcmp(name, "IPMP_DescriptorUpdate")) tag = GF_ODF_IPMP_UPDATE_TAG; @@ -2279,7 +2433,7 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X es_id = xmt_get_esd_id(parser, es_ids); if (!es_id) xmt_report(parser, GF_OK, "Warning: Cannot find ES Descriptor %s - skipping", es_ids); else { - esdR->ES_ID = (u16*)realloc(esdR->ES_ID, sizeof(u16) * (esdR->NbESDs+1)); + esdR->ES_ID = (u16*)gf_realloc(esdR->ES_ID, sizeof(u16) * (esdR->NbESDs+1)); esdR->ES_ID[esdR->NbESDs] = es_id; esdR->NbESDs++; } @@ -2298,7 +2452,7 @@ static void xmt_parse_command(GF_XMTParser *parser, const char *name, const GF_X od_id = xmt_get_od_id(parser, od_ids); if (!od_id) xmt_report(parser, GF_OK, "Warning: Cannot find Object Descriptor %s - skipping", od_ids); else { - odR->OD_ID = (u16*)realloc(odR->OD_ID, sizeof(u16) * (odR->NbODs+1)); + odR->OD_ID = (u16*)gf_realloc(odR->OD_ID, sizeof(u16) * (odR->NbODs+1)); odR->OD_ID[odR->NbODs] = od_id; odR->NbODs++; } @@ -2318,6 +2472,8 @@ static void xmt_node_start(void *sax_cbck, const char *name, const char *name_sp if (parser->last_error) { gf_xml_sax_suspend(parser->sax_parser, 1); + if (parser->command_buffer) + parser->command_buffer->buffer = NULL; return; } @@ -2332,14 +2488,19 @@ static void xmt_node_start(void *sax_cbck, const char *name, const char *name_sp return; } - /*init doc state*/ - if (parser->state == XMT_STATE_INIT) { + /*init doc state with already loaded context (for chunk encoding)*/ + if ((parser->state == XMT_STATE_INIT) && (parser->load->flags & GF_SM_LOAD_CONTEXT_READY) && (parser->doc_type == 1)) { + parser->state = XMT_STATE_COMMANDS; + } + /*init doc state for regular parsing*/ + else if (parser->state == XMT_STATE_INIT) { /*XMT-A header*/ if ((parser->doc_type == 1) && !strcmp(name, "Header")) parser->state = XMT_STATE_HEAD; /*X3D header*/ else if ((parser->doc_type == 2) && !strcmp(name, "head")) parser->state = XMT_STATE_HEAD; /*XMT-O header*/ else if ((parser->doc_type == 3) && !strcmp(name, "head")) parser->state = XMT_STATE_HEAD; + return; } @@ -2351,6 +2512,13 @@ static void xmt_node_start(void *sax_cbck, const char *name, const char *name_sp if (desc) gf_list_add(parser->descriptors, desc); return; } + if (parser->state==XMT_STATE_END) { + if (!strcmp(name, "head")) { + parser->state = XMT_STATE_HEAD; + } else { + parser->state = XMT_STATE_COMMANDS; + } + } /*scene content*/ if (parser->state==XMT_STATE_BODY) { @@ -2369,7 +2537,6 @@ static void xmt_node_start(void *sax_cbck, const char *name, const char *name_sp else if ((parser->doc_type == 3) && !strcmp(name, "body")) parser->state = XMT_STATE_COMMANDS; return; } - /*XMT-A command*/ if ((parser->doc_type == 1) && (parser->state == XMT_STATE_COMMANDS)) { /*OD command*/ @@ -2575,7 +2742,7 @@ static void xmt_node_end(void *sax_cbck, const char *name, const char *name_spac /*SF/MFNode proto field, just pop node stack*/ else if (!top->node && !strcmp(name, "field")) { gf_list_rem_last(parser->nodes); - free(top); + gf_free(top); } else if (top->node && top->node->sgprivate->tag == TAG_ProtoNode) { if (!strcmp(name, "node") || !strcmp(name, "nodes")) { top->container_field.far_ptr = NULL; @@ -2584,14 +2751,14 @@ static void xmt_node_end(void *sax_cbck, const char *name, const char *name_spac } else if (!strcmp(name, "ProtoInstance")) { gf_list_rem_last(parser->nodes); node = top->node; - free(top); + gf_free(top); goto attach_node; } } } else if (top->node->sgprivate->tag==tag) { node = top->node; gf_list_rem_last(parser->nodes); - free(top); + gf_free(top); attach_node: top = (XMTNodeStack*)gf_list_last(parser->nodes); @@ -2697,7 +2864,11 @@ attach_node: if (parser->load->flags & GF_SM_LOAD_FOR_PLAYBACK) { /*load scripts*/ if (!parser->parsing_proto) { - if ((tag==TAG_MPEG4_Script) || (tag==TAG_X3D_Script) ) { + if ((tag==TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (tag==TAG_X3D_Script) +#endif + ) { /*it may happen that the script uses itself as a field (not sure this is compliant since this implies a cyclic structure, but happens in some X3D conformance seq)*/ if (!top || (top->node != node)) { @@ -2717,7 +2888,7 @@ attach_node: } } else if (parser->current_node_tag==tag) { gf_list_rem_last(parser->nodes); - free(top); + gf_free(top); } else { xmt_report(parser, GF_OK, "Warning: closing element %s doesn't match created node %s", name, gf_node_get_class_name(top->node) ); } @@ -2741,13 +2912,15 @@ static void xmt_text_content(void *sax_cbck, const char *text_content, Bool is_c switch (gf_node_get_tag((GF_Node *)node)) { case TAG_MPEG4_Script: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Script: +#endif if (is_cdata) { SFScript *sc_f; M_Script *sc = (M_Script *) node; gf_sg_vrml_mf_reset(& sc->url, GF_SG_VRML_MFSCRIPT); gf_sg_vrml_mf_append(& sc->url, GF_SG_VRML_MFSCRIPT, (void **) &sc_f); - sc->url.vals[0].script_text = (unsigned char*)strdup(text_content); + sc->url.vals[0].script_text = (unsigned char*)gf_strdup(text_content); } break; default: @@ -2778,25 +2951,46 @@ static GF_XMTParser *xmt_new_parser(GF_SceneLoader *load) return parser; } -GF_Err gf_sm_load_init_xmt(GF_SceneLoader *load) +static GF_Err xmt_restore_context(GF_SceneLoader *load) { - GF_Err e; - GF_XMTParser *parser; + u32 i; + GF_StreamContext *sc; + GF_XMTParser *parser = (GF_XMTParser *)load->loader_priv; + if (!parser || !load->ctx) return GF_BAD_PARAM; - if (!load->fileName) return GF_BAD_PARAM; - parser = xmt_new_parser(load); - GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("XMT: MPEG-4 (XMT) Scene Parsing\n")); - e = gf_xml_sax_parse_file(parser->sax_parser, (const char *)load->fileName, xmt_progress); - if (e<0) xmt_report(parser, e, "Invalid XML document\n", gf_xml_sax_get_error(parser->sax_parser)); - return parser->last_error; + /*restore context - note that base layer are ALWAYS declared BEFORE enhancement layers with gpac parsers*/ + i=0; + while ((sc = (GF_StreamContext*)gf_list_enum(load->ctx->streams, &i))){ + switch (sc->streamType) { + case GF_STREAM_SCENE: + case GF_STREAM_PRIVATE_SCENE: + if (!parser->scene_es) parser->scene_es = sc; break; + case GF_STREAM_OD: if (!parser->od_es) parser->od_es = sc; break; + default: break; + } + } + /*scene creation - pick up a size*/ + if (!parser->scene_es) { + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("XMT: No BIFS Streams found in existing context - creating one\n")); + parser->scene_es = gf_sm_stream_new(load->ctx, 0, GF_STREAM_SCENE, GPAC_OTI_SCENE_BIFS); + parser->load->ctx->scene_width = 0; + parser->load->ctx->scene_height = 0; + parser->load->ctx->is_pixel_metrics = 1; + } + else parser->base_scene_id = parser->scene_es->ESID; + if (parser->od_es) parser->base_od_id = parser->od_es->ESID; + + parser->doc_type = (load->type==GF_SM_LOAD_X3D) ? 2 : 1; + return GF_OK; } -GF_Err gf_sm_load_init_xmt_string(GF_SceneLoader *load, char *str_data) + +static GF_Err load_xmt_initialize(GF_SceneLoader *load, char *str_data) { GF_Err e; - GF_XMTParser *parser = (GF_XMTParser *)load->loader_priv; + GF_XMTParser *parser; - if (!parser) { + if (str_data) { char BOM[5]; if (strlen(str_data)<4) return GF_BAD_PARAM; BOM[0] = str_data[0]; @@ -2811,51 +3005,113 @@ GF_Err gf_sm_load_init_xmt_string(GF_SceneLoader *load, char *str_data) return e; } str_data += 4; + } else if (load->fileName) { + parser = xmt_new_parser(load); + } else { + return GF_BAD_PARAM; + } - if (load->flags & GF_SM_LOAD_CONTEXT_READY) { - parser->doc_type = (load->type==GF_SM_LOAD_X3D) ? 2 : 1; - parser->state = XMT_STATE_COMMANDS; - } + /*chunk parsing*/ + if (load->flags & GF_SM_LOAD_CONTEXT_READY) { + GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("XMT: MPEG-4 (XMT) Chunk Parsing\n")); + + e = xmt_restore_context(load); + if (e) return e; + + } else { + GF_LOG(GF_LOG_INFO, GF_LOG_PARSER, ("XMT: MPEG-4 (XMT) Scene Parsing\n")); + } + + if (str_data) { + return gf_xml_sax_parse(parser->sax_parser, str_data); } - e = gf_xml_sax_parse(parser->sax_parser, str_data); - if (e<0) return xmt_report(parser, e, "Invalid XML document: %s", gf_xml_sax_get_error(parser->sax_parser)); return GF_OK; } -GF_Err gf_sm_load_run_xmt(GF_SceneLoader *load) +static GF_Err load_xmt_run(GF_SceneLoader *load) +{ + GF_Err e; + GF_XMTParser *parser = (GF_XMTParser *)load->loader_priv; + if (!parser) { + e = load_xmt_initialize(load, NULL); + if (e) return e; + } + + e = gf_xml_sax_parse_file(parser->sax_parser, (const char *)load->fileName, xmt_progress); + + xmt_resolve_routes(parser); + xmt_resolve_od_links(parser); + + parser->last_error=GF_OK; + if (e<0) return xmt_report(parser, e, "Invalid XML document: %s", gf_xml_sax_get_error(parser->sax_parser)); + + return GF_OK; +} + +static GF_Err load_xmt_parse_string(GF_SceneLoader *load, char *str) { + GF_Err e; + GF_XMTParser *parser = (GF_XMTParser *)load->loader_priv; + if (!parser) { + return load_xmt_initialize(load, str); + } + e = gf_xml_sax_parse(parser->sax_parser, str); + + xmt_resolve_routes(parser); + xmt_resolve_od_links(parser); + + parser->last_error=GF_OK; + if (e<0) return xmt_report(parser, e, "Invalid XML document: %s", gf_xml_sax_get_error(parser->sax_parser)); return GF_OK; } -GF_Err gf_sm_load_done_xmt(GF_SceneLoader *load) +static void load_xmt_done(GF_SceneLoader *load) { GF_XMTParser *parser = (GF_XMTParser *)load->loader_priv; - if (!parser) return GF_OK; + if (!parser) return; + while (1) { XMTNodeStack *st = (XMTNodeStack *)gf_list_last(parser->nodes); if (!st) break; gf_list_rem_last(parser->nodes); gf_node_register(st->node, NULL); gf_node_unregister(st->node, NULL); - free(st); + gf_free(st); } - if (parser->x3d_root) free(parser->x3d_root); + if (parser->x3d_root) gf_free(parser->x3d_root); gf_list_del(parser->nodes); gf_list_del(parser->descriptors); gf_list_del(parser->def_nodes); gf_list_del(parser->peeked_nodes); - xmt_resolve_routes(parser); + gf_list_del(parser->inserted_routes); gf_list_del(parser->unresolved_routes); - xmt_resolve_od_links(parser); gf_list_del(parser->od_links); gf_list_del(parser->esd_links); gf_xml_sax_del(parser->sax_parser); if (parser->script_to_load) gf_list_del(parser->script_to_load); - free(parser); + gf_free(parser); load->loader_priv = NULL; +} + +static GF_Err load_xmt_suspend(GF_SceneLoader *load, Bool suspend) +{ + GF_XMTParser *parser = (GF_XMTParser *)load->loader_priv; + if (parser) gf_xml_sax_suspend(parser->sax_parser, suspend); + return GF_OK; +} + + +GF_Err gf_sm_load_init_xmt(GF_SceneLoader *load) +{ + load->process = load_xmt_run; + load->done = load_xmt_done; + load->parse_string = load_xmt_parse_string; + load->suspend = load_xmt_suspend; + if (load->fileName) return load_xmt_initialize(load, NULL); return GF_OK; } +#endif /*GPAC_DISABLE_LOADER_XMT*/ diff --git a/src/scene_manager/scene_dump.c b/src/scene_manager/scene_dump.c index ebca7a2..ee506fb 100644 --- a/src/scene_manager/scene_dump.c +++ b/src/scene_manager/scene_dump.c @@ -30,12 +30,11 @@ #include #include -//#ifndef GPAC_READ_ONLY - #ifndef __SYMBIAN32__ #include #endif +#ifndef GPAC_DISABLE_SCENE_DUMP /*for QP types*/ #include "../bifs/quant.h" @@ -44,10 +43,13 @@ struct _scenedump { /*the scene we're dumping - set at each SceneReplace or mannually*/ GF_SceneGraph *sg; +#ifndef GPAC_DISABLE_VRML /*the proto we're dumping*/ GF_Proto *current_proto; +#endif FILE *trace; u32 indent; + char *filename; u32 dump_mode; u16 CurrentESID; @@ -67,12 +69,11 @@ struct _scenedump Bool in_text; }; - -GF_Err DumpRoute(GF_SceneDumper *sdump, GF_Route *r, u32 dump_type); -void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldContainer); +static GF_Err gf_dump_vrml_route(GF_SceneDumper *sdump, GF_Route *r, u32 dump_type); +static void gf_dump_vrml_node(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldContainer); #ifndef GPAC_DISABLE_SVG -void SD_DumpSVG_Element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool is_root); +void gf_dump_svg_element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool is_root); #endif GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 indent, Bool skip_first_replace); @@ -80,12 +81,10 @@ GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 inde GF_EXPORT GF_SceneDumper *gf_sm_dumper_new(GF_SceneGraph *graph, char *_rad_name, char indent_char, u32 dump_mode) { - char rad_name[GF_MAX_PATH]; GF_SceneDumper *tmp; if (!graph) return NULL; GF_SAFEALLOC(tmp, GF_SceneDumper); - strcpy(rad_name, _rad_name ? _rad_name : ""); /*store original*/ tmp->dump_mode = dump_mode; @@ -95,11 +94,13 @@ GF_SceneDumper *gf_sm_dumper_new(GF_SceneGraph *graph, char *_rad_name, char ind tmp->XMLDump = 1; if (dump_mode==GF_SM_DUMP_LASER) tmp->LSRDump = 1; if (_rad_name) { - strcat(rad_name, tmp->LSRDump ? ".xsr" : ".svg"); - - tmp->trace = fopen(rad_name, "wt"); + const char* ext_name = tmp->LSRDump ? ".xsr" : ".svg"; + tmp->filename = gf_malloc(strlen(_rad_name ? _rad_name : "") + strlen(ext_name) + 1); + strcpy(tmp->filename, _rad_name ? _rad_name : ""); + strcat(tmp->filename, ext_name); + tmp->trace = gf_f64_open(tmp->filename, "wt"); if (!tmp->trace) { - free(tmp); + gf_free(tmp); return NULL; } } else { @@ -125,16 +126,20 @@ GF_SceneDumper *gf_sm_dumper_new(GF_SceneGraph *graph, char *_rad_name, char ind } if (_rad_name) { + const char* ext_name; switch (dump_mode) { - case GF_SM_DUMP_X3D_XML: strcat(rad_name, ".x3d"); tmp->XMLDump = 1; tmp->X3DDump = 1; break; - case GF_SM_DUMP_XMTA: strcat(rad_name, ".xmt"); tmp->XMLDump = 1; break; - case GF_SM_DUMP_X3D_VRML: strcat(rad_name, ".x3dv"); tmp->X3DDump = 1; break; - case GF_SM_DUMP_VRML: strcat(rad_name, ".wrl"); break; - default: strcat(rad_name, ".bt"); break; - } - tmp->trace = fopen(rad_name, "wt"); + case GF_SM_DUMP_X3D_XML: ext_name = ".x3d"; tmp->XMLDump = 1; tmp->X3DDump = 1; break; + case GF_SM_DUMP_XMTA: ext_name = ".xmt"; tmp->XMLDump = 1; break; + case GF_SM_DUMP_X3D_VRML: ext_name = ".x3dv"; tmp->X3DDump = 1; break; + case GF_SM_DUMP_VRML: ext_name = ".wrl"; break; + default: ext_name = ".bt"; break; + } + tmp->filename = gf_malloc(strlen(_rad_name ? _rad_name : "") + strlen(ext_name) + 1); + strcpy(tmp->filename, _rad_name ? _rad_name : ""); + strcat(tmp->filename, ext_name); + tmp->trace = gf_f64_open(tmp->filename, "wt"); if (!tmp->trace) { - free(tmp); + gf_free(tmp); return NULL; } } else { @@ -167,11 +172,20 @@ void gf_sm_dumper_del(GF_SceneDumper *sdump) gf_list_del(sdump->mem_def_nodes); gf_list_del(sdump->inserted_routes); if (sdump->trace != stdout) fclose(sdump->trace); - free(sdump); + if (sdump->filename) { + gf_free(sdump->filename); + sdump->filename = NULL; + } + gf_free(sdump); } +char *gf_sm_dump_get_name(GF_SceneDumper *bd) +{ + if (!bd) return NULL; + return bd->filename; +} -void SD_SetupDump(GF_SceneDumper *sdump, GF_Descriptor *root_od) +static void gf_dump_setup(GF_SceneDumper *sdump, GF_Descriptor *root_od) { if (sdump->XMLDump) { fprintf(sdump->trace, "\n"); @@ -185,7 +199,7 @@ void SD_SetupDump(GF_SceneDumper *sdump, GF_Descriptor *root_od) if (sdump->dump_mode==GF_SM_DUMP_SVG) return; if (sdump->LSRDump) { fprintf(sdump->trace, "\n"); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_OD_DUMP if (root_od) { GF_ObjectDescriptor *iod = (GF_ObjectDescriptor *)root_od; u32 i, count; @@ -211,7 +225,7 @@ void SD_SetupDump(GF_SceneDumper *sdump, GF_Descriptor *root_od) if (sdump->XMLDump) { fprintf(sdump->trace, "\n"); fprintf(sdump->trace, "
      \n"); -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_OD_DUMP if (root_od) gf_odf_dump_desc(root_od, sdump->trace, 1, 1); #endif fprintf(sdump->trace, "
      \n"); @@ -224,7 +238,7 @@ void SD_SetupDump(GF_SceneDumper *sdump, GF_Descriptor *root_od) fprintf(sdump->trace, "#VRML V2.0\n"); } else { /*dump root OD*/ -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_OD_DUMP if (root_od) gf_odf_dump_desc(root_od, sdump->trace, 0, 0); #endif } @@ -244,7 +258,7 @@ void SD_SetupDump(GF_SceneDumper *sdump, GF_Descriptor *root_od) } } -void SD_FinalizeDump(GF_SceneDumper *sdump, GF_Descriptor *root_od) +static void gf_dump_finalize(GF_SceneDumper *sdump, GF_Descriptor *root_od) { if (sdump->dump_mode==GF_SM_DUMP_SVG) return; @@ -266,7 +280,7 @@ void SD_FinalizeDump(GF_SceneDumper *sdump, GF_Descriptor *root_od) } } -Bool SD_IsDEFNode(GF_SceneDumper *sdump, GF_Node *node) +static Bool gf_dump_vrml_is_def_node(GF_SceneDumper *sdump, GF_Node *node) { s32 i = gf_list_find(sdump->dump_nodes, node); if (i>=0) return 0; @@ -274,7 +288,7 @@ Bool SD_IsDEFNode(GF_SceneDumper *sdump, GF_Node *node) return 1; } -GF_Node *SD_FindNode(GF_SceneDumper *sdump, u32 ID) +static GF_Node *gf_dump_find_node(GF_SceneDumper *sdump, u32 ID) { GF_Node *ret = gf_sg_find_node(sdump->sg, ID); if (ret) return ret; @@ -288,7 +302,7 @@ GF_Node *SD_FindNode(GF_SceneDumper *sdump, u32 ID) } -void StartElement(GF_SceneDumper *sdump, const char *name) +static void StartElement(GF_SceneDumper *sdump, const char *name) { if (!sdump->trace) return; DUMP_IND(sdump); @@ -298,7 +312,8 @@ void StartElement(GF_SceneDumper *sdump, const char *name) fprintf(sdump->trace, "<%s", name); } } -void EndElementHeader(GF_SceneDumper *sdump, Bool has_sub_el) + +static void EndElementHeader(GF_SceneDumper *sdump, Bool has_sub_el) { if (!sdump->trace) return; if (sdump->XMLDump) { @@ -309,7 +324,8 @@ void EndElementHeader(GF_SceneDumper *sdump, Bool has_sub_el) } } } -void EndElement(GF_SceneDumper *sdump, const char *name, Bool had_sub_el) + +static void EndElement(GF_SceneDumper *sdump, const char *name, Bool had_sub_el) { if (!sdump->trace) return; if (!sdump->XMLDump) { @@ -323,7 +339,7 @@ void EndElement(GF_SceneDumper *sdump, const char *name, Bool had_sub_el) } } -void StartAttribute(GF_SceneDumper *sdump, const char *name) +static void StartAttribute(GF_SceneDumper *sdump, const char *name) { if (!sdump->trace) return; if (!sdump->XMLDump) { @@ -334,7 +350,7 @@ void StartAttribute(GF_SceneDumper *sdump, const char *name) } } -void EndAttribute(GF_SceneDumper *sdump) +static void EndAttribute(GF_SceneDumper *sdump) { if (!sdump->trace) return; if (!sdump->XMLDump) { @@ -345,7 +361,7 @@ void EndAttribute(GF_SceneDumper *sdump) } -void StartList(GF_SceneDumper *sdump, const char *name) +static void StartList(GF_SceneDumper *sdump, const char *name) { if (!sdump->trace) return; DUMP_IND(sdump); @@ -359,7 +375,7 @@ void StartList(GF_SceneDumper *sdump, const char *name) } } -void EndList(GF_SceneDumper *sdump, const char *name) +static void EndList(GF_SceneDumper *sdump, const char *name) { if (!sdump->trace) return; DUMP_IND(sdump); @@ -370,7 +386,55 @@ void EndList(GF_SceneDumper *sdump, const char *name) } } -void DumpNodeID(GF_SceneDumper *sdump, GF_Node *node) + +static void scene_dump_utf_string(GF_SceneDumper *sdump, Bool escape_xml, char *str) +{ + u32 len, i; + u16 *uniLine; + if (!str) return; + len = strlen(str); + if (!len) return; + uniLine = (u16*)gf_malloc(sizeof(u16) * len); + len = gf_utf8_mbstowcs(uniLine, len, (const char **) &str); + if (len != (u32) (-1)) { + for (i=0; itrace, "\\"); + switch (uniLine[i]) { + case '\'': + if (escape_xml) fprintf(sdump->trace, "'"); + else fprintf(sdump->trace, "'"); + break; + case '\"': + if (escape_xml) fprintf(sdump->trace, """); + else fprintf(sdump->trace, "\""); + break; + case '&': + fprintf(sdump->trace, "&"); + break; + case '>': + fprintf(sdump->trace, ">"); + break; + case '<': + fprintf(sdump->trace, "<"); + break; + case '\r': fprintf(sdump->trace, ""); break; + case '\n': fprintf(sdump->trace, ""); break; + default: + if (uniLine[i]<128) { + fprintf(sdump->trace, "%c", (u8) uniLine[i]); + } else { + fprintf(sdump->trace, "&#%d;", uniLine[i]); + } + break; + } + } + } + gf_free(uniLine); +} + +#ifndef GPAC_DISABLE_VRML + +static void scene_dump_vrml_id(GF_SceneDumper *sdump, GF_Node *node) { u32 id; const char *node_name; @@ -383,7 +447,7 @@ void DumpNodeID(GF_SceneDumper *sdump, GF_Node *node) fprintf(sdump->trace, "N%d", id - 1); } -Bool DumpFindRouteName(GF_SceneDumper *sdump, u32 ID, const char **outName) +static Bool scene_dump_vrml_find_route_name(GF_SceneDumper *sdump, u32 ID, const char **outName) { GF_Route *r; u32 i; @@ -413,10 +477,10 @@ Bool DumpFindRouteName(GF_SceneDumper *sdump, u32 ID, const char **outName) return 0; } -void DumpRouteID(GF_SceneDumper *sdump, u32 routeID, char *rName) +static void scene_dump_vrml_route_id(GF_SceneDumper *sdump, u32 routeID, char *rName) { if (!sdump->trace) return; - if (!rName) DumpFindRouteName(sdump, routeID, (const char **) &rName); + if (!rName) scene_dump_vrml_find_route_name(sdump, routeID, (const char **) &rName); if (rName) fprintf(sdump->trace, "%s", rName); @@ -424,65 +488,12 @@ void DumpRouteID(GF_SceneDumper *sdump, u32 routeID, char *rName) fprintf(sdump->trace, "R%d", routeID - 1); } -void DumpBool(GF_SceneDumper *sdump, char *name, u32 value) -{ - if (!sdump->trace) return; - StartAttribute(sdump, name); - fprintf(sdump->trace, "%s", value ? "true" : "false"); - EndAttribute(sdump); -} - -void DumpUTFString(GF_SceneDumper *sdump, Bool escape_xml, char *str) -{ - u32 len, i; - u16 *uniLine; - if (!str) return; - len = strlen(str); - if (!len) return; - uniLine = (u16*)malloc(sizeof(u16) * len); - len = gf_utf8_mbstowcs(uniLine, len, (const char **) &str); - if (len != (size_t) (-1)) { - for (i=0; itrace, "\\"); - switch (uniLine[i]) { - case '\'': - if (escape_xml) fprintf(sdump->trace, "'"); - else fprintf(sdump->trace, "'"); - break; - case '\"': - if (escape_xml) fprintf(sdump->trace, """); - else fprintf(sdump->trace, "\""); - break; - case '&': - fprintf(sdump->trace, "&"); - break; - case '>': - fprintf(sdump->trace, ">"); - break; - case '<': - fprintf(sdump->trace, "<"); - break; - case '\r': fprintf(sdump->trace, ""); break; - case '\n': fprintf(sdump->trace, ""); break; - default: - if (uniLine[i]<128) { - fprintf(sdump->trace, "%c", (u8) uniLine[i]); - } else { - fprintf(sdump->trace, "&#%d;", uniLine[i]); - } - break; - } - } - } - free(uniLine); -} - -void DumpSFField(GF_SceneDumper *sdump, u32 type, void *ptr, Bool is_mf) +static void gf_dump_vrml_sffield(GF_SceneDumper *sdump, u32 type, void *ptr, Bool is_mf) { switch (type) { case GF_SG_VRML_SFBOOL: - fprintf(sdump->trace, "%s", * ((SFBool *)ptr) ? "TRUE" : "FALSE"); + fprintf(sdump->trace, "%s", * ((SFBool *)ptr) ? "true" : "false"); break; case GF_SG_VRML_SFINT32: fprintf(sdump->trace, "%d", * ((SFInt32 *)ptr) ); @@ -518,6 +529,17 @@ void DumpSFField(GF_SceneDumper *sdump, u32 type, void *ptr, Bool is_mf) fprintf(sdump->trace, "%g %g %g %g", FIX2FLT( ((SFRotation *)ptr)->x ), FIX2FLT( ((SFRotation *)ptr)->y ), FIX2FLT( ((SFRotation *)ptr)->z ), FIX2FLT( ((SFRotation *)ptr)->q ) ); break; + case GF_SG_VRML_SFATTRREF: + { + SFAttrRef *ar = (SFAttrRef *)ptr; + if (ar->node) { + GF_FieldInfo pinfo; + gf_node_get_field(ar->node, ar->fieldIndex, &pinfo); + scene_dump_vrml_id(sdump, ar->node); + fprintf(sdump->trace, ".%s", pinfo.name); + } + } + break; case GF_SG_VRML_SFSCRIPT: { u32 len, i; @@ -525,9 +547,9 @@ void DumpSFField(GF_SceneDumper *sdump, u32 type, void *ptr, Bool is_mf) u16 *uniLine; str = (char*)((SFScript *)ptr)->script_text; len = strlen(str); - uniLine = (u16*)malloc(sizeof(short) * len); + uniLine = (u16*)gf_malloc(sizeof(short) * len); len = gf_utf8_mbstowcs(uniLine, len, (const char **) &str); - if (len != (size_t) -1) { + if (len != (u32) -1) { if (!sdump->XMLDump) fputc('\"', sdump->trace); for (i=0; iXMLDump) fprintf(sdump->trace, "\"\n"); } - free(uniLine); + gf_free(uniLine); DUMP_IND(sdump); } break; @@ -579,7 +601,7 @@ void DumpSFField(GF_SceneDumper *sdump, u32 type, void *ptr, Bool is_mf) str = ((SFString *)ptr)->buffer; if (str && str[0]) { if (sdump->XMLDump) { - DumpUTFString(sdump, 1, str); + scene_dump_utf_string(sdump, 1, str); } else if (!strchr(str, '\"')) { fprintf(sdump->trace, "%s", str); } else { @@ -614,7 +636,7 @@ void DumpSFField(GF_SceneDumper *sdump, u32 type, void *ptr, Bool is_mf) } #else fprintf(sdump->trace, sdump->XMLDump ? (sdump->X3DDump ? "'" : """) : "\""); - fprintf(sdump->trace, ((SFURL *)ptr)->url); + fprintf(sdump->trace, "%s", ((SFURL *)ptr)->url); fprintf(sdump->trace, sdump->XMLDump ? (sdump->X3DDump ? "'" : """) : "\""); #endif } else { @@ -657,7 +679,7 @@ void DumpSFField(GF_SceneDumper *sdump, u32 type, void *ptr, Bool is_mf) } -void DumpFieldValue(GF_SceneDumper *sdump, GF_FieldInfo field) +static void gf_dump_vrml_simple_field(GF_SceneDumper *sdump, GF_FieldInfo field) { GenMFField *mffield; u32 i, sf_type; @@ -667,14 +689,14 @@ void DumpFieldValue(GF_SceneDumper *sdump, GF_FieldInfo field) switch (field.fieldType) { case GF_SG_VRML_SFNODE: assert ( *(GF_Node **)field.far_ptr); - DumpNode(sdump, *(GF_Node **)field.far_ptr, 0, NULL); + gf_dump_vrml_node(sdump, *(GF_Node **)field.far_ptr, 0, NULL); return; case GF_SG_VRML_MFNODE: list = * ((GF_ChildNodeItem **) field.far_ptr); assert( list ); sdump->indent++; while (list) { - DumpNode(sdump, list->node, 1, NULL); + gf_dump_vrml_node(sdump, list->node, 1, NULL); list = list->next; } sdump->indent--; @@ -686,7 +708,7 @@ void DumpFieldValue(GF_SceneDumper *sdump, GF_FieldInfo field) } if (gf_sg_vrml_is_sf_field(field.fieldType)) { if (sdump->XMLDump) StartAttribute(sdump, "value"); - DumpSFField(sdump, field.fieldType, field.far_ptr, 0); + gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0); if (sdump->XMLDump) EndAttribute(sdump); } else { mffield = (GenMFField *) field.far_ptr; @@ -702,7 +724,7 @@ void DumpFieldValue(GF_SceneDumper *sdump, GF_FieldInfo field) if (i) fprintf(sdump->trace, " "); gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i); /*this is to cope with single MFString which shall appear as SF in XMT*/ - DumpSFField(sdump, sf_type, slot_ptr, 1); + gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, 1); } if (!sdump->XMLDump) { fprintf(sdump->trace, "]"); @@ -714,7 +736,7 @@ void DumpFieldValue(GF_SceneDumper *sdump, GF_FieldInfo field) } } -Bool SD_NeedsFieldContainer(GF_Node *node, GF_FieldInfo *fi) +static Bool gf_dump_vrml_needs_container(GF_Node *node, GF_FieldInfo *fi) { u32 i, count, nb_ndt; GF_FieldInfo info; @@ -729,7 +751,7 @@ Bool SD_NeedsFieldContainer(GF_Node *node, GF_FieldInfo *fi) return (nb_ndt>1) ? 1 : 0; } -void DumpField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) +static void gf_dump_vrml_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) { GenMFField *mffield; u32 i, sf_type; @@ -750,7 +772,7 @@ void DumpField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) } else { StartAttribute(sdump, field.name); } - DumpNode(sdump, *(GF_Node **)field.far_ptr, 0, NULL); + gf_dump_vrml_node(sdump, *(GF_Node **)field.far_ptr, 0, NULL); if (sdump->XMLDump) { if (!sdump->X3DDump) { @@ -763,7 +785,7 @@ void DumpField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) return; case GF_SG_VRML_MFNODE: needs_field_container = 0; - if (sdump->XMLDump && sdump->X3DDump) needs_field_container = SD_NeedsFieldContainer(node, &field); + if (sdump->XMLDump && sdump->X3DDump) needs_field_container = gf_dump_vrml_needs_container(node, &field); if (!sdump->X3DDump) { if (gf_node_get_tag(node)==TAG_X3D_Switch) field.name = "choice"; } @@ -772,7 +794,7 @@ void DumpField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) if (!sdump->XMLDump || !sdump->X3DDump) StartList(sdump, field.name); sdump->indent++; while (list) { - DumpNode(sdump, list->node, 1, needs_field_container ? (char *) field.name : NULL); + gf_dump_vrml_node(sdump, list->node, 1, needs_field_container ? (char *) field.name : NULL); list = list->next; } sdump->indent--; @@ -798,10 +820,36 @@ void DumpField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) EndElement(sdump, (char *) field.name, 1); } return; + + case GF_SG_VRML_MFATTRREF: + if (sdump->XMLDump) { + MFAttrRef *ar = (MFAttrRef *)field.far_ptr; + StartElement(sdump, (char *) field.name); + EndElementHeader(sdump, 1); + sdump->indent++; + + for (i=0; icount; i++) { + if (ar->vals[i].node) { + GF_FieldInfo pinfo; + DUMP_IND(sdump); + gf_node_get_field(ar->vals[i].node, ar->vals[i].fieldIndex, &pinfo); + fprintf(sdump->trace, "vals[i].node); + fprintf(sdump->trace, "\" field=\"%s\"/>\n", pinfo.name); + } + } + + sdump->indent--; + EndElement(sdump, (char *) field.name, 1); + return; + } + break; } + + if (gf_sg_vrml_is_sf_field(field.fieldType)) { StartAttribute(sdump, field.name); - DumpSFField(sdump, field.fieldType, field.far_ptr, 0); + gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0); EndAttribute(sdump); } else { mffield = (GenMFField *) field.far_ptr; @@ -826,7 +874,7 @@ void DumpField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) for (i=0; icount; i++) { if (i) fprintf(sdump->trace, " "); gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i); - DumpSFField(sdump, sf_type, slot_ptr, 1); + gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, 1); } if (!sdump->XMLDump) fprintf(sdump->trace, "]"); @@ -847,7 +895,7 @@ void DumpField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) } } -const char * GetXMTFieldTypeName(u32 fieldType) +static const char *GetXMTFieldTypeName(u32 fieldType) { switch (fieldType) { case GF_SG_VRML_SFBOOL: return "Boolean"; @@ -875,7 +923,7 @@ const char * GetXMTFieldTypeName(u32 fieldType) default: return "unknown"; } } -const char * GetXMTFieldTypeValueName(u32 fieldType) +static const char *GetXMTFieldTypeValueName(u32 fieldType) { switch (fieldType) { case GF_SG_VRML_SFBOOL: return "booleanValue"; @@ -902,9 +950,10 @@ const char * GetXMTFieldTypeValueName(u32 fieldType) } } -const char *SD_GetQuantCatName(u32 QP_Type) +static const char *SD_GetQuantCatName(u32 QP_Type) { switch (QP_Type) { +#ifndef GPAC_DISABLE_BIFS case QC_3DPOS: return "position3D"; case QC_2DPOS: return "position2D"; case QC_ORDER: return "drawingOrder"; @@ -919,12 +968,13 @@ const char *SD_GetQuantCatName(u32 QP_Type) case QC_SIZE_2D: return "size2D"; case QC_LINEAR_SCALAR: return "linear"; case QC_COORD_INDEX: return "coordIndex"; +#endif default: return "unknown"; } } /*field dumping for proto declaration and Script*/ -void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool has_sublist) +static void gf_dump_vrml_dyn_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool has_sublist) { GenMFField *mffield; u32 i, sf_type; @@ -947,7 +997,7 @@ void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool fprintf(sdump->trace, ">\n"); sdump->indent++; fprintf(sdump->trace, ""); - DumpNode(sdump, field.far_ptr ? *(GF_Node **)field.far_ptr : NULL, 0, NULL); + gf_dump_vrml_node(sdump, field.far_ptr ? *(GF_Node **)field.far_ptr : NULL, 0, NULL); fprintf(sdump->trace, ""); sdump->indent--; if (!has_sublist) @@ -955,7 +1005,7 @@ void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool } else { if (field.far_ptr) { fprintf(sdump->trace, ">\n"); - DumpNode(sdump, *(GF_Node **)field.far_ptr, 0, NULL); + gf_dump_vrml_node(sdump, *(GF_Node **)field.far_ptr, 0, NULL); fprintf(sdump->trace, "\n"); } else { fprintf(sdump->trace, "/>\n"); @@ -968,7 +1018,7 @@ void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool } else { fprintf(sdump->trace, " %s=\"", GetXMTFieldTypeValueName(field.fieldType)); } - DumpSFField(sdump, field.fieldType, field.far_ptr, 0); + gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0); if (has_sublist) fprintf(sdump->trace, "\">\n"); else @@ -982,9 +1032,9 @@ void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool if ((field.eventType==GF_SG_EVENT_FIELD) || (field.eventType==GF_SG_EVENT_EXPOSED_FIELD)) { fprintf(sdump->trace, " "); if (field.fieldType == GF_SG_VRML_SFNODE) { - DumpNode(sdump, field.far_ptr ? *(GF_Node **)field.far_ptr : NULL, 0, NULL); + gf_dump_vrml_node(sdump, field.far_ptr ? *(GF_Node **)field.far_ptr : NULL, 0, NULL); } else { - DumpFieldValue(sdump, field); + gf_dump_vrml_simple_field(sdump, field); } } fprintf(sdump->trace, "\n"); @@ -1004,7 +1054,7 @@ void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool fprintf(sdump->trace, "\n"); sdump->indent++; while (l) { - DumpNode(sdump, l->node, 1, NULL); + gf_dump_vrml_node(sdump, l->node, 1, NULL); l = l->next; } sdump->indent--; @@ -1014,7 +1064,7 @@ void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool if (i) fprintf(sdump->trace, " "); if (field.fieldType != GF_SG_VRML_MFNODE) { gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i); - DumpSFField(sdump, sf_type, slot_ptr, (mffield->count>1) ? 1 : 0); + gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, (mffield->count>1) ? 1 : 0); } } } @@ -1037,7 +1087,7 @@ void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool sdump->indent++; if (!sdump->X3DDump) fprintf(sdump->trace, ""); while (list) { - DumpNode(sdump, list->node, 1, NULL); + gf_dump_vrml_node(sdump, list->node, 1, NULL); list = list->next; } if (!sdump->X3DDump) fprintf(sdump->trace, ""); @@ -1055,7 +1105,7 @@ void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool if (i) fprintf(sdump->trace, " "); if (field.fieldType != GF_SG_VRML_MFNODE) { gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i); - DumpSFField(sdump, sf_type, slot_ptr, (mffield->count>1) ? 1 : 0); + gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, (mffield->count>1) ? 1 : 0); } } if (has_sublist) @@ -1072,7 +1122,7 @@ void DumpDynField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool /*field dumping for proto instance*/ -void DumpProtoField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) +static void gf_dump_vrml_proto_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) { GenMFField *mffield; u32 i, sf_type; @@ -1085,7 +1135,7 @@ void DumpProtoField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) fprintf(sdump->trace, ">\n"); sdump->indent++; if (!sdump->X3DDump) fprintf(sdump->trace, ""); - DumpNode(sdump, field.far_ptr ? *(GF_Node **)field.far_ptr : NULL, 0, NULL); + gf_dump_vrml_node(sdump, field.far_ptr ? *(GF_Node **)field.far_ptr : NULL, 0, NULL); if (!sdump->X3DDump) fprintf(sdump->trace, ""); sdump->indent--; DUMP_IND(sdump); @@ -1096,7 +1146,7 @@ void DumpProtoField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) } else { fprintf(sdump->trace, " %s=\"", GetXMTFieldTypeValueName(field.fieldType)); } - DumpSFField(sdump, field.fieldType, field.far_ptr, 0); + gf_dump_vrml_sffield(sdump, field.fieldType, field.far_ptr, 0); fprintf(sdump->trace, "\"/>\n"); } } else { @@ -1110,7 +1160,7 @@ void DumpProtoField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) sdump->indent++; if (!sdump->X3DDump) fprintf(sdump->trace, ""); while (list) { - DumpNode(sdump, list->node, 1, NULL); + gf_dump_vrml_node(sdump, list->node, 1, NULL); list = list->next; } if (!sdump->X3DDump) fprintf(sdump->trace, ""); @@ -1127,7 +1177,7 @@ void DumpProtoField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) if (i) fprintf(sdump->trace, " "); if (field.fieldType != GF_SG_VRML_MFNODE) { gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, &slot_ptr, i); - DumpSFField(sdump, sf_type, slot_ptr, (mffield->count>1) ? 1 : 0); + gf_dump_vrml_sffield(sdump, sf_type, slot_ptr, (mffield->count>1) ? 1 : 0); } } fprintf(sdump->trace, "\"/>\n"); @@ -1136,7 +1186,7 @@ void DumpProtoField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field) } } -GF_Route *SD_GetISedField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo *field) +static GF_Route *gf_dump_vrml_get_IS(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo *field) { u32 i; GF_Route *r; @@ -1154,11 +1204,11 @@ GF_Route *SD_GetISedField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo *fi return NULL; } -void DumpISField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool isScript, Bool skip_is) +static void gf_dump_vrml_IS_field(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool isScript, Bool skip_is) { GF_FieldInfo pfield; - GF_Route *r = SD_GetISedField(sdump, node, &field); + GF_Route *r = gf_dump_vrml_get_IS(sdump, node, &field); if (r->FromNode) { pfield.fieldIndex = r->ToField.fieldIndex; gf_sg_proto_get_field(sdump->current_proto, NULL, &pfield); @@ -1185,21 +1235,10 @@ void DumpISField(GF_SceneDumper *sdump, GF_Node *node, GF_FieldInfo field, Bool } } } -const char *SD_GetNodeName(GF_SceneDumper *sdump, GF_Node *node) -{ - /*convert whatever possible*/ - if (sdump->X3DDump) { - if (node->sgprivate->tag == TAG_MPEG4_Circle) return "Circle2D"; - else if (node->sgprivate->tag == TAG_MPEG4_Rectangle) return "Rectangle2D"; - } else if (!sdump->X3DDump) { - if (node->sgprivate->tag == TAG_X3D_Circle2D) return "Circle"; - else if (node->sgprivate->tag == TAG_X3D_Rectangle2D) return "Rectangle"; - } - return gf_node_get_class_name(node); -} -Bool SD_CanDumpNode(GF_SceneDumper *sdump, GF_Node *node) +static Bool scene_dump_vrml_can_dump(GF_SceneDumper *sdump, GF_Node *node) { +#ifndef GPAC_DISABLE_VRML const char *name; u32 tag; @@ -1210,7 +1249,9 @@ Bool SD_CanDumpNode(GF_SceneDumper *sdump, GF_Node *node) if (node->sgprivate->tag==TAG_MPEG4_Rectangle) return 1; if (node->sgprivate->tag==TAG_MPEG4_Circle) return 1; name = gf_node_get_class_name(node); +#ifndef GPAC_DISABLE_X3D tag = gf_node_x3d_type_by_class_name(name); +#endif return tag ? 1 : 0; } else { if (node->sgprivate->tag<=GF_NODE_RANGE_LAST_MPEG4) return 1; @@ -1220,9 +1261,12 @@ Bool SD_CanDumpNode(GF_SceneDumper *sdump, GF_Node *node) tag = gf_node_mpeg4_type_by_class_name(name); return tag ? 1 : 0; } +#else + return 1; +#endif } -void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldContainer) +static void gf_dump_vrml_node(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldContainer) { u32 i, count, to_dump, sub_el, ID; u32 *def_fields; @@ -1239,23 +1283,36 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon /*this dumper works only for VRML like graphs*/ if (node->sgprivate->tag>GF_NODE_RANGE_LAST_X3D) return; - if (!SD_CanDumpNode(sdump, node)) { + if (!scene_dump_vrml_can_dump(sdump, node)) { GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[Scene Dump] node %s not part of %s standard - removing\n", gf_node_get_class_name(node), sdump->X3DDump ? "X3D" : (sdump->dump_mode==GF_SM_DUMP_VRML) ? "VRML" : "MPEG4")); if (!in_list) fprintf(sdump->trace, "NULL"); return; } - name = (char *) SD_GetNodeName(sdump, node); + /*convert whatever possible*/ + name = (char*)gf_node_get_class_name(node); +#ifndef GPAC_DISABLE_VRML + if (sdump->X3DDump) { + if (node->sgprivate->tag == TAG_MPEG4_Circle) name = "Circle2D"; + else if (node->sgprivate->tag == TAG_MPEG4_Rectangle) name = "Rectangle2D"; + } else if (!sdump->X3DDump) { + if (node->sgprivate->tag == TAG_X3D_Circle2D) name = "Circle"; + else if (node->sgprivate->tag == TAG_X3D_Rectangle2D) name = "Rectangle"; + } +#endif + + + isProto = (gf_node_get_tag(node) == TAG_ProtoNode) ? 1 : 0; ID = gf_node_get_id(node); isDEF = 0; if (ID) { - isDEF = SD_IsDEFNode(sdump, node); + isDEF = gf_dump_vrml_is_def_node(sdump, node); if (!isDEF) { if (!sdump->XMLDump) { if (in_list) DUMP_IND(sdump); fprintf(sdump->trace, "USE "); - DumpNodeID(sdump, node); + scene_dump_vrml_id(sdump, node); if (in_list) fprintf(sdump->trace, "\n"); } else { if (isProto) { @@ -1267,7 +1324,7 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon StartElement(sdump, name); } StartAttribute(sdump, "USE"); - DumpNodeID(sdump, node); + scene_dump_vrml_id(sdump, node); EndAttribute(sdump); EndElementHeader(sdump, 0); } @@ -1277,14 +1334,16 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon /*get all fields*/ count = gf_node_get_field_count(node); - def_fields = (u32*)malloc(sizeof(u32) * count); + def_fields = (u32*)gf_malloc(sizeof(u32) * count); base = NULL; switch (gf_node_get_tag(node)) { +#ifndef GPAC_DISABLE_VRML case TAG_X3D_Script: case TAG_MPEG4_Script: isScript = 1; break; +#endif default: isScript = 0; break; @@ -1314,7 +1373,7 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon gf_node_get_field(node, i, &field); if (sdump->current_proto) { - if (SD_GetISedField(sdump, node, &field) != NULL) { + if (gf_dump_vrml_get_IS(sdump, node, &field) != NULL) { def_fields[i] = 3; if ((field.fieldType == GF_SG_VRML_SFNODE) || (field.fieldType == GF_SG_VRML_MFNODE)) def_fields[i] = sdump->XMLDump ? 4 : 3; @@ -1361,6 +1420,16 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon } } break; + case GF_SG_VRML_MFATTRREF: + { + MFAttrRef *p = (MFAttrRef*)field.far_ptr; + if (p->count) { + def_fields[i] = 2; + to_dump++; + sub_el++; + } + } + break; default: if (isScript) { to_dump++; @@ -1381,7 +1450,7 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon if (!sdump->XMLDump) { if (isDEF) { fprintf(sdump->trace, "DEF "); - DumpNodeID(sdump, node); + scene_dump_vrml_id(sdump, node); fprintf(sdump->trace, " "); } fprintf(sdump->trace, "%s {}\n", name); @@ -1392,7 +1461,7 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon } else { fprintf(sdump->trace, "<%s DEF=\"", name); } - DumpNodeID(sdump, node); + scene_dump_vrml_id(sdump, node); fprintf(sdump->trace, "\"/>\n"); } else { if (isProto) { @@ -1402,7 +1471,7 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon } } } - free(def_fields); + gf_free(def_fields); return; } @@ -1410,7 +1479,7 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon if (in_list) DUMP_IND(sdump); if (isDEF) { fprintf(sdump->trace, "DEF "); - DumpNodeID(sdump, node); + scene_dump_vrml_id(sdump, node); fprintf(sdump->trace, " "); } fprintf(sdump->trace, "%s {\n", name); @@ -1425,7 +1494,7 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon } if (isDEF) { StartAttribute(sdump, "DEF"); - DumpNodeID(sdump, node); + scene_dump_vrml_id(sdump, node); EndAttribute(sdump); } } @@ -1437,24 +1506,24 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon case 1: gf_node_get_field(node, i, &field); if (!isScript) { - DumpField(sdump, node, field); + gf_dump_vrml_field(sdump, node, field); } /*special script dump case, static fields except url*/ else if (i==1 || i==2) { - if (*((SFBool *)field.far_ptr)) DumpField(sdump, node, field); + if (*((SFBool *)field.far_ptr)) gf_dump_vrml_field(sdump, node, field); } /*in bt first dump fields - in XMT first dump url*/ else if (i && !sdump->XMLDump) { - DumpDynField(sdump, node, field, 0); + gf_dump_vrml_dyn_field(sdump, node, field, 0); } else if (!i && sdump->XMLDump) { - DumpField(sdump, node, field); + gf_dump_vrml_field(sdump, node, field); } break; /*IS field*/ case 3: if (sdump->XMLDump) break; gf_node_get_field(node, i, &field); - DumpISField(sdump, node, field, isScript, 0); + gf_dump_vrml_IS_field(sdump, node, field, isScript, 0); def_fields[i] = 0; break; default: @@ -1476,7 +1545,7 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon for (i=0;iXMLDump) { @@ -1490,22 +1559,22 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon gf_node_get_field(node, i, &field); if (!isScript) { if (isProto && sdump->XMLDump) { - DumpProtoField(sdump, node, field); + gf_dump_vrml_proto_field(sdump, node, field); } else { - DumpField(sdump, node, field); + gf_dump_vrml_field(sdump, node, field); } } else { /*X3D script metadata, NOT DYN*/ if ((i==3) && (node->sgprivate->tag==TAG_X3D_Script) ) { - if (*((GF_Node **)field.far_ptr)) DumpField(sdump, node, field); + if (*((GF_Node **)field.far_ptr)) gf_dump_vrml_field(sdump, node, field); } else { - DumpDynField(sdump, node, field, 0); + gf_dump_vrml_dyn_field(sdump, node, field, 0); } } break; case 4: gf_node_get_field(node, i, &field); - DumpISField(sdump, node, field, isScript, 0); + gf_dump_vrml_IS_field(sdump, node, field, isScript, 0); break; } } @@ -1514,7 +1583,7 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon /*finally dump script - XMT dumping is broken!!*/ if (isScript && !sdump->XMLDump) { gf_node_get_field(node, 0, &field); - DumpField(sdump, node, field); + gf_dump_vrml_field(sdump, node, field); } sdump->indent --; @@ -1524,10 +1593,11 @@ void DumpNode(GF_SceneDumper *sdump, GF_Node *node, Bool in_list, char *fieldCon } else { EndElement(sdump, isProto ? "ProtoInstance" : name, sub_el); } - free(def_fields); + gf_free(def_fields); } -GF_Err DumpMultipleIndexedReplace(GF_SceneDumper *sdump, GF_Command *com) + +static GF_Err DumpMultipleIndexedReplace(GF_SceneDumper *sdump, GF_Command *com) { u32 i; GF_FieldInfo field; @@ -1540,11 +1610,11 @@ GF_Err DumpMultipleIndexedReplace(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\" atField=\"%s\">\n", field.name); } else { fprintf(sdump->trace, "MULTIPLEINDREPLACE "); - DumpNodeID(sdump, com->node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, ".%s [\n", field.name); } sdump->indent++; @@ -1558,7 +1628,7 @@ GF_Err DumpMultipleIndexedReplace(GF_SceneDumper *sdump, GF_Command *com) } else { fprintf(sdump->trace, "%d BY ", inf->pos); } - DumpFieldValue(sdump, field); + gf_dump_vrml_simple_field(sdump, field); if (sdump->XMLDump) { fprintf(sdump->trace, "/>"); } else { @@ -1575,7 +1645,7 @@ GF_Err DumpMultipleIndexedReplace(GF_SceneDumper *sdump, GF_Command *com) return GF_OK; } -GF_Err DumpMultipleReplace(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpMultipleReplace(GF_SceneDumper *sdump, GF_Command *com) { u32 i; GF_FieldInfo info; @@ -1585,7 +1655,7 @@ GF_Err DumpMultipleReplace(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\">\n"); sdump->indent++; @@ -1597,11 +1667,11 @@ GF_Err DumpMultipleReplace(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); if (gf_sg_vrml_get_sf_type(info.fieldType) != GF_SG_VRML_SFNODE) { fprintf(sdump->trace, "trace, "/>\n"); } else { fprintf(sdump->trace, ""); - DumpField(sdump, com->node, info); + gf_dump_vrml_field(sdump, com->node, info); fprintf(sdump->trace, "\n"); } } @@ -1611,14 +1681,14 @@ GF_Err DumpMultipleReplace(GF_SceneDumper *sdump, GF_Command *com) fprintf(sdump->trace, "\n"); } else { fprintf(sdump->trace, "MULTIPLEREPLACE "); - DumpNodeID(sdump, com->node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, " {\n"); sdump->indent++; i=0; while ((inf = (GF_CommandField *) gf_list_enum(com->command_fields, &i))) { gf_node_get_field(com->node, inf->fieldIndex, &info); info.far_ptr = inf->field_ptr; - DumpField(sdump, com->node, info); + gf_dump_vrml_field(sdump, com->node, info); } sdump->indent--; DUMP_IND(sdump); @@ -1627,7 +1697,7 @@ GF_Err DumpMultipleReplace(GF_SceneDumper *sdump, GF_Command *com) return GF_OK; } -GF_Err DumpGlobalQP(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpGlobalQP(GF_SceneDumper *sdump, GF_Command *com) { GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; @@ -1639,13 +1709,13 @@ GF_Err DumpGlobalQP(GF_SceneDumper *sdump, GF_Command *com) } else { fprintf(sdump->trace, "GLOBALQP "); } - DumpNode(sdump, inf->new_node, 0, NULL); + gf_dump_vrml_node(sdump, inf->new_node, 0, NULL); if (sdump->XMLDump) fprintf(sdump->trace, "\n"); else fprintf(sdump->trace, "\n"); return GF_OK; } -GF_Err DumpNodeInsert(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpNodeInsert(GF_SceneDumper *sdump, GF_Command *com) { GF_CommandField *inf; char posname[20]; @@ -1667,39 +1737,39 @@ GF_Err DumpNodeInsert(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\" position=\"%s\">", posname); } else { if (inf->pos==-1) { fprintf(sdump->trace, "APPEND TO "); } else fprintf(sdump->trace, "INSERT AT "); - DumpNodeID(sdump, com->node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, ".children"); if (inf->pos!=-1) fprintf(sdump->trace, "[%d]", inf->pos); fprintf(sdump->trace, " "); } - DumpNode(sdump, inf->new_node, 0, NULL); + gf_dump_vrml_node(sdump, inf->new_node, 0, NULL); if (sdump->XMLDump) fprintf(sdump->trace, ""); fprintf(sdump->trace, "\n"); return GF_OK; } -GF_Err DumpRouteInsert(GF_SceneDumper *sdump, GF_Command *com, Bool is_scene_replace) +static GF_Err DumpRouteInsert(GF_SceneDumper *sdump, GF_Command *com, Bool is_scene_replace) { GF_Route r; memset(&r, 0, sizeof(GF_Route)); r.ID = com->RouteID; r.name = com->def_name; - r.FromNode = SD_FindNode(sdump, com->fromNodeID); + r.FromNode = gf_dump_find_node(sdump, com->fromNodeID); r.FromField.fieldIndex = com->fromFieldIndex; - r.ToNode = SD_FindNode(sdump, com->toNodeID); + r.ToNode = gf_dump_find_node(sdump, com->toNodeID); r.ToField.fieldIndex = com->toFieldIndex; gf_list_add(sdump->inserted_routes, com); if (is_scene_replace) { - DumpRoute(sdump, &r, 0); + gf_dump_vrml_route(sdump, &r, 0); } else { DUMP_IND(sdump); if (sdump->XMLDump) { @@ -1707,13 +1777,13 @@ GF_Err DumpRouteInsert(GF_SceneDumper *sdump, GF_Command *com, Bool is_scene_rep } else { fprintf(sdump->trace, "INSERT "); } - DumpRoute(sdump, &r, 2); + gf_dump_vrml_route(sdump, &r, 2); if (sdump->XMLDump) fprintf(sdump->trace, ""); } return GF_OK; } -GF_Err DumpIndexInsert(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpIndexInsert(GF_SceneDumper *sdump, GF_Command *com) { GF_Err e; GF_FieldInfo field, sffield; @@ -1741,12 +1811,12 @@ GF_Err DumpIndexInsert(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\" atField=\"%s\" position=\"%s\"", field.name, posname); } else { if (inf->pos==-1) { fprintf(sdump->trace, "APPEND TO "); } else fprintf(sdump->trace, "INSERT AT "); - DumpNodeID(sdump, com->node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, ".%s", field.name); if (inf->pos!=-1) fprintf(sdump->trace, "[%d]", inf->pos); fprintf(sdump->trace, " "); @@ -1757,19 +1827,19 @@ GF_Err DumpIndexInsert(GF_SceneDumper *sdump, GF_Command *com) if (field.fieldType==GF_SG_VRML_MFNODE) { if (sdump->XMLDump) fprintf(sdump->trace, ">\n"); - DumpNode(sdump, inf->new_node, 0, NULL); + gf_dump_vrml_node(sdump, inf->new_node, 0, NULL); if (sdump->XMLDump) fprintf(sdump->trace, ""); fprintf(sdump->trace, "\n"); } else { sffield.far_ptr = inf->field_ptr; - DumpFieldValue(sdump, sffield); + gf_dump_vrml_simple_field(sdump, sffield); if (sdump->XMLDump) fprintf(sdump->trace, "/>"); fprintf(sdump->trace, "\n"); } return e; } -GF_Err DumpIndexDelete(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpIndexDelete(GF_SceneDumper *sdump, GF_Command *com) { char posname[20]; GF_FieldInfo field; @@ -1794,12 +1864,12 @@ GF_Err DumpIndexDelete(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\" atField=\"%s\" position=\"%s\"/>", field.name, posname); } else { fprintf(sdump->trace, "DELETE "); if (inf->pos==-1) fprintf(sdump->trace, "%s ", posname); - DumpNodeID(sdump, com->node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, ".%s", field.name); if (inf->pos!=-1) fprintf(sdump->trace, "[%d]", inf->pos); fprintf(sdump->trace, "\n"); @@ -1808,7 +1878,7 @@ GF_Err DumpIndexDelete(GF_SceneDumper *sdump, GF_Command *com) } -GF_Err DumpNodeDelete(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpNodeDelete(GF_SceneDumper *sdump, GF_Command *com) { DUMP_IND(sdump); if (sdump->XMLDump) { @@ -1817,27 +1887,27 @@ GF_Err DumpNodeDelete(GF_SceneDumper *sdump, GF_Command *com) } else { fprintf(sdump->trace, "node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\"/>\n"); } else { if (com->tag==GF_SG_NODE_DELETE_EX) fprintf(sdump->trace, "X"); fprintf(sdump->trace, "DELETE "); - DumpNodeID(sdump, com->node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\n"); } return GF_OK; } -GF_Err DumpRouteDelete(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpRouteDelete(GF_SceneDumper *sdump, GF_Command *com) { DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "RouteID, com->def_name); + scene_dump_vrml_route_id(sdump, com->RouteID, com->def_name); fprintf(sdump->trace, "\"/>\n"); } else { fprintf(sdump->trace, "DELETE ROUTE "); - DumpRouteID(sdump, com->RouteID, com->def_name); + scene_dump_vrml_route_id(sdump, com->RouteID, com->def_name); fprintf(sdump->trace, "\n"); } return GF_OK; @@ -1845,7 +1915,7 @@ GF_Err DumpRouteDelete(GF_SceneDumper *sdump, GF_Command *com) -GF_Err DumpNodeReplace(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpNodeReplace(GF_SceneDumper *sdump, GF_Command *com) { GF_CommandField *inf; if (!gf_list_count(com->command_fields)) return GF_OK; @@ -1853,21 +1923,21 @@ GF_Err DumpNodeReplace(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\">"); - DumpNode(sdump, inf->new_node, 0, NULL); + gf_dump_vrml_node(sdump, inf->new_node, 0, NULL); fprintf(sdump->trace, "\n"); } else { fprintf(sdump->trace, "REPLACE "); - DumpNodeID(sdump, com->node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, " BY "); - DumpNode(sdump, inf->new_node, 0, NULL); + gf_dump_vrml_node(sdump, inf->new_node, 0, NULL); fprintf(sdump->trace, "\n"); } return GF_OK; } -GF_Err DumpFieldReplace(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpFieldReplace(GF_SceneDumper *sdump, GF_Command *com) { GF_Err e; GF_FieldInfo field; @@ -1880,18 +1950,18 @@ GF_Err DumpFieldReplace(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\" atField=\"%s\" ", field.name); } else { fprintf(sdump->trace, "REPLACE "); - DumpNodeID(sdump, com->node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, ".%s BY ", field.name); } switch (field.fieldType) { case GF_SG_VRML_SFNODE: if (sdump->XMLDump) fprintf(sdump->trace, ">"); - DumpNode(sdump, inf->new_node, 0, NULL); + gf_dump_vrml_node(sdump, inf->new_node, 0, NULL); if (sdump->XMLDump) fprintf(sdump->trace, ""); else fprintf(sdump->trace, "\n"); break; @@ -1906,7 +1976,7 @@ GF_Err DumpFieldReplace(GF_SceneDumper *sdump, GF_Command *com) sdump->indent++; tmp = inf->node_list; while (tmp) { - DumpNode(sdump, tmp->node, 1, NULL); + gf_dump_vrml_node(sdump, tmp->node, 1, NULL); tmp = tmp->next; } sdump->indent--; @@ -1934,7 +2004,7 @@ GF_Err DumpFieldReplace(GF_SceneDumper *sdump, GF_Command *com) break; default: field.far_ptr = inf->field_ptr; - DumpFieldValue(sdump, field); + gf_dump_vrml_simple_field(sdump, field); if (sdump->XMLDump) fprintf(sdump->trace, "/>"); fprintf(sdump->trace, "\n"); } @@ -1942,7 +2012,7 @@ GF_Err DumpFieldReplace(GF_SceneDumper *sdump, GF_Command *com) } -GF_Err DumpIndexReplace(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpIndexReplace(GF_SceneDumper *sdump, GF_Command *com) { char posname[20]; GF_Err e; @@ -1970,12 +2040,12 @@ GF_Err DumpIndexReplace(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, "\" atField=\"%s\" position=\"%s\"", field.name, posname); } else { fprintf(sdump->trace, "REPLACE "); if (inf->pos==-1) fprintf(sdump->trace, "%s ", posname); - DumpNodeID(sdump, com->node); + scene_dump_vrml_id(sdump, com->node); fprintf(sdump->trace, ".%s", field.name); if (inf->pos!=-1) fprintf(sdump->trace, "[%d]", inf->pos); fprintf(sdump->trace, " BY "); @@ -1983,47 +2053,176 @@ GF_Err DumpIndexReplace(GF_SceneDumper *sdump, GF_Command *com) if (field.fieldType == GF_SG_VRML_MFNODE) { if (sdump->XMLDump) fprintf(sdump->trace, ">\n"); - DumpNode(sdump, inf->new_node, 0, NULL); + gf_dump_vrml_node(sdump, inf->new_node, 0, NULL); fprintf(sdump->trace, (sdump->XMLDump) ? "\n" : "\n"); } else { field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); field.far_ptr = inf->field_ptr; - DumpFieldValue(sdump, field); + gf_dump_vrml_simple_field(sdump, field); fprintf(sdump->trace, sdump->XMLDump ? "/>\n" : "\n"); } return GF_OK; } -GF_Err DumpRouteReplace(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpXReplace(GF_SceneDumper *sdump, GF_Command *com) +{ + char posname[20]; + GF_Err e; + GF_FieldInfo field, idxField; + GF_Node *toNode, *target; + GF_CommandField *inf; + if (!gf_list_count(com->command_fields)) return GF_OK; + inf = (GF_CommandField *) gf_list_get(com->command_fields, 0); + + e = gf_node_get_field(com->node, inf->fieldIndex, &field); + if (e) return e; + + toNode = target = NULL; + /*indexed replacement with index given by other node field*/ + if (com->toNodeID) { + toNode = gf_sg_find_node(com->in_scene, com->toNodeID); + if (!toNode) return GF_NON_COMPLIANT_BITSTREAM; + e = gf_node_get_field(toNode, com->toFieldIndex, &idxField); + } + else { + /*indexed replacement */ + if (inf->pos>=-1) { + if (gf_sg_vrml_is_sf_field(field.fieldType)) return GF_NON_COMPLIANT_BITSTREAM; + switch (inf->pos) { + case 0: + strcpy(posname, "BEGIN"); + break; + case -1: + strcpy(posname, sdump->XMLDump ? "END" : "LAST"); + break; + default: + sprintf(posname, "%d", inf->pos); + break; + } + field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); + } + } + field.far_ptr = inf->field_ptr; + + DUMP_IND(sdump); + if (sdump->XMLDump) { + fprintf(sdump->trace, "node); + fprintf(sdump->trace, "\" atField=\"%s\"", field.name); + + if (toNode) { + fprintf(sdump->trace, " atIndexNode=\""); + scene_dump_vrml_id(sdump, toNode); + fprintf(sdump->trace, "\" atIndexField=\"%s\"", idxField.name); + + field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); + } + if (com->ChildNodeTag) { + GF_FieldInfo cfield; + GF_Node *cnode; + + if (com->ChildNodeTag>0) { + cnode = gf_node_new(com->in_scene, com->ChildNodeTag); + } else { + GF_Proto *proto = gf_sg_find_proto(com->in_scene, -com->ChildNodeTag , NULL); + if (!proto) return GF_SG_UNKNOWN_NODE; + cnode = gf_sg_proto_create_instance(com->in_scene, proto); + } + if (!cnode) return GF_SG_UNKNOWN_NODE; + gf_node_register(cnode, NULL); + gf_node_get_field(cnode, com->child_field, &cfield); + fprintf(sdump->trace, " atChildField=\"%s\"", cfield.name); + gf_node_unregister(cnode, NULL); + + field.fieldType = cfield.fieldType; + } + + if (com->fromNodeID) { + target = gf_sg_find_node(com->in_scene, com->fromNodeID); + if (!target) return GF_NON_COMPLIANT_BITSTREAM; + e = gf_node_get_field(target, com->fromFieldIndex, &idxField); + + fprintf(sdump->trace, " fromNode=\""); + scene_dump_vrml_id(sdump, target); + fprintf(sdump->trace, "\" fromField=\"%s\">\n", idxField.name); + return GF_OK; + } else { + if (inf->pos>=-1) fprintf(sdump->trace, " position=\"%s\"", posname); + } + } else { + fprintf(sdump->trace, "XREPLACE "); + if (inf->pos==-1) fprintf(sdump->trace, "%s ", posname); + scene_dump_vrml_id(sdump, com->node); + fprintf(sdump->trace, ".%s", field.name); + if (toNode) { + fprintf(sdump->trace, "["); + scene_dump_vrml_id(sdump, toNode); + fprintf(sdump->trace, ".%s]", idxField.name); + field.fieldType = gf_sg_vrml_get_sf_type(field.fieldType); + } + else if (inf->pos!=-1) fprintf(sdump->trace, "[%d]", inf->pos); + if (com->ChildNodeTag) { + GF_FieldInfo cfield; + GF_Node *cnode; + if (com->ChildNodeTag>0) { + cnode = gf_node_new(com->in_scene, com->ChildNodeTag); + } else { + GF_Proto *proto = gf_sg_find_proto(com->in_scene, -com->ChildNodeTag , NULL); + if (!proto) return GF_SG_UNKNOWN_NODE; + cnode = gf_sg_proto_create_instance(com->in_scene, proto); + } + if (!cnode) return GF_SG_UNKNOWN_NODE; + gf_node_register(cnode, NULL); + gf_node_get_field(cnode, com->child_field, &cfield); + fprintf(sdump->trace, ".%s", cfield.name); + gf_node_unregister(cnode, NULL); + field.fieldType = cfield.fieldType; + } + fprintf(sdump->trace, " BY "); + } + + if (field.fieldType == GF_SG_VRML_MFNODE) { + if (sdump->XMLDump) fprintf(sdump->trace, ">\n"); + gf_dump_vrml_node(sdump, inf->new_node, 0, NULL); + fprintf(sdump->trace, (sdump->XMLDump) ? "\n" : "\n"); + } else { + gf_dump_vrml_simple_field(sdump, field); + fprintf(sdump->trace, sdump->XMLDump ? "/>\n" : "\n"); + } + return GF_OK; +} + + +static GF_Err DumpRouteReplace(GF_SceneDumper *sdump, GF_Command *com) { const char *name; GF_Route r2; - if (!DumpFindRouteName(sdump, com->RouteID, &name)) return GF_BAD_PARAM; + if (!scene_dump_vrml_find_route_name(sdump, com->RouteID, &name)) return GF_BAD_PARAM; memset(&r2, 0, sizeof(GF_Route)); - r2.FromNode = SD_FindNode(sdump, com->fromNodeID); + r2.FromNode = gf_dump_find_node(sdump, com->fromNodeID); r2.FromField.fieldIndex = com->fromFieldIndex; - r2.ToNode = SD_FindNode(sdump, com->toNodeID); + r2.ToNode = gf_dump_find_node(sdump, com->toNodeID); r2.ToField.fieldIndex = com->toFieldIndex; DUMP_IND(sdump); if (sdump->XMLDump) { fprintf(sdump->trace, "RouteID, (char *) name); + scene_dump_vrml_route_id(sdump, com->RouteID, (char *) name); fprintf(sdump->trace, "\">\n"); } else { fprintf(sdump->trace, "REPLACE ROUTE "); - DumpRouteID(sdump, com->RouteID, (char *) name); + scene_dump_vrml_route_id(sdump, com->RouteID, (char *) name); fprintf(sdump->trace, " BY "); } - DumpRoute(sdump, &r2, 1); + gf_dump_vrml_route(sdump, &r2, 1); if (sdump->XMLDump ) fprintf(sdump->trace, ""); return GF_OK; } -GF_Err DumpRoute(GF_SceneDumper *sdump, GF_Route *r, u32 dump_type) +static GF_Err gf_dump_vrml_route(GF_SceneDumper *sdump, GF_Route *r, u32 dump_type) { char toNode[512], fromNode[512]; const char *node_name; @@ -2049,7 +2248,7 @@ GF_Err DumpRoute(GF_SceneDumper *sdump, GF_Route *r, u32 dump_type) fprintf(sdump->trace, "ID) { StartAttribute(sdump, "DEF"); - DumpRouteID(sdump, r->ID, r->name); + scene_dump_vrml_route_id(sdump, r->ID, r->name); EndAttribute(sdump); } fprintf(sdump->trace, " fromNode=\"%s\" fromField=\"%s\" toNode=\"%s\" toField=\"%s\"/>\n", fromNode, r->FromField.name, toNode, r->ToField.name); @@ -2057,7 +2256,7 @@ GF_Err DumpRoute(GF_SceneDumper *sdump, GF_Route *r, u32 dump_type) if (dump_type==2) fprintf(sdump->trace, "ROUTE "); if (r->ID) { fprintf(sdump->trace, "DEF "); - DumpRouteID(sdump, r->ID, r->name); + scene_dump_vrml_route_id(sdump, r->ID, r->name); fprintf(sdump->trace, " "); } if (dump_type==1) { @@ -2071,8 +2270,11 @@ GF_Err DumpRoute(GF_SceneDumper *sdump, GF_Route *r, u32 dump_type) } -GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList) +static GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList) { +#ifdef GPAC_DISABLE_VRML + return GF_OK; +#else u32 i, j, count; GF_FieldInfo field; GF_Err e; @@ -2093,7 +2295,7 @@ GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList) fprintf(sdump->trace, "Name, proto->ID); if (proto->ExternProto.count) { fprintf(sdump->trace, " locations=\""); - DumpSFField(sdump, GF_SG_VRML_SFURL, &proto->ExternProto.vals[0], 0); + gf_dump_vrml_sffield(sdump, GF_SG_VRML_SFURL, &proto->ExternProto.vals[0], 0); fprintf(sdump->trace, "\""); } fprintf(sdump->trace, ">\n"); @@ -2113,7 +2315,7 @@ GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList) field.NDTtype = NDT_SFWorldNode; field.on_event_in = NULL; - DumpDynField(sdump, NULL, field, pf->QP_Type ? 1 : 0); + gf_dump_vrml_dyn_field(sdump, NULL, field, pf->QP_Type ? 1 : 0); if (!pf->QP_Type) continue; @@ -2125,6 +2327,7 @@ GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList) } else { fprintf(sdump->trace, "{QP %d", pf->QP_Type); } +#ifndef GPAC_DISABLE_BIFS if (pf->QP_Type==QC_LINEAR_SCALAR) fprintf(sdump->trace, sdump->XMLDump ? " nbBits=\"%d\"" : " nbBits %d", pf->NumBits); if (pf->hasMinMax) { switch (pf->QP_Type) { @@ -2145,6 +2348,7 @@ GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList) break; } } +#endif fprintf(sdump->trace, sdump->XMLDump ? "/>\n" : "}\n"); sdump->indent--; if (sdump->XMLDump) { @@ -2163,7 +2367,7 @@ GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList) if (proto->ExternProto.count) { if (!sdump->XMLDump) { fprintf(sdump->trace, " \""); - DumpSFField(sdump, GF_SG_VRML_SFURL, &proto->ExternProto.vals[0], 0); + gf_dump_vrml_sffield(sdump, GF_SG_VRML_SFURL, &proto->ExternProto.vals[0], 0); fprintf(sdump->trace, "\"\n\n"); } else { fprintf(sdump->trace, "\n"); @@ -2186,13 +2390,13 @@ GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList) count = gf_list_count(proto->node_code); for (j=0; jnode_code, j); - DumpNode(sdump, n, 1, NULL); + gf_dump_vrml_node(sdump, n, 1, NULL); } count = gf_list_count(proto->sub_graph->Routes); for (j=0; jsub_graph->Routes, j); if (r->IS_route) continue; - DumpRoute(sdump, r, 0); + gf_dump_vrml_route(sdump, r, 0); } if (sdump->XMLDump && sdump->X3DDump) fprintf(sdump->trace, "\n"); @@ -2210,9 +2414,10 @@ GF_Err DumpProtos(GF_SceneDumper *sdump, GF_List *protoList) } sdump->current_proto = prev_proto; return GF_OK; +#endif } -GF_Err DumpSceneReplace(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpSceneReplace(GF_SceneDumper *sdump, GF_Command *com) { if (sdump->XMLDump) { if (!sdump->X3DDump) { @@ -2221,7 +2426,11 @@ GF_Err DumpSceneReplace(GF_SceneDumper *sdump, GF_Command *com) sdump->indent++; } StartElement(sdump, "Scene"); - if (!sdump->X3DDump && com->use_names) DumpBool(sdump, "USENAMES", com->use_names); + if (!sdump->X3DDump && com->use_names) { + StartAttribute(sdump, "USENAMES"); + fprintf(sdump->trace, "%s", com->use_names ? "true" : "false"); + EndAttribute(sdump); + } EndElementHeader(sdump, 1); sdump->indent++; } else { @@ -2231,13 +2440,23 @@ GF_Err DumpSceneReplace(GF_SceneDumper *sdump, GF_Command *com) } } DumpProtos(sdump, com->new_proto_list); - DumpNode(sdump, com->node, 0, NULL); + gf_dump_vrml_node(sdump, com->node, 0, NULL); if (!sdump->XMLDump) fprintf(sdump->trace, "\n\n"); + if (com->aggregated) { + u32 i, count; + count = gf_list_count(com->node->sgprivate->scenegraph->Routes); + for (i=0; inode->sgprivate->scenegraph->Routes, i); + if (r->IS_route) continue; + gf_dump_vrml_route(sdump, r, 0); + } + } + return GF_OK; } -GF_Err DumpProtoInsert(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpProtoInsert(GF_SceneDumper *sdump, GF_Command *com) { DUMP_IND(sdump); if (sdump->XMLDump) { @@ -2257,6 +2476,8 @@ GF_Err DumpProtoInsert(GF_SceneDumper *sdump, GF_Command *com) return GF_OK; } +#endif /*GPAC_DISABLE_VRML*/ + #ifndef GPAC_DISABLE_SVG static char *lsr_format_node_id(GF_Node *n, u32 NodeID, char *str) @@ -2282,18 +2503,18 @@ static char *sd_get_lsr_namespace(GF_SceneGraph *sg) return ""; } -GF_Err DumpLSRNewScene(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpLSRNewScene(GF_SceneDumper *sdump, GF_Command *com) { char *lsrns = sd_get_lsr_namespace(com->in_scene); fprintf(sdump->trace, "<%sNewScene>\n", lsrns); - SD_DumpSVG_Element(sdump, com->node, NULL, 0); + gf_dump_svg_element(sdump, com->node, NULL, 0); fprintf(sdump->trace, "\n", lsrns); return GF_OK; } -GF_Err DumpLSRAddReplaceInsert(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpLSRAddReplaceInsert(GF_SceneDumper *sdump, GF_Command *com) { - char szAtt[80000]; + char szID[100]; Bool is_text = 0; GF_CommandField *f; char *lsrns = sd_get_lsr_namespace(com->in_scene); @@ -2302,7 +2523,7 @@ GF_Err DumpLSRAddReplaceInsert(GF_SceneDumper *sdump, GF_Command *com) DUMP_IND(sdump); - fprintf(sdump->trace, "<%s%s ref=\"%s\" ", lsrns, com_name, lsr_format_node_id(com->node, com->RouteID, szAtt)); + fprintf(sdump->trace, "<%s%s ref=\"%s\" ", lsrns, com_name, lsr_format_node_id(com->node, com->RouteID, szID)); f = (GF_CommandField *) gf_list_get(com->command_fields, 0); if (f && (f->pos>=0) ) fprintf(sdump->trace, "index=\"%d\" ", f->pos); if (f) { @@ -2317,23 +2538,25 @@ GF_Err DumpLSRAddReplaceInsert(GF_SceneDumper *sdump, GF_Command *com) fprintf(sdump->trace, "attributeName=\"%s\" ", att_name); if (f->field_ptr) { + char *att; info.far_ptr = f->field_ptr; info.fieldIndex = f->fieldIndex; info.fieldType = f->fieldType; info.name = att_name; if ((s32) f->pos >= 0) { - gf_svg_dump_attribute_indexed(com->node, &info, szAtt); + att = gf_svg_dump_attribute_indexed(com->node, &info); } else { - gf_svg_dump_attribute(com->node, &info, szAtt); + att = gf_svg_dump_attribute(com->node, &info); } - fprintf(sdump->trace, "value=\"%s\" ", szAtt); + fprintf(sdump->trace, "value=\"%s\" ", att ? att : ""); + if (att) gf_free(att); } if (com->fromNodeID) { GF_FieldInfo op_info; GF_Node *op = gf_sg_find_node(sdump->sg, com->fromNodeID); - fprintf(sdump->trace, "operandElementId=\"%s\" ", lsr_format_node_id(op, com->RouteID, szAtt)); + fprintf(sdump->trace, "operandElementId=\"%s\" ", lsr_format_node_id(op, com->RouteID, szID)); gf_node_get_field(op, com->fromFieldIndex, &op_info); fprintf(sdump->trace, "operandAttributeName=\"%s\" ", op_info.name); } @@ -2354,11 +2577,11 @@ GF_Err DumpLSRAddReplaceInsert(GF_SceneDumper *sdump, GF_Command *com) sdump->indent++; } if (f->new_node) { - SD_DumpSVG_Element(sdump, f->new_node, com->node, 0); + gf_dump_svg_element(sdump, f->new_node, com->node, 0); } else if (f->node_list) { GF_ChildNodeItem *list = f->node_list; while (list) { - SD_DumpSVG_Element(sdump, list->node, com->node, 0); + gf_dump_svg_element(sdump, list->node, com->node, 0); list = list->next; } } @@ -2367,11 +2590,11 @@ GF_Err DumpLSRAddReplaceInsert(GF_SceneDumper *sdump, GF_Command *com) fprintf(sdump->trace, "\n", lsrns, com_name); return GF_OK; } -GF_Err DumpLSRClean(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpLSRClean(GF_SceneDumper *sdump, GF_Command *com) { return GF_OK; } -GF_Err DumpLSRDelete(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpLSRDelete(GF_SceneDumper *sdump, GF_Command *com) { char szID[1024]; GF_CommandField *f; @@ -2383,19 +2606,19 @@ GF_Err DumpLSRDelete(GF_SceneDumper *sdump, GF_Command *com) fprintf(sdump->trace, "/>\n"); return GF_OK; } -GF_Err DumpLSRInsert(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpLSRInsert(GF_SceneDumper *sdump, GF_Command *com) { return GF_OK; } -GF_Err DumpLSRRestore(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpLSRRestore(GF_SceneDumper *sdump, GF_Command *com) { return GF_OK; } -GF_Err DumpLSRSave(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpLSRSave(GF_SceneDumper *sdump, GF_Command *com) { return GF_OK; } -GF_Err DumpLSRSendEvent(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpLSRSendEvent(GF_SceneDumper *sdump, GF_Command *com) { char szID[1024]; char *lsrns = sd_get_lsr_namespace(com->in_scene); @@ -2427,7 +2650,7 @@ GF_Err DumpLSRSendEvent(GF_SceneDumper *sdump, GF_Command *com) fprintf(sdump->trace, "/>\n"); return GF_OK; } -GF_Err DumpLSRActivate(GF_SceneDumper *sdump, GF_Command *com) +static GF_Err DumpLSRActivate(GF_SceneDumper *sdump, GF_Command *com) { char szID[1024]; char *lsrns = sd_get_lsr_namespace(com->in_scene); @@ -2468,6 +2691,7 @@ GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 inde GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[Scene Dump] MPEG-4 Commands found, not supported in %s - skipping\n", sdump->X3DDump ? "X3D" : "VRML")); break; } +#ifndef GPAC_DISABLE_VRML if (has_scene_replace && (com->tag != GF_SG_ROUTE_INSERT)) { has_scene_replace = 0; if (sdump->XMLDump) { @@ -2477,7 +2701,10 @@ GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 inde EndElement(sdump, "Replace", 1); } } +#endif + switch (com->tag) { +#ifndef GPAC_DISABLE_VRML /*insert commands*/ case GF_SG_NODE_INSERT: e = DumpNodeInsert(sdump, com); break; case GF_SG_INDEXED_INSERT: e = DumpIndexInsert(sdump, com); break; @@ -2494,6 +2721,7 @@ GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 inde case GF_SG_FIELD_REPLACE: e = DumpFieldReplace(sdump, com); break; case GF_SG_INDEXED_REPLACE: e = DumpIndexReplace(sdump, com); break; case GF_SG_ROUTE_REPLACE: e = DumpRouteReplace(sdump, com); break; + case GF_SG_XREPLACE: e = DumpXReplace(sdump, com); break; case GF_SG_SCENE_REPLACE: /*we don't support replace scene in conditional*/ assert(!sdump->current_com_list); @@ -2540,6 +2768,9 @@ GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 inde case GF_SG_MULTIPLE_INDEXED_REPLACE: e = DumpMultipleIndexedReplace(sdump, com); break; case GF_SG_NODE_DELETE_EX: e = DumpNodeDelete(sdump, com); break; +#endif + + #ifndef GPAC_DISABLE_SVG /*laser commands*/ case GF_SG_LSR_NEW_SCENE: e = DumpLSRNewScene(sdump, com); break; @@ -2589,10 +2820,10 @@ GF_Err gf_sm_dump_command_list(GF_SceneDumper *sdump, GF_List *comList, u32 inde } #ifndef GPAC_DISABLE_SVG -void SD_DumpSVG_Element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool is_root) +void gf_dump_svg_element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool is_root) { GF_ChildNodeItem *list; - char attName[100], attValue[81920]; + char attName[100], *attValue, attID[100]; u32 i, count, nID; Bool needs_cr; SVG_Element *svg = (SVG_Element *)n; @@ -2628,7 +2859,7 @@ void SD_DumpSVG_Element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool fprintf(sdump->trace, "%s", txt->textContent); fprintf(sdump->trace, "]]>"); } else if (txt->type==GF_DOM_TEXT_REGULAR) { - DumpUTFString(sdump, 0, txt->textContent); + scene_dump_utf_string(sdump, 0, txt->textContent); } } } @@ -2646,7 +2877,7 @@ void SD_DumpSVG_Element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool fprintf(sdump->trace, "<%s", gf_node_get_class_name(n)); ns = gf_xml_get_element_namespace(n); - if (nID) fprintf(sdump->trace, " id=\"%s\"", lsr_format_node_id(n, 0, attValue)); + if (nID) fprintf(sdump->trace, " id=\"%s\"", lsr_format_node_id(n, 0, attID)); att = svg->attributes; while (att) { @@ -2691,9 +2922,12 @@ void SD_DumpSVG_Element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool } } info.far_ptr = att->data; - gf_svg_dump_attribute((GF_Node*)svg, &info, attValue); + attValue = gf_svg_dump_attribute((GF_Node*)svg, &info); if (/*strcmp(info.name, "xmlns") &&*/ (info.fieldType = strlen(attValue))) fprintf(sdump->trace, " %s=\"%s\"", info.name, attValue); + + if (attValue) gf_free(attValue); + fflush(sdump->trace); att = att->next; } @@ -2724,8 +2958,9 @@ void SD_DumpSVG_Element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool } } } - if (svg->children) fprintf(sdump->trace, ">"); - else { + if (svg->children) { + fprintf(sdump->trace, ">"); + } else { fprintf(sdump->trace, "/>"); return; } @@ -2753,7 +2988,7 @@ void SD_DumpSVG_Element(GF_SceneDumper *sdump, GF_Node *n, GF_Node *parent, Bool list = svg->children; while (list) { if (!sdump->in_text) fprintf(sdump->trace, "\n"); - SD_DumpSVG_Element(sdump, list->node, n, 0); + gf_dump_svg_element(sdump, list->node, n, 0); list = list->next; } if (!sdump->in_text) fprintf(sdump->trace, "\n"); @@ -2774,7 +3009,7 @@ static void gf_sm_dump_saf_hdr(GF_SceneDumper *dumper, char *unit_name, u64 au_t fprintf(dumper->trace, ">\n"); } -void dump_od_to_saf(GF_SceneDumper *dumper, GF_AUContext *au, u32 indent) +static void dump_od_to_saf(GF_SceneDumper *dumper, GF_AUContext *au, u32 indent) { u32 i, count; @@ -2814,13 +3049,13 @@ void dump_od_to_saf(GF_SceneDumper *dumper, GF_AUContext *au, u32 indent) } -GF_Err SD_SetSceneGraph(GF_SceneDumper *sdump, GF_SceneGraph *sg) +static GF_Err SD_SetSceneGraph(GF_SceneDumper *sdump, GF_SceneGraph *sg) { if (sdump) sdump->sg = sg; return GF_OK; } -GF_Err SD_DumpDOMElement(GF_SceneDumper *sdump, GF_DOMFullNode *node) +static GF_Err SD_DumpDOMElement(GF_SceneDumper *sdump, GF_DOMFullNode *node) { const char *ns; u32 child_type = 0; @@ -2855,7 +3090,7 @@ GF_Err SD_DumpDOMElement(GF_SceneDumper *sdump, GF_DOMFullNode *node) child_type = 2; txt = (GF_DOMText *)child->node; if (txt->type==GF_DOM_TEXT_REGULAR) { - DumpUTFString(sdump, 0, txt->textContent); + scene_dump_utf_string(sdump, 0, txt->textContent); } else if (txt->type==GF_DOM_TEXT_CDATA) { fprintf(sdump->trace, ""); fprintf(sdump->trace, "%s", txt->textContent); @@ -2889,13 +3124,15 @@ GF_Err gf_sm_dump_graph(GF_SceneDumper *sdump, Bool skip_proto, Bool skip_routes tag = sdump->sg->RootNode->sgprivate->tag; if (tag<=GF_NODE_RANGE_LAST_X3D) { - SD_SetupDump(sdump, NULL); + gf_dump_setup(sdump, NULL); if (sdump->XMLDump) { StartElement(sdump, "Scene"); EndElementHeader(sdump, 1); sdump->indent++; } +#ifndef GPAC_DISABLE_VRML + if (!skip_proto) { e = DumpProtos(sdump, sdump->sg->protos); if (e) return e; @@ -2904,11 +3141,11 @@ GF_Err gf_sm_dump_graph(GF_SceneDumper *sdump, Bool skip_proto, Bool skip_routes if (sdump->X3DDump) { GF_ChildNodeItem *list = ((GF_ParentNode *)sdump->sg->RootNode)->children; while (list) { - DumpNode(sdump, list->node, 0, NULL); + gf_dump_vrml_node(sdump, list->node, 0, NULL); list = list->next; } } else { - DumpNode(sdump, sdump->sg->RootNode, 0, NULL); + gf_dump_vrml_node(sdump, sdump->sg->RootNode, 0, NULL); } if (!sdump->XMLDump) fprintf(sdump->trace, "\n\n"); if (!skip_routes) { @@ -2916,7 +3153,7 @@ GF_Err gf_sm_dump_graph(GF_SceneDumper *sdump, Bool skip_proto, Bool skip_routes u32 i=0; while ((r = (GF_Route*)gf_list_enum(sdump->sg->Routes, &i))) { if (r->IS_route || (r->graph!=sdump->sg)) continue; - e = DumpRoute(sdump, r, 0); + e = gf_dump_vrml_route(sdump, r, 0); if (e) return e; } } @@ -2924,20 +3161,21 @@ GF_Err gf_sm_dump_graph(GF_SceneDumper *sdump, Bool skip_proto, Bool skip_routes sdump->indent--; EndElement(sdump, "Scene", 1); } +#endif /*GPAC_DISABLE_VRML*/ - SD_FinalizeDump(sdump, NULL); + gf_dump_finalize(sdump, NULL); return GF_OK; } #ifndef GPAC_DISABLE_SVG else if ((tag>=GF_NODE_RANGE_FIRST_SVG) && (tag<=GF_NODE_RANGE_LAST_SVG)) { sdump->dump_mode = GF_SM_DUMP_SVG; - SD_SetupDump(sdump, NULL); - SD_DumpSVG_Element(sdump, sdump->sg->RootNode, NULL, 1); + gf_dump_setup(sdump, NULL); + gf_dump_svg_element(sdump, sdump->sg->RootNode, NULL, 1); return GF_OK; } else if (tag==TAG_DOMFullNode) { sdump->dump_mode = GF_SM_DUMP_XML; - SD_SetupDump(sdump, NULL); + gf_dump_setup(sdump, NULL); SD_DumpDOMElement(sdump, (GF_DOMFullNode*)sdump->sg->RootNode); } #endif @@ -3042,7 +3280,7 @@ GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode) num_scene = (num_scene>1) ? 1 : 0; num_od = (num_od>1) ? 1 : 0; - SD_SetupDump(dumper, (GF_Descriptor *) ctx->root_od); + gf_dump_setup(dumper, (GF_Descriptor *) ctx->root_od); #ifndef GPAC_DISABLE_SVG if (dumper->dump_mode==GF_SM_DUMP_SVG) { @@ -3050,13 +3288,13 @@ GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode) GF_Command *com = NULL; if (au) com = (GF_Command*)gf_list_get(au->commands, 0); if (!au) { - SD_DumpSVG_Element(dumper, dumper->sg->RootNode, NULL, 1); + gf_dump_svg_element(dumper, dumper->sg->RootNode, NULL, 1); } else if (!com || (com->tag!=GF_SG_LSR_NEW_SCENE) || !com->node) { e = GF_NOT_SUPPORTED; } else { - SD_DumpSVG_Element(dumper, com->node, NULL, 1); + gf_dump_svg_element(dumper, com->node, NULL, 1); } - SD_FinalizeDump(dumper, (GF_Descriptor *) ctx->root_od); + gf_dump_finalize(dumper, (GF_Descriptor *) ctx->root_od); gf_sm_dumper_del(dumper); gf_list_del(sample_list); return e; @@ -3074,7 +3312,7 @@ GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode) if (!dumper->XMLDump) { if (!first_bifs || (au->owner->streamType != GF_STREAM_SCENE) ) { - if (au->is_rap) fprintf(dumper->trace, "RAP "); + if (au->flags & GF_SM_AU_RAP) fprintf(dumper->trace, "RAP "); fprintf(dumper->trace, "AT "LLD" ", LLD_CAST au->timing); if ( (au->owner->streamType==GF_STREAM_OD && num_od) || (au->owner->streamType==GF_STREAM_SCENE && num_scene)) { fprintf(dumper->trace, "IN %d ", au->owner->ESID); @@ -3088,7 +3326,7 @@ GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode) if (dumper->LSRDump) { dump_od_to_saf(dumper, au, indent); } else { -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_OD_DUMP e = gf_odf_dump_com_list(au->commands, dumper->trace, indent+1, 0); #endif } @@ -3134,7 +3372,7 @@ GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode) if (dumper->LSRDump) { dump_od_to_saf(dumper, au, indent+1); } else { -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_OD_DUMP e = gf_odf_dump_com_list(au->commands, dumper->trace, indent+1, 1); #endif } @@ -3142,7 +3380,7 @@ GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode) case GF_STREAM_SCENE: if (gf_list_count(au->commands)) { if (dumper->LSRDump) - gf_sm_dump_saf_hdr(dumper, "sceneUnit", au->timing, au->is_rap); + gf_sm_dump_saf_hdr(dumper, "sceneUnit", au->timing, au->flags & GF_SM_AU_RAP); e = gf_sm_dump_command_list(dumper, au->commands, indent+1, first_bifs); first_bifs = 0; @@ -3157,18 +3395,22 @@ GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode) } if (dumper->X3DDump || (dumper->dump_mode==GF_SM_DUMP_VRML)) break; } + +#ifndef GPAC_DISABLE_VRML if (no_root_found && ctx->scene_graph->RootNode) { GF_Route *r; DumpProtos(dumper, ctx->scene_graph->protos); - DumpNode(dumper, ctx->scene_graph->RootNode, 0, NULL); + gf_dump_vrml_node(dumper, ctx->scene_graph->RootNode, 0, NULL); i=0; fprintf(dumper->trace, "\n"); while ((r = (GF_Route*)gf_list_enum(dumper->sg->Routes, &i))) { if (r->IS_route || (r->graph!=dumper->sg)) continue; - e = DumpRoute(dumper, r, 0); + e = gf_dump_vrml_route(dumper, r, 0); if (e) return e; } } +#endif + /*close command*/ if (!dumper->X3DDump && first_par) fprintf(dumper->trace, " </par>\n"); @@ -3177,11 +3419,10 @@ GF_Err gf_sm_dump(GF_SceneManager *ctx, char *rad_name, u32 dump_mode) GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[Scene Dump] MPEG-4 Commands found, not supported in %s - skipping\n", dumper->X3DDump ? "X3D" : "VRML")); } - SD_FinalizeDump(dumper, (GF_Descriptor *) ctx->root_od); + gf_dump_finalize(dumper, (GF_Descriptor *) ctx->root_od); gf_sm_dumper_del(dumper); gf_list_del(sample_list); return e; } -//#endif - +#endif /*GPAC_DISABLE_SCENE_DUMP*/ diff --git a/src/scene_manager/scene_engine.c b/src/scene_manager/scene_engine.c new file mode 100644 index 0000000..dc4b0b4 --- /dev/null +++ b/src/scene_manager/scene_engine.c @@ -0,0 +1,1140 @@ +/* + * GPAC Multimedia Framework + * + * Authors: Cyril Concolato - Jean le Feuvre + * Copyright (c) 2005-200X ENST + * 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/scene_engine.h> + +#ifndef GPAC_DISABLE_SENG +#include <gpac/scene_manager.h> + +#ifndef GPAC_DISABLE_BIFS_ENC +#include <gpac/bifs.h> +#endif + +#ifndef GPAC_DISABLE_VRML +#include <gpac/nodes_mpeg4.h> +#endif + +#ifndef GPAC_DISABLE_LASER +#include <gpac/laser.h> +#endif + +#include <gpac/constants.h> +#include <gpac/base_coding.h> + +#include <time.h> + +/* for DIMS GZ encoding */ +#include <zlib.h> + +struct __tag_scene_engine +{ + GF_SceneGraph *sg; + GF_SceneManager *ctx; + GF_SceneLoader loader; + void *calling_object; + Bool owns_context; +#ifndef GPAC_DISABLE_BIFS_ENC + GF_BifsEncoder *bifsenc; +#endif +#ifndef GPAC_DISABLE_LASER + GF_LASeRCodec *lsrenc; +#endif + + u32 start_time; + + char *dump_path; + + Bool embed_resources; + Bool dump_rap; +}; + +#ifndef GPAC_DISABLE_BIFS_ENC +static GF_Err gf_sm_setup_bifsenc(GF_SceneEngine *seng, GF_StreamContext *sc, GF_ESD *esd) +{ + GF_Err e; + char *data; + u32 data_len; + u32 nbb; + Bool encode_names, delete_bcfg; + GF_BIFSConfig *bcfg; + + if (!esd->decoderConfig || (esd->decoderConfig->streamType != GF_STREAM_SCENE)) return GF_BAD_PARAM; + + e = GF_OK; + if (!seng->bifsenc) + seng->bifsenc = gf_bifs_encoder_new(seng->ctx->scene_graph); + + delete_bcfg = 0; + /*inputctx is not properly setup, do it*/ + if (!esd->decoderConfig->decoderSpecificInfo) { + bcfg = (GF_BIFSConfig*)gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG); + bcfg->pixelMetrics = seng->ctx->is_pixel_metrics; + bcfg->pixelWidth = seng->ctx->scene_width; + bcfg->pixelHeight = seng->ctx->scene_height; + delete_bcfg = 1; + } + /*regular case*/ + else if (esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_BIFS_CFG_TAG) { + bcfg = (GF_BIFSConfig *)esd->decoderConfig->decoderSpecificInfo; + } + /*happens when loading from MP4 in which case BIFSc is not decoded*/ + else { + bcfg = gf_odf_get_bifs_config(esd->decoderConfig->decoderSpecificInfo, esd->decoderConfig->objectTypeIndication); + delete_bcfg = 1; + } + + /*NO CHANGE TO BIFSC otherwise the generated update will not match the input context + The only case we modify the bifs config is when XXXBits is not specified*/ + nbb = gf_get_bit_size(seng->ctx->max_node_id); + if (!bcfg->nodeIDbits) bcfg->nodeIDbits = nbb; + else if (bcfg->nodeIDbits<nbb) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.NodeIDBits too small (%d bits vs %d nodes)\n", bcfg->nodeIDbits, seng->ctx->max_node_id)); + } + nbb = gf_get_bit_size(seng->ctx->max_route_id); + if (!bcfg->routeIDbits) bcfg->routeIDbits = nbb; + else if (bcfg->routeIDbits<nbb) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.RouteIDBits too small (%d bits vs %d routes)\n", bcfg->routeIDbits, seng->ctx->max_route_id)); + } + nbb = gf_get_bit_size(seng->ctx->max_proto_id); + if (!bcfg->protoIDbits) bcfg->protoIDbits=nbb; + else if (bcfg->protoIDbits<nbb) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CODING, ("[BIFS] BIFSConfig.ProtoIDBits too small (%d bits vs %d protos)\n", bcfg->protoIDbits, seng->ctx->max_proto_id)); + } + + /*this is the real pb, not stored in cfg or file level, set at EACH replaceScene*/ + encode_names = 0; + + /* The BIFS Config that is passed here should be the BIFSConfig from the IOD */ + gf_bifs_encoder_new_stream(seng->bifsenc, esd->ESID, bcfg, encode_names, 0); + if (delete_bcfg) gf_odf_desc_del((GF_Descriptor *)bcfg); + + gf_bifs_encoder_get_config(seng->bifsenc, esd->ESID, &data, &data_len); + + if (esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo); + esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); + esd->decoderConfig->decoderSpecificInfo->data = data; + esd->decoderConfig->decoderSpecificInfo->dataLength = data_len; + + sc->dec_cfg = gf_malloc(sizeof(char)*data_len); + memcpy(sc->dec_cfg, data, data_len); + sc->dec_cfg_len = data_len; + + esd->decoderConfig->objectTypeIndication = gf_bifs_encoder_get_version(seng->bifsenc, esd->ESID); + + return GF_OK; +} +#endif /*GPAC_DISABLE_BIFS_ENC*/ + +#ifndef GPAC_DISABLE_LASER +static GF_Err gf_sm_setup_lsrenc(GF_SceneEngine *seng, GF_StreamContext *sc, GF_ESD *esd) +{ + GF_Err e; + char *data; + u32 data_len; + GF_LASERConfig lsr_cfg; + + if (!esd->decoderConfig || (esd->decoderConfig->streamType != GF_STREAM_SCENE)) return GF_BAD_PARAM; + + e = GF_OK; + seng->lsrenc = gf_laser_encoder_new(seng->ctx->scene_graph); + + + /*inputctx is not properly setup, do it*/ + if (!esd->decoderConfig->decoderSpecificInfo) { + memset(&lsr_cfg, 0, sizeof(GF_LASERConfig)); + } + /*regular case*/ + else if (esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_LASER_CFG_TAG) { + memcpy(&lsr_cfg, (GF_LASERConfig *)esd->decoderConfig->decoderSpecificInfo, sizeof(GF_LASERConfig) ); + } + /*happens when loading from MP4 in which case BIFSc is not decoded*/ + else { + gf_odf_get_laser_config(esd->decoderConfig->decoderSpecificInfo, &lsr_cfg); + } + + gf_laser_encoder_new_stream(seng->lsrenc, esd->ESID , &lsr_cfg); + + gf_laser_encoder_get_config(seng->lsrenc, esd->ESID, &data, &data_len); + + if (esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo); + esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); + esd->decoderConfig->decoderSpecificInfo->data = data; + esd->decoderConfig->decoderSpecificInfo->dataLength = data_len; + + sc->dec_cfg = gf_malloc(sizeof(char)*data_len); + memcpy(sc->dec_cfg, data, data_len); + sc->dec_cfg_len = data_len; + return GF_OK; +} +#endif /*GPAC_DISABLE_LASER*/ + +static GF_Err gf_sm_live_setup(GF_SceneEngine *seng) +{ + GF_Err e; + GF_StreamContext *sc; + GF_InitialObjectDescriptor *iod; + GF_ESD *esd; + u32 i, j, count; + + e = GF_OK; + + iod = (GF_InitialObjectDescriptor *) seng->ctx->root_od; + + /*build an IOD*/ + if (!iod) { + seng->ctx->root_od = (GF_ObjectDescriptor*) gf_odf_desc_new(GF_ODF_IOD_TAG); + iod = (GF_InitialObjectDescriptor *) seng->ctx->root_od; + + i=0; + while ((sc = gf_list_enum(seng->ctx->streams, &i))) { + if (sc->streamType != GF_STREAM_SCENE) continue; + + if (!sc->ESID) sc->ESID = 1; + + esd = gf_odf_desc_esd_new(2); + gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo); + esd->decoderConfig->decoderSpecificInfo = NULL; + esd->ESID = sc->ESID; + esd->decoderConfig->streamType = GF_STREAM_SCENE; + esd->decoderConfig->objectTypeIndication = sc->objectType; + gf_list_add(iod->ESDescriptors, esd); + + if (!sc->timeScale) sc->timeScale = 1000; + esd->slConfig->timestampResolution = sc->timeScale; + } + } + + count = gf_list_count(seng->ctx->streams); + i=0; + while ((sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i))) { + + j=0; + while ((esd = gf_list_enum(seng->ctx->root_od->ESDescriptors, &j))) { + if (sc->ESID==esd->ESID) { + break; + } + } + if (!esd) continue; + + if (!esd->slConfig) esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); + if (!esd->slConfig->timestampResolution) esd->slConfig->timestampResolution = 1000; + if (!sc->timeScale) sc->timeScale = esd->slConfig->timestampResolution; + + + if (sc->streamType == GF_STREAM_SCENE) { + switch (sc->objectType) { +#ifndef GPAC_DISABLE_BIFS_ENC + case GPAC_OTI_SCENE_BIFS: + case GPAC_OTI_SCENE_BIFS_V2: + e = gf_sm_setup_bifsenc(seng, sc, esd); + break; +#endif + +#ifndef GPAC_DISABLE_LASER + case GPAC_OTI_SCENE_LASER: + e = gf_sm_setup_lsrenc(seng, sc, esd); + break; +#endif + case GPAC_OTI_SCENE_DIMS: + /* Nothing to be done here */ + break; + default: + e = GF_NOT_SUPPORTED; + break; + } + if (e) return e; + } + } + return e; +} + + +GF_EXPORT +GF_Err gf_seng_enable_aggregation(GF_SceneEngine *seng, u16 ESID, u16 onESID) +{ + GF_Err e = GF_STREAM_NOT_FOUND; + GF_StreamContext *sc; + + if (ESID) { + u32 i=0; + while (sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i)) { + if (sc->ESID==ESID) break; + } + } else { + sc = (GF_StreamContext*)gf_list_get(seng->ctx->streams, 0); + } + if (!sc) return GF_STREAM_NOT_FOUND; + + sc->aggregate_on_esid = onESID; + return GF_OK; +} + + +#define ZLIB_COMPRESS_SAFE 4 + +static GF_Err compress_dims_payload(char **data, u32 data_len, u32 *max_size, u32 offset) +{ + z_stream stream; + int err; + char *dest = (char *)gf_malloc(sizeof(char)*data_len*ZLIB_COMPRESS_SAFE); + stream.next_in = (Bytef*)(*data) + offset; + stream.avail_in = (uInt)data_len - offset; + stream.next_out = ( Bytef*)dest; + stream.avail_out = (uInt)data_len*ZLIB_COMPRESS_SAFE; + stream.zalloc = (alloc_func)NULL; + stream.zfree = (free_func)NULL; + stream.opaque = (voidpf)NULL; + + err = deflateInit(&stream, 9); + if (err != Z_OK) { + gf_free(dest); + return GF_IO_ERR; + } + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + gf_free(dest); + return GF_IO_ERR; + } + if (data_len - offset<stream.total_out) { + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SceneEngine] compressed data (%d) larger than input (%d)\n", (u32) stream.total_out, (u32) data_len - offset)); + } + + if (*max_size < stream.total_out) { + *max_size = data_len*ZLIB_COMPRESS_SAFE; + *data = gf_realloc(*data, *max_size * sizeof(char)); + } + + memcpy((*data) + offset, dest, sizeof(char)*stream.total_out); + *max_size = offset + stream.total_out; + gf_free(dest); + + deflateEnd(&stream); + return GF_OK; +} + +/* Set to 1 if you want every dump with a timed file name */ +//#define DUMP_DIMS_LOG_WITH_TIME + +static GF_Err gf_seng_encode_dims_au(GF_SceneEngine *seng, u16 ESID, GF_List *commands, char **data, u32 *size) +{ + GF_Err e; + GF_SceneDumper *dumper = NULL; + char rad_name[4096]; + char file_name[4096]; + FILE *file = NULL; + u64 fsize; + char *buffer = NULL; + GF_BitStream *bs = NULL; + u32 offset; + u8 dims_header; + Bool compress_dims; +#ifdef DUMP_DIMS_LOG_WITH_TIME + u32 do_dump_with_time = 1; +#endif + u32 buffer_len; + char *cache_dir, *dump_name; + + if (!data) return GF_BAD_PARAM; + + e = GF_OK; + + if (!seng->dump_path) cache_dir = "C:\\Windows\\Temp"; + else cache_dir = seng->dump_path; + + dump_name = "gpac_scene_engine_dump"; + compress_dims = 1; + +#ifdef DUMP_DIMS_LOG_WITH_TIME +start: +#endif + + if (commands && gf_list_count(commands)) { + sprintf(rad_name, "%s%c%s%s", cache_dir, GF_PATH_SEPARATOR, dump_name, "_update"); + } else { +#ifndef DUMP_DIMS_LOG_WITH_TIME + sprintf(rad_name, "%s%c%s%s", cache_dir, GF_PATH_SEPARATOR, "rap_", dump_name); +#else + char date_str[100], time_str[100]; + time_t now; + struct tm *tm_tot; + now = time(NULL); + tm_tot = localtime(&now); + strftime(date_str, 100, "%Yy%mm%dd", tm_tot); + strftime(time_str, 100, "%Hh%Mm%Ss", tm_tot); + sprintf(rad_name, "%s%c%s-%s-%s%s", cache_dir, GF_PATH_SEPARATOR, date_str, time_str, "rap_", dump_name); +#endif + } + dumper = gf_sm_dumper_new(seng->ctx->scene_graph, rad_name, ' ', GF_SM_DUMP_SVG); + if (!dumper) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot create SVG dumper for %s.svg\n", rad_name)); + e = GF_IO_ERR; + goto exit; + } + + if (commands && gf_list_count(commands)) { + e = gf_sm_dump_command_list(dumper, commands, 0, 0); + } else { + e = gf_sm_dump_graph(dumper, 0, 0); + } + gf_sm_dumper_del(dumper); + + if(seng->dump_rap){ + GF_SceneDumper *dumper = NULL; + + sprintf(rad_name, "%s%c%s%s", cache_dir, GF_PATH_SEPARATOR, "rap_", dump_name); + + dumper = gf_sm_dumper_new(seng->ctx->scene_graph, rad_name, ' ', GF_SM_DUMP_SVG); + if (!dumper) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot create SVG dumper for %s.svg\n", rad_name)); + e = GF_IO_ERR; + goto exit; + } + e = gf_sm_dump_graph(dumper, 0, 0); + gf_sm_dumper_del(dumper); + } + + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot dump DIMS Commands\n")); + goto exit; + } +#ifdef DUMP_DIMS_LOG_WITH_TIME + if (do_dump_with_time) { + do_dump_with_time = 0; + goto start; + } +#endif + + sprintf(file_name, "%s.svg", rad_name); + file = gf_f64_open(file_name, "rb"); + if (!file) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] Cannot open SVG dump file %s\n", file_name)); + e = GF_IO_ERR; + goto exit; + } + gf_f64_seek(file, 0, SEEK_END); + fsize = gf_f64_tell(file); + + if (fsize == 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CONTAINER, ("[SceneEngine] SVG dump %s is empty\n", file_name)); + goto exit; + } + + /* First, read the dump in a buffer */ + buffer = gf_malloc((size_t)fsize * sizeof(char)); + gf_f64_seek(file, 0, SEEK_SET); + fsize = fread(buffer, sizeof(char), (size_t)fsize, file); + fclose(file); + file = NULL; + + /* Then, set DIMS unit header - TODO: notify redundant units*/ + dims_header = 0; + if (commands && gf_list_count(commands)) { + dims_header = GF_DIMS_UNIT_P; /* streamer->all_non_rap_critical ? 0 : GF_DIMS_UNIT_P;*/ + } else { + /*redundant RAP with complete scene*/ + dims_header = GF_DIMS_UNIT_M | GF_DIMS_UNIT_S | GF_DIMS_UNIT_I | GF_DIMS_UNIT_P; + } + + /* Then, if compression is asked, we do it */ + buffer_len = (u32)fsize; + assert(fsize < 1<<31); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("[SceneEngine] Sending DIMS data - sizes: raw (%d)", buffer_len)); + if (compress_dims) { + dims_header |= GF_DIMS_UNIT_C; + e = compress_dims_payload(&buffer, buffer_len, &buffer_len, 0); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("/ compressed (%d)", buffer_len)); + if (e) goto exit; + } + GF_LOG(GF_LOG_DEBUG, GF_LOG_CONTAINER, ("\n")); + + /* Then, prepare the DIMS data using a bitstream instead of direct manipulation for endianness + The new bitstream size should be: + the size of the (compressed) data + + 1 bytes for the header + + 2 bytes for the size + + 4 bytes if the size is greater than 65535 + */ + bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); + if (buffer_len > 65535) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CONTAINER, ("[SceneEngine] Warning: DIMS Unit size too big !!!\n")); + gf_bs_write_u16(bs, 0); /* internal GPAC hack to indicate that the size is larger than 65535 */ + gf_bs_write_u32(bs, buffer_len+1); + offset = 6; + } else { + gf_bs_write_u16(bs, buffer_len+1); + offset = 2; + } + gf_bs_write_u8(bs, dims_header); + gf_bs_write_data(bs, buffer, buffer_len); + + gf_free(buffer); + buffer = NULL; + + gf_bs_get_content(bs, data, size); + gf_bs_del(bs); + +exit: + if (buffer) gf_free(buffer); + if (file) fclose(file); + return e; +} + +static Bool gf_sm_check_for_modif(GF_AUContext *au) +{ + GF_Command *com; + Bool modified=0; + u32 i=0; + /*au is marked as modified - this happens when commands are concatenated into the au*/ + if (au->flags & GF_SM_AU_MODIFIED) { + au->flags &= ~GF_SM_AU_MODIFIED; + modified=1; + } + /*check each command*/ + while (com = gf_list_enum(au->commands, &i)) { + u32 j=0; + GF_CommandField *field; + if (!com->node) continue; + /*check root node (for SCENE_REPLACE) */ + if (gf_node_dirty_get(com->node)) { + modified=1; + gf_node_dirty_reset(com->node); + } + /*check all command fields of type SFNODE or MFNODE*/ + while (field = gf_list_enum(com->command_fields, &j)) { + switch (field->fieldType) { + case GF_SG_VRML_SFNODE: + if (field->new_node) { + if (gf_node_dirty_get(field->new_node)) { + modified=1; + gf_node_dirty_reset(field->new_node); + } + } + break; + case GF_SG_VRML_MFNODE: + if (field->field_ptr) { + GF_ChildNodeItem *child; + child = field->node_list; + while (child) { + if (gf_node_dirty_get(child->node)) { + modified=1; + gf_node_dirty_reset(child->node); + } + child = child->next; + } + } + break; + } + } + } + return modified; +} + +static GF_Err gf_sm_live_encode_scene_au(GF_SceneEngine *seng, gf_seng_callback callback, Bool from_start) +{ + GF_Err e; + u32 i, j, size, count, nb_streams; + char *data; + GF_AUContext *au; + + if (!callback) return GF_BAD_PARAM; + + e = GF_OK; + + nb_streams = gf_list_count(seng->ctx->streams); + for (i=0; i<nb_streams;i++) { + GF_StreamContext *sc = gf_list_get(seng->ctx->streams, i); + if (sc->streamType != GF_STREAM_SCENE) continue; + + count = gf_list_count(sc->AUs); + j = from_start ? 0 : sc->current_au_count; + for (; j<count; j++) { + au = (GF_AUContext *)gf_list_get(sc->AUs, j); + data = NULL; + size = 0; + /*in case using XMT*/ + if (au->timing_sec) au->timing = (u64) (au->timing_sec * sc->timeScale); + + if (from_start && !j && !gf_sm_check_for_modif(au)) continue; + + switch (sc->objectType) { +#ifndef GPAC_DISABLE_BIFS_ENC + case GPAC_OTI_SCENE_BIFS: + case GPAC_OTI_SCENE_BIFS_V2: + e = gf_bifs_encode_au(seng->bifsenc, sc->ESID, au->commands, &data, &size); + break; +#endif + +#ifndef GPAC_DISABLE_BIFS_ENC + case GPAC_OTI_SCENE_LASER: + e = gf_laser_encode_au(seng->lsrenc, sc->ESID, au->commands, 0, &data, &size); + break; +#endif + case GPAC_OTI_SCENE_DIMS: + e = gf_seng_encode_dims_au(seng, sc->ESID, au->commands, &data, &size); + break; + + default: + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("Cannot encode AU for Scene OTI %x\n", sc->objectType)); + break; + } + callback(seng->calling_object, sc->ESID, data, size, au->timing); + gf_free(data); + data = NULL; + if (e) break; + } + } + return e; +} + +GF_EXPORT +GF_Err gf_seng_aggregate_context(GF_SceneEngine *seng, u16 ESID) +{ + return gf_sm_aggregate(seng->ctx, ESID); +} + +GF_EXPORT +GF_Err gf_seng_dump_rap_on(GF_SceneEngine *seng, Bool dump_rap) +{ + seng->dump_rap = dump_rap; + return 0; +} + +GF_EXPORT +GF_Err gf_seng_save_context(GF_SceneEngine *seng, char *ctxFileName) +{ + u32 d_mode, do_enc; + char szF[GF_MAX_PATH], *ext; + GF_Err e; + + /*check if we dump to BT, XMT or encode to MP4*/ + ext = NULL; + if (ctxFileName) { + strcpy(szF, ctxFileName); + ext = strrchr(szF, '.'); + } + d_mode = GF_SM_DUMP_BT; + do_enc = 0; + if (ext) { + if (!stricmp(ext, ".xmt") || !stricmp(ext, ".xmta")) d_mode = GF_SM_DUMP_XMTA; + else if (!stricmp(ext, ".mp4")) do_enc = 1; + ext[0] = 0; + } + + if (do_enc) { +#ifndef GPAC_DISABLE_SCENE_ENCODER + GF_ISOFile *mp4; + strcat(szF, ".mp4"); + mp4 = gf_isom_open(szF, GF_ISOM_OPEN_WRITE, NULL); + e = gf_sm_encode_to_file(seng->ctx, mp4, NULL); + if (e) gf_isom_delete(mp4); + else gf_isom_close(mp4); +#else + return GF_NOT_SUPPORTED; +#endif + } else { + e = gf_sm_dump(seng->ctx, ctxFileName ? szF : NULL, d_mode); + } + return e; +} + +static GF_AUContext *gf_seng_create_new_au(GF_StreamContext *sc, u32 time) +{ + GF_AUContext *new_au, *last_au; + last_au = gf_list_last(sc->AUs); + if (last_au && last_au->timing == time) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SCENE, ("[SceneEngine] Forcing new AU\n")); + time++; + } + new_au = gf_sm_stream_au_new(sc, time, 0, 0); + return new_au; +} + +GF_EXPORT +GF_Err gf_seng_encode_from_string(GF_SceneEngine *seng, u16 ESID, Bool disable_aggregation, char *auString, gf_seng_callback callback) +{ + GF_StreamContext *sc; + u32 i, count; + GF_Err e; + + count = gf_list_count(seng->ctx->streams); + i = 0; + while ((sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i))) { + sc->current_au_count = gf_list_count(sc->AUs); + sc->disable_aggregation = disable_aggregation; + } + seng->loader.flags |= GF_SM_LOAD_CONTEXT_READY; + seng->loader.force_es_id = ESID; + + /* We need to create an empty AU for the parser to correctly parse a LASeR Command without SceneUnit */ + sc = gf_list_get(seng->ctx->streams, 0); + if (sc->objectType == GPAC_OTI_SCENE_DIMS) { + gf_seng_create_new_au(sc, 0); + } + + e = gf_sm_load_string(&seng->loader, auString, 0); + if (e) goto exit; + + i = 0; + while ((sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i))) { + sc->disable_aggregation = 0; + } + e = gf_sm_live_encode_scene_au(seng, callback, 0); +exit: + return e; +} + + +GF_EXPORT +GF_Err gf_seng_encode_from_commands(GF_SceneEngine *seng, u16 ESID, Bool disable_aggregation, u32 time, GF_List *commands, gf_seng_callback callback) +{ + GF_Err e; + u32 size; + char *data; + GF_StreamContext *sc; + u32 i, nb_streams; + GF_AUContext *new_au; + + if (!callback) return GF_BAD_PARAM; + if (!commands || !gf_list_count(commands)) return GF_BAD_PARAM; + + e = GF_OK; + + /* if the ESID is not provided we try to use the first scene stream */ + sc = NULL; + nb_streams = gf_list_count(seng->ctx->streams); + for (i=0; i<nb_streams;i++) { + GF_StreamContext *tmp_sc = gf_list_get(seng->ctx->streams, i); + if (tmp_sc->streamType != GF_STREAM_SCENE) continue; + sc = tmp_sc; + if (!ESID) break; + else if (sc->ESID == ESID) break; + } + if (!sc) return GF_BAD_PARAM; + /* We need to create an empty AU for the parser to correctly parse a LASeR Command without SceneUnit */ + new_au = gf_seng_create_new_au(sc, time); + + if (disable_aggregation) new_au->flags = GF_SM_AU_NOT_AGGREGATED; + + + + /* Removing the commands from the input list to avoid destruction + and setting the RAP flag */ + while (gf_list_count(commands)) { + GF_Command *com = gf_list_get(commands, 0); + gf_list_rem(commands, 0); + switch (com->tag) { + case GF_SG_SCENE_REPLACE: + case GF_SG_LSR_NEW_SCENE: + new_au->flags |= GF_SM_AU_RAP; + break; + } + gf_list_add(new_au->commands, com); + } + + data = NULL; + size = 0; + + switch(sc->objectType) { +#ifndef GPAC_DISABLE_BIFS_ENC + case GPAC_OTI_SCENE_BIFS: + case GPAC_OTI_SCENE_BIFS_V2: + e = gf_bifs_encode_au(seng->bifsenc, ESID, new_au->commands, &data, &size); + break; +#endif + +#ifndef GPAC_DISABLE_BIFS_ENC + case GPAC_OTI_SCENE_LASER: + e = gf_laser_encode_au(seng->lsrenc, ESID, new_au->commands, 0, &data, &size); + break; +#endif + case GPAC_OTI_SCENE_DIMS: + e = gf_seng_encode_dims_au(seng, ESID, new_au->commands, &data, &size); + break; + default: + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("Cannot encode commands for Scene OTI %x\n", sc->objectType)); + break; + } + callback(seng->calling_object, ESID, data, size, 0); + gf_free(data); + return e; +} + +GF_EXPORT +GF_Err gf_seng_encode_from_file(GF_SceneEngine *seng, u16 ESID, Bool disable_aggregation, char *auFile, gf_seng_callback callback) +{ + GF_Err e; + GF_StreamContext *sc; + u32 i, count; + Bool dims = 0; + + seng->loader.fileName = auFile; + seng->loader.ctx = seng->ctx; + seng->loader.force_es_id = ESID; + + sc = NULL; + count = gf_list_count(seng->ctx->streams); + i=0; + while ((sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i))) { + sc->current_au_count = gf_list_count(sc->AUs); + sc->disable_aggregation = disable_aggregation; + } + /* We need to create an empty AU for the parser to correctly parse a LASeR Command without SceneUnit */ + sc = gf_list_get(seng->ctx->streams, 0); + if (sc->objectType == GPAC_OTI_SCENE_DIMS) { + dims = 1; + gf_seng_create_new_au(sc, 0); + } + seng->loader.flags |= GF_SM_LOAD_CONTEXT_READY; + + if (dims) { + seng->loader.type |= GF_SM_LOAD_DIMS; + } else { + seng->loader.flags |= GF_SM_LOAD_MPEG4_STRICT; + } + e = gf_sm_load_run(&seng->loader); + + if (e<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] cannot load AU File %s (error %s)\n", auFile, gf_error_to_string(e))); + goto exit; + } + + i = 0; + while ((sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i))) { + sc->disable_aggregation = 0; + } + + e = gf_sm_live_encode_scene_au(seng, callback, 0); + if (e) goto exit; +exit: + return e; +} + +GF_EXPORT +GF_Err gf_seng_encode_context(GF_SceneEngine *seng, gf_seng_callback callback) +{ + if (!seng) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] Cannot encode context. No seng provided\n")); + return GF_BAD_PARAM; + } + return gf_sm_live_encode_scene_au(seng, callback, 1); +} + +GF_EXPORT +void gf_seng_terminate(GF_SceneEngine *seng) +{ +#ifndef GPAC_DISABLE_BIFS_ENC + if (seng->bifsenc) gf_bifs_encoder_del(seng->bifsenc); +#endif + +#ifndef GPAC_DISABLE_BIFS_ENC + if (seng->lsrenc) gf_laser_encoder_del(seng->lsrenc); +#endif + + gf_sm_load_done(&seng->loader); + + if (seng->owns_context) { + if (seng->ctx) gf_sm_del(seng->ctx); + if (seng->sg) gf_sg_del(seng->sg); + } + gf_free(seng); +} + +GF_EXPORT +GF_Err gf_seng_get_stream_config(GF_SceneEngine *seng, u32 idx, u16 *ESID, const char **config, u32 *config_len, u32 *streamType, u32 *objectType, u32 *timeScale) +{ + GF_StreamContext *sc = gf_list_get(seng->ctx->streams, idx); + if (!sc || !ESID || !config || !config_len) return GF_BAD_PARAM; + *ESID = sc->ESID; + *config = sc->dec_cfg; + *config_len = sc->dec_cfg_len; + if (streamType) *streamType = sc->streamType; + if (objectType) *objectType = sc->objectType; + if (timeScale) *timeScale = sc->timeScale; + return GF_OK; +} + + +#ifndef GPAC_DISABLE_VRML + +static void seng_exec_conditional(M_Conditional *c, GF_SceneGraph *scene) +{ + GF_List *clist = c->buffer.commandList; + c->buffer.commandList = NULL; + + gf_sg_command_apply_list(gf_node_get_graph((GF_Node*)c), clist, 0.0); + + if (c->buffer.commandList != NULL) { + while (gf_list_count(clist)) { + GF_Command *sub_com = (GF_Command *)gf_list_get(clist, 0); + gf_sg_command_del(sub_com); + gf_list_rem(clist, 0); + } + gf_list_del(clist); + } else { + c->buffer.commandList = clist; + } +} + +static void seng_conditional_activate(GF_Node *node, GF_Route *route) +{ + GF_SceneEngine *seng = (GF_SceneEngine *) gf_node_get_private(node); + M_Conditional *c = (M_Conditional*)node; + if (c->activate) seng_exec_conditional(c, seng->sg); +} + +static void seng_conditional_reverse_activate(GF_Node *node, GF_Route *route) +{ + GF_SceneEngine *seng = (GF_SceneEngine *) gf_node_get_private(node); + M_Conditional*c = (M_Conditional*)node; + if (!c->reverseActivate) seng_exec_conditional(c, seng->sg); +} +#endif //GPAC_DISABLE_VRML + + +static void gf_seng_on_node_modified(void *_seng, u32 type, GF_Node *node, void *ctxdata) +{ + switch (type) { +#ifndef GPAC_DISABLE_VRML + case GF_SG_CALLBACK_INIT: + if (gf_node_get_tag(node) == TAG_MPEG4_Conditional) { + M_Conditional*c = (M_Conditional*)node; + c->on_activate = seng_conditional_activate; + c->on_reverseActivate = seng_conditional_reverse_activate; + gf_node_set_private(node, _seng); + } + break; +#endif + case GF_SG_CALLBACK_MODIFIED: + gf_node_dirty_parents(node); + break; + } +} + +GF_EXPORT +GF_SceneEngine *gf_seng_init(void *calling_object, char * inputContext, u32 load_type, char *dump_path, Bool embed_resources) +{ + GF_SceneEngine *seng; + GF_Err e = GF_OK; + + if (!inputContext) return NULL; + + GF_SAFEALLOC(seng, GF_SceneEngine) + if (!seng) return NULL; + + seng->calling_object = calling_object; + + /*Step 1: create context and load input*/ + seng->sg = gf_sg_new(); + gf_sg_set_node_callback(seng->sg, gf_seng_on_node_modified); + gf_sg_set_private(seng->sg, seng); + seng->dump_path = dump_path; + seng->ctx = gf_sm_new(seng->sg); + seng->owns_context = 1; + memset(&(seng->loader), 0, sizeof(GF_SceneLoader)); + seng->loader.ctx = seng->ctx; + seng->loader.type = load_type; + /*since we're encoding in BIFS we must get MPEG-4 nodes only*/ + seng->loader.flags = GF_SM_LOAD_MPEG4_STRICT; + if (embed_resources) seng->loader.flags |= GF_SM_LOAD_EMBEDS_RES; + + seng->loader.fileName = inputContext; + e = gf_sm_load_init(&(seng->loader)); + if (!e) e = gf_sm_load_run(&(seng->loader)); + + if (e<0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] Cannot load context from %s (error %s)\n", inputContext, gf_error_to_string(e))); + goto exit; + } + e = gf_sm_live_setup(seng); + if (e!=GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] cannot init scene encoder for context (error %s)\n", gf_error_to_string(e))); + goto exit; + } + return seng; + +exit: + gf_seng_terminate(seng); + return NULL; +} + +GF_EXPORT +GF_SceneEngine *gf_seng_init_from_context(void *calling_object, GF_SceneManager *ctx, char *dump_path) +{ + GF_SceneEngine *seng; + GF_Err e = GF_OK; + + if (!ctx) return NULL; + + GF_SAFEALLOC(seng, GF_SceneEngine) + if (!seng) return NULL; + + seng->calling_object = calling_object; + seng->dump_path = dump_path; + /*Step 1: create context and load input*/ + seng->sg = ctx->scene_graph; + seng->ctx = ctx; + seng->owns_context = 0; + + e = gf_sm_live_setup(seng); + if (e!=GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] cannot init scene encoder for context (error %s)\n", gf_error_to_string(e))); + goto exit; + } + return seng; + +exit: + gf_seng_terminate(seng); + return NULL; +} + +GF_EXPORT +GF_SceneEngine *gf_seng_init_from_string(void *calling_object, char * inputContext, u32 load_type, u32 width, u32 height, Bool usePixelMetrics, char *dump_path) +{ + GF_SceneEngine *seng; + GF_Err e = GF_OK; + + if (!inputContext) return NULL; + + GF_SAFEALLOC(seng, GF_SceneEngine) + if (!seng) return NULL; + + seng->calling_object = calling_object; + seng->dump_path = dump_path; + /*Step 1: create context and load input*/ + seng->sg = gf_sg_new(); + seng->ctx = gf_sm_new(seng->sg); + seng->owns_context = 1; + memset(& seng->loader, 0, sizeof(GF_SceneLoader)); + seng->loader.ctx = seng->ctx; + seng->loader.type = load_type; + /*since we're encoding in BIFS we must get MPEG-4 nodes only*/ + seng->loader.flags = GF_SM_LOAD_MPEG4_STRICT; + + /* assign a loader type only if it was not requested (e.g. DIMS should not be overriden by SVG) */ + if (!seng->loader.type) { + if (inputContext[0] == '<') { + if (strstr(inputContext, "<svg ")) seng->loader.type = GF_SM_LOAD_SVG; + else if (strstr(inputContext, "<saf ")) seng->loader.type = GF_SM_LOAD_XSR; + else if (strstr(inputContext, "XMT-A") || strstr(inputContext, "X3D")) seng->loader.type = GF_SM_LOAD_XMTA; + } else { + seng->loader.type = GF_SM_LOAD_BT; + } + } + e = gf_sm_load_string(&seng->loader, inputContext, 0); + + if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] cannot load context from %s (error %s)\n", inputContext, gf_error_to_string(e))); + goto exit; + } + if (!seng->ctx->root_od) { + seng->ctx->is_pixel_metrics = usePixelMetrics; + seng->ctx->scene_width = width; + seng->ctx->scene_height = height; + } + + e = gf_sm_live_setup(seng); + if (e!=GF_OK) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[SceneEngine] cannot init scene encoder for context (error %s)\n", gf_error_to_string(e))); + goto exit; + } + return seng; + +exit: + gf_seng_terminate(seng); + return NULL; +} + +GF_EXPORT +u32 gf_seng_get_stream_count(GF_SceneEngine *seng) +{ + return gf_list_count(seng->ctx->streams); +} + +GF_EXPORT +GF_Err gf_seng_get_stream_carousel_info(GF_SceneEngine *seng, u16 ESID, u32 *carousel_period, u16 *aggregate_on_es_id) +{ + u32 i=0; + GF_StreamContext *sc; + + if (carousel_period) *carousel_period = (u32) -1; + if (aggregate_on_es_id) *aggregate_on_es_id = 0; + + while (sc = gf_list_enum(seng->ctx->streams, &i)) { + if (sc->ESID==ESID) { + if (carousel_period) *carousel_period = sc->carousel_period; + if (aggregate_on_es_id) *aggregate_on_es_id = sc->aggregate_on_esid; + return GF_OK; + } + } + return GF_OK; +} + +GF_EXPORT +char *gf_seng_get_base64_iod(GF_SceneEngine *seng) +{ + u32 size, size64; + char *buffer, *buf64; + u32 i=0; + GF_StreamContext*sc = NULL; + + if (!seng->ctx->root_od) return NULL; + + while ((sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i))) { + if ((sc->streamType == GF_STREAM_SCENE) && (sc->objectType != GPAC_OTI_SCENE_DIMS)) + break; + } + if (!sc) return NULL; + + size = 0; + gf_odf_desc_write((GF_Descriptor *) seng->ctx->root_od, &buffer, &size); + buf64 = gf_malloc(size*2); + size64 = gf_base64_encode( buffer, size, buf64, size*2); + buf64[size64] = 0; + gf_free(buffer); + return buf64; +} + +GF_EXPORT +GF_Descriptor *gf_seng_get_iod(GF_SceneEngine *seng) +{ + u32 i=0; + GF_Descriptor *out_iod = NULL; + GF_StreamContext*sc = NULL; + + if (!seng->ctx->root_od) return NULL; + while ((sc = (GF_StreamContext*)gf_list_enum(seng->ctx->streams, &i))) { + if ((sc->streamType == GF_STREAM_SCENE) && (sc->objectType != GPAC_OTI_SCENE_DIMS)) + break; + } + if (!sc) return NULL; + gf_odf_desc_copy((GF_Descriptor *)seng->ctx->root_od, &out_iod); + return out_iod; +} + + +#endif /*GPAC_DISABLE_SENG*/ + diff --git a/src/scene_manager/scene_manager.c b/src/scene_manager/scene_manager.c index 96dbb47..38de23b 100644 --- a/src/scene_manager/scene_manager.c +++ b/src/scene_manager/scene_manager.c @@ -28,35 +28,6 @@ #include <gpac/bifs.h> #include <gpac/xml.h> #include <gpac/internal/scenegraph_dev.h> -#include <gpac/internal/bifs_dev.h> - - -Bool gf_node_in_table_by_tag(u32 tag, u32 NDTType) -{ - if (!tag) return 0; - if (tag==TAG_ProtoNode) return 1; - else if (tag<=GF_NODE_RANGE_LAST_MPEG4) { - u32 i; - - for (i=0;i<GF_BIFS_LAST_VERSION; i++) { - if (gf_bifs_get_node_type(NDTType, tag, i+1)) return 1; - } - return 0; - } else if (tag<=GF_NODE_RANGE_LAST_X3D) { - return gf_x3d_get_node_type(NDTType, tag); - } - return 0; -} - -Bool gf_node_in_table(GF_Node *node, u32 NDTType) -{ - u32 tag = node ? node->sgprivate->tag : 0; - if (tag==TAG_ProtoNode) { - tag = gf_sg_proto_get_root_tag(((GF_ProtoInstance *)node)->proto_interface); - if (tag==TAG_UndefinedNode) return 1; - } - return gf_node_in_table_by_tag(tag, NDTType); -} GF_EXPORT @@ -94,7 +65,7 @@ GF_StreamContext *gf_sm_stream_new(GF_SceneManager *ctx, u16 ES_ID, u8 streamTyp tmp->AUs = gf_list_new(); tmp->ESID = ES_ID; tmp->streamType = streamType; - tmp->objectType = objectType; + tmp->objectType = objectType ? objectType : 1; tmp->timeScale = 1000; gf_list_add(ctx->streams, tmp); return tmp; @@ -112,26 +83,44 @@ GF_StreamContext *gf_sm_stream_find(GF_SceneManager *ctx, u16 ES_ID) return NULL; } +GF_EXPORT +GF_MuxInfo *gf_sm_get_mux_info(GF_ESD *src) +{ + u32 i; + GF_MuxInfo *mux; + i=0; + while ((mux = (GF_MuxInfo *)gf_list_enum(src->extensionDescriptors, &i))) { + if (mux->tag == GF_ODF_MUXINFO_TAG) return mux; + } + return NULL; +} + + +static void gf_sm_au_del(GF_StreamContext *sc, GF_AUContext *au) +{ + while (gf_list_count(au->commands)) { + void *comptr = gf_list_last(au->commands); + gf_list_rem_last(au->commands); + switch (sc->streamType) { + case GF_STREAM_OD: + gf_odf_com_del((GF_ODCom**) & comptr); + break; + case GF_STREAM_SCENE: + gf_sg_command_del((GF_Command *)comptr); + break; + } + } + gf_list_del(au->commands); + gf_free(au); +} + static void gf_sm_reset_stream(GF_StreamContext *sc) { while (gf_list_count(sc->AUs)) { GF_AUContext *au = (GF_AUContext *)gf_list_last(sc->AUs); gf_list_rem_last(sc->AUs); + gf_sm_au_del(sc, au); - while (gf_list_count(au->commands)) { - void *comptr = gf_list_last(au->commands); - gf_list_rem_last(au->commands); - switch (sc->streamType) { - case GF_STREAM_OD: - gf_odf_com_del((GF_ODCom**) & comptr); - break; - case GF_STREAM_SCENE: - gf_sg_command_del((GF_Command *)comptr); - break; - } - } - gf_list_del(au->commands); - free(au); } } @@ -139,7 +128,9 @@ static void gf_sm_delete_stream(GF_StreamContext *sc) { gf_sm_reset_stream(sc); gf_list_del(sc->AUs); - free(sc); + if (sc->name) gf_free(sc->name); + if (sc->dec_cfg) gf_free(sc->dec_cfg); + gf_free(sc); } GF_EXPORT @@ -161,7 +152,7 @@ void gf_sm_del(GF_SceneManager *ctx) } gf_list_del(ctx->streams); if (ctx->root_od) gf_odf_desc_del((GF_Descriptor *) ctx->root_od); - free(ctx); + gf_free(ctx); } GF_EXPORT @@ -181,192 +172,446 @@ GF_AUContext *gf_sm_stream_au_new(GF_StreamContext *stream, u64 timing, Double t { u32 i; GF_AUContext *tmp; - - /*look for existing AU*/ - i=0; - while ((tmp = (GF_AUContext *)gf_list_enum(stream->AUs, &i))) { - if (timing && (tmp->timing==timing)) return tmp; - else if (time_sec && (tmp->timing_sec == time_sec)) return tmp; - else if (!time_sec && !timing && !tmp->timing && !tmp->timing_sec) return tmp; - /*insert AU*/ - else if ((time_sec && time_sec<tmp->timing_sec) || (timing && timing<tmp->timing)) { - tmp = (GF_AUContext *)malloc(sizeof(GF_AUContext)); - tmp->commands = gf_list_new(); - tmp->is_rap = isRap; - tmp->timing = timing; - tmp->timing_sec = time_sec; - tmp->owner = stream; - gf_list_insert(stream->AUs, tmp, i); - return tmp; - } - } - tmp = (GF_AUContext *)malloc(sizeof(GF_AUContext)); + u64 tmp_timing; + + tmp_timing = timing ? timing : (u64) (time_sec*1000); + if (stream->last_au_time >= tmp_timing) { + /*look for existing AU*/ + i=0; + while ((tmp = (GF_AUContext *)gf_list_enum(stream->AUs, &i))) { + if (timing && (tmp->timing==timing)) return tmp; + else if (time_sec && (tmp->timing_sec == time_sec)) return tmp; + else if (!time_sec && !timing && !tmp->timing && !tmp->timing_sec) return tmp; + /*insert AU*/ + else if ((time_sec && time_sec<tmp->timing_sec) || (timing && timing<tmp->timing)) { + GF_SAFEALLOC(tmp, GF_AUContext); + tmp->commands = gf_list_new(); + if (isRap) tmp->flags = GF_SM_AU_RAP; + tmp->timing = timing; + tmp->timing_sec = time_sec; + tmp->owner = stream; + gf_list_insert(stream->AUs, tmp, i-1); + return tmp; + } + } + } + GF_SAFEALLOC(tmp, GF_AUContext); tmp->commands = gf_list_new(); - tmp->is_rap = isRap; + if (isRap) tmp->flags = GF_SM_AU_RAP; tmp->timing = timing; tmp->timing_sec = time_sec; tmp->owner = stream; + if (stream->disable_aggregation) tmp->flags |= GF_SM_AU_NOT_AGGREGATED; gf_list_add(stream->AUs, tmp); + stream->last_au_time = tmp_timing; return tmp; } +static Bool node_in_commands_subtree(GF_Node *node, GF_List *commands) +{ + u32 i, j, count, nb_fields; + + count = gf_list_count(commands); + for (i=0; i<count; i++) { + GF_Command *com = gf_list_get(commands, i); + if (com->tag>=GF_SG_LAST_BIFS_COMMAND) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[Scene Manager] Command check for LASeR/DIMS not supported\n")); + return 0; + } + if (com->tag==GF_SG_SCENE_REPLACE) { + if (gf_node_parent_of(com->node, node)) return 1; + continue; + } + nb_fields = gf_list_count(com->command_fields); + for (j=0; j<nb_fields; j++) { + GF_CommandField *field = gf_list_get(com->command_fields, j); + switch (field->fieldType) { + case GF_SG_VRML_SFNODE: + if (field->new_node) { + if (gf_node_parent_of(field->new_node, node)) return 1; + } + break; + case GF_SG_VRML_MFNODE: + if (field->field_ptr) { + GF_ChildNodeItem *child; + child = field->node_list; + while (child) { + if (gf_node_parent_of(child->node, node)) return 1; + child = child->next; + } + } + break; + } + } + } + return 0; +} + +static u32 store_or_aggregate(GF_StreamContext *sc, GF_Command *com, GF_List *commands, Bool *has_modif) +{ + u32 i, count, j, nb_fields; + GF_CommandField *field, *check_field; + + /*if our command deals with a node inserted in the commands list, apply command list*/ + if (node_in_commands_subtree(com->node, commands)) return 0; + + /*otherwise, check if we can substitute a previous command with this one*/ + count = gf_list_count(commands); + for (i=0; i<count; i++) { + GF_Command *check = gf_list_get(commands, i); + + if (sc->streamType == GF_STREAM_SCENE) { + Bool check_index=0; + Bool original_is_index = 0; + Bool apply; + switch (com->tag) { + case GF_SG_INDEXED_REPLACE: + check_index=1; + case GF_SG_MULTIPLE_INDEXED_REPLACE: + case GF_SG_FIELD_REPLACE: + case GF_SG_MULTIPLE_REPLACE: + if (check->node != com->node) break; + /*we may aggregate an indexed insertion and a replace one*/ + if (check_index) { + if (check->tag == GF_SG_INDEXED_REPLACE) {} + else if (check->tag == GF_SG_INDEXED_INSERT) { original_is_index = 1; } + else { + break; + } + } else { + if (check->tag != com->tag) break; + } + nb_fields = gf_list_count(com->command_fields); + if (gf_list_count(check->command_fields) != nb_fields) break; + apply=1; + for (j=0; j<nb_fields; j++) { + field = gf_list_get(com->command_fields, j); + check_field = gf_list_get(check->command_fields, j); + if ((field->pos != check_field->pos) || (field->fieldIndex != check_field->fieldIndex)) { + apply=0; + break; + } + } + /*same target node+fields, destroy first command and store new one*/ + if (apply) { + /*if indexed, change command tag*/ + if (original_is_index) com->tag = GF_SG_INDEXED_INSERT; + + gf_sg_command_del((GF_Command *)check); + gf_list_rem(commands, i); + if (has_modif) *has_modif = 1; + return 1; + } + break; + + case GF_SG_NODE_REPLACE: + if (check->tag != GF_SG_NODE_REPLACE) { + break; + } + /*TODO - THIS IS NOT SUPPORTED IN GPAC SINCE WE NEVER ALLOW FOR DUPLICATE NODE IDs IN THE SCENE !!!*/ + if (gf_node_get_id(check->node) != gf_node_get_id(com->node) ) { + break; + } + /*same node ID, destroy first command and store new one*/ + gf_sg_command_del((GF_Command *)check); + gf_list_rem(commands, i); + if (has_modif) *has_modif = 1; + return 1; + + case GF_SG_INDEXED_DELETE: + /*look for an indexed insert before the indexed delete with same target pos and node. If found, discard both commands!*/ + if (check->tag != GF_SG_INDEXED_INSERT) break; + if (com->node != check->node) break; + field = gf_list_get(com->command_fields, 0); + check_field = gf_list_get(check->command_fields, 0); + if (!field || !check_field) break; + if (field->pos != check_field->pos) break; + if (field->fieldIndex != check_field->fieldIndex) break; + + gf_sg_command_del((GF_Command *)check); + gf_list_rem(commands, i); + if (has_modif) *has_modif = 1; + return 2; + + default: + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[Scene Manager] Stream Aggregation not implemented for command - aggregating on main scene\n")); + break; + } + } + } + /*the command modifies another stream than associated current carousel stream, we have to store it.*/ + if (has_modif) *has_modif=1; + return 1; +} + +static GF_StreamContext *gf_sm_get_stream(GF_SceneManager *ctx, u16 ESID) +{ + u32 i, count; + count = gf_list_count(ctx->streams); + for (i=0;i<count;i++) { + GF_StreamContext *sc = gf_list_get(ctx->streams, i); + if (sc->ESID==ESID) return sc; + } + return NULL; +} + GF_EXPORT -GF_Err gf_sm_make_random_access(GF_SceneManager *ctx) +GF_Err gf_sm_aggregate(GF_SceneManager *ctx, u16 ESID) { GF_Err e; - u32 i, j, stream_count, au_count, com_count; + u32 i, stream_count; +#ifndef GPAC_DISABLE_VRML + u32 j; GF_AUContext *au; GF_Command *com; +#endif e = GF_OK; + +#if DEBUG_RAP + com_count = 0; + stream_count = gf_list_count(ctx->streams); + for (i=0; i<stream_count; i++) { + GF_StreamContext *sc = (GF_StreamContext *)gf_list_get(ctx->streams, i); + if (sc->streamType == GF_STREAM_SCENE) { + au_count = gf_list_count(sc->AUs); + for (j=0; j<au_count; j++) { + au = (GF_AUContext *)gf_list_get(sc->AUs, j); + com_count += gf_list_count(au->commands); + } + } + } + GF_LOG(GF_LOG_INFO, GF_LOG_SCENE, ("[SceneManager] Making RAP with %d commands\n", com_count)); +#endif + stream_count = gf_list_count(ctx->streams); for (i=0; i<stream_count; i++) { + GF_AUContext *carousel_au; + GF_List *carousel_commands; + Bool self_carousel; + GF_StreamContext *aggregate_on_stream; GF_StreamContext *sc = (GF_StreamContext *)gf_list_get(ctx->streams, i); - /*FIXME - do this as well for ODs*/ + if (ESID && (sc->ESID!=ESID)) continue; + + /*locate the AU in which our commands will be aggregated*/ + carousel_au = NULL; + carousel_commands = NULL; + self_carousel = 0; + aggregate_on_stream = sc->aggregate_on_esid ? gf_sm_get_stream(ctx, sc->aggregate_on_esid) : NULL; + if (aggregate_on_stream==sc) { + carousel_commands = gf_list_new(); + self_carousel = 1; + } else if (aggregate_on_stream) { + if (!gf_list_count(aggregate_on_stream->AUs)) { + carousel_au = gf_sm_stream_au_new(aggregate_on_stream, 0, 0, 1); + } else { + /* assert we already performed aggregation */ + assert(gf_list_count(aggregate_on_stream->AUs)==1); + carousel_au = gf_list_get(aggregate_on_stream->AUs, 0); + } + carousel_commands = carousel_au->commands; + } + /*TODO - do this as well for ODs*/ +#ifndef GPAC_DISABLE_VRML if (sc->streamType == GF_STREAM_SCENE) { + Bool has_modif = 0; + Bool first_au=1; + /*we check for each stream if it is a base stream (SceneReplace ...) - several streams may carry RAPs if inline nodes are used*/ + Bool base_stream_found = 0; + u32 first_au_com_count = 0; + + /*in DIMS we use an empty initial AU with no commands to signal the RAP*/ + if (sc->objectType == GPAC_OTI_SCENE_DIMS) base_stream_found = 1; + /*apply all commands - this will also apply the SceneReplace*/ - j=0; - while ((au = (GF_AUContext *)gf_list_enum(sc->AUs, &j))) { - e = gf_sg_command_apply_list(ctx->scene_graph, au->commands, 0); - if (e) return e; - } + while (gf_list_count(sc->AUs)) { + Bool first_com=1; + u32 count; + au = (GF_AUContext *) gf_list_get(sc->AUs, 0); + gf_list_rem(sc->AUs, 0); + + /*AU not aggregated*/ + if (au->flags & GF_SM_AU_NOT_AGGREGATED) { + gf_sm_au_del(sc, au); + first_au=0; + continue; + } - /* Delete all the commands in the stream */ - while ( (au_count = gf_list_count(sc->AUs)) ) { - au = (GF_AUContext *)gf_list_get(sc->AUs, au_count-1); - gf_list_rem(sc->AUs, au_count-1); - while ( (com_count = gf_list_count(au->commands)) ) { - com = (GF_Command*)gf_list_get(au->commands, com_count - 1); - gf_list_rem(au->commands, com_count - 1); - gf_sg_command_del(com); + count = gf_list_count(au->commands); + if (first_au && (au->flags & GF_SM_AU_CAROUSEL) ) first_au_com_count = count; + + for (j=0; j<count; j++) { + u32 store=0; + com = gf_list_get(au->commands, j); + if (!base_stream_found) { + switch (com->tag) { + case GF_SG_SCENE_REPLACE: + case GF_SG_LSR_NEW_SCENE: + case GF_SG_LSR_REFRESH_SCENE: + base_stream_found = 1; + break; + } + } + + /*aggregate the command*/ + + /*if stream doesn't carry a carousel or carries the base carousel (scene replace), always apply the command*/ + if (base_stream_found || !sc->aggregate_on_esid) { + store = 0; + } + /*otherwise, check wether the command should be kept in this stream as is, or can be aggregated on this stream*/ + else { + switch (com->tag) { + /*the following commands do not impact a sub-tree (eg do not deal with nodes), we cannot + aggregate them... */ + case GF_SG_ROUTE_REPLACE: + case GF_SG_ROUTE_DELETE: + case GF_SG_ROUTE_INSERT: + case GF_SG_PROTO_INSERT: + case GF_SG_PROTO_DELETE: + case GF_SG_PROTO_DELETE_ALL: + case GF_SG_GLOBAL_QUANTIZER: + case GF_SG_LSR_RESTORE: + case GF_SG_LSR_SAVE: + case GF_SG_LSR_SEND_EVENT: + case GF_SG_LSR_CLEAN: + /*todo check in which category to put these commands*/ +// case GF_SG_LSR_ACTIVATE: +// case GF_SG_LSR_DEACTIVATE: + store = 1; + break; + /*other commands: + !!! we need to know if the target node of the command has been inserted in this stream !!! + + This is a tedious task, for now we will consider the following cases: + - locate a similar command in the stored list: remove the similar one and aggregate on stream + - by default all AUs are stored if the stream is in aggregate mode - we should fix that by checking insertion points: + if a command apllies on a node that has been inserted in this stream, we can aggregate, otherwise store + */ + default: + /*check if we can directly store the command*/ + assert(carousel_commands); + store = store_or_aggregate(sc, com, carousel_commands, &has_modif); + break; + } + } + + switch (store) { + /*command has been merged with a previous command in carousel and needs to be destroyed*/ + case 2: + gf_list_rem(au->commands, j); + j--; + count--; + gf_sg_command_del((GF_Command *)com); + break; + /*command shall be moved to carousel without being applied*/ + case 1: + gf_list_insert(carousel_commands, com, 0); + gf_list_rem(au->commands, j); + j--; + count--; + break; + /*command can be applied*/ + default: + e = gf_sg_command_apply(ctx->scene_graph, com, 0); + break; + } + first_com=0; } - gf_list_del(au->commands); - free(au); + gf_sm_au_del(sc, au); + first_au=0; } + /*and recreate scene replace*/ - au = gf_sm_stream_au_new(sc, 0, 0, 1); - com = gf_sg_command_new(ctx->scene_graph, GF_SG_SCENE_REPLACE); - com->node = ctx->scene_graph->RootNode; - ctx->scene_graph->RootNode = NULL; - gf_list_del(com->new_proto_list); - com->new_proto_list = ctx->scene_graph->protos; - ctx->scene_graph->protos = NULL; - /*indicate the command is the aggregated scene graph, so that PROTOs and ROUTEs - are taken from the scenegraph when encoding*/ - com->aggregated = 1; - gf_list_add(au->commands, com); + if (base_stream_found) { + au = gf_sm_stream_au_new(sc, 0, 0, 1); + + switch (sc->objectType) { + case GPAC_OTI_SCENE_BIFS: + case GPAC_OTI_SCENE_BIFS_V2: + com = gf_sg_command_new(ctx->scene_graph, GF_SG_SCENE_REPLACE); + break; + case GPAC_OTI_SCENE_LASER: + com = gf_sg_command_new(ctx->scene_graph, GF_SG_LSR_NEW_SCENE); + break; + case GPAC_OTI_SCENE_DIMS: + /* We do not create a new command, empty AU is enough in DIMS*/ + default: + com = NULL; + break; + } + + if (com) { + com->node = ctx->scene_graph->RootNode; + ctx->scene_graph->RootNode = NULL; + gf_list_del(com->new_proto_list); + com->new_proto_list = ctx->scene_graph->protos; + ctx->scene_graph->protos = NULL; + /*indicate the command is the aggregated scene graph, so that PROTOs and ROUTEs + are taken from the scenegraph when encoding*/ + com->aggregated = 1; + gf_list_add(au->commands, com); + } + } + /*update carousel flags of the AU*/ + else if (carousel_commands) { + /*if current stream caries its own carousel*/ + if (!carousel_au) { + carousel_au = gf_sm_stream_au_new(sc, 0, 0, 1); + gf_list_del(carousel_au->commands); + carousel_au->commands = carousel_commands; + } + carousel_au->flags |= GF_SM_AU_RAP | GF_SM_AU_CAROUSEL; + if (has_modif) carousel_au->flags |= GF_SM_AU_MODIFIED; + } } +#endif } return e; } - +#ifndef GPAC_DISABLE_LOADER_BT GF_Err gf_sm_load_init_bt(GF_SceneLoader *load); -void gf_sm_load_done_bt(GF_SceneLoader *load); -GF_Err gf_sm_load_run_bt(GF_SceneLoader *load); -GF_Err gf_sm_load_init_bt_string(GF_SceneLoader *load, char *str); -GF_Err gf_sm_load_done_bt_string(GF_SceneLoader *load); +#endif +#ifndef GPAC_DISABLE_LOADER_XMT GF_Err gf_sm_load_init_xmt(GF_SceneLoader *load); -void gf_sm_load_done_xmt(GF_SceneLoader *load); -GF_Err gf_sm_load_run_xmt(GF_SceneLoader *load); -GF_Err gf_sm_load_init_xmt_string(GF_SceneLoader *load, char *str); +#endif +#ifndef GPAC_DISABLE_LOADER_ISOM GF_Err gf_sm_load_init_isom(GF_SceneLoader *load); -void gf_sm_load_done_isom(GF_SceneLoader *load); -GF_Err gf_sm_load_run_isom(GF_SceneLoader *load); +#endif #ifndef GPAC_DISABLE_SVG GF_Err gf_sm_load_init_svg(GF_SceneLoader *load); -GF_Err gf_sm_load_done_svg(GF_SceneLoader *load); -GF_Err gf_sm_load_run_svg(GF_SceneLoader *load); -GF_Err gf_sm_load_init_svg_string(GF_SceneLoader *load, char *str); GF_Err gf_sm_load_init_xbl(GF_SceneLoader *load); -GF_Err gf_sm_load_done_xbl(GF_SceneLoader *load); GF_Err gf_sm_load_run_xbl(GF_SceneLoader *load); +void gf_sm_load_done_xbl(GF_SceneLoader *load); #endif -#ifndef GPAC_READ_ONLY - +#ifndef GPAC_DISABLE_SWF_IMPORT GF_Err gf_sm_load_init_swf(GF_SceneLoader *load); -void gf_sm_load_done_swf(GF_SceneLoader *load); -GF_Err gf_sm_load_run_swf(GF_SceneLoader *load); - -GF_Err gf_sm_load_init_qt(GF_SceneLoader *load); -void gf_sm_load_done_qt(GF_SceneLoader *load); -GF_Err gf_sm_load_run_qt(GF_SceneLoader *load); #endif -static GF_Err gf_sm_load_init_from_string(GF_SceneLoader *load, char *str) -{ - - /*we need at least a scene graph*/ - if (!load || (!load->ctx && !load->scene_graph)) return GF_BAD_PARAM; - - if (!load->type) return GF_NOT_SUPPORTED; - - if (!load->scene_graph) load->scene_graph = load->ctx->scene_graph; +#ifndef GPAC_DISABLE_QTVR - switch (load->type) { - case GF_SM_LOAD_BT: - case GF_SM_LOAD_VRML: - case GF_SM_LOAD_X3DV: - return gf_sm_load_init_bt_string(load, str); - case GF_SM_LOAD_XMTA: - case GF_SM_LOAD_X3D: - return gf_sm_load_init_xmt_string(load, str); -#ifndef GPAC_DISABLE_SVG - case GF_SM_LOAD_SVG_DA: - case GF_SM_LOAD_XSR: - case GF_SM_LOAD_DIMS: - return gf_sm_load_init_svg_string(load, str); -#endif - case GF_SM_LOAD_SWF: - return GF_NOT_SUPPORTED; -#ifndef GPAC_READ_ONLY - case GF_SM_LOAD_MP4: - return GF_NOT_SUPPORTED; +GF_Err gf_sm_load_init_qt(GF_SceneLoader *load); #endif - } - return GF_NOT_SUPPORTED; -} -static void gf_sm_load_done_string(GF_SceneLoader *load, Bool do_clean) -{ - switch (load->type) { - case GF_SM_LOAD_BT: - case GF_SM_LOAD_VRML: - case GF_SM_LOAD_X3DV: - gf_sm_load_done_bt_string(load); - break; - case GF_SM_LOAD_XMTA: - case GF_SM_LOAD_X3D: - /*we do not reset it here to enable SAX parsing*/ - if (do_clean) gf_sm_load_done_xmt(load); - break; -#ifndef GPAC_DISABLE_SVG - /*we do not reset it here to enable SAX parsing*/ - case GF_SM_LOAD_SVG_DA: - case GF_SM_LOAD_XSR: - case GF_SM_LOAD_DIMS: - break; -#endif - default: - break; - } -} + GF_EXPORT GF_Err gf_sm_load_string(GF_SceneLoader *load, char *str, Bool do_clean) { - GF_Err e = gf_sm_load_init_from_string(load, str); - if (e) return e; - e = gf_sm_load_run(load); - gf_sm_load_done_string(load, do_clean); - return (e<0) ? e : GF_OK; + GF_Err e; + if (!load->type) e = GF_BAD_PARAM; + else if (load->parse_string) e = load->parse_string(load, str); + else e = GF_NOT_SUPPORTED; + + return e; } @@ -377,12 +622,19 @@ GF_Err gf_sm_load_init(GF_SceneLoader *load) GF_Err e = GF_NOT_SUPPORTED; char *ext, szExt[50]; /*we need at least a scene graph*/ - if (!load || (!load->ctx && !load->scene_graph) || (!load->fileName && !load->isom)) return GF_BAD_PARAM; + if (!load || (!load->ctx && !load->scene_graph) +#ifndef GPAC_DISABLE_ISOM + || (!load->fileName && !load->isom && !(load->flags & GF_SM_LOAD_FOR_PLAYBACK) ) +#endif + ) return GF_BAD_PARAM; if (!load->type) { +#ifndef GPAC_DISABLE_ISOM if (load->isom) { load->type = GF_SM_LOAD_MP4; - } else { + } else +#endif + { ext = strrchr(load->fileName, '.'); if (!ext) return GF_NOT_SUPPORTED; if (!stricmp(ext, ".gz")) { @@ -397,11 +649,13 @@ GF_Err gf_sm_load_init(GF_SceneLoader *load) if (strstr(szExt, "bt")) load->type = GF_SM_LOAD_BT; else if (strstr(szExt, "wrl")) load->type = GF_SM_LOAD_VRML; else if (strstr(szExt, "x3dv")) load->type = GF_SM_LOAD_X3DV; +#ifndef GPAC_DISABLE_LOADER_XMT else if (strstr(szExt, "xmt") || strstr(szExt, "xmta")) load->type = GF_SM_LOAD_XMTA; else if (strstr(szExt, "x3d")) load->type = GF_SM_LOAD_X3D; +#endif else if (strstr(szExt, "swf")) load->type = GF_SM_LOAD_SWF; else if (strstr(szExt, "mov")) load->type = GF_SM_LOAD_QT; - else if (strstr(szExt, "svg")) load->type = GF_SM_LOAD_SVG_DA; + else if (strstr(szExt, "svg")) load->type = GF_SM_LOAD_SVG; else if (strstr(szExt, "xsr")) load->type = GF_SM_LOAD_XSR; else if (strstr(szExt, "xbl")) load->type = GF_SM_LOAD_XBL; else if (strstr(szExt, "xml")) { @@ -412,7 +666,7 @@ GF_Err gf_sm_load_init(GF_SceneLoader *load) else if (!strcmp(rtype, "X3D")) load->type = GF_SM_LOAD_X3D; else if (!strcmp(rtype, "bindings")) load->type = GF_SM_LOAD_XBL; - free(rtype); + gf_free(rtype); } } } @@ -422,30 +676,48 @@ GF_Err gf_sm_load_init(GF_SceneLoader *load) if (!load->scene_graph) load->scene_graph = load->ctx->scene_graph; switch (load->type) { +#ifndef GPAC_DISABLE_LOADER_BT case GF_SM_LOAD_BT: case GF_SM_LOAD_VRML: case GF_SM_LOAD_X3DV: return gf_sm_load_init_bt(load); +#endif + +#ifndef GPAC_DISABLE_LOADER_XMT case GF_SM_LOAD_XMTA: case GF_SM_LOAD_X3D: return gf_sm_load_init_xmt(load); +#endif + #ifndef GPAC_DISABLE_SVG - case GF_SM_LOAD_SVG_DA: + case GF_SM_LOAD_SVG: case GF_SM_LOAD_XSR: case GF_SM_LOAD_DIMS: return gf_sm_load_init_svg(load); case GF_SM_LOAD_XBL: - return gf_sm_load_init_xbl(load); + e = gf_sm_load_init_xbl(load); + + load->process = gf_sm_load_run_xbl;; + load->done = gf_sm_load_done_xbl; + return e; #endif -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_SWF_IMPORT case GF_SM_LOAD_SWF: return gf_sm_load_init_swf(load); - case GF_SM_LOAD_QT: - return gf_sm_load_init_qt(load); +#endif + +#ifndef GPAC_DISABLE_LOADER_ISOM case GF_SM_LOAD_MP4: return gf_sm_load_init_isom(load); #endif + +#ifndef GPAC_DISABLE_QTVR + case GF_SM_LOAD_QT: + return gf_sm_load_init_qt(load); +#endif + } return GF_NOT_SUPPORTED; } @@ -453,73 +725,19 @@ GF_Err gf_sm_load_init(GF_SceneLoader *load) GF_EXPORT void gf_sm_load_done(GF_SceneLoader *load) { - switch (load->type) { - case GF_SM_LOAD_BT: - case GF_SM_LOAD_VRML: - case GF_SM_LOAD_X3DV: - gf_sm_load_done_bt(load); - break; - case GF_SM_LOAD_XMTA: - case GF_SM_LOAD_X3D: - gf_sm_load_done_xmt(load); - break; -#ifndef GPAC_DISABLE_SVG - case GF_SM_LOAD_SVG_DA: - case GF_SM_LOAD_XSR: - case GF_SM_LOAD_DIMS: - gf_sm_load_done_svg(load); - break; - - case GF_SM_LOAD_XBL: - gf_sm_load_done_xbl(load); - break; -#endif - -#ifndef GPAC_READ_ONLY - case GF_SM_LOAD_SWF: - gf_sm_load_done_swf(load); - break; - case GF_SM_LOAD_QT: - gf_sm_load_done_qt(load); - break; - case GF_SM_LOAD_MP4: - gf_sm_load_done_isom(load); - break; -#endif - } + if (load->done) load->done(load); } GF_EXPORT GF_Err gf_sm_load_run(GF_SceneLoader *load) { - switch (load->type) { - case GF_SM_LOAD_BT: - case GF_SM_LOAD_VRML: - case GF_SM_LOAD_X3DV: - return gf_sm_load_run_bt(load); - case GF_SM_LOAD_XMTA: - case GF_SM_LOAD_X3D: - return gf_sm_load_run_xmt(load); -#ifndef GPAC_DISABLE_SVG - case GF_SM_LOAD_SVG_DA: - case GF_SM_LOAD_XSR: - case GF_SM_LOAD_DIMS: - return gf_sm_load_run_svg(load); -#endif -#ifndef GPAC_DISABLE_SVG - case GF_SM_LOAD_XBL: - return gf_sm_load_run_xbl(load); -#endif -#ifndef GPAC_READ_ONLY - case GF_SM_LOAD_SWF: - return gf_sm_load_run_swf(load); - case GF_SM_LOAD_QT: - return gf_sm_load_run_qt(load); - case GF_SM_LOAD_MP4: - return gf_sm_load_run_isom(load); -#endif - default: - return GF_BAD_PARAM; - } + if (load->process) return load->process(load); + return GF_OK; } +GF_EXPORT +GF_Err gf_sm_load_suspend(GF_SceneLoader *load, Bool suspend) +{ + if (load->suspend) return load->suspend(load, suspend); + return GF_OK; +} diff --git a/src/scene_manager/scene_stats.c b/src/scene_manager/scene_stats.c index 64b115a..cb73599 100644 --- a/src/scene_manager/scene_stats.c +++ b/src/scene_manager/scene_stats.c @@ -26,7 +26,7 @@ #include <gpac/constants.h> #include <gpac/internal/scenegraph_dev.h> -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_SCENE_STATS struct _statman { @@ -59,12 +59,12 @@ static void ResetStatisitics(GF_SceneStatistics *stat) while (gf_list_count(stat->node_stats)) { GF_NodeStats *ptr = (GF_NodeStats *)gf_list_get(stat->node_stats, 0); gf_list_rem(stat->node_stats, 0); - free(ptr); + gf_free(ptr); } while (gf_list_count(stat->proto_stats)) { GF_NodeStats *ptr = (GF_NodeStats *)gf_list_get(stat->proto_stats, 0); gf_list_rem(stat->proto_stats, 0); - free(ptr); + gf_free(ptr); } stat->max_2d.x = FIX_MIN; stat->max_2d.y = FIX_MIN; @@ -85,7 +85,7 @@ static void DeleteStatisitics(GF_SceneStatistics *stat) ResetStatisitics(stat); gf_list_del(stat->node_stats); gf_list_del(stat->proto_stats); - free(stat); + gf_free(stat); } static void StatNode(GF_SceneStatistics *stat, GF_Node *n, Bool isUsed, Bool isDelete, GF_Node *prev) @@ -95,6 +95,7 @@ static void StatNode(GF_SceneStatistics *stat, GF_Node *n, Bool isUsed, Bool isD if (!stat) return; if (n->sgprivate->tag == TAG_ProtoNode) { +#ifndef GPAC_DISABLE_VRML GF_ProtoInstance *pr = (GF_ProtoInstance *)n; i=0; while ((ptr = (GF_NodeStats *)gf_list_enum(stat->proto_stats, &i))) { @@ -107,6 +108,7 @@ static void StatNode(GF_SceneStatistics *stat, GF_Node *n, Bool isUsed, Bool isD ptr->name = gf_sg_proto_get_class_name(pr->proto_interface); gf_list_add(stat->proto_stats, ptr); } +#endif } else { i=0; while ((ptr = (GF_NodeStats *)gf_list_enum(stat->node_stats, &i))) { @@ -156,6 +158,8 @@ static void StatFixed(GF_SceneStatistics *stat, Fixed v, Bool scale) if (stat->min_fixed > v) stat->min_fixed = v; } + + static void StatSVGPoint(GF_SceneStatistics *stat, SFVec2f *val) { if (!stat) return; @@ -365,10 +369,8 @@ Bool StatIsUSE(GF_StatManager *st, GF_Node *n) static GF_Err StatNodeGraph(GF_StatManager *st, GF_Node *n) { - GF_Node *child, *clone; - GF_ChildNodeItem *list; - u32 i, count; - GF_FieldInfo field, clone_field; + GF_Node *clone; + GF_FieldInfo field; if (!n) return GF_OK; StatNode(st->stats, n, StatIsUSE(st, n), 0, NULL); @@ -376,8 +378,13 @@ static GF_Err StatNodeGraph(GF_StatManager *st, GF_Node *n) if (n->sgprivate->tag != TAG_ProtoNode) { clone = gf_node_new(n->sgprivate->scenegraph, n->sgprivate->tag); } else { +#ifndef GPAC_DISABLE_VRML clone = gf_sg_proto_create_node(n->sgprivate->scenegraph, ((GF_ProtoInstance *)n)->proto_interface, NULL); +#else + clone = NULL; +#endif } + if (!clone) return GF_OK; gf_node_register(clone, NULL); #ifndef GPAC_DISABLE_SVG @@ -401,7 +408,14 @@ static GF_Err StatNodeGraph(GF_StatManager *st, GF_Node *n) #endif if (n->sgprivate->tag == TAG_DOMText) { } else if (n->sgprivate->tag == TAG_DOMFullNode) { - } else { + } +#ifndef GPAC_DISABLE_VRML + else if (n->sgprivate->tag<= GF_NODE_RANGE_LAST_X3D) { + GF_Node *child; + GF_ChildNodeItem *list; + u32 i, count; + GF_FieldInfo clone_field; + count = gf_node_get_field_count(n); for (i=0; i<count; i++) { @@ -430,6 +444,8 @@ static GF_Err StatNodeGraph(GF_StatManager *st, GF_Node *n) } } } +#endif + gf_node_unregister(clone, NULL); return GF_OK; } @@ -437,6 +453,9 @@ static GF_Err StatNodeGraph(GF_StatManager *st, GF_Node *n) GF_EXPORT GF_Err gf_sm_stats_for_command(GF_StatManager *stat, GF_Command *com) { +#ifdef GPAC_DISABLE_VRML + return GF_NOT_SUPPORTED; +#else GF_FieldInfo field; GF_Err e; GF_ChildNodeItem *list; @@ -528,6 +547,7 @@ GF_Err gf_sm_stats_for_command(GF_StatManager *stat, GF_Command *com) return GF_BAD_PARAM; } return GF_OK; +#endif } static GF_Err gf_sm_stat_au(GF_List *commandList, GF_StatManager *st) @@ -580,7 +600,7 @@ GF_Err gf_sm_stats_for_graph(GF_StatManager *stat, GF_SceneGraph *sg) GF_EXPORT GF_StatManager *gf_sm_stats_new() { - GF_StatManager *sm = (GF_StatManager *)malloc(sizeof(GF_StatManager)); + GF_StatManager *sm = (GF_StatManager *)gf_malloc(sizeof(GF_StatManager)); sm->def_nodes = gf_list_new(); sm->stats = NewSceneStats(); return sm; @@ -592,7 +612,7 @@ void gf_sm_stats_del(GF_StatManager *stat) { gf_list_del(stat->def_nodes); DeleteStatisitics(stat->stats); - free(stat); + gf_free(stat); } GF_EXPORT @@ -608,5 +628,5 @@ void gf_sm_stats_reset(GF_StatManager *stat) ResetStatisitics(stat->stats); } -#endif +#endif /*GPAC_DISABLE_SCENE_STATS*/ diff --git a/src/scene_manager/swf_bifs.c b/src/scene_manager/swf_bifs.c index a0d870c..1e5a063 100644 --- a/src/scene_manager/swf_bifs.c +++ b/src/scene_manager/swf_bifs.c @@ -27,7 +27,10 @@ #include <gpac/internal/swf_dev.h> #include <gpac/internal/scenegraph_dev.h> -#ifndef GPAC_READ_ONLY + +#ifndef GPAC_DISABLE_VRML + +#ifndef GPAC_DISABLE_SWF_IMPORT #define SWF_TEXT_SCALE (1/1024.0f) @@ -652,7 +655,7 @@ static void s2b_insert_shape(M_OrderedGroup *og, M_Shape *n, Bool is_proto) static void s2b_insert_rec_in_coord(M_Coordinate2D *c, SWFShapeRec *srec) { u32 i, j; - srec->path->idx = malloc(sizeof(u32)*srec->path->nbPts); + srec->path->idx = gf_malloc(sizeof(u32)*srec->path->nbPts); for (i=0; i<srec->path->nbPts; i++) { for (j=0; j<c->point.count; j++) { @@ -662,7 +665,7 @@ static void s2b_insert_rec_in_coord(M_Coordinate2D *c, SWFShapeRec *srec) } if (j==c->point.count) { c->point.count++; - c->point.vals = realloc(c->point.vals, sizeof(SFVec2f)*c->point.count); + c->point.vals = gf_realloc(c->point.vals, sizeof(SFVec2f)*c->point.count); c->point.vals[j] = srec->path->pts[i]; } srec->path->idx[i] = j; @@ -861,35 +864,35 @@ static GF_Err swf_bifs_define_text(SWFReader *read, SWFText *text) if (ft->fontName) { gf_sg_vrml_mf_reset(&f->family, GF_SG_VRML_MFSTRING); gf_sg_vrml_mf_append(&f->family, GF_SG_VRML_MFSTRING, &ptr); - ((SFString*)ptr)->buffer = strdup(ft->fontName); + ((SFString*)ptr)->buffer = gf_strdup(ft->fontName); } gf_sg_vrml_mf_reset(&f->justify, GF_SG_VRML_MFSTRING); gf_sg_vrml_mf_append(&f->justify, GF_SG_VRML_MFSTRING, &ptr); - ((SFString*)ptr)->buffer = strdup("BEGIN"); + ((SFString*)ptr)->buffer = gf_strdup("BEGIN"); - if (f->style.buffer) free(f->style.buffer); - if (ft->is_italic && ft->is_bold) f->style.buffer = strdup("BOLDITALIC"); - else if (ft->is_bold) f->style.buffer = strdup("BOLD"); - else if (ft->is_italic) f->style.buffer = strdup("ITALIC"); - else f->style.buffer = strdup("PLAIN"); + if (f->style.buffer) gf_free(f->style.buffer); + if (ft->is_italic && ft->is_bold) f->style.buffer = gf_strdup("BOLDITALIC"); + else if (ft->is_bold) f->style.buffer = gf_strdup("BOLD"); + else if (ft->is_italic) f->style.buffer = gf_strdup("ITALIC"); + else f->style.buffer = gf_strdup("PLAIN"); /*convert to UTF-8*/ - str_w = (u16*)malloc(sizeof(u16) * (gr->nbGlyphs+1)); + str_w = (u16*)gf_malloc(sizeof(u16) * (gr->nbGlyphs+1)); for (j=0; j<gr->nbGlyphs; j++) str_w[j] = ft->glyph_codes[gr->indexes[j]]; str_w[j] = 0; - str = (char*)malloc(sizeof(char) * (gr->nbGlyphs+2)); + str = (char*)gf_malloc(sizeof(char) * (gr->nbGlyphs+2)); widestr = str_w; j = gf_utf8_wcstombs(str, sizeof(u8) * (gr->nbGlyphs+1), (const unsigned short **) &widestr); if (j != (u32) -1) { str[j] = 0; gf_sg_vrml_mf_reset(&t->string, GF_SG_VRML_MFSTRING); gf_sg_vrml_mf_append(&t->string, GF_SG_VRML_MFSTRING, &ptr); - ((SFString*)ptr)->buffer = (char*)malloc(sizeof(char) * (j+1)); + ((SFString*)ptr)->buffer = (char*)gf_malloc(sizeof(char) * (j+1)); memcpy(((SFString*)ptr)->buffer, str, sizeof(char) * (j+1)); } - free(str); - free(str_w); + gf_free(str); + gf_free(str_w); gl = (M_Shape *) s2b_new_node(read, TAG_MPEG4_Shape); gl->appearance = s2b_get_appearance(read, (GF_Node *) gl, gr->col, 0, 0); @@ -960,7 +963,7 @@ static void swf_ntext(void *sax_cbck, const char *content, Bool is_cdata) t = (SWFFlatText *)sax_cbck; len = strlen(content); if (!len) return; - t->final = realloc(t->final, sizeof(char)*(t->len+len+1)); + t->final = gf_realloc(t->final, sizeof(char)*(t->len+len+1)); t->final [t->len] = 0; strcat(t->final, content); t->len = strlen(t->final)+1; @@ -1004,16 +1007,16 @@ static GF_Err swf_bifs_define_edit_text(SWFReader *read, SWFEditText *text) gf_sg_vrml_mf_append(&f->justify, GF_SG_VRML_MFSTRING, (void**)&ptr); switch (text->align) { case 0: - ((SFString*)ptr)->buffer = strdup("BEGIN"); + ((SFString*)ptr)->buffer = gf_strdup("BEGIN"); break; case 1: - ((SFString*)ptr)->buffer = strdup("END"); + ((SFString*)ptr)->buffer = gf_strdup("END"); break; case 3: - ((SFString*)ptr)->buffer = strdup("JUSTIFY"); + ((SFString*)ptr)->buffer = gf_strdup("JUSTIFY"); break; default: - ((SFString*)ptr)->buffer = strdup("MIDDLE"); + ((SFString*)ptr)->buffer = gf_strdup("MIDDLE"); break; } @@ -1021,8 +1024,8 @@ static GF_Err swf_bifs_define_edit_text(SWFReader *read, SWFEditText *text) if (!text->read_only) strcat(styles, "EDITABLE"); if (text->password) strcat(styles, "PASSWORD"); - if (f->style.buffer) free(f->style.buffer); - f->style.buffer = strdup(styles); + if (f->style.buffer) gf_free(f->style.buffer); + f->style.buffer = gf_strdup(styles); if (text->init_value) { gf_sg_vrml_mf_reset(&t->string, GF_SG_VRML_MFSTRING); @@ -1039,11 +1042,11 @@ static GF_Err swf_bifs_define_edit_text(SWFReader *read, SWFEditText *text) gf_xml_sax_del(xml); if (flat.final) { - ((SFString*)ptr)->buffer = strdup(flat.final); - free(flat.final); + ((SFString*)ptr)->buffer = gf_strdup(flat.final); + gf_free(flat.final); } } else { - ((SFString*)ptr)->buffer = strdup(text->init_value); + ((SFString*)ptr)->buffer = gf_strdup(text->init_value); } } @@ -1058,16 +1061,16 @@ static GF_Err swf_bifs_define_edit_text(SWFReader *read, SWFEditText *text) gf_sg_vrml_mf_append(&layout->justify, GF_SG_VRML_MFSTRING, NULL); switch (text->align) { case 0: - layout->justify.vals[0] = strdup("BEGIN"); + layout->justify.vals[0] = gf_strdup("BEGIN"); break; case 1: - layout->justify.vals[0] = strdup("END"); + layout->justify.vals[0] = gf_strdup("END"); break; case 3: - layout->justify.vals[0] = strdup("JUSTIFY"); + layout->justify.vals[0] = gf_strdup("JUSTIFY"); break; default: - layout->justify.vals[0] = strdup("MIDDLE"); + layout->justify.vals[0] = gf_strdup("MIDDLE"); break; } if (text->multiline || text->word_wrap) layout->wrap = 1; @@ -1370,7 +1373,7 @@ static GF_Err swf_bifs_setup_sound(SWFReader *read, SWFSound *snd, Bool soundstr /*setup mux info*/ mux = (GF_MuxInfo*)gf_odf_desc_new(GF_ODF_MUXINFO_TAG); - mux->file_name = strdup(snd->szFileName); + mux->file_name = gf_strdup(snd->szFileName); // mux->startTime = snd->frame_delay_ms; mux->startTime = 0; /*MP3 in, destroy file once done*/ @@ -1464,7 +1467,7 @@ static GF_Err swf_bifs_setup_image(SWFReader *read, u32 ID, char *fileName) /*setup mux info*/ mux = (GF_MuxInfo*)gf_odf_desc_new(GF_ODF_MUXINFO_TAG); - mux->file_name = strdup(fileName); + mux->file_name = gf_strdup(fileName); /*destroy file once done*/ //mux->delete_file = 1; gf_list_add(esd->extensionDescriptors, mux); @@ -1557,8 +1560,8 @@ static void s2b_set_field(SWFReader *read, GF_List *dst, GF_Node *n, char *field if (type==GF_SG_VRML_SFSTRING) { if (((SFString*)f->field_ptr)->buffer) - free(((SFString*)f->field_ptr)->buffer); - ((SFString*)f->field_ptr)->buffer = strdup( (char *) val); + gf_free(((SFString*)f->field_ptr)->buffer); + ((SFString*)f->field_ptr)->buffer = gf_strdup( (char *) val); } else { gf_sg_vrml_field_copy(f->field_ptr, val, type); } @@ -1573,7 +1576,7 @@ static void s2b_set_field(SWFReader *read, GF_List *dst, GF_Node *n, char *field f = gf_sg_command_field_new(com); f->field_ptr = gf_sg_vrml_field_pointer_new(type); if (type==GF_SG_VRML_SFSTRING) { - ((SFString*)f->field_ptr)->buffer = strdup( (char *) val); + ((SFString*)f->field_ptr)->buffer = gf_strdup( (char *) val); } else { gf_sg_vrml_field_copy(f->field_ptr, val, type); } @@ -1926,7 +1929,7 @@ static GF_Err swf_bifs_define_button(SWFReader *read, SWF_Button *btn) if (sprite_ctrl) { S2BBtnRec *btnrec; if (!read->buttons) read->buttons = gf_list_new(); - btnrec = malloc(sizeof(S2BBtnRec)); + btnrec = gf_malloc(sizeof(S2BBtnRec)); btnrec->btn_id = btn->ID; btnrec->sprite_up_id = br->character_id; gf_list_add(read->buttons, btnrec); @@ -1972,7 +1975,7 @@ static void swf_bifs_finalize(SWFReader *read) while (gf_list_count(read->buttons)) { S2BBtnRec *btnrec = gf_list_get(read->buttons, 0); gf_list_rem(read->buttons, 0); - free(btnrec); + gf_free(btnrec); } count = gf_list_count(read->fonts); @@ -2095,13 +2098,13 @@ GF_Err swf_to_bifs_init(SWFReader *read) n = s2b_new_node(read, TAG_MPEG4_WorldInfo); gf_node_insert_child(read->root, n, -1); gf_node_register(n, read->root); - ((M_WorldInfo *)n)->title.buffer = strdup("GPAC SWF CONVERTION DISCLAIMER"); + ((M_WorldInfo *)n)->title.buffer = gf_strdup("GPAC SWF CONVERTION DISCLAIMER"); gf_sg_vrml_mf_alloc( & ((M_WorldInfo *)n)->info, GF_SG_VRML_MFSTRING, 3); sprintf(szMsg, "%s file converted to MPEG-4 Systems", read->load->fileName); - ((M_WorldInfo *)n)->info.vals[0] = strdup(szMsg); - ((M_WorldInfo *)n)->info.vals[1] = strdup("Conversion done using GPAC version " GPAC_FULL_VERSION " - (C) 2000-2005 GPAC"); - ((M_WorldInfo *)n)->info.vals[2] = strdup("Macromedia SWF to MPEG-4 Conversion mapping released under GPL license"); + ((M_WorldInfo *)n)->info.vals[0] = gf_strdup(szMsg); + ((M_WorldInfo *)n)->info.vals[1] = gf_strdup("Conversion done using GPAC version " GPAC_FULL_VERSION " - (C) 2000-2005 GPAC"); + ((M_WorldInfo *)n)->info.vals[2] = gf_strdup("Macromedia SWF to MPEG-4 Conversion mapping released under GPL license"); /*background*/ n = s2b_new_node(read, TAG_MPEG4_Background2D); @@ -2160,7 +2163,7 @@ GF_Err swf_to_bifs_init(SWFReader *read) if (read->load->ctx) read->load->ctx->max_proto_id = 1; gf_sg_vrml_mf_reset(&proto->ExternProto, GF_SG_VRML_MFURL); gf_sg_vrml_mf_append(&proto->ExternProto, GF_SG_VRML_MFURL, (void **) &url); - url->url = strdup("urn:inet:gpac:builtin:IndexedCurve2D"); + url->url = gf_strdup("urn:inet:gpac:builtin:IndexedCurve2D"); gf_sg_proto_field_new(proto, GF_SG_VRML_SFNODE, GF_SG_EVENT_EXPOSED_FIELD, "coord"); @@ -2248,5 +2251,12 @@ GF_Err swf_to_bifs_init(SWFReader *read) return GF_OK; } -#endif +#endif /*GPAC_DISABLE_SWF_IMPORT*/ + +#else +GF_Err swf_to_bifs_init(SWFReader *read) +{ + return GF_NOT_SUPPORTED; +} +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/scene_manager/swf_parse.c b/src/scene_manager/swf_parse.c index 77d9983..ce9e972 100644 --- a/src/scene_manager/swf_parse.c +++ b/src/scene_manager/swf_parse.c @@ -29,7 +29,7 @@ #include <zlib.h> -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_SWF_IMPORT /*display list item (one per layer only)*/ @@ -105,16 +105,17 @@ static void swf_init_decompress(SWFReader *read) u32 size, dst_size; char *src, *dst; + assert(gf_bs_get_size(read->bs)-8 < 1<<31); /*must fit within 32 bits*/ size = (u32) gf_bs_get_size(read->bs)-8; dst_size = read->length; - src = malloc(sizeof(char)*size); - dst = malloc(sizeof(char)*dst_size); + src = gf_malloc(sizeof(char)*size); + dst = gf_malloc(sizeof(char)*dst_size); memset(dst, 0, sizeof(char)*8); gf_bs_read_data(read->bs, src, size); dst_size -= 8; uncompress(dst+8, (uLongf *)&dst_size, src, size); dst_size += 8; - free(src); + gf_free(src); read->mem = dst; gf_bs_del(read->bs); read->bs = gf_bs_new(read->mem, dst_size, GF_BITSTREAM_READ); @@ -325,7 +326,7 @@ static char *swf_get_string(SWFReader *read) u32 i = 0; if (read->size>1024) { - name = malloc(sizeof(char)*read->size); + name = gf_malloc(sizeof(char)*read->size); } else { name = szName; } @@ -335,9 +336,9 @@ static char *swf_get_string(SWFReader *read) i++; } if (read->size>1024) { - return realloc(name, sizeof(char)*(strlen(name)+1)); + return gf_realloc(name, sizeof(char)*(strlen(name)+1)); } else { - return strdup(szName); + return gf_strdup(szName); } } @@ -351,15 +352,15 @@ static SWFShapeRec *swf_new_shape_rec() static SWFShapeRec *swf_clone_shape_rec(SWFShapeRec *old_sr) { - SWFShapeRec *new_sr = (SWFShapeRec *)malloc(sizeof(SWFShapeRec)); + SWFShapeRec *new_sr = (SWFShapeRec *)gf_malloc(sizeof(SWFShapeRec)); memcpy(new_sr, old_sr, sizeof(SWFShapeRec)); - new_sr->path = (SWFPath*)malloc(sizeof(SWFPath)); + new_sr->path = (SWFPath*)gf_malloc(sizeof(SWFPath)); memset(new_sr->path, 0, sizeof(SWFPath)); if (old_sr->nbGrad) { - new_sr->grad_col = (u32*)malloc(sizeof(u32) * old_sr->nbGrad); + new_sr->grad_col = (u32*)gf_malloc(sizeof(u32) * old_sr->nbGrad); memcpy(new_sr->grad_col, old_sr->grad_col, sizeof(u32) * old_sr->nbGrad); - new_sr->grad_ratio = (u8*)malloc(sizeof(u8) * old_sr->nbGrad); + new_sr->grad_ratio = (u8*)gf_malloc(sizeof(u8) * old_sr->nbGrad); memcpy(new_sr->grad_ratio, old_sr->grad_ratio, sizeof(u8) * old_sr->nbGrad); } return new_sr; @@ -389,8 +390,8 @@ static void swf_parse_styles(SWFReader *read, u32 revision, SWFShape *shape, u32 swf_align(read); style->nbGrad = swf_read_int(read, 8); if (style->nbGrad) { - style->grad_col = (u32 *) malloc(sizeof(u32) * style->nbGrad); - style->grad_ratio = (u8 *) malloc(sizeof(u8) * style->nbGrad); + style->grad_col = (u32 *) gf_malloc(sizeof(u32) * style->nbGrad); + style->grad_ratio = (u8 *) gf_malloc(sizeof(u8) * style->nbGrad); for (j=0; j<style->nbGrad; j++) { style->grad_ratio[j] = swf_read_int(read, 8); if (revision==2) style->grad_col[j] = swf_get_argb(read); @@ -403,30 +404,30 @@ static void swf_parse_styles(SWFReader *read, u32 revision, SWFShape *shape, u32 u32 i; u32 *grad_col; u8 *grad_ratio; - grad_ratio = (u8 *) malloc(sizeof(u8) * (style->nbGrad+1)); - grad_col = (u32 *) malloc(sizeof(u32) * (style->nbGrad+1)); + grad_ratio = (u8 *) gf_malloc(sizeof(u8) * (style->nbGrad+1)); + grad_col = (u32 *) gf_malloc(sizeof(u32) * (style->nbGrad+1)); grad_col[0] = style->grad_col[0]; grad_ratio[0] = 0; for (i=0; i<style->nbGrad; i++) { grad_col[i+1] = style->grad_col[i]; grad_ratio[i+1] = style->grad_ratio[i]; } - free(style->grad_col); + gf_free(style->grad_col); style->grad_col = grad_col; - free(style->grad_ratio); + gf_free(style->grad_ratio); style->grad_ratio = grad_ratio; style->nbGrad++; } if (style->grad_ratio[style->nbGrad-1] != 255) { - u32 *grad_col = (u32*)malloc(sizeof(u32) * (style->nbGrad+1)); - u8 *grad_ratio = (u8*)malloc(sizeof(u8) * (style->nbGrad+1)); + u32 *grad_col = (u32*)gf_malloc(sizeof(u32) * (style->nbGrad+1)); + u8 *grad_ratio = (u8*)gf_malloc(sizeof(u8) * (style->nbGrad+1)); memcpy(grad_col, style->grad_col, sizeof(u32) * style->nbGrad); memcpy(grad_ratio, style->grad_ratio, sizeof(u8) * style->nbGrad); grad_col[style->nbGrad] = style->grad_col[style->nbGrad-1]; grad_ratio[style->nbGrad] = 255; - free(style->grad_col); + gf_free(style->grad_col); style->grad_col = grad_col; - free(style->grad_ratio); + gf_free(style->grad_ratio); style->grad_ratio = grad_ratio; style->nbGrad++; } @@ -477,7 +478,7 @@ static void swf_parse_styles(SWFReader *read, u32 revision, SWFShape *shape, u32 static void swf_path_realloc_pts(SWFPath *path, u32 nbPts) { - path->pts = (SFVec2f*)realloc(path->pts, sizeof(SFVec2f) * (path->nbPts + nbPts)); + path->pts = (SFVec2f*)gf_realloc(path->pts, sizeof(SFVec2f) * (path->nbPts + nbPts)); } static void swf_path_add_com(SWFShapeRec *sr, SFVec2f pt, SFVec2f ctr, u32 type) @@ -485,7 +486,7 @@ static void swf_path_add_com(SWFShapeRec *sr, SFVec2f pt, SFVec2f ctr, u32 type) /*not an error*/ if (!sr) return; - sr->path->types = (u32*)realloc(sr->path->types, sizeof(u32) * (sr->path->nbType+1)); + sr->path->types = (u32*)gf_realloc(sr->path->types, sizeof(u32) * (sr->path->nbType+1)); sr->path->types[sr->path->nbType] = type; switch (type) { @@ -513,8 +514,8 @@ static void swf_referse_path(SWFPath *path) if (path->nbType<=1) return; - types = (u32 *) malloc(sizeof(u32) * path->nbType); - pts = (SFVec2f *) malloc(sizeof(SFVec2f) * path->nbPts); + types = (u32 *) gf_malloc(sizeof(u32) * path->nbType); + pts = (SFVec2f *) gf_malloc(sizeof(SFVec2f) * path->nbPts); /*need first moveTo*/ @@ -549,23 +550,23 @@ static void swf_referse_path(SWFPath *path) } j++; } - free(path->pts); + gf_free(path->pts); path->pts = pts; - free(path->types); + gf_free(path->types); path->types = types; } static void swf_free_shape_rec(SWFShapeRec *ptr) { - if (ptr->grad_col) free(ptr->grad_col); - if (ptr->grad_ratio) free(ptr->grad_ratio); + if (ptr->grad_col) gf_free(ptr->grad_col); + if (ptr->grad_ratio) gf_free(ptr->grad_ratio); if (ptr->path) { - if (ptr->path->pts) free(ptr->path->pts); - if (ptr->path->types) free(ptr->path->types); - if (ptr->path->idx) free(ptr->path->idx); - free(ptr->path); + if (ptr->path->pts) gf_free(ptr->path->pts); + if (ptr->path->types) gf_free(ptr->path->types); + if (ptr->path->idx) gf_free(ptr->path->idx); + gf_free(ptr->path); } - free(ptr); + gf_free(ptr); } static void swf_reset_rec_list(GF_List *recs) @@ -581,18 +582,18 @@ static void swf_append_path(SWFPath *a, SWFPath *b) { if (b->nbType<=1) return; - a->pts = (SFVec2f*)realloc(a->pts, sizeof(SFVec2f) * (a->nbPts + b->nbPts)); + a->pts = (SFVec2f*)gf_realloc(a->pts, sizeof(SFVec2f) * (a->nbPts + b->nbPts)); memcpy(&a->pts[a->nbPts], b->pts, sizeof(SFVec2f)*b->nbPts); a->nbPts += b->nbPts; - a->types = (u32*)realloc(a->types, sizeof(u32)*(a->nbType+ b->nbType)); + a->types = (u32*)gf_realloc(a->types, sizeof(u32)*(a->nbType+ b->nbType)); memcpy(&a->types[a->nbType], b->types, sizeof(u32)*b->nbType); a->nbType += b->nbType; } static void swf_path_add_type(SWFPath *path, u32 val) { - path->types = (u32*)realloc(path->types, sizeof(u32) * (path->nbType + 1)); + path->types = (u32*)gf_realloc(path->types, sizeof(u32) * (path->nbType + 1)); path->types[path->nbType] = val; path->nbType++; } @@ -677,9 +678,9 @@ restart: break; } } - free(p->pts); - free(p->types); - free(p); + gf_free(p->pts); + gf_free(p->types); + gf_free(p); gf_list_rem(paths, i); goto restart; } @@ -709,9 +710,9 @@ restart: break; } } - free(np->pts); - free(np->types); - free(np); + gf_free(np->pts); + gf_free(np->types); + gf_free(np); gf_list_rem(paths, j); j--; } @@ -719,8 +720,8 @@ restart: } /*reassemble path*/ - free(a->pts); - free(a->types); + gf_free(a->pts); + gf_free(a->types); memset(a, 0, sizeof(SWFPath)); while (gf_list_count(paths)) { @@ -792,9 +793,9 @@ restart: } } } - free(sorted->pts); - free(sorted->types); - free(sorted); + gf_free(sorted->pts); + gf_free(sorted->types); + gf_free(sorted); gf_list_rem(paths, 0); } gf_list_del(paths); @@ -1106,8 +1107,8 @@ static GF_Err swf_actions(SWFReader *read, u32 mask, u32 key) act.url = swf_get_string(read); act.target = swf_get_string(read); read->action(read, &act); - free(act.url); - free(act.target); + gf_free(act.url); + gf_free(act.target); break; /* next frame */ case 0x04: DO_ACT(GF_SWF_AS3_NEXT_FRAME) @@ -1134,14 +1135,14 @@ static GF_Err swf_actions(SWFReader *read, u32 mask, u32 key) act.type = GF_SWF_AS3_SET_TARGET; act.target = swf_get_string(read); read->action(read, &act); - free(act.target); + gf_free(act.target); break; /* goto label */ case 0x8C: act.type = GF_SWF_AS3_GOTO_LABEL; act.target = swf_get_string(read); read->action(read, &act); - free(act.target); + gf_free(act.target); break; default: // swf_report(read, GF_OK, "Skipping unsupported action %x", action_code); @@ -1293,7 +1294,7 @@ static GF_Err swf_place_obj(SWFReader *read, u32 revision) if (has_name) { name = swf_get_string(read); - free(name); + gf_free(name); } if (has_clip_actions) { swf_get_16(read); @@ -1416,7 +1417,7 @@ static GF_Err swf_def_font(SWFReader *read, u32 revision) count = swf_get_16(read); ft->nbGlyphs = count / 2; - offset_table = (u32*)malloc(sizeof(u32) * ft->nbGlyphs); + offset_table = (u32*)gf_malloc(sizeof(u32) * ft->nbGlyphs); offset_table[0] = 0; for (i=1; i<ft->nbGlyphs; i++) offset_table[i] = swf_get_16(read); @@ -1426,7 +1427,7 @@ static GF_Err swf_def_font(SWFReader *read, u32 revision) if (e) break; swf_parse_shape_def(read, ft, 0); } - free(offset_table); + gf_free(offset_table); if (e) return e; } else if (revision==1) { SWFRec rc; @@ -1442,7 +1443,7 @@ static GF_Err swf_def_font(SWFReader *read, u32 revision) ft->is_bold = swf_read_int(read, 1); swf_read_int(read, 8); count = swf_read_int(read, 8); - ft->fontName = (char*)malloc(sizeof(u8)*count+1); + ft->fontName = (char*)gf_malloc(sizeof(u8)*count+1); ft->fontName[count] = 0; for (i=0; i<count; i++) ft->fontName[i] = swf_read_int(read, 8); @@ -1450,7 +1451,7 @@ static GF_Err swf_def_font(SWFReader *read, u32 revision) start = swf_get_file_pos(read); if (ft->nbGlyphs) { - offset_table = (u32*)malloc(sizeof(u32) * ft->nbGlyphs); + offset_table = (u32*)gf_malloc(sizeof(u32) * ft->nbGlyphs); for (i=0; i<ft->nbGlyphs; i++) { if (wide_offset) offset_table[i] = swf_get_32(read); else offset_table[i] = swf_get_16(read); @@ -1471,7 +1472,7 @@ static GF_Err swf_def_font(SWFReader *read, u32 revision) swf_parse_shape_def(read, ft, 0); } - free(offset_table); + gf_free(offset_table); if (e) return e; checkpos = swf_get_file_pos(read); @@ -1480,7 +1481,7 @@ static GF_Err swf_def_font(SWFReader *read, u32 revision) return GF_NON_COMPLIANT_BITSTREAM; } - ft->glyph_codes = (u16*)malloc(sizeof(u16) * ft->nbGlyphs); + ft->glyph_codes = (u16*)gf_malloc(sizeof(u16) * ft->nbGlyphs); for (i=0; i<ft->nbGlyphs; i++) { if (wide_codes) ft->glyph_codes[i] = swf_get_16(read); else ft->glyph_codes[i] = swf_read_int(read, 8); @@ -1491,7 +1492,7 @@ static GF_Err swf_def_font(SWFReader *read, u32 revision) ft->descent = swf_get_s16(read); ft->leading = swf_get_s16(read); if (ft->nbGlyphs) { - ft->glyph_adv = (s16*)malloc(sizeof(s16) * ft->nbGlyphs); + ft->glyph_adv = (s16*)gf_malloc(sizeof(s16) * ft->nbGlyphs); for (i=0; i<ft->nbGlyphs; i++) ft->glyph_adv[i] = swf_get_s16(read); for (i=0; i<ft->nbGlyphs; i++) swf_get_rec(read, &rc); } @@ -1527,9 +1528,9 @@ static GF_Err swf_def_font_info(SWFReader *read) return GF_BAD_PARAM; } /*overwrite font info*/ - if (ft->fontName) free(ft->fontName); + if (ft->fontName) gf_free(ft->fontName); count = swf_read_int(read, 8); - ft->fontName = (char*)malloc(sizeof(char) * (count+1)); + ft->fontName = (char*)gf_malloc(sizeof(char) * (count+1)); ft->fontName[count] = 0; for (i=0; i<count; i++) ft->fontName[i] = swf_read_int(read, 8); swf_read_int(read, 2); @@ -1541,8 +1542,8 @@ static GF_Err swf_def_font_info(SWFReader *read) /*TODO - this should be remapped to a font data stream, we currently only assume the glyph code table is the same as the original font file...*/ wide_chars = swf_read_int(read, 1); - if (ft->glyph_codes) free(ft->glyph_codes); - ft->glyph_codes = (u16*)malloc(sizeof(u16) * ft->nbGlyphs); + if (ft->glyph_codes) gf_free(ft->glyph_codes); + ft->glyph_codes = (u16*)gf_malloc(sizeof(u16) * ft->nbGlyphs); for (i=0; i<ft->nbGlyphs; i++) { if (wide_chars) ft->glyph_codes[i] = swf_get_16(read); @@ -1596,8 +1597,8 @@ static GF_Err swf_def_text(SWFReader *read, u32 revision) gr->orig_x = offX; gr->orig_y = offY; gr->nbGlyphs = count; - gr->indexes = (u32*)malloc(sizeof(u32) * gr->nbGlyphs); - gr->dx = (Fixed*)malloc(sizeof(Fixed) * gr->nbGlyphs); + gr->indexes = (u32*)gf_malloc(sizeof(u32) * gr->nbGlyphs); + gr->dx = (Fixed*)gf_malloc(sizeof(Fixed) * gr->nbGlyphs); for (i=0; i<gr->nbGlyphs; i++) { gr->indexes[i] = swf_read_int(read, nbits_glyph); gr->dx[i] = FLT2FIX( swf_read_int(read, nbits_adv) * SWF_TWIP_SCALE ); @@ -1638,9 +1639,9 @@ exit: while (gf_list_count(txt.text)) { SWFGlyphRec *gr = (SWFGlyphRec *)gf_list_get(txt.text, 0); gf_list_rem(txt.text, 0); - if (gr->indexes) free(gr->indexes); - if (gr->dx) free(gr->dx); - free(gr); + if (gr->indexes) gf_free(gr->indexes); + if (gr->dx) gf_free(gr->dx); + gf_free(gr); } gf_list_del(txt.text); @@ -1700,8 +1701,8 @@ static GF_Err swf_def_edit_text(SWFReader *read) if (! (read->flags & GF_SM_SWF_NO_TEXT) ) { e = read->define_edit_text(read, &txt); } - free(var_name); - if (txt.init_value) free(txt.init_value); + gf_free(var_name); + if (txt.init_value) gf_free(txt.init_value); return e; } @@ -1710,8 +1711,8 @@ static void swf_delete_sound_stream(SWFReader *read) { if (!read->sound_stream) return; if (read->sound_stream->output) fclose(read->sound_stream->output); - if (read->sound_stream->szFileName) free(read->sound_stream->szFileName); - free(read->sound_stream); + if (read->sound_stream->szFileName) gf_free(read->sound_stream->szFileName); + gf_free(read->sound_stream); read->sound_stream = NULL; } @@ -1753,7 +1754,7 @@ static GF_Err swf_def_sprite(SWFReader *read) while (gf_list_count(read->display_list)) { DispShape *s = (DispShape *)gf_list_get(read->display_list, 0); gf_list_rem(read->display_list, 0); - free(s); + gf_free(s); } gf_list_del(read->display_list); read->display_list = prev_dlist; @@ -1780,12 +1781,12 @@ static GF_Err swf_def_sound(SWFReader *read) /*raw PCM*/ case 0: swf_report(read, GF_NOT_SUPPORTED, "Raw PCM Audio not supported"); - free(snd); + gf_free(snd); break; /*ADPCM*/ case 1: swf_report(read, GF_NOT_SUPPORTED, "AD-PCM Audio not supported"); - free(snd); + gf_free(snd); break; /*MP3*/ case 2: @@ -1796,16 +1797,16 @@ static GF_Err swf_def_sound(SWFReader *read) sprintf(szName, "swf_sound_%d.mp3", snd->ID); if (read->localPath) { - snd->szFileName = (char*)malloc(sizeof(char)*GF_MAX_PATH); + snd->szFileName = (char*)gf_malloc(sizeof(char)*GF_MAX_PATH); strcpy(snd->szFileName, read->localPath); strcat(snd->szFileName, szName); } else { - snd->szFileName = strdup(szName); + snd->szFileName = gf_strdup(szName); } - snd->output = fopen(snd->szFileName, "wb"); + snd->output = gf_f64_open(snd->szFileName, "wb"); alloc_size = 4096; - frame = (char*)malloc(sizeof(char)*4096); + frame = (char*)gf_malloc(sizeof(char)*4096); snd->frame_delay_ms = swf_get_16(read); snd->frame_delay_ms = read->current_frame*1000; snd->frame_delay_ms /= read->frame_rate; @@ -1819,12 +1820,12 @@ static GF_Err swf_def_sound(SWFReader *read) tot_size += toread; } - free(frame); + gf_free(frame); return gf_list_add(read->sounds, snd); } case 3: swf_report(read, GF_NOT_SUPPORTED, "Unrecognized sound format"); - free(snd); + gf_free(snd); break; } return GF_OK; @@ -1926,12 +1927,12 @@ static GF_Err swf_soundstream_hdr(SWFReader *read) /*raw PCM*/ case 0: swf_report(read, GF_NOT_SUPPORTED, "Raw PCM Audio not supported"); - free(snd); + gf_free(snd); break; /*ADPCM*/ case 1: swf_report(read, GF_NOT_SUPPORTED, "AD-PCM Audio not supported"); - free(snd); + gf_free(snd); break; /*MP3*/ case 2: @@ -1941,12 +1942,12 @@ static GF_Err swf_soundstream_hdr(SWFReader *read) } else { sprintf(szName, "swf_soundstream_%d.mp3", read->current_sprite_id); } - read->sound_stream->szFileName = strdup(szName); + read->sound_stream->szFileName = gf_strdup(szName); read->setup_sound(read, read->sound_stream, 0); break; case 3: swf_report(read, GF_NOT_SUPPORTED, "Unrecognized sound format"); - free(snd); + gf_free(snd); break; } return GF_OK; @@ -1954,6 +1955,9 @@ static GF_Err swf_soundstream_hdr(SWFReader *read) static GF_Err swf_soundstream_block(SWFReader *read) { +#ifdef GPAC_DISABLE_AV_PARSERS + return swf_func_skip(read); +#else unsigned char bytes[4]; u32 hdr, alloc_size, size, tot_size, samplesPerFrame, delay; char *frame; @@ -1968,7 +1972,7 @@ static GF_Err swf_soundstream_block(SWFReader *read) /*error at setup*/ if (!read->sound_stream->output) { - read->sound_stream->output = fopen(read->sound_stream->szFileName, "wb"); + read->sound_stream->output = gf_f64_open(read->sound_stream->szFileName, "wb"); if (!read->sound_stream->output) return swf_func_skip(read); } @@ -1982,7 +1986,7 @@ static GF_Err swf_soundstream_block(SWFReader *read) if (!samplesPerFrame) return GF_OK; alloc_size = 1; - frame = (char*)malloc(sizeof(char)); + frame = (char*)gf_malloc(sizeof(char)); tot_size = 4; /*parse all frames*/ while (1) { @@ -1993,7 +1997,7 @@ static GF_Err swf_soundstream_block(SWFReader *read) hdr = GF_4CC(bytes[0], bytes[1], bytes[2], bytes[3]); size = gf_mp3_frame_size(hdr); if (alloc_size<size-4) { - frame = (char*)realloc(frame, sizeof(char)*(size-4)); + frame = (char*)gf_realloc(frame, sizeof(char)*(size-4)); alloc_size = size-4; } /*watchout for truncated framesif */ @@ -2005,8 +2009,9 @@ static GF_Err swf_soundstream_block(SWFReader *read) if (tot_size + size >= read->size) break; tot_size += size; } - free(frame); + gf_free(frame); return GF_OK; +#endif } static GF_Err swf_def_hdr_jpeg(SWFReader *read) @@ -2017,7 +2022,7 @@ static GF_Err swf_def_hdr_jpeg(SWFReader *read) } read->jpeg_hdr_size = read->size; if (read->size) { - read->jpeg_hdr = malloc(sizeof(char)*read->size); + read->jpeg_hdr = gf_malloc(sizeof(char)*read->size); swf_read_data(read, read->jpeg_hdr, read->size); } return GF_OK; @@ -2052,7 +2057,7 @@ static GF_Err swf_def_bits_jpeg(SWFReader *read, u32 version) } if (version!=3) - file = fopen(szName, "wb"); + file = gf_f64_open(szName, "wb"); if (version==1 && read->jpeg_hdr_size) { /*remove JPEG EOI*/ @@ -2061,7 +2066,7 @@ static GF_Err swf_def_bits_jpeg(SWFReader *read, u32 version) swf_get_16(read); size-=2; } - buf = malloc(sizeof(u8)*size); + buf = gf_malloc(sizeof(u8)*size); swf_read_data(read, buf, size); if (version==1) { fwrite(buf, 1, size, file); @@ -2098,22 +2103,22 @@ static GF_Err swf_def_bits_jpeg(SWFReader *read, u32 version) gf_bs_del(bs); osize = w*h*4; - raw = malloc(sizeof(char)*osize); + raw = gf_malloc(sizeof(char)*osize); memset(raw, 0, sizeof(char)*osize); e = gf_img_jpeg_dec(buf+skip, size-skip, &w, &h, &pf, raw, &osize, 4); /*read alpha map and decompress it*/ - if (size<AlphaPlaneSize) buf = realloc(buf, sizeof(u8)*AlphaPlaneSize); + if (size<AlphaPlaneSize) buf = gf_realloc(buf, sizeof(u8)*AlphaPlaneSize); swf_read_data(read, buf, AlphaPlaneSize); osize = w*h; - dst = malloc(sizeof(char)*osize); + dst = gf_malloc(sizeof(char)*osize); uncompress(dst, (uLongf *) &osize, buf, AlphaPlaneSize); /*write alpha channel*/ for (j=0; j<osize; j++) { raw[4*j + 3] = dst[j]; } - free(dst); + gf_free(dst); /*write png*/ if (read->load->localPath) { @@ -2123,16 +2128,16 @@ static GF_Err swf_def_bits_jpeg(SWFReader *read, u32 version) } osize = w*h*4; - buf = realloc(buf, sizeof(char)*osize); - gf_img_png_enc(raw, w, h, GF_PIXEL_RGBA, buf, &osize); + buf = gf_realloc(buf, sizeof(char)*osize); + gf_img_png_enc(raw, w, h, h*4, GF_PIXEL_RGBA, buf, &osize); - file = fopen(szName, "wb"); + file = gf_f64_open(szName, "wb"); fwrite(buf, 1, osize, file); fclose(file); - free(raw); + gf_free(raw); } - free(buf); + gf_free(buf); return read->setup_image(read, ID, szName); @@ -2241,7 +2246,7 @@ static GF_Err swf_process_tag(SWFReader *read) case SWF_FRAMELABEL: { char *framelabel = swf_get_string(read); - free(framelabel); + gf_free(framelabel); return GF_OK; } @@ -2365,24 +2370,24 @@ void gf_sm_load_done_swf(GF_SceneLoader *load) if (!read) return; gf_bs_del(read->bs); - if (read->mem) free(read->mem); + if (read->mem) gf_free(read->mem); read->finalize(read); while (gf_list_count(read->display_list)) { DispShape *s = (DispShape *)gf_list_get(read->display_list, 0); gf_list_rem(read->display_list, 0); - free(s); + gf_free(s); } gf_list_del(read->display_list); while (gf_list_count(read->fonts)) { SWFFont *ft = (SWFFont *)gf_list_get(read->fonts, 0); gf_list_rem(read->fonts, 0); - if (ft->glyph_adv) free(ft->glyph_adv); - if (ft->glyph_codes) free(ft->glyph_codes); - if (ft->fontName) free(ft->fontName); + if (ft->glyph_adv) gf_free(ft->glyph_adv); + if (ft->glyph_codes) gf_free(ft->glyph_codes); + if (ft->fontName) gf_free(ft->fontName); gf_list_del(ft->glyphs); - free(ft); + gf_free(ft); } gf_list_del(read->fonts); gf_list_del(read->apps); @@ -2391,16 +2396,16 @@ void gf_sm_load_done_swf(GF_SceneLoader *load) SWFSound *snd = (SWFSound *)gf_list_get(read->sounds, 0); gf_list_rem(read->sounds, 0); if (snd->output) fclose(snd->output); - if (snd->szFileName) free(snd->szFileName); - free(snd); + if (snd->szFileName) gf_free(snd->szFileName); + gf_free(snd); } gf_list_del(read->sounds); swf_delete_sound_stream(read); - if (read->jpeg_hdr) free(read->jpeg_hdr); - if (read->localPath) free(read->localPath); + if (read->jpeg_hdr) gf_free(read->jpeg_hdr); + if (read->localPath) gf_free(read->localPath); fclose(read->input); - free(read); + gf_free(read); load->loader_priv = NULL; } @@ -2414,7 +2419,7 @@ GF_Err gf_sm_load_init_swf(GF_SceneLoader *load) u8 version; if (!load->ctx || !load->scene_graph || !load->fileName) return GF_BAD_PARAM; - input = fopen(load->fileName, "rb"); + input = gf_f64_open(load->fileName, "rb"); if (!input) return GF_URL_ERROR; GF_SAFEALLOC(read, SWFReader); @@ -2432,14 +2437,14 @@ GF_Err gf_sm_load_init_swf(GF_SceneLoader *load) read->flags = load->swf_import_flags; read->flat_limit = FLT2FIX(load->swf_flatten_limit); - if (load->localPath) read->localPath = strdup(load->localPath); + if (load->localPath) read->localPath = gf_strdup(load->localPath); else { char *c; - read->localPath = strdup(load->fileName); + read->localPath = gf_strdup(load->fileName); c = strrchr(read->localPath, GF_PATH_SEPARATOR); if (c) c[1] = 0; else { - free(read->localPath); + gf_free(read->localPath); read->localPath = NULL; } } @@ -2481,6 +2486,7 @@ GF_Err gf_sm_load_init_swf(GF_SceneLoader *load) } e = swf_to_bifs_init(read); + if (e) goto exit; /*parse all tags*/ while (e == GF_OK) { @@ -2489,10 +2495,13 @@ GF_Err gf_sm_load_init_swf(GF_SceneLoader *load) } if (e==GF_EOS) e = GF_OK; + load->done = gf_sm_load_done_swf; + load->process = gf_sm_load_run_swf; + exit: if (e) gf_sm_load_done_swf(load); return e; } -#endif +#endif /*GPAC_DISABLE_SWF_IMPORT*/ diff --git a/src/scene_manager/text_to_bifs.c b/src/scene_manager/text_to_bifs.c index 50efcf6..10d2467 100644 --- a/src/scene_manager/text_to_bifs.c +++ b/src/scene_manager/text_to_bifs.c @@ -52,7 +52,7 @@ static GF_Err gf_text_guess_format(char *filename, u32 *fmt) { char szLine[2048], szTest[10]; u32 val; - FILE *test = fopen(filename, "rt"); + FILE *test = gf_f64_open(filename, "rt"); if (!test) return GF_URL_ERROR; while (fgets(szLine, 2048, test) != NULL) { @@ -71,13 +71,18 @@ static GF_Err gf_text_guess_format(char *filename, u32 *fmt) if (!strnicmp(ext, ".ttxt", 5)) *fmt = GF_TEXT_IMPORT_TTXT; ext = strstr(szLine, "?>"); if (ext) ext += 2; - if (!ext[0]) fgets(szLine, 2048, test); + if (!ext[0]){ + if (!fgets(szLine, 2048, test)) + szLine[0] = '\0'; + } if (strstr(szLine, "x-quicktime-tx3g")) *fmt = GF_TEXT_IMPORT_TEXML; } fclose(test); return GF_OK; } +#ifndef GPAC_DISABLE_VRML + static GF_Err gf_text_import_srt_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo *mux) { GF_Err e; @@ -136,7 +141,7 @@ static GF_Err gf_text_import_srt_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxI } } - srt_in = fopen(mux->file_name, "rt"); + srt_in = gf_f64_open(mux->file_name, "rt"); if (!srt_in) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] cannot open input file %s\n", mux->file_name)); return GF_URL_ERROR; @@ -177,13 +182,13 @@ static GF_Err gf_text_import_srt_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxI inf->fieldType = style.fieldType; inf->field_ptr = gf_sg_vrml_field_pointer_new(style.fieldType); sfstr = (SFString *)inf->field_ptr; - if (bold && italic && underlined) sfstr->buffer = strdup("BOLDITALIC UNDERLINED"); - else if (italic && underlined) sfstr->buffer = strdup("ITALIC UNDERLINED"); - else if (bold && underlined) sfstr->buffer = strdup("BOLD UNDERLINED"); - else if (underlined) sfstr->buffer = strdup("UNDERLINED"); - else if (bold && italic) sfstr->buffer = strdup("BOLDITALIC"); - else if (bold) sfstr->buffer = strdup("BOLD"); - else sfstr->buffer = strdup("ITALIC"); + if (bold && italic && underlined) sfstr->buffer = gf_strdup("BOLDITALIC UNDERLINED"); + else if (italic && underlined) sfstr->buffer = gf_strdup("ITALIC UNDERLINED"); + else if (bold && underlined) sfstr->buffer = gf_strdup("BOLD UNDERLINED"); + else if (underlined) sfstr->buffer = gf_strdup("UNDERLINED"); + else if (bold && italic) sfstr->buffer = gf_strdup("BOLDITALIC"); + else if (bold) sfstr->buffer = gf_strdup("BOLD"); + else sfstr->buffer = gf_strdup("ITALIC"); gf_list_add(au->commands, com); } @@ -317,7 +322,7 @@ static GF_Err gf_text_import_srt_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxI len++; } szText[len] = 0; - sfstr->buffer = strdup(szText); + sfstr->buffer = gf_strdup(szText); break; } } @@ -327,6 +332,10 @@ exit: fclose(srt_in); return e; } +#endif /*GPAC_DISABLE_VRML*/ + + +#ifndef GPAC_DISABLE_VRML static GF_Err gf_text_import_sub_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo *mux) { @@ -386,7 +395,7 @@ static GF_Err gf_text_import_sub_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxI } } - sub_in = fopen(mux->file_name, "rt"); + sub_in = gf_f64_open(mux->file_name, "rt"); if (!sub_in) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] cannot open input file %s\n", mux->file_name)); return GF_URL_ERROR; @@ -498,17 +507,20 @@ static GF_Err gf_text_import_sub_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxI gf_list_add(au->commands, com); gf_sg_vrml_mf_append(inf->field_ptr, GF_SG_VRML_MFSTRING, (void **) &sfstr); - sfstr->buffer = strdup(szText); + sfstr->buffer = gf_strdup(szText); } if (e) gf_sm_stream_del(ctx, srt); fclose(sub_in); return e; } +#endif + GF_EXPORT GF_Err gf_sm_import_bifs_subtitle(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo *mux) { +#ifndef GPAC_DISABLE_VRML GF_Err e; u32 fmt; e = gf_text_guess_format(mux->file_name, &fmt); @@ -517,5 +529,8 @@ GF_Err gf_sm_import_bifs_subtitle(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo if (fmt==1) return gf_text_import_srt_bifs(ctx, src, mux); else return gf_text_import_sub_bifs(ctx, src, mux); +#else + return GF_NOT_SUPPORTED; +#endif } diff --git a/src/scenegraph/base_scenegraph.c b/src/scenegraph/base_scenegraph.c index 7c2de6f..989689c 100644 --- a/src/scenegraph/base_scenegraph.c +++ b/src/scenegraph/base_scenegraph.c @@ -38,7 +38,7 @@ static void ReplaceDEFNode(GF_Node *FromNode, GF_Node *node, GF_Node *newNode, B static void ReplaceIRINode(GF_Node *FromNode, GF_Node *oldNode, GF_Node *newNode); #endif -static void node_modif_stub(GF_SceneGraph *sg, GF_Node *node, GF_FieldInfo *info) +static void node_modif_stub(GF_SceneGraph *sg, GF_Node *node, GF_FieldInfo *info, GF_Node *script) { } @@ -48,13 +48,15 @@ GF_SceneGraph *gf_sg_new() GF_SAFEALLOC(tmp, GF_SceneGraph); if (!tmp) return NULL; + tmp->exported_nodes = gf_list_new(); + +#ifndef GPAC_DISABLE_VRML tmp->protos = gf_list_new(); tmp->unregistered_protos = gf_list_new(); - tmp->Routes = gf_list_new(); tmp->routes_to_activate = gf_list_new(); tmp->routes_to_destroy = gf_list_new(); - tmp->exported_nodes = gf_list_new(); +#endif #ifndef GPAC_DISABLE_SVG tmp->dom_evt.evt_list = gf_list_new(); @@ -85,12 +87,16 @@ GF_SceneGraph *gf_sg_new_subscene(GF_SceneGraph *scene) tmp->script_action = scene->script_action; tmp->script_action_cbck = scene->script_action_cbck; tmp->script_load = scene->script_load; + tmp->on_node_modified = scene->on_node_modified; /*by default use the same callbacks*/ tmp->userpriv = scene->userpriv; tmp->GetSceneTime = scene->GetSceneTime; - tmp->GetExternProtoLib = scene->GetExternProtoLib; tmp->NodeCallback = scene->NodeCallback; + +#ifndef GPAC_DISABLE_VRML + tmp->GetExternProtoLib = scene->GetExternProtoLib; +#endif return tmp; } @@ -121,10 +127,13 @@ void gf_sg_del(GF_SceneGraph *sg) { if (!sg) return; +#ifndef GPAC_DISABLE_VRML if (sg->global_qp) { gf_node_unregister(sg->global_qp, NULL); sg->global_qp = NULL; } +#endif + gf_sg_reset(sg); #ifndef GPAC_DISABLE_SVG @@ -138,13 +147,17 @@ void gf_sg_del(GF_SceneGraph *sg) gf_list_del(sg->scripts); gf_list_del(sg->objects); #endif + +#ifndef GPAC_DISABLE_VRML gf_list_del(sg->Routes); gf_list_del(sg->protos); gf_list_del(sg->unregistered_protos); gf_list_del(sg->routes_to_activate); gf_list_del(sg->routes_to_destroy); +#endif + gf_list_del(sg->exported_nodes); - free(sg); + gf_free(sg); } /*recursive traverse of the whole graph to check for scope mixes (nodes from an inline graph @@ -191,7 +204,7 @@ void SG_GraphRemoved(GF_Node *node, GF_SceneGraph *sg) if (prev) prev->next = list->next; else *(GF_ChildNodeItem **) info.far_ptr = list->next; cur = list; - free(cur); + gf_free(cur); } else { SG_GraphRemoved(list->node, sg); } @@ -234,7 +247,7 @@ void SG_GraphRemoved(GF_Node *node, GF_SceneGraph *sg) if (prev) prev->next = list->next; else f->node_list = list->next; cur = list; - free(cur); + gf_free(cur); } else { SG_GraphRemoved(list->node, sg); } @@ -273,6 +286,8 @@ static GFINLINE u32 get_num_id_nodes(GF_SceneGraph *sg) GF_EXPORT void gf_sg_reset(GF_SceneGraph *sg) { + GF_SceneGraph *par; + GF_List *gc; u32 type, count; NodeIDedItem *reg_node; if (!sg) return; @@ -287,6 +302,7 @@ void gf_sg_reset(GF_SceneGraph *sg) } #endif + gc = gf_list_new(); #ifdef GPAC_HAS_SPIDERMONKEY /*scripts are the first source of cylic references in the graph. In order to clean properly force a remove of all script nodes, this will release all references to nodes in JS*/ @@ -300,6 +316,8 @@ void gf_sg_reset(GF_SceneGraph *sg) /*FORCE destroy in case the script refers to itself*/ n->sgprivate->num_instances=1; gf_node_unregister(n, NULL); + /*remember this script was forced to be destroyed*/ + gf_list_add(gc, n); } #endif @@ -312,9 +330,10 @@ void gf_sg_reset(GF_SceneGraph *sg) } /*flush any pending add_listener*/ - gf_dom_listener_process_add(sg); + gf_dom_listener_reset_defered(sg); #endif +#ifndef GPAC_DISABLE_VRML while (gf_list_count(sg->routes_to_activate)) { gf_list_rem(sg->routes_to_activate, 0); } @@ -326,17 +345,22 @@ void gf_sg_reset(GF_SceneGraph *sg) gf_sg_route_del(r); } +#endif - /*reset the main tree*/ - if (sg->RootNode) gf_node_unregister(sg->RootNode, NULL); - sg->RootNode = NULL; - /*THEN reset all exported symbols (we must do it after the reset in case of scripts)*/ + /*reset all exported symbols */ while (gf_list_count(sg->exported_nodes)) { GF_Node *n = gf_list_get(sg->exported_nodes, 0); gf_list_rem(sg->exported_nodes, 0); gf_node_replace(n, NULL, 0); } + /*reassign the list of exported nodes to our garbage collected nodes*/ + gf_list_del(sg->exported_nodes); + sg->exported_nodes = gc; + + /*reset the main tree*/ + if (sg->RootNode) gf_node_unregister(sg->RootNode, NULL); + sg->RootNode = NULL; /*WATCHOUT: we may have cyclic dependencies due to 1- a node referencing itself (forbidden in VRML) @@ -348,7 +372,11 @@ restart: while (reg_node) { Bool ignore = 0; GF_Node *node = reg_node->node; - if (!node || (node==sg->global_qp) ) { + if (!node +#ifndef GPAC_DISABLE_VRML + || (node==sg->global_qp) +#endif + ) { reg_node = reg_node->next; continue; } @@ -376,7 +404,7 @@ restart: #endif ReplaceDEFNode(nlist->node, reg_node->node, NULL, 0); - free(nlist); + gf_free(nlist); nlist = next; } if (ignore) { @@ -389,12 +417,17 @@ restart: //sg->node_registry[i-1] = NULL; count = get_num_id_nodes(sg); node->sgprivate->num_instances = 1; + /*remember this node was forced to be destroyed*/ + gf_list_add(sg->exported_nodes, node); gf_node_unregister(node, NULL); if (count != get_num_id_nodes(sg)) goto restart; reg_node = reg_node->next; } - assert((sg->id_node==NULL) || sg->global_qp); + /*reset the forced destroy ndoes*/ + gf_list_reset(sg->exported_nodes); + +#ifndef GPAC_DISABLE_VRML /*destroy all proto*/ while (gf_list_count(sg->protos)) { GF_Proto *p = (GF_Proto *)gf_list_get(sg->protos, 0); @@ -407,24 +440,45 @@ restart: /*this will unregister the proto from the graph, so don't delete the chain entry*/ gf_sg_proto_del(p); } -#ifndef GPAC_DISABLE_SVG -// assert(gf_list_count(sg->xlink_hrefs) == 0); -#endif /*last destroy all routes*/ gf_sg_destroy_routes(sg); sg->simulation_tick = 0; +#endif /*GPAC_DISABLE_VRML*/ + +#ifndef GPAC_DISABLE_SVG +// assert(gf_list_count(sg->xlink_hrefs) == 0); +#endif + while (gf_list_count(sg->ns)) { GF_XMLNS *ns = gf_list_get(sg->ns, 0); gf_list_rem(sg->ns, 0); - if (ns->name) free(ns->name); - if (ns->qname) free(ns->qname); - free(ns); + if (ns->name) gf_free(ns->name); + if (ns->qname) gf_free(ns->qname); + gf_free(ns); } gf_list_del(sg->ns); sg->ns = 0; + par = sg; + while (par->parent_scene) par = par->parent_scene; + +#ifndef GPAC_DISABLE_SVG + if (par != sg) { + u32 count, i; + count = gf_list_count(par->smil_timed_elements); + for (i=0; i<count; i++) { + SMIL_Timing_RTI *rti = gf_list_get(par->smil_timed_elements, i); + if (rti->timed_elt->sgprivate->scenegraph == sg) { + gf_list_rem(par->smil_timed_elements, i); + i--; + count--; + } + } + } +#endif + #ifdef GF_SELF_REPLACE_ENABLE sg->graph_has_been_reset = 1; #endif @@ -481,7 +535,9 @@ GF_EXPORT Bool gf_sg_use_pixel_metrics(GF_SceneGraph *sg) { if (sg) { +#ifndef GPAC_DISABLE_VRML while (sg->pOwningProto) sg = sg->parent_scene; +#endif return sg->usePixelMetrics; } return 0; @@ -516,8 +572,8 @@ void remove_node_id(GF_SceneGraph *sg, GF_Node *node) sg->id_node = reg_node->next; if (sg->id_node_last==reg_node) sg->id_node_last = reg_node->next; - if (reg_node->NodeName) free(reg_node->NodeName); - free(reg_node); + if (reg_node->NodeName) gf_free(reg_node->NodeName); + gf_free(reg_node); } else { NodeIDedItem *to_del; while (reg_node->next) { @@ -530,24 +586,34 @@ void remove_node_id(GF_SceneGraph *sg, GF_Node *node) if (sg->id_node_last==to_del) { sg->id_node_last = reg_node->next ? reg_node->next : reg_node; } - if (to_del->NodeName) free(to_del->NodeName); - free(to_del); + if (to_del->NodeName) gf_free(to_del->NodeName); + gf_free(to_del); break; } } } +GF_Err gf_node_try_destroy(GF_SceneGraph *sg, GF_Node *pNode, GF_Node *parentNode) +{ + if (!sg) return GF_BAD_PARAM; + /*if node has been destroyed, don't even look at it*/ + if (gf_list_find(sg->exported_nodes, pNode)>=0) return GF_OK; + if (!pNode || !pNode->sgprivate->num_instances) return GF_OK; + return gf_node_unregister(pNode, parentNode); +} + GF_EXPORT GF_Err gf_node_unregister(GF_Node *pNode, GF_Node *parentNode) { +#ifndef GPAC_DISABLE_VRML u32 j; - GF_SceneGraph *pSG; GF_Route *r; +#endif + Bool detach=0; + GF_SceneGraph *pSG; if (!pNode) return GF_OK; pSG = pNode->sgprivate->scenegraph; - /*if this is a proto its is registered in its parent graph, not the current*/ - if (pSG && (pNode == (GF_Node*)pSG->pOwningProto)) pSG = pSG->parent_scene; if (parentNode) { GF_ParentList *nlist = pNode->sgprivate->parents; @@ -561,7 +627,8 @@ GF_Err gf_node_unregister(GF_Node *pNode, GF_Node *parentNode) } if (prev) prev->next = nlist->next; else pNode->sgprivate->parents = nlist->next; - free(nlist); + gf_free(nlist); + if (pNode->sgprivate->parents==NULL) detach=1; break; } } @@ -570,15 +637,25 @@ GF_Err gf_node_unregister(GF_Node *pNode, GF_Node *parentNode) } } +#ifndef GPAC_DISABLE_VRML + /*if this is a proto its is registered in its parent graph, not the current*/ + if (pSG && (pNode == (GF_Node*)pSG->pOwningProto)) pSG = pSG->parent_scene; +#endif + /*unregister the instance*/ assert(pNode->sgprivate->num_instances); pNode->sgprivate->num_instances -= 1; /*this is just an instance removed*/ if (pNode->sgprivate->num_instances) { +#ifdef GPAC_HAS_SPIDERMONKEY + if (pNode->sgprivate->num_instances==1) detach=1; + if (pNode->sgprivate->scenegraph->on_node_modified && detach && pNode->sgprivate->interact && pNode->sgprivate->interact->js_binding) { + pNode->sgprivate->scenegraph->on_node_modified(pNode->sgprivate->scenegraph, pNode, NULL, NULL); + } +#endif return GF_OK; } - assert(pNode->sgprivate->parents==NULL); @@ -588,6 +665,7 @@ GF_Err gf_node_unregister(GF_Node *pNode, GF_Node *parentNode) remove_node_id(pSG, pNode); } +#ifndef GPAC_DISABLE_VRML /*check all routes from or to this node and destroy them - cf spec*/ j=0; while ((r = (GF_Route *)gf_list_enum(pSG->Routes, &j))) { @@ -596,6 +674,14 @@ GF_Err gf_node_unregister(GF_Node *pNode, GF_Node *parentNode) j--; } } +#endif + +#ifndef GPAC_DISABLE_SVG + if (pSG->use_stack && (gf_list_del_item(pSG->use_stack, pNode)>=0)) { + pSG->abort_bubbling = 1; + } +#endif + } /*delete the node*/ if (pNode->sgprivate->scenegraph && (pNode->sgprivate->scenegraph->RootNode==pNode)) { @@ -611,30 +697,25 @@ GF_Err gf_node_unregister(GF_Node *pNode, GF_Node *parentNode) GF_EXPORT GF_Err gf_node_register(GF_Node *node, GF_Node *parentNode) { - GF_SceneGraph *pSG; if (!node) return GF_OK; - - pSG = node->sgprivate->scenegraph; - /*if this is a proto register to the parent graph, not the current*/ - if (pSG && (node == (GF_Node*)pSG->pOwningProto)) pSG = pSG->parent_scene; node->sgprivate->num_instances ++; /*parent may be NULL (top node and proto)*/ if (parentNode) { if (!node->sgprivate->parents) { - node->sgprivate->parents = (GF_ParentList*)malloc(sizeof(GF_ParentList)); + node->sgprivate->parents = (GF_ParentList*)gf_malloc(sizeof(GF_ParentList)); node->sgprivate->parents->next = NULL; node->sgprivate->parents->node = parentNode; } else { GF_ParentList *item, *nlist = node->sgprivate->parents; while (nlist->next) nlist = nlist->next; - item = (GF_ParentList*)malloc(sizeof(GF_ParentList)); + item = (GF_ParentList*)gf_malloc(sizeof(GF_ParentList)); item->next = NULL; item->node = parentNode; nlist->next = item; } - if (parentNode->sgprivate->scenegraph != pSG) { - gf_list_add(pSG->exported_nodes, node); + if (parentNode->sgprivate->scenegraph != node->sgprivate->scenegraph) { + gf_list_add(node->sgprivate->scenegraph->exported_nodes, node); } } return GF_OK; @@ -645,14 +726,14 @@ this doesn't propagate in the scene graph. If updateOrderedGroup and new_node is is updated*/ static void ReplaceDEFNode(GF_Node *FromNode, GF_Node *node, GF_Node *newNode, Bool updateOrderedGroup) { - u32 i, j; + u32 i, j, count; GF_Node *p; GF_ChildNodeItem *list; - GF_FieldInfo field; /*browse all fields*/ - for (i=0; i<gf_node_get_field_count(FromNode); i++) { + count = gf_node_get_field_count(FromNode); + for (i=0; i<count; i++) { gf_node_get_field(FromNode, i, &field); switch (field.fieldType) { case GF_SG_VRML_SFNODE: @@ -681,6 +762,7 @@ static void ReplaceDEFNode(GF_Node *FromNode, GF_Node *node, GF_Node *newNode, B list->node = newNode; } else { gf_node_list_del_child( (GF_ChildNodeItem **) field.far_ptr, list->node); +#ifndef GPAC_DISABLE_VRML if (updateOrderedGroup && (FromNode->sgprivate->tag==TAG_MPEG4_OrderedGroup)) { GF_FieldInfo info; M_OrderedGroup *og = (M_OrderedGroup *)FromNode; @@ -691,6 +773,7 @@ static void ReplaceDEFNode(GF_Node *FromNode, GF_Node *node, GF_Node *newNode, B gf_sg_vrml_mf_remove(&og->order, GF_SG_VRML_SFINT32, j); gf_node_changed_internal(FromNode, &info, 1); } +#endif } goto exit; } @@ -702,6 +785,21 @@ static void ReplaceDEFNode(GF_Node *FromNode, GF_Node *node, GF_Node *newNode, B } /*since we don't filter parent nodes this is called once per USE, not per container, so return if found*/ exit: + +#ifndef GPAC_DISABLE_VRML + /*Notify all scripts that the node is being removed from its parent - we have to do that because nodes used in scripts are not + always registered in MF/SFNodes fields of the script.*/ + switch (FromNode->sgprivate->tag) { + case TAG_MPEG4_Script: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Script: +#endif + if (FromNode->sgprivate->scenegraph->on_node_modified) + FromNode->sgprivate->scenegraph->on_node_modified(FromNode->sgprivate->scenegraph, node, NULL, FromNode); + break; + } +#endif + gf_node_changed(FromNode, &field); } @@ -740,7 +838,7 @@ static void ReplaceIRINode(GF_Node *FromNode, GF_Node *old_node, GF_Node *newNod } else { if (prev) prev->next = child->next; else ((SVG_Element *)FromNode)->children = child->next; - free(child); + gf_free(child); } break; } @@ -751,14 +849,17 @@ static void ReplaceIRINode(GF_Node *FromNode, GF_Node *old_node, GF_Node *newNod GF_Err gf_node_replace(GF_Node *node, GF_Node *new_node, Bool updateOrderedGroup) { u32 type; - Bool replace_root, replace_proto; +#ifndef GPAC_DISABLE_VRML + Bool replace_proto; +#endif + Bool replace_root; GF_Node *par; GF_SceneGraph *pSG = node->sgprivate->scenegraph; +#ifndef GPAC_DISABLE_VRML /*if this is a proto its is registered in its parent graph, not the current*/ if (node == (GF_Node*)pSG->pOwningProto) pSG = pSG->parent_scene; -// if (!SG_SearchForNodeIndex(pSG, node, &i)) return GF_BAD_PARAM; -// assert(node == pSG->node_registry[i]); +#endif type = (node->sgprivate->tag>GF_NODE_RANGE_LAST_VRML) ? 1 : 0; #ifndef GPAC_DISABLE_SVG @@ -769,11 +870,14 @@ GF_Err gf_node_replace(GF_Node *node, GF_Node *new_node, Bool updateOrderedGroup /*first check if this is the root node*/ replace_root = (node->sgprivate->scenegraph->RootNode == node) ? 1 : 0; + +#ifndef GPAC_DISABLE_VRML replace_proto = 0; if (node->sgprivate->scenegraph->pOwningProto && (gf_list_find(node->sgprivate->scenegraph->pOwningProto->node_code, node)>=0)) { replace_proto = 1; } +#endif while (node->sgprivate->parents) { Bool do_break = node->sgprivate->parents->next ? 0 : 1; @@ -797,13 +901,14 @@ GF_Err gf_node_replace(GF_Node *node, GF_Node *new_node, Bool updateOrderedGroup gf_node_unregister(node, NULL); pSG->RootNode = new_node; } +#ifndef GPAC_DISABLE_VRML if (replace_proto) { pSG = node->sgprivate->scenegraph; gf_list_del_item(pSG->pOwningProto->node_code, node); if (pSG->pOwningProto->RenderingNode==node) pSG->pOwningProto->RenderingNode = NULL; gf_node_unregister(node, NULL); } - +#endif return GF_OK; } @@ -811,10 +916,10 @@ static GFINLINE void insert_node_def(GF_SceneGraph *sg, GF_Node *def, u32 ID, co { NodeIDedItem *reg_node, *cur; - reg_node = (NodeIDedItem *) malloc(sizeof(NodeIDedItem)); + reg_node = (NodeIDedItem *) gf_malloc(sizeof(NodeIDedItem)); reg_node->node = def; reg_node->NodeID = ID; - reg_node->NodeName = name ? strdup(name) : NULL; + reg_node->NodeName = name ? gf_strdup(name) : NULL; if (!sg->id_node) { sg->id_node = reg_node; @@ -852,8 +957,10 @@ GF_Err gf_node_set_id(GF_Node *p, u32 ID, const char *name) if (!ID || !p || !p->sgprivate->scenegraph) return GF_BAD_PARAM; pSG = p->sgprivate->scenegraph; +#ifndef GPAC_DISABLE_VRML /*if this is a proto register to the parent graph, not the current*/ if (p == (GF_Node*)pSG->pOwningProto) pSG = pSG->parent_scene; +#endif /*new DEF ID*/ if (!(p->sgprivate->flags & GF_NODE_IS_DEF) ) { @@ -862,10 +969,10 @@ GF_Err gf_node_set_id(GF_Node *p, u32 ID, const char *name) } /*reassigning ID, remove node def*/ else { - char *_name = strdup(name); + char *_name = gf_strdup(name); remove_node_id(pSG, p); insert_node_def(pSG, p, ID, _name); - free(_name); + gf_free(_name); } return GF_OK; } @@ -877,8 +984,10 @@ GF_Err gf_node_remove_id(GF_Node *p) if (!p) return GF_BAD_PARAM; pSG = p->sgprivate->scenegraph; +#ifndef GPAC_DISABLE_VRML /*if this is a proto register to the parent graph, not the current*/ if (p == (GF_Node*)pSG->pOwningProto) pSG = pSG->parent_scene; +#endif /*new DEF ID*/ if (p->sgprivate->flags & GF_NODE_IS_DEF) { @@ -910,37 +1019,43 @@ void gf_node_traverse(GF_Node *node, void *renderStack) #endif return; } + +#ifndef GPAC_DISABLE_VRML if (node->sgprivate->tag != TAG_ProtoNode) return; - /*proto only traverses its first child*/ - if (((GF_ProtoInstance *) node)->RenderingNode) { - node = ((GF_ProtoInstance *) node)->RenderingNode; - /*if rendering node is a proto and not a hardcoded proto, traverse it*/ - if (!node->sgprivate->UserCallback && (node->sgprivate->tag == TAG_ProtoNode)) { - gf_node_traverse(node, renderStack); - return; - } - } /*if no rendering function is assigned this is a real proto (otherwise this is an hardcoded one)*/ - else if (!node->sgprivate->UserCallback) { - /*if no rendering node, check if the proto is fully instanciated (externProto)*/ - GF_ProtoInstance *proto_inst = (GF_ProtoInstance *) node; - gf_node_dirty_clear(node, 0); - /*proto has been deleted or dummy proto (without node code)*/ - if (!proto_inst->proto_interface || proto_inst->is_loaded) return; - /*try to load the code*/ - gf_sg_proto_instanciate(proto_inst); - - /*if user callback is set, this is an hardcoded proto. If not, locate the first traversable node*/ - if (!node->sgprivate->UserCallback) { - if (!proto_inst->RenderingNode) { - gf_node_dirty_set(node, 0, 1); + if (!node->sgprivate->UserCallback) { + + /*if a rendering node is assigned use it*/ + if (((GF_ProtoInstance *) node)->RenderingNode) { + node = ((GF_ProtoInstance *) node)->RenderingNode; + /*if rendering node is a proto and not a hardcoded proto, traverse it*/ + if (!node->sgprivate->UserCallback && (node->sgprivate->tag == TAG_ProtoNode)) { + gf_node_traverse(node, renderStack); return; } - /*signal we have been loaded*/ - node->sgprivate->scenegraph->NodeCallback(node->sgprivate->scenegraph->userpriv, GF_SG_CALLBACK_MODIFIED, node, NULL); + } + /*if no rendering node, check if the proto is fully instanciated (externProto)*/ + else { + GF_ProtoInstance *proto_inst = (GF_ProtoInstance *) node; + gf_node_dirty_clear(node, 0); + /*proto has been deleted or dummy proto (without node code)*/ + if (!proto_inst->proto_interface || (proto_inst->flags & GF_SG_PROTO_LOADED) ) return; + /*try to load the code*/ + gf_sg_proto_instanciate(proto_inst); + + /*if user callback is set, this is an hardcoded proto. If not, locate the first traversable node*/ + if (!node->sgprivate->UserCallback) { + if (!proto_inst->RenderingNode) { + gf_node_dirty_set(node, 0, 1); + return; + } + /*signal we have been loaded*/ + node->sgprivate->scenegraph->NodeCallback(node->sgprivate->scenegraph->userpriv, GF_SG_CALLBACK_MODIFIED, node, NULL); + } } } + if (node->sgprivate->UserCallback) { #ifdef GF_CYCLIC_TRAVERSE_ON if (node->sgprivate->flags & GF_NODE_IN_TRAVERSE) return; @@ -952,6 +1067,8 @@ void gf_node_traverse(GF_Node *node, void *renderStack) node->sgprivate->flags &= ~GF_NODE_IN_TRAVERSE; #endif } + +#endif /*GPAC_DISABLE_VRML*/ } GF_EXPORT @@ -962,6 +1079,24 @@ void gf_node_allow_cyclic_traverse(GF_Node *node) #endif } + +GF_EXPORT +Bool gf_node_set_cyclic_traverse_flag(GF_Node *node, Bool on) +{ + Bool ret = 1; +#ifdef GF_CYCLIC_TRAVERSE_ON + if (node) { + ret = (node->sgprivate->flags & GF_NODE_IN_TRAVERSE) ? 0 : 1; + if (on) { + node->sgprivate->flags |= GF_NODE_IN_TRAVERSE; + } else { + node->sgprivate->flags &= ~GF_NODE_IN_TRAVERSE; + } + } +#endif + return ret; +} + /*blindly calls RenderNode on all nodes in the "children" list*/ GF_EXPORT void gf_node_traverse_children(GF_Node *node, void *renderStack) @@ -1044,7 +1179,7 @@ void gf_node_setup(GF_Node *p, u32 tag) GF_Node *gf_sg_new_base_node() { - GF_Node *newnode = (GF_Node *)malloc(sizeof(GF_Node)); + GF_Node *newnode = (GF_Node *)gf_malloc(sizeof(GF_Node)); gf_node_setup(newnode, TAG_UndefinedNode); return newnode; } @@ -1062,8 +1197,10 @@ u32 gf_node_get_id(GF_Node*p) assert(p); if (!(p->sgprivate->flags & GF_NODE_IS_DEF)) return 0; sg = p->sgprivate->scenegraph; +#ifndef GPAC_DISABLE_VRML /*if this is a proto, look in parent graph*/ if (p == (GF_Node*)sg->pOwningProto) sg = sg->parent_scene; +#endif reg_node = sg->id_node; while (reg_node) { @@ -1081,8 +1218,10 @@ const char *gf_node_get_name(GF_Node*p) if (!p || !(p->sgprivate->flags & GF_NODE_IS_DEF)) return NULL; sg = p->sgprivate->scenegraph; +#ifndef GPAC_DISABLE_VRML /*if this is a proto, look in parent graph*/ if (p == (GF_Node*)sg->pOwningProto) sg = sg->parent_scene; +#endif reg_node = sg->id_node; while (reg_node) { @@ -1104,8 +1243,10 @@ const char *gf_node_get_name_and_id(GF_Node*p, u32 *id) } sg = p->sgprivate->scenegraph; +#ifndef GPAC_DISABLE_VRML /*if this is a proto, look in parent graph*/ if (p == (GF_Node*)sg->pOwningProto) sg = sg->parent_scene; +#endif reg_node = sg->id_node; while (reg_node) { @@ -1153,7 +1294,7 @@ void gf_node_unregister_children(GF_Node *container, GF_ChildNodeItem *child) gf_node_unregister(child->node, container); cur = child; child = child->next; - free(cur); + gf_free(cur); } } @@ -1167,7 +1308,7 @@ GF_Err gf_node_list_insert_child(GF_ChildNodeItem **list, GF_Node *n, u32 pos) child = *list; - cur = (GF_ChildNodeItem*) malloc(sizeof(GF_ChildNodeItem)); + cur = (GF_ChildNodeItem*) gf_malloc(sizeof(GF_ChildNodeItem)); if (!cur) return GF_OUT_OF_MEM; cur->node = n; cur->next = NULL; @@ -1221,7 +1362,7 @@ GF_Err gf_node_list_add_child(GF_ChildNodeItem **list, GF_Node *n) child = *list; - cur = (GF_ChildNodeItem*) malloc(sizeof(GF_ChildNodeItem)); + cur = (GF_ChildNodeItem*) gf_malloc(sizeof(GF_ChildNodeItem)); if (!cur) return GF_OUT_OF_MEM; cur->node = n; cur->next = NULL; @@ -1242,7 +1383,7 @@ GF_Err gf_node_list_add_child_last(GF_ChildNodeItem **list, GF_Node *n, GF_Child child = *list; - cur = (GF_ChildNodeItem*) malloc(sizeof(GF_ChildNodeItem)); + cur = (GF_ChildNodeItem*) gf_malloc(sizeof(GF_ChildNodeItem)); if (!cur) return GF_OUT_OF_MEM; cur->node = n; cur->next = NULL; @@ -1273,7 +1414,7 @@ Bool gf_node_list_del_child(GF_ChildNodeItem **list, GF_Node *n) if (!child) return 0; if (child->node==n) { *list = child->next; - free(child); + gf_free(child); return 1; } @@ -1284,7 +1425,7 @@ Bool gf_node_list_del_child(GF_ChildNodeItem **list, GF_Node *n) } cur = child->next; child->next = cur->next; - free(cur); + gf_free(cur); return 1; } return 0; @@ -1302,7 +1443,7 @@ GF_Node *gf_node_list_del_child_idx(GF_ChildNodeItem **list, u32 pos) if (!pos) { *list = child->next; ret = child->node; - free(child); + gf_free(child); return ret; } @@ -1315,7 +1456,7 @@ GF_Node *gf_node_list_del_child_idx(GF_ChildNodeItem **list, u32 pos) cur = child->next; child->next = cur->next; ret = cur->node; - free(cur); + gf_free(cur); return ret; } return NULL; @@ -1356,17 +1497,25 @@ void gf_node_free(GF_Node *node) gf_dom_listener_del(n, node->sgprivate->interact->dom_evt); } gf_list_del(node->sgprivate->interact->dom_evt->evt_list); - free(node->sgprivate->interact->dom_evt); + gf_free(node->sgprivate->interact->dom_evt); } if (node->sgprivate->interact->animations) { gf_list_del(node->sgprivate->interact->animations); } #endif - free(node->sgprivate->interact); +#ifdef GPAC_HAS_SPIDERMONKEY + if (node->sgprivate->interact->js_binding) { + if (node->sgprivate->scenegraph->on_node_modified) + node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, NULL, NULL); + gf_list_del(node->sgprivate->interact->js_binding->fields); + gf_free(node->sgprivate->interact->js_binding); + } +#endif + gf_free(node->sgprivate->interact); } assert(! node->sgprivate->parents); - free(node->sgprivate); - free(node); + gf_free(node->sgprivate); + gf_free(node); } GF_EXPORT @@ -1385,35 +1534,37 @@ GF_Node *gf_node_get_parent(GF_Node *node, u32 idx) GF_ParentList *nlist = node->sgprivate->parents; /*break cyclic graphs*/ if (node->sgprivate->scenegraph->RootNode==node) return NULL; +#ifndef GPAC_DISABLE_VRML if (node->sgprivate->scenegraph->pOwningProto && node->sgprivate->scenegraph->pOwningProto->RenderingNode==node) return NULL; +#endif if (!nlist) return NULL; while (idx) { nlist = nlist->next; idx--;} return nlist ? nlist->node : NULL; } -static GFINLINE void dirty_children(GF_Node *node, u32 val) +static void dirty_children(GF_Node *node) { u32 i, count; GF_FieldInfo info; if (!node) return; - node->sgprivate->flags |= val; + node->sgprivate->flags &= GF_NODE_INTERNAL_FLAGS; if (node->sgprivate->tag>=GF_NODE_RANGE_LAST_VRML) { GF_ChildNodeItem *child = ((GF_ParentNode*)node)->children; while (child) { - dirty_children(child->node, val); + dirty_children(child->node); child = child->next; } } else { count = gf_node_get_field_count(node); for (i=0; i<count; i++) { gf_node_get_field(node, i, &info); - if (info.fieldType==GF_SG_VRML_SFNODE) dirty_children(*(GF_Node **)info.far_ptr, val); + if (info.fieldType==GF_SG_VRML_SFNODE) dirty_children(*(GF_Node **)info.far_ptr); else if (info.fieldType==GF_SG_VRML_MFNODE) { GF_ChildNodeItem *list = *(GF_ChildNodeItem **) info.far_ptr; while (list) { - dirty_children(list->node, val); + dirty_children(list->node); list = list->next; } } @@ -1423,7 +1574,11 @@ static GFINLINE void dirty_children(GF_Node *node, u32 val) static void dirty_parents(GF_Node *node) { Bool check_root = 1; - GF_ParentList *nlist = node->sgprivate->parents; + GF_ParentList *nlist; + + if (!node) return; + + nlist = node->sgprivate->parents; while (nlist) { GF_Node *p = nlist->node; if (! (p->sgprivate->flags & GF_SG_CHILD_DIRTY)) { @@ -1439,11 +1594,21 @@ static void dirty_parents(GF_Node *node) if (node->sgprivate->scenegraph->NodeCallback && (node==node->sgprivate->scenegraph->RootNode) ) { node->sgprivate->scenegraph->NodeCallback(node->sgprivate->scenegraph->userpriv, GF_SG_CALLBACK_GRAPH_DIRTY, NULL, NULL); } +#ifndef GPAC_DISABLE_VRML /*or if parent graph is a protoinstance but the node is not this proto*/ else if (node->sgprivate->scenegraph->pOwningProto) { GF_Node *the_node = (GF_Node *) node->sgprivate->scenegraph->pOwningProto; if (the_node != node) dirty_parents(the_node); } +#endif + } +} +GF_EXPORT +void gf_node_dirty_parent_graph(GF_Node *node) +{ + /*if root node of the scenegraph*/ + if (node->sgprivate->scenegraph->NodeCallback ) { + node->sgprivate->scenegraph->NodeCallback(node->sgprivate->scenegraph->userpriv, GF_SG_CALLBACK_GRAPH_DIRTY, NULL, NULL); } } @@ -1486,7 +1651,7 @@ void gf_node_dirty_reset(GF_Node *node) if (!node) return; if (node->sgprivate->flags & ~GF_NODE_INTERNAL_FLAGS) { node->sgprivate->flags &= GF_NODE_INTERNAL_FLAGS; - dirty_children(node, 0); + dirty_children(node); } } @@ -1501,12 +1666,16 @@ void gf_node_init(GF_Node *node) if (!pSG->NodeCallback) return; /*internal nodes*/ +#ifndef GPAC_DISABLE_VRML if (gf_sg_vrml_node_init(node)) return; +#endif + #ifndef GPAC_DISABLE_SVG - else if (gf_svg_node_init(node)) return; + if (gf_svg_node_init(node)) return; #endif + /*user defined init*/ - else pSG->NodeCallback(pSG->userpriv, GF_SG_CALLBACK_INIT, node, NULL); + pSG->NodeCallback(pSG->userpriv, GF_SG_CALLBACK_INIT, node, NULL); } @@ -1518,14 +1687,33 @@ void gf_node_changed_internal(GF_Node *node, GF_FieldInfo *field, Bool notify_sc sg = node->sgprivate->scenegraph; assert(sg); +#ifndef GPAC_DISABLE_VRML /*signal changes in node to JS for MFFields*/ - if (field && notify_scripts && (node->sgprivate->flags & GF_NODE_HAS_BINDING) && !gf_sg_vrml_is_sf_field(field->fieldType) ) - sg->on_node_modified(sg, node, field); + if (field && notify_scripts && (node->sgprivate->flags & GF_NODE_HAS_BINDING) && !gf_sg_vrml_is_sf_field(field->fieldType) ) { + sg->on_node_modified(sg, node, field, NULL); + } +#endif + +#ifndef GPAC_DISABLE_SVG + if (field && node->sgprivate->interact && node->sgprivate->interact->dom_evt) { + GF_DOM_Event evt; + memset(&evt, 0, sizeof(GF_DOM_Event)); + evt.bubbles = 1; + evt.type = GF_EVENT_ATTR_MODIFIED; + evt.attr = field; + evt.detail = field->fieldIndex; + gf_dom_event_fire(node, &evt); + } +#endif + /*internal nodes*/ +#ifndef GPAC_DISABLE_VRML if (gf_sg_vrml_node_changed(node, field)) return; +#endif + #ifndef GPAC_DISABLE_SVG - else if (gf_svg_node_changed(node, field)) return; + if (gf_svg_node_changed(node, field)) return; #endif /*force child dirty tag*/ @@ -1543,7 +1731,7 @@ void gf_node_changed(GF_Node *node, GF_FieldInfo *field) #ifndef GPAC_DISABLE_SVG /* we should avoid dispatching a DOMSubtreeModified event on insertion of time values in begin/end fields because this retriggers begin/end events and reinsertion */ - if (field == NULL && + if ((field == NULL || ((field->fieldIndex != TAG_SVG_ATT_begin) && (field->fieldIndex != TAG_SVG_ATT_end))) && node->sgprivate->tag >= GF_NODE_RANGE_FIRST_SVG && node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG) { GF_DOM_Event evt; evt.type = GF_EVENT_TREE_MODIFIED; @@ -1559,14 +1747,14 @@ void gf_node_del(GF_Node *node) if (node->sgprivate->tag==TAG_UndefinedNode) gf_node_free(node); else if (node->sgprivate->tag==TAG_DOMText) { GF_DOMText *t = (GF_DOMText *)node; - if (t->textContent) free(t->textContent); + if (t->textContent) gf_free(t->textContent); gf_sg_parent_reset(node); gf_node_free(node); } else if (node->sgprivate->tag==TAG_DOMUpdates) { u32 i, count; GF_DOMUpdates *up = (GF_DOMUpdates *)node; - if (up->data) free(up->data); + if (up->data) gf_free(up->data); count = gf_list_count(up->updates); for (i=0; i<count; i++) { GF_Command *com = gf_list_get(up->updates, i); @@ -1581,13 +1769,20 @@ void gf_node_del(GF_Node *node) #ifndef GPAC_DISABLE_SVG gf_node_delete_attributes(node); #endif - if (n->name) free(n->name); + if (n->name) gf_free(n->name); gf_sg_parent_reset(node); gf_node_free(node); } +#ifndef GPAC_DISABLE_VRML else if (node->sgprivate->tag == TAG_ProtoNode) gf_sg_proto_del_instance((GF_ProtoInstance *)node); +#endif +#ifndef GPAC_DISABLE_VRML else if (node->sgprivate->tag<=GF_NODE_RANGE_LAST_MPEG4) gf_sg_mpeg4_node_del(node); +#ifndef GPAC_DISABLE_X3D else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) gf_sg_x3d_node_del(node); +#endif +#endif /*GPAC_DISABLE_VRML*/ + #ifndef GPAC_DISABLE_SVG else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_SVG) gf_svg_node_del(node); #endif @@ -1599,8 +1794,10 @@ u32 gf_node_get_field_count(GF_Node *node) { assert(node); if (node->sgprivate->tag <= TAG_UndefinedNode) return 0; +#ifndef GPAC_DISABLE_VRML /*for both MPEG4 & X3D*/ else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_node_get_num_fields_in_mode(node, GF_SG_FIELD_CODING_ALL); +#endif #ifndef GPAC_DISABLE_SVG else if (node->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) return gf_node_get_attribute_count(node); #endif @@ -1612,10 +1809,14 @@ const char *gf_node_get_class_name(GF_Node *node) { assert(node && node->sgprivate->tag); if (node->sgprivate->tag==TAG_UndefinedNode) return "UndefinedNode"; +#ifndef GPAC_DISABLE_VRML else if (node->sgprivate->tag==TAG_ProtoNode) return ((GF_ProtoInstance*)node)->proto_name; else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) return gf_sg_mpeg4_node_get_class_name(node->sgprivate->tag); +#ifndef GPAC_DISABLE_X3D else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_sg_x3d_node_get_class_name(node->sgprivate->tag); - else if (node->sgprivate->tag==TAG_DOMText) return ""; +#endif +#endif + else if (node->sgprivate->tag==TAG_DOMText) return "DOMText"; else if (node->sgprivate->tag==TAG_DOMFullNode) { char *xmlns; GF_DOMFullNode*full = (GF_DOMFullNode*)node; @@ -1638,11 +1839,16 @@ u32 gf_sg_node_get_tag_by_class_name(const char *name, u32 ns) u32 tag; /* TODO: handle name spaces */ +#ifndef GPAC_DISABLE_VRML tag = gf_node_mpeg4_type_by_class_name(name); if (tag) return tag; +#ifndef GPAC_DISABLE_X3D tag = gf_node_x3d_type_by_class_name(name); if (tag) return tag; +#endif + +#endif #ifndef GPAC_DISABLE_SVG tag = gf_xml_get_element_tag(name, ns); @@ -1660,8 +1866,12 @@ GF_Node *gf_node_new(GF_SceneGraph *inScene, u32 tag) /*cannot create proto this way*/ if (tag==TAG_ProtoNode) return NULL; else if (tag==TAG_UndefinedNode) node = gf_sg_new_base_node(); +#ifndef GPAC_DISABLE_VRML else if (tag <= GF_NODE_RANGE_LAST_MPEG4) node = gf_sg_mpeg4_node_new(tag); +#ifndef GPAC_DISABLE_X3D else if (tag <= GF_NODE_RANGE_LAST_X3D) node = gf_sg_x3d_node_new(tag); +#endif +#endif else if (tag == TAG_DOMText) { GF_DOMText *n; GF_SAFEALLOC(n, GF_DOMText); @@ -1681,8 +1891,19 @@ GF_Node *gf_node_new(GF_SceneGraph *inScene, u32 tag) else node = NULL; if (node) node->sgprivate->scenegraph = inScene; + /*script is inited as soon as created since fields are dynamically added*/ - if ((tag==TAG_MPEG4_Script) || (tag==TAG_X3D_Script) ) gf_sg_script_init(node); +#ifndef GPAC_DISABLE_VRML + switch (tag) { + case TAG_MPEG4_Script: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Script: +#endif + gf_sg_script_init(node); + break; + } +#endif + return node; } @@ -1696,11 +1917,19 @@ GF_Err gf_node_get_field(GF_Node *node, u32 FieldIndex, GF_FieldInfo *info) info->fieldIndex = FieldIndex; if (node->sgprivate->tag==TAG_UndefinedNode) return GF_BAD_PARAM; +#ifndef GPAC_DISABLE_VRML else if (node->sgprivate->tag == TAG_ProtoNode) return gf_sg_proto_get_field(NULL, node, info); - else if ((node->sgprivate->tag == TAG_MPEG4_Script) || (node->sgprivate->tag == TAG_X3D_Script) ) + else if ((node->sgprivate->tag == TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (node->sgprivate->tag == TAG_X3D_Script) +#endif + ) return gf_sg_script_get_field(node, info); else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) return gf_sg_mpeg4_node_get_field(node, info); +#ifndef GPAC_DISABLE_X3D else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_sg_x3d_node_get_field(node, info); +#endif +#endif /*GPAC_DISABLE_VRML*/ #ifndef GPAC_DISABLE_SVG else if (node->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) return gf_node_get_attribute_info(node, info); @@ -1731,14 +1960,23 @@ GF_Err gf_node_get_field_by_name(GF_Node *node, char *name, GF_FieldInfo *field) s32 res = -1; if (node->sgprivate->tag==TAG_UndefinedNode) return GF_BAD_PARAM; +#ifndef GPAC_DISABLE_VRML else if (node->sgprivate->tag == TAG_ProtoNode) { res = gf_sg_proto_get_field_index_by_name(NULL, node, name); } - else if ((node->sgprivate->tag == TAG_MPEG4_Script) || (node->sgprivate->tag == TAG_X3D_Script) ) { + else if ((node->sgprivate->tag == TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (node->sgprivate->tag == TAG_X3D_Script) +#endif + ) { return gf_node_get_field_by_name_enum(node, name, field); } else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) res = gf_sg_mpeg4_node_get_field_index_by_name(node, name); +#ifndef GPAC_DISABLE_X3D else if (node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) res = gf_sg_x3d_node_get_field_index_by_name(node, name); +#endif +#endif /*GPAC_DISABLE_VRML*/ + #ifndef GPAC_DISABLE_SVG else if (node->sgprivate->tag >= GF_NODE_FIRST_DOM_NODE_TAG) return gf_node_get_attribute_by_name(node, name, 0, 1, 0, field); #endif @@ -1847,8 +2085,10 @@ GF_Node *gf_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *cloned_pa { if (!orig) return NULL; if (orig->sgprivate->tag < GF_NODE_RANGE_LAST_VRML) { +#ifndef GPAC_DISABLE_VRML /*deep clone is always true for VRML*/ return gf_vrml_node_clone(inScene, orig, cloned_parent, id); +#endif } else if (orig->sgprivate->tag == TAG_DOMUpdates) { /*TODO*/ return NULL; @@ -1860,6 +2100,17 @@ GF_Node *gf_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *cloned_pa return NULL; } +u32 gf_xml_get_namespace_id(char *name) +{ + if (!strcmp(name, "http://www.w3.org/XML/1998/namespace")) return GF_XMLNS_XML; + else if (!strcmp(name, "http://www.w3.org/2001/xml-events")) return GF_XMLNS_XMLEV; + else if (!strcmp(name, "http://www.w3.org/1999/xlink")) return GF_XMLNS_XLINK; + else if (!strcmp(name, "http://www.w3.org/2000/svg")) return GF_XMLNS_SVG; + else if (!strcmp(name, "urn:mpeg:mpeg4:laser:2005")) return GF_XMLNS_LASER; + else if (!strcmp(name, "http://www.w3.org/ns/xbl")) return GF_XMLNS_XBL; + else if (!strcmp(name, "http://gpac.sourceforge.net/svg-extensions")) return GF_XMLNS_SVG_GPAC_EXTENSION; + return GF_XMLNS_UNDEFINED; +} GF_Err gf_sg_add_namespace(GF_SceneGraph *sg, char *name, char *qname) { @@ -1867,27 +2118,22 @@ GF_Err gf_sg_add_namespace(GF_SceneGraph *sg, char *name, char *qname) GF_XMLNS *ns; if (!name) return GF_BAD_PARAM; - id = GF_XMLNS_NONE; - if (!strcmp(name, "http://www.w3.org/XML/1998/namespace")) id = GF_XMLNS_XML; - else if (!strcmp(name, "http://www.w3.org/2001/xml-events")) id = GF_XMLNS_XMLEV; - else if (!strcmp(name, "http://www.w3.org/1999/xlink")) id = GF_XMLNS_XLINK; - else if (!strcmp(name, "http://www.w3.org/2000/svg")) id = GF_XMLNS_SVG; - else if (!strcmp(name, "urn:mpeg:mpeg4:laser:2005")) id = GF_XMLNS_LASER; - else if (!strcmp(name, "http://www.w3.org/ns/xbl")) id = GF_XMLNS_XBL; + id = gf_xml_get_namespace_id(name); if (!sg->ns) sg->ns = gf_list_new(); GF_SAFEALLOC(ns, GF_XMLNS); ns->xmlns_id = id ? id : gf_crc_32(name, strlen(name)); - ns->name = strdup(name); + ns->name = gf_strdup(name); - ns->qname = qname ? strdup(qname) : NULL; + ns->qname = qname ? gf_strdup(qname) : NULL; return gf_list_insert(sg->ns, ns, 0); } GF_Err gf_sg_remove_namespace(GF_SceneGraph *sg, char *ns_name, char *q_name) { u32 i, count; + if (!ns_name) return GF_OK; count = sg->ns ? gf_list_count(sg->ns) : 0; for (i=0; i<count; i++) { Bool ok=0; @@ -1899,9 +2145,9 @@ GF_Err gf_sg_remove_namespace(GF_SceneGraph *sg, char *ns_name, char *q_name) if (ok && ns->name && !strcmp(ns->name, ns_name)) { gf_list_rem(sg->ns, i); - free(ns->name); - if (ns->qname) free(ns->qname); - free(ns); + gf_free(ns->name); + if (ns->qname) gf_free(ns->qname); + gf_free(ns); return GF_OK; } } @@ -1925,7 +2171,7 @@ u32 gf_sg_get_namespace_code(GF_SceneGraph *sg, char *qname) if (!strcmp(qname, "xml")) return GF_XMLNS_XML; /*we could also add the basic namespaces in case this has been forgotten ?*/ } - return GF_XMLNS_NONE; + return GF_XMLNS_UNDEFINED; } u32 gf_sg_get_namespace_code_from_name(GF_SceneGraph *sg, char *name) @@ -1940,7 +2186,7 @@ u32 gf_sg_get_namespace_code_from_name(GF_SceneGraph *sg, char *name) if (!ns->name && !name) return ns->xmlns_id; } - return GF_XMLNS_NONE; + return GF_XMLNS_UNDEFINED; } const char *gf_sg_get_namespace_qname(GF_SceneGraph *sg, u32 xmlns_id) @@ -1972,3 +2218,86 @@ const char *gf_sg_get_namespace(GF_SceneGraph *sg, u32 xmlns_id) } +char *gf_node_dump_attribute(GF_Node *n, GF_FieldInfo *info) +{ +#ifndef GPAC_DISABLE_SVG + if (gf_node_get_tag(n) >= GF_NODE_FIRST_DOM_NODE_TAG) { + return gf_svg_dump_attribute(n, info); + } +#endif + +#ifndef GPAC_DISABLE_VRML + return gf_node_vrml_dump_attribute(n, info); +#else + return NULL; +#endif +} + + +/*this is not a NodeReplace, thus only the given container is updated - pos is 0-based*/ +GF_Err gf_node_replace_child(GF_Node *node, GF_ChildNodeItem **container, s32 pos, GF_Node *newNode) +{ + GF_ChildNodeItem *child, *prev; + u32 tag; + u32 cur_pos = 0; + + child = *container; + prev = NULL; + while (child->next) { + if ((pos<0) || (cur_pos!=(u32)pos)) { + prev = child; + child = child->next; + cur_pos++; + continue; + } + break; + } + tag = child->node->sgprivate->tag; + gf_node_unregister(child->node, node); + if (newNode) { + child->node = newNode; +#ifndef GPAC_DISABLE_VRML + if (tag==TAG_MPEG4_ColorTransform) + node->sgprivate->flags |= GF_SG_VRML_COLOR_DIRTY; +#endif + } else { + if (prev) prev->next = child->next; + else *container = child->next; + gf_free(child); + } + return GF_OK; +} + + +GF_EXPORT +Bool gf_node_parent_of(GF_Node *node, GF_Node *target) +{ + u32 i, count; + GF_FieldInfo info; + if (!node) return 0; + if (node==target) return 1; + + if (node->sgprivate->tag>=GF_NODE_RANGE_LAST_VRML) { + GF_ChildNodeItem *child = ((GF_ParentNode*)node)->children; + while (child) { + if (gf_node_parent_of(child->node, target)) return 1; + child = child->next; + } + } else { + count = gf_node_get_field_count(node); + for (i=0; i<count; i++) { + gf_node_get_field(node, i, &info); + if (info.fieldType==GF_SG_VRML_SFNODE) { + if (gf_node_parent_of(*(GF_Node **)info.far_ptr, target)) return 1; + } + else if (info.fieldType==GF_SG_VRML_MFNODE) { + GF_ChildNodeItem *list = *(GF_ChildNodeItem **) info.far_ptr; + while (list) { + if (gf_node_parent_of(list->node, target)) return 1; + list = list->next; + } + } + } + } + return 0; +} diff --git a/src/scenegraph/commands.c b/src/scenegraph/commands.c index 6c03231..d244c57 100644 --- a/src/scenegraph/commands.c +++ b/src/scenegraph/commands.c @@ -40,46 +40,25 @@ GF_Command *gf_sg_command_new(GF_SceneGraph *graph, u32 tag) if (tag < GF_SG_LAST_BIFS_COMMAND) ptr->new_proto_list = gf_list_new(); return ptr; } -static void SG_CheckNodeUnregister(GF_Command *com) -{ - NodeIDedItem *reg_node; - switch (com->tag) { - case GF_SG_SCENE_REPLACE: - case GF_SG_LSR_NEW_SCENE: - case GF_SG_LSR_REFRESH_SCENE: - gf_node_unregister(com->node, NULL); - break; - default: - /*check if node is in registry - do NOT check the node's internals, because it may have been destroyed - when cyclic references are found (only happens with conditional replacing self/other conditional buffer) - note that we're sure the node has an ID since this is not a replace scene*/ - reg_node = com->in_scene->id_node; - while (reg_node) { - if (reg_node->node == com->node) { - gf_node_unregister(com->node, NULL); - return; - } - reg_node = reg_node->next; - } - break; - } -} GF_EXPORT void gf_sg_command_del(GF_Command *com) { +#ifndef GPAC_DISABLE_VRML u32 i; GF_Proto *proto; +#endif if (!com) return; if (com->tag < GF_SG_LAST_BIFS_COMMAND) { +#ifndef GPAC_DISABLE_VRML while (gf_list_count(com->command_fields)) { GF_CommandField *inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); gf_list_rem(com->command_fields, 0); switch (inf->fieldType) { case GF_SG_VRML_SFNODE: - if (inf->new_node) gf_node_unregister(inf->new_node, com->node); + if (inf->new_node) gf_node_try_destroy(com->in_scene, inf->new_node, NULL); break; case GF_SG_VRML_MFNODE: if (inf->field_ptr) { @@ -87,9 +66,9 @@ void gf_sg_command_del(GF_Command *com) child = inf->node_list; while (child) { cur = child; - gf_node_unregister(child->node, com->node); + gf_node_try_destroy(com->in_scene, child->node, NULL); child = child->next; - free(cur); + gf_free(cur); } } break; @@ -97,54 +76,68 @@ void gf_sg_command_del(GF_Command *com) if (inf->field_ptr) gf_sg_vrml_field_pointer_del(inf->field_ptr, inf->fieldType); break; } - free(inf); + gf_free(inf); } +#endif } else { #ifndef GPAC_DISABLE_SVG while (gf_list_count(com->command_fields)) { GF_CommandField *inf = (GF_CommandField *)gf_list_get(com->command_fields, 0); gf_list_rem(com->command_fields, 0); - if (inf->new_node) gf_node_unregister(inf->new_node, com->node); + if (inf->new_node) gf_node_unregister(inf->new_node, NULL); else if (inf->node_list) { - gf_node_unregister_children(com->node, inf->node_list); + GF_ChildNodeItem *cur, *child; + child = inf->node_list; + while (child) { + cur = child; + gf_node_try_destroy(com->in_scene, child->node, NULL); + child = child->next; + gf_free(cur); + } } else if (inf->field_ptr) { gf_svg_delete_attribute_value(inf->fieldType, inf->field_ptr, com->in_scene); } - free(inf); + gf_free(inf); } #endif } gf_list_del(com->command_fields); +#ifndef GPAC_DISABLE_VRML i=0; while ((proto = (GF_Proto*)gf_list_enum(com->new_proto_list, &i))) { gf_sg_proto_del(proto); } gf_list_del(com->new_proto_list); +#endif if (com->node) { - if (!com->in_scene) gf_node_unregister(com->node, NULL); - else SG_CheckNodeUnregister(com); + gf_node_try_destroy(com->in_scene, com->node, NULL); } - if (com->del_proto_list) free(com->del_proto_list); - if (com->def_name) free(com->def_name); + if (com->del_proto_list) gf_free(com->del_proto_list); + if (com->def_name) gf_free(com->def_name); if (com->scripts_to_load) gf_list_del(com->scripts_to_load); - free(com); + if (com->unres_name) gf_free(com->unres_name); + gf_free(com); } static void SG_CheckFieldChange(GF_Node *node, GF_FieldInfo *field) { /*and propagate eventIn if any*/ if (field->on_event_in) { - field->on_event_in(node); - } else if ((field->eventType==GF_SG_EVENT_IN) && (gf_node_get_tag(node) == TAG_MPEG4_Script)) { + field->on_event_in(node, NULL); + } +#ifndef GPAC_DISABLE_VRML + else if ((field->eventType==GF_SG_EVENT_IN) && (gf_node_get_tag(node) == TAG_MPEG4_Script)) { gf_sg_script_event_in(node, field); - } else { + } + else { /*Notify eventOut in all cases to handle protos*/ gf_node_event_out(node, field->fieldIndex); } +#endif /*signal node modif*/ gf_node_changed(node, field); } @@ -157,7 +150,7 @@ static void gf_node_unregister_children_deactivate(GF_Node *container, GF_ChildN gf_node_deactivate(child->node); cur = child; child = child->next; - free(cur); + gf_free(cur); } } @@ -167,14 +160,20 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of { GF_Err e; GF_CommandField *inf; +#ifndef GPAC_DISABLE_VRML GF_FieldInfo field; - GF_Node *def, *node; void *slot_ptr; + GF_Node *def; +#endif + GF_Node *node; if (!com || !graph) return GF_BAD_PARAM; + if (com->never_apply) return GF_OK; + e = GF_OK; switch (com->tag) { +#ifndef GPAC_DISABLE_VRML case GF_SG_SCENE_REPLACE: /*unregister root*/ gf_node_unregister(graph->RootNode, NULL); @@ -199,6 +198,9 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of /*DO NOT TOUCH node registry*/ /*DO NOT TOUCH UNREGISTERED PROTOS*/ + /*if no protos (previously aggregated command) create proto list*/ + if (!graph->protos) graph->protos = gf_list_new(); + /*move all protos in graph*/ while (gf_list_count(com->new_proto_list)) { GF_Proto *p = (GF_Proto*)gf_list_get(com->new_proto_list, 0); @@ -218,42 +220,6 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of if (inf->new_node) gf_node_register(inf->new_node, NULL); break; - case GF_SG_FIELD_REPLACE_OP: - { - void *src_ptr; - u32 src_type; - u32 j=0; - GF_FieldInfo src; - def = gf_sg_find_node(com->in_scene, com->fromNodeID); - if (!def) return GF_SG_UNKNOWN_NODE; - e = gf_node_get_field(def, com->fromFieldIndex, &src); - if (e) return e; - - src_type = src.fieldType; - src_ptr = src.far_ptr; - if (com->send_event_x>=0) { - src_type = gf_sg_vrml_get_sf_type(src.fieldType); - e = gf_sg_vrml_mf_get_item(src.far_ptr, src.fieldType, &src_ptr, com->send_event_x); - if (e) return e; - } - - while ((inf = (GF_CommandField*)gf_list_enum(com->command_fields, &j))) { - e = gf_node_get_field(com->node, inf->fieldIndex, &field); - if (e) return e; - if (inf->pos>=0) { - void *slot_ptr; - e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & slot_ptr, inf->pos); - if (e) return e; - gf_sg_vrml_field_copy(slot_ptr, src_ptr, src_type); - } else { - gf_sg_vrml_field_copy(field.far_ptr, src_ptr, src_type); - } - } - - SG_CheckFieldChange(com->node, &field); - } - break; - case GF_SG_MULTIPLE_REPLACE: case GF_SG_FIELD_REPLACE: { @@ -280,7 +246,7 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of list = * ((GF_ChildNodeItem **) inf->field_ptr); prev=NULL; while (list) { - cur = malloc(sizeof(GF_ChildNodeItem)); + cur = gf_malloc(sizeof(GF_ChildNodeItem)); cur->next = NULL; cur->node = list->node; if (prev) { @@ -301,13 +267,15 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of SFCommandBuffer *cb_src = (SFCommandBuffer *)inf->field_ptr; /*reset dest*/ + if (!cb_dst->commandList) cb_dst->commandList = gf_list_new(); + while (gf_list_count(cb_dst->commandList)) { GF_Command *sub_com = (GF_Command *)gf_list_get(cb_dst->commandList, 0); gf_sg_command_del(sub_com); gf_list_rem(cb_dst->commandList, 0); } if (cb_dst->buffer) { - free(cb_dst->buffer); + gf_free(cb_dst->buffer); cb_dst->buffer = NULL; } @@ -316,7 +284,7 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of count = gf_list_count(cb_src->commandList); for (i=0; i<count;i++) { GF_Command *sub_com = (GF_Command *)gf_list_get(cb_src->commandList, i); - GF_Command *new_com = gf_sg_command_clone(sub_com, sg, 0); + GF_Command *new_com = gf_sg_vrml_command_clone(sub_com, sg, 0); gf_list_add(cb_dst->commandList, new_com); } } @@ -393,7 +361,7 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of gf_sg_route_set_id(r, com->RouteID); if (name) { gf_sg_route_set_name(r, name); - free(name); + gf_free(name); } break; } @@ -423,7 +391,7 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of if ((inf->pos < 0) || ((u32) inf->pos >= ((GenMFField *) field.far_ptr)->count) ) { inf->pos = ((GenMFField *)field.far_ptr)->count - 1; } - /*this is a regular MFField, just remove the item (realloc)*/ + /*this is a regular MFField, just remove the item (gf_realloc)*/ e = gf_sg_vrml_mf_remove(field.far_ptr, field.fieldType, inf->pos); } /*deletion -> node has changed*/ @@ -451,7 +419,7 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of if (com->RouteID) gf_sg_route_set_id(r, com->RouteID); if (com->def_name) { gf_sg_route_set_name(r, com->def_name); - free(com->def_name); + gf_free(com->def_name); com->def_name = NULL; } break; @@ -517,10 +485,142 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of } /*DO NOT TOUCH UNREGISTERED PROTOS*/ return GF_OK; + case GF_SG_XREPLACE: + { + s32 pos = -2; + GF_Node *target = NULL; + GF_ChildNodeItem *list, *cur, *prev; + GF_FieldInfo value; + inf = (GF_CommandField*)gf_list_get(com->command_fields, 0); + if (!inf) return GF_SG_UNKNOWN_NODE; + + e = gf_node_get_field(com->node, inf->fieldIndex, &field); + if (e) return e; + target = com->node; + + if (!gf_sg_vrml_is_sf_field(field.fieldType)) { + GF_FieldInfo idxField; + if ((inf->pos != -2) || com->toNodeID) { + if (com->toNodeID) { + GF_Node *idxNode = gf_sg_find_node(graph, com->toNodeID); + if (!idxNode) return GF_SG_UNKNOWN_NODE; + + if (gf_node_get_field(idxNode, com->toFieldIndex, &idxField) != GF_OK) return GF_OK; + pos = 0; + switch (idxField.fieldType) { + case GF_SG_VRML_SFBOOL: + if (*(SFBool*)idxField.far_ptr) pos = 1; + break; + case GF_SG_VRML_SFINT32: + if (*(SFInt32*)idxField.far_ptr >=0) pos = *(SFInt32*)idxField.far_ptr; + break; + case GF_SG_VRML_SFFLOAT: + if ( (*(SFFloat *)idxField.far_ptr) >=0) pos = (s32) floor( FIX2FLT(*(SFFloat*)idxField.far_ptr) ); + break; + case GF_SG_VRML_SFTIME: + if ( (*(SFTime *)idxField.far_ptr) >=0) pos = (s32) floor( (*(SFTime *)idxField.far_ptr) ); + break; + } + } else { + pos = inf->pos; + } + } + } + /*override target node*/ + if ((field.fieldType==GF_SG_VRML_MFNODE) && (pos>=-1) && com->ChildNodeTag) { + target = gf_node_list_get_child(*(GF_ChildNodeItem **)field.far_ptr, pos); + if (!target) return GF_SG_UNKNOWN_NODE; + if (gf_node_get_field(target, com->child_field, &field) != GF_OK) return GF_SG_UNKNOWN_NODE; + pos=-2; + } + + if (com->fromNodeID) { + GF_Node *fromNode = gf_sg_find_node(graph, com->fromNodeID); + if (!fromNode) return GF_SG_UNKNOWN_NODE; + e = gf_node_get_field(fromNode, com->fromFieldIndex, &value); + if (e) return e; + } else { + value.far_ptr = inf->field_ptr; + value.fieldType = inf->fieldType; + } + /*indexed replacement*/ + if (pos>=-1) { + /*if MFNode remove the child and set new node*/ + if (field.fieldType == GF_SG_VRML_MFNODE) { + GF_Node *nn = *(GF_Node**)value.far_ptr; + gf_node_replace_child(target, (GF_ChildNodeItem**) field.far_ptr, pos, nn); + if (nn) gf_node_register(nn, NULL); + } + /*erase the field item*/ + else { + u32 sftype; + if ((pos < 0) || ((u32) pos >= ((GenMFField *) field.far_ptr)->count) ) { + pos = ((GenMFField *)field.far_ptr)->count - 1; + /*may happen with text and default value*/ + if (pos < 0) { + pos = 0; + gf_sg_vrml_mf_alloc(field.far_ptr, field.fieldType, 1); + } + } + e = gf_sg_vrml_mf_get_item(field.far_ptr, field.fieldType, & slot_ptr, pos); + if (e) return e; + sftype = gf_sg_vrml_get_sf_type(field.fieldType); + gf_sg_vrml_field_copy(slot_ptr, value.far_ptr, sftype); + /*note we don't add time offset, since there's no MFTime*/ + } + } else { + switch (field.fieldType) { + case GF_SG_VRML_SFNODE: + { + node = *((GF_Node **) field.far_ptr); + e = gf_node_unregister(node, target); + *((GF_Node **) field.far_ptr) = *((GF_Node **) value.far_ptr) ; + if (!e) gf_node_register(*(GF_Node **) value.far_ptr, target); + break; + } + case GF_SG_VRML_MFNODE: + gf_node_unregister_children(target, * ((GF_ChildNodeItem **) field.far_ptr)); + * ((GF_ChildNodeItem **) field.far_ptr) = NULL; + + list = * ((GF_ChildNodeItem **) value.far_ptr); + prev=NULL; + while (list) { + cur = gf_malloc(sizeof(GF_ChildNodeItem)); + cur->next = NULL; + cur->node = list->node; + if (prev) { + prev->next = cur; + } else { + * ((GF_ChildNodeItem **) field.far_ptr) = cur; + } + gf_node_register(list->node, target); + prev = cur; + list = list->next; + } + break; + + default: + if (!gf_sg_vrml_is_sf_field(field.fieldType)) { + e = gf_sg_vrml_mf_reset(field.far_ptr, field.fieldType); + } + if (e) return e; + gf_sg_vrml_field_clone(field.far_ptr, value.far_ptr, field.fieldType, graph); + + if ((field.fieldType==GF_SG_VRML_SFTIME) && !strstr(field.name, "media")) + *(SFTime *)field.far_ptr = *(SFTime *)field.far_ptr + time_offset; + break; + } + } + SG_CheckFieldChange(target, &field); + } + return GF_OK; /*only used by BIFS*/ case GF_SG_GLOBAL_QUANTIZER: return GF_OK; +#endif /*GPAC_DISABLE_VRML*/ + + #ifndef GPAC_DISABLE_SVG /*laser commands*/ case GF_SG_LSR_NEW_SCENE: @@ -596,7 +696,7 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of prev = NULL; child = inf->node_list; while (child) { - cur = (GF_ChildNodeItem*)malloc(sizeof(GF_ChildNodeItem)); + cur = (GF_ChildNodeItem*)gf_malloc(sizeof(GF_ChildNodeItem)); cur->next = NULL; cur->node = child->node; gf_node_register(child->node, com->node); @@ -637,6 +737,8 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of else if (inf->fieldType==SVG_TRANSFORM_TRANSLATE) gf_mx2d_add_translation(dest, pt->x, pt->y); else if (inf->fieldType == SVG_TRANSFORM_ROTATE) gf_mx2d_add_rotation(dest, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle); } + /*signal node modif*/ + gf_node_changed(com->node, &a); } else { if ((inf->fieldIndex==(u32) -1) && (inf->fieldType==DOM_String_datatype)) { char *str = *(SVG_String*)inf->field_ptr; @@ -644,13 +746,15 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of if (com->tag == GF_SG_LSR_REPLACE) { GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; if (t && (t->sgprivate->tag==TAG_DOMText)) { - if (t->textContent) free(t->textContent); + if (t->textContent) gf_free(t->textContent); t->textContent = NULL; - if (str) t->textContent = strdup(str); + if (str) t->textContent = gf_strdup(str); } } else { - if (str) gf_dom_add_text_node(com->node, strdup(str)); + if (str) gf_dom_add_text_node(com->node, gf_strdup(str)); } + /*signal node modif*/ + gf_node_changed(com->node, NULL); } else if ((inf->fieldIndex==TAG_LSR_ATT_scale) || (inf->fieldIndex==TAG_LSR_ATT_translation) @@ -677,6 +781,8 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of if (inf->fieldIndex==TAG_LSR_ATT_translation) gf_mx2d_add_translation(&mx->mat, ((GF_Point2D*)inf->field_ptr)->x, ((GF_Point2D*)inf->field_ptr)->y); if (inf->fieldIndex==TAG_LSR_ATT_rotation) gf_mx2d_add_rotation(&mx->mat, 0, 0, ((SVG_Point_Angle*)inf->field_ptr)->angle); } + /*signal node modif*/ + gf_node_changed(com->node, &a); } else if (gf_node_get_attribute_by_tag(com->node, inf->fieldIndex, 1, 0, &a) == GF_OK) { b = a; @@ -686,12 +792,13 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of } else { gf_svg_attributes_add(&a, &b, &a, 0); } + if (a.fieldType==XMLRI_datatype) { + gf_node_dirty_set(com->node, GF_SG_SVG_XLINK_HREF_DIRTY, 0); + } + /*signal node modif*/ + gf_node_changed(com->node, &a); } - b = a; - b.far_ptr = inf->field_ptr; } - /*signal node modif*/ - gf_node_changed(com->node, &a); } else if (com->fromNodeID) { GF_FieldInfo a, b; GF_Node *fromNode = gf_sg_find_node(graph, com->fromNodeID); @@ -704,12 +811,12 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of if (com->tag == GF_SG_LSR_REPLACE) { GF_DOMText *t = ((SVG_Element*)com->node)->children ? (GF_DOMText*) ((SVG_Element*)com->node)->children->node :NULL; if (t && (t->sgprivate->tag==TAG_DOMText)) { - if (t->textContent) free(t->textContent); + if (t->textContent) gf_free(t->textContent); t->textContent = NULL; - if (str) t->textContent = strdup(str); + if (str) t->textContent = gf_strdup(str); } } else { - if (str) gf_dom_add_text_node(com->node, strdup(str)); + if (str) gf_dom_add_text_node(com->node, gf_strdup(str)); } } else { gf_node_get_field(com->node, inf->fieldIndex, &a); @@ -750,6 +857,7 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of } if (e) return e; +#ifndef GPAC_DISABLE_VRML if (com->scripts_to_load) { while (gf_list_count(com->scripts_to_load)) { GF_Node *script = (GF_Node *)gf_list_get(com->scripts_to_load, 0); @@ -759,6 +867,8 @@ GF_Err gf_sg_command_apply(GF_SceneGraph *graph, GF_Command *com, Double time_of gf_list_del(com->scripts_to_load); com->scripts_to_load = NULL; } +#endif + return GF_OK; } @@ -784,12 +894,12 @@ GF_Err gf_sg_command_apply_list(GF_SceneGraph *graph, GF_List *comList, Double t return GF_OK; } -GF_Command *gf_sg_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool force_clone) +#ifndef GPAC_DISABLE_VRML +GF_Command *gf_sg_vrml_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool force_clone) { u32 i, count; GF_Command *dest; - if (com->tag==GF_SG_SCENE_REPLACE) return NULL; /*FIXME - to do*/ if (gf_list_count(com->new_proto_list)) return NULL; dest = gf_sg_command_new(inGraph, com->tag); @@ -805,7 +915,7 @@ GF_Command *gf_sg_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool fo } /*route insert, replace and delete*/ dest->RouteID = com->RouteID; - if (com->def_name) dest->def_name = strdup(com->def_name); + if (com->def_name) dest->def_name = gf_strdup(com->def_name); dest->fromNodeID = com->fromNodeID; dest->fromFieldIndex = com->fromFieldIndex; dest->toNodeID = com->toNodeID; @@ -814,11 +924,11 @@ GF_Command *gf_sg_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool fo dest->send_event_x = com->send_event_x; dest->send_event_y = com->send_event_y; if (com->send_event_string) - dest->send_event_string = strdup(com->send_event_string); + dest->send_event_string = gf_strdup(com->send_event_string); dest->del_proto_list_size = com->del_proto_list_size; if (com->del_proto_list_size) { - dest->del_proto_list = (u32*)malloc(sizeof(u32) * com->del_proto_list_size); + dest->del_proto_list = (u32*)gf_malloc(sizeof(u32) * com->del_proto_list_size); memcpy(dest->del_proto_list, com->del_proto_list, sizeof(u32) * com->del_proto_list_size); } count = gf_list_count(com->command_fields); @@ -829,9 +939,11 @@ GF_Command *gf_sg_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool fo fd->fieldIndex = fo->fieldIndex; fd->fieldType = fo->fieldType; fd->pos = fo->pos; + + /*FIXME - this can also be LASeR commands, not supported for now*/ if (fo->field_ptr) { fd->field_ptr = gf_sg_vrml_field_pointer_new(fd->fieldType); - gf_sg_vrml_field_copy(fd->field_ptr, fo->field_ptr, fo->fieldType); + gf_sg_vrml_field_clone(fd->field_ptr, fo->field_ptr, fo->fieldType, dest->in_scene); } if (fo->new_node) { @@ -848,7 +960,7 @@ GF_Command *gf_sg_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool fo prev = NULL; child = fo->node_list; while (child) { - cur = (GF_ChildNodeItem*) malloc(sizeof(GF_ChildNodeItem)); + cur = (GF_ChildNodeItem*) gf_malloc(sizeof(GF_ChildNodeItem)); if (force_clone) { cur->node = gf_node_clone(inGraph, child->node, dest->node, "", 0); } else { @@ -867,3 +979,5 @@ GF_Command *gf_sg_command_clone(GF_Command *com, GF_SceneGraph *inGraph, Bool fo return dest; } +#endif + diff --git a/src/scenegraph/dom_events.c b/src/scenegraph/dom_events.c index d24bcc7..3ade26c 100644 --- a/src/scenegraph/dom_events.c +++ b/src/scenegraph/dom_events.c @@ -102,7 +102,7 @@ u32 gf_node_get_dom_event_filter(GF_Node *node) return node->sgprivate->scenegraph->dom_evt_filter; } -GF_Err gf_dom_listener_add(GF_Node *listener, GF_DOMEventTarget *evt_target) +GF_Err gf_sg_listener_add(GF_Node *listener, GF_DOMEventTarget *evt_target) { GF_FieldInfo info; if (!evt_target || !listener) return GF_BAD_PARAM; @@ -140,14 +140,13 @@ GF_Err gf_node_dom_listener_add(GF_Node *node, GF_Node *listener) node->sgprivate->interact->dom_evt->ptr_type = GF_DOM_EVENT_NODE; node->sgprivate->interact->dom_evt->evt_list = gf_list_new(); } - return gf_dom_listener_add(listener, node->sgprivate->interact->dom_evt); + return gf_sg_listener_add(listener, node->sgprivate->interact->dom_evt); } GF_Err gf_dom_listener_del(GF_Node *listener, GF_DOMEventTarget *target) { GF_FieldInfo info; if (!listener || !target) return GF_BAD_PARAM; - if (gf_list_del_item(target->evt_list, listener)<0) return GF_BAD_PARAM; if (gf_node_get_attribute_by_tag((GF_Node *)listener, TAG_XMLEV_ATT_event, 0, 0, &info) == GF_OK) { @@ -155,6 +154,7 @@ GF_Err gf_dom_listener_del(GF_Node *listener, GF_DOMEventTarget *target) gf_sg_unregister_event_type(listener->sgprivate->scenegraph, gf_dom_event_get_category(type)); } listener->sgprivate->UserPrivate = NULL; + gf_node_unregister((GF_Node *)listener, NULL); return GF_OK; } @@ -179,10 +179,10 @@ typedef struct GF_Node *listener; } DOMAddListener; -void gf_dom_listener_post_add(GF_Node *obs, GF_Node *listener) +void gf_sg_listener_post_add(GF_Node *obs, GF_Node *listener) { DOMAddListener *l; - l = (DOMAddListener*)malloc(sizeof(DOMAddListener)); + l = (DOMAddListener*)gf_malloc(sizeof(DOMAddListener)); l->listener = listener; l->obs = obs; gf_list_add(obs->sgprivate->scenegraph->listeners_to_add, l); @@ -195,11 +195,20 @@ void gf_dom_listener_process_add(GF_SceneGraph *sg) for (i=0; i<count; i++) { DOMAddListener *l = (DOMAddListener *)gf_list_get(sg->listeners_to_add, i); gf_node_dom_listener_add(l->obs, l->listener); - free(l); + gf_free(l); } gf_list_reset(sg->listeners_to_add); } +void gf_dom_listener_reset_defered(GF_SceneGraph *sg) +{ + while (gf_list_count(sg->listeners_to_add)) { + DOMAddListener *l = (DOMAddListener *)gf_list_get(sg->listeners_to_add, 0); + gf_list_rem(sg->listeners_to_add, 0); + gf_free(l); + } +} + void gf_sg_handle_dom_event(GF_Node *hdl, GF_DOM_Event *event, GF_Node *observer) { #ifdef GPAC_HAS_SPIDERMONKEY @@ -329,7 +338,7 @@ static Bool sg_fire_dom_event(GF_DOMEventTarget *et, GF_DOM_Event *event, GF_Sce if (event->type==GF_EVENT_LOAD) { dom_event_process(listen, event, observer); /*delete listener*/ - gf_dom_listener_del(listen, et); + //gf_dom_listener_del(listen, et); } else if (n) { assert(n->sgprivate->num_instances); /*protect node*/ @@ -363,7 +372,7 @@ static Bool sg_fire_dom_event(GF_DOMEventTarget *et, GF_DOM_Event *event, GF_Sce count = post_count; } } - /*propagation stoped*/ + /*propagation stopped*/ if (event->event_phase & (GF_DOM_EVENT_PHASE_CANCEL|GF_DOM_EVENT_PHASE_CANCEL_ALL) ) { gf_dom_listener_process_add(sg); return 0; @@ -378,7 +387,8 @@ static void gf_sg_dom_event_bubble(GF_Node *node, GF_DOM_Event *event, GF_List * { GF_Node *parent; - if (!node) return; + if (!node || node->sgprivate->scenegraph->abort_bubbling) return; + /*get the node's parent*/ parent = gf_node_get_parent(node, 0); @@ -396,11 +406,9 @@ static void gf_sg_dom_event_bubble(GF_Node *node, GF_DOM_Event *event, GF_List * parent = gf_list_get(use_stack, cur_par_idx); if (cur_par_idx>1) cur_par_idx-=2; else cur_par_idx = 0; - node->sgprivate->scenegraph->use_stack = use_stack; /*if no events attached,bubble by default*/ if (parent->sgprivate->interact && !sg_fire_dom_event(parent->sgprivate->interact->dom_evt, event, node->sgprivate->scenegraph, parent)) return; gf_sg_dom_event_bubble(parent, event, use_stack, cur_par_idx); - node->sgprivate->scenegraph->use_stack = use_stack; return; } } @@ -420,10 +428,13 @@ void gf_sg_dom_stack_parents(GF_Node *node, GF_List *stack) GF_EXPORT Bool gf_dom_event_fire_ex(GF_Node *node, GF_DOM_Event *event, GF_List *use_stack) { + GF_SceneGraph *sg; + GF_List *prev_use_stack; + Bool prev_bub; GF_DOMEventTarget cur_target; u32 cur_par_idx; if (!node || !event) return 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[DOM Events ] Time %f - Firing event %s.%s\n", gf_node_get_scene_time(node), gf_node_get_log_name(node), gf_dom_event_get_name(event->type))); + GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[DOM Events ] Graph 0x%x Time %f - Firing event %s.%s\n", gf_node_get_graph(node), gf_node_get_scene_time(node), gf_node_get_log_name(node), gf_dom_event_get_name(event->type))); /*flush any pending add_listener see "determine the current target's candidate event listeners" in http://www.w3.org/TR/DOM-Level-3-Events/events.html*/ @@ -473,12 +484,22 @@ Bool gf_dom_event_fire_ex(GF_Node *node, GF_DOM_Event *event, GF_List *use_stack cur_par_idx = gf_list_count(use_stack); if (cur_par_idx) cur_par_idx--; } + + sg = node->sgprivate->scenegraph; + + prev_use_stack = sg->use_stack ; + prev_bub = sg->abort_bubbling; + sg->use_stack = use_stack; + sg->abort_bubbling = 0; + if ( (!node->sgprivate->interact || sg_fire_dom_event(node->sgprivate->interact->dom_evt, event, node->sgprivate->scenegraph, node)) && event->bubbles) { /*bubbling phase*/ event->event_phase = GF_DOM_EVENT_PHASE_BUBBLE; gf_sg_dom_event_bubble(node, event, use_stack, cur_par_idx); } + sg->use_stack = prev_use_stack; + sg->abort_bubbling = prev_bub; return event->consumed ? 1 : 0; } @@ -554,7 +575,7 @@ static void gf_smil_handle_event(GF_Node *timed_elt, GF_FieldInfo *info, GF_DOM_ for (i=0; i<count; i++) { proto = (SMIL_Time*)gf_list_get(times, i); if ((proto->type == GF_SMIL_TIME_EVENT_RESOLVED) && (proto->clock<scene_time) ) { - free(proto); + gf_free(proto); gf_list_rem(times, i); i--; count--; @@ -663,7 +684,10 @@ static void gf_smil_setup_event_list(GF_Node *node, GF_List *l, Bool is_begin) else { continue; } + /*We don't want to insert the implicit listener in the DOM. However remember + the listener at the handler level in case the handler gets destroyed*/ gf_node_set_private((GF_Node *)hdl, node); + gf_node_register((GF_Node*)node, NULL); /*we keep the t->element pointer in order to discard the source of identical events (begin of # elements, ...)*/ } } @@ -677,6 +701,13 @@ void gf_smil_setup_events(GF_Node *node) gf_smil_setup_event_list(node, * (GF_List **)info.far_ptr, 0); } +void gf_dom_set_textContent(GF_Node *n, char *text) +{ + GF_ParentNode *par = (GF_ParentNode *)n; + gf_node_unregister_children(n, par->children); + par->children = NULL; + if (text) gf_dom_add_text_node(n, gf_strdup( text) ); +} GF_DOMText *gf_dom_add_text_node(GF_Node *parent, char *text_data) { @@ -699,6 +730,35 @@ GF_DOMText *gf_dom_new_text_node(GF_SceneGraph *sg) return text; } +char *gf_dom_flatten_textContent(GF_Node *n) +{ + u32 len = 0; + char *res = NULL; + GF_ChildNodeItem *list; + + if ((n->sgprivate->tag==TAG_DOMText) && ((GF_DOMText*)n)->textContent) { + /*if ( ((GF_DOMText*)n)->type == GF_DOM_TEXT_REGULAR) */{ + res = gf_strdup(((GF_DOMText*)n)->textContent); + len = strlen(res); + } + } + + list = ((GF_ParentNode *)n)->children; + while (list) { + char *t = gf_dom_flatten_textContent(list->node); + if (t) { + u32 sub_len = strlen(t); + res = gf_realloc(res, sizeof(char)*(len+sub_len+1)); + if (!len) res[0] = 0; + len += sub_len; + strcat(res, t); + gf_free(t); + } + list = list->next; + } + return res; +} + GF_DOMUpdates *gf_dom_add_updates_node(GF_Node *parent) { GF_DOMUpdates *text; diff --git a/src/scenegraph/dom_smjs.c b/src/scenegraph/dom_smjs.c index b3795b8..ee788bc 100644 --- a/src/scenegraph/dom_smjs.c +++ b/src/scenegraph/dom_smjs.c @@ -11,15 +11,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -40,23 +40,13 @@ #ifdef GPAC_HAS_SPIDERMONKEY -#include <jsapi.h> +#include <jsapi.h> -JSBool js_has_instance(JSContext *c, JSObject *obj, jsval val, JSBool *vp) -{ - *vp = JS_FALSE; - if (JSVAL_IS_OBJECT(val)) { - JSObject *p; - JSClass *js_class = JS_GET_CLASS(c, obj); - p = JSVAL_TO_OBJECT(val); - if (JS_InstanceOf(c, p, js_class, NULL) ) *vp = JS_TRUE; - } - return JS_TRUE; -} +JSBool my_js_has_instance(JSContext *c, JSObject *obj, jsval val, JSBool *vp); static GFINLINE Bool ScriptAction(GF_SceneGraph *scene, u32 type, GF_Node *node, GF_JSAPIParam *param) { - if (scene->script_action) + if (scene->script_action) return scene->script_action(scene->script_action_cbck, type, node, param); return 0; } @@ -76,21 +66,27 @@ static GFINLINE GF_SceneGraph *xml_get_scenegraph(JSContext *c) char *js_get_utf8(jsval val) { +#if 0 jschar *utf16; char *txt; u32 len; if (!JSVAL_CHECK_STRING(val) || JSVAL_IS_NULL(val)) return NULL; + /*locate SVG sequence responsible for this code add-on in test suit*/ utf16 = JS_GetStringChars(JSVAL_TO_STRING(val) ); len = gf_utf8_wcslen(utf16)*2 + 1; - txt = malloc(sizeof(char)*len); - len = gf_utf8_wcstombs(txt, len, &utf16); + txt = gf_malloc(sizeof(char)*len); + len = gf_utf8_wcstombs(txt, len, (const u16**) &utf16); if ((s32)len<0) { - free(txt); + gf_free(txt); return NULL; } txt[len]=0; return txt; +#else + if (!JSVAL_CHECK_STRING(val) || JSVAL_IS_NULL(val)) return NULL; + return gf_strdup( JS_GetStringBytes(JSVAL_TO_STRING(val) ) ); +#endif } /************************************************************ @@ -113,32 +109,36 @@ typedef struct JSClass xmlHTTPRequestClass; JSClass DCCIClass; - JSObject *dom_node_proto; + JSClass storageClass; + + JSObject *dom_node_proto; JSObject *dom_document_proto; JSObject *dom_element_proto; JSObject *dom_event_proto; + JSObject *storage_proto; void *(*get_element_class)(GF_Node *n); void *(*get_document_class)(GF_SceneGraph *n); + GF_List *handlers; } GF_DOMRuntime; static GF_DOMRuntime *dom_rt = NULL; static JSBool xml_dom3_not_implemented(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) -{ +{ return JS_TRUE; } #define JS_DOM3_uDOM_FIRST_PROP 18 -static void dom_node_changed(GF_Node *n, Bool child_modif, GF_FieldInfo *info) +void dom_node_changed(GF_Node *n, Bool child_modif, GF_FieldInfo *info) { if (info) { if (child_modif) { gf_node_dirty_set(n, GF_SG_CHILD_DIRTY, 0); - } + } #ifndef GPAC_DISABLE_SVG else { u32 flag = gf_svg_get_modification_flags((SVG_Element *)n, info); @@ -223,29 +223,41 @@ static jsval dom_document_construct(JSContext *c, GF_SceneGraph *sg) sg->reference_count++; gf_node_register(sg->RootNode, NULL); - jsclass = &dom_rt->domDocumentClass; + jsclass = NULL; if (dom_rt->get_document_class) jsclass = (JSClass *) dom_rt->get_document_class(sg); + if (!jsclass) jsclass = &dom_rt->domDocumentClass; + new_obj = JS_NewObject(c, jsclass, 0, 0); JS_SetPrivate(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) { + Bool set_rooted; GF_SceneGraph *sg; - u32 i, count; JSObject *new_obj; if (!n || !n->sgprivate->scenegraph) return JSVAL_VOID; if (n->sgprivate->tag<TAG_DOMText) return JSVAL_VOID; sg = n->sgprivate->scenegraph; - count = gf_list_count(sg->objects); - for (i=0; i<count; i++) { - JSObject *obj = gf_list_get(sg->objects, i); - GF_Node *a_node = JS_GetPrivate(c, obj); - if (n==a_node) return OBJECT_TO_JSVAL(obj); + /*if parent doc is not a scene (eg it is a doc being parsed/constructed from script, don't root objects*/ + set_rooted = sg->reference_count ? 0 : 1; + + if (n->sgprivate->interact && n->sgprivate->interact->js_binding && n->sgprivate->interact->js_binding->node) { + if (set_rooted && (gf_list_find(sg->objects, n->sgprivate->interact->js_binding->node)<0)) { + const char *name = gf_node_get_name(n); + if (name) { + gf_js_add_named_root(c, &n->sgprivate->interact->js_binding->node, name); + } else { + gf_js_add_root(c, &n->sgprivate->interact->js_binding->node); + } + gf_list_add(sg->objects, n->sgprivate->interact->js_binding->node); + } + return OBJECT_TO_JSVAL(n->sgprivate->interact->js_binding->node); } if (n->sgprivate->scenegraph->reference_count) @@ -254,31 +266,53 @@ static jsval dom_base_node_construct(JSContext *c, JSClass *_class, GF_Node *n) gf_node_register(n, NULL); new_obj = JS_NewObject(c, _class, 0, 0); JS_SetPrivate(c, new_obj, n); - gf_list_add(sg->objects, new_obj); + + if (!n->sgprivate->interact) GF_SAFEALLOC(n->sgprivate->interact, struct _node_interactive_ext); + if (!n->sgprivate->interact->js_binding) { + GF_SAFEALLOC(n->sgprivate->interact->js_binding, struct _node_js_binding); + } + n->sgprivate->interact->js_binding->node = new_obj; + + /*don't root the node until inserted in the tree*/ + if (n->sgprivate->parents && set_rooted) { + const char *name = gf_node_get_name(n); + if (name) { + gf_js_add_named_root(c, &n->sgprivate->interact->js_binding->node, name); + } else { + gf_js_add_root(c, &n->sgprivate->interact->js_binding->node); + } + gf_list_add(sg->objects, n->sgprivate->interact->js_binding->node); + } return OBJECT_TO_JSVAL(new_obj); } static jsval dom_node_construct(JSContext *c, GF_Node *n) { - JSClass *__class = &dom_rt->domElementClass; + 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); + if (!__class ) __class = &dom_rt->domElementClass; + /*in our implementation ONLY ELEMENTS are created, never attributes. We therefore always create Elements when asked to create a node !!*/ return dom_base_node_construct(c, __class, n); } jsval dom_element_construct(JSContext *c, GF_Node *n) { - JSClass *__class = &dom_rt->domElementClass; + 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); + if (!__class) __class = &dom_rt->domElementClass; + return dom_base_node_construct(c, __class, n); } @@ -297,7 +331,7 @@ static void dom_unregister_node(GF_Node *n) gf_node_unregister(n, NULL); if (sg->reference_count) { sg->reference_count--; - if (!sg->reference_count) + if (!sg->reference_count) gf_sg_del(sg); } } @@ -331,11 +365,11 @@ jsval dom_node_get_sibling(JSContext *c, GF_Node *n, Bool is_prev, Bool elt_only val = child->node; } if (is_prev) { - if (idx<=cur) + if (idx<=cur) break; } else { if (idx>=cur) val = NULL; - if (val && idx<cur) + if (val && idx<cur) break; } child = child->next; @@ -344,39 +378,11 @@ jsval dom_node_get_sibling(JSContext *c, GF_Node *n, Bool is_prev, Bool elt_only return dom_node_construct(c, val); } -char *dom_node_flatten_text(GF_Node *n) -{ - u32 len = 0; - char *res = NULL; - GF_ChildNodeItem *list; - - if ((n->sgprivate->tag==TAG_DOMText) && ((GF_DOMText*)n)->textContent) { - if ( ((GF_DOMText*)n)->type == GF_DOM_TEXT_REGULAR) { - res = strdup(((GF_DOMText*)n)->textContent); - len = strlen(res); - } - } - - list = ((GF_ParentNode *)n)->children; - while (list) { - char *t = dom_node_flatten_text(list->node); - if (t) { - u32 sub_len = strlen(t); - res = realloc(res, sizeof(char)*(len+sub_len+1)); - if (!len) res[0] = 0; - len += sub_len; - strcat(res, t); - free(t); - } - list = list->next; - } - return res; -} /*dom3 NodeList/NamedNodeMap*/ typedef struct -{ +{ /*set if the object is a childList from an existing node*/ GF_ParentNode *owner; /*child list*/ @@ -417,26 +423,27 @@ static void dom_nodelist_finalize(JSContext *c, JSObject *obj) GF_ChildNodeItem *child = nl->child; nl->child = child->next; dom_unregister_node(child->node); - free(child); + gf_free(child); } } - free(nl); + gf_free(nl); } static JSBool dom_nodelist_item(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { GF_Node *n; - u32 idx, count; + u32 count; + s32 idx; DOMNodeList *nl; - if (!JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL) ) + if (!JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL) ) return JS_TRUE; - if ((argc!=1) || !JSVAL_IS_INT(argv[0])) + if ((argc!=1) || !JSVAL_IS_INT(argv[0])) return JS_TRUE; nl = (DOMNodeList *)JS_GetPrivate(c, obj); count = gf_node_list_get_count(nl->owner ? nl->owner->children : nl->child); idx = JSVAL_TO_INT(argv[0]); - if ((idx<0) || (idx>=count)) { + if ((idx<0) || ((u32) idx>=count)) { *rval = JSVAL_VOID; return JS_TRUE; } @@ -450,7 +457,7 @@ static JSBool dom_nodelist_item(JSContext *c, JSObject *obj, uintN argc, jsval * static JSBool dom_nodelist_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) { DOMNodeList *nl; - if (!JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL) + if (!JS_InstanceOf(c, obj, &dom_rt->domNodeListClass, NULL) ) return JS_TRUE; @@ -475,14 +482,28 @@ static JSBool dom_nodelist_setProperty(JSContext *c, JSObject *obj, jsval id, js /*dom event listener*/ #define JS_DOM3_EVEN_TARGET_INTERFACE \ - {"addEventListenerNS", dom_event_add_listener, 4}, \ - {"removeEventListenerNS", dom_event_remove_listener, 4}, \ - {"addEventListener", dom_event_add_listener, 3}, \ - {"removeEventListener", dom_event_remove_listener, 3}, \ - {"dispatchEvent", xml_dom3_not_implemented, 1}, + {"addEventListenerNS", dom_event_add_listener, 4, 0, 0}, \ + {"removeEventListenerNS", dom_event_remove_listener, 4, 0, 0}, \ + {"addEventListener", dom_event_add_listener, 3, 0, 0}, \ + {"removeEventListener", dom_event_remove_listener, 3, 0, 0}, \ + {"dispatchEvent", xml_dom3_not_implemented, 1, 0, 0}, + + +static void dom_handler_remove(GF_Node *node, void *rs, Bool is_destroy) +{ + if (is_destroy) { + SVG_handlerElement *handler = (SVG_handlerElement *)node; + if (handler->js_context && handler->js_fun_val) { + /*unprotect the function*/ + gf_js_remove_root(handler->js_context, &(handler->js_fun_val)); + handler->js_fun_val=0; + gf_list_del_item(dom_rt->handlers, handler); + } + } +} /*eventListeners routines used by document, element and connection interfaces*/ -JSBool dom_event_add_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node) +JSBool gf_sg_js_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *on_node) { GF_DOMEventTarget *target; GF_FieldInfo info; @@ -508,14 +529,14 @@ JSBool dom_event_add_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsval return JS_TRUE; #endif } else { - if (vrml_node) { - n = vrml_node; + if (on_node) { + n = on_node; } else { n = dom_get_element(c, obj); } if (n) sg = n->sgprivate->scenegraph; } - + /*FIXME - SVG uDOM connection not supported yet*/ if (!sg) return JS_TRUE; @@ -554,7 +575,7 @@ JSBool dom_event_add_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsval if (evtType==GF_EVENT_UNKNOWN) goto err_exit; listener = gf_node_new(sg, TAG_SVG_listener); - /*we don't register the listener with the parent node , it will be registered + /*we don't register the listener with the parent node , it will be registered on gf_dom_listener__add*/ /*!!! create the handler in the scene owning the script context !!! */ @@ -568,6 +589,13 @@ JSBool dom_event_add_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsval if (!callback) { handler->js_fun = fun; handler->js_fun_val = funval; + if (handler->js_fun_val) { + handler->js_context = c; + /*protect the function - we don't know how it was passed to us, so prevent it from being GCed*/ + gf_js_add_root(handler->js_context, &handler->js_fun_val); + handler->sgprivate->UserCallback = dom_handler_remove; + gf_list_add(dom_rt->handlers, handler); + } handler->evt_listen_obj = evt_handler; } } @@ -585,35 +613,40 @@ JSBool dom_event_add_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsval gf_node_get_attribute_by_tag((GF_Node*)handler, TAG_XMLEV_ATT_event, 1, 0, &info); ((XMLEV_Event*)info.far_ptr)->type = evtType; - if (callback) gf_dom_add_text_node((GF_Node *)handler, strdup(callback)); + if (callback) gf_dom_add_text_node((GF_Node *)handler, gf_strdup(callback)); #ifndef GPAC_DISABLE_SVG if (handler->sgprivate->scenegraph->svg_js) handler->handle_event = gf_sg_handle_dom_event; #endif - - if (!handler->handle_event) { - handler->handle_event = gf_sg_handle_dom_event_for_vrml; + + if (on_node) { handler->js_context = c; +#ifndef GPAC_DISABLE_VRML + if (on_node->sgprivate->tag <= GF_NODE_RANGE_LAST_VRML) + handler->handle_event = gf_sg_handle_dom_event_for_vrml; +#endif } /*don't add listener directly, post it and wait for event processing*/ if (n) { - gf_dom_listener_post_add((GF_Node *) n, listener); + gf_sg_listener_post_add((GF_Node *) n, listener); } else { - gf_dom_listener_add(listener, target); + gf_sg_listener_add(listener, target); } err_exit: - if (inNS) free(inNS); + if (inNS) gf_free(inNS); return JS_TRUE; } + + JSBool dom_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - return dom_event_add_listener_ex(c, obj, argc, argv, rval, NULL); + return gf_sg_js_event_add_listener(c, obj, argc, argv, rval, NULL); } -JSBool dom_event_remove_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node) +JSBool gf_sg_js_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node) { #ifndef GPAC_DISABLE_SVG char *type, *callback; @@ -641,7 +674,7 @@ JSBool dom_event_remove_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsv gf_dom_listener_process_add(sg); if (node) { if (node->sgprivate->interact) target = node->sgprivate->interact->dom_evt; - } + } /*FIXME - SVG uDOM connection not supported yet*/ else { target = &sg->dom_evt; @@ -669,7 +702,7 @@ JSBool dom_event_remove_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsv evtType = gf_dom_event_type_by_name(type); if (evtType==GF_EVENT_UNKNOWN) goto err_exit; - + count = gf_list_count(target->evt_list); for (i=0; i<count; i++) { GF_FieldInfo info; @@ -686,7 +719,7 @@ JSBool dom_event_remove_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsv hdl = (SVG_handlerElement *) ((XMLRI*)info.far_ptr)->target; if (!hdl) continue; if (funval) { - if (funval != hdl->js_fun_val) continue; + if (funval != (jsval) hdl->js_fun_val) continue; } else if (hdl->children) { txt = (GF_DOMText *) hdl->children->node; if (txt->sgprivate->tag != TAG_DOMText) continue; @@ -702,13 +735,13 @@ JSBool dom_event_remove_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsv #endif err_exit: - if (inNS) free(inNS); + if (inNS) gf_free(inNS); return JS_TRUE; } JSBool dom_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - return dom_event_remove_listener_ex(c, obj, argc, argv, rval, NULL); + return gf_sg_js_event_remove_listener(c, obj, argc, argv, rval, NULL); } /*dom3 node*/ @@ -718,7 +751,11 @@ static void dom_node_finalize(JSContext *c, JSObject *obj) /*the JS proto of the svgClass or a destroyed object*/ if (!n) return; if (!n->sgprivate) return; + + JS_SetPrivate(c, obj, NULL); gf_list_del_item(n->sgprivate->scenegraph->objects, obj); + + dom_js_pre_destroy(c, n->sgprivate->scenegraph, n); dom_unregister_node(n); } @@ -741,33 +778,48 @@ static Bool check_dom_parents(JSContext *c, GF_Node *n, GF_Node *parent) return 1; } -static void dom_node_inserted(GF_Node *par, GF_Node *n, s32 pos) +static void dom_node_inserted(JSContext *c, GF_Node *n, GF_Node *parent, s32 pos) { - GF_ParentNode *old_par; + GF_ParentNode *old_parent; Bool do_init = 0; /*if node is already in graph, remove it from its parent*/ - old_par = (GF_ParentNode*)gf_node_get_parent(n, 0); - if (old_par) { + old_parent = (GF_ParentNode*)gf_node_get_parent(n, 0); + if (old_parent) { /*prevent destruction when removing node*/ n->sgprivate->num_instances++; - gf_node_list_del_child(&old_par->children, n); - gf_node_unregister(n, (GF_Node*)old_par); + gf_node_list_del_child(&old_parent->children, n); + gf_node_unregister(n, (GF_Node*)old_parent); n->sgprivate->num_instances--; } else { do_init = (n->sgprivate->UserCallback || n->sgprivate->UserPrivate) ? 0 : 1; + + } + /*node is being inserted - if node has a valid binding, re-root it if needed*/ + if (n->sgprivate->interact && n->sgprivate->interact->js_binding) { + JSObject *nobj = n->sgprivate->interact->js_binding->node; + if (nobj && (gf_list_find(n->sgprivate->scenegraph->objects, nobj)<0) ) { + const char *name = gf_node_get_name(n); + if (name) { + gf_js_add_named_root(c, &n->sgprivate->interact->js_binding->node, name); + } else { + gf_js_add_root(c, &n->sgprivate->interact->js_binding->node); + } + gf_list_add(n->sgprivate->scenegraph->objects, nobj); + } } - if (pos<0) gf_node_list_add_child( & ((GF_ParentNode *)par)->children, n); - else gf_node_list_insert_child( & ((GF_ParentNode *)par)->children, n, (u32) pos); - gf_node_register(n, par); + if (pos<0) gf_node_list_add_child( & ((GF_ParentNode *)parent)->children, n); + else gf_node_list_insert_child( & ((GF_ParentNode *)parent)->children, n, (u32) pos); + gf_node_register(n, parent); if (do_init) { /*node is a handler, create listener*/ - if (par && (n->sgprivate->tag==TAG_SVG_handler)) { - gf_dom_listener_build_ex(par, 0, 0, n, NULL); + if (parent && (n->sgprivate->tag==TAG_SVG_handler)) { + gf_dom_listener_build_ex(parent, 0, 0, n, NULL); } gf_node_init(n); + #ifndef GPAC_DISABLE_SVG if (n->sgprivate->interact && n->sgprivate->interact->dom_evt) { @@ -779,9 +831,9 @@ static void dom_node_inserted(GF_Node *par, GF_Node *n, s32 pos) #endif } /*node is being re-inserted, activate it in case*/ - if (!old_par) gf_node_activate(n); + if (!old_parent) gf_node_activate(n); - dom_node_changed(par, 1, NULL); + dom_node_changed(parent, 1, NULL); } static JSBool xml_node_insert_before(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) @@ -790,7 +842,7 @@ static JSBool xml_node_insert_before(JSContext *c, JSObject *obj, uintN argc, js u32 tag; GF_Node *n, *target, *new_node; GF_ParentNode *par; - if (!argc || !JSVAL_IS_OBJECT(argv[0])) + if (!argc || !JSVAL_IS_OBJECT(argv[0])) return JS_TRUE; n = dom_get_node(c, obj); @@ -820,7 +872,7 @@ static JSBool xml_node_insert_before(JSContext *c, JSObject *obj, uintN argc, js return dom_throw_exception(c, GF_DOM_EXC_NOT_FOUND_ERR); } } - dom_node_inserted(n, new_node, idx); + dom_node_inserted(c, new_node, n, idx); *rval = argv[0]; return JS_TRUE; } @@ -843,7 +895,7 @@ static JSBool xml_node_append_child(JSContext *c, JSObject *obj, uintN argc, jsv if (!check_dom_parents(c, n, new_node)) return JS_FALSE; - dom_node_inserted(n, new_node, -1); + dom_node_inserted(c, new_node, n, -1); *rval = argv[0]; return JS_TRUE; @@ -872,8 +924,11 @@ static JSBool xml_node_replace_child(JSContext *c, JSObject *obj, uintN argc, js gf_node_list_del_child(&par->children, old_node); gf_node_unregister(old_node, n); - dom_node_inserted(n, new_node, -1); - + dom_node_inserted(c, new_node, n, -1); + + /*whenever we remove a node from the tree, call GC to cleanup the JS binding if any. Not doing so may screw up node IDs*/ + n->sgprivate->scenegraph->svg_js->force_gc = 1; + *rval = argv[0]; return JS_TRUE; } @@ -884,6 +939,7 @@ static JSBool xml_node_remove_child(JSContext *c, JSObject *obj, uintN argc, jsv GF_Node *n, *old_node; GF_ParentNode *par; if (!argc || !JSVAL_IS_OBJECT(argv[0])) return JS_TRUE; + n = dom_get_node(c, obj); if (!n) return JS_TRUE; @@ -892,7 +948,7 @@ static JSBool xml_node_remove_child(JSContext *c, JSObject *obj, uintN argc, jsv tag = gf_node_get_tag(n); if (tag==TAG_DOMText) return JS_TRUE; par = (GF_ParentNode*)n; - + /*if node is present in parent, unregister*/ if (gf_node_list_del_child(&par->children, old_node)) { gf_node_unregister(old_node, n); @@ -901,6 +957,8 @@ static JSBool xml_node_remove_child(JSContext *c, JSObject *obj, uintN argc, jsv } *rval = argv[0]; dom_node_changed(n, 1, NULL); + /*whenever we remove a node from the tree, call GC to cleanup the JS binding if any. Not doing so may screw up node IDs*/ + n->sgprivate->scenegraph->svg_js->force_gc = 1; return JS_TRUE; } @@ -912,7 +970,7 @@ static JSBool xml_clone_node(JSContext *c, JSObject *obj, uintN argc, jsval *arg n = dom_get_node(c, obj); if (!n) return JS_TRUE; deep = argc ? JSVAL_TO_BOOLEAN(argv[0]) : 0; - + clone = gf_node_clone(n->sgprivate->scenegraph, n, NULL, "", deep); *rval = dom_node_construct(c, clone); return JS_TRUE; @@ -1016,7 +1074,7 @@ static JSBool dom_node_getProperty(JSContext *c, JSObject *obj, jsval id, jsval GF_Node *n; GF_SceneGraph *sg = NULL; GF_ParentNode *par; - + n = dom_get_node(c, obj); if (!n) { sg = dom_get_doc(c, obj); @@ -1153,11 +1211,46 @@ static JSBool dom_node_getProperty(JSContext *c, JSObject *obj, jsval id, jsval case 15: *vp = JSVAL_VOID; if (!sg) { - char *res = dom_node_flatten_text(n); + char *res = gf_dom_flatten_textContent(n); *vp = STRING_TO_JSVAL( JS_NewStringCopyZ(c, res) ); - free(res); + gf_free(res); + } + return JS_TRUE; + + case 16:/*firstElementChild*/ + *vp = JSVAL_NULL; + if (n->sgprivate->tag!=TAG_DOMText) { + GF_ChildNodeItem *child = ((GF_ParentNode*)n)->children; + while (child) { + if (child->node->sgprivate->tag != TAG_DOMText) { + *vp = dom_element_construct(c, child->node); + break; + } + child = child->next; + } + } + return JS_TRUE; + case 17:/*lastElementChild*/ + *vp = JSVAL_NULL; + if (n->sgprivate->tag!=TAG_DOMText) { + GF_Node *last = NULL; + GF_ChildNodeItem *child = ((GF_ParentNode*)n)->children; + while (child) { + if (child->node->sgprivate->tag != TAG_DOMText) { + last = child->node; + } + child = child->next; + } + if (last) *vp = dom_element_construct(c, last); } return JS_TRUE; + case 18:/*previousElementSibling*/ + *vp = dom_node_get_sibling(c, n, 1, 1); + return JS_TRUE; + case 19:/*nextElementSibling*/ + *vp = dom_node_get_sibling(c, n, 0, 1); + return JS_TRUE; + } /*not supported*/ return JS_TRUE; @@ -1165,11 +1258,13 @@ static JSBool dom_node_getProperty(JSContext *c, JSObject *obj, jsval id, jsval void dom_node_set_textContent(GF_Node *n, char *text) { - GF_ParentNode *par = (GF_ParentNode *)n; - gf_node_unregister_children(n, par->children); - par->children = NULL; - gf_dom_add_text_node(n, strdup( text) ); - dom_node_changed(n, 1, NULL); + GF_FieldInfo info; + gf_dom_set_textContent(n, text); + + gf_node_dirty_set(n, GF_SG_CHILD_DIRTY, 0); + memset(&info, 0, sizeof(GF_FieldInfo)); + info.fieldIndex = (u32) -1; + gf_node_changed(n, &info); } static JSBool dom_node_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) @@ -1192,7 +1287,7 @@ static JSBool dom_node_setProperty(JSContext *c, JSObject *obj, jsval id, jsval case 1: if ((tag==TAG_DOMText) && JSVAL_CHECK_STRING(*vp)) { GF_DOMText *txt = (GF_DOMText *)n; - if (txt->textContent) free(txt->textContent); + if (txt->textContent) gf_free(txt->textContent); txt->textContent = js_get_utf8(*vp); dom_node_changed(n, 1, NULL); } @@ -1204,11 +1299,11 @@ static JSBool dom_node_setProperty(JSContext *c, JSObject *obj, jsval id, jsval return JS_TRUE; /*"textContent"*/ case 15: - { + { char *txt; txt = js_get_utf8(*vp); dom_node_set_textContent(n, txt); - if (txt) free(txt); + if (txt) gf_free(txt); } return JS_TRUE; } @@ -1229,12 +1324,15 @@ void dom_document_finalize(JSContext *c, JSObject *obj) /*the JS proto of the svgClass or a destroyed object*/ if (!sg) return; + JS_SetPrivate(c, sg->document, NULL); sg->document = NULL; - gf_node_unregister(sg->RootNode, NULL); - if (sg->reference_count) { - sg->reference_count--; - if (!sg->reference_count) - gf_sg_del(sg); + if (sg->RootNode) { + gf_node_unregister(sg->RootNode, NULL); + if (sg->reference_count) { + sg->reference_count--; + if (!sg->reference_count) + gf_sg_del(sg); + } } } @@ -1251,17 +1349,17 @@ static JSBool dom_document_getProperty(JSContext *c, JSObject *obj, jsval id, js case 2:/*implementation*/ /*FIXME, this is wrong, we should have our own implementation but at the current time we rely on the global object to provide it*/ - *vp = OBJECT_TO_JSVAL( JS_GetGlobalObject(c) ); + *vp = OBJECT_TO_JSVAL( JS_GetGlobalObject(c) ); return JS_TRUE; case 3: /*"documentElement"*/ *vp = dom_element_construct(c, sg->RootNode); return JS_TRUE; case 11:/*global*/ - *vp = OBJECT_TO_JSVAL( JS_GetGlobalObject(c) ); + *vp = OBJECT_TO_JSVAL( JS_GetGlobalObject(c) ); return JS_TRUE; - + /*NOT SUPPORTED YET*/ case 1: /*"doctype"*/ @@ -1286,7 +1384,7 @@ static JSBool dom_document_setProperty(JSContext *c, JSObject *obj, jsval id, js if (!JSVAL_IS_INT(id)) return JS_TRUE; prop_id = JSVAL_TO_INT(id); - + switch (prop_id) { case 6:/*"xmlStandalone"*/ break; @@ -1311,7 +1409,7 @@ static JSBool xml_document_create_element(JSContext *c, JSObject *obj, uintN arg char *name, *xmlns; GF_SceneGraph *sg = dom_get_doc(c, obj); - if (!sg || !argc || !JSVAL_CHECK_STRING(argv[0]) ) + if (!sg || !argc || !JSVAL_CHECK_STRING(argv[0]) ) return JS_TRUE; name = NULL; @@ -1334,7 +1432,7 @@ static JSBool xml_document_create_element(JSContext *c, JSObject *obj, uintN arg n = gf_node_new(sg, tag); if (n && (tag == TAG_DOMFullNode)) { GF_DOMFullNode *elt = (GF_DOMFullNode *)n; - elt->name = strdup(name); + elt->name = gf_strdup(name); if (xmlns) { gf_sg_add_namespace(sg, xmlns, NULL); elt->ns = gf_sg_get_namespace_code_from_name(sg, xmlns); @@ -1342,7 +1440,7 @@ static JSBool xml_document_create_element(JSContext *c, JSObject *obj, uintN arg } *rval = dom_element_construct(c, n); } - if (xmlns) free(xmlns); + if (xmlns) gf_free(xmlns); return JS_TRUE; } @@ -1355,7 +1453,7 @@ static JSBool xml_document_create_text(JSContext *c, JSObject *obj, uintN argc, n = gf_node_new(sg, TAG_DOMText); if (argc) { char *str = js_get_utf8(argv[0]); - if (!str) str = strdup(""); + if (!str) str = gf_strdup(""); ((GF_DOMText*)n)->textContent = str; } *rval = dom_text_construct(c, n); @@ -1421,7 +1519,7 @@ static JSBool xml_document_element_by_id(JSContext *c, JSObject *obj, uintN argc if (!argc || !JSVAL_CHECK_STRING(argv[0])) return JS_TRUE; id = JSVAL_GET_STRING(argv[0]); - /*we don't use the regular gf_sg_find_node_by_name because we may have nodes defined with the + /*we don't use the regular gf_sg_find_node_by_name because we may have nodes defined with the same ID and we need to locate the first one which is inserted in the tree*/ n = NULL; reg_node = sg->id_node; @@ -1468,16 +1566,16 @@ static JSBool xml_element_get_attribute(JSContext *c, JSObject *obj, uintN argc, { char *name, *ns; GF_Node *n = dom_get_node(c, obj); - if (!n) + if (!n) return JS_TRUE; - if (!argc || !JSVAL_CHECK_STRING(argv[0])) + if (!argc || !JSVAL_CHECK_STRING(argv[0])) return JS_TRUE; name = JSVAL_GET_STRING(argv[0]); ns = NULL; /*NS version*/ if (argc==2) { - if (!JSVAL_CHECK_STRING(argv[1])) + if (!JSVAL_CHECK_STRING(argv[1])) return JS_TRUE; ns = js_get_utf8(argv[0]); name = JSVAL_GET_STRING(argv[1]); @@ -1487,8 +1585,10 @@ static JSBool xml_element_get_attribute(JSContext *c, JSObject *obj, uintN argc, /*ugly ugly hack ...*/ if (!strcmp(name, "id") || !strcmp(name, "xml:id") ) { char *sID = (char *) gf_node_get_name(n); - *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, sID ? sID : "") ); - goto exit; + if (sID) { + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, sID ? sID : "") ); + goto exit; + } } if (n->sgprivate->tag==TAG_DOMFullNode) { @@ -1496,7 +1596,7 @@ static JSBool xml_element_get_attribute(JSContext *c, JSObject *obj, uintN argc, GF_DOMFullAttribute *att = (GF_DOMFullAttribute*)node->attributes; while (att) { if ((att->tag==TAG_DOM_ATT_any) && !strcmp(att->name, name)) { - *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, (char*)att->data ) ); + *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, *(char**)att->data ) ); goto exit; } att = (GF_DOMFullAttribute *) att->next; @@ -1516,15 +1616,15 @@ static JSBool xml_element_get_attribute(JSContext *c, JSObject *obj, uintN argc, } if (gf_node_get_attribute_by_name(n, name, ns_code, 0, 0, &info)==GF_OK) { - char szAtt[4096]; - gf_svg_dump_attribute(n, &info, szAtt); + char *szAtt = gf_svg_dump_attribute(n, &info); *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, szAtt) ); + if (szAtt) gf_free(szAtt); goto exit; - } + } } *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "") ); exit: - if (ns) free(ns); + if (ns) gf_free(ns); return JS_TRUE; } @@ -1533,7 +1633,7 @@ static JSBool xml_element_has_attribute(JSContext *c, JSObject *obj, uintN argc, { char *name, *ns; GF_Node *n = dom_get_node(c, obj); - if (!n) + if (!n) return JS_TRUE; if (!argc || !JSVAL_CHECK_STRING(argv[0])) return JS_TRUE; @@ -1572,7 +1672,7 @@ static JSBool xml_element_has_attribute(JSContext *c, JSObject *obj, uintN argc, } *rval = BOOLEAN_TO_JSVAL(JS_FALSE); exit: - if (ns) free(ns); + if (ns) gf_free(ns); return JS_TRUE; } @@ -1618,16 +1718,16 @@ static JSBool xml_element_remove_attribute(JSContext *c, JSObject *obj, uintN ar if ((att->tag==TAG_DOM_ATT_any) && !strcmp(att->name, name)) { if (prev) prev->next = att->next; else node->attributes = att->next; - if (att->data) free(att->data); - free(att->name); - free(att); + if (att->data) gf_free(att->data); + gf_free(att->name); + gf_free(att); dom_node_changed(n, 0, NULL); goto exit; } else if (tag==att->tag) { if (prev) prev->next = att->next; else node->attributes = att->next; gf_svg_delete_attribute_value(att->data_type, att->data, n->sgprivate->scenegraph); - free(att); + gf_free(att); dom_node_changed(n, 0, NULL); goto exit; } @@ -1635,7 +1735,7 @@ static JSBool xml_element_remove_attribute(JSContext *c, JSObject *obj, uintN ar att = (GF_DOMFullAttribute *) att->next; } exit: - if (ns) free(ns); + if (ns) gf_free(ns); return JS_TRUE; } @@ -1706,14 +1806,14 @@ static JSBool xml_element_set_attribute(JSContext *c, JSObject *obj, uintN argc, handler = (SVG_handlerElement *) ((XMLRI*)info.far_ptr)->target; text = (GF_DOMText*)handler->children->node; if (text->sgprivate->tag==TAG_DOMText) { - if (text->textContent) free(text->textContent); - text->textContent = strdup(val); + if (text->textContent) gf_free(text->textContent); + text->textContent = gf_strdup(val); } goto exit; } /*nope, create a listener*/ handler = gf_dom_listener_build(n, evtType, 0); - gf_dom_add_text_node((GF_Node*)handler, strdup(val) ); + gf_dom_add_text_node((GF_Node*)handler, gf_strdup(val) ); goto exit; } } @@ -1724,8 +1824,8 @@ static JSBool xml_element_set_attribute(JSContext *c, JSObject *obj, uintN argc, GF_DOMFullAttribute *att = (GF_DOMFullAttribute*)node->attributes; while (att) { if ((att->tag==TAG_DOM_ATT_any) && !strcmp(att->name, name)) { - if (att->data) free(att->data); - att->data = strdup(val); + if (att->data) gf_free(att->data); + att->data = gf_strdup(val); dom_node_changed(n, 0, NULL); goto exit; } @@ -1734,37 +1834,81 @@ static JSBool xml_element_set_attribute(JSContext *c, JSObject *obj, uintN argc, } /*create new att*/ GF_SAFEALLOC(att, GF_DOMFullAttribute); - att->name = strdup(name); - att->data = strdup(val); + att->name = gf_strdup(name); + att->data = gf_strdup(val); if (prev) prev->next = (GF_DOMAttribute*) att; else node->attributes = (GF_DOMAttribute*) att; goto exit; } - + if (n->sgprivate->tag==TAG_DOMText) { goto exit; } if (n->sgprivate->tag<=GF_NODE_RANGE_LAST_SVG) { GF_FieldInfo info; + u32 anim_value_type = 0; u32 ns_code = 0; if (ns) { ns_code = gf_sg_get_namespace_code_from_name(n->sgprivate->scenegraph, ns); } else { ns_code = gf_xml_get_element_namespace(n); } + if (!strcmp(name, "attributeName")) { + if (gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_attributeName, 0, 0, &info) == GF_OK) { + SMIL_AttributeName *attname = (SMIL_AttributeName *)info.far_ptr; + + /*parse the attribute name even if the target is not found, because a namespace could be specified and + only valid for the current node*/ + if (!attname->type) { + char *sep; + char *name = attname->name; + sep = strchr(name, ':'); + if (sep) { + sep[0] = 0; + attname->type = gf_sg_get_namespace_code(n->sgprivate->scenegraph, name); + sep[0] = ':'; + name = gf_strdup(sep+1); + gf_free(attname->name); + attname->name = name; + } + } + } + } + + if ((n->sgprivate->tag == TAG_SVG_animateTransform) && (strstr(name, "from") || strstr(name, "to")) ) { + if (gf_node_get_attribute_by_tag((GF_Node *)n, TAG_SVG_ATT_transform_type, 1, 0, &info) != GF_OK) + goto exit; + + switch(*(SVG_TransformType *) info.far_ptr) { + case SVG_TRANSFORM_TRANSLATE: anim_value_type = SVG_Transform_Translate_datatype; break; + case SVG_TRANSFORM_SCALE: anim_value_type = SVG_Transform_Scale_datatype; break; + case SVG_TRANSFORM_ROTATE: anim_value_type = SVG_Transform_Rotate_datatype; break; + case SVG_TRANSFORM_SKEWX: anim_value_type = SVG_Transform_SkewX_datatype; break; + case SVG_TRANSFORM_SKEWY: anim_value_type = SVG_Transform_SkewY_datatype; break; + case SVG_TRANSFORM_MATRIX: anim_value_type = SVG_Transform_datatype; break; + default: + goto exit; + } + } + + if (gf_node_get_attribute_by_name(n, name, ns_code, 1, 1, &info)==GF_OK) { - gf_svg_parse_attribute(n, &info, val, 0); + gf_svg_parse_attribute(n, &info, val, anim_value_type); if (info.fieldType==SVG_ID_datatype) { - gf_svg_parse_element_id(n, *(SVG_String*)info.far_ptr, 0); + char *idname = *(SVG_String*)info.far_ptr; + gf_svg_parse_element_id(n, idname, 0); + } + if (info.fieldType==XMLRI_datatype) { + gf_node_dirty_set(n, GF_SG_SVG_XLINK_HREF_DIRTY, 0); } dom_node_changed(n, 0, &info); goto exit; } } exit: - if (ns) free(ns); + if (ns) gf_free(ns); return JS_TRUE; } @@ -1821,7 +1965,7 @@ static JSBool xml_element_set_id(JSContext *c, JSObject *obj, uintN argc, jsval } if (is_id) { if (!name) return JS_TRUE; - gf_node_set_id(n, gf_sg_get_max_node_id(n->sgprivate->scenegraph) + 1, strdup(name) ); + gf_node_set_id(n, gf_sg_get_max_node_id(n->sgprivate->scenegraph) + 1, gf_strdup(name) ); } else if (node_id) { gf_node_remove_id(n); } @@ -1867,11 +2011,11 @@ static JSBool dom_text_setProperty(JSContext *c, JSObject *obj, jsval id, jsval switch (prop_id) { case 1: /*"data"*/ - if (txt->textContent) free(txt->textContent); + if (txt->textContent) gf_free(txt->textContent); txt->textContent = NULL; if (JSVAL_CHECK_STRING(*vp)) { char *str = js_get_utf8(*vp); - txt->textContent = str ? str : strdup("" ); + txt->textContent = str ? str : gf_strdup("" ); } dom_node_changed((GF_Node*)txt, 0, NULL); return JS_TRUE; @@ -1916,10 +2060,10 @@ static JSBool event_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp if (evt->is_vrml) return JS_TRUE; switch (evt->target_type) { case GF_DOM_EVENT_NODE: - *vp = dom_element_construct(c, (GF_Node*) evt->target); + *vp = dom_element_construct(c, (GF_Node*) evt->target); break; case GF_DOM_EVENT_DOCUMENT: - *vp = dom_document_construct(c, (GF_SceneGraph *) evt->target); + *vp = dom_document_construct(c, (GF_SceneGraph *) evt->target); break; } return JS_TRUE; @@ -1927,10 +2071,10 @@ static JSBool event_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp if (evt->is_vrml) return JS_TRUE; switch (evt->currentTarget->ptr_type) { case GF_DOM_EVENT_NODE: - *vp = dom_element_construct(c, (GF_Node*) evt->currentTarget->ptr); + *vp = dom_element_construct(c, (GF_Node*) evt->currentTarget->ptr); break; case GF_DOM_EVENT_DOCUMENT: - *vp = dom_document_construct(c, (GF_SceneGraph *) evt->currentTarget->ptr); + *vp = dom_document_construct(c, (GF_SceneGraph *) evt->currentTarget->ptr); break; } return JS_TRUE; @@ -1940,7 +2084,7 @@ static JSBool event_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp case 4: /*bubbles*/ *vp = BOOLEAN_TO_JSVAL(evt->bubbles ? JS_TRUE : JS_FALSE); return JS_TRUE; case 5: /*cancelable*/ - *vp = BOOLEAN_TO_JSVAL(evt->cancelable ? JS_TRUE : JS_FALSE); return JS_TRUE; + *vp = BOOLEAN_TO_JSVAL(evt->cancelable ? JS_TRUE : JS_FALSE); return JS_TRUE; case 6: /*namespaceURI*/ *vp = JSVAL_NULL; return JS_TRUE; @@ -1952,7 +2096,7 @@ static JSBool event_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp case 8: *vp = BOOLEAN_TO_JSVAL((evt->event_phase & GF_DOM_EVENT_PHASE_PREVENT) ? JS_TRUE : JS_FALSE); return JS_TRUE; - + case 20:/*detail*/ *vp = INT_TO_JSVAL(evt->detail); return JS_TRUE; @@ -1984,14 +2128,14 @@ static JSBool event_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp *vp = INT_TO_JSVAL(evt->button); return JS_TRUE; case 35:/*relatedTarget*/ if (evt->is_vrml) return JS_TRUE; - *vp = dom_element_construct(c, evt->relatedTarget); + *vp = dom_element_construct(c, evt->relatedTarget); return JS_TRUE; case 36:/*wheelDelta*/ *vp = INT_TO_JSVAL(FIX2INT(evt->new_scale) ); return JS_TRUE; - + /*DOM3 event keyIndentifier*/ - case 40: + case 40: s = JS_NewStringCopyZ(c, gf_dom_get_key_name(evt->detail) ); *vp = STRING_TO_JSVAL( s ); return JS_TRUE; @@ -2020,18 +2164,31 @@ static JSBool event_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp /*VRML ones*/ case 60:/*width*/ - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, evt->screen_rect.width) ); + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->screen_rect.width) ) ); return JS_TRUE; case 61:/*height*/ - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, evt->screen_rect.height) ); + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->screen_rect.height)) ); return JS_TRUE; - case 62:/*h_translation*/ - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, evt->new_translate.x) ); + case 62:/*offset_x*/ + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->screen_rect.x) ) ); return JS_TRUE; - case 63:/*v_translation*/ - *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, evt->new_translate.y) ); + case 63:/*offset_x*/ + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->screen_rect.y)) ); return JS_TRUE; - + case 64:/*vp_width*/ + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->prev_translate.x)) ); + return JS_TRUE; + case 65:/*vp_height*/ + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->prev_translate.y)) ); + return JS_TRUE; + case 66:/*translation_x*/ + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->new_translate.x)) ); + return JS_TRUE; + case 67:/*translation_y*/ + *vp = DOUBLE_TO_JSVAL( JS_NewDouble(c, FIX2FLT(evt->new_translate.y)) ); + return JS_TRUE; + case 68:/*type3d*/ + *vp = INT_TO_JSVAL(evt->detail); return JS_TRUE; default: return JS_TRUE; } @@ -2070,6 +2227,8 @@ typedef struct GF_List *node_stack; /*dom graph*/ GF_SceneGraph *document; + + Bool use_cache; } XMLHTTPContext; static void xml_http_append_send_header(XMLHTTPContext *ctx, char *hdr, char *val) @@ -2096,7 +2255,7 @@ static void xml_http_append_send_header(XMLHTTPContext *ctx, char *hdr, char *va || !stricmp(hdr, "TE") || !stricmp(hdr, "Trailer") || !stricmp(hdr, "Transfer-Encoding") - || !stricmp(hdr, "Upgrade") + || !stricmp(hdr, "Upgrade") ) { return; } @@ -2123,15 +2282,15 @@ static void xml_http_append_send_header(XMLHTTPContext *ctx, char *hdr, char *va || !stricmp(hdr, "Proxy-Authorization") || !stricmp(hdr, "SOAPAction") || !stricmp(hdr, "Timeout") ) { - free(ctx->headers[nb_hdr+1]); - ctx->headers[nb_hdr+1] = strdup(val); + gf_free(ctx->headers[nb_hdr+1]); + ctx->headers[nb_hdr+1] = gf_strdup(val); return; } /*append value*/ else { - char *new_val = malloc(sizeof(char) * (strlen(ctx->headers[nb_hdr+1])+strlen(val)+3)); + char *new_val = gf_malloc(sizeof(char) * (strlen(ctx->headers[nb_hdr+1])+strlen(val)+3)); sprintf(new_val, "%s, %s", ctx->headers[nb_hdr+1], val); - free(ctx->headers[nb_hdr+1]); + gf_free(ctx->headers[nb_hdr+1]); ctx->headers[nb_hdr+1] = new_val; return; } @@ -2142,9 +2301,9 @@ static void xml_http_append_send_header(XMLHTTPContext *ctx, char *hdr, char *va if (ctx->headers) { while (ctx->headers[nb_hdr]) nb_hdr+=2; } - ctx->headers = realloc(ctx->headers, sizeof(char*)*(nb_hdr+3)); - ctx->headers[nb_hdr] = strdup(hdr); - ctx->headers[nb_hdr+1] = strdup(val ? val : ""); + ctx->headers = gf_realloc(ctx->headers, sizeof(char*)*(nb_hdr+3)); + ctx->headers[nb_hdr] = gf_strdup(hdr); + ctx->headers[nb_hdr+1] = gf_strdup(val ? val : ""); ctx->headers[nb_hdr+2] = NULL; } @@ -2153,11 +2312,11 @@ static void xml_http_reset_recv_hdr(XMLHTTPContext *ctx) u32 nb_hdr = 0; if (ctx->recv_headers) { while (ctx->recv_headers[nb_hdr]) { - free(ctx->recv_headers[nb_hdr]); - free(ctx->recv_headers[nb_hdr+1]); + gf_free(ctx->recv_headers[nb_hdr]); + gf_free(ctx->recv_headers[nb_hdr+1]); nb_hdr+=2; } - free(ctx->recv_headers); + gf_free(ctx->recv_headers); ctx->recv_headers = NULL; } } @@ -2167,9 +2326,9 @@ static void xml_http_append_recv_header(XMLHTTPContext *ctx, char *hdr, char *va if (ctx->recv_headers) { while (ctx->recv_headers[nb_hdr]) nb_hdr+=2; } - ctx->recv_headers = realloc(ctx->recv_headers, sizeof(char*)*(nb_hdr+3)); - ctx->recv_headers[nb_hdr] = strdup(hdr); - ctx->recv_headers[nb_hdr+1] = strdup(val ? val : ""); + ctx->recv_headers = gf_realloc(ctx->recv_headers, sizeof(char*)*(nb_hdr+3)); + ctx->recv_headers[nb_hdr] = gf_strdup(hdr); + ctx->recv_headers[nb_hdr+1] = gf_strdup(val ? val : ""); ctx->recv_headers[nb_hdr+2] = NULL; } @@ -2177,17 +2336,17 @@ static void xml_http_append_recv_header(XMLHTTPContext *ctx, char *hdr, char *va static void xml_http_reset(XMLHTTPContext *ctx) { u32 nb_hdr = 0; - if (ctx->method) { free(ctx->method); ctx->method = NULL; } - if (ctx->url) { free(ctx->url); ctx->url = NULL; } + if (ctx->method) { gf_free(ctx->method); ctx->method = NULL; } + if (ctx->url) { gf_free(ctx->url); ctx->url = NULL; } xml_http_reset_recv_hdr(ctx); if (ctx->headers) { while (ctx->headers[nb_hdr]) { - free(ctx->headers[nb_hdr]); - free(ctx->headers[nb_hdr+1]); + gf_free(ctx->headers[nb_hdr]); + gf_free(ctx->headers[nb_hdr+1]); nb_hdr+=2; } - free(ctx->headers); + gf_free(ctx->headers); ctx->headers = NULL; } if (ctx->sess) { @@ -2195,15 +2354,15 @@ static void xml_http_reset(XMLHTTPContext *ctx) ctx->sess = NULL; } if (ctx->data) { - free(ctx->data); + gf_free(ctx->data); ctx->data = NULL; } if (ctx->statusText) { - free(ctx->statusText); + gf_free(ctx->statusText); ctx->statusText = NULL; } if (ctx->url) { - free(ctx->url); + gf_free(ctx->url); ctx->url = NULL; } if (ctx->sax) { @@ -2219,6 +2378,7 @@ static void xml_http_reset(XMLHTTPContext *ctx) /*we're sure the graph is a "nomade" one since we initially put the refcount to 1 ourselves*/ ctx->document->reference_count--; if (!ctx->document->reference_count) { + dom_js_pre_destroy(ctx->c, ctx->document, NULL); gf_sg_del(ctx->document); } } @@ -2237,8 +2397,9 @@ static void xml_http_finalize(JSContext *c, JSObject *obj) if (!JS_InstanceOf(c, obj, &dom_rt->xmlHTTPRequestClass, NULL) ) return; ctx = (XMLHTTPContext *)JS_GetPrivate(c, obj); if (ctx) { + if (ctx->onreadystatechange) gf_js_remove_root(c, &(ctx->onreadystatechange)); xml_http_reset(ctx); - free(ctx); + gf_free(ctx); } } static JSBool xml_http_constructor(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) @@ -2255,12 +2416,23 @@ static JSBool xml_http_constructor(JSContext *c, JSObject *obj, uintN argc, jsva static void xml_http_state_change(XMLHTTPContext *ctx) { + GF_SceneGraph *scene; + GF_Node *n; jsval rval; //GF_SceneGraph *scene = (GF_SceneGraph *) xml_get_scenegraph(ctx->c); if (ctx->onreadystatechange) JS_CallFunction(ctx->c, ctx->_this, ctx->onreadystatechange, 0, NULL, &rval); - /*todo - fire event*/ + /*todo - fire XHR events*/ + + /*Flush BIFS eventOut events*/ +#ifndef GPAC_DISABLE_VRML + scene = JS_GetContextPrivate(ctx->c); + /*this is a scene, we look for a node (if scene is used, this is DOM-based scripting not VRML*/ + if (scene->__reserved_null == 0) return; + n = JS_GetContextPrivate(ctx->c); + gf_js_vrml_flush_event_out(n, (GF_ScriptPriv *)n->sgprivate->UserPrivate); +#endif } @@ -2290,16 +2462,18 @@ static JSBool xml_http_open(JSContext *c, JSObject *obj, uintN argc, jsval *argv && strcmp(val, "PUT") && strcmp(val, "DELETE") && strcmp(val, "OPTIONS") ) return JS_TRUE; - ctx->method = strdup(val); + ctx->method = gf_strdup(val); - val = JSVAL_GET_STRING(argv[1]); /*concatenate URL*/ scene = xml_get_scenegraph(c); +#ifndef GPAC_DISABLE_VRML while (scene->pOwningProto && scene->parent_scene) scene = scene->parent_scene; - ScriptAction(scene, GF_JSAPI_OP_GET_SCENE_URI, scene->RootNode, &par); +#endif - if (par.uri.url) ctx->url = gf_url_concatenate(par.uri.url, val); - if (!ctx->url) ctx->url = strdup(val); + par.uri.nb_params = 0; + par.uri.url = JSVAL_GET_STRING(argv[1]); + ScriptAction(scene, GF_JSAPI_OP_RESOLVE_URI, scene->RootNode, &par); + ctx->url = (char *)par.uri.url; /*async defaults to true*/ ctx->async = 1; @@ -2348,10 +2522,10 @@ static void xml_http_sax_start(void *sax_cbck, const char *node_name, const char XMLHTTPContext *ctx = (XMLHTTPContext *)sax_cbck; GF_DOMFullNode *node = (GF_DOMFullNode *) gf_node_new(ctx->document, TAG_DOMFullNode); - node->name = strdup(node_name); + node->name = gf_strdup(node_name); for (i=0; i<nb_attributes; i++) { - /* special case for 'xml:id' to be parsed as an ID - NOTE: we do not test for the 'id' attribute because without DTD we are not sure that it's an ID */ + /* special case for 'xml:id' to be parsed as an ID + NOTE: we do not test for the 'id' attribute because without DTD we are not sure that it's an ID */ if (!stricmp(attributes[i].name, "xml:id")) { u32 id = gf_sg_get_max_node_id(ctx->document) + 1; gf_node_set_id((GF_Node *)node, id, attributes[i].value); @@ -2359,8 +2533,10 @@ static void xml_http_sax_start(void *sax_cbck, const char *node_name, const char GF_DOMFullAttribute *att; GF_SAFEALLOC(att, GF_DOMFullAttribute); att->tag = TAG_DOM_ATT_any; - att->name = strdup(attributes[i].name); - att->data = strdup(attributes[i].value); + att->name = gf_strdup(attributes[i].name); + att->data_type = (u16) DOM_String_datatype; + att->data = gf_svg_create_attribute_value(att->data_type); + *((char **)att->data) = gf_strdup(attributes[i].value); if (prev) prev->next = (GF_DOMAttribute*)att; else node->attributes = (GF_DOMAttribute*)att; prev = att; @@ -2401,11 +2577,13 @@ static void xml_http_sax_text(void *sax_cbck, const char *content, Bool is_cdata } if (i==len) return; - txt = gf_dom_add_text_node((GF_Node *)par, strdup(content) ); + txt = gf_dom_add_text_node((GF_Node *)par, gf_strdup(content) ); txt->type = is_cdata ? GF_DOM_TEXT_CDATA : GF_DOM_TEXT_REGULAR; } } +#define USE_PROGRESSIVE_SAX 0 + static void xml_http_on_data(void *usr_cbk, GF_NETIO_Parameter *parameter) { XMLHTTPContext *ctx = (XMLHTTPContext *)usr_cbk; @@ -2422,13 +2600,13 @@ static void xml_http_on_data(void *usr_cbk, GF_NETIO_Parameter *parameter) return; case GF_NETIO_WAIT_FOR_REPLY: /*reset send() state (data, current header) and prepare recv headers*/ - if (ctx->data) free(ctx->data); + if (ctx->data) gf_free(ctx->data); ctx->data = NULL; ctx->size = 0; ctx->cur_header = 0; ctx->html_status = 0; if (ctx->statusText) { - free(ctx->statusText); + gf_free(ctx->statusText); ctx->statusText = NULL; } xml_http_reset_recv_hdr(ctx); @@ -2439,7 +2617,7 @@ static void xml_http_on_data(void *usr_cbk, GF_NETIO_Parameter *parameter) case GF_NETIO_PARSE_REPLY: ctx->html_status = parameter->reply; if (parameter->value) { - ctx->statusText = strdup(parameter->value); + ctx->statusText = gf_strdup(parameter->value); } ctx->readyState = 3; xml_http_state_change(ctx); @@ -2476,10 +2654,13 @@ static void xml_http_on_data(void *usr_cbk, GF_NETIO_Parameter *parameter) ctx->document = gf_sg_new(); /*mark this doc as "nomade", and let it leave until all references to it are destroyed*/ ctx->document->reference_count = 1; + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[XmlHttpRequest] content type %s not supported\n", parameter->value)); } return; case GF_NETIO_DATA_EXCHANGE: if (parameter->data && parameter->size) { +#if USE_PROGRESSIVE_SAX if (ctx->sax) { GF_Err e; if (!ctx->size) e = gf_xml_sax_init(ctx->sax, parameter->data); @@ -2489,13 +2670,27 @@ static void xml_http_on_data(void *usr_cbk, GF_NETIO_Parameter *parameter) ctx->sax = NULL; } } - ctx->data = realloc(ctx->data, sizeof(char)*(ctx->size+parameter->size+1)); +#endif + ctx->data = gf_realloc(ctx->data, sizeof(char)*(ctx->size+parameter->size+1)); memcpy(ctx->data + ctx->size, parameter->data, sizeof(char)*parameter->size); ctx->size += parameter->size; ctx->data[ctx->size] = 0; } return; case GF_NETIO_DATA_TRANSFERED: + if (ctx->sax) { + if(ctx->use_cache ) { + const char *filename; + ctx->sax = gf_xml_sax_new(xml_http_sax_start, xml_http_sax_end, xml_http_sax_text, ctx); + filename = gf_dm_sess_get_cache_name(ctx->sess); + gf_xml_sax_parse_file(ctx->sax, filename, NULL); + } +#if !USE_PROGRESSIVE_SAX + else { + gf_xml_sax_init(ctx->sax, ctx->data); + } +#endif + } break; case GF_NETIO_DISCONNECTED: return; @@ -2509,7 +2704,7 @@ static void xml_http_on_data(void *usr_cbk, GF_NETIO_Parameter *parameter) gf_dm_sess_del(ctx->sess); ctx->sess = NULL; } - + /*error, complete reset*/ if (parameter->error) { xml_http_reset(ctx); @@ -2538,7 +2733,7 @@ static JSBool xml_http_send(JSContext *c, JSObject *obj, uintN argc, jsval *argv 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; - + /*NOT SUPPORTED YET, we must serialize the sg*/ return JS_TRUE; } else { @@ -2553,18 +2748,68 @@ static JSBool xml_http_send(JSContext *c, JSObject *obj, uintN argc, jsval *argv if (!par.dnld_man) return JS_TRUE; /*reset previous text*/ - if (ctx->data) free(ctx->data); + if (ctx->data) gf_free(ctx->data); - ctx->data = data ? strdup(data) : NULL; - ctx->sess = gf_dm_sess_new(par.dnld_man, ctx->url, GF_NETIO_SESSION_NOT_CACHED, xml_http_on_data, ctx, &e); - if (!ctx->sess) return JS_TRUE; + ctx->data = data ? gf_strdup(data) : NULL; + ctx->use_cache = 0; + if (!strncmp(ctx->url, "http://", 7)) { + ctx->sess = gf_dm_sess_new(par.dnld_man, ctx->url, (ctx->use_cache ? 0 : GF_NETIO_SESSION_NOT_CACHED), xml_http_on_data, ctx, &e); + + if (!ctx->sess) return JS_TRUE; + + /*just wait for destruction*/ + if (!ctx->async) { + while (ctx->sess) { + gf_sleep(20); + } + } + } else { + u64 fsize; + FILE * xmlf; + + if (ctx->data) gf_free(ctx->data); + ctx->data = NULL; + ctx->size = 0; + ctx->cur_header = 0; + ctx->html_status = 0; + if (ctx->statusText) { + gf_free(ctx->statusText); + ctx->statusText = NULL; + } - /*just wait for destruction*/ - if (!ctx->async) { - while (ctx->sess) { - gf_sleep(20); + xmlf = gf_f64_open(ctx->url, "rt"); + if (!xmlf) { + ctx->html_status = 404; + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[XmlHttpRequest] cannot parse %s\n", ctx->url)); + return JS_TRUE; } + ctx->readyState = 2; + xml_http_state_change(ctx); + + gf_f64_seek(xmlf, 0, SEEK_END); + fsize = gf_f64_tell(xmlf); + gf_f64_seek(xmlf, 0, SEEK_SET); + + ctx->data = gf_malloc(sizeof(char)*(size_t)(fsize+1)); + fsize = fread(ctx->data, sizeof(char), (size_t)fsize, xmlf); + fclose(xmlf); + ctx->data[fsize] = 0; + + ctx->sax = gf_xml_sax_new(xml_http_sax_start, xml_http_sax_end, xml_http_sax_text, ctx); + ctx->node_stack = gf_list_new(); + ctx->document = gf_sg_new(); + /*mark this doc as "nomade", and let it leave until all references to it are destroyed*/ + ctx->document->reference_count = 1; + + gf_xml_sax_parse_file(ctx->sax, ctx->url, NULL); + + ctx->readyState = 3; + xml_http_state_change(ctx); + ctx->readyState = 4; + ctx->html_status = 200; + xml_http_state_change(ctx); } + return JS_TRUE; } @@ -2664,18 +2909,18 @@ static JSBool xml_http_getProperty(JSContext *c, JSObject *obj, jsval id, jsval if (JSVAL_IS_INT(id)) { switch (JSVAL_TO_INT(id)) { /*onreadystatechange*/ - case 0: + case 0: if (ctx->onreadystatechange) { - *vp = OBJECT_TO_JSVAL(ctx->onreadystatechange); + *vp = OBJECT_TO_JSVAL((JSObject*)ctx->onreadystatechange); } else { *vp = JSVAL_VOID; } return JS_TRUE; /*readyState*/ - case 1: + case 1: *vp = INT_TO_JSVAL(ctx->readyState); return JS_TRUE; /*responseText*/ - case 2: + case 2: if (ctx->readyState<3) return JS_TRUE; if (ctx->data) { s = JS_NewStringCopyZ(c, ctx->data); @@ -2685,15 +2930,19 @@ static JSBool xml_http_getProperty(JSContext *c, JSObject *obj, jsval id, jsval } return JS_TRUE; /*responseXML*/ - case 3: + case 3: if (ctx->readyState<3) return JS_TRUE; - *vp = dom_document_construct(c, ctx->document); + if (ctx->data) { + *vp = dom_document_construct(c, ctx->document); + } else { + *vp = JSVAL_VOID; + } return JS_TRUE; /*status*/ - case 4: + case 4: *vp = INT_TO_JSVAL(ctx->html_status); return JS_TRUE; /*statusText*/ - case 5: + case 5: if (ctx->statusText) { s = JS_NewStringCopyZ(c, ctx->statusText); *vp = STRING_TO_JSVAL( s ); @@ -2719,12 +2968,14 @@ static JSBool xml_http_setProperty(JSContext *c, JSObject *obj, jsval id, jsval if (JSVAL_IS_INT(id)) { switch (JSVAL_TO_INT(id)) { /*onreadystatechange*/ - case 0: + case 0: break; /*all other properties are read-only*/ default: return JS_TRUE; } + if (ctx->onreadystatechange) gf_js_remove_root(c, &(ctx->onreadystatechange)); + if (JSVAL_IS_VOID(*vp)) { ctx->onreadystatechange = NULL; return JS_TRUE; @@ -2734,11 +2985,10 @@ static JSBool xml_http_setProperty(JSContext *c, JSObject *obj, jsval id, jsval char *callback = JSVAL_GET_STRING(*vp); if (! JS_LookupProperty(c, JS_GetGlobalObject(c), callback, &fval)) return JS_TRUE; ctx->onreadystatechange = JS_ValueToFunction(c, fval); - if (ctx->onreadystatechange) return JS_TRUE; } else if (JSVAL_IS_OBJECT(*vp)) { ctx->onreadystatechange = JS_ValueToFunction(c, *vp); - if (ctx->onreadystatechange) return JS_TRUE; } + if (ctx->onreadystatechange) gf_js_add_root(c, &(ctx->onreadystatechange)); return JS_TRUE; } return JS_TRUE; @@ -2775,7 +3025,7 @@ static JSBool dcci_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) *vp = JSVAL_NULL; return JS_TRUE; /*valueType*/ - case 1: + case 1: value = "DOMString"; att = (GF_DOMFullAttribute*) n->attributes; while (att) { @@ -2789,7 +3039,7 @@ static JSBool dcci_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) *vp = STRING_TO_JSVAL( s ); return JS_TRUE; /*propertyType*/ - case 2: + case 2: value = "DOMString"; att = (GF_DOMFullAttribute*) n->attributes; while (att) { @@ -2803,7 +3053,7 @@ static JSBool dcci_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) *vp = STRING_TO_JSVAL( s ); return JS_TRUE; /*readOnly*/ - case 3: + case 3: att = (GF_DOMFullAttribute*) n->attributes; while (att) { if (att->name && !strcmp(att->name, "readOnly") && att->data && !strcmp(att->data, "true")) { @@ -2815,15 +3065,15 @@ static JSBool dcci_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) *vp = BOOLEAN_TO_JSVAL(JS_FALSE); return JS_TRUE; /*DCCIMetadataInterfaceType*/ - case 4: + case 4: *vp = JSVAL_NULL; return JS_TRUE; /*DCCIMetadataInterface*/ - case 5: + case 5: *vp = JSVAL_NULL; return JS_TRUE; /*version*/ - case 6: + case 6: s = JS_NewStringCopyZ(c, "1.0"); *vp = STRING_TO_JSVAL( s ); return JS_TRUE; @@ -2851,7 +3101,7 @@ static JSBool dcci_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) if (JSVAL_IS_INT(id)) { switch (JSVAL_TO_INT(id)) { /*value*/ - case 0: + case 0: dcci_getProperty(c, obj, INT_TO_JSVAL(3), &readonly); if (JSVAL_TO_BOOLEAN(readonly) == JS_TRUE) return JS_TRUE; child = n->children; @@ -2859,8 +3109,8 @@ static JSBool dcci_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) if (child->node && (child->node->sgprivate->tag==TAG_DOMText)) { GF_DOMText *txt = (GF_DOMText *)child->node; if (txt->type==GF_DOM_TEXT_REGULAR) { - if (txt->textContent) free(txt->textContent); - txt->textContent = strdup(str); + if (txt->textContent) gf_free(txt->textContent); + txt->textContent = gf_strdup(str); break; } @@ -2868,7 +3118,7 @@ static JSBool dcci_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) child = child->next; } if (!child) - gf_dom_add_text_node((GF_Node*)n, strdup(str) ); + gf_dom_add_text_node((GF_Node*)n, gf_strdup(str) ); memset(&evt, 0, sizeof(GF_DOM_Event)); evt.type = GF_EVENT_DCCI_PROP_CHANGE; @@ -2878,7 +3128,7 @@ static JSBool dcci_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) n->sgprivate->scenegraph->modified = 1; return JS_TRUE; /*propertyType*/ - case 2: + case 2: return JS_TRUE; /*all other properties are read-only*/ @@ -2900,7 +3150,7 @@ Bool dcci_prop_lookup(GF_DOMFullNode *n, char *ns, char *name, Bool deep, Bool f /*name mismatch*/ if (strcmp(name, "*") && n->name && strcmp(name, n->name)) ok = 0; - + /*"Some DCCIProperty nodes may not have a value"*/ if (ok) return 1; @@ -2948,7 +3198,7 @@ void dcci_prop_collect(DOMNodeList *nl, GF_DOMFullNode *n, char *ns, char *name, /*name mismatch*/ if (strcmp(name, "*") && n->name && strcmp(name, n->name)) ok = 0; - + /*"Some DCCIProperty nodes may not have a value"*/ if (ok) { gf_node_register((GF_Node*)n, NULL); @@ -2994,10 +3244,38 @@ static JSBool dcci_search_property(JSContext *c, JSObject *obj, uintN argc, jsva return JS_TRUE; } +static JSBool storage_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + if (!JS_InstanceOf(c, obj, &dom_rt->storageClass, NULL) ) return JS_TRUE; + return JS_TRUE; +} + +static JSBool storage_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) +{ + if (!JS_InstanceOf(c, obj, &dom_rt->storageClass, NULL) ) return JS_TRUE; + return JS_TRUE; +} + +static JSBool storage_constructor(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + if (!JS_InstanceOf(c, obj, &dom_rt->storageClass, NULL) ) return JS_TRUE; + return JS_TRUE; +} + +static void storage_finalize(JSContext *c, JSObject *obj) +{ +} + +void dom_js_define_storage(JSContext *c, JSObject *parent_obj, const char *name) +{ + JS_DefineObject(c, parent_obj, name, &dom_rt->storageClass, 0, 0 ); +} + void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global) { if (!dom_rt) { GF_SAFEALLOC(dom_rt, GF_DOMRuntime); + dom_rt->handlers = gf_list_new(); JS_SETUP_CLASS(dom_rt->domNodeClass, "Node", JSCLASS_HAS_PRIVATE, dom_node_getProperty, dom_node_setProperty, dom_node_finalize); JS_SETUP_CLASS(dom_rt->domDocumentClass, "Document", JSCLASS_HAS_PRIVATE, dom_document_getProperty, dom_document_setProperty, dom_document_finalize); /*Element uses the same destructor as node*/ @@ -3010,56 +3288,63 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global) JS_SETUP_CLASS(dom_rt->domNodeListClass, "NodeList", JSCLASS_HAS_PRIVATE, dom_nodelist_getProperty, dom_nodelist_setProperty, dom_nodelist_finalize); JS_SETUP_CLASS(dom_rt->xmlHTTPRequestClass, "XMLHttpRequest", JSCLASS_HAS_PRIVATE, xml_http_getProperty, xml_http_setProperty, xml_http_finalize); + JS_SETUP_CLASS(dom_rt->storageClass, "Storage", JSCLASS_HAS_PRIVATE, storage_getProperty, storage_setProperty, storage_finalize); JS_SETUP_CLASS(dom_rt->DCCIClass, "DCCI", JSCLASS_HAS_PRIVATE, dcci_getProperty, dcci_setProperty, dom_node_finalize); GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] dom run-time allocated\n")); } dom_rt->nb_inst++; - + define_dom_exception(c, global); { JSFunctionSpec nodeFuncs[] = { - {"insertBefore", xml_node_insert_before, 2}, - {"replaceChild", xml_node_replace_child, 2}, - {"removeChild", xml_node_remove_child, 1}, - {"appendChild", xml_node_append_child, 1}, - {"hasChildNodes", xml_node_has_children, 0}, - {"cloneNode", xml_clone_node, 1}, - {"normalize", xml_dom3_not_implemented, 0}, - {"isSupported", xml_dom3_not_implemented, 2}, - {"hasAttributes", xml_node_has_attributes, 0}, - {"compareDocumentPosition", xml_dom3_not_implemented, 1}, - {"isSameNode", xml_node_is_same_node, 1}, - {"lookupPrefix", xml_dom3_not_implemented, 1}, - {"isDefaultNamespace", xml_dom3_not_implemented, 1}, - {"lookupNamespaceURI", xml_dom3_not_implemented, 1}, + {"insertBefore", xml_node_insert_before, 2, 0, 0}, + {"replaceChild", xml_node_replace_child, 2, 0, 0}, + {"removeChild", xml_node_remove_child, 1, 0, 0}, + {"appendChild", xml_node_append_child, 1, 0, 0}, + {"hasChildNodes", xml_node_has_children, 0, 0, 0}, + {"cloneNode", xml_clone_node, 1, 0, 0}, + {"normalize", xml_dom3_not_implemented, 0, 0, 0}, + {"isSupported", xml_dom3_not_implemented, 2, 0, 0}, + {"hasAttributes", xml_node_has_attributes, 0, 0, 0}, + {"compareDocumentPosition", xml_dom3_not_implemented, 1, 0, 0}, + {"isSameNode", xml_node_is_same_node, 1, 0, 0}, + {"lookupPrefix", xml_dom3_not_implemented, 1, 0, 0}, + {"isDefaultNamespace", xml_dom3_not_implemented, 1, 0, 0}, + {"lookupNamespaceURI", xml_dom3_not_implemented, 1, 0, 0}, /*we don't support full node compare*/ - {"isEqualNode", xml_node_is_same_node, 1}, - {"getFeature", xml_dom3_not_implemented, 2}, - {"setUserData", xml_dom3_not_implemented, 3}, - {"getUserData", xml_dom3_not_implemented, 1}, - {0} + {"isEqualNode", xml_node_is_same_node, 1, 0, 0}, + {"getFeature", xml_dom3_not_implemented, 2, 0, 0}, + {"setUserData", xml_dom3_not_implemented, 3, 0, 0}, + {"getUserData", xml_dom3_not_implemented, 1, 0, 0}, + {0, 0, 0, 0, 0} }; JSPropertySpec nodeProps[] = { - {"nodeName", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"nodeValue", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"nodeType", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"parentNode", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"childNodes", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"firstChild", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"lastChild", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"previousSibling", 7, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"nextSibling", 8, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"attributes", 9, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"ownerDocument", 10, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"namespaceURI", 11, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"prefix", 12, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"localName", 13, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"baseURI", 14, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"textContent", 15, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {0} + {"nodeName", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"nodeValue", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"nodeType", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"parentNode", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"childNodes", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"firstChild", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"lastChild", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"previousSibling", 7, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"nextSibling", 8, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"attributes", 9, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"ownerDocument", 10, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"namespaceURI", 11, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"prefix", 12, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"localName", 13, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"baseURI", 14, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"textContent", 15, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + /*elementTraversal interface*/ + {"firstElementChild", 16, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"lastElementChild", 17, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"previousElementSibling", 18, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"nextElementSibling", 19, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + + {0, 0, 0, 0, 0} }; dom_rt->dom_node_proto = JS_InitClass(c, global, 0, &dom_rt->domNodeClass, 0, 0, nodeProps, nodeFuncs, 0, 0); GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] node class initialized\n")); @@ -3072,77 +3357,77 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global) } { JSFunctionSpec documentFuncs[] = { - {"createElement", xml_document_create_element, 1}, - {"createDocumentFragment", xml_dom3_not_implemented, 0}, - {"createTextNode", xml_document_create_text, 1}, - {"createComment", xml_dom3_not_implemented, 1}, - {"createCDATASection", xml_dom3_not_implemented, 1}, - {"createProcessingInstruction", xml_dom3_not_implemented, 2}, - {"createAttribute", xml_dom3_not_implemented, 1}, - {"createEntityReference", xml_dom3_not_implemented, 1}, - {"getElementsByTagName", xml_document_elements_by_tag, 1}, - {"importNode", xml_dom3_not_implemented, 2}, - {"createElementNS", xml_document_create_element, 2}, - {"createAttributeNS", xml_dom3_not_implemented, 2}, - {"getElementsByTagNameNS", xml_document_elements_by_tag, 2}, - {"getElementById", xml_document_element_by_id, 1}, - {"adoptNode", xml_dom3_not_implemented, 1}, - {"normalizeDocument", xml_dom3_not_implemented, 0}, - {"renameNode", xml_dom3_not_implemented, 3}, + {"createElement", xml_document_create_element, 1, 0, 0}, + {"createDocumentFragment", xml_dom3_not_implemented, 0, 0, 0}, + {"createTextNode", xml_document_create_text, 1, 0, 0}, + {"createComment", xml_dom3_not_implemented, 1, 0, 0}, + {"createCDATASection", xml_dom3_not_implemented, 1, 0, 0}, + {"createProcessingInstruction", xml_dom3_not_implemented, 2, 0, 0}, + {"createAttribute", xml_dom3_not_implemented, 1, 0, 0}, + {"createEntityReference", xml_dom3_not_implemented, 1, 0, 0}, + {"getElementsByTagName", xml_document_elements_by_tag, 1, 0, 0}, + {"importNode", xml_dom3_not_implemented, 2, 0, 0}, + {"createElementNS", xml_document_create_element, 2, 0, 0}, + {"createAttributeNS", xml_dom3_not_implemented, 2, 0, 0}, + {"getElementsByTagNameNS", xml_document_elements_by_tag, 2, 0, 0}, + {"getElementById", xml_document_element_by_id, 1, 0, 0}, + {"adoptNode", xml_dom3_not_implemented, 1, 0, 0}, + {"normalizeDocument", xml_dom3_not_implemented, 0, 0, 0}, + {"renameNode", xml_dom3_not_implemented, 3, 0, 0}, /*eventTarget interface*/ JS_DOM3_EVEN_TARGET_INTERFACE /*DocumentEvent interface*/ - {"createEvent", xml_dom3_not_implemented, 1}, - {0} + {"createEvent", xml_dom3_not_implemented, 1, 0, 0}, + {0, 0, 0, 0, 0} }; JSPropertySpec documentProps[] = { - {"doctype", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"implementation", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"documentElement", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"inputEncoding", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"xmlEncoding", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"xmlStandalone", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"xmlVersion", 7, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"strictErrorChecking", 8, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"documentURI", 9, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"domConfig", 10, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {0} + {"doctype", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"implementation", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"documentElement", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"inputEncoding", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"xmlEncoding", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"xmlStandalone", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"xmlVersion", 7, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"strictErrorChecking", 8, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"documentURI", 9, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"domConfig", 10, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {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_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] document class initialized\n")); } - + { JSFunctionSpec elementFuncs[] = { - {"getAttribute", xml_element_get_attribute, 1}, - {"setAttribute", xml_element_set_attribute, 2}, - {"removeAttribute", xml_element_remove_attribute, 1}, - {"getAttributeNS", xml_element_get_attribute, 2}, - {"setAttributeNS", xml_element_set_attribute, 3}, - {"removeAttributeNS", xml_element_remove_attribute, 2}, - {"hasAttribute", xml_element_has_attribute, 1}, - {"hasAttributeNS", xml_element_has_attribute, 2}, - {"getElementsByTagName", xml_element_elements_by_tag, 1}, - {"getElementsByTagNameNS", xml_element_elements_by_tag, 2}, - {"setIdAttribute", xml_element_set_id, 2}, - {"setIdAttributeNS", xml_element_set_id, 3}, - {"getAttributeNode", xml_dom3_not_implemented, 1}, - {"setAttributeNode", xml_dom3_not_implemented, 1}, - {"removeAttributeNode", xml_dom3_not_implemented, 1}, - {"getAttributeNodeNS", xml_dom3_not_implemented, 2}, - {"setAttributeNodeNS", xml_dom3_not_implemented, 1}, - {"setIdAttributeNode", xml_dom3_not_implemented, 2}, + {"getAttribute", xml_element_get_attribute, 1, 0, 0}, + {"setAttribute", xml_element_set_attribute, 2, 0, 0}, + {"removeAttribute", xml_element_remove_attribute, 1, 0, 0}, + {"getAttributeNS", xml_element_get_attribute, 2, 0, 0}, + {"setAttributeNS", xml_element_set_attribute, 3, 0, 0}, + {"removeAttributeNS", xml_element_remove_attribute, 2, 0, 0}, + {"hasAttribute", xml_element_has_attribute, 1, 0, 0}, + {"hasAttributeNS", xml_element_has_attribute, 2, 0, 0}, + {"getElementsByTagName", xml_element_elements_by_tag, 1, 0, 0}, + {"getElementsByTagNameNS", xml_element_elements_by_tag, 2, 0, 0}, + {"setIdAttribute", xml_element_set_id, 2, 0, 0}, + {"setIdAttributeNS", xml_element_set_id, 3, 0, 0}, + {"getAttributeNode", xml_dom3_not_implemented, 1, 0, 0}, + {"setAttributeNode", xml_dom3_not_implemented, 1, 0, 0}, + {"removeAttributeNode", xml_dom3_not_implemented, 1, 0, 0}, + {"getAttributeNodeNS", xml_dom3_not_implemented, 2, 0, 0}, + {"setAttributeNodeNS", xml_dom3_not_implemented, 1, 0, 0}, + {"setIdAttributeNode", xml_dom3_not_implemented, 2, 0, 0}, /*eventTarget interface*/ JS_DOM3_EVEN_TARGET_INTERFACE - {0} + {0, 0, 0, 0, 0} }; JSPropertySpec elementProps[] = { - {"tagName", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"schemaTypeInfo", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {0} + {"tagName", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"schemaTypeInfo", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | 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_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] element class initialized\n")); @@ -3151,89 +3436,94 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global) { JSFunctionSpec textFuncs[] = { #if 0 - {"substringData", xml_dom3_not_implemented, 2}, - {"appendData", xml_dom3_not_implemented, 1}, - {"insertData", xml_dom3_not_implemented, 2}, - {"deleteData", xml_dom3_not_implemented, 2}, - {"replaceData", xml_dom3_not_implemented, 3}, + {"substringData", xml_dom3_not_implemented, 2, 0, 0}, + {"appendData", xml_dom3_not_implemented, 1, 0, 0}, + {"insertData", xml_dom3_not_implemented, 2, 0, 0}, + {"deleteData", xml_dom3_not_implemented, 2, 0, 0}, + {"replaceData", xml_dom3_not_implemented, 3, 0, 0}, /*text*/ - {"splitText", xml_dom3_not_implemented, 1}, - {"replaceWholeText", xml_dom3_not_implemented, 1}, + {"splitText", xml_dom3_not_implemented, 1, 0, 0}, + {"replaceWholeText", xml_dom3_not_implemented, 1, 0, 0}, #endif - {0} + {0, 0, 0, 0, 0} }; JSPropertySpec textProps[] = { - {"data", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"length", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"data", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"length", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, /*text*/ - {"isElementContentWhitespace", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"wholeText", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {0} + {"isElementContentWhitespace", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"wholeText", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | 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_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] text class initialized\n")); } - + /*event API*/ { JSFunctionSpec eventFuncs[] = { - {"stopPropagation", event_stop_propagation, 0}, - {"stopImmediatePropagation", event_stop_immediate_propagation, 0}, - {"preventDefault", event_prevent_default, 0}, + {"stopPropagation", event_stop_propagation, 0, 0, 0}, + {"stopImmediatePropagation", event_stop_immediate_propagation, 0, 0, 0}, + {"preventDefault", event_prevent_default, 0, 0, 0}, #if 0 - {"initEvent", event_prevent_default, 3}, - {"initEventNS", event_prevent_default, 4}, + {"initEvent", event_prevent_default, 3, 0, 0}, + {"initEventNS", event_prevent_default, 4, 0, 0}, #endif - {0}, + {0, 0, 0, 0, 0} }; JSPropertySpec eventProps[] = { - {"type", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"target", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"currentTarget", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"eventPhase", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"bubbles", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"cancelable", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"timeStamp", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"namespaceURI", 7, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"defaultPrevented", 8, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"type", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"target", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"currentTarget", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"eventPhase", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"bubbles", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"cancelable", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"timeStamp", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"namespaceURI", 7, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"defaultPrevented", 8, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, /*UIEvent*/ - {"detail", 20, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"detail", 20, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, /*text, connectionEvent*/ - {"data", 25, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"data", 25, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, /*MouseEvent*/ - {"screenX", 30, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"screenY", 31, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"clientX", 32, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"clientY", 33, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"button", 34, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"relatedTarget", 35, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"screenX", 30, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"screenY", 31, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"clientX", 32, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"clientY", 33, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"button", 34, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"relatedTarget", 35, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, /*wheelEvent*/ - {"wheelDelta", 36, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"wheelDelta", 36, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, /*keyboard*/ - {"keyIdentifier", 40, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"keyChar", 41, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"charCode", 42, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - + {"keyIdentifier", 40, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"keyChar", 41, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"charCode", 42, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + /*progress*/ - {"lengthComputable",50, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"typeArg", 51, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"loaded", 52, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"total", 53, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"bufferLevelValid", 54, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"bufferLevel", 55, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"bufferRemainingTime", 56, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"status", 57, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"lengthComputable",50, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"typeArg", 51, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"loaded", 52, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"total", 53, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"bufferLevelValid", 54, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"bufferLevel", 55, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"bufferRemainingTime", 56, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"status", 57, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, /*used by vrml*/ - {"width", 60, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"height", 61, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"translation_x", 62, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"translation_y", 63, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - - - {0}, + {"width", 60, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"height", 61, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"offset_x", 62, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"offset_y", 63, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"vp_width", 64, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"vp_height", 65, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"translation_x", 66, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"translation_y", 67, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"type3d", 68, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + + + {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_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[DOMCore] Event class initialized\n")); @@ -3251,41 +3541,51 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global) { JSFunctionSpec nodeListFuncs[] = { - {"item", dom_nodelist_item, 1}, - {0} + {"item", dom_nodelist_item, 1, 0, 0}, + {0, 0, 0, 0, 0} }; JSPropertySpec nodeListProps[] = { - {"length", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {0} + {"length", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {0, 0, 0, 0, 0} }; 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")); } - + { JSPropertySpec xmlHTTPRequestClassProps[] = { - {"onreadystatechange", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"readyState", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"responseText", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"responseXML", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"status", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"statusText", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {0} + {"onreadystatechange", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"readyState", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"responseText", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"responseXML", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"status", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"statusText", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {0, 0, 0, 0, 0} }; JSFunctionSpec xmlHTTPRequestClassFuncs[] = { - {"open", xml_http_open, 2}, - {"setRequestHeader", xml_http_set_header, 2}, - {"send", xml_http_send, 0}, - {"abort", xml_http_abort, 0}, - {"getAllResponseHeaders", xml_http_get_all_headers, 0}, - {"getResponseHeader", xml_http_get_header, 1}, + {"open", xml_http_open, 2, 0, 0}, + {"setRequestHeader", xml_http_set_header, 2, 0, 0}, + {"send", xml_http_send, 0, 0, 0}, + {"abort", xml_http_abort, 0, 0, 0}, + {"getAllResponseHeaders", xml_http_get_all_headers, 0, 0, 0}, + {"getResponseHeader", xml_http_get_header, 1, 0, 0}, /*todo - addEventListener and removeEventListener*/ - {0} + {0, 0, 0, 0, 0} }; 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")); } + { + JSPropertySpec storageClassProps[] = { + {0, 0, 0, 0, 0} + }; + JSFunctionSpec storageClassFuncs[] = { + {0, 0, 0, 0, 0} + }; + dom_rt->storage_proto = 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")); + } { GF_SceneGraph *dcci; @@ -3301,19 +3601,19 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global) if (dcci && dcci->RootNode) { JSPropertySpec DCCIClassProps[] = { - {"value", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"valueType", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"propertyType", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"readOnly", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"DCCIMetadataInterfaceType", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"DCCIMetadataInterface", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"version", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {0} + {"value", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"valueType", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"propertyType", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"readOnly", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"DCCIMetadataInterfaceType", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"DCCIMetadataInterface", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"version", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {0, 0, 0, 0, 0} }; JSFunctionSpec DCCIClassFuncs[] = { - {"hasProperty", dcci_has_property, 3}, - {"searchProperty", dcci_search_property, 4}, - {0} + {"hasProperty", dcci_has_property, 3, 0, 0}, + {"searchProperty", dcci_search_property, 4, 0, 0}, + {0, 0, 0, 0, 0} }; JS_InitClass(c, global, dom_rt->dom_element_proto, &dom_rt->DCCIClass, 0, 0, DCCIClassProps, DCCIClassFuncs, 0, 0); @@ -3326,12 +3626,63 @@ void dom_js_load(GF_SceneGraph *scene, JSContext *c, JSObject *global) } } +void dom_js_pre_destroy(JSContext *c, GF_SceneGraph *sg, GF_Node *n) +{ + u32 i, count; + + + if (n) { + if (n->sgprivate->interact && n->sgprivate->interact->js_binding && n->sgprivate->interact->js_binding->node) { + JSObject *obj = n->sgprivate->interact->js_binding->node; + JS_SetPrivate(c, obj, NULL); + n->sgprivate->interact->js_binding->node=NULL; + if (gf_list_del_item(sg->objects, obj)>=0) { + gf_js_remove_root(c, &(n->sgprivate->interact->js_binding->node)); + } + } + return; + } + + /*force cleanup of scripts/handlers not destroyed - this usually happens when a script/handler node has been created in a script + but not inserted in the graph*/ + while (gf_list_count(sg->objects)) { + GF_Node *n; + JSObject *obj = gf_list_get(sg->objects, 0); + n = dom_get_node(c, obj); + if (n) { + JS_SetPrivate(c, obj, NULL); + n->sgprivate->interact->js_binding->node=NULL; + gf_node_unregister(n, NULL); + gf_js_remove_root(c, &(n->sgprivate->interact->js_binding->node)); + } + gf_list_rem(sg->objects, 0); + } + + count = gf_list_count(dom_rt->handlers); + for (i=0; i<count; i++) { + SVG_handlerElement *handler = (SVG_handlerElement *)gf_list_get(dom_rt->handlers, i); + if (handler->js_context==c) { + /*unprotect the function*/ + gf_js_remove_root(handler->js_context, &(handler->js_fun_val)); + handler->js_fun_val=0; + handler->js_context=0; + gf_list_rem(dom_rt->handlers, i); + i--; + count--; + } + } + if (sg->document) { + dom_document_finalize(c, sg->document); + } +} + void dom_js_unload() { if (!dom_rt) return; dom_rt->nb_inst--; if (!dom_rt->nb_inst) { - free(dom_rt); + gf_list_del(dom_rt->handlers); + gf_free(dom_rt); dom_rt = NULL; } } @@ -3345,9 +3696,10 @@ static void dom_js_define_document_ex(JSContext *c, JSObject *global, GF_SceneGr if (doc->reference_count) doc->reference_count++; - __class = &dom_rt->domDocumentClass; + __class = NULL; if (dom_rt->get_document_class) __class = dom_rt->get_document_class(doc); + if (!__class) __class = &dom_rt->domDocumentClass; obj = JS_DefineObject(c, global, name, __class, 0, 0 ); gf_node_register(doc->RootNode, NULL); @@ -3403,7 +3755,7 @@ GF_Err gf_sg_new_from_xml_doc(const char *src, GF_SceneGraph **scene) e = gf_xml_sax_parse_file(ctx->sax, src, NULL); gf_xml_sax_del(ctx->sax); gf_list_del(ctx->node_stack); - free(ctx); + gf_free(ctx); *scene = NULL; if (e<0) { @@ -3439,7 +3791,7 @@ static void xml_reload_node_start(void *sax_cbck, const char *node_name, const c GF_DOMFullNode *par = NULL; XMLReloadContext *ctx = (XMLReloadContext *)sax_cbck; GF_DOMFullNode *node; - + node = gf_list_last(ctx->node_stack); if (!node) { is_root = 1; @@ -3452,8 +3804,8 @@ static void xml_reload_node_start(void *sax_cbck, const char *node_name, const c if (node->ns && name_space && strcmp(gf_sg_get_namespace(node->sgprivate->scenegraph, node->ns), name_space)) same_node = 0; if (!same_node) { - if (node->name) free(node->name); - node->name = strdup(node_name); + if (node->name) gf_free(node->name); + node->name = gf_strdup(node_name); node->ns = 0; if (name_space) { gf_sg_add_namespace(node->sgprivate->scenegraph, (char *) name_space, NULL); @@ -3481,7 +3833,7 @@ static void xml_reload_node_start(void *sax_cbck, const char *node_name, const c /*create the new node*/ node = (GF_DOMFullNode *) gf_node_new(ctx->document, TAG_DOMFullNode); - node->name = strdup(node_name); + node->name = gf_strdup(node_name); if (name_space) { gf_sg_add_namespace(node->sgprivate->scenegraph, (char *)name_space, NULL); node->ns = gf_sg_get_namespace_code(node->sgprivate->scenegraph, (char *)name_space); @@ -3509,8 +3861,8 @@ static void xml_reload_node_start(void *sax_cbck, const char *node_name, const c found = 1; if (strcmp(att->data, attributes[i].value)) { atts_modified = 1; - free(att->data); - att->data = strdup(attributes[i].value); + gf_free(att->data); + att->data = gf_strdup(attributes[i].value); } } } @@ -3530,11 +3882,11 @@ static void xml_reload_node_start(void *sax_cbck, const char *node_name, const c GF_DOMFullAttribute *tmp, *att; att = (GF_DOMFullAttribute *)node->attributes; while (att) { - if (att->name) free(att->name); - if (att->data) free(att->data); + if (att->name) gf_free(att->name); + if (att->data) gf_free(att->data); tmp = att; att = (GF_DOMFullAttribute *)att->next; - free(tmp); + gf_free(tmp); } /*parse all atts*/ @@ -3546,8 +3898,8 @@ static void xml_reload_node_start(void *sax_cbck, const char *node_name, const c GF_DOMFullAttribute *att; GF_SAFEALLOC(att, GF_DOMFullAttribute); att->tag = TAG_DOM_ATT_any; - att->name = strdup(attributes[i].name); - att->data = strdup(attributes[i].value); + att->name = gf_strdup(attributes[i].name); + att->data = gf_strdup(attributes[i].value); if (prev) prev->next = (GF_DOMAttribute*)att; else node->attributes = (GF_DOMAttribute*)att; prev = att; @@ -3598,15 +3950,15 @@ static void xml_reload_text_content(void *sax_cbck, const char *content, Bool is txt = (GF_DOMText *)child->node; if (!strcmp(txt->textContent, content) && ((txt->type==GF_DOM_TEXT_REGULAR) || is_cdata)) return; - if (txt->textContent) free(txt->textContent); - txt->textContent = strdup(content); + if (txt->textContent) gf_free(txt->textContent); + txt->textContent = gf_strdup(content); txt->type = is_cdata ? GF_DOM_TEXT_CDATA : GF_DOM_TEXT_REGULAR; break; } child = child->next; } if (!txt) { - txt = gf_dom_add_text_node((GF_Node *)par, strdup(content) ); + txt = gf_dom_add_text_node((GF_Node *)par, gf_strdup(content) ); txt->type = is_cdata ? GF_DOM_TEXT_CDATA : GF_DOM_TEXT_REGULAR; memset(&evt, 0, sizeof(GF_DOM_Event)); diff --git a/src/scenegraph/mpeg4_animators.c b/src/scenegraph/mpeg4_animators.c index 141cc4c..5e708c3 100644 --- a/src/scenegraph/mpeg4_animators.c +++ b/src/scenegraph/mpeg4_animators.c @@ -27,6 +27,9 @@ /*MPEG4 tags (for internal nodes)*/ #include <gpac/nodes_mpeg4.h> + +#ifndef GPAC_DISABLE_VRML + static Fixed Interpolate(Fixed keyValue1, Fixed keyValue2, Fixed fraction) { return gf_mulfix(keyValue2 - keyValue1, fraction) + keyValue1; @@ -94,9 +97,9 @@ static Fixed quadratic_knots[] = {0,0,0,FIX_ONE,FIX_ONE,FIX_ONE}; static void anurbs_reset(anim_nurbs *nurbs) { - if (nurbs->n) free(nurbs->n); - if (nurbs->left) free(nurbs->left); - if (nurbs->right) free(nurbs->right); + if (nurbs->n) gf_free(nurbs->n); + if (nurbs->left) gf_free(nurbs->left); + if (nurbs->right) gf_free(nurbs->right); nurbs->n = nurbs->left = nurbs->right = NULL; } @@ -137,9 +140,9 @@ static void anurbs_basis(anim_nurbs *nurbs, s32 span, Fixed t) u32 i, j; Fixed saved, temp; if (!nurbs->n) { - nurbs->n = (Fixed*)malloc(sizeof(Fixed) * (nurbs->p+1)); - nurbs->left = (Fixed*)malloc(sizeof(Fixed) * (nurbs->p+1)); - nurbs->right = (Fixed*)malloc(sizeof(Fixed) * (nurbs->p+1)); + nurbs->n = (Fixed*)gf_malloc(sizeof(Fixed) * (nurbs->p+1)); + nurbs->left = (Fixed*)gf_malloc(sizeof(Fixed) * (nurbs->p+1)); + nurbs->right = (Fixed*)gf_malloc(sizeof(Fixed) * (nurbs->p+1)); } nurbs->n[0] = FIX_ONE; @@ -278,7 +281,7 @@ static void Anim_Destroy(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { AnimatorStack *stack = (AnimatorStack *)gf_node_get_private(node); anurbs_reset(&stack->anurbs); - free(stack); + gf_free(stack); } } @@ -339,7 +342,7 @@ static void PA_Update(M_PositionAnimator *pa, AnimatorStack *stack) } Animator_Update(stack, pa->keyValueType, pa->keyValue.count, &pa->keySpline, pa->weight.count, pa->weight.vals); } -static void PA_SetFraction(GF_Node *node) +static void PA_SetFraction(GF_Node *node, GF_Route *route) { Fixed frac; u32 nbKeys, nbVals, i; @@ -499,7 +502,7 @@ static void PA2D_Update(M_PositionAnimator2D *pa, AnimatorStack *stack) } Animator_Update(stack, pa->keyValueType, pa->keyValue.count, &pa->keySpline, pa->weight.count, pa->weight.vals); } -static void PA2D_SetFraction(GF_Node *node) +static void PA2D_SetFraction(GF_Node *node, GF_Route *route) { Fixed frac; u32 nbKeys, nbVals, i; @@ -656,7 +659,7 @@ static void SA_Update(M_ScalarAnimator *sa, AnimatorStack *stack) Animator_Update(stack, sa->keyValueType, sa->keyValue.count, &sa->keySpline, sa->weight.count, sa->weight.vals); } -void SA_SetFraction(GF_Node *node) +void SA_SetFraction(GF_Node *node, GF_Route *route) { Fixed frac; u32 nbKeys, nbVals, i; @@ -790,3 +793,4 @@ void SA_Init(GF_Node *n) } +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/scenegraph/mpeg4_nodes.c b/src/scenegraph/mpeg4_nodes.c index 5156221..a1005dd 100644 --- a/src/scenegraph/mpeg4_nodes.c +++ b/src/scenegraph/mpeg4_nodes.c @@ -24,9 +24,9 @@ /* - DO NOT MOFIFY - File generated on GMT Thu Aug 07 11:43:26 2008 + DO NOT MOFIFY - File generated on GMT Mon Jan 18 12:27:12 2010 - BY MPEG4Gen for GPAC Version 0.4.5-DEV + BY MPEG4Gen for GPAC Version 0.4.6-DEV */ #include <gpac/nodes_mpeg4.h> @@ -34,6 +34,8 @@ #include <gpac/internal/scenegraph_dev.h> +#ifndef GPAC_DISABLE_VRML + /* Anchor Node deletion */ @@ -600,7 +602,7 @@ GF_Node *AudioBuffer_Create() p->startTime = 0; p->stopTime = 0; p->numChan = 1; - p->phaseGroup.vals = (SFInt32*)malloc(sizeof(SFInt32)*1); + p->phaseGroup.vals = (SFInt32*)gf_malloc(sizeof(SFInt32)*1); p->phaseGroup.count = 1; p->phaseGroup.vals[0] = 1; p->length = FLT2FIX(0.0); @@ -1773,7 +1775,7 @@ GF_Node *Background_Create() gf_node_setup((GF_Node *)p, TAG_MPEG4_Background); /*default field values*/ - p->skyColor.vals = (SFColor*)malloc(sizeof(SFColor)*1); + p->skyColor.vals = (SFColor*)gf_malloc(sizeof(SFColor)*1); p->skyColor.count = 1; p->skyColor.vals[0].red = FLT2FIX(0); p->skyColor.vals[0].green = FLT2FIX(0); @@ -4596,6 +4598,157 @@ GF_Node *ElevationGrid_Create() } +/* + Expression Node deletion +*/ + +static void Expression_Del(GF_Node *node) +{ + M_Expression *p = (M_Expression *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 Expression_Def2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 Expression_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 Expression_Out2All[] = { 0, 1, 2, 3, 4, 5}; + +static u32 Expression_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 6; + } +} + +static GF_Err Expression_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Expression_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Expression_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Expression_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Expression_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "expression_select1"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Expression *) node)->expression_select1; + return GF_OK; + case 1: + info->name = "expression_intensity1"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Expression *) node)->expression_intensity1; + return GF_OK; + case 2: + info->name = "expression_select2"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Expression *) node)->expression_select2; + return GF_OK; + case 3: + info->name = "expression_intensity2"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Expression *) node)->expression_intensity2; + return GF_OK; + case 4: + info->name = "init_face"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Expression *) node)->init_face; + return GF_OK; + case 5: + info->name = "expression_def"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Expression *) node)->expression_def; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Expression_get_field_index_by_name(char *name) +{ + if (!strcmp("expression_select1", name)) return 0; + if (!strcmp("expression_intensity1", name)) return 1; + if (!strcmp("expression_select2", name)) return 2; + if (!strcmp("expression_intensity2", name)) return 3; + if (!strcmp("init_face", name)) return 4; + if (!strcmp("expression_def", name)) return 5; + return -1; + } +static Bool Expression_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 1: + *AType = 0; + *QType = 13; + *QT13_bits = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(63); + return 1; + case 2: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 3: + *AType = 0; + *QType = 13; + *QT13_bits = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(63); + return 1; + default: + return 0; + } +} + + + +GF_Node *Expression_Create() +{ + M_Expression *p; + GF_SAFEALLOC(p, M_Expression); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Expression); + + /*default field values*/ + p->expression_select1 = 0; + p->expression_intensity1 = 0; + p->expression_select2 = 0; + p->expression_intensity2 = 0; + return (GF_Node *)p; +} + + /* Extrusion Node deletion */ @@ -4809,7 +4962,7 @@ GF_Node *Extrusion_Create() p->ccw = 1; p->convex = 1; p->creaseAngle = FLT2FIX(0.0); - p->crossSection.vals = (SFVec2f*)malloc(sizeof(SFVec2f)*5); + p->crossSection.vals = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*5); p->crossSection.count = 5; p->crossSection.vals[0].x = FLT2FIX(1); p->crossSection.vals[0].y = FLT2FIX(1); @@ -4822,18 +4975,18 @@ GF_Node *Extrusion_Create() p->crossSection.vals[4].x = FLT2FIX(1); p->crossSection.vals[4].y = FLT2FIX(1); p->endCap = 1; - p->orientation.vals = (GF_Vec4*)malloc(sizeof(GF_Vec4)*1); + p->orientation.vals = (GF_Vec4*)gf_malloc(sizeof(GF_Vec4)*1); p->orientation.count = 1; p->orientation.vals[0].x = FLT2FIX(0); p->orientation.vals[0].y = FLT2FIX(0); p->orientation.vals[0].z = FLT2FIX(1); p->orientation.vals[0].q = FLT2FIX(0); - p->scale.vals = (SFVec2f*)malloc(sizeof(SFVec2f)*1); + p->scale.vals = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*1); p->scale.count = 1; p->scale.vals[0].x = FLT2FIX(1); p->scale.vals[0].y = FLT2FIX(1); p->solid = 1; - p->spine.vals = (SFVec3f *)malloc(sizeof(SFVec3f)*2); + p->spine.vals = (SFVec3f *)gf_malloc(sizeof(SFVec3f)*2); p->spine.count = 2; p->spine.vals[0].x = FLT2FIX(0); p->spine.vals[0].y = FLT2FIX(0); @@ -4846,85 +4999,89 @@ GF_Node *Extrusion_Create() /* - Fog Node deletion + Face Node deletion */ -static void Fog_Del(GF_Node *node) +static void Face_Del(GF_Node *node) { - M_Fog *p = (M_Fog *) node; - gf_sg_sfstring_del(p->fogType); + M_Face *p = (M_Face *) node; + gf_node_unregister((GF_Node *) p->fap, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->fdp, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->fit, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->ttsSource, (GF_Node *) p); + gf_node_unregister_children((GF_Node *) p, p->renderedFace); gf_node_free((GF_Node *) p); } -static const u16 Fog_Def2All[] = { 0, 1, 2}; -static const u16 Fog_In2All[] = { 0, 1, 2, 3}; -static const u16 Fog_Out2All[] = { 0, 1, 2, 4}; -static const u16 Fog_Dyn2All[] = { 0, 2}; +static const u16 Face_Def2All[] = { 0, 1, 2, 3, 4}; +static const u16 Face_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 Face_Out2All[] = { 0, 1, 2, 3, 4}; -static u32 Fog_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Face_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 4; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_DYN: return 0; default: return 5; } } -static GF_Err Fog_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Face_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Fog_In2All[inField]; + *allField = Face_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Fog_Def2All[inField]; + *allField = Face_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Fog_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Fog_Dyn2All[inField]; + *allField = Face_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Fog_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Face_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "color"; + info->name = "fap"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_Fog *) node)->color; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFFAPNode; + info->far_ptr = & ((M_Face *)node)->fap; return GF_OK; case 1: - info->name = "fogType"; + info->name = "fdp"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_Fog *) node)->fogType; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFFDPNode; + info->far_ptr = & ((M_Face *)node)->fdp; return GF_OK; case 2: - info->name = "visibilityRange"; + info->name = "fit"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Fog *) node)->visibilityRange; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFFITNode; + info->far_ptr = & ((M_Face *)node)->fit; return GF_OK; case 3: - info->name = "set_bind"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Fog *)node)->on_set_bind; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Fog *) node)->set_bind; + info->name = "ttsSource"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_Face *)node)->ttsSource; return GF_OK; case 4: - info->name = "isBound"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Fog *) node)->isBound; + info->name = "renderedFace"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Face *)node)->renderedFace; return GF_OK; default: return GF_BAD_PARAM; @@ -4932,30 +5089,18 @@ static GF_Err Fog_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Fog_get_field_index_by_name(char *name) +static s32 Face_get_field_index_by_name(char *name) { - if (!strcmp("color", name)) return 0; - if (!strcmp("fogType", name)) return 1; - if (!strcmp("visibilityRange", name)) return 2; - if (!strcmp("set_bind", name)) return 3; - if (!strcmp("isBound", name)) return 4; + if (!strcmp("fap", name)) return 0; + if (!strcmp("fdp", name)) return 1; + if (!strcmp("fit", name)) return 2; + if (!strcmp("ttsSource", name)) return 3; + if (!strcmp("renderedFace", name)) return 4; return -1; } -static Bool Fog_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool Face_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 4; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 2: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -4963,126 +5108,83 @@ static Bool Fog_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fi -GF_Node *Fog_Create() +GF_Node *Face_Create() { - M_Fog *p; - GF_SAFEALLOC(p, M_Fog); + M_Face *p; + GF_SAFEALLOC(p, M_Face); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Fog); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Face); /*default field values*/ - p->color.red = FLT2FIX(1); - p->color.green = FLT2FIX(1); - p->color.blue = FLT2FIX(1); - p->fogType.buffer = (char*)malloc(sizeof(char) * 7); - strcpy(p->fogType.buffer, "LINEAR"); - p->visibilityRange = FLT2FIX(0); return (GF_Node *)p; } /* - FontStyle Node deletion + FaceDefMesh Node deletion */ -static void FontStyle_Del(GF_Node *node) +static void FaceDefMesh_Del(GF_Node *node) { - M_FontStyle *p = (M_FontStyle *) node; - gf_sg_mfstring_del(p->family); - gf_sg_mfstring_del(p->justify); - gf_sg_sfstring_del(p->language); - gf_sg_sfstring_del(p->style); + M_FaceDefMesh *p = (M_FaceDefMesh *) node; + gf_node_unregister((GF_Node *) p->faceSceneGraphNode, (GF_Node *) p); + gf_sg_mfint32_del(p->intervalBorders); + gf_sg_mfint32_del(p->coordIndex); + gf_sg_mfvec3f_del(p->displacements); gf_node_free((GF_Node *) p); } -static const u16 FontStyle_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; -static const u16 FontStyle_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; -static const u16 FontStyle_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 FaceDefMesh_Def2All[] = { 0, 1, 2, 3}; -static u32 FontStyle_get_field_count(GF_Node *node, u8 IndexMode) +static u32 FaceDefMesh_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 9; - case GF_SG_FIELD_CODING_DEF: return 9; - case GF_SG_FIELD_CODING_OUT: return 9; + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 0; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 9; + return 4; } } -static GF_Err FontStyle_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err FaceDefMesh_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = FontStyle_In2All[inField]; - return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = FontStyle_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = FontStyle_Out2All[inField]; + *allField = FaceDefMesh_Def2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err FontStyle_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err FaceDefMesh_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "family"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_FontStyle *) node)->family; + info->name = "faceSceneGraphNode"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_FaceDefMesh *)node)->faceSceneGraphNode; return GF_OK; case 1: - info->name = "horizontal"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_FontStyle *) node)->horizontal; + info->name = "intervalBorders"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FaceDefMesh *) node)->intervalBorders; return GF_OK; case 2: - info->name = "justify"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_FontStyle *) node)->justify; + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FaceDefMesh *) node)->coordIndex; return GF_OK; case 3: - info->name = "language"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_FontStyle *) node)->language; - return GF_OK; - case 4: - info->name = "leftToRight"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_FontStyle *) node)->leftToRight; - return GF_OK; - case 5: - info->name = "size"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_FontStyle *) node)->size; - return GF_OK; - case 6: - info->name = "spacing"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_FontStyle *) node)->spacing; - return GF_OK; - case 7: - info->name = "style"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_FontStyle *) node)->style; - return GF_OK; - case 8: - info->name = "topToBottom"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_FontStyle *) node)->topToBottom; + info->name = "displacements"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_FaceDefMesh *) node)->displacements; return GF_OK; default: return GF_BAD_PARAM; @@ -5090,33 +5192,28 @@ static GF_Err FontStyle_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 FontStyle_get_field_index_by_name(char *name) +static s32 FaceDefMesh_get_field_index_by_name(char *name) { - if (!strcmp("family", name)) return 0; - if (!strcmp("horizontal", name)) return 1; - if (!strcmp("justify", name)) return 2; - if (!strcmp("language", name)) return 3; - if (!strcmp("leftToRight", name)) return 4; - if (!strcmp("size", name)) return 5; - if (!strcmp("spacing", name)) return 6; - if (!strcmp("style", name)) return 7; - if (!strcmp("topToBottom", name)) return 8; + if (!strcmp("faceSceneGraphNode", name)) return 0; + if (!strcmp("intervalBorders", name)) return 1; + if (!strcmp("coordIndex", name)) return 2; + if (!strcmp("displacements", name)) return 3; return -1; } -static Bool FontStyle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool FaceDefMesh_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 5: + case 1: *AType = 0; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + *QType = 0; return 1; - case 6: + case 2: *AType = 0; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + *QType = 0; + return 1; + case 3: + *AType = 0; + *QType = 0; return 1; default: return 0; @@ -5125,132 +5222,90 @@ static Bool FontStyle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATy -GF_Node *FontStyle_Create() +GF_Node *FaceDefMesh_Create() { - M_FontStyle *p; - GF_SAFEALLOC(p, M_FontStyle); + M_FaceDefMesh *p; + GF_SAFEALLOC(p, M_FaceDefMesh); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_FontStyle); + gf_node_setup((GF_Node *)p, TAG_MPEG4_FaceDefMesh); /*default field values*/ - p->family.vals = (char**)malloc(sizeof(SFString)*1); - p->family.count = 1; - p->family.vals[0] = (char*)malloc(sizeof(char) * 6); - strcpy(p->family.vals[0], "SERIF"); - p->horizontal = 1; - p->justify.vals = (char**)malloc(sizeof(SFString)*1); - p->justify.count = 1; - p->justify.vals[0] = (char*)malloc(sizeof(char) * 6); - strcpy(p->justify.vals[0], "BEGIN"); - p->leftToRight = 1; - p->size = FLT2FIX(1.0); - p->spacing = FLT2FIX(1.0); - p->style.buffer = (char*)malloc(sizeof(char) * 6); - strcpy(p->style.buffer, "PLAIN"); - p->topToBottom = 1; return (GF_Node *)p; } /* - Form Node deletion + FaceDefTables Node deletion */ -static void Form_Del(GF_Node *node) +static void FaceDefTables_Del(GF_Node *node) { - M_Form *p = (M_Form *) node; - gf_sg_mfint32_del(p->groups); - gf_sg_mfstring_del(p->constraints); - gf_sg_mfint32_del(p->groupsIndex); - gf_sg_vrml_parent_destroy((GF_Node *) p); + M_FaceDefTables *p = (M_FaceDefTables *) node; + gf_node_unregister_children((GF_Node *) p, p->faceDefMesh); + gf_node_unregister_children((GF_Node *) p, p->faceDefTransform); gf_node_free((GF_Node *) p); } -static const u16 Form_Def2All[] = { 2, 3, 4, 5, 6}; -static const u16 Form_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 Form_Out2All[] = { 2, 3, 4, 5, 6}; -static const u16 Form_Dyn2All[] = { 3}; +static const u16 FaceDefTables_Def2All[] = { 0, 1, 2, 3}; +static const u16 FaceDefTables_In2All[] = { 2, 3}; +static const u16 FaceDefTables_Out2All[] = { 2, 3}; -static u32 Form_get_field_count(GF_Node *node, u8 IndexMode) +static u32 FaceDefTables_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 7; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 5; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 7; + return 4; } } -static GF_Err Form_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err FaceDefTables_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Form_In2All[inField]; + *allField = FaceDefTables_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Form_Def2All[inField]; + *allField = FaceDefTables_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Form_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Form_Dyn2All[inField]; + *allField = FaceDefTables_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Form_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err FaceDefTables_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Form *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Form *)node)->addChildren; + info->name = "fapID"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FaceDefTables *) node)->fapID; return GF_OK; case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Form *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Form *)node)->removeChildren; + info->name = "highLevelSelect"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FaceDefTables *) node)->highLevelSelect; return GF_OK; case 2: - info->name = "children"; + info->name = "faceDefMesh"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Form *)node)->children; + info->NDTtype = NDT_SFFaceDefMeshNode; + info->far_ptr = & ((M_FaceDefTables *)node)->faceDefMesh; return GF_OK; case 3: - info->name = "size"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Form *) node)->size; - return GF_OK; - case 4: - info->name = "groups"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_Form *) node)->groups; - return GF_OK; - case 5: - info->name = "constraints"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_Form *) node)->constraints; - return GF_OK; - case 6: - info->name = "groupsIndex"; + info->name = "faceDefTransform"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_Form *) node)->groupsIndex; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFFaceDefTransformNode; + info->far_ptr = & ((M_FaceDefTables *)node)->faceDefTransform; return GF_OK; default: return GF_BAD_PARAM; @@ -5258,39 +5313,30 @@ static GF_Err Form_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Form_get_field_index_by_name(char *name) +static s32 FaceDefTables_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; - if (!strcmp("size", name)) return 3; - if (!strcmp("groups", name)) return 4; - if (!strcmp("constraints", name)) return 5; - if (!strcmp("groupsIndex", name)) return 6; + if (!strcmp("fapID", name)) return 0; + if (!strcmp("highLevelSelect", name)) return 1; + if (!strcmp("faceDefMesh", name)) return 2; + if (!strcmp("faceDefTransform", name)) return 3; return -1; } -static Bool Form_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool FaceDefTables_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 3: - *AType = 12; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 4: + case 0: *AType = 0; *QType = 13; - *QT13_bits = 10; - *b_min = FLT2FIX(-1); - *b_max = FLT2FIX(1022); + *QT13_bits = 7; + *b_min = FLT2FIX(1); + *b_max = FLT2FIX( 68); return 1; - case 6: + case 1: *AType = 0; *QType = 13; - *QT13_bits = 10; - *b_min = FLT2FIX(-1); - *b_max = FLT2FIX(1022); + *QT13_bits = 6; + *b_min = FLT2FIX(1); + *b_max = FLT2FIX( 64); return 1; default: return 0; @@ -5299,89 +5345,88 @@ static Bool Form_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, F -GF_Node *Form_Create() +GF_Node *FaceDefTables_Create() { - M_Form *p; - GF_SAFEALLOC(p, M_Form); + M_FaceDefTables *p; + GF_SAFEALLOC(p, M_FaceDefTables); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Form); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_MPEG4_FaceDefTables); /*default field values*/ - p->size.x = FLT2FIX(-1); - p->size.y = FLT2FIX(-1); + p->fapID = 1; + p->highLevelSelect = 1; return (GF_Node *)p; } /* - Group Node deletion + FaceDefTransform Node deletion */ -static void Group_Del(GF_Node *node) +static void FaceDefTransform_Del(GF_Node *node) { - M_Group *p = (M_Group *) node; - gf_sg_vrml_parent_destroy((GF_Node *) p); + M_FaceDefTransform *p = (M_FaceDefTransform *) node; + gf_node_unregister((GF_Node *) p->faceSceneGraphNode, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Group_Def2All[] = { 2}; -static const u16 Group_In2All[] = { 0, 1, 2}; -static const u16 Group_Out2All[] = { 2}; +static const u16 FaceDefTransform_Def2All[] = { 0, 1, 2, 3, 4}; -static u32 Group_get_field_count(GF_Node *node, u8 IndexMode) +static u32 FaceDefTransform_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 0; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 3; + return 5; } } -static GF_Err Group_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err FaceDefTransform_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = Group_In2All[inField]; - return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Group_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = Group_Out2All[inField]; + *allField = FaceDefTransform_Def2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Group_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err FaceDefTransform_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Group *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; + info->name = "faceSceneGraphNode"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Group *)node)->addChildren; + info->far_ptr = & ((M_FaceDefTransform *)node)->faceSceneGraphNode; return GF_OK; case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Group *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Group *)node)->removeChildren; + info->name = "fieldId"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FaceDefTransform *) node)->fieldId; return GF_OK; case 2: - info->name = "children"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Group *)node)->children; + info->name = "rotationDef"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_FaceDefTransform *) node)->rotationDef; + return GF_OK; + case 3: + info->name = "scaleDef"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_FaceDefTransform *) node)->scaleDef; + return GF_OK; + case 4: + info->name = "translationDef"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_FaceDefTransform *) node)->translationDef; return GF_OK; default: return GF_BAD_PARAM; @@ -5389,16 +5434,32 @@ static GF_Err Group_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Group_get_field_index_by_name(char *name) +static s32 FaceDefTransform_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; + if (!strcmp("faceSceneGraphNode", name)) return 0; + if (!strcmp("fieldId", name)) return 1; + if (!strcmp("rotationDef", name)) return 2; + if (!strcmp("scaleDef", name)) return 3; + if (!strcmp("translationDef", name)) return 4; return -1; } -static Bool Group_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool FaceDefTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 2: + *AType = 0; + *QType = 10; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 0; + *QType = 7; + return 1; + case 4: + *AType = 0; + *QType = 1; + return 1; default: return 0; } @@ -5406,352 +5467,14620 @@ static Bool Group_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, -GF_Node *Group_Create() +GF_Node *FaceDefTransform_Create() { - M_Group *p; - GF_SAFEALLOC(p, M_Group); + M_FaceDefTransform *p; + GF_SAFEALLOC(p, M_FaceDefTransform); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Group); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_MPEG4_FaceDefTransform); /*default field values*/ + p->fieldId = 1; + p->rotationDef.x = FLT2FIX(0); + p->rotationDef.y = FLT2FIX(0); + p->rotationDef.z = FLT2FIX(1); + p->rotationDef.q = FLT2FIX(0); + p->scaleDef.x = FLT2FIX(1); + p->scaleDef.y = FLT2FIX(1); + p->scaleDef.z = FLT2FIX(1); + p->translationDef.x = FLT2FIX(0); + p->translationDef.y = FLT2FIX(0); + p->translationDef.z = FLT2FIX(0); return (GF_Node *)p; } /* - ImageTexture Node deletion + FAP Node deletion */ -static void ImageTexture_Del(GF_Node *node) +static void FAP_Del(GF_Node *node) { - M_ImageTexture *p = (M_ImageTexture *) node; - gf_sg_mfurl_del(p->url); + M_FAP *p = (M_FAP *) node; + gf_node_unregister((GF_Node *) p->viseme, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->expression, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 ImageTexture_Def2All[] = { 0, 1, 2}; -static const u16 ImageTexture_In2All[] = { 0}; -static const u16 ImageTexture_Out2All[] = { 0}; +static const u16 FAP_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67}; +static const u16 FAP_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67}; +static const u16 FAP_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67}; -static u32 ImageTexture_get_field_count(GF_Node *node, u8 IndexMode) +static u32 FAP_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_IN: return 68; + case GF_SG_FIELD_CODING_DEF: return 68; + case GF_SG_FIELD_CODING_OUT: return 68; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 3; + return 68; } } -static GF_Err ImageTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err FAP_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = ImageTexture_In2All[inField]; + *allField = FAP_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = ImageTexture_Def2All[inField]; + *allField = FAP_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = ImageTexture_Out2All[inField]; + *allField = FAP_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err ImageTexture_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err FAP_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "url"; + info->name = "viseme"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_ImageTexture *) node)->url; - return GF_OK; - case 1: - info->name = "repeatS"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ImageTexture *) node)->repeatS; - return GF_OK; - case 2: - info->name = "repeatT"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ImageTexture *) node)->repeatT; - return GF_OK; - default: - return GF_BAD_PARAM; - } -} - - -static s32 ImageTexture_get_field_index_by_name(char *name) -{ - if (!strcmp("url", name)) return 0; - if (!strcmp("repeatS", name)) return 1; - if (!strcmp("repeatT", name)) return 2; - return -1; - } -static Bool ImageTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) -{ - switch (FieldIndex) { - default: - return 0; - } -} - - - -GF_Node *ImageTexture_Create() -{ - M_ImageTexture *p; - GF_SAFEALLOC(p, M_ImageTexture); - if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_ImageTexture); - - /*default field values*/ - p->repeatS = 1; - p->repeatT = 1; - return (GF_Node *)p; -} - - -/* - IndexedFaceSet Node deletion -*/ - -static void IndexedFaceSet_Del(GF_Node *node) -{ - M_IndexedFaceSet *p = (M_IndexedFaceSet *) node; - gf_sg_mfint32_del(p->set_colorIndex); - gf_sg_mfint32_del(p->set_coordIndex); - gf_sg_mfint32_del(p->set_normalIndex); - gf_sg_mfint32_del(p->set_texCoordIndex); - gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->normal, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->texCoord, (GF_Node *) p); - gf_sg_mfint32_del(p->colorIndex); - gf_sg_mfint32_del(p->coordIndex); - gf_sg_mfint32_del(p->normalIndex); - gf_sg_mfint32_del(p->texCoordIndex); - gf_node_free((GF_Node *) p); -} - -static const u16 IndexedFaceSet_Def2All[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; -static const u16 IndexedFaceSet_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static const u16 IndexedFaceSet_Out2All[] = { 4, 5, 6, 7}; - -static u32 IndexedFaceSet_get_field_count(GF_Node *node, u8 IndexMode) -{ - switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 8; - case GF_SG_FIELD_CODING_DEF: return 14; - case GF_SG_FIELD_CODING_OUT: return 4; - case GF_SG_FIELD_CODING_DYN: return 0; - default: - return 18; - } -} - -static GF_Err IndexedFaceSet_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) -{ - switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = IndexedFaceSet_In2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DEF: - *allField = IndexedFaceSet_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = IndexedFaceSet_Out2All[inField]; - return GF_OK; - default: - return GF_BAD_PARAM; - } -} -static GF_Err IndexedFaceSet_get_field(GF_Node *node, GF_FieldInfo *info) -{ - switch (info->fieldIndex) { - case 0: - info->name = "set_colorIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedFaceSet *)node)->on_set_colorIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet *) node)->set_colorIndex; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFVisemeNode; + info->far_ptr = & ((M_FAP *)node)->viseme; return GF_OK; case 1: - info->name = "set_coordIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedFaceSet *)node)->on_set_coordIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet *) node)->set_coordIndex; + info->name = "expression"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFExpressionNode; + info->far_ptr = & ((M_FAP *)node)->expression; return GF_OK; case 2: - info->name = "set_normalIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedFaceSet *)node)->on_set_normalIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet *) node)->set_normalIndex; + info->name = "open_jaw"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->open_jaw; return GF_OK; case 3: - info->name = "set_texCoordIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedFaceSet *)node)->on_set_texCoordIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet *) node)->set_texCoordIndex; + info->name = "lower_t_midlip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lower_t_midlip; return GF_OK; case 4: - info->name = "color"; + info->name = "raise_b_midlip"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((M_IndexedFaceSet *)node)->color; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_b_midlip; return GF_OK; case 5: - info->name = "coord"; + info->name = "stretch_l_corner"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinateNode; - info->far_ptr = & ((M_IndexedFaceSet *)node)->coord; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->stretch_l_corner; return GF_OK; case 6: - info->name = "normal"; + info->name = "stretch_r_corner"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFNormalNode; - info->far_ptr = & ((M_IndexedFaceSet *)node)->normal; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->stretch_r_corner; return GF_OK; case 7: - info->name = "texCoord"; + info->name = "lower_t_lip_lm"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureCoordinateNode; - info->far_ptr = & ((M_IndexedFaceSet *)node)->texCoord; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lower_t_lip_lm; return GF_OK; case 8: - info->name = "ccw"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_IndexedFaceSet *) node)->ccw; + info->name = "lower_t_lip_rm"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lower_t_lip_rm; return GF_OK; case 9: - info->name = "colorIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet *) node)->colorIndex; + info->name = "lower_b_lip_lm"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lower_b_lip_lm; return GF_OK; case 10: - info->name = "colorPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_IndexedFaceSet *) node)->colorPerVertex; + info->name = "lower_b_lip_rm"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lower_b_lip_rm; return GF_OK; case 11: - info->name = "convex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_IndexedFaceSet *) node)->convex; + info->name = "raise_l_cornerlip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_l_cornerlip; return GF_OK; case 12: - info->name = "coordIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet *) node)->coordIndex; + info->name = "raise_r_cornerlip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_r_cornerlip; return GF_OK; case 13: - info->name = "creaseAngle"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_IndexedFaceSet *) node)->creaseAngle; + info->name = "thrust_jaw"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->thrust_jaw; return GF_OK; case 14: - info->name = "normalIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet *) node)->normalIndex; + info->name = "shift_jaw"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->shift_jaw; return GF_OK; case 15: - info->name = "normalPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_IndexedFaceSet *) node)->normalPerVertex; + info->name = "push_b_lip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->push_b_lip; return GF_OK; case 16: - info->name = "solid"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_IndexedFaceSet *) node)->solid; + info->name = "push_t_lip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->push_t_lip; return GF_OK; case 17: - info->name = "texCoordIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet *) node)->texCoordIndex; + info->name = "depress_chin"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->depress_chin; return GF_OK; - default: - return GF_BAD_PARAM; - } -} - - -static s32 IndexedFaceSet_get_field_index_by_name(char *name) -{ - if (!strcmp("set_colorIndex", name)) return 0; - if (!strcmp("set_coordIndex", name)) return 1; - if (!strcmp("set_normalIndex", name)) return 2; - if (!strcmp("set_texCoordIndex", name)) return 3; - if (!strcmp("color", name)) return 4; - if (!strcmp("coord", name)) return 5; - if (!strcmp("normal", name)) return 6; - if (!strcmp("texCoord", name)) return 7; - if (!strcmp("ccw", name)) return 8; - if (!strcmp("colorIndex", name)) return 9; - if (!strcmp("colorPerVertex", name)) return 10; - if (!strcmp("convex", name)) return 11; - if (!strcmp("coordIndex", name)) return 12; - if (!strcmp("creaseAngle", name)) return 13; - if (!strcmp("normalIndex", name)) return 14; - if (!strcmp("normalPerVertex", name)) return 15; - if (!strcmp("solid", name)) return 16; - if (!strcmp("texCoordIndex", name)) return 17; - return -1; - } -static Bool IndexedFaceSet_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) -{ - switch (FieldIndex) { - case 9: - *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + case 18: + info->name = "close_t_l_eyelid"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->close_t_l_eyelid; + return GF_OK; + case 19: + info->name = "close_t_r_eyelid"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->close_t_r_eyelid; + return GF_OK; + case 20: + info->name = "close_b_l_eyelid"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->close_b_l_eyelid; + return GF_OK; + case 21: + info->name = "close_b_r_eyelid"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->close_b_r_eyelid; + return GF_OK; + case 22: + info->name = "yaw_l_eyeball"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->yaw_l_eyeball; + return GF_OK; + case 23: + info->name = "yaw_r_eyeball"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->yaw_r_eyeball; + return GF_OK; + case 24: + info->name = "pitch_l_eyeball"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->pitch_l_eyeball; + return GF_OK; + case 25: + info->name = "pitch_r_eyeball"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->pitch_r_eyeball; + return GF_OK; + case 26: + info->name = "thrust_l_eyeball"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->thrust_l_eyeball; + return GF_OK; + case 27: + info->name = "thrust_r_eyeball"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->thrust_r_eyeball; + return GF_OK; + case 28: + info->name = "dilate_l_pupil"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->dilate_l_pupil; + return GF_OK; + case 29: + info->name = "dilate_r_pupil"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->dilate_r_pupil; + return GF_OK; + case 30: + info->name = "raise_l_i_eyebrow"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_l_i_eyebrow; + return GF_OK; + case 31: + info->name = "raise_r_i_eyebrow"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_r_i_eyebrow; + return GF_OK; + case 32: + info->name = "raise_l_m_eyebrow"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_l_m_eyebrow; + return GF_OK; + case 33: + info->name = "raise_r_m_eyebrow"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_r_m_eyebrow; + return GF_OK; + case 34: + info->name = "raise_l_o_eyebrow"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_l_o_eyebrow; + return GF_OK; + case 35: + info->name = "raise_r_o_eyebrow"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_r_o_eyebrow; + return GF_OK; + case 36: + info->name = "squeeze_l_eyebrow"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->squeeze_l_eyebrow; + return GF_OK; + case 37: + info->name = "squeeze_r_eyebrow"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->squeeze_r_eyebrow; + return GF_OK; + case 38: + info->name = "puff_l_cheek"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->puff_l_cheek; + return GF_OK; + case 39: + info->name = "puff_r_cheek"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->puff_r_cheek; + return GF_OK; + case 40: + info->name = "lift_l_cheek"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lift_l_cheek; + return GF_OK; + case 41: + info->name = "lift_r_cheek"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lift_r_cheek; + return GF_OK; + case 42: + info->name = "shift_tongue_tip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->shift_tongue_tip; + return GF_OK; + case 43: + info->name = "raise_tongue_tip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_tongue_tip; + return GF_OK; + case 44: + info->name = "thrust_tongue_tip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->thrust_tongue_tip; + return GF_OK; + case 45: + info->name = "raise_tongue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_tongue; + return GF_OK; + case 46: + info->name = "tongue_roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->tongue_roll; + return GF_OK; + case 47: + info->name = "head_pitch"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->head_pitch; + return GF_OK; + case 48: + info->name = "head_yaw"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->head_yaw; + return GF_OK; + case 49: + info->name = "head_roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->head_roll; + return GF_OK; + case 50: + info->name = "lower_t_midlip_o"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lower_t_midlip_o; + return GF_OK; + case 51: + info->name = "raise_b_midlip_o"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_b_midlip_o; + return GF_OK; + case 52: + info->name = "stretch_l_cornerlip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->stretch_l_cornerlip; + return GF_OK; + case 53: + info->name = "stretch_r_cornerlip"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->stretch_r_cornerlip; + return GF_OK; + case 54: + info->name = "lower_t_lip_lm_o"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lower_t_lip_lm_o; + return GF_OK; + case 55: + info->name = "lower_t_lip_rm_o"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->lower_t_lip_rm_o; + return GF_OK; + case 56: + info->name = "raise_b_lip_lm_o"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_b_lip_lm_o; + return GF_OK; + case 57: + info->name = "raise_b_lip_rm_o"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_b_lip_rm_o; + return GF_OK; + case 58: + info->name = "raise_l_cornerlip_o"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_l_cornerlip_o; + return GF_OK; + case 59: + info->name = "raise_r_cornerlip_o"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_r_cornerlip_o; + return GF_OK; + case 60: + info->name = "stretch_l_nose"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->stretch_l_nose; + return GF_OK; + case 61: + info->name = "stretch_r_nose"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->stretch_r_nose; + return GF_OK; + case 62: + info->name = "raise_nose"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_nose; + return GF_OK; + case 63: + info->name = "bend_nose"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->bend_nose; + return GF_OK; + case 64: + info->name = "raise_l_ear"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_l_ear; + return GF_OK; + case 65: + info->name = "raise_r_ear"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->raise_r_ear; + return GF_OK; + case 66: + info->name = "pull_l_ear"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->pull_l_ear; + return GF_OK; + case 67: + info->name = "pull_r_ear"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FAP *) node)->pull_r_ear; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 FAP_get_field_index_by_name(char *name) +{ + if (!strcmp("viseme", name)) return 0; + if (!strcmp("expression", name)) return 1; + if (!strcmp("open_jaw", name)) return 2; + if (!strcmp("lower_t_midlip", name)) return 3; + if (!strcmp("raise_b_midlip", name)) return 4; + if (!strcmp("stretch_l_corner", name)) return 5; + if (!strcmp("stretch_r_corner", name)) return 6; + if (!strcmp("lower_t_lip_lm", name)) return 7; + if (!strcmp("lower_t_lip_rm", name)) return 8; + if (!strcmp("lower_b_lip_lm", name)) return 9; + if (!strcmp("lower_b_lip_rm", name)) return 10; + if (!strcmp("raise_l_cornerlip", name)) return 11; + if (!strcmp("raise_r_cornerlip", name)) return 12; + if (!strcmp("thrust_jaw", name)) return 13; + if (!strcmp("shift_jaw", name)) return 14; + if (!strcmp("push_b_lip", name)) return 15; + if (!strcmp("push_t_lip", name)) return 16; + if (!strcmp("depress_chin", name)) return 17; + if (!strcmp("close_t_l_eyelid", name)) return 18; + if (!strcmp("close_t_r_eyelid", name)) return 19; + if (!strcmp("close_b_l_eyelid", name)) return 20; + if (!strcmp("close_b_r_eyelid", name)) return 21; + if (!strcmp("yaw_l_eyeball", name)) return 22; + if (!strcmp("yaw_r_eyeball", name)) return 23; + if (!strcmp("pitch_l_eyeball", name)) return 24; + if (!strcmp("pitch_r_eyeball", name)) return 25; + if (!strcmp("thrust_l_eyeball", name)) return 26; + if (!strcmp("thrust_r_eyeball", name)) return 27; + if (!strcmp("dilate_l_pupil", name)) return 28; + if (!strcmp("dilate_r_pupil", name)) return 29; + if (!strcmp("raise_l_i_eyebrow", name)) return 30; + if (!strcmp("raise_r_i_eyebrow", name)) return 31; + if (!strcmp("raise_l_m_eyebrow", name)) return 32; + if (!strcmp("raise_r_m_eyebrow", name)) return 33; + if (!strcmp("raise_l_o_eyebrow", name)) return 34; + if (!strcmp("raise_r_o_eyebrow", name)) return 35; + if (!strcmp("squeeze_l_eyebrow", name)) return 36; + if (!strcmp("squeeze_r_eyebrow", name)) return 37; + if (!strcmp("puff_l_cheek", name)) return 38; + if (!strcmp("puff_r_cheek", name)) return 39; + if (!strcmp("lift_l_cheek", name)) return 40; + if (!strcmp("lift_r_cheek", name)) return 41; + if (!strcmp("shift_tongue_tip", name)) return 42; + if (!strcmp("raise_tongue_tip", name)) return 43; + if (!strcmp("thrust_tongue_tip", name)) return 44; + if (!strcmp("raise_tongue", name)) return 45; + if (!strcmp("tongue_roll", name)) return 46; + if (!strcmp("head_pitch", name)) return 47; + if (!strcmp("head_yaw", name)) return 48; + if (!strcmp("head_roll", name)) return 49; + if (!strcmp("lower_t_midlip_o", name)) return 50; + if (!strcmp("raise_b_midlip_o", name)) return 51; + if (!strcmp("stretch_l_cornerlip", name)) return 52; + if (!strcmp("stretch_r_cornerlip", name)) return 53; + if (!strcmp("lower_t_lip_lm_o", name)) return 54; + if (!strcmp("lower_t_lip_rm_o", name)) return 55; + if (!strcmp("raise_b_lip_lm_o", name)) return 56; + if (!strcmp("raise_b_lip_rm_o", name)) return 57; + if (!strcmp("raise_l_cornerlip_o", name)) return 58; + if (!strcmp("raise_r_cornerlip_o", name)) return 59; + if (!strcmp("stretch_l_nose", name)) return 60; + if (!strcmp("stretch_r_nose", name)) return 61; + if (!strcmp("raise_nose", name)) return 62; + if (!strcmp("bend_nose", name)) return 63; + if (!strcmp("raise_l_ear", name)) return 64; + if (!strcmp("raise_r_ear", name)) return 65; + if (!strcmp("pull_l_ear", name)) return 66; + if (!strcmp("pull_r_ear", name)) return 67; + return -1; + } +static Bool FAP_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 2: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 5: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 8: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 9: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 10: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 11: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 12: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 0; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 13: *AType = 0; - *QType = 6; + *QType = 0; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(6.2831853); + *b_max = FIX_MAX; return 1; case 14: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 0; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 17: + case 15: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 16: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 17: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 18: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 19: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 20: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 21: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 22: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 23: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 24: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 25: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 26: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 27: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 28: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 29: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 30: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 31: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 32: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 33: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 34: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 35: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 36: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 37: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 38: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 39: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 40: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 41: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 42: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 43: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 44: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 45: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 46: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 47: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 48: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 49: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 50: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 51: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 52: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 53: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 54: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 55: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 56: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 57: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 58: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 59: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 60: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 61: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 62: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 63: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 64: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 65: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 66: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 67: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *FAP_Create() +{ + M_FAP *p; + GF_SAFEALLOC(p, M_FAP); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_FAP); + + /*default field values*/ + p->open_jaw = 2 << 31; + p->lower_t_midlip = 2 << 31; + p->raise_b_midlip = 2 << 31; + p->stretch_l_corner = 2 << 31; + p->stretch_r_corner = 2 << 31; + p->lower_t_lip_lm = 2 << 31; + p->lower_t_lip_rm = 2 << 31; + p->lower_b_lip_lm = 2 << 31; + p->lower_b_lip_rm = 2 << 31; + p->raise_l_cornerlip = 2 << 31; + p->raise_r_cornerlip = 2 << 31; + p->thrust_jaw = 2 << 31; + p->shift_jaw = 2 << 31; + p->push_b_lip = 2 << 31; + p->push_t_lip = 2 << 31; + p->depress_chin = 2 << 31; + p->close_t_l_eyelid = 2 << 31; + p->close_t_r_eyelid = 2 << 31; + p->close_b_l_eyelid = 2 << 31; + p->close_b_r_eyelid = 2 << 31; + p->yaw_l_eyeball = 2 << 31; + p->yaw_r_eyeball = 2 << 31; + p->pitch_l_eyeball = 2 << 31; + p->pitch_r_eyeball = 2 << 31; + p->thrust_l_eyeball = 2 << 31; + p->thrust_r_eyeball = 2 << 31; + p->dilate_l_pupil = 2 << 31; + p->dilate_r_pupil = 2 << 31; + p->raise_l_i_eyebrow = 2 << 31; + p->raise_r_i_eyebrow = 2 << 31; + p->raise_l_m_eyebrow = 2 << 31; + p->raise_r_m_eyebrow = 2 << 31; + p->raise_l_o_eyebrow = 2 << 31; + p->raise_r_o_eyebrow = 2 << 31; + p->squeeze_l_eyebrow = 2 << 31; + p->squeeze_r_eyebrow = 2 << 31; + p->puff_l_cheek = 2 << 31; + p->puff_r_cheek = 2 << 31; + p->lift_l_cheek = 2 << 31; + p->lift_r_cheek = 2 << 31; + p->shift_tongue_tip = 2 << 31; + p->raise_tongue_tip = 2 << 31; + p->thrust_tongue_tip = 2 << 31; + p->raise_tongue = 2 << 31; + p->tongue_roll = 2 << 31; + p->head_pitch = 2 << 31; + p->head_yaw = 2 << 31; + p->head_roll = 2 << 31; + p->lower_t_midlip_o = 2 << 31; + p->raise_b_midlip_o = 2 << 31; + p->stretch_l_cornerlip = 2 << 31; + p->stretch_r_cornerlip = 2 << 31; + p->lower_t_lip_lm_o = 2 << 31; + p->lower_t_lip_rm_o = 2 << 31; + p->raise_b_lip_lm_o = 2 << 31; + p->raise_b_lip_rm_o = 2 << 31; + p->raise_l_cornerlip_o = 2 << 31; + p->raise_r_cornerlip_o = 2 << 31; + p->stretch_l_nose = 2 << 31; + p->stretch_r_nose = 2 << 31; + p->raise_nose = 2 << 31; + p->bend_nose = 2 << 31; + p->raise_l_ear = 2 << 31; + p->raise_r_ear = 2 << 31; + p->pull_l_ear = 2 << 31; + p->pull_r_ear = 2 << 31; + return (GF_Node *)p; +} + + +/* + FDP Node deletion +*/ + +static void FDP_Del(GF_Node *node) +{ + M_FDP *p = (M_FDP *) node; + gf_node_unregister((GF_Node *) p->featurePointsCoord, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->textureCoord, (GF_Node *) p); + gf_node_unregister_children((GF_Node *) p, p->faceDefTables); + gf_node_unregister_children((GF_Node *) p, p->faceSceneGraph); + gf_node_free((GF_Node *) p); +} + +static const u16 FDP_Def2All[] = { 0, 1, 2, 3, 4}; +static const u16 FDP_In2All[] = { 0, 1, 2, 3}; +static const u16 FDP_Out2All[] = { 0, 1, 2, 3}; + +static u32 FDP_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 5; + } +} + +static GF_Err FDP_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = FDP_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = FDP_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = FDP_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err FDP_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "featurePointsCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((M_FDP *)node)->featurePointsCoord; + return GF_OK; + case 1: + info->name = "textureCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((M_FDP *)node)->textureCoord; + return GF_OK; + case 2: + info->name = "faceDefTables"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFFaceDefTablesNode; + info->far_ptr = & ((M_FDP *)node)->faceDefTables; + return GF_OK; + case 3: + info->name = "faceSceneGraph"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_FDP *)node)->faceSceneGraph; + return GF_OK; + case 4: + info->name = "useOrthoTexture"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_FDP *) node)->useOrthoTexture; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 FDP_get_field_index_by_name(char *name) +{ + if (!strcmp("featurePointsCoord", name)) return 0; + if (!strcmp("textureCoord", name)) return 1; + if (!strcmp("faceDefTables", name)) return 2; + if (!strcmp("faceSceneGraph", name)) return 3; + if (!strcmp("useOrthoTexture", name)) return 4; + return -1; + } +static Bool FDP_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *FDP_Create() +{ + M_FDP *p; + GF_SAFEALLOC(p, M_FDP); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_FDP); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + FIT Node deletion +*/ + +static void FIT_Del(GF_Node *node) +{ + M_FIT *p = (M_FIT *) node; + gf_sg_mfint32_del(p->FAPs); + gf_sg_mfint32_del(p->Graph); + gf_sg_mfint32_del(p->numeratorExp); + gf_sg_mfint32_del(p->denominatorExp); + gf_sg_mfint32_del(p->numeratorImpulse); + gf_sg_mfint32_del(p->numeratorTerms); + gf_sg_mfint32_del(p->denominatorTerms); + gf_sg_mffloat_del(p->numeratorCoefs); + gf_sg_mffloat_del(p->denominatorCoefs); + gf_node_free((GF_Node *) p); +} + +static const u16 FIT_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 FIT_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 FIT_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; + +static u32 FIT_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 9; + case GF_SG_FIELD_CODING_DEF: return 9; + case GF_SG_FIELD_CODING_OUT: return 9; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 9; + } +} + +static GF_Err FIT_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = FIT_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = FIT_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = FIT_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err FIT_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "FAPs"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FIT *) node)->FAPs; + return GF_OK; + case 1: + info->name = "Graph"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FIT *) node)->Graph; + return GF_OK; + case 2: + info->name = "numeratorExp"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FIT *) node)->numeratorExp; + return GF_OK; + case 3: + info->name = "denominatorExp"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FIT *) node)->denominatorExp; + return GF_OK; + case 4: + info->name = "numeratorImpulse"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FIT *) node)->numeratorImpulse; + return GF_OK; + case 5: + info->name = "numeratorTerms"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FIT *) node)->numeratorTerms; + return GF_OK; + case 6: + info->name = "denominatorTerms"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FIT *) node)->denominatorTerms; + return GF_OK; + case 7: + info->name = "numeratorCoefs"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_FIT *) node)->numeratorCoefs; + return GF_OK; + case 8: + info->name = "denominatorCoefs"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_FIT *) node)->denominatorCoefs; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 FIT_get_field_index_by_name(char *name) +{ + if (!strcmp("FAPs", name)) return 0; + if (!strcmp("Graph", name)) return 1; + if (!strcmp("numeratorExp", name)) return 2; + if (!strcmp("denominatorExp", name)) return 3; + if (!strcmp("numeratorImpulse", name)) return 4; + if (!strcmp("numeratorTerms", name)) return 5; + if (!strcmp("denominatorTerms", name)) return 6; + if (!strcmp("numeratorCoefs", name)) return 7; + if (!strcmp("denominatorCoefs", name)) return 8; + return -1; + } +static Bool FIT_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 13; + *QT13_bits = 7; + *b_min = FLT2FIX(-1); + *b_max = FLT2FIX(68); + return 1; + case 1: + *AType = 0; + *QType = 13; + *QT13_bits = 7; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(68); + return 1; + case 2: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(15); + return 1; + case 3: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(15); + return 1; + case 4: + *AType = 0; + *QType = 13; + *QT13_bits = 10; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1023); + return 1; + case 5: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(10); + return 1; + case 6: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(10); + return 1; + default: + return 0; + } +} + + + +GF_Node *FIT_Create() +{ + M_FIT *p; + GF_SAFEALLOC(p, M_FIT); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_FIT); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + Fog Node deletion +*/ + +static void Fog_Del(GF_Node *node) +{ + M_Fog *p = (M_Fog *) node; + gf_sg_sfstring_del(p->fogType); + gf_node_free((GF_Node *) p); +} + +static const u16 Fog_Def2All[] = { 0, 1, 2}; +static const u16 Fog_In2All[] = { 0, 1, 2, 3}; +static const u16 Fog_Out2All[] = { 0, 1, 2, 4}; +static const u16 Fog_Dyn2All[] = { 0, 2}; + +static u32 Fog_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 2; + default: + return 5; + } +} + +static GF_Err Fog_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Fog_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Fog_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Fog_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Fog_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Fog_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_Fog *) node)->color; + return GF_OK; + case 1: + info->name = "fogType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_Fog *) node)->fogType; + return GF_OK; + case 2: + info->name = "visibilityRange"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Fog *) node)->visibilityRange; + return GF_OK; + case 3: + info->name = "set_bind"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Fog *)node)->on_set_bind; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Fog *) node)->set_bind; + return GF_OK; + case 4: + info->name = "isBound"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Fog *) node)->isBound; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Fog_get_field_index_by_name(char *name) +{ + if (!strcmp("color", name)) return 0; + if (!strcmp("fogType", name)) return 1; + if (!strcmp("visibilityRange", name)) return 2; + if (!strcmp("set_bind", name)) return 3; + if (!strcmp("isBound", name)) return 4; + return -1; + } +static Bool Fog_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 4; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Fog_Create() +{ + M_Fog *p; + GF_SAFEALLOC(p, M_Fog); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Fog); + + /*default field values*/ + p->color.red = FLT2FIX(1); + p->color.green = FLT2FIX(1); + p->color.blue = FLT2FIX(1); + p->fogType.buffer = (char*)gf_malloc(sizeof(char) * 7); + strcpy(p->fogType.buffer, "LINEAR"); + p->visibilityRange = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + FontStyle Node deletion +*/ + +static void FontStyle_Del(GF_Node *node) +{ + M_FontStyle *p = (M_FontStyle *) node; + gf_sg_mfstring_del(p->family); + gf_sg_mfstring_del(p->justify); + gf_sg_sfstring_del(p->language); + gf_sg_sfstring_del(p->style); + gf_node_free((GF_Node *) p); +} + +static const u16 FontStyle_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 FontStyle_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 FontStyle_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; + +static u32 FontStyle_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 9; + case GF_SG_FIELD_CODING_DEF: return 9; + case GF_SG_FIELD_CODING_OUT: return 9; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 9; + } +} + +static GF_Err FontStyle_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = FontStyle_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = FontStyle_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = FontStyle_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err FontStyle_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "family"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_FontStyle *) node)->family; + return GF_OK; + case 1: + info->name = "horizontal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_FontStyle *) node)->horizontal; + return GF_OK; + case 2: + info->name = "justify"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_FontStyle *) node)->justify; + return GF_OK; + case 3: + info->name = "language"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_FontStyle *) node)->language; + return GF_OK; + case 4: + info->name = "leftToRight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_FontStyle *) node)->leftToRight; + return GF_OK; + case 5: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_FontStyle *) node)->size; + return GF_OK; + case 6: + info->name = "spacing"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_FontStyle *) node)->spacing; + return GF_OK; + case 7: + info->name = "style"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_FontStyle *) node)->style; + return GF_OK; + case 8: + info->name = "topToBottom"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_FontStyle *) node)->topToBottom; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 FontStyle_get_field_index_by_name(char *name) +{ + if (!strcmp("family", name)) return 0; + if (!strcmp("horizontal", name)) return 1; + if (!strcmp("justify", name)) return 2; + if (!strcmp("language", name)) return 3; + if (!strcmp("leftToRight", name)) return 4; + if (!strcmp("size", name)) return 5; + if (!strcmp("spacing", name)) return 6; + if (!strcmp("style", name)) return 7; + if (!strcmp("topToBottom", name)) return 8; + return -1; + } +static Bool FontStyle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 5: + *AType = 0; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 0; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *FontStyle_Create() +{ + M_FontStyle *p; + GF_SAFEALLOC(p, M_FontStyle); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_FontStyle); + + /*default field values*/ + p->family.vals = (char**)gf_malloc(sizeof(SFString)*1); + p->family.count = 1; + p->family.vals[0] = (char*)gf_malloc(sizeof(char) * 6); + strcpy(p->family.vals[0], "SERIF"); + p->horizontal = 1; + p->justify.vals = (char**)gf_malloc(sizeof(SFString)*1); + p->justify.count = 1; + p->justify.vals[0] = (char*)gf_malloc(sizeof(char) * 6); + strcpy(p->justify.vals[0], "BEGIN"); + p->leftToRight = 1; + p->size = FLT2FIX(1.0); + p->spacing = FLT2FIX(1.0); + p->style.buffer = (char*)gf_malloc(sizeof(char) * 6); + strcpy(p->style.buffer, "PLAIN"); + p->topToBottom = 1; + return (GF_Node *)p; +} + + +/* + Form Node deletion +*/ + +static void Form_Del(GF_Node *node) +{ + M_Form *p = (M_Form *) node; + gf_sg_mfint32_del(p->groups); + gf_sg_mfstring_del(p->constraints); + gf_sg_mfint32_del(p->groupsIndex); + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Form_Def2All[] = { 2, 3, 4, 5, 6}; +static const u16 Form_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 Form_Out2All[] = { 2, 3, 4, 5, 6}; +static const u16 Form_Dyn2All[] = { 3}; + +static u32 Form_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 7; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 7; + } +} + +static GF_Err Form_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Form_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Form_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Form_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Form_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Form_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Form *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Form *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Form *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Form *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Form *)node)->children; + return GF_OK; + case 3: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Form *) node)->size; + return GF_OK; + case 4: + info->name = "groups"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_Form *) node)->groups; + return GF_OK; + case 5: + info->name = "constraints"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_Form *) node)->constraints; + return GF_OK; + case 6: + info->name = "groupsIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_Form *) node)->groupsIndex; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Form_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("size", name)) return 3; + if (!strcmp("groups", name)) return 4; + if (!strcmp("constraints", name)) return 5; + if (!strcmp("groupsIndex", name)) return 6; + return -1; + } +static Bool Form_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 3: + *AType = 12; + *QType = 12; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 0; + *QType = 13; + *QT13_bits = 10; + *b_min = FLT2FIX(-1); + *b_max = FLT2FIX(1022); + return 1; + case 6: + *AType = 0; + *QType = 13; + *QT13_bits = 10; + *b_min = FLT2FIX(-1); + *b_max = FLT2FIX(1022); + return 1; + default: + return 0; + } +} + + + +GF_Node *Form_Create() +{ + M_Form *p; + GF_SAFEALLOC(p, M_Form); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Form); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->size.x = FLT2FIX(-1); + p->size.y = FLT2FIX(-1); + return (GF_Node *)p; +} + + +/* + Group Node deletion +*/ + +static void Group_Del(GF_Node *node) +{ + M_Group *p = (M_Group *) node; + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Group_Def2All[] = { 2}; +static const u16 Group_In2All[] = { 0, 1, 2}; +static const u16 Group_Out2All[] = { 2}; + +static u32 Group_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 3; + } +} + +static GF_Err Group_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Group_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Group_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Group_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Group_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Group *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Group *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Group *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Group *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Group *)node)->children; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Group_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + return -1; + } +static Bool Group_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *Group_Create() +{ + M_Group *p; + GF_SAFEALLOC(p, M_Group); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Group); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + ImageTexture Node deletion +*/ + +static void ImageTexture_Del(GF_Node *node) +{ + M_ImageTexture *p = (M_ImageTexture *) node; + gf_sg_mfurl_del(p->url); + gf_node_free((GF_Node *) p); +} + +static const u16 ImageTexture_Def2All[] = { 0, 1, 2}; +static const u16 ImageTexture_In2All[] = { 0}; +static const u16 ImageTexture_Out2All[] = { 0}; + +static u32 ImageTexture_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 3; + } +} + +static GF_Err ImageTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = ImageTexture_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = ImageTexture_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = ImageTexture_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err ImageTexture_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_ImageTexture *) node)->url; + return GF_OK; + case 1: + info->name = "repeatS"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ImageTexture *) node)->repeatS; + return GF_OK; + case 2: + info->name = "repeatT"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ImageTexture *) node)->repeatT; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 ImageTexture_get_field_index_by_name(char *name) +{ + if (!strcmp("url", name)) return 0; + if (!strcmp("repeatS", name)) return 1; + if (!strcmp("repeatT", name)) return 2; + return -1; + } +static Bool ImageTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *ImageTexture_Create() +{ + M_ImageTexture *p; + GF_SAFEALLOC(p, M_ImageTexture); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_ImageTexture); + + /*default field values*/ + p->repeatS = 1; + p->repeatT = 1; + return (GF_Node *)p; +} + + +/* + IndexedFaceSet Node deletion +*/ + +static void IndexedFaceSet_Del(GF_Node *node) +{ + M_IndexedFaceSet *p = (M_IndexedFaceSet *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_sg_mfint32_del(p->set_coordIndex); + gf_sg_mfint32_del(p->set_normalIndex); + gf_sg_mfint32_del(p->set_texCoordIndex); + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->normal, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->texCoord, (GF_Node *) p); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mfint32_del(p->coordIndex); + gf_sg_mfint32_del(p->normalIndex); + gf_sg_mfint32_del(p->texCoordIndex); + gf_node_free((GF_Node *) p); +} + +static const u16 IndexedFaceSet_Def2All[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; +static const u16 IndexedFaceSet_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 IndexedFaceSet_Out2All[] = { 4, 5, 6, 7}; + +static u32 IndexedFaceSet_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 8; + case GF_SG_FIELD_CODING_DEF: return 14; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 18; + } +} + +static GF_Err IndexedFaceSet_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = IndexedFaceSet_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = IndexedFaceSet_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = IndexedFaceSet_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err IndexedFaceSet_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedFaceSet *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet *) node)->set_colorIndex; + return GF_OK; + case 1: + info->name = "set_coordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedFaceSet *)node)->on_set_coordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet *) node)->set_coordIndex; + return GF_OK; + case 2: + info->name = "set_normalIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedFaceSet *)node)->on_set_normalIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet *) node)->set_normalIndex; + return GF_OK; + case 3: + info->name = "set_texCoordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedFaceSet *)node)->on_set_texCoordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet *) node)->set_texCoordIndex; + return GF_OK; + case 4: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_IndexedFaceSet *)node)->color; + return GF_OK; + case 5: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((M_IndexedFaceSet *)node)->coord; + return GF_OK; + case 6: + info->name = "normal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((M_IndexedFaceSet *)node)->normal; + return GF_OK; + case 7: + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((M_IndexedFaceSet *)node)->texCoord; + return GF_OK; + case 8: + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_IndexedFaceSet *) node)->ccw; + return GF_OK; + case 9: + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet *) node)->colorIndex; + return GF_OK; + case 10: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_IndexedFaceSet *) node)->colorPerVertex; + return GF_OK; + case 11: + info->name = "convex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_IndexedFaceSet *) node)->convex; + return GF_OK; + case 12: + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet *) node)->coordIndex; + return GF_OK; + case 13: + info->name = "creaseAngle"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_IndexedFaceSet *) node)->creaseAngle; + return GF_OK; + case 14: + info->name = "normalIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet *) node)->normalIndex; + return GF_OK; + case 15: + info->name = "normalPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_IndexedFaceSet *) node)->normalPerVertex; + return GF_OK; + case 16: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_IndexedFaceSet *) node)->solid; + return GF_OK; + case 17: + info->name = "texCoordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet *) node)->texCoordIndex; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IndexedFaceSet_get_field_index_by_name(char *name) +{ + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("set_coordIndex", name)) return 1; + if (!strcmp("set_normalIndex", name)) return 2; + if (!strcmp("set_texCoordIndex", name)) return 3; + if (!strcmp("color", name)) return 4; + if (!strcmp("coord", name)) return 5; + if (!strcmp("normal", name)) return 6; + if (!strcmp("texCoord", name)) return 7; + if (!strcmp("ccw", name)) return 8; + if (!strcmp("colorIndex", name)) return 9; + if (!strcmp("colorPerVertex", name)) return 10; + if (!strcmp("convex", name)) return 11; + if (!strcmp("coordIndex", name)) return 12; + if (!strcmp("creaseAngle", name)) return 13; + if (!strcmp("normalIndex", name)) return 14; + if (!strcmp("normalPerVertex", name)) return 15; + if (!strcmp("solid", name)) return 16; + if (!strcmp("texCoordIndex", name)) return 17; + return -1; + } +static Bool IndexedFaceSet_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 9: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 12: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 13: + *AType = 0; + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(6.2831853); + return 1; + case 14: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 17: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *IndexedFaceSet_Create() +{ + M_IndexedFaceSet *p; + GF_SAFEALLOC(p, M_IndexedFaceSet); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_IndexedFaceSet); + + /*default field values*/ + p->ccw = 1; + p->colorPerVertex = 1; + p->convex = 1; + p->creaseAngle = FLT2FIX(0.0); + p->normalPerVertex = 1; + p->solid = 1; + return (GF_Node *)p; +} + + +/* + IndexedFaceSet2D Node deletion +*/ + +static void IndexedFaceSet2D_Del(GF_Node *node) +{ + M_IndexedFaceSet2D *p = (M_IndexedFaceSet2D *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_sg_mfint32_del(p->set_coordIndex); + gf_sg_mfint32_del(p->set_texCoordIndex); + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->texCoord, (GF_Node *) p); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mfint32_del(p->coordIndex); + gf_sg_mfint32_del(p->texCoordIndex); + gf_node_free((GF_Node *) p); +} + +static const u16 IndexedFaceSet2D_Def2All[] = { 3, 4, 5, 6, 7, 8, 9, 10}; +static const u16 IndexedFaceSet2D_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 IndexedFaceSet2D_Out2All[] = { 3, 4, 5}; + +static u32 IndexedFaceSet2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 11; + } +} + +static GF_Err IndexedFaceSet2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = IndexedFaceSet2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = IndexedFaceSet2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = IndexedFaceSet2D_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err IndexedFaceSet2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedFaceSet2D *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet2D *) node)->set_colorIndex; + return GF_OK; + case 1: + info->name = "set_coordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedFaceSet2D *)node)->on_set_coordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet2D *) node)->set_coordIndex; + return GF_OK; + case 2: + info->name = "set_texCoordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedFaceSet2D *)node)->on_set_texCoordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet2D *) node)->set_texCoordIndex; + return GF_OK; + case 3: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_IndexedFaceSet2D *)node)->color; + return GF_OK; + case 4: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinate2DNode; + info->far_ptr = & ((M_IndexedFaceSet2D *)node)->coord; + return GF_OK; + case 5: + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((M_IndexedFaceSet2D *)node)->texCoord; + return GF_OK; + case 6: + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet2D *) node)->colorIndex; + return GF_OK; + case 7: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_IndexedFaceSet2D *) node)->colorPerVertex; + return GF_OK; + case 8: + info->name = "convex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_IndexedFaceSet2D *) node)->convex; + return GF_OK; + case 9: + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet2D *) node)->coordIndex; + return GF_OK; + case 10: + info->name = "texCoordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedFaceSet2D *) node)->texCoordIndex; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IndexedFaceSet2D_get_field_index_by_name(char *name) +{ + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("set_coordIndex", name)) return 1; + if (!strcmp("set_texCoordIndex", name)) return 2; + if (!strcmp("color", name)) return 3; + if (!strcmp("coord", name)) return 4; + if (!strcmp("texCoord", name)) return 5; + if (!strcmp("colorIndex", name)) return 6; + if (!strcmp("colorPerVertex", name)) return 7; + if (!strcmp("convex", name)) return 8; + if (!strcmp("coordIndex", name)) return 9; + if (!strcmp("texCoordIndex", name)) return 10; + return -1; + } +static Bool IndexedFaceSet2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 6: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 9: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 10: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *IndexedFaceSet2D_Create() +{ + M_IndexedFaceSet2D *p; + GF_SAFEALLOC(p, M_IndexedFaceSet2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_IndexedFaceSet2D); + + /*default field values*/ + p->colorPerVertex = 1; + p->convex = 1; + return (GF_Node *)p; +} + + +/* + IndexedLineSet Node deletion +*/ + +static void IndexedLineSet_Del(GF_Node *node) +{ + M_IndexedLineSet *p = (M_IndexedLineSet *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_sg_mfint32_del(p->set_coordIndex); + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mfint32_del(p->coordIndex); + gf_node_free((GF_Node *) p); +} + +static const u16 IndexedLineSet_Def2All[] = { 2, 3, 4, 5, 6}; +static const u16 IndexedLineSet_In2All[] = { 0, 1, 2, 3}; +static const u16 IndexedLineSet_Out2All[] = { 2, 3}; + +static u32 IndexedLineSet_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 7; + } +} + +static GF_Err IndexedLineSet_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = IndexedLineSet_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = IndexedLineSet_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = IndexedLineSet_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err IndexedLineSet_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedLineSet *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedLineSet *) node)->set_colorIndex; + return GF_OK; + case 1: + info->name = "set_coordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedLineSet *)node)->on_set_coordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedLineSet *) node)->set_coordIndex; + return GF_OK; + case 2: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_IndexedLineSet *)node)->color; + return GF_OK; + case 3: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((M_IndexedLineSet *)node)->coord; + return GF_OK; + case 4: + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedLineSet *) node)->colorIndex; + return GF_OK; + case 5: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_IndexedLineSet *) node)->colorPerVertex; + return GF_OK; + case 6: + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedLineSet *) node)->coordIndex; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IndexedLineSet_get_field_index_by_name(char *name) +{ + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("set_coordIndex", name)) return 1; + if (!strcmp("color", name)) return 2; + if (!strcmp("coord", name)) return 3; + if (!strcmp("colorIndex", name)) return 4; + if (!strcmp("colorPerVertex", name)) return 5; + if (!strcmp("coordIndex", name)) return 6; + return -1; + } +static Bool IndexedLineSet_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 4: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *IndexedLineSet_Create() +{ + M_IndexedLineSet *p; + GF_SAFEALLOC(p, M_IndexedLineSet); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_IndexedLineSet); + + /*default field values*/ + p->colorPerVertex = 1; + return (GF_Node *)p; +} + + +/* + IndexedLineSet2D Node deletion +*/ + +static void IndexedLineSet2D_Del(GF_Node *node) +{ + M_IndexedLineSet2D *p = (M_IndexedLineSet2D *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_sg_mfint32_del(p->set_coordIndex); + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mfint32_del(p->coordIndex); + gf_node_free((GF_Node *) p); +} + +static const u16 IndexedLineSet2D_Def2All[] = { 2, 3, 4, 5, 6}; +static const u16 IndexedLineSet2D_In2All[] = { 0, 1, 2, 3}; +static const u16 IndexedLineSet2D_Out2All[] = { 2, 3}; + +static u32 IndexedLineSet2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 7; + } +} + +static GF_Err IndexedLineSet2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = IndexedLineSet2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = IndexedLineSet2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = IndexedLineSet2D_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err IndexedLineSet2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedLineSet2D *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedLineSet2D *) node)->set_colorIndex; + return GF_OK; + case 1: + info->name = "set_coordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_IndexedLineSet2D *)node)->on_set_coordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedLineSet2D *) node)->set_coordIndex; + return GF_OK; + case 2: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_IndexedLineSet2D *)node)->color; + return GF_OK; + case 3: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinate2DNode; + info->far_ptr = & ((M_IndexedLineSet2D *)node)->coord; + return GF_OK; + case 4: + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedLineSet2D *) node)->colorIndex; + return GF_OK; + case 5: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_IndexedLineSet2D *) node)->colorPerVertex; + return GF_OK; + case 6: + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_IndexedLineSet2D *) node)->coordIndex; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IndexedLineSet2D_get_field_index_by_name(char *name) +{ + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("set_coordIndex", name)) return 1; + if (!strcmp("color", name)) return 2; + if (!strcmp("coord", name)) return 3; + if (!strcmp("colorIndex", name)) return 4; + if (!strcmp("colorPerVertex", name)) return 5; + if (!strcmp("coordIndex", name)) return 6; + return -1; + } +static Bool IndexedLineSet2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 4: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *IndexedLineSet2D_Create() +{ + M_IndexedLineSet2D *p; + GF_SAFEALLOC(p, M_IndexedLineSet2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_IndexedLineSet2D); + + /*default field values*/ + p->colorPerVertex = 1; + return (GF_Node *)p; +} + + +/* + Inline Node deletion +*/ + +static void Inline_Del(GF_Node *node) +{ + M_Inline *p = (M_Inline *) node; + gf_sg_mfurl_del(p->url); + gf_node_free((GF_Node *) p); +} + +static const u16 Inline_Def2All[] = { 0}; +static const u16 Inline_In2All[] = { 0}; +static const u16 Inline_Out2All[] = { 0}; + +static u32 Inline_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 1; + } +} + +static GF_Err Inline_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Inline_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Inline_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Inline_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Inline_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_Inline *) node)->url; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Inline_get_field_index_by_name(char *name) +{ + if (!strcmp("url", name)) return 0; + return -1; + } +static Bool Inline_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *Inline_Create() +{ + M_Inline *p; + GF_SAFEALLOC(p, M_Inline); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Inline); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + LOD Node deletion +*/ + +static void LOD_Del(GF_Node *node) +{ + M_LOD *p = (M_LOD *) node; + gf_node_unregister_children((GF_Node *) p, p->level); + gf_sg_mffloat_del(p->range); + gf_node_free((GF_Node *) p); +} + +static const u16 LOD_Def2All[] = { 0, 1, 2}; +static const u16 LOD_In2All[] = { 0}; +static const u16 LOD_Out2All[] = { 0}; + +static u32 LOD_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 3; + } +} + +static GF_Err LOD_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = LOD_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = LOD_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = LOD_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err LOD_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "level"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_LOD *)node)->level; + return GF_OK; + case 1: + info->name = "center"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_LOD *) node)->center; + return GF_OK; + case 2: + info->name = "range"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_LOD *) node)->range; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 LOD_get_field_index_by_name(char *name) +{ + if (!strcmp("level", name)) return 0; + if (!strcmp("center", name)) return 1; + if (!strcmp("range", name)) return 2; + return -1; + } +static Bool LOD_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 2: + *AType = 0; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *LOD_Create() +{ + M_LOD *p; + GF_SAFEALLOC(p, M_LOD); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_LOD); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + Layer2D Node deletion +*/ + +static void Layer2D_Del(GF_Node *node) +{ + M_Layer2D *p = (M_Layer2D *) node; + gf_node_unregister((GF_Node *) p->background, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->viewport, (GF_Node *) p); + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Layer2D_Def2All[] = { 2, 3, 4, 5}; +static const u16 Layer2D_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 Layer2D_Out2All[] = { 2, 3, 4, 5}; +static const u16 Layer2D_Dyn2All[] = { 3}; + +static u32 Layer2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 6; + } +} + +static GF_Err Layer2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Layer2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Layer2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Layer2D_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Layer2D_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Layer2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Layer2D *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Layer2D *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Layer2D *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Layer2D *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Layer2D *)node)->children; + return GF_OK; + case 3: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Layer2D *) node)->size; + return GF_OK; + case 4: + info->name = "background"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFBackground2DNode; + info->far_ptr = & ((M_Layer2D *)node)->background; + return GF_OK; + case 5: + info->name = "viewport"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFViewportNode; + info->far_ptr = & ((M_Layer2D *)node)->viewport; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Layer2D_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("size", name)) return 3; + if (!strcmp("background", name)) return 4; + if (!strcmp("viewport", name)) return 5; + return -1; + } +static Bool Layer2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 3: + *AType = 12; + *QType = 12; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Layer2D_Create() +{ + M_Layer2D *p; + GF_SAFEALLOC(p, M_Layer2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Layer2D); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->size.x = FLT2FIX(-1); + p->size.y = FLT2FIX(-1); + return (GF_Node *)p; +} + + +/* + Layer3D Node deletion +*/ + +static void Layer3D_Del(GF_Node *node) +{ + M_Layer3D *p = (M_Layer3D *) node; + gf_node_unregister((GF_Node *) p->background, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->fog, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->navigationInfo, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->viewpoint, (GF_Node *) p); + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Layer3D_Def2All[] = { 2, 3, 4, 5, 6, 7}; +static const u16 Layer3D_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 Layer3D_Out2All[] = { 2, 3, 4, 5, 6, 7}; +static const u16 Layer3D_Dyn2All[] = { 3}; + +static u32 Layer3D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 8; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 8; + } +} + +static GF_Err Layer3D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Layer3D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Layer3D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Layer3D_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Layer3D_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Layer3D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Layer3D *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Layer3D *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Layer3D *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Layer3D *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Layer3D *)node)->children; + return GF_OK; + case 3: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Layer3D *) node)->size; + return GF_OK; + case 4: + info->name = "background"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFBackground3DNode; + info->far_ptr = & ((M_Layer3D *)node)->background; + return GF_OK; + case 5: + info->name = "fog"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFFogNode; + info->far_ptr = & ((M_Layer3D *)node)->fog; + return GF_OK; + case 6: + info->name = "navigationInfo"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNavigationInfoNode; + info->far_ptr = & ((M_Layer3D *)node)->navigationInfo; + return GF_OK; + case 7: + info->name = "viewpoint"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFViewpointNode; + info->far_ptr = & ((M_Layer3D *)node)->viewpoint; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Layer3D_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("size", name)) return 3; + if (!strcmp("background", name)) return 4; + if (!strcmp("fog", name)) return 5; + if (!strcmp("navigationInfo", name)) return 6; + if (!strcmp("viewpoint", name)) return 7; + return -1; + } +static Bool Layer3D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 3: + *AType = 12; + *QType = 12; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Layer3D_Create() +{ + M_Layer3D *p; + GF_SAFEALLOC(p, M_Layer3D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Layer3D); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->size.x = FLT2FIX(-1); + p->size.y = FLT2FIX(-1); + return (GF_Node *)p; +} + + +/* + Layout Node deletion +*/ + +static void Layout_Del(GF_Node *node) +{ + M_Layout *p = (M_Layout *) node; + gf_sg_mfstring_del(p->justify); + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Layout_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; +static const u16 Layout_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; +static const u16 Layout_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; +static const u16 Layout_Dyn2All[] = { 4, 9, 13}; + +static u32 Layout_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 15; + case GF_SG_FIELD_CODING_DEF: return 13; + case GF_SG_FIELD_CODING_OUT: return 13; + case GF_SG_FIELD_CODING_DYN: return 3; + default: + return 15; + } +} + +static GF_Err Layout_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Layout_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Layout_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Layout_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Layout_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Layout_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Layout *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Layout *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Layout *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Layout *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Layout *)node)->children; + return GF_OK; + case 3: + info->name = "wrap"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Layout *) node)->wrap; + return GF_OK; + case 4: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Layout *) node)->size; + return GF_OK; + case 5: + info->name = "horizontal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Layout *) node)->horizontal; + return GF_OK; + case 6: + info->name = "justify"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_Layout *) node)->justify; + return GF_OK; + case 7: + info->name = "leftToRight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Layout *) node)->leftToRight; + return GF_OK; + case 8: + info->name = "topToBottom"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Layout *) node)->topToBottom; + return GF_OK; + case 9: + info->name = "spacing"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Layout *) node)->spacing; + return GF_OK; + case 10: + info->name = "smoothScroll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Layout *) node)->smoothScroll; + return GF_OK; + case 11: + info->name = "loop"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Layout *) node)->loop; + return GF_OK; + case 12: + info->name = "scrollVertical"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Layout *) node)->scrollVertical; + return GF_OK; + case 13: + info->name = "scrollRate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Layout *) node)->scrollRate; + return GF_OK; + case 14: + info->name = "scrollMode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Layout *) node)->scrollMode; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Layout_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("wrap", name)) return 3; + if (!strcmp("size", name)) return 4; + if (!strcmp("horizontal", name)) return 5; + if (!strcmp("justify", name)) return 6; + if (!strcmp("leftToRight", name)) return 7; + if (!strcmp("topToBottom", name)) return 8; + if (!strcmp("spacing", name)) return 9; + if (!strcmp("smoothScroll", name)) return 10; + if (!strcmp("loop", name)) return 11; + if (!strcmp("scrollVertical", name)) return 12; + if (!strcmp("scrollRate", name)) return 13; + if (!strcmp("scrollMode", name)) return 14; + return -1; + } +static Bool Layout_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 4: + *AType = 12; + *QType = 12; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 9: + *AType = 7; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 13: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 14: + *AType = 0; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(-1); + *b_max = FLT2FIX(1); + return 1; + default: + return 0; + } +} + + + +GF_Node *Layout_Create() +{ + M_Layout *p; + GF_SAFEALLOC(p, M_Layout); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Layout); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->size.x = FLT2FIX(-1); + p->size.y = FLT2FIX(-1); + p->horizontal = 1; + p->justify.vals = (char**)gf_malloc(sizeof(SFString)*1); + p->justify.count = 1; + p->justify.vals[0] = (char*)gf_malloc(sizeof(char) * 6); + strcpy(p->justify.vals[0], "BEGIN"); + p->leftToRight = 1; + p->topToBottom = 1; + p->spacing = FLT2FIX(1); + p->scrollVertical = 1; + p->scrollRate = FLT2FIX(0); + p->scrollMode = 0; + return (GF_Node *)p; +} + + +/* + LineProperties Node deletion +*/ + +static void LineProperties_Del(GF_Node *node) +{ + M_LineProperties *p = (M_LineProperties *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 LineProperties_Def2All[] = { 0, 1, 2}; +static const u16 LineProperties_In2All[] = { 0, 1, 2}; +static const u16 LineProperties_Out2All[] = { 0, 1, 2}; +static const u16 LineProperties_Dyn2All[] = { 0, 2}; + +static u32 LineProperties_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 2; + default: + return 3; + } +} + +static GF_Err LineProperties_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = LineProperties_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = LineProperties_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = LineProperties_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = LineProperties_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err LineProperties_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "lineColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_LineProperties *) node)->lineColor; + return GF_OK; + case 1: + info->name = "lineStyle"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_LineProperties *) node)->lineStyle; + return GF_OK; + case 2: + info->name = "width"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_LineProperties *) node)->width; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 LineProperties_get_field_index_by_name(char *name) +{ + if (!strcmp("lineColor", name)) return 0; + if (!strcmp("lineStyle", name)) return 1; + if (!strcmp("width", name)) return 2; + return -1; + } +static Bool LineProperties_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 4; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 1: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(5); + return 1; + case 2: + *AType = 7; + *QType = 12; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *LineProperties_Create() +{ + M_LineProperties *p; + GF_SAFEALLOC(p, M_LineProperties); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_LineProperties); + + /*default field values*/ + p->lineColor.red = FLT2FIX(0); + p->lineColor.green = FLT2FIX(0); + p->lineColor.blue = FLT2FIX(0); + p->lineStyle = 0; + p->width = FLT2FIX(1); + return (GF_Node *)p; +} + + +/* + ListeningPoint Node deletion +*/ + +static void ListeningPoint_Del(GF_Node *node) +{ + M_ListeningPoint *p = (M_ListeningPoint *) node; + gf_sg_sfstring_del(p->description); + gf_node_free((GF_Node *) p); +} + +static const u16 ListeningPoint_Def2All[] = { 1, 2, 3, 4}; +static const u16 ListeningPoint_In2All[] = { 0, 1, 2, 3}; +static const u16 ListeningPoint_Out2All[] = { 1, 2, 3, 5, 6}; +static const u16 ListeningPoint_Dyn2All[] = { 2, 3}; + +static u32 ListeningPoint_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_DYN: return 2; + default: + return 7; + } +} + +static GF_Err ListeningPoint_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = ListeningPoint_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = ListeningPoint_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = ListeningPoint_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = ListeningPoint_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err ListeningPoint_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_bind"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_ListeningPoint *)node)->on_set_bind; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ListeningPoint *) node)->set_bind; + return GF_OK; + case 1: + info->name = "jump"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ListeningPoint *) node)->jump; + return GF_OK; + case 2: + info->name = "orientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_ListeningPoint *) node)->orientation; + return GF_OK; + case 3: + info->name = "position"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_ListeningPoint *) node)->position; + return GF_OK; + case 4: + info->name = "description"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_ListeningPoint *) node)->description; + return GF_OK; + case 5: + info->name = "bindTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_ListeningPoint *) node)->bindTime; + return GF_OK; + case 6: + info->name = "isBound"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ListeningPoint *) node)->isBound; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 ListeningPoint_get_field_index_by_name(char *name) +{ + if (!strcmp("set_bind", name)) return 0; + if (!strcmp("jump", name)) return 1; + if (!strcmp("orientation", name)) return 2; + if (!strcmp("position", name)) return 3; + if (!strcmp("description", name)) return 4; + if (!strcmp("bindTime", name)) return 5; + if (!strcmp("isBound", name)) return 6; + return -1; + } +static Bool ListeningPoint_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 2: + *AType = 10; + *QType = 10; + return 1; + case 3: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *ListeningPoint_Create() +{ + M_ListeningPoint *p; + GF_SAFEALLOC(p, M_ListeningPoint); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_ListeningPoint); + + /*default field values*/ + p->jump = 1; + p->orientation.x = FLT2FIX(0); + p->orientation.y = FLT2FIX(0); + p->orientation.z = FLT2FIX(1); + p->orientation.q = FLT2FIX(0); + p->position.x = FLT2FIX(0); + p->position.y = FLT2FIX(0); + p->position.z = FLT2FIX(10); + return (GF_Node *)p; +} + + +/* + Material Node deletion +*/ + +static void Material_Del(GF_Node *node) +{ + M_Material *p = (M_Material *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 Material_Def2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 Material_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 Material_Out2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 Material_Dyn2All[] = { 0, 1, 2, 3, 4, 5}; + +static u32 Material_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 6; + default: + return 6; + } +} + +static GF_Err Material_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Material_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Material_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Material_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Material_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Material_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "ambientIntensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Material *) node)->ambientIntensity; + return GF_OK; + case 1: + info->name = "diffuseColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_Material *) node)->diffuseColor; + return GF_OK; + case 2: + info->name = "emissiveColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_Material *) node)->emissiveColor; + return GF_OK; + case 3: + info->name = "shininess"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Material *) node)->shininess; + return GF_OK; + case 4: + info->name = "specularColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_Material *) node)->specularColor; + return GF_OK; + case 5: + info->name = "transparency"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Material *) node)->transparency; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Material_get_field_index_by_name(char *name) +{ + if (!strcmp("ambientIntensity", name)) return 0; + if (!strcmp("diffuseColor", name)) return 1; + if (!strcmp("emissiveColor", name)) return 2; + if (!strcmp("shininess", name)) return 3; + if (!strcmp("specularColor", name)) return 4; + if (!strcmp("transparency", name)) return 5; + return -1; + } +static Bool Material_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 1: + *AType = 4; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 4; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 3: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 4: + *AType = 4; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 5: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + default: + return 0; + } +} + + + +GF_Node *Material_Create() +{ + M_Material *p; + GF_SAFEALLOC(p, M_Material); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Material); + + /*default field values*/ + p->ambientIntensity = FLT2FIX(0.2); + p->diffuseColor.red = FLT2FIX(0.8); + p->diffuseColor.green = FLT2FIX(0.8); + p->diffuseColor.blue = FLT2FIX(0.8); + p->emissiveColor.red = FLT2FIX(0); + p->emissiveColor.green = FLT2FIX(0); + p->emissiveColor.blue = FLT2FIX(0); + p->shininess = FLT2FIX(0.2); + p->specularColor.red = FLT2FIX(0); + p->specularColor.green = FLT2FIX(0); + p->specularColor.blue = FLT2FIX(0); + p->transparency = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + Material2D Node deletion +*/ + +static void Material2D_Del(GF_Node *node) +{ + M_Material2D *p = (M_Material2D *) node; + gf_node_unregister((GF_Node *) p->lineProps, (GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Material2D_Def2All[] = { 0, 1, 2, 3}; +static const u16 Material2D_In2All[] = { 0, 1, 2, 3}; +static const u16 Material2D_Out2All[] = { 0, 1, 2, 3}; +static const u16 Material2D_Dyn2All[] = { 0, 3}; + +static u32 Material2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 2; + default: + return 4; + } +} + +static GF_Err Material2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Material2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Material2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Material2D_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Material2D_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Material2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "emissiveColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_Material2D *) node)->emissiveColor; + return GF_OK; + case 1: + info->name = "filled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Material2D *) node)->filled; + return GF_OK; + case 2: + info->name = "lineProps"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFLinePropertiesNode; + info->far_ptr = & ((M_Material2D *)node)->lineProps; + return GF_OK; + case 3: + info->name = "transparency"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Material2D *) node)->transparency; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Material2D_get_field_index_by_name(char *name) +{ + if (!strcmp("emissiveColor", name)) return 0; + if (!strcmp("filled", name)) return 1; + if (!strcmp("lineProps", name)) return 2; + if (!strcmp("transparency", name)) return 3; + return -1; + } +static Bool Material2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 4; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 3: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + default: + return 0; + } +} + + + +GF_Node *Material2D_Create() +{ + M_Material2D *p; + GF_SAFEALLOC(p, M_Material2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Material2D); + + /*default field values*/ + p->emissiveColor.red = FLT2FIX(0.8); + p->emissiveColor.green = FLT2FIX(0.8); + p->emissiveColor.blue = FLT2FIX(0.8); + p->transparency = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + MovieTexture Node deletion +*/ + +static void MovieTexture_Del(GF_Node *node) +{ + M_MovieTexture *p = (M_MovieTexture *) node; + gf_sg_mfurl_del(p->url); + gf_node_free((GF_Node *) p); +} + +static const u16 MovieTexture_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 MovieTexture_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 MovieTexture_Out2All[] = { 0, 1, 2, 3, 4, 7, 8}; +static const u16 MovieTexture_Dyn2All[] = { 1}; + +static u32 MovieTexture_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 9; + } +} + +static GF_Err MovieTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = MovieTexture_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = MovieTexture_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = MovieTexture_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = MovieTexture_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err MovieTexture_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "loop"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MovieTexture *) node)->loop; + return GF_OK; + case 1: + info->name = "speed"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_MovieTexture *) node)->speed; + return GF_OK; + case 2: + info->name = "startTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MovieTexture *) node)->startTime; + return GF_OK; + case 3: + info->name = "stopTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MovieTexture *) node)->stopTime; + return GF_OK; + case 4: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_MovieTexture *) node)->url; + return GF_OK; + case 5: + info->name = "repeatS"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MovieTexture *) node)->repeatS; + return GF_OK; + case 6: + info->name = "repeatT"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MovieTexture *) node)->repeatT; + return GF_OK; + case 7: + info->name = "duration_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MovieTexture *) node)->duration_changed; + return GF_OK; + case 8: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MovieTexture *) node)->isActive; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 MovieTexture_get_field_index_by_name(char *name) +{ + if (!strcmp("loop", name)) return 0; + if (!strcmp("speed", name)) return 1; + if (!strcmp("startTime", name)) return 2; + if (!strcmp("stopTime", name)) return 3; + if (!strcmp("url", name)) return 4; + if (!strcmp("repeatS", name)) return 5; + if (!strcmp("repeatT", name)) return 6; + if (!strcmp("duration_changed", name)) return 7; + if (!strcmp("isActive", name)) return 8; + return -1; + } +static Bool MovieTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *MovieTexture_Create() +{ + M_MovieTexture *p; + GF_SAFEALLOC(p, M_MovieTexture); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_MovieTexture); + + /*default field values*/ + p->speed = FLT2FIX(1.0); + p->startTime = 0; + p->stopTime = 0; + p->repeatS = 1; + p->repeatT = 1; + return (GF_Node *)p; +} + + +/* + NavigationInfo Node deletion +*/ + +static void NavigationInfo_Del(GF_Node *node) +{ + M_NavigationInfo *p = (M_NavigationInfo *) node; + gf_sg_mffloat_del(p->avatarSize); + gf_sg_mfstring_del(p->type); + gf_node_free((GF_Node *) p); +} + +static const u16 NavigationInfo_Def2All[] = { 1, 2, 3, 4, 5}; +static const u16 NavigationInfo_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 NavigationInfo_Out2All[] = { 1, 2, 3, 4, 5, 6}; +static const u16 NavigationInfo_Dyn2All[] = { 5}; + +static u32 NavigationInfo_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 7; + } +} + +static GF_Err NavigationInfo_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = NavigationInfo_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = NavigationInfo_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = NavigationInfo_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = NavigationInfo_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err NavigationInfo_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_bind"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_NavigationInfo *)node)->on_set_bind; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_NavigationInfo *) node)->set_bind; + return GF_OK; + case 1: + info->name = "avatarSize"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_NavigationInfo *) node)->avatarSize; + return GF_OK; + case 2: + info->name = "headlight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_NavigationInfo *) node)->headlight; + return GF_OK; + case 3: + info->name = "speed"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_NavigationInfo *) node)->speed; + return GF_OK; + case 4: + info->name = "type"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_NavigationInfo *) node)->type; + return GF_OK; + case 5: + info->name = "visibilityLimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_NavigationInfo *) node)->visibilityLimit; + return GF_OK; + case 6: + info->name = "isBound"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_NavigationInfo *) node)->isBound; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 NavigationInfo_get_field_index_by_name(char *name) +{ + if (!strcmp("set_bind", name)) return 0; + if (!strcmp("avatarSize", name)) return 1; + if (!strcmp("headlight", name)) return 2; + if (!strcmp("speed", name)) return 3; + if (!strcmp("type", name)) return 4; + if (!strcmp("visibilityLimit", name)) return 5; + if (!strcmp("isBound", name)) return 6; + return -1; + } +static Bool NavigationInfo_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 5: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *NavigationInfo_Create() +{ + M_NavigationInfo *p; + GF_SAFEALLOC(p, M_NavigationInfo); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_NavigationInfo); + + /*default field values*/ + p->avatarSize.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*3); + p->avatarSize.count = 3; + p->avatarSize.vals[0] = FLT2FIX(0.25); + p->avatarSize.vals[1] = FLT2FIX(1.6); + p->avatarSize.vals[2] = FLT2FIX(0.75); + p->headlight = 1; + p->speed = FLT2FIX(1.0); + p->type.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->type.count = 2; + p->type.vals[0] = (char*)gf_malloc(sizeof(char) * 5); + strcpy(p->type.vals[0], "WALK"); + p->type.vals[1] = (char*)gf_malloc(sizeof(char) * 4); + strcpy(p->type.vals[1], "ANY"); + p->visibilityLimit = FLT2FIX(0.0); + return (GF_Node *)p; +} + + +/* + Normal Node deletion +*/ + +static void Normal_Del(GF_Node *node) +{ + M_Normal *p = (M_Normal *) node; + gf_sg_mfvec3f_del(p->vector); + gf_node_free((GF_Node *) p); +} + +static const u16 Normal_Def2All[] = { 0}; +static const u16 Normal_In2All[] = { 0}; +static const u16 Normal_Out2All[] = { 0}; +static const u16 Normal_Dyn2All[] = { 0}; + +static u32 Normal_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 1; + } +} + +static GF_Err Normal_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Normal_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Normal_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Normal_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Normal_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Normal_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "vector"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_Normal *) node)->vector; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Normal_get_field_index_by_name(char *name) +{ + if (!strcmp("vector", name)) return 0; + return -1; + } +static Bool Normal_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 9; + *QType = 9; + return 1; + default: + return 0; + } +} + + + +GF_Node *Normal_Create() +{ + M_Normal *p; + GF_SAFEALLOC(p, M_Normal); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Normal); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + NormalInterpolator Node deletion +*/ + +static void NormalInterpolator_Del(GF_Node *node) +{ + M_NormalInterpolator *p = (M_NormalInterpolator *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfvec3f_del(p->keyValue); + gf_sg_mfvec3f_del(p->value_changed); + gf_node_free((GF_Node *) p); +} + +static const u16 NormalInterpolator_Def2All[] = { 1, 2}; +static const u16 NormalInterpolator_In2All[] = { 0, 1, 2}; +static const u16 NormalInterpolator_Out2All[] = { 1, 2, 3}; + +static u32 NormalInterpolator_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 4; + } +} + +static GF_Err NormalInterpolator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = NormalInterpolator_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = NormalInterpolator_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = NormalInterpolator_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err NormalInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_NormalInterpolator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_NormalInterpolator *) node)->set_fraction; + return GF_OK; + case 1: + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_NormalInterpolator *) node)->key; + return GF_OK; + case 2: + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_NormalInterpolator *) node)->keyValue; + return GF_OK; + case 3: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_NormalInterpolator *) node)->value_changed; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 NormalInterpolator_get_field_index_by_name(char *name) +{ + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("key", name)) return 1; + if (!strcmp("keyValue", name)) return 2; + if (!strcmp("value_changed", name)) return 3; + return -1; + } +static Bool NormalInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 0; + *QType = 9; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *NormalInterpolator_Create() +{ + M_NormalInterpolator *p; + GF_SAFEALLOC(p, M_NormalInterpolator); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_NormalInterpolator); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + OrderedGroup Node deletion +*/ + +static void OrderedGroup_Del(GF_Node *node) +{ + M_OrderedGroup *p = (M_OrderedGroup *) node; + gf_sg_mffloat_del(p->order); + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 OrderedGroup_Def2All[] = { 2, 3}; +static const u16 OrderedGroup_In2All[] = { 0, 1, 2, 3}; +static const u16 OrderedGroup_Out2All[] = { 2, 3}; + +static u32 OrderedGroup_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 4; + } +} + +static GF_Err OrderedGroup_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = OrderedGroup_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = OrderedGroup_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = OrderedGroup_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err OrderedGroup_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_OrderedGroup *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_OrderedGroup *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_OrderedGroup *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_OrderedGroup *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_OrderedGroup *)node)->children; + return GF_OK; + case 3: + info->name = "order"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_OrderedGroup *) node)->order; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 OrderedGroup_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("order", name)) return 3; + return -1; + } +static Bool OrderedGroup_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 3: + *AType = 0; + *QType = 3; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *OrderedGroup_Create() +{ + M_OrderedGroup *p; + GF_SAFEALLOC(p, M_OrderedGroup); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_OrderedGroup); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + OrientationInterpolator Node deletion +*/ + +static void OrientationInterpolator_Del(GF_Node *node) +{ + M_OrientationInterpolator *p = (M_OrientationInterpolator *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfrotation_del(p->keyValue); + gf_node_free((GF_Node *) p); +} + +static const u16 OrientationInterpolator_Def2All[] = { 1, 2}; +static const u16 OrientationInterpolator_In2All[] = { 0, 1, 2}; +static const u16 OrientationInterpolator_Out2All[] = { 1, 2, 3}; + +static u32 OrientationInterpolator_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 4; + } +} + +static GF_Err OrientationInterpolator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = OrientationInterpolator_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = OrientationInterpolator_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = OrientationInterpolator_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err OrientationInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_OrientationInterpolator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_OrientationInterpolator *) node)->set_fraction; + return GF_OK; + case 1: + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_OrientationInterpolator *) node)->key; + return GF_OK; + case 2: + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFROTATION; + info->far_ptr = & ((M_OrientationInterpolator *) node)->keyValue; + return GF_OK; + case 3: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_OrientationInterpolator *) node)->value_changed; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 OrientationInterpolator_get_field_index_by_name(char *name) +{ + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("key", name)) return 1; + if (!strcmp("keyValue", name)) return 2; + if (!strcmp("value_changed", name)) return 3; + return -1; + } +static Bool OrientationInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 0; + *QType = 10; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *OrientationInterpolator_Create() +{ + M_OrientationInterpolator *p; + GF_SAFEALLOC(p, M_OrientationInterpolator); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_OrientationInterpolator); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + PixelTexture Node deletion +*/ + +static void PixelTexture_Del(GF_Node *node) +{ + M_PixelTexture *p = (M_PixelTexture *) node; + gf_sg_sfimage_del(p->image); + gf_node_free((GF_Node *) p); +} + +static const u16 PixelTexture_Def2All[] = { 0, 1, 2}; +static const u16 PixelTexture_In2All[] = { 0}; +static const u16 PixelTexture_Out2All[] = { 0}; + +static u32 PixelTexture_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 3; + } +} + +static GF_Err PixelTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = PixelTexture_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = PixelTexture_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = PixelTexture_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err PixelTexture_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "image"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFIMAGE; + info->far_ptr = & ((M_PixelTexture *) node)->image; + return GF_OK; + case 1: + info->name = "repeatS"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PixelTexture *) node)->repeatS; + return GF_OK; + case 2: + info->name = "repeatT"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PixelTexture *) node)->repeatT; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 PixelTexture_get_field_index_by_name(char *name) +{ + if (!strcmp("image", name)) return 0; + if (!strcmp("repeatS", name)) return 1; + if (!strcmp("repeatT", name)) return 2; + return -1; + } +static Bool PixelTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 0; + return 1; + default: + return 0; + } +} + + + +GF_Node *PixelTexture_Create() +{ + M_PixelTexture *p; + GF_SAFEALLOC(p, M_PixelTexture); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_PixelTexture); + + /*default field values*/ + p->repeatS = 1; + p->repeatT = 1; + return (GF_Node *)p; +} + + +/* + PlaneSensor Node deletion +*/ + +static void PlaneSensor_Del(GF_Node *node) +{ + M_PlaneSensor *p = (M_PlaneSensor *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 PlaneSensor_Def2All[] = { 0, 1, 2, 3, 4}; +static const u16 PlaneSensor_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 PlaneSensor_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; + +static u32 PlaneSensor_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 8; + } +} + +static GF_Err PlaneSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = PlaneSensor_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = PlaneSensor_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = PlaneSensor_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err PlaneSensor_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "autoOffset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PlaneSensor *) node)->autoOffset; + return GF_OK; + case 1: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PlaneSensor *) node)->enabled; + return GF_OK; + case 2: + info->name = "maxPosition"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PlaneSensor *) node)->maxPosition; + return GF_OK; + case 3: + info->name = "minPosition"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PlaneSensor *) node)->minPosition; + return GF_OK; + case 4: + info->name = "offset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_PlaneSensor *) node)->offset; + return GF_OK; + case 5: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PlaneSensor *) node)->isActive; + return GF_OK; + case 6: + info->name = "trackPoint_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_PlaneSensor *) node)->trackPoint_changed; + return GF_OK; + case 7: + info->name = "translation_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_PlaneSensor *) node)->translation_changed; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 PlaneSensor_get_field_index_by_name(char *name) +{ + if (!strcmp("autoOffset", name)) return 0; + if (!strcmp("enabled", name)) return 1; + if (!strcmp("maxPosition", name)) return 2; + if (!strcmp("minPosition", name)) return 3; + if (!strcmp("offset", name)) return 4; + if (!strcmp("isActive", name)) return 5; + if (!strcmp("trackPoint_changed", name)) return 6; + if (!strcmp("translation_changed", name)) return 7; + return -1; + } +static Bool PlaneSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 2: + *AType = 0; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 0; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 0; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *PlaneSensor_Create() +{ + M_PlaneSensor *p; + GF_SAFEALLOC(p, M_PlaneSensor); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_PlaneSensor); + + /*default field values*/ + p->autoOffset = 1; + p->enabled = 1; + p->maxPosition.x = FLT2FIX(-1); + p->maxPosition.y = FLT2FIX(-1); + p->minPosition.x = FLT2FIX(0); + p->minPosition.y = FLT2FIX(0); + p->offset.x = FLT2FIX(0); + p->offset.y = FLT2FIX(0); + p->offset.z = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + PlaneSensor2D Node deletion +*/ + +static void PlaneSensor2D_Del(GF_Node *node) +{ + M_PlaneSensor2D *p = (M_PlaneSensor2D *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 PlaneSensor2D_Def2All[] = { 0, 1, 2, 3, 4}; +static const u16 PlaneSensor2D_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 PlaneSensor2D_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; + +static u32 PlaneSensor2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 8; + } +} + +static GF_Err PlaneSensor2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = PlaneSensor2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = PlaneSensor2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = PlaneSensor2D_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err PlaneSensor2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "autoOffset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PlaneSensor2D *) node)->autoOffset; + return GF_OK; + case 1: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PlaneSensor2D *) node)->enabled; + return GF_OK; + case 2: + info->name = "maxPosition"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PlaneSensor2D *) node)->maxPosition; + return GF_OK; + case 3: + info->name = "minPosition"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PlaneSensor2D *) node)->minPosition; + return GF_OK; + case 4: + info->name = "offset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PlaneSensor2D *) node)->offset; + return GF_OK; + case 5: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PlaneSensor2D *) node)->isActive; + return GF_OK; + case 6: + info->name = "trackPoint_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PlaneSensor2D *) node)->trackPoint_changed; + return GF_OK; + case 7: + info->name = "translation_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PlaneSensor2D *) node)->translation_changed; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 PlaneSensor2D_get_field_index_by_name(char *name) +{ + if (!strcmp("autoOffset", name)) return 0; + if (!strcmp("enabled", name)) return 1; + if (!strcmp("maxPosition", name)) return 2; + if (!strcmp("minPosition", name)) return 3; + if (!strcmp("offset", name)) return 4; + if (!strcmp("isActive", name)) return 5; + if (!strcmp("trackPoint_changed", name)) return 6; + if (!strcmp("translation_changed", name)) return 7; + return -1; + } +static Bool PlaneSensor2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 2: + *AType = 0; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 0; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 0; + *QType = 12; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *PlaneSensor2D_Create() +{ + M_PlaneSensor2D *p; + GF_SAFEALLOC(p, M_PlaneSensor2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_PlaneSensor2D); + + /*default field values*/ + p->autoOffset = 1; + p->enabled = 1; + p->maxPosition.x = FLT2FIX(0); + p->maxPosition.y = FLT2FIX(0); + p->minPosition.x = FLT2FIX(0); + p->minPosition.y = FLT2FIX(0); + p->offset.x = FLT2FIX(0); + p->offset.y = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + PointLight Node deletion +*/ + +static void PointLight_Del(GF_Node *node) +{ + M_PointLight *p = (M_PointLight *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 PointLight_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 PointLight_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 PointLight_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 PointLight_Dyn2All[] = { 0, 1, 2, 3, 4, 6}; + +static u32 PointLight_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 7; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 6; + default: + return 7; + } +} + +static GF_Err PointLight_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = PointLight_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = PointLight_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = PointLight_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = PointLight_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err PointLight_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "ambientIntensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PointLight *) node)->ambientIntensity; + return GF_OK; + case 1: + info->name = "attenuation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_PointLight *) node)->attenuation; + return GF_OK; + case 2: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_PointLight *) node)->color; + return GF_OK; + case 3: + info->name = "intensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PointLight *) node)->intensity; + return GF_OK; + case 4: + info->name = "location"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_PointLight *) node)->location; + return GF_OK; + case 5: + info->name = "on"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PointLight *) node)->on; + return GF_OK; + case 6: + info->name = "radius"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PointLight *) node)->radius; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 PointLight_get_field_index_by_name(char *name) +{ + if (!strcmp("ambientIntensity", name)) return 0; + if (!strcmp("attenuation", name)) return 1; + if (!strcmp("color", name)) return 2; + if (!strcmp("intensity", name)) return 3; + if (!strcmp("location", name)) return 4; + if (!strcmp("on", name)) return 5; + if (!strcmp("radius", name)) return 6; + return -1; + } +static Bool PointLight_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 1: + *AType = 1; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 2: + *AType = 4; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 3: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 4: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *PointLight_Create() +{ + M_PointLight *p; + GF_SAFEALLOC(p, M_PointLight); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_PointLight); + + /*default field values*/ + p->ambientIntensity = FLT2FIX(0); + p->attenuation.x = FLT2FIX(1); + p->attenuation.y = FLT2FIX(0); + p->attenuation.z = FLT2FIX(0); + p->color.red = FLT2FIX(1); + p->color.green = FLT2FIX(1); + p->color.blue = FLT2FIX(1); + p->intensity = FLT2FIX(1); + p->location.x = FLT2FIX(0); + p->location.y = FLT2FIX(0); + p->location.z = FLT2FIX(0); + p->on = 1; + p->radius = FLT2FIX(100); + return (GF_Node *)p; +} + + +/* + PointSet Node deletion +*/ + +static void PointSet_Del(GF_Node *node) +{ + M_PointSet *p = (M_PointSet *) node; + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 PointSet_Def2All[] = { 0, 1}; +static const u16 PointSet_In2All[] = { 0, 1}; +static const u16 PointSet_Out2All[] = { 0, 1}; + +static u32 PointSet_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 2; + } +} + +static GF_Err PointSet_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = PointSet_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = PointSet_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = PointSet_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err PointSet_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_PointSet *)node)->color; + return GF_OK; + case 1: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((M_PointSet *)node)->coord; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 PointSet_get_field_index_by_name(char *name) +{ + if (!strcmp("color", name)) return 0; + if (!strcmp("coord", name)) return 1; + return -1; + } +static Bool PointSet_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *PointSet_Create() +{ + M_PointSet *p; + GF_SAFEALLOC(p, M_PointSet); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_PointSet); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + PointSet2D Node deletion +*/ + +static void PointSet2D_Del(GF_Node *node) +{ + M_PointSet2D *p = (M_PointSet2D *) node; + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 PointSet2D_Def2All[] = { 0, 1}; +static const u16 PointSet2D_In2All[] = { 0, 1}; +static const u16 PointSet2D_Out2All[] = { 0, 1}; + +static u32 PointSet2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 2; + } +} + +static GF_Err PointSet2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = PointSet2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = PointSet2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = PointSet2D_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err PointSet2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_PointSet2D *)node)->color; + return GF_OK; + case 1: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinate2DNode; + info->far_ptr = & ((M_PointSet2D *)node)->coord; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 PointSet2D_get_field_index_by_name(char *name) +{ + if (!strcmp("color", name)) return 0; + if (!strcmp("coord", name)) return 1; + return -1; + } +static Bool PointSet2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *PointSet2D_Create() +{ + M_PointSet2D *p; + GF_SAFEALLOC(p, M_PointSet2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_PointSet2D); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + PositionInterpolator Node deletion +*/ + +static void PositionInterpolator_Del(GF_Node *node) +{ + M_PositionInterpolator *p = (M_PositionInterpolator *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfvec3f_del(p->keyValue); + gf_node_free((GF_Node *) p); +} + +static const u16 PositionInterpolator_Def2All[] = { 1, 2}; +static const u16 PositionInterpolator_In2All[] = { 0, 1, 2}; +static const u16 PositionInterpolator_Out2All[] = { 1, 2, 3}; + +static u32 PositionInterpolator_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 4; + } +} + +static GF_Err PositionInterpolator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = PositionInterpolator_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = PositionInterpolator_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = PositionInterpolator_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err PositionInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_PositionInterpolator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PositionInterpolator *) node)->set_fraction; + return GF_OK; + case 1: + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PositionInterpolator *) node)->key; + return GF_OK; + case 2: + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_PositionInterpolator *) node)->keyValue; + return GF_OK; + case 3: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_PositionInterpolator *) node)->value_changed; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 PositionInterpolator_get_field_index_by_name(char *name) +{ + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("key", name)) return 1; + if (!strcmp("keyValue", name)) return 2; + if (!strcmp("value_changed", name)) return 3; + return -1; + } +static Bool PositionInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 0; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *PositionInterpolator_Create() +{ + M_PositionInterpolator *p; + GF_SAFEALLOC(p, M_PositionInterpolator); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionInterpolator); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + PositionInterpolator2D Node deletion +*/ + +static void PositionInterpolator2D_Del(GF_Node *node) +{ + M_PositionInterpolator2D *p = (M_PositionInterpolator2D *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfvec2f_del(p->keyValue); + gf_node_free((GF_Node *) p); +} + +static const u16 PositionInterpolator2D_Def2All[] = { 1, 2}; +static const u16 PositionInterpolator2D_In2All[] = { 0, 1, 2}; +static const u16 PositionInterpolator2D_Out2All[] = { 1, 2, 3}; + +static u32 PositionInterpolator2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 4; + } +} + +static GF_Err PositionInterpolator2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = PositionInterpolator2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = PositionInterpolator2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = PositionInterpolator2D_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err PositionInterpolator2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_PositionInterpolator2D *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PositionInterpolator2D *) node)->set_fraction; + return GF_OK; + case 1: + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PositionInterpolator2D *) node)->key; + return GF_OK; + case 2: + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_PositionInterpolator2D *) node)->keyValue; + return GF_OK; + case 3: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PositionInterpolator2D *) node)->value_changed; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 PositionInterpolator2D_get_field_index_by_name(char *name) +{ + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("key", name)) return 1; + if (!strcmp("keyValue", name)) return 2; + if (!strcmp("value_changed", name)) return 3; + return -1; + } +static Bool PositionInterpolator2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 0; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *PositionInterpolator2D_Create() +{ + M_PositionInterpolator2D *p; + GF_SAFEALLOC(p, M_PositionInterpolator2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionInterpolator2D); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + ProximitySensor2D Node deletion +*/ + +static void ProximitySensor2D_Del(GF_Node *node) +{ + M_ProximitySensor2D *p = (M_ProximitySensor2D *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 ProximitySensor2D_Def2All[] = { 0, 1, 2}; +static const u16 ProximitySensor2D_In2All[] = { 0, 1, 2}; +static const u16 ProximitySensor2D_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; + +static u32 ProximitySensor2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 8; + } +} + +static GF_Err ProximitySensor2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = ProximitySensor2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = ProximitySensor2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = ProximitySensor2D_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err ProximitySensor2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_ProximitySensor2D *) node)->center; + return GF_OK; + case 1: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_ProximitySensor2D *) node)->size; + return GF_OK; + case 2: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ProximitySensor2D *) node)->enabled; + return GF_OK; + case 3: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ProximitySensor2D *) node)->isActive; + return GF_OK; + case 4: + info->name = "position_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_ProximitySensor2D *) node)->position_changed; + return GF_OK; + case 5: + info->name = "orientation_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ProximitySensor2D *) node)->orientation_changed; + return GF_OK; + case 6: + info->name = "enterTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_ProximitySensor2D *) node)->enterTime; + return GF_OK; + case 7: + info->name = "exitTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_ProximitySensor2D *) node)->exitTime; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 ProximitySensor2D_get_field_index_by_name(char *name) +{ + if (!strcmp("center", name)) return 0; + if (!strcmp("size", name)) return 1; + if (!strcmp("enabled", name)) return 2; + if (!strcmp("isActive", name)) return 3; + if (!strcmp("position_changed", name)) return 4; + if (!strcmp("orientation_changed", name)) return 5; + if (!strcmp("enterTime", name)) return 6; + if (!strcmp("exitTime", name)) return 7; + return -1; + } +static Bool ProximitySensor2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 2; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 0; + *QType = 12; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *ProximitySensor2D_Create() +{ + M_ProximitySensor2D *p; + GF_SAFEALLOC(p, M_ProximitySensor2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_ProximitySensor2D); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->size.x = FLT2FIX(0); + p->size.y = FLT2FIX(0); + p->enabled = 1; + return (GF_Node *)p; +} + + +/* + ProximitySensor Node deletion +*/ + +static void ProximitySensor_Del(GF_Node *node) +{ + M_ProximitySensor *p = (M_ProximitySensor *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 ProximitySensor_Def2All[] = { 0, 1, 2}; +static const u16 ProximitySensor_In2All[] = { 0, 1, 2}; +static const u16 ProximitySensor_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; + +static u32 ProximitySensor_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 8; + } +} + +static GF_Err ProximitySensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = ProximitySensor_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = ProximitySensor_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = ProximitySensor_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err ProximitySensor_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_ProximitySensor *) node)->center; + return GF_OK; + case 1: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_ProximitySensor *) node)->size; + return GF_OK; + case 2: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ProximitySensor *) node)->enabled; + return GF_OK; + case 3: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ProximitySensor *) node)->isActive; + return GF_OK; + case 4: + info->name = "position_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_ProximitySensor *) node)->position_changed; + return GF_OK; + case 5: + info->name = "orientation_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_ProximitySensor *) node)->orientation_changed; + return GF_OK; + case 6: + info->name = "enterTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_ProximitySensor *) node)->enterTime; + return GF_OK; + case 7: + info->name = "exitTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_ProximitySensor *) node)->exitTime; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 ProximitySensor_get_field_index_by_name(char *name) +{ + if (!strcmp("center", name)) return 0; + if (!strcmp("size", name)) return 1; + if (!strcmp("enabled", name)) return 2; + if (!strcmp("isActive", name)) return 3; + if (!strcmp("position_changed", name)) return 4; + if (!strcmp("orientation_changed", name)) return 5; + if (!strcmp("enterTime", name)) return 6; + if (!strcmp("exitTime", name)) return 7; + return -1; + } +static Bool ProximitySensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 0; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *ProximitySensor_Create() +{ + M_ProximitySensor *p; + GF_SAFEALLOC(p, M_ProximitySensor); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_ProximitySensor); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->size.x = FLT2FIX(0); + p->size.y = FLT2FIX(0); + p->size.z = FLT2FIX(0); + p->enabled = 1; + return (GF_Node *)p; +} + + +/* + QuantizationParameter Node deletion +*/ + +static void QuantizationParameter_Del(GF_Node *node) +{ + M_QuantizationParameter *p = (M_QuantizationParameter *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 QuantizationParameter_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39}; + +static u32 QuantizationParameter_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 40; + case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 40; + } +} + +static GF_Err QuantizationParameter_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_DEF: + *allField = QuantizationParameter_Def2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err QuantizationParameter_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "isLocal"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->isLocal; + return GF_OK; + case 1: + info->name = "position3DQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->position3DQuant; + return GF_OK; + case 2: + info->name = "position3DMin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_QuantizationParameter *) node)->position3DMin; + return GF_OK; + case 3: + info->name = "position3DMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_QuantizationParameter *) node)->position3DMax; + return GF_OK; + case 4: + info->name = "position3DNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->position3DNbBits; + return GF_OK; + case 5: + info->name = "position2DQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->position2DQuant; + return GF_OK; + case 6: + info->name = "position2DMin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_QuantizationParameter *) node)->position2DMin; + return GF_OK; + case 7: + info->name = "position2DMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_QuantizationParameter *) node)->position2DMax; + return GF_OK; + case 8: + info->name = "position2DNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->position2DNbBits; + return GF_OK; + case 9: + info->name = "drawOrderQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->drawOrderQuant; + return GF_OK; + case 10: + info->name = "drawOrderMin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->drawOrderMin; + return GF_OK; + case 11: + info->name = "drawOrderMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->drawOrderMax; + return GF_OK; + case 12: + info->name = "drawOrderNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->drawOrderNbBits; + return GF_OK; + case 13: + info->name = "colorQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->colorQuant; + return GF_OK; + case 14: + info->name = "colorMin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->colorMin; + return GF_OK; + case 15: + info->name = "colorMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->colorMax; + return GF_OK; + case 16: + info->name = "colorNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->colorNbBits; + return GF_OK; + case 17: + info->name = "textureCoordinateQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->textureCoordinateQuant; + return GF_OK; + case 18: + info->name = "textureCoordinateMin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->textureCoordinateMin; + return GF_OK; + case 19: + info->name = "textureCoordinateMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->textureCoordinateMax; + return GF_OK; + case 20: + info->name = "textureCoordinateNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->textureCoordinateNbBits; + return GF_OK; + case 21: + info->name = "angleQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->angleQuant; + return GF_OK; + case 22: + info->name = "angleMin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->angleMin; + return GF_OK; + case 23: + info->name = "angleMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->angleMax; + return GF_OK; + case 24: + info->name = "angleNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->angleNbBits; + return GF_OK; + case 25: + info->name = "scaleQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->scaleQuant; + return GF_OK; + case 26: + info->name = "scaleMin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->scaleMin; + return GF_OK; + case 27: + info->name = "scaleMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->scaleMax; + return GF_OK; + case 28: + info->name = "scaleNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->scaleNbBits; + return GF_OK; + case 29: + info->name = "keyQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->keyQuant; + return GF_OK; + case 30: + info->name = "keyMin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->keyMin; + return GF_OK; + case 31: + info->name = "keyMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->keyMax; + return GF_OK; + case 32: + info->name = "keyNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->keyNbBits; + return GF_OK; + case 33: + info->name = "normalQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->normalQuant; + return GF_OK; + case 34: + info->name = "normalNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->normalNbBits; + return GF_OK; + case 35: + info->name = "sizeQuant"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->sizeQuant; + return GF_OK; + case 36: + info->name = "sizeMin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->sizeMin; + return GF_OK; + case 37: + info->name = "sizeMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_QuantizationParameter *) node)->sizeMax; + return GF_OK; + case 38: + info->name = "sizeNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_QuantizationParameter *) node)->sizeNbBits; + return GF_OK; + case 39: + info->name = "useEfficientCoding"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_QuantizationParameter *) node)->useEfficientCoding; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 QuantizationParameter_get_field_index_by_name(char *name) +{ + if (!strcmp("isLocal", name)) return 0; + if (!strcmp("position3DQuant", name)) return 1; + if (!strcmp("position3DMin", name)) return 2; + if (!strcmp("position3DMax", name)) return 3; + if (!strcmp("position3DNbBits", name)) return 4; + if (!strcmp("position2DQuant", name)) return 5; + if (!strcmp("position2DMin", name)) return 6; + if (!strcmp("position2DMax", name)) return 7; + if (!strcmp("position2DNbBits", name)) return 8; + if (!strcmp("drawOrderQuant", name)) return 9; + if (!strcmp("drawOrderMin", name)) return 10; + if (!strcmp("drawOrderMax", name)) return 11; + if (!strcmp("drawOrderNbBits", name)) return 12; + if (!strcmp("colorQuant", name)) return 13; + if (!strcmp("colorMin", name)) return 14; + if (!strcmp("colorMax", name)) return 15; + if (!strcmp("colorNbBits", name)) return 16; + if (!strcmp("textureCoordinateQuant", name)) return 17; + if (!strcmp("textureCoordinateMin", name)) return 18; + if (!strcmp("textureCoordinateMax", name)) return 19; + if (!strcmp("textureCoordinateNbBits", name)) return 20; + if (!strcmp("angleQuant", name)) return 21; + if (!strcmp("angleMin", name)) return 22; + if (!strcmp("angleMax", name)) return 23; + if (!strcmp("angleNbBits", name)) return 24; + if (!strcmp("scaleQuant", name)) return 25; + if (!strcmp("scaleMin", name)) return 26; + if (!strcmp("scaleMax", name)) return 27; + if (!strcmp("scaleNbBits", name)) return 28; + if (!strcmp("keyQuant", name)) return 29; + if (!strcmp("keyMin", name)) return 30; + if (!strcmp("keyMax", name)) return 31; + if (!strcmp("keyNbBits", name)) return 32; + if (!strcmp("normalQuant", name)) return 33; + if (!strcmp("normalNbBits", name)) return 34; + if (!strcmp("sizeQuant", name)) return 35; + if (!strcmp("sizeMin", name)) return 36; + if (!strcmp("sizeMax", name)) return 37; + if (!strcmp("sizeNbBits", name)) return 38; + if (!strcmp("useEfficientCoding", name)) return 39; + return -1; + } +static Bool QuantizationParameter_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 2: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 6: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 8: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 10: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 11: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 12: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 14: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 15: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 16: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 18: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 19: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 20: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 22: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(6.2831853); + return 1; + case 23: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(6.2831853); + return 1; + case 24: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 26: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 27: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 28: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 30: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 31: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 32: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 34: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 36: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 37: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 38: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + default: + return 0; + } +} + + + +GF_Node *QuantizationParameter_Create() +{ + M_QuantizationParameter *p; + GF_SAFEALLOC(p, M_QuantizationParameter); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_QuantizationParameter); + + /*default field values*/ + p->position3DMin.x = FIX_MIN; + p->position3DMin.y = FIX_MIN; + p->position3DMin.z = FIX_MIN; + p->position3DMax.x = FIX_MAX; + p->position3DMax.y = FIX_MAX; + p->position3DMax.z = FIX_MAX; + p->position3DNbBits = 16; + p->position2DMin.x = FIX_MIN; + p->position2DMin.y = FIX_MIN; + p->position2DMax.x = FIX_MAX; + p->position2DMax.y = FIX_MAX; + p->position2DNbBits = 16; + p->drawOrderMin = FIX_MIN; + p->drawOrderMax = FIX_MAX; + p->drawOrderNbBits = 8; + p->colorQuant = 1; + p->colorMin = FLT2FIX(0.0); + p->colorMax = FLT2FIX(1.0); + p->colorNbBits = 8; + p->textureCoordinateQuant = 1; + p->textureCoordinateMin = FLT2FIX(0); + p->textureCoordinateMax = FLT2FIX(1); + p->textureCoordinateNbBits = 16; + p->angleQuant = 1; + p->angleMin = FLT2FIX(0.0); + p->angleMax = FLT2FIX(6.2831853); + p->angleNbBits = 16; + p->scaleMin = FLT2FIX(0.0); + p->scaleMax = FIX_MAX; + p->scaleNbBits = 8; + p->keyQuant = 1; + p->keyMin = FLT2FIX(0.0); + p->keyMax = FLT2FIX(1.0); + p->keyNbBits = 8; + p->normalQuant = 1; + p->normalNbBits = 8; + p->sizeMin = FLT2FIX(0); + p->sizeMax = FIX_MAX; + p->sizeNbBits = 8; + return (GF_Node *)p; +} + + +/* + Rectangle Node deletion +*/ + +static void Rectangle_Del(GF_Node *node) +{ + M_Rectangle *p = (M_Rectangle *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 Rectangle_Def2All[] = { 0}; +static const u16 Rectangle_In2All[] = { 0}; +static const u16 Rectangle_Out2All[] = { 0}; +static const u16 Rectangle_Dyn2All[] = { 0}; + +static u32 Rectangle_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 1; + } +} + +static GF_Err Rectangle_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Rectangle_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Rectangle_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Rectangle_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Rectangle_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Rectangle_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Rectangle *) node)->size; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Rectangle_get_field_index_by_name(char *name) +{ + if (!strcmp("size", name)) return 0; + return -1; + } +static Bool Rectangle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 2; + *QType = 12; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Rectangle_Create() +{ + M_Rectangle *p; + GF_SAFEALLOC(p, M_Rectangle); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Rectangle); + + /*default field values*/ + p->size.x = FLT2FIX(2); + p->size.y = FLT2FIX(2); + return (GF_Node *)p; +} + + +/* + ScalarInterpolator Node deletion +*/ + +static void ScalarInterpolator_Del(GF_Node *node) +{ + M_ScalarInterpolator *p = (M_ScalarInterpolator *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mffloat_del(p->keyValue); + gf_node_free((GF_Node *) p); +} + +static const u16 ScalarInterpolator_Def2All[] = { 1, 2}; +static const u16 ScalarInterpolator_In2All[] = { 0, 1, 2}; +static const u16 ScalarInterpolator_Out2All[] = { 1, 2, 3}; + +static u32 ScalarInterpolator_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 4; + } +} + +static GF_Err ScalarInterpolator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = ScalarInterpolator_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = ScalarInterpolator_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = ScalarInterpolator_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err ScalarInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_ScalarInterpolator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ScalarInterpolator *) node)->set_fraction; + return GF_OK; + case 1: + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_ScalarInterpolator *) node)->key; + return GF_OK; + case 2: + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_ScalarInterpolator *) node)->keyValue; + return GF_OK; + case 3: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ScalarInterpolator *) node)->value_changed; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 ScalarInterpolator_get_field_index_by_name(char *name) +{ + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("key", name)) return 1; + if (!strcmp("keyValue", name)) return 2; + if (!strcmp("value_changed", name)) return 3; + return -1; + } +static Bool ScalarInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *ScalarInterpolator_Create() +{ + M_ScalarInterpolator *p; + GF_SAFEALLOC(p, M_ScalarInterpolator); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_ScalarInterpolator); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + Script Node deletion +*/ + +static void Script_Del(GF_Node *node) +{ + M_Script *p = (M_Script *) node; + gf_sg_mfscript_del(p->url); + gf_node_free((GF_Node *) p); +} + +static const u16 Script_Def2All[] = { 0, 1, 2}; +static const u16 Script_In2All[] = { 0}; +static const u16 Script_Out2All[] = { 0}; + +static u32 Script_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 3; + } +} + +static GF_Err Script_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Script_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Script_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Script_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Script_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSCRIPT; + info->far_ptr = & ((M_Script *) node)->url; + return GF_OK; + case 1: + info->name = "directOutput"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Script *) node)->directOutput; + return GF_OK; + case 2: + info->name = "mustEvaluate"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Script *) node)->mustEvaluate; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Script_get_field_index_by_name(char *name) +{ + if (!strcmp("url", name)) return 0; + if (!strcmp("directOutput", name)) return 1; + if (!strcmp("mustEvaluate", name)) return 2; + return -1; + } +static Bool Script_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *Script_Create() +{ + M_Script *p; + GF_SAFEALLOC(p, M_Script); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Script); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + Shape Node deletion +*/ + +static void Shape_Del(GF_Node *node) +{ + M_Shape *p = (M_Shape *) node; + gf_node_unregister((GF_Node *) p->appearance, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->geometry, (GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Shape_Def2All[] = { 0, 1}; +static const u16 Shape_In2All[] = { 0, 1}; +static const u16 Shape_Out2All[] = { 0, 1}; + +static u32 Shape_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 2; + } +} + +static GF_Err Shape_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Shape_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Shape_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Shape_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Shape_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "appearance"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFAppearanceNode; + info->far_ptr = & ((M_Shape *)node)->appearance; + return GF_OK; + case 1: + info->name = "geometry"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_Shape *)node)->geometry; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Shape_get_field_index_by_name(char *name) +{ + if (!strcmp("appearance", name)) return 0; + if (!strcmp("geometry", name)) return 1; + return -1; + } +static Bool Shape_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *Shape_Create() +{ + M_Shape *p; + GF_SAFEALLOC(p, M_Shape); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Shape); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + Sound Node deletion +*/ + +static void Sound_Del(GF_Node *node) +{ + M_Sound *p = (M_Sound *) node; + gf_node_unregister((GF_Node *) p->source, (GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Sound_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 Sound_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 Sound_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 Sound_Dyn2All[] = { 1, 2, 3, 4, 5, 6}; + +static u32 Sound_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 9; + case GF_SG_FIELD_CODING_DEF: return 10; + case GF_SG_FIELD_CODING_OUT: return 9; + case GF_SG_FIELD_CODING_DYN: return 6; + default: + return 10; + } +} + +static GF_Err Sound_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Sound_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Sound_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Sound_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Sound_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Sound_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "direction"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Sound *) node)->direction; + return GF_OK; + case 1: + info->name = "intensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Sound *) node)->intensity; + return GF_OK; + case 2: + info->name = "location"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Sound *) node)->location; + return GF_OK; + case 3: + info->name = "maxBack"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Sound *) node)->maxBack; + return GF_OK; + case 4: + info->name = "maxFront"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Sound *) node)->maxFront; + return GF_OK; + case 5: + info->name = "minBack"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Sound *) node)->minBack; + return GF_OK; + case 6: + info->name = "minFront"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Sound *) node)->minFront; + return GF_OK; + case 7: + info->name = "priority"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Sound *) node)->priority; + return GF_OK; + case 8: + info->name = "source"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_Sound *)node)->source; + return GF_OK; + case 9: + info->name = "spatialize"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Sound *) node)->spatialize; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Sound_get_field_index_by_name(char *name) +{ + if (!strcmp("direction", name)) return 0; + if (!strcmp("intensity", name)) return 1; + if (!strcmp("location", name)) return 2; + if (!strcmp("maxBack", name)) return 3; + if (!strcmp("maxFront", name)) return 4; + if (!strcmp("minBack", name)) return 5; + if (!strcmp("minFront", name)) return 6; + if (!strcmp("priority", name)) return 7; + if (!strcmp("source", name)) return 8; + if (!strcmp("spatialize", name)) return 9; + return -1; + } +static Bool Sound_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 9; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 7; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 5: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 0; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + default: + return 0; + } +} + + + +GF_Node *Sound_Create() +{ + M_Sound *p; + GF_SAFEALLOC(p, M_Sound); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Sound); + + /*default field values*/ + p->direction.x = FLT2FIX(0); + p->direction.y = FLT2FIX(0); + p->direction.z = FLT2FIX(1); + p->intensity = FLT2FIX(1); + p->location.x = FLT2FIX(0); + p->location.y = FLT2FIX(0); + p->location.z = FLT2FIX(0); + p->maxBack = FLT2FIX(10); + p->maxFront = FLT2FIX(10); + p->minBack = FLT2FIX(1); + p->minFront = FLT2FIX(1); + p->priority = FLT2FIX(0); + p->spatialize = 1; + return (GF_Node *)p; +} + + +/* + Sound2D Node deletion +*/ + +static void Sound2D_Del(GF_Node *node) +{ + M_Sound2D *p = (M_Sound2D *) node; + gf_node_unregister((GF_Node *) p->source, (GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Sound2D_Def2All[] = { 0, 1, 2, 3}; +static const u16 Sound2D_In2All[] = { 0, 1, 2}; +static const u16 Sound2D_Out2All[] = { 0, 1, 2}; +static const u16 Sound2D_Dyn2All[] = { 0, 1}; + +static u32 Sound2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 2; + default: + return 4; + } +} + +static GF_Err Sound2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Sound2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Sound2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Sound2D_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Sound2D_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Sound2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "intensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Sound2D *) node)->intensity; + return GF_OK; + case 1: + info->name = "location"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Sound2D *) node)->location; + return GF_OK; + case 2: + info->name = "source"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_Sound2D *)node)->source; + return GF_OK; + case 3: + info->name = "spatialize"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Sound2D *) node)->spatialize; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Sound2D_get_field_index_by_name(char *name) +{ + if (!strcmp("intensity", name)) return 0; + if (!strcmp("location", name)) return 1; + if (!strcmp("source", name)) return 2; + if (!strcmp("spatialize", name)) return 3; + return -1; + } +static Bool Sound2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 7; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 1: + *AType = 2; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Sound2D_Create() +{ + M_Sound2D *p; + GF_SAFEALLOC(p, M_Sound2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Sound2D); + + /*default field values*/ + p->intensity = FLT2FIX(1); + p->location.x = FLT2FIX(0); + p->location.y = FLT2FIX(0); + p->spatialize = 1; + return (GF_Node *)p; +} + + +/* + Sphere Node deletion +*/ + +static void Sphere_Del(GF_Node *node) +{ + M_Sphere *p = (M_Sphere *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 Sphere_Def2All[] = { 0}; + +static u32 Sphere_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 1; + } +} + +static GF_Err Sphere_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_DEF: + *allField = Sphere_Def2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Sphere_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "radius"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Sphere *) node)->radius; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Sphere_get_field_index_by_name(char *name) +{ + if (!strcmp("radius", name)) return 0; + return -1; + } +static Bool Sphere_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Sphere_Create() +{ + M_Sphere *p; + GF_SAFEALLOC(p, M_Sphere); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Sphere); + + /*default field values*/ + p->radius = FLT2FIX(1); + return (GF_Node *)p; +} + + +/* + SphereSensor Node deletion +*/ + +static void SphereSensor_Del(GF_Node *node) +{ + M_SphereSensor *p = (M_SphereSensor *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 SphereSensor_Def2All[] = { 0, 1, 2}; +static const u16 SphereSensor_In2All[] = { 0, 1, 2}; +static const u16 SphereSensor_Out2All[] = { 0, 1, 2, 3, 4, 5}; + +static u32 SphereSensor_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 6; + } +} + +static GF_Err SphereSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = SphereSensor_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = SphereSensor_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = SphereSensor_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err SphereSensor_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "autoOffset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SphereSensor *) node)->autoOffset; + return GF_OK; + case 1: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SphereSensor *) node)->enabled; + return GF_OK; + case 2: + info->name = "offset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_SphereSensor *) node)->offset; + return GF_OK; + case 3: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SphereSensor *) node)->isActive; + return GF_OK; + case 4: + info->name = "rotation_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_SphereSensor *) node)->rotation_changed; + return GF_OK; + case 5: + info->name = "trackPoint_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SphereSensor *) node)->trackPoint_changed; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 SphereSensor_get_field_index_by_name(char *name) +{ + if (!strcmp("autoOffset", name)) return 0; + if (!strcmp("enabled", name)) return 1; + if (!strcmp("offset", name)) return 2; + if (!strcmp("isActive", name)) return 3; + if (!strcmp("rotation_changed", name)) return 4; + if (!strcmp("trackPoint_changed", name)) return 5; + return -1; + } +static Bool SphereSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 2: + *AType = 0; + *QType = 10; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *SphereSensor_Create() +{ + M_SphereSensor *p; + GF_SAFEALLOC(p, M_SphereSensor); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_SphereSensor); + + /*default field values*/ + p->autoOffset = 1; + p->enabled = 1; + p->offset.x = FLT2FIX(0); + p->offset.y = FLT2FIX(1); + p->offset.z = FLT2FIX(0); + p->offset.q = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + SpotLight Node deletion +*/ + +static void SpotLight_Del(GF_Node *node) +{ + M_SpotLight *p = (M_SpotLight *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 SpotLight_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 SpotLight_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 SpotLight_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 SpotLight_Dyn2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 9}; + +static u32 SpotLight_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 10; + case GF_SG_FIELD_CODING_DEF: return 10; + case GF_SG_FIELD_CODING_OUT: return 10; + case GF_SG_FIELD_CODING_DYN: return 9; + default: + return 10; + } +} + +static GF_Err SpotLight_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = SpotLight_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = SpotLight_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = SpotLight_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = SpotLight_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err SpotLight_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "ambientIntensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SpotLight *) node)->ambientIntensity; + return GF_OK; + case 1: + info->name = "attenuation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SpotLight *) node)->attenuation; + return GF_OK; + case 2: + info->name = "beamWidth"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SpotLight *) node)->beamWidth; + return GF_OK; + case 3: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_SpotLight *) node)->color; + return GF_OK; + case 4: + info->name = "cutOffAngle"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SpotLight *) node)->cutOffAngle; + return GF_OK; + case 5: + info->name = "direction"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SpotLight *) node)->direction; + return GF_OK; + case 6: + info->name = "intensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SpotLight *) node)->intensity; + return GF_OK; + case 7: + info->name = "location"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SpotLight *) node)->location; + return GF_OK; + case 8: + info->name = "on"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SpotLight *) node)->on; + return GF_OK; + case 9: + info->name = "radius"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SpotLight *) node)->radius; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 SpotLight_get_field_index_by_name(char *name) +{ + if (!strcmp("ambientIntensity", name)) return 0; + if (!strcmp("attenuation", name)) return 1; + if (!strcmp("beamWidth", name)) return 2; + if (!strcmp("color", name)) return 3; + if (!strcmp("cutOffAngle", name)) return 4; + if (!strcmp("direction", name)) return 5; + if (!strcmp("intensity", name)) return 6; + if (!strcmp("location", name)) return 7; + if (!strcmp("on", name)) return 8; + if (!strcmp("radius", name)) return 9; + return -1; + } +static Bool SpotLight_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 1: + *AType = 1; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 2: + *AType = 8; + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1.5707963); + return 1; + case 3: + *AType = 4; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 4: + *AType = 8; + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1.5707963); + return 1; + case 5: + *AType = 9; + *QType = 9; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 7: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 9: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *SpotLight_Create() +{ + M_SpotLight *p; + GF_SAFEALLOC(p, M_SpotLight); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_SpotLight); + + /*default field values*/ + p->ambientIntensity = FLT2FIX(0); + p->attenuation.x = FLT2FIX(1); + p->attenuation.y = FLT2FIX(0); + p->attenuation.z = FLT2FIX(0); + p->beamWidth = FLT2FIX(1.570796); + p->color.red = FLT2FIX(1); + p->color.green = FLT2FIX(1); + p->color.blue = FLT2FIX(1); + p->cutOffAngle = FLT2FIX(0.785398); + p->direction.x = FLT2FIX(0); + p->direction.y = FLT2FIX(0); + p->direction.z = FLT2FIX(-1); + p->intensity = FLT2FIX(1); + p->location.x = FLT2FIX(0); + p->location.y = FLT2FIX(0); + p->location.z = FLT2FIX(0); + p->on = 1; + p->radius = FLT2FIX(100); + return (GF_Node *)p; +} + + +/* + Switch Node deletion +*/ + +static void Switch_Del(GF_Node *node) +{ + M_Switch *p = (M_Switch *) node; + gf_node_unregister_children((GF_Node *) p, p->choice); + gf_node_free((GF_Node *) p); +} + +static const u16 Switch_Def2All[] = { 0, 1}; +static const u16 Switch_In2All[] = { 0, 1}; +static const u16 Switch_Out2All[] = { 0, 1}; + +static u32 Switch_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 2; + } +} + +static GF_Err Switch_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Switch_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Switch_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Switch_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Switch_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "choice"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Switch *)node)->choice; + return GF_OK; + case 1: + info->name = "whichChoice"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Switch *) node)->whichChoice; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Switch_get_field_index_by_name(char *name) +{ + if (!strcmp("choice", name)) return 0; + if (!strcmp("whichChoice", name)) return 1; + return -1; + } +static Bool Switch_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 13; + *QT13_bits = 10; + *b_min = FLT2FIX(-1); + *b_max = FLT2FIX( 1022); + return 1; + default: + return 0; + } +} + + + +GF_Node *Switch_Create() +{ + M_Switch *p; + GF_SAFEALLOC(p, M_Switch); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Switch); + + /*default field values*/ + p->whichChoice = -1; + return (GF_Node *)p; +} + + +/* + TermCap Node deletion +*/ + +static void TermCap_Del(GF_Node *node) +{ + M_TermCap *p = (M_TermCap *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 TermCap_Def2All[] = { 1}; +static const u16 TermCap_In2All[] = { 0, 1}; +static const u16 TermCap_Out2All[] = { 1, 2}; + +static u32 TermCap_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 3; + } +} + +static GF_Err TermCap_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = TermCap_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = TermCap_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = TermCap_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err TermCap_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "evaluate"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_TermCap *)node)->on_evaluate; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TermCap *) node)->evaluate; + return GF_OK; + case 1: + info->name = "capability"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_TermCap *) node)->capability; + return GF_OK; + case 2: + info->name = "value"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_TermCap *) node)->value; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 TermCap_get_field_index_by_name(char *name) +{ + if (!strcmp("evaluate", name)) return 0; + if (!strcmp("capability", name)) return 1; + if (!strcmp("value", name)) return 2; + return -1; + } +static Bool TermCap_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 13; + *QT13_bits = 7; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(127); + return 1; + case 2: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(7); + return 1; + default: + return 0; + } +} + + + +GF_Node *TermCap_Create() +{ + M_TermCap *p; + GF_SAFEALLOC(p, M_TermCap); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_TermCap); + + /*default field values*/ + p->capability = 0; + return (GF_Node *)p; +} + + +/* + Text Node deletion +*/ + +static void Text_Del(GF_Node *node) +{ + M_Text *p = (M_Text *) node; + gf_sg_mfstring_del(p->string); + gf_sg_mffloat_del(p->length); + gf_node_unregister((GF_Node *) p->fontStyle, (GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Text_Def2All[] = { 0, 1, 2, 3}; +static const u16 Text_In2All[] = { 0, 1, 2, 3}; +static const u16 Text_Out2All[] = { 0, 1, 2, 3}; +static const u16 Text_Dyn2All[] = { 1, 3}; + +static u32 Text_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 2; + default: + return 4; + } +} + +static GF_Err Text_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Text_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Text_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Text_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Text_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Text_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "string"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_Text *) node)->string; + return GF_OK; + case 1: + info->name = "length"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_Text *) node)->length; + return GF_OK; + case 2: + info->name = "fontStyle"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFFontStyleNode; + info->far_ptr = & ((M_Text *)node)->fontStyle; + return GF_OK; + case 3: + info->name = "maxExtent"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Text *) node)->maxExtent; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Text_get_field_index_by_name(char *name) +{ + if (!strcmp("string", name)) return 0; + if (!strcmp("length", name)) return 1; + if (!strcmp("fontStyle", name)) return 2; + if (!strcmp("maxExtent", name)) return 3; + return -1; + } +static Bool Text_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 7; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Text_Create() +{ + M_Text *p; + GF_SAFEALLOC(p, M_Text); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Text); + + /*default field values*/ + p->maxExtent = FLT2FIX(0.0); + return (GF_Node *)p; +} + + +/* + TextureCoordinate Node deletion +*/ + +static void TextureCoordinate_Del(GF_Node *node) +{ + M_TextureCoordinate *p = (M_TextureCoordinate *) node; + gf_sg_mfvec2f_del(p->point); + gf_node_free((GF_Node *) p); +} + +static const u16 TextureCoordinate_Def2All[] = { 0}; +static const u16 TextureCoordinate_In2All[] = { 0}; +static const u16 TextureCoordinate_Out2All[] = { 0}; +static const u16 TextureCoordinate_Dyn2All[] = { 0}; + +static u32 TextureCoordinate_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 1; + } +} + +static GF_Err TextureCoordinate_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = TextureCoordinate_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = TextureCoordinate_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = TextureCoordinate_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = TextureCoordinate_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err TextureCoordinate_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "point"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_TextureCoordinate *) node)->point; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 TextureCoordinate_get_field_index_by_name(char *name) +{ + if (!strcmp("point", name)) return 0; + return -1; + } +static Bool TextureCoordinate_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 2; + *QType = 5; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *TextureCoordinate_Create() +{ + M_TextureCoordinate *p; + GF_SAFEALLOC(p, M_TextureCoordinate); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_TextureCoordinate); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + TextureTransform Node deletion +*/ + +static void TextureTransform_Del(GF_Node *node) +{ + M_TextureTransform *p = (M_TextureTransform *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 TextureTransform_Def2All[] = { 0, 1, 2, 3}; +static const u16 TextureTransform_In2All[] = { 0, 1, 2, 3}; +static const u16 TextureTransform_Out2All[] = { 0, 1, 2, 3}; +static const u16 TextureTransform_Dyn2All[] = { 0, 1, 2, 3}; + +static u32 TextureTransform_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 4; + default: + return 4; + } +} + +static GF_Err TextureTransform_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = TextureTransform_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = TextureTransform_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = TextureTransform_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = TextureTransform_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err TextureTransform_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_TextureTransform *) node)->center; + return GF_OK; + case 1: + info->name = "rotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_TextureTransform *) node)->rotation; + return GF_OK; + case 2: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_TextureTransform *) node)->scale; + return GF_OK; + case 3: + info->name = "translation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_TextureTransform *) node)->translation; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 TextureTransform_get_field_index_by_name(char *name) +{ + if (!strcmp("center", name)) return 0; + if (!strcmp("rotation", name)) return 1; + if (!strcmp("scale", name)) return 2; + if (!strcmp("translation", name)) return 3; + return -1; + } +static Bool TextureTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 2; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 6; + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(6.2831853); + return 1; + case 2: + *AType = 12; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 2; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *TextureTransform_Create() +{ + M_TextureTransform *p; + GF_SAFEALLOC(p, M_TextureTransform); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_TextureTransform); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->rotation = FLT2FIX(0); + p->scale.x = FLT2FIX(1); + p->scale.y = FLT2FIX(1); + p->translation.x = FLT2FIX(0); + p->translation.y = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + TimeSensor Node deletion +*/ + +static void TimeSensor_Del(GF_Node *node) +{ + M_TimeSensor *p = (M_TimeSensor *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 TimeSensor_Def2All[] = { 0, 1, 2, 3, 4}; +static const u16 TimeSensor_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 TimeSensor_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; + +static u32 TimeSensor_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 9; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 9; + } +} + +static GF_Err TimeSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = TimeSensor_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = TimeSensor_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = TimeSensor_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err TimeSensor_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "cycleInterval"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TimeSensor *) node)->cycleInterval; + return GF_OK; + case 1: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_TimeSensor *) node)->enabled; + return GF_OK; + case 2: + info->name = "loop"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_TimeSensor *) node)->loop; + return GF_OK; + case 3: + info->name = "startTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TimeSensor *) node)->startTime; + return GF_OK; + case 4: + info->name = "stopTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TimeSensor *) node)->stopTime; + return GF_OK; + case 5: + info->name = "cycleTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TimeSensor *) node)->cycleTime; + return GF_OK; + case 6: + info->name = "fraction_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_TimeSensor *) node)->fraction_changed; + return GF_OK; + case 7: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_TimeSensor *) node)->isActive; + return GF_OK; + case 8: + info->name = "time"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TimeSensor *) node)->time; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 TimeSensor_get_field_index_by_name(char *name) +{ + if (!strcmp("cycleInterval", name)) return 0; + if (!strcmp("enabled", name)) return 1; + if (!strcmp("loop", name)) return 2; + if (!strcmp("startTime", name)) return 3; + if (!strcmp("stopTime", name)) return 4; + if (!strcmp("cycleTime", name)) return 5; + if (!strcmp("fraction_changed", name)) return 6; + if (!strcmp("isActive", name)) return 7; + if (!strcmp("time", name)) return 8; + return -1; + } +static Bool TimeSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *TimeSensor_Create() +{ + M_TimeSensor *p; + GF_SAFEALLOC(p, M_TimeSensor); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_TimeSensor); + + /*default field values*/ + p->cycleInterval = 1; + p->enabled = 1; + p->startTime = 0; + p->stopTime = 0; + return (GF_Node *)p; +} + + +/* + TouchSensor Node deletion +*/ + +static void TouchSensor_Del(GF_Node *node) +{ + M_TouchSensor *p = (M_TouchSensor *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 TouchSensor_Def2All[] = { 0}; +static const u16 TouchSensor_In2All[] = { 0}; +static const u16 TouchSensor_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; + +static u32 TouchSensor_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 7; + } +} + +static GF_Err TouchSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = TouchSensor_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = TouchSensor_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = TouchSensor_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err TouchSensor_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_TouchSensor *) node)->enabled; + return GF_OK; + case 1: + info->name = "hitNormal_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_TouchSensor *) node)->hitNormal_changed; + return GF_OK; + case 2: + info->name = "hitPoint_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_TouchSensor *) node)->hitPoint_changed; + return GF_OK; + case 3: + info->name = "hitTexCoord_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_TouchSensor *) node)->hitTexCoord_changed; + return GF_OK; + case 4: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_TouchSensor *) node)->isActive; + return GF_OK; + case 5: + info->name = "isOver"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_TouchSensor *) node)->isOver; + return GF_OK; + case 6: + info->name = "touchTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TouchSensor *) node)->touchTime; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 TouchSensor_get_field_index_by_name(char *name) +{ + if (!strcmp("enabled", name)) return 0; + if (!strcmp("hitNormal_changed", name)) return 1; + if (!strcmp("hitPoint_changed", name)) return 2; + if (!strcmp("hitTexCoord_changed", name)) return 3; + if (!strcmp("isActive", name)) return 4; + if (!strcmp("isOver", name)) return 5; + if (!strcmp("touchTime", name)) return 6; + return -1; + } +static Bool TouchSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *TouchSensor_Create() +{ + M_TouchSensor *p; + GF_SAFEALLOC(p, M_TouchSensor); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_TouchSensor); + + /*default field values*/ + p->enabled = 1; + return (GF_Node *)p; +} + + +/* + Transform Node deletion +*/ + +static void Transform_Del(GF_Node *node) +{ + M_Transform *p = (M_Transform *) node; + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Transform_Def2All[] = { 2, 3, 4, 5, 6, 7}; +static const u16 Transform_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 Transform_Out2All[] = { 2, 3, 4, 5, 6, 7}; +static const u16 Transform_Dyn2All[] = { 2, 4, 5, 6, 7}; + +static u32 Transform_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 8; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 5; + default: + return 8; + } +} + +static GF_Err Transform_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Transform_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Transform_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Transform_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Transform_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Transform_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Transform *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Transform *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Transform *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Transform *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Transform *) node)->center; + return GF_OK; + case 3: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Transform *)node)->children; + return GF_OK; + case 4: + info->name = "rotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_Transform *) node)->rotation; + return GF_OK; + case 5: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Transform *) node)->scale; + return GF_OK; + case 6: + info->name = "scaleOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_Transform *) node)->scaleOrientation; + return GF_OK; + case 7: + info->name = "translation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Transform *) node)->translation; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Transform_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("center", name)) return 2; + if (!strcmp("children", name)) return 3; + if (!strcmp("rotation", name)) return 4; + if (!strcmp("scale", name)) return 5; + if (!strcmp("scaleOrientation", name)) return 6; + if (!strcmp("translation", name)) return 7; + return -1; + } +static Bool Transform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 2: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 10; + *QType = 10; + return 1; + case 5: + *AType = 11; + *QType = 7; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 10; + *QType = 10; + return 1; + case 7: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Transform_Create() +{ + M_Transform *p; + GF_SAFEALLOC(p, M_Transform); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Transform); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->rotation.x = FLT2FIX(0); + p->rotation.y = FLT2FIX(0); + p->rotation.z = FLT2FIX(1); + p->rotation.q = FLT2FIX(0); + p->scale.x = FLT2FIX(1); + p->scale.y = FLT2FIX(1); + p->scale.z = FLT2FIX(1); + p->scaleOrientation.x = FLT2FIX(0); + p->scaleOrientation.y = FLT2FIX(0); + p->scaleOrientation.z = FLT2FIX(1); + p->scaleOrientation.q = FLT2FIX(0); + p->translation.x = FLT2FIX(0); + p->translation.y = FLT2FIX(0); + p->translation.z = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + Transform2D Node deletion +*/ + +static void Transform2D_Del(GF_Node *node) +{ + M_Transform2D *p = (M_Transform2D *) node; + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 Transform2D_Def2All[] = { 2, 3, 4, 5, 6, 7}; +static const u16 Transform2D_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 Transform2D_Out2All[] = { 2, 3, 4, 5, 6, 7}; +static const u16 Transform2D_Dyn2All[] = { 3, 4, 5, 6, 7}; + +static u32 Transform2D_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 8; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 5; + default: + return 8; + } +} + +static GF_Err Transform2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Transform2D_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Transform2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Transform2D_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Transform2D_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Transform2D_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Transform2D *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Transform2D *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Transform2D *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Transform2D *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Transform2D *)node)->children; + return GF_OK; + case 3: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Transform2D *) node)->center; + return GF_OK; + case 4: + info->name = "rotationAngle"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Transform2D *) node)->rotationAngle; + return GF_OK; + case 5: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Transform2D *) node)->scale; + return GF_OK; + case 6: + info->name = "scaleOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Transform2D *) node)->scaleOrientation; + return GF_OK; + case 7: + info->name = "translation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Transform2D *) node)->translation; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Transform2D_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("center", name)) return 3; + if (!strcmp("rotationAngle", name)) return 4; + if (!strcmp("scale", name)) return 5; + if (!strcmp("scaleOrientation", name)) return 6; + if (!strcmp("translation", name)) return 7; + return -1; + } +static Bool Transform2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 3: + *AType = 2; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 6; + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(6.2831853); + return 1; + case 5: + *AType = 12; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 6; + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(6.2831853); + return 1; + case 7: + *AType = 2; + *QType = 2; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Transform2D_Create() +{ + M_Transform2D *p; + GF_SAFEALLOC(p, M_Transform2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Transform2D); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->rotationAngle = FLT2FIX(0); + p->scale.x = FLT2FIX(1); + p->scale.y = FLT2FIX(1); + p->scaleOrientation = FLT2FIX(0); + p->translation.x = FLT2FIX(0); + p->translation.y = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + Valuator Node deletion +*/ + +static void Valuator_Del(GF_Node *node) +{ + M_Valuator *p = (M_Valuator *) node; + gf_sg_mfcolor_del(p->inMFColor); + gf_sg_mffloat_del(p->inMFFloat); + gf_sg_mfint32_del(p->inMFInt32); + gf_sg_mfrotation_del(p->inMFRotation); + gf_sg_sfstring_del(p->inSFString); + gf_sg_mfstring_del(p->inMFString); + gf_sg_mfvec2f_del(p->inMFVec2f); + gf_sg_mfvec3f_del(p->inMFVec3f); + gf_sg_mfcolor_del(p->outMFColor); + gf_sg_mffloat_del(p->outMFFloat); + gf_sg_mfint32_del(p->outMFInt32); + gf_sg_mfrotation_del(p->outMFRotation); + gf_sg_sfstring_del(p->outSFString); + gf_sg_mfstring_del(p->outMFString); + gf_sg_mfvec2f_del(p->outMFVec2f); + gf_sg_mfvec3f_del(p->outMFVec3f); + gf_node_free((GF_Node *) p); +} + +static const u16 Valuator_Def2All[] = { 32, 33, 34, 35, 36, 37, 38, 39, 40}; +static const u16 Valuator_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 32, 33, 34, 35, 36, 37, 38, 39, 40}; +static const u16 Valuator_Out2All[] = { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}; + +static u32 Valuator_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 25; + case GF_SG_FIELD_CODING_DEF: return 9; + case GF_SG_FIELD_CODING_OUT: return 25; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 41; + } +} + +static GF_Err Valuator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Valuator_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Valuator_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Valuator_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Valuator_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "inSFBool"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inSFBool; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Valuator *) node)->inSFBool; + return GF_OK; + case 1: + info->name = "inSFColor"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inSFColor; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_Valuator *) node)->inSFColor; + return GF_OK; + case 2: + info->name = "inMFColor"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inMFColor; + info->fieldType = GF_SG_VRML_MFCOLOR; + info->far_ptr = & ((M_Valuator *) node)->inMFColor; + return GF_OK; + case 3: + info->name = "inSFFloat"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inSFFloat; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->inSFFloat; + return GF_OK; + case 4: + info->name = "inMFFloat"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inMFFloat; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->inMFFloat; + return GF_OK; + case 5: + info->name = "inSFInt32"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inSFInt32; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Valuator *) node)->inSFInt32; + return GF_OK; + case 6: + info->name = "inMFInt32"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inMFInt32; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_Valuator *) node)->inMFInt32; + return GF_OK; + case 7: + info->name = "inSFRotation"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inSFRotation; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_Valuator *) node)->inSFRotation; + return GF_OK; + case 8: + info->name = "inMFRotation"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inMFRotation; + info->fieldType = GF_SG_VRML_MFROTATION; + info->far_ptr = & ((M_Valuator *) node)->inMFRotation; + return GF_OK; + case 9: + info->name = "inSFString"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inSFString; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_Valuator *) node)->inSFString; + return GF_OK; + case 10: + info->name = "inMFString"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inMFString; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_Valuator *) node)->inMFString; + return GF_OK; + case 11: + info->name = "inSFTime"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inSFTime; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_Valuator *) node)->inSFTime; + return GF_OK; + case 12: + info->name = "inSFVec2f"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inSFVec2f; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Valuator *) node)->inSFVec2f; + return GF_OK; + case 13: + info->name = "inMFVec2f"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inMFVec2f; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_Valuator *) node)->inMFVec2f; + return GF_OK; + case 14: + info->name = "inSFVec3f"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inSFVec3f; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Valuator *) node)->inSFVec3f; + return GF_OK; + case 15: + info->name = "inMFVec3f"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Valuator *)node)->on_inMFVec3f; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_Valuator *) node)->inMFVec3f; + return GF_OK; + case 16: + info->name = "outSFBool"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Valuator *) node)->outSFBool; + return GF_OK; + case 17: + info->name = "outSFColor"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_Valuator *) node)->outSFColor; + return GF_OK; + case 18: + info->name = "outMFColor"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFCOLOR; + info->far_ptr = & ((M_Valuator *) node)->outMFColor; + return GF_OK; + case 19: + info->name = "outSFFloat"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->outSFFloat; + return GF_OK; + case 20: + info->name = "outMFFloat"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->outMFFloat; + return GF_OK; + case 21: + info->name = "outSFInt32"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Valuator *) node)->outSFInt32; + return GF_OK; + case 22: + info->name = "outMFInt32"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_Valuator *) node)->outMFInt32; + return GF_OK; + case 23: + info->name = "outSFRotation"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_Valuator *) node)->outSFRotation; + return GF_OK; + case 24: + info->name = "outMFRotation"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFROTATION; + info->far_ptr = & ((M_Valuator *) node)->outMFRotation; + return GF_OK; + case 25: + info->name = "outSFString"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_Valuator *) node)->outSFString; + return GF_OK; + case 26: + info->name = "outMFString"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_Valuator *) node)->outMFString; + return GF_OK; + case 27: + info->name = "outSFTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_Valuator *) node)->outSFTime; + return GF_OK; + case 28: + info->name = "outSFVec2f"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Valuator *) node)->outSFVec2f; + return GF_OK; + case 29: + info->name = "outMFVec2f"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_Valuator *) node)->outMFVec2f; + return GF_OK; + case 30: + info->name = "outSFVec3f"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Valuator *) node)->outSFVec3f; + return GF_OK; + case 31: + info->name = "outMFVec3f"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_Valuator *) node)->outMFVec3f; + return GF_OK; + case 32: + info->name = "Factor1"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->Factor1; + return GF_OK; + case 33: + info->name = "Factor2"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->Factor2; + return GF_OK; + case 34: + info->name = "Factor3"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->Factor3; + return GF_OK; + case 35: + info->name = "Factor4"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->Factor4; + return GF_OK; + case 36: + info->name = "Offset1"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->Offset1; + return GF_OK; + case 37: + info->name = "Offset2"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->Offset2; + return GF_OK; + case 38: + info->name = "Offset3"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->Offset3; + return GF_OK; + case 39: + info->name = "Offset4"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Valuator *) node)->Offset4; + return GF_OK; + case 40: + info->name = "Sum"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Valuator *) node)->Sum; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Valuator_get_field_index_by_name(char *name) +{ + if (!strcmp("inSFBool", name)) return 0; + if (!strcmp("inSFColor", name)) return 1; + if (!strcmp("inMFColor", name)) return 2; + if (!strcmp("inSFFloat", name)) return 3; + if (!strcmp("inMFFloat", name)) return 4; + if (!strcmp("inSFInt32", name)) return 5; + if (!strcmp("inMFInt32", name)) return 6; + if (!strcmp("inSFRotation", name)) return 7; + if (!strcmp("inMFRotation", name)) return 8; + if (!strcmp("inSFString", name)) return 9; + if (!strcmp("inMFString", name)) return 10; + if (!strcmp("inSFTime", name)) return 11; + if (!strcmp("inSFVec2f", name)) return 12; + if (!strcmp("inMFVec2f", name)) return 13; + if (!strcmp("inSFVec3f", name)) return 14; + if (!strcmp("inMFVec3f", name)) return 15; + if (!strcmp("outSFBool", name)) return 16; + if (!strcmp("outSFColor", name)) return 17; + if (!strcmp("outMFColor", name)) return 18; + if (!strcmp("outSFFloat", name)) return 19; + if (!strcmp("outMFFloat", name)) return 20; + if (!strcmp("outSFInt32", name)) return 21; + if (!strcmp("outMFInt32", name)) return 22; + if (!strcmp("outSFRotation", name)) return 23; + if (!strcmp("outMFRotation", name)) return 24; + if (!strcmp("outSFString", name)) return 25; + if (!strcmp("outMFString", name)) return 26; + if (!strcmp("outSFTime", name)) return 27; + if (!strcmp("outSFVec2f", name)) return 28; + if (!strcmp("outMFVec2f", name)) return 29; + if (!strcmp("outSFVec3f", name)) return 30; + if (!strcmp("outMFVec3f", name)) return 31; + if (!strcmp("Factor1", name)) return 32; + if (!strcmp("Factor2", name)) return 33; + if (!strcmp("Factor3", name)) return 34; + if (!strcmp("Factor4", name)) return 35; + if (!strcmp("Offset1", name)) return 36; + if (!strcmp("Offset2", name)) return 37; + if (!strcmp("Offset3", name)) return 38; + if (!strcmp("Offset4", name)) return 39; + if (!strcmp("Sum", name)) return 40; + return -1; + } +static Bool Valuator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 32: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 33: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 34: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 35: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 36: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 37: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 38: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 39: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Valuator_Create() +{ + M_Valuator *p; + GF_SAFEALLOC(p, M_Valuator); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Valuator); + + /*default field values*/ + p->Factor1 = FLT2FIX(1.0); + p->Factor2 = FLT2FIX(1.0); + p->Factor3 = FLT2FIX(1.0); + p->Factor4 = FLT2FIX(1.0); + p->Offset1 = FLT2FIX(0.0); + p->Offset2 = FLT2FIX(0.0); + p->Offset3 = FLT2FIX(0.0); + p->Offset4 = FLT2FIX(0.0); + return (GF_Node *)p; +} + + +/* + Viewpoint Node deletion +*/ + +static void Viewpoint_Del(GF_Node *node) +{ + M_Viewpoint *p = (M_Viewpoint *) node; + gf_sg_sfstring_del(p->description); + gf_node_free((GF_Node *) p); +} + +static const u16 Viewpoint_Def2All[] = { 1, 2, 3, 4, 5}; +static const u16 Viewpoint_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 Viewpoint_Out2All[] = { 1, 2, 3, 4, 6, 7}; +static const u16 Viewpoint_Dyn2All[] = { 1, 3, 4}; + +static u32 Viewpoint_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 3; + default: + return 8; + } +} + +static GF_Err Viewpoint_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Viewpoint_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Viewpoint_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Viewpoint_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Viewpoint_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Viewpoint_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_bind"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Viewpoint *)node)->on_set_bind; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Viewpoint *) node)->set_bind; + return GF_OK; + case 1: + info->name = "fieldOfView"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Viewpoint *) node)->fieldOfView; + return GF_OK; + case 2: + info->name = "jump"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Viewpoint *) node)->jump; + return GF_OK; + case 3: + info->name = "orientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_Viewpoint *) node)->orientation; + return GF_OK; + case 4: + info->name = "position"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Viewpoint *) node)->position; + return GF_OK; + case 5: + info->name = "description"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_Viewpoint *) node)->description; + return GF_OK; + case 6: + info->name = "bindTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_Viewpoint *) node)->bindTime; + return GF_OK; + case 7: + info->name = "isBound"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Viewpoint *) node)->isBound; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Viewpoint_get_field_index_by_name(char *name) +{ + if (!strcmp("set_bind", name)) return 0; + if (!strcmp("fieldOfView", name)) return 1; + if (!strcmp("jump", name)) return 2; + if (!strcmp("orientation", name)) return 3; + if (!strcmp("position", name)) return 4; + if (!strcmp("description", name)) return 5; + if (!strcmp("bindTime", name)) return 6; + if (!strcmp("isBound", name)) return 7; + return -1; + } +static Bool Viewpoint_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 8; + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(3.1415927); + return 1; + case 3: + *AType = 10; + *QType = 10; + return 1; + case 4: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *Viewpoint_Create() +{ + M_Viewpoint *p; + GF_SAFEALLOC(p, M_Viewpoint); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Viewpoint); + + /*default field values*/ + p->fieldOfView = FLT2FIX(0.785398); + p->jump = 1; + p->orientation.x = FLT2FIX(0); + p->orientation.y = FLT2FIX(0); + p->orientation.z = FLT2FIX(1); + p->orientation.q = FLT2FIX(0); + p->position.x = FLT2FIX(0); + p->position.y = FLT2FIX(0); + p->position.z = FLT2FIX(10); + return (GF_Node *)p; +} + + +/* + VisibilitySensor Node deletion +*/ + +static void VisibilitySensor_Del(GF_Node *node) +{ + M_VisibilitySensor *p = (M_VisibilitySensor *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 VisibilitySensor_Def2All[] = { 0, 1, 2}; +static const u16 VisibilitySensor_In2All[] = { 0, 1, 2}; +static const u16 VisibilitySensor_Out2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 VisibilitySensor_Dyn2All[] = { 0, 2}; + +static u32 VisibilitySensor_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 2; + default: + return 6; + } +} + +static GF_Err VisibilitySensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = VisibilitySensor_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = VisibilitySensor_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = VisibilitySensor_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = VisibilitySensor_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err VisibilitySensor_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_VisibilitySensor *) node)->center; + return GF_OK; + case 1: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_VisibilitySensor *) node)->enabled; + return GF_OK; + case 2: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_VisibilitySensor *) node)->size; + return GF_OK; + case 3: + info->name = "enterTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_VisibilitySensor *) node)->enterTime; + return GF_OK; + case 4: + info->name = "exitTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_VisibilitySensor *) node)->exitTime; + return GF_OK; + case 5: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_VisibilitySensor *) node)->isActive; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 VisibilitySensor_get_field_index_by_name(char *name) +{ + if (!strcmp("center", name)) return 0; + if (!strcmp("enabled", name)) return 1; + if (!strcmp("size", name)) return 2; + if (!strcmp("enterTime", name)) return 3; + if (!strcmp("exitTime", name)) return 4; + if (!strcmp("isActive", name)) return 5; + return -1; + } +static Bool VisibilitySensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 2: + *AType = 11; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *VisibilitySensor_Create() +{ + M_VisibilitySensor *p; + GF_SAFEALLOC(p, M_VisibilitySensor); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_VisibilitySensor); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->enabled = 1; + p->size.x = FLT2FIX(0); + p->size.y = FLT2FIX(0); + p->size.z = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + Viseme Node deletion +*/ + +static void Viseme_Del(GF_Node *node) +{ + M_Viseme *p = (M_Viseme *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 Viseme_Def2All[] = { 0, 1, 2, 3}; +static const u16 Viseme_In2All[] = { 0, 1, 2, 3}; +static const u16 Viseme_Out2All[] = { 0, 1, 2, 3}; + +static u32 Viseme_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 4; + } +} + +static GF_Err Viseme_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Viseme_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Viseme_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Viseme_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Viseme_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "viseme_select1"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Viseme *) node)->viseme_select1; + return GF_OK; + case 1: + info->name = "viseme_select2"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Viseme *) node)->viseme_select2; + return GF_OK; + case 2: + info->name = "viseme_blend"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Viseme *) node)->viseme_blend; + return GF_OK; + case 3: + info->name = "viseme_def"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Viseme *) node)->viseme_def; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Viseme_get_field_index_by_name(char *name) +{ + if (!strcmp("viseme_select1", name)) return 0; + if (!strcmp("viseme_select2", name)) return 1; + if (!strcmp("viseme_blend", name)) return 2; + if (!strcmp("viseme_def", name)) return 3; + return -1; + } +static Bool Viseme_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 1: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; + case 2: + *AType = 0; + *QType = 13; + *QT13_bits = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(63); + return 1; + default: + return 0; + } +} + + + +GF_Node *Viseme_Create() +{ + M_Viseme *p; + GF_SAFEALLOC(p, M_Viseme); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Viseme); + + /*default field values*/ + p->viseme_select1 = 0; + p->viseme_select2 = 0; + p->viseme_blend = 0; + return (GF_Node *)p; +} + + +/* + WorldInfo Node deletion +*/ + +static void WorldInfo_Del(GF_Node *node) +{ + M_WorldInfo *p = (M_WorldInfo *) node; + gf_sg_mfstring_del(p->info); + gf_sg_sfstring_del(p->title); + gf_node_free((GF_Node *) p); +} + +static const u16 WorldInfo_Def2All[] = { 0, 1}; + +static u32 WorldInfo_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 2; + } +} + +static GF_Err WorldInfo_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_DEF: + *allField = WorldInfo_Def2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err WorldInfo_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "info"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_WorldInfo *) node)->info; + return GF_OK; + case 1: + info->name = "title"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_WorldInfo *) node)->title; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 WorldInfo_get_field_index_by_name(char *name) +{ + if (!strcmp("info", name)) return 0; + if (!strcmp("title", name)) return 1; + return -1; + } +static Bool WorldInfo_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *WorldInfo_Create() +{ + M_WorldInfo *p; + GF_SAFEALLOC(p, M_WorldInfo); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_WorldInfo); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + AcousticMaterial Node deletion +*/ + +static void AcousticMaterial_Del(GF_Node *node) +{ + M_AcousticMaterial *p = (M_AcousticMaterial *) node; + gf_sg_mffloat_del(p->reffunc); + gf_sg_mffloat_del(p->transfunc); + gf_sg_mffloat_del(p->refFrequency); + gf_sg_mffloat_del(p->transFrequency); + gf_node_free((GF_Node *) p); +} + +static const u16 AcousticMaterial_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 AcousticMaterial_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 AcousticMaterial_Out2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 AcousticMaterial_Dyn2All[] = { 0, 1, 2, 3, 4, 5}; + +static u32 AcousticMaterial_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 10; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 6; + default: + return 10; + } +} + +static GF_Err AcousticMaterial_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = AcousticMaterial_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = AcousticMaterial_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = AcousticMaterial_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = AcousticMaterial_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err AcousticMaterial_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "ambientIntensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_AcousticMaterial *) node)->ambientIntensity; + return GF_OK; + case 1: + info->name = "diffuseColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_AcousticMaterial *) node)->diffuseColor; + return GF_OK; + case 2: + info->name = "emissiveColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_AcousticMaterial *) node)->emissiveColor; + return GF_OK; + case 3: + info->name = "shininess"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_AcousticMaterial *) node)->shininess; + return GF_OK; + case 4: + info->name = "specularColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_AcousticMaterial *) node)->specularColor; + return GF_OK; + case 5: + info->name = "transparency"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_AcousticMaterial *) node)->transparency; + return GF_OK; + case 6: + info->name = "reffunc"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_AcousticMaterial *) node)->reffunc; + return GF_OK; + case 7: + info->name = "transfunc"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_AcousticMaterial *) node)->transfunc; + return GF_OK; + case 8: + info->name = "refFrequency"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_AcousticMaterial *) node)->refFrequency; + return GF_OK; + case 9: + info->name = "transFrequency"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_AcousticMaterial *) node)->transFrequency; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 AcousticMaterial_get_field_index_by_name(char *name) +{ + if (!strcmp("ambientIntensity", name)) return 0; + if (!strcmp("diffuseColor", name)) return 1; + if (!strcmp("emissiveColor", name)) return 2; + if (!strcmp("shininess", name)) return 3; + if (!strcmp("specularColor", name)) return 4; + if (!strcmp("transparency", name)) return 5; + if (!strcmp("reffunc", name)) return 6; + if (!strcmp("transfunc", name)) return 7; + if (!strcmp("refFrequency", name)) return 8; + if (!strcmp("transFrequency", name)) return 9; + return -1; + } +static Bool AcousticMaterial_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 1: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 3: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 4: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 5: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 6: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 8: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 9: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *AcousticMaterial_Create() +{ + M_AcousticMaterial *p; + GF_SAFEALLOC(p, M_AcousticMaterial); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_AcousticMaterial); + + /*default field values*/ + p->ambientIntensity = FLT2FIX(0.2); + p->diffuseColor.red = FLT2FIX(0.8); + p->diffuseColor.green = FLT2FIX(0.8); + p->diffuseColor.blue = FLT2FIX(0.8); + p->emissiveColor.red = FLT2FIX(0); + p->emissiveColor.green = FLT2FIX(0); + p->emissiveColor.blue = FLT2FIX(0); + p->shininess = FLT2FIX(0.2); + p->specularColor.red = FLT2FIX(0); + p->specularColor.green = FLT2FIX(0); + p->specularColor.blue = FLT2FIX(0); + p->transparency = FLT2FIX(0); + p->reffunc.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->reffunc.count = 1; + p->reffunc.vals[0] = FLT2FIX(0); + p->transfunc.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->transfunc.count = 1; + p->transfunc.vals[0] = FLT2FIX(1); + p->refFrequency.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->refFrequency.count = 1; + p->refFrequency.vals[0] = FLT2FIX(0); + p->transFrequency.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->transFrequency.count = 1; + p->transFrequency.vals[0] = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + AcousticScene Node deletion +*/ + +static void AcousticScene_Del(GF_Node *node) +{ + M_AcousticScene *p = (M_AcousticScene *) node; + gf_sg_mftime_del(p->reverbTime); + gf_sg_mffloat_del(p->reverbFreq); + gf_node_free((GF_Node *) p); +} + +static const u16 AcousticScene_Def2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 AcousticScene_In2All[] = { 4, 5}; +static const u16 AcousticScene_Out2All[] = { 4, 5}; +static const u16 AcousticScene_Dyn2All[] = { 4}; + +static u32 AcousticScene_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 6; + } +} + +static GF_Err AcousticScene_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = AcousticScene_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = AcousticScene_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = AcousticScene_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = AcousticScene_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err AcousticScene_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "center"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_AcousticScene *) node)->center; + return GF_OK; + case 1: + info->name = "Size"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_AcousticScene *) node)->Size; + return GF_OK; + case 2: + info->name = "reverbTime"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFTIME; + info->far_ptr = & ((M_AcousticScene *) node)->reverbTime; + return GF_OK; + case 3: + info->name = "reverbFreq"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_AcousticScene *) node)->reverbFreq; + return GF_OK; + case 4: + info->name = "reverbLevel"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_AcousticScene *) node)->reverbLevel; + return GF_OK; + case 5: + info->name = "reverbDelay"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_AcousticScene *) node)->reverbDelay; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 AcousticScene_get_field_index_by_name(char *name) +{ + if (!strcmp("center", name)) return 0; + if (!strcmp("Size", name)) return 1; + if (!strcmp("reverbTime", name)) return 2; + if (!strcmp("reverbFreq", name)) return 3; + if (!strcmp("reverbLevel", name)) return 4; + if (!strcmp("reverbDelay", name)) return 5; + return -1; + } +static Bool AcousticScene_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 0; + *QType = 11; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 2: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0 ); + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0 ); + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 7; + *QType = 0; + *b_min = FLT2FIX(0 ); + *b_max = FIX_MAX; + return 1; + case 5: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0 ); + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *AcousticScene_Create() +{ + M_AcousticScene *p; + GF_SAFEALLOC(p, M_AcousticScene); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_AcousticScene); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->Size.x = FLT2FIX(-1); + p->Size.y = FLT2FIX(-1); + p->Size.z = FLT2FIX(-1); + p->reverbTime.vals = (SFTime*)gf_malloc(sizeof(SFTime)*1); + p->reverbTime.count = 1; + p->reverbTime.vals[0] = 0; + p->reverbFreq.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->reverbFreq.count = 1; + p->reverbFreq.vals[0] = FLT2FIX(1000); + p->reverbLevel = FLT2FIX(0.4); + p->reverbDelay = 0.5; + return (GF_Node *)p; +} + + +/* + ApplicationWindow Node deletion +*/ + +static void ApplicationWindow_Del(GF_Node *node) +{ + M_ApplicationWindow *p = (M_ApplicationWindow *) node; + gf_sg_sfstring_del(p->description); + gf_sg_mfstring_del(p->parameter); + gf_sg_mfurl_del(p->url); + gf_node_free((GF_Node *) p); +} + +static const u16 ApplicationWindow_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 ApplicationWindow_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 ApplicationWindow_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 ApplicationWindow_Dyn2All[] = { 6}; + +static u32 ApplicationWindow_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 7; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 1; + default: + return 7; + } +} + +static GF_Err ApplicationWindow_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = ApplicationWindow_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = ApplicationWindow_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = ApplicationWindow_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = ApplicationWindow_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err ApplicationWindow_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ApplicationWindow *) node)->isActive; + return GF_OK; + case 1: + info->name = "startTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_ApplicationWindow *) node)->startTime; + return GF_OK; + case 2: + info->name = "stopTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_ApplicationWindow *) node)->stopTime; + return GF_OK; + case 3: + info->name = "description"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_ApplicationWindow *) node)->description; + return GF_OK; + case 4: + info->name = "parameter"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_ApplicationWindow *) node)->parameter; + return GF_OK; + case 5: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_ApplicationWindow *) node)->url; + return GF_OK; + case 6: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_ApplicationWindow *) node)->size; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 ApplicationWindow_get_field_index_by_name(char *name) +{ + if (!strcmp("isActive", name)) return 0; + if (!strcmp("startTime", name)) return 1; + if (!strcmp("stopTime", name)) return 2; + if (!strcmp("description", name)) return 3; + if (!strcmp("parameter", name)) return 4; + if (!strcmp("url", name)) return 5; + if (!strcmp("size", name)) return 6; + return -1; + } +static Bool ApplicationWindow_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 2: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 12; + *QType = 12; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + default: + return 0; + } +} + + + +GF_Node *ApplicationWindow_Create() +{ + M_ApplicationWindow *p; + GF_SAFEALLOC(p, M_ApplicationWindow); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_ApplicationWindow); + + /*default field values*/ + p->startTime = 0; + p->stopTime = 0; + p->size.x = FLT2FIX(0); + p->size.y = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + BAP Node deletion +*/ + +static void BAP_Del(GF_Node *node) +{ + M_BAP *p = (M_BAP *) node; + gf_node_free((GF_Node *) p); +} + +static const u16 BAP_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295}; +static const u16 BAP_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295}; +static const u16 BAP_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295}; + +static u32 BAP_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 296; + case GF_SG_FIELD_CODING_DEF: return 296; + case GF_SG_FIELD_CODING_OUT: return 296; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 296; + } +} + +static GF_Err BAP_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = BAP_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = BAP_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = BAP_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err BAP_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "sacroiliac_tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->sacroiliac_tilt; + return GF_OK; + case 1: + info->name = "sacroiliac_torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->sacroiliac_torsion; + return GF_OK; + case 2: + info->name = "sacroiliac_roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->sacroiliac_roll; + return GF_OK; + case 3: + info->name = "l_hip_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_hip_flexion; + return GF_OK; + case 4: + info->name = "r_hip_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_hip_flexion; + return GF_OK; + case 5: + info->name = "l_hip_abduct"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_hip_abduct; + return GF_OK; + case 6: + info->name = "r_hip_abduct"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_hip_abduct; + return GF_OK; + case 7: + info->name = "l_hip_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_hip_twisting; + return GF_OK; + case 8: + info->name = "r_hip_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_hip_twisting; + return GF_OK; + case 9: + info->name = "l_knee_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_knee_flexion; + return GF_OK; + case 10: + info->name = "r_knee_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_knee_flexion; + return GF_OK; + case 11: + info->name = "l_knee_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_knee_twisting; + return GF_OK; + case 12: + info->name = "r_knee_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_knee_twisting; + return GF_OK; + case 13: + info->name = "l_ankle_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_ankle_flexion; + return GF_OK; + case 14: + info->name = "r_ankle_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_ankle_flexion; + return GF_OK; + case 15: + info->name = "l_ankle_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_ankle_twisting; + return GF_OK; + case 16: + info->name = "r_ankle_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_ankle_twisting; + return GF_OK; + case 17: + info->name = "l_subtalar_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_subtalar_flexion; + return GF_OK; + case 18: + info->name = "r_subtalar_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_subtalar_flexion; + return GF_OK; + case 19: + info->name = "l_midtarsal_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_midtarsal_flexion; + return GF_OK; + case 20: + info->name = "r_midtarsal_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_midtarsal_flexion; + return GF_OK; + case 21: + info->name = "l_metatarsal_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_metatarsal_flexion; + return GF_OK; + case 22: + info->name = "r_metatarsal_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_metatarsal_flexion; + return GF_OK; + case 23: + info->name = "l_sternoclavicular_abduct"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_sternoclavicular_abduct; + return GF_OK; + case 24: + info->name = "r_sternoclavicular_abduct"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_sternoclavicular_abduct; + return GF_OK; + case 25: + info->name = "l_sternoclavicular_rotate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_sternoclavicular_rotate; + return GF_OK; + case 26: + info->name = "r_sternoclavicular_rotate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_sternoclavicular_rotate; + return GF_OK; + case 27: + info->name = "l_acromioclavicular_abduct"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_acromioclavicular_abduct; + return GF_OK; + case 28: + info->name = "r_acromioclavicular_abduct"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_acromioclavicular_abduct; + return GF_OK; + case 29: + info->name = "l_acromioclavicular_rotate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_acromioclavicular_rotate; + return GF_OK; + case 30: + info->name = "r_acromioclavicular_rotate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_acromioclavicular_rotate; + return GF_OK; + case 31: + info->name = "l_shoulder_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_shoulder_flexion; + return GF_OK; + case 32: + info->name = "r_shoulder_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_shoulder_flexion; + return GF_OK; + case 33: + info->name = "l_shoulder_abduct"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_shoulder_abduct; + return GF_OK; + case 34: + info->name = "r_shoulder_abduct"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_shoulder_abduct; + return GF_OK; + case 35: + info->name = "l_shoulder_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_shoulder_twisting; + return GF_OK; + case 36: + info->name = "r_shoulder_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_shoulder_twisting; + return GF_OK; + case 37: + info->name = "l_elbow_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_elbow_flexion; + return GF_OK; + case 38: + info->name = "r_elbow_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_elbow_flexion; + return GF_OK; + case 39: + info->name = "l_elbow_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_elbow_twisting; + return GF_OK; + case 40: + info->name = "r_elbow_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_elbow_twisting; + return GF_OK; + case 41: + info->name = "l_wrist_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_wrist_flexion; + return GF_OK; + case 42: + info->name = "r_wrist_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_wrist_flexion; + return GF_OK; + case 43: + info->name = "l_wrist_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_wrist_pivot; + return GF_OK; + case 44: + info->name = "r_wrist_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_wrist_pivot; + return GF_OK; + case 45: + info->name = "l_wrist_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_wrist_twisting; + return GF_OK; + case 46: + info->name = "r_wrist_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_wrist_twisting; + return GF_OK; + case 47: + info->name = "skullbase_roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->skullbase_roll; + return GF_OK; + case 48: + info->name = "skullbase_torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->skullbase_torsion; + return GF_OK; + case 49: + info->name = "skullbase_tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->skullbase_tilt; + return GF_OK; + case 50: + info->name = "vc1roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc1roll; + return GF_OK; + case 51: + info->name = "vc1torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc1torsion; + return GF_OK; + case 52: + info->name = "vc1tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc1tilt; + return GF_OK; + case 53: + info->name = "vc2roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc2roll; + return GF_OK; + case 54: + info->name = "vc2torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc2torsion; + return GF_OK; + case 55: + info->name = "vc2tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc2tilt; + return GF_OK; + case 56: + info->name = "vc3roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc3roll; + return GF_OK; + case 57: + info->name = "vc3torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc3torsion; + return GF_OK; + case 58: + info->name = "vc3tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc3tilt; + return GF_OK; + case 59: + info->name = "vc4roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc4roll; + return GF_OK; + case 60: + info->name = "vc4torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc4torsion; + return GF_OK; + case 61: + info->name = "vc4tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc4tilt; + return GF_OK; + case 62: + info->name = "vc5roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc5roll; + return GF_OK; + case 63: + info->name = "vc5torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc5torsion; + return GF_OK; + case 64: + info->name = "vc5tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc5tilt; + return GF_OK; + case 65: + info->name = "vc6roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc6roll; + return GF_OK; + case 66: + info->name = "vc6torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc6torsion; + return GF_OK; + case 67: + info->name = "vc6tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc6tilt; + return GF_OK; + case 68: + info->name = "vc7roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc7roll; + return GF_OK; + case 69: + info->name = "vc7torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc7torsion; + return GF_OK; + case 70: + info->name = "vc7tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vc7tilt; + return GF_OK; + case 71: + info->name = "vt1roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt1roll; + return GF_OK; + case 72: + info->name = "vt1torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt1torsion; + return GF_OK; + case 73: + info->name = "vt1tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt1tilt; + return GF_OK; + case 74: + info->name = "vt2roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt2roll; + return GF_OK; + case 75: + info->name = "vt2torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt2torsion; + return GF_OK; + case 76: + info->name = "vt2tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt2tilt; + return GF_OK; + case 77: + info->name = "vt3roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt3roll; + return GF_OK; + case 78: + info->name = "vt3torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt3torsion; + return GF_OK; + case 79: + info->name = "vt3tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt3tilt; + return GF_OK; + case 80: + info->name = "vt4roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt4roll; + return GF_OK; + case 81: + info->name = "vt4torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt4torsion; + return GF_OK; + case 82: + info->name = "vt4tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt4tilt; + return GF_OK; + case 83: + info->name = "vt5roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt5roll; + return GF_OK; + case 84: + info->name = "vt5torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt5torsion; + return GF_OK; + case 85: + info->name = "vt5tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt5tilt; + return GF_OK; + case 86: + info->name = "vt6roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt6roll; + return GF_OK; + case 87: + info->name = "vt6torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt6torsion; + return GF_OK; + case 88: + info->name = "vt6tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt6tilt; + return GF_OK; + case 89: + info->name = "vt7roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt7roll; + return GF_OK; + case 90: + info->name = "vt7torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt7torsion; + return GF_OK; + case 91: + info->name = "vt7tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt7tilt; + return GF_OK; + case 92: + info->name = "vt8roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt8roll; + return GF_OK; + case 93: + info->name = "vt8torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt8torsion; + return GF_OK; + case 94: + info->name = "vt8tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt8tilt; + return GF_OK; + case 95: + info->name = "vt9roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt9roll; + return GF_OK; + case 96: + info->name = "vt9torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt9torsion; + return GF_OK; + case 97: + info->name = "vt9tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt9tilt; + return GF_OK; + case 98: + info->name = "vt10roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt10roll; + return GF_OK; + case 99: + info->name = "vt10torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt10torsion; + return GF_OK; + case 100: + info->name = "vt10tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt10tilt; + return GF_OK; + case 101: + info->name = "vt11roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt11roll; + return GF_OK; + case 102: + info->name = "vt11torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt11torsion; + return GF_OK; + case 103: + info->name = "vt11tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt11tilt; + return GF_OK; + case 104: + info->name = "vt12roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt12roll; + return GF_OK; + case 105: + info->name = "vt12torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt12torsion; + return GF_OK; + case 106: + info->name = "vt12tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vt12tilt; + return GF_OK; + case 107: + info->name = "vl1roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl1roll; + return GF_OK; + case 108: + info->name = "vl1torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl1torsion; + return GF_OK; + case 109: + info->name = "vl1tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl1tilt; + return GF_OK; + case 110: + info->name = "vl2roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl2roll; + return GF_OK; + case 111: + info->name = "vl2torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl2torsion; + return GF_OK; + case 112: + info->name = "vl2tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl2tilt; + return GF_OK; + case 113: + info->name = "vl3roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl3roll; + return GF_OK; + case 114: + info->name = "vl3torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl3torsion; + return GF_OK; + case 115: + info->name = "vl3tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl3tilt; + return GF_OK; + case 116: + info->name = "vl4roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl4roll; + return GF_OK; + case 117: + info->name = "vl4torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl4torsion; + return GF_OK; + case 118: + info->name = "vl4tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl4tilt; + return GF_OK; + case 119: + info->name = "vl5roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl5roll; + return GF_OK; + case 120: + info->name = "vl5torsion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl5torsion; + return GF_OK; + case 121: + info->name = "vl5tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->vl5tilt; + return GF_OK; + case 122: + info->name = "l_pinky0_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_pinky0_flexion; + return GF_OK; + case 123: + info->name = "r_pinky0_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_pinky0_flexion; + return GF_OK; + case 124: + info->name = "l_pinky1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_pinky1_flexion; + return GF_OK; + case 125: + info->name = "r_pinky1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_pinky1_flexion; + return GF_OK; + case 126: + info->name = "l_pinky1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_pinky1_pivot; + return GF_OK; + case 127: + info->name = "r_pinky1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_pinky1_pivot; + return GF_OK; + case 128: + info->name = "l_pinky1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_pinky1_twisting; + return GF_OK; + case 129: + info->name = "r_pinky1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_pinky1_twisting; + return GF_OK; + case 130: + info->name = "l_pinky2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_pinky2_flexion; + return GF_OK; + case 131: + info->name = "r_pinky2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_pinky2_flexion; + return GF_OK; + case 132: + info->name = "l_pinky3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_pinky3_flexion; + return GF_OK; + case 133: + info->name = "r_pinky3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_pinky3_flexion; + return GF_OK; + case 134: + info->name = "l_ring0_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_ring0_flexion; + return GF_OK; + case 135: + info->name = "r_ring0_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_ring0_flexion; + return GF_OK; + case 136: + info->name = "l_ring1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_ring1_flexion; + return GF_OK; + case 137: + info->name = "r_ring1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_ring1_flexion; + return GF_OK; + case 138: + info->name = "l_ring1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_ring1_pivot; + return GF_OK; + case 139: + info->name = "r_ring1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_ring1_pivot; + return GF_OK; + case 140: + info->name = "l_ring1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_ring1_twisting; + return GF_OK; + case 141: + info->name = "r_ring1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_ring1_twisting; + return GF_OK; + case 142: + info->name = "l_ring2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_ring2_flexion; + return GF_OK; + case 143: + info->name = "r_ring2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_ring2_flexion; + return GF_OK; + case 144: + info->name = "l_ring3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_ring3_flexion; + return GF_OK; + case 145: + info->name = "r_ring3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_ring3_flexion; + return GF_OK; + case 146: + info->name = "l_middle0_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_middle0_flexion; + return GF_OK; + case 147: + info->name = "r_middle0_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_middle0_flexion; + return GF_OK; + case 148: + info->name = "l_middle1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_middle1_flexion; + return GF_OK; + case 149: + info->name = "r_middle1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_middle1_flexion; + return GF_OK; + case 150: + info->name = "l_middle1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_middle1_pivot; + return GF_OK; + case 151: + info->name = "r_middle1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_middle1_pivot; + return GF_OK; + case 152: + info->name = "l_middle1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_middle1_twisting; + return GF_OK; + case 153: + info->name = "r_middle1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_middle1_twisting; + return GF_OK; + case 154: + info->name = "l_middle2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_middle2_flexion; + return GF_OK; + case 155: + info->name = "r_middle2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_middle2_flexion; + return GF_OK; + case 156: + info->name = "l_middle3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_middle3_flexion; + return GF_OK; + case 157: + info->name = "r_middle3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_middle3_flexion; + return GF_OK; + case 158: + info->name = "l_index0_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_index0_flexion; + return GF_OK; + case 159: + info->name = "r_index0_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_index0_flexion; + return GF_OK; + case 160: + info->name = "l_index1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_index1_flexion; + return GF_OK; + case 161: + info->name = "r_index1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_index1_flexion; + return GF_OK; + case 162: + info->name = "l_index1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_index1_pivot; + return GF_OK; + case 163: + info->name = "r_index1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_index1_pivot; + return GF_OK; + case 164: + info->name = "l_index1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_index1_twisting; + return GF_OK; + case 165: + info->name = "r_index1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_index1_twisting; + return GF_OK; + case 166: + info->name = "l_index2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_index2_flexion; + return GF_OK; + case 167: + info->name = "r_index2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_index2_flexion; + return GF_OK; + case 168: + info->name = "l_index3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_index3_flexion; + return GF_OK; + case 169: + info->name = "r_index3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_index3_flexion; + return GF_OK; + case 170: + info->name = "l_thumb1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_thumb1_flexion; + return GF_OK; + case 171: + info->name = "r_thumb1_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_thumb1_flexion; + return GF_OK; + case 172: + info->name = "l_thumb1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_thumb1_pivot; + return GF_OK; + case 173: + info->name = "r_thumb1_pivot"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_thumb1_pivot; + return GF_OK; + case 174: + info->name = "l_thumb1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_thumb1_twisting; + return GF_OK; + case 175: + info->name = "r_thumb1_twisting"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_thumb1_twisting; + return GF_OK; + case 176: + info->name = "l_thumb2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_thumb2_flexion; + return GF_OK; + case 177: + info->name = "r_thumb2_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_thumb2_flexion; + return GF_OK; + case 178: + info->name = "l_thumb3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->l_thumb3_flexion; + return GF_OK; + case 179: + info->name = "r_thumb3_flexion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->r_thumb3_flexion; + return GF_OK; + case 180: + info->name = "HumanoidRoot_tr_vertical"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->HumanoidRoot_tr_vertical; + return GF_OK; + case 181: + info->name = "HumanoidRoot_tr_lateral"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->HumanoidRoot_tr_lateral; + return GF_OK; + case 182: + info->name = "HumanoidRoot_tr_frontal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->HumanoidRoot_tr_frontal; + return GF_OK; + case 183: + info->name = "HumanoidRoot_rt_body_turn"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->HumanoidRoot_rt_body_turn; + return GF_OK; + case 184: + info->name = "HumanoidRoot_rt_body_roll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->HumanoidRoot_rt_body_roll; + return GF_OK; + case 185: + info->name = "HumanoidRoot_rt_body_tilt"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->HumanoidRoot_rt_body_tilt; + return GF_OK; + case 186: + info->name = "extensionBap187"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap187; + return GF_OK; + case 187: + info->name = "extensionBap188"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap188; + return GF_OK; + case 188: + info->name = "extensionBap189"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap189; + return GF_OK; + case 189: + info->name = "extensionBap190"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap190; + return GF_OK; + case 190: + info->name = "extensionBap191"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap191; + return GF_OK; + case 191: + info->name = "extensionBap192"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap192; + return GF_OK; + case 192: + info->name = "extensionBap193"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap193; + return GF_OK; + case 193: + info->name = "extensionBap194"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap194; + return GF_OK; + case 194: + info->name = "extensionBap195"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap195; + return GF_OK; + case 195: + info->name = "extensionBap196"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap196; + return GF_OK; + case 196: + info->name = "extensionBap197"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap197; + return GF_OK; + case 197: + info->name = "extensionBap198"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap198; + return GF_OK; + case 198: + info->name = "extensionBap199"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap199; + return GF_OK; + case 199: + info->name = "extensionBap200"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap200; + return GF_OK; + case 200: + info->name = "extensionBap201"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap201; + return GF_OK; + case 201: + info->name = "extensionBap202"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap202; + return GF_OK; + case 202: + info->name = "extensionBap203"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap203; + return GF_OK; + case 203: + info->name = "extensionBap204"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap204; + return GF_OK; + case 204: + info->name = "extensionBap205"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap205; + return GF_OK; + case 205: + info->name = "extensionBap206"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap206; + return GF_OK; + case 206: + info->name = "extensionBap207"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap207; + return GF_OK; + case 207: + info->name = "extensionBap208"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap208; + return GF_OK; + case 208: + info->name = "extensionBap209"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap209; + return GF_OK; + case 209: + info->name = "extensionBap210"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap210; + return GF_OK; + case 210: + info->name = "extensionBap211"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap211; + return GF_OK; + case 211: + info->name = "extensionBap212"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap212; + return GF_OK; + case 212: + info->name = "extensionBap213"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap213; + return GF_OK; + case 213: + info->name = "extensionBap214"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap214; + return GF_OK; + case 214: + info->name = "extensionBap215"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap215; + return GF_OK; + case 215: + info->name = "extensionBap216"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap216; + return GF_OK; + case 216: + info->name = "extensionBap217"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap217; + return GF_OK; + case 217: + info->name = "extensionBap218"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap218; + return GF_OK; + case 218: + info->name = "extensionBap219"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap219; + return GF_OK; + case 219: + info->name = "extensionBap220"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap220; + return GF_OK; + case 220: + info->name = "extensionBap221"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap221; + return GF_OK; + case 221: + info->name = "extensionBap222"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap222; + return GF_OK; + case 222: + info->name = "extensionBap223"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap223; + return GF_OK; + case 223: + info->name = "extensionBap224"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap224; + return GF_OK; + case 224: + info->name = "extensionBap225"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap225; + return GF_OK; + case 225: + info->name = "extensionBap226"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap226; + return GF_OK; + case 226: + info->name = "extensionBap227"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap227; + return GF_OK; + case 227: + info->name = "extensionBap228"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap228; + return GF_OK; + case 228: + info->name = "extensionBap229"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap229; + return GF_OK; + case 229: + info->name = "extensionBap230"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap230; + return GF_OK; + case 230: + info->name = "extensionBap231"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap231; + return GF_OK; + case 231: + info->name = "extensionBap232"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap232; + return GF_OK; + case 232: + info->name = "extensionBap233"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap233; + return GF_OK; + case 233: + info->name = "extensionBap234"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap234; + return GF_OK; + case 234: + info->name = "extensionBap235"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap235; + return GF_OK; + case 235: + info->name = "extensionBap236"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap236; + return GF_OK; + case 236: + info->name = "extensionBap237"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap237; + return GF_OK; + case 237: + info->name = "extensionBap238"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap238; + return GF_OK; + case 238: + info->name = "extensionBap239"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap239; + return GF_OK; + case 239: + info->name = "extensionBap240"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap240; + return GF_OK; + case 240: + info->name = "extensionBap241"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap241; + return GF_OK; + case 241: + info->name = "extensionBap242"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap242; + return GF_OK; + case 242: + info->name = "extensionBap243"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap243; + return GF_OK; + case 243: + info->name = "extensionBap244"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap244; + return GF_OK; + case 244: + info->name = "extensionBap245"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap245; + return GF_OK; + case 245: + info->name = "extensionBap246"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap246; + return GF_OK; + case 246: + info->name = "extensionBap247"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap247; + return GF_OK; + case 247: + info->name = "extensionBap248"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap248; + return GF_OK; + case 248: + info->name = "extensionBap249"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap249; + return GF_OK; + case 249: + info->name = "extensionBap250"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap250; + return GF_OK; + case 250: + info->name = "extensionBap251"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap251; + return GF_OK; + case 251: + info->name = "extensionBap252"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap252; + return GF_OK; + case 252: + info->name = "extensionBap253"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap253; + return GF_OK; + case 253: + info->name = "extensionBap254"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap254; + return GF_OK; + case 254: + info->name = "extensionBap255"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap255; + return GF_OK; + case 255: + info->name = "extensionBap256"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap256; + return GF_OK; + case 256: + info->name = "extensionBap257"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap257; + return GF_OK; + case 257: + info->name = "extensionBap258"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap258; + return GF_OK; + case 258: + info->name = "extensionBap259"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap259; + return GF_OK; + case 259: + info->name = "extensionBap260"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap260; + return GF_OK; + case 260: + info->name = "extensionBap261"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap261; + return GF_OK; + case 261: + info->name = "extensionBap262"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap262; + return GF_OK; + case 262: + info->name = "extensionBap263"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap263; + return GF_OK; + case 263: + info->name = "extensionBap264"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap264; + return GF_OK; + case 264: + info->name = "extensionBap265"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap265; + return GF_OK; + case 265: + info->name = "extensionBap266"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap266; + return GF_OK; + case 266: + info->name = "extensionBap267"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap267; + return GF_OK; + case 267: + info->name = "extensionBap268"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap268; + return GF_OK; + case 268: + info->name = "extensionBap269"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap269; + return GF_OK; + case 269: + info->name = "extensionBap270"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap270; + return GF_OK; + case 270: + info->name = "extensionBap271"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap271; + return GF_OK; + case 271: + info->name = "extensionBap272"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap272; + return GF_OK; + case 272: + info->name = "extensionBap273"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap273; + return GF_OK; + case 273: + info->name = "extensionBap274"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap274; + return GF_OK; + case 274: + info->name = "extensionBap275"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap275; + return GF_OK; + case 275: + info->name = "extensionBap276"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap276; + return GF_OK; + case 276: + info->name = "extensionBap277"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap277; + return GF_OK; + case 277: + info->name = "extensionBap278"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap278; + return GF_OK; + case 278: + info->name = "extensionBap279"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap279; + return GF_OK; + case 279: + info->name = "extensionBap280"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap280; + return GF_OK; + case 280: + info->name = "extensionBap281"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap281; + return GF_OK; + case 281: + info->name = "extensionBap282"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap282; + return GF_OK; + case 282: + info->name = "extensionBap283"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap283; + return GF_OK; + case 283: + info->name = "extensionBap284"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap284; + return GF_OK; + case 284: + info->name = "extensionBap285"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap285; + return GF_OK; + case 285: + info->name = "extensionBap286"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap286; + return GF_OK; + case 286: + info->name = "extensionBap287"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap287; + return GF_OK; + case 287: + info->name = "extensionBap288"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap288; + return GF_OK; + case 288: + info->name = "extensionBap289"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap289; + return GF_OK; + case 289: + info->name = "extensionBap290"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap290; + return GF_OK; + case 290: + info->name = "extensionBap291"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap291; + return GF_OK; + case 291: + info->name = "extensionBap292"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap292; + return GF_OK; + case 292: + info->name = "extensionBap293"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap293; + return GF_OK; + case 293: + info->name = "extensionBap294"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap294; + return GF_OK; + case 294: + info->name = "extensionBap295"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap295; + return GF_OK; + case 295: + info->name = "extensionBap296"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BAP *) node)->extensionBap296; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 BAP_get_field_index_by_name(char *name) +{ + if (!strcmp("sacroiliac_tilt", name)) return 0; + if (!strcmp("sacroiliac_torsion", name)) return 1; + if (!strcmp("sacroiliac_roll", name)) return 2; + if (!strcmp("l_hip_flexion", name)) return 3; + if (!strcmp("r_hip_flexion", name)) return 4; + if (!strcmp("l_hip_abduct", name)) return 5; + if (!strcmp("r_hip_abduct", name)) return 6; + if (!strcmp("l_hip_twisting", name)) return 7; + if (!strcmp("r_hip_twisting", name)) return 8; + if (!strcmp("l_knee_flexion", name)) return 9; + if (!strcmp("r_knee_flexion", name)) return 10; + if (!strcmp("l_knee_twisting", name)) return 11; + if (!strcmp("r_knee_twisting", name)) return 12; + if (!strcmp("l_ankle_flexion", name)) return 13; + if (!strcmp("r_ankle_flexion", name)) return 14; + if (!strcmp("l_ankle_twisting", name)) return 15; + if (!strcmp("r_ankle_twisting", name)) return 16; + if (!strcmp("l_subtalar_flexion", name)) return 17; + if (!strcmp("r_subtalar_flexion", name)) return 18; + if (!strcmp("l_midtarsal_flexion", name)) return 19; + if (!strcmp("r_midtarsal_flexion", name)) return 20; + if (!strcmp("l_metatarsal_flexion", name)) return 21; + if (!strcmp("r_metatarsal_flexion", name)) return 22; + if (!strcmp("l_sternoclavicular_abduct", name)) return 23; + if (!strcmp("r_sternoclavicular_abduct", name)) return 24; + if (!strcmp("l_sternoclavicular_rotate", name)) return 25; + if (!strcmp("r_sternoclavicular_rotate", name)) return 26; + if (!strcmp("l_acromioclavicular_abduct", name)) return 27; + if (!strcmp("r_acromioclavicular_abduct", name)) return 28; + if (!strcmp("l_acromioclavicular_rotate", name)) return 29; + if (!strcmp("r_acromioclavicular_rotate", name)) return 30; + if (!strcmp("l_shoulder_flexion", name)) return 31; + if (!strcmp("r_shoulder_flexion", name)) return 32; + if (!strcmp("l_shoulder_abduct", name)) return 33; + if (!strcmp("r_shoulder_abduct", name)) return 34; + if (!strcmp("l_shoulder_twisting", name)) return 35; + if (!strcmp("r_shoulder_twisting", name)) return 36; + if (!strcmp("l_elbow_flexion", name)) return 37; + if (!strcmp("r_elbow_flexion", name)) return 38; + if (!strcmp("l_elbow_twisting", name)) return 39; + if (!strcmp("r_elbow_twisting", name)) return 40; + if (!strcmp("l_wrist_flexion", name)) return 41; + if (!strcmp("r_wrist_flexion", name)) return 42; + if (!strcmp("l_wrist_pivot", name)) return 43; + if (!strcmp("r_wrist_pivot", name)) return 44; + if (!strcmp("l_wrist_twisting", name)) return 45; + if (!strcmp("r_wrist_twisting", name)) return 46; + if (!strcmp("skullbase_roll", name)) return 47; + if (!strcmp("skullbase_torsion", name)) return 48; + if (!strcmp("skullbase_tilt", name)) return 49; + if (!strcmp("vc1roll", name)) return 50; + if (!strcmp("vc1torsion", name)) return 51; + if (!strcmp("vc1tilt", name)) return 52; + if (!strcmp("vc2roll", name)) return 53; + if (!strcmp("vc2torsion", name)) return 54; + if (!strcmp("vc2tilt", name)) return 55; + if (!strcmp("vc3roll", name)) return 56; + if (!strcmp("vc3torsion", name)) return 57; + if (!strcmp("vc3tilt", name)) return 58; + if (!strcmp("vc4roll", name)) return 59; + if (!strcmp("vc4torsion", name)) return 60; + if (!strcmp("vc4tilt", name)) return 61; + if (!strcmp("vc5roll", name)) return 62; + if (!strcmp("vc5torsion", name)) return 63; + if (!strcmp("vc5tilt", name)) return 64; + if (!strcmp("vc6roll", name)) return 65; + if (!strcmp("vc6torsion", name)) return 66; + if (!strcmp("vc6tilt", name)) return 67; + if (!strcmp("vc7roll", name)) return 68; + if (!strcmp("vc7torsion", name)) return 69; + if (!strcmp("vc7tilt", name)) return 70; + if (!strcmp("vt1roll", name)) return 71; + if (!strcmp("vt1torsion", name)) return 72; + if (!strcmp("vt1tilt", name)) return 73; + if (!strcmp("vt2roll", name)) return 74; + if (!strcmp("vt2torsion", name)) return 75; + if (!strcmp("vt2tilt", name)) return 76; + if (!strcmp("vt3roll", name)) return 77; + if (!strcmp("vt3torsion", name)) return 78; + if (!strcmp("vt3tilt", name)) return 79; + if (!strcmp("vt4roll", name)) return 80; + if (!strcmp("vt4torsion", name)) return 81; + if (!strcmp("vt4tilt", name)) return 82; + if (!strcmp("vt5roll", name)) return 83; + if (!strcmp("vt5torsion", name)) return 84; + if (!strcmp("vt5tilt", name)) return 85; + if (!strcmp("vt6roll", name)) return 86; + if (!strcmp("vt6torsion", name)) return 87; + if (!strcmp("vt6tilt", name)) return 88; + if (!strcmp("vt7roll", name)) return 89; + if (!strcmp("vt7torsion", name)) return 90; + if (!strcmp("vt7tilt", name)) return 91; + if (!strcmp("vt8roll", name)) return 92; + if (!strcmp("vt8torsion", name)) return 93; + if (!strcmp("vt8tilt", name)) return 94; + if (!strcmp("vt9roll", name)) return 95; + if (!strcmp("vt9torsion", name)) return 96; + if (!strcmp("vt9tilt", name)) return 97; + if (!strcmp("vt10roll", name)) return 98; + if (!strcmp("vt10torsion", name)) return 99; + if (!strcmp("vt10tilt", name)) return 100; + if (!strcmp("vt11roll", name)) return 101; + if (!strcmp("vt11torsion", name)) return 102; + if (!strcmp("vt11tilt", name)) return 103; + if (!strcmp("vt12roll", name)) return 104; + if (!strcmp("vt12torsion", name)) return 105; + if (!strcmp("vt12tilt", name)) return 106; + if (!strcmp("vl1roll", name)) return 107; + if (!strcmp("vl1torsion", name)) return 108; + if (!strcmp("vl1tilt", name)) return 109; + if (!strcmp("vl2roll", name)) return 110; + if (!strcmp("vl2torsion", name)) return 111; + if (!strcmp("vl2tilt", name)) return 112; + if (!strcmp("vl3roll", name)) return 113; + if (!strcmp("vl3torsion", name)) return 114; + if (!strcmp("vl3tilt", name)) return 115; + if (!strcmp("vl4roll", name)) return 116; + if (!strcmp("vl4torsion", name)) return 117; + if (!strcmp("vl4tilt", name)) return 118; + if (!strcmp("vl5roll", name)) return 119; + if (!strcmp("vl5torsion", name)) return 120; + if (!strcmp("vl5tilt", name)) return 121; + if (!strcmp("l_pinky0_flexion", name)) return 122; + if (!strcmp("r_pinky0_flexion", name)) return 123; + if (!strcmp("l_pinky1_flexion", name)) return 124; + if (!strcmp("r_pinky1_flexion", name)) return 125; + if (!strcmp("l_pinky1_pivot", name)) return 126; + if (!strcmp("r_pinky1_pivot", name)) return 127; + if (!strcmp("l_pinky1_twisting", name)) return 128; + if (!strcmp("r_pinky1_twisting", name)) return 129; + if (!strcmp("l_pinky2_flexion", name)) return 130; + if (!strcmp("r_pinky2_flexion", name)) return 131; + if (!strcmp("l_pinky3_flexion", name)) return 132; + if (!strcmp("r_pinky3_flexion", name)) return 133; + if (!strcmp("l_ring0_flexion", name)) return 134; + if (!strcmp("r_ring0_flexion", name)) return 135; + if (!strcmp("l_ring1_flexion", name)) return 136; + if (!strcmp("r_ring1_flexion", name)) return 137; + if (!strcmp("l_ring1_pivot", name)) return 138; + if (!strcmp("r_ring1_pivot", name)) return 139; + if (!strcmp("l_ring1_twisting", name)) return 140; + if (!strcmp("r_ring1_twisting", name)) return 141; + if (!strcmp("l_ring2_flexion", name)) return 142; + if (!strcmp("r_ring2_flexion", name)) return 143; + if (!strcmp("l_ring3_flexion", name)) return 144; + if (!strcmp("r_ring3_flexion", name)) return 145; + if (!strcmp("l_middle0_flexion", name)) return 146; + if (!strcmp("r_middle0_flexion", name)) return 147; + if (!strcmp("l_middle1_flexion", name)) return 148; + if (!strcmp("r_middle1_flexion", name)) return 149; + if (!strcmp("l_middle1_pivot", name)) return 150; + if (!strcmp("r_middle1_pivot", name)) return 151; + if (!strcmp("l_middle1_twisting", name)) return 152; + if (!strcmp("r_middle1_twisting", name)) return 153; + if (!strcmp("l_middle2_flexion", name)) return 154; + if (!strcmp("r_middle2_flexion", name)) return 155; + if (!strcmp("l_middle3_flexion", name)) return 156; + if (!strcmp("r_middle3_flexion", name)) return 157; + if (!strcmp("l_index0_flexion", name)) return 158; + if (!strcmp("r_index0_flexion", name)) return 159; + if (!strcmp("l_index1_flexion", name)) return 160; + if (!strcmp("r_index1_flexion", name)) return 161; + if (!strcmp("l_index1_pivot", name)) return 162; + if (!strcmp("r_index1_pivot", name)) return 163; + if (!strcmp("l_index1_twisting", name)) return 164; + if (!strcmp("r_index1_twisting", name)) return 165; + if (!strcmp("l_index2_flexion", name)) return 166; + if (!strcmp("r_index2_flexion", name)) return 167; + if (!strcmp("l_index3_flexion", name)) return 168; + if (!strcmp("r_index3_flexion", name)) return 169; + if (!strcmp("l_thumb1_flexion", name)) return 170; + if (!strcmp("r_thumb1_flexion", name)) return 171; + if (!strcmp("l_thumb1_pivot", name)) return 172; + if (!strcmp("r_thumb1_pivot", name)) return 173; + if (!strcmp("l_thumb1_twisting", name)) return 174; + if (!strcmp("r_thumb1_twisting", name)) return 175; + if (!strcmp("l_thumb2_flexion", name)) return 176; + if (!strcmp("r_thumb2_flexion", name)) return 177; + if (!strcmp("l_thumb3_flexion", name)) return 178; + if (!strcmp("r_thumb3_flexion", name)) return 179; + if (!strcmp("HumanoidRoot_tr_vertical", name)) return 180; + if (!strcmp("HumanoidRoot_tr_lateral", name)) return 181; + if (!strcmp("HumanoidRoot_tr_frontal", name)) return 182; + if (!strcmp("HumanoidRoot_rt_body_turn", name)) return 183; + if (!strcmp("HumanoidRoot_rt_body_roll", name)) return 184; + if (!strcmp("HumanoidRoot_rt_body_tilt", name)) return 185; + if (!strcmp("extensionBap187", name)) return 186; + if (!strcmp("extensionBap188", name)) return 187; + if (!strcmp("extensionBap189", name)) return 188; + if (!strcmp("extensionBap190", name)) return 189; + if (!strcmp("extensionBap191", name)) return 190; + if (!strcmp("extensionBap192", name)) return 191; + if (!strcmp("extensionBap193", name)) return 192; + if (!strcmp("extensionBap194", name)) return 193; + if (!strcmp("extensionBap195", name)) return 194; + if (!strcmp("extensionBap196", name)) return 195; + if (!strcmp("extensionBap197", name)) return 196; + if (!strcmp("extensionBap198", name)) return 197; + if (!strcmp("extensionBap199", name)) return 198; + if (!strcmp("extensionBap200", name)) return 199; + if (!strcmp("extensionBap201", name)) return 200; + if (!strcmp("extensionBap202", name)) return 201; + if (!strcmp("extensionBap203", name)) return 202; + if (!strcmp("extensionBap204", name)) return 203; + if (!strcmp("extensionBap205", name)) return 204; + if (!strcmp("extensionBap206", name)) return 205; + if (!strcmp("extensionBap207", name)) return 206; + if (!strcmp("extensionBap208", name)) return 207; + if (!strcmp("extensionBap209", name)) return 208; + if (!strcmp("extensionBap210", name)) return 209; + if (!strcmp("extensionBap211", name)) return 210; + if (!strcmp("extensionBap212", name)) return 211; + if (!strcmp("extensionBap213", name)) return 212; + if (!strcmp("extensionBap214", name)) return 213; + if (!strcmp("extensionBap215", name)) return 214; + if (!strcmp("extensionBap216", name)) return 215; + if (!strcmp("extensionBap217", name)) return 216; + if (!strcmp("extensionBap218", name)) return 217; + if (!strcmp("extensionBap219", name)) return 218; + if (!strcmp("extensionBap220", name)) return 219; + if (!strcmp("extensionBap221", name)) return 220; + if (!strcmp("extensionBap222", name)) return 221; + if (!strcmp("extensionBap223", name)) return 222; + if (!strcmp("extensionBap224", name)) return 223; + if (!strcmp("extensionBap225", name)) return 224; + if (!strcmp("extensionBap226", name)) return 225; + if (!strcmp("extensionBap227", name)) return 226; + if (!strcmp("extensionBap228", name)) return 227; + if (!strcmp("extensionBap229", name)) return 228; + if (!strcmp("extensionBap230", name)) return 229; + if (!strcmp("extensionBap231", name)) return 230; + if (!strcmp("extensionBap232", name)) return 231; + if (!strcmp("extensionBap233", name)) return 232; + if (!strcmp("extensionBap234", name)) return 233; + if (!strcmp("extensionBap235", name)) return 234; + if (!strcmp("extensionBap236", name)) return 235; + if (!strcmp("extensionBap237", name)) return 236; + if (!strcmp("extensionBap238", name)) return 237; + if (!strcmp("extensionBap239", name)) return 238; + if (!strcmp("extensionBap240", name)) return 239; + if (!strcmp("extensionBap241", name)) return 240; + if (!strcmp("extensionBap242", name)) return 241; + if (!strcmp("extensionBap243", name)) return 242; + if (!strcmp("extensionBap244", name)) return 243; + if (!strcmp("extensionBap245", name)) return 244; + if (!strcmp("extensionBap246", name)) return 245; + if (!strcmp("extensionBap247", name)) return 246; + if (!strcmp("extensionBap248", name)) return 247; + if (!strcmp("extensionBap249", name)) return 248; + if (!strcmp("extensionBap250", name)) return 249; + if (!strcmp("extensionBap251", name)) return 250; + if (!strcmp("extensionBap252", name)) return 251; + if (!strcmp("extensionBap253", name)) return 252; + if (!strcmp("extensionBap254", name)) return 253; + if (!strcmp("extensionBap255", name)) return 254; + if (!strcmp("extensionBap256", name)) return 255; + if (!strcmp("extensionBap257", name)) return 256; + if (!strcmp("extensionBap258", name)) return 257; + if (!strcmp("extensionBap259", name)) return 258; + if (!strcmp("extensionBap260", name)) return 259; + if (!strcmp("extensionBap261", name)) return 260; + if (!strcmp("extensionBap262", name)) return 261; + if (!strcmp("extensionBap263", name)) return 262; + if (!strcmp("extensionBap264", name)) return 263; + if (!strcmp("extensionBap265", name)) return 264; + if (!strcmp("extensionBap266", name)) return 265; + if (!strcmp("extensionBap267", name)) return 266; + if (!strcmp("extensionBap268", name)) return 267; + if (!strcmp("extensionBap269", name)) return 268; + if (!strcmp("extensionBap270", name)) return 269; + if (!strcmp("extensionBap271", name)) return 270; + if (!strcmp("extensionBap272", name)) return 271; + if (!strcmp("extensionBap273", name)) return 272; + if (!strcmp("extensionBap274", name)) return 273; + if (!strcmp("extensionBap275", name)) return 274; + if (!strcmp("extensionBap276", name)) return 275; + if (!strcmp("extensionBap277", name)) return 276; + if (!strcmp("extensionBap278", name)) return 277; + if (!strcmp("extensionBap279", name)) return 278; + if (!strcmp("extensionBap280", name)) return 279; + if (!strcmp("extensionBap281", name)) return 280; + if (!strcmp("extensionBap282", name)) return 281; + if (!strcmp("extensionBap283", name)) return 282; + if (!strcmp("extensionBap284", name)) return 283; + if (!strcmp("extensionBap285", name)) return 284; + if (!strcmp("extensionBap286", name)) return 285; + if (!strcmp("extensionBap287", name)) return 286; + if (!strcmp("extensionBap288", name)) return 287; + if (!strcmp("extensionBap289", name)) return 288; + if (!strcmp("extensionBap290", name)) return 289; + if (!strcmp("extensionBap291", name)) return 290; + if (!strcmp("extensionBap292", name)) return 291; + if (!strcmp("extensionBap293", name)) return 292; + if (!strcmp("extensionBap294", name)) return 293; + if (!strcmp("extensionBap295", name)) return 294; + if (!strcmp("extensionBap296", name)) return 295; + return -1; + } +static Bool BAP_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 2: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 3: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 5: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 8: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 9: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 10: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 11: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 12: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 13: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 14: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 15: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 16: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 17: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 18: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 19: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 20: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 21: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 22: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 23: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 24: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 25: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 26: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 27: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 28: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 29: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 30: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 31: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 32: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 33: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 34: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 35: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 36: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 37: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 38: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 39: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 40: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 41: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 42: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 43: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 44: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 45: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 46: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 47: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 48: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 49: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 50: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 51: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 52: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 53: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 54: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 55: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 56: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 57: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 58: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 59: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 60: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 61: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 62: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 63: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 64: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 65: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 66: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 67: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 68: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 69: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 70: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 71: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 72: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 73: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 74: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 75: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 76: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 77: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 78: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 79: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 80: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 81: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 82: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 83: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 84: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 85: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 86: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 87: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 88: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 89: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 90: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 91: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 92: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 93: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 94: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 95: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 96: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 97: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 98: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 99: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 100: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 101: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 102: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 103: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 104: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 105: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 106: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 107: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 108: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 109: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 110: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 111: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 112: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 113: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 114: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 115: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 116: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 117: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 118: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 119: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 120: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 121: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 122: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 123: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 124: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 125: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 126: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 127: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 128: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 129: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 130: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 131: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 132: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 133: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 134: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 135: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 136: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 137: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 138: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 139: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 140: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 141: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 142: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 143: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 144: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 145: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 146: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 147: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 148: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 149: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 150: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 151: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 152: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 153: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 154: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 155: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 156: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 157: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 158: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 159: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 160: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 161: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 162: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 163: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 164: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 165: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 166: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 167: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 168: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 169: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 170: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 171: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 172: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 173: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 174: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 175: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 176: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 177: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 178: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 179: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 180: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 181: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 182: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 183: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 184: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 185: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 186: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 187: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 188: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 189: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 190: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 191: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 192: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 193: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 194: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 195: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 196: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 197: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 198: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 199: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 200: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 201: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 202: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 203: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 204: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 205: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 206: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 207: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 208: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 209: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 210: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 211: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 212: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 213: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 214: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 215: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 216: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 217: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 218: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 219: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 220: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 221: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 222: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 223: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 224: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 225: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 226: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 227: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 228: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 229: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 230: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 231: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 232: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 233: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 234: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 235: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 236: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 237: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 238: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 239: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 240: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 241: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 242: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 243: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 244: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 245: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 246: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 247: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 248: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 249: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 250: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 251: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 252: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 253: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 254: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 255: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 256: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 257: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 258: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 259: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 260: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 261: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 262: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 263: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 264: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 265: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 266: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 267: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 268: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 269: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 270: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 271: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 272: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 273: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 274: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 275: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 276: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 277: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 278: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 279: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 280: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 281: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 282: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 283: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 284: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 285: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 286: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 287: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 288: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 289: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 290: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 291: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 292: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 293: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 294: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 295: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; default: @@ -5761,149 +20090,598 @@ static Bool IndexedFaceSet_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *IndexedFaceSet_Create() +GF_Node *BAP_Create() +{ + M_BAP *p; + GF_SAFEALLOC(p, M_BAP); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_BAP); + + /*default field values*/ + p->sacroiliac_tilt = 2 << 31; + p->sacroiliac_torsion = 2 << 31; + p->sacroiliac_roll = 2 << 31; + p->l_hip_flexion = 2 << 31; + p->r_hip_flexion = 2 << 31; + p->l_hip_abduct = 2 << 31; + p->r_hip_abduct = 2 << 31; + p->l_hip_twisting = 2 << 31; + p->r_hip_twisting = 2 << 31; + p->l_knee_flexion = 2 << 31; + p->r_knee_flexion = 2 << 31; + p->l_knee_twisting = 2 << 31; + p->r_knee_twisting = 2 << 31; + p->l_ankle_flexion = 2 << 31; + p->r_ankle_flexion = 2 << 31; + p->l_ankle_twisting = 2 << 31; + p->r_ankle_twisting = 2 << 31; + p->l_subtalar_flexion = 2 << 31; + p->r_subtalar_flexion = 2 << 31; + p->l_midtarsal_flexion = 2 << 31; + p->r_midtarsal_flexion = 2 << 31; + p->l_metatarsal_flexion = 2 << 31; + p->r_metatarsal_flexion = 2 << 31; + p->l_sternoclavicular_abduct = 2 << 31; + p->r_sternoclavicular_abduct = 2 << 31; + p->l_sternoclavicular_rotate = 2 << 31; + p->r_sternoclavicular_rotate = 2 << 31; + p->l_acromioclavicular_abduct = 2 << 31; + p->r_acromioclavicular_abduct = 2 << 31; + p->l_acromioclavicular_rotate = 2 << 31; + p->r_acromioclavicular_rotate = 2 << 31; + p->l_shoulder_flexion = 2 << 31; + p->r_shoulder_flexion = 2 << 31; + p->l_shoulder_abduct = 2 << 31; + p->r_shoulder_abduct = 2 << 31; + p->l_shoulder_twisting = 2 << 31; + p->r_shoulder_twisting = 2 << 31; + p->l_elbow_flexion = 2 << 31; + p->r_elbow_flexion = 2 << 31; + p->l_elbow_twisting = 2 << 31; + p->r_elbow_twisting = 2 << 31; + p->l_wrist_flexion = 2 << 31; + p->r_wrist_flexion = 2 << 31; + p->l_wrist_pivot = 2 << 31; + p->r_wrist_pivot = 2 << 31; + p->l_wrist_twisting = 2 << 31; + p->r_wrist_twisting = 2 << 31; + p->skullbase_roll = 2 << 31; + p->skullbase_torsion = 2 << 31; + p->skullbase_tilt = 2 << 31; + p->vc1roll = 2 << 31; + p->vc1torsion = 2 << 31; + p->vc1tilt = 2 << 31; + p->vc2roll = 2 << 31; + p->vc2torsion = 2 << 31; + p->vc2tilt = 2 << 31; + p->vc3roll = 2 << 31; + p->vc3torsion = 2 << 31; + p->vc3tilt = 2 << 31; + p->vc4roll = 2 << 31; + p->vc4torsion = 2 << 31; + p->vc4tilt = 2 << 31; + p->vc5roll = 2 << 31; + p->vc5torsion = 2 << 31; + p->vc5tilt = 2 << 31; + p->vc6roll = 2 << 31; + p->vc6torsion = 2 << 31; + p->vc6tilt = 2 << 31; + p->vc7roll = 2 << 31; + p->vc7torsion = 2 << 31; + p->vc7tilt = 2 << 31; + p->vt1roll = 2 << 31; + p->vt1torsion = 2 << 31; + p->vt1tilt = 2 << 31; + p->vt2roll = 2 << 31; + p->vt2torsion = 2 << 31; + p->vt2tilt = 2 << 31; + p->vt3roll = 2 << 31; + p->vt3torsion = 2 << 31; + p->vt3tilt = 2 << 31; + p->vt4roll = 2 << 31; + p->vt4torsion = 2 << 31; + p->vt4tilt = 2 << 31; + p->vt5roll = 2 << 31; + p->vt5torsion = 2 << 31; + p->vt5tilt = 2 << 31; + p->vt6roll = 2 << 31; + p->vt6torsion = 2 << 31; + p->vt6tilt = 2 << 31; + p->vt7roll = 2 << 31; + p->vt7torsion = 2 << 31; + p->vt7tilt = 2 << 31; + p->vt8roll = 2 << 31; + p->vt8torsion = 2 << 31; + p->vt8tilt = 2 << 31; + p->vt9roll = 2 << 31; + p->vt9torsion = 2 << 31; + p->vt9tilt = 2 << 31; + p->vt10roll = 2 << 31; + p->vt10torsion = 2 << 31; + p->vt10tilt = 2 << 31; + p->vt11roll = 2 << 31; + p->vt11torsion = 2 << 31; + p->vt11tilt = 2 << 31; + p->vt12roll = 2 << 31; + p->vt12torsion = 2 << 31; + p->vt12tilt = 2 << 31; + p->vl1roll = 2 << 31; + p->vl1torsion = 2 << 31; + p->vl1tilt = 2 << 31; + p->vl2roll = 2 << 31; + p->vl2torsion = 2 << 31; + p->vl2tilt = 2 << 31; + p->vl3roll = 2 << 31; + p->vl3torsion = 2 << 31; + p->vl3tilt = 2 << 31; + p->vl4roll = 2 << 31; + p->vl4torsion = 2 << 31; + p->vl4tilt = 2 << 31; + p->vl5roll = 2 << 31; + p->vl5torsion = 2 << 31; + p->vl5tilt = 2 << 31; + p->l_pinky0_flexion = 2 << 31; + p->r_pinky0_flexion = 2 << 31; + p->l_pinky1_flexion = 2 << 31; + p->r_pinky1_flexion = 2 << 31; + p->l_pinky1_pivot = 2 << 31; + p->r_pinky1_pivot = 2 << 31; + p->l_pinky1_twisting = 2 << 31; + p->r_pinky1_twisting = 2 << 31; + p->l_pinky2_flexion = 2 << 31; + p->r_pinky2_flexion = 2 << 31; + p->l_pinky3_flexion = 2 << 31; + p->r_pinky3_flexion = 2 << 31; + p->l_ring0_flexion = 2 << 31; + p->r_ring0_flexion = 2 << 31; + p->l_ring1_flexion = 2 << 31; + p->r_ring1_flexion = 2 << 31; + p->l_ring1_pivot = 2 << 31; + p->r_ring1_pivot = 2 << 31; + p->l_ring1_twisting = 2 << 31; + p->r_ring1_twisting = 2 << 31; + p->l_ring2_flexion = 2 << 31; + p->r_ring2_flexion = 2 << 31; + p->l_ring3_flexion = 2 << 31; + p->r_ring3_flexion = 2 << 31; + p->l_middle0_flexion = 2 << 31; + p->r_middle0_flexion = 2 << 31; + p->l_middle1_flexion = 2 << 31; + p->r_middle1_flexion = 2 << 31; + p->l_middle1_pivot = 2 << 31; + p->r_middle1_pivot = 2 << 31; + p->l_middle1_twisting = 2 << 31; + p->r_middle1_twisting = 2 << 31; + p->l_middle2_flexion = 2 << 31; + p->r_middle2_flexion = 2 << 31; + p->l_middle3_flexion = 2 << 31; + p->r_middle3_flexion = 2 << 31; + p->l_index0_flexion = 2 << 31; + p->r_index0_flexion = 2 << 31; + p->l_index1_flexion = 2 << 31; + p->r_index1_flexion = 2 << 31; + p->l_index1_pivot = 2 << 31; + p->r_index1_pivot = 2 << 31; + p->l_index1_twisting = 2 << 31; + p->r_index1_twisting = 2 << 31; + p->l_index2_flexion = 2 << 31; + p->r_index2_flexion = 2 << 31; + p->l_index3_flexion = 2 << 31; + p->r_index3_flexion = 2 << 31; + p->l_thumb1_flexion = 2 << 31; + p->r_thumb1_flexion = 2 << 31; + p->l_thumb1_pivot = 2 << 31; + p->r_thumb1_pivot = 2 << 31; + p->l_thumb1_twisting = 2 << 31; + p->r_thumb1_twisting = 2 << 31; + p->l_thumb2_flexion = 2 << 31; + p->r_thumb2_flexion = 2 << 31; + p->l_thumb3_flexion = 2 << 31; + p->r_thumb3_flexion = 2 << 31; + p->HumanoidRoot_tr_vertical = 2 << 31; + p->HumanoidRoot_tr_lateral = 2 << 31; + p->HumanoidRoot_tr_frontal = 2 << 31; + p->HumanoidRoot_rt_body_turn = 2 << 31; + p->HumanoidRoot_rt_body_roll = 2 << 31; + p->HumanoidRoot_rt_body_tilt = 2 << 31; + p->extensionBap187 = 2 << 31; + p->extensionBap188 = 2 << 31; + p->extensionBap189 = 2 << 31; + p->extensionBap190 = 2 << 31; + p->extensionBap191 = 2 << 31; + p->extensionBap192 = 2 << 31; + p->extensionBap193 = 2 << 31; + p->extensionBap194 = 2 << 31; + p->extensionBap195 = 2 << 31; + p->extensionBap196 = 2 << 31; + p->extensionBap197 = 2 << 31; + p->extensionBap198 = 2 << 31; + p->extensionBap199 = 2 << 31; + p->extensionBap200 = 2 << 31; + p->extensionBap201 = 2 << 31; + p->extensionBap202 = 2 << 31; + p->extensionBap203 = 2 << 31; + p->extensionBap204 = 2 << 31; + p->extensionBap205 = 2 << 31; + p->extensionBap206 = 2 << 31; + p->extensionBap207 = 2 << 31; + p->extensionBap208 = 2 << 31; + p->extensionBap209 = 2 << 31; + p->extensionBap210 = 2 << 31; + p->extensionBap211 = 2 << 31; + p->extensionBap212 = 2 << 31; + p->extensionBap213 = 2 << 31; + p->extensionBap214 = 2 << 31; + p->extensionBap215 = 2 << 31; + p->extensionBap216 = 2 << 31; + p->extensionBap217 = 2 << 31; + p->extensionBap218 = 2 << 31; + p->extensionBap219 = 2 << 31; + p->extensionBap220 = 2 << 31; + p->extensionBap221 = 2 << 31; + p->extensionBap222 = 2 << 31; + p->extensionBap223 = 2 << 31; + p->extensionBap224 = 2 << 31; + p->extensionBap225 = 2 << 31; + p->extensionBap226 = 2 << 31; + p->extensionBap227 = 2 << 31; + p->extensionBap228 = 2 << 31; + p->extensionBap229 = 2 << 31; + p->extensionBap230 = 2 << 31; + p->extensionBap231 = 2 << 31; + p->extensionBap232 = 2 << 31; + p->extensionBap233 = 2 << 31; + p->extensionBap234 = 2 << 31; + p->extensionBap235 = 2 << 31; + p->extensionBap236 = 2 << 31; + p->extensionBap237 = 2 << 31; + p->extensionBap238 = 2 << 31; + p->extensionBap239 = 2 << 31; + p->extensionBap240 = 2 << 31; + p->extensionBap241 = 2 << 31; + p->extensionBap242 = 2 << 31; + p->extensionBap243 = 2 << 31; + p->extensionBap244 = 2 << 31; + p->extensionBap245 = 2 << 31; + p->extensionBap246 = 2 << 31; + p->extensionBap247 = 2 << 31; + p->extensionBap248 = 2 << 31; + p->extensionBap249 = 2 << 31; + p->extensionBap250 = 2 << 31; + p->extensionBap251 = 2 << 31; + p->extensionBap252 = 2 << 31; + p->extensionBap253 = 2 << 31; + p->extensionBap254 = 2 << 31; + p->extensionBap255 = 2 << 31; + p->extensionBap256 = 2 << 31; + p->extensionBap257 = 2 << 31; + p->extensionBap258 = 2 << 31; + p->extensionBap259 = 2 << 31; + p->extensionBap260 = 2 << 31; + p->extensionBap261 = 2 << 31; + p->extensionBap262 = 2 << 31; + p->extensionBap263 = 2 << 31; + p->extensionBap264 = 2 << 31; + p->extensionBap265 = 2 << 31; + p->extensionBap266 = 2 << 31; + p->extensionBap267 = 2 << 31; + p->extensionBap268 = 2 << 31; + p->extensionBap269 = 2 << 31; + p->extensionBap270 = 2 << 31; + p->extensionBap271 = 2 << 31; + p->extensionBap272 = 2 << 31; + p->extensionBap273 = 2 << 31; + p->extensionBap274 = 2 << 31; + p->extensionBap275 = 2 << 31; + p->extensionBap276 = 2 << 31; + p->extensionBap277 = 2 << 31; + p->extensionBap278 = 2 << 31; + p->extensionBap279 = 2 << 31; + p->extensionBap280 = 2 << 31; + p->extensionBap281 = 2 << 31; + p->extensionBap282 = 2 << 31; + p->extensionBap283 = 2 << 31; + p->extensionBap284 = 2 << 31; + p->extensionBap285 = 2 << 31; + p->extensionBap286 = 2 << 31; + p->extensionBap287 = 2 << 31; + p->extensionBap288 = 2 << 31; + p->extensionBap289 = 2 << 31; + p->extensionBap290 = 2 << 31; + p->extensionBap291 = 2 << 31; + p->extensionBap292 = 2 << 31; + p->extensionBap293 = 2 << 31; + p->extensionBap294 = 2 << 31; + p->extensionBap295 = 2 << 31; + p->extensionBap296 = 2 << 31; + return (GF_Node *)p; +} + + +/* + BDP Node deletion +*/ + +static void BDP_Del(GF_Node *node) +{ + M_BDP *p = (M_BDP *) node; + gf_node_unregister_children((GF_Node *) p, p->bodyDefTables); + gf_node_unregister_children((GF_Node *) p, p->bodySceneGraph); + gf_node_free((GF_Node *) p); +} + +static const u16 BDP_Def2All[] = { 0, 1}; +static const u16 BDP_In2All[] = { 0, 1}; +static const u16 BDP_Out2All[] = { 0, 1}; + +static u32 BDP_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 2; + } +} + +static GF_Err BDP_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = BDP_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = BDP_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = BDP_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err BDP_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "bodyDefTables"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFBodyDefTableNode; + info->far_ptr = & ((M_BDP *)node)->bodyDefTables; + return GF_OK; + case 1: + info->name = "bodySceneGraph"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_BDP *)node)->bodySceneGraph; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 BDP_get_field_index_by_name(char *name) +{ + if (!strcmp("bodyDefTables", name)) return 0; + if (!strcmp("bodySceneGraph", name)) return 1; + return -1; + } +static Bool BDP_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *BDP_Create() { - M_IndexedFaceSet *p; - GF_SAFEALLOC(p, M_IndexedFaceSet); + M_BDP *p; + GF_SAFEALLOC(p, M_BDP); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_IndexedFaceSet); + gf_node_setup((GF_Node *)p, TAG_MPEG4_BDP); /*default field values*/ - p->ccw = 1; - p->colorPerVertex = 1; - p->convex = 1; - p->creaseAngle = FLT2FIX(0.0); - p->normalPerVertex = 1; - p->solid = 1; return (GF_Node *)p; } /* - IndexedFaceSet2D Node deletion + Body Node deletion */ -static void IndexedFaceSet2D_Del(GF_Node *node) +static void Body_Del(GF_Node *node) { - M_IndexedFaceSet2D *p = (M_IndexedFaceSet2D *) node; - gf_sg_mfint32_del(p->set_colorIndex); - gf_sg_mfint32_del(p->set_coordIndex); - gf_sg_mfint32_del(p->set_texCoordIndex); - gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->texCoord, (GF_Node *) p); - gf_sg_mfint32_del(p->colorIndex); - gf_sg_mfint32_del(p->coordIndex); - gf_sg_mfint32_del(p->texCoordIndex); + M_Body *p = (M_Body *) node; + gf_node_unregister((GF_Node *) p->bdp, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->bap, (GF_Node *) p); + gf_node_unregister_children((GF_Node *) p, p->renderedBody); gf_node_free((GF_Node *) p); } -static const u16 IndexedFaceSet2D_Def2All[] = { 3, 4, 5, 6, 7, 8, 9, 10}; -static const u16 IndexedFaceSet2D_In2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 IndexedFaceSet2D_Out2All[] = { 3, 4, 5}; +static const u16 Body_Def2All[] = { 0, 1, 2}; +static const u16 Body_In2All[] = { 0, 1, 2}; +static const u16 Body_Out2All[] = { 0, 1, 2}; -static u32 IndexedFaceSet2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Body_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 6; - case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 3; case GF_SG_FIELD_CODING_OUT: return 3; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 11; + return 3; } } -static GF_Err IndexedFaceSet2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Body_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = IndexedFaceSet2D_In2All[inField]; + *allField = Body_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = IndexedFaceSet2D_Def2All[inField]; + *allField = Body_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = IndexedFaceSet2D_Out2All[inField]; + *allField = Body_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err IndexedFaceSet2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Body_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_colorIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedFaceSet2D *)node)->on_set_colorIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet2D *) node)->set_colorIndex; + info->name = "bdp"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFBDPNode; + info->far_ptr = & ((M_Body *)node)->bdp; return GF_OK; case 1: - info->name = "set_coordIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedFaceSet2D *)node)->on_set_coordIndex; + info->name = "bap"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFBAPNode; + info->far_ptr = & ((M_Body *)node)->bap; + return GF_OK; + case 2: + info->name = "renderedBody"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Body *)node)->renderedBody; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Body_get_field_index_by_name(char *name) +{ + if (!strcmp("bdp", name)) return 0; + if (!strcmp("bap", name)) return 1; + if (!strcmp("renderedBody", name)) return 2; + return -1; + } +static Bool Body_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *Body_Create() +{ + M_Body *p; + GF_SAFEALLOC(p, M_Body); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_Body); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + BodyDefTable Node deletion +*/ + +static void BodyDefTable_Del(GF_Node *node) +{ + M_BodyDefTable *p = (M_BodyDefTable *) node; + gf_sg_sfstring_del(p->bodySceneGraphNodeName); + gf_sg_mfint32_del(p->bapIDs); + gf_sg_mfint32_del(p->vertexIds); + gf_sg_mfint32_del(p->bapCombinations); + gf_sg_mfvec3f_del(p->displacements); + gf_node_free((GF_Node *) p); +} + +static const u16 BodyDefTable_Def2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 BodyDefTable_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 BodyDefTable_Out2All[] = { 0, 1, 2, 3, 4, 5}; + +static u32 BodyDefTable_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 6; + } +} + +static GF_Err BodyDefTable_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = BodyDefTable_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = BodyDefTable_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = BodyDefTable_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err BodyDefTable_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "bodySceneGraphNodeName"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_BodyDefTable *) node)->bodySceneGraphNodeName; + return GF_OK; + case 1: + info->name = "bapIDs"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet2D *) node)->set_coordIndex; + info->far_ptr = & ((M_BodyDefTable *) node)->bapIDs; return GF_OK; case 2: - info->name = "set_texCoordIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedFaceSet2D *)node)->on_set_texCoordIndex; + info->name = "vertexIds"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet2D *) node)->set_texCoordIndex; + info->far_ptr = & ((M_BodyDefTable *) node)->vertexIds; return GF_OK; case 3: - info->name = "color"; + info->name = "bapCombinations"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((M_IndexedFaceSet2D *)node)->color; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_BodyDefTable *) node)->bapCombinations; return GF_OK; case 4: - info->name = "coord"; + info->name = "displacements"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinate2DNode; - info->far_ptr = & ((M_IndexedFaceSet2D *)node)->coord; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_BodyDefTable *) node)->displacements; return GF_OK; case 5: - info->name = "texCoord"; + info->name = "numInterpolateKeys"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureCoordinateNode; - info->far_ptr = & ((M_IndexedFaceSet2D *)node)->texCoord; - return GF_OK; - case 6: - info->name = "colorIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet2D *) node)->colorIndex; - return GF_OK; - case 7: - info->name = "colorPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_IndexedFaceSet2D *) node)->colorPerVertex; - return GF_OK; - case 8: - info->name = "convex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_IndexedFaceSet2D *) node)->convex; - return GF_OK; - case 9: - info->name = "coordIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet2D *) node)->coordIndex; - return GF_OK; - case 10: - info->name = "texCoordIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedFaceSet2D *) node)->texCoordIndex; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BodyDefTable *) node)->numInterpolateKeys; return GF_OK; default: return GF_BAD_PARAM; @@ -5911,40 +20689,42 @@ static GF_Err IndexedFaceSet2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 IndexedFaceSet2D_get_field_index_by_name(char *name) +static s32 BodyDefTable_get_field_index_by_name(char *name) { - if (!strcmp("set_colorIndex", name)) return 0; - if (!strcmp("set_coordIndex", name)) return 1; - if (!strcmp("set_texCoordIndex", name)) return 2; - if (!strcmp("color", name)) return 3; - if (!strcmp("coord", name)) return 4; - if (!strcmp("texCoord", name)) return 5; - if (!strcmp("colorIndex", name)) return 6; - if (!strcmp("colorPerVertex", name)) return 7; - if (!strcmp("convex", name)) return 8; - if (!strcmp("coordIndex", name)) return 9; - if (!strcmp("texCoordIndex", name)) return 10; + if (!strcmp("bodySceneGraphNodeName", name)) return 0; + if (!strcmp("bapIDs", name)) return 1; + if (!strcmp("vertexIds", name)) return 2; + if (!strcmp("bapCombinations", name)) return 3; + if (!strcmp("displacements", name)) return 4; + if (!strcmp("numInterpolateKeys", name)) return 5; return -1; } -static Bool IndexedFaceSet2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool BodyDefTable_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 6: + case 1: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 13; + *QT13_bits = 9; + *b_min = FLT2FIX(1); + *b_max = FLT2FIX(296); + return 1; + case 2: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); *b_max = FIX_MAX; return 1; - case 9: + case 3: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 0; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 10: + case 5: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 0; + *b_min = FLT2FIX(2); *b_max = FIX_MAX; return 1; default: @@ -5954,116 +20734,91 @@ static Bool IndexedFaceSet2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *IndexedFaceSet2D_Create() +GF_Node *BodyDefTable_Create() { - M_IndexedFaceSet2D *p; - GF_SAFEALLOC(p, M_IndexedFaceSet2D); + M_BodyDefTable *p; + GF_SAFEALLOC(p, M_BodyDefTable); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_IndexedFaceSet2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_BodyDefTable); /*default field values*/ - p->colorPerVertex = 1; - p->convex = 1; + p->numInterpolateKeys = 2; return (GF_Node *)p; } /* - IndexedLineSet Node deletion + BodySegmentConnectionHint Node deletion */ -static void IndexedLineSet_Del(GF_Node *node) +static void BodySegmentConnectionHint_Del(GF_Node *node) { - M_IndexedLineSet *p = (M_IndexedLineSet *) node; - gf_sg_mfint32_del(p->set_colorIndex); - gf_sg_mfint32_del(p->set_coordIndex); - gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); - gf_sg_mfint32_del(p->colorIndex); - gf_sg_mfint32_del(p->coordIndex); + M_BodySegmentConnectionHint *p = (M_BodySegmentConnectionHint *) node; + gf_sg_sfstring_del(p->firstSegmentNodeName); + gf_sg_sfstring_del(p->secondSegmentNodeName); + gf_sg_mfint32_del(p->firstVertexIdList); + gf_sg_mfint32_del(p->secondVertexIdList); gf_node_free((GF_Node *) p); } -static const u16 IndexedLineSet_Def2All[] = { 2, 3, 4, 5, 6}; -static const u16 IndexedLineSet_In2All[] = { 0, 1, 2, 3}; -static const u16 IndexedLineSet_Out2All[] = { 2, 3}; +static const u16 BodySegmentConnectionHint_Def2All[] = { 0, 1, 2, 3}; +static const u16 BodySegmentConnectionHint_In2All[] = { 0, 1, 2, 3}; +static const u16 BodySegmentConnectionHint_Out2All[] = { 0, 1, 2, 3}; -static u32 IndexedLineSet_get_field_count(GF_Node *node, u8 IndexMode) +static u32 BodySegmentConnectionHint_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 7; + return 4; } } -static GF_Err IndexedLineSet_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err BodySegmentConnectionHint_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = IndexedLineSet_In2All[inField]; + *allField = BodySegmentConnectionHint_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = IndexedLineSet_Def2All[inField]; + *allField = BodySegmentConnectionHint_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = IndexedLineSet_Out2All[inField]; + *allField = BodySegmentConnectionHint_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err IndexedLineSet_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err BodySegmentConnectionHint_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_colorIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedLineSet *)node)->on_set_colorIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedLineSet *) node)->set_colorIndex; + info->name = "firstSegmentNodeName"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_BodySegmentConnectionHint *) node)->firstSegmentNodeName; return GF_OK; case 1: - info->name = "set_coordIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedLineSet *)node)->on_set_coordIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedLineSet *) node)->set_coordIndex; + info->name = "secondSegmentNodeName"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_BodySegmentConnectionHint *) node)->secondSegmentNodeName; return GF_OK; case 2: - info->name = "color"; + info->name = "firstVertexIdList"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((M_IndexedLineSet *)node)->color; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_BodySegmentConnectionHint *) node)->firstVertexIdList; return GF_OK; case 3: - info->name = "coord"; + info->name = "secondVertexIdList"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinateNode; - info->far_ptr = & ((M_IndexedLineSet *)node)->coord; - return GF_OK; - case 4: - info->name = "colorIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedLineSet *) node)->colorIndex; - return GF_OK; - case 5: - info->name = "colorPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_IndexedLineSet *) node)->colorPerVertex; - return GF_OK; - case 6: - info->name = "coordIndex"; - info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedLineSet *) node)->coordIndex; + info->far_ptr = & ((M_BodySegmentConnectionHint *) node)->secondVertexIdList; return GF_OK; default: return GF_BAD_PARAM; @@ -6071,30 +20826,27 @@ static GF_Err IndexedLineSet_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 IndexedLineSet_get_field_index_by_name(char *name) +static s32 BodySegmentConnectionHint_get_field_index_by_name(char *name) { - if (!strcmp("set_colorIndex", name)) return 0; - if (!strcmp("set_coordIndex", name)) return 1; - if (!strcmp("color", name)) return 2; - if (!strcmp("coord", name)) return 3; - if (!strcmp("colorIndex", name)) return 4; - if (!strcmp("colorPerVertex", name)) return 5; - if (!strcmp("coordIndex", name)) return 6; + if (!strcmp("firstSegmentNodeName", name)) return 0; + if (!strcmp("secondSegmentNodeName", name)) return 1; + if (!strcmp("firstVertexIdList", name)) return 2; + if (!strcmp("secondVertexIdList", name)) return 3; return -1; } -static Bool IndexedLineSet_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool BodySegmentConnectionHint_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 4: + case 2: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 0; + *b_min = FLT2FIX(0); *b_max = FIX_MAX; return 1; - case 6: + case 3: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 0; + *b_min = FLT2FIX(0); *b_max = FIX_MAX; return 1; default: @@ -6104,146 +20856,224 @@ static Bool IndexedLineSet_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *IndexedLineSet_Create() +GF_Node *BodySegmentConnectionHint_Create() { - M_IndexedLineSet *p; - GF_SAFEALLOC(p, M_IndexedLineSet); + M_BodySegmentConnectionHint *p; + GF_SAFEALLOC(p, M_BodySegmentConnectionHint); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_IndexedLineSet); + gf_node_setup((GF_Node *)p, TAG_MPEG4_BodySegmentConnectionHint); /*default field values*/ - p->colorPerVertex = 1; return (GF_Node *)p; } /* - IndexedLineSet2D Node deletion + DirectiveSound Node deletion */ -static void IndexedLineSet2D_Del(GF_Node *node) +static void DirectiveSound_Del(GF_Node *node) { - M_IndexedLineSet2D *p = (M_IndexedLineSet2D *) node; - gf_sg_mfint32_del(p->set_colorIndex); - gf_sg_mfint32_del(p->set_coordIndex); - gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); - gf_sg_mfint32_del(p->colorIndex); - gf_sg_mfint32_del(p->coordIndex); + M_DirectiveSound *p = (M_DirectiveSound *) node; + gf_node_unregister((GF_Node *) p->source, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->perceptualParameters, (GF_Node *) p); + gf_sg_mffloat_del(p->directivity); + gf_sg_mffloat_del(p->angles); + gf_sg_mffloat_del(p->frequency); gf_node_free((GF_Node *) p); } -static const u16 IndexedLineSet2D_Def2All[] = { 2, 3, 4, 5, 6}; -static const u16 IndexedLineSet2D_In2All[] = { 0, 1, 2, 3}; -static const u16 IndexedLineSet2D_Out2All[] = { 2, 3}; +static const u16 DirectiveSound_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 DirectiveSound_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 DirectiveSound_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 DirectiveSound_Dyn2All[] = { 0, 1, 2}; -static u32 IndexedLineSet2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 DirectiveSound_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 2; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 7; + case GF_SG_FIELD_CODING_DEF: return 13; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 3; default: - return 7; + return 13; } } -static GF_Err IndexedLineSet2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err DirectiveSound_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = IndexedLineSet2D_In2All[inField]; + *allField = DirectiveSound_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = IndexedLineSet2D_Def2All[inField]; + *allField = DirectiveSound_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = IndexedLineSet2D_Out2All[inField]; + *allField = DirectiveSound_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = DirectiveSound_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err IndexedLineSet2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err DirectiveSound_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_colorIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedLineSet2D *)node)->on_set_colorIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedLineSet2D *) node)->set_colorIndex; + info->name = "direction"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_DirectiveSound *) node)->direction; return GF_OK; case 1: - info->name = "set_coordIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_IndexedLineSet2D *)node)->on_set_coordIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedLineSet2D *) node)->set_coordIndex; + info->name = "intensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_DirectiveSound *) node)->intensity; return GF_OK; case 2: - info->name = "color"; + info->name = "location"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((M_IndexedLineSet2D *)node)->color; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_DirectiveSound *) node)->location; return GF_OK; case 3: - info->name = "coord"; + info->name = "source"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinate2DNode; - info->far_ptr = & ((M_IndexedLineSet2D *)node)->coord; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_DirectiveSound *)node)->source; return GF_OK; case 4: - info->name = "colorIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedLineSet2D *) node)->colorIndex; + info->name = "perceptualParameters"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFPerceptualParameterNode; + info->far_ptr = & ((M_DirectiveSound *)node)->perceptualParameters; return GF_OK; case 5: - info->name = "colorPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; + info->name = "roomEffect"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_IndexedLineSet2D *) node)->colorPerVertex; + info->far_ptr = & ((M_DirectiveSound *) node)->roomEffect; return GF_OK; case 6: - info->name = "coordIndex"; + info->name = "spatialize"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_DirectiveSound *) node)->spatialize; + return GF_OK; + case 7: + info->name = "directivity"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_IndexedLineSet2D *) node)->coordIndex; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_DirectiveSound *) node)->directivity; + return GF_OK; + case 8: + info->name = "angles"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_DirectiveSound *) node)->angles; + return GF_OK; + case 9: + info->name = "frequency"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_DirectiveSound *) node)->frequency; + return GF_OK; + case 10: + info->name = "speedOfSound"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_DirectiveSound *) node)->speedOfSound; + return GF_OK; + case 11: + info->name = "distance"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_DirectiveSound *) node)->distance; + return GF_OK; + case 12: + info->name = "useAirabs"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_DirectiveSound *) node)->useAirabs; return GF_OK; default: return GF_BAD_PARAM; } } - -static s32 IndexedLineSet2D_get_field_index_by_name(char *name) -{ - if (!strcmp("set_colorIndex", name)) return 0; - if (!strcmp("set_coordIndex", name)) return 1; - if (!strcmp("color", name)) return 2; - if (!strcmp("coord", name)) return 3; - if (!strcmp("colorIndex", name)) return 4; - if (!strcmp("colorPerVertex", name)) return 5; - if (!strcmp("coordIndex", name)) return 6; + +static s32 DirectiveSound_get_field_index_by_name(char *name) +{ + if (!strcmp("direction", name)) return 0; + if (!strcmp("intensity", name)) return 1; + if (!strcmp("location", name)) return 2; + if (!strcmp("source", name)) return 3; + if (!strcmp("perceptualParameters", name)) return 4; + if (!strcmp("roomEffect", name)) return 5; + if (!strcmp("spatialize", name)) return 6; + if (!strcmp("directivity", name)) return 7; + if (!strcmp("angles", name)) return 8; + if (!strcmp("frequency", name)) return 9; + if (!strcmp("speedOfSound", name)) return 10; + if (!strcmp("distance", name)) return 11; + if (!strcmp("useAirabs", name)) return 12; return -1; } -static Bool IndexedLineSet2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool DirectiveSound_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 4: + case 0: + *AType = 9; + *QType = 9; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 7; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 2: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 7: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 0; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 6: + case 8: *AType = 0; - *QType = 14; - *b_min = FLT2FIX(-1); + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(3.14159265); + return 1; + case 9: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 10: + *AType = 0; + *QType = 1; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 11: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); *b_max = FIX_MAX; return 1; default: @@ -6253,70 +21083,104 @@ static Bool IndexedLineSet2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *IndexedLineSet2D_Create() +GF_Node *DirectiveSound_Create() { - M_IndexedLineSet2D *p; - GF_SAFEALLOC(p, M_IndexedLineSet2D); + M_DirectiveSound *p; + GF_SAFEALLOC(p, M_DirectiveSound); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_IndexedLineSet2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_DirectiveSound); /*default field values*/ - p->colorPerVertex = 1; + p->direction.x = FLT2FIX(0); + p->direction.y = FLT2FIX(0); + p->direction.z = FLT2FIX(-1); + p->intensity = FLT2FIX(1); + p->location.x = FLT2FIX(0); + p->location.y = FLT2FIX(0); + p->location.z = FLT2FIX(0); + p->spatialize = 1; + p->directivity.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->directivity.count = 1; + p->directivity.vals[0] = FLT2FIX(1); + p->angles.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->angles.count = 1; + p->angles.vals[0] = FLT2FIX(1); + p->speedOfSound = FLT2FIX(340); + p->distance = FLT2FIX(100); return (GF_Node *)p; } /* - Inline Node deletion + Hierarchical3DMesh Node deletion */ -static void Inline_Del(GF_Node *node) +static void Hierarchical3DMesh_Del(GF_Node *node) { - M_Inline *p = (M_Inline *) node; + M_Hierarchical3DMesh *p = (M_Hierarchical3DMesh *) node; gf_sg_mfurl_del(p->url); gf_node_free((GF_Node *) p); } -static const u16 Inline_Def2All[] = { 0}; -static const u16 Inline_In2All[] = { 0}; -static const u16 Inline_Out2All[] = { 0}; +static const u16 Hierarchical3DMesh_Def2All[] = { 1, 2}; +static const u16 Hierarchical3DMesh_In2All[] = { 0, 1}; +static const u16 Hierarchical3DMesh_Out2All[] = { 1, 3}; -static u32 Inline_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Hierarchical3DMesh_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 1; + return 4; } } -static GF_Err Inline_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Hierarchical3DMesh_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Inline_In2All[inField]; + *allField = Hierarchical3DMesh_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Inline_Def2All[inField]; + *allField = Hierarchical3DMesh_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Inline_Out2All[inField]; + *allField = Hierarchical3DMesh_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Inline_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Hierarchical3DMesh_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "url"; + info->name = "triangleBudget"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Hierarchical3DMesh *)node)->on_triangleBudget; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Hierarchical3DMesh *) node)->triangleBudget; + return GF_OK; + case 1: + info->name = "level"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Hierarchical3DMesh *) node)->level; + return GF_OK; + case 2: + info->name = "url"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_Inline *) node)->url; + info->far_ptr = & ((M_Hierarchical3DMesh *) node)->url; + return GF_OK; + case 3: + info->name = "doneLoading"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Hierarchical3DMesh *) node)->doneLoading; return GF_OK; default: return GF_BAD_PARAM; @@ -6324,14 +21188,29 @@ static GF_Err Inline_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Inline_get_field_index_by_name(char *name) +static s32 Hierarchical3DMesh_get_field_index_by_name(char *name) { - if (!strcmp("url", name)) return 0; + if (!strcmp("triangleBudget", name)) return 0; + if (!strcmp("level", name)) return 1; + if (!strcmp("url", name)) return 2; + if (!strcmp("doneLoading", name)) return 3; return -1; } -static Bool Inline_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool Hierarchical3DMesh_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; default: return 0; } @@ -6339,83 +21218,103 @@ static Bool Inline_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, -GF_Node *Inline_Create() +GF_Node *Hierarchical3DMesh_Create() { - M_Inline *p; - GF_SAFEALLOC(p, M_Inline); + M_Hierarchical3DMesh *p; + GF_SAFEALLOC(p, M_Hierarchical3DMesh); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Inline); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Hierarchical3DMesh); /*default field values*/ + p->level = FLT2FIX(1); return (GF_Node *)p; } /* - LOD Node deletion + MaterialKey Node deletion */ -static void LOD_Del(GF_Node *node) +static void MaterialKey_Del(GF_Node *node) { - M_LOD *p = (M_LOD *) node; - gf_node_unregister_children((GF_Node *) p, p->level); - gf_sg_mffloat_del(p->range); + M_MaterialKey *p = (M_MaterialKey *) node; gf_node_free((GF_Node *) p); } -static const u16 LOD_Def2All[] = { 0, 1, 2}; -static const u16 LOD_In2All[] = { 0}; -static const u16 LOD_Out2All[] = { 0}; +static const u16 MaterialKey_Def2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 MaterialKey_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 MaterialKey_Out2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 MaterialKey_Dyn2All[] = { 2, 3, 4, 5}; -static u32 LOD_get_field_count(GF_Node *node, u8 IndexMode) +static u32 MaterialKey_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 1; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 4; default: - return 3; + return 6; } } -static GF_Err LOD_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err MaterialKey_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = LOD_In2All[inField]; + *allField = MaterialKey_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = LOD_Def2All[inField]; + *allField = MaterialKey_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = LOD_Out2All[inField]; + *allField = MaterialKey_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = MaterialKey_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err LOD_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MaterialKey_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "level"; + info->name = "isKeyed"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_LOD *)node)->level; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MaterialKey *) node)->isKeyed; return GF_OK; case 1: - info->name = "center"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_LOD *) node)->center; + info->name = "isRGB"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MaterialKey *) node)->isRGB; return GF_OK; case 2: - info->name = "range"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_LOD *) node)->range; + info->name = "keyColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_MaterialKey *) node)->keyColor; + return GF_OK; + case 3: + info->name = "lowThreshold"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_MaterialKey *) node)->lowThreshold; + return GF_OK; + case 4: + info->name = "highThreshold"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_MaterialKey *) node)->highThreshold; + return GF_OK; + case 5: + info->name = "transparency"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_MaterialKey *) node)->transparency; return GF_OK; default: return GF_BAD_PARAM; @@ -6423,27 +21322,42 @@ static GF_Err LOD_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 LOD_get_field_index_by_name(char *name) +static s32 MaterialKey_get_field_index_by_name(char *name) { - if (!strcmp("level", name)) return 0; - if (!strcmp("center", name)) return 1; - if (!strcmp("range", name)) return 2; + if (!strcmp("isKeyed", name)) return 0; + if (!strcmp("isRGB", name)) return 1; + if (!strcmp("keyColor", name)) return 2; + if (!strcmp("lowThreshold", name)) return 3; + if (!strcmp("highThreshold", name)) return 4; + if (!strcmp("transparency", name)) return 5; return -1; } -static Bool LOD_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool MaterialKey_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 0; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; case 2: - *AType = 0; - *QType = 11; + *AType = 4; + *QType = 4; *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + *b_max = FLT2FIX(1); + return 1; + case 3: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 4: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 5: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); return 1; default: return 0; @@ -6452,115 +21366,191 @@ static Bool LOD_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fi -GF_Node *LOD_Create() +GF_Node *MaterialKey_Create() { - M_LOD *p; - GF_SAFEALLOC(p, M_LOD); + M_MaterialKey *p; + GF_SAFEALLOC(p, M_MaterialKey); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_LOD); + gf_node_setup((GF_Node *)p, TAG_MPEG4_MaterialKey); /*default field values*/ - p->center.x = FLT2FIX(0); - p->center.y = FLT2FIX(0); - p->center.z = FLT2FIX(0); + p->isKeyed = 1; + p->isRGB = 1; + p->keyColor.red = FLT2FIX(0); + p->keyColor.green = FLT2FIX(0); + p->keyColor.blue = FLT2FIX(0); + p->lowThreshold = FLT2FIX(0); + p->highThreshold = FLT2FIX(0); + p->transparency = FLT2FIX(0); return (GF_Node *)p; } /* - Layer2D Node deletion + PerceptualParameters Node deletion */ -static void Layer2D_Del(GF_Node *node) +static void PerceptualParameters_Del(GF_Node *node) { - M_Layer2D *p = (M_Layer2D *) node; - gf_node_unregister((GF_Node *) p->background, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->viewport, (GF_Node *) p); - gf_sg_vrml_parent_destroy((GF_Node *) p); + M_PerceptualParameters *p = (M_PerceptualParameters *) node; + gf_sg_mffloat_del(p->omniDirectivity); + gf_sg_mffloat_del(p->directFilterGains); + gf_sg_mffloat_del(p->inputFilterGains); gf_node_free((GF_Node *) p); } -static const u16 Layer2D_Def2All[] = { 2, 3, 4, 5}; -static const u16 Layer2D_In2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 Layer2D_Out2All[] = { 2, 3, 4, 5}; -static const u16 Layer2D_Dyn2All[] = { 3}; +static const u16 PerceptualParameters_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; +static const u16 PerceptualParameters_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; +static const u16 PerceptualParameters_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; +static const u16 PerceptualParameters_Dyn2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; -static u32 Layer2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 PerceptualParameters_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 6; - case GF_SG_FIELD_CODING_DEF: return 4; - case GF_SG_FIELD_CODING_OUT: return 4; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_IN: return 19; + case GF_SG_FIELD_CODING_DEF: return 19; + case GF_SG_FIELD_CODING_OUT: return 19; + case GF_SG_FIELD_CODING_DYN: return 15; default: - return 6; + return 19; } } -static GF_Err Layer2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err PerceptualParameters_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Layer2D_In2All[inField]; + *allField = PerceptualParameters_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Layer2D_Def2All[inField]; + *allField = PerceptualParameters_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Layer2D_Out2All[inField]; + *allField = PerceptualParameters_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = Layer2D_Dyn2All[inField]; + *allField = PerceptualParameters_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Layer2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err PerceptualParameters_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Layer2D *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Layer2D *)node)->addChildren; + info->name = "sourcePresence"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->sourcePresence; return GF_OK; case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Layer2D *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Layer2D *)node)->removeChildren; + info->name = "sourceWarmth"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->sourceWarmth; return GF_OK; case 2: - info->name = "children"; + info->name = "sourceBrilliance"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Layer2D *)node)->children; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->sourceBrilliance; return GF_OK; case 3: - info->name = "size"; + info->name = "roomPresence"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Layer2D *) node)->size; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->roomPresence; return GF_OK; case 4: - info->name = "background"; + info->name = "runningReverberance"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFBackground2DNode; - info->far_ptr = & ((M_Layer2D *)node)->background; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->runningReverberance; return GF_OK; case 5: - info->name = "viewport"; + info->name = "envelopment"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFViewportNode; - info->far_ptr = & ((M_Layer2D *)node)->viewport; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->envelopment; + return GF_OK; + case 6: + info->name = "lateReverberance"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->lateReverberance; + return GF_OK; + case 7: + info->name = "heavyness"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->heavyness; + return GF_OK; + case 8: + info->name = "liveness"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->liveness; + return GF_OK; + case 9: + info->name = "omniDirectivity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->omniDirectivity; + return GF_OK; + case 10: + info->name = "directFilterGains"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->directFilterGains; + return GF_OK; + case 11: + info->name = "inputFilterGains"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->inputFilterGains; + return GF_OK; + case 12: + info->name = "refDistance"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->refDistance; + return GF_OK; + case 13: + info->name = "freqLow"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->freqLow; + return GF_OK; + case 14: + info->name = "freqHigh"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PerceptualParameters *) node)->freqHigh; + return GF_OK; + case 15: + info->name = "timeLimit1"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_PerceptualParameters *) node)->timeLimit1; + return GF_OK; + case 16: + info->name = "timeLimit2"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_PerceptualParameters *) node)->timeLimit2; + return GF_OK; + case 17: + info->name = "timeLimit3"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_PerceptualParameters *) node)->timeLimit3; + return GF_OK; + case 18: + info->name = "modalDensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_PerceptualParameters *) node)->modalDensity; return GF_OK; default: return GF_BAD_PARAM; @@ -6568,22 +21558,143 @@ static GF_Err Layer2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Layer2D_get_field_index_by_name(char *name) +static s32 PerceptualParameters_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; - if (!strcmp("size", name)) return 3; - if (!strcmp("background", name)) return 4; - if (!strcmp("viewport", name)) return 5; + if (!strcmp("sourcePresence", name)) return 0; + if (!strcmp("sourceWarmth", name)) return 1; + if (!strcmp("sourceBrilliance", name)) return 2; + if (!strcmp("roomPresence", name)) return 3; + if (!strcmp("runningReverberance", name)) return 4; + if (!strcmp("envelopment", name)) return 5; + if (!strcmp("lateReverberance", name)) return 6; + if (!strcmp("heavyness", name)) return 7; + if (!strcmp("liveness", name)) return 8; + if (!strcmp("omniDirectivity", name)) return 9; + if (!strcmp("directFilterGains", name)) return 10; + if (!strcmp("inputFilterGains", name)) return 11; + if (!strcmp("refDistance", name)) return 12; + if (!strcmp("freqLow", name)) return 13; + if (!strcmp("freqHigh", name)) return 14; + if (!strcmp("timeLimit1", name)) return 15; + if (!strcmp("timeLimit2", name)) return 16; + if (!strcmp("timeLimit3", name)) return 17; + if (!strcmp("modalDensity", name)) return 18; return -1; } -static Bool Layer2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool PerceptualParameters_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 0: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 2: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; case 3: - *AType = 12; - *QType = 12; + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 5: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 8: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 9: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 10: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 11: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 12: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 13: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 14: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 15: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 16: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 17: + *AType = 0; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 18: + *AType = 0; + *QType = 0; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; @@ -6594,131 +21705,182 @@ static Bool Layer2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType -GF_Node *Layer2D_Create() +GF_Node *PerceptualParameters_Create() { - M_Layer2D *p; - GF_SAFEALLOC(p, M_Layer2D); + M_PerceptualParameters *p; + GF_SAFEALLOC(p, M_PerceptualParameters); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Layer2D); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_MPEG4_PerceptualParameters); /*default field values*/ - p->size.x = FLT2FIX(-1); - p->size.y = FLT2FIX(-1); + p->sourcePresence = FLT2FIX(1.0); + p->sourceWarmth = FLT2FIX(1.0); + p->sourceBrilliance = FLT2FIX(1.0); + p->roomPresence = FLT2FIX(1.0); + p->runningReverberance = FLT2FIX(1.0); + p->envelopment = FLT2FIX(0.0); + p->lateReverberance = FLT2FIX(1.0); + p->heavyness = FLT2FIX(1.0); + p->liveness = FLT2FIX(1.0); + p->omniDirectivity.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->omniDirectivity.count = 1; + p->omniDirectivity.vals[0] = FLT2FIX(1.0); + p->directFilterGains.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*3); + p->directFilterGains.count = 3; + p->directFilterGains.vals[0] = FLT2FIX(1.0); + p->directFilterGains.vals[1] = FLT2FIX(1.0); + p->directFilterGains.vals[2] = FLT2FIX(1.0); + p->inputFilterGains.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*3); + p->inputFilterGains.count = 3; + p->inputFilterGains.vals[0] = FLT2FIX(1.0); + p->inputFilterGains.vals[1] = FLT2FIX(1.0); + p->inputFilterGains.vals[2] = FLT2FIX(1.0); + p->refDistance = FLT2FIX(1.0); + p->freqLow = FLT2FIX(250.0); + p->freqHigh = FLT2FIX(4000.0); + p->timeLimit1 = 0.02; + p->timeLimit2 = 0.04; + p->timeLimit3 = 0.1; + p->modalDensity = 0.8; return (GF_Node *)p; } /* - Layer3D Node deletion + TemporalTransform Node deletion */ -static void Layer3D_Del(GF_Node *node) +static void TemporalTransform_Del(GF_Node *node) { - M_Layer3D *p = (M_Layer3D *) node; - gf_node_unregister((GF_Node *) p->background, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->fog, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->navigationInfo, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->viewpoint, (GF_Node *) p); + M_TemporalTransform *p = (M_TemporalTransform *) node; + gf_sg_mfurl_del(p->url); + gf_sg_mfint32_del(p->stretchMode); + gf_sg_mfint32_del(p->shrinkMode); gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Layer3D_Def2All[] = { 2, 3, 4, 5, 6, 7}; -static const u16 Layer3D_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static const u16 Layer3D_Out2All[] = { 2, 3, 4, 5, 6, 7}; -static const u16 Layer3D_Dyn2All[] = { 3}; +static const u16 TemporalTransform_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; +static const u16 TemporalTransform_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; +static const u16 TemporalTransform_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 TemporalTransform_Dyn2All[] = { 7, 8}; -static u32 Layer3D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 TemporalTransform_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 8; - case GF_SG_FIELD_CODING_DEF: return 6; - case GF_SG_FIELD_CODING_OUT: return 6; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_IN: return 12; + case GF_SG_FIELD_CODING_DEF: return 10; + case GF_SG_FIELD_CODING_OUT: return 11; + case GF_SG_FIELD_CODING_DYN: return 2; default: - return 8; + return 13; } } -static GF_Err Layer3D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err TemporalTransform_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Layer3D_In2All[inField]; + *allField = TemporalTransform_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Layer3D_Def2All[inField]; + *allField = TemporalTransform_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Layer3D_Out2All[inField]; + *allField = TemporalTransform_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = Layer3D_Dyn2All[inField]; + *allField = TemporalTransform_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Layer3D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err TemporalTransform_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: info->name = "addChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Layer3D *)node)->on_addChildren; + info->on_event_in = ((M_TemporalTransform *)node)->on_addChildren; info->fieldType = GF_SG_VRML_MFNODE; info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Layer3D *)node)->addChildren; + info->far_ptr = & ((M_TemporalTransform *)node)->addChildren; return GF_OK; case 1: info->name = "removeChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Layer3D *)node)->on_removeChildren; + info->on_event_in = ((M_TemporalTransform *)node)->on_removeChildren; info->fieldType = GF_SG_VRML_MFNODE; info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Layer3D *)node)->removeChildren; + info->far_ptr = & ((M_TemporalTransform *)node)->removeChildren; return GF_OK; case 2: info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFNODE; info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Layer3D *)node)->children; + info->far_ptr = & ((M_TemporalTransform *)node)->children; return GF_OK; case 3: - info->name = "size"; + info->name = "url"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Layer3D *) node)->size; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_TemporalTransform *) node)->url; return GF_OK; case 4: - info->name = "background"; + info->name = "startTime"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFBackground3DNode; - info->far_ptr = & ((M_Layer3D *)node)->background; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TemporalTransform *) node)->startTime; return GF_OK; case 5: - info->name = "fog"; + info->name = "optimalDuration"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFFogNode; - info->far_ptr = & ((M_Layer3D *)node)->fog; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TemporalTransform *) node)->optimalDuration; return GF_OK; case 6: - info->name = "navigationInfo"; + info->name = "active"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFNavigationInfoNode; - info->far_ptr = & ((M_Layer3D *)node)->navigationInfo; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_TemporalTransform *) node)->active; + return GF_OK; + case 7: + info->name = "speed"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_TemporalTransform *) node)->speed; + return GF_OK; + case 8: + info->name = "scalability"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_TemporalTransform *) node)->scalability; + return GF_OK; + case 9: + info->name = "stretchMode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_TemporalTransform *) node)->stretchMode; + return GF_OK; + case 10: + info->name = "shrinkMode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_TemporalTransform *) node)->shrinkMode; return GF_OK; - case 7: - info->name = "viewpoint"; + case 11: + info->name = "maxDelay"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFViewpointNode; - info->far_ptr = & ((M_Layer3D *)node)->viewpoint; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TemporalTransform *) node)->maxDelay; + return GF_OK; + case 12: + info->name = "actualDuration"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_TemporalTransform *) node)->actualDuration; return GF_OK; default: return GF_BAD_PARAM; @@ -6726,27 +21888,52 @@ static GF_Err Layer3D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Layer3D_get_field_index_by_name(char *name) +static s32 TemporalTransform_get_field_index_by_name(char *name) { if (!strcmp("addChildren", name)) return 0; if (!strcmp("removeChildren", name)) return 1; if (!strcmp("children", name)) return 2; - if (!strcmp("size", name)) return 3; - if (!strcmp("background", name)) return 4; - if (!strcmp("fog", name)) return 5; - if (!strcmp("navigationInfo", name)) return 6; - if (!strcmp("viewpoint", name)) return 7; + if (!strcmp("url", name)) return 3; + if (!strcmp("startTime", name)) return 4; + if (!strcmp("optimalDuration", name)) return 5; + if (!strcmp("active", name)) return 6; + if (!strcmp("speed", name)) return 7; + if (!strcmp("scalability", name)) return 8; + if (!strcmp("stretchMode", name)) return 9; + if (!strcmp("shrinkMode", name)) return 10; + if (!strcmp("maxDelay", name)) return 11; + if (!strcmp("actualDuration", name)) return 12; return -1; } -static Bool Layer3D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool TemporalTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 3: + case 7: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 8: *AType = 12; *QType = 12; - *b_min = FIX_MIN; + *b_min = FLT2FIX(-1); *b_max = FIX_MAX; return 1; + case 9: + *AType = 0; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(2); + return 1; + case 10: + *AType = 0; + *QType = 13; + *QT13_bits = 1; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; default: return 0; } @@ -6754,166 +21941,136 @@ static Bool Layer3D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType -GF_Node *Layer3D_Create() +GF_Node *TemporalTransform_Create() { - M_Layer3D *p; - GF_SAFEALLOC(p, M_Layer3D); + M_TemporalTransform *p; + GF_SAFEALLOC(p, M_TemporalTransform); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Layer3D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_TemporalTransform); gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->size.x = FLT2FIX(-1); - p->size.y = FLT2FIX(-1); + p->startTime = -1.0; + p->optimalDuration = -1.0; + p->speed = FLT2FIX(1.0); + p->scalability.x = FLT2FIX(1.0); + p->scalability.y = FLT2FIX(1.0); + p->stretchMode.vals = (SFInt32*)gf_malloc(sizeof(SFInt32)*1); + p->stretchMode.count = 1; + p->stretchMode.vals[0] = 0; + p->shrinkMode.vals = (SFInt32*)gf_malloc(sizeof(SFInt32)*1); + p->shrinkMode.count = 1; + p->shrinkMode.vals[0] = 0; + p->maxDelay = 0; return (GF_Node *)p; } /* - Layout Node deletion + TemporalGroup Node deletion */ -static void Layout_Del(GF_Node *node) +static void TemporalGroup_Del(GF_Node *node) { - M_Layout *p = (M_Layout *) node; - gf_sg_mfstring_del(p->justify); + M_TemporalGroup *p = (M_TemporalGroup *) node; + gf_sg_mffloat_del(p->priority); gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Layout_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; -static const u16 Layout_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; -static const u16 Layout_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; -static const u16 Layout_Dyn2All[] = { 4, 9, 13}; +static const u16 TemporalGroup_Def2All[] = { 2, 3, 4, 5, 6}; +static const u16 TemporalGroup_In2All[] = { 0, 1, 2, 6}; +static const u16 TemporalGroup_Out2All[] = { 2, 6, 7, 8}; -static u32 Layout_get_field_count(GF_Node *node, u8 IndexMode) +static u32 TemporalGroup_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 15; - case GF_SG_FIELD_CODING_DEF: return 13; - case GF_SG_FIELD_CODING_OUT: return 13; - case GF_SG_FIELD_CODING_DYN: return 3; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 15; + return 9; } } -static GF_Err Layout_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err TemporalGroup_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Layout_In2All[inField]; + *allField = TemporalGroup_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Layout_Def2All[inField]; + *allField = TemporalGroup_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Layout_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Layout_Dyn2All[inField]; + *allField = TemporalGroup_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Layout_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err TemporalGroup_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: info->name = "addChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Layout *)node)->on_addChildren; + info->on_event_in = ((M_TemporalGroup *)node)->on_addChildren; info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Layout *)node)->addChildren; + info->NDTtype = NDT_SFTemporalNode; + info->far_ptr = & ((M_TemporalGroup *)node)->addChildren; return GF_OK; case 1: info->name = "removeChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Layout *)node)->on_removeChildren; + info->on_event_in = ((M_TemporalGroup *)node)->on_removeChildren; info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Layout *)node)->removeChildren; + info->NDTtype = NDT_SFTemporalNode; + info->far_ptr = & ((M_TemporalGroup *)node)->removeChildren; return GF_OK; case 2: info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Layout *)node)->children; + info->NDTtype = NDT_SFTemporalNode; + info->far_ptr = & ((M_TemporalGroup *)node)->children; return GF_OK; case 3: - info->name = "wrap"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->name = "costart"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Layout *) node)->wrap; + info->far_ptr = & ((M_TemporalGroup *) node)->costart; return GF_OK; case 4: - info->name = "size"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Layout *) node)->size; + info->name = "coend"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_TemporalGroup *) node)->coend; return GF_OK; case 5: - info->name = "horizontal"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->name = "meet"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Layout *) node)->horizontal; + info->far_ptr = & ((M_TemporalGroup *) node)->meet; return GF_OK; case 6: - info->name = "justify"; + info->name = "priority"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_Layout *) node)->justify; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_TemporalGroup *) node)->priority; return GF_OK; case 7: - info->name = "leftToRight"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Layout *) node)->leftToRight; + info->far_ptr = & ((M_TemporalGroup *) node)->isActive; return GF_OK; case 8: - info->name = "topToBottom"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Layout *) node)->topToBottom; - return GF_OK; - case 9: - info->name = "spacing"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Layout *) node)->spacing; - return GF_OK; - case 10: - info->name = "smoothScroll"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Layout *) node)->smoothScroll; - return GF_OK; - case 11: - info->name = "loop"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Layout *) node)->loop; - return GF_OK; - case 12: - info->name = "scrollVertical"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Layout *) node)->scrollVertical; - return GF_OK; - case 13: - info->name = "scrollRate"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Layout *) node)->scrollRate; - return GF_OK; - case 14: - info->name = "scrollMode"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->name = "activeChild"; + info->eventType = GF_SG_EVENT_OUT; info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_Layout *) node)->scrollMode; + info->far_ptr = & ((M_TemporalGroup *) node)->activeChild; return GF_OK; default: return GF_BAD_PARAM; @@ -6921,52 +22078,27 @@ static GF_Err Layout_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Layout_get_field_index_by_name(char *name) +static s32 TemporalGroup_get_field_index_by_name(char *name) { if (!strcmp("addChildren", name)) return 0; if (!strcmp("removeChildren", name)) return 1; if (!strcmp("children", name)) return 2; - if (!strcmp("wrap", name)) return 3; - if (!strcmp("size", name)) return 4; - if (!strcmp("horizontal", name)) return 5; - if (!strcmp("justify", name)) return 6; - if (!strcmp("leftToRight", name)) return 7; - if (!strcmp("topToBottom", name)) return 8; - if (!strcmp("spacing", name)) return 9; - if (!strcmp("smoothScroll", name)) return 10; - if (!strcmp("loop", name)) return 11; - if (!strcmp("scrollVertical", name)) return 12; - if (!strcmp("scrollRate", name)) return 13; - if (!strcmp("scrollMode", name)) return 14; + if (!strcmp("costart", name)) return 3; + if (!strcmp("coend", name)) return 4; + if (!strcmp("meet", name)) return 5; + if (!strcmp("priority", name)) return 6; + if (!strcmp("isActive", name)) return 7; + if (!strcmp("activeChild", name)) return 8; return -1; } -static Bool Layout_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool TemporalGroup_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 4: - *AType = 12; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 9: - *AType = 7; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 13: - *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 14: - *AType = 0; - *QType = 13; - *QT13_bits = 2; - *b_min = FLT2FIX(-1); - *b_max = FLT2FIX(1); + case 6: + *AType = 0; + *QType = 3; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; return 1; default: return 0; @@ -6975,98 +22107,91 @@ static Bool Layout_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, -GF_Node *Layout_Create() +GF_Node *TemporalGroup_Create() { - M_Layout *p; - GF_SAFEALLOC(p, M_Layout); + M_TemporalGroup *p; + GF_SAFEALLOC(p, M_TemporalGroup); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Layout); + gf_node_setup((GF_Node *)p, TAG_MPEG4_TemporalGroup); gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->size.x = FLT2FIX(-1); - p->size.y = FLT2FIX(-1); - p->horizontal = 1; - p->justify.vals = (char**)malloc(sizeof(SFString)*1); - p->justify.count = 1; - p->justify.vals[0] = (char*)malloc(sizeof(char) * 6); - strcpy(p->justify.vals[0], "BEGIN"); - p->leftToRight = 1; - p->topToBottom = 1; - p->spacing = FLT2FIX(1); - p->scrollVertical = 1; - p->scrollRate = FLT2FIX(0); - p->scrollMode = 0; + p->costart = 1; return (GF_Node *)p; } /* - LineProperties Node deletion + ServerCommand Node deletion */ -static void LineProperties_Del(GF_Node *node) +static void ServerCommand_Del(GF_Node *node) { - M_LineProperties *p = (M_LineProperties *) node; + M_ServerCommand *p = (M_ServerCommand *) node; + gf_sg_mfurl_del(p->url); + gf_sg_sfstring_del(p->command); gf_node_free((GF_Node *) p); } -static const u16 LineProperties_Def2All[] = { 0, 1, 2}; -static const u16 LineProperties_In2All[] = { 0, 1, 2}; -static const u16 LineProperties_Out2All[] = { 0, 1, 2}; -static const u16 LineProperties_Dyn2All[] = { 0, 2}; +static const u16 ServerCommand_Def2All[] = { 1, 2, 3}; +static const u16 ServerCommand_In2All[] = { 0, 1, 2, 3}; +static const u16 ServerCommand_Out2All[] = { 1, 2, 3}; -static u32 LineProperties_get_field_count(GF_Node *node, u8 IndexMode) +static u32 ServerCommand_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_IN: return 4; case GF_SG_FIELD_CODING_DEF: return 3; case GF_SG_FIELD_CODING_OUT: return 3; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 3; + return 4; } } -static GF_Err LineProperties_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err ServerCommand_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = LineProperties_In2All[inField]; + *allField = ServerCommand_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = LineProperties_Def2All[inField]; + *allField = ServerCommand_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = LineProperties_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = LineProperties_Dyn2All[inField]; + *allField = ServerCommand_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err LineProperties_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err ServerCommand_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "lineColor"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_LineProperties *) node)->lineColor; + info->name = "trigger"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_ServerCommand *)node)->on_trigger; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ServerCommand *) node)->trigger; return GF_OK; case 1: - info->name = "lineStyle"; + info->name = "enable"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_LineProperties *) node)->lineStyle; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ServerCommand *) node)->enable; return GF_OK; case 2: - info->name = "width"; + info->name = "url"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_LineProperties *) node)->width; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_ServerCommand *) node)->url; + return GF_OK; + case 3: + info->name = "command"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_ServerCommand *) node)->command; return GF_OK; default: return GF_BAD_PARAM; @@ -7074,35 +22199,17 @@ static GF_Err LineProperties_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 LineProperties_get_field_index_by_name(char *name) +static s32 ServerCommand_get_field_index_by_name(char *name) { - if (!strcmp("lineColor", name)) return 0; - if (!strcmp("lineStyle", name)) return 1; - if (!strcmp("width", name)) return 2; + if (!strcmp("trigger", name)) return 0; + if (!strcmp("enable", name)) return 1; + if (!strcmp("url", name)) return 2; + if (!strcmp("command", name)) return 3; return -1; } -static Bool LineProperties_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool ServerCommand_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 4; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 1: - *AType = 0; - *QType = 13; - *QT13_bits = 3; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(5); - return 1; - case 2: - *AType = 7; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -7110,115 +22217,88 @@ static Bool LineProperties_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *LineProperties_Create() +GF_Node *ServerCommand_Create() { - M_LineProperties *p; - GF_SAFEALLOC(p, M_LineProperties); + M_ServerCommand *p; + GF_SAFEALLOC(p, M_ServerCommand); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_LineProperties); + gf_node_setup((GF_Node *)p, TAG_MPEG4_ServerCommand); /*default field values*/ - p->lineColor.red = FLT2FIX(0); - p->lineColor.green = FLT2FIX(0); - p->lineColor.blue = FLT2FIX(0); - p->lineStyle = 0; - p->width = FLT2FIX(1); return (GF_Node *)p; } /* - ListeningPoint Node deletion + InputSensor Node deletion */ -static void ListeningPoint_Del(GF_Node *node) +static void InputSensor_Del(GF_Node *node) { - M_ListeningPoint *p = (M_ListeningPoint *) node; - gf_sg_sfstring_del(p->description); + M_InputSensor *p = (M_InputSensor *) node; + gf_sg_sfcommand_del(p->buffer); + gf_sg_mfurl_del(p->url); gf_node_free((GF_Node *) p); } -static const u16 ListeningPoint_Def2All[] = { 1, 2, 3, 4}; -static const u16 ListeningPoint_In2All[] = { 0, 1, 2, 3}; -static const u16 ListeningPoint_Out2All[] = { 1, 2, 3, 5, 6}; -static const u16 ListeningPoint_Dyn2All[] = { 2, 3}; +static const u16 InputSensor_Def2All[] = { 0, 1, 2}; +static const u16 InputSensor_In2All[] = { 0, 1, 2}; +static const u16 InputSensor_Out2All[] = { 0, 1, 2, 3}; -static u32 ListeningPoint_get_field_count(GF_Node *node, u8 IndexMode) +static u32 InputSensor_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 4; - case GF_SG_FIELD_CODING_OUT: return 5; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 7; + return 4; } } -static GF_Err ListeningPoint_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err InputSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = ListeningPoint_In2All[inField]; + *allField = InputSensor_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = ListeningPoint_Def2All[inField]; + *allField = InputSensor_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = ListeningPoint_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = ListeningPoint_Dyn2All[inField]; + *allField = InputSensor_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err ListeningPoint_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err InputSensor_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_bind"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_ListeningPoint *)node)->on_set_bind; + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ListeningPoint *) node)->set_bind; + info->far_ptr = & ((M_InputSensor *) node)->enabled; return GF_OK; case 1: - info->name = "jump"; + info->name = "buffer"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ListeningPoint *) node)->jump; + info->fieldType = GF_SG_VRML_SFCOMMANDBUFFER; + info->far_ptr = & ((M_InputSensor *) node)->buffer; return GF_OK; case 2: - info->name = "orientation"; + info->name = "url"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_ListeningPoint *) node)->orientation; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_InputSensor *) node)->url; return GF_OK; case 3: - info->name = "position"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_ListeningPoint *) node)->position; - return GF_OK; - case 4: - info->name = "description"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_ListeningPoint *) node)->description; - return GF_OK; - case 5: - info->name = "bindTime"; + info->name = "eventTime"; info->eventType = GF_SG_EVENT_OUT; info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_ListeningPoint *) node)->bindTime; - return GF_OK; - case 6: - info->name = "isBound"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ListeningPoint *) node)->isBound; + info->far_ptr = & ((M_InputSensor *) node)->eventTime; return GF_OK; default: return GF_BAD_PARAM; @@ -7226,30 +22306,17 @@ static GF_Err ListeningPoint_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 ListeningPoint_get_field_index_by_name(char *name) +static s32 InputSensor_get_field_index_by_name(char *name) { - if (!strcmp("set_bind", name)) return 0; - if (!strcmp("jump", name)) return 1; - if (!strcmp("orientation", name)) return 2; - if (!strcmp("position", name)) return 3; - if (!strcmp("description", name)) return 4; - if (!strcmp("bindTime", name)) return 5; - if (!strcmp("isBound", name)) return 6; + if (!strcmp("enabled", name)) return 0; + if (!strcmp("buffer", name)) return 1; + if (!strcmp("url", name)) return 2; + if (!strcmp("eventTime", name)) return 3; return -1; } -static Bool ListeningPoint_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool InputSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 2: - *AType = 10; - *QType = 10; - return 1; - case 3: - *AType = 1; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -7257,110 +22324,114 @@ static Bool ListeningPoint_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *ListeningPoint_Create() +GF_Node *InputSensor_Create() { - M_ListeningPoint *p; - GF_SAFEALLOC(p, M_ListeningPoint); + M_InputSensor *p; + GF_SAFEALLOC(p, M_InputSensor); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_ListeningPoint); + gf_node_setup((GF_Node *)p, TAG_MPEG4_InputSensor); + p->buffer.commandList = gf_list_new(); - /*default field values*/ - p->jump = 1; - p->orientation.x = FLT2FIX(0); - p->orientation.y = FLT2FIX(0); - p->orientation.z = FLT2FIX(1); - p->orientation.q = FLT2FIX(0); - p->position.x = FLT2FIX(0); - p->position.y = FLT2FIX(0); - p->position.z = FLT2FIX(10); + /*default field values*/ + p->enabled = 1; return (GF_Node *)p; } /* - Material Node deletion + MatteTexture Node deletion */ -static void Material_Del(GF_Node *node) +static void MatteTexture_Del(GF_Node *node) { - M_Material *p = (M_Material *) node; + M_MatteTexture *p = (M_MatteTexture *) node; + gf_node_unregister((GF_Node *) p->surfaceA, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->surfaceB, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->alphaSurface, (GF_Node *) p); + gf_sg_sfstring_del(p->operation); + gf_sg_mffloat_del(p->parameter); gf_node_free((GF_Node *) p); } -static const u16 Material_Def2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 Material_In2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 Material_Out2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 Material_Dyn2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 MatteTexture_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 MatteTexture_In2All[] = { 3, 5, 6}; +static const u16 MatteTexture_Out2All[] = { 3, 5, 6}; -static u32 Material_get_field_count(GF_Node *node, u8 IndexMode) +static u32 MatteTexture_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 6; - case GF_SG_FIELD_CODING_DEF: return 6; - case GF_SG_FIELD_CODING_OUT: return 6; - case GF_SG_FIELD_CODING_DYN: return 6; + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 6; + return 7; } } -static GF_Err Material_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err MatteTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Material_In2All[inField]; + *allField = MatteTexture_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Material_Def2All[inField]; + *allField = MatteTexture_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Material_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Material_Dyn2All[inField]; + *allField = MatteTexture_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Material_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MatteTexture_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "ambientIntensity"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Material *) node)->ambientIntensity; + info->name = "surfaceA"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_MatteTexture *)node)->surfaceA; return GF_OK; case 1: - info->name = "diffuseColor"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_Material *) node)->diffuseColor; + info->name = "surfaceB"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_MatteTexture *)node)->surfaceB; return GF_OK; case 2: - info->name = "emissiveColor"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_Material *) node)->emissiveColor; + info->name = "alphaSurface"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_MatteTexture *)node)->alphaSurface; return GF_OK; case 3: - info->name = "shininess"; + info->name = "operation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Material *) node)->shininess; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_MatteTexture *) node)->operation; return GF_OK; case 4: - info->name = "specularColor"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_Material *) node)->specularColor; + info->name = "overwrite"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MatteTexture *) node)->overwrite; return GF_OK; case 5: - info->name = "transparency"; + info->name = "fraction"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Material *) node)->transparency; + info->far_ptr = & ((M_MatteTexture *) node)->fraction; + return GF_OK; + case 6: + info->name = "parameter"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_MatteTexture *) node)->parameter; return GF_OK; default: return GF_BAD_PARAM; @@ -7368,55 +22439,20 @@ static GF_Err Material_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Material_get_field_index_by_name(char *name) +static s32 MatteTexture_get_field_index_by_name(char *name) { - if (!strcmp("ambientIntensity", name)) return 0; - if (!strcmp("diffuseColor", name)) return 1; - if (!strcmp("emissiveColor", name)) return 2; - if (!strcmp("shininess", name)) return 3; - if (!strcmp("specularColor", name)) return 4; - if (!strcmp("transparency", name)) return 5; + if (!strcmp("surfaceA", name)) return 0; + if (!strcmp("surfaceB", name)) return 1; + if (!strcmp("alphaSurface", name)) return 2; + if (!strcmp("operation", name)) return 3; + if (!strcmp("overwrite", name)) return 4; + if (!strcmp("fraction", name)) return 5; + if (!strcmp("parameter", name)) return 6; return -1; } -static Bool Material_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool MatteTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 1: - *AType = 4; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 2: - *AType = 4; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 3: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 4: - *AType = 4; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 5: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; default: return 0; } @@ -7424,104 +22460,103 @@ static Bool Material_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATyp -GF_Node *Material_Create() +GF_Node *MatteTexture_Create() { - M_Material *p; - GF_SAFEALLOC(p, M_Material); + M_MatteTexture *p; + GF_SAFEALLOC(p, M_MatteTexture); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Material); + gf_node_setup((GF_Node *)p, TAG_MPEG4_MatteTexture); /*default field values*/ - p->ambientIntensity = FLT2FIX(0.2); - p->diffuseColor.red = FLT2FIX(0.8); - p->diffuseColor.green = FLT2FIX(0.8); - p->diffuseColor.blue = FLT2FIX(0.8); - p->emissiveColor.red = FLT2FIX(0); - p->emissiveColor.green = FLT2FIX(0); - p->emissiveColor.blue = FLT2FIX(0); - p->shininess = FLT2FIX(0.2); - p->specularColor.red = FLT2FIX(0); - p->specularColor.green = FLT2FIX(0); - p->specularColor.blue = FLT2FIX(0); - p->transparency = FLT2FIX(0); + p->fraction = FLT2FIX(0); + p->parameter.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->parameter.count = 1; + p->parameter.vals[0] = FLT2FIX(0); return (GF_Node *)p; } /* - Material2D Node deletion + MediaBuffer Node deletion */ -static void Material2D_Del(GF_Node *node) +static void MediaBuffer_Del(GF_Node *node) { - M_Material2D *p = (M_Material2D *) node; - gf_node_unregister((GF_Node *) p->lineProps, (GF_Node *) p); + M_MediaBuffer *p = (M_MediaBuffer *) node; + gf_sg_mfurl_del(p->url); gf_node_free((GF_Node *) p); } -static const u16 Material2D_Def2All[] = { 0, 1, 2, 3}; -static const u16 Material2D_In2All[] = { 0, 1, 2, 3}; -static const u16 Material2D_Out2All[] = { 0, 1, 2, 3}; -static const u16 Material2D_Dyn2All[] = { 0, 3}; +static const u16 MediaBuffer_Def2All[] = { 0, 1, 2, 3, 5}; +static const u16 MediaBuffer_In2All[] = { 0, 1, 2, 3, 5}; +static const u16 MediaBuffer_Out2All[] = { 0, 1, 2, 3, 4, 5}; -static u32 Material2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 MediaBuffer_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 4; - case GF_SG_FIELD_CODING_OUT: return 4; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 4; + return 6; } } -static GF_Err Material2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err MediaBuffer_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Material2D_In2All[inField]; + *allField = MediaBuffer_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Material2D_Def2All[inField]; + *allField = MediaBuffer_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Material2D_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Material2D_Dyn2All[inField]; + *allField = MediaBuffer_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Material2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MediaBuffer_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "emissiveColor"; + info->name = "bufferSize"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_Material2D *) node)->emissiveColor; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_MediaBuffer *) node)->bufferSize; return GF_OK; case 1: - info->name = "filled"; + info->name = "url"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Material2D *) node)->filled; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_MediaBuffer *) node)->url; return GF_OK; case 2: - info->name = "lineProps"; + info->name = "mediaStartTime"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFLinePropertiesNode; - info->far_ptr = & ((M_Material2D *)node)->lineProps; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MediaBuffer *) node)->mediaStartTime; return GF_OK; case 3: - info->name = "transparency"; + info->name = "mediaStopTime"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Material2D *) node)->transparency; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MediaBuffer *) node)->mediaStopTime; + return GF_OK; + case 4: + info->name = "isBuffered"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MediaBuffer *) node)->isBuffered; + return GF_OK; + case 5: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MediaBuffer *) node)->enabled; return GF_OK; default: return GF_BAD_PARAM; @@ -7529,29 +22564,19 @@ static GF_Err Material2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Material2D_get_field_index_by_name(char *name) +static s32 MediaBuffer_get_field_index_by_name(char *name) { - if (!strcmp("emissiveColor", name)) return 0; - if (!strcmp("filled", name)) return 1; - if (!strcmp("lineProps", name)) return 2; - if (!strcmp("transparency", name)) return 3; + if (!strcmp("bufferSize", name)) return 0; + if (!strcmp("url", name)) return 1; + if (!strcmp("mediaStartTime", name)) return 2; + if (!strcmp("mediaStopTime", name)) return 3; + if (!strcmp("isBuffered", name)) return 4; + if (!strcmp("enabled", name)) return 5; return -1; } -static Bool Material2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool MediaBuffer_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 4; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 3: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; default: return 0; } @@ -7559,125 +22584,121 @@ static Bool Material2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AT -GF_Node *Material2D_Create() +GF_Node *MediaBuffer_Create() { - M_Material2D *p; - GF_SAFEALLOC(p, M_Material2D); + M_MediaBuffer *p; + GF_SAFEALLOC(p, M_MediaBuffer); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Material2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_MediaBuffer); /*default field values*/ - p->emissiveColor.red = FLT2FIX(0.8); - p->emissiveColor.green = FLT2FIX(0.8); - p->emissiveColor.blue = FLT2FIX(0.8); - p->transparency = FLT2FIX(0); + p->bufferSize = FLT2FIX(0.0); + p->mediaStartTime = -1; + p->mediaStopTime = FIX_MAX; + p->enabled = 1; return (GF_Node *)p; } /* - MovieTexture Node deletion + MediaControl Node deletion */ -static void MovieTexture_Del(GF_Node *node) +static void MediaControl_Del(GF_Node *node) { - M_MovieTexture *p = (M_MovieTexture *) node; + M_MediaControl *p = (M_MediaControl *) node; gf_sg_mfurl_del(p->url); gf_node_free((GF_Node *) p); } -static const u16 MovieTexture_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 MovieTexture_In2All[] = { 0, 1, 2, 3, 4}; -static const u16 MovieTexture_Out2All[] = { 0, 1, 2, 3, 4, 7, 8}; -static const u16 MovieTexture_Dyn2All[] = { 1}; +static const u16 MediaControl_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 MediaControl_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 MediaControl_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; -static u32 MovieTexture_get_field_count(GF_Node *node, u8 IndexMode) +static u32 MediaControl_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 5; - case GF_SG_FIELD_CODING_DEF: return 7; - case GF_SG_FIELD_CODING_OUT: return 7; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_IN: return 8; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 9; + case GF_SG_FIELD_CODING_DYN: return 0; default: return 9; } } -static GF_Err MovieTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err MediaControl_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = MovieTexture_In2All[inField]; + *allField = MediaControl_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = MovieTexture_Def2All[inField]; + *allField = MediaControl_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = MovieTexture_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = MovieTexture_Dyn2All[inField]; + *allField = MediaControl_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err MovieTexture_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MediaControl_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "loop"; + info->name = "url"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MovieTexture *) node)->loop; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_MediaControl *) node)->url; return GF_OK; case 1: - info->name = "speed"; + info->name = "mediaStartTime"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_MovieTexture *) node)->speed; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MediaControl *) node)->mediaStartTime; return GF_OK; case 2: - info->name = "startTime"; + info->name = "mediaStopTime"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MovieTexture *) node)->startTime; + info->far_ptr = & ((M_MediaControl *) node)->mediaStopTime; return GF_OK; case 3: - info->name = "stopTime"; + info->name = "mediaSpeed"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MovieTexture *) node)->stopTime; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_MediaControl *) node)->mediaSpeed; return GF_OK; case 4: - info->name = "url"; + info->name = "loop"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_MovieTexture *) node)->url; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MediaControl *) node)->loop; return GF_OK; case 5: - info->name = "repeatS"; - info->eventType = GF_SG_EVENT_FIELD; + info->name = "preRoll"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MovieTexture *) node)->repeatS; + info->far_ptr = & ((M_MediaControl *) node)->preRoll; return GF_OK; case 6: - info->name = "repeatT"; - info->eventType = GF_SG_EVENT_FIELD; + info->name = "mute"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MovieTexture *) node)->repeatT; + info->far_ptr = & ((M_MediaControl *) node)->mute; return GF_OK; case 7: - info->name = "duration_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MovieTexture *) node)->duration_changed; + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MediaControl *) node)->enabled; return GF_OK; case 8: - info->name = "isActive"; + info->name = "isPreRolled"; info->eventType = GF_SG_EVENT_OUT; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MovieTexture *) node)->isActive; + info->far_ptr = & ((M_MediaControl *) node)->isPreRolled; return GF_OK; default: return GF_BAD_PARAM; @@ -7685,28 +22706,22 @@ static GF_Err MovieTexture_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MovieTexture_get_field_index_by_name(char *name) +static s32 MediaControl_get_field_index_by_name(char *name) { - if (!strcmp("loop", name)) return 0; - if (!strcmp("speed", name)) return 1; - if (!strcmp("startTime", name)) return 2; - if (!strcmp("stopTime", name)) return 3; - if (!strcmp("url", name)) return 4; - if (!strcmp("repeatS", name)) return 5; - if (!strcmp("repeatT", name)) return 6; - if (!strcmp("duration_changed", name)) return 7; - if (!strcmp("isActive", name)) return 8; + if (!strcmp("url", name)) return 0; + if (!strcmp("mediaStartTime", name)) return 1; + if (!strcmp("mediaStopTime", name)) return 2; + if (!strcmp("mediaSpeed", name)) return 3; + if (!strcmp("loop", name)) return 4; + if (!strcmp("preRoll", name)) return 5; + if (!strcmp("mute", name)) return 6; + if (!strcmp("enabled", name)) return 7; + if (!strcmp("isPreRolled", name)) return 8; return -1; } -static Bool MovieTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool MediaControl_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -7714,116 +22729,105 @@ static Bool MovieTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 * -GF_Node *MovieTexture_Create() +GF_Node *MediaControl_Create() { - M_MovieTexture *p; - GF_SAFEALLOC(p, M_MovieTexture); + M_MediaControl *p; + GF_SAFEALLOC(p, M_MediaControl); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_MovieTexture); + gf_node_setup((GF_Node *)p, TAG_MPEG4_MediaControl); /*default field values*/ - p->speed = FLT2FIX(1.0); - p->startTime = 0; - p->stopTime = 0; - p->repeatS = 1; - p->repeatT = 1; + p->mediaStartTime = -1; + p->mediaStopTime = FIX_MAX; + p->mediaSpeed = FLT2FIX(1.0); + p->preRoll = 1; + p->enabled = 1; return (GF_Node *)p; } /* - NavigationInfo Node deletion + MediaSensor Node deletion */ -static void NavigationInfo_Del(GF_Node *node) +static void MediaSensor_Del(GF_Node *node) { - M_NavigationInfo *p = (M_NavigationInfo *) node; - gf_sg_mffloat_del(p->avatarSize); - gf_sg_mfstring_del(p->type); + M_MediaSensor *p = (M_MediaSensor *) node; + gf_sg_mfurl_del(p->url); + gf_sg_mfstring_del(p->info); gf_node_free((GF_Node *) p); } -static const u16 NavigationInfo_Def2All[] = { 1, 2, 3, 4, 5}; -static const u16 NavigationInfo_In2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 NavigationInfo_Out2All[] = { 1, 2, 3, 4, 5, 6}; -static const u16 NavigationInfo_Dyn2All[] = { 5}; +static const u16 MediaSensor_Def2All[] = { 0}; +static const u16 MediaSensor_In2All[] = { 0}; +static const u16 MediaSensor_Out2All[] = { 0, 1, 2, 3, 4, 5}; -static u32 NavigationInfo_get_field_count(GF_Node *node, u8 IndexMode) +static u32 MediaSensor_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 6; - case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 1; case GF_SG_FIELD_CODING_OUT: return 6; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 7; + return 6; } } -static GF_Err NavigationInfo_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err MediaSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = NavigationInfo_In2All[inField]; + *allField = MediaSensor_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = NavigationInfo_Def2All[inField]; + *allField = MediaSensor_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = NavigationInfo_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = NavigationInfo_Dyn2All[inField]; + *allField = MediaSensor_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err NavigationInfo_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MediaSensor_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_bind"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_NavigationInfo *)node)->on_set_bind; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_NavigationInfo *) node)->set_bind; + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_MediaSensor *) node)->url; return GF_OK; case 1: - info->name = "avatarSize"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_NavigationInfo *) node)->avatarSize; + info->name = "mediaCurrentTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MediaSensor *) node)->mediaCurrentTime; return GF_OK; case 2: - info->name = "headlight"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_NavigationInfo *) node)->headlight; + info->name = "streamObjectStartTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MediaSensor *) node)->streamObjectStartTime; return GF_OK; case 3: - info->name = "speed"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_NavigationInfo *) node)->speed; + info->name = "mediaDuration"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MediaSensor *) node)->mediaDuration; return GF_OK; case 4: - info->name = "type"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_NavigationInfo *) node)->type; - return GF_OK; - case 5: - info->name = "visibilityLimit"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_NavigationInfo *) node)->visibilityLimit; - return GF_OK; - case 6: - info->name = "isBound"; + info->name = "isActive"; info->eventType = GF_SG_EVENT_OUT; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_NavigationInfo *) node)->isBound; + info->far_ptr = & ((M_MediaSensor *) node)->isActive; + return GF_OK; + case 5: + info->name = "info"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_MediaSensor *) node)->info; return GF_OK; default: return GF_BAD_PARAM; @@ -7831,38 +22835,19 @@ static GF_Err NavigationInfo_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 NavigationInfo_get_field_index_by_name(char *name) +static s32 MediaSensor_get_field_index_by_name(char *name) { - if (!strcmp("set_bind", name)) return 0; - if (!strcmp("avatarSize", name)) return 1; - if (!strcmp("headlight", name)) return 2; - if (!strcmp("speed", name)) return 3; - if (!strcmp("type", name)) return 4; - if (!strcmp("visibilityLimit", name)) return 5; - if (!strcmp("isBound", name)) return 6; + if (!strcmp("url", name)) return 0; + if (!strcmp("mediaCurrentTime", name)) return 1; + if (!strcmp("streamObjectStartTime", name)) return 2; + if (!strcmp("mediaDuration", name)) return 3; + if (!strcmp("isActive", name)) return 4; + if (!strcmp("info", name)) return 5; return -1; } -static Bool NavigationInfo_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool MediaSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 0; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 3: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 5: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -7870,87 +22855,82 @@ static Bool NavigationInfo_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *NavigationInfo_Create() +GF_Node *MediaSensor_Create() { - M_NavigationInfo *p; - GF_SAFEALLOC(p, M_NavigationInfo); + M_MediaSensor *p; + GF_SAFEALLOC(p, M_MediaSensor); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_NavigationInfo); + gf_node_setup((GF_Node *)p, TAG_MPEG4_MediaSensor); /*default field values*/ - p->avatarSize.vals = (SFFloat*)malloc(sizeof(SFFloat)*3); - p->avatarSize.count = 3; - p->avatarSize.vals[0] = FLT2FIX(0.25); - p->avatarSize.vals[1] = FLT2FIX(1.6); - p->avatarSize.vals[2] = FLT2FIX(0.75); - p->headlight = 1; - p->speed = FLT2FIX(1.0); - p->type.vals = (char**)malloc(sizeof(SFString)*2); - p->type.count = 2; - p->type.vals[0] = (char*)malloc(sizeof(char) * 5); - strcpy(p->type.vals[0], "WALK"); - p->type.vals[1] = (char*)malloc(sizeof(char) * 4); - strcpy(p->type.vals[1], "ANY"); - p->visibilityLimit = FLT2FIX(0.0); return (GF_Node *)p; } /* - Normal Node deletion + BitWrapper Node deletion */ -static void Normal_Del(GF_Node *node) +static void BitWrapper_Del(GF_Node *node) { - M_Normal *p = (M_Normal *) node; - gf_sg_mfvec3f_del(p->vector); + M_BitWrapper *p = (M_BitWrapper *) node; + gf_node_unregister((GF_Node *) p->node, (GF_Node *) p); + gf_sg_mfurl_del(p->url); + gf_sg_sfstring_del(p->buffer); gf_node_free((GF_Node *) p); } -static const u16 Normal_Def2All[] = { 0}; -static const u16 Normal_In2All[] = { 0}; -static const u16 Normal_Out2All[] = { 0}; -static const u16 Normal_Dyn2All[] = { 0}; +static const u16 BitWrapper_Def2All[] = { 0, 1, 2, 3}; -static u32 Normal_get_field_count(GF_Node *node, u8 IndexMode) +static u32 BitWrapper_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 1; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 1; + return 4; } } -static GF_Err Normal_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err BitWrapper_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = Normal_In2All[inField]; - return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Normal_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = Normal_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Normal_Dyn2All[inField]; + *allField = BitWrapper_Def2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Normal_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err BitWrapper_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "vector"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((M_Normal *) node)->vector; + info->name = "node"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFWorldNode; + info->far_ptr = & ((M_BitWrapper *)node)->node; + return GF_OK; + case 1: + info->name = "type"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BitWrapper *) node)->type; + return GF_OK; + case 2: + info->name = "url"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_BitWrapper *) node)->url; + return GF_OK; + case 3: + info->name = "buffer"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_BitWrapper *) node)->buffer; return GF_OK; default: return GF_BAD_PARAM; @@ -7958,18 +22938,17 @@ static GF_Err Normal_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Normal_get_field_index_by_name(char *name) +static s32 BitWrapper_get_field_index_by_name(char *name) { - if (!strcmp("vector", name)) return 0; + if (!strcmp("node", name)) return 0; + if (!strcmp("type", name)) return 1; + if (!strcmp("url", name)) return 2; + if (!strcmp("buffer", name)) return 3; return -1; } -static Bool Normal_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool BitWrapper_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 9; - *QType = 9; - return 1; default: return 0; } @@ -7977,36 +22956,37 @@ static Bool Normal_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, -GF_Node *Normal_Create() +GF_Node *BitWrapper_Create() { - M_Normal *p; - GF_SAFEALLOC(p, M_Normal); + M_BitWrapper *p; + GF_SAFEALLOC(p, M_BitWrapper); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Normal); + gf_node_setup((GF_Node *)p, TAG_MPEG4_BitWrapper); /*default field values*/ + p->type = 0; return (GF_Node *)p; } /* - NormalInterpolator Node deletion + CoordinateInterpolator4D Node deletion */ -static void NormalInterpolator_Del(GF_Node *node) +static void CoordinateInterpolator4D_Del(GF_Node *node) { - M_NormalInterpolator *p = (M_NormalInterpolator *) node; + M_CoordinateInterpolator4D *p = (M_CoordinateInterpolator4D *) node; gf_sg_mffloat_del(p->key); - gf_sg_mfvec3f_del(p->keyValue); - gf_sg_mfvec3f_del(p->value_changed); + gf_sg_mfvec4f_del(p->keyValue); + gf_sg_mfvec4f_del(p->value_changed); gf_node_free((GF_Node *) p); } -static const u16 NormalInterpolator_Def2All[] = { 1, 2}; -static const u16 NormalInterpolator_In2All[] = { 0, 1, 2}; -static const u16 NormalInterpolator_Out2All[] = { 1, 2, 3}; +static const u16 CoordinateInterpolator4D_Def2All[] = { 1, 2}; +static const u16 CoordinateInterpolator4D_In2All[] = { 0, 1, 2}; +static const u16 CoordinateInterpolator4D_Out2All[] = { 1, 2, 3}; -static u32 NormalInterpolator_get_field_count(GF_Node *node, u8 IndexMode) +static u32 CoordinateInterpolator4D_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: return 3; @@ -8018,49 +22998,49 @@ static u32 NormalInterpolator_get_field_count(GF_Node *node, u8 IndexMode) } } -static GF_Err NormalInterpolator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err CoordinateInterpolator4D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = NormalInterpolator_In2All[inField]; + *allField = CoordinateInterpolator4D_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = NormalInterpolator_Def2All[inField]; + *allField = CoordinateInterpolator4D_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = NormalInterpolator_Out2All[inField]; + *allField = CoordinateInterpolator4D_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err NormalInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err CoordinateInterpolator4D_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: info->name = "set_fraction"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_NormalInterpolator *)node)->on_set_fraction; + info->on_event_in = ((M_CoordinateInterpolator4D *)node)->on_set_fraction; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_NormalInterpolator *) node)->set_fraction; + info->far_ptr = & ((M_CoordinateInterpolator4D *) node)->set_fraction; return GF_OK; case 1: info->name = "key"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_NormalInterpolator *) node)->key; + info->far_ptr = & ((M_CoordinateInterpolator4D *) node)->key; return GF_OK; case 2: info->name = "keyValue"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((M_NormalInterpolator *) node)->keyValue; + info->fieldType = GF_SG_VRML_MFVEC4F; + info->far_ptr = & ((M_CoordinateInterpolator4D *) node)->keyValue; return GF_OK; case 3: info->name = "value_changed"; info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((M_NormalInterpolator *) node)->value_changed; + info->fieldType = GF_SG_VRML_MFVEC4F; + info->far_ptr = & ((M_CoordinateInterpolator4D *) node)->value_changed; return GF_OK; default: return GF_BAD_PARAM; @@ -8068,7 +23048,7 @@ static GF_Err NormalInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 NormalInterpolator_get_field_index_by_name(char *name) +static s32 CoordinateInterpolator4D_get_field_index_by_name(char *name) { if (!strcmp("set_fraction", name)) return 0; if (!strcmp("key", name)) return 1; @@ -8076,7 +23056,7 @@ static s32 NormalInterpolator_get_field_index_by_name(char *name) if (!strcmp("value_changed", name)) return 3; return -1; } -static Bool NormalInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool CoordinateInterpolator4D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { case 1: @@ -8087,7 +23067,7 @@ static Bool NormalInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType return 1; case 2: *AType = 0; - *QType = 9; + *QType = 15; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; @@ -8098,93 +23078,286 @@ static Bool NormalInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType -GF_Node *NormalInterpolator_Create() +GF_Node *CoordinateInterpolator4D_Create() +{ + M_CoordinateInterpolator4D *p; + GF_SAFEALLOC(p, M_CoordinateInterpolator4D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_CoordinateInterpolator4D); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + DepthImage Node deletion +*/ + +static void DepthImage_Del(GF_Node *node) +{ + M_DepthImage *p = (M_DepthImage *) node; + gf_node_unregister((GF_Node *) p->diTexture, (GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 DepthImage_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; + +static u32 DepthImage_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 7; + } +} + +static GF_Err DepthImage_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_DEF: + *allField = DepthImage_Def2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err DepthImage_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "diTexture"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFDepthTextureNode; + info->far_ptr = & ((M_DepthImage *)node)->diTexture; + return GF_OK; + case 1: + info->name = "farPlane"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_DepthImage *) node)->farPlane; + return GF_OK; + case 2: + info->name = "fieldOfView"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_DepthImage *) node)->fieldOfView; + return GF_OK; + case 3: + info->name = "nearPlane"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_DepthImage *) node)->nearPlane; + return GF_OK; + case 4: + info->name = "orientation"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_DepthImage *) node)->orientation; + return GF_OK; + case 5: + info->name = "orthographic"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_DepthImage *) node)->orthographic; + return GF_OK; + case 6: + info->name = "position"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_DepthImage *) node)->position; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 DepthImage_get_field_index_by_name(char *name) +{ + if (!strcmp("diTexture", name)) return 0; + if (!strcmp("farPlane", name)) return 1; + if (!strcmp("fieldOfView", name)) return 2; + if (!strcmp("nearPlane", name)) return 3; + if (!strcmp("orientation", name)) return 4; + if (!strcmp("orthographic", name)) return 5; + if (!strcmp("position", name)) return 6; + return -1; + } +static Bool DepthImage_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *DepthImage_Create() { - M_NormalInterpolator *p; - GF_SAFEALLOC(p, M_NormalInterpolator); + M_DepthImage *p; + GF_SAFEALLOC(p, M_DepthImage); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_NormalInterpolator); + gf_node_setup((GF_Node *)p, TAG_MPEG4_DepthImage); /*default field values*/ + p->farPlane = FLT2FIX(100); + p->fieldOfView.x = FLT2FIX(0.785398); + p->fieldOfView.y = FLT2FIX(0.785398); + p->nearPlane = FLT2FIX(10); + p->orientation.x = FLT2FIX(0); + p->orientation.y = FLT2FIX(0); + p->orientation.z = FLT2FIX(1); + p->orientation.q = FLT2FIX(0); + p->orthographic = 1; + p->position.x = FLT2FIX(0); + p->position.y = FLT2FIX(0); + p->position.z = FLT2FIX(10); return (GF_Node *)p; } /* - OrderedGroup Node deletion + FFD Node deletion */ -static void OrderedGroup_Del(GF_Node *node) +static void FFD_Del(GF_Node *node) { - M_OrderedGroup *p = (M_OrderedGroup *) node; - gf_sg_mffloat_del(p->order); + M_FFD *p = (M_FFD *) node; + gf_sg_mfvec4f_del(p->controlPoint); + gf_sg_mffloat_del(p->uKnot); + gf_sg_mffloat_del(p->vKnot); + gf_sg_mffloat_del(p->wKnot); gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 OrderedGroup_Def2All[] = { 2, 3}; -static const u16 OrderedGroup_In2All[] = { 0, 1, 2, 3}; -static const u16 OrderedGroup_Out2All[] = { 2, 3}; +static const u16 FFD_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 FFD_In2All[] = { 0, 1, 2, 3}; +static const u16 FFD_Out2All[] = { 2, 3}; +static const u16 FFD_Dyn2All[] = { 3}; -static u32 OrderedGroup_get_field_count(GF_Node *node, u8 IndexMode) +static u32 FFD_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_DEF: return 11; case GF_SG_FIELD_CODING_OUT: return 2; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_DYN: return 1; default: - return 4; + return 13; } } -static GF_Err OrderedGroup_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err FFD_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = OrderedGroup_In2All[inField]; + *allField = FFD_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = OrderedGroup_Def2All[inField]; + *allField = FFD_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = OrderedGroup_Out2All[inField]; + *allField = FFD_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = FFD_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err OrderedGroup_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err FFD_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: info->name = "addChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_OrderedGroup *)node)->on_addChildren; + info->on_event_in = ((M_FFD *)node)->on_addChildren; info->fieldType = GF_SG_VRML_MFNODE; info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_OrderedGroup *)node)->addChildren; + info->far_ptr = & ((M_FFD *)node)->addChildren; return GF_OK; case 1: info->name = "removeChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_OrderedGroup *)node)->on_removeChildren; + info->on_event_in = ((M_FFD *)node)->on_removeChildren; info->fieldType = GF_SG_VRML_MFNODE; info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_OrderedGroup *)node)->removeChildren; + info->far_ptr = & ((M_FFD *)node)->removeChildren; return GF_OK; case 2: info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFNODE; info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_OrderedGroup *)node)->children; + info->far_ptr = & ((M_FFD *)node)->children; return GF_OK; case 3: - info->name = "order"; + info->name = "controlPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC4F; + info->far_ptr = & ((M_FFD *) node)->controlPoint; + return GF_OK; + case 4: + info->name = "uDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FFD *) node)->uDimension; + return GF_OK; + case 5: + info->name = "uKnot"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_OrderedGroup *) node)->order; + info->far_ptr = & ((M_FFD *) node)->uKnot; + return GF_OK; + case 6: + info->name = "uOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FFD *) node)->uOrder; + return GF_OK; + case 7: + info->name = "vDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FFD *) node)->vDimension; + return GF_OK; + case 8: + info->name = "vKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_FFD *) node)->vKnot; + return GF_OK; + case 9: + info->name = "vOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FFD *) node)->vOrder; + return GF_OK; + case 10: + info->name = "wDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FFD *) node)->wDimension; + return GF_OK; + case 11: + info->name = "wKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_FFD *) node)->wKnot; + return GF_OK; + case 12: + info->name = "wOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FFD *) node)->wOrder; return GF_OK; default: return GF_BAD_PARAM; @@ -8192,23 +23365,74 @@ static GF_Err OrderedGroup_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 OrderedGroup_get_field_index_by_name(char *name) +static s32 FFD_get_field_index_by_name(char *name) { if (!strcmp("addChildren", name)) return 0; if (!strcmp("removeChildren", name)) return 1; if (!strcmp("children", name)) return 2; - if (!strcmp("order", name)) return 3; + if (!strcmp("controlPoint", name)) return 3; + if (!strcmp("uDimension", name)) return 4; + if (!strcmp("uKnot", name)) return 5; + if (!strcmp("uOrder", name)) return 6; + if (!strcmp("vDimension", name)) return 7; + if (!strcmp("vKnot", name)) return 8; + if (!strcmp("vOrder", name)) return 9; + if (!strcmp("wDimension", name)) return 10; + if (!strcmp("wKnot", name)) return 11; + if (!strcmp("wOrder", name)) return 12; return -1; } -static Bool OrderedGroup_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool FFD_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { case 3: - *AType = 0; - *QType = 3; - *b_min = FLT2FIX(0); + *AType = 15; + *QType = 15; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; + case 4: + *AType = 0; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(2); + *b_max = FLT2FIX(257); + return 1; + case 6: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(2); + *b_max = FLT2FIX(33); + return 1; + case 7: + *AType = 0; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(2); + *b_max = FLT2FIX(257); + return 1; + case 9: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(2); + *b_max = FLT2FIX(33); + return 1; + case 10: + *AType = 0; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(2); + *b_max = FLT2FIX(257); + return 1; + case 12: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(2); + *b_max = FLT2FIX(33); + return 1; default: return 0; } @@ -8216,90 +23440,105 @@ static Bool OrderedGroup_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 * -GF_Node *OrderedGroup_Create() +GF_Node *FFD_Create() { - M_OrderedGroup *p; - GF_SAFEALLOC(p, M_OrderedGroup); + M_FFD *p; + GF_SAFEALLOC(p, M_FFD); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_OrderedGroup); + gf_node_setup((GF_Node *)p, TAG_MPEG4_FFD); gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ + p->uDimension = 2; + p->uOrder = 2; + p->vDimension = 2; + p->vOrder = 2; + p->wDimension = 2; + p->wOrder = 2; return (GF_Node *)p; } /* - OrientationInterpolator Node deletion + Implicit Node deletion */ -static void OrientationInterpolator_Del(GF_Node *node) +static void Implicit_Del(GF_Node *node) { - M_OrientationInterpolator *p = (M_OrientationInterpolator *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfrotation_del(p->keyValue); + M_Implicit *p = (M_Implicit *) node; + gf_sg_mffloat_del(p->c); + gf_sg_mfint32_del(p->densities); gf_node_free((GF_Node *) p); } -static const u16 OrientationInterpolator_Def2All[] = { 1, 2}; -static const u16 OrientationInterpolator_In2All[] = { 0, 1, 2}; -static const u16 OrientationInterpolator_Out2All[] = { 1, 2, 3}; +static const u16 Implicit_Def2All[] = { 0, 1, 2, 3, 4}; +static const u16 Implicit_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 Implicit_Out2All[] = { 0, 1, 2, 3, 4}; +static const u16 Implicit_Dyn2All[] = { 0, 1}; -static u32 OrientationInterpolator_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Implicit_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 3; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_DYN: return 2; default: - return 4; + return 5; } } -static GF_Err OrientationInterpolator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Implicit_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = OrientationInterpolator_In2All[inField]; + *allField = Implicit_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = OrientationInterpolator_Def2All[inField]; + *allField = Implicit_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = OrientationInterpolator_Out2All[inField]; + *allField = Implicit_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Implicit_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err OrientationInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Implicit_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_fraction"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_OrientationInterpolator *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_OrientationInterpolator *) node)->set_fraction; + info->name = "bboxSize"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Implicit *) node)->bboxSize; return GF_OK; case 1: - info->name = "key"; + info->name = "c"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_OrientationInterpolator *) node)->key; + info->far_ptr = & ((M_Implicit *) node)->c; return GF_OK; case 2: - info->name = "keyValue"; + info->name = "densities"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFROTATION; - info->far_ptr = & ((M_OrientationInterpolator *) node)->keyValue; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_Implicit *) node)->densities; return GF_OK; case 3: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_OrientationInterpolator *) node)->value_changed; + info->name = "dual"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Implicit *) node)->dual; + return GF_OK; + case 4: + info->name = "solid"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Implicit *) node)->solid; return GF_OK; default: return GF_BAD_PARAM; @@ -8307,26 +23546,27 @@ static GF_Err OrientationInterpolator_get_field(GF_Node *node, GF_FieldInfo *inf } -static s32 OrientationInterpolator_get_field_index_by_name(char *name) +static s32 Implicit_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("key", name)) return 1; - if (!strcmp("keyValue", name)) return 2; - if (!strcmp("value_changed", name)) return 3; + if (!strcmp("bboxSize", name)) return 0; + if (!strcmp("c", name)) return 1; + if (!strcmp("densities", name)) return 2; + if (!strcmp("dual", name)) return 3; + if (!strcmp("solid", name)) return 4; return -1; } -static Bool OrientationInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool Implicit_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 0; - *QType = 8; + case 0: + *AType = 11; + *QType = 11; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *b_max = FIX_MAX; return 1; - case 2: - *AType = 0; - *QType = 10; + case 1: + *AType = 7; + *QType = 0; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; @@ -8337,81 +23577,97 @@ static Bool OrientationInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 * -GF_Node *OrientationInterpolator_Create() +GF_Node *Implicit_Create() { - M_OrientationInterpolator *p; - GF_SAFEALLOC(p, M_OrientationInterpolator); + M_Implicit *p; + GF_SAFEALLOC(p, M_Implicit); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_OrientationInterpolator); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Implicit); /*default field values*/ + p->bboxSize.x = FLT2FIX(2); + p->bboxSize.y = FLT2FIX(2); + p->bboxSize.z = FLT2FIX(2); return (GF_Node *)p; } /* - PixelTexture Node deletion + XXLFM_Appearance Node deletion */ -static void PixelTexture_Del(GF_Node *node) +static void XXLFM_Appearance_Del(GF_Node *node) { - M_PixelTexture *p = (M_PixelTexture *) node; - gf_sg_sfimage_del(p->image); + M_XXLFM_Appearance *p = (M_XXLFM_Appearance *) node; + gf_node_unregister((GF_Node *) p->blendList, (GF_Node *) p); + gf_node_unregister_children((GF_Node *) p, p->lightMapList); + gf_node_unregister_children((GF_Node *) p, p->tileList); + gf_node_unregister((GF_Node *) p->vertexFrameList, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 PixelTexture_Def2All[] = { 0, 1, 2}; -static const u16 PixelTexture_In2All[] = { 0}; -static const u16 PixelTexture_Out2All[] = { 0}; +static const u16 XXLFM_Appearance_Def2All[] = { 0, 1, 2, 3}; +static const u16 XXLFM_Appearance_In2All[] = { 0, 1, 2, 3}; +static const u16 XXLFM_Appearance_Out2All[] = { 0, 1, 2, 3}; -static u32 PixelTexture_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XXLFM_Appearance_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 3; + return 4; } } -static GF_Err PixelTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XXLFM_Appearance_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PixelTexture_In2All[inField]; + *allField = XXLFM_Appearance_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PixelTexture_Def2All[inField]; + *allField = XXLFM_Appearance_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PixelTexture_Out2All[inField]; + *allField = XXLFM_Appearance_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PixelTexture_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XXLFM_Appearance_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "image"; + info->name = "blendList"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFIMAGE; - info->far_ptr = & ((M_PixelTexture *) node)->image; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFBlendListNode; + info->far_ptr = & ((M_XXLFM_Appearance *)node)->blendList; return GF_OK; case 1: - info->name = "repeatS"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PixelTexture *) node)->repeatS; + info->name = "lightMapList"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFLightMapNode; + info->far_ptr = & ((M_XXLFM_Appearance *)node)->lightMapList; return GF_OK; case 2: - info->name = "repeatT"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PixelTexture *) node)->repeatT; + info->name = "tileList"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_XXLFM_Appearance *)node)->tileList; + return GF_OK; + case 3: + info->name = "vertexFrameList"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFFrameListNode; + info->far_ptr = & ((M_XXLFM_Appearance *)node)->vertexFrameList; return GF_OK; default: return GF_BAD_PARAM; @@ -8419,20 +23675,17 @@ static GF_Err PixelTexture_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PixelTexture_get_field_index_by_name(char *name) +static s32 XXLFM_Appearance_get_field_index_by_name(char *name) { - if (!strcmp("image", name)) return 0; - if (!strcmp("repeatS", name)) return 1; - if (!strcmp("repeatT", name)) return 2; + if (!strcmp("blendList", name)) return 0; + if (!strcmp("lightMapList", name)) return 1; + if (!strcmp("tileList", name)) return 2; + if (!strcmp("vertexFrameList", name)) return 3; return -1; } -static Bool PixelTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XXLFM_Appearance_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 0; - *QType = 0; - return 1; default: return 0; } @@ -8440,112 +23693,76 @@ static Bool PixelTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 * -GF_Node *PixelTexture_Create() +GF_Node *XXLFM_Appearance_Create() { - M_PixelTexture *p; - GF_SAFEALLOC(p, M_PixelTexture); + M_XXLFM_Appearance *p; + GF_SAFEALLOC(p, M_XXLFM_Appearance); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PixelTexture); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXLFM_Appearance); /*default field values*/ - p->repeatS = 1; - p->repeatT = 1; return (GF_Node *)p; } /* - PlaneSensor Node deletion + XXLFM_BlendList Node deletion */ -static void PlaneSensor_Del(GF_Node *node) +static void XXLFM_BlendList_Del(GF_Node *node) { - M_PlaneSensor *p = (M_PlaneSensor *) node; + M_XXLFM_BlendList *p = (M_XXLFM_BlendList *) node; + gf_sg_mfint32_del(p->blendMode); + gf_sg_mfint32_del(p->lightMapIndex); gf_node_free((GF_Node *) p); } -static const u16 PlaneSensor_Def2All[] = { 0, 1, 2, 3, 4}; -static const u16 PlaneSensor_In2All[] = { 0, 1, 2, 3, 4}; -static const u16 PlaneSensor_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 XXLFM_BlendList_Def2All[] = { 0, 1}; +static const u16 XXLFM_BlendList_In2All[] = { 0, 1}; +static const u16 XXLFM_BlendList_Out2All[] = { 0, 1}; -static u32 PlaneSensor_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XXLFM_BlendList_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 5; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 8; + return 2; } } -static GF_Err PlaneSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XXLFM_BlendList_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PlaneSensor_In2All[inField]; + *allField = XXLFM_BlendList_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PlaneSensor_Def2All[inField]; + *allField = XXLFM_BlendList_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PlaneSensor_Out2All[inField]; + *allField = XXLFM_BlendList_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PlaneSensor_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XXLFM_BlendList_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "autoOffset"; + info->name = "blendMode"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PlaneSensor *) node)->autoOffset; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XXLFM_BlendList *) node)->blendMode; return GF_OK; case 1: - info->name = "enabled"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PlaneSensor *) node)->enabled; - return GF_OK; - case 2: - info->name = "maxPosition"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PlaneSensor *) node)->maxPosition; - return GF_OK; - case 3: - info->name = "minPosition"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PlaneSensor *) node)->minPosition; - return GF_OK; - case 4: - info->name = "offset"; + info->name = "lightMapIndex"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_PlaneSensor *) node)->offset; - return GF_OK; - case 5: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PlaneSensor *) node)->isActive; - return GF_OK; - case 6: - info->name = "trackPoint_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_PlaneSensor *) node)->trackPoint_changed; - return GF_OK; - case 7: - info->name = "translation_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_PlaneSensor *) node)->translation_changed; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XXLFM_BlendList *) node)->lightMapIndex; return GF_OK; default: return GF_BAD_PARAM; @@ -8553,38 +23770,25 @@ static GF_Err PlaneSensor_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PlaneSensor_get_field_index_by_name(char *name) +static s32 XXLFM_BlendList_get_field_index_by_name(char *name) { - if (!strcmp("autoOffset", name)) return 0; - if (!strcmp("enabled", name)) return 1; - if (!strcmp("maxPosition", name)) return 2; - if (!strcmp("minPosition", name)) return 3; - if (!strcmp("offset", name)) return 4; - if (!strcmp("isActive", name)) return 5; - if (!strcmp("trackPoint_changed", name)) return 6; - if (!strcmp("translation_changed", name)) return 7; + if (!strcmp("blendMode", name)) return 0; + if (!strcmp("lightMapIndex", name)) return 1; return -1; } -static Bool PlaneSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XXLFM_BlendList_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 2: - *AType = 0; - *QType = 2; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 3: + case 0: *AType = 0; - *QType = 2; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 13; + *QT13_bits = 1; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); return 1; - case 4: + case 1: *AType = 0; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 14; return 1; default: return 0; @@ -8593,119 +23797,76 @@ static Bool PlaneSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *A -GF_Node *PlaneSensor_Create() +GF_Node *XXLFM_BlendList_Create() { - M_PlaneSensor *p; - GF_SAFEALLOC(p, M_PlaneSensor); + M_XXLFM_BlendList *p; + GF_SAFEALLOC(p, M_XXLFM_BlendList); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PlaneSensor); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXLFM_BlendList); /*default field values*/ - p->autoOffset = 1; - p->enabled = 1; - p->maxPosition.x = FLT2FIX(-1); - p->maxPosition.y = FLT2FIX(-1); - p->minPosition.x = FLT2FIX(0); - p->minPosition.y = FLT2FIX(0); - p->offset.x = FLT2FIX(0); - p->offset.y = FLT2FIX(0); - p->offset.z = FLT2FIX(0); return (GF_Node *)p; } /* - PlaneSensor2D Node deletion + XXLFM_FrameList Node deletion */ -static void PlaneSensor2D_Del(GF_Node *node) +static void XXLFM_FrameList_Del(GF_Node *node) { - M_PlaneSensor2D *p = (M_PlaneSensor2D *) node; + M_XXLFM_FrameList *p = (M_XXLFM_FrameList *) node; + gf_sg_mfint32_del(p->index); + gf_sg_mfvec3f_del(p->frame); gf_node_free((GF_Node *) p); } -static const u16 PlaneSensor2D_Def2All[] = { 0, 1, 2, 3, 4}; -static const u16 PlaneSensor2D_In2All[] = { 0, 1, 2, 3, 4}; -static const u16 PlaneSensor2D_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 XXLFM_FrameList_Def2All[] = { 0, 1}; +static const u16 XXLFM_FrameList_In2All[] = { 0, 1}; +static const u16 XXLFM_FrameList_Out2All[] = { 0, 1}; -static u32 PlaneSensor2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XXLFM_FrameList_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 5; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 8; + return 2; } } -static GF_Err PlaneSensor2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XXLFM_FrameList_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PlaneSensor2D_In2All[inField]; + *allField = XXLFM_FrameList_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PlaneSensor2D_Def2All[inField]; + *allField = XXLFM_FrameList_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PlaneSensor2D_Out2All[inField]; + *allField = XXLFM_FrameList_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PlaneSensor2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XXLFM_FrameList_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "autoOffset"; + info->name = "index"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PlaneSensor2D *) node)->autoOffset; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XXLFM_FrameList *) node)->index; return GF_OK; case 1: - info->name = "enabled"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PlaneSensor2D *) node)->enabled; - return GF_OK; - case 2: - info->name = "maxPosition"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PlaneSensor2D *) node)->maxPosition; - return GF_OK; - case 3: - info->name = "minPosition"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PlaneSensor2D *) node)->minPosition; - return GF_OK; - case 4: - info->name = "offset"; + info->name = "frame"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PlaneSensor2D *) node)->offset; - return GF_OK; - case 5: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PlaneSensor2D *) node)->isActive; - return GF_OK; - case 6: - info->name = "trackPoint_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PlaneSensor2D *) node)->trackPoint_changed; - return GF_OK; - case 7: - info->name = "translation_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PlaneSensor2D *) node)->translation_changed; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_XXLFM_FrameList *) node)->frame; return GF_OK; default: return GF_BAD_PARAM; @@ -8713,38 +23874,24 @@ static GF_Err PlaneSensor2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PlaneSensor2D_get_field_index_by_name(char *name) +static s32 XXLFM_FrameList_get_field_index_by_name(char *name) { - if (!strcmp("autoOffset", name)) return 0; - if (!strcmp("enabled", name)) return 1; - if (!strcmp("maxPosition", name)) return 2; - if (!strcmp("minPosition", name)) return 3; - if (!strcmp("offset", name)) return 4; - if (!strcmp("isActive", name)) return 5; - if (!strcmp("trackPoint_changed", name)) return 6; - if (!strcmp("translation_changed", name)) return 7; + if (!strcmp("index", name)) return 0; + if (!strcmp("frame", name)) return 1; return -1; } -static Bool PlaneSensor2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XXLFM_FrameList_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 2: - *AType = 0; - *QType = 2; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 3: + case 0: *AType = 0; - *QType = 2; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 14; return 1; - case 4: + case 1: *AType = 0; - *QType = 12; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 1; + *b_min = FLT2FIX(-1); + *b_max = FLT2FIX(1); return 1; default: return 0; @@ -8753,116 +23900,110 @@ static Bool PlaneSensor2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *PlaneSensor2D_Create() +GF_Node *XXLFM_FrameList_Create() { - M_PlaneSensor2D *p; - GF_SAFEALLOC(p, M_PlaneSensor2D); + M_XXLFM_FrameList *p; + GF_SAFEALLOC(p, M_XXLFM_FrameList); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PlaneSensor2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXLFM_FrameList); /*default field values*/ - p->autoOffset = 1; - p->enabled = 1; - p->maxPosition.x = FLT2FIX(0); - p->maxPosition.y = FLT2FIX(0); - p->minPosition.x = FLT2FIX(0); - p->minPosition.y = FLT2FIX(0); - p->offset.x = FLT2FIX(0); - p->offset.y = FLT2FIX(0); + p->index.vals = (SFInt32*)gf_malloc(sizeof(SFInt32)*1); + p->index.count = 1; + p->index.vals[0] = -1; + p->frame.vals = (SFVec3f *)gf_malloc(sizeof(SFVec3f)*3); + p->frame.count = 3; + p->frame.vals[0].x = FLT2FIX(1); + p->frame.vals[0].y = FLT2FIX(0); + p->frame.vals[0].z = FLT2FIX(0); + p->frame.vals[1].x = FLT2FIX(0); + p->frame.vals[1].y = FLT2FIX(1); + p->frame.vals[1].z = FLT2FIX(0); + p->frame.vals[2].x = FLT2FIX(0); + p->frame.vals[2].y = FLT2FIX(0); + p->frame.vals[2].z = FLT2FIX(1); return (GF_Node *)p; } /* - PointLight Node deletion + XXLFM_LightMap Node deletion */ -static void PointLight_Del(GF_Node *node) +static void XXLFM_LightMap_Del(GF_Node *node) { - M_PointLight *p = (M_PointLight *) node; + M_XXLFM_LightMap *p = (M_XXLFM_LightMap *) node; + gf_node_unregister((GF_Node *) p->surfaceMapList, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->viewMapList, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 PointLight_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 PointLight_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 PointLight_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 PointLight_Dyn2All[] = { 0, 1, 2, 3, 4, 6}; +static const u16 XXLFM_LightMap_Def2All[] = { 0, 1, 2, 3, 4}; +static const u16 XXLFM_LightMap_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 XXLFM_LightMap_Out2All[] = { 0, 1, 2, 3, 4}; -static u32 PointLight_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XXLFM_LightMap_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 7; - case GF_SG_FIELD_CODING_DEF: return 7; - case GF_SG_FIELD_CODING_OUT: return 7; - case GF_SG_FIELD_CODING_DYN: return 6; + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 7; + return 5; } } -static GF_Err PointLight_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XXLFM_LightMap_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PointLight_In2All[inField]; + *allField = XXLFM_LightMap_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PointLight_Def2All[inField]; + *allField = XXLFM_LightMap_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PointLight_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = PointLight_Dyn2All[inField]; + *allField = XXLFM_LightMap_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PointLight_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XXLFM_LightMap_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "ambientIntensity"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PointLight *) node)->ambientIntensity; - return GF_OK; - case 1: - info->name = "attenuation"; + info->name = "biasRGB"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_PointLight *) node)->attenuation; + info->far_ptr = & ((M_XXLFM_LightMap *) node)->biasRGB; return GF_OK; - case 2: - info->name = "color"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_PointLight *) node)->color; - return GF_OK; - case 3: - info->name = "intensity"; + case 1: + info->name = "priorityLevel"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PointLight *) node)->intensity; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_XXLFM_LightMap *) node)->priorityLevel; return GF_OK; - case 4: - info->name = "location"; + case 2: + info->name = "scaleRGB"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_PointLight *) node)->location; + info->far_ptr = & ((M_XXLFM_LightMap *) node)->scaleRGB; return GF_OK; - case 5: - info->name = "on"; + case 3: + info->name = "surfaceMapList"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PointLight *) node)->on; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFSurfaceMapNode; + info->far_ptr = & ((M_XXLFM_LightMap *)node)->surfaceMapList; return GF_OK; - case 6: - info->name = "radius"; + case 4: + info->name = "viewMapList"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PointLight *) node)->radius; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFViewMapNode; + info->far_ptr = & ((M_XXLFM_LightMap *)node)->viewMapList; return GF_OK; default: return GF_BAD_PARAM; @@ -8870,56 +24011,37 @@ static GF_Err PointLight_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PointLight_get_field_index_by_name(char *name) +static s32 XXLFM_LightMap_get_field_index_by_name(char *name) { - if (!strcmp("ambientIntensity", name)) return 0; - if (!strcmp("attenuation", name)) return 1; - if (!strcmp("color", name)) return 2; - if (!strcmp("intensity", name)) return 3; - if (!strcmp("location", name)) return 4; - if (!strcmp("on", name)) return 5; - if (!strcmp("radius", name)) return 6; + if (!strcmp("biasRGB", name)) return 0; + if (!strcmp("priorityLevel", name)) return 1; + if (!strcmp("scaleRGB", name)) return 2; + if (!strcmp("surfaceMapList", name)) return 3; + if (!strcmp("viewMapList", name)) return 4; return -1; } -static Bool PointLight_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XXLFM_LightMap_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { case 0: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); + *AType = 0; + *QType = 7; + *b_min = FLT2FIX(-1); *b_max = FLT2FIX(1); return 1; case 1: - *AType = 1; - *QType = 11; + *AType = 0; + *QType = 13; + *QT13_bits = 8; *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + *b_max = FLT2FIX(255); return 1; case 2: - *AType = 4; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 3: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); + *AType = 0; + *QType = 7; + *b_min = FLT2FIX(-1); *b_max = FLT2FIX(1); return 1; - case 4: - *AType = 1; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 6: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -8927,91 +24049,98 @@ static Bool PointLight_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AT -GF_Node *PointLight_Create() +GF_Node *XXLFM_LightMap_Create() { - M_PointLight *p; - GF_SAFEALLOC(p, M_PointLight); + M_XXLFM_LightMap *p; + GF_SAFEALLOC(p, M_XXLFM_LightMap); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PointLight); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXLFM_LightMap); /*default field values*/ - p->ambientIntensity = FLT2FIX(0); - p->attenuation.x = FLT2FIX(1); - p->attenuation.y = FLT2FIX(0); - p->attenuation.z = FLT2FIX(0); - p->color.red = FLT2FIX(1); - p->color.green = FLT2FIX(1); - p->color.blue = FLT2FIX(1); - p->intensity = FLT2FIX(1); - p->location.x = FLT2FIX(0); - p->location.y = FLT2FIX(0); - p->location.z = FLT2FIX(0); - p->on = 1; - p->radius = FLT2FIX(100); + p->biasRGB.x = FLT2FIX(0); + p->biasRGB.y = FLT2FIX(0); + p->biasRGB.z = FLT2FIX(0); + p->priorityLevel = 0; + p->scaleRGB.x = FLT2FIX(1); + p->scaleRGB.y = FLT2FIX(1); + p->scaleRGB.z = FLT2FIX(1); return (GF_Node *)p; } /* - PointSet Node deletion + XXLFM_SurfaceMapList Node deletion */ -static void PointSet_Del(GF_Node *node) +static void XXLFM_SurfaceMapList_Del(GF_Node *node) { - M_PointSet *p = (M_PointSet *) node; - gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + M_XXLFM_SurfaceMapList *p = (M_XXLFM_SurfaceMapList *) node; + gf_sg_mfint32_del(p->tileIndex); + gf_node_unregister((GF_Node *) p->triangleCoordinate, (GF_Node *) p); + gf_sg_mfint32_del(p->triangleIndex); + gf_sg_mfint32_del(p->viewMapIndex); gf_node_free((GF_Node *) p); } -static const u16 PointSet_Def2All[] = { 0, 1}; -static const u16 PointSet_In2All[] = { 0, 1}; -static const u16 PointSet_Out2All[] = { 0, 1}; +static const u16 XXLFM_SurfaceMapList_Def2All[] = { 0, 1, 2, 3}; +static const u16 XXLFM_SurfaceMapList_In2All[] = { 0, 1, 2, 3}; +static const u16 XXLFM_SurfaceMapList_Out2All[] = { 0, 1, 2, 3}; -static u32 PointSet_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XXLFM_SurfaceMapList_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 2; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 2; + return 4; } } -static GF_Err PointSet_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XXLFM_SurfaceMapList_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PointSet_In2All[inField]; + *allField = XXLFM_SurfaceMapList_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PointSet_Def2All[inField]; + *allField = XXLFM_SurfaceMapList_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PointSet_Out2All[inField]; + *allField = XXLFM_SurfaceMapList_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PointSet_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XXLFM_SurfaceMapList_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "color"; + info->name = "tileIndex"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((M_PointSet *)node)->color; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XXLFM_SurfaceMapList *) node)->tileIndex; return GF_OK; case 1: - info->name = "coord"; + info->name = "triangleCoordinate"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinateNode; - info->far_ptr = & ((M_PointSet *)node)->coord; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((M_XXLFM_SurfaceMapList *)node)->triangleCoordinate; + return GF_OK; + case 2: + info->name = "triangleIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XXLFM_SurfaceMapList *) node)->triangleIndex; + return GF_OK; + case 3: + info->name = "viewMapIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XXLFM_SurfaceMapList *) node)->viewMapIndex; return GF_OK; default: return GF_BAD_PARAM; @@ -9019,15 +24148,29 @@ static GF_Err PointSet_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PointSet_get_field_index_by_name(char *name) +static s32 XXLFM_SurfaceMapList_get_field_index_by_name(char *name) { - if (!strcmp("color", name)) return 0; - if (!strcmp("coord", name)) return 1; + if (!strcmp("tileIndex", name)) return 0; + if (!strcmp("triangleCoordinate", name)) return 1; + if (!strcmp("triangleIndex", name)) return 2; + if (!strcmp("viewMapIndex", name)) return 3; return -1; } -static Bool PointSet_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XXLFM_SurfaceMapList_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 14; + return 1; + case 2: + *AType = 0; + *QType = 14; + return 1; + case 3: + *AType = 0; + *QType = 14; + return 1; default: return 0; } @@ -9035,12 +24178,12 @@ static Bool PointSet_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATyp -GF_Node *PointSet_Create() +GF_Node *XXLFM_SurfaceMapList_Create() { - M_PointSet *p; - GF_SAFEALLOC(p, M_PointSet); + M_XXLFM_SurfaceMapList *p; + GF_SAFEALLOC(p, M_XXLFM_SurfaceMapList); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PointSet); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXLFM_SurfaceMapList); /*default field values*/ return (GF_Node *)p; @@ -9048,65 +24191,79 @@ GF_Node *PointSet_Create() /* - PointSet2D Node deletion + XXLFM_ViewMapList Node deletion */ -static void PointSet2D_Del(GF_Node *node) +static void XXLFM_ViewMapList_Del(GF_Node *node) { - M_PointSet2D *p = (M_PointSet2D *) node; - gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + M_XXLFM_ViewMapList *p = (M_XXLFM_ViewMapList *) node; + gf_node_unregister((GF_Node *) p->textureOrigin, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->textureSize, (GF_Node *) p); + gf_sg_mfint32_del(p->tileIndex); + gf_sg_mfint32_del(p->vertexIndex); gf_node_free((GF_Node *) p); } -static const u16 PointSet2D_Def2All[] = { 0, 1}; -static const u16 PointSet2D_In2All[] = { 0, 1}; -static const u16 PointSet2D_Out2All[] = { 0, 1}; +static const u16 XXLFM_ViewMapList_Def2All[] = { 0, 1, 2, 3}; +static const u16 XXLFM_ViewMapList_In2All[] = { 0, 1, 2, 3}; +static const u16 XXLFM_ViewMapList_Out2All[] = { 0, 1, 2, 3}; -static u32 PointSet2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XXLFM_ViewMapList_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 2; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 2; + return 4; } } -static GF_Err PointSet2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XXLFM_ViewMapList_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PointSet2D_In2All[inField]; + *allField = XXLFM_ViewMapList_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PointSet2D_Def2All[inField]; + *allField = XXLFM_ViewMapList_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PointSet2D_Out2All[inField]; + *allField = XXLFM_ViewMapList_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PointSet2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XXLFM_ViewMapList_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "color"; + info->name = "textureOrigin"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((M_PointSet2D *)node)->color; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((M_XXLFM_ViewMapList *)node)->textureOrigin; return GF_OK; case 1: - info->name = "coord"; + info->name = "textureSize"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinate2DNode; - info->far_ptr = & ((M_PointSet2D *)node)->coord; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((M_XXLFM_ViewMapList *)node)->textureSize; + return GF_OK; + case 2: + info->name = "tileIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XXLFM_ViewMapList *) node)->tileIndex; + return GF_OK; + case 3: + info->name = "vertexIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XXLFM_ViewMapList *) node)->vertexIndex; return GF_OK; default: return GF_BAD_PARAM; @@ -9114,15 +24271,25 @@ static GF_Err PointSet2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PointSet2D_get_field_index_by_name(char *name) +static s32 XXLFM_ViewMapList_get_field_index_by_name(char *name) { - if (!strcmp("color", name)) return 0; - if (!strcmp("coord", name)) return 1; + if (!strcmp("textureOrigin", name)) return 0; + if (!strcmp("textureSize", name)) return 1; + if (!strcmp("tileIndex", name)) return 2; + if (!strcmp("vertexIndex", name)) return 3; return -1; } -static Bool PointSet2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XXLFM_ViewMapList_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 2: + *AType = 0; + *QType = 14; + return 1; + case 3: + *AType = 0; + *QType = 14; + return 1; default: return 0; } @@ -9130,12 +24297,12 @@ static Bool PointSet2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AT -GF_Node *PointSet2D_Create() +GF_Node *XXLFM_ViewMapList_Create() { - M_PointSet2D *p; - GF_SAFEALLOC(p, M_PointSet2D); + M_XXLFM_ViewMapList *p; + GF_SAFEALLOC(p, M_XXLFM_ViewMapList); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PointSet2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXLFM_ViewMapList); /*default field values*/ return (GF_Node *)p; @@ -9143,76 +24310,218 @@ GF_Node *PointSet2D_Create() /* - PositionInterpolator Node deletion + MeshGrid Node deletion */ -static void PositionInterpolator_Del(GF_Node *node) +static void MeshGrid_Del(GF_Node *node) { - M_PositionInterpolator *p = (M_PositionInterpolator *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfvec3f_del(p->keyValue); + M_MeshGrid *p = (M_MeshGrid *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_sg_mfint32_del(p->set_coordIndex); + gf_sg_mfint32_del(p->set_normalIndex); + gf_sg_mfint32_del(p->set_texCoordIndex); + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->gridCoord, (GF_Node *) p); + gf_sg_mfint32_del(p->nLevels); + gf_node_unregister((GF_Node *) p->normal, (GF_Node *) p); + gf_sg_mfint32_del(p->nSlices); + gf_node_unregister((GF_Node *) p->texCoord, (GF_Node *) p); + gf_sg_mffloat_del(p->vertexOffset); + gf_sg_mfint32_del(p->vertexLink); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mfint32_del(p->coordIndex); + gf_sg_mfint32_del(p->normalIndex); + gf_sg_mfint32_del(p->texCoordIndex); + gf_sg_mfint32_del(p->nVertices); gf_node_free((GF_Node *) p); } -static const u16 PositionInterpolator_Def2All[] = { 1, 2}; -static const u16 PositionInterpolator_In2All[] = { 0, 1, 2}; -static const u16 PositionInterpolator_Out2All[] = { 1, 2, 3}; +static const u16 MeshGrid_Def2All[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; +static const u16 MeshGrid_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; +static const u16 MeshGrid_Out2All[] = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 21, 22}; +static const u16 MeshGrid_Dyn2All[] = { 6, 7, 9, 10, 12, 14}; -static u32 PositionInterpolator_get_field_count(GF_Node *node, u8 IndexMode) +static u32 MeshGrid_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 3; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 16; + case GF_SG_FIELD_CODING_DEF: return 17; + case GF_SG_FIELD_CODING_OUT: return 14; + case GF_SG_FIELD_CODING_DYN: return 6; default: - return 4; + return 23; } } -static GF_Err PositionInterpolator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err MeshGrid_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PositionInterpolator_In2All[inField]; + *allField = MeshGrid_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = MeshGrid_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = MeshGrid_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = MeshGrid_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err MeshGrid_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_MeshGrid *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->set_colorIndex; + return GF_OK; + case 1: + info->name = "set_coordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_MeshGrid *)node)->on_set_coordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->set_coordIndex; + return GF_OK; + case 2: + info->name = "set_normalIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_MeshGrid *)node)->on_set_normalIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->set_normalIndex; + return GF_OK; + case 3: + info->name = "set_texCoordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_MeshGrid *)node)->on_set_texCoordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->set_texCoordIndex; return GF_OK; - case GF_SG_FIELD_CODING_DEF: - *allField = PositionInterpolator_Def2All[inField]; + case 4: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_MeshGrid *)node)->color; return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = PositionInterpolator_Out2All[inField]; + case 5: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((M_MeshGrid *)node)->coord; return GF_OK; - default: - return GF_BAD_PARAM; - } -} -static GF_Err PositionInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) -{ - switch (info->fieldIndex) { - case 0: - info->name = "set_fraction"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_PositionInterpolator *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PositionInterpolator *) node)->set_fraction; + case 6: + info->name = "displayLevel"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->displayLevel; return GF_OK; - case 1: - info->name = "key"; + case 7: + info->name = "filterType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->filterType; + return GF_OK; + case 8: + info->name = "gridCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((M_MeshGrid *)node)->gridCoord; + return GF_OK; + case 9: + info->name = "hierarchicalLevel"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->hierarchicalLevel; + return GF_OK; + case 10: + info->name = "nLevels"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->nLevels; + return GF_OK; + case 11: + info->name = "normal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((M_MeshGrid *)node)->normal; + return GF_OK; + case 12: + info->name = "nSlices"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->nSlices; + return GF_OK; + case 13: + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((M_MeshGrid *)node)->texCoord; + return GF_OK; + case 14: + info->name = "vertexOffset"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PositionInterpolator *) node)->key; + info->far_ptr = & ((M_MeshGrid *) node)->vertexOffset; return GF_OK; - case 2: - info->name = "keyValue"; + case 15: + info->name = "vertexLink"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((M_PositionInterpolator *) node)->keyValue; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->vertexLink; return GF_OK; - case 3: - info->name = "value_changed"; + case 16: + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->colorIndex; + return GF_OK; + case 17: + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->coordIndex; + return GF_OK; + case 18: + info->name = "normalIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->normalIndex; + return GF_OK; + case 19: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MeshGrid *) node)->solid; + return GF_OK; + case 20: + info->name = "texCoordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->texCoordIndex; + return GF_OK; + case 21: + info->name = "isLoading"; info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_PositionInterpolator *) node)->value_changed; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MeshGrid *) node)->isLoading; + return GF_OK; + case 22: + info->name = "nVertices"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MeshGrid *) node)->nVertices; return GF_OK; default: return GF_BAD_PARAM; @@ -9220,27 +24529,100 @@ static GF_Err PositionInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PositionInterpolator_get_field_index_by_name(char *name) +static s32 MeshGrid_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("key", name)) return 1; - if (!strcmp("keyValue", name)) return 2; - if (!strcmp("value_changed", name)) return 3; + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("set_coordIndex", name)) return 1; + if (!strcmp("set_normalIndex", name)) return 2; + if (!strcmp("set_texCoordIndex", name)) return 3; + if (!strcmp("color", name)) return 4; + if (!strcmp("coord", name)) return 5; + if (!strcmp("displayLevel", name)) return 6; + if (!strcmp("filterType", name)) return 7; + if (!strcmp("gridCoord", name)) return 8; + if (!strcmp("hierarchicalLevel", name)) return 9; + if (!strcmp("nLevels", name)) return 10; + if (!strcmp("normal", name)) return 11; + if (!strcmp("nSlices", name)) return 12; + if (!strcmp("texCoord", name)) return 13; + if (!strcmp("vertexOffset", name)) return 14; + if (!strcmp("vertexLink", name)) return 15; + if (!strcmp("colorIndex", name)) return 16; + if (!strcmp("coordIndex", name)) return 17; + if (!strcmp("normalIndex", name)) return 18; + if (!strcmp("solid", name)) return 19; + if (!strcmp("texCoordIndex", name)) return 20; + if (!strcmp("isLoading", name)) return 21; + if (!strcmp("nVertices", name)) return 22; return -1; } -static Bool PositionInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool MeshGrid_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: + case 6: + *AType = 13; + *QType = 13; + *QT13_bits = 32; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 13; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX( 1); + return 1; + case 9: + *AType = 13; + *QType = 13; + *QT13_bits = 32; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 10: + *AType = 7; + *QType = 7; + return 1; + case 12: + *AType = 7; + *QType = 7; + return 1; + case 14: + *AType = 7; + *QType = 7; + *b_min = FLT2FIX(0.0); + *b_max = FLT2FIX( 2.0); + return 1; + case 15: *AType = 0; - *QType = 8; + *QType = 13; + *QT13_bits = 2; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *b_max = FLT2FIX( 3); return 1; - case 2: + case 16: *AType = 0; - *QType = 1; - *b_min = FIX_MIN; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 17: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 18: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); + *b_max = FIX_MAX; + return 1; + case 20: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(-1); *b_max = FIX_MAX; return 1; default: @@ -9250,89 +24632,99 @@ static Bool PositionInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QTy -GF_Node *PositionInterpolator_Create() +GF_Node *MeshGrid_Create() { - M_PositionInterpolator *p; - GF_SAFEALLOC(p, M_PositionInterpolator); + M_MeshGrid *p; + GF_SAFEALLOC(p, M_MeshGrid); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionInterpolator); + gf_node_setup((GF_Node *)p, TAG_MPEG4_MeshGrid); /*default field values*/ + p->displayLevel = 0; + p->filterType = 0; + p->hierarchicalLevel = 0; + p->solid = 1; return (GF_Node *)p; } /* - PositionInterpolator2D Node deletion + NonLinearDeformer Node deletion */ -static void PositionInterpolator2D_Del(GF_Node *node) +static void NonLinearDeformer_Del(GF_Node *node) { - M_PositionInterpolator2D *p = (M_PositionInterpolator2D *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfvec2f_del(p->keyValue); + M_NonLinearDeformer *p = (M_NonLinearDeformer *) node; + gf_sg_mffloat_del(p->extend); + gf_node_unregister((GF_Node *) p->geometry, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 PositionInterpolator2D_Def2All[] = { 1, 2}; -static const u16 PositionInterpolator2D_In2All[] = { 0, 1, 2}; -static const u16 PositionInterpolator2D_Out2All[] = { 1, 2, 3}; +static const u16 NonLinearDeformer_Def2All[] = { 0, 1, 2, 3, 4}; +static const u16 NonLinearDeformer_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 NonLinearDeformer_Out2All[] = { 0, 1, 2, 3, 4}; -static u32 PositionInterpolator2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 NonLinearDeformer_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 5; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 4; + return 5; } } -static GF_Err PositionInterpolator2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err NonLinearDeformer_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PositionInterpolator2D_In2All[inField]; + *allField = NonLinearDeformer_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PositionInterpolator2D_Def2All[inField]; + *allField = NonLinearDeformer_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PositionInterpolator2D_Out2All[inField]; + *allField = NonLinearDeformer_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PositionInterpolator2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NonLinearDeformer_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_fraction"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_PositionInterpolator2D *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PositionInterpolator2D *) node)->set_fraction; + info->name = "axis"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_NonLinearDeformer *) node)->axis; return GF_OK; case 1: - info->name = "key"; + info->name = "extend"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PositionInterpolator2D *) node)->key; + info->far_ptr = & ((M_NonLinearDeformer *) node)->extend; return GF_OK; case 2: - info->name = "keyValue"; + info->name = "geometry"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((M_PositionInterpolator2D *) node)->keyValue; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_NonLinearDeformer *)node)->geometry; return GF_OK; case 3: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PositionInterpolator2D *) node)->value_changed; + info->name = "param"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_NonLinearDeformer *) node)->param; + return GF_OK; + case 4: + info->name = "type"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_NonLinearDeformer *) node)->type; return GF_OK; default: return GF_BAD_PARAM; @@ -9340,29 +24732,18 @@ static GF_Err PositionInterpolator2D_get_field(GF_Node *node, GF_FieldInfo *info } -static s32 PositionInterpolator2D_get_field_index_by_name(char *name) +static s32 NonLinearDeformer_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("key", name)) return 1; - if (!strcmp("keyValue", name)) return 2; - if (!strcmp("value_changed", name)) return 3; + if (!strcmp("axis", name)) return 0; + if (!strcmp("extend", name)) return 1; + if (!strcmp("geometry", name)) return 2; + if (!strcmp("param", name)) return 3; + if (!strcmp("type", name)) return 4; return -1; } -static Bool PositionInterpolator2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool NonLinearDeformer_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 0; - *QType = 8; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 2: - *AType = 0; - *QType = 2; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -9370,110 +24751,126 @@ static Bool PositionInterpolator2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *Q -GF_Node *PositionInterpolator2D_Create() +GF_Node *NonLinearDeformer_Create() { - M_PositionInterpolator2D *p; - GF_SAFEALLOC(p, M_PositionInterpolator2D); + M_NonLinearDeformer *p; + GF_SAFEALLOC(p, M_NonLinearDeformer); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionInterpolator2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_NonLinearDeformer); /*default field values*/ + p->axis.x = FLT2FIX(0); + p->axis.y = FLT2FIX(0); + p->axis.z = FLT2FIX(1); + p->param = FLT2FIX(0); + p->type = 0; return (GF_Node *)p; } /* - ProximitySensor2D Node deletion + NurbsCurve Node deletion */ -static void ProximitySensor2D_Del(GF_Node *node) +static void NurbsCurve_Del(GF_Node *node) { - M_ProximitySensor2D *p = (M_ProximitySensor2D *) node; + M_NurbsCurve *p = (M_NurbsCurve *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_sg_mfvec4f_del(p->controlPoint); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mffloat_del(p->knot); gf_node_free((GF_Node *) p); } -static const u16 ProximitySensor2D_Def2All[] = { 0, 1, 2}; -static const u16 ProximitySensor2D_In2All[] = { 0, 1, 2}; -static const u16 ProximitySensor2D_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 NurbsCurve_Def2All[] = { 1, 2, 3, 4, 5, 6, 7}; +static const u16 NurbsCurve_In2All[] = { 0, 1, 2, 3}; +static const u16 NurbsCurve_Out2All[] = { 1, 2, 3}; +static const u16 NurbsCurve_Dyn2All[] = { 2}; -static u32 ProximitySensor2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 NurbsCurve_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 8; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 1; default: return 8; } } -static GF_Err ProximitySensor2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err NurbsCurve_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = ProximitySensor2D_In2All[inField]; + *allField = NurbsCurve_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = ProximitySensor2D_Def2All[inField]; + *allField = NurbsCurve_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = ProximitySensor2D_Out2All[inField]; + *allField = NurbsCurve_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = NurbsCurve_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err ProximitySensor2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsCurve_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "center"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_ProximitySensor2D *) node)->center; + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_NurbsCurve *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_NurbsCurve *) node)->set_colorIndex; return GF_OK; case 1: - info->name = "size"; + info->name = "color"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_ProximitySensor2D *) node)->size; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_NurbsCurve *)node)->color; return GF_OK; case 2: - info->name = "enabled"; + info->name = "controlPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ProximitySensor2D *) node)->enabled; + info->fieldType = GF_SG_VRML_MFVEC4F; + info->far_ptr = & ((M_NurbsCurve *) node)->controlPoint; return GF_OK; case 3: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ProximitySensor2D *) node)->isActive; + info->name = "tessellation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_NurbsCurve *) node)->tessellation; return GF_OK; case 4: - info->name = "position_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_ProximitySensor2D *) node)->position_changed; + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_NurbsCurve *) node)->colorIndex; return GF_OK; case 5: - info->name = "orientation_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ProximitySensor2D *) node)->orientation_changed; + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_NurbsCurve *) node)->colorPerVertex; return GF_OK; case 6: - info->name = "enterTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_ProximitySensor2D *) node)->enterTime; + info->name = "knot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_NurbsCurve *) node)->knot; return GF_OK; case 7: - info->name = "exitTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_ProximitySensor2D *) node)->exitTime; + info->name = "order"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_NurbsCurve *) node)->order; return GF_OK; default: return GF_BAD_PARAM; @@ -9481,32 +24878,37 @@ static GF_Err ProximitySensor2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 ProximitySensor2D_get_field_index_by_name(char *name) +static s32 NurbsCurve_get_field_index_by_name(char *name) { - if (!strcmp("center", name)) return 0; - if (!strcmp("size", name)) return 1; - if (!strcmp("enabled", name)) return 2; - if (!strcmp("isActive", name)) return 3; - if (!strcmp("position_changed", name)) return 4; - if (!strcmp("orientation_changed", name)) return 5; - if (!strcmp("enterTime", name)) return 6; - if (!strcmp("exitTime", name)) return 7; + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("color", name)) return 1; + if (!strcmp("controlPoint", name)) return 2; + if (!strcmp("tessellation", name)) return 3; + if (!strcmp("colorIndex", name)) return 4; + if (!strcmp("colorPerVertex", name)) return 5; + if (!strcmp("knot", name)) return 6; + if (!strcmp("order", name)) return 7; return -1; } -static Bool ProximitySensor2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool NurbsCurve_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 0; - *QType = 2; - *b_min = FLT2FIX(-1); + case 2: + *AType = 15; + *QType = 15; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 1: + case 4: *AType = 0; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + *QType = 14; + return 1; + case 7: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(3); + *b_max = FLT2FIX(34); return 1; default: return 0; @@ -9515,115 +24917,124 @@ static Bool ProximitySensor2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *ProximitySensor2D_Create() +GF_Node *NurbsCurve_Create() { - M_ProximitySensor2D *p; - GF_SAFEALLOC(p, M_ProximitySensor2D); + M_NurbsCurve *p; + GF_SAFEALLOC(p, M_NurbsCurve); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_ProximitySensor2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_NurbsCurve); /*default field values*/ - p->center.x = FLT2FIX(0); - p->center.y = FLT2FIX(0); - p->size.x = FLT2FIX(0); - p->size.y = FLT2FIX(0); - p->enabled = 1; + p->tessellation = 0; + p->colorPerVertex = 1; + p->order = 4; return (GF_Node *)p; } /* - ProximitySensor Node deletion + NurbsCurve2D Node deletion */ -static void ProximitySensor_Del(GF_Node *node) +static void NurbsCurve2D_Del(GF_Node *node) { - M_ProximitySensor *p = (M_ProximitySensor *) node; + M_NurbsCurve2D *p = (M_NurbsCurve2D *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_sg_mfvec3f_del(p->controlPoint); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mffloat_del(p->knot); gf_node_free((GF_Node *) p); } -static const u16 ProximitySensor_Def2All[] = { 0, 1, 2}; -static const u16 ProximitySensor_In2All[] = { 0, 1, 2}; -static const u16 ProximitySensor_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 NurbsCurve2D_Def2All[] = { 1, 2, 3, 4, 5, 6, 7}; +static const u16 NurbsCurve2D_In2All[] = { 0, 1, 2, 3}; +static const u16 NurbsCurve2D_Out2All[] = { 1, 2, 3}; +static const u16 NurbsCurve2D_Dyn2All[] = { 2}; -static u32 ProximitySensor_get_field_count(GF_Node *node, u8 IndexMode) +static u32 NurbsCurve2D_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 8; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 1; default: return 8; } } -static GF_Err ProximitySensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err NurbsCurve2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = ProximitySensor_In2All[inField]; + *allField = NurbsCurve2D_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = ProximitySensor_Def2All[inField]; + *allField = NurbsCurve2D_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = ProximitySensor_Out2All[inField]; + *allField = NurbsCurve2D_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = NurbsCurve2D_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err ProximitySensor_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsCurve2D_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "center"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_ProximitySensor *) node)->center; + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_NurbsCurve2D *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_NurbsCurve2D *) node)->set_colorIndex; return GF_OK; case 1: - info->name = "size"; + info->name = "color"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_ProximitySensor *) node)->size; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_NurbsCurve2D *)node)->color; return GF_OK; case 2: - info->name = "enabled"; + info->name = "controlPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ProximitySensor *) node)->enabled; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_NurbsCurve2D *) node)->controlPoint; return GF_OK; case 3: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ProximitySensor *) node)->isActive; + info->name = "tessellation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_NurbsCurve2D *) node)->tessellation; return GF_OK; case 4: - info->name = "position_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_ProximitySensor *) node)->position_changed; + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_NurbsCurve2D *) node)->colorIndex; return GF_OK; case 5: - info->name = "orientation_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_ProximitySensor *) node)->orientation_changed; + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_NurbsCurve2D *) node)->colorPerVertex; return GF_OK; case 6: - info->name = "enterTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_ProximitySensor *) node)->enterTime; + info->name = "knot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_NurbsCurve2D *) node)->knot; return GF_OK; case 7: - info->name = "exitTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_ProximitySensor *) node)->exitTime; + info->name = "order"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_NurbsCurve2D *) node)->order; return GF_OK; default: return GF_BAD_PARAM; @@ -9631,32 +25042,37 @@ static GF_Err ProximitySensor_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 ProximitySensor_get_field_index_by_name(char *name) +static s32 NurbsCurve2D_get_field_index_by_name(char *name) { - if (!strcmp("center", name)) return 0; - if (!strcmp("size", name)) return 1; - if (!strcmp("enabled", name)) return 2; - if (!strcmp("isActive", name)) return 3; - if (!strcmp("position_changed", name)) return 4; - if (!strcmp("orientation_changed", name)) return 5; - if (!strcmp("enterTime", name)) return 6; - if (!strcmp("exitTime", name)) return 7; + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("color", name)) return 1; + if (!strcmp("controlPoint", name)) return 2; + if (!strcmp("tessellation", name)) return 3; + if (!strcmp("colorIndex", name)) return 4; + if (!strcmp("colorPerVertex", name)) return 5; + if (!strcmp("knot", name)) return 6; + if (!strcmp("order", name)) return 7; return -1; } -static Bool ProximitySensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool NurbsCurve2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 0; - *QType = 1; + case 2: + *AType = 2; + *QType = 2; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 1: + case 4: *AType = 0; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + *QType = 14; + return 1; + case 7: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(3); + *b_max = FLT2FIX(34); return 1; default: return 0; @@ -9665,301 +25081,190 @@ static Bool ProximitySensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u -GF_Node *ProximitySensor_Create() +GF_Node *NurbsCurve2D_Create() { - M_ProximitySensor *p; - GF_SAFEALLOC(p, M_ProximitySensor); + M_NurbsCurve2D *p; + GF_SAFEALLOC(p, M_NurbsCurve2D); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_ProximitySensor); + gf_node_setup((GF_Node *)p, TAG_MPEG4_NurbsCurve2D); /*default field values*/ - p->center.x = FLT2FIX(0); - p->center.y = FLT2FIX(0); - p->center.z = FLT2FIX(0); - p->size.x = FLT2FIX(0); - p->size.y = FLT2FIX(0); - p->size.z = FLT2FIX(0); - p->enabled = 1; + p->tessellation = 0; + p->colorPerVertex = 1; + p->order = 4; return (GF_Node *)p; } /* - QuantizationParameter Node deletion + NurbsSurface Node deletion */ -static void QuantizationParameter_Del(GF_Node *node) +static void NurbsSurface_Del(GF_Node *node) { - M_QuantizationParameter *p = (M_QuantizationParameter *) node; + M_NurbsSurface *p = (M_NurbsSurface *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_sg_mfint32_del(p->set_texColorIndex); + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_sg_mfvec4f_del(p->controlPoint); + gf_node_unregister((GF_Node *) p->texCoord, (GF_Node *) p); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mfint32_del(p->texColorIndex); + gf_sg_mffloat_del(p->uKnot); + gf_sg_mffloat_del(p->vKnot); gf_node_free((GF_Node *) p); } -static const u16 QuantizationParameter_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39}; +static const u16 NurbsSurface_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; +static const u16 NurbsSurface_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 NurbsSurface_Out2All[] = { 2, 3, 4, 5, 6}; +static const u16 NurbsSurface_Dyn2All[] = { 3}; -static u32 QuantizationParameter_get_field_count(GF_Node *node, u8 IndexMode) +static u32 NurbsSurface_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 0; - case GF_SG_FIELD_CODING_DEF: return 40; - case GF_SG_FIELD_CODING_OUT: return 0; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 7; + case GF_SG_FIELD_CODING_DEF: return 16; + case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_DYN: return 1; default: - return 40; + return 18; } } -static GF_Err QuantizationParameter_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err NurbsSurface_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = NurbsSurface_In2All[inField]; + return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = QuantizationParameter_Def2All[inField]; + *allField = NurbsSurface_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = NurbsSurface_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = NurbsSurface_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err QuantizationParameter_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsSurface_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "isLocal"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->isLocal; + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_NurbsSurface *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_NurbsSurface *) node)->set_colorIndex; return GF_OK; case 1: - info->name = "position3DQuant"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->position3DQuant; + info->name = "set_texColorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_NurbsSurface *)node)->on_set_texColorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_NurbsSurface *) node)->set_texColorIndex; return GF_OK; case 2: - info->name = "position3DMin"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_QuantizationParameter *) node)->position3DMin; + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_NurbsSurface *)node)->color; return GF_OK; case 3: - info->name = "position3DMax"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_QuantizationParameter *) node)->position3DMax; + info->name = "controlPoint"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC4F; + info->far_ptr = & ((M_NurbsSurface *) node)->controlPoint; return GF_OK; case 4: - info->name = "position3DNbBits"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->position3DNbBits; + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((M_NurbsSurface *)node)->texCoord; return GF_OK; case 5: - info->name = "position2DQuant"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->position2DQuant; + info->name = "uTessellation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_NurbsSurface *) node)->uTessellation; return GF_OK; case 6: - info->name = "position2DMin"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_QuantizationParameter *) node)->position2DMin; + info->name = "vTessellation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_NurbsSurface *) node)->vTessellation; return GF_OK; case 7: - info->name = "position2DMax"; + info->name = "ccw"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_QuantizationParameter *) node)->position2DMax; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_NurbsSurface *) node)->ccw; return GF_OK; case 8: - info->name = "position2DNbBits"; + info->name = "colorIndex"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->position2DNbBits; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_NurbsSurface *) node)->colorIndex; return GF_OK; case 9: - info->name = "drawOrderQuant"; + info->name = "colorPerVertex"; info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->drawOrderQuant; + info->far_ptr = & ((M_NurbsSurface *) node)->colorPerVertex; return GF_OK; case 10: - info->name = "drawOrderMin"; + info->name = "solid"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->drawOrderMin; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_NurbsSurface *) node)->solid; return GF_OK; case 11: - info->name = "drawOrderMax"; + info->name = "texColorIndex"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->drawOrderMax; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_NurbsSurface *) node)->texColorIndex; return GF_OK; case 12: - info->name = "drawOrderNbBits"; + info->name = "uDimension"; info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->drawOrderNbBits; + info->far_ptr = & ((M_NurbsSurface *) node)->uDimension; return GF_OK; case 13: - info->name = "colorQuant"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->colorQuant; - return GF_OK; - case 14: - info->name = "colorMin"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->colorMin; - return GF_OK; - case 15: - info->name = "colorMax"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->colorMax; - return GF_OK; - case 16: - info->name = "colorNbBits"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->colorNbBits; - return GF_OK; - case 17: - info->name = "textureCoordinateQuant"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->textureCoordinateQuant; - return GF_OK; - case 18: - info->name = "textureCoordinateMin"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->textureCoordinateMin; - return GF_OK; - case 19: - info->name = "textureCoordinateMax"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->textureCoordinateMax; - return GF_OK; - case 20: - info->name = "textureCoordinateNbBits"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->textureCoordinateNbBits; - return GF_OK; - case 21: - info->name = "angleQuant"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->angleQuant; - return GF_OK; - case 22: - info->name = "angleMin"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->angleMin; - return GF_OK; - case 23: - info->name = "angleMax"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->angleMax; - return GF_OK; - case 24: - info->name = "angleNbBits"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->angleNbBits; - return GF_OK; - case 25: - info->name = "scaleQuant"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->scaleQuant; - return GF_OK; - case 26: - info->name = "scaleMin"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->scaleMin; - return GF_OK; - case 27: - info->name = "scaleMax"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->scaleMax; - return GF_OK; - case 28: - info->name = "scaleNbBits"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->scaleNbBits; - return GF_OK; - case 29: - info->name = "keyQuant"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->keyQuant; - return GF_OK; - case 30: - info->name = "keyMin"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->keyMin; - return GF_OK; - case 31: - info->name = "keyMax"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->keyMax; - return GF_OK; - case 32: - info->name = "keyNbBits"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->keyNbBits; - return GF_OK; - case 33: - info->name = "normalQuant"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->normalQuant; - return GF_OK; - case 34: - info->name = "normalNbBits"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->normalNbBits; - return GF_OK; - case 35: - info->name = "sizeQuant"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->sizeQuant; - return GF_OK; - case 36: - info->name = "sizeMin"; + info->name = "uKnot"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->sizeMin; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_NurbsSurface *) node)->uKnot; return GF_OK; - case 37: - info->name = "sizeMax"; + case 14: + info->name = "uOrder"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_QuantizationParameter *) node)->sizeMax; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_NurbsSurface *) node)->uOrder; return GF_OK; - case 38: - info->name = "sizeNbBits"; + case 15: + info->name = "vDimension"; info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_QuantizationParameter *) node)->sizeNbBits; + info->far_ptr = & ((M_NurbsSurface *) node)->vDimension; return GF_OK; - case 39: - info->name = "useEfficientCoding"; + case 16: + info->name = "vKnot"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_QuantizationParameter *) node)->useEfficientCoding; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_NurbsSurface *) node)->vKnot; + return GF_OK; + case 17: + info->name = "vOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_NurbsSurface *) node)->vOrder; return GF_OK; default: return GF_BAD_PARAM; @@ -9967,231 +25272,456 @@ static GF_Err QuantizationParameter_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 QuantizationParameter_get_field_index_by_name(char *name) +static s32 NurbsSurface_get_field_index_by_name(char *name) { - if (!strcmp("isLocal", name)) return 0; - if (!strcmp("position3DQuant", name)) return 1; - if (!strcmp("position3DMin", name)) return 2; - if (!strcmp("position3DMax", name)) return 3; - if (!strcmp("position3DNbBits", name)) return 4; - if (!strcmp("position2DQuant", name)) return 5; - if (!strcmp("position2DMin", name)) return 6; - if (!strcmp("position2DMax", name)) return 7; - if (!strcmp("position2DNbBits", name)) return 8; - if (!strcmp("drawOrderQuant", name)) return 9; - if (!strcmp("drawOrderMin", name)) return 10; - if (!strcmp("drawOrderMax", name)) return 11; - if (!strcmp("drawOrderNbBits", name)) return 12; - if (!strcmp("colorQuant", name)) return 13; - if (!strcmp("colorMin", name)) return 14; - if (!strcmp("colorMax", name)) return 15; - if (!strcmp("colorNbBits", name)) return 16; - if (!strcmp("textureCoordinateQuant", name)) return 17; - if (!strcmp("textureCoordinateMin", name)) return 18; - if (!strcmp("textureCoordinateMax", name)) return 19; - if (!strcmp("textureCoordinateNbBits", name)) return 20; - if (!strcmp("angleQuant", name)) return 21; - if (!strcmp("angleMin", name)) return 22; - if (!strcmp("angleMax", name)) return 23; - if (!strcmp("angleNbBits", name)) return 24; - if (!strcmp("scaleQuant", name)) return 25; - if (!strcmp("scaleMin", name)) return 26; - if (!strcmp("scaleMax", name)) return 27; - if (!strcmp("scaleNbBits", name)) return 28; - if (!strcmp("keyQuant", name)) return 29; - if (!strcmp("keyMin", name)) return 30; - if (!strcmp("keyMax", name)) return 31; - if (!strcmp("keyNbBits", name)) return 32; - if (!strcmp("normalQuant", name)) return 33; - if (!strcmp("normalNbBits", name)) return 34; - if (!strcmp("sizeQuant", name)) return 35; - if (!strcmp("sizeMin", name)) return 36; - if (!strcmp("sizeMax", name)) return 37; - if (!strcmp("sizeNbBits", name)) return 38; - if (!strcmp("useEfficientCoding", name)) return 39; + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("set_texColorIndex", name)) return 1; + if (!strcmp("color", name)) return 2; + if (!strcmp("controlPoint", name)) return 3; + if (!strcmp("texCoord", name)) return 4; + if (!strcmp("uTessellation", name)) return 5; + if (!strcmp("vTessellation", name)) return 6; + if (!strcmp("ccw", name)) return 7; + if (!strcmp("colorIndex", name)) return 8; + if (!strcmp("colorPerVertex", name)) return 9; + if (!strcmp("solid", name)) return 10; + if (!strcmp("texColorIndex", name)) return 11; + if (!strcmp("uDimension", name)) return 12; + if (!strcmp("uKnot", name)) return 13; + if (!strcmp("uOrder", name)) return 14; + if (!strcmp("vDimension", name)) return 15; + if (!strcmp("vKnot", name)) return 16; + if (!strcmp("vOrder", name)) return 17; return -1; } -static Bool QuantizationParameter_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool NurbsSurface_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 2: - *AType = 0; - *QType = 0; + case 3: + *AType = 15; + *QType = 15; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 3: + case 8: *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 14; return 1; - case 4: + case 11: + *AType = 0; + *QType = 14; + return 1; + case 12: + *AType = 0; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(3); + *b_max = FLT2FIX(258); + return 1; + case 14: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(3); + *b_max = FLT2FIX(34); + return 1; + case 15: + *AType = 0; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(3); + *b_max = FLT2FIX(258); + return 1; + case 17: *AType = 0; *QType = 13; *QT13_bits = 5; + *b_min = FLT2FIX(3); + *b_max = FLT2FIX(34); + return 1; + default: + return 0; + } +} + + + +GF_Node *NurbsSurface_Create() +{ + M_NurbsSurface *p; + GF_SAFEALLOC(p, M_NurbsSurface); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_NurbsSurface); + + /*default field values*/ + p->uTessellation = 0; + p->vTessellation = 0; + p->ccw = 1; + p->colorPerVertex = 1; + p->solid = 1; + p->uDimension = 4; + p->uOrder = 4; + p->vDimension = 4; + p->vOrder = 4; + return (GF_Node *)p; +} + + +/* + OctreeImage Node deletion +*/ + +static void OctreeImage_Del(GF_Node *node) +{ + M_OctreeImage *p = (M_OctreeImage *) node; + gf_node_unregister_children((GF_Node *) p, p->images); + gf_sg_mfint32_del(p->octree); + gf_sg_mfint32_del(p->voxelImageIndex); + gf_node_free((GF_Node *) p); +} + +static const u16 OctreeImage_Def2All[] = { 0, 1, 2, 3}; + +static u32 OctreeImage_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 4; + } +} + +static GF_Err OctreeImage_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_DEF: + *allField = OctreeImage_Def2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err OctreeImage_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "images"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFDepthImageNode; + info->far_ptr = & ((M_OctreeImage *)node)->images; + return GF_OK; + case 1: + info->name = "octree"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_OctreeImage *) node)->octree; + return GF_OK; + case 2: + info->name = "octreeResolution"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_OctreeImage *) node)->octreeResolution; + return GF_OK; + case 3: + info->name = "voxelImageIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_OctreeImage *) node)->voxelImageIndex; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 OctreeImage_get_field_index_by_name(char *name) +{ + if (!strcmp("images", name)) return 0; + if (!strcmp("octree", name)) return 1; + if (!strcmp("octreeResolution", name)) return 2; + if (!strcmp("voxelImageIndex", name)) return 3; + return -1; + } +static Bool OctreeImage_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 13; + *QT13_bits = 8; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); + *b_max = FLT2FIX(255); return 1; - case 6: + case 3: *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(255); return 1; + default: + return 0; + } +} + + + +GF_Node *OctreeImage_Create() +{ + M_OctreeImage *p; + GF_SAFEALLOC(p, M_OctreeImage); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_OctreeImage); + + /*default field values*/ + p->octreeResolution = 256; + return (GF_Node *)p; +} + + +/* + XXParticles Node deletion +*/ + +static void XXParticles_Del(GF_Node *node) +{ + M_XXParticles *p = (M_XXParticles *) node; + gf_node_unregister_children((GF_Node *) p, p->influences); + gf_node_unregister((GF_Node *) p->init, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->primitive, (GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 XXParticles_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}; +static const u16 XXParticles_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}; +static const u16 XXParticles_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}; + +static u32 XXParticles_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 25; + case GF_SG_FIELD_CODING_DEF: return 25; + case GF_SG_FIELD_CODING_OUT: return 25; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 25; + } +} + +static GF_Err XXParticles_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = XXParticles_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = XXParticles_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = XXParticles_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err XXParticles_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "creationRate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->creationRate; + return GF_OK; + case 1: + info->name = "creationRateVariation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->creationRateVariation; + return GF_OK; + case 2: + info->name = "emitAlpha"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->emitAlpha; + return GF_OK; + case 3: + info->name = "emitColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_XXParticles *) node)->emitColor; + return GF_OK; + case 4: + info->name = "emitColorVariation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_XXParticles *) node)->emitColorVariation; + return GF_OK; + case 5: + info->name = "emitterPosition"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_XXParticles *) node)->emitterPosition; + return GF_OK; + case 6: + info->name = "emitVelocity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_XXParticles *) node)->emitVelocity; + return GF_OK; case 7: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; + info->name = "emitVelocityVariation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_XXParticles *) node)->emitVelocityVariation; + return GF_OK; case 8: - *AType = 0; - *QType = 13; - *QT13_bits = 5; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); - return 1; + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_XXParticles *) node)->enabled; + return GF_OK; + case 9: + info->name = "fadeAlpha"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->fadeAlpha; + return GF_OK; case 10: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; + info->name = "fadeColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_XXParticles *) node)->fadeColor; + return GF_OK; case 11: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; + info->name = "fadeRate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->fadeRate; + return GF_OK; case 12: - *AType = 0; - *QType = 13; - *QT13_bits = 5; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); - return 1; + info->name = "force"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_XXParticles *) node)->force; + return GF_OK; + case 13: + info->name = "influences"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFInfluenceNode; + info->far_ptr = & ((M_XXParticles *)node)->influences; + return GF_OK; case 14: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; + info->name = "init"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFWorldNode; + info->far_ptr = & ((M_XXParticles *)node)->init; + return GF_OK; case 15: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; + info->name = "maxLifeTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_XXParticles *) node)->maxLifeTime; + return GF_OK; case 16: - *AType = 0; - *QType = 13; - *QT13_bits = 5; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); - return 1; + info->name = "maxLifeTimeVariation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->maxLifeTimeVariation; + return GF_OK; + case 17: + info->name = "maxParticles"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_XXParticles *) node)->maxParticles; + return GF_OK; case 18: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; + info->name = "minRange"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->minRange; + return GF_OK; case 19: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; + info->name = "maxRange"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->maxRange; + return GF_OK; case 20: - *AType = 0; - *QType = 13; - *QT13_bits = 5; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); - return 1; + info->name = "primitive"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFWorldNode; + info->far_ptr = & ((M_XXParticles *)node)->primitive; + return GF_OK; + case 21: + info->name = "primitiveType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_XXParticles *) node)->primitiveType; + return GF_OK; case 22: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(6.2831853); - return 1; + info->name = "particleRadius"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->particleRadius; + return GF_OK; case 23: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(6.2831853); - return 1; + info->name = "particleRadiusRate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->particleRadiusRate; + return GF_OK; case 24: - *AType = 0; - *QType = 13; - *QT13_bits = 5; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); - return 1; - case 26: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 27: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 28: - *AType = 0; - *QType = 13; - *QT13_bits = 5; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); - return 1; - case 30: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 31: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 32: - *AType = 0; - *QType = 13; - *QT13_bits = 5; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); - return 1; - case 34: - *AType = 0; - *QType = 13; - *QT13_bits = 5; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); - return 1; - case 36: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 37: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 38: - *AType = 0; - *QType = 13; - *QT13_bits = 5; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(31); - return 1; + info->name = "particleRadiusVariation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticles *) node)->particleRadiusVariation; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 XXParticles_get_field_index_by_name(char *name) +{ + if (!strcmp("creationRate", name)) return 0; + if (!strcmp("creationRateVariation", name)) return 1; + if (!strcmp("emitAlpha", name)) return 2; + if (!strcmp("emitColor", name)) return 3; + if (!strcmp("emitColorVariation", name)) return 4; + if (!strcmp("emitterPosition", name)) return 5; + if (!strcmp("emitVelocity", name)) return 6; + if (!strcmp("emitVelocityVariation", name)) return 7; + if (!strcmp("enabled", name)) return 8; + if (!strcmp("fadeAlpha", name)) return 9; + if (!strcmp("fadeColor", name)) return 10; + if (!strcmp("fadeRate", name)) return 11; + if (!strcmp("force", name)) return 12; + if (!strcmp("influences", name)) return 13; + if (!strcmp("init", name)) return 14; + if (!strcmp("maxLifeTime", name)) return 15; + if (!strcmp("maxLifeTimeVariation", name)) return 16; + if (!strcmp("maxParticles", name)) return 17; + if (!strcmp("minRange", name)) return 18; + if (!strcmp("maxRange", name)) return 19; + if (!strcmp("primitive", name)) return 20; + if (!strcmp("primitiveType", name)) return 21; + if (!strcmp("particleRadius", name)) return 22; + if (!strcmp("particleRadiusRate", name)) return 23; + if (!strcmp("particleRadiusVariation", name)) return 24; + return -1; + } +static Bool XXParticles_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { default: return 0; } @@ -10199,111 +25729,110 @@ static Bool QuantizationParameter_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QT -GF_Node *QuantizationParameter_Create() +GF_Node *XXParticles_Create() { - M_QuantizationParameter *p; - GF_SAFEALLOC(p, M_QuantizationParameter); + M_XXParticles *p; + GF_SAFEALLOC(p, M_XXParticles); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_QuantizationParameter); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXParticles); - /*default field values*/ - p->position3DMin.x = FIX_MIN; - p->position3DMin.y = FIX_MIN; - p->position3DMin.z = FIX_MIN; - p->position3DMax.x = FIX_MAX; - p->position3DMax.y = FIX_MAX; - p->position3DMax.z = FIX_MAX; - p->position3DNbBits = 16; - p->position2DMin.x = FIX_MIN; - p->position2DMin.y = FIX_MIN; - p->position2DMax.x = FIX_MAX; - p->position2DMax.y = FIX_MAX; - p->position2DNbBits = 16; - p->drawOrderMin = FIX_MIN; - p->drawOrderMax = FIX_MAX; - p->drawOrderNbBits = 8; - p->colorQuant = 1; - p->colorMin = FLT2FIX(0.0); - p->colorMax = FLT2FIX(1.0); - p->colorNbBits = 8; - p->textureCoordinateQuant = 1; - p->textureCoordinateMin = FLT2FIX(0); - p->textureCoordinateMax = FLT2FIX(1); - p->textureCoordinateNbBits = 16; - p->angleQuant = 1; - p->angleMin = FLT2FIX(0.0); - p->angleMax = FLT2FIX(6.2831853); - p->angleNbBits = 16; - p->scaleMin = FLT2FIX(0.0); - p->scaleMax = FIX_MAX; - p->scaleNbBits = 8; - p->keyQuant = 1; - p->keyMin = FLT2FIX(0.0); - p->keyMax = FLT2FIX(1.0); - p->keyNbBits = 8; - p->normalQuant = 1; - p->normalNbBits = 8; - p->sizeMin = FLT2FIX(0); - p->sizeMax = FIX_MAX; - p->sizeNbBits = 8; + /*default field values*/ + p->creationRate = FLT2FIX(500); + p->creationRateVariation = FLT2FIX(0); + p->emitAlpha = FLT2FIX(1.0); + p->emitColor.red = FLT2FIX(1); + p->emitColor.green = FLT2FIX(1); + p->emitColor.blue = FLT2FIX(1); + p->emitColorVariation.red = FLT2FIX(0); + p->emitColorVariation.green = FLT2FIX(0); + p->emitColorVariation.blue = FLT2FIX(0); + p->emitterPosition.x = FLT2FIX(0); + p->emitterPosition.y = FLT2FIX(3); + p->emitterPosition.z = FLT2FIX(0); + p->emitVelocity.x = FLT2FIX(0); + p->emitVelocity.y = FLT2FIX(0); + p->emitVelocity.z = FLT2FIX(0); + p->emitVelocityVariation.x = FLT2FIX(1); + p->emitVelocityVariation.y = FLT2FIX(1); + p->emitVelocityVariation.z = FLT2FIX(1); + p->enabled = 1; + p->fadeAlpha = FLT2FIX(1.0); + p->fadeColor.red = FLT2FIX(0.25); + p->fadeColor.green = FLT2FIX(0.25); + p->fadeColor.blue = FLT2FIX(0.25); + p->fadeRate = FLT2FIX(0.25); + p->force.x = FLT2FIX(0); + p->force.y = FLT2FIX(-9.8); + p->force.z = FLT2FIX(0); + p->maxLifeTime = 5; + p->maxLifeTimeVariation = FLT2FIX(0); + p->maxParticles = 500; + p->minRange = FLT2FIX(1); + p->maxRange = FLT2FIX(-1); + p->primitiveType = 2; + p->particleRadius = FLT2FIX(0.1); + p->particleRadiusRate = FLT2FIX(0); + p->particleRadiusVariation = FLT2FIX(0); return (GF_Node *)p; } /* - Rectangle Node deletion + XXParticleInitBox Node deletion */ -static void Rectangle_Del(GF_Node *node) +static void XXParticleInitBox_Del(GF_Node *node) { - M_Rectangle *p = (M_Rectangle *) node; + M_XXParticleInitBox *p = (M_XXParticleInitBox *) node; gf_node_free((GF_Node *) p); } -static const u16 Rectangle_Def2All[] = { 0}; -static const u16 Rectangle_In2All[] = { 0}; -static const u16 Rectangle_Out2All[] = { 0}; -static const u16 Rectangle_Dyn2All[] = { 0}; +static const u16 XXParticleInitBox_Def2All[] = { 0, 1}; +static const u16 XXParticleInitBox_In2All[] = { 0, 1}; +static const u16 XXParticleInitBox_Out2All[] = { 0, 1}; -static u32 Rectangle_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XXParticleInitBox_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 1; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 1; + return 2; } } -static GF_Err Rectangle_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XXParticleInitBox_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Rectangle_In2All[inField]; + *allField = XXParticleInitBox_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Rectangle_Def2All[inField]; + *allField = XXParticleInitBox_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Rectangle_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Rectangle_Dyn2All[inField]; + *allField = XXParticleInitBox_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Rectangle_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XXParticleInitBox_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: + info->name = "falloff"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXParticleInitBox *) node)->falloff; + return GF_OK; + case 1: info->name = "size"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Rectangle *) node)->size; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_XXParticleInitBox *) node)->size; return GF_OK; default: return GF_BAD_PARAM; @@ -10311,20 +25840,15 @@ static GF_Err Rectangle_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Rectangle_get_field_index_by_name(char *name) +static s32 XXParticleInitBox_get_field_index_by_name(char *name) { - if (!strcmp("size", name)) return 0; + if (!strcmp("falloff", name)) return 0; + if (!strcmp("size", name)) return 1; return -1; } -static Bool Rectangle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XXParticleInitBox_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 2; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -10332,91 +25856,90 @@ static Bool Rectangle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATy -GF_Node *Rectangle_Create() +GF_Node *XXParticleInitBox_Create() { - M_Rectangle *p; - GF_SAFEALLOC(p, M_Rectangle); + M_XXParticleInitBox *p; + GF_SAFEALLOC(p, M_XXParticleInitBox); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Rectangle); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXParticleInitBox); /*default field values*/ - p->size.x = FLT2FIX(2); - p->size.y = FLT2FIX(2); + p->falloff = FLT2FIX(0); + p->size.x = FLT2FIX(1); + p->size.y = FLT2FIX(1); + p->size.z = FLT2FIX(1); return (GF_Node *)p; } /* - ScalarInterpolator Node deletion + XXPlanarObstacle Node deletion */ -static void ScalarInterpolator_Del(GF_Node *node) +static void XXPlanarObstacle_Del(GF_Node *node) { - M_ScalarInterpolator *p = (M_ScalarInterpolator *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mffloat_del(p->keyValue); + M_XXPlanarObstacle *p = (M_XXPlanarObstacle *) node; gf_node_free((GF_Node *) p); } -static const u16 ScalarInterpolator_Def2All[] = { 1, 2}; -static const u16 ScalarInterpolator_In2All[] = { 0, 1, 2}; -static const u16 ScalarInterpolator_Out2All[] = { 1, 2, 3}; +static const u16 XXPlanarObstacle_Def2All[] = { 0, 1, 2, 3}; +static const u16 XXPlanarObstacle_In2All[] = { 0, 1, 2, 3}; +static const u16 XXPlanarObstacle_Out2All[] = { 0, 1, 2, 3}; -static u32 ScalarInterpolator_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XXPlanarObstacle_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; case GF_SG_FIELD_CODING_DYN: return 0; default: return 4; } } -static GF_Err ScalarInterpolator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XXPlanarObstacle_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = ScalarInterpolator_In2All[inField]; + *allField = XXPlanarObstacle_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = ScalarInterpolator_Def2All[inField]; + *allField = XXPlanarObstacle_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = ScalarInterpolator_Out2All[inField]; + *allField = XXPlanarObstacle_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err ScalarInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XXPlanarObstacle_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_fraction"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_ScalarInterpolator *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ScalarInterpolator *) node)->set_fraction; + info->name = "distance"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_XXPlanarObstacle *) node)->distance; return GF_OK; case 1: - info->name = "key"; + info->name = "normal"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_ScalarInterpolator *) node)->key; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_XXPlanarObstacle *) node)->normal; return GF_OK; case 2: - info->name = "keyValue"; + info->name = "reflection"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_ScalarInterpolator *) node)->keyValue; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXPlanarObstacle *) node)->reflection; return GF_OK; case 3: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; + info->name = "absorption"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ScalarInterpolator *) node)->value_changed; + info->far_ptr = & ((M_XXPlanarObstacle *) node)->absorption; return GF_OK; default: return GF_BAD_PARAM; @@ -10424,29 +25947,17 @@ static GF_Err ScalarInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 ScalarInterpolator_get_field_index_by_name(char *name) +static s32 XXPlanarObstacle_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("key", name)) return 1; - if (!strcmp("keyValue", name)) return 2; - if (!strcmp("value_changed", name)) return 3; + if (!strcmp("distance", name)) return 0; + if (!strcmp("normal", name)) return 1; + if (!strcmp("reflection", name)) return 2; + if (!strcmp("absorption", name)) return 3; return -1; } -static Bool ScalarInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XXPlanarObstacle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 0; - *QType = 8; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 2: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -10454,81 +25965,94 @@ static Bool ScalarInterpolator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType -GF_Node *ScalarInterpolator_Create() +GF_Node *XXPlanarObstacle_Create() { - M_ScalarInterpolator *p; - GF_SAFEALLOC(p, M_ScalarInterpolator); + M_XXPlanarObstacle *p; + GF_SAFEALLOC(p, M_XXPlanarObstacle); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_ScalarInterpolator); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXPlanarObstacle); /*default field values*/ + p->distance.x = FLT2FIX(0); + p->distance.y = FLT2FIX(0); + p->distance.z = FLT2FIX(0); + p->normal.x = FLT2FIX(0); + p->normal.y = FLT2FIX(1); + p->normal.z = FLT2FIX(0); + p->reflection = FLT2FIX(0); + p->absorption = FLT2FIX(0); return (GF_Node *)p; } /* - Script Node deletion + XXPointAttractor Node deletion */ -static void Script_Del(GF_Node *node) +static void XXPointAttractor_Del(GF_Node *node) { - M_Script *p = (M_Script *) node; - gf_sg_mfscript_del(p->url); + M_XXPointAttractor *p = (M_XXPointAttractor *) node; gf_node_free((GF_Node *) p); } -static const u16 Script_Def2All[] = { 0, 1, 2}; -static const u16 Script_In2All[] = { 0}; -static const u16 Script_Out2All[] = { 0}; +static const u16 XXPointAttractor_Def2All[] = { 0, 1, 2, 3}; +static const u16 XXPointAttractor_In2All[] = { 0, 1, 2, 3}; +static const u16 XXPointAttractor_Out2All[] = { 0, 1, 2, 3}; -static u32 Script_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XXPointAttractor_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 3; + return 4; } } -static GF_Err Script_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XXPointAttractor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Script_In2All[inField]; + *allField = XXPointAttractor_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Script_Def2All[inField]; + *allField = XXPointAttractor_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Script_Out2All[inField]; + *allField = XXPointAttractor_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Script_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XXPointAttractor_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "url"; + info->name = "innerRadius"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSCRIPT; - info->far_ptr = & ((M_Script *) node)->url; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXPointAttractor *) node)->innerRadius; return GF_OK; case 1: - info->name = "directOutput"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Script *) node)->directOutput; + info->name = "outerRadius"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXPointAttractor *) node)->outerRadius; return GF_OK; case 2: - info->name = "mustEvaluate"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Script *) node)->mustEvaluate; + info->name = "position"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_XXPointAttractor *) node)->position; + return GF_OK; + case 3: + info->name = "rate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XXPointAttractor *) node)->rate; return GF_OK; default: return GF_BAD_PARAM; @@ -10536,14 +26060,15 @@ static GF_Err Script_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Script_get_field_index_by_name(char *name) +static s32 XXPointAttractor_get_field_index_by_name(char *name) { - if (!strcmp("url", name)) return 0; - if (!strcmp("directOutput", name)) return 1; - if (!strcmp("mustEvaluate", name)) return 2; + if (!strcmp("innerRadius", name)) return 0; + if (!strcmp("outerRadius", name)) return 1; + if (!strcmp("position", name)) return 2; + if (!strcmp("rate", name)) return 3; return -1; } -static Bool Script_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XXPointAttractor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { default: @@ -10553,78 +26078,92 @@ static Bool Script_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, -GF_Node *Script_Create() +GF_Node *XXPointAttractor_Create() { - M_Script *p; - GF_SAFEALLOC(p, M_Script); + M_XXPointAttractor *p; + GF_SAFEALLOC(p, M_XXPointAttractor); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Script); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XXPointAttractor); /*default field values*/ + p->innerRadius = FLT2FIX(10); + p->outerRadius = FLT2FIX(100); + p->position.x = FLT2FIX(0); + p->position.y = FLT2FIX(0); + p->position.z = FLT2FIX(0); + p->rate = FLT2FIX(1); return (GF_Node *)p; } /* - Shape Node deletion + PointTexture Node deletion */ -static void Shape_Del(GF_Node *node) +static void PointTexture_Del(GF_Node *node) { - M_Shape *p = (M_Shape *) node; - gf_node_unregister((GF_Node *) p->appearance, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->geometry, (GF_Node *) p); + M_PointTexture *p = (M_PointTexture *) node; + gf_sg_mfcolor_del(p->color); + gf_sg_mfint32_del(p->depth); gf_node_free((GF_Node *) p); } -static const u16 Shape_Def2All[] = { 0, 1}; -static const u16 Shape_In2All[] = { 0, 1}; -static const u16 Shape_Out2All[] = { 0, 1}; +static const u16 PointTexture_Def2All[] = { 0, 1, 2, 3, 4}; -static u32 Shape_get_field_count(GF_Node *node, u8 IndexMode) +static u32 PointTexture_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 2; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 0; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 2; + return 5; } } -static GF_Err Shape_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err PointTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = Shape_In2All[inField]; - return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Shape_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = Shape_Out2All[inField]; + *allField = PointTexture_Def2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Shape_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err PointTexture_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "appearance"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFAppearanceNode; - info->far_ptr = & ((M_Shape *)node)->appearance; + info->name = "color"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFCOLOR; + info->far_ptr = & ((M_PointTexture *) node)->color; return GF_OK; case 1: - info->name = "geometry"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFGeometryNode; - info->far_ptr = & ((M_Shape *)node)->geometry; + info->name = "depth"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_PointTexture *) node)->depth; + return GF_OK; + case 2: + info->name = "depthNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PointTexture *) node)->depthNbBits; + return GF_OK; + case 3: + info->name = "height"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PointTexture *) node)->height; + return GF_OK; + case 4: + info->name = "width"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PointTexture *) node)->width; return GF_OK; default: return GF_BAD_PARAM; @@ -10632,15 +26171,25 @@ static GF_Err Shape_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Shape_get_field_index_by_name(char *name) +static s32 PointTexture_get_field_index_by_name(char *name) { - if (!strcmp("appearance", name)) return 0; - if (!strcmp("geometry", name)) return 1; + if (!strcmp("color", name)) return 0; + if (!strcmp("depth", name)) return 1; + if (!strcmp("depthNbBits", name)) return 2; + if (!strcmp("height", name)) return 3; + if (!strcmp("width", name)) return 4; return -1; } -static Bool Shape_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool PointTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 2: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(31); + return 1; default: return 0; } @@ -10648,128 +26197,149 @@ static Bool Shape_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, -GF_Node *Shape_Create() +GF_Node *PointTexture_Create() { - M_Shape *p; - GF_SAFEALLOC(p, M_Shape); + M_PointTexture *p; + GF_SAFEALLOC(p, M_PointTexture); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Shape); + gf_node_setup((GF_Node *)p, TAG_MPEG4_PointTexture); /*default field values*/ + p->depthNbBits = 7; + p->height = 256; + p->width = 256; return (GF_Node *)p; } /* - Sound Node deletion + PositionAnimator Node deletion */ -static void Sound_Del(GF_Node *node) +static void PositionAnimator_Del(GF_Node *node) { - M_Sound *p = (M_Sound *) node; - gf_node_unregister((GF_Node *) p->source, (GF_Node *) p); + M_PositionAnimator *p = (M_PositionAnimator *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfrotation_del(p->keyOrientation); + gf_sg_mfvec2f_del(p->keySpline); + gf_sg_mfvec3f_del(p->keyValue); + gf_sg_mffloat_del(p->weight); gf_node_free((GF_Node *) p); } -static const u16 Sound_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 Sound_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; -static const u16 Sound_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; -static const u16 Sound_Dyn2All[] = { 1, 2, 3, 4, 5, 6}; - -static u32 Sound_get_field_count(GF_Node *node, u8 IndexMode) +static const u16 PositionAnimator_Def2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 PositionAnimator_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 PositionAnimator_Out2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; + +static u32 PositionAnimator_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 9; - case GF_SG_FIELD_CODING_DEF: return 10; - case GF_SG_FIELD_CODING_OUT: return 9; - case GF_SG_FIELD_CODING_DYN: return 6; + case GF_SG_FIELD_CODING_IN: return 10; + case GF_SG_FIELD_CODING_DEF: return 9; + case GF_SG_FIELD_CODING_OUT: return 12; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 10; + return 13; } } -static GF_Err Sound_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err PositionAnimator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Sound_In2All[inField]; + *allField = PositionAnimator_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Sound_Def2All[inField]; + *allField = PositionAnimator_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Sound_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Sound_Dyn2All[inField]; + *allField = PositionAnimator_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Sound_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err PositionAnimator_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "direction"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_Sound *) node)->direction; + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_PositionAnimator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PositionAnimator *) node)->set_fraction; return GF_OK; case 1: - info->name = "intensity"; + info->name = "fromTo"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Sound *) node)->intensity; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PositionAnimator *) node)->fromTo; return GF_OK; case 2: - info->name = "location"; + info->name = "key"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_Sound *) node)->location; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PositionAnimator *) node)->key; return GF_OK; case 3: - info->name = "maxBack"; + info->name = "keyOrientation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Sound *) node)->maxBack; + info->fieldType = GF_SG_VRML_MFROTATION; + info->far_ptr = & ((M_PositionAnimator *) node)->keyOrientation; return GF_OK; case 4: - info->name = "maxFront"; + info->name = "keyType"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Sound *) node)->maxFront; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PositionAnimator *) node)->keyType; return GF_OK; case 5: - info->name = "minBack"; + info->name = "keySpline"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Sound *) node)->minBack; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_PositionAnimator *) node)->keySpline; return GF_OK; case 6: - info->name = "minFront"; + info->name = "keyValue"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Sound *) node)->minFront; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_PositionAnimator *) node)->keyValue; return GF_OK; case 7: - info->name = "priority"; + info->name = "keyValueType"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Sound *) node)->priority; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PositionAnimator *) node)->keyValueType; return GF_OK; case 8: - info->name = "source"; + info->name = "offset"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFAudioNode; - info->far_ptr = & ((M_Sound *)node)->source; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_PositionAnimator *) node)->offset; return GF_OK; case 9: - info->name = "spatialize"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Sound *) node)->spatialize; + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PositionAnimator *) node)->weight; + return GF_OK; + case 10: + info->name = "endValue"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_PositionAnimator *) node)->endValue; + return GF_OK; + case 11: + info->name = "rotation_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_PositionAnimator *) node)->rotation_changed; + return GF_OK; + case 12: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_PositionAnimator *) node)->value_changed; return GF_OK; default: return GF_BAD_PARAM; @@ -10777,70 +26347,47 @@ static GF_Err Sound_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Sound_get_field_index_by_name(char *name) +static s32 PositionAnimator_get_field_index_by_name(char *name) { - if (!strcmp("direction", name)) return 0; - if (!strcmp("intensity", name)) return 1; - if (!strcmp("location", name)) return 2; - if (!strcmp("maxBack", name)) return 3; - if (!strcmp("maxFront", name)) return 4; - if (!strcmp("minBack", name)) return 5; - if (!strcmp("minFront", name)) return 6; - if (!strcmp("priority", name)) return 7; - if (!strcmp("source", name)) return 8; - if (!strcmp("spatialize", name)) return 9; + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("fromTo", name)) return 1; + if (!strcmp("key", name)) return 2; + if (!strcmp("keyOrientation", name)) return 3; + if (!strcmp("keyType", name)) return 4; + if (!strcmp("keySpline", name)) return 5; + if (!strcmp("keyValue", name)) return 6; + if (!strcmp("keyValueType", name)) return 7; + if (!strcmp("offset", name)) return 8; + if (!strcmp("weight", name)) return 9; + if (!strcmp("endValue", name)) return 10; + if (!strcmp("rotation_changed", name)) return 11; + if (!strcmp("value_changed", name)) return 12; return -1; } -static Bool Sound_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool PositionAnimator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 0; - *QType = 9; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; case 1: - *AType = 7; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *AType = 0; + *QType = 8; return 1; case 2: - *AType = 1; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 3: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 4: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + *AType = 0; + *QType = 8; return 1; case 5: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + *AType = 0; + *QType = 8; return 1; case 6: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 7: *AType = 0; *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + return 1; + case 8: + *AType = 0; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; return 1; default: return 0; @@ -10849,105 +26396,158 @@ static Bool Sound_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, -GF_Node *Sound_Create() +GF_Node *PositionAnimator_Create() { - M_Sound *p; - GF_SAFEALLOC(p, M_Sound); + M_PositionAnimator *p; + GF_SAFEALLOC(p, M_PositionAnimator); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Sound); + gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionAnimator); /*default field values*/ - p->direction.x = FLT2FIX(0); - p->direction.y = FLT2FIX(0); - p->direction.z = FLT2FIX(1); - p->intensity = FLT2FIX(1); - p->location.x = FLT2FIX(0); - p->location.y = FLT2FIX(0); - p->location.z = FLT2FIX(0); - p->maxBack = FLT2FIX(10); - p->maxFront = FLT2FIX(10); - p->minBack = FLT2FIX(1); - p->minFront = FLT2FIX(1); - p->priority = FLT2FIX(0); - p->spatialize = 1; + p->fromTo.x = FLT2FIX(0); + p->fromTo.y = FLT2FIX(1); + p->keyType = 0; + p->keySpline.vals = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*2); + p->keySpline.count = 2; + p->keySpline.vals[0].x = FLT2FIX(0); + p->keySpline.vals[0].y = FLT2FIX(0); + p->keySpline.vals[1].x = FLT2FIX(1); + p->keySpline.vals[1].y = FLT2FIX(1); + p->keyValueType = 0; + p->offset.x = FLT2FIX(0); + p->offset.y = FLT2FIX(0); + p->offset.z = FLT2FIX(0); return (GF_Node *)p; } /* - Sound2D Node deletion + PositionAnimator2D Node deletion */ -static void Sound2D_Del(GF_Node *node) +static void PositionAnimator2D_Del(GF_Node *node) { - M_Sound2D *p = (M_Sound2D *) node; - gf_node_unregister((GF_Node *) p->source, (GF_Node *) p); + M_PositionAnimator2D *p = (M_PositionAnimator2D *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfvec2f_del(p->keySpline); + gf_sg_mfvec2f_del(p->keyValue); + gf_sg_mffloat_del(p->weight); gf_node_free((GF_Node *) p); } -static const u16 Sound2D_Def2All[] = { 0, 1, 2, 3}; -static const u16 Sound2D_In2All[] = { 0, 1, 2}; -static const u16 Sound2D_Out2All[] = { 0, 1, 2}; -static const u16 Sound2D_Dyn2All[] = { 0, 1}; +static const u16 PositionAnimator2D_Def2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 PositionAnimator2D_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 PositionAnimator2D_Out2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; -static u32 Sound2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 PositionAnimator2D_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 4; - case GF_SG_FIELD_CODING_OUT: return 3; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_IN: return 10; + case GF_SG_FIELD_CODING_DEF: return 9; + case GF_SG_FIELD_CODING_OUT: return 12; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 4; + return 13; } } -static GF_Err Sound2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err PositionAnimator2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Sound2D_In2All[inField]; + *allField = PositionAnimator2D_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Sound2D_Def2All[inField]; + *allField = PositionAnimator2D_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Sound2D_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Sound2D_Dyn2All[inField]; + *allField = PositionAnimator2D_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Sound2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err PositionAnimator2D_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "intensity"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_PositionAnimator2D *)node)->on_set_fraction; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Sound2D *) node)->intensity; + info->far_ptr = & ((M_PositionAnimator2D *) node)->set_fraction; return GF_OK; case 1: - info->name = "location"; + info->name = "fromTo"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Sound2D *) node)->location; + info->far_ptr = & ((M_PositionAnimator2D *) node)->fromTo; return GF_OK; case 2: - info->name = "source"; + info->name = "key"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFAudioNode; - info->far_ptr = & ((M_Sound2D *)node)->source; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PositionAnimator2D *) node)->key; return GF_OK; case 3: - info->name = "spatialize"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Sound2D *) node)->spatialize; + info->name = "keyOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PositionAnimator2D *) node)->keyOrientation; + return GF_OK; + case 4: + info->name = "keyType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PositionAnimator2D *) node)->keyType; + return GF_OK; + case 5: + info->name = "keySpline"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_PositionAnimator2D *) node)->keySpline; + return GF_OK; + case 6: + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_PositionAnimator2D *) node)->keyValue; + return GF_OK; + case 7: + info->name = "keyValueType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PositionAnimator2D *) node)->keyValueType; + return GF_OK; + case 8: + info->name = "offset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PositionAnimator2D *) node)->offset; + return GF_OK; + case 9: + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PositionAnimator2D *) node)->weight; + return GF_OK; + case 10: + info->name = "endValue"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PositionAnimator2D *) node)->endValue; + return GF_OK; + case 11: + info->name = "rotation_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PositionAnimator2D *) node)->rotation_changed; + return GF_OK; + case 12: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_PositionAnimator2D *) node)->value_changed; return GF_OK; default: return GF_BAD_PARAM; @@ -10955,25 +26555,44 @@ static GF_Err Sound2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Sound2D_get_field_index_by_name(char *name) +static s32 PositionAnimator2D_get_field_index_by_name(char *name) { - if (!strcmp("intensity", name)) return 0; - if (!strcmp("location", name)) return 1; - if (!strcmp("source", name)) return 2; - if (!strcmp("spatialize", name)) return 3; + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("fromTo", name)) return 1; + if (!strcmp("key", name)) return 2; + if (!strcmp("keyOrientation", name)) return 3; + if (!strcmp("keyType", name)) return 4; + if (!strcmp("keySpline", name)) return 5; + if (!strcmp("keyValue", name)) return 6; + if (!strcmp("keyValueType", name)) return 7; + if (!strcmp("offset", name)) return 8; + if (!strcmp("weight", name)) return 9; + if (!strcmp("endValue", name)) return 10; + if (!strcmp("rotation_changed", name)) return 11; + if (!strcmp("value_changed", name)) return 12; return -1; } -static Bool Sound2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool PositionAnimator2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 7; + case 1: + *AType = 0; + *QType = 8; + return 1; + case 2: + *AType = 0; + *QType = 8; + return 1; + case 5: + *AType = 0; + *QType = 8; + return 1; + case 6: + *AType = 0; *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); return 1; - case 1: - *AType = 2; + case 8: + *AType = 0; *QType = 2; *b_min = FIX_MIN; *b_max = FIX_MAX; @@ -10985,64 +26604,102 @@ static Bool Sound2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType -GF_Node *Sound2D_Create() +GF_Node *PositionAnimator2D_Create() { - M_Sound2D *p; - GF_SAFEALLOC(p, M_Sound2D); + M_PositionAnimator2D *p; + GF_SAFEALLOC(p, M_PositionAnimator2D); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Sound2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionAnimator2D); /*default field values*/ - p->intensity = FLT2FIX(1); - p->location.x = FLT2FIX(0); - p->location.y = FLT2FIX(0); - p->spatialize = 1; + p->fromTo.x = FLT2FIX(0); + p->fromTo.y = FLT2FIX(1); + p->keyOrientation = 0; + p->keyType = 0; + p->keySpline.vals = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*2); + p->keySpline.count = 2; + p->keySpline.vals[0].x = FLT2FIX(0); + p->keySpline.vals[0].y = FLT2FIX(0); + p->keySpline.vals[1].x = FLT2FIX(1); + p->keySpline.vals[1].y = FLT2FIX(1); + p->keyValueType = 0; + p->offset.x = FLT2FIX(0); + p->offset.y = FLT2FIX(0); return (GF_Node *)p; } /* - Sphere Node deletion + PositionInterpolator4D Node deletion */ -static void Sphere_Del(GF_Node *node) +static void PositionInterpolator4D_Del(GF_Node *node) { - M_Sphere *p = (M_Sphere *) node; + M_PositionInterpolator4D *p = (M_PositionInterpolator4D *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfvec4f_del(p->keyValue); gf_node_free((GF_Node *) p); } -static const u16 Sphere_Def2All[] = { 0}; +static const u16 PositionInterpolator4D_Def2All[] = { 1, 2}; +static const u16 PositionInterpolator4D_In2All[] = { 0, 1, 2}; +static const u16 PositionInterpolator4D_Out2All[] = { 1, 2, 3}; -static u32 Sphere_get_field_count(GF_Node *node, u8 IndexMode) +static u32 PositionInterpolator4D_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 0; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 3; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 1; + return 4; } } -static GF_Err Sphere_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err PositionInterpolator4D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = PositionInterpolator4D_In2All[inField]; + return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Sphere_Def2All[inField]; + *allField = PositionInterpolator4D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = PositionInterpolator4D_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Sphere_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err PositionInterpolator4D_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "radius"; - info->eventType = GF_SG_EVENT_FIELD; + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_PositionInterpolator4D *)node)->on_set_fraction; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Sphere *) node)->radius; + info->far_ptr = & ((M_PositionInterpolator4D *) node)->set_fraction; + return GF_OK; + case 1: + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_PositionInterpolator4D *) node)->key; + return GF_OK; + case 2: + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC4F; + info->far_ptr = & ((M_PositionInterpolator4D *) node)->keyValue; + return GF_OK; + case 3: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC4F; + info->far_ptr = & ((M_PositionInterpolator4D *) node)->value_changed; return GF_OK; default: return GF_BAD_PARAM; @@ -11050,18 +26707,27 @@ static GF_Err Sphere_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Sphere_get_field_index_by_name(char *name) +static s32 PositionInterpolator4D_get_field_index_by_name(char *name) { - if (!strcmp("radius", name)) return 0; + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("key", name)) return 1; + if (!strcmp("keyValue", name)) return 2; + if (!strcmp("value_changed", name)) return 3; return -1; } -static Bool Sphere_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool PositionInterpolator4D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: + case 1: *AType = 0; - *QType = 11; + *QType = 8; *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 0; + *QType = 15; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; default: @@ -11071,99 +26737,190 @@ static Bool Sphere_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, -GF_Node *Sphere_Create() +GF_Node *PositionInterpolator4D_Create() { - M_Sphere *p; - GF_SAFEALLOC(p, M_Sphere); + M_PositionInterpolator4D *p; + GF_SAFEALLOC(p, M_PositionInterpolator4D); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Sphere); + gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionInterpolator4D); /*default field values*/ - p->radius = FLT2FIX(1); return (GF_Node *)p; } /* - SphereSensor Node deletion + ProceduralTexture Node deletion */ -static void SphereSensor_Del(GF_Node *node) +static void ProceduralTexture_Del(GF_Node *node) { - M_SphereSensor *p = (M_SphereSensor *) node; + M_ProceduralTexture *p = (M_ProceduralTexture *) node; + gf_sg_mfvec2f_del(p->aWarpmap); + gf_sg_mffloat_del(p->aWeights); + gf_sg_mfvec2f_del(p->bWarpmap); + gf_sg_mffloat_del(p->bWeights); + gf_sg_mfcolor_del(p->color); + gf_sg_mfvec2f_del(p->xWarpmap); + gf_sg_mfvec2f_del(p->yWarpmap); + gf_sg_sfimage_del(p->image_changed); gf_node_free((GF_Node *) p); } -static const u16 SphereSensor_Def2All[] = { 0, 1, 2}; -static const u16 SphereSensor_In2All[] = { 0, 1, 2}; -static const u16 SphereSensor_Out2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 ProceduralTexture_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; +static const u16 ProceduralTexture_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; +static const u16 ProceduralTexture_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}; -static u32 SphereSensor_get_field_count(GF_Node *node, u8 IndexMode) +static u32 ProceduralTexture_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_IN: return 19; + case GF_SG_FIELD_CODING_DEF: return 19; + case GF_SG_FIELD_CODING_OUT: return 20; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 6; + return 20; } } -static GF_Err SphereSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err ProceduralTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = SphereSensor_In2All[inField]; + *allField = ProceduralTexture_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = SphereSensor_Def2All[inField]; + *allField = ProceduralTexture_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = SphereSensor_Out2All[inField]; + *allField = ProceduralTexture_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err SphereSensor_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err ProceduralTexture_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "autoOffset"; + info->name = "aSmooth"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_SphereSensor *) node)->autoOffset; + info->far_ptr = & ((M_ProceduralTexture *) node)->aSmooth; return GF_OK; case 1: - info->name = "enabled"; + info->name = "aWarpmap"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_SphereSensor *) node)->enabled; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_ProceduralTexture *) node)->aWarpmap; return GF_OK; case 2: - info->name = "offset"; + info->name = "aWeights"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_SphereSensor *) node)->offset; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_ProceduralTexture *) node)->aWeights; return GF_OK; case 3: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; + info->name = "bSmooth"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_SphereSensor *) node)->isActive; + info->far_ptr = & ((M_ProceduralTexture *) node)->bSmooth; return GF_OK; case 4: - info->name = "rotation_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_SphereSensor *) node)->rotation_changed; + info->name = "bWarpmap"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_ProceduralTexture *) node)->bWarpmap; return GF_OK; case 5: - info->name = "trackPoint_changed"; + info->name = "bWeights"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_ProceduralTexture *) node)->bWeights; + return GF_OK; + case 6: + info->name = "cellWidth"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_ProceduralTexture *) node)->cellWidth; + return GF_OK; + case 7: + info->name = "cellHeight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_ProceduralTexture *) node)->cellHeight; + return GF_OK; + case 8: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFCOLOR; + info->far_ptr = & ((M_ProceduralTexture *) node)->color; + return GF_OK; + case 9: + info->name = "distortion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ProceduralTexture *) node)->distortion; + return GF_OK; + case 10: + info->name = "height"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_ProceduralTexture *) node)->height; + return GF_OK; + case 11: + info->name = "roughness"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_ProceduralTexture *) node)->roughness; + return GF_OK; + case 12: + info->name = "seed"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_ProceduralTexture *) node)->seed; + return GF_OK; + case 13: + info->name = "type"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_ProceduralTexture *) node)->type; + return GF_OK; + case 14: + info->name = "xSmooth"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ProceduralTexture *) node)->xSmooth; + return GF_OK; + case 15: + info->name = "xWarpmap"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_ProceduralTexture *) node)->xWarpmap; + return GF_OK; + case 16: + info->name = "ySmooth"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_ProceduralTexture *) node)->ySmooth; + return GF_OK; + case 17: + info->name = "yWarpmap"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_ProceduralTexture *) node)->yWarpmap; + return GF_OK; + case 18: + info->name = "width"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_ProceduralTexture *) node)->width; + return GF_OK; + case 19: + info->name = "image_changed"; info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_SphereSensor *) node)->trackPoint_changed; + info->fieldType = GF_SG_VRML_SFIMAGE; + info->far_ptr = & ((M_ProceduralTexture *) node)->image_changed; return GF_OK; default: return GF_BAD_PARAM; @@ -11171,24 +26928,109 @@ static GF_Err SphereSensor_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 SphereSensor_get_field_index_by_name(char *name) -{ - if (!strcmp("autoOffset", name)) return 0; - if (!strcmp("enabled", name)) return 1; - if (!strcmp("offset", name)) return 2; - if (!strcmp("isActive", name)) return 3; - if (!strcmp("rotation_changed", name)) return 4; - if (!strcmp("trackPoint_changed", name)) return 5; +static s32 ProceduralTexture_get_field_index_by_name(char *name) +{ + if (!strcmp("aSmooth", name)) return 0; + if (!strcmp("aWarpmap", name)) return 1; + if (!strcmp("aWeights", name)) return 2; + if (!strcmp("bSmooth", name)) return 3; + if (!strcmp("bWarpmap", name)) return 4; + if (!strcmp("bWeights", name)) return 5; + if (!strcmp("cellWidth", name)) return 6; + if (!strcmp("cellHeight", name)) return 7; + if (!strcmp("color", name)) return 8; + if (!strcmp("distortion", name)) return 9; + if (!strcmp("height", name)) return 10; + if (!strcmp("roughness", name)) return 11; + if (!strcmp("seed", name)) return 12; + if (!strcmp("type", name)) return 13; + if (!strcmp("xSmooth", name)) return 14; + if (!strcmp("xWarpmap", name)) return 15; + if (!strcmp("ySmooth", name)) return 16; + if (!strcmp("yWarpmap", name)) return 17; + if (!strcmp("width", name)) return 18; + if (!strcmp("image_changed", name)) return 19; return -1; } -static Bool SphereSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool ProceduralTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 2: + case 1: *AType = 0; - *QType = 10; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 4: + *AType = 0; + *QType = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX( 1); + return 1; + case 6: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(15); + return 1; + case 7: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(15); + return 1; + case 8: + *AType = 0; + *QType = 4; + return 1; + case 9: + *AType = 0; + *QType = 13; + *QT13_bits = 16; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 10: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(1); + *b_max = FLT2FIX(15); + return 1; + case 11: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(15); + return 1; + case 13: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(4); + return 1; + case 15: + *AType = 0; + *QType = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 17: + *AType = 0; + *QType = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 18: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(1); + *b_max = FLT2FIX(15); return 1; default: return 0; @@ -11197,132 +27039,197 @@ static Bool SphereSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 * -GF_Node *SphereSensor_Create() +GF_Node *ProceduralTexture_Create() { - M_SphereSensor *p; - GF_SAFEALLOC(p, M_SphereSensor); + M_ProceduralTexture *p; + GF_SAFEALLOC(p, M_ProceduralTexture); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_SphereSensor); + gf_node_setup((GF_Node *)p, TAG_MPEG4_ProceduralTexture); /*default field values*/ - p->autoOffset = 1; - p->enabled = 1; - p->offset.x = FLT2FIX(0); - p->offset.y = FLT2FIX(1); - p->offset.z = FLT2FIX(0); - p->offset.q = FLT2FIX(0); + p->aWarpmap.vals = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*2); + p->aWarpmap.count = 2; + p->aWarpmap.vals[0].x = FLT2FIX(0); + p->aWarpmap.vals[0].y = FLT2FIX(0); + p->aWarpmap.vals[1].x = FLT2FIX(1); + p->aWarpmap.vals[1].y = FLT2FIX(1); + p->aWeights.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*16); + p->aWeights.count = 16; + p->aWeights.vals[0] = FLT2FIX(0); + p->aWeights.vals[1] = FLT2FIX(0); + p->aWeights.vals[2] = FLT2FIX(0); + p->aWeights.vals[3] = FLT2FIX(0); + p->aWeights.vals[4] = FLT2FIX(0); + p->aWeights.vals[5] = FLT2FIX(0); + p->aWeights.vals[6] = FLT2FIX(0); + p->aWeights.vals[7] = FLT2FIX(0); + p->aWeights.vals[8] = FLT2FIX(0); + p->aWeights.vals[9] = FLT2FIX(0); + p->aWeights.vals[10] = FLT2FIX(0); + p->aWeights.vals[11] = FLT2FIX(0); + p->aWeights.vals[12] = FLT2FIX(1); + p->aWeights.vals[13] = FLT2FIX(0); + p->aWeights.vals[14] = FLT2FIX(0); + p->aWeights.vals[15] = FLT2FIX(0); + p->bWarpmap.vals = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*2); + p->bWarpmap.count = 2; + p->bWarpmap.vals[0].x = FLT2FIX(0); + p->bWarpmap.vals[0].y = FLT2FIX(0); + p->bWarpmap.vals[1].x = FLT2FIX(1); + p->bWarpmap.vals[1].y = FLT2FIX(1); + p->bWeights.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*16); + p->bWeights.count = 16; + p->bWeights.vals[0] = FLT2FIX(0); + p->bWeights.vals[1] = FLT2FIX(0); + p->bWeights.vals[2] = FLT2FIX(0); + p->bWeights.vals[3] = FLT2FIX(0); + p->bWeights.vals[4] = FLT2FIX(0); + p->bWeights.vals[5] = FLT2FIX(1); + p->bWeights.vals[6] = FLT2FIX(0); + p->bWeights.vals[7] = FLT2FIX(0); + p->bWeights.vals[8] = FLT2FIX(0); + p->bWeights.vals[9] = FLT2FIX(0); + p->bWeights.vals[10] = FLT2FIX(0); + p->bWeights.vals[11] = FLT2FIX(0); + p->bWeights.vals[12] = FLT2FIX(0); + p->bWeights.vals[13] = FLT2FIX(0); + p->bWeights.vals[14] = FLT2FIX(0); + p->bWeights.vals[15] = FLT2FIX(0); + p->cellWidth = 4; + p->cellHeight = 4; + p->color.vals = (SFColor*)gf_malloc(sizeof(SFColor)*4); + p->color.count = 4; + p->color.vals[0].red = FLT2FIX(0.3); + p->color.vals[0].green = FLT2FIX(0.698); + p->color.vals[0].blue = FLT2FIX(1); + p->color.vals[1].red = FLT2FIX(0.8); + p->color.vals[1].green = FLT2FIX(0.8); + p->color.vals[1].blue = FLT2FIX(0.8); + p->color.vals[2].red = FLT2FIX(1); + p->color.vals[2].green = FLT2FIX(1); + p->color.vals[2].blue = FLT2FIX(1); + p->color.vals[3].red = FLT2FIX(0); + p->color.vals[3].green = FLT2FIX(0); + p->color.vals[3].blue = FLT2FIX(0); + p->distortion = FLT2FIX(0); + p->height = 7; + p->roughness = 0; + p->seed = 129093; + p->type = 0; + p->width = 7; return (GF_Node *)p; } /* - SpotLight Node deletion + Quadric Node deletion */ -static void SpotLight_Del(GF_Node *node) +static void Quadric_Del(GF_Node *node) { - M_SpotLight *p = (M_SpotLight *) node; + M_Quadric *p = (M_Quadric *) node; + gf_sg_mfint32_del(p->densities); gf_node_free((GF_Node *) p); } -static const u16 SpotLight_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 SpotLight_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 SpotLight_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 SpotLight_Dyn2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 9}; +static const u16 Quadric_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 Quadric_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 Quadric_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 Quadric_Dyn2All[] = { 0, 3, 4, 5, 6, 7, 8}; -static u32 SpotLight_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Quadric_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: return 10; case GF_SG_FIELD_CODING_DEF: return 10; case GF_SG_FIELD_CODING_OUT: return 10; - case GF_SG_FIELD_CODING_DYN: return 9; + case GF_SG_FIELD_CODING_DYN: return 7; default: return 10; } } -static GF_Err SpotLight_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Quadric_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = SpotLight_In2All[inField]; + *allField = Quadric_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = SpotLight_Def2All[inField]; + *allField = Quadric_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = SpotLight_Out2All[inField]; + *allField = Quadric_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = SpotLight_Dyn2All[inField]; + *allField = Quadric_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err SpotLight_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Quadric_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "ambientIntensity"; + info->name = "bboxSize"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_SpotLight *) node)->ambientIntensity; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Quadric *) node)->bboxSize; return GF_OK; case 1: - info->name = "attenuation"; + info->name = "densities"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_SpotLight *) node)->attenuation; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_Quadric *) node)->densities; return GF_OK; case 2: - info->name = "beamWidth"; + info->name = "dual"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_SpotLight *) node)->beamWidth; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Quadric *) node)->dual; return GF_OK; case 3: - info->name = "color"; + info->name = "P0"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_SpotLight *) node)->color; + info->fieldType = GF_SG_VRML_SFVEC4F; + info->far_ptr = & ((M_Quadric *) node)->P0; return GF_OK; case 4: - info->name = "cutOffAngle"; + info->name = "P1"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_SpotLight *) node)->cutOffAngle; + info->fieldType = GF_SG_VRML_SFVEC4F; + info->far_ptr = & ((M_Quadric *) node)->P1; return GF_OK; case 5: - info->name = "direction"; + info->name = "P2"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_SpotLight *) node)->direction; + info->fieldType = GF_SG_VRML_SFVEC4F; + info->far_ptr = & ((M_Quadric *) node)->P2; return GF_OK; case 6: - info->name = "intensity"; + info->name = "P3"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_SpotLight *) node)->intensity; + info->fieldType = GF_SG_VRML_SFVEC4F; + info->far_ptr = & ((M_Quadric *) node)->P3; return GF_OK; case 7: - info->name = "location"; + info->name = "P4"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_SpotLight *) node)->location; + info->fieldType = GF_SG_VRML_SFVEC4F; + info->far_ptr = & ((M_Quadric *) node)->P4; return GF_OK; case 8: - info->name = "on"; + info->name = "P5"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_SpotLight *) node)->on; + info->fieldType = GF_SG_VRML_SFVEC4F; + info->far_ptr = & ((M_Quadric *) node)->P5; return GF_OK; case 9: - info->name = "radius"; + info->name = "solid"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_SpotLight *) node)->radius; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Quadric *) node)->solid; return GF_OK; default: return GF_BAD_PARAM; @@ -11330,75 +27237,63 @@ static GF_Err SpotLight_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 SpotLight_get_field_index_by_name(char *name) -{ - if (!strcmp("ambientIntensity", name)) return 0; - if (!strcmp("attenuation", name)) return 1; - if (!strcmp("beamWidth", name)) return 2; - if (!strcmp("color", name)) return 3; - if (!strcmp("cutOffAngle", name)) return 4; - if (!strcmp("direction", name)) return 5; - if (!strcmp("intensity", name)) return 6; - if (!strcmp("location", name)) return 7; - if (!strcmp("on", name)) return 8; - if (!strcmp("radius", name)) return 9; +static s32 Quadric_get_field_index_by_name(char *name) +{ + if (!strcmp("bboxSize", name)) return 0; + if (!strcmp("densities", name)) return 1; + if (!strcmp("dual", name)) return 2; + if (!strcmp("P0", name)) return 3; + if (!strcmp("P1", name)) return 4; + if (!strcmp("P2", name)) return 5; + if (!strcmp("P3", name)) return 6; + if (!strcmp("P4", name)) return 7; + if (!strcmp("P5", name)) return 8; + if (!strcmp("solid", name)) return 9; return -1; } -static Bool SpotLight_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool Quadric_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { case 0: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 1: - *AType = 1; + *AType = 11; *QType = 11; *b_min = FLT2FIX(0); *b_max = FIX_MAX; return 1; - case 2: - *AType = 8; - *QType = 6; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1.5707963); - return 1; case 3: - *AType = 4; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *AType = 15; + *QType = 15; + *b_min = FIX_MIN; + *b_max = FIX_MAX; return 1; case 4: - *AType = 8; - *QType = 6; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1.5707963); + *AType = 15; + *QType = 15; + *b_min = FIX_MIN; + *b_max = FIX_MAX; return 1; case 5: - *AType = 9; - *QType = 9; + *AType = 15; + *QType = 15; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 6: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *AType = 15; + *QType = 15; + *b_min = FIX_MIN; + *b_max = FIX_MAX; return 1; case 7: - *AType = 1; - *QType = 1; + *AType = 15; + *QType = 15; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 9: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); + case 8: + *AType = 15; + *QType = 15; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; default: @@ -11408,94 +27303,254 @@ static Bool SpotLight_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATy -GF_Node *SpotLight_Create() +GF_Node *Quadric_Create() { - M_SpotLight *p; - GF_SAFEALLOC(p, M_SpotLight); + M_Quadric *p; + GF_SAFEALLOC(p, M_Quadric); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_SpotLight); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Quadric); /*default field values*/ - p->ambientIntensity = FLT2FIX(0); - p->attenuation.x = FLT2FIX(1); - p->attenuation.y = FLT2FIX(0); - p->attenuation.z = FLT2FIX(0); - p->beamWidth = FLT2FIX(1.570796); - p->color.red = FLT2FIX(1); - p->color.green = FLT2FIX(1); - p->color.blue = FLT2FIX(1); - p->cutOffAngle = FLT2FIX(0.785398); - p->direction.x = FLT2FIX(0); - p->direction.y = FLT2FIX(0); - p->direction.z = FLT2FIX(-1); - p->intensity = FLT2FIX(1); - p->location.x = FLT2FIX(0); - p->location.y = FLT2FIX(0); - p->location.z = FLT2FIX(0); - p->on = 1; - p->radius = FLT2FIX(100); + p->bboxSize.x = FLT2FIX(2); + p->bboxSize.y = FLT2FIX(2); + p->bboxSize.z = FLT2FIX(2); + p->P0.x = FLT2FIX(-1); + p->P0.y = FLT2FIX(0); + p->P0.z = FLT2FIX(0); + p->P0.q = FLT2FIX(1); + p->P1.x = FLT2FIX(1); + p->P1.y = FLT2FIX(0); + p->P1.z = FLT2FIX(0); + p->P1.q = FLT2FIX(1); + p->P2.x = FLT2FIX(0); + p->P2.y = FLT2FIX(1); + p->P2.z = FLT2FIX(0); + p->P2.q = FLT2FIX(0); + p->P3.x = FLT2FIX(0); + p->P3.y = FLT2FIX(0); + p->P3.z = FLT2FIX(1); + p->P3.q = FLT2FIX(0); + p->P4.x = FLT2FIX(0); + p->P4.y = FLT2FIX(1); + p->P4.z = FLT2FIX(0); + p->P4.q = FLT2FIX(1); + p->P5.x = FLT2FIX(0); + p->P5.y = FLT2FIX(0); + p->P5.z = FLT2FIX(1); + p->P5.q = FLT2FIX(1); return (GF_Node *)p; } /* - Switch Node deletion + SBBone Node deletion */ -static void Switch_Del(GF_Node *node) -{ - M_Switch *p = (M_Switch *) node; - gf_node_unregister_children((GF_Node *) p, p->choice); +static void SBBone_Del(GF_Node *node) +{ + M_SBBone *p = (M_SBBone *) node; + gf_sg_mffloat_del(p->ikPitchLimit); + gf_sg_mffloat_del(p->ikRollLimit); + gf_sg_mffloat_del(p->ikTxLimit); + gf_sg_mffloat_del(p->ikTyLimit); + gf_sg_mffloat_del(p->ikTzLimit); + gf_sg_mffloat_del(p->ikYawLimit); + gf_sg_mffloat_del(p->sectionInner); + gf_sg_mffloat_del(p->sectionOuter); + gf_sg_mffloat_del(p->sectionPosition); + gf_sg_mfint32_del(p->skinCoordIndex); + gf_sg_mffloat_del(p->skinCoordWeight); + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Switch_Def2All[] = { 0, 1}; -static const u16 Switch_In2All[] = { 0, 1}; -static const u16 Switch_Out2All[] = { 0, 1}; +static const u16 SBBone_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}; +static const u16 SBBone_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}; +static const u16 SBBone_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}; +static const u16 SBBone_Dyn2All[] = { 3, 5, 14, 16, 17, 23}; -static u32 Switch_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SBBone_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 2; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 2; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 24; + case GF_SG_FIELD_CODING_DEF: return 22; + case GF_SG_FIELD_CODING_OUT: return 22; + case GF_SG_FIELD_CODING_DYN: return 6; default: - return 2; + return 24; } } -static GF_Err Switch_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SBBone_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Switch_In2All[inField]; + *allField = SBBone_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Switch_Def2All[inField]; + *allField = SBBone_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Switch_Out2All[inField]; + *allField = SBBone_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = SBBone_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Switch_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SBBone_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "choice"; + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SBBone *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBBone *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SBBone *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBBone *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "boneID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SBBone *) node)->boneID; + return GF_OK; + case 3: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBBone *) node)->center; + return GF_OK; + case 4: + info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFNODE; info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Switch *)node)->choice; + info->far_ptr = & ((M_SBBone *)node)->children; return GF_OK; - case 1: - info->name = "whichChoice"; + case 5: + info->name = "endpoint"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBBone *) node)->endpoint; + return GF_OK; + case 6: + info->name = "falloff"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_Switch *) node)->whichChoice; + info->far_ptr = & ((M_SBBone *) node)->falloff; + return GF_OK; + case 7: + info->name = "ikChainPosition"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SBBone *) node)->ikChainPosition; + return GF_OK; + case 8: + info->name = "ikPitchLimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->ikPitchLimit; + return GF_OK; + case 9: + info->name = "ikRollLimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->ikRollLimit; + return GF_OK; + case 10: + info->name = "ikTxLimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->ikTxLimit; + return GF_OK; + case 11: + info->name = "ikTyLimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->ikTyLimit; + return GF_OK; + case 12: + info->name = "ikTzLimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->ikTzLimit; + return GF_OK; + case 13: + info->name = "ikYawLimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->ikYawLimit; + return GF_OK; + case 14: + info->name = "rotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_SBBone *) node)->rotation; + return GF_OK; + case 15: + info->name = "rotationOrder"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SBBone *) node)->rotationOrder; + return GF_OK; + case 16: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBBone *) node)->scale; + return GF_OK; + case 17: + info->name = "scaleOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_SBBone *) node)->scaleOrientation; + return GF_OK; + case 18: + info->name = "sectionInner"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->sectionInner; + return GF_OK; + case 19: + info->name = "sectionOuter"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->sectionOuter; + return GF_OK; + case 20: + info->name = "sectionPosition"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->sectionPosition; + return GF_OK; + case 21: + info->name = "skinCoordIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SBBone *) node)->skinCoordIndex; + return GF_OK; + case 22: + info->name = "skinCoordWeight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBBone *) node)->skinCoordWeight; + return GF_OK; + case 23: + info->name = "translation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBBone *) node)->translation; return GF_OK; default: return GF_BAD_PARAM; @@ -11503,21 +27558,92 @@ static GF_Err Switch_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Switch_get_field_index_by_name(char *name) +static s32 SBBone_get_field_index_by_name(char *name) { - if (!strcmp("choice", name)) return 0; - if (!strcmp("whichChoice", name)) return 1; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("boneID", name)) return 2; + if (!strcmp("center", name)) return 3; + if (!strcmp("children", name)) return 4; + if (!strcmp("endpoint", name)) return 5; + if (!strcmp("falloff", name)) return 6; + if (!strcmp("ikChainPosition", name)) return 7; + if (!strcmp("ikPitchLimit", name)) return 8; + if (!strcmp("ikRollLimit", name)) return 9; + if (!strcmp("ikTxLimit", name)) return 10; + if (!strcmp("ikTyLimit", name)) return 11; + if (!strcmp("ikTzLimit", name)) return 12; + if (!strcmp("ikYawLimit", name)) return 13; + if (!strcmp("rotation", name)) return 14; + if (!strcmp("rotationOrder", name)) return 15; + if (!strcmp("scale", name)) return 16; + if (!strcmp("scaleOrientation", name)) return 17; + if (!strcmp("sectionInner", name)) return 18; + if (!strcmp("sectionOuter", name)) return 19; + if (!strcmp("sectionPosition", name)) return 20; + if (!strcmp("skinCoordIndex", name)) return 21; + if (!strcmp("skinCoordWeight", name)) return 22; + if (!strcmp("translation", name)) return 23; return -1; } -static Bool Switch_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SBBone_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: + case 2: *AType = 0; *QType = 13; *QT13_bits = 10; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1023); + return 1; + case 3: + *AType = 1; + *QType = 1; + return 1; + case 5: + *AType = 1; + *QType = 1; + return 1; + case 6: + *AType = 0; + *QType = 13; + *QT13_bits = 3; *b_min = FLT2FIX(-1); - *b_max = FLT2FIX( 1022); + *b_max = FLT2FIX(4); + return 1; + case 7: + *AType = 0; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(3); + return 1; + case 14: + *AType = 10; + *QType = 10; + return 1; + case 15: + *AType = 0; + *QType = 13; + *QT13_bits = 5; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(23); + return 1; + case 16: + *AType = 11; + *QType = 7; + return 1; + case 17: + *AType = 10; + *QType = 10; + return 1; + case 21: + *AType = 0; + *QType = 14; + return 1; + case 23: + *AType = 1; + *QType = 1; return 1; default: return 0; @@ -11526,82 +27652,131 @@ static Bool Switch_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, -GF_Node *Switch_Create() +GF_Node *SBBone_Create() { - M_Switch *p; - GF_SAFEALLOC(p, M_Switch); + M_SBBone *p; + GF_SAFEALLOC(p, M_SBBone); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Switch); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SBBone); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->whichChoice = -1; + p->boneID = 0; + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->endpoint.x = FLT2FIX(0); + p->endpoint.y = FLT2FIX(0); + p->endpoint.z = FLT2FIX(1); + p->falloff = 1; + p->ikChainPosition = 0; + p->rotation.x = FLT2FIX(0); + p->rotation.y = FLT2FIX(0); + p->rotation.z = FLT2FIX(1); + p->rotation.q = FLT2FIX(0); + p->rotationOrder = 0; + p->scale.x = FLT2FIX(0); + p->scale.y = FLT2FIX(0); + p->scale.z = FLT2FIX(0); + p->scaleOrientation.x = FLT2FIX(0); + p->scaleOrientation.y = FLT2FIX(0); + p->scaleOrientation.z = FLT2FIX(1); + p->scaleOrientation.q = FLT2FIX(0); + p->translation.x = FLT2FIX(0); + p->translation.y = FLT2FIX(0); + p->translation.z = FLT2FIX(0); return (GF_Node *)p; } /* - TermCap Node deletion + SBMuscle Node deletion */ -static void TermCap_Del(GF_Node *node) +static void SBMuscle_Del(GF_Node *node) { - M_TermCap *p = (M_TermCap *) node; + M_SBMuscle *p = (M_SBMuscle *) node; + gf_node_unregister((GF_Node *) p->muscleCurve, (GF_Node *) p); + gf_sg_mfint32_del(p->skinCoordIndex); + gf_sg_mffloat_del(p->skinCoordWeight); gf_node_free((GF_Node *) p); } -static const u16 TermCap_Def2All[] = { 1}; -static const u16 TermCap_In2All[] = { 0, 1}; -static const u16 TermCap_Out2All[] = { 1, 2}; +static const u16 SBMuscle_Def2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 SBMuscle_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 SBMuscle_Out2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 SBMuscle_Dyn2All[] = { 3}; -static u32 TermCap_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SBMuscle_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 2; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 2; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_DYN: return 1; default: - return 3; + return 6; } } -static GF_Err TermCap_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SBMuscle_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = TermCap_In2All[inField]; + *allField = SBMuscle_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = TermCap_Def2All[inField]; + *allField = SBMuscle_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = TermCap_Out2All[inField]; + *allField = SBMuscle_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = SBMuscle_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err TermCap_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SBMuscle_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "evaluate"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_TermCap *)node)->on_evaluate; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TermCap *) node)->evaluate; + info->name = "falloff"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SBMuscle *) node)->falloff; return GF_OK; case 1: - info->name = "capability"; + info->name = "muscleCurve"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_TermCap *) node)->capability; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_SBMuscle *)node)->muscleCurve; return GF_OK; case 2: - info->name = "value"; - info->eventType = GF_SG_EVENT_OUT; + info->name = "muscleID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_TermCap *) node)->value; + info->far_ptr = & ((M_SBMuscle *) node)->muscleID; + return GF_OK; + case 3: + info->name = "radius"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SBMuscle *) node)->radius; + return GF_OK; + case 4: + info->name = "skinCoordIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SBMuscle *) node)->skinCoordIndex; + return GF_OK; + case 5: + info->name = "skinCoordWeight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_SBMuscle *) node)->skinCoordWeight; return GF_OK; default: return GF_BAD_PARAM; @@ -11609,29 +27784,42 @@ static GF_Err TermCap_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 TermCap_get_field_index_by_name(char *name) +static s32 SBMuscle_get_field_index_by_name(char *name) { - if (!strcmp("evaluate", name)) return 0; - if (!strcmp("capability", name)) return 1; - if (!strcmp("value", name)) return 2; + if (!strcmp("falloff", name)) return 0; + if (!strcmp("muscleCurve", name)) return 1; + if (!strcmp("muscleID", name)) return 2; + if (!strcmp("radius", name)) return 3; + if (!strcmp("skinCoordIndex", name)) return 4; + if (!strcmp("skinCoordWeight", name)) return 5; return -1; } -static Bool TermCap_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SBMuscle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: + case 0: *AType = 0; *QType = 13; - *QT13_bits = 7; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(127); + *QT13_bits = 3; + *b_min = FLT2FIX(-1); + *b_max = FLT2FIX(4); return 1; case 2: *AType = 0; *QType = 13; - *QT13_bits = 3; + *QT13_bits = 10; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(7); + *b_max = FLT2FIX(1023); + return 1; + case 3: + *AType = 11; + *QType = 7; + return 1; + case 4: + *AType = 0; + *QType = 14; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; return 1; default: return 0; @@ -11640,95 +27828,119 @@ static Bool TermCap_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType -GF_Node *TermCap_Create() +GF_Node *SBMuscle_Create() { - M_TermCap *p; - GF_SAFEALLOC(p, M_TermCap); + M_SBMuscle *p; + GF_SAFEALLOC(p, M_SBMuscle); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_TermCap); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SBMuscle); /*default field values*/ - p->capability = 0; + p->falloff = 1; + p->muscleID = 0; + p->radius = 1; return (GF_Node *)p; } /* - Text Node deletion + SBSegment Node deletion */ -static void Text_Del(GF_Node *node) +static void SBSegment_Del(GF_Node *node) { - M_Text *p = (M_Text *) node; - gf_sg_mfstring_del(p->string); - gf_sg_mffloat_del(p->length); - gf_node_unregister((GF_Node *) p->fontStyle, (GF_Node *) p); + M_SBSegment *p = (M_SBSegment *) node; + gf_sg_mfvec3f_del(p->momentsOfInertia); + gf_sg_sfstring_del(p->name); + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Text_Def2All[] = { 0, 1, 2, 3}; -static const u16 Text_In2All[] = { 0, 1, 2, 3}; -static const u16 Text_Out2All[] = { 0, 1, 2, 3}; -static const u16 Text_Dyn2All[] = { 1, 3}; +static const u16 SBSegment_Def2All[] = { 2, 3, 4, 5, 6}; +static const u16 SBSegment_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 SBSegment_Out2All[] = { 2, 3, 4, 5, 6}; +static const u16 SBSegment_Dyn2All[] = { 2}; -static u32 Text_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SBSegment_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 4; - case GF_SG_FIELD_CODING_OUT: return 4; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_IN: return 7; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_DYN: return 1; default: - return 4; + return 7; } } -static GF_Err Text_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SBSegment_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Text_In2All[inField]; + *allField = SBSegment_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Text_Def2All[inField]; + *allField = SBSegment_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Text_Out2All[inField]; + *allField = SBSegment_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = Text_Dyn2All[inField]; + *allField = SBSegment_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Text_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SBSegment_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "string"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_Text *) node)->string; + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SBSegment *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBSegment *)node)->addChildren; return GF_OK; case 1: - info->name = "length"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_Text *) node)->length; + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SBSegment *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBSegment *)node)->removeChildren; return GF_OK; case 2: - info->name = "fontStyle"; + info->name = "centerOfMass"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFFontStyleNode; - info->far_ptr = & ((M_Text *)node)->fontStyle; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBSegment *) node)->centerOfMass; return GF_OK; case 3: - info->name = "maxExtent"; + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBSegment *)node)->children; + return GF_OK; + case 4: + info->name = "mass"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Text *) node)->maxExtent; + info->far_ptr = & ((M_SBSegment *) node)->mass; + return GF_OK; + case 5: + info->name = "momentsOfInertia"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_SBSegment *) node)->momentsOfInertia; + return GF_OK; + case 6: + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_SBSegment *) node)->name; return GF_OK; default: return GF_BAD_PARAM; @@ -11736,28 +27948,23 @@ static GF_Err Text_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Text_get_field_index_by_name(char *name) +static s32 SBSegment_get_field_index_by_name(char *name) { - if (!strcmp("string", name)) return 0; - if (!strcmp("length", name)) return 1; - if (!strcmp("fontStyle", name)) return 2; - if (!strcmp("maxExtent", name)) return 3; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("centerOfMass", name)) return 2; + if (!strcmp("children", name)) return 3; + if (!strcmp("mass", name)) return 4; + if (!strcmp("momentsOfInertia", name)) return 5; + if (!strcmp("name", name)) return 6; return -1; } -static Bool Text_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SBSegment_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 3: - *AType = 7; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + case 2: + *AType = 1; + *QType = 1; return 1; default: return 0; @@ -11766,74 +27973,143 @@ static Bool Text_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, F -GF_Node *Text_Create() +GF_Node *SBSegment_Create() { - M_Text *p; - GF_SAFEALLOC(p, M_Text); + M_SBSegment *p; + GF_SAFEALLOC(p, M_SBSegment); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Text); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SBSegment); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->maxExtent = FLT2FIX(0.0); + p->centerOfMass.x = FLT2FIX(0); + p->centerOfMass.y = FLT2FIX(0); + p->centerOfMass.z = FLT2FIX(0); + p->mass = FLT2FIX(0); + p->momentsOfInertia.vals = (SFVec3f *)gf_malloc(sizeof(SFVec3f)*3); + p->momentsOfInertia.count = 3; + p->momentsOfInertia.vals[0].x = FLT2FIX(0); + p->momentsOfInertia.vals[0].y = FLT2FIX(0); + p->momentsOfInertia.vals[0].z = FLT2FIX(0); + p->momentsOfInertia.vals[1].x = FLT2FIX(0); + p->momentsOfInertia.vals[1].y = FLT2FIX(0); + p->momentsOfInertia.vals[1].z = FLT2FIX(0); + p->momentsOfInertia.vals[2].x = FLT2FIX(0); + p->momentsOfInertia.vals[2].y = FLT2FIX(0); + p->momentsOfInertia.vals[2].z = FLT2FIX(0); return (GF_Node *)p; } /* - TextureCoordinate Node deletion + SBSite Node deletion */ -static void TextureCoordinate_Del(GF_Node *node) +static void SBSite_Del(GF_Node *node) { - M_TextureCoordinate *p = (M_TextureCoordinate *) node; - gf_sg_mfvec2f_del(p->point); + M_SBSite *p = (M_SBSite *) node; + gf_sg_sfstring_del(p->name); + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 TextureCoordinate_Def2All[] = { 0}; -static const u16 TextureCoordinate_In2All[] = { 0}; -static const u16 TextureCoordinate_Out2All[] = { 0}; -static const u16 TextureCoordinate_Dyn2All[] = { 0}; +static const u16 SBSite_Def2All[] = { 2, 3, 4, 5, 6, 7, 8}; +static const u16 SBSite_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 SBSite_Out2All[] = { 2, 3, 4, 5, 6, 7, 8}; +static const u16 SBSite_Dyn2All[] = { 2, 5, 6, 7, 8}; -static u32 TextureCoordinate_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SBSite_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 1; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_IN: return 9; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 5; default: - return 1; + return 9; } } -static GF_Err TextureCoordinate_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SBSite_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = TextureCoordinate_In2All[inField]; + *allField = SBSite_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = SBSite_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = SBSite_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = SBSite_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err SBSite_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SBSite *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBSite *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SBSite *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBSite *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBSite *) node)->center; + return GF_OK; + case 3: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBSite *)node)->children; return GF_OK; - case GF_SG_FIELD_CODING_DEF: - *allField = TextureCoordinate_Def2All[inField]; + case 4: + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_SBSite *) node)->name; return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = TextureCoordinate_Out2All[inField]; + case 5: + info->name = "rotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_SBSite *) node)->rotation; return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = TextureCoordinate_Dyn2All[inField]; + case 6: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBSite *) node)->scale; return GF_OK; - default: - return GF_BAD_PARAM; - } -} -static GF_Err TextureCoordinate_get_field(GF_Node *node, GF_FieldInfo *info) -{ - switch (info->fieldIndex) { - case 0: - info->name = "point"; + case 7: + info->name = "scaleOrientation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((M_TextureCoordinate *) node)->point; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_SBSite *) node)->scaleOrientation; + return GF_OK; + case 8: + info->name = "translation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBSite *) node)->translation; return GF_OK; default: return GF_BAD_PARAM; @@ -11841,19 +28117,41 @@ static GF_Err TextureCoordinate_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 TextureCoordinate_get_field_index_by_name(char *name) +static s32 SBSite_get_field_index_by_name(char *name) { - if (!strcmp("point", name)) return 0; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("center", name)) return 2; + if (!strcmp("children", name)) return 3; + if (!strcmp("name", name)) return 4; + if (!strcmp("rotation", name)) return 5; + if (!strcmp("scale", name)) return 6; + if (!strcmp("scaleOrientation", name)) return 7; + if (!strcmp("translation", name)) return 8; return -1; } -static Bool TextureCoordinate_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SBSite_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 2; - *QType = 5; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + case 2: + *AType = 1; + *QType = 1; + return 1; + case 5: + *AType = 10; + *QType = 10; + return 1; + case 6: + *AType = 11; + *QType = 7; + return 1; + case 7: + *AType = 10; + *QType = 10; + return 1; + case 8: + *AType = 1; + *QType = 1; return 1; default: return 0; @@ -11862,90 +28160,193 @@ static Bool TextureCoordinate_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *TextureCoordinate_Create() +GF_Node *SBSite_Create() { - M_TextureCoordinate *p; - GF_SAFEALLOC(p, M_TextureCoordinate); + M_SBSite *p; + GF_SAFEALLOC(p, M_SBSite); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_TextureCoordinate); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SBSite); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->rotation.x = FLT2FIX(0); + p->rotation.y = FLT2FIX(0); + p->rotation.z = FLT2FIX(1); + p->rotation.q = FLT2FIX(0); + p->scale.x = FLT2FIX(1); + p->scale.y = FLT2FIX(1); + p->scale.z = FLT2FIX(1); + p->scaleOrientation.x = FLT2FIX(0); + p->scaleOrientation.y = FLT2FIX(0); + p->scaleOrientation.z = FLT2FIX(1); + p->scaleOrientation.q = FLT2FIX(0); + p->translation.x = FLT2FIX(0); + p->translation.y = FLT2FIX(0); + p->translation.z = FLT2FIX(0); return (GF_Node *)p; } /* - TextureTransform Node deletion + SBSkinnedModel Node deletion */ -static void TextureTransform_Del(GF_Node *node) -{ - M_TextureTransform *p = (M_TextureTransform *) node; +static void SBSkinnedModel_Del(GF_Node *node) +{ + M_SBSkinnedModel *p = (M_SBSkinnedModel *) node; + gf_node_unregister_children((GF_Node *) p, p->bones); + gf_node_unregister_children((GF_Node *) p, p->muscles); + gf_sg_sfstring_del(p->name); + gf_node_unregister_children((GF_Node *) p, p->segments); + gf_node_unregister_children((GF_Node *) p, p->sites); + gf_node_unregister_children((GF_Node *) p, p->skeleton); + gf_node_unregister_children((GF_Node *) p, p->skin); + gf_node_unregister((GF_Node *) p->skinCoord, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->skinNormal, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->weighsComputationSkinCoord, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 TextureTransform_Def2All[] = { 0, 1, 2, 3}; -static const u16 TextureTransform_In2All[] = { 0, 1, 2, 3}; -static const u16 TextureTransform_Out2All[] = { 0, 1, 2, 3}; -static const u16 TextureTransform_Dyn2All[] = { 0, 1, 2, 3}; +static const u16 SBSkinnedModel_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; +static const u16 SBSkinnedModel_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; +static const u16 SBSkinnedModel_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; +static const u16 SBSkinnedModel_Dyn2All[] = { 1, 4, 6, 7, 13}; -static u32 TextureTransform_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SBSkinnedModel_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 4; - case GF_SG_FIELD_CODING_OUT: return 4; - case GF_SG_FIELD_CODING_DYN: return 4; + case GF_SG_FIELD_CODING_IN: return 15; + case GF_SG_FIELD_CODING_DEF: return 15; + case GF_SG_FIELD_CODING_OUT: return 15; + case GF_SG_FIELD_CODING_DYN: return 5; default: - return 4; + return 15; } } -static GF_Err TextureTransform_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SBSkinnedModel_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = TextureTransform_In2All[inField]; + *allField = SBSkinnedModel_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = TextureTransform_Def2All[inField]; + *allField = SBSkinnedModel_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = TextureTransform_Out2All[inField]; + *allField = SBSkinnedModel_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = TextureTransform_Dyn2All[inField]; + *allField = SBSkinnedModel_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err TextureTransform_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SBSkinnedModel_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "center"; + info->name = "bones"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_TextureTransform *) node)->center; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFSBBoneNode; + info->far_ptr = & ((M_SBSkinnedModel *)node)->bones; return GF_OK; case 1: - info->name = "rotation"; + info->name = "center"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_TextureTransform *) node)->rotation; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBSkinnedModel *) node)->center; return GF_OK; case 2: - info->name = "scale"; + info->name = "muscles"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_TextureTransform *) node)->scale; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFSBMuscleNode; + info->far_ptr = & ((M_SBSkinnedModel *)node)->muscles; return GF_OK; case 3: + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_SBSkinnedModel *) node)->name; + return GF_OK; + case 4: + info->name = "rotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_SBSkinnedModel *) node)->rotation; + return GF_OK; + case 5: + info->name = "segments"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFSBSegmentNode; + info->far_ptr = & ((M_SBSkinnedModel *)node)->segments; + return GF_OK; + case 6: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBSkinnedModel *) node)->scale; + return GF_OK; + case 7: + info->name = "scaleOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_SBSkinnedModel *) node)->scaleOrientation; + return GF_OK; + case 8: + info->name = "sites"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFSBSiteNode; + info->far_ptr = & ((M_SBSkinnedModel *)node)->sites; + return GF_OK; + case 9: + info->name = "skeleton"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBSkinnedModel *)node)->skeleton; + return GF_OK; + case 10: + info->name = "skin"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBSkinnedModel *)node)->skin; + return GF_OK; + case 11: + info->name = "skinCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((M_SBSkinnedModel *)node)->skinCoord; + return GF_OK; + case 12: + info->name = "skinNormal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((M_SBSkinnedModel *)node)->skinNormal; + return GF_OK; + case 13: info->name = "translation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_TextureTransform *) node)->translation; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SBSkinnedModel *) node)->translation; + return GF_OK; + case 14: + info->name = "weighsComputationSkinCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBSkinnedModel *)node)->weighsComputationSkinCoord; return GF_OK; default: return GF_BAD_PARAM; @@ -11953,40 +28354,47 @@ static GF_Err TextureTransform_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 TextureTransform_get_field_index_by_name(char *name) +static s32 SBSkinnedModel_get_field_index_by_name(char *name) { - if (!strcmp("center", name)) return 0; - if (!strcmp("rotation", name)) return 1; - if (!strcmp("scale", name)) return 2; - if (!strcmp("translation", name)) return 3; + if (!strcmp("bones", name)) return 0; + if (!strcmp("center", name)) return 1; + if (!strcmp("muscles", name)) return 2; + if (!strcmp("name", name)) return 3; + if (!strcmp("rotation", name)) return 4; + if (!strcmp("segments", name)) return 5; + if (!strcmp("scale", name)) return 6; + if (!strcmp("scaleOrientation", name)) return 7; + if (!strcmp("sites", name)) return 8; + if (!strcmp("skeleton", name)) return 9; + if (!strcmp("skin", name)) return 10; + if (!strcmp("skinCoord", name)) return 11; + if (!strcmp("skinNormal", name)) return 12; + if (!strcmp("translation", name)) return 13; + if (!strcmp("weighsComputationSkinCoord", name)) return 14; return -1; } -static Bool TextureTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SBSkinnedModel_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 2; - *QType = 2; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; case 1: - *AType = 6; - *QType = 6; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(6.2831853); + *AType = 1; + *QType = 1; return 1; - case 2: - *AType = 12; + case 4: + *AType = 10; + *QType = 10; + return 1; + case 6: + *AType = 11; *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; return 1; - case 3: - *AType = 2; - *QType = 2; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + case 7: + *AType = 10; + *QType = 10; + return 1; + case 13: + *AType = 1; + *QType = 1; return 1; default: return 0; @@ -11995,123 +28403,94 @@ static Bool TextureTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *TextureTransform_Create() +GF_Node *SBSkinnedModel_Create() { - M_TextureTransform *p; - GF_SAFEALLOC(p, M_TextureTransform); + M_SBSkinnedModel *p; + GF_SAFEALLOC(p, M_SBSkinnedModel); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_TextureTransform); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SBSkinnedModel); /*default field values*/ p->center.x = FLT2FIX(0); p->center.y = FLT2FIX(0); - p->rotation = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->rotation.x = FLT2FIX(0); + p->rotation.y = FLT2FIX(0); + p->rotation.z = FLT2FIX(1); + p->rotation.q = FLT2FIX(0); p->scale.x = FLT2FIX(1); p->scale.y = FLT2FIX(1); + p->scale.z = FLT2FIX(1); + p->scaleOrientation.x = FLT2FIX(0); + p->scaleOrientation.y = FLT2FIX(0); + p->scaleOrientation.z = FLT2FIX(1); + p->scaleOrientation.q = FLT2FIX(0); p->translation.x = FLT2FIX(0); p->translation.y = FLT2FIX(0); + p->translation.z = FLT2FIX(0); return (GF_Node *)p; } /* - TimeSensor Node deletion + SBVCAnimation Node deletion */ -static void TimeSensor_Del(GF_Node *node) +static void SBVCAnimation_Del(GF_Node *node) { - M_TimeSensor *p = (M_TimeSensor *) node; + M_SBVCAnimation *p = (M_SBVCAnimation *) node; + gf_sg_mfurl_del(p->url); + gf_node_unregister_children((GF_Node *) p, p->virtualCharacters); gf_node_free((GF_Node *) p); } -static const u16 TimeSensor_Def2All[] = { 0, 1, 2, 3, 4}; -static const u16 TimeSensor_In2All[] = { 0, 1, 2, 3, 4}; -static const u16 TimeSensor_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 SBVCAnimation_Def2All[] = { 0, 1}; +static const u16 SBVCAnimation_In2All[] = { 0, 1}; +static const u16 SBVCAnimation_Out2All[] = { 0, 1}; -static u32 TimeSensor_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SBVCAnimation_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 5; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 9; + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 9; + return 2; } } -static GF_Err TimeSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SBVCAnimation_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = TimeSensor_In2All[inField]; + *allField = SBVCAnimation_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = TimeSensor_Def2All[inField]; + *allField = SBVCAnimation_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = TimeSensor_Out2All[inField]; + *allField = SBVCAnimation_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err TimeSensor_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SBVCAnimation_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "cycleInterval"; + info->name = "url"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TimeSensor *) node)->cycleInterval; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_SBVCAnimation *) node)->url; return GF_OK; case 1: - info->name = "enabled"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TimeSensor *) node)->enabled; - return GF_OK; - case 2: - info->name = "loop"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TimeSensor *) node)->loop; - return GF_OK; - case 3: - info->name = "startTime"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TimeSensor *) node)->startTime; - return GF_OK; - case 4: - info->name = "stopTime"; + info->name = "virtualCharacters"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TimeSensor *) node)->stopTime; - return GF_OK; - case 5: - info->name = "cycleTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TimeSensor *) node)->cycleTime; - return GF_OK; - case 6: - info->name = "fraction_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_TimeSensor *) node)->fraction_changed; - return GF_OK; - case 7: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TimeSensor *) node)->isActive; - return GF_OK; - case 8: - info->name = "time"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TimeSensor *) node)->time; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBVCAnimation *)node)->virtualCharacters; return GF_OK; default: return GF_BAD_PARAM; @@ -12119,20 +28498,13 @@ static GF_Err TimeSensor_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 TimeSensor_get_field_index_by_name(char *name) +static s32 SBVCAnimation_get_field_index_by_name(char *name) { - if (!strcmp("cycleInterval", name)) return 0; - if (!strcmp("enabled", name)) return 1; - if (!strcmp("loop", name)) return 2; - if (!strcmp("startTime", name)) return 3; - if (!strcmp("stopTime", name)) return 4; - if (!strcmp("cycleTime", name)) return 5; - if (!strcmp("fraction_changed", name)) return 6; - if (!strcmp("isActive", name)) return 7; - if (!strcmp("time", name)) return 8; + if (!strcmp("url", name)) return 0; + if (!strcmp("virtualCharacters", name)) return 1; return -1; } -static Bool TimeSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SBVCAnimation_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { default: @@ -12142,108 +28514,133 @@ static Bool TimeSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AT -GF_Node *TimeSensor_Create() +GF_Node *SBVCAnimation_Create() { - M_TimeSensor *p; - GF_SAFEALLOC(p, M_TimeSensor); + M_SBVCAnimation *p; + GF_SAFEALLOC(p, M_SBVCAnimation); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_TimeSensor); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SBVCAnimation); /*default field values*/ - p->cycleInterval = 1; - p->enabled = 1; - p->startTime = 0; - p->stopTime = 0; return (GF_Node *)p; } /* - TouchSensor Node deletion + ScalarAnimator Node deletion */ -static void TouchSensor_Del(GF_Node *node) +static void ScalarAnimator_Del(GF_Node *node) { - M_TouchSensor *p = (M_TouchSensor *) node; + M_ScalarAnimator *p = (M_ScalarAnimator *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfvec2f_del(p->keySpline); + gf_sg_mffloat_del(p->keyValue); + gf_sg_mffloat_del(p->weight); gf_node_free((GF_Node *) p); } -static const u16 TouchSensor_Def2All[] = { 0}; -static const u16 TouchSensor_In2All[] = { 0}; -static const u16 TouchSensor_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 ScalarAnimator_Def2All[] = { 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 ScalarAnimator_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 ScalarAnimator_Out2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; -static u32 TouchSensor_get_field_count(GF_Node *node, u8 IndexMode) +static u32 ScalarAnimator_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_IN: return 9; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 10; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 7; + return 11; } } -static GF_Err TouchSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err ScalarAnimator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = TouchSensor_In2All[inField]; + *allField = ScalarAnimator_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = TouchSensor_Def2All[inField]; + *allField = ScalarAnimator_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = TouchSensor_Out2All[inField]; + *allField = ScalarAnimator_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err TouchSensor_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err ScalarAnimator_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "enabled"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TouchSensor *) node)->enabled; + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_ScalarAnimator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ScalarAnimator *) node)->set_fraction; return GF_OK; case 1: - info->name = "hitNormal_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_TouchSensor *) node)->hitNormal_changed; + info->name = "fromTo"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_ScalarAnimator *) node)->fromTo; return GF_OK; case 2: - info->name = "hitPoint_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_TouchSensor *) node)->hitPoint_changed; + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_ScalarAnimator *) node)->key; return GF_OK; case 3: - info->name = "hitTexCoord_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_TouchSensor *) node)->hitTexCoord_changed; + info->name = "keyType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_ScalarAnimator *) node)->keyType; return GF_OK; case 4: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TouchSensor *) node)->isActive; + info->name = "keySpline"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((M_ScalarAnimator *) node)->keySpline; return GF_OK; case 5: - info->name = "isOver"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TouchSensor *) node)->isOver; + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_ScalarAnimator *) node)->keyValue; return GF_OK; case 6: - info->name = "touchTime"; + info->name = "keyValueType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_ScalarAnimator *) node)->keyValueType; + return GF_OK; + case 7: + info->name = "offset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ScalarAnimator *) node)->offset; + return GF_OK; + case 8: + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_ScalarAnimator *) node)->weight; + return GF_OK; + case 9: + info->name = "endValue"; info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TouchSensor *) node)->touchTime; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ScalarAnimator *) node)->endValue; + return GF_OK; + case 10: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ScalarAnimator *) node)->value_changed; return GF_OK; default: return GF_BAD_PARAM; @@ -12251,20 +28648,40 @@ static GF_Err TouchSensor_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 TouchSensor_get_field_index_by_name(char *name) +static s32 ScalarAnimator_get_field_index_by_name(char *name) { - if (!strcmp("enabled", name)) return 0; - if (!strcmp("hitNormal_changed", name)) return 1; - if (!strcmp("hitPoint_changed", name)) return 2; - if (!strcmp("hitTexCoord_changed", name)) return 3; - if (!strcmp("isActive", name)) return 4; - if (!strcmp("isOver", name)) return 5; - if (!strcmp("touchTime", name)) return 6; + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("fromTo", name)) return 1; + if (!strcmp("key", name)) return 2; + if (!strcmp("keyType", name)) return 3; + if (!strcmp("keySpline", name)) return 4; + if (!strcmp("keyValue", name)) return 5; + if (!strcmp("keyValueType", name)) return 6; + if (!strcmp("offset", name)) return 7; + if (!strcmp("weight", name)) return 8; + if (!strcmp("endValue", name)) return 9; + if (!strcmp("value_changed", name)) return 10; return -1; } -static Bool TouchSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool ScalarAnimator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 8; + return 1; + case 2: + *AType = 0; + *QType = 8; + return 1; + case 4: + *AType = 0; + *QType = 8; + return 1; + case 5: + *AType = 0; + *QType = 0; + return 1; default: return 0; } @@ -12272,121 +28689,81 @@ static Bool TouchSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *A -GF_Node *TouchSensor_Create() +GF_Node *ScalarAnimator_Create() { - M_TouchSensor *p; - GF_SAFEALLOC(p, M_TouchSensor); + M_ScalarAnimator *p; + GF_SAFEALLOC(p, M_ScalarAnimator); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_TouchSensor); + gf_node_setup((GF_Node *)p, TAG_MPEG4_ScalarAnimator); /*default field values*/ - p->enabled = 1; + p->fromTo.x = FLT2FIX(0); + p->fromTo.y = FLT2FIX(1); + p->keyType = 0; + p->keySpline.vals = (SFVec2f*)gf_malloc(sizeof(SFVec2f)*2); + p->keySpline.count = 2; + p->keySpline.vals[0].x = FLT2FIX(0); + p->keySpline.vals[0].y = FLT2FIX(0); + p->keySpline.vals[1].x = FLT2FIX(1); + p->keySpline.vals[1].y = FLT2FIX(1); + p->keyValueType = 0; + p->offset = FLT2FIX(0); return (GF_Node *)p; } /* - Transform Node deletion + SimpleTexture Node deletion */ -static void Transform_Del(GF_Node *node) +static void SimpleTexture_Del(GF_Node *node) { - M_Transform *p = (M_Transform *) node; - gf_sg_vrml_parent_destroy((GF_Node *) p); + M_SimpleTexture *p = (M_SimpleTexture *) node; + gf_node_unregister((GF_Node *) p->depth, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->texture, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Transform_Def2All[] = { 2, 3, 4, 5, 6, 7}; -static const u16 Transform_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static const u16 Transform_Out2All[] = { 2, 3, 4, 5, 6, 7}; -static const u16 Transform_Dyn2All[] = { 2, 4, 5, 6, 7}; +static const u16 SimpleTexture_Def2All[] = { 0, 1}; -static u32 Transform_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SimpleTexture_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 8; - case GF_SG_FIELD_CODING_DEF: return 6; - case GF_SG_FIELD_CODING_OUT: return 6; - case GF_SG_FIELD_CODING_DYN: return 5; + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 8; + return 2; } } -static GF_Err Transform_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SimpleTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = Transform_In2All[inField]; - return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Transform_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = Transform_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Transform_Dyn2All[inField]; + *allField = SimpleTexture_Def2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Transform_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SimpleTexture_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Transform *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Transform *)node)->addChildren; + info->name = "depth"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_SimpleTexture *)node)->depth; return GF_OK; case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Transform *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Transform *)node)->removeChildren; - return GF_OK; - case 2: - info->name = "center"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_Transform *) node)->center; - return GF_OK; - case 3: - info->name = "children"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_Transform *)node)->children; - return GF_OK; - case 4: - info->name = "rotation"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_Transform *) node)->rotation; - return GF_OK; - case 5: - info->name = "scale"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_Transform *) node)->scale; - return GF_OK; - case 6: - info->name = "scaleOrientation"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_Transform *) node)->scaleOrientation; - return GF_OK; - case 7: - info->name = "translation"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_Transform *) node)->translation; + info->name = "texture"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_SimpleTexture *)node)->texture; return GF_OK; default: return GF_BAD_PARAM; @@ -12394,47 +28771,15 @@ static GF_Err Transform_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Transform_get_field_index_by_name(char *name) +static s32 SimpleTexture_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("center", name)) return 2; - if (!strcmp("children", name)) return 3; - if (!strcmp("rotation", name)) return 4; - if (!strcmp("scale", name)) return 5; - if (!strcmp("scaleOrientation", name)) return 6; - if (!strcmp("translation", name)) return 7; + if (!strcmp("depth", name)) return 0; + if (!strcmp("texture", name)) return 1; return -1; } -static Bool Transform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SimpleTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 2: - *AType = 1; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 4: - *AType = 10; - *QType = 10; - return 1; - case 5: - *AType = 11; - *QType = 7; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 6: - *AType = 10; - *QType = 10; - return 1; - case 7: - *AType = 1; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -12442,188 +28787,108 @@ static Bool Transform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATy -GF_Node *Transform_Create() +GF_Node *SimpleTexture_Create() { - M_Transform *p; - GF_SAFEALLOC(p, M_Transform); + M_SimpleTexture *p; + GF_SAFEALLOC(p, M_SimpleTexture); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Transform); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SimpleTexture); /*default field values*/ - p->center.x = FLT2FIX(0); - p->center.y = FLT2FIX(0); - p->center.z = FLT2FIX(0); - p->rotation.x = FLT2FIX(0); - p->rotation.y = FLT2FIX(0); - p->rotation.z = FLT2FIX(1); - p->rotation.q = FLT2FIX(0); - p->scale.x = FLT2FIX(1); - p->scale.y = FLT2FIX(1); - p->scale.z = FLT2FIX(1); - p->scaleOrientation.x = FLT2FIX(0); - p->scaleOrientation.y = FLT2FIX(0); - p->scaleOrientation.z = FLT2FIX(1); - p->scaleOrientation.q = FLT2FIX(0); - p->translation.x = FLT2FIX(0); - p->translation.y = FLT2FIX(0); - p->translation.z = FLT2FIX(0); return (GF_Node *)p; } /* - Transform2D Node deletion + SolidRep Node deletion */ -static void Transform2D_Del(GF_Node *node) +static void SolidRep_Del(GF_Node *node) { - M_Transform2D *p = (M_Transform2D *) node; - gf_sg_vrml_parent_destroy((GF_Node *) p); + M_SolidRep *p = (M_SolidRep *) node; + gf_sg_mfint32_del(p->densityList); + gf_node_unregister((GF_Node *) p->solidTree, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Transform2D_Def2All[] = { 2, 3, 4, 5, 6, 7}; -static const u16 Transform2D_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static const u16 Transform2D_Out2All[] = { 2, 3, 4, 5, 6, 7}; -static const u16 Transform2D_Dyn2All[] = { 3, 4, 5, 6, 7}; +static const u16 SolidRep_Def2All[] = { 0, 1, 2}; +static const u16 SolidRep_In2All[] = { 0, 1, 2}; +static const u16 SolidRep_Out2All[] = { 0, 1, 2}; +static const u16 SolidRep_Dyn2All[] = { 0}; -static u32 Transform2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SolidRep_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 8; - case GF_SG_FIELD_CODING_DEF: return 6; - case GF_SG_FIELD_CODING_OUT: return 6; - case GF_SG_FIELD_CODING_DYN: return 5; + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 1; default: - return 8; + return 3; } } -static GF_Err Transform2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SolidRep_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Transform2D_In2All[inField]; + *allField = SolidRep_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Transform2D_Def2All[inField]; + *allField = SolidRep_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Transform2D_Out2All[inField]; + *allField = SolidRep_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = Transform2D_Dyn2All[inField]; + *allField = SolidRep_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Transform2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SolidRep_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Transform2D *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Transform2D *)node)->addChildren; - return GF_OK; - case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Transform2D *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Transform2D *)node)->removeChildren; - return GF_OK; - case 2: - info->name = "children"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Transform2D *)node)->children; - return GF_OK; - case 3: - info->name = "center"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Transform2D *) node)->center; - return GF_OK; - case 4: - info->name = "rotationAngle"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Transform2D *) node)->rotationAngle; - return GF_OK; - case 5: - info->name = "scale"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Transform2D *) node)->scale; - return GF_OK; - case 6: - info->name = "scaleOrientation"; + info->name = "bboxSize"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Transform2D *) node)->scaleOrientation; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SolidRep *) node)->bboxSize; return GF_OK; - case 7: - info->name = "translation"; + case 1: + info->name = "densityList"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Transform2D *) node)->translation; - return GF_OK; - default: - return GF_BAD_PARAM; - } -} - - -static s32 Transform2D_get_field_index_by_name(char *name) -{ - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; - if (!strcmp("center", name)) return 3; - if (!strcmp("rotationAngle", name)) return 4; - if (!strcmp("scale", name)) return 5; - if (!strcmp("scaleOrientation", name)) return 6; - if (!strcmp("translation", name)) return 7; - return -1; - } -static Bool Transform2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) -{ - switch (FieldIndex) { - case 3: - *AType = 2; - *QType = 2; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 4: - *AType = 6; - *QType = 6; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(6.2831853); - return 1; - case 5: - *AType = 12; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 6: - *AType = 6; - *QType = 6; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SolidRep *) node)->densityList; + return GF_OK; + case 2: + info->name = "solidTree"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SolidRep *)node)->solidTree; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 SolidRep_get_field_index_by_name(char *name) +{ + if (!strcmp("bboxSize", name)) return 0; + if (!strcmp("densityList", name)) return 1; + if (!strcmp("solidTree", name)) return 2; + return -1; + } +static Bool SolidRep_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 0: + *AType = 11; + *QType = 11; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(6.2831853); - return 1; - case 7: - *AType = 2; - *QType = 2; - *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; default: @@ -12633,451 +28898,304 @@ static Bool Transform2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *A -GF_Node *Transform2D_Create() +GF_Node *SolidRep_Create() { - M_Transform2D *p; - GF_SAFEALLOC(p, M_Transform2D); + M_SolidRep *p; + GF_SAFEALLOC(p, M_SolidRep); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Transform2D); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SolidRep); /*default field values*/ - p->center.x = FLT2FIX(0); - p->center.y = FLT2FIX(0); - p->rotationAngle = FLT2FIX(0); - p->scale.x = FLT2FIX(1); - p->scale.y = FLT2FIX(1); - p->scaleOrientation = FLT2FIX(0); - p->translation.x = FLT2FIX(0); - p->translation.y = FLT2FIX(0); + p->bboxSize.x = FLT2FIX(2); + p->bboxSize.y = FLT2FIX(2); + p->bboxSize.z = FLT2FIX(2); return (GF_Node *)p; } /* - Valuator Node deletion + SubdivisionSurface Node deletion */ -static void Valuator_Del(GF_Node *node) +static void SubdivisionSurface_Del(GF_Node *node) { - M_Valuator *p = (M_Valuator *) node; - gf_sg_mfcolor_del(p->inMFColor); - gf_sg_mffloat_del(p->inMFFloat); - gf_sg_mfint32_del(p->inMFInt32); - gf_sg_mfrotation_del(p->inMFRotation); - gf_sg_sfstring_del(p->inSFString); - gf_sg_mfstring_del(p->inMFString); - gf_sg_mfvec2f_del(p->inMFVec2f); - gf_sg_mfvec3f_del(p->inMFVec3f); - gf_sg_mfcolor_del(p->outMFColor); - gf_sg_mffloat_del(p->outMFFloat); - gf_sg_mfint32_del(p->outMFInt32); - gf_sg_mfrotation_del(p->outMFRotation); - gf_sg_sfstring_del(p->outSFString); - gf_sg_mfstring_del(p->outMFString); - gf_sg_mfvec2f_del(p->outMFVec2f); - gf_sg_mfvec3f_del(p->outMFVec3f); + M_SubdivisionSurface *p = (M_SubdivisionSurface *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_sg_mfint32_del(p->set_coordIndex); + gf_sg_mfint32_del(p->set_cornerVertexIndex); + gf_sg_mfint32_del(p->set_creaseEdgeIndex); + gf_sg_mfint32_del(p->set_creaseVertexIndex); + gf_sg_mfint32_del(p->set_dartVertexIndex); + gf_sg_mfint32_del(p->set_texCoordIndex); + gf_node_unregister((GF_Node *) p->color, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->coord, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->texCoord, (GF_Node *) p); + gf_node_unregister_children((GF_Node *) p, p->sectors); + gf_sg_mfint32_del(p->invisibleEdgeIndex); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mfint32_del(p->coordIndex); + gf_sg_mfint32_del(p->cornerVertexIndex); + gf_sg_mfint32_del(p->creaseEdgeIndex); + gf_sg_mfint32_del(p->creaseVertexIndex); + gf_sg_mfint32_del(p->dartVertexIndex); + gf_sg_mfint32_del(p->texCoordIndex); gf_node_free((GF_Node *) p); } -static const u16 Valuator_Def2All[] = { 32, 33, 34, 35, 36, 37, 38, 39, 40}; -static const u16 Valuator_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 32, 33, 34, 35, 36, 37, 38, 39, 40}; -static const u16 Valuator_Out2All[] = { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}; +static const u16 SubdivisionSurface_Def2All[] = { 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25}; +static const u16 SubdivisionSurface_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; +static const u16 SubdivisionSurface_Out2All[] = { 7, 8, 9, 10, 11, 12, 13}; -static u32 Valuator_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SubdivisionSurface_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 25; - case GF_SG_FIELD_CODING_DEF: return 9; - case GF_SG_FIELD_CODING_OUT: return 25; + case GF_SG_FIELD_CODING_IN: return 14; + case GF_SG_FIELD_CODING_DEF: return 19; + case GF_SG_FIELD_CODING_OUT: return 7; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 41; + return 26; } } -static GF_Err Valuator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SubdivisionSurface_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Valuator_In2All[inField]; + *allField = SubdivisionSurface_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Valuator_Def2All[inField]; + *allField = SubdivisionSurface_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Valuator_Out2All[inField]; + *allField = SubdivisionSurface_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Valuator_get_field(GF_Node *node, GF_FieldInfo *info) -{ - switch (info->fieldIndex) { - case 0: - info->name = "inSFBool"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inSFBool; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Valuator *) node)->inSFBool; - return GF_OK; - case 1: - info->name = "inSFColor"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inSFColor; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_Valuator *) node)->inSFColor; - return GF_OK; - case 2: - info->name = "inMFColor"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inMFColor; - info->fieldType = GF_SG_VRML_MFCOLOR; - info->far_ptr = & ((M_Valuator *) node)->inMFColor; - return GF_OK; - case 3: - info->name = "inSFFloat"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inSFFloat; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->inSFFloat; - return GF_OK; - case 4: - info->name = "inMFFloat"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inMFFloat; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->inMFFloat; - return GF_OK; - case 5: - info->name = "inSFInt32"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inSFInt32; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_Valuator *) node)->inSFInt32; - return GF_OK; - case 6: - info->name = "inMFInt32"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inMFInt32; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_Valuator *) node)->inMFInt32; - return GF_OK; - case 7: - info->name = "inSFRotation"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inSFRotation; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_Valuator *) node)->inSFRotation; - return GF_OK; - case 8: - info->name = "inMFRotation"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inMFRotation; - info->fieldType = GF_SG_VRML_MFROTATION; - info->far_ptr = & ((M_Valuator *) node)->inMFRotation; - return GF_OK; - case 9: - info->name = "inSFString"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inSFString; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_Valuator *) node)->inSFString; - return GF_OK; - case 10: - info->name = "inMFString"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inMFString; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_Valuator *) node)->inMFString; - return GF_OK; - case 11: - info->name = "inSFTime"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inSFTime; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_Valuator *) node)->inSFTime; - return GF_OK; - case 12: - info->name = "inSFVec2f"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inSFVec2f; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Valuator *) node)->inSFVec2f; - return GF_OK; - case 13: - info->name = "inMFVec2f"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inMFVec2f; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((M_Valuator *) node)->inMFVec2f; - return GF_OK; - case 14: - info->name = "inSFVec3f"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inSFVec3f; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_Valuator *) node)->inSFVec3f; - return GF_OK; - case 15: - info->name = "inMFVec3f"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Valuator *)node)->on_inMFVec3f; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((M_Valuator *) node)->inMFVec3f; - return GF_OK; - case 16: - info->name = "outSFBool"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Valuator *) node)->outSFBool; - return GF_OK; - case 17: - info->name = "outSFColor"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_Valuator *) node)->outSFColor; - return GF_OK; - case 18: - info->name = "outMFColor"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFCOLOR; - info->far_ptr = & ((M_Valuator *) node)->outMFColor; - return GF_OK; - case 19: - info->name = "outSFFloat"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->outSFFloat; - return GF_OK; - case 20: - info->name = "outMFFloat"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->outMFFloat; - return GF_OK; - case 21: - info->name = "outSFInt32"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_Valuator *) node)->outSFInt32; - return GF_OK; - case 22: - info->name = "outMFInt32"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_Valuator *) node)->outMFInt32; - return GF_OK; - case 23: - info->name = "outSFRotation"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_Valuator *) node)->outSFRotation; - return GF_OK; - case 24: - info->name = "outMFRotation"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFROTATION; - info->far_ptr = & ((M_Valuator *) node)->outMFRotation; - return GF_OK; - case 25: - info->name = "outSFString"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_Valuator *) node)->outSFString; +static GF_Err SubdivisionSurface_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SubdivisionSurface *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->set_colorIndex; return GF_OK; - case 26: - info->name = "outMFString"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_Valuator *) node)->outMFString; + case 1: + info->name = "set_coordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SubdivisionSurface *)node)->on_set_coordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->set_coordIndex; return GF_OK; - case 27: - info->name = "outSFTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_Valuator *) node)->outSFTime; + case 2: + info->name = "set_cornerVertexIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SubdivisionSurface *)node)->on_set_cornerVertexIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->set_cornerVertexIndex; return GF_OK; - case 28: - info->name = "outSFVec2f"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Valuator *) node)->outSFVec2f; + case 3: + info->name = "set_creaseEdgeIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SubdivisionSurface *)node)->on_set_creaseEdgeIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->set_creaseEdgeIndex; return GF_OK; - case 29: - info->name = "outMFVec2f"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((M_Valuator *) node)->outMFVec2f; + case 4: + info->name = "set_creaseVertexIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SubdivisionSurface *)node)->on_set_creaseVertexIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->set_creaseVertexIndex; return GF_OK; - case 30: - info->name = "outSFVec3f"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_Valuator *) node)->outSFVec3f; + case 5: + info->name = "set_dartVertexIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SubdivisionSurface *)node)->on_set_dartVertexIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->set_dartVertexIndex; return GF_OK; - case 31: - info->name = "outMFVec3f"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((M_Valuator *) node)->outMFVec3f; + case 6: + info->name = "set_texCoordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SubdivisionSurface *)node)->on_set_texCoordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->set_texCoordIndex; return GF_OK; - case 32: - info->name = "Factor1"; + case 7: + info->name = "color"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->Factor1; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((M_SubdivisionSurface *)node)->color; return GF_OK; - case 33: - info->name = "Factor2"; + case 8: + info->name = "coord"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->Factor2; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((M_SubdivisionSurface *)node)->coord; return GF_OK; - case 34: - info->name = "Factor3"; + case 9: + info->name = "texCoord"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->Factor3; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((M_SubdivisionSurface *)node)->texCoord; return GF_OK; - case 35: - info->name = "Factor4"; + case 10: + info->name = "sectors"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->Factor4; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFSubdivSurfaceSectorNode; + info->far_ptr = & ((M_SubdivisionSurface *)node)->sectors; return GF_OK; - case 36: - info->name = "Offset1"; + case 11: + info->name = "subdivisionLevel"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->Offset1; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->subdivisionLevel; return GF_OK; - case 37: - info->name = "Offset2"; + case 12: + info->name = "subdivisionType"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->Offset2; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->subdivisionType; return GF_OK; - case 38: - info->name = "Offset3"; + case 13: + info->name = "subdivisionSubType"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->Offset3; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->subdivisionSubType; return GF_OK; - case 39: - info->name = "Offset4"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Valuator *) node)->Offset4; + case 14: + info->name = "invisibleEdgeIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->invisibleEdgeIndex; return GF_OK; - case 40: - info->name = "Sum"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + case 15: + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Valuator *) node)->Sum; + info->far_ptr = & ((M_SubdivisionSurface *) node)->ccw; return GF_OK; - default: - return GF_BAD_PARAM; - } -} - - -static s32 Valuator_get_field_index_by_name(char *name) -{ - if (!strcmp("inSFBool", name)) return 0; - if (!strcmp("inSFColor", name)) return 1; - if (!strcmp("inMFColor", name)) return 2; - if (!strcmp("inSFFloat", name)) return 3; - if (!strcmp("inMFFloat", name)) return 4; - if (!strcmp("inSFInt32", name)) return 5; - if (!strcmp("inMFInt32", name)) return 6; - if (!strcmp("inSFRotation", name)) return 7; - if (!strcmp("inMFRotation", name)) return 8; - if (!strcmp("inSFString", name)) return 9; - if (!strcmp("inMFString", name)) return 10; - if (!strcmp("inSFTime", name)) return 11; - if (!strcmp("inSFVec2f", name)) return 12; - if (!strcmp("inMFVec2f", name)) return 13; - if (!strcmp("inSFVec3f", name)) return 14; - if (!strcmp("inMFVec3f", name)) return 15; - if (!strcmp("outSFBool", name)) return 16; - if (!strcmp("outSFColor", name)) return 17; - if (!strcmp("outMFColor", name)) return 18; - if (!strcmp("outSFFloat", name)) return 19; - if (!strcmp("outMFFloat", name)) return 20; - if (!strcmp("outSFInt32", name)) return 21; - if (!strcmp("outMFInt32", name)) return 22; - if (!strcmp("outSFRotation", name)) return 23; - if (!strcmp("outMFRotation", name)) return 24; - if (!strcmp("outSFString", name)) return 25; - if (!strcmp("outMFString", name)) return 26; - if (!strcmp("outSFTime", name)) return 27; - if (!strcmp("outSFVec2f", name)) return 28; - if (!strcmp("outMFVec2f", name)) return 29; - if (!strcmp("outSFVec3f", name)) return 30; - if (!strcmp("outMFVec3f", name)) return 31; - if (!strcmp("Factor1", name)) return 32; - if (!strcmp("Factor2", name)) return 33; - if (!strcmp("Factor3", name)) return 34; - if (!strcmp("Factor4", name)) return 35; - if (!strcmp("Offset1", name)) return 36; - if (!strcmp("Offset2", name)) return 37; - if (!strcmp("Offset3", name)) return 38; - if (!strcmp("Offset4", name)) return 39; - if (!strcmp("Sum", name)) return 40; - return -1; - } -static Bool Valuator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) -{ - switch (FieldIndex) { - case 32: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 33: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 34: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 35: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 36: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 37: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 38: + case 16: + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->colorIndex; + return GF_OK; + case 17: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SubdivisionSurface *) node)->colorPerVertex; + return GF_OK; + case 18: + info->name = "convex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SubdivisionSurface *) node)->convex; + return GF_OK; + case 19: + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->coordIndex; + return GF_OK; + case 20: + info->name = "cornerVertexIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->cornerVertexIndex; + return GF_OK; + case 21: + info->name = "creaseEdgeIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->creaseEdgeIndex; + return GF_OK; + case 22: + info->name = "creaseVertexIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->creaseVertexIndex; + return GF_OK; + case 23: + info->name = "dartVertexIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->dartVertexIndex; + return GF_OK; + case 24: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SubdivisionSurface *) node)->solid; + return GF_OK; + case 25: + info->name = "texCoordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SubdivisionSurface *) node)->texCoordIndex; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 SubdivisionSurface_get_field_index_by_name(char *name) +{ + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("set_coordIndex", name)) return 1; + if (!strcmp("set_cornerVertexIndex", name)) return 2; + if (!strcmp("set_creaseEdgeIndex", name)) return 3; + if (!strcmp("set_creaseVertexIndex", name)) return 4; + if (!strcmp("set_dartVertexIndex", name)) return 5; + if (!strcmp("set_texCoordIndex", name)) return 6; + if (!strcmp("color", name)) return 7; + if (!strcmp("coord", name)) return 8; + if (!strcmp("texCoord", name)) return 9; + if (!strcmp("sectors", name)) return 10; + if (!strcmp("subdivisionLevel", name)) return 11; + if (!strcmp("subdivisionType", name)) return 12; + if (!strcmp("subdivisionSubType", name)) return 13; + if (!strcmp("invisibleEdgeIndex", name)) return 14; + if (!strcmp("ccw", name)) return 15; + if (!strcmp("colorIndex", name)) return 16; + if (!strcmp("colorPerVertex", name)) return 17; + if (!strcmp("convex", name)) return 18; + if (!strcmp("coordIndex", name)) return 19; + if (!strcmp("cornerVertexIndex", name)) return 20; + if (!strcmp("creaseEdgeIndex", name)) return 21; + if (!strcmp("creaseVertexIndex", name)) return 22; + if (!strcmp("dartVertexIndex", name)) return 23; + if (!strcmp("solid", name)) return 24; + if (!strcmp("texCoordIndex", name)) return 25; + return -1; + } +static Bool SubdivisionSurface_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 12: *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(3); return 1; - case 39: + case 13: *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(3); return 1; default: return 0; @@ -13086,124 +29204,111 @@ static Bool Valuator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATyp -GF_Node *Valuator_Create() +GF_Node *SubdivisionSurface_Create() { - M_Valuator *p; - GF_SAFEALLOC(p, M_Valuator); + M_SubdivisionSurface *p; + GF_SAFEALLOC(p, M_SubdivisionSurface); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Valuator); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SubdivisionSurface); /*default field values*/ - p->Factor1 = FLT2FIX(1.0); - p->Factor2 = FLT2FIX(1.0); - p->Factor3 = FLT2FIX(1.0); - p->Factor4 = FLT2FIX(1.0); - p->Offset1 = FLT2FIX(0.0); - p->Offset2 = FLT2FIX(0.0); - p->Offset3 = FLT2FIX(0.0); - p->Offset4 = FLT2FIX(0.0); + p->subdivisionLevel = 0; + p->subdivisionType = 0; + p->subdivisionSubType = 0; + p->ccw = 1; + p->colorPerVertex = 1; + p->convex = 1; + p->solid = 1; return (GF_Node *)p; } /* - Viewpoint Node deletion + SubdivSurfaceSector Node deletion */ -static void Viewpoint_Del(GF_Node *node) +static void SubdivSurfaceSector_Del(GF_Node *node) { - M_Viewpoint *p = (M_Viewpoint *) node; - gf_sg_sfstring_del(p->description); + M_SubdivSurfaceSector *p = (M_SubdivSurfaceSector *) node; gf_node_free((GF_Node *) p); } -static const u16 Viewpoint_Def2All[] = { 1, 2, 3, 4, 5}; -static const u16 Viewpoint_In2All[] = { 0, 1, 2, 3, 4}; -static const u16 Viewpoint_Out2All[] = { 1, 2, 3, 4, 6, 7}; -static const u16 Viewpoint_Dyn2All[] = { 1, 3, 4}; +static const u16 SubdivSurfaceSector_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 SubdivSurfaceSector_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 SubdivSurfaceSector_Out2All[] = { 0, 1, 2, 3, 4}; -static u32 Viewpoint_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SubdivSurfaceSector_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: return 5; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 6; - case GF_SG_FIELD_CODING_DYN: return 3; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 8; + return 7; } } -static GF_Err Viewpoint_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SubdivSurfaceSector_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Viewpoint_In2All[inField]; + *allField = SubdivSurfaceSector_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Viewpoint_Def2All[inField]; + *allField = SubdivSurfaceSector_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Viewpoint_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Viewpoint_Dyn2All[inField]; + *allField = SubdivSurfaceSector_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Viewpoint_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SubdivSurfaceSector_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_bind"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Viewpoint *)node)->on_set_bind; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Viewpoint *) node)->set_bind; + info->name = "flatness"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SubdivSurfaceSector *) node)->flatness; return GF_OK; case 1: - info->name = "fieldOfView"; + info->name = "normal"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Viewpoint *) node)->fieldOfView; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SubdivSurfaceSector *) node)->normal; return GF_OK; case 2: - info->name = "jump"; + info->name = "normalTension"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Viewpoint *) node)->jump; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SubdivSurfaceSector *) node)->normalTension; return GF_OK; case 3: - info->name = "orientation"; + info->name = "tag"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_Viewpoint *) node)->orientation; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SubdivSurfaceSector *) node)->_tag; return GF_OK; case 4: - info->name = "position"; + info->name = "theta"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_Viewpoint *) node)->position; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SubdivSurfaceSector *) node)->theta; return GF_OK; case 5: - info->name = "description"; + info->name = "faceIndex"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_Viewpoint *) node)->description; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SubdivSurfaceSector *) node)->faceIndex; return GF_OK; case 6: - info->name = "bindTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_Viewpoint *) node)->bindTime; - return GF_OK; - case 7: - info->name = "isBound"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Viewpoint *) node)->isBound; + info->name = "vertexIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SubdivSurfaceSector *) node)->vertexIndex; return GF_OK; default: return GF_BAD_PARAM; @@ -13211,36 +29316,56 @@ static GF_Err Viewpoint_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Viewpoint_get_field_index_by_name(char *name) +static s32 SubdivSurfaceSector_get_field_index_by_name(char *name) { - if (!strcmp("set_bind", name)) return 0; - if (!strcmp("fieldOfView", name)) return 1; - if (!strcmp("jump", name)) return 2; - if (!strcmp("orientation", name)) return 3; - if (!strcmp("position", name)) return 4; - if (!strcmp("description", name)) return 5; - if (!strcmp("bindTime", name)) return 6; - if (!strcmp("isBound", name)) return 7; + if (!strcmp("flatness", name)) return 0; + if (!strcmp("normal", name)) return 1; + if (!strcmp("normalTension", name)) return 2; + if (!strcmp("tag", name)) return 3; + if (!strcmp("theta", name)) return 4; + if (!strcmp("faceIndex", name)) return 5; + if (!strcmp("vertexIndex", name)) return 6; return -1; } -static Bool Viewpoint_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SubdivSurfaceSector_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 0: + *AType = 0; + *QType = 7; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; case 1: - *AType = 8; - *QType = 6; + *AType = 0; + *QType = 9; + return 1; + case 2: + *AType = 0; + *QType = 7; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(3.1415927); + *b_max = FLT2FIX(1); return 1; case 3: - *AType = 10; - *QType = 10; + *AType = 0; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(2); return 1; case 4: - *AType = 1; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *AType = 0; + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(6.2831853); + return 1; + case 5: + *AType = 0; + *QType = 14; + return 1; + case 6: + *AType = 0; + *QType = 14; return 1; default: return 0; @@ -13249,111 +29374,97 @@ static Bool Viewpoint_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATy -GF_Node *Viewpoint_Create() +GF_Node *SubdivSurfaceSector_Create() { - M_Viewpoint *p; - GF_SAFEALLOC(p, M_Viewpoint); + M_SubdivSurfaceSector *p; + GF_SAFEALLOC(p, M_SubdivSurfaceSector); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Viewpoint); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SubdivSurfaceSector); /*default field values*/ - p->fieldOfView = FLT2FIX(0.785398); - p->jump = 1; - p->orientation.x = FLT2FIX(0); - p->orientation.y = FLT2FIX(0); - p->orientation.z = FLT2FIX(1); - p->orientation.q = FLT2FIX(0); - p->position.x = FLT2FIX(0); - p->position.y = FLT2FIX(0); - p->position.z = FLT2FIX(10); + p->flatness = FLT2FIX(0); + p->normal.x = FLT2FIX(0); + p->normal.y = FLT2FIX(0); + p->normal.z = FLT2FIX(0); + p->normalTension = FLT2FIX(0); + p->_tag = 0; + p->theta = FLT2FIX(0); + p->faceIndex = 0; + p->vertexIndex = 0; return (GF_Node *)p; } /* - VisibilitySensor Node deletion + WaveletSubdivisionSurface Node deletion */ -static void VisibilitySensor_Del(GF_Node *node) +static void WaveletSubdivisionSurface_Del(GF_Node *node) { - M_VisibilitySensor *p = (M_VisibilitySensor *) node; + M_WaveletSubdivisionSurface *p = (M_WaveletSubdivisionSurface *) node; + gf_node_unregister((GF_Node *) p->baseMesh, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 VisibilitySensor_Def2All[] = { 0, 1, 2}; -static const u16 VisibilitySensor_In2All[] = { 0, 1, 2}; -static const u16 VisibilitySensor_Out2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 VisibilitySensor_Dyn2All[] = { 0, 2}; +static const u16 WaveletSubdivisionSurface_Def2All[] = { 0, 1, 2, 3}; +static const u16 WaveletSubdivisionSurface_In2All[] = { 0, 1, 2, 3}; +static const u16 WaveletSubdivisionSurface_Out2All[] = { 0, 1, 2, 3}; -static u32 VisibilitySensor_get_field_count(GF_Node *node, u8 IndexMode) +static u32 WaveletSubdivisionSurface_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 6; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 6; + return 4; } } -static GF_Err VisibilitySensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err WaveletSubdivisionSurface_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = VisibilitySensor_In2All[inField]; + *allField = WaveletSubdivisionSurface_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = VisibilitySensor_Def2All[inField]; + *allField = WaveletSubdivisionSurface_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = VisibilitySensor_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = VisibilitySensor_Dyn2All[inField]; + *allField = WaveletSubdivisionSurface_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err VisibilitySensor_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err WaveletSubdivisionSurface_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "center"; + info->name = "baseMesh"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_VisibilitySensor *) node)->center; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_WaveletSubdivisionSurface *)node)->baseMesh; return GF_OK; case 1: - info->name = "enabled"; + info->name = "fieldOfView"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_VisibilitySensor *) node)->enabled; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_WaveletSubdivisionSurface *) node)->fieldOfView; return GF_OK; case 2: - info->name = "size"; + info->name = "frequency"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_VisibilitySensor *) node)->size; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_WaveletSubdivisionSurface *) node)->frequency; return GF_OK; case 3: - info->name = "enterTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_VisibilitySensor *) node)->enterTime; - return GF_OK; - case 4: - info->name = "exitTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_VisibilitySensor *) node)->exitTime; - return GF_OK; - case 5: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_VisibilitySensor *) node)->isActive; + info->name = "quality"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_WaveletSubdivisionSurface *) node)->quality; return GF_OK; default: return GF_BAD_PARAM; @@ -13361,31 +29472,17 @@ static GF_Err VisibilitySensor_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 VisibilitySensor_get_field_index_by_name(char *name) +static s32 WaveletSubdivisionSurface_get_field_index_by_name(char *name) { - if (!strcmp("center", name)) return 0; - if (!strcmp("enabled", name)) return 1; - if (!strcmp("size", name)) return 2; - if (!strcmp("enterTime", name)) return 3; - if (!strcmp("exitTime", name)) return 4; - if (!strcmp("isActive", name)) return 5; + if (!strcmp("baseMesh", name)) return 0; + if (!strcmp("fieldOfView", name)) return 1; + if (!strcmp("frequency", name)) return 2; + if (!strcmp("quality", name)) return 3; return -1; } -static Bool VisibilitySensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool WaveletSubdivisionSurface_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 1; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 2: - *AType = 11; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -13393,75 +29490,117 @@ static Bool VisibilitySensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *VisibilitySensor_Create() +GF_Node *WaveletSubdivisionSurface_Create() { - M_VisibilitySensor *p; - GF_SAFEALLOC(p, M_VisibilitySensor); + M_WaveletSubdivisionSurface *p; + GF_SAFEALLOC(p, M_WaveletSubdivisionSurface); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_VisibilitySensor); + gf_node_setup((GF_Node *)p, TAG_MPEG4_WaveletSubdivisionSurface); /*default field values*/ - p->center.x = FLT2FIX(0); - p->center.y = FLT2FIX(0); - p->center.z = FLT2FIX(0); - p->enabled = 1; - p->size.x = FLT2FIX(0); - p->size.y = FLT2FIX(0); - p->size.z = FLT2FIX(0); + p->fieldOfView = FLT2FIX(0.785398); + p->frequency = FLT2FIX(1.0); + p->quality = 1; return (GF_Node *)p; } /* - WorldInfo Node deletion + Clipper2D Node deletion */ -static void WorldInfo_Del(GF_Node *node) +static void Clipper2D_Del(GF_Node *node) { - M_WorldInfo *p = (M_WorldInfo *) node; - gf_sg_mfstring_del(p->info); - gf_sg_sfstring_del(p->title); + M_Clipper2D *p = (M_Clipper2D *) node; + gf_node_unregister((GF_Node *) p->geometry, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->transform, (GF_Node *) p); + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 WorldInfo_Def2All[] = { 0, 1}; +static const u16 Clipper2D_Def2All[] = { 2, 3, 4, 5, 6}; +static const u16 Clipper2D_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 Clipper2D_Out2All[] = { 2, 3, 4, 5, 6}; -static u32 WorldInfo_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Clipper2D_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 0; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_IN: return 7; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 5; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 2; + return 7; } } -static GF_Err WorldInfo_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Clipper2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Clipper2D_In2All[inField]; + return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = WorldInfo_Def2All[inField]; + *allField = Clipper2D_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Clipper2D_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err WorldInfo_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Clipper2D_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "info"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_WorldInfo *) node)->info; + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Clipper2D *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Clipper2D *)node)->addChildren; return GF_OK; case 1: - info->name = "title"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_WorldInfo *) node)->title; + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Clipper2D *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Clipper2D *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Clipper2D *)node)->children; + return GF_OK; + case 3: + info->name = "geometry"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_Clipper2D *)node)->geometry; + return GF_OK; + case 4: + info->name = "inside"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Clipper2D *) node)->inside; + return GF_OK; + case 5: + info->name = "transform"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_Clipper2D *)node)->transform; + return GF_OK; + case 6: + info->name = "XOR"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Clipper2D *) node)->XOR; return GF_OK; default: return GF_BAD_PARAM; @@ -13469,13 +29608,18 @@ static GF_Err WorldInfo_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 WorldInfo_get_field_index_by_name(char *name) +static s32 Clipper2D_get_field_index_by_name(char *name) { - if (!strcmp("info", name)) return 0; - if (!strcmp("title", name)) return 1; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("geometry", name)) return 3; + if (!strcmp("inside", name)) return 4; + if (!strcmp("transform", name)) return 5; + if (!strcmp("XOR", name)) return 6; return -1; } -static Bool WorldInfo_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool Clipper2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { default: @@ -13485,130 +29629,212 @@ static Bool WorldInfo_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATy -GF_Node *WorldInfo_Create() +GF_Node *Clipper2D_Create() { - M_WorldInfo *p; - GF_SAFEALLOC(p, M_WorldInfo); + M_Clipper2D *p; + GF_SAFEALLOC(p, M_Clipper2D); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_WorldInfo); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Clipper2D); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ + p->inside = 1; return (GF_Node *)p; } /* - AcousticMaterial Node deletion + ColorTransform Node deletion */ -static void AcousticMaterial_Del(GF_Node *node) +static void ColorTransform_Del(GF_Node *node) { - M_AcousticMaterial *p = (M_AcousticMaterial *) node; - gf_sg_mffloat_del(p->reffunc); - gf_sg_mffloat_del(p->transfunc); - gf_sg_mffloat_del(p->refFrequency); - gf_sg_mffloat_del(p->transFrequency); + M_ColorTransform *p = (M_ColorTransform *) node; + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 AcousticMaterial_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 AcousticMaterial_In2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 AcousticMaterial_Out2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 AcousticMaterial_Dyn2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 ColorTransform_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}; +static const u16 ColorTransform_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}; +static const u16 ColorTransform_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}; +static const u16 ColorTransform_Dyn2All[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}; -static u32 AcousticMaterial_get_field_count(GF_Node *node, u8 IndexMode) +static u32 ColorTransform_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 6; - case GF_SG_FIELD_CODING_DEF: return 10; - case GF_SG_FIELD_CODING_OUT: return 6; - case GF_SG_FIELD_CODING_DYN: return 6; + case GF_SG_FIELD_CODING_IN: return 23; + case GF_SG_FIELD_CODING_DEF: return 21; + case GF_SG_FIELD_CODING_OUT: return 21; + case GF_SG_FIELD_CODING_DYN: return 20; default: - return 10; + return 23; } } -static GF_Err AcousticMaterial_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err ColorTransform_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = AcousticMaterial_In2All[inField]; + *allField = ColorTransform_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = AcousticMaterial_Def2All[inField]; + *allField = ColorTransform_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = AcousticMaterial_Out2All[inField]; + *allField = ColorTransform_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = AcousticMaterial_Dyn2All[inField]; + *allField = ColorTransform_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err AcousticMaterial_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err ColorTransform_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "ambientIntensity"; + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_ColorTransform *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_ColorTransform *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_ColorTransform *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_ColorTransform *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_ColorTransform *)node)->children; + return GF_OK; + case 3: + info->name = "mrr"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mrr; + return GF_OK; + case 4: + info->name = "mrg"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mrg; + return GF_OK; + case 5: + info->name = "mrb"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mrb; + return GF_OK; + case 6: + info->name = "mra"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mra; + return GF_OK; + case 7: + info->name = "tr"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->tr; + return GF_OK; + case 8: + info->name = "mgr"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mgr; + return GF_OK; + case 9: + info->name = "mgg"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mgg; + return GF_OK; + case 10: + info->name = "mgb"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mgb; + return GF_OK; + case 11: + info->name = "mga"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mga; + return GF_OK; + case 12: + info->name = "tg"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->tg; + return GF_OK; + case 13: + info->name = "mbr"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mbr; + return GF_OK; + case 14: + info->name = "mbg"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_AcousticMaterial *) node)->ambientIntensity; + info->far_ptr = & ((M_ColorTransform *) node)->mbg; return GF_OK; - case 1: - info->name = "diffuseColor"; + case 15: + info->name = "mbb"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_AcousticMaterial *) node)->diffuseColor; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mbb; return GF_OK; - case 2: - info->name = "emissiveColor"; + case 16: + info->name = "mba"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_AcousticMaterial *) node)->emissiveColor; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mba; return GF_OK; - case 3: - info->name = "shininess"; + case 17: + info->name = "tb"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_AcousticMaterial *) node)->shininess; + info->far_ptr = & ((M_ColorTransform *) node)->tb; return GF_OK; - case 4: - info->name = "specularColor"; + case 18: + info->name = "mar"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_AcousticMaterial *) node)->specularColor; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mar; return GF_OK; - case 5: - info->name = "transparency"; + case 19: + info->name = "mag"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_AcousticMaterial *) node)->transparency; - return GF_OK; - case 6: - info->name = "reffunc"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_AcousticMaterial *) node)->reffunc; + info->far_ptr = & ((M_ColorTransform *) node)->mag; return GF_OK; - case 7: - info->name = "transfunc"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_AcousticMaterial *) node)->transfunc; + case 20: + info->name = "mab"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->mab; return GF_OK; - case 8: - info->name = "refFrequency"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_AcousticMaterial *) node)->refFrequency; + case 21: + info->name = "maa"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->maa; return GF_OK; - case 9: - info->name = "transFrequency"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_AcousticMaterial *) node)->transFrequency; + case 22: + info->name = "ta"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_ColorTransform *) node)->ta; return GF_OK; default: return GF_BAD_PARAM; @@ -13616,81 +29842,154 @@ static GF_Err AcousticMaterial_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 AcousticMaterial_get_field_index_by_name(char *name) +static s32 ColorTransform_get_field_index_by_name(char *name) { - if (!strcmp("ambientIntensity", name)) return 0; - if (!strcmp("diffuseColor", name)) return 1; - if (!strcmp("emissiveColor", name)) return 2; - if (!strcmp("shininess", name)) return 3; - if (!strcmp("specularColor", name)) return 4; - if (!strcmp("transparency", name)) return 5; - if (!strcmp("reffunc", name)) return 6; - if (!strcmp("transfunc", name)) return 7; - if (!strcmp("refFrequency", name)) return 8; - if (!strcmp("transFrequency", name)) return 9; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("mrr", name)) return 3; + if (!strcmp("mrg", name)) return 4; + if (!strcmp("mrb", name)) return 5; + if (!strcmp("mra", name)) return 6; + if (!strcmp("tr", name)) return 7; + if (!strcmp("mgr", name)) return 8; + if (!strcmp("mgg", name)) return 9; + if (!strcmp("mgb", name)) return 10; + if (!strcmp("mga", name)) return 11; + if (!strcmp("tg", name)) return 12; + if (!strcmp("mbr", name)) return 13; + if (!strcmp("mbg", name)) return 14; + if (!strcmp("mbb", name)) return 15; + if (!strcmp("mba", name)) return 16; + if (!strcmp("tb", name)) return 17; + if (!strcmp("mar", name)) return 18; + if (!strcmp("mag", name)) return 19; + if (!strcmp("mab", name)) return 20; + if (!strcmp("maa", name)) return 21; + if (!strcmp("ta", name)) return 22; return -1; } -static Bool AcousticMaterial_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool ColorTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 1: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 2: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; case 3: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; return 1; case 4: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; return 1; case 5: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; return 1; case 6: - *AType = 0; - *QType = 0; + *AType = 7; + *QType = 7; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 7: - *AType = 0; - *QType = 0; + *AType = 7; + *QType = 4; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 8: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 9: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 10: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 11: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 12: + *AType = 7; + *QType = 4; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 13: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 14: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 15: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 16: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 17: + *AType = 7; + *QType = 4; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 18: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 19: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 20: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 21: + *AType = 7; + *QType = 7; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 22: + *AType = 7; + *QType = 4; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; default: @@ -13700,128 +29999,93 @@ static Bool AcousticMaterial_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *AcousticMaterial_Create() +GF_Node *ColorTransform_Create() { - M_AcousticMaterial *p; - GF_SAFEALLOC(p, M_AcousticMaterial); + M_ColorTransform *p; + GF_SAFEALLOC(p, M_ColorTransform); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_AcousticMaterial); + gf_node_setup((GF_Node *)p, TAG_MPEG4_ColorTransform); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->ambientIntensity = FLT2FIX(0.2); - p->diffuseColor.red = FLT2FIX(0.8); - p->diffuseColor.green = FLT2FIX(0.8); - p->diffuseColor.blue = FLT2FIX(0.8); - p->emissiveColor.red = FLT2FIX(0); - p->emissiveColor.green = FLT2FIX(0); - p->emissiveColor.blue = FLT2FIX(0); - p->shininess = FLT2FIX(0.2); - p->specularColor.red = FLT2FIX(0); - p->specularColor.green = FLT2FIX(0); - p->specularColor.blue = FLT2FIX(0); - p->transparency = FLT2FIX(0); - p->reffunc.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->reffunc.count = 1; - p->reffunc.vals[0] = FLT2FIX(0); - p->transfunc.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->transfunc.count = 1; - p->transfunc.vals[0] = FLT2FIX(1); - p->refFrequency.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->refFrequency.count = 1; - p->refFrequency.vals[0] = FLT2FIX(0); - p->transFrequency.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->transFrequency.count = 1; - p->transFrequency.vals[0] = FLT2FIX(0); + p->mrr = FLT2FIX(1); + p->mrg = FLT2FIX(0); + p->mrb = FLT2FIX(0); + p->mra = FLT2FIX(0); + p->tr = FLT2FIX(0); + p->mgr = FLT2FIX(0); + p->mgg = FLT2FIX(1); + p->mgb = FLT2FIX(0); + p->mga = FLT2FIX(0); + p->tg = FLT2FIX(0); + p->mbr = FLT2FIX(0); + p->mbg = FLT2FIX(0); + p->mbb = FLT2FIX(1); + p->mba = FLT2FIX(0); + p->tb = FLT2FIX(0); + p->mar = FLT2FIX(0); + p->mag = FLT2FIX(0); + p->mab = FLT2FIX(0); + p->maa = FLT2FIX(1); + p->ta = FLT2FIX(0); return (GF_Node *)p; } /* - AcousticScene Node deletion + Ellipse Node deletion */ -static void AcousticScene_Del(GF_Node *node) +static void Ellipse_Del(GF_Node *node) { - M_AcousticScene *p = (M_AcousticScene *) node; - gf_sg_mftime_del(p->reverbTime); - gf_sg_mffloat_del(p->reverbFreq); + M_Ellipse *p = (M_Ellipse *) node; gf_node_free((GF_Node *) p); } -static const u16 AcousticScene_Def2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 AcousticScene_In2All[] = { 4, 5}; -static const u16 AcousticScene_Out2All[] = { 4, 5}; -static const u16 AcousticScene_Dyn2All[] = { 4}; +static const u16 Ellipse_Def2All[] = { 0}; +static const u16 Ellipse_In2All[] = { 0}; +static const u16 Ellipse_Out2All[] = { 0}; +static const u16 Ellipse_Dyn2All[] = { 0}; -static u32 AcousticScene_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Ellipse_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 2; - case GF_SG_FIELD_CODING_DEF: return 6; - case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 1; case GF_SG_FIELD_CODING_DYN: return 1; default: - return 6; + return 1; } } -static GF_Err AcousticScene_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Ellipse_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = AcousticScene_In2All[inField]; + *allField = Ellipse_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = AcousticScene_Def2All[inField]; + *allField = Ellipse_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = AcousticScene_Out2All[inField]; + *allField = Ellipse_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = AcousticScene_Dyn2All[inField]; + *allField = Ellipse_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err AcousticScene_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Ellipse_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "center"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_AcousticScene *) node)->center; - return GF_OK; - case 1: - info->name = "Size"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_AcousticScene *) node)->Size; - return GF_OK; - case 2: - info->name = "reverbTime"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFTIME; - info->far_ptr = & ((M_AcousticScene *) node)->reverbTime; - return GF_OK; - case 3: - info->name = "reverbFreq"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_AcousticScene *) node)->reverbFreq; - return GF_OK; - case 4: - info->name = "reverbLevel"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_AcousticScene *) node)->reverbLevel; - return GF_OK; - case 5: - info->name = "reverbDelay"; + info->name = "radius"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_AcousticScene *) node)->reverbDelay; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Ellipse *) node)->radius; return GF_OK; default: return GF_BAD_PARAM; @@ -13829,53 +30093,18 @@ static GF_Err AcousticScene_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 AcousticScene_get_field_index_by_name(char *name) +static s32 Ellipse_get_field_index_by_name(char *name) { - if (!strcmp("center", name)) return 0; - if (!strcmp("Size", name)) return 1; - if (!strcmp("reverbTime", name)) return 2; - if (!strcmp("reverbFreq", name)) return 3; - if (!strcmp("reverbLevel", name)) return 4; - if (!strcmp("reverbDelay", name)) return 5; + if (!strcmp("radius", name)) return 0; return -1; } -static Bool AcousticScene_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool Ellipse_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { case 0: - *AType = 0; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 1: - *AType = 0; - *QType = 11; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 2: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0 ); - *b_max = FIX_MAX; - return 1; - case 3: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0 ); - *b_max = FIX_MAX; - return 1; - case 4: - *AType = 7; - *QType = 0; - *b_min = FLT2FIX(0 ); - *b_max = FIX_MAX; - return 1; - case 5: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0 ); + *AType = 2; + *QType = 12; + *b_min = FLT2FIX(0); *b_max = FIX_MAX; return 1; default: @@ -13885,125 +30114,115 @@ static Bool AcousticScene_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *AcousticScene_Create() +GF_Node *Ellipse_Create() { - M_AcousticScene *p; - GF_SAFEALLOC(p, M_AcousticScene); + M_Ellipse *p; + GF_SAFEALLOC(p, M_Ellipse); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_AcousticScene); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Ellipse); /*default field values*/ - p->center.x = FLT2FIX(0); - p->center.y = FLT2FIX(0); - p->center.z = FLT2FIX(0); - p->Size.x = FLT2FIX(-1); - p->Size.y = FLT2FIX(-1); - p->Size.z = FLT2FIX(-1); - p->reverbTime.vals = (SFTime*)malloc(sizeof(SFTime)*1); - p->reverbTime.count = 1; - p->reverbTime.vals[0] = 0; - p->reverbFreq.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->reverbFreq.count = 1; - p->reverbFreq.vals[0] = FLT2FIX(1000); - p->reverbLevel = FLT2FIX(0.4); - p->reverbDelay = 0.5; + p->radius.x = FLT2FIX(1); + p->radius.y = FLT2FIX(1); return (GF_Node *)p; } /* - ApplicationWindow Node deletion + LinearGradient Node deletion */ -static void ApplicationWindow_Del(GF_Node *node) +static void LinearGradient_Del(GF_Node *node) { - M_ApplicationWindow *p = (M_ApplicationWindow *) node; - gf_sg_sfstring_del(p->description); - gf_sg_mfstring_del(p->parameter); - gf_sg_mfurl_del(p->url); + M_LinearGradient *p = (M_LinearGradient *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfcolor_del(p->keyValue); + gf_sg_mffloat_del(p->opacity); + gf_node_unregister((GF_Node *) p->transform, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 ApplicationWindow_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 ApplicationWindow_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 ApplicationWindow_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 ApplicationWindow_Dyn2All[] = { 6}; +static const u16 LinearGradient_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 LinearGradient_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 LinearGradient_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 LinearGradient_Dyn2All[] = { 0, 5}; -static u32 ApplicationWindow_get_field_count(GF_Node *node, u8 IndexMode) +static u32 LinearGradient_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: return 7; case GF_SG_FIELD_CODING_DEF: return 7; case GF_SG_FIELD_CODING_OUT: return 7; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_DYN: return 2; default: return 7; } } -static GF_Err ApplicationWindow_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err LinearGradient_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = ApplicationWindow_In2All[inField]; + *allField = LinearGradient_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = ApplicationWindow_Def2All[inField]; + *allField = LinearGradient_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = ApplicationWindow_Out2All[inField]; + *allField = LinearGradient_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = ApplicationWindow_Dyn2All[inField]; + *allField = LinearGradient_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err ApplicationWindow_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err LinearGradient_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "isActive"; + info->name = "endPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ApplicationWindow *) node)->isActive; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_LinearGradient *) node)->endPoint; return GF_OK; case 1: - info->name = "startTime"; + info->name = "key"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_ApplicationWindow *) node)->startTime; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_LinearGradient *) node)->key; return GF_OK; case 2: - info->name = "stopTime"; + info->name = "keyValue"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_ApplicationWindow *) node)->stopTime; + info->fieldType = GF_SG_VRML_MFCOLOR; + info->far_ptr = & ((M_LinearGradient *) node)->keyValue; return GF_OK; case 3: - info->name = "description"; + info->name = "opacity"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_ApplicationWindow *) node)->description; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_LinearGradient *) node)->opacity; return GF_OK; case 4: - info->name = "parameter"; + info->name = "spreadMethod"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_ApplicationWindow *) node)->parameter; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_LinearGradient *) node)->spreadMethod; return GF_OK; case 5: - info->name = "url"; + info->name = "startPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_ApplicationWindow *) node)->url; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_LinearGradient *) node)->startPoint; return GF_OK; case 6: - info->name = "size"; + info->name = "transform"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_ApplicationWindow *) node)->size; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_LinearGradient *)node)->transform; return GF_OK; default: return GF_BAD_PARAM; @@ -14011,35 +30230,54 @@ static GF_Err ApplicationWindow_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 ApplicationWindow_get_field_index_by_name(char *name) +static s32 LinearGradient_get_field_index_by_name(char *name) { - if (!strcmp("isActive", name)) return 0; - if (!strcmp("startTime", name)) return 1; - if (!strcmp("stopTime", name)) return 2; - if (!strcmp("description", name)) return 3; - if (!strcmp("parameter", name)) return 4; - if (!strcmp("url", name)) return 5; - if (!strcmp("size", name)) return 6; + if (!strcmp("endPoint", name)) return 0; + if (!strcmp("key", name)) return 1; + if (!strcmp("keyValue", name)) return 2; + if (!strcmp("opacity", name)) return 3; + if (!strcmp("spreadMethod", name)) return 4; + if (!strcmp("startPoint", name)) return 5; + if (!strcmp("transform", name)) return 6; return -1; } -static Bool ApplicationWindow_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool LinearGradient_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 0; - *QType = 0; + case 0: + *AType = 2; + *QType = 5; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; + case 1: + *AType = 0; + *QType = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; case 2: *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); return 1; - case 6: - *AType = 12; - *QType = 12; + case 3: + *AType = 0; + *QType = 7; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 4: + *AType = 0; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(2); + return 1; + case 5: + *AType = 2; + *QType = 5; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; @@ -14050,155 +30288,143 @@ static Bool ApplicationWindow_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *ApplicationWindow_Create() +GF_Node *LinearGradient_Create() { - M_ApplicationWindow *p; - GF_SAFEALLOC(p, M_ApplicationWindow); + M_LinearGradient *p; + GF_SAFEALLOC(p, M_LinearGradient); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_ApplicationWindow); + gf_node_setup((GF_Node *)p, TAG_MPEG4_LinearGradient); /*default field values*/ - p->startTime = 0; - p->stopTime = 0; - p->size.x = FLT2FIX(0); - p->size.y = FLT2FIX(0); + p->endPoint.x = FLT2FIX(1); + p->endPoint.y = FLT2FIX(0); + p->opacity.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->opacity.count = 1; + p->opacity.vals[0] = FLT2FIX(1); + p->spreadMethod = 0; + p->startPoint.x = FLT2FIX(0); + p->startPoint.y = FLT2FIX(0); return (GF_Node *)p; } /* - DirectiveSound Node deletion + PathLayout Node deletion */ -static void DirectiveSound_Del(GF_Node *node) +static void PathLayout_Del(GF_Node *node) { - M_DirectiveSound *p = (M_DirectiveSound *) node; - gf_node_unregister((GF_Node *) p->source, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->perceptualParameters, (GF_Node *) p); - gf_sg_mffloat_del(p->directivity); - gf_sg_mffloat_del(p->angles); - gf_sg_mffloat_del(p->frequency); + M_PathLayout *p = (M_PathLayout *) node; + gf_node_unregister((GF_Node *) p->geometry, (GF_Node *) p); + gf_sg_mfint32_del(p->alignment); + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 DirectiveSound_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; -static const u16 DirectiveSound_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 DirectiveSound_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 DirectiveSound_Dyn2All[] = { 0, 1, 2}; +static const u16 PathLayout_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 PathLayout_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 PathLayout_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 PathLayout_Dyn2All[] = { 5, 6}; -static u32 DirectiveSound_get_field_count(GF_Node *node, u8 IndexMode) +static u32 PathLayout_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 7; - case GF_SG_FIELD_CODING_DEF: return 13; - case GF_SG_FIELD_CODING_OUT: return 7; - case GF_SG_FIELD_CODING_DYN: return 3; + case GF_SG_FIELD_CODING_IN: return 10; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_DYN: return 2; default: - return 13; + return 10; } } -static GF_Err DirectiveSound_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err PathLayout_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = DirectiveSound_In2All[inField]; + *allField = PathLayout_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = DirectiveSound_Def2All[inField]; + *allField = PathLayout_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = DirectiveSound_Out2All[inField]; + *allField = PathLayout_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = DirectiveSound_Dyn2All[inField]; + *allField = PathLayout_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err DirectiveSound_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err PathLayout_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "direction"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_DirectiveSound *) node)->direction; + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_PathLayout *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_PathLayout *)node)->addChildren; return GF_OK; case 1: - info->name = "intensity"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_DirectiveSound *) node)->intensity; + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_PathLayout *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_PathLayout *)node)->removeChildren; return GF_OK; case 2: - info->name = "location"; + info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_DirectiveSound *) node)->location; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_PathLayout *)node)->children; return GF_OK; case 3: - info->name = "source"; + info->name = "geometry"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFAudioNode; - info->far_ptr = & ((M_DirectiveSound *)node)->source; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_PathLayout *)node)->geometry; return GF_OK; case 4: - info->name = "perceptualParameters"; + info->name = "alignment"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFPerceptualParameterNode; - info->far_ptr = & ((M_DirectiveSound *)node)->perceptualParameters; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_PathLayout *) node)->alignment; return GF_OK; case 5: - info->name = "roomEffect"; + info->name = "pathOffset"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_DirectiveSound *) node)->roomEffect; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PathLayout *) node)->pathOffset; return GF_OK; case 6: - info->name = "spatialize"; + info->name = "spacing"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_DirectiveSound *) node)->spatialize; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_PathLayout *) node)->spacing; return GF_OK; case 7: - info->name = "directivity"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_DirectiveSound *) node)->directivity; + info->name = "reverseLayout"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_PathLayout *) node)->reverseLayout; return GF_OK; case 8: - info->name = "angles"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_DirectiveSound *) node)->angles; + info->name = "wrapMode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PathLayout *) node)->wrapMode; return GF_OK; case 9: - info->name = "frequency"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_DirectiveSound *) node)->frequency; - return GF_OK; - case 10: - info->name = "speedOfSound"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_DirectiveSound *) node)->speedOfSound; - return GF_OK; - case 11: - info->name = "distance"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_DirectiveSound *) node)->distance; - return GF_OK; - case 12: - info->name = "useAirabs"; - info->eventType = GF_SG_EVENT_FIELD; + info->name = "splitText"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_DirectiveSound *) node)->useAirabs; + info->far_ptr = & ((M_PathLayout *) node)->splitText; return GF_OK; default: return GF_BAD_PARAM; @@ -14206,73 +30432,48 @@ static GF_Err DirectiveSound_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 DirectiveSound_get_field_index_by_name(char *name) +static s32 PathLayout_get_field_index_by_name(char *name) { - if (!strcmp("direction", name)) return 0; - if (!strcmp("intensity", name)) return 1; - if (!strcmp("location", name)) return 2; - if (!strcmp("source", name)) return 3; - if (!strcmp("perceptualParameters", name)) return 4; - if (!strcmp("roomEffect", name)) return 5; - if (!strcmp("spatialize", name)) return 6; - if (!strcmp("directivity", name)) return 7; - if (!strcmp("angles", name)) return 8; - if (!strcmp("frequency", name)) return 9; - if (!strcmp("speedOfSound", name)) return 10; - if (!strcmp("distance", name)) return 11; - if (!strcmp("useAirabs", name)) return 12; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("geometry", name)) return 3; + if (!strcmp("alignment", name)) return 4; + if (!strcmp("pathOffset", name)) return 5; + if (!strcmp("spacing", name)) return 6; + if (!strcmp("reverseLayout", name)) return 7; + if (!strcmp("wrapMode", name)) return 8; + if (!strcmp("splitText", name)) return 9; return -1; } -static Bool DirectiveSound_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool PathLayout_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { - switch (FieldIndex) { - case 0: - *AType = 9; - *QType = 9; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + switch (FieldIndex) { + case 4: + *AType = 0; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(-1); + *b_max = FLT2FIX(1); return 1; - case 1: + case 5: *AType = 7; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 2: - *AType = 1; - *QType = 1; + *QType = 7; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 7: - *AType = 0; - *QType = 0; + case 6: + *AType = 7; + *QType = 7; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 8: *AType = 0; - *QType = 6; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(3.14159265); - return 1; - case 9: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 10: - *AType = 0; - *QType = 1; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 11: - *AType = 0; - *QType = 0; + *QType = 13; + *QT13_bits = 2; *b_min = FLT2FIX(0); - *b_max = FIX_MAX; + *b_max = FLT2FIX(2); return 1; default: return 0; @@ -14281,104 +30482,127 @@ static Bool DirectiveSound_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *DirectiveSound_Create() +GF_Node *PathLayout_Create() { - M_DirectiveSound *p; - GF_SAFEALLOC(p, M_DirectiveSound); + M_PathLayout *p; + GF_SAFEALLOC(p, M_PathLayout); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_DirectiveSound); + gf_node_setup((GF_Node *)p, TAG_MPEG4_PathLayout); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->direction.x = FLT2FIX(0); - p->direction.y = FLT2FIX(0); - p->direction.z = FLT2FIX(-1); - p->intensity = FLT2FIX(1); - p->location.x = FLT2FIX(0); - p->location.y = FLT2FIX(0); - p->location.z = FLT2FIX(0); - p->spatialize = 1; - p->directivity.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->directivity.count = 1; - p->directivity.vals[0] = FLT2FIX(1); - p->angles.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->angles.count = 1; - p->angles.vals[0] = FLT2FIX(1); - p->speedOfSound = FLT2FIX(340); - p->distance = FLT2FIX(100); + p->alignment.vals = (SFInt32*)gf_malloc(sizeof(SFInt32)*1); + p->alignment.count = 1; + p->alignment.vals[0] = 0; + p->pathOffset = FLT2FIX(0); + p->spacing = FLT2FIX(1.0); + p->wrapMode = 0; + p->splitText = 1; return (GF_Node *)p; } /* - Hierarchical3DMesh Node deletion + RadialGradient Node deletion */ -static void Hierarchical3DMesh_Del(GF_Node *node) +static void RadialGradient_Del(GF_Node *node) { - M_Hierarchical3DMesh *p = (M_Hierarchical3DMesh *) node; - gf_sg_mfurl_del(p->url); + M_RadialGradient *p = (M_RadialGradient *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfcolor_del(p->keyValue); + gf_sg_mffloat_del(p->opacity); + gf_node_unregister((GF_Node *) p->transform, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Hierarchical3DMesh_Def2All[] = { 1, 2}; -static const u16 Hierarchical3DMesh_In2All[] = { 0, 1}; -static const u16 Hierarchical3DMesh_Out2All[] = { 1, 3}; +static const u16 RadialGradient_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 RadialGradient_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 RadialGradient_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 RadialGradient_Dyn2All[] = { 0, 1, 5}; -static u32 Hierarchical3DMesh_get_field_count(GF_Node *node, u8 IndexMode) +static u32 RadialGradient_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 2; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 2; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 8; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_DYN: return 3; default: - return 4; + return 8; } } -static GF_Err Hierarchical3DMesh_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err RadialGradient_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Hierarchical3DMesh_In2All[inField]; + *allField = RadialGradient_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Hierarchical3DMesh_Def2All[inField]; + *allField = RadialGradient_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Hierarchical3DMesh_Out2All[inField]; + *allField = RadialGradient_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = RadialGradient_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Hierarchical3DMesh_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err RadialGradient_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "triangleBudget"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Hierarchical3DMesh *)node)->on_triangleBudget; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_Hierarchical3DMesh *) node)->triangleBudget; + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_RadialGradient *) node)->center; return GF_OK; case 1: - info->name = "level"; + info->name = "focalPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Hierarchical3DMesh *) node)->level; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_RadialGradient *) node)->focalPoint; return GF_OK; case 2: - info->name = "url"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_Hierarchical3DMesh *) node)->url; + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_RadialGradient *) node)->key; return GF_OK; case 3: - info->name = "doneLoading"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Hierarchical3DMesh *) node)->doneLoading; + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFCOLOR; + info->far_ptr = & ((M_RadialGradient *) node)->keyValue; + return GF_OK; + case 4: + info->name = "opacity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_RadialGradient *) node)->opacity; + return GF_OK; + case 5: + info->name = "radius"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_RadialGradient *) node)->radius; + return GF_OK; + case 6: + info->name = "spreadMethod"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_RadialGradient *) node)->spreadMethod; + return GF_OK; + case 7: + info->name = "transform"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_RadialGradient *)node)->transform; return GF_OK; default: return GF_BAD_PARAM; @@ -14386,29 +30610,64 @@ static GF_Err Hierarchical3DMesh_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Hierarchical3DMesh_get_field_index_by_name(char *name) +static s32 RadialGradient_get_field_index_by_name(char *name) { - if (!strcmp("triangleBudget", name)) return 0; - if (!strcmp("level", name)) return 1; - if (!strcmp("url", name)) return 2; - if (!strcmp("doneLoading", name)) return 3; + if (!strcmp("center", name)) return 0; + if (!strcmp("focalPoint", name)) return 1; + if (!strcmp("key", name)) return 2; + if (!strcmp("keyValue", name)) return 3; + if (!strcmp("opacity", name)) return 4; + if (!strcmp("radius", name)) return 5; + if (!strcmp("spreadMethod", name)) return 6; + if (!strcmp("transform", name)) return 7; return -1; } -static Bool Hierarchical3DMesh_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool RadialGradient_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { case 0: - *AType = 0; - *QType = 0; - *b_min = FLT2FIX(-1); + *AType = 2; + *QType = 5; + *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 1: + *AType = 2; + *QType = 5; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 2: *AType = 0; - *QType = 0; - *b_min = FLT2FIX(-1); + *QType = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 3: + *AType = 0; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 4: + *AType = 0; + *QType = 7; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 5: + *AType = 7; + *QType = 12; + *b_min = FLT2FIX(0); *b_max = FIX_MAX; return 1; + case 6: + *AType = 0; + *QType = 13; + *QT13_bits = 2; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(2); + return 1; default: return 0; } @@ -14416,103 +30675,144 @@ static Bool Hierarchical3DMesh_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType -GF_Node *Hierarchical3DMesh_Create() +GF_Node *RadialGradient_Create() { - M_Hierarchical3DMesh *p; - GF_SAFEALLOC(p, M_Hierarchical3DMesh); + M_RadialGradient *p; + GF_SAFEALLOC(p, M_RadialGradient); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Hierarchical3DMesh); + gf_node_setup((GF_Node *)p, TAG_MPEG4_RadialGradient); /*default field values*/ - p->level = FLT2FIX(1); + p->center.x = FLT2FIX(0.5); + p->center.y = FLT2FIX(0.5); + p->focalPoint.x = FLT2FIX(0); + p->focalPoint.y = FLT2FIX(0); + p->opacity.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->opacity.count = 1; + p->opacity.vals[0] = FLT2FIX(1); + p->radius = FLT2FIX(0.5); + p->spreadMethod = 0; return (GF_Node *)p; } /* - MaterialKey Node deletion + SynthesizedTexture Node deletion */ -static void MaterialKey_Del(GF_Node *node) +static void SynthesizedTexture_Del(GF_Node *node) { - M_MaterialKey *p = (M_MaterialKey *) node; + M_SynthesizedTexture *p = (M_SynthesizedTexture *) node; + gf_sg_mfvec3f_del(p->translation); + gf_sg_mfrotation_del(p->rotation); + gf_sg_mfurl_del(p->url); gf_node_free((GF_Node *) p); } -static const u16 MaterialKey_Def2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 MaterialKey_In2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 MaterialKey_Out2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 MaterialKey_Dyn2All[] = { 2, 3, 4, 5}; +static const u16 SynthesizedTexture_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 SynthesizedTexture_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 SynthesizedTexture_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +static const u16 SynthesizedTexture_Dyn2All[] = { 0, 1, 5}; -static u32 MaterialKey_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SynthesizedTexture_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 6; - case GF_SG_FIELD_CODING_DEF: return 6; - case GF_SG_FIELD_CODING_OUT: return 6; - case GF_SG_FIELD_CODING_DYN: return 4; + case GF_SG_FIELD_CODING_IN: return 9; + case GF_SG_FIELD_CODING_DEF: return 9; + case GF_SG_FIELD_CODING_OUT: return 11; + case GF_SG_FIELD_CODING_DYN: return 3; default: - return 6; + return 11; } } -static GF_Err MaterialKey_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SynthesizedTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = MaterialKey_In2All[inField]; + *allField = SynthesizedTexture_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = MaterialKey_Def2All[inField]; + *allField = SynthesizedTexture_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = MaterialKey_Out2All[inField]; + *allField = SynthesizedTexture_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = MaterialKey_Dyn2All[inField]; + *allField = SynthesizedTexture_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err MaterialKey_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SynthesizedTexture_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "isKeyed"; + info->name = "translation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MaterialKey *) node)->isKeyed; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_SynthesizedTexture *) node)->translation; return GF_OK; case 1: - info->name = "isRGB"; + info->name = "rotation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MaterialKey *) node)->isRGB; + info->fieldType = GF_SG_VRML_MFROTATION; + info->far_ptr = & ((M_SynthesizedTexture *) node)->rotation; return GF_OK; case 2: - info->name = "keyColor"; + info->name = "pixelWidth"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_MaterialKey *) node)->keyColor; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SynthesizedTexture *) node)->pixelWidth; return GF_OK; case 3: - info->name = "lowThreshold"; + info->name = "pixelHeight"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_MaterialKey *) node)->lowThreshold; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_SynthesizedTexture *) node)->pixelHeight; return GF_OK; case 4: - info->name = "highThreshold"; + info->name = "loop"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_MaterialKey *) node)->highThreshold; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SynthesizedTexture *) node)->loop; return GF_OK; case 5: - info->name = "transparency"; + info->name = "speed"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_MaterialKey *) node)->transparency; + info->far_ptr = & ((M_SynthesizedTexture *) node)->speed; + return GF_OK; + case 6: + info->name = "startTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_SynthesizedTexture *) node)->startTime; + return GF_OK; + case 7: + info->name = "stopTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_SynthesizedTexture *) node)->stopTime; + return GF_OK; + case 8: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_SynthesizedTexture *) node)->url; + return GF_OK; + case 9: + info->name = "duration_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_SynthesizedTexture *) node)->duration_changed; + return GF_OK; + case 10: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SynthesizedTexture *) node)->isActive; return GF_OK; default: return GF_BAD_PARAM; @@ -14520,42 +30820,55 @@ static GF_Err MaterialKey_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MaterialKey_get_field_index_by_name(char *name) +static s32 SynthesizedTexture_get_field_index_by_name(char *name) { - if (!strcmp("isKeyed", name)) return 0; - if (!strcmp("isRGB", name)) return 1; - if (!strcmp("keyColor", name)) return 2; - if (!strcmp("lowThreshold", name)) return 3; - if (!strcmp("highThreshold", name)) return 4; - if (!strcmp("transparency", name)) return 5; + if (!strcmp("translation", name)) return 0; + if (!strcmp("rotation", name)) return 1; + if (!strcmp("pixelWidth", name)) return 2; + if (!strcmp("pixelHeight", name)) return 3; + if (!strcmp("loop", name)) return 4; + if (!strcmp("speed", name)) return 5; + if (!strcmp("startTime", name)) return 6; + if (!strcmp("stopTime", name)) return 7; + if (!strcmp("url", name)) return 8; + if (!strcmp("duration_changed", name)) return 9; + if (!strcmp("isActive", name)) return 10; return -1; } -static Bool MaterialKey_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SynthesizedTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 0: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 1: + *AType = 10; + *QType = 10; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; case 2: - *AType = 4; - *QType = 4; + *AType = 0; + *QType = 13; + *QT13_bits = 16; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *b_max = FIX_MAX /*WARNING: modified to allow 16.16 fixed point version!!*/; return 1; case 3: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 4: - *AType = 8; - *QType = 4; + *AType = 0; + *QType = 13; + *QT13_bits = 16; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *b_max = FIX_MAX /*WARNING: modified to allow 16.16 fixed point version!!*/; return 1; case 5: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; return 1; default: return 0; @@ -14564,191 +30877,131 @@ static Bool MaterialKey_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *A -GF_Node *MaterialKey_Create() +GF_Node *SynthesizedTexture_Create() { - M_MaterialKey *p; - GF_SAFEALLOC(p, M_MaterialKey); + M_SynthesizedTexture *p; + GF_SAFEALLOC(p, M_SynthesizedTexture); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_MaterialKey); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SynthesizedTexture); /*default field values*/ - p->isKeyed = 1; - p->isRGB = 1; - p->keyColor.red = FLT2FIX(0); - p->keyColor.green = FLT2FIX(0); - p->keyColor.blue = FLT2FIX(0); - p->lowThreshold = FLT2FIX(0); - p->highThreshold = FLT2FIX(0); - p->transparency = FLT2FIX(0); + p->pixelWidth = -1; + p->pixelHeight = -1; + p->speed = FLT2FIX(1.0); + p->startTime = 0; + p->stopTime = 0; return (GF_Node *)p; } /* - PerceptualParameters Node deletion + TransformMatrix2D Node deletion */ -static void PerceptualParameters_Del(GF_Node *node) +static void TransformMatrix2D_Del(GF_Node *node) { - M_PerceptualParameters *p = (M_PerceptualParameters *) node; - gf_sg_mffloat_del(p->omniDirectivity); - gf_sg_mffloat_del(p->directFilterGains); - gf_sg_mffloat_del(p->inputFilterGains); + M_TransformMatrix2D *p = (M_TransformMatrix2D *) node; + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 PerceptualParameters_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; -static const u16 PerceptualParameters_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; -static const u16 PerceptualParameters_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}; -static const u16 PerceptualParameters_Dyn2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; +static const u16 TransformMatrix2D_Def2All[] = { 2, 3, 4, 5, 6, 7, 8}; +static const u16 TransformMatrix2D_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 TransformMatrix2D_Out2All[] = { 2, 3, 4, 5, 6, 7, 8}; +static const u16 TransformMatrix2D_Dyn2All[] = { 3, 4, 5, 6, 7, 8}; -static u32 PerceptualParameters_get_field_count(GF_Node *node, u8 IndexMode) +static u32 TransformMatrix2D_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 19; - case GF_SG_FIELD_CODING_DEF: return 19; - case GF_SG_FIELD_CODING_OUT: return 19; - case GF_SG_FIELD_CODING_DYN: return 15; + case GF_SG_FIELD_CODING_IN: return 9; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 6; default: - return 19; + return 9; } } -static GF_Err PerceptualParameters_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err TransformMatrix2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PerceptualParameters_In2All[inField]; + *allField = TransformMatrix2D_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PerceptualParameters_Def2All[inField]; + *allField = TransformMatrix2D_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PerceptualParameters_Out2All[inField]; + *allField = TransformMatrix2D_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = PerceptualParameters_Dyn2All[inField]; + *allField = TransformMatrix2D_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PerceptualParameters_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err TransformMatrix2D_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "sourcePresence"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->sourcePresence; + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_TransformMatrix2D *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_TransformMatrix2D *)node)->addChildren; return GF_OK; case 1: - info->name = "sourceWarmth"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->sourceWarmth; - return GF_OK; - case 2: - info->name = "sourceBrilliance"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->sourceBrilliance; - return GF_OK; - case 3: - info->name = "roomPresence"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->roomPresence; - return GF_OK; - case 4: - info->name = "runningReverberance"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->runningReverberance; - return GF_OK; - case 5: - info->name = "envelopment"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->envelopment; - return GF_OK; - case 6: - info->name = "lateReverberance"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->lateReverberance; - return GF_OK; - case 7: - info->name = "heavyness"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->heavyness; - return GF_OK; - case 8: - info->name = "liveness"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->liveness; - return GF_OK; - case 9: - info->name = "omniDirectivity"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->omniDirectivity; - return GF_OK; - case 10: - info->name = "directFilterGains"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->directFilterGains; + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_TransformMatrix2D *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_TransformMatrix2D *)node)->removeChildren; return GF_OK; - case 11: - info->name = "inputFilterGains"; + case 2: + info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->inputFilterGains; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_TransformMatrix2D *)node)->children; return GF_OK; - case 12: - info->name = "refDistance"; + case 3: + info->name = "mxx"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->refDistance; + info->far_ptr = & ((M_TransformMatrix2D *) node)->mxx; return GF_OK; - case 13: - info->name = "freqLow"; + case 4: + info->name = "mxy"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->freqLow; + info->far_ptr = & ((M_TransformMatrix2D *) node)->mxy; return GF_OK; - case 14: - info->name = "freqHigh"; + case 5: + info->name = "tx"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PerceptualParameters *) node)->freqHigh; - return GF_OK; - case 15: - info->name = "timeLimit1"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_PerceptualParameters *) node)->timeLimit1; + info->far_ptr = & ((M_TransformMatrix2D *) node)->tx; return GF_OK; - case 16: - info->name = "timeLimit2"; + case 6: + info->name = "myx"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_PerceptualParameters *) node)->timeLimit2; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_TransformMatrix2D *) node)->myx; return GF_OK; - case 17: - info->name = "timeLimit3"; + case 7: + info->name = "myy"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_PerceptualParameters *) node)->timeLimit3; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_TransformMatrix2D *) node)->myy; return GF_OK; - case 18: - info->name = "modalDensity"; + case 8: + info->name = "ty"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_PerceptualParameters *) node)->modalDensity; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_TransformMatrix2D *) node)->ty; return GF_OK; default: return GF_BAD_PARAM; @@ -14756,145 +31009,243 @@ static GF_Err PerceptualParameters_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PerceptualParameters_get_field_index_by_name(char *name) +static s32 TransformMatrix2D_get_field_index_by_name(char *name) { - if (!strcmp("sourcePresence", name)) return 0; - if (!strcmp("sourceWarmth", name)) return 1; - if (!strcmp("sourceBrilliance", name)) return 2; - if (!strcmp("roomPresence", name)) return 3; - if (!strcmp("runningReverberance", name)) return 4; - if (!strcmp("envelopment", name)) return 5; - if (!strcmp("lateReverberance", name)) return 6; - if (!strcmp("heavyness", name)) return 7; - if (!strcmp("liveness", name)) return 8; - if (!strcmp("omniDirectivity", name)) return 9; - if (!strcmp("directFilterGains", name)) return 10; - if (!strcmp("inputFilterGains", name)) return 11; - if (!strcmp("refDistance", name)) return 12; - if (!strcmp("freqLow", name)) return 13; - if (!strcmp("freqHigh", name)) return 14; - if (!strcmp("timeLimit1", name)) return 15; - if (!strcmp("timeLimit2", name)) return 16; - if (!strcmp("timeLimit3", name)) return 17; - if (!strcmp("modalDensity", name)) return 18; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("mxx", name)) return 3; + if (!strcmp("mxy", name)) return 4; + if (!strcmp("tx", name)) return 5; + if (!strcmp("myx", name)) return 6; + if (!strcmp("myy", name)) return 7; + if (!strcmp("ty", name)) return 8; return -1; } -static Bool PerceptualParameters_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool TransformMatrix2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 1: - *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 2: - *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; case 3: *AType = 7; - *QType = 0; + *QType = 7; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 4: *AType = 7; - *QType = 0; + *QType = 7; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 5: *AType = 7; - *QType = 0; + *QType = 7; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 6: *AType = 7; - *QType = 0; + *QType = 7; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 7: *AType = 7; - *QType = 0; + *QType = 7; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; case 8: *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 9: - *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 10: - *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 11: - *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 12: - *AType = 7; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 13: - *AType = 7; - *QType = 0; + *QType = 7; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 14: - *AType = 7; - *QType = 0; + default: + return 0; + } +} + + + +GF_Node *TransformMatrix2D_Create() +{ + M_TransformMatrix2D *p; + GF_SAFEALLOC(p, M_TransformMatrix2D); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_TransformMatrix2D); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->mxx = FLT2FIX(1); + p->mxy = FLT2FIX(0); + p->tx = FLT2FIX(0); + p->myx = FLT2FIX(0); + p->myy = FLT2FIX(1); + p->ty = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + Viewport Node deletion +*/ + +static void Viewport_Del(GF_Node *node) +{ + M_Viewport *p = (M_Viewport *) node; + gf_sg_mfint32_del(p->alignment); + gf_sg_sfstring_del(p->description); + gf_node_free((GF_Node *) p); +} + +static const u16 Viewport_Def2All[] = { 1, 2, 3, 4, 5, 6}; +static const u16 Viewport_In2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 Viewport_Out2All[] = { 1, 2, 3, 4, 5, 7, 8}; +static const u16 Viewport_Dyn2All[] = { 1, 2, 3}; + +static u32 Viewport_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 6; + case GF_SG_FIELD_CODING_DEF: return 6; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 3; + default: + return 9; + } +} + +static GF_Err Viewport_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = Viewport_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = Viewport_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = Viewport_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Viewport_Dyn2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err Viewport_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_bind"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Viewport *)node)->on_set_bind; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Viewport *) node)->set_bind; + return GF_OK; + case 1: + info->name = "position"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Viewport *) node)->position; + return GF_OK; + case 2: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_Viewport *) node)->size; + return GF_OK; + case 3: + info->name = "orientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Viewport *) node)->orientation; + return GF_OK; + case 4: + info->name = "alignment"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_Viewport *) node)->alignment; + return GF_OK; + case 5: + info->name = "fit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Viewport *) node)->fit; + return GF_OK; + case 6: + info->name = "description"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_Viewport *) node)->description; + return GF_OK; + case 7: + info->name = "bindTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_Viewport *) node)->bindTime; + return GF_OK; + case 8: + info->name = "isBound"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Viewport *) node)->isBound; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Viewport_get_field_index_by_name(char *name) +{ + if (!strcmp("set_bind", name)) return 0; + if (!strcmp("position", name)) return 1; + if (!strcmp("size", name)) return 2; + if (!strcmp("orientation", name)) return 3; + if (!strcmp("alignment", name)) return 4; + if (!strcmp("fit", name)) return 5; + if (!strcmp("description", name)) return 6; + if (!strcmp("bindTime", name)) return 7; + if (!strcmp("isBound", name)) return 8; + return -1; + } +static Bool Viewport_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + case 1: + *AType = 1; + *QType = 1; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 15: - *AType = 0; - *QType = 0; + case 2: + *AType = 12; + *QType = 12; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 16: - *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + case 3: + *AType = 6; + *QType = 6; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(6.2831853); return 1; - case 17: + case 4: *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(-1); + *b_max = FLT2FIX(1); return 1; - case 18: + case 5: *AType = 0; - *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(2); return 1; default: return 0; @@ -14903,182 +31254,96 @@ static Bool PerceptualParameters_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QTy -GF_Node *PerceptualParameters_Create() +GF_Node *Viewport_Create() { - M_PerceptualParameters *p; - GF_SAFEALLOC(p, M_PerceptualParameters); + M_Viewport *p; + GF_SAFEALLOC(p, M_Viewport); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PerceptualParameters); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Viewport); /*default field values*/ - p->sourcePresence = FLT2FIX(1.0); - p->sourceWarmth = FLT2FIX(1.0); - p->sourceBrilliance = FLT2FIX(1.0); - p->roomPresence = FLT2FIX(1.0); - p->runningReverberance = FLT2FIX(1.0); - p->envelopment = FLT2FIX(0.0); - p->lateReverberance = FLT2FIX(1.0); - p->heavyness = FLT2FIX(1.0); - p->liveness = FLT2FIX(1.0); - p->omniDirectivity.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->omniDirectivity.count = 1; - p->omniDirectivity.vals[0] = FLT2FIX(1.0); - p->directFilterGains.vals = (SFFloat*)malloc(sizeof(SFFloat)*3); - p->directFilterGains.count = 3; - p->directFilterGains.vals[0] = FLT2FIX(1.0); - p->directFilterGains.vals[1] = FLT2FIX(1.0); - p->directFilterGains.vals[2] = FLT2FIX(1.0); - p->inputFilterGains.vals = (SFFloat*)malloc(sizeof(SFFloat)*3); - p->inputFilterGains.count = 3; - p->inputFilterGains.vals[0] = FLT2FIX(1.0); - p->inputFilterGains.vals[1] = FLT2FIX(1.0); - p->inputFilterGains.vals[2] = FLT2FIX(1.0); - p->refDistance = FLT2FIX(1.0); - p->freqLow = FLT2FIX(250.0); - p->freqHigh = FLT2FIX(4000.0); - p->timeLimit1 = 0.02; - p->timeLimit2 = 0.04; - p->timeLimit3 = 0.1; - p->modalDensity = 0.8; + p->position.x = FLT2FIX(0); + p->position.y = FLT2FIX(0); + p->size.x = FLT2FIX(-1); + p->size.y = FLT2FIX(-1); + p->orientation = FLT2FIX(0); + p->alignment.vals = (SFInt32*)gf_malloc(sizeof(SFInt32)*1); + p->alignment.count = 1; + p->alignment.vals[0] = 0; + p->fit = 0; return (GF_Node *)p; } /* - TemporalTransform Node deletion + XCurve2D Node deletion */ -static void TemporalTransform_Del(GF_Node *node) +static void XCurve2D_Del(GF_Node *node) { - M_TemporalTransform *p = (M_TemporalTransform *) node; - gf_sg_mfurl_del(p->url); - gf_sg_mfint32_del(p->stretchMode); - gf_sg_mfint32_del(p->shrinkMode); - gf_sg_vrml_parent_destroy((GF_Node *) p); + M_XCurve2D *p = (M_XCurve2D *) node; + gf_node_unregister((GF_Node *) p->point, (GF_Node *) p); + gf_sg_mfint32_del(p->type); gf_node_free((GF_Node *) p); } -static const u16 TemporalTransform_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -static const u16 TemporalTransform_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -static const u16 TemporalTransform_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; -static const u16 TemporalTransform_Dyn2All[] = { 7, 8}; +static const u16 XCurve2D_Def2All[] = { 0, 1, 2}; +static const u16 XCurve2D_In2All[] = { 0, 1, 2}; +static const u16 XCurve2D_Out2All[] = { 0, 1, 2}; +static const u16 XCurve2D_Dyn2All[] = { 1}; -static u32 TemporalTransform_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XCurve2D_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 12; - case GF_SG_FIELD_CODING_DEF: return 10; - case GF_SG_FIELD_CODING_OUT: return 11; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 3; + case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_DYN: return 1; default: - return 13; + return 3; } } -static GF_Err TemporalTransform_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XCurve2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = TemporalTransform_In2All[inField]; + *allField = XCurve2D_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = TemporalTransform_Def2All[inField]; + *allField = XCurve2D_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = TemporalTransform_Out2All[inField]; + *allField = XCurve2D_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = TemporalTransform_Dyn2All[inField]; + *allField = XCurve2D_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err TemporalTransform_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XCurve2D_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_TemporalTransform *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_TemporalTransform *)node)->addChildren; - return GF_OK; - case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_TemporalTransform *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_TemporalTransform *)node)->removeChildren; - return GF_OK; - case 2: - info->name = "children"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_TemporalTransform *)node)->children; - return GF_OK; - case 3: - info->name = "url"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_TemporalTransform *) node)->url; - return GF_OK; - case 4: - info->name = "startTime"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TemporalTransform *) node)->startTime; - return GF_OK; - case 5: - info->name = "optimalDuration"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TemporalTransform *) node)->optimalDuration; - return GF_OK; - case 6: - info->name = "active"; + info->name = "point"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TemporalTransform *) node)->active; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinate2DNode; + info->far_ptr = & ((M_XCurve2D *)node)->point; return GF_OK; - case 7: - info->name = "speed"; + case 1: + info->name = "fineness"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_TemporalTransform *) node)->speed; - return GF_OK; - case 8: - info->name = "scalability"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_TemporalTransform *) node)->scalability; - return GF_OK; - case 9: - info->name = "stretchMode"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_TemporalTransform *) node)->stretchMode; - return GF_OK; - case 10: - info->name = "shrinkMode"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_TemporalTransform *) node)->shrinkMode; - return GF_OK; - case 11: - info->name = "maxDelay"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TemporalTransform *) node)->maxDelay; + info->far_ptr = & ((M_XCurve2D *) node)->fineness; return GF_OK; - case 12: - info->name = "actualDuration"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_TemporalTransform *) node)->actualDuration; + case 2: + info->name = "type"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XCurve2D *) node)->type; return GF_OK; default: return GF_BAD_PARAM; @@ -15086,51 +31351,28 @@ static GF_Err TemporalTransform_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 TemporalTransform_get_field_index_by_name(char *name) +static s32 XCurve2D_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; - if (!strcmp("url", name)) return 3; - if (!strcmp("startTime", name)) return 4; - if (!strcmp("optimalDuration", name)) return 5; - if (!strcmp("active", name)) return 6; - if (!strcmp("speed", name)) return 7; - if (!strcmp("scalability", name)) return 8; - if (!strcmp("stretchMode", name)) return 9; - if (!strcmp("shrinkMode", name)) return 10; - if (!strcmp("maxDelay", name)) return 11; - if (!strcmp("actualDuration", name)) return 12; + if (!strcmp("point", name)) return 0; + if (!strcmp("fineness", name)) return 1; + if (!strcmp("type", name)) return 2; return -1; } -static Bool TemporalTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XCurve2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 7: + case 1: *AType = 7; *QType = 0; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 8: - *AType = 12; - *QType = 12; - *b_min = FLT2FIX(-1); - *b_max = FIX_MAX; - return 1; - case 9: - *AType = 0; - *QType = 13; - *QT13_bits = 2; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(2); + *b_max = FLT2FIX(1); return 1; - case 10: + case 2: *AType = 0; *QType = 13; - *QT13_bits = 1; + *QT13_bits = 4; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *b_max = FLT2FIX(15); return 1; default: return 0; @@ -15139,136 +31381,174 @@ static Bool TemporalTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *TemporalTransform_Create() +GF_Node *XCurve2D_Create() { - M_TemporalTransform *p; - GF_SAFEALLOC(p, M_TemporalTransform); + M_XCurve2D *p; + GF_SAFEALLOC(p, M_XCurve2D); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_TemporalTransform); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XCurve2D); /*default field values*/ - p->startTime = -1.0; - p->optimalDuration = -1.0; - p->speed = FLT2FIX(1.0); - p->scalability.x = FLT2FIX(1.0); - p->scalability.y = FLT2FIX(1.0); - p->stretchMode.vals = (SFInt32*)malloc(sizeof(SFInt32)*1); - p->stretchMode.count = 1; - p->stretchMode.vals[0] = 0; - p->shrinkMode.vals = (SFInt32*)malloc(sizeof(SFInt32)*1); - p->shrinkMode.count = 1; - p->shrinkMode.vals[0] = 0; - p->maxDelay = 0; + p->fineness = FLT2FIX(0.5); return (GF_Node *)p; } /* - TemporalGroup Node deletion + XFontStyle Node deletion */ -static void TemporalGroup_Del(GF_Node *node) +static void XFontStyle_Del(GF_Node *node) { - M_TemporalGroup *p = (M_TemporalGroup *) node; - gf_sg_mffloat_del(p->priority); - gf_sg_vrml_parent_destroy((GF_Node *) p); + M_XFontStyle *p = (M_XFontStyle *) node; + gf_sg_mfstring_del(p->fontName); + gf_sg_mfstring_del(p->justify); + gf_sg_sfstring_del(p->language); + gf_sg_sfstring_del(p->stretch); + gf_sg_sfstring_del(p->style); + gf_sg_mfstring_del(p->featureName); + gf_sg_mfint32_del(p->featureStartOffset); + gf_sg_mfint32_del(p->featureLength); + gf_sg_mfint32_del(p->featureValue); gf_node_free((GF_Node *) p); } -static const u16 TemporalGroup_Def2All[] = { 2, 3, 4, 5, 6}; -static const u16 TemporalGroup_In2All[] = { 0, 1, 2, 6}; -static const u16 TemporalGroup_Out2All[] = { 2, 6, 7, 8}; +static const u16 XFontStyle_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; +static const u16 XFontStyle_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; +static const u16 XFontStyle_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; -static u32 TemporalGroup_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XFontStyle_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 4; + case GF_SG_FIELD_CODING_IN: return 17; + case GF_SG_FIELD_CODING_DEF: return 17; + case GF_SG_FIELD_CODING_OUT: return 17; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 9; + return 17; } } -static GF_Err TemporalGroup_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XFontStyle_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = TemporalGroup_In2All[inField]; + *allField = XFontStyle_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = TemporalGroup_Def2All[inField]; + *allField = XFontStyle_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = TemporalGroup_Out2All[inField]; + *allField = XFontStyle_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err TemporalGroup_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XFontStyle_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_TemporalGroup *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SFTemporalNode; - info->far_ptr = & ((M_TemporalGroup *)node)->addChildren; + info->name = "fontName"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_XFontStyle *) node)->fontName; return GF_OK; case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_TemporalGroup *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SFTemporalNode; - info->far_ptr = & ((M_TemporalGroup *)node)->removeChildren; + info->name = "horizontal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_XFontStyle *) node)->horizontal; return GF_OK; case 2: - info->name = "children"; + info->name = "justify"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SFTemporalNode; - info->far_ptr = & ((M_TemporalGroup *)node)->children; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_XFontStyle *) node)->justify; return GF_OK; case 3: - info->name = "costart"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TemporalGroup *) node)->costart; + info->name = "language"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_XFontStyle *) node)->language; return GF_OK; case 4: - info->name = "coend"; - info->eventType = GF_SG_EVENT_FIELD; + info->name = "leftToRight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TemporalGroup *) node)->coend; + info->far_ptr = & ((M_XFontStyle *) node)->leftToRight; return GF_OK; case 5: - info->name = "meet"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TemporalGroup *) node)->meet; + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XFontStyle *) node)->size; return GF_OK; case 6: - info->name = "priority"; + info->name = "stretch"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_TemporalGroup *) node)->priority; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_XFontStyle *) node)->stretch; return GF_OK; case 7: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_TemporalGroup *) node)->isActive; + info->name = "letterSpacing"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XFontStyle *) node)->letterSpacing; return GF_OK; case 8: - info->name = "activeChild"; - info->eventType = GF_SG_EVENT_OUT; + info->name = "wordSpacing"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XFontStyle *) node)->wordSpacing; + return GF_OK; + case 9: + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_TemporalGroup *) node)->activeChild; + info->far_ptr = & ((M_XFontStyle *) node)->weight; + return GF_OK; + case 10: + info->name = "fontKerning"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_XFontStyle *) node)->fontKerning; + return GF_OK; + case 11: + info->name = "style"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_XFontStyle *) node)->style; + return GF_OK; + case 12: + info->name = "topToBottom"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_XFontStyle *) node)->topToBottom; + return GF_OK; + case 13: + info->name = "featureName"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_XFontStyle *) node)->featureName; + return GF_OK; + case 14: + info->name = "featureStartOffset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XFontStyle *) node)->featureStartOffset; + return GF_OK; + case 15: + info->name = "featureLength"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XFontStyle *) node)->featureLength; + return GF_OK; + case 16: + info->name = "featureValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_XFontStyle *) node)->featureValue; return GF_OK; default: return GF_BAD_PARAM; @@ -15276,25 +31556,45 @@ static GF_Err TemporalGroup_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 TemporalGroup_get_field_index_by_name(char *name) +static s32 XFontStyle_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; - if (!strcmp("costart", name)) return 3; - if (!strcmp("coend", name)) return 4; - if (!strcmp("meet", name)) return 5; - if (!strcmp("priority", name)) return 6; - if (!strcmp("isActive", name)) return 7; - if (!strcmp("activeChild", name)) return 8; + if (!strcmp("fontName", name)) return 0; + if (!strcmp("horizontal", name)) return 1; + if (!strcmp("justify", name)) return 2; + if (!strcmp("language", name)) return 3; + if (!strcmp("leftToRight", name)) return 4; + if (!strcmp("size", name)) return 5; + if (!strcmp("stretch", name)) return 6; + if (!strcmp("letterSpacing", name)) return 7; + if (!strcmp("wordSpacing", name)) return 8; + if (!strcmp("weight", name)) return 9; + if (!strcmp("fontKerning", name)) return 10; + if (!strcmp("style", name)) return 11; + if (!strcmp("topToBottom", name)) return 12; + if (!strcmp("featureName", name)) return 13; + if (!strcmp("featureStartOffset", name)) return 14; + if (!strcmp("featureLength", name)) return 15; + if (!strcmp("featureValue", name)) return 16; return -1; } -static Bool TemporalGroup_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XFontStyle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 6: + case 5: *AType = 0; - *QType = 3; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 0; + *QType = 11; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 8: + *AType = 0; + *QType = 11; *b_min = FLT2FIX(0); *b_max = FIX_MAX; return 1; @@ -15305,91 +31605,169 @@ static Bool TemporalGroup_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *TemporalGroup_Create() +GF_Node *XFontStyle_Create() { - M_TemporalGroup *p; - GF_SAFEALLOC(p, M_TemporalGroup); + M_XFontStyle *p; + GF_SAFEALLOC(p, M_XFontStyle); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_TemporalGroup); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XFontStyle); /*default field values*/ - p->costart = 1; + p->fontName.vals = (char**)gf_malloc(sizeof(SFString)*1); + p->fontName.count = 1; + p->fontName.vals[0] = (char*)gf_malloc(sizeof(char) * 6); + strcpy(p->fontName.vals[0], "SERIF"); + p->horizontal = 1; + p->justify.vals = (char**)gf_malloc(sizeof(SFString)*1); + p->justify.count = 1; + p->justify.vals[0] = (char*)gf_malloc(sizeof(char) * 6); + strcpy(p->justify.vals[0], "BEGIN"); + p->leftToRight = 1; + p->size = FLT2FIX(1.0); + p->stretch.buffer = (char*)gf_malloc(sizeof(char) * 7); + strcpy(p->stretch.buffer, "NORMAL"); + p->letterSpacing = FLT2FIX(0.0); + p->wordSpacing = FLT2FIX(0.0); + p->weight = 400; + p->fontKerning = 1; + p->style.buffer = (char*)gf_malloc(sizeof(char) * 6); + strcpy(p->style.buffer, "PLAIN"); + p->topToBottom = 1; return (GF_Node *)p; } /* - ServerCommand Node deletion + XLineProperties Node deletion */ -static void ServerCommand_Del(GF_Node *node) +static void XLineProperties_Del(GF_Node *node) { - M_ServerCommand *p = (M_ServerCommand *) node; - gf_sg_mfurl_del(p->url); - gf_sg_sfstring_del(p->command); + M_XLineProperties *p = (M_XLineProperties *) node; + gf_sg_mffloat_del(p->dashes); + gf_node_unregister((GF_Node *) p->texture, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->textureTransform, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 ServerCommand_Def2All[] = { 1, 2, 3}; -static const u16 ServerCommand_In2All[] = { 0, 1, 2, 3}; -static const u16 ServerCommand_Out2All[] = { 1, 2, 3}; +static const u16 XLineProperties_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 XLineProperties_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 XLineProperties_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 XLineProperties_Dyn2All[] = { 0, 7, 8, 9, 10}; -static u32 ServerCommand_get_field_count(GF_Node *node, u8 IndexMode) +static u32 XLineProperties_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 4; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 3; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 13; + case GF_SG_FIELD_CODING_DEF: return 13; + case GF_SG_FIELD_CODING_OUT: return 13; + case GF_SG_FIELD_CODING_DYN: return 5; default: - return 4; + return 13; } } -static GF_Err ServerCommand_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err XLineProperties_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = ServerCommand_In2All[inField]; + *allField = XLineProperties_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = ServerCommand_Def2All[inField]; + *allField = XLineProperties_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = ServerCommand_Out2All[inField]; + *allField = XLineProperties_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = XLineProperties_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err ServerCommand_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err XLineProperties_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "trigger"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_ServerCommand *)node)->on_trigger; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ServerCommand *) node)->trigger; + info->name = "lineColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_XLineProperties *) node)->lineColor; return GF_OK; case 1: - info->name = "enable"; + info->name = "lineStyle"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_ServerCommand *) node)->enable; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_XLineProperties *) node)->lineStyle; return GF_OK; case 2: - info->name = "url"; + info->name = "isCenterAligned"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_ServerCommand *) node)->url; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_XLineProperties *) node)->isCenterAligned; return GF_OK; case 3: - info->name = "command"; + info->name = "isScalable"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_ServerCommand *) node)->command; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_XLineProperties *) node)->isScalable; + return GF_OK; + case 4: + info->name = "lineCap"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_XLineProperties *) node)->lineCap; + return GF_OK; + case 5: + info->name = "lineJoin"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_XLineProperties *) node)->lineJoin; + return GF_OK; + case 6: + info->name = "miterLimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XLineProperties *) node)->miterLimit; + return GF_OK; + case 7: + info->name = "transparency"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XLineProperties *) node)->transparency; + return GF_OK; + case 8: + info->name = "width"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XLineProperties *) node)->width; + return GF_OK; + case 9: + info->name = "dashOffset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_XLineProperties *) node)->dashOffset; + return GF_OK; + case 10: + info->name = "dashes"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_XLineProperties *) node)->dashes; + return GF_OK; + case 11: + info->name = "texture"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_XLineProperties *)node)->texture; + return GF_OK; + case 12: + info->name = "textureTransform"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureTransformNode; + info->far_ptr = & ((M_XLineProperties *)node)->textureTransform; return GF_OK; default: return GF_BAD_PARAM; @@ -15397,17 +31775,83 @@ static GF_Err ServerCommand_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 ServerCommand_get_field_index_by_name(char *name) +static s32 XLineProperties_get_field_index_by_name(char *name) { - if (!strcmp("trigger", name)) return 0; - if (!strcmp("enable", name)) return 1; - if (!strcmp("url", name)) return 2; - if (!strcmp("command", name)) return 3; + if (!strcmp("lineColor", name)) return 0; + if (!strcmp("lineStyle", name)) return 1; + if (!strcmp("isCenterAligned", name)) return 2; + if (!strcmp("isScalable", name)) return 3; + if (!strcmp("lineCap", name)) return 4; + if (!strcmp("lineJoin", name)) return 5; + if (!strcmp("miterLimit", name)) return 6; + if (!strcmp("transparency", name)) return 7; + if (!strcmp("width", name)) return 8; + if (!strcmp("dashOffset", name)) return 9; + if (!strcmp("dashes", name)) return 10; + if (!strcmp("texture", name)) return 11; + if (!strcmp("textureTransform", name)) return 12; return -1; } -static Bool ServerCommand_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool XLineProperties_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 0: + *AType = 4; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 1: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(5); + return 1; + case 4: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(2); + return 1; + case 5: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(2); + return 1; + case 6: + *AType = 0; + *QType = 12; + *b_min = FLT2FIX(1); + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 8; + *QType = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 8: + *AType = 7; + *QType = 12; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 9: + *AType = 7; + *QType = 12; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 10: + *AType = 7; + *QType = 12; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; default: return 0; } @@ -15415,88 +31859,193 @@ static Bool ServerCommand_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *ServerCommand_Create() +GF_Node *XLineProperties_Create() { - M_ServerCommand *p; - GF_SAFEALLOC(p, M_ServerCommand); + M_XLineProperties *p; + GF_SAFEALLOC(p, M_XLineProperties); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_ServerCommand); + gf_node_setup((GF_Node *)p, TAG_MPEG4_XLineProperties); /*default field values*/ + p->lineColor.red = FLT2FIX(0); + p->lineColor.green = FLT2FIX(0); + p->lineColor.blue = FLT2FIX(0); + p->lineStyle = 0; + p->isCenterAligned = 1; + p->isScalable = 1; + p->lineCap = 0; + p->lineJoin = 0; + p->miterLimit = FLT2FIX(4); + p->transparency = FLT2FIX(0); + p->width = FLT2FIX(1); + p->dashOffset = FLT2FIX(0); return (GF_Node *)p; } /* - InputSensor Node deletion + AdvancedAudioBuffer Node deletion */ -static void InputSensor_Del(GF_Node *node) +static void AdvancedAudioBuffer_Del(GF_Node *node) { - M_InputSensor *p = (M_InputSensor *) node; - gf_sg_sfcommand_del(p->buffer); - gf_sg_mfurl_del(p->url); + M_AdvancedAudioBuffer *p = (M_AdvancedAudioBuffer *) node; + gf_sg_mfint32_del(p->phaseGroup); + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 InputSensor_Def2All[] = { 0, 1, 2}; -static const u16 InputSensor_In2All[] = { 0, 1, 2}; -static const u16 InputSensor_Out2All[] = { 0, 1, 2, 3}; +static const u16 AdvancedAudioBuffer_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; +static const u16 AdvancedAudioBuffer_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; +static const u16 AdvancedAudioBuffer_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16, 17}; +static const u16 AdvancedAudioBuffer_Dyn2All[] = { 4}; -static u32 InputSensor_get_field_count(GF_Node *node, u8 IndexMode) +static u32 AdvancedAudioBuffer_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 4; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 14; + case GF_SG_FIELD_CODING_DEF: return 14; + case GF_SG_FIELD_CODING_OUT: return 14; + case GF_SG_FIELD_CODING_DYN: return 1; default: - return 4; + return 18; } } -static GF_Err InputSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err AdvancedAudioBuffer_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = InputSensor_In2All[inField]; + *allField = AdvancedAudioBuffer_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = InputSensor_Def2All[inField]; + *allField = AdvancedAudioBuffer_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = InputSensor_Out2All[inField]; + *allField = AdvancedAudioBuffer_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = AdvancedAudioBuffer_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err InputSensor_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err AdvancedAudioBuffer_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "enabled"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_InputSensor *) node)->enabled; + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_AdvancedAudioBuffer *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_AdvancedAudioBuffer *)node)->addChildren; return GF_OK; case 1: - info->name = "buffer"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOMMANDBUFFER; - info->far_ptr = & ((M_InputSensor *) node)->buffer; + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_AdvancedAudioBuffer *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_AdvancedAudioBuffer *)node)->removeChildren; return GF_OK; case 2: - info->name = "url"; + info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_InputSensor *) node)->url; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_AdvancedAudioBuffer *)node)->children; return GF_OK; case 3: - info->name = "eventTime"; + info->name = "loop"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->loop; + return GF_OK; + case 4: + info->name = "pitch"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->pitch; + return GF_OK; + case 5: + info->name = "startTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->startTime; + return GF_OK; + case 6: + info->name = "stopTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->stopTime; + return GF_OK; + case 7: + info->name = "startLoadTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->startLoadTime; + return GF_OK; + case 8: + info->name = "stopLoadTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->stopLoadTime; + return GF_OK; + case 9: + info->name = "loadMode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->loadMode; + return GF_OK; + case 10: + info->name = "numAccumulatedBlocks"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->numAccumulatedBlocks; + return GF_OK; + case 11: + info->name = "deleteBlock"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->deleteBlock; + return GF_OK; + case 12: + info->name = "playBlock"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->playBlock; + return GF_OK; + case 13: + info->name = "length"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->length; + return GF_OK; + case 14: + info->name = "numChan"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->numChan; + return GF_OK; + case 15: + info->name = "phaseGroup"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->phaseGroup; + return GF_OK; + case 16: + info->name = "duration_changed"; info->eventType = GF_SG_EVENT_OUT; info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_InputSensor *) node)->eventTime; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->duration_changed; + return GF_OK; + case 17: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_AdvancedAudioBuffer *) node)->isActive; return GF_OK; default: return GF_BAD_PARAM; @@ -15504,17 +32053,109 @@ static GF_Err InputSensor_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 InputSensor_get_field_index_by_name(char *name) +static s32 AdvancedAudioBuffer_get_field_index_by_name(char *name) { - if (!strcmp("enabled", name)) return 0; - if (!strcmp("buffer", name)) return 1; - if (!strcmp("url", name)) return 2; - if (!strcmp("eventTime", name)) return 3; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("loop", name)) return 3; + if (!strcmp("pitch", name)) return 4; + if (!strcmp("startTime", name)) return 5; + if (!strcmp("stopTime", name)) return 6; + if (!strcmp("startLoadTime", name)) return 7; + if (!strcmp("stopLoadTime", name)) return 8; + if (!strcmp("loadMode", name)) return 9; + if (!strcmp("numAccumulatedBlocks", name)) return 10; + if (!strcmp("deleteBlock", name)) return 11; + if (!strcmp("playBlock", name)) return 12; + if (!strcmp("length", name)) return 13; + if (!strcmp("numChan", name)) return 14; + if (!strcmp("phaseGroup", name)) return 15; + if (!strcmp("duration_changed", name)) return 16; + if (!strcmp("isActive", name)) return 17; return -1; } -static Bool InputSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool AdvancedAudioBuffer_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 4: + *AType = 7; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 5: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 7: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 8: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 9: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(4); + return 1; + case 10: + *AType = 0; + *QType = 13; + *QT13_bits = 16; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX /*WARNING: modified to allow 16.16 fixed point version!!*/; + return 1; + case 11: + *AType = 0; + *QType = 13; + *QT13_bits = 17; + *b_min = FLT2FIX(-65536.0f); + *b_max = FLT2FIX( 0); + return 1; + case 12: + *AType = 0; + *QType = 13; + *QT13_bits = 17; + *b_min = FLT2FIX(-65536.0f); + *b_max = FLT2FIX( 0); + return 1; + case 13: + *AType = 0; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 14: + *AType = 0; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(255); + return 1; + case 15: + *AType = 0; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(255); + return 1; default: return 0; } @@ -15522,114 +32163,219 @@ static Bool InputSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *A -GF_Node *InputSensor_Create() +GF_Node *AdvancedAudioBuffer_Create() { - M_InputSensor *p; - GF_SAFEALLOC(p, M_InputSensor); + M_AdvancedAudioBuffer *p; + GF_SAFEALLOC(p, M_AdvancedAudioBuffer); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_InputSensor); - p->buffer.commandList = gf_list_new(); + gf_node_setup((GF_Node *)p, TAG_MPEG4_AdvancedAudioBuffer); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->enabled = 1; + p->pitch = FLT2FIX(1.0); + p->startTime = 0; + p->stopTime = 0; + p->startLoadTime = 0; + p->stopLoadTime = 0; + p->loadMode = 0; + p->numAccumulatedBlocks = 0; + p->deleteBlock = 0; + p->playBlock = 0; + p->length = FLT2FIX(0.0); + p->numChan = 1; return (GF_Node *)p; } /* - MatteTexture Node deletion + AudioChannelConfig Node deletion */ -static void MatteTexture_Del(GF_Node *node) +static void AudioChannelConfig_Del(GF_Node *node) { - M_MatteTexture *p = (M_MatteTexture *) node; - gf_node_unregister((GF_Node *) p->surfaceA, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->surfaceB, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->alphaSurface, (GF_Node *) p); - gf_sg_sfstring_del(p->operation); - gf_sg_mffloat_del(p->parameter); + M_AudioChannelConfig *p = (M_AudioChannelConfig *) node; + gf_sg_mfint32_del(p->channelCoordinateSystems); + gf_sg_mffloat_del(p->channelSoundLocation); + gf_sg_mfint32_del(p->channelDirectionalPattern); + gf_sg_mfvec3f_del(p->channelDirection); + gf_sg_mfint32_del(p->ambComponentIndex); + gf_sg_mffloat_del(p->ambBackwardMatrix); + gf_sg_mfint32_del(p->ambSoundfieldResolution); + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 MatteTexture_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 MatteTexture_In2All[] = { 3, 5, 6}; -static const u16 MatteTexture_Out2All[] = { 3, 5, 6}; +static const u16 AudioChannelConfig_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21}; +static const u16 AudioChannelConfig_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; +static const u16 AudioChannelConfig_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; -static u32 MatteTexture_get_field_count(GF_Node *node, u8 IndexMode) +static u32 AudioChannelConfig_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 7; - case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_IN: return 21; + case GF_SG_FIELD_CODING_DEF: return 20; + case GF_SG_FIELD_CODING_OUT: return 19; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 7; + return 22; } } -static GF_Err MatteTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err AudioChannelConfig_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = MatteTexture_In2All[inField]; + *allField = AudioChannelConfig_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = MatteTexture_Def2All[inField]; + *allField = AudioChannelConfig_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = MatteTexture_Out2All[inField]; + *allField = AudioChannelConfig_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err MatteTexture_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err AudioChannelConfig_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "surfaceA"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureNode; - info->far_ptr = & ((M_MatteTexture *)node)->surfaceA; + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_AudioChannelConfig *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_AudioChannelConfig *)node)->addChildren; return GF_OK; case 1: - info->name = "surfaceB"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureNode; - info->far_ptr = & ((M_MatteTexture *)node)->surfaceB; + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_AudioChannelConfig *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_AudioChannelConfig *)node)->removeChildren; return GF_OK; case 2: - info->name = "alphaSurface"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureNode; - info->far_ptr = & ((M_MatteTexture *)node)->alphaSurface; + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_AudioChannelConfig *)node)->children; return GF_OK; case 3: - info->name = "operation"; + info->name = "generalChannelFormat"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_MatteTexture *) node)->operation; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->generalChannelFormat; return GF_OK; case 4: - info->name = "overwrite"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MatteTexture *) node)->overwrite; + info->name = "fixedPreset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->fixedPreset; return GF_OK; case 5: - info->name = "fraction"; + info->name = "fixedPresetSubset"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_MatteTexture *) node)->fraction; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->fixedPresetSubset; return GF_OK; case 6: - info->name = "parameter"; + info->name = "fixedPresetAddInf"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->fixedPresetAddInf; + return GF_OK; + case 7: + info->name = "channelCoordinateSystems"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->channelCoordinateSystems; + return GF_OK; + case 8: + info->name = "channelSoundLocation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_MatteTexture *) node)->parameter; + info->far_ptr = & ((M_AudioChannelConfig *) node)->channelSoundLocation; + return GF_OK; + case 9: + info->name = "channelDirectionalPattern"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->channelDirectionalPattern; + return GF_OK; + case 10: + info->name = "channelDirection"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_AudioChannelConfig *) node)->channelDirection; + return GF_OK; + case 11: + info->name = "ambResolution2D"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambResolution2D; + return GF_OK; + case 12: + info->name = "ambResolution3D"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambResolution3D; + return GF_OK; + case 13: + info->name = "ambEncodingConvention"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambEncodingConvention; + return GF_OK; + case 14: + info->name = "ambNfcReferenceDistance"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambNfcReferenceDistance; + return GF_OK; + case 15: + info->name = "ambSoundSpeed"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambSoundSpeed; + return GF_OK; + case 16: + info->name = "ambArrangementRule"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambArrangementRule; + return GF_OK; + case 17: + info->name = "ambRecombinationPreset"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambRecombinationPreset; + return GF_OK; + case 18: + info->name = "ambComponentIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambComponentIndex; + return GF_OK; + case 19: + info->name = "ambBackwardMatrix"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambBackwardMatrix; + return GF_OK; + case 20: + info->name = "ambSoundfieldResolution"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->ambSoundfieldResolution; + return GF_OK; + case 21: + info->name = "numChannel"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_AudioChannelConfig *) node)->numChannel; return GF_OK; default: return GF_BAD_PARAM; @@ -15637,20 +32383,126 @@ static GF_Err MatteTexture_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MatteTexture_get_field_index_by_name(char *name) +static s32 AudioChannelConfig_get_field_index_by_name(char *name) { - if (!strcmp("surfaceA", name)) return 0; - if (!strcmp("surfaceB", name)) return 1; - if (!strcmp("alphaSurface", name)) return 2; - if (!strcmp("operation", name)) return 3; - if (!strcmp("overwrite", name)) return 4; - if (!strcmp("fraction", name)) return 5; - if (!strcmp("parameter", name)) return 6; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("generalChannelFormat", name)) return 3; + if (!strcmp("fixedPreset", name)) return 4; + if (!strcmp("fixedPresetSubset", name)) return 5; + if (!strcmp("fixedPresetAddInf", name)) return 6; + if (!strcmp("channelCoordinateSystems", name)) return 7; + if (!strcmp("channelSoundLocation", name)) return 8; + if (!strcmp("channelDirectionalPattern", name)) return 9; + if (!strcmp("channelDirection", name)) return 10; + if (!strcmp("ambResolution2D", name)) return 11; + if (!strcmp("ambResolution3D", name)) return 12; + if (!strcmp("ambEncodingConvention", name)) return 13; + if (!strcmp("ambNfcReferenceDistance", name)) return 14; + if (!strcmp("ambSoundSpeed", name)) return 15; + if (!strcmp("ambArrangementRule", name)) return 16; + if (!strcmp("ambRecombinationPreset", name)) return 17; + if (!strcmp("ambComponentIndex", name)) return 18; + if (!strcmp("ambBackwardMatrix", name)) return 19; + if (!strcmp("ambSoundfieldResolution", name)) return 20; + if (!strcmp("numChannel", name)) return 21; return -1; } -static Bool MatteTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool AudioChannelConfig_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 3: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(4); + return 1; + case 4: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(15); + return 1; + case 6: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(2); + return 1; + case 7: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(6); + return 1; + case 9: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(2); + return 1; + case 11: + *AType = 0; + *QType = 13; + *QT13_bits = 7; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(127); + return 1; + case 12: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(15); + return 1; + case 13: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(5); + return 1; + case 16: + *AType = 0; + *QType = 13; + *QT13_bits = 3; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(7); + return 1; + case 17: + *AType = 0; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(15); + return 1; + case 18: + *AType = 0; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(255); + return 1; + case 20: + *AType = 0; + *QType = 13; + *QT13_bits = 7; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(127); + return 1; + case 21: + *AType = 0; + *QType = 13; + *QT13_bits = 8; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(255); + return 1; default: return 0; } @@ -15658,103 +32510,117 @@ static Bool MatteTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 * -GF_Node *MatteTexture_Create() +GF_Node *AudioChannelConfig_Create() { - M_MatteTexture *p; - GF_SAFEALLOC(p, M_MatteTexture); + M_AudioChannelConfig *p; + GF_SAFEALLOC(p, M_AudioChannelConfig); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_MatteTexture); + gf_node_setup((GF_Node *)p, TAG_MPEG4_AudioChannelConfig); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->fraction = FLT2FIX(0); - p->parameter.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->parameter.count = 1; - p->parameter.vals[0] = FLT2FIX(0); + p->generalChannelFormat = 0; + p->fixedPreset = 0; + p->fixedPresetSubset = 0; + p->fixedPresetAddInf = 0; + p->ambResolution2D = 1; + p->ambResolution3D = 0; + p->ambEncodingConvention = 0; + p->ambNfcReferenceDistance = FLT2FIX(1.5); + p->ambSoundSpeed = FLT2FIX(340.0); + p->ambArrangementRule = 0; + p->ambRecombinationPreset = 0; + p->numChannel = 0; return (GF_Node *)p; } /* - MediaBuffer Node deletion + DepthImageV2 Node deletion */ -static void MediaBuffer_Del(GF_Node *node) +static void DepthImageV2_Del(GF_Node *node) { - M_MediaBuffer *p = (M_MediaBuffer *) node; - gf_sg_mfurl_del(p->url); + M_DepthImageV2 *p = (M_DepthImageV2 *) node; + gf_node_unregister((GF_Node *) p->diTexture, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 MediaBuffer_Def2All[] = { 0, 1, 2, 3, 5}; -static const u16 MediaBuffer_In2All[] = { 0, 1, 2, 3, 5}; -static const u16 MediaBuffer_Out2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 DepthImageV2_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static u32 MediaBuffer_get_field_count(GF_Node *node, u8 IndexMode) +static u32 DepthImageV2_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 5; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 0; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 6; + return 8; } } -static GF_Err MediaBuffer_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err DepthImageV2_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = MediaBuffer_In2All[inField]; - return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = MediaBuffer_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = MediaBuffer_Out2All[inField]; + *allField = DepthImageV2_Def2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err MediaBuffer_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err DepthImageV2_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "bufferSize"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_MediaBuffer *) node)->bufferSize; + info->name = "diTexture"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFDepthTextureNode; + info->far_ptr = & ((M_DepthImageV2 *)node)->diTexture; return GF_OK; case 1: - info->name = "url"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_MediaBuffer *) node)->url; + info->name = "farPlane"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_DepthImageV2 *) node)->farPlane; return GF_OK; case 2: - info->name = "mediaStartTime"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MediaBuffer *) node)->mediaStartTime; + info->name = "fieldOfView"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_DepthImageV2 *) node)->fieldOfView; return GF_OK; case 3: - info->name = "mediaStopTime"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MediaBuffer *) node)->mediaStopTime; + info->name = "nearPlane"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_DepthImageV2 *) node)->nearPlane; return GF_OK; case 4: - info->name = "isBuffered"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MediaBuffer *) node)->isBuffered; + info->name = "orientation"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_DepthImageV2 *) node)->orientation; return GF_OK; case 5: - info->name = "enabled"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->name = "orthographic"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MediaBuffer *) node)->enabled; + info->far_ptr = & ((M_DepthImageV2 *) node)->orthographic; + return GF_OK; + case 6: + info->name = "position"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_DepthImageV2 *) node)->position; + return GF_OK; + case 7: + info->name = "splatMinMax"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_DepthImageV2 *) node)->splatMinMax; return GF_OK; default: return GF_BAD_PARAM; @@ -15762,17 +32628,19 @@ static GF_Err MediaBuffer_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MediaBuffer_get_field_index_by_name(char *name) +static s32 DepthImageV2_get_field_index_by_name(char *name) { - if (!strcmp("bufferSize", name)) return 0; - if (!strcmp("url", name)) return 1; - if (!strcmp("mediaStartTime", name)) return 2; - if (!strcmp("mediaStopTime", name)) return 3; - if (!strcmp("isBuffered", name)) return 4; - if (!strcmp("enabled", name)) return 5; + if (!strcmp("diTexture", name)) return 0; + if (!strcmp("farPlane", name)) return 1; + if (!strcmp("fieldOfView", name)) return 2; + if (!strcmp("nearPlane", name)) return 3; + if (!strcmp("orientation", name)) return 4; + if (!strcmp("orthographic", name)) return 5; + if (!strcmp("position", name)) return 6; + if (!strcmp("splatMinMax", name)) return 7; return -1; } -static Bool MediaBuffer_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool DepthImageV2_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { default: @@ -15782,121 +32650,105 @@ static Bool MediaBuffer_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *A -GF_Node *MediaBuffer_Create() +GF_Node *DepthImageV2_Create() { - M_MediaBuffer *p; - GF_SAFEALLOC(p, M_MediaBuffer); + M_DepthImageV2 *p; + GF_SAFEALLOC(p, M_DepthImageV2); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_MediaBuffer); + gf_node_setup((GF_Node *)p, TAG_MPEG4_DepthImageV2); /*default field values*/ - p->bufferSize = FLT2FIX(0.0); - p->mediaStartTime = -1; - p->mediaStopTime = FIX_MAX; - p->enabled = 1; + p->farPlane = FLT2FIX(100); + p->fieldOfView.x = FLT2FIX(0.75); + p->fieldOfView.y = FLT2FIX(0.75); + p->nearPlane = FLT2FIX(10); + p->orientation.x = FLT2FIX(0); + p->orientation.y = FLT2FIX(0); + p->orientation.z = FLT2FIX(1); + p->orientation.q = FLT2FIX(0); + p->orthographic = 1; + p->position.x = FLT2FIX(0); + p->position.y = FLT2FIX(0); + p->position.z = FLT2FIX(10); + p->splatMinMax.x = FLT2FIX(0.115); + p->splatMinMax.y = FLT2FIX(0.975); return (GF_Node *)p; } /* - MediaControl Node deletion + MorphShape Node deletion */ -static void MediaControl_Del(GF_Node *node) +static void MorphShape_Del(GF_Node *node) { - M_MediaControl *p = (M_MediaControl *) node; - gf_sg_mfurl_del(p->url); + M_MorphShape *p = (M_MorphShape *) node; + gf_node_unregister((GF_Node *) p->baseShape, (GF_Node *) p); + gf_node_unregister_children((GF_Node *) p, p->targetShapes); + gf_sg_mffloat_del(p->weights); gf_node_free((GF_Node *) p); } -static const u16 MediaControl_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static const u16 MediaControl_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static const u16 MediaControl_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 MorphShape_Def2All[] = { 0, 1, 2, 3}; +static const u16 MorphShape_In2All[] = { 0, 1, 2, 3}; +static const u16 MorphShape_Out2All[] = { 0, 1, 2, 3}; -static u32 MediaControl_get_field_count(GF_Node *node, u8 IndexMode) +static u32 MorphShape_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 8; - case GF_SG_FIELD_CODING_DEF: return 8; - case GF_SG_FIELD_CODING_OUT: return 9; + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 4; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 9; + return 4; } } -static GF_Err MediaControl_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err MorphShape_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = MediaControl_In2All[inField]; + *allField = MorphShape_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = MediaControl_Def2All[inField]; + *allField = MorphShape_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = MediaControl_Out2All[inField]; + *allField = MorphShape_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err MediaControl_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MorphShape_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "url"; + info->name = "baseShape"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_MediaControl *) node)->url; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_MorphShape *)node)->baseShape; return GF_OK; case 1: - info->name = "mediaStartTime"; + info->name = "morphID"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MediaControl *) node)->mediaStartTime; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_MorphShape *) node)->morphID; return GF_OK; case 2: - info->name = "mediaStopTime"; + info->name = "targetShapes"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MediaControl *) node)->mediaStopTime; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_MorphShape *)node)->targetShapes; return GF_OK; case 3: - info->name = "mediaSpeed"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_MediaControl *) node)->mediaSpeed; - return GF_OK; - case 4: - info->name = "loop"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MediaControl *) node)->loop; - return GF_OK; - case 5: - info->name = "preRoll"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MediaControl *) node)->preRoll; - return GF_OK; - case 6: - info->name = "mute"; + info->name = "weights"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MediaControl *) node)->mute; - return GF_OK; - case 7: - info->name = "enabled"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MediaControl *) node)->enabled; - return GF_OK; - case 8: - info->name = "isPreRolled"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MediaControl *) node)->isPreRolled; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_MorphShape *) node)->weights; return GF_OK; default: return GF_BAD_PARAM; @@ -15904,22 +32756,24 @@ static GF_Err MediaControl_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MediaControl_get_field_index_by_name(char *name) +static s32 MorphShape_get_field_index_by_name(char *name) { - if (!strcmp("url", name)) return 0; - if (!strcmp("mediaStartTime", name)) return 1; - if (!strcmp("mediaStopTime", name)) return 2; - if (!strcmp("mediaSpeed", name)) return 3; - if (!strcmp("loop", name)) return 4; - if (!strcmp("preRoll", name)) return 5; - if (!strcmp("mute", name)) return 6; - if (!strcmp("enabled", name)) return 7; - if (!strcmp("isPreRolled", name)) return 8; + if (!strcmp("baseShape", name)) return 0; + if (!strcmp("morphID", name)) return 1; + if (!strcmp("targetShapes", name)) return 2; + if (!strcmp("weights", name)) return 3; return -1; } -static Bool MediaControl_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool MorphShape_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 1: + *AType = 0; + *QType = 13; + *QT13_bits = 7; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX( 1023); + return 1; default: return 0; } @@ -15927,105 +32781,117 @@ static Bool MediaControl_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 * -GF_Node *MediaControl_Create() +GF_Node *MorphShape_Create() { - M_MediaControl *p; - GF_SAFEALLOC(p, M_MediaControl); + M_MorphShape *p; + GF_SAFEALLOC(p, M_MorphShape); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_MediaControl); + gf_node_setup((GF_Node *)p, TAG_MPEG4_MorphShape); /*default field values*/ - p->mediaStartTime = -1; - p->mediaStopTime = FIX_MAX; - p->mediaSpeed = FLT2FIX(1.0); - p->preRoll = 1; - p->enabled = 1; + p->morphID = 0; return (GF_Node *)p; } /* - MediaSensor Node deletion + MultiTexture Node deletion */ -static void MediaSensor_Del(GF_Node *node) +static void MultiTexture_Del(GF_Node *node) { - M_MediaSensor *p = (M_MediaSensor *) node; - gf_sg_mfurl_del(p->url); - gf_sg_mfstring_del(p->info); + M_MultiTexture *p = (M_MultiTexture *) node; + gf_sg_mfint32_del(p->function); + gf_sg_mfint32_del(p->mode); + gf_sg_mfint32_del(p->source); + gf_node_unregister_children((GF_Node *) p, p->texture); + gf_sg_mfvec3f_del(p->cameraVector); gf_node_free((GF_Node *) p); } -static const u16 MediaSensor_Def2All[] = { 0}; -static const u16 MediaSensor_In2All[] = { 0}; -static const u16 MediaSensor_Out2All[] = { 0, 1, 2, 3, 4, 5}; +static const u16 MultiTexture_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 MultiTexture_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 MultiTexture_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static u32 MediaSensor_get_field_count(GF_Node *node, u8 IndexMode) +static u32 MultiTexture_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 6; + case GF_SG_FIELD_CODING_IN: return 8; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 8; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 6; + return 8; } } -static GF_Err MediaSensor_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err MultiTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = MediaSensor_In2All[inField]; + *allField = MultiTexture_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = MediaSensor_Def2All[inField]; + *allField = MultiTexture_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = MediaSensor_Out2All[inField]; + *allField = MultiTexture_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err MediaSensor_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MultiTexture_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "url"; + info->name = "alpha"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((M_MediaSensor *) node)->url; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_MultiTexture *) node)->alpha; return GF_OK; case 1: - info->name = "mediaCurrentTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MediaSensor *) node)->mediaCurrentTime; + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((M_MultiTexture *) node)->color; return GF_OK; case 2: - info->name = "streamObjectStartTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MediaSensor *) node)->streamObjectStartTime; + info->name = "function"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MultiTexture *) node)->function; return GF_OK; case 3: - info->name = "mediaDuration"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_MediaSensor *) node)->mediaDuration; + info->name = "mode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MultiTexture *) node)->mode; return GF_OK; case 4: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_MediaSensor *) node)->isActive; + info->name = "source"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MultiTexture *) node)->source; return GF_OK; case 5: - info->name = "info"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_MediaSensor *) node)->info; + info->name = "texture"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_MultiTexture *)node)->texture; + return GF_OK; + case 6: + info->name = "cameraVector"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_MultiTexture *) node)->cameraVector; + return GF_OK; + case 7: + info->name = "transparent"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MultiTexture *) node)->transparent; return GF_OK; default: return GF_BAD_PARAM; @@ -16033,17 +32899,19 @@ static GF_Err MediaSensor_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MediaSensor_get_field_index_by_name(char *name) +static s32 MultiTexture_get_field_index_by_name(char *name) { - if (!strcmp("url", name)) return 0; - if (!strcmp("mediaCurrentTime", name)) return 1; - if (!strcmp("streamObjectStartTime", name)) return 2; - if (!strcmp("mediaDuration", name)) return 3; - if (!strcmp("isActive", name)) return 4; - if (!strcmp("info", name)) return 5; + if (!strcmp("alpha", name)) return 0; + if (!strcmp("color", name)) return 1; + if (!strcmp("function", name)) return 2; + if (!strcmp("mode", name)) return 3; + if (!strcmp("source", name)) return 4; + if (!strcmp("texture", name)) return 5; + if (!strcmp("cameraVector", name)) return 6; + if (!strcmp("transparent", name)) return 7; return -1; } -static Bool MediaSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool MultiTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { default: @@ -16053,90 +32921,112 @@ static Bool MediaSensor_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *A -GF_Node *MediaSensor_Create() +GF_Node *MultiTexture_Create() { - M_MediaSensor *p; - GF_SAFEALLOC(p, M_MediaSensor); + M_MultiTexture *p; + GF_SAFEALLOC(p, M_MultiTexture); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_MediaSensor); + gf_node_setup((GF_Node *)p, TAG_MPEG4_MultiTexture); /*default field values*/ + p->alpha = FLT2FIX(1); + p->color.red = FLT2FIX(1); + p->color.green = FLT2FIX(1); + p->color.blue = FLT2FIX(1); return (GF_Node *)p; } /* - CoordinateInterpolator4D Node deletion + PointTextureV2 Node deletion */ -static void CoordinateInterpolator4D_Del(GF_Node *node) +static void PointTextureV2_Del(GF_Node *node) { - M_CoordinateInterpolator4D *p = (M_CoordinateInterpolator4D *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfvec4f_del(p->keyValue); - gf_sg_mfvec4f_del(p->value_changed); + M_PointTextureV2 *p = (M_PointTextureV2 *) node; + gf_sg_mfcolor_del(p->color); + gf_sg_mfint32_del(p->depth); + gf_node_unregister((GF_Node *) p->normal, (GF_Node *) p); + gf_sg_mfvec3f_del(p->splatU); + gf_sg_mfvec3f_del(p->splatV); gf_node_free((GF_Node *) p); } -static const u16 CoordinateInterpolator4D_Def2All[] = { 1, 2}; -static const u16 CoordinateInterpolator4D_In2All[] = { 0, 1, 2}; -static const u16 CoordinateInterpolator4D_Out2All[] = { 1, 2, 3}; +static const u16 PointTextureV2_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static u32 CoordinateInterpolator4D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 PointTextureV2_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 3; + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 0; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 4; + return 8; } } -static GF_Err CoordinateInterpolator4D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err PointTextureV2_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = CoordinateInterpolator4D_In2All[inField]; - return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = CoordinateInterpolator4D_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = CoordinateInterpolator4D_Out2All[inField]; + *allField = PointTextureV2_Def2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err CoordinateInterpolator4D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err PointTextureV2_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_fraction"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_CoordinateInterpolator4D *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_CoordinateInterpolator4D *) node)->set_fraction; + info->name = "color"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFCOLOR; + info->far_ptr = & ((M_PointTextureV2 *) node)->color; return GF_OK; case 1: - info->name = "key"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_CoordinateInterpolator4D *) node)->key; + info->name = "depth"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_PointTextureV2 *) node)->depth; return GF_OK; case 2: - info->name = "keyValue"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC4F; - info->far_ptr = & ((M_CoordinateInterpolator4D *) node)->keyValue; + info->name = "depthNbBits"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PointTextureV2 *) node)->depthNbBits; return GF_OK; case 3: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFVEC4F; - info->far_ptr = & ((M_CoordinateInterpolator4D *) node)->value_changed; + info->name = "height"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PointTextureV2 *) node)->height; + return GF_OK; + case 4: + info->name = "normal"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((M_PointTextureV2 *)node)->normal; + return GF_OK; + case 5: + info->name = "splatU"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_PointTextureV2 *) node)->splatU; + return GF_OK; + case 6: + info->name = "splatV"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((M_PointTextureV2 *) node)->splatV; + return GF_OK; + case 7: + info->name = "width"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_PointTextureV2 *) node)->width; return GF_OK; default: return GF_BAD_PARAM; @@ -16144,26 +33034,37 @@ static GF_Err CoordinateInterpolator4D_get_field(GF_Node *node, GF_FieldInfo *in } -static s32 CoordinateInterpolator4D_get_field_index_by_name(char *name) +static s32 PointTextureV2_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("key", name)) return 1; - if (!strcmp("keyValue", name)) return 2; - if (!strcmp("value_changed", name)) return 3; + if (!strcmp("color", name)) return 0; + if (!strcmp("depth", name)) return 1; + if (!strcmp("depthNbBits", name)) return 2; + if (!strcmp("height", name)) return 3; + if (!strcmp("normal", name)) return 4; + if (!strcmp("splatU", name)) return 5; + if (!strcmp("splatV", name)) return 6; + if (!strcmp("width", name)) return 7; return -1; } -static Bool CoordinateInterpolator4D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool PointTextureV2_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: + case 2: *AType = 0; - *QType = 8; + *QType = 13; + *QT13_bits = 5; *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); + *b_max = FLT2FIX(31); return 1; - case 2: + case 5: *AType = 0; - *QType = 15; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 0; + *QType = 1; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; @@ -16174,95 +33075,133 @@ static Bool CoordinateInterpolator4D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 -GF_Node *CoordinateInterpolator4D_Create() +GF_Node *PointTextureV2_Create() { - M_CoordinateInterpolator4D *p; - GF_SAFEALLOC(p, M_CoordinateInterpolator4D); + M_PointTextureV2 *p; + GF_SAFEALLOC(p, M_PointTextureV2); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_CoordinateInterpolator4D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_PointTextureV2); /*default field values*/ + p->depthNbBits = 7; + p->height = 256; + p->width = 256; return (GF_Node *)p; } /* - NonLinearDeformer Node deletion + SBVCAnimationV2 Node deletion */ -static void NonLinearDeformer_Del(GF_Node *node) +static void SBVCAnimationV2_Del(GF_Node *node) { - M_NonLinearDeformer *p = (M_NonLinearDeformer *) node; - gf_sg_mffloat_del(p->extend); - gf_node_unregister((GF_Node *) p->geometry, (GF_Node *) p); + M_SBVCAnimationV2 *p = (M_SBVCAnimationV2 *) node; + gf_sg_mfint32_del(p->activeUrlIndex); + gf_sg_mfurl_del(p->url); + gf_node_unregister_children((GF_Node *) p, p->virtualCharacters); gf_node_free((GF_Node *) p); } -static const u16 NonLinearDeformer_Def2All[] = { 0, 1, 2, 3, 4}; -static const u16 NonLinearDeformer_In2All[] = { 0, 1, 2, 3, 4}; -static const u16 NonLinearDeformer_Out2All[] = { 0, 1, 2, 3, 4}; +static const u16 SBVCAnimationV2_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 SBVCAnimationV2_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 SBVCAnimationV2_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; +static const u16 SBVCAnimationV2_Dyn2All[] = { 2, 5}; -static u32 NonLinearDeformer_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SBVCAnimationV2_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 5; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 5; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 8; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 10; + case GF_SG_FIELD_CODING_DYN: return 2; default: - return 5; + return 10; } } -static GF_Err NonLinearDeformer_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SBVCAnimationV2_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = NonLinearDeformer_In2All[inField]; + *allField = SBVCAnimationV2_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = NonLinearDeformer_Def2All[inField]; + *allField = SBVCAnimationV2_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = NonLinearDeformer_Out2All[inField]; + *allField = SBVCAnimationV2_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = SBVCAnimationV2_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err NonLinearDeformer_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SBVCAnimationV2_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "axis"; + info->name = "activeUrlIndex"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_NonLinearDeformer *) node)->axis; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_SBVCAnimationV2 *) node)->activeUrlIndex; return GF_OK; case 1: - info->name = "extend"; + info->name = "loop"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_NonLinearDeformer *) node)->extend; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SBVCAnimationV2 *) node)->loop; return GF_OK; case 2: - info->name = "geometry"; + info->name = "speed"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFGeometryNode; - info->far_ptr = & ((M_NonLinearDeformer *)node)->geometry; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SBVCAnimationV2 *) node)->speed; return GF_OK; case 3: - info->name = "param"; + info->name = "startTime"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_NonLinearDeformer *) node)->param; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_SBVCAnimationV2 *) node)->startTime; return GF_OK; case 4: - info->name = "type"; + info->name = "stopTime"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_NonLinearDeformer *) node)->type; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_SBVCAnimationV2 *) node)->stopTime; + return GF_OK; + case 5: + info->name = "transitionTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SBVCAnimationV2 *) node)->transitionTime; + return GF_OK; + case 6: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_SBVCAnimationV2 *) node)->url; + return GF_OK; + case 7: + info->name = "virtualCharacters"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SBVCAnimationV2 *)node)->virtualCharacters; + return GF_OK; + case 8: + info->name = "duration_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_SBVCAnimationV2 *) node)->duration_changed; + return GF_OK; + case 9: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SBVCAnimationV2 *) node)->isActive; return GF_OK; default: return GF_BAD_PARAM; @@ -16270,18 +33209,35 @@ static GF_Err NonLinearDeformer_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 NonLinearDeformer_get_field_index_by_name(char *name) +static s32 SBVCAnimationV2_get_field_index_by_name(char *name) { - if (!strcmp("axis", name)) return 0; - if (!strcmp("extend", name)) return 1; - if (!strcmp("geometry", name)) return 2; - if (!strcmp("param", name)) return 3; - if (!strcmp("type", name)) return 4; + if (!strcmp("activeUrlIndex", name)) return 0; + if (!strcmp("loop", name)) return 1; + if (!strcmp("speed", name)) return 2; + if (!strcmp("startTime", name)) return 3; + if (!strcmp("stopTime", name)) return 4; + if (!strcmp("transitionTime", name)) return 5; + if (!strcmp("url", name)) return 6; + if (!strcmp("virtualCharacters", name)) return 7; + if (!strcmp("duration_changed", name)) return 8; + if (!strcmp("isActive", name)) return 9; return -1; } -static Bool NonLinearDeformer_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SBVCAnimationV2_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { + case 2: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 5: + *AType = 7; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; default: return 0; } @@ -16289,151 +33245,98 @@ static Bool NonLinearDeformer_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *NonLinearDeformer_Create() +GF_Node *SBVCAnimationV2_Create() { - M_NonLinearDeformer *p; - GF_SAFEALLOC(p, M_NonLinearDeformer); + M_SBVCAnimationV2 *p; + GF_SAFEALLOC(p, M_SBVCAnimationV2); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_NonLinearDeformer); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SBVCAnimationV2); /*default field values*/ - p->axis.x = FLT2FIX(0); - p->axis.y = FLT2FIX(0); - p->axis.z = FLT2FIX(1); - p->param = FLT2FIX(0); - p->type = 0; + p->speed = FLT2FIX(1.0); + p->startTime = 0; + p->stopTime = 0; + p->transitionTime = FLT2FIX(0); return (GF_Node *)p; } /* - PositionAnimator Node deletion + SimpleTextureV2 Node deletion */ -static void PositionAnimator_Del(GF_Node *node) +static void SimpleTextureV2_Del(GF_Node *node) { - M_PositionAnimator *p = (M_PositionAnimator *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfrotation_del(p->keyOrientation); - gf_sg_mfvec2f_del(p->keySpline); - gf_sg_mfvec3f_del(p->keyValue); - gf_sg_mffloat_del(p->weight); + M_SimpleTextureV2 *p = (M_SimpleTextureV2 *) node; + gf_node_unregister((GF_Node *) p->depth, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->normal, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->splatU, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->splatV, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->texture, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 PositionAnimator_Def2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 PositionAnimator_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 PositionAnimator_Out2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 SimpleTextureV2_Def2All[] = { 0, 1, 2, 3, 4}; -static u32 PositionAnimator_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SimpleTextureV2_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 10; - case GF_SG_FIELD_CODING_DEF: return 9; - case GF_SG_FIELD_CODING_OUT: return 12; + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 0; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 13; + return 5; } } -static GF_Err PositionAnimator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SimpleTextureV2_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = PositionAnimator_In2All[inField]; - return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PositionAnimator_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = PositionAnimator_Out2All[inField]; + *allField = SimpleTextureV2_Def2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PositionAnimator_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SimpleTextureV2_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_fraction"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_PositionAnimator *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PositionAnimator *) node)->set_fraction; - return GF_OK; - case 1: - info->name = "fromTo"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PositionAnimator *) node)->fromTo; - return GF_OK; - case 2: - info->name = "key"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PositionAnimator *) node)->key; - return GF_OK; - case 3: - info->name = "keyOrientation"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFROTATION; - info->far_ptr = & ((M_PositionAnimator *) node)->keyOrientation; - return GF_OK; - case 4: - info->name = "keyType"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_PositionAnimator *) node)->keyType; - return GF_OK; - case 5: - info->name = "keySpline"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((M_PositionAnimator *) node)->keySpline; - return GF_OK; - case 6: - info->name = "keyValue"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((M_PositionAnimator *) node)->keyValue; - return GF_OK; - case 7: - info->name = "keyValueType"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_PositionAnimator *) node)->keyValueType; - return GF_OK; - case 8: - info->name = "offset"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_PositionAnimator *) node)->offset; + info->name = "depth"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_SimpleTextureV2 *)node)->depth; return GF_OK; - case 9: - info->name = "weight"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PositionAnimator *) node)->weight; + case 1: + info->name = "normal"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_SimpleTextureV2 *)node)->normal; return GF_OK; - case 10: - info->name = "endValue"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_PositionAnimator *) node)->endValue; + case 2: + info->name = "splatU"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_SimpleTextureV2 *)node)->splatU; return GF_OK; - case 11: - info->name = "rotation_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFROTATION; - info->far_ptr = & ((M_PositionAnimator *) node)->rotation_changed; + case 3: + info->name = "splatV"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_SimpleTextureV2 *)node)->splatV; return GF_OK; - case 12: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((M_PositionAnimator *) node)->value_changed; + case 4: + info->name = "texture"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((M_SimpleTextureV2 *)node)->texture; return GF_OK; default: return GF_BAD_PARAM; @@ -16441,48 +33344,18 @@ static GF_Err PositionAnimator_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PositionAnimator_get_field_index_by_name(char *name) +static s32 SimpleTextureV2_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("fromTo", name)) return 1; - if (!strcmp("key", name)) return 2; - if (!strcmp("keyOrientation", name)) return 3; - if (!strcmp("keyType", name)) return 4; - if (!strcmp("keySpline", name)) return 5; - if (!strcmp("keyValue", name)) return 6; - if (!strcmp("keyValueType", name)) return 7; - if (!strcmp("offset", name)) return 8; - if (!strcmp("weight", name)) return 9; - if (!strcmp("endValue", name)) return 10; - if (!strcmp("rotation_changed", name)) return 11; - if (!strcmp("value_changed", name)) return 12; + if (!strcmp("depth", name)) return 0; + if (!strcmp("normal", name)) return 1; + if (!strcmp("splatU", name)) return 2; + if (!strcmp("splatV", name)) return 3; + if (!strcmp("texture", name)) return 4; return -1; } -static Bool PositionAnimator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SimpleTextureV2_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 0; - *QType = 8; - return 1; - case 2: - *AType = 0; - *QType = 8; - return 1; - case 5: - *AType = 0; - *QType = 8; - return 1; - case 6: - *AType = 0; - *QType = 4; - return 1; - case 8: - *AType = 0; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -16490,158 +33363,110 @@ static Bool PositionAnimator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *PositionAnimator_Create() +GF_Node *SimpleTextureV2_Create() { - M_PositionAnimator *p; - GF_SAFEALLOC(p, M_PositionAnimator); + M_SimpleTextureV2 *p; + GF_SAFEALLOC(p, M_SimpleTextureV2); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionAnimator); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SimpleTextureV2); /*default field values*/ - p->fromTo.x = FLT2FIX(0); - p->fromTo.y = FLT2FIX(1); - p->keyType = 0; - p->keySpline.vals = (SFVec2f*)malloc(sizeof(SFVec2f)*2); - p->keySpline.count = 2; - p->keySpline.vals[0].x = FLT2FIX(0); - p->keySpline.vals[0].y = FLT2FIX(0); - p->keySpline.vals[1].x = FLT2FIX(1); - p->keySpline.vals[1].y = FLT2FIX(1); - p->keyValueType = 0; - p->offset.x = FLT2FIX(0); - p->offset.y = FLT2FIX(0); - p->offset.z = FLT2FIX(0); return (GF_Node *)p; } /* - PositionAnimator2D Node deletion + SurroundingSound Node deletion */ -static void PositionAnimator2D_Del(GF_Node *node) +static void SurroundingSound_Del(GF_Node *node) { - M_PositionAnimator2D *p = (M_PositionAnimator2D *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfvec2f_del(p->keySpline); - gf_sg_mfvec2f_del(p->keyValue); - gf_sg_mffloat_del(p->weight); + M_SurroundingSound *p = (M_SurroundingSound *) node; + gf_node_unregister((GF_Node *) p->source, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 PositionAnimator2D_Def2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 PositionAnimator2D_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 PositionAnimator2D_Out2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 SurroundingSound_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 SurroundingSound_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 SurroundingSound_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 SurroundingSound_Dyn2All[] = { 1, 3, 5}; -static u32 PositionAnimator2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 SurroundingSound_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 10; - case GF_SG_FIELD_CODING_DEF: return 9; - case GF_SG_FIELD_CODING_OUT: return 12; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 7; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 3; default: - return 13; + return 7; } } -static GF_Err PositionAnimator2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err SurroundingSound_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PositionAnimator2D_In2All[inField]; + *allField = SurroundingSound_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PositionAnimator2D_Def2All[inField]; + *allField = SurroundingSound_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PositionAnimator2D_Out2All[inField]; + *allField = SurroundingSound_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = SurroundingSound_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PositionAnimator2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err SurroundingSound_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_fraction"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_PositionAnimator2D *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PositionAnimator2D *) node)->set_fraction; + info->name = "source"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_SurroundingSound *)node)->source; return GF_OK; case 1: - info->name = "fromTo"; + info->name = "intensity"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PositionAnimator2D *) node)->fromTo; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SurroundingSound *) node)->intensity; return GF_OK; case 2: - info->name = "key"; + info->name = "distance"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PositionAnimator2D *) node)->key; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SurroundingSound *) node)->distance; return GF_OK; case 3: - info->name = "keyOrientation"; + info->name = "location"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_PositionAnimator2D *) node)->keyOrientation; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_SurroundingSound *) node)->location; return GF_OK; case 4: - info->name = "keyType"; + info->name = "distortionFactor"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_PositionAnimator2D *) node)->keyType; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_SurroundingSound *) node)->distortionFactor; return GF_OK; case 5: - info->name = "keySpline"; + info->name = "orientation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((M_PositionAnimator2D *) node)->keySpline; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_SurroundingSound *) node)->orientation; return GF_OK; case 6: - info->name = "keyValue"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((M_PositionAnimator2D *) node)->keyValue; - return GF_OK; - case 7: - info->name = "keyValueType"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_PositionAnimator2D *) node)->keyValueType; - return GF_OK; - case 8: - info->name = "offset"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PositionAnimator2D *) node)->offset; - return GF_OK; - case 9: - info->name = "weight"; + info->name = "isTransformable"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PositionAnimator2D *) node)->weight; - return GF_OK; - case 10: - info->name = "endValue"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PositionAnimator2D *) node)->endValue; - return GF_OK; - case 11: - info->name = "rotation_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PositionAnimator2D *) node)->rotation_changed; - return GF_OK; - case 12: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_PositionAnimator2D *) node)->value_changed; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_SurroundingSound *) node)->isTransformable; return GF_OK; default: return GF_BAD_PARAM; @@ -16649,45 +33474,41 @@ static GF_Err PositionAnimator2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PositionAnimator2D_get_field_index_by_name(char *name) +static s32 SurroundingSound_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("fromTo", name)) return 1; - if (!strcmp("key", name)) return 2; - if (!strcmp("keyOrientation", name)) return 3; - if (!strcmp("keyType", name)) return 4; - if (!strcmp("keySpline", name)) return 5; - if (!strcmp("keyValue", name)) return 6; - if (!strcmp("keyValueType", name)) return 7; - if (!strcmp("offset", name)) return 8; - if (!strcmp("weight", name)) return 9; - if (!strcmp("endValue", name)) return 10; - if (!strcmp("rotation_changed", name)) return 11; - if (!strcmp("value_changed", name)) return 12; + if (!strcmp("source", name)) return 0; + if (!strcmp("intensity", name)) return 1; + if (!strcmp("distance", name)) return 2; + if (!strcmp("location", name)) return 3; + if (!strcmp("distortionFactor", name)) return 4; + if (!strcmp("orientation", name)) return 5; + if (!strcmp("isTransformable", name)) return 6; return -1; } -static Bool PositionAnimator2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SurroundingSound_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { case 1: - *AType = 0; - *QType = 8; + *AType = 7; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); return 1; case 2: *AType = 0; - *QType = 8; - return 1; - case 5: - *AType = 0; - *QType = 8; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; return 1; - case 6: - *AType = 0; - *QType = 4; + case 3: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; return 1; - case 8: - *AType = 0; - *QType = 2; + case 5: + *AType = 10; + *QType = 10; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; @@ -16698,102 +33519,137 @@ static Bool PositionAnimator2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType -GF_Node *PositionAnimator2D_Create() +GF_Node *SurroundingSound_Create() { - M_PositionAnimator2D *p; - GF_SAFEALLOC(p, M_PositionAnimator2D); + M_SurroundingSound *p; + GF_SAFEALLOC(p, M_SurroundingSound); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionAnimator2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SurroundingSound); /*default field values*/ - p->fromTo.x = FLT2FIX(0); - p->fromTo.y = FLT2FIX(1); - p->keyOrientation = 0; - p->keyType = 0; - p->keySpline.vals = (SFVec2f*)malloc(sizeof(SFVec2f)*2); - p->keySpline.count = 2; - p->keySpline.vals[0].x = FLT2FIX(0); - p->keySpline.vals[0].y = FLT2FIX(0); - p->keySpline.vals[1].x = FLT2FIX(1); - p->keySpline.vals[1].y = FLT2FIX(1); - p->keyValueType = 0; - p->offset.x = FLT2FIX(0); - p->offset.y = FLT2FIX(0); + p->intensity = FLT2FIX(1.0); + p->distance = FLT2FIX(0.0); + p->location.x = FLT2FIX(0.0); + p->location.y = FLT2FIX(0.0); + p->location.z = FLT2FIX(0.0); + p->distortionFactor = FLT2FIX(0.0); + p->orientation.x = FLT2FIX(0.0); + p->orientation.y = FLT2FIX(0.0); + p->orientation.z = FLT2FIX(1.0); + p->orientation.q = FLT2FIX(0.0); + p->isTransformable = 1; return (GF_Node *)p; } /* - PositionInterpolator4D Node deletion + Transform3DAudio Node deletion */ -static void PositionInterpolator4D_Del(GF_Node *node) +static void Transform3DAudio_Del(GF_Node *node) { - M_PositionInterpolator4D *p = (M_PositionInterpolator4D *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfvec4f_del(p->keyValue); + M_Transform3DAudio *p = (M_Transform3DAudio *) node; + gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 PositionInterpolator4D_Def2All[] = { 1, 2}; -static const u16 PositionInterpolator4D_In2All[] = { 0, 1, 2}; -static const u16 PositionInterpolator4D_Out2All[] = { 1, 2, 3}; +static const u16 Transform3DAudio_Def2All[] = { 2, 3, 4, 5, 6, 7, 8}; +static const u16 Transform3DAudio_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 Transform3DAudio_Out2All[] = { 2, 3, 4, 5, 6, 7, 8}; +static const u16 Transform3DAudio_Dyn2All[] = { 3, 4, 5, 6, 7}; -static u32 PositionInterpolator4D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Transform3DAudio_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 2; - case GF_SG_FIELD_CODING_OUT: return 3; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 9; + case GF_SG_FIELD_CODING_DEF: return 7; + case GF_SG_FIELD_CODING_OUT: return 7; + case GF_SG_FIELD_CODING_DYN: return 5; default: - return 4; + return 9; } } -static GF_Err PositionInterpolator4D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Transform3DAudio_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PositionInterpolator4D_In2All[inField]; + *allField = Transform3DAudio_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PositionInterpolator4D_Def2All[inField]; + *allField = Transform3DAudio_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PositionInterpolator4D_Out2All[inField]; + *allField = Transform3DAudio_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = Transform3DAudio_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PositionInterpolator4D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Transform3DAudio_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_fraction"; + info->name = "addChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_PositionInterpolator4D *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PositionInterpolator4D *) node)->set_fraction; + info->on_event_in = ((M_Transform3DAudio *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Transform3DAudio *)node)->addChildren; return GF_OK; case 1: - info->name = "key"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_PositionInterpolator4D *) node)->key; + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Transform3DAudio *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Transform3DAudio *)node)->removeChildren; return GF_OK; case 2: - info->name = "keyValue"; + info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC4F; - info->far_ptr = & ((M_PositionInterpolator4D *) node)->keyValue; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Transform3DAudio *)node)->children; return GF_OK; case 3: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFVEC4F; - info->far_ptr = & ((M_PositionInterpolator4D *) node)->value_changed; + info->name = "thirdCenterCoordinate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Transform3DAudio *) node)->thirdCenterCoordinate; + return GF_OK; + case 4: + info->name = "rotationVector"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Transform3DAudio *) node)->rotationVector; + return GF_OK; + case 5: + info->name = "thirdScaleCoordinate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Transform3DAudio *) node)->thirdScaleCoordinate; + return GF_OK; + case 6: + info->name = "scaleOrientationVector"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_Transform3DAudio *) node)->scaleOrientationVector; + return GF_OK; + case 7: + info->name = "thirdTranslationCoordinate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_Transform3DAudio *) node)->thirdTranslationCoordinate; + return GF_OK; + case 8: + info->name = "coordinateTransform"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((M_Transform3DAudio *) node)->coordinateTransform; return GF_OK; default: return GF_BAD_PARAM; @@ -16801,29 +33657,58 @@ static GF_Err PositionInterpolator4D_get_field(GF_Node *node, GF_FieldInfo *info } -static s32 PositionInterpolator4D_get_field_index_by_name(char *name) +static s32 Transform3DAudio_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("key", name)) return 1; - if (!strcmp("keyValue", name)) return 2; - if (!strcmp("value_changed", name)) return 3; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("thirdCenterCoordinate", name)) return 3; + if (!strcmp("rotationVector", name)) return 4; + if (!strcmp("thirdScaleCoordinate", name)) return 5; + if (!strcmp("scaleOrientationVector", name)) return 6; + if (!strcmp("thirdTranslationCoordinate", name)) return 7; + if (!strcmp("coordinateTransform", name)) return 8; return -1; } -static Bool PositionInterpolator4D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool Transform3DAudio_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 0; - *QType = 8; + case 3: + *AType = 7; + *QType = 0; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 4: + *AType = 11; + *QType = 7; + *b_min = FLT2FIX(-3.14159265); + *b_max = FLT2FIX(3.14159265); + return 1; + case 5: + *AType = 7; + *QType = 0; *b_min = FLT2FIX(0); + *b_max = FIX_MAX; + return 1; + case 6: + *AType = 11; + *QType = 7; + *b_min = FLT2FIX(-1); *b_max = FLT2FIX(1); return 1; - case 2: - *AType = 0; - *QType = 15; + case 7: + *AType = 7; + *QType = 0; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; + case 8: + *AType = 0; + *QType = 10; + *b_min = FLT2FIX(-3.14159265); + *b_max = FLT2FIX(3.14159265); + return 1; default: return 0; } @@ -16831,133 +33716,175 @@ static Bool PositionInterpolator4D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *Q -GF_Node *PositionInterpolator4D_Create() +GF_Node *Transform3DAudio_Create() { - M_PositionInterpolator4D *p; - GF_SAFEALLOC(p, M_PositionInterpolator4D); + M_Transform3DAudio *p; + GF_SAFEALLOC(p, M_Transform3DAudio); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PositionInterpolator4D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Transform3DAudio); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ + p->thirdCenterCoordinate = FLT2FIX(0.0); + p->rotationVector.x = FLT2FIX(0.0); + p->rotationVector.y = FLT2FIX(0.0); + p->rotationVector.z = FLT2FIX(1.0); + p->thirdScaleCoordinate = FLT2FIX(0.0); + p->scaleOrientationVector.x = FLT2FIX(0.0); + p->scaleOrientationVector.y = FLT2FIX(0.0); + p->scaleOrientationVector.z = FLT2FIX(1.0); + p->thirdTranslationCoordinate = FLT2FIX(0.0); + p->coordinateTransform.x = FLT2FIX(1.0); + p->coordinateTransform.y = FLT2FIX(0.0); + p->coordinateTransform.z = FLT2FIX(0.0); + p->coordinateTransform.q = FLT2FIX(-1.5707963); return (GF_Node *)p; } /* - ScalarAnimator Node deletion + WideSound Node deletion */ -static void ScalarAnimator_Del(GF_Node *node) +static void WideSound_Del(GF_Node *node) { - M_ScalarAnimator *p = (M_ScalarAnimator *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfvec2f_del(p->keySpline); - gf_sg_mffloat_del(p->keyValue); - gf_sg_mffloat_del(p->weight); + M_WideSound *p = (M_WideSound *) node; + gf_node_unregister((GF_Node *) p->source, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->perceptualParameters, (GF_Node *) p); + gf_sg_mffloat_del(p->size); gf_node_free((GF_Node *) p); } -static const u16 ScalarAnimator_Def2All[] = { 1, 2, 3, 4, 5, 6, 7, 8}; -static const u16 ScalarAnimator_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; -static const u16 ScalarAnimator_Out2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +static const u16 WideSound_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; +static const u16 WideSound_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; +static const u16 WideSound_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; +static const u16 WideSound_Dyn2All[] = { 1, 2, 8}; -static u32 ScalarAnimator_get_field_count(GF_Node *node, u8 IndexMode) +static u32 WideSound_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 9; - case GF_SG_FIELD_CODING_DEF: return 8; - case GF_SG_FIELD_CODING_OUT: return 10; - case GF_SG_FIELD_CODING_DYN: return 0; + case GF_SG_FIELD_CODING_IN: return 12; + case GF_SG_FIELD_CODING_DEF: return 15; + case GF_SG_FIELD_CODING_OUT: return 12; + case GF_SG_FIELD_CODING_DYN: return 3; default: - return 11; + return 15; } } -static GF_Err ScalarAnimator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err WideSound_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = ScalarAnimator_In2All[inField]; + *allField = WideSound_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = ScalarAnimator_Def2All[inField]; + *allField = WideSound_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = ScalarAnimator_Out2All[inField]; + *allField = WideSound_Out2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DYN: + *allField = WideSound_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err ScalarAnimator_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err WideSound_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_fraction"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_ScalarAnimator *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ScalarAnimator *) node)->set_fraction; + info->name = "source"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFAudioNode; + info->far_ptr = & ((M_WideSound *)node)->source; return GF_OK; case 1: - info->name = "fromTo"; + info->name = "intensity"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_ScalarAnimator *) node)->fromTo; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_WideSound *) node)->intensity; return GF_OK; case 2: - info->name = "key"; + info->name = "location"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_ScalarAnimator *) node)->key; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_WideSound *) node)->location; return GF_OK; case 3: - info->name = "keyType"; + info->name = "spatialize"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_ScalarAnimator *) node)->keyType; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_WideSound *) node)->spatialize; return GF_OK; case 4: - info->name = "keySpline"; + info->name = "perceptualParameters"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((M_ScalarAnimator *) node)->keySpline; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFPerceptualParameterNode; + info->far_ptr = & ((M_WideSound *)node)->perceptualParameters; return GF_OK; case 5: - info->name = "keyValue"; + info->name = "roomEffect"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_ScalarAnimator *) node)->keyValue; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_WideSound *) node)->roomEffect; return GF_OK; case 6: - info->name = "keyValueType"; + info->name = "shape"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_ScalarAnimator *) node)->keyValueType; + info->far_ptr = & ((M_WideSound *) node)->shape; return GF_OK; case 7: - info->name = "offset"; + info->name = "size"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ScalarAnimator *) node)->offset; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_WideSound *) node)->size; return GF_OK; case 8: - info->name = "weight"; + info->name = "direction"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_ScalarAnimator *) node)->weight; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_WideSound *) node)->direction; return GF_OK; case 9: - info->name = "endValue"; - info->eventType = GF_SG_EVENT_OUT; + info->name = "density"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ScalarAnimator *) node)->endValue; + info->far_ptr = & ((M_WideSound *) node)->density; return GF_OK; case 10: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; + info->name = "diffuseSelect"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_WideSound *) node)->diffuseSelect; + return GF_OK; + case 11: + info->name = "decorrStrength"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ScalarAnimator *) node)->value_changed; + info->far_ptr = & ((M_WideSound *) node)->decorrStrength; + return GF_OK; + case 12: + info->name = "speedOfSound"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_WideSound *) node)->speedOfSound; + return GF_OK; + case 13: + info->name = "distance"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_WideSound *) node)->distance; + return GF_OK; + case 14: + info->name = "useAirabs"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_WideSound *) node)->useAirabs; return GF_OK; default: return GF_BAD_PARAM; @@ -16965,39 +33892,70 @@ static GF_Err ScalarAnimator_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 ScalarAnimator_get_field_index_by_name(char *name) +static s32 WideSound_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("fromTo", name)) return 1; - if (!strcmp("key", name)) return 2; - if (!strcmp("keyType", name)) return 3; - if (!strcmp("keySpline", name)) return 4; - if (!strcmp("keyValue", name)) return 5; - if (!strcmp("keyValueType", name)) return 6; - if (!strcmp("offset", name)) return 7; - if (!strcmp("weight", name)) return 8; - if (!strcmp("endValue", name)) return 9; - if (!strcmp("value_changed", name)) return 10; + if (!strcmp("source", name)) return 0; + if (!strcmp("intensity", name)) return 1; + if (!strcmp("location", name)) return 2; + if (!strcmp("spatialize", name)) return 3; + if (!strcmp("perceptualParameters", name)) return 4; + if (!strcmp("roomEffect", name)) return 5; + if (!strcmp("shape", name)) return 6; + if (!strcmp("size", name)) return 7; + if (!strcmp("direction", name)) return 8; + if (!strcmp("density", name)) return 9; + if (!strcmp("diffuseSelect", name)) return 10; + if (!strcmp("decorrStrength", name)) return 11; + if (!strcmp("speedOfSound", name)) return 12; + if (!strcmp("distance", name)) return 13; + if (!strcmp("useAirabs", name)) return 14; return -1; } -static Bool ScalarAnimator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool WideSound_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { case 1: + *AType = 7; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(1); + return 1; + case 2: + *AType = 1; + *QType = 1; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 6: *AType = 0; - *QType = 8; + *QType = 13; + *QT13_bits = 4; + *b_min = FLT2FIX(0); + *b_max = FLT2FIX(4); return 1; - case 2: + case 8: + *AType = 9; + *QType = 9; + *b_min = FIX_MIN; + *b_max = FIX_MAX; + return 1; + case 10: *AType = 0; - *QType = 8; + *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; return 1; - case 4: + case 12: *AType = 0; - *QType = 8; + *QType = 1; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; return 1; - case 5: + case 13: *AType = 0; *QType = 0; + *b_min = FLT2FIX(0); + *b_max = FIX_MAX; return 1; default: return 0; @@ -17006,125 +33964,95 @@ static Bool ScalarAnimator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *ScalarAnimator_Create() +GF_Node *WideSound_Create() { - M_ScalarAnimator *p; - GF_SAFEALLOC(p, M_ScalarAnimator); + M_WideSound *p; + GF_SAFEALLOC(p, M_WideSound); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_ScalarAnimator); + gf_node_setup((GF_Node *)p, TAG_MPEG4_WideSound); /*default field values*/ - p->fromTo.x = FLT2FIX(0); - p->fromTo.y = FLT2FIX(1); - p->keyType = 0; - p->keySpline.vals = (SFVec2f*)malloc(sizeof(SFVec2f)*2); - p->keySpline.count = 2; - p->keySpline.vals[0].x = FLT2FIX(0); - p->keySpline.vals[0].y = FLT2FIX(0); - p->keySpline.vals[1].x = FLT2FIX(1); - p->keySpline.vals[1].y = FLT2FIX(1); - p->keyValueType = 0; - p->offset = FLT2FIX(0); + p->intensity = FLT2FIX(1); + p->location.x = FLT2FIX(0.0); + p->location.y = FLT2FIX(0.0); + p->location.z = FLT2FIX(0.0); + p->spatialize = 1; + p->shape = 0; + p->size.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->size.count = 1; + p->size.vals[0] = FLT2FIX(0.0); + p->direction.x = FLT2FIX(0.0); + p->direction.y = FLT2FIX(1.0); + p->direction.z = FLT2FIX(0.0); + p->density = FLT2FIX(0.5); + p->diffuseSelect = 1; + p->decorrStrength = FLT2FIX(1.0); + p->speedOfSound = FLT2FIX(340.0); + p->distance = FLT2FIX(1000.0); return (GF_Node *)p; } /* - Clipper2D Node deletion + ScoreShape Node deletion */ -static void Clipper2D_Del(GF_Node *node) +static void ScoreShape_Del(GF_Node *node) { - M_Clipper2D *p = (M_Clipper2D *) node; + M_ScoreShape *p = (M_ScoreShape *) node; + gf_node_unregister((GF_Node *) p->score, (GF_Node *) p); gf_node_unregister((GF_Node *) p->geometry, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->transform, (GF_Node *) p); - gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Clipper2D_Def2All[] = { 2, 3, 4, 5, 6}; -static const u16 Clipper2D_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 Clipper2D_Out2All[] = { 2, 3, 4, 5, 6}; +static const u16 ScoreShape_Def2All[] = { 0, 1}; +static const u16 ScoreShape_In2All[] = { 0, 1}; +static const u16 ScoreShape_Out2All[] = { 0, 1}; -static u32 Clipper2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 ScoreShape_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 7; - case GF_SG_FIELD_CODING_DEF: return 5; - case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 7; + return 2; } } -static GF_Err Clipper2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err ScoreShape_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Clipper2D_In2All[inField]; + *allField = ScoreShape_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Clipper2D_Def2All[inField]; + *allField = ScoreShape_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Clipper2D_Out2All[inField]; + *allField = ScoreShape_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Clipper2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err ScoreShape_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Clipper2D *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Clipper2D *)node)->addChildren; - return GF_OK; - case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Clipper2D *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Clipper2D *)node)->removeChildren; - return GF_OK; - case 2: - info->name = "children"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Clipper2D *)node)->children; - return GF_OK; - case 3: - info->name = "geometry"; + info->name = "score"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFGeometryNode; - info->far_ptr = & ((M_Clipper2D *)node)->geometry; - return GF_OK; - case 4: - info->name = "inside"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Clipper2D *) node)->inside; + info->NDTtype = NDT_SFMusicScoreNode; + info->far_ptr = & ((M_ScoreShape *)node)->score; return GF_OK; - case 5: - info->name = "transform"; + case 1: + info->name = "geometry"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_Clipper2D *)node)->transform; - return GF_OK; - case 6: - info->name = "XOR"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Clipper2D *) node)->XOR; + info->far_ptr = & ((M_ScoreShape *)node)->geometry; return GF_OK; default: return GF_BAD_PARAM; @@ -17132,18 +34060,13 @@ static GF_Err Clipper2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Clipper2D_get_field_index_by_name(char *name) +static s32 ScoreShape_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; - if (!strcmp("geometry", name)) return 3; - if (!strcmp("inside", name)) return 4; - if (!strcmp("transform", name)) return 5; - if (!strcmp("XOR", name)) return 6; + if (!strcmp("score", name)) return 0; + if (!strcmp("geometry", name)) return 1; return -1; } -static Bool Clipper2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool ScoreShape_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { default: @@ -17153,212 +34076,271 @@ static Bool Clipper2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATy -GF_Node *Clipper2D_Create() +GF_Node *ScoreShape_Create() { - M_Clipper2D *p; - GF_SAFEALLOC(p, M_Clipper2D); + M_ScoreShape *p; + GF_SAFEALLOC(p, M_ScoreShape); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Clipper2D); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_MPEG4_ScoreShape); /*default field values*/ - p->inside = 1; return (GF_Node *)p; } /* - ColorTransform Node deletion + MusicScore Node deletion */ -static void ColorTransform_Del(GF_Node *node) +static void MusicScore_Del(GF_Node *node) { - M_ColorTransform *p = (M_ColorTransform *) node; - gf_sg_vrml_parent_destroy((GF_Node *) p); + M_MusicScore *p = (M_MusicScore *) node; + gf_sg_sfstring_del(p->gotoLabel); + gf_sg_mfstring_del(p->argumentsOnExecute); + gf_sg_sfstring_del(p->commandOnExecute); + gf_sg_mfstring_del(p->partsLyrics); + gf_sg_mfint32_del(p->partsShown); + gf_sg_mfurl_del(p->url); + gf_sg_mfurl_del(p->urlSA); + gf_sg_sfstring_del(p->viewType); + gf_sg_sfstring_del(p->activatedLink); + gf_sg_mfstring_del(p->availableCommands); + gf_sg_mfstring_del(p->availableLabels); + gf_sg_mfstring_del(p->availableLyricLanguages); + gf_sg_mfstring_del(p->availableViewTypes); + gf_sg_mfstring_del(p->partNames); gf_node_free((GF_Node *) p); } -static const u16 ColorTransform_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}; -static const u16 ColorTransform_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}; -static const u16 ColorTransform_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}; -static const u16 ColorTransform_Dyn2All[] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}; +static const u16 MusicScore_Def2All[] = { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; +static const u16 MusicScore_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; +static const u16 MusicScore_Out2All[] = { 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}; +static const u16 MusicScore_Dyn2All[] = { 14}; -static u32 ColorTransform_get_field_count(GF_Node *node, u8 IndexMode) +static u32 MusicScore_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 23; - case GF_SG_FIELD_CODING_DEF: return 21; - case GF_SG_FIELD_CODING_OUT: return 21; - case GF_SG_FIELD_CODING_DYN: return 20; + case GF_SG_FIELD_CODING_IN: return 21; + case GF_SG_FIELD_CODING_DEF: return 16; + case GF_SG_FIELD_CODING_OUT: return 26; + case GF_SG_FIELD_CODING_DYN: return 1; default: - return 23; + return 31; } } -static GF_Err ColorTransform_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err MusicScore_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = ColorTransform_In2All[inField]; + *allField = MusicScore_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = ColorTransform_Def2All[inField]; + *allField = MusicScore_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = ColorTransform_Out2All[inField]; + *allField = MusicScore_Out2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DYN: - *allField = ColorTransform_Dyn2All[inField]; + *allField = MusicScore_Dyn2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err ColorTransform_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MusicScore_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; + info->name = "executeCommand"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_ColorTransform *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_ColorTransform *)node)->addChildren; + info->on_event_in = ((M_MusicScore *)node)->on_executeCommand; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MusicScore *) node)->executeCommand; return GF_OK; case 1: - info->name = "removeChildren"; + info->name = "gotoLabel"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_ColorTransform *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_ColorTransform *)node)->removeChildren; + info->on_event_in = ((M_MusicScore *)node)->on_gotoLabel; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->gotoLabel; return GF_OK; case 2: - info->name = "children"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_ColorTransform *)node)->children; + info->name = "gotoMeasure"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_MusicScore *)node)->on_gotoMeasure; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_MusicScore *) node)->gotoMeasure; return GF_OK; case 3: - info->name = "mrr"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mrr; + info->name = "highlightTimePosition"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_MusicScore *)node)->on_highlightTimePosition; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MusicScore *) node)->highlightTimePosition; return GF_OK; case 4: - info->name = "mrg"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mrg; + info->name = "mousePosition"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_MusicScore *)node)->on_mousePosition; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_MusicScore *) node)->mousePosition; return GF_OK; case 5: - info->name = "mrb"; + info->name = "argumentsOnExecute"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mrb; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->argumentsOnExecute; return GF_OK; case 6: - info->name = "mra"; + info->name = "commandOnExecute"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mra; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->commandOnExecute; return GF_OK; case 7: - info->name = "tr"; + info->name = "firstVisibleMeasure"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->tr; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_MusicScore *) node)->firstVisibleMeasure; return GF_OK; case 8: - info->name = "mgr"; + info->name = "hyperlinkEnable"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mgr; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MusicScore *) node)->hyperlinkEnable; return GF_OK; case 9: - info->name = "mgg"; + info->name = "loop"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mgg; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MusicScore *) node)->loop; return GF_OK; case 10: - info->name = "mgb"; + info->name = "partsLyrics"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mgb; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->partsLyrics; return GF_OK; case 11: - info->name = "mga"; + info->name = "partsShown"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mga; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_MusicScore *) node)->partsShown; return GF_OK; case 12: - info->name = "tg"; + info->name = "scoreOffset"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->tg; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MusicScore *) node)->scoreOffset; return GF_OK; case 13: - info->name = "mbr"; + info->name = "size"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mbr; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((M_MusicScore *) node)->size; return GF_OK; case 14: - info->name = "mbg"; + info->name = "speed"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mbg; + info->far_ptr = & ((M_MusicScore *) node)->speed; return GF_OK; case 15: - info->name = "mbb"; + info->name = "startTime"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mbb; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MusicScore *) node)->startTime; return GF_OK; case 16: - info->name = "mba"; + info->name = "stopTime"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mba; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((M_MusicScore *) node)->stopTime; return GF_OK; case 17: - info->name = "tb"; + info->name = "transpose"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->tb; + info->far_ptr = & ((M_MusicScore *) node)->transpose; + return GF_OK; + case 18: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_MusicScore *) node)->url; + return GF_OK; + case 19: + info->name = "urlSA"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_MusicScore *) node)->urlSA; + return GF_OK; + case 20: + info->name = "viewType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->viewType; + return GF_OK; + case 21: + info->name = "activatedLink"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->activatedLink; + return GF_OK; + case 22: + info->name = "availableCommands"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->availableCommands; + return GF_OK; + case 23: + info->name = "availableLabels"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->availableLabels; + return GF_OK; + case 24: + info->name = "availableLyricLanguages"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->availableLyricLanguages; return GF_OK; - case 18: - info->name = "mar"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mar; + case 25: + info->name = "availableViewTypes"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->availableViewTypes; return GF_OK; - case 19: - info->name = "mag"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mag; + case 26: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_MusicScore *) node)->isActive; return GF_OK; - case 20: - info->name = "mab"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->mab; + case 27: + info->name = "highlightPosition"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((M_MusicScore *) node)->highlightPosition; return GF_OK; - case 21: - info->name = "maa"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->maa; + case 28: + info->name = "lastVisibleMeasure"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_MusicScore *) node)->lastVisibleMeasure; return GF_OK; - case 22: - info->name = "ta"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_ColorTransform *) node)->ta; + case 29: + info->name = "numMeasures"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_MusicScore *) node)->numMeasures; + return GF_OK; + case 30: + info->name = "partNames"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((M_MusicScore *) node)->partNames; return GF_OK; default: return GF_BAD_PARAM; @@ -17366,156 +34348,145 @@ static GF_Err ColorTransform_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 ColorTransform_get_field_index_by_name(char *name) -{ - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; - if (!strcmp("mrr", name)) return 3; - if (!strcmp("mrg", name)) return 4; - if (!strcmp("mrb", name)) return 5; - if (!strcmp("mra", name)) return 6; - if (!strcmp("tr", name)) return 7; - if (!strcmp("mgr", name)) return 8; - if (!strcmp("mgg", name)) return 9; - if (!strcmp("mgb", name)) return 10; - if (!strcmp("mga", name)) return 11; - if (!strcmp("tg", name)) return 12; - if (!strcmp("mbr", name)) return 13; - if (!strcmp("mbg", name)) return 14; - if (!strcmp("mbb", name)) return 15; - if (!strcmp("mba", name)) return 16; - if (!strcmp("tb", name)) return 17; - if (!strcmp("mar", name)) return 18; - if (!strcmp("mag", name)) return 19; - if (!strcmp("mab", name)) return 20; - if (!strcmp("maa", name)) return 21; - if (!strcmp("ta", name)) return 22; +static s32 MusicScore_get_field_index_by_name(char *name) +{ + if (!strcmp("executeCommand", name)) return 0; + if (!strcmp("gotoLabel", name)) return 1; + if (!strcmp("gotoMeasure", name)) return 2; + if (!strcmp("highlightTimePosition", name)) return 3; + if (!strcmp("mousePosition", name)) return 4; + if (!strcmp("argumentsOnExecute", name)) return 5; + if (!strcmp("commandOnExecute", name)) return 6; + if (!strcmp("firstVisibleMeasure", name)) return 7; + if (!strcmp("hyperlinkEnable", name)) return 8; + if (!strcmp("loop", name)) return 9; + if (!strcmp("partsLyrics", name)) return 10; + if (!strcmp("partsShown", name)) return 11; + if (!strcmp("scoreOffset", name)) return 12; + if (!strcmp("size", name)) return 13; + if (!strcmp("speed", name)) return 14; + if (!strcmp("startTime", name)) return 15; + if (!strcmp("stopTime", name)) return 16; + if (!strcmp("transpose", name)) return 17; + if (!strcmp("url", name)) return 18; + if (!strcmp("urlSA", name)) return 19; + if (!strcmp("viewType", name)) return 20; + if (!strcmp("activatedLink", name)) return 21; + if (!strcmp("availableCommands", name)) return 22; + if (!strcmp("availableLabels", name)) return 23; + if (!strcmp("availableLyricLanguages", name)) return 24; + if (!strcmp("availableViewTypes", name)) return 25; + if (!strcmp("isActive", name)) return 26; + if (!strcmp("highlightPosition", name)) return 27; + if (!strcmp("lastVisibleMeasure", name)) return 28; + if (!strcmp("numMeasures", name)) return 29; + if (!strcmp("partNames", name)) return 30; return -1; } -static Bool ColorTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool MusicScore_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 3: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 4: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 5: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 6: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 7: - *AType = 7; - *QType = 4; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 8: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 9: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 10: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 11: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 12: - *AType = 7; - *QType = 4; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 13: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; case 14: *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 15: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 16: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 17: - *AType = 7; - *QType = 4; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 18: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 19: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 20: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 21: - *AType = 7; - *QType = 7; + *QType = 0; *b_min = FIX_MIN; *b_max = FIX_MAX; return 1; - case 22: - *AType = 7; - *QType = 4; - *b_min = FIX_MIN; - *b_max = FIX_MAX; + default: + return 0; + } +} + + + +GF_Node *MusicScore_Create() +{ + M_MusicScore *p; + GF_SAFEALLOC(p, M_MusicScore); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_MusicScore); + + /*default field values*/ + p->firstVisibleMeasure = 0; + p->hyperlinkEnable = 1; + p->scoreOffset = 0.0; + p->size.x = FLT2FIX(-1); + p->size.y = FLT2FIX(-1); + p->speed = FLT2FIX(1.0); + p->startTime = 0; + p->stopTime = 0; + p->transpose = FLT2FIX(0.0); + return (GF_Node *)p; +} + + +/* + FootPrintSetNode Node deletion +*/ + +static void FootPrintSetNode_Del(GF_Node *node) +{ + M_FootPrintSetNode *p = (M_FootPrintSetNode *) node; + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 FootPrintSetNode_Def2All[] = { 0}; +static const u16 FootPrintSetNode_In2All[] = { 0}; +static const u16 FootPrintSetNode_Out2All[] = { 0}; + +static u32 FootPrintSetNode_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 1; + case GF_SG_FIELD_CODING_DEF: return 1; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 0; + default: return 1; + } +} + +static GF_Err FootPrintSetNode_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = FootPrintSetNode_In2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_DEF: + *allField = FootPrintSetNode_Def2All[inField]; + return GF_OK; + case GF_SG_FIELD_CODING_OUT: + *allField = FootPrintSetNode_Out2All[inField]; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} +static GF_Err FootPrintSetNode_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_FootPrintSetNode *)node)->children; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 FootPrintSetNode_get_field_index_by_name(char *name) +{ + if (!strcmp("children", name)) return 0; + return -1; + } +static Bool FootPrintSetNode_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { default: return 0; } @@ -17523,93 +34494,77 @@ static Bool ColorTransform_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *ColorTransform_Create() +GF_Node *FootPrintSetNode_Create() { - M_ColorTransform *p; - GF_SAFEALLOC(p, M_ColorTransform); + M_FootPrintSetNode *p; + GF_SAFEALLOC(p, M_FootPrintSetNode); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_ColorTransform); + gf_node_setup((GF_Node *)p, TAG_MPEG4_FootPrintSetNode); gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->mrr = FLT2FIX(1); - p->mrg = FLT2FIX(0); - p->mrb = FLT2FIX(0); - p->mra = FLT2FIX(0); - p->tr = FLT2FIX(0); - p->mgr = FLT2FIX(0); - p->mgg = FLT2FIX(1); - p->mgb = FLT2FIX(0); - p->mga = FLT2FIX(0); - p->tg = FLT2FIX(0); - p->mbr = FLT2FIX(0); - p->mbg = FLT2FIX(0); - p->mbb = FLT2FIX(1); - p->mba = FLT2FIX(0); - p->tb = FLT2FIX(0); - p->mar = FLT2FIX(0); - p->mag = FLT2FIX(0); - p->mab = FLT2FIX(0); - p->maa = FLT2FIX(1); - p->ta = FLT2FIX(0); return (GF_Node *)p; } /* - Ellipse Node deletion + FootPrintNode Node deletion */ -static void Ellipse_Del(GF_Node *node) +static void FootPrintNode_Del(GF_Node *node) { - M_Ellipse *p = (M_Ellipse *) node; + M_FootPrintNode *p = (M_FootPrintNode *) node; + gf_node_unregister((GF_Node *) p->footprint, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 Ellipse_Def2All[] = { 0}; -static const u16 Ellipse_In2All[] = { 0}; -static const u16 Ellipse_Out2All[] = { 0}; -static const u16 Ellipse_Dyn2All[] = { 0}; +static const u16 FootPrintNode_Def2All[] = { 0, 1}; +static const u16 FootPrintNode_In2All[] = { 0, 1}; +static const u16 FootPrintNode_Out2All[] = { 0, 1}; -static u32 Ellipse_get_field_count(GF_Node *node, u8 IndexMode) +static u32 FootPrintNode_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 1; - case GF_SG_FIELD_CODING_DEF: return 1; - case GF_SG_FIELD_CODING_OUT: return 1; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_IN: return 2; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 1; + return 2; } } -static GF_Err Ellipse_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err FootPrintNode_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = Ellipse_In2All[inField]; + *allField = FootPrintNode_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Ellipse_Def2All[inField]; + *allField = FootPrintNode_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = Ellipse_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Ellipse_Dyn2All[inField]; + *allField = FootPrintNode_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Ellipse_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err FootPrintNode_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "radius"; + info->name = "index"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Ellipse *) node)->radius; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FootPrintNode *) node)->index; + return GF_OK; + case 1: + info->name = "footprint"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_FootPrintNode *)node)->footprint; return GF_OK; default: return GF_BAD_PARAM; @@ -17617,20 +34572,15 @@ static GF_Err Ellipse_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Ellipse_get_field_index_by_name(char *name) +static s32 FootPrintNode_get_field_index_by_name(char *name) { - if (!strcmp("radius", name)) return 0; + if (!strcmp("index", name)) return 0; + if (!strcmp("footprint", name)) return 1; return -1; } -static Bool Ellipse_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool FootPrintNode_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 2; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -17638,115 +34588,119 @@ static Bool Ellipse_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType -GF_Node *Ellipse_Create() +GF_Node *FootPrintNode_Create() { - M_Ellipse *p; - GF_SAFEALLOC(p, M_Ellipse); + M_FootPrintNode *p; + GF_SAFEALLOC(p, M_FootPrintNode); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Ellipse); + gf_node_setup((GF_Node *)p, TAG_MPEG4_FootPrintNode); /*default field values*/ - p->radius.x = FLT2FIX(1); - p->radius.y = FLT2FIX(1); + p->index = -1; return (GF_Node *)p; } /* - LinearGradient Node deletion + BuildingPartNode Node deletion */ -static void LinearGradient_Del(GF_Node *node) +static void BuildingPartNode_Del(GF_Node *node) { - M_LinearGradient *p = (M_LinearGradient *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfcolor_del(p->keyValue); - gf_sg_mffloat_del(p->opacity); - gf_node_unregister((GF_Node *) p->transform, (GF_Node *) p); + M_BuildingPartNode *p = (M_BuildingPartNode *) node; + gf_node_unregister((GF_Node *) p->footprint, (GF_Node *) p); + gf_node_unregister_children((GF_Node *) p, p->alternativeGeometry); + gf_node_unregister_children((GF_Node *) p, p->roofs); + gf_node_unregister_children((GF_Node *) p, p->facades); gf_node_free((GF_Node *) p); } -static const u16 LinearGradient_Def2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 LinearGradient_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 LinearGradient_Out2All[] = { 0, 1, 2, 3, 4, 5, 6}; -static const u16 LinearGradient_Dyn2All[] = { 0, 5}; +static const u16 BuildingPartNode_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 BuildingPartNode_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; +static const u16 BuildingPartNode_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static u32 LinearGradient_get_field_count(GF_Node *node, u8 IndexMode) +static u32 BuildingPartNode_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 7; - case GF_SG_FIELD_CODING_DEF: return 7; - case GF_SG_FIELD_CODING_OUT: return 7; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_IN: return 8; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 7; + return 8; } } -static GF_Err LinearGradient_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err BuildingPartNode_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = LinearGradient_In2All[inField]; + *allField = BuildingPartNode_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = LinearGradient_Def2All[inField]; + *allField = BuildingPartNode_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = LinearGradient_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = LinearGradient_Dyn2All[inField]; + *allField = BuildingPartNode_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err LinearGradient_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err BuildingPartNode_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "endPoint"; + info->name = "index"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_LinearGradient *) node)->endPoint; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BuildingPartNode *) node)->index; return GF_OK; case 1: - info->name = "key"; + info->name = "footprint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_LinearGradient *) node)->key; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_BuildingPartNode *)node)->footprint; return GF_OK; case 2: - info->name = "keyValue"; + info->name = "buildingIndex"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFCOLOR; - info->far_ptr = & ((M_LinearGradient *) node)->keyValue; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_BuildingPartNode *) node)->buildingIndex; return GF_OK; case 3: - info->name = "opacity"; + info->name = "height"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_LinearGradient *) node)->opacity; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_BuildingPartNode *) node)->height; return GF_OK; case 4: - info->name = "spreadMethod"; + info->name = "altitude"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_LinearGradient *) node)->spreadMethod; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_BuildingPartNode *) node)->altitude; return GF_OK; case 5: - info->name = "startPoint"; + info->name = "alternativeGeometry"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_LinearGradient *) node)->startPoint; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_BuildingPartNode *)node)->alternativeGeometry; return GF_OK; case 6: - info->name = "transform"; + info->name = "roofs"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_LinearGradient *)node)->transform; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_BuildingPartNode *)node)->roofs; + return GF_OK; + case 7: + info->name = "facades"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_BuildingPartNode *)node)->facades; return GF_OK; default: return GF_BAD_PARAM; @@ -17754,57 +34708,21 @@ static GF_Err LinearGradient_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 LinearGradient_get_field_index_by_name(char *name) +static s32 BuildingPartNode_get_field_index_by_name(char *name) { - if (!strcmp("endPoint", name)) return 0; - if (!strcmp("key", name)) return 1; - if (!strcmp("keyValue", name)) return 2; - if (!strcmp("opacity", name)) return 3; - if (!strcmp("spreadMethod", name)) return 4; - if (!strcmp("startPoint", name)) return 5; - if (!strcmp("transform", name)) return 6; + if (!strcmp("index", name)) return 0; + if (!strcmp("footprint", name)) return 1; + if (!strcmp("buildingIndex", name)) return 2; + if (!strcmp("height", name)) return 3; + if (!strcmp("altitude", name)) return 4; + if (!strcmp("alternativeGeometry", name)) return 5; + if (!strcmp("roofs", name)) return 6; + if (!strcmp("facades", name)) return 7; return -1; } -static Bool LinearGradient_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool BuildingPartNode_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 2; - *QType = 5; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 1: - *AType = 0; - *QType = 8; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 2: - *AType = 0; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 3: - *AType = 0; - *QType = 7; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 4: - *AType = 0; - *QType = 13; - *QT13_bits = 2; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(2); - return 1; - case 5: - *AType = 2; - *QType = 5; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -17812,143 +34730,140 @@ static Bool LinearGradient_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *LinearGradient_Create() +GF_Node *BuildingPartNode_Create() { - M_LinearGradient *p; - GF_SAFEALLOC(p, M_LinearGradient); + M_BuildingPartNode *p; + GF_SAFEALLOC(p, M_BuildingPartNode); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_LinearGradient); + gf_node_setup((GF_Node *)p, TAG_MPEG4_BuildingPartNode); /*default field values*/ - p->endPoint.x = FLT2FIX(1); - p->endPoint.y = FLT2FIX(0); - p->opacity.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->opacity.count = 1; - p->opacity.vals[0] = FLT2FIX(1); - p->spreadMethod = 0; - p->startPoint.x = FLT2FIX(0); - p->startPoint.y = FLT2FIX(0); + p->index = -1; + p->buildingIndex = -1; + p->height = FLT2FIX(0); + p->altitude = FLT2FIX(0); return (GF_Node *)p; } /* - PathLayout Node deletion + RoofNode Node deletion */ -static void PathLayout_Del(GF_Node *node) +static void RoofNode_Del(GF_Node *node) { - M_PathLayout *p = (M_PathLayout *) node; - gf_node_unregister((GF_Node *) p->geometry, (GF_Node *) p); - gf_sg_mfint32_del(p->alignment); - gf_sg_vrml_parent_destroy((GF_Node *) p); + M_RoofNode *p = (M_RoofNode *) node; + gf_sg_mffloat_del(p->SlopeAngle); + gf_sg_sfurl_del(p->RoofTextureURL); gf_node_free((GF_Node *) p); } -static const u16 PathLayout_Def2All[] = { 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 PathLayout_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 PathLayout_Out2All[] = { 2, 3, 4, 5, 6, 7, 8, 9}; -static const u16 PathLayout_Dyn2All[] = { 5, 6}; +static const u16 RoofNode_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; +static const u16 RoofNode_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; +static const u16 RoofNode_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}; -static u32 PathLayout_get_field_count(GF_Node *node, u8 IndexMode) +static u32 RoofNode_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 10; - case GF_SG_FIELD_CODING_DEF: return 8; - case GF_SG_FIELD_CODING_OUT: return 8; - case GF_SG_FIELD_CODING_DYN: return 2; + case GF_SG_FIELD_CODING_IN: return 12; + case GF_SG_FIELD_CODING_DEF: return 12; + case GF_SG_FIELD_CODING_OUT: return 12; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 10; + return 12; } } -static GF_Err PathLayout_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err RoofNode_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = PathLayout_In2All[inField]; + *allField = RoofNode_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = PathLayout_Def2All[inField]; + *allField = RoofNode_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = PathLayout_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = PathLayout_Dyn2All[inField]; + *allField = RoofNode_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err PathLayout_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err RoofNode_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_PathLayout *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_PathLayout *)node)->addChildren; + info->name = "Type"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_RoofNode *) node)->Type; return GF_OK; case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_PathLayout *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_PathLayout *)node)->removeChildren; + info->name = "Height"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_RoofNode *) node)->Height; return GF_OK; case 2: - info->name = "children"; + info->name = "SlopeAngle"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_PathLayout *)node)->children; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_RoofNode *) node)->SlopeAngle; return GF_OK; case 3: - info->name = "geometry"; + info->name = "EaveProjection"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFGeometryNode; - info->far_ptr = & ((M_PathLayout *)node)->geometry; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_RoofNode *) node)->EaveProjection; return GF_OK; case 4: - info->name = "alignment"; + info->name = "EdgeSupportIndex"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_PathLayout *) node)->alignment; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_RoofNode *) node)->EdgeSupportIndex; return GF_OK; case 5: - info->name = "pathOffset"; + info->name = "RoofTextureURL"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PathLayout *) node)->pathOffset; + info->fieldType = GF_SG_VRML_SFURL; + info->far_ptr = & ((M_RoofNode *) node)->RoofTextureURL; return GF_OK; case 6: - info->name = "spacing"; + info->name = "IsGenericTexture"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_PathLayout *) node)->spacing; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_RoofNode *) node)->IsGenericTexture; return GF_OK; case 7: - info->name = "reverseLayout"; + info->name = "TextureXScale"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PathLayout *) node)->reverseLayout; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_RoofNode *) node)->TextureXScale; return GF_OK; case 8: - info->name = "wrapMode"; + info->name = "TextureYScale"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_PathLayout *) node)->wrapMode; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_RoofNode *) node)->TextureYScale; return GF_OK; case 9: - info->name = "splitText"; + info->name = "TextureXPosition"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_PathLayout *) node)->splitText; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_RoofNode *) node)->TextureXPosition; + return GF_OK; + case 10: + info->name = "TextureYPosition"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_RoofNode *) node)->TextureYPosition; + return GF_OK; + case 11: + info->name = "TextureRotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_RoofNode *) node)->TextureRotation; return GF_OK; default: return GF_BAD_PARAM; @@ -17956,49 +34871,25 @@ static GF_Err PathLayout_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 PathLayout_get_field_index_by_name(char *name) +static s32 RoofNode_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; - if (!strcmp("geometry", name)) return 3; - if (!strcmp("alignment", name)) return 4; - if (!strcmp("pathOffset", name)) return 5; - if (!strcmp("spacing", name)) return 6; - if (!strcmp("reverseLayout", name)) return 7; - if (!strcmp("wrapMode", name)) return 8; - if (!strcmp("splitText", name)) return 9; + if (!strcmp("Type", name)) return 0; + if (!strcmp("Height", name)) return 1; + if (!strcmp("SlopeAngle", name)) return 2; + if (!strcmp("EaveProjection", name)) return 3; + if (!strcmp("EdgeSupportIndex", name)) return 4; + if (!strcmp("RoofTextureURL", name)) return 5; + if (!strcmp("IsGenericTexture", name)) return 6; + if (!strcmp("TextureXScale", name)) return 7; + if (!strcmp("TextureYScale", name)) return 8; + if (!strcmp("TextureXPosition", name)) return 9; + if (!strcmp("TextureYPosition", name)) return 10; + if (!strcmp("TextureRotation", name)) return 11; return -1; } -static Bool PathLayout_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool RoofNode_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 4: - *AType = 0; - *QType = 13; - *QT13_bits = 2; - *b_min = FLT2FIX(-1); - *b_max = FLT2FIX(1); - return 1; - case 5: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 6: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 8: - *AType = 0; - *QType = 13; - *QT13_bits = 2; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(2); - return 1; default: return 0; } @@ -18006,127 +34897,158 @@ static Bool PathLayout_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AT -GF_Node *PathLayout_Create() +GF_Node *RoofNode_Create() { - M_PathLayout *p; - GF_SAFEALLOC(p, M_PathLayout); + M_RoofNode *p; + GF_SAFEALLOC(p, M_RoofNode); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_PathLayout); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_MPEG4_RoofNode); /*default field values*/ - p->alignment.vals = (SFInt32*)malloc(sizeof(SFInt32)*1); - p->alignment.count = 1; - p->alignment.vals[0] = 0; - p->pathOffset = FLT2FIX(0); - p->spacing = FLT2FIX(1.0); - p->wrapMode = 0; - p->splitText = 1; + p->Type = 0; + p->Height = FLT2FIX(0.0); + p->SlopeAngle.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->SlopeAngle.count = 1; + p->SlopeAngle.vals[0] = FLT2FIX(0.0); + p->EaveProjection = FLT2FIX(0.0); + p->EdgeSupportIndex = -1; + p->IsGenericTexture = 1; + p->TextureXScale = FLT2FIX(1.0); + p->TextureYScale = FLT2FIX(1.0); + p->TextureXPosition = FLT2FIX(0.0); + p->TextureYPosition = FLT2FIX(0.0); + p->TextureRotation = FLT2FIX(0.0); return (GF_Node *)p; } /* - RadialGradient Node deletion + FacadeNode Node deletion */ -static void RadialGradient_Del(GF_Node *node) +static void FacadeNode_Del(GF_Node *node) { - M_RadialGradient *p = (M_RadialGradient *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfcolor_del(p->keyValue); - gf_sg_mffloat_del(p->opacity); - gf_node_unregister((GF_Node *) p->transform, (GF_Node *) p); + M_FacadeNode *p = (M_FacadeNode *) node; + gf_sg_sfurl_del(p->FacadePrimitive); + gf_sg_mfint32_del(p->NbFacadeCellsByStorey); + gf_sg_mffloat_del(p->StoreyHeight); + gf_node_unregister_children((GF_Node *) p, p->FacadeCellsArray); gf_node_free((GF_Node *) p); } -static const u16 RadialGradient_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static const u16 RadialGradient_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static const u16 RadialGradient_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static const u16 RadialGradient_Dyn2All[] = { 0, 1, 5}; +static const u16 FacadeNode_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 FacadeNode_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; +static const u16 FacadeNode_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; -static u32 RadialGradient_get_field_count(GF_Node *node, u8 IndexMode) +static u32 FacadeNode_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 8; - case GF_SG_FIELD_CODING_DEF: return 8; - case GF_SG_FIELD_CODING_OUT: return 8; - case GF_SG_FIELD_CODING_DYN: return 3; + case GF_SG_FIELD_CODING_IN: return 13; + case GF_SG_FIELD_CODING_DEF: return 13; + case GF_SG_FIELD_CODING_OUT: return 13; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 8; + return 13; } } -static GF_Err RadialGradient_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err FacadeNode_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = RadialGradient_In2All[inField]; + *allField = FacadeNode_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = RadialGradient_Def2All[inField]; + *allField = FacadeNode_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = RadialGradient_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = RadialGradient_Dyn2All[inField]; + *allField = FacadeNode_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err RadialGradient_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err FacadeNode_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "center"; + info->name = "WidthRatio"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_RadialGradient *) node)->center; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_FacadeNode *) node)->WidthRatio; return GF_OK; case 1: - info->name = "focalPoint"; + info->name = "XScale"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_RadialGradient *) node)->focalPoint; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_FacadeNode *) node)->XScale; return GF_OK; case 2: - info->name = "key"; + info->name = "YScale"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_RadialGradient *) node)->key; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_FacadeNode *) node)->YScale; return GF_OK; case 3: - info->name = "keyValue"; + info->name = "XPosition"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFCOLOR; - info->far_ptr = & ((M_RadialGradient *) node)->keyValue; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_FacadeNode *) node)->XPosition; return GF_OK; case 4: - info->name = "opacity"; + info->name = "YPosition"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_RadialGradient *) node)->opacity; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_FacadeNode *) node)->YPosition; return GF_OK; case 5: - info->name = "radius"; + info->name = "XRepeatInterval"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_RadialGradient *) node)->radius; + info->far_ptr = & ((M_FacadeNode *) node)->XRepeatInterval; return GF_OK; case 6: - info->name = "spreadMethod"; + info->name = "YRepeatInterval"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_RadialGradient *) node)->spreadMethod; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((M_FacadeNode *) node)->YRepeatInterval; return GF_OK; case 7: - info->name = "transform"; + info->name = "Repeat"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((M_RadialGradient *)node)->transform; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_FacadeNode *) node)->Repeat; + return GF_OK; + case 8: + info->name = "FacadePrimitive"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFURL; + info->far_ptr = & ((M_FacadeNode *) node)->FacadePrimitive; + return GF_OK; + case 9: + info->name = "NbStories"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_FacadeNode *) node)->NbStories; + return GF_OK; + case 10: + info->name = "NbFacadeCellsByStorey"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((M_FacadeNode *) node)->NbFacadeCellsByStorey; + return GF_OK; + case 11: + info->name = "StoreyHeight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((M_FacadeNode *) node)->StoreyHeight; + return GF_OK; + case 12: + info->name = "FacadeCellsArray"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((M_FacadeNode *)node)->FacadeCellsArray; return GF_OK; default: return GF_BAD_PARAM; @@ -18134,64 +35056,26 @@ static GF_Err RadialGradient_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 RadialGradient_get_field_index_by_name(char *name) +static s32 FacadeNode_get_field_index_by_name(char *name) { - if (!strcmp("center", name)) return 0; - if (!strcmp("focalPoint", name)) return 1; - if (!strcmp("key", name)) return 2; - if (!strcmp("keyValue", name)) return 3; - if (!strcmp("opacity", name)) return 4; - if (!strcmp("radius", name)) return 5; - if (!strcmp("spreadMethod", name)) return 6; - if (!strcmp("transform", name)) return 7; + if (!strcmp("WidthRatio", name)) return 0; + if (!strcmp("XScale", name)) return 1; + if (!strcmp("YScale", name)) return 2; + if (!strcmp("XPosition", name)) return 3; + if (!strcmp("YPosition", name)) return 4; + if (!strcmp("XRepeatInterval", name)) return 5; + if (!strcmp("YRepeatInterval", name)) return 6; + if (!strcmp("Repeat", name)) return 7; + if (!strcmp("FacadePrimitive", name)) return 8; + if (!strcmp("NbStories", name)) return 9; + if (!strcmp("NbFacadeCellsByStorey", name)) return 10; + if (!strcmp("StoreyHeight", name)) return 11; + if (!strcmp("FacadeCellsArray", name)) return 12; return -1; } -static Bool RadialGradient_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool FacadeNode_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 2; - *QType = 5; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 1: - *AType = 2; - *QType = 5; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 2: - *AType = 0; - *QType = 8; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 3: - *AType = 0; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 4: - *AType = 0; - *QType = 7; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 5: - *AType = 7; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 6: - *AType = 0; - *QType = 13; - *QT13_bits = 2; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(2); - return 1; default: return 0; } @@ -18199,135 +35083,124 @@ static Bool RadialGradient_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 -GF_Node *RadialGradient_Create() +GF_Node *FacadeNode_Create() { - M_RadialGradient *p; - GF_SAFEALLOC(p, M_RadialGradient); + M_FacadeNode *p; + GF_SAFEALLOC(p, M_FacadeNode); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_RadialGradient); + gf_node_setup((GF_Node *)p, TAG_MPEG4_FacadeNode); /*default field values*/ - p->center.x = FLT2FIX(0.5); - p->center.y = FLT2FIX(0.5); - p->focalPoint.x = FLT2FIX(0); - p->focalPoint.y = FLT2FIX(0); - p->opacity.vals = (SFFloat*)malloc(sizeof(SFFloat)*1); - p->opacity.count = 1; - p->opacity.vals[0] = FLT2FIX(1); - p->radius = FLT2FIX(0.5); - p->spreadMethod = 0; + p->WidthRatio = FLT2FIX(1.0); + p->XScale = FLT2FIX(1.0); + p->YScale = FLT2FIX(1.0); + p->XPosition = FLT2FIX(0.0); + p->YPosition = FLT2FIX(0.0); + p->XRepeatInterval = FLT2FIX(0.0); + p->YRepeatInterval = FLT2FIX(0.0); + p->NbStories = 0; + p->NbFacadeCellsByStorey.vals = (SFInt32*)gf_malloc(sizeof(SFInt32)*1); + p->NbFacadeCellsByStorey.count = 1; + p->NbFacadeCellsByStorey.vals[0] = 0; + p->StoreyHeight.vals = (SFFloat*)gf_malloc(sizeof(SFFloat)*1); + p->StoreyHeight.count = 1; + p->StoreyHeight.vals[0] = FLT2FIX(1.0); return (GF_Node *)p; } /* - TransformMatrix2D Node deletion + Shadow Node deletion */ -static void TransformMatrix2D_Del(GF_Node *node) +static void Shadow_Del(GF_Node *node) { - M_TransformMatrix2D *p = (M_TransformMatrix2D *) node; + M_Shadow *p = (M_Shadow *) node; gf_sg_vrml_parent_destroy((GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 TransformMatrix2D_Def2All[] = { 2, 3, 4, 5, 6, 7, 8}; -static const u16 TransformMatrix2D_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; -static const u16 TransformMatrix2D_Out2All[] = { 2, 3, 4, 5, 6, 7, 8}; -static const u16 TransformMatrix2D_Dyn2All[] = { 3, 4, 5, 6, 7, 8}; +static const u16 Shadow_Def2All[] = { 2, 3, 4, 5, 6}; +static const u16 Shadow_In2All[] = { 0, 1, 2, 3, 4, 5, 6}; +static const u16 Shadow_Out2All[] = { 2, 3, 4, 5, 6}; -static u32 TransformMatrix2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Shadow_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 9; - case GF_SG_FIELD_CODING_DEF: return 7; - case GF_SG_FIELD_CODING_OUT: return 7; - case GF_SG_FIELD_CODING_DYN: return 6; + case GF_SG_FIELD_CODING_IN: return 7; + case GF_SG_FIELD_CODING_DEF: return 5; + case GF_SG_FIELD_CODING_OUT: return 5; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 9; + return 7; } } -static GF_Err TransformMatrix2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Shadow_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = TransformMatrix2D_In2All[inField]; + *allField = Shadow_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = TransformMatrix2D_Def2All[inField]; + *allField = Shadow_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = TransformMatrix2D_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = TransformMatrix2D_Dyn2All[inField]; + *allField = Shadow_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err TransformMatrix2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Shadow_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_TransformMatrix2D *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_TransformMatrix2D *)node)->addChildren; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Shadow *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Shadow *)node)->addChildren; return GF_OK; case 1: info->name = "removeChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_TransformMatrix2D *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_TransformMatrix2D *)node)->removeChildren; + info->on_event_in = ((M_Shadow *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Shadow *)node)->removeChildren; return GF_OK; case 2: info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF2DNode; - info->far_ptr = & ((M_TransformMatrix2D *)node)->children; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_Shadow *)node)->children; return GF_OK; case 3: - info->name = "mxx"; + info->name = "enabled"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_TransformMatrix2D *) node)->mxx; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Shadow *) node)->enabled; return GF_OK; case 4: - info->name = "mxy"; + info->name = "cast"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_TransformMatrix2D *) node)->mxy; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Shadow *) node)->cast; return GF_OK; case 5: - info->name = "tx"; + info->name = "receive"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_TransformMatrix2D *) node)->tx; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Shadow *) node)->receive; return GF_OK; case 6: - info->name = "myx"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_TransformMatrix2D *) node)->myx; - return GF_OK; - case 7: - info->name = "myy"; + info->name = "penumbra"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_TransformMatrix2D *) node)->myy; - return GF_OK; - case 8: - info->name = "ty"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_TransformMatrix2D *) node)->ty; + info->far_ptr = & ((M_Shadow *) node)->penumbra; return GF_OK; default: return GF_BAD_PARAM; @@ -18335,58 +35208,20 @@ static GF_Err TransformMatrix2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 TransformMatrix2D_get_field_index_by_name(char *name) +static s32 Shadow_get_field_index_by_name(char *name) { if (!strcmp("addChildren", name)) return 0; if (!strcmp("removeChildren", name)) return 1; if (!strcmp("children", name)) return 2; - if (!strcmp("mxx", name)) return 3; - if (!strcmp("mxy", name)) return 4; - if (!strcmp("tx", name)) return 5; - if (!strcmp("myx", name)) return 6; - if (!strcmp("myy", name)) return 7; - if (!strcmp("ty", name)) return 8; + if (!strcmp("enabled", name)) return 3; + if (!strcmp("cast", name)) return 4; + if (!strcmp("receive", name)) return 5; + if (!strcmp("penumbra", name)) return 6; return -1; } -static Bool TransformMatrix2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool Shadow_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 3: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 4: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 5: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 6: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 7: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 8: - *AType = 7; - *QType = 7; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -18394,130 +35229,111 @@ static Bool TransformMatrix2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, -GF_Node *TransformMatrix2D_Create() +GF_Node *Shadow_Create() { - M_TransformMatrix2D *p; - GF_SAFEALLOC(p, M_TransformMatrix2D); + M_Shadow *p; + GF_SAFEALLOC(p, M_Shadow); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_TransformMatrix2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Shadow); gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->mxx = FLT2FIX(1); - p->mxy = FLT2FIX(0); - p->tx = FLT2FIX(0); - p->myx = FLT2FIX(0); - p->myy = FLT2FIX(1); - p->ty = FLT2FIX(0); + p->enabled = 1; + p->cast = 1; + p->receive = 1; + p->penumbra = FLT2FIX(0); return (GF_Node *)p; } /* - Viewport Node deletion + CacheTexture Node deletion */ -static void Viewport_Del(GF_Node *node) +static void CacheTexture_Del(GF_Node *node) { - M_Viewport *p = (M_Viewport *) node; - gf_sg_mfint32_del(p->alignment); - gf_sg_sfstring_del(p->description); + M_CacheTexture *p = (M_CacheTexture *) node; + gf_sg_sfstring_del(p->decoderSpecificInfo); + gf_sg_sfstring_del(p->image); + gf_sg_sfstring_del(p->cacheURL); + gf_sg_mfurl_del(p->cacheOD); gf_node_free((GF_Node *) p); } -static const u16 Viewport_Def2All[] = { 1, 2, 3, 4, 5, 6}; -static const u16 Viewport_In2All[] = { 0, 1, 2, 3, 4, 5}; -static const u16 Viewport_Out2All[] = { 1, 2, 3, 4, 5, 7, 8}; -static const u16 Viewport_Dyn2All[] = { 1, 2, 3}; +static const u16 CacheTexture_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7}; -static u32 Viewport_get_field_count(GF_Node *node, u8 IndexMode) +static u32 CacheTexture_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 6; - case GF_SG_FIELD_CODING_DEF: return 6; - case GF_SG_FIELD_CODING_OUT: return 7; - case GF_SG_FIELD_CODING_DYN: return 3; + case GF_SG_FIELD_CODING_IN: return 0; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 0; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 9; + return 8; } } -static GF_Err Viewport_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err CacheTexture_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: - *allField = Viewport_In2All[inField]; - return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = Viewport_Def2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_OUT: - *allField = Viewport_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = Viewport_Dyn2All[inField]; + *allField = CacheTexture_Def2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err Viewport_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err CacheTexture_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_bind"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((M_Viewport *)node)->on_set_bind; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Viewport *) node)->set_bind; + info->name = "objectTypeIndication"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_CacheTexture *) node)->objectTypeIndication; return GF_OK; case 1: - info->name = "position"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Viewport *) node)->position; + info->name = "decoderSpecificInfo"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_CacheTexture *) node)->decoderSpecificInfo; return GF_OK; case 2: - info->name = "size"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFVEC2F; - info->far_ptr = & ((M_Viewport *) node)->size; + info->name = "image"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_CacheTexture *) node)->image; return GF_OK; case 3: - info->name = "orientation"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_Viewport *) node)->orientation; + info->name = "cacheURL"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_CacheTexture *) node)->cacheURL; return GF_OK; case 4: - info->name = "alignment"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_Viewport *) node)->alignment; + info->name = "cacheOD"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((M_CacheTexture *) node)->cacheOD; return GF_OK; case 5: - info->name = "fit"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->name = "expirationDate"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_Viewport *) node)->fit; + info->far_ptr = & ((M_CacheTexture *) node)->expirationDate; return GF_OK; case 6: - info->name = "description"; + info->name = "repeatS"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_Viewport *) node)->description; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_CacheTexture *) node)->repeatS; return GF_OK; case 7: - info->name = "bindTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((M_Viewport *) node)->bindTime; - return GF_OK; - case 8: - info->name = "isBound"; - info->eventType = GF_SG_EVENT_OUT; + info->name = "repeatT"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_Viewport *) node)->isBound; + info->far_ptr = & ((M_CacheTexture *) node)->repeatT; return GF_OK; default: return GF_BAD_PARAM; @@ -18525,54 +35341,21 @@ static GF_Err Viewport_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Viewport_get_field_index_by_name(char *name) +static s32 CacheTexture_get_field_index_by_name(char *name) { - if (!strcmp("set_bind", name)) return 0; - if (!strcmp("position", name)) return 1; - if (!strcmp("size", name)) return 2; - if (!strcmp("orientation", name)) return 3; - if (!strcmp("alignment", name)) return 4; - if (!strcmp("fit", name)) return 5; - if (!strcmp("description", name)) return 6; - if (!strcmp("bindTime", name)) return 7; - if (!strcmp("isBound", name)) return 8; + if (!strcmp("objectTypeIndication", name)) return 0; + if (!strcmp("decoderSpecificInfo", name)) return 1; + if (!strcmp("image", name)) return 2; + if (!strcmp("cacheURL", name)) return 3; + if (!strcmp("cacheOD", name)) return 4; + if (!strcmp("expirationDate", name)) return 5; + if (!strcmp("repeatS", name)) return 6; + if (!strcmp("repeatT", name)) return 7; return -1; } -static Bool Viewport_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool CacheTexture_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 1; - *QType = 1; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 2: - *AType = 12; - *QType = 12; - *b_min = FIX_MIN; - *b_max = FIX_MAX; - return 1; - case 3: - *AType = 6; - *QType = 6; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(6.2831853); - return 1; - case 4: - *AType = 0; - *QType = 13; - *QT13_bits = 3; - *b_min = FLT2FIX(-1); - *b_max = FLT2FIX(1); - return 1; - case 5: - *AType = 0; - *QType = 13; - *QT13_bits = 3; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(2); - return 1; default: return 0; } @@ -18580,96 +35363,123 @@ static Bool Viewport_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATyp -GF_Node *Viewport_Create() +GF_Node *CacheTexture_Create() { - M_Viewport *p; - GF_SAFEALLOC(p, M_Viewport); + M_CacheTexture *p; + GF_SAFEALLOC(p, M_CacheTexture); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_Viewport); + gf_node_setup((GF_Node *)p, TAG_MPEG4_CacheTexture); /*default field values*/ - p->position.x = FLT2FIX(0); - p->position.y = FLT2FIX(0); - p->size.x = FLT2FIX(-1); - p->size.y = FLT2FIX(-1); - p->orientation = FLT2FIX(0); - p->alignment.vals = (SFInt32*)malloc(sizeof(SFInt32)*1); - p->alignment.count = 1; - p->alignment.vals[0] = 0; - p->fit = 0; + p->objectTypeIndication = 0; + p->expirationDate = 0; + p->repeatS = 1; + p->repeatT = 1; return (GF_Node *)p; } /* - XCurve2D Node deletion + EnvironmentTest Node deletion */ -static void XCurve2D_Del(GF_Node *node) +static void EnvironmentTest_Del(GF_Node *node) { - M_XCurve2D *p = (M_XCurve2D *) node; - gf_node_unregister((GF_Node *) p->point, (GF_Node *) p); - gf_sg_mfint32_del(p->type); + M_EnvironmentTest *p = (M_EnvironmentTest *) node; + gf_sg_sfstring_del(p->compareValue); + gf_sg_sfstring_del(p->parameterValue); gf_node_free((GF_Node *) p); } -static const u16 XCurve2D_Def2All[] = { 0, 1, 2}; -static const u16 XCurve2D_In2All[] = { 0, 1, 2}; -static const u16 XCurve2D_Out2All[] = { 0, 1, 2}; -static const u16 XCurve2D_Dyn2All[] = { 1}; +static const u16 EnvironmentTest_Def2All[] = { 1, 2, 3, 4}; +static const u16 EnvironmentTest_In2All[] = { 0, 1, 2, 3, 4}; +static const u16 EnvironmentTest_Out2All[] = { 1, 2, 3, 4, 5, 6, 7, 8}; -static u32 XCurve2D_get_field_count(GF_Node *node, u8 IndexMode) +static u32 EnvironmentTest_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 3; - case GF_SG_FIELD_CODING_DEF: return 3; - case GF_SG_FIELD_CODING_OUT: return 3; - case GF_SG_FIELD_CODING_DYN: return 1; + case GF_SG_FIELD_CODING_IN: return 5; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 8; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 3; + return 9; } } -static GF_Err XCurve2D_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err EnvironmentTest_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = XCurve2D_In2All[inField]; + *allField = EnvironmentTest_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = XCurve2D_Def2All[inField]; + *allField = EnvironmentTest_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = XCurve2D_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = XCurve2D_Dyn2All[inField]; + *allField = EnvironmentTest_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err XCurve2D_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err EnvironmentTest_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "point"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinate2DNode; - info->far_ptr = & ((M_XCurve2D *)node)->point; + info->name = "evaluate"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_EnvironmentTest *)node)->on_evaluate; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_EnvironmentTest *) node)->evaluate; return GF_OK; case 1: - info->name = "fineness"; + info->name = "enabled"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_XCurve2D *) node)->fineness; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_EnvironmentTest *) node)->enabled; return GF_OK; case 2: - info->name = "type"; + info->name = "parameter"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_XCurve2D *) node)->type; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_EnvironmentTest *) node)->parameter; + return GF_OK; + case 3: + info->name = "compareValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_EnvironmentTest *) node)->compareValue; + return GF_OK; + case 4: + info->name = "evaluateOnChange"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_EnvironmentTest *) node)->evaluateOnChange; + return GF_OK; + case 5: + info->name = "valueLarger"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_EnvironmentTest *) node)->valueLarger; + return GF_OK; + case 6: + info->name = "valueEqual"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_EnvironmentTest *) node)->valueEqual; + return GF_OK; + case 7: + info->name = "valueSmaller"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_EnvironmentTest *) node)->valueSmaller; + return GF_OK; + case 8: + info->name = "parameterValue"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_EnvironmentTest *) node)->parameterValue; return GF_OK; default: return GF_BAD_PARAM; @@ -18677,29 +35487,22 @@ static GF_Err XCurve2D_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 XCurve2D_get_field_index_by_name(char *name) +static s32 EnvironmentTest_get_field_index_by_name(char *name) { - if (!strcmp("point", name)) return 0; - if (!strcmp("fineness", name)) return 1; - if (!strcmp("type", name)) return 2; + if (!strcmp("evaluate", name)) return 0; + if (!strcmp("enabled", name)) return 1; + if (!strcmp("parameter", name)) return 2; + if (!strcmp("compareValue", name)) return 3; + if (!strcmp("evaluateOnChange", name)) return 4; + if (!strcmp("valueLarger", name)) return 5; + if (!strcmp("valueEqual", name)) return 6; + if (!strcmp("valueSmaller", name)) return 7; + if (!strcmp("parameterValue", name)) return 8; return -1; } -static Bool XCurve2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool EnvironmentTest_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 1: - *AType = 7; - *QType = 0; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 2: - *AType = 0; - *QType = 13; - *QT13_bits = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(15); - return 1; default: return 0; } @@ -18707,174 +35510,259 @@ static Bool XCurve2D_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *ATyp -GF_Node *XCurve2D_Create() +GF_Node *EnvironmentTest_Create() { - M_XCurve2D *p; - GF_SAFEALLOC(p, M_XCurve2D); + M_EnvironmentTest *p; + GF_SAFEALLOC(p, M_EnvironmentTest); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_XCurve2D); + gf_node_setup((GF_Node *)p, TAG_MPEG4_EnvironmentTest); /*default field values*/ - p->fineness = FLT2FIX(0.5); + p->enabled = 1; + p->parameter = 0; + p->evaluateOnChange = 1; return (GF_Node *)p; } /* - XFontStyle Node deletion + KeyNavigator Node deletion */ -static void XFontStyle_Del(GF_Node *node) +static void KeyNavigator_Del(GF_Node *node) { - M_XFontStyle *p = (M_XFontStyle *) node; - gf_sg_mfstring_del(p->fontName); - gf_sg_mfstring_del(p->justify); - gf_sg_sfstring_del(p->language); - gf_sg_sfstring_del(p->stretch); - gf_sg_sfstring_del(p->style); - gf_sg_mfstring_del(p->featureName); - gf_sg_mfint32_del(p->featureStartOffset); - gf_sg_mfint32_del(p->featureLength); - gf_sg_mfint32_del(p->featureValue); + M_KeyNavigator *p = (M_KeyNavigator *) node; + gf_node_unregister((GF_Node *) p->sensor, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->left, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->right, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->up, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->down, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->select, (GF_Node *) p); + gf_node_unregister((GF_Node *) p->quit, (GF_Node *) p); gf_node_free((GF_Node *) p); } -static const u16 XFontStyle_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; -static const u16 XFontStyle_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; -static const u16 XFontStyle_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; +static const u16 KeyNavigator_Def2All[] = { 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 KeyNavigator_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8}; +static const u16 KeyNavigator_Out2All[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9}; -static u32 XFontStyle_get_field_count(GF_Node *node, u8 IndexMode) +static u32 KeyNavigator_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 17; - case GF_SG_FIELD_CODING_DEF: return 17; - case GF_SG_FIELD_CODING_OUT: return 17; + case GF_SG_FIELD_CODING_IN: return 9; + case GF_SG_FIELD_CODING_DEF: return 8; + case GF_SG_FIELD_CODING_OUT: return 9; case GF_SG_FIELD_CODING_DYN: return 0; default: - return 17; + return 10; } } -static GF_Err XFontStyle_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err KeyNavigator_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = XFontStyle_In2All[inField]; + *allField = KeyNavigator_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = XFontStyle_Def2All[inField]; + *allField = KeyNavigator_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = XFontStyle_Out2All[inField]; + *allField = KeyNavigator_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err XFontStyle_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err KeyNavigator_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "fontName"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_XFontStyle *) node)->fontName; + info->name = "setFocus"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_KeyNavigator *)node)->on_setFocus; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_KeyNavigator *) node)->setFocus; return GF_OK; case 1: - info->name = "horizontal"; + info->name = "sensor"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_XFontStyle *) node)->horizontal; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_KeyNavigator *)node)->sensor; return GF_OK; case 2: - info->name = "justify"; + info->name = "left"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_XFontStyle *) node)->justify; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_KeyNavigator *)node)->left; return GF_OK; case 3: - info->name = "language"; + info->name = "right"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_XFontStyle *) node)->language; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_KeyNavigator *)node)->right; return GF_OK; case 4: - info->name = "leftToRight"; + info->name = "up"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_XFontStyle *) node)->leftToRight; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_KeyNavigator *)node)->up; return GF_OK; case 5: - info->name = "size"; + info->name = "down"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_XFontStyle *) node)->size; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_KeyNavigator *)node)->down; return GF_OK; case 6: - info->name = "stretch"; + info->name = "select"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_XFontStyle *) node)->stretch; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_KeyNavigator *)node)->select; return GF_OK; case 7: - info->name = "letterSpacing"; + info->name = "quit"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_XFontStyle *) node)->letterSpacing; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SF2DNode; + info->far_ptr = & ((M_KeyNavigator *)node)->quit; return GF_OK; case 8: - info->name = "wordSpacing"; + info->name = "step"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_XFontStyle *) node)->wordSpacing; + info->far_ptr = & ((M_KeyNavigator *) node)->step; return GF_OK; case 9: - info->name = "weight"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_XFontStyle *) node)->weight; - return GF_OK; - case 10: - info->name = "fontKerning"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->name = "focusSet"; + info->eventType = GF_SG_EVENT_OUT; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_XFontStyle *) node)->fontKerning; + info->far_ptr = & ((M_KeyNavigator *) node)->focusSet; return GF_OK; - case 11: - info->name = "style"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((M_XFontStyle *) node)->style; + default: + return GF_BAD_PARAM; + } +} + + +static s32 KeyNavigator_get_field_index_by_name(char *name) +{ + if (!strcmp("setFocus", name)) return 0; + if (!strcmp("sensor", name)) return 1; + if (!strcmp("left", name)) return 2; + if (!strcmp("right", name)) return 3; + if (!strcmp("up", name)) return 4; + if (!strcmp("down", name)) return 5; + if (!strcmp("select", name)) return 6; + if (!strcmp("quit", name)) return 7; + if (!strcmp("step", name)) return 8; + if (!strcmp("focusSet", name)) return 9; + return -1; + } +static Bool KeyNavigator_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +{ + switch (FieldIndex) { + default: + return 0; + } +} + + + +GF_Node *KeyNavigator_Create() +{ + M_KeyNavigator *p; + GF_SAFEALLOC(p, M_KeyNavigator); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_MPEG4_KeyNavigator); + + /*default field values*/ + p->step = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + SpacePartition Node deletion +*/ + +static void SpacePartition_Del(GF_Node *node) +{ + M_SpacePartition *p = (M_SpacePartition *) node; + gf_sg_sfurl_del(p->SPStream); + gf_sg_vrml_parent_destroy((GF_Node *) p); + gf_node_free((GF_Node *) p); +} + +static const u16 SpacePartition_Def2All[] = { 2, 3}; +static const u16 SpacePartition_In2All[] = { 0, 1, 2, 3}; +static const u16 SpacePartition_Out2All[] = { 2, 3}; + +static u32 SpacePartition_get_field_count(GF_Node *node, u8 IndexMode) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: return 4; + case GF_SG_FIELD_CODING_DEF: return 2; + case GF_SG_FIELD_CODING_OUT: return 2; + case GF_SG_FIELD_CODING_DYN: return 0; + default: + return 4; + } +} + +static GF_Err SpacePartition_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +{ + switch(IndexMode) { + case GF_SG_FIELD_CODING_IN: + *allField = SpacePartition_In2All[inField]; return GF_OK; - case 12: - info->name = "topToBottom"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_XFontStyle *) node)->topToBottom; + case GF_SG_FIELD_CODING_DEF: + *allField = SpacePartition_Def2All[inField]; return GF_OK; - case 13: - info->name = "featureName"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((M_XFontStyle *) node)->featureName; + case GF_SG_FIELD_CODING_OUT: + *allField = SpacePartition_Out2All[inField]; return GF_OK; - case 14: - info->name = "featureStartOffset"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_XFontStyle *) node)->featureStartOffset; + default: + return GF_BAD_PARAM; + } +} +static GF_Err SpacePartition_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SpacePartition *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SpacePartition *)node)->addChildren; return GF_OK; - case 15: - info->name = "featureLength"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_XFontStyle *) node)->featureLength; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_SpacePartition *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SpacePartition *)node)->removeChildren; return GF_OK; - case 16: - info->name = "featureValue"; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((M_SpacePartition *)node)->children; + return GF_OK; + case 3: + info->name = "SPStream"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((M_XFontStyle *) node)->featureValue; + info->fieldType = GF_SG_VRML_SFURL; + info->far_ptr = & ((M_SpacePartition *) node)->SPStream; return GF_OK; default: return GF_BAD_PARAM; @@ -18882,48 +35770,17 @@ static GF_Err XFontStyle_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 XFontStyle_get_field_index_by_name(char *name) +static s32 SpacePartition_get_field_index_by_name(char *name) { - if (!strcmp("fontName", name)) return 0; - if (!strcmp("horizontal", name)) return 1; - if (!strcmp("justify", name)) return 2; - if (!strcmp("language", name)) return 3; - if (!strcmp("leftToRight", name)) return 4; - if (!strcmp("size", name)) return 5; - if (!strcmp("stretch", name)) return 6; - if (!strcmp("letterSpacing", name)) return 7; - if (!strcmp("wordSpacing", name)) return 8; - if (!strcmp("weight", name)) return 9; - if (!strcmp("fontKerning", name)) return 10; - if (!strcmp("style", name)) return 11; - if (!strcmp("topToBottom", name)) return 12; - if (!strcmp("featureName", name)) return 13; - if (!strcmp("featureStartOffset", name)) return 14; - if (!strcmp("featureLength", name)) return 15; - if (!strcmp("featureValue", name)) return 16; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("SPStream", name)) return 3; return -1; } -static Bool XFontStyle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool SpacePartition_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 5: - *AType = 0; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 7: - *AType = 0; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 8: - *AType = 0; - *QType = 11; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -18931,169 +35788,102 @@ static Bool XFontStyle_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AT -GF_Node *XFontStyle_Create() +GF_Node *SpacePartition_Create() { - M_XFontStyle *p; - GF_SAFEALLOC(p, M_XFontStyle); + M_SpacePartition *p; + GF_SAFEALLOC(p, M_SpacePartition); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_XFontStyle); + gf_node_setup((GF_Node *)p, TAG_MPEG4_SpacePartition); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->fontName.vals = (char**)malloc(sizeof(SFString)*1); - p->fontName.count = 1; - p->fontName.vals[0] = (char*)malloc(sizeof(char) * 6); - strcpy(p->fontName.vals[0], "SERIF"); - p->horizontal = 1; - p->justify.vals = (char**)malloc(sizeof(SFString)*1); - p->justify.count = 1; - p->justify.vals[0] = (char*)malloc(sizeof(char) * 6); - strcpy(p->justify.vals[0], "BEGIN"); - p->leftToRight = 1; - p->size = FLT2FIX(1.0); - p->stretch.buffer = (char*)malloc(sizeof(char) * 7); - strcpy(p->stretch.buffer, "NORMAL"); - p->letterSpacing = FLT2FIX(0.0); - p->wordSpacing = FLT2FIX(0.0); - p->weight = 400; - p->fontKerning = 1; - p->style.buffer = (char*)malloc(sizeof(char) * 6); - strcpy(p->style.buffer, "PLAIN"); - p->topToBottom = 1; return (GF_Node *)p; } /* - XLineProperties Node deletion + Storage Node deletion */ -static void XLineProperties_Del(GF_Node *node) +static void Storage_Del(GF_Node *node) { - M_XLineProperties *p = (M_XLineProperties *) node; - gf_sg_mffloat_del(p->dashes); - gf_node_unregister((GF_Node *) p->texture, (GF_Node *) p); - gf_node_unregister((GF_Node *) p->textureTransform, (GF_Node *) p); + M_Storage *p = (M_Storage *) node; + gf_sg_sfstring_del(p->name); gf_node_free((GF_Node *) p); } -static const u16 XLineProperties_Def2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; -static const u16 XLineProperties_In2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; -static const u16 XLineProperties_Out2All[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; -static const u16 XLineProperties_Dyn2All[] = { 0, 7, 8, 9, 10}; +static const u16 Storage_Def2All[] = { 2, 3, 4, 5}; +static const u16 Storage_In2All[] = { 0, 1, 2}; +static const u16 Storage_Out2All[] = { 2}; -static u32 XLineProperties_get_field_count(GF_Node *node, u8 IndexMode) +static u32 Storage_get_field_count(GF_Node *node, u8 IndexMode) { switch(IndexMode) { - case GF_SG_FIELD_CODING_IN: return 13; - case GF_SG_FIELD_CODING_DEF: return 13; - case GF_SG_FIELD_CODING_OUT: return 13; - case GF_SG_FIELD_CODING_DYN: return 5; + case GF_SG_FIELD_CODING_IN: return 3; + case GF_SG_FIELD_CODING_DEF: return 4; + case GF_SG_FIELD_CODING_OUT: return 1; + case GF_SG_FIELD_CODING_DYN: return 0; default: - return 13; + return 6; } } -static GF_Err XLineProperties_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) +static GF_Err Storage_get_field_index(GF_Node *n, u32 inField, u8 IndexMode, u32 *allField) { switch(IndexMode) { case GF_SG_FIELD_CODING_IN: - *allField = XLineProperties_In2All[inField]; + *allField = Storage_In2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_DEF: - *allField = XLineProperties_Def2All[inField]; + *allField = Storage_Def2All[inField]; return GF_OK; case GF_SG_FIELD_CODING_OUT: - *allField = XLineProperties_Out2All[inField]; - return GF_OK; - case GF_SG_FIELD_CODING_DYN: - *allField = XLineProperties_Dyn2All[inField]; + *allField = Storage_Out2All[inField]; return GF_OK; default: return GF_BAD_PARAM; } } -static GF_Err XLineProperties_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Storage_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "lineColor"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((M_XLineProperties *) node)->lineColor; + info->name = "forceSave"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Storage *)node)->on_forceSave; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Storage *) node)->forceSave; return GF_OK; case 1: - info->name = "lineStyle"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_XLineProperties *) node)->lineStyle; + info->name = "forceRestore"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((M_Storage *)node)->on_forceRestore; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((M_Storage *) node)->forceRestore; return GF_OK; case 2: - info->name = "isCenterAligned"; + info->name = "auto"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_XLineProperties *) node)->isCenterAligned; + info->far_ptr = & ((M_Storage *) node)->_auto; return GF_OK; case 3: - info->name = "isScalable"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((M_XLineProperties *) node)->isScalable; + info->name = "expireAfter"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((M_Storage *) node)->expireAfter; return GF_OK; case 4: - info->name = "lineCap"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_XLineProperties *) node)->lineCap; + info->name = "name"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((M_Storage *) node)->name; return GF_OK; case 5: - info->name = "lineJoin"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((M_XLineProperties *) node)->lineJoin; - return GF_OK; - case 6: - info->name = "miterLimit"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_XLineProperties *) node)->miterLimit; - return GF_OK; - case 7: - info->name = "transparency"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_XLineProperties *) node)->transparency; - return GF_OK; - case 8: - info->name = "width"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_XLineProperties *) node)->width; - return GF_OK; - case 9: - info->name = "dashOffset"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((M_XLineProperties *) node)->dashOffset; - return GF_OK; - case 10: - info->name = "dashes"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((M_XLineProperties *) node)->dashes; - return GF_OK; - case 11: - info->name = "texture"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureNode; - info->far_ptr = & ((M_XLineProperties *)node)->texture; - return GF_OK; - case 12: - info->name = "textureTransform"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureTransformNode; - info->far_ptr = & ((M_XLineProperties *)node)->textureTransform; + info->name = "storageList"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFATTRREF; + info->far_ptr = & ((M_Storage *) node)->storageList; return GF_OK; default: return GF_BAD_PARAM; @@ -19101,83 +35891,19 @@ static GF_Err XLineProperties_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 XLineProperties_get_field_index_by_name(char *name) +static s32 Storage_get_field_index_by_name(char *name) { - if (!strcmp("lineColor", name)) return 0; - if (!strcmp("lineStyle", name)) return 1; - if (!strcmp("isCenterAligned", name)) return 2; - if (!strcmp("isScalable", name)) return 3; - if (!strcmp("lineCap", name)) return 4; - if (!strcmp("lineJoin", name)) return 5; - if (!strcmp("miterLimit", name)) return 6; - if (!strcmp("transparency", name)) return 7; - if (!strcmp("width", name)) return 8; - if (!strcmp("dashOffset", name)) return 9; - if (!strcmp("dashes", name)) return 10; - if (!strcmp("texture", name)) return 11; - if (!strcmp("textureTransform", name)) return 12; + if (!strcmp("forceSave", name)) return 0; + if (!strcmp("forceRestore", name)) return 1; + if (!strcmp("auto", name)) return 2; + if (!strcmp("expireAfter", name)) return 3; + if (!strcmp("name", name)) return 4; + if (!strcmp("storageList", name)) return 5; return -1; } -static Bool XLineProperties_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) +static Bool Storage_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) { switch (FieldIndex) { - case 0: - *AType = 4; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 1: - *AType = 0; - *QType = 13; - *QT13_bits = 3; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(5); - return 1; - case 4: - *AType = 0; - *QType = 13; - *QT13_bits = 3; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(2); - return 1; - case 5: - *AType = 0; - *QType = 13; - *QT13_bits = 3; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(2); - return 1; - case 6: - *AType = 0; - *QType = 12; - *b_min = FLT2FIX(1); - *b_max = FIX_MAX; - return 1; - case 7: - *AType = 8; - *QType = 4; - *b_min = FLT2FIX(0); - *b_max = FLT2FIX(1); - return 1; - case 8: - *AType = 7; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 9: - *AType = 7; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; - case 10: - *AType = 7; - *QType = 12; - *b_min = FLT2FIX(0); - *b_max = FIX_MAX; - return 1; default: return 0; } @@ -19185,26 +35911,16 @@ static Bool XLineProperties_get_aq_info(GF_Node *n, u32 FieldIndex, u8 *QType, u -GF_Node *XLineProperties_Create() +GF_Node *Storage_Create() { - M_XLineProperties *p; - GF_SAFEALLOC(p, M_XLineProperties); + M_Storage *p; + GF_SAFEALLOC(p, M_Storage); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_MPEG4_XLineProperties); + gf_node_setup((GF_Node *)p, TAG_MPEG4_Storage); /*default field values*/ - p->lineColor.red = FLT2FIX(0); - p->lineColor.green = FLT2FIX(0); - p->lineColor.blue = FLT2FIX(0); - p->lineStyle = 0; - p->isCenterAligned = 1; - p->isScalable = 1; - p->lineCap = 0; - p->lineJoin = 0; - p->miterLimit = FLT2FIX(4); - p->transparency = FLT2FIX(0); - p->width = FLT2FIX(1); - p->dashOffset = FLT2FIX(0); + p->_auto = 1; + p->expireAfter = 0; return (GF_Node *)p; } @@ -19280,8 +35996,24 @@ GF_Node *gf_sg_mpeg4_node_new(u32 NodeTag) return DiscSensor_Create(); case TAG_MPEG4_ElevationGrid: return ElevationGrid_Create(); + case TAG_MPEG4_Expression: + return Expression_Create(); case TAG_MPEG4_Extrusion: return Extrusion_Create(); + case TAG_MPEG4_Face: + return Face_Create(); + case TAG_MPEG4_FaceDefMesh: + return FaceDefMesh_Create(); + case TAG_MPEG4_FaceDefTables: + return FaceDefTables_Create(); + case TAG_MPEG4_FaceDefTransform: + return FaceDefTransform_Create(); + case TAG_MPEG4_FAP: + return FAP_Create(); + case TAG_MPEG4_FDP: + return FDP_Create(); + case TAG_MPEG4_FIT: + return FIT_Create(); case TAG_MPEG4_Fog: return Fog_Create(); case TAG_MPEG4_FontStyle: @@ -19394,6 +36126,8 @@ GF_Node *gf_sg_mpeg4_node_new(u32 NodeTag) return Viewpoint_Create(); case TAG_MPEG4_VisibilitySensor: return VisibilitySensor_Create(); + case TAG_MPEG4_Viseme: + return Viseme_Create(); case TAG_MPEG4_WorldInfo: return WorldInfo_Create(); case TAG_MPEG4_AcousticMaterial: @@ -19402,6 +36136,16 @@ GF_Node *gf_sg_mpeg4_node_new(u32 NodeTag) return AcousticScene_Create(); case TAG_MPEG4_ApplicationWindow: return ApplicationWindow_Create(); + case TAG_MPEG4_BAP: + return BAP_Create(); + case TAG_MPEG4_BDP: + return BDP_Create(); + case TAG_MPEG4_Body: + return Body_Create(); + case TAG_MPEG4_BodyDefTable: + return BodyDefTable_Create(); + case TAG_MPEG4_BodySegmentConnectionHint: + return BodySegmentConnectionHint_Create(); case TAG_MPEG4_DirectiveSound: return DirectiveSound_Create(); case TAG_MPEG4_Hierarchical3DMesh: @@ -19426,18 +36170,84 @@ GF_Node *gf_sg_mpeg4_node_new(u32 NodeTag) return MediaControl_Create(); case TAG_MPEG4_MediaSensor: return MediaSensor_Create(); + case TAG_MPEG4_BitWrapper: + return BitWrapper_Create(); case TAG_MPEG4_CoordinateInterpolator4D: return CoordinateInterpolator4D_Create(); + case TAG_MPEG4_DepthImage: + return DepthImage_Create(); + case TAG_MPEG4_FFD: + return FFD_Create(); + case TAG_MPEG4_Implicit: + return Implicit_Create(); + case TAG_MPEG4_XXLFM_Appearance: + return XXLFM_Appearance_Create(); + case TAG_MPEG4_XXLFM_BlendList: + return XXLFM_BlendList_Create(); + case TAG_MPEG4_XXLFM_FrameList: + return XXLFM_FrameList_Create(); + case TAG_MPEG4_XXLFM_LightMap: + return XXLFM_LightMap_Create(); + case TAG_MPEG4_XXLFM_SurfaceMapList: + return XXLFM_SurfaceMapList_Create(); + case TAG_MPEG4_XXLFM_ViewMapList: + return XXLFM_ViewMapList_Create(); + case TAG_MPEG4_MeshGrid: + return MeshGrid_Create(); case TAG_MPEG4_NonLinearDeformer: return NonLinearDeformer_Create(); + case TAG_MPEG4_NurbsCurve: + return NurbsCurve_Create(); + case TAG_MPEG4_NurbsCurve2D: + return NurbsCurve2D_Create(); + case TAG_MPEG4_NurbsSurface: + return NurbsSurface_Create(); + case TAG_MPEG4_OctreeImage: + return OctreeImage_Create(); + case TAG_MPEG4_XXParticles: + return XXParticles_Create(); + case TAG_MPEG4_XXParticleInitBox: + return XXParticleInitBox_Create(); + case TAG_MPEG4_XXPlanarObstacle: + return XXPlanarObstacle_Create(); + case TAG_MPEG4_XXPointAttractor: + return XXPointAttractor_Create(); + case TAG_MPEG4_PointTexture: + return PointTexture_Create(); case TAG_MPEG4_PositionAnimator: return PositionAnimator_Create(); case TAG_MPEG4_PositionAnimator2D: return PositionAnimator2D_Create(); case TAG_MPEG4_PositionInterpolator4D: return PositionInterpolator4D_Create(); + case TAG_MPEG4_ProceduralTexture: + return ProceduralTexture_Create(); + case TAG_MPEG4_Quadric: + return Quadric_Create(); + case TAG_MPEG4_SBBone: + return SBBone_Create(); + case TAG_MPEG4_SBMuscle: + return SBMuscle_Create(); + case TAG_MPEG4_SBSegment: + return SBSegment_Create(); + case TAG_MPEG4_SBSite: + return SBSite_Create(); + case TAG_MPEG4_SBSkinnedModel: + return SBSkinnedModel_Create(); + case TAG_MPEG4_SBVCAnimation: + return SBVCAnimation_Create(); case TAG_MPEG4_ScalarAnimator: return ScalarAnimator_Create(); + case TAG_MPEG4_SimpleTexture: + return SimpleTexture_Create(); + case TAG_MPEG4_SolidRep: + return SolidRep_Create(); + case TAG_MPEG4_SubdivisionSurface: + return SubdivisionSurface_Create(); + case TAG_MPEG4_SubdivSurfaceSector: + return SubdivSurfaceSector_Create(); + case TAG_MPEG4_WaveletSubdivisionSurface: + return WaveletSubdivisionSurface_Create(); case TAG_MPEG4_Clipper2D: return Clipper2D_Create(); case TAG_MPEG4_ColorTransform: @@ -19450,6 +36260,8 @@ GF_Node *gf_sg_mpeg4_node_new(u32 NodeTag) return PathLayout_Create(); case TAG_MPEG4_RadialGradient: return RadialGradient_Create(); + case TAG_MPEG4_SynthesizedTexture: + return SynthesizedTexture_Create(); case TAG_MPEG4_TransformMatrix2D: return TransformMatrix2D_Create(); case TAG_MPEG4_Viewport: @@ -19460,6 +36272,54 @@ GF_Node *gf_sg_mpeg4_node_new(u32 NodeTag) return XFontStyle_Create(); case TAG_MPEG4_XLineProperties: return XLineProperties_Create(); + case TAG_MPEG4_AdvancedAudioBuffer: + return AdvancedAudioBuffer_Create(); + case TAG_MPEG4_AudioChannelConfig: + return AudioChannelConfig_Create(); + case TAG_MPEG4_DepthImageV2: + return DepthImageV2_Create(); + case TAG_MPEG4_MorphShape: + return MorphShape_Create(); + case TAG_MPEG4_MultiTexture: + return MultiTexture_Create(); + case TAG_MPEG4_PointTextureV2: + return PointTextureV2_Create(); + case TAG_MPEG4_SBVCAnimationV2: + return SBVCAnimationV2_Create(); + case TAG_MPEG4_SimpleTextureV2: + return SimpleTextureV2_Create(); + case TAG_MPEG4_SurroundingSound: + return SurroundingSound_Create(); + case TAG_MPEG4_Transform3DAudio: + return Transform3DAudio_Create(); + case TAG_MPEG4_WideSound: + return WideSound_Create(); + case TAG_MPEG4_ScoreShape: + return ScoreShape_Create(); + case TAG_MPEG4_MusicScore: + return MusicScore_Create(); + case TAG_MPEG4_FootPrintSetNode: + return FootPrintSetNode_Create(); + case TAG_MPEG4_FootPrintNode: + return FootPrintNode_Create(); + case TAG_MPEG4_BuildingPartNode: + return BuildingPartNode_Create(); + case TAG_MPEG4_RoofNode: + return RoofNode_Create(); + case TAG_MPEG4_FacadeNode: + return FacadeNode_Create(); + case TAG_MPEG4_Shadow: + return Shadow_Create(); + case TAG_MPEG4_CacheTexture: + return CacheTexture_Create(); + case TAG_MPEG4_EnvironmentTest: + return EnvironmentTest_Create(); + case TAG_MPEG4_KeyNavigator: + return KeyNavigator_Create(); + case TAG_MPEG4_SpacePartition: + return SpacePartition_Create(); + case TAG_MPEG4_Storage: + return Storage_Create(); default: return NULL; } @@ -19534,8 +36394,24 @@ const char *gf_sg_mpeg4_node_get_class_name(u32 NodeTag) return "DiscSensor"; case TAG_MPEG4_ElevationGrid: return "ElevationGrid"; + case TAG_MPEG4_Expression: + return "Expression"; case TAG_MPEG4_Extrusion: return "Extrusion"; + case TAG_MPEG4_Face: + return "Face"; + case TAG_MPEG4_FaceDefMesh: + return "FaceDefMesh"; + case TAG_MPEG4_FaceDefTables: + return "FaceDefTables"; + case TAG_MPEG4_FaceDefTransform: + return "FaceDefTransform"; + case TAG_MPEG4_FAP: + return "FAP"; + case TAG_MPEG4_FDP: + return "FDP"; + case TAG_MPEG4_FIT: + return "FIT"; case TAG_MPEG4_Fog: return "Fog"; case TAG_MPEG4_FontStyle: @@ -19648,6 +36524,8 @@ const char *gf_sg_mpeg4_node_get_class_name(u32 NodeTag) return "Viewpoint"; case TAG_MPEG4_VisibilitySensor: return "VisibilitySensor"; + case TAG_MPEG4_Viseme: + return "Viseme"; case TAG_MPEG4_WorldInfo: return "WorldInfo"; case TAG_MPEG4_AcousticMaterial: @@ -19656,6 +36534,16 @@ const char *gf_sg_mpeg4_node_get_class_name(u32 NodeTag) return "AcousticScene"; case TAG_MPEG4_ApplicationWindow: return "ApplicationWindow"; + case TAG_MPEG4_BAP: + return "BAP"; + case TAG_MPEG4_BDP: + return "BDP"; + case TAG_MPEG4_Body: + return "Body"; + case TAG_MPEG4_BodyDefTable: + return "BodyDefTable"; + case TAG_MPEG4_BodySegmentConnectionHint: + return "BodySegmentConnectionHint"; case TAG_MPEG4_DirectiveSound: return "DirectiveSound"; case TAG_MPEG4_Hierarchical3DMesh: @@ -19680,18 +36568,84 @@ const char *gf_sg_mpeg4_node_get_class_name(u32 NodeTag) return "MediaControl"; case TAG_MPEG4_MediaSensor: return "MediaSensor"; + case TAG_MPEG4_BitWrapper: + return "BitWrapper"; case TAG_MPEG4_CoordinateInterpolator4D: return "CoordinateInterpolator4D"; + case TAG_MPEG4_DepthImage: + return "DepthImage"; + case TAG_MPEG4_FFD: + return "FFD"; + case TAG_MPEG4_Implicit: + return "Implicit"; + case TAG_MPEG4_XXLFM_Appearance: + return "XXLFM_Appearance"; + case TAG_MPEG4_XXLFM_BlendList: + return "XXLFM_BlendList"; + case TAG_MPEG4_XXLFM_FrameList: + return "XXLFM_FrameList"; + case TAG_MPEG4_XXLFM_LightMap: + return "XXLFM_LightMap"; + case TAG_MPEG4_XXLFM_SurfaceMapList: + return "XXLFM_SurfaceMapList"; + case TAG_MPEG4_XXLFM_ViewMapList: + return "XXLFM_ViewMapList"; + case TAG_MPEG4_MeshGrid: + return "MeshGrid"; case TAG_MPEG4_NonLinearDeformer: return "NonLinearDeformer"; + case TAG_MPEG4_NurbsCurve: + return "NurbsCurve"; + case TAG_MPEG4_NurbsCurve2D: + return "NurbsCurve2D"; + case TAG_MPEG4_NurbsSurface: + return "NurbsSurface"; + case TAG_MPEG4_OctreeImage: + return "OctreeImage"; + case TAG_MPEG4_XXParticles: + return "XXParticles"; + case TAG_MPEG4_XXParticleInitBox: + return "XXParticleInitBox"; + case TAG_MPEG4_XXPlanarObstacle: + return "XXPlanarObstacle"; + case TAG_MPEG4_XXPointAttractor: + return "XXPointAttractor"; + case TAG_MPEG4_PointTexture: + return "PointTexture"; case TAG_MPEG4_PositionAnimator: return "PositionAnimator"; case TAG_MPEG4_PositionAnimator2D: return "PositionAnimator2D"; case TAG_MPEG4_PositionInterpolator4D: return "PositionInterpolator4D"; + case TAG_MPEG4_ProceduralTexture: + return "ProceduralTexture"; + case TAG_MPEG4_Quadric: + return "Quadric"; + case TAG_MPEG4_SBBone: + return "SBBone"; + case TAG_MPEG4_SBMuscle: + return "SBMuscle"; + case TAG_MPEG4_SBSegment: + return "SBSegment"; + case TAG_MPEG4_SBSite: + return "SBSite"; + case TAG_MPEG4_SBSkinnedModel: + return "SBSkinnedModel"; + case TAG_MPEG4_SBVCAnimation: + return "SBVCAnimation"; case TAG_MPEG4_ScalarAnimator: return "ScalarAnimator"; + case TAG_MPEG4_SimpleTexture: + return "SimpleTexture"; + case TAG_MPEG4_SolidRep: + return "SolidRep"; + case TAG_MPEG4_SubdivisionSurface: + return "SubdivisionSurface"; + case TAG_MPEG4_SubdivSurfaceSector: + return "SubdivSurfaceSector"; + case TAG_MPEG4_WaveletSubdivisionSurface: + return "WaveletSubdivisionSurface"; case TAG_MPEG4_Clipper2D: return "Clipper2D"; case TAG_MPEG4_ColorTransform: @@ -19704,6 +36658,8 @@ const char *gf_sg_mpeg4_node_get_class_name(u32 NodeTag) return "PathLayout"; case TAG_MPEG4_RadialGradient: return "RadialGradient"; + case TAG_MPEG4_SynthesizedTexture: + return "SynthesizedTexture"; case TAG_MPEG4_TransformMatrix2D: return "TransformMatrix2D"; case TAG_MPEG4_Viewport: @@ -19714,6 +36670,54 @@ const char *gf_sg_mpeg4_node_get_class_name(u32 NodeTag) return "XFontStyle"; case TAG_MPEG4_XLineProperties: return "XLineProperties"; + case TAG_MPEG4_AdvancedAudioBuffer: + return "AdvancedAudioBuffer"; + case TAG_MPEG4_AudioChannelConfig: + return "AudioChannelConfig"; + case TAG_MPEG4_DepthImageV2: + return "DepthImageV2"; + case TAG_MPEG4_MorphShape: + return "MorphShape"; + case TAG_MPEG4_MultiTexture: + return "MultiTexture"; + case TAG_MPEG4_PointTextureV2: + return "PointTextureV2"; + case TAG_MPEG4_SBVCAnimationV2: + return "SBVCAnimationV2"; + case TAG_MPEG4_SimpleTextureV2: + return "SimpleTextureV2"; + case TAG_MPEG4_SurroundingSound: + return "SurroundingSound"; + case TAG_MPEG4_Transform3DAudio: + return "Transform3DAudio"; + case TAG_MPEG4_WideSound: + return "WideSound"; + case TAG_MPEG4_ScoreShape: + return "ScoreShape"; + case TAG_MPEG4_MusicScore: + return "MusicScore"; + case TAG_MPEG4_FootPrintSetNode: + return "FootPrintSetNode"; + case TAG_MPEG4_FootPrintNode: + return "FootPrintNode"; + case TAG_MPEG4_BuildingPartNode: + return "BuildingPartNode"; + case TAG_MPEG4_RoofNode: + return "RoofNode"; + case TAG_MPEG4_FacadeNode: + return "FacadeNode"; + case TAG_MPEG4_Shadow: + return "Shadow"; + case TAG_MPEG4_CacheTexture: + return "CacheTexture"; + case TAG_MPEG4_EnvironmentTest: + return "EnvironmentTest"; + case TAG_MPEG4_KeyNavigator: + return "KeyNavigator"; + case TAG_MPEG4_SpacePartition: + return "SpacePartition"; + case TAG_MPEG4_Storage: + return "Storage"; default: return "Unknown Node"; } @@ -19788,8 +36792,24 @@ void gf_sg_mpeg4_node_del(GF_Node *node) DiscSensor_Del(node); return; case TAG_MPEG4_ElevationGrid: ElevationGrid_Del(node); return; + case TAG_MPEG4_Expression: + Expression_Del(node); return; case TAG_MPEG4_Extrusion: Extrusion_Del(node); return; + case TAG_MPEG4_Face: + Face_Del(node); return; + case TAG_MPEG4_FaceDefMesh: + FaceDefMesh_Del(node); return; + case TAG_MPEG4_FaceDefTables: + FaceDefTables_Del(node); return; + case TAG_MPEG4_FaceDefTransform: + FaceDefTransform_Del(node); return; + case TAG_MPEG4_FAP: + FAP_Del(node); return; + case TAG_MPEG4_FDP: + FDP_Del(node); return; + case TAG_MPEG4_FIT: + FIT_Del(node); return; case TAG_MPEG4_Fog: Fog_Del(node); return; case TAG_MPEG4_FontStyle: @@ -19902,6 +36922,8 @@ void gf_sg_mpeg4_node_del(GF_Node *node) Viewpoint_Del(node); return; case TAG_MPEG4_VisibilitySensor: VisibilitySensor_Del(node); return; + case TAG_MPEG4_Viseme: + Viseme_Del(node); return; case TAG_MPEG4_WorldInfo: WorldInfo_Del(node); return; case TAG_MPEG4_AcousticMaterial: @@ -19910,6 +36932,16 @@ void gf_sg_mpeg4_node_del(GF_Node *node) AcousticScene_Del(node); return; case TAG_MPEG4_ApplicationWindow: ApplicationWindow_Del(node); return; + case TAG_MPEG4_BAP: + BAP_Del(node); return; + case TAG_MPEG4_BDP: + BDP_Del(node); return; + case TAG_MPEG4_Body: + Body_Del(node); return; + case TAG_MPEG4_BodyDefTable: + BodyDefTable_Del(node); return; + case TAG_MPEG4_BodySegmentConnectionHint: + BodySegmentConnectionHint_Del(node); return; case TAG_MPEG4_DirectiveSound: DirectiveSound_Del(node); return; case TAG_MPEG4_Hierarchical3DMesh: @@ -19934,18 +36966,84 @@ void gf_sg_mpeg4_node_del(GF_Node *node) MediaControl_Del(node); return; case TAG_MPEG4_MediaSensor: MediaSensor_Del(node); return; + case TAG_MPEG4_BitWrapper: + BitWrapper_Del(node); return; case TAG_MPEG4_CoordinateInterpolator4D: CoordinateInterpolator4D_Del(node); return; + case TAG_MPEG4_DepthImage: + DepthImage_Del(node); return; + case TAG_MPEG4_FFD: + FFD_Del(node); return; + case TAG_MPEG4_Implicit: + Implicit_Del(node); return; + case TAG_MPEG4_XXLFM_Appearance: + XXLFM_Appearance_Del(node); return; + case TAG_MPEG4_XXLFM_BlendList: + XXLFM_BlendList_Del(node); return; + case TAG_MPEG4_XXLFM_FrameList: + XXLFM_FrameList_Del(node); return; + case TAG_MPEG4_XXLFM_LightMap: + XXLFM_LightMap_Del(node); return; + case TAG_MPEG4_XXLFM_SurfaceMapList: + XXLFM_SurfaceMapList_Del(node); return; + case TAG_MPEG4_XXLFM_ViewMapList: + XXLFM_ViewMapList_Del(node); return; + case TAG_MPEG4_MeshGrid: + MeshGrid_Del(node); return; case TAG_MPEG4_NonLinearDeformer: NonLinearDeformer_Del(node); return; + case TAG_MPEG4_NurbsCurve: + NurbsCurve_Del(node); return; + case TAG_MPEG4_NurbsCurve2D: + NurbsCurve2D_Del(node); return; + case TAG_MPEG4_NurbsSurface: + NurbsSurface_Del(node); return; + case TAG_MPEG4_OctreeImage: + OctreeImage_Del(node); return; + case TAG_MPEG4_XXParticles: + XXParticles_Del(node); return; + case TAG_MPEG4_XXParticleInitBox: + XXParticleInitBox_Del(node); return; + case TAG_MPEG4_XXPlanarObstacle: + XXPlanarObstacle_Del(node); return; + case TAG_MPEG4_XXPointAttractor: + XXPointAttractor_Del(node); return; + case TAG_MPEG4_PointTexture: + PointTexture_Del(node); return; case TAG_MPEG4_PositionAnimator: PositionAnimator_Del(node); return; case TAG_MPEG4_PositionAnimator2D: PositionAnimator2D_Del(node); return; case TAG_MPEG4_PositionInterpolator4D: PositionInterpolator4D_Del(node); return; + case TAG_MPEG4_ProceduralTexture: + ProceduralTexture_Del(node); return; + case TAG_MPEG4_Quadric: + Quadric_Del(node); return; + case TAG_MPEG4_SBBone: + SBBone_Del(node); return; + case TAG_MPEG4_SBMuscle: + SBMuscle_Del(node); return; + case TAG_MPEG4_SBSegment: + SBSegment_Del(node); return; + case TAG_MPEG4_SBSite: + SBSite_Del(node); return; + case TAG_MPEG4_SBSkinnedModel: + SBSkinnedModel_Del(node); return; + case TAG_MPEG4_SBVCAnimation: + SBVCAnimation_Del(node); return; case TAG_MPEG4_ScalarAnimator: ScalarAnimator_Del(node); return; + case TAG_MPEG4_SimpleTexture: + SimpleTexture_Del(node); return; + case TAG_MPEG4_SolidRep: + SolidRep_Del(node); return; + case TAG_MPEG4_SubdivisionSurface: + SubdivisionSurface_Del(node); return; + case TAG_MPEG4_SubdivSurfaceSector: + SubdivSurfaceSector_Del(node); return; + case TAG_MPEG4_WaveletSubdivisionSurface: + WaveletSubdivisionSurface_Del(node); return; case TAG_MPEG4_Clipper2D: Clipper2D_Del(node); return; case TAG_MPEG4_ColorTransform: @@ -19958,6 +37056,8 @@ void gf_sg_mpeg4_node_del(GF_Node *node) PathLayout_Del(node); return; case TAG_MPEG4_RadialGradient: RadialGradient_Del(node); return; + case TAG_MPEG4_SynthesizedTexture: + SynthesizedTexture_Del(node); return; case TAG_MPEG4_TransformMatrix2D: TransformMatrix2D_Del(node); return; case TAG_MPEG4_Viewport: @@ -19968,6 +37068,54 @@ void gf_sg_mpeg4_node_del(GF_Node *node) XFontStyle_Del(node); return; case TAG_MPEG4_XLineProperties: XLineProperties_Del(node); return; + case TAG_MPEG4_AdvancedAudioBuffer: + AdvancedAudioBuffer_Del(node); return; + case TAG_MPEG4_AudioChannelConfig: + AudioChannelConfig_Del(node); return; + case TAG_MPEG4_DepthImageV2: + DepthImageV2_Del(node); return; + case TAG_MPEG4_MorphShape: + MorphShape_Del(node); return; + case TAG_MPEG4_MultiTexture: + MultiTexture_Del(node); return; + case TAG_MPEG4_PointTextureV2: + PointTextureV2_Del(node); return; + case TAG_MPEG4_SBVCAnimationV2: + SBVCAnimationV2_Del(node); return; + case TAG_MPEG4_SimpleTextureV2: + SimpleTextureV2_Del(node); return; + case TAG_MPEG4_SurroundingSound: + SurroundingSound_Del(node); return; + case TAG_MPEG4_Transform3DAudio: + Transform3DAudio_Del(node); return; + case TAG_MPEG4_WideSound: + WideSound_Del(node); return; + case TAG_MPEG4_ScoreShape: + ScoreShape_Del(node); return; + case TAG_MPEG4_MusicScore: + MusicScore_Del(node); return; + case TAG_MPEG4_FootPrintSetNode: + FootPrintSetNode_Del(node); return; + case TAG_MPEG4_FootPrintNode: + FootPrintNode_Del(node); return; + case TAG_MPEG4_BuildingPartNode: + BuildingPartNode_Del(node); return; + case TAG_MPEG4_RoofNode: + RoofNode_Del(node); return; + case TAG_MPEG4_FacadeNode: + FacadeNode_Del(node); return; + case TAG_MPEG4_Shadow: + Shadow_Del(node); return; + case TAG_MPEG4_CacheTexture: + CacheTexture_Del(node); return; + case TAG_MPEG4_EnvironmentTest: + EnvironmentTest_Del(node); return; + case TAG_MPEG4_KeyNavigator: + KeyNavigator_Del(node); return; + case TAG_MPEG4_SpacePartition: + SpacePartition_Del(node); return; + case TAG_MPEG4_Storage: + Storage_Del(node); return; default: return; } @@ -20009,7 +37157,15 @@ u32 gf_sg_mpeg4_node_get_field_count(GF_Node *node, u8 code_mode) case TAG_MPEG4_DirectionalLight:return DirectionalLight_get_field_count(node, code_mode); case TAG_MPEG4_DiscSensor:return DiscSensor_get_field_count(node, code_mode); case TAG_MPEG4_ElevationGrid:return ElevationGrid_get_field_count(node, code_mode); + case TAG_MPEG4_Expression:return Expression_get_field_count(node, code_mode); case TAG_MPEG4_Extrusion:return Extrusion_get_field_count(node, code_mode); + case TAG_MPEG4_Face:return Face_get_field_count(node, code_mode); + case TAG_MPEG4_FaceDefMesh:return FaceDefMesh_get_field_count(node, code_mode); + case TAG_MPEG4_FaceDefTables:return FaceDefTables_get_field_count(node, code_mode); + case TAG_MPEG4_FaceDefTransform:return FaceDefTransform_get_field_count(node, code_mode); + case TAG_MPEG4_FAP:return FAP_get_field_count(node, code_mode); + case TAG_MPEG4_FDP:return FDP_get_field_count(node, code_mode); + case TAG_MPEG4_FIT:return FIT_get_field_count(node, code_mode); case TAG_MPEG4_Fog:return Fog_get_field_count(node, code_mode); case TAG_MPEG4_FontStyle:return FontStyle_get_field_count(node, code_mode); case TAG_MPEG4_Form:return Form_get_field_count(node, code_mode); @@ -20066,10 +37222,16 @@ u32 gf_sg_mpeg4_node_get_field_count(GF_Node *node, u8 code_mode) case TAG_MPEG4_Valuator:return Valuator_get_field_count(node, code_mode); case TAG_MPEG4_Viewpoint:return Viewpoint_get_field_count(node, code_mode); case TAG_MPEG4_VisibilitySensor:return VisibilitySensor_get_field_count(node, code_mode); + case TAG_MPEG4_Viseme:return Viseme_get_field_count(node, code_mode); case TAG_MPEG4_WorldInfo:return WorldInfo_get_field_count(node, code_mode); case TAG_MPEG4_AcousticMaterial:return AcousticMaterial_get_field_count(node, code_mode); case TAG_MPEG4_AcousticScene:return AcousticScene_get_field_count(node, code_mode); case TAG_MPEG4_ApplicationWindow:return ApplicationWindow_get_field_count(node, code_mode); + case TAG_MPEG4_BAP:return BAP_get_field_count(node, code_mode); + case TAG_MPEG4_BDP:return BDP_get_field_count(node, code_mode); + case TAG_MPEG4_Body:return Body_get_field_count(node, code_mode); + case TAG_MPEG4_BodyDefTable:return BodyDefTable_get_field_count(node, code_mode); + case TAG_MPEG4_BodySegmentConnectionHint:return BodySegmentConnectionHint_get_field_count(node, code_mode); case TAG_MPEG4_DirectiveSound:return DirectiveSound_get_field_count(node, code_mode); case TAG_MPEG4_Hierarchical3DMesh:return Hierarchical3DMesh_get_field_count(node, code_mode); case TAG_MPEG4_MaterialKey:return MaterialKey_get_field_count(node, code_mode); @@ -20082,23 +37244,81 @@ u32 gf_sg_mpeg4_node_get_field_count(GF_Node *node, u8 code_mode) case TAG_MPEG4_MediaBuffer:return MediaBuffer_get_field_count(node, code_mode); case TAG_MPEG4_MediaControl:return MediaControl_get_field_count(node, code_mode); case TAG_MPEG4_MediaSensor:return MediaSensor_get_field_count(node, code_mode); + case TAG_MPEG4_BitWrapper:return BitWrapper_get_field_count(node, code_mode); case TAG_MPEG4_CoordinateInterpolator4D:return CoordinateInterpolator4D_get_field_count(node, code_mode); + case TAG_MPEG4_DepthImage:return DepthImage_get_field_count(node, code_mode); + case TAG_MPEG4_FFD:return FFD_get_field_count(node, code_mode); + case TAG_MPEG4_Implicit:return Implicit_get_field_count(node, code_mode); + case TAG_MPEG4_XXLFM_Appearance:return XXLFM_Appearance_get_field_count(node, code_mode); + case TAG_MPEG4_XXLFM_BlendList:return XXLFM_BlendList_get_field_count(node, code_mode); + case TAG_MPEG4_XXLFM_FrameList:return XXLFM_FrameList_get_field_count(node, code_mode); + case TAG_MPEG4_XXLFM_LightMap:return XXLFM_LightMap_get_field_count(node, code_mode); + case TAG_MPEG4_XXLFM_SurfaceMapList:return XXLFM_SurfaceMapList_get_field_count(node, code_mode); + case TAG_MPEG4_XXLFM_ViewMapList:return XXLFM_ViewMapList_get_field_count(node, code_mode); + case TAG_MPEG4_MeshGrid:return MeshGrid_get_field_count(node, code_mode); case TAG_MPEG4_NonLinearDeformer:return NonLinearDeformer_get_field_count(node, code_mode); + case TAG_MPEG4_NurbsCurve:return NurbsCurve_get_field_count(node, code_mode); + case TAG_MPEG4_NurbsCurve2D:return NurbsCurve2D_get_field_count(node, code_mode); + case TAG_MPEG4_NurbsSurface:return NurbsSurface_get_field_count(node, code_mode); + case TAG_MPEG4_OctreeImage:return OctreeImage_get_field_count(node, code_mode); + case TAG_MPEG4_XXParticles:return XXParticles_get_field_count(node, code_mode); + case TAG_MPEG4_XXParticleInitBox:return XXParticleInitBox_get_field_count(node, code_mode); + case TAG_MPEG4_XXPlanarObstacle:return XXPlanarObstacle_get_field_count(node, code_mode); + case TAG_MPEG4_XXPointAttractor:return XXPointAttractor_get_field_count(node, code_mode); + case TAG_MPEG4_PointTexture:return PointTexture_get_field_count(node, code_mode); case TAG_MPEG4_PositionAnimator:return PositionAnimator_get_field_count(node, code_mode); case TAG_MPEG4_PositionAnimator2D:return PositionAnimator2D_get_field_count(node, code_mode); case TAG_MPEG4_PositionInterpolator4D:return PositionInterpolator4D_get_field_count(node, code_mode); + case TAG_MPEG4_ProceduralTexture:return ProceduralTexture_get_field_count(node, code_mode); + case TAG_MPEG4_Quadric:return Quadric_get_field_count(node, code_mode); + case TAG_MPEG4_SBBone:return SBBone_get_field_count(node, code_mode); + case TAG_MPEG4_SBMuscle:return SBMuscle_get_field_count(node, code_mode); + case TAG_MPEG4_SBSegment:return SBSegment_get_field_count(node, code_mode); + case TAG_MPEG4_SBSite:return SBSite_get_field_count(node, code_mode); + case TAG_MPEG4_SBSkinnedModel:return SBSkinnedModel_get_field_count(node, code_mode); + case TAG_MPEG4_SBVCAnimation:return SBVCAnimation_get_field_count(node, code_mode); case TAG_MPEG4_ScalarAnimator:return ScalarAnimator_get_field_count(node, code_mode); + case TAG_MPEG4_SimpleTexture:return SimpleTexture_get_field_count(node, code_mode); + case TAG_MPEG4_SolidRep:return SolidRep_get_field_count(node, code_mode); + case TAG_MPEG4_SubdivisionSurface:return SubdivisionSurface_get_field_count(node, code_mode); + case TAG_MPEG4_SubdivSurfaceSector:return SubdivSurfaceSector_get_field_count(node, code_mode); + case TAG_MPEG4_WaveletSubdivisionSurface:return WaveletSubdivisionSurface_get_field_count(node, code_mode); case TAG_MPEG4_Clipper2D:return Clipper2D_get_field_count(node, code_mode); case TAG_MPEG4_ColorTransform:return ColorTransform_get_field_count(node, code_mode); case TAG_MPEG4_Ellipse:return Ellipse_get_field_count(node, code_mode); case TAG_MPEG4_LinearGradient:return LinearGradient_get_field_count(node, code_mode); case TAG_MPEG4_PathLayout:return PathLayout_get_field_count(node, code_mode); case TAG_MPEG4_RadialGradient:return RadialGradient_get_field_count(node, code_mode); + case TAG_MPEG4_SynthesizedTexture:return SynthesizedTexture_get_field_count(node, code_mode); case TAG_MPEG4_TransformMatrix2D:return TransformMatrix2D_get_field_count(node, code_mode); case TAG_MPEG4_Viewport:return Viewport_get_field_count(node, code_mode); case TAG_MPEG4_XCurve2D:return XCurve2D_get_field_count(node, code_mode); case TAG_MPEG4_XFontStyle:return XFontStyle_get_field_count(node, code_mode); case TAG_MPEG4_XLineProperties:return XLineProperties_get_field_count(node, code_mode); + case TAG_MPEG4_AdvancedAudioBuffer:return AdvancedAudioBuffer_get_field_count(node, code_mode); + case TAG_MPEG4_AudioChannelConfig:return AudioChannelConfig_get_field_count(node, code_mode); + case TAG_MPEG4_DepthImageV2:return DepthImageV2_get_field_count(node, code_mode); + case TAG_MPEG4_MorphShape:return MorphShape_get_field_count(node, code_mode); + case TAG_MPEG4_MultiTexture:return MultiTexture_get_field_count(node, code_mode); + case TAG_MPEG4_PointTextureV2:return PointTextureV2_get_field_count(node, code_mode); + case TAG_MPEG4_SBVCAnimationV2:return SBVCAnimationV2_get_field_count(node, code_mode); + case TAG_MPEG4_SimpleTextureV2:return SimpleTextureV2_get_field_count(node, code_mode); + case TAG_MPEG4_SurroundingSound:return SurroundingSound_get_field_count(node, code_mode); + case TAG_MPEG4_Transform3DAudio:return Transform3DAudio_get_field_count(node, code_mode); + case TAG_MPEG4_WideSound:return WideSound_get_field_count(node, code_mode); + case TAG_MPEG4_ScoreShape:return ScoreShape_get_field_count(node, code_mode); + case TAG_MPEG4_MusicScore:return MusicScore_get_field_count(node, code_mode); + case TAG_MPEG4_FootPrintSetNode:return FootPrintSetNode_get_field_count(node, code_mode); + case TAG_MPEG4_FootPrintNode:return FootPrintNode_get_field_count(node, code_mode); + case TAG_MPEG4_BuildingPartNode:return BuildingPartNode_get_field_count(node, code_mode); + case TAG_MPEG4_RoofNode:return RoofNode_get_field_count(node, code_mode); + case TAG_MPEG4_FacadeNode:return FacadeNode_get_field_count(node, code_mode); + case TAG_MPEG4_Shadow:return Shadow_get_field_count(node, code_mode); + case TAG_MPEG4_CacheTexture:return CacheTexture_get_field_count(node, code_mode); + case TAG_MPEG4_EnvironmentTest:return EnvironmentTest_get_field_count(node, code_mode); + case TAG_MPEG4_KeyNavigator:return KeyNavigator_get_field_count(node, code_mode); + case TAG_MPEG4_SpacePartition:return SpacePartition_get_field_count(node, code_mode); + case TAG_MPEG4_Storage:return Storage_get_field_count(node, code_mode); default: return 0; } @@ -20140,7 +37360,15 @@ GF_Err gf_sg_mpeg4_node_get_field(GF_Node *node, GF_FieldInfo *field) case TAG_MPEG4_DirectionalLight: return DirectionalLight_get_field(node, field); case TAG_MPEG4_DiscSensor: return DiscSensor_get_field(node, field); case TAG_MPEG4_ElevationGrid: return ElevationGrid_get_field(node, field); + case TAG_MPEG4_Expression: return Expression_get_field(node, field); case TAG_MPEG4_Extrusion: return Extrusion_get_field(node, field); + case TAG_MPEG4_Face: return Face_get_field(node, field); + case TAG_MPEG4_FaceDefMesh: return FaceDefMesh_get_field(node, field); + case TAG_MPEG4_FaceDefTables: return FaceDefTables_get_field(node, field); + case TAG_MPEG4_FaceDefTransform: return FaceDefTransform_get_field(node, field); + case TAG_MPEG4_FAP: return FAP_get_field(node, field); + case TAG_MPEG4_FDP: return FDP_get_field(node, field); + case TAG_MPEG4_FIT: return FIT_get_field(node, field); case TAG_MPEG4_Fog: return Fog_get_field(node, field); case TAG_MPEG4_FontStyle: return FontStyle_get_field(node, field); case TAG_MPEG4_Form: return Form_get_field(node, field); @@ -20197,10 +37425,16 @@ GF_Err gf_sg_mpeg4_node_get_field(GF_Node *node, GF_FieldInfo *field) case TAG_MPEG4_Valuator: return Valuator_get_field(node, field); case TAG_MPEG4_Viewpoint: return Viewpoint_get_field(node, field); case TAG_MPEG4_VisibilitySensor: return VisibilitySensor_get_field(node, field); + case TAG_MPEG4_Viseme: return Viseme_get_field(node, field); case TAG_MPEG4_WorldInfo: return WorldInfo_get_field(node, field); case TAG_MPEG4_AcousticMaterial: return AcousticMaterial_get_field(node, field); case TAG_MPEG4_AcousticScene: return AcousticScene_get_field(node, field); case TAG_MPEG4_ApplicationWindow: return ApplicationWindow_get_field(node, field); + case TAG_MPEG4_BAP: return BAP_get_field(node, field); + case TAG_MPEG4_BDP: return BDP_get_field(node, field); + case TAG_MPEG4_Body: return Body_get_field(node, field); + case TAG_MPEG4_BodyDefTable: return BodyDefTable_get_field(node, field); + case TAG_MPEG4_BodySegmentConnectionHint: return BodySegmentConnectionHint_get_field(node, field); case TAG_MPEG4_DirectiveSound: return DirectiveSound_get_field(node, field); case TAG_MPEG4_Hierarchical3DMesh: return Hierarchical3DMesh_get_field(node, field); case TAG_MPEG4_MaterialKey: return MaterialKey_get_field(node, field); @@ -20213,23 +37447,81 @@ GF_Err gf_sg_mpeg4_node_get_field(GF_Node *node, GF_FieldInfo *field) case TAG_MPEG4_MediaBuffer: return MediaBuffer_get_field(node, field); case TAG_MPEG4_MediaControl: return MediaControl_get_field(node, field); case TAG_MPEG4_MediaSensor: return MediaSensor_get_field(node, field); + case TAG_MPEG4_BitWrapper: return BitWrapper_get_field(node, field); case TAG_MPEG4_CoordinateInterpolator4D: return CoordinateInterpolator4D_get_field(node, field); + case TAG_MPEG4_DepthImage: return DepthImage_get_field(node, field); + case TAG_MPEG4_FFD: return FFD_get_field(node, field); + case TAG_MPEG4_Implicit: return Implicit_get_field(node, field); + case TAG_MPEG4_XXLFM_Appearance: return XXLFM_Appearance_get_field(node, field); + case TAG_MPEG4_XXLFM_BlendList: return XXLFM_BlendList_get_field(node, field); + case TAG_MPEG4_XXLFM_FrameList: return XXLFM_FrameList_get_field(node, field); + case TAG_MPEG4_XXLFM_LightMap: return XXLFM_LightMap_get_field(node, field); + case TAG_MPEG4_XXLFM_SurfaceMapList: return XXLFM_SurfaceMapList_get_field(node, field); + case TAG_MPEG4_XXLFM_ViewMapList: return XXLFM_ViewMapList_get_field(node, field); + case TAG_MPEG4_MeshGrid: return MeshGrid_get_field(node, field); case TAG_MPEG4_NonLinearDeformer: return NonLinearDeformer_get_field(node, field); + case TAG_MPEG4_NurbsCurve: return NurbsCurve_get_field(node, field); + case TAG_MPEG4_NurbsCurve2D: return NurbsCurve2D_get_field(node, field); + case TAG_MPEG4_NurbsSurface: return NurbsSurface_get_field(node, field); + case TAG_MPEG4_OctreeImage: return OctreeImage_get_field(node, field); + case TAG_MPEG4_XXParticles: return XXParticles_get_field(node, field); + case TAG_MPEG4_XXParticleInitBox: return XXParticleInitBox_get_field(node, field); + case TAG_MPEG4_XXPlanarObstacle: return XXPlanarObstacle_get_field(node, field); + case TAG_MPEG4_XXPointAttractor: return XXPointAttractor_get_field(node, field); + case TAG_MPEG4_PointTexture: return PointTexture_get_field(node, field); case TAG_MPEG4_PositionAnimator: return PositionAnimator_get_field(node, field); case TAG_MPEG4_PositionAnimator2D: return PositionAnimator2D_get_field(node, field); case TAG_MPEG4_PositionInterpolator4D: return PositionInterpolator4D_get_field(node, field); + case TAG_MPEG4_ProceduralTexture: return ProceduralTexture_get_field(node, field); + case TAG_MPEG4_Quadric: return Quadric_get_field(node, field); + case TAG_MPEG4_SBBone: return SBBone_get_field(node, field); + case TAG_MPEG4_SBMuscle: return SBMuscle_get_field(node, field); + case TAG_MPEG4_SBSegment: return SBSegment_get_field(node, field); + case TAG_MPEG4_SBSite: return SBSite_get_field(node, field); + case TAG_MPEG4_SBSkinnedModel: return SBSkinnedModel_get_field(node, field); + case TAG_MPEG4_SBVCAnimation: return SBVCAnimation_get_field(node, field); case TAG_MPEG4_ScalarAnimator: return ScalarAnimator_get_field(node, field); + case TAG_MPEG4_SimpleTexture: return SimpleTexture_get_field(node, field); + case TAG_MPEG4_SolidRep: return SolidRep_get_field(node, field); + case TAG_MPEG4_SubdivisionSurface: return SubdivisionSurface_get_field(node, field); + case TAG_MPEG4_SubdivSurfaceSector: return SubdivSurfaceSector_get_field(node, field); + case TAG_MPEG4_WaveletSubdivisionSurface: return WaveletSubdivisionSurface_get_field(node, field); case TAG_MPEG4_Clipper2D: return Clipper2D_get_field(node, field); case TAG_MPEG4_ColorTransform: return ColorTransform_get_field(node, field); case TAG_MPEG4_Ellipse: return Ellipse_get_field(node, field); case TAG_MPEG4_LinearGradient: return LinearGradient_get_field(node, field); case TAG_MPEG4_PathLayout: return PathLayout_get_field(node, field); case TAG_MPEG4_RadialGradient: return RadialGradient_get_field(node, field); + case TAG_MPEG4_SynthesizedTexture: return SynthesizedTexture_get_field(node, field); case TAG_MPEG4_TransformMatrix2D: return TransformMatrix2D_get_field(node, field); case TAG_MPEG4_Viewport: return Viewport_get_field(node, field); case TAG_MPEG4_XCurve2D: return XCurve2D_get_field(node, field); case TAG_MPEG4_XFontStyle: return XFontStyle_get_field(node, field); case TAG_MPEG4_XLineProperties: return XLineProperties_get_field(node, field); + case TAG_MPEG4_AdvancedAudioBuffer: return AdvancedAudioBuffer_get_field(node, field); + case TAG_MPEG4_AudioChannelConfig: return AudioChannelConfig_get_field(node, field); + case TAG_MPEG4_DepthImageV2: return DepthImageV2_get_field(node, field); + case TAG_MPEG4_MorphShape: return MorphShape_get_field(node, field); + case TAG_MPEG4_MultiTexture: return MultiTexture_get_field(node, field); + case TAG_MPEG4_PointTextureV2: return PointTextureV2_get_field(node, field); + case TAG_MPEG4_SBVCAnimationV2: return SBVCAnimationV2_get_field(node, field); + case TAG_MPEG4_SimpleTextureV2: return SimpleTextureV2_get_field(node, field); + case TAG_MPEG4_SurroundingSound: return SurroundingSound_get_field(node, field); + case TAG_MPEG4_Transform3DAudio: return Transform3DAudio_get_field(node, field); + case TAG_MPEG4_WideSound: return WideSound_get_field(node, field); + case TAG_MPEG4_ScoreShape: return ScoreShape_get_field(node, field); + case TAG_MPEG4_MusicScore: return MusicScore_get_field(node, field); + case TAG_MPEG4_FootPrintSetNode: return FootPrintSetNode_get_field(node, field); + case TAG_MPEG4_FootPrintNode: return FootPrintNode_get_field(node, field); + case TAG_MPEG4_BuildingPartNode: return BuildingPartNode_get_field(node, field); + case TAG_MPEG4_RoofNode: return RoofNode_get_field(node, field); + case TAG_MPEG4_FacadeNode: return FacadeNode_get_field(node, field); + case TAG_MPEG4_Shadow: return Shadow_get_field(node, field); + case TAG_MPEG4_CacheTexture: return CacheTexture_get_field(node, field); + case TAG_MPEG4_EnvironmentTest: return EnvironmentTest_get_field(node, field); + case TAG_MPEG4_KeyNavigator: return KeyNavigator_get_field(node, field); + case TAG_MPEG4_SpacePartition: return SpacePartition_get_field(node, field); + case TAG_MPEG4_Storage: return Storage_get_field(node, field); default: return GF_BAD_PARAM; } @@ -20271,7 +37563,15 @@ GF_Err gf_sg_mpeg4_node_get_field_index(GF_Node *node, u32 inField, u8 code_mode case TAG_MPEG4_DirectionalLight: return DirectionalLight_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_DiscSensor: return DiscSensor_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_ElevationGrid: return ElevationGrid_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_Expression: return Expression_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_Extrusion: return Extrusion_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_Face: return Face_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FaceDefMesh: return FaceDefMesh_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FaceDefTables: return FaceDefTables_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FaceDefTransform: return FaceDefTransform_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FAP: return FAP_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FDP: return FDP_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FIT: return FIT_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_Fog: return Fog_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_FontStyle: return FontStyle_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_Form: return Form_get_field_index(node, inField, code_mode, fieldIndex); @@ -20328,10 +37628,16 @@ GF_Err gf_sg_mpeg4_node_get_field_index(GF_Node *node, u32 inField, u8 code_mode case TAG_MPEG4_Valuator: return Valuator_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_Viewpoint: return Viewpoint_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_VisibilitySensor: return VisibilitySensor_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_Viseme: return Viseme_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_WorldInfo: return WorldInfo_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_AcousticMaterial: return AcousticMaterial_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_AcousticScene: return AcousticScene_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_ApplicationWindow: return ApplicationWindow_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_BAP: return BAP_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_BDP: return BDP_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_Body: return Body_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_BodyDefTable: return BodyDefTable_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_BodySegmentConnectionHint: return BodySegmentConnectionHint_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_DirectiveSound: return DirectiveSound_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_Hierarchical3DMesh: return Hierarchical3DMesh_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_MaterialKey: return MaterialKey_get_field_index(node, inField, code_mode, fieldIndex); @@ -20344,23 +37650,81 @@ GF_Err gf_sg_mpeg4_node_get_field_index(GF_Node *node, u32 inField, u8 code_mode case TAG_MPEG4_MediaBuffer: return MediaBuffer_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_MediaControl: return MediaControl_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_MediaSensor: return MediaSensor_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_BitWrapper: return BitWrapper_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_CoordinateInterpolator4D: return CoordinateInterpolator4D_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_DepthImage: return DepthImage_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FFD: return FFD_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_Implicit: return Implicit_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXLFM_Appearance: return XXLFM_Appearance_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXLFM_BlendList: return XXLFM_BlendList_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXLFM_FrameList: return XXLFM_FrameList_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXLFM_LightMap: return XXLFM_LightMap_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXLFM_SurfaceMapList: return XXLFM_SurfaceMapList_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXLFM_ViewMapList: return XXLFM_ViewMapList_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_MeshGrid: return MeshGrid_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_NonLinearDeformer: return NonLinearDeformer_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_NurbsCurve: return NurbsCurve_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_NurbsCurve2D: return NurbsCurve2D_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_NurbsSurface: return NurbsSurface_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_OctreeImage: return OctreeImage_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXParticles: return XXParticles_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXParticleInitBox: return XXParticleInitBox_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXPlanarObstacle: return XXPlanarObstacle_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_XXPointAttractor: return XXPointAttractor_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_PointTexture: return PointTexture_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_PositionAnimator: return PositionAnimator_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_PositionAnimator2D: return PositionAnimator2D_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_PositionInterpolator4D: return PositionInterpolator4D_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_ProceduralTexture: return ProceduralTexture_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_Quadric: return Quadric_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SBBone: return SBBone_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SBMuscle: return SBMuscle_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SBSegment: return SBSegment_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SBSite: return SBSite_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SBSkinnedModel: return SBSkinnedModel_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SBVCAnimation: return SBVCAnimation_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_ScalarAnimator: return ScalarAnimator_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SimpleTexture: return SimpleTexture_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SolidRep: return SolidRep_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SubdivisionSurface: return SubdivisionSurface_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SubdivSurfaceSector: return SubdivSurfaceSector_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_WaveletSubdivisionSurface: return WaveletSubdivisionSurface_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_Clipper2D: return Clipper2D_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_ColorTransform: return ColorTransform_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_Ellipse: return Ellipse_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_LinearGradient: return LinearGradient_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_PathLayout: return PathLayout_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_RadialGradient: return RadialGradient_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SynthesizedTexture: return SynthesizedTexture_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_TransformMatrix2D: return TransformMatrix2D_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_Viewport: return Viewport_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_XCurve2D: return XCurve2D_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_XFontStyle: return XFontStyle_get_field_index(node, inField, code_mode, fieldIndex); case TAG_MPEG4_XLineProperties: return XLineProperties_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_AdvancedAudioBuffer: return AdvancedAudioBuffer_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_AudioChannelConfig: return AudioChannelConfig_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_DepthImageV2: return DepthImageV2_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_MorphShape: return MorphShape_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_MultiTexture: return MultiTexture_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_PointTextureV2: return PointTextureV2_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SBVCAnimationV2: return SBVCAnimationV2_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SimpleTextureV2: return SimpleTextureV2_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SurroundingSound: return SurroundingSound_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_Transform3DAudio: return Transform3DAudio_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_WideSound: return WideSound_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_ScoreShape: return ScoreShape_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_MusicScore: return MusicScore_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FootPrintSetNode: return FootPrintSetNode_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FootPrintNode: return FootPrintNode_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_BuildingPartNode: return BuildingPartNode_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_RoofNode: return RoofNode_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_FacadeNode: return FacadeNode_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_Shadow: return Shadow_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_CacheTexture: return CacheTexture_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_EnvironmentTest: return EnvironmentTest_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_KeyNavigator: return KeyNavigator_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_SpacePartition: return SpacePartition_get_field_index(node, inField, code_mode, fieldIndex); + case TAG_MPEG4_Storage: return Storage_get_field_index(node, inField, code_mode, fieldIndex); default: return GF_BAD_PARAM; } @@ -20402,7 +37766,15 @@ Bool gf_sg_mpeg4_node_get_aq_info(GF_Node *node, u32 FieldIndex, u8 *QType, u8 * case TAG_MPEG4_DirectionalLight: return DirectionalLight_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_DiscSensor: return DiscSensor_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_ElevationGrid: return ElevationGrid_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_Expression: return Expression_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_Extrusion: return Extrusion_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_Face: return Face_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FaceDefMesh: return FaceDefMesh_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FaceDefTables: return FaceDefTables_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FaceDefTransform: return FaceDefTransform_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FAP: return FAP_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FDP: return FDP_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FIT: return FIT_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_Fog: return Fog_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_FontStyle: return FontStyle_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_Form: return Form_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); @@ -20459,10 +37831,16 @@ Bool gf_sg_mpeg4_node_get_aq_info(GF_Node *node, u32 FieldIndex, u8 *QType, u8 * case TAG_MPEG4_Valuator: return Valuator_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_Viewpoint: return Viewpoint_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_VisibilitySensor: return VisibilitySensor_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_Viseme: return Viseme_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_WorldInfo: return WorldInfo_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_AcousticMaterial: return AcousticMaterial_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_AcousticScene: return AcousticScene_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_ApplicationWindow: return ApplicationWindow_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_BAP: return BAP_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_BDP: return BDP_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_Body: return Body_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_BodyDefTable: return BodyDefTable_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_BodySegmentConnectionHint: return BodySegmentConnectionHint_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_DirectiveSound: return DirectiveSound_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_Hierarchical3DMesh: return Hierarchical3DMesh_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_MaterialKey: return MaterialKey_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); @@ -20475,23 +37853,81 @@ Bool gf_sg_mpeg4_node_get_aq_info(GF_Node *node, u32 FieldIndex, u8 *QType, u8 * case TAG_MPEG4_MediaBuffer: return MediaBuffer_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_MediaControl: return MediaControl_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_MediaSensor: return MediaSensor_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_BitWrapper: return BitWrapper_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_CoordinateInterpolator4D: return CoordinateInterpolator4D_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_DepthImage: return DepthImage_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FFD: return FFD_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_Implicit: return Implicit_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXLFM_Appearance: return XXLFM_Appearance_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXLFM_BlendList: return XXLFM_BlendList_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXLFM_FrameList: return XXLFM_FrameList_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXLFM_LightMap: return XXLFM_LightMap_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXLFM_SurfaceMapList: return XXLFM_SurfaceMapList_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXLFM_ViewMapList: return XXLFM_ViewMapList_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_MeshGrid: return MeshGrid_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_NonLinearDeformer: return NonLinearDeformer_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_NurbsCurve: return NurbsCurve_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_NurbsCurve2D: return NurbsCurve2D_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_NurbsSurface: return NurbsSurface_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_OctreeImage: return OctreeImage_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXParticles: return XXParticles_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXParticleInitBox: return XXParticleInitBox_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXPlanarObstacle: return XXPlanarObstacle_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_XXPointAttractor: return XXPointAttractor_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_PointTexture: return PointTexture_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_PositionAnimator: return PositionAnimator_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_PositionAnimator2D: return PositionAnimator2D_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_PositionInterpolator4D: return PositionInterpolator4D_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_ProceduralTexture: return ProceduralTexture_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_Quadric: return Quadric_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SBBone: return SBBone_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SBMuscle: return SBMuscle_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SBSegment: return SBSegment_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SBSite: return SBSite_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SBSkinnedModel: return SBSkinnedModel_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SBVCAnimation: return SBVCAnimation_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_ScalarAnimator: return ScalarAnimator_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SimpleTexture: return SimpleTexture_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SolidRep: return SolidRep_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SubdivisionSurface: return SubdivisionSurface_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SubdivSurfaceSector: return SubdivSurfaceSector_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_WaveletSubdivisionSurface: return WaveletSubdivisionSurface_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_Clipper2D: return Clipper2D_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_ColorTransform: return ColorTransform_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_Ellipse: return Ellipse_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_LinearGradient: return LinearGradient_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_PathLayout: return PathLayout_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_RadialGradient: return RadialGradient_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SynthesizedTexture: return SynthesizedTexture_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_TransformMatrix2D: return TransformMatrix2D_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_Viewport: return Viewport_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_XCurve2D: return XCurve2D_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_XFontStyle: return XFontStyle_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); case TAG_MPEG4_XLineProperties: return XLineProperties_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_AdvancedAudioBuffer: return AdvancedAudioBuffer_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_AudioChannelConfig: return AudioChannelConfig_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_DepthImageV2: return DepthImageV2_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_MorphShape: return MorphShape_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_MultiTexture: return MultiTexture_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_PointTextureV2: return PointTextureV2_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SBVCAnimationV2: return SBVCAnimationV2_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SimpleTextureV2: return SimpleTextureV2_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SurroundingSound: return SurroundingSound_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_Transform3DAudio: return Transform3DAudio_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_WideSound: return WideSound_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_ScoreShape: return ScoreShape_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_MusicScore: return MusicScore_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FootPrintSetNode: return FootPrintSetNode_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FootPrintNode: return FootPrintNode_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_BuildingPartNode: return BuildingPartNode_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_RoofNode: return RoofNode_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_FacadeNode: return FacadeNode_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_Shadow: return Shadow_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_CacheTexture: return CacheTexture_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_EnvironmentTest: return EnvironmentTest_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_KeyNavigator: return KeyNavigator_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_SpacePartition: return SpacePartition_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); + case TAG_MPEG4_Storage: return Storage_get_aq_info(node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); default: return 0; } @@ -20511,6 +37947,9 @@ u32 gf_sg_mpeg4_node_get_child_ndt(GF_Node *node) case TAG_MPEG4_Collision: return NDT_SF3DNode; case TAG_MPEG4_CompositeTexture2D: return NDT_SF2DNode; case TAG_MPEG4_CompositeTexture3D: return NDT_SF3DNode; + case TAG_MPEG4_Face: return NDT_SF3DNode; + case TAG_MPEG4_FaceDefTables: return NDT_SFFaceDefMeshNode; + case TAG_MPEG4_FDP: return NDT_SFFaceDefTablesNode; case TAG_MPEG4_Form: return NDT_SF2DNode; case TAG_MPEG4_Group: return NDT_SF3DNode; case TAG_MPEG4_LOD: return NDT_SF3DNode; @@ -20521,12 +37960,35 @@ u32 gf_sg_mpeg4_node_get_child_ndt(GF_Node *node) case TAG_MPEG4_Switch: return NDT_SF3DNode; case TAG_MPEG4_Transform: return NDT_SF3DNode; case TAG_MPEG4_Transform2D: return NDT_SF2DNode; + case TAG_MPEG4_BDP: return NDT_SFBodyDefTableNode; + case TAG_MPEG4_Body: return NDT_SF3DNode; case TAG_MPEG4_TemporalTransform: return NDT_SF3DNode; case TAG_MPEG4_TemporalGroup: return NDT_SFTemporalNode; + case TAG_MPEG4_FFD: return NDT_SF3DNode; + case TAG_MPEG4_XXLFM_Appearance: return NDT_SFLightMapNode; + case TAG_MPEG4_OctreeImage: return NDT_SFDepthImageNode; + case TAG_MPEG4_XXParticles: return NDT_SFInfluenceNode; + case TAG_MPEG4_SBBone: return NDT_SF3DNode; + case TAG_MPEG4_SBSegment: return NDT_SF3DNode; + case TAG_MPEG4_SBSite: return NDT_SF3DNode; + case TAG_MPEG4_SBSkinnedModel: return NDT_SFSBBoneNode; + case TAG_MPEG4_SBVCAnimation: return NDT_SF3DNode; + case TAG_MPEG4_SubdivisionSurface: return NDT_SFSubdivSurfaceSectorNode; case TAG_MPEG4_Clipper2D: return NDT_SF2DNode; case TAG_MPEG4_ColorTransform: return NDT_SF3DNode; case TAG_MPEG4_PathLayout: return NDT_SF2DNode; case TAG_MPEG4_TransformMatrix2D: return NDT_SF2DNode; + case TAG_MPEG4_AdvancedAudioBuffer: return NDT_SFAudioNode; + case TAG_MPEG4_AudioChannelConfig: return NDT_SFAudioNode; + case TAG_MPEG4_MorphShape: return NDT_SF3DNode; + case TAG_MPEG4_MultiTexture: return NDT_SFTextureNode; + case TAG_MPEG4_SBVCAnimationV2: return NDT_SF3DNode; + case TAG_MPEG4_Transform3DAudio: return NDT_SF3DNode; + case TAG_MPEG4_FootPrintSetNode: return NDT_SFGeometryNode; + case TAG_MPEG4_BuildingPartNode: return NDT_SFGeometryNode; + case TAG_MPEG4_FacadeNode: return NDT_SFGeometryNode; + case TAG_MPEG4_Shadow: return NDT_SF3DNode; + case TAG_MPEG4_SpacePartition: return NDT_SF3DNode; default: return 0; } @@ -20569,7 +38031,15 @@ u32 gf_node_mpeg4_type_by_class_name(const char *node_name) if (!strcmp(node_name, "DirectionalLight")) return TAG_MPEG4_DirectionalLight; if (!strcmp(node_name, "DiscSensor")) return TAG_MPEG4_DiscSensor; if (!strcmp(node_name, "ElevationGrid")) return TAG_MPEG4_ElevationGrid; + if (!strcmp(node_name, "Expression")) return TAG_MPEG4_Expression; if (!strcmp(node_name, "Extrusion")) return TAG_MPEG4_Extrusion; + if (!strcmp(node_name, "Face")) return TAG_MPEG4_Face; + if (!strcmp(node_name, "FaceDefMesh")) return TAG_MPEG4_FaceDefMesh; + if (!strcmp(node_name, "FaceDefTables")) return TAG_MPEG4_FaceDefTables; + if (!strcmp(node_name, "FaceDefTransform")) return TAG_MPEG4_FaceDefTransform; + if (!strcmp(node_name, "FAP")) return TAG_MPEG4_FAP; + if (!strcmp(node_name, "FDP")) return TAG_MPEG4_FDP; + if (!strcmp(node_name, "FIT")) return TAG_MPEG4_FIT; if (!strcmp(node_name, "Fog")) return TAG_MPEG4_Fog; if (!strcmp(node_name, "FontStyle")) return TAG_MPEG4_FontStyle; if (!strcmp(node_name, "Form")) return TAG_MPEG4_Form; @@ -20626,10 +38096,16 @@ u32 gf_node_mpeg4_type_by_class_name(const char *node_name) if (!strcmp(node_name, "Valuator")) return TAG_MPEG4_Valuator; if (!strcmp(node_name, "Viewpoint")) return TAG_MPEG4_Viewpoint; if (!strcmp(node_name, "VisibilitySensor")) return TAG_MPEG4_VisibilitySensor; + if (!strcmp(node_name, "Viseme")) return TAG_MPEG4_Viseme; if (!strcmp(node_name, "WorldInfo")) return TAG_MPEG4_WorldInfo; if (!strcmp(node_name, "AcousticMaterial")) return TAG_MPEG4_AcousticMaterial; if (!strcmp(node_name, "AcousticScene")) return TAG_MPEG4_AcousticScene; if (!strcmp(node_name, "ApplicationWindow")) return TAG_MPEG4_ApplicationWindow; + if (!strcmp(node_name, "BAP")) return TAG_MPEG4_BAP; + if (!strcmp(node_name, "BDP")) return TAG_MPEG4_BDP; + if (!strcmp(node_name, "Body")) return TAG_MPEG4_Body; + if (!strcmp(node_name, "BodyDefTable")) return TAG_MPEG4_BodyDefTable; + if (!strcmp(node_name, "BodySegmentConnectionHint")) return TAG_MPEG4_BodySegmentConnectionHint; if (!strcmp(node_name, "DirectiveSound")) return TAG_MPEG4_DirectiveSound; if (!strcmp(node_name, "Hierarchical3DMesh")) return TAG_MPEG4_Hierarchical3DMesh; if (!strcmp(node_name, "MaterialKey")) return TAG_MPEG4_MaterialKey; @@ -20642,23 +38118,81 @@ u32 gf_node_mpeg4_type_by_class_name(const char *node_name) if (!strcmp(node_name, "MediaBuffer")) return TAG_MPEG4_MediaBuffer; if (!strcmp(node_name, "MediaControl")) return TAG_MPEG4_MediaControl; if (!strcmp(node_name, "MediaSensor")) return TAG_MPEG4_MediaSensor; + if (!strcmp(node_name, "BitWrapper")) return TAG_MPEG4_BitWrapper; if (!strcmp(node_name, "CoordinateInterpolator4D")) return TAG_MPEG4_CoordinateInterpolator4D; + if (!strcmp(node_name, "DepthImage")) return TAG_MPEG4_DepthImage; + if (!strcmp(node_name, "FFD")) return TAG_MPEG4_FFD; + if (!strcmp(node_name, "Implicit")) return TAG_MPEG4_Implicit; + if (!strcmp(node_name, "XXLFM_Appearance")) return TAG_MPEG4_XXLFM_Appearance; + if (!strcmp(node_name, "XXLFM_BlendList")) return TAG_MPEG4_XXLFM_BlendList; + if (!strcmp(node_name, "XXLFM_FrameList")) return TAG_MPEG4_XXLFM_FrameList; + if (!strcmp(node_name, "XXLFM_LightMap")) return TAG_MPEG4_XXLFM_LightMap; + if (!strcmp(node_name, "XXLFM_SurfaceMapList")) return TAG_MPEG4_XXLFM_SurfaceMapList; + if (!strcmp(node_name, "XXLFM_ViewMapList")) return TAG_MPEG4_XXLFM_ViewMapList; + if (!strcmp(node_name, "MeshGrid")) return TAG_MPEG4_MeshGrid; if (!strcmp(node_name, "NonLinearDeformer")) return TAG_MPEG4_NonLinearDeformer; + if (!strcmp(node_name, "NurbsCurve")) return TAG_MPEG4_NurbsCurve; + if (!strcmp(node_name, "NurbsCurve2D")) return TAG_MPEG4_NurbsCurve2D; + if (!strcmp(node_name, "NurbsSurface")) return TAG_MPEG4_NurbsSurface; + if (!strcmp(node_name, "OctreeImage")) return TAG_MPEG4_OctreeImage; + if (!strcmp(node_name, "XXParticles")) return TAG_MPEG4_XXParticles; + if (!strcmp(node_name, "XXParticleInitBox")) return TAG_MPEG4_XXParticleInitBox; + if (!strcmp(node_name, "XXPlanarObstacle")) return TAG_MPEG4_XXPlanarObstacle; + if (!strcmp(node_name, "XXPointAttractor")) return TAG_MPEG4_XXPointAttractor; + if (!strcmp(node_name, "PointTexture")) return TAG_MPEG4_PointTexture; if (!strcmp(node_name, "PositionAnimator")) return TAG_MPEG4_PositionAnimator; if (!strcmp(node_name, "PositionAnimator2D")) return TAG_MPEG4_PositionAnimator2D; if (!strcmp(node_name, "PositionInterpolator4D")) return TAG_MPEG4_PositionInterpolator4D; + if (!strcmp(node_name, "ProceduralTexture")) return TAG_MPEG4_ProceduralTexture; + if (!strcmp(node_name, "Quadric")) return TAG_MPEG4_Quadric; + if (!strcmp(node_name, "SBBone")) return TAG_MPEG4_SBBone; + if (!strcmp(node_name, "SBMuscle")) return TAG_MPEG4_SBMuscle; + if (!strcmp(node_name, "SBSegment")) return TAG_MPEG4_SBSegment; + if (!strcmp(node_name, "SBSite")) return TAG_MPEG4_SBSite; + if (!strcmp(node_name, "SBSkinnedModel")) return TAG_MPEG4_SBSkinnedModel; + if (!strcmp(node_name, "SBVCAnimation")) return TAG_MPEG4_SBVCAnimation; if (!strcmp(node_name, "ScalarAnimator")) return TAG_MPEG4_ScalarAnimator; + if (!strcmp(node_name, "SimpleTexture")) return TAG_MPEG4_SimpleTexture; + if (!strcmp(node_name, "SolidRep")) return TAG_MPEG4_SolidRep; + if (!strcmp(node_name, "SubdivisionSurface")) return TAG_MPEG4_SubdivisionSurface; + if (!strcmp(node_name, "SubdivSurfaceSector")) return TAG_MPEG4_SubdivSurfaceSector; + if (!strcmp(node_name, "WaveletSubdivisionSurface")) return TAG_MPEG4_WaveletSubdivisionSurface; if (!strcmp(node_name, "Clipper2D")) return TAG_MPEG4_Clipper2D; if (!strcmp(node_name, "ColorTransform")) return TAG_MPEG4_ColorTransform; if (!strcmp(node_name, "Ellipse")) return TAG_MPEG4_Ellipse; if (!strcmp(node_name, "LinearGradient")) return TAG_MPEG4_LinearGradient; if (!strcmp(node_name, "PathLayout")) return TAG_MPEG4_PathLayout; if (!strcmp(node_name, "RadialGradient")) return TAG_MPEG4_RadialGradient; + if (!strcmp(node_name, "SynthesizedTexture")) return TAG_MPEG4_SynthesizedTexture; if (!strcmp(node_name, "TransformMatrix2D")) return TAG_MPEG4_TransformMatrix2D; if (!strcmp(node_name, "Viewport")) return TAG_MPEG4_Viewport; if (!strcmp(node_name, "XCurve2D")) return TAG_MPEG4_XCurve2D; if (!strcmp(node_name, "XFontStyle")) return TAG_MPEG4_XFontStyle; if (!strcmp(node_name, "XLineProperties")) return TAG_MPEG4_XLineProperties; + if (!strcmp(node_name, "AdvancedAudioBuffer")) return TAG_MPEG4_AdvancedAudioBuffer; + if (!strcmp(node_name, "AudioChannelConfig")) return TAG_MPEG4_AudioChannelConfig; + if (!strcmp(node_name, "DepthImageV2")) return TAG_MPEG4_DepthImageV2; + if (!strcmp(node_name, "MorphShape")) return TAG_MPEG4_MorphShape; + if (!strcmp(node_name, "MultiTexture")) return TAG_MPEG4_MultiTexture; + if (!strcmp(node_name, "PointTextureV2")) return TAG_MPEG4_PointTextureV2; + if (!strcmp(node_name, "SBVCAnimationV2")) return TAG_MPEG4_SBVCAnimationV2; + if (!strcmp(node_name, "SimpleTextureV2")) return TAG_MPEG4_SimpleTextureV2; + if (!strcmp(node_name, "SurroundingSound")) return TAG_MPEG4_SurroundingSound; + if (!strcmp(node_name, "Transform3DAudio")) return TAG_MPEG4_Transform3DAudio; + if (!strcmp(node_name, "WideSound")) return TAG_MPEG4_WideSound; + if (!strcmp(node_name, "ScoreShape")) return TAG_MPEG4_ScoreShape; + if (!strcmp(node_name, "MusicScore")) return TAG_MPEG4_MusicScore; + if (!strcmp(node_name, "FootPrintSetNode")) return TAG_MPEG4_FootPrintSetNode; + if (!strcmp(node_name, "FootPrintNode")) return TAG_MPEG4_FootPrintNode; + if (!strcmp(node_name, "BuildingPartNode")) return TAG_MPEG4_BuildingPartNode; + if (!strcmp(node_name, "RoofNode")) return TAG_MPEG4_RoofNode; + if (!strcmp(node_name, "FacadeNode")) return TAG_MPEG4_FacadeNode; + if (!strcmp(node_name, "Shadow")) return TAG_MPEG4_Shadow; + if (!strcmp(node_name, "CacheTexture")) return TAG_MPEG4_CacheTexture; + if (!strcmp(node_name, "EnvironmentTest")) return TAG_MPEG4_EnvironmentTest; + if (!strcmp(node_name, "KeyNavigator")) return TAG_MPEG4_KeyNavigator; + if (!strcmp(node_name, "SpacePartition")) return TAG_MPEG4_SpacePartition; + if (!strcmp(node_name, "Storage")) return TAG_MPEG4_Storage; return 0; } @@ -20698,7 +38232,15 @@ s32 gf_sg_mpeg4_node_get_field_index_by_name(GF_Node *node, char *name) case TAG_MPEG4_DirectionalLight: return DirectionalLight_get_field_index_by_name(name); case TAG_MPEG4_DiscSensor: return DiscSensor_get_field_index_by_name(name); case TAG_MPEG4_ElevationGrid: return ElevationGrid_get_field_index_by_name(name); + case TAG_MPEG4_Expression: return Expression_get_field_index_by_name(name); case TAG_MPEG4_Extrusion: return Extrusion_get_field_index_by_name(name); + case TAG_MPEG4_Face: return Face_get_field_index_by_name(name); + case TAG_MPEG4_FaceDefMesh: return FaceDefMesh_get_field_index_by_name(name); + case TAG_MPEG4_FaceDefTables: return FaceDefTables_get_field_index_by_name(name); + case TAG_MPEG4_FaceDefTransform: return FaceDefTransform_get_field_index_by_name(name); + case TAG_MPEG4_FAP: return FAP_get_field_index_by_name(name); + case TAG_MPEG4_FDP: return FDP_get_field_index_by_name(name); + case TAG_MPEG4_FIT: return FIT_get_field_index_by_name(name); case TAG_MPEG4_Fog: return Fog_get_field_index_by_name(name); case TAG_MPEG4_FontStyle: return FontStyle_get_field_index_by_name(name); case TAG_MPEG4_Form: return Form_get_field_index_by_name(name); @@ -20755,10 +38297,16 @@ s32 gf_sg_mpeg4_node_get_field_index_by_name(GF_Node *node, char *name) case TAG_MPEG4_Valuator: return Valuator_get_field_index_by_name(name); case TAG_MPEG4_Viewpoint: return Viewpoint_get_field_index_by_name(name); case TAG_MPEG4_VisibilitySensor: return VisibilitySensor_get_field_index_by_name(name); + case TAG_MPEG4_Viseme: return Viseme_get_field_index_by_name(name); case TAG_MPEG4_WorldInfo: return WorldInfo_get_field_index_by_name(name); case TAG_MPEG4_AcousticMaterial: return AcousticMaterial_get_field_index_by_name(name); case TAG_MPEG4_AcousticScene: return AcousticScene_get_field_index_by_name(name); case TAG_MPEG4_ApplicationWindow: return ApplicationWindow_get_field_index_by_name(name); + case TAG_MPEG4_BAP: return BAP_get_field_index_by_name(name); + case TAG_MPEG4_BDP: return BDP_get_field_index_by_name(name); + case TAG_MPEG4_Body: return Body_get_field_index_by_name(name); + case TAG_MPEG4_BodyDefTable: return BodyDefTable_get_field_index_by_name(name); + case TAG_MPEG4_BodySegmentConnectionHint: return BodySegmentConnectionHint_get_field_index_by_name(name); case TAG_MPEG4_DirectiveSound: return DirectiveSound_get_field_index_by_name(name); case TAG_MPEG4_Hierarchical3DMesh: return Hierarchical3DMesh_get_field_index_by_name(name); case TAG_MPEG4_MaterialKey: return MaterialKey_get_field_index_by_name(name); @@ -20771,25 +38319,85 @@ s32 gf_sg_mpeg4_node_get_field_index_by_name(GF_Node *node, char *name) case TAG_MPEG4_MediaBuffer: return MediaBuffer_get_field_index_by_name(name); case TAG_MPEG4_MediaControl: return MediaControl_get_field_index_by_name(name); case TAG_MPEG4_MediaSensor: return MediaSensor_get_field_index_by_name(name); + case TAG_MPEG4_BitWrapper: return BitWrapper_get_field_index_by_name(name); case TAG_MPEG4_CoordinateInterpolator4D: return CoordinateInterpolator4D_get_field_index_by_name(name); + case TAG_MPEG4_DepthImage: return DepthImage_get_field_index_by_name(name); + case TAG_MPEG4_FFD: return FFD_get_field_index_by_name(name); + case TAG_MPEG4_Implicit: return Implicit_get_field_index_by_name(name); + case TAG_MPEG4_XXLFM_Appearance: return XXLFM_Appearance_get_field_index_by_name(name); + case TAG_MPEG4_XXLFM_BlendList: return XXLFM_BlendList_get_field_index_by_name(name); + case TAG_MPEG4_XXLFM_FrameList: return XXLFM_FrameList_get_field_index_by_name(name); + case TAG_MPEG4_XXLFM_LightMap: return XXLFM_LightMap_get_field_index_by_name(name); + case TAG_MPEG4_XXLFM_SurfaceMapList: return XXLFM_SurfaceMapList_get_field_index_by_name(name); + case TAG_MPEG4_XXLFM_ViewMapList: return XXLFM_ViewMapList_get_field_index_by_name(name); + case TAG_MPEG4_MeshGrid: return MeshGrid_get_field_index_by_name(name); case TAG_MPEG4_NonLinearDeformer: return NonLinearDeformer_get_field_index_by_name(name); + case TAG_MPEG4_NurbsCurve: return NurbsCurve_get_field_index_by_name(name); + case TAG_MPEG4_NurbsCurve2D: return NurbsCurve2D_get_field_index_by_name(name); + case TAG_MPEG4_NurbsSurface: return NurbsSurface_get_field_index_by_name(name); + case TAG_MPEG4_OctreeImage: return OctreeImage_get_field_index_by_name(name); + case TAG_MPEG4_XXParticles: return XXParticles_get_field_index_by_name(name); + case TAG_MPEG4_XXParticleInitBox: return XXParticleInitBox_get_field_index_by_name(name); + case TAG_MPEG4_XXPlanarObstacle: return XXPlanarObstacle_get_field_index_by_name(name); + case TAG_MPEG4_XXPointAttractor: return XXPointAttractor_get_field_index_by_name(name); + case TAG_MPEG4_PointTexture: return PointTexture_get_field_index_by_name(name); case TAG_MPEG4_PositionAnimator: return PositionAnimator_get_field_index_by_name(name); case TAG_MPEG4_PositionAnimator2D: return PositionAnimator2D_get_field_index_by_name(name); case TAG_MPEG4_PositionInterpolator4D: return PositionInterpolator4D_get_field_index_by_name(name); + case TAG_MPEG4_ProceduralTexture: return ProceduralTexture_get_field_index_by_name(name); + case TAG_MPEG4_Quadric: return Quadric_get_field_index_by_name(name); + case TAG_MPEG4_SBBone: return SBBone_get_field_index_by_name(name); + case TAG_MPEG4_SBMuscle: return SBMuscle_get_field_index_by_name(name); + case TAG_MPEG4_SBSegment: return SBSegment_get_field_index_by_name(name); + case TAG_MPEG4_SBSite: return SBSite_get_field_index_by_name(name); + case TAG_MPEG4_SBSkinnedModel: return SBSkinnedModel_get_field_index_by_name(name); + case TAG_MPEG4_SBVCAnimation: return SBVCAnimation_get_field_index_by_name(name); case TAG_MPEG4_ScalarAnimator: return ScalarAnimator_get_field_index_by_name(name); + case TAG_MPEG4_SimpleTexture: return SimpleTexture_get_field_index_by_name(name); + case TAG_MPEG4_SolidRep: return SolidRep_get_field_index_by_name(name); + case TAG_MPEG4_SubdivisionSurface: return SubdivisionSurface_get_field_index_by_name(name); + case TAG_MPEG4_SubdivSurfaceSector: return SubdivSurfaceSector_get_field_index_by_name(name); + case TAG_MPEG4_WaveletSubdivisionSurface: return WaveletSubdivisionSurface_get_field_index_by_name(name); case TAG_MPEG4_Clipper2D: return Clipper2D_get_field_index_by_name(name); case TAG_MPEG4_ColorTransform: return ColorTransform_get_field_index_by_name(name); case TAG_MPEG4_Ellipse: return Ellipse_get_field_index_by_name(name); case TAG_MPEG4_LinearGradient: return LinearGradient_get_field_index_by_name(name); case TAG_MPEG4_PathLayout: return PathLayout_get_field_index_by_name(name); case TAG_MPEG4_RadialGradient: return RadialGradient_get_field_index_by_name(name); + case TAG_MPEG4_SynthesizedTexture: return SynthesizedTexture_get_field_index_by_name(name); case TAG_MPEG4_TransformMatrix2D: return TransformMatrix2D_get_field_index_by_name(name); case TAG_MPEG4_Viewport: return Viewport_get_field_index_by_name(name); case TAG_MPEG4_XCurve2D: return XCurve2D_get_field_index_by_name(name); case TAG_MPEG4_XFontStyle: return XFontStyle_get_field_index_by_name(name); case TAG_MPEG4_XLineProperties: return XLineProperties_get_field_index_by_name(name); + case TAG_MPEG4_AdvancedAudioBuffer: return AdvancedAudioBuffer_get_field_index_by_name(name); + case TAG_MPEG4_AudioChannelConfig: return AudioChannelConfig_get_field_index_by_name(name); + case TAG_MPEG4_DepthImageV2: return DepthImageV2_get_field_index_by_name(name); + case TAG_MPEG4_MorphShape: return MorphShape_get_field_index_by_name(name); + case TAG_MPEG4_MultiTexture: return MultiTexture_get_field_index_by_name(name); + case TAG_MPEG4_PointTextureV2: return PointTextureV2_get_field_index_by_name(name); + case TAG_MPEG4_SBVCAnimationV2: return SBVCAnimationV2_get_field_index_by_name(name); + case TAG_MPEG4_SimpleTextureV2: return SimpleTextureV2_get_field_index_by_name(name); + case TAG_MPEG4_SurroundingSound: return SurroundingSound_get_field_index_by_name(name); + case TAG_MPEG4_Transform3DAudio: return Transform3DAudio_get_field_index_by_name(name); + case TAG_MPEG4_WideSound: return WideSound_get_field_index_by_name(name); + case TAG_MPEG4_ScoreShape: return ScoreShape_get_field_index_by_name(name); + case TAG_MPEG4_MusicScore: return MusicScore_get_field_index_by_name(name); + case TAG_MPEG4_FootPrintSetNode: return FootPrintSetNode_get_field_index_by_name(name); + case TAG_MPEG4_FootPrintNode: return FootPrintNode_get_field_index_by_name(name); + case TAG_MPEG4_BuildingPartNode: return BuildingPartNode_get_field_index_by_name(name); + case TAG_MPEG4_RoofNode: return RoofNode_get_field_index_by_name(name); + case TAG_MPEG4_FacadeNode: return FacadeNode_get_field_index_by_name(name); + case TAG_MPEG4_Shadow: return Shadow_get_field_index_by_name(name); + case TAG_MPEG4_CacheTexture: return CacheTexture_get_field_index_by_name(name); + case TAG_MPEG4_EnvironmentTest: return EnvironmentTest_get_field_index_by_name(name); + case TAG_MPEG4_KeyNavigator: return KeyNavigator_get_field_index_by_name(name); + case TAG_MPEG4_SpacePartition: return SpacePartition_get_field_index_by_name(name); + case TAG_MPEG4_Storage: return Storage_get_field_index_by_name(name); default: return -1; } } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/scenegraph/mpeg4_valuator.c b/src/scenegraph/mpeg4_valuator.c index c53b71b..bd09cd7 100644 --- a/src/scenegraph/mpeg4_valuator.c +++ b/src/scenegraph/mpeg4_valuator.c @@ -27,6 +27,9 @@ /*MPEG4 tags (for internal nodes)*/ #include <gpac/nodes_mpeg4.h> + +#ifndef GPAC_DISABLE_VRML + static void format_sftime_string(Fixed _val, char *str) { u32 h, m, s; @@ -42,17 +45,109 @@ static void format_sftime_string(Fixed _val, char *str) sprintf(str, "%s%02d:%02d:%02d", neg ? "-" : "", h, m, s); } +static void valuator_get_output(M_Valuator *p, GenMFField *inMFField, u32 inType, Bool do_sum, u32 i, SFVec4f *output, u32 *num_out) +{ + + switch (inType) { + case GF_SG_VRML_MFINT32: + { + SFInt32 sfi = ((MFInt32 *)inMFField)->vals[i]; + Fixed vi = INT2FIX(sfi); + output->x = gf_mulfix(p->Factor1, vi) + p->Offset1; + output->y = gf_mulfix(p->Factor2, vi) + p->Offset2; + output->z = gf_mulfix(p->Factor3, vi) + p->Offset3; + output->q = gf_mulfix(p->Factor4, vi) + p->Offset4; + } + break; + case GF_SG_VRML_MFFLOAT: + { + Fixed sff = ((MFFloat *)inMFField)->vals[i]; + output->x = gf_mulfix(p->Factor1, sff) + p->Offset1; + output->y = gf_mulfix(p->Factor2, sff) + p->Offset2; + output->z = gf_mulfix(p->Factor3, sff) + p->Offset3; + output->q = gf_mulfix(p->Factor4, sff) + p->Offset4; + } + break; + case GF_SG_VRML_MFCOLOR: + { + SFColor sfc = ((MFColor *)inMFField)->vals[i]; + output->x = gf_mulfix(p->Factor1, sfc.red) + p->Offset1; + output->y = gf_mulfix(p->Factor2, sfc.green) + p->Offset2; + output->z = gf_mulfix(p->Factor3, sfc.blue) + p->Offset3; + output->q = p->Offset4; + *num_out = 3; + } + break; + case GF_SG_VRML_MFVEC2F: + { + SFVec2f sfv = ((MFVec2f *)inMFField)->vals[i]; + output->x = gf_mulfix(p->Factor1, sfv.x) + p->Offset1; + output->y = gf_mulfix(p->Factor2, sfv.y) + p->Offset2; + output->z = p->Offset3; + output->q = p->Offset4; + *num_out = 2; + } + break; + case GF_SG_VRML_MFVEC3F: + { + SFVec3f sfv = ((MFVec3f *)inMFField)->vals[i]; + output->x = gf_mulfix(p->Factor1, sfv.x) + p->Offset1; + output->y = gf_mulfix(p->Factor2, sfv.y) + p->Offset2; + output->z = gf_mulfix(p->Factor3, sfv.z) + p->Offset3; + output->q = p->Offset4; + *num_out = 3; + } + break; + case GF_SG_VRML_MFVEC4F: + case GF_SG_VRML_MFROTATION: + { + SFVec4f sfv = ((MFVec4f *)inMFField)->vals[i]; + output->x = gf_mulfix(p->Factor1, sfv.x) + p->Offset1; + output->y = gf_mulfix(p->Factor2, sfv.y) + p->Offset2; + output->z = gf_mulfix(p->Factor3, sfv.z) + p->Offset3; + output->q = gf_mulfix(p->Factor4, sfv.q) + p->Offset4; + *num_out = 4; + } + break; + case GF_SG_VRML_MFSTRING: + /*cf below*/ + output->x = output->y = output->z = output->q = 0; + if (((MFString *)inMFField)->vals[i]) { + if (!stricmp(((MFString *)inMFField)->vals[i], "true")) { + output->x = output->y = output->z = output->q = FIX_ONE; + } else if (!strstr(((MFString *)inMFField)->vals[i], ".")) { + output->x = INT2FIX( atoi(((MFString *)inMFField)->vals[i]) ); + output->y = output->z = output->q = output->x; + } else { + output->x = FLT2FIX( atof(((MFString *)inMFField)->vals[i]) ); + output->y = output->z = output->q = output->x; + } + } + + output->x = gf_mulfix(p->Factor1, output->x) + p->Offset1; + output->y = gf_mulfix(p->Factor2, output->y) + p->Offset2; + output->z = gf_mulfix(p->Factor3, output->z) + p->Offset3; + output->q = gf_mulfix(p->Factor4, output->q) + p->Offset4; + break; + + } + if (do_sum) { + output->x = output->x + output->y + output->z + output->q; + output->y = output->z = output->q = output->x; + } +} + static void SetValuatorOutput(M_Valuator *p, SFVec4f *inSFField, GenMFField *inMFField, u32 inType) { char str[500]; - u32 i; + u32 i, j; GF_Route *r; SFVec4f output, sf_out; + MFVec4f *mf_output = (MFVec4f *)gf_node_get_private((GF_Node*)p); u32 count, num_out; Bool do_sum; - if (!gf_node_get_id((GF_Node*)p) && !p->sgprivate->scenegraph->pOwningProto) return; - if (!p->sgprivate->interact) return; + if (!p->sgprivate->interact || !mf_output) return; do_sum = p->Sum; num_out = 1; @@ -86,15 +181,19 @@ static void SetValuatorOutput(M_Valuator *p, SFVec4f *inSFField, GenMFField *inM } else { count = inMFField->count; } - /*reallocate all MF fields*/ -/* gf_sg_vrml_mf_reset(&p->outMFColor, GF_SG_VRML_MFCOLOR); - gf_sg_vrml_mf_reset(&p->outMFFloat, GF_SG_VRML_MFFLOAT); - gf_sg_vrml_mf_reset(&p->outMFInt32, GF_SG_VRML_MFINT32); - gf_sg_vrml_mf_reset(&p->outMFRotation, GF_SG_VRML_MFROTATION); - gf_sg_vrml_mf_reset(&p->outMFString, GF_SG_VRML_MFSTRING); - gf_sg_vrml_mf_reset(&p->outMFVec2f, GF_SG_VRML_MFVEC2F); - gf_sg_vrml_mf_reset(&p->outMFVec3f, GF_SG_VRML_MFVEC3F); -*/ + + /*allocate temp buffer and compute values*/ + gf_sg_vrml_mf_alloc(mf_output, GF_SG_VRML_MFVEC4F, count); + for (i=0; i<count; i++) { + if (inType) { + valuator_get_output(p, inMFField, inType, do_sum, i, &output, &num_out); + mf_output->vals[i] = output; + } else if (!i) { + mf_output->vals[0] = output; + } + if (!i) sf_out = output; + } + gf_sg_vrml_mf_alloc(&p->outMFColor, GF_SG_VRML_MFCOLOR, count); gf_sg_vrml_mf_alloc(&p->outMFFloat, GF_SG_VRML_MFFLOAT, count); gf_sg_vrml_mf_alloc(&p->outMFInt32, GF_SG_VRML_MFINT32, count); @@ -102,172 +201,129 @@ static void SetValuatorOutput(M_Valuator *p, SFVec4f *inSFField, GenMFField *inM gf_sg_vrml_mf_alloc(&p->outMFString, GF_SG_VRML_MFSTRING, count); gf_sg_vrml_mf_alloc(&p->outMFVec2f, GF_SG_VRML_MFVEC2F, count); gf_sg_vrml_mf_alloc(&p->outMFVec3f, GF_SG_VRML_MFVEC3F, count); - /*set all MF outputs*/ - for (i=0; i<count; i++) { - if (inType) { - switch (inType) { - case GF_SG_VRML_MFINT32: - { - SFInt32 sfi = ((MFInt32 *)inMFField)->vals[i]; - Fixed vi = INT2FIX(sfi); - output.x = gf_mulfix(p->Factor1, vi) + p->Offset1; - output.y = gf_mulfix(p->Factor2, vi) + p->Offset2; - output.z = gf_mulfix(p->Factor3, vi) + p->Offset3; - output.q = gf_mulfix(p->Factor4, vi) + p->Offset4; - } - break; - case GF_SG_VRML_MFFLOAT: - { - Fixed sff = ((MFFloat *)inMFField)->vals[i]; - output.x = gf_mulfix(p->Factor1, sff) + p->Offset1; - output.y = gf_mulfix(p->Factor2, sff) + p->Offset2; - output.z = gf_mulfix(p->Factor3, sff) + p->Offset3; - output.q = gf_mulfix(p->Factor4, sff) + p->Offset4; + /*valuator is a special case, all routes are triggered*/ + j=0; + while ((r = (GF_Route*)gf_list_enum(p->sgprivate->interact->routes, &j))) { + if (r->FromNode != (GF_Node *)p) continue; + if (!r->is_setup) gf_sg_route_setup(r); + if (r->FromField.eventType != GF_SG_EVENT_OUT) continue; + + /*TODO we could optimize more and check if the field has been set or not ...*/ + switch (r->FromField.fieldType) { + case GF_SG_VRML_SFBOOL: + p->outSFBool = (Bool) (sf_out.x ? 1 : 0); + break; + case GF_SG_VRML_SFFLOAT: + p->outSFFloat = sf_out.x; + break; + case GF_SG_VRML_SFINT32: + p->outSFInt32 = FIX2INT(sf_out.x); + break; + case GF_SG_VRML_SFTIME: + p->outSFTime = (SFTime) FIX2FLT(sf_out.x); + break; + case GF_SG_VRML_SFROTATION: + p->outSFRotation.x = sf_out.x; + p->outSFRotation.y = sf_out.y; + p->outSFRotation.z = sf_out.z; + p->outSFRotation.q = sf_out.q; + break; + case GF_SG_VRML_SFCOLOR: + p->outSFColor.red = sf_out.x; + p->outSFColor.green = sf_out.y; + p->outSFColor.blue = sf_out.z; + break; + case GF_SG_VRML_SFVEC2F: + p->outSFVec2f.x = sf_out.x; + p->outSFVec2f.y = sf_out.y; + break; + case GF_SG_VRML_SFVEC3F: + p->outSFVec3f.x = sf_out.x; + p->outSFVec3f.y = sf_out.y; + p->outSFVec3f.z = sf_out.z; + break; + case GF_SG_VRML_SFSTRING: + if (num_out==1) { + if (inType==GF_SG_VRML_SFTIME) { + format_sftime_string(output.x, str); + } else { + sprintf(str, "%.6f", FIX2FLT(sf_out.x)); + } + } else if (num_out==2) { + sprintf(str, "%.4f %.4f", FIX2FLT(sf_out.x), FIX2FLT(sf_out.y)); + } else if (num_out==3) { + sprintf(str, "%.3f %.3f %.3f", FIX2FLT(sf_out.x), FIX2FLT(sf_out.y), FIX2FLT(sf_out.z)); + } else if (num_out==4) { + sprintf(str, "%.2f %.2f %.2f %.2f", FIX2FLT(sf_out.x), FIX2FLT(sf_out.y), FIX2FLT(sf_out.z), FIX2FLT(sf_out.q)); } - break; - case GF_SG_VRML_MFCOLOR: - { - SFColor sfc = ((MFColor *)inMFField)->vals[i]; - output.x = gf_mulfix(p->Factor1, sfc.red) + p->Offset1; - output.y = gf_mulfix(p->Factor2, sfc.green) + p->Offset2; - output.z = gf_mulfix(p->Factor3, sfc.blue) + p->Offset3; - output.q = p->Offset4; - num_out = 3; + if (p->outSFString.buffer ) gf_free(p->outSFString.buffer); + p->outSFString.buffer = gf_strdup(str); + break; + + + case GF_SG_VRML_MFFLOAT: + gf_sg_vrml_mf_alloc(&p->outMFFloat, GF_SG_VRML_MFFLOAT, count); + for (i=0; i<count; i++) + p->outMFFloat.vals[i] = mf_output->vals[i].x; + break; + case GF_SG_VRML_MFINT32: + gf_sg_vrml_mf_alloc(&p->outMFInt32, GF_SG_VRML_MFINT32, count); + for (i=0; i<count; i++) + p->outMFInt32.vals[i] = FIX2INT(mf_output->vals[i].x); + break; + case GF_SG_VRML_MFCOLOR: + gf_sg_vrml_mf_alloc(&p->outMFColor, GF_SG_VRML_MFCOLOR, count); + for (i=0; i<count; i++) { + p->outMFColor.vals[i].red = mf_output->vals[i].x; + p->outMFColor.vals[i].green = mf_output->vals[i].y; + p->outMFColor.vals[i].blue = mf_output->vals[i].z; } - break; - case GF_SG_VRML_MFVEC2F: - { - SFVec2f sfv = ((MFVec2f *)inMFField)->vals[i]; - output.x = gf_mulfix(p->Factor1, sfv.x) + p->Offset1; - output.y = gf_mulfix(p->Factor2, sfv.y) + p->Offset2; - output.z = p->Offset3; - output.q = p->Offset4; - num_out = 2; + break; + case GF_SG_VRML_MFVEC2F: + gf_sg_vrml_mf_alloc(&p->outMFVec2f, GF_SG_VRML_MFVEC2F, count); + for (i=0; i<count; i++) { + p->outMFVec2f.vals[i].x = mf_output->vals[i].x; + p->outMFVec2f.vals[i].y = mf_output->vals[i].y; } - break; - case GF_SG_VRML_MFVEC3F: - { - SFVec3f sfv = ((MFVec3f *)inMFField)->vals[i]; - output.x = gf_mulfix(p->Factor1, sfv.x) + p->Offset1; - output.y = gf_mulfix(p->Factor2, sfv.y) + p->Offset2; - output.z = gf_mulfix(p->Factor3, sfv.z) + p->Offset3; - output.q = p->Offset4; - num_out = 3; + break; + case GF_SG_VRML_MFVEC3F: + gf_sg_vrml_mf_alloc(&p->outMFVec3f, GF_SG_VRML_MFVEC3F, count); + for (i=0; i<count; i++) { + p->outMFVec3f.vals[i].x = mf_output->vals[i].x; + p->outMFVec3f.vals[i].y = mf_output->vals[i].y; + p->outMFVec3f.vals[i].z = mf_output->vals[i].z; } - break; - case GF_SG_VRML_MFVEC4F: - case GF_SG_VRML_MFROTATION: - { - SFVec4f sfv = ((MFVec4f *)inMFField)->vals[i]; - output.x = gf_mulfix(p->Factor1, sfv.x) + p->Offset1; - output.y = gf_mulfix(p->Factor2, sfv.y) + p->Offset2; - output.z = gf_mulfix(p->Factor3, sfv.z) + p->Offset3; - output.q = gf_mulfix(p->Factor4, sfv.q) + p->Offset4; - num_out = 4; + break; + case GF_SG_VRML_MFROTATION: + gf_sg_vrml_mf_alloc(&p->outMFRotation, GF_SG_VRML_MFROTATION, count); + for (i=0; i<count; i++) { + p->outMFRotation.vals[i].x = mf_output->vals[i].x; + p->outMFRotation.vals[i].y = mf_output->vals[i].y; + p->outMFRotation.vals[i].z = mf_output->vals[i].z; + p->outMFRotation.vals[i].q = mf_output->vals[i].q; } - break; - case GF_SG_VRML_MFSTRING: - /*cf below*/ - output.x = output.y = output.z = output.q = 0; - if (((MFString *)inMFField)->vals[i]) { - if (!stricmp(((MFString *)inMFField)->vals[i], "true")) { - output.x = output.y = output.z = output.q = FIX_ONE; - } else if (!strstr(((MFString *)inMFField)->vals[i], ".")) { - output.x = INT2FIX( atoi(((MFString *)inMFField)->vals[i]) ); - output.y = output.z = output.q = output.x; + break; + case GF_SG_VRML_MFSTRING: + gf_sg_vrml_mf_alloc(&p->outMFString, GF_SG_VRML_MFSTRING, count); gf_sg_vrml_mf_alloc(&p->outMFVec2f, GF_SG_VRML_MFVEC2F, count); + for (i=0; i<count; i++) { + if (num_out==1) { + if (inType==GF_SG_VRML_SFTIME) { + format_sftime_string(mf_output->vals[i].x, str); } else { - output.x = FLT2FIX( atof(((MFString *)inMFField)->vals[i]) ); - output.y = output.z = output.q = output.x; + sprintf(str, "%g", FIX2FLT(mf_output->vals[i].x)); } + } else if (num_out==2) { + sprintf(str, "%g %g", FIX2FLT(mf_output->vals[i].x), FIX2FLT(mf_output->vals[i].y)); + } else if (num_out==3) { + sprintf(str, "%g %g %g", FIX2FLT(mf_output->vals[i].x), FIX2FLT(mf_output->vals[i].y), FIX2FLT(mf_output->vals[i].z)); + } else if (num_out==4) { + sprintf(str, "%g %g %g %g", FIX2FLT(mf_output->vals[i].x), FIX2FLT(mf_output->vals[i].y), FIX2FLT(mf_output->vals[i].z), FIX2FLT(mf_output->vals[i].q)); } - - output.x = gf_mulfix(p->Factor1, output.x) + p->Offset1; - output.y = gf_mulfix(p->Factor2, output.y) + p->Offset2; - output.z = gf_mulfix(p->Factor3, output.z) + p->Offset3; - output.q = gf_mulfix(p->Factor4, output.q) + p->Offset4; - break; - - } - if (do_sum) { - output.x = output.x + output.y + output.z + output.q; - output.y = output.z = output.q = output.x; + if (p->outMFString.vals[i]) gf_free(p->outMFString.vals[i]); + p->outMFString.vals[i] = gf_strdup(str); } + break; } - - p->outMFFloat.vals[i] = output.x; - p->outMFInt32.vals[i] = FIX2INT(output.x); - p->outMFColor.vals[i].red = output.x; - p->outMFColor.vals[i].green = output.y; - p->outMFColor.vals[i].blue = output.z; - p->outMFVec2f.vals[i].x = output.x; - p->outMFVec2f.vals[i].y = output.y; - p->outMFVec3f.vals[i].x = output.x; - p->outMFVec3f.vals[i].y = output.y; - p->outMFVec3f.vals[i].z = output.z; - p->outMFRotation.vals[i].x = output.x; - p->outMFRotation.vals[i].y = output.y; - p->outMFRotation.vals[i].z = output.z; - p->outMFRotation.vals[i].q = output.q; - - if (num_out==1) { - if (inType==GF_SG_VRML_SFTIME) { - format_sftime_string(output.x, str); - } else { - sprintf(str, "%g", FIX2FLT(output.x)); - } - } else if (num_out==2) { - sprintf(str, "%g %g", FIX2FLT(output.x), FIX2FLT(output.y)); - } else if (num_out==3) { - sprintf(str, "%g %g %g", FIX2FLT(output.x), FIX2FLT(output.y), FIX2FLT(output.z)); - } else if (num_out==4) { - sprintf(str, "%g %g %g %g", FIX2FLT(output.x), FIX2FLT(output.y), FIX2FLT(output.z), FIX2FLT(output.q)); - } - - if (p->outMFString.vals[i]) free(p->outMFString.vals[i]); - p->outMFString.vals[i] = strdup(str); - - if (!i) sf_out = output; - - } - - p->outSFBool = (Bool) (sf_out.x ? 1 : 0); - p->outSFFloat = sf_out.x; - p->outSFInt32 = FIX2INT(sf_out.x); - p->outSFTime = (SFTime) FIX2FLT(sf_out.x); - p->outSFRotation.x = sf_out.x; - p->outSFRotation.y = sf_out.y; - p->outSFRotation.z = sf_out.z; - p->outSFRotation.q = sf_out.q; - p->outSFColor.red = sf_out.x; - p->outSFColor.green = sf_out.y; - p->outSFColor.blue = sf_out.z; - p->outSFVec2f.x = sf_out.x; - p->outSFVec2f.y = sf_out.y; - p->outSFVec3f.x = sf_out.x; - p->outSFVec3f.y = sf_out.y; - p->outSFVec3f.z = sf_out.z; - - if (num_out==1) { - if (inType==GF_SG_VRML_SFTIME) { - format_sftime_string(output.x, str); - } else { - sprintf(str, "%.6f", FIX2FLT(sf_out.x)); - } - } else if (num_out==2) { - sprintf(str, "%.4f %.4f", FIX2FLT(sf_out.x), FIX2FLT(sf_out.y)); - } else if (num_out==3) { - sprintf(str, "%.3f %.3f %.3f", FIX2FLT(sf_out.x), FIX2FLT(sf_out.y), FIX2FLT(sf_out.z)); - } else if (num_out==4) { - sprintf(str, "%.2f %.2f %.2f %.2f", FIX2FLT(sf_out.x), FIX2FLT(sf_out.y), FIX2FLT(sf_out.z), FIX2FLT(sf_out.q)); - } - if (p->outSFString.buffer ) free(p->outSFString.buffer); - p->outSFString.buffer = strdup(str); - - /*valuator is a special case, all routes are triggered*/ - i=0; - while ((r = (GF_Route*)gf_list_enum(p->sgprivate->interact->routes, &i))) { - if (r->FromNode != (GF_Node *)p) continue; - if (r->IS_route) { gf_sg_route_activate(r); } else { @@ -284,35 +340,35 @@ SFVec2f), for all components i of output.i, input.i shall take the value of the conversion" */ -static void Valuator_SetInSFBool(GF_Node *n) +static void Valuator_SetInSFBool(GF_Node *n, GF_Route *route) { SFVec4f val; M_Valuator *_this = (M_Valuator *) n; val.x = val.y = val.z = val.q = _this->inSFBool ? FIX_ONE : 0; SetValuatorOutput(_this, &val, NULL, GF_SG_VRML_SFBOOL); } -static void Valuator_SetInSFFloat(GF_Node *n) +static void Valuator_SetInSFFloat(GF_Node *n, GF_Route *route) { SFVec4f val; M_Valuator *_this = (M_Valuator *) n; val.x = val.y = val.z = val.q = _this->inSFFloat; SetValuatorOutput(_this, &val, NULL, GF_SG_VRML_SFFLOAT); } -static void Valuator_SetInSFInt32(GF_Node *n) +static void Valuator_SetInSFInt32(GF_Node *n, GF_Route *route) { SFVec4f val; M_Valuator *_this = (M_Valuator *) n; val.x = val.y = val.z = val.q = INT2FIX(_this->inSFInt32); SetValuatorOutput(_this, &val, NULL, GF_SG_VRML_SFINT32); } -static void Valuator_SetInSFTime(GF_Node *n) +static void Valuator_SetInSFTime(GF_Node *n, GF_Route *route) { SFVec4f val; M_Valuator *_this = (M_Valuator *) n; val.x = val.y = val.z = val.q = FLT2FIX(_this->inSFTime); SetValuatorOutput(_this, &val, NULL, GF_SG_VRML_SFTIME); } -static void Valuator_SetInSFColor(GF_Node *n) +static void Valuator_SetInSFColor(GF_Node *n, GF_Route *route) { SFVec4f val; M_Valuator *_this = (M_Valuator *) n; @@ -322,7 +378,7 @@ static void Valuator_SetInSFColor(GF_Node *n) val.q = 0; SetValuatorOutput(_this, &val, NULL, GF_SG_VRML_SFCOLOR); } -static void Valuator_SetInSFVec2f(GF_Node *n) +static void Valuator_SetInSFVec2f(GF_Node *n, GF_Route *route) { SFVec4f val; M_Valuator *_this = (M_Valuator *) n; @@ -331,7 +387,7 @@ static void Valuator_SetInSFVec2f(GF_Node *n) val.z = val.q = 0; SetValuatorOutput(_this, &val, NULL, GF_SG_VRML_SFVEC2F); } -static void Valuator_SetInSFVec3f(GF_Node *n) +static void Valuator_SetInSFVec3f(GF_Node *n, GF_Route *route) { SFVec4f val; M_Valuator *_this = (M_Valuator *) n; @@ -341,7 +397,7 @@ static void Valuator_SetInSFVec3f(GF_Node *n) val.q = 0; SetValuatorOutput(_this, &val, NULL, GF_SG_VRML_SFVEC3F); } -static void Valuator_SetInSFRotation(GF_Node *n) +static void Valuator_SetInSFRotation(GF_Node *n, GF_Route *route) { SFVec4f val; M_Valuator *_this = (M_Valuator *) n; @@ -355,7 +411,7 @@ Convert if the content of the string represents an int, float or double value. ‘Boolean’ string values 'true' and 'false' are converted to 1.0 and 0.0 respectively. Any other string is converted to 0.0 */ -static void Valuator_SetInSFString(GF_Node *n) +static void Valuator_SetInSFString(GF_Node *n, GF_Route *route) { SFVec4f val; M_Valuator *_this = (M_Valuator *) n; @@ -373,45 +429,57 @@ static void Valuator_SetInSFString(GF_Node *n) SetValuatorOutput(_this, &val, NULL, GF_SG_VRML_SFSTRING); } -static void Valuator_SetInMFColor(GF_Node *n) +static void Valuator_SetInMFColor(GF_Node *n, GF_Route *route) { M_Valuator *_this = (M_Valuator *) n; SetValuatorOutput(_this, NULL, (GenMFField *) &_this->inMFColor, GF_SG_VRML_MFCOLOR); } -static void Valuator_SetInMFFloat(GF_Node *n) +static void Valuator_SetInMFFloat(GF_Node *n, GF_Route *route) { M_Valuator *_this = (M_Valuator *) n; SetValuatorOutput(_this, NULL, (GenMFField *) &_this->inMFFloat, GF_SG_VRML_MFFLOAT); } -static void Valuator_SetInMFInt32(GF_Node *n) +static void Valuator_SetInMFInt32(GF_Node *n, GF_Route *route) { M_Valuator *_this = (M_Valuator *) n; SetValuatorOutput(_this, NULL, (GenMFField *) &_this->inMFInt32, GF_SG_VRML_MFINT32); } -static void Valuator_SetInMFVec2f(GF_Node *n) +static void Valuator_SetInMFVec2f(GF_Node *n, GF_Route *route) { M_Valuator *_this = (M_Valuator *) n; SetValuatorOutput(_this, NULL, (GenMFField *) &_this->inMFVec2f, GF_SG_VRML_MFVEC2F); } -static void Valuator_SetInMFVec3f(GF_Node *n) +static void Valuator_SetInMFVec3f(GF_Node *n, GF_Route *route) { M_Valuator *_this = (M_Valuator *) n; SetValuatorOutput(_this, NULL, (GenMFField *) &_this->inMFVec3f, GF_SG_VRML_MFVEC3F); } -static void Valuator_SetInMFRotation(GF_Node *n) +static void Valuator_SetInMFRotation(GF_Node *n, GF_Route *route) { M_Valuator *_this = (M_Valuator *) n; SetValuatorOutput(_this, NULL, (GenMFField *) &_this->inMFRotation, GF_SG_VRML_MFROTATION); } -static void Valuator_SetInMFString(GF_Node *n) +static void Valuator_SetInMFString(GF_Node *n, GF_Route *route) { M_Valuator *_this = (M_Valuator *) n; SetValuatorOutput(_this, NULL, (GenMFField *) &_this->inMFString, GF_SG_VRML_MFSTRING); } + +static void valuator_destroy(GF_Node *node, void *rs, Bool is_destroy) +{ + if (is_destroy) { + MFVec4f *stack = (MFVec4f *)gf_node_get_private(node); + gf_sg_vrml_field_pointer_del(stack, GF_SG_VRML_MFROTATION); + } +} + Bool InitValuator(M_Valuator *node) { + MFVec4f *temp = gf_sg_vrml_field_pointer_new(GF_SG_VRML_MFROTATION); + if (!temp) return 1; + node->on_inSFTime = Valuator_SetInSFTime; node->on_inSFBool = Valuator_SetInSFBool; node->on_inSFColor = Valuator_SetInSFColor; @@ -428,5 +496,12 @@ Bool InitValuator(M_Valuator *node) node->on_inMFVec3f = Valuator_SetInMFVec3f; node->on_inMFRotation = Valuator_SetInMFRotation; node->on_inMFString = Valuator_SetInMFString; + + gf_node_set_private((GF_Node*)node, temp); + gf_node_set_callback_function((GF_Node*)node, valuator_destroy); + return 1; } + + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/scenegraph/smil_anim.c b/src/scenegraph/smil_anim.c index 3f65d8b..967a22c 100644 --- a/src/scenegraph/smil_anim.c +++ b/src/scenegraph/smil_anim.c @@ -1,1462 +1,1513 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Authors: Cyril Concolato - Jean Le Feuvre - * Copyright (c)2004-200X ENST - All rights reserved - * - * This file is part of GPAC / SVG Scene Graph 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/scenegraph_dev.h> -#include <gpac/nodes_svg.h> - -#ifndef GPAC_DISABLE_LOG -u32 time_spent_in_anim = 0; -#endif - -#ifndef GPAC_DISABLE_SVG - - -/************************************************************************************** - * Each GF_Node holds the (SVG/SMIL) animation elements which target itself in a list * - * The following are the generic functions to manipulate this list: * - * - add a new animation to the list, * - * - get an animation from the list, * - * - remove an animation from the list, * - * - count the animations in the list, * - * - delete the list * - **************************************************************************************/ -GF_Err gf_node_animation_add(GF_Node *node, void *animation) -{ - if (!node || !animation) return GF_BAD_PARAM; - if (!node->sgprivate->interact) GF_SAFEALLOC(node->sgprivate->interact, struct _node_interactive_ext); - if (!node->sgprivate->interact->animations) node->sgprivate->interact->animations = gf_list_new(); - return gf_list_add(node->sgprivate->interact->animations, animation); -} - -GF_Err gf_node_animation_del(GF_Node *node) -{ - if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return GF_BAD_PARAM; - gf_list_del(node->sgprivate->interact->animations); - node->sgprivate->interact->animations = NULL; - return GF_OK; -} - -u32 gf_node_animation_count(GF_Node *node) -{ - if (!node || !node->sgprivate->interact|| !node->sgprivate->interact->animations) return 0; - return gf_list_count(node->sgprivate->interact->animations); -} - -void *gf_node_animation_get(GF_Node *node, u32 i) -{ - if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return 0; - return gf_list_get(node->sgprivate->interact->animations, i); -} - -GF_Err gf_node_animation_rem(GF_Node *node, u32 i) -{ - if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return GF_OK; - return gf_list_rem(node->sgprivate->interact->animations, i); -} -/************************************************************************************** - * End of Generic GF_Node animations list * - **************************************************************************************/ - - -/************************************************************************************** - * Helping functions for animation * - **************************************************************************************/ -/* Sets the pointer to the attribute value with the pointer - to the value which passed (if unspecified) */ -void gf_svg_attributes_resolve_unspecified(GF_FieldInfo *in, GF_FieldInfo *p, GF_FieldInfo *t) -{ - if (in->fieldType == 0) { - if (p->fieldType == SVG_Transform_datatype) { - /* if the input value is not specified, and the presentation value is of type Transform, - then we should use the default identity transform instead of the presentation value */ - *in = *t; - } else { - *in = *p; - } - } -} - -/* Replaces the pointer to the attribute value with the pointer - to the value which is inherited (if inherited) */ -void gf_svg_attributes_resolve_inherit(GF_FieldInfo *in, GF_FieldInfo *prop) -{ - if (gf_svg_is_inherit(in)) *in = *prop; -} - -/* Replaces the pointer to the attribute value with the pointer - to the value of the color attribute (if the current value is set to currentColor) */ -void gf_svg_attributes_resolve_currentColor(GF_FieldInfo *in, GF_FieldInfo *current_color) -{ - if ((in->fieldType == SVG_Paint_datatype) && gf_svg_is_current_color(in)) { - *in = *current_color; - } -} - -/************************************************************************************** - * The main function doing evaluation of the animation is: gf_smil_anim_evaluate * - * Depending on the timing status of the animation it calls: * - * - gf_smil_anim_animate * - * - gf_smil_anim_animate_with_fraction * - * - gf_smil_anim_freeze * - * - gf_smil_anim_remove * - * * - * The gf_smil_anim_animate consists in * - * - interpolating using gf_smil_anim_compute_interpolation_value * - * - accumulating using gf_smil_anim_apply_accumulate * - * - applying additive behavior * - * * - * Depending on the animation attributes, one of the following functions is called * - * by the function gf_smil_anim_compute_interpolation_value * - * - gf_smil_anim_set * - * - gf_smil_anim_animate_using_values * - * - gf_smil_anim_animate_from_to * - * - gf_smil_anim_animate_from_by * - * - gf_smil_anim_animate_using_path * - * * - * In most animation methods, the important step in the animation is to resolve * - * the inherit and currentColor values to perform further interpolation, i.e. calls: * - * gf_svg_attributes_resolve_currentColor(&info, &rai->owner->current_color_value); * - * gf_svg_attributes_resolve_inherit(&info, &rai->owner->parent_presentation_value); * - * * - **************************************************************************************/ -static void gf_smil_anim_set(SMIL_Anim_RTI *rai) -{ - GF_FieldInfo to_info; - SMILAnimationAttributesPointers *animp = rai->animp; - - if (!animp->to || !animp->to->type) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SMIL, - ("[SMIL Animation] Animation %s - set element without to attribute\n", - gf_node_get_log_name((GF_Node *)rai->anim_elt))); - return; - } - - if (rai->change_detection_mode) { - /* if the set has been applied, unless next animations are additive we don't need - to apply it again */ - if (rai->previous_coef > 0) rai->interpolated_value_changed = 0; - else rai->interpolated_value_changed = 1; - return; - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying set animation\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), - gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - to_info.fieldType = animp->to->type; - to_info.far_ptr = animp->to->value; - /* we do not need to resolve currentColor values or inherit values here, - because no further interpolation is required for the animation and - because inheritance is applied after animations in the compositor. */ - - gf_svg_attributes_copy(&rai->interpolated_value, &to_info, 0); - rai->previous_coef = FIX_ONE; - } -} - -static void gf_smil_anim_use_keypoints_keytimes(SMIL_Anim_RTI *rai, Fixed normalized_simple_time, - Fixed *interpolation_coefficient, u32 *keyValueIndex) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - u32 keyTimeIndex = 0; - Fixed interval_duration; - - *interpolation_coefficient = normalized_simple_time; - - /* Computing new interpolation coefficient */ - if (rai->key_times_count) { - Fixed keyTimeBefore = 0, keyTimeAfter=0; - for (keyTimeIndex = rai->previous_keytime_index; keyTimeIndex< rai->key_times_count; keyTimeIndex++) { - Fixed *tm1, *t = (Fixed *)gf_list_get(*animp->keyTimes, keyTimeIndex); - if (normalized_simple_time < *t) { - rai->previous_keytime_index = keyTimeIndex; - tm1 = (Fixed *) gf_list_get(*animp->keyTimes, keyTimeIndex-1); - if (tm1) keyTimeBefore = *tm1; - else keyTimeBefore = 0; - keyTimeAfter = *t; - break; - } - } - keyTimeIndex--; - interval_duration = keyTimeAfter - keyTimeBefore; - if (keyValueIndex) *keyValueIndex = keyTimeIndex; - if (interval_duration) - *interpolation_coefficient = gf_divfix(normalized_simple_time - keyTimeBefore, interval_duration); - else - *interpolation_coefficient = FIX_ONE; - if (!rai->change_detection_mode) - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - Using Key Times: index %d, interval duration %.2f, coeff: %.2f\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), - gf_node_get_log_name((GF_Node *)rai->anim_elt), - keyTimeIndex, - interval_duration, - interpolation_coefficient)); - } - - if (rai->anim_elt->sgprivate->tag == TAG_SVG_animateMotion && rai->key_points_count) { - Fixed *p1, *p2; - p1 = (Fixed *)gf_list_get(*animp->keyPoints, keyTimeIndex); - if (animp->calcMode && *animp->calcMode == SMIL_CALCMODE_DISCRETE) { - *interpolation_coefficient = *p1; - } else { - p2 = (Fixed *)gf_list_get(*animp->keyPoints, keyTimeIndex+1); - *interpolation_coefficient = gf_mulfix(FIX_ONE - *interpolation_coefficient, *p1) - + gf_mulfix(*interpolation_coefficient, (p2 ? *p2 : *p1)); - } - if (keyValueIndex) *keyValueIndex = 0; - if (!rai->change_detection_mode) - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - Using Key Points: key Point Index %d, coeff: %.2f\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyTimeIndex, *interpolation_coefficient)); - } -} - -static void gf_smil_anim_animate_using_values(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - GF_List *values = NULL; - GF_FieldInfo value_info, value_info_next; - u32 keyValueIndex; - Fixed interpolation_coefficient; - u32 real_calcMode; - - values = animp->values->values; - - memset(&value_info, 0, sizeof(GF_FieldInfo)); - value_info.fieldType = animp->values->type; - value_info_next = value_info; - - real_calcMode = (gf_svg_attribute_is_interpolatable(animp->values->type)? - (animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR): - SMIL_CALCMODE_DISCRETE - ); - - if (rai->values_count == 1) { - if (rai->change_detection_mode) { - /* Since we have only 1 value, the previous key index should always be 0, - unless the animation has not started or is reset (-1) */ - if (rai->previous_key_index == 0) rai->interpolated_value_changed = 0; - else rai->interpolated_value_changed = 1; - return; - } else { - value_info.far_ptr = gf_list_get(values, 0); - /* no further interpolation needed - therefore no need to resolve inherit and currentColor */ - gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); - rai->previous_key_index = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - Using values[0] as interpolation value\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - return; - } - } - - /* Computing new key value index and interpolation coefficient */ - if (!rai->key_times_count) { - if (real_calcMode == SMIL_CALCMODE_DISCRETE) { - if (normalized_simple_time == FIX_ONE) { - keyValueIndex = rai->values_count-1; - interpolation_coefficient = FIX_ONE; - } else { - Fixed tmp = normalized_simple_time*rai->values_count; - Fixed tmp_floor = gf_floor(tmp); - if ((tmp - tmp_floor) == 0 && tmp) { - keyValueIndex = FIX2INT(tmp_floor) - 1; - } else { - keyValueIndex = FIX2INT(tmp_floor); - } - interpolation_coefficient = tmp - INT2FIX(keyValueIndex); - } - } else { - Fixed tmp = normalized_simple_time*(rai->values_count-1); - if (normalized_simple_time == FIX_ONE) { - keyValueIndex = rai->values_count-2; - } else { - keyValueIndex = FIX2INT(gf_floor(tmp)); - } - interpolation_coefficient = tmp - INT2FIX(keyValueIndex); - } - //GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Animation] Time %f - Animation %s - No KeyTimes: key index %d, coeff: %.2f\n", gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex, FIX2FLT(interpolation_coefficient))); - } else { - gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, &keyValueIndex); - } - - if (rai->change_detection_mode) { - if (real_calcMode == SMIL_CALCMODE_DISCRETE && rai->previous_key_index == (s32)keyValueIndex && rai->previous_coef != -FIX_ONE) { - rai->interpolated_value_changed = 0; - } else if (rai->previous_key_index == (s32)keyValueIndex && rai->previous_coef == interpolation_coefficient) - rai->interpolated_value_changed = 0; - else - rai->interpolated_value_changed = 1; - } else { - rai->previous_key_index = keyValueIndex; - rai->previous_coef = interpolation_coefficient; - - switch (real_calcMode) { - case SMIL_CALCMODE_DISCRETE: - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying discrete animation using values (key value index: %d)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex)); - value_info.far_ptr = gf_list_get(values, keyValueIndex); - /* no further interpolation needed - therefore no need to resolve inherit and currentColor */ - gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); - break; - case SMIL_CALCMODE_PACED: - /* TODO: at the moment assume it is linear */ - case SMIL_CALCMODE_SPLINE: - /* TODO: at the moment assume it is linear */ - case SMIL_CALCMODE_LINEAR: - if (keyValueIndex == rai->values_count - 1) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying linear animation using values (setting last key value: %d)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex)); - value_info.far_ptr = gf_list_get(values, rai->values_count - 1); - /* no further interpolation needed - therefore no need to resolve inherit and currentColor */ - gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); - } else { - - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying linear animation using values (key value indices: %d, %d / coeff: %f)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex, keyValueIndex+1, interpolation_coefficient)); - value_info.far_ptr = gf_list_get(values, keyValueIndex); - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(animp->values->type)) { - gf_svg_attributes_resolve_currentColor(&value_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&value_info, &rai->owner->parent_presentation_value); - } - - value_info_next.far_ptr = gf_list_get(values, keyValueIndex+1); - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(animp->values->type)) { - gf_svg_attributes_resolve_currentColor(&value_info_next, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&value_info_next, &rai->owner->parent_presentation_value); - } - - gf_svg_attributes_interpolate(&value_info, - &value_info_next, - &rai->interpolated_value, - interpolation_coefficient, 1); - } - break; - } - } -} - -static void gf_smil_anim_animate_from_to(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - GF_FieldInfo from_info, to_info; - SMILAnimationAttributesPointers *animp = rai->animp; - Fixed interpolation_coefficient; - s32 useFrom = (normalized_simple_time<=FIX_ONE/2); - u32 real_calcMode; - - real_calcMode = (animp->to && gf_svg_attribute_is_interpolatable(animp->to->type)? - (animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR): - SMIL_CALCMODE_DISCRETE - ); - - if (rai->change_detection_mode) { - if (rai->previous_coef == normalized_simple_time) - rai->interpolated_value_changed = 0; - else { - if (real_calcMode == SMIL_CALCMODE_DISCRETE && - useFrom == rai->previous_key_index) { - rai->interpolated_value_changed = 0; - } else { - rai->interpolated_value_changed = 1; - } - } - } else { - - if (animp->from) { - from_info.fieldType = animp->from->type; - from_info.far_ptr = animp->from->value; - } else { - from_info.fieldType = 0; - from_info.far_ptr = NULL; - } - - if (rai->is_first_anim) - gf_svg_attributes_resolve_unspecified(&from_info, - &rai->owner->specified_value, - &rai->default_transform_value); - else - gf_svg_attributes_resolve_unspecified(&from_info, - &rai->owner->presentation_value, - &rai->default_transform_value); - - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { - gf_svg_attributes_resolve_currentColor(&from_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&from_info, &rai->owner->parent_presentation_value); - } - if (animp->to) { - to_info.fieldType = animp->to->type; - to_info.far_ptr = animp->to->value; - } else { - to_info.fieldType = 0; - to_info.far_ptr = NULL; - } - - if (rai->is_first_anim) - gf_svg_attributes_resolve_unspecified(&to_info, - &rai->owner->specified_value, - &rai->default_transform_value); - else - gf_svg_attributes_resolve_unspecified(&to_info, - &rai->owner->presentation_value, - &rai->default_transform_value); - - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(to_info.fieldType)) { - gf_svg_attributes_resolve_currentColor(&to_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&to_info, &rai->owner->parent_presentation_value); - } - - gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, NULL); - - rai->previous_coef = interpolation_coefficient; - - switch (real_calcMode) { - case SMIL_CALCMODE_DISCRETE: - { - /* before half of the duration stay at 'from' and then switch to 'to' */ - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-to animation (using %s value)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), (useFrom?"from":"to"))); - gf_svg_attributes_copy(&rai->interpolated_value, (useFrom?&from_info:&to_info), 0); - rai->previous_key_index = useFrom; - } - break; - case SMIL_CALCMODE_SPLINE: - case SMIL_CALCMODE_PACED: - case SMIL_CALCMODE_LINEAR: - default: - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-to animation (linear interpolation, using coefficient %f)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), interpolation_coefficient)); - gf_svg_attributes_interpolate(&from_info, &to_info, &rai->interpolated_value, interpolation_coefficient, 1); - break; - } - } -} - -static void gf_smil_anim_animate_from_by(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - Fixed from_coef; - GF_FieldInfo from_info, by_info; - SMILAnimationAttributesPointers *animp = rai->animp; - s32 useFrom = (normalized_simple_time<=FIX_ONE/2); - - if (rai->change_detection_mode) { - if (rai->previous_coef == normalized_simple_time) - rai->interpolated_value_changed = 0; - else { - if (animp->calcMode && - *animp->calcMode == SMIL_CALCMODE_DISCRETE && - useFrom == rai->previous_key_index) { - rai->interpolated_value_changed = 0; - } else { - rai->interpolated_value_changed = 1; - } - } - } else { - rai->previous_coef = normalized_simple_time; - - if (animp->from) { - from_info.fieldType = animp->from->type; - from_info.far_ptr = animp->from->value; - from_coef = FIX_ONE; - } else { - from_info.fieldType = 0; - from_info.far_ptr = NULL; - /* this is a by animation only, then, it is always additive, - we don't need the from value*/ - from_coef = 0; - } - - if (rai->is_first_anim) - gf_svg_attributes_resolve_unspecified(&from_info, - &rai->owner->specified_value, - &rai->default_transform_value); - else - gf_svg_attributes_resolve_unspecified(&from_info, - &rai->owner->presentation_value, - &rai->default_transform_value); - - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { - gf_svg_attributes_resolve_currentColor(&from_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&from_info, &rai->owner->parent_presentation_value); - } - - if (animp->by) { - by_info.fieldType = animp->by->type; - by_info.far_ptr = animp->by->value; - } else { - by_info.fieldType = 0; - by_info.far_ptr = NULL; - } - - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { - gf_svg_attributes_resolve_currentColor(&by_info, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&by_info, &rai->owner->parent_presentation_value); - } - - switch ((animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR)) { - case SMIL_CALCMODE_DISCRETE: - { - /* before half of the duration stay at 'from' and then switch to 'to' */ - if (useFrom) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (setting from)", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - gf_svg_attributes_muladd(from_coef, &from_info, 0, &by_info, &rai->interpolated_value, 0); - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (setting from+by)", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - gf_svg_attributes_muladd(from_coef, &from_info, FIX_ONE, &by_info, &rai->interpolated_value, 0); - } - rai->previous_key_index = useFrom; - } - break; - case SMIL_CALCMODE_SPLINE: - case SMIL_CALCMODE_PACED: - case SMIL_CALCMODE_LINEAR: - default: - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (linear interpolation between from and from+by, coef: %f)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), normalized_simple_time)); - gf_svg_attributes_muladd(from_coef, &from_info, normalized_simple_time, &by_info, &rai->interpolated_value, 0); - break; - } - } -} - -static void gf_svg_compute_path_anim(SMIL_Anim_RTI *rai, GF_Matrix2D *m, Fixed normalized_simple_time) -{ - Fixed offset; - offset = gf_mulfix(normalized_simple_time, rai->length); - gf_mx2d_init(*m); - - gf_path_iterator_get_transform(rai->path_iterator, offset, 1, m, 1, 0); - //GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("offset: %f, position: (%f, %f)", offset, ((GF_Matrix2D *)rai->interpolated_value.far_ptr)->m[2], ((GF_Matrix2D *)rai->interpolated_value.far_ptr)->m[5])); - switch (rai->rotate) { - case SVG_NUMBER_AUTO: - break; - case SVG_NUMBER_AUTO_REVERSE: - gf_mx2d_add_rotation(m, m->m[2], m->m[5], GF_PI); - break; - default: - m->m[0] = FIX_ONE; - m->m[1] = 0; - m->m[3] = 0; - m->m[4] = FIX_ONE; - } -} - -static void gf_smil_anim_animate_using_path(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - Fixed interpolation_coefficient; - - gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, NULL); - - if (rai->change_detection_mode) { - if (rai->previous_coef == interpolation_coefficient) - rai->interpolated_value_changed = 0; - else { - rai->interpolated_value_changed = 1; - } - } else { - rai->previous_coef = interpolation_coefficient; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying path animation (coef: %f)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), normalized_simple_time)); - - gf_svg_compute_path_anim(rai, (GF_Matrix2D*)rai->interpolated_value.far_ptr, interpolation_coefficient); - } -} - -static void gf_smil_anim_compute_interpolation_value(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - - if (rai->path) { - gf_smil_anim_animate_using_path(rai, normalized_simple_time); - } else if (rai->anim_elt->sgprivate->tag == TAG_SVG_set) { - gf_smil_anim_set(rai); - } else if (rai->values_count) { - /* Ignore 'from'/'to'/'by'*/ - gf_smil_anim_animate_using_values(rai, normalized_simple_time); - } else if ((animp->by && animp->by->type) && (!animp->to || animp->to->type == 0)) { - /* 'to' is not specified but 'by' is, so this is a 'by' animation or a 'from'-'by' animation */ - gf_smil_anim_animate_from_by(rai, normalized_simple_time); - } else { - /* Ignore 'by' if specified */ - gf_smil_anim_animate_from_to(rai, normalized_simple_time); - } - -#ifndef GPAC_DISABLE_LOG - if (0 && (gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char str[1000]; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - gf_svg_dump_attribute(rai->anim_elt, &rai->interpolated_value, str); - assert(strlen(str) < 1000); - gf_log("[SMIL Animation] Time %f - Animation %s - Interpolation value changed for attribute %s, new value: %s \n", - gf_node_get_scene_time(rai->anim_elt), gf_node_get_log_name(rai->anim_elt), - gf_svg_get_attribute_name(rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); - } -#endif -} - -void gf_smil_anim_set_anim_runtime_in_timing(GF_Node *n) -{ - u32 i, j; - SVGTimedAnimBaseElement *timed_elt = NULL; - SMIL_Timing_RTI *rti = NULL; - GF_Node *target = NULL; - - if (!n) return; - timed_elt = (SVGTimedAnimBaseElement *)n; - - if (!gf_svg_is_animation_tag(n->sgprivate->tag)) return; - - target = timed_elt->xlinkp->href->target; - if (!target) return; - - if (timed_elt->timingp) rti = timed_elt->timingp->runtime; - if (!rti) return; - - rti->rai = NULL; - - for (i = 0; i < gf_node_animation_count(target); i++) { - SMIL_Anim_RTI *rai_tmp; - SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(target, i); - j=0; - while ((rai_tmp = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { - if (rai_tmp->timingp->runtime == rti) { - rti->rai = rai_tmp; - return; - } - } - } -} - -static void gf_smil_anim_get_last_specified_value(SMIL_Anim_RTI *rai) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - - if (!animp) return; - - if (rai->path) { - if (!rai->last_specified_value.far_ptr) rai->last_specified_value.far_ptr = malloc(sizeof(GF_Matrix2D)); - gf_svg_compute_path_anim(rai, rai->last_specified_value.far_ptr, FIX_ONE); - return; - } else if (rai->anim_elt->sgprivate->tag == TAG_SVG_set) { - if (animp->to) { - rai->last_specified_value.fieldType = animp->to->type; - rai->last_specified_value.far_ptr = animp->to->value; - } else { - /* TODO ??? */ - GF_LOG(GF_LOG_ERROR, GF_LOG_SMIL, - ("[SMIL Animation] Animation %s - set element without to attribute\n", - gf_node_get_log_name((GF_Node *)rai->anim_elt))); - } - return; - } - - if (rai->values_count) { - /* Ignore from/to/by*/ - rai->last_specified_value.fieldType = animp->values->type; - rai->last_specified_value.far_ptr = gf_list_last(animp->values->values); - } else if ((animp->by && animp->by->type) && (!animp->to || animp->to->type == 0)) { - rai->last_specified_value.fieldType = animp->by->type; - rai->last_specified_value.far_ptr = animp->by->value; - } else if (animp->to) { - rai->last_specified_value.fieldType = animp->to->type; - rai->last_specified_value.far_ptr = animp->to->value; - } - if (gf_svg_is_inherit(&rai->last_specified_value)) { - rai->last_specified_value.fieldType = rai->owner->presentation_value.fieldType; - rai->last_specified_value.far_ptr = rai->owner->presentation_value.far_ptr; - } - if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(rai->last_specified_value.fieldType)) { - gf_svg_attributes_resolve_currentColor(&rai->last_specified_value, &rai->owner->current_color_value); - gf_svg_attributes_resolve_inherit(&rai->last_specified_value, &rai->owner->parent_presentation_value); - } -} - -/* if the animation behavior is accumulative and this is not the first iteration, - then we modify the interpolation value as follows: - interpolation value += last specified value * number of iterations completed */ -static void gf_smil_anim_apply_accumulate(SMIL_Anim_RTI *rai) -{ - u32 nb_iterations; - - SMILAnimationAttributesPointers *animp = rai->animp; - SMILTimingAttributesPointers *timingp = rai->timingp; - - nb_iterations = (timingp->runtime->current_interval ? timingp->runtime->current_interval->nb_iterations : 1); - - if (rai->change_detection_mode) { - if ((animp->accumulate && *animp->accumulate == SMIL_ACCUMULATE_SUM) - && nb_iterations > 0 - && rai->previous_iteration != (s32) nb_iterations) { - /* if we actually do accumulation and the number of iteration is different, - then we force the result as changed regardless of the result of the interpolation - (TODO: check if this need to be improved)*/ - rai->interpolated_value_changed = 1; - } else { - /* if we don't accumulate we leave the value of interpolated_value_changed unchanged */ - } - } else { - if (nb_iterations > 0 && rai->previous_iteration != (s32) nb_iterations) { - rai->previous_iteration = nb_iterations; - } - - if ((animp->accumulate && *animp->accumulate == SMIL_ACCUMULATE_SUM) && nb_iterations > 0) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying accumulation (iteration #%d)\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), nb_iterations)); - - gf_svg_attributes_muladd(FIX_ONE, &rai->interpolated_value, - INT2FIX(nb_iterations), &rai->last_specified_value, - &rai->interpolated_value, 1); - - if ((animp->from) && animp->by && (rai->last_specified_value.far_ptr == animp->by->value)) { - /* this is a from-by animation, the last specified value is not the 'by' value but actually 'from'+'by', - we need to add nb_iterations times from to the interpolated_value - see (animate-elem-210-t.svg (upper two circles in the mid column, after 9s/14s */ - GF_FieldInfo from_info; - from_info.fieldType = rai->animp->from->type; - from_info.far_ptr = rai->animp->from->value; - gf_svg_attributes_muladd(FIX_ONE, &rai->interpolated_value, - INT2FIX(nb_iterations), &from_info, - &rai->interpolated_value, 1); - } - } - } -} - -static void gf_smil_apply_additive(SMIL_Anim_RTI *rai) -{ - SMILAnimationAttributesPointers *animp = rai->animp; - if (rai->change_detection_mode) return; - else { - /* Apply additive behavior if required - PV = (additive == sum ? PV + animp->IV : animp->IV); */ - if (animp->additive && *animp->additive == SMIL_ADDITIVE_SUM) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying additive behavior\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - gf_svg_attributes_add((rai->is_first_anim ? &rai->owner->specified_value : &rai->owner->presentation_value), - &rai->interpolated_value, - &rai->owner->presentation_value, - 1); - -#ifndef GPAC_DISABLE_LOG - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char str[1000]; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value, str); - assert(strlen(str) < 1000); - gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), - gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); - } -#endif - - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying non-additive behavior\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - /* FIXME: if we switch pointers to avoid copying values, - we need to modify the address in the DOM node as well, - we also need to take care about change detections. Not easy!! - - void *tmp = rai->owner->presentation_value.far_ptr; - rai->owner->presentation_value.far_ptr = rai->interpolated_value.far_ptr; - rai->interpolated_value.far_ptr = tmp; - */ - - gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->interpolated_value, 1); -#ifndef GPAC_DISABLE_LOG - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char str[1000]; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value, str); - assert(strlen(str) < 1000); - gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), - gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); - } -#endif - } - } -} - -static void gf_smil_anim_animate(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) -{ - SMIL_Anim_RTI *rai = rti->rai; - SMILAnimationAttributesPointers *animp = rai->animp; - - if (!rai || !animp) return; - - gf_smil_anim_compute_interpolation_value(rai, normalized_simple_time); - gf_smil_anim_apply_accumulate(rai); - gf_smil_apply_additive(rai); -} - -static void gf_smil_anim_animate_with_fraction(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) -{ - gf_smil_anim_animate(rti, rti->fraction); - rti->evaluate_status = SMIL_TIMING_EVAL_NONE; -} - -void gf_smil_anim_reset_variables(SMIL_Anim_RTI *rai) -{ - if (!rai) return; - /* we reset all the animation parameters to force computation of next interpolation value - when the animation restarts */ - rai->interpolated_value_changed = 0; - rai->previous_key_index = -1; - rai->previous_coef = -FIX_ONE; - rai->previous_iteration = -1; - rai->previous_keytime_index = 0; - rai->anim_done = 0; -} - -/* copy/paste of the animate function - TODO: check if computations of interpolation value can be avoided. -*/ -static void gf_smil_anim_freeze(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) -{ - SMIL_Anim_RTI *rai = rti->rai; - SMILAnimationAttributesPointers *animp = rai->animp; - - if (!rai || !animp) return; - - if (rai->change_detection_mode) { - if (rai->anim_done == 0) - rai->interpolated_value_changed = 1; - else - rai->interpolated_value_changed = 0; - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying freeze behavior\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - gf_smil_anim_compute_interpolation_value(rai, normalized_simple_time); - gf_smil_anim_apply_accumulate(rai); - gf_smil_apply_additive(rai); - rai->anim_done = 1; - } -} - -static void gf_smil_anim_remove(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) -{ - SMIL_Anim_RTI *rai = rti->rai; - if (!rai) return; - - if (rai->change_detection_mode) { - if (rai->anim_done == 0) - rai->interpolated_value_changed = 1; - else - rai->interpolated_value_changed = 0; - } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, - ("[SMIL Animation] Time %f - Animation %s - applying remove behavior\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); - - /* TODO: see if we can avoid this copy by switching pointers */ - gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->owner->specified_value, 0); - /* TODO: check if we need to apply additive behavior even in fill='remove' - maybe (see animate-elem-211-t.svg) */ - - rai->anim_done = 1; - -#ifndef GPAC_DISABLE_LOG - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char str[1000]; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value, str); - assert(strlen(str) < 1000); - gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", - gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), - gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); - } -#endif - - } -} - -static void gf_smil_anim_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_simple_time, u32 state) -{ - SMIL_Anim_RTI *rai = rti->rai; - switch (state) { - case SMIL_TIMING_EVAL_REPEAT: - /* we are starting a new cycle of animation, therefore we need to reset the previous state variables - like previous_keytime_index ... */ - gf_smil_anim_reset_variables(rai); - case SMIL_TIMING_EVAL_UPDATE: - gf_smil_anim_animate(rti, normalized_simple_time); - break; - case SMIL_TIMING_EVAL_FREEZE: - gf_smil_anim_freeze(rti, normalized_simple_time); - break; - case SMIL_TIMING_EVAL_REMOVE: - gf_smil_anim_remove(rti, normalized_simple_time); - break; - case SMIL_TIMING_EVAL_FRACTION: - gf_smil_anim_animate_with_fraction(rti, normalized_simple_time); - break; -/* - discard should be done before in smil_notify_time - case SMIL_TIMING_EVAL_DISCARD: - break; -*/ - } -} -/************************************************************************************** - **************************************************************************************/ - -GF_EXPORT -void gf_svg_apply_animations(GF_Node *node, SVGPropertiesPointers *render_svg_props) -{ - u32 count_all, i; -#ifndef GPAC_DISABLE_LOG - u32 time=0; - u32 active_anim; - - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RTI)) { - time = gf_sys_clock(); - } -#endif - - /* Perform all the animations on this node */ - count_all = gf_node_animation_count(node); - for (i = 0; i < count_all; i++) { - GF_FieldInfo info; - s32 j; - u32 count; - SMIL_AttributeAnimations *aa; - - - aa = (SMIL_AttributeAnimations *)gf_node_animation_get(node, i); - count = gf_list_count(aa->anims); - if (!count) continue; - - aa->presentation_value_changed = 0; - - if (aa->is_property) { - /* Storing the pointer to the parent presentation value, - i.e. the presentation value produced at the parent level in the tree */ - aa->parent_presentation_value = aa->presentation_value; - aa->parent_presentation_value.far_ptr = - gf_svg_get_property_pointer((SVG_Element *)node, aa->orig_dom_ptr, render_svg_props); - - /* Storing also the pointer to the presentation value of the color property - (special handling of the keyword 'currentColor' if used in animation values) */ - gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_color, 1, 1, &info); - aa->current_color_value.far_ptr = info.far_ptr; - } - - /* We start with the last animation (TODO in the execution order), then scan in the reverse order - up to the first animation which is not additive, to determine if the presentation value will change - We evaluate each animation, but only in the 'change_detection_mode' */ - for (j = count-1; j >= 0; j--) { - SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j); - SMIL_Timing_RTI *rti = rai->timingp->runtime; - - rai->interpolated_value_changed = 0; - - /* The evaluate_status has been updated when notifying the new scene time to this animation, - i.e. before the scene tree traversal */ - if (rti->evaluate_status) { - rai->change_detection_mode = 1; - rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); - aa->presentation_value_changed += rai->interpolated_value_changed; - if (!rai->animp->additive || *rai->animp->additive == SMIL_ADDITIVE_REPLACE) { - /* we don't need to check previous animations since this one will overwrite it */ - j--; - break; - } - } - } - - active_anim = 0; - if (aa->presentation_value_changed) { - /* If the result of all the combined animations will produce a different result compared to the previous frame, - we start in the forward order from the j were the previous step stopped (i.e. the first anim in replace mode) - and evaluate each animation, in the computation mode (change_detection_mode = 0)*/ - for (j++; j<(s32)count; j++) { - SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j); - SMIL_Timing_RTI *rti = rai->timingp->runtime; - - if (j == 0) rai->is_first_anim = 1; - else rai->is_first_anim = 0; - - if (rti->evaluate_status) { - rai->change_detection_mode = 0; - rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); - active_anim++; - } - } - } - -/* DEBUG: uncomment this line to remove animation effect, and keep animation computation */ -// gf_svg_attributes_copy(&aa->presentation_value, &aa->specified_value, 0); - -#ifndef GPAC_DISABLE_LOG - if (aa->presentation_value_changed) { - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { - char str[1000]; - gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); - gf_svg_dump_attribute(node, &aa->presentation_value, str); - assert(strlen(str) < 1000); - gf_log("[SMIL Animation] Time %f - Element %s - Presentation value changed for attribute %s, new value: %s - dirty flags %x\n", - gf_node_get_scene_time(node), gf_node_get_log_name(node), - gf_svg_get_attribute_name(node, aa->presentation_value.fieldIndex), str, aa->dirty_flags); - } - } -#endif - - /* we only set dirty flags when a real flag is set to avoid unnecessary computation - for example, it is not necessary to set it when the anim is an animateTransform - since there is no associated flag */ - if (aa->dirty_flags) { - if (aa->presentation_value_changed) { - gf_node_dirty_set(node, aa->dirty_flags, aa->dirty_parents); - } else { - /* WARNING - This does not work for use elements because apply_animations may be called several times */ - if (active_anim) gf_node_dirty_clear(node, aa->dirty_flags); - } - } - } - -#ifndef GPAC_DISABLE_LOG - if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RTI)) { - time_spent_in_anim += gf_sys_clock() - time; - } -#endif -} - - - -void gf_smil_anim_init_runtime_info(GF_Node *e) -{ - u32 i; - GF_FieldInfo target_attribute; - SMIL_AttributeAnimations *aa = NULL; - SMIL_Anim_RTI *rai; - XLinkAttributesPointers *xlinkp = NULL; - SMILAnimationAttributesPointers *animp = NULL; - SMILTimingAttributesPointers *timingp = NULL; - GF_Node *target = NULL; - - if (!e) return; - - /* Filling animation structures to be independent of the SVG Element structure */ - animp = ((SVGTimedAnimBaseElement *)e)->animp; - timingp = ((SVGTimedAnimBaseElement *)e)->timingp; - xlinkp = ((SVGTimedAnimBaseElement *)e)->xlinkp; - - target = xlinkp->href->target; - - memset(&target_attribute, 0, sizeof(GF_FieldInfo)); - if (animp->attributeName && (animp->attributeName->name || animp->attributeName->tag)) { - /* Filling the target_attribute structure with info on the animated attribute (type, pointer to data, ...) - NOTE: in the mode Dynamic Allocation of Attributes, this means that the animated - attribute is created with a default value, if it was not specified on the target element */ - if (animp->attributeName->tag) { - gf_node_get_attribute_by_tag(target, animp->attributeName->tag, 1, 1, &target_attribute); - } else { - gf_node_get_field_by_name(target, animp->attributeName->name, &target_attribute); - } - } else { - /* All animation elements should have a target attribute except for animateMotion - cf http://www.w3.org/mid/u403c21ajf1sjqtk58g0g38eaep9f9g2ss@hive.bjoern.hoehrmann.de - "For animateMotion, the attributeName is implied and cannot be specified; - animateTransform requires specification of the attribute name and any attribute that is - a transform-like attribute can be a target, e.g. gradientTransform."*/ - - switch (e->sgprivate->tag) { - case TAG_SVG_animateMotion: - /* Explicit creation of the pseudo 'motionTransform' attribute since it cannot be specified */ - gf_node_get_attribute_by_tag(target, TAG_SVG_ATT_motionTransform, 1, 0, &target_attribute); - gf_mx2d_init(*(GF_Matrix2D *)target_attribute.far_ptr); - break; - default: - GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, - ("[SMIL Animation] Missing attributeName attribute on element %s\n", - gf_node_get_log_name((GF_Node*)e) )); - return; - } - } - - if (animp->attributeType && *animp->attributeType == SMIL_ATTRIBUTETYPE_CSS) { - /* see example animate-elem-219-t.svg from the SVG test suite, upper row */ - if (!gf_svg_is_property(target, &target_attribute)) { - GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, - ("[SMIL Animation] Using CSS attributeType for an animation on an attribute which is not a property %s\n", - gf_node_get_log_name((GF_Node*)e) )); - return; - } - } - - /* Creation and setup of the runtime structure for animation */ - GF_SAFEALLOC(rai, SMIL_Anim_RTI) - - rai->anim_elt = e; - rai->animp = animp; - rai->timingp = timingp; - rai->xlinkp = xlinkp; - - gf_mx2d_init(rai->identity); - rai->default_transform_value.far_ptr = &rai->identity; - rai->default_transform_value.fieldType = SVG_Transform_datatype; - - /* the interpolated value has the same type as the target attribute, - but we need to create a new pointer to hold its value */ - rai->interpolated_value = target_attribute; - rai->interpolated_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType); - - /* there has not been any interpolation yet, so the previous key index and interpolation coefficient - shall not be set*/ - gf_smil_anim_reset_variables(rai); - - rai->values_count = (animp->values ? gf_list_count(animp->values->values) : 0); - rai->key_times_count = (animp->keyTimes ? gf_list_count(*animp->keyTimes) : 0); - rai->key_points_count = (animp->keyPoints ? gf_list_count(*animp->keyPoints) : 0); - rai->key_splines_count = (animp->keySplines ? gf_list_count(*animp->keySplines) : 0); - - - if (!rai->values_count && /* 'values' attribute not specified */ - (!animp->to || animp->to->type == 0) && /* 'to' attribute not specified */ - (!animp->from || animp->from->type == 0) && /* 'from' attribute not specified */ - (animp->by && animp->by->type != 0)) { /* 'by' attribute specified */ - /* if this is a 'by' animation without from the animation is defined to be additive - see http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#AnimationNS-FromToBy - we override the additive attribute */ - if (!animp->additive) { - /* this case can only happen with dynamic allocation of attributes */ - GF_FieldInfo info; - gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_additive, 1, 0, &info); - animp->additive = info.far_ptr; - } - if (*animp->additive == SMIL_ADDITIVE_REPLACE) { - GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, ("[SMIL Animation] Warning: by-animations cannot use additive=\"replace\"\n")); - } - *animp->additive = SMIL_ADDITIVE_SUM; - } - - /*TODO - http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation - To animation defines its own kind of additive semantics, so the additive attribute is ignored. - */ - - /*TODO - http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation - Because to animation is defined in terms of absolute values of the target attribute, - cumulative animation is not defined: - */ - - /* TODO - http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-setElement - The set element is non-additive. The additive and accumulate attributes are not allowed, - and will be ignored if specified. - */ - - /* For animateMotion, we need to retrieve the value of the rotate attribute, retrieve the path either - from the 'path' attribute or from the 'mpath' element, and then initialize the path iterator*/ - if (e->sgprivate->tag == TAG_SVG_animateMotion) { - GF_Path *the_path = NULL; - GF_ChildNodeItem *child = NULL; - - GF_FieldInfo info; - if (gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_rotate, 0, 0, &info) == GF_OK) { - rai->rotate = ((SVG_Rotate *)info.far_ptr)->type; - } else { - rai->rotate = SVG_NUMBER_VALUE; - } - if (gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_path, 0, 0, &info) == GF_OK) { - the_path = ((SVG_PathData *)info.far_ptr); - } - child = ((SVG_Element *)e)->children; - - if ((!animp->to || animp->to->type == 0) && - (!animp->by || animp->by->type == 0) && - (!animp->values || animp->values->type == 0)) { -#if USE_GF_PATH - if (!gf_path_is_empty(the_path)) { - rai->path = the_path; - rai->path_iterator = gf_path_iterator_new(rai->path); - rai->length = gf_path_iterator_get_length(rai->path_iterator); - } -#else - rai->path = gf_path_new(); - if (gf_list_count(the_path->points)) { - gf_svg_path_build(rai->path, the_path->commands, the_path->points); - rai->path_iterator = gf_path_iterator_new(rai->path); - rai->length = gf_path_iterator_get_length(rai->path_iterator); - } -#endif - else { - while (child) { - GF_Node *used_path = NULL; - u32 child_tag = gf_node_get_tag(child->node); - if (child_tag == TAG_SVG_mpath) { - GF_FieldInfo info; - if (gf_node_get_attribute_by_tag(child->node, TAG_XLINK_ATT_href, 0, 0, &info) == GF_OK) { - XMLRI *iri = (XMLRI *)info.far_ptr; - if (iri->target) used_path = iri->target; - else if (iri->string) used_path = - (GF_Node *)gf_sg_find_node_by_name(gf_node_get_graph(child->node), iri->string); - if (used_path && gf_node_get_tag(used_path) == TAG_SVG_path) { - gf_node_get_attribute_by_tag(used_path, TAG_SVG_ATT_d, 1, 0, &info); -#if USE_GF_PATH - rai->path = (SVG_PathData *)info.far_ptr; -#else - gf_svg_path_build(rai->path, - ((SVG_PathData *)info.far_ptr)->commands, - ((SVG_PathData *)info.far_ptr)->points); -#endif - rai->path_iterator = gf_path_iterator_new(rai->path); - rai->length = gf_path_iterator_get_length(rai->path_iterator); - } - } - break; - } - child = child->next; - } - } - } - } - - /* for all animations, check if there is already one animation on this attribute, - if yes, get the list and append the new animation runtime info - if no, create a list and add the new animation runtime info. */ - for (i = 0; i < gf_node_animation_count(target); i++) { - aa = (SMIL_AttributeAnimations *)gf_node_animation_get(target, i); - if (aa->presentation_value.fieldIndex == target_attribute.fieldIndex) { - gf_list_add(aa->anims, rai); - break; - } - aa = NULL; - } - if (!aa) { - GF_SAFEALLOC(aa, SMIL_AttributeAnimations) - - /* We determine if the animated attribute is a property since this changes quite a lot the animation model */ - aa->is_property = gf_svg_is_property(target, &target_attribute); - aa->current_color_value.fieldType = SVG_Paint_datatype; - - /* We copy (one copy for all animations on the same attribute) the DOM specified - value before any animation starts (because the animation will override it), - we also save the initial memory address of the specified value (orig_dom_ptr) - for inheritance hack */ - aa->specified_value = target_attribute; - aa->orig_dom_ptr = aa->specified_value.far_ptr; - aa->specified_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType); - gf_svg_attributes_copy(&aa->specified_value, &target_attribute, 0); - - /* Now, the initial memory address of the specified value holds the presentation value, - and the presentation value is initialized */ - aa->presentation_value = target_attribute; - - aa->anims = gf_list_new(); - gf_list_add(aa->anims, rai); - gf_node_animation_add(target, aa); - - /* determine what the rendering will need to do when the animation runs */ - aa->dirty_flags = gf_svg_get_modification_flags((SVG_Element *)target, &target_attribute); - - /* If the animation will result in a change of geometry or of the display property, - this animation will require traversing the tree, we need to inform the parents of the target node */ - aa->dirty_parents = 0; - if (aa->dirty_flags & (GF_SG_SVG_GEOMETRY_DIRTY | GF_SG_SVG_DISPLAY_DIRTY)) aa->dirty_parents = 1; - } - - rai->owner = aa; - gf_smil_anim_get_last_specified_value(rai); - - /* for animation (unlike other timed elements like video), the evaluation (i.e. interpolation) cannot be done - during timing evaluation, because due to inheritance, interpolation can only be computed - during scene tree traversal, therefore we need to postpone evaluation of the timed element */ - timingp->runtime->postpone = 1; - - timingp->runtime->evaluate = gf_smil_anim_evaluate; -} - -void gf_smil_anim_delete_runtime_info(SMIL_Anim_RTI *rai) -{ - gf_svg_delete_attribute_value(rai->interpolated_value.fieldType, - rai->interpolated_value.far_ptr, - rai->anim_elt->sgprivate->scenegraph); - if (rai->path) { - gf_svg_delete_attribute_value(rai->last_specified_value.fieldType, - rai->last_specified_value.far_ptr, - rai->anim_elt->sgprivate->scenegraph); - } -#if USE_GF_PATH -#else - if (rai->path) gf_path_del(rai->path); -#endif - if (rai->path_iterator) gf_path_iterator_del(rai->path_iterator); - free(rai); -} - -void gf_smil_anim_remove_from_target(GF_Node *anim, GF_Node *target) -{ - u32 i, j; - if (!target) return; - for (i = 0; i < gf_node_animation_count((GF_Node *)target); i ++) { - SMIL_Anim_RTI *rai; - SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get((GF_Node *)target, i); - j=0; - while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { - if ((GF_Node *)rai->anim_elt == anim) { - gf_list_rem(aa->anims, j-1); - gf_smil_anim_delete_runtime_info(rai); - break; - } - } - if (gf_list_count(aa->anims) == 0) { - gf_list_del(aa->anims); - gf_svg_delete_attribute_value(aa->specified_value.fieldType, - aa->specified_value.far_ptr, - target->sgprivate->scenegraph); - aa->presentation_value.far_ptr = aa->orig_dom_ptr; - gf_node_animation_rem((GF_Node *)target, i); - free(aa); - } - } -} - -void gf_smil_anim_delete_animations(GF_Node *e) -{ - u32 i, j; - - for (i = 0; i < gf_node_animation_count(e); i ++) { - SMIL_Anim_RTI *rai; - SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(e, i); - gf_svg_delete_attribute_value(aa->specified_value.fieldType, - aa->specified_value.far_ptr, - e->sgprivate->scenegraph); - j=0; - while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { - rai->xlinkp->href->target = NULL; - gf_smil_anim_delete_runtime_info(rai); - } - gf_list_del(aa->anims); - free(aa); - } - gf_node_animation_del(e); -} - -void gf_smil_anim_init_discard(GF_Node *node) -{ - SVGAllAttributes all_atts; - XLinkAttributesPointers *xlinkp = NULL; - SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; - gf_smil_timing_init_runtime_info(node); - - gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); - GF_SAFEALLOC(e->xlinkp, XLinkAttributesPointers); - xlinkp = e->xlinkp; - xlinkp->href = all_atts.xlink_href; - xlinkp->type = all_atts.xlink_type; - - e->timingp->runtime->evaluate_status = SMIL_TIMING_EVAL_DISCARD; -} - -void gf_smil_anim_init_node(GF_Node *node) -{ - XLinkAttributesPointers *xlinkp = NULL; - SMILAnimationAttributesPointers *animp = NULL; - SVGAllAttributes all_atts; - SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; - - gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); - e->xlinkp = malloc(sizeof(XLinkAttributesPointers)); - xlinkp = e->xlinkp; - xlinkp->href = all_atts.xlink_href; - xlinkp->type = all_atts.xlink_type; - - e->animp = malloc(sizeof(SMILAnimationAttributesPointers)); - animp = e->animp; - animp->accumulate = all_atts.accumulate; - animp->additive = all_atts.additive; - animp->attributeName = all_atts.attributeName; - animp->attributeType = all_atts.attributeType; - animp->by = all_atts.by; - animp->calcMode = all_atts.calcMode; - animp->from = all_atts.from; - animp->keySplines = all_atts.keySplines; - animp->keyTimes = all_atts.keyTimes; - animp->lsr_enabled = all_atts.lsr_enabled; - animp->to = all_atts.to; - animp->type = all_atts.transform_type; - animp->values = all_atts.values; - if (node->sgprivate->tag == TAG_SVG_animateMotion) { - e->animp->keyPoints = all_atts.keyPoints; - e->animp->origin = all_atts.origin; - e->animp->path = all_atts.path; - e->animp->rotate = all_atts.rotate; - } else { - e->animp->keyPoints = NULL; - e->animp->origin = NULL; - e->animp->path = NULL; - e->animp->rotate = NULL; - } - - if (xlinkp->href->type == XMLRI_STRING) { - if (!xlinkp->href->string) { - fprintf(stderr, "Error: IRI not initialized\n"); - return; - } else { - GF_Node *n; - - n = (GF_Node*)gf_sg_find_node_by_name(gf_node_get_graph(node), xlinkp->href->string); - if (n) { - xlinkp->href->type = XMLRI_ELEMENTID; - xlinkp->href->target = n; - gf_node_register_iri(node->sgprivate->scenegraph, xlinkp->href); - } else { - return; - } - } - } - if (!xlinkp->href->target) return; - - gf_smil_timing_init_runtime_info(node); - gf_smil_anim_init_runtime_info(node); - gf_smil_anim_set_anim_runtime_in_timing(node); -} - - - -#endif /*GPAC_DISABLE_SVG*/ +/* + * GPAC - Multimedia Framework C SDK + * + * Authors: Cyril Concolato - Jean Le Feuvre + * Copyright (c)2004-200X ENST - All rights reserved + * + * This file is part of GPAC / SVG Scene Graph 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/scenegraph_dev.h> +#include <gpac/nodes_svg.h> + +#ifndef GPAC_DISABLE_LOG +u32 time_spent_in_anim = 0; +#endif + +#ifndef GPAC_DISABLE_SVG + + +/************************************************************************************** + * Each GF_Node holds the (SVG/SMIL) animation elements which target itself in a list * + * The following are the generic functions to manipulate this list: * + * - add a new animation to the list, * + * - get an animation from the list, * + * - remove an animation from the list, * + * - count the animations in the list, * + * - delete the list * + **************************************************************************************/ +GF_Err gf_node_animation_add(GF_Node *node, void *animation) +{ + if (!node || !animation) return GF_BAD_PARAM; + if (!node->sgprivate->interact) GF_SAFEALLOC(node->sgprivate->interact, struct _node_interactive_ext); + if (!node->sgprivate->interact->animations) node->sgprivate->interact->animations = gf_list_new(); + return gf_list_add(node->sgprivate->interact->animations, animation); +} + +GF_Err gf_node_animation_del(GF_Node *node) +{ + if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return GF_BAD_PARAM; + gf_list_del(node->sgprivate->interact->animations); + node->sgprivate->interact->animations = NULL; + return GF_OK; +} + +u32 gf_node_animation_count(GF_Node *node) +{ + if (!node || !node->sgprivate->interact|| !node->sgprivate->interact->animations) return 0; + return gf_list_count(node->sgprivate->interact->animations); +} + +void *gf_node_animation_get(GF_Node *node, u32 i) +{ + if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return 0; + return gf_list_get(node->sgprivate->interact->animations, i); +} + +GF_Err gf_node_animation_rem(GF_Node *node, u32 i) +{ + if (!node || !node->sgprivate->interact || !node->sgprivate->interact->animations) return GF_OK; + return gf_list_rem(node->sgprivate->interact->animations, i); +} +/************************************************************************************** + * End of Generic GF_Node animations list * + **************************************************************************************/ + + +/************************************************************************************** + * Helping functions for animation * + **************************************************************************************/ +/* Sets the pointer to the attribute value with the pointer + to the value which passed (if unspecified) */ +void gf_svg_attributes_resolve_unspecified(GF_FieldInfo *in, GF_FieldInfo *p, GF_FieldInfo *t) +{ + if (in->fieldType == 0) { + if (p->fieldType == SVG_Transform_datatype) { + /* if the input value is not specified, and the presentation value is of type Transform, + then we should use the default identity transform instead of the presentation value */ + *in = *t; + } else { + *in = *p; + } + } +} + +/* Replaces the pointer to the attribute value with the pointer + to the value which is inherited (if inherited) */ +void gf_svg_attributes_resolve_inherit(GF_FieldInfo *in, GF_FieldInfo *prop) +{ + if (gf_svg_is_inherit(in)) *in = *prop; +} + +/* Replaces the pointer to the attribute value with the pointer + to the value of the color attribute (if the current value is set to currentColor) */ +void gf_svg_attributes_resolve_currentColor(GF_FieldInfo *in, GF_FieldInfo *current_color) +{ + if ((in->fieldType == SVG_Paint_datatype) && gf_svg_is_current_color(in)) { + *in = *current_color; + } +} + +/************************************************************************************** + * The main function doing evaluation of the animation is: gf_smil_anim_evaluate * + * Depending on the timing status of the animation it calls: * + * - gf_smil_anim_animate * + * - gf_smil_anim_animate_with_fraction * + * - gf_smil_anim_freeze * + * - gf_smil_anim_remove * + * * + * The gf_smil_anim_animate consists in * + * - interpolating using gf_smil_anim_compute_interpolation_value * + * - accumulating using gf_smil_anim_apply_accumulate * + * - applying additive behavior * + * * + * Depending on the animation attributes, one of the following functions is called * + * by the function gf_smil_anim_compute_interpolation_value * + * - gf_smil_anim_set * + * - gf_smil_anim_animate_using_values * + * - gf_smil_anim_animate_from_to * + * - gf_smil_anim_animate_from_by * + * - gf_smil_anim_animate_using_path * + * * + * In most animation methods, the important step in the animation is to resolve * + * the inherit and currentColor values to perform further interpolation, i.e. calls: * + * gf_svg_attributes_resolve_currentColor(&info, &rai->owner->current_color_value); * + * gf_svg_attributes_resolve_inherit(&info, &rai->owner->parent_presentation_value); * + * * + **************************************************************************************/ +static void gf_smil_anim_set(SMIL_Anim_RTI *rai) +{ + GF_FieldInfo to_info; + SMILAnimationAttributesPointers *animp = rai->animp; + + if (!animp->to || !animp->to->type) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SMIL, + ("[SMIL Animation] Animation %s - set element without to attribute\n", + gf_node_get_log_name((GF_Node *)rai->anim_elt))); + return; + } + + if (rai->change_detection_mode) { + /* if the set has been applied, unless next animations are additive we don't need + to apply it again */ + if (rai->previous_coef > 0) rai->interpolated_value_changed = 0; + else rai->interpolated_value_changed = 1; + return; + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying set animation\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), + gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + to_info.fieldType = animp->to->type; + to_info.far_ptr = animp->to->value; + /* we do not need to resolve currentColor values or inherit values here, + because no further interpolation is required for the animation and + because inheritance is applied after animations in the compositor. */ + + gf_svg_attributes_copy(&rai->interpolated_value, &to_info, 0); + rai->previous_coef = FIX_ONE; + } +} + +static void gf_smil_anim_use_keypoints_keytimes(SMIL_Anim_RTI *rai, Fixed normalized_simple_time, + Fixed *interpolation_coefficient, u32 *keyValueIndex) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + u32 keyTimeIndex = 0; + Fixed interval_duration; + + *interpolation_coefficient = normalized_simple_time; + + /* Computing new interpolation coefficient */ + if (rai->key_times_count) { + Fixed keyTimeBefore = 0, keyTimeAfter=0; + for (keyTimeIndex = rai->previous_keytime_index; keyTimeIndex< rai->key_times_count; keyTimeIndex++) { + Fixed *tm1, *t = (Fixed *)gf_list_get(*animp->keyTimes, keyTimeIndex); + if (normalized_simple_time < *t) { + rai->previous_keytime_index = keyTimeIndex; + tm1 = (Fixed *) gf_list_get(*animp->keyTimes, keyTimeIndex-1); + if (tm1) keyTimeBefore = *tm1; + else keyTimeBefore = 0; + keyTimeAfter = *t; + break; + } + } + keyTimeIndex--; + interval_duration = keyTimeAfter - keyTimeBefore; + if (keyValueIndex) *keyValueIndex = keyTimeIndex; + if (interval_duration) + *interpolation_coefficient = gf_divfix(normalized_simple_time - keyTimeBefore, interval_duration); + else + *interpolation_coefficient = FIX_ONE; + if (!rai->change_detection_mode) + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - Using Key Times: index %d, interval duration %.2f, coeff: %.2f\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), + gf_node_get_log_name((GF_Node *)rai->anim_elt), + keyTimeIndex, + interval_duration, + interpolation_coefficient)); + } + + if (rai->anim_elt->sgprivate->tag == TAG_SVG_animateMotion && rai->key_points_count) { + Fixed *p1, *p2; + p1 = (Fixed *)gf_list_get(*animp->keyPoints, keyTimeIndex); + if (animp->calcMode && *animp->calcMode == SMIL_CALCMODE_DISCRETE) { + *interpolation_coefficient = *p1; + } else { + p2 = (Fixed *)gf_list_get(*animp->keyPoints, keyTimeIndex+1); + *interpolation_coefficient = gf_mulfix(FIX_ONE - *interpolation_coefficient, *p1) + + gf_mulfix(*interpolation_coefficient, (p2 ? *p2 : *p1)); + } + if (keyValueIndex) *keyValueIndex = 0; + if (!rai->change_detection_mode) + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - Using Key Points: key Point Index %d, coeff: %.2f\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyTimeIndex, *interpolation_coefficient)); + } +} + +static void gf_smil_anim_animate_using_values(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + GF_List *values = NULL; + GF_FieldInfo value_info, value_info_next; + u32 keyValueIndex; + Fixed interpolation_coefficient; + u32 real_calcMode; + + values = animp->values->values; + + memset(&value_info, 0, sizeof(GF_FieldInfo)); + value_info.fieldType = animp->values->type; + value_info_next = value_info; + + real_calcMode = (gf_svg_attribute_is_interpolatable(animp->values->type)? + (animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR): + SMIL_CALCMODE_DISCRETE + ); + + if (rai->values_count == 1) { + if (rai->change_detection_mode) { + /* Since we have only 1 value, the previous key index should always be 0, + unless the animation has not started or is reset (-1) */ + if (rai->previous_key_index == 0) rai->interpolated_value_changed = 0; + else rai->interpolated_value_changed = 1; + return; + } else { + value_info.far_ptr = gf_list_get(values, 0); + /* no further interpolation needed + therefore no need to resolve inherit and currentColor */ + gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); + rai->previous_key_index = 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - Using values[0] as interpolation value\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + return; + } + } + + /* Computing new key value index and interpolation coefficient */ + if (!rai->key_times_count) { + if (real_calcMode == SMIL_CALCMODE_DISCRETE) { + if (normalized_simple_time == FIX_ONE) { + keyValueIndex = rai->values_count-1; + interpolation_coefficient = FIX_ONE; + } else { + Fixed tmp = normalized_simple_time*rai->values_count; + Fixed tmp_floor = gf_floor(tmp); + if ((tmp - tmp_floor) == 0 && tmp) { + keyValueIndex = FIX2INT(tmp_floor) - 1; + } else { + keyValueIndex = FIX2INT(tmp_floor); + } + interpolation_coefficient = tmp - INT2FIX(keyValueIndex); + } + } else { + Fixed tmp = normalized_simple_time*(rai->values_count-1); + if (normalized_simple_time == FIX_ONE) { + keyValueIndex = rai->values_count-2; + } else { + keyValueIndex = FIX2INT(gf_floor(tmp)); + } + interpolation_coefficient = tmp - INT2FIX(keyValueIndex); + } + //GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Animation] Time %f - Animation %s - No KeyTimes: key index %d, coeff: %.2f\n", gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex, FIX2FLT(interpolation_coefficient))); + } else { + gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, &keyValueIndex); + } + + if (rai->change_detection_mode) { + if (real_calcMode == SMIL_CALCMODE_DISCRETE && rai->previous_key_index == (s32)keyValueIndex && rai->previous_coef != -FIX_ONE) { + rai->interpolated_value_changed = 0; + } else if (rai->previous_key_index == (s32)keyValueIndex && rai->previous_coef == interpolation_coefficient) + rai->interpolated_value_changed = 0; + else + rai->interpolated_value_changed = 1; + } else { + rai->previous_key_index = keyValueIndex; + rai->previous_coef = interpolation_coefficient; + + switch (real_calcMode) { + case SMIL_CALCMODE_DISCRETE: + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying discrete animation using values (key value index: %d)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex)); + value_info.far_ptr = gf_list_get(values, keyValueIndex); + /* no further interpolation needed + therefore no need to resolve inherit and currentColor */ + gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); + break; + case SMIL_CALCMODE_PACED: + /* TODO: at the moment assume it is linear */ + case SMIL_CALCMODE_SPLINE: + /* TODO: at the moment assume it is linear */ + case SMIL_CALCMODE_LINEAR: + if (keyValueIndex == rai->values_count - 1) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying linear animation using values (setting last key value: %d)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex)); + value_info.far_ptr = gf_list_get(values, rai->values_count - 1); + /* no further interpolation needed + therefore no need to resolve inherit and currentColor */ + gf_svg_attributes_copy(&rai->interpolated_value, &value_info, 0); + } else { + + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying linear animation using values (key value indices: %d, %d / coeff: %f)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), keyValueIndex, keyValueIndex+1, interpolation_coefficient)); + value_info.far_ptr = gf_list_get(values, keyValueIndex); + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(animp->values->type)) { + gf_svg_attributes_resolve_currentColor(&value_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&value_info, &rai->owner->parent_presentation_value); + } + + value_info_next.far_ptr = gf_list_get(values, keyValueIndex+1); + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(animp->values->type)) { + gf_svg_attributes_resolve_currentColor(&value_info_next, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&value_info_next, &rai->owner->parent_presentation_value); + } + + gf_svg_attributes_interpolate(&value_info, + &value_info_next, + &rai->interpolated_value, + interpolation_coefficient, 1); + } + break; + } + } +} + +static void gf_smil_anim_animate_from_to(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + GF_FieldInfo from_info, to_info; + SMILAnimationAttributesPointers *animp = rai->animp; + Fixed interpolation_coefficient; + s32 useFrom = (normalized_simple_time<=FIX_ONE/2); + u32 real_calcMode; + + real_calcMode = (animp->to && gf_svg_attribute_is_interpolatable(animp->to->type)? + (animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR): + SMIL_CALCMODE_DISCRETE + ); + + if (rai->change_detection_mode) { + if (rai->previous_coef == normalized_simple_time) + rai->interpolated_value_changed = 0; + else { + if (real_calcMode == SMIL_CALCMODE_DISCRETE && + useFrom == rai->previous_key_index) { + rai->interpolated_value_changed = 0; + } else { + rai->interpolated_value_changed = 1; + } + } + } else { + + if (animp->from) { + from_info.fieldType = animp->from->type; + from_info.far_ptr = animp->from->value; + } else { + from_info.fieldType = 0; + from_info.far_ptr = NULL; + } + + if (rai->is_first_anim) + gf_svg_attributes_resolve_unspecified(&from_info, + &rai->owner->specified_value, + &rai->default_transform_value); + else + gf_svg_attributes_resolve_unspecified(&from_info, + &rai->owner->presentation_value, + &rai->default_transform_value); + + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { + gf_svg_attributes_resolve_currentColor(&from_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&from_info, &rai->owner->parent_presentation_value); + } + if (animp->to) { + to_info.fieldType = animp->to->type; + to_info.far_ptr = animp->to->value; + } else { + to_info.fieldType = 0; + to_info.far_ptr = NULL; + } + + if (rai->is_first_anim) + gf_svg_attributes_resolve_unspecified(&to_info, + &rai->owner->specified_value, + &rai->default_transform_value); + else + gf_svg_attributes_resolve_unspecified(&to_info, + &rai->owner->presentation_value, + &rai->default_transform_value); + + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(to_info.fieldType)) { + gf_svg_attributes_resolve_currentColor(&to_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&to_info, &rai->owner->parent_presentation_value); + } + + gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, NULL); + + rai->previous_coef = interpolation_coefficient; + + switch (real_calcMode) { + case SMIL_CALCMODE_DISCRETE: + { + /* before half of the duration stay at 'from' and then switch to 'to' */ + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-to animation (using %s value)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), (useFrom?"from":"to"))); + gf_svg_attributes_copy(&rai->interpolated_value, (useFrom?&from_info:&to_info), 0); + rai->previous_key_index = useFrom; + } + break; + case SMIL_CALCMODE_SPLINE: + case SMIL_CALCMODE_PACED: + case SMIL_CALCMODE_LINEAR: + default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-to animation (linear interpolation, using coefficient %f)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), interpolation_coefficient)); + gf_svg_attributes_interpolate(&from_info, &to_info, &rai->interpolated_value, interpolation_coefficient, 1); + break; + } + } +} + +static void gf_smil_anim_animate_from_by(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + Fixed from_coef; + GF_FieldInfo from_info, by_info; + SMILAnimationAttributesPointers *animp = rai->animp; + s32 useFrom = (normalized_simple_time<=FIX_ONE/2); + + if (rai->change_detection_mode) { + if (rai->previous_coef == normalized_simple_time) + rai->interpolated_value_changed = 0; + else { + if (animp->calcMode && + *animp->calcMode == SMIL_CALCMODE_DISCRETE && + useFrom == rai->previous_key_index) { + rai->interpolated_value_changed = 0; + } else { + rai->interpolated_value_changed = 1; + } + } + } else { + rai->previous_coef = normalized_simple_time; + + if (animp->from) { + from_info.fieldType = animp->from->type; + from_info.far_ptr = animp->from->value; + from_coef = FIX_ONE; + } else { + from_info.fieldType = 0; + from_info.far_ptr = NULL; + /* this is a by animation only, then, it is always additive, + we don't need the from value*/ + from_coef = 0; + } + + if (rai->is_first_anim) + gf_svg_attributes_resolve_unspecified(&from_info, + &rai->owner->specified_value, + &rai->default_transform_value); + else + gf_svg_attributes_resolve_unspecified(&from_info, + &rai->owner->presentation_value, + &rai->default_transform_value); + + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { + gf_svg_attributes_resolve_currentColor(&from_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&from_info, &rai->owner->parent_presentation_value); + } + + if (animp->by) { + by_info.fieldType = animp->by->type; + by_info.far_ptr = animp->by->value; + } else { + by_info.fieldType = 0; + by_info.far_ptr = NULL; + } + + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(from_info.fieldType)) { + gf_svg_attributes_resolve_currentColor(&by_info, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&by_info, &rai->owner->parent_presentation_value); + } + + switch ((animp->calcMode ? *animp->calcMode : SMIL_CALCMODE_LINEAR)) { + case SMIL_CALCMODE_DISCRETE: + { + /* before half of the duration stay at 'from' and then switch to 'to' */ + if (useFrom) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (setting from)", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + gf_svg_attributes_muladd(from_coef, &from_info, 0, &by_info, &rai->interpolated_value, 0); + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (setting from+by)", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + gf_svg_attributes_muladd(from_coef, &from_info, FIX_ONE, &by_info, &rai->interpolated_value, 0); + } + rai->previous_key_index = useFrom; + } + break; + case SMIL_CALCMODE_SPLINE: + case SMIL_CALCMODE_PACED: + case SMIL_CALCMODE_LINEAR: + default: + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying from-by animation (linear interpolation between from and from+by, coef: %f)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), normalized_simple_time)); + gf_svg_attributes_muladd(from_coef, &from_info, normalized_simple_time, &by_info, &rai->interpolated_value, 0); + break; + } + } +} + +static void gf_svg_compute_path_anim(SMIL_Anim_RTI *rai, GF_Matrix2D *m, Fixed normalized_simple_time) +{ + Fixed offset; + offset = gf_mulfix(normalized_simple_time, rai->length); + gf_mx2d_init(*m); + + gf_path_iterator_get_transform(rai->path_iterator, offset, 1, m, 1, 0); + //GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("offset: %f, position: (%f, %f)", offset, ((GF_Matrix2D *)rai->interpolated_value.far_ptr)->m[2], ((GF_Matrix2D *)rai->interpolated_value.far_ptr)->m[5])); + switch (rai->rotate) { + case SVG_NUMBER_AUTO: + break; + case SVG_NUMBER_AUTO_REVERSE: + gf_mx2d_add_rotation(m, m->m[2], m->m[5], GF_PI); + break; + default: + m->m[0] = FIX_ONE; + m->m[1] = 0; + m->m[3] = 0; + m->m[4] = FIX_ONE; + } +} + +static void gf_smil_anim_animate_using_path(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + Fixed interpolation_coefficient; + + gf_smil_anim_use_keypoints_keytimes(rai, normalized_simple_time, &interpolation_coefficient, NULL); + + if (rai->change_detection_mode) { + if (rai->previous_coef == interpolation_coefficient) + rai->interpolated_value_changed = 0; + else { + rai->interpolated_value_changed = 1; + } + } else { + rai->previous_coef = interpolation_coefficient; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying path animation (coef: %f)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), normalized_simple_time)); + + gf_svg_compute_path_anim(rai, (GF_Matrix2D*)rai->interpolated_value.far_ptr, interpolation_coefficient); + } +} + +static void gf_smil_anim_compute_interpolation_value(SMIL_Anim_RTI *rai, Fixed normalized_simple_time) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + + if (rai->path) { + gf_smil_anim_animate_using_path(rai, normalized_simple_time); + } else if (rai->anim_elt->sgprivate->tag == TAG_SVG_set) { + gf_smil_anim_set(rai); + } else if (rai->values_count) { + /* Ignore 'from'/'to'/'by'*/ + gf_smil_anim_animate_using_values(rai, normalized_simple_time); + } else if ((animp->by && animp->by->type) && (!animp->to || animp->to->type == 0)) { + /* 'to' is not specified but 'by' is, so this is a 'by' animation or a 'from'-'by' animation */ + gf_smil_anim_animate_from_by(rai, normalized_simple_time); + } else { + /* Ignore 'by' if specified */ + gf_smil_anim_animate_from_to(rai, normalized_simple_time); + } + +#ifndef GPAC_DISABLE_LOG + if (0 && (gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute(rai->anim_elt, &rai->interpolated_value); + + gf_log("[SMIL Animation] Time %f - Animation %s - Interpolation value changed for attribute %s, new value: %s \n", + gf_node_get_scene_time(rai->anim_elt), gf_node_get_log_name(rai->anim_elt), + gf_svg_get_attribute_name(rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); + + if (str) gf_free(str); + } +#endif +} + +void gf_smil_anim_set_anim_runtime_in_timing(GF_Node *n) +{ + u32 i, j; + SVGTimedAnimBaseElement *timed_elt = NULL; + SMIL_Timing_RTI *rti = NULL; + GF_Node *target = NULL; + + if (!n) return; + timed_elt = (SVGTimedAnimBaseElement *)n; + + if (!gf_svg_is_animation_tag(n->sgprivate->tag)) return; + + target = timed_elt->xlinkp->href->target; + if (!target) return; + + if (timed_elt->timingp) rti = timed_elt->timingp->runtime; + if (!rti) return; + + rti->rai = NULL; + + for (i = 0; i < gf_node_animation_count(target); i++) { + SMIL_Anim_RTI *rai_tmp; + SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(target, i); + j=0; + while ((rai_tmp = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { + if (rai_tmp->timingp->runtime == rti) { + rti->rai = rai_tmp; + return; + } + } + } +} + +static void gf_smil_anim_get_last_specified_value(SMIL_Anim_RTI *rai) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + + if (!animp) return; + + if (rai->path) { + if (!rai->last_specified_value.far_ptr) rai->last_specified_value.far_ptr = gf_malloc(sizeof(GF_Matrix2D)); + gf_svg_compute_path_anim(rai, rai->last_specified_value.far_ptr, FIX_ONE); + return; + } else if (rai->anim_elt->sgprivate->tag == TAG_SVG_set) { + if (animp->to) { + rai->last_specified_value.fieldType = animp->to->type; + rai->last_specified_value.far_ptr = animp->to->value; + } else { + /* TODO ??? */ + GF_LOG(GF_LOG_ERROR, GF_LOG_SMIL, + ("[SMIL Animation] Animation %s - set element without to attribute\n", + gf_node_get_log_name((GF_Node *)rai->anim_elt))); + } + return; + } + + if (rai->values_count) { + /* Ignore from/to/by*/ + rai->last_specified_value.fieldType = animp->values->type; + rai->last_specified_value.far_ptr = gf_list_last(animp->values->values); + } else if ((animp->by && animp->by->type) && (!animp->to || animp->to->type == 0)) { + rai->last_specified_value.fieldType = animp->by->type; + rai->last_specified_value.far_ptr = animp->by->value; + } else if (animp->to) { + rai->last_specified_value.fieldType = animp->to->type; + rai->last_specified_value.far_ptr = animp->to->value; + } + if (gf_svg_is_inherit(&rai->last_specified_value)) { + rai->last_specified_value.fieldType = rai->owner->presentation_value.fieldType; + rai->last_specified_value.far_ptr = rai->owner->presentation_value.far_ptr; + } + if (rai->owner->is_property && gf_svg_attribute_is_interpolatable(rai->last_specified_value.fieldType)) { + gf_svg_attributes_resolve_currentColor(&rai->last_specified_value, &rai->owner->current_color_value); + gf_svg_attributes_resolve_inherit(&rai->last_specified_value, &rai->owner->parent_presentation_value); + } +} + +/* if the animation behavior is accumulative and this is not the first iteration, + then we modify the interpolation value as follows: + interpolation value += last specified value * number of iterations completed */ +static void gf_smil_anim_apply_accumulate(SMIL_Anim_RTI *rai) +{ + u32 nb_iterations; + + SMILAnimationAttributesPointers *animp = rai->animp; + SMILTimingAttributesPointers *timingp = rai->timingp; + + nb_iterations = (timingp->runtime->current_interval ? timingp->runtime->current_interval->nb_iterations : 1); + + if (rai->change_detection_mode) { + if ((animp->accumulate && *animp->accumulate == SMIL_ACCUMULATE_SUM) + && nb_iterations > 0 + && rai->previous_iteration != (s32) nb_iterations) { + /* if we actually do accumulation and the number of iteration is different, + then we force the result as changed regardless of the result of the interpolation + (TODO: check if this need to be improved)*/ + rai->interpolated_value_changed = 1; + } else { + /* if we don't accumulate we leave the value of interpolated_value_changed unchanged */ + } + } else { + if (nb_iterations > 0 && rai->previous_iteration != (s32) nb_iterations) { + rai->previous_iteration = nb_iterations; + } + + if ((animp->accumulate && *animp->accumulate == SMIL_ACCUMULATE_SUM) && nb_iterations > 0) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying accumulation (iteration #%d)\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt), nb_iterations)); + + gf_svg_attributes_muladd(FIX_ONE, &rai->interpolated_value, + INT2FIX(nb_iterations), &rai->last_specified_value, + &rai->interpolated_value, 1); + + if ((animp->from) && animp->by && (rai->last_specified_value.far_ptr == animp->by->value)) { + /* this is a from-by animation, the last specified value is not the 'by' value but actually 'from'+'by', + we need to add nb_iterations times from to the interpolated_value + see (animate-elem-210-t.svg (upper two circles in the mid column, after 9s/14s */ + GF_FieldInfo from_info; + from_info.fieldType = rai->animp->from->type; + from_info.far_ptr = rai->animp->from->value; + gf_svg_attributes_muladd(FIX_ONE, &rai->interpolated_value, + INT2FIX(nb_iterations), &from_info, + &rai->interpolated_value, 1); + } + } + } +} + +static void gf_smil_apply_additive(SMIL_Anim_RTI *rai) +{ + SMILAnimationAttributesPointers *animp = rai->animp; + if (rai->change_detection_mode) return; + else { + /* Apply additive behavior if required + PV = (additive == sum ? PV + animp->IV : animp->IV); */ + if (animp->additive && *animp->additive == SMIL_ADDITIVE_SUM) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying additive behavior\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + gf_svg_attributes_add((rai->is_first_anim ? &rai->owner->specified_value : &rai->owner->presentation_value), + &rai->interpolated_value, + &rai->owner->presentation_value, + 1); + +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value); + gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), + gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); + + if (str) gf_free(str); + } +#endif + + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying non-additive behavior\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + /* FIXME: if we switch pointers to avoid copying values, + we need to modify the address in the DOM node as well, + we also need to take care about change detections. Not easy!! + + void *tmp = rai->owner->presentation_value.far_ptr; + rai->owner->presentation_value.far_ptr = rai->interpolated_value.far_ptr; + rai->interpolated_value.far_ptr = tmp; + */ + + gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->interpolated_value, 1); +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value); + + gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), + gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); + + if (str) gf_free(str); + } +#endif + } + } +} + +static void gf_smil_anim_animate(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) +{ + SMIL_Anim_RTI *rai = rti->rai; + SMILAnimationAttributesPointers *animp = rai->animp; + + if (!rai || !animp) return; + + gf_smil_anim_compute_interpolation_value(rai, normalized_simple_time); + gf_smil_anim_apply_accumulate(rai); + gf_smil_apply_additive(rai); +} + +static void gf_smil_anim_animate_with_fraction(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) +{ + gf_smil_anim_animate(rti, rti->fraction); + rti->evaluate_status = SMIL_TIMING_EVAL_NONE; +} + +void gf_smil_anim_reset_variables(SMIL_Anim_RTI *rai) +{ + if (!rai) return; + /* we reset all the animation parameters to force computation of next interpolation value + when the animation restarts */ + rai->interpolated_value_changed = 0; + rai->previous_key_index = -1; + rai->previous_coef = -FIX_ONE; + rai->previous_iteration = -1; + rai->previous_keytime_index = 0; + rai->anim_done = 0; +} + +/* copy/paste of the animate function + TODO: check if computations of interpolation value can be avoided. +*/ +static void gf_smil_anim_freeze(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) +{ + SMIL_Anim_RTI *rai = rti->rai; + SMILAnimationAttributesPointers *animp = rai->animp; + + if (!rai || !animp) return; + + if (rai->change_detection_mode) { + if (rai->anim_done == 0) + rai->interpolated_value_changed = 1; + else + rai->interpolated_value_changed = 0; + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying freeze behavior\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + gf_smil_anim_compute_interpolation_value(rai, normalized_simple_time); + gf_smil_anim_apply_accumulate(rai); + gf_smil_apply_additive(rai); + rai->anim_done = 1; + } +} + +static void gf_smil_anim_remove(SMIL_Timing_RTI *rti, Fixed normalized_simple_time) +{ + SMIL_Anim_RTI *rai = rti->rai; + if (!rai) return; + + if (rai->change_detection_mode) { + if (rai->anim_done == 0) + rai->interpolated_value_changed = 1; + else + rai->interpolated_value_changed = 0; + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, + ("[SMIL Animation] Time %f - Animation %s - applying remove behavior\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node *)rai->anim_elt))); + + /* TODO: see if we can avoid this copy by switching pointers */ + gf_svg_attributes_copy(&rai->owner->presentation_value, &rai->owner->specified_value, 0); + /* TODO: check if we need to apply additive behavior even in fill='remove' + maybe (see animate-elem-211-t.svg) */ + + rai->anim_done = 1; + +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute((GF_Node*)rai->anim_elt, &rai->owner->presentation_value); + + gf_log("[SMIL Animation] Time %f - Animation %s - Presentation value changed for attribute %s, new value: %s\n", + gf_node_get_scene_time((GF_Node*)rai->anim_elt), gf_node_get_log_name((GF_Node*)rai->anim_elt), + gf_svg_get_attribute_name((GF_Node*)rai->anim_elt, rai->owner->presentation_value.fieldIndex), str); + if (str) gf_free(str); + } +#endif + + } +} + +static void gf_smil_anim_evaluate(SMIL_Timing_RTI *rti, Fixed normalized_simple_time, u32 state) +{ + SMIL_Anim_RTI *rai = rti->rai; + switch (state) { + case SMIL_TIMING_EVAL_REPEAT: + /* we are starting a new cycle of animation, therefore we need to reset the previous state variables + like previous_keytime_index ... */ + gf_smil_anim_reset_variables(rai); + case SMIL_TIMING_EVAL_UPDATE: + gf_smil_anim_animate(rti, normalized_simple_time); + break; + case SMIL_TIMING_EVAL_FREEZE: + gf_smil_anim_freeze(rti, normalized_simple_time); + break; + case SMIL_TIMING_EVAL_REMOVE: + gf_smil_anim_remove(rti, normalized_simple_time); + break; + case SMIL_TIMING_EVAL_FRACTION: + gf_smil_anim_animate_with_fraction(rti, normalized_simple_time); + break; +/* + discard should be done before in smil_notify_time + case SMIL_TIMING_EVAL_DISCARD: + break; +*/ + } +} +/************************************************************************************** + **************************************************************************************/ + +GF_EXPORT +void gf_svg_apply_animations(GF_Node *node, SVGPropertiesPointers *render_svg_props) +{ + u32 count_all, i; +#ifndef GPAC_DISABLE_LOG + u32 time=0; + u32 active_anim; + + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RTI)) { + time = gf_sys_clock(); + } +#endif + + /* Perform all the animations on this node */ + count_all = gf_node_animation_count(node); + for (i = 0; i < count_all; i++) { + GF_FieldInfo info; + s32 j; + u32 count; + SMIL_AttributeAnimations *aa; + + + aa = (SMIL_AttributeAnimations *)gf_node_animation_get(node, i); + count = gf_list_count(aa->anims); + if (!count) continue; + + aa->presentation_value_changed = 0; + + if (aa->is_property) { + /* Storing the pointer to the parent presentation value, + i.e. the presentation value produced at the parent level in the tree */ + aa->parent_presentation_value = aa->presentation_value; + aa->parent_presentation_value.far_ptr = + gf_svg_get_property_pointer((SVG_Element *)node, aa->orig_dom_ptr, render_svg_props); + + /* Storing also the pointer to the presentation value of the color property + (special handling of the keyword 'currentColor' if used in animation values) */ + gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_color, 1, 1, &info); + aa->current_color_value.far_ptr = info.far_ptr; + } + + /* We start with the last animation (TODO in the execution order), then scan in the reverse order + up to the first animation which is not additive, to determine if the presentation value will change + We evaluate each animation, but only in the 'change_detection_mode' */ + for (j = count-1; j >= 0; j--) { + SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j); + SMIL_Timing_RTI *rti = rai->timingp->runtime; + + rai->interpolated_value_changed = 0; + + /* The evaluate_status has been updated when notifying the new scene time to this animation, + i.e. before the scene tree traversal */ + if (rti->evaluate_status) { + rai->change_detection_mode = 1; + rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); + aa->presentation_value_changed += rai->interpolated_value_changed; + if (!rai->animp->additive || *rai->animp->additive == SMIL_ADDITIVE_REPLACE) { + /* we don't need to check previous animations since this one will overwrite it */ + j--; + break; + } + } + } + + active_anim = 0; + if (aa->presentation_value_changed) { + /* If the result of all the combined animations will produce a different result compared to the previous frame, + we start in the forward order from the j were the previous step stopped (i.e. the first anim in replace mode) + and evaluate each animation, in the computation mode (change_detection_mode = 0)*/ + for (j++; j<(s32)count; j++) { + SMIL_Anim_RTI *rai = (SMIL_Anim_RTI *)gf_list_get(aa->anims, j); + SMIL_Timing_RTI *rti = rai->timingp->runtime; + + if (j == 0) rai->is_first_anim = 1; + else rai->is_first_anim = 0; + + if (rti->evaluate_status) { + rai->change_detection_mode = 0; + rti->evaluate(rti, rti->normalized_simple_time, rti->evaluate_status); + active_anim++; + } + } + } + +/* DEBUG: uncomment this line to remove animation effect, and keep animation computation */ +// gf_svg_attributes_copy(&aa->presentation_value, &aa->specified_value, 0); + +#ifndef GPAC_DISABLE_LOG + if (aa->presentation_value_changed) { + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_SMIL)) { + char *str; + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SMIL); + str = gf_svg_dump_attribute(node, &aa->presentation_value); + + gf_log("[SMIL Animation] Time %f - Element %s - Presentation value changed for attribute %s, new value: %s - dirty flags %x\n", + gf_node_get_scene_time(node), gf_node_get_log_name(node), + gf_svg_get_attribute_name(node, aa->presentation_value.fieldIndex), str, aa->dirty_flags); + + if (str) gf_free(str); + } + } +#endif + + /* we only set dirty flags when a real flag is set to avoid unnecessary computation + for example, it is not necessary to set it when the anim is an animateTransform + since there is no associated flag */ + if (aa->dirty_flags) { + if (aa->presentation_value_changed) { + gf_node_dirty_set(node, aa->dirty_flags, aa->dirty_parents); + } else { + /* WARNING - This does not work for use elements because apply_animations may be called several times */ + if (active_anim) gf_node_dirty_clear(node, aa->dirty_flags); + } + } + } + +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= GF_LOG_DEBUG) && (gf_log_get_tools() & GF_LOG_RTI)) { + time_spent_in_anim += gf_sys_clock() - time; + } +#endif +} + + + +void gf_smil_anim_init_runtime_info(GF_Node *e) +{ + u32 i; + GF_FieldInfo target_attribute; + SMIL_AttributeAnimations *aa = NULL; + SMIL_Anim_RTI *rai; + XLinkAttributesPointers *xlinkp = NULL; + SMILAnimationAttributesPointers *animp = NULL; + SMILTimingAttributesPointers *timingp = NULL; + GF_Node *target = NULL; + + if (!e) return; + + /* Filling animation structures to be independent of the SVG Element structure */ + animp = ((SVGTimedAnimBaseElement *)e)->animp; + timingp = ((SVGTimedAnimBaseElement *)e)->timingp; + xlinkp = ((SVGTimedAnimBaseElement *)e)->xlinkp; + + target = xlinkp->href->target; + + memset(&target_attribute, 0, sizeof(GF_FieldInfo)); + if (animp->attributeName && (animp->attributeName->name || animp->attributeName->tag)) { + /* Filling the target_attribute structure with info on the animated attribute (type, pointer to data, ...) + NOTE: in the mode Dynamic Allocation of Attributes, this means that the animated + attribute is created with a default value, if it was not specified on the target element */ + if (animp->attributeName->tag) { + gf_node_get_attribute_by_tag(target, animp->attributeName->tag, 1, 1, &target_attribute); + } else { + gf_node_get_field_by_name(target, animp->attributeName->name, &target_attribute); + } + } else { + /* All animation elements should have a target attribute except for animateMotion + cf http://www.w3.org/mid/u403c21ajf1sjqtk58g0g38eaep9f9g2ss@hive.bjoern.hoehrmann.de + "For animateMotion, the attributeName is implied and cannot be specified; + animateTransform requires specification of the attribute name and any attribute that is + a transform-like attribute can be a target, e.g. gradientTransform."*/ + + switch (e->sgprivate->tag) { + case TAG_SVG_animateMotion: + /* Explicit creation of the pseudo 'motionTransform' attribute since it cannot be specified */ + gf_node_get_attribute_by_tag(target, TAG_SVG_ATT_motionTransform, 1, 0, &target_attribute); + gf_mx2d_init(*(GF_Matrix2D *)target_attribute.far_ptr); + break; + default: + GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, + ("[SMIL Animation] Missing attributeName attribute on element %s\n", + gf_node_get_log_name((GF_Node*)e) )); + return; + } + } + + if (animp->attributeType && *animp->attributeType == SMIL_ATTRIBUTETYPE_CSS) { + /* see example animate-elem-219-t.svg from the SVG test suite, upper row */ + if (!gf_svg_is_property(target, &target_attribute)) { + GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, + ("[SMIL Animation] Using CSS attributeType for an animation on an attribute which is not a property %s\n", + gf_node_get_log_name((GF_Node*)e) )); + return; + } + } + + /* Creation and setup of the runtime structure for animation */ + GF_SAFEALLOC(rai, SMIL_Anim_RTI) + + rai->anim_elt = e; + rai->animp = animp; + rai->timingp = timingp; + rai->xlinkp = xlinkp; + + gf_mx2d_init(rai->identity); + rai->default_transform_value.far_ptr = &rai->identity; + rai->default_transform_value.fieldType = SVG_Transform_datatype; + + /* the interpolated value has the same type as the target attribute, + but we need to create a new pointer to hold its value */ + rai->interpolated_value = target_attribute; + rai->interpolated_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType); + + /* there has not been any interpolation yet, so the previous key index and interpolation coefficient + shall not be set*/ + gf_smil_anim_reset_variables(rai); + + rai->values_count = (animp->values ? gf_list_count(animp->values->values) : 0); + rai->key_times_count = (animp->keyTimes ? gf_list_count(*animp->keyTimes) : 0); + rai->key_points_count = (animp->keyPoints ? gf_list_count(*animp->keyPoints) : 0); + rai->key_splines_count = (animp->keySplines ? gf_list_count(*animp->keySplines) : 0); + + + if (!rai->values_count && /* 'values' attribute not specified */ + (!animp->to || animp->to->type == 0) && /* 'to' attribute not specified */ + (!animp->from || animp->from->type == 0) && /* 'from' attribute not specified */ + (animp->by && animp->by->type != 0)) { /* 'by' attribute specified */ + /* if this is a 'by' animation without from the animation is defined to be additive + see http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#AnimationNS-FromToBy + we override the additive attribute */ + if (!animp->additive) { + /* this case can only happen with dynamic allocation of attributes */ + GF_FieldInfo info; + gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_additive, 1, 0, &info); + animp->additive = info.far_ptr; + } + if (*animp->additive == SMIL_ADDITIVE_REPLACE) { + GF_LOG(GF_LOG_WARNING, GF_LOG_SMIL, ("[SMIL Animation] Warning: by-animations cannot use additive=\"replace\"\n")); + } + *animp->additive = SMIL_ADDITIVE_SUM; + } + + /*TODO + http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation + To animation defines its own kind of additive semantics, so the additive attribute is ignored. + */ + + /*TODO + http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-ToAnimation + Because to animation is defined in terms of absolute values of the target attribute, + cumulative animation is not defined: + */ + + /* TODO + http://www.w3.org/TR/2005/REC-SMIL2-20051213/animation.html#animationNS-setElement + The set element is non-additive. The additive and accumulate attributes are not allowed, + and will be ignored if specified. + */ + + /* For animateMotion, we need to retrieve the value of the rotate attribute, retrieve the path either + from the 'path' attribute or from the 'mpath' element, and then initialize the path iterator*/ + if (e->sgprivate->tag == TAG_SVG_animateMotion) { + GF_Path *the_path = NULL; + GF_ChildNodeItem *child = NULL; + + GF_FieldInfo info; + if (gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_rotate, 0, 0, &info) == GF_OK) { + rai->rotate = ((SVG_Rotate *)info.far_ptr)->type; + } else { + rai->rotate = SVG_NUMBER_VALUE; + } + if (gf_node_get_attribute_by_tag(e, TAG_SVG_ATT_path, 0, 0, &info) == GF_OK) { + the_path = ((SVG_PathData *)info.far_ptr); + } + child = ((SVG_Element *)e)->children; + + if ((!animp->to || animp->to->type == 0) && + (!animp->by || animp->by->type == 0) && + (!animp->values || animp->values->type == 0)) { +#if USE_GF_PATH + if (!gf_path_is_empty(the_path)) { + rai->path = the_path; + rai->path_iterator = gf_path_iterator_new(rai->path); + rai->length = gf_path_iterator_get_length(rai->path_iterator); + } +#else + rai->path = gf_path_new(); + if (gf_list_count(the_path->points)) { + gf_svg_path_build(rai->path, the_path->commands, the_path->points); + rai->path_iterator = gf_path_iterator_new(rai->path); + rai->length = gf_path_iterator_get_length(rai->path_iterator); + } +#endif + else { + while (child) { + GF_Node *used_path = NULL; + u32 child_tag = gf_node_get_tag(child->node); + if (child_tag == TAG_SVG_mpath) { + GF_FieldInfo info; + if (gf_node_get_attribute_by_tag(child->node, TAG_XLINK_ATT_href, 0, 0, &info) == GF_OK) { + XMLRI *iri = (XMLRI *)info.far_ptr; + if (iri->target) used_path = iri->target; + else if (iri->string) used_path = + (GF_Node *)gf_sg_find_node_by_name(gf_node_get_graph(child->node), iri->string); + if (used_path && gf_node_get_tag(used_path) == TAG_SVG_path) { + gf_node_get_attribute_by_tag(used_path, TAG_SVG_ATT_d, 1, 0, &info); +#if USE_GF_PATH + rai->path = (SVG_PathData *)info.far_ptr; +#else + gf_svg_path_build(rai->path, + ((SVG_PathData *)info.far_ptr)->commands, + ((SVG_PathData *)info.far_ptr)->points); +#endif + rai->path_iterator = gf_path_iterator_new(rai->path); + rai->length = gf_path_iterator_get_length(rai->path_iterator); + } + } + break; + } + child = child->next; + } + } + } + } + + /* for all animations, check if there is already one animation on this attribute, + if yes, get the list and append the new animation runtime info + if no, create a list and add the new animation runtime info. */ + for (i = 0; i < gf_node_animation_count(target); i++) { + aa = (SMIL_AttributeAnimations *)gf_node_animation_get(target, i); + if (aa->presentation_value.fieldIndex == target_attribute.fieldIndex) { + gf_list_add(aa->anims, rai); + break; + } + aa = NULL; + } + if (!aa) { + GF_SAFEALLOC(aa, SMIL_AttributeAnimations) + + /* We determine if the animated attribute is a property since this changes quite a lot the animation model */ + aa->is_property = gf_svg_is_property(target, &target_attribute); + aa->current_color_value.fieldType = SVG_Paint_datatype; + + /* We copy (one copy for all animations on the same attribute) the DOM specified + value before any animation starts (because the animation will override it), + we also save the initial memory address of the specified value (orig_dom_ptr) + for inheritance hack */ + aa->specified_value = target_attribute; + aa->orig_dom_ptr = aa->specified_value.far_ptr; + aa->specified_value.far_ptr = gf_svg_create_attribute_value(target_attribute.fieldType); + gf_svg_attributes_copy(&aa->specified_value, &target_attribute, 0); + + /* Now, the initial memory address of the specified value holds the presentation value, + and the presentation value is initialized */ + aa->presentation_value = target_attribute; + + aa->anims = gf_list_new(); + gf_list_add(aa->anims, rai); + gf_node_animation_add(target, aa); + + /* determine what the rendering will need to do when the animation runs */ + aa->dirty_flags = gf_svg_get_modification_flags((SVG_Element *)target, &target_attribute); + + /* If the animation will result in a change of geometry or of the display property, + this animation will require traversing the tree, we need to inform the parents of the target node */ + aa->dirty_parents = 0; + if (aa->dirty_flags & (GF_SG_SVG_GEOMETRY_DIRTY | GF_SG_SVG_DISPLAY_DIRTY)) aa->dirty_parents = 1; + } + + rai->owner = aa; + gf_smil_anim_get_last_specified_value(rai); + + /* for animation (unlike other timed elements like video), the evaluation (i.e. interpolation) cannot be done + during timing evaluation, because due to inheritance, interpolation can only be computed + during scene tree traversal, therefore we need to postpone evaluation of the timed element */ + timingp->runtime->postpone = 1; + + timingp->runtime->evaluate = gf_smil_anim_evaluate; +} + +void gf_smil_anim_delete_runtime_info(SMIL_Anim_RTI *rai) +{ + gf_svg_delete_attribute_value(rai->interpolated_value.fieldType, + rai->interpolated_value.far_ptr, + rai->anim_elt->sgprivate->scenegraph); + if (rai->path) { + gf_svg_delete_attribute_value(rai->last_specified_value.fieldType, + rai->last_specified_value.far_ptr, + rai->anim_elt->sgprivate->scenegraph); + } +#if USE_GF_PATH +#else + if (rai->path) gf_path_del(rai->path); +#endif + if (rai->path_iterator) gf_path_iterator_del(rai->path_iterator); + gf_free(rai); +} + +void gf_smil_anim_remove_from_target(GF_Node *anim, GF_Node *target) +{ + u32 i, j; + if (!target) return; + for (i = 0; i < gf_node_animation_count((GF_Node *)target); i ++) { + SMIL_Anim_RTI *rai; + SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get((GF_Node *)target, i); + j=0; + while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { + if ((GF_Node *)rai->anim_elt == anim) { + gf_list_rem(aa->anims, j-1); + gf_smil_anim_delete_runtime_info(rai); + break; + } + } + if (gf_list_count(aa->anims) == 0) { + gf_list_del(aa->anims); + gf_svg_delete_attribute_value(aa->specified_value.fieldType, + aa->specified_value.far_ptr, + target->sgprivate->scenegraph); + aa->presentation_value.far_ptr = aa->orig_dom_ptr; + gf_node_animation_rem((GF_Node *)target, i); + gf_free(aa); + } + } +} + +void gf_smil_anim_delete_animations(GF_Node *e) +{ + u32 i, j; + + for (i = 0; i < gf_node_animation_count(e); i ++) { + SMIL_Anim_RTI *rai; + SMIL_AttributeAnimations *aa = (SMIL_AttributeAnimations *)gf_node_animation_get(e, i); + gf_svg_delete_attribute_value(aa->specified_value.fieldType, + aa->specified_value.far_ptr, + e->sgprivate->scenegraph); + j=0; + while ((rai = (SMIL_Anim_RTI *)gf_list_enum(aa->anims, &j))) { + rai->xlinkp->href->target = NULL; + gf_smil_anim_delete_runtime_info(rai); + } + gf_list_del(aa->anims); + gf_free(aa); + } + gf_node_animation_del(e); +} + +void gf_smil_anim_init_discard(GF_Node *node) +{ + SVGAllAttributes all_atts; + XLinkAttributesPointers *xlinkp = NULL; + SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; + gf_smil_timing_init_runtime_info(node); + + gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); + GF_SAFEALLOC(e->xlinkp, XLinkAttributesPointers); + xlinkp = e->xlinkp; + xlinkp->href = all_atts.xlink_href; + xlinkp->type = all_atts.xlink_type; + + e->timingp->runtime->evaluate_status = SMIL_TIMING_EVAL_DISCARD; +} + +void gf_smil_anim_init_node(GF_Node *node) +{ + XLinkAttributesPointers *xlinkp = NULL; + SMILAnimationAttributesPointers *animp = NULL; + SVGAllAttributes all_atts; + SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)node; + + gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); + e->xlinkp = gf_malloc(sizeof(XLinkAttributesPointers)); + xlinkp = e->xlinkp; + xlinkp->href = all_atts.xlink_href; + xlinkp->type = all_atts.xlink_type; + + /*perform init of default values*/ + if (!xlinkp->href) { + GF_FieldInfo info; + gf_node_get_attribute_by_tag((GF_Node *)node, TAG_XLINK_ATT_href, 1, 0, &info); + xlinkp->href = info.far_ptr; + xlinkp->href->type = XMLRI_ELEMENTID; + xlinkp->href->target = gf_node_get_parent(node, 0); + } + if (xlinkp->href->type == XMLRI_STRING) { + if (!xlinkp->href->string) { + fprintf(stderr, "Error: IRI not initialized\n"); + return; + } else { + GF_Node *n; + + n = (GF_Node*)gf_sg_find_node_by_name(gf_node_get_graph(node), xlinkp->href->string); + if (n) { + xlinkp->href->type = XMLRI_ELEMENTID; + xlinkp->href->target = n; + gf_node_register_iri(node->sgprivate->scenegraph, xlinkp->href); + } else { + return; + } + } + } + if (!xlinkp->href->target) return; + + // We may not have an attribute name, when using an animateMotion element + if (node->sgprivate->tag != TAG_SVG_animateMotion && !all_atts.attributeName) return; + + if ( (all_atts.to && (all_atts.to->type==0)) + || (all_atts.from && (all_atts.from->type==0)) + || (all_atts.from && (all_atts.from->type==0)) + ) { + GF_FieldInfo info; + if (gf_node_get_attribute_by_name((GF_Node *)xlinkp->href->target, all_atts.attributeName->name, 0, 1, 1, &info)==GF_OK) { + u32 anim_value_type = info.fieldType; + u32 i; + for (i=0; i<3; i++) { + u32 tag = 0; + switch (i) { + case 0: tag=TAG_SVG_ATT_to; break; + case 1: tag=TAG_SVG_ATT_from; break; + case 2: tag=TAG_SVG_ATT_by; break; + } + if (gf_node_get_attribute_by_tag((GF_Node *)node, tag, 0, 0, &info)==GF_OK) { + SMIL_AnimateValue *attval = info.far_ptr; + if (attval->type==0) { + SVG_String *string = attval->value; + attval->value = NULL; + if (string) { + gf_svg_parse_attribute((GF_Node *)node, &info, * string, anim_value_type); + if (* string) gf_free(* string); + gf_free(string); + } + } + } + } + } + } + + e->animp = gf_malloc(sizeof(SMILAnimationAttributesPointers)); + animp = e->animp; + animp->accumulate = all_atts.accumulate; + animp->additive = all_atts.additive; + animp->attributeName = all_atts.attributeName; + animp->attributeType = all_atts.attributeType; + animp->by = all_atts.by; + animp->calcMode = all_atts.calcMode; + animp->from = all_atts.from; + animp->keySplines = all_atts.keySplines; + animp->keyTimes = all_atts.keyTimes; + animp->lsr_enabled = all_atts.lsr_enabled; + animp->to = all_atts.to; + animp->type = all_atts.transform_type; + animp->values = all_atts.values; + if (node->sgprivate->tag == TAG_SVG_animateMotion) { + e->animp->keyPoints = all_atts.keyPoints; + e->animp->origin = all_atts.origin; + e->animp->path = all_atts.path; + e->animp->rotate = all_atts.rotate; + } else { + e->animp->keyPoints = NULL; + e->animp->origin = NULL; + e->animp->path = NULL; + e->animp->rotate = NULL; + } + + + gf_smil_timing_init_runtime_info(node); + gf_smil_anim_init_runtime_info(node); + gf_smil_anim_set_anim_runtime_in_timing(node); +} + + + +#endif /*GPAC_DISABLE_SVG*/ diff --git a/src/scenegraph/smil_timing.c b/src/scenegraph/smil_timing.c index 42a0d97..36f3f4e 100644 --- a/src/scenegraph/smil_timing.c +++ b/src/scenegraph/smil_timing.c @@ -319,7 +319,7 @@ void gf_smil_timing_init_runtime_info(GF_Node *timed_elt) SVGTimedAnimBaseElement *e = (SVGTimedAnimBaseElement *)timed_elt; gf_svg_flatten_attributes((SVG_Element *)e, &all_atts); - e->timingp = malloc(sizeof(SMILTimingAttributesPointers)); + e->timingp = gf_malloc(sizeof(SMILTimingAttributesPointers)); e->timingp->begin = all_atts.begin; e->timingp->clipBegin = all_atts.clipBegin; e->timingp->clipEnd = all_atts.clipEnd; @@ -403,19 +403,20 @@ void gf_smil_timing_delete_runtime_info(GF_Node *timed_elt, SMIL_Timing_RTI *rti if (!rti || !timed_elt) return; GF_LOG(GF_LOG_DEBUG, GF_LOG_SMIL, ("[SMIL Timing ] Time %f - Timed element %s - Destruction\n", gf_node_get_scene_time((GF_Node *)rti->timed_elt), gf_node_get_log_name((GF_Node *)rti->timed_elt))); - free(rti->current_interval); - free(rti->next_interval); + gf_free(rti->current_interval); + gf_free(rti->next_interval); /* we inform the rootmost scene graph that this node will not need notification of the scene time anymore */ sg = timed_elt->sgprivate->scenegraph; while (sg->parent_scene) sg = sg->parent_scene; gf_list_del_item(sg->smil_timed_elements, rti); + gf_list_del_item(sg->modified_smil_timed_elements, rti); /*remove all associated listeners*/ if (rti->timingp->begin) gf_smil_timing_reset_time_list(* rti->timingp->begin); if (rti->timingp->end) gf_smil_timing_reset_time_list(* rti->timingp->end); - free(rti); + gf_free(rti); } GF_EXPORT @@ -442,6 +443,13 @@ Bool gf_smil_notify_timed_elements(GF_SceneGraph *sg) if (!sg) return 0; active_count = 0; + + /* + Note: whenever a timed element is active, we trigger a gf_node_dirty_parent_graph so that the parent graph + is aware that some modifications may happen in the subtree. This is needed for cases where the subtree + is in an offscreen surface, to force retraversing of the subtree and thus apply the animation. + + */ /* notify the new scene time to the register timed elements this might modify other timed elements or the element itself @@ -468,9 +476,11 @@ Bool gf_smil_notify_timed_elements(GF_SceneGraph *sg) but which require a tree traversal */ i--; active_count ++; + gf_node_dirty_parent_graph(rti->timed_elt); break; case 1: active_count++; + gf_node_dirty_parent_graph(rti->timed_elt); break; case 0: default: @@ -501,9 +511,11 @@ Bool gf_smil_notify_timed_elements(GF_SceneGraph *sg) break; case -3: active_count++; + gf_node_dirty_parent_graph(rti->timed_elt); break; case 1: active_count++; + gf_node_dirty_parent_graph(rti->timed_elt); break; case 0: default: @@ -939,7 +951,7 @@ Bool gf_svg_resolve_smil_times(GF_Node *anim, void *event_base_element, t->element = gf_sg_find_node_by_name(anim->sgprivate->scenegraph, t->element_id); if (t->element) { - free(t->element_id); + gf_free(t->element_id); t->element_id = NULL; done++; } @@ -983,7 +995,7 @@ void gf_smil_timing_insert_clock(GF_Node *elt, Bool is_end, Double clock) /*remove past instanciations*/ if ((first->type==GF_SMIL_TIME_EVENT_RESOLVED) && (first->clock < begin->clock)) { gf_list_rem(l, i); - free(first); + gf_free(first); i--; count--; continue; diff --git a/src/scenegraph/svg_attributes.c b/src/scenegraph/svg_attributes.c index ba7aa5c..62ab268 100644 --- a/src/scenegraph/svg_attributes.c +++ b/src/scenegraph/svg_attributes.c @@ -11,15 +11,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -34,7 +34,7 @@ #define DUMP_COORDINATES 1 -static const struct dom_event_def {u32 event; const char *name; u32 category; } defined_dom_events [] = +static const struct dom_event_def {u32 event; const char *name; u32 category; } defined_dom_events [] = { { GF_EVENT_ABORT, "abort", GF_DOM_EVENT_DOM }, { GF_EVENT_ERROR, "error", GF_DOM_EVENT_DOM }, @@ -64,8 +64,8 @@ static const struct dom_event_def {u32 event; const char *name; u32 category; } { GF_EVENT_MOUSEOUT, "mouseout", GF_DOM_EVENT_MOUSE }, { GF_EVENT_MOUSEOVER, "mouseover", GF_DOM_EVENT_MOUSE }, { GF_EVENT_MOUSEUP, "mouseup", GF_DOM_EVENT_MOUSE }, + { GF_EVENT_MOUSEWHEEL, "wheel", GF_DOM_EVENT_MOUSE }, { GF_EVENT_MOUSEWHEEL, "SVGMousewheel", GF_DOM_EVENT_MOUSE }, - { GF_EVENT_MOUSEWHEEL, "mousewheel", GF_DOM_EVENT_MOUSE }, /*activate is not a basic DOM but a MOUSE and KEY event*/ { GF_EVENT_ACTIVATE, "activate", GF_DOM_EVENT_MOUSE | GF_DOM_EVENT_KEY }, @@ -132,6 +132,9 @@ static const struct dom_event_def {u32 event; const char *name; u32 category; } { GF_EVENT_MEDIA_STOP, "Stop", GF_DOM_EVENT_MEDIA_ACCESS }, { GF_EVENT_MEDIA_ERROR, "Error", GF_DOM_EVENT_MEDIA_ACCESS }, + /*GPAC internals*/ + { GF_EVENT_SCENE_ATTACHED, "gpac_scene_attached", GF_DOM_EVENT_DOM }, + { GF_EVENT_VP_RESIZE, "gpac_vp_changed", GF_DOM_EVENT_DOM }, }; u32 gf_dom_event_type_by_name(const char *name) @@ -170,7 +173,7 @@ u32 gf_dom_event_get_category(u32 type) } -static const struct predef_keyid {u32 key_code; const char *name; } predefined_key_identifiers[] = +static const struct predef_keyid {u32 key_code; const char *name; } predefined_key_identifiers[] = { { GF_KEY_ACCEPT, "Accept" }, { GF_KEY_AGAIN, "Again" }, @@ -384,12 +387,12 @@ u32 gf_dom_get_key_type(char *key_name) c[0] = key_name[0]; c[1] = 0; strupr(c); - if (c[0] >= 'A' && c[0] <= 'Z') + if (c[0] >= 'A' && c[0] <= 'Z') return (GF_KEY_A + (c[0] - 'A') ); - + if (c[0] >= '0' && c[0] <= '9') return ( GF_KEY_0 + (c[0] - '0') ); - + switch (c[0]) { case '@': return GF_KEY_AT; case '*': return GF_KEY_STAR; @@ -438,7 +441,7 @@ u32 gf_dom_get_key_type(char *key_name) } /* Basic SVG datatype parsing functions */ -static const struct predef_col { const char *name; u8 r; u8 g; u8 b; } predefined_colors[] = +static const struct predef_col { const char *name; u8 r; u8 g; u8 b; } predefined_colors[] = { {"aliceblue",240, 248, 255}, {"antiquewhite",250, 235, 215}, @@ -592,7 +595,7 @@ static const struct predef_col { const char *name; u8 r; u8 g; u8 b; } predefine /* Basic SVG datatype parsing functions */ -static const struct sys_col { const char *name; u8 type; } system_colors[] = +static const struct sys_col { const char *name; u8 type; } system_colors[] = { {"ActiveBorder", SVG_COLOR_ACTIVE_BORDER}, {"ActiveCaption", SVG_COLOR_ACTIVE_CAPTION}, @@ -667,10 +670,10 @@ u32 gf_svg_get_system_paint_server_type(const char *name) return 0; } -/* Reads an SVG Color +/* Reads an SVG Color either #RRGGBB, #RGB, rgb(r,g,b) in [0,255] , colorname, or 'r g b' in [0,1] ignores any space, comma, semi-column before and any space after - TODO: + TODO: transform the char into char and duplicate the input, instead of modifying it be more robust to errors in color description ex rgb(0 0 0) */ @@ -707,9 +710,19 @@ static void svg_parse_color(SVG_Color *col, char *attribute_content) str++; sscanf(str, "%f", &_val); col->red = FLT2FIX(_val); str = strstr(str, ","); + if (!str) { + /* space separated colors/percentages are not allowed neither in SVG 1.1 nor in SVG T1.2 */ + col->red = col->green = col->blue = 0; + return; + } str++; sscanf(str, "%f", &_val); col->green = FLT2FIX(_val); str = strstr(str, ","); + if (!str) { + /* space separated colors/percentages are not allowed neither in SVG 1.1 nor in SVG T1.2 */ + col->red = col->green = col->blue = 0; + return; + } str++; sscanf(str, "%f", &_val); col->blue = FLT2FIX(_val); if (is_percentage) { @@ -735,51 +748,75 @@ static void svg_parse_color(SVG_Color *col, char *attribute_content) } } -/* - Reads a float in scientific notation - trims any space, comma, semi-column before or after +/* + Reads a number (i.e. without unit) according to the CSS syntax (same as SVG paths and transforms) + trims any space, comma, semi-column before or after (TODO: fix this) reads an optional + or - then reads a digit between 0 and 9 optionally followed by an '.' and digits between 0 and 9 optionally followed by e or E and digits between 0 and 9 - Returns the number of char read in d + Returns the number of chars read in d */ -static u32 svg_parse_float(char *d, Fixed *f, Bool is_angle) +static u32 svg_parse_number(char *d, Fixed *f, Bool is_angle) { + u32 nb_digit_before = 0; + u32 nb_digit_after = 0; + Bool has_fractional = 0; Bool is_negative = 0; Float _val = 0; u32 i = 0; + + /* warning the comma and semicolumn should not be there when parsing a number in a path */ while ((d[i] != 0) && strchr(" ,;\r\n\t", d[i])) i++; - if (!d[i]) goto end; - if (d[i] == '+') i++; - if (d[i] == '-') { + + if (!d[i]) { + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG Parsing] Parsing number with empty string or only spaces: %s\n", d)); + return 0; + } + if (d[i] == '+') { + i++; + } else if (d[i] == '-') { is_negative = 1; i++; } - if ((d[i]=='N') && (d[i+1]=='a') && (d[i+2]=='N')) { + /* Warning: this is not normal, should be detected somehow by checking the BNF */ + /* if ((d[i]=='N') && (d[i+1]=='a') && (d[i+2]=='N')) { i+= 3; _val = 0; goto end; - } + }*/ + /* read the digit-sequence token of the BNF */ while (d[i] >= '0' && d[i] <= '9' && d[i] != 0) { _val = _val*10 + (d[i]-'0'); + nb_digit_before++; i++; } - if (!d[i]) goto end; if (d[i] == '.') { - u32 nb_digit_after = 0; + has_fractional = 1; i++; while (d[i] >= '0' && d[i] <= '9' && d[i] != 0) { _val = _val*10 + (d[i]-'0'); nb_digit_after++; i++; } - _val /= (Float)pow(10,nb_digit_after); - if (!d[i]) goto end; - } + if (nb_digit_after) { + _val /= (Float)pow(10,nb_digit_after); + } else if (nb_digit_before == 0) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error in parsing number (expecting digits before or after a '.': %s\n", d)); + return 0; + } else { + /* dangling '.' without digits after. This is allowed by the BNF */ + } + } + if ((nb_digit_before == 0) && (has_fractional == 0)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error in parsing number (expecting digits):%s\n", d)); + return 0; + } + /* reading the exponent */ if (d[i] == 'e' || d[i] == 'E') { Bool neg_exp = 0; - s32 exp = 0; + u32 nb_exp_digits = 0; + s32 exp = 0; i++; if (d[i] == '+') i++; else if (d[i] == '-') { @@ -788,19 +825,26 @@ static u32 svg_parse_float(char *d, Fixed *f, Bool is_angle) } while (d[i] >= '0' && d[i] <= '9' && d[i] != 0) { exp = exp*10 + (d[i]-'0'); + nb_exp_digits++; i++; } - _val *= (Float)pow(10, neg_exp ? -exp : exp); + if (nb_exp_digits) { + _val *= (Float)pow(10, neg_exp ? -exp : exp); + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error in parsing exponent, 'e' or 'E' should be followed by digits: %s\n", d)); + return 0; + } } -end: + /* We can now produce the final number */ if (is_negative) _val *= -1; - //_val = atof(d); if (is_angle) { _val/=180; (*f) = gf_mulfix(FLT2FIX(_val), GF_PI); } else { (*f) = FLT2FIX(_val); } + + /* warning the comma and semicolumn should not be there when parsing a path number */ while (d[i] != 0 && (d[i] == ' ' || d[i] == ',' || d[i] == ';')) i++; return i; } @@ -808,13 +852,13 @@ end: /* Parse an Offset Value, i.e +/- Clock Value */ -static GF_Err svg_parse_clock_value(char *d, Double *clock_value) +static GF_Err svg_parse_clock_value(char *d, Double *clock_value) { char *tmp; s32 sign = 1; - + if (!d) return GF_BAD_PARAM; - + if (!d[0]) return GF_BAD_PARAM; if (d[0] == '+') d++; @@ -823,12 +867,12 @@ static GF_Err svg_parse_clock_value(char *d, Double *clock_value) if (!d[0]) return GF_BAD_PARAM; /* According to SVG, the following are invalid syntaxes (see animate-elem-225-t.svg) - '+-2s' + '+-2s' '1++s' even though sscanf returns the right values */ if (strchr(d, '+') || strchr(d, '-')) return GF_BAD_PARAM; - /* No embedded white space is allowed in clock values, + /* No embedded white space is allowed in clock values, although leading and trailing white space characters will be ignored.*/ while (*d == ' ') d++; @@ -874,14 +918,14 @@ static GF_Err svg_parse_clock_value(char *d, Double *clock_value) return GF_OK; } /* Parses one SVG time value: - indefinite, + indefinite, element_id.event_name wallclock, accessKey, - events, + events, clock value. */ -static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d) +static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d) { GF_Err e = GF_OK; char *tmp; @@ -890,13 +934,13 @@ static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d) if ((d[0] >= '0' && d[0] <= '9') || d[0] == '+' || d[0] == '-'){ v->type = GF_SMIL_TIME_CLOCK; return svg_parse_clock_value(d, &(v->clock)); - } - + } + /* Indefinite Values */ else if (!strcmp(d, "indefinite")) { v->type = GF_SMIL_TIME_INDEFINITE; return GF_OK; - } + } /* Wallclock Values */ else if ((tmp = strstr(d, "wallclock("))) { @@ -913,27 +957,27 @@ static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d) sscanf(tmp, "%d-%d-%dT", &year, &month, &day); tmp1++; tmp = tmp1; - } + } if ((tmp1 = strchr(tmp, ':')) ) { if ((tmp2 = strchr(tmp1, ':')) ) { /* HHMMSS */ - sscanf(tmp, "%d:%d:%f", &hours, &minutes, &seconds); + sscanf(tmp, "%d:%d:%f", &hours, &minutes, &seconds); } else { /* HHMM */ - sscanf(tmp, "%d:%d", &hours, &minutes); + sscanf(tmp, "%d:%d", &hours, &minutes); } } if (strchr(tmp, 'Z')) { return GF_OK; } else { if ( (tmp1 = strchr(tmp, '+')) ) { - sscanf(tmp1, "%d:%d", &nhours, &nminutes); + sscanf(tmp1, "%d:%d", &nhours, &nminutes); } else if ( (tmp1 = strchr(tmp, '-')) ) { - sscanf(tmp1, "%d:%d", &nhours, &nminutes); + sscanf(tmp1, "%d:%d", &nhours, &nminutes); } } return GF_OK; - } + } /* AccessKey Values */ else if ((tmp = strstr(d, "accessKey("))) { @@ -951,9 +995,9 @@ static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d) tmp++; e = svg_parse_clock_value(tmp, &(v->clock)); if (c == '-') v->clock *= -1; - } + } return e; - } + } else { Bool had_param = 0; @@ -965,7 +1009,7 @@ static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d) GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] expecting an id before '.' in SMIL Time .%s\n", tmp+1)); return GF_BAD_PARAM; } - v->element_id = strdup(d); + v->element_id = gf_strdup(d); tmp[0] = '.'; tmp++; } else { @@ -982,9 +1026,9 @@ static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d) if (!tmp) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] expecting ')' in SMIL Time %s\n", d)); return GF_BAD_PARAM; - } + } tmp++; - } + } if ((tmp2 = strchr(tmp, '+')) || (tmp2 = strchr(tmp, '-'))) { char c = *tmp2; char *tmp3 = tmp2; @@ -1009,15 +1053,16 @@ static GF_Err smil_parse_time(GF_Node *elt, SMIL_Time *v, char *d) } /* Parses a list of SVG transformations and collapses them in the given matrix */ -void gf_svg_parse_transformlist(GF_Matrix2D *mat, char *attribute_content) +Bool gf_svg_parse_transformlist(GF_Matrix2D *mat, char *attribute_content) { GF_Matrix2D tmp; char *str; + u32 read_chars; u32 i; - + gf_mx2d_init(*mat); - + str = attribute_content; i = 0; while (str[i] != 0) { @@ -1025,163 +1070,309 @@ void gf_svg_parse_transformlist(GF_Matrix2D *mat, char *attribute_content) if (str[i] == ',') i++; while (str[i] == ' ') i++; if (strstr(str+i, "scale")==str+i) { - Fixed sx, sy; i += 5; - while(str[i] != 0 && str[i] == ' ') i++; + while(str[i] == ' ') i++; if (str[i] == '(') { + Fixed sx, sy; i++; - i+=svg_parse_float(&(str[i]), &sx, 0); + read_chars = svg_parse_number(&(str[i]), &sx, 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading sx component in scale: %s\n", attribute_content)); + return 0; + } + i += read_chars; + if (str[i] == ')') { sy = sx; } else { - i+=svg_parse_float(&(str[i]), &sy, 0); + read_chars = svg_parse_number(&(str[i]), &sy, 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading sy component in scale: %s\n", attribute_content)); + return 0; + } + i += read_chars; + } + gf_mx2d_init(tmp); + gf_mx2d_add_scale(&tmp, sx, sy); + gf_mx2d_add_matrix(&tmp, mat); + gf_mx2d_copy(*mat, tmp); + + while(str[i] == ' ') i++; + if (str[i] == ')') i++; + else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content)); + return 0; } - i++; + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content)); + return 0; } - gf_mx2d_init(tmp); - gf_mx2d_add_scale(&tmp, sx, sy); - gf_mx2d_add_matrix(&tmp, mat); - gf_mx2d_copy(*mat, tmp); - while(str[i] != 0 && str[i] == ' ') i++; } else if (strstr(str+i, "translate")==str+i) { - Fixed tx, ty; i += 9; - while(str[i] != 0 && str[i] == ' ') i++; + while(str[i] == ' ') i++; if (str[i] == '(') { + Fixed tx, ty; i++; - i+=svg_parse_float(&(str[i]), &tx, 0); + read_chars = svg_parse_number(&(str[i]), &tx, 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading tx component in translate: %s\n", attribute_content)); + return 0; + } + i += read_chars; if (str[i] == ')') { ty = 0; } else { - i+=svg_parse_float(&(str[i]), &ty, 0); + read_chars = svg_parse_number(&(str[i]), &ty, 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading ty component in translate: %s\n", attribute_content)); + return 0; + } + i += read_chars; } - i++; + gf_mx2d_init(tmp); + gf_mx2d_add_translation(&tmp, tx, ty); + gf_mx2d_add_matrix(&tmp, mat); + gf_mx2d_copy(*mat, tmp); + while(str[i] == ' ') i++; + if (str[i] == ')') i++; + else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content)); + return 0; + } + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content)); + return 0; } - gf_mx2d_init(tmp); - gf_mx2d_add_translation(&tmp, tx, ty); - gf_mx2d_add_matrix(&tmp, mat); - gf_mx2d_copy(*mat, tmp); - while(str[i] != 0 && str[i] == ' ') i++; } else if (strstr(str+i, "rotate")==str+i) { - Fixed angle, cx, cy; i += 6; - while(str[i] != 0 && str[i] == ' ') i++; + while(str[i] == ' ') i++; if (str[i] == '(') { + Fixed angle, cx, cy; i++; - i+=svg_parse_float(&(str[i]), &angle, 1); + read_chars = svg_parse_number(&(str[i]), &angle, 1); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading angle component in rotate: %s\n", attribute_content)); + return 0; + } + i += read_chars; if (str[i] == ')') { cx = cy = 0; } else { - i+=svg_parse_float(&(str[i]), &cx, 0); - i+=svg_parse_float(&(str[i]), &cy, 0); + read_chars = svg_parse_number(&(str[i]), &cx, 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading cx component in rotate: %s\n", attribute_content)); + return 0; + } + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &cy, 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading cy component in rotate: %s\n", attribute_content)); + return 0; + } + i += read_chars; } - i++; + gf_mx2d_init(tmp); + gf_mx2d_add_rotation(&tmp, cx, cy, angle); + gf_mx2d_add_matrix(&tmp, mat); + gf_mx2d_copy(*mat, tmp); + while(str[i] == ' ') i++; + if (str[i] == ')') i++; + else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content)); + return 0; + } + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content)); + return 0; } - gf_mx2d_init(tmp); - gf_mx2d_add_rotation(&tmp, cx, cy, angle); - gf_mx2d_add_matrix(&tmp, mat); - gf_mx2d_copy(*mat, tmp); - while(str[i] != 0 && str[i] == ' ') i++; } else if (strstr(str+i, "skewX")==str+i) { - Fixed angle; i += 5; - while(str[i] != 0 && str[i] == ' ') i++; + while(str[i] == ' ') i++; if (str[i] == '(') { + Fixed angle; i++; - i+=svg_parse_float(&(str[i]), &angle, 1); - i++; + read_chars = svg_parse_number(&(str[i]), &angle, 1); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading angle in skewX: %s\n", attribute_content)); + return 0; + } + i += read_chars; + gf_mx2d_init(tmp); + gf_mx2d_add_skew_x(&tmp, angle); + gf_mx2d_add_matrix(&tmp, mat); + gf_mx2d_copy(*mat, tmp); + while(str[i] == ' ') i++; + if (str[i] == ')') i++; + else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content)); + return 0; + } + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content)); + return 0; } - gf_mx2d_init(tmp); - gf_mx2d_add_skew_x(&tmp, angle); - gf_mx2d_add_matrix(&tmp, mat); - gf_mx2d_copy(*mat, tmp); - while(str[i] != 0 && str[i] == ' ') i++; } else if (strstr(str+i, "skewY")==str+i) { - Fixed angle; i += 5; - while(str[i] != 0 && str[i] == ' ') i++; + while(str[i] == ' ') i++; if (str[i] == '(') { + Fixed angle; i++; - i+=svg_parse_float(&(str[i]), &angle, 1); - i++; + read_chars = svg_parse_number(&(str[i]), &angle, 1); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading angle component in skewY: %s\n", attribute_content)); + return 0; + } + i += read_chars; + gf_mx2d_init(tmp); + gf_mx2d_add_skew_y(&tmp, angle); + gf_mx2d_add_matrix(&tmp, mat); + gf_mx2d_copy(*mat, tmp); + while(str[i] == ' ') i++; + if (str[i] == ')') i++; + else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content)); + return 0; + } + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content)); + return 0; } - gf_mx2d_init(tmp); - gf_mx2d_add_skew_y(&tmp, angle); - gf_mx2d_add_matrix(&tmp, mat); - gf_mx2d_copy(*mat, tmp); - while(str[i] != 0 && str[i] == ' ') i++; } else if (strstr(str+i, "matrix")==str+i) { i+=6; - while(str[i] != 0 && str[i] == ' ') i++; + while(str[i] == ' ') i++; if (str[i] == '(') { i++; - i+=svg_parse_float(&(str[i]), &(tmp.m[0]), 0); - i+=svg_parse_float(&(str[i]), &(tmp.m[3]), 0); - i+=svg_parse_float(&(str[i]), &(tmp.m[1]), 0); - i+=svg_parse_float(&(str[i]), &(tmp.m[4]), 0); - i+=svg_parse_float(&(str[i]), &(tmp.m[2]), 0); - i+=svg_parse_float(&(str[i]), &(tmp.m[5]), 0); - i++; + read_chars = svg_parse_number(&(str[i]), &(tmp.m[0]), 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient a in matrix: %s\n", attribute_content)); + return 0; + } + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &(tmp.m[3]), 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient b in matrix: %s\n", attribute_content)); + return 0; + } + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &(tmp.m[1]), 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient c in matrix: %s\n", attribute_content)); + return 0; + } + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &(tmp.m[4]), 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient d in matrix: %s\n", attribute_content)); + return 0; + } + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &(tmp.m[2]), 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient e in matrix: %s\n", attribute_content)); + return 0; + } + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &(tmp.m[5]), 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient f in matrix: %s\n", attribute_content)); + return 0; + } + i += read_chars; + gf_mx2d_add_matrix(&tmp, mat); + gf_mx2d_copy(*mat, tmp); + while(str[i] == ' ') i++; + if (str[i] == ')') i++; + else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content)); + return 0; + } + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in transform attribute: %s\n", attribute_content)); + return 0; } - gf_mx2d_add_matrix(&tmp, mat); - gf_mx2d_copy(*mat, tmp); - while(str[i] != 0 && str[i] == ' ') i++; - if (str[i] == ')') i++; - } + } /*for svgView parsing*/ if (str[i] == ')') i++; } + return 1; } /* Parses an SVG transform attribute and collapses all in the given matrix */ -static Bool svg_parse_transform(SVG_Transform *t, char *attribute_content) +static Bool svg_parse_transform(SVG_Transform *t, char *attribute_content) { char *str; u32 i; + u32 read_chars; str = attribute_content; i = 0; - if ((str = strstr(attribute_content, "ref("))) { + if ((str = strstr(attribute_content, "ref"))) { t->is_ref = 1; gf_mx2d_init(t->mat); - str+=4; - while(str[i] != 0 && str[i] == ' ') i++; - if (str[i] == 's' && str[i+1] == 'v' && str[i+2] == 'g') { - i+=3; - while(str[i] != 0 && str[i] == ' ') i++; - if (str[i] == ',') i++; - else if (str[i] == ')') { - i++; - return GF_OK; - } - i+=svg_parse_float(&(str[i]), &(t->mat.m[2]), 0); - i+=svg_parse_float(&(str[i]), &(t->mat.m[5]), 0); - while(str[i] != 0 && str[i] == ' ') i++; - if (str[i] == ')') i++; + str+=2; + while (str[i] == ' ') i++; + if (str[i] == '(') { i++; + while (str[i] == ' ') i++; + if (str[i] == 's' && str[i+1] == 'v' && str[i+2] == 'g') { + i+=3; + while (str[i] == ' ') i++; + if (str[i] == ',') { + i++; + } else if (str[i] == ')') { + i++; + return GF_OK; + } + read_chars = svg_parse_number(&(str[i]), &(t->mat.m[2]), 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient tx in ref transform: %s\n", attribute_content)); + return GF_BAD_PARAM; + } + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &(t->mat.m[5]), 0); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error reading coefficient ty in ref transform: %s\n", attribute_content)); + return GF_BAD_PARAM; + } + i += read_chars; + } else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Unsupported syntax for ref transform attribute")); + } + while (str[i] == ' ') i++; + if (str[i] == ')') i++; + else { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing closing parenthesis in transform attribute: %s\n", attribute_content)); + } return GF_OK; } else { - while(str[i] != 0 && str[i] != ')') i++; - i++; - return GF_NOT_SUPPORTED; + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Missing opening parenthesis in ref transform attribute: %s\n", attribute_content)); + return GF_BAD_PARAM; } - } else { - gf_svg_parse_transformlist(&t->mat, attribute_content); + read_chars = gf_svg_parse_transformlist(&t->mat, attribute_content); + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error parsing transform list: %s\n", attribute_content)); + return GF_BAD_PARAM; + } } return GF_OK; } #undef REMOVE_ALLOC -#if USE_GF_PATH +#if USE_GF_PATH //#define PARSE_PATH_ONLY -static void svg_parse_path(SVG_PathData *path, char *attribute_content) +static void svg_parse_path(SVG_PathData *path, char *attribute_content) { char *d = attribute_content; - + + /* used to detect end of BNF production: + "The processing of the BNF must consume as much of a given BNF production as possible, + stopping at the point when a character is encountered which no longer satisfies the production." */ + u32 read_chars = 0; + /* Point used to start a new subpath when the previous subpath is closed */ SVG_Point prev_m_pt; /* Point used to convert relative 'lower-case commands' into absolute */ @@ -1200,7 +1391,7 @@ static void svg_parse_path(SVG_PathData *path, char *attribute_content) prev_c = 'M'; orig.x = orig.y = ct_orig.x = ct_orig.y = prev_m_pt.x = prev_m_pt.y = rel_ref_pt.x = rel_ref_pt.y = end.x = end.y = 0; while(1) { - while ( (d[i]==' ') || (d[i] =='\t') || (d[i] =='\r') || (d[i] =='\n') ) i++; + while ( (d[i]==' ') || (d[i] =='\t') || (d[i] =='\r') || (d[i] =='\n') ) i++; c = d[i]; if (! c) break; next_command: @@ -1208,8 +1399,12 @@ next_command: case 'm': case 'M': i++; - i += svg_parse_float(&(d[i]), &(orig.x), 0); - i += svg_parse_float(&(d[i]), &(orig.y), 0); + read_chars = svg_parse_number(&(d[i]), &(orig.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(orig.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 'm') { orig.x += rel_ref_pt.x; orig.y += rel_ref_pt.y; @@ -1220,7 +1415,7 @@ next_command: rel_ref_pt = orig; prev_m_pt = orig; /*provision for nextCurveTo when no curve is specified: - "If there is no previous command or if the previous command was not an C, c, S or s, + "If there is no previous command or if the previous command was not an C, c, S or s, assume the first control point is coincident with the current point. */ ct_orig = orig; @@ -1229,8 +1424,12 @@ next_command: case 'L': case 'l': i++; - i += svg_parse_float(&(d[i]), &(orig.x), 0); - i += svg_parse_float(&(d[i]), &(orig.y), 0); + read_chars = svg_parse_number(&(d[i]), &(orig.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(orig.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 'l') { orig.x += rel_ref_pt.x; orig.y += rel_ref_pt.y; @@ -1246,14 +1445,16 @@ next_command: break; case 'H': case 'h': - i++; - i += svg_parse_float(&(d[i]), &(orig.x), 0); + i++; + read_chars = svg_parse_number(&(d[i]), &(orig.x), 0); + if (!read_chars) return; + i += read_chars; if (c == 'h') { orig.x += rel_ref_pt.x; } orig.y = rel_ref_pt.y; #ifndef PARSE_PATH_ONLY - gf_path_add_line_to(path, orig.x, orig.y); + gf_path_add_line_to(path, orig.x, orig.y); #endif rel_ref_pt.x = orig.x; orig = end; @@ -1263,14 +1464,16 @@ next_command: break; case 'V': case 'v': - i++; - i += svg_parse_float(&(d[i]), &(orig.y), 0); + i++; + read_chars = svg_parse_number(&(d[i]), &(orig.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 'v') { orig.y += rel_ref_pt.y; } orig.x = rel_ref_pt.x; #ifndef PARSE_PATH_ONLY - gf_path_add_line_to(path, orig.x, orig.y); + gf_path_add_line_to(path, orig.x, orig.y); #endif rel_ref_pt.y = orig.y; orig = end; @@ -1280,21 +1483,33 @@ next_command: break; case 'C': case 'c': - i++; - i += svg_parse_float(&(d[i]), &(ct_orig.x), 0); - i += svg_parse_float(&(d[i]), &(ct_orig.y), 0); + i++; + read_chars = svg_parse_number(&(d[i]), &(ct_orig.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(ct_orig.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 'c') { ct_orig.x += rel_ref_pt.x; ct_orig.y += rel_ref_pt.y; } - i += svg_parse_float(&(d[i]), &(ct_end.x), 0); - i += svg_parse_float(&(d[i]), &(ct_end.y), 0); + read_chars = svg_parse_number(&(d[i]), &(ct_end.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(ct_end.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 'c') { ct_end.x += rel_ref_pt.x; ct_end.y += rel_ref_pt.y; } - i += svg_parse_float(&(d[i]), &(end.x), 0); - i += svg_parse_float(&(d[i]), &(end.y), 0); + read_chars = svg_parse_number(&(d[i]), &(end.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(end.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 'c') { end.x += rel_ref_pt.x; end.y += rel_ref_pt.y; @@ -1309,17 +1524,25 @@ next_command: break; case 'S': case 's': - i++; + i++; ct_orig.x = 2*orig.x - ct_orig.x; ct_orig.y = 2*orig.y - ct_orig.y; - i += svg_parse_float(&(d[i]), &(ct_end.x), 0); - i += svg_parse_float(&(d[i]), &(ct_end.y), 0); + read_chars = svg_parse_number(&(d[i]), &(ct_end.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(ct_end.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 's') { ct_end.x += rel_ref_pt.x; ct_end.y += rel_ref_pt.y; } - i += svg_parse_float(&(d[i]), &(end.x), 0); - i += svg_parse_float(&(d[i]), &(end.y), 0); + read_chars = svg_parse_number(&(d[i]), &(end.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(end.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 's') { end.x += rel_ref_pt.x; end.y += rel_ref_pt.y; @@ -1334,21 +1557,29 @@ next_command: break; case 'Q': case 'q': - i++; - i += svg_parse_float(&(d[i]), &(ct_orig.x), 0); - i += svg_parse_float(&(d[i]), &(ct_orig.y), 0); + i++; + read_chars = svg_parse_number(&(d[i]), &(ct_orig.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(ct_orig.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 'q') { ct_orig.x += rel_ref_pt.x; ct_orig.y += rel_ref_pt.y; } - i += svg_parse_float(&(d[i]), &(end.x), 0); - i += svg_parse_float(&(d[i]), &(end.y), 0); + read_chars = svg_parse_number(&(d[i]), &(end.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(end.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 'q') { end.x += rel_ref_pt.x; end.y += rel_ref_pt.y; } #ifndef PARSE_PATH_ONLY - gf_path_add_quadratic_to(path, ct_orig.x, ct_orig.y, end.x, end.y); + gf_path_add_quadratic_to(path, ct_orig.x, ct_orig.y, end.x, end.y); #endif rel_ref_pt = end; orig = end; @@ -1356,11 +1587,15 @@ next_command: break; case 'T': case 't': - i++; + i++; ct_orig.x = 2*orig.x - ct_orig.x; ct_orig.y = 2*orig.y - ct_orig.y; - i += svg_parse_float(&(d[i]), &(end.x), 0); - i += svg_parse_float(&(d[i]), &(end.y), 0); + read_chars = svg_parse_number(&(d[i]), &(end.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(end.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 't') { end.x += rel_ref_pt.x; end.y += rel_ref_pt.y; @@ -1374,29 +1609,45 @@ next_command: break; case 'A': case 'a': - i++; - - i += svg_parse_float(&(d[i]), &(orig.x), 0); - i += svg_parse_float(&(d[i]), &(orig.y), 0); + i++; - i += svg_parse_float(&(d[i]), &(x_axis_rotation), 0); - i += svg_parse_float(&(d[i]), &(large_arc_flag), 0); - i += svg_parse_float(&(d[i]), &(sweep_flag), 0); - - i += svg_parse_float(&(d[i]), &(end.x), 0); - i += svg_parse_float(&(d[i]), &(end.y), 0); + read_chars = svg_parse_number(&(d[i]), &(orig.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(orig.y), 0); + if (!read_chars) return; + i += read_chars; + + read_chars = svg_parse_number(&(d[i]), &(x_axis_rotation), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(large_arc_flag), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(sweep_flag), 0); + if (!read_chars) return; + i += read_chars; + + read_chars = svg_parse_number(&(d[i]), &(end.x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(d[i]), &(end.y), 0); + if (!read_chars) return; + i += read_chars; if (c == 'a') { end.x += rel_ref_pt.x; end.y += rel_ref_pt.y; } +#ifndef PARSE_PATH_ONLY gf_path_add_svg_arc_to(path, end.x, end.y, orig.x, orig.y, x_axis_rotation , (large_arc_flag == FIX_ONE ? 1 : 0), (sweep_flag == FIX_ONE ? 1 : 0)); +#endif rel_ref_pt = end; ct_orig = end; prev_c = c; break; case 'Z': case 'z': - i++; + i++; #ifndef PARSE_PATH_ONLY gf_path_close(path); #endif @@ -1421,7 +1672,7 @@ next_command: } #else /* TODO: Change the function to handle elliptical arcs, requires changing data structure */ -static void svg_parse_path(SVG_PathData *d_attribute, char *attribute_content) +static void svg_parse_path(SVG_PathData *d_attribute, char *attribute_content) { GF_List *d_commands = d_attribute->commands; GF_List *d_points = d_attribute->points; @@ -1439,7 +1690,7 @@ static void svg_parse_path(SVG_PathData *d_attribute, char *attribute_content) cur_pt.x = cur_pt.y = 0; prev_m_pt.x = prev_m_pt.y = 0; while(1) { - while ( (d[i]==' ') || (d[i] =='\t') ) i++; + while ( (d[i]==' ') || (d[i] =='\t') ) i++; c = d[i]; if (! c) break; next_command: @@ -1455,8 +1706,8 @@ next_command: GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->x), 0); - i += svg_parse_float(&(d[i]), &(pt->y), 0); + i += svg_parse_number(&(d[i]), &(pt->x), 0); + i += svg_parse_number(&(d[i]), &(pt->y), 0); if (c == 'm') { pt->x += cur_pt.x; pt->y += cur_pt.y; @@ -1473,12 +1724,12 @@ next_command: GF_SAFEALLOC(command, u8) gf_list_add(d_commands, command); *command = SVG_PATHCOMMAND_L; - + GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->x), 0); - i += svg_parse_float(&(d[i]), &(pt->y), 0); + i += svg_parse_number(&(d[i]), &(pt->x), 0); + i += svg_parse_number(&(d[i]), &(pt->y), 0); if (c == 'l') { pt->x += cur_pt.x; pt->y += cur_pt.y; @@ -1489,7 +1740,7 @@ next_command: break; case 'H': case 'h': - i++; + i++; #ifndef REMOVE_ALLOC GF_SAFEALLOC(command, u8) gf_list_add(d_commands, command); @@ -1498,7 +1749,7 @@ next_command: GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->x), 0); + i += svg_parse_number(&(d[i]), &(pt->x), 0); if (c == 'h') { pt->x += cur_pt.x; } @@ -1508,7 +1759,7 @@ next_command: break; case 'V': case 'v': - i++; + i++; #ifndef REMOVE_ALLOC GF_SAFEALLOC(command, u8) gf_list_add(d_commands, command); @@ -1517,7 +1768,7 @@ next_command: GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->y), 0); + i += svg_parse_number(&(d[i]), &(pt->y), 0); if (c == 'v') { pt->y += cur_pt.y; } @@ -1527,92 +1778,92 @@ next_command: break; case 'C': case 'c': - i++; + i++; #ifndef REMOVE_ALLOC GF_SAFEALLOC(command, u8) gf_list_add(d_commands, command); *command = SVG_PATHCOMMAND_C; #endif - + for (k=0; k<3; k++) { #ifndef REMOVE_ALLOC GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->x), 0); - i += svg_parse_float(&(d[i]), &(pt->y), 0); + i += svg_parse_number(&(d[i]), &(pt->x), 0); + i += svg_parse_number(&(d[i]), &(pt->y), 0); if (c == 'c') { pt->x += cur_pt.x; pt->y += cur_pt.y; } - } + } cur_pt.x = pt->x; cur_pt.y = pt->y; prev_c = c; break; case 'S': case 's': - i++; + i++; #ifndef REMOVE_ALLOC GF_SAFEALLOC(command, u8) gf_list_add(d_commands, command); *command = SVG_PATHCOMMAND_S; #endif - + for (k=0; k<2; k++) { #ifndef REMOVE_ALLOC GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->x), 0); - i += svg_parse_float(&(d[i]), &(pt->y), 0); + i += svg_parse_number(&(d[i]), &(pt->x), 0); + i += svg_parse_number(&(d[i]), &(pt->y), 0); if (c == 's') { pt->x += cur_pt.x; pt->y += cur_pt.y; } - } + } cur_pt.x = pt->x; cur_pt.y = pt->y; prev_c = c; break; case 'Q': case 'q': - i++; + i++; #ifndef REMOVE_ALLOC GF_SAFEALLOC(command, u8) gf_list_add(d_commands, command); *command = SVG_PATHCOMMAND_Q; #endif - + for (k=0; k<2; k++) { #ifndef REMOVE_ALLOC GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->x), 0); - i += svg_parse_float(&(d[i]), &(pt->y), 0); + i += svg_parse_number(&(d[i]), &(pt->x), 0); + i += svg_parse_number(&(d[i]), &(pt->y), 0); if (c == 'q') { pt->x += cur_pt.x; pt->y += cur_pt.y; } - } + } cur_pt.x = pt->x; cur_pt.y = pt->y; prev_c = c; break; case 'T': case 't': - i++; + i++; #ifndef REMOVE_ALLOC GF_SAFEALLOC(command, u8) gf_list_add(d_commands, command); *command = SVG_PATHCOMMAND_T; - + GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->x), 0); - i += svg_parse_float(&(d[i]), &(pt->y), 0); + i += svg_parse_number(&(d[i]), &(pt->x), 0); + i += svg_parse_number(&(d[i]), &(pt->y), 0); if (c == 't') { pt->x += cur_pt.x; pt->y += cur_pt.y; @@ -1625,28 +1876,28 @@ next_command: case 'a': { Fixed tmp; - i++; + i++; #ifndef REMOVE_ALLOC GF_SAFEALLOC(command, u8) gf_list_add(d_commands, command); *command = SVG_PATHCOMMAND_A; - + GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->x), 0); - i += svg_parse_float(&(d[i]), &(pt->y), 0); + i += svg_parse_number(&(d[i]), &(pt->x), 0); + i += svg_parse_number(&(d[i]), &(pt->y), 0); + + i += svg_parse_number(&(d[i]), &(tmp), 0); + i += svg_parse_number(&(d[i]), &(tmp), 0); + i += svg_parse_number(&(d[i]), &(tmp), 0); - i += svg_parse_float(&(d[i]), &(tmp), 0); - i += svg_parse_float(&(d[i]), &(tmp), 0); - i += svg_parse_float(&(d[i]), &(tmp), 0); - #ifndef REMOVE_ALLOC GF_SAFEALLOC(pt, SVG_Point) gf_list_add(d_points, pt); #endif - i += svg_parse_float(&(d[i]), &(pt->x), 0); - i += svg_parse_float(&(d[i]), &(pt->y), 0); + i += svg_parse_number(&(d[i]), &(pt->x), 0); + i += svg_parse_number(&(d[i]), &(pt->y), 0); if (c == 'a') { pt->x += cur_pt.x; pt->y += cur_pt.y; @@ -1658,7 +1909,7 @@ next_command: break; case 'Z': case 'z': - i++; + i++; #ifndef REMOVE_ALLOC GF_SAFEALLOC(command, u8) gf_list_add(d_commands, command); @@ -1689,12 +1940,12 @@ next_command: static void svg_parse_iri(GF_Node *elt, XMLRI *iri, char *attribute_content) { if (iri->string) { - free(iri->string); + gf_free(iri->string); iri->string = NULL; } /* TODO: Handle xpointer(id()) syntax */ if (attribute_content[0] == '#') { - iri->string = strdup(attribute_content); + iri->string = gf_strdup(attribute_content); iri->target = gf_sg_find_node_by_name(elt->sgprivate->scenegraph, attribute_content + 1); if (!iri->target) { iri->type = XMLRI_STRING; @@ -1704,7 +1955,7 @@ static void svg_parse_iri(GF_Node *elt, XMLRI *iri, char *attribute_content) } } else { iri->type = XMLRI_STRING; - iri->string = strdup(attribute_content); + iri->string = gf_strdup(attribute_content); } } @@ -1713,7 +1964,7 @@ static void svg_parse_idref(GF_Node *elt, XML_IDREF *iri, char *attribute_conten iri->type = XMLRI_ELEMENTID; iri->target = gf_sg_find_node_by_name(elt->sgprivate->scenegraph, attribute_content); if (!iri->target) { - iri->string = strdup(attribute_content); + iri->string = gf_strdup(attribute_content); } else { gf_node_register_iri(elt->sgprivate->scenegraph, iri); } @@ -1738,11 +1989,16 @@ static void svg_parse_paint(GF_Node *n, SVG_Paint *paint, char *attribute_conten } } - -static u32 svg_parse_number(SVG_Number *number, char *value_string, Bool clamp0to1) +/* Parses a length which is a number with a unit */ +static u32 svg_parse_length(SVG_Number *number, char *value_string, Bool clamp0to1) { - char *unit = NULL; + char c; + char *unit = NULL; u32 len = 0; + u32 unit_pos; + u32 unit_len = 0; + u32 read_chars; + if (!strcmp(value_string, "inherit")) { number->type = SVG_NUMBER_INHERIT; return 7; @@ -1754,6 +2010,7 @@ static u32 svg_parse_number(SVG_Number *number, char *value_string, Bool clamp0t return 12; } else if ((unit = strstr(value_string, "%")) ) { number->type = SVG_NUMBER_PERCENTAGE; + unit_len = 1; } else if ((unit = strstr(value_string, "em"))) { number->type = SVG_NUMBER_EMS; } else if ((unit = strstr(value_string, "ex"))) { @@ -1773,8 +2030,23 @@ static u32 svg_parse_number(SVG_Number *number, char *value_string, Bool clamp0t } else { number->type = SVG_NUMBER_VALUE; } - if (unit) len = strlen(unit); - len+=svg_parse_float(value_string, &(number->value), 0); + if (unit) { + if (!unit_len) unit_len = 2; + unit_pos = unit - value_string; + /* setting the first unit character to 0 for the svg_parse_number method to finish */ + c = value_string[unit_pos]; + value_string[unit_pos] = 0; + } + read_chars = svg_parse_number(value_string, &(number->value), 0); + if (unit) { + value_string[unit_pos] = c; + } + if (!read_chars) { + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Parsing] Error in parsing: %s\n", value_string)); + len = 0; + } else { + len = unit_len + read_chars; + } if (clamp0to1) number->value = MAX(0, MIN(1, number->value)); return len; @@ -1790,7 +2062,7 @@ static void svg_parse_visibility(SVG_Visibility *value, char *value_string) *value = SVG_VISIBILITY_HIDDEN; } else if (!strcmp(value_string, "collapse")) { *value = SVG_VISIBILITY_COLLAPSE; - } + } } static void svg_parse_display(SVG_Display *value, char *value_string) @@ -1831,11 +2103,11 @@ static void svg_parse_display(SVG_Display *value, char *value_string) *value = SVG_DISPLAY_TABLE_CELL; } else if (!strcmp(value_string, "table-caption")) { *value = SVG_DISPLAY_TABLE_CAPTION; - } + } } static void svg_parse_displayalign(SVG_DisplayAlign *value, char *value_string) -{ +{ if (!strcmp(value_string, "inherit")) { *value = SVG_DISPLAYALIGN_INHERIT; } else if (!strcmp(value_string, "auto")) { @@ -1850,7 +2122,7 @@ static void svg_parse_displayalign(SVG_DisplayAlign *value, char *value_string) } static void svg_parse_textalign(SVG_TextAlign *value, char *value_string) -{ +{ if (!strcmp(value_string, "inherit")) { *value = SVG_TEXTALIGN_INHERIT; } else if (!strcmp(value_string, "start")) { @@ -1859,7 +2131,7 @@ static void svg_parse_textalign(SVG_TextAlign *value, char *value_string) *value = SVG_TEXTALIGN_CENTER; } else if (!strcmp(value_string, "end")) { *value = SVG_TEXTALIGN_END; - } + } } static void svg_parse_pointerevents(SVG_PointerEvents *value, char *value_string) @@ -2009,7 +2281,7 @@ static void svg_parse_clipfillrule(SVG_FillRule *value, char *value_string) *value = SVG_FILLRULE_NONZERO; } else if (!strcmp(value_string, "evenodd")) { *value = SVG_FILLRULE_EVENODD; - } + } } static void svg_parse_strokelinejoin(SVG_StrokeLineJoin *value, char *value_string) @@ -2022,7 +2294,7 @@ static void svg_parse_strokelinejoin(SVG_StrokeLineJoin *value, char *value_stri *value = SVG_STROKELINEJOIN_ROUND; } else if (!strcmp(value_string, "bevel")) { *value = SVG_STROKELINEJOIN_BEVEL; - } + } } static void svg_parse_strokelinecap(SVG_StrokeLineCap *value, char *value_string) @@ -2035,7 +2307,7 @@ static void svg_parse_strokelinecap(SVG_StrokeLineCap *value, char *value_string *value = SVG_STROKELINECAP_ROUND; } else if (!strcmp(value_string, "square")) { *value = SVG_STROKELINECAP_SQUARE; - } + } } static void svg_parse_fontfamily(SVG_FontFamily *value, char *value_string) @@ -2044,7 +2316,7 @@ static void svg_parse_fontfamily(SVG_FontFamily *value, char *value_string) value->type = SVG_FONTFAMILY_INHERIT; } else { value->type = SVG_FONTFAMILY_VALUE; - value->value = strdup(value_string); + value->value = gf_strdup(value_string); } } @@ -2058,7 +2330,7 @@ static void svg_parse_fontstyle(SVG_FontStyle *value, char *value_string) *value = SVG_FONTSTYLE_ITALIC; } else if (!strcmp(value_string, "oblique")) { *value = SVG_FONTSTYLE_OBLIQUE; - } + } } static void svg_parse_fontweight(SVG_FontWeight *value, char *value_string) @@ -2091,7 +2363,7 @@ static void svg_parse_fontweight(SVG_FontWeight *value, char *value_string) *value = SVG_FONTWEIGHT_800; } else if (!strcmp(value_string, "900")) { *value = SVG_FONTWEIGHT_900; - } + } } static void svg_parse_fontvariant(SVG_FontVariant *value, char *value_string) @@ -2102,7 +2374,7 @@ static void svg_parse_fontvariant(SVG_FontVariant *value, char *value_string) *value = SVG_FONTVARIANT_NORMAL; } else if (!strcmp(value_string, "small-caps")) { *value = SVG_FONTVARIANT_SMALLCAPS; - } + } } static void svg_parse_boolean(SVG_Boolean *value, char *value_string) @@ -2189,15 +2461,15 @@ static void smil_parse_time_list(GF_Node *e, GF_List *values, char *begin_or_end err: /* See SVG spec: - "If the 'begin' attribute is - syntactically invalid, in the list itself or in any of the individual + "If the 'begin' attribute is + syntactically invalid, in the list itself or in any of the individual list values, it is equivalent to a single 'begin' value of 'indefinite'."*/ len = gf_list_count(values); while (len) { SMIL_Time *v = (SMIL_Time*)gf_list_get(values, 0); - if (v->element_id) free(v->element_id); + if (v->element_id) gf_free(v->element_id); gf_list_rem(values, 0); - free(v); + gf_free(v); len--; } @@ -2287,7 +2559,7 @@ static void smil_parse_calcmode(SMIL_CalcMode *value, char *value_string) *value = SMIL_CALCMODE_PACED; } else if (!strcmp(value_string, "spline")) { *value = SMIL_CALCMODE_SPLINE; - } + } } static void smil_parse_additive(SMIL_Additive *value, char *value_string) @@ -2296,7 +2568,7 @@ static void smil_parse_additive(SMIL_Additive *value, char *value_string) *value = SMIL_ADDITIVE_REPLACE; } else if (!strcmp(value_string, "sum")) { *value = SMIL_ADDITIVE_SUM; - } + } } static void smil_parse_accumulate(SMIL_Accumulate *value, char *value_string) @@ -2305,7 +2577,7 @@ static void smil_parse_accumulate(SMIL_Accumulate *value, char *value_string) *value = SMIL_ACCUMULATE_NONE; } else if (!strcmp(value_string, "sum")) { *value = SMIL_ACCUMULATE_SUM; - } + } } static void smil_parse_syncBehaviorOrDefault(SMIL_SyncBehavior *value, char *value_string) @@ -2320,7 +2592,7 @@ static void smil_parse_syncBehaviorOrDefault(SMIL_SyncBehavior *value, char *val *value = SMIL_SYNCBEHAVIOR_CANSLIP; } else if (!strcmp(value_string, "independent")) { *value = SMIL_SYNCBEHAVIOR_INDEPENDENT; - } + } } static void smil_parse_syncToleranceOrDefault(SMIL_SyncTolerance *value, char *value_string) @@ -2337,19 +2609,29 @@ static void smil_parse_syncToleranceOrDefault(SMIL_SyncTolerance *value, char *v static void svg_parse_viewbox(SVG_ViewBox *value, char *value_string) { + u32 read_chars; char *str = value_string; if (!strcmp(str, "none")) { value->is_set = 0; } else { u32 i = 0; value->is_set = 1; - i+=svg_parse_float(&(str[i]), &(value->x), 0); - i+=svg_parse_float(&(str[i]), &(value->y), 0); - i+=svg_parse_float(&(str[i]), &(value->width), 0); - i+=svg_parse_float(&(str[i]), &(value->height), 0); + read_chars = svg_parse_number(&(str[i]), &(value->x), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &(value->y), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &(value->width), 0); + if (!read_chars) return; + i += read_chars; + read_chars = svg_parse_number(&(str[i]), &(value->height), 0); + if (!read_chars) return; + i += read_chars; } } +/* Parses a list of coordinates or a list of lengths (in SVG, length and coordinate is the same type )*/ static void svg_parse_coordinates(GF_List *values, char *value_string) { SVG_Coordinate *c; @@ -2360,14 +2642,14 @@ static void svg_parse_coordinates(GF_List *values, char *value_string) while (gf_list_count(values)) { c = (SVG_Coordinate*)gf_list_get(values, 0); gf_list_rem(values, 0); - free(c); + gf_free(c); } while (i < len) { u32 sub; GF_SAFEALLOC(c, SVG_Coordinate) - sub = svg_parse_number(c, &(str[i]), 0); + sub = svg_parse_length(c, &(str[i]), 0); if (!sub) { - free(c); + gf_free(c); return; } i+=sub; @@ -2375,12 +2657,14 @@ static void svg_parse_coordinates(GF_List *values, char *value_string) } } +/* Parse a point as a pair of number without units */ u32 svg_parse_point(SVG_Point *p, char *value_string) { u32 i = 0, j = 0; - i = svg_parse_float(&(value_string[i]), &(p->x), 0); - j = svg_parse_float(&(value_string[i]), &(p->y), 0); - /* we need to detect an odd number of coordinates in polygon points list + i = svg_parse_number(&(value_string[i]), &(p->x), 0); + /* TODO: handle cases where a point has an invalid syntax */ + j = svg_parse_number(&(value_string[i]), &(p->y), 0); + /* we need to detect an odd number of coordinates in polygon points list cf. http://www.w3.org/TR/SVGMobile12/shapes.html#PolygonElement see svg_parse_points */ if (j == 0) return 0; @@ -2389,13 +2673,16 @@ u32 svg_parse_point(SVG_Point *p, char *value_string) static u32 svg_parse_point_into_matrix(GF_Matrix2D *p, char *value_string) { - u32 i = 0; + u32 i = 0, j = 0; gf_mx2d_init(*p); - i+=svg_parse_float(&(value_string[i]), &(p->m[2]), 0); - i+=svg_parse_float(&(value_string[i]), &(p->m[5]), 0); - return i; + i = svg_parse_number(&(value_string[i]), &(p->m[2]), 0); + if (i == 0) return 0; + j = svg_parse_number(&(value_string[i]), &(p->m[5]), 0); + if (j == 0) return 0; + return i+j; } +/* Parses the points attribute of a polygon or polyline element */ static void svg_parse_points(GF_List *values, char *value_string) { u32 i = 0, j; @@ -2407,11 +2694,11 @@ static void svg_parse_points(GF_List *values, char *value_string) j = svg_parse_point(p, &str[i]); if (j == 0) { /* cf. http://www.w3.org/TR/SVGMobile12/shapes.html#PolygonElement - If an odd number of coordinates is provided, then the element + If an odd number of coordinates is provided, then the element is treated as if the attribute had not been specified.*/ while (gf_list_count(values)) { p = (SVG_Point *)gf_list_get(values, 0); - free(p); + gf_free(p); gf_list_rem(values, 0); } return; @@ -2421,19 +2708,22 @@ static void svg_parse_points(GF_List *values, char *value_string) } } -static void svg_parse_floats(GF_List *values, char *value_string, Bool is_angle) +/* Parses a list of numbers */ +static void svg_parse_numbers(GF_List *values, char *value_string, Bool is_angle) { + u32 read_chars; u32 i = 0; char *str = value_string; u32 len = strlen(str); while (i < len) { Fixed *f; GF_SAFEALLOC(f, Fixed) - i+=svg_parse_float(&(str[i]), f, is_angle); - if (!i) { - free(f); + read_chars = svg_parse_number(&(str[i]), f, is_angle); + if (!read_chars) { + gf_free(f); return; } + i += read_chars; gf_list_add(values, f); } } @@ -2443,13 +2733,13 @@ static void svg_string_list_add(GF_List *values, char *string, u32 string_type) XMLRI *iri; switch (string_type) { case 1: - iri = (XMLRI*)malloc(sizeof(XMLRI)); + iri = (XMLRI*)gf_malloc(sizeof(XMLRI)); iri->type = XMLRI_STRING; - iri->string = strdup(string); + iri->string = gf_strdup(string); gf_list_add(values, iri); break; default: - gf_list_add(values, strdup(string)); + gf_list_add(values, gf_strdup(string)); break; } } @@ -2461,9 +2751,9 @@ static void svg_parse_strings(GF_List *values, char *value_string, u32 string_ty while (gf_list_count(values)) { next = (char*)gf_list_last(values); gf_list_rem_last(values); - free(next); + gf_free(next); } - + while (1) { while (sep && sep[0]==' ') sep++; if (!sep) break; @@ -2486,28 +2776,36 @@ static void svg_parse_strings(GF_List *values, char *value_string, u32 string_ty static void svg_parse_strokedasharray(SVG_StrokeDashArray *value, char *value_string) { + u32 read_chars; if (!strcmp(value_string, "none")) { value->type = SVG_STROKEDASHARRAY_NONE; } else if (!strcmp(value_string, "inherit")) { value->type = SVG_STROKEDASHARRAY_INHERIT; } else { - Array *vals = &(value->array); + UnitArray *vals = &(value->array); GF_List *values = gf_list_new(); u32 i = 0; u32 len = strlen(value_string); char *str = value_string; while (i < len) { - Fixed *f; - GF_SAFEALLOC(f, Fixed) - i+=svg_parse_float(&(str[i]), f, 0); + SVG_Length *f; + GF_SAFEALLOC(f, SVG_Length) + read_chars = svg_parse_length(f, &(str[i]), 0); + if (!read_chars) { + free(f); + return; + } + i += read_chars; gf_list_add(values, f); } vals->count = gf_list_count(values); - vals->vals = (Fixed *) malloc(sizeof(Fixed)*vals->count); + vals->units = (u8 *) gf_malloc(sizeof(u8)*vals->count); + vals->vals = (Fixed *) gf_malloc(sizeof(Fixed)*vals->count); for (i = 0; i < vals->count; i++) { - Fixed *f = (Fixed *)gf_list_get(values, i); - vals->vals[i] = *f; - free(f); + SVG_Length *f = (SVG_Length *)gf_list_get(values, i); + vals->vals[i] = f->value; + vals->units[i] = f->type; + gf_free(f); } gf_list_del(values); value->type = SVG_STROKEDASHARRAY_ARRAY; @@ -2520,7 +2818,7 @@ static void svg_parse_zoomandpan(SVG_ZoomAndPan *value, char *value_string) *value = SVG_ZOOMANDPAN_DISABLE; } else if (!strcmp(value_string, "magnify")) { *value = SVG_ZOOMANDPAN_MAGNIFY; - } + } } static void svg_parse_preserveaspectratio(SVG_PreserveAspectRatio *par, char *attribute_content) @@ -2645,7 +2943,7 @@ static void svg_parse_transformbehavior(SVG_TransformBehavior *tb, char *attribu static void svg_parse_focus(GF_Node *e, SVG_Focus *o, char *attribute_content) { - if (o->target.string) free(o->target.string); + if (o->target.string) gf_free(o->target.string); o->target.string = NULL; o->target.target = NULL; @@ -2681,7 +2979,7 @@ void svg_parse_anim_values(GF_Node *n, SMIL_AnimateValues *anim_values, char *an GF_FieldInfo info; info.fieldType = anim_value_type; anim_values->type = anim_value_type; - + str = anim_values_string; while (1) { if (str[i] == ';' || str[i] == 0) { @@ -2720,8 +3018,8 @@ GF_Err laser_parse_size(LASeR_Size *size, char *attribute_content) { char *str = attribute_content; u32 i = 0; - i+=svg_parse_float(&(str[i]), &(size->width), 0); - i+=svg_parse_float(&(str[i]), &(size->height), 0); + i+=svg_parse_number(&(str[i]), &(size->width), 0); + i+=svg_parse_number(&(str[i]), &(size->height), 0); return GF_OK; } @@ -2736,17 +3034,18 @@ GF_Err gf_svg_parse_element_id(GF_Node *n, const char *nodename, Bool warning_if /* Parse an SVG attribute */ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_content, u8 anim_value_type) { - if (info->fieldType != DOM_String_datatype) { + /* for all attributes, except strings, apply some sort of white space normalization*/ + if (info->fieldType != DOM_String_datatype && strlen(attribute_content)) { u32 i, len; /*remove spaces at the begining*/ - while (strchr("\r\n\t ", attribute_content[0])) + while (attribute_content[0] && (strchr("\r\n\t ", attribute_content[0]))) attribute_content++; /*change all special chars in spaces*/ i=0; len = strlen(attribute_content); while (i<len) { - if (strchr("\r\n\t", attribute_content[i])) + if (strchr("\r\n\t", attribute_content[i])) attribute_content[i] = ' '; i++; } @@ -2843,7 +3142,7 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co break; case SMIL_AttributeType_datatype: smil_parse_attributeType((SMIL_AttributeType *)info->far_ptr, attribute_content); - break; + break; case SMIL_CalcMode_datatype: smil_parse_calcmode((SMIL_CalcMode *)info->far_ptr, attribute_content); break; @@ -2883,15 +3182,23 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co else if (!strcmp(attribute_content, "repeat")) *(u8*)info->far_ptr = SVG_SPREAD_REPEAT; else *(u8*)info->far_ptr = SVG_SPREAD_PAD; break; + case SVG_Filter_TransferType_datatype: + if (!strcmp(attribute_content, "table")) *(u8*)info->far_ptr = SVG_FILTER_TRANSFER_TABLE; + else if (!strcmp(attribute_content, "discrete")) *(u8*)info->far_ptr = SVG_FILTER_TRANSFER_DISCRETE; + else if (!strcmp(attribute_content, "linear")) *(u8*)info->far_ptr = SVG_FILTER_TRANSFER_LINEAR; + else if (!strcmp(attribute_content, "gamma")) *(u8*)info->far_ptr = SVG_FILTER_TRANSFER_GAMMA; + else *(u8*)info->far_ptr = SVG_FILTER_TRANSFER_IDENTITY; + break; + /* end of keyword type parsing */ - /* keyword | floats */ + /* keyword | numbers (with possibly units) */ case SVG_Length_datatype: - case SVG_Coordinate_datatype: + case SVG_Coordinate_datatype: case SVG_FontSize_datatype: case SVG_Rotate_datatype: - case SVG_Number_datatype: - svg_parse_number((SVG_Number*)info->far_ptr, attribute_content, 0); + case SVG_Number_datatype: + svg_parse_length((SVG_Number*)info->far_ptr, attribute_content, 0); break; case SMIL_AnimateValue_datatype: @@ -2908,7 +3215,7 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co svg_parse_idref(n, (XMLRI*)info->far_ptr, attribute_content); break; case SMIL_AttributeName_datatype: - ((SMIL_AttributeName *)info->far_ptr)->name = strdup(attribute_content); + ((SMIL_AttributeName *)info->far_ptr)->name = gf_strdup(attribute_content); break; case SMIL_Times_datatype: smil_parse_time_list(n, *(GF_List **)info->far_ptr, attribute_content); @@ -2928,9 +3235,9 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co case SMIL_KeyTimes_datatype: case SMIL_KeyPoints_datatype: case SMIL_KeySplines_datatype: - svg_parse_floats(*(GF_List **)(info->far_ptr), attribute_content, 0); - break; case SVG_Numbers_datatype: + svg_parse_numbers(*(GF_List **)(info->far_ptr), attribute_content, 0); + break; case SVG_Coordinates_datatype: svg_parse_coordinates(*(GF_List **)(info->far_ptr), attribute_content); break; @@ -2953,11 +3260,11 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co { u32 i = 0; SVG_Point *p = (SVG_Point *)info->far_ptr;; - i+=svg_parse_float(&(attribute_content[i]), &(p->x), 0); + i+=svg_parse_number(&(attribute_content[i]), &(p->x), 0); if (attribute_content[i] == 0) { p->y = 0; } else { - i+=svg_parse_float(&(attribute_content[i]), &(p->y), 0); + i+=svg_parse_number(&(attribute_content[i]), &(p->y), 0); } } break; @@ -2965,11 +3272,11 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co { u32 i = 0; SVG_Point *p = (SVG_Point *)info->far_ptr;; - i+=svg_parse_float(&(attribute_content[i]), &(p->x), 0); + i+=svg_parse_number(&(attribute_content[i]), &(p->x), 0); if (attribute_content[i] == 0) { p->y = p->x; } else { - i+=svg_parse_float(&(attribute_content[i]), &(p->y), 0); + i+=svg_parse_number(&(attribute_content[i]), &(p->y), 0); } } break; @@ -2977,20 +3284,20 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co case SVG_Transform_SkewY_datatype: { Fixed *p = (Fixed *)info->far_ptr; - svg_parse_float(attribute_content, p, 1); + svg_parse_number(attribute_content, p, 1); } break; case SVG_Transform_Rotate_datatype: { u32 i = 0; SVG_Point_Angle *p = (SVG_Point_Angle *)info->far_ptr;; - i+=svg_parse_float(&(attribute_content[i]), &(p->angle), 1); + i+=svg_parse_number(&(attribute_content[i]), &(p->angle), 1); if (attribute_content[i] == 0) { p->y = p->x = 0; } else { - i+=svg_parse_float(&(attribute_content[i]), &(p->x), 0); - i+=svg_parse_float(&(attribute_content[i]), &(p->y), 0); - } + i+=svg_parse_number(&(attribute_content[i]), &(p->x), 0); + i+=svg_parse_number(&(attribute_content[i]), &(p->y), 0); + } } break; case SVG_PreserveAspectRatio_datatype: @@ -3004,9 +3311,9 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co case DOM_String_datatype: case SVG_ContentType_datatype: case SVG_LanguageID_datatype: - if (*(SVG_String *)info->far_ptr) free(*(SVG_String *)info->far_ptr); + if (*(SVG_String *)info->far_ptr) gf_free(*(SVG_String *)info->far_ptr); - *(SVG_String *)info->far_ptr = strdup(attribute_content); + *(SVG_String *)info->far_ptr = gf_strdup(attribute_content); break; case DOM_StringList_datatype: @@ -3033,7 +3340,7 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co sep2[0] = 0; xml_ev->parameter = gf_dom_get_key_type(sep+1); sep2[0] = ')'; - } + } } else { xml_ev->parameter = 0; xml_ev->type = gf_dom_event_type_by_name(attribute_content); @@ -3053,6 +3360,10 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co case SVG_Clock_datatype: svg_parse_clock_value(attribute_content, (SVG_Clock*)info->far_ptr); break; + case SVG_Unknown_datatype: + if (*(SVG_String *)info->far_ptr) gf_free(*(SVG_String *)info->far_ptr); + *(SVG_String *)info->far_ptr = gf_strdup(attribute_content); + break; default: GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG Parsing] Cannot parse attribute %s\n", info->name, gf_svg_attribute_type_to_string(info->fieldType))); break; @@ -3060,7 +3371,7 @@ GF_Err gf_svg_parse_attribute(GF_Node *n, GF_FieldInfo *info, char *attribute_co return GF_OK; } -void svg_parse_one_style(GF_Node *n, char *one_style) +void svg_parse_one_style(GF_Node *n, char *one_style) { GF_FieldInfo info; char *c, sep; @@ -3083,12 +3394,12 @@ void svg_parse_one_style(GF_Node *n, char *one_style) one_style[attributeNameLen] = sep; } -void gf_svg_parse_style(GF_Node *n, char *style) +void gf_svg_parse_style(GF_Node *n, char *style) { u32 i = 0; char *str = style; s32 psemi = -1; - + while (1) { if (str[i] == ';' || str[i] == 0) { u32 single_value_len = 0; @@ -3107,6 +3418,7 @@ void gf_svg_parse_style(GF_Node *n, char *style) } +GF_EXPORT void *gf_svg_create_attribute_value(u32 attribute_type) { switch (attribute_type) { @@ -3126,12 +3438,12 @@ void *gf_svg_create_attribute_value(u32 attribute_type) break; case SVG_Paint_datatype: { - SVG_Paint *paint; + SVG_Paint *paint; GF_SAFEALLOC(paint, SVG_Paint) return paint; } break; - + /* keyword types */ case SVG_FillRule_datatype: case SVG_StrokeLineJoin_datatype: @@ -3170,6 +3482,7 @@ void *gf_svg_create_attribute_value(u32 attribute_type) case SVG_TransformBehavior_datatype: case SVG_SpreadMethod_datatype: case SVG_Focusable_datatype: + case SVG_Filter_TransferType_datatype: { u8 *keyword; GF_SAFEALLOC(keyword, u8) @@ -3195,8 +3508,8 @@ void *gf_svg_create_attribute_value(u32 attribute_type) GF_SAFEALLOC(number, SVG_Number) return number; } - break; - + break; + case SVG_StrokeDashArray_datatype: { SVG_StrokeDashArray *array; @@ -3311,7 +3624,7 @@ void *gf_svg_create_attribute_value(u32 attribute_type) #if USE_GF_PATH gf_path_reset(path); path->fineness = FIX_ONE; -#else +#else path->commands = gf_list_new(); path->points = gf_list_new(); #endif @@ -3386,24 +3699,33 @@ void *gf_svg_create_attribute_value(u32 attribute_type) } break; + case 0: + { + SVG_String *string; + GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG Attributes] Unspecified attribute type - defaulting to string.\n")); + GF_SAFEALLOC(string, SVG_String); + return string; + } + + default: - GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Attributes] Cannot create attribute value - Type %s not supported.\n", gf_svg_attribute_type_to_string(attribute_type))); + GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[SVG Attributes] Cannot create attribute value: Type %s not supported.\n", gf_svg_attribute_type_to_string(attribute_type))); break; - } + } return NULL; } -static void svg_dump_color(SVG_Color *col, char *attValue) +static char *svg_dump_color(SVG_Color *col) { - if (col->type == SVG_COLOR_CURRENTCOLOR) strcpy(attValue, "currentColor"); - else if (col->type == SVG_COLOR_INHERIT) strcpy(attValue, "inherit"); + char *res; + if (col->type == SVG_COLOR_CURRENTCOLOR) return gf_strdup("currentColor"); + else if (col->type == SVG_COLOR_INHERIT) return gf_strdup("inherit"); else if (col->type !=SVG_COLOR_RGBCOLOR) { u32 i, count; count = sizeof(system_colors) / sizeof(struct sys_col); for (i=0; i<count; i++) { if (col->type == system_colors[i].type) { - strcpy(attValue, system_colors[i].name); - return; + return gf_strdup(system_colors[i].name); } } } else { @@ -3418,72 +3740,96 @@ static void svg_dump_color(SVG_Color *col, char *attValue) && (g == predefined_colors[i].g) && (b == predefined_colors[i].b) ) { - strcpy(attValue, predefined_colors[i].name); - return; + return gf_strdup(predefined_colors[i].name); } } - sprintf(attValue, "#%02X%02X%02X", r, g, b); + res = gf_malloc(sizeof(char)*8); + sprintf(res, "#%02X%02X%02X", r, g, b); /*compress it...*/ - if ( (attValue[1]==attValue[2]) && (attValue[3]==attValue[4]) && (attValue[5]==attValue[6]) ) - sprintf(attValue, "#%c%c%c", attValue[1], attValue[3], attValue[5]); + if ( (res[1]==res[2]) && (res[3]==res[4]) && (res[5]==res[6]) ) + sprintf(res, "#%c%c%c", res[1], res[3], res[5]); + return res; } + return NULL; } -static void svg_dump_number(SVG_Number *l, char *attValue) +static char *svg_dump_number(SVG_Number *l) { - if (l->type==SVG_NUMBER_INHERIT) strcpy(attValue, "inherit"); - else if (l->type == SVG_NUMBER_AUTO) strcpy(attValue, "auto"); - else if (l->type == SVG_NUMBER_AUTO_REVERSE) strcpy(attValue, "auto-reverse"); + char tmp[100]; + if (l->type==SVG_NUMBER_INHERIT) return gf_strdup("inherit"); + else if (l->type == SVG_NUMBER_AUTO) return gf_strdup("auto"); + else if (l->type == SVG_NUMBER_AUTO_REVERSE) return gf_strdup("auto-reverse"); else { - sprintf(attValue, "%g", FIX2FLT(l->value) ); - if (l->type == SVG_NUMBER_PERCENTAGE) strcat(attValue, "%"); - else if (l->type == SVG_NUMBER_EMS) strcat(attValue, "em"); - else if (l->type == SVG_NUMBER_EXS) strcat(attValue, "ex"); - else if (l->type == SVG_NUMBER_PX) strcat(attValue, "px"); - else if (l->type == SVG_NUMBER_CM) strcat(attValue, "cm"); - else if (l->type == SVG_NUMBER_MM) strcat(attValue, "mm"); - else if (l->type == SVG_NUMBER_IN) strcat(attValue, "in"); - else if (l->type == SVG_NUMBER_PT) strcat(attValue, "pt"); - else if (l->type == SVG_NUMBER_PC) strcat(attValue, "pc"); + sprintf(tmp, "%g", FIX2FLT(l->value) ); + if (l->type == SVG_NUMBER_PERCENTAGE) strcat(tmp, "%"); + else if (l->type == SVG_NUMBER_EMS) strcat(tmp, "em"); + else if (l->type == SVG_NUMBER_EXS) strcat(tmp, "ex"); + else if (l->type == SVG_NUMBER_PX) strcat(tmp, "px"); + else if (l->type == SVG_NUMBER_CM) strcat(tmp, "cm"); + else if (l->type == SVG_NUMBER_MM) strcat(tmp, "mm"); + else if (l->type == SVG_NUMBER_IN) strcat(tmp, "in"); + else if (l->type == SVG_NUMBER_PT) strcat(tmp, "pt"); + else if (l->type == SVG_NUMBER_PC) strcat(tmp, "pc"); + + return gf_strdup(tmp); } } -static void svg_dump_iri(XMLRI*iri, char *attValue) +static char *svg_dump_iri(XMLRI*iri) { if (iri->type == XMLRI_ELEMENTID) { const char *name; + char *res; name = gf_node_get_name((GF_Node *)iri->target); - if (name) sprintf(attValue, "#%s", gf_node_get_name((GF_Node *)iri->target)); - else sprintf(attValue, "#N%d", gf_node_get_id((GF_Node *)iri->target) - 1); + + if (name) { + res = gf_malloc(sizeof(char)*(strlen(name)+2)); + sprintf(res, "#%s", name); + } else if (iri->target) { + res = gf_malloc(sizeof(char)*32); + sprintf(res, "#N%d", gf_node_get_id((GF_Node *)iri->target) - 1); + } else { + res = gf_strdup(""); + } + return res; } - else if ((iri->type == XMLRI_STRING) && iri->string) strcpy(attValue, iri->string); - else strcpy(attValue, ""); + else if ((iri->type == XMLRI_STRING) && iri->string) + return gf_strdup(iri->string); + else + return gf_strdup(""); } -static void svg_dump_idref(XMLRI*iri, char *attValue) +static char *svg_dump_idref(XMLRI*iri) { const char *name; if (iri->target) { name = gf_node_get_name((GF_Node *)iri->target); - if (name) sprintf(attValue, "%s", gf_node_get_name((GF_Node *)iri->target)); - else sprintf(attValue, "N%d", gf_node_get_id((GF_Node *)iri->target) - 1); - return; + if (name) return gf_strdup(name); + else { + char tmp[50]; + sprintf(tmp, "N%d", gf_node_get_id((GF_Node *)iri->target) - 1); + return gf_strdup(tmp); + } } - if (iri->string) strcpy(attValue, iri->string); + if (iri->string) return gf_strdup(iri->string); + return gf_strdup(""); } #if USE_GF_PATH -static void svg_dump_path(SVG_PathData *path, char *attValue) +static char *svg_dump_path(SVG_PathData *path) { char szT[1000]; GF_Point2D *pt, last_pt, *ct1, *ct2, *end; u32 i, *contour; - strcpy(attValue, ""); + char *res = gf_malloc(sizeof(char)); + res[0] = 0; contour = path->contours; last_pt.x = last_pt.y = 0; for (i=0; i<path->n_points; ) { + szT[0] = 0; + switch (path->tags[i]) { case GF_PATH_CURVE_ON: case GF_PATH_CLOSE: @@ -3498,7 +3844,6 @@ static void svg_dump_path(SVG_PathData *path, char *attValue) else if (i && (last_pt.y==pt->y)) sprintf(szT, "H%g", FIX2FLT(pt->x)); else sprintf(szT, "L%g %g", FIX2FLT(pt->x), FIX2FLT(pt->y)); } - strcat(attValue, szT); last_pt = *pt; i++; break; @@ -3506,10 +3851,10 @@ static void svg_dump_path(SVG_PathData *path, char *attValue) ct1 = &path->points[i]; end = &path->points[i+1]; sprintf(szT, "Q%g %g %g %g", FIX2FLT(ct1->x), FIX2FLT(ct1->y), FIX2FLT(end->x), FIX2FLT(end->y)); - strcat(attValue, szT); + last_pt = *end; if (path->tags[i+2]==GF_PATH_CLOSE) { - strcat(attValue, "z"); + strcat(szT, "z"); } i+=2; break; @@ -3518,16 +3863,19 @@ static void svg_dump_path(SVG_PathData *path, char *attValue) ct2 = &path->points[i+1]; end = &path->points[i+2]; sprintf(szT, "C%g %g %g %g %g %g", FIX2FLT(ct1->x), FIX2FLT(ct1->y), FIX2FLT(ct2->x), FIX2FLT(ct2->y), FIX2FLT(end->x), FIX2FLT(end->y)); - strcat(attValue, szT); last_pt = *end; if (path->tags[i+2]==GF_PATH_CLOSE) { - strcat(attValue, "z"); + strcat(szT, "z"); } i+=3; break; } + if (szT[0]) { + res = gf_realloc(res, sizeof(char)*(strlen(szT)+strlen(res)+1)); + strcat(res, szT); + } } - + return res; } #else static void svg_dump_point(SVG_Point *pt, char *attValue) @@ -3545,7 +3893,7 @@ static void svg_dump_path(SVG_PathData *path, char *attValue) u8 command = *(u8 *)gf_list_get(path->commands, i); switch(command) { case SVG_PATHCOMMAND_M: - strcat(attValue, "M"); + strcat(attValue, "M"); svg_dump_point((SVG_Point*)gf_list_get(path->points, pt_i), szT); strcat(attValue, szT); pt_i++; @@ -3624,7 +3972,7 @@ static void svg_dump_access_key(XMLEV_Event *evt, char *attValue) break; } } - /* OLD LASeR CODE + /* OLD LASeR CODE switch (evt->parameter) { case 0: strcat(attValue, "UP"); break; case 1: strcat(attValue, "DOWN"); break; @@ -3651,8 +3999,10 @@ static void svg_dump_access_key(XMLEV_Event *evt, char *attValue) strcat(attValue, ")"); } -static void gf_svg_dump_matrix(GF_Matrix2D *matrix, char *attValue) +static char *gf_svg_dump_matrix(GF_Matrix2D *matrix) { + char attValue[1024]; + attValue[0]=0; /*try to do a simple decomposition...*/ if (!matrix->m[1] && !matrix->m[3]) { if (matrix->m[2] != 0 || matrix->m[5] != 0) sprintf(attValue, "translate(%g,%g)", FIX2FLT(matrix->m[2]), FIX2FLT(matrix->m[5]) ); @@ -3674,301 +4024,309 @@ static void gf_svg_dump_matrix(GF_Matrix2D *matrix, char *attValue) sy = gf_divfix(matrix->m[4], cos_a); angle = gf_divfix(180*angle, GF_PI); if ((sx==sy) && ( ABS(FIX_ONE - ABS(sx) ) < FIX_ONE/100)) { - if (matrix->m[2] != 0 || matrix->m[5] != 0) + if (matrix->m[2] != 0 || matrix->m[5] != 0) sprintf(attValue, "translate(%g,%g) rotate(%g)", FIX2FLT(matrix->m[2]), FIX2FLT(matrix->m[5]), FIX2FLT(gf_divfix(angle*180, GF_PI) ) ); - else + else sprintf(attValue, "rotate(%g)", FIX2FLT(gf_divfix(angle*180, GF_PI) ) ); } else { - if (matrix->m[2] != 0 || matrix->m[5] != 0) + if (matrix->m[2] != 0 || matrix->m[5] != 0) sprintf(attValue, "translate(%g,%g) scale(%g,%g) rotate(%g)", FIX2FLT(matrix->m[2]), FIX2FLT(matrix->m[5]), FIX2FLT(sx), FIX2FLT(sy), FIX2FLT(gf_divfix(angle*180, GF_PI) ) ); - else + else sprintf(attValue, "scale(%g,%g) rotate(%g)", FIX2FLT(sx), FIX2FLT(sy), FIX2FLT(gf_divfix(angle*180, GF_PI) ) ); } } else { Fixed a = angle; if (a<0) a += GF_2PI; - if (matrix->m[2] != 0 || matrix->m[5] != 0) + if (matrix->m[2] != 0 || matrix->m[5] != 0) sprintf(attValue, "translate(%g,%g) rotate(%g)", FIX2FLT(matrix->m[2]), FIX2FLT(matrix->m[5]), FIX2FLT(gf_divfix(a*180, GF_PI) ) ); - else + else sprintf(attValue, "rotate(%g)", FIX2FLT(gf_divfix(a*180, GF_PI) ) ); } - } + } /*default*/ if (!strlen(attValue)) - sprintf(attValue, "matrix(%g %g %g %g %g %g)", FIX2FLT(matrix->m[0]), FIX2FLT(matrix->m[3]), FIX2FLT(matrix->m[1]), FIX2FLT(matrix->m[4]), FIX2FLT(matrix->m[2]), FIX2FLT(matrix->m[5]) ); + sprintf(attValue, "matrix(%g %g %g %g %g %g)", FIX2FLT(matrix->m[0]), FIX2FLT(matrix->m[3]), FIX2FLT(matrix->m[1]), FIX2FLT(matrix->m[4]), FIX2FLT(matrix->m[2]), FIX2FLT(matrix->m[5]) ); + + return gf_strdup(attValue); } -GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) +char *gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info) { + char tmp[1024]; u8 intVal; - strcpy(attValue, ""); - if (!info->far_ptr) return GF_OK; + + if (!info->far_ptr) return gf_strdup(""); intVal = *(u8 *)info->far_ptr; - + switch (info->fieldType) { case SVG_Boolean_datatype: - sprintf(attValue, "%s", *(SVG_Boolean *)info->far_ptr ? "true" : "false"); - break; + return gf_strdup( *(SVG_Boolean *)info->far_ptr ? "true" : "false"); + case SVG_Color_datatype: - { - SVG_Color *col = (SVG_Color *)info->far_ptr; - svg_dump_color(col, attValue); - } - break; + return svg_dump_color((SVG_Color *)info->far_ptr); + case SVG_Paint_datatype: { SVG_Paint *paint = (SVG_Paint *)info->far_ptr; - if (paint->type == SVG_PAINT_NONE) strcpy(attValue, "none"); - else if (paint->type == SVG_PAINT_INHERIT) strcpy(attValue, "inherit"); + if (paint->type == SVG_PAINT_NONE) return gf_strdup("none"); + else if (paint->type == SVG_PAINT_INHERIT) return gf_strdup("inherit"); else if (paint->type == SVG_PAINT_URI) { - char tmp[1024]; - svg_dump_iri(&paint->iri, tmp); - sprintf(attValue, "url(%s)", tmp); - } else svg_dump_color(&paint->color, attValue); + char *tmp = svg_dump_iri(&paint->iri); + char *res = gf_malloc(sizeof(char)*(strlen(tmp)+6)); + sprintf(res, "url(%s)", tmp); + gf_free(tmp); + return res; + } else { + return svg_dump_color(&paint->color); + } } break; /* beginning of keyword type parsing */ case SVG_FillRule_datatype: - if (intVal == SVG_FILLRULE_INHERIT) strcpy(attValue, "inherit"); - else if (intVal == SVG_FILLRULE_NONZERO) strcpy(attValue, "nonzero"); - else strcpy(attValue, "evenodd"); + if (intVal == SVG_FILLRULE_INHERIT) return gf_strdup("inherit"); + else if (intVal == SVG_FILLRULE_NONZERO) return gf_strdup("nonzero"); + else return gf_strdup("evenodd"); break; case SVG_StrokeLineJoin_datatype: - if (intVal==SVG_STROKELINEJOIN_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_STROKELINEJOIN_MITER) strcpy(attValue, "miter"); - else if (intVal==SVG_STROKELINEJOIN_ROUND) strcpy(attValue, "round"); - else if (intVal==SVG_STROKELINEJOIN_BEVEL) strcpy(attValue, "bevel"); + if (intVal==SVG_STROKELINEJOIN_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_STROKELINEJOIN_MITER) return gf_strdup("miter"); + else if (intVal==SVG_STROKELINEJOIN_ROUND) return gf_strdup("round"); + else if (intVal==SVG_STROKELINEJOIN_BEVEL) return gf_strdup("bevel"); break; case SVG_StrokeLineCap_datatype: - if (intVal==SVG_STROKELINECAP_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_STROKELINECAP_BUTT) strcpy(attValue, "butt"); - else if (intVal==SVG_STROKELINECAP_ROUND) strcpy(attValue, "round"); - else if (intVal==SVG_STROKELINECAP_SQUARE) strcpy(attValue, "square"); + if (intVal==SVG_STROKELINECAP_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_STROKELINECAP_BUTT) return gf_strdup("butt"); + else if (intVal==SVG_STROKELINECAP_ROUND) return gf_strdup("round"); + else if (intVal==SVG_STROKELINECAP_SQUARE) return gf_strdup("square"); break; case SVG_FontStyle_datatype: - if (intVal==SVG_FONTSTYLE_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_FONTSTYLE_NORMAL) strcpy(attValue, "normal"); - else if (intVal==SVG_FONTSTYLE_ITALIC) strcpy(attValue, "italic"); - else if (intVal==SVG_FONTSTYLE_OBLIQUE) strcpy(attValue, "oblique"); + if (intVal==SVG_FONTSTYLE_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_FONTSTYLE_NORMAL) return gf_strdup("normal"); + else if (intVal==SVG_FONTSTYLE_ITALIC) return gf_strdup("italic"); + else if (intVal==SVG_FONTSTYLE_OBLIQUE) return gf_strdup("oblique"); break; case SVG_FontWeight_datatype: - if (intVal==SVG_FONTWEIGHT_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_FONTWEIGHT_NORMAL) strcpy(attValue, "normal"); - else if (intVal==SVG_FONTWEIGHT_BOLD) strcpy(attValue, "bold"); - else if (intVal==SVG_FONTWEIGHT_BOLDER) strcpy(attValue, "bolder"); - else if (intVal==SVG_FONTWEIGHT_LIGHTER) strcpy(attValue, "lighter"); - else if (intVal==SVG_FONTWEIGHT_100) strcpy(attValue, "100"); - else if (intVal==SVG_FONTWEIGHT_200) strcpy(attValue, "200"); - else if (intVal==SVG_FONTWEIGHT_300) strcpy(attValue, "300"); - else if (intVal==SVG_FONTWEIGHT_400) strcpy(attValue, "400"); - else if (intVal==SVG_FONTWEIGHT_500) strcpy(attValue, "500"); - else if (intVal==SVG_FONTWEIGHT_600) strcpy(attValue, "600"); - else if (intVal==SVG_FONTWEIGHT_700) strcpy(attValue, "700"); - else if (intVal==SVG_FONTWEIGHT_800) strcpy(attValue, "800"); - else if (intVal==SVG_FONTWEIGHT_900) strcpy(attValue, "900"); + if (intVal==SVG_FONTWEIGHT_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_FONTWEIGHT_NORMAL) return gf_strdup("normal"); + else if (intVal==SVG_FONTWEIGHT_BOLD) return gf_strdup("bold"); + else if (intVal==SVG_FONTWEIGHT_BOLDER) return gf_strdup("bolder"); + else if (intVal==SVG_FONTWEIGHT_LIGHTER) return gf_strdup("lighter"); + else if (intVal==SVG_FONTWEIGHT_100) return gf_strdup("100"); + else if (intVal==SVG_FONTWEIGHT_200) return gf_strdup("200"); + else if (intVal==SVG_FONTWEIGHT_300) return gf_strdup("300"); + else if (intVal==SVG_FONTWEIGHT_400) return gf_strdup("400"); + else if (intVal==SVG_FONTWEIGHT_500) return gf_strdup("500"); + else if (intVal==SVG_FONTWEIGHT_600) return gf_strdup("600"); + else if (intVal==SVG_FONTWEIGHT_700) return gf_strdup("700"); + else if (intVal==SVG_FONTWEIGHT_800) return gf_strdup("800"); + else if (intVal==SVG_FONTWEIGHT_900) return gf_strdup("900"); break; case SVG_FontVariant_datatype: - if (intVal==SVG_FONTVARIANT_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_FONTVARIANT_NORMAL) strcpy(attValue, "normal"); - else if (intVal==SVG_FONTVARIANT_SMALLCAPS) strcpy(attValue, "small-caps"); + if (intVal==SVG_FONTVARIANT_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_FONTVARIANT_NORMAL) return gf_strdup("normal"); + else if (intVal==SVG_FONTVARIANT_SMALLCAPS) return gf_strdup("small-caps"); break; case SVG_TextAnchor_datatype: - if (intVal==SVG_TEXTANCHOR_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_TEXTANCHOR_START) strcpy(attValue, "start"); - else if (intVal==SVG_TEXTANCHOR_MIDDLE) strcpy(attValue, "middle"); - else if (intVal==SVG_TEXTANCHOR_END) strcpy(attValue, "end"); + if (intVal==SVG_TEXTANCHOR_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_TEXTANCHOR_START) return gf_strdup("start"); + else if (intVal==SVG_TEXTANCHOR_MIDDLE) return gf_strdup("middle"); + else if (intVal==SVG_TEXTANCHOR_END) return gf_strdup("end"); break; case SVG_Display_datatype: - if (intVal==SVG_DISPLAY_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_DISPLAY_NONE) strcpy(attValue, "none"); - else if (intVal==SVG_DISPLAY_INLINE) strcpy(attValue, "inline"); - else if (intVal==SVG_DISPLAY_BLOCK) strcpy(attValue, "block"); - else if (intVal==SVG_DISPLAY_LIST_ITEM) strcpy(attValue, "list-item"); - else if (intVal==SVG_DISPLAY_RUN_IN) strcpy(attValue, "run-in"); - else if (intVal==SVG_DISPLAY_COMPACT) strcpy(attValue, "compact"); - else if (intVal==SVG_DISPLAY_MARKER) strcpy(attValue, "marker"); - else if (intVal==SVG_DISPLAY_TABLE) strcpy(attValue, "table"); - else if (intVal==SVG_DISPLAY_INLINE_TABLE) strcpy(attValue, "inline-table"); - else if (intVal==SVG_DISPLAY_TABLE_ROW_GROUP) strcpy(attValue, "table-row-group"); - else if (intVal==SVG_DISPLAY_TABLE_HEADER_GROUP) strcpy(attValue, "table-header-group"); - else if (intVal==SVG_DISPLAY_TABLE_FOOTER_GROUP) strcpy(attValue, "table-footer-group"); - else if (intVal==SVG_DISPLAY_TABLE_ROW) strcpy(attValue, "table-row"); - else if (intVal==SVG_DISPLAY_TABLE_COLUMN_GROUP) strcpy(attValue, "table-column-group"); - else if (intVal==SVG_DISPLAY_TABLE_COLUMN) strcpy(attValue, "table-column"); - else if (intVal==SVG_DISPLAY_TABLE_CELL) strcpy(attValue, "table-cell"); - else if (intVal==SVG_DISPLAY_TABLE_CAPTION) strcpy(attValue, "table-caption"); + if (intVal==SVG_DISPLAY_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_DISPLAY_NONE) return gf_strdup("none"); + else if (intVal==SVG_DISPLAY_INLINE) return gf_strdup("inline"); + else if (intVal==SVG_DISPLAY_BLOCK) return gf_strdup("block"); + else if (intVal==SVG_DISPLAY_LIST_ITEM) return gf_strdup("list-item"); + else if (intVal==SVG_DISPLAY_RUN_IN) return gf_strdup("run-in"); + else if (intVal==SVG_DISPLAY_COMPACT) return gf_strdup("compact"); + else if (intVal==SVG_DISPLAY_MARKER) return gf_strdup("marker"); + else if (intVal==SVG_DISPLAY_TABLE) return gf_strdup("table"); + else if (intVal==SVG_DISPLAY_INLINE_TABLE) return gf_strdup("inline-table"); + else if (intVal==SVG_DISPLAY_TABLE_ROW_GROUP) return gf_strdup("table-row-group"); + else if (intVal==SVG_DISPLAY_TABLE_HEADER_GROUP) return gf_strdup("table-header-group"); + else if (intVal==SVG_DISPLAY_TABLE_FOOTER_GROUP) return gf_strdup("table-footer-group"); + else if (intVal==SVG_DISPLAY_TABLE_ROW) return gf_strdup("table-row"); + else if (intVal==SVG_DISPLAY_TABLE_COLUMN_GROUP) return gf_strdup("table-column-group"); + else if (intVal==SVG_DISPLAY_TABLE_COLUMN) return gf_strdup("table-column"); + else if (intVal==SVG_DISPLAY_TABLE_CELL) return gf_strdup("table-cell"); + else if (intVal==SVG_DISPLAY_TABLE_CAPTION) return gf_strdup("table-caption"); break; case SVG_Visibility_datatype: - if (intVal==SVG_VISIBILITY_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_VISIBILITY_VISIBLE) strcpy(attValue, "visible"); - else if (intVal==SVG_VISIBILITY_HIDDEN) strcpy(attValue, "hidden"); - else if (intVal==SVG_VISIBILITY_COLLAPSE) strcpy(attValue, "collapse"); + if (intVal==SVG_VISIBILITY_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_VISIBILITY_VISIBLE) return gf_strdup("visible"); + else if (intVal==SVG_VISIBILITY_HIDDEN) return gf_strdup("hidden"); + else if (intVal==SVG_VISIBILITY_COLLAPSE) return gf_strdup("collapse"); break; case SVG_Overflow_datatype: - if (intVal==SVG_OVERFLOW_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_OVERFLOW_VISIBLE) strcpy(attValue, "visible"); - else if (intVal==SVG_OVERFLOW_HIDDEN) strcpy(attValue, "hidden"); - else if (intVal==SVG_OVERFLOW_SCROLL) strcpy(attValue, "scroll"); - else if (intVal==SVG_OVERFLOW_AUTO) strcpy(attValue, "auto"); + if (intVal==SVG_OVERFLOW_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_OVERFLOW_VISIBLE) return gf_strdup("visible"); + else if (intVal==SVG_OVERFLOW_HIDDEN) return gf_strdup("hidden"); + else if (intVal==SVG_OVERFLOW_SCROLL) return gf_strdup("scroll"); + else if (intVal==SVG_OVERFLOW_AUTO) return gf_strdup("auto"); break; case SVG_ZoomAndPan_datatype: - if (intVal==SVG_ZOOMANDPAN_DISABLE) strcpy(attValue, "disable"); - else strcpy(attValue, "magnify"); + if (intVal==SVG_ZOOMANDPAN_DISABLE) return gf_strdup("disable"); + else return gf_strdup("magnify"); break; case SVG_DisplayAlign_datatype: - if (intVal==SVG_DISPLAYALIGN_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_DISPLAYALIGN_AUTO) strcpy(attValue, "auto"); - else if (intVal==SVG_DISPLAYALIGN_BEFORE) strcpy(attValue, "before"); - else if (intVal==SVG_DISPLAYALIGN_CENTER) strcpy(attValue, "center"); - else if (intVal==SVG_DISPLAYALIGN_AFTER) strcpy(attValue, "after"); + if (intVal==SVG_DISPLAYALIGN_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_DISPLAYALIGN_AUTO) return gf_strdup("auto"); + else if (intVal==SVG_DISPLAYALIGN_BEFORE) return gf_strdup("before"); + else if (intVal==SVG_DISPLAYALIGN_CENTER) return gf_strdup("center"); + else if (intVal==SVG_DISPLAYALIGN_AFTER) return gf_strdup("after"); break; case SVG_TextAlign_datatype: - if (intVal==SVG_TEXTALIGN_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_TEXTALIGN_START) strcpy(attValue, "start"); - else if (intVal==SVG_TEXTALIGN_CENTER) strcpy(attValue, "center"); - else if (intVal==SVG_TEXTALIGN_END) strcpy(attValue, "end"); + if (intVal==SVG_TEXTALIGN_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_TEXTALIGN_START) return gf_strdup("start"); + else if (intVal==SVG_TEXTALIGN_CENTER) return gf_strdup("center"); + else if (intVal==SVG_TEXTALIGN_END) return gf_strdup("end"); break; case SVG_PointerEvents_datatype: - if (intVal==SVG_POINTEREVENTS_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_POINTEREVENTS_VISIBLEPAINTED) strcpy(attValue, "visiblePainted"); - else if (intVal==SVG_POINTEREVENTS_VISIBLEFILL) strcpy(attValue, "visibleFill"); - else if (intVal==SVG_POINTEREVENTS_VISIBLESTROKE) strcpy(attValue, "visibleStroke"); - else if (intVal==SVG_POINTEREVENTS_VISIBLE) strcpy(attValue, "visible"); - else if (intVal==SVG_POINTEREVENTS_PAINTED) strcpy(attValue, "painted"); - else if (intVal==SVG_POINTEREVENTS_FILL) strcpy(attValue, "fill"); - else if (intVal==SVG_POINTEREVENTS_STROKE) strcpy(attValue, "stroke"); - else if (intVal==SVG_POINTEREVENTS_ALL) strcpy(attValue, "all"); - else if (intVal==SVG_POINTEREVENTS_NONE) strcpy(attValue, "none"); - else if (intVal==SVG_POINTEREVENTS_BOUNDINGBOX) strcpy(attValue, "boundingBox"); + if (intVal==SVG_POINTEREVENTS_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_POINTEREVENTS_VISIBLEPAINTED) return gf_strdup("visiblePainted"); + else if (intVal==SVG_POINTEREVENTS_VISIBLEFILL) return gf_strdup("visibleFill"); + else if (intVal==SVG_POINTEREVENTS_VISIBLESTROKE) return gf_strdup("visibleStroke"); + else if (intVal==SVG_POINTEREVENTS_VISIBLE) return gf_strdup("visible"); + else if (intVal==SVG_POINTEREVENTS_PAINTED) return gf_strdup("painted"); + else if (intVal==SVG_POINTEREVENTS_FILL) return gf_strdup("fill"); + else if (intVal==SVG_POINTEREVENTS_STROKE) return gf_strdup("stroke"); + else if (intVal==SVG_POINTEREVENTS_ALL) return gf_strdup("all"); + else if (intVal==SVG_POINTEREVENTS_NONE) return gf_strdup("none"); + else if (intVal==SVG_POINTEREVENTS_BOUNDINGBOX) return gf_strdup("boundingBox"); break; case SVG_RenderingHint_datatype: - if (intVal==SVG_RENDERINGHINT_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_RENDERINGHINT_AUTO) strcpy(attValue, "auto"); - else if (intVal==SVG_RENDERINGHINT_OPTIMIZEQUALITY) strcpy(attValue, "optimizeQuality"); - else if (intVal==SVG_RENDERINGHINT_OPTIMIZESPEED) strcpy(attValue, "optimizeSpeed"); - else if (intVal==SVG_RENDERINGHINT_OPTIMIZELEGIBILITY) strcpy(attValue, "optimizeLegibility"); - else if (intVal==SVG_RENDERINGHINT_CRISPEDGES) strcpy(attValue, "crispEdges"); - else if (intVal==SVG_RENDERINGHINT_GEOMETRICPRECISION) strcpy(attValue, "geometricPrecision"); + if (intVal==SVG_RENDERINGHINT_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_RENDERINGHINT_AUTO) return gf_strdup("auto"); + else if (intVal==SVG_RENDERINGHINT_OPTIMIZEQUALITY) return gf_strdup("optimizeQuality"); + else if (intVal==SVG_RENDERINGHINT_OPTIMIZESPEED) return gf_strdup("optimizeSpeed"); + else if (intVal==SVG_RENDERINGHINT_OPTIMIZELEGIBILITY) return gf_strdup("optimizeLegibility"); + else if (intVal==SVG_RENDERINGHINT_CRISPEDGES) return gf_strdup("crispEdges"); + else if (intVal==SVG_RENDERINGHINT_GEOMETRICPRECISION) return gf_strdup("geometricPrecision"); break; case SVG_VectorEffect_datatype: - if (intVal==SVG_VECTOREFFECT_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SVG_VECTOREFFECT_NONE) strcpy(attValue, "none"); - else if (intVal==SVG_VECTOREFFECT_NONSCALINGSTROKE) strcpy(attValue, "non-scaling-stroke"); + if (intVal==SVG_VECTOREFFECT_INHERIT) return gf_strdup("inherit"); + else if (intVal==SVG_VECTOREFFECT_NONE) return gf_strdup("none"); + else if (intVal==SVG_VECTOREFFECT_NONSCALINGSTROKE) return gf_strdup("non-scaling-stroke"); break; case SVG_PlaybackOrder_datatype: - if (intVal== SVG_PLAYBACKORDER_FORWARDONLY) strcpy(attValue, "forwardOnly"); - else if (intVal== SVG_PLAYBACKORDER_ALL) strcpy(attValue, "all"); + if (intVal== SVG_PLAYBACKORDER_FORWARDONLY) return gf_strdup("forwardOnly"); + else if (intVal== SVG_PLAYBACKORDER_ALL) return gf_strdup("all"); break; case SVG_TimelineBegin_datatype: - if (intVal== SVG_TIMELINEBEGIN_ONSTART) strcpy(attValue, "onStart"); - else if (intVal== SVG_TIMELINEBEGIN_ONLOAD) strcpy(attValue, "onLoad"); + if (intVal== SVG_TIMELINEBEGIN_ONSTART) return gf_strdup("onStart"); + else if (intVal== SVG_TIMELINEBEGIN_ONLOAD) return gf_strdup("onLoad"); break; case XML_Space_datatype: - if (intVal==XML_SPACE_DEFAULT) strcpy(attValue, "default"); - else if (intVal==XML_SPACE_PRESERVE) strcpy(attValue, "preserve"); + if (intVal==XML_SPACE_DEFAULT) return gf_strdup("default"); + else if (intVal==XML_SPACE_PRESERVE) return gf_strdup("preserve"); break; case XMLEV_Propagate_datatype: - if (intVal==XMLEVENT_PROPAGATE_CONTINUE) strcpy(attValue, "continue"); - else if (intVal==XMLEVENT_PROPAGATE_STOP) strcpy(attValue, "stop"); + if (intVal==XMLEVENT_PROPAGATE_CONTINUE) return gf_strdup("continue"); + else if (intVal==XMLEVENT_PROPAGATE_STOP) return gf_strdup("stop"); break; case XMLEV_DefaultAction_datatype: - if (intVal==XMLEVENT_DEFAULTACTION_CANCEL) strcpy(attValue, "cancel"); - else if (intVal==XMLEVENT_DEFAULTACTION_PERFORM) strcpy(attValue, "perform"); + if (intVal==XMLEVENT_DEFAULTACTION_CANCEL) return gf_strdup("cancel"); + else if (intVal==XMLEVENT_DEFAULTACTION_PERFORM) return gf_strdup("perform"); break; case XMLEV_Phase_datatype: - if (intVal==XMLEVENT_PHASE_DEFAULT) strcpy(attValue, "default"); - else if (intVal==XMLEVENT_PHASE_CAPTURE) strcpy(attValue, "capture"); + if (intVal==XMLEVENT_PHASE_DEFAULT) return gf_strdup("default"); + else if (intVal==XMLEVENT_PHASE_CAPTURE) return gf_strdup("capture"); break; case SMIL_SyncBehavior_datatype: - if (intVal==SMIL_SYNCBEHAVIOR_INHERIT) strcpy(attValue, "inherit"); - else if (intVal==SMIL_SYNCBEHAVIOR_DEFAULT) strcpy(attValue, "default"); - else if (intVal==SMIL_SYNCBEHAVIOR_LOCKED) strcpy(attValue, "locked"); - else if (intVal==SMIL_SYNCBEHAVIOR_CANSLIP) strcpy(attValue, "canSlip"); - else if (intVal==SMIL_SYNCBEHAVIOR_INDEPENDENT) strcpy(attValue, "independent"); + if (intVal==SMIL_SYNCBEHAVIOR_INHERIT) return gf_strdup("inherit"); + else if (intVal==SMIL_SYNCBEHAVIOR_DEFAULT) return gf_strdup("default"); + else if (intVal==SMIL_SYNCBEHAVIOR_LOCKED) return gf_strdup("locked"); + else if (intVal==SMIL_SYNCBEHAVIOR_CANSLIP) return gf_strdup("canSlip"); + else if (intVal==SMIL_SYNCBEHAVIOR_INDEPENDENT) return gf_strdup("independent"); break; case SMIL_SyncTolerance_datatype: - if (((SMIL_SyncTolerance*)info->far_ptr)->type==SMIL_SYNCTOLERANCE_INHERIT) strcpy(attValue, "inherit"); - else if (((SMIL_SyncTolerance*)info->far_ptr)->type==SMIL_SYNCTOLERANCE_DEFAULT) strcpy(attValue, "default"); + if (((SMIL_SyncTolerance*)info->far_ptr)->type==SMIL_SYNCTOLERANCE_INHERIT) return gf_strdup("inherit"); + else if (((SMIL_SyncTolerance*)info->far_ptr)->type==SMIL_SYNCTOLERANCE_DEFAULT) return gf_strdup("default"); else if (((SMIL_SyncTolerance*)info->far_ptr)->type==SMIL_SYNCBEHAVIOR_LOCKED) { - sprintf(attValue, "%g", ((SMIL_SyncTolerance*)info->far_ptr)->value); + sprintf(tmp, "%g", ((SMIL_SyncTolerance*)info->far_ptr)->value); + return gf_strdup(tmp); } break; case SMIL_AttributeType_datatype: - if (intVal==SMIL_ATTRIBUTETYPE_AUTO) strcpy(attValue, "auto"); - else if (intVal==SMIL_ATTRIBUTETYPE_XML) strcpy(attValue, "XML"); - else if (intVal==SMIL_ATTRIBUTETYPE_CSS) strcpy(attValue, "CSS"); - break; + if (intVal==SMIL_ATTRIBUTETYPE_AUTO) return gf_strdup("auto"); + else if (intVal==SMIL_ATTRIBUTETYPE_XML) return gf_strdup("XML"); + else if (intVal==SMIL_ATTRIBUTETYPE_CSS) return gf_strdup("CSS"); + break; case SMIL_CalcMode_datatype: - if (intVal==SMIL_CALCMODE_DISCRETE) strcpy(attValue, "discrete"); - else if (intVal==SMIL_CALCMODE_LINEAR) strcpy(attValue, "linear"); - else if (intVal==SMIL_CALCMODE_PACED) strcpy(attValue, "paced"); - else if (intVal==SMIL_CALCMODE_SPLINE) strcpy(attValue, "spline"); + if (intVal==SMIL_CALCMODE_DISCRETE) return gf_strdup("discrete"); + else if (intVal==SMIL_CALCMODE_LINEAR) return gf_strdup("linear"); + else if (intVal==SMIL_CALCMODE_PACED) return gf_strdup("paced"); + else if (intVal==SMIL_CALCMODE_SPLINE) return gf_strdup("spline"); break; case SMIL_Additive_datatype: - if (intVal==SMIL_ADDITIVE_REPLACE) strcpy(attValue, "replace"); - else if (intVal==SMIL_ADDITIVE_SUM) strcpy(attValue, "sum"); + if (intVal==SMIL_ADDITIVE_REPLACE) return gf_strdup("replace"); + else if (intVal==SMIL_ADDITIVE_SUM) return gf_strdup("sum"); break; case SMIL_Accumulate_datatype: - if (intVal==SMIL_ACCUMULATE_NONE) strcpy(attValue, "none"); - else if (intVal==SMIL_ACCUMULATE_SUM) strcpy(attValue, "sum"); + if (intVal==SMIL_ACCUMULATE_NONE) return gf_strdup("none"); + else if (intVal==SMIL_ACCUMULATE_SUM) return gf_strdup("sum"); break; case SMIL_Restart_datatype: - if (intVal==SMIL_RESTART_ALWAYS) strcpy(attValue, "always"); - else if (intVal==SMIL_RESTART_WHENNOTACTIVE) strcpy(attValue, "whenNotActive"); - else if (intVal==SMIL_RESTART_NEVER) strcpy(attValue, "never"); + if (intVal==SMIL_RESTART_ALWAYS) return gf_strdup("always"); + else if (intVal==SMIL_RESTART_WHENNOTACTIVE) return gf_strdup("whenNotActive"); + else if (intVal==SMIL_RESTART_NEVER) return gf_strdup("never"); break; case SMIL_Fill_datatype: - if (intVal==SMIL_FILL_FREEZE) strcpy(attValue, "freeze"); - else if (intVal==SMIL_FILL_REMOVE) strcpy(attValue, "remove"); + if (intVal==SMIL_FILL_FREEZE) return gf_strdup("freeze"); + else if (intVal==SMIL_FILL_REMOVE) return gf_strdup("remove"); break; case SVG_GradientUnit_datatype: - if (intVal==SVG_GRADIENTUNITS_USER) strcpy(attValue, "userSpaceOnUse"); - else if (intVal==SVG_GRADIENTUNITS_OBJECT) strcpy(attValue, "objectBoundingBox"); + if (intVal==SVG_GRADIENTUNITS_USER) return gf_strdup("userSpaceOnUse"); + else if (intVal==SVG_GRADIENTUNITS_OBJECT) return gf_strdup("objectBoundingBox"); break; case SVG_InitialVisibility_datatype: - if (intVal==SVG_INITIALVISIBILTY_WHENSTARTED) strcpy(attValue, "whenStarted"); - else if (intVal==SVG_INITIALVISIBILTY_ALWAYS) strcpy(attValue, "always"); + if (intVal==SVG_INITIALVISIBILTY_WHENSTARTED) return gf_strdup("whenStarted"); + else if (intVal==SVG_INITIALVISIBILTY_ALWAYS) return gf_strdup("always"); break; case SVG_FocusHighlight_datatype: - if (intVal==SVG_FOCUSHIGHLIGHT_AUTO) strcpy(attValue, "auto"); - else if (intVal==SVG_FOCUSHIGHLIGHT_NONE) strcpy(attValue, "none"); + if (intVal==SVG_FOCUSHIGHLIGHT_AUTO) return gf_strdup("auto"); + else if (intVal==SVG_FOCUSHIGHLIGHT_NONE) return gf_strdup("none"); break; case SVG_Overlay_datatype: - if (intVal==SVG_OVERLAY_NONE) strcpy(attValue, "none"); - else if (intVal==SVG_OVERLAY_TOP) strcpy(attValue, "top"); + if (intVal==SVG_OVERLAY_NONE) return gf_strdup("none"); + else if (intVal==SVG_OVERLAY_TOP) return gf_strdup("top"); break; case SVG_TransformBehavior_datatype: - if (intVal==SVG_TRANSFORMBEHAVIOR_GEOMETRIC) strcpy(attValue, "geometric"); - else if (intVal==SVG_TRANSFORMBEHAVIOR_PINNED) strcpy(attValue, "pinned"); - else if (intVal==SVG_TRANSFORMBEHAVIOR_PINNED90) strcpy(attValue, "pinned90"); - else if (intVal==SVG_TRANSFORMBEHAVIOR_PINNED180) strcpy(attValue, "pinned180"); - else if (intVal==SVG_TRANSFORMBEHAVIOR_PINNED270) strcpy(attValue, "pinned270"); + if (intVal==SVG_TRANSFORMBEHAVIOR_GEOMETRIC) return gf_strdup("geometric"); + else if (intVal==SVG_TRANSFORMBEHAVIOR_PINNED) return gf_strdup("pinned"); + else if (intVal==SVG_TRANSFORMBEHAVIOR_PINNED90) return gf_strdup("pinned90"); + else if (intVal==SVG_TRANSFORMBEHAVIOR_PINNED180) return gf_strdup("pinned180"); + else if (intVal==SVG_TRANSFORMBEHAVIOR_PINNED270) return gf_strdup("pinned270"); break; case SVG_SpreadMethod_datatype: - if (intVal==SVG_SPREAD_REFLECT) strcpy(attValue, "reflect"); - else if (intVal==SVG_SPREAD_REFLECT) strcpy(attValue, "repeat"); - else strcpy(attValue, "pad"); + if (intVal==SVG_SPREAD_REFLECT) return gf_strdup("reflect"); + else if (intVal==SVG_SPREAD_REFLECT) return gf_strdup("repeat"); + else return gf_strdup("pad"); + break; + + case SVG_Filter_TransferType_datatype: + if (intVal==SVG_FILTER_TRANSFER_TABLE) return gf_strdup("table"); + else if (intVal==SVG_FILTER_TRANSFER_DISCRETE) return gf_strdup("discrete"); + else if (intVal==SVG_FILTER_TRANSFER_LINEAR) return gf_strdup("linear"); + else if (intVal==SVG_FILTER_TRANSFER_GAMMA) return gf_strdup("gamma"); + else return gf_strdup("identity"); break; case LASeR_Choice_datatype: - if (intVal==LASeR_CHOICE_ALL) strcpy(attValue, "all"); - else if (intVal==LASeR_CHOICE_NONE) strcpy(attValue, "none"); + if (intVal==LASeR_CHOICE_ALL) return gf_strdup("all"); + else if (intVal==LASeR_CHOICE_NONE) return gf_strdup("none"); else if (intVal==LASeR_CHOICE_N) { - char szT[1000]; - sprintf(szT, "%d", ((LASeR_Choice *)info->far_ptr)->choice_index); - strcat(attValue, szT); + sprintf(tmp, "%d", ((LASeR_Choice *)info->far_ptr)->choice_index); + return gf_strdup(tmp); } break; case LASeR_Size_datatype: - { - char szT[1000]; - sprintf(szT, "%g %g", FIX2FLT(((LASeR_Size *)info->far_ptr)->width), FIX2FLT(((LASeR_Size *)info->far_ptr)->height)); - strcat(attValue, szT); - } - break; + sprintf(tmp, "%g %g", FIX2FLT(((LASeR_Size *)info->far_ptr)->width), FIX2FLT(((LASeR_Size *)info->far_ptr)->height)); + return gf_strdup(tmp); /* end of keyword type parsing */ /* inheritable floats */ @@ -3978,35 +4336,39 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) case SVG_Rotate_datatype: case SVG_Number_datatype: #if DUMP_COORDINATES - svg_dump_number((SVG_Number *)info->far_ptr, attValue); + return svg_dump_number((SVG_Number *)info->far_ptr); #endif - break; case XMLRI_datatype: - svg_dump_iri((XMLRI*)info->far_ptr, attValue); - break; + return svg_dump_iri((XMLRI*)info->far_ptr); case XML_IDREF_datatype: - svg_dump_idref((XMLRI*)info->far_ptr, attValue); - break; + return svg_dump_idref((XMLRI*)info->far_ptr); case XMLRI_List_datatype: { GF_List *l = *(GF_List **)info->far_ptr; u32 i, count = gf_list_count(l); + char *attVal = gf_malloc(sizeof(char)); + attVal[0] = 0; for (i=0; i<count; i++) { - char szT[1024]; + u32 len; + char *szT; XMLRI *iri = (XMLRI *)gf_list_get(l, i); - svg_dump_iri(iri, szT); - if (strlen(szT)) { - if (strlen(attValue)) strcat(attValue, " "); - strcat(attValue, szT); + szT = svg_dump_iri(iri); + len = strlen(szT); + if (len) { + attVal = gf_realloc(attVal, sizeof(char)*(len+strlen(attVal)+ (i ? 2 : 1) )); + if (i) strcat(attVal, " "); + strcat(attVal, szT); } + gf_free(szT); } + return attVal; } break; case SVG_PathData_datatype: #if DUMP_COORDINATES - svg_dump_path((SVG_PathData *)info->far_ptr, attValue); + return svg_dump_path((SVG_PathData *)info->far_ptr); #endif break; case SVG_Points_datatype: @@ -4015,13 +4377,17 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) GF_List *l = *(GF_List **) info->far_ptr; u32 i = 0; u32 count = gf_list_count(l); + char *attVal = gf_malloc(sizeof(char)); + attVal[0] = 0; for (i=0; i<count; i++) { - char szT[1000]; + char szT[200]; SVG_Point *p = (SVG_Point *)gf_list_get(l, i); sprintf(szT, "%g %g", FIX2FLT(p->x), FIX2FLT(p->y)); - if (i) strcat(attValue, " "); - strcat(attValue, szT); + attVal = gf_realloc(attVal, sizeof(char)*(strlen(szT)+strlen(attVal)+ (i ? 2 : 1) )); + if (i) strcat(attVal, " "); + strcat(attVal, szT); } + return attVal; #endif } break; @@ -4032,13 +4398,17 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) GF_List *l = *(GF_List **) info->far_ptr; u32 i = 0; u32 count = gf_list_count(l); + char *attVal = gf_malloc(sizeof(char)); + attVal[0] = 0; for (i=0; i<count; i++) { char szT[1000]; Fixed *p = (Fixed *)gf_list_get(l, i); sprintf(szT, "%g", FIX2FLT(*p)); - if (i) strcat(attValue, " "); - strcat(attValue, szT); + attVal = gf_realloc(attVal, sizeof(char)*(strlen(szT)+strlen(attVal)+ (i ? 2 : 1) )); + if (i) strcat(attVal, " "); + strcat(attVal, szT); } + return attVal; } break; case SVG_Coordinates_datatype: @@ -4047,121 +4417,146 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) GF_List *l = *(GF_List **) info->far_ptr; u32 i = 0; u32 count = gf_list_count(l); + char *attVal = gf_malloc(sizeof(char)); + attVal[0]=0; for (i=0; i<count; i++) { - char szT[1000]; + char *szT; SVG_Coordinate *p = (SVG_Coordinate *)gf_list_get(l, i); - svg_dump_number((SVG_Length *)p, szT); - if (strstr(szT, "pt")) { - fprintf(stderr, "found pt in output\n"); - } - if (i) strcat(attValue, " "); - strcat(attValue, szT); + szT = svg_dump_number((SVG_Length *)p); + attVal = gf_realloc(attVal, sizeof(char)*(strlen(szT)+strlen(attVal)+ (i ? 2 : 1) )); + if (i) strcat(attVal, " "); + strcat(attVal, szT); + gf_free(szT); } + return attVal; #endif } break; case SVG_ViewBox_datatype: { SVG_ViewBox *v = (SVG_ViewBox *)info->far_ptr; - if (v->is_set) - sprintf(attValue, "%g %g %g %g", FIX2FLT(v->x), FIX2FLT(v->y), FIX2FLT(v->width), FIX2FLT(v->height) ); - else - strcat(attValue, "none"); + if (v->is_set) { + sprintf(tmp, "%g %g %g %g", FIX2FLT(v->x), FIX2FLT(v->y), FIX2FLT(v->width), FIX2FLT(v->height) ); + return gf_strdup(tmp); + } else + return gf_strdup("none"); } break; case SVG_StrokeDashArray_datatype: { SVG_StrokeDashArray *p = (SVG_StrokeDashArray *)info->far_ptr; - if (p->type==SVG_STROKEDASHARRAY_NONE) strcpy(attValue, "none"); - else if (p->type==SVG_STROKEDASHARRAY_INHERIT) strcpy(attValue, "inherit"); + if (p->type==SVG_STROKEDASHARRAY_NONE) return gf_strdup("none"); + else if (p->type==SVG_STROKEDASHARRAY_INHERIT) return gf_strdup("inherit"); else if (p->type==SVG_STROKEDASHARRAY_ARRAY) { u32 i = 0; + char *attVal = gf_malloc(sizeof(char)); + attVal[0] = 0; for (i=0; i<p->array.count; i++) { - char szT[1000]; - sprintf(szT, "%g", FIX2FLT(p->array.vals[i])); - if (i) strcat(attValue, " "); - strcat(attValue, szT); + char *szT; + SVG_Length l; + l.type = p->array.units[i]; + l.value = p->array.vals[i]; + szT = svg_dump_number(&l); + attVal = gf_realloc(attVal, sizeof(char)*(strlen(szT)+strlen(attVal)+ (i ? 2 : 1) )); + if (i) strcat(attVal, " "); + strcat(attVal, szT); } + return attVal; } } break; case SVG_FontFamily_datatype: { SVG_FontFamily *f = (SVG_FontFamily *)info->far_ptr; - strcpy(attValue, (f->type==SVG_FONTFAMILY_INHERIT) ? "inherit" : (const char *) f->value); + return gf_strdup( (f->type==SVG_FONTFAMILY_INHERIT) ? "inherit" : (const char *) f->value); } - break; + case SVG_PreserveAspectRatio_datatype: { SVG_PreserveAspectRatio *par = (SVG_PreserveAspectRatio *)info->far_ptr; - if (par->defer) strcat(attValue, "defer "); - if (par->align == SVG_PRESERVEASPECTRATIO_NONE) strcat(attValue, "none"); - else if (par->align == SVG_PRESERVEASPECTRATIO_XMINYMIN) strcat(attValue, "xMinYMin"); - else if (par->align == SVG_PRESERVEASPECTRATIO_XMIDYMIN) strcat(attValue, "xMidYMin"); - else if (par->align == SVG_PRESERVEASPECTRATIO_XMAXYMIN) strcat(attValue, "xMaxYMin"); - else if (par->align == SVG_PRESERVEASPECTRATIO_XMINYMID) strcat(attValue, "xMinYMid"); - else if (par->align == SVG_PRESERVEASPECTRATIO_XMIDYMID) strcat(attValue, "xMidYMid"); - else if (par->align == SVG_PRESERVEASPECTRATIO_XMAXYMID) strcat(attValue, "xMaxYMid"); - else if (par->align == SVG_PRESERVEASPECTRATIO_XMINYMAX) strcat(attValue, "xMinYMax"); - else if (par->align == SVG_PRESERVEASPECTRATIO_XMIDYMAX) strcat(attValue, "xMidYMax"); - else if (par->align == SVG_PRESERVEASPECTRATIO_XMAXYMAX) strcat(attValue, "xMaxYMax"); - if (par->meetOrSlice== SVG_MEETORSLICE_SLICE) strcat(attValue, " slice"); + tmp[0] = 0; + if (par->defer) strcat(tmp, "defer "); + if (par->align == SVG_PRESERVEASPECTRATIO_NONE) strcat(tmp, "none"); + else if (par->align == SVG_PRESERVEASPECTRATIO_XMINYMIN) strcat(tmp, "xMinYMin"); + else if (par->align == SVG_PRESERVEASPECTRATIO_XMIDYMIN) strcat(tmp, "xMidYMin"); + else if (par->align == SVG_PRESERVEASPECTRATIO_XMAXYMIN) strcat(tmp, "xMaxYMin"); + else if (par->align == SVG_PRESERVEASPECTRATIO_XMINYMID) strcat(tmp, "xMinYMid"); + else if (par->align == SVG_PRESERVEASPECTRATIO_XMIDYMID) strcat(tmp, "xMidYMid"); + else if (par->align == SVG_PRESERVEASPECTRATIO_XMAXYMID) strcat(tmp, "xMaxYMid"); + else if (par->align == SVG_PRESERVEASPECTRATIO_XMINYMAX) strcat(tmp, "xMinYMax"); + else if (par->align == SVG_PRESERVEASPECTRATIO_XMIDYMAX) strcat(tmp, "xMidYMax"); + else if (par->align == SVG_PRESERVEASPECTRATIO_XMAXYMAX) strcat(tmp, "xMaxYMax"); + if (par->meetOrSlice== SVG_MEETORSLICE_SLICE) strcat(tmp, " slice"); + + return gf_strdup(tmp); } - break; + case SVG_Clock_datatype: - sprintf(attValue, "%g", * (SVG_Clock *)info->far_ptr ); - break; + sprintf(tmp, "%g", * (SVG_Clock *)info->far_ptr ); + return gf_strdup(tmp); case SVG_ID_datatype: case SVG_LanguageID_datatype: case SVG_GradientOffset_datatype: case DOM_String_datatype: case SVG_ContentType_datatype: - if (*(SVG_String *)info->far_ptr) - strcpy(attValue, *(SVG_String *)info->far_ptr ); + if (*(SVG_String *)info->far_ptr) + return gf_strdup( *(SVG_String *)info->far_ptr ); break; + case SVG_Focus_datatype: { SVG_Focus *foc = (SVG_Focus *)info->far_ptr; - if (foc->type==SVG_FOCUS_SELF) strcpy(attValue, "self"); - else if (foc->type==SVG_FOCUS_AUTO) strcpy(attValue, "auto"); - else sprintf(attValue, "#%s", foc->target.string); + if (foc->type==SVG_FOCUS_SELF) return gf_strdup("self"); + else if (foc->type==SVG_FOCUS_AUTO) return gf_strdup("auto"); + else { + sprintf(tmp, "#%s", foc->target.string); + return gf_strdup(tmp); + } } break; case SVG_Focusable_datatype: { SVG_Focusable *f = (SVG_Focusable *)info->far_ptr; - if (*f == SVG_FOCUSABLE_TRUE) strcpy(attValue, "true"); - else if (*f == SVG_FOCUSABLE_FALSE) strcpy(attValue, "false"); - else strcpy(attValue, "auto"); + if (*f == SVG_FOCUSABLE_TRUE) return gf_strdup("true"); + else if (*f == SVG_FOCUSABLE_FALSE) return gf_strdup("false"); + else return gf_strdup("auto"); } - break; case DOM_StringList_datatype: { GF_List *l1 = *(GF_List **) info->far_ptr; u32 i = 0; u32 count = gf_list_count(l1); + char *attVal = gf_malloc(sizeof(char)); + attVal[0] = 0; for (i=0; i<count; i++) { char *p1 = (char *)gf_list_get(l1, i); - if (strlen(attValue)) strcat(attValue, " "); - strcat(attValue, p1); + attVal = gf_realloc(attVal, sizeof(char)*(strlen(p1)+strlen(attVal)+ (i ? 2 : 1) )); + if (i) strcat(attVal, " "); + strcat(attVal, p1); } + return attVal; } - break; + case SVG_Numbers_datatype: { #if DUMP_COORDINATES GF_List *l1 = *(GF_List **) info->far_ptr; u32 i = 0; u32 count = gf_list_count(l1); + char *attVal = gf_malloc(sizeof(char)); + attVal[0]=0; for (i=0; i<count; i++) { - char szT[1024]; + char *szT; SVG_Number *p = (SVG_Number *)gf_list_get(l1, i); - svg_dump_number(p, attValue); - if (i) strcat(attValue, " "); - strcat(attValue, szT); + szT = svg_dump_number(p); + attVal = gf_realloc(attVal, sizeof(char)*(strlen(szT)+strlen(attVal)+ (i ? 2 : 1) )); + if (i) strcat(attVal, " "); + strcat(attVal, szT); + gf_free(szT); } + return attVal; #endif } break; @@ -4170,7 +4565,8 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) { #if DUMP_COORDINATES GF_Matrix2D *m = (GF_Matrix2D *)info->far_ptr; - sprintf(attValue, "%g %g", FIX2FLT(m->m[2]), FIX2FLT(m->m[5])); + sprintf(tmp, "%g %g", FIX2FLT(m->m[2]), FIX2FLT(m->m[5])); + return gf_strdup(tmp); #endif } break; @@ -4179,9 +4575,10 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) { SVG_Transform *t= (SVG_Transform *)info->far_ptr; if (t->is_ref) { - sprintf(attValue, "ref(svg,%g,%g)", FIX2FLT(t->mat.m[2]), FIX2FLT(t->mat.m[5]) ); + sprintf(tmp, "ref(svg,%g,%g)", FIX2FLT(t->mat.m[2]), FIX2FLT(t->mat.m[5]) ); + return gf_strdup(tmp); } else { - gf_svg_dump_matrix(&t->mat, attValue); + return gf_svg_dump_matrix(&t->mat); } } break; @@ -4190,7 +4587,8 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) { SVG_Point *pt = (SVG_Point *)info->far_ptr; #if DUMP_COORDINATES - sprintf(attValue, "%g %g", FIX2FLT(pt->x), FIX2FLT(pt->y) ); + sprintf(tmp, "%g %g", FIX2FLT(pt->x), FIX2FLT(pt->y) ); + return gf_strdup(tmp); #endif } break; @@ -4200,10 +4598,11 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) SVG_Point *pt = (SVG_Point *)info->far_ptr; #if DUMP_COORDINATES if (pt->x == pt->y) { - sprintf(attValue, "%g", FIX2FLT(pt->x)); + sprintf(tmp, "%g", FIX2FLT(pt->x)); } else { - sprintf(attValue, "%g %g", FIX2FLT(pt->x), FIX2FLT(pt->y) ); + sprintf(tmp, "%g %g", FIX2FLT(pt->x), FIX2FLT(pt->y) ); } + return gf_strdup(tmp); #endif } break; @@ -4213,7 +4612,8 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) { Fixed *f = (Fixed *)info->far_ptr; #if DUMP_COORDINATES - sprintf(attValue, "%g", FIX2FLT( 180 * gf_divfix(*f, GF_PI) )); + sprintf(tmp, "%g", FIX2FLT( 180 * gf_divfix(*f, GF_PI) )); + return gf_strdup(tmp); #endif } break; @@ -4223,10 +4623,11 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) SVG_Point_Angle *pt = (SVG_Point_Angle *)info->far_ptr; #if DUMP_COORDINATES if (pt->x || pt->y) { - sprintf(attValue, "%g %g %g", FIX2FLT( 180 * gf_divfix(pt->angle, GF_PI) ), FIX2FLT(pt->x), FIX2FLT(pt->y) ); + sprintf(tmp, "%g %g %g", FIX2FLT( 180 * gf_divfix(pt->angle, GF_PI) ), FIX2FLT(pt->x), FIX2FLT(pt->y) ); } else { - sprintf(attValue, "%g", FIX2FLT(gf_divfix(180 * pt->angle, GF_PI) )); + sprintf(tmp, "%g", FIX2FLT(gf_divfix(180 * pt->angle, GF_PI) )); } + return gf_strdup(tmp); #endif } break; @@ -4234,48 +4635,30 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) case SMIL_AttributeName_datatype: { SMIL_AttributeName *att_name = (SMIL_AttributeName *) info->far_ptr; - if (att_name->name) { - strcpy(attValue, att_name->name); - return GF_OK; - } - if (att_name->tag) { - strcpy(attValue, gf_svg_get_attribute_name(elt, att_name->tag)); - return GF_OK; - } + if (att_name->name) + return gf_strdup(att_name->name); -#if 0 - GF_Node *t=NULL; - u32 i, count; - if (!elt->xlink) break; - t = (GF_Node *) elt->xlink->href.target; - if (!t) break; - count = gf_node_get_field_count(t); - for (i=0; i<count; i++) { - GF_FieldInfo fi; - gf_node_get_field(t, i, &fi); - if (fi.far_ptr == att_name->field_ptr) { - sprintf(attValue, fi.name); - return GF_OK; - } - } -#endif + if (att_name->tag) + return gf_strdup( gf_svg_get_attribute_name(elt, att_name->tag) ); } break; + case SMIL_Times_datatype: { u32 i, count; GF_Node *par = gf_node_get_parent((GF_Node *)elt, 0); GF_List *l = *(GF_List **) info->far_ptr; + char *attVal = gf_malloc(sizeof(char)); + attVal[0] = 0; count = gf_list_count(l); for (i=0; i<count; i++) { char szBuf[1000]; SMIL_Time *t = (SMIL_Time *)gf_list_get(l, i); - if (i) strcat(attValue, ";"); + szBuf[0] = 0; if (t->type == GF_SMIL_TIME_CLOCK) { sprintf(szBuf, "%gs", t->clock); - strcat(attValue, szBuf); } else if (t->type==GF_SMIL_TIME_INDEFINITE) { - strcat(attValue, "indefinite"); + strcpy(szBuf, "indefinite"); } else if (t->type==GF_SMIL_TIME_WALLCLOCK) { u32 h, m, s; /*TODO - day month and year*/ @@ -4283,44 +4666,49 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) m = (u32) (t->clock * 60 - 60*h); s = (u32) (t->clock - 3600*h - 60*m); sprintf(szBuf, "wallclock(%d:%d:%d)", h, m, s); - strcat(attValue, szBuf); } else if (t->type==GF_SMIL_TIME_EVENT) { if (t->event.type == GF_EVENT_KEYDOWN) { svg_dump_access_key(&t->event, szBuf); - strcat(attValue, szBuf); } else { if (t->element_id) { - strcat(attValue, t->element_id); - strcat(attValue, "."); + strcpy(szBuf, t->element_id); + strcat(szBuf, "."); } else if (t->element && (t->element!=par) && gf_node_get_id(t->element) ) { const char *name = gf_node_get_name(t->element); if (name) { - strcat(attValue, name); + strcpy(szBuf, name); } else { sprintf(szBuf, "N%d", gf_node_get_id(t->element)-1 ); - strcat(attValue, szBuf); } - strcat(attValue, "."); + strcat(szBuf, "."); } - strcat(attValue, gf_dom_event_get_name(t->event.type)); + strcat(szBuf, gf_dom_event_get_name(t->event.type)); } if (t->clock) { - sprintf(szBuf, "%gs", t->clock); - strcat(attValue, "+"); - strcat(attValue, szBuf); + char szCk[40]; + sprintf(szCk, "+%gs", t->clock); + strcat(szBuf, szCk); } } + if (szBuf[0]) { + attVal = gf_realloc(attVal, sizeof(char)*(strlen(attVal)+strlen(szBuf)+ (i ? 2 : 1) )); + if ( strlen(attVal) ) strcat(attVal, ";"); + strcat(attVal, szBuf); + } } + return attVal; } break; case SMIL_Duration_datatype: { SMIL_Duration *dur = (SMIL_Duration *)info->far_ptr; - if (dur->type == SMIL_DURATION_INDEFINITE) strcpy(attValue, "indefinite"); - else if (dur->type == SMIL_DURATION_MEDIA) strcpy(attValue, "media"); - else if (dur->type == SMIL_DURATION_DEFINED) sprintf(attValue, "%gs", dur->clock_value); - else { + if (dur->type == SMIL_DURATION_INDEFINITE) return gf_strdup("indefinite"); + else if (dur->type == SMIL_DURATION_MEDIA) return gf_strdup("media"); + else if (dur->type == SMIL_DURATION_DEFINED) { + sprintf(tmp, "%gs", dur->clock_value); + return gf_strdup(tmp); + } else { GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG Dumping] smil duration not assigned\n")); } } @@ -4328,8 +4716,11 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) case SMIL_RepeatCount_datatype: { SMIL_RepeatCount *rep = (SMIL_RepeatCount *)info->far_ptr; - if (rep->type == SMIL_REPEATCOUNT_INDEFINITE) strcpy(attValue, "indefinite"); - else if (rep->type == SMIL_REPEATCOUNT_DEFINED) sprintf(attValue, "%g", FIX2FLT(rep->count) ); + if (rep->type == SMIL_REPEATCOUNT_INDEFINITE) return gf_strdup("indefinite"); + else if (rep->type == SMIL_REPEATCOUNT_DEFINED) { + sprintf(tmp, "%g", FIX2FLT(rep->count) ); + return gf_strdup(tmp); + } else { GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG Dumping] smil repeat count not assigned\n")); } @@ -4338,12 +4729,12 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) case SVG_TransformType_datatype: { SVG_TransformType tr = *(SVG_TransformType *)info->far_ptr; - if (tr == SVG_TRANSFORM_MATRIX) strcpy(attValue, "matrix"); - else if (tr == SVG_TRANSFORM_SCALE) strcpy(attValue, "scale"); - else if (tr == SVG_TRANSFORM_ROTATE) strcpy(attValue, "rotate"); - else if (tr == SVG_TRANSFORM_TRANSLATE) strcpy(attValue, "translate"); - else if (tr == SVG_TRANSFORM_SKEWX) strcpy(attValue, "skewX"); - else if (tr == SVG_TRANSFORM_SKEWY) strcpy(attValue, "skewY"); + if (tr == SVG_TRANSFORM_MATRIX) return gf_strdup("matrix"); + else if (tr == SVG_TRANSFORM_SCALE) return gf_strdup("scale"); + else if (tr == SVG_TRANSFORM_ROTATE) return gf_strdup("rotate"); + else if (tr == SVG_TRANSFORM_TRANSLATE) return gf_strdup("translate"); + else if (tr == SVG_TRANSFORM_SKEWX) return gf_strdup("skewX"); + else if (tr == SVG_TRANSFORM_SKEWY) return gf_strdup("skewY"); } break; @@ -4355,7 +4746,7 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) a_fi.fieldType = av->type; a_fi.name = info->name; a_fi.far_ptr = av->value; - gf_svg_dump_attribute(elt, &a_fi, attValue); + return gf_svg_dump_attribute(elt, &a_fi); } break; case SMIL_AnimateValues_datatype: @@ -4363,54 +4754,60 @@ GF_Err gf_svg_dump_attribute(GF_Node *elt, GF_FieldInfo *info, char *attValue) GF_FieldInfo a_fi; u32 i, count; SMIL_AnimateValues *av = (SMIL_AnimateValues*)info->far_ptr; + char *attVal = gf_malloc(sizeof(char)); + attVal[0] = 0; if (av->type) { count = gf_list_count(av->values); a_fi.fieldIndex = 0; a_fi.fieldType = av->type; a_fi.name = info->name; for (i=0; i<count; i++) { - char szBuf[1024]; + char *szBuf; a_fi.far_ptr = gf_list_get(av->values, i); - gf_svg_dump_attribute(elt, &a_fi, szBuf); - if (i) strcat(attValue, ";"); - strcat(attValue, szBuf); + szBuf = gf_svg_dump_attribute(elt, &a_fi); + + attVal = gf_realloc(attVal, sizeof(char)*(strlen(attVal)+strlen(szBuf)+ (i ? 2 : 1) )); + if (i) strcat(attVal, ";"); + strcat(attVal, szBuf); + gf_free(szBuf); } } + return attVal; } - break; case XMLEV_Event_datatype: { XMLEV_Event *d = (XMLEV_Event *)info->far_ptr; if (d->parameter) { - svg_dump_access_key(d, attValue); + svg_dump_access_key(d, tmp); } else { - strcpy(attValue, gf_dom_event_get_name(d->type)); + strcpy(tmp, gf_dom_event_get_name(d->type)); } - break; + return gf_strdup(tmp); } default: GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG Dumping] field %s of type %s not supported\n", info->name, gf_svg_attribute_type_to_string(info->fieldType))); break; } - return GF_OK; + return gf_strdup(""); } -GF_Err gf_svg_dump_attribute_indexed(GF_Node *elt, GF_FieldInfo *info, char *attValue) +char *gf_svg_dump_attribute_indexed(GF_Node *elt, GF_FieldInfo *info) { - strcpy(attValue, ""); + char tmp[1024]; + switch (info->fieldType) { case SVG_PointerEvents_datatype: break; case XMLRI_List_datatype: - strcpy(attValue, (char *) info->far_ptr); - break; + return gf_strdup( (char *) info->far_ptr); case SVG_Points_datatype: { #if DUMP_COORDINATES SVG_Point *p = (SVG_Point *)info->far_ptr; - sprintf(attValue, "%g %g", FIX2FLT(p->x), FIX2FLT(p->y)); + sprintf(tmp, "%g %g", FIX2FLT(p->x), FIX2FLT(p->y)); + return gf_strdup(tmp); #endif } break; @@ -4419,92 +4816,90 @@ GF_Err gf_svg_dump_attribute_indexed(GF_Node *elt, GF_FieldInfo *info, char *att case SMIL_KeySplines_datatype: { Fixed *p = (Fixed *)info->far_ptr; - sprintf(attValue, "%g", FIX2FLT(*p)); + sprintf(tmp, "%g", FIX2FLT(*p)); + return gf_strdup(tmp); } break; case SVG_Coordinates_datatype: - { #if DUMP_COORDINATES - SVG_Coordinate *p = (SVG_Coordinate *)info->far_ptr; - svg_dump_number((SVG_Length *)p, attValue); - if (strstr(attValue, "pt")) { - fprintf(stderr, "found pt in output\n"); - } + return svg_dump_number((SVG_Length *) (SVG_Coordinate *)info->far_ptr); #endif - } break; case SVG_ViewBox_datatype: { Fixed *v = (Fixed *)info->far_ptr; - sprintf(attValue, "%g", FIX2FLT(*v)); + sprintf(tmp, "%g", FIX2FLT(*v)); + return gf_strdup(tmp); } break; case SVG_StrokeDashArray_datatype: { + /*TODO: fix this: should be an SVG_Length*/ Fixed *p = (Fixed *)info->far_ptr; - sprintf(attValue, "%g", FIX2FLT(*p)); + sprintf(tmp, "%g", FIX2FLT(*p)); + return gf_strdup(tmp); } break; case SMIL_Times_datatype: { SMIL_Time *t = (SMIL_Time *)info->far_ptr; if (t->type == GF_SMIL_TIME_CLOCK) { - sprintf(attValue, "%gs", t->clock); + sprintf(tmp, "%gs", t->clock); } else if (t->type==GF_SMIL_TIME_INDEFINITE) { - strcpy(attValue, "indefinite"); + strcpy(tmp, "indefinite"); } else if (t->type==GF_SMIL_TIME_WALLCLOCK) { u32 h, m, s; /*TODO - day month and year*/ h = (u32) t->clock * 3600; m = (u32) (t->clock * 60 - 60*h); s = (u32) (t->clock - 3600*h - 60*m); - sprintf(attValue, "wallclock(%d:%d:%d)", h, m, s); + sprintf(tmp, "wallclock(%d:%d:%d)", h, m, s); } else if (t->type==GF_SMIL_TIME_EVENT) { GF_Node *par = gf_node_get_parent((GF_Node *)elt, 0); if (t->event.type == GF_EVENT_KEYDOWN) { - svg_dump_access_key(&t->event, attValue); + svg_dump_access_key(&t->event, tmp); } else { - strcpy(attValue, ""); + strcpy(tmp, ""); if (t->element_id) { - strcat(attValue, t->element_id); - strcat(attValue, "."); + strcat(tmp, t->element_id); + strcat(tmp, "."); } else if (t->element && (t->element!=par) && gf_node_get_id(t->element) ) { const char *name = gf_node_get_name(t->element); if (name) { - strcat(attValue, name); + strcat(tmp, name); } else { - sprintf(attValue, "N%d", gf_node_get_id(t->element)-1 ); + sprintf(tmp, "N%d", gf_node_get_id(t->element)-1 ); } - strcat(attValue, "."); + strcat(tmp, "."); } - strcat(attValue, gf_dom_event_get_name(t->event.type)); + strcat(tmp, gf_dom_event_get_name(t->event.type)); } if (t->clock) { char szBuf[100]; - sprintf(szBuf, "%gs", t->clock); - strcpy(attValue, "+"); - strcat(attValue, szBuf); + sprintf(szBuf, "+%gs", t->clock); + strcat(tmp, szBuf); } } + return gf_strdup(tmp); } - break; + default: GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[SVG Dumping] indexed field %s of type %s not supported\n", info->name, gf_svg_attribute_type_to_string(info->fieldType))); break; } - return GF_OK; + return gf_strdup(""); } static Bool svg_viewbox_equal(SVG_ViewBox *v1, SVG_ViewBox *v2) { if (v1->is_set != v2->is_set) return 0; - if (!v1->is_set) + if (!v1->is_set) return 1; else { if ( (v1->x == v2->x) && (v1->y == v2->y) && (v1->width == v2->width) && (v1->height == v2->height) ) return 1; - else + else return 0; } } @@ -4558,7 +4953,7 @@ Bool gf_svg_attributes_equal(GF_FieldInfo *f1, GF_FieldInfo *f2) if (f1->fieldType!=f2->fieldType) return 0; if (f1->far_ptr && !f2->far_ptr) return 0; if (f2->far_ptr && !f1->far_ptr) return 0; - if (!f1->far_ptr) return 1; + if (!f1->far_ptr) return 1; v1 = *(u8 *)f1->far_ptr; v2 = *(u8 *)f2->far_ptr; @@ -4730,6 +5125,7 @@ Bool gf_svg_attributes_equal(GF_FieldInfo *f1, GF_FieldInfo *f2) u32 i = 0; if (p1->array.count != p2->array.count) return 0; for (i=0; i<p1->array.count; i++) { + if (p1->array.units[i] != p2->array.units[i]) return 0; if (p1->array.vals[i] != p2->array.vals[i]) return 0; } } @@ -4757,7 +5153,7 @@ Bool gf_svg_attributes_equal(GF_FieldInfo *f1, GF_FieldInfo *f2) SVG_Transform *t2 = (SVG_Transform *)f2->far_ptr; if (t1->is_ref == t2->is_ref) return svg_matrices_equal(&t1->mat, &t2->mat); - else + else return 0; } @@ -4995,7 +5391,7 @@ static GF_Err svg_points_muladd(Fixed alpha, SVG_Points *a, Fixed beta, SVG_Poin while (gf_list_count(*c)) { SVG_Point *ptc = (SVG_Point *)gf_list_get(*c, 0); gf_list_rem(*c, 0); - free(ptc); + gf_free(ptc); } for (i = 0; i < a_count; i ++) { SVG_Point *ptc; @@ -5016,10 +5412,10 @@ static GF_Err svg_points_copy(SVG_Points *a, SVG_Points *b) count = gf_list_count(*a); for (i = 0; i < count; i++) { SVG_Point *pt = (SVG_Point *)gf_list_get(*a, i); - free(pt); + gf_free(pt); } gf_list_reset(*a); - + count = gf_list_count(*b); for (i = 0; i < count; i ++) { SVG_Point *ptb = (SVG_Point *)gf_list_get(*b, i); @@ -5058,10 +5454,10 @@ static GF_Err svg_numbers_copy(SVG_Numbers *a, SVG_Numbers *b) count = gf_list_count(*a); for (i = 0; i < count; i++) { SVG_Coordinate *c = (SVG_Coordinate *)gf_list_get(*a, i); - free(c); + gf_free(c); } gf_list_reset(*a); - + count = gf_list_count(*b); for (i = 0; i < count; i ++) { SVG_Number *na; @@ -5075,13 +5471,13 @@ static GF_Err svg_numbers_copy(SVG_Numbers *a, SVG_Numbers *b) #if USE_GF_PATH static GF_Err svg_path_copy(SVG_PathData *a, SVG_PathData *b) { - if (a->contours) free(a->contours); - if (a->points) free(a->points); - if (a->tags) free(a->tags); + if (a->contours) gf_free(a->contours); + if (a->points) gf_free(a->points); + if (a->tags) gf_free(a->tags); - a->contours = (u32 *)malloc(sizeof(u32)*b->n_contours); - a->points = (GF_Point2D *) malloc(sizeof(GF_Point2D)*b->n_points); - a->tags = (u8 *) malloc(sizeof(u8)*b->n_points); + a->contours = (u32 *)gf_malloc(sizeof(u32)*b->n_contours); + a->points = (GF_Point2D *) gf_malloc(sizeof(GF_Point2D)*b->n_points); + a->tags = (u8 *) gf_malloc(sizeof(u8)*b->n_points); memcpy(a->contours, b->contours, sizeof(u32)*b->n_contours); a->n_contours = b->n_contours; memcpy(a->points, b->points, sizeof(GF_Point2D)*b->n_points); @@ -5099,19 +5495,19 @@ static GF_Err svg_path_copy(SVG_PathData *a, SVG_PathData *b) count = gf_list_count(a->commands); for (i = 0; i < count; i++) { u8 *command = (u8 *)gf_list_get(a->commands, i); - free(command); + gf_free(command); } gf_list_reset(a->commands); count = gf_list_count(a->points); for (i = 0; i < count; i++) { SVG_Point *pt = (SVG_Point *)gf_list_get(a->points, i); - free(pt); + gf_free(pt); } gf_list_reset(a->points); - + count = gf_list_count(b->commands); for (i = 0; i < count; i ++) { - u8 *nc = (u8 *)malloc(sizeof(u8)); + u8 *nc = (u8 *)gf_malloc(sizeof(u8)); *nc = *(u8*)gf_list_get(b->commands, i); gf_list_add(a->commands, nc); } @@ -5163,17 +5559,17 @@ static GF_Err svg_path_muladd(Fixed alpha, SVG_PathData *a, Fixed beta, SVG_Path while (gf_list_count(c->commands)) { u8 *command = (u8 *)gf_list_last(c->commands); - free(command); + gf_free(command); gf_list_rem_last(c->commands); } while (gf_list_count(c->points)) { SVG_Point *pt = (SVG_Point *)gf_list_last(c->points); - free(pt); + gf_free(pt); gf_list_rem_last(c->points); } - + for (i = 0; i < ccount; i++) { - u8 *nc = (u8 *)malloc(sizeof(u8)); + u8 *nc = (u8 *)gf_malloc(sizeof(u8)); *nc = *(u8*)gf_list_get(a->commands, i); gf_list_add(c->commands, nc); } @@ -5198,8 +5594,10 @@ static GF_Err svg_dasharray_muladd(Fixed alpha, SVG_StrokeDashArray *a, Fixed be c->type = a->type; c->array.count = a->array.count; - c->array.vals = (Fixed *) malloc(sizeof(Fixed)*c->array.count); + c->array.vals = (Fixed *) gf_malloc(sizeof(Fixed)*c->array.count); for (i = 0; i < c->array.count; i++) { + /* TODO: convert units if needed */ + c->array.units[i] = a->array.units[i]; c->array.vals[i] = gf_mulfix(alpha, a->array.vals[i]) + gf_mulfix(beta, b->array.vals[i]); } return GF_OK; @@ -5209,7 +5607,9 @@ static GF_Err svg_dasharray_copy(SVG_StrokeDashArray *a, SVG_StrokeDashArray *b) { a->type = b->type; a->array.count = b->array.count; - a->array.vals = (Fixed*)malloc(sizeof(Fixed)*a->array.count); + a->array.units = (u8*)gf_malloc(sizeof(u8)*a->array.count); + memcpy(a->array.units, b->array.units, sizeof(u8)*a->array.count); + a->array.vals = (Fixed*)gf_malloc(sizeof(Fixed)*a->array.count); memcpy(a->array.vals, b->array.vals, sizeof(Fixed)*a->array.count); return GF_OK; } @@ -5224,7 +5624,7 @@ static GF_Err svg_matrix_muladd(Fixed alpha, GF_Matrix2D *a, Fixed beta, GF_Matr gf_mx2d_copy(*c, tmp); } else */ if (alpha <= FIX_ONE) { - /* This case should happen only when using animateMotion and accumulation + /* This case should happen only when using animateMotion and accumulation see animate-elem-202-t.svg we only add and multiply the translation component; */ /* @@ -5254,9 +5654,9 @@ static GF_Err laser_size_muladd(Fixed alpha, LASeR_Size *sza, Fixed beta, LASeR_ } /* c = alpha * a + beta * b */ -GF_Err gf_svg_attributes_muladd(Fixed alpha, GF_FieldInfo *a, - Fixed beta, GF_FieldInfo *b, - GF_FieldInfo *c, +GF_Err gf_svg_attributes_muladd(Fixed alpha, GF_FieldInfo *a, + Fixed beta, GF_FieldInfo *b, + GF_FieldInfo *c, Bool clamp) { if (!a->far_ptr || !b->far_ptr || !c->far_ptr) return GF_BAD_PARAM; @@ -5333,10 +5733,13 @@ GF_Err gf_svg_attributes_muladd(Fixed alpha, GF_FieldInfo *a, } else { /* a and c are matrices but b is not */ GF_Matrix2D tmp; + /*TOCHECK what is this test*/ +/* if (alpha != FIX_ONE) { GF_LOG(GF_LOG_ERROR, GF_LOG_INTERACT, ("[SVG Attributes] matrix operations not supported\n")); return GF_NOT_SUPPORTED; } +*/ gf_mx2d_init(tmp); switch (b->fieldType) { case SVG_Transform_Translate_datatype: @@ -5374,8 +5777,8 @@ GF_Err gf_svg_attributes_muladd(Fixed alpha, GF_FieldInfo *a, case SVG_Transform_Scale_datatype: if (b->fieldType == SVG_Transform_Scale_datatype) { if (alpha == FIX_ONE && beta == FIX_ONE) { - /* addition of matrices which represent scales is equivalent - to multiplication of scale coefficients, we assume this only happens if + /* addition of matrices which represent scales is equivalent + to multiplication of scale coefficients, we assume this only happens if alpha and beta are set to one */ ((SVG_Point*)c->far_ptr)->x = gf_mulfix(((SVG_Point*)a->far_ptr)->x,((SVG_Point*)b->far_ptr)->x); ((SVG_Point*)c->far_ptr)->y = gf_mulfix(((SVG_Point*)a->far_ptr)->y,((SVG_Point*)b->far_ptr)->y); @@ -5425,12 +5828,12 @@ GF_Err gf_svg_attributes_muladd(Fixed alpha, GF_FieldInfo *a, len_a = FIX2INT(alpha * len_a); len_b = FIX2INT(beta * len_b); len = len_a + len_b + 1; - res = (char*)malloc(sizeof(char) * len); + res = (char*)gf_malloc(sizeof(char) * len); memcpy(res, *s_a, len_a); memcpy(res+len_a, *s_b, len_b); res[len-1] = 0; s_a = (SVG_String*)c->far_ptr; - if (*s_a) free(*s_a); + if (*s_a) gf_free(*s_a); *s_a = res; } break; @@ -5590,7 +5993,7 @@ GF_Err gf_svg_attributes_copy(GF_FieldInfo *a, GF_FieldInfo *b, Bool clamp) return GF_NOT_SUPPORTED; } return GF_OK; - + /* Keyword types */ case SVG_Boolean_datatype: case SVG_FillRule_datatype: @@ -5638,24 +6041,24 @@ GF_Err gf_svg_attributes_copy(GF_FieldInfo *a, GF_FieldInfo *b, Bool clamp) case SVG_LanguageID_datatype: case SVG_ContentType_datatype: case DOM_String_datatype: - if (* (SVG_String *)a->far_ptr) free(* (SVG_String *)a->far_ptr); - * (SVG_String *)a->far_ptr = strdup(*(SVG_String *)b->far_ptr); + if (* (SVG_String *)a->far_ptr) gf_free(* (SVG_String *)a->far_ptr); + * (SVG_String *)a->far_ptr = gf_strdup(*(SVG_String *)b->far_ptr); return GF_OK; case SVG_FontFamily_datatype: ((SVG_FontFamily *)a->far_ptr)->type = ((SVG_FontFamily *)b->far_ptr)->type; - if ( ((SVG_FontFamily *)a->far_ptr)->value) free( ((SVG_FontFamily *)a->far_ptr)->value ); - ((SVG_FontFamily *)a->far_ptr)->value = (((SVG_FontFamily *)b->far_ptr)->value ? strdup(((SVG_FontFamily *)b->far_ptr)->value) : NULL ); + if ( ((SVG_FontFamily *)a->far_ptr)->value) gf_free( ((SVG_FontFamily *)a->far_ptr)->value ); + ((SVG_FontFamily *)a->far_ptr)->value = (((SVG_FontFamily *)b->far_ptr)->value ? gf_strdup(((SVG_FontFamily *)b->far_ptr)->value) : NULL ); return GF_OK; case XMLRI_datatype: case XML_IDREF_datatype: ((XMLRI *)a->far_ptr)->type = ((XMLRI *)b->far_ptr)->type; - if (((XMLRI *)a->far_ptr)->string) free(((XMLRI *)a->far_ptr)->string); + if (((XMLRI *)a->far_ptr)->string) gf_free(((XMLRI *)a->far_ptr)->string); if (((XMLRI *)b->far_ptr)->string) { - ((XMLRI *)a->far_ptr)->string = strdup(((XMLRI *)b->far_ptr)->string); + ((XMLRI *)a->far_ptr)->string = gf_strdup(((XMLRI *)b->far_ptr)->string); } else { - ((XMLRI *)a->far_ptr)->string = strdup(""); + ((XMLRI *)a->far_ptr)->string = gf_strdup(""); } ((XMLRI *)a->far_ptr)->target = ((XMLRI *)b->far_ptr)->target; if (((XMLRI *)a->far_ptr)->type == XMLRI_ELEMENTID) { @@ -5664,12 +6067,12 @@ GF_Err gf_svg_attributes_copy(GF_FieldInfo *a, GF_FieldInfo *b, Bool clamp) if (n) gf_node_register_iri(gf_node_get_graph(n), (XMLRI*)a->far_ptr); } return GF_OK; - + case SVG_Focus_datatype: { ((SVG_Focus *)a->far_ptr)->type = ((SVG_Focus *)b->far_ptr)->type; - if ( ((SVG_Focus *)b->far_ptr)->target.string) - ((SVG_Focus *)a->far_ptr)->target.string = strdup( ((SVG_Focus *)b->far_ptr)->target.string); + if ( ((SVG_Focus *)b->far_ptr)->target.string) + ((SVG_Focus *)a->far_ptr)->target.string = gf_strdup( ((SVG_Focus *)b->far_ptr)->target.string); } return GF_OK; @@ -5681,13 +6084,13 @@ GF_Err gf_svg_attributes_copy(GF_FieldInfo *a, GF_FieldInfo *b, Bool clamp) while (gf_list_count(dst)) { SMIL_Time *t = gf_list_get(dst, 0); gf_list_rem(dst, 0); - free(t); + gf_free(t); } count = gf_list_count(src); for (i=0;i<count;i++) { SMIL_Time *t2; SMIL_Time *t = gf_list_get(src, i); - t2 = (SMIL_Time*)malloc(sizeof(SMIL_Time)); + t2 = (SMIL_Time*)gf_malloc(sizeof(SMIL_Time)); memcpy(t2, t, sizeof(SMIL_Time)); gf_list_add(dst, t2); } @@ -5699,7 +6102,7 @@ GF_Err gf_svg_attributes_copy(GF_FieldInfo *a, GF_FieldInfo *b, Bool clamp) SMIL_AttributeName *sab = (SMIL_AttributeName *)b->far_ptr; saa->tag = sab->tag; saa->type = sab->type; - saa->name = sab->name ? strdup(sab->name) : NULL; + saa->name = sab->name ? gf_strdup(sab->name) : NULL; } break; case SMIL_Duration_datatype: @@ -5750,7 +6153,7 @@ GF_Err gf_svg_attributes_add(GF_FieldInfo *a, GF_FieldInfo *b, GF_FieldInfo *c, return gf_svg_attributes_muladd(FIX_ONE, a, FIX_ONE, b, c, clamp); } -Bool gf_svg_attribute_is_interpolatable(u32 type) +Bool gf_svg_attribute_is_interpolatable(u32 type) { switch (type) { /* additive types which can really be interpolated */ @@ -5774,7 +6177,7 @@ Bool gf_svg_attribute_is_interpolatable(u32 type) case SVG_Transform_SkewY_datatype: case LASeR_Size_datatype: return 1; - } + } return 0; } @@ -5783,7 +6186,7 @@ GF_Err gf_svg_attributes_interpolate(GF_FieldInfo *a, GF_FieldInfo *b, GF_FieldI if (!a->far_ptr || !b->far_ptr || !c->far_ptr) return GF_BAD_PARAM; c->fieldType = a->fieldType; - + switch (a->fieldType) { /* additive types which can really be interpolated */ @@ -5808,7 +6211,7 @@ GF_Err gf_svg_attributes_interpolate(GF_FieldInfo *a, GF_FieldInfo *b, GF_FieldI case LASeR_Size_datatype: return gf_svg_attributes_muladd(FIX_ONE-coef, a, coef, b, c, clamp); - /* discrete types: interpolation is the selection of one of the 2 values + /* discrete types: interpolation is the selection of one of the 2 values using the coeff and a the 0.5 threshold */ /* Keyword types */ case SVG_Boolean_datatype: @@ -5905,89 +6308,89 @@ Bool gf_svg_is_current_color(GF_FieldInfo *a) char *gf_svg_attribute_type_to_string(u32 att_type) { switch (att_type) { - case SVG_FillRule_datatype: return "FillRule"; - case SVG_StrokeLineJoin_datatype: return "StrokeLineJoin"; - case SVG_StrokeLineCap_datatype: return "StrokeLineCap"; - case SVG_FontStyle_datatype: return "FontStyle"; - case SVG_FontWeight_datatype: return "FontWeight"; - case SVG_FontVariant_datatype: return "FontVariant"; - case SVG_TextAnchor_datatype: return "TextAnchor"; - case SVG_TransformType_datatype: return "TransformType"; - case SVG_Display_datatype: return "Display"; - case SVG_Visibility_datatype: return "Visibility"; - case SVG_Overflow_datatype: return "Overflow"; - case SVG_ZoomAndPan_datatype: return "ZoomAndPan"; - case SVG_DisplayAlign_datatype: return "DisplayAlign"; - case SVG_PointerEvents_datatype: return "PointerEvents"; - case SVG_RenderingHint_datatype: return "RenderingHint"; - case SVG_VectorEffect_datatype: return "VectorEffect"; - case SVG_PlaybackOrder_datatype: return "PlaybackOrder"; - case SVG_TimelineBegin_datatype: return "TimelineBegin"; - case XML_Space_datatype: return "XML_Space"; - case XMLEV_Propagate_datatype: return "XMLEV_Propagate"; - case XMLEV_DefaultAction_datatype: return "XMLEV_DefaultAction"; - case XMLEV_Phase_datatype: return "XMLEV_Phase"; - case SMIL_SyncBehavior_datatype: return "SMIL_SyncBehavior"; - case SMIL_SyncTolerance_datatype: return "SMIL_SyncTolerance"; - case SMIL_AttributeType_datatype: return "SMIL_AttributeType"; - case SMIL_CalcMode_datatype: return "SMIL_CalcMode"; - case SMIL_Additive_datatype: return "SMIL_Additive"; - case SMIL_Accumulate_datatype: return "SMIL_Accumulate"; - case SMIL_Restart_datatype: return "SMIL_Restart"; - case SMIL_Fill_datatype: return "SMIL_Fill"; - case SVG_GradientUnit_datatype: return "GradientUnit"; - case SVG_InitialVisibility_datatype:return "InitialVisibility"; - case SVG_FocusHighlight_datatype: return "FocusHighlight"; - case SVG_Overlay_datatype: return "Overlay"; - case SVG_TransformBehavior_datatype:return "TransformBehavior"; - case SVG_SpreadMethod_datatype: return "SpreadMethod"; - case SVG_TextAlign_datatype: return "TextAlign"; - case SVG_Number_datatype: return "Number"; - case SVG_FontSize_datatype: return "FontSize"; - case SVG_Length_datatype: return "Length"; - case SVG_Coordinate_datatype: return "Coordinate"; - case SVG_Rotate_datatype: return "Rotate"; - case SVG_Numbers_datatype: return "Numbers"; - case SVG_Points_datatype: return "Points"; - case SVG_Coordinates_datatype: return "Coordinates"; - case DOM_StringList_datatype: return "StringList"; - case XMLRI_List_datatype: return "ListOfIRI"; - case SMIL_KeyTimes_datatype: return "SMIL_KeyTimes"; - case SMIL_KeySplines_datatype: return "SMIL_KeySplines"; - case SMIL_KeyPoints_datatype: return "SMIL_KeyPoints"; - case SMIL_Times_datatype: return "SMIL_Times"; - case SMIL_AnimateValue_datatype: return "SMIL_AnimateValue"; - case SMIL_AnimateValues_datatype: return "SMIL_AnimateValues"; - case SMIL_Duration_datatype: return "SMIL_Duration"; - case SMIL_RepeatCount_datatype: return "SMIL_RepeatCount"; - case SMIL_AttributeName_datatype: return "SMIL_AttributeName"; - case SVG_Boolean_datatype: return "Boolean"; - case SVG_Color_datatype: return "Color"; - case SVG_Paint_datatype: return "Paint"; - case SVG_PathData_datatype: return "PathData"; - case SVG_FontFamily_datatype: return "FontFamily"; - case SVG_ID_datatype: return "ID"; - case XMLRI_datatype: return "IRI"; - case XML_IDREF_datatype: return "IDREF"; - case SVG_StrokeDashArray_datatype: return "StrokeDashArray"; - case SVG_PreserveAspectRatio_datatype:return "PreserveAspectRatio"; - case SVG_ViewBox_datatype: return "ViewBox"; - case SVG_GradientOffset_datatype: return "GradientOffset"; - case SVG_Focus_datatype : return "Focus"; - case SVG_Clock_datatype : return "Clock"; - case DOM_String_datatype : return "String"; - case SVG_ContentType_datatype: return "ContentType"; - case SVG_LanguageID_datatype: return "LanguageID"; - case XMLEV_Event_datatype: return "XMLEV_Event"; - case SVG_Motion_datatype: return "Motion"; - case SVG_Transform_datatype: return "Transform"; - case SVG_Transform_Translate_datatype:return "Translate"; - case SVG_Transform_Scale_datatype: return "Scale"; - case SVG_Transform_SkewX_datatype: return "SkewX"; - case SVG_Transform_SkewY_datatype: return "SkewY"; - case SVG_Transform_Rotate_datatype: return "Rotate"; - case LASeR_Choice_datatype: return "LASeR_Choice"; - case LASeR_Size_datatype: return "LASeR_Size"; + case SVG_FillRule_datatype: return "FillRule"; + case SVG_StrokeLineJoin_datatype: return "StrokeLineJoin"; + case SVG_StrokeLineCap_datatype: return "StrokeLineCap"; + case SVG_FontStyle_datatype: return "FontStyle"; + case SVG_FontWeight_datatype: return "FontWeight"; + case SVG_FontVariant_datatype: return "FontVariant"; + case SVG_TextAnchor_datatype: return "TextAnchor"; + case SVG_TransformType_datatype: return "TransformType"; + case SVG_Display_datatype: return "Display"; + case SVG_Visibility_datatype: return "Visibility"; + case SVG_Overflow_datatype: return "Overflow"; + case SVG_ZoomAndPan_datatype: return "ZoomAndPan"; + case SVG_DisplayAlign_datatype: return "DisplayAlign"; + case SVG_PointerEvents_datatype: return "PointerEvents"; + case SVG_RenderingHint_datatype: return "RenderingHint"; + case SVG_VectorEffect_datatype: return "VectorEffect"; + case SVG_PlaybackOrder_datatype: return "PlaybackOrder"; + case SVG_TimelineBegin_datatype: return "TimelineBegin"; + case XML_Space_datatype: return "XML_Space"; + case XMLEV_Propagate_datatype: return "XMLEV_Propagate"; + case XMLEV_DefaultAction_datatype: return "XMLEV_DefaultAction"; + case XMLEV_Phase_datatype: return "XMLEV_Phase"; + case SMIL_SyncBehavior_datatype: return "SMIL_SyncBehavior"; + case SMIL_SyncTolerance_datatype: return "SMIL_SyncTolerance"; + case SMIL_AttributeType_datatype: return "SMIL_AttributeType"; + case SMIL_CalcMode_datatype: return "SMIL_CalcMode"; + case SMIL_Additive_datatype: return "SMIL_Additive"; + case SMIL_Accumulate_datatype: return "SMIL_Accumulate"; + case SMIL_Restart_datatype: return "SMIL_Restart"; + case SMIL_Fill_datatype: return "SMIL_Fill"; + case SVG_GradientUnit_datatype: return "GradientUnit"; + case SVG_InitialVisibility_datatype:return "InitialVisibility"; + case SVG_FocusHighlight_datatype: return "FocusHighlight"; + case SVG_Overlay_datatype: return "Overlay"; + case SVG_TransformBehavior_datatype:return "TransformBehavior"; + case SVG_SpreadMethod_datatype: return "SpreadMethod"; + case SVG_TextAlign_datatype: return "TextAlign"; + case SVG_Number_datatype: return "Number"; + case SVG_FontSize_datatype: return "FontSize"; + case SVG_Length_datatype: return "Length"; + case SVG_Coordinate_datatype: return "Coordinate"; + case SVG_Rotate_datatype: return "Rotate"; + case SVG_Numbers_datatype: return "Numbers"; + case SVG_Points_datatype: return "Points"; + case SVG_Coordinates_datatype: return "Coordinates"; + case DOM_StringList_datatype: return "StringList"; + case XMLRI_List_datatype: return "ListOfIRI"; + case SMIL_KeyTimes_datatype: return "SMIL_KeyTimes"; + case SMIL_KeySplines_datatype: return "SMIL_KeySplines"; + case SMIL_KeyPoints_datatype: return "SMIL_KeyPoints"; + case SMIL_Times_datatype: return "SMIL_Times"; + case SMIL_AnimateValue_datatype: return "SMIL_AnimateValue"; + case SMIL_AnimateValues_datatype: return "SMIL_AnimateValues"; + case SMIL_Duration_datatype: return "SMIL_Duration"; + case SMIL_RepeatCount_datatype: return "SMIL_RepeatCount"; + case SMIL_AttributeName_datatype: return "SMIL_AttributeName"; + case SVG_Boolean_datatype: return "Boolean"; + case SVG_Color_datatype: return "Color"; + case SVG_Paint_datatype: return "Paint"; + case SVG_PathData_datatype: return "PathData"; + case SVG_FontFamily_datatype: return "FontFamily"; + case SVG_ID_datatype: return "ID"; + case XMLRI_datatype: return "IRI"; + case XML_IDREF_datatype: return "IDREF"; + case SVG_StrokeDashArray_datatype: return "StrokeDashArray"; + case SVG_PreserveAspectRatio_datatype:return "PreserveAspectRatio"; + case SVG_ViewBox_datatype: return "ViewBox"; + case SVG_GradientOffset_datatype: return "GradientOffset"; + case SVG_Focus_datatype : return "Focus"; + case SVG_Clock_datatype : return "Clock"; + case DOM_String_datatype : return "String"; + case SVG_ContentType_datatype: return "ContentType"; + case SVG_LanguageID_datatype: return "LanguageID"; + case XMLEV_Event_datatype: return "XMLEV_Event"; + case SVG_Motion_datatype: return "Motion"; + case SVG_Transform_datatype: return "Transform"; + case SVG_Transform_Translate_datatype:return "Translate"; + case SVG_Transform_Scale_datatype: return "Scale"; + case SVG_Transform_SkewX_datatype: return "SkewX"; + case SVG_Transform_SkewY_datatype: return "SkewY"; + case SVG_Transform_Rotate_datatype: return "Rotate"; + case LASeR_Choice_datatype: return "LASeR_Choice"; + case LASeR_Size_datatype: return "LASeR_Size"; default: return "UnknownType"; } } diff --git a/src/scenegraph/svg_properties.c b/src/scenegraph/svg_properties.c index d9592fb..56a5f6f 100644 --- a/src/scenegraph/svg_properties.c +++ b/src/scenegraph/svg_properties.c @@ -72,7 +72,7 @@ void gf_svg_properties_init_pointers(SVGPropertiesPointers *svg_props) GF_SAFEALLOC(svg_props->font_family, SVG_FontFamily); svg_props->font_family->type = SVG_FONTFAMILY_VALUE; - svg_props->font_family->value = strdup("Arial"); + svg_props->font_family->value = gf_strdup("Arial"); GF_SAFEALLOC(svg_props->font_size, SVG_FontSize); svg_props->font_size->type = SVG_NUMBER_VALUE; @@ -179,49 +179,49 @@ GF_EXPORT void gf_svg_properties_reset_pointers(SVGPropertiesPointers *svg_props) { if (!svg_props) return; - if(svg_props->audio_level) free(svg_props->audio_level); + if(svg_props->audio_level) gf_free(svg_props->audio_level); gf_svg_delete_paint(NULL, svg_props->color); - if(svg_props->color_rendering) free(svg_props->color_rendering); - if(svg_props->display) free(svg_props->display); - if(svg_props->display_align) free(svg_props->display_align); + if(svg_props->color_rendering) gf_free(svg_props->color_rendering); + if(svg_props->display) gf_free(svg_props->display); + if(svg_props->display_align) gf_free(svg_props->display_align); gf_svg_delete_paint(NULL, svg_props->fill); - if(svg_props->fill_opacity) free(svg_props->fill_opacity); - if(svg_props->fill_rule) free(svg_props->fill_rule); + if(svg_props->fill_opacity) gf_free(svg_props->fill_opacity); + if(svg_props->fill_rule) gf_free(svg_props->fill_rule); if(svg_props->font_family) { - if (svg_props->font_family->value) free(svg_props->font_family->value); - free(svg_props->font_family); - } - if(svg_props->font_size) free(svg_props->font_size); - if(svg_props->font_style) free(svg_props->font_style); - if(svg_props->font_variant) free(svg_props->font_variant); - if(svg_props->font_weight) free(svg_props->font_weight); - if(svg_props->image_rendering) free(svg_props->image_rendering); - if(svg_props->line_increment) free(svg_props->line_increment); - if(svg_props->opacity) free(svg_props->opacity); - if(svg_props->pointer_events) free(svg_props->pointer_events); - if(svg_props->shape_rendering) free(svg_props->shape_rendering); + if (svg_props->font_family->value) gf_free(svg_props->font_family->value); + gf_free(svg_props->font_family); + } + if(svg_props->font_size) gf_free(svg_props->font_size); + if(svg_props->font_style) gf_free(svg_props->font_style); + if(svg_props->font_variant) gf_free(svg_props->font_variant); + if(svg_props->font_weight) gf_free(svg_props->font_weight); + if(svg_props->image_rendering) gf_free(svg_props->image_rendering); + if(svg_props->line_increment) gf_free(svg_props->line_increment); + if(svg_props->opacity) gf_free(svg_props->opacity); + if(svg_props->pointer_events) gf_free(svg_props->pointer_events); + if(svg_props->shape_rendering) gf_free(svg_props->shape_rendering); gf_svg_delete_paint(NULL, svg_props->solid_color); - if(svg_props->solid_opacity) free(svg_props->solid_opacity); + if(svg_props->solid_opacity) gf_free(svg_props->solid_opacity); gf_svg_delete_paint(NULL, svg_props->stop_color); - if(svg_props->stop_opacity) free(svg_props->stop_opacity); + if(svg_props->stop_opacity) gf_free(svg_props->stop_opacity); gf_svg_delete_paint(NULL, svg_props->stroke); if(svg_props->stroke_dasharray) { - if (svg_props->stroke_dasharray->array.count) free(svg_props->stroke_dasharray->array.vals); - free(svg_props->stroke_dasharray); - } - if(svg_props->stroke_dashoffset) free(svg_props->stroke_dashoffset); - if(svg_props->stroke_linecap) free(svg_props->stroke_linecap); - if(svg_props->stroke_linejoin) free(svg_props->stroke_linejoin); - if(svg_props->stroke_miterlimit) free(svg_props->stroke_miterlimit); - if(svg_props->stroke_opacity) free(svg_props->stroke_opacity); - if(svg_props->stroke_width) free(svg_props->stroke_width); - if(svg_props->text_align) free(svg_props->text_align); - if(svg_props->text_anchor) free(svg_props->text_anchor); - if(svg_props->text_rendering) free(svg_props->text_rendering); - if(svg_props->vector_effect) free(svg_props->vector_effect); + if (svg_props->stroke_dasharray->array.count) gf_free(svg_props->stroke_dasharray->array.vals); + gf_free(svg_props->stroke_dasharray); + } + if(svg_props->stroke_dashoffset) gf_free(svg_props->stroke_dashoffset); + if(svg_props->stroke_linecap) gf_free(svg_props->stroke_linecap); + if(svg_props->stroke_linejoin) gf_free(svg_props->stroke_linejoin); + if(svg_props->stroke_miterlimit) gf_free(svg_props->stroke_miterlimit); + if(svg_props->stroke_opacity) gf_free(svg_props->stroke_opacity); + if(svg_props->stroke_width) gf_free(svg_props->stroke_width); + if(svg_props->text_align) gf_free(svg_props->text_align); + if(svg_props->text_anchor) gf_free(svg_props->text_anchor); + if(svg_props->text_rendering) gf_free(svg_props->text_rendering); + if(svg_props->vector_effect) gf_free(svg_props->vector_effect); gf_svg_delete_paint(NULL, svg_props->viewport_fill); - if(svg_props->viewport_fill_opacity) free(svg_props->viewport_fill_opacity); - if(svg_props->visibility) free(svg_props->visibility); + if(svg_props->viewport_fill_opacity) gf_free(svg_props->viewport_fill_opacity); + if(svg_props->visibility) gf_free(svg_props->visibility); memset(svg_props, 0, sizeof(SVGPropertiesPointers)); } @@ -801,6 +801,7 @@ void gf_svg_flatten_attributes(SVG_Element *e, SVGAllAttributes *all_atts) case TAG_SVG_ATT_fill_opacity: all_atts->fill_opacity = (SVG_Number *)att->data; break; case TAG_SVG_ATT_stroke_opacity: all_atts->stroke_opacity = (SVG_Number *)att->data; break; case TAG_SVG_ATT_fill: all_atts->fill = (SVG_Paint *)att->data; break; + case TAG_SVG_ATT_filter: all_atts->filter = (SVG_Paint *)att->data; break; case TAG_SVG_ATT_fill_rule: all_atts->fill_rule = (SVG_FillRule *)att->data; break; case TAG_SVG_ATT_stroke: all_atts->stroke = (SVG_Paint *)att->data; break; case TAG_SVG_ATT_stroke_dasharray: all_atts->stroke_dasharray = (SVG_StrokeDashArray *)att->data; break; @@ -928,6 +929,7 @@ void gf_svg_flatten_attributes(SVG_Element *e, SVGAllAttributes *all_atts) case TAG_SVG_ATT_x2: all_atts->x2 = (SVG_Coordinate *)att->data; break; case TAG_SVG_ATT_y2: all_atts->y2 = (SVG_Coordinate *)att->data; break; case TAG_SVG_ATT_gradientUnits: all_atts->gradientUnits = (SVG_GradientUnit *)att->data; break; + case TAG_SVG_ATT_filterUnits: all_atts->focusable = (SVG_GradientUnit *)att->data; break; case TAG_SVG_ATT_spreadMethod: all_atts->spreadMethod = (SVG_SpreadMethod *)att->data; break; case TAG_SVG_ATT_gradientTransform: all_atts->gradientTransform = (SVG_Transform *)att->data; break; case TAG_SVG_ATT_pathLength: all_atts->pathLength = (SVG_Number *)att->data; break; @@ -961,6 +963,10 @@ void gf_svg_flatten_attributes(SVG_Element *e, SVGAllAttributes *all_atts) case TAG_SVG_ATT_overlay: all_atts->overlay = (SVG_Overlay *)att->data; break; case TAG_SVG_ATT_fullscreen: all_atts->fullscreen = (SVG_Boolean *)att->data; break; case TAG_SVG_ATT_motionTransform: all_atts->motionTransform = (SVG_Motion *)att->data; break; + + case TAG_GSVG_ATT_useAsPrimary: all_atts->gpac_useAsPrimary = (SVG_Boolean *)att->data; break; + case TAG_GSVG_ATT_depthOffset: all_atts->gpac_depthOffset = (SVG_Number *)att->data; break; + case TAG_GSVG_ATT_depthGain: all_atts->gpac_depthGain = (SVG_Number *)att->data; break; } att = att->next; diff --git a/src/scenegraph/svg_smjs.c b/src/scenegraph/svg_smjs.c index e18ce89..3166da3 100644 --- a/src/scenegraph/svg_smjs.c +++ b/src/scenegraph/svg_smjs.c @@ -11,15 +11,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -32,7 +32,9 @@ #ifdef GPAC_HAS_SPIDERMONKEY -#include <jsapi.h> +#include <jsapi.h> + +JSBool my_js_has_instance(JSContext *c, JSObject *obj, jsval val, JSBool *vp); #define JSVAL_CHECK_STRING(_v) (JSVAL_IS_STRING(_v) || JSVAL_IS_NULL(_v)) #define JSVAL_GET_STRING(_v) (JSVAL_IS_NULL(_v) ? NULL : JS_GetStringBytes(JSVAL_TO_STRING(_v)) ) @@ -47,14 +49,14 @@ void dom_document_finalize(JSContext *c, JSObject *obj); GF_Node *dom_get_element(JSContext *c, JSObject *obj); GF_SceneGraph *dom_get_doc(JSContext *c, JSObject *obj); -JSBool js_has_instance(JSContext *c, JSObject *obj, jsval val, JSBool *vp); +void dom_node_changed(GF_Node *n, Bool child_modif, GF_FieldInfo *info); + JSBool dom_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval); JSBool dom_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval); char *js_get_utf8(jsval val); void dom_node_set_textContent(GF_Node *n, char *text); -char *dom_node_flatten_text(GF_Node *n); jsval dom_node_get_sibling(JSContext *c, GF_Node *n, Bool is_prev, Bool elt_only); @@ -70,7 +72,7 @@ jsval dom_node_get_sibling(JSContext *c, GF_Node *n, Bool is_prev, Bool elt_only static GFINLINE Bool ScriptAction(GF_SceneGraph *scene, u32 type, GF_Node *node, GF_JSAPIParam *param) { - if (scene->script_action) + if (scene->script_action) return scene->script_action(scene->script_action_cbck, type, node, param); return 0; } @@ -94,19 +96,6 @@ static GF_SVGuDOM *svg_rt = NULL; static JSObject *svg_new_path_object(JSContext *c, SVG_PathData *d); -static void svg_node_changed(GF_Node *n, GF_FieldInfo *info) -{ - if (!info) { - gf_node_changed(n, NULL); - } else { - u32 flag = gf_svg_get_modification_flags((SVG_Element *)n, info); - gf_node_dirty_set(n, flag, 0); - } - /*trigger rendering*/ - if (n->sgprivate->scenegraph->NodeCallback) - n->sgprivate->scenegraph->NodeCallback(n->sgprivate->scenegraph->userpriv, GF_SG_CALLBACK_MODIFIED, n, info); -} - /*note we are using float to avoid conversions fixed to/from JS native */ typedef struct @@ -148,7 +137,7 @@ static JSBool svg_nav_to_location(JSContext *c, JSObject *obj, uintN argc, jsval GF_JSAPIParam par; GF_SceneGraph *sg; if ((argc!=1) || !JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL)) return JS_TRUE; - sg = JS_GetContextPrivate(c); + sg = JS_GetPrivate(c, obj); par.uri.url = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); par.uri.nb_params = 0; ScriptAction(sg, GF_JSAPI_OP_LOAD_URL, sg->RootNode, &par); @@ -162,47 +151,39 @@ static JSBool svg_parse_xml(JSContext *c, JSObject *obj, uintN argc, jsval *argv GF_Node *node; char *str; GF_Node *gf_sm_load_svg_from_string(GF_SceneGraph *sg, char *svg_str); - + doc_obj = JSVAL_TO_OBJECT(argv[1]); if (!doc_obj) { dom_throw_exception(c, GF_DOM_EXC_WRONG_DOCUMENT_ERR); return JS_FALSE; } + str = js_get_utf8(argv[0]); if (!str) return JS_TRUE; - sg = dom_get_doc(c, doc_obj); node = gf_sm_load_svg_from_string(sg, str); - free(str); + gf_free(str); *rval = dom_element_construct(c, node); - return JS_TRUE; } static void svg_script_error(JSContext *c, const char *msg, JSErrorReport *jserr) { - GF_SceneGraph *sg = JS_GetContextPrivate(c); - _ScriptMessage(sg, GF_SCRIPT_ERROR, msg); + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[JavaScript] Error: %s - line %d (%s)", msg, jserr->lineno, jserr->linebuf)); } -static JSBool svg_echo(JSContext *c, JSObject *p, uintN argc, jsval *argv, jsval *rval) +static JSBool svg_echo(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - u32 i; - char buf[5000]; - GF_SceneGraph *sg = JS_GetContextPrivate(c); + GF_SceneGraph *sg; + if ((argc!=1) || !JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL)) return JS_TRUE; + sg = JS_GetPrivate(c, obj); if (!sg) return JS_TRUE; - strcpy(buf, ""); - for (i = 0; i < argc; i++) { - jschar*utf; - JSString *str = JS_ValueToString(c, argv[i]); - if (!str) return JS_TRUE; - if (i) strcat(buf, " "); - utf = JS_GetStringChars(str); - strcat(buf, JS_GetStringBytes(str)); + if (JSVAL_IS_STRING(argv[0])) { + char *str = JS_GetStringBytes(JS_ValueToString(c, argv[0]) ); + _ScriptMessage(sg, GF_SCRIPT_INFO, str); } - _ScriptMessage(sg, GF_SCRIPT_INFO, buf); return JS_TRUE; } @@ -236,17 +217,17 @@ static void svg_define_udom_exception(JSContext *c, JSObject *global) static JSBool global_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) { GF_SceneGraph *sg; - if (!JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL) ) + if (!JS_InstanceOf(c, obj, &svg_rt->globalClass, NULL) ) return JS_TRUE; - sg = JS_GetContextPrivate(c); + sg = JS_GetPrivate(c, obj); if (JSVAL_IS_INT(id)) { switch (JSVAL_TO_INT(id)) { /*namespaceURI*/ - case 0: + case 0: return JS_TRUE; /*parent*/ - case 1: + case 1: *vp = JSVAL_VOID; if (sg->parent_scene && sg->parent_scene->svg_js) *vp = OBJECT_TO_JSVAL(sg->parent_scene->svg_js->global); return JS_TRUE; @@ -278,7 +259,7 @@ static JSBool dom_imp_has_feature(JSContext *c, JSObject *obj, uintN argc, jsval else if (!stricmp(fname, "mouseevents")) *rval = BOOLEAN_TO_JSVAL(JS_TRUE); else if (!stricmp(fname, "mutationevents")) *rval = BOOLEAN_TO_JSVAL(JS_TRUE); else if (!stricmp(fname, "events")) *rval = BOOLEAN_TO_JSVAL(JS_TRUE); - + fname[len] = sep; } return JS_TRUE; @@ -313,7 +294,7 @@ static JSBool svg_doc_getProperty(JSContext *c, JSObject *obj, jsval id, jsval * prop_id = JSVAL_TO_INT(id); switch (prop_id) { case 0:/*global*/ - *vp = OBJECT_TO_JSVAL( JS_GetGlobalObject(c) ); + *vp = OBJECT_TO_JSVAL( JS_GetGlobalObject(c) ); return JS_TRUE; } return JS_TRUE; @@ -343,40 +324,6 @@ static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, jsval id, jsv } return JS_TRUE; } - case 1:/*firstElementChild*/ - *vp = JSVAL_NULL; - if (n->sgprivate->tag!=TAG_DOMText) { - GF_ChildNodeItem *child = ((GF_ParentNode*)n)->children; - while (child) { - if (child->node->sgprivate->tag != TAG_DOMText) { - *vp = dom_element_construct(c, child->node); - break; - } - child = child->next; - } - } - return JS_TRUE; - case 2:/*lastElementChild*/ - *vp = JSVAL_NULL; - if (n->sgprivate->tag!=TAG_DOMText) { - GF_Node *last = NULL; - GF_ChildNodeItem *child = ((GF_ParentNode*)n)->children; - while (child) { - if (child->node->sgprivate->tag != TAG_DOMText) { - last = child->node; - } - child = child->next; - } - if (last) *vp = dom_element_construct(c, last); - } - return JS_TRUE; - case 3:/*previousElementSibling*/ - *vp = dom_node_get_sibling(c, n, 1, 1); - return JS_TRUE; - case 4:/*nextElementSibling*/ - *vp = dom_node_get_sibling(c, n, 0, 1); - return JS_TRUE; - case 5:/*currentScale*/ if (n->sgprivate->tag!=TAG_SVG_svg) return JS_TRUE; if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_GET_SCALE, (GF_Node *)n, &par)) { @@ -385,7 +332,7 @@ static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, jsval id, jsv return JS_TRUE; } return JS_TRUE; - case 6:/*currentRotate*/ + case 6:/*currentRotate*/ if (n->sgprivate->tag!=TAG_SVG_svg) return JS_TRUE; if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_GET_ROTATION, (GF_Node *)n, &par)) { d = JS_NewDouble(c, FIX2FLT(par.val) ); @@ -397,7 +344,7 @@ static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, jsval id, jsv 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); - pointCI *rc = malloc(sizeof(pointCI)); + pointCI *rc = gf_malloc(sizeof(pointCI)); rc->x = FIX2FLT(par.pt.x); rc->y = FIX2FLT(par.pt.y); rc->sg = n->sgprivate->scenegraph; @@ -410,7 +357,7 @@ static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, jsval id, jsv 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); - rectCI *rc = malloc(sizeof(rectCI)); + rectCI *rc = gf_malloc(sizeof(rectCI)); rc->x = FIX2FLT(par.rc.x); rc->y = FIX2FLT(par.rc.y); rc->w = FIX2FLT(par.rc.width); @@ -421,11 +368,11 @@ static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, jsval id, jsv return JS_TRUE; } return JS_TRUE; - case 9:/*currentTime*/ + case 9:/*currentTime*/ d = JS_NewDouble(c, gf_node_get_scene_time((GF_Node *)n) ); *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE; - case 10:/*isPaused*/ + case 10:/*isPaused*/ *vp = BOOLEAN_TO_JSVAL(JS_FALSE); return JS_TRUE; case 11:/*ownerSVGElement*/ @@ -450,7 +397,7 @@ static JSBool svg_element_getProperty(JSContext *c, JSObject *obj, jsval id, jsv case 13:/*correspondingUseElement*/ *vp = dom_element_construct(c, get_corresponding_use(n)); return JS_TRUE; - default: + default: return JS_TRUE; } return JS_TRUE; @@ -477,18 +424,18 @@ static JSBool svg_element_setProperty(JSContext *c, JSObject *obj, jsval id, jsv if (!nid) nid = gf_sg_get_next_available_node_id(n->sgprivate->scenegraph); gf_node_set_id(n, nid, id); if (gf_node_get_attribute_by_tag(n, TAG_XML_ATT_id, 1, 0, &info)==GF_OK) { - if (*(DOM_String *)info.far_ptr) free(*(DOM_String *)info.far_ptr); - *(DOM_String *)info.far_ptr = strdup(id); + if (*(DOM_String *)info.far_ptr) gf_free(*(DOM_String *)info.far_ptr); + *(DOM_String *)info.far_ptr = gf_strdup(id); } if (gf_node_get_attribute_by_tag(n, TAG_SVG_ATT_id, 1, 0, &info)==GF_OK) { - if (*(DOM_String *)info.far_ptr) free(*(DOM_String *)info.far_ptr); - *(DOM_String *)info.far_ptr = strdup(id); + if (*(DOM_String *)info.far_ptr) gf_free(*(DOM_String *)info.far_ptr); + *(DOM_String *)info.far_ptr = gf_strdup(id); } } } return JS_TRUE; /*currentScale*/ - case 5: + case 5: if (!JSVAL_IS_NUMBER(*vp) || (n->sgprivate->tag!=TAG_SVG_svg)) return JS_TRUE; JS_ValueToNumber(c, *vp, &d); par.val = FLT2FIX(d); @@ -500,7 +447,7 @@ static JSBool svg_element_setProperty(JSContext *c, JSObject *obj, jsval id, jsv } return JS_TRUE; /*currentRotate*/ - case 6: + case 6: if (!JSVAL_IS_NUMBER(*vp) || (n->sgprivate->tag!=TAG_SVG_svg)) return JS_TRUE; JS_ValueToNumber(c, *vp, &d); par.val = FLT2FIX(d); @@ -517,7 +464,7 @@ static JSBool svg_element_setProperty(JSContext *c, JSObject *obj, jsval id, jsv return JS_TRUE; } return JS_TRUE; - default: + default: return JS_TRUE; } return JS_TRUE; @@ -555,7 +502,7 @@ JSBool svg_udom_smil_time_insert(JSContext *c, JSObject *obj, uintN argc, jsval SMIL_Time *newtime; GF_Node *n = svg_udom_smil_check_instance(c, obj); if (!n) return JS_TRUE; - + if (is_end) { info.far_ptr = ((SVGTimedAnimBaseElement *)n)->timingp->end; @@ -575,7 +522,7 @@ JSBool svg_udom_smil_time_insert(JSContext *c, JSObject *obj, uintN argc, jsval offset = d; } newtime->clock = gf_node_get_scene_time(n) + offset; - + /*insert in sorted order*/ count = gf_list_count(times); for (i=0; i<count; i++) { @@ -586,8 +533,8 @@ JSBool svg_udom_smil_time_insert(JSContext *c, JSObject *obj, uintN argc, jsval break; } } - gf_list_insert(times, newtime, i); - + gf_list_insert(times, newtime, i); + info.fieldType = SMIL_Times_datatype; gf_node_changed(n, &info); return JS_TRUE; @@ -640,7 +587,7 @@ JSBool svg_udom_smil_resume(JSContext *c, JSObject *obj, uintN argc, jsval *argv JSBool svg_udom_get_trait(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { - char attValue[1024], *ns, *name; + char *attValue, *ns, *name; GF_Err e; GF_FieldInfo info; GF_Node *n = dom_get_element(c, obj); @@ -657,9 +604,9 @@ JSBool svg_udom_get_trait(JSContext *c, JSObject *obj, uintN argc, jsval *argv, if (!name) return JS_TRUE; if (!strcmp(name, "#text")) { - char *res = dom_node_flatten_text(n); + char *res = gf_dom_flatten_textContent(n); *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, res) ); - free(res); + gf_free(res); return JS_TRUE; } e = gf_node_get_field_by_name(n, name, &info); @@ -723,8 +670,9 @@ JSBool svg_udom_get_trait(JSContext *c, JSObject *obj, uintN argc, jsval *argv, case SVG_ID_datatype: case SVG_GradientOffset_datatype: /*end of DOM string traits*/ - gf_svg_dump_attribute(n, &info, attValue); + attValue = gf_svg_dump_attribute(n, &info); *rval = STRING_TO_JSVAL( JS_NewStringCopyZ(c, attValue) ); + if (attValue) gf_free(attValue); return JS_TRUE; /*dump to trait*/ break; @@ -807,7 +755,7 @@ JSBool svg_udom_get_matrix_trait(JSContext *c, JSObject *obj, uintN argc, jsval if (gf_node_get_field_by_name(n, szName, &info) != GF_OK) return JS_TRUE; if (info.fieldType==SVG_Transform_datatype) { - GF_Matrix2D *mx = malloc(sizeof(GF_Matrix2D)); + GF_Matrix2D *mx = gf_malloc(sizeof(GF_Matrix2D)); mO = JS_NewObject(c, &svg_rt->matrixClass, 0, 0); gf_mx2d_init(*mx); gf_mx2d_copy(*mx, ((SVG_Transform*)info.far_ptr)->mat); @@ -935,7 +883,7 @@ JSBool svg_udom_set_trait(JSContext *c, JSObject *obj, uintN argc, jsval *argv, } else if (argc==2) { name = JSVAL_GET_STRING(argv[0]); val = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); - } else + } else return JS_TRUE; if (!name) return JS_TRUE; if (!strcmp(name, "#text")) { @@ -952,7 +900,7 @@ JSBool svg_udom_set_trait(JSContext *c, JSObject *obj, uintN argc, jsval *argv, e = gf_svg_parse_attribute(n, &info, val, 0); if (e) return dom_throw_exception(c, GF_DOM_EXC_INVALID_ACCESS_ERR); - svg_node_changed(n, &info); + dom_node_changed(n, 0, &info); return JS_TRUE; } @@ -991,7 +939,7 @@ JSBool svg_udom_set_float_trait(JSContext *c, JSObject *obj, uintN argc, jsval * while (gf_list_count(*l)) { val = gf_list_get(*l, 0); gf_list_rem(*l, 0); - free(val); + gf_free(val); } GF_SAFEALLOC(val, SVG_Coordinate); val->type=SVG_NUMBER_VALUE; @@ -1002,7 +950,7 @@ JSBool svg_udom_set_float_trait(JSContext *c, JSObject *obj, uintN argc, jsval * default: return JS_TRUE; } - svg_node_changed(n, &info); + dom_node_changed(n, 0, &info); return JS_TRUE; } JSBool svg_udom_set_matrix_trait(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) @@ -1027,7 +975,7 @@ JSBool svg_udom_set_matrix_trait(JSContext *c, JSObject *obj, uintN argc, jsval if (info.fieldType==SVG_Transform_datatype) { gf_mx2d_copy(((SVG_Transform*)info.far_ptr)->mat, *mx); - svg_node_changed(n, NULL); + dom_node_changed(n, 0, NULL); return JS_TRUE; } return JS_TRUE; @@ -1058,7 +1006,7 @@ JSBool svg_udom_set_rect_trait(JSContext *c, JSObject *obj, uintN argc, jsval *a v->y = FLT2FIX(rc->y); v->width = FLT2FIX(rc->w); v->height = FLT2FIX(rc->h); - svg_node_changed(n, NULL); + dom_node_changed(n, 0, NULL); return JS_TRUE; } return JS_TRUE; @@ -1089,16 +1037,16 @@ JSBool svg_udom_set_path_trait(JSContext *c, JSObject *obj, uintN argc, jsval *a while (gf_list_count(d->commands)) { u8 *t = gf_list_get(d->commands, 0); gf_list_rem(d->commands, 0); - free(t); + gf_free(t); } while (gf_list_count(d->points)) { SVG_Point *t = gf_list_get(d->points, 0); gf_list_rem(d->points, 0); - free(t); + gf_free(t); } nb_pts = 0; for (i=0; i<path->nb_coms; i++) { - u8 *t = malloc(sizeof(u8)); + u8 *t = gf_malloc(sizeof(u8)); *t = path->tags[i]; gf_list_add(d->commands, t); switch (*t) { @@ -1109,12 +1057,12 @@ JSBool svg_udom_set_path_trait(JSContext *c, JSObject *obj, uintN argc, jsval *a } } for (i=0; i<nb_pts; i++) { - SVG_Point *t = malloc(sizeof(SVG_Point)); + SVG_Point *t = gf_malloc(sizeof(SVG_Point)); t->x = FLT2FIX(path->pts[i].x); t->y = FLT2FIX(path->pts[i].y); gf_list_add(d->points, t); } - svg_node_changed(n, NULL); + dom_node_changed(n, 0, NULL); return JS_TRUE; #endif } @@ -1149,7 +1097,7 @@ JSBool svg_udom_set_rgb_color_trait(JSContext *c, JSObject *obj, uintN argc, jsv col->red = FLT2FIX(rgb->r / 255.0f); col->green = FLT2FIX(rgb->g / 255.0f); col->blue = FLT2FIX(rgb->b / 255.0f); - svg_node_changed(n, &info); + dom_node_changed(n, 0, &info); return JS_TRUE; } case SVG_Paint_datatype: @@ -1160,7 +1108,7 @@ JSBool svg_udom_set_rgb_color_trait(JSContext *c, JSObject *obj, uintN argc, jsv paint->color.red = FLT2FIX(rgb->r / 255.0f); paint->color.green = FLT2FIX(rgb->g / 255.0f); paint->color.blue = FLT2FIX(rgb->b / 255.0f); - svg_node_changed(n, &info); + dom_node_changed(n, 0, &info); return JS_TRUE; } } @@ -1177,7 +1125,7 @@ static JSBool svg_get_bbox(JSContext *c, JSObject *obj, uintN argc, jsval *argv, 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); - rectCI *rc = malloc(sizeof(rectCI)); + rectCI *rc = gf_malloc(sizeof(rectCI)); rc->sg = NULL; rc->x = FIX2FLT(par.bbox.min_edge.x); /*BBox is in 3D coord system style*/ @@ -1210,7 +1158,7 @@ JSBool svg_udom_get_screen_ctm(JSContext *c, JSObject *obj, uintN argc, jsval *a if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_GET_TRANSFORM, (GF_Node *)n, &par)) { JSObject *mO = JS_NewObject(c, &svg_rt->matrixClass, 0, 0); - GF_Matrix2D *mx = malloc(sizeof(GF_Matrix2D)); + GF_Matrix2D *mx = gf_malloc(sizeof(GF_Matrix2D)); gf_mx2d_from_mx(mx, &par.mx); JS_SetPrivate(c, mO, mx); *rval = OBJECT_TO_JSVAL(mO); @@ -1227,7 +1175,7 @@ JSBool svg_udom_create_matrix_components(JSContext *c, JSObject *obj, uintN argc GF_Node *n = dom_get_element(c, obj); if (!n) return JS_TRUE; if (argc!=6) return JS_TRUE; - + GF_SAFEALLOC(mx, GF_Matrix2D) JS_ValueToNumber(c, argv[0], &v); mx->m[0] = FLT2FIX(v); @@ -1311,7 +1259,7 @@ JSBool svg_udom_move_focus(JSContext *c, JSObject *obj, uintN argc, jsval *argv, if ((argc!=1) || !JSVAL_IS_OBJECT(argv[0])) return JS_TRUE; par.opt = JSVAL_TO_INT(argv[1]); - if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_SET_FOCUS, (GF_Node *)n, &par)) + if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_SET_FOCUS, (GF_Node *)n, &par)) return JS_TRUE; return JS_TRUE; } @@ -1326,7 +1274,7 @@ JSBool svg_udom_set_focus(JSContext *c, JSObject *obj, uintN argc, jsval *argv, /*NOT IN THE GRAPH*/ if (!par.node || !par.node->sgprivate->num_instances) return JS_TRUE; - if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_SET_FOCUS, (GF_Node *)n, &par)) + if (ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_SET_FOCUS, (GF_Node *)n, &par)) return JS_TRUE; return JS_TRUE; } @@ -1335,9 +1283,9 @@ JSBool svg_udom_get_focus(JSContext *c, JSObject *obj, uintN argc, jsval *argv, GF_JSAPIParam par; GF_Node *n = dom_get_element(c, obj); if (!n || argc) return JS_TRUE; - + *rval = JSVAL_VOID; - if (!ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_GET_FOCUS, (GF_Node *)n, &par)) + if (!ScriptAction(n->sgprivate->scenegraph, GF_JSAPI_OP_GET_FOCUS, (GF_Node *)n, &par)) return JS_TRUE; if (par.node) { @@ -1380,27 +1328,27 @@ static JSBool svg_connection_close(JSContext *c, JSObject *obj, uintN argc, jsva return JS_TRUE; } static JSPropertySpec connectionProps[] = { - {"connected", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {0} + {"connected", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {0, 0, 0, 0, 0} }; static JSFunctionSpec connectionFuncs[] = { /*eventTarget interface*/ - {"addEventListenerNS", dom_event_add_listener, 4}, - {"removeEventListenerNS", dom_event_remove_listener, 4}, - {"addEventListenerNS", dom_event_add_listener, 3}, - {"removeEventListenerNS", dom_event_remove_listener, 3}, + {"addEventListenerNS", dom_event_add_listener, 4, 0, 0}, + {"removeEventListenerNS", dom_event_remove_listener, 4, 0, 0}, + {"addEventListenerNS", dom_event_add_listener, 3, 0, 0}, + {"removeEventListenerNS", dom_event_remove_listener, 3, 0, 0}, /*connection interface*/ - {"setEncoding", svg_connection_set_encoding, 1}, - {"connect", svg_connection_connect, 1}, - {"send", svg_connection_send, 1}, - {"close", svg_connection_close, 0}, - {0} + {"setEncoding", svg_connection_set_encoding, 1, 0, 0}, + {"connect", svg_connection_connect, 1, 0, 0}, + {"send", svg_connection_send, 1, 0, 0}, + {"close", svg_connection_close, 0, 0, 0}, + {0, 0, 0, 0, 0} }; static void baseCI_finalize(JSContext *c, JSObject *obj) { void *data = JS_GetPrivate(c, obj); - if (data) free(data); + if (data) gf_free(data); } static JSBool rgb_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) @@ -1536,10 +1484,10 @@ static JSObject *svg_new_path_object(JSContext *c, SVG_PathData *d) if (d) { u32 i, count; p->nb_coms = gf_list_count(d->commands); - p->tags = malloc(sizeof(u8) * p->nb_coms); + p->tags = gf_malloc(sizeof(u8) * p->nb_coms); for (i=0; i<p->nb_coms; i++) p->tags[i] = * (u8 *) gf_list_get(d->commands, i); count = gf_list_count(d->points); - p->pts = malloc(sizeof(pointCI) * count); + p->pts = gf_malloc(sizeof(pointCI) * count); for (i=0; i<count; i++) { GF_Point2D *pt = gf_list_get(d->commands, i); p->pts[i].x = FIX2FLT(pt->x); @@ -1565,9 +1513,9 @@ static void pathCI_finalize(JSContext *c, JSObject *obj) { pathCI *p = JS_GetPrivate(c, obj); if (p) { - if (p->pts) free(p->pts); - if (p->tags) free(p->tags); - free(p); + if (p->pts) gf_free(p->pts); + if (p->tags) gf_free(p->tags); + gf_free(p); } } @@ -1599,10 +1547,10 @@ static JSBool svg_path_get_segment(JSContext *c, JSObject *obj, uintN argc, jsva case 1: *vp = INT_TO_JSVAL(76); return JS_TRUE; /* Line To */ case 2:/* Curve To */ case 3:/* next Curve To */ - *vp = INT_TO_JSVAL(67); return JS_TRUE; + *vp = INT_TO_JSVAL(67); return JS_TRUE; case 4:/* Quad To */ case 5:/* next Quad To */ - *vp = INT_TO_JSVAL(81); return JS_TRUE; + *vp = INT_TO_JSVAL(81); return JS_TRUE; case 6: *vp = INT_TO_JSVAL(90); return JS_TRUE; /* Close */ } return JS_TRUE; @@ -1633,18 +1581,18 @@ static JSBool svg_path_get_segment_param(JSContext *c, JSObject *obj, uintN argc } } switch (p->tags[idx]) { - case 0: - case 1: + case 0: + case 1: if (param_idx>1) return JS_TRUE; pt = &p->pts[pt_idx]; - d = JS_NewDouble(c, param_idx ? pt->y : pt->x); - *vp = DOUBLE_TO_JSVAL(d); + d = JS_NewDouble(c, param_idx ? pt->y : pt->x); + *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE; case 2:/* Curve To */ if (param_idx>5) return JS_TRUE; pt = &p->pts[pt_idx + (param_idx/2) ]; d = JS_NewDouble(c, (param_idx%2) ? pt->y : pt->x); - *vp = DOUBLE_TO_JSVAL(d); + *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE; case 3:/* Next Curve To */ if (param_idx>5) return JS_TRUE; @@ -1656,13 +1604,13 @@ static JSBool svg_path_get_segment_param(JSContext *c, JSObject *obj, uintN argc pt = &p->pts[pt_idx + (param_idx/2)]; d = JS_NewDouble(c, (param_idx%2) ? pt->y : pt->x); } - *vp = DOUBLE_TO_JSVAL(d); + *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE; case 4:/* Quad To */ if (param_idx>3) return JS_TRUE; pt = &p->pts[pt_idx + (param_idx/2) ]; d = JS_NewDouble(c, (param_idx%2) ? pt->y : pt->x); - *vp = DOUBLE_TO_JSVAL(d); + *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE; case 5:/* Next Quad To */ if (param_idx>3) return JS_TRUE; @@ -1674,12 +1622,12 @@ static JSBool svg_path_get_segment_param(JSContext *c, JSObject *obj, uintN argc pt = &p->pts[pt_idx]; d = JS_NewDouble(c, param_idx ? pt->y : pt->x); } - *vp = DOUBLE_TO_JSVAL(d); + *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE; /*spec is quite obscur here*/ case 6: - d = JS_NewDouble(c, 0); - *vp = DOUBLE_TO_JSVAL(d); + d = JS_NewDouble(c, 0); + *vp = DOUBLE_TO_JSVAL(d); return JS_TRUE; } return JS_TRUE; @@ -1699,7 +1647,7 @@ static u32 svg_path_realloc_pts(pathCI *p, u32 nb_pts) case 5: orig_pts+=1; break; } } - p->pts = realloc(p->pts, sizeof(ptCI)*(nb_pts+orig_pts)); + p->pts = gf_realloc(p->pts, sizeof(ptCI)*(nb_pts+orig_pts)); return orig_pts; } static JSBool svg_path_move_to(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *vp) @@ -1716,7 +1664,7 @@ static JSBool svg_path_move_to(JSContext *c, JSObject *obj, uintN argc, jsval *a nb_pts = svg_path_realloc_pts(p, 1); p->pts[nb_pts].x = (Float) x; p->pts[nb_pts].y = (Float) y; - p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); + p->tags = gf_realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); p->tags[p->nb_coms] = 0; p->nb_coms++; return JS_TRUE; @@ -1735,7 +1683,7 @@ static JSBool svg_path_line_to(JSContext *c, JSObject *obj, uintN argc, jsval *a nb_pts = svg_path_realloc_pts(p, 1); p->pts[nb_pts].x = (Float) x; p->pts[nb_pts].y = (Float) y; - p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); + p->tags = gf_realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); p->tags[p->nb_coms] = 1; p->nb_coms++; return JS_TRUE; @@ -1757,7 +1705,7 @@ static JSBool svg_path_quad_to(JSContext *c, JSObject *obj, uintN argc, jsval *a nb_pts = svg_path_realloc_pts(p, 2); p->pts[nb_pts].x = (Float) x1; p->pts[nb_pts].y = (Float) y1; p->pts[nb_pts+1].x = (Float) x2; p->pts[nb_pts+1].y = (Float) y2; - p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); + p->tags = gf_realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); p->tags[p->nb_coms] = 4; p->nb_coms++; return JS_TRUE; @@ -1781,7 +1729,7 @@ static JSBool svg_path_curve_to(JSContext *c, JSObject *obj, uintN argc, jsval * p->pts[nb_pts].x = (Float) x1; p->pts[nb_pts].y = (Float) y1; p->pts[nb_pts+1].x = (Float) x2; p->pts[nb_pts+1].y = (Float) y2; p->pts[nb_pts+2].x = (Float) x; p->pts[nb_pts+2].y = (Float) y; - p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); + p->tags = gf_realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); p->tags[p->nb_coms] = 2; p->nb_coms++; return JS_TRUE; @@ -1793,7 +1741,7 @@ static JSBool svg_path_close(JSContext *c, JSObject *obj, uintN argc, jsval *arg p = JS_GetPrivate(c, obj); if (!p) return JS_TRUE; if (argc) return JS_TRUE; - p->tags = realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); + p->tags = gf_realloc(p->tags, sizeof(u8)*(p->nb_coms+1) ); p->tags[p->nb_coms] = 6; p->nb_coms++; return JS_TRUE; @@ -1937,7 +1885,7 @@ static JSBool svg_mx2d_rotate(JSContext *c, JSObject *obj, uintN argc, jsval *ar 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); - rectCI *rc = malloc(sizeof(rectCI)); + rectCI *rc = gf_malloc(sizeof(rectCI)); rc->x = FIX2FLT(x); rc->y = FIX2FLT(y); rc->w = FIX2FLT(width); @@ -1950,7 +1898,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); - pointCI *pt = malloc(sizeof(pointCI)); + pointCI *pt = gf_malloc(sizeof(pointCI)); pt->x = FIX2FLT(x); pt->y = FIX2FLT(y); pt->sg = NULL; @@ -1960,11 +1908,18 @@ jsval svg_udom_new_point(JSContext *c, Fixed x, Fixed y) void *svg_get_element_class(GF_Node *n) { - return &svg_rt->svgElement; + if (!n) return NULL; + if ((n->sgprivate->tag>=GF_NODE_RANGE_FIRST_SVG) && (n->sgprivate->tag<=GF_NODE_RANGE_LAST_SVG)) + return &svg_rt->svgElement; + return NULL; } -void *svg_get_document_class(GF_SceneGraph *n) +void *svg_get_document_class(GF_SceneGraph *sg) { - return &svg_rt->svgDocument; + GF_Node *n = sg->RootNode; + if (!n) return NULL; + if ((n->sgprivate->tag>=GF_NODE_RANGE_FIRST_SVG) && (n->sgprivate->tag<=GF_NODE_RANGE_LAST_SVG)) + return &svg_rt->svgDocument; + return NULL; } @@ -1981,18 +1936,19 @@ static void svg_init_js_api(GF_SceneGraph *scene) JS_SetPrivate(scene->svg_js->js_ctx, scene->svg_js->global, scene); { JSPropertySpec globalClassProps[] = { - {"connected", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"parent", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {0} + {"connected", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"parent", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {0, 0, 0, 0, 0} }; JSFunctionSpec globalClassFuncs[] = { - {"createConnection", svg_connection_create, 0}, - {"gotoLocation", svg_nav_to_location, 1}, - {"alert", svg_echo, 0}, + {"createConnection", svg_connection_create, 0, 0, 0}, + {"gotoLocation", svg_nav_to_location, 1, 0, 0}, + {"alert", svg_echo, 0, 0, 0}, + {"print", svg_echo, 0, 0, 0}, /*technically, this is part of Implementation interface, not global, but let's try not to complicate things too much*/ - {"hasFeature", dom_imp_has_feature, 2}, - {"parseXML", svg_parse_xml, 0}, - {0} + {"hasFeature", dom_imp_has_feature, 2, 0, 0}, + {"parseXML", svg_parse_xml, 0, 0, 0}, + {0, 0, 0, 0, 0} }; JS_DefineFunctions(scene->svg_js->js_ctx, scene->svg_js->global, globalClassFuncs); JS_DefineProperties(scene->svg_js->js_ctx, scene->svg_js->global, globalClassProps); @@ -2010,11 +1966,10 @@ static void svg_init_js_api(GF_SceneGraph *scene) { JSPropertySpec svgDocumentProps[] = { - {"global", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - /*in our implementation, defaultView is just an alias to the global object*/ - {"defaultView", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - - {0} + /*in our implementation, defaultView is just an alias to the global Window object*/ + {"defaultView", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + + {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); @@ -2024,77 +1979,72 @@ static void svg_init_js_api(GF_SceneGraph *scene) { JSFunctionSpec svgElementFuncs[] = { /*trait access interface*/ - {"getTrait", svg_udom_get_trait, 1}, - {"getTraitNS", svg_udom_get_trait, 2}, - {"getFloatTrait", svg_udom_get_float_trait, 1}, - {"getMatrixTrait", svg_udom_get_matrix_trait, 1}, - {"getRectTrait", svg_udom_get_rect_trait, 1}, - {"getPathTrait", svg_udom_get_path_trait, 1}, - {"getRGBColorTrait", svg_udom_get_rgb_color_trait, 1}, + {"getTrait", svg_udom_get_trait, 1, 0, 0}, + {"getTraitNS", svg_udom_get_trait, 2, 0, 0}, + {"getFloatTrait", svg_udom_get_float_trait, 1, 0, 0}, + {"getMatrixTrait", svg_udom_get_matrix_trait, 1, 0, 0}, + {"getRectTrait", svg_udom_get_rect_trait, 1, 0, 0}, + {"getPathTrait", svg_udom_get_path_trait, 1, 0, 0}, + {"getRGBColorTrait", svg_udom_get_rgb_color_trait, 1, 0, 0}, /*FALLBACK TO BASE-VALUE FOR NOW - WILL NEED EITHER DOM TREE-CLONING OR A FAKE RENDER PASS FOR EACH PRESENTATION VALUE ACCESS*/ - {"getPresentationTrait", svg_udom_get_trait, 1}, - {"getPresentationTraitNS", svg_udom_get_trait, 2}, - {"getFloatPresentationTrait", svg_udom_get_float_trait, 1}, - {"getMatrixPresentationTrait", svg_udom_get_matrix_trait, 1}, - {"getRectPresentationTrait", svg_udom_get_rect_trait, 1}, - {"getPathPresentationTrait", svg_udom_get_path_trait, 1}, - {"getRGBColorPresentationTrait", svg_udom_get_rgb_color_trait, 1}, - {"setTrait", svg_udom_set_trait, 2}, - {"setTraitNS", svg_udom_set_trait, 3}, - {"setFloatTrait", svg_udom_set_float_trait, 2}, - {"setMatrixTrait", svg_udom_set_matrix_trait, 2}, - {"setRectTrait", svg_udom_set_rect_trait, 2}, - {"setPathTrait", svg_udom_set_path_trait, 2}, - {"setRGBColorTrait", svg_udom_set_rgb_color_trait, 2}, + {"getPresentationTrait", svg_udom_get_trait, 1, 0, 0}, + {"getPresentationTraitNS", svg_udom_get_trait, 2, 0, 0}, + {"getFloatPresentationTrait", svg_udom_get_float_trait, 1, 0, 0}, + {"getMatrixPresentationTrait", svg_udom_get_matrix_trait, 1, 0, 0}, + {"getRectPresentationTrait", svg_udom_get_rect_trait, 1, 0, 0}, + {"getPathPresentationTrait", svg_udom_get_path_trait, 1, 0, 0}, + {"getRGBColorPresentationTrait", svg_udom_get_rgb_color_trait, 1, 0, 0}, + {"setTrait", svg_udom_set_trait, 2, 0, 0}, + {"setTraitNS", svg_udom_set_trait, 3, 0, 0}, + {"setFloatTrait", svg_udom_set_float_trait, 2, 0, 0}, + {"setMatrixTrait", svg_udom_set_matrix_trait, 2, 0, 0}, + {"setRectTrait", svg_udom_set_rect_trait, 2, 0, 0}, + {"setPathTrait", svg_udom_set_path_trait, 2, 0, 0}, + {"setRGBColorTrait", svg_udom_set_rgb_color_trait, 2, 0, 0}, /*locatable interface*/ - {"getBBox", svg_udom_get_local_bbox, 0}, - {"getScreenCTM", svg_udom_get_screen_ctm, 0}, - {"getScreenBBox", svg_udom_get_screen_bbox, 0}, + {"getBBox", svg_udom_get_local_bbox, 0, 0, 0}, + {"getScreenCTM", svg_udom_get_screen_ctm, 0, 0, 0}, + {"getScreenBBox", svg_udom_get_screen_bbox, 0, 0, 0}, /*svgSVGElement interface*/ - {"createSVGMatrixComponents", svg_udom_create_matrix_components, 0}, - {"createSVGRect", svg_udom_create_rect, 0}, - {"createSVGPath", svg_udom_create_path, 0}, - {"createSVGRGBColor", svg_udom_create_color, 0}, - {"createSVGPoint", svg_udom_create_point, 0}, - - {"moveFocus", svg_udom_move_focus, 0}, - {"setFocus", svg_udom_set_focus, 0}, - {"getCurrentFocusedObject", svg_udom_get_focus, 0}, - {"getCurrentTime", svg_udom_get_time, 0}, - + {"createSVGMatrixComponents", svg_udom_create_matrix_components, 0, 0, 0}, + {"createSVGRect", svg_udom_create_rect, 0, 0, 0}, + {"createSVGPath", svg_udom_create_path, 0, 0, 0}, + {"createSVGRGBColor", svg_udom_create_color, 0, 0, 0}, + {"createSVGPoint", svg_udom_create_point, 0, 0, 0}, + + {"moveFocus", svg_udom_move_focus, 0, 0, 0}, + {"setFocus", svg_udom_set_focus, 0, 0, 0}, + {"getCurrentFocusedObject", svg_udom_get_focus, 0, 0, 0}, + {"getCurrentTime", svg_udom_get_time, 0, 0, 0}, + /*timeControl interface*/ - {"beginElementAt", svg_udom_smil_begin, 1}, - {"beginElement", svg_udom_smil_begin, 0}, - {"endElementAt", svg_udom_smil_end, 1}, - {"endElement", svg_udom_smil_end, 0}, - {"pauseElement", svg_udom_smil_pause, 0}, - {"resumeElement", svg_udom_smil_resume, 0}, - {0} + {"beginElementAt", svg_udom_smil_begin, 1, 0, 0}, + {"beginElement", svg_udom_smil_begin, 0, 0, 0}, + {"endElementAt", svg_udom_smil_end, 1, 0, 0}, + {"endElement", svg_udom_smil_end, 0, 0, 0}, + {"pauseElement", svg_udom_smil_pause, 0, 0, 0}, + {"resumeElement", svg_udom_smil_resume, 0, 0, 0}, + {0, 0, 0, 0, 0} }; JSPropertySpec svgElementProps[] = { /*svgElement interface*/ - {"id", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - /*elementTraversal interface - all SVGElement implement this*/ - {"firstElementChild", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"lastElementChild", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"previousElementSibling", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"nextElementSibling", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"id", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, /*svgSVGElement interface*/ - {"currentScale", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"currentRotate", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"currentTranslate", 7, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"viewport", 8, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"currentTime", 9, JSPROP_ENUMERATE | JSPROP_PERMANENT}, + {"currentScale", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"currentRotate", 6, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"currentTranslate", 7, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"viewport", 8, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"currentTime", 9, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, /*timeControl interface*/ - {"isPaused", 10, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"isPaused", 10, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, /*old SVG1.1 stuff*/ - {"ownerSVGElement", 11, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, + {"ownerSVGElement", 11, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, /*SVGElementInstance*/ - {"correspondingElement", 12, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {"correspondingUseElement", 13, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {0} + {"correspondingElement", 12, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {"correspondingUseElement", 13, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY, 0, 0}, + {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); @@ -2104,70 +2054,70 @@ static void svg_init_js_api(GF_SceneGraph *scene) /*RGBColor class*/ { JSPropertySpec rgbClassProps[] = { - {"red", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"green", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"blue", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {0} + {"red", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"green", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"blue", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT, 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); } /*SVGRect class*/ { JSPropertySpec rectClassProps[] = { - {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"width", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"height", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {0} + {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"width", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"height", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT, 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); } /*SVGPoint class*/ { JSPropertySpec pointClassProps[] = { - {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {0} + {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 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); } /*SVGMatrix class*/ { JSFunctionSpec matrixClassFuncs[] = { - {"getComponent", svg_mx2d_get_component, 1}, - {"mMultiply", svg_mx2d_multiply, 1}, - {"inverse", svg_mx2d_inverse, 0}, - {"mTranslate", svg_mx2d_translate, 2}, - {"mScale", svg_mx2d_scale, 1}, - {"mRotate", svg_mx2d_rotate, 1}, - {0} + {"getComponent", svg_mx2d_get_component, 1, 0, 0}, + {"mMultiply", svg_mx2d_multiply, 1, 0, 0}, + {"inverse", svg_mx2d_inverse, 0, 0, 0}, + {"mTranslate", svg_mx2d_translate, 2, 0, 0}, + {"mScale", svg_mx2d_scale, 1, 0, 0}, + {"mRotate", svg_mx2d_rotate, 1, 0, 0}, + {0, 0, 0, 0, 0} }; JSPropertySpec matrixClassProps[] = { - {"a", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"b", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"c", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"d", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"e", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {"f", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT }, - {0} + {"a", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"b", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"c", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"d", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"e", 4, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"f", 5, JSPROP_ENUMERATE | JSPROP_PERMANENT, 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); } /*SVGPath class*/ { JSFunctionSpec pathClassFuncs[] = { - {"getSegment", svg_path_get_segment, 1}, - {"getSegmentParam", svg_path_get_segment_param, 2}, - {"moveTo", svg_path_move_to, 2}, - {"lineTo", svg_path_line_to, 2}, - {"quadTo", svg_path_quad_to, 4}, - {"curveTo", svg_path_curve_to, 6}, - {"close", svg_path_close, 0}, - {0} + {"getSegment", svg_path_get_segment, 1, 0, 0}, + {"getSegmentParam", svg_path_get_segment_param, 2, 0, 0}, + {"moveTo", svg_path_move_to, 2, 0, 0}, + {"lineTo", svg_path_line_to, 2, 0, 0}, + {"quadTo", svg_path_quad_to, 4, 0, 0}, + {"curveTo", svg_path_curve_to, 6, 0, 0}, + {"close", svg_path_close, 0, 0, 0}, + {0, 0, 0, 0, 0} }; JSPropertySpec pathClassProps[] = { - {"numberOfSegments", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY}, - {0} + {"numberOfSegments", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT | 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); @@ -2199,23 +2149,30 @@ Bool svg_script_execute(GF_SceneGraph *sg, char *utf8_script, GF_DOM_Event *even strcat(szFuncName, "(evt)"); utf8_script = szFuncName; } + + gf_sg_lock_javascript(1); + prev_event = JS_GetPrivate(sg->svg_js->js_ctx, sg->svg_js->event); JS_SetPrivate(sg->svg_js->js_ctx, sg->svg_js->event, event); ret = JS_EvaluateScript(sg->svg_js->js_ctx, sg->svg_js->global, utf8_script, strlen(utf8_script), 0, 0, &rval); JS_SetPrivate(sg->svg_js->js_ctx, sg->svg_js->event, prev_event); - /*clean-up*/ - JS_GC(sg->svg_js->js_ctx); - if (ret==JS_FALSE) { char *sep = strchr(utf8_script, '('); - if (!sep) return 0; - sep[0] = 0; - JS_LookupProperty(sg->svg_js->js_ctx, sg->svg_js->global, utf8_script, &rval); - sep[0] = '('; - if (JSVAL_IS_VOID(rval)) return 0; + if (sep) { + sep[0] = 0; + ret = JS_LookupProperty(sg->svg_js->js_ctx, sg->svg_js->global, utf8_script, &rval); + sep[0] = '('; + } } - return 1; + + if (sg->svg_js->force_gc) { + JS_GC(sg->svg_js->js_ctx); + sg->svg_js->force_gc = 0; + } + gf_sg_lock_javascript(0); + + return (ret==JS_FALSE) ? 0 : 1; } static void svg_script_predestroy(GF_Node *n, void *eff, Bool is_destroy) @@ -2227,30 +2184,24 @@ static void svg_script_predestroy(GF_Node *n, void *eff, Bool is_destroy) if (svg_js->nb_scripts) { svg_js->nb_scripts--; + + /*detach this script from our object cache*/ + dom_js_pre_destroy(svg_js->js_ctx, n->sgprivate->scenegraph, n); + if (!svg_js->nb_scripts) { + dom_js_pre_destroy(svg_js->js_ctx, n->sgprivate->scenegraph, NULL); /*user-defined extensions*/ gf_sg_load_script_extensions(n->sgprivate->scenegraph, svg_js->js_ctx, svg_js->global, 1); gf_sg_ecmascript_del(svg_js->js_ctx); dom_js_unload(svg_js->js_ctx, svg_js->global); - free(svg_js); + gf_free(svg_js); n->sgprivate->scenegraph->svg_js = NULL; assert(svg_rt); svg_rt->nb_inst--; if (!svg_rt->nb_inst) { - free(svg_rt); + gf_free(svg_rt); svg_rt = NULL; } - } else { - u32 i, count; - /*detach this script from our object cache*/ - count = gf_list_count(n->sgprivate->scenegraph->objects); - for (i=0; i<count; i++) { - JSObject *obj = gf_list_get(n->sgprivate->scenegraph->objects, i); - GF_Node *a_node = JS_GetPrivate(svg_js->js_ctx, obj); - if (n==a_node) - JS_SetPrivate(svg_js->js_ctx, obj, NULL); - } - } } } @@ -2263,14 +2214,14 @@ static GF_Err JSScript_CreateSVGContext(GF_SceneGraph *sg) /*create new ecmascript context*/ svg_js->js_ctx = gf_sg_ecmascript_new(sg); if (!svg_js->js_ctx) { - free(svg_js); + gf_free(svg_js); return GF_SCRIPT_ERROR; } if (!svg_rt) { GF_SAFEALLOC(svg_rt, GF_SVGuDOM); JS_SETUP_CLASS(svg_rt->svgElement, "SVGElement", JSCLASS_HAS_PRIVATE, svg_element_getProperty, svg_element_setProperty, dom_element_finalize); JS_SETUP_CLASS(svg_rt->svgDocument, "SVGDocument", JSCLASS_HAS_PRIVATE, svg_doc_getProperty, JS_PropertyStub, dom_document_finalize); - JS_SETUP_CLASS(svg_rt->globalClass, "global", JSCLASS_HAS_PRIVATE, global_getProperty, JS_PropertyStub, JS_FinalizeStub); + JS_SETUP_CLASS(svg_rt->globalClass, "Window", JSCLASS_HAS_PRIVATE, global_getProperty, JS_PropertyStub, JS_FinalizeStub); JS_SETUP_CLASS(svg_rt->rgbClass, "SVGRGBColor", JSCLASS_HAS_PRIVATE, rgb_getProperty, rgb_setProperty, baseCI_finalize); JS_SETUP_CLASS(svg_rt->rectClass, "SVGRect", JSCLASS_HAS_PRIVATE, rect_getProperty, rect_setProperty, baseCI_finalize); JS_SETUP_CLASS(svg_rt->pointClass, "SVGPoint", JSCLASS_HAS_PRIVATE, point_getProperty, point_setProperty, baseCI_finalize); @@ -2315,7 +2266,7 @@ static Bool svg_js_load_script(GF_Node *script, char *file) GF_SVGJS *svg_js; svg_js = script->sgprivate->scenegraph->svg_js; - jsf = fopen(file, "rb"); + jsf = gf_f64_open(file, "rb"); if (!jsf) { GF_JSAPIParam par; GF_SceneGraph *scene = script->sgprivate->scenegraph; @@ -2325,17 +2276,17 @@ static Bool svg_js_load_script(GF_Node *script, char *file) abs_url = (char *) par.uri.url; if (abs_url) { - jsf = fopen(abs_url, "rb"); - free(abs_url); + jsf = gf_f64_open(abs_url, "rb"); + gf_free(abs_url); } } if (!jsf) return 0; - fseek(jsf, 0, SEEK_END); - fsize = ftell(jsf); - fseek(jsf, 0, SEEK_SET); - jsscript = malloc(sizeof(char)*(fsize+1)); - fread(jsscript, sizeof(char)*fsize, 1, jsf); + gf_f64_seek(jsf, 0, SEEK_END); + fsize = (u32) gf_f64_tell(jsf); + gf_f64_seek(jsf, 0, SEEK_SET); + jsscript = gf_malloc(sizeof(char)*(size_t)(fsize+1)); + fsize = fread(jsscript, sizeof(char), (size_t)fsize, jsf); fclose(jsf); jsscript[fsize] = 0; @@ -2346,52 +2297,26 @@ static Bool svg_js_load_script(GF_Node *script, char *file) return 1; } + gf_sg_lock_javascript(1); + ret = JS_EvaluateScript(svg_js->js_ctx, svg_js->global, jsscript, sizeof(char)*fsize, 0, 0, &rval); + + if (svg_js->force_gc) { + JS_GC(svg_js->js_ctx); + svg_js->force_gc = 0; + } + gf_sg_lock_javascript(0); + if (ret==JS_FALSE) success = 0; gf_dom_listener_process_add(script->sgprivate->scenegraph); - free(jsscript); + gf_free(jsscript); return success; } #include <gpac/download.h> #include <gpac/network.h> -/* Download is performed asynchronously, so the script loading must be performed in this function */ -static void JS_SVG_NetIO(void *cbck, GF_NETIO_Parameter *param) -{ - GF_Err e; - JSFileDownload *jsdnload = (JSFileDownload *)cbck; - GF_Node *node = jsdnload->node; - - e = param->error; - if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { - const char *szCache = gf_dm_sess_get_cache_name(jsdnload->sess); - if (!svg_js_load_script(jsdnload->node, (char *) szCache)) - e = GF_SCRIPT_ERROR; - else - e = GF_OK; - - } else { - if (!e) { - /* the download is going on */ - return; - } else { - /* there was an error during the download */ - } - } - - /*destroy current download session (ie, destroy ourselves)*/ - gf_dm_sess_del(jsdnload->sess); - free(jsdnload); - - if (e) { - GF_JSAPIParam par; - par.info.e = e; - par.info.msg = "Cannot fetch script"; - ScriptAction(node->sgprivate->scenegraph, GF_JSAPI_OP_MESSAGE, NULL, &par); - } -} void JSScript_LoadSVG(GF_Node *node) { @@ -2415,38 +2340,47 @@ void JSScript_LoadSVG(GF_Node *node) } /*if href download the script file*/ if (gf_node_get_attribute_by_tag(node, TAG_XLINK_ATT_href, 0, 0, &href_info) == GF_OK) { + GF_DownloadManager *dnld_man; GF_JSAPIParam par; char *url; GF_Err e; - JSFileDownload *jsdnload; XMLRI *xmlri = (XMLRI *)href_info.far_ptr; - - /* getting the base uri of the scene and concatenating */ - ScriptAction(node->sgprivate->scenegraph, GF_JSAPI_OP_GET_SCENE_URI, node, &par); - url = NULL; - if (par.uri.url) url = gf_url_concatenate(par.uri.url, xmlri->string); - if (!url) url = strdup(xmlri->string); + + /* getting a download manager */ + par.dnld_man = NULL; + ScriptAction(node->sgprivate->scenegraph, GF_JSAPI_OP_GET_DOWNLOAD_MANAGER, NULL, &par); + dnld_man = par.dnld_man; + + + /* resolve the uri of the script*/ + par.uri.nb_params = 0; + par.uri.url = xmlri->string; + ScriptAction(node->sgprivate->scenegraph, GF_JSAPI_OP_RESOLVE_URI, node, &par); + url = (char *)par.uri.url; /* if the file is local, we don't need to download it */ if (!strstr(url, "://") || !strnicmp(url, "file://", 7)) { svg_js_load_script(node, url); - } else { - - /* getting a download manager */ - par.dnld_man = NULL; - ScriptAction(node->sgprivate->scenegraph, GF_JSAPI_OP_GET_DOWNLOAD_MANAGER, NULL, &par); - if (par.dnld_man) { - - GF_SAFEALLOC(jsdnload, JSFileDownload); - jsdnload->node = node; - jsdnload->sess = gf_dm_sess_new(par.dnld_man, url, 0, JS_SVG_NetIO, jsdnload, &e); - if (!jsdnload->sess) { - free(jsdnload); + } else if (dnld_man) { + /*fetch the remote script synchronously and load it - cf section on script processing in SVG specs*/ + GF_DownloadSession *sess = gf_dm_sess_new(dnld_man, url, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL, &e); + if (sess) { + e = gf_dm_sess_process(sess); + if (e==GF_OK) { + const char *szCache = gf_dm_sess_get_cache_name(sess); + if (!svg_js_load_script(node, (char *) szCache)) + e = GF_SCRIPT_ERROR; } + gf_dm_sess_del(sess); + } + if (e) { + par.info.e = e; + par.info.msg = "Cannot fetch script"; + ScriptAction(node->sgprivate->scenegraph, GF_JSAPI_OP_MESSAGE, NULL, &par); } } - free(url); - } + gf_free(url); + } /*for scripts only, execute*/ else if (node->sgprivate->tag == TAG_SVG_script) { txt = svg_get_text_child(node); @@ -2459,6 +2393,18 @@ void JSScript_LoadSVG(GF_Node *node) } } + +#ifdef _DEBUG +//#define DUMP_DEF_AND_ROOT +#endif + +#ifdef DUMP_DEF_AND_ROOT +void dump_root(const char *name, void *rp, void *data) +{ + if (name[0]=='_') fprintf(stdout, "\t%s\n", name); +} +#endif + static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_Node *observer) { GF_DOMText *txt = NULL; @@ -2476,22 +2422,44 @@ static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_No /*not sure about this (cf test struct-use-205-t.svg)*/ if (!node->sgprivate->parents) return 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[DOM Events ] Executing script code from handler\n")); - svg_js = node->sgprivate->scenegraph->svg_js; +#ifndef GPAC_DISABLE_LOG + if ((gf_log_get_level() >= (GF_LOG_DEBUG)) && (gf_log_get_tools() & (GF_LOG_SCRIPT))) { + char *content; + if (hdl->js_fun_val) { + JSString *s = JS_DecompileFunction(svg_js->js_ctx, JS_ValueToFunction(svg_js->js_ctx, (jsval) hdl->js_fun_val), 0); + content = JS_GetStringBytes(s); + } else if (hdl->js_fun) { + JSString *s=JS_DecompileFunction(svg_js->js_ctx, (JSFunction *)hdl->js_fun, 0); + content = JS_GetStringBytes(s); + } else if (txt) { + content = txt->textContent; + } else { + content = "unknown"; + } + gf_log_lt(GF_LOG_DEBUG, GF_LOG_SCRIPT); + gf_log("[DOM Events ] Executing script code from handler: %s\n", content); + } +#endif + + gf_sg_lock_javascript(1); prev_event = JS_GetPrivate(svg_js->js_ctx, svg_js->event); /*break loops*/ - if (prev_event && (prev_event->type==event->type) && (prev_event->target==event->target)) + if (prev_event && (prev_event->type==event->type) && (prev_event->target==event->target)) { + gf_sg_lock_javascript(0); return 0; + } JS_SetPrivate(svg_js->js_ctx, svg_js->event, event); + svg_js->in_script = 1; + /*if an observer is being specified, use it*/ if (hdl->evt_listen_obj) __this = hdl->evt_listen_obj; /*compile the jsfun if any - 'this' is the associated observer*/ else __this = observer ? JSVAL_TO_OBJECT( dom_element_construct(svg_js->js_ctx, observer) ) : svg_js->global; if (txt && !hdl->js_fun) { - char *argn = "evt"; + const char *argn = "evt"; hdl->js_fun = JS_CompileFunction(svg_js->js_ctx, __this, NULL, 1, &argn, txt->textContent, strlen(txt->textContent), NULL, 0); } @@ -2511,15 +2479,39 @@ static Bool svg_script_execute_handler(GF_Node *node, GF_DOM_Event *event, GF_No } else { ret = JS_CallFunctionName(svg_js->js_ctx, hdl->evt_listen_obj, "handleEvent", 1, argv, &rval); } - } + } else if (JS_LookupProperty(svg_js->js_ctx, svg_js->global, txt->textContent, &fval) && !JSVAL_IS_VOID(fval) ) { - if (svg_script_execute(node->sgprivate->scenegraph, txt->textContent, event)) + if (svg_script_execute(node->sgprivate->scenegraph, txt->textContent, event)) ret = JS_FALSE; - } + } else { ret = JS_EvaluateScript(svg_js->js_ctx, __this, txt->textContent, strlen(txt->textContent), 0, 0, &rval); } JS_SetPrivate(svg_js->js_ctx, svg_js->event, prev_event); + if (txt ) hdl->js_fun=0; + + while (svg_js->force_gc) { + svg_js->force_gc = 0; + JS_GC(svg_js->js_ctx); + } + svg_js->in_script = 0; + + gf_sg_lock_javascript(0); + +#ifdef DUMP_DEF_AND_ROOT + if ((event->type==GF_EVENT_CLICK) || (event->type==GF_EVENT_MOUSEOVER)) { + NodeIDedItem *reg_node; + fprintf(stdout, "Node registry\n"); + reg_node = hdl->sgprivate->scenegraph->id_node; + while (reg_node) { + fprintf(stdout, "\t%s\n", reg_node->NodeName); + reg_node = reg_node->next; + } + + fprintf(stdout, "\n\nNamed roots:\n"); + JS_DumpNamedRoots(JS_GetRuntime(svg_js->js_ctx), dump_root, NULL); + } +#endif if (ret==JS_FALSE) { _ScriptMessage(node->sgprivate->scenegraph, GF_SCRIPT_ERROR, "SVG: Invalid handler textContent"); diff --git a/src/scenegraph/svg_types.c b/src/scenegraph/svg_types.c index 160dba1..e0000b7 100644 --- a/src/scenegraph/svg_types.c +++ b/src/scenegraph/svg_types.c @@ -74,13 +74,29 @@ void gf_svg_node_del(GF_Node *node) gf_smil_anim_delete_animations((GF_Node *)p); } if (p->sgprivate->tag==TAG_SVG_listener) { - /*remove from parent's listener list*/ + /*remove from target's listener list*/ GF_DOMEventTarget *evt = node->sgprivate->UserPrivate; node->sgprivate->UserPrivate = NULL; - gf_dom_listener_del(node, evt); + if (evt) + gf_list_del_item(evt->evt_list, p); +#if 0 + if (evt && (gf_node_get_attribute_by_tag(p, TAG_XMLEV_ATT_event, 0, 0, &info) == GF_OK)) { + u32 type = ((XMLEV_Event *)info.far_ptr)->type; + gf_sg_unregister_event_type(p->sgprivate->scenegraph, gf_dom_event_get_category(type)); + } +#endif + } + /*if this is a handler with a UserPrivate, this is a handler with an implicit listener + (eg handler with ev:event=""). Destroy the associated listener*/ + if (p->sgprivate->tag==TAG_SVG_handler) { + GF_Node *listener = p->sgprivate->UserPrivate; + if (listener && (listener->sgprivate->tag==TAG_SVG_listener)) { + gf_node_unregister(listener, NULL); +// gf_svg_node_del(listener); + } } /*remove this node from associated listeners*/ - else if (node->sgprivate->interact && node->sgprivate->interact->dom_evt) { + if (node->sgprivate->interact && node->sgprivate->interact->dom_evt) { u32 i, count; count = gf_dom_listener_count(node); for (i=0; i<count; i++) { @@ -92,14 +108,14 @@ void gf_svg_node_del(GF_Node *node) if (gf_svg_is_timing_tag(node->sgprivate->tag)) { SVGTimedAnimBaseElement *tap = (SVGTimedAnimBaseElement *)node; if (tap->animp) { - free(tap->animp); + gf_free(tap->animp); gf_smil_anim_remove_from_target((GF_Node *)tap, (GF_Node *)tap->xlinkp->href->target); } if (tap->timingp) { gf_smil_timing_delete_runtime_info((GF_Node *)tap, tap->timingp->runtime); - free(tap->timingp); + gf_free(tap->timingp); } - if (tap->xlinkp) free(tap->xlinkp); + if (tap->xlinkp) gf_free(tap->xlinkp); } gf_node_delete_attributes(node); @@ -187,13 +203,13 @@ void gf_svg_reset_path(SVG_PathData d) count = gf_list_count(d.commands); for (i = 0; i < count; i++) { u8 *command = (u8 *)gf_list_get(d.commands, i); - free(command); + gf_free(command); } gf_list_del(d.commands); count = gf_list_count(d.points); for (i = 0; i < count; i++) { SVG_Point *pt = (SVG_Point *)gf_list_get(d.points, i); - free(pt); + gf_free(pt); } gf_list_del(d.points); #endif @@ -289,8 +305,8 @@ void gf_smil_delete_times(GF_List *list) count = gf_list_count(list); for (i = 0; i < count; i++) { SMIL_Time *v = (SMIL_Time *)gf_list_get(list, i); - if (v->element_id) free(v->element_id); - free(v); + if (v->element_id) gf_free(v->element_id); + gf_free(v); } gf_list_del(list); } @@ -300,7 +316,7 @@ void gf_svg_delete_points(GF_List *list) u32 i, count = gf_list_count(list); for (i = 0; i < count; i++) { SVG_Point *p = (SVG_Point *)gf_list_get(list, i); - free(p); + gf_free(p); } gf_list_del(list); } @@ -310,7 +326,7 @@ void gf_svg_delete_coordinates(GF_List *list) u32 i, count = gf_list_count(list); for (i = 0; i < count; i++) { SVG_Coordinate *c = (SVG_Coordinate *)gf_list_get(list, i); - free(c); + gf_free(c); } gf_list_del(list); } @@ -318,7 +334,7 @@ void gf_svg_delete_coordinates(GF_List *list) void gf_svg_reset_iri(GF_SceneGraph *sg, XMLRI *iri) { if (!iri) return; - if (iri->string) free(iri->string); + if (iri->string) gf_free(iri->string); gf_node_unregister_iri(sg, iri); } @@ -326,7 +342,7 @@ void gf_svg_delete_paint(GF_SceneGraph *sg, SVG_Paint *paint) { if (!paint) return; if (paint->type == SVG_PAINT_URI && sg) gf_svg_reset_iri(sg, &paint->iri); - free(paint); + gf_free(paint); } static void svg_delete_one_anim_value(u8 anim_datatype, void *anim_value, GF_SceneGraph *sg) @@ -363,29 +379,29 @@ void gf_svg_delete_attribute_value(u32 type, void *value, GF_SceneGraph *sg) case XMLRI_datatype: case XML_IDREF_datatype: gf_svg_reset_iri(sg, (XMLRI *)value); - free(value); + gf_free(value); break; case SVG_Focus_datatype: gf_svg_reset_iri(sg, & ((SVG_Focus*)value)->target); - free(value); + gf_free(value); break; case SVG_PathData_datatype: #if USE_GF_PATH gf_path_del((GF_Path *)value); #else - free(value); + gf_free(value); #endif break; case SVG_ID_datatype: case DOM_String_datatype: case SVG_ContentType_datatype: case SVG_LanguageID_datatype: - if (*(SVG_String *)value) free(*(SVG_String *)value); - free(value); + if (*(SVG_String *)value) gf_free(*(SVG_String *)value); + gf_free(value); break; case SVG_StrokeDashArray_datatype: - if (((SVG_StrokeDashArray*)value)->array.vals) free(((SVG_StrokeDashArray*)value)->array.vals); - free(value); + if (((SVG_StrokeDashArray*)value)->array.vals) gf_free(((SVG_StrokeDashArray*)value)->array.vals); + gf_free(value); break; case SVG_Numbers_datatype: case SVG_Coordinates_datatype: @@ -394,57 +410,57 @@ void gf_svg_delete_attribute_value(u32 type, void *value, GF_SceneGraph *sg) while (gf_list_count(l)) { void *n = gf_list_last(l); gf_list_rem_last(l); - free(n); + gf_free(n); } gf_list_del(l); - free(value); + gf_free(value); break; case SVG_FontFamily_datatype: { SVG_FontFamily *ff = (SVG_FontFamily *)value; - if (ff->value) free(ff->value); - free(value); + if (ff->value) gf_free(ff->value); + gf_free(value); } break; case SMIL_AttributeName_datatype: { SMIL_AttributeName *an = (SMIL_AttributeName *)value; - if (an->name) free(an->name); - free(value); + if (an->name) gf_free(an->name); + gf_free(value); } break; case SMIL_Times_datatype: gf_smil_delete_times(*(SMIL_Times *)value); - free(value); + gf_free(value); break; case SMIL_AnimateValue_datatype: svg_delete_one_anim_value(((SMIL_AnimateValue *)value)->type, ((SMIL_AnimateValue *)value)->value, sg); - free(value); + gf_free(value); break; case SMIL_AnimateValues_datatype: gf_svg_reset_animate_values(*((SMIL_AnimateValues *)value), sg); - free(value); + gf_free(value); break; case DOM_StringList_datatype: l = *(GF_List**)value; while (gf_list_count(l)) { char *n = gf_list_last(l); gf_list_rem_last(l); - free(n); + gf_free(n); } gf_list_del(l); - free(value); + gf_free(value); break; case XMLRI_List_datatype: l = *(GF_List**)value; while (gf_list_count(l)) { XMLRI *r = gf_list_last(l); gf_list_rem_last(l); - if (r->string) free(r->string); - free(r); + if (r->string) gf_free(r->string); + gf_free(r); } gf_list_del(l); - free(value); + gf_free(value); break; case SMIL_KeyTimes_datatype: case SMIL_KeySplines_datatype: @@ -452,10 +468,10 @@ void gf_svg_delete_attribute_value(u32 type, void *value, GF_SceneGraph *sg) while (gf_list_count(l)) { Fixed *f = gf_list_last(l); gf_list_rem_last(l); - free(f); + gf_free(f); } gf_list_del(l); - free(value); + gf_free(value); break; case SMIL_RepeatCount_datatype: @@ -465,7 +481,7 @@ void gf_svg_delete_attribute_value(u32 type, void *value, GF_SceneGraph *sg) case SVG_Visibility_datatype: case SVG_Display_datatype: default: - free(value); + gf_free(value); } } @@ -475,7 +491,7 @@ void gf_smil_delete_key_types(GF_List *l) while (gf_list_count(l)) { Fixed *t = (Fixed *)gf_list_get(l, 0); gf_list_rem(l, 0); - free(t); + gf_free(t); } gf_list_del(l); } diff --git a/src/scenegraph/vrml_interpolators.c b/src/scenegraph/vrml_interpolators.c index cb42f1b..6bea733 100644 --- a/src/scenegraph/vrml_interpolators.c +++ b/src/scenegraph/vrml_interpolators.c @@ -28,6 +28,43 @@ #include <gpac/nodes_x3d.h> +GF_EXPORT +SFRotation gf_sg_sfrotation_interpolate(SFRotation kv1, SFRotation kv2, Fixed fraction) +{ + SFRotation res; + Fixed newa, olda; + Bool stzero = ( ABS(kv1.q) < FIX_EPSILON) ? 1 : 0; + Bool endzero = ( ABS(kv2.q) < FIX_EPSILON) ? 1 : 0; + Fixed testa = gf_mulfix(kv1.x, kv2.x) + gf_mulfix(kv1.y, kv2.y) + gf_mulfix(kv1.y, kv2.y); + + if (testa>= 0) { + res.x = kv1.x + gf_mulfix(fraction, kv2.x-kv1.x); + res.y = kv1.y + gf_mulfix(fraction, kv2.y-kv1.y); + res.z = kv1.z + gf_mulfix(fraction, kv2.z-kv1.z); + newa = kv2.q; + } else { + res.x = kv1.x + gf_mulfix(fraction, -kv2.x -kv1.x); + res.y = kv1.y + gf_mulfix(fraction, -kv2.y-kv1.y); + res.z = kv1.z + gf_mulfix(fraction, -kv2.z-kv1.z); + newa = -kv2.q; + } + olda = kv1.q; + if (stzero || endzero) { + res.x = stzero ? kv2.x : kv1.x; + res.y = stzero ? kv2.y : kv1.y; + res.z = stzero ? kv2.z : kv1.z; + } + res.q = olda + gf_mulfix(fraction, newa - olda); + if (res.q > GF_2PI) { + res.q -= GF_2PI; + } else if (res.q < GF_2PI) { + res.q += GF_2PI; + } + return res; +} + +#ifndef GPAC_DISABLE_VRML + static Fixed Interpolate(Fixed keyValue1, Fixed keyValue2, Fixed fraction) { return gf_mulfix(keyValue2 - keyValue1, fraction) + keyValue1; @@ -41,7 +78,7 @@ static Fixed GetInterpolateFraction(Fixed key1, Fixed key2, Fixed fraction) return gf_divfix(fraction - key1, keyDiff); } -static void CI2D_SetFraction(GF_Node *n) +static void CI2D_SetFraction(GF_Node *n, GF_Route *route) { Fixed frac; u32 numElemPerKey, i, j; @@ -141,7 +178,7 @@ static Bool CI_SetFraction(Fixed fraction, MFVec3f *vals, MFFloat *key, MFVec3f } -static void CoordInt_SetFraction(GF_Node *n) +static void CoordInt_SetFraction(GF_Node *n, GF_Route *route) { M_CoordinateInterpolator *_this = (M_CoordinateInterpolator *) n; @@ -156,7 +193,7 @@ Bool InitCoordinateInterpolator(M_CoordinateInterpolator *n) return 1; } -static void NormInt_SetFraction(GF_Node *n) +static void NormInt_SetFraction(GF_Node *n, GF_Route *route) { u32 i; M_NormalInterpolator *_this = (M_NormalInterpolator *) n; @@ -176,7 +213,7 @@ Bool InitNormalInterpolator(M_NormalInterpolator *n) return 1; } -static void ColorInt_SetFraction(GF_Node *node) +static void ColorInt_SetFraction(GF_Node *node, GF_Route *route) { u32 i; Fixed frac; @@ -221,7 +258,7 @@ Bool InitColorInterpolator(M_ColorInterpolator *node) } -static void PosInt2D_SetFraction(GF_Node *node) +static void PosInt2D_SetFraction(GF_Node *node, GF_Route *route) { M_PositionInterpolator2D *_this = (M_PositionInterpolator2D *)node; u32 i; @@ -257,7 +294,7 @@ Bool InitPositionInterpolator2D(M_PositionInterpolator2D *node) return 1; } -static void PosInt_SetFraction(GF_Node *node) +static void PosInt_SetFraction(GF_Node *node, GF_Route *route) { u32 i; Fixed frac; @@ -294,7 +331,7 @@ Bool InitPositionInterpolator(M_PositionInterpolator *node) return 1; } -static void ScalarInt_SetFraction(GF_Node *node) +static void ScalarInt_SetFraction(GF_Node *node, GF_Route *route) { M_ScalarInterpolator *_this = (M_ScalarInterpolator *)node; u32 i; @@ -328,42 +365,8 @@ Bool InitScalarInterpolator(M_ScalarInterpolator *node) return 1; } -GF_EXPORT -SFRotation gf_sg_sfrotation_interpolate(SFRotation kv1, SFRotation kv2, Fixed fraction) -{ - SFRotation res; - Fixed newa, olda; - Bool stzero = ( ABS(kv1.q) < FIX_EPSILON) ? 1 : 0; - Bool endzero = ( ABS(kv2.q) < FIX_EPSILON) ? 1 : 0; - Fixed testa = gf_mulfix(kv1.x, kv2.x) + gf_mulfix(kv1.y, kv2.y) + gf_mulfix(kv1.y, kv2.y); - - if (testa>= 0) { - res.x = kv1.x + gf_mulfix(fraction, kv2.x-kv1.x); - res.y = kv1.y + gf_mulfix(fraction, kv2.y-kv1.y); - res.z = kv1.z + gf_mulfix(fraction, kv2.z-kv1.z); - newa = kv2.q; - } else { - res.x = kv1.x + gf_mulfix(fraction, -kv2.x -kv1.x); - res.y = kv1.y + gf_mulfix(fraction, -kv2.y-kv1.y); - res.z = kv1.z + gf_mulfix(fraction, -kv2.z-kv1.z); - newa = -kv2.q; - } - olda = kv1.q; - if (stzero || endzero) { - res.x = stzero ? kv2.x : kv1.x; - res.y = stzero ? kv2.y : kv1.y; - res.z = stzero ? kv2.z : kv1.z; - } - res.q = olda + gf_mulfix(fraction, newa - olda); - if (res.q > GF_2PI) { - res.q -= GF_2PI; - } else if (res.q < GF_2PI) { - res.q += GF_2PI; - } - return res; -} -static void OrientInt_SetFraction(GF_Node *node) +static void OrientInt_SetFraction(GF_Node *node, GF_Route *route) { u32 i; Fixed frac; @@ -398,7 +401,7 @@ Bool InitOrientationInterpolator(M_OrientationInterpolator *node) return 1; } -static void CI4D_SetFraction(GF_Node *n) +static void CI4D_SetFraction(GF_Node *n, GF_Route *route) { Fixed frac; u32 numElemPerKey, i, j; @@ -460,7 +463,7 @@ Bool InitCoordinateInterpolator4D(M_CoordinateInterpolator4D *node) return 1; } -static void PI4D_SetFraction(GF_Node *node) +static void PI4D_SetFraction(GF_Node *node, GF_Route *route) { u32 i; Fixed frac; @@ -500,7 +503,9 @@ Bool InitPositionInterpolator4D(M_PositionInterpolator4D *node) -static void BooleanFilter_setValue(GF_Node *n) +#ifndef GPAC_DISABLE_X3D + +static void BooleanFilter_setValue(GF_Node *n, GF_Route *route) { X_BooleanFilter *bf = (X_BooleanFilter *)n; if (!bf->set_boolean) { @@ -521,7 +526,7 @@ void InitBooleanFilter(GF_Node *n) bf->on_set_boolean = BooleanFilter_setValue; } -static void BooleanSequencer_setFraction(GF_Node *n) +static void BooleanSequencer_setFraction(GF_Node *n, GF_Route *route) { u32 i; X_BooleanSequencer *bs = (X_BooleanSequencer*)n; @@ -543,7 +548,7 @@ static void BooleanSequencer_setFraction(GF_Node *n) gf_node_event_out(n, 3);//"value_changed" } -static void BooleanSequencer_setNext(GF_Node *n) +static void BooleanSequencer_setNext(GF_Node *n, GF_Route *route) { s32 *prev_val, val; X_BooleanSequencer *bs = (X_BooleanSequencer*)n; @@ -556,7 +561,7 @@ static void BooleanSequencer_setNext(GF_Node *n) gf_node_event_out(n, 3);//"value_changed" } -static void BooleanSequencer_setPrevious(GF_Node *n) +static void BooleanSequencer_setPrevious(GF_Node *n, GF_Route *route) { s32 *prev_val, val; X_BooleanSequencer *bs = (X_BooleanSequencer*)n; @@ -574,7 +579,7 @@ static void DestroyBooleanSequencer(GF_Node *n, void *eff, Bool is_destroy) { if (is_destroy) { s32 *st = (s32 *) gf_node_get_private(n); - free(st); + gf_free(st); } } void InitBooleanSequencer(GF_Node *n) @@ -583,12 +588,12 @@ void InitBooleanSequencer(GF_Node *n) bs->on_next = BooleanSequencer_setNext; bs->on_previous = BooleanSequencer_setPrevious; bs->on_set_fraction = BooleanSequencer_setFraction; - n->sgprivate->UserPrivate = malloc(sizeof(s32)); + n->sgprivate->UserPrivate = gf_malloc(sizeof(s32)); *(s32 *)n->sgprivate->UserPrivate = 0; n->sgprivate->UserCallback = DestroyBooleanSequencer; } -static void BooleanToggle_setValue(GF_Node *n) +static void BooleanToggle_setValue(GF_Node *n, GF_Route *route) { X_BooleanToggle *bt = (X_BooleanToggle *)n; if (bt->set_boolean) { @@ -602,7 +607,7 @@ void InitBooleanToggle(GF_Node *n) bt->on_set_boolean = BooleanToggle_setValue; } -static void BooleanTrigger_setTime(GF_Node *n) +static void BooleanTrigger_setTime(GF_Node *n, GF_Route *route) { X_BooleanTrigger *bt = (X_BooleanTrigger *)n; bt->triggerTrue = 1; @@ -614,7 +619,7 @@ void InitBooleanTrigger(GF_Node *n) bt->on_set_triggerTime = BooleanTrigger_setTime; } -static void IntegerSequencer_setFraction(GF_Node *n) +static void IntegerSequencer_setFraction(GF_Node *n, GF_Route *route) { u32 i; X_IntegerSequencer *is = (X_IntegerSequencer *)n; @@ -636,7 +641,7 @@ static void IntegerSequencer_setFraction(GF_Node *n) gf_node_event_out(n, 3);//"value_changed" } -static void IntegerSequencer_setNext(GF_Node *n) +static void IntegerSequencer_setNext(GF_Node *n, GF_Route *route) { s32 *prev_val, val; X_IntegerSequencer *is = (X_IntegerSequencer*)n; @@ -649,7 +654,7 @@ static void IntegerSequencer_setNext(GF_Node *n) gf_node_event_out(n, 3);//"value_changed" } -static void IntegerSequencer_setPrevious(GF_Node *n) +static void IntegerSequencer_setPrevious(GF_Node *n, GF_Route *route) { s32 *prev_val, val; X_IntegerSequencer *is = (X_IntegerSequencer *)n; @@ -667,7 +672,7 @@ static void DestroyIntegerSequencer(GF_Node *n, void *eff, Bool is_destroy) { if (is_destroy) { s32 *st = (s32 *)gf_node_get_private(n); - free(st); + gf_free(st); } } void InitIntegerSequencer(GF_Node *n) @@ -676,12 +681,12 @@ void InitIntegerSequencer(GF_Node *n) bs->on_next = IntegerSequencer_setNext; bs->on_previous = IntegerSequencer_setPrevious; bs->on_set_fraction = IntegerSequencer_setFraction; - n->sgprivate->UserPrivate = malloc(sizeof(s32)); + n->sgprivate->UserPrivate = gf_malloc(sizeof(s32)); *(s32 *)n->sgprivate->UserPrivate = 0; n->sgprivate->UserCallback = DestroyIntegerSequencer; } -static void IntegerTrigger_setTrigger(GF_Node *n) +static void IntegerTrigger_setTrigger(GF_Node *n, GF_Route *route) { X_IntegerTrigger *it = (X_IntegerTrigger *)n; if (it->set_boolean) { @@ -695,7 +700,7 @@ void InitIntegerTrigger(GF_Node *n) it->on_set_boolean = IntegerTrigger_setTrigger; } -static void TimeTrigger_setTrigger(GF_Node *n) +static void TimeTrigger_setTrigger(GF_Node *n, GF_Route *route) { X_TimeTrigger *tt = (X_TimeTrigger *)n; tt->triggerTime = gf_node_get_scene_time(n); @@ -707,3 +712,7 @@ void InitTimeTrigger(GF_Node *n) tt->on_set_boolean = TimeTrigger_setTrigger; } +#endif /*GPAC_DISABLE_X3D*/ + + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/scenegraph/vrml_proto.c b/src/scenegraph/vrml_proto.c index c4e8751..58883ab 100644 --- a/src/scenegraph/vrml_proto.c +++ b/src/scenegraph/vrml_proto.c @@ -28,6 +28,8 @@ #include <gpac/nodes_mpeg4.h> #include <gpac/nodes_x3d.h> +#ifndef GPAC_DISABLE_VRML + GF_Proto *gf_sg_proto_new(GF_SceneGraph *inScene, u32 ProtoID, char *name, Bool unregistered) { @@ -50,9 +52,9 @@ GF_Proto *gf_sg_proto_new(GF_SceneGraph *inScene, u32 ProtoID, char *name, Bool tmp->instances = gf_list_new(); if (name) - tmp->Name = strdup(name); + tmp->Name = gf_strdup(name); else - tmp->Name = strdup("Unnamed Proto"); + tmp->Name = gf_strdup("Unnamed Proto"); tmp->ID = ProtoID; if (!unregistered) { gf_list_add(inScene->protos, tmp); @@ -128,12 +130,12 @@ GF_Err gf_sg_proto_del(GF_Proto *proto) else if (field->def_value) gf_sg_vrml_field_pointer_del(field->def_value, field->FieldType); - if (field->FieldName) free(field->FieldName); + if (field->FieldName) gf_free(field->FieldName); - /*QP fields are SF fields, we can safely free() them*/ - if (field->qp_max_value) free(field->qp_max_value); - if (field->qp_min_value) free(field->qp_min_value); - free(field); + /*QP fields are SF fields, we can safely gf_free() them*/ + if (field->qp_max_value) gf_free(field->qp_max_value); + if (field->qp_min_value) gf_free(field->qp_min_value); + gf_free(field); gf_list_rem(proto->proto_fields, 0); } gf_list_del(proto->proto_fields); @@ -148,10 +150,10 @@ GF_Err gf_sg_proto_del(GF_Proto *proto) gf_sg_del(proto->sub_graph); - if (proto->Name) free(proto->Name); + if (proto->Name) gf_free(proto->Name); gf_sg_mfurl_del(proto->ExternProto); gf_list_del(proto->instances); - free(proto); + gf_free(proto); return GF_OK; } @@ -219,7 +221,7 @@ GF_ProtoFieldInterface *gf_sg_proto_field_new(GF_Proto *proto, u32 fieldType, u3 tmp->def_value = gf_sg_vrml_field_pointer_new(fieldType); } - if (fieldName) tmp->FieldName = strdup(fieldName); + if (fieldName) tmp->FieldName = gf_strdup(fieldName); tmp->ALL_index = gf_list_count(proto->proto_fields); tmp->OUT_index = tmp->DEF_index = tmp->IN_index = (u32) -1; @@ -367,11 +369,12 @@ GF_Node *gf_vrml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *clon if (inst_id_suffix[0] && id) { id = gf_sg_get_next_available_node_id(inScene); if (orig_name) { - szNodeName = malloc(sizeof(char)*(strlen(orig_name)+strlen(inst_id_suffix)+1)); + szNodeName = gf_malloc(sizeof(char)*(strlen(orig_name)+strlen(inst_id_suffix)+1)); strcpy(szNodeName, orig_name); strcat(szNodeName, inst_id_suffix); } - } + } + else if (orig_name) szNodeName = gf_strdup(orig_name); } if (id) { @@ -379,7 +382,7 @@ GF_Node *gf_vrml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *clon /*node already created, USE*/ if (node) { gf_node_register(node, cloned_parent); - if (inst_id_suffix[0] && szNodeName) free(szNodeName); + if (szNodeName) gf_free(szNodeName); return node; } } @@ -395,9 +398,23 @@ GF_Node *gf_vrml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *clon count = gf_node_get_field_count(orig); is_script = 0; - if ((orig->sgprivate->tag==TAG_MPEG4_Script) || (orig->sgprivate->tag==TAG_X3D_Script)) is_script = 1; + if ((orig->sgprivate->tag==TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (orig->sgprivate->tag==TAG_X3D_Script) +#endif + ) + is_script = 1; + if (is_script) gf_sg_script_prepare_clone(node, orig); + + /*register node*/ + if (id) { + gf_node_set_id(node, id, szNodeName); + if (szNodeName) gf_free(szNodeName); + } + gf_node_register(node, cloned_parent); + /*copy each field*/ for (i=0; i<count; i++) { gf_node_get_field(orig, i, &field_orig); @@ -435,7 +452,7 @@ GF_Node *gf_vrml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *clon } break; default: - gf_sg_vrml_field_copy(field.far_ptr, field_orig.far_ptr, field.fieldType); + gf_sg_vrml_field_clone(field.far_ptr, field_orig.far_ptr, field.fieldType, inScene); break; } } @@ -446,24 +463,14 @@ GF_Node *gf_vrml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *clon M_InputSensor *clone_is = (M_InputSensor *)node; M_InputSensor *orig_is = (M_InputSensor *)orig; while ( (com_o = (GF_Command *)gf_list_enum(orig_is->buffer.commandList, &k) ) ) { - com_f = gf_sg_command_clone(com_o, node->sgprivate->scenegraph, 1); + com_f = gf_sg_vrml_command_clone(com_o, node->sgprivate->scenegraph, 1); gf_list_add(clone_is->buffer.commandList, com_f); } } - /*register node*/ - if (id) { - gf_node_set_id(node, id, szNodeName); - if (inst_id_suffix[0] && szNodeName) free(szNodeName); - } - gf_node_register(node, cloned_parent); - -#ifndef GPAC_READ_ONLY /*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 -#endif - if (node->sgprivate->tag != TAG_ProtoNode) gf_node_init(node); + else if (node->sgprivate->tag != TAG_ProtoNode) gf_node_init(node); if (!inScene->pOwningProto) return node; proto = inScene->pOwningProto; @@ -511,14 +518,15 @@ GF_Err gf_sg_proto_get_field_ind_static(GF_Node *Node, u32 inField, u8 IndexMode } -static Bool is_same_proto(GF_Proto *p1, GF_Proto *p2) +static Bool is_same_proto(GF_Proto *extern_proto, GF_Proto *proto) { u32 i, count; - if (gf_list_count(p1->proto_fields) != gf_list_count(p2->proto_fields)) return 0; - count = gf_list_count(p1->proto_fields); + /*CRML allows external protos to have more fields defined that the externProto referencing them*/ + if (gf_list_count(extern_proto->proto_fields) > gf_list_count(proto->proto_fields)) return 0; + count = gf_list_count(extern_proto->proto_fields); for (i=0; i<count; i++) { - GF_ProtoFieldInterface *pf1 = (GF_ProtoFieldInterface*)gf_list_get(p1->proto_fields, i); - GF_ProtoFieldInterface *pf2 = (GF_ProtoFieldInterface*)gf_list_get(p2->proto_fields, i); + GF_ProtoFieldInterface *pf1 = (GF_ProtoFieldInterface*)gf_list_get(extern_proto->proto_fields, i); + GF_ProtoFieldInterface *pf2 = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, i); if (pf1->EventType != pf2->EventType) return 0; if (pf1->FieldType != pf2->FieldType) return 0; /*note we don't check names since we're not sure both protos use name coding (MPEG4 only)*/ @@ -526,7 +534,7 @@ static Bool is_same_proto(GF_Proto *p1, GF_Proto *p2) return 1; } -static GF_Proto *SG_FindProtoByInterface(GF_SceneGraph *sg, GF_Proto *the_proto) +static GF_Proto *find_proto_by_interface(GF_SceneGraph *sg, GF_Proto *extern_proto) { GF_Proto *proto; u32 i, count; @@ -536,16 +544,17 @@ static GF_Proto *SG_FindProtoByInterface(GF_SceneGraph *sg, GF_Proto *the_proto) /*browse all top-level */ i=0; while ((proto = (GF_Proto*)gf_list_enum(sg->protos, &i))) { - if (is_same_proto(proto, the_proto)) return proto; + if (is_same_proto(proto, extern_proto)) return proto; } /*browse all top-level unregistered in reverse order*/ count = gf_list_count(sg->unregistered_protos); for (i=count; i>0; i--) { proto = (GF_Proto*)gf_list_get(sg->unregistered_protos, i-1); - if (is_same_proto(proto, the_proto)) return proto; + if (is_same_proto(proto, extern_proto)) return proto; } return NULL; } + /*performs common initialization of routes ISed fields and protos once everything is loaded*/ void gf_sg_proto_instanciate(GF_ProtoInstance *proto_node) { @@ -567,6 +576,15 @@ void gf_sg_proto_instanciate(GF_ProtoInstance *proto_node) /*this is an hardcoded proto - all routes, node modifications and co are handled internally*/ if (extern_lib == GF_SG_INTERNAL_PROTO) { proto_node->sgprivate->flags |= GF_SG_NODE_DIRTY; + // take default values + count = gf_list_count(owner->proto_fields); + for (i=0; i<count; i++) { + GF_ProtoField *pf = (GF_ProtoField *)gf_list_get(proto_node->fields, i); + if (!pf->has_been_accessed) { + pfi = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, i); + gf_sg_vrml_field_copy(pf->field_pointer, pfi->def_value, pfi->FieldType); + } + } owner->parent_graph->NodeCallback(owner->parent_graph->userpriv, GF_SG_CALLBACK_INIT, (GF_Node *) proto_node, NULL); return; } @@ -588,10 +606,15 @@ void gf_sg_proto_instanciate(GF_ProtoInstance *proto_node) proto = gf_sg_find_proto(extern_lib, ID, szName); } if (!proto) proto = gf_sg_find_proto(extern_lib, owner->ID, owner->Name); - if (!proto) proto = SG_FindProtoByInterface(extern_lib, owner); + if (!proto) proto = find_proto_by_interface(extern_lib, owner); + + if (proto && !is_same_proto(owner, proto)) { + proto = NULL; + GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[Scenegraph] fields/types mismatch for PROTO %s - skipping instantiation\n", owner->Name)); + } /*couldn't find proto in the given lib, consider the proto as loaded (give up)*/ if (!proto) { - proto_node->is_loaded = 1; + proto_node->flags |= GF_SG_PROTO_LOADED; return; } /*cf VRML: once an external proto is loaded, copy back the default field values of the external proto*/ @@ -601,6 +624,8 @@ void gf_sg_proto_instanciate(GF_ProtoInstance *proto_node) if (!pf->has_been_accessed) { pfi = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, i); gf_sg_vrml_field_copy(pf->field_pointer, pfi->def_value, pfi->FieldType); + } else { + pfi = (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, i); } } @@ -660,10 +685,26 @@ void gf_sg_proto_instanciate(GF_ProtoInstance *proto_node) if (!route->IS_route || !route->ToNode) continue; /* assert(route->is_setup); if ((route->FromField.eventType == GF_SG_EVENT_OUT) || (route->FromField.eventType == GF_SG_EVENT_IN) ) continue; -*/ if ((route->ToNode->sgprivate->tag==TAG_MPEG4_Script) || (route->ToNode->sgprivate->tag==TAG_X3D_Script) ) +*/ + if ((route->ToNode->sgprivate->tag==TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (route->ToNode->sgprivate->tag==TAG_X3D_Script) +#endif + ) gf_sg_route_activate(route); } - proto_node->is_loaded = 1; + +#if 0 + /*reset all regular route activation times - if we don't do so, creating a proto by script and then manipulating one of its + ISed field may not trigger the proper routes*/ + i=0; + while ((route = (GF_Route*)gf_list_enum(proto_node->sgprivate->scenegraph->Routes, &i))) { + if (!route->IS_route) { + route->lastActivateTime = 0; + } + } +#endif + proto_node->flags |= GF_SG_PROTO_LOADED; } void gf_sg_proto_mark_field_loaded(GF_Node *proto_inst, GF_FieldInfo *info) @@ -691,7 +732,7 @@ GF_Node *gf_sg_proto_create_node(GF_SceneGraph *scene, GF_Proto *proto, GF_Proto proto_node->proto_interface = proto; gf_list_add(proto->instances, proto_node); - proto_node->proto_name = strdup(proto->Name); + proto_node->proto_name = gf_strdup(proto->Name); /*create the namespace*/ proto_node->sgprivate->scenegraph = gf_sg_new_subscene(scene); @@ -738,7 +779,7 @@ GF_Err gf_sg_proto_load_code(GF_Node *node) if (node->sgprivate->tag != TAG_ProtoNode) return GF_BAD_PARAM; inst = (GF_ProtoInstance *) node; if (!inst->proto_interface) return GF_BAD_PARAM; - if (inst->is_loaded) return GF_OK; + if (inst->flags & GF_SG_PROTO_LOADED) return GF_OK; gf_sg_proto_instanciate(inst); return GF_OK; } @@ -790,12 +831,12 @@ void gf_sg_proto_del_instance(GF_ProtoInstance *inst) GF_ChildNodeItem *cur = list; gf_node_unregister(list->node, (GF_Node *) inst); list = list->next; - free(cur); + gf_free(cur); } } } - free(field); + gf_free(field); index++; } gf_list_del(inst->fields); @@ -815,7 +856,7 @@ void gf_sg_proto_del_instance(GF_ProtoInstance *inst) sg = inst->sgprivate->scenegraph; - free((char *) inst->proto_name); + gf_free((char *) inst->proto_name); sg->pOwningProto = NULL; /*and finally destroy the node. If the proto is a hardcoded one (UserCallback set), destroy the node first @@ -824,8 +865,9 @@ void gf_sg_proto_del_instance(GF_ProtoInstance *inst) gf_node_free((GF_Node *)inst); gf_sg_del(sg); } else { - gf_sg_del(sg); + gf_sg_reset(sg); gf_node_free((GF_Node *)inst); + gf_sg_del(sg); } } @@ -874,6 +916,25 @@ GF_Err gf_sg_proto_field_set_ised(GF_Proto *proto, u32 protoFieldIndex, GF_Node r->FromNode = NULL; r->ToField.fieldIndex = nodeFieldIndex; r->ToNode = node; + /*create an ISed route for the eventOut part of the exposedFIeld*/ + if ((field.eventType==GF_SG_EVENT_EXPOSED_FIELD) && (nodeField.eventType==GF_SG_EVENT_EXPOSED_FIELD)) { + GF_Route *r2; + GF_SAFEALLOC(r2, GF_Route); + if (!r2) { + gf_free(r); + return GF_OUT_OF_MEM; + } + r2->IS_route = 1; + r2->FromField.fieldIndex = nodeFieldIndex; + r2->FromNode = node; + r2->ToField.fieldIndex = protoFieldIndex; + r2->ToNode = NULL; + r2->graph = proto->sub_graph; + if (!node->sgprivate->interact) GF_SAFEALLOC(node->sgprivate->interact, struct _node_interactive_ext); + if (!node->sgprivate->interact->routes) node->sgprivate->interact->routes = gf_list_new(); + gf_list_add(node->sgprivate->interact->routes, r2); + gf_list_add(proto->sub_graph->Routes, r2); + } break; case GF_SG_EVENT_OUT: r->FromField.fieldIndex = nodeFieldIndex; @@ -884,7 +945,7 @@ GF_Err gf_sg_proto_field_set_ised(GF_Proto *proto, u32 protoFieldIndex, GF_Node if (!node->sgprivate->interact->routes) node->sgprivate->interact->routes = gf_list_new(); break; default: - free(r); + gf_free(r); return GF_BAD_PARAM; } } @@ -935,6 +996,26 @@ GF_Err gf_sg_proto_instance_set_ised(GF_Node *protoinst, u32 protoFieldIndex, GF r->FromNode = protoinst; r->ToField.fieldIndex = nodeFieldIndex; r->ToNode = node; + + /*create an ISed route for the eventOut part of the exposedFIeld*/ + if ((field.eventType==GF_SG_EVENT_EXPOSED_FIELD) && (nodeField.eventType==GF_SG_EVENT_EXPOSED_FIELD)) { + GF_Route *r2; + GF_SAFEALLOC(r2, GF_Route); + if (!r2) { + gf_free(r); + return GF_OUT_OF_MEM; + } + r2->IS_route = 1; + r2->FromField.fieldIndex = nodeFieldIndex; + r2->FromNode = node; + r2->ToField.fieldIndex = protoFieldIndex; + r2->ToNode = protoinst; + r2->graph = node->sgprivate->scenegraph; + if (!node->sgprivate->interact) GF_SAFEALLOC(node->sgprivate->interact, struct _node_interactive_ext); + if (!node->sgprivate->interact->routes) node->sgprivate->interact->routes = gf_list_new(); + gf_list_add(node->sgprivate->interact->routes, r2); + gf_list_add(r->graph->Routes, r2); + } break; case GF_SG_EVENT_OUT: r->FromField.fieldIndex = nodeFieldIndex; @@ -946,7 +1027,7 @@ GF_Err gf_sg_proto_instance_set_ised(GF_Node *protoinst, u32 protoFieldIndex, GF gf_list_add(node->sgprivate->interact->routes, r); break; default: - free(r); + gf_free(r); return GF_BAD_PARAM; } } @@ -1040,48 +1121,27 @@ GF_ProtoFieldInterface *gf_sg_proto_field_find(GF_Proto *proto, u32 fieldIndex) return (GF_ProtoFieldInterface*)gf_list_get(proto->proto_fields, fieldIndex); } -void gf_sg_proto_check_field_change(GF_Node *node, u32 fieldIndex) +void gf_sg_proto_propagate_event(GF_Node *node, u32 fieldIndex, GF_Node *from_node) { u32 i; - GF_Route *r; if (!node) return; - - if ((node->sgprivate->tag == TAG_ProtoNode) && node->sgprivate->interact && node->sgprivate->interact->routes){ - i=0; - while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->routes, &i))) { - if (!r->IS_route) continue; - /*eventIn or exposedField*/ - if ((r->FromNode == node) && (r->FromField.fieldIndex == fieldIndex) ) { - if (gf_sg_route_activate(r)) - gf_node_changed(r->ToNode, &r->FromField); - } - /*eventOut*/ - if ((r->ToNode == node) && (r->ToField.fieldIndex == fieldIndex) ) { - gf_sg_route_activate(r); - } - } - /*no notification for proto changes*/ - return; - } - /*the node has to belong to a proto graph*/ - if (! node->sgprivate->scenegraph->pOwningProto) return; - /*no routes defined*/ - if (!node->sgprivate->interact) return; - - /*search for IS routes_events in the node and activate them. Field can also be an eventOut !!*/ + /*propagation only for proto*/ + if (node->sgprivate->tag != TAG_ProtoNode) return; + /*with ISed fields*/ + if (!node->sgprivate->interact || !node->sgprivate->interact->routes) return; + /*we only need to propagate ISed for eventIn/exposedField. This means that if the event comes from + the same scene graph as the proto (eg from the proto code) we don't propagate the event*/ + if (from_node->sgprivate->scenegraph == node->sgprivate->scenegraph) return; + + /*for all ISed routes*/ i=0; while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->routes, &i))) { if (!r->IS_route) continue; - /*activate eventOuts*/ - if ((r->FromNode == node) && (r->FromField.fieldIndex == fieldIndex)) { - gf_sg_route_activate(r); - } - /*or eventIns / (exposed)Fields*/ - else if ((r->ToNode == node) && (r->ToField.fieldIndex == fieldIndex)) { - /*don't forget to notify the node it has changed*/ + /*connecting from this node && field to a destination node other than the event source (this will break loops due to exposedFields)*/ + if ((r->FromNode == node) && (r->FromField.fieldIndex == fieldIndex) && (r->ToNode != from_node) ) { if (gf_sg_route_activate(r)) - gf_node_changed(node, &r->ToField); + gf_node_changed(r->ToNode, &r->ToField); } } } @@ -1201,6 +1261,21 @@ GF_SceneGraph *Node_GetExternProtoScene(GF_Node *node) return sg; } +GF_EXPORT +GF_Err gf_node_proto_set_grouping(GF_Node *node) +{ + if (!node || (node->sgprivate->tag!=TAG_ProtoNode)) return GF_BAD_PARAM; + ((GF_ProtoInstance *)node)->flags |= GF_SG_PROTO_IS_GROUPING; + return GF_OK; +} + +GF_EXPORT +Bool gf_node_proto_is_grouping(GF_Node *node) +{ + if (!node || (node->sgprivate->tag!=TAG_ProtoNode)) return 0; + if ( ((GF_ProtoInstance *)node)->flags & GF_SG_PROTO_IS_GROUPING) return 1; + return 0; +} GF_EXPORT GF_Node *gf_node_get_proto_root(GF_Node *node) @@ -1229,3 +1304,5 @@ Bool gf_node_is_proto_root(GF_Node *node) if (gf_list_find(node->sgprivate->scenegraph->pOwningProto->node_code, node)>=0) return 1; return 0; } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/scenegraph/vrml_route.c b/src/scenegraph/vrml_route.c index 215342e..2833355 100644 --- a/src/scenegraph/vrml_route.c +++ b/src/scenegraph/vrml_route.c @@ -27,6 +27,8 @@ #include <gpac/nodes_mpeg4.h> #include <gpac/nodes_x3d.h> +#ifndef GPAC_DISABLE_VRML + GF_EXPORT GF_Route *gf_sg_route_new(GF_SceneGraph *sg, GF_Node *fromNode, u32 fromField, GF_Node *toNode, u32 toField) @@ -55,8 +57,6 @@ void gf_sg_route_del(GF_Route *r) GF_SceneGraph *sg; s32 ind; - gf_sg_route_unqueue(r->graph, r); - /*remove declared routes*/ ind = gf_list_del_item(r->graph->Routes, r); /*remove route from node - do this regardless of setup state since the route is registered upon creation*/ @@ -67,10 +67,18 @@ void gf_sg_route_del(GF_Route *r) r->FromNode->sgprivate->interact->routes = NULL; } } + /*special case for script events: notify desdctruction*/ + if (r->ToNode && (r->ToField.fieldType==GF_SG_VRML_SCRIPT_FUNCTION) && r->ToField.on_event_in) { + r->is_setup = 0; + r->FromNode = NULL; + r->ToField.on_event_in(r->ToNode, r); + } + r->is_setup = 0; sg = r->graph; while (sg->parent_scene) sg = sg->parent_scene; gf_list_add(sg->routes_to_destroy, r); + gf_list_del_item(sg->routes_to_activate, r); } @@ -90,8 +98,8 @@ void gf_sg_destroy_routes(GF_SceneGraph *sg) GF_Route *r = (GF_Route *)gf_list_get(sg->routes_to_destroy, 0); gf_list_rem(sg->routes_to_destroy, 0); gf_sg_route_unqueue(sg, r); - if (r->name) free(r->name); - free(r); + if (r->name) gf_free(r->name); + gf_free(r); } } @@ -119,6 +127,7 @@ void gf_sg_activate_routes(GF_SceneGraph *sg) if (!sg) return; sg->simulation_tick++; + gf_sg_destroy_routes(sg); while (gf_list_count(sg->routes_to_activate)) { r = (GF_Route *)gf_list_get(sg->routes_to_activate, 0); @@ -136,7 +145,6 @@ void gf_sg_activate_routes(GF_SceneGraph *sg) } } } - gf_sg_destroy_routes(sg); } void gf_sg_route_unqueue(GF_SceneGraph *sg, GF_Route *r) @@ -193,8 +201,8 @@ GF_Err gf_sg_route_set_name(GF_Route *route, char *name) if (!name || !route) return GF_BAD_PARAM; ptr = gf_sg_route_find_by_name(route->graph, name); if (ptr) return GF_BAD_PARAM; - if (route->name) free(route->name); - route->name = strdup(name); + if (route->name) gf_free(route->name); + route->name = gf_strdup(name); return GF_OK; } char *gf_sg_route_get_name(GF_Route *route) @@ -202,13 +210,40 @@ char *gf_sg_route_get_name(GF_Route *route) return route->name; } -static void gf_sg_route_setup(GF_Route *r) +void gf_sg_route_setup(GF_Route *r) { gf_node_get_field(r->FromNode, r->FromField.fieldIndex, &r->FromField); gf_node_get_field(r->ToNode, r->ToField.fieldIndex, &r->ToField); + switch (r->FromField.fieldType) { + case GF_SG_VRML_MFNODE: + if (r->ToField.fieldType != GF_SG_VRML_MFNODE) return; + break; + case GF_SG_VRML_SFNODE: + if (r->ToField.fieldType != GF_SG_VRML_SFNODE) return; + break; + } r->is_setup = 1; } +/*send event out of proto - all ISed fields are ignored*/ +static void gf_node_event_out_proto(GF_Node *node, u32 FieldIndex) +{ + u32 i; + GF_Route *r; + if (!node) return; + + if (!node->sgprivate->interact) return; + + //search for routes to activate in the order they where declared + i=0; + while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->routes, &i))) { + if (r->IS_route) continue; + if (r->FromNode != node) continue; + if (r->FromField.fieldIndex != FieldIndex) continue; + gf_sg_route_queue(node->sgprivate->scenegraph, r); + } +} + Bool gf_sg_route_activate(GF_Route *r) { Bool ret; @@ -217,6 +252,7 @@ Bool gf_sg_route_activate(GF_Route *r) if (!r->is_setup) { gf_sg_route_setup(r); + if (!r->is_setup) return 0; /*special case when initing ISed routes on eventOuts: skip*/ if (r->IS_route) { if (r->FromField.eventType == GF_SG_EVENT_OUT) return 0; @@ -225,9 +261,16 @@ Bool gf_sg_route_activate(GF_Route *r) } #ifndef GPAC_DISABLE_LOG if (r->IS_route) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[VRML Event] executing %s.%s IS %s.%s\n", gf_node_get_name(r->FromNode), r->FromField.name, gf_node_get_name(r->ToNode), r->ToField.name)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[VRML Event] executing %s.%s IS %s.%s", gf_node_get_name(r->FromNode), r->FromField.name, gf_node_get_name(r->ToNode), r->ToField.name)); + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[VRML Event] executing ROUTE %s.%s TO %s.%s", gf_node_get_name(r->FromNode), r->FromField.name, gf_node_get_name(r->ToNode), r->ToField.name)); + } + if (r->FromField.fieldType==GF_SG_VRML_SFBOOL) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("\tBOOL VAL: %d\n", *((SFBool*)r->FromField.far_ptr))); + } else if (r->FromField.fieldType==GF_SG_VRML_SFINT32) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("\tINT VAL: %d\n", *((SFInt32*)r->FromField.far_ptr))); } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("[VRML Event] executing ROUTE %s.%s TO %s.%s\n", gf_node_get_name(r->FromNode), r->FromField.name, gf_node_get_name(r->ToNode), r->ToField.name)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_INTERACT, ("\n")); } #endif @@ -281,23 +324,29 @@ Bool gf_sg_route_activate(GF_Route *r) //if this is a supported eventIn call watcher if (r->ToField.on_event_in) { - r->ToField.on_event_in(r->ToNode); + r->ToField.on_event_in(r->ToNode, r); } //if this is a script eventIn call directly script - else if (((r->ToNode->sgprivate->tag==TAG_MPEG4_Script) || (r->ToNode->sgprivate->tag==TAG_X3D_Script) ) - && ((r->ToField.eventType==GF_SG_EVENT_IN) /*|| (r->ToField.eventType==GF_SG_EVENT_FIELD)*/) ) { + else if (((r->ToNode->sgprivate->tag==TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (r->ToNode->sgprivate->tag==TAG_X3D_Script) +#endif + ) && ((r->ToField.eventType==GF_SG_EVENT_IN) /*|| (r->ToField.eventType==GF_SG_EVENT_FIELD)*/) ) { gf_sg_script_event_in(r->ToNode, &r->ToField); } //check if ISed or not - this will notify the node of any changes else { - gf_sg_proto_check_field_change(r->ToNode, r->ToField.fieldIndex); + gf_sg_proto_propagate_event(r->ToNode, r->ToField.fieldIndex, r->FromNode); /*only happen on proto, an eventOut may route to an eventOut*/ if (r->IS_route && r->ToField.eventType==GF_SG_EVENT_OUT) gf_node_event_out(r->ToNode, r->ToField.fieldIndex); } /*and signal routes on exposed fields if field changed*/ if (r->ToField.eventType == GF_SG_EVENT_EXPOSED_FIELD) - gf_node_event_out(r->ToNode, r->ToField.fieldIndex); + if (r->IS_route) + gf_node_event_out_proto(r->ToNode, r->ToField.fieldIndex); + else + gf_node_event_out(r->ToNode, r->ToField.fieldIndex); return ret; } @@ -309,7 +358,8 @@ void gf_node_event_out(GF_Node *node, u32 FieldIndex) GF_Route *r; if (!node) return; - if (!node->sgprivate->interact) return; + /*node has no routes*/ + if (!node->sgprivate->interact || !node->sgprivate->interact->routes) return; //search for routes to activate in the order they where declared i=0; @@ -335,12 +385,9 @@ void gf_node_event_out_str(GF_Node *node, const char *eventName) u32 i; GF_Route *r; - /*node is being deleted ignore event*/ - if (!node->sgprivate->interact) return; + /*node has no routes*/ + if (!node->sgprivate->interact || !node->sgprivate->interact->routes) return; - //this is not an ISed - if (!(node->sgprivate->flags & GF_NODE_IS_DEF) && !node->sgprivate->scenegraph->pOwningProto) return; - //search for routes to activate in the order they where declared i=0; while ((r = (GF_Route*)gf_list_enum(node->sgprivate->interact->routes, &i))) { @@ -358,3 +405,4 @@ void gf_node_event_out_str(GF_Node *node, const char *eventName) } } +#endif /*GPAC_DISABLE_VRML*/ \ No newline at end of file diff --git a/src/scenegraph/vrml_script.c b/src/scenegraph/vrml_script.c index c7cb845..7de3386 100644 --- a/src/scenegraph/vrml_script.c +++ b/src/scenegraph/vrml_script.c @@ -27,28 +27,15 @@ #include <gpac/nodes_mpeg4.h> #include <gpac/nodes_x3d.h> -#if defined(GPAC_HAS_SPIDERMONKEY) && !defined(__GNUC__) -# if defined(_WIN32_WCE) -# pragma comment(lib, "js") -# elif defined (WIN32) -# pragma comment(lib, "js32") -# endif -#endif + +#ifndef GPAC_DISABLE_VRML + static u32 script_get_nb_static_field(GF_Node *node) { return (node->sgprivate->tag==TAG_MPEG4_Script) ? 3 : 4; } -Bool gf_sg_has_scripting() -{ -#ifdef GPAC_HAS_SPIDERMONKEY - return 1; -#else - return 0; -#endif -} - void Script_PreDestroy(GF_Node *node, void *eff, Bool is_destroy) { GF_ScriptPriv *priv; @@ -79,11 +66,11 @@ void Script_PreDestroy(GF_Node *node, void *eff, Bool is_destroy) break; } } - if (field->name) free(field->name); - free(field); + if (field->name) gf_free(field->name); + gf_free(field); } gf_list_del(priv->fields); - free(priv); + gf_free(priv); } u32 gf_sg_script_get_num_fields(GF_Node *node, u8 IndexMode) @@ -150,7 +137,11 @@ GF_Err gf_sg_script_get_field(GF_Node *node, GF_FieldInfo *info) //static fields if (info->fieldIndex < nb_static) { if (nb_static==3) return gf_sg_mpeg4_node_get_field(node, info); +#ifndef GPAC_DISABLE_X3D return gf_sg_x3d_node_get_field(node, info); +#else + return GF_NOT_SUPPORTED; +#endif } //dyn fields @@ -199,7 +190,11 @@ GF_ScriptField *gf_sg_script_field_new(GF_Node *node, u32 eventType, u32 fieldTy { GF_ScriptPriv *priv; GF_ScriptField *field; - if (!name || ((node->sgprivate->tag != TAG_MPEG4_Script) && (node->sgprivate->tag != TAG_X3D_Script))) + if (!name || ((node->sgprivate->tag != TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + && (node->sgprivate->tag != TAG_X3D_Script) +#endif + )) return NULL; if (eventType > GF_SG_SCRIPT_TYPE_EVENT_OUT) return NULL; @@ -207,7 +202,7 @@ GF_ScriptField *gf_sg_script_field_new(GF_Node *node, u32 eventType, u32 fieldTy GF_SAFEALLOC(field, GF_ScriptField) field->fieldType = fieldType; - field->name = strdup(name); + field->name = gf_strdup(name); field->DEF_index = field->IN_index = field->OUT_index = -1; switch (eventType) { @@ -300,3 +295,4 @@ void gf_sg_script_event_in(GF_Node *node, GF_FieldInfo *in_field) } +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/scenegraph/vrml_smjs.c b/src/scenegraph/vrml_smjs.c index 9d37cfa..bf8daf5 100644 --- a/src/scenegraph/vrml_smjs.c +++ b/src/scenegraph/vrml_smjs.c @@ -10,40 +10,91 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <gpac/internal/scenegraph_dev.h> -/*MPEG4 & X3D tags (for node tables & script handling)*/ -#include <gpac/nodes_mpeg4.h> -#include <gpac/nodes_x3d.h> #ifdef GPAC_HAS_SPIDERMONKEY -#ifndef GPAC_DISABLE_SVG -/*SVG tags for script handling*/ -#include <gpac/nodes_svg.h> -#endif - #include <gpac/internal/terminal_dev.h> +#include <gpac/modules/term_ext.h> #include <gpac/modules/js_usr.h> -#include <jsapi.h> +#include <jsapi.h> -void gf_sg_script_to_node_field(struct JSContext *c, jsval v, GF_FieldInfo *field, GF_Node *owner, GF_JSField *parent); -jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_Node *parent, Bool no_cache, Bool force_evaluate); +/*fixes for JS > 1.8.0rc1 where GC routines have changed*/ +Bool gf_js_add_root(JSContext *cx, void *rp) +{ +#ifdef SPIDERMONKEY_NEW_API + return (JS_AddValueRoot(cx, rp)==JS_TRUE) ? 1 : 0; +#else + return (JS_AddRoot(cx, rp)==JS_TRUE) ? 1 : 0; +#endif +} +Bool gf_js_add_named_root(JSContext *cx, void *rp, const char *name) +{ +#ifdef SPIDERMONKEY_NEW_API + return (JS_AddNamedValueRoot(cx, rp, name)==JS_TRUE) ? 1 : 0; +#else + return (JS_AddNamedRoot(cx, rp, name)==JS_TRUE) ? 1 : 0; +#endif +} +Bool gf_js_remove_root(JSContext *cx, void *rp) +{ +#ifdef SPIDERMONKEY_NEW_API + return (JS_RemoveValueRoot(cx, rp)==JS_TRUE) ? 1 : 0; +#else + return (JS_RemoveRoot(cx, rp)==JS_TRUE) ? 1 : 0; +#endif +} + + +#if !defined(__GNUC__) +# if defined(_WIN32_WCE) +# pragma comment(lib, "js") +# elif defined (WIN32) +# pragma comment(lib, "js32") +# endif +#endif + +/*define this macro to force Garbage Collection after each input to JS (script initialize/shutdown and all eventIn) */ +//#define FORCE_GC + + +typedef struct +{ + u8 is_setup; + /*set to true for proto IS fields*/ + u8 IS_route; + + u32 ID; + char *name; + + /*scope of this route*/ + GF_SceneGraph *graph; + u32 lastActivateTime; + + GF_Node *FromNode; + GF_FieldInfo FromField; + + GF_Node *ToNode; + GF_FieldInfo ToField; + + JSObject *obj; + jsval fun; +} GF_RouteToFunction; -JSBool js_has_instance(JSContext *c, JSObject *obj, jsval val, JSBool *vp); #define _ScriptMessage(_c, _e, _msg) { \ GF_Node *_n = (GF_Node *) JS_GetContextPrivate(_c); \ @@ -55,26 +106,29 @@ JSBool js_has_instance(JSContext *c, JSObject *obj, jsval val, JSBool *vp); } \ } -Bool ScriptAction(JSContext *c, GF_SceneGraph *scene, u32 type, GF_Node *node, GF_JSAPIParam *param) +static Bool ScriptAction(JSContext *c, GF_SceneGraph *scene, u32 type, GF_Node *node, GF_JSAPIParam *param) { if (!scene) { GF_Node *n = (GF_Node *) JS_GetContextPrivate(c); scene = n->sgprivate->scenegraph; } - if (scene->script_action) + if (scene->script_action) return scene->script_action(scene->script_action_cbck, type, node, param); return 0; } - - typedef struct { JSRuntime *js_runtime; u32 nb_inst; + + GF_Mutex *mx; + + JSClass SFNodeClass; + +#ifndef GPAC_DISABLE_VRML JSClass globalClass; JSClass browserClass; - JSClass SFNodeClass; JSClass SFVec2fClass; JSClass SFVec3fClass; JSClass SFRotationClass; @@ -91,6 +145,7 @@ typedef struct JSClass MFStringClass; JSClass MFUrlClass; JSClass MFNodeClass; +#endif /*extensions are loaded for the lifetime of the runtime NOT of the context - this avoids nasty crashes with multiple contexts in SpiderMonkey (root'ing bug with InitStandardClasses)*/ @@ -100,24 +155,162 @@ typedef struct static GF_JSRuntime *js_rt = NULL; - - void gf_sg_load_script_extensions(GF_SceneGraph *sg, JSContext *c, JSObject *obj, Bool unload) { u32 i, count; - count = gf_list_count(js_rt->extensions); + count = gf_list_count(js_rt->extensions); for (i=0; i<count; i++) { GF_JSUserExtension *ext = (GF_JSUserExtension *) gf_list_get(js_rt->extensions, i); ext->load(ext, sg, c, obj, unload); } + + //if (js_rt->nb_inst==1) + { + GF_Terminal *term; + GF_JSAPIParam par; + + if (!sg->script_action) return; + if (!sg->script_action(sg->script_action_cbck, GF_JSAPI_OP_GET_TERM, sg->RootNode, &par)) + return; + + term = par.term; + + count = gf_list_count(term->extensions); + for (i=0; i<count; i++) { + GF_TermExt *ext = (GF_TermExt *) gf_list_get(term->extensions, i); + if (ext->caps & GF_TERM_EXTENSION_JS) { + GF_TermExtJS te; + te.ctx = c; + te.global = obj; + te.scenegraph = sg; + te.unload = unload; + ext->process(ext, GF_TERM_EXT_JSBIND, &te); + } + } + } +} + + +static void gf_sg_load_script_modules(GF_SceneGraph *sg) +{ + GF_Terminal *term; + u32 i, count; + GF_JSAPIParam par; + + js_rt->extensions = gf_list_new(); + + if (!sg->script_action) return; + if (!sg->script_action(sg->script_action_cbck, GF_JSAPI_OP_GET_TERM, sg->RootNode, &par)) + return; + + term = par.term; + + count = gf_modules_get_count(term->user->modules); + for (i=0; i<count; i++) { + GF_JSUserExtension *ext = (GF_JSUserExtension *) gf_modules_load_interface(term->user->modules, i, GF_JS_USER_EXT_INTERFACE); + if (!ext) continue; + gf_list_add(js_rt->extensions, ext); + } +} + +static void gf_sg_unload_script_modules() +{ + while (gf_list_count(js_rt->extensions)) { + GF_JSUserExtension *ext = gf_list_last(js_rt->extensions); + gf_list_rem_last(js_rt->extensions); + gf_modules_close_interface((GF_BaseInterface *) ext); + } + gf_list_del(js_rt->extensions); +} + + +#ifdef __SYMBIAN32__ +const long MAX_HEAP_BYTES = 256 * 1024L; +#else +const long MAX_HEAP_BYTES = 4*1024 * 1024L; +#endif +const long STACK_CHUNK_BYTES = 8*1024L; + +JSContext *gf_sg_ecmascript_new(GF_SceneGraph *sg) +{ + if (!js_rt) { + JSRuntime *js_runtime = JS_NewRuntime(MAX_HEAP_BYTES); + if (!js_runtime) { + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[ECMAScript] Cannot allocate ECMAScript runtime\n")); + return NULL; + } + GF_SAFEALLOC(js_rt, GF_JSRuntime); + js_rt->js_runtime = js_runtime; + js_rt->mx = gf_mx_new("JavaScript"); + GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[ECMAScript] ECMAScript runtime allocated 0x%08x\n", js_runtime)); + gf_sg_load_script_modules(sg); + } + js_rt->nb_inst++; + return JS_NewContext(js_rt->js_runtime, STACK_CHUNK_BYTES); +} + +void gf_sg_ecmascript_del(JSContext *ctx) +{ + JS_SetGlobalObject(ctx, NULL); + JS_DestroyContext(ctx); + if (js_rt) { + js_rt->nb_inst --; + if (js_rt->nb_inst == 0) { + JS_DestroyRuntime(js_rt->js_runtime); + JS_ShutDown(); + gf_sg_unload_script_modules(); + gf_mx_del(js_rt->mx); + gf_free(js_rt); + js_rt = NULL; + } + } +} + +JSBool my_js_has_instance(JSContext *c, JSObject *obj, jsval val, JSBool *vp) +{ + *vp = JS_FALSE; + if (JSVAL_IS_OBJECT(val)) { + JSObject *p; + JSClass *js_class = JS_GET_CLASS(c, obj); + p = JSVAL_TO_OBJECT(val); + if (JS_InstanceOf(c, p, js_class, NULL) ) *vp = JS_TRUE; + } + return JS_TRUE; } +#ifndef GPAC_DISABLE_SVG +/*SVG tags for script handling*/ +#include <gpac/nodes_svg.h> + +GF_Node *dom_get_element(JSContext *c, JSObject *obj); +#endif + +#ifndef GPAC_DISABLE_VRML + +/*MPEG4 & X3D tags (for node tables & script handling)*/ +#include <gpac/nodes_mpeg4.h> +#include <gpac/nodes_x3d.h> + + +void gf_sg_script_to_node_field(struct JSContext *c, jsval v, GF_FieldInfo *field, GF_Node *owner, GF_JSField *parent); +jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_Node *parent, Bool force_evaluate); + +static void JSScript_NodeModified(GF_SceneGraph *sg, GF_Node *node, GF_FieldInfo *info, GF_Node *script); + +void JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain); + + +#ifdef FORCE_GC +void MyJSGC(JSContext *c) { + JS_GC(c); +} +#endif void SFColor_fromHSV(SFColor *col) { Fixed f, q, t, p, hue, sat, val; - u32 i; + u32 i; hue = col->red; sat = col->green; val = col->blue; @@ -171,18 +364,11 @@ void SFColor_toHSV(SFColor *col) col->blue = _max; } -static void vrml_node_register(GF_Node *node, GF_Node *parent) -{ - if (node) { - node->sgprivate->flags |= GF_NODE_HAS_BINDING; - gf_node_register(node, parent); - } -} - -static GFINLINE GF_JSField *NewJSField() +static GFINLINE GF_JSField *NewJSField(JSContext *c) { GF_JSField *ptr; - GF_SAFEALLOC(ptr, GF_JSField) + GF_SAFEALLOC(ptr, GF_JSField); + ptr->js_ctx = c; return ptr; } @@ -198,24 +384,25 @@ static GFINLINE GF_ScriptPriv *JS_GetScriptStack(JSContext *c) static void script_error(JSContext *c, const char *msg, JSErrorReport *jserr) { -// GF_JSInterface *ifce = JS_GetInterface(c); -// if (ifce) ifce->ScriptMessage(ifce->callback, GF_SCRIPT_ERROR, msg); - GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[JavaScript] Error: %s", msg)); + GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[JavaScript] Error: %s - line %d (%s)", msg, jserr->lineno, jserr->linebuf)); } -static JSBool JSPrint(JSContext *c, JSObject *p, uintN argc, jsval *argv, jsval *rval) +static void vrml_node_register(JSContext *c, GF_Node *node) { - u32 i; - char buf[5000]; + if (node) { + GF_Node *parent = (GF_Node*)JS_GetContextPrivate(c); + node->sgprivate->flags |= GF_NODE_HAS_BINDING; + gf_node_register(node, (node == parent) ? NULL : parent); + } +} + - strcpy(buf, ""); - for (i = 0; i < argc; i++) { - JSString *str = JS_ValueToString(c, argv[i]); - if (!str) return JS_FALSE; - if (i) strcat(buf, " "); - strcat(buf, JS_GetStringBytes(str)); +static JSBool JSPrint(JSContext *c, JSObject *p, uintN argc, jsval *argv, jsval *rval) +{ + if (JSVAL_IS_STRING(argv[0])) { + char *str = JS_GetStringBytes(JS_ValueToString(c, argv[0]) ); + _ScriptMessage(c, GF_SCRIPT_INFO, str); } - _ScriptMessage(c, GF_SCRIPT_INFO, buf); return JS_TRUE; } @@ -223,14 +410,14 @@ static JSBool getName(JSContext *c, JSObject *obj, uintN n, jsval *v, jsval *rva { JSString *s = JS_NewStringCopyZ(c, "GPAC RichMediaEngine"); if (!s) return JS_FALSE; - *rval = STRING_TO_JSVAL(s); + *rval = STRING_TO_JSVAL(s); return JS_TRUE; } static JSBool getVersion(JSContext*c, JSObject*obj, uintN n, jsval *v, jsval *rval) { JSString *s = JS_NewStringCopyZ(c, GPAC_FULL_VERSION); if (!s) return JS_FALSE; - *rval = STRING_TO_JSVAL(s); + *rval = STRING_TO_JSVAL(s); return JS_TRUE; } static JSBool getCurrentSpeed(JSContext *c, JSObject *o, uintN n, jsval *v, jsval *rval) @@ -255,37 +442,87 @@ static JSBool getWorldURL(JSContext*c, JSObject*obj, uintN n, jsval *v, jsval *r { GF_JSAPIParam par; GF_Node *node = JS_GetContextPrivate(c); - if (ScriptAction(c, NULL, GF_JSAPI_OP_GET_SCENE_URI, node->sgprivate->scenegraph->RootNode, &par)) { + par.uri.url = NULL; + par.uri.nb_params = 0; + if (ScriptAction(c, NULL, GF_JSAPI_OP_RESOLVE_URI, node->sgprivate->scenegraph->RootNode, &par)) { JSString *s = JS_NewStringCopyZ(c, par.uri.url); if (!s) return JS_FALSE; *rval = STRING_TO_JSVAL(s); + gf_free(par.uri.url); return JS_TRUE; } return JS_FALSE; } -static JSBool getScript(JSContext*c, JSObject*obj, uintN n, jsval *v, jsval *rval) + +static JSObject *node_get_binding(GF_ScriptPriv *priv, GF_Node *node, Bool is_constructor) { - JSObject *an_obj; + JSObject *obj; GF_JSField *field; + + if (node->sgprivate->interact && node->sgprivate->interact->js_binding && node->sgprivate->interact->js_binding->node) { + field = node->sgprivate->interact->js_binding->node; + if (!field->is_rooted) { + gf_js_add_root(priv->js_ctx, &field->obj); + field->is_rooted=1; + } + return field->obj; + } + + field = NewJSField(priv->js_ctx); + field->field.fieldType = GF_SG_VRML_SFNODE; + field->node = node; + field->field.far_ptr = &field->node; + vrml_node_register(priv->js_ctx, node); + + obj = JS_NewObject(priv->js_ctx, &js_rt->SFNodeClass, 0, 0); + JS_SetPrivate(priv->js_ctx, obj, field); + + gf_list_add(priv->js_cache, obj); + field->obj = obj; + + + /*remember the object*/ + if (!node->sgprivate->interact) GF_SAFEALLOC(node->sgprivate->interact, struct _node_interactive_ext); + if (!node->sgprivate->interact->js_binding) { + GF_SAFEALLOC(node->sgprivate->interact->js_binding, struct _node_js_binding); + node->sgprivate->interact->js_binding->fields = gf_list_new(); + } + node->sgprivate->flags |= GF_NODE_HAS_BINDING; + node->sgprivate->interact->js_binding->node = field; + if (!is_constructor) { + field->is_rooted = 1; + gf_js_add_root(priv->js_ctx, &field->obj); + } + return obj; +} + +static JSBool getScript(JSContext*c, JSObject*obj, uintN n, jsval *v, jsval *rval) +{ GF_ScriptPriv *priv = JS_GetScriptStack(c); GF_Node *node = JS_GetContextPrivate(c); + JSObject *an_obj = node_get_binding(priv, node, 0); - vrml_node_register(node, NULL); - field = NewJSField(); - field->field.fieldType = GF_SG_VRML_SFNODE; - field->temp_node = node; - field->field.far_ptr = &field->temp_node; + if (an_obj) *rval = OBJECT_TO_JSVAL(an_obj); + return JS_TRUE; +} + +static JSBool loadScript(JSContext*c, JSObject*obj, uintN argc, jsval *argv, jsval *rval) +{ + Bool no_complain = 0; + char *url; + GF_Node *node = JS_GetContextPrivate(c); + if (!argc || !JSVAL_IS_STRING(argv[0])) return JS_TRUE; - an_obj = JS_NewObject(priv->js_ctx, &js_rt->SFNodeClass, 0, priv->js_obj); - field->obj = an_obj; - JS_SetPrivate(c, an_obj, field); - *rval = OBJECT_TO_JSVAL(an_obj); + if ((argc>1) && JSVAL_IS_BOOLEAN(argv[1])) no_complain = (JSVAL_TO_BOOLEAN(argv[1])==JS_TRUE) ? 1 : 0; + + url = JS_GetStringBytes(JSVAL_TO_STRING(argv[0])); + if (url) JSScriptFromFile(node, url, no_complain); return JS_TRUE; } + static JSBool getProto(JSContext*c, JSObject*obj, uintN n, jsval *v, jsval *rval) { JSObject *an_obj; - GF_JSField *field; GF_ScriptPriv *priv = JS_GetScriptStack(c); GF_Node *node = JS_GetContextPrivate(c); if (!node->sgprivate->scenegraph->pOwningProto) { @@ -293,23 +530,43 @@ static JSBool getProto(JSContext*c, JSObject*obj, uintN n, jsval *v, jsval *rval return JS_TRUE; } node = (GF_Node *) node->sgprivate->scenegraph->pOwningProto; - vrml_node_register(node, NULL); - field = NewJSField(); - field->field.fieldType = GF_SG_VRML_SFNODE; - field->temp_node = node; - field->field.far_ptr = &field->temp_node; - an_obj = JS_NewObject(priv->js_ctx, &js_rt->SFNodeClass, 0, priv->js_obj); - field->obj = an_obj; - JS_SetPrivate(c, an_obj, field); - *rval = OBJECT_TO_JSVAL(an_obj); + an_obj = node_get_binding(priv, node, 0); + if (an_obj) *rval = OBJECT_TO_JSVAL(an_obj); + return JS_TRUE; +} + +#ifndef GPAC_DISABLE_SVG +char *js_get_utf8(jsval val); +jsval dom_element_construct(JSContext *c, GF_Node *n); +#endif + +static JSBool vrml_parse_xml(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ +#ifndef GPAC_DISABLE_SVG + GF_SceneGraph *sg; + GF_Node *node; + char *str; + GF_Node *gf_sm_load_svg_from_string(GF_SceneGraph *sg, char *svg_str); + + str = js_get_utf8(argv[0]); + if (!str) return JS_TRUE; + + node = JS_GetContextPrivate(c); + sg = node->sgprivate->scenegraph; + + node = gf_sm_load_svg_from_string(sg, str); + gf_free(str); + *rval = dom_element_construct(c, node); +#endif return JS_TRUE; } + + static JSBool getElementById(JSContext*c, JSObject*obj, uintN argc, jsval *argv, jsval *rval) { GF_Node *elt; JSObject *an_obj; - GF_JSField *field; char *name = NULL; u32 ID = 0; GF_ScriptPriv *priv = JS_GetScriptStack(c); @@ -324,16 +581,8 @@ static JSBool getElementById(JSContext*c, JSObject*obj, uintN argc, jsval *argv, else elt = gf_sg_find_node_by_name(sc->sgprivate->scenegraph, name); if (!elt) return JS_TRUE; - vrml_node_register(elt, NULL); - field = NewJSField(); - field->field.fieldType = GF_SG_VRML_SFNODE; - field->temp_node = elt; - field->field.far_ptr = &field->temp_node; - - an_obj = JS_NewObject(c, &js_rt->SFNodeClass, 0, priv->js_obj); - field->obj = an_obj; - JS_SetPrivate(c, an_obj, field); - *rval = OBJECT_TO_JSVAL(an_obj); + an_obj = node_get_binding(priv, elt, 0); + if (an_obj) *rval = OBJECT_TO_JSVAL(an_obj); return JS_TRUE; } @@ -341,31 +590,79 @@ static JSBool replaceWorld(JSContext*c, JSObject*o, uintN n, jsval *v, jsval *rv { return JS_TRUE; } + +static void on_route_to_object(GF_Node *node, GF_Route *_r) +{ + jsval argv[2], rval; + Double time; + GF_FieldInfo t_info; + GF_ScriptPriv *priv; + JSObject *obj; + GF_RouteToFunction *r = (GF_RouteToFunction *)_r; + if (!node) return; + priv = gf_node_get_private(node); + if (!priv) return; + + if (!r->FromNode) { + if (r->obj) { + gf_js_remove_root(priv->js_ctx, &r->obj); + r->obj=NULL; + } + if (r->fun) { + gf_js_remove_root(priv->js_ctx, &r->fun); + r->fun=0; + } + return; + } + + obj = (JSObject *) r->obj; + if (!obj) obj = priv->js_obj; + + memset(&t_info, 0, sizeof(GF_FieldInfo)); + time = gf_node_get_scene_time(node); + t_info.far_ptr = &time; + t_info.fieldType = GF_SG_VRML_SFTIME; + t_info.fieldIndex = -1; + t_info.name = "timestamp"; + + argv[1] = gf_sg_script_to_smjs_field(priv, &t_info, node, 1); + argv[0] = gf_sg_script_to_smjs_field(priv, &r->FromField, r->FromNode, 1); + + /*protect args*/ + if (JSVAL_IS_GCTHING(argv[0])) gf_js_add_root(priv->js_ctx, &argv[0]); + if (JSVAL_IS_GCTHING(argv[1])) gf_js_add_root(priv->js_ctx, &argv[1]); + + JS_CallFunctionValue(priv->js_ctx, obj, (jsval) r->fun, 2, argv, &rval); + + /*release args*/ + if (JSVAL_IS_GCTHING(argv[0])) gf_js_remove_root(priv->js_ctx, &argv[0]); + if (JSVAL_IS_GCTHING(argv[1])) gf_js_remove_root(priv->js_ctx, &argv[1]); + +#ifdef FORCE_GC + MyJSGC(priv->js_ctx); +#endif +} + static JSBool addRoute(JSContext*c, JSObject*o, uintN argc, jsval *argv, jsval *rv) { GF_JSField *ptr; GF_Node *n1, *n2; char *f1, *f2; GF_FieldInfo info; - GF_Route *r; u32 f_id1, f_id2; 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[2]) || !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 *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0])); assert(ptr->field.fieldType==GF_SG_VRML_SFNODE); n1 = * ((GF_Node **)ptr->field.far_ptr); - ptr = (GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[2])); - assert(ptr->field.fieldType==GF_SG_VRML_SFNODE); - n2 = * ((GF_Node **)ptr->field.far_ptr); - - if (!n1 || !n2) return JS_FALSE; + if (!n1) return JS_FALSE; + n2 = NULL; + + if (!JSVAL_IS_STRING(argv[1])) return JS_FALSE; f1 = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); - f2 = JS_GetStringBytes(JSVAL_TO_STRING(argv[3])); - if (!f1 || !f2) return JS_FALSE; - + if (!f1) return JS_FALSE; if (!strnicmp(f1, "_field", 6)) { f_id1 = atoi(f1+6); if (gf_node_get_field(n1, f_id1, &info) != GF_OK) return JS_FALSE; @@ -373,23 +670,79 @@ static JSBool addRoute(JSContext*c, JSObject*o, uintN argc, jsval *argv, jsval * if (gf_node_get_field_by_name(n1, f1, &info) != GF_OK) return JS_FALSE; f_id1 = info.fieldIndex; } - if (!strnicmp(f2, "_field", 6)) { - f_id2 = atoi(f2+6); - if (gf_node_get_field(n2, f_id2, &info) != GF_OK) return JS_FALSE; - } else { - if ((n2->sgprivate->tag==TAG_MPEG4_Script) || (n2->sgprivate->tag==TAG_X3D_Script)) { - GF_FieldInfo src = info; - if (gf_node_get_field_by_name(n2, f2, &info) != GF_OK) { - gf_sg_script_field_new(n2, GF_SG_SCRIPT_TYPE_EVENT_IN, src.fieldType, f2); + + + 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]) ) { + GF_Route *r; + ptr = (GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[2])); + assert(ptr->field.fieldType==GF_SG_VRML_SFNODE); + n2 = * ((GF_Node **)ptr->field.far_ptr); + if (!n2) return JS_FALSE; + + f2 = JS_GetStringBytes(JSVAL_TO_STRING(argv[3])); + if (!f2) return JS_FALSE; + + if (!strnicmp(f2, "_field", 6)) { + f_id2 = atoi(f2+6); + if (gf_node_get_field(n2, f_id2, &info) != GF_OK) return JS_FALSE; + } else { + if ((n2->sgprivate->tag==TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (n2->sgprivate->tag==TAG_X3D_Script) +#endif + ) { + GF_FieldInfo src = info; + if (gf_node_get_field_by_name(n2, f2, &info) != GF_OK) { + gf_sg_script_field_new(n2, GF_SG_SCRIPT_TYPE_EVENT_IN, src.fieldType, f2); + } } - } - if (gf_node_get_field_by_name(n2, f2, &info) != GF_OK) return JS_FALSE; - f_id2 = info.fieldIndex; + if (gf_node_get_field_by_name(n2, f2, &info) != GF_OK) return JS_FALSE; + f_id2 = info.fieldIndex; + } + + r = gf_sg_route_new(n1->sgprivate->scenegraph, n1, f_id1, n2, f_id2); + if (!r) return JS_FALSE; } - r = gf_sg_route_new(n1->sgprivate->scenegraph, n1, f_id1, n2, f_id2); - if (!r) return JS_FALSE; + /*route to object*/ + else { + GF_RouteToFunction *r; + if (!JSVAL_IS_OBJECT(argv[3]) || !JS_ObjectIsFunction(c, JSVAL_TO_OBJECT(argv[3])) ) return JS_FALSE; + + GF_SAFEALLOC(r, GF_RouteToFunction) + if (!r) return JS_FALSE; + r->FromNode = n1; + r->FromField.fieldIndex = f_id1; + gf_node_get_field(r->FromNode, f_id1, &r->FromField); + + r->ToNode = (GF_Node*)JS_GetScript(c); + r->ToField.fieldType = GF_SG_VRML_SCRIPT_FUNCTION; + r->ToField.on_event_in = on_route_to_object; + r->ToField.eventType = GF_SG_EVENT_IN; + r->ToField.far_ptr = NULL; + r->ToField.name = JS_GetFunctionName( JS_ValueToFunction(c, argv[3] ) ); + + r->obj = JSVAL_TO_OBJECT( argv[2] ) ; + gf_js_add_root(c, & r->obj); + + r->fun = argv[3]; + gf_js_add_root(c, &r->fun); + + r->is_setup = 1; + r->graph = n1->sgprivate->scenegraph; + + if (!n1->sgprivate->interact) GF_SAFEALLOC(n1->sgprivate->interact, struct _node_interactive_ext); + if (!n1->sgprivate->interact->routes) n1->sgprivate->interact->routes = gf_list_new(); + gf_list_add(n1->sgprivate->interact->routes, r); + gf_list_add(n1->sgprivate->scenegraph->Routes, r); + } + return JS_TRUE; } + + static JSBool deleteRoute(JSContext*c, JSObject*o, uintN argc, jsval *argv, jsval *rv) { GF_JSField *ptr; @@ -409,14 +762,14 @@ static JSBool deleteRoute(JSContext*c, JSObject*o, uintN argc, jsval *argv, jsva ptr = (GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[2])); assert(ptr->field.fieldType==GF_SG_VRML_SFNODE); n2 = * ((GF_Node **)ptr->field.far_ptr); - + if (!n1 || !n2) return JS_FALSE; if (!n1->sgprivate->interact) return JS_TRUE; f1 = JS_GetStringBytes(JSVAL_TO_STRING(argv[1])); f2 = JS_GetStringBytes(JSVAL_TO_STRING(argv[3])); if (!f1 || !f2) return JS_FALSE; - + if (!strnicmp(f1, "_field", 6)) { f_id1 = atoi(f1+6); if (gf_node_get_field(n1, f_id1, &info) != GF_OK) return JS_FALSE; @@ -465,7 +818,7 @@ static JSBool loadURL(JSContext*c, JSObject*obj, uintN argc, jsval *argv, jsval return JS_FALSE; } if (!JSVAL_IS_OBJECT(argv[0])) return JS_FALSE; - + JS_ValueToObject(c, argv[0], &p); f = (GF_JSField *) JS_GetPrivate(c, p); @@ -499,6 +852,7 @@ static JSBool setDescription(JSContext*c, JSObject*o, uintN argc, jsval *argv, j static JSBool createVrmlFromString(JSContext*c, JSObject*obj, uintN argc, jsval *argv, jsval *rval) { +#ifndef GPAC_DISABLE_LOADER_BT GF_ScriptPriv *priv; GF_FieldInfo field; /*BT/VRML from string*/ @@ -519,7 +873,7 @@ static JSBool createVrmlFromString(JSContext*c, JSObject*obj, uintN argc, jsval memset(&field, 0, sizeof(GF_FieldInfo)); field.fieldType = GF_SG_VRML_MFNODE; field.far_ptr = &nlist; - *rval = gf_sg_script_to_smjs_field(priv, &field, NULL, 0, 0); + *rval = gf_sg_script_to_smjs_field(priv, &field, NULL, 0); /*don't forget to unregister all this stuff*/ while (gf_list_count(nlist)) { @@ -529,6 +883,9 @@ static JSBool createVrmlFromString(JSContext*c, JSObject*obj, uintN argc, jsval } gf_list_del(nlist); return JS_TRUE; +#else + return JS_FALSE; +#endif } static JSBool getOption(JSContext*c, JSObject*obj, uintN argc, jsval *argv, jsval *rval) @@ -538,7 +895,7 @@ static JSBool getOption(JSContext*c, JSObject*obj, uintN argc, jsval *argv, jsva GF_Node *sc_node = JS_GetContextPrivate(c); JSString *js_sec_name, *js_key_name; if (argc < 2) return JSVAL_FALSE; - + if (!JSVAL_IS_STRING(argv[0])) return JSVAL_FALSE; js_sec_name = JSVAL_TO_STRING(argv[0]); par.gpac_cfg.section = JS_GetStringBytes(js_sec_name); @@ -553,8 +910,8 @@ static JSBool getOption(JSContext*c, JSObject*obj, uintN argc, jsval *argv, jsva s = JS_NewStringCopyZ(c, par.gpac_cfg.key_val ? (const char *)par.gpac_cfg.key_val : ""); if (!s) return JS_FALSE; - *rval = STRING_TO_JSVAL(s); - return JS_TRUE; + *rval = STRING_TO_JSVAL(s); + return JS_TRUE; } static JSBool setOption(JSContext*c, JSObject*obj, uintN argc, jsval *argv, jsval *rval) @@ -563,7 +920,7 @@ static JSBool setOption(JSContext*c, JSObject*obj, uintN argc, jsval *argv, jsva GF_Node *sc_node = JS_GetContextPrivate(c); JSString *js_sec_name, *js_key_name, *js_key_val; if (argc < 3) return JSVAL_FALSE; - + if (!JSVAL_IS_STRING(argv[0])) return JSVAL_FALSE; js_sec_name = JSVAL_TO_STRING(argv[0]); par.gpac_cfg.section = JS_GetStringBytes(js_sec_name); @@ -597,20 +954,25 @@ void Script_FieldChanged(JSContext *c, GF_Node *parent, GF_JSField *parent_owner if (!parent) return; script_field = 0; - if ((parent->sgprivate->tag == TAG_MPEG4_Script) || (parent->sgprivate->tag == TAG_X3D_Script) ) { + if ((parent->sgprivate->tag == TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (parent->sgprivate->tag == TAG_X3D_Script) +#endif + ) { script_field = 1; if ( (GF_Node *) JS_GetContextPrivate(c) == parent) script_field = 2; } if (script_field!=2) { - if (field->on_event_in) field->on_event_in(parent); + if (field->on_event_in) field->on_event_in(parent, NULL); else if (script_field && (field->eventType==GF_SG_EVENT_IN) ) { gf_sg_script_event_in(parent, field); gf_node_changed_internal(parent, field, 0); return; } /*field has changed, set routes...*/ - if (parent->sgprivate->tag == TAG_ProtoNode)gf_sg_proto_check_field_change(parent, field->fieldIndex); + if (parent->sgprivate->tag == TAG_ProtoNode) + gf_sg_proto_propagate_event(parent, field->fieldIndex, (GF_Node*)JS_GetScript(c)); else { gf_node_event_out(parent, field->fieldIndex); gf_node_changed_internal(parent, field, 0); @@ -642,7 +1004,7 @@ JSBool gf_sg_script_eventout_set_prop(JSContext *c, JSObject *obj, jsval id, jsv GF_FieldInfo info; JSString *str = JS_ValueToString(c, id); if (!str) return JS_FALSE; - + eventName = JS_GetStringBytes(str); script = JS_GetScriptStack(c); @@ -710,23 +1072,52 @@ static GFINLINE void sffield_toString(char *str, void *f_ptr, u32 fieldType) strcat(str, temp); break; } - + } } -static void JS_ObjectDestroyed(JSContext *c, JSObject *obj) +static void JS_ObjectDestroyed(JSContext *c, JSObject *obj, GF_JSField *ptr, Bool is_js_call) { - GF_ScriptPriv *priv = JS_GetScriptStack(c); + JS_SetPrivate(c, obj, NULL); + + if (ptr) { + /*if ptr is a node, remove node binding*/ + if (ptr->node + && ptr->node->sgprivate->interact + && ptr->node->sgprivate->interact->js_binding + && (ptr->node->sgprivate->interact->js_binding->node == ptr) + ) { + ptr->node->sgprivate->interact->js_binding->node = NULL; + } + + /*if ptr is a field, remove field binding from parent*/ + if (ptr->owner && ptr->owner->sgprivate->interact && ptr->owner->sgprivate->interact->js_binding) { + gf_list_del_item(ptr->owner->sgprivate->interact->js_binding->fields, ptr); + } - JS_SetPrivate(c, obj, 0); - if (priv->js_cache) - gf_list_del_item(priv->js_cache, obj); + + /* + If object is still registered, remove it from the js_cache + + !!! WATCHOUT !!! + SpiderMonkey GC may call an object finalizer on ANY context, not the one in which the object + was created !! We therefore keep a pointer to the parent context to remove GC'ed objects from the context cache + */ + if (ptr->obj && is_js_call) { + GF_ScriptPriv *priv; + if (ptr->js_ctx) c = ptr->js_ctx; + priv = JS_GetScriptStack(c); + + gf_list_del_item(priv->js_cache, obj); + } + } } static JSBool field_toString(JSContext *c, JSObject *obj, uintN n, jsval *v, jsval *rval) { - u32 i, len; + u32 i; + jsuint len; jsdouble d; char temp[1000]; char str[5000]; @@ -782,8 +1173,8 @@ static JSBool field_toString(JSContext *c, JSObject *obj, uintN n, jsval *v, jsv } s = JS_NewStringCopyZ(c, str); if (!s) return JS_FALSE; - *rval = STRING_TO_JSVAL(s); - return JS_TRUE; + *rval = STRING_TO_JSVAL(s); + return JS_TRUE; } static JSBool SFNodeConstructor(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) @@ -798,10 +1189,10 @@ static JSBool SFNodeConstructor(JSContext *c, JSObject *obj, uintN argc, jsval * GF_ScriptPriv *priv = JS_GetScriptStack(c); M_Script *sc = JS_GetScript(c); if (!argc) { - field = NewJSField(); + field = NewJSField(c); field->field.fieldType = GF_SG_VRML_SFNODE; - field->temp_node = NULL; - field->field.far_ptr = &field->temp_node; + field->node = NULL; + field->field.far_ptr = &field->node; JS_SetPrivate(c, obj, field); *rval = OBJECT_TO_JSVAL(obj); return JS_TRUE; @@ -838,10 +1229,15 @@ locate_proto: return JS_FALSE; } } else { - if (sc->sgprivate->tag==TAG_MPEG4_Script) { + switch (sc->sgprivate->tag) { + case TAG_MPEG4_Script: tag = gf_node_mpeg4_type_by_class_name(node_name); - } else { + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Script: tag = gf_node_x3d_type_by_class_name(node_name); + break; +#endif } if (!tag) goto locate_proto; new_node = gf_node_new(sc->sgprivate->scenegraph, tag); @@ -849,17 +1245,7 @@ locate_proto: gf_node_init(new_node); } - vrml_node_register(new_node, NULL); - field = NewJSField(); - field->field.fieldType = GF_SG_VRML_SFNODE; - field->temp_node = new_node; - field->field.far_ptr = &field->temp_node; - - field->obj = obj; - JS_AddRoot(c, &field->obj); - if (priv->js_cache) gf_list_add(priv->js_cache, obj); - - JS_SetPrivate(c, obj, field); + obj = node_get_binding(priv, new_node, 1); *rval = OBJECT_TO_JSVAL(obj); return JS_TRUE; @@ -867,18 +1253,20 @@ locate_proto: static void node_finalize_ex(JSContext *c, JSObject *obj, Bool is_js_call) { GF_JSField *ptr = (GF_JSField *) JS_GetPrivate(c, obj); - - if (is_js_call) - JS_ObjectDestroyed(c, obj); - + + JS_ObjectDestroyed(c, obj, ptr, is_js_call); + if (ptr) { - /*num_instances may be 0 if the node is the script being destroyed*/ - if (ptr->temp_node && ptr->temp_node->sgprivate->num_instances) { + GF_Node *parent = (GF_Node *)JS_GetScript(ptr->js_ctx ? ptr->js_ctx : c); + if (ptr->node + /*num_instances may be 0 if the node is the script being destroyed*/ + && ptr->node->sgprivate->num_instances + ) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] unregistering node %s (%s)\n", gf_node_get_name(ptr->temp_node), gf_node_get_class_name(ptr->temp_node))); - gf_node_unregister(ptr->temp_node, ptr->owner); + GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] unregistering node %s (%s)\n", gf_node_get_name(ptr->node), gf_node_get_class_name(ptr->node))); + gf_node_unregister(ptr->node, (ptr->node==parent) ? NULL : parent); } - free(ptr); + gf_free(ptr); } } static void node_finalize(JSContext *c, JSObject *obj) @@ -910,11 +1298,11 @@ static JSBool node_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) if (!strnicmp(fieldName, "_field", 6)) { index = atoi(fieldName+6); if ( gf_node_get_field(n, index, &info) == GF_OK) { - *vp = gf_sg_script_to_smjs_field(priv, &info, n, 0, 0); + *vp = gf_sg_script_to_smjs_field(priv, &info, n, 0); return JS_TRUE; } } else if ( gf_node_get_field_by_name(n, fieldName, &info) == GF_OK) { - *vp = gf_sg_script_to_smjs_field(priv, &info, n, 0, 0); + *vp = gf_sg_script_to_smjs_field(priv, &info, n, 0); return JS_TRUE; } return JS_TRUE; @@ -945,7 +1333,7 @@ static JSBool node_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) if (n && JSVAL_IS_STRING(id)) { JSString *str = JSVAL_TO_STRING(id); fieldname = JS_GetStringBytes(str); - + /*fieldID indexing*/ if (!strnicmp(fieldname, "_field", 6)) { index = atoi(fieldname+6); @@ -956,8 +1344,9 @@ static JSBool node_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) if (!strnicmp(fieldname, "set_", 4)) { fieldname+=4; if (gf_node_get_field_by_name(n, fieldname, &info) != GF_OK) return JS_TRUE; - } else + } else { return JS_TRUE; + } } } if (gf_node_get_tag(n)==TAG_ProtoNode) @@ -981,6 +1370,7 @@ static JSBool node_toString(JSContext *c, JSObject *obj, uintN i, jsval *v, jsva str[0] = 0; n = * ((GF_Node **)f->field.far_ptr); + if (!n) return JS_FALSE; name = gf_node_get_name_and_id(n, &id); if (id) { @@ -993,19 +1383,33 @@ static JSBool node_toString(JSContext *c, JSObject *obj, uintN i, jsval *v, jsva strcat(str, gf_node_get_class_name(n)); s = JS_NewStringCopyZ(c, (const char *) str); if (!s) return JS_FALSE; - *rval = STRING_TO_JSVAL(s); - return JS_TRUE; + *rval = STRING_TO_JSVAL(s); + return JS_TRUE; +} + +static JSBool node_getTime(JSContext *c, JSObject *obj, uintN i, jsval *v, jsval *rval) +{ + GF_Node *n; + GF_JSField *f; + if (! JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) return JS_FALSE; + f = (GF_JSField *) JS_GetPrivate(c, obj); + if (!f) return JS_FALSE; + + n = * ((GF_Node **)f->field.far_ptr); + if (!n) return JS_FALSE; + *rval = DOUBLE_TO_JSVAL(JS_NewDouble(c, gf_node_get_scene_time(n) )); + return JS_TRUE; } /* Generic field destructor */ static void field_finalize(JSContext *c, JSObject *obj) { GF_JSField *ptr = (GF_JSField *) JS_GetPrivate(c, obj); - JS_ObjectDestroyed(c, obj); + JS_ObjectDestroyed(c, obj, ptr, 1); if (!ptr) return; if (ptr->field_ptr) gf_sg_vrml_field_pointer_del(ptr->field_ptr, ptr->field.fieldType); - free(ptr); + gf_free(ptr); } @@ -1018,14 +1422,14 @@ static GFINLINE GF_JSField *SFImage_Create(JSContext *c, JSObject *obj, u32 w, u u32 i, len; GF_JSField *field; SFImage *v; - field = NewJSField(); + field = NewJSField(c); v = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFIMAGE); field->field_ptr = field->field.far_ptr = v; field->field.fieldType = GF_SG_VRML_SFIMAGE; v->width = w; v->height = h; v->numComponents = nbComp; - v->pixels = (u8 *) malloc(sizeof(u8) * nbComp * w * h); + v->pixels = (u8 *) gf_malloc(sizeof(u8) * nbComp * w * h); len = MIN(nbComp * w * h, pixels->count); for (i=0; i<len; i++) v->pixels[i] = (u8) pixels->vals[i]; JS_SetPrivate(c, obj, field); @@ -1057,7 +1461,7 @@ static JSBool image_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp case 0: *vp = INT_TO_JSVAL( sfi->width ); break; case 1: *vp = INT_TO_JSVAL( sfi->height); break; case 2: *vp = INT_TO_JSVAL( sfi->numComponents ); break; - case 3: + case 3: { u32 i, len; JSObject *an_obj = JS_ConstructObject(priv->js_ctx, &js_rt->MFInt32Class, 0, priv->js_obj); @@ -1068,7 +1472,7 @@ static JSBool image_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp } } break; - default: + default: return JS_TRUE; } } @@ -1081,7 +1485,7 @@ static JSBool image_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp Bool changed = 0; GF_JSField *ptr = (GF_JSField *) JS_GetPrivate(c, obj); SFImage *sfi; - + /*this is the prototype*/ if (!ptr) { if (! JSVAL_IS_STRING(id)) return JS_FALSE; @@ -1092,23 +1496,23 @@ static JSBool image_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp if (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) >= 0 && JSVAL_TO_INT(id) < 4) { switch (JSVAL_TO_INT(id)) { - case 0: - ival = JSVAL_TO_INT(vp); + case 0: + ival = JSVAL_TO_INT(*vp); changed = ! (sfi->width == ival); sfi->width = ival; - if (changed && sfi->pixels) { free(sfi->pixels); sfi->pixels = NULL; } + if (changed && sfi->pixels) { gf_free(sfi->pixels); sfi->pixels = NULL; } break; - case 1: - ival = JSVAL_TO_INT(vp); + case 1: + ival = JSVAL_TO_INT(*vp); changed = ! (sfi->height == ival); sfi->height = ival; - if (changed && sfi->pixels) { free(sfi->pixels); sfi->pixels = NULL; } + if (changed && sfi->pixels) { gf_free(sfi->pixels); sfi->pixels = NULL; } break; - case 2: - ival = JSVAL_TO_INT(vp); + case 2: + ival = JSVAL_TO_INT(*vp); changed = ! (sfi->numComponents == ival); sfi->numComponents = ival; - if (changed && sfi->pixels) { free(sfi->pixels); sfi->pixels = NULL; } + if (changed && sfi->pixels) { gf_free(sfi->pixels); sfi->pixels = NULL; } break; case 3: { @@ -1116,9 +1520,9 @@ static JSBool image_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp u32 len, i; if (!JSVAL_IS_OBJECT(*vp) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(*vp), &js_rt->MFInt32Class, NULL)) return JS_FALSE; pixels = (MFInt32 *) ((GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(*vp)))->field.far_ptr; - if (sfi->pixels) free(sfi->pixels); + if (sfi->pixels) gf_free(sfi->pixels); len = sfi->width*sfi->height*sfi->numComponents; - sfi->pixels = (char *) malloc(sizeof(char)*len); + sfi->pixels = (char *) gf_malloc(sizeof(char)*len); len = MAX(len, pixels->count); for (i=0; i<len; i++) sfi->pixels[i] = (u8) pixels->vals[i]; changed = 1; @@ -1137,7 +1541,7 @@ static GFINLINE GF_JSField *SFVec2f_Create(JSContext *c, JSObject *obj, Fixed x, { GF_JSField *field; SFVec2f *v; - field = NewJSField(); + field = NewJSField(c); v = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFVEC2F); field->field_ptr = field->field.far_ptr = v; field->field.fieldType = GF_SG_VRML_SFVEC2F; @@ -1157,6 +1561,7 @@ static JSBool SFVec2fConstructor(JSContext *c, JSObject *obj, uintN argc, jsval static JSBool vec2f_getProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) { GF_JSField *val = (GF_JSField *) JS_GetPrivate(c, obj); + if (JSVAL_IS_INT(id)) { switch (JSVAL_TO_INT(id)) { case 0: *vp = DOUBLE_TO_JSVAL(JS_NewDouble(c, FIX2FLT( ((SFVec2f*)val->field.far_ptr)->x) )); break; @@ -1183,12 +1588,12 @@ static JSBool vec2f_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp if (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) >= 0 && JSVAL_TO_INT(id) < 2 && JS_ValueToNumber(c, *vp, &d)) { switch (JSVAL_TO_INT(id)) { - case 0: + case 0: v = FLT2FIX( d); changed = ! ( ((SFVec2f*)ptr->field.far_ptr)->x == v); ((SFVec2f*)ptr->field.far_ptr)->x = v; break; - case 1: + case 1: v = FLT2FIX( d); changed = ! ( ((SFVec2f*)ptr->field.far_ptr)->y == v); ((SFVec2f*)ptr->field.far_ptr)->y = v; @@ -1211,7 +1616,7 @@ static JSBool vec2f_add(JSContext *c, JSObject *obj, uintN argc, jsval *argv, js v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; v2 = ((GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); SFVec2f_Create(c, pNew, v1->x + v2->x, v1->y + v2->y); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1225,7 +1630,7 @@ static JSBool vec2f_subtract(JSContext *c, JSObject *obj, uintN argc, jsval *arg v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; v2 = ((GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); SFVec2f_Create(c, pNew, v1->x - v2->x, v1->y - v2->y); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1235,7 +1640,7 @@ static JSBool vec2f_negate(JSContext *c, JSObject *obj, uintN n, jsval *v, jsval SFVec2f *v1; JSObject *pNew; v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); SFVec2f_Create(c, pNew, -v1->x , -v1->y ); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1248,7 +1653,7 @@ static JSBool vec2f_multiply(JSContext *c, JSObject *obj, uintN argc, jsval *arg Fixed v; if (argc<=0) return JS_FALSE; v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(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) ); @@ -1263,7 +1668,7 @@ static JSBool vec2f_divide(JSContext *c, JSObject *obj, uintN argc, jsval *argv, Fixed v; if (argc<=0) return JS_FALSE; v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(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)); @@ -1286,7 +1691,7 @@ static JSBool vec2f_normalize(JSContext *c, JSObject *obj, uintN n, jsval *val, JSObject *pNew; v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; res = gf_v2d_len(v1); - pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec2fClass, 0, JS_GetParent(c, obj)); SFVec2f_Create(c, pNew, gf_divfix(v1->x, res), gf_divfix(v1->y, res) ); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1309,7 +1714,7 @@ static GFINLINE GF_JSField *SFVec3f_Create(JSContext *c, JSObject *obj, Fixed x, { GF_JSField *field; SFVec3f *v; - field = NewJSField(); + field = NewJSField(c); v = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFVEC3F); field->field_ptr = field->field.far_ptr = v; field->field.fieldType = GF_SG_VRML_SFVEC3F; @@ -1357,17 +1762,17 @@ static JSBool vec3f_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp if (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) >= 0 && JSVAL_TO_INT(id) < 3 && JS_ValueToNumber(c, *vp, &d)) { switch (JSVAL_TO_INT(id)) { - case 0: + case 0: v = FLT2FIX( d); changed = ! ( ((SFVec3f*)ptr->field.far_ptr)->x == v); ((SFVec3f*)ptr->field.far_ptr)->x = v; break; - case 1: + case 1: v = FLT2FIX( d); changed = ! ( ((SFVec3f*)ptr->field.far_ptr)->y == v); ((SFVec3f*)ptr->field.far_ptr)->y = v; break; - case 2: + case 2: v = FLT2FIX( d); changed = ! ( ((SFVec3f*)ptr->field.far_ptr)->z == v); ((SFVec3f*)ptr->field.far_ptr)->z = v; @@ -1388,7 +1793,7 @@ static JSBool vec3f_add(JSContext *c, JSObject *obj, uintN argc, jsval *argv, js v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; v2 = ((GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); SFVec3f_Create(c, pNew, v1->x + v2->x, v1->y + v2->y, v1->z + v2->z); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1402,7 +1807,7 @@ static JSBool vec3f_subtract(JSContext *c, JSObject *obj, uintN argc, jsval *arg v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; v2 = ((GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); SFVec3f_Create(c, pNew, v1->x - v2->x, v1->y - v2->y, v1->z - v2->z); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1412,7 +1817,7 @@ static JSBool vec3f_negate(JSContext *c, JSObject *obj, uintN n, jsval *v, jsval SFVec3f *v1; JSObject *pNew; v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); SFVec3f_Create(c, pNew, -v1->x , -v1->y , -v1->z ); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1426,7 +1831,7 @@ static JSBool vec3f_multiply(JSContext *c, JSObject *obj, uintN argc, jsval *arg if (argc<=0) return JS_FALSE; v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(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) ); @@ -1441,7 +1846,7 @@ static JSBool vec3f_divide(JSContext *c, JSObject *obj, uintN argc, jsval *argv, Fixed v; if (argc<=0) return JS_FALSE; v1 = ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(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)); @@ -1463,7 +1868,7 @@ static JSBool vec3f_normalize(JSContext *c, JSObject *obj, uintN n, jsval *val, JSObject *pNew; v1 = * (SFVec3f *) ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; gf_vec_norm(&v1); - pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); SFVec3f_Create(c, pNew, v1.x, v1.y, v1.z); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1489,7 +1894,7 @@ static JSBool vec3f_cross(JSContext *c, JSObject *obj, uintN argc, jsval *argv, v1 = * (SFVec3f *) ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; v2 = * (SFVec3f *) ((GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); v3 = gf_vec_cross(v1, v2); SFVec3f_Create(c, pNew, v3.x, v3.y, v3.z); *rval = OBJECT_TO_JSVAL(pNew); @@ -1503,7 +1908,7 @@ static GFINLINE GF_JSField *SFRotation_Create(JSContext *c, JSObject *obj, Fixed { GF_JSField *field; SFRotation *v; - field = NewJSField(); + field = NewJSField(c); v = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFROTATION); field->field_ptr = field->field.far_ptr = v; field->field.fieldType = GF_SG_VRML_SFROTATION; @@ -1588,22 +1993,22 @@ static JSBool rot_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp) if (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) >= 0 && JSVAL_TO_INT(id) < 4 && JS_ValueToNumber(c, *vp, &d)) { switch (JSVAL_TO_INT(id)) { - case 0: + case 0: v = FLT2FIX(d); changed = ! ( ((SFRotation*)ptr->field.far_ptr)->x == v); ((SFRotation*)ptr->field.far_ptr)->x = v; break; - case 1: + case 1: v = FLT2FIX(d); changed = ! ( ((SFRotation*)ptr->field.far_ptr)->y == v); ((SFRotation*)ptr->field.far_ptr)->y = v; break; - case 2: + case 2: v = FLT2FIX(d); changed = ! ( ((SFRotation*)ptr->field.far_ptr)->z == v); ((SFRotation*)ptr->field.far_ptr)->z = v; break; - case 3: + case 3: v = FLT2FIX(d); changed = ! ( ((SFRotation*)ptr->field.far_ptr)->q == v); ((SFRotation*)ptr->field.far_ptr)->q = v; @@ -1620,7 +2025,7 @@ static JSBool rot_getAxis(JSContext *c, JSObject *obj, uintN argc, jsval *argv, SFRotation r; JSObject *pNew; r = * (SFRotation *) ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); SFVec3f_Create(c, pNew, r.x, r.y, r.z); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1630,7 +2035,7 @@ static JSBool rot_inverse(JSContext *c, JSObject *obj, uintN argc, jsval *argv, SFRotation r; JSObject *pNew; r = * (SFRotation *) ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; - pNew = JS_NewObject(c, &js_rt->SFRotationClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFRotationClass, 0, JS_GetParent(c, obj)); SFRotation_Create(c, pNew, r.x, r.y, r.z, r.q-GF_PI); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1644,7 +2049,7 @@ static JSBool rot_multiply(JSContext *c, JSObject *obj, uintN argc, jsval *argv, if (argc<=0 || !JSVAL_IS_OBJECT(argv[0]) || !JS_InstanceOf(c, JSVAL_TO_OBJECT(argv[0]), &js_rt->SFRotationClass, NULL)) return JS_FALSE; - + r1 = * (SFRotation *) ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; r2 = * (SFRotation *) ((GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(argv[0])))->field.far_ptr; q1 = gf_quat_from_rotation(r1); @@ -1652,7 +2057,7 @@ static JSBool rot_multiply(JSContext *c, JSObject *obj, uintN argc, jsval *argv, q1 = gf_quat_multiply(&q1, &q2); r1 = gf_quat_to_rotation(&q1); - pNew = JS_NewObject(c, &js_rt->SFRotationClass, 0, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFRotationClass, 0, JS_GetParent(c, obj)); SFRotation_Create(c, pNew, r1.x, r1.y, r1.z, r1.q); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1673,7 +2078,7 @@ static JSBool rot_multVec(JSContext *c, JSObject *obj, uintN argc, jsval *argv, 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, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFVec3fClass, 0, JS_GetParent(c, obj)); SFVec3f_Create(c, pNew, v.x, v.y, v.z); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1711,7 +2116,7 @@ static JSBool rot_slerp(JSContext *c, JSObject *obj, uintN argc, jsval *argv, js 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, JS_GetParent(c, obj)); + pNew = JS_NewObject(c, &js_rt->SFRotationClass, 0, JS_GetParent(c, obj)); SFRotation_Create(c, pNew, res.x, res.y, res.z, res.q); *rval = OBJECT_TO_JSVAL(pNew); return JS_TRUE; @@ -1722,7 +2127,7 @@ static GFINLINE GF_JSField *SFColor_Create(JSContext *c, JSObject *obj, Fixed r, { GF_JSField *field; SFColor *v; - field = NewJSField(); + field = NewJSField(c); v = gf_sg_vrml_field_pointer_new(GF_SG_VRML_SFCOLOR); field->field_ptr = field->field.far_ptr = v; field->field.fieldType = GF_SG_VRML_SFCOLOR; @@ -1770,22 +2175,22 @@ static JSBool color_setProperty(JSContext *c, JSObject *obj, jsval id, jsval *vp if (JSVAL_IS_INT(id) && JSVAL_TO_INT(id) >= 0 && JSVAL_TO_INT(id) < 3 && JS_ValueToNumber(c, *vp, &d)) { switch (JSVAL_TO_INT(id)) { - case 0: + case 0: v = FLT2FIX(d); changed = ! ( ((SFColor*)ptr->field.far_ptr)->red == v); ((SFColor*)ptr->field.far_ptr)->red = v; break; - case 1: + case 1: v = FLT2FIX(d); changed = ! ( ((SFColor*)ptr->field.far_ptr)->green == v); ((SFColor*)ptr->field.far_ptr)->green = v; break; - case 2: + case 2: v = FLT2FIX(d); changed = ! ( ((SFColor*)ptr->field.far_ptr)->blue == v); ((SFColor*)ptr->field.far_ptr)->blue = v; break; - default: + default: return JS_TRUE; } if (changed) Script_FieldChanged(c, NULL, ptr, NULL); @@ -1829,16 +2234,21 @@ static JSBool color_getHSV(JSContext *c, JSObject *obj, uintN n, jsval *va, jsva return JS_TRUE; } - -static JSBool MFArrayConstructor(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, u32 fieldType) +static void setup_js_array(JSContext *c, JSObject *obj, GF_JSField *ptr, uintN argc, jsval *argv) { GF_ScriptPriv *priv = JS_GetScriptStack(c); - GF_JSField *ptr = NewJSField(); - ptr->field.fieldType = fieldType; + ptr->obj = obj; ptr->js_list = JS_NewArrayObject(c, (jsint) argc, argv); - JS_AddRoot(c, &ptr->js_list); + gf_js_add_root(c, &ptr->js_list); + ptr->is_rooted = 1; gf_list_add(priv->js_cache, obj); +} +static JSBool MFArrayConstructor(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, u32 fieldType) +{ + GF_JSField *ptr = NewJSField(c); + ptr->field.fieldType = fieldType; + setup_js_array(c, obj, ptr, (jsint) argc, argv); JS_SetPrivate(c, obj, ptr); *rval = OBJECT_TO_JSVAL(obj); return obj == 0 ? JS_FALSE : JS_TRUE; @@ -1877,22 +2287,25 @@ static JSBool MFNodeConstructor(JSContext *c, JSObject *obj, uintN argc, jsval * static void array_finalize_ex(JSContext *c, JSObject *obj, Bool is_js_call) { GF_JSField *ptr = (GF_JSField *) JS_GetPrivate(c, obj); - if (is_js_call) - JS_ObjectDestroyed(c, obj); + + JS_ObjectDestroyed(c, obj, ptr, 1); + if (!ptr) return; GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] unregistering MFField %s\n", ptr->field.name)); - if (ptr->js_list) JS_RemoveRoot(c, &ptr->js_list); + if (ptr->js_list && ptr->is_rooted) { + gf_js_remove_root(c, &ptr->js_list); + } /*MFNode*/ if (ptr->temp_list) { gf_node_unregister_children(ptr->owner, ptr->temp_list); - } + } if (ptr->field_ptr) { gf_sg_vrml_field_pointer_del(ptr->field_ptr, ptr->field.fieldType); } - free(ptr); + gf_free(ptr); } static void array_finalize(JSContext *c, JSObject *obj) { @@ -1914,7 +2327,8 @@ JSBool array_getElement(JSContext *c, JSObject *obj, jsval id, jsval *rval) //this could be overloaded for each MF type... JSBool array_setElement(JSContext *c, JSObject *obj, jsval id, jsval *rval) { - u32 ind, len; + u32 ind; + jsuint len; jsdouble d; GF_JSField *from; JSBool ret; @@ -1943,28 +2357,28 @@ JSBool array_setElement(JSContext *c, JSObject *obj, jsval id, jsval *rval) while (len<ind) { jsval a_val; switch (ptr->field.fieldType) { - case GF_SG_VRML_MFBOOL: - a_val = BOOLEAN_TO_JSVAL(0); + case GF_SG_VRML_MFBOOL: + a_val = BOOLEAN_TO_JSVAL(0); break; - case GF_SG_VRML_MFINT32: - a_val = INT_TO_JSVAL(0); + case GF_SG_VRML_MFINT32: + a_val = INT_TO_JSVAL(0); break; - case GF_SG_VRML_MFFLOAT: - case GF_SG_VRML_MFTIME: + case GF_SG_VRML_MFFLOAT: + case GF_SG_VRML_MFTIME: a_val = DOUBLE_TO_JSVAL( JS_NewDouble(c, 0) ); break; case GF_SG_VRML_MFSTRING: case GF_SG_VRML_MFURL: a_val = STRING_TO_JSVAL( JS_NewStringCopyZ(c, "") ); break; - case GF_SG_VRML_MFVEC2F: - case GF_SG_VRML_MFVEC3F: + case GF_SG_VRML_MFVEC2F: + case GF_SG_VRML_MFVEC3F: case GF_SG_VRML_MFCOLOR: - case GF_SG_VRML_MFROTATION: + case GF_SG_VRML_MFROTATION: a_val = OBJECT_TO_JSVAL( JS_ConstructObject(c, the_sf_class, 0, obj) ); break; - default: - a_val = INT_TO_JSVAL(0); + default: + a_val = INT_TO_JSVAL(0); break; } @@ -1974,7 +2388,7 @@ JSBool array_setElement(JSContext *c, JSObject *obj, jsval id, jsval *rval) JS_SetElement(c, ptr->js_list, len, &a_val); len++; } - if (ptr->field.fieldType!=GF_SG_VRML_MFNODE) + if (ptr->field.far_ptr && (ptr->field.fieldType!=GF_SG_VRML_MFNODE)) gf_sg_vrml_mf_insert(ptr->field.far_ptr, ptr->field.fieldType, &sf_slot, ind); } @@ -1997,14 +2411,25 @@ JSBool array_setElement(JSContext *c, JSObject *obj, jsval id, jsval *rval) } else if (ptr->field.fieldType==GF_SG_VRML_MFURL) { if (!JSVAL_IS_STRING(*rval)) return JS_FALSE; } - ret = JS_SetElement(c, ptr->js_list, ind, rval); - if (ret==JS_FALSE) return JS_FALSE; - if (!ptr->owner) return JS_TRUE; /*rewrite MFNode entry*/ if (ptr->field.fieldType==GF_SG_VRML_MFNODE) { GF_Node *prev_n, *new_n; + JSObject *anobj; + GF_JSField *pf; + + if (!ptr->owner) return JS_TRUE; + + anobj = JSVAL_TO_OBJECT(*rval); + pf = JS_GetPrivate(c, anobj); + + + anobj = node_get_binding(JS_GetScriptStack(c), pf->node, 0); + + /*add it to the new object if needed*/ + ret = JS_SetElement(c, ptr->js_list, ind, rval); + /*get and delete previous node if any, but unregister later*/ prev_n = gf_node_list_del_child_idx( (GF_ChildNodeItem **)ptr->field.far_ptr, ind); @@ -2013,7 +2438,7 @@ JSBool array_setElement(JSContext *c, JSObject *obj, jsval id, jsval *rval) new_n = *(GF_Node**)from->field.far_ptr; if (new_n) { gf_node_list_insert_child( (GF_ChildNodeItem **)ptr->field.far_ptr , new_n, ind); - vrml_node_register(new_n, ptr->owner); + gf_node_register(new_n, ptr->owner); } /*unregister previous node*/ if (prev_n) gf_node_unregister(prev_n, ptr->owner); @@ -2022,6 +2447,11 @@ JSBool array_setElement(JSContext *c, JSObject *obj, jsval id, jsval *rval) return JS_TRUE; } + ret = JS_SetElement(c, ptr->js_list, ind, rval); + if (ret==JS_FALSE) return JS_FALSE; + + if (!ptr->owner) return JS_TRUE; + /*rewrite MF slot*/ switch (ptr->field.fieldType) { case GF_SG_VRML_MFBOOL: @@ -2040,31 +2470,40 @@ JSBool array_setElement(JSContext *c, JSObject *obj, jsval id, jsval *rval) break; case GF_SG_VRML_MFSTRING: if (((MFString *)ptr->field.far_ptr)->vals[ind]) { - free(((MFString *)ptr->field.far_ptr)->vals[ind]); + 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_val = JS_GetStringBytes(str); - ((MFString *)ptr->field.far_ptr)->vals[ind] = strdup(str_val); + ((MFString *)ptr->field.far_ptr)->vals[ind] = gf_strdup(str_val); break; case GF_SG_VRML_MFURL: if (((MFURL *)ptr->field.far_ptr)->vals[ind].url) { - free(((MFURL *)ptr->field.far_ptr)->vals[ind].url); + 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_val = JS_GetStringBytes(str); - ((MFURL *)ptr->field.far_ptr)->vals[ind].url = strdup(str_val); + ((MFURL *)ptr->field.far_ptr)->vals[ind].url = gf_strdup(str_val); ((MFURL *)ptr->field.far_ptr)->vals[ind].OD_ID = 0; break; case GF_SG_VRML_MFVEC2F: + from = (GF_JSField *) JS_GetPrivate(c, JSVAL_TO_OBJECT(*rval)); + 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 *) JS_GetPrivate(c, JSVAL_TO_OBJECT(*rval)); + 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 *) JS_GetPrivate(c, JSVAL_TO_OBJECT(*rval)); + 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 *) JS_GetPrivate(c, JSVAL_TO_OBJECT(*rval)); - gf_sg_vrml_field_copy(& ((GenMFField *)ptr->field.far_ptr)->array[ind], from->field.far_ptr, from->field.fieldType); + gf_sg_vrml_field_copy(& ((MFColor *)ptr->field.far_ptr)->vals[ind], from->field.far_ptr, from->field.fieldType); break; } @@ -2080,8 +2519,7 @@ JSBool array_setLength(JSContext *c, JSObject *obj, jsval v, jsval *val) GF_JSField *ptr = (GF_JSField *) JS_GetPrivate(c, obj); if (!JSVAL_IS_INT(*val) || JSVAL_TO_INT(*val) < 0) return JS_FALSE; len = JSVAL_TO_INT(*val); - ret = JS_SetArrayLength(c, ptr->js_list, len); - if (ret==JS_FALSE) return ret; + if (!len) { if (ptr->field.fieldType==GF_SG_VRML_MFNODE) { @@ -2090,9 +2528,14 @@ JSBool array_setLength(JSContext *c, JSObject *obj, jsval v, jsval *val) } else { gf_sg_vrml_mf_reset(ptr->field.far_ptr, ptr->field.fieldType); } + JS_SetArrayLength(c, ptr->js_list, 0); + Script_FieldChanged(c, NULL, ptr, NULL); return JS_TRUE; } + ret = JS_SetArrayLength(c, ptr->js_list, len); + if (ret==JS_FALSE) return ret; + #if 0 /*insert till index if needed*/ if (ptr->field.fieldType != GF_SG_VRML_MFNODE) { @@ -2109,7 +2552,18 @@ JSBool array_setLength(JSContext *c, JSObject *obj, jsval v, jsval *val) case GF_SG_VRML_MFVEC3F: the_sf_class = &js_rt->SFVec3fClass; break; case GF_SG_VRML_MFCOLOR: the_sf_class = &js_rt->SFColorClass; break; case GF_SG_VRML_MFROTATION: the_sf_class = &js_rt->SFRotationClass; break; - case GF_SG_VRML_MFNODE: the_sf_class = &js_rt->SFNodeClass; break; + case GF_SG_VRML_MFNODE: + { + u32 c = gf_node_list_get_count(*(GF_ChildNodeItem**)ptr->field.far_ptr); + while (len < c) { + GF_Node *n = gf_node_list_del_child_idx((GF_ChildNodeItem**)ptr->field.far_ptr, c-1); + if (n) gf_node_unregister(n, ptr->owner); + c--; + } + if (len>c) + fprintf(stdout, "NOT SUPPORTED!!!\n"); + } + return JS_TRUE; } sftype = gf_sg_vrml_get_sf_type(ptr->field.fieldType); for (i=0; i<len; i++) { @@ -2121,8 +2575,8 @@ JSBool array_setLength(JSContext *c, JSObject *obj, jsval v, jsval *val) switch (sftype) { case GF_SG_VRML_SFBOOL: a_val = BOOLEAN_TO_JSVAL(0); break; case GF_SG_VRML_SFINT32: a_val = INT_TO_JSVAL(0); break; - case GF_SG_VRML_SFFLOAT: - case GF_SG_VRML_SFTIME: + case GF_SG_VRML_SFFLOAT: + case GF_SG_VRML_SFTIME: a_val = DOUBLE_TO_JSVAL( JS_NewDouble(c, 0) ); break; case GF_SG_VRML_SFSTRING: @@ -2153,8 +2607,8 @@ static JSBool MFVec2fConstructor(JSContext *c, JSObject *obj, uintN argc, jsval jsval val; JSObject *item; u32 i; - GF_JSField *ptr = NewJSField(); - ptr->js_list = JS_NewArrayObject(c, 0, 0); + GF_JSField *ptr = NewJSField(c); + setup_js_array(c, obj, ptr, 0, 0); JS_SetArrayLength(c, ptr->js_list, argc); JS_SetPrivate(c, obj, ptr); @@ -2177,9 +2631,9 @@ static JSBool MFVec3fConstructor(JSContext *c, JSObject *obj, uintN argc, jsval jsval val; JSObject *item; u32 i; - GF_JSField *ptr = NewJSField(); + GF_JSField *ptr = NewJSField(c); ptr->field.fieldType = GF_SG_VRML_MFVEC3F; - ptr->js_list = JS_NewArrayObject(c, (jsint) argc, argv); + setup_js_array(c, obj, ptr, 0, 0); JS_SetArrayLength(c, ptr->js_list, argc); JS_SetPrivate(c, obj, ptr); @@ -2202,9 +2656,9 @@ static JSBool MFRotationConstructor(JSContext *c, JSObject *obj, uintN argc, jsv jsval val; JSObject *item; u32 i; - GF_JSField *ptr = NewJSField(); + GF_JSField *ptr = NewJSField(c); ptr->field.fieldType = GF_SG_VRML_MFROTATION; - ptr->js_list = JS_NewArrayObject(c, 0, 0); + setup_js_array(c, obj, ptr, 0, 0); JS_SetArrayLength(c, ptr->js_list, argc); JS_SetPrivate(c, obj, ptr); @@ -2227,9 +2681,9 @@ static JSBool MFColorConstructor(JSContext *c, JSObject *obj, uintN argc, jsval jsval val; JSObject *item; u32 i; - GF_JSField *ptr = NewJSField(); + GF_JSField *ptr = NewJSField(c); ptr->field.fieldType = GF_SG_VRML_MFCOLOR; - ptr->js_list = JS_NewArrayObject(c, 0, 0); + setup_js_array(c, obj, ptr, 0, 0); JS_SetArrayLength(c, ptr->js_list, argc); JS_SetPrivate(c, obj, ptr); @@ -2247,8 +2701,9 @@ static JSBool MFColorConstructor(JSContext *c, JSObject *obj, uintN argc, jsval } #ifndef GPAC_DISABLE_SVG -JSBool dom_event_add_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node); -JSBool dom_event_remove_listener_ex(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node); + +JSBool gf_sg_js_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node); +JSBool gf_sg_js_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval, GF_Node *vrml_node); JSBool vrml_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -2258,8 +2713,8 @@ JSBool vrml_event_add_listener(JSContext *c, JSObject *obj, uintN argc, jsval *a ptr = (GF_JSField *) JS_GetPrivate(c, obj); assert(ptr->field.fieldType==GF_SG_VRML_SFNODE); node = * ((GF_Node **)ptr->field.far_ptr); - - return dom_event_add_listener_ex(c, obj, argc, argv, rval, node); + + return gf_sg_js_event_add_listener(c, obj, argc, argv, rval, node); } JSBool vrml_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) { @@ -2270,12 +2725,12 @@ JSBool vrml_event_remove_listener(JSContext *c, JSObject *obj, uintN argc, jsval assert(ptr->field.fieldType==GF_SG_VRML_SFNODE); node = * ((GF_Node **)ptr->field.far_ptr); - return dom_event_remove_listener_ex(c, obj, argc, argv, rval, node); + return gf_sg_js_event_remove_listener(c, obj, argc, argv, rval, node); } #endif static JSBool vrml_dom3_not_implemented(JSContext *c, JSObject *obj, uintN argc, jsval *argv, jsval *rval) -{ +{ return JS_FALSE; } @@ -2284,7 +2739,7 @@ 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_SETUP_CLASS(js_rt->globalClass, "global", JSCLASS_HAS_PRIVATE, JS_PropertyStub, JS_PropertyStub, JS_FinalizeStub); JS_SETUP_CLASS(js_rt->browserClass , "Browser", 0, @@ -2310,7 +2765,7 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script) JS_SETUP_CLASS(js_rt->MFInt32Class , "MFInt32", JSCLASS_HAS_PRIVATE, array_getElement, array_setElement, array_finalize); - + JS_SETUP_CLASS(js_rt->MFBoolClass , "MFBool", JSCLASS_HAS_PRIVATE, array_getElement, array_setElement, array_finalize); @@ -2347,8 +2802,10 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script) JS_InitStandardClasses(sc->js_ctx, sc->js_obj); { JSFunctionSpec globalFunctions[] = { - {"print", JSPrint, 0}, - { 0 } + {"print", JSPrint, 0, 0, 0}, + {"alert", JSPrint, 0, 0, 0}, + {"parseXML", vrml_parse_xml, 0, 0, 0}, + {0, 0, 0, 0, 0} }; JS_DefineFunctions(sc->js_ctx, sc->js_obj, globalFunctions ); } @@ -2356,122 +2813,125 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script) JS_SetPrivate(sc->js_ctx, sc->js_obj, script->sgprivate->scenegraph); - JS_DefineProperty(sc->js_ctx, sc->js_obj, "FALSE", BOOLEAN_TO_JSVAL(0), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT ); - JS_DefineProperty(sc->js_ctx, sc->js_obj, "TRUE", BOOLEAN_TO_JSVAL(1), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT ); + JS_DefineProperty(sc->js_ctx, sc->js_obj, "FALSE", BOOLEAN_TO_JSVAL(JS_FALSE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT ); + JS_DefineProperty(sc->js_ctx, sc->js_obj, "TRUE", BOOLEAN_TO_JSVAL(JS_TRUE), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT ); + 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 ); JS_DefineProperty(sc->js_ctx, sc->js_browser, "_this", PRIVATE_TO_JSVAL(script), 0, 0, JSPROP_READONLY | JSPROP_PERMANENT ); { JSFunctionSpec browserFunctions[] = { - {"getName", getName, 0}, - {"getVersion", getVersion, 0}, - {"getCurrentSpeed", getCurrentSpeed, 0}, - {"getCurrentFrameRate", getCurrentFrameRate, 0}, - {"getWorldURL", getWorldURL, 0}, - {"replaceWorld", replaceWorld, 0}, - {"addRoute", addRoute, 0}, - {"deleteRoute", deleteRoute, 0}, - {"loadURL", loadURL, 0}, - {"createVrmlFromString", createVrmlFromString, 0}, - {"setDescription", setDescription, 0}, - {"print", JSPrint, 0}, - {"getOption", getOption, 0}, - {"setOption", setOption, 0}, - {"getScript", getScript, 0}, - {"getProto", getProto, 0}, - {"getElementById", getElementById, 0}, - {0} + {"getName", getName, 0, 0, 0}, + {"getVersion", getVersion, 0, 0, 0}, + {"getCurrentSpeed", getCurrentSpeed, 0, 0, 0}, + {"getCurrentFrameRate", getCurrentFrameRate, 0, 0, 0}, + {"getWorldURL", getWorldURL, 0, 0, 0}, + {"replaceWorld", replaceWorld, 1, 0, 0}, + {"addRoute", addRoute, 4, 0, 0}, + {"deleteRoute", deleteRoute, 4, 0, 0}, + {"loadURL", loadURL, 1, 0, 0}, + {"createVrmlFromString", createVrmlFromString, 1, 0, 0}, + {"setDescription", setDescription, 1, 0, 0}, + {"print", JSPrint, 1, 0, 0}, + {"getOption", getOption, 2, 0, 0}, + {"setOption", setOption, 3, 0, 0}, + {"getScript", getScript, 0, 0, 0}, + {"getProto", getProto, 0, 0, 0}, + {"loadScript", loadScript, 1, 0, 0}, + {"getElementById", getElementById, 1, 0, 0}, + {0, 0, 0, 0, 0} }; JS_DefineFunctions(sc->js_ctx, sc->js_browser, browserFunctions); } { JSFunctionSpec SFNodeMethods[] = { - {"toString", node_toString, 0}, + {"toString", node_toString, 0, 0, 0}, + {"getTime", node_getTime, 0, 0, 0}, #ifndef GPAC_DISABLE_SVG - {"addEventListenerNS", vrml_event_add_listener, 4}, - {"removeEventListenerNS", vrml_event_remove_listener, 4}, - {"addEventListener", vrml_event_add_listener, 3}, - {"removeEventListener", vrml_event_remove_listener, 3}, - {"dispatchEvent", vrml_dom3_not_implemented, 1}, + {"addEventListenerNS", vrml_event_add_listener, 4, 0, 0}, + {"removeEventListenerNS", vrml_event_remove_listener, 4, 0, 0}, + {"addEventListener", vrml_event_add_listener, 3, 0, 0}, + {"removeEventListener", vrml_event_remove_listener, 3, 0, 0}, + {"dispatchEvent", vrml_dom3_not_implemented, 1, 0, 0}, #endif - {0} + {0, 0, 0, 0, 0} }; JSPropertySpec SFNodeProps[] = { - {"__dummy", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {0} + {"__dummy", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 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); } { JSPropertySpec SFVec2fProps[] = { - {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {0} + {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {0, 0, 0, 0, 0} }; JSFunctionSpec SFVec2fMethods[] = { - {"add", vec2f_add, 1}, - {"divide", vec2f_divide, 1}, - {"dot", vec2f_dot, 1}, - {"length", vec2f_length, 0}, - {"multiply", vec2f_multiply, 1}, - {"normalize", vec2f_normalize,0}, - {"subtract", vec2f_subtract, 1}, - {"negate", vec2f_negate, 0}, - {"toString", field_toString, 0}, - {0} + {"add", vec2f_add, 1, 0, 0}, + {"divide", vec2f_divide, 1, 0, 0}, + {"dot", vec2f_dot, 1, 0, 0}, + {"length", vec2f_length, 0, 0, 0}, + {"multiply", vec2f_multiply, 1, 0, 0}, + {"normalize", vec2f_normalize,0, 0, 0}, + {"subtract", vec2f_subtract, 1, 0, 0}, + {"negate", vec2f_negate, 0, 0, 0}, + {"toString", field_toString, 0, 0, 0}, + {0, 0, 0, 0, 0} }; JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFVec2fClass, SFVec2fConstructor, 0, SFVec2fProps, SFVec2fMethods, 0, 0); } { JSPropertySpec SFVec3fProps[] = { - {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"z", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {0} + {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"z", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {0, 0, 0, 0, 0} }; JSFunctionSpec SFVec3fMethods[] = { - {"add", vec3f_add, 1}, - {"divide", vec3f_divide, 1}, - {"dot", vec3f_dot, 1}, - {"length", vec3f_length, 0}, - {"multiply", vec3f_multiply, 1}, - {"normalize", vec3f_normalize,0}, - {"subtract", vec3f_subtract, 1}, - {"cross", vec3f_cross, 1}, - {"negate", vec3f_negate, 0}, - {"toString", field_toString, 0}, - {0} + {"add", vec3f_add, 1, 0, 0}, + {"divide", vec3f_divide, 1, 0, 0}, + {"dot", vec3f_dot, 1, 0, 0}, + {"length", vec3f_length, 0, 0, 0}, + {"multiply", vec3f_multiply, 1, 0, 0}, + {"normalize", vec3f_normalize,0, 0, 0}, + {"subtract", vec3f_subtract, 1, 0, 0}, + {"cross", vec3f_cross, 1, 0, 0}, + {"negate", vec3f_negate, 0, 0, 0}, + {"toString", field_toString, 0, 0, 0}, + {0, 0, 0, 0, 0} }; JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFVec3fClass, SFVec3fConstructor, 0, SFVec3fProps, SFVec3fMethods, 0, 0); } { JSPropertySpec SFRotationProps[] = { - {"xAxis", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"yAxis", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"zAxis", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"angle", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {0} + {"xAxis", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"yAxis", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"zAxis", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"angle", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {0, 0, 0, 0, 0} }; JSFunctionSpec SFRotationMethods[] = { - {"getAxis", rot_getAxis, 1}, - {"inverse", rot_inverse, 1}, - {"multiply", rot_multiply, 1}, - {"multVec", rot_multVec, 0}, - {"setAxis", rot_setAxis, 1}, - {"slerp", rot_slerp,0}, - {"toString", field_toString, 0}, - {0} + {"getAxis", rot_getAxis, 1, 0, 0}, + {"inverse", rot_inverse, 1, 0, 0}, + {"multiply", rot_multiply, 1, 0, 0}, + {"multVec", rot_multVec, 0, 0, 0}, + {"setAxis", rot_setAxis, 1, 0, 0}, + {"slerp", rot_slerp,0, 0, 0}, + {"toString", field_toString, 0, 0, 0}, + {0, 0, 0, 0, 0} }; JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->SFRotationClass, SFRotationConstructor, 0, SFRotationProps, SFRotationMethods, 0, 0); } { JSPropertySpec SFColorProps[] = { - {"r", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"g", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"b", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {0} + {"r", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"g", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"b", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {0, 0, 0, 0, 0} }; JSFunctionSpec SFColorMethods[] = { {"setHSV", color_setHSV, 3, 0, 0}, @@ -2483,11 +2943,11 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script) } { JSPropertySpec SFImageProps[] = { - {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"comp", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {"array", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT}, - {0} + {"x", 0, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"y", 1, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"comp", 2, JSPROP_ENUMERATE | JSPROP_PERMANENT, 0, 0}, + {"array", 3, JSPROP_ENUMERATE | JSPROP_PERMANENT, 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); } @@ -2496,11 +2956,11 @@ void gf_sg_script_init_sm_api(GF_ScriptPriv *sc, GF_Node *script) JSPropertySpec MFArrayProp[] = { { "length", 0, JSPROP_PERMANENT, array_getLength, array_setLength }, { "assign", 0, JSPROP_PERMANENT, array_getElement, array_setElement}, - { 0, 0, 0, 0, 0 } + { 0, 0, 0, 0, 0 } }; JSFunctionSpec MFArrayMethods[] = { - {"toString", field_toString, 0}, - {0} + {"toString", field_toString, 0, 0, 0}, + {0, 0, 0, 0, 0} }; JS_InitClass(sc->js_ctx, sc->js_obj, 0, &js_rt->MFInt32Class, MFInt32Constructor, 0, MFArrayProp, MFArrayMethods, 0, 0); @@ -2586,8 +3046,8 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF char *str_val = JS_GetStringBytes(str); /*we do filter strings since rebuilding a text is quite slow, so let's avoid killing the compositors*/ if (!s->buffer || strcmp(str_val, s->buffer)) { - if ( s->buffer) free(s->buffer); - s->buffer = strdup(str_val); + if ( s->buffer) gf_free(s->buffer); + s->buffer = gf_strdup(str_val); Script_FieldChanged(c, owner, parent, field); } return; @@ -2595,8 +3055,8 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF case GF_SG_VRML_SFURL: { JSString *str = JSVAL_IS_STRING(val) ? JSVAL_TO_STRING(val) : JS_ValueToString(c, val); - if (((SFURL*)field->far_ptr)->url) free(((SFURL*)field->far_ptr)->url); - ((SFURL*)field->far_ptr)->url = strdup(JS_GetStringBytes(str)); + if (((SFURL*)field->far_ptr)->url) gf_free(((SFURL*)field->far_ptr)->url); + ((SFURL*)field->far_ptr)->url = gf_strdup(JS_GetStringBytes(str)); ((SFURL*)field->far_ptr)->OD_ID = 0; Script_FieldChanged(c, owner, parent, field); return; @@ -2606,7 +3066,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF JSString *str = JSVAL_TO_STRING(val); gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType); gf_sg_vrml_mf_alloc(field->far_ptr, field->fieldType, 1); - ((MFString*)field->far_ptr)->vals[0] = strdup(JS_GetStringBytes(str)); + ((MFString*)field->far_ptr)->vals[0] = gf_strdup(JS_GetStringBytes(str)); Script_FieldChanged(c, owner, parent, field); return; } @@ -2615,7 +3075,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF JSString *str = JSVAL_TO_STRING(val); gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType); gf_sg_vrml_mf_alloc(field->far_ptr, field->fieldType, 1); - ((MFURL*)field->far_ptr)->vals[0].url = strdup(JS_GetStringBytes(str)); + ((MFURL*)field->far_ptr)->vals[0].url = gf_strdup(JS_GetStringBytes(str)); ((MFURL*)field->far_ptr)->vals[0].OD_ID = 0; Script_FieldChanged(c, owner, parent, field); return; @@ -2669,16 +3129,17 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF case GF_SG_VRML_SFNODE: { /*replace object*/ - if (*((GF_Node**)field->far_ptr)) + if (*((GF_Node**)field->far_ptr)) { gf_node_unregister(*((GF_Node**)field->far_ptr), owner); + *((GF_Node**)field->far_ptr) = NULL; + } if (JSVAL_IS_NULL(val)) { - field->far_ptr = NULL; Script_FieldChanged(c, owner, parent, field); } else if (JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) { GF_Node *n = * (GF_Node**) ((GF_JSField *) JS_GetPrivate(c, obj))->field.far_ptr; * ((GF_Node **)field->far_ptr) = n; - vrml_node_register(n, owner); + gf_node_register(n, owner); Script_FieldChanged(c, owner, parent, field); } return; @@ -2696,7 +3157,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF break; } - //from here we handle only MF fields + //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) @@ -2723,7 +3184,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF GF_ChildNodeItem *last = NULL; gf_node_unregister_children(owner, * (GF_ChildNodeItem **) field->far_ptr); * (GF_ChildNodeItem **) field->far_ptr = NULL; - + for (i=0; i<len; i++) { JSObject *node_obj; JS_GetElement(c, p->js_list, (jsint) i, &item); @@ -2736,15 +3197,17 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF child = * ((GF_Node**)from->field.far_ptr); gf_node_list_add_child_last( (GF_ChildNodeItem **) field->far_ptr , child, &last); - vrml_node_register(child, owner); + gf_node_register(child, owner); } Script_FieldChanged(c, owner, parent, field); + /*and mark the field as changed*/ + JSScript_NodeModified(owner->sgprivate->scenegraph, owner, field, NULL); return; } - + /*again, check text changes*/ changed = (field->fieldType == GF_SG_VRML_MFSTRING) ? 0 : 1; - /*realloc*/ + /*gf_realloc*/ if (len != ((GenMFField *)field->far_ptr)->count) { gf_sg_vrml_mf_reset(field->far_ptr, field->fieldType); gf_sg_vrml_mf_alloc(field->far_ptr, field->fieldType, len); @@ -2783,8 +3246,8 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF JSString *str = JSVAL_IS_STRING(item) ? JSVAL_TO_STRING(item) : JS_ValueToString(c, item); char *str_val = JS_GetStringBytes(str); if (!mfs->vals[i] || strcmp(str_val, mfs->vals[i]) ) { - if (mfs->vals[i]) free(mfs->vals[i]); - mfs->vals[i] = strdup(str_val); + if (mfs->vals[i]) gf_free(mfs->vals[i]); + mfs->vals[i] = gf_strdup(str_val); changed = 1; } } @@ -2793,8 +3256,8 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF { MFURL *mfu = (MFURL *) field->far_ptr; JSString *str = JSVAL_IS_STRING(item) ? JSVAL_TO_STRING(item) : JS_ValueToString(c, item); - if (mfu->vals[i].url) free(mfu->vals[i].url); - mfu->vals[i].url = strdup(JS_GetStringBytes(str)); + if (mfu->vals[i].url) gf_free(mfu->vals[i].url); + mfu->vals[i].url = gf_strdup(JS_GetStringBytes(str)); mfu->vals[i].OD_ID = 0; } break; @@ -2833,8 +3296,147 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF if (changed) Script_FieldChanged(c, owner, parent, field); } + +static void gf_sg_script_update_cached_object(GF_ScriptPriv *priv, JSObject *obj, GF_JSField *jsf, GF_FieldInfo *field, GF_Node *parent) +{ + u32 i; + jsval newVal; + GF_JSField *slot = NULL; + JSString *s; + + /*we need to rebuild MF types where SF is a native type.*/ + GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] Recomputing cached jsobj\n") ); + switch (jsf->field.fieldType) { + case GF_SG_VRML_MFBOOL: + { + MFBool *f = (MFBool *) field->far_ptr; + JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); + JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); + for (i=0; i<f->count; i++) { + newVal = BOOLEAN_TO_JSVAL(f->vals[i]); + JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); + } + } + break; + case GF_SG_VRML_MFINT32: + { + MFInt32 *f = (MFInt32 *) field->far_ptr; + JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); + JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); + for (i=0; i<f->count; i++) { + newVal = INT_TO_JSVAL(f->vals[i]); + JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); + } + } + break; + case GF_SG_VRML_MFFLOAT: + { + MFFloat *f = (MFFloat *) field->far_ptr; + JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); + JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); + for (i=0; i<f->count; i++) { + newVal = DOUBLE_TO_JSVAL(JS_NewDouble(priv->js_ctx, FIX2FLT(f->vals[i]))); + JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); + } + } + break; + case GF_SG_VRML_MFTIME: + { + MFTime *f = (MFTime *) field->far_ptr; + JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); + JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); + for (i=0; i<f->count; i++) { + newVal = DOUBLE_TO_JSVAL(JS_NewDouble(priv->js_ctx, f->vals[i])); + JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); + } + } + break; + case GF_SG_VRML_MFSTRING: + { + MFString *f = (MFString *) field->far_ptr; + JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); + JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); + for (i=0; i<f->count; i++) { + s = JS_NewStringCopyZ(priv->js_ctx, f->vals[i]); + newVal = STRING_TO_JSVAL( s ); + JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); + } + } + break; + case GF_SG_VRML_MFURL: + { + MFURL *f = (MFURL *) field->far_ptr; + JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); + JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); + for (i=0; i<f->count; i++) { + if (f->vals[i].OD_ID > 0) { + char msg[30]; + sprintf(msg, "od:%d", f->vals[i].OD_ID); + s = JS_NewStringCopyZ(priv->js_ctx, (const char *) msg); + } else { + s = JS_NewStringCopyZ(priv->js_ctx, f->vals[i].url); + } + newVal = STRING_TO_JSVAL(s); + JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); + } + } + break; + /* + MFNode is tricky because in VRML/MPEG-4, SFNode are assigned by referenced, not copy. + We therefore need to make sure we reuse existing SFNode object rather than + blindly recreating them + */ + case GF_SG_VRML_MFNODE: + { + GF_ChildNodeItem *f = *(GF_ChildNodeItem **) field->far_ptr; + u32 cache_count, j; + jsuint count; + GF_List *temp_objs = gf_list_new(); + + /*1: find all existing objs for each node*/ + JS_GetArrayLength(priv->js_ctx, jsf->js_list, &count); + cache_count = gf_list_count(priv->js_cache); + + while (f) { + slot = NULL; + /*first look in the original array*/ + for (j=0; j<count; j++) { + JSObject *an_obj; + JS_GetElement(priv->js_ctx, jsf->js_list, (jsint) j, &newVal); + an_obj = JSVAL_TO_OBJECT(newVal); + if (an_obj) slot = JS_GetPrivate(priv->js_ctx, an_obj); + if (slot && (slot->node==f->node)) { + gf_list_add(temp_objs, an_obj); + break; + } + slot = NULL; + } + if (!slot) { + JSObject *an_obj = node_get_binding(priv, f->node, 0); + gf_list_add(temp_objs, an_obj); + } + f = f->next; + } + /*2- and rewrite the final array*/ + count = gf_list_count(temp_objs); + if (JS_SetArrayLength(priv->js_ctx, jsf->js_list, count) != JS_TRUE) return; + for (j=0; j<count; j++) { + JSObject *an_obj = gf_list_get(temp_objs, j); + slot = JS_GetPrivate(priv->js_ctx, an_obj); + newVal = OBJECT_TO_JSVAL(an_obj); + JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) j, &newVal); + } + gf_list_del(temp_objs); + } + break; + } + jsf->field.NDTtype = 0; +} + + + #define SETUP_FIELD \ - jsf = NewJSField(); \ + jsf = NewJSField(priv->js_ctx); \ jsf->owner = parent; \ if(parent) gf_node_get_field(parent, field->fieldIndex, &jsf->field); \ @@ -2845,7 +3447,7 @@ void gf_sg_script_to_node_field(JSContext *c, jsval val, GF_FieldInfo *field, GF -jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_Node *parent, Bool skip_cache, Bool force_evaluate) +jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_Node *parent, Bool force_evaluate) { u32 i; JSObject *obj = NULL; @@ -2888,136 +3490,33 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No } +#if 1 /*look into object bank in case we already have this object*/ - if (parent && !skip_cache && priv->js_cache) { + if (parent && parent->sgprivate->interact && parent->sgprivate->interact->js_binding) { i=0; - while ((obj = gf_list_enum(priv->js_cache, &i))) { - jsf = (GF_JSField *) JS_GetPrivate(priv->js_ctx, obj); - if (jsf - && (jsf->owner==parent) + while ((jsf = gf_list_enum(parent->sgprivate->interact->js_binding->fields, &i))) { + obj = jsf->obj; + if ( + /*make sure we use the same JS context*/ + (jsf->js_ctx == priv->js_ctx) + && (jsf->owner == parent) +#if 0 && (jsf->field.fieldIndex == field->fieldIndex) /*type check needed for MFNode entries*/ - && (jsf->field.fieldType==field->fieldType) - ) { - - GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] found cached jsobj 0x%08x (field %s) in script bank 0x%08x\n", obj, field->name, priv->js_cache) ); - if (!force_evaluate && !jsf->reevaluate) return OBJECT_TO_JSVAL(obj); + && (jsf->field.fieldType==field->fieldType) +#else + && (jsf->field.far_ptr==field->far_ptr) +#endif + ) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] found cached jsobj 0x%08x (field %s) in script %s bank (%d entries)\n", obj, field->name, gf_node_get_log_name((GF_Node*)JS_GetScript(priv->js_ctx)), gf_list_count(priv->js_cache) ) ); + if (!force_evaluate && !jsf->field.NDTtype) return OBJECT_TO_JSVAL(obj); - /*we need to rebuild MF types where SF is a native type.*/ - GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] Recomputing cached jsobj\n") ); - switch (jsf->field.fieldType) { - case GF_SG_VRML_MFBOOL: - { - MFBool *f = (MFBool *) field->far_ptr; - JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); - JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); - for (i=0; i<f->count; i++) { - newVal = BOOLEAN_TO_JSVAL(f->vals[i]); - JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); - } - } - break; - case GF_SG_VRML_MFINT32: - { - MFInt32 *f = (MFInt32 *) field->far_ptr; - JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); - JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); - for (i=0; i<f->count; i++) { - newVal = INT_TO_JSVAL(f->vals[i]); - JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); - } - } - break; - case GF_SG_VRML_MFFLOAT: - { - MFFloat *f = (MFFloat *) field->far_ptr; - JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); - JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); - for (i=0; i<f->count; i++) { - newVal = DOUBLE_TO_JSVAL(JS_NewDouble(priv->js_ctx, FIX2FLT(f->vals[i]))); - JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); - } - } - break; - case GF_SG_VRML_MFTIME: - { - MFTime *f = (MFTime *) field->far_ptr; - JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); - JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); - for (i=0; i<f->count; i++) { - newVal = DOUBLE_TO_JSVAL(JS_NewDouble(priv->js_ctx, f->vals[i])); - JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); - } - } - break; - case GF_SG_VRML_MFSTRING: - { - MFString *f = (MFString *) field->far_ptr; - JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); - JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); - for (i=0; i<f->count; i++) { - s = JS_NewStringCopyZ(priv->js_ctx, f->vals[i]); - newVal = STRING_TO_JSVAL( s ); - JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); - } - } - break; - case GF_SG_VRML_MFURL: - { - MFURL *f = (MFURL *) field->far_ptr; - JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); - JS_SetArrayLength(priv->js_ctx, jsf->js_list, f->count); - for (i=0; i<f->count; i++) { - if (f->vals[i].OD_ID > 0) { - char msg[30]; - sprintf(msg, "od:%d", f->vals[i].OD_ID); - s = JS_NewStringCopyZ(priv->js_ctx, (const char *) msg); - } else { - s = JS_NewStringCopyZ(priv->js_ctx, f->vals[i].url); - } - newVal = STRING_TO_JSVAL(s); - JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); - } - } - break; - case GF_SG_VRML_MFNODE: - { - GF_ChildNodeItem *f = *(GF_ChildNodeItem **) field->far_ptr; - u32 count = 0; - while (f) { - count++; - f = f->next; - } - /*this will destroy the different objects*/ - JS_SetArrayLength(priv->js_ctx, jsf->js_list, 0); - if (JS_SetArrayLength(priv->js_ctx, jsf->js_list, count) != JS_TRUE) return JSVAL_NULL; - - count = 0; - f = *(GF_ChildNodeItem **) field->far_ptr; - while (f) { - JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFNodeClass, 0, obj); - slot = NewJSField(); - slot->owner = parent; - slot->temp_node = f->node; - slot->field.far_ptr = & slot->temp_node; - slot->field.fieldType = GF_SG_VRML_SFNODE; - vrml_node_register(f->node, parent); - JS_SetPrivate(priv->js_ctx, pf, slot); - - newVal = OBJECT_TO_JSVAL(pf); - JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) count, &newVal); - count++; - - f = f->next; - } - } - break; - } - jsf->reevaluate = 0; + gf_sg_script_update_cached_object(priv, obj, jsf, field, parent); return OBJECT_TO_JSVAL(obj); } } } +#endif GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] creating jsobj %s.%s\n", gf_node_get_name(parent), field->name) ); @@ -3043,8 +3542,15 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No obj = JS_NewObject(priv->js_ctx, &js_rt->SFImageClass, 0, priv->js_obj); break; case GF_SG_VRML_SFNODE: - SETUP_FIELD - obj = JS_NewObject(priv->js_ctx, &js_rt->SFNodeClass, 0, priv->js_obj); + if (! *(GF_Node**) field->far_ptr) + return JSVAL_NULL; + + obj = node_get_binding(priv, *(GF_Node**) field->far_ptr, 0); + jsf = JS_GetPrivate(priv->js_ctx, obj); + if (!jsf->owner) + jsf->owner = parent; + else + return OBJECT_TO_JSVAL(obj); break; @@ -3182,39 +3688,30 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No case GF_SG_VRML_MFNODE: { - u32 size; + u32 size, count; GF_ChildNodeItem *f = * ((GF_ChildNodeItem **)field->far_ptr); obj = JS_ConstructObject(priv->js_ctx, &js_rt->MFNodeClass, 0, priv->js_obj); SETUP_MF_FIELD size = gf_node_list_get_count(f); if (JS_SetArrayLength(priv->js_ctx, jsf->js_list, size) != JS_TRUE) return JSVAL_NULL; + count = gf_list_count(priv->js_cache); i=0; while (f) { - JSObject *pf = JS_NewObject(priv->js_ctx, &js_rt->SFNodeClass, 0, obj); + JSObject *pf; + slot = NULL; + n = f->node; + pf = node_get_binding(priv, n, 0); + if (n->sgprivate->tag == TAG_ProtoNode) { GF_ProtoInstance *proto_inst = (GF_ProtoInstance *) n; - if (!proto_inst->RenderingNode) + if (!proto_inst->RenderingNode) gf_sg_proto_instanciate(proto_inst); } - slot = NewJSField(); - slot->owner = parent; - slot->temp_node = n; - slot->field.far_ptr = & slot->temp_node; - slot->field.fieldType = GF_SG_VRML_SFNODE; - slot->field.fieldIndex = jsf->field.fieldIndex; - - vrml_node_register(n, parent); - JS_SetPrivate(priv->js_ctx, pf, slot); - - /*if this is the obj corresponding to an existing field/node, store it and prevent GC on object*/ - if (!skip_cache && priv->js_cache) { - slot->obj = pf; - JS_AddRoot(priv->js_ctx, &slot->obj); - gf_list_add(priv->js_cache, pf); - } + slot = JS_GetPrivate(priv->js_ctx, pf); + if (!slot->owner) slot->owner = parent; newVal = OBJECT_TO_JSVAL(pf); JS_SetElement(priv->js_ctx, jsf->js_list, (jsint) i, &newVal); @@ -3232,17 +3729,50 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No if (!obj) return JSVAL_NULL; //store field associated with object if needed if (jsf) { - if (parent) parent->sgprivate->flags |= GF_NODE_HAS_BINDING; - JS_SetPrivate(priv->js_ctx, obj, jsf); /*if this is the obj corresponding to an existing field/node, store it and prevent GC on object*/ - if (parent && !skip_cache && priv->js_cache) { - jsf->obj = obj; - JS_AddRoot(priv->js_ctx, &jsf->obj); - gf_list_add(priv->js_cache, obj); + if (parent) { + + /*remember the object*/ + if (!parent->sgprivate->interact) GF_SAFEALLOC(parent->sgprivate->interact, struct _node_interactive_ext); + if (!parent->sgprivate->interact->js_binding) { + GF_SAFEALLOC(parent->sgprivate->interact->js_binding, struct _node_js_binding); + parent->sgprivate->interact->js_binding->fields = gf_list_new(); + } + + if ( gf_list_find(parent->sgprivate->interact->js_binding->fields, jsf) < 0) { + assert(jsf->owner == parent); + gf_list_add(parent->sgprivate->interact->js_binding->fields, jsf); + } + - if (jsf->js_list) - JS_AddRoot(priv->js_ctx, &jsf->js_list); + if (!jsf->obj) { + jsf->obj = obj; + assert(gf_list_find(priv->js_cache, obj)<0); + gf_list_add(priv->js_cache, obj); + } + + /*our JS Array object (MFXXX) are always rooted and added to the cache upon construction*/ + if (jsf->js_list) { + u32 i; + jsuint count; + + JS_GetArrayLength(jsf->js_ctx, jsf->js_list, &count); + + for (i=0; i<count; i++) { + jsval item; + JS_GetElement(jsf->js_ctx, jsf->js_list, (jsint) i, &item); + if (JSVAL_IS_OBJECT(item)) { + GF_JSField *afield = JS_GetPrivate(jsf->js_ctx, JSVAL_TO_OBJECT(item)); + if (afield->owner != parent) continue; + + if ( gf_list_find(parent->sgprivate->interact->js_binding->fields, afield) < 0) { + gf_list_add(parent->sgprivate->interact->js_binding->fields, afield); + } + } + } + } + parent->sgprivate->flags |= GF_NODE_HAS_BINDING; } } return OBJECT_TO_JSVAL(obj); @@ -3251,61 +3781,79 @@ jsval gf_sg_script_to_smjs_field(GF_ScriptPriv *priv, GF_FieldInfo *field, GF_No static void JS_ReleaseRootObjects(GF_ScriptPriv *priv) { - if (priv->js_cache) { - u32 i, count = gf_list_count(priv->js_cache); - for (i=0; i<count; i++) { - GF_JSField *jsf; - JSObject *obj = gf_list_get(priv->js_cache, i); - jsf = (GF_JSField *) JS_GetPrivate(priv->js_ctx, obj); - - /* !!! WARNING !!! - - SpiderMonkey GC is handled at the JSRuntime level, not at the JSContext level. - Objects may not be finalized until the runtime is destroyed/GC'ed, which is not what we want. - We therefore destroy by hand all SFNode/MFNode - */ - if (jsf->obj) { - JS_RemoveRoot(priv->js_ctx, &jsf->obj); - jsf->obj = NULL; - - if (jsf->temp_node) { - node_finalize_ex(priv->js_ctx, obj, 0); - JS_SetPrivate(priv->js_ctx, obj, NULL); - } - } + u32 i=0; + + while (gf_list_count(priv->js_cache)) { + GF_JSField *jsf; + /*we don't walk through the list since unprotecting an element could trigger GC which in turn could modify this list content*/ + JSObject *obj = gf_list_last(priv->js_cache); + gf_list_rem_last(priv->js_cache); + jsf = (GF_JSField *) JS_GetPrivate(priv->js_ctx, obj); + if (!jsf) continue; + + /* !!! WARNING !!! + + SpiderMonkey GC is handled at the JSRuntime level, not at the JSContext level. + Objects may not be finalized until the runtime is destroyed/GC'ed, which is not what we want. + We therefore destroy by hand all SFNode/MFNode + */ + + if (jsf->is_rooted) { if (jsf->js_list) { - JS_RemoveRoot(priv->js_ctx, &jsf->js_list); - jsf->js_list = NULL; - if (jsf->temp_list) { - array_finalize_ex(priv->js_ctx, obj, 0); - JS_SetPrivate(priv->js_ctx, obj, NULL); - } + gf_js_remove_root(priv->js_ctx, &jsf->js_list); + } else { + gf_js_remove_root(priv->js_ctx, &jsf->obj); } + jsf->is_rooted=0; } + jsf->obj = NULL; + + if (jsf->js_list) + array_finalize_ex(priv->js_ctx, obj, 0); + else if (jsf->node) + node_finalize_ex(priv->js_ctx, obj, 0); + else + jsf->js_ctx=NULL; } } static void JS_PreDestroy(GF_Node *node) { +#if 0 jsval fval, rval; +#endif GF_ScriptPriv *priv = node->sgprivate->UserPrivate; if (!priv) return; - + + GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[Script] Destroying script node %s", gf_node_get_log_name(node) )); + + /*"shutdown" is no longer supported, as it is typically called when one of a parent node is destroyed through + a GC call. Calling JS_LookupProperty or JS_CallFunctionValue when GC is running will crash SpiderMonkey*/ +#if 0 if (JS_LookupProperty(priv->js_ctx, priv->js_obj, "shutdown", &fval)) if (! JSVAL_IS_VOID(fval)) JS_CallFunctionValue(priv->js_ctx, priv->js_obj, fval, 0, NULL, &rval); +#endif + + if (priv->event) gf_js_remove_root(priv->js_ctx, &priv->event); /*unprotect all cached objects from GC*/ JS_ReleaseRootObjects(priv); gf_sg_load_script_extensions(node->sgprivate->scenegraph, priv->js_ctx, priv->js_obj, 1); + +#ifndef GPAC_DISABLE_SVG + dom_js_pre_destroy(priv->js_ctx, node->sgprivate->scenegraph, NULL); +#endif + gf_sg_ecmascript_del(priv->js_ctx); #ifndef GPAC_DISABLE_SVG dom_js_unload(); #endif - - if (priv->js_cache) gf_list_del(priv->js_cache); + + gf_list_del(priv->js_cache); + priv->js_ctx = NULL; /*unregister script from parent scene (cf base_scenegraph::sg_reset) */ gf_list_del_item(node->sgprivate->scenegraph->scripts, node); @@ -3325,24 +3873,24 @@ static void JS_InitScriptFields(GF_ScriptPriv *priv, GF_Node *sc) switch (sf->eventType) { case GF_SG_EVENT_IN: gf_node_get_field(sc, sf->ALL_index, &info); - val = gf_sg_script_to_smjs_field(priv, &info, sc, 0, 0); + val = gf_sg_script_to_smjs_field(priv, &info, sc, 0); break; case GF_SG_EVENT_OUT: gf_node_get_field(sc, sf->ALL_index, &info); - val = gf_sg_script_to_smjs_field(priv, &info, sc, 0, 0); + val = gf_sg_script_to_smjs_field(priv, &info, sc, 0); /*for native types directly modified*/ JS_DefineProperty(priv->js_ctx, priv->js_obj, (const char *) sf->name, val, 0, gf_sg_script_eventout_set_prop, JSPROP_PERMANENT ); break; default: gf_node_get_field(sc, sf->ALL_index, &info); - val = gf_sg_script_to_smjs_field(priv, &info, sc, 0, 0); + val = gf_sg_script_to_smjs_field(priv, &info, sc, 0); JS_DefineProperty(priv->js_ctx, priv->js_obj, (const char *) sf->name, val, 0, 0, JSPROP_PERMANENT); break; } } } -static void flush_event_out(GF_Node *node, GF_ScriptPriv *priv) +void gf_js_vrml_flush_event_out(GF_Node *node, GF_ScriptPriv *priv) { u32 i; GF_ScriptField *sf; @@ -3353,6 +3901,13 @@ static void flush_event_out(GF_Node *node, GF_ScriptPriv *priv) if (sf->activate_event_out) { sf->activate_event_out = 0; gf_node_event_out(node, sf->ALL_index); +#ifndef GPAC_DISABLE_SVG + if (node->sgprivate->interact && node->sgprivate->interact->dom_evt) { + GF_FieldInfo info; + if (gf_node_get_field(node, sf->ALL_index, &info)==GF_OK) + gf_node_changed(node, &info); + } +#endif } } } @@ -3365,187 +3920,156 @@ static void JS_EventIn(GF_Node *node, GF_FieldInfo *in_field) GF_ScriptField *sf; GF_FieldInfo t_info; GF_ScriptPriv *priv; - u32 i; + u32 i; priv = node->sgprivate->UserPrivate; /*no support for change of static fields*/ if (in_field->fieldIndex<3) return; - + i = (node->sgprivate->tag==TAG_MPEG4_Script) ? 3 : 4; sf = gf_list_get(priv->fields, in_field->fieldIndex - i); time = gf_node_get_scene_time(node); /* - if (sf->last_route_time == time) return; + if (sf->last_route_time == time) return; */ sf->last_route_time = time; + gf_sg_lock_javascript(1); + //locate function - if (! JS_LookupProperty(priv->js_ctx, priv->js_obj, sf->name, &fval)) return; - if (JSVAL_IS_VOID(fval)) return; + if (! JS_LookupProperty(priv->js_ctx, priv->js_obj, sf->name, &fval) || JSVAL_IS_VOID(fval)) { + gf_sg_lock_javascript(0); + return; + } - argv[0] = gf_sg_script_to_smjs_field(priv, in_field, node, 0, 1); + argv[0] = gf_sg_script_to_smjs_field(priv, in_field, node, 1); memset(&t_info, 0, sizeof(GF_FieldInfo)); t_info.far_ptr = &sf->last_route_time; t_info.fieldType = GF_SG_VRML_SFTIME; t_info.fieldIndex = -1; t_info.name = "timestamp"; - argv[1] = gf_sg_script_to_smjs_field(priv, &t_info, node, 0, 1); + argv[1] = gf_sg_script_to_smjs_field(priv, &t_info, node, 1); /*protect args*/ - if (JSVAL_IS_GCTHING(argv[0])) JS_AddRoot(priv->js_ctx, &argv[0]); - if (JSVAL_IS_GCTHING(argv[1])) JS_AddRoot(priv->js_ctx, &argv[1]); + if (JSVAL_IS_GCTHING(argv[0])) gf_js_add_root(priv->js_ctx, &argv[0]); + if (JSVAL_IS_GCTHING(argv[1])) gf_js_add_root(priv->js_ctx, &argv[1]); JS_CallFunctionValue(priv->js_ctx, priv->js_obj, fval, 2, argv, &rval); /*release args*/ - if (JSVAL_IS_GCTHING(argv[0])) JS_RemoveRoot(priv->js_ctx, &argv[0]); - if (JSVAL_IS_GCTHING(argv[1])) JS_RemoveRoot(priv->js_ctx, &argv[1]); - - flush_event_out(node, priv); - /*perform JS cleanup*/ - JS_MaybeGC(priv->js_ctx); + if (JSVAL_IS_GCTHING(argv[0])) gf_js_remove_root(priv->js_ctx, &argv[0]); + if (JSVAL_IS_GCTHING(argv[1])) gf_js_remove_root(priv->js_ctx, &argv[1]); + +#ifdef FORCE_GC + MyJSGC(priv->js_ctx); +#endif + + gf_sg_lock_javascript(0); + + gf_js_vrml_flush_event_out(node, priv); } -void JSScriptFromFile(GF_Node *node); -static Bool vrml_js_load_script(M_Script *script, char *file) +static Bool vrml_js_load_script(M_Script *script, char *file, Bool primary_script) { FILE *jsf; char *jsscript; - u32 fsize; + u64 fsize; Bool success = 1; JSBool ret; jsval rval, fval; GF_ScriptPriv *priv = (GF_ScriptPriv *) script->sgprivate->UserPrivate; - jsf = fopen(file, "rb"); + jsf = gf_f64_open(file, "rb"); if (!jsf) return 0; - fseek(jsf, 0, SEEK_END); - fsize = ftell(jsf); - fseek(jsf, 0, SEEK_SET); - jsscript = malloc(sizeof(char)*(fsize+1)); - fread(jsscript, sizeof(char)*fsize, 1, jsf); + gf_f64_seek(jsf, 0, SEEK_END); + fsize = gf_f64_tell(jsf); + gf_f64_seek(jsf, 0, SEEK_SET); + jsscript = gf_malloc(sizeof(char)*(size_t)(fsize+1)); + fsize = fread(jsscript, sizeof(char), (size_t)fsize, jsf); fclose(jsf); jsscript[fsize] = 0; - ret = JS_EvaluateScript(priv->js_ctx, priv->js_obj, jsscript, sizeof(char)*fsize, 0, 0, &rval); + ret = JS_EvaluateScript(priv->js_ctx, priv->js_obj, jsscript, sizeof(char)*(size_t)fsize, 0, 0, &rval); if (ret==JS_FALSE) success = 0; - if (success && JS_LookupProperty(priv->js_ctx, priv->js_obj, "initialize", &fval)) { + if (success && primary_script && JS_LookupProperty(priv->js_ctx, priv->js_obj, "initialize", &fval)) { if (! JSVAL_IS_VOID(fval)) { JS_CallFunctionValue(priv->js_ctx, priv->js_obj, fval, 0, NULL, &rval); - flush_event_out((GF_Node *)script, priv); + gf_js_vrml_flush_event_out((GF_Node *)script, priv); } } - free(jsscript); + gf_free(jsscript); return success; } - -static void JS_NetIO(void *cbck, GF_NETIO_Parameter *param) -{ - GF_Err e; - JSFileDownload *jsdnload = (JSFileDownload *)cbck; - M_Script *script = (M_Script *)jsdnload->node; - - e = param->error; - if (param->msg_type==GF_NETIO_DATA_TRANSFERED) { - const char *szCache = gf_dm_sess_get_cache_name(jsdnload->sess); - if (!vrml_js_load_script(script, (char *) szCache)) - e = GF_SCRIPT_ERROR; - else - e = GF_OK; - } else if (!e) return; - - /*destroy current download session (ie, destroy ourselves)*/ - gf_dm_sess_del(jsdnload->sess); - free(jsdnload); - - if (e) { - u32 i; - if (script->url.count<=1) { - GF_JSAPIParam par; - par.info.e = e; - par.info.msg = "Cannot fetch script"; - ScriptAction(NULL, script->sgprivate->scenegraph, GF_JSAPI_OP_MESSAGE, NULL, &par); - return; - } - free(script->url.vals[0].script_text); - for (i=0; i<script->url.count-1; i++) - script->url.vals[i].script_text = script->url.vals[i+1].script_text; - script->url.vals[script->url.count-1].script_text = NULL; - script->url.count -= 1; - JSScriptFromFile((GF_Node *)script); - } -} - -void JSScriptFromFile(GF_Node *node) +/*fetches each listed URL and attempts to load the script - this is SYNCHRONOUS*/ +void JSScriptFromFile(GF_Node *node, const char *opt_file, Bool no_complain) { + GF_JSAPIParam par; u32 i; + GF_DownloadManager *dnld_man; + char *url; GF_Err e; - char szExt[50], *ext; - M_Script *script = (M_Script *)node; - Bool can_dnload = 0; + const char *ext; + MFScript the_url; + SFScript __url; - for (i=0; i<script->url.count; i++) { - ext = strrchr(script->url.vals[i].script_text, '.'); - if (!ext) break; - strcpy(szExt, ext); - strlwr(szExt); - if (strcmp(szExt, ".js")) continue; - can_dnload = 1; - break; - } - if (!can_dnload) return; + M_Script *script = (M_Script *)node; e = GF_SCRIPT_ERROR; - if (!vrml_js_load_script(script, script->url.vals[0].script_text)) { - GF_JSAPIParam par; - char *url; - GF_Err e; - JSFileDownload *jsdnload; + par.dnld_man = NULL; + ScriptAction(NULL, node->sgprivate->scenegraph, GF_JSAPI_OP_GET_DOWNLOAD_MANAGER, NULL, &par); + if (!par.dnld_man) return; + dnld_man = par.dnld_man; + + if (opt_file) { + the_url.count = 1; + __url.script_text = (char *) opt_file; + the_url.vals = &__url; + } else { + the_url = script->url; + } - ScriptAction(NULL, node->sgprivate->scenegraph, GF_JSAPI_OP_GET_SCENE_URI, node, &par); - url = NULL; - if (par.uri.url) url = gf_url_concatenate(par.uri.url, script->url.vals[0].script_text); - if (!url) url = strdup(script->url.vals[0].script_text); + for (i=0; i<the_url.count; i++) { + par.uri.url = the_url.vals[i].script_text; + par.uri.nb_params = 0; + ScriptAction(NULL, node->sgprivate->scenegraph, GF_JSAPI_OP_RESOLVE_URI, node, &par); + url = (char *)par.uri.url; - par.dnld_man = NULL; - ScriptAction(NULL, node->sgprivate->scenegraph, GF_JSAPI_OP_GET_DOWNLOAD_MANAGER, NULL, &par); - if (!par.dnld_man) return; + ext = strrchr(url, '.'); + if (ext && strnicmp(ext, ".js", 3)) { + gf_free(url); + continue; + } if (!strstr(url, "://") || !strnicmp(url, "file://", 7)) { - free(url); - -retry: - if (script->url.count<=1) { - GF_JSAPIParam par; - par.info.e = e; - par.info.msg = "Cannot fetch script"; - ScriptAction(NULL, script->sgprivate->scenegraph, GF_JSAPI_OP_GET_DCCI, NULL, &par); - return; - } - free(script->url.vals[0].script_text); - for (i=0; i<script->url.count-1; i++) - script->url.vals[i].script_text = script->url.vals[i+1].script_text; - script->url.vals[script->url.count-1].script_text = NULL; - script->url.count -= 1; - JSScriptFromFile((GF_Node *)script); + Bool res = vrml_js_load_script(script, url, opt_file ? 0 : 1); + gf_free(url); + if (res || no_complain) return; } else { - GF_SAFEALLOC(jsdnload, JSFileDownload); - jsdnload->node = node; - jsdnload->sess = gf_dm_sess_new(par.dnld_man, script->url.vals[0].script_text, 0, JS_NetIO, jsdnload, &e); - free(url); - if (!jsdnload->sess) { - free(jsdnload); - goto retry; + GF_DownloadSession *sess = gf_dm_sess_new(dnld_man, url, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL, &e); + if (sess) { + e = gf_dm_sess_process(sess); + if (e==GF_OK) { + const char *szCache = gf_dm_sess_get_cache_name(sess); + if (!vrml_js_load_script(script, (char *) szCache, opt_file ? 0 : 1)) + e = GF_SCRIPT_ERROR; + } + gf_dm_sess_del(sess); } + gf_free(url); + if (!e) return; } } + + par.info.e = GF_SCRIPT_ERROR; + par.info.msg = "Cannot fetch script"; + ScriptAction(NULL, node->sgprivate->scenegraph, GF_JSAPI_OP_MESSAGE, NULL, &par); } static void JSScript_LoadVRML(GF_Node *node) @@ -3585,6 +4109,8 @@ static void JSScript_LoadVRML(GF_Node *node) return; } + gf_sg_lock_javascript(1); + JS_SetContextPrivate(priv->js_ctx, node); gf_sg_script_init_sm_api(priv, node); GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] Built-in classes initialized\n")); @@ -3593,6 +4119,7 @@ static void JSScript_LoadVRML(GF_Node *node) dom_js_load(node->sgprivate->scenegraph, priv->js_ctx, priv->js_obj); /*create event object, and remember it*/ priv->event = dom_js_define_event(priv->js_ctx, priv->js_obj); + gf_js_add_root(priv->js_ctx, &priv->event); #endif gf_sg_load_script_extensions(node->sgprivate->scenegraph, priv->js_ctx, priv->js_obj, 0); @@ -3607,32 +4134,40 @@ static void JSScript_LoadVRML(GF_Node *node) priv->JS_EventIn = JS_EventIn; if (!local_script) { - JSScriptFromFile(node); + JSScriptFromFile(node, NULL, 0); + gf_sg_lock_javascript(0); return; } GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[VRML JS] Evaluating script %s\n", str)); ret = JS_EvaluateScript(priv->js_ctx, priv->js_obj, str, strlen(str), 0, 0, &rval); - if (ret==JS_FALSE) { - return; + if (ret==JS_TRUE) { + /*call initialize if present*/ + if (JS_LookupProperty(priv->js_ctx, priv->js_obj, "initialize", &fval) && !JSVAL_IS_VOID(fval)) + JS_CallFunctionValue(priv->js_ctx, priv->js_obj, fval, 0, NULL, &rval); + + gf_js_vrml_flush_event_out(node, priv); } - /*call initialize if present*/ - if (! JS_LookupProperty(priv->js_ctx, priv->js_obj, "initialize", &fval)) return; - if (JSVAL_IS_VOID(fval)) return; - JS_CallFunctionValue(priv->js_ctx, priv->js_obj, fval, 0, NULL, &rval); +#ifdef FORCE_GC + MyJSGC(priv->js_ctx); +#endif - flush_event_out(node, priv); - /*perform JS cleanup*/ - JS_MaybeGC(priv->js_ctx); + gf_sg_lock_javascript(0); } static void JSScript_Load(GF_Node *node) { +#ifndef GPAC_DISABLE_SVG + void JSScript_LoadSVG(GF_Node *node); +#endif + switch (node->sgprivate->tag) { case TAG_MPEG4_Script: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Script: +#endif JSScript_LoadVRML(node); break; #ifndef GPAC_DISABLE_SVG @@ -3647,117 +4182,125 @@ static void JSScript_Load(GF_Node *node) } - - -static void gf_sg_load_script_modules(GF_SceneGraph *sg) +static void JSScript_NodeModified(GF_SceneGraph *sg, GF_Node *node, GF_FieldInfo *info, GF_Node *script) { - GF_Terminal *term; - u32 i, count; - GF_JSAPIParam par; - - js_rt->extensions = gf_list_new(); + u32 i; + GF_JSField *jsf; + /*this is REPLACE NODE signaling*/ + if (script) { + u32 i, count; + GF_ScriptPriv *priv = gf_node_get_private(script); + count = gf_list_count(priv->js_cache); + for (i=0; i<count; i++) { + JSObject *obj = gf_list_get(priv->js_cache, i); + jsf = JS_GetPrivate(priv->js_ctx, obj); + if (jsf->node && (jsf->node==node)) { + jsf->node = NULL; + } + } - if (!sg->script_action) return; - if (!sg->script_action(sg->script_action_cbck, GF_JSAPI_OP_GET_TERM, sg->RootNode, &par)) return; - - term = par.term; - - count = gf_modules_get_count(term->user->modules); - for (i=0; i<count; i++) { - GF_JSUserExtension *ext = (GF_JSUserExtension *) gf_modules_load_interface(term->user->modules, i, GF_JS_USER_EXT_INTERFACE); - if (!ext) continue; - gf_list_add(js_rt->extensions, ext); - } -} - -static void gf_sg_unload_script_modules() -{ - while (gf_list_count(js_rt->extensions)) { - GF_JSUserExtension *ext = gf_list_last(js_rt->extensions); - gf_list_rem_last(js_rt->extensions); - gf_modules_close_interface((GF_BaseInterface *) ext); } - gf_list_del(js_rt->extensions); -} + if (!info) { + /*handle DOM case*/ + if ((node->sgprivate->tag>=GF_NODE_FIRST_PARENT_NODE_TAG) + && node->sgprivate->interact + && node->sgprivate->interact->js_binding + && node->sgprivate->interact->js_binding->node) + { -#ifdef __SYMBIAN32__ -const long MAX_HEAP_BYTES = 256 * 1024L; -#else -const long MAX_HEAP_BYTES = 4*1024 * 1024L; + if (gf_list_del_item(sg->objects, node->sgprivate->interact->js_binding->node)>=0) { +#ifndef GPAC_DISABLE_SVG + JSBool ret = gf_js_remove_root(sg->svg_js->js_ctx, &(node->sgprivate->interact->js_binding->node)); + if (sg->svg_js->in_script) + sg->svg_js->force_gc = 1; + else + { + JS_GC(sg->svg_js->js_ctx); + JS_ClearNewbornRoots(sg->svg_js->js_ctx); + } #endif -const long STACK_CHUNK_BYTES = 8*1024L; - -JSContext *gf_sg_ecmascript_new(GF_SceneGraph *sg) -{ - if (!js_rt) { - JSRuntime *js_runtime = JS_NewRuntime(MAX_HEAP_BYTES); - if (!js_runtime) { - GF_LOG(GF_LOG_ERROR, GF_LOG_SCRIPT, ("[ECMAScript] Cannot allocate ECMAScript runtime\n")); - return NULL; + } + return; } - GF_SAFEALLOC(js_rt, GF_JSRuntime); - js_rt->js_runtime = js_runtime; - GF_LOG(GF_LOG_DEBUG, GF_LOG_SCRIPT, ("[ECMAScript] ECMAScript runtime allocated 0x%08x\n", js_runtime)); - gf_sg_load_script_modules(sg); - } - js_rt->nb_inst++; - return JS_NewContext(js_rt->js_runtime, STACK_CHUNK_BYTES); -} -void gf_sg_ecmascript_del(JSContext *ctx) -{ - JS_SetGlobalObject(ctx, NULL); - JS_DestroyContext(ctx); - if (js_rt) { - js_rt->nb_inst --; - if (js_rt->nb_inst == 0) { - JS_DestroyRuntime(js_rt->js_runtime); - JS_ShutDown(); - gf_sg_unload_script_modules(); - free(js_rt); - js_rt = NULL; + /*this is unregister signaling*/ + if (node->sgprivate->parents) { + switch (node->sgprivate->parents->node->sgprivate->tag) { + case TAG_MPEG4_Script: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Script: +#endif + /*node is no longer used in the graph, remove root and let the script handle it, */ + if (node->sgprivate->interact->js_binding->node) { + GF_JSField *field = node->sgprivate->interact->js_binding->node; + if (field->is_rooted) { + gf_js_remove_root(field->js_ctx, &field->obj); + field->is_rooted = 0; + } + } + break; + } + return; + } + /*final destroy*/ + if (!node->sgprivate->num_instances) { + i=0; + while ((jsf = gf_list_enum(node->sgprivate->interact->js_binding->fields, &i))) { + jsf->owner = NULL; + + if (jsf->js_list) { + u32 j; + jsuint count; + JS_GetArrayLength(jsf->js_ctx, jsf->js_list, &count); + + for (j=0; j<count; j++) { + jsval item; + JS_GetElement(jsf->js_ctx, jsf->js_list, (jsint) j, &item); + if (JSVAL_IS_OBJECT(item)) { + GF_JSField *afield = JS_GetPrivate(jsf->js_ctx, JSVAL_TO_OBJECT(item)); + afield->owner = NULL; + } + } + gf_js_remove_root(jsf->js_ctx, &jsf->js_list); + jsf->js_list = NULL; + } + } } + return; } -} + /*this is field modification signaling*/ + if (!node->sgprivate->interact || !node->sgprivate->interact->js_binding) return; + i=0; + while ((jsf = gf_list_enum(node->sgprivate->interact->js_binding->fields, &i))) { + if ((jsf->field.fieldIndex == info->fieldIndex) && (jsf->field.fieldType == info->fieldType)) { + jsf->field.NDTtype = 1; -static void JSScript_NodeModified(GF_SceneGraph *sg, GF_Node *node, GF_FieldInfo *info) -{ - JSObject *obj = NULL; - GF_ScriptPriv *priv; - u32 i, count, j; + /*if field is a script field, rewrite it right away because script fields are exposed + as global variables within the script - count = gf_list_count(sg->scripts); - for (i=0; i<count; i++) { - GF_Node *p = gf_list_get(sg->scripts, i); - if ((p->sgprivate->tag!=TAG_MPEG4_Script) && (p->sgprivate->tag!=TAG_X3D_Script)) - continue; + We also have a special value '-1' for the NDT for addChildren and removeChildren*/ - priv = (GF_ScriptPriv *)gf_node_get_private(p); - if (!priv->js_cache) continue; - - j=0; - while ((obj = gf_list_enum(priv->js_cache, &j))) { - GF_JSField *jsf = (GF_JSField *) JS_GetPrivate(priv->js_ctx, obj); - if (jsf - && (jsf->owner==node) - && (jsf->field.fieldIndex == info->fieldIndex) - && (jsf->field.fieldType == info->fieldType)) { - jsf->reevaluate = 1; + if ((info->NDTtype == (u32) -1) || (node == (GF_Node*)JS_GetScript(jsf->js_ctx))) { + gf_sg_script_update_cached_object( JS_GetScriptStack(jsf->js_ctx), jsf->obj, jsf, &jsf->field, node); } + return; } } } void gf_sg_handle_dom_event_for_vrml(GF_Node *node, GF_DOM_Event *event, GF_Node *observer) { +#ifndef GPAC_DISABLE_SVG GF_ScriptPriv *priv; Bool prev_type; JSBool ret = JS_FALSE; GF_DOM_Event *prev_event = NULL; SVG_handlerElement *hdl; jsval rval; + JSObject *evt; + jsval argv[1]; hdl = (SVG_handlerElement *) node; if (!hdl->js_fun_val && !hdl->evt_listen_obj) return; @@ -3767,35 +4310,38 @@ void gf_sg_handle_dom_event_for_vrml(GF_Node *node, GF_DOM_Event *event, GF_Node priv = JS_GetScriptStack(hdl->js_context); prev_event = JS_GetPrivate(priv->js_ctx, priv->event); /*break loops*/ - if (prev_event && (prev_event->type==event->type) && (prev_event->target==event->target)) + if (prev_event && (prev_event->type==event->type) && (prev_event->target==event->target)) return; + gf_sg_lock_javascript(1); + prev_type = event->is_vrml; event->is_vrml = 1; JS_SetPrivate(priv->js_ctx, priv->event, event); + evt = gf_dom_new_event(priv->js_ctx); + JS_SetPrivate(priv->js_ctx, evt, event); + argv[0] = OBJECT_TO_JSVAL(evt); - { - JSObject *evt; - jsval argv[1]; - evt = gf_dom_new_event(priv->js_ctx); - JS_SetPrivate(priv->js_ctx, evt, event); - argv[0] = OBJECT_TO_JSVAL(evt); - - if (hdl->js_fun_val) { - jsval funval = (JSWord) hdl->js_fun_val; - ret = JS_CallFunctionValue(priv->js_ctx, hdl->evt_listen_obj ? (JSObject *)hdl->evt_listen_obj: priv->js_obj, funval, 1, argv, &rval); - } else { - ret = JS_CallFunctionName(priv->js_ctx, hdl->evt_listen_obj, "handleEvent", 1, argv, &rval); - } + if (hdl->js_fun_val) { + jsval funval = (JSWord) hdl->js_fun_val; + ret = JS_CallFunctionValue(priv->js_ctx, hdl->evt_listen_obj ? (JSObject *)hdl->evt_listen_obj: priv->js_obj, funval, 1, argv, &rval); + } else { + ret = JS_CallFunctionName(priv->js_ctx, hdl->evt_listen_obj, "handleEvent", 1, argv, &rval); } - + event->is_vrml = prev_type; JS_SetPrivate(priv->js_ctx, priv->event, prev_event); -} + gf_sg_lock_javascript(0); #endif +} + +#endif /*GPAC_DISABLE_VRML*/ + +#endif /*GPAC_HAS_SPIDERMONKEY*/ + /*set JavaScript interface*/ @@ -3805,10 +4351,52 @@ void gf_sg_set_script_action(GF_SceneGraph *scene, gf_sg_script_action script_ac scene->script_action = script_act; scene->script_action_cbck = cbk; -#ifdef GPAC_HAS_SPIDERMONKEY +#if defined(GPAC_HAS_SPIDERMONKEY) && !defined(GPAC_DISABLE_VRML) scene->script_load = JSScript_Load; scene->on_node_modified = JSScript_NodeModified; #endif } +#ifdef GPAC_HAS_SPIDERMONKEY + +GF_Node *gf_sg_js_get_node(JSContext *c, JSObject *obj) +{ + JSBool has_p; +#ifndef GPAC_DISABLE_VRML + if (js_rt && JS_InstanceOf(c, obj, &js_rt->SFNodeClass, NULL) ) { + GF_JSField *ptr = (GF_JSField *) JS_GetPrivate(c, obj); + if (ptr->field.fieldType==GF_SG_VRML_SFNODE) return * ((GF_Node **)ptr->field.far_ptr); + } +#endif + +#ifndef GPAC_DISABLE_SVG + has_p = 0; + if (JS_HasProperty(c, obj, "namespaceURI", &has_p)) { + if (has_p==JS_TRUE) return dom_get_element(c, obj); + } +#endif + return NULL; +} + +#endif + + +Bool gf_sg_has_scripting() +{ +#ifdef GPAC_HAS_SPIDERMONKEY + return 1; +#else + return 0; +#endif +} + +void gf_sg_lock_javascript(Bool LockIt) +{ +#ifdef GPAC_HAS_SPIDERMONKEY + if (js_rt) { + if (LockIt) gf_mx_p(js_rt->mx); + else gf_mx_v(js_rt->mx); + } +#endif +} diff --git a/src/scenegraph/vrml_tools.c b/src/scenegraph/vrml_tools.c index 630dbba..e51db21 100644 --- a/src/scenegraph/vrml_tools.c +++ b/src/scenegraph/vrml_tools.c @@ -28,40 +28,39 @@ #include <gpac/nodes_mpeg4.h> #include <gpac/nodes_x3d.h> -/*this is not a NodeReplace, thus only the given container is updated - pos is 0-based*/ -GF_Err gf_node_replace_child(GF_Node *node, GF_ChildNodeItem **container, s32 pos, GF_Node *newNode) -{ - GF_ChildNodeItem *child, *prev; - u32 tag; - u32 cur_pos = 0; - - child = *container; - prev = NULL; - while (child->next) { - if ((pos<0) || (cur_pos!=(u32)pos)) { - prev = child; - child = child->next; - cur_pos++; - continue; + +#ifndef GPAC_DISABLE_VRML +#include <gpac/internal/bifs_dev.h> + + +Bool gf_node_in_table_by_tag(u32 tag, u32 NDTType) +{ + if (!tag) return 0; + if (tag==TAG_ProtoNode) return 1; + else if (tag<=GF_NODE_RANGE_LAST_MPEG4) { +#ifndef GPAC_DISABLE_BIFS + u32 i; + for (i=0;i<GF_BIFS_LAST_VERSION; i++) { + if (gf_bifs_get_node_type(NDTType, tag, i+1)) return 1; } - break; - } - tag = child->node->sgprivate->tag; - gf_node_unregister(child->node, node); - if (newNode) { - child->node = newNode; - if (tag==TAG_MPEG4_ColorTransform) - node->sgprivate->flags |= GF_SG_VRML_COLOR_DIRTY; - } else { - if (prev) prev->next = child->next; - else *container = child->next; - free(child); + return 0; +#else + /*if BIFS is disabled, we don't have the NDTs - we therefore allow any node in any table otherwise we would reject + them all*/ + return 1; +#endif + + } +#ifndef GPAC_DISABLE_X3D + else if (tag<=GF_NODE_RANGE_LAST_X3D) { + return gf_x3d_get_node_type(NDTType, tag); } - return GF_OK; +#endif + return 0; } -static void Node_on_add_children(GF_Node *node) +static void Node_on_add_children(GF_Node *node, GF_Route *route) { GF_ChildNodeItem *list; GF_FieldInfo field; @@ -80,13 +79,24 @@ static void Node_on_add_children(GF_Node *node) field.name = "children"; field.eventType = GF_SG_EVENT_EXPOSED_FIELD; field.fieldType = GF_SG_VRML_MFNODE; - field.NDTtype = 0; + field.NDTtype = -1; field.fieldIndex = 2; field.far_ptr = & n->children; + gf_node_event_out(node, field.fieldIndex); gf_node_changed(node, &field); + + if (node->sgprivate->scenegraph->on_node_modified) { + field.name = "addChildren"; + field.eventType = GF_SG_EVENT_IN; + field.fieldType = GF_SG_VRML_MFNODE; + field.NDTtype = -1; + field.fieldIndex = 0; + field.far_ptr = & n->addChildren; + node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL); + } } -static void Node_on_remove_children(GF_Node *node) +static void Node_on_remove_children(GF_Node *node, GF_Route *route) { GF_ChildNodeItem *list; GF_FieldInfo field; @@ -108,10 +118,22 @@ static void Node_on_remove_children(GF_Node *node) field.name = "children"; field.eventType = GF_SG_EVENT_EXPOSED_FIELD; field.fieldType = GF_SG_VRML_MFNODE; - field.NDTtype = 0; + field.NDTtype = -1; field.fieldIndex = 2; field.far_ptr = & n->children; + gf_node_event_out(node, field.fieldIndex); gf_node_changed(node, &field); + + + if (node->sgprivate->scenegraph->on_node_modified) { + field.name = "removeChildren"; + field.eventType = GF_SG_EVENT_IN; + field.fieldType = GF_SG_VRML_MFNODE; + field.NDTtype = -1; + field.fieldIndex = 1; + field.far_ptr = & n->removeChildren; + node->sgprivate->scenegraph->on_node_modified(node->sgprivate->scenegraph, node, &field, NULL); + } } void gf_sg_vrml_parent_setup(GF_Node *pNode) @@ -246,225 +268,205 @@ GF_Proto *gf_sg_find_proto(GF_SceneGraph *sg, u32 ProtoID, char *name) -u32 gf_bifs_get_child_table(GF_Node *Node) -{ - assert(Node); - return gf_sg_mpeg4_node_get_child_ndt(Node); -} - - -GF_Err gf_bifs_get_field_index(GF_Node *Node, u32 inField, u8 IndexMode, u32 *allField) -{ - assert(Node); - switch (Node->sgprivate->tag) { - case TAG_ProtoNode: - return gf_sg_proto_get_field_ind_static(Node, inField, IndexMode, allField); - case TAG_MPEG4_Script: - case TAG_X3D_Script: - return gf_sg_script_get_field_index(Node, inField, IndexMode, allField); - default: - return gf_sg_mpeg4_node_get_field_index(Node, inField, IndexMode, allField); - } -} - - -/* QUANTIZATION AND BIFS_Anim Info */ -GF_EXPORT -Bool gf_bifs_get_aq_info(GF_Node *Node, u32 FieldIndex, u8 *QType, u8 *AType, Fixed *b_min, Fixed *b_max, u32 *QT13_bits) -{ - switch (Node->sgprivate->tag) { - case TAG_ProtoNode: return gf_sg_proto_get_aq_info(Node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); - default: return gf_sg_mpeg4_node_get_aq_info(Node, FieldIndex, QType, AType, b_min, b_max, QT13_bits); - } -} - static SFBool *NewSFBool() { - SFBool *tmp = (SFBool *)malloc(sizeof(SFBool)); + SFBool *tmp = (SFBool *)gf_malloc(sizeof(SFBool)); memset(tmp, 0, sizeof(SFBool)); return tmp; } static SFFloat *NewSFFloat() { - SFFloat *tmp = (SFFloat *)malloc(sizeof(SFFloat)); + SFFloat *tmp = (SFFloat *)gf_malloc(sizeof(SFFloat)); memset(tmp, 0, sizeof(SFFloat)); return tmp; } static SFDouble *NewSFDouble() { - SFDouble *tmp = (SFDouble *)malloc(sizeof(SFDouble)); + SFDouble *tmp = (SFDouble *)gf_malloc(sizeof(SFDouble)); memset(tmp, 0, sizeof(SFDouble)); return tmp; } static SFTime *NewSFTime() { - SFTime *tmp = (SFTime *)malloc(sizeof(SFTime)); + SFTime *tmp = (SFTime *)gf_malloc(sizeof(SFTime)); memset(tmp, 0, sizeof(SFTime)); return tmp; } static SFInt32 *NewSFInt32() { - SFInt32 *tmp = (SFInt32 *)malloc(sizeof(SFInt32)); + SFInt32 *tmp = (SFInt32 *)gf_malloc(sizeof(SFInt32)); memset(tmp, 0, sizeof(SFInt32)); return tmp; } static SFString *NewSFString() { - SFString *tmp = (SFString *)malloc(sizeof(SFString)); + SFString *tmp = (SFString *)gf_malloc(sizeof(SFString)); memset(tmp, 0, sizeof(SFString)); return tmp; } static SFVec3f *NewSFVec3f() { - SFVec3f *tmp = (SFVec3f *)malloc(sizeof(SFVec3f)); + SFVec3f *tmp = (SFVec3f *)gf_malloc(sizeof(SFVec3f)); memset(tmp, 0, sizeof(SFVec3f)); return tmp; } static SFVec3d *NewSFVec3d() { - SFVec3d *tmp = (SFVec3d *)malloc(sizeof(SFVec3d)); + SFVec3d *tmp = (SFVec3d *)gf_malloc(sizeof(SFVec3d)); memset(tmp, 0, sizeof(SFVec3d)); return tmp; } static SFVec2f *NewSFVec2f() { - SFVec2f *tmp = (SFVec2f *)malloc(sizeof(SFVec2f)); + SFVec2f *tmp = (SFVec2f *)gf_malloc(sizeof(SFVec2f)); memset(tmp, 0, sizeof(SFVec2f)); return tmp; } static SFVec2d *NewSFVec2d() { - SFVec2d *tmp = (SFVec2d *)malloc(sizeof(SFVec2d)); + SFVec2d *tmp = (SFVec2d *)gf_malloc(sizeof(SFVec2d)); memset(tmp, 0, sizeof(SFVec2d)); return tmp; } static SFColor *NewSFColor() { - SFColor *tmp = (SFColor *)malloc(sizeof(SFColor)); + SFColor *tmp = (SFColor *)gf_malloc(sizeof(SFColor)); memset(tmp, 0, sizeof(SFColor)); return tmp; } static SFColorRGBA *NewSFColorRGBA() { - SFColorRGBA *tmp = (SFColorRGBA *)malloc(sizeof(SFColorRGBA)); + SFColorRGBA *tmp = (SFColorRGBA *)gf_malloc(sizeof(SFColorRGBA)); memset(tmp, 0, sizeof(SFColorRGBA)); return tmp; } static SFRotation *NewSFRotation() { - SFRotation *tmp = (SFRotation *)malloc(sizeof(SFRotation)); + SFRotation *tmp = (SFRotation *)gf_malloc(sizeof(SFRotation)); memset(tmp, 0, sizeof(SFRotation)); return tmp; } static SFImage *NewSFImage() { - SFImage *tmp = (SFImage *)malloc(sizeof(SFImage)); + SFImage *tmp = (SFImage *)gf_malloc(sizeof(SFImage)); memset(tmp, 0, sizeof(SFImage)); return tmp; } static SFURL *NewSFURL() { - SFURL *tmp = (SFURL *)malloc(sizeof(SFURL)); + SFURL *tmp = (SFURL *)gf_malloc(sizeof(SFURL)); memset(tmp, 0, sizeof(SFURL)); return tmp; } static SFCommandBuffer *NewSFCommandBuffer() { - SFCommandBuffer *tmp = (SFCommandBuffer *)malloc(sizeof(SFCommandBuffer)); + SFCommandBuffer *tmp = (SFCommandBuffer *)gf_malloc(sizeof(SFCommandBuffer)); memset(tmp, 0, sizeof(SFCommandBuffer)); tmp->commandList = gf_list_new(); return tmp; } static SFScript *NewSFScript() { - SFScript *tmp = (SFScript *)malloc(sizeof(SFScript)); + SFScript *tmp = (SFScript *)gf_malloc(sizeof(SFScript)); memset(tmp, 0, sizeof(SFScript)); return tmp; } +static SFAttrRef *NewSFAttrRef() +{ + SFAttrRef *tmp; + GF_SAFEALLOC(tmp, SFAttrRef); + return tmp; +} static MFBool *NewMFBool() { - MFBool *tmp = (MFBool *)malloc(sizeof(MFBool)); + MFBool *tmp = (MFBool *)gf_malloc(sizeof(MFBool)); memset(tmp, 0, sizeof(MFBool)); return tmp; } static MFFloat *NewMFFloat() { - MFFloat *tmp = (MFFloat *)malloc(sizeof(MFFloat)); + MFFloat *tmp = (MFFloat *)gf_malloc(sizeof(MFFloat)); memset(tmp, 0, sizeof(MFFloat)); return tmp; } static MFTime *NewMFTime() { - MFTime *tmp = (MFTime *)malloc(sizeof(MFTime)); + MFTime *tmp = (MFTime *)gf_malloc(sizeof(MFTime)); memset(tmp, 0, sizeof(MFTime)); return tmp; } static MFInt32 *NewMFInt32() { - MFInt32 *tmp = (MFInt32 *)malloc(sizeof(MFInt32)); + MFInt32 *tmp = (MFInt32 *)gf_malloc(sizeof(MFInt32)); memset(tmp, 0, sizeof(MFInt32)); return tmp; } static MFString *NewMFString() { - MFString *tmp = (MFString *)malloc(sizeof(MFString)); + MFString *tmp = (MFString *)gf_malloc(sizeof(MFString)); memset(tmp, 0, sizeof(MFString)); return tmp; } static MFVec3f *NewMFVec3f() { - MFVec3f *tmp = (MFVec3f *)malloc(sizeof(MFVec3f)); + MFVec3f *tmp = (MFVec3f *)gf_malloc(sizeof(MFVec3f)); memset(tmp, 0, sizeof(MFVec3f)); return tmp; } static MFVec3d *NewMFVec3d() { - MFVec3d *tmp = (MFVec3d *)malloc(sizeof(MFVec3d)); + MFVec3d *tmp = (MFVec3d *)gf_malloc(sizeof(MFVec3d)); memset(tmp, 0, sizeof(MFVec3d)); return tmp; } static MFVec2f *NewMFVec2f() { - MFVec2f *tmp = (MFVec2f *)malloc(sizeof(MFVec2f)); + MFVec2f *tmp = (MFVec2f *)gf_malloc(sizeof(MFVec2f)); memset(tmp, 0, sizeof(MFVec2f)); return tmp; } static MFVec2d *NewMFVec2d() { - MFVec2d *tmp = (MFVec2d *)malloc(sizeof(MFVec2d)); + MFVec2d *tmp = (MFVec2d *)gf_malloc(sizeof(MFVec2d)); memset(tmp, 0, sizeof(MFVec2d)); return tmp; } static MFColor *NewMFColor() { - MFColor *tmp = (MFColor *)malloc(sizeof(MFColor)); + MFColor *tmp = (MFColor *)gf_malloc(sizeof(MFColor)); memset(tmp, 0, sizeof(MFColor)); return tmp; } static MFColorRGBA *NewMFColorRGBA() { - MFColorRGBA *tmp = (MFColorRGBA *)malloc(sizeof(MFColorRGBA)); + MFColorRGBA *tmp = (MFColorRGBA *)gf_malloc(sizeof(MFColorRGBA)); memset(tmp, 0, sizeof(MFColorRGBA)); return tmp; } static MFRotation *NewMFRotation() { - MFRotation *tmp = (MFRotation *)malloc(sizeof(MFRotation)); + MFRotation *tmp = (MFRotation *)gf_malloc(sizeof(MFRotation)); memset(tmp, 0, sizeof(MFRotation)); return tmp; } static MFURL *NewMFURL() { - MFURL *tmp = (MFURL *)malloc(sizeof(MFURL)); + MFURL *tmp = (MFURL *)gf_malloc(sizeof(MFURL)); memset(tmp, 0, sizeof(MFURL)); return tmp; } static MFScript *NewMFScript() { - MFScript *tmp = (MFScript *)malloc(sizeof(MFScript)); + MFScript *tmp = (MFScript *)gf_malloc(sizeof(MFScript)); memset(tmp, 0, sizeof(MFScript)); return tmp; } +static MFAttrRef *NewMFAttrRef() +{ + MFAttrRef *tmp; + GF_SAFEALLOC(tmp, MFAttrRef); + return tmp; +} void *gf_sg_vrml_field_pointer_new(u32 FieldType) { @@ -483,6 +485,7 @@ void *gf_sg_vrml_field_pointer_new(u32 FieldType) case GF_SG_VRML_SFCOLORRGBA: return NewSFColorRGBA(); case GF_SG_VRML_SFROTATION: return NewSFRotation(); case GF_SG_VRML_SFIMAGE: return NewSFImage(); + case GF_SG_VRML_SFATTRREF: return NewSFAttrRef(); case GF_SG_VRML_MFBOOL: return NewMFBool(); case GF_SG_VRML_MFFLOAT: return NewMFFloat(); case GF_SG_VRML_MFTIME: return NewMFTime(); @@ -494,7 +497,10 @@ void *gf_sg_vrml_field_pointer_new(u32 FieldType) case GF_SG_VRML_MFVEC2D: return NewMFVec2d(); case GF_SG_VRML_MFCOLOR: return NewMFColor(); case GF_SG_VRML_MFCOLORRGBA: return NewMFColorRGBA(); - case GF_SG_VRML_MFROTATION: return NewMFRotation(); + case GF_SG_VRML_MFROTATION: + case GF_SG_VRML_MFVEC4F: + return NewMFRotation(); + case GF_SG_VRML_MFATTRREF: return NewMFAttrRef(); //used in commands case GF_SG_VRML_SFCOMMANDBUFFER: @@ -513,32 +519,23 @@ void *gf_sg_vrml_field_pointer_new(u32 FieldType) return NULL; } -void gf_sg_mfint32_del(MFInt32 par) { free(par.vals); } -void gf_sg_mffloat_del(MFFloat par) { free(par.vals); } -void gf_sg_mfdouble_del(MFDouble par) { free(par.vals); } -void gf_sg_mfbool_del(MFBool par) { free(par.vals); } -void gf_sg_mfcolor_del(MFColor par) { free(par.vals); } -void gf_sg_mfcolor_rgba_del(MFColorRGBA par) { free(par.vals); } -void gf_sg_mfrotation_del(MFRotation par) { free(par.vals); } -void gf_sg_mftime_del(MFTime par) { free(par.vals); } -void gf_sg_mfvec2f_del(MFVec2f par) { free(par.vals); } -void gf_sg_mfvec2d_del(MFVec2d par) { free(par.vals); } -void gf_sg_mfvec3f_del(MFVec3f par) { free(par.vals); } -void gf_sg_mfvec3d_del(MFVec3d par) { free(par.vals); } -void gf_sg_mfvec4f_del(MFVec4f par) { free(par.vals); } -void gf_sg_sfimage_del(SFImage im) { free(im.pixels); } -void gf_sg_sfurl_del(SFURL url) { if (url.url) free(url.url); } -void gf_sg_sfstring_del(SFString par) { if (par.buffer) free(par.buffer); } -void gf_sg_sfscript_del(SFScript par) { if (par.script_text) free(par.script_text); } - -void gf_sg_mfstring_del(MFString par) -{ - u32 i; - for (i=0; i<par.count; i++) { - if (par.vals[i]) free(par.vals[i]); - } - free(par.vals); -} +void gf_sg_mfint32_del(MFInt32 par) { gf_free(par.vals); } +void gf_sg_mffloat_del(MFFloat par) { gf_free(par.vals); } +void gf_sg_mfdouble_del(MFDouble par) { gf_free(par.vals); } +void gf_sg_mfbool_del(MFBool par) { gf_free(par.vals); } +void gf_sg_mfcolor_del(MFColor par) { gf_free(par.vals); } +void gf_sg_mfcolor_rgba_del(MFColorRGBA par) { gf_free(par.vals); } +void gf_sg_mfrotation_del(MFRotation par) { gf_free(par.vals); } +void gf_sg_mftime_del(MFTime par) { gf_free(par.vals); } +void gf_sg_mfvec2f_del(MFVec2f par) { gf_free(par.vals); } +void gf_sg_mfvec2d_del(MFVec2d par) { gf_free(par.vals); } +void gf_sg_mfvec3f_del(MFVec3f par) { gf_free(par.vals); } +void gf_sg_mfvec3d_del(MFVec3d par) { gf_free(par.vals); } +void gf_sg_mfvec4f_del(MFVec4f par) { gf_free(par.vals); } +void gf_sg_mfattrref_del(MFAttrRef par) { gf_free(par.vals); } +void gf_sg_sfimage_del(SFImage im) { gf_free(im.pixels); } +void gf_sg_sfstring_del(SFString par) { if (par.buffer) gf_free(par.buffer); } +void gf_sg_sfscript_del(SFScript par) { if (par.script_text) gf_free(par.script_text); } void gf_sg_sfcommand_del(SFCommandBuffer cb) @@ -549,28 +546,9 @@ void gf_sg_sfcommand_del(SFCommandBuffer cb) gf_sg_command_del(com); } gf_list_del(cb.commandList); - if (cb.buffer) free(cb.buffer); -} - -GF_EXPORT -void gf_sg_mfurl_del(MFURL url) -{ - u32 i; - for (i=0; i<url.count; i++) { - gf_sg_sfurl_del(url.vals[i]); - } - free(url.vals); -} -void gf_sg_mfscript_del(MFScript sc) -{ - u32 i; - for (i=0; i<sc.count; i++) { - if (sc.vals[i].script_text) free(sc.vals[i].script_text); - } - free(sc.vals); + if (cb.buffer) gf_free(cb.buffer); } - void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType) { GF_Node *node; @@ -588,9 +566,10 @@ void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType) case GF_SG_VRML_SFCOLOR: case GF_SG_VRML_SFCOLORRGBA: case GF_SG_VRML_SFROTATION: + case GF_SG_VRML_SFATTRREF: break; case GF_SG_VRML_SFSTRING: - if ( ((SFString *)field)->buffer) free(((SFString *)field)->buffer); + if ( ((SFString *)field)->buffer) gf_free(((SFString *)field)->buffer); break; case GF_SG_VRML_SFIMAGE: gf_sg_sfimage_del(* ((SFImage *)field)); @@ -641,6 +620,7 @@ void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType) gf_sg_mfcolor_rgba_del( * ((MFColorRGBA *)field)); break; case GF_SG_VRML_MFROTATION: + case GF_SG_VRML_MFVEC4F: gf_sg_mfrotation_del( * ((MFRotation *)field)); break; case GF_SG_VRML_SFURL: @@ -649,6 +629,9 @@ void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType) case GF_SG_VRML_MFURL: gf_sg_mfurl_del( * ((MFURL *) field)); break; + case GF_SG_VRML_MFATTRREF: + gf_sg_mfattrref_del( * ((MFAttrRef *) field)); + break; //used only in proto since this field is created by default for regular nodes case GF_SG_VRML_MFNODE: assert(0); @@ -662,18 +645,161 @@ void gf_sg_vrml_field_pointer_del(void *field, u32 FieldType) return; } //free pointer - free(field); + gf_free(field); } +/********************************************************************* + MF Fields manipulation (alloc, gf_realloc, GetAt) +*********************************************************************/ +const char *gf_sg_vrml_get_event_type_name(u32 EventType, Bool forX3D) +{ + switch (EventType) { + case GF_SG_EVENT_IN: return forX3D ? "inputOnly" : "eventIn"; + case GF_SG_EVENT_FIELD: return forX3D ? "initializeOnly" : "field"; + case GF_SG_EVENT_EXPOSED_FIELD: return forX3D ? "inputOutput" : "exposedField"; + case GF_SG_EVENT_OUT: return forX3D ? "outputOnly" : "eventOut"; + default: return "unknownEvent"; + } +} + +const char *gf_sg_vrml_get_field_type_by_name(u32 FieldType) +{ + + switch (FieldType) { + case GF_SG_VRML_SFBOOL: return "SFBool"; + case GF_SG_VRML_SFFLOAT: return "SFFloat"; + case GF_SG_VRML_SFDOUBLE: return "SFDouble"; + case GF_SG_VRML_SFTIME: return "SFTime"; + case GF_SG_VRML_SFINT32: return "SFInt32"; + case GF_SG_VRML_SFSTRING: return "SFString"; + case GF_SG_VRML_SFVEC3F: return "SFVec3f"; + case GF_SG_VRML_SFVEC2F: return "SFVec2f"; + case GF_SG_VRML_SFVEC3D: return "SFVec3d"; + case GF_SG_VRML_SFVEC2D: return "SFVec2d"; + case GF_SG_VRML_SFCOLOR: return "SFColor"; + case GF_SG_VRML_SFCOLORRGBA: return "SFColorRGBA"; + case GF_SG_VRML_SFROTATION: return "SFRotation"; + case GF_SG_VRML_SFIMAGE: return "SFImage"; + case GF_SG_VRML_SFNODE: return "SFNode"; + case GF_SG_VRML_SFVEC4F: return "SFVec4f"; + case GF_SG_VRML_SFATTRREF: return "SFAttrRef"; + case GF_SG_VRML_MFBOOL: return "MFBool"; + case GF_SG_VRML_MFFLOAT: return "MFFloat"; + case GF_SG_VRML_MFDOUBLE: return "MFDouble"; + case GF_SG_VRML_MFTIME: return "MFTime"; + case GF_SG_VRML_MFINT32: return "MFInt32"; + case GF_SG_VRML_MFSTRING: return "MFString"; + case GF_SG_VRML_MFVEC3F: return "MFVec3f"; + case GF_SG_VRML_MFVEC2F: return "MFVec2f"; + case GF_SG_VRML_MFVEC3D: return "MFVec3d"; + case GF_SG_VRML_MFVEC2D: return "MFVec2d"; + case GF_SG_VRML_MFCOLOR: return "MFColor"; + case GF_SG_VRML_MFCOLORRGBA: return "MFColorRGBA"; + case GF_SG_VRML_MFROTATION: return "MFRotation"; + case GF_SG_VRML_MFIMAGE: return "MFImage"; + case GF_SG_VRML_MFNODE: return "MFNode"; + case GF_SG_VRML_MFVEC4F: return "MFVec4f"; + case GF_SG_VRML_SFURL: return "SFURL"; + case GF_SG_VRML_MFURL: return "MFURL"; + case GF_SG_VRML_MFATTRREF: return "MFAttrRef"; + case GF_SG_VRML_SFCOMMANDBUFFER: return "SFCommandBuffer"; + case GF_SG_VRML_SFSCRIPT: return "SFScript"; + case GF_SG_VRML_MFSCRIPT: return "MFScript"; + default: return "UnknownType"; + } +} + +u32 gf_sg_field_type_by_name(char *fieldType) +{ + if (!stricmp(fieldType, "SFBool")) return GF_SG_VRML_SFBOOL; + else if (!stricmp(fieldType, "SFFloat")) return GF_SG_VRML_SFFLOAT; + else if (!stricmp(fieldType, "SFDouble")) return GF_SG_VRML_SFDOUBLE; + else if (!stricmp(fieldType, "SFTime")) return GF_SG_VRML_SFTIME; + else if (!stricmp(fieldType, "SFInt32")) return GF_SG_VRML_SFINT32; + else if (!stricmp(fieldType, "SFString")) return GF_SG_VRML_SFSTRING; + else if (!stricmp(fieldType, "SFVec2f")) return GF_SG_VRML_SFVEC2F; + else if (!stricmp(fieldType, "SFVec3f")) return GF_SG_VRML_SFVEC3F; + else if (!stricmp(fieldType, "SFVec2d")) return GF_SG_VRML_SFVEC2D; + else if (!stricmp(fieldType, "SFVec3d")) return GF_SG_VRML_SFVEC3D; + else if (!stricmp(fieldType, "SFColor")) return GF_SG_VRML_SFCOLOR; + else if (!stricmp(fieldType, "SFColorRGBA")) return GF_SG_VRML_SFCOLORRGBA; + else if (!stricmp(fieldType, "SFRotation")) return GF_SG_VRML_SFROTATION; + else if (!stricmp(fieldType, "SFImage")) return GF_SG_VRML_SFIMAGE; + else if (!stricmp(fieldType, "SFAttrRef")) return GF_SG_VRML_SFATTRREF; + else if (!stricmp(fieldType, "SFNode")) return GF_SG_VRML_SFNODE; + + else if (!stricmp(fieldType, "MFBool")) return GF_SG_VRML_MFBOOL; + else if (!stricmp(fieldType, "MFFloat")) return GF_SG_VRML_MFFLOAT; + else if (!stricmp(fieldType, "MFDouble")) return GF_SG_VRML_MFDOUBLE; + else if (!stricmp(fieldType, "MFTime")) return GF_SG_VRML_MFTIME; + else if (!stricmp(fieldType, "MFInt32")) return GF_SG_VRML_MFINT32; + else if (!stricmp(fieldType, "MFString")) return GF_SG_VRML_MFSTRING; + else if (!stricmp(fieldType, "MFVec2f")) return GF_SG_VRML_MFVEC2F; + else if (!stricmp(fieldType, "MFVec3f")) return GF_SG_VRML_MFVEC3F; + else if (!stricmp(fieldType, "MFVec2d")) return GF_SG_VRML_MFVEC2D; + else if (!stricmp(fieldType, "MFVec3d")) return GF_SG_VRML_MFVEC3D; + else if (!stricmp(fieldType, "MFColor")) return GF_SG_VRML_MFCOLOR; + else if (!stricmp(fieldType, "MFColorRGBA")) return GF_SG_VRML_MFCOLORRGBA; + else if (!stricmp(fieldType, "MFRotation")) return GF_SG_VRML_MFROTATION; + else if (!stricmp(fieldType, "MFImage")) return GF_SG_VRML_MFIMAGE; + else if (!stricmp(fieldType, "MFAttrRef")) return GF_SG_VRML_MFATTRREF; + else if (!stricmp(fieldType, "MFNode")) return GF_SG_VRML_MFNODE; + + return GF_SG_VRML_UNKNOWN; +} + +#endif + +void gf_sg_sfurl_del(SFURL url) { if (url.url) gf_free(url.url); } + Bool gf_sg_vrml_is_sf_field(u32 FieldType) { return (FieldType<GF_SG_VRML_FIRST_MF); } -/********************************************************************* - MF Fields manipulation (alloc, realloc, GetAt) -*********************************************************************/ +void gf_sg_mfstring_del(MFString par) +{ + u32 i; + for (i=0; i<par.count; i++) { + if (par.vals[i]) gf_free(par.vals[i]); + } + gf_free(par.vals); +} + + +GF_EXPORT +void gf_sg_mfurl_del(MFURL url) +{ + u32 i; + for (i=0; i<url.count; i++) { + gf_sg_sfurl_del(url.vals[i]); + } + gf_free(url.vals); +} +void gf_sg_mfscript_del(MFScript sc) +{ + u32 i; + for (i=0; i<sc.count; i++) { + if (sc.vals[i].script_text) gf_free(sc.vals[i].script_text); + } + gf_free(sc.vals); +} + + +void gf_sg_vrml_copy_mfurl(MFURL *dst, MFURL *src) +{ + u32 i; + gf_sg_vrml_mf_reset(dst, GF_SG_VRML_MFURL); + dst->count = src->count; + dst->vals = gf_malloc(sizeof(SFURL)*src->count); + for (i=0; i<src->count; i++) { + dst->vals[i].OD_ID = src->vals[i].OD_ID; + dst->vals[i].url = src->vals[i].url ? gf_strdup(src->vals[i].url) : NULL; + } +} + + //return the size of fixed fields (eg no buffer in the field) u32 gf_sg_vrml_get_sf_size(u32 FieldType) @@ -711,8 +837,12 @@ u32 gf_sg_vrml_get_sf_size(u32 FieldType) return 4*sizeof(SFFloat); case GF_SG_VRML_SFROTATION: case GF_SG_VRML_MFROTATION: + case GF_SG_VRML_MFVEC4F: return 4*sizeof(SFFloat); + case GF_SG_VRML_SFATTRREF: + case GF_SG_VRML_MFATTRREF: + return sizeof(SFAttrRef); //check if that works!! case GF_SG_VRML_SFSTRING: case GF_SG_VRML_MFSTRING: @@ -768,6 +898,9 @@ u32 gf_sg_vrml_get_sf_type(u32 FieldType) case GF_SG_VRML_SFROTATION: case GF_SG_VRML_MFROTATION: return GF_SG_VRML_SFROTATION; + case GF_SG_VRML_SFATTRREF: + case GF_SG_VRML_MFATTRREF: + return GF_SG_VRML_SFATTRREF; //check if that works!! case GF_SG_VRML_SFSTRING: @@ -788,99 +921,6 @@ u32 gf_sg_vrml_get_sf_type(u32 FieldType) } } -const char *gf_sg_vrml_get_event_type_name(u32 EventType, Bool forX3D) -{ - switch (EventType) { - case GF_SG_EVENT_IN: return forX3D ? "inputOnly" : "eventIn"; - case GF_SG_EVENT_FIELD: return forX3D ? "initializeOnly" : "field"; - case GF_SG_EVENT_EXPOSED_FIELD: return forX3D ? "inputOutput" : "exposedField"; - case GF_SG_EVENT_OUT: return forX3D ? "outputOnly" : "eventOut"; - default: return "unknownEvent"; - } -} - -const char *gf_sg_vrml_get_field_type_by_name(u32 FieldType) -{ - - switch (FieldType) { - case GF_SG_VRML_SFBOOL: return "SFBool"; - case GF_SG_VRML_SFFLOAT: return "SFFloat"; - case GF_SG_VRML_SFDOUBLE: return "SFDouble"; - case GF_SG_VRML_SFTIME: return "SFTime"; - case GF_SG_VRML_SFINT32: return "SFInt32"; - case GF_SG_VRML_SFSTRING: return "SFString"; - case GF_SG_VRML_SFVEC3F: return "SFVec3f"; - case GF_SG_VRML_SFVEC2F: return "SFVec2f"; - case GF_SG_VRML_SFVEC3D: return "SFVec3d"; - case GF_SG_VRML_SFVEC2D: return "SFVec2d"; - case GF_SG_VRML_SFCOLOR: return "SFColor"; - case GF_SG_VRML_SFCOLORRGBA: return "SFColorRGBA"; - case GF_SG_VRML_SFROTATION: return "SFRotation"; - case GF_SG_VRML_SFIMAGE: return "SFImage"; - case GF_SG_VRML_SFNODE: return "SFNode"; - case GF_SG_VRML_SFVEC4F: return "SFVec4f"; - case GF_SG_VRML_MFBOOL: return "MFBool"; - case GF_SG_VRML_MFFLOAT: return "MFFloat"; - case GF_SG_VRML_MFDOUBLE: return "MFDouble"; - case GF_SG_VRML_MFTIME: return "MFTime"; - case GF_SG_VRML_MFINT32: return "MFInt32"; - case GF_SG_VRML_MFSTRING: return "MFString"; - case GF_SG_VRML_MFVEC3F: return "MFVec3f"; - case GF_SG_VRML_MFVEC2F: return "MFVec2f"; - case GF_SG_VRML_MFVEC3D: return "MFVec3d"; - case GF_SG_VRML_MFVEC2D: return "MFVec2d"; - case GF_SG_VRML_MFCOLOR: return "MFColor"; - case GF_SG_VRML_MFCOLORRGBA: return "MFColorRGBA"; - case GF_SG_VRML_MFROTATION: return "MFRotation"; - case GF_SG_VRML_MFIMAGE: return "MFImage"; - case GF_SG_VRML_MFNODE: return "MFNode"; - case GF_SG_VRML_MFVEC4F: return "MFVec4f"; - case GF_SG_VRML_SFURL: return "SFURL"; - case GF_SG_VRML_MFURL: return "MFURL"; - case GF_SG_VRML_SFCOMMANDBUFFER: return "SFCommandBuffer"; - case GF_SG_VRML_SFSCRIPT: return "SFScript"; - case GF_SG_VRML_MFSCRIPT: return "MFScript"; - default: return "UnknownType"; - } -} - -u32 gf_sg_field_type_by_name(char *fieldType) -{ - if (!stricmp(fieldType, "SFBool")) return GF_SG_VRML_SFBOOL; - else if (!stricmp(fieldType, "SFFloat")) return GF_SG_VRML_SFFLOAT; - else if (!stricmp(fieldType, "SFDouble")) return GF_SG_VRML_SFDOUBLE; - else if (!stricmp(fieldType, "SFTime")) return GF_SG_VRML_SFTIME; - else if (!stricmp(fieldType, "SFInt32")) return GF_SG_VRML_SFINT32; - else if (!stricmp(fieldType, "SFString")) return GF_SG_VRML_SFSTRING; - else if (!stricmp(fieldType, "SFVec2f")) return GF_SG_VRML_SFVEC2F; - else if (!stricmp(fieldType, "SFVec3f")) return GF_SG_VRML_SFVEC3F; - else if (!stricmp(fieldType, "SFVec2d")) return GF_SG_VRML_SFVEC2D; - else if (!stricmp(fieldType, "SFVec3d")) return GF_SG_VRML_SFVEC3D; - else if (!stricmp(fieldType, "SFColor")) return GF_SG_VRML_SFCOLOR; - else if (!stricmp(fieldType, "SFColorRGBA")) return GF_SG_VRML_SFCOLORRGBA; - else if (!stricmp(fieldType, "SFRotation")) return GF_SG_VRML_SFROTATION; - else if (!stricmp(fieldType, "SFImage")) return GF_SG_VRML_SFIMAGE; - else if (!stricmp(fieldType, "SFNode")) return GF_SG_VRML_SFNODE; - - else if (!stricmp(fieldType, "MFBool")) return GF_SG_VRML_MFBOOL; - else if (!stricmp(fieldType, "MFFloat")) return GF_SG_VRML_MFFLOAT; - else if (!stricmp(fieldType, "MFDouble")) return GF_SG_VRML_MFDOUBLE; - else if (!stricmp(fieldType, "MFTime")) return GF_SG_VRML_MFTIME; - else if (!stricmp(fieldType, "MFInt32")) return GF_SG_VRML_MFINT32; - else if (!stricmp(fieldType, "MFString")) return GF_SG_VRML_MFSTRING; - else if (!stricmp(fieldType, "MFVec2f")) return GF_SG_VRML_MFVEC2F; - else if (!stricmp(fieldType, "MFVec3f")) return GF_SG_VRML_MFVEC3F; - else if (!stricmp(fieldType, "MFVec2d")) return GF_SG_VRML_MFVEC2D; - else if (!stricmp(fieldType, "MFVec3d")) return GF_SG_VRML_MFVEC3D; - else if (!stricmp(fieldType, "MFColor")) return GF_SG_VRML_MFCOLOR; - else if (!stricmp(fieldType, "MFColorRGBA")) return GF_SG_VRML_MFCOLORRGBA; - else if (!stricmp(fieldType, "MFRotation")) return GF_SG_VRML_MFROTATION; - else if (!stricmp(fieldType, "MFImage")) return GF_SG_VRML_MFIMAGE; - else if (!stricmp(fieldType, "MFNode")) return GF_SG_VRML_MFNODE; - - return GF_SG_VRML_UNKNOWN; -} - // // Insert (+alloc) an MFField with a specified position for insertion and sets the ptr to the // newly created slot @@ -902,8 +942,8 @@ GF_Err gf_sg_vrml_mf_insert(void *mf, u32 FieldType, void **new_ptr, u32 InsertA //first item ever if (!mffield->count || !mffield->array) { - if (mffield->array) free(mffield->array); - mffield->array = (char*)malloc(sizeof(char)*FieldSize); + if (mffield->array) gf_free(mffield->array); + mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize); memset(mffield->array, 0, sizeof(char)*FieldSize); mffield->count = 1; if (new_ptr) *new_ptr = mffield->array; @@ -912,14 +952,14 @@ GF_Err gf_sg_vrml_mf_insert(void *mf, u32 FieldType, void **new_ptr, u32 InsertA //append at the end if (InsertAt >= mffield->count) { - mffield->array = (char*)realloc(mffield->array, sizeof(char)*(1+mffield->count)*FieldSize); + mffield->array = (char*)gf_realloc(mffield->array, sizeof(char)*(1+mffield->count)*FieldSize); memset(mffield->array + mffield->count * FieldSize, 0, FieldSize); if (new_ptr) *new_ptr = mffield->array + mffield->count * FieldSize; mffield->count += 1; return GF_OK; } //alloc 1+itemCount - buffer = (char*)malloc(sizeof(char)*(1+mffield->count)*FieldSize); + buffer = (char*)gf_malloc(sizeof(char)*(1+mffield->count)*FieldSize); //insert in the array k=0; @@ -933,12 +973,45 @@ GF_Err gf_sg_vrml_mf_insert(void *mf, u32 FieldType, void **new_ptr, u32 InsertA } memcpy(buffer + (k+i) * FieldSize , mffield->array + i*FieldSize, FieldSize); } - free(mffield->array); + gf_free(mffield->array); mffield->array = buffer; mffield->count += 1; return GF_OK; } + +GF_EXPORT +GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType) +{ + GenMFField *mffield = (GenMFField *)mf; + if (!mffield->array) return GF_OK; + + //field we can't copy + if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; + if (!gf_sg_vrml_get_sf_size(FieldType)) return GF_BAD_PARAM; + + switch (FieldType) { + case GF_SG_VRML_MFSTRING: + gf_sg_mfstring_del( * ((MFString *) mf)); + break; + case GF_SG_VRML_MFURL: + gf_sg_mfurl_del( * ((MFURL *) mf)); + break; + case GF_SG_VRML_MFSCRIPT: + gf_sg_mfscript_del( * ((MFScript *) mf)); + break; + default: + if (mffield->array) gf_free(mffield->array); + break; + } + + mffield->array = NULL; + mffield->count = 0; + return GF_OK; +} + +#ifndef GPAC_DISABLE_VRML + #define MAX_MFFIELD_ALLOC 5000000 GF_EXPORT GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems) @@ -958,7 +1031,7 @@ GF_Err gf_sg_vrml_mf_alloc(void *mf, u32 FieldType, u32 NbItems) if (mffield->count==NbItems) return GF_OK; gf_sg_vrml_mf_reset(mf, FieldType); if (NbItems) { - mffield->array = (char*)malloc(sizeof(char)*FieldSize*NbItems); + mffield->array = (char*)gf_malloc(sizeof(char)*FieldSize*NbItems); memset(mffield->array, 0, sizeof(char)*FieldSize*NbItems); } mffield->count = NbItems; @@ -1007,13 +1080,13 @@ GF_Err gf_sg_vrml_mf_remove(void *mf, u32 FieldType, u32 RemoveFrom) if (!mffield->count || RemoveFrom >= mffield->count) return GF_BAD_PARAM; if (mffield->count == 1) { - free(mffield->array); + gf_free(mffield->array); mffield->array = NULL; mffield->count = 0; return GF_OK; } k=0; - buffer = (char*)malloc(sizeof(char)*(mffield->count-1)*FieldSize); + buffer = (char*)gf_malloc(sizeof(char)*(mffield->count-1)*FieldSize); for (i=0; i<mffield->count; i++) { if (RemoveFrom == i) { k = 1; @@ -1021,42 +1094,12 @@ GF_Err gf_sg_vrml_mf_remove(void *mf, u32 FieldType, u32 RemoveFrom) memcpy(buffer + (i-k)*FieldSize, mffield->array + i*FieldSize, FieldSize); } } - free(mffield->array); + gf_free(mffield->array); mffield->array = buffer; mffield->count -= 1; return GF_OK; } -GF_EXPORT -GF_Err gf_sg_vrml_mf_reset(void *mf, u32 FieldType) -{ - GenMFField *mffield = (GenMFField *)mf; - if (!mffield->array) return GF_OK; - - //field we can't copy - if (gf_sg_vrml_is_sf_field(FieldType)) return GF_BAD_PARAM; - if (!gf_sg_vrml_get_sf_size(FieldType)) return GF_BAD_PARAM; - - switch (FieldType) { - case GF_SG_VRML_MFSTRING: - gf_sg_mfstring_del( * ((MFString *) mf)); - break; - case GF_SG_VRML_MFURL: - gf_sg_mfurl_del( * ((MFURL *) mf)); - break; - case GF_SG_VRML_MFSCRIPT: - gf_sg_mfscript_del( * ((MFScript *) mf)); - break; - default: - if (mffield->array) free(mffield->array); - break; - } - - mffield->array = NULL; - mffield->count = 0; - return GF_OK; -} - /*special cloning with type-casting from SF/MF strings to URL conversion since proto URL doesn't exist as a field type (it's just a stupid encoding trick) */ void VRML_FieldCopyCast(void *dest, u32 dst_field_type, void *orig, u32 ori_field_type) @@ -1073,26 +1116,26 @@ void VRML_FieldCopyCast(void *dest, u32 dst_field_type, void *orig, u32 ori_fiel url = ((SFURL *)orig); if (url->OD_ID>0) { sprintf(tmp, "%d", url->OD_ID); - if ( ((SFString*)dest)->buffer) free(((SFString*)dest)->buffer); - ((SFString*)dest)->buffer = strdup(tmp); + if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); + ((SFString*)dest)->buffer = gf_strdup(tmp); } else { - if ( ((SFString*)dest)->buffer) free(((SFString*)dest)->buffer); - ((SFString*)dest)->buffer = strdup(url->url); + if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); + ((SFString*)dest)->buffer = gf_strdup(url->url); } } /*for SFString to MFString cast*/ else if (ori_field_type == GF_SG_VRML_SFSTRING) { - if ( ((SFString*)dest)->buffer) free(((SFString*)dest)->buffer); - ((SFString*)dest)->buffer = strdup(((SFString*)orig)->buffer); + if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); + ((SFString*)dest)->buffer = gf_strdup(((SFString*)orig)->buffer); } return; case GF_SG_VRML_SFURL: if (ori_field_type != GF_SG_VRML_SFSTRING) return; url = ((SFURL *)dest); url->OD_ID = 0; - if (url->url) free(url->url); + if (url->url) gf_free(url->url); if ( ((SFString*)orig)->buffer) - url->url = strdup(((SFString*)orig)->buffer); + url->url = gf_strdup(((SFString*)orig)->buffer); else url->url = NULL; return; @@ -1127,7 +1170,7 @@ void VRML_FieldCopyCast(void *dest, u32 dst_field_type, void *orig, u32 ori_fiel } GF_EXPORT -void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type) +void gf_sg_vrml_field_clone(void *dest, void *orig, u32 field_type, GF_SceneGraph *inScene) { u32 size, i, sf_type; void *dst_field, *orig_field; @@ -1159,50 +1202,63 @@ void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type) case GF_SG_VRML_SFVEC3F: memcpy(dest, orig, sizeof(SFVec3f)); break; + case GF_SG_VRML_SFATTRREF: + memcpy(dest, orig, sizeof(SFAttrRef)); + break; case GF_SG_VRML_SFSTRING: - if ( ((SFString*)dest)->buffer) free(((SFString*)dest)->buffer); + if ( ((SFString*)dest)->buffer) gf_free(((SFString*)dest)->buffer); if ( ((SFString*)orig)->buffer ) - ((SFString*)dest)->buffer = strdup(((SFString*)orig)->buffer); + ((SFString*)dest)->buffer = gf_strdup(((SFString*)orig)->buffer); else ((SFString*)dest)->buffer = NULL; break; case GF_SG_VRML_SFURL: - if ( ((SFURL *)dest)->url ) free( ((SFURL *)dest)->url ); + if ( ((SFURL *)dest)->url ) gf_free( ((SFURL *)dest)->url ); ((SFURL *)dest)->OD_ID = ((SFURL *)orig)->OD_ID; if (((SFURL *)orig)->url) - ((SFURL *)dest)->url = strdup(((SFURL *)orig)->url); + ((SFURL *)dest)->url = gf_strdup(((SFURL *)orig)->url); else ((SFURL *)dest)->url = NULL; break; case GF_SG_VRML_SFIMAGE: - if (((SFImage *)dest)->pixels) free(((SFImage *)dest)->pixels); + if (((SFImage *)dest)->pixels) gf_free(((SFImage *)dest)->pixels); ((SFImage *)dest)->width = ((SFImage *)orig)->width; ((SFImage *)dest)->height = ((SFImage *)orig)->height; ((SFImage *)dest)->numComponents = ((SFImage *)orig)->numComponents; size = ((SFImage *)dest)->width * ((SFImage *)dest)->height * ((SFImage *)dest)->numComponents; - ((SFImage *)dest)->pixels = (u8*)malloc(sizeof(char)*size); + ((SFImage *)dest)->pixels = (u8*)gf_malloc(sizeof(char)*size); memcpy(((SFImage *)dest)->pixels, ((SFImage *)orig)->pixels, sizeof(char)*size); break; case GF_SG_VRML_SFCOMMANDBUFFER: - gf_sg_sfcommand_del( *(SFCommandBuffer *)dest); - ((SFCommandBuffer *)dest)->commandList = gf_list_new(); - ((SFCommandBuffer *)dest)->bufferSize = ((SFCommandBuffer *)orig)->bufferSize; - if (((SFCommandBuffer *)dest)->bufferSize) { - ((SFCommandBuffer *)dest)->buffer = (u8*)malloc(sizeof(char)*((SFCommandBuffer *)orig)->bufferSize); - memcpy(((SFCommandBuffer *)dest)->buffer, - ((SFCommandBuffer *)orig)->buffer, - sizeof(char)*((SFCommandBuffer *)orig)->bufferSize); + { + SFCommandBuffer *cb_dst = (SFCommandBuffer *)dest; + SFCommandBuffer *cb_src = (SFCommandBuffer *)orig; + + cb_dst->bufferSize = cb_src->bufferSize; + if (cb_dst->bufferSize) { + cb_dst->buffer = (u8*)gf_realloc(cb_dst->buffer, sizeof(char)*cb_dst->bufferSize); + memcpy(cb_dst->buffer, cb_src->buffer, sizeof(char)*cb_src->bufferSize); } else { - ((SFCommandBuffer *)dest)->buffer = NULL; + u32 j, c2; + if (cb_dst->buffer) gf_free(cb_dst->buffer); + cb_dst->buffer = NULL; + /*clone command list*/ + c2 = gf_list_count(cb_src->commandList); + for (j=0; j<c2;j++) { + GF_Command *sub_com = (GF_Command *)gf_list_get(cb_src->commandList, j); + GF_Command *new_com = gf_sg_vrml_command_clone(sub_com, inScene, 0); + gf_list_add(cb_dst->commandList, new_com); + } } + } break; /*simply copy text string*/ case GF_SG_VRML_SFSCRIPT: - if (((SFScript*)dest)->script_text) free(((SFScript*)dest)->script_text); + if (((SFScript*)dest)->script_text) gf_free(((SFScript*)dest)->script_text); ((SFScript*)dest)->script_text = NULL; if ( ((SFScript*)orig)->script_text) - ((SFScript *)dest)->script_text = (u8*)strdup( (char*) ((SFScript*)orig)->script_text ); + ((SFScript *)dest)->script_text = (u8*)gf_strdup( (char*) ((SFScript*)orig)->script_text ); break; @@ -1215,9 +1271,10 @@ void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type) case GF_SG_VRML_MFVEC2F: case GF_SG_VRML_MFCOLOR: case GF_SG_VRML_MFROTATION: + case GF_SG_VRML_MFATTRREF: size = gf_sg_vrml_get_sf_size(field_type) * ((GenMFField *)orig)->count; if (((GenMFField *)orig)->count != ((GenMFField *)dest)->count) { - ((GenMFField *)dest)->array = realloc(((GenMFField *)dest)->array, size); + ((GenMFField *)dest)->array = gf_realloc(((GenMFField *)dest)->array, size); ((GenMFField *)dest)->count = ((GenMFField *)orig)->count; } memcpy(((GenMFField *)dest)->array, ((GenMFField *)orig)->array, size); @@ -1241,6 +1298,11 @@ void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type) } } +GF_EXPORT +void gf_sg_vrml_field_copy(void *dest, void *orig, u32 field_type) +{ + gf_sg_vrml_field_clone(dest, orig, field_type, NULL); +} GF_EXPORT Bool gf_sg_vrml_field_equal(void *dest, void *orig, u32 field_type) @@ -1301,12 +1363,16 @@ Bool gf_sg_vrml_field_equal(void *dest, void *orig, u32 field_type) } break; case GF_SG_VRML_SFIMAGE: + case GF_SG_VRML_SFATTRREF: case GF_SG_VRML_SFSCRIPT: case GF_SG_VRML_SFCOMMANDBUFFER: changed = 1; break; //MFFields + case GF_SG_VRML_MFATTRREF: + changed = 1; + break; case GF_SG_VRML_MFBOOL: case GF_SG_VRML_MFFLOAT: case GF_SG_VRML_MFTIME: @@ -1356,10 +1422,16 @@ u32 gf_node_get_num_fields_in_mode(GF_Node *Node, u8 IndexMode) { assert(Node); if (Node->sgprivate->tag == TAG_ProtoNode) return gf_sg_proto_get_num_fields(Node, IndexMode); - else if ((Node->sgprivate->tag == TAG_MPEG4_Script) || (Node->sgprivate->tag == TAG_X3D_Script) ) + else if ((Node->sgprivate->tag == TAG_MPEG4_Script) +#ifndef GPAC_DISABLE_X3D + || (Node->sgprivate->tag == TAG_X3D_Script) +#endif + ) return gf_sg_script_get_num_fields(Node, IndexMode); else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_MPEG4) return gf_sg_mpeg4_node_get_field_count(Node, IndexMode); +#ifndef GPAC_DISABLE_X3D else if (Node->sgprivate->tag <= GF_NODE_RANGE_LAST_X3D) return gf_sg_x3d_node_get_field_count(Node); +#endif else return 0; } @@ -1397,27 +1469,41 @@ Bool gf_sg_vrml_node_init(GF_Node *node) { switch (node->sgprivate->tag) { case TAG_MPEG4_ColorInterpolator: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_ColorInterpolator: +#endif return InitColorInterpolator((M_ColorInterpolator *)node); case TAG_MPEG4_CoordinateInterpolator: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_CoordinateInterpolator: +#endif return InitCoordinateInterpolator((M_CoordinateInterpolator *)node); case TAG_MPEG4_CoordinateInterpolator2D: return InitCoordinateInterpolator2D((M_CoordinateInterpolator2D *)node); case TAG_MPEG4_NormalInterpolator: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_NormalInterpolator: +#endif return InitNormalInterpolator((M_NormalInterpolator*)node); case TAG_MPEG4_OrientationInterpolator: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_OrientationInterpolator: +#endif return InitOrientationInterpolator((M_OrientationInterpolator*)node); case TAG_MPEG4_PositionInterpolator: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_PositionInterpolator: +#endif return InitPositionInterpolator((M_PositionInterpolator *)node); case TAG_MPEG4_PositionInterpolator2D: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_PositionInterpolator2D: +#endif return InitPositionInterpolator2D((M_PositionInterpolator2D *)node); case TAG_MPEG4_ScalarInterpolator: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_ScalarInterpolator: +#endif return InitScalarInterpolator((M_ScalarInterpolator *)node); case TAG_MPEG4_Valuator: return InitValuator((M_Valuator *)node); @@ -1432,9 +1518,12 @@ Bool gf_sg_vrml_node_init(GF_Node *node) case TAG_MPEG4_CoordinateInterpolator4D: return InitCoordinateInterpolator4D((M_CoordinateInterpolator4D *)node); case TAG_MPEG4_Script: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Script: +#endif return 1; +#ifndef GPAC_DISABLE_X3D case TAG_X3D_BooleanFilter: InitBooleanFilter(node); return 1; case TAG_X3D_BooleanSequencer: InitBooleanSequencer(node); return 1; case TAG_X3D_BooleanToggle: InitBooleanToggle(node); return 1; @@ -1442,6 +1531,7 @@ Bool gf_sg_vrml_node_init(GF_Node *node) case TAG_X3D_IntegerSequencer: InitIntegerSequencer(node); return 1; case TAG_X3D_IntegerTrigger: InitIntegerTrigger(node); return 1; case TAG_X3D_TimeTrigger: InitTimeTrigger(node); return 1; +#endif } return 0; } @@ -1453,23 +1543,24 @@ Bool gf_sg_vrml_node_changed(GF_Node *node, GF_FieldInfo *field) /*hardcoded protos need modification notifs*/ if (node->sgprivate->UserCallback) return 0; case TAG_MPEG4_ColorInterpolator: - case TAG_X3D_ColorInterpolator: case TAG_MPEG4_CoordinateInterpolator: - case TAG_X3D_CoordinateInterpolator: case TAG_MPEG4_CoordinateInterpolator2D: case TAG_MPEG4_NormalInterpolator: - case TAG_X3D_NormalInterpolator: case TAG_MPEG4_OrientationInterpolator: - case TAG_X3D_OrientationInterpolator: case TAG_MPEG4_PositionInterpolator: - case TAG_X3D_PositionInterpolator: case TAG_MPEG4_PositionInterpolator2D: case TAG_MPEG4_ScalarInterpolator: - case TAG_X3D_ScalarInterpolator: case TAG_MPEG4_Valuator: case TAG_MPEG4_PositionInterpolator4D: case TAG_MPEG4_CoordinateInterpolator4D: case TAG_MPEG4_Script: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_ColorInterpolator: + case TAG_X3D_CoordinateInterpolator: + case TAG_X3D_NormalInterpolator: + case TAG_X3D_OrientationInterpolator: + case TAG_X3D_PositionInterpolator: + case TAG_X3D_ScalarInterpolator: case TAG_X3D_Script: case TAG_X3D_BooleanFilter: case TAG_X3D_BooleanSequencer: @@ -1478,6 +1569,7 @@ Bool gf_sg_vrml_node_changed(GF_Node *node, GF_FieldInfo *field) case TAG_X3D_IntegerSequencer: case TAG_X3D_IntegerTrigger: case TAG_X3D_TimeTrigger: +#endif return 1; case TAG_MPEG4_PositionAnimator: PA_Modified(node, field); return 1; case TAG_MPEG4_PositionAnimator2D: PA2D_Modified(node, field); return 1; @@ -1487,3 +1579,113 @@ Bool gf_sg_vrml_node_changed(GF_Node *node, GF_FieldInfo *field) } +char *gf_node_vrml_dump_attribute(GF_Node *n, GF_FieldInfo *info) +{ + char szVal[1024]; + + switch (info->fieldType) { + case GF_SG_VRML_SFBOOL: + strcpy(szVal, *((SFBool*)info->far_ptr) ? "TRUE" : "FALSE"); + return gf_strdup(szVal); + case GF_SG_VRML_SFINT32: + sprintf(szVal, "%d", *((SFInt32*)info->far_ptr) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFFLOAT: + sprintf(szVal, "%g", FIX2FLT( *((SFFloat*)info->far_ptr) ) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFDOUBLE: + sprintf(szVal, "%g", *((SFDouble *)info->far_ptr) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFTIME: + sprintf(szVal, "%g", *((SFTime *)info->far_ptr) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFVEC2F: + sprintf(szVal, "%g %g", FIX2FLT(((SFVec2f *)info->far_ptr)->x), FIX2FLT( ((SFVec2f *)info->far_ptr)->y) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFVEC2D: + sprintf(szVal, "%g %g", ((SFVec2d *)info->far_ptr)->x, ((SFVec2d *)info->far_ptr)->y); + return gf_strdup(szVal); + case GF_SG_VRML_SFVEC3F: + sprintf(szVal, "%g %g %g", FIX2FLT(((SFVec3f *)info->far_ptr)->x), FIX2FLT( ((SFVec3f *)info->far_ptr)->y) , FIX2FLT( ((SFVec3f *)info->far_ptr)->z) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFVEC3D: + sprintf(szVal, "%g %g %g", ((SFVec3d *)info->far_ptr)->x, ((SFVec3d *)info->far_ptr)->y, ((SFVec3d *)info->far_ptr)->z); + return gf_strdup(szVal); + case GF_SG_VRML_SFCOLOR: + sprintf(szVal, "%g %g %g", FIX2FLT(((SFColor *)info->far_ptr)->red), FIX2FLT( ((SFColor *)info->far_ptr)->green) , FIX2FLT( ((SFColor *)info->far_ptr)->blue) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFCOLORRGBA: + sprintf(szVal, "%g %g %g %g", FIX2FLT(((SFColorRGBA *)info->far_ptr)->red), FIX2FLT( ((SFColorRGBA*)info->far_ptr)->green) , FIX2FLT( ((SFColorRGBA*)info->far_ptr)->blue) , FIX2FLT( ((SFColorRGBA*)info->far_ptr)->alpha) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFROTATION: + sprintf(szVal, "%g %g %g %g", FIX2FLT(((SFRotation *)info->far_ptr)->x), FIX2FLT( ((SFRotation *)info->far_ptr)->y) , FIX2FLT( ((SFRotation *)info->far_ptr)->z), FIX2FLT( ((SFRotation *)info->far_ptr)->q) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFSTRING: + if (!((SFString*)info->far_ptr)->buffer ) return gf_strdup(""); + return gf_strdup( ((SFString*)info->far_ptr)->buffer ); + + case GF_SG_VRML_SFURL: + if (((SFURL *)info->far_ptr)->url) { + return gf_strdup( ((SFURL *)info->far_ptr)->url ); + } else { + sprintf(szVal, "od://%d", ((SFURL *)info->far_ptr)->OD_ID); + return gf_strdup(szVal); + } + + case GF_SG_VRML_SFIMAGE: + { + u32 i, count; + char *buf; + SFImage *img = (SFImage *)info->far_ptr; + + count = img->width * img->height * img->numComponents; + i = (3/*' 0x'*/ + 2/*%02X*/*img->numComponents)*count + 20; + buf = gf_malloc(sizeof(char) * i); + + sprintf(buf , "%d %d %d", img->width, img->height, img->numComponents); + + for (i=0; i<count; ) { + switch (img->numComponents) { + case 1: + sprintf(szVal, " 0x%02X", img->pixels[i]); + i++; + break; + case 2: + sprintf(szVal, " 0x%02X%02X", img->pixels[i], img->pixels[i+1]); + i+=2; + break; + case 3: + sprintf(szVal, " 0x%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2]); + i+=3; + break; + case 4: + sprintf(szVal, " 0x%02X%02X%02X%02X", img->pixels[i], img->pixels[i+1], img->pixels[i+2], img->pixels[i+3]); + i+=4; + break; + } + strcat(buf, szVal); + } + return buf; + } + default: + break; + } + /*todo - dump MFFields*/ + return NULL; +} + +#endif /*GPAC_DISABLE_VRML*/ + +Bool gf_node_in_table(GF_Node *node, u32 NDTType) +{ +#ifndef GPAC_DISABLE_VRML + u32 tag = node ? node->sgprivate->tag : 0; + if (tag==TAG_ProtoNode) { + tag = gf_sg_proto_get_root_tag(((GF_ProtoInstance *)node)->proto_interface); + if (tag==TAG_UndefinedNode) return 1; + } + return gf_node_in_table_by_tag(tag, NDTType); +#else + return 1; +#endif +} diff --git a/src/scenegraph/x3d_nodes.c b/src/scenegraph/x3d_nodes.c index b27e4e4..8ca5e41 100644 --- a/src/scenegraph/x3d_nodes.c +++ b/src/scenegraph/x3d_nodes.c @@ -24,9 +24,9 @@ /* - DO NOT MOFIFY - File generated on GMT Thu Aug 07 11:44:22 2008 + DO NOT MOFIFY - File generated on GMT Fri Jul 31 16:39:50 2009 - BY X3DGen for GPAC Version 0.4.5-DEV + BY X3DGen for GPAC Version 0.4.6-DEV */ @@ -36,6 +36,8 @@ /*for NDT tag definitions*/ #include <gpac/nodes_mpeg4.h> +#ifndef GPAC_DISABLE_X3D + /* Anchor Node deletion @@ -391,7 +393,7 @@ static GF_Node *ArcClose2D_Create() gf_node_setup((GF_Node *)p, TAG_X3D_ArcClose2D); /*default field values*/ - p->closureType.buffer = (char*) malloc(sizeof(char) * 4); + p->closureType.buffer = (char*) gf_malloc(sizeof(char) * 4); strcpy(p->closureType.buffer, "PIE"); p->endAngle = FLT2FIX(1.5707963); p->radius = FLT2FIX(1); @@ -693,7 +695,7 @@ static GF_Node *Background_Create() gf_node_setup((GF_Node *)p, TAG_X3D_Background); /*default field values*/ - p->skyColor.vals = (SFColor*)malloc(sizeof(SFColor)*1); + p->skyColor.vals = (SFColor*)gf_malloc(sizeof(SFColor)*1); p->skyColor.count = 1; p->skyColor.vals[0].red = FLT2FIX(0); p->skyColor.vals[0].green = FLT2FIX(0); @@ -2674,344 +2676,4388 @@ static GF_Node *ElevationGrid_Create() /* - Extrusion Node deletion + EspduTransform Node deletion */ -static void Extrusion_Del(GF_Node *node) -{ - X_Extrusion *p = (X_Extrusion *) node; - gf_sg_mfvec2f_del(p->set_crossSection); - gf_sg_mfrotation_del(p->set_orientation); - gf_sg_mfvec2f_del(p->set_scale); - gf_sg_mfvec3f_del(p->set_spine); - gf_sg_mfvec2f_del(p->crossSection); - gf_sg_mfrotation_del(p->orientation); - gf_sg_mfvec2f_del(p->scale); - gf_sg_mfvec3f_del(p->spine); +static void EspduTransform_Del(GF_Node *node) +{ + X_EspduTransform *p = (X_EspduTransform *) node; + gf_sg_sfstring_del(p->address); + gf_sg_mfint32_del(p->articulationParameterDesignatorArray); + gf_sg_mfint32_del(p->articulationParameterChangeIndicatorArray); + gf_sg_mfint32_del(p->articulationParameterIdPartAttachedToArray); + gf_sg_mfint32_del(p->articulationParameterTypeArray); + gf_sg_mffloat_del(p->articulationParameterArray); + gf_sg_sfstring_del(p->marking); + gf_sg_sfstring_del(p->multicastRelayHost); + gf_sg_sfstring_del(p->networkMode); gf_node_unregister((GF_Node *) p->metadata, node); + gf_sg_vrml_parent_destroy(node); gf_node_free((GF_Node *)p); } -static u32 Extrusion_get_field_count(GF_Node *node, u8 dummy) +static u32 EspduTransform_get_field_count(GF_Node *node, u8 dummy) { - return 15; + return 86; } -static GF_Err Extrusion_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err EspduTransform_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_crossSection"; + info->name = "addChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_Extrusion *)node)->on_set_crossSection; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((X_Extrusion *) node)->set_crossSection; + info->on_event_in = ((X_EspduTransform *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_EspduTransform *)node)->addChildren; return GF_OK; case 1: - info->name = "set_orientation"; + info->name = "removeChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_Extrusion *)node)->on_set_orientation; - info->fieldType = GF_SG_VRML_MFROTATION; - info->far_ptr = & ((X_Extrusion *) node)->set_orientation; + info->on_event_in = ((X_EspduTransform *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_EspduTransform *)node)->removeChildren; return GF_OK; case 2: - info->name = "set_scale"; + info->name = "set_articulationParameterValue0"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_Extrusion *)node)->on_set_scale; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((X_Extrusion *) node)->set_scale; + info->on_event_in = ((X_EspduTransform *)node)->on_set_articulationParameterValue0; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->set_articulationParameterValue0; return GF_OK; case 3: - info->name = "set_spine"; + info->name = "set_articulationParameterValue1"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_Extrusion *)node)->on_set_spine; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((X_Extrusion *) node)->set_spine; + info->on_event_in = ((X_EspduTransform *)node)->on_set_articulationParameterValue1; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->set_articulationParameterValue1; return GF_OK; case 4: - info->name = "beginCap"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_Extrusion *) node)->beginCap; + info->name = "set_articulationParameterValue2"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_EspduTransform *)node)->on_set_articulationParameterValue2; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->set_articulationParameterValue2; return GF_OK; case 5: - info->name = "ccw"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_Extrusion *) node)->ccw; + info->name = "set_articulationParameterValue3"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_EspduTransform *)node)->on_set_articulationParameterValue3; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->set_articulationParameterValue3; return GF_OK; case 6: - info->name = "convex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_Extrusion *) node)->convex; + info->name = "set_articulationParameterValue4"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_EspduTransform *)node)->on_set_articulationParameterValue4; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->set_articulationParameterValue4; return GF_OK; case 7: - info->name = "creaseAngle"; - info->eventType = GF_SG_EVENT_FIELD; + info->name = "set_articulationParameterValue5"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_EspduTransform *)node)->on_set_articulationParameterValue5; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_Extrusion *) node)->creaseAngle; + info->far_ptr = & ((X_EspduTransform *) node)->set_articulationParameterValue5; return GF_OK; case 8: - info->name = "crossSection"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((X_Extrusion *) node)->crossSection; + info->name = "set_articulationParameterValue6"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_EspduTransform *)node)->on_set_articulationParameterValue6; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->set_articulationParameterValue6; return GF_OK; case 9: - info->name = "endCap"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_Extrusion *) node)->endCap; + info->name = "set_articulationParameterValue7"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_EspduTransform *)node)->on_set_articulationParameterValue7; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->set_articulationParameterValue7; return GF_OK; case 10: - info->name = "orientation"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFROTATION; - info->far_ptr = & ((X_Extrusion *) node)->orientation; + info->name = "address"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_EspduTransform *) node)->address; return GF_OK; case 11: - info->name = "scale"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFVEC2F; - info->far_ptr = & ((X_Extrusion *) node)->scale; + info->name = "applicationID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->applicationID; return GF_OK; case 12: - info->name = "solid"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_Extrusion *) node)->solid; + info->name = "articulationParameterCount"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterCount; return GF_OK; case 13: - info->name = "spine"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((X_Extrusion *) node)->spine; + info->name = "articulationParameterDesignatorArray"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterDesignatorArray; return GF_OK; case 14: - info->name = "metadata"; + info->name = "articulationParameterChangeIndicatorArray"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_Extrusion *)node)->metadata; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterChangeIndicatorArray; return GF_OK; - default: - return GF_BAD_PARAM; - } -} - - -static s32 Extrusion_get_field_index_by_name(char *name) -{ - if (!strcmp("set_crossSection", name)) return 0; - if (!strcmp("set_orientation", name)) return 1; - if (!strcmp("set_scale", name)) return 2; - if (!strcmp("set_spine", name)) return 3; - if (!strcmp("beginCap", name)) return 4; - if (!strcmp("ccw", name)) return 5; - if (!strcmp("convex", name)) return 6; - if (!strcmp("creaseAngle", name)) return 7; - if (!strcmp("crossSection", name)) return 8; - if (!strcmp("endCap", name)) return 9; - if (!strcmp("orientation", name)) return 10; - if (!strcmp("scale", name)) return 11; - if (!strcmp("solid", name)) return 12; - if (!strcmp("spine", name)) return 13; - if (!strcmp("metadata", name)) return 14; - return -1; - } - - -static GF_Node *Extrusion_Create() -{ - X_Extrusion *p; - GF_SAFEALLOC(p, X_Extrusion); - if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_Extrusion); - - /*default field values*/ - p->beginCap = 1; - p->ccw = 1; - p->convex = 1; - p->creaseAngle = FLT2FIX(0.0); - p->crossSection.vals = (SFVec2f*) malloc(sizeof(SFVec2f)*5); - p->crossSection.count = 5; - p->crossSection.vals[0].x = FLT2FIX(1); - p->crossSection.vals[0].y = FLT2FIX(1); - p->crossSection.vals[1].x = FLT2FIX(1); - p->crossSection.vals[1].y = FLT2FIX(-1); - p->crossSection.vals[2].x = FLT2FIX(-1); - p->crossSection.vals[2].y = FLT2FIX(-1); - p->crossSection.vals[3].x = FLT2FIX(-1); - p->crossSection.vals[3].y = FLT2FIX(1); - p->crossSection.vals[4].x = FLT2FIX(1); - p->crossSection.vals[4].y = FLT2FIX(1); - p->endCap = 1; - p->orientation.vals = (GF_Vec4*)malloc(sizeof(GF_Vec4)*1); - p->orientation.count = 1; - p->orientation.vals[0].x = FLT2FIX(0); - p->orientation.vals[0].y = FLT2FIX(0); - p->orientation.vals[0].z = FLT2FIX(1); - p->orientation.vals[0].q = FLT2FIX(0); - p->scale.vals = (SFVec2f*) malloc(sizeof(SFVec2f)*1); - p->scale.count = 1; - p->scale.vals[0].x = FLT2FIX(1); - p->scale.vals[0].y = FLT2FIX(1); - p->solid = 1; - p->spine.vals = (SFVec3f*)malloc(sizeof(SFVec3f)*2); - p->spine.count = 2; - p->spine.vals[0].x = FLT2FIX(0); - p->spine.vals[0].y = FLT2FIX(0); - p->spine.vals[0].z = FLT2FIX(0); - p->spine.vals[1].x = FLT2FIX(0); - p->spine.vals[1].y = FLT2FIX(1); - p->spine.vals[1].z = FLT2FIX(0); - return (GF_Node *)p; -} - - -/* - FillProperties Node deletion -*/ - -static void FillProperties_Del(GF_Node *node) -{ - X_FillProperties *p = (X_FillProperties *) node; - gf_node_free((GF_Node *)p); -} - - -static u32 FillProperties_get_field_count(GF_Node *node, u8 dummy) -{ - return 4; -} - -static GF_Err FillProperties_get_field(GF_Node *node, GF_FieldInfo *info) -{ - switch (info->fieldIndex) { - case 0: - info->name = "filled"; + case 15: + info->name = "articulationParameterIdPartAttachedToArray"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_FillProperties *) node)->filled; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterIdPartAttachedToArray; return GF_OK; - case 1: - info->name = "hatchColor"; + case 16: + info->name = "articulationParameterTypeArray"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((X_FillProperties *) node)->hatchColor; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterTypeArray; return GF_OK; - case 2: - info->name = "hatched"; + case 17: + info->name = "articulationParameterArray"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_FillProperties *) node)->hatched; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterArray; return GF_OK; - case 3: - info->name = "hatchStyle"; + case 18: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_EspduTransform *) node)->center; + return GF_OK; + case 19: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_EspduTransform *)node)->children; + return GF_OK; + case 20: + info->name = "collisionType"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((X_FillProperties *) node)->hatchStyle; + info->far_ptr = & ((X_EspduTransform *) node)->collisionType; return GF_OK; - default: - return GF_BAD_PARAM; - } -} - - -static s32 FillProperties_get_field_index_by_name(char *name) -{ - if (!strcmp("filled", name)) return 0; - if (!strcmp("hatchColor", name)) return 1; - if (!strcmp("hatched", name)) return 2; - if (!strcmp("hatchStyle", name)) return 3; - return -1; - } - - -static GF_Node *FillProperties_Create() -{ - X_FillProperties *p; - GF_SAFEALLOC(p, X_FillProperties); - if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_FillProperties); - - /*default field values*/ - p->filled = 1; - p->hatchColor.red = FLT2FIX(1); - p->hatchColor.green = FLT2FIX(1); - p->hatchColor.blue = FLT2FIX(1); - p->hatched = 1; - p->hatchStyle = 1; - return (GF_Node *)p; + case 21: + info->name = "deadReckoning"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->deadReckoning; + return GF_OK; + case 22: + info->name = "detonationLocation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_EspduTransform *) node)->detonationLocation; + return GF_OK; + case 23: + info->name = "detonationRelativeLocation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_EspduTransform *) node)->detonationRelativeLocation; + return GF_OK; + case 24: + info->name = "detonationResult"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->detonationResult; + return GF_OK; + case 25: + info->name = "entityCategory"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->entityCategory; + return GF_OK; + case 26: + info->name = "entityCountry"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->entityCountry; + return GF_OK; + case 27: + info->name = "entityDomain"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->entityDomain; + return GF_OK; + case 28: + info->name = "entityExtra"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->entityExtra; + return GF_OK; + case 29: + info->name = "entityID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->entityID; + return GF_OK; + case 30: + info->name = "entityKind"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->entityKind; + return GF_OK; + case 31: + info->name = "entitySpecific"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->entitySpecific; + return GF_OK; + case 32: + info->name = "entitySubCategory"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->entitySubCategory; + return GF_OK; + case 33: + info->name = "eventApplicationID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->eventApplicationID; + return GF_OK; + case 34: + info->name = "eventEntityID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->eventEntityID; + return GF_OK; + case 35: + info->name = "eventNumber"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->eventNumber; + return GF_OK; + case 36: + info->name = "eventSiteID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->eventSiteID; + return GF_OK; + case 37: + info->name = "fired1"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->fired1; + return GF_OK; + case 38: + info->name = "fired2"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->fired2; + return GF_OK; + case 39: + info->name = "fireMissionIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->fireMissionIndex; + return GF_OK; + case 40: + info->name = "firingRange"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->firingRange; + return GF_OK; + case 41: + info->name = "firingRate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->firingRate; + return GF_OK; + case 42: + info->name = "forceID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->forceID; + return GF_OK; + case 43: + info->name = "fuse"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->fuse; + return GF_OK; + case 44: + info->name = "linearVelocity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_EspduTransform *) node)->linearVelocity; + return GF_OK; + case 45: + info->name = "linearAcceleration"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_EspduTransform *) node)->linearAcceleration; + return GF_OK; + case 46: + info->name = "marking"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_EspduTransform *) node)->marking; + return GF_OK; + case 47: + info->name = "multicastRelayHost"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_EspduTransform *) node)->multicastRelayHost; + return GF_OK; + case 48: + info->name = "multicastRelayPort"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->multicastRelayPort; + return GF_OK; + case 49: + info->name = "munitionApplicationID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->munitionApplicationID; + return GF_OK; + case 50: + info->name = "munitionEndPoint"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_EspduTransform *) node)->munitionEndPoint; + return GF_OK; + case 51: + info->name = "munitionEntityID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->munitionEntityID; + return GF_OK; + case 52: + info->name = "munitionQuantity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->munitionQuantity; + return GF_OK; + case 53: + info->name = "munitionSiteID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->munitionSiteID; + return GF_OK; + case 54: + info->name = "munitionStartPoint"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_EspduTransform *) node)->munitionStartPoint; + return GF_OK; + case 55: + info->name = "networkMode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_EspduTransform *) node)->networkMode; + return GF_OK; + case 56: + info->name = "port"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->port; + return GF_OK; + case 57: + info->name = "readInterval"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_EspduTransform *) node)->readInterval; + return GF_OK; + case 58: + info->name = "rotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_EspduTransform *) node)->rotation; + return GF_OK; + case 59: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_EspduTransform *) node)->scale; + return GF_OK; + case 60: + info->name = "scaleOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_EspduTransform *) node)->scaleOrientation; + return GF_OK; + case 61: + info->name = "siteID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->siteID; + return GF_OK; + case 62: + info->name = "translation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_EspduTransform *) node)->translation; + return GF_OK; + case 63: + info->name = "warhead"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_EspduTransform *) node)->warhead; + return GF_OK; + case 64: + info->name = "writeInterval"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_EspduTransform *) node)->writeInterval; + return GF_OK; + case 65: + info->name = "rtpHeaderExpected"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->rtpHeaderExpected; + return GF_OK; + case 66: + info->name = "articulationParameterValue0_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterValue0_changed; + return GF_OK; + case 67: + info->name = "articulationParameterValue1_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterValue1_changed; + return GF_OK; + case 68: + info->name = "articulationParameterValue2_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterValue2_changed; + return GF_OK; + case 69: + info->name = "articulationParameterValue3_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterValue3_changed; + return GF_OK; + case 70: + info->name = "articulationParameterValue4_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterValue4_changed; + return GF_OK; + case 71: + info->name = "articulationParameterValue5_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterValue5_changed; + return GF_OK; + case 72: + info->name = "articulationParameterValue6_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterValue6_changed; + return GF_OK; + case 73: + info->name = "articulationParameterValue7_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_EspduTransform *) node)->articulationParameterValue7_changed; + return GF_OK; + case 74: + info->name = "collideTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_EspduTransform *) node)->collideTime; + return GF_OK; + case 75: + info->name = "detonateTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_EspduTransform *) node)->detonateTime; + return GF_OK; + case 76: + info->name = "firedTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_EspduTransform *) node)->firedTime; + return GF_OK; + case 77: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->isActive; + return GF_OK; + case 78: + info->name = "isCollided"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->isCollided; + return GF_OK; + case 79: + info->name = "isDetonated"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->isDetonated; + return GF_OK; + case 80: + info->name = "isNetworkReader"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->isNetworkReader; + return GF_OK; + case 81: + info->name = "isNetworkWriter"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->isNetworkWriter; + return GF_OK; + case 82: + info->name = "isRtpHeaderHeard"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->isRtpHeaderHeard; + return GF_OK; + case 83: + info->name = "isStandAlone"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_EspduTransform *) node)->isStandAlone; + return GF_OK; + case 84: + info->name = "timestamp"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_EspduTransform *) node)->timestamp; + return GF_OK; + case 85: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_EspduTransform *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 EspduTransform_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("set_articulationParameterValue0", name)) return 2; + if (!strcmp("set_articulationParameterValue1", name)) return 3; + if (!strcmp("set_articulationParameterValue2", name)) return 4; + if (!strcmp("set_articulationParameterValue3", name)) return 5; + if (!strcmp("set_articulationParameterValue4", name)) return 6; + if (!strcmp("set_articulationParameterValue5", name)) return 7; + if (!strcmp("set_articulationParameterValue6", name)) return 8; + if (!strcmp("set_articulationParameterValue7", name)) return 9; + if (!strcmp("address", name)) return 10; + if (!strcmp("applicationID", name)) return 11; + if (!strcmp("articulationParameterCount", name)) return 12; + if (!strcmp("articulationParameterDesignatorArray", name)) return 13; + if (!strcmp("articulationParameterChangeIndicatorArray", name)) return 14; + if (!strcmp("articulationParameterIdPartAttachedToArray", name)) return 15; + if (!strcmp("articulationParameterTypeArray", name)) return 16; + if (!strcmp("articulationParameterArray", name)) return 17; + if (!strcmp("center", name)) return 18; + if (!strcmp("children", name)) return 19; + if (!strcmp("collisionType", name)) return 20; + if (!strcmp("deadReckoning", name)) return 21; + if (!strcmp("detonationLocation", name)) return 22; + if (!strcmp("detonationRelativeLocation", name)) return 23; + if (!strcmp("detonationResult", name)) return 24; + if (!strcmp("entityCategory", name)) return 25; + if (!strcmp("entityCountry", name)) return 26; + if (!strcmp("entityDomain", name)) return 27; + if (!strcmp("entityExtra", name)) return 28; + if (!strcmp("entityID", name)) return 29; + if (!strcmp("entityKind", name)) return 30; + if (!strcmp("entitySpecific", name)) return 31; + if (!strcmp("entitySubCategory", name)) return 32; + if (!strcmp("eventApplicationID", name)) return 33; + if (!strcmp("eventEntityID", name)) return 34; + if (!strcmp("eventNumber", name)) return 35; + if (!strcmp("eventSiteID", name)) return 36; + if (!strcmp("fired1", name)) return 37; + if (!strcmp("fired2", name)) return 38; + if (!strcmp("fireMissionIndex", name)) return 39; + if (!strcmp("firingRange", name)) return 40; + if (!strcmp("firingRate", name)) return 41; + if (!strcmp("forceID", name)) return 42; + if (!strcmp("fuse", name)) return 43; + if (!strcmp("linearVelocity", name)) return 44; + if (!strcmp("linearAcceleration", name)) return 45; + if (!strcmp("marking", name)) return 46; + if (!strcmp("multicastRelayHost", name)) return 47; + if (!strcmp("multicastRelayPort", name)) return 48; + if (!strcmp("munitionApplicationID", name)) return 49; + if (!strcmp("munitionEndPoint", name)) return 50; + if (!strcmp("munitionEntityID", name)) return 51; + if (!strcmp("munitionQuantity", name)) return 52; + if (!strcmp("munitionSiteID", name)) return 53; + if (!strcmp("munitionStartPoint", name)) return 54; + if (!strcmp("networkMode", name)) return 55; + if (!strcmp("port", name)) return 56; + if (!strcmp("readInterval", name)) return 57; + if (!strcmp("rotation", name)) return 58; + if (!strcmp("scale", name)) return 59; + if (!strcmp("scaleOrientation", name)) return 60; + if (!strcmp("siteID", name)) return 61; + if (!strcmp("translation", name)) return 62; + if (!strcmp("warhead", name)) return 63; + if (!strcmp("writeInterval", name)) return 64; + if (!strcmp("rtpHeaderExpected", name)) return 65; + if (!strcmp("articulationParameterValue0_changed", name)) return 66; + if (!strcmp("articulationParameterValue1_changed", name)) return 67; + if (!strcmp("articulationParameterValue2_changed", name)) return 68; + if (!strcmp("articulationParameterValue3_changed", name)) return 69; + if (!strcmp("articulationParameterValue4_changed", name)) return 70; + if (!strcmp("articulationParameterValue5_changed", name)) return 71; + if (!strcmp("articulationParameterValue6_changed", name)) return 72; + if (!strcmp("articulationParameterValue7_changed", name)) return 73; + if (!strcmp("collideTime", name)) return 74; + if (!strcmp("detonateTime", name)) return 75; + if (!strcmp("firedTime", name)) return 76; + if (!strcmp("isActive", name)) return 77; + if (!strcmp("isCollided", name)) return 78; + if (!strcmp("isDetonated", name)) return 79; + if (!strcmp("isNetworkReader", name)) return 80; + if (!strcmp("isNetworkWriter", name)) return 81; + if (!strcmp("isRtpHeaderHeard", name)) return 82; + if (!strcmp("isStandAlone", name)) return 83; + if (!strcmp("timestamp", name)) return 84; + if (!strcmp("metadata", name)) return 85; + return -1; + } + + +static GF_Node *EspduTransform_Create() +{ + X_EspduTransform *p; + GF_SAFEALLOC(p, X_EspduTransform); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_EspduTransform); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->address.buffer = (char*) gf_malloc(sizeof(char) * 10); + strcpy(p->address.buffer, "localhost"); + p->applicationID = 1; + p->articulationParameterCount = 0; + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->collisionType = 0; + p->deadReckoning = 0; + p->detonationLocation.x = FLT2FIX(0); + p->detonationLocation.y = FLT2FIX(0); + p->detonationLocation.z = FLT2FIX(0); + p->detonationRelativeLocation.x = FLT2FIX(0); + p->detonationRelativeLocation.y = FLT2FIX(0); + p->detonationRelativeLocation.z = FLT2FIX(0); + p->detonationResult = 0; + p->entityCategory = 0; + p->entityCountry = 0; + p->entityDomain = 0; + p->entityExtra = 0; + p->entityID = 0; + p->entityKind = 0; + p->entitySpecific = 0; + p->entitySubCategory = 0; + p->eventApplicationID = 1; + p->eventEntityID = 0; + p->eventNumber = 0; + p->eventSiteID = 0; + p->fireMissionIndex = 0; + p->firingRange = FLT2FIX(0.0); + p->firingRate = 0; + p->forceID = 0; + p->fuse = 0; + p->linearVelocity.x = FLT2FIX(0); + p->linearVelocity.y = FLT2FIX(0); + p->linearVelocity.z = FLT2FIX(0); + p->linearAcceleration.x = FLT2FIX(0); + p->linearAcceleration.y = FLT2FIX(0); + p->linearAcceleration.z = FLT2FIX(0); + p->multicastRelayPort = 0; + p->munitionApplicationID = 1; + p->munitionEndPoint.x = FLT2FIX(0); + p->munitionEndPoint.y = FLT2FIX(0); + p->munitionEndPoint.z = FLT2FIX(0); + p->munitionEntityID = 0; + p->munitionQuantity = 0; + p->munitionSiteID = 0; + p->munitionStartPoint.x = FLT2FIX(0); + p->munitionStartPoint.y = FLT2FIX(0); + p->munitionStartPoint.z = FLT2FIX(0); + p->networkMode.buffer = (char*) gf_malloc(sizeof(char) * 11); + strcpy(p->networkMode.buffer, "standAlone"); + p->port = 0; + p->readInterval = 0.1; + p->rotation.x = FLT2FIX(0); + p->rotation.y = FLT2FIX(0); + p->rotation.z = FLT2FIX(1); + p->rotation.q = FLT2FIX(0); + p->scale.x = FLT2FIX(1); + p->scale.y = FLT2FIX(1); + p->scale.z = FLT2FIX(1); + p->scaleOrientation.x = FLT2FIX(0); + p->scaleOrientation.y = FLT2FIX(0); + p->scaleOrientation.z = FLT2FIX(1); + p->scaleOrientation.q = FLT2FIX(0); + p->siteID = 0; + p->translation.x = FLT2FIX(0); + p->translation.y = FLT2FIX(0); + p->translation.z = FLT2FIX(0); + p->warhead = 0; + p->writeInterval = 1.0; + return (GF_Node *)p; +} + + +/* + Extrusion Node deletion +*/ + +static void Extrusion_Del(GF_Node *node) +{ + X_Extrusion *p = (X_Extrusion *) node; + gf_sg_mfvec2f_del(p->set_crossSection); + gf_sg_mfrotation_del(p->set_orientation); + gf_sg_mfvec2f_del(p->set_scale); + gf_sg_mfvec3f_del(p->set_spine); + gf_sg_mfvec2f_del(p->crossSection); + gf_sg_mfrotation_del(p->orientation); + gf_sg_mfvec2f_del(p->scale); + gf_sg_mfvec3f_del(p->spine); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 Extrusion_get_field_count(GF_Node *node, u8 dummy) +{ + return 15; +} + +static GF_Err Extrusion_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_crossSection"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_Extrusion *)node)->on_set_crossSection; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((X_Extrusion *) node)->set_crossSection; + return GF_OK; + case 1: + info->name = "set_orientation"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_Extrusion *)node)->on_set_orientation; + info->fieldType = GF_SG_VRML_MFROTATION; + info->far_ptr = & ((X_Extrusion *) node)->set_orientation; + return GF_OK; + case 2: + info->name = "set_scale"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_Extrusion *)node)->on_set_scale; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((X_Extrusion *) node)->set_scale; + return GF_OK; + case 3: + info->name = "set_spine"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_Extrusion *)node)->on_set_spine; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((X_Extrusion *) node)->set_spine; + return GF_OK; + case 4: + info->name = "beginCap"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_Extrusion *) node)->beginCap; + return GF_OK; + case 5: + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_Extrusion *) node)->ccw; + return GF_OK; + case 6: + info->name = "convex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_Extrusion *) node)->convex; + return GF_OK; + case 7: + info->name = "creaseAngle"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_Extrusion *) node)->creaseAngle; + return GF_OK; + case 8: + info->name = "crossSection"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((X_Extrusion *) node)->crossSection; + return GF_OK; + case 9: + info->name = "endCap"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_Extrusion *) node)->endCap; + return GF_OK; + case 10: + info->name = "orientation"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFROTATION; + info->far_ptr = & ((X_Extrusion *) node)->orientation; + return GF_OK; + case 11: + info->name = "scale"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((X_Extrusion *) node)->scale; + return GF_OK; + case 12: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_Extrusion *) node)->solid; + return GF_OK; + case 13: + info->name = "spine"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((X_Extrusion *) node)->spine; + return GF_OK; + case 14: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_Extrusion *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Extrusion_get_field_index_by_name(char *name) +{ + if (!strcmp("set_crossSection", name)) return 0; + if (!strcmp("set_orientation", name)) return 1; + if (!strcmp("set_scale", name)) return 2; + if (!strcmp("set_spine", name)) return 3; + if (!strcmp("beginCap", name)) return 4; + if (!strcmp("ccw", name)) return 5; + if (!strcmp("convex", name)) return 6; + if (!strcmp("creaseAngle", name)) return 7; + if (!strcmp("crossSection", name)) return 8; + if (!strcmp("endCap", name)) return 9; + if (!strcmp("orientation", name)) return 10; + if (!strcmp("scale", name)) return 11; + if (!strcmp("solid", name)) return 12; + if (!strcmp("spine", name)) return 13; + if (!strcmp("metadata", name)) return 14; + return -1; + } + + +static GF_Node *Extrusion_Create() +{ + X_Extrusion *p; + GF_SAFEALLOC(p, X_Extrusion); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_Extrusion); + + /*default field values*/ + p->beginCap = 1; + p->ccw = 1; + p->convex = 1; + p->creaseAngle = FLT2FIX(0.0); + p->crossSection.vals = (SFVec2f*) gf_malloc(sizeof(SFVec2f)*5); + p->crossSection.count = 5; + p->crossSection.vals[0].x = FLT2FIX(1); + p->crossSection.vals[0].y = FLT2FIX(1); + p->crossSection.vals[1].x = FLT2FIX(1); + p->crossSection.vals[1].y = FLT2FIX(-1); + p->crossSection.vals[2].x = FLT2FIX(-1); + p->crossSection.vals[2].y = FLT2FIX(-1); + p->crossSection.vals[3].x = FLT2FIX(-1); + p->crossSection.vals[3].y = FLT2FIX(1); + p->crossSection.vals[4].x = FLT2FIX(1); + p->crossSection.vals[4].y = FLT2FIX(1); + p->endCap = 1; + p->orientation.vals = (GF_Vec4*)gf_malloc(sizeof(GF_Vec4)*1); + p->orientation.count = 1; + p->orientation.vals[0].x = FLT2FIX(0); + p->orientation.vals[0].y = FLT2FIX(0); + p->orientation.vals[0].z = FLT2FIX(1); + p->orientation.vals[0].q = FLT2FIX(0); + p->scale.vals = (SFVec2f*) gf_malloc(sizeof(SFVec2f)*1); + p->scale.count = 1; + p->scale.vals[0].x = FLT2FIX(1); + p->scale.vals[0].y = FLT2FIX(1); + p->solid = 1; + p->spine.vals = (SFVec3f*)gf_malloc(sizeof(SFVec3f)*2); + p->spine.count = 2; + p->spine.vals[0].x = FLT2FIX(0); + p->spine.vals[0].y = FLT2FIX(0); + p->spine.vals[0].z = FLT2FIX(0); + p->spine.vals[1].x = FLT2FIX(0); + p->spine.vals[1].y = FLT2FIX(1); + p->spine.vals[1].z = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + FillProperties Node deletion +*/ + +static void FillProperties_Del(GF_Node *node) +{ + X_FillProperties *p = (X_FillProperties *) node; + gf_node_free((GF_Node *)p); +} + + +static u32 FillProperties_get_field_count(GF_Node *node, u8 dummy) +{ + return 4; +} + +static GF_Err FillProperties_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "filled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_FillProperties *) node)->filled; + return GF_OK; + case 1: + info->name = "hatchColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((X_FillProperties *) node)->hatchColor; + return GF_OK; + case 2: + info->name = "hatched"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_FillProperties *) node)->hatched; + return GF_OK; + case 3: + info->name = "hatchStyle"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_FillProperties *) node)->hatchStyle; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 FillProperties_get_field_index_by_name(char *name) +{ + if (!strcmp("filled", name)) return 0; + if (!strcmp("hatchColor", name)) return 1; + if (!strcmp("hatched", name)) return 2; + if (!strcmp("hatchStyle", name)) return 3; + return -1; + } + + +static GF_Node *FillProperties_Create() +{ + X_FillProperties *p; + GF_SAFEALLOC(p, X_FillProperties); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_FillProperties); + + /*default field values*/ + p->filled = 1; + p->hatchColor.red = FLT2FIX(1); + p->hatchColor.green = FLT2FIX(1); + p->hatchColor.blue = FLT2FIX(1); + p->hatched = 1; + p->hatchStyle = 1; + return (GF_Node *)p; +} + + +/* + Fog Node deletion +*/ + +static void Fog_Del(GF_Node *node) +{ + X_Fog *p = (X_Fog *) node; + gf_sg_sfstring_del(p->fogType); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 Fog_get_field_count(GF_Node *node, u8 dummy) +{ + return 7; +} + +static GF_Err Fog_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((X_Fog *) node)->color; + return GF_OK; + case 1: + info->name = "fogType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_Fog *) node)->fogType; + return GF_OK; + case 2: + info->name = "visibilityRange"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_Fog *) node)->visibilityRange; + return GF_OK; + case 3: + info->name = "set_bind"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_Fog *)node)->on_set_bind; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_Fog *) node)->set_bind; + return GF_OK; + case 4: + info->name = "isBound"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_Fog *) node)->isBound; + return GF_OK; + case 5: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_Fog *)node)->metadata; + return GF_OK; + case 6: + info->name = "bindTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_Fog *) node)->bindTime; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Fog_get_field_index_by_name(char *name) +{ + if (!strcmp("color", name)) return 0; + if (!strcmp("fogType", name)) return 1; + if (!strcmp("visibilityRange", name)) return 2; + if (!strcmp("set_bind", name)) return 3; + if (!strcmp("isBound", name)) return 4; + if (!strcmp("metadata", name)) return 5; + if (!strcmp("bindTime", name)) return 6; + return -1; + } + + +static GF_Node *Fog_Create() +{ + X_Fog *p; + GF_SAFEALLOC(p, X_Fog); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_Fog); + + /*default field values*/ + p->color.red = FLT2FIX(1); + p->color.green = FLT2FIX(1); + p->color.blue = FLT2FIX(1); + p->fogType.buffer = (char*) gf_malloc(sizeof(char) * 7); + strcpy(p->fogType.buffer, "LINEAR"); + p->visibilityRange = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + FontStyle Node deletion +*/ + +static void FontStyle_Del(GF_Node *node) +{ + X_FontStyle *p = (X_FontStyle *) node; + gf_sg_mfstring_del(p->family); + gf_sg_mfstring_del(p->justify); + gf_sg_sfstring_del(p->language); + gf_sg_sfstring_del(p->style); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 FontStyle_get_field_count(GF_Node *node, u8 dummy) +{ + return 10; +} + +static GF_Err FontStyle_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "family"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_FontStyle *) node)->family; + return GF_OK; + case 1: + info->name = "horizontal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_FontStyle *) node)->horizontal; + return GF_OK; + case 2: + info->name = "justify"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_FontStyle *) node)->justify; + return GF_OK; + case 3: + info->name = "language"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_FontStyle *) node)->language; + return GF_OK; + case 4: + info->name = "leftToRight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_FontStyle *) node)->leftToRight; + return GF_OK; + case 5: + info->name = "size"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_FontStyle *) node)->size; + return GF_OK; + case 6: + info->name = "spacing"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_FontStyle *) node)->spacing; + return GF_OK; + case 7: + info->name = "style"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_FontStyle *) node)->style; + return GF_OK; + case 8: + info->name = "topToBottom"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_FontStyle *) node)->topToBottom; + return GF_OK; + case 9: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_FontStyle *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 FontStyle_get_field_index_by_name(char *name) +{ + if (!strcmp("family", name)) return 0; + if (!strcmp("horizontal", name)) return 1; + if (!strcmp("justify", name)) return 2; + if (!strcmp("language", name)) return 3; + if (!strcmp("leftToRight", name)) return 4; + if (!strcmp("size", name)) return 5; + if (!strcmp("spacing", name)) return 6; + if (!strcmp("style", name)) return 7; + if (!strcmp("topToBottom", name)) return 8; + if (!strcmp("metadata", name)) return 9; + return -1; + } + + +static GF_Node *FontStyle_Create() +{ + X_FontStyle *p; + GF_SAFEALLOC(p, X_FontStyle); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_FontStyle); + + /*default field values*/ + p->family.vals = (char**)gf_malloc(sizeof(SFString)*1); + p->family.count = 1; + p->family.vals[0] = (char*)gf_malloc(sizeof(char) * 6); + strcpy(p->family.vals[0], "SERIF"); + p->horizontal = 1; + p->justify.vals = (char**)gf_malloc(sizeof(SFString)*1); + p->justify.count = 1; + p->justify.vals[0] = (char*)gf_malloc(sizeof(char) * 6); + strcpy(p->justify.vals[0], "BEGIN"); + p->leftToRight = 1; + p->size = FLT2FIX(1.0); + p->spacing = FLT2FIX(1.0); + p->style.buffer = (char*) gf_malloc(sizeof(char) * 6); + strcpy(p->style.buffer, "PLAIN"); + p->topToBottom = 1; + return (GF_Node *)p; +} + + +/* + GeoCoordinate Node deletion +*/ + +static void GeoCoordinate_Del(GF_Node *node) +{ + X_GeoCoordinate *p = (X_GeoCoordinate *) node; + gf_sg_mfvec3d_del(p->point); + gf_node_unregister((GF_Node *) p->geoOrigin, node); + gf_sg_mfstring_del(p->geoSystem); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 GeoCoordinate_get_field_count(GF_Node *node, u8 dummy) +{ + return 4; +} + +static GF_Err GeoCoordinate_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "point"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3D; + info->far_ptr = & ((X_GeoCoordinate *) node)->point; + return GF_OK; + case 1: + info->name = "geoOrigin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeoOriginNode; + info->far_ptr = & ((X_GeoCoordinate *)node)->geoOrigin; + return GF_OK; + case 2: + info->name = "geoSystem"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoCoordinate *) node)->geoSystem; + return GF_OK; + case 3: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_GeoCoordinate *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 GeoCoordinate_get_field_index_by_name(char *name) +{ + if (!strcmp("point", name)) return 0; + if (!strcmp("geoOrigin", name)) return 1; + if (!strcmp("geoSystem", name)) return 2; + if (!strcmp("metadata", name)) return 3; + return -1; + } + + +static GF_Node *GeoCoordinate_Create() +{ + X_GeoCoordinate *p; + GF_SAFEALLOC(p, X_GeoCoordinate); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_GeoCoordinate); + + /*default field values*/ + p->geoSystem.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->geoSystem.count = 2; + p->geoSystem.vals[0] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[0], "GD"); + p->geoSystem.vals[1] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[1], "WE"); + return (GF_Node *)p; +} + + +/* + GeoElevationGrid Node deletion +*/ + +static void GeoElevationGrid_Del(GF_Node *node) +{ + X_GeoElevationGrid *p = (X_GeoElevationGrid *) node; + gf_sg_mfdouble_del(p->set_height); + gf_node_unregister((GF_Node *) p->color, node); + gf_node_unregister((GF_Node *) p->normal, node); + gf_node_unregister((GF_Node *) p->texCoord, node); + gf_sg_sfstring_del(p->geoGridOrigin); + gf_node_unregister((GF_Node *) p->geoOrigin, node); + gf_sg_mfstring_del(p->geoSystem); + gf_sg_mfdouble_del(p->height); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 GeoElevationGrid_get_field_count(GF_Node *node, u8 dummy) +{ + return 19; +} + +static GF_Err GeoElevationGrid_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_height"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_GeoElevationGrid *)node)->on_set_height; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_GeoElevationGrid *) node)->set_height; + return GF_OK; + case 1: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((X_GeoElevationGrid *)node)->color; + return GF_OK; + case 2: + info->name = "normal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((X_GeoElevationGrid *)node)->normal; + return GF_OK; + case 3: + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((X_GeoElevationGrid *)node)->texCoord; + return GF_OK; + case 4: + info->name = "yScale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_GeoElevationGrid *) node)->yScale; + return GF_OK; + case 5: + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoElevationGrid *) node)->ccw; + return GF_OK; + case 6: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoElevationGrid *) node)->colorPerVertex; + return GF_OK; + case 7: + info->name = "creaseAngle"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_GeoElevationGrid *) node)->creaseAngle; + return GF_OK; + case 8: + info->name = "geoGridOrigin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_GeoElevationGrid *) node)->geoGridOrigin; + return GF_OK; + case 9: + info->name = "geoOrigin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeoOriginNode; + info->far_ptr = & ((X_GeoElevationGrid *)node)->geoOrigin; + return GF_OK; + case 10: + info->name = "geoSystem"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoElevationGrid *) node)->geoSystem; + return GF_OK; + case 11: + info->name = "height"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_GeoElevationGrid *) node)->height; + return GF_OK; + case 12: + info->name = "normalPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoElevationGrid *) node)->normalPerVertex; + return GF_OK; + case 13: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoElevationGrid *) node)->solid; + return GF_OK; + case 14: + info->name = "xDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_GeoElevationGrid *) node)->xDimension; + return GF_OK; + case 15: + info->name = "xSpacing"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFDOUBLE; + info->far_ptr = & ((X_GeoElevationGrid *) node)->xSpacing; + return GF_OK; + case 16: + info->name = "zDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_GeoElevationGrid *) node)->zDimension; + return GF_OK; + case 17: + info->name = "zSpacing"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFDOUBLE; + info->far_ptr = & ((X_GeoElevationGrid *) node)->zSpacing; + return GF_OK; + case 18: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_GeoElevationGrid *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 GeoElevationGrid_get_field_index_by_name(char *name) +{ + if (!strcmp("set_height", name)) return 0; + if (!strcmp("color", name)) return 1; + if (!strcmp("normal", name)) return 2; + if (!strcmp("texCoord", name)) return 3; + if (!strcmp("yScale", name)) return 4; + if (!strcmp("ccw", name)) return 5; + if (!strcmp("colorPerVertex", name)) return 6; + if (!strcmp("creaseAngle", name)) return 7; + if (!strcmp("geoGridOrigin", name)) return 8; + if (!strcmp("geoOrigin", name)) return 9; + if (!strcmp("geoSystem", name)) return 10; + if (!strcmp("height", name)) return 11; + if (!strcmp("normalPerVertex", name)) return 12; + if (!strcmp("solid", name)) return 13; + if (!strcmp("xDimension", name)) return 14; + if (!strcmp("xSpacing", name)) return 15; + if (!strcmp("zDimension", name)) return 16; + if (!strcmp("zSpacing", name)) return 17; + if (!strcmp("metadata", name)) return 18; + return -1; + } + + +static GF_Node *GeoElevationGrid_Create() +{ + X_GeoElevationGrid *p; + GF_SAFEALLOC(p, X_GeoElevationGrid); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_GeoElevationGrid); + + /*default field values*/ + p->yScale = FLT2FIX(1.0); + p->ccw = 1; + p->colorPerVertex = 1; + p->creaseAngle = FLT2FIX(0.0); + p->geoGridOrigin.buffer = (char*) gf_malloc(sizeof(char) * 6); + strcpy(p->geoGridOrigin.buffer, "0 0 0"); + p->geoSystem.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->geoSystem.count = 2; + p->geoSystem.vals[0] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[0], "GD"); + p->geoSystem.vals[1] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[1], "WE"); + p->normalPerVertex = 1; + p->solid = 1; + p->xDimension = 0; + p->xSpacing = (SFDouble) 1.0; + p->zDimension = 0; + p->zSpacing = (SFDouble) 1.0; + return (GF_Node *)p; +} + + +/* + GeoLocation Node deletion +*/ + +static void GeoLocation_Del(GF_Node *node) +{ + X_GeoLocation *p = (X_GeoLocation *) node; + gf_node_unregister((GF_Node *) p->geoOrigin, node); + gf_sg_mfstring_del(p->geoSystem); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_sg_vrml_parent_destroy(node); + gf_node_free((GF_Node *)p); +} + + +static u32 GeoLocation_get_field_count(GF_Node *node, u8 dummy) +{ + return 7; +} + +static GF_Err GeoLocation_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_GeoLocation *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_GeoLocation *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_GeoLocation *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_GeoLocation *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_GeoLocation *)node)->children; + return GF_OK; + case 3: + info->name = "geoCoords"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3D; + info->far_ptr = & ((X_GeoLocation *) node)->geoCoords; + return GF_OK; + case 4: + info->name = "geoOrigin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeoOriginNode; + info->far_ptr = & ((X_GeoLocation *)node)->geoOrigin; + return GF_OK; + case 5: + info->name = "geoSystem"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoLocation *) node)->geoSystem; + return GF_OK; + case 6: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_GeoLocation *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 GeoLocation_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("geoCoords", name)) return 3; + if (!strcmp("geoOrigin", name)) return 4; + if (!strcmp("geoSystem", name)) return 5; + if (!strcmp("metadata", name)) return 6; + return -1; + } + + +static GF_Node *GeoLocation_Create() +{ + X_GeoLocation *p; + GF_SAFEALLOC(p, X_GeoLocation); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_GeoLocation); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->geoCoords.x = (SFDouble) 0; + p->geoCoords.y = (SFDouble) 0; + p->geoCoords.z = (SFDouble) 0; + p->geoSystem.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->geoSystem.count = 2; + p->geoSystem.vals[0] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[0], "GD"); + p->geoSystem.vals[1] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[1], "WE"); + return (GF_Node *)p; +} + + +/* + GeoLOD Node deletion +*/ + +static void GeoLOD_Del(GF_Node *node) +{ + X_GeoLOD *p = (X_GeoLOD *) node; + gf_sg_mfurl_del(p->child1Url); + gf_sg_mfurl_del(p->child2Url); + gf_sg_mfurl_del(p->child3Url); + gf_sg_mfurl_del(p->child4Url); + gf_node_unregister((GF_Node *) p->geoOrigin, node); + gf_sg_mfstring_del(p->geoSystem); + gf_sg_mfurl_del(p->rootUrl); + gf_node_unregister_children(node, p->rootNode); + gf_node_unregister_children(node, p->children); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 GeoLOD_get_field_count(GF_Node *node, u8 dummy) +{ + return 12; +} + +static GF_Err GeoLOD_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "center"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3D; + info->far_ptr = & ((X_GeoLOD *) node)->center; + return GF_OK; + case 1: + info->name = "child1Url"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((X_GeoLOD *) node)->child1Url; + return GF_OK; + case 2: + info->name = "child2Url"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((X_GeoLOD *) node)->child2Url; + return GF_OK; + case 3: + info->name = "child3Url"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((X_GeoLOD *) node)->child3Url; + return GF_OK; + case 4: + info->name = "child4Url"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((X_GeoLOD *) node)->child4Url; + return GF_OK; + case 5: + info->name = "geoOrigin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeoOriginNode; + info->far_ptr = & ((X_GeoLOD *)node)->geoOrigin; + return GF_OK; + case 6: + info->name = "geoSystem"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoLOD *) node)->geoSystem; + return GF_OK; + case 7: + info->name = "range"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_GeoLOD *) node)->range; + return GF_OK; + case 8: + info->name = "rootUrl"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((X_GeoLOD *) node)->rootUrl; + return GF_OK; + case 9: + info->name = "rootNode"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_GeoLOD *)node)->rootNode; + return GF_OK; + case 10: + info->name = "children"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_GeoLOD *)node)->children; + return GF_OK; + case 11: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_GeoLOD *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 GeoLOD_get_field_index_by_name(char *name) +{ + if (!strcmp("center", name)) return 0; + if (!strcmp("child1Url", name)) return 1; + if (!strcmp("child2Url", name)) return 2; + if (!strcmp("child3Url", name)) return 3; + if (!strcmp("child4Url", name)) return 4; + if (!strcmp("geoOrigin", name)) return 5; + if (!strcmp("geoSystem", name)) return 6; + if (!strcmp("range", name)) return 7; + if (!strcmp("rootUrl", name)) return 8; + if (!strcmp("rootNode", name)) return 9; + if (!strcmp("children", name)) return 10; + if (!strcmp("metadata", name)) return 11; + return -1; + } + + +static GF_Node *GeoLOD_Create() +{ + X_GeoLOD *p; + GF_SAFEALLOC(p, X_GeoLOD); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_GeoLOD); + + /*default field values*/ + p->center.x = (SFDouble) 0; + p->center.y = (SFDouble) 0; + p->center.z = (SFDouble) 0; + p->geoSystem.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->geoSystem.count = 2; + p->geoSystem.vals[0] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[0], "GD"); + p->geoSystem.vals[1] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[1], "WE"); + p->range = FLT2FIX(10); + return (GF_Node *)p; +} + + +/* + GeoMetadata Node deletion +*/ + +static void GeoMetadata_Del(GF_Node *node) +{ + X_GeoMetadata *p = (X_GeoMetadata *) node; + gf_node_unregister_children(node, p->data); + gf_sg_mfstring_del(p->summary); + gf_sg_mfurl_del(p->url); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 GeoMetadata_get_field_count(GF_Node *node, u8 dummy) +{ + return 4; +} + +static GF_Err GeoMetadata_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "data"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_GeoMetadata *)node)->data; + return GF_OK; + case 1: + info->name = "summary"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoMetadata *) node)->summary; + return GF_OK; + case 2: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((X_GeoMetadata *) node)->url; + return GF_OK; + case 3: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_GeoMetadata *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 GeoMetadata_get_field_index_by_name(char *name) +{ + if (!strcmp("data", name)) return 0; + if (!strcmp("summary", name)) return 1; + if (!strcmp("url", name)) return 2; + if (!strcmp("metadata", name)) return 3; + return -1; + } + + +static GF_Node *GeoMetadata_Create() +{ + X_GeoMetadata *p; + GF_SAFEALLOC(p, X_GeoMetadata); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_GeoMetadata); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + GeoOrigin Node deletion +*/ + +static void GeoOrigin_Del(GF_Node *node) +{ + X_GeoOrigin *p = (X_GeoOrigin *) node; + gf_sg_mfstring_del(p->geoSystem); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 GeoOrigin_get_field_count(GF_Node *node, u8 dummy) +{ + return 4; +} + +static GF_Err GeoOrigin_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "geoCoords"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3D; + info->far_ptr = & ((X_GeoOrigin *) node)->geoCoords; + return GF_OK; + case 1: + info->name = "geoSystem"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoOrigin *) node)->geoSystem; + return GF_OK; + case 2: + info->name = "rotateYUp"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoOrigin *) node)->rotateYUp; + return GF_OK; + case 3: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_GeoOrigin *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 GeoOrigin_get_field_index_by_name(char *name) +{ + if (!strcmp("geoCoords", name)) return 0; + if (!strcmp("geoSystem", name)) return 1; + if (!strcmp("rotateYUp", name)) return 2; + if (!strcmp("metadata", name)) return 3; + return -1; + } + + +static GF_Node *GeoOrigin_Create() +{ + X_GeoOrigin *p; + GF_SAFEALLOC(p, X_GeoOrigin); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_GeoOrigin); + + /*default field values*/ + p->geoCoords.x = (SFDouble) 0; + p->geoCoords.y = (SFDouble) 0; + p->geoCoords.z = (SFDouble) 0; + p->geoSystem.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->geoSystem.count = 2; + p->geoSystem.vals[0] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[0], "GD"); + p->geoSystem.vals[1] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[1], "WE"); + return (GF_Node *)p; +} + + +/* + GeoPositionInterpolator Node deletion +*/ + +static void GeoPositionInterpolator_Del(GF_Node *node) +{ + X_GeoPositionInterpolator *p = (X_GeoPositionInterpolator *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfvec3d_del(p->keyValue); + gf_node_unregister((GF_Node *) p->geoOrigin, node); + gf_sg_mfstring_del(p->geoSystem); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 GeoPositionInterpolator_get_field_count(GF_Node *node, u8 dummy) +{ + return 8; +} + +static GF_Err GeoPositionInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_GeoPositionInterpolator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_GeoPositionInterpolator *) node)->set_fraction; + return GF_OK; + case 1: + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_GeoPositionInterpolator *) node)->key; + return GF_OK; + case 2: + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3D; + info->far_ptr = & ((X_GeoPositionInterpolator *) node)->keyValue; + return GF_OK; + case 3: + info->name = "geoOrigin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeoOriginNode; + info->far_ptr = & ((X_GeoPositionInterpolator *)node)->geoOrigin; + return GF_OK; + case 4: + info->name = "geoSystem"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoPositionInterpolator *) node)->geoSystem; + return GF_OK; + case 5: + info->name = "geovalue_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3D; + info->far_ptr = & ((X_GeoPositionInterpolator *) node)->geovalue_changed; + return GF_OK; + case 6: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_GeoPositionInterpolator *) node)->value_changed; + return GF_OK; + case 7: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_GeoPositionInterpolator *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 GeoPositionInterpolator_get_field_index_by_name(char *name) +{ + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("key", name)) return 1; + if (!strcmp("keyValue", name)) return 2; + if (!strcmp("geoOrigin", name)) return 3; + if (!strcmp("geoSystem", name)) return 4; + if (!strcmp("geovalue_changed", name)) return 5; + if (!strcmp("value_changed", name)) return 6; + if (!strcmp("metadata", name)) return 7; + return -1; + } + + +static GF_Node *GeoPositionInterpolator_Create() +{ + X_GeoPositionInterpolator *p; + GF_SAFEALLOC(p, X_GeoPositionInterpolator); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_GeoPositionInterpolator); + + /*default field values*/ + p->geoSystem.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->geoSystem.count = 2; + p->geoSystem.vals[0] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[0], "GD"); + p->geoSystem.vals[1] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[1], "WE"); + return (GF_Node *)p; +} + + +/* + GeoTouchSensor Node deletion +*/ + +static void GeoTouchSensor_Del(GF_Node *node) +{ + X_GeoTouchSensor *p = (X_GeoTouchSensor *) node; + gf_node_unregister((GF_Node *) p->geoOrigin, node); + gf_sg_mfstring_del(p->geoSystem); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 GeoTouchSensor_get_field_count(GF_Node *node, u8 dummy) +{ + return 11; +} + +static GF_Err GeoTouchSensor_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "enabled"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoTouchSensor *) node)->enabled; + return GF_OK; + case 1: + info->name = "geoOrigin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeoOriginNode; + info->far_ptr = & ((X_GeoTouchSensor *)node)->geoOrigin; + return GF_OK; + case 2: + info->name = "geoSystem"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoTouchSensor *) node)->geoSystem; + return GF_OK; + case 3: + info->name = "hitNormal_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_GeoTouchSensor *) node)->hitNormal_changed; + return GF_OK; + case 4: + info->name = "hitPoint_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_GeoTouchSensor *) node)->hitPoint_changed; + return GF_OK; + case 5: + info->name = "hitTexCoord_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((X_GeoTouchSensor *) node)->hitTexCoord_changed; + return GF_OK; + case 6: + info->name = "hitGeoCoord_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3D; + info->far_ptr = & ((X_GeoTouchSensor *) node)->hitGeoCoord_changed; + return GF_OK; + case 7: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoTouchSensor *) node)->isActive; + return GF_OK; + case 8: + info->name = "isOver"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoTouchSensor *) node)->isOver; + return GF_OK; + case 9: + info->name = "touchTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_GeoTouchSensor *) node)->touchTime; + return GF_OK; + case 10: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_GeoTouchSensor *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 GeoTouchSensor_get_field_index_by_name(char *name) +{ + if (!strcmp("enabled", name)) return 0; + if (!strcmp("geoOrigin", name)) return 1; + if (!strcmp("geoSystem", name)) return 2; + if (!strcmp("hitNormal_changed", name)) return 3; + if (!strcmp("hitPoint_changed", name)) return 4; + if (!strcmp("hitTexCoord_changed", name)) return 5; + if (!strcmp("hitGeoCoord_changed", name)) return 6; + if (!strcmp("isActive", name)) return 7; + if (!strcmp("isOver", name)) return 8; + if (!strcmp("touchTime", name)) return 9; + if (!strcmp("metadata", name)) return 10; + return -1; + } + + +static GF_Node *GeoTouchSensor_Create() +{ + X_GeoTouchSensor *p; + GF_SAFEALLOC(p, X_GeoTouchSensor); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_GeoTouchSensor); + + /*default field values*/ + p->enabled = 1; + p->geoSystem.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->geoSystem.count = 2; + p->geoSystem.vals[0] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[0], "GD"); + p->geoSystem.vals[1] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[1], "WE"); + return (GF_Node *)p; +} + + +/* + GeoViewpoint Node deletion +*/ + +static void GeoViewpoint_Del(GF_Node *node) +{ + X_GeoViewpoint *p = (X_GeoViewpoint *) node; + gf_sg_sfstring_del(p->set_orientation); + gf_sg_sfstring_del(p->set_position); + gf_sg_sfstring_del(p->description); + gf_sg_mfstring_del(p->navType); + gf_node_unregister((GF_Node *) p->geoOrigin, node); + gf_sg_mfstring_del(p->geoSystem); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 GeoViewpoint_get_field_count(GF_Node *node, u8 dummy) +{ + return 16; +} + +static GF_Err GeoViewpoint_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_bind"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_GeoViewpoint *)node)->on_set_bind; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoViewpoint *) node)->set_bind; + return GF_OK; + case 1: + info->name = "set_orientation"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_GeoViewpoint *)node)->on_set_orientation; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_GeoViewpoint *) node)->set_orientation; + return GF_OK; + case 2: + info->name = "set_position"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_GeoViewpoint *)node)->on_set_position; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_GeoViewpoint *) node)->set_position; + return GF_OK; + case 3: + info->name = "description"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_GeoViewpoint *) node)->description; + return GF_OK; + case 4: + info->name = "fieldOfView"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_GeoViewpoint *) node)->fieldOfView; + return GF_OK; + case 5: + info->name = "headlight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoViewpoint *) node)->headlight; + return GF_OK; + case 6: + info->name = "jump"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoViewpoint *) node)->jump; + return GF_OK; + case 7: + info->name = "navType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoViewpoint *) node)->navType; + return GF_OK; + case 8: + info->name = "bindTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_GeoViewpoint *) node)->bindTime; + return GF_OK; + case 9: + info->name = "isBound"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_GeoViewpoint *) node)->isBound; + return GF_OK; + case 10: + info->name = "geoOrigin"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeoOriginNode; + info->far_ptr = & ((X_GeoViewpoint *)node)->geoOrigin; + return GF_OK; + case 11: + info->name = "geoSystem"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_GeoViewpoint *) node)->geoSystem; + return GF_OK; + case 12: + info->name = "orientation"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_GeoViewpoint *) node)->orientation; + return GF_OK; + case 13: + info->name = "position"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3D; + info->far_ptr = & ((X_GeoViewpoint *) node)->position; + return GF_OK; + case 14: + info->name = "speedFactor"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_GeoViewpoint *) node)->speedFactor; + return GF_OK; + case 15: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_GeoViewpoint *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 GeoViewpoint_get_field_index_by_name(char *name) +{ + if (!strcmp("set_bind", name)) return 0; + if (!strcmp("set_orientation", name)) return 1; + if (!strcmp("set_position", name)) return 2; + if (!strcmp("description", name)) return 3; + if (!strcmp("fieldOfView", name)) return 4; + if (!strcmp("headlight", name)) return 5; + if (!strcmp("jump", name)) return 6; + if (!strcmp("navType", name)) return 7; + if (!strcmp("bindTime", name)) return 8; + if (!strcmp("isBound", name)) return 9; + if (!strcmp("geoOrigin", name)) return 10; + if (!strcmp("geoSystem", name)) return 11; + if (!strcmp("orientation", name)) return 12; + if (!strcmp("position", name)) return 13; + if (!strcmp("speedFactor", name)) return 14; + if (!strcmp("metadata", name)) return 15; + return -1; + } + + +static GF_Node *GeoViewpoint_Create() +{ + X_GeoViewpoint *p; + GF_SAFEALLOC(p, X_GeoViewpoint); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_GeoViewpoint); + + /*default field values*/ + p->fieldOfView = FLT2FIX(0.785398); + p->headlight = 1; + p->jump = 1; + p->navType.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->navType.count = 2; + p->navType.vals[0] = (char*)gf_malloc(sizeof(char) * 8); + strcpy(p->navType.vals[0], "EXAMINE"); + p->navType.vals[1] = (char*)gf_malloc(sizeof(char) * 4); + strcpy(p->navType.vals[1], "ANY"); + p->geoSystem.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->geoSystem.count = 2; + p->geoSystem.vals[0] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[0], "GD"); + p->geoSystem.vals[1] = (char*)gf_malloc(sizeof(char) * 3); + strcpy(p->geoSystem.vals[1], "WE"); + p->orientation.x = FLT2FIX(0); + p->orientation.y = FLT2FIX(0); + p->orientation.z = FLT2FIX(1); + p->orientation.q = FLT2FIX(0); + p->position.x = (SFDouble) 0; + p->position.y = (SFDouble) 0; + p->position.z = (SFDouble) 100000; + p->speedFactor = FLT2FIX(1.0); + return (GF_Node *)p; +} + + +/* + Group Node deletion +*/ + +static void Group_Del(GF_Node *node) +{ + X_Group *p = (X_Group *) node; + gf_node_unregister((GF_Node *) p->metadata, node); + gf_sg_vrml_parent_destroy(node); + gf_node_free((GF_Node *)p); +} + + +static u32 Group_get_field_count(GF_Node *node, u8 dummy) +{ + return 4; +} + +static GF_Err Group_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_Group *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_Group *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_Group *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_Group *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_Group *)node)->children; + return GF_OK; + case 3: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_Group *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Group_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("metadata", name)) return 3; + return -1; + } + + +static GF_Node *Group_Create() +{ + X_Group *p; + GF_SAFEALLOC(p, X_Group); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_Group); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + HAnimDisplacer Node deletion +*/ + +static void HAnimDisplacer_Del(GF_Node *node) +{ + X_HAnimDisplacer *p = (X_HAnimDisplacer *) node; + gf_sg_mfint32_del(p->coordIndex); + gf_sg_mfvec3f_del(p->displacements); + gf_sg_sfstring_del(p->name); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 HAnimDisplacer_get_field_count(GF_Node *node, u8 dummy) +{ + return 5; +} + +static GF_Err HAnimDisplacer_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_HAnimDisplacer *) node)->coordIndex; + return GF_OK; + case 1: + info->name = "displacements"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((X_HAnimDisplacer *) node)->displacements; + return GF_OK; + case 2: + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_HAnimDisplacer *) node)->name; + return GF_OK; + case 3: + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_HAnimDisplacer *) node)->weight; + return GF_OK; + case 4: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_HAnimDisplacer *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 HAnimDisplacer_get_field_index_by_name(char *name) +{ + if (!strcmp("coordIndex", name)) return 0; + if (!strcmp("displacements", name)) return 1; + if (!strcmp("name", name)) return 2; + if (!strcmp("weight", name)) return 3; + if (!strcmp("metadata", name)) return 4; + return -1; + } + + +static GF_Node *HAnimDisplacer_Create() +{ + X_HAnimDisplacer *p; + GF_SAFEALLOC(p, X_HAnimDisplacer); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_HAnimDisplacer); + + /*default field values*/ + p->weight = FLT2FIX(0.0); + return (GF_Node *)p; +} + + +/* + HAnimHumanoid Node deletion +*/ + +static void HAnimHumanoid_Del(GF_Node *node) +{ + X_HAnimHumanoid *p = (X_HAnimHumanoid *) node; + gf_sg_mfstring_del(p->info); + gf_node_unregister_children(node, p->joints); + gf_sg_sfstring_del(p->name); + gf_node_unregister_children(node, p->segments); + gf_node_unregister_children(node, p->sites); + gf_node_unregister_children(node, p->skeleton); + gf_node_unregister_children(node, p->skin); + gf_node_unregister((GF_Node *) p->skinCoord, node); + gf_node_unregister((GF_Node *) p->skinNormal, node); + gf_sg_sfstring_del(p->version); + gf_node_unregister_children(node, p->viewpoints); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 HAnimHumanoid_get_field_count(GF_Node *node, u8 dummy) +{ + return 17; +} + +static GF_Err HAnimHumanoid_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimHumanoid *) node)->center; + return GF_OK; + case 1: + info->name = "info"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_HAnimHumanoid *) node)->info; + return GF_OK; + case 2: + info->name = "joints"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFHAnimNode; + info->far_ptr = & ((X_HAnimHumanoid *)node)->joints; + return GF_OK; + case 3: + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_HAnimHumanoid *) node)->name; + return GF_OK; + case 4: + info->name = "rotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_HAnimHumanoid *) node)->rotation; + return GF_OK; + case 5: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimHumanoid *) node)->scale; + return GF_OK; + case 6: + info->name = "scaleOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_HAnimHumanoid *) node)->scaleOrientation; + return GF_OK; + case 7: + info->name = "segments"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFHAnimNode; + info->far_ptr = & ((X_HAnimHumanoid *)node)->segments; + return GF_OK; + case 8: + info->name = "sites"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFHAnimNode; + info->far_ptr = & ((X_HAnimHumanoid *)node)->sites; + return GF_OK; + case 9: + info->name = "skeleton"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFHAnimNode; + info->far_ptr = & ((X_HAnimHumanoid *)node)->skeleton; + return GF_OK; + case 10: + info->name = "skin"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_HAnimHumanoid *)node)->skin; + return GF_OK; + case 11: + info->name = "skinCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_HAnimHumanoid *)node)->skinCoord; + return GF_OK; + case 12: + info->name = "skinNormal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((X_HAnimHumanoid *)node)->skinNormal; + return GF_OK; + case 13: + info->name = "translation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimHumanoid *) node)->translation; + return GF_OK; + case 14: + info->name = "version"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_HAnimHumanoid *) node)->version; + return GF_OK; + case 15: + info->name = "viewpoints"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFViewpointNode; + info->far_ptr = & ((X_HAnimHumanoid *)node)->viewpoints; + return GF_OK; + case 16: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_HAnimHumanoid *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 HAnimHumanoid_get_field_index_by_name(char *name) +{ + if (!strcmp("center", name)) return 0; + if (!strcmp("info", name)) return 1; + if (!strcmp("joints", name)) return 2; + if (!strcmp("name", name)) return 3; + if (!strcmp("rotation", name)) return 4; + if (!strcmp("scale", name)) return 5; + if (!strcmp("scaleOrientation", name)) return 6; + if (!strcmp("segments", name)) return 7; + if (!strcmp("sites", name)) return 8; + if (!strcmp("skeleton", name)) return 9; + if (!strcmp("skin", name)) return 10; + if (!strcmp("skinCoord", name)) return 11; + if (!strcmp("skinNormal", name)) return 12; + if (!strcmp("translation", name)) return 13; + if (!strcmp("version", name)) return 14; + if (!strcmp("viewpoints", name)) return 15; + if (!strcmp("metadata", name)) return 16; + return -1; + } + + +static GF_Node *HAnimHumanoid_Create() +{ + X_HAnimHumanoid *p; + GF_SAFEALLOC(p, X_HAnimHumanoid); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_HAnimHumanoid); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->rotation.x = FLT2FIX(0); + p->rotation.y = FLT2FIX(0); + p->rotation.z = FLT2FIX(1); + p->rotation.q = FLT2FIX(0); + p->scale.x = FLT2FIX(1); + p->scale.y = FLT2FIX(1); + p->scale.z = FLT2FIX(1); + p->scaleOrientation.x = FLT2FIX(0); + p->scaleOrientation.y = FLT2FIX(0); + p->scaleOrientation.z = FLT2FIX(1); + p->scaleOrientation.q = FLT2FIX(0); + p->translation.x = FLT2FIX(0); + p->translation.y = FLT2FIX(0); + p->translation.z = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + HAnimJoint Node deletion +*/ + +static void HAnimJoint_Del(GF_Node *node) +{ + X_HAnimJoint *p = (X_HAnimJoint *) node; + gf_node_unregister_children(node, p->displacers); + gf_sg_mffloat_del(p->llimit); + gf_sg_sfstring_del(p->name); + gf_sg_mfint32_del(p->skinCoordIndex); + gf_sg_mffloat_del(p->skinCoordWeight); + gf_sg_mffloat_del(p->stiffness); + gf_sg_mffloat_del(p->ulimit); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_sg_vrml_parent_destroy(node); + gf_node_free((GF_Node *)p); +} + + +static u32 HAnimJoint_get_field_count(GF_Node *node, u8 dummy) +{ + return 17; +} + +static GF_Err HAnimJoint_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_HAnimJoint *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFHAnimNode; + info->far_ptr = & ((X_HAnimJoint *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_HAnimJoint *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFHAnimNode; + info->far_ptr = & ((X_HAnimJoint *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFHAnimNode; + info->far_ptr = & ((X_HAnimJoint *)node)->children; + return GF_OK; + case 3: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimJoint *) node)->center; + return GF_OK; + case 4: + info->name = "displacers"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFHAnimDisplacerNode; + info->far_ptr = & ((X_HAnimJoint *)node)->displacers; + return GF_OK; + case 5: + info->name = "limitOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_HAnimJoint *) node)->limitOrientation; + return GF_OK; + case 6: + info->name = "llimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_HAnimJoint *) node)->llimit; + return GF_OK; + case 7: + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_HAnimJoint *) node)->name; + return GF_OK; + case 8: + info->name = "rotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_HAnimJoint *) node)->rotation; + return GF_OK; + case 9: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimJoint *) node)->scale; + return GF_OK; + case 10: + info->name = "scaleOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_HAnimJoint *) node)->scaleOrientation; + return GF_OK; + case 11: + info->name = "skinCoordIndex"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_HAnimJoint *) node)->skinCoordIndex; + return GF_OK; + case 12: + info->name = "skinCoordWeight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_HAnimJoint *) node)->skinCoordWeight; + return GF_OK; + case 13: + info->name = "stiffness"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_HAnimJoint *) node)->stiffness; + return GF_OK; + case 14: + info->name = "translation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimJoint *) node)->translation; + return GF_OK; + case 15: + info->name = "ulimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_HAnimJoint *) node)->ulimit; + return GF_OK; + case 16: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_HAnimJoint *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 HAnimJoint_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("center", name)) return 3; + if (!strcmp("displacers", name)) return 4; + if (!strcmp("limitOrientation", name)) return 5; + if (!strcmp("llimit", name)) return 6; + if (!strcmp("name", name)) return 7; + if (!strcmp("rotation", name)) return 8; + if (!strcmp("scale", name)) return 9; + if (!strcmp("scaleOrientation", name)) return 10; + if (!strcmp("skinCoordIndex", name)) return 11; + if (!strcmp("skinCoordWeight", name)) return 12; + if (!strcmp("stiffness", name)) return 13; + if (!strcmp("translation", name)) return 14; + if (!strcmp("ulimit", name)) return 15; + if (!strcmp("metadata", name)) return 16; + return -1; + } + + +static GF_Node *HAnimJoint_Create() +{ + X_HAnimJoint *p; + GF_SAFEALLOC(p, X_HAnimJoint); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_HAnimJoint); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->limitOrientation.x = FLT2FIX(0); + p->limitOrientation.y = FLT2FIX(0); + p->limitOrientation.z = FLT2FIX(1); + p->limitOrientation.q = FLT2FIX(0); + p->rotation.x = FLT2FIX(0); + p->rotation.y = FLT2FIX(0); + p->rotation.z = FLT2FIX(1); + p->rotation.q = FLT2FIX(0); + p->scale.x = FLT2FIX(1); + p->scale.y = FLT2FIX(1); + p->scale.z = FLT2FIX(1); + p->scaleOrientation.x = FLT2FIX(0); + p->scaleOrientation.y = FLT2FIX(0); + p->scaleOrientation.z = FLT2FIX(1); + p->scaleOrientation.q = FLT2FIX(0); + p->stiffness.vals = (SFFloat *)gf_malloc(sizeof(SFFloat)*3); + p->stiffness.count = 3; + p->stiffness.vals[0] = FLT2FIX(0); + p->stiffness.vals[1] = FLT2FIX(0); + p->stiffness.vals[2] = FLT2FIX(0); + p->translation.x = FLT2FIX(0); + p->translation.y = FLT2FIX(0); + p->translation.z = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + HAnimSegment Node deletion +*/ + +static void HAnimSegment_Del(GF_Node *node) +{ + X_HAnimSegment *p = (X_HAnimSegment *) node; + gf_node_unregister((GF_Node *) p->coord, node); + gf_node_unregister_children(node, p->displacers); + gf_sg_mffloat_del(p->momentsOfInertia); + gf_sg_sfstring_del(p->name); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_sg_vrml_parent_destroy(node); + gf_node_free((GF_Node *)p); +} + + +static u32 HAnimSegment_get_field_count(GF_Node *node, u8 dummy) +{ + return 10; +} + +static GF_Err HAnimSegment_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_HAnimSegment *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_HAnimSegment *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_HAnimSegment *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_HAnimSegment *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_HAnimSegment *)node)->children; + return GF_OK; + case 3: + info->name = "centerOfMass"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimSegment *) node)->centerOfMass; + return GF_OK; + case 4: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_HAnimSegment *)node)->coord; + return GF_OK; + case 5: + info->name = "displacers"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFHAnimDisplacerNode; + info->far_ptr = & ((X_HAnimSegment *)node)->displacers; + return GF_OK; + case 6: + info->name = "mass"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_HAnimSegment *) node)->mass; + return GF_OK; + case 7: + info->name = "momentsOfInertia"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_HAnimSegment *) node)->momentsOfInertia; + return GF_OK; + case 8: + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_HAnimSegment *) node)->name; + return GF_OK; + case 9: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_HAnimSegment *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 HAnimSegment_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("centerOfMass", name)) return 3; + if (!strcmp("coord", name)) return 4; + if (!strcmp("displacers", name)) return 5; + if (!strcmp("mass", name)) return 6; + if (!strcmp("momentsOfInertia", name)) return 7; + if (!strcmp("name", name)) return 8; + if (!strcmp("metadata", name)) return 9; + return -1; + } + + +static GF_Node *HAnimSegment_Create() +{ + X_HAnimSegment *p; + GF_SAFEALLOC(p, X_HAnimSegment); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_HAnimSegment); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->centerOfMass.x = FLT2FIX(0); + p->centerOfMass.y = FLT2FIX(0); + p->centerOfMass.z = FLT2FIX(0); + p->mass = FLT2FIX(0); + p->momentsOfInertia.vals = (SFFloat *)gf_malloc(sizeof(SFFloat)*9); + p->momentsOfInertia.count = 9; + p->momentsOfInertia.vals[0] = FLT2FIX(0); + p->momentsOfInertia.vals[1] = FLT2FIX(0); + p->momentsOfInertia.vals[2] = FLT2FIX(0); + p->momentsOfInertia.vals[3] = FLT2FIX(0); + p->momentsOfInertia.vals[4] = FLT2FIX(0); + p->momentsOfInertia.vals[5] = FLT2FIX(0); + p->momentsOfInertia.vals[6] = FLT2FIX(0); + p->momentsOfInertia.vals[7] = FLT2FIX(0); + p->momentsOfInertia.vals[8] = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + HAnimSite Node deletion +*/ + +static void HAnimSite_Del(GF_Node *node) +{ + X_HAnimSite *p = (X_HAnimSite *) node; + gf_sg_sfstring_del(p->name); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_sg_vrml_parent_destroy(node); + gf_node_free((GF_Node *)p); +} + + +static u32 HAnimSite_get_field_count(GF_Node *node, u8 dummy) +{ + return 10; +} + +static GF_Err HAnimSite_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "addChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_HAnimSite *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_HAnimSite *)node)->addChildren; + return GF_OK; + case 1: + info->name = "removeChildren"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_HAnimSite *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_HAnimSite *)node)->removeChildren; + return GF_OK; + case 2: + info->name = "children"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_HAnimSite *)node)->children; + return GF_OK; + case 3: + info->name = "center"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimSite *) node)->center; + return GF_OK; + case 4: + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_HAnimSite *) node)->name; + return GF_OK; + case 5: + info->name = "rotation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_HAnimSite *) node)->rotation; + return GF_OK; + case 6: + info->name = "scale"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimSite *) node)->scale; + return GF_OK; + case 7: + info->name = "scaleOrientation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_HAnimSite *) node)->scaleOrientation; + return GF_OK; + case 8: + info->name = "translation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_HAnimSite *) node)->translation; + return GF_OK; + case 9: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_HAnimSite *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 HAnimSite_get_field_index_by_name(char *name) +{ + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("center", name)) return 3; + if (!strcmp("name", name)) return 4; + if (!strcmp("rotation", name)) return 5; + if (!strcmp("scale", name)) return 6; + if (!strcmp("scaleOrientation", name)) return 7; + if (!strcmp("translation", name)) return 8; + if (!strcmp("metadata", name)) return 9; + return -1; + } + + +static GF_Node *HAnimSite_Create() +{ + X_HAnimSite *p; + GF_SAFEALLOC(p, X_HAnimSite); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_HAnimSite); + gf_sg_vrml_parent_setup((GF_Node *) p); + + /*default field values*/ + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); + p->rotation.x = FLT2FIX(0); + p->rotation.y = FLT2FIX(0); + p->rotation.z = FLT2FIX(1); + p->rotation.q = FLT2FIX(0); + p->scale.x = FLT2FIX(1); + p->scale.y = FLT2FIX(1); + p->scale.z = FLT2FIX(1); + p->scaleOrientation.x = FLT2FIX(0); + p->scaleOrientation.y = FLT2FIX(0); + p->scaleOrientation.z = FLT2FIX(1); + p->scaleOrientation.q = FLT2FIX(0); + p->translation.x = FLT2FIX(0); + p->translation.y = FLT2FIX(0); + p->translation.z = FLT2FIX(0); + return (GF_Node *)p; +} + + +/* + ImageTexture Node deletion +*/ + +static void ImageTexture_Del(GF_Node *node) +{ + X_ImageTexture *p = (X_ImageTexture *) node; + gf_sg_mfurl_del(p->url); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 ImageTexture_get_field_count(GF_Node *node, u8 dummy) +{ + return 4; +} + +static GF_Err ImageTexture_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((X_ImageTexture *) node)->url; + return GF_OK; + case 1: + info->name = "repeatS"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_ImageTexture *) node)->repeatS; + return GF_OK; + case 2: + info->name = "repeatT"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_ImageTexture *) node)->repeatT; + return GF_OK; + case 3: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_ImageTexture *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 ImageTexture_get_field_index_by_name(char *name) +{ + if (!strcmp("url", name)) return 0; + if (!strcmp("repeatS", name)) return 1; + if (!strcmp("repeatT", name)) return 2; + if (!strcmp("metadata", name)) return 3; + return -1; + } + + +static GF_Node *ImageTexture_Create() +{ + X_ImageTexture *p; + GF_SAFEALLOC(p, X_ImageTexture); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_ImageTexture); + + /*default field values*/ + p->repeatS = 1; + p->repeatT = 1; + return (GF_Node *)p; +} + + +/* + IndexedFaceSet Node deletion +*/ + +static void IndexedFaceSet_Del(GF_Node *node) +{ + X_IndexedFaceSet *p = (X_IndexedFaceSet *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_sg_mfint32_del(p->set_coordIndex); + gf_sg_mfint32_del(p->set_normalIndex); + gf_sg_mfint32_del(p->set_texCoordIndex); + gf_node_unregister((GF_Node *) p->color, node); + gf_node_unregister((GF_Node *) p->coord, node); + gf_node_unregister((GF_Node *) p->normal, node); + gf_node_unregister((GF_Node *) p->texCoord, node); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mfint32_del(p->coordIndex); + gf_sg_mfint32_del(p->normalIndex); + gf_sg_mfint32_del(p->texCoordIndex); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 IndexedFaceSet_get_field_count(GF_Node *node, u8 dummy) +{ + return 19; +} + +static GF_Err IndexedFaceSet_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IndexedFaceSet *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedFaceSet *) node)->set_colorIndex; + return GF_OK; + case 1: + info->name = "set_coordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IndexedFaceSet *)node)->on_set_coordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedFaceSet *) node)->set_coordIndex; + return GF_OK; + case 2: + info->name = "set_normalIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IndexedFaceSet *)node)->on_set_normalIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedFaceSet *) node)->set_normalIndex; + return GF_OK; + case 3: + info->name = "set_texCoordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IndexedFaceSet *)node)->on_set_texCoordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedFaceSet *) node)->set_texCoordIndex; + return GF_OK; + case 4: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((X_IndexedFaceSet *)node)->color; + return GF_OK; + case 5: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_IndexedFaceSet *)node)->coord; + return GF_OK; + case 6: + info->name = "normal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((X_IndexedFaceSet *)node)->normal; + return GF_OK; + case 7: + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((X_IndexedFaceSet *)node)->texCoord; + return GF_OK; + case 8: + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedFaceSet *) node)->ccw; + return GF_OK; + case 9: + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedFaceSet *) node)->colorIndex; + return GF_OK; + case 10: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedFaceSet *) node)->colorPerVertex; + return GF_OK; + case 11: + info->name = "convex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedFaceSet *) node)->convex; + return GF_OK; + case 12: + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedFaceSet *) node)->coordIndex; + return GF_OK; + case 13: + info->name = "creaseAngle"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_IndexedFaceSet *) node)->creaseAngle; + return GF_OK; + case 14: + info->name = "normalIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedFaceSet *) node)->normalIndex; + return GF_OK; + case 15: + info->name = "normalPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedFaceSet *) node)->normalPerVertex; + return GF_OK; + case 16: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedFaceSet *) node)->solid; + return GF_OK; + case 17: + info->name = "texCoordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedFaceSet *) node)->texCoordIndex; + return GF_OK; + case 18: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_IndexedFaceSet *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IndexedFaceSet_get_field_index_by_name(char *name) +{ + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("set_coordIndex", name)) return 1; + if (!strcmp("set_normalIndex", name)) return 2; + if (!strcmp("set_texCoordIndex", name)) return 3; + if (!strcmp("color", name)) return 4; + if (!strcmp("coord", name)) return 5; + if (!strcmp("normal", name)) return 6; + if (!strcmp("texCoord", name)) return 7; + if (!strcmp("ccw", name)) return 8; + if (!strcmp("colorIndex", name)) return 9; + if (!strcmp("colorPerVertex", name)) return 10; + if (!strcmp("convex", name)) return 11; + if (!strcmp("coordIndex", name)) return 12; + if (!strcmp("creaseAngle", name)) return 13; + if (!strcmp("normalIndex", name)) return 14; + if (!strcmp("normalPerVertex", name)) return 15; + if (!strcmp("solid", name)) return 16; + if (!strcmp("texCoordIndex", name)) return 17; + if (!strcmp("metadata", name)) return 18; + return -1; + } + + +static GF_Node *IndexedFaceSet_Create() +{ + X_IndexedFaceSet *p; + GF_SAFEALLOC(p, X_IndexedFaceSet); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_IndexedFaceSet); + + /*default field values*/ + p->ccw = 1; + p->colorPerVertex = 1; + p->convex = 1; + p->creaseAngle = FLT2FIX(0.0); + p->normalPerVertex = 1; + p->solid = 1; + return (GF_Node *)p; +} + + +/* + IndexedLineSet Node deletion +*/ + +static void IndexedLineSet_Del(GF_Node *node) +{ + X_IndexedLineSet *p = (X_IndexedLineSet *) node; + gf_sg_mfint32_del(p->set_colorIndex); + gf_sg_mfint32_del(p->set_coordIndex); + gf_node_unregister((GF_Node *) p->color, node); + gf_node_unregister((GF_Node *) p->coord, node); + gf_sg_mfint32_del(p->colorIndex); + gf_sg_mfint32_del(p->coordIndex); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 IndexedLineSet_get_field_count(GF_Node *node, u8 dummy) +{ + return 8; +} + +static GF_Err IndexedLineSet_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_colorIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IndexedLineSet *)node)->on_set_colorIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedLineSet *) node)->set_colorIndex; + return GF_OK; + case 1: + info->name = "set_coordIndex"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IndexedLineSet *)node)->on_set_coordIndex; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedLineSet *) node)->set_coordIndex; + return GF_OK; + case 2: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((X_IndexedLineSet *)node)->color; + return GF_OK; + case 3: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_IndexedLineSet *)node)->coord; + return GF_OK; + case 4: + info->name = "colorIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedLineSet *) node)->colorIndex; + return GF_OK; + case 5: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedLineSet *) node)->colorPerVertex; + return GF_OK; + case 6: + info->name = "coordIndex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedLineSet *) node)->coordIndex; + return GF_OK; + case 7: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_IndexedLineSet *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IndexedLineSet_get_field_index_by_name(char *name) +{ + if (!strcmp("set_colorIndex", name)) return 0; + if (!strcmp("set_coordIndex", name)) return 1; + if (!strcmp("color", name)) return 2; + if (!strcmp("coord", name)) return 3; + if (!strcmp("colorIndex", name)) return 4; + if (!strcmp("colorPerVertex", name)) return 5; + if (!strcmp("coordIndex", name)) return 6; + if (!strcmp("metadata", name)) return 7; + return -1; + } + + +static GF_Node *IndexedLineSet_Create() +{ + X_IndexedLineSet *p; + GF_SAFEALLOC(p, X_IndexedLineSet); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_IndexedLineSet); + + /*default field values*/ + p->colorPerVertex = 1; + return (GF_Node *)p; +} + + +/* + IndexedTriangleFanSet Node deletion +*/ + +static void IndexedTriangleFanSet_Del(GF_Node *node) +{ + X_IndexedTriangleFanSet *p = (X_IndexedTriangleFanSet *) node; + gf_sg_mfint32_del(p->set_index); + gf_node_unregister((GF_Node *) p->color, node); + gf_node_unregister((GF_Node *) p->coord, node); + gf_node_unregister((GF_Node *) p->normal, node); + gf_node_unregister((GF_Node *) p->texCoord, node); + gf_sg_mfint32_del(p->index); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 IndexedTriangleFanSet_get_field_count(GF_Node *node, u8 dummy) +{ + return 11; +} + +static GF_Err IndexedTriangleFanSet_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_index"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IndexedTriangleFanSet *)node)->on_set_index; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->set_index; + return GF_OK; + case 1: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->color; + return GF_OK; + case 2: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->coord; + return GF_OK; + case 3: + info->name = "normal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->normal; + return GF_OK; + case 4: + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->texCoord; + return GF_OK; + case 5: + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->ccw; + return GF_OK; + case 6: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->colorPerVertex; + return GF_OK; + case 7: + info->name = "normalPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->normalPerVertex; + return GF_OK; + case 8: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->solid; + return GF_OK; + case 9: + info->name = "index"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->index; + return GF_OK; + case 10: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IndexedTriangleFanSet_get_field_index_by_name(char *name) +{ + if (!strcmp("set_index", name)) return 0; + if (!strcmp("color", name)) return 1; + if (!strcmp("coord", name)) return 2; + if (!strcmp("normal", name)) return 3; + if (!strcmp("texCoord", name)) return 4; + if (!strcmp("ccw", name)) return 5; + if (!strcmp("colorPerVertex", name)) return 6; + if (!strcmp("normalPerVertex", name)) return 7; + if (!strcmp("solid", name)) return 8; + if (!strcmp("index", name)) return 9; + if (!strcmp("metadata", name)) return 10; + return -1; + } + + +static GF_Node *IndexedTriangleFanSet_Create() +{ + X_IndexedTriangleFanSet *p; + GF_SAFEALLOC(p, X_IndexedTriangleFanSet); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_IndexedTriangleFanSet); + + /*default field values*/ + p->ccw = 1; + p->colorPerVertex = 1; + p->normalPerVertex = 1; + p->solid = 1; + return (GF_Node *)p; +} + + +/* + IndexedTriangleSet Node deletion +*/ + +static void IndexedTriangleSet_Del(GF_Node *node) +{ + X_IndexedTriangleSet *p = (X_IndexedTriangleSet *) node; + gf_sg_mfint32_del(p->set_index); + gf_node_unregister((GF_Node *) p->color, node); + gf_node_unregister((GF_Node *) p->coord, node); + gf_node_unregister((GF_Node *) p->normal, node); + gf_node_unregister((GF_Node *) p->texCoord, node); + gf_sg_mfint32_del(p->index); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 IndexedTriangleSet_get_field_count(GF_Node *node, u8 dummy) +{ + return 11; +} + +static GF_Err IndexedTriangleSet_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_index"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IndexedTriangleSet *)node)->on_set_index; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedTriangleSet *) node)->set_index; + return GF_OK; + case 1: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((X_IndexedTriangleSet *)node)->color; + return GF_OK; + case 2: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_IndexedTriangleSet *)node)->coord; + return GF_OK; + case 3: + info->name = "normal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((X_IndexedTriangleSet *)node)->normal; + return GF_OK; + case 4: + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((X_IndexedTriangleSet *)node)->texCoord; + return GF_OK; + case 5: + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleSet *) node)->ccw; + return GF_OK; + case 6: + info->name = "colorPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleSet *) node)->colorPerVertex; + return GF_OK; + case 7: + info->name = "normalPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleSet *) node)->normalPerVertex; + return GF_OK; + case 8: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleSet *) node)->solid; + return GF_OK; + case 9: + info->name = "index"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedTriangleSet *) node)->index; + return GF_OK; + case 10: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_IndexedTriangleSet *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IndexedTriangleSet_get_field_index_by_name(char *name) +{ + if (!strcmp("set_index", name)) return 0; + if (!strcmp("color", name)) return 1; + if (!strcmp("coord", name)) return 2; + if (!strcmp("normal", name)) return 3; + if (!strcmp("texCoord", name)) return 4; + if (!strcmp("ccw", name)) return 5; + if (!strcmp("colorPerVertex", name)) return 6; + if (!strcmp("normalPerVertex", name)) return 7; + if (!strcmp("solid", name)) return 8; + if (!strcmp("index", name)) return 9; + if (!strcmp("metadata", name)) return 10; + return -1; + } + + +static GF_Node *IndexedTriangleSet_Create() +{ + X_IndexedTriangleSet *p; + GF_SAFEALLOC(p, X_IndexedTriangleSet); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_IndexedTriangleSet); + + /*default field values*/ + p->ccw = 1; + p->colorPerVertex = 1; + p->normalPerVertex = 1; + p->solid = 1; + return (GF_Node *)p; +} + + +/* + IndexedTriangleStripSet Node deletion +*/ + +static void IndexedTriangleStripSet_Del(GF_Node *node) +{ + X_IndexedTriangleStripSet *p = (X_IndexedTriangleStripSet *) node; + gf_sg_mfint32_del(p->set_index); + gf_node_unregister((GF_Node *) p->color, node); + gf_node_unregister((GF_Node *) p->coord, node); + gf_node_unregister((GF_Node *) p->normal, node); + gf_node_unregister((GF_Node *) p->texCoord, node); + gf_sg_mfint32_del(p->index); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 IndexedTriangleStripSet_get_field_count(GF_Node *node, u8 dummy) +{ + return 11; +} + +static GF_Err IndexedTriangleStripSet_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_index"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IndexedTriangleStripSet *)node)->on_set_index; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->set_index; + return GF_OK; + case 1: + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->color; + return GF_OK; + case 2: + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->coord; + return GF_OK; + case 3: + info->name = "creaseAngle"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->creaseAngle; + return GF_OK; + case 4: + info->name = "normal"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNormalNode; + info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->normal; + return GF_OK; + case 5: + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->texCoord; + return GF_OK; + case 6: + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->ccw; + return GF_OK; + case 7: + info->name = "normalPerVertex"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->normalPerVertex; + return GF_OK; + case 8: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->solid; + return GF_OK; + case 9: + info->name = "index"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->index; + return GF_OK; + case 10: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IndexedTriangleStripSet_get_field_index_by_name(char *name) +{ + if (!strcmp("set_index", name)) return 0; + if (!strcmp("color", name)) return 1; + if (!strcmp("coord", name)) return 2; + if (!strcmp("creaseAngle", name)) return 3; + if (!strcmp("normal", name)) return 4; + if (!strcmp("texCoord", name)) return 5; + if (!strcmp("ccw", name)) return 6; + if (!strcmp("normalPerVertex", name)) return 7; + if (!strcmp("solid", name)) return 8; + if (!strcmp("index", name)) return 9; + if (!strcmp("metadata", name)) return 10; + return -1; + } + + +static GF_Node *IndexedTriangleStripSet_Create() +{ + X_IndexedTriangleStripSet *p; + GF_SAFEALLOC(p, X_IndexedTriangleStripSet); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_IndexedTriangleStripSet); + + /*default field values*/ + p->creaseAngle = FLT2FIX(0); + p->ccw = 1; + p->normalPerVertex = 1; + p->solid = 1; + return (GF_Node *)p; +} + + +/* + Inline Node deletion +*/ + +static void Inline_Del(GF_Node *node) +{ + X_Inline *p = (X_Inline *) node; + gf_sg_mfurl_del(p->url); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 Inline_get_field_count(GF_Node *node, u8 dummy) +{ + return 3; +} + +static GF_Err Inline_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((X_Inline *) node)->url; + return GF_OK; + case 1: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_Inline *)node)->metadata; + return GF_OK; + case 2: + info->name = "load"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_Inline *) node)->load; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Inline_get_field_index_by_name(char *name) +{ + if (!strcmp("url", name)) return 0; + if (!strcmp("metadata", name)) return 1; + if (!strcmp("load", name)) return 2; + return -1; + } + + +static GF_Node *Inline_Create() +{ + X_Inline *p; + GF_SAFEALLOC(p, X_Inline); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_Inline); + + /*default field values*/ + p->load = 1; + return (GF_Node *)p; +} + + +/* + IntegerSequencer Node deletion +*/ + +static void IntegerSequencer_Del(GF_Node *node) +{ + X_IntegerSequencer *p = (X_IntegerSequencer *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfint32_del(p->keyValue); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 IntegerSequencer_get_field_count(GF_Node *node, u8 dummy) +{ + return 7; +} + +static GF_Err IntegerSequencer_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "next"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IntegerSequencer *)node)->on_next; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IntegerSequencer *) node)->next; + return GF_OK; + case 1: + info->name = "previous"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IntegerSequencer *)node)->on_previous; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IntegerSequencer *) node)->previous; + return GF_OK; + case 2: + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IntegerSequencer *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_IntegerSequencer *) node)->set_fraction; + return GF_OK; + case 3: + info->name = "key"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_IntegerSequencer *) node)->key; + return GF_OK; + case 4: + info->name = "keyValue"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_IntegerSequencer *) node)->keyValue; + return GF_OK; + case 5: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_IntegerSequencer *) node)->value_changed; + return GF_OK; + case 6: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_IntegerSequencer *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IntegerSequencer_get_field_index_by_name(char *name) +{ + if (!strcmp("next", name)) return 0; + if (!strcmp("previous", name)) return 1; + if (!strcmp("set_fraction", name)) return 2; + if (!strcmp("key", name)) return 3; + if (!strcmp("keyValue", name)) return 4; + if (!strcmp("value_changed", name)) return 5; + if (!strcmp("metadata", name)) return 6; + return -1; + } + + +static GF_Node *IntegerSequencer_Create() +{ + X_IntegerSequencer *p; + GF_SAFEALLOC(p, X_IntegerSequencer); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_IntegerSequencer); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + IntegerTrigger Node deletion +*/ + +static void IntegerTrigger_Del(GF_Node *node) +{ + X_IntegerTrigger *p = (X_IntegerTrigger *) node; + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 IntegerTrigger_get_field_count(GF_Node *node, u8 dummy) +{ + return 4; +} + +static GF_Err IntegerTrigger_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "set_boolean"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_IntegerTrigger *)node)->on_set_boolean; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_IntegerTrigger *) node)->set_boolean; + return GF_OK; + case 1: + info->name = "integerKey"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_IntegerTrigger *) node)->integerKey; + return GF_OK; + case 2: + info->name = "triggerValue"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_IntegerTrigger *) node)->triggerValue; + return GF_OK; + case 3: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_IntegerTrigger *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 IntegerTrigger_get_field_index_by_name(char *name) +{ + if (!strcmp("set_boolean", name)) return 0; + if (!strcmp("integerKey", name)) return 1; + if (!strcmp("triggerValue", name)) return 2; + if (!strcmp("metadata", name)) return 3; + return -1; + } + + +static GF_Node *IntegerTrigger_Create() +{ + X_IntegerTrigger *p; + GF_SAFEALLOC(p, X_IntegerTrigger); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_IntegerTrigger); + + /*default field values*/ + p->integerKey = -1; + return (GF_Node *)p; } /* - Fog Node deletion + KeySensor Node deletion */ -static void Fog_Del(GF_Node *node) +static void KeySensor_Del(GF_Node *node) { - X_Fog *p = (X_Fog *) node; - gf_sg_sfstring_del(p->fogType); + X_KeySensor *p = (X_KeySensor *) node; + gf_sg_sfstring_del(p->keyPress); + gf_sg_sfstring_del(p->keyRelease); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 Fog_get_field_count(GF_Node *node, u8 dummy) +static u32 KeySensor_get_field_count(GF_Node *node, u8 dummy) { - return 7; + return 10; } -static GF_Err Fog_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err KeySensor_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "color"; + info->name = "enabled"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((X_Fog *) node)->color; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_KeySensor *) node)->enabled; return GF_OK; case 1: - info->name = "fogType"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_Fog *) node)->fogType; + info->name = "actionKeyPress"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_KeySensor *) node)->actionKeyPress; return GF_OK; case 2: - info->name = "visibilityRange"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_Fog *) node)->visibilityRange; + info->name = "actionKeyRelease"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_KeySensor *) node)->actionKeyRelease; return GF_OK; case 3: - info->name = "set_bind"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_Fog *)node)->on_set_bind; + info->name = "altKey"; + info->eventType = GF_SG_EVENT_OUT; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_Fog *) node)->set_bind; + info->far_ptr = & ((X_KeySensor *) node)->altKey; return GF_OK; case 4: - info->name = "isBound"; + info->name = "controlKey"; info->eventType = GF_SG_EVENT_OUT; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_Fog *) node)->isBound; + info->far_ptr = & ((X_KeySensor *) node)->controlKey; return GF_OK; case 5: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_KeySensor *) node)->isActive; + return GF_OK; + case 6: + info->name = "keyPress"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_KeySensor *) node)->keyPress; + return GF_OK; + case 7: + info->name = "keyRelease"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_KeySensor *) node)->keyRelease; + return GF_OK; + case 8: + info->name = "shiftKey"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_KeySensor *) node)->shiftKey; + return GF_OK; + case 9: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_Fog *)node)->metadata; - return GF_OK; - case 6: - info->name = "bindTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((X_Fog *) node)->bindTime; + info->far_ptr = & ((X_KeySensor *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -3019,121 +7065,79 @@ static GF_Err Fog_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Fog_get_field_index_by_name(char *name) +static s32 KeySensor_get_field_index_by_name(char *name) { - if (!strcmp("color", name)) return 0; - if (!strcmp("fogType", name)) return 1; - if (!strcmp("visibilityRange", name)) return 2; - if (!strcmp("set_bind", name)) return 3; - if (!strcmp("isBound", name)) return 4; - if (!strcmp("metadata", name)) return 5; - if (!strcmp("bindTime", name)) return 6; + if (!strcmp("enabled", name)) return 0; + if (!strcmp("actionKeyPress", name)) return 1; + if (!strcmp("actionKeyRelease", name)) return 2; + if (!strcmp("altKey", name)) return 3; + if (!strcmp("controlKey", name)) return 4; + if (!strcmp("isActive", name)) return 5; + if (!strcmp("keyPress", name)) return 6; + if (!strcmp("keyRelease", name)) return 7; + if (!strcmp("shiftKey", name)) return 8; + if (!strcmp("metadata", name)) return 9; return -1; } -static GF_Node *Fog_Create() +static GF_Node *KeySensor_Create() { - X_Fog *p; - GF_SAFEALLOC(p, X_Fog); + X_KeySensor *p; + GF_SAFEALLOC(p, X_KeySensor); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_Fog); + gf_node_setup((GF_Node *)p, TAG_X3D_KeySensor); /*default field values*/ - p->color.red = FLT2FIX(1); - p->color.green = FLT2FIX(1); - p->color.blue = FLT2FIX(1); - p->fogType.buffer = (char*) malloc(sizeof(char) * 7); - strcpy(p->fogType.buffer, "LINEAR"); - p->visibilityRange = FLT2FIX(0); + p->enabled = 1; return (GF_Node *)p; } /* - FontStyle Node deletion + LineProperties Node deletion */ -static void FontStyle_Del(GF_Node *node) +static void LineProperties_Del(GF_Node *node) { - X_FontStyle *p = (X_FontStyle *) node; - gf_sg_mfstring_del(p->family); - gf_sg_mfstring_del(p->justify); - gf_sg_sfstring_del(p->language); - gf_sg_sfstring_del(p->style); + X_LineProperties *p = (X_LineProperties *) node; gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 FontStyle_get_field_count(GF_Node *node, u8 dummy) +static u32 LineProperties_get_field_count(GF_Node *node, u8 dummy) { - return 10; + return 4; } -static GF_Err FontStyle_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err LineProperties_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "family"; + info->name = "applied"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((X_FontStyle *) node)->family; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_LineProperties *) node)->applied; return GF_OK; case 1: - info->name = "horizontal"; + info->name = "linetype"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_FontStyle *) node)->horizontal; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_LineProperties *) node)->linetype; return GF_OK; case 2: - info->name = "justify"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((X_FontStyle *) node)->justify; - return GF_OK; - case 3: - info->name = "language"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_FontStyle *) node)->language; - return GF_OK; - case 4: - info->name = "leftToRight"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_FontStyle *) node)->leftToRight; - return GF_OK; - case 5: - info->name = "size"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_FontStyle *) node)->size; - return GF_OK; - case 6: - info->name = "spacing"; + info->name = "linewidthScaleFactor"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_FontStyle *) node)->spacing; - return GF_OK; - case 7: - info->name = "style"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_FontStyle *) node)->style; - return GF_OK; - case 8: - info->name = "topToBottom"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_FontStyle *) node)->topToBottom; + info->far_ptr = & ((X_LineProperties *) node)->linewidthScaleFactor; return GF_OK; - case 9: + case 3: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_FontStyle *)node)->metadata; + info->far_ptr = & ((X_LineProperties *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -3141,99 +7145,80 @@ static GF_Err FontStyle_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 FontStyle_get_field_index_by_name(char *name) +static s32 LineProperties_get_field_index_by_name(char *name) { - if (!strcmp("family", name)) return 0; - if (!strcmp("horizontal", name)) return 1; - if (!strcmp("justify", name)) return 2; - if (!strcmp("language", name)) return 3; - if (!strcmp("leftToRight", name)) return 4; - if (!strcmp("size", name)) return 5; - if (!strcmp("spacing", name)) return 6; - if (!strcmp("style", name)) return 7; - if (!strcmp("topToBottom", name)) return 8; - if (!strcmp("metadata", name)) return 9; + if (!strcmp("applied", name)) return 0; + if (!strcmp("linetype", name)) return 1; + if (!strcmp("linewidthScaleFactor", name)) return 2; + if (!strcmp("metadata", name)) return 3; return -1; } -static GF_Node *FontStyle_Create() +static GF_Node *LineProperties_Create() { - X_FontStyle *p; - GF_SAFEALLOC(p, X_FontStyle); + X_LineProperties *p; + GF_SAFEALLOC(p, X_LineProperties); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_FontStyle); + gf_node_setup((GF_Node *)p, TAG_X3D_LineProperties); /*default field values*/ - p->family.vals = (char**)malloc(sizeof(SFString)*1); - p->family.count = 1; - p->family.vals[0] = (char*)malloc(sizeof(char) * 6); - strcpy(p->family.vals[0], "SERIF"); - p->horizontal = 1; - p->justify.vals = (char**)malloc(sizeof(SFString)*1); - p->justify.count = 1; - p->justify.vals[0] = (char*)malloc(sizeof(char) * 6); - strcpy(p->justify.vals[0], "BEGIN"); - p->leftToRight = 1; - p->size = FLT2FIX(1.0); - p->spacing = FLT2FIX(1.0); - p->style.buffer = (char*) malloc(sizeof(char) * 6); - strcpy(p->style.buffer, "PLAIN"); - p->topToBottom = 1; + p->applied = 1; + p->linetype = 1; + p->linewidthScaleFactor = FLT2FIX(0); return (GF_Node *)p; } /* - Group Node deletion + LineSet Node deletion */ -static void Group_Del(GF_Node *node) +static void LineSet_Del(GF_Node *node) { - X_Group *p = (X_Group *) node; + X_LineSet *p = (X_LineSet *) node; + gf_node_unregister((GF_Node *) p->color, node); + gf_node_unregister((GF_Node *) p->coord, node); + gf_sg_mfint32_del(p->vertexCount); gf_node_unregister((GF_Node *) p->metadata, node); - gf_sg_vrml_parent_destroy(node); gf_node_free((GF_Node *)p); } -static u32 Group_get_field_count(GF_Node *node, u8 dummy) +static u32 LineSet_get_field_count(GF_Node *node, u8 dummy) { return 4; } -static GF_Err Group_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err LineSet_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_Group *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((X_Group *)node)->addChildren; + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFColorNode; + info->far_ptr = & ((X_LineSet *)node)->color; return GF_OK; case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_Group *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((X_Group *)node)->removeChildren; + info->name = "coord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_LineSet *)node)->coord; return GF_OK; case 2: - info->name = "children"; + info->name = "vertexCount"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((X_Group *)node)->children; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_LineSet *) node)->vertexCount; return GF_OK; case 3: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_Group *)node)->metadata; + info->far_ptr = & ((X_LineSet *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -3241,23 +7226,22 @@ static GF_Err Group_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Group_get_field_index_by_name(char *name) +static s32 LineSet_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; + if (!strcmp("color", name)) return 0; + if (!strcmp("coord", name)) return 1; + if (!strcmp("vertexCount", name)) return 2; if (!strcmp("metadata", name)) return 3; return -1; } -static GF_Node *Group_Create() +static GF_Node *LineSet_Create() { - X_Group *p; - GF_SAFEALLOC(p, X_Group); + X_LineSet *p; + GF_SAFEALLOC(p, X_LineSet); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_Group); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_X3D_LineSet); /*default field values*/ return (GF_Node *)p; @@ -3265,50 +7249,75 @@ static GF_Node *Group_Create() /* - ImageTexture Node deletion + LoadSensor Node deletion */ -static void ImageTexture_Del(GF_Node *node) +static void LoadSensor_Del(GF_Node *node) { - X_ImageTexture *p = (X_ImageTexture *) node; - gf_sg_mfurl_del(p->url); + X_LoadSensor *p = (X_LoadSensor *) node; + gf_node_unregister_children(node, p->watchList); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 ImageTexture_get_field_count(GF_Node *node, u8 dummy) +static u32 LoadSensor_get_field_count(GF_Node *node, u8 dummy) { - return 4; + return 8; } -static GF_Err ImageTexture_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err LoadSensor_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "url"; + info->name = "enabled"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((X_ImageTexture *) node)->url; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_LoadSensor *) node)->enabled; return GF_OK; case 1: - info->name = "repeatS"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_ImageTexture *) node)->repeatS; + info->name = "timeOut"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_LoadSensor *) node)->timeOut; return GF_OK; case 2: - info->name = "repeatT"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_ImageTexture *) node)->repeatT; + info->name = "watchList"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFStreamingNode; + info->far_ptr = & ((X_LoadSensor *)node)->watchList; return GF_OK; case 3: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_LoadSensor *) node)->isActive; + return GF_OK; + case 4: + info->name = "isLoaded"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_LoadSensor *) node)->isLoaded; + return GF_OK; + case 5: + info->name = "loadTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_LoadSensor *) node)->loadTime; + return GF_OK; + case 6: + info->name = "progress"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_LoadSensor *) node)->progress; + return GF_OK; + case 7: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_ImageTexture *)node)->metadata; + info->far_ptr = & ((X_LoadSensor *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -3316,184 +7325,97 @@ static GF_Err ImageTexture_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 ImageTexture_get_field_index_by_name(char *name) +static s32 LoadSensor_get_field_index_by_name(char *name) { - if (!strcmp("url", name)) return 0; - if (!strcmp("repeatS", name)) return 1; - if (!strcmp("repeatT", name)) return 2; - if (!strcmp("metadata", name)) return 3; + if (!strcmp("enabled", name)) return 0; + if (!strcmp("timeOut", name)) return 1; + if (!strcmp("watchList", name)) return 2; + if (!strcmp("isActive", name)) return 3; + if (!strcmp("isLoaded", name)) return 4; + if (!strcmp("loadTime", name)) return 5; + if (!strcmp("progress", name)) return 6; + if (!strcmp("metadata", name)) return 7; return -1; } -static GF_Node *ImageTexture_Create() +static GF_Node *LoadSensor_Create() { - X_ImageTexture *p; - GF_SAFEALLOC(p, X_ImageTexture); + X_LoadSensor *p; + GF_SAFEALLOC(p, X_LoadSensor); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_ImageTexture); + gf_node_setup((GF_Node *)p, TAG_X3D_LoadSensor); /*default field values*/ - p->repeatS = 1; - p->repeatT = 1; + p->enabled = 1; + p->timeOut = 0; return (GF_Node *)p; } /* - IndexedFaceSet Node deletion + LOD Node deletion */ -static void IndexedFaceSet_Del(GF_Node *node) +static void LOD_Del(GF_Node *node) { - X_IndexedFaceSet *p = (X_IndexedFaceSet *) node; - gf_sg_mfint32_del(p->set_colorIndex); - gf_sg_mfint32_del(p->set_coordIndex); - gf_sg_mfint32_del(p->set_normalIndex); - gf_sg_mfint32_del(p->set_texCoordIndex); - gf_node_unregister((GF_Node *) p->color, node); - gf_node_unregister((GF_Node *) p->coord, node); - gf_node_unregister((GF_Node *) p->normal, node); - gf_node_unregister((GF_Node *) p->texCoord, node); - gf_sg_mfint32_del(p->colorIndex); - gf_sg_mfint32_del(p->coordIndex); - gf_sg_mfint32_del(p->normalIndex); - gf_sg_mfint32_del(p->texCoordIndex); + X_LOD *p = (X_LOD *) node; + gf_sg_mffloat_del(p->range); gf_node_unregister((GF_Node *) p->metadata, node); + gf_sg_vrml_parent_destroy(node); gf_node_free((GF_Node *)p); } -static u32 IndexedFaceSet_get_field_count(GF_Node *node, u8 dummy) +static u32 LOD_get_field_count(GF_Node *node, u8 dummy) { - return 19; + return 6; } -static GF_Err IndexedFaceSet_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err LOD_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_colorIndex"; + info->name = "addChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IndexedFaceSet *)node)->on_set_colorIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedFaceSet *) node)->set_colorIndex; + info->on_event_in = ((X_LOD *)node)->on_addChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_LOD *)node)->addChildren; return GF_OK; case 1: - info->name = "set_coordIndex"; + info->name = "removeChildren"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IndexedFaceSet *)node)->on_set_coordIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedFaceSet *) node)->set_coordIndex; + info->on_event_in = ((X_LOD *)node)->on_removeChildren; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_LOD *)node)->removeChildren; return GF_OK; case 2: - info->name = "set_normalIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IndexedFaceSet *)node)->on_set_normalIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedFaceSet *) node)->set_normalIndex; - return GF_OK; - case 3: - info->name = "set_texCoordIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IndexedFaceSet *)node)->on_set_texCoordIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedFaceSet *) node)->set_texCoordIndex; - return GF_OK; - case 4: - info->name = "color"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((X_IndexedFaceSet *)node)->color; - return GF_OK; - case 5: - info->name = "coord"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinateNode; - info->far_ptr = & ((X_IndexedFaceSet *)node)->coord; - return GF_OK; - case 6: - info->name = "normal"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFNormalNode; - info->far_ptr = & ((X_IndexedFaceSet *)node)->normal; - return GF_OK; - case 7: - info->name = "texCoord"; + info->name = "children"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureCoordinateNode; - info->far_ptr = & ((X_IndexedFaceSet *)node)->texCoord; - return GF_OK; - case 8: - info->name = "ccw"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedFaceSet *) node)->ccw; - return GF_OK; - case 9: - info->name = "colorIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedFaceSet *) node)->colorIndex; - return GF_OK; - case 10: - info->name = "colorPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedFaceSet *) node)->colorPerVertex; - return GF_OK; - case 11: - info->name = "convex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedFaceSet *) node)->convex; - return GF_OK; - case 12: - info->name = "coordIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedFaceSet *) node)->coordIndex; - return GF_OK; - case 13: - info->name = "creaseAngle"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_IndexedFaceSet *) node)->creaseAngle; - return GF_OK; - case 14: - info->name = "normalIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedFaceSet *) node)->normalIndex; - return GF_OK; - case 15: - info->name = "normalPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedFaceSet *) node)->normalPerVertex; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SF3DNode; + info->far_ptr = & ((X_LOD *)node)->children; return GF_OK; - case 16: - info->name = "solid"; + case 3: + info->name = "center"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedFaceSet *) node)->solid; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_LOD *) node)->center; return GF_OK; - case 17: - info->name = "texCoordIndex"; + case 4: + info->name = "range"; info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedFaceSet *) node)->texCoordIndex; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_LOD *) node)->range; return GF_OK; - case 18: + case 5: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_IndexedFaceSet *)node)->metadata; + info->far_ptr = & ((X_LOD *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -3501,127 +7423,96 @@ static GF_Err IndexedFaceSet_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 IndexedFaceSet_get_field_index_by_name(char *name) +static s32 LOD_get_field_index_by_name(char *name) { - if (!strcmp("set_colorIndex", name)) return 0; - if (!strcmp("set_coordIndex", name)) return 1; - if (!strcmp("set_normalIndex", name)) return 2; - if (!strcmp("set_texCoordIndex", name)) return 3; - if (!strcmp("color", name)) return 4; - if (!strcmp("coord", name)) return 5; - if (!strcmp("normal", name)) return 6; - if (!strcmp("texCoord", name)) return 7; - if (!strcmp("ccw", name)) return 8; - if (!strcmp("colorIndex", name)) return 9; - if (!strcmp("colorPerVertex", name)) return 10; - if (!strcmp("convex", name)) return 11; - if (!strcmp("coordIndex", name)) return 12; - if (!strcmp("creaseAngle", name)) return 13; - if (!strcmp("normalIndex", name)) return 14; - if (!strcmp("normalPerVertex", name)) return 15; - if (!strcmp("solid", name)) return 16; - if (!strcmp("texCoordIndex", name)) return 17; - if (!strcmp("metadata", name)) return 18; + if (!strcmp("addChildren", name)) return 0; + if (!strcmp("removeChildren", name)) return 1; + if (!strcmp("children", name)) return 2; + if (!strcmp("center", name)) return 3; + if (!strcmp("range", name)) return 4; + if (!strcmp("metadata", name)) return 5; return -1; } -static GF_Node *IndexedFaceSet_Create() +static GF_Node *LOD_Create() { - X_IndexedFaceSet *p; - GF_SAFEALLOC(p, X_IndexedFaceSet); + X_LOD *p; + GF_SAFEALLOC(p, X_LOD); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_IndexedFaceSet); + gf_node_setup((GF_Node *)p, TAG_X3D_LOD); + gf_sg_vrml_parent_setup((GF_Node *) p); /*default field values*/ - p->ccw = 1; - p->colorPerVertex = 1; - p->convex = 1; - p->creaseAngle = FLT2FIX(0.0); - p->normalPerVertex = 1; - p->solid = 1; + p->center.x = FLT2FIX(0); + p->center.y = FLT2FIX(0); + p->center.z = FLT2FIX(0); return (GF_Node *)p; } /* - IndexedLineSet Node deletion + Material Node deletion */ -static void IndexedLineSet_Del(GF_Node *node) +static void Material_Del(GF_Node *node) { - X_IndexedLineSet *p = (X_IndexedLineSet *) node; - gf_sg_mfint32_del(p->set_colorIndex); - gf_sg_mfint32_del(p->set_coordIndex); - gf_node_unregister((GF_Node *) p->color, node); - gf_node_unregister((GF_Node *) p->coord, node); - gf_sg_mfint32_del(p->colorIndex); - gf_sg_mfint32_del(p->coordIndex); + X_Material *p = (X_Material *) node; gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 IndexedLineSet_get_field_count(GF_Node *node, u8 dummy) +static u32 Material_get_field_count(GF_Node *node, u8 dummy) { - return 8; + return 7; } -static GF_Err IndexedLineSet_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Material_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_colorIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IndexedLineSet *)node)->on_set_colorIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedLineSet *) node)->set_colorIndex; + info->name = "ambientIntensity"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_Material *) node)->ambientIntensity; return GF_OK; case 1: - info->name = "set_coordIndex"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IndexedLineSet *)node)->on_set_coordIndex; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedLineSet *) node)->set_coordIndex; + info->name = "diffuseColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((X_Material *) node)->diffuseColor; return GF_OK; case 2: - info->name = "color"; + info->name = "emissiveColor"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((X_IndexedLineSet *)node)->color; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((X_Material *) node)->emissiveColor; return GF_OK; case 3: - info->name = "coord"; + info->name = "shininess"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinateNode; - info->far_ptr = & ((X_IndexedLineSet *)node)->coord; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_Material *) node)->shininess; return GF_OK; case 4: - info->name = "colorIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedLineSet *) node)->colorIndex; + info->name = "specularColor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((X_Material *) node)->specularColor; return GF_OK; case 5: - info->name = "colorPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedLineSet *) node)->colorPerVertex; + info->name = "transparency"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_Material *) node)->transparency; return GF_OK; case 6: - info->name = "coordIndex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedLineSet *) node)->coordIndex; - return GF_OK; - case 7: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_IndexedLineSet *)node)->metadata; + info->far_ptr = & ((X_Material *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -3629,130 +7520,90 @@ static GF_Err IndexedLineSet_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 IndexedLineSet_get_field_index_by_name(char *name) +static s32 Material_get_field_index_by_name(char *name) { - if (!strcmp("set_colorIndex", name)) return 0; - if (!strcmp("set_coordIndex", name)) return 1; - if (!strcmp("color", name)) return 2; - if (!strcmp("coord", name)) return 3; - if (!strcmp("colorIndex", name)) return 4; - if (!strcmp("colorPerVertex", name)) return 5; - if (!strcmp("coordIndex", name)) return 6; - if (!strcmp("metadata", name)) return 7; + if (!strcmp("ambientIntensity", name)) return 0; + if (!strcmp("diffuseColor", name)) return 1; + if (!strcmp("emissiveColor", name)) return 2; + if (!strcmp("shininess", name)) return 3; + if (!strcmp("specularColor", name)) return 4; + if (!strcmp("transparency", name)) return 5; + if (!strcmp("metadata", name)) return 6; return -1; } -static GF_Node *IndexedLineSet_Create() +static GF_Node *Material_Create() { - X_IndexedLineSet *p; - GF_SAFEALLOC(p, X_IndexedLineSet); + X_Material *p; + GF_SAFEALLOC(p, X_Material); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_IndexedLineSet); + gf_node_setup((GF_Node *)p, TAG_X3D_Material); /*default field values*/ - p->colorPerVertex = 1; + p->ambientIntensity = FLT2FIX(0.2); + p->diffuseColor.red = FLT2FIX(0.8); + p->diffuseColor.green = FLT2FIX(0.8); + p->diffuseColor.blue = FLT2FIX(0.8); + p->emissiveColor.red = FLT2FIX(0); + p->emissiveColor.green = FLT2FIX(0); + p->emissiveColor.blue = FLT2FIX(0); + p->shininess = FLT2FIX(0.2); + p->specularColor.red = FLT2FIX(0); + p->specularColor.green = FLT2FIX(0); + p->specularColor.blue = FLT2FIX(0); + p->transparency = FLT2FIX(0); return (GF_Node *)p; } /* - IndexedTriangleFanSet Node deletion + MetadataDouble Node deletion */ -static void IndexedTriangleFanSet_Del(GF_Node *node) +static void MetadataDouble_Del(GF_Node *node) { - X_IndexedTriangleFanSet *p = (X_IndexedTriangleFanSet *) node; - gf_sg_mfint32_del(p->set_index); - gf_node_unregister((GF_Node *) p->color, node); - gf_node_unregister((GF_Node *) p->coord, node); - gf_node_unregister((GF_Node *) p->normal, node); - gf_node_unregister((GF_Node *) p->texCoord, node); - gf_sg_mfint32_del(p->index); + X_MetadataDouble *p = (X_MetadataDouble *) node; + gf_sg_sfstring_del(p->name); + gf_sg_sfstring_del(p->reference); + gf_sg_mfdouble_del(p->value); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 IndexedTriangleFanSet_get_field_count(GF_Node *node, u8 dummy) +static u32 MetadataDouble_get_field_count(GF_Node *node, u8 dummy) { - return 11; + return 4; } -static GF_Err IndexedTriangleFanSet_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MetadataDouble_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_index"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IndexedTriangleFanSet *)node)->on_set_index; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->set_index; + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataDouble *) node)->name; return GF_OK; case 1: - info->name = "color"; + info->name = "reference"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->color; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataDouble *) node)->reference; return GF_OK; case 2: - info->name = "coord"; + info->name = "value"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinateNode; - info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->coord; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_MetadataDouble *) node)->value; return GF_OK; case 3: - info->name = "normal"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFNormalNode; - info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->normal; - return GF_OK; - case 4: - info->name = "texCoord"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureCoordinateNode; - info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->texCoord; - return GF_OK; - case 5: - info->name = "ccw"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->ccw; - return GF_OK; - case 6: - info->name = "colorPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->colorPerVertex; - return GF_OK; - case 7: - info->name = "normalPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->normalPerVertex; - return GF_OK; - case 8: - info->name = "solid"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->solid; - return GF_OK; - case 9: - info->name = "index"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedTriangleFanSet *) node)->index; - return GF_OK; - case 10: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_IndexedTriangleFanSet *)node)->metadata; + info->far_ptr = & ((X_MetadataDouble *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -3760,136 +7611,75 @@ static GF_Err IndexedTriangleFanSet_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 IndexedTriangleFanSet_get_field_index_by_name(char *name) +static s32 MetadataDouble_get_field_index_by_name(char *name) { - if (!strcmp("set_index", name)) return 0; - if (!strcmp("color", name)) return 1; - if (!strcmp("coord", name)) return 2; - if (!strcmp("normal", name)) return 3; - if (!strcmp("texCoord", name)) return 4; - if (!strcmp("ccw", name)) return 5; - if (!strcmp("colorPerVertex", name)) return 6; - if (!strcmp("normalPerVertex", name)) return 7; - if (!strcmp("solid", name)) return 8; - if (!strcmp("index", name)) return 9; - if (!strcmp("metadata", name)) return 10; + if (!strcmp("name", name)) return 0; + if (!strcmp("reference", name)) return 1; + if (!strcmp("value", name)) return 2; + if (!strcmp("metadata", name)) return 3; return -1; } -static GF_Node *IndexedTriangleFanSet_Create() +static GF_Node *MetadataDouble_Create() { - X_IndexedTriangleFanSet *p; - GF_SAFEALLOC(p, X_IndexedTriangleFanSet); + X_MetadataDouble *p; + GF_SAFEALLOC(p, X_MetadataDouble); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_IndexedTriangleFanSet); + gf_node_setup((GF_Node *)p, TAG_X3D_MetadataDouble); /*default field values*/ - p->ccw = 1; - p->colorPerVertex = 1; - p->normalPerVertex = 1; - p->solid = 1; return (GF_Node *)p; } /* - IndexedTriangleSet Node deletion + MetadataFloat Node deletion */ -static void IndexedTriangleSet_Del(GF_Node *node) +static void MetadataFloat_Del(GF_Node *node) { - X_IndexedTriangleSet *p = (X_IndexedTriangleSet *) node; - gf_sg_mfint32_del(p->set_index); - gf_node_unregister((GF_Node *) p->color, node); - gf_node_unregister((GF_Node *) p->coord, node); - gf_node_unregister((GF_Node *) p->normal, node); - gf_node_unregister((GF_Node *) p->texCoord, node); - gf_sg_mfint32_del(p->index); + X_MetadataFloat *p = (X_MetadataFloat *) node; + gf_sg_sfstring_del(p->name); + gf_sg_sfstring_del(p->reference); + gf_sg_mffloat_del(p->value); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 IndexedTriangleSet_get_field_count(GF_Node *node, u8 dummy) +static u32 MetadataFloat_get_field_count(GF_Node *node, u8 dummy) { - return 11; + return 4; } -static GF_Err IndexedTriangleSet_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MetadataFloat_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_index"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IndexedTriangleSet *)node)->on_set_index; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedTriangleSet *) node)->set_index; + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataFloat *) node)->name; return GF_OK; case 1: - info->name = "color"; + info->name = "reference"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((X_IndexedTriangleSet *)node)->color; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataFloat *) node)->reference; return GF_OK; case 2: - info->name = "coord"; + info->name = "value"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinateNode; - info->far_ptr = & ((X_IndexedTriangleSet *)node)->coord; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_MetadataFloat *) node)->value; return GF_OK; case 3: - info->name = "normal"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFNormalNode; - info->far_ptr = & ((X_IndexedTriangleSet *)node)->normal; - return GF_OK; - case 4: - info->name = "texCoord"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureCoordinateNode; - info->far_ptr = & ((X_IndexedTriangleSet *)node)->texCoord; - return GF_OK; - case 5: - info->name = "ccw"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleSet *) node)->ccw; - return GF_OK; - case 6: - info->name = "colorPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleSet *) node)->colorPerVertex; - return GF_OK; - case 7: - info->name = "normalPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleSet *) node)->normalPerVertex; - return GF_OK; - case 8: - info->name = "solid"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleSet *) node)->solid; - return GF_OK; - case 9: - info->name = "index"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedTriangleSet *) node)->index; - return GF_OK; - case 10: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_IndexedTriangleSet *)node)->metadata; + info->far_ptr = & ((X_MetadataFloat *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -3897,215 +7687,152 @@ static GF_Err IndexedTriangleSet_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 IndexedTriangleSet_get_field_index_by_name(char *name) +static s32 MetadataFloat_get_field_index_by_name(char *name) { - if (!strcmp("set_index", name)) return 0; - if (!strcmp("color", name)) return 1; - if (!strcmp("coord", name)) return 2; - if (!strcmp("normal", name)) return 3; - if (!strcmp("texCoord", name)) return 4; - if (!strcmp("ccw", name)) return 5; - if (!strcmp("colorPerVertex", name)) return 6; - if (!strcmp("normalPerVertex", name)) return 7; - if (!strcmp("solid", name)) return 8; - if (!strcmp("index", name)) return 9; - if (!strcmp("metadata", name)) return 10; + if (!strcmp("name", name)) return 0; + if (!strcmp("reference", name)) return 1; + if (!strcmp("value", name)) return 2; + if (!strcmp("metadata", name)) return 3; return -1; } -static GF_Node *IndexedTriangleSet_Create() +static GF_Node *MetadataFloat_Create() { - X_IndexedTriangleSet *p; - GF_SAFEALLOC(p, X_IndexedTriangleSet); + X_MetadataFloat *p; + GF_SAFEALLOC(p, X_MetadataFloat); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_IndexedTriangleSet); + gf_node_setup((GF_Node *)p, TAG_X3D_MetadataFloat); /*default field values*/ - p->ccw = 1; - p->colorPerVertex = 1; - p->normalPerVertex = 1; - p->solid = 1; return (GF_Node *)p; } /* - IndexedTriangleStripSet Node deletion + MetadataInteger Node deletion */ -static void IndexedTriangleStripSet_Del(GF_Node *node) +static void MetadataInteger_Del(GF_Node *node) { - X_IndexedTriangleStripSet *p = (X_IndexedTriangleStripSet *) node; - gf_sg_mfint32_del(p->set_index); - gf_node_unregister((GF_Node *) p->color, node); - gf_node_unregister((GF_Node *) p->coord, node); - gf_node_unregister((GF_Node *) p->normal, node); - gf_node_unregister((GF_Node *) p->texCoord, node); - gf_sg_mfint32_del(p->index); + X_MetadataInteger *p = (X_MetadataInteger *) node; + gf_sg_sfstring_del(p->name); + gf_sg_sfstring_del(p->reference); + gf_sg_mfint32_del(p->value); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 IndexedTriangleStripSet_get_field_count(GF_Node *node, u8 dummy) +static u32 MetadataInteger_get_field_count(GF_Node *node, u8 dummy) { - return 11; + return 4; } -static GF_Err IndexedTriangleStripSet_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MetadataInteger_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_index"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IndexedTriangleStripSet *)node)->on_set_index; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->set_index; + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataInteger *) node)->name; return GF_OK; case 1: - info->name = "color"; + info->name = "reference"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->color; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataInteger *) node)->reference; return GF_OK; case 2: - info->name = "coord"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinateNode; - info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->coord; - return GF_OK; - case 3: - info->name = "creaseAngle"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->creaseAngle; - return GF_OK; - case 4: - info->name = "normal"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFNormalNode; - info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->normal; - return GF_OK; - case 5: - info->name = "texCoord"; + info->name = "value"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFTextureCoordinateNode; - info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->texCoord; - return GF_OK; - case 6: - info->name = "ccw"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->ccw; - return GF_OK; - case 7: - info->name = "normalPerVertex"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->normalPerVertex; - return GF_OK; - case 8: - info->name = "solid"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->solid; - return GF_OK; - case 9: - info->name = "index"; - info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IndexedTriangleStripSet *) node)->index; + info->far_ptr = & ((X_MetadataInteger *) node)->value; return GF_OK; - case 10: + case 3: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_IndexedTriangleStripSet *)node)->metadata; + info->far_ptr = & ((X_MetadataInteger *)node)->metadata; return GF_OK; - default: - return GF_BAD_PARAM; - } -} - - -static s32 IndexedTriangleStripSet_get_field_index_by_name(char *name) -{ - if (!strcmp("set_index", name)) return 0; - if (!strcmp("color", name)) return 1; - if (!strcmp("coord", name)) return 2; - if (!strcmp("creaseAngle", name)) return 3; - if (!strcmp("normal", name)) return 4; - if (!strcmp("texCoord", name)) return 5; - if (!strcmp("ccw", name)) return 6; - if (!strcmp("normalPerVertex", name)) return 7; - if (!strcmp("solid", name)) return 8; - if (!strcmp("index", name)) return 9; - if (!strcmp("metadata", name)) return 10; + default: + return GF_BAD_PARAM; + } +} + + +static s32 MetadataInteger_get_field_index_by_name(char *name) +{ + if (!strcmp("name", name)) return 0; + if (!strcmp("reference", name)) return 1; + if (!strcmp("value", name)) return 2; + if (!strcmp("metadata", name)) return 3; return -1; } -static GF_Node *IndexedTriangleStripSet_Create() +static GF_Node *MetadataInteger_Create() { - X_IndexedTriangleStripSet *p; - GF_SAFEALLOC(p, X_IndexedTriangleStripSet); + X_MetadataInteger *p; + GF_SAFEALLOC(p, X_MetadataInteger); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_IndexedTriangleStripSet); + gf_node_setup((GF_Node *)p, TAG_X3D_MetadataInteger); /*default field values*/ - p->creaseAngle = FLT2FIX(0); - p->ccw = 1; - p->normalPerVertex = 1; - p->solid = 1; return (GF_Node *)p; } /* - Inline Node deletion + MetadataSet Node deletion */ -static void Inline_Del(GF_Node *node) +static void MetadataSet_Del(GF_Node *node) { - X_Inline *p = (X_Inline *) node; - gf_sg_mfurl_del(p->url); + X_MetadataSet *p = (X_MetadataSet *) node; + gf_sg_sfstring_del(p->name); + gf_sg_sfstring_del(p->reference); + gf_node_unregister_children(node, p->value); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 Inline_get_field_count(GF_Node *node, u8 dummy) +static u32 MetadataSet_get_field_count(GF_Node *node, u8 dummy) { - return 3; + return 4; } -static GF_Err Inline_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MetadataSet_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "url"; + info->name = "name"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((X_Inline *) node)->url; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataSet *) node)->name; return GF_OK; case 1: - info->name = "metadata"; + info->name = "reference"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_Inline *)node)->metadata; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataSet *) node)->reference; return GF_OK; case 2: - info->name = "load"; + info->name = "value"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_Inline *) node)->load; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_MetadataSet *)node)->value; + return GF_OK; + case 3: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_MetadataSet *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -4113,95 +7840,75 @@ static GF_Err Inline_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Inline_get_field_index_by_name(char *name) +static s32 MetadataSet_get_field_index_by_name(char *name) { - if (!strcmp("url", name)) return 0; - if (!strcmp("metadata", name)) return 1; - if (!strcmp("load", name)) return 2; + if (!strcmp("name", name)) return 0; + if (!strcmp("reference", name)) return 1; + if (!strcmp("value", name)) return 2; + if (!strcmp("metadata", name)) return 3; return -1; } -static GF_Node *Inline_Create() +static GF_Node *MetadataSet_Create() { - X_Inline *p; - GF_SAFEALLOC(p, X_Inline); + X_MetadataSet *p; + GF_SAFEALLOC(p, X_MetadataSet); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_Inline); + gf_node_setup((GF_Node *)p, TAG_X3D_MetadataSet); /*default field values*/ - p->load = 1; return (GF_Node *)p; } /* - IntegerSequencer Node deletion + MetadataString Node deletion */ -static void IntegerSequencer_Del(GF_Node *node) +static void MetadataString_Del(GF_Node *node) { - X_IntegerSequencer *p = (X_IntegerSequencer *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfint32_del(p->keyValue); + X_MetadataString *p = (X_MetadataString *) node; + gf_sg_sfstring_del(p->name); + gf_sg_sfstring_del(p->reference); + gf_sg_mfstring_del(p->value); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 IntegerSequencer_get_field_count(GF_Node *node, u8 dummy) +static u32 MetadataString_get_field_count(GF_Node *node, u8 dummy) { - return 7; + return 4; } -static GF_Err IntegerSequencer_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MetadataString_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "next"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IntegerSequencer *)node)->on_next; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IntegerSequencer *) node)->next; + info->name = "name"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataString *) node)->name; return GF_OK; case 1: - info->name = "previous"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IntegerSequencer *)node)->on_previous; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IntegerSequencer *) node)->previous; - return GF_OK; - case 2: - info->name = "set_fraction"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IntegerSequencer *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_IntegerSequencer *) node)->set_fraction; - return GF_OK; - case 3: - info->name = "key"; + info->name = "reference"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((X_IntegerSequencer *) node)->key; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_MetadataString *) node)->reference; return GF_OK; - case 4: - info->name = "keyValue"; + case 2: + info->name = "value"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_IntegerSequencer *) node)->keyValue; - return GF_OK; - case 5: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((X_IntegerSequencer *) node)->value_changed; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_MetadataString *) node)->value; return GF_OK; - case 6: + case 3: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_IntegerSequencer *)node)->metadata; + info->far_ptr = & ((X_MetadataString *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -4209,25 +7916,22 @@ static GF_Err IntegerSequencer_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 IntegerSequencer_get_field_index_by_name(char *name) +static s32 MetadataString_get_field_index_by_name(char *name) { - if (!strcmp("next", name)) return 0; - if (!strcmp("previous", name)) return 1; - if (!strcmp("set_fraction", name)) return 2; - if (!strcmp("key", name)) return 3; - if (!strcmp("keyValue", name)) return 4; - if (!strcmp("value_changed", name)) return 5; - if (!strcmp("metadata", name)) return 6; + if (!strcmp("name", name)) return 0; + if (!strcmp("reference", name)) return 1; + if (!strcmp("value", name)) return 2; + if (!strcmp("metadata", name)) return 3; return -1; } -static GF_Node *IntegerSequencer_Create() +static GF_Node *MetadataString_Create() { - X_IntegerSequencer *p; - GF_SAFEALLOC(p, X_IntegerSequencer); + X_MetadataString *p; + GF_SAFEALLOC(p, X_MetadataString); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_IntegerSequencer); + gf_node_setup((GF_Node *)p, TAG_X3D_MetadataString); /*default field values*/ return (GF_Node *)p; @@ -4235,50 +7939,110 @@ static GF_Node *IntegerSequencer_Create() /* - IntegerTrigger Node deletion + MovieTexture Node deletion */ -static void IntegerTrigger_Del(GF_Node *node) +static void MovieTexture_Del(GF_Node *node) { - X_IntegerTrigger *p = (X_IntegerTrigger *) node; + X_MovieTexture *p = (X_MovieTexture *) node; + gf_sg_mfurl_del(p->url); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 IntegerTrigger_get_field_count(GF_Node *node, u8 dummy) +static u32 MovieTexture_get_field_count(GF_Node *node, u8 dummy) { - return 4; + return 14; } -static GF_Err IntegerTrigger_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MovieTexture_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_boolean"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_IntegerTrigger *)node)->on_set_boolean; + info->name = "loop"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_IntegerTrigger *) node)->set_boolean; + info->far_ptr = & ((X_MovieTexture *) node)->loop; return GF_OK; case 1: - info->name = "integerKey"; + info->name = "speed"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((X_IntegerTrigger *) node)->integerKey; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_MovieTexture *) node)->speed; return GF_OK; case 2: - info->name = "triggerValue"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((X_IntegerTrigger *) node)->triggerValue; + info->name = "startTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_MovieTexture *) node)->startTime; return GF_OK; case 3: + info->name = "stopTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_MovieTexture *) node)->stopTime; + return GF_OK; + case 4: + info->name = "url"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFURL; + info->far_ptr = & ((X_MovieTexture *) node)->url; + return GF_OK; + case 5: + info->name = "repeatS"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_MovieTexture *) node)->repeatS; + return GF_OK; + case 6: + info->name = "repeatT"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_MovieTexture *) node)->repeatT; + return GF_OK; + case 7: + info->name = "duration_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_MovieTexture *) node)->duration_changed; + return GF_OK; + case 8: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_MovieTexture *) node)->isActive; + return GF_OK; + case 9: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_IntegerTrigger *)node)->metadata; + info->far_ptr = & ((X_MovieTexture *)node)->metadata; + return GF_OK; + case 10: + info->name = "resumeTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_MovieTexture *) node)->resumeTime; + return GF_OK; + case 11: + info->name = "pauseTime"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_MovieTexture *) node)->pauseTime; + return GF_OK; + case 12: + info->name = "elapsedTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_MovieTexture *) node)->elapsedTime; + return GF_OK; + case 13: + info->name = "isPaused"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_MovieTexture *) node)->isPaused; return GF_OK; default: return GF_BAD_PARAM; @@ -4286,111 +8050,112 @@ static GF_Err IntegerTrigger_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 IntegerTrigger_get_field_index_by_name(char *name) +static s32 MovieTexture_get_field_index_by_name(char *name) { - if (!strcmp("set_boolean", name)) return 0; - if (!strcmp("integerKey", name)) return 1; - if (!strcmp("triggerValue", name)) return 2; - if (!strcmp("metadata", name)) return 3; + if (!strcmp("loop", name)) return 0; + if (!strcmp("speed", name)) return 1; + if (!strcmp("startTime", name)) return 2; + if (!strcmp("stopTime", name)) return 3; + if (!strcmp("url", name)) return 4; + if (!strcmp("repeatS", name)) return 5; + if (!strcmp("repeatT", name)) return 6; + if (!strcmp("duration_changed", name)) return 7; + if (!strcmp("isActive", name)) return 8; + if (!strcmp("metadata", name)) return 9; + if (!strcmp("resumeTime", name)) return 10; + if (!strcmp("pauseTime", name)) return 11; + if (!strcmp("elapsedTime", name)) return 12; + if (!strcmp("isPaused", name)) return 13; return -1; } -static GF_Node *IntegerTrigger_Create() +static GF_Node *MovieTexture_Create() { - X_IntegerTrigger *p; - GF_SAFEALLOC(p, X_IntegerTrigger); + X_MovieTexture *p; + GF_SAFEALLOC(p, X_MovieTexture); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_IntegerTrigger); + gf_node_setup((GF_Node *)p, TAG_X3D_MovieTexture); /*default field values*/ - p->integerKey = -1; + p->speed = FLT2FIX(1.0); + p->startTime = 0; + p->stopTime = 0; + p->repeatS = 1; + p->repeatT = 1; + p->resumeTime = 0; + p->pauseTime = 0; return (GF_Node *)p; } /* - KeySensor Node deletion + MultiTexture Node deletion */ -static void KeySensor_Del(GF_Node *node) +static void MultiTexture_Del(GF_Node *node) { - X_KeySensor *p = (X_KeySensor *) node; - gf_sg_sfstring_del(p->keyPress); - gf_sg_sfstring_del(p->keyRelease); + X_MultiTexture *p = (X_MultiTexture *) node; + gf_sg_mfstring_del(p->function); + gf_sg_mfstring_del(p->mode); + gf_sg_mfstring_del(p->source); + gf_node_unregister_children(node, p->texture); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 KeySensor_get_field_count(GF_Node *node, u8 dummy) +static u32 MultiTexture_get_field_count(GF_Node *node, u8 dummy) { - return 10; + return 7; } -static GF_Err KeySensor_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MultiTexture_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "enabled"; + info->name = "alpha"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_KeySensor *) node)->enabled; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_MultiTexture *) node)->alpha; return GF_OK; case 1: - info->name = "actionKeyPress"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((X_KeySensor *) node)->actionKeyPress; + info->name = "color"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFCOLOR; + info->far_ptr = & ((X_MultiTexture *) node)->color; return GF_OK; case 2: - info->name = "actionKeyRelease"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((X_KeySensor *) node)->actionKeyRelease; + info->name = "function"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_MultiTexture *) node)->function; return GF_OK; case 3: - info->name = "altKey"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_KeySensor *) node)->altKey; + info->name = "mode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_MultiTexture *) node)->mode; return GF_OK; case 4: - info->name = "controlKey"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_KeySensor *) node)->controlKey; + info->name = "source"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_MultiTexture *) node)->source; return GF_OK; case 5: - info->name = "isActive"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_KeySensor *) node)->isActive; + info->name = "texture"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFTextureNode; + info->far_ptr = & ((X_MultiTexture *)node)->texture; return GF_OK; case 6: - info->name = "keyPress"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_KeySensor *) node)->keyPress; - return GF_OK; - case 7: - info->name = "keyRelease"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_KeySensor *) node)->keyRelease; - return GF_OK; - case 8: - info->name = "shiftKey"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_KeySensor *) node)->shiftKey; - return GF_OK; - case 9: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_KeySensor *)node)->metadata; + info->far_ptr = & ((X_MultiTexture *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -4398,79 +8163,69 @@ static GF_Err KeySensor_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 KeySensor_get_field_index_by_name(char *name) +static s32 MultiTexture_get_field_index_by_name(char *name) { - if (!strcmp("enabled", name)) return 0; - if (!strcmp("actionKeyPress", name)) return 1; - if (!strcmp("actionKeyRelease", name)) return 2; - if (!strcmp("altKey", name)) return 3; - if (!strcmp("controlKey", name)) return 4; - if (!strcmp("isActive", name)) return 5; - if (!strcmp("keyPress", name)) return 6; - if (!strcmp("keyRelease", name)) return 7; - if (!strcmp("shiftKey", name)) return 8; - if (!strcmp("metadata", name)) return 9; + if (!strcmp("alpha", name)) return 0; + if (!strcmp("color", name)) return 1; + if (!strcmp("function", name)) return 2; + if (!strcmp("mode", name)) return 3; + if (!strcmp("source", name)) return 4; + if (!strcmp("texture", name)) return 5; + if (!strcmp("metadata", name)) return 6; return -1; } -static GF_Node *KeySensor_Create() +static GF_Node *MultiTexture_Create() { - X_KeySensor *p; - GF_SAFEALLOC(p, X_KeySensor); + X_MultiTexture *p; + GF_SAFEALLOC(p, X_MultiTexture); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_KeySensor); + gf_node_setup((GF_Node *)p, TAG_X3D_MultiTexture); /*default field values*/ - p->enabled = 1; + p->alpha = FLT2FIX(1); + p->color.red = FLT2FIX(1); + p->color.green = FLT2FIX(1); + p->color.blue = FLT2FIX(1); return (GF_Node *)p; } /* - LineProperties Node deletion + MultiTextureCoordinate Node deletion */ -static void LineProperties_Del(GF_Node *node) +static void MultiTextureCoordinate_Del(GF_Node *node) { - X_LineProperties *p = (X_LineProperties *) node; + X_MultiTextureCoordinate *p = (X_MultiTextureCoordinate *) node; + gf_node_unregister_children(node, p->texCoord); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 LineProperties_get_field_count(GF_Node *node, u8 dummy) +static u32 MultiTextureCoordinate_get_field_count(GF_Node *node, u8 dummy) { - return 4; + return 2; } -static GF_Err LineProperties_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MultiTextureCoordinate_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "applied"; + info->name = "texCoord"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_LineProperties *) node)->applied; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((X_MultiTextureCoordinate *)node)->texCoord; return GF_OK; case 1: - info->name = "linetype"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFINT32; - info->far_ptr = & ((X_LineProperties *) node)->linetype; - return GF_OK; - case 2: - info->name = "linewidthScaleFactor"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_LineProperties *) node)->linewidthScaleFactor; - return GF_OK; - case 3: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_LineProperties *)node)->metadata; + info->far_ptr = & ((X_MultiTextureCoordinate *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -4478,80 +8233,60 @@ static GF_Err LineProperties_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 LineProperties_get_field_index_by_name(char *name) +static s32 MultiTextureCoordinate_get_field_index_by_name(char *name) { - if (!strcmp("applied", name)) return 0; - if (!strcmp("linetype", name)) return 1; - if (!strcmp("linewidthScaleFactor", name)) return 2; - if (!strcmp("metadata", name)) return 3; + if (!strcmp("texCoord", name)) return 0; + if (!strcmp("metadata", name)) return 1; return -1; } -static GF_Node *LineProperties_Create() +static GF_Node *MultiTextureCoordinate_Create() { - X_LineProperties *p; - GF_SAFEALLOC(p, X_LineProperties); + X_MultiTextureCoordinate *p; + GF_SAFEALLOC(p, X_MultiTextureCoordinate); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_LineProperties); + gf_node_setup((GF_Node *)p, TAG_X3D_MultiTextureCoordinate); /*default field values*/ - p->applied = 1; - p->linetype = 1; - p->linewidthScaleFactor = FLT2FIX(0); return (GF_Node *)p; } /* - LineSet Node deletion + MultiTextureTransform Node deletion */ -static void LineSet_Del(GF_Node *node) +static void MultiTextureTransform_Del(GF_Node *node) { - X_LineSet *p = (X_LineSet *) node; - gf_node_unregister((GF_Node *) p->color, node); - gf_node_unregister((GF_Node *) p->coord, node); - gf_sg_mfint32_del(p->vertexCount); + X_MultiTextureTransform *p = (X_MultiTextureTransform *) node; + gf_node_unregister_children(node, p->textureTransform); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 LineSet_get_field_count(GF_Node *node, u8 dummy) +static u32 MultiTextureTransform_get_field_count(GF_Node *node, u8 dummy) { - return 4; + return 2; } -static GF_Err LineSet_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err MultiTextureTransform_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "color"; + info->name = "textureTransform"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFColorNode; - info->far_ptr = & ((X_LineSet *)node)->color; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFTextureTransformNode; + info->far_ptr = & ((X_MultiTextureTransform *)node)->textureTransform; return GF_OK; case 1: - info->name = "coord"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFCoordinateNode; - info->far_ptr = & ((X_LineSet *)node)->coord; - return GF_OK; - case 2: - info->name = "vertexCount"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_LineSet *) node)->vertexCount; - return GF_OK; - case 3: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_LineSet *)node)->metadata; + info->far_ptr = & ((X_MultiTextureTransform *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -4559,22 +8294,20 @@ static GF_Err LineSet_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 LineSet_get_field_index_by_name(char *name) +static s32 MultiTextureTransform_get_field_index_by_name(char *name) { - if (!strcmp("color", name)) return 0; - if (!strcmp("coord", name)) return 1; - if (!strcmp("vertexCount", name)) return 2; - if (!strcmp("metadata", name)) return 3; + if (!strcmp("textureTransform", name)) return 0; + if (!strcmp("metadata", name)) return 1; return -1; } -static GF_Node *LineSet_Create() +static GF_Node *MultiTextureTransform_Create() { - X_LineSet *p; - GF_SAFEALLOC(p, X_LineSet); + X_MultiTextureTransform *p; + GF_SAFEALLOC(p, X_MultiTextureTransform); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_LineSet); + gf_node_setup((GF_Node *)p, TAG_X3D_MultiTextureTransform); /*default field values*/ return (GF_Node *)p; @@ -4582,68 +8315,89 @@ static GF_Node *LineSet_Create() /* - LOD Node deletion + NavigationInfo Node deletion */ -static void LOD_Del(GF_Node *node) +static void NavigationInfo_Del(GF_Node *node) { - X_LOD *p = (X_LOD *) node; - gf_sg_mffloat_del(p->range); + X_NavigationInfo *p = (X_NavigationInfo *) node; + gf_sg_mffloat_del(p->avatarSize); + gf_sg_mfstring_del(p->type); gf_node_unregister((GF_Node *) p->metadata, node); - gf_sg_vrml_parent_destroy(node); + gf_sg_mfstring_del(p->transitionType); gf_node_free((GF_Node *)p); } -static u32 LOD_get_field_count(GF_Node *node, u8 dummy) +static u32 NavigationInfo_get_field_count(GF_Node *node, u8 dummy) { - return 6; + return 10; } -static GF_Err LOD_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NavigationInfo_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "addChildren"; + info->name = "set_bind"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_LOD *)node)->on_addChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((X_LOD *)node)->addChildren; + info->on_event_in = ((X_NavigationInfo *)node)->on_set_bind; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NavigationInfo *) node)->set_bind; return GF_OK; case 1: - info->name = "removeChildren"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_LOD *)node)->on_removeChildren; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((X_LOD *)node)->removeChildren; + info->name = "avatarSize"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_NavigationInfo *) node)->avatarSize; return GF_OK; case 2: - info->name = "children"; + info->name = "headlight"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SF3DNode; - info->far_ptr = & ((X_LOD *)node)->children; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NavigationInfo *) node)->headlight; return GF_OK; case 3: - info->name = "center"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFVEC3F; - info->far_ptr = & ((X_LOD *) node)->center; + info->name = "speed"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_NavigationInfo *) node)->speed; return GF_OK; case 4: - info->name = "range"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((X_LOD *) node)->range; + info->name = "type"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_NavigationInfo *) node)->type; return GF_OK; case 5: + info->name = "visibilityLimit"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_NavigationInfo *) node)->visibilityLimit; + return GF_OK; + case 6: + info->name = "isBound"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NavigationInfo *) node)->isBound; + return GF_OK; + case 7: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_LOD *)node)->metadata; + info->far_ptr = & ((X_NavigationInfo *)node)->metadata; + return GF_OK; + case 8: + info->name = "transitionType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFSTRING; + info->far_ptr = & ((X_NavigationInfo *) node)->transitionType; + return GF_OK; + case 9: + info->name = "bindTime"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_NavigationInfo *) node)->bindTime; return GF_OK; default: return GF_BAD_PARAM; @@ -4651,96 +8405,87 @@ static GF_Err LOD_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 LOD_get_field_index_by_name(char *name) +static s32 NavigationInfo_get_field_index_by_name(char *name) { - if (!strcmp("addChildren", name)) return 0; - if (!strcmp("removeChildren", name)) return 1; - if (!strcmp("children", name)) return 2; - if (!strcmp("center", name)) return 3; - if (!strcmp("range", name)) return 4; - if (!strcmp("metadata", name)) return 5; + if (!strcmp("set_bind", name)) return 0; + if (!strcmp("avatarSize", name)) return 1; + if (!strcmp("headlight", name)) return 2; + if (!strcmp("speed", name)) return 3; + if (!strcmp("type", name)) return 4; + if (!strcmp("visibilityLimit", name)) return 5; + if (!strcmp("isBound", name)) return 6; + if (!strcmp("metadata", name)) return 7; + if (!strcmp("transitionType", name)) return 8; + if (!strcmp("bindTime", name)) return 9; return -1; } -static GF_Node *LOD_Create() +static GF_Node *NavigationInfo_Create() { - X_LOD *p; - GF_SAFEALLOC(p, X_LOD); + X_NavigationInfo *p; + GF_SAFEALLOC(p, X_NavigationInfo); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_LOD); - gf_sg_vrml_parent_setup((GF_Node *) p); + gf_node_setup((GF_Node *)p, TAG_X3D_NavigationInfo); /*default field values*/ - p->center.x = FLT2FIX(0); - p->center.y = FLT2FIX(0); - p->center.z = FLT2FIX(0); + p->avatarSize.vals = (SFFloat *)gf_malloc(sizeof(SFFloat)*3); + p->avatarSize.count = 3; + p->avatarSize.vals[0] = FLT2FIX(0.25); + p->avatarSize.vals[1] = FLT2FIX(1.6); + p->avatarSize.vals[2] = FLT2FIX(0.75); + p->headlight = 1; + p->speed = FLT2FIX(1.0); + p->type.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->type.count = 2; + p->type.vals[0] = (char*)gf_malloc(sizeof(char) * 5); + strcpy(p->type.vals[0], "WALK"); + p->type.vals[1] = (char*)gf_malloc(sizeof(char) * 4); + strcpy(p->type.vals[1], "ANY"); + p->visibilityLimit = FLT2FIX(0.0); + p->transitionType.vals = (char**)gf_malloc(sizeof(SFString)*2); + p->transitionType.count = 2; + p->transitionType.vals[0] = (char*)gf_malloc(sizeof(char) * 5); + strcpy(p->transitionType.vals[0], "WALK"); + p->transitionType.vals[1] = (char*)gf_malloc(sizeof(char) * 4); + strcpy(p->transitionType.vals[1], "ANY"); return (GF_Node *)p; } /* - Material Node deletion + Normal Node deletion */ -static void Material_Del(GF_Node *node) +static void Normal_Del(GF_Node *node) { - X_Material *p = (X_Material *) node; + X_Normal *p = (X_Normal *) node; + gf_sg_mfvec3f_del(p->vector); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 Material_get_field_count(GF_Node *node, u8 dummy) +static u32 Normal_get_field_count(GF_Node *node, u8 dummy) { - return 7; + return 2; } -static GF_Err Material_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err Normal_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "ambientIntensity"; + info->name = "vector"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_Material *) node)->ambientIntensity; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((X_Normal *) node)->vector; return GF_OK; case 1: - info->name = "diffuseColor"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((X_Material *) node)->diffuseColor; - return GF_OK; - case 2: - info->name = "emissiveColor"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((X_Material *) node)->emissiveColor; - return GF_OK; - case 3: - info->name = "shininess"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_Material *) node)->shininess; - return GF_OK; - case 4: - info->name = "specularColor"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((X_Material *) node)->specularColor; - return GF_OK; - case 5: - info->name = "transparency"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_Material *) node)->transparency; - return GF_OK; - case 6: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_Material *)node)->metadata; + info->far_ptr = & ((X_Normal *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -4748,90 +8493,80 @@ static GF_Err Material_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Material_get_field_index_by_name(char *name) +static s32 Normal_get_field_index_by_name(char *name) { - if (!strcmp("ambientIntensity", name)) return 0; - if (!strcmp("diffuseColor", name)) return 1; - if (!strcmp("emissiveColor", name)) return 2; - if (!strcmp("shininess", name)) return 3; - if (!strcmp("specularColor", name)) return 4; - if (!strcmp("transparency", name)) return 5; - if (!strcmp("metadata", name)) return 6; + if (!strcmp("vector", name)) return 0; + if (!strcmp("metadata", name)) return 1; return -1; } -static GF_Node *Material_Create() +static GF_Node *Normal_Create() { - X_Material *p; - GF_SAFEALLOC(p, X_Material); + X_Normal *p; + GF_SAFEALLOC(p, X_Normal); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_Material); + gf_node_setup((GF_Node *)p, TAG_X3D_Normal); /*default field values*/ - p->ambientIntensity = FLT2FIX(0.2); - p->diffuseColor.red = FLT2FIX(0.8); - p->diffuseColor.green = FLT2FIX(0.8); - p->diffuseColor.blue = FLT2FIX(0.8); - p->emissiveColor.red = FLT2FIX(0); - p->emissiveColor.green = FLT2FIX(0); - p->emissiveColor.blue = FLT2FIX(0); - p->shininess = FLT2FIX(0.2); - p->specularColor.red = FLT2FIX(0); - p->specularColor.green = FLT2FIX(0); - p->specularColor.blue = FLT2FIX(0); - p->transparency = FLT2FIX(0); return (GF_Node *)p; } /* - MetadataDouble Node deletion + NormalInterpolator Node deletion */ -static void MetadataDouble_Del(GF_Node *node) +static void NormalInterpolator_Del(GF_Node *node) { - X_MetadataDouble *p = (X_MetadataDouble *) node; - gf_sg_sfstring_del(p->name); - gf_sg_sfstring_del(p->reference); - gf_sg_mfdouble_del(p->value); + X_NormalInterpolator *p = (X_NormalInterpolator *) node; + gf_sg_mffloat_del(p->key); + gf_sg_mfvec3f_del(p->keyValue); + gf_sg_mfvec3f_del(p->value_changed); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 MetadataDouble_get_field_count(GF_Node *node, u8 dummy) +static u32 NormalInterpolator_get_field_count(GF_Node *node, u8 dummy) { - return 4; + return 5; } -static GF_Err MetadataDouble_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NormalInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "name"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataDouble *) node)->name; + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_NormalInterpolator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_NormalInterpolator *) node)->set_fraction; return GF_OK; case 1: - info->name = "reference"; + info->name = "key"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataDouble *) node)->reference; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_NormalInterpolator *) node)->key; return GF_OK; case 2: - info->name = "value"; + info->name = "keyValue"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFDOUBLE; - info->far_ptr = & ((X_MetadataDouble *) node)->value; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((X_NormalInterpolator *) node)->keyValue; return GF_OK; case 3: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((X_NormalInterpolator *) node)->value_changed; + return GF_OK; + case 4: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MetadataDouble *)node)->metadata; + info->far_ptr = & ((X_NormalInterpolator *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -4839,22 +8574,23 @@ static GF_Err MetadataDouble_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MetadataDouble_get_field_index_by_name(char *name) +static s32 NormalInterpolator_get_field_index_by_name(char *name) { - if (!strcmp("name", name)) return 0; - if (!strcmp("reference", name)) return 1; - if (!strcmp("value", name)) return 2; - if (!strcmp("metadata", name)) return 3; + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("key", name)) return 1; + if (!strcmp("keyValue", name)) return 2; + if (!strcmp("value_changed", name)) return 3; + if (!strcmp("metadata", name)) return 4; return -1; } -static GF_Node *MetadataDouble_Create() +static GF_Node *NormalInterpolator_Create() { - X_MetadataDouble *p; - GF_SAFEALLOC(p, X_MetadataDouble); + X_NormalInterpolator *p; + GF_SAFEALLOC(p, X_NormalInterpolator); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_MetadataDouble); + gf_node_setup((GF_Node *)p, TAG_X3D_NormalInterpolator); /*default field values*/ return (GF_Node *)p; @@ -4862,52 +8598,70 @@ static GF_Node *MetadataDouble_Create() /* - MetadataFloat Node deletion + NurbsCurve Node deletion */ -static void MetadataFloat_Del(GF_Node *node) +static void NurbsCurve_Del(GF_Node *node) { - X_MetadataFloat *p = (X_MetadataFloat *) node; - gf_sg_sfstring_del(p->name); - gf_sg_sfstring_del(p->reference); - gf_sg_mffloat_del(p->value); + X_NurbsCurve *p = (X_NurbsCurve *) node; + gf_sg_mfvec3f_del(p->controlPoint); + gf_sg_mfdouble_del(p->weight); + gf_sg_mffloat_del(p->knot); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 MetadataFloat_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsCurve_get_field_count(GF_Node *node, u8 dummy) { - return 4; + return 7; } -static GF_Err MetadataFloat_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsCurve_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "name"; + info->name = "controlPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataFloat *) node)->name; + info->fieldType = GF_SG_VRML_MFVEC3F; + info->far_ptr = & ((X_NurbsCurve *) node)->controlPoint; return GF_OK; case 1: - info->name = "reference"; + info->name = "tessellation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataFloat *) node)->reference; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsCurve *) node)->tessellation; return GF_OK; case 2: - info->name = "value"; + info->name = "weight"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((X_MetadataFloat *) node)->value; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsCurve *) node)->weight; return GF_OK; case 3: + info->name = "closed"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsCurve *) node)->closed; + return GF_OK; + case 4: + info->name = "knot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_NurbsCurve *) node)->knot; + return GF_OK; + case 5: + info->name = "order"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsCurve *) node)->order; + return GF_OK; + case 6: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MetadataFloat *)node)->metadata; + info->far_ptr = & ((X_NurbsCurve *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -4915,75 +8669,98 @@ static GF_Err MetadataFloat_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MetadataFloat_get_field_index_by_name(char *name) +static s32 NurbsCurve_get_field_index_by_name(char *name) { - if (!strcmp("name", name)) return 0; - if (!strcmp("reference", name)) return 1; - if (!strcmp("value", name)) return 2; - if (!strcmp("metadata", name)) return 3; + if (!strcmp("controlPoint", name)) return 0; + if (!strcmp("tessellation", name)) return 1; + if (!strcmp("weight", name)) return 2; + if (!strcmp("closed", name)) return 3; + if (!strcmp("knot", name)) return 4; + if (!strcmp("order", name)) return 5; + if (!strcmp("metadata", name)) return 6; return -1; } -static GF_Node *MetadataFloat_Create() +static GF_Node *NurbsCurve_Create() { - X_MetadataFloat *p; - GF_SAFEALLOC(p, X_MetadataFloat); + X_NurbsCurve *p; + GF_SAFEALLOC(p, X_NurbsCurve); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_MetadataFloat); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsCurve); /*default field values*/ + p->tessellation = 0; + p->order = 3; return (GF_Node *)p; } /* - MetadataInteger Node deletion + NurbsCurve2D Node deletion */ -static void MetadataInteger_Del(GF_Node *node) +static void NurbsCurve2D_Del(GF_Node *node) { - X_MetadataInteger *p = (X_MetadataInteger *) node; - gf_sg_sfstring_del(p->name); - gf_sg_sfstring_del(p->reference); - gf_sg_mfint32_del(p->value); + X_NurbsCurve2D *p = (X_NurbsCurve2D *) node; + gf_sg_mfvec2f_del(p->controlPoint); + gf_sg_mffloat_del(p->weight); + gf_sg_mffloat_del(p->knot); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 MetadataInteger_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsCurve2D_get_field_count(GF_Node *node, u8 dummy) { - return 4; + return 7; } -static GF_Err MetadataInteger_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsCurve2D_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "name"; + info->name = "controlPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataInteger *) node)->name; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((X_NurbsCurve2D *) node)->controlPoint; return GF_OK; case 1: - info->name = "reference"; + info->name = "tessellation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataInteger *) node)->reference; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsCurve2D *) node)->tessellation; return GF_OK; case 2: - info->name = "value"; + info->name = "weight"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFINT32; - info->far_ptr = & ((X_MetadataInteger *) node)->value; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_NurbsCurve2D *) node)->weight; return GF_OK; case 3: + info->name = "knot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_NurbsCurve2D *) node)->knot; + return GF_OK; + case 4: + info->name = "order"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsCurve2D *) node)->order; + return GF_OK; + case 5: + info->name = "closed"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsCurve2D *) node)->closed; + return GF_OK; + case 6: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MetadataInteger *)node)->metadata; + info->far_ptr = & ((X_NurbsCurve2D *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -4991,76 +8768,100 @@ static GF_Err MetadataInteger_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MetadataInteger_get_field_index_by_name(char *name) +static s32 NurbsCurve2D_get_field_index_by_name(char *name) { - if (!strcmp("name", name)) return 0; - if (!strcmp("reference", name)) return 1; - if (!strcmp("value", name)) return 2; - if (!strcmp("metadata", name)) return 3; + if (!strcmp("controlPoint", name)) return 0; + if (!strcmp("tessellation", name)) return 1; + if (!strcmp("weight", name)) return 2; + if (!strcmp("knot", name)) return 3; + if (!strcmp("order", name)) return 4; + if (!strcmp("closed", name)) return 5; + if (!strcmp("metadata", name)) return 6; return -1; } -static GF_Node *MetadataInteger_Create() +static GF_Node *NurbsCurve2D_Create() { - X_MetadataInteger *p; - GF_SAFEALLOC(p, X_MetadataInteger); + X_NurbsCurve2D *p; + GF_SAFEALLOC(p, X_NurbsCurve2D); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_MetadataInteger); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsCurve2D); /*default field values*/ + p->tessellation = 0; + p->order = 3; return (GF_Node *)p; } /* - MetadataSet Node deletion + NurbsOrientationInterpolator Node deletion */ -static void MetadataSet_Del(GF_Node *node) +static void NurbsOrientationInterpolator_Del(GF_Node *node) { - X_MetadataSet *p = (X_MetadataSet *) node; - gf_sg_sfstring_del(p->name); - gf_sg_sfstring_del(p->reference); - gf_node_unregister_children(node, p->value); + X_NurbsOrientationInterpolator *p = (X_NurbsOrientationInterpolator *) node; + gf_node_unregister((GF_Node *) p->controlPoints, node); + gf_sg_mfdouble_del(p->knot); + gf_sg_mfdouble_del(p->weight); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 MetadataSet_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsOrientationInterpolator_get_field_count(GF_Node *node, u8 dummy) { - return 4; + return 7; } -static GF_Err MetadataSet_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsOrientationInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "name"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataSet *) node)->name; + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_NurbsOrientationInterpolator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_NurbsOrientationInterpolator *) node)->set_fraction; return GF_OK; case 1: - info->name = "reference"; + info->name = "controlPoints"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataSet *) node)->reference; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_NurbsOrientationInterpolator *)node)->controlPoints; return GF_OK; case 2: - info->name = "value"; + info->name = "knot"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MetadataSet *)node)->value; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsOrientationInterpolator *) node)->knot; return GF_OK; case 3: + info->name = "order"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsOrientationInterpolator *) node)->order; + return GF_OK; + case 4: + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsOrientationInterpolator *) node)->weight; + return GF_OK; + case 5: + info->name = "value_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFROTATION; + info->far_ptr = & ((X_NurbsOrientationInterpolator *) node)->value_changed; + return GF_OK; + case 6: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MetadataSet *)node)->metadata; + info->far_ptr = & ((X_NurbsOrientationInterpolator *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -5068,75 +8869,149 @@ static GF_Err MetadataSet_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MetadataSet_get_field_index_by_name(char *name) +static s32 NurbsOrientationInterpolator_get_field_index_by_name(char *name) { - if (!strcmp("name", name)) return 0; - if (!strcmp("reference", name)) return 1; - if (!strcmp("value", name)) return 2; - if (!strcmp("metadata", name)) return 3; + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("controlPoints", name)) return 1; + if (!strcmp("knot", name)) return 2; + if (!strcmp("order", name)) return 3; + if (!strcmp("weight", name)) return 4; + if (!strcmp("value_changed", name)) return 5; + if (!strcmp("metadata", name)) return 6; return -1; } -static GF_Node *MetadataSet_Create() +static GF_Node *NurbsOrientationInterpolator_Create() { - X_MetadataSet *p; - GF_SAFEALLOC(p, X_MetadataSet); + X_NurbsOrientationInterpolator *p; + GF_SAFEALLOC(p, X_NurbsOrientationInterpolator); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_MetadataSet); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsOrientationInterpolator); /*default field values*/ + p->order = 3; return (GF_Node *)p; } /* - MetadataString Node deletion + NurbsPatchSurface Node deletion */ -static void MetadataString_Del(GF_Node *node) +static void NurbsPatchSurface_Del(GF_Node *node) { - X_MetadataString *p = (X_MetadataString *) node; - gf_sg_sfstring_del(p->name); - gf_sg_sfstring_del(p->reference); - gf_sg_mfstring_del(p->value); + X_NurbsPatchSurface *p = (X_NurbsPatchSurface *) node; + gf_node_unregister((GF_Node *) p->controlPoint, node); + gf_node_unregister((GF_Node *) p->texCoord, node); + gf_sg_mfdouble_del(p->weight); + gf_sg_mfdouble_del(p->uKnot); + gf_sg_mfdouble_del(p->vKnot); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 MetadataString_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsPatchSurface_get_field_count(GF_Node *node, u8 dummy) { - return 4; + return 15; } -static GF_Err MetadataString_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsPatchSurface_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "name"; + info->name = "controlPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataString *) node)->name; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_NurbsPatchSurface *)node)->controlPoint; return GF_OK; case 1: - info->name = "reference"; + info->name = "texCoord"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFSTRING; - info->far_ptr = & ((X_MetadataString *) node)->reference; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((X_NurbsPatchSurface *)node)->texCoord; return GF_OK; case 2: - info->name = "value"; + info->name = "uTessellation"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((X_MetadataString *) node)->value; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->uTessellation; return GF_OK; case 3: + info->name = "vTessellation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->vTessellation; + return GF_OK; + case 4: + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->weight; + return GF_OK; + case 5: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->solid; + return GF_OK; + case 6: + info->name = "uClosed"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->uClosed; + return GF_OK; + case 7: + info->name = "uDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->uDimension; + return GF_OK; + case 8: + info->name = "uKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->uKnot; + return GF_OK; + case 9: + info->name = "uOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->uOrder; + return GF_OK; + case 10: + info->name = "vClosed"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->vClosed; + return GF_OK; + case 11: + info->name = "vDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->vDimension; + return GF_OK; + case 12: + info->name = "vKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->vKnot; + return GF_OK; + case 13: + info->name = "vOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsPatchSurface *) node)->vOrder; + return GF_OK; + case 14: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MetadataString *)node)->metadata; + info->far_ptr = & ((X_NurbsPatchSurface *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -5144,133 +9019,113 @@ static GF_Err MetadataString_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MetadataString_get_field_index_by_name(char *name) -{ - if (!strcmp("name", name)) return 0; - if (!strcmp("reference", name)) return 1; - if (!strcmp("value", name)) return 2; - if (!strcmp("metadata", name)) return 3; +static s32 NurbsPatchSurface_get_field_index_by_name(char *name) +{ + if (!strcmp("controlPoint", name)) return 0; + if (!strcmp("texCoord", name)) return 1; + if (!strcmp("uTessellation", name)) return 2; + if (!strcmp("vTessellation", name)) return 3; + if (!strcmp("weight", name)) return 4; + if (!strcmp("solid", name)) return 5; + if (!strcmp("uClosed", name)) return 6; + if (!strcmp("uDimension", name)) return 7; + if (!strcmp("uKnot", name)) return 8; + if (!strcmp("uOrder", name)) return 9; + if (!strcmp("vClosed", name)) return 10; + if (!strcmp("vDimension", name)) return 11; + if (!strcmp("vKnot", name)) return 12; + if (!strcmp("vOrder", name)) return 13; + if (!strcmp("metadata", name)) return 14; return -1; } -static GF_Node *MetadataString_Create() +static GF_Node *NurbsPatchSurface_Create() { - X_MetadataString *p; - GF_SAFEALLOC(p, X_MetadataString); + X_NurbsPatchSurface *p; + GF_SAFEALLOC(p, X_NurbsPatchSurface); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_MetadataString); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsPatchSurface); /*default field values*/ + p->uTessellation = 0; + p->vTessellation = 0; + p->solid = 1; + p->uDimension = 0; + p->uOrder = 3; + p->vDimension = 0; + p->vOrder = 3; return (GF_Node *)p; } /* - MovieTexture Node deletion + NurbsPositionInterpolator Node deletion */ -static void MovieTexture_Del(GF_Node *node) +static void NurbsPositionInterpolator_Del(GF_Node *node) { - X_MovieTexture *p = (X_MovieTexture *) node; - gf_sg_mfurl_del(p->url); + X_NurbsPositionInterpolator *p = (X_NurbsPositionInterpolator *) node; + gf_node_unregister((GF_Node *) p->controlPoints, node); + gf_sg_mfdouble_del(p->knot); + gf_sg_mfdouble_del(p->weight); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 MovieTexture_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsPositionInterpolator_get_field_count(GF_Node *node, u8 dummy) { - return 14; + return 7; } -static GF_Err MovieTexture_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsPositionInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "loop"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_MovieTexture *) node)->loop; + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_NurbsPositionInterpolator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_NurbsPositionInterpolator *) node)->set_fraction; return GF_OK; case 1: - info->name = "speed"; + info->name = "controlPoints"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_MovieTexture *) node)->speed; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_NurbsPositionInterpolator *)node)->controlPoints; return GF_OK; case 2: - info->name = "startTime"; + info->name = "knot"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((X_MovieTexture *) node)->startTime; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsPositionInterpolator *) node)->knot; return GF_OK; case 3: - info->name = "stopTime"; + info->name = "order"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((X_MovieTexture *) node)->stopTime; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsPositionInterpolator *) node)->order; return GF_OK; case 4: - info->name = "url"; + info->name = "weight"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFURL; - info->far_ptr = & ((X_MovieTexture *) node)->url; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsPositionInterpolator *) node)->weight; return GF_OK; case 5: - info->name = "repeatS"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_MovieTexture *) node)->repeatS; - return GF_OK; - case 6: - info->name = "repeatT"; - info->eventType = GF_SG_EVENT_FIELD; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_MovieTexture *) node)->repeatT; - return GF_OK; - case 7: - info->name = "duration_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((X_MovieTexture *) node)->duration_changed; - return GF_OK; - case 8: - info->name = "isActive"; + info->name = "value_changed"; info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_MovieTexture *) node)->isActive; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_NurbsPositionInterpolator *) node)->value_changed; return GF_OK; - case 9: + case 6: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MovieTexture *)node)->metadata; - return GF_OK; - case 10: - info->name = "resumeTime"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((X_MovieTexture *) node)->resumeTime; - return GF_OK; - case 11: - info->name = "pauseTime"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((X_MovieTexture *) node)->pauseTime; - return GF_OK; - case 12: - info->name = "elapsedTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((X_MovieTexture *) node)->elapsedTime; - return GF_OK; - case 13: - info->name = "isPaused"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_MovieTexture *) node)->isPaused; + info->far_ptr = & ((X_NurbsPositionInterpolator *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -5278,112 +9133,90 @@ static GF_Err MovieTexture_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MovieTexture_get_field_index_by_name(char *name) +static s32 NurbsPositionInterpolator_get_field_index_by_name(char *name) { - if (!strcmp("loop", name)) return 0; - if (!strcmp("speed", name)) return 1; - if (!strcmp("startTime", name)) return 2; - if (!strcmp("stopTime", name)) return 3; - if (!strcmp("url", name)) return 4; - if (!strcmp("repeatS", name)) return 5; - if (!strcmp("repeatT", name)) return 6; - if (!strcmp("duration_changed", name)) return 7; - if (!strcmp("isActive", name)) return 8; - if (!strcmp("metadata", name)) return 9; - if (!strcmp("resumeTime", name)) return 10; - if (!strcmp("pauseTime", name)) return 11; - if (!strcmp("elapsedTime", name)) return 12; - if (!strcmp("isPaused", name)) return 13; + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("controlPoints", name)) return 1; + if (!strcmp("knot", name)) return 2; + if (!strcmp("order", name)) return 3; + if (!strcmp("weight", name)) return 4; + if (!strcmp("value_changed", name)) return 5; + if (!strcmp("metadata", name)) return 6; return -1; } -static GF_Node *MovieTexture_Create() +static GF_Node *NurbsPositionInterpolator_Create() { - X_MovieTexture *p; - GF_SAFEALLOC(p, X_MovieTexture); + X_NurbsPositionInterpolator *p; + GF_SAFEALLOC(p, X_NurbsPositionInterpolator); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_MovieTexture); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsPositionInterpolator); /*default field values*/ - p->speed = FLT2FIX(1.0); - p->startTime = 0; - p->stopTime = 0; - p->repeatS = 1; - p->repeatT = 1; - p->resumeTime = 0; - p->pauseTime = 0; + p->order = 3; return (GF_Node *)p; } /* - MultiTexture Node deletion + NurbsSet Node deletion */ -static void MultiTexture_Del(GF_Node *node) +static void NurbsSet_Del(GF_Node *node) { - X_MultiTexture *p = (X_MultiTexture *) node; - gf_sg_mfstring_del(p->function); - gf_sg_mfstring_del(p->mode); - gf_sg_mfstring_del(p->source); - gf_node_unregister_children(node, p->texture); + X_NurbsSet *p = (X_NurbsSet *) node; + gf_node_unregister_children(node, p->addGeometry); + gf_node_unregister_children(node, p->removeGeometry); + gf_node_unregister_children(node, p->geometry); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 MultiTexture_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsSet_get_field_count(GF_Node *node, u8 dummy) { - return 7; + return 5; } -static GF_Err MultiTexture_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsSet_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "alpha"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_MultiTexture *) node)->alpha; + info->name = "addGeometry"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_NurbsSet *)node)->on_addGeometry; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFNurbsSurfaceNode; + info->far_ptr = & ((X_NurbsSet *)node)->addGeometry; return GF_OK; case 1: - info->name = "color"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFCOLOR; - info->far_ptr = & ((X_MultiTexture *) node)->color; + info->name = "removeGeometry"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_NurbsSet *)node)->on_removeGeometry; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFNurbsSurfaceNode; + info->far_ptr = & ((X_NurbsSet *)node)->removeGeometry; return GF_OK; case 2: - info->name = "function"; + info->name = "geometry"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((X_MultiTexture *) node)->function; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFNurbsSurfaceNode; + info->far_ptr = & ((X_NurbsSet *)node)->geometry; return GF_OK; case 3: - info->name = "mode"; + info->name = "tessellationScale"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((X_MultiTexture *) node)->mode; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_NurbsSet *) node)->tessellationScale; return GF_OK; case 4: - info->name = "source"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((X_MultiTexture *) node)->source; - return GF_OK; - case 5: - info->name = "texture"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SFTextureNode; - info->far_ptr = & ((X_MultiTexture *)node)->texture; - return GF_OK; - case 6: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MultiTexture *)node)->metadata; + info->far_ptr = & ((X_NurbsSet *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -5391,69 +9224,128 @@ static GF_Err MultiTexture_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MultiTexture_get_field_index_by_name(char *name) +static s32 NurbsSet_get_field_index_by_name(char *name) { - if (!strcmp("alpha", name)) return 0; - if (!strcmp("color", name)) return 1; - if (!strcmp("function", name)) return 2; - if (!strcmp("mode", name)) return 3; - if (!strcmp("source", name)) return 4; - if (!strcmp("texture", name)) return 5; - if (!strcmp("metadata", name)) return 6; + if (!strcmp("addGeometry", name)) return 0; + if (!strcmp("removeGeometry", name)) return 1; + if (!strcmp("geometry", name)) return 2; + if (!strcmp("tessellationScale", name)) return 3; + if (!strcmp("metadata", name)) return 4; return -1; } -static GF_Node *MultiTexture_Create() +static GF_Node *NurbsSet_Create() { - X_MultiTexture *p; - GF_SAFEALLOC(p, X_MultiTexture); + X_NurbsSet *p; + GF_SAFEALLOC(p, X_NurbsSet); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_MultiTexture); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsSet); /*default field values*/ - p->alpha = FLT2FIX(1); - p->color.red = FLT2FIX(1); - p->color.green = FLT2FIX(1); - p->color.blue = FLT2FIX(1); + p->tessellationScale = FLT2FIX(1.0); return (GF_Node *)p; } /* - MultiTextureCoordinate Node deletion + NurbsSurfaceInterpolator Node deletion */ -static void MultiTextureCoordinate_Del(GF_Node *node) +static void NurbsSurfaceInterpolator_Del(GF_Node *node) { - X_MultiTextureCoordinate *p = (X_MultiTextureCoordinate *) node; - gf_node_unregister_children(node, p->texCoord); + X_NurbsSurfaceInterpolator *p = (X_NurbsSurfaceInterpolator *) node; + gf_node_unregister((GF_Node *) p->controlPoints, node); + gf_sg_mfdouble_del(p->weight); + gf_sg_mfdouble_del(p->uKnot); + gf_sg_mfdouble_del(p->vKnot); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 MultiTextureCoordinate_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsSurfaceInterpolator_get_field_count(GF_Node *node, u8 dummy) { - return 2; + return 12; } -static GF_Err MultiTextureCoordinate_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsSurfaceInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "texCoord"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SFTextureCoordinateNode; - info->far_ptr = & ((X_MultiTextureCoordinate *)node)->texCoord; + info->name = "set_fraction"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_NurbsSurfaceInterpolator *)node)->on_set_fraction; + info->fieldType = GF_SG_VRML_SFVEC2F; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->set_fraction; return GF_OK; case 1: + info->name = "controlPoints"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *)node)->controlPoints; + return GF_OK; + case 2: + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->weight; + return GF_OK; + case 3: + info->name = "position_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->position_changed; + return GF_OK; + case 4: + info->name = "normal_changed"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->normal_changed; + return GF_OK; + case 5: + info->name = "uDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->uDimension; + return GF_OK; + case 6: + info->name = "uKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->uKnot; + return GF_OK; + case 7: + info->name = "uOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->uOrder; + return GF_OK; + case 8: + info->name = "vDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->vDimension; + return GF_OK; + case 9: + info->name = "vKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->vKnot; + return GF_OK; + case 10: + info->name = "vOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *) node)->vOrder; + return GF_OK; + case 11: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MultiTextureCoordinate *)node)->metadata; + info->far_ptr = & ((X_NurbsSurfaceInterpolator *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -5461,60 +9353,94 @@ static GF_Err MultiTextureCoordinate_get_field(GF_Node *node, GF_FieldInfo *info } -static s32 MultiTextureCoordinate_get_field_index_by_name(char *name) +static s32 NurbsSurfaceInterpolator_get_field_index_by_name(char *name) { - if (!strcmp("texCoord", name)) return 0; - if (!strcmp("metadata", name)) return 1; + if (!strcmp("set_fraction", name)) return 0; + if (!strcmp("controlPoints", name)) return 1; + if (!strcmp("weight", name)) return 2; + if (!strcmp("position_changed", name)) return 3; + if (!strcmp("normal_changed", name)) return 4; + if (!strcmp("uDimension", name)) return 5; + if (!strcmp("uKnot", name)) return 6; + if (!strcmp("uOrder", name)) return 7; + if (!strcmp("vDimension", name)) return 8; + if (!strcmp("vKnot", name)) return 9; + if (!strcmp("vOrder", name)) return 10; + if (!strcmp("metadata", name)) return 11; return -1; } -static GF_Node *MultiTextureCoordinate_Create() +static GF_Node *NurbsSurfaceInterpolator_Create() { - X_MultiTextureCoordinate *p; - GF_SAFEALLOC(p, X_MultiTextureCoordinate); + X_NurbsSurfaceInterpolator *p; + GF_SAFEALLOC(p, X_NurbsSurfaceInterpolator); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_MultiTextureCoordinate); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsSurfaceInterpolator); /*default field values*/ + p->uDimension = 0; + p->uOrder = 3; + p->vDimension = 0; + p->vOrder = 3; return (GF_Node *)p; } /* - MultiTextureTransform Node deletion + NurbsSweptSurface Node deletion */ -static void MultiTextureTransform_Del(GF_Node *node) +static void NurbsSweptSurface_Del(GF_Node *node) { - X_MultiTextureTransform *p = (X_MultiTextureTransform *) node; - gf_node_unregister_children(node, p->textureTransform); + X_NurbsSweptSurface *p = (X_NurbsSweptSurface *) node; + gf_node_unregister((GF_Node *) p->crossSectionCurve, node); + gf_node_unregister((GF_Node *) p->trajectoryCurve, node); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 MultiTextureTransform_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsSweptSurface_get_field_count(GF_Node *node, u8 dummy) { - return 2; + return 5; } -static GF_Err MultiTextureTransform_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsSweptSurface_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "textureTransform"; + info->name = "crossSectionCurve"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFNODE; - info->NDTtype = NDT_SFTextureTransformNode; - info->far_ptr = & ((X_MultiTextureTransform *)node)->textureTransform; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNurbsControlCurveNode; + info->far_ptr = & ((X_NurbsSweptSurface *)node)->crossSectionCurve; return GF_OK; case 1: + info->name = "trajectoryCurve"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNurbsCurveNode; + info->far_ptr = & ((X_NurbsSweptSurface *)node)->trajectoryCurve; + return GF_OK; + case 2: + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsSweptSurface *) node)->ccw; + return GF_OK; + case 3: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsSweptSurface *) node)->solid; + return GF_OK; + case 4: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_MultiTextureTransform *)node)->metadata; + info->far_ptr = & ((X_NurbsSweptSurface *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -5522,110 +9448,85 @@ static GF_Err MultiTextureTransform_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 MultiTextureTransform_get_field_index_by_name(char *name) +static s32 NurbsSweptSurface_get_field_index_by_name(char *name) { - if (!strcmp("textureTransform", name)) return 0; - if (!strcmp("metadata", name)) return 1; + if (!strcmp("crossSectionCurve", name)) return 0; + if (!strcmp("trajectoryCurve", name)) return 1; + if (!strcmp("ccw", name)) return 2; + if (!strcmp("solid", name)) return 3; + if (!strcmp("metadata", name)) return 4; return -1; } -static GF_Node *MultiTextureTransform_Create() +static GF_Node *NurbsSweptSurface_Create() { - X_MultiTextureTransform *p; - GF_SAFEALLOC(p, X_MultiTextureTransform); + X_NurbsSweptSurface *p; + GF_SAFEALLOC(p, X_NurbsSweptSurface); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_MultiTextureTransform); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsSweptSurface); /*default field values*/ + p->ccw = 1; + p->solid = 1; return (GF_Node *)p; } /* - NavigationInfo Node deletion + NurbsSwungSurface Node deletion */ -static void NavigationInfo_Del(GF_Node *node) +static void NurbsSwungSurface_Del(GF_Node *node) { - X_NavigationInfo *p = (X_NavigationInfo *) node; - gf_sg_mffloat_del(p->avatarSize); - gf_sg_mfstring_del(p->type); + X_NurbsSwungSurface *p = (X_NurbsSwungSurface *) node; + gf_node_unregister((GF_Node *) p->profileCurve, node); + gf_node_unregister((GF_Node *) p->trajectoryCurve, node); gf_node_unregister((GF_Node *) p->metadata, node); - gf_sg_mfstring_del(p->transitionType); gf_node_free((GF_Node *)p); } -static u32 NavigationInfo_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsSwungSurface_get_field_count(GF_Node *node, u8 dummy) { - return 10; + return 5; } -static GF_Err NavigationInfo_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsSwungSurface_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_bind"; - info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_NavigationInfo *)node)->on_set_bind; - info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_NavigationInfo *) node)->set_bind; + info->name = "profileCurve"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNurbsControlCurveNode; + info->far_ptr = & ((X_NurbsSwungSurface *)node)->profileCurve; return GF_OK; case 1: - info->name = "avatarSize"; + info->name = "trajectoryCurve"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((X_NavigationInfo *) node)->avatarSize; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFNurbsControlCurveNode; + info->far_ptr = & ((X_NurbsSwungSurface *)node)->trajectoryCurve; return GF_OK; case 2: - info->name = "headlight"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->name = "ccw"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_NavigationInfo *) node)->headlight; + info->far_ptr = & ((X_NurbsSwungSurface *) node)->ccw; return GF_OK; case 3: - info->name = "speed"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_NavigationInfo *) node)->speed; - return GF_OK; - case 4: - info->name = "type"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((X_NavigationInfo *) node)->type; - return GF_OK; - case 5: - info->name = "visibilityLimit"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_NavigationInfo *) node)->visibilityLimit; - return GF_OK; - case 6: - info->name = "isBound"; - info->eventType = GF_SG_EVENT_OUT; + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; info->fieldType = GF_SG_VRML_SFBOOL; - info->far_ptr = & ((X_NavigationInfo *) node)->isBound; + info->far_ptr = & ((X_NurbsSwungSurface *) node)->solid; return GF_OK; - case 7: + case 4: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_NavigationInfo *)node)->metadata; - return GF_OK; - case 8: - info->name = "transitionType"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFSTRING; - info->far_ptr = & ((X_NavigationInfo *) node)->transitionType; - return GF_OK; - case 9: - info->name = "bindTime"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_SFTIME; - info->far_ptr = & ((X_NavigationInfo *) node)->bindTime; + info->far_ptr = & ((X_NurbsSwungSurface *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -5633,87 +9534,109 @@ static GF_Err NavigationInfo_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 NavigationInfo_get_field_index_by_name(char *name) +static s32 NurbsSwungSurface_get_field_index_by_name(char *name) { - if (!strcmp("set_bind", name)) return 0; - if (!strcmp("avatarSize", name)) return 1; - if (!strcmp("headlight", name)) return 2; - if (!strcmp("speed", name)) return 3; - if (!strcmp("type", name)) return 4; - if (!strcmp("visibilityLimit", name)) return 5; - if (!strcmp("isBound", name)) return 6; - if (!strcmp("metadata", name)) return 7; - if (!strcmp("transitionType", name)) return 8; - if (!strcmp("bindTime", name)) return 9; + if (!strcmp("profileCurve", name)) return 0; + if (!strcmp("trajectoryCurve", name)) return 1; + if (!strcmp("ccw", name)) return 2; + if (!strcmp("solid", name)) return 3; + if (!strcmp("metadata", name)) return 4; return -1; } -static GF_Node *NavigationInfo_Create() +static GF_Node *NurbsSwungSurface_Create() { - X_NavigationInfo *p; - GF_SAFEALLOC(p, X_NavigationInfo); + X_NurbsSwungSurface *p; + GF_SAFEALLOC(p, X_NurbsSwungSurface); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_NavigationInfo); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsSwungSurface); /*default field values*/ - p->avatarSize.vals = (SFFloat *)malloc(sizeof(SFFloat)*3); - p->avatarSize.count = 3; - p->avatarSize.vals[0] = FLT2FIX(0.25); - p->avatarSize.vals[1] = FLT2FIX(1.6); - p->avatarSize.vals[2] = FLT2FIX(0.75); - p->headlight = 1; - p->speed = FLT2FIX(1.0); - p->type.vals = (char**)malloc(sizeof(SFString)*2); - p->type.count = 2; - p->type.vals[0] = (char*)malloc(sizeof(char) * 5); - strcpy(p->type.vals[0], "WALK"); - p->type.vals[1] = (char*)malloc(sizeof(char) * 4); - strcpy(p->type.vals[1], "ANY"); - p->visibilityLimit = FLT2FIX(0.0); - p->transitionType.vals = (char**)malloc(sizeof(SFString)*2); - p->transitionType.count = 2; - p->transitionType.vals[0] = (char*)malloc(sizeof(char) * 5); - strcpy(p->transitionType.vals[0], "WALK"); - p->transitionType.vals[1] = (char*)malloc(sizeof(char) * 4); - strcpy(p->transitionType.vals[1], "ANY"); + p->ccw = 1; + p->solid = 1; return (GF_Node *)p; } /* - Normal Node deletion + NurbsTextureCoordinate Node deletion */ -static void Normal_Del(GF_Node *node) +static void NurbsTextureCoordinate_Del(GF_Node *node) { - X_Normal *p = (X_Normal *) node; - gf_sg_mfvec3f_del(p->vector); + X_NurbsTextureCoordinate *p = (X_NurbsTextureCoordinate *) node; + gf_sg_mfvec2f_del(p->controlPoint); + gf_sg_mffloat_del(p->weight); + gf_sg_mfdouble_del(p->uKnot); + gf_sg_mfdouble_del(p->vKnot); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 Normal_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsTextureCoordinate_get_field_count(GF_Node *node, u8 dummy) { - return 2; + return 9; } -static GF_Err Normal_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsTextureCoordinate_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "vector"; + info->name = "controlPoint"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((X_Normal *) node)->vector; + info->fieldType = GF_SG_VRML_MFVEC2F; + info->far_ptr = & ((X_NurbsTextureCoordinate *) node)->controlPoint; return GF_OK; case 1: + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFFLOAT; + info->far_ptr = & ((X_NurbsTextureCoordinate *) node)->weight; + return GF_OK; + case 2: + info->name = "uDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTextureCoordinate *) node)->uDimension; + return GF_OK; + case 3: + info->name = "uKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsTextureCoordinate *) node)->uKnot; + return GF_OK; + case 4: + info->name = "uOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTextureCoordinate *) node)->uOrder; + return GF_OK; + case 5: + info->name = "vDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTextureCoordinate *) node)->vDimension; + return GF_OK; + case 6: + info->name = "vKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsTextureCoordinate *) node)->vKnot; + return GF_OK; + case 7: + info->name = "vOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTextureCoordinate *) node)->vOrder; + return GF_OK; + case 8: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_Normal *)node)->metadata; + info->far_ptr = & ((X_NurbsTextureCoordinate *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -5721,80 +9644,180 @@ static GF_Err Normal_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Normal_get_field_index_by_name(char *name) +static s32 NurbsTextureCoordinate_get_field_index_by_name(char *name) { - if (!strcmp("vector", name)) return 0; - if (!strcmp("metadata", name)) return 1; + if (!strcmp("controlPoint", name)) return 0; + if (!strcmp("weight", name)) return 1; + if (!strcmp("uDimension", name)) return 2; + if (!strcmp("uKnot", name)) return 3; + if (!strcmp("uOrder", name)) return 4; + if (!strcmp("vDimension", name)) return 5; + if (!strcmp("vKnot", name)) return 6; + if (!strcmp("vOrder", name)) return 7; + if (!strcmp("metadata", name)) return 8; return -1; } -static GF_Node *Normal_Create() +static GF_Node *NurbsTextureCoordinate_Create() { - X_Normal *p; - GF_SAFEALLOC(p, X_Normal); + X_NurbsTextureCoordinate *p; + GF_SAFEALLOC(p, X_NurbsTextureCoordinate); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_Normal); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsTextureCoordinate); /*default field values*/ + p->uDimension = 0; + p->uOrder = 3; + p->vDimension = 0; + p->vOrder = 3; return (GF_Node *)p; } /* - NormalInterpolator Node deletion + NurbsTrimmedSurface Node deletion */ -static void NormalInterpolator_Del(GF_Node *node) +static void NurbsTrimmedSurface_Del(GF_Node *node) { - X_NormalInterpolator *p = (X_NormalInterpolator *) node; - gf_sg_mffloat_del(p->key); - gf_sg_mfvec3f_del(p->keyValue); - gf_sg_mfvec3f_del(p->value_changed); + X_NurbsTrimmedSurface *p = (X_NurbsTrimmedSurface *) node; + gf_node_unregister_children(node, p->addTrimmingContour); + gf_node_unregister_children(node, p->removeTrimmingContour); + gf_node_unregister_children(node, p->trimmingContour); + gf_node_unregister((GF_Node *) p->controlPoint, node); + gf_node_unregister((GF_Node *) p->texCoord, node); + gf_sg_mfdouble_del(p->weight); + gf_sg_mfdouble_del(p->uKnot); + gf_sg_mfdouble_del(p->vKnot); gf_node_unregister((GF_Node *) p->metadata, node); gf_node_free((GF_Node *)p); } -static u32 NormalInterpolator_get_field_count(GF_Node *node, u8 dummy) +static u32 NurbsTrimmedSurface_get_field_count(GF_Node *node, u8 dummy) { - return 5; + return 18; } -static GF_Err NormalInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) +static GF_Err NurbsTrimmedSurface_get_field(GF_Node *node, GF_FieldInfo *info) { switch (info->fieldIndex) { case 0: - info->name = "set_fraction"; + info->name = "addTrimmingContour"; info->eventType = GF_SG_EVENT_IN; - info->on_event_in = ((X_NormalInterpolator *)node)->on_set_fraction; - info->fieldType = GF_SG_VRML_SFFLOAT; - info->far_ptr = & ((X_NormalInterpolator *) node)->set_fraction; + info->on_event_in = ((X_NurbsTrimmedSurface *)node)->on_addTrimmingContour; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFNurbsControlCurveNode; + info->far_ptr = & ((X_NurbsTrimmedSurface *)node)->addTrimmingContour; return GF_OK; case 1: - info->name = "key"; - info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFFLOAT; - info->far_ptr = & ((X_NormalInterpolator *) node)->key; + info->name = "removeTrimmingContour"; + info->eventType = GF_SG_EVENT_IN; + info->on_event_in = ((X_NurbsTrimmedSurface *)node)->on_removeTrimmingContour; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFNurbsControlCurveNode; + info->far_ptr = & ((X_NurbsTrimmedSurface *)node)->removeTrimmingContour; return GF_OK; case 2: - info->name = "keyValue"; + info->name = "trimmingContour"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((X_NormalInterpolator *) node)->keyValue; + info->fieldType = GF_SG_VRML_MFNODE; + info->NDTtype = NDT_SFNurbsControlCurveNode; + info->far_ptr = & ((X_NurbsTrimmedSurface *)node)->trimmingContour; + return GF_OK; + case 3: + info->name = "controlPoint"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFCoordinateNode; + info->far_ptr = & ((X_NurbsTrimmedSurface *)node)->controlPoint; + return GF_OK; + case 4: + info->name = "texCoord"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFTextureCoordinateNode; + info->far_ptr = & ((X_NurbsTrimmedSurface *)node)->texCoord; + return GF_OK; + case 5: + info->name = "uTessellation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->uTessellation; + return GF_OK; + case 6: + info->name = "vTessellation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->vTessellation; + return GF_OK; + case 7: + info->name = "weight"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->weight; + return GF_OK; + case 8: + info->name = "solid"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->solid; + return GF_OK; + case 9: + info->name = "uClosed"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->uClosed; + return GF_OK; + case 10: + info->name = "uDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->uDimension; + return GF_OK; + case 11: + info->name = "uKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->uKnot; + return GF_OK; + case 12: + info->name = "uOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->uOrder; + return GF_OK; + case 13: + info->name = "vClosed"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->vClosed; + return GF_OK; + case 14: + info->name = "vDimension"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->vDimension; return GF_OK; - case 3: - info->name = "value_changed"; - info->eventType = GF_SG_EVENT_OUT; - info->fieldType = GF_SG_VRML_MFVEC3F; - info->far_ptr = & ((X_NormalInterpolator *) node)->value_changed; + case 15: + info->name = "vKnot"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_MFDOUBLE; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->vKnot; return GF_OK; - case 4: + case 16: + info->name = "vOrder"; + info->eventType = GF_SG_EVENT_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_NurbsTrimmedSurface *) node)->vOrder; + return GF_OK; + case 17: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_NormalInterpolator *)node)->metadata; + info->far_ptr = & ((X_NurbsTrimmedSurface *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -5802,25 +9825,45 @@ static GF_Err NormalInterpolator_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 NormalInterpolator_get_field_index_by_name(char *name) +static s32 NurbsTrimmedSurface_get_field_index_by_name(char *name) { - if (!strcmp("set_fraction", name)) return 0; - if (!strcmp("key", name)) return 1; - if (!strcmp("keyValue", name)) return 2; - if (!strcmp("value_changed", name)) return 3; - if (!strcmp("metadata", name)) return 4; + if (!strcmp("addTrimmingContour", name)) return 0; + if (!strcmp("removeTrimmingContour", name)) return 1; + if (!strcmp("trimmingContour", name)) return 2; + if (!strcmp("controlPoint", name)) return 3; + if (!strcmp("texCoord", name)) return 4; + if (!strcmp("uTessellation", name)) return 5; + if (!strcmp("vTessellation", name)) return 6; + if (!strcmp("weight", name)) return 7; + if (!strcmp("solid", name)) return 8; + if (!strcmp("uClosed", name)) return 9; + if (!strcmp("uDimension", name)) return 10; + if (!strcmp("uKnot", name)) return 11; + if (!strcmp("uOrder", name)) return 12; + if (!strcmp("vClosed", name)) return 13; + if (!strcmp("vDimension", name)) return 14; + if (!strcmp("vKnot", name)) return 15; + if (!strcmp("vOrder", name)) return 16; + if (!strcmp("metadata", name)) return 17; return -1; } -static GF_Node *NormalInterpolator_Create() +static GF_Node *NurbsTrimmedSurface_Create() { - X_NormalInterpolator *p; - GF_SAFEALLOC(p, X_NormalInterpolator); + X_NurbsTrimmedSurface *p; + GF_SAFEALLOC(p, X_NurbsTrimmedSurface); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_NormalInterpolator); + gf_node_setup((GF_Node *)p, TAG_X3D_NurbsTrimmedSurface); /*default field values*/ + p->uTessellation = 0; + p->vTessellation = 0; + p->solid = 1; + p->uDimension = 0; + p->uOrder = 3; + p->vDimension = 0; + p->vOrder = 3; return (GF_Node *)p; } @@ -6708,6 +10751,255 @@ static GF_Node *ProximitySensor_Create() } +/* + ReceiverPdu Node deletion +*/ + +static void ReceiverPdu_Del(GF_Node *node) +{ + X_ReceiverPdu *p = (X_ReceiverPdu *) node; + gf_sg_sfstring_del(p->address); + gf_sg_sfstring_del(p->multicastRelayHost); + gf_sg_sfstring_del(p->networkMode); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 ReceiverPdu_get_field_count(GF_Node *node, u8 dummy) +{ + return 26; +} + +static GF_Err ReceiverPdu_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "address"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_ReceiverPdu *) node)->address; + return GF_OK; + case 1: + info->name = "applicationID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->applicationID; + return GF_OK; + case 2: + info->name = "entityID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->entityID; + return GF_OK; + case 3: + info->name = "multicastRelayHost"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_ReceiverPdu *) node)->multicastRelayHost; + return GF_OK; + case 4: + info->name = "multicastRelayPort"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->multicastRelayPort; + return GF_OK; + case 5: + info->name = "networkMode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_ReceiverPdu *) node)->networkMode; + return GF_OK; + case 6: + info->name = "port"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->port; + return GF_OK; + case 7: + info->name = "radioID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->radioID; + return GF_OK; + case 8: + info->name = "readInterval"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_ReceiverPdu *) node)->readInterval; + return GF_OK; + case 9: + info->name = "receivedPower"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_ReceiverPdu *) node)->receivedPower; + return GF_OK; + case 10: + info->name = "receiverState"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->receiverState; + return GF_OK; + case 11: + info->name = "rtpHeaderExpected"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_ReceiverPdu *) node)->rtpHeaderExpected; + return GF_OK; + case 12: + info->name = "siteID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->siteID; + return GF_OK; + case 13: + info->name = "transmitterApplicationID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->transmitterApplicationID; + return GF_OK; + case 14: + info->name = "transmitterEntityID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->transmitterEntityID; + return GF_OK; + case 15: + info->name = "transmitterRadioID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->transmitterRadioID; + return GF_OK; + case 16: + info->name = "transmitterSiteID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->transmitterSiteID; + return GF_OK; + case 17: + info->name = "whichGeometry"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_ReceiverPdu *) node)->whichGeometry; + return GF_OK; + case 18: + info->name = "writeInterval"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_ReceiverPdu *) node)->writeInterval; + return GF_OK; + case 19: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_ReceiverPdu *) node)->isActive; + return GF_OK; + case 20: + info->name = "isNetworkReader"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_ReceiverPdu *) node)->isNetworkReader; + return GF_OK; + case 21: + info->name = "isNetworkWriter"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_ReceiverPdu *) node)->isNetworkWriter; + return GF_OK; + case 22: + info->name = "isRtpHeaderHeard"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_ReceiverPdu *) node)->isRtpHeaderHeard; + return GF_OK; + case 23: + info->name = "isStandAlone"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_ReceiverPdu *) node)->isStandAlone; + return GF_OK; + case 24: + info->name = "timestamp"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_ReceiverPdu *) node)->timestamp; + return GF_OK; + case 25: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_ReceiverPdu *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 ReceiverPdu_get_field_index_by_name(char *name) +{ + if (!strcmp("address", name)) return 0; + if (!strcmp("applicationID", name)) return 1; + if (!strcmp("entityID", name)) return 2; + if (!strcmp("multicastRelayHost", name)) return 3; + if (!strcmp("multicastRelayPort", name)) return 4; + if (!strcmp("networkMode", name)) return 5; + if (!strcmp("port", name)) return 6; + if (!strcmp("radioID", name)) return 7; + if (!strcmp("readInterval", name)) return 8; + if (!strcmp("receivedPower", name)) return 9; + if (!strcmp("receiverState", name)) return 10; + if (!strcmp("rtpHeaderExpected", name)) return 11; + if (!strcmp("siteID", name)) return 12; + if (!strcmp("transmitterApplicationID", name)) return 13; + if (!strcmp("transmitterEntityID", name)) return 14; + if (!strcmp("transmitterRadioID", name)) return 15; + if (!strcmp("transmitterSiteID", name)) return 16; + if (!strcmp("whichGeometry", name)) return 17; + if (!strcmp("writeInterval", name)) return 18; + if (!strcmp("isActive", name)) return 19; + if (!strcmp("isNetworkReader", name)) return 20; + if (!strcmp("isNetworkWriter", name)) return 21; + if (!strcmp("isRtpHeaderHeard", name)) return 22; + if (!strcmp("isStandAlone", name)) return 23; + if (!strcmp("timestamp", name)) return 24; + if (!strcmp("metadata", name)) return 25; + return -1; + } + + +static GF_Node *ReceiverPdu_Create() +{ + X_ReceiverPdu *p; + GF_SAFEALLOC(p, X_ReceiverPdu); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_ReceiverPdu); + + /*default field values*/ + p->address.buffer = (char*) gf_malloc(sizeof(char) * 10); + strcpy(p->address.buffer, "localhost"); + p->applicationID = 1; + p->entityID = 0; + p->multicastRelayPort = 0; + p->networkMode.buffer = (char*) gf_malloc(sizeof(char) * 11); + strcpy(p->networkMode.buffer, "standAlone"); + p->port = 0; + p->radioID = 0; + p->readInterval = FLT2FIX(0.1); + p->receivedPower = FLT2FIX(0.0); + p->receiverState = 0; + p->siteID = 0; + p->transmitterApplicationID = 1; + p->transmitterEntityID = 0; + p->transmitterRadioID = 0; + p->transmitterSiteID = 0; + p->whichGeometry = 1; + p->writeInterval = FLT2FIX(1.0); + return (GF_Node *)p; +} + + /* Rectangle2D Node deletion */ @@ -6951,23 +11243,231 @@ static GF_Err Shape_get_field(GF_Node *node, GF_FieldInfo *info) case 0: info->name = "appearance"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFAppearanceNode; - info->far_ptr = & ((X_Shape *)node)->appearance; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFAppearanceNode; + info->far_ptr = & ((X_Shape *)node)->appearance; + return GF_OK; + case 1: + info->name = "geometry"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFGeometryNode; + info->far_ptr = & ((X_Shape *)node)->geometry; + return GF_OK; + case 2: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_Shape *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 Shape_get_field_index_by_name(char *name) +{ + if (!strcmp("appearance", name)) return 0; + if (!strcmp("geometry", name)) return 1; + if (!strcmp("metadata", name)) return 2; + return -1; + } + + +static GF_Node *Shape_Create() +{ + X_Shape *p; + GF_SAFEALLOC(p, X_Shape); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_Shape); + + /*default field values*/ + return (GF_Node *)p; +} + + +/* + SignalPdu Node deletion +*/ + +static void SignalPdu_Del(GF_Node *node) +{ + X_SignalPdu *p = (X_SignalPdu *) node; + gf_sg_sfstring_del(p->address); + gf_sg_mfint32_del(p->data); + gf_sg_sfstring_del(p->multicastRelayHost); + gf_sg_sfstring_del(p->networkMode); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 SignalPdu_get_field_count(GF_Node *node, u8 dummy) +{ + return 26; +} + +static GF_Err SignalPdu_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "address"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_SignalPdu *) node)->address; + return GF_OK; + case 1: + info->name = "applicationID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->applicationID; + return GF_OK; + case 2: + info->name = "data"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_MFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->data; + return GF_OK; + case 3: + info->name = "dataLength"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->dataLength; + return GF_OK; + case 4: + info->name = "encodingScheme"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->encodingScheme; + return GF_OK; + case 5: + info->name = "entityID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->entityID; + return GF_OK; + case 6: + info->name = "multicastRelayHost"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_SignalPdu *) node)->multicastRelayHost; + return GF_OK; + case 7: + info->name = "multicastRelayPort"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->multicastRelayPort; + return GF_OK; + case 8: + info->name = "networkMode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_SignalPdu *) node)->networkMode; + return GF_OK; + case 9: + info->name = "port"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->port; return GF_OK; - case 1: - info->name = "geometry"; + case 10: + info->name = "radioID"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; - info->fieldType = GF_SG_VRML_SFNODE; - info->NDTtype = NDT_SFGeometryNode; - info->far_ptr = & ((X_Shape *)node)->geometry; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->radioID; return GF_OK; - case 2: + case 11: + info->name = "readInterval"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_SignalPdu *) node)->readInterval; + return GF_OK; + case 12: + info->name = "rtpHeaderExpected"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_SignalPdu *) node)->rtpHeaderExpected; + return GF_OK; + case 13: + info->name = "sampleRate"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->sampleRate; + return GF_OK; + case 14: + info->name = "samples"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->samples; + return GF_OK; + case 15: + info->name = "siteID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->siteID; + return GF_OK; + case 16: + info->name = "tdlType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->tdlType; + return GF_OK; + case 17: + info->name = "whichGeometry"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_SignalPdu *) node)->whichGeometry; + return GF_OK; + case 18: + info->name = "writeInterval"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_SignalPdu *) node)->writeInterval; + return GF_OK; + case 19: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_SignalPdu *) node)->isActive; + return GF_OK; + case 20: + info->name = "isNetworkReader"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_SignalPdu *) node)->isNetworkReader; + return GF_OK; + case 21: + info->name = "isNetworkWriter"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_SignalPdu *) node)->isNetworkWriter; + return GF_OK; + case 22: + info->name = "isRtpHeaderHeard"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_SignalPdu *) node)->isRtpHeaderHeard; + return GF_OK; + case 23: + info->name = "isStandAlone"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_SignalPdu *) node)->isStandAlone; + return GF_OK; + case 24: + info->name = "timestamp"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_SignalPdu *) node)->timestamp; + return GF_OK; + case 25: info->name = "metadata"; info->eventType = GF_SG_EVENT_EXPOSED_FIELD; info->fieldType = GF_SG_VRML_SFNODE; info->NDTtype = NDT_SFMetadataNode; - info->far_ptr = & ((X_Shape *)node)->metadata; + info->far_ptr = & ((X_SignalPdu *)node)->metadata; return GF_OK; default: return GF_BAD_PARAM; @@ -6975,23 +11475,64 @@ static GF_Err Shape_get_field(GF_Node *node, GF_FieldInfo *info) } -static s32 Shape_get_field_index_by_name(char *name) -{ - if (!strcmp("appearance", name)) return 0; - if (!strcmp("geometry", name)) return 1; - if (!strcmp("metadata", name)) return 2; +static s32 SignalPdu_get_field_index_by_name(char *name) +{ + if (!strcmp("address", name)) return 0; + if (!strcmp("applicationID", name)) return 1; + if (!strcmp("data", name)) return 2; + if (!strcmp("dataLength", name)) return 3; + if (!strcmp("encodingScheme", name)) return 4; + if (!strcmp("entityID", name)) return 5; + if (!strcmp("multicastRelayHost", name)) return 6; + if (!strcmp("multicastRelayPort", name)) return 7; + if (!strcmp("networkMode", name)) return 8; + if (!strcmp("port", name)) return 9; + if (!strcmp("radioID", name)) return 10; + if (!strcmp("readInterval", name)) return 11; + if (!strcmp("rtpHeaderExpected", name)) return 12; + if (!strcmp("sampleRate", name)) return 13; + if (!strcmp("samples", name)) return 14; + if (!strcmp("siteID", name)) return 15; + if (!strcmp("tdlType", name)) return 16; + if (!strcmp("whichGeometry", name)) return 17; + if (!strcmp("writeInterval", name)) return 18; + if (!strcmp("isActive", name)) return 19; + if (!strcmp("isNetworkReader", name)) return 20; + if (!strcmp("isNetworkWriter", name)) return 21; + if (!strcmp("isRtpHeaderHeard", name)) return 22; + if (!strcmp("isStandAlone", name)) return 23; + if (!strcmp("timestamp", name)) return 24; + if (!strcmp("metadata", name)) return 25; return -1; } -static GF_Node *Shape_Create() +static GF_Node *SignalPdu_Create() { - X_Shape *p; - GF_SAFEALLOC(p, X_Shape); + X_SignalPdu *p; + GF_SAFEALLOC(p, X_SignalPdu); if(!p) return NULL; - gf_node_setup((GF_Node *)p, TAG_X3D_Shape); + gf_node_setup((GF_Node *)p, TAG_X3D_SignalPdu); /*default field values*/ + p->address.buffer = (char*) gf_malloc(sizeof(char) * 10); + strcpy(p->address.buffer, "localhost"); + p->applicationID = 1; + p->dataLength = 0; + p->encodingScheme = 0; + p->entityID = 0; + p->multicastRelayPort = 0; + p->networkMode.buffer = (char*) gf_malloc(sizeof(char) * 11); + strcpy(p->networkMode.buffer, "standAlone"); + p->port = 0; + p->radioID = 0; + p->readInterval = FLT2FIX(0.1); + p->sampleRate = 0; + p->samples = 0; + p->siteID = 0; + p->tdlType = 0; + p->whichGeometry = 1; + p->writeInterval = FLT2FIX(1.0); return (GF_Node *)p; } @@ -7938,12 +12479,12 @@ static GF_Node *TextureBackground_Create() gf_node_setup((GF_Node *)p, TAG_X3D_TextureBackground); /*default field values*/ - p->skyColor.vals = (SFColor*)malloc(sizeof(SFColor)*1); + p->skyColor.vals = (SFColor*)gf_malloc(sizeof(SFColor)*1); p->skyColor.count = 1; p->skyColor.vals[0].red = FLT2FIX(0); p->skyColor.vals[0].green = FLT2FIX(0); p->skyColor.vals[0].blue = FLT2FIX(0); - p->transparency.vals = (SFFloat *)malloc(sizeof(SFFloat)*1); + p->transparency.vals = (SFFloat *)gf_malloc(sizeof(SFFloat)*1); p->transparency.count = 1; p->transparency.vals[0] = FLT2FIX(0); return (GF_Node *)p; @@ -8074,7 +12615,7 @@ static GF_Node *TextureCoordinateGenerator_Create() gf_node_setup((GF_Node *)p, TAG_X3D_TextureCoordinateGenerator); /*default field values*/ - p->mode.buffer = (char*) malloc(sizeof(char) * 7); + p->mode.buffer = (char*) gf_malloc(sizeof(char) * 7); strcpy(p->mode.buffer, "SPHERE"); return (GF_Node *)p; } @@ -8625,6 +13166,387 @@ static GF_Node *Transform_Create() } +/* + TransmitterPdu Node deletion +*/ + +static void TransmitterPdu_Del(GF_Node *node) +{ + X_TransmitterPdu *p = (X_TransmitterPdu *) node; + gf_sg_sfstring_del(p->address); + gf_sg_sfstring_del(p->multicastRelayHost); + gf_sg_sfstring_del(p->networkMode); + gf_node_unregister((GF_Node *) p->metadata, node); + gf_node_free((GF_Node *)p); +} + + +static u32 TransmitterPdu_get_field_count(GF_Node *node, u8 dummy) +{ + return 42; +} + +static GF_Err TransmitterPdu_get_field(GF_Node *node, GF_FieldInfo *info) +{ + switch (info->fieldIndex) { + case 0: + info->name = "address"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_TransmitterPdu *) node)->address; + return GF_OK; + case 1: + info->name = "antennaLocation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_TransmitterPdu *) node)->antennaLocation; + return GF_OK; + case 2: + info->name = "antennaPatternLength"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->antennaPatternLength; + return GF_OK; + case 3: + info->name = "antennaPatternType"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->antennaPatternType; + return GF_OK; + case 4: + info->name = "applicationID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->applicationID; + return GF_OK; + case 5: + info->name = "cryptoKeyID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->cryptoKeyID; + return GF_OK; + case 6: + info->name = "cryptoSystem"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->cryptoSystem; + return GF_OK; + case 7: + info->name = "entityID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->entityID; + return GF_OK; + case 8: + info->name = "frequency"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->frequency; + return GF_OK; + case 9: + info->name = "inputSource"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->inputSource; + return GF_OK; + case 10: + info->name = "lengthOfModulationParameters"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->lengthOfModulationParameters; + return GF_OK; + case 11: + info->name = "modulationTypeDetail"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->modulationTypeDetail; + return GF_OK; + case 12: + info->name = "modulationTypeMajor"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->modulationTypeMajor; + return GF_OK; + case 13: + info->name = "modulationTypeSpreadSpectrum"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->modulationTypeSpreadSpectrum; + return GF_OK; + case 14: + info->name = "modulationTypeSystem"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->modulationTypeSystem; + return GF_OK; + case 15: + info->name = "multicastRelayHost"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_TransmitterPdu *) node)->multicastRelayHost; + return GF_OK; + case 16: + info->name = "multicastRelayPort"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->multicastRelayPort; + return GF_OK; + case 17: + info->name = "networkMode"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFSTRING; + info->far_ptr = & ((X_TransmitterPdu *) node)->networkMode; + return GF_OK; + case 18: + info->name = "port"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->port; + return GF_OK; + case 19: + info->name = "power"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_TransmitterPdu *) node)->power; + return GF_OK; + case 20: + info->name = "radioEntityTypeCategory"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->radioEntityTypeCategory; + return GF_OK; + case 21: + info->name = "radioEntityTypeCountry"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->radioEntityTypeCountry; + return GF_OK; + case 22: + info->name = "radioEntityTypeDomain"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->radioEntityTypeDomain; + return GF_OK; + case 23: + info->name = "radioEntityTypeKind"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->radioEntityTypeKind; + return GF_OK; + case 24: + info->name = "radioEntityTypeNomenclature"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->radioEntityTypeNomenclature; + return GF_OK; + case 25: + info->name = "radioEntityTypeNomenclatureVersion"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->radioEntityTypeNomenclatureVersion; + return GF_OK; + case 26: + info->name = "radioID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->radioID; + return GF_OK; + case 27: + info->name = "readInterval"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_TransmitterPdu *) node)->readInterval; + return GF_OK; + case 28: + info->name = "relativeAntennaLocation"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFVEC3F; + info->far_ptr = & ((X_TransmitterPdu *) node)->relativeAntennaLocation; + return GF_OK; + case 29: + info->name = "rtpHeaderExpected"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_TransmitterPdu *) node)->rtpHeaderExpected; + return GF_OK; + case 30: + info->name = "siteID"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->siteID; + return GF_OK; + case 31: + info->name = "transmitFrequencyBandwidth"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_TransmitterPdu *) node)->transmitFrequencyBandwidth; + return GF_OK; + case 32: + info->name = "transmitState"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->transmitState; + return GF_OK; + case 33: + info->name = "whichGeometry"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFINT32; + info->far_ptr = & ((X_TransmitterPdu *) node)->whichGeometry; + return GF_OK; + case 34: + info->name = "writeInterval"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFFLOAT; + info->far_ptr = & ((X_TransmitterPdu *) node)->writeInterval; + return GF_OK; + case 35: + info->name = "isActive"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_TransmitterPdu *) node)->isActive; + return GF_OK; + case 36: + info->name = "isNetworkReader"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_TransmitterPdu *) node)->isNetworkReader; + return GF_OK; + case 37: + info->name = "isNetworkWriter"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_TransmitterPdu *) node)->isNetworkWriter; + return GF_OK; + case 38: + info->name = "isRtpHeaderHeard"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_TransmitterPdu *) node)->isRtpHeaderHeard; + return GF_OK; + case 39: + info->name = "isStandAlone"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFBOOL; + info->far_ptr = & ((X_TransmitterPdu *) node)->isStandAlone; + return GF_OK; + case 40: + info->name = "timestamp"; + info->eventType = GF_SG_EVENT_OUT; + info->fieldType = GF_SG_VRML_SFTIME; + info->far_ptr = & ((X_TransmitterPdu *) node)->timestamp; + return GF_OK; + case 41: + info->name = "metadata"; + info->eventType = GF_SG_EVENT_EXPOSED_FIELD; + info->fieldType = GF_SG_VRML_SFNODE; + info->NDTtype = NDT_SFMetadataNode; + info->far_ptr = & ((X_TransmitterPdu *)node)->metadata; + return GF_OK; + default: + return GF_BAD_PARAM; + } +} + + +static s32 TransmitterPdu_get_field_index_by_name(char *name) +{ + if (!strcmp("address", name)) return 0; + if (!strcmp("antennaLocation", name)) return 1; + if (!strcmp("antennaPatternLength", name)) return 2; + if (!strcmp("antennaPatternType", name)) return 3; + if (!strcmp("applicationID", name)) return 4; + if (!strcmp("cryptoKeyID", name)) return 5; + if (!strcmp("cryptoSystem", name)) return 6; + if (!strcmp("entityID", name)) return 7; + if (!strcmp("frequency", name)) return 8; + if (!strcmp("inputSource", name)) return 9; + if (!strcmp("lengthOfModulationParameters", name)) return 10; + if (!strcmp("modulationTypeDetail", name)) return 11; + if (!strcmp("modulationTypeMajor", name)) return 12; + if (!strcmp("modulationTypeSpreadSpectrum", name)) return 13; + if (!strcmp("modulationTypeSystem", name)) return 14; + if (!strcmp("multicastRelayHost", name)) return 15; + if (!strcmp("multicastRelayPort", name)) return 16; + if (!strcmp("networkMode", name)) return 17; + if (!strcmp("port", name)) return 18; + if (!strcmp("power", name)) return 19; + if (!strcmp("radioEntityTypeCategory", name)) return 20; + if (!strcmp("radioEntityTypeCountry", name)) return 21; + if (!strcmp("radioEntityTypeDomain", name)) return 22; + if (!strcmp("radioEntityTypeKind", name)) return 23; + if (!strcmp("radioEntityTypeNomenclature", name)) return 24; + if (!strcmp("radioEntityTypeNomenclatureVersion", name)) return 25; + if (!strcmp("radioID", name)) return 26; + if (!strcmp("readInterval", name)) return 27; + if (!strcmp("relativeAntennaLocation", name)) return 28; + if (!strcmp("rtpHeaderExpected", name)) return 29; + if (!strcmp("siteID", name)) return 30; + if (!strcmp("transmitFrequencyBandwidth", name)) return 31; + if (!strcmp("transmitState", name)) return 32; + if (!strcmp("whichGeometry", name)) return 33; + if (!strcmp("writeInterval", name)) return 34; + if (!strcmp("isActive", name)) return 35; + if (!strcmp("isNetworkReader", name)) return 36; + if (!strcmp("isNetworkWriter", name)) return 37; + if (!strcmp("isRtpHeaderHeard", name)) return 38; + if (!strcmp("isStandAlone", name)) return 39; + if (!strcmp("timestamp", name)) return 40; + if (!strcmp("metadata", name)) return 41; + return -1; + } + + +static GF_Node *TransmitterPdu_Create() +{ + X_TransmitterPdu *p; + GF_SAFEALLOC(p, X_TransmitterPdu); + if(!p) return NULL; + gf_node_setup((GF_Node *)p, TAG_X3D_TransmitterPdu); + + /*default field values*/ + p->address.buffer = (char*) gf_malloc(sizeof(char) * 10); + strcpy(p->address.buffer, "localhost"); + p->antennaLocation.x = FLT2FIX(0); + p->antennaLocation.y = FLT2FIX(0); + p->antennaLocation.z = FLT2FIX(0); + p->antennaPatternLength = 0; + p->antennaPatternType = 0; + p->applicationID = 1; + p->cryptoKeyID = 0; + p->cryptoSystem = 0; + p->entityID = 0; + p->frequency = 0; + p->inputSource = 0; + p->lengthOfModulationParameters = 0; + p->modulationTypeDetail = 0; + p->modulationTypeMajor = 0; + p->modulationTypeSpreadSpectrum = 0; + p->modulationTypeSystem = 0; + p->multicastRelayPort = 0; + p->networkMode.buffer = (char*) gf_malloc(sizeof(char) * 11); + strcpy(p->networkMode.buffer, "standAlone"); + p->port = 0; + p->power = FLT2FIX(0.0); + p->radioEntityTypeCategory = 0; + p->radioEntityTypeCountry = 0; + p->radioEntityTypeDomain = 0; + p->radioEntityTypeKind = 0; + p->radioEntityTypeNomenclature = 0; + p->radioEntityTypeNomenclatureVersion = 0; + p->radioID = 0; + p->readInterval = FLT2FIX(0.1); + p->relativeAntennaLocation.x = FLT2FIX(0); + p->relativeAntennaLocation.y = FLT2FIX(0); + p->relativeAntennaLocation.z = FLT2FIX(0); + p->siteID = 0; + p->transmitFrequencyBandwidth = FLT2FIX(0.0); + p->transmitState = 0; + p->whichGeometry = 1; + p->writeInterval = FLT2FIX(1.0); + return (GF_Node *)p; +} + + /* TriangleFanSet Node deletion */ @@ -9424,6 +14346,8 @@ GF_Node *gf_sg_x3d_node_new(u32 NodeTag) return Disk2D_Create(); case TAG_X3D_ElevationGrid: return ElevationGrid_Create(); + case TAG_X3D_EspduTransform: + return EspduTransform_Create(); case TAG_X3D_Extrusion: return Extrusion_Create(); case TAG_X3D_FillProperties: @@ -9432,8 +14356,36 @@ GF_Node *gf_sg_x3d_node_new(u32 NodeTag) return Fog_Create(); case TAG_X3D_FontStyle: return FontStyle_Create(); + case TAG_X3D_GeoCoordinate: + return GeoCoordinate_Create(); + case TAG_X3D_GeoElevationGrid: + return GeoElevationGrid_Create(); + case TAG_X3D_GeoLocation: + return GeoLocation_Create(); + case TAG_X3D_GeoLOD: + return GeoLOD_Create(); + case TAG_X3D_GeoMetadata: + return GeoMetadata_Create(); + case TAG_X3D_GeoOrigin: + return GeoOrigin_Create(); + case TAG_X3D_GeoPositionInterpolator: + return GeoPositionInterpolator_Create(); + case TAG_X3D_GeoTouchSensor: + return GeoTouchSensor_Create(); + case TAG_X3D_GeoViewpoint: + return GeoViewpoint_Create(); case TAG_X3D_Group: return Group_Create(); + case TAG_X3D_HAnimDisplacer: + return HAnimDisplacer_Create(); + case TAG_X3D_HAnimHumanoid: + return HAnimHumanoid_Create(); + case TAG_X3D_HAnimJoint: + return HAnimJoint_Create(); + case TAG_X3D_HAnimSegment: + return HAnimSegment_Create(); + case TAG_X3D_HAnimSite: + return HAnimSite_Create(); case TAG_X3D_ImageTexture: return ImageTexture_Create(); case TAG_X3D_IndexedFaceSet: @@ -9458,6 +14410,8 @@ GF_Node *gf_sg_x3d_node_new(u32 NodeTag) return LineProperties_Create(); case TAG_X3D_LineSet: return LineSet_Create(); + case TAG_X3D_LoadSensor: + return LoadSensor_Create(); case TAG_X3D_LOD: return LOD_Create(); case TAG_X3D_Material: @@ -9486,6 +14440,28 @@ GF_Node *gf_sg_x3d_node_new(u32 NodeTag) return Normal_Create(); case TAG_X3D_NormalInterpolator: return NormalInterpolator_Create(); + case TAG_X3D_NurbsCurve: + return NurbsCurve_Create(); + case TAG_X3D_NurbsCurve2D: + return NurbsCurve2D_Create(); + case TAG_X3D_NurbsOrientationInterpolator: + return NurbsOrientationInterpolator_Create(); + case TAG_X3D_NurbsPatchSurface: + return NurbsPatchSurface_Create(); + case TAG_X3D_NurbsPositionInterpolator: + return NurbsPositionInterpolator_Create(); + case TAG_X3D_NurbsSet: + return NurbsSet_Create(); + case TAG_X3D_NurbsSurfaceInterpolator: + return NurbsSurfaceInterpolator_Create(); + case TAG_X3D_NurbsSweptSurface: + return NurbsSweptSurface_Create(); + case TAG_X3D_NurbsSwungSurface: + return NurbsSwungSurface_Create(); + case TAG_X3D_NurbsTextureCoordinate: + return NurbsTextureCoordinate_Create(); + case TAG_X3D_NurbsTrimmedSurface: + return NurbsTrimmedSurface_Create(); case TAG_X3D_OrientationInterpolator: return OrientationInterpolator_Create(); case TAG_X3D_PixelTexture: @@ -9506,6 +14482,8 @@ GF_Node *gf_sg_x3d_node_new(u32 NodeTag) return PositionInterpolator2D_Create(); case TAG_X3D_ProximitySensor: return ProximitySensor_Create(); + case TAG_X3D_ReceiverPdu: + return ReceiverPdu_Create(); case TAG_X3D_Rectangle2D: return Rectangle2D_Create(); case TAG_X3D_ScalarInterpolator: @@ -9514,6 +14492,8 @@ GF_Node *gf_sg_x3d_node_new(u32 NodeTag) return Script_Create(); case TAG_X3D_Shape: return Shape_Create(); + case TAG_X3D_SignalPdu: + return SignalPdu_Create(); case TAG_X3D_Sound: return Sound_Create(); case TAG_X3D_Sphere: @@ -9546,6 +14526,8 @@ GF_Node *gf_sg_x3d_node_new(u32 NodeTag) return TouchSensor_Create(); case TAG_X3D_Transform: return Transform_Create(); + case TAG_X3D_TransmitterPdu: + return TransmitterPdu_Create(); case TAG_X3D_TriangleFanSet: return TriangleFanSet_Create(); case TAG_X3D_TriangleSet: @@ -9628,6 +14610,8 @@ const char *gf_sg_x3d_node_get_class_name(u32 NodeTag) return "Disk2D"; case TAG_X3D_ElevationGrid: return "ElevationGrid"; + case TAG_X3D_EspduTransform: + return "EspduTransform"; case TAG_X3D_Extrusion: return "Extrusion"; case TAG_X3D_FillProperties: @@ -9636,8 +14620,36 @@ const char *gf_sg_x3d_node_get_class_name(u32 NodeTag) return "Fog"; case TAG_X3D_FontStyle: return "FontStyle"; + case TAG_X3D_GeoCoordinate: + return "GeoCoordinate"; + case TAG_X3D_GeoElevationGrid: + return "GeoElevationGrid"; + case TAG_X3D_GeoLocation: + return "GeoLocation"; + case TAG_X3D_GeoLOD: + return "GeoLOD"; + case TAG_X3D_GeoMetadata: + return "GeoMetadata"; + case TAG_X3D_GeoOrigin: + return "GeoOrigin"; + case TAG_X3D_GeoPositionInterpolator: + return "GeoPositionInterpolator"; + case TAG_X3D_GeoTouchSensor: + return "GeoTouchSensor"; + case TAG_X3D_GeoViewpoint: + return "GeoViewpoint"; case TAG_X3D_Group: return "Group"; + case TAG_X3D_HAnimDisplacer: + return "HAnimDisplacer"; + case TAG_X3D_HAnimHumanoid: + return "HAnimHumanoid"; + case TAG_X3D_HAnimJoint: + return "HAnimJoint"; + case TAG_X3D_HAnimSegment: + return "HAnimSegment"; + case TAG_X3D_HAnimSite: + return "HAnimSite"; case TAG_X3D_ImageTexture: return "ImageTexture"; case TAG_X3D_IndexedFaceSet: @@ -9662,6 +14674,8 @@ const char *gf_sg_x3d_node_get_class_name(u32 NodeTag) return "LineProperties"; case TAG_X3D_LineSet: return "LineSet"; + case TAG_X3D_LoadSensor: + return "LoadSensor"; case TAG_X3D_LOD: return "LOD"; case TAG_X3D_Material: @@ -9690,6 +14704,28 @@ const char *gf_sg_x3d_node_get_class_name(u32 NodeTag) return "Normal"; case TAG_X3D_NormalInterpolator: return "NormalInterpolator"; + case TAG_X3D_NurbsCurve: + return "NurbsCurve"; + case TAG_X3D_NurbsCurve2D: + return "NurbsCurve2D"; + case TAG_X3D_NurbsOrientationInterpolator: + return "NurbsOrientationInterpolator"; + case TAG_X3D_NurbsPatchSurface: + return "NurbsPatchSurface"; + case TAG_X3D_NurbsPositionInterpolator: + return "NurbsPositionInterpolator"; + case TAG_X3D_NurbsSet: + return "NurbsSet"; + case TAG_X3D_NurbsSurfaceInterpolator: + return "NurbsSurfaceInterpolator"; + case TAG_X3D_NurbsSweptSurface: + return "NurbsSweptSurface"; + case TAG_X3D_NurbsSwungSurface: + return "NurbsSwungSurface"; + case TAG_X3D_NurbsTextureCoordinate: + return "NurbsTextureCoordinate"; + case TAG_X3D_NurbsTrimmedSurface: + return "NurbsTrimmedSurface"; case TAG_X3D_OrientationInterpolator: return "OrientationInterpolator"; case TAG_X3D_PixelTexture: @@ -9710,6 +14746,8 @@ const char *gf_sg_x3d_node_get_class_name(u32 NodeTag) return "PositionInterpolator2D"; case TAG_X3D_ProximitySensor: return "ProximitySensor"; + case TAG_X3D_ReceiverPdu: + return "ReceiverPdu"; case TAG_X3D_Rectangle2D: return "Rectangle2D"; case TAG_X3D_ScalarInterpolator: @@ -9718,6 +14756,8 @@ const char *gf_sg_x3d_node_get_class_name(u32 NodeTag) return "Script"; case TAG_X3D_Shape: return "Shape"; + case TAG_X3D_SignalPdu: + return "SignalPdu"; case TAG_X3D_Sound: return "Sound"; case TAG_X3D_Sphere: @@ -9750,6 +14790,8 @@ const char *gf_sg_x3d_node_get_class_name(u32 NodeTag) return "TouchSensor"; case TAG_X3D_Transform: return "Transform"; + case TAG_X3D_TransmitterPdu: + return "TransmitterPdu"; case TAG_X3D_TriangleFanSet: return "TriangleFanSet"; case TAG_X3D_TriangleSet: @@ -9832,6 +14874,8 @@ void gf_sg_x3d_node_del(GF_Node *node) Disk2D_Del(node); return; case TAG_X3D_ElevationGrid: ElevationGrid_Del(node); return; + case TAG_X3D_EspduTransform: + EspduTransform_Del(node); return; case TAG_X3D_Extrusion: Extrusion_Del(node); return; case TAG_X3D_FillProperties: @@ -9840,8 +14884,36 @@ void gf_sg_x3d_node_del(GF_Node *node) Fog_Del(node); return; case TAG_X3D_FontStyle: FontStyle_Del(node); return; + case TAG_X3D_GeoCoordinate: + GeoCoordinate_Del(node); return; + case TAG_X3D_GeoElevationGrid: + GeoElevationGrid_Del(node); return; + case TAG_X3D_GeoLocation: + GeoLocation_Del(node); return; + case TAG_X3D_GeoLOD: + GeoLOD_Del(node); return; + case TAG_X3D_GeoMetadata: + GeoMetadata_Del(node); return; + case TAG_X3D_GeoOrigin: + GeoOrigin_Del(node); return; + case TAG_X3D_GeoPositionInterpolator: + GeoPositionInterpolator_Del(node); return; + case TAG_X3D_GeoTouchSensor: + GeoTouchSensor_Del(node); return; + case TAG_X3D_GeoViewpoint: + GeoViewpoint_Del(node); return; case TAG_X3D_Group: Group_Del(node); return; + case TAG_X3D_HAnimDisplacer: + HAnimDisplacer_Del(node); return; + case TAG_X3D_HAnimHumanoid: + HAnimHumanoid_Del(node); return; + case TAG_X3D_HAnimJoint: + HAnimJoint_Del(node); return; + case TAG_X3D_HAnimSegment: + HAnimSegment_Del(node); return; + case TAG_X3D_HAnimSite: + HAnimSite_Del(node); return; case TAG_X3D_ImageTexture: ImageTexture_Del(node); return; case TAG_X3D_IndexedFaceSet: @@ -9866,6 +14938,8 @@ void gf_sg_x3d_node_del(GF_Node *node) LineProperties_Del(node); return; case TAG_X3D_LineSet: LineSet_Del(node); return; + case TAG_X3D_LoadSensor: + LoadSensor_Del(node); return; case TAG_X3D_LOD: LOD_Del(node); return; case TAG_X3D_Material: @@ -9894,6 +14968,28 @@ void gf_sg_x3d_node_del(GF_Node *node) Normal_Del(node); return; case TAG_X3D_NormalInterpolator: NormalInterpolator_Del(node); return; + case TAG_X3D_NurbsCurve: + NurbsCurve_Del(node); return; + case TAG_X3D_NurbsCurve2D: + NurbsCurve2D_Del(node); return; + case TAG_X3D_NurbsOrientationInterpolator: + NurbsOrientationInterpolator_Del(node); return; + case TAG_X3D_NurbsPatchSurface: + NurbsPatchSurface_Del(node); return; + case TAG_X3D_NurbsPositionInterpolator: + NurbsPositionInterpolator_Del(node); return; + case TAG_X3D_NurbsSet: + NurbsSet_Del(node); return; + case TAG_X3D_NurbsSurfaceInterpolator: + NurbsSurfaceInterpolator_Del(node); return; + case TAG_X3D_NurbsSweptSurface: + NurbsSweptSurface_Del(node); return; + case TAG_X3D_NurbsSwungSurface: + NurbsSwungSurface_Del(node); return; + case TAG_X3D_NurbsTextureCoordinate: + NurbsTextureCoordinate_Del(node); return; + case TAG_X3D_NurbsTrimmedSurface: + NurbsTrimmedSurface_Del(node); return; case TAG_X3D_OrientationInterpolator: OrientationInterpolator_Del(node); return; case TAG_X3D_PixelTexture: @@ -9914,6 +15010,8 @@ void gf_sg_x3d_node_del(GF_Node *node) PositionInterpolator2D_Del(node); return; case TAG_X3D_ProximitySensor: ProximitySensor_Del(node); return; + case TAG_X3D_ReceiverPdu: + ReceiverPdu_Del(node); return; case TAG_X3D_Rectangle2D: Rectangle2D_Del(node); return; case TAG_X3D_ScalarInterpolator: @@ -9922,6 +15020,8 @@ void gf_sg_x3d_node_del(GF_Node *node) Script_Del(node); return; case TAG_X3D_Shape: Shape_Del(node); return; + case TAG_X3D_SignalPdu: + SignalPdu_Del(node); return; case TAG_X3D_Sound: Sound_Del(node); return; case TAG_X3D_Sphere: @@ -9954,6 +15054,8 @@ void gf_sg_x3d_node_del(GF_Node *node) TouchSensor_Del(node); return; case TAG_X3D_Transform: Transform_Del(node); return; + case TAG_X3D_TransmitterPdu: + TransmitterPdu_Del(node); return; case TAG_X3D_TriangleFanSet: TriangleFanSet_Del(node); return; case TAG_X3D_TriangleSet: @@ -10006,11 +15108,26 @@ u32 gf_sg_x3d_node_get_field_count(GF_Node *node) case TAG_X3D_DirectionalLight:return DirectionalLight_get_field_count(node, 0); case TAG_X3D_Disk2D:return Disk2D_get_field_count(node, 0); case TAG_X3D_ElevationGrid:return ElevationGrid_get_field_count(node, 0); + case TAG_X3D_EspduTransform:return EspduTransform_get_field_count(node, 0); case TAG_X3D_Extrusion:return Extrusion_get_field_count(node, 0); case TAG_X3D_FillProperties:return FillProperties_get_field_count(node, 0); case TAG_X3D_Fog:return Fog_get_field_count(node, 0); case TAG_X3D_FontStyle:return FontStyle_get_field_count(node, 0); + case TAG_X3D_GeoCoordinate:return GeoCoordinate_get_field_count(node, 0); + case TAG_X3D_GeoElevationGrid:return GeoElevationGrid_get_field_count(node, 0); + case TAG_X3D_GeoLocation:return GeoLocation_get_field_count(node, 0); + case TAG_X3D_GeoLOD:return GeoLOD_get_field_count(node, 0); + case TAG_X3D_GeoMetadata:return GeoMetadata_get_field_count(node, 0); + case TAG_X3D_GeoOrigin:return GeoOrigin_get_field_count(node, 0); + case TAG_X3D_GeoPositionInterpolator:return GeoPositionInterpolator_get_field_count(node, 0); + case TAG_X3D_GeoTouchSensor:return GeoTouchSensor_get_field_count(node, 0); + case TAG_X3D_GeoViewpoint:return GeoViewpoint_get_field_count(node, 0); case TAG_X3D_Group:return Group_get_field_count(node, 0); + case TAG_X3D_HAnimDisplacer:return HAnimDisplacer_get_field_count(node, 0); + case TAG_X3D_HAnimHumanoid:return HAnimHumanoid_get_field_count(node, 0); + case TAG_X3D_HAnimJoint:return HAnimJoint_get_field_count(node, 0); + case TAG_X3D_HAnimSegment:return HAnimSegment_get_field_count(node, 0); + case TAG_X3D_HAnimSite:return HAnimSite_get_field_count(node, 0); case TAG_X3D_ImageTexture:return ImageTexture_get_field_count(node, 0); case TAG_X3D_IndexedFaceSet:return IndexedFaceSet_get_field_count(node, 0); case TAG_X3D_IndexedLineSet:return IndexedLineSet_get_field_count(node, 0); @@ -10023,6 +15140,7 @@ u32 gf_sg_x3d_node_get_field_count(GF_Node *node) case TAG_X3D_KeySensor:return KeySensor_get_field_count(node, 0); case TAG_X3D_LineProperties:return LineProperties_get_field_count(node, 0); case TAG_X3D_LineSet:return LineSet_get_field_count(node, 0); + case TAG_X3D_LoadSensor:return LoadSensor_get_field_count(node, 0); case TAG_X3D_LOD:return LOD_get_field_count(node, 0); case TAG_X3D_Material:return Material_get_field_count(node, 0); case TAG_X3D_MetadataDouble:return MetadataDouble_get_field_count(node, 0); @@ -10037,6 +15155,17 @@ u32 gf_sg_x3d_node_get_field_count(GF_Node *node) case TAG_X3D_NavigationInfo:return NavigationInfo_get_field_count(node, 0); case TAG_X3D_Normal:return Normal_get_field_count(node, 0); case TAG_X3D_NormalInterpolator:return NormalInterpolator_get_field_count(node, 0); + case TAG_X3D_NurbsCurve:return NurbsCurve_get_field_count(node, 0); + case TAG_X3D_NurbsCurve2D:return NurbsCurve2D_get_field_count(node, 0); + case TAG_X3D_NurbsOrientationInterpolator:return NurbsOrientationInterpolator_get_field_count(node, 0); + case TAG_X3D_NurbsPatchSurface:return NurbsPatchSurface_get_field_count(node, 0); + case TAG_X3D_NurbsPositionInterpolator:return NurbsPositionInterpolator_get_field_count(node, 0); + case TAG_X3D_NurbsSet:return NurbsSet_get_field_count(node, 0); + case TAG_X3D_NurbsSurfaceInterpolator:return NurbsSurfaceInterpolator_get_field_count(node, 0); + case TAG_X3D_NurbsSweptSurface:return NurbsSweptSurface_get_field_count(node, 0); + case TAG_X3D_NurbsSwungSurface:return NurbsSwungSurface_get_field_count(node, 0); + case TAG_X3D_NurbsTextureCoordinate:return NurbsTextureCoordinate_get_field_count(node, 0); + case TAG_X3D_NurbsTrimmedSurface:return NurbsTrimmedSurface_get_field_count(node, 0); case TAG_X3D_OrientationInterpolator:return OrientationInterpolator_get_field_count(node, 0); case TAG_X3D_PixelTexture:return PixelTexture_get_field_count(node, 0); case TAG_X3D_PlaneSensor:return PlaneSensor_get_field_count(node, 0); @@ -10047,10 +15176,12 @@ u32 gf_sg_x3d_node_get_field_count(GF_Node *node) case TAG_X3D_PositionInterpolator:return PositionInterpolator_get_field_count(node, 0); case TAG_X3D_PositionInterpolator2D:return PositionInterpolator2D_get_field_count(node, 0); case TAG_X3D_ProximitySensor:return ProximitySensor_get_field_count(node, 0); + case TAG_X3D_ReceiverPdu:return ReceiverPdu_get_field_count(node, 0); case TAG_X3D_Rectangle2D:return Rectangle2D_get_field_count(node, 0); case TAG_X3D_ScalarInterpolator:return ScalarInterpolator_get_field_count(node, 0); case TAG_X3D_Script:return Script_get_field_count(node, 0); case TAG_X3D_Shape:return Shape_get_field_count(node, 0); + case TAG_X3D_SignalPdu:return SignalPdu_get_field_count(node, 0); case TAG_X3D_Sound:return Sound_get_field_count(node, 0); case TAG_X3D_Sphere:return Sphere_get_field_count(node, 0); case TAG_X3D_SphereSensor:return SphereSensor_get_field_count(node, 0); @@ -10067,6 +15198,7 @@ u32 gf_sg_x3d_node_get_field_count(GF_Node *node) case TAG_X3D_TimeTrigger:return TimeTrigger_get_field_count(node, 0); case TAG_X3D_TouchSensor:return TouchSensor_get_field_count(node, 0); case TAG_X3D_Transform:return Transform_get_field_count(node, 0); + case TAG_X3D_TransmitterPdu:return TransmitterPdu_get_field_count(node, 0); case TAG_X3D_TriangleFanSet:return TriangleFanSet_get_field_count(node, 0); case TAG_X3D_TriangleSet:return TriangleSet_get_field_count(node, 0); case TAG_X3D_TriangleSet2D:return TriangleSet2D_get_field_count(node, 0); @@ -10112,11 +15244,26 @@ GF_Err gf_sg_x3d_node_get_field(GF_Node *node, GF_FieldInfo *field) case TAG_X3D_DirectionalLight: return DirectionalLight_get_field(node, field); case TAG_X3D_Disk2D: return Disk2D_get_field(node, field); case TAG_X3D_ElevationGrid: return ElevationGrid_get_field(node, field); + case TAG_X3D_EspduTransform: return EspduTransform_get_field(node, field); case TAG_X3D_Extrusion: return Extrusion_get_field(node, field); case TAG_X3D_FillProperties: return FillProperties_get_field(node, field); case TAG_X3D_Fog: return Fog_get_field(node, field); case TAG_X3D_FontStyle: return FontStyle_get_field(node, field); + case TAG_X3D_GeoCoordinate: return GeoCoordinate_get_field(node, field); + case TAG_X3D_GeoElevationGrid: return GeoElevationGrid_get_field(node, field); + case TAG_X3D_GeoLocation: return GeoLocation_get_field(node, field); + case TAG_X3D_GeoLOD: return GeoLOD_get_field(node, field); + case TAG_X3D_GeoMetadata: return GeoMetadata_get_field(node, field); + case TAG_X3D_GeoOrigin: return GeoOrigin_get_field(node, field); + case TAG_X3D_GeoPositionInterpolator: return GeoPositionInterpolator_get_field(node, field); + case TAG_X3D_GeoTouchSensor: return GeoTouchSensor_get_field(node, field); + case TAG_X3D_GeoViewpoint: return GeoViewpoint_get_field(node, field); case TAG_X3D_Group: return Group_get_field(node, field); + case TAG_X3D_HAnimDisplacer: return HAnimDisplacer_get_field(node, field); + case TAG_X3D_HAnimHumanoid: return HAnimHumanoid_get_field(node, field); + case TAG_X3D_HAnimJoint: return HAnimJoint_get_field(node, field); + case TAG_X3D_HAnimSegment: return HAnimSegment_get_field(node, field); + case TAG_X3D_HAnimSite: return HAnimSite_get_field(node, field); case TAG_X3D_ImageTexture: return ImageTexture_get_field(node, field); case TAG_X3D_IndexedFaceSet: return IndexedFaceSet_get_field(node, field); case TAG_X3D_IndexedLineSet: return IndexedLineSet_get_field(node, field); @@ -10129,6 +15276,7 @@ GF_Err gf_sg_x3d_node_get_field(GF_Node *node, GF_FieldInfo *field) case TAG_X3D_KeySensor: return KeySensor_get_field(node, field); case TAG_X3D_LineProperties: return LineProperties_get_field(node, field); case TAG_X3D_LineSet: return LineSet_get_field(node, field); + case TAG_X3D_LoadSensor: return LoadSensor_get_field(node, field); case TAG_X3D_LOD: return LOD_get_field(node, field); case TAG_X3D_Material: return Material_get_field(node, field); case TAG_X3D_MetadataDouble: return MetadataDouble_get_field(node, field); @@ -10143,6 +15291,17 @@ GF_Err gf_sg_x3d_node_get_field(GF_Node *node, GF_FieldInfo *field) case TAG_X3D_NavigationInfo: return NavigationInfo_get_field(node, field); case TAG_X3D_Normal: return Normal_get_field(node, field); case TAG_X3D_NormalInterpolator: return NormalInterpolator_get_field(node, field); + case TAG_X3D_NurbsCurve: return NurbsCurve_get_field(node, field); + case TAG_X3D_NurbsCurve2D: return NurbsCurve2D_get_field(node, field); + case TAG_X3D_NurbsOrientationInterpolator: return NurbsOrientationInterpolator_get_field(node, field); + case TAG_X3D_NurbsPatchSurface: return NurbsPatchSurface_get_field(node, field); + case TAG_X3D_NurbsPositionInterpolator: return NurbsPositionInterpolator_get_field(node, field); + case TAG_X3D_NurbsSet: return NurbsSet_get_field(node, field); + case TAG_X3D_NurbsSurfaceInterpolator: return NurbsSurfaceInterpolator_get_field(node, field); + case TAG_X3D_NurbsSweptSurface: return NurbsSweptSurface_get_field(node, field); + case TAG_X3D_NurbsSwungSurface: return NurbsSwungSurface_get_field(node, field); + case TAG_X3D_NurbsTextureCoordinate: return NurbsTextureCoordinate_get_field(node, field); + case TAG_X3D_NurbsTrimmedSurface: return NurbsTrimmedSurface_get_field(node, field); case TAG_X3D_OrientationInterpolator: return OrientationInterpolator_get_field(node, field); case TAG_X3D_PixelTexture: return PixelTexture_get_field(node, field); case TAG_X3D_PlaneSensor: return PlaneSensor_get_field(node, field); @@ -10153,10 +15312,12 @@ GF_Err gf_sg_x3d_node_get_field(GF_Node *node, GF_FieldInfo *field) case TAG_X3D_PositionInterpolator: return PositionInterpolator_get_field(node, field); case TAG_X3D_PositionInterpolator2D: return PositionInterpolator2D_get_field(node, field); case TAG_X3D_ProximitySensor: return ProximitySensor_get_field(node, field); + case TAG_X3D_ReceiverPdu: return ReceiverPdu_get_field(node, field); case TAG_X3D_Rectangle2D: return Rectangle2D_get_field(node, field); case TAG_X3D_ScalarInterpolator: return ScalarInterpolator_get_field(node, field); case TAG_X3D_Script: return Script_get_field(node, field); case TAG_X3D_Shape: return Shape_get_field(node, field); + case TAG_X3D_SignalPdu: return SignalPdu_get_field(node, field); case TAG_X3D_Sound: return Sound_get_field(node, field); case TAG_X3D_Sphere: return Sphere_get_field(node, field); case TAG_X3D_SphereSensor: return SphereSensor_get_field(node, field); @@ -10173,6 +15334,7 @@ GF_Err gf_sg_x3d_node_get_field(GF_Node *node, GF_FieldInfo *field) case TAG_X3D_TimeTrigger: return TimeTrigger_get_field(node, field); case TAG_X3D_TouchSensor: return TouchSensor_get_field(node, field); case TAG_X3D_Transform: return Transform_get_field(node, field); + case TAG_X3D_TransmitterPdu: return TransmitterPdu_get_field(node, field); case TAG_X3D_TriangleFanSet: return TriangleFanSet_get_field(node, field); case TAG_X3D_TriangleSet: return TriangleSet_get_field(node, field); case TAG_X3D_TriangleSet2D: return TriangleSet2D_get_field(node, field); @@ -10219,11 +15381,26 @@ u32 gf_node_x3d_type_by_class_name(const char *node_name) if (!strcmp(node_name, "DirectionalLight")) return TAG_X3D_DirectionalLight; if (!strcmp(node_name, "Disk2D")) return TAG_X3D_Disk2D; if (!strcmp(node_name, "ElevationGrid")) return TAG_X3D_ElevationGrid; + if (!strcmp(node_name, "EspduTransform")) return TAG_X3D_EspduTransform; if (!strcmp(node_name, "Extrusion")) return TAG_X3D_Extrusion; if (!strcmp(node_name, "FillProperties")) return TAG_X3D_FillProperties; if (!strcmp(node_name, "Fog")) return TAG_X3D_Fog; if (!strcmp(node_name, "FontStyle")) return TAG_X3D_FontStyle; + if (!strcmp(node_name, "GeoCoordinate")) return TAG_X3D_GeoCoordinate; + if (!strcmp(node_name, "GeoElevationGrid")) return TAG_X3D_GeoElevationGrid; + if (!strcmp(node_name, "GeoLocation")) return TAG_X3D_GeoLocation; + if (!strcmp(node_name, "GeoLOD")) return TAG_X3D_GeoLOD; + if (!strcmp(node_name, "GeoMetadata")) return TAG_X3D_GeoMetadata; + if (!strcmp(node_name, "GeoOrigin")) return TAG_X3D_GeoOrigin; + if (!strcmp(node_name, "GeoPositionInterpolator")) return TAG_X3D_GeoPositionInterpolator; + if (!strcmp(node_name, "GeoTouchSensor")) return TAG_X3D_GeoTouchSensor; + if (!strcmp(node_name, "GeoViewpoint")) return TAG_X3D_GeoViewpoint; if (!strcmp(node_name, "Group")) return TAG_X3D_Group; + if (!strcmp(node_name, "HAnimDisplacer")) return TAG_X3D_HAnimDisplacer; + if (!strcmp(node_name, "HAnimHumanoid")) return TAG_X3D_HAnimHumanoid; + if (!strcmp(node_name, "HAnimJoint")) return TAG_X3D_HAnimJoint; + if (!strcmp(node_name, "HAnimSegment")) return TAG_X3D_HAnimSegment; + if (!strcmp(node_name, "HAnimSite")) return TAG_X3D_HAnimSite; if (!strcmp(node_name, "ImageTexture")) return TAG_X3D_ImageTexture; if (!strcmp(node_name, "IndexedFaceSet")) return TAG_X3D_IndexedFaceSet; if (!strcmp(node_name, "IndexedLineSet")) return TAG_X3D_IndexedLineSet; @@ -10236,6 +15413,7 @@ u32 gf_node_x3d_type_by_class_name(const char *node_name) if (!strcmp(node_name, "KeySensor")) return TAG_X3D_KeySensor; if (!strcmp(node_name, "LineProperties")) return TAG_X3D_LineProperties; if (!strcmp(node_name, "LineSet")) return TAG_X3D_LineSet; + if (!strcmp(node_name, "LoadSensor")) return TAG_X3D_LoadSensor; if (!strcmp(node_name, "LOD")) return TAG_X3D_LOD; if (!strcmp(node_name, "Material")) return TAG_X3D_Material; if (!strcmp(node_name, "MetadataDouble")) return TAG_X3D_MetadataDouble; @@ -10250,6 +15428,17 @@ u32 gf_node_x3d_type_by_class_name(const char *node_name) if (!strcmp(node_name, "NavigationInfo")) return TAG_X3D_NavigationInfo; if (!strcmp(node_name, "Normal")) return TAG_X3D_Normal; if (!strcmp(node_name, "NormalInterpolator")) return TAG_X3D_NormalInterpolator; + if (!strcmp(node_name, "NurbsCurve")) return TAG_X3D_NurbsCurve; + if (!strcmp(node_name, "NurbsCurve2D")) return TAG_X3D_NurbsCurve2D; + if (!strcmp(node_name, "NurbsOrientationInterpolator")) return TAG_X3D_NurbsOrientationInterpolator; + if (!strcmp(node_name, "NurbsPatchSurface")) return TAG_X3D_NurbsPatchSurface; + if (!strcmp(node_name, "NurbsPositionInterpolator")) return TAG_X3D_NurbsPositionInterpolator; + if (!strcmp(node_name, "NurbsSet")) return TAG_X3D_NurbsSet; + if (!strcmp(node_name, "NurbsSurfaceInterpolator")) return TAG_X3D_NurbsSurfaceInterpolator; + if (!strcmp(node_name, "NurbsSweptSurface")) return TAG_X3D_NurbsSweptSurface; + if (!strcmp(node_name, "NurbsSwungSurface")) return TAG_X3D_NurbsSwungSurface; + if (!strcmp(node_name, "NurbsTextureCoordinate")) return TAG_X3D_NurbsTextureCoordinate; + if (!strcmp(node_name, "NurbsTrimmedSurface")) return TAG_X3D_NurbsTrimmedSurface; if (!strcmp(node_name, "OrientationInterpolator")) return TAG_X3D_OrientationInterpolator; if (!strcmp(node_name, "PixelTexture")) return TAG_X3D_PixelTexture; if (!strcmp(node_name, "PlaneSensor")) return TAG_X3D_PlaneSensor; @@ -10260,10 +15449,12 @@ u32 gf_node_x3d_type_by_class_name(const char *node_name) if (!strcmp(node_name, "PositionInterpolator")) return TAG_X3D_PositionInterpolator; if (!strcmp(node_name, "PositionInterpolator2D")) return TAG_X3D_PositionInterpolator2D; if (!strcmp(node_name, "ProximitySensor")) return TAG_X3D_ProximitySensor; + if (!strcmp(node_name, "ReceiverPdu")) return TAG_X3D_ReceiverPdu; if (!strcmp(node_name, "Rectangle2D")) return TAG_X3D_Rectangle2D; if (!strcmp(node_name, "ScalarInterpolator")) return TAG_X3D_ScalarInterpolator; if (!strcmp(node_name, "Script")) return TAG_X3D_Script; if (!strcmp(node_name, "Shape")) return TAG_X3D_Shape; + if (!strcmp(node_name, "SignalPdu")) return TAG_X3D_SignalPdu; if (!strcmp(node_name, "Sound")) return TAG_X3D_Sound; if (!strcmp(node_name, "Sphere")) return TAG_X3D_Sphere; if (!strcmp(node_name, "SphereSensor")) return TAG_X3D_SphereSensor; @@ -10280,6 +15471,7 @@ u32 gf_node_x3d_type_by_class_name(const char *node_name) if (!strcmp(node_name, "TimeTrigger")) return TAG_X3D_TimeTrigger; if (!strcmp(node_name, "TouchSensor")) return TAG_X3D_TouchSensor; if (!strcmp(node_name, "Transform")) return TAG_X3D_Transform; + if (!strcmp(node_name, "TransmitterPdu")) return TAG_X3D_TransmitterPdu; if (!strcmp(node_name, "TriangleFanSet")) return TAG_X3D_TriangleFanSet; if (!strcmp(node_name, "TriangleSet")) return TAG_X3D_TriangleSet; if (!strcmp(node_name, "TriangleSet2D")) return TAG_X3D_TriangleSet2D; @@ -10323,11 +15515,26 @@ s32 gf_sg_x3d_node_get_field_index_by_name(GF_Node *node, char *name) case TAG_X3D_DirectionalLight: return DirectionalLight_get_field_index_by_name(name); case TAG_X3D_Disk2D: return Disk2D_get_field_index_by_name(name); case TAG_X3D_ElevationGrid: return ElevationGrid_get_field_index_by_name(name); + case TAG_X3D_EspduTransform: return EspduTransform_get_field_index_by_name(name); case TAG_X3D_Extrusion: return Extrusion_get_field_index_by_name(name); case TAG_X3D_FillProperties: return FillProperties_get_field_index_by_name(name); case TAG_X3D_Fog: return Fog_get_field_index_by_name(name); case TAG_X3D_FontStyle: return FontStyle_get_field_index_by_name(name); + case TAG_X3D_GeoCoordinate: return GeoCoordinate_get_field_index_by_name(name); + case TAG_X3D_GeoElevationGrid: return GeoElevationGrid_get_field_index_by_name(name); + case TAG_X3D_GeoLocation: return GeoLocation_get_field_index_by_name(name); + case TAG_X3D_GeoLOD: return GeoLOD_get_field_index_by_name(name); + case TAG_X3D_GeoMetadata: return GeoMetadata_get_field_index_by_name(name); + case TAG_X3D_GeoOrigin: return GeoOrigin_get_field_index_by_name(name); + case TAG_X3D_GeoPositionInterpolator: return GeoPositionInterpolator_get_field_index_by_name(name); + case TAG_X3D_GeoTouchSensor: return GeoTouchSensor_get_field_index_by_name(name); + case TAG_X3D_GeoViewpoint: return GeoViewpoint_get_field_index_by_name(name); case TAG_X3D_Group: return Group_get_field_index_by_name(name); + case TAG_X3D_HAnimDisplacer: return HAnimDisplacer_get_field_index_by_name(name); + case TAG_X3D_HAnimHumanoid: return HAnimHumanoid_get_field_index_by_name(name); + case TAG_X3D_HAnimJoint: return HAnimJoint_get_field_index_by_name(name); + case TAG_X3D_HAnimSegment: return HAnimSegment_get_field_index_by_name(name); + case TAG_X3D_HAnimSite: return HAnimSite_get_field_index_by_name(name); case TAG_X3D_ImageTexture: return ImageTexture_get_field_index_by_name(name); case TAG_X3D_IndexedFaceSet: return IndexedFaceSet_get_field_index_by_name(name); case TAG_X3D_IndexedLineSet: return IndexedLineSet_get_field_index_by_name(name); @@ -10340,6 +15547,7 @@ s32 gf_sg_x3d_node_get_field_index_by_name(GF_Node *node, char *name) case TAG_X3D_KeySensor: return KeySensor_get_field_index_by_name(name); case TAG_X3D_LineProperties: return LineProperties_get_field_index_by_name(name); case TAG_X3D_LineSet: return LineSet_get_field_index_by_name(name); + case TAG_X3D_LoadSensor: return LoadSensor_get_field_index_by_name(name); case TAG_X3D_LOD: return LOD_get_field_index_by_name(name); case TAG_X3D_Material: return Material_get_field_index_by_name(name); case TAG_X3D_MetadataDouble: return MetadataDouble_get_field_index_by_name(name); @@ -10354,6 +15562,17 @@ s32 gf_sg_x3d_node_get_field_index_by_name(GF_Node *node, char *name) case TAG_X3D_NavigationInfo: return NavigationInfo_get_field_index_by_name(name); case TAG_X3D_Normal: return Normal_get_field_index_by_name(name); case TAG_X3D_NormalInterpolator: return NormalInterpolator_get_field_index_by_name(name); + case TAG_X3D_NurbsCurve: return NurbsCurve_get_field_index_by_name(name); + case TAG_X3D_NurbsCurve2D: return NurbsCurve2D_get_field_index_by_name(name); + case TAG_X3D_NurbsOrientationInterpolator: return NurbsOrientationInterpolator_get_field_index_by_name(name); + case TAG_X3D_NurbsPatchSurface: return NurbsPatchSurface_get_field_index_by_name(name); + case TAG_X3D_NurbsPositionInterpolator: return NurbsPositionInterpolator_get_field_index_by_name(name); + case TAG_X3D_NurbsSet: return NurbsSet_get_field_index_by_name(name); + case TAG_X3D_NurbsSurfaceInterpolator: return NurbsSurfaceInterpolator_get_field_index_by_name(name); + case TAG_X3D_NurbsSweptSurface: return NurbsSweptSurface_get_field_index_by_name(name); + case TAG_X3D_NurbsSwungSurface: return NurbsSwungSurface_get_field_index_by_name(name); + case TAG_X3D_NurbsTextureCoordinate: return NurbsTextureCoordinate_get_field_index_by_name(name); + case TAG_X3D_NurbsTrimmedSurface: return NurbsTrimmedSurface_get_field_index_by_name(name); case TAG_X3D_OrientationInterpolator: return OrientationInterpolator_get_field_index_by_name(name); case TAG_X3D_PixelTexture: return PixelTexture_get_field_index_by_name(name); case TAG_X3D_PlaneSensor: return PlaneSensor_get_field_index_by_name(name); @@ -10364,10 +15583,12 @@ s32 gf_sg_x3d_node_get_field_index_by_name(GF_Node *node, char *name) case TAG_X3D_PositionInterpolator: return PositionInterpolator_get_field_index_by_name(name); case TAG_X3D_PositionInterpolator2D: return PositionInterpolator2D_get_field_index_by_name(name); case TAG_X3D_ProximitySensor: return ProximitySensor_get_field_index_by_name(name); + case TAG_X3D_ReceiverPdu: return ReceiverPdu_get_field_index_by_name(name); case TAG_X3D_Rectangle2D: return Rectangle2D_get_field_index_by_name(name); case TAG_X3D_ScalarInterpolator: return ScalarInterpolator_get_field_index_by_name(name); case TAG_X3D_Script: return Script_get_field_index_by_name(name); case TAG_X3D_Shape: return Shape_get_field_index_by_name(name); + case TAG_X3D_SignalPdu: return SignalPdu_get_field_index_by_name(name); case TAG_X3D_Sound: return Sound_get_field_index_by_name(name); case TAG_X3D_Sphere: return Sphere_get_field_index_by_name(name); case TAG_X3D_SphereSensor: return SphereSensor_get_field_index_by_name(name); @@ -10384,6 +15605,7 @@ s32 gf_sg_x3d_node_get_field_index_by_name(GF_Node *node, char *name) case TAG_X3D_TimeTrigger: return TimeTrigger_get_field_index_by_name(name); case TAG_X3D_TouchSensor: return TouchSensor_get_field_index_by_name(name); case TAG_X3D_Transform: return Transform_get_field_index_by_name(name); + case TAG_X3D_TransmitterPdu: return TransmitterPdu_get_field_index_by_name(name); case TAG_X3D_TriangleFanSet: return TriangleFanSet_get_field_index_by_name(name); case TAG_X3D_TriangleSet: return TriangleSet_get_field_index_by_name(name); case TAG_X3D_TriangleSet2D: return TriangleSet2D_get_field_index_by_name(name); @@ -10626,3 +15848,5 @@ Bool gf_x3d_get_node_type(u32 NDT_Tag, u32 NodeTag) for(i=0; i<count; i++) { if (types[i]==NodeTag) return 1;} return 0; } +#endif /*GPAC_DISABLE_X3D*/ + diff --git a/src/scenegraph/xbl_process.c b/src/scenegraph/xbl_process.c index d5371fd..4d16b55 100644 --- a/src/scenegraph/xbl_process.c +++ b/src/scenegraph/xbl_process.c @@ -69,7 +69,7 @@ static GF_Err xbl_parse_report(GF_XBL_Parser *parser, GF_Err e, char *format, .. return e; } -static void xbl_parse_progress(void *cbk, u32 done, u32 total) +static void xbl_parse_progress(void *cbk, u64 done, u64 total) { gf_set_progress("XBL Parsing", done, total); } @@ -106,7 +106,7 @@ static XBL_Element *xbl_parse_element(GF_XBL_Parser *parser, const char *name, c if (attribute_tag!=TAG_DOM_ATT_any) { /*FIXME do we need to check if the attribute is specified several times*/ GF_DOMAttribute *dom_att = gf_xml_create_attribute((GF_Node*)elt, attribute_tag); - dom_att->data = strdup(att->value); + dom_att->data = gf_strdup(att->value); } else { xbl_parse_report(parser, GF_OK, "Skipping attribute %s on node %s", att->name, name); } @@ -165,7 +165,7 @@ static void xbl_node_end(void *sax_cbck, const char *name, const char *name_spac return; } } - free(top); + gf_free(top); gf_list_rem_last(parser->node_stack); } else if (top) { if (top->unknown_depth) { @@ -212,20 +212,20 @@ GF_Err gf_sm_load_run_xbl(GF_SceneLoader *load) return GF_OK; } -GF_Err gf_sm_load_done_xbl(GF_SceneLoader *load) +void gf_sm_load_done_xbl(GF_SceneLoader *load) { GF_XBL_Parser *parser = (GF_XBL_Parser *)load->loader_priv; - if (!parser) return GF_OK; + if (!parser) return; while (gf_list_count(parser->node_stack)) { XBL_NodeStack *st = (XBL_NodeStack *)gf_list_last(parser->node_stack); gf_list_rem_last(parser->node_stack); - free(st); + gf_free(st); } gf_list_del(parser->node_stack); if (parser->sax_parser) gf_xml_sax_del(parser->sax_parser); - free(parser); + gf_free(parser); load->loader_priv = NULL; - return GF_OK; + return; } void apply(GF_Node *bound_doc, GF_Node *binding_doc) diff --git a/src/scenegraph/xml_ns.c b/src/scenegraph/xml_ns.c index 00044c3..31a6267 100644 --- a/src/scenegraph/xml_ns.c +++ b/src/scenegraph/xml_ns.c @@ -41,6 +41,8 @@ enum GF_SVG_ATTOPT_CURSOR = 3, /*attribute only valid for listener*/ GF_SVG_ATTOPT_LISTENER = 4, + /*attribute only valid for filters*/ + GF_SVG_ATTOPT_FILTER = 5, } GF_SVGAttOption; static const struct xml_att_def { const char *name; u32 tag; u32 type; u32 opts; u32 xmlns; } xml_attributes [] = @@ -208,6 +210,7 @@ static const struct xml_att_def { const char *name; u32 tag; u32 type; u32 opts; { "x2", TAG_SVG_ATT_x2, SVG_Coordinate_datatype, 0, GF_XMLNS_SVG }, { "y2", TAG_SVG_ATT_y2, SVG_Coordinate_datatype, 0, GF_XMLNS_SVG }, { "gradientUnits", TAG_SVG_ATT_gradientUnits, SVG_GradientUnit_datatype, 0, GF_XMLNS_SVG }, + { "filterUnits", TAG_SVG_ATT_filterUnits, SVG_GradientUnit_datatype, 0, GF_XMLNS_SVG }, { "spreadMethod", TAG_SVG_ATT_spreadMethod, SVG_SpreadMethod_datatype, 0, GF_XMLNS_SVG }, { "gradientTransform", TAG_SVG_ATT_gradientTransform, SVG_Transform_datatype, 0, GF_XMLNS_SVG }, { "pathLength", TAG_SVG_ATT_pathLength, SVG_Number_datatype, 0, GF_XMLNS_SVG }, @@ -241,12 +244,16 @@ static const struct xml_att_def { const char *name; u32 tag; u32 type; u32 opts; { "fill", TAG_SVG_ATT_smil_fill, SMIL_Fill_datatype, GF_SVG_ATTOPT_SMIL, GF_XMLNS_SVG }, /*regular paint fill*/ { "fill", TAG_SVG_ATT_fill, SVG_Paint_datatype, 0, GF_XMLNS_SVG }, + /*filter*/ + { "filter", TAG_SVG_ATT_filter, SVG_Paint_datatype, 0, GF_XMLNS_SVG }, /*text rotate*/ { "rotate", TAG_SVG_ATT_text_rotate, SVG_Numbers_datatype, GF_SVG_ATTOPT_TEXT, GF_XMLNS_SVG }, /*regular matrix rotate*/ { "rotate", TAG_SVG_ATT_rotate, SVG_Rotate_datatype, 0, GF_XMLNS_SVG }, /*SMIL anim type*/ { "type", TAG_SVG_ATT_transform_type, SVG_TransformType_datatype, GF_SVG_ATTOPT_SMIL, GF_XMLNS_SVG }, + /*Filter componentTransfer type*/ + { "type", TAG_SVG_ATT_filter_transfer_type, SVG_Filter_TransferType_datatype, GF_SVG_ATTOPT_FILTER, GF_XMLNS_SVG }, /*regular content type*/ { "type", TAG_SVG_ATT_type, SVG_ContentType_datatype, 0, GF_XMLNS_SVG }, /*text x*/ @@ -257,6 +264,12 @@ static const struct xml_att_def { const char *name; u32 tag; u32 type; u32 opts; { "y", TAG_SVG_ATT_text_y, SVG_Coordinates_datatype, GF_SVG_ATTOPT_TEXT, GF_XMLNS_SVG }, /*regular y position*/ { "y", TAG_SVG_ATT_y, SVG_Coordinate_datatype, 0, GF_XMLNS_SVG }, + + /*filters*/ + { "tableValues", TAG_SVG_ATT_filter_table_values, SVG_Numbers_datatype, 0, GF_XMLNS_SVG }, + { "intercept", TAG_SVG_ATT_filter_intercept, SVG_Number_datatype, 0, GF_XMLNS_SVG }, + { "amplitude", TAG_SVG_ATT_filter_amplitude, SVG_Number_datatype, 0, GF_XMLNS_SVG }, + { "exponent", TAG_SVG_ATT_filter_exponent, SVG_Number_datatype, 0, GF_XMLNS_SVG }, /*LASeR*/ { "enabled", TAG_LSR_ATT_enabled, SVG_Boolean_datatype, 0, GF_XMLNS_LASER }, @@ -289,6 +302,12 @@ static const struct xml_att_def { const char *name; u32 tag; u32 type; u32 opts; { "command", TAG_XBL_ATT_command, DOM_String_datatype, 0, GF_XMLNS_XBL }, { "preventdefault", TAG_XBL_ATT_preventdefault, DOM_String_datatype, 0, GF_XMLNS_XBL }, { "src", TAG_XBL_ATT_src, DOM_String_datatype, 0, GF_XMLNS_XBL }, + + /*GPAC SVG Extensions*/ + { "use-as-primary", TAG_GSVG_ATT_useAsPrimary, SVG_Boolean_datatype, 0, GF_XMLNS_SVG_GPAC_EXTENSION}, + { "depthOffset", TAG_GSVG_ATT_depthOffset, SVG_Number_datatype, 0, GF_XMLNS_SVG_GPAC_EXTENSION}, + { "depthGain", TAG_GSVG_ATT_depthGain, SVG_Number_datatype, 0, GF_XMLNS_SVG_GPAC_EXTENSION}, + }; void gf_xml_push_namespaces(GF_DOMNode *elt) @@ -322,6 +341,39 @@ void gf_xml_pop_namespaces(GF_DOMNode *elt) } +static u32 gf_xml_get_namespace(GF_DOMNode *elt, const char *attribute_name) +{ + GF_DOMAttribute *att = elt->attributes; + while (att) { + if (att->tag==TAG_DOM_ATT_any) { + GF_DOMFullAttribute *datt = (GF_DOMFullAttribute*)att; + if (datt->name && !strncmp(datt->name, "xmlns", 5) && !strcmp(datt->name+6, attribute_name)) { + return gf_xml_get_namespace_id(*(DOM_String *) datt->data); + } + } + att = att->next; + } + if (!elt->sgprivate->parents) return 0; + return gf_xml_get_namespace((GF_DOMNode*)elt->sgprivate->parents->node, attribute_name); +} + +static char *gf_xml_get_namespace_qname(GF_DOMNode *elt, u32 ns) +{ + GF_DOMAttribute *att = elt->attributes; + while (att) { + if (att->tag==TAG_DOM_ATT_any) { + GF_DOMFullAttribute *datt = (GF_DOMFullAttribute*)att; + if (datt->name && !strncmp(datt->name, "xmlns", 5) && (gf_xml_get_namespace_id(*(DOM_String *) datt->data)==ns)) { + if (datt->name[5]) return datt->name+6; + return NULL; + } + } + att = att->next; + } + if (!elt->sgprivate->parents) return NULL; + return gf_xml_get_namespace_qname((GF_DOMNode*)elt->sgprivate->parents->node, ns); +} + u32 gf_xml_get_attribute_tag(GF_Node *elt, char *attribute_name, u32 ns) { char *ns_sep; @@ -330,10 +382,11 @@ u32 gf_xml_get_attribute_tag(GF_Node *elt, char *attribute_name, u32 ns) if (!ns) { ns_sep = strchr(attribute_name, ':'); - ns = 0; + ns = GF_XMLNS_UNDEFINED; if (ns_sep) { ns_sep[0] = 0; ns = gf_sg_get_namespace_code(elt->sgprivate->scenegraph, attribute_name); + if (ns==GF_XMLNS_UNDEFINED) ns = gf_xml_get_namespace((GF_DOMNode*)elt, attribute_name); ns_sep[0] = ':'; attribute_name = ++ns_sep; } else { @@ -374,6 +427,37 @@ u32 gf_xml_get_attribute_tag(GF_Node *elt, char *attribute_name, u32 ns) if (elt->sgprivate->tag == TAG_SVG_listener) return xml_attributes[i].tag; break; + case GF_SVG_ATTOPT_FILTER: + switch (elt->sgprivate->tag) { + case TAG_SVG_filter: + case TAG_SVG_feDistantLight: + case TAG_SVG_fePointLight: + case TAG_SVG_feSpotLight: + case TAG_SVG_feBlend: + case TAG_SVG_feColorMatrix: + case TAG_SVG_feComponentTransfer: + case TAG_SVG_feFuncR: + case TAG_SVG_feFuncG: + case TAG_SVG_feFuncB: + case TAG_SVG_feFuncA: + case TAG_SVG_feComposite: + case TAG_SVG_feConvolveMatrix: + case TAG_SVG_feDiffuseLighting: + case TAG_SVG_feDisplacementMap: + case TAG_SVG_feFlood: + case TAG_SVG_feGaussianBlur: + case TAG_SVG_feImage: + case TAG_SVG_feMerge: + case TAG_SVG_feMorphology: + case TAG_SVG_feOffset: + case TAG_SVG_feSpecularLighting: + case TAG_SVG_feTile: + case TAG_SVG_feTurbulence: + return xml_attributes[i].tag; + default: + break; + } + break; default: return xml_attributes[i].tag; } @@ -404,7 +488,7 @@ const char*gf_svg_get_attribute_name(GF_Node *node, u32 tag) if (ns == xml_attributes[i].xmlns) return xml_attributes[i].name; - xmlns = (char *) gf_sg_get_namespace_qname(node->sgprivate->scenegraph, xml_attributes[i].xmlns); + xmlns = (char *) gf_xml_get_namespace_qname((GF_DOMNode*)node, xml_attributes[i].xmlns); if (xmlns) { sprintf(node->sgprivate->scenegraph->szNameBuffer, "%s:%s", xmlns, xml_attributes[i].name); return node->sgprivate->scenegraph->szNameBuffer; @@ -470,6 +554,30 @@ static const struct xml_elt_def { const char *name; u32 tag; u32 xmlns; } xml_el { "tspan", TAG_SVG_tspan, GF_XMLNS_SVG }, { "use", TAG_SVG_use, GF_XMLNS_SVG }, { "video", TAG_SVG_video, GF_XMLNS_SVG }, + { "filter", TAG_SVG_filter, GF_XMLNS_SVG }, + { "feDistantLight", TAG_SVG_feDistantLight, GF_XMLNS_SVG }, + { "fePointLight", TAG_SVG_fePointLight, GF_XMLNS_SVG }, + { "feSpotLight", TAG_SVG_feSpotLight, GF_XMLNS_SVG }, + { "feBlend", TAG_SVG_feBlend, GF_XMLNS_SVG }, + { "feColorMatrix", TAG_SVG_feColorMatrix, GF_XMLNS_SVG }, + { "feComponentTransfer", TAG_SVG_feComponentTransfer, GF_XMLNS_SVG }, + { "feFuncR", TAG_SVG_feFuncR, GF_XMLNS_SVG }, + { "feFuncG", TAG_SVG_feFuncG, GF_XMLNS_SVG }, + { "feFuncB", TAG_SVG_feFuncB, GF_XMLNS_SVG }, + { "feFuncA", TAG_SVG_feFuncA, GF_XMLNS_SVG }, + { "feComposite", TAG_SVG_feComposite, GF_XMLNS_SVG }, + { "feConvolveMatrix", TAG_SVG_feConvolveMatrix, GF_XMLNS_SVG }, + { "feDiffuseLighting", TAG_SVG_feDiffuseLighting, GF_XMLNS_SVG }, + { "feDisplacementMap", TAG_SVG_feDisplacementMap, GF_XMLNS_SVG }, + { "feFlood", TAG_SVG_feFlood, GF_XMLNS_SVG }, + { "feGaussianBlur", TAG_SVG_feGaussianBlur, GF_XMLNS_SVG }, + { "feImage", TAG_SVG_feImage, GF_XMLNS_SVG }, + { "feMerge", TAG_SVG_feMerge, GF_XMLNS_SVG }, + { "feMorphology", TAG_SVG_feMorphology, GF_XMLNS_SVG }, + { "feOffset", TAG_SVG_feOffset, GF_XMLNS_SVG }, + { "feSpecularLighting", TAG_SVG_feSpecularLighting, GF_XMLNS_SVG }, + { "feTile", TAG_SVG_feTile, GF_XMLNS_SVG }, + { "feTurbulence", TAG_SVG_feTurbulence, GF_XMLNS_SVG }, /*LASeR*/ { "conditional", TAG_LSR_conditional, GF_XMLNS_LASER }, @@ -549,7 +657,7 @@ u32 gf_xml_get_element_namespace(GF_Node *n) for (i=0; i<count; i++) { if (n->sgprivate->tag==xml_elements[i].tag) return xml_elements[i].xmlns; } - return GF_XMLNS_NONE; + return GF_XMLNS_UNDEFINED; } @@ -591,9 +699,9 @@ void gf_node_delete_attributes(GF_Node *node) tmp = att; att = att->next; if (tmp->tag==TAG_DOM_ATT_any) { - free( ((GF_DOMFullAttribute*)tmp)->name); + gf_free( ((GF_DOMFullAttribute*)tmp)->name); } - free(tmp); + gf_free(tmp); } } @@ -622,7 +730,7 @@ GF_Err gf_node_get_attribute_by_name(GF_Node *node, char *name, u32 xmlns_code, while (att) { if (((u32) att->tag == TAG_DOM_ATT_any) && - ((!ns && !strcmp(name, att->name)) || (!strncmp(att->name, ns, len) && !strcmp(att->name+len+1, name))) + ((!ns && !strcmp(name, att->name)) || (ns && !strncmp(att->name, ns, len) && !strcmp(att->name+len+1, name))) ) { field->fieldIndex = att->tag; field->fieldType = att->data_type; @@ -638,7 +746,7 @@ GF_Err gf_node_get_attribute_by_name(GF_Node *node, char *name, u32 xmlns_code, att->tag = (u16) TAG_DOM_ATT_any; att->data = gf_svg_create_attribute_value(att->data_type); - att->name = strdup(name); + att->name = gf_strdup(name); if (!xmlns_code) att->xmlns = gf_xml_get_element_namespace(node); else @@ -658,8 +766,9 @@ GF_Err gf_node_get_attribute_by_name(GF_Node *node, char *name, u32 xmlns_code, } -static void attributes_set_default_value(u32 node_tag, SVGAttribute *att) +static void attributes_set_default_value(GF_Node *node, SVGAttribute *att) { + u32 node_tag = node->sgprivate->tag; switch (att->tag) { case TAG_SVG_ATT_width: case TAG_SVG_ATT_height: @@ -783,7 +892,7 @@ static void attributes_set_default_value(u32 node_tag, SVGAttribute *att) break; default: - GF_LOG(GF_LOG_ERROR, GF_LOG_SCENE, ("[Scene] Cannot create default value for SVG attribute %s\n", gf_svg_get_attribute_name(NULL, att->tag))); + GF_LOG(GF_LOG_DEBUG, GF_LOG_SCENE, ("[Scene] Cannot create default value for SVG attribute %s\n", gf_svg_get_attribute_name(node, att->tag))); } } @@ -816,7 +925,7 @@ GF_Err gf_node_get_attribute_by_tag(GF_Node *node, u32 attribute_tag, Bool creat field->fieldIndex = att->tag; /* attribute name should not be called, if needed use gf_svg_get_attribute_name(att->tag);*/ field->name = NULL; - if (set_default) attributes_set_default_value(node->sgprivate->tag, att); + if (set_default) attributes_set_default_value(node, att); return GF_OK; } } @@ -852,14 +961,14 @@ GF_Node *gf_xml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *clone n_src = (GF_DOMText *)orig; n_dst = (GF_DOMText *)clone; n_dst->type = n_src->type; - n_dst->textContent = strdup(n_src->textContent); + n_dst->textContent = gf_strdup(n_src->textContent); } else { if (orig->sgprivate->tag == TAG_DOMFullNode) { GF_DOMFullNode *n_src,*n_dst; n_src = (GF_DOMFullNode *)orig; n_dst = (GF_DOMFullNode *)clone; n_dst->ns = n_src->ns; - n_dst->name = strdup(n_dst->name); + n_dst->name = gf_strdup(n_dst->name); } att = ((GF_DOMNode *)orig)->attributes; @@ -909,20 +1018,20 @@ GF_Node *gf_xml_node_clone(GF_SceneGraph *inScene, GF_Node *orig, GF_Node *clone static u32 check_existing_file(char *base_file, char *ext, char *data, u32 data_size, u32 idx) { char szFile[GF_MAX_PATH]; - u32 fsize; + u64 fsize; FILE *f; sprintf(szFile, "%s%04X%s", base_file, idx, ext); - f = fopen(szFile, "rb"); + f = gf_f64_open(szFile, "rb"); if (!f) return 0; - fseek(f, 0, SEEK_END); - fsize = ftell(f); + gf_f64_seek(f, 0, SEEK_END); + fsize = gf_f64_tell(f); if (fsize==data_size) { u32 offset=0; char cache[1024]; - fseek(f, 0, SEEK_SET); + gf_f64_seek(f, 0, SEEK_SET); while (fsize) { u32 read = fread(cache, 1, 1024, f); fsize -= read; @@ -972,7 +1081,8 @@ GF_Err gf_node_store_embedded_data(XMLRI *iri, const char *cache_dir, const char sep = (char *)iri->string + 5; if (!strncmp(sep, "image/jpg", 9) || !strncmp(sep, "image/jpeg", 10)) ext = ".jpg"; else if (!strncmp(sep, "image/png", 9)) ext = ".png"; - else return GF_OK; + else if (!strncmp(sep, "image/svg+xml", 13)) ext = ".svg"; + else return GF_BAD_PARAM; data = NULL; @@ -980,13 +1090,13 @@ GF_Err gf_node_store_embedded_data(XMLRI *iri, const char *cache_dir, const char if (!strncmp(sep, ";base64,", 8)) { sep += 8; data_size = 2*strlen(sep); - data = (char*)malloc(sizeof(char)*data_size); + data = (char*)gf_malloc(sizeof(char)*data_size); if (!data) return GF_OUT_OF_MEM; data_size = gf_base64_decode(sep, strlen(sep), data, data_size); } else if (!strncmp(sep, ";base16,", 8)) { data_size = 2*strlen(sep); - data = (char*)malloc(sizeof(char)*data_size); + data = (char*)gf_malloc(sizeof(char)*data_size); if (!data) return GF_OUT_OF_MEM; sep += 8; data_size = gf_base16_decode(sep, strlen(sep), data, data_size); @@ -1011,19 +1121,19 @@ GF_Err gf_node_store_embedded_data(XMLRI *iri, const char *cache_dir, const char strcat(szFile, ext); if (!existing) { - f = fopen(szFile, "wb"); + f = gf_f64_open(szFile, "wb"); if (!f) { - free(data); - free(iri->string); + gf_free(data); + gf_free(iri->string); iri->string = NULL; return GF_IO_ERR; } fwrite(data, data_size, 1, f); fclose(f); } - free(data); - free(iri->string); - iri->string = strdup(szFile); + gf_free(data); + gf_free(iri->string); + iri->string = gf_strdup(szFile); return GF_OK; } diff --git a/src/terminal/channel.c b/src/terminal/channel.c index 6606d29..db94489 100644 --- a/src/terminal/channel.c +++ b/src/terminal/channel.c @@ -37,7 +37,7 @@ static void ch_buffer_off(GF_Channel *ch) if (ch->BufferOn) { ch->BufferOn = 0; gf_clock_buffer_off(ch->clock); - GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: buffering off at %d (nb buffering on clock: %d)\n", ch->esd->ESID, gf_term_get_time(ch->odm->term), ch->clock->Buffering)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: buffering off at STB %d (OTB %d) (nb buffering on clock: %d)\n", ch->esd->ESID, gf_term_get_time(ch->odm->term), gf_clock_time(ch->clock), ch->clock->Buffering)); } } @@ -79,7 +79,7 @@ static void Channel_Reset(GF_Channel *ch, Bool for_start) ch_buffer_off(ch); - if (ch->buffer) free(ch->buffer); + if (ch->buffer) gf_free(ch->buffer); ch->buffer = NULL; ch->len = ch->allocSize = 0; @@ -107,7 +107,6 @@ GF_Channel *gf_es_new(GF_ESD *esd) tmp->mx = gf_mx_new("Channel"); tmp->esd = esd; - tmp->chan_id = (u32) tmp; tmp->es_state = GF_ESM_ES_SETUP; nbBits = sizeof(u32) * 8 - esd->slConfig->AUSeqNumLength; @@ -129,14 +128,13 @@ GF_Channel *gf_es_new(GF_ESD *esd) tmp->ocr_scale /= esd->slConfig->OCRResolution; } - Channel_Reset(tmp, 0); return tmp; } /*reconfig SL settings for this channel - this is needed by some net services*/ -void gf_es_reconfig_sl(GF_Channel *ch, GF_SLConfig *slc) +void gf_es_reconfig_sl(GF_Channel *ch, GF_SLConfig *slc, Bool use_m2ts_sections) { u32 nbBits; @@ -159,6 +157,17 @@ void gf_es_reconfig_sl(GF_Channel *ch, GF_SLConfig *slc) ch->ocr_scale = 1000; ch->ocr_scale /= ch->esd->slConfig->OCRResolution; } + ch->carousel_type = GF_ESM_CAROUSEL_NONE; + if (use_m2ts_sections) { + ch->carousel_type = GF_ESM_CAROUSEL_MPEG2; + } else { + switch (ch->esd->decoderConfig->streamType) { + case GF_STREAM_OD: + case GF_STREAM_SCENE: + ch->carousel_type = ch->esd->slConfig->AUSeqNumLength ? GF_ESM_CAROUSEL_MPEG4 : GF_ESM_CAROUSEL_NONE; + break; + } + } } @@ -174,7 +183,7 @@ void gf_es_del(GF_Channel *ch) gf_modules_close_interface((GF_BaseInterface *) ch->ipmp_tool); if (ch->mx) gf_mx_del(ch->mx); - free(ch); + gf_free(ch); } Bool gf_es_owns_clock(GF_Channel *ch) @@ -193,7 +202,7 @@ GF_Err gf_es_start(GF_Channel *ch) case GF_ESM_ES_SETUP: return GF_BAD_PARAM; /*if the channel is already running, don't reset its settings. This only happens in the case of broadcast - objects started several times by the scene but not stoped at the ODManager level (cf gf_odm_stop)*/ + objects started several times by the scene but not stopped at the ODManager level (cf gf_odm_stop)*/ case GF_ESM_ES_RUNNING: return GF_OK; default: @@ -213,10 +222,18 @@ GF_Err gf_es_start(GF_Channel *ch) /*and start buffering - pull channels always turn off buffering immediately, otherwise buffering size is setup by the network service - except InputSensor*/ if ((ch->esd->decoderConfig->streamType != GF_STREAM_INTERACT) || ch->esd->URLString) { - ch_buffer_on(ch); + /*don't trigger rebuffer*/ + //if (ch->MinBuffer || (ch->clock->clock_init && ch->clock->Paused)) + ch_buffer_on(ch); } ch->last_au_time = gf_term_get_time(ch->odm->term); ch->es_state = GF_ESM_ES_RUNNING; + + ch->resync_drift = 0; + if (ch->clock->clockID==ch->esd->ESID) { + const char *opt = gf_cfg_get_key(ch->clock->term->user->config, "Systems", "ResyncLateClock"); + if (opt) ch->resync_drift = atoi(opt); + } return GF_OK; } @@ -247,31 +264,29 @@ void Channel_WaitRAP(GF_Channel *ch) /*if using RAP signal and codec not resilient, wait for rap. If RAP isn't signaled DON'T wait for it :)*/ if (!ch->codec_resilient) ch->stream_state = 2; - if (ch->buffer) free(ch->buffer); + if (ch->buffer) gf_free(ch->buffer); ch->buffer = NULL; ch->AULength = 0; ch->au_sn = 0; } -void gf_es_map_time(GF_Channel *ch, Bool reset) +void gf_es_reset_buffers(GF_Channel *ch) { gf_mx_p(ch->mx); - if (ch->buffer) free(ch->buffer); + + if (ch->buffer) gf_free(ch->buffer); ch->buffer = NULL; ch->len = ch->allocSize = 0; - if (reset) { - gf_db_unit_del(ch->AU_buffer_first); - ch->AU_buffer_first = ch->AU_buffer_last = NULL; - ch->AU_Count = 0; - } else { - GF_DBUnit *au = ch->AU_buffer_first; - while (au) { - au->DTS = au->CTS = ch->ts_offset; - au = au->next; - } - } + gf_db_unit_del(ch->AU_buffer_first); + ch->AU_buffer_first = ch->AU_buffer_last = NULL; + ch->AU_Count = 0; + + if (ch->odm->codec && ch->odm->codec->CB) + gf_cm_reset(ch->odm->codec->CB); + ch->BufferTime = 0; + gf_mx_v(ch->mx); } @@ -286,9 +301,6 @@ static Bool Channel_NeedsBuffering(GF_Channel *ch, u32 ForRebuffering) } return 0; } - /*we're in a broadcast scenario and one of the stream running on this clock has completed its buffering: - abort all buffering*/ - if (ch->clock->no_time_ctrl == 2) return 0; /*nothing received, buffer needed*/ if (!ch->first_au_fetched && !ch->AU_buffer_first) { @@ -298,7 +310,7 @@ static Bool Channel_NeedsBuffering(GF_Channel *ch, u32 ForRebuffering) gf_term_message(ch->odm->term, ch->service->url, "Data timeout - aborting buffering", GF_OK); ch->MinBuffer = ch->MaxBuffer = 0; ch->au_duration = 0; - gf_inline_buffering_info(ch->odm->parentscene ? ch->odm->parentscene : ch->odm->subscene); + gf_scene_buffering_info(ch->odm->parentscene ? ch->odm->parentscene : ch->odm->subscene); return 0; } else { now = ch->odm->term->net_data_timeout + ch->last_au_time - now; @@ -331,14 +343,13 @@ static Bool Channel_NeedsBuffering(GF_Channel *ch, u32 ForRebuffering) static void Channel_UpdateBuffering(GF_Channel *ch, Bool update_info) { - if (update_info && ch->MaxBuffer) gf_inline_buffering_info(ch->odm->parentscene ? ch->odm->parentscene : ch->odm->subscene); + if (update_info && ch->MaxBuffer) gf_scene_buffering_info(ch->odm->parentscene ? ch->odm->parentscene : ch->odm->subscene); gf_term_service_media_event(ch->odm, GF_EVENT_MEDIA_DATA_PROGRESS); if (!Channel_NeedsBuffering(ch, 0)) { ch_buffer_off(ch); - if (ch->MaxBuffer && update_info) gf_inline_buffering_info(ch->odm->parentscene ? ch->odm->parentscene : ch->odm->subscene); - if (ch->clock->no_time_ctrl) ch->clock->no_time_ctrl = 2; + if (ch->MaxBuffer && update_info) gf_scene_buffering_info(ch->odm->parentscene ? ch->odm->parentscene : ch->odm->subscene); gf_term_service_media_event(ch->odm, GF_EVENT_MEDIA_PLAYABLE); } @@ -346,7 +357,7 @@ static void Channel_UpdateBuffering(GF_Channel *ch, Bool update_info) static void Channel_UpdateBufferTime(GF_Channel *ch) { - if (!ch->AU_buffer_first) { + if (!ch->AU_buffer_first || !ch->IsClockInit) { ch->BufferTime = 0; } else if (ch->skip_sl) { @@ -369,9 +380,16 @@ static void Channel_UpdateBufferTime(GF_Channel *ch) } } else { s32 bt = ch->AU_buffer_last->DTS - gf_clock_time(ch->clock); - ch->BufferTime = 0; - if (bt>0) ch->BufferTime = (u32) bt; + if (bt>0) { + ch->BufferTime = (u32) bt; + if (ch->clock->speed != FIX_ONE) { + ch->BufferTime = FIX2INT( gf_divfix( INT2FIX(ch->AU_buffer_last->DTS - ch->AU_buffer_first->DTS) , ch->clock->speed)) ; + } + } else { + ch->BufferTime = 0; + } } + ch->BufferTime += ch->au_duration; } @@ -383,7 +401,7 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) if (!ch->buffer || !ch->len) { if (ch->buffer) { - free(ch->buffer); + gf_free(ch->buffer); ch->buffer = NULL; } return; @@ -391,7 +409,7 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) au = gf_db_unit_new(); if (!au) { - free(ch->buffer); + gf_free(ch->buffer); ch->buffer = NULL; ch->len = 0; return; @@ -399,7 +417,16 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) au->CTS = ch->CTS; au->DTS = ch->DTS; - au->RAP = ch->IsRap; + if (ch->IsRap) au->flags |= GF_DB_AU_RAP; + if (ch->CTS_past_offset) { + au->CTS = ch->CTS_past_offset; + au->flags |= GF_DB_AU_CTS_IN_PAST; + ch->CTS_past_offset = 0; + } + if (ch->no_timestamps) { + au->flags |= GF_DB_AU_NO_TIMESTAMPS; + ch->no_timestamps=0; + } au->data = ch->buffer; au->dataLength = ch->len; au->PaddingBits = ch->padingBits; @@ -410,7 +437,7 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) ch->buffer = NULL; if (ch->len + ch->media_padding_bytes != ch->allocSize) { - au->data = (char*)realloc(au->data, sizeof(char) * (au->dataLength + ch->media_padding_bytes)); + au->data = (char*)gf_realloc(au->data, sizeof(char) * (au->dataLength + ch->media_padding_bytes)); } if (ch->media_padding_bytes) memset(au->data + au->dataLength, 0, sizeof(char)*ch->media_padding_bytes); @@ -425,7 +452,7 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) slh.compositionTimeStampFlag = slh.decodingTimeStampFlag = 1; slh.decodingTimeStamp = ch->net_dts; slh.compositionTimeStamp = ch->net_cts; - slh.randomAccessPointFlag = au->RAP; + slh.randomAccessPointFlag = (au->flags & GF_DB_AU_RAP) ? 1 : 0; ch->service->cache->Write(ch->service->cache, ch, au->data, au->dataLength, &slh); } @@ -441,14 +468,19 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) /*enable deinterleaving only for audio channels (some video transport may not be able to compute DTS, cf MPEG1-2/RTP) HOWEVER, we must recompute a monotone increasing DTS in case the decoder does perform frame reordering in which case the DTS is used for presentation time!!*/ - else if (ch->odm->codec && (ch->odm->codec->type!=GF_STREAM_AUDIO)) { + else if (ch->esd->decoderConfig->streamType!=GF_STREAM_AUDIO) { +#if 0 GF_DBUnit *au_prev, *ins_au; u32 DTS; - +#endif + au->DTS = 0; /*append AU*/ ch->AU_buffer_last->next = au; ch->AU_buffer_last = ch->AU_buffer_last->next; +#if 0 + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] Media deinterleaving OD %d ch %d\n", ch->esd->ESID, ch->odm->OD->objectDescriptorID)); + DTS = au->DTS; au_prev = ch->AU_buffer_first; /*locate first AU in buffer with DTS greater than new unit CTS*/ @@ -462,6 +494,7 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) } /*and apply*/ ins_au->DTS = DTS; +#endif } else { GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] Audio deinterleaving OD %d ch %d\n", ch->esd->ESID, ch->odm->OD->objectDescriptorID)); /*de-interleaving of AUs*/ @@ -475,8 +508,8 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) } assert(au_prev); if (au_prev->next->DTS==au->DTS) { - free(au->data); - free(au); + gf_free(au->data); + gf_free(au); } else { au->next = au_prev->next; au_prev->next = au; @@ -490,7 +523,7 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) ch->au_duration = 0; if (duration) ch->au_duration = (u32) ((u64)1000 * duration / ch->ts_res); - GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d - Dispatch AU CTS %d time %d Buffer %d Nb AUs %d\n", ch->esd->ESID, au->CTS, gf_clock_time(ch->clock), ch->BufferTime, ch->AU_Count)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d - Dispatch AU DTS %d - CTS %d - size %d time %d Buffer %d Nb AUs %d - First AU relative timing %d\n", ch->esd->ESID, au->DTS, au->CTS, au->dataLength, gf_clock_real_time(ch->clock), ch->BufferTime, ch->AU_Count, ch->AU_buffer_first ? ch->AU_buffer_first->DTS - gf_clock_time(ch->clock) : 0 )); /*little optimisation: if direct dispatching is possible, try to decode the AU we must lock the media scheduler to avoid deadlocks with other codecs accessing the scene or @@ -500,6 +533,8 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) u32 current_frame; GF_Terminal *term = ch->odm->term; ch_buffer_off(ch); + + gf_es_lock(ch, 0); if (gf_mx_try_lock(term->mm_mx)) { switch (ch->esd->decoderConfig->streamType) { case GF_STREAM_OD: @@ -514,6 +549,7 @@ static void Channel_DispatchAU(GF_Channel *ch, u32 duration) } gf_mx_v(term->mm_mx); } + gf_es_lock(ch, 1); current_frame = term->compositor->frame_number; /*wait for initial setup to complete before giving back the hand to the caller service*/ @@ -557,9 +593,9 @@ void Channel_ReceiveSkipSL(GF_ClientService *serv, GF_Channel *ch, char *StreamB gf_es_lock(ch, 1); au = gf_db_unit_new(); - au->RAP = 1; + au->flags = GF_DB_AU_RAP; au->DTS = gf_clock_time(ch->clock); - au->data = (char*)malloc(sizeof(char) * (ch->media_padding_bytes + StreamLength)); + au->data = (char*)gf_malloc(sizeof(char) * (ch->media_padding_bytes + StreamLength)); memcpy(au->data, StreamBuf, sizeof(char) * StreamLength); if (ch->media_padding_bytes) memset(au->data + StreamLength, 0, sizeof(char)*ch->media_padding_bytes); au->dataLength = StreamLength; @@ -597,14 +633,49 @@ void Channel_ReceiveSkipSL(GF_ClientService *serv, GF_Channel *ch, char *StreamB gf_es_lock(ch, 0); } +static void gf_es_check_timing(GF_Channel *ch) +{ + /*the first data received inits the clock - this is needed to handle clock dependencies on non-initialized + streams (eg, bifs/od depends on audio/video clock)*/ + 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)); + ch->IsClockInit = 1; + } + } + /*channel is the OCR, force a re-init of the clock since we cannot assume the AU used to init the clock was + not sent ahead of time*/ + else if (gf_es_owns_clock(ch)) { + if (!ch->clock->use_ocr) { + ch->clock->clock_init = 0; + gf_clock_set_time(ch->clock, ch->DTS); + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: initializing clock at STB %d - AU DTS %d - %d buffering - OTB %d\n", ch->esd->ESID, gf_term_get_time(ch->odm->term), ch->DTS, ch->clock->Buffering, gf_clock_time(ch->clock) )); + ch->IsClockInit = 1; + } + } + /*if channel is not the OCR, shift all time stamps to match the current time at clock init*/ + else if (!ch->IsClockInit ) { +// ch->ts_offset += gf_clock_real_time(ch->clock); + if (ch->clock->clock_init) ch->IsClockInit = 1; + } + /*deal with some broken DMB streams were the timestamps on BIFS/OD are not set (0) or completely out of sync + of the OCR clock (usually audio). If the audio codec (BSAC ...) is not found, we force re-initializing of the clock + so that video can play back correctly*/ + else if (gf_clock_time(ch->clock) * 1000 < ch->DTS) { + ch->clock->clock_init = 0; + gf_clock_set_time(ch->clock, ch->DTS); + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: re-initializing clock at STB %d - AU DTS %d - %d buffering\n", ch->esd->ESID, gf_term_get_time(ch->odm->term), ch->DTS, ch->clock->Buffering)); + ch->IsClockInit = 1; + } +} /*handles reception of an SL-PDU, logical or physical*/ -void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *StreamBuf, u32 StreamLength, GF_SLHeader *header, GF_Err reception_status) +void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *payload, u32 payload_size, GF_SLHeader *header, GF_Err reception_status) { GF_SLHeader hdr; - u32 nbAU, OldLength, size, AUSeqNum, SLHdrLen; + u32 nbAU, OldLength, size, AUSeqNum; Bool EndAU, NewAU; - char *payload; if (ch->bypass_sl_and_db) { GF_SceneDecoder *sdec; @@ -615,7 +686,7 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea sdec = (GF_SceneDecoder *)ch->odm->codec->decio; } gf_mx_p(ch->mx); - sdec->ProcessData(sdec, StreamBuf, StreamLength, ch->esd->ESID, 0, 0); + sdec->ProcessData(sdec, payload, payload_size, ch->esd->ESID, 0, 0); gf_mx_v(ch->mx); return; } @@ -624,20 +695,57 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea /*physical SL-PDU - depacketize*/ if (!header) { - if (!StreamLength) return; - gf_sl_depacketize(ch->esd->slConfig, &hdr, StreamBuf, StreamLength, &SLHdrLen); - StreamLength -= SLHdrLen; + u32 SLHdrLen; + if (!payload_size) return; + gf_sl_depacketize(ch->esd->slConfig, &hdr, payload, payload_size, &SLHdrLen); + payload_size -= SLHdrLen; + payload += SLHdrLen; } else { hdr = *header; - SLHdrLen = 0; } - payload = StreamBuf + SLHdrLen; if (ch->skip_sl) { - Channel_ReceiveSkipSL(serv, ch, payload, StreamLength); + Channel_ReceiveSkipSL(serv, ch, payload, payload_size); return; } + /*we ignore OCRs for the moment*/ + if (hdr.OCRflag) { + if (!ch->IsClockInit) { + /*channel is the OCR, re-initialize the clock with the proper OCR*/ + if (gf_es_owns_clock(ch)) { + u32 OCR_TS; + /*if SL is mapped from network module(eg not coded), OCR=PCR shall be given in 27Mhz units*/ + if (hdr.m2ts_pcr) { + OCR_TS = (u32) ( hdr.objectClockReference / 27000); + } else { + OCR_TS = (u32) ( (s64) (hdr.objectClockReference) * ch->ocr_scale); + } + ch->clock->clock_init = 0; + gf_clock_set_time(ch->clock, OCR_TS); + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: initializing clock at STB %d from OCR TS %d - %d buffering - OTB %d\n", ch->esd->ESID, gf_term_get_time(ch->odm->term), OCR_TS, ch->clock->Buffering, gf_clock_time(ch->clock) )); + if (ch->clock->clock_init) ch->IsClockInit = 1; + } + } +#if 0 + /*compute clock drift*/ + else { + u32 ck; + u32 OCR_TS; + if (hdr.m2ts_pcr) { + OCR_TS = (u32) ( hdr.objectClockReference / 27000); + } else { + OCR_TS = (u32) ( (s64) (hdr.objectClockReference) * ch->ocr_scale); + } + ck = gf_clock_time(ch->clock); + GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: At OTB %d adjusting OCR to %d (diff %d)\n", ch->esd->ESID, gf_clock_real_time(ch->clock), OCR_TS, (s32) OCR_TS - (s32) ck)); + gf_clock_set_time(ch->clock, (u32) OCR_TS); + } +#endif + if (!payload_size) return; + } + + /*check state*/ if (!ch->codec_resilient && (reception_status==GF_CORRUPTED_DATA)) { Channel_WaitRAP(ch); @@ -656,7 +764,7 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea /*get RAP*/ if (ch->esd->slConfig->hasRandomAccessUnitsOnlyFlag) { hdr.randomAccessPointFlag = 1; - } else if (!ch->esd->slConfig->useRandomAccessPointFlag || ch->codec_resilient) { + } else if ((ch->carousel_type!=GF_ESM_CAROUSEL_MPEG2) && (!ch->esd->slConfig->useRandomAccessPointFlag || ch->codec_resilient) ) { ch->stream_state = 0; } @@ -692,7 +800,6 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea } /*IDLE stream shall be processed*/ - NewAU = 0; if (hdr.accessUnitStartFlag) { NewAU = 1; @@ -705,9 +812,10 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea GF_LOG(GF_LOG_WARNING, GF_LOG_SYNC, ("[SyncLayer] ES%d: missed end of AU (DTS %d)\n", ch->esd->ESID, ch->DTS)); } if (ch->codec_resilient) { + if (!ch->IsClockInit) gf_es_check_timing(ch); Channel_DispatchAU(ch, 0); } else { - free(ch->buffer); + gf_free(ch->buffer); ch->buffer = NULL; ch->AULength = 0; ch->len = ch->allocSize = 0; @@ -715,20 +823,39 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea } AUSeqNum = hdr.AU_sequenceNumber; /*Get CTS */ - if (hdr.compositionTimeStampFlag) { - ch->net_dts = ch->net_cts = hdr.compositionTimeStamp; - /*get DTS */ - if (hdr.decodingTimeStampFlag) ch->net_dts = hdr.decodingTimeStamp; - - /*until clock is not init check seed ts*/ - if (!ch->IsClockInit && (ch->net_dts < ch->seed_ts)) - ch->seed_ts = ch->net_dts; - - ch->net_dts -= ch->seed_ts; - ch->net_cts -= ch->seed_ts; - /*TS Wraping not tested*/ - ch->CTS = (u32) (ch->ts_offset + (s64) (ch->net_cts) * 1000 / ch->ts_res); - ch->DTS = (u32) (ch->ts_offset + (s64) (ch->net_dts) * 1000 / ch->ts_res); + if (ch->esd->slConfig->useTimestampsFlag) { + if (hdr.compositionTimeStampFlag) { + ch->net_dts = ch->net_cts = hdr.compositionTimeStamp; + /*get DTS */ + if (hdr.decodingTimeStampFlag) ch->net_dts = hdr.decodingTimeStamp; + +#if 0 + /*until clock is not init check seed ts*/ + if (!ch->IsClockInit && (ch->net_dts < ch->seed_ts)) + ch->seed_ts = ch->net_dts; +#endif + + if (ch->net_cts<ch->seed_ts) { + u64 diff = ch->seed_ts - ch->net_cts; + ch->CTS_past_offset = (u32) (diff * 1000 / ch->ts_res) + ch->ts_offset; + + ch->net_dts = ch->net_cts = 0; + ch->CTS = ch->DTS = gf_clock_time(ch->clock); + } else { + if (ch->net_dts>ch->seed_ts) ch->net_dts -= ch->seed_ts; + else ch->net_dts=0; + ch->net_cts -= ch->seed_ts; + ch->CTS_past_offset = 0; + + /*TS Wraping not tested*/ + ch->CTS = (u32) (ch->ts_offset + (s64) (ch->net_cts) * 1000 / ch->ts_res); + ch->DTS = (u32) (ch->ts_offset + (s64) (ch->net_dts) * 1000 / ch->ts_res); + } + + ch->no_timestamps = 0; + } else { + ch->no_timestamps = 1; + } } else { /*use CU duration*/ if (!ch->IsClockInit) ch->DTS = ch->CTS = ch->ts_offset; @@ -751,22 +878,6 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea } } - if (!ch->IsClockInit && (hdr.compositionTimeStampFlag || !ch->esd->slConfig->useTimestampsFlag) ) { - /*the first data received inits the clock - this is needed to handle clock dependencies on non-initialized - streams (eg, bifs/od depends on audio/video clock)*/ - if (!ch->clock->clock_init) { - 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)); - } - /*channel is the OCR, force a re-init of the clock since we cannot assume the AU used to init the clock was - not sent ahead of time*/ - else if (gf_es_owns_clock(ch)) { - ch->clock->clock_init = 0; - gf_clock_set_time(ch->clock, ch->DTS); - GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: initializing clock at STB %d - AU DTS %d - %d buffering\n", ch->esd->ESID, gf_term_get_time(ch->odm->term), ch->DTS, ch->clock->Buffering)); - } - if (ch->clock->clock_init) ch->IsClockInit = 1; - } /*if the AU Length is carried in SL, get its size*/ if (ch->esd->slConfig->AULength > 0) { ch->AULength = hdr.accessUnitLength; @@ -774,43 +885,82 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea ch->AULength = 0; } /*carousel for repeated AUs.*/ - if (ch->esd->slConfig->AUSeqNumLength) { - if (hdr.randomAccessPointFlag) { - /*initial tune-in*/ - if (ch->stream_state==1) { - GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: RAP Carousel found - tuning in\n", ch->esd->ESID)); + if (ch->carousel_type) { + Bool use_rap = hdr.randomAccessPointFlag; + + if (ch->carousel_type==GF_ESM_CAROUSEL_MPEG2) { + AUSeqNum = hdr.m2ts_version_number_plus_one-1; + /*mpeg-2 section carrouseling does not take into account the RAP nature of the tables*/ + + + if (AUSeqNum==ch->au_sn) { + if (ch->stream_state) { + ch->stream_state=0; + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: MPEG-2 Carousel: tuning in\n", ch->esd->ESID)); + } else { + ch->skip_carousel_au = 1; + GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: MPEG-2 Carousel: repeated AU (TS %d) - skipping\n", ch->esd->ESID, ch->CTS)); + return; + } + } else { + GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: MPEG-2 Carousel: updated AU (TS %d)\n", ch->esd->ESID, ch->CTS)); + ch->stream_state=0; ch->au_sn = AUSeqNum; - ch->stream_state = 0; } - /*carousel RAP*/ - else if (AUSeqNum == ch->au_sn) { - /*error recovery*/ - if (ch->stream_state==2) { - GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: RAP Carousel found - recovering\n", ch->esd->ESID)); + } else { + if (hdr.randomAccessPointFlag) { + /*initial tune-in*/ + if (ch->stream_state==1) { + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: RAP Carousel found (TS %d) - tuning in\n", ch->esd->ESID, ch->CTS)); + ch->au_sn = AUSeqNum; + ch->stream_state = 0; + } + /*carousel RAP*/ + else if (AUSeqNum == ch->au_sn) { + /*error recovery*/ + if (ch->stream_state==2) { + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: RAP Carousel found (TS %d) - recovering\n", ch->esd->ESID, ch->CTS)); + ch->stream_state = 0; + } + else { + ch->skip_carousel_au = 1; + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: RAP Carousel found (TS %d) - skipping\n", ch->esd->ESID, ch->CTS)); + return; + } + } + /*regular RAP*/ + else { + if (ch->stream_state==2) { + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: RAP Carousel found (TS %d) - recovering from previous errors\n", ch->esd->ESID, ch->CTS)); + } + ch->au_sn = AUSeqNum; ch->stream_state = 0; + } + } + /*regular AU but waiting for RAP*/ + else if (ch->stream_state) { + ch->skip_carousel_au = 1; + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: Waiting for RAP Carousel - skipping\n", ch->esd->ESID)); + return; + } + /*previous packet(s) loss: check for critical or non-critical AUs*/ + else if (reception_status == GF_REMOTE_SERVICE_ERROR) { + if (ch->au_sn == AUSeqNum) { + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: Lost a non critical packet\n", ch->esd->ESID)); } + /*Packet lost are critical*/ else { - ch->skip_carousel_au = 1; - GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: RAP Carousel found - skipping\n", ch->esd->ESID)); + ch->stream_state = 2; + GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: Lost a critical packet - skipping\n", ch->esd->ESID)); return; } - } - /*regular RAP*/ - else { + } else { ch->au_sn = AUSeqNum; - ch->stream_state = 0; + GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: NON-RAP AU received (TS %d)\n", ch->esd->ESID, ch->DTS)); } - } - /*regular AU but waiting for RAP*/ - else if (ch->stream_state) { - ch->skip_carousel_au = 1; - GF_LOG(GF_LOG_INFO, GF_LOG_SYNC, ("[SyncLayer] ES%d: Waiting for RAP Carousel - skipping\n", ch->esd->ESID)); - return; - } else { - ch->au_sn = AUSeqNum; - GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: NON-RAP AU received\n", ch->esd->ESID)); } } + /*no carousel signaling, tune-in at first RAP*/ else if (hdr.randomAccessPointFlag) { ch->stream_state = 0; @@ -825,35 +975,24 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea /*update the RAP marker on a packet base (to cope with AVC/H264 NALU->AU reconstruction)*/ if (hdr.randomAccessPointFlag) ch->IsRap = 1; - /* we need to skip all the packets of the current AU in the carousel scenario */ - if (ch->skip_carousel_au == 1) return; - - /*we ignore OCRs for the moment*/ -#if 0 - /*Apply OCR*/ - if (!ch->BufferOn && ch->IsClockInit && hdr.OCRflag) { - u32 OCR_TS = (u32) (s64) (((s64) hdr.objectClockReference) * ch->ocr_scale); - u32 ck = gf_clock_time(ch->clock); - OCR_TS += ch->BufferTime; - fprintf(stdout, "OCR %d OTB %d Diff %d Buffer %d (%d AUs) \n", OCR_TS, ck, OCR_TS - ck, ch->BufferTime, ch->AU_Count); - - GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: At OTB %d adjusting OCR to %d\n", ch->esd->ESID, gf_clock_real_time(ch->clock), OCR_TS)); - gf_clock_set_time(ch->clock, OCR_TS); - } -#endif /*get AU end state*/ OldLength = ch->buffer ? ch->len : 0; EndAU = hdr.accessUnitEndFlag; - if (ch->AULength == OldLength + StreamLength) EndAU = 1; + if (ch->AULength == OldLength + payload_size) EndAU = 1; if (EndAU) ch->NextIsAUStart = 1; - if (!StreamLength && EndAU && ch->buffer) { + if (EndAU && !ch->IsClockInit) 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; + + if (!payload_size && EndAU && ch->buffer) { GF_LOG(GF_LOG_DEBUG, GF_LOG_SYNC, ("[SyncLayer] ES%d: Empty packet, flushing buffer\n", ch->esd->ESID)); Channel_DispatchAU(ch, 0); return; } - if (!StreamLength) return; + if (!payload_size) return; /*missed begining, unusable*/ if (!ch->buffer && !NewAU) { @@ -869,8 +1008,8 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea /*we should NEVER have a bitstream at this stage*/ assert(!ch->buffer); /*ignore length fields*/ - size = StreamLength + ch->media_padding_bytes; - ch->buffer = (char*)malloc(sizeof(char) * size); + size = payload_size + ch->media_padding_bytes; + ch->buffer = (char*)gf_malloc(sizeof(char) * size); if (!ch->buffer) { assert(0); return; @@ -889,7 +1028,7 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea evt.event_type=GF_IPMP_TOOL_PROCESS_DATA; evt.channel = ch; evt.data = payload; - evt.data_size = StreamLength; + evt.data_size = payload_size; evt.is_encrypted = hdr.isma_encrypted; evt.isma_BSO = hdr.isma_BSO; e = ch->ipmp_tool->process(ch->ipmp_tool, &evt); @@ -901,9 +1040,9 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea /*restart*/ if (evt.restart_requested) { if (ch->odm->parentscene->is_dynamic_scene) { - gf_inline_restart_dynamic(ch->odm->parentscene, 0); + gf_scene_restart_dynamic(ch->odm->parentscene, 0); } else { - MC_Restart(ch->odm); + mediacontrol_restart(ch->odm); } } } @@ -917,15 +1056,15 @@ void gf_es_receive_sl_packet(GF_ClientService *serv, GF_Channel *ch, char *Strea } else { /*check if enough space*/ size = ch->allocSize; - if (size && (StreamLength + ch->len <= size)) { - memcpy(ch->buffer+ch->len, payload, StreamLength); - ch->len += StreamLength; + if (size && (payload_size + ch->len <= size)) { + memcpy(ch->buffer+ch->len, payload, payload_size); + ch->len += payload_size; } else { - size = StreamLength + ch->len + ch->media_padding_bytes; - ch->buffer = (char*)realloc(ch->buffer, sizeof(char) * size); - memcpy(ch->buffer+ch->len, payload, StreamLength); + size = payload_size + ch->len + ch->media_padding_bytes; + ch->buffer = (char*)gf_realloc(ch->buffer, sizeof(char) * size); + memcpy(ch->buffer+ch->len, payload, payload_size); ch->allocSize = size; - ch->len += StreamLength; + ch->len += payload_size; } if (hdr.paddingFlag) ch->padingBits = hdr.paddingBits; } @@ -943,7 +1082,6 @@ void gf_es_on_eos(GF_Channel *ch) /*flush buffer*/ ch_buffer_off(ch); - ch->clock->has_seen_eos = 1; gf_odm_on_eos(ch->odm, ch); } @@ -968,6 +1106,8 @@ GF_DBUnit *gf_es_get_au(GF_Channel *ch) /*pull from stream - resume clock if needed*/ ch_buffer_off(ch); + memset(&slh, 0, sizeof(GF_SLHeader)); + e = gf_term_channel_get_sl_packet(ch->service, ch, (char **) &ch->AU_buffer_pull->data, &ch->AU_buffer_pull->dataLength, &slh, &comp, &state, &is_new_data); if (e) state = e; switch (state) { @@ -977,8 +1117,12 @@ GF_DBUnit *gf_es_get_au(GF_Channel *ch) case GF_OK: break; default: - gf_term_message(ch->odm->term, ch->service->url , "Data reception failure", state); - return NULL; + { + char m[100]; + sprintf(m, "Data reception failure on channel %d", ch->esd->ESID); + gf_term_message(ch->odm->term, ch->service->url , m, state); + return NULL; + } } assert(!comp); /*update timing if new stream data but send no data*/ @@ -1002,9 +1146,9 @@ GF_DBUnit *gf_es_get_au(GF_Channel *ch) /*restart*/ if (evt.restart_requested) { if (ch->odm->parentscene->is_dynamic_scene) { - gf_inline_restart_dynamic(ch->odm->parentscene, 0); + gf_scene_restart_dynamic(ch->odm->parentscene, 0); } else { - MC_Restart(ch->odm); + mediacontrol_restart(ch->odm); } } } @@ -1022,7 +1166,7 @@ GF_DBUnit *gf_es_get_au(GF_Channel *ch) ch->AU_buffer_pull->CTS = (u32) ch->CTS; ch->AU_buffer_pull->DTS = (u32) ch->DTS; ch->AU_buffer_pull->PaddingBits = ch->padingBits; - ch->AU_buffer_pull->RAP = ch->IsRap; + if (ch->IsRap) ch->AU_buffer_pull->flags |= GF_DB_AU_RAP; return ch->AU_buffer_pull; } @@ -1109,7 +1253,7 @@ static void refresh_non_interactive_clocks(GF_ObjectManager *odm) u32 i, j; GF_Channel *ch; GF_ObjectManager *test_od; - GF_InlineScene *in_scene; + GF_Scene *in_scene; /*check for inline*/ in_scene = odm->subscene ? odm->subscene : odm->parentscene; @@ -1122,7 +1266,7 @@ static void refresh_non_interactive_clocks(GF_ObjectManager *odm) } i=0; - while ((test_od = (GF_ObjectManager *)gf_list_enum(in_scene->ODlist, &i)) ) { + while ((test_od = (GF_ObjectManager *)gf_list_enum(in_scene->resources, &i)) ) { j=0; while ((ch = (GF_Channel*)gf_list_enum(test_od->channels, &j)) ) { if (ch->clock->no_time_ctrl) { @@ -1180,8 +1324,8 @@ void gf_es_on_connect(GF_Channel *ch) /*turn off buffering for JPEG and PNG*/ switch (ch->esd->decoderConfig->objectTypeIndication) { - case 0x6C: - case 0x6D: + case GPAC_OTI_IMAGE_JPEG: + case GPAC_OTI_IMAGE_PNG: can_buffer = 0; break; } @@ -1223,8 +1367,10 @@ void gf_es_on_connect(GF_Channel *ch) /*get duration*/ com.command_type = GF_NET_CHAN_DURATION; com.base.on_channel = ch; - if (gf_term_service_command(ch->service, &com) == GF_OK) - gf_odm_set_duration(ch->odm, ch, (u64) (1000*com.duration.duration)); + if (gf_term_service_command(ch->service, &com) == GF_OK) { + if (com.duration.duration>=0) + gf_odm_set_duration(ch->odm, ch, (u64) (1000*com.duration.duration)); + } } void gf_es_config_drm(GF_Channel *ch, GF_NetComDRMConfig *drm_cfg) diff --git a/src/terminal/clock.c b/src/terminal/clock.c index 3787f51..466b0f8 100644 --- a/src/terminal/clock.c +++ b/src/terminal/clock.c @@ -4,14 +4,14 @@ * Copyright (c) Jean Le Feuvre 2000-2005 * All rights reserved * - * This file is part of GPAC / Media terminal sub-project + * This file scene part of GPAC / Media terminal sub-project * - * GPAC is free software; you can redistribute it and/or modify + * GPAC scene 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, + * GPAC scene 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. @@ -39,7 +39,7 @@ GF_Clock *NewClock(GF_Terminal *term) void gf_clock_del(GF_Clock *ck) { gf_mx_del(ck->mx); - free(ck); + gf_free(ck); } GF_Clock *gf_clock_find(GF_List *Clocks, u16 clockID, u16 ES_ID) @@ -57,7 +57,7 @@ GF_Clock *gf_clock_find(GF_List *Clocks, u16 clockID, u16 ES_ID) return NULL; } -GF_Clock *CK_LookForClockDep(struct _inline_scene *is, u16 clockID) +GF_Clock *CK_LookForClockDep(GF_Scene *scene, u16 clockID) { u32 i, j; GF_Channel *ch; @@ -65,12 +65,12 @@ GF_Clock *CK_LookForClockDep(struct _inline_scene *is, u16 clockID) /*check in top OD*/ i=0; - while ((ch = (GF_Channel*)gf_list_enum(is->root_od->channels, &i))) { + while ((ch = (GF_Channel*)gf_list_enum(scene->root_od->channels, &i))) { if (ch->esd->ESID == clockID) return ch->clock; } /*check in sub ODs*/ j=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &j))) { + while ((odm = (GF_ObjectManager*)gf_list_enum(scene->resources, &j))) { i=0; while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i))) { if (ch->esd->ESID == clockID) return ch->clock; @@ -80,32 +80,36 @@ GF_Clock *CK_LookForClockDep(struct _inline_scene *is, u16 clockID) } /*remove clocks created due to out-of-order OCR dependencies*/ -void CK_ResolveClockDep(GF_List *clocks, struct _inline_scene *is, GF_Clock *ck, u16 Clock_ESID) +void CK_ResolveClockDep(GF_List *clocks, GF_Scene *scene, GF_Clock *ck, u16 Clock_ESID) { u32 i, j; GF_Clock *clock; GF_Channel *ch; GF_ObjectManager *odm; - /*check all channels - if any is using a clock which ID is the clock_ESID then + /*check all channels - if any scene using a clock which ID == the clock_ESID then this clock shall be removed*/ i=0; - while ((ch = (GF_Channel*)gf_list_enum(is->root_od->channels, &i))) { + while ((ch = (GF_Channel*)gf_list_enum(scene->root_od->channels, &i))) { if (ch->clock->clockID == Clock_ESID) { - if (is->scene_codec && is->scene_codec->ck == ch->clock) is->scene_codec->ck = ck; - if (is->od_codec && is->od_codec->ck == ch->clock) is->od_codec->ck = ck; - if (is->root_od->oci_codec && is->root_od->oci_codec->ck == ch->clock) is->root_od->oci_codec->ck = ck; + if (scene->scene_codec && scene->scene_codec->ck == ch->clock) scene->scene_codec->ck = ck; + if (scene->od_codec && scene->od_codec->ck == ch->clock) scene->od_codec->ck = ck; +#ifndef GPAC_MINIMAL_ODF + if (scene->root_od->oci_codec && scene->root_od->oci_codec->ck == ch->clock) scene->root_od->oci_codec->ck = ck; +#endif ch->clock = ck; if (ch->esd) ch->esd->OCRESID = ck->clockID; } } j=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &j))) { + while ((odm = (GF_ObjectManager*)gf_list_enum(scene->resources, &j))) { i=0; while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i))) { if (ch->clock->clockID == Clock_ESID) { if (odm->codec && (odm->codec->ck==ch->clock)) odm->codec->ck = ck; +#ifndef GPAC_MINIMAL_ODF if (odm->oci_codec && (odm->oci_codec->ck==ch->clock)) odm->oci_codec->ck = ck; +#endif ch->clock = ck; if (ch->esd) ch->esd->OCRESID = ck->clockID; } @@ -122,22 +126,22 @@ void CK_ResolveClockDep(GF_List *clocks, struct _inline_scene *is, GF_Clock *ck, } } -GF_Clock *gf_clock_attach(GF_List *clocks, struct _inline_scene *is, u16 clockID, u16 ES_ID, s32 hasOCR) +GF_Clock *gf_clock_attach(GF_List *clocks, GF_Scene *scene, u16 clockID, u16 ES_ID, s32 hasOCR) { Bool check_dep; GF_Clock *tmp = gf_clock_find(clocks, clockID, ES_ID); /*ck dep can only be solved if in the main service*/ - check_dep = (is->root_od->net_service && is->root_od->net_service->Clocks==clocks) ? 1 : 0; + check_dep = (scene->root_od->net_service && scene->root_od->net_service->Clocks==clocks) ? 1 : 0; /*this partly solves a->b->c*/ - if (!tmp && check_dep) tmp = CK_LookForClockDep(is, clockID); + if (!tmp && check_dep) tmp = CK_LookForClockDep(scene, clockID); if (!tmp) { - tmp = NewClock(is->root_od->term); + tmp = NewClock(scene->root_od->term); tmp->clockID = clockID; gf_list_add(clocks, tmp); } else { if (tmp->clockID == ES_ID) tmp->clockID = clockID; /*this finally solves a->b->c*/ - if (check_dep && (tmp->clockID != ES_ID)) CK_ResolveClockDep(clocks, is, tmp, ES_ID); + if (check_dep && (tmp->clockID != ES_ID)) CK_ResolveClockDep(clocks, scene, tmp, ES_ID); } if (hasOCR >= 0) tmp->use_ocr = hasOCR; return tmp; @@ -148,7 +152,7 @@ void gf_clock_reset(GF_Clock *ck) ck->clock_init = 0; ck->drift = 0; ck->discontinuity_time = 0; - //do NOT reset buffering flag, because RESET is called only + //do NOT reset buffering flag, because RESET scene called only //for the stream owning the clock, and other streams may //have signaled buffering on this clock ck->init_time = 0; @@ -173,13 +177,15 @@ void gf_clock_set_time(GF_Clock *ck, u32 TS) ck->PauseTime = ck->StartTime = gf_term_get_time(ck->term); if (ck->term->play_state) ck->Paused ++; } +#if 0 /*TODO: test with pure OCR streams*/ else if (ck->use_ocr) { /*just update the drift - we could also apply a drift algo*/ u32 now = gf_clock_real_time(ck); - s32 drift = now - (u32) TS; + s32 drift = (s32) TS - (s32) now; ck->drift += drift; } +#endif } @@ -237,7 +243,7 @@ Bool gf_clock_is_started(GF_Clock *ck) return 1; } -/*buffering is protected by a mutex because it may be triggered by composition memory (audio or visual threads)*/ +/*buffering scene protected by a mutex because it may be triggered by composition memory (audio or visual threads)*/ void gf_clock_buffer_on(GF_Clock *ck) { gf_mx_p(ck->mx); @@ -264,7 +270,7 @@ void gf_clock_set_speed(GF_Clock *ck, Fixed speed) if (speed==ck->speed) return; time = gf_term_get_time(ck->term); /*adjust start time*/ - ck->discontinuity_time = gf_clock_time(ck); + ck->discontinuity_time = gf_clock_time(ck) - ck->init_time; ck->PauseTime = ck->StartTime = time; ck->speed = speed; } diff --git a/src/terminal/decoder.c b/src/terminal/decoder.c index f8e3d8a..883b513 100644 --- a/src/terminal/decoder.c +++ b/src/terminal/decoder.c @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -27,6 +27,7 @@ #include <gpac/internal/terminal_dev.h> #include <gpac/internal/compositor_dev.h> #include <gpac/constants.h> +#include <gpac/crypt.h> #include "media_memory.h" #include "media_control.h" #include "input_sensor.h" @@ -48,16 +49,15 @@ GF_Codec *gf_codec_new(GF_ObjectManager *odm, GF_ESD *base_layer, s32 PL, GF_Err if (PL<0) PL = 0xFF; *e = Codec_Load(tmp, base_layer, PL); - + if (*e) { - free(tmp); + gf_free(tmp); return NULL; } /*remember codec type*/ tmp->type = base_layer->decoderConfig->streamType; - tmp->inChannels = gf_list_new(); + tmp->inChannels = gf_list_new(); tmp->Status = GF_ESM_CODEC_STOP; - return tmp; } @@ -67,7 +67,7 @@ GF_Codec *gf_codec_use_codec(GF_Codec *codec, GF_ObjectManager *odm) if (!codec->decio) return NULL; GF_SAFEALLOC(tmp, GF_Codec); tmp->type = codec->type; - tmp->inChannels = gf_list_new(); + tmp->inChannels = gf_list_new(); tmp->Status = GF_ESM_CODEC_STOP; tmp->odm = odm; tmp->flags = codec->flags | GF_ESM_CODEC_IS_USE; @@ -95,7 +95,7 @@ GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch) if (ch->esd->decoderConfig->decoderSpecificInfo) { dsi = ch->esd->decoderConfig->decoderSpecificInfo->data; dsiSize = ch->esd->decoderConfig->decoderSpecificInfo->dataLength; - } + } /*For objects declared in OD stream, override with network DSI if any*/ if (ch->service && !(ch->odm->flags & GF_ODM_NOT_IN_OD_STREAM) ) { com.command_type = GF_NET_CHAN_GET_DSI; @@ -105,7 +105,7 @@ GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch) dsi = com.get_dsi.dsi; dsiSize = com.get_dsi.dsi_len; - if (ch->esd->decoderConfig->decoderSpecificInfo->data) free(ch->esd->decoderConfig->decoderSpecificInfo->data); + if (ch->esd->decoderConfig->decoderSpecificInfo->data) gf_free(ch->esd->decoderConfig->decoderSpecificInfo->data); ch->esd->decoderConfig->decoderSpecificInfo->data = com.get_dsi.dsi; ch->esd->decoderConfig->decoderSpecificInfo->dataLength = com.get_dsi.dsi_len; } @@ -153,19 +153,22 @@ GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch) } if ((codec->type==GF_STREAM_AUDIO) && (max<2)) max = 2; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[ODM] Creating composition buffer for codec %s - %d units %d bytes each\n", codec->decio->module_name, max, CUsize)); /*setup CB*/ if (!codec->CB && max) { + GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[ODM] Creating composition buffer for codec %s - %d units %d bytes each\n", codec->decio->module_name, max, CUsize)); + codec->CB = gf_cm_new(CUsize, max); codec->CB->Min = min; codec->CB->odm = codec->odm; } - /*check re-ordering - set by default on all codecs*/ - codec->is_reordering = 1; - cap.CapCode = GF_CODEC_REORDER; - if (gf_codec_get_capability(codec, &cap) == GF_OK); - codec->is_reordering = cap.cap.valueInt; + if (codec->CB) { + /*check re-ordering - set by default on all codecs*/ + codec->is_reordering = 1; + cap.CapCode = GF_CODEC_REORDER; + if (gf_codec_get_capability(codec, &cap) == GF_OK) + codec->is_reordering = cap.cap.valueInt; + } /*setup net channel config*/ if (ch->service) { @@ -174,7 +177,7 @@ GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch) com.base.on_channel = ch; com.cfg.priority = ch->esd->streamPriority; - com.cfg.sync_id = (u32) ch->clock; + com.cfg.sync_id = ch->clock->clockID; memcpy(&com.cfg.sl_config, ch->esd->slConfig, sizeof(GF_SLConfig)); /*get the frame duration if audio (used by some network stack)*/ if (ch->odm->codec && (ch->odm->codec->type==GF_STREAM_AUDIO) ) { @@ -184,8 +187,21 @@ GF_Err gf_codec_add_channel(GF_Codec *codec, GF_Channel *ch) cap.CapCode = GF_CODEC_CU_DURATION; gf_codec_get_capability(ch->odm->codec, &cap); com.cfg.frame_duration = cap.cap.valueInt; - } + } gf_term_service_command(ch->service, &com); + + ch->carousel_type = GF_ESM_CAROUSEL_NONE; + if (com.cfg.use_m2ts_sections) { + ch->carousel_type = GF_ESM_CAROUSEL_MPEG2; + } else { + switch (ch->esd->decoderConfig->streamType) { + case GF_STREAM_OD: + case GF_STREAM_SCENE: + ch->carousel_type = ch->esd->slConfig->AUSeqNumLength ? GF_ESM_CAROUSEL_MPEG4 : GF_ESM_CAROUSEL_NONE; + break; + } + } + } } @@ -269,7 +285,7 @@ static void Decoder_GetNextAU(GF_Codec *codec, GF_Channel **activeChannel, GF_DB if ((codec->type==GF_STREAM_OCR) && ch->IsClockInit) { /*check duration - we assume that scalable OCR streams are just pure nonsense...*/ if (ch->is_pulling && codec->odm->duration) { - if (gf_clock_time(codec->ck) > codec->odm->duration) + if (gf_clock_time(codec->ck) > codec->odm->duration) gf_es_on_eos(ch); } return; @@ -291,7 +307,7 @@ static void Decoder_GetNextAU(GF_Codec *codec, GF_Channel **activeChannel, GF_DB } /*FIXME - we're breaking sync (couple of frames delay)*/ - if (*nextAU && codec->is_reordering) + if (codec->is_reordering && *nextAU) (*nextAU)->CTS = (*nextAU)->DTS; } @@ -300,20 +316,20 @@ static GF_Err SystemCodec_Process(GF_Codec *codec, u32 TimeAvailable) { GF_DBUnit *AU; GF_Channel *ch; - u32 now, obj_time, mm_level, au_time; - Bool scene_locked; + u32 now, obj_time, mm_level, au_time, cts; + GF_Scene *scene_locked; Bool check_next_unit; GF_SceneDecoder *sdec = (GF_SceneDecoder *)codec->decio; GF_Err e = GF_OK; - scene_locked = 0; - + scene_locked = NULL; + /*for resync, if needed - the logic behind this is that there is no composition memory on sytems codecs so "frame dropping" is done by preventing the compositor from redrawing after an update and decoding following AU - so that the compositor is always woken up once all late systems AUs are decoded. This flag is overriden when + so that the compositor is always woken up once all late systems AUs are decoded. This flag is overriden when seeking*/ check_next_unit = (codec->odm->term->flags & GF_TERM_SYSDEC_RESYNC) ? 1 : 0; - + check_unit: /*muting systems codec means we don't decode until mute is off - likely there will be visible however @@ -334,7 +350,7 @@ check_unit: if (!cap.cap.valueInt) { gf_term_stop_codec(codec); 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 + /*this is just by safety, since seeking is only allowed when a single clock is present in the scene*/ if (gf_list_count(codec->odm->net_service->Clocks)==1) codec->odm->subscene->static_media_ressources=1; @@ -343,9 +359,11 @@ check_unit: } goto exit; } - - if (ch && ch->odm->media_ctrl && !ch->odm->media_ctrl->media_speed) + +#ifndef GPAC_DISABLE_VRML + if (ch && ch->odm->media_ctrl && !ch->odm->media_ctrl->media_speed) goto exit; +#endif /*get the object time*/ obj_time = gf_clock_time(codec->ck); @@ -356,48 +374,57 @@ check_unit: /*check timing based on the input channel and main FPS*/ if (AU->DTS > obj_time /*+ codec->odm->term->half_frame_duration*/) goto exit; - /*check seeking and update timing - do NOT use the base layer, since BIFS streams may depend on other + cts = AU->CTS; + /*in cases where no CTS was set for the BIFS (which may be interpreted as "now", although not compliant), use the object clock*/ + if (AU->flags & GF_DB_AU_NO_TIMESTAMPS) au_time = obj_time; + /*case where CTS is in the past (carousels) */ + else if (AU->flags & GF_DB_AU_CTS_IN_PAST) { + au_time = - (s32) AU->CTS; + cts = AU->DTS; + } + /*regular case, SFTime will be from CTS (since DTS == CTS)*/ + else au_time = AU->DTS; + + /*check seeking and update timing - do NOT use the base layer, since BIFS streams may depend on other streams not on the same clock*/ - if (codec->last_unit_cts == AU->CTS ) { - /*hack for RTSP streaming of systems streams, except InputSensor*/ - if (!ch->is_pulling && (codec->type != GF_STREAM_INTERACT) && (AU->dataLength == codec->prev_au_size)) { - gf_es_drop_au(ch); - GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[SysDec] Same MPEG-4 Systems AU detected - dropping\n")); - goto check_unit; - } + if (codec->last_unit_cts == cts) { /*seeking for systems is done by not releasing the graph until seek is done*/ check_next_unit = 1; mm_level = GF_CODEC_LEVEL_SEEK; - au_time = AU->DTS; - } + } /*set system stream timing*/ else { codec->last_unit_cts = AU->CTS; /*we're droping the frame*/ if (scene_locked) codec->nb_droped ++; mm_level = GF_CODEC_LEVEL_NORMAL; - au_time = AU->DTS; } /*lock scene*/ if (!scene_locked) { - if (!gf_mx_try_lock(codec->odm->term->compositor->mx)) return GF_OK; - //gf_term_lock_compositor(codec->odm->term, 1); - scene_locked = 1; + scene_locked = codec->odm->subscene ? codec->odm->subscene : codec->odm->parentscene; + if (!gf_mx_try_lock(scene_locked->mx)) return GF_OK; + if (scene_locked==scene_locked->root_od->term->root_scene) { + if (!gf_mx_try_lock(scene_locked->root_od->term->compositor->mx)) { + gf_mx_v(scene_locked->mx); + return GF_OK; + } + } /*if terminal is paused, force step-mode: it won't hurt in regular pause/play and ensures proper frame dumping*/ if (codec->odm->term->play_state) codec->odm->term->compositor->step_mode=1; } - /*current media time for system objects is the clock time, since the media is likely to have random + /*current media time for system objects is the clock time, since the media is likely to have random updates in time*/ codec->odm->current_time = gf_clock_time(codec->ck); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[SysDec] Codec %s AU CTS %d channel %d OTB %d\n", sdec->module_name , AU->CTS, ch->esd->ESID, codec->odm->current_time)); now = gf_term_get_time(codec->odm->term); e = sdec->ProcessData(sdec, AU->data, AU->dataLength, ch->esd->ESID, au_time, mm_level); now = gf_term_get_time(codec->odm->term) - now; + GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[%s] ODM%d#CH%d at %d decoded AU TS %d in %d ms\n", sdec->module_name, codec->odm->OD->objectDescriptorID, ch->esd->ESID, codec->odm->current_time, AU->CTS, now)); + codec_update_stats(codec, AU->dataLength, now); codec->prev_au_size = AU->dataLength; @@ -405,32 +432,38 @@ check_unit: gf_es_drop_au(ch); if (e) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CODEC, ("[SysDec] Codec %s AU CTS %d Decode error %s\n", sdec->module_name , AU->CTS, gf_error_to_string(e) )); if (e<0) ch->stream_state = 2; goto exit; } /*in broadcast mode, generate a scene if none is available*/ if (codec->ck->no_time_ctrl) { - GF_InlineScene *is = codec->odm->subscene ? codec->odm->subscene : codec->odm->parentscene; + GF_Scene *scene = codec->odm->subscene ? codec->odm->subscene : codec->odm->parentscene; /*static OD resources (embedded in ESD) in broadcast mode, reset time*/ if (codec->flags & GF_ESM_CODEC_IS_STATIC_OD) gf_clock_reset(codec->ck); /*generate a temp scene if none is in place*/ - if (is->graph_attached != 1) { - Bool prev_dyn = is->is_dynamic_scene; - is->is_dynamic_scene = 1; - gf_inline_regenerate(is); - is->graph_attached = 2; - is->is_dynamic_scene = prev_dyn; + if (scene->graph_attached != 1) { + Bool prev_dyn = scene->is_dynamic_scene; + scene->is_dynamic_scene = 1; + gf_scene_regenerate(scene); + scene->graph_attached = 2; + scene->is_dynamic_scene = prev_dyn; GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[Decoder] Got OD resources before scene - generating temporary scene\n")); } } /*if no release restart*/ if (check_next_unit) goto check_unit; - + exit: - if (scene_locked) gf_term_lock_compositor(codec->odm->term, 0); + if (scene_locked) { + gf_mx_v(scene_locked->mx); + if (scene_locked==scene_locked->root_od->term->root_scene) { + gf_mx_v(scene_locked->root_od->term->compositor->mx); + } + } return e; } @@ -442,9 +475,10 @@ static GF_Err PrivateScene_Process(GF_Codec *codec, u32 TimeAvailable) Bool resume_clock; u32 now; GF_Channel *ch; + GF_Scene *scene_locked; GF_SceneDecoder *sdec = (GF_SceneDecoder *)codec->decio; GF_Err e = GF_OK; - + /*muting systems codec means we don't decode until mute is off - likely there will be visible however there is no other way to decode system AUs without modifying the content, which is what mute is about on visual...*/ if (codec->Muted) return GF_OK; @@ -454,6 +488,8 @@ static GF_Err PrivateScene_Process(GF_Codec *codec, u32 TimeAvailable) return GF_OK; } + scene_locked = codec->odm->subscene ? codec->odm->subscene : codec->odm->parentscene; + ch = (GF_Channel*)gf_list_get(codec->inChannels, 0); if (!ch) return GF_OK; resume_clock = 0; @@ -461,12 +497,11 @@ static GF_Err PrivateScene_Process(GF_Codec *codec, u32 TimeAvailable) if (!ch->IsClockInit) { Bool started; /*signal seek*/ - if (!gf_mx_try_lock(codec->odm->term->compositor->mx)) return GF_OK; - //gf_term_lock_compositor(codec->odm->term, 1); + if (!gf_mx_try_lock(scene_locked->mx)) return GF_OK; gf_es_init_dummy(ch); sdec->ProcessData(sdec, NULL, 0, ch->esd->ESID, -1, GF_CODEC_LEVEL_NORMAL); - gf_term_lock_compositor(codec->odm->term, 0); + gf_mx_v(scene_locked->mx); started = gf_clock_is_started(ch->clock); /*let's be nice to the scene loader (that usually involves quite some parsing), pause clock while parsing*/ @@ -480,8 +515,7 @@ static GF_Err PrivateScene_Process(GF_Codec *codec, u32 TimeAvailable) /*lock scene*/ GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[PrivateDec] Codec %s Processing at %d\n", sdec->module_name , codec->odm->current_time)); - //gf_term_lock_compositor(codec->odm->term, 1); - if (!gf_mx_try_lock(codec->odm->term->compositor->mx)) return GF_OK; + if (!gf_mx_try_lock(scene_locked->mx)) return GF_OK; now = gf_term_get_time(codec->odm->term); e = sdec->ProcessData(sdec, NULL, 0, ch->esd->ESID, codec->odm->current_time, GF_CODEC_LEVEL_NORMAL); now = gf_term_get_time(codec->odm->term) - now; @@ -498,7 +532,7 @@ static GF_Err PrivateScene_Process(GF_Codec *codec, u32 TimeAvailable) codec_update_stats(codec, 0, now); - gf_term_lock_compositor(codec->odm->term, 0); + gf_mx_v(scene_locked->mx); if (e==GF_EOS) { /*first end of stream, evaluate duration*/ @@ -512,7 +546,7 @@ static GF_Err PrivateScene_Process(GF_Codec *codec, u32 TimeAvailable) static GFINLINE GF_Err LockCompositionUnit(GF_Codec *dec, u32 CU_TS, GF_CMUnit **cu, u32 *cu_size) { if (!dec->CB) return GF_BAD_PARAM; - + *cu = gf_cm_lock_input(dec->CB, CU_TS, dec->is_reordering); if (! *cu ) return GF_OUT_OF_MEM; *cu_size = dec->CB->UnitSize; @@ -526,7 +560,7 @@ static GFINLINE GF_Err UnlockCompositionUnit(GF_Codec *dec, GF_CMUnit *CU, u32 c if (CU->TS < dec->CB->LastRenderedTS) { GF_LOG(GF_LOG_INFO, GF_LOG_CODEC, ("[ODM] CU (TS %d) later than last frame drawn (TS %d) - droping\n", CU->TS, dec->CB->LastRenderedTS)); cu_size = 0; - } + } /*unlock the CB*/ gf_cm_unlock_input(dec->CB, CU, cu_size, dec->is_reordering); @@ -537,7 +571,7 @@ static GFINLINE GF_Err UnlockCompositionUnit(GF_Codec *dec, GF_CMUnit *CU, u32 c static GF_Err ResizeCompositionBuffer(GF_Codec *dec, u32 NewSize) { if (!dec || !dec->CB) return GF_BAD_PARAM; - + /*update config*/ gf_mo_update_caps(dec->odm->mo); @@ -547,7 +581,7 @@ static GF_Err ResizeCompositionBuffer(GF_Codec *dec, u32 NewSize) GF_LOG(GF_LOG_DEBUG, GF_LOG_CODEC, ("[ODM] Resizing composition buffer for codec %s - %d bytes per unit\n", dec->decio->module_name, NewSize)); gf_cm_resize(dec->CB, NewSize); } - } + } /*audio: make sure we have enough data in CM to entirely fill the HW audio buffer...*/ else { u32 unit_size, audio_buf_len, unit_count; @@ -575,7 +609,7 @@ static GF_Err ResizeCompositionBuffer(GF_Codec *dec, u32 NewSize) if (!dec->CB->Min) dec->CB->Min = 1; } if ((dec->type==GF_STREAM_VISUAL) && dec->odm->parentscene->is_dynamic_scene) { - gf_inline_force_scene_size_video(dec->odm->parentscene, dec->odm->mo); + gf_scene_force_size_to_video(dec->odm->parentscene, dec->odm->mo); } return GF_OK; } @@ -604,7 +638,7 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable) if (codec->Status == GF_ESM_CODEC_EOS) { /*if codec is reordering, try to flush it*/ if (codec->is_reordering) { - if ( LockCompositionUnit(codec, codec->last_unit_cts+1, &CU, &unit_size) == GF_OUT_OF_MEM) + if ( LockCompositionUnit(codec, codec->last_unit_cts+1, &CU, &unit_size) == GF_OUT_OF_MEM) return GF_OK; e = mdec->ProcessData(mdec, NULL, 0, 0, CU->data, &unit_size, 0, 0); if (e==GF_OK) e = UnlockCompositionUnit(codec, CU, unit_size); @@ -613,7 +647,7 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable) 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) + else if (ch && !ch->BufferOn) gf_cm_abort_buffering(codec->CB); return GF_OK; } @@ -626,10 +660,27 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable) gf_es_drop_au(ch); return GF_BAD_PARAM; } - /*image codecs - usually only one image is tolerated in the stream, but just in case force reset of CB*/ - if ((codec->CB->Capacity==1) && codec->CB->UnitCount && (obj_time>=AU->CTS)) { - codec->CB->output->dataLength = 0; - codec->CB->UnitCount = 0; + + /*image codecs*/ + if (codec->CB->Capacity == 1) { + /*a SHA signature is computed for each AU. This avoids decoding/recompositing when identical (for instance streaming a carousel)*/ + u8 new_unit_signature[20]; + gf_sha1_csum(AU->data, AU->dataLength, new_unit_signature); + if (!memcmp(codec->last_unit_signature, new_unit_signature, sizeof(new_unit_signature))) { + codec->nb_repeted_frames++; + gf_es_drop_au(ch); + return GF_OK; + } + codec->nb_repeted_frames = 0; + memcpy(codec->last_unit_signature, new_unit_signature, sizeof(new_unit_signature)); + + /*usually only one image is tolerated in the stream, but just in case force reset of CB*/ + if (codec->CB->UnitCount && (obj_time>=AU->CTS)) { + gf_mx_p(codec->odm->mx); + codec->CB->output->dataLength = 0; + codec->CB->UnitCount = 0; + gf_mx_v(codec->odm->mx); + } } /*try to refill the full buffer*/ @@ -641,7 +692,12 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable) if (!ch->skip_sl && codec->last_unit_cts && (codec->last_unit_cts == AU->CTS) && !ch->esd->dependsOnESID) { mmlevel = GF_CODEC_LEVEL_SEEK; /*object clock is paused by media control or terminal is paused: exact frame seek*/ - if ((codec->ck->mc && codec->ck->mc->paused) || (codec->odm->term->play_state)) { + if ( +#ifndef GPAC_DISABLE_VRML + (codec->ck->mc && codec->ck->mc->paused) || +#endif + (codec->odm->term->play_state) + ) { gf_cm_rewind_input(codec->CB); mmlevel = GF_CODEC_LEVEL_NORMAL; /*force staying in step-mode*/ @@ -654,7 +710,13 @@ static GF_Err MediaCodec_Process(GF_Codec *codec, u32 TimeAvailable) NOTE: the 100 ms safety gard is to avoid discarding audio*/ if (!ch->skip_sl && (AU->CTS + 100 < obj_time) ) { mmlevel = GF_CODEC_LEVEL_DROP; - GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[Decoder] ODM%d: frame too late (%d vs %d) - using drop level\n", codec->odm->OD->objectDescriptorID, AU->CTS, obj_time)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[%s] ODM%d: frame too late (%d vs %d) - using drop level\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, AU->CTS, obj_time)); + + if (ch->resync_drift && (AU->CTS + ch->resync_drift < obj_time)) { + ch->clock->StartTime += (obj_time - AU->CTS); + GF_LOG(GF_LOG_WARNING, GF_LOG_MEDIA, ("[%s] ODM%d: decoder too slow on OCR stream - rewinding clock of %d ms\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, obj_time - AU->CTS)); + obj_time = gf_clock_time(codec->ck); + } } /*we are late according to the media manager*/ else if (codec->PriorityBoost) { @@ -686,14 +748,17 @@ 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) return GF_OK; scalable_retry: now = gf_term_get_time(codec->odm->term); - e = mdec->ProcessData(mdec, AU->data, AU->dataLength, ch->esd->ESID, CU->data, &unit_size, AU->PaddingBits, mmlevel); + if (!CU->data && unit_size) + e = GF_OUT_OF_MEM; + 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; @@ -708,11 +773,11 @@ scalable_retry: /*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_SEEK) unit_size = 0; e = UnlockCompositionUnit(codec, CU, unit_size); - GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI|GF_LOG_CODEC, ("[%s] ODM%d at %d decoded packed frame TS %d in %d ms\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, obj_time, AU->CTS, now)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI|GF_LOG_CODEC, ("[%s] ODM%d at %d decoded packed frame TS %d in %d ms\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock), AU->CTS, now)); if (ch->skip_sl) { if (codec->bytes_per_sec) { codec->cur_audio_bytes += unit_size; @@ -737,10 +802,14 @@ scalable_retry: processing a scalable stream*/ case GF_OK: if (unit_size) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI|GF_LOG_CODEC, ("[%s] ODM%d at %d decoded frame TS %d in %d ms (DTS %d)\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, obj_time, AU->CTS, now, AU->DTS)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_RTI|GF_LOG_CODEC, ("[%s] ODM%d at %d decoded frame TS %d in %d ms (DTS %d)\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock), AU->CTS, now, AU->DTS)); + } + /*if no size the decoder is not using the composition memory - if the object is in intitial buffering resume it!!*/ + else if (codec->CB->Status == CB_BUFFER) { + gf_cm_abort_buffering(codec->CB); } /*in seek don't dispatch any output*/ - if (mmlevel == GF_CODEC_LEVEL_SEEK) + if (mmlevel == GF_CODEC_LEVEL_SEEK) unit_size = 0; codec_update_stats(codec, AU->dataLength, now); @@ -755,11 +824,18 @@ scalable_retry: codec->cur_video_frames += 1; } } +#ifndef GPAC_DISABLE_LOGS + if (codec->odm->flags & GF_ODM_PREFETCH) { + GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] At %d decoding frame TS %d in prefetch mode\n", codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock) )); + } +#endif break; default: unit_size = 0; /*error - if the object is in intitial buffering resume it!!*/ gf_cm_abort_buffering(codec->CB); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] At %d (frame TS %d - %d ms ): decoded error %s\n", codec->odm->OD->objectDescriptorID, gf_clock_real_time(ch->clock), AU->CTS, now, gf_error_to_string(e) )); + e = GF_OK; break; } @@ -774,9 +850,10 @@ drop: prev_ch = ch; gf_es_drop_au(ch); + AU = NULL; + if (e) { UnlockCompositionUnit(codec, CU, unit_size); - GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Decoder %s] ODM%d: decoded error %s\n", codec->decio->module_name, codec->odm->OD->objectDescriptorID, gf_error_to_string(e) )); return e; } @@ -806,7 +883,11 @@ drop: GF_Err gf_codec_process(GF_Codec *codec, u32 TimeAvailable) { if (codec->Status == GF_ESM_CODEC_STOP) return GF_OK; +#ifndef GPAC_DISABLE_VRML codec->Muted = (codec->odm->media_ctrl && codec->odm->media_ctrl->control->mute) ? 1 : 0; +#else + codec->Muted = 0; +#endif /*OCR: needed for OCR in pull mode (dummy streams used to sync various sources)*/ if (codec->type==GF_STREAM_OCR) { @@ -820,8 +901,10 @@ GF_Err gf_codec_process(GF_Codec *codec, u32 TimeAvailable) /*if the codec is in EOS state, move to STOP*/ if (codec->Status == GF_ESM_CODEC_EOS) { gf_term_stop_codec(codec); +#ifndef GPAC_DISABLE_VRML /*if a mediacontrol is ruling this OCR*/ - if (codec->odm->media_ctrl && codec->odm->media_ctrl->control->loop) MC_Restart(codec->odm); + if (codec->odm->media_ctrl && codec->odm->media_ctrl->control->loop) mediacontrol_restart(codec->odm); +#endif } } } @@ -865,11 +948,13 @@ void gf_codec_set_status(GF_Codec *codec, u32 Status) codec->nb_dec_frames = codec->total_dec_time = codec->max_dec_time = 0; codec->cur_audio_bytes = codec->cur_video_frames = 0; codec->nb_droped = 0; + codec->nb_repeted_frames = 0; + memset(codec->last_unit_signature, 0, sizeof(codec->last_unit_signature)); } else codec->Status = Status; if (!codec->CB) return; - + /*notify CB*/ switch (Status) { case GF_ESM_CODEC_PLAY: @@ -910,7 +995,7 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) } ifce_type = GF_SCENE_DECODER_INTERFACE; - if ((esd->decoderConfig->streamType==GF_STREAM_AUDIO) + if ((esd->decoderConfig->streamType==GF_STREAM_AUDIO) || (esd->decoderConfig->streamType==GF_STREAM_VISUAL) || (esd->decoderConfig->streamType==GF_STREAM_ND_SUBPIC) ) @@ -924,7 +1009,7 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) sOpt = NULL; switch (esd->decoderConfig->streamType) { case GF_STREAM_VISUAL: - if ((esd->decoderConfig->objectTypeIndication==0x6C) || (esd->decoderConfig->objectTypeIndication==0x6D)) + if ((esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_JPEG) || (esd->decoderConfig->objectTypeIndication==GPAC_OTI_IMAGE_PNG)) sOpt = gf_cfg_get_key(term->user->config, "Systems", "DefImageDec"); else sOpt = gf_cfg_get_key(term->user->config, "Systems", "DefVideoDec"); @@ -936,7 +1021,7 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) break; } } - + if (sOpt) { ifce = (GF_BaseDecoder *) gf_modules_load_interface_by_name(term->user->modules, sOpt, ifce_type); if (ifce) { @@ -944,12 +1029,12 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) codec->decio = ifce; return GF_OK; } - gf_modules_close_interface((GF_BaseInterface *) ifce); + gf_modules_close_interface((GF_BaseInterface *) ifce); } } /*prefered codec module per streamType/objectType from config*/ - sprintf(szPrefDec, "codec_%02x_%02x", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); + sprintf(szPrefDec, "codec_%02X_%02X", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); sOpt = gf_cfg_get_key(term->user->config, "Systems", szPrefDec); if (sOpt) { ifce = (GF_BaseDecoder *) gf_modules_load_interface_by_name(term->user->modules, sOpt, ifce_type); @@ -958,7 +1043,7 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) codec->decio = ifce; return GF_OK; } - gf_modules_close_interface((GF_BaseInterface *) ifce); + gf_modules_close_interface((GF_BaseInterface *) ifce); } } /*not found, check all modules*/ @@ -968,6 +1053,8 @@ static GF_Err Codec_LoadModule(GF_Codec *codec, GF_ESD *esd, u32 PL) if (!ifce) continue; if (ifce->CanHandleStream && ifce->CanHandleStream(ifce, esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication, cfg, cfg_size, PL) ) { codec->decio = ifce; + sprintf(szPrefDec, "codec_%02X_%02X", esd->decoderConfig->streamType, esd->decoderConfig->objectTypeIndication); + gf_cfg_set_key(term->user->config, "Systems", szPrefDec, ifce->module_name); return GF_OK; } gf_modules_close_interface((GF_BaseInterface *) ifce); @@ -982,16 +1069,18 @@ GF_Err Codec_Load(GF_Codec *codec, GF_ESD *esd, u32 PL) case GF_STREAM_OCR: codec->decio = NULL; return GF_OK; - /*InteractionStream is currently hardcoded*/ +#ifndef GPAC_DISABLE_VRML + /*InteractionStream */ case GF_STREAM_INTERACT: - codec->decio = (GF_BaseDecoder *) NewISCodec(PL); + codec->decio = (GF_BaseDecoder *) gf_isdec_new(esd, PL); assert(codec->decio->InterfaceType == GF_SCENE_DECODER_INTERFACE); return GF_OK; +#endif /*load decoder module*/ case GF_STREAM_VISUAL: case GF_STREAM_AUDIO: - if (!esd->decoderConfig->objectTypeIndication) + if (!esd->decoderConfig->objectTypeIndication) return GF_NON_COMPLIANT_BITSTREAM; default: return Codec_LoadModule(codec, esd, PL); @@ -1006,12 +1095,14 @@ void gf_codec_del(GF_Codec *codec) if (!(codec->flags & GF_ESM_CODEC_IS_USE)) { switch (codec->type) { /*input sensor streams are handled internally for now*/ +#ifndef GPAC_DISABLE_VRML case GF_STREAM_INTERACT: gf_mx_p(codec->odm->term->net_mx); - ISDec_Delete(codec->decio); + gf_isdec_del(codec->decio); gf_list_del_item(codec->odm->term->input_streams, codec); gf_mx_v(codec->odm->term->net_mx); break; +#endif default: gf_modules_close_interface((GF_BaseInterface *) codec->decio); break; @@ -1019,7 +1110,7 @@ void gf_codec_del(GF_Codec *codec) } if (codec->CB) gf_cm_del(codec->CB); gf_list_del(codec->inChannels); - free(codec); + gf_free(codec); } diff --git a/src/terminal/inline.c b/src/terminal/inline.c deleted file mode 100644 index 2e96602..0000000 --- a/src/terminal/inline.c +++ /dev/null @@ -1,1719 +0,0 @@ -/* - * GPAC - Multimedia Framework C SDK - * - * Copyright (c) Jean Le Feuvre 2000-2005 - * All rights reserved - * - * This file is part of GPAC / Media terminal 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. - * - */ - - - -/*for OD service types*/ -#include <gpac/constants.h> -#include <gpac/internal/terminal_dev.h> -#include "media_control.h" -#include <gpac/compositor.h> -#include <gpac/nodes_x3d.h> - -/*SVG properties*/ -#ifndef GPAC_DISABLE_SVG -#include <gpac/scenegraph_svg.h> -#endif - -/*extern proto fetcher*/ -typedef struct -{ - MFURL *url; - GF_MediaObject *mo; -} ProtoLink; - -GF_EXPORT -Double gf_inline_get_time(void *_is) -{ - GF_InlineScene *is = (GF_InlineScene *)_is; -#if 0 - u32 ret; - GF_Clock *ck; - assert(is); - ck = is->scene_codec ? is->scene_codec->ck : is->dyn_ck; - if (!ck) return 0.0; - ret = gf_clock_time(ck); - if (is->root_od->media_stop_time && (is->root_od->media_stop_time<ret)) ret = (u32) is->root_od->media_stop_time; - return ret/1000.0; -#else - return is->simulation_time; -#endif -} - -void gf_inline_sample_time(GF_InlineScene *is) -{ - u32 ret; - GF_Clock *ck; - ck = is->scene_codec ? is->scene_codec->ck : is->dyn_ck; - if (!ck) - is->simulation_time = 0; - else { - ret = gf_clock_time(ck); - if (is->root_od->media_stop_time && (is->root_od->media_stop_time<ret)) ret = (u32) is->root_od->media_stop_time; - is->simulation_time = ((Double) ret) / 1000.0; - } -} - -GF_InlineScene *gf_inline_new(GF_InlineScene *parentScene) -{ - GF_InlineScene *tmp; - GF_SAFEALLOC(tmp, GF_InlineScene); - if (! tmp) return NULL; - - tmp->ODlist = gf_list_new(); - tmp->media_objects = gf_list_new(); - tmp->extern_protos = gf_list_new(); - tmp->inline_nodes = gf_list_new(); - tmp->extra_scenes = gf_list_new(); - /*init inline scene*/ - if (parentScene) { - tmp->graph = gf_sg_new_subscene(parentScene->graph); - } else { - tmp->graph = gf_sg_new(); - } - - gf_sg_set_private(tmp->graph, tmp); - gf_sg_set_node_callback(tmp->graph, gf_term_node_callback); - gf_sg_set_scene_time_callback(tmp->graph, gf_inline_get_time); - - gf_sg_set_proto_loader(tmp->graph, gf_inline_get_proto_lib); - return tmp; -} - -void gf_inline_del(GF_InlineScene *is) -{ - gf_list_del(is->ODlist); - gf_list_del(is->inline_nodes); - assert(!gf_list_count(is->extra_scenes) ); - gf_list_del(is->extra_scenes); - - while (gf_list_count(is->extern_protos)) { - ProtoLink *pl = (ProtoLink *)gf_list_get(is->extern_protos, 0); - gf_list_rem(is->extern_protos, 0); - free(pl); - } - gf_list_del(is->extern_protos); - - /*delete scene decoder */ - if (is->scene_codec) { - GF_SceneDecoder *dec = (GF_SceneDecoder *)is->scene_codec->decio; - /*make sure the scene codec doesn't have anything left in the scene graph*/ - if (dec->ReleaseScene) dec->ReleaseScene(dec); - - gf_term_remove_codec(is->root_od->term, is->scene_codec); - gf_codec_del(is->scene_codec); - /*reset pointer to NULL in case nodes try to access scene time*/ - is->scene_codec = NULL; - } - - /*delete the scene graph*/ - gf_sg_del(is->graph); - - if (is->od_codec) { - gf_term_remove_codec(is->root_od->term, is->od_codec); - gf_codec_del(is->od_codec); - is->od_codec = NULL; - } - /*don't touch the root_od, will be deleted by the parent scene*/ - - /*clean all remaining associations*/ - while (gf_list_count(is->media_objects)) { - GF_MediaObject *obj = (GF_MediaObject *)gf_list_get(is->media_objects, 0); - if (obj->odm) obj->odm->mo = NULL; - gf_list_rem(is->media_objects, 0); - gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL); - gf_list_del(obj->nodes); - free(obj); - } - gf_list_del(is->media_objects); - - if (is->audio_url.url) free(is->audio_url.url); - if (is->visual_url.url) free(is->visual_url.url); - if (is->text_url.url) free(is->text_url.url); - if (is->fragment_uri) free(is->fragment_uri); - if (is->redirect_xml_base) free(is->redirect_xml_base); - free(is); -} - -GF_EXPORT -GF_ObjectManager *gf_inline_find_odm(GF_InlineScene *is, u16 OD_ID) -{ - GF_ObjectManager *odm; - u32 i=0; - while ((odm = (GF_ObjectManager *)gf_list_enum(is->ODlist, &i))) { - if (odm->OD && odm->OD->objectDescriptorID == OD_ID) return odm; - } - return NULL; -} - -GF_EXPORT -void gf_inline_disconnect(GF_InlineScene *is, Bool for_shutdown) -{ - u32 i; - GF_MediaObject *obj; - GF_Node *root_node; - GF_ObjectManager *odm; - GF_SceneDecoder *dec = NULL; - if (is->scene_codec) dec = (GF_SceneDecoder *)is->scene_codec->decio; - - gf_term_lock_compositor(is->root_od->term, 1); - - /*disconnect / kill all objects BEFORE reseting the scene graph since we have - potentially registered Inline nodes of the graph with the sub-scene*/ - if (!for_shutdown && is->static_media_ressources) { - i=0; - /*stop all objects but DON'T DESTROY THEM*/ - while ((odm = (GF_ObjectManager *)gf_list_enum(is->ODlist, &i))) { - if (odm->state) gf_odm_disconnect(odm, 0); - } - /*reset all stream associations*/ - i=0; - while ((obj = (GF_MediaObject*)gf_list_enum(is->media_objects, &i))) { - gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL); - gf_list_reset(obj->nodes); - } - } else { - while (gf_list_count(is->ODlist)) { - odm = (GF_ObjectManager *)gf_list_get(is->ODlist, 0); - gf_odm_disconnect(odm, (for_shutdown || !is->static_media_ressources) ? 1 : 0); - } - } - - root_node = gf_sg_get_root_node(is->graph); - /*reset private stack of all inline nodes still registered*/ - while (gf_list_count(is->inline_nodes)) { - GF_Node *n = (GF_Node *)gf_list_get(is->inline_nodes, 0); - gf_list_rem(is->inline_nodes, 0); - switch (gf_node_get_tag(n)) { - case TAG_MPEG4_Inline: - case TAG_X3D_Inline: - gf_node_set_private(n, NULL); - break; - } - } - - /*remove all associated eventTargets - THIS ENEDS CLEANUP*/ - i=0; - while ((obj = (GF_MediaObject *)gf_list_enum(is->ODlist, &i))) { - if (obj->nodes) gf_list_reset(obj->nodes); - } - - if (is->graph_attached && (is->root_od->term->root_scene == is)) { - gf_sc_set_scene(is->root_od->term->compositor, NULL); - } - /*release the scene*/ - if (dec && dec->ReleaseScene) dec->ReleaseScene(dec); - gf_sg_reset(is->graph); - is->graph_attached = 0; - - gf_term_lock_compositor(is->root_od->term, 0); - - - assert(!gf_list_count(is->extra_scenes) ); - /*reset statc ressource flag since we destroyed scene objects*/ - is->static_media_ressources = 0; - - /*remove stream associations*/ - while (gf_list_count(is->media_objects)) { - obj = (GF_MediaObject*)gf_list_get(is->media_objects, 0); - gf_list_rem(is->media_objects, 0); - if (obj->odm) obj->odm->mo = NULL; - gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL); - gf_list_del(obj->nodes); - free(obj); - } -} - -static void IS_InsertObject(GF_InlineScene *is, GF_MediaObject *mo, Bool lock_timelines, GF_MediaObject *sync_ref, Bool keep_fragment) -{ - GF_ObjectManager *root_od; - GF_ObjectManager *odm; - char *url; - if (!mo || !is) return; - - odm = gf_odm_new(); - /*remember OD*/ - odm->mo = mo; - mo->odm = odm; - odm->parentscene = is; - odm->OD = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); - odm->OD->objectDescriptorID = GF_ESM_DYNAMIC_OD_ID; - odm->parentscene = is; - odm->term = is->root_od->term; - root_od = is->root_od; - - url = mo->URLs.vals[0].url; - if (!stricmp(url, "KeySensor")) { - GF_ESD *esd = gf_odf_desc_esd_new(0); - esd->decoderConfig->streamType = GF_STREAM_INTERACT; - esd->decoderConfig->objectTypeIndication = 1; - free(esd->decoderConfig->decoderSpecificInfo->data); - esd->decoderConfig->decoderSpecificInfo->data = strdup(" KeySensor"); - esd->decoderConfig->decoderSpecificInfo->data[0] = 9; - esd->decoderConfig->decoderSpecificInfo->dataLength = 10; - esd->ESID = esd->OCRESID = 65534; - gf_list_add(odm->OD->ESDescriptors, esd); - } else if (!stricmp(url, "StringSensor")) { - GF_ESD *esd = gf_odf_desc_esd_new(0); - esd->decoderConfig->streamType = GF_STREAM_INTERACT; - esd->decoderConfig->objectTypeIndication = 1; - free(esd->decoderConfig->decoderSpecificInfo->data); - esd->decoderConfig->decoderSpecificInfo->data = strdup(" StringSensor"); - esd->decoderConfig->decoderSpecificInfo->data[0] = 12; - esd->decoderConfig->decoderSpecificInfo->dataLength = 13; - esd->ESID = esd->OCRESID = 65534; - gf_list_add(odm->OD->ESDescriptors, esd); - } else if (!stricmp(url, "Mouse")) { - GF_ESD *esd = gf_odf_desc_esd_new(0); - esd->decoderConfig->streamType = GF_STREAM_INTERACT; - esd->decoderConfig->objectTypeIndication = 1; - free(esd->decoderConfig->decoderSpecificInfo->data); - esd->decoderConfig->decoderSpecificInfo->data = strdup(" Mouse"); - esd->decoderConfig->decoderSpecificInfo->data[0] = 5; - esd->decoderConfig->decoderSpecificInfo->dataLength = 6; - esd->ESID = esd->OCRESID = 65534; - gf_list_add(odm->OD->ESDescriptors, esd); - } else { - if (!keep_fragment) { - char *frag = strrchr(mo->URLs.vals[0].url, '#'); - if (frag) frag[0] = 0; - odm->OD->URLString = strdup(mo->URLs.vals[0].url); - if (frag) frag[0] = '#'; - } else { - odm->OD->URLString = strdup(mo->URLs.vals[0].url); - } - if (lock_timelines) odm->flags |= GF_ODM_INHERIT_TIMELINE; - } - - /*HACK - temp storage of sync ref*/ - if (sync_ref) odm->ocr_codec = (struct _generic_codec *)sync_ref; - - gf_list_add(is->ODlist, odm); - gf_odm_setup_object(odm, root_od->net_service); -} - -static void IS_ReinsertObject(GF_InlineScene *is, GF_MediaObject *mo) -{ - u32 i; - free(mo->URLs.vals[0].url); - mo->URLs.vals[0].url = NULL; - for (i=0; i<mo->URLs.count-1; i++) mo->URLs.vals[i].url = mo->URLs.vals[i+1].url; - mo->URLs.vals[mo->URLs.count-1].url = NULL; - mo->URLs.count-=1; - /*FIXME - we should re-ananlyse whether the fragment is important or not ...*/ - IS_InsertObject(is, mo, 0, NULL, 0); -} - - -void gf_inline_remove_object(GF_InlineScene *is, GF_ObjectManager *odm, Bool for_shutdown) -{ - u32 i; - GF_MediaObject *obj; - - gf_list_del_item(is->ODlist, odm); - - - i=0; - while ((obj = (GF_MediaObject*)gf_list_enum(is->media_objects, &i))) { - if ( - /*assigned object*/ - (obj->odm==odm) || - /*remote OD*/ - ((obj->OD_ID!=GF_ESM_DYNAMIC_OD_ID) && odm->OD && (obj->OD_ID == odm->OD->objectDescriptorID) ) || - /*dynamic OD*/ - (obj->URLs.count && odm->OD && odm->OD->URLString && !stricmp(obj->URLs.vals[0].url, odm->OD->URLString)) - ) { - gf_odm_lock(odm, 1); - obj->flags = 0; - if (obj->odm) obj->odm->mo = NULL; - odm->mo = NULL; - obj->odm = NULL; - - obj->frame = NULL; - obj->framesize = obj->timestamp = 0; - - gf_odm_lock(odm, 0); - - /*if graph not attached we can remove the link (this is likely scene shutdown for some error)*/ - if (!is->graph_attached) { - ProtoLink *pl; - u32 j=0; - while ((pl = (ProtoLink *)gf_list_enum(is->extern_protos, &j))) { - if (pl->mo==obj) { - pl->mo = NULL; - break; - } - } - gf_list_rem(is->media_objects, i-1); - gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL); - gf_list_del(obj->nodes); - free(obj); - } else if (!for_shutdown) { - /*if dynamic OD and more than 1 URLs resetup*/ - if ((obj->OD_ID==GF_ESM_DYNAMIC_OD_ID) && (obj->URLs.count>1)) IS_ReinsertObject(is, obj); - } - return; - } - } -} - -u32 URL_GetODID(MFURL *url) -{ - u32 i, j, tmpid; - char *str, *s_url; - u32 id = 0; - - if (!url) return 0; - - for (i=0; i<url->count; i++) { - if (url->vals[i].OD_ID) { - /*works because OD ID 0 is forbidden in MPEG4*/ - if (!id) { - id = url->vals[i].OD_ID; - } - /*bad url, only one object can be described in MPEG4 urls*/ - else if (id != url->vals[i].OD_ID) return 0; - } else if (url->vals[i].url && strlen(url->vals[i].url)) { - /*format: od:ID or od:ID#segment - also check for "ID" in case...*/ - str = url->vals[i].url; - if (!strnicmp(str, "od:", 3)) str += 3; - /*remove segment info*/ - s_url = strdup(str); - j = 0; - while (j<strlen(s_url)) { - if (s_url[j]=='#') { - s_url[j] = 0; - break; - } - j++; - } - j = sscanf(s_url, "%d", &tmpid); - /*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/ - if (j==1) { - char szURL[20]; - sprintf(szURL, "%d", tmpid); - if (stricmp(szURL, s_url)) j = 0; - } - free(s_url); - - if (j!= 1) { - /*dynamic OD if only one URL specified*/ - if (!i) return GF_ESM_DYNAMIC_OD_ID; - /*otherwise ignore*/ - continue; - } - if (!id) { - id = tmpid; - continue; - } - /*bad url, only one object can be described in MPEG4 urls*/ - else if (id != tmpid) return 0; - } - } - return id; -} - - -//browse all channels and update buffering info -void gf_inline_buffering_info(GF_InlineScene *is) -{ - u32 i, j, max_buffer, cur_buffer; - GF_Channel *ch; - GF_Event evt; - GF_ObjectManager *odm; - if (!is) return; - - max_buffer = cur_buffer = 0; - - /*get buffering on root OD*/ - j=0; - while ((ch = (GF_Channel*)gf_list_enum(is->root_od->channels, &j))) { - /*count only re-buffering channels*/ - if (!ch->BufferOn) continue; - - max_buffer += ch->MaxBuffer; - cur_buffer += (ch->BufferTime>0) ? ch->BufferTime : 1; - } - - /*get buffering on all ODs*/ - i=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i))) { - if (!odm->codec) continue; - j=0; - while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &j))) { - /*count only re-buffering channels*/ - if (!ch->BufferOn) continue; - - max_buffer += ch->MaxBuffer; - cur_buffer += (ch->BufferTime>0) ? ch->BufferTime : 1; - } - } - - evt.type = GF_EVENT_PROGRESS; - evt.progress.progress_type = 0; - evt.progress.service = is->root_od->net_service->url; - if (!max_buffer || !cur_buffer || (max_buffer <= cur_buffer)) { - evt.progress.done = evt.progress.total = max_buffer; - } else { - evt.progress.done = cur_buffer; - evt.progress.total = max_buffer; - } - GF_USER_SENDEVENT(is->root_od->term->user, &evt); -} - - -static Bool Inline_SetScene(M_Inline *root) -{ - GF_MediaObject *mo; - GF_InlineScene *parent; - GF_SceneGraph *graph = gf_node_get_graph((GF_Node *) root); - parent = (GF_InlineScene *)gf_sg_get_private(graph); - if (!parent) return 0; - - mo = gf_inline_get_media_object_ex(parent, &root->url, GF_MEDIA_OBJECT_SCENE, 0, NULL, 0, (GF_Node*)root); - if (!mo || !mo->odm) return 0; - - if (!mo->odm->subscene) { - gf_term_invalidate_compositor(parent->root_od->term); - return 0; - } - /*assign inline scene as private stack of inline node, and remember inline node for event propagation*/ - gf_node_set_private((GF_Node *)root, mo->odm->subscene); - gf_list_add(mo->odm->subscene->inline_nodes, root); - /*play*/ - gf_mo_play(mo, 0, -1, 0); - return 1; -} - -static Bool gf_mo_is_same_url_ex(GF_MediaObject *obj, MFURL *an_url, Bool *keep_fragment, u32 obj_hint_type) -{ - Bool include_sub_url = 0; - u32 i; - char szURL1[GF_MAX_PATH], szURL2[GF_MAX_PATH], *ext; - - if (keep_fragment) *keep_fragment = 0; - if (obj->OD_ID==GF_ESM_DYNAMIC_OD_ID) { - if (!obj->URLs.count) { - if (!obj->odm) return 0; - strcpy(szURL1, obj->odm->net_service->url); - } else { - strcpy(szURL1, obj->URLs.vals[0].url); - } - } else { - if (!obj->URLs.count) return 0; - strcpy(szURL1, obj->URLs.vals[0].url); - } - - /*don't analyse audio/video to locate segments or viewports*/ - if (obj->type==GF_MEDIA_OBJECT_AUDIO) - include_sub_url = 1; - else if (obj->type==GF_MEDIA_OBJECT_VIDEO) - include_sub_url = 1; - else if ((obj->type==GF_MEDIA_OBJECT_SCENE) && keep_fragment && obj->odm) { - GF_ClientService *ns; - u32 j; - /*for remoteODs/dynamic ODs, check if one of the running service cannot be used*/ - for (i=0; i<an_url->count; i++) { - char *frag = strrchr(an_url->vals[i].url, '#'); - j=0; - /*this is the same object (may need some refinement)*/ - if (!stricmp(szURL1, an_url->vals[i].url)) return 1; - - /*fragment is a media segment, same URL*/ - if (frag ) { - Bool same_res = 0; - frag[0] = 0; - same_res = !strncmp(an_url->vals[i].url, szURL1, strlen(an_url->vals[i].url)) ? 1 : 0; - frag[0] = '#'; - - /*if we're talking about the same resource, check if the fragment can be matched*/ - if (same_res) { - /*if the expected type is a segment (undefined media type) - and the fragment is a media segment, same URL - */ - if (obj->odm->subscene && (gf_sg_find_node_by_name(obj->odm->subscene->graph, frag+1)!=NULL) ) - return 1; - - /*if the expected type is a segment (undefined media type) - and the fragment is a media segment, same URL - */ - if (!obj_hint_type && gf_odm_find_segment(obj->odm, frag+1)) - return 1; - } - } - - while ( (ns = (GF_ClientService*)gf_list_enum(obj->odm->term->net_services, &j)) ) { - /*sub-service of an existing service - don't touch any fragment*/ - if (gf_term_service_can_handle_url(ns, an_url->vals[i].url)) { - *keep_fragment = 1; - return 0; - } - } - } - } - - /*check on full URL without removing fragment IDs*/ - if (include_sub_url) { - for (i=0; i<an_url->count; i++) { - if (!stricmp(szURL1, an_url->vals[i].url)) return 1; - } - return 0; - } - ext = strrchr(szURL1, '#'); - if (ext) ext[0] = 0; - for (i=0; i<an_url->count; i++) { - if (!an_url->vals[i].url) return 0; - strcpy(szURL2, an_url->vals[i].url); - ext = strrchr(szURL2, '#'); - if (ext) ext[0] = 0; - if (!stricmp(szURL1, szURL2)) return 1; - } - return 0; -} - -Bool gf_mo_is_same_url(GF_MediaObject *obj, MFURL *an_url) -{ - return gf_mo_is_same_url_ex(obj, an_url, NULL, 0); -} - -void gf_inline_on_modified(GF_Node *node) -{ - u32 ODID; - GF_MediaObject *mo; - M_Inline *pInline = (M_Inline *) node; - GF_InlineScene *pIS = (GF_InlineScene *)gf_node_get_private(node); - - ODID = URL_GetODID(&pInline->url); - if (pIS) { - mo = (pIS->root_od) ? pIS->root_od->mo : NULL; - - /*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/ - if (mo) { - Bool changed = 1; - if (ODID != GF_ESM_DYNAMIC_OD_ID) { - if (ODID && (ODID==pIS->root_od->OD->objectDescriptorID)) changed = 0; - } else { - if (gf_mo_is_same_url(mo, &pInline->url) ) changed = 0; - } - if (mo->num_open) { - if (!changed) return; - mo->num_open --; - if (!mo->num_open) { - gf_odm_stop(pIS->root_od, 1); - gf_inline_disconnect(pIS, 1); - assert(gf_list_count(pIS->ODlist) == 0); - } - } - } - } - if (ODID) Inline_SetScene(pInline); -} - - -static void IS_CheckMediaRestart(GF_InlineScene *is) -{ - /*no ctrl if no duration*/ - if (!is->duration) return; - if (!is->needs_restart) gf_odm_check_segment_switch(is->root_od); - if (is->needs_restart) return; - - if (is->root_od->media_ctrl && is->root_od->media_ctrl->control->loop) { - GF_Clock *ck = gf_odm_get_media_clock(is->root_od); - if (ck->has_seen_eos) { - u32 now = gf_clock_time(ck); - u64 dur = is->duration; - if (is->root_od->media_ctrl->current_seg) { - /*only process when all segments are played*/ - if (gf_list_count(is->root_od->media_ctrl->seg) <= is->root_od->media_ctrl->current_seg) { - is->needs_restart = 1; - is->root_od->media_ctrl->current_seg = 0; - } - } - else { - Double s, e; - s = now; s/=1000; - e = -1; - MC_GetRange(is->root_od->media_ctrl, &s, &e); - if ((e>=0) && (e<GF_MAX_FLOAT)) dur = (u32) (e*1000); - if (dur<now) { - is->needs_restart = 1; - is->root_od->media_ctrl->current_seg = 0; - } - } - } else { - /*trigger render until to watch for restart...*/ - gf_term_invalidate_compositor(is->root_od->term); - } - } -} - -static void gf_inline_traverse(GF_Node *n, void *rs, Bool is_destroy) -{ - GF_InlineScene *is = (GF_InlineScene *)gf_node_get_private(n); - - if (is_destroy) { - GF_MediaObject *mo = (is && is->root_od) ? is->root_od->mo : NULL; - - if (is) gf_list_del_item(is->inline_nodes, n); - - if (!mo) return; - /*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/ - if (mo->num_open) { - mo->num_open --; - if (!mo->num_open) { - /*this is unspecified in the spec: whenever an inline not using the - OD framework is destroyed, destroy the associated resource*/ - if (mo->OD_ID == GF_ESM_DYNAMIC_OD_ID) { - gf_odm_disconnect(is->root_od, 1); - - /*get parent scene and remove MediaObject in case the ressource - gets re-requested later on*/ - is = (GF_InlineScene *)gf_sg_get_private(gf_node_get_graph((GF_Node *) n) ); - gf_list_del_item(is->media_objects, mo); - gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL); - gf_list_del(mo->nodes); - free(mo); - } else { - gf_odm_stop(is->root_od, 1); - gf_inline_disconnect(is, 1); - assert(gf_list_count(is->ODlist) == 0); - } - } - } - return; - } - - - //if no private scene is associated get the node parent graph, retrieve the IS and find the OD - if (!is) { - M_Inline *inl = (M_Inline *)n; - Inline_SetScene(inl); - is = (GF_InlineScene *)gf_node_get_private(n); - if (!is) { - /*just like protos, we must invalidate parent graph until attached*/ - if (inl->url.count) - gf_node_dirty_set(n, 0, 1); - return; - } - } - - IS_CheckMediaRestart(is); - - /*if we need to restart, shutdown graph and do it*/ - if (is->needs_restart) { - u32 current_seg = 0; - /*special case: scene change*/ - if (is->needs_restart==2) { - is->needs_restart = 0; - gf_inline_on_modified(n); - return; - } - - if (is->root_od->media_ctrl) current_seg = is->root_od->media_ctrl->current_seg; - is->needs_restart = 0; - - if (is->is_dynamic_scene) { - if (is->root_od->media_ctrl) is->root_od->media_ctrl->current_seg = current_seg; - gf_inline_restart_dynamic(is, 0); - } else { - /*we cannot use gf_mo_restart since it only sets the needs_restart for inline scenes. - The rational is that gf_mo_restart can be called from the parent scene (OK) or from the scene itself, in - which case shutting down the graph would crash the compositor. We therefore need two render passes to - safely restart an inline scene*/ - - /*1- stop main object from playing but don't disconnect channels*/ - gf_odm_stop(is->root_od, 1); - /*2- close all ODs inside the scene and reset the graph*/ - gf_inline_disconnect(is, 0); - if (is->root_od->media_ctrl) is->root_od->media_ctrl->current_seg = current_seg; - /*3- restart the scene*/ - gf_odm_start(is->root_od); - } - gf_node_dirty_set(n, 0, 1); - return; - } - - /*if not attached return (attaching the graph cannot be done in render since render is not called while unattached :) */ - if (!is->graph_attached) { - /*just like protos, we must invalidate parent graph until attached*/ - gf_node_dirty_set(n, 0, 1); - return; - } - /*clear dirty flags for any sub-inlines, bitmaps or protos*/ - gf_node_dirty_clear(n, 0); - - gf_sc_traverse_subscene(is->root_od->term->compositor, n, is->graph, rs); -} - - -static void gf_is_resize_event(GF_InlineScene *is) -{ - /*fire resize event*/ -#ifndef GPAC_DISABLE_SVG - u32 i, count; - u32 w, h; - GF_DOM_Event evt; - memset(&evt, 0, sizeof(GF_DOM_Event)); - w = h = 0; - gf_sg_get_scene_size_info(is->graph, &w, &h); - evt.type = GF_EVENT_RESIZE; - evt.screen_rect.width = INT2FIX(w); - evt.screen_rect.height = INT2FIX(h); - gf_dom_event_fire(gf_sg_get_root_node(is->graph), &evt); - - count=gf_list_count(is->inline_nodes); - for (i=0;i<count; i++) { - gf_dom_event_fire( gf_list_get(is->inline_nodes, i), &evt ); - } -#endif -} - -GF_EXPORT -void gf_inline_attach_to_compositor(GF_InlineScene *is) -{ - char *url; - if ((is->graph_attached==1) || (gf_sg_get_root_node(is->graph)==NULL) ) { - gf_term_invalidate_compositor(is->root_od->term); - return; - } - is->graph_attached = 1; - - /*locate fragment IRI*/ - if (!is->root_od || !is->root_od->net_service || !is->root_od->net_service->url) return; - if (is->fragment_uri) { - free(is->fragment_uri); - is->fragment_uri = NULL; - } - url = strchr(is->root_od->net_service->url, '#'); - if (url) is->fragment_uri = strdup(url+1); - - /*main display scene, setup compositor*/ - if (is->root_od->term->root_scene == is) { - gf_sc_set_scene(is->root_od->term->compositor, is->graph); - } - else { - u32 i, count=gf_list_count(is->inline_nodes); - for (i=0;i<count; i++) - gf_node_dirty_parents( gf_list_get(is->inline_nodes, i) ); - gf_term_invalidate_compositor(is->root_od->term); - - if (is->root_od->parentscene->is_dynamic_scene) { - u32 w, h; - gf_sg_get_scene_size_info(is->graph, &w, &h); - gf_sc_set_size(is->root_od->term->compositor, w, h); - } - gf_is_resize_event(is); - } -} - -static GF_MediaObject *IS_CheckExistingObject(GF_InlineScene *is, MFURL *urls, u32 type) -{ - GF_MediaObject *obj; - u32 i = 0; - while ((obj = (GF_MediaObject *)gf_list_enum(is->media_objects, &i))) { - if (type && (type != obj->type)) continue; - if ((obj->OD_ID == GF_ESM_DYNAMIC_OD_ID) && gf_mo_is_same_url(obj, urls)) return obj; - else if ((obj->OD_ID != GF_ESM_DYNAMIC_OD_ID) && (obj->OD_ID == urls->vals[0].OD_ID)) return obj; - } - return NULL; -} - -static GFINLINE Bool is_match_obj_type(u32 type, u32 hint_type) -{ - if (!hint_type) return 1; - if (type==hint_type) return 1; - /*TEXT are used by animation stream*/ - if ((type==GF_MEDIA_OBJECT_TEXT) && (hint_type==GF_MEDIA_OBJECT_UPDATES)) return 1; - return 0; -} - -GF_MediaObject *gf_inline_get_media_object_ex(GF_InlineScene *is, MFURL *url, u32 obj_type_hint, Bool lock_timelines, GF_MediaObject *sync_ref, Bool always_load_new, GF_Node *node) -{ - GF_MediaObject *obj; - Bool keep_fragment = 1; - u32 i, OD_ID; - - OD_ID = URL_GetODID(url); - if (!OD_ID) return NULL; - - if (!always_load_new) { - obj = NULL; - i=0; - while ((obj = (GF_MediaObject *)gf_list_enum(is->media_objects, &i))) { - if ( - /*regular OD scheme*/ - (OD_ID != GF_ESM_DYNAMIC_OD_ID && (obj->OD_ID==OD_ID)) - || - /*dynamic OD scheme*/ - ((OD_ID == GF_ESM_DYNAMIC_OD_ID) && (obj->OD_ID==GF_ESM_DYNAMIC_OD_ID) - /*if object type unknown (media control, media sensor), return first obj matching URL - otherwise check types*/ - && is_match_obj_type(obj->type, obj_type_hint) - /*locate sub-url in given one and handle fragments (viewpoint/segments/...)*/ - && gf_mo_is_same_url_ex(obj, url, &keep_fragment, obj_type_hint) - ) - ) { - - if (node && (gf_list_find(obj->nodes, node)<0)) - gf_list_add(obj->nodes, node); - return obj; - } - } - } - /*we cannot create an OD manager at this point*/ - if (obj_type_hint==GF_MEDIA_OBJECT_UNDEF) return NULL; - - /*create a new object identification*/ - obj = gf_mo_new(); - obj->OD_ID = OD_ID; - obj->type = obj_type_hint; - - /*register node with object*/ - if (node) - gf_list_add(obj->nodes, node); - - /*if animation stream object, remember originating node - !! FIXME - this should be cleaned up !! - */ - if (obj->type == GF_MEDIA_OBJECT_UPDATES) - obj->node_ptr = node; - - gf_list_add(is->media_objects, obj); - if (OD_ID == GF_ESM_DYNAMIC_OD_ID) { - gf_sg_vrml_field_copy(&obj->URLs, url, GF_SG_VRML_MFURL); - IS_InsertObject(is, obj, lock_timelines, sync_ref, keep_fragment); - /*safety check!!!*/ - if (gf_list_find(is->media_objects, obj)<0) - return NULL; - } - return obj; -} - -GF_MediaObject *gf_inline_get_media_object(GF_InlineScene *is, MFURL *url, u32 obj_type_hint, Bool lock_timelines) -{ - return gf_inline_get_media_object_ex(is, url, obj_type_hint, lock_timelines, NULL, 0, NULL); -} - -GF_EXPORT -void gf_inline_setup_object(GF_InlineScene *is, GF_ObjectManager *odm) -{ - GF_MediaObject *obj; - u32 i; - - /*an object may already be assigned (when using ESD URLs, setup is performed twice)*/ - if (odm->mo != NULL) goto existing; - - i=0; - while ((obj = (GF_MediaObject*)gf_list_enum(is->media_objects, &i))) { - if (obj->OD_ID==GF_ESM_DYNAMIC_OD_ID) { - //assert(obj->odm); - if (obj->odm == odm) { - /*assign FINAL OD, not parent*/ - obj->odm = odm; - odm->mo = obj; - goto existing; - } - } - else if (obj->OD_ID == odm->OD->objectDescriptorID) { - assert(obj->odm==NULL); - obj->odm = odm; - odm->mo = obj; - goto existing; - } - } - /*newly created OD*/ - odm->mo = gf_mo_new(); - gf_list_add(is->media_objects, odm->mo); - odm->mo->odm = odm; - odm->mo->OD_ID = odm->OD->objectDescriptorID; - -existing: - /*setup object type*/ - if (!odm->codec) odm->mo->type = GF_MEDIA_OBJECT_SCENE; - else if (odm->codec->type == GF_STREAM_VISUAL) odm->mo->type = GF_MEDIA_OBJECT_VIDEO; - else if (odm->codec->type == GF_STREAM_AUDIO) odm->mo->type = GF_MEDIA_OBJECT_AUDIO; - else if (odm->codec->type == GF_STREAM_TEXT) odm->mo->type = GF_MEDIA_OBJECT_TEXT; - else if (odm->codec->type == GF_STREAM_SCENE) odm->mo->type = GF_MEDIA_OBJECT_UPDATES; - - /*update info*/ - gf_mo_update_caps(odm->mo); - /*media object playback has already been requested by the scene, trigger media start*/ - if (odm->mo->num_open && !odm->state) { - gf_odm_start(odm); - if (odm->mo->speed != FIX_ONE) gf_odm_set_speed(odm, odm->mo->speed); - } - if ((odm->mo->type==GF_MEDIA_OBJECT_VIDEO) && is->is_dynamic_scene) { - gf_inline_force_scene_size_video(is, odm->mo); - } - /*invalidate scene for all nodes using the OD*/ - gf_term_invalidate_compositor(odm->term); -} - -void gf_inline_restart(GF_InlineScene *is) -{ - is->needs_restart = 1; - gf_term_invalidate_compositor(is->root_od->term); -} - - -GF_EXPORT -void gf_inline_set_duration(GF_InlineScene *is) -{ - Double dur; - u32 i; - u64 max_dur; - GF_ObjectManager *odm; - MediaSensorStack *media_sens; - GF_Clock *ck; - - /*this is not normative but works in so many cases... set the duration to the max duration - of all streams sharing the clock*/ - ck = gf_odm_get_media_clock(is->root_od); - max_dur = is->root_od->duration; - i=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i))) { - if (!odm->codec) continue; - if (!ck || gf_odm_shares_clock(odm, ck)) { - if (odm->duration>max_dur) max_dur = odm->duration; - } - } - if (is->duration == max_dur) return; - - is->duration = max_dur; - dur = (Double) (s64) is->duration; - dur /= 1000; - - i=0; - while ((media_sens = (MediaSensorStack*)gf_list_enum(is->root_od->ms_stack, &i))) { - if (media_sens->sensor->isActive) { - media_sens->sensor->mediaDuration = dur; - gf_node_event_out_str((GF_Node *) media_sens->sensor, "mediaDuration"); - } - } - - if ((is == is->root_od->term->root_scene) && is->root_od->term->user->EventProc) { - GF_Event evt; - evt.type = GF_EVENT_DURATION; - evt.duration.duration = dur; - evt.duration.can_seek = !(is->root_od->flags & GF_ODM_NO_TIME_CTRL); - if (dur<2.0) evt.duration.can_seek = 0; - GF_USER_SENDEVENT(is->root_od->term->user,&evt); - } - -} - - -static Bool IS_IsHardcodedProto(MFURL *url, GF_Config *cfg) -{ - 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; - } - return 0; -} - -void IS_LoadExternProto(GF_InlineScene *is, MFURL *url) -{ - u32 i; - ProtoLink *pl; - if (!url || !url->count) return; - - /*internal, don't waste ressources*/ - if (IS_IsHardcodedProto(url, is->root_od->term->user->config)) return; - - i=0; - while ((pl = (ProtoLink*)gf_list_enum(is->extern_protos, &i)) ) { - if (pl->url == url) return; - if (pl->url->vals[0].OD_ID && (pl->url->vals[0].OD_ID == url->vals[0].OD_ID)) return; - if (pl->url->vals[0].url && url->vals[0].url && !stricmp(pl->url->vals[0].url, url->vals[0].url) ) return; - } - pl = (ProtoLink*)malloc(sizeof(ProtoLink)); - pl->url = url; - gf_list_add(is->extern_protos, pl); - pl->mo = gf_inline_get_media_object(is, url, GF_MEDIA_OBJECT_SCENE, 0); - /*this may already be destroyed*/ - if (pl->mo) gf_mo_play(pl->mo, 0, -1, 0); -} - -GF_EXPORT -GF_SceneGraph *gf_inline_get_proto_lib(void *_is, MFURL *lib_url) -{ - ProtoLink *pl; - u32 i; - GF_InlineScene *is = (GF_InlineScene *) _is; - if (!is || !lib_url->count) return NULL; - - if (IS_IsHardcodedProto(lib_url, is->root_od->term->user->config)) return GF_SG_INTERNAL_PROTO; - - i=0; - while ((pl = (ProtoLink*)gf_list_enum(is->extern_protos, &i))) { - if (!pl->mo) continue; - if (URL_GetODID(pl->url) != GF_ESM_DYNAMIC_OD_ID) { - if (URL_GetODID(pl->url) == URL_GetODID(lib_url)) { - if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL; - return pl->mo->odm->subscene->graph; - } - } else if (lib_url->vals[0].url) { - if (gf_mo_is_same_url(pl->mo, lib_url)) { - if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL; - return pl->mo->odm->subscene->graph; - } - } - } - - /*not found, create loader*/ - IS_LoadExternProto(is, lib_url); - - /*and return NULL*/ - return NULL; -} - -GF_ObjectManager *IS_GetProtoSceneByGraph(void *_is, GF_SceneGraph *sg) -{ - u32 i; - ProtoLink *pl; - GF_InlineScene *is = (GF_InlineScene *) _is; - if (!is) return NULL; - i=0; - while ((pl = (ProtoLink*)gf_list_enum(is->extern_protos, &i))) { - if (pl->mo->odm && pl->mo->odm->subscene && (pl->mo->odm->subscene->graph==sg)) return pl->mo->odm; - } - return NULL; -} - - -Bool IS_IsProtoLibObject(GF_InlineScene *is, GF_ObjectManager *odm) -{ - u32 i; - ProtoLink *pl; - i=0; - while ((pl = (ProtoLink*)gf_list_enum(is->extern_protos, &i))) { - if (pl->mo->odm == odm) return 1; - } - return 0; -} - - -GF_MediaObject *gf_inline_find_object(GF_InlineScene *is, u16 ODID, char *url) -{ - u32 i; - GF_MediaObject *mo; - if (!url && !ODID) return NULL; - i=0; - while ((mo = (GF_MediaObject *)gf_list_enum(is->media_objects, &i))) { - if (ODID==GF_ESM_DYNAMIC_OD_ID) { - if (mo->URLs.count && !stricmp(mo->URLs.vals[0].url, url)) return mo; - } else if (mo->OD_ID==ODID) return mo; - } - return NULL; -} - - -const char *IS_GetSceneViewName(GF_InlineScene *is) -{ - char *seg_name; - /*check any viewpoint*/ - seg_name = strrchr(is->root_od->net_service->url, '#'); - if (!seg_name) return NULL; - seg_name += 1; - /*look for a media segment with this name - if none found, this is a viewpoint name*/ - if (gf_odm_find_segment(is->root_od, seg_name) != NULL) return NULL; - return seg_name; -} - -GF_EXPORT -Bool gf_inline_default_scene_viewpoint(GF_Node *node) -{ - const char *nname, *sname; - GF_SceneGraph *sg = gf_node_get_graph(node); - GF_InlineScene *is = sg ? (GF_InlineScene *) gf_sg_get_private(sg) : NULL; - if (!is) return 0; - - nname = gf_node_get_name(node); - if (!nname) return 0; - sname = IS_GetSceneViewName(is); - if (!sname) return 0; - return (!strcmp(nname, sname)); -} - -GF_EXPORT -void gf_inline_register_extra_graph(GF_InlineScene *is, GF_SceneGraph *extra_scene, Bool do_remove) -{ - if (do_remove) { - if (gf_list_find(is->extra_scenes, extra_scene)<0) return; - gf_list_del_item(is->extra_scenes, extra_scene); - /*for root scene*/ - if (is->root_od->term->root_scene == is) { - gf_sc_register_extra_graph(is->root_od->term->compositor, extra_scene, 1); - } - } else { - if (gf_list_find(is->extra_scenes, extra_scene)>=0) return; - gf_list_add(is->extra_scenes, extra_scene); - /*for root scene*/ - if (is->root_od->term->root_scene == is) { - gf_sc_register_extra_graph(is->root_od->term->compositor, extra_scene, 0); - } - } -} - - -static void gf_inline_get_video_size(GF_MediaObject *mo, u32 *w, u32 *h) -{ - u32 pixel_ar; - if (!gf_mo_get_visual_info(mo, w, h, NULL, &pixel_ar, NULL)) return; - if (pixel_ar) { - u32 n, d; - n = (pixel_ar>>16) & 0xFF; - d = (pixel_ar) & 0xFF; - *w = (*w * n) / d; - } -} - -static void IS_UpdateVideoPos(GF_InlineScene *is) -{ - MFURL url; - M_Transform2D *tr; - GF_MediaObject *mo; - u32 w, h, v_w, v_h; - if (!is->visual_url.OD_ID && !is->visual_url.url) return; - - url.count = 1; - url.vals = &is->visual_url; - mo = IS_CheckExistingObject(is, &url, GF_MEDIA_OBJECT_VIDEO); - if (!mo) return; - tr = (M_Transform2D *) gf_sg_find_node_by_name(is->graph, "DYN_TRANS"); - if (!tr) return; - - gf_sg_get_scene_size_info(is->graph, &w, &h); - if (!w || !h) return; - - gf_inline_get_video_size(mo, &v_w, &v_h); - tr->translation.x = INT2FIX((s32) (w - v_w)) / 2; - tr->translation.y = INT2FIX((s32) (h - v_h)) / 2; - gf_node_dirty_set((GF_Node *)tr, 0, 0); - - if (is->root_od->term->root_scene == is) { - //if (is->graph_attached) gf_sc_set_scene(is->root_od->term->compositor, NULL); - gf_sc_set_scene(is->root_od->term->compositor, is->graph); - } -} - -static GF_Node *is_create_node(GF_SceneGraph *sg, u32 tag, const char *def_name) -{ - GF_Node *n = gf_node_new(sg, tag); - if (n) { - if (def_name) gf_node_set_id(n, gf_sg_get_next_available_node_id(sg), def_name); - gf_node_init(n); - } - return n; -} - -static Bool is_odm_url(SFURL *url, GF_ObjectManager *odm) -{ - if (!url->OD_ID && !url->url) return 0; - if (odm->OD->objectDescriptorID != GF_ESM_DYNAMIC_OD_ID) return (url->OD_ID==odm->OD->objectDescriptorID) ? 1 : 0; - if (!url->url || !odm->OD->URLString) return 0; - return !stricmp(url->url, odm->OD->URLString); -} - -void gf_inline_force_scene_size_video(GF_InlineScene *is, GF_MediaObject *mo) -{ - u32 w, h; - gf_inline_get_video_size(mo, &w, &h); - gf_inline_force_scene_size(is, w, h); -} - - -/*regenerates the scene graph for dynamic scene. -This will also try to reload any previously presented streams. Note that in the usual case the scene is generated -just once when receiving the first OD AU (ressources are NOT destroyed when seeking), but since the network may need -to update the OD ressources, we still kake care of it*/ -void gf_inline_regenerate(GF_InlineScene *is) -{ - u32 i, nb_obj, w, h; - GF_Node *n1, *n2; - SFURL *sfu; - GF_Event evt; - GF_ObjectManager *first_odm, *odm; - M_AudioClip *ac; - M_MovieTexture *mt; - M_AnimationStream *as; - M_Inline *dims; - - if (!is->is_dynamic_scene) return; - - GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Inline] Regenerating scene graph for service %s\n", is->root_od->net_service->url)); - - gf_sc_lock(is->root_od->term->compositor, 1); - - if (is->root_od->term->root_scene == is) - gf_sc_set_scene(is->root_od->term->compositor, NULL); - - gf_sg_reset(is->graph); - gf_sg_get_scene_size_info(is->graph, &w, &h); - gf_sg_set_scene_size_info(is->graph, w, h, 1); - - n1 = is_create_node(is->graph, TAG_MPEG4_OrderedGroup, NULL); - gf_sg_set_root_node(is->graph, n1); - gf_node_register(n1, NULL); - - n2 = is_create_node(is->graph, TAG_MPEG4_Sound2D, NULL); - gf_node_list_add_child( &((GF_ParentNode *)n1)->children, n2); - gf_node_register(n2, n1); - - ac = (M_AudioClip *) is_create_node(is->graph, TAG_MPEG4_AudioClip, "DYN_AUDIO"); - ac->startTime = gf_inline_get_time(is); - ((M_Sound2D *)n2)->source = (GF_Node *)ac; - gf_node_register((GF_Node *)ac, n2); - - nb_obj = 0; - first_odm = NULL; - i=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i))) { - if (!odm->codec || (odm->codec->type!=GF_STREAM_AUDIO)) continue; - - if (is_odm_url(&is->audio_url, odm)) { - gf_sg_vrml_mf_append(&ac->url, GF_SG_VRML_MFURL, (void **) &sfu); - sfu->OD_ID = is->audio_url.OD_ID; - if (is->audio_url.url) sfu->url = strdup(is->audio_url.url); - first_odm = NULL; - nb_obj++; - break; - } - if (!first_odm) first_odm = odm; - } - if (first_odm) { - if (is->audio_url.url) free(is->audio_url.url); - is->audio_url.url = NULL; - is->audio_url.OD_ID = first_odm->OD->objectDescriptorID; - if (is->audio_url.OD_ID==GF_ESM_DYNAMIC_OD_ID) is->audio_url.url = strdup(first_odm->net_service->url); - gf_sg_vrml_mf_append(&ac->url, GF_SG_VRML_MFURL, (void **) &sfu); - sfu->OD_ID = is->audio_url.OD_ID; - if (is->audio_url.url) sfu->url = strdup(is->audio_url.url); - nb_obj++; - - if (!is->dyn_ck) is->dyn_ck = first_odm->codec->ck; - } - - /*transform for any translation due to scene resize (3GPP)*/ - n2 = is_create_node(is->graph, TAG_MPEG4_Transform2D, "DYN_TRANS"); - gf_node_list_add_child( &((GF_ParentNode *)n1)->children, n2); - gf_node_register(n2, n1); - n1 = n2; - - n2 = is_create_node(is->graph, TAG_MPEG4_Shape, NULL); - gf_node_list_add_child( &((GF_ParentNode *)n1)->children, n2); - gf_node_register(n2, n1); - n1 = n2; - n2 = is_create_node(is->graph, TAG_MPEG4_Appearance, NULL); - ((M_Shape *)n1)->appearance = n2; - gf_node_register(n2, n1); - - /*note we create a movie texture even for images...*/ - mt = (M_MovieTexture *) is_create_node(is->graph, TAG_MPEG4_MovieTexture, "DYN_VIDEO"); - mt->startTime = gf_inline_get_time(is); - ((M_Appearance *)n2)->texture = (GF_Node *)mt; - gf_node_register((GF_Node *)mt, n2); - - first_odm = NULL; - i=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i))) { - if (!odm->codec || (odm->codec->type!=GF_STREAM_VISUAL)) continue; - - if (is_odm_url(&is->visual_url, odm)) { - gf_sg_vrml_mf_append(&mt->url, GF_SG_VRML_MFURL, (void **) &sfu); - sfu->OD_ID = is->visual_url.OD_ID; - if (is->visual_url.url) sfu->url = strdup(is->visual_url.url); - if (odm->mo) { - gf_inline_get_video_size(odm->mo, &w, &h); - gf_sg_set_scene_size_info(is->graph, w, h, 1); - } - first_odm = NULL; - nb_obj++; - break; - } - if (!first_odm) - first_odm = odm; - } - if (first_odm) { - if (is->visual_url.url) free(is->visual_url.url); - is->visual_url.url = NULL; - is->visual_url.OD_ID = first_odm->OD->objectDescriptorID; - if (is->visual_url.OD_ID==GF_ESM_DYNAMIC_OD_ID) is->visual_url.url = strdup(first_odm->net_service->url); - - gf_sg_vrml_mf_append(&mt->url, GF_SG_VRML_MFURL, (void **) &sfu); - sfu->OD_ID = is->visual_url.OD_ID; - if (is->visual_url.url) sfu->url = strdup(is->visual_url.url); - - if (first_odm->mo) { - gf_inline_get_video_size(first_odm->mo, &w, &h); - gf_sg_set_scene_size_info(is->graph, w, h, 1); - } - nb_obj++; - if (!is->dyn_ck) is->dyn_ck = first_odm->codec->ck; - } - - n2 = is_create_node(is->graph, TAG_MPEG4_Bitmap, NULL); - ((M_Shape *)n1)->geometry = n2; - gf_node_register(n2, n1); - - - /*text streams controlled through AnimationStream*/ - n1 = gf_sg_get_root_node(is->graph); - as = (M_AnimationStream *) is_create_node(is->graph, TAG_MPEG4_AnimationStream, "DYN_TEXT"); - gf_node_list_add_child( &((GF_ParentNode *)n1)->children, (GF_Node*)as); - gf_node_register((GF_Node *)as, n1); - - first_odm = NULL; - i=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i))) { - if (!odm->codec || ((odm->codec->type!=GF_STREAM_TEXT) && (odm->codec->type!=GF_STREAM_ND_SUBPIC)) ) continue; - - if (!nb_obj || is_odm_url(&is->text_url, odm)) { - if (is->text_url.url) free(is->text_url.url); - is->text_url.url = NULL; - - gf_sg_vrml_mf_append(&as->url, GF_SG_VRML_MFURL, (void **) &sfu); - sfu->OD_ID = is->text_url.OD_ID = odm->OD->objectDescriptorID; - if (odm->OD->objectDescriptorID == GF_ESM_DYNAMIC_OD_ID) { - sfu->url = strdup(odm->net_service->url); - is->text_url.url = strdup(odm->net_service->url); - } - first_odm = NULL; - if (!is->dyn_ck) is->dyn_ck = odm->codec->ck; - break; - } - if (!first_odm) first_odm = odm; - } - if (first_odm) { - if (is->text_url.url) free(is->text_url.url); - is->text_url.url = NULL; - gf_sg_vrml_mf_append(&as->url, GF_SG_VRML_MFURL, (void **) &sfu); - sfu->OD_ID = is->text_url.OD_ID = first_odm->OD->objectDescriptorID; - if (is->text_url.OD_ID==GF_ESM_DYNAMIC_OD_ID) { - is->text_url.url = strdup(first_odm->net_service->url); - sfu->url = strdup(first_odm->net_service->url); - } - if (!is->dyn_ck) is->dyn_ck = first_odm->codec->ck; - } - - - /*3GPP DIMS streams controlled */ - n1 = gf_sg_get_root_node(is->graph); - dims = (M_Inline *) is_create_node(is->graph, TAG_MPEG4_Inline, "DYN_SCENE"); - gf_node_list_add_child( &((GF_ParentNode *)n1)->children, (GF_Node*)dims); - gf_node_register((GF_Node *)dims, n1); - - i=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i))) { - if (!odm->subscene || !odm->subscene->scene_codec) continue; - - gf_sg_vrml_mf_append(&dims->url, GF_SG_VRML_MFURL, (void **) &sfu); - sfu->OD_ID = odm->OD->objectDescriptorID; - if (odm->OD->objectDescriptorID == GF_ESM_DYNAMIC_OD_ID) { - sfu->url = strdup(odm->net_service->url); - } - if (!is->dyn_ck) is->dyn_ck = odm->subscene->scene_codec->ck; - break; - } - - gf_sc_lock(is->root_od->term->compositor, 0); - - /*disconnect to force resize*/ - if (is->root_od->term->root_scene == is) { - if (is->graph_attached) gf_sc_set_scene(is->root_od->term->compositor, NULL); - gf_sc_set_scene(is->root_od->term->compositor, is->graph); - is->graph_attached = 1; - evt.type = GF_EVENT_STREAMLIST; - GF_USER_SENDEVENT(is->root_od->term->user,&evt); - IS_UpdateVideoPos(is); - } else { - is->graph_attached = 1; - gf_term_invalidate_compositor(is->root_od->term); - } -} - -static Bool check_odm_deactivate(SFURL *url, GF_ObjectManager *odm, GF_Node *n) -{ - GF_FieldInfo info; - if (!is_odm_url(url, odm) || !n) return 0; - - if (url->url) free(url->url); - url->url = NULL; - url->OD_ID = 0; - - gf_node_get_field_by_name(n, "url", &info); - gf_sg_vrml_mf_reset(info.far_ptr, GF_SG_VRML_MFURL); - gf_node_get_field_by_name(n, "stopTime", &info); - *((SFTime *)info.far_ptr) = gf_node_get_scene_time(n); - gf_node_changed(n, NULL); - return 1; -} - -void gf_inline_select_object(GF_InlineScene *is, GF_ObjectManager *odm) -{ - char *url; - if (!is->is_dynamic_scene || !is->graph_attached || !odm) return; - - if (!odm->codec) return; - - if (odm->state) { - if (check_odm_deactivate(&is->audio_url, odm, gf_sg_find_node_by_name(is->graph, "DYN_AUDIO")) ) return; - if (check_odm_deactivate(&is->visual_url, odm, gf_sg_find_node_by_name(is->graph, "DYN_VIDEO") )) return; - if (check_odm_deactivate(&is->text_url, odm, gf_sg_find_node_by_name(is->graph, "DYN_TEXT") )) return; - } - - if (odm->codec->type == GF_STREAM_AUDIO) { - M_AudioClip *ac = (M_AudioClip *) gf_sg_find_node_by_name(is->graph, "DYN_AUDIO"); - if (!ac) return; - if (is->audio_url.url) free(is->audio_url.url); - is->audio_url.url = NULL; - is->audio_url.OD_ID = odm->OD->objectDescriptorID; - if (!ac->url.count) gf_sg_vrml_mf_alloc(&ac->url, GF_SG_VRML_MFURL, 1); - ac->url.vals[0].OD_ID = odm->OD->objectDescriptorID; - if (ac->url.vals[0].url) { - free(ac->url.vals[0].url); - ac->url.vals[0].url = NULL; - } - url = odm->mo->URLs.count ? odm->mo->URLs.vals[0].url : NULL; - if (url) { - is->audio_url.url = strdup(url); - ac->url.vals[0].url = strdup(url); - } - ac->startTime = gf_inline_get_time(is); - gf_node_changed((GF_Node *)ac, NULL); - return; - } - - if (odm->codec->type == GF_STREAM_VISUAL) { - M_MovieTexture *mt = (M_MovieTexture*) gf_sg_find_node_by_name(is->graph, "DYN_VIDEO"); - if (!mt) return; - if (is->visual_url.url) free(is->visual_url.url); - is->visual_url.url = NULL; - is->visual_url.OD_ID = odm->OD->objectDescriptorID; - if (!mt->url.count) gf_sg_vrml_mf_alloc(&mt->url, GF_SG_VRML_MFURL, 1); - mt->url.vals[0].OD_ID = odm->OD->objectDescriptorID; - if (mt->url.vals[0].url) free(mt->url.vals[0].url); - url = odm->mo->URLs.count ? odm->mo->URLs.vals[0].url : NULL; - if (url) { - is->visual_url.url = strdup(url); - mt->url.vals[0].url = strdup(url); - } - mt->startTime = gf_inline_get_time(is); - gf_node_changed((GF_Node *)mt, NULL); - if (odm->mo) gf_inline_force_scene_size_video(is, odm->mo); - return; - } - - - if (odm->codec->type == GF_STREAM_TEXT) { - M_AnimationStream *as = (M_AnimationStream*) gf_sg_find_node_by_name(is->graph, "DYN_TEXT"); - if (!as) return; - if (is->text_url.url) free(is->text_url.url); - is->text_url.url = NULL; - is->text_url.OD_ID = odm->OD->objectDescriptorID; - if (!as->url.count) gf_sg_vrml_mf_alloc(&as->url, GF_SG_VRML_MFURL, 1); - as->url.vals[0].OD_ID = odm->OD->objectDescriptorID; - if (as->url.vals[0].url) free(as->url.vals[0].url); - url = odm->mo->URLs.count ? odm->mo->URLs.vals[0].url : NULL; - if (url) { - is->text_url.url = strdup(url); - as->url.vals[0].url = strdup(url); - } - as->startTime = gf_inline_get_time(is); - gf_node_changed((GF_Node *)as, NULL); - return; - } -} - - -GF_EXPORT -void gf_inline_force_scene_size(GF_InlineScene *is, u32 width, u32 height) -{ - /*for now only allowed when no scene info*/ - if (!is->is_dynamic_scene) return; - gf_sg_set_scene_size_info(is->graph, width, height, gf_sg_use_pixel_metrics(is->graph)); - - if (is->root_od->term->root_scene == is) - gf_sc_set_scene(is->root_od->term->compositor, is->graph); - - gf_is_resize_event(is); - - IS_UpdateVideoPos(is); -} - -void gf_inline_restart_dynamic(GF_InlineScene *is, u64 from_time) -{ - u32 i; - GF_List *to_restart; - GF_ObjectManager *odm; - - GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[InlineScene] Restarting from "LLD"\n", LLD_CAST from_time)); - to_restart = gf_list_new(); - i=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i))) { - if (odm->state) { - gf_list_add(to_restart, odm); - gf_odm_stop(odm, 1); - } - } - - /*reset clock*/ - if (is->dyn_ck) gf_clock_reset(is->dyn_ck); - - /*restart objects*/ - i=0; - while ((odm = (GF_ObjectManager*)gf_list_enum(to_restart, &i))) { - odm->media_start_time = from_time; - gf_odm_start(odm); - } - gf_list_del(to_restart); - - /*also check nodes if no media control since they may be deactivated (end of stream)*/ - if (!is->root_od->media_ctrl) { - M_AudioClip *ac = (M_AudioClip *) gf_sg_find_node_by_name(is->graph, "DYN_AUDIO"); - M_MovieTexture *mt = (M_MovieTexture *) gf_sg_find_node_by_name(is->graph, "DYN_VIDEO"); - M_AnimationStream *as = (M_AnimationStream *) gf_sg_find_node_by_name(is->graph, "DYN_TEXT"); - if (ac) { - ac->startTime = gf_inline_get_time(is); - gf_node_changed((GF_Node *)ac, NULL); - } - if (mt) { - mt->startTime = gf_inline_get_time(is); - gf_node_changed((GF_Node *)mt, NULL); - } - if (as) { - as->startTime = gf_inline_get_time(is); - gf_node_changed((GF_Node *)as, NULL); - } - } -} - - -GF_EXPORT -Bool gf_inline_process_anchor(GF_Node *caller, GF_Event *evt) -{ - u32 i; - GF_Terminal *term; - M_Inline *inl; - GF_InlineScene *is; - GF_SceneGraph *sg = gf_node_get_graph(caller); - if (!sg) return 1; - is = (GF_InlineScene *)gf_sg_get_private(sg); - if (!is) return 1; - term = is->root_od->term; - - /*if main scene forward to user. If no params or first one not "self" forward to user*/ - if ((term->root_scene==is) || !evt->navigate.parameters || !evt->navigate.param_count || (stricmp(evt->navigate.parameters[0], "self") && stricmp(evt->navigate.parameters[0], "_self"))) { - if (term->user->EventProc) return term->user->EventProc(term->user->opaque, evt); - return 1; - } - /*FIXME this is too restrictive, we assume the navigate URL is really a presentation one...*/ - i=0; - while ((inl = (M_Inline*)gf_list_enum(is->inline_nodes, &i))) { - switch (gf_node_get_tag((GF_Node *)inl)) { - case TAG_MPEG4_Inline: - case TAG_X3D_Inline: - gf_sg_vrml_mf_reset(&inl->url, GF_SG_VRML_MFURL); - gf_sg_vrml_mf_alloc(&inl->url, GF_SG_VRML_MFURL, 1); - inl->url.vals[0].url = strdup(evt->navigate.to_url ? evt->navigate.to_url : ""); - /*signal URL change but don't destroy inline scene now since we got this event from inside the scene, - this could crash compositors*/ - is->needs_restart = 2; - break; - } - } - return 1; -} - -GF_EXPORT -GF_Compositor *gf_sc_get_compositor(GF_Node *node) -{ - GF_InlineScene *is; - GF_SceneGraph *sg = gf_node_get_graph(node); - if (!sg) return NULL; - is = (GF_InlineScene *)gf_sg_get_private(sg); - if (!is) return NULL; - return is->root_od->term->compositor; -} - -const char *gf_inline_get_fragment_uri(GF_Node *node) -{ - GF_SceneGraph *sg = gf_node_get_graph(node); - GF_InlineScene *is = sg ? (GF_InlineScene *) gf_sg_get_private(sg) : NULL; - if (!is) return NULL; - return is->fragment_uri; -} -void gf_inline_set_fragment_uri(GF_Node *node, const char *uri) -{ - GF_SceneGraph *sg = gf_node_get_graph(node); - GF_InlineScene *is = sg ? (GF_InlineScene *) gf_sg_get_private(sg) : NULL; - if (!is) return; - if (is->fragment_uri) { - free(is->fragment_uri); - is->fragment_uri = NULL; - } - if (uri) is->fragment_uri = strdup(uri); -} - -GF_Node *gf_inline_get_subscene_root(GF_Node *node) -{ - GF_InlineScene *is; - if (!node) return NULL; - switch (gf_node_get_tag(node)) { - case TAG_MPEG4_Inline: case TAG_X3D_Inline: - break; - default: - return NULL; - } - is = (GF_InlineScene *)gf_node_get_private(node); - if (!is) return NULL; - return gf_sg_get_root_node(is->graph); -} - -GF_Node *gf_inline_get_parent_node(GF_Node *node, u32 idx) -{ - GF_InlineScene *is; - if (!node) return NULL; - switch (gf_node_get_tag(node)) { - case TAG_MPEG4_Inline: case TAG_X3D_Inline: - is = (GF_InlineScene *)gf_node_get_private(node); - break; - default: - is = (GF_InlineScene *)gf_sg_get_private(gf_node_get_graph(node)); - break; - } - if (!is) return NULL; - return (GF_Node *) gf_list_get(is->inline_nodes, idx); -} - -void InitInline(GF_InlineScene *is, GF_Node *node) -{ - gf_node_set_callback_function(node, gf_inline_traverse); -} - - diff --git a/src/terminal/input_sensor.c b/src/terminal/input_sensor.c index 7a1fc1f..f643154 100644 --- a/src/terminal/input_sensor.c +++ b/src/terminal/input_sensor.c @@ -23,10 +23,12 @@ */ #include <gpac/internal/terminal_dev.h> +#include <gpac/internal/compositor_dev.h> #include <gpac/utf.h> #include <gpac/nodes_x3d.h> #include <gpac/constants.h> -#include <gpac/compositor.h> + +#ifndef GPAC_DISABLE_VRML #include "input_sensor.h" @@ -49,7 +51,7 @@ static u32 htk_num_users = 0; input sensor decoder(s) handling */ -GF_Err IS_Configure(GF_BaseDecoder *plug, GF_InlineScene *scene, Bool is_remote) +GF_Err gf_isdec_configure(GF_BaseDecoder *plug, GF_Scene *scene, Bool is_remote) { ISPriv *is = (ISPriv *)plug->privateStack; /*we can only deal with encoded content (for now)*/ @@ -62,7 +64,7 @@ GF_Err IS_Configure(GF_BaseDecoder *plug, GF_InlineScene *scene, Bool is_remote) static void add_field(ISPriv *priv, u32 fieldType, const char *fieldName) { - GF_FieldInfo *field = (GF_FieldInfo *) malloc(sizeof(GF_FieldInfo)); + GF_FieldInfo *field = (GF_FieldInfo *) gf_malloc(sizeof(GF_FieldInfo)); memset(field, 0, sizeof(GF_FieldInfo)); field->fieldType = fieldType; field->far_ptr = gf_sg_vrml_field_pointer_new(fieldType); @@ -71,6 +73,38 @@ static void add_field(ISPriv *priv, u32 fieldType, const char *fieldName) gf_list_add(priv->ddf, field); } +static void isdev_add_field(GF_InputSensorDevice *dev, u32 fieldType, const char *fieldName) +{ + ISPriv *is = (ISPriv *)dev->input_decoder->privateStack; + add_field(is, fieldType, fieldName); +} + +static void isdev_dispatch_frame(struct __input_device *dev, u8 *data, u32 data_len) +{ + GF_SLHeader slh; + GF_Codec*cod; + u32 i; + ISPriv *priv = (ISPriv *)dev->input_decoder->privateStack; + + memset(&slh, 0, sizeof(GF_SLHeader)); + slh.accessUnitStartFlag = slh.accessUnitEndFlag = 1; + slh.compositionTimeStampFlag = 1; + /*note we could use an exact TS but it's not needed: since the input is generated locally + we want it to be decoded as soon as possible, thus using 0 emulates permanent seeking on + InputSensor stream, hence forces input frame resync*/ + slh.compositionTimeStamp = 0; + + /*get all decoders and send frame*/ + i=0; + while ((cod = (GF_Codec*)gf_list_enum(priv->scene->root_od->term->input_streams, &i))) { + ISPriv *is = (ISPriv *)cod->decio->privateStack; + if (is->type==priv->type) { + GF_Channel *ch = (GF_Channel *)gf_list_get(cod->inChannels, 0); + gf_es_receive_sl_packet(ch->service, ch, data, data_len, &slh, GF_OK); + } + } +} + static GF_Err IS_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) { GF_BitStream *bs; @@ -92,9 +126,9 @@ static GF_Err IS_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) devName[i] = gf_bs_read_int(bs, 8); } devName[i] = 0; + is->type = gf_crc_32(devName, len); size = len + 1; - is->type = 0; if (!stricmp(devName, "KeySensor")) { is->type = IS_KeySensor; add_field(is, GF_SG_VRML_SFINT32, "keyPressed"); @@ -127,53 +161,28 @@ static GF_Err IS_AttachStream(GF_BaseDecoder *plug, GF_ESD *esd) add_field(is, GF_SG_VRML_SFBOOL, "middleButtonDown"); add_field(is, GF_SG_VRML_SFBOOL, "rightButtonDown"); add_field(is, GF_SG_VRML_SFFLOAT, "wheel"); - -#if GPAC_HTK_DEMO - } else if (!stricmp(devName, "HTKSensor")) { - FILE *f; - u32 nb_word, nbPhone, c, j; - char szPh[3]; - char szName[1024]; - char *szPath = gf_cfg_get_key(is->scene->root_od->term->user->config, "HTK", "HTKDirectory"); - if (!szPath) szPath = gf_cfg_get_key(is->scene->root_od->term->user->config, "General", "ModulesDirectory"); - strcpy(is->szHTKPath, szPath); - if (szPath[strlen(szPath)-1] != GF_PATH_SEPARATOR) is->szHTKPath[strlen(szPath)] = GF_PATH_SEPARATOR; - - add_field(is, GF_SG_VRML_SFSTRING, "word"); - add_field(is, GF_SG_VRML_SFINT32, "wordIndex"); - add_field(is, GF_SG_VRML_SFFLOAT, "wordScore"); - - if (!htk_num_users) { - HTK_Init(is->szHTKPath); - htk_num_users++; - } - - sprintf(szName, "HTKD_%d", (u32) is); - strcat(is->szHTKPath, szName); - - f = fopen(is->szHTKPath, "wt"); - szPh[2] = 0; - nb_word = gf_bs_read_int(bs, 8); - for (i=0; i<nb_word; i++) { - nbPhone = gf_bs_read_int(bs, 8); - while ((c=gf_bs_read_int(bs, 8))) fprintf(f, "%c", c); - fprintf(f, " "); - for (j=0; j<nbPhone; j++) { - gf_bs_read_data(bs, szPh, 2); - if (j) fprintf(f, " "); - if (!stricmp(szPh, "vc")) fprintf(f, "vcl"); - else fprintf(f, "%s", szPh); + } + else { + GF_InputSensorDevice *ifce; + /*not found, check all modules*/ + u32 plugCount = gf_modules_get_count(is->scene->root_od->term->user->modules); + for (i = 0; i < plugCount ; i++) { + ifce = (GF_InputSensorDevice *) gf_modules_load_interface(is->scene->root_od->term->user->modules, i, GF_INPUT_DEVICE_INTERFACE); + if (!ifce) continue; + ifce->input_decoder = plug; + if (ifce->RegisterDevice && ifce->RegisterDevice(ifce, devName, bs, isdev_add_field) ) { + is->io_dev = ifce; + break; } - fprintf(f, "\n"); + gf_modules_close_interface((GF_BaseInterface *) ifce); } - fprintf(f, "RIEN sp\nSENT-END [] endsil\nSENT-START [] inisil\n"); - fclose(f); - is->type = IS_HTKSensor; + if (!is->io_dev) return GF_NOT_SUPPORTED; - StartHTK(is); -#endif - + is->io_dev->DispatchFrame = isdev_dispatch_frame; + plug->module_name = is->io_dev->module_name; + plug->author_name = is->io_dev->author_name; } + gf_bs_del(bs); return GF_OK; } @@ -182,15 +191,6 @@ static GF_Err IS_DetachStream(GF_BaseDecoder *plug, u16 ES_ID) { ISPriv *is = (ISPriv *)plug->privateStack; is->ES_ID = 0; -#if GPAC_HTK_DEMO - if (htk_num_users) { - htk_num_users--; - if (!htk_num_users) { - while (is->htk_running) gf_sleep(10); - HTK_Close(); - } - } -#endif return GF_OK; } @@ -258,8 +258,8 @@ static GF_Err IS_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffer length = gf_bs_read_int(bs, size); if (gf_bs_available(bs) < length) return GF_NON_COMPLIANT_BITSTREAM; - if ( ((SFString *)field->far_ptr)->buffer ) free( ((SFString *)field->far_ptr)->buffer); - ((SFString *)field->far_ptr)->buffer = (char*)malloc(sizeof(char)*(length+1)); + if ( ((SFString *)field->far_ptr)->buffer ) gf_free( ((SFString *)field->far_ptr)->buffer); + ((SFString *)field->far_ptr)->buffer = (char*)gf_malloc(sizeof(char)*(length+1)); memset(((SFString *)field->far_ptr)->buffer , 0, length+1); for (j=0; j<length; j++) { ((SFString *)field->far_ptr)->buffer[j] = gf_bs_read_int(bs, 8); @@ -288,11 +288,11 @@ static GF_Err IS_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffer if (len && (priv->enteredText[len-1] == priv->termChar)) { ptr = priv->enteredText; len = gf_utf8_wcstombs(tmp_utf8, 5000, &ptr); - if (outText->buffer) free(outText->buffer); - outText->buffer = (char*)malloc(sizeof(char) * (len+1)); + if (outText->buffer) gf_free(outText->buffer); + outText->buffer = (char*)gf_malloc(sizeof(char) * (len+1)); memcpy(outText->buffer, tmp_utf8, sizeof(char) * len); outText->buffer[len] = 0; - if (inText->buffer) free(inText->buffer); + if (inText->buffer) gf_free(inText->buffer); inText->buffer = NULL; priv->text_len = 0; @@ -312,8 +312,8 @@ static GF_Err IS_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffer priv->text_len = len; ptr = priv->enteredText; len = gf_utf8_wcstombs(tmp_utf8, 5000, &ptr); - if (inText->buffer) free(inText->buffer); - inText->buffer = (char*)malloc(sizeof(char) * (len+1)); + if (inText->buffer) gf_free(inText->buffer); + inText->buffer = (char*)gf_malloc(sizeof(char) * (len+1)); memcpy(inText->buffer, tmp_utf8, sizeof(char) * len); inText->buffer[len] = 0; field1->eventType = 1; @@ -330,7 +330,7 @@ static GF_Err IS_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffer if (!st->is->enabled) continue; count = gf_list_count(st->is->buffer.commandList); - scene_time = gf_inline_get_time(priv->scene); + scene_time = gf_scene_get_time(priv->scene); for (j=0; j<count; j++) { GF_Command *com = (GF_Command *)gf_list_get(st->is->buffer.commandList, j); GF_FieldInfo *field = (GF_FieldInfo *)gf_list_get(priv->ddf, j); @@ -345,7 +345,7 @@ static GF_Err IS_ProcessData(GF_SceneDecoder *plug, char *inBuffer, u32 inBuffer return e; } -void ISDec_Delete(GF_BaseDecoder *plug) +void gf_isdec_del(GF_BaseDecoder *plug) { ISPriv *priv = (ISPriv *)plug->privateStack; gf_list_del(priv->is_nodes); @@ -354,27 +354,24 @@ void ISDec_Delete(GF_BaseDecoder *plug) GF_FieldInfo *fi = (GF_FieldInfo *)gf_list_get(priv->ddf, 0); gf_list_rem(priv->ddf, 0); gf_sg_vrml_field_pointer_del(fi->far_ptr, fi->fieldType); - free(fi); + gf_free(fi); } gf_list_del(priv->ddf); -#if GPAC_HTK_DEMO - gf_th_del(priv->th); -#endif - free(priv); - free(plug); + gf_free(priv); + gf_free(plug); } -GF_BaseDecoder *NewISCodec(u32 PL) +GF_BaseDecoder *gf_isdec_new(GF_ESD *esd, u32 PL) { ISPriv *priv; GF_SceneDecoder *tmp; - tmp = (GF_SceneDecoder*) malloc(sizeof(GF_SceneDecoder)); + tmp = (GF_SceneDecoder*) gf_malloc(sizeof(GF_SceneDecoder)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_SceneDecoder)); - priv = (ISPriv *) malloc(sizeof(ISPriv)); + priv = (ISPriv *) gf_malloc(sizeof(ISPriv)); memset(priv, 0, sizeof(ISPriv)); priv->is_nodes = gf_list_new(); @@ -391,10 +388,6 @@ GF_BaseDecoder *NewISCodec(u32 PL) tmp->AttachScene = NULL; GF_REGISTER_MODULE_INTERFACE(tmp, GF_SCENE_DECODER_INTERFACE, "GPAC InputSensor Decoder", "gpac distribution") - -#if GPAC_HTK_DEMO - priv->th = gf_th_new("HTKDecoder"); -#endif return (GF_BaseDecoder *) tmp; } @@ -426,13 +419,17 @@ static void IS_Unregister(GF_Node *node, ISStack *st) /*stop stream*/ if (st->mo->num_open) gf_mo_stop(st->mo); st->mo = NULL; - st->registered = 0; + if (st->registered) { + st->registered = 0; + if (is_dec->io_dev && is_dec->io_dev->Stop) is_dec->io_dev->Start(is_dec->io_dev); + } } static void IS_Register(GF_Node *n) { GF_ObjectManager *odm; ISPriv *is_dec; + u32 i; ISStack *st = (ISStack *)gf_node_get_private(n); odm = st->mo->odm; if (!odm) return; @@ -442,14 +439,22 @@ static void IS_Register(GF_Node *n) /*get IS dec*/ is_dec = (ISPriv*)odm->codec->decio->privateStack; gf_list_add(is_dec->is_nodes, st); - st->registered = 1; -#if GPAC_HTK_DEMO - StartHTK(is_dec); -#endif + /*start stream*/ gf_mo_play(st->mo, 0, -1, 0); gf_term_unqueue_node_traverse(odm->term, n); + + /*we want at least one sensor enabled*/ + i=0; + while ((st = gf_list_enum(is_dec->is_nodes, &i))) { + if (st->is->enabled) { + st->registered = 1; + if (is_dec->io_dev && is_dec->io_dev->Start) is_dec->io_dev->Start(is_dec->io_dev); + break; + } + } + } static void TraverseInputSensor(GF_Node *node, void *rs, Bool is_destroy) @@ -458,41 +463,37 @@ static void TraverseInputSensor(GF_Node *node, void *rs, Bool is_destroy) M_InputSensor *is = (M_InputSensor *)node; if (is_destroy) { - GF_InlineScene *is; + GF_Scene *scene; if (st->registered) IS_Unregister(node, st); - is = (GF_InlineScene*)gf_sg_get_private(gf_node_get_graph(node)); - gf_term_unqueue_node_traverse(is->root_od->term, node); - free(st); + scene = (GF_Scene*)gf_sg_get_private(gf_node_get_graph(node)); + gf_term_unqueue_node_traverse(scene->root_od->term, node); + gf_free(st); } else { /*get decoder object */ - if (!st->mo) st->mo = gf_mo_register(node, &is->url, 0); + if (!st->mo) st->mo = gf_mo_register(node, &is->url, 0, 0); /*register with decoder*/ if (st->mo && !st->registered) IS_Register(node); } } -void InitInputSensor(GF_InlineScene *is, GF_Node *node) +void InitInputSensor(GF_Scene *scene, GF_Node *node) { ISStack *stack; GF_SAFEALLOC(stack, ISStack); stack->is = (M_InputSensor *) node; gf_node_set_private(node, stack); gf_node_set_callback_function(node, TraverseInputSensor); - gf_term_queue_node_traverse(is->root_od->term, node); + gf_term_queue_node_traverse(scene->root_od->term, node); } /*check only URL changes*/ void InputSensorModified(GF_Node *node) { -#if GPAC_HTK_DEMO - GF_ObjectManager *odm; - ISPriv *is_dec; -#endif GF_MediaObject *mo; ISStack *st = (ISStack *)gf_node_get_private(node); - mo = gf_mo_register(node, &st->is->url, 0); + mo = gf_mo_register(node, &st->is->url, 0, 0); if ((mo!=st->mo) || !st->registered){ if (mo!=st->mo) { if (st->mo) IS_Unregister(node, st); @@ -506,16 +507,6 @@ void InputSensorModified(GF_Node *node) IS_Unregister(node, st); return; } - -#if GPAC_HTK_DEMO - /*turn audio analyse on/off*/ - if (!st->is_dec || !st->is_dec->od_man) return; - odm = st->is_dec->od_man; - assert(odm->codec && (odm->codec->type == GF_STREAM_INTERACT)); - /*get IS dec*/ - is_dec = odm->codec->decio->privateStack; - StartHTK(is_dec); -#endif } @@ -561,6 +552,8 @@ void gf_term_mouse_input(GF_Terminal *term, GF_EventMouse *event) /*get BIFS coordinates*/ gf_sc_map_point(term->compositor, X, Y, &bX, &bY); + bX = gf_divfix(bX, term->compositor->scale_x); + bY = gf_divfix(bY, term->compositor->scale_y); bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); @@ -606,7 +599,7 @@ void gf_term_mouse_input(GF_Terminal *term, GF_EventMouse *event) gf_es_receive_sl_packet(ch->service, ch, buf, buf_size, &slh, GF_OK); } } - free(buf); + gf_free(buf); } void gf_term_keyboard_input(GF_Terminal *term, u32 key_code, u32 hw_code, Bool isKeyUp) @@ -615,7 +608,9 @@ void gf_term_keyboard_input(GF_Terminal *term, u32 key_code, u32 hw_code, Bool i GF_BitStream *bs; GF_SLHeader slh; char *buf; +#ifndef GPAC_DISABLE_X3D X_KeySensor *n; +#endif u32 buf_size; u32 actionKey = 0; u32 shiftKeyDown, controlKeyDown, altKeyDown; @@ -718,8 +713,9 @@ void gf_term_keyboard_input(GF_Terminal *term, u32 key_code, u32 hw_code, Bool i IS_ProcessData((GF_SceneDecoder*)cod->decio, buf, buf_size, 0, 0, 0); } } - free(buf); + gf_free(buf); +#ifndef GPAC_DISABLE_X3D i=0; while ((n = (X_KeySensor*)gf_list_enum(term->x3d_sensors, &i))) { u16 tc[2]; @@ -730,21 +726,21 @@ void gf_term_keyboard_input(GF_Terminal *term, u32 key_code, u32 hw_code, Bool i if (!n->enabled) return; if (keyPressed) { - if (n->keyPress.buffer) free(n->keyPress.buffer); + if (n->keyPress.buffer) gf_free(n->keyPress.buffer); tc[0] = keyPressed; tc[1] = 0; ptr = tc; len = gf_utf8_wcstombs(szStr, 10, &ptr); - n->keyPress.buffer = (char*)malloc(sizeof(char) * (len+1)); + n->keyPress.buffer = (char*)gf_malloc(sizeof(char) * (len+1)); memcpy(n->keyPress.buffer, szStr, sizeof(char) * len); n->keyPress.buffer[len] = 0; gf_node_event_out_str((GF_Node *)n, "keyPress"); } if (keyReleased) { - if (n->keyRelease.buffer) free(n->keyRelease.buffer); + if (n->keyRelease.buffer) gf_free(n->keyRelease.buffer); tc[0] = keyReleased; tc[1] = 0; ptr = tc; len = gf_utf8_wcstombs(szStr, 10, &ptr); - n->keyRelease.buffer = (char*)malloc(sizeof(char) * (len+1)); + n->keyRelease.buffer = (char*)gf_malloc(sizeof(char) * (len+1)); memcpy(n->keyRelease.buffer, szStr, sizeof(char) * len); n->keyRelease.buffer[len] = 0; gf_node_event_out_str((GF_Node *)n, "keyRelease"); @@ -779,6 +775,7 @@ void gf_term_keyboard_input(GF_Terminal *term, u32 key_code, u32 hw_code, Bool i gf_node_event_out_str((GF_Node *)n, "isActive"); } } +#endif } void gf_term_string_input(GF_Terminal *term, u32 character) @@ -786,7 +783,9 @@ void gf_term_string_input(GF_Terminal *term, u32 character) u32 i; GF_BitStream *bs; GF_SLHeader slh; +#ifndef GPAC_DISABLE_X3D X_StringSensor *n; +#endif GF_Codec *cod; char *buf; u32 buf_size; @@ -820,11 +819,12 @@ void gf_term_string_input(GF_Terminal *term, u32 character) gf_es_receive_sl_packet(ch->service, ch, buf, buf_size, &slh, GF_OK); - free(buf); + gf_free(buf); } } +#ifndef GPAC_DISABLE_X3D /*get all X3D StringSensors*/ i=0; while ((n = (X_StringSensor*)gf_list_enum(term->x3d_sensors, &i))) { @@ -843,15 +843,15 @@ void gf_term_string_input(GF_Terminal *term, u32 character) st->enteredText[st->text_len] = 0; ptr = st->enteredText; len = gf_utf8_wcstombs(szStr, 10, &ptr); - if (n->enteredText.buffer) free(n->enteredText.buffer); + if (n->enteredText.buffer) gf_free(n->enteredText.buffer); szStr[len] = 0; - n->enteredText.buffer = strdup(szStr); + n->enteredText.buffer = gf_strdup(szStr); gf_node_event_out_str((GF_Node *)n, "enteredText"); } } else if (character=='\r') { - if (n->finalText.buffer) free(n->finalText.buffer); + if (n->finalText.buffer) gf_free(n->finalText.buffer); n->finalText.buffer = n->enteredText.buffer; - n->enteredText.buffer = strdup(""); + n->enteredText.buffer = gf_strdup(""); st->text_len = 0; gf_node_event_out_str((GF_Node *)n, "enteredText"); gf_node_event_out_str((GF_Node *)n, "finalText"); @@ -861,14 +861,17 @@ void gf_term_string_input(GF_Terminal *term, u32 character) st->enteredText[st->text_len] = 0; ptr = st->enteredText; len = gf_utf8_wcstombs(szStr, 10, &ptr); - if (n->enteredText.buffer) free(n->enteredText.buffer); + if (n->enteredText.buffer) gf_free(n->enteredText.buffer); szStr[len] = 0; - n->enteredText.buffer = strdup(szStr); + n->enteredText.buffer = gf_strdup(szStr); gf_node_event_out_str((GF_Node *)n, "enteredText"); } } +#endif } +#ifndef GPAC_DISABLE_X3D + void DestroyKeySensor(GF_Node *node, void *rs, Bool is_destroy) { if (is_destroy) { @@ -876,11 +879,11 @@ void DestroyKeySensor(GF_Node *node, void *rs, Bool is_destroy) gf_list_del_item(term->x3d_sensors, node); } } -void InitKeySensor(GF_InlineScene *is, GF_Node *node) +void InitKeySensor(GF_Scene *scene, GF_Node *node) { - gf_node_set_private(node, is->root_od->term); + gf_node_set_private(node, scene->root_od->term); gf_node_set_callback_function(node, DestroyKeySensor); - gf_list_add(is->root_od->term->x3d_sensors, node); + gf_list_add(scene->root_od->term->x3d_sensors, node); } void DestroyStringSensor(GF_Node *node, void *rs, Bool is_destroy) @@ -888,101 +891,30 @@ void DestroyStringSensor(GF_Node *node, void *rs, Bool is_destroy) if (is_destroy) { StringSensorStack *st = (StringSensorStack *) gf_node_get_private(node); gf_list_del_item(st->term->x3d_sensors, node); - free(st); + gf_free(st); } } -void InitStringSensor(GF_InlineScene *is, GF_Node *node) +void InitStringSensor(GF_Scene *scene, GF_Node *node) { StringSensorStack*st; GF_SAFEALLOC(st, StringSensorStack) - st->term = is->root_od->term; + st->term = scene->root_od->term; gf_node_set_private(node, st); gf_node_set_callback_function(node, DestroyStringSensor); - gf_list_add(is->root_od->term->x3d_sensors, node); + gf_list_add(scene->root_od->term->x3d_sensors, node); } -#if GPAC_HTK_DEMO -u32 RunHTKDec(void *par) -{ - GF_BitStream *bs; - char *szWord; - s32 word_index; - u32 len, val, i; - Float word_score; - GF_SLHeader slh; - GF_Codec *cod; - unsigned char *buf; - u32 buf_size; - - - ISPriv *is_dec = (ISPriv *)par; -// while (is_dec->htk_running) +#endif /*GPAC_DISABLE_X3D*/ - HTK_DoDetection(); - szWord = HTK_GetWord(); - word_index = HTK_GetWordIndex(); - word_score = HTK_GetWordScore(); - - bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE); - - /*HTK sensor buffer format: SFString - SFInt32 - SFFloat*/ - gf_bs_write_int(bs, 1, 1); - len = strlen(szWord); - val = gf_get_bit_size(len); - gf_bs_write_int(bs, val, 5); - gf_bs_write_int(bs, len, val); - for (i=0; i<len; i++) gf_bs_write_int(bs, szWord[i], 8); - - gf_bs_write_int(bs, 1, 1); - gf_bs_write_int(bs, word_index, 32); - gf_bs_write_int(bs, 1, 1); - gf_bs_write_float(bs, word_score); - - gf_bs_align(bs); - gf_bs_get_content(bs, &buf, &buf_size); - gf_bs_del(bs); - - memset(&slh, 0, sizeof(GF_SLHeader)); - slh.accessUnitStartFlag = slh.accessUnitEndFlag = 1; - slh.compositionTimeStamp = 0; - - /*get all IS keySensor decoders and send frame*/ - i=0; - while ((cod = gf_list_enum(is_dec->scene->root_od->term->input_streams, &i))) { - ISPriv *is = cod->decio->privateStack; - if (is != is_dec) continue; - if (is->type==IS_HTKSensor) { - GF_Channel *ch = gf_list_get(cod->inChannels, 0); - gf_es_receive_sl_packet(ch->service, ch, buf, buf_size, &slh, GF_OK); - } - } - free(buf); - - is_dec->htk_running = 0; - return 0; +#else +void gf_term_mouse_input(GF_Terminal *term, GF_EventMouse *event) +{ } - -void StartHTK(ISPriv *is_dec) +void gf_term_keyboard_input(GF_Terminal *term, u32 key_code, u32 hw_code, Bool isKeyUp) +{ +} +void gf_term_string_input(GF_Terminal *term, u32 character) { - u32 j; - Bool run; - ISStack *st; - run = 0; - j=0; - while ((st = gf_list_enum(is_dec->is_nodes, &j))) { - if (st->is->enabled) { - run = 1; - break; - } - } - if (is_dec->htk_running && run) return; - if (!is_dec->htk_running && !run) return; - - is_dec->htk_running = run; - if (run) { - HTK_SetDictionary(is_dec->szHTKPath); - gf_th_run(is_dec->th, RunHTKDec, is_dec); - } } -#endif +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/terminal/input_sensor.h b/src/terminal/input_sensor.h index aa88726..949719d 100644 --- a/src/terminal/input_sensor.h +++ b/src/terminal/input_sensor.h @@ -29,6 +29,8 @@ /*input sensor defs*/ #include <gpac/nodes_mpeg4.h> +#ifndef GPAC_DISABLE_VRML + enum { IS_KeySensor = 1, @@ -39,16 +41,20 @@ enum #define GPAC_HTK_DEMO 0 + typedef struct { /*parent scene*/ - GF_InlineScene *scene; + GF_Scene *scene; /*list of attached nodes*/ GF_List *is_nodes; /*stream ID*/ u16 ES_ID; /*uncompressed data frame*/ GF_List *ddf; + + GF_InputSensorDevice *io_dev; + u32 type; /*string sensor sep char */ @@ -67,9 +73,9 @@ typedef struct } ISPriv; -GF_BaseDecoder *NewISCodec(u32 PL); -void ISDec_Delete(GF_BaseDecoder *plug); -GF_Err IS_Configure(GF_BaseDecoder *plug, GF_InlineScene *scene, Bool is_remote); +GF_BaseDecoder *gf_isdec_new(GF_ESD *esd, u32 PL); +void gf_isdec_del(GF_BaseDecoder *plug); +GF_Err gf_isdec_configure(GF_BaseDecoder *plug, GF_Scene *scene, Bool is_remote); typedef struct @@ -82,10 +88,10 @@ typedef struct } ISStack; -void InitInputSensor(GF_InlineScene *is, GF_Node *node); +void InitInputSensor(GF_Scene *scene, GF_Node *node); void InputSensorModified(GF_Node *n); -void InitKeySensor(GF_InlineScene *is, GF_Node *node); +void InitKeySensor(GF_Scene *scene, GF_Node *node); typedef struct @@ -95,7 +101,10 @@ typedef struct GF_Terminal *term; } StringSensorStack; -void InitStringSensor(GF_InlineScene *is, GF_Node *node); +void InitStringSensor(GF_Scene *scene, GF_Node *node); + +#endif /*GPAC_DISABLE_VRML*/ + #endif /*_INPUT_SENSOR_H_*/ diff --git a/src/terminal/media_control.c b/src/terminal/media_control.c index 6a2c521..72a90f7 100644 --- a/src/terminal/media_control.c +++ b/src/terminal/media_control.c @@ -26,33 +26,22 @@ #include "media_control.h" #include <gpac/constants.h> -Bool MC_URLChanged(MFURL *old_url, MFURL *new_url) -{ - u32 i; - if (URL_GetODID(old_url) != URL_GetODID(new_url)) return 1; - if (old_url->count != new_url->count) return 1; - - for (i=0; i<old_url->count; i++) { - if (old_url->vals[i].url || new_url->vals[i].url) { - if (!old_url->vals[i].url || !new_url->vals[i].url) return 1; - if (strcmp(old_url->vals[i].url, new_url->vals[i].url)) return 1; - } - } - return 0; -} - -void MC_Restart(GF_ObjectManager *odm) +void mediacontrol_restart(GF_ObjectManager *odm) { GF_List *to_restart; GF_ObjectManager *ctrl_od; GF_Clock *ck, *scene_ck; u32 i; u32 current_seg; +#ifndef GPAC_DISABLE_VRML MediaControlStack *ctrl; +#endif + if (!odm || (odm->flags & GF_ODM_NO_TIME_CTRL) ) return; - ctrl = ODM_GetMediaControl(odm); +#ifndef GPAC_DISABLE_VRML + ctrl = gf_odm_get_mediacontrol(odm); if (ctrl) { /*we have a control - filter calls to only handle objects owning media control*/ ctrl_od = ctrl->stream->odm; @@ -68,12 +57,13 @@ void MC_Restart(GF_ObjectManager *odm) return; } } +#endif /*if clock is main scene clock do nothing*/ scene_ck = gf_odm_get_media_clock(odm->parentscene->root_od); if (gf_odm_shares_clock(odm, scene_ck)) { if (odm->parentscene->is_dynamic_scene) - gf_inline_restart_dynamic(odm->parentscene, 0); + gf_scene_restart_dynamic(odm->parentscene, 0); return; } @@ -82,17 +72,19 @@ void MC_Restart(GF_ObjectManager *odm) if (!ck) return; current_seg = 0; +#ifndef GPAC_DISABLE_VRML /*store current segment idx*/ if (ctrl) { current_seg = ctrl->current_seg; /*if last segment is passed restart*/ if (gf_list_count(ctrl->seg) == current_seg) current_seg = 0; } +#endif to_restart = gf_list_new(); /*do stop/start in 2 pass, it's much cleaner for servers*/ i=0; - while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(odm->parentscene->ODlist, &i))) { + while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(odm->parentscene->resources, &i))) { if (!gf_odm_shares_clock(ctrl_od, ck)) continue; /*if running, stop and collect for restart*/ if (ctrl_od->state) { @@ -102,23 +94,45 @@ void MC_Restart(GF_ObjectManager *odm) } /*force clock reset since we don't know how OD ordering is done*/ gf_clock_reset(ck); +#ifndef GPAC_DISABLE_VRML if (ctrl) ctrl->current_seg = current_seg; +#endif /*play on all ODs collected for restart*/ i=0; while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(to_restart, &i))) { - gf_odm_start(ctrl_od); + gf_odm_start(ctrl_od, 0); } gf_list_del(to_restart); } +#ifndef GPAC_DISABLE_VRML + +Bool MC_URLChanged(MFURL *old_url, MFURL *new_url) +{ + u32 i; + if (gf_mo_get_od_id(old_url) != gf_mo_get_od_id(new_url)) return 1; + if (old_url->count != new_url->count) return 1; + + for (i=0; i<old_url->count; i++) { + if (old_url->vals[i].url || new_url->vals[i].url) { + if (!old_url->vals[i].url || !new_url->vals[i].url) return 1; + if (strcmp(old_url->vals[i].url, new_url->vals[i].url)) return 1; + } + } + return 0; +} + + + + /*resume all objects*/ -void MC_Resume(GF_ObjectManager *odm) +void mediacontrol_resume(GF_ObjectManager *odm) { u32 i; GF_ObjectManager *ctrl_od; - GF_InlineScene *in_scene; + GF_Scene *in_scene; GF_Clock *ck; if (odm->flags & GF_ODM_NO_TIME_CTRL) return; @@ -137,7 +151,7 @@ void MC_Resume(GF_ObjectManager *odm) } i=0; - while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->ODlist, &i))) { + while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->resources, &i))) { if (!odm->subscene && !gf_odm_shares_clock(ctrl_od, ck)) continue; gf_odm_resume(ctrl_od); } @@ -145,11 +159,11 @@ void MC_Resume(GF_ObjectManager *odm) /*pause all objects*/ -void MC_Pause(GF_ObjectManager *odm) +void mediacontrol_pause(GF_ObjectManager *odm) { u32 i; GF_ObjectManager *ctrl_od; - GF_InlineScene *in_scene; + GF_Scene *in_scene; GF_Clock *ck; if (odm->flags & GF_ODM_NO_TIME_CTRL) return; @@ -168,7 +182,7 @@ void MC_Pause(GF_ObjectManager *odm) } i=0; - while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->ODlist, &i))) { + while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->resources, &i))) { if (!odm->subscene && !gf_odm_shares_clock(ctrl_od, ck)) continue; gf_odm_pause(ctrl_od); } @@ -180,7 +194,7 @@ void MC_SetSpeed(GF_ObjectManager *odm, Fixed speed) { u32 i; GF_ObjectManager *ctrl_od; - GF_InlineScene *in_scene; + GF_Scene *in_scene; GF_Clock *ck; if (odm->flags & GF_ODM_NO_TIME_CTRL) return; @@ -198,7 +212,7 @@ void MC_SetSpeed(GF_ObjectManager *odm, Fixed speed) } i=0; - while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->ODlist, &i))) { + while ((ctrl_od = (GF_ObjectManager*)gf_list_enum(in_scene->resources, &i))) { if (!gf_odm_shares_clock(ctrl_od, ck)) continue; gf_odm_set_speed(ctrl_od, speed); } @@ -261,14 +275,14 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy) /*reset ODM using this control*/ if (stack->stream && stack->stream->odm) { odm = stack->stream->odm; - ODM_RemoveMediaControl(odm, stack); + gf_odm_remove_mediacontrol(odm, stack); } /*also removes the association ck<->MC if the object has been destroyed before the node*/ if (stack->ck) stack->ck->mc = NULL; gf_list_del(stack->seg); gf_sg_vrml_mf_reset(&stack->url, GF_SG_VRML_MFURL); - free(stack); + gf_free(stack); return; } @@ -284,7 +298,10 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy) gf_sg_vrml_mf_reset(&stack->url, GF_SG_VRML_MFURL); prev = stack->stream; - stack->stream = gf_inline_get_media_object(stack->parent, &stack->control->url, GF_MEDIA_OBJECT_UNDEF, 0); + if (gf_list_find(stack->parent->scene_objects, prev)<0) + prev = NULL; + + stack->stream = gf_scene_get_media_object(stack->parent, &stack->control->url, GF_MEDIA_OBJECT_UNDEF, 0); if (stack->stream) { if (!stack->stream->odm) return; /*MediaControl on inline: if dynamic scene, make sure it is connected before attaching...*/ @@ -294,9 +311,9 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy) gf_sg_vrml_field_copy(&stack->url, &stack->control->url, GF_SG_VRML_MFURL); /*remove from prev*/ - if (prev && prev->odm && (prev != stack->stream)) ODM_RemoveMediaControl(prev->odm, stack); + if (prev && prev->odm && (prev != stack->stream)) gf_odm_remove_mediacontrol(prev->odm, stack); /*register with new*/ - ODM_SetMediaControl((GF_ObjectManager *) stack->stream->odm, stack); + gf_odm_set_mediacontrol((GF_ObjectManager *) stack->stream->odm, stack); while (gf_list_count(stack->seg)) gf_list_rem(stack->seg, 0); gf_odm_init_segments((GF_ObjectManager *) stack->stream->odm, stack->seg, &stack->control->url); @@ -307,28 +324,39 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy) } /*control has been removed and we were paused, resume*/ else if (stack->paused) { - MC_Resume((GF_ObjectManager *) prev->odm); + mediacontrol_resume((GF_ObjectManager *) prev->odm); stack->paused = 0; } /*MediaControl has been detached*/ else { - ODM_RemoveMediaControl(prev->odm, stack); + if (prev) + gf_odm_remove_mediacontrol(prev->odm, stack); return; } } } else { - stack->stream = gf_inline_get_media_object(stack->parent, &stack->control->url, GF_MEDIA_OBJECT_UNDEF, 0); + stack->stream = gf_scene_get_media_object(stack->parent, &stack->control->url, GF_MEDIA_OBJECT_UNDEF, 0); if (!stack->stream || !stack->stream->odm) { if (stack->control->url.count) gf_term_invalidate_compositor(stack->parent->root_od->term); + stack->stream = NULL; return; } stack->ck = gf_odm_get_media_clock(stack->stream->odm); + /*OD not ready yet*/ + if (!stack->ck) { + stack->stream = NULL; + if (stack->control->url.count) gf_term_invalidate_compositor(stack->parent->root_od->term); + return; + } gf_sg_vrml_field_copy(&stack->url, &stack->control->url, GF_SG_VRML_MFURL); - ODM_SetMediaControl((GF_ObjectManager *) stack->stream->odm, stack); + gf_odm_set_mediacontrol((GF_ObjectManager *) stack->stream->odm, stack); while (gf_list_count(stack->seg)) gf_list_rem(stack->seg, 0); gf_odm_init_segments((GF_ObjectManager *) stack->stream->odm, stack->seg, &stack->control->url); stack->current_seg = 0; + + /*we shouldn't have to restart unless start/stop times have been changed, which is tested below*/ + need_restart = 0; } if (!stack->changed || !stack->control->enabled) return; @@ -337,7 +365,7 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy) /*if not previously enabled and now enabled, switch all other controls off and reactivate*/ if (!stack->enabled) { stack->enabled = 1; - need_restart = ODM_SwitchMediaControl(stack->stream->odm, stack); + need_restart = gf_odm_switch_mediacontrol(stack->stream->odm, stack); } stack->changed = 0; @@ -356,19 +384,19 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy) stack->media_stop = stack->control->mediaStopTime; stack->is_init = 1; /*the object has already been started, and media start time is not 0, restart*/ - if (stack->stream->num_open && (stack->media_start > 0) ) MC_Restart(odm); + if (stack->stream->num_open && (stack->media_start > 0) ) mediacontrol_restart(odm); return; } if (stack->media_speed != stack->control->mediaSpeed) { /*if no speed pause*/ if (!stack->control->mediaSpeed && !stack->paused) { - MC_Pause(odm); + mediacontrol_pause(odm); stack->paused = 1; } /*else resume if paused*/ else if (stack->control->mediaSpeed && stack->paused) { - MC_Resume(odm); + mediacontrol_resume(odm); stack->paused = 0; need_restart += shall_restart; } @@ -396,20 +424,20 @@ void RenderMediaControl(GF_Node *node, void *rs, Bool is_destroy) } if (need_restart) { - MC_Restart(odm); + mediacontrol_restart(odm); } /*handle preroll*/ } -void InitMediaControl(GF_InlineScene *is, GF_Node *node) +void InitMediaControl(GF_Scene *scene, GF_Node *node) { MediaControlStack *stack; GF_SAFEALLOC(stack, MediaControlStack); stack->changed = 1; - stack->parent = is; + stack->parent = scene; stack->control = (M_MediaControl *)node; stack->seg = gf_list_new(); @@ -438,6 +466,144 @@ void MC_Modified(GF_Node *node) // else stack->changed = 1; } + gf_node_dirty_set( gf_sg_get_root_node(gf_node_get_graph(node)), 0, 1); /*invalidate scene, we recompute MC state in render*/ gf_term_invalidate_compositor(stack->parent->root_od->term); } + + +void gf_odm_set_mediacontrol(GF_ObjectManager *odm, MediaControlStack *ctrl) +{ + u32 i; + GF_Channel *ch; + + /*keep track of it*/ + if (ctrl && (gf_list_find(odm->mc_stack, ctrl) < 0)) gf_list_add(odm->mc_stack, ctrl); + if (ctrl && !ctrl->control->enabled) return; + + if (odm->subscene && odm->subscene->is_dynamic_scene) { + if (odm->subscene->dyn_ck) { + /*deactivate current control*/ + if (ctrl && odm->subscene->dyn_ck->mc) { + odm->subscene->dyn_ck->mc->control->enabled = 0; + gf_node_event_out_str((GF_Node *)odm->subscene->dyn_ck->mc->control, "enabled"); + } + odm->subscene->dyn_ck->mc = ctrl; + } + } else { + /*for each clock in the controled OD*/ + i=0; + while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i))) { + if (ch->clock->mc != ctrl) { + /*deactivate current control*/ + if (ctrl && ch->clock->mc) { + ch->clock->mc->control->enabled = 0; + gf_node_event_out_str((GF_Node *)ch->clock->mc->control, "enabled"); + } + /*and attach this control to the clock*/ + ch->clock->mc = ctrl; + } + } + } + /*store active control on media*/ + odm->media_ctrl = gf_odm_get_mediacontrol(odm); +} + + + +MediaControlStack *gf_odm_get_mediacontrol(GF_ObjectManager *odm) +{ + GF_Clock *ck; + ck = gf_odm_get_media_clock(odm); + if (!ck) return NULL; + return ck->mc; +} + + +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); +} + +Bool gf_odm_switch_mediacontrol(GF_ObjectManager *odm, MediaControlStack *ctrl) +{ + u32 i; + MediaControlStack *st2; + if (!ctrl->control->enabled) return 0; + + /*for all media controls other than this one force enable to false*/ + i=0; + while ((st2 = (MediaControlStack *)gf_list_enum(odm->mc_stack, &i))) { + if (st2 == ctrl) continue; + if (st2->control->enabled) { + st2->control->enabled = 0; + gf_node_event_out_str((GF_Node *) st2->control, "enabled"); + } + st2->enabled = 0; + } + if (ctrl == odm->media_ctrl) return 0; + gf_odm_set_mediacontrol(odm, ctrl); + return 1; +} + +Bool gf_odm_check_segment_switch(GF_ObjectManager *odm) +{ + u32 count, i; + GF_Segment *cur, *next; + MediaControlStack *ctrl = gf_odm_get_mediacontrol(odm); + + /*if no control or control not on this object ignore segment switch*/ + if (!ctrl || (ctrl->stream->odm != odm)) return 0; + + count = gf_list_count(ctrl->seg); + /*reached end of controled stream (no more segments)*/ + if (ctrl->current_seg>=count) return 0; + + /*synth media, trigger if end of segment run-time*/ + if (!odm->codec || ((odm->codec->type!=GF_STREAM_VISUAL) && (odm->codec->type!=GF_STREAM_AUDIO))) { + GF_Clock *ck = gf_odm_get_media_clock(odm); + u32 now = gf_clock_time(ck); + u64 dur = odm->subscene ? odm->subscene->duration : odm->duration; + cur = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg); + if (odm->subscene && odm->subscene->needs_restart) return 0; + if (cur) dur = (u32) ((cur->Duration+cur->startTime)*1000); + if (now<=dur) return 0; + } else { + /*FIXME - for natural media with scalability, we should only process when all streams of the object are done*/ + } + + /*get current segment and move to next one*/ + cur = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg); + ctrl->current_seg ++; + + /*resync in case we have been issuing a play range over several segments*/ + for (i=ctrl->current_seg; i<count; i++) { + next = (GF_Segment *)gf_list_get(ctrl->seg, i); + if ( + /*if next seg start is after cur seg start*/ + (cur->startTime < next->startTime) + /*if next seg start is before cur seg end*/ + && (cur->startTime + cur->Duration > next->startTime) + /*if next seg start is already passed*/ + && (1000*next->startTime < odm->current_time) + /*then next segment was taken into account when requesting play*/ + ) { + cur = next; + ctrl->current_seg ++; + } + } + /*if last segment in ctrl is done, end of stream*/ + if (ctrl->current_seg >= count) return 0; + next = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg); + + /*if next seg start is not in current seg, media needs restart*/ + if ((next->startTime < cur->startTime) || (cur->startTime + cur->Duration < next->startTime)) + mediacontrol_restart(odm); + + return 1; +} + + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/terminal/media_control.h b/src/terminal/media_control.h index 7d767c1..0f8ef6d 100644 --- a/src/terminal/media_control.h +++ b/src/terminal/media_control.h @@ -32,6 +32,17 @@ #include <gpac/nodes_mpeg4.h> +/*restart object and takes care of media control/clock dependencies*/ +void mediacontrol_restart(GF_ObjectManager *odm); +void mediacontrol_pause(GF_ObjectManager *odm); +void mediacontrol_resume(GF_ObjectManager *odm); + +Bool MC_URLChanged(MFURL *old_url, MFURL *new_url); + +void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos); + +#ifndef GPAC_DISABLE_VRML + /*to do: add preroll support*/ typedef struct _media_control { @@ -43,7 +54,7 @@ typedef struct _media_control Bool enabled; MFURL url; - GF_InlineScene *parent; + GF_Scene *parent; /*stream owner*/ GF_MediaObject *stream; /*stream owner's clock*/ @@ -58,36 +69,29 @@ typedef struct _media_control GF_List *seg; /*current active segment index (ie, controling the PLAY range of the media)*/ u32 current_seg; - } MediaControlStack; -void InitMediaControl(GF_InlineScene *is, GF_Node *node); +void InitMediaControl(GF_Scene *scene, GF_Node *node); void MC_Modified(GF_Node *node); void MC_GetRange(MediaControlStack *ctrl, Double *start_range, Double *end_range); /*assign mediaControl for this object*/ -void ODM_SetMediaControl(GF_ObjectManager *odm, struct _media_control *ctrl); +void gf_odm_set_mediacontrol(GF_ObjectManager *odm, struct _media_control *ctrl); /*get media control ruling the clock the media is running on*/ -struct _media_control *ODM_GetMediaControl(GF_ObjectManager *odm); -/*get mediaControl controling and owned by the OD, or NULL if none*/ -struct _media_control *ODM_GetObjectMediaControl(GF_ObjectManager *odm); +struct _media_control *gf_odm_get_mediacontrol(GF_ObjectManager *odm); /*removes control from OD context*/ -void ODM_RemoveMediaControl(GF_ObjectManager *odm, struct _media_control *ctrl); +void gf_odm_remove_mediacontrol(GF_ObjectManager *odm, struct _media_control *ctrl); /*switches control (propagates enable=FALSE), returns 1 if control associated with OD has changed to new one*/ -Bool ODM_SwitchMediaControl(GF_ObjectManager *odm, struct _media_control *ctrl); +Bool gf_odm_switch_mediacontrol(GF_ObjectManager *odm, struct _media_control *ctrl); -/*restart object and takes care of media control/clock dependencies*/ -void MC_Restart(GF_ObjectManager *odm); -void MC_Pause(GF_ObjectManager *odm); -void MC_Resume(GF_ObjectManager *odm); - -Bool MC_URLChanged(MFURL *old_url, MFURL *new_url); +/*returns 1 if this is a segment switch, 0 otherwise - takes care of object restart if segment switch*/ +Bool gf_odm_check_segment_switch(GF_ObjectManager *odm); typedef struct _media_sensor { M_MediaSensor *sensor; - GF_InlineScene *parent; + GF_Scene *parent; GF_List *seg; Bool is_init; @@ -98,11 +102,11 @@ typedef struct _media_sensor u32 active_seg; } MediaSensorStack; -void InitMediaSensor(GF_InlineScene *is, GF_Node *node); +void InitMediaSensor(GF_Scene *scene, GF_Node *node); void MS_Modified(GF_Node *node); -void MS_UpdateTiming(GF_ObjectManager *odm, Bool is_eos); void MS_Stop(MediaSensorStack *st); +#endif /*GPAC_DISABLE_VRML*/ #endif /*_MEDIA_CONTROL_H_*/ diff --git a/src/terminal/media_manager.c b/src/terminal/media_manager.c index d4de80c..251b055 100644 --- a/src/terminal/media_manager.c +++ b/src/terminal/media_manager.c @@ -39,7 +39,8 @@ enum GF_MM_CE_THREADED = 1<<2, GF_MM_CE_REQ_THREAD = 1<<3, /*only used by threaded decs to signal end of thread*/ - GF_MM_CE_DEAD = 1<<4 + GF_MM_CE_DEAD = 1<<4, + GF_MM_CE_DISCRADED = 1<<5, }; typedef struct @@ -66,7 +67,7 @@ GF_Err gf_term_init_scheduler(GF_Terminal *term, u32 threading_mode) break; } - if (term->user->init_flags & GF_TERM_NO_VISUAL_THREAD) return GF_OK; + if (term->user->init_flags & GF_TERM_NO_THREAD) return GF_OK; term->mm_thread = gf_th_new("MediaManager"); term->flags |= GF_TERM_RUNNING; @@ -78,10 +79,23 @@ GF_Err gf_term_init_scheduler(GF_Terminal *term, u32 threading_mode) void gf_term_stop_scheduler(GF_Terminal *term) { if (term->mm_thread) { + u32 count, i; + term->flags &= ~GF_TERM_RUNNING; while (!(term->flags & GF_TERM_DEAD) ) gf_sleep(2); + count = gf_list_count(term->codecs); + for (i=0; i<count; i++) { + CodecEntry *ce = gf_list_get(term->codecs, i); + if (ce->flags & GF_MM_CE_DISCRADED) { + gf_free(ce); + gf_list_rem(term->codecs, i); + count--; + i--; + } + } + assert(! gf_list_count(term->codecs)); gf_th_del(term->mm_thread); } @@ -219,8 +233,12 @@ void gf_term_remove_codec(GF_Terminal *term, GF_Codec *codec) gf_th_del(ce->thread); gf_mx_del(ce->mx); } - free(ce); - gf_list_rem(term->codecs, i-1); + if (locked) { + gf_free(ce); + gf_list_rem(term->codecs, i-1); + } else { + ce->flags |= GF_MM_CE_DISCRADED; + } break; } if (locked) gf_mx_v(term->mm_mx); @@ -248,6 +266,7 @@ static u32 MM_SimulationStep(GF_Terminal *term) term->compositor->networks_time = gf_sys_clock(); #endif + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Media Manager] Entering simultion step\n")); gf_term_handle_services(term); #ifndef GF_DISABLE_LOG @@ -289,7 +308,13 @@ static u32 MM_SimulationStep(GF_Terminal *term) time_taken = gf_sys_clock() - time_taken; - if (ce->dec->CB && (ce->dec->CB->UnitCount >= ce->dec->CB->Min)) ce->dec->PriorityBoost = 0; + if (ce->flags & GF_MM_CE_DISCRADED) { + gf_free(ce); + gf_list_rem(term->codecs, term->last_codec); + count--; + } else { + if (ce->dec->CB && (ce->dec->CB->UnitCount >= ce->dec->CB->Min)) ce->dec->PriorityBoost = 0; + } remain -= 1; if (!remain) break; @@ -321,7 +346,7 @@ static u32 MM_SimulationStep(GF_Terminal *term) if (!(term->user->init_flags & GF_TERM_NO_REGULATION)) { gf_sleep(time_left); } -// GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Simulation step done in %d / %d ms\n", term->frame_duration-time_left, term->frame_duration)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Media Manager] Simulation step done in %d / %d ms\n", term->frame_duration-time_left, term->frame_duration)); return time_left; } @@ -421,6 +446,7 @@ void gf_term_start_codec(GF_Codec *codec) void gf_term_stop_codec(GF_Codec *codec) { + GF_CodecCapability cap; Bool locked = 0; CodecEntry *ce; GF_Terminal *term = codec->odm->term; @@ -439,9 +465,12 @@ void gf_term_stop_codec(GF_Codec *codec) } else { 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) ) { - GF_CodecCapability cap; cap.CapCode = GF_CODEC_SHOW_SCENE; cap.cap.valueInt = 0; gf_codec_set_capability(codec, cap); @@ -537,6 +566,26 @@ void gf_term_set_threading(GF_Terminal *term, u32 mode) gf_mx_v(term->mm_mx); } +Bool gf_term_lock_codec(GF_Codec *codec, Bool lock) +{ + Bool res = 1; + CodecEntry *ce; + GF_Terminal *term = codec->odm->term; + + ce = mm_get_codec(term->codecs, codec); + if (!ce) return 0; + + if (ce->mx) { + if (lock) res = gf_mx_try_lock(ce->mx); + else gf_mx_v(ce->mx); + } + else { + if (lock) res = gf_mx_try_lock(term->mm_mx); + else gf_mx_v(term->mm_mx); + } + return res; +} + void gf_term_set_priority(GF_Terminal *term, s32 Priority) { u32 i; diff --git a/src/terminal/media_memory.c b/src/terminal/media_memory.c index c1ec90c..0f50693 100644 --- a/src/terminal/media_memory.c +++ b/src/terminal/media_memory.c @@ -43,8 +43,8 @@ void gf_db_unit_del(GF_DBUnit *db) { if (!db) return; if (db->next) gf_db_unit_del(db->next); - if (db->data) free(db->data); - free(db); + if (db->data) gf_free(db->data); + gf_free(db); } static GF_CMUnit *gf_cm_unit_new() @@ -54,18 +54,39 @@ static GF_CMUnit *gf_cm_unit_new() return tmp; } +#ifdef _WIN32_WCE +#include <winbase.h> +static GFINLINE void *my_large_alloc(u32 size) { + void *ptr; + if (!size) return NULL; + ptr = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + if (!ptr) { + DWORD res = GetLastError(); + GF_LOG(GF_LOG_ERROR, GF_LOG_MEDIA, ("Cannot resize composition buffer to %d bytes - error %d", size, res)); + return NULL; + } + return ptr; +} +static GFINLINE void my_large_gf_free(void *ptr) { + if (ptr) VirtualFree(ptr, 0, MEM_RELEASE); +} +#else +#define my_large_alloc(_size) (_size ? gf_malloc(sizeof(char)*_size) : NULL) +#define my_large_gf_free(_ptr) gf_free(_ptr) +#endif + + static void gf_cm_unit_del(GF_CMUnit *cb) { if (cb->next) gf_cm_unit_del(cb->next); cb->next = NULL; if (cb->data) { - free(cb->data); + my_large_gf_free(cb->data); cb->data = NULL; } - free(cb); + gf_free(cb); } - GF_CompositionMemory *gf_cm_new(u32 UnitSize, u32 capacity) { GF_CompositionMemory *tmp; @@ -89,7 +110,7 @@ GF_CompositionMemory *gf_cm_new(u32 UnitSize, u32 capacity) cu->prev = prev; } cu->dataLength = 0; - cu->data = UnitSize ? (char*)malloc(sizeof(char)*UnitSize) : NULL; + cu->data = UnitSize ? (char*)my_large_alloc(sizeof(char)*UnitSize) : NULL; if (cu->data) memset(cu->data, 0, sizeof(char)*UnitSize); prev = cu; capacity --; @@ -119,7 +140,7 @@ void gf_cm_del(GF_CompositionMemory *cb) cb->input->prev->next = NULL; gf_cm_unit_del(cb->input); gf_odm_lock(cb->odm, 0); - free(cb); + gf_free(cb); } void gf_cm_rewind_input(GF_CompositionMemory *cb) @@ -366,11 +387,12 @@ void gf_cm_resize(GF_CompositionMemory *cb, u32 newCapacity) cu = cb->input; cb->UnitSize = newCapacity; - /*don't touch any existing memory (it may happen on the fly with audio)*/ - cu->data = (char*)realloc(cu->data, sizeof(char)*newCapacity); + my_large_gf_free(cu->data); + cu->data = (char*) my_large_alloc(newCapacity); cu = cu->next; while (cu != cb->input) { - cu->data = (char*)realloc(cu->data, sizeof(char)*newCapacity); + my_large_gf_free(cu->data); + cu->data = (char*) my_large_alloc(newCapacity); cu = cu->next; } @@ -406,7 +428,7 @@ void gf_cm_reinit(GF_CompositionMemory *cb, u32 UnitSize, u32 Capacity) cu->prev = prev; } cu->dataLength = 0; - cu->data = (char*)malloc(sizeof(char)*UnitSize); + cu->data = (char*)my_large_alloc(UnitSize); prev = cu; Capacity --; i++; @@ -444,8 +466,10 @@ GF_CMUnit *gf_cm_get_output(GF_CompositionMemory *cb) cb->Status = CB_STOP; cb->odm->current_time = (u32) cb->odm->media_stop_time; +#ifndef GPAC_DISABLE_VRML /*force update of media time*/ - MS_UpdateTiming(cb->odm, 1); + mediasensor_update_timing(cb->odm, 1); +#endif } goto exit; } @@ -459,13 +483,16 @@ GF_CMUnit *gf_cm_get_output(GF_CompositionMemory *cb) GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] Switching composition memory to stop state - time %d\n", cb->odm->OD->objectDescriptorID, (u32) cb->odm->media_stop_time)); cb->Status = CB_STOP; cb->odm->current_time = (u32) cb->odm->media_stop_time; +#ifndef GPAC_DISABLE_VRML /*force update of media time*/ - MS_UpdateTiming(cb->odm, 1); + mediasensor_update_timing(cb->odm, 1); +#endif + gf_odm_signal_eos(cb->odm); } } out = cb->output; - assert(out->TS >= cb->LastRenderedTS); + //assert(out->TS >= cb->LastRenderedTS); exit: return out; diff --git a/src/terminal/media_memory.h b/src/terminal/media_memory.h index 29dce9b..76b836c 100644 --- a/src/terminal/media_memory.h +++ b/src/terminal/media_memory.h @@ -32,6 +32,17 @@ extern "C" { #include <gpac/thread.h> +enum +{ + /*AU is RAP*/ + GF_DB_AU_RAP = 1, + /*special flag for systems streams: we may receive a CTS in a carousel, to indicate the + SFTime init time*/ + GF_DB_AU_CTS_IN_PAST = 1<<1, + /*hack for some DMB streams not signaling TS for BIFS*/ + GF_DB_AU_NO_TIMESTAMPS = 1<<2 +}; + /*compressed media unit*/ typedef struct _decoding_buffer { @@ -41,8 +52,8 @@ typedef struct _decoding_buffer u32 DTS; /*composition time stamp in ms*/ u32 CTS; - /*random access point flag*/ - Bool RAP; + /*AU flags*/ + u8 flags; /*amount of padding bits*/ u8 PaddingBits; @@ -57,7 +68,7 @@ void gf_db_unit_del(GF_DBUnit *db); /*composition memory (composition buffer) status*/ enum { - /*CB stoped (contains invalid data)*/ + /*CB stopped (contains invalid data)*/ CB_STOP = 0, /*CB playing (contains valid data)*/ CB_PLAY, diff --git a/src/terminal/media_object.c b/src/terminal/media_object.c index 8622715..987653a 100644 --- a/src/terminal/media_object.c +++ b/src/terminal/media_object.c @@ -32,7 +32,7 @@ #include <gpac/nodes_svg.h> -static GF_MediaObject *get_sync_reference(GF_InlineScene *is, XMLRI *iri, u32 o_type, GF_Node *orig_ref, Bool *post_pone) +static GF_MediaObject *get_sync_reference(GF_Scene *scene, XMLRI *iri, u32 o_type, GF_Node *orig_ref, Bool *post_pone) { MFURL mfurl; SFURL sfurl; @@ -46,8 +46,8 @@ static GF_MediaObject *get_sync_reference(GF_InlineScene *is, XMLRI *iri, u32 o_ return NULL; } else { if (iri->target) ref = iri->target; - else if (iri->string[0]=='#') ref = gf_sg_find_node_by_name(is->graph, iri->string+1); - else ref = gf_sg_find_node_by_name(is->graph, iri->string); + else if (iri->string[0]=='#') ref = gf_sg_find_node_by_name(scene->graph, iri->string+1); + else ref = gf_sg_find_node_by_name(scene->graph, iri->string); if (ref) { #ifndef GPAC_DISABLE_SVG @@ -61,13 +61,13 @@ static GF_MediaObject *get_sync_reference(GF_InlineScene *is, XMLRI *iri, u32 o_ case TAG_SVG_audio: o_type = GF_MEDIA_OBJECT_AUDIO; if (gf_node_get_attribute_by_tag(ref, TAG_XLINK_ATT_href, 0, 0, &info)==GF_OK) { - return get_sync_reference(is, info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone); + return get_sync_reference(scene, info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone); } return NULL; case TAG_SVG_video: o_type = GF_MEDIA_OBJECT_VIDEO; if (gf_node_get_attribute_by_tag(ref, TAG_XLINK_ATT_href, 0, 0, &info)==GF_OK) { - return get_sync_reference(is, info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone); + return get_sync_reference(scene, info.far_ptr, o_type, orig_ref ? orig_ref : ref, post_pone); } return NULL; #endif @@ -82,52 +82,71 @@ static GF_MediaObject *get_sync_reference(GF_InlineScene *is, XMLRI *iri, u32 o_ mfurl.vals[0].OD_ID = stream_id; mfurl.vals[0].url = iri->string; - res = gf_inline_get_media_object(is, &mfurl, o_type, 0); + res = gf_scene_get_media_object(scene, &mfurl, o_type, 0); if (!res) *post_pone = 1; return res; } GF_EXPORT -GF_MediaObject *gf_mo_register(GF_Node *node, MFURL *url, Bool lock_timelines) +GF_MediaObject *gf_mo_register(GF_Node *node, MFURL *url, Bool lock_timelines, Bool force_new_res) { u32 obj_type; #ifndef GPAC_DISABLE_SVG Bool post_pone; GF_FieldInfo info; #endif - GF_InlineScene *is; + GF_Scene *scene; GF_MediaObject *res, *syncRef; GF_SceneGraph *sg = gf_node_get_graph(node); if (!sg) return NULL; - is = (GF_InlineScene*)gf_sg_get_private(sg); - if (!is) return NULL; + scene = (GF_Scene*)gf_sg_get_private(sg); + if (!scene) return NULL; syncRef = NULL; /*keep track of the kind of object expected if URL is not using OD scheme*/ switch (gf_node_get_tag(node)) { - /*MPEG4 only*/ - case TAG_MPEG4_AudioSource: obj_type = GF_MEDIA_OBJECT_AUDIO; break; +#ifndef GPAC_DISABLE_VRML + /*MPEG-4 / VRML / X3D only*/ + case TAG_MPEG4_AudioClip: + case TAG_MPEG4_AudioSource: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_AudioClip: +#endif + obj_type = GF_MEDIA_OBJECT_AUDIO; + break; case TAG_MPEG4_AnimationStream: obj_type = GF_MEDIA_OBJECT_UPDATES; break; + case TAG_MPEG4_InputSensor: + obj_type = GF_MEDIA_OBJECT_INTERACT; + break; + case TAG_MPEG4_Background2D: + case TAG_MPEG4_Background: + case TAG_MPEG4_ImageTexture: + case TAG_MPEG4_CacheTexture: + case TAG_MPEG4_MovieTexture: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Background: + case TAG_X3D_ImageTexture: + case TAG_X3D_MovieTexture: +#endif + obj_type = GF_MEDIA_OBJECT_VIDEO; + break; + case TAG_MPEG4_Inline: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Inline: +#endif + obj_type = GF_MEDIA_OBJECT_SCENE; + break; +#endif /*GPAC_DISABLE_VRML*/ - case TAG_MPEG4_InputSensor: obj_type = GF_MEDIA_OBJECT_INTERACT; break; - - /*MPEG4/X3D*/ - case TAG_MPEG4_MovieTexture: case TAG_X3D_MovieTexture: obj_type = GF_MEDIA_OBJECT_VIDEO; break; - case TAG_MPEG4_Background2D: obj_type = GF_MEDIA_OBJECT_VIDEO; break; - case TAG_MPEG4_Background: case TAG_X3D_Background: obj_type = GF_MEDIA_OBJECT_VIDEO; break; - case TAG_MPEG4_ImageTexture: case TAG_X3D_ImageTexture: obj_type = GF_MEDIA_OBJECT_VIDEO; break; - case TAG_MPEG4_AudioClip: case TAG_X3D_AudioClip: obj_type = GF_MEDIA_OBJECT_AUDIO; break; - case TAG_MPEG4_Inline: case TAG_X3D_Inline: obj_type = GF_MEDIA_OBJECT_SCENE; break; - /*SVG*/ #ifndef GPAC_DISABLE_SVG case TAG_SVG_audio: obj_type = GF_MEDIA_OBJECT_AUDIO; if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, 0, 0, &info)==GF_OK) { - syncRef = get_sync_reference(is, info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone); + syncRef = get_sync_reference(scene, info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone); /*syncRef is specified but doesn't exist yet, post-pone*/ if (post_pone) return NULL; } @@ -135,7 +154,7 @@ GF_MediaObject *gf_mo_register(GF_Node *node, MFURL *url, Bool lock_timelines) case TAG_SVG_video: obj_type = GF_MEDIA_OBJECT_VIDEO; if (gf_node_get_attribute_by_tag(node, TAG_SVG_ATT_syncReference, 0, 0, &info)==GF_OK) { - syncRef = get_sync_reference(is, info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone); + syncRef = get_sync_reference(scene, info.far_ptr, GF_MEDIA_OBJECT_UNDEF, node, &post_pone); /*syncRef is specified but doesn't exist yet, post-pone*/ if (post_pone) return NULL; } @@ -143,22 +162,27 @@ GF_MediaObject *gf_mo_register(GF_Node *node, MFURL *url, Bool lock_timelines) case TAG_SVG_image: obj_type = GF_MEDIA_OBJECT_VIDEO; break; + case TAG_SVG_foreignObject: + case TAG_SVG_animation: + obj_type = GF_MEDIA_OBJECT_SCENE; + break; #endif default: obj_type = GF_MEDIA_OBJECT_UNDEF; break; } /*move to primary resource handler*/ - while (is->secondary_resource && is->root_od->parentscene) - is = is->root_od->parentscene; + while (scene->secondary_resource && scene->root_od->parentscene) + scene = scene->root_od->parentscene; - res = gf_inline_get_media_object_ex(is, url, obj_type, lock_timelines, syncRef, 0, node); + res = gf_scene_get_media_object_ex(scene, url, obj_type, lock_timelines, syncRef, force_new_res, node); if (res) { } return res; } + void gf_mo_unregister(GF_Node *node, GF_MediaObject *mo) { if (mo && node) { @@ -169,7 +193,7 @@ void gf_mo_unregister(GF_Node *node, GF_MediaObject *mo) GF_MediaObject *gf_mo_new() { GF_MediaObject *mo; - mo = (GF_MediaObject *) malloc(sizeof(GF_MediaObject)); + mo = (GF_MediaObject *) gf_malloc(sizeof(GF_MediaObject)); memset(mo, 0, sizeof(GF_MediaObject)); mo->speed = FIX_ONE; mo->URLs.count = 0; @@ -289,6 +313,7 @@ void gf_mo_update_caps(GF_MediaObject *mo) GF_EXPORT char *gf_mo_fetch_data(GF_MediaObject *mo, Bool resync, Bool *eos, u32 *timestamp, u32 *size) { + Bool force_decode = 0; u32 obj_time; GF_CMUnit *CU; *eos = 0; @@ -318,6 +343,17 @@ char *gf_mo_fetch_data(GF_MediaObject *mo, Bool resync, Bool *eos, u32 *timestam gf_odm_lock(mo->odm, 0); return NULL; } + if (! *eos && (mo->odm->codec->ck->speed > FIX_ONE)) + force_decode = 1; + + if (force_decode) { + gf_odm_lock(mo->odm, 0); + if (gf_term_lock_codec(mo->odm->codec, 1)) { + gf_codec_process(mo->odm->codec, 1); + gf_term_lock_codec(mo->odm->codec, 0); + } + gf_odm_lock(mo->odm, 1); + } /*new frame to fetch, lock*/ CU = gf_cm_get_output(mo->odm->codec->CB); @@ -337,7 +373,21 @@ char *gf_mo_fetch_data(GF_MediaObject *mo, Bool resync, Bool *eos, u32 *timestam u32 nb_droped = 0; obj_time = gf_clock_time(mo->odm->codec->ck); while (CU->TS < obj_time) { - if (!CU->next->dataLength) break; + if (!CU->next->dataLength) { + if (force_decode) { + obj_time = gf_clock_time(mo->odm->codec->ck); + gf_odm_lock(mo->odm, 0); + if (gf_term_lock_codec(mo->odm->codec, 1)) { + gf_codec_process(mo->odm->codec, 1); + gf_term_lock_codec(mo->odm->codec, 0); + } + gf_odm_lock(mo->odm, 1); + if (!CU->next->dataLength) + break; + } else { + break; + } + } /*figure out closest time*/ if (CU->next->TS > obj_time) { *eos = 0; @@ -351,15 +401,19 @@ char *gf_mo_fetch_data(GF_MediaObject *mo, Bool resync, Bool *eos, u32 *timestam /*discard*/ CU->RenderedLength = CU->dataLength = 0; gf_cm_drop_output(mo->odm->codec->CB); + /*get next*/ CU = gf_cm_get_output(mo->odm->codec->CB); *eos = gf_cm_is_eos(mo->odm->codec->CB); } } + mo->framesize = CU->dataLength - CU->RenderedLength; mo->frame = CU->data + CU->RenderedLength; if (mo->timestamp != CU->TS) { - MS_UpdateTiming(mo->odm, *eos); +#ifndef GPAC_DISABLE_VRML + mediasensor_update_timing(mo->odm, *eos); +#endif mo->timestamp = CU->TS; GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[ODM%d] At OTB %d fetch frame TS %d size %d - %d unit in CB\n", mo->odm->OD->objectDescriptorID, gf_clock_time(mo->odm->codec->ck), mo->timestamp, mo->framesize, mo->odm->codec->CB->UnitCount)); /*signal EOS after rendering last frame, not while rendering it*/ @@ -380,7 +434,9 @@ char *gf_mo_fetch_data(GF_MediaObject *mo, Bool resync, Bool *eos, u32 *timestam GF_EXPORT void gf_mo_release_data(GF_MediaObject *mo, u32 nb_bytes, s32 forceDrop) { +#if 0 u32 obj_time; +#endif if (!gf_odm_lock_mo(mo)) return; if (!mo->nb_fetch || !mo->odm->codec) { @@ -420,6 +476,8 @@ void gf_mo_release_data(GF_MediaObject *mo, u32 nb_bytes, s32 forceDrop) forceDrop--; // if (forceDrop) mo->odm->codec->nb_droped++; } else { + /*we cannot drop since we don't know the speed of the playback (which can even be frame by frame)*/ +#if 0 obj_time = gf_clock_time(mo->odm->codec->ck); if (mo->odm->codec->CB->output->next->dataLength) { if (2*obj_time < mo->timestamp + mo->odm->codec->CB->output->next->TS ) { @@ -430,6 +488,9 @@ void gf_mo_release_data(GF_MediaObject *mo, u32 nb_bytes, s32 forceDrop) } else { gf_cm_drop_output(mo->odm->codec->CB); } +#else + mo->odm->codec->CB->output->RenderedLength = 0; +#endif } } } @@ -467,14 +528,19 @@ void gf_mo_play(GF_MediaObject *mo, Double clipBegin, Double clipEnd, Bool can_l if (!mo) return; if (!mo->num_open && mo->odm) { + s32 res; Bool is_restart = 0; /*remove object from media queue*/ gf_term_lock_net(mo->odm->term, 1); - gf_list_del_item(mo->odm->term->media_queue, mo->odm); + res = gf_list_del_item(mo->odm->term->media_queue, mo->odm); gf_term_lock_net(mo->odm->term, 0); - if (mo->odm->media_start_time == (u64) -1) is_restart = 1; + if (mo->odm->action_type!=GF_ODM_ACTION_PLAY) { + mo->odm->action_type = GF_ODM_ACTION_PLAY; + is_restart = 0; + res = -1; + } if (mo->odm->flags & GF_ODM_NO_TIME_CTRL) { mo->odm->media_start_time = 0; @@ -497,17 +563,17 @@ void gf_mo_play(GF_MediaObject *mo, Double clipBegin, Double clipEnd, Bool can_l } } if (is_restart) { - MC_Restart(mo->odm); + mediacontrol_restart(mo->odm); } else { - if (mo->odm->subscene && mo->odm->subscene->is_dynamic_scene) - mo->odm->flags |= GF_ODM_REGENERATE_SCENE; + /*FIXME - this breaks inital loading on JPEG and PNG files ...*/ +// if (mo->odm->subscene && mo->odm->subscene->is_dynamic_scene) mo->odm->flags |= GF_ODM_REGENERATE_SCENE; - gf_odm_start(mo->odm); + gf_odm_start(mo->odm, (res>=0) ? 1 : 0); } } else if (mo->odm) { if (mo->num_to_restart) mo->num_restart--; if (!mo->num_restart && (mo->num_to_restart==mo->num_open+1) ) { - MC_Restart(mo->odm); + mediacontrol_restart(mo->odm); mo->num_to_restart = mo->num_restart = 0; } } @@ -528,7 +594,7 @@ void gf_mo_stop(GF_MediaObject *mo) gf_list_add(mo->odm->term->media_queue, mo->odm); /*signal STOP request*/ - mo->odm->media_start_time = (u64)-1; + mo->odm->action_type = GF_ODM_ACTION_STOP; gf_mx_v(mo->odm->term->net_mx); } else { @@ -541,12 +607,14 @@ void gf_mo_stop(GF_MediaObject *mo) GF_EXPORT void gf_mo_restart(GF_MediaObject *mo) { - MediaControlStack *ctrl; + void *mediactrl_stack = NULL; if (!gf_odm_lock_mo(mo)) return; - ctrl = ODM_GetMediaControl(mo->odm); +#ifndef GPAC_DISABLE_VRML + mediactrl_stack = gf_odm_get_mediacontrol(mo->odm); +#endif /*if no control and not root of a scene, check timelines are unlocked*/ - if (!ctrl && !mo->odm->subscene) { + if (!mediactrl_stack && !mo->odm->subscene) { /*don't restart if sharing parent scene clock*/ if (gf_odm_shares_clock(mo->odm, gf_odm_get_media_clock(mo->odm->parentscene->root_od))) { gf_odm_lock(mo->odm, 0); @@ -554,19 +622,156 @@ void gf_mo_restart(GF_MediaObject *mo) } } /*all other cases, call restart to take into account clock references*/ - MC_Restart(mo->odm); + mediacontrol_restart(mo->odm); gf_odm_lock(mo->odm, 0); } +u32 gf_mo_get_od_id(MFURL *url) +{ + u32 i, j, tmpid; + char *str, *s_url; + u32 id = 0; + + if (!url) return 0; + + for (i=0; i<url->count; i++) { + if (url->vals[i].OD_ID) { + /*works because OD ID 0 is forbidden in MPEG4*/ + if (!id) { + id = url->vals[i].OD_ID; + } + /*bad url, only one object can be described in MPEG4 urls*/ + else if (id != url->vals[i].OD_ID) return 0; + } else if (url->vals[i].url && strlen(url->vals[i].url)) { + /*format: od:ID or od:ID#segment - also check for "ID" in case...*/ + str = url->vals[i].url; + if (!strnicmp(str, "od:", 3)) str += 3; + /*remove segment info*/ + s_url = gf_strdup(str); + j = 0; + while (j<strlen(s_url)) { + if (s_url[j]=='#') { + s_url[j] = 0; + break; + } + j++; + } + j = sscanf(s_url, "%d", &tmpid); + /*be carefull, an url like "11-regression-test.mp4" will return 1 on sscanf :)*/ + if (j==1) { + char szURL[20]; + sprintf(szURL, "%d", tmpid); + if (stricmp(szURL, s_url)) j = 0; + } + gf_free(s_url); + + if (j!= 1) { + /*dynamic OD if only one URL specified*/ + if (!i) return GF_MEDIA_EXTERNAL_ID; + /*otherwise ignore*/ + continue; + } + if (!id) { + id = tmpid; + continue; + } + /*bad url, only one object can be described in MPEG4 urls*/ + else if (id != tmpid) return 0; + } + } + return id; +} + + +Bool gf_mo_is_same_url(GF_MediaObject *obj, MFURL *an_url, Bool *keep_fragment, u32 obj_hint_type) +{ + Bool include_sub_url = 0; + u32 i; + char szURL1[GF_MAX_PATH], szURL2[GF_MAX_PATH], *ext; + + if (obj->OD_ID==GF_MEDIA_EXTERNAL_ID) { + if (!obj->URLs.count) { + if (!obj->odm) return 0; + strcpy(szURL1, obj->odm->net_service->url); + } else { + strcpy(szURL1, obj->URLs.vals[0].url); + } + } else { + if (!obj->URLs.count) return 0; + strcpy(szURL1, obj->URLs.vals[0].url); + } + + /*don't analyse audio/video to locate segments or viewports*/ + if ((obj->type==GF_MEDIA_OBJECT_AUDIO) || (obj->type==GF_MEDIA_OBJECT_VIDEO)) { + if (keep_fragment) *keep_fragment = 0; + include_sub_url = 1; + } else if ((obj->type==GF_MEDIA_OBJECT_SCENE) && keep_fragment && obj->odm) { + GF_ClientService *ns; + u32 j; + /*for remoteODs/dynamic ODs, check if one of the running service cannot be used*/ + for (i=0; i<an_url->count; i++) { + char *frag = strrchr(an_url->vals[i].url, '#'); + j=0; + /*this is the same object (may need some refinement)*/ + if (!stricmp(szURL1, an_url->vals[i].url)) return 1; + + /*fragment is a media segment, same URL*/ + if (frag ) { + Bool same_res = 0; + frag[0] = 0; + same_res = !strncmp(an_url->vals[i].url, szURL1, strlen(an_url->vals[i].url)) ? 1 : 0; + frag[0] = '#'; + + /*if we're talking about the same resource, check if the fragment can be matched*/ + if (same_res) { + /*if the fragment is a node which can be found, this is the same resource*/ + if (obj->odm->subscene && (gf_sg_find_node_by_name(obj->odm->subscene->graph, frag+1)!=NULL) ) + return 1; + + /*if the expected type is an existing segment (undefined media type), this is the same resource*/ + if (!obj_hint_type && gf_odm_find_segment(obj->odm, frag+1)) + return 1; + } + } + + while ( (ns = (GF_ClientService*)gf_list_enum(obj->odm->term->net_services, &j)) ) { + /*sub-service of an existing service - don't touch any fragment*/ + if (gf_term_service_can_handle_url(ns, an_url->vals[i].url)) { + *keep_fragment = 1; + return 0; + } + } + } + } + + /*check on full URL without removing fragment IDs*/ + if (include_sub_url) { + for (i=0; i<an_url->count; i++) { + if (!stricmp(szURL1, an_url->vals[i].url)) return 1; + } + return 0; + } + ext = strrchr(szURL1, '#'); + if (ext) ext[0] = 0; + for (i=0; i<an_url->count; i++) { + if (!an_url->vals[i].url) return 0; + strcpy(szURL2, an_url->vals[i].url); + ext = strrchr(szURL2, '#'); + if (ext) ext[0] = 0; + if (!stricmp(szURL1, szURL2)) return 1; + } + return 0; +} + GF_EXPORT Bool gf_mo_url_changed(GF_MediaObject *mo, MFURL *url) { u32 od_id; Bool ret = 0; if (!mo) return (url ? 1 : 0); - od_id = URL_GetODID(url); - if ( (mo->OD_ID == GF_ESM_DYNAMIC_OD_ID) && (od_id == GF_ESM_DYNAMIC_OD_ID)) { - ret = !gf_mo_is_same_url(mo, url); + od_id = gf_mo_get_od_id(url); + if ( (mo->OD_ID == GF_MEDIA_EXTERNAL_ID) && (od_id == GF_MEDIA_EXTERNAL_ID)) { + ret = !gf_mo_is_same_url(mo, url, NULL, 0); } else { ret = (mo->OD_ID == od_id) ? 0 : 1; } @@ -581,45 +786,65 @@ Bool gf_mo_url_changed(GF_MediaObject *mo, MFURL *url) GF_EXPORT void gf_mo_pause(GF_MediaObject *mo) { +#ifndef GPAC_DISABLE_VRML if (!mo || !mo->num_open || !mo->odm) return; - - MC_Pause(mo->odm); + mediacontrol_pause(mo->odm); +#endif } GF_EXPORT void gf_mo_resume(GF_MediaObject *mo) { +#ifndef GPAC_DISABLE_VRML if (!mo || !mo->num_open || !mo->odm) return; - - MC_Resume(mo->odm); + mediacontrol_resume(mo->odm); +#endif } GF_EXPORT void gf_mo_set_speed(GF_MediaObject *mo, Fixed speed) { +#ifndef GPAC_DISABLE_VRML MediaControlStack *ctrl; +#endif if (!mo) return; if (!mo->odm) { mo->speed = speed; return; } +#ifndef GPAC_DISABLE_VRML /*if media control forbidd that*/ - ctrl = ODM_GetMediaControl(mo->odm); + ctrl = gf_odm_get_mediacontrol(mo->odm); if (ctrl) return; +#endif gf_odm_set_speed(mo->odm, speed); } +GF_EXPORT +Fixed gf_mo_get_current_speed(GF_MediaObject *mo) +{ + return (mo && mo->odm && mo->odm->codec) ? mo->odm->codec->ck->speed : FIX_ONE; +} + + GF_EXPORT Fixed gf_mo_get_speed(GF_MediaObject *mo, Fixed in_speed) { - Fixed res; + Fixed res = in_speed; + +#ifndef GPAC_DISABLE_VRML MediaControlStack *ctrl; + if (!gf_odm_lock_mo(mo)) return in_speed; + /*get control*/ - ctrl = ODM_GetMediaControl(mo->odm); - res = ctrl ? ctrl->control->mediaSpeed : in_speed; + ctrl = gf_odm_get_mediacontrol(mo->odm); + if (ctrl) res = ctrl->control->mediaSpeed; + gf_odm_lock(mo->odm, 0); +#endif + return res; } @@ -627,16 +852,26 @@ GF_EXPORT Bool gf_mo_get_loop(GF_MediaObject *mo, Bool in_loop) { GF_Clock *ck; +#ifndef GPAC_DISABLE_VRML MediaControlStack *ctrl; +#endif if (!gf_odm_lock_mo(mo)) return in_loop; /*get control*/ - ctrl = ODM_GetMediaControl(mo->odm); +#ifndef GPAC_DISABLE_VRML + ctrl = gf_odm_get_mediacontrol(mo->odm); if (ctrl) in_loop = ctrl->control->loop; +#endif /*otherwise looping is only accepted if not sharing parent scene clock*/ ck = gf_odm_get_media_clock(mo->odm->parentscene->root_od); - if (gf_odm_shares_clock(mo->odm, ck)) in_loop = 0; + if (gf_odm_shares_clock(mo->odm, ck)) { + in_loop = 0; +#ifndef GPAC_DISABLE_VRML + if (ctrl && ctrl->stream->odm && ctrl->stream->odm->subscene) + gf_term_invalidate_compositor(mo->odm->term); +#endif + } gf_odm_lock(mo->odm, 0); return in_loop; } @@ -655,7 +890,9 @@ GF_EXPORT Bool gf_mo_should_deactivate(GF_MediaObject *mo) { Bool res = 0; +#ifndef GPAC_DISABLE_VRML MediaControlStack *ctrl; +#endif if (!gf_odm_lock_mo(mo)) return 0; @@ -664,15 +901,18 @@ Bool gf_mo_should_deactivate(GF_MediaObject *mo) return 0; } +#ifndef GPAC_DISABLE_VRML /*get media control and see if object owning control is running*/ - ctrl = ODM_GetMediaControl(mo->odm); + ctrl = gf_odm_get_mediacontrol(mo->odm); if (!ctrl) res = 1; /*if ctrl and ctrl not ruling this mediaObject, deny deactivation*/ else if (ctrl->stream->odm != mo->odm) res = 0; /*this is currently under discussion in MPEG. for now we deny deactivation as soon as a mediaControl is here*/ else if (ctrl->stream->odm->state) res = 0; /*otherwise allow*/ - else res = 1; + else +#endif + res = 1; gf_odm_lock(mo->odm, 0); return res; @@ -682,9 +922,11 @@ GF_EXPORT Bool gf_mo_is_muted(GF_MediaObject *mo) { Bool res = 0; +#ifndef GPAC_DISABLE_VRML if (!gf_odm_lock_mo(mo)) return 0; res = mo->odm->media_ctrl ? mo->odm->media_ctrl->control->mute : 0; gf_odm_lock(mo->odm, 0); +#endif return res; } @@ -761,15 +1003,15 @@ Bool gf_mo_has_audio(GF_MediaObject *mo) u32 i; GF_NetworkCommand com; GF_ClientService *ns; - GF_InlineScene *is; + GF_Scene *scene; if (!mo || !mo->odm) return 0; if (mo->type != GF_MEDIA_OBJECT_VIDEO) return 0; ns = mo->odm->net_service; - is = mo->odm->parentscene; + scene = mo->odm->parentscene; sub_url = strchr(ns->url, '#'); - for (i=0; i<gf_list_count(is->ODlist); i++) { - GF_ObjectManager *odm = gf_list_get(is->ODlist, i); + for (i=0; i<gf_list_count(scene->resources); i++) { + GF_ObjectManager *odm = gf_list_get(scene->resources, i); if (odm->net_service != ns) continue; if (!odm->mo) continue; diff --git a/src/terminal/media_sensor.c b/src/terminal/media_sensor.c index f11fb14..4224845 100644 --- a/src/terminal/media_sensor.c +++ b/src/terminal/media_sensor.c @@ -26,6 +26,8 @@ #include "media_control.h" #include <gpac/constants.h> +#ifndef GPAC_DISABLE_VRML + /*render : setup media sensor and update timing in case of inline scenes*/ void RenderMediaSensor(GF_Node *node, void *rs, Bool is_destroy) { @@ -38,11 +40,11 @@ void RenderMediaSensor(GF_Node *node, void *rs, Bool is_destroy) gf_list_del_item(st->stream->odm->ms_stack, st); gf_list_del(st->seg); - free(st); + gf_free(st); return; } - if (!st->stream) st->stream = gf_mo_register(node, &st->sensor->url, 0); + if (!st->stream) st->stream = gf_mo_register(node, &st->sensor->url, 0, 0); if (!st->stream || !st->stream->odm) return; if (!st->is_init) { @@ -72,16 +74,16 @@ void RenderMediaSensor(GF_Node *node, void *rs, Bool is_destroy) if (ck && gf_clock_is_started(ck) ) { st->stream->odm->current_time = gf_clock_time(ck); - MS_UpdateTiming(st->stream->odm, 0); + mediasensor_update_timing(st->stream->odm, 0); } } -void InitMediaSensor(GF_InlineScene *is, GF_Node *node) +void InitMediaSensor(GF_Scene *scene, GF_Node *node) { MediaSensorStack *st; GF_SAFEALLOC(st, MediaSensorStack); - st->parent = is; + st->parent = scene; st->sensor = (M_MediaSensor *)node; st->seg = gf_list_new(); gf_node_set_callback_function(node, RenderMediaSensor); @@ -98,16 +100,16 @@ void MS_Modified(GF_Node *node) while (gf_list_count(st->seg)) gf_list_rem(st->seg, 0); /*unlink from OD*/ - if (st->stream && st->stream->odm) + if (st->stream && st->stream->odm && st->stream->odm->ms_stack) gf_list_del_item(st->stream->odm->ms_stack, st); gf_mo_unregister(node, st->stream); - st->stream = gf_mo_register(node, &st->sensor->url, 0); + st->stream = gf_mo_register(node, &st->sensor->url, 0, 0); st->is_init = 0; gf_term_invalidate_compositor(st->parent->root_od->term); } -void MS_UpdateTiming(GF_ObjectManager *odm, Bool is_eos) +void mediasensor_update_timing(GF_ObjectManager *odm, Bool is_eos) { GF_Segment *desc; u32 i, count, j, ms_count; @@ -189,7 +191,7 @@ void MS_UpdateTiming(GF_ObjectManager *odm, Bool is_eos) /*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 ? strdup(desc->SegmentName) : NULL; + media_sens->sensor->info.vals[0] = desc->SegmentName ? gf_strdup(desc->SegmentName) : NULL; gf_node_event_out_str((GF_Node *) media_sens->sensor, "info"); /*set duration*/ media_sens->sensor->mediaDuration = desc->Duration; @@ -230,3 +232,5 @@ void MS_Stop(MediaSensorStack *st) } st->active_seg = 0; } + +#endif /*GPAC_DISABLE_VRML*/ diff --git a/src/terminal/mpeg4_inline.c b/src/terminal/mpeg4_inline.c new file mode 100644 index 0000000..4a95ec4 --- /dev/null +++ b/src/terminal/mpeg4_inline.c @@ -0,0 +1,715 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * All rights reserved + * + * This file is part of GPAC / Media terminal 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. + * + */ + + + +/*for OD service types*/ +#include <gpac/constants.h> +/*for URL concatenation*/ +#include <gpac/network.h> +#include <gpac/internal/terminal_dev.h> +#include "media_control.h" +#include <gpac/compositor.h> +#include <gpac/nodes_x3d.h> +#include <gpac/crypt.h> + +/*SVG properties*/ +#ifndef GPAC_DISABLE_SVG +#include <gpac/scenegraph_svg.h> +#endif + + + +#ifndef GPAC_DISABLE_VRML + +void gf_inline_restart(GF_Scene *scene) +{ + scene->needs_restart = 1; + gf_term_invalidate_compositor(scene->root_od->term); +} + + +static Bool gf_inline_set_scene(M_Inline *root) +{ + GF_MediaObject *mo; + GF_Scene *parent; + GF_SceneGraph *graph = gf_node_get_graph((GF_Node *) root); + parent = (GF_Scene *)gf_sg_get_private(graph); + if (!parent) return 0; + + mo = gf_scene_get_media_object_ex(parent, &root->url, GF_MEDIA_OBJECT_SCENE, 0, NULL, 0, (GF_Node*)root); + if (!mo || !mo->odm) return 0; + + if (!mo->odm->subscene) { + gf_term_invalidate_compositor(parent->root_od->term); + return 0; + } + /*assign inline scene as private stack of inline node, and remember inline node for event propagation*/ + gf_node_set_private((GF_Node *)root, mo->odm->subscene); + /*play*/ + gf_mo_play(mo, 0, -1, 0); + return 1; +} + +void gf_inline_on_modified(GF_Node *node) +{ + u32 ODID; + GF_MediaObject *mo; + M_Inline *pInline = (M_Inline *) node; + GF_Scene *scene = (GF_Scene *)gf_node_get_private(node); + + ODID = gf_mo_get_od_id(&pInline->url); + if (scene) { + mo = (scene->root_od) ? scene->root_od->mo : NULL; + + /*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/ + if (mo) { + Bool changed = 1; + if (ODID != GF_MEDIA_EXTERNAL_ID) { + if (ODID && (ODID==scene->root_od->OD->objectDescriptorID)) changed = 0; + } else { + if (gf_mo_is_same_url(mo, &pInline->url, NULL, 0) ) changed = 0; + } + if (mo->num_open) { + if (!changed) return; + + gf_scene_notify_event(scene, GF_EVENT_UNLOAD, node, NULL); + gf_node_dirty_parents(node); + gf_list_del_item(mo->nodes, node); + + switch (gf_node_get_tag(node)) { + case TAG_MPEG4_Inline: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Inline: +#endif + gf_node_set_private(node, NULL); + break; + } + + mo->num_open --; + if (!mo->num_open) { + if (ODID == GF_MEDIA_EXTERNAL_ID) { + GF_Scene *parent = scene->root_od->parentscene; + /*!!! THIS WILL DESTROY THE INLINE SCENE OBJECT !!!*/ + gf_odm_disconnect(scene->root_od, 1); + /*and force removal of the media object*/ + if (parent) { + if (gf_list_del_item(parent->scene_objects, mo)>=0) { + gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL); + gf_list_del(mo->nodes); + gf_free(mo); + } + } + } else { + gf_term_lock_net(scene->root_od->term, 1); + + /*external media are completely unloaded*/ + if (scene->root_od->OD->objectDescriptorID==GF_MEDIA_EXTERNAL_ID) { + scene->root_od->action_type = GF_ODM_ACTION_DELETE; + } else { + scene->root_od->action_type = GF_ODM_ACTION_STOP; + } + if (gf_list_find(scene->root_od->term->media_queue, scene->root_od)<0) + gf_list_add(scene->root_od->term->media_queue, scene->root_od); + + gf_term_lock_net(scene->root_od->term, 0); + } + } + } + } + } + if (ODID) gf_inline_set_scene(pInline); +} + +static void gf_inline_check_restart(GF_Scene *scene) +{ + /*no ctrl if no duration*/ + if (!scene->duration) return; + if (!scene->needs_restart) gf_odm_check_segment_switch(scene->root_od); + if (scene->needs_restart) return; + + if (scene->root_od->media_ctrl && scene->root_od->media_ctrl->control->loop) { + GF_Clock *ck = gf_odm_get_media_clock(scene->root_od); + if (ck->has_seen_eos) { + u32 now = gf_clock_time(ck); + u64 dur = scene->duration; + if (scene->root_od->media_ctrl->current_seg) { + /*only process when all segments are played*/ + if (gf_list_count(scene->root_od->media_ctrl->seg) <= scene->root_od->media_ctrl->current_seg) { + scene->needs_restart = 1; + scene->root_od->media_ctrl->current_seg = 0; + } + } + else { + Double s, e; + s = now; s/=1000; + e = -1; + MC_GetRange(scene->root_od->media_ctrl, &s, &e); + if ((e>=0) && (e<GF_MAX_FLOAT)) dur = (u32) (e*1000); + if (dur<now) { + scene->needs_restart = 1; + scene->root_od->media_ctrl->current_seg = 0; + } + } + } else { + /*trigger render until to watch for restart...*/ + gf_term_invalidate_compositor(scene->root_od->term); + } + } +} + +static void gf_inline_traverse(GF_Node *n, void *rs, Bool is_destroy) +{ + MFURL *current_url; + GF_Scene *scene = (GF_Scene *)gf_node_get_private(n); + + if (is_destroy) { + GF_MediaObject *mo; + if (!scene) return; + mo = scene->root_od ? scene->root_od->mo : NULL; + + gf_scene_notify_event(scene, GF_EVENT_UNLOAD, n, NULL); + if (!mo) return; + gf_list_del_item(mo->nodes, n); + + /*disconnect current inline if we're the last one using it (same as regular OD session leave/join)*/ + if (mo->num_open) { + mo->num_open --; + if (!mo->num_open) { + /*this is unspecified in the spec: whenever an inline not using the + OD framework is destroyed, destroy the associated resource*/ + if (mo->OD_ID == GF_MEDIA_EXTERNAL_ID) { + gf_odm_disconnect(scene->root_od, 1); + + /*get parent scene and remove MediaObject in case the ressource + gets re-requested later on*/ + scene = (GF_Scene *)gf_sg_get_private(gf_node_get_graph((GF_Node *) n) ); + if (gf_list_del_item(scene->scene_objects, mo)>=0) { + gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL); + gf_list_del(mo->nodes); + gf_free(mo); + } + } else { + gf_odm_stop(scene->root_od, 1); + gf_scene_disconnect(scene, 1); + assert(gf_list_count(scene->resources) == 0); + } + } + } + return; + } + + + //if no private scene is associated get the node parent graph, retrieve the IS and find the OD + if (!scene) { + M_Inline *inl = (M_Inline *)n; + gf_inline_set_scene(inl); + scene = (GF_Scene *)gf_node_get_private(n); + if (!scene) { + /*just like protos, we must invalidate parent graph until attached*/ + if (inl->url.count) + gf_node_dirty_set(n, 0, 1); + return; + } + } + + gf_inline_check_restart(scene); + + /*if we need to restart, shutdown graph and do it*/ + if (scene->needs_restart) { + u32 current_seg = 0; + /*special case: scene change*/ + if (scene->needs_restart==2) { + scene->needs_restart = 0; + gf_inline_on_modified(n); + return; + } + + if (scene->root_od->media_ctrl) current_seg = scene->root_od->media_ctrl->current_seg; + scene->needs_restart = 0; + + gf_mx_p(scene->mx); + if (scene->is_dynamic_scene) { + u32 from = 0; + if (scene->root_od->media_ctrl) { + scene->root_od->media_ctrl->current_seg = current_seg; + from = (u32) (scene->root_od->media_ctrl->media_start * 1000); + } + gf_scene_restart_dynamic(scene, from); + } else { + /*we cannot use gf_mo_restart since it only sets the needs_restart for inline scenes. + The rational is that gf_mo_restart can be called from the parent scene (OK) or from the scene itself, in + which case shutting down the graph would crash the compositor. We therefore need two render passes to + safely restart an inline scene*/ + + /*1- stop main object from playing but don't disconnect channels*/ + gf_odm_stop(scene->root_od, 1); + /*2- close all ODs inside the scene and reset the graph*/ + gf_scene_disconnect(scene, 0); + if (scene->root_od->media_ctrl) scene->root_od->media_ctrl->current_seg = current_seg; + /*3- restart the scene*/ + gf_odm_start(scene->root_od, 0); + } + gf_mx_v(scene->mx); + + gf_node_dirty_set(n, 0, 1); + return; + } + + /*if not attached return (attaching the graph cannot be done in render since render is not called while unattached :) */ + if (!scene->graph_attached) { + /*just like protos, we must invalidate parent graph until attached*/ + gf_node_dirty_set(n, 0, 1); + return; + } + /*clear dirty flags for any sub-inlines, bitmaps or protos*/ + gf_node_dirty_clear(n, 0); + + current_url = scene->current_url; + scene->current_url = & ((M_Inline*)n)->url; + gf_sc_traverse_subscene(scene->root_od->term->compositor, n, scene->graph, rs); + scene->current_url = current_url; +} + + +static Bool gf_inline_is_hardcoded_proto(MFURL *url, GF_Config *cfg) +{ + 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; + } + return 0; +} + +GF_SceneGraph *gf_inline_get_proto_lib(void *_is, MFURL *lib_url) +{ + GF_ProtoLink *pl; + u32 i; + 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; + + i=0; + while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i))) { + if (!pl->mo) continue; + if (gf_mo_get_od_id(pl->url) != GF_MEDIA_EXTERNAL_ID) { + if (gf_mo_get_od_id(pl->url) == gf_mo_get_od_id(lib_url)) { + if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL; + return pl->mo->odm->subscene->graph; + } + } + } + + /*for string URL based protos, recursively check until top if the proto lib is not already present*/ + if (lib_url->vals[0].url) { + GF_Scene *check_scene = scene; + while (check_scene) { + i=0; + while ((pl = (GF_ProtoLink*)gf_list_enum(check_scene->extern_protos, &i))) { + char *url1, *url2; + Bool ok; + if (!pl->mo) continue; + if (gf_mo_get_od_id(pl->url) != GF_MEDIA_EXTERNAL_ID) continue; + /*not the same url*/ + if (!gf_mo_is_same_url(pl->mo, lib_url, NULL, 0)) continue; + /*check the url path is the same*/ + url1 = gf_url_concatenate(pl->mo->odm->net_service->url, lib_url->vals[0].url); + url2 = gf_url_concatenate(scene->root_od->net_service->url, lib_url->vals[0].url); + ok = 0; + if (url1 && url2 && !strcmp(url1, url2)) ok=1; + if (url1) gf_free(url1); + if (url2) gf_free(url2); + if (!ok) continue; + if (!pl->mo->odm || !pl->mo->odm->subscene) return NULL; + return pl->mo->odm->subscene->graph; + } + check_scene = check_scene->root_od->parentscene; + } + } + + /*not found, let's try to load it*/ + + 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; + + i=0; + while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i)) ) { + if (pl->url == lib_url) return NULL; + if (pl->url->vals[0].OD_ID && (pl->url->vals[0].OD_ID == lib_url->vals[0].OD_ID)) return NULL; + if (pl->url->vals[0].url && lib_url->vals[0].url && !stricmp(pl->url->vals[0].url, lib_url->vals[0].url) ) return NULL; + } + pl = (GF_ProtoLink*)gf_malloc(sizeof(GF_ProtoLink)); + pl->url = lib_url; + gf_list_add(scene->extern_protos, pl); + pl->mo = gf_scene_get_media_object(scene, lib_url, GF_MEDIA_OBJECT_SCENE, 0); + /*this may already be destroyed*/ + if (pl->mo) gf_mo_play(pl->mo, 0, -1, 0); + + /*and return NULL*/ + return NULL; +} + +Bool gf_inline_is_protolib_object(GF_Scene *scene, GF_ObjectManager *odm) +{ + u32 i; + GF_ProtoLink *pl; + i=0; + while ((pl = (GF_ProtoLink*)gf_list_enum(scene->extern_protos, &i))) { + if (pl->mo->odm == odm) return 1; + } + return 0; +} + +GF_EXPORT +Bool gf_inline_is_default_viewpoint(GF_Node *node) +{ + const char *nname, *seg_name; + GF_SceneGraph *sg = gf_node_get_graph(node); + GF_Scene *scene = sg ? (GF_Scene *) gf_sg_get_private(sg) : NULL; + if (!scene) return 0; + + nname = gf_node_get_name(node); + if (!nname) return 0; + + /*check any viewpoint*/ + seg_name = strrchr(scene->root_od->net_service->url, '#'); + + /*check the URL of the parent*/ + if (!seg_name && scene->current_url) { + if (scene->current_url->count && scene->current_url->vals[0].url) + seg_name = strrchr(scene->current_url->vals[0].url, '#'); + } else if (!seg_name && scene->root_od->mo && scene->root_od->mo->URLs.count && scene->root_od->mo->URLs.vals[0].url) { + seg_name = strrchr(scene->root_od->mo->URLs.vals[0].url, '#'); + } + if (!seg_name) return 0; + seg_name += 1; + /*look for a media segment with this name - if none found, this is a viewpoint name*/ + if (gf_odm_find_segment(scene->root_od, (char *) seg_name) != NULL) return 0; + + return (!strcmp(nname, seg_name)); +} + + +void gf_init_inline(GF_Scene *scene, GF_Node *node) +{ + gf_node_set_callback_function(node, gf_inline_traverse); +} + +static GF_Config *storage_get_cfg(M_Storage *storage) +{ + GF_Scene *scene; + scene = (GF_Scene *)gf_node_get_private((GF_Node*)storage); + return scene->root_od->term->user->config; +} + +static char *storage_get_section(M_Storage *storage) +{ + GF_Scene *scene; + char *szPath; + u8 hash[20], name[50]; + u32 i, len; + + scene = (GF_Scene *)gf_node_get_private((GF_Node*)storage); + + len = strlen(scene->root_od->net_service->url)+strlen(storage->name.buffer)+2; + szPath = gf_malloc(sizeof(char)* len); + strcpy(szPath, scene->root_od->net_service->url); + strcat(szPath, "@"); + strcat(szPath, storage->name.buffer); + gf_sha1_csum(szPath, strlen(szPath), hash); + gf_free(szPath); + + strcpy(name, "@cache="); + for (i=0; i<20; i++) { + char t[3]; + t[2] = 0; + sprintf(t, "%02X", hash[i]); + strcat(name, t); + } + return gf_strdup(name); +} + +static void storage_parse_sf(void *ptr, u32 fieldType, char *opt) +{ + Float v1, v2, v3; + switch (fieldType) { + case GF_SG_VRML_SFBOOL: + sscanf(opt, "%d", ((SFBool *)ptr)); + break; + case GF_SG_VRML_SFINT32: + sscanf(opt, "%d", ((SFInt32 *)ptr) ); + break; + case GF_SG_VRML_SFTIME: + sscanf(opt, "%lf", ((SFTime *)ptr) ); + break; + case GF_SG_VRML_SFFLOAT: + sscanf(opt, "%g", &v1); + * (SFFloat *)ptr = FLT2FIX(v1); + break; + case GF_SG_VRML_SFVEC2F: + sscanf(opt, "%g %g", &v1, &v2); + ((SFVec2f*)ptr)->x = FLT2FIX(v1); + ((SFVec2f*)ptr)->y = FLT2FIX(v2); + break; + case GF_SG_VRML_SFVEC3F: + sscanf(opt, "%g %g %g", &v1, &v2, &v3); + ((SFVec3f*)ptr)->x = FLT2FIX(v1); + ((SFVec3f*)ptr)->y = FLT2FIX(v2); + ((SFVec3f*)ptr)->z = FLT2FIX(v3); + break; + case GF_SG_VRML_SFSTRING: + if ( ((SFString *)ptr)->buffer) gf_free(((SFString *)ptr)->buffer); + ((SFString *)ptr)->buffer = gf_strdup(opt); + break; + default: + break; + } +} + +static void gf_storage_load(M_Storage *storage) +{ + const char *opt; + char szID[20]; + u32 i, count; + u32 sec, exp, frac; + GF_Config *cfg = storage_get_cfg(storage); + char *section = storage_get_section(storage); + if (!cfg || !section) return; + + if (!gf_cfg_get_key_count(cfg, section)) { + gf_free(section); + return; + } + opt = gf_cfg_get_key(cfg, section, "expireAfterNTP"); + gf_net_get_ntp(&sec, &frac); + sscanf(opt, "%u", &exp); + if (exp && (exp<=sec)) { + gf_cfg_del_section(cfg, section); + gf_free(section); + return; + } + + count = gf_cfg_get_key_count(cfg, section)-1; + if (!count || (count!=storage->storageList.count)) { + gf_cfg_del_section(cfg, section); + gf_free(section); + return; + } + + for (i=0; i<count; i++) { + GF_FieldInfo info; + sprintf(szID, "%d", i); + opt = gf_cfg_get_key(cfg, section, szID); + if (!opt) break; + if (!storage->storageList.vals[i].node) break; + if (gf_node_get_field(storage->storageList.vals[i].node, storage->storageList.vals[i].fieldIndex, &info) != GF_OK) break; + + if (gf_sg_vrml_is_sf_field(info.fieldType)) { + storage_parse_sf(info.far_ptr, info.fieldType, (char *) opt); + } else { + u32 sftype = gf_sg_vrml_get_sf_type(info.fieldType); + char *sep, *val; + void *slot; + gf_sg_vrml_mf_reset(info.far_ptr, info.fieldType); + while (1) { + val = strchr(opt, '\''); + sep = val ? strchr(val+1, '\'') : NULL; + if (!val || !sep) break; + + sep[0] = 0; + gf_sg_vrml_mf_append(info.far_ptr, info.fieldType, &slot); + storage_parse_sf(slot, sftype, val+1); + sep[0] = '\''; + opt = sep+1; + } + } + gf_node_changed(storage->storageList.vals[i].node, &info); + } + gf_free(section); +} + +char *storage_serialize_sf(void *ptr, u32 fieldType) +{ + char szVal[50]; + switch (fieldType) { + case GF_SG_VRML_SFBOOL: + sprintf(szVal, "%d", *((SFBool *)ptr) ? 1 : 0); + return gf_strdup(szVal); + case GF_SG_VRML_SFINT32: + sprintf(szVal, "%d", *((SFInt32 *)ptr) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFTIME: + sprintf(szVal, "%g", *((SFTime *)ptr) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFFLOAT: + sprintf(szVal, "%g", FIX2FLT( *((SFFloat *)ptr) ) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFVEC2F: + sprintf(szVal, "%g %g", FIX2FLT( ((SFVec2f *)ptr)->x), FIX2FLT( ((SFVec2f *)ptr)->y) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFVEC3F: + sprintf(szVal, "%g %g %g", FIX2FLT( ((SFVec3f *)ptr)->x), FIX2FLT( ((SFVec3f *)ptr)->y) , FIX2FLT( ((SFVec3f *)ptr)->z) ); + return gf_strdup(szVal); + case GF_SG_VRML_SFSTRING: + return gf_strdup( ((SFString *)ptr)->buffer ? ((SFString *)ptr)->buffer : ""); + + default: + break; + } + return NULL; +} + +void gf_storage_save(M_Storage *storage) +{ + char szID[20]; + u32 i; + GF_Config *cfg = storage_get_cfg(storage); + char *section = storage_get_section(storage); + if (!cfg || !section) return; + + gf_cfg_del_section(cfg, section); + + if (storage->expireAfter) { + u32 sec, frac; + char szNTP[100]; + gf_net_get_ntp(&sec, &frac); + sec += storage->expireAfter; + sprintf(szNTP, "%u", sec); + gf_cfg_set_key(cfg, section, "expireAfterNTP", szNTP); + } else { + gf_cfg_set_key(cfg, section, "expireAfterNTP", "0"); + } + + for (i=0; i<storage->storageList.count; i++) { + char *val; + GF_FieldInfo info; + sprintf(szID, "%d", i); + + if (!storage->storageList.vals[i].node) break; + if (gf_node_get_field(storage->storageList.vals[i].node, storage->storageList.vals[i].fieldIndex, &info) != GF_OK) break; + + if (gf_sg_vrml_is_sf_field(info.fieldType)) { + val = storage_serialize_sf(info.far_ptr, info.fieldType); + } else { + u32 sftype = gf_sg_vrml_get_sf_type(info.fieldType); + char *slotval; + void *slot; + val = NULL; + for (i=0; i<((GenMFField *)info.far_ptr)->count; i++) { + if (gf_sg_vrml_mf_get_item(info.far_ptr, info.fieldType, &slot, i) != GF_OK) break; + slotval = storage_serialize_sf(info.far_ptr, info.fieldType); + if (!slotval) break; + if (val) { + val = gf_realloc(val, strlen(val) + 3 + strlen(slot)); + } else { + val = gf_malloc(3 + strlen(slot)); + val[0] = 0; + } + strcat(val, "'"); + strcat(val, slotval); + strcat(val, "'"); + gf_free(slot); + } + } + if (val) { + gf_cfg_set_key(cfg, section, szID, val); + gf_free(val); + } + } + gf_free(section); +} + + +static void gf_storage_traverse(GF_Node *n, void *rs, Bool is_destroy) +{ + if (is_destroy) { + GF_Scene *scene = gf_node_get_private(n); + GF_ClientService *net_service = scene->root_od->net_service; + while (scene->root_od->parentscene) { + if (scene->root_od->parentscene->root_od->net_service != net_service) + break; + scene = scene->root_od->parentscene; + } + gf_list_del_item(scene->storages, n); + } +} + +static void on_force_restore(GF_Node *n, struct _route *_route) +{ + gf_storage_load((M_Storage *)n); +} +static void on_force_save(GF_Node *n, struct _route *_route) +{ + gf_storage_save((M_Storage *)n); +} + +void gf_scene_init_storage(GF_Scene *scene, GF_Node *node) +{ + GF_ClientService *net_service; + M_Storage *storage = (M_Storage *) node; + + if (!storage->name.buffer || !strlen(storage->name.buffer) ) return; + if (!storage->storageList.count) return; + + storage->on_forceSave = on_force_save; + storage->on_forceRestore = on_force_restore; + gf_node_set_callback_function(node, gf_storage_traverse); + gf_node_set_private(node, scene); + + net_service = scene->root_od->net_service; + while (scene->root_od->parentscene) { + if (scene->root_od->parentscene->root_od->net_service != net_service) + break; + scene = scene->root_od->parentscene; + } + gf_list_add(scene->storages, node); + if (storage->_auto) gf_storage_load(storage); +} + +#endif + +GF_Node *gf_scene_get_keynav(GF_SceneGraph *sg, GF_Node *sensor) +{ +#ifndef GPAC_DISABLE_VRML + u32 i, count; + GF_Scene *scene = gf_sg_get_private(sg); + if (!scene) return NULL; + if (!sensor) return gf_list_get(scene->keynavigators, 0); + + count = gf_list_count(scene->keynavigators); + for (i=0; i<count; i++) { + M_KeyNavigator *kn = gf_list_get(scene->keynavigators, i); + if (kn->sensor==sensor) return (GF_Node *) kn; + } +#endif + return NULL; +} + + diff --git a/src/terminal/network_service.c b/src/terminal/network_service.c index 18a3337..7be4183 100644 --- a/src/terminal/network_service.c +++ b/src/terminal/network_service.c @@ -24,6 +24,7 @@ #include <gpac/internal/terminal_dev.h> #include <gpac/network.h> +#include "media_memory.h" @@ -33,7 +34,6 @@ static GFINLINE GF_Channel *gf_term_get_channel(GF_ClientService *service, LPNET { GF_Channel *ch = (GF_Channel *)ns; if (!service || !ch) return NULL; - if (ch->chan_id != (u32) ch) return NULL; if (ch->service != service) return NULL; return ch; } @@ -51,9 +51,9 @@ static void term_on_message(void *user_priv, GF_ClientService *service, GF_Err e gf_term_message(term, service->url, szMsg, GF_OK); /*reload scene*/ - if (term->reload_url) free(term->reload_url); + if (term->reload_url) gf_free(term->reload_url); term->reload_state = 1; - term->reload_url = strdup(term->root_scene->root_od->net_service->url); + term->reload_url = gf_strdup(term->root_scene->root_od->net_service->url); gf_cfg_set_key(term->user->config, "Network", "UDPNotAvailable", "yes"); return; } @@ -67,11 +67,11 @@ static void term_on_connect(void *user_priv, GF_ClientService *service, LPNETCHA GF_ObjectManager *root; GET_TERM(); - GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Connection ACK received from %s (channel %d) - %s\n", service->url, (u32) netch, gf_error_to_string(err) )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] %s connection ACK received from %s - %s\n", netch ? "Channel" : "Service", service->url, gf_error_to_string(err) )); root = service->owner; if (root && (root->net_service != service)) { - gf_term_message(term, service->url, "Incomaptible module type", GF_SERVICE_ERROR); + gf_term_message(term, service->url, "Incompatible module type", GF_SERVICE_ERROR); return; } /*this is service connection*/ @@ -100,13 +100,13 @@ static void term_on_connect(void *user_priv, GF_ClientService *service, LPNETCHA GF_Event evt; evt.type = GF_EVENT_CONNECT; evt.connect.is_connected = 0; - GF_USER_SENDEVENT(term->user, &evt); + gf_term_send_event(term, &evt); } else { /*try to reinsert OD for VRML/X3D with multiple URLs: 1- first remove from parent scene without destroying object, this will trigger a re-setup if other URLs are present 2- then destroy object*/ - gf_inline_remove_object(root->parentscene, root, 0); + gf_scene_remove_object(root->parentscene, root, 0); gf_odm_disconnect(root, 1); } return; @@ -128,7 +128,7 @@ static void term_on_connect(void *user_priv, GF_ClientService *service, LPNETCHA if (gf_odm_post_es_setup(cs->ch, cs->dec, err) == GF_OK) { if (cs->ch->odm && (gf_list_find(ODs, cs->ch->odm)==-1) ) gf_list_add(ODs, cs->ch->odm); } - free(cs); + gf_free(cs); } gf_term_lock_net(term, 0); /*finally setup all ODs concerned (we do this later in case of scalability)*/ @@ -136,7 +136,7 @@ static void term_on_connect(void *user_priv, GF_ClientService *service, LPNETCHA GF_ObjectManager *odm = (GF_ObjectManager*)gf_list_get(ODs, 0); gf_list_rem(ODs, 0); /*force re-setup*/ - gf_inline_setup_object(odm->parentscene, odm); + gf_scene_setup_object(odm->parentscene, odm); } gf_list_del(ODs); } else { @@ -155,14 +155,15 @@ static void term_on_connect(void *user_priv, GF_ClientService *service, LPNETCHA ch = gf_term_get_channel(service, netch); if (!ch) return; - /*confirm channel connection even if error - this allow playback of objects even if not all streams are setup - */ + /*confirm channel connection even if error - this allow playback of objects even if not all streams are setup*/ gf_term_lock_net(term, 1); gf_es_on_connect(ch); gf_term_lock_net(term, 0); - if (err) { - gf_term_message(term, service->url, "Channel Connection Failed", err); + if (err && ((err!=GF_STREAM_NOT_FOUND) || (ch->esd->decoderConfig->streamType!=GF_STREAM_INTERACT))) { + char szMsg[1024]; + sprintf(szMsg, "Channel %d connection failure", ch->esd->ESID); + gf_term_message(term, service->url, szMsg, err); ch->es_state = GF_ESM_ES_UNAVAILABLE; // return; } @@ -174,7 +175,7 @@ static void term_on_connect(void *user_priv, GF_ClientService *service, LPNETCHA if ( (ch->odm->mo && ch->odm->mo->num_open) || !ch->odm->parentscene ) { - gf_odm_start(ch->odm); + gf_odm_start(ch->odm, 0); } #if 0 else if (ch->odm->codec && ch->odm->codec->ck && ch->odm->codec->ck->no_time_ctrl) { @@ -248,17 +249,17 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des { u32 i; GF_MediaObject *the_mo; - GF_InlineScene *is; + GF_Scene *scene; GF_ObjectManager *odm, *root; GF_ObjectDescriptor *od; GET_TERM(); root = service->owner; - is = root->subscene ? root->subscene : root->parentscene; + scene = root->subscene ? root->subscene : root->parentscene; GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[Service %s] %s\n", service->url, media_desc ? "Adding new media object" : "Regenerating scene graph")); if (!media_desc) { - if (!no_scene_check) gf_inline_regenerate(is); + if (!no_scene_check) gf_scene_regenerate(scene); return; } @@ -276,15 +277,15 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des gf_term_lock_net(term, 1); /*object declared this way are not part of an OD stream and are considered as dynamic*/ -// od->objectDescriptorID = GF_ESM_DYNAMIC_OD_ID; +// od->objectDescriptorID = GF_MEDIA_EXTERNAL_ID; /*check if we have a mediaObject in the scene not attached and matching this object*/ the_mo = NULL; odm = NULL; - for (i=0; i<gf_list_count(is->media_objects); i++) { + for (i=0; i<gf_list_count(scene->scene_objects); i++) { char *frag, *ext; GF_ESD *esd; - GF_MediaObject *mo = gf_list_get(is->media_objects, i); + GF_MediaObject *mo = gf_list_get(scene->scene_objects, i); if (!mo->odm) continue; /*already assigned object - this may happen since the compositor has no control on when objects are declared by the service, therefore opening file#video and file#audio may result in the objects being declared twice if the service doesn't @@ -299,7 +300,7 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des } continue; } - if (mo->OD_ID != GF_ESM_DYNAMIC_OD_ID) { + if (mo->OD_ID != GF_MEDIA_EXTERNAL_ID) { if (mo->OD_ID == od->objectDescriptorID) { the_mo = mo; odm = mo->odm; @@ -336,7 +337,7 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des if (frag) { u32 frag_id = 0; u32 ID = od->objectDescriptorID; - if (ID==GF_ESM_DYNAMIC_OD_ID) ID = esd->ESID; + if (ID==GF_MEDIA_EXTERNAL_ID) ID = esd->ESID; frag++; frag_id = atoi(frag); if (ID!=frag_id) continue; @@ -349,8 +350,8 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des if (!odm) { odm = gf_odm_new(); odm->term = term; - odm->parentscene = is; - gf_list_add(is->ODlist, odm); + odm->parentscene = scene; + gf_list_add(scene->resources, odm); } odm->OD = od; odm->mo = the_mo; @@ -361,7 +362,7 @@ static void term_on_media_add(void *user_priv, GF_ClientService *service, GF_Des gf_odm_setup_object(odm, service); /*OD inserted by service: resetup scene*/ - if (!no_scene_check && is->is_dynamic_scene) gf_inline_regenerate(is); + if (!no_scene_check && scene->is_dynamic_scene) gf_scene_regenerate(scene); } static void term_on_command(void *user_priv, GF_ClientService *service, GF_NetworkCommand *com, GF_Err response) @@ -383,9 +384,9 @@ static void term_on_command(void *user_priv, GF_ClientService *service, GF_Netwo /*browse all channels in the scene, running on this service, and get buffer info*/ od_list = NULL; if (service->owner->parentscene) { - od_list = service->owner->parentscene->ODlist; + od_list = service->owner->parentscene->resources; } else if (service->owner->subscene) { - od_list = service->owner->subscene->ODlist; + od_list = service->owner->subscene->resources; } if (!od_list) { com->buffer.occupancy = 0; @@ -397,6 +398,7 @@ static void term_on_command(void *user_priv, GF_ClientService *service, GF_Netwo i=0; while ((odm = (GF_ObjectManager*)gf_list_enum(od_list, &i))) { u32 j, count; + if (!odm->codec) continue; count = gf_list_count(odm->channels); for (j=0; j<count; j++) { GF_Channel *ch = (GF_Channel *)gf_list_get(odm->channels, j); @@ -405,8 +407,13 @@ static void term_on_command(void *user_priv, GF_ClientService *service, GF_Netwo if (!ch->MaxBuffer || ch->dispatch_after_db || ch->bypass_sl_and_db || ch->IsEndOfStream) continue; if (ch->MaxBuffer>com->buffer.max) com->buffer.max = ch->MaxBuffer; if (ch->MinBuffer<com->buffer.min) com->buffer.min = ch->MinBuffer; - if ((ch->AU_Count > 2) && ((u32) ch->BufferTime<com->buffer.occupancy)) - com->buffer.occupancy = ch->BufferTime; + if (ch->IsClockInit && (u32) ch->BufferTime < com->buffer.occupancy) { + if ((ch->AU_Count<=2) || (odm->codec->CB->UnitCount <= odm->codec->CB->Min)) { + com->buffer.occupancy = 0; + } else { + com->buffer.occupancy = ch->BufferTime; + } + } } } gf_mx_v(term->mm_mx); @@ -416,7 +423,7 @@ static void term_on_command(void *user_priv, GF_ClientService *service, GF_Netwo if (com->command_type==GF_NET_SERVICE_INFO) { GF_Event evt; evt.type = GF_EVENT_METADATA; - GF_USER_SENDEVENT(term->user, &evt); + gf_term_send_event(term, &evt); return; } @@ -431,21 +438,14 @@ static void term_on_command(void *user_priv, GF_ClientService *service, GF_Netwo /*SL reconfiguration*/ case GF_NET_CHAN_RECONFIG: gf_term_lock_net(term, 1); - gf_es_reconfig_sl(ch, &com->cfg.sl_config); + gf_es_reconfig_sl(ch, &com->cfg.sl_config, com->cfg.use_m2ts_sections); gf_term_lock_net(term, 0); return; /*time mapping (TS to media-time)*/ case GF_NET_CHAN_MAP_TIME: ch->seed_ts = com->map_time.timestamp; ch->ts_offset = (u32) (com->map_time.media_time*1000); - /* - if (gf_es_owns_clock(ch)) { - ch->ts_offset = (u32) (com->map_time.media_time*1000); - } else { - ch->ts_offset = gf_clock_time(ch->clock); - } - */ - gf_es_map_time(ch, com->map_time.reset_buffers); + if (com->map_time.reset_buffers) gf_es_reset_buffers(ch); break; /*duration changed*/ case GF_NET_CHAN_DURATION: @@ -515,7 +515,7 @@ static char *get_mime_type(GF_Terminal *term, const char *url, GF_Err *ret_code) return NULL; } mime_type = (char *) gf_dm_sess_mime_type(sess); - if (mime_type) mime_type = strdup(mime_type); + if (mime_type) mime_type = gf_strdup(mime_type); else *ret_code = gf_dm_sess_last_error(sess); gf_dm_sess_del(sess); return mime_type; @@ -548,8 +548,8 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char { u32 i; GF_Err e; - char *sURL, *ext, *mime_type; - char szExt[500]; + char *sURL, *qm, *frag, *ext, *mime_type, *url_res; + char szExt[50]; GF_InputService *ifce; GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Looking for plugin for URL %s\n", url)); @@ -563,7 +563,7 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char if (parent_url) sURL = gf_url_concatenate(parent_url, url); /*path absolute*/ - if (!sURL) sURL = strdup(url); + if (!sURL) sURL = gf_strdup(url); if (gf_url_is_local(sURL)) gf_url_to_fs_path(sURL); @@ -577,7 +577,7 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char */ mime_type = get_mime_type(term, sURL, &e); if (e) { - free(sURL); + gf_free(sURL); (*ret_code) = e; return NULL; } @@ -589,7 +589,7 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char || !stricmp(mime_type, "application/octet-stream") ) ) { - free(mime_type); + gf_free(mime_type); mime_type = NULL; } @@ -599,6 +599,10 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char if (mime_type) { const char *sPlug = gf_cfg_get_key(term->user->config, "MimeTypes", mime_type); GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Mime type found: %s\n", mime_type)); + if (!sPlug) { + gf_free(mime_type); + mime_type=NULL; + } if (sPlug) sPlug = strrchr(sPlug, '"'); if (sPlug) { sPlug += 2; @@ -610,16 +614,24 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char } } - - ext = strchr(sURL, '#'); - if (ext) { - char *anext; - ext[0] = 0; - anext = strrchr(sURL, '.'); - ext[0] = '#'; - ext = anext; + /* The file extension, if any, is before '?' if any or before '#' if any.*/ + url_res = strrchr(sURL, '/'); + if (!url_res) url_res = strrchr(sURL, '\\'); + if (!url_res) url_res = sURL; + qm = strchr(url_res, '?'); + if (qm) { + qm[0] = 0; + ext = strrchr(url_res, '.'); + qm[0] = '?'; } else { - ext = strrchr(sURL, '.'); + frag = strchr(url_res, '#'); + if (frag) { + frag[0] = 0; + ext = strrchr(url_res, '.'); + frag[0] = '#'; + } else { + ext = strrchr(url_res, '.'); + } } if (ext && !stricmp(ext, ".gz")) { char *anext; @@ -631,12 +643,17 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char /*no mime type: either local or streaming. If streaming discard extension checking*/ if (!ifce && !mime_type && strstr(sURL, "://") && strnicmp(sURL, "file://", 7)) ext = NULL; - if (mime_type) free(mime_type); + if (mime_type) { + gf_free(mime_type); + if (!ifce) return NULL; + } /*browse extensions for prefered module*/ if (!ifce && ext) { u32 keyCount; - strcpy(szExt, &ext[1]); + strncpy(szExt, &ext[1], 49); + ext = strrchr(szExt, '?'); + if (ext) ext[0] = 0; ext = strrchr(szExt, '#'); if (ext) ext[0] = 0; @@ -678,7 +695,7 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char } if (!ifce) { - free(sURL); + gf_free(sURL); (*ret_code) = GF_NOT_SUPPORTED; return NULL; } @@ -687,11 +704,11 @@ static GF_InputService *gf_term_can_handle_service(GF_Terminal *term, const char return ifce; } -GF_ClientService *gf_term_service_new(GF_Terminal *term, struct _od_manager *owner, const char *url, GF_ClientService *parent_service, GF_Err *ret_code) +GF_ClientService *gf_term_service_new(GF_Terminal *term, struct _od_manager *owner, const char *url, const char *parent_url, GF_Err *ret_code) { char *sURL; GF_ClientService *serv; - GF_InputService *ifce = gf_term_can_handle_service(term, url, parent_service ? parent_service->url : NULL, 0, &sURL, ret_code); + GF_InputService *ifce = gf_term_can_handle_service(term, url, parent_url, 0, &sURL, ret_code); if (!ifce) return NULL; GF_SAFEALLOC(serv, GF_ClientService); @@ -717,7 +734,7 @@ Bool gf_term_is_supported_url(GF_Terminal *term, const char *fileName, Bool use_ ifce = gf_term_can_handle_service(term, fileName, parent_url, no_mime_check, &sURL, &e); if (!ifce) return 0; gf_modules_close_interface((GF_BaseInterface *) ifce); - free(sURL); + gf_free(sURL); return 1; } @@ -793,7 +810,7 @@ void NM_DeleteService(GF_ClientService *ns) const char *sOpt = gf_cfg_get_key(ns->term->user->config, "StreamingCache", "AutoSave"); if (ns->cache) gf_term_service_cache_close(ns, (sOpt && !stricmp(sOpt, "yes")) ? 1 : 0); gf_modules_close_interface((GF_BaseInterface *)ns->ifce); - free(ns->url); + gf_free(ns->url); assert(!ns->nb_odm_users); assert(!ns->nb_ch_users); @@ -809,7 +826,7 @@ void NM_DeleteService(GF_ClientService *ns) assert(!gf_list_count(ns->dnloads)); gf_list_del(ns->dnloads); - free(ns); + gf_free(ns); } GF_EXPORT @@ -824,13 +841,13 @@ GF_DownloadSession *gf_term_download_new(GF_ClientService *service, const char * GF_Err e; GF_DownloadSession * sess; char *sURL; - if (!service || !user_io) return NULL; + if (!service) return NULL; sURL = gf_url_concatenate(service->url, url); /*path was absolute*/ - if (!sURL) sURL = strdup(url); + if (!sURL) sURL = gf_strdup(url); sess = gf_dm_sess_new(service->term->downloader, sURL, flags, user_io, cbk, &e); - free(sURL); + gf_free(sURL); if (!sess) return NULL; gf_dm_sess_set_private(sess, service); gf_list_add(service->dnloads, sess); @@ -884,7 +901,7 @@ void gf_term_download_update_stats(GF_DownloadSession * sess) evt.progress.service = szURI; evt.progress.total = total_size; evt.progress.done = bytes_done; - GF_USER_SENDEVENT(serv->term->user, &evt); + gf_term_send_event(serv->term, &evt); } GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] %s received %d / %d\n", szURI, bytes_done, total_size)); break; @@ -909,7 +926,7 @@ void gf_term_register_mime_type(GF_InputService *ifce, const char *mimeType, con if (!ifce || !mimeType || !extList || !description) return; len = strlen(extList) + 3 + strlen(description) + 3 + strlen(ifce->module_name) + 1; - buf = (char*)malloc(sizeof(char)*len); + buf = (char*)gf_malloc(sizeof(char)*len); sprintf(buf, "\"%s\" ", extList); strlwr(buf); strcat(buf, "\""); @@ -917,7 +934,7 @@ void gf_term_register_mime_type(GF_InputService *ifce, const char *mimeType, con strcat(buf, "\" "); strcat(buf, ifce->module_name); gf_modules_set_option((GF_BaseInterface *)(GF_BaseInterface *)ifce, "MimeTypes", mimeType, buf); - free(buf); + gf_free(buf); } GF_EXPORT diff --git a/src/terminal/object_browser.c b/src/terminal/object_browser.c index 0791388..346ac01 100644 --- a/src/terminal/object_browser.c +++ b/src/terminal/object_browser.c @@ -35,7 +35,7 @@ #include <gpac/nodes_svg.h> -static Bool check_in_scene(GF_InlineScene *scene, GF_ObjectManager *odm) +static Bool check_in_scene(GF_Scene *scene, GF_ObjectManager *odm) { u32 i; GF_ObjectManager *ptr, *root; @@ -45,7 +45,7 @@ static Bool check_in_scene(GF_InlineScene *scene, GF_ObjectManager *odm) scene = root->subscene; i=0; - while ((ptr = (GF_ObjectManager *)gf_list_enum(scene->ODlist, &i))) { + while ((ptr = (GF_ObjectManager *)gf_list_enum(scene->resources, &i))) { if (ptr == odm) return 1; if (check_in_scene(ptr->subscene, odm)) return 1; } @@ -73,7 +73,7 @@ u32 gf_term_get_object_count(GF_Terminal *term, GF_ObjectManager *scene_od) if (!term || !scene_od) return 0; if (!gf_term_check_odm(term, scene_od)) return 0; if (!scene_od->subscene) return 0; - return gf_list_count(scene_od->subscene->ODlist); + return gf_list_count(scene_od->subscene->resources); } /*returns indexed (0-based) OD manager in the scene*/ @@ -82,18 +82,18 @@ GF_ObjectManager *gf_term_get_object(GF_Terminal *term, GF_ObjectManager *scene_ if (!term || !scene_od) return NULL; if (!gf_term_check_odm(term, scene_od)) return NULL; if (!scene_od->subscene) return NULL; - return (GF_ObjectManager *) gf_list_get(scene_od->subscene->ODlist, index); + return (GF_ObjectManager *) gf_list_get(scene_od->subscene->resources, index); } u32 gf_term_object_subscene_type(GF_Terminal *term, GF_ObjectManager *odm) { - Bool IS_IsProtoLibObject(GF_InlineScene *is, GF_ObjectManager *odm); - if (!term || !odm) return 0; if (!gf_term_check_odm(term, odm)) return 0; if (!odm->subscene) return 0; - if (odm->parentscene) return IS_IsProtoLibObject(odm->parentscene, odm) ? 3 : 2; +#ifndef GPAC_DISABLE_VRML + if (odm->parentscene) return gf_inline_is_protolib_object(odm->parentscene, odm) ? 3 : 2; +#endif return 1; } @@ -103,12 +103,12 @@ void gf_term_select_object(GF_Terminal *term, GF_ObjectManager *odm) if (!term || !odm) return; if (!gf_term_check_odm(term, odm)) return; - gf_inline_select_object(term->root_scene, odm); + gf_scene_select_object(term->root_scene, odm); } -static void get_codec_stats(GF_Codec *dec, ODInfo *info) +static void get_codec_stats(GF_Codec *dec, GF_MediaInfo *info) { info->avg_bitrate = dec->avg_bit_rate; info->max_bitrate = dec->max_bit_rate; @@ -117,14 +117,14 @@ static void get_codec_stats(GF_Codec *dec, ODInfo *info) info->total_dec_time = dec->total_dec_time; } -GF_Err gf_term_get_object_info(GF_Terminal *term, GF_ObjectManager *odm, ODInfo *info) +GF_Err gf_term_get_object_info(GF_Terminal *term, GF_ObjectManager *odm, GF_MediaInfo *info) { GF_Channel *ch; if (!term || !odm || !odm->OD || !info) return GF_BAD_PARAM; if (!gf_term_check_odm(term, odm)) return GF_BAD_PARAM; - memset(info, 0, sizeof(ODInfo)); + memset(info, 0, sizeof(GF_MediaInfo)); info->od = odm->OD; info->duration = (Double) (s64)odm->duration; @@ -241,6 +241,9 @@ GF_Err gf_term_get_object_info(GF_Terminal *term, GF_ObjectManager *odm, ODInfo ch = (GF_Channel*)gf_list_get(odm->channels, 0); if (ch && ch->esd->langDesc) info->lang = ch->esd->langDesc->langCode; + + if (odm->mo && odm->mo->URLs.count) + info->media_url = odm->mo->URLs.vals[0].url; return GF_OK; } @@ -297,7 +300,6 @@ GF_Err gf_term_get_service_info(GF_Terminal *term, GF_ObjectManager *odm, NetInf const char *gf_term_get_world_info(GF_Terminal *term, GF_ObjectManager *scene_od, GF_List *descriptions) { GF_Node *info; - u32 i; if (!term) return NULL; info = NULL; if (!scene_od) { @@ -314,20 +316,24 @@ const char *gf_term_get_world_info(GF_Terminal *term, GF_ObjectManager *scene_od //return ((SVG_titleElement *) info)->textContent; return "TO FIX IN GPAC!!"; } else { +#ifndef GPAC_DISABLE_VRML M_WorldInfo *wi = (M_WorldInfo *) info; if (descriptions) { + u32 i; for (i=0; i<wi->info.count; i++) { gf_list_add(descriptions, wi->info.vals[i]); } } return wi->title.buffer; +#endif } + return "GPAC"; } -GF_Err gf_term_dump_scene(GF_Terminal *term, char *rad_name, Bool xml_dump, Bool skip_protos, GF_ObjectManager *scene_od) +GF_Err gf_term_dump_scene(GF_Terminal *term, char *rad_name, char **filename, Bool xml_dump, Bool skip_protos, GF_ObjectManager *scene_od) { -#ifndef GPAC_READ_ONLY +#ifndef GPAC_DISABLE_SCENE_DUMP GF_SceneGraph *sg; GF_ObjectManager *odm; GF_SceneDumper *dumper; @@ -365,8 +371,10 @@ GF_Err gf_term_dump_scene(GF_Terminal *term, char *rad_name, Bool xml_dump, Bool } dumper = gf_sm_dumper_new(sg, rad_name, ' ', mode); + if (!dumper) return GF_IO_ERR; e = gf_sm_dump_graph(dumper, skip_protos, 0); + if (filename) *filename = gf_strdup(gf_sm_dump_get_name(dumper)); gf_sm_dumper_del(dumper); return e; #else diff --git a/src/terminal/object_manager.c b/src/terminal/object_manager.c index 60e99b0..12efbc3 100644 --- a/src/terminal/object_manager.c +++ b/src/terminal/object_manager.c @@ -46,17 +46,22 @@ GF_ObjectManager *gf_odm_new() tmp->OD_PL = (u8) -1; tmp->Scene_PL = (u8) -1; tmp->Visual_PL = (u8) -1; + tmp->mx = gf_mx_new("ODM"); +#ifndef GPAC_DISABLE_VRML tmp->ms_stack = gf_list_new(); tmp->mc_stack = gf_list_new(); - tmp->mx = gf_mx_new("ODM"); +#endif return tmp; } void gf_odm_del(GF_ObjectManager *odm) { Bool lock; +#ifndef GPAC_DISABLE_VRML u32 i; MediaSensorStack *media_sens; + MediaControlStack *media_ctrl; +#endif /*make sure we are not in the media queue*/ gf_mx_p(odm->term->net_mx); @@ -64,23 +69,32 @@ void gf_odm_del(GF_ObjectManager *odm) gf_mx_v(odm->term->net_mx); lock = gf_mx_try_lock(odm->mx); + +#ifndef GPAC_DISABLE_VRML i=0; while ((media_sens = (MediaSensorStack *)gf_list_enum(odm->ms_stack, &i))) { MS_Stop(media_sens); /*and detach from stream object*/ media_sens->is_init = 0; } + gf_list_del(odm->ms_stack); + + i=0; + while ((media_ctrl = (MediaControlStack *)gf_list_enum(odm->mc_stack, &i))) { + media_ctrl->stream = NULL; + media_ctrl->ck = NULL; + } + gf_list_del(odm->mc_stack); +#endif if (odm->mo) odm->mo->odm = NULL; gf_list_del(odm->channels); - gf_list_del(odm->ms_stack); - gf_list_del(odm->mc_stack); gf_odf_desc_del((GF_Descriptor *)odm->OD); assert (!odm->net_service); if (lock) gf_mx_v(odm->mx); gf_mx_del(odm->mx); - free(odm); + gf_free(odm); } @@ -110,7 +124,7 @@ void gf_odm_disconnect(GF_ObjectManager *odm, Bool do_remove) gf_odm_stop(odm, 1); /*disconnect sub-scene*/ - if (odm->subscene) gf_inline_disconnect(odm->subscene, do_remove); + if (odm->subscene) gf_scene_disconnect(odm->subscene, do_remove); /*no destroy*/ if (!do_remove) return; @@ -120,7 +134,9 @@ void gf_odm_disconnect(GF_ObjectManager *odm, Bool do_remove) /*unload the decoders before deleting the channels to prevent any access fault*/ if (odm->codec) gf_term_remove_codec(odm->term, odm->codec); if (odm->ocr_codec) gf_term_remove_codec(odm->term, odm->ocr_codec); +#ifndef GPAC_MINIMAL_ODF if (odm->oci_codec) gf_term_remove_codec(odm->term, odm->oci_codec); +#endif /*then delete all the channels in this OD */ while (gf_list_count(odm->channels)) { @@ -143,27 +159,31 @@ void gf_odm_disconnect(GF_ObjectManager *odm, Bool do_remove) gf_codec_del(odm->ocr_codec); odm->ocr_codec = NULL; } +#ifndef GPAC_MINIMAL_ODF if (odm->oci_codec) { gf_codec_del(odm->oci_codec); odm->oci_codec = NULL; } +#endif /*detach from network service */ if (odm->net_service) { GF_ClientService *ns = odm->net_service; - if (ns->owner == odm) { + if (odm->flags & GF_ODM_SERVICE_ENTRY) { if (ns->nb_odm_users) ns->nb_odm_users--; - /*detach it!!*/ - ns->owner = NULL; - /*try to assign a new root in case this is not scene shutdown*/ - if (ns->nb_odm_users && odm->parentscene) { - GF_ObjectManager *new_root; - u32 i = 0; - while ((new_root = (GF_ObjectManager *)gf_list_enum(odm->parentscene->ODlist, &i)) ) { - if (new_root == odm) continue; - if (new_root->net_service != ns) continue; - ns->owner = new_root; - break; + if (ns->owner == odm) { + /*detach it!!*/ + ns->owner = NULL; + /*try to assign a new root in case this is not scene shutdown*/ + if (ns->nb_odm_users && odm->parentscene) { + GF_ObjectManager *new_root; + u32 i = 0; + while ((new_root = (GF_ObjectManager *)gf_list_enum(odm->parentscene->resources, &i)) ) { + if (new_root == odm) continue; + if (new_root->net_service != ns) continue; + ns->owner = new_root; + break; + } } } } @@ -175,8 +195,8 @@ void gf_odm_disconnect(GF_ObjectManager *odm, Bool do_remove) /*delete from the parent scene.*/ if (odm->parentscene) { - gf_inline_remove_object(odm->parentscene, odm, do_remove); - if (odm->subscene) gf_inline_del(odm->subscene); + gf_scene_remove_object(odm->parentscene, odm, do_remove); + if (odm->subscene) gf_scene_del(odm->subscene); gf_odm_del(odm); return; } @@ -185,13 +205,13 @@ void gf_odm_disconnect(GF_ObjectManager *odm, Bool do_remove) if (odm->term->root_scene) { GF_Event evt; assert(odm->term->root_scene == odm->subscene); - gf_inline_del(odm->subscene); + gf_scene_del(odm->subscene); /*reset main pointer*/ odm->term->root_scene = NULL; evt.type = GF_EVENT_CONNECT; evt.connect.is_connected = 0; - GF_USER_SENDEVENT(odm->term->user, &evt); + gf_term_send_event(odm->term, &evt); } /*delete the ODMan*/ @@ -206,7 +226,6 @@ void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url char *sub_url = (char *) service_sub_url; GF_Terminal *term; GF_Descriptor *desc; - GF_IPMP_ToolList *toolList; // assert(odm->OD==NULL); @@ -226,7 +245,7 @@ void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url /*for remote ODs, get expected OD type in case the service needs to generate the IOD on the fly*/ if (odm->parentscene && odm->OD && odm->OD->URLString) { GF_MediaObject *mo; - mo = gf_inline_find_object(odm->parentscene, odm->OD->objectDescriptorID, odm->OD->URLString); + mo = gf_scene_find_object(odm->parentscene, odm->OD->objectDescriptorID, odm->OD->URLString); if (mo) od_type = mo->type; ext = strchr(odm->OD->URLString, '#'); if (ext) sub_url = ext; @@ -243,22 +262,22 @@ void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url desc = gf_odf_desc_new(GF_ODF_OD_TAG); } odm->net_service->nb_odm_users++; + odm->flags |= GF_ODM_SERVICE_ENTRY; if (!gf_list_count( ((GF_ObjectDescriptor*)desc)->ESDescriptors)) { /*new subscene*/ if (!odm->subscene) { assert(odm->parentscene); - odm->subscene = gf_inline_new(odm->parentscene); + odm->subscene = gf_scene_new(odm->parentscene); odm->subscene->root_od = odm; } } - toolList = NULL; switch (desc->tag) { case GF_ODF_IOD_TAG: { GF_InitialObjectDescriptor *the_iod = (GF_InitialObjectDescriptor *)desc; - odm->OD = (GF_ObjectDescriptor*)malloc(sizeof(GF_ObjectDescriptor)); + odm->OD = (GF_ObjectDescriptor*)gf_malloc(sizeof(GF_ObjectDescriptor)); memcpy(odm->OD, the_iod, sizeof(GF_ObjectDescriptor)); odm->OD->tag = GF_ODF_OD_TAG; /*Check P&Ls of this IOD*/ @@ -269,8 +288,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; - toolList = the_iod->IPMPToolList; - free(the_iod); + gf_odf_desc_del((GF_Descriptor *) the_iod->IPMPToolList); + gf_free(the_iod); } break; case GF_ODF_OD_TAG: @@ -282,25 +301,6 @@ void gf_odm_setup_entry_point(GF_ObjectManager *odm, const char *service_sub_url goto err_exit; } - if (toolList) { - Bool ipmp_failed = 0; -/* - GF_IPMP_Tool *ipmpt; - i=0; - while ((ipmpt = gf_list_enum(toolList->ipmp_tools, &i))) { - if (!Term_CheckIPMPTool(odm->term, ipmpt)) { - ipmp_failed = 1; - break; - } - } -*/ - gf_odf_desc_del((GF_Descriptor *)toolList); - if (ipmp_failed) { - gf_term_message(odm->term, odm->net_service->url, "MPEG4 IPMP Setup Failure - cannot process content", GF_SERVICE_ERROR); - goto err_exit; - } - } - gf_term_lock_net(term, 1); gf_odm_setup_object(odm, odm->net_service); gf_term_lock_net(term, 0); @@ -312,7 +312,7 @@ err_exit: GF_Event evt; evt.type = GF_EVENT_CONNECT; evt.connect.is_connected = 0; - GF_USER_SENDEVENT(odm->term->user, &evt); + gf_term_send_event(odm->term, &evt); } } @@ -397,6 +397,7 @@ GF_Err ODM_ValidateOD(GF_ObjectManager *odm, Bool *hasInline) /*step 1: validate OD*/ i=0; while ((esd = (GF_ESD *)gf_list_enum(odm->OD->ESDescriptors, &i))) { + assert(esd->decoderConfig); switch (esd->decoderConfig->streamType) { case GF_STREAM_OD: nb_od++; break; case GF_STREAM_OCR: nb_ocr++; break; @@ -427,8 +428,10 @@ GF_Err ODM_ValidateOD(GF_ObjectManager *odm, Bool *hasInline) /*select independant streams - check language and (TODO) bitrate & term caps*/ sOpt = gf_cfg_get_key(odm->term->user->config, "Systems", "Language3CC"); if (!sOpt) { - gf_cfg_set_key(odm->term->user->config, "Systems", "Language3CC", "und"); - sOpt = "und"; + sOpt = "eng"; + gf_cfg_set_key(odm->term->user->config, "Systems", "Language3CC", sOpt); + gf_cfg_set_key(odm->term->user->config, "Systems", "Language2CC", "en"); + gf_cfg_set_key(odm->term->user->config, "Systems", "LanguageName", "English"); } lang = (sOpt[0]<<16) | (sOpt[1]<<8) | sOpt[2]; #if 0 @@ -486,7 +489,7 @@ GF_Err ODM_ValidateOD(GF_ObjectManager *odm, Bool *hasInline) /*connection of OD and setup of streams. The streams are not requested if the OD is in an unexecuted state the ODM is created either because of IOD / remoteOD, or by the OD codec. In the later -case, the GF_InlineScene pointer will be set by the OD codec.*/ +case, the GF_Scene pointer will be set by the OD codec.*/ GF_EXPORT void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) { @@ -516,11 +519,11 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) propagation (stored at the inline level) */ if (odm->mo && (odm->mo->type==GF_MEDIA_OBJECT_SCENE)) { - odm->subscene = gf_inline_new(odm->parentscene); + odm->subscene = gf_scene_new(odm->parentscene); odm->subscene->root_od = odm; } - gf_term_connect_object(odm->term, odm, url, parent); - free(url); + gf_term_connect_object(odm->term, odm, url, parent ? parent->url : NULL); + gf_free(url); return; } /*restore OD ID */ @@ -545,10 +548,10 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) hasInline = 0; } - /*if there is a BIFS stream in the OD, we need an GF_InlineScene (except if we already + /*if there is a BIFS stream in the OD, we need an GF_Scene (except if we already have one, which means this is the first IOD)*/ if (hasInline && !odm->subscene) { - odm->subscene = gf_inline_new(odm->parentscene); + odm->subscene = gf_scene_new(odm->parentscene); odm->subscene->root_od = odm; } @@ -563,6 +566,8 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) /*avoid channels PLAY request when confirming connection (sync network service)*/ odm->state = GF_ODM_STATE_IN_SETUP; + + gf_odm_lock(odm, 1); i=0; while ((esd = (GF_ESD *)gf_list_enum(odm->OD->ESDescriptors, &i)) ) { e = gf_odm_setup_es(odm, esd, serv, syncRef); @@ -574,22 +579,12 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) } } odm->state = GF_ODM_STATE_STOP; + gf_odm_lock(odm, 0); } - - /*special case for ODs only having OCRs: force a START since they're never refered to by media nodes*/ - if (odm->ocr_codec) gf_odm_start(odm); - -#if 0 - /*clean up - note that this will not be performed if one of the stream is using ESD URL*/ - if (!numOK) { - gf_odm_disconnect(odm, 1); - return; - } -#endif /*setup mediaobject info except for top-level OD*/ if (odm->parentscene) { - gf_inline_setup_object(odm->parentscene, odm); + gf_scene_setup_object(odm->parentscene, odm); } else { /*othewise send a connect ack for top level*/ GF_Event evt; @@ -598,25 +593,43 @@ void gf_odm_setup_object(GF_ObjectManager *odm, GF_ClientService *serv) evt.type = GF_EVENT_CONNECT; evt.connect.is_connected = 1; - GF_USER_SENDEVENT(odm->term->user, &evt); + gf_term_send_event(odm->term, &evt); } - /* and connect ONLY if main scene - inlines are connected when attached to Inline nodes*/ + /* start object*/ + /*case 1: object is the root, always start*/ if (!odm->parentscene) { assert(odm->subscene == odm->term->root_scene); assert(odm->subscene->root_od==odm); - gf_odm_start(odm); + gf_odm_start(odm, 0); + } + /*case 2: object is a pure OCR object - connect*/ + else if (odm->ocr_codec) { + gf_odm_start(odm, 0); + } + /*case 3: if the object is inserted from a broadcast, start it if not already done. This covers cases where the scene (BIFS, LASeR) and + the media (images) are both carrouseled and the carrousels are interleaved. If we wait for the scene to trigger a PLAY, we will likely + have to wait for an entire image carousel period to start filling the buffers, which is sub-optimal*/ + else if (!odm->state && (odm->flags & GF_ODM_NO_TIME_CTRL)) { + GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] Inserted from broadcast - forcing play\n", odm->OD->objectDescriptorID)); + gf_odm_start(odm, 0); + odm->flags |= GF_ODM_PREFETCH; } /*for objects inserted by user (subs & co), auto select*/ - if (odm->term->root_scene->is_dynamic_scene && (odm->OD->objectDescriptorID==GF_ESM_DYNAMIC_OD_ID) && (odm->flags & GF_ODM_REMOTE_OD)) { + if (odm->parentscene && odm->parentscene->is_dynamic_scene + && (odm->OD->objectDescriptorID==GF_MEDIA_EXTERNAL_ID) + && (odm->flags & GF_ODM_REMOTE_OD) + ) { GF_Event evt; if (odm->OD_PL) { - gf_inline_select_object(odm->term->root_scene, odm); + gf_scene_select_object(odm->parentscene, odm); odm->OD_PL = 0; } - evt.type = GF_EVENT_STREAMLIST; - GF_USER_SENDEVENT(odm->term->user,&evt); + if (odm->parentscene==odm->term->root_scene) { + evt.type = GF_EVENT_STREAMLIST; + gf_term_send_event(odm->term,&evt); + } } } @@ -643,7 +656,7 @@ GF_Err gf_odm_setup_es(GF_ObjectManager *odm, GF_ESD *esd, GF_ClientService *ser u16 clockID; Bool emulated_od = 0; GF_Err e; - GF_InlineScene *is; + GF_Scene *scene; /*find the clock for this new channel*/ ck = NULL; @@ -664,8 +677,7 @@ GF_Err gf_odm_setup_es(GF_ObjectManager *odm, GF_ESD *esd, GF_ClientService *ser } /*get clocks namespace (eg, parent scene)*/ - is = odm->subscene ? odm->subscene : odm->parentscene; - if (is->force_sub_clock_id) esd->OCRESID = is->force_sub_clock_id; + scene = odm->subscene ? odm->subscene : odm->parentscene; ck_namespace = odm->net_service->Clocks; /*little trick for non-OD addressing: if object is a remote one, and service owner already has clocks, @@ -696,16 +708,16 @@ GF_Err gf_odm_setup_es(GF_ObjectManager *odm, GF_ESD *esd, GF_ClientService *ser /*override clock dependencies if specified*/ if (odm->term->flags & GF_TERM_SINGLE_CLOCK) { - if (is->scene_codec) { - clockID = is->scene_codec->ck->clockID; - } else if (is->od_codec) { - clockID = is->od_codec->ck->clockID; + if (scene->scene_codec) { + clockID = scene->scene_codec->ck->clockID; + } else if (scene->od_codec) { + clockID = scene->od_codec->ck->clockID; } ck_namespace = odm->term->root_scene->root_od->net_service->Clocks; } /*if the GF_Clock is the stream, check if we have embedded OCR in the stream...*/ if (clockID == esd->ESID) { - flag = (esd->slConfig && esd->slConfig->OCRLength > 0); + flag = (esd->slConfig && esd->slConfig->OCRLength); } if (!esd->slConfig) { @@ -713,8 +725,7 @@ GF_Err gf_odm_setup_es(GF_ObjectManager *odm, GF_ESD *esd, GF_ClientService *ser esd->slConfig->timestampResolution = 1000; } - /*attach clock in namespace*/ - ck = gf_clock_attach(ck_namespace, is, clockID, esd->ESID, flag); + ck = gf_clock_attach(ck_namespace, scene, clockID, esd->ESID, flag); if (!ck) return GF_OUT_OF_MEM; esd->OCRESID = ck->clockID; @@ -768,6 +779,7 @@ clock_setup: dec = odm->subscene->scene_codec; } break; +#ifndef GPAC_MINIMAL_ODF case GF_STREAM_OCI: /*OCI - only one per OD */ if (odm->oci_codec) { @@ -778,6 +790,7 @@ clock_setup: gf_term_add_codec(odm->term, odm->oci_codec); } break; +#endif case GF_STREAM_AUDIO: case GF_STREAM_VISUAL: @@ -790,11 +803,12 @@ clock_setup: break; /*interaction stream*/ +#ifndef GPAC_DISABLE_VRML case GF_STREAM_INTERACT: if (!odm->codec) { odm->codec = gf_codec_new(odm, esd, odm->OD_PL, &e); if (!e) { - IS_Configure(odm->codec->decio, odm->parentscene, esd->URLString ? 1 : 0); + gf_isdec_configure(odm->codec->decio, odm->parentscene, esd->URLString ? 1 : 0); gf_term_add_codec(odm->term, odm->codec); /*register it*/ gf_list_add(odm->term->input_streams, odm->codec); @@ -805,6 +819,7 @@ clock_setup: emulated_od = 1; } break; +#endif case GF_STREAM_PRIVATE_SCENE: if (odm->subscene) { @@ -843,18 +858,18 @@ clock_setup: /*setup scene decoder*/ if (dec->decio && (dec->decio->InterfaceType==GF_SCENE_DECODER_INTERFACE) ) { GF_SceneDecoder *sdec = (GF_SceneDecoder *) dec->decio; - is = odm->subscene ? odm->subscene : odm->parentscene; + scene = odm->subscene ? odm->subscene : odm->parentscene; if (sdec->AttachScene) { /*if a node asked for this media object, use the scene graph of the node (AnimationStream in PROTO)*/ if (odm->mo && odm->mo->node_ptr) { - GF_SceneGraph *sg = is->graph; + GF_SceneGraph *sg = scene->graph; /*FIXME - this MUST be cleaned up*/ - is->graph = gf_node_get_graph((GF_Node*)odm->mo->node_ptr); - sdec->AttachScene(sdec, is, (is->scene_codec==dec) ? 1: 0); - is->graph = sg; + scene->graph = gf_node_get_graph((GF_Node*)odm->mo->node_ptr); + sdec->AttachScene(sdec, scene, (scene->scene_codec==dec) ? 1: 0); + scene->graph = sg; odm->mo->node_ptr = NULL; } else { - sdec->AttachScene(sdec, is, (is->scene_codec==dec) ? 1: 0); + sdec->AttachScene(sdec, scene, (scene->scene_codec==dec) ? 1: 0); } } } @@ -887,7 +902,7 @@ clock_setup: update is received, but this is not true with ESD URLs, where service setup may take some time (file downloading, authentification, etc...). We therefore need to wait for the service connect response before setting up the channel...*/ - cs = (GF_ChannelSetup*)malloc(sizeof(GF_ChannelSetup)); + cs = (GF_ChannelSetup*)gf_malloc(sizeof(GF_ChannelSetup)); cs->ch = ch; cs->dec = dec; @@ -902,7 +917,7 @@ clock_setup: s32 i = gf_list_find(odm->term->channels_pending, cs); if (i>=0) { gf_list_rem(odm->term->channels_pending, (u32) i); - free(cs); + gf_free(cs); odm->pending_channels--; ODM_CheckChannelService(ch); gf_es_del(ch); @@ -911,7 +926,7 @@ clock_setup: gf_term_lock_net(odm->term, 0); if (ch->service->owner) { gf_list_del_item(odm->term->channels_pending, cs); - free(cs); + gf_free(cs); return gf_odm_post_es_setup(ch, dec, GF_OK); } return e; @@ -1045,14 +1060,14 @@ void ODM_DeleteChannel(GF_ObjectManager *odm, GF_Channel *ch) count = gf_codec_remove_channel(odm->codec, ch); if (!count && odm->ocr_codec) count = gf_codec_remove_channel(odm->ocr_codec, ch); +#ifndef GPAC_MINIMAL_ODF if (!count && odm->oci_codec) count = gf_codec_remove_channel(odm->oci_codec, ch); +#endif if (!count && odm->subscene) { if (odm->subscene->scene_codec) count = gf_codec_remove_channel(odm->subscene->scene_codec, ch); if (!count) count = gf_codec_remove_channel(odm->subscene->od_codec, ch); } - assert(count); - if (ch->service) { ch->service->ifce->DisconnectChannel(ch->service->ifce, ch); if (ch->esd->URLString) { @@ -1095,40 +1110,64 @@ esd_found: /*this is the tricky part: make sure the net is locked before doing anything since an async service reply could destroy the object we're queuing for play*/ -void gf_odm_start(GF_ObjectManager *odm) +void gf_odm_start(GF_ObjectManager *odm, Bool was_in_media_queue) { + Bool skip_register = 1; gf_term_lock_net(odm->term, 1); - /*only if not open & ready (not waiting for ACK on channel setup)*/ - if (!odm->state && !odm->pending_channels && odm->OD) { - GF_Channel *ch; - u32 i = 0; - odm->state = GF_ODM_STATE_PLAY; + odm->flags &= ~GF_ODM_PREFETCH; - /*look for a given segment name to play*/ - if (odm->subscene) { - char *url, *frag; - assert(odm->subscene->root_od==odm); - - url = (odm->mo && odm->mo->URLs.count) ? odm->mo->URLs.vals[0].url : odm->net_service->url; - frag = strrchr(url, '#'); - if (frag) { - GF_Segment *seg = gf_odm_find_segment(odm, frag+1); - if (seg) { - odm->media_start_time = (u64) ((s64) seg->startTime*1000); - odm->media_stop_time = (u64) ((s64) (seg->startTime + seg->Duration)*1000); + /*only if not open & ready (not waiting for ACK on channel setup)*/ + if (!odm->pending_channels && odm->OD) { + /*object is not started - issue channel setup requests*/ + if (!odm->state) { + GF_Channel *ch; + u32 i = 0; + odm->state = GF_ODM_STATE_PLAY; + + /*look for a given segment name to play*/ + if (odm->subscene) { + char *url, *frag; + assert(odm->subscene->root_od==odm); + + url = (odm->mo && odm->mo->URLs.count) ? odm->mo->URLs.vals[0].url : odm->net_service->url; + frag = strrchr(url, '#'); + if (frag) { + GF_Segment *seg = gf_odm_find_segment(odm, frag+1); + if (seg) { + odm->media_start_time = (u64) ((s64) seg->startTime*1000); + odm->media_stop_time = (u64) ((s64) (seg->startTime + seg->Duration)*1000); + } } } + + /*start all channels and postpone play - this assures that all channels of a multiplexed are setup + before one starts playing*/ + while ( (ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) { + gf_es_start(ch); + GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] CH%d: At OTB %d starting channel\n", odm->OD->objectDescriptorID, ch->esd->ESID, gf_clock_time(ch->clock))); + } + skip_register = 0; + } + /*object is already started - only reinsert in media queue if this function was called on an object already in the queue*/ + else { + skip_register = was_in_media_queue ? 0 : 1; } - /*start all channels and postpone play - this assures that all channels of a multiplexed are setup - before one starts playing*/ - while ( (ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) { - gf_es_start(ch); - GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[ODM%d] CH%d: At OTB %d starting channel\n", odm->OD->objectDescriptorID, ch->esd->ESID, gf_clock_time(ch->clock))); + if (!skip_register && (gf_list_find(odm->term->media_queue, odm)<0)) { + odm->action_type = GF_ODM_ACTION_PLAY; + gf_list_add(odm->term->media_queue, odm); } - if (gf_list_find(odm->term->media_queue, odm)<0) gf_list_add(odm->term->media_queue, odm); } + +#if 0 + /*reset CB to stop state, otherwise updating a texture between gf_odm_start and gf_odm_play might trigger an end of stream*/ + if (odm->codec && odm->codec->CB) { + gf_cm_set_status(odm->codec->CB, CB_STOP); + odm->codec->CB->HasSeenEOS = 0; + } +#endif + gf_term_lock_net(odm->term, 0); } @@ -1140,7 +1179,9 @@ void gf_odm_play(GF_ObjectManager *odm) u64 range_end; Bool skip_od_st; GF_NetworkCommand com; +#ifndef GPAC_DISABLE_VRML MediaControlStack *ctrl; +#endif GF_Clock *parent_ck = NULL; if (odm->parentscene) { @@ -1205,8 +1246,9 @@ void gf_odm_play(GF_ObjectManager *odm) } } +#ifndef GPAC_DISABLE_VRML /*if object shares parent scene clock, do not use media control*/ - ctrl = parent_ck ? NULL : ODM_GetMediaControl(odm); + ctrl = parent_ck ? NULL : gf_odm_get_mediacontrol(odm); /*override range and speed with MC*/ if (ctrl) { MC_GetRange(ctrl, &com.play.start_range, &com.play.end_range); @@ -1230,6 +1272,8 @@ void gf_odm_play(GF_ObjectManager *odm) com.play.start_range += ck_time; } } +#endif + /*full object playback*/ if (com.play.end_range<=0) { odm->media_stop_time = odm->subscene ? 0 : odm->duration; @@ -1280,20 +1324,43 @@ void gf_odm_play(GF_ObjectManager *odm) if (odm->flags & GF_ODM_REGENERATE_SCENE) { odm->flags &= ~GF_ODM_REGENERATE_SCENE; - gf_inline_regenerate(odm->subscene); + gf_scene_regenerate(odm->subscene); } } if (odm->ocr_codec) gf_term_start_codec(odm->ocr_codec); +#ifndef GPAC_MINIMAL_ODF if (odm->oci_codec) gf_term_start_codec(odm->oci_codec); +#endif } +Bool gf_odm_owns_clock(GF_ObjectManager *odm, GF_Clock *ck) +{ + u32 i, j; + GF_ObjectManager *od; + GF_Channel *ch; + i=0; + while ((ch = gf_list_enum(odm->channels, &i))) { + if (ch->esd->ESID==ck->clockID) return 1; + } + j=0; + while ((od = gf_list_enum(odm->subscene->resources, &j))) { + i=0; + while ((ch = gf_list_enum(od->channels, &i))) { + if (ch->esd->ESID==ck->clockID) return 1; + } + } + return 0; +} void gf_odm_stop(GF_ObjectManager *odm, Bool force_close) { GF_Channel *ch; u32 i; +#ifndef GPAC_DISABLE_VRML MediaControlStack *ctrl; MediaSensorStack *media_sens; +#endif + GF_NetworkCommand com; if (!odm->state) return; @@ -1333,12 +1400,14 @@ void gf_odm_stop(GF_ObjectManager *odm, Bool force_close) if (odm->subscene->od_codec) gf_term_stop_codec(odm->subscene->od_codec); /*stops all resources of the subscene as well*/ - while ((sub_odm=(GF_ObjectManager *)gf_list_enum(odm->subscene->ODlist, &i))) { + 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); +#ifndef GPAC_MINIMAL_ODF if (odm->oci_codec) gf_term_stop_codec(odm->oci_codec); +#endif gf_term_lock_net(odm->term, 1); @@ -1367,7 +1436,9 @@ void gf_odm_stop(GF_ObjectManager *odm, Bool force_close) i=0; while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ) { /*stops clock if this is a scene stop*/ - if (!(odm->flags & GF_ODM_INHERIT_TIMELINE) && odm->subscene) gf_clock_stop(ch->clock); + if (!(odm->flags & GF_ODM_INHERIT_TIMELINE) && odm->subscene && gf_odm_owns_clock(odm, ch->clock) ) { + gf_clock_stop(ch->clock); + } gf_es_stop(ch); } @@ -1376,6 +1447,7 @@ void gf_odm_stop(GF_ObjectManager *odm, Bool force_close) odm->state = GF_ODM_STATE_STOP; odm->current_time = 0; +#ifndef GPAC_DISABLE_VRML /*reset media sensor(s)*/ if (force_close!=2) { i = 0; @@ -1384,14 +1456,38 @@ void gf_odm_stop(GF_ObjectManager *odm, Bool force_close) } } /*reset media control state*/ - ctrl = ODM_GetMediaControl(odm); + ctrl = gf_odm_get_mediacontrol(odm); if (ctrl) ctrl->current_seg = 0; +#endif + } void gf_odm_on_eos(GF_ObjectManager *odm, GF_Channel *on_channel) { + u32 i, count, nb_eos, nb_share_clock; +#ifndef GPAC_DISABLE_VRML if (gf_odm_check_segment_switch(odm)) return; +#endif + nb_share_clock=0; + nb_eos = 0; + count = gf_list_count(odm->channels); + for (i=0; i<count; i++) { + GF_Channel *ch = gf_list_get(odm->channels, i); + if (on_channel) { + if (ch->clock != on_channel->clock) continue; + nb_share_clock++; + } + if (ch->IsEndOfStream) nb_eos++; + } + if (on_channel) { + if (nb_eos==nb_share_clock) { + on_channel->clock->has_seen_eos = 1; + } + if (nb_eos != count) return; + } else { + if (nb_eos != count) return; + } gf_term_service_media_event(odm, GF_EVENT_MEDIA_END_OF_DATA); if (odm->codec && (on_channel->esd->decoderConfig->streamType==odm->codec->type)) { @@ -1403,7 +1499,9 @@ void gf_odm_on_eos(GF_ObjectManager *odm, GF_Channel *on_channel) return; } if (on_channel->esd->decoderConfig->streamType==GF_STREAM_OCI) { +#ifndef GPAC_MINIMAL_ODF gf_codec_set_status(odm->oci_codec, GF_ESM_CODEC_EOS); +#endif return; } if (!odm->subscene) return; @@ -1436,7 +1534,7 @@ void gf_odm_set_duration(GF_ObjectManager *odm, GF_Channel *ch, u64 stream_durat } /*update scene duration*/ - gf_inline_set_duration(odm->subscene ? odm->subscene : (odm->parentscene ? odm->parentscene : odm->term->root_scene)); + gf_scene_set_duration(odm->subscene ? odm->subscene : (odm->parentscene ? odm->parentscene : odm->term->root_scene)); } @@ -1450,89 +1548,6 @@ GF_Clock *gf_odm_get_media_clock(GF_ObjectManager *odm) } -void ODM_SetMediaControl(GF_ObjectManager *odm, MediaControlStack *ctrl) -{ - u32 i; - GF_Channel *ch; - - /*keep track of it*/ - if (ctrl && (gf_list_find(odm->mc_stack, ctrl) < 0)) gf_list_add(odm->mc_stack, ctrl); - if (ctrl && !ctrl->control->enabled) return; - - if (odm->subscene && odm->subscene->is_dynamic_scene) { - if (odm->subscene->dyn_ck) { - /*deactivate current control*/ - if (ctrl && odm->subscene->dyn_ck->mc) { - odm->subscene->dyn_ck->mc->control->enabled = 0; - gf_node_event_out_str((GF_Node *)odm->subscene->dyn_ck->mc->control, "enabled"); - } - odm->subscene->dyn_ck->mc = ctrl; - } - } else { - /*for each clock in the controled OD*/ - i=0; - while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i))) { - if (ch->clock->mc != ctrl) { - /*deactivate current control*/ - if (ctrl && ch->clock->mc) { - ch->clock->mc->control->enabled = 0; - gf_node_event_out_str((GF_Node *)ch->clock->mc->control, "enabled"); - } - /*and attach this control to the clock*/ - ch->clock->mc = ctrl; - } - } - } - /*store active control on media*/ - odm->media_ctrl = ODM_GetMediaControl(odm); -} - -MediaControlStack *ODM_GetMediaControl(GF_ObjectManager *odm) -{ - GF_Clock *ck; - ck = gf_odm_get_media_clock(odm); - if (!ck) return NULL; - return ck->mc; -} - -MediaControlStack *ODM_GetObjectMediaControl(GF_ObjectManager *odm) -{ - MediaControlStack *ctrl; - ctrl = ODM_GetMediaControl(odm); - if (!ctrl) return NULL; - /*inline scene control*/ - if (odm->subscene && (ctrl->stream->odm == odm->subscene->root_od) ) return ctrl; - if (ctrl->stream->OD_ID != odm->OD->objectDescriptorID) return NULL; - return ctrl; -} - -void ODM_RemoveMediaControl(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) ODM_SetMediaControl(odm, NULL); -} - -Bool ODM_SwitchMediaControl(GF_ObjectManager *odm, MediaControlStack *ctrl) -{ - u32 i; - MediaControlStack *st2; - if (!ctrl->control->enabled) return 0; - - /*for all media controls other than this one force enable to false*/ - i=0; - while ((st2 = (MediaControlStack *)gf_list_enum(odm->mc_stack, &i))) { - if (st2 == ctrl) continue; - if (st2->control->enabled) { - st2->control->enabled = 0; - gf_node_event_out_str((GF_Node *) st2->control, "enabled"); - } - st2->enabled = 0; - } - if (ctrl == odm->media_ctrl) return 0; - ODM_SetMediaControl(odm, ctrl); - return 1; -} Bool gf_odm_shares_clock(GF_ObjectManager *odm, GF_Clock *ck) { @@ -1550,7 +1565,9 @@ void gf_odm_pause(GF_ObjectManager *odm) { u32 i; GF_NetworkCommand com; +#ifndef GPAC_DISABLE_VRML MediaSensorStack *media_sens; +#endif GF_Channel *ch; if (odm->flags & GF_ODM_NO_TIME_CTRL) return; @@ -1568,7 +1585,9 @@ void gf_odm_pause(GF_ObjectManager *odm) if (odm->subscene->od_codec) gf_term_stop_codec(odm->subscene->od_codec); } if (odm->ocr_codec) gf_term_stop_codec(odm->ocr_codec); +#ifndef GPAC_MINIMAL_ODF if (odm->oci_codec) gf_term_stop_codec(odm->oci_codec); +#endif com.command_type = GF_NET_CHAN_PAUSE; i=0; @@ -1578,6 +1597,7 @@ void gf_odm_pause(GF_ObjectManager *odm) gf_term_service_command(ch->service, &com); } +#ifndef GPAC_DISABLE_VRML /*mediaSensor shall generate isActive false when paused*/ i=0; while ((media_sens = (MediaSensorStack *)gf_list_enum(odm->ms_stack, &i)) ) { @@ -1586,6 +1606,8 @@ void gf_odm_pause(GF_ObjectManager *odm) gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); } } +#endif + } void gf_odm_resume(GF_ObjectManager *odm) @@ -1593,7 +1615,9 @@ void gf_odm_resume(GF_ObjectManager *odm) u32 i; GF_NetworkCommand com; GF_Channel *ch; +#ifndef GPAC_DISABLE_VRML MediaSensorStack *media_sens; +#endif if (odm->flags & GF_ODM_NO_TIME_CTRL) return; @@ -1610,8 +1634,10 @@ void gf_odm_resume(GF_ObjectManager *odm) if (odm->subscene->od_codec) gf_term_start_codec(odm->subscene->od_codec); } if (odm->ocr_codec) gf_term_start_codec(odm->ocr_codec); +#ifndef GPAC_MINIMAL_ODF if (odm->oci_codec) gf_term_start_codec(odm->oci_codec); - +#endif + com.command_type = GF_NET_CHAN_RESUME; i=0; while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &i)) ){ @@ -1620,6 +1646,7 @@ void gf_odm_resume(GF_ObjectManager *odm) gf_term_service_command(ch->service, &com); } +#ifndef GPAC_DISABLE_VRML /*mediaSensor shall generate isActive TRUE when resumed*/ i=0; while ((media_sens = (MediaSensorStack *)gf_list_enum(odm->ms_stack, &i)) ){ @@ -1628,6 +1655,7 @@ void gf_odm_resume(GF_ObjectManager *odm) gf_node_event_out_str((GF_Node *) media_sens->sensor, "isActive"); } } +#endif } void gf_odm_set_speed(GF_ObjectManager *odm, Fixed speed) @@ -1729,60 +1757,13 @@ void gf_odm_init_segments(GF_ObjectManager *odm, GF_List *list, MFURL *url) } } -Bool gf_odm_check_segment_switch(GF_ObjectManager *odm) +void gf_odm_signal_eos(GF_ObjectManager *odm) { - u32 count, i; - GF_Segment *cur, *next; - MediaControlStack *ctrl = ODM_GetMediaControl(odm); - - /*if no control or control not on this object ignore segment switch*/ - if (!ctrl || (ctrl->stream->odm != odm)) return 0; - - count = gf_list_count(ctrl->seg); - /*reached end of controled stream (no more segments)*/ - if (ctrl->current_seg>=count) return 0; - - /*synth media, trigger if end of segment run-time*/ - if (!odm->codec || ((odm->codec->type!=GF_STREAM_VISUAL) && (odm->codec->type!=GF_STREAM_AUDIO))) { - GF_Clock *ck = gf_odm_get_media_clock(odm); - u32 now = gf_clock_time(ck); - u64 dur = odm->subscene ? odm->subscene->duration : odm->duration; - cur = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg); - if (odm->subscene && odm->subscene->needs_restart) return 0; - if (cur) dur = (u32) ((cur->Duration+cur->startTime)*1000); - if (now<=dur) return 0; - } else { - /*FIXME - for natural media with scalability, we should only process when all streams of the object are done*/ - } - - /*get current segment and move to next one*/ - cur = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg); - ctrl->current_seg ++; - - /*resync in case we have been issuing a play range over several segments*/ - for (i=ctrl->current_seg; i<count; i++) { - next = (GF_Segment *)gf_list_get(ctrl->seg, i); - if ( - /*if next seg start is after cur seg start*/ - (cur->startTime < next->startTime) - /*if next seg start is before cur seg end*/ - && (cur->startTime + cur->Duration > next->startTime) - /*if next seg start is already passed*/ - && (1000*next->startTime < odm->current_time) - /*then next segment was taken into account when requesting play*/ - ) { - cur = next; - ctrl->current_seg ++; - } + if (odm->parentscene != odm->term->root_scene) return; + if (gf_term_check_end_of_scene(odm->term, 0)) { + GF_Event evt; + evt.type = GF_EVENT_EOS; + gf_term_send_event(odm->term, &evt); } - /*if last segment in ctrl is done, end of stream*/ - if (ctrl->current_seg >= count) return 0; - next = (GF_Segment *)gf_list_get(ctrl->seg, ctrl->current_seg); - - /*if next seg start is not in current seg, media needs restart*/ - if ((next->startTime < cur->startTime) || (cur->startTime + cur->Duration < next->startTime)) - MC_Restart(odm); - - return 1; } diff --git a/src/terminal/scene.c b/src/terminal/scene.c new file mode 100644 index 0000000..629d35d --- /dev/null +++ b/src/terminal/scene.c @@ -0,0 +1,1407 @@ +/* + * GPAC - Multimedia Framework C SDK + * + * Copyright (c) Jean Le Feuvre 2000-2005 + * All rights reserved + * + * This file is part of GPAC / Media terminal 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. + * + */ + + + +/*for OD service types*/ +#include <gpac/constants.h> +/*for URL concatenation*/ +#include <gpac/network.h> +#include <gpac/internal/terminal_dev.h> +#include "media_control.h" +#include <gpac/compositor.h> +#include <gpac/nodes_x3d.h> + +/*SVG properties*/ +#ifndef GPAC_DISABLE_SVG +#include <gpac/scenegraph_svg.h> +#endif + +GF_EXPORT +Double gf_scene_get_time(void *_is) +{ + GF_Scene *scene = (GF_Scene *)_is; +#if 0 + u32 ret; + GF_Clock *ck; + assert(is); + ck = scene->scene_codec ? scene->scene_codec->ck : scene->dyn_ck; + if (!ck) return 0.0; + ret = gf_clock_time(ck); + if (scene->root_od->media_stop_time && (scene->root_od->media_stop_time<ret)) ret = (u32) scene->root_od->media_stop_time; + return ret/1000.0; +#else + return scene->simulation_time; +#endif +} + +#ifndef GPAC_DISABLE_VRML +void gf_storage_save(M_Storage *storage); +#endif + +void gf_scene_sample_time(GF_Scene *scene) +{ + u32 ret; + GF_Clock *ck; + ck = scene->scene_codec ? scene->scene_codec->ck : scene->dyn_ck; + if (!ck) + scene->simulation_time = 0; + else { + ret = gf_clock_time(ck); + if (scene->root_od->media_stop_time && (scene->root_od->media_stop_time<ret)) ret = (u32) scene->root_od->media_stop_time; + scene->simulation_time = ((Double) ret) / 1000.0; + } +} + +static void inline_on_media_event(GF_Scene *scene, u32 type) +{ + gf_term_service_media_event(scene->scene_codec->odm, type); +} + + +GF_Scene *gf_scene_new(GF_Scene *parentScene) +{ + GF_Scene *tmp; + GF_SAFEALLOC(tmp, GF_Scene); + if (! tmp) return NULL; + + tmp->mx = gf_mx_new("SceneMutex"); + tmp->resources = gf_list_new(); + tmp->scene_objects = gf_list_new(); + tmp->extra_scenes = gf_list_new(); + /*init inline scene*/ + if (parentScene) { + tmp->graph = gf_sg_new_subscene(parentScene->graph); + } else { + tmp->graph = gf_sg_new(); + } + + gf_sg_set_private(tmp->graph, tmp); + gf_sg_set_node_callback(tmp->graph, gf_term_node_callback); + gf_sg_set_scene_time_callback(tmp->graph, gf_scene_get_time); + +#ifndef GPAC_DISABLE_VRML + tmp->extern_protos = gf_list_new(); + gf_sg_set_proto_loader(tmp->graph, gf_inline_get_proto_lib); + + tmp->storages = gf_list_new(); + tmp->keynavigators = gf_list_new(); + +#endif + tmp->on_media_event = inline_on_media_event; + return tmp; +} + +void gf_scene_del(GF_Scene *scene) +{ + gf_list_del(scene->resources); + assert(!gf_list_count(scene->extra_scenes) ); + gf_list_del(scene->extra_scenes); + +#ifndef GPAC_DISABLE_VRML + while (gf_list_count(scene->extern_protos)) { + GF_ProtoLink *pl = (GF_ProtoLink *)gf_list_get(scene->extern_protos, 0); + gf_list_rem(scene->extern_protos, 0); + gf_free(pl); + } + gf_list_del(scene->extern_protos); +#endif + + /*delete scene decoder */ + if (scene->scene_codec) { + GF_SceneDecoder *dec = (GF_SceneDecoder *)scene->scene_codec->decio; + /*make sure the scene codec doesn't have anything left in the scene graph*/ + if (dec->ReleaseScene) dec->ReleaseScene(dec); + + gf_term_remove_codec(scene->root_od->term, scene->scene_codec); + gf_codec_del(scene->scene_codec); + /*reset pointer to NULL in case nodes try to access scene time*/ + scene->scene_codec = NULL; + } + + /*delete the scene graph*/ + gf_sg_del(scene->graph); + + if (scene->od_codec) { + gf_term_remove_codec(scene->root_od->term, scene->od_codec); + gf_codec_del(scene->od_codec); + scene->od_codec = NULL; + } + /*don't touch the root_od, will be deleted by the parent scene*/ + + /*clean all remaining associations*/ + while (gf_list_count(scene->scene_objects)) { + GF_MediaObject *obj = (GF_MediaObject *)gf_list_get(scene->scene_objects, 0); + if (obj->odm) obj->odm->mo = NULL; + gf_list_rem(scene->scene_objects, 0); + gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL); + gf_list_del(obj->nodes); + gf_free(obj); + } + gf_list_del(scene->scene_objects); +#ifndef GPAC_DISABLE_VRML + gf_list_del(scene->storages); + gf_list_del(scene->keynavigators); +#endif + + if (scene->audio_url.url) gf_free(scene->audio_url.url); + if (scene->visual_url.url) gf_free(scene->visual_url.url); + if (scene->text_url.url) gf_free(scene->text_url.url); + if (scene->dims_url.url) gf_free(scene->dims_url.url); + if (scene->fragment_uri) gf_free(scene->fragment_uri); + if (scene->redirect_xml_base) gf_free(scene->redirect_xml_base); + gf_mx_del(scene->mx); + gf_free(scene); +} + +GF_EXPORT +GF_ObjectManager *gf_scene_find_odm(GF_Scene *scene, u16 OD_ID) +{ + GF_ObjectManager *odm; + u32 i=0; + while ((odm = (GF_ObjectManager *)gf_list_enum(scene->resources, &i))) { + if (odm->OD && odm->OD->objectDescriptorID == OD_ID) return odm; + } + return NULL; +} + +GF_EXPORT +void gf_scene_disconnect(GF_Scene *scene, Bool for_shutdown) +{ + u32 i; + GF_MediaObject *obj; + GF_Node *root_node; + GF_ObjectManager *odm; + GF_SceneDecoder *dec = NULL; + if (scene->scene_codec) dec = (GF_SceneDecoder *)scene->scene_codec->decio; + + gf_term_lock_compositor(scene->root_od->term, 1); + + /*disconnect / kill all objects BEFORE reseting the scene graph since we have + potentially registered Inline nodes of the graph with the sub-scene*/ + if (!for_shutdown && scene->static_media_ressources) { + i=0; + /*stop all objects but DON'T DESTROY THEM*/ + while ((odm = (GF_ObjectManager *)gf_list_enum(scene->resources, &i))) { + if (odm->state) gf_odm_disconnect(odm, 0); + } + /*reset all stream associations*/ + i=0; + while ((obj = (GF_MediaObject*)gf_list_enum(scene->scene_objects, &i))) { + gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL); + gf_list_reset(obj->nodes); + } + } else { + while (gf_list_count(scene->resources)) { + odm = (GF_ObjectManager *)gf_list_get(scene->resources, 0); + gf_odm_disconnect(odm, (for_shutdown || !scene->static_media_ressources) ? 1 : 0); + } +#ifndef GPAC_DISABLE_VRML + while (gf_list_count(scene->extern_protos)) { + GF_ProtoLink *pl = (GF_ProtoLink *)gf_list_get(scene->extern_protos, 0); + gf_list_rem(scene->extern_protos, 0); + gf_free(pl); + } +#endif + } + + root_node = gf_sg_get_root_node(scene->graph); + if (for_shutdown && scene->root_od->mo) { + /*reset private stack of all inline nodes still registered*/ + while (gf_list_count(scene->root_od->mo->nodes)) { + GF_Node *n = (GF_Node *)gf_list_get(scene->root_od->mo->nodes, 0); + gf_list_rem(scene->root_od->mo->nodes, 0); +#ifndef GPAC_DISABLE_VRML + switch (gf_node_get_tag(n)) { + case TAG_MPEG4_Inline: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Inline: +#endif + gf_node_set_private(n, NULL); + break; + } +#endif + } + } + + /*remove all associated eventTargets - THIS NEEDS CLEANUP*/ + i=0; + while ((obj = (GF_MediaObject *)gf_list_enum(scene->resources, &i))) { + if (obj->nodes) gf_list_reset(obj->nodes); + } + +#ifndef GPAC_DISABLE_VRML + while (gf_list_count(scene->storages)) { + M_Storage *storage = gf_list_get(scene->storages, 0); + gf_list_rem(scene->storages, 0); + if (storage->_auto) gf_storage_save(storage); + } +#endif + + if (scene->graph_attached && (scene->root_od->term->root_scene == scene)) { + gf_sc_set_scene(scene->root_od->term->compositor, NULL); + } + /*release the scene*/ + if (dec && dec->ReleaseScene) dec->ReleaseScene(dec); + gf_sg_reset(scene->graph); + scene->graph_attached = 0; + + assert(!gf_list_count(scene->extra_scenes) ); + /*reset statc ressource flag since we destroyed scene objects*/ + scene->static_media_ressources = 0; + + /*remove stream associations*/ + while (gf_list_count(scene->scene_objects)) { + obj = (GF_MediaObject*)gf_list_get(scene->scene_objects, 0); + gf_list_rem(scene->scene_objects, 0); + if (obj->odm) obj->odm->mo = NULL; + gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL); + gf_list_del(obj->nodes); + gf_free(obj); + } + + if (for_shutdown && scene->root_od && scene->root_od->mo) { + } + gf_term_lock_compositor(scene->root_od->term, 0); +} + +static void gf_scene_insert_object(GF_Scene *scene, GF_MediaObject *mo, Bool lock_timelines, GF_MediaObject *sync_ref, Bool keep_fragment, GF_Scene *original_parent_scene) +{ + GF_ObjectManager *root_od; + GF_ObjectManager *odm; + char *url; + if (!mo || !scene) return; + + odm = gf_odm_new(); + /*remember OD*/ + odm->mo = mo; + mo->odm = odm; + odm->parentscene = scene; + odm->OD = (GF_ObjectDescriptor *) gf_odf_desc_new(GF_ODF_OD_TAG); + odm->OD->objectDescriptorID = GF_MEDIA_EXTERNAL_ID; + odm->parentscene = scene; + odm->term = scene->root_od->term; + root_od = scene->root_od; + + url = mo->URLs.vals[0].url; + if (!stricmp(url, "KeySensor")) { + GF_ESD *esd = gf_odf_desc_esd_new(0); + esd->decoderConfig->streamType = GF_STREAM_INTERACT; + esd->decoderConfig->objectTypeIndication = 1; + gf_free(esd->decoderConfig->decoderSpecificInfo->data); + esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(" KeySensor"); + esd->decoderConfig->decoderSpecificInfo->data[0] = 9; + esd->decoderConfig->decoderSpecificInfo->dataLength = 10; + esd->ESID = esd->OCRESID = 65534; + gf_list_add(odm->OD->ESDescriptors, esd); + } else if (!stricmp(url, "StringSensor")) { + GF_ESD *esd = gf_odf_desc_esd_new(0); + esd->decoderConfig->streamType = GF_STREAM_INTERACT; + esd->decoderConfig->objectTypeIndication = 1; + gf_free(esd->decoderConfig->decoderSpecificInfo->data); + esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(" StringSensor"); + esd->decoderConfig->decoderSpecificInfo->data[0] = 12; + esd->decoderConfig->decoderSpecificInfo->dataLength = 13; + esd->ESID = esd->OCRESID = 65534; + gf_list_add(odm->OD->ESDescriptors, esd); + } else if (!stricmp(url, "Mouse")) { + GF_ESD *esd = gf_odf_desc_esd_new(0); + esd->decoderConfig->streamType = GF_STREAM_INTERACT; + esd->decoderConfig->objectTypeIndication = 1; + gf_free(esd->decoderConfig->decoderSpecificInfo->data); + esd->decoderConfig->decoderSpecificInfo->data = gf_strdup(" Mouse"); + esd->decoderConfig->decoderSpecificInfo->data[0] = 5; + esd->decoderConfig->decoderSpecificInfo->dataLength = 6; + esd->ESID = esd->OCRESID = 65534; + gf_list_add(odm->OD->ESDescriptors, esd); + } else { + if (!keep_fragment) { + char *frag = strrchr(mo->URLs.vals[0].url, '#'); + if (frag) frag[0] = 0; + odm->OD->URLString = gf_strdup(mo->URLs.vals[0].url); + if (frag) frag[0] = '#'; + } else { + odm->OD->URLString = gf_strdup(mo->URLs.vals[0].url); + } + if (lock_timelines) odm->flags |= GF_ODM_INHERIT_TIMELINE; + } + + /*HACK - temp storage of sync ref*/ + if (sync_ref) odm->ocr_codec = (struct _generic_codec *)sync_ref; + + gf_list_add(scene->resources, odm); + if (original_parent_scene) { + gf_odm_setup_object(odm, original_parent_scene->root_od->net_service); + } else { + gf_odm_setup_object(odm, root_od->net_service); + } +} + +static void gf_scene_reinsert_object(GF_Scene *scene, GF_MediaObject *mo) +{ + u32 i; + gf_free(mo->URLs.vals[0].url); + mo->URLs.vals[0].url = NULL; + for (i=0; i<mo->URLs.count-1; i++) mo->URLs.vals[i].url = mo->URLs.vals[i+1].url; + mo->URLs.vals[mo->URLs.count-1].url = NULL; + mo->URLs.count-=1; + /*FIXME - we should re-ananlyse whether the fragment is important or not ...*/ + gf_scene_insert_object(scene, mo, 0, NULL, 0, NULL); +} + + +void gf_scene_remove_object(GF_Scene *scene, GF_ObjectManager *odm, Bool for_shutdown) +{ + u32 i; + GF_MediaObject *obj; + + gf_term_lock_net(odm->term, 1); + gf_list_del_item(scene->resources, odm); + gf_term_lock_net(odm->term, 0); + + + i=0; + while ((obj = (GF_MediaObject*)gf_list_enum(scene->scene_objects, &i))) { + if ( + /*assigned object*/ + (obj->odm==odm) || + /*remote OD*/ + ((obj->OD_ID!=GF_MEDIA_EXTERNAL_ID) && odm->OD && (obj->OD_ID == odm->OD->objectDescriptorID) ) || + /*dynamic OD*/ + (obj->URLs.count && odm->OD && odm->OD->URLString && !stricmp(obj->URLs.vals[0].url, odm->OD->URLString)) + ) { + Bool discard_obj = 0; + gf_odm_lock(odm, 1); + obj->flags = 0; + if (obj->odm) obj->odm->mo = NULL; + odm->mo = NULL; + obj->odm = NULL; + + obj->frame = NULL; + obj->framesize = obj->timestamp = 0; + + gf_odm_lock(odm, 0); + + /*if graph not attached we can remove the link (this is likely scene shutdown for some error)*/ + if (!scene->graph_attached) { +#ifndef GPAC_DISABLE_VRML + GF_ProtoLink *pl; + u32 j=0; + while ((pl = (GF_ProtoLink *)gf_list_enum(scene->extern_protos, &j))) { + if (pl->mo==obj) { + pl->mo = NULL; + break; + } + } +#endif + discard_obj = 1; + } else if (!for_shutdown) { + /*if dynamic OD and more than 1 URLs resetup*/ + if ((obj->OD_ID==GF_MEDIA_EXTERNAL_ID) && (obj->URLs.count>1)) { + discard_obj = 0; + gf_scene_reinsert_object(scene, obj); + } else { + discard_obj = 2; + } + } + /*discard media object*/ + else if (for_shutdown==2) + discard_obj = 1; + + /*reset private stack of all inline nodes still registered*/ + if (discard_obj) { + while (gf_list_count(obj->nodes)) { + GF_Node *n = (GF_Node *)gf_list_get(obj->nodes, 0); + gf_list_rem(obj->nodes, 0); +#ifndef GPAC_DISABLE_VRML + switch (gf_node_get_tag(n)) { + case TAG_MPEG4_Inline: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Inline: +#endif + gf_node_set_private(n, NULL); + break; + } +#endif + } + } + + if (discard_obj==1) { + gf_list_rem(scene->scene_objects, i-1); + gf_sg_vrml_mf_reset(&obj->URLs, GF_SG_VRML_MFURL); + gf_list_del(obj->nodes); + gf_free(obj); + } + return; + } + } +} + + +//browse all channels and update buffering info +void gf_scene_buffering_info(GF_Scene *scene) +{ + u32 i, j, max_buffer, cur_buffer; + GF_Channel *ch; + GF_Event evt; + GF_ObjectManager *odm; + if (!scene) return; + + max_buffer = cur_buffer = 0; + + /*get buffering on root OD*/ + j=0; + while ((ch = (GF_Channel*)gf_list_enum(scene->root_od->channels, &j))) { + /*count only re-buffering channels*/ + if (!ch->BufferOn) continue; + + max_buffer += ch->MaxBuffer; + cur_buffer += (ch->BufferTime>0) ? ch->BufferTime : 1; + } + + /*get buffering on all ODs*/ + i=0; + while ((odm = (GF_ObjectManager*)gf_list_enum(scene->resources, &i))) { + if (!odm->codec) continue; + j=0; + while ((ch = (GF_Channel*)gf_list_enum(odm->channels, &j))) { + /*count only re-buffering channels*/ + if (!ch->BufferOn) continue; + + max_buffer += ch->MaxBuffer; + cur_buffer += (ch->BufferTime>0) ? ch->BufferTime : 1; + } + } + + evt.type = GF_EVENT_PROGRESS; + evt.progress.progress_type = 0; + evt.progress.service = scene->root_od->net_service->url; + if (!max_buffer || !cur_buffer || (max_buffer <= cur_buffer)) { + evt.progress.done = evt.progress.total = max_buffer; + } else { + evt.progress.done = cur_buffer; + evt.progress.total = max_buffer; + } + gf_term_send_event(scene->root_od->term, &evt); +} + + + +void gf_scene_notify_event(GF_Scene *scene, u32 event_type, GF_Node *n, void *_event) +{ + /*fire resize event*/ +#ifndef GPAC_DISABLE_SVG + GF_Node *root; + u32 i, count; + u32 w, h; + GF_DOM_Event evt, *event; + event = (GF_DOM_Event *)_event; + + if (!scene) return; + root = gf_sg_get_root_node(scene->graph); + if (!root) return; + + if (!event) { + memset(&evt, 0, sizeof(GF_DOM_Event)); + event = &evt; + w = h = 0; + gf_sg_get_scene_size_info(scene->graph, &w, &h); + evt.type = event_type; + evt.screen_rect.width = INT2FIX(w); + evt.screen_rect.height = INT2FIX(h); + if (root) { +#ifndef GPAC_DISABLE_VRML + switch (gf_node_get_tag(root)) { + case TAG_MPEG4_Group: + case TAG_MPEG4_Layer3D: + evt.detail = 1; + break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Group: + evt.detail = 2; + break; +#endif + } +#endif + } + } + if (n) { + gf_dom_event_fire(n, event); + } else { + gf_dom_event_fire(root, event); + + count=scene->root_od->mo ? gf_list_count(scene->root_od->mo->nodes) : 0; + for (i=0;i<count; i++) { + gf_dom_event_fire( gf_list_get(scene->root_od->mo->nodes, i), event); + } + } +#endif +} + + +GF_EXPORT +void gf_scene_attach_to_compositor(GF_Scene *scene) +{ + char *url; + if (!scene->root_od) return; + + if ((scene->graph_attached==1) || (gf_sg_get_root_node(scene->graph)==NULL) ) { + gf_term_invalidate_compositor(scene->root_od->term); + return; + } + scene->graph_attached = 1; + + /*locate fragment IRI*/ + if (scene->root_od->net_service && scene->root_od->net_service->url) { + if (scene->fragment_uri) { + gf_free(scene->fragment_uri); + scene->fragment_uri = NULL; + } + url = strchr(scene->root_od->net_service->url, '#'); + if (url) scene->fragment_uri = gf_strdup(url+1); + } + + /*main display scene, setup compositor*/ + if (scene->root_od->term->root_scene == scene) { + gf_sc_set_scene(scene->root_od->term->compositor, scene->graph); + } + else { + u32 i, count; + count = scene->root_od->mo ? gf_list_count(scene->root_od->mo->nodes) : 0; + for (i=0;i<count; i++) { + gf_node_dirty_parents( gf_list_get(scene->root_od->mo->nodes, i) ); + } + gf_term_invalidate_compositor(scene->root_od->term); + + if (scene->root_od->parentscene->is_dynamic_scene) { + u32 w, h; + gf_sg_get_scene_size_info(scene->graph, &w, &h); + gf_sc_set_size(scene->root_od->term->compositor, w, h); + } + /*trigger a scene attach event*/ + gf_scene_notify_event(scene, GF_EVENT_SCENE_ATTACHED, NULL, NULL); + } +} + +static GF_MediaObject *IS_CheckExistingObject(GF_Scene *scene, MFURL *urls, u32 type) +{ + GF_MediaObject *obj; + u32 i = 0; + while ((obj = (GF_MediaObject *)gf_list_enum(scene->scene_objects, &i))) { + if (type && (type != obj->type)) continue; + if ((obj->OD_ID == GF_MEDIA_EXTERNAL_ID) && gf_mo_is_same_url(obj, urls, NULL, 0)) return obj; + else if ((obj->OD_ID != GF_MEDIA_EXTERNAL_ID) && (obj->OD_ID == urls->vals[0].OD_ID)) return obj; + } + return NULL; +} + +static GFINLINE Bool is_match_obj_type(u32 type, u32 hint_type) +{ + if (!hint_type) return 1; + if (type==hint_type) return 1; + /*TEXT are used by animation stream*/ + if ((type==GF_MEDIA_OBJECT_TEXT) && (hint_type==GF_MEDIA_OBJECT_UPDATES)) return 1; + return 0; +} + +GF_MediaObject *gf_scene_get_media_object_ex(GF_Scene *scene, MFURL *url, u32 obj_type_hint, Bool lock_timelines, GF_MediaObject *sync_ref, Bool force_new_if_not_attached, GF_Node *node) +{ + GF_MediaObject *obj; + GF_Scene *original_parent_scene = NULL; + Bool keep_fragment = 1; + Bool first_pass = force_new_if_not_attached ? 0 : 1; + u32 i, OD_ID; + + OD_ID = gf_mo_get_od_id(url); + if (!OD_ID) return NULL; + + /*the first pass is needed to detect objects already inserted and registered with the given nodes, regardless of + the force_new_if_not_attached flag. This ty^pically occurs when a resource is first created then linked to an animation/inline*/ +restart: + obj = NULL; + i=0; + while ((obj = (GF_MediaObject *)gf_list_enum(scene->scene_objects, &i))) { + if ( + /*regular OD scheme*/ + (OD_ID != GF_MEDIA_EXTERNAL_ID && (obj->OD_ID==OD_ID)) + || + /*dynamic OD scheme*/ + ((OD_ID == GF_MEDIA_EXTERNAL_ID) && (obj->OD_ID==GF_MEDIA_EXTERNAL_ID) + /*if object type unknown (media control, media sensor), return first obj matching URL + otherwise check types*/ + && is_match_obj_type(obj->type, obj_type_hint) + /*locate sub-url in given one and handle fragments (viewpoint/segments/...)*/ + && gf_mo_is_same_url(obj, url, &keep_fragment, obj_type_hint) + ) + ) { + + if (!first_pass && !force_new_if_not_attached) { + if (node && (gf_list_find(obj->nodes, node)<0)) + gf_list_add(obj->nodes, node); + return obj; + } + /*special case where the URL is requested twice for the same node: use the existing resource*/ + else if (node && (gf_list_find(obj->nodes, node)>=0)) { + return obj; + } + } + } + if (first_pass) { + first_pass = 0; + goto restart; + } + + /*we cannot create an OD manager at this point*/ + if (obj_type_hint==GF_MEDIA_OBJECT_UNDEF) return NULL; + + /*create a new object identification*/ + obj = gf_mo_new(); + obj->OD_ID = OD_ID; + obj->type = obj_type_hint; + + /*register node with object*/ + if (node) { + gf_list_add(obj->nodes, node); + + original_parent_scene = (GF_Scene*) gf_sg_get_private(gf_node_get_graph(node)); + } + + /*if animation stream object, remember originating node + !! FIXME - this should be cleaned up !! + */ + if (obj->type == GF_MEDIA_OBJECT_UPDATES) + obj->node_ptr = node; + + gf_list_add(scene->scene_objects, obj); + if (OD_ID == GF_MEDIA_EXTERNAL_ID) { + gf_sg_vrml_copy_mfurl(&obj->URLs, url); + gf_scene_insert_object(scene, obj, lock_timelines, sync_ref, keep_fragment, original_parent_scene); + /*safety check!!!*/ + if (gf_list_find(scene->scene_objects, obj)<0) + return NULL; + } + return obj; +} + +GF_MediaObject *gf_scene_get_media_object(GF_Scene *scene, MFURL *url, u32 obj_type_hint, Bool lock_timelines) +{ + return gf_scene_get_media_object_ex(scene, url, obj_type_hint, lock_timelines, NULL, 0, NULL); +} + +GF_EXPORT +void gf_scene_setup_object(GF_Scene *scene, GF_ObjectManager *odm) +{ + GF_MediaObject *obj; + u32 i; + + /*an object may already be assigned (when using ESD URLs, setup is performed twice)*/ + if (odm->mo != NULL) goto existing; + + i=0; + while ((obj = (GF_MediaObject*)gf_list_enum(scene->scene_objects, &i))) { + if (obj->OD_ID==GF_MEDIA_EXTERNAL_ID) { + //assert(obj->odm); + if (obj->odm == odm) { + /*assign FINAL OD, not parent*/ + obj->odm = odm; + odm->mo = obj; + goto existing; + } + } + else if (obj->OD_ID == odm->OD->objectDescriptorID) { + assert(obj->odm==NULL); + obj->odm = odm; + odm->mo = obj; + goto existing; + } + } + /*newly created OD*/ + odm->mo = gf_mo_new(); + gf_list_add(scene->scene_objects, odm->mo); + odm->mo->odm = odm; + odm->mo->OD_ID = odm->OD->objectDescriptorID; + +existing: + /*setup object type*/ + if (!odm->codec) odm->mo->type = GF_MEDIA_OBJECT_SCENE; + else if (odm->codec->type == GF_STREAM_VISUAL) odm->mo->type = GF_MEDIA_OBJECT_VIDEO; + else if (odm->codec->type == GF_STREAM_AUDIO) odm->mo->type = GF_MEDIA_OBJECT_AUDIO; + else if (odm->codec->type == GF_STREAM_TEXT) odm->mo->type = GF_MEDIA_OBJECT_TEXT; + else if (odm->codec->type == GF_STREAM_SCENE) odm->mo->type = GF_MEDIA_OBJECT_UPDATES; + + /*update info*/ + gf_mo_update_caps(odm->mo); + /*media object playback has already been requested by the scene, trigger media start*/ + if (odm->mo->num_open && !odm->state) { + gf_odm_start(odm, 0); + if (odm->mo->speed != FIX_ONE) gf_odm_set_speed(odm, odm->mo->speed); + } + if ((odm->mo->type==GF_MEDIA_OBJECT_VIDEO) && scene->is_dynamic_scene) { + gf_scene_force_size_to_video(scene, odm->mo); + } + /*invalidate scene for all nodes using the OD*/ + gf_term_invalidate_compositor(odm->term); +} + +GF_EXPORT +void gf_scene_set_duration(GF_Scene *scene) +{ + Double dur; + u32 i; + u64 max_dur; + GF_ObjectManager *odm; +#ifndef GPAC_DISABLE_VRML + MediaSensorStack *media_sens; +#endif + GF_Clock *ck; + + /*this is not normative but works in so many cases... set the duration to the max duration + of all streams sharing the clock*/ + ck = gf_odm_get_media_clock(scene->root_od); + max_dur = scene->root_od->duration; + i=0; + while ((odm = (GF_ObjectManager*)gf_list_enum(scene->resources, &i))) { + if (!odm->codec) continue; + if (!ck || gf_odm_shares_clock(odm, ck)) { + if (odm->duration>max_dur) max_dur = odm->duration; + } + } + if (scene->duration == max_dur) return; + + scene->duration = max_dur; + dur = (Double) (s64) scene->duration; + dur /= 1000; + +#ifndef GPAC_DISABLE_VRML + i=0; + while ((media_sens = (MediaSensorStack*)gf_list_enum(scene->root_od->ms_stack, &i))) { + if (media_sens->sensor->isActive) { + media_sens->sensor->mediaDuration = dur; + gf_node_event_out_str((GF_Node *) media_sens->sensor, "mediaDuration"); + } + } +#endif + + if ((scene == scene->root_od->term->root_scene) && scene->root_od->term->user->EventProc) { + GF_Event evt; + evt.type = GF_EVENT_DURATION; + evt.duration.duration = dur; + evt.duration.can_seek = !(scene->root_od->flags & GF_ODM_NO_TIME_CTRL); + if (dur<2.0) evt.duration.can_seek = 0; + gf_term_send_event(scene->root_od->term,&evt); + } + +} + +GF_MediaObject *gf_scene_find_object(GF_Scene *scene, u16 ODID, char *url) +{ + u32 i; + GF_MediaObject *mo; + if (!url && !ODID) return NULL; + i=0; + while ((mo = (GF_MediaObject *)gf_list_enum(scene->scene_objects, &i))) { + if (ODID==GF_MEDIA_EXTERNAL_ID) { + if (mo->URLs.count && !stricmp(mo->URLs.vals[0].url, url)) return mo; + } else if (mo->OD_ID==ODID) return mo; + } + return NULL; +} + + +GF_EXPORT +void gf_scene_register_extra_graph(GF_Scene *scene, GF_SceneGraph *extra_scene, Bool do_remove) +{ + if (do_remove) { + if (gf_list_find(scene->extra_scenes, extra_scene)<0) return; + gf_list_del_item(scene->extra_scenes, extra_scene); + /*for root scene*/ + if (scene->root_od->term->root_scene == scene) { + gf_sc_register_extra_graph(scene->root_od->term->compositor, extra_scene, 1); + } + } else { + if (gf_list_find(scene->extra_scenes, extra_scene)>=0) return; + gf_list_add(scene->extra_scenes, extra_scene); + /*for root scene*/ + if (scene->root_od->term->root_scene == scene) { + gf_sc_register_extra_graph(scene->root_od->term->compositor, extra_scene, 0); + } + } +} + + + +static void gf_scene_get_video_size(GF_MediaObject *mo, u32 *w, u32 *h) +{ + u32 pixel_ar; + if (!gf_mo_get_visual_info(mo, w, h, NULL, &pixel_ar, NULL)) return; + if (pixel_ar) { + u32 n, d; + n = (pixel_ar>>16) & 0xFF; + d = (pixel_ar) & 0xFF; + *w = (*w * n) / d; + } +} + +void gf_scene_force_size_to_video(GF_Scene *scene, GF_MediaObject *mo) +{ + u32 w, h; + gf_scene_get_video_size(mo, &w, &h); + gf_scene_force_size(scene, w, h); +} + +#ifndef GPAC_DISABLE_VRML + +static void IS_UpdateVideoPos(GF_Scene *scene) +{ + MFURL url; + M_Transform2D *tr; + GF_MediaObject *mo; + u32 w, h, v_w, v_h; + if (!scene->visual_url.OD_ID && !scene->visual_url.url) return; + + url.count = 1; + url.vals = &scene->visual_url; + mo = IS_CheckExistingObject(scene, &url, GF_MEDIA_OBJECT_VIDEO); + if (!mo) return; + tr = (M_Transform2D *) gf_sg_find_node_by_name(scene->graph, "DYN_TRANS"); + if (!tr) return; + + gf_sg_get_scene_size_info(scene->graph, &w, &h); + if (!w || !h) return; + + gf_scene_get_video_size(mo, &v_w, &v_h); + tr->translation.x = INT2FIX((s32) (w - v_w)) / 2; + tr->translation.y = INT2FIX((s32) (h - v_h)) / 2; + gf_node_dirty_set((GF_Node *)tr, 0, 0); + + if (scene->root_od->term->root_scene == scene) { + //if (scene->graph_attached) gf_sc_set_scene(scene->root_od->term->compositor, NULL); + gf_sc_set_scene(scene->root_od->term->compositor, scene->graph); + } +} + +static GF_Node *is_create_node(GF_SceneGraph *sg, u32 tag, const char *def_name) +{ + GF_Node *n = gf_node_new(sg, tag); + if (n) { + if (def_name) gf_node_set_id(n, gf_sg_get_next_available_node_id(sg), def_name); + gf_node_init(n); + } + return n; +} + +static Bool is_odm_url(SFURL *url, GF_ObjectManager *odm) +{ + if (!url->OD_ID && !url->url) return 0; + if (odm->OD->objectDescriptorID != GF_MEDIA_EXTERNAL_ID) return (url->OD_ID==odm->OD->objectDescriptorID) ? 1 : 0; + if (!url->url || !odm->OD->URLString) return 0; + return !stricmp(url->url, odm->OD->URLString); +} + +static void set_media_url(GF_Scene *scene, SFURL *media_url, GF_Node *node, MFURL *node_url, u32 type) +{ + u32 w, h; + SFURL *sfu; + Bool url_changed = 0; + /*scene url is not set, find the first one*/ + if (!media_url->OD_ID) { + u32 i=0; + GF_ObjectManager *odm = NULL; + while ((odm = (GF_ObjectManager*)gf_list_enum(scene->resources, &i))) { + if (type==GF_STREAM_TEXT) { + if (!odm->codec || ((odm->codec->type!=type) && (odm->codec->type!=GF_STREAM_ND_SUBPIC))) continue; + } + else if (type==GF_STREAM_SCENE) { + if (!odm->subscene || !odm->subscene->scene_codec) continue; + } + else { + if (!odm->codec || (odm->codec->type!=type)) continue; + } + + media_url->OD_ID = odm->OD->objectDescriptorID; + if (media_url->OD_ID==GF_MEDIA_EXTERNAL_ID) media_url->url = gf_strdup(odm->net_service->url); + + if (!scene->dyn_ck) { + if (odm->subscene) { + scene->dyn_ck = odm->subscene->scene_codec->ck; + } else { + scene->dyn_ck = odm->codec->ck; + } + } + + if (odm->mo && (type==GF_STREAM_VISUAL)) { + gf_scene_get_video_size(odm->mo, &w, &h); + if (w&&h) gf_sg_set_scene_size_info(scene->graph, w, h, 1); + } + break; + } + if (!odm) { + if (media_url->OD_ID ) url_changed = 1; + media_url->OD_ID = 0; + if (media_url->url) { + gf_free(media_url->url); + media_url->url = NULL; + } + } + } + + if (media_url->OD_ID) { + if (!node_url->count) url_changed = 1; + else if (node_url->vals[0].OD_ID!=media_url->OD_ID) url_changed = 1; + else if (media_url->OD_ID==GF_MEDIA_EXTERNAL_ID) { + if (!node_url->vals[0].url || !media_url->url || strcmp(node_url->vals[0].url, media_url->url) ) url_changed = 1; + } + } else { + if (node_url->count) url_changed = 1; + } + + if (url_changed) { + gf_sg_vrml_mf_reset(node_url, GF_SG_VRML_MFURL); + gf_sg_vrml_mf_append(node_url, GF_SG_VRML_MFURL, (void **) &sfu); + sfu->OD_ID = media_url->OD_ID; + if (media_url->url) sfu->url = gf_strdup(media_url->url); + + gf_node_changed(node, NULL); + } + +} + +/*regenerates the scene graph for dynamic scene. +This will also try to reload any previously presented streams. Note that in the usual case the scene is generated +just once when receiving the first OD AU (ressources are NOT destroyed when seeking), but since the network may need +to update the OD ressources, we still kake care of it*/ +void gf_scene_regenerate(GF_Scene *scene) +{ + GF_Node *n1, *n2; + GF_Event evt; + M_AudioClip *ac; + M_MovieTexture *mt; + M_AnimationStream *as; + M_Inline *dims; + + if (!scene->is_dynamic_scene) return; + + GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Inline] Regenerating scene graph for service %s\n", scene->root_od->net_service->url)); + + gf_sc_lock(scene->root_od->term->compositor, 1); + + ac = (M_AudioClip *) gf_sg_find_node_by_name(scene->graph, "DYN_AUDIO"); + + /*this is the first time, generate a scene graph*/ + if (!ac) { + /*create an OrderedGroup*/ + n1 = is_create_node(scene->graph, TAG_MPEG4_OrderedGroup, NULL); + gf_sg_set_root_node(scene->graph, n1); + gf_node_register(n1, NULL); + + /*create an sound2D and an audioClip node*/ + n2 = is_create_node(scene->graph, TAG_MPEG4_Sound2D, NULL); + gf_node_list_add_child( &((GF_ParentNode *)n1)->children, n2); + gf_node_register(n2, n1); + + ac = (M_AudioClip *) is_create_node(scene->graph, TAG_MPEG4_AudioClip, "DYN_AUDIO"); + ac->startTime = gf_scene_get_time(scene); + ((M_Sound2D *)n2)->source = (GF_Node *)ac; + gf_node_register((GF_Node *)ac, n2); + + + /*transform for any translation due to scene resize (3GPP)*/ + n2 = is_create_node(scene->graph, TAG_MPEG4_Transform2D, "DYN_TRANS"); + gf_node_list_add_child( &((GF_ParentNode *)n1)->children, n2); + gf_node_register(n2, n1); + n1 = n2; + + /*create a shape and bitmap node*/ + n2 = is_create_node(scene->graph, TAG_MPEG4_Shape, NULL); + gf_node_list_add_child( &((GF_ParentNode *)n1)->children, n2); + gf_node_register(n2, n1); + n1 = n2; + n2 = is_create_node(scene->graph, TAG_MPEG4_Appearance, NULL); + ((M_Shape *)n1)->appearance = n2; + gf_node_register(n2, n1); + + /*note we create a movie texture even for images...*/ + mt = (M_MovieTexture *) is_create_node(scene->graph, TAG_MPEG4_MovieTexture, "DYN_VIDEO"); + mt->startTime = gf_scene_get_time(scene); + ((M_Appearance *)n2)->texture = (GF_Node *)mt; + gf_node_register((GF_Node *)mt, n2); + + n2 = is_create_node(scene->graph, TAG_MPEG4_Bitmap, NULL); + ((M_Shape *)n1)->geometry = n2; + gf_node_register(n2, n1); + + + /*text streams controlled through AnimationStream*/ + n1 = gf_sg_get_root_node(scene->graph); + as = (M_AnimationStream *) is_create_node(scene->graph, TAG_MPEG4_AnimationStream, "DYN_TEXT"); + gf_node_list_add_child( &((GF_ParentNode *)n1)->children, (GF_Node*)as); + gf_node_register((GF_Node *)as, n1); + + + /*3GPP DIMS streams controlled */ + n1 = gf_sg_get_root_node(scene->graph); + dims = (M_Inline *) is_create_node(scene->graph, TAG_MPEG4_Inline, "DYN_SCENE"); + gf_node_list_add_child( &((GF_ParentNode *)n1)->children, (GF_Node*)dims); + gf_node_register((GF_Node *)dims, n1); + + } + + ac = (M_AudioClip *) gf_sg_find_node_by_name(scene->graph, "DYN_AUDIO"); + set_media_url(scene, &scene->audio_url, (GF_Node*)ac, &ac->url, GF_STREAM_AUDIO); + + mt = (M_MovieTexture *) gf_sg_find_node_by_name(scene->graph, "DYN_VIDEO"); + set_media_url(scene, &scene->visual_url, (GF_Node*)mt, &mt->url, GF_STREAM_VISUAL); + + as = (M_AnimationStream *) gf_sg_find_node_by_name(scene->graph, "DYN_TEXT"); + set_media_url(scene, &scene->text_url, (GF_Node*)as, &as->url, GF_STREAM_TEXT); + + dims = (M_Inline *) gf_sg_find_node_by_name(scene->graph, "DYN_SCENE"); + set_media_url(scene, &scene->dims_url, (GF_Node*)dims, &dims->url, GF_STREAM_SCENE); + + gf_sc_lock(scene->root_od->term->compositor, 0); + + /*disconnect to force resize*/ + if (scene->root_od->term->root_scene == scene) { + gf_sc_set_scene(scene->root_od->term->compositor, scene->graph); + scene->graph_attached = 1; + evt.type = GF_EVENT_STREAMLIST; + gf_term_send_event(scene->root_od->term, &evt); + IS_UpdateVideoPos(scene); + } else { + scene->graph_attached = 1; + gf_scene_notify_event(scene, GF_EVENT_SCENE_ATTACHED, NULL, NULL); + gf_term_invalidate_compositor(scene->root_od->term); + } +} +#else +/*!!fixme - we would need an SVG scene in case no VRML support is present !!!*/ +void gf_scene_regenerate(GF_Scene *scene) {} +void gf_scene_restart_dynamic(GF_Scene *scene, u64 from_time) {} +void gf_scene_select_object(GF_Scene *scene, GF_ObjectManager *odm) {} +#endif /*GPAC_DISABLE_VRML*/ + +#ifndef GPAC_DISABLE_VRML + +static Bool check_odm_deactivate(SFURL *url, GF_ObjectManager *odm, GF_Node *n) +{ + GF_FieldInfo info; + if (!is_odm_url(url, odm) || !n) return 0; + + if (url->url) gf_free(url->url); + url->url = NULL; + url->OD_ID = 0; + + gf_node_get_field_by_name(n, "url", &info); + gf_sg_vrml_mf_reset(info.far_ptr, GF_SG_VRML_MFURL); + gf_node_get_field_by_name(n, "stopTime", &info); + *((SFTime *)info.far_ptr) = gf_node_get_scene_time(n); + gf_node_changed(n, NULL); + return 1; +} + +void gf_scene_select_object(GF_Scene *scene, GF_ObjectManager *odm) +{ + char *url; + if (!scene->is_dynamic_scene || !scene->graph_attached || !odm) return; + + if (!odm->codec) return; + + if (odm->state) { + if (check_odm_deactivate(&scene->audio_url, odm, gf_sg_find_node_by_name(scene->graph, "DYN_AUDIO")) ) return; + if (check_odm_deactivate(&scene->visual_url, odm, gf_sg_find_node_by_name(scene->graph, "DYN_VIDEO") )) return; + if (check_odm_deactivate(&scene->text_url, odm, gf_sg_find_node_by_name(scene->graph, "DYN_TEXT") )) return; + } + + if (odm->codec->type == GF_STREAM_AUDIO) { + M_AudioClip *ac = (M_AudioClip *) gf_sg_find_node_by_name(scene->graph, "DYN_AUDIO"); + if (!ac) return; + if (scene->audio_url.url) gf_free(scene->audio_url.url); + scene->audio_url.url = NULL; + scene->audio_url.OD_ID = odm->OD->objectDescriptorID; + if (!ac->url.count) gf_sg_vrml_mf_alloc(&ac->url, GF_SG_VRML_MFURL, 1); + ac->url.vals[0].OD_ID = odm->OD->objectDescriptorID; + if (ac->url.vals[0].url) { + gf_free(ac->url.vals[0].url); + ac->url.vals[0].url = NULL; + } + url = odm->mo->URLs.count ? odm->mo->URLs.vals[0].url : NULL; + if (url) { + scene->audio_url.url = gf_strdup(url); + ac->url.vals[0].url = gf_strdup(url); + } + ac->startTime = gf_scene_get_time(scene); + gf_node_changed((GF_Node *)ac, NULL); + return; + } + + if (odm->codec->type == GF_STREAM_VISUAL) { + M_MovieTexture *mt = (M_MovieTexture*) gf_sg_find_node_by_name(scene->graph, "DYN_VIDEO"); + if (!mt) return; + if (scene->visual_url.url) gf_free(scene->visual_url.url); + scene->visual_url.url = NULL; + scene->visual_url.OD_ID = odm->OD->objectDescriptorID; + if (!mt->url.count) gf_sg_vrml_mf_alloc(&mt->url, GF_SG_VRML_MFURL, 1); + mt->url.vals[0].OD_ID = odm->OD->objectDescriptorID; + if (mt->url.vals[0].url) gf_free(mt->url.vals[0].url); + url = odm->mo->URLs.count ? odm->mo->URLs.vals[0].url : NULL; + if (url) { + scene->visual_url.url = gf_strdup(url); + mt->url.vals[0].url = gf_strdup(url); + } + mt->startTime = gf_scene_get_time(scene); + gf_node_changed((GF_Node *)mt, NULL); + if (odm->mo) gf_scene_force_size_to_video(scene, odm->mo); + return; + } + + + if (odm->codec->type == GF_STREAM_TEXT) { + M_AnimationStream *as = (M_AnimationStream*) gf_sg_find_node_by_name(scene->graph, "DYN_TEXT"); + if (!as) return; + if (scene->text_url.url) gf_free(scene->text_url.url); + scene->text_url.url = NULL; + scene->text_url.OD_ID = odm->OD->objectDescriptorID; + if (!as->url.count) gf_sg_vrml_mf_alloc(&as->url, GF_SG_VRML_MFURL, 1); + as->url.vals[0].OD_ID = odm->OD->objectDescriptorID; + if (as->url.vals[0].url) gf_free(as->url.vals[0].url); + url = odm->mo->URLs.count ? odm->mo->URLs.vals[0].url : NULL; + if (url) { + scene->text_url.url = gf_strdup(url); + as->url.vals[0].url = gf_strdup(url); + } + as->startTime = gf_scene_get_time(scene); + gf_node_changed((GF_Node *)as, NULL); + return; + } +} + +void gf_scene_restart_dynamic(GF_Scene *scene, u64 from_time) +{ + u32 i; + GF_List *to_restart; + GF_ObjectManager *odm; + + GF_LOG(GF_LOG_INFO, GF_LOG_MEDIA, ("[InlineScene] Restarting from "LLD"\n", LLD_CAST from_time)); + to_restart = gf_list_new(); + i=0; + while ((odm = (GF_ObjectManager*)gf_list_enum(scene->resources, &i))) { + if (odm->state != GF_ODM_STATE_BLOCKED) { + gf_list_add(to_restart, odm); + if (odm->state == GF_ODM_STATE_PLAY) { + gf_odm_stop(odm, 1); + } + } + } + + /*reset clock*/ + if (scene->dyn_ck) { + gf_clock_reset(scene->dyn_ck); + scene->simulation_time = from_time/1000.0; + } + /*restart objects*/ + i=0; + while ((odm = (GF_ObjectManager*)gf_list_enum(to_restart, &i))) { + odm->media_start_time = from_time; + gf_odm_start(odm, 0); + } + gf_list_del(to_restart); + + /*also check nodes since they may be deactivated (end of stream)*/ + { + M_AudioClip *ac = (M_AudioClip *) gf_sg_find_node_by_name(scene->graph, "DYN_AUDIO"); + M_MovieTexture *mt = (M_MovieTexture *) gf_sg_find_node_by_name(scene->graph, "DYN_VIDEO"); + M_AnimationStream *as = (M_AnimationStream *) gf_sg_find_node_by_name(scene->graph, "DYN_TEXT"); + if (ac) { + ac->startTime = gf_scene_get_time(scene); + gf_node_changed((GF_Node *)ac, NULL); + } + if (mt) { + mt->startTime = gf_scene_get_time(scene); + gf_node_changed((GF_Node *)mt, NULL); + } + if (as) { + as->startTime = gf_scene_get_time(scene); + gf_node_changed((GF_Node *)as, NULL); + } + } +} + +#endif /*GPAC_DISABLE_VRML*/ + + +GF_EXPORT +void gf_scene_force_size(GF_Scene *scene, u32 width, u32 height) +{ + /*for now only allowed when no scene info*/ + if (!scene->is_dynamic_scene) return; + gf_sg_set_scene_size_info(scene->graph, width, height, gf_sg_use_pixel_metrics(scene->graph)); + + if (scene->root_od->term->root_scene == scene) + gf_sc_set_scene(scene->root_od->term->compositor, scene->graph); + + gf_scene_notify_event(scene, GF_EVENT_SCENE_ATTACHED, NULL, NULL); + +#ifndef GPAC_DISABLE_VRML + IS_UpdateVideoPos(scene); +#endif +} + + +GF_EXPORT +Bool gf_scene_process_anchor(GF_Node *caller, GF_Event *evt) +{ + GF_Terminal *term; +#ifndef GPAC_DISABLE_VRML + u32 i; + M_Inline *inl; +#endif + GF_Scene *scene; + GF_SceneGraph *sg = gf_node_get_graph(caller); + if (!sg) return 1; + scene = (GF_Scene *)gf_sg_get_private(sg); + if (!scene) return 1; + term = scene->root_od->term; + + /*if main scene forward to user. If no params or first one not "self" forward to user*/ + if ((term->root_scene==scene) || !evt->navigate.parameters || !evt->navigate.param_count || (stricmp(evt->navigate.parameters[0], "self") && stricmp(evt->navigate.parameters[0], "_self"))) { + if (term->user->EventProc) return gf_term_send_event(term, evt); + return 1; + } + + if (!scene->root_od->mo) return 1; + + /*FIXME this is too restrictive, we assume the navigate URL is really a presentation one...*/ +#ifndef GPAC_DISABLE_VRML + i=0; + while ((inl = (M_Inline*)gf_list_enum(scene->root_od->mo->nodes, &i))) { + switch (gf_node_get_tag((GF_Node *)inl)) { + case TAG_MPEG4_Inline: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Inline: +#endif + gf_sg_vrml_mf_reset(&inl->url, GF_SG_VRML_MFURL); + gf_sg_vrml_mf_alloc(&inl->url, GF_SG_VRML_MFURL, 1); + inl->url.vals[0].url = gf_strdup(evt->navigate.to_url ? evt->navigate.to_url : ""); + /*signal URL change but don't destroy inline scene now since we got this event from inside the scene, + this could crash compositors*/ + scene->needs_restart = 2; + break; + } + } +#endif + + return 1; +} + +GF_EXPORT +GF_Compositor *gf_sc_get_compositor(GF_Node *node) +{ + GF_Scene *scene; + GF_SceneGraph *sg = gf_node_get_graph(node); + if (!sg) return NULL; + scene = (GF_Scene *)gf_sg_get_private(sg); + if (!scene) return NULL; + return scene->root_od->term->compositor; +} + +const char *gf_scene_get_fragment_uri(GF_Node *node) +{ + GF_SceneGraph *sg = gf_node_get_graph(node); + GF_Scene *scene = sg ? (GF_Scene *) gf_sg_get_private(sg) : NULL; + if (!scene) return NULL; + return scene->fragment_uri; +} +void gf_scene_set_fragment_uri(GF_Node *node, const char *uri) +{ + GF_SceneGraph *sg = gf_node_get_graph(node); + GF_Scene *scene = sg ? (GF_Scene *) gf_sg_get_private(sg) : NULL; + if (!scene) return; + if (scene->fragment_uri) { + gf_free(scene->fragment_uri); + scene->fragment_uri = NULL; + } + if (uri) scene->fragment_uri = gf_strdup(uri); +} + + +GF_Node *gf_scene_get_subscene_root(GF_Node *node) +{ + GF_Scene *scene; + if (!node) return NULL; + switch (gf_node_get_tag(node)) { +#ifndef GPAC_DISABLE_VRML + case TAG_MPEG4_Inline: +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_Inline: +#endif + break; +#endif + default: + return NULL; + } + scene = (GF_Scene *)gf_node_get_private(node); + if (!scene) return NULL; + if (!scene->graph) return NULL; + return gf_sg_get_root_node(scene->graph); +} + +/*returns 0 if any of the clock still hasn't seen EOS*/ +Bool gf_scene_check_clocks(GF_ClientService *ns, GF_Scene *scene) +{ + GF_Clock *ck; + u32 i; + if (scene) { + GF_ObjectManager *odm; + if (scene->root_od->net_service != ns) { + if (!gf_scene_check_clocks(scene->root_od->net_service, scene)) return 0; + } + i=0; + while ( (odm = (GF_ObjectManager*)gf_list_enum(scene->resources, &i)) ) { + if (odm->net_service != ns) { + if (!gf_scene_check_clocks(odm->net_service, NULL)) return 0; + } + } + } + i=0; + while ( (ck = (GF_Clock *)gf_list_enum(ns->Clocks, &i) ) ) { + if (!ck->has_seen_eos) return 0; + } + return 1; +} + +const char *gf_scene_get_service_url(GF_SceneGraph *sg) +{ + GF_Scene *scene = gf_sg_get_private(sg); + if (scene) return scene->root_od->net_service->url; + return NULL; +} +Bool gf_scene_lock(GF_SceneGraph *sg, Bool do_lock) +{ + GF_Scene *scene = gf_sg_get_private(sg); + if (!scene) return 0; + if (do_lock) return gf_mx_try_lock(scene->mx); + else gf_mx_v(scene->mx); + return 1; +} + diff --git a/src/terminal/svg_external.c b/src/terminal/svg_external.c index 49a4d35..3c89af8 100644 --- a/src/terminal/svg_external.c +++ b/src/terminal/svg_external.c @@ -38,17 +38,17 @@ char *gf_term_resolve_xlink(GF_Node *node, char *the_url) { char *url; - GF_InlineScene *is = gf_sg_get_private(gf_node_get_graph(node)); - if (!is) return NULL; + GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node)); + if (!scene) return NULL; - url = strdup(the_url); + url = gf_strdup(the_url); /*apply XML:base*/ while (node) { GF_FieldInfo info; if (gf_node_get_attribute_by_tag(node, TAG_XML_ATT_base, 0, 0, &info)==GF_OK) { char *new_url = gf_url_concatenate( ((XMLRI*)info.far_ptr)->string, url); if (new_url) { - free(url); + gf_free(url); url = new_url; } } @@ -58,14 +58,17 @@ char *gf_term_resolve_xlink(GF_Node *node, char *the_url) /*if this is a fragment and no XML:BASE was found, this is a fragment of the current document*/ if (url[0]=='#') return url; - if (is) { + if (scene) { char *the_url; - if (is->redirect_xml_base) { - the_url = gf_url_concatenate(is->redirect_xml_base, url); + if (scene->redirect_xml_base) { + the_url = gf_url_concatenate(scene->redirect_xml_base, url); } else { - the_url = gf_url_concatenate(is->root_od->net_service->url, url); +// the_url = gf_url_concatenate(is->root_od->net_service->url, url); + /*the root url of a document should be "." if not specified, so that the final URL resolve happens only once + at the service level*/ + the_url = gf_strdup(url); } - free(url); + gf_free(url); return the_url; } return url; @@ -79,8 +82,8 @@ GF_Err gf_term_get_mfurl_from_xlink(GF_Node *node, MFURL *mfurl) SFURL *sfurl = NULL; GF_FieldInfo info; XMLRI *iri; - GF_InlineScene *is = gf_sg_get_private(gf_node_get_graph(node)); - if (!is) return GF_BAD_PARAM; + GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node)); + if (!scene) return GF_BAD_PARAM; gf_sg_vrml_mf_reset(mfurl, GF_SG_VRML_MFURL); @@ -100,8 +103,11 @@ GF_Err gf_term_get_mfurl_from_xlink(GF_Node *node, MFURL *mfurl) if (stream_id) return GF_OK; if (!strncmp(iri->string, "data:", 5)) { - const char *cache_dir = gf_cfg_get_key(is->root_od->term->user->config, "General", "CacheDirectory"); - return gf_node_store_embedded_data(iri, cache_dir, "embedded_"); + const char *cache_dir = gf_cfg_get_key(scene->root_od->term->user->config, "General", "CacheDirectory"); + e = gf_node_store_embedded_data(iri, cache_dir, "embedded_"); + if (e) return e; + sfurl->url = gf_strdup(iri->string); + return GF_OK; } sfurl->url = gf_term_resolve_xlink(node, iri->string); return e; @@ -109,14 +115,14 @@ GF_Err gf_term_get_mfurl_from_xlink(GF_Node *node, MFURL *mfurl) /* Creates a subscene from the xlink:href */ -static GF_InlineScene *gf_svg_get_subscene(GF_Node *elt, XLinkAttributesPointers *xlinkp, SMILSyncAttributesPointers *syncp, Bool use_sync, Bool primary_resource) +static GF_Scene *gf_svg_get_subscene(GF_Node *elt, XLinkAttributesPointers *xlinkp, SMILSyncAttributesPointers *syncp, Bool use_sync, Bool primary_resource) { MFURL url; Bool lock_timelines = 0; GF_MediaObject *mo; GF_SceneGraph *graph = gf_node_get_graph(elt); - GF_InlineScene *is = (GF_InlineScene *)gf_sg_get_private(graph); - if (!is) return NULL; + GF_Scene *scene = (GF_Scene *)gf_sg_get_private(graph); + if (!scene) return NULL; if (use_sync && syncp) { switch ((syncp->syncBehavior?*syncp->syncBehavior:SMIL_SYNCBEHAVIOR_DEFAULT)) { @@ -148,10 +154,10 @@ static GF_InlineScene *gf_svg_get_subscene(GF_Node *elt, XLinkAttributesPointers gf_term_get_mfurl_from_xlink(elt, &url); - while (is->secondary_resource && is->root_od->parentscene) - is = is->root_od->parentscene; + while (scene->secondary_resource && scene->root_od->parentscene) + scene = scene->root_od->parentscene; - mo = gf_inline_get_media_object_ex(is, &url, GF_MEDIA_OBJECT_SCENE, lock_timelines, NULL, primary_resource, elt); + mo = gf_scene_get_media_object_ex(scene, &url, GF_MEDIA_OBJECT_SCENE, lock_timelines, NULL, primary_resource, elt); gf_sg_vrml_mf_reset(&url, GF_SG_VRML_MFURL); if (!mo || !mo->odm) return NULL; @@ -162,12 +168,12 @@ static GF_InlineScene *gf_svg_get_subscene(GF_Node *elt, XLinkAttributesPointers GF_MediaObject *gf_mo_load_xlink_resource(GF_Node *node, Bool primary_resource, Double clipBegin, Double clipEnd) { - GF_InlineScene *new_resource; + GF_Scene *new_resource; SVGAllAttributes all_atts; XLinkAttributesPointers xlinkp; SMILSyncAttributesPointers syncp; - GF_InlineScene *is = gf_sg_get_private(gf_node_get_graph(node)); - if (!is) return NULL; + GF_Scene *scene = gf_sg_get_private(gf_node_get_graph(node)); + if (!scene) return NULL; gf_svg_flatten_attributes((SVG_Element *)node, &all_atts); xlinkp.actuate = all_atts.xlink_actuate; @@ -192,9 +198,6 @@ GF_MediaObject *gf_mo_load_xlink_resource(GF_Node *node, Bool primary_resource, new_resource = gf_svg_get_subscene(node, &xlinkp, &syncp, primary_resource ? 1 : 0, primary_resource); if (!new_resource) return NULL; - /*remember parent node for event propagation*/ - gf_list_add(new_resource->inline_nodes, node); - /*play*/ gf_mo_play(new_resource->root_od->mo, 0, -1, 0); @@ -211,12 +214,11 @@ void gf_mo_unload_xlink_resource(GF_Node *node, GF_MediaObject *mo) } if (mo->num_open) { mo->num_open--; - gf_list_del_item(mo->odm->subscene->inline_nodes, node); if (!mo->num_open) { - /*do we simply stop the associated document or unload it??? to check*/ // gf_mo_stop(mo); - gf_odm_disconnect(mo->odm, 1); + gf_odm_disconnect(mo->odm, 2); + return; } } diff --git a/src/terminal/term_node_init.c b/src/terminal/term_node_init.c index 596e0f1..7f4556f 100644 --- a/src/terminal/term_node_init.c +++ b/src/terminal/term_node_init.c @@ -30,27 +30,43 @@ /*includes X3D nodes for WorldInfo, Inline and Key/String sensors*/ #include <gpac/nodes_x3d.h> #include <gpac/nodes_svg.h> +#include <gpac/options.h> +#ifndef GPAC_DISABLE_VRML -void InitMediaControl(GF_InlineScene *is, GF_Node *node); +void InitMediaControl(GF_Scene *scene, GF_Node *node); void MC_Modified(GF_Node *node); -void InitMediaSensor(GF_InlineScene *is, GF_Node *node); + +void InitMediaSensor(GF_Scene *scene, GF_Node *node); void MS_Modified(GF_Node *node); -void InitInline(GF_InlineScene *is, GF_Node *node); + +void gf_init_inline(GF_Scene *scene, GF_Node *node); +void gf_inline_on_modified(GF_Node *node); + +void gf_scene_init_storage(GF_Scene *scene, GF_Node *node); void TraverseWorldInfo(GF_Node *node, void *rs, Bool is_destroy) { - GF_InlineScene *is = (GF_InlineScene *)gf_node_get_private(node); - is->world_info = is_destroy ? NULL : (M_WorldInfo *) node; + GF_Scene *scene = (GF_Scene *)gf_node_get_private(node); + scene->world_info = is_destroy ? NULL : (M_WorldInfo *) node; } -void svg_traverse_title(GF_Node *node, void *rs, Bool is_destroy) +void TraverseKeyNavigator(GF_Node *node, void *rs, Bool is_destroy) { - GF_InlineScene *is = (GF_InlineScene *)gf_node_get_private(node); - is->world_info = is_destroy ? NULL : (M_WorldInfo *) node; + if (is_destroy) { + GF_Scene *scene = (GF_Scene *)gf_node_get_private(node); + gf_list_del_item(scene->keynavigators, node); + gf_sc_key_navigator_del(scene->root_od->term->compositor, node); + } } -void evaluate_term_cap(GF_Node *node) +void on_kn_set_focus(GF_Node*node, GF_Route *_route) +{ + GF_Scene *scene = (GF_Scene *)gf_node_get_private(node); + gf_sc_change_key_navigator(scene->root_od->term->compositor, node); +} + +void evaluate_term_cap(GF_Node *node, GF_Route *route) { GF_SystemRTInfo rti; Double fps; @@ -59,11 +75,11 @@ void evaluate_term_cap(GF_Node *node) u32 b_charge, b_level; M_TermCap *tc = (M_TermCap *)node; - GF_InlineScene *is = gf_node_get_private(node); + GF_Scene *scene = gf_node_get_private(node); tc->value = 0; switch (tc->capability) { case 0: /*framerate*/ - fps = gf_sc_get_fps(is->root_od->term->compositor, 1); + fps = gf_sc_get_fps(scene->root_od->term->compositor, 1); if (fps<=5.0) tc->value = 1; else if (fps<=10.0) tc->value = 2; else if (fps<=20.0) tc->value = 3; @@ -73,7 +89,7 @@ void evaluate_term_cap(GF_Node *node) case 1: /*colordepth*/ return; case 2: /*screensize*/ - height = is->root_od->term->compositor->display_height; + height = scene->root_od->term->compositor->display_height; if (height<200) tc->value = 1; else if (height<400) tc->value = 2; else if (height<800) tc->value = 3; @@ -110,13 +126,13 @@ void evaluate_term_cap(GF_Node *node) /*GPAC extensions*/ case 100: /*display width*/ - tc->value = is->root_od->term->compositor->display_width; + tc->value = scene->root_od->term->compositor->display_width; break; case 101: /*display height*/ - tc->value = is->root_od->term->compositor->display_height; + tc->value = scene->root_od->term->compositor->display_height; break; case 102: /*frame rate*/ - tc->value = (u32) gf_sc_get_fps(is->root_od->term->compositor, 1); + tc->value = (u32) gf_sc_get_fps(scene->root_od->term->compositor, 1); break; case 103: /*total CPU*/ if (!gf_sys_get_rti(200, &rti, 0) ) return; @@ -139,23 +155,23 @@ void evaluate_term_cap(GF_Node *node) tc->value = (u32) (rti.process_memory/1024); break; case 109: /*battery on/off*/ - gf_sys_get_battery_state(&b_on, &b_charge, &b_level); + gf_sys_get_battery_state(&b_on, &b_charge, &b_level, NULL, NULL); tc->value = b_on; break; case 110: /*battery charging*/ - gf_sys_get_battery_state(&b_on, &b_charge, &b_level); + gf_sys_get_battery_state(&b_on, &b_charge, &b_level, NULL, NULL); tc->value = b_charge; break; case 111: /*battery level*/ - gf_sys_get_battery_state(&b_on, &b_charge, &b_level); + gf_sys_get_battery_state(&b_on, &b_charge, &b_level, NULL, NULL); tc->value = b_level; break; case 112: /*audio vol*/ - tc->value = gf_sys_get_battery_state(&b_on, &b_charge, &b_level); + tc->value = gf_sc_get_option(scene->root_od->term->compositor, GF_OPT_AUDIO_VOLUME); break; case 113: /*audio pan*/ - tc->value = gf_sys_get_battery_state(&b_on, &b_charge, &b_level); + tc->value = gf_sc_get_option(scene->root_od->term->compositor, GF_OPT_AUDIO_PAN); break; default: return; @@ -163,92 +179,148 @@ void evaluate_term_cap(GF_Node *node) gf_node_event_out(node, 2); } -static void InitTermCap(GF_InlineScene *is, GF_Node *node) +static void InitTermCap(GF_Scene *scene, GF_Node *node) { M_TermCap *tc = (M_TermCap *)node; tc->on_evaluate = evaluate_term_cap; - gf_node_set_private(node, is); + gf_node_set_private(node, scene); /*evaluate upon init (cf BIFS spec)*/ - evaluate_term_cap(node); + evaluate_term_cap(node, NULL); } -void gf_term_on_node_init(void *_is, GF_Node *node) +#endif /*GPAC_DISABLE_VRML*/ + + +#ifndef GPAC_DISABLE_SVG +static void svg_traverse_title(GF_Node *node, void *rs, Bool is_destroy) { - GF_InlineScene *is = (GF_InlineScene *)_is; - if (!node || !is) return; + GF_Scene *scene = (GF_Scene *)gf_node_get_private(node); + scene->world_info = is_destroy ? NULL : node; +} +#endif + + +void gf_term_on_node_init(void *_scene, GF_Node *node) +{ + GF_Scene *scene = (GF_Scene *)_scene; + if (!node || !scene) return; switch (gf_node_get_tag(node)) { +#ifndef GPAC_DISABLE_VRML + case TAG_MPEG4_Inline: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Inline: - InitInline(is, node); break; +#endif + gf_init_inline(scene, node); break; case TAG_MPEG4_MediaBuffer: break; - case TAG_MPEG4_MediaControl: InitMediaControl(is, node); break; - case TAG_MPEG4_MediaSensor: InitMediaSensor(is, node); break; - case TAG_MPEG4_InputSensor: InitInputSensor(is, node); break; + case TAG_MPEG4_MediaControl: InitMediaControl(scene, node); break; + case TAG_MPEG4_MediaSensor: InitMediaSensor(scene, node); break; + case TAG_MPEG4_InputSensor: InitInputSensor(scene, node); break; /*BIFS nodes, get back to codec, but filter externProtos*/ case TAG_MPEG4_Conditional: break; case TAG_MPEG4_QuantizationParameter: break; /*world info is stored at the inline scene level*/ case TAG_MPEG4_WorldInfo: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_WorldInfo: +#endif gf_node_set_callback_function(node, TraverseWorldInfo); - gf_node_set_private(node, is); + gf_node_set_private(node, scene); break; - case TAG_X3D_KeySensor: InitKeySensor(is, node); break; - case TAG_X3D_StringSensor: InitStringSensor(is, node); break; +#ifndef GPAC_DISABLE_X3D + case TAG_X3D_KeySensor: InitKeySensor(scene, node); break; + case TAG_X3D_StringSensor: InitStringSensor(scene, node); break; +#endif case TAG_MPEG4_TermCap: - InitTermCap(is, node); break; + InitTermCap(scene, node); break; -#ifndef GPAC_DISABLE_SVG + case TAG_MPEG4_Storage: + gf_scene_init_storage(scene, node); break; + case TAG_MPEG4_KeyNavigator: + gf_node_set_callback_function(node, TraverseKeyNavigator); + gf_node_set_private(node, scene); + gf_list_add(scene->keynavigators, node); + ((M_KeyNavigator*)node)->on_setFocus = on_kn_set_focus; + break; + +#endif + + +#ifndef GPAC_DISABLE_SVG case TAG_SVG_title: gf_node_set_callback_function(node, svg_traverse_title); - gf_node_set_private(node, is); + gf_node_set_private(node, scene); break; #endif - default: gf_sc_on_node_init(is->root_od->term->compositor, node); break; + default: gf_sc_on_node_init(scene->root_od->term->compositor, node); break; } } void gf_term_on_node_modified(void *_is, GF_Node *node) { - GF_InlineScene *is = (GF_InlineScene *)_is; - if (!is) return; + GF_Scene *scene = (GF_Scene *)_is; + if (!scene) return; if (!node) { - gf_sc_invalidate(is->root_od->term->compositor, NULL); + gf_sc_invalidate(scene->root_od->term->compositor, NULL); return; } switch (gf_node_get_tag(node)) { +#ifndef GPAC_DISABLE_VRML case TAG_MPEG4_Inline: +#ifndef GPAC_DISABLE_X3D case TAG_X3D_Inline: - gf_inline_on_modified(node); break; - case TAG_MPEG4_MediaBuffer: break; - case TAG_MPEG4_MediaControl: MC_Modified(node); break; - case TAG_MPEG4_MediaSensor: MS_Modified(node); break; - case TAG_MPEG4_InputSensor: InputSensorModified(node); break; - case TAG_MPEG4_Conditional: break; - default: gf_sc_invalidate(is->root_od->term->compositor, node); break; +#endif + gf_inline_on_modified(node); + break; + case TAG_MPEG4_MediaBuffer: + break; + case TAG_MPEG4_MediaControl: + MC_Modified(node); + break; + case TAG_MPEG4_MediaSensor: + MS_Modified(node); + break; + case TAG_MPEG4_InputSensor: + InputSensorModified(node); + break; + case TAG_MPEG4_Conditional: + break; + case TAG_MPEG4_Storage: + break; +#endif + default: gf_sc_invalidate(scene->root_od->term->compositor, node); break; } } GF_EXPORT void gf_term_node_callback(void *_is, u32 type, GF_Node *n, void *param) { - if (type==GF_SG_CALLBACK_MODIFIED) gf_term_on_node_modified(_is, n); - else if (type==GF_SG_CALLBACK_INIT) gf_term_on_node_init(_is, n); + switch (type) { + case GF_SG_CALLBACK_MODIFIED: + gf_term_on_node_modified(_is, n); + break; + case GF_SG_CALLBACK_INIT: + gf_term_on_node_init(_is, n); + break; /*get all inline nodes using this subscene and bubble up...*/ - else if (type==GF_SG_CALLBACK_GRAPH_DIRTY) { + case GF_SG_CALLBACK_GRAPH_DIRTY: + { u32 i=0; GF_Node *root; - GF_InlineScene *is = (GF_InlineScene *)_is; - - while ((root=(GF_Node*)gf_list_enum(is->inline_nodes, &i))) { - gf_node_dirty_set(root, GF_SG_CHILD_DIRTY, 1); + GF_Scene *scene = (GF_Scene *)_is; + if (scene->root_od->mo) { + while ((root=(GF_Node*)gf_list_enum(scene->root_od->mo->nodes, &i))) { + gf_node_dirty_set(root, GF_SG_CHILD_DIRTY, 1); + } } } + break; + } } diff --git a/src/terminal/terminal.c b/src/terminal/terminal.c index e4a0d27..93e6ade 100644 --- a/src/terminal/terminal.c +++ b/src/terminal/terminal.c @@ -26,14 +26,18 @@ #include <gpac/internal/terminal_dev.h> #include <gpac/internal/compositor_dev.h> #include <gpac/internal/scenegraph_dev.h> -#include <gpac/modules/term_ext.h> #include <gpac/constants.h> #include <gpac/options.h> #include <gpac/network.h> #include <gpac/xml.h> + /*textual command processing*/ #include <gpac/scene_manager.h> +#include "media_memory.h" + +void gf_term_load_shortcuts(GF_Terminal *term); + u32 gf_term_get_time(GF_Terminal *term) { assert(term); @@ -91,7 +95,7 @@ static Bool term_script_action(void *opaque, u32 type, GF_Node *n, GF_JSAPIParam if (!term->user->EventProc) return 0; evt.type = GF_EVENT_SET_CAPTION; evt.caption.caption = param->uri.url; - term->user->EventProc(term->user->opaque, &evt); + gf_term_send_event(term, &evt); return 1; } if (type==GF_JSAPI_OP_GET_DCCI) { @@ -99,30 +103,29 @@ static Bool term_script_action(void *opaque, u32 type, GF_Node *n, GF_JSAPIParam return 1; } if (type==GF_JSAPI_OP_GET_SUBSCENE) { - GF_InlineScene *is = (GF_InlineScene *)gf_node_get_private(n); - param->scene = is->graph; + GF_Scene *scene = (GF_Scene *)gf_node_get_private(n); + param->scene = scene->graph; return 1; } - if (type==GF_JSAPI_OP_EVAL_IRI) { - GF_InlineScene *is; - if (!n) return 0; - is = (GF_InlineScene *)gf_sg_get_private(gf_node_get_graph(n)); - if (!param->uri.url) { - /*wait for compositor to be completely setup*/ - if (is->graph_attached && term->compositor->scene && !term->compositor->msg_type) return 1; - return 0; + + if (type==GF_JSAPI_OP_RESOLVE_URI) { + char *url; + char new_url[GF_MAX_PATH], localized_url[GF_MAX_PATH]; + Bool result; + GF_Scene *scene = (GF_Scene *)gf_sg_get_private(gf_node_get_graph(n)); + url = (char *)param->uri.url; + if (!url) { + param->uri.url = gf_strdup(scene->root_od->net_service->url); + param->uri.nb_params = 0; + return 1; } - /*todo*/ - return 0; - } - - if (type==GF_JSAPI_OP_GET_SCENE_URI) { - GF_InlineScene *is = (GF_InlineScene *)gf_sg_get_private(gf_node_get_graph(n)); - param->uri.url = is->root_od->net_service->url; - param->uri.nb_params = 0; + result = gf_term_relocate_url(term, url, scene->root_od->net_service->url, new_url, localized_url); + if (result && new_url) param->uri.url = gf_strdup(new_url); + else param->uri.url = gf_url_concatenate(scene->root_od->net_service->url, url); return 1; } + ret = gf_sc_script_action(term->compositor, type, n, param); if (ret) return ret; @@ -134,7 +137,7 @@ static Bool term_script_action(void *opaque, u32 type, GF_Node *n, GF_JSAPIParam evt.navigate.to_url = param->uri.url; evt.navigate.parameters = param->uri.params; evt.navigate.param_count = param->uri.nb_params; - return term->user->EventProc(term->user->opaque, &evt); + return gf_term_send_event(term, &evt); } else { /*TODO*/ return 0; @@ -144,6 +147,99 @@ static Bool term_script_action(void *opaque, u32 type, GF_Node *n, GF_JSAPIParam } +static Bool term_find_res(GF_TermLocales *loc, char *parent, char *path, char *relocated_path, char *localized_rel_path) +{ + FILE *f; + + if (loc->szAbsRelocatedPath) gf_free(loc->szAbsRelocatedPath); + loc->szAbsRelocatedPath = gf_url_concatenate(parent, path); + if (!loc->szAbsRelocatedPath) loc->szAbsRelocatedPath = gf_strdup(path); + + f = gf_f64_open(loc->szAbsRelocatedPath, "rb"); + if (f) { + fclose(f); + strcpy(localized_rel_path, path); + strcpy(relocated_path, loc->szAbsRelocatedPath); + return 1; + } + return 0; +} + +/* Checks if, for a given relative path, there exists a localized version in an given folder + if this is the case, it returns the absolute localized path, otherwise it returns null. + if the resource was localized, the last parameter is set to the localized relative path. +*/ +static Bool term_check_locales(void *__self, const char *locales_parent_path, const char *rel_path, char *relocated_path, char *localized_rel_path) +{ + char path[GF_MAX_PATH]; + const char *opt; + + GF_TermLocales *loc = (GF_TermLocales*)__self; + + /* Checks if the rel_path argument really contains a relative path (no ':', no '/' at the beginning) */ + if (strstr(rel_path, "://") || (rel_path[0]=='/') || strstr(rel_path, ":\\")) { + return 0; + } + + /*Checks if the absolute path is really absolute and points to a local file (no http or else) */ + if (!locales_parent_path || + (locales_parent_path && (locales_parent_path[0] != '/') && strstr(locales_parent_path, "://") && strnicmp(locales_parent_path, "file://", 7))) { + return 0; + } + opt = gf_cfg_get_key(loc->term->user->config, "Systems", "Language2CC"); + if (opt) { + if (!strcmp(opt, "*") || !strcmp(opt, "un") ) + opt = NULL; + } + + while (opt) { + char lan[100]; + char *sep; + char *sep_lang = strchr(opt, ';'); + if (sep_lang) sep_lang[0] = 0; + + while (strchr(" \t", opt[0])) + opt++; + + strcpy(lan, opt); + + if (sep_lang) { + sep_lang[0] = ';'; + opt = sep_lang+1; + } else { + opt = NULL; + } + + while (1) { + sep = strstr(lan, "-*"); + if (!sep) break; + strncpy(sep, sep+2, strlen(sep)-2); + } + + sprintf(path, "locales/%s/%s", lan, rel_path); + if (term_find_res(loc, (char *) locales_parent_path, (char *) path, relocated_path, localized_rel_path)) + return 1; + + /*recursively remove region (sub)tags*/ + while (1) { + sep = strrchr(lan, '-'); + if (!sep) break; + sep[0] = 0; + sprintf(path, "locales/%s/%s", lan, rel_path); + if (term_find_res(loc, (char *) locales_parent_path, (char *) path, relocated_path, localized_rel_path)) + return 1; + } + } + + if (term_find_res(loc, (char *) locales_parent_path, (char *) rel_path, relocated_path, localized_rel_path)) + return 1; + /* if we did not find the localized file, both the relocated and localized strings are NULL */ + strcpy(localized_rel_path, ""); + strcpy(relocated_path, ""); + return 0; +} + + static void gf_term_reload_cfg(GF_Terminal *term) { const char *sOpt; @@ -168,13 +264,15 @@ static void gf_term_reload_cfg(GF_Terminal *term) term->flags &= ~GF_TERM_SINGLE_CLOCK; sOpt = gf_cfg_get_key(term->user->config, "Compositor", "FrameRate"); - if (sOpt) { - fps = atof(sOpt); - term->frame_duration = (u32) (1000/fps); - gf_sc_set_fps(term->compositor, fps); + if (!sOpt) { + sOpt = "30.0"; + gf_cfg_set_key(term->user->config, "Compositor", "FrameRate", "30.0"); } + fps = atof(sOpt); + term->frame_duration = (u32) (1000/fps); + gf_sc_set_fps(term->compositor, fps); - if (term->user->init_flags & GF_TERM_NO_VISUAL_THREAD){ + if (term->user->init_flags & GF_TERM_NO_THREAD){ //gf_term_set_threading(term->mediaman, 1); } else { prio = GF_THREAD_PRIORITY_NORMAL; @@ -203,7 +301,7 @@ static void gf_term_reload_cfg(GF_Terminal *term) sOpt = gf_cfg_get_key(term->user->config, "Network", "DataTimeout"); if (sOpt) term->net_data_timeout = atoi(sOpt); - if (term->root_scene) gf_inline_set_duration(term->root_scene); + if (term->root_scene) gf_scene_set_duration(term->root_scene); #ifndef GPAC_DISABLE_SVG if (term->dcci_doc) { @@ -212,6 +310,8 @@ static void gf_term_reload_cfg(GF_Terminal *term) } #endif + gf_term_load_shortcuts(term); + /*reload compositor config*/ gf_sc_set_option(term->compositor, GF_OPT_RELOAD_CONFIG, 1); } @@ -223,7 +323,7 @@ static Bool gf_term_get_user_pass(void *usr_cbk, const char *site_url, char *usr evt.auth.site_url = site_url; evt.auth.user = usr_name; evt.auth.password = password; - return term->user->EventProc(term->user->opaque, &evt); + return gf_term_send_event(term, &evt); } @@ -248,8 +348,8 @@ static void gf_term_set_play_state(GF_Terminal *term, u32 PlayState, Bool reset_ /*only play/pause if connected*/ if (!term || !term->root_scene) return; /*and if not already paused/playing*/ - if (!term->play_state && !PlayState) return; - if (term->play_state && (PlayState==GF_STATE_PAUSED)) return; + if ((term->play_state == GF_STATE_PLAYING) && (PlayState == GF_STATE_PLAYING)) return; + if ((term->play_state != GF_STATE_PLAYING) && (PlayState == GF_STATE_PAUSED)) return; /*pause compositor*/ if ((PlayState==GF_STATE_PLAYING) && reset_audio) @@ -257,18 +357,23 @@ static void gf_term_set_play_state(GF_Terminal *term, u32 PlayState, Bool reset_ else gf_sc_set_option(term->compositor, GF_OPT_PLAY_STATE, PlayState); - if (PlayState==GF_STATE_STEP_PAUSE) PlayState = term->play_state ? GF_STATE_PLAYING : GF_STATE_PAUSED; + /* if the current play state in the terminal is the same as the requested play state, we don't touch the clocks + in particular, if the request is a step, if the clocks are paused, we leave them paused */ + if (PlayState==GF_STATE_STEP_PAUSE) { + //PlayState = term->play_state ? GF_STATE_PLAYING : GF_STATE_PAUSED; + return; + } + if (term->play_state == PlayState) return; term->play_state = PlayState; if (!pause_clocks) return; - gf_term_pause_all_clocks(term, PlayState ? 1 : 0); } -static void gf_term_connect_from_time_ex(GF_Terminal * term, const char *URL, u64 startTime, Bool pause_at_first_frame, Bool secondary_scene) +static void gf_term_connect_from_time_ex(GF_Terminal * term, const char *URL, u64 startTime, Bool pause_at_first_frame, Bool secondary_scene, const char *parent_path) { - GF_InlineScene *is; + GF_Scene *scene; GF_ObjectManager *odm; const char *main_url; if (!URL || !strlen(URL)) return; @@ -289,14 +394,14 @@ static void gf_term_connect_from_time_ex(GF_Terminal * term, const char *URL, u6 gf_term_lock_net(term, 1); GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Creating new root scene\n", URL)); /*create a new scene*/ - is = gf_inline_new(NULL); - gf_sg_set_script_action(is->graph, term_script_action, term); + scene = gf_scene_new(NULL); + gf_sg_set_script_action(scene->graph, term_script_action, term); odm = gf_odm_new(); - is->root_od = odm; - term->root_scene = is; + scene->root_od = odm; + term->root_scene = scene; odm->parentscene = NULL; - odm->subscene = is; + odm->subscene = scene; odm->term = term; GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] root scene created\n", URL)); gf_term_lock_net(term, 0); @@ -306,9 +411,53 @@ static void gf_term_connect_from_time_ex(GF_Terminal * term, const char *URL, u6 if (pause_at_first_frame) gf_term_set_play_state(term, GF_STATE_STEP_PAUSE, 0, 0); /*connect - we don't have any parentID */ - gf_term_connect_object(term, odm, (char *) URL, NULL); + gf_term_connect_object(term, odm, (char *) URL, (char*)parent_path); } +void gf_term_refresh_cache(GF_Config *cfg) +{ + u32 i, count; + count = gf_cfg_get_section_count(cfg); + for (i=0; i<count; i++) { + const char *opt; + u32 sec, frac, exp; + Bool force_delete; + const char *file; + const char *name = gf_cfg_get_section_name(cfg, i); + if (strncmp(name, "@cache=", 7)) continue; + + file = gf_cfg_get_key(cfg, name, "cacheFile"); + opt = gf_cfg_get_key(cfg, name, "expireAfterNTP"); + if (!opt) { + if (file) gf_delete_file((char*) file); + gf_cfg_del_section(cfg, name); + i--; + count--; + continue; + } + + force_delete = 0; + if (file) { + FILE *t = gf_f64_open(file, "r"); + if (!t) force_delete = 1; + else fclose(t); + } + sscanf(opt, "%u", &exp); + gf_net_get_ntp(&sec, &frac); + if (exp && (exp<sec)) force_delete=1; + + if (force_delete) { + if (file) gf_delete_file((char*) opt); + + gf_cfg_del_section(cfg, name); + i--; + count--; + continue; + } + } +} + + GF_EXPORT GF_Terminal *gf_term_new(GF_User *user) { @@ -320,18 +469,20 @@ GF_Terminal *gf_term_new(GF_User *user) GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Creating terminal\n")); - tmp = (GF_Terminal*)malloc(sizeof(GF_Terminal)); + tmp = (GF_Terminal*)gf_malloc(sizeof(GF_Terminal)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_Terminal)); /*just for safety*/ - gf_sys_init(); + gf_sys_init(0); tmp->user = user; /*this is not changeable at runtime*/ - if (user->init_flags & GF_TERM_NO_VISUAL_THREAD) { + if (user->init_flags & GF_TERM_NO_THREAD) { tmp->flags |= GF_TERM_DRAW_FRAME; + } else if (user->init_flags & GF_TERM_DRAW_FRAME) { + tmp->flags |= GF_TERM_DRAW_FRAME; } else { cf = gf_cfg_get_key(user->config, "Systems", "NoVisualThread"); if (!cf || !stricmp(cf, "no")) { @@ -344,7 +495,7 @@ GF_Terminal *gf_term_new(GF_User *user) /*setup scene compositor*/ tmp->compositor = gf_sc_new(user, !(tmp->flags & GF_TERM_DRAW_FRAME) , tmp); if (!tmp->compositor) { - free(tmp); + gf_free(tmp); return NULL; } GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] compositor loaded\n")); @@ -388,23 +539,42 @@ GF_Terminal *gf_term_new(GF_User *user) if (ifce) gf_list_add(tmp->extensions, ifce); } tmp->unthreaded_extensions = gf_list_new(); + tmp->evt_mx = gf_mx_new("Event Filter"); + tmp->event_filters = gf_list_new(); for (i=0; i< gf_list_count(tmp->extensions); i++) { GF_TermExt *ifce = gf_list_get(tmp->extensions, i); - if (!ifce->process(ifce, tmp, GF_TERM_EXT_START)) { + if (!ifce->process(ifce, GF_TERM_EXT_START, tmp)) { + gf_modules_close_interface((GF_BaseInterface *) ifce); gf_list_rem(tmp->extensions, i); i--; - } else if (ifce->caps & GF_TERM_EXT_CAP_NOT_THREADED) { + continue; + } + + if (ifce->caps & GF_TERM_EXTENSION_NOT_THREADED) gf_list_add(tmp->unthreaded_extensions, ifce); - } + + if (ifce->caps & GF_TERM_EXTENSION_FILTER_EVENT) + gf_list_add(tmp->event_filters, ifce); } + if (!gf_list_count(tmp->unthreaded_extensions)) { gf_list_del(tmp->unthreaded_extensions); tmp->unthreaded_extensions = NULL; } + if (!gf_list_count(tmp->event_filters)) { + gf_list_del(tmp->event_filters); + tmp->event_filters = NULL; + } + tmp->uri_relocators = gf_list_new(); + tmp->locales.relocate_uri = term_check_locales; + tmp->locales.term = tmp; + gf_list_add(tmp->uri_relocators, &tmp->locales); + tmp->speed_ratio = FIX_ONE; + gf_term_refresh_cache(user->config); cf = gf_cfg_get_key(user->config, "General", "GUIFile"); if (cf) { - gf_term_connect_from_time_ex(tmp, cf, 0, 0, 1); + gf_term_connect_from_time_ex(tmp, cf, 0, 0, 1, NULL); } return tmp; } @@ -441,12 +611,15 @@ GF_Err gf_term_del(GF_Terminal * term) /*unload extensions*/ for (i=0; i< gf_list_count(term->extensions); i++) { GF_TermExt *ifce = gf_list_get(term->extensions, i); - ifce->process(ifce, term, GF_TERM_EXT_STOP); + ifce->process(ifce, GF_TERM_EXT_STOP, NULL); } /*stop the media manager */ gf_term_stop_scheduler(term); + /*remove all event filters*/ + gf_list_reset(term->event_filters); + /*unload extensions*/ for (i=0; i< gf_list_count(term->extensions); i++) { GF_TermExt *ifce = gf_list_get(term->extensions, i); @@ -455,6 +628,14 @@ GF_Err gf_term_del(GF_Terminal * term) gf_list_del(term->extensions); if (term->unthreaded_extensions) gf_list_del(term->unthreaded_extensions); + gf_mx_p(term->evt_mx); + if (term->event_filters) { + gf_list_del(term->event_filters); + term->event_filters = NULL; + } + gf_mx_v(term->evt_mx); + gf_mx_del(term->evt_mx); + /*delete compositor before the input sensor stacks to avoid receiving events from the compositor when destroying these stacks*/ gf_sc_del(term->compositor); @@ -470,7 +651,12 @@ GF_Err gf_term_del(GF_Terminal * term) gf_list_del(term->media_queue); if (term->downloader) gf_dm_del(term->downloader); + if (term->locales.szAbsRelocatedPath) gf_free(term->locales.szAbsRelocatedPath); + gf_list_del(term->uri_relocators); + + if (term->dcci_doc) { +#ifndef GPAC_DISABLE_SCENE_DUMP if (term->dcci_doc->modified) { char *pref_file = (char *)gf_cfg_get_key(term->user->config, "General", "EnvironmentFile"); GF_SceneDumper *dumper = gf_sm_dumper_new(term->dcci_doc, pref_file, ' ', GF_SM_DUMP_AUTO_XML); @@ -478,12 +664,13 @@ GF_Err gf_term_del(GF_Terminal * term) e = gf_sm_dump_graph(dumper, 1, 0); gf_sm_dumper_del(dumper); } +#endif gf_sg_del(term->dcci_doc); } gf_mx_del(term->net_mx); gf_sys_close(); - free(term); + gf_free(term); GF_LOG(GF_LOG_DEBUG, GF_LOG_MEDIA, ("[Terminal] Terminal destroyed\n")); return e; } @@ -491,8 +678,13 @@ GF_Err gf_term_del(GF_Terminal * term) void gf_term_message(GF_Terminal *term, const char *service, const char *message, GF_Err error) { + GF_Event evt; if (!term || !term->user) return; - GF_USER_MESSAGE(term->user, service, message, error); + evt.type = GF_EVENT_MESSAGE; + evt.message.service = service; + evt.message.message = message; + evt.message.error = error; + gf_term_send_event(term, &evt); } GF_Err gf_term_step_clocks(GF_Terminal * term, u32 ms_diff) @@ -501,7 +693,7 @@ GF_Err gf_term_step_clocks(GF_Terminal * term, u32 ms_diff) GF_ClientService *ns; /*only play/pause if connected*/ if (!term || !term->root_scene || !term->root_scene->root_od) return GF_BAD_PARAM; - if (!term->play_state) return GF_BAD_PARAM; + if (term->play_state == GF_STATE_PLAYING) return GF_BAD_PARAM; gf_sc_lock(term->compositor, 1); i=0; @@ -513,7 +705,7 @@ GF_Err gf_term_step_clocks(GF_Terminal * term, u32 ms_diff) } } term->compositor->step_mode = 1; - term->compositor->draw_next_frame = 1; + gf_sc_next_frame_state(term->compositor, GF_SC_DRAW_FRAME); gf_sc_lock(term->compositor, 0); return GF_OK; } @@ -521,13 +713,19 @@ GF_Err gf_term_step_clocks(GF_Terminal * term, u32 ms_diff) GF_EXPORT void gf_term_connect_from_time(GF_Terminal * term, const char *URL, u64 startTime, Bool pause_at_first_frame) { - gf_term_connect_from_time_ex(term, URL, startTime, pause_at_first_frame, 0); + gf_term_connect_from_time_ex(term, URL, startTime, pause_at_first_frame, 0, NULL); } GF_EXPORT void gf_term_connect(GF_Terminal * term, const char *URL) { - gf_term_connect_from_time(term, URL, 0, 0); + gf_term_connect_from_time_ex(term, URL, 0, 0, 0, NULL); +} + +GF_EXPORT +void gf_term_connect_with_path(GF_Terminal * term, const char *URL, const char *parent_path) +{ + gf_term_connect_from_time_ex(term, URL, 0, 0, 0, parent_path); } GF_EXPORT @@ -535,12 +733,12 @@ void gf_term_disconnect(GF_Terminal *term) { if (!term->root_scene) return; /*resume*/ - if (term->play_state) gf_term_set_play_state(term, GF_STATE_PLAYING, 1, 1); + if (term->play_state != GF_STATE_PLAYING) gf_term_set_play_state(term, GF_STATE_PLAYING, 1, 1); if (term->root_scene->root_od) { gf_odm_disconnect(term->root_scene->root_od, 1); } else { - gf_inline_del(term->root_scene); + gf_scene_del(term->root_scene); term->root_scene = NULL; } while (term->root_scene || gf_list_count(term->net_services_to_remove)) { @@ -614,42 +812,21 @@ Double gf_term_get_simulation_frame_rate(GF_Terminal *term) } -/*returns 0 if any of the clock still hasn't seen EOS*/ -u32 Term_CheckClocks(GF_ClientService *ns, GF_InlineScene *is) -{ - GF_Clock *ck; - u32 i; - if (is) { - GF_ObjectManager *odm; - if (is->root_od->net_service != ns) { - if (!Term_CheckClocks(is->root_od->net_service, is)) return 0; - } - i=0; - while ( (odm = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i)) ) { - if (odm->net_service != ns) { - if (!Term_CheckClocks(odm->net_service, NULL)) return 0; - } - } - } - i=0; - while ( (ck = (GF_Clock *)gf_list_enum(ns->Clocks, &i) ) ) { - if (!ck->has_seen_eos) return 0; - } - return 1; -} -u32 Term_CheckIsOver(GF_Terminal *term) +u32 gf_term_check_end_of_scene(GF_Terminal *term, Bool skip_interactions) { if (!term->root_scene) return 1; - /*if input sensors consider the scene runs forever*/ - if (gf_list_count(term->input_streams)) return 0; - if (gf_list_count(term->x3d_sensors)) return 0; - + if (!skip_interactions) { + /*if input sensors consider the scene runs forever*/ + if (gf_list_count(term->input_streams)) return 0; + if (gf_list_count(term->x3d_sensors)) return 0; + } /*check no clocks are still running*/ - if (!Term_CheckClocks(term->root_scene->root_od->net_service, term->root_scene)) return 0; + if (!gf_scene_check_clocks(term->root_scene->root_od->net_service, term->root_scene)) return 0; if (term->root_scene->is_dynamic_scene) return 1; + /*ask compositor if there are sensors*/ - return gf_sc_get_option(term->compositor, GF_OPT_IS_FINISHED); + return gf_sc_get_option(term->compositor, skip_interactions ? GF_OPT_IS_OVER : GF_OPT_IS_FINISHED); } /*get rendering option*/ @@ -659,7 +836,8 @@ u32 gf_term_get_option(GF_Terminal * term, u32 type) if (!term) return 0; switch (type) { case GF_OPT_HAS_JAVASCRIPT: return gf_sg_has_scripting(); - case GF_OPT_IS_FINISHED: return Term_CheckIsOver(term); + case GF_OPT_IS_FINISHED: return gf_term_check_end_of_scene(term, 0); + case GF_OPT_IS_OVER: return gf_term_check_end_of_scene(term, 1); case GF_OPT_PLAY_STATE: if (term->compositor->step_mode) return GF_STATE_STEP_PAUSE; if (term->root_scene) { @@ -672,7 +850,7 @@ u32 gf_term_get_option(GF_Terminal * term, u32 type) if (ck->Buffering) return GF_STATE_STEP_PAUSE; } - if (term->play_state) return GF_STATE_PAUSED; + if (term->play_state != GF_STATE_PLAYING) return GF_STATE_PAUSED; return GF_STATE_PLAYING; case GF_OPT_MEDIA_CACHE: if (!term->enable_cache) return GF_MEDIA_CACHE_DISABLED; @@ -702,19 +880,32 @@ void gf_term_handle_services(GF_Terminal *term) /*play ODs that need it*/ while (gf_list_count(term->media_queue)) { + Bool destroy = 0; GF_ObjectManager *odm = (GF_ObjectManager *)gf_list_get(term->media_queue, 0); gf_list_rem(term->media_queue, 0); /*unlock net before sending play/pause*/ gf_mx_v(term->net_mx); - /*this is a stop*/ - if (odm->media_start_time == (u64)-1) { - odm->media_start_time = 0; - gf_odm_stop(odm, 0); - } - /*this is a play*/ - else { + + switch (odm->action_type) { + case GF_ODM_ACTION_STOP: + if (odm->codec && odm->codec->CB && (odm->codec->CB->Capacity==1)) { + if (odm->mo->OD_ID==GF_MEDIA_EXTERNAL_ID) destroy = 1; + else if (odm->OD && (odm->OD->objectDescriptorID==GF_MEDIA_EXTERNAL_ID)) destroy = 1; + } + if (destroy) { + gf_odm_disconnect(odm, 2); + } else { + gf_odm_stop(odm, 0); + } + break; + case GF_ODM_ACTION_PLAY: gf_odm_play(odm); + break; + case GF_ODM_ACTION_DELETE: + gf_odm_disconnect(odm, 2); + break; } + odm->action_type = GF_ODM_ACTION_PLAY; /*relock net before sending play/pause*/ gf_mx_p(term->net_mx); @@ -754,7 +945,7 @@ void gf_term_handle_services(GF_Terminal *term) count = gf_list_count(term->unthreaded_extensions); for (i=0; i<count; i++) { GF_TermExt *ifce = gf_list_get(term->unthreaded_extensions, i); - ifce->process(ifce, term, GF_TERM_EXT_PROCESS); + ifce->process(ifce, GF_TERM_EXT_PROCESS, NULL); } } @@ -768,8 +959,10 @@ void gf_term_handle_services(GF_Terminal *term) if (term->reload_state == 2) { if (gf_list_count(term->net_services)) return; term->reload_state = 0; - gf_term_connect(term, term->reload_url); - free(term->reload_url); + if (term->reload_url) { + gf_term_connect(term, term->reload_url); + gf_free(term->reload_url); + } term->reload_url = NULL; } } @@ -868,7 +1061,7 @@ void gf_term_service_media_event(GF_ObjectManager *odm, u32 event_type) GF_DOMMediaAccessEvent mae; GF_DOM_Event evt; GF_ObjectManager *an_od; - GF_InlineScene *is; + GF_Scene *scene; if (!odm) return; if (odm->mo) { @@ -894,12 +1087,12 @@ void gf_term_service_media_event(GF_ObjectManager *odm, u32 event_type) transport = 2; min_time = min_buffer = (u32) -1; - is = odm->subscene ? odm->subscene : odm->parentscene; + scene = odm->subscene ? odm->subscene : odm->parentscene; /*get buffering on root OD*/ - mae_collect_info(odm->net_service, is->root_od, &mae, transport, &min_time, &min_buffer); + mae_collect_info(odm->net_service, scene->root_od, &mae, transport, &min_time, &min_buffer); /*get buffering on all ODs*/ i=0; - while ((an_od = (GF_ObjectManager*)gf_list_enum(is->ODlist, &i))) { + while ((an_od = (GF_ObjectManager*)gf_list_enum(scene->resources, &i))) { mae_collect_info(odm->net_service, an_od, &mae, transport, &min_time, &min_buffer); } @@ -919,7 +1112,7 @@ void gf_term_service_media_event(GF_ObjectManager *odm, u32 event_type) gf_dom_event_fire(node, &evt); } if (!count) { - GF_Node *root = gf_sg_get_root_node(is->graph); + GF_Node *root = gf_sg_get_root_node(scene->graph); if (root) gf_dom_event_fire(root, &evt); } if (locked) gf_sc_lock(odm->term->compositor, 0); @@ -927,14 +1120,68 @@ void gf_term_service_media_event(GF_ObjectManager *odm, u32 event_type) } +/* Browses all registered relocators (ZIP-based, ISOFF-based or file-system-based to relocate a URI based on the locale */ +Bool gf_term_relocate_url(GF_Terminal *term, const char *service_url, const char *parent_url, char *out_relocated_url, char *out_localized_url) +{ + u32 i, count; + + i=0; + count = gf_list_count(term->uri_relocators); + for (i=0; i<count; i++) { + Bool result; + GF_URIRelocator *uri_relocator = gf_list_get(term->uri_relocators, i); + result = uri_relocator->relocate_uri(uri_relocator, parent_url, service_url, out_relocated_url, out_localized_url); + if (result) return 1; + } + return 0; +} + /*connects given OD manager to its URL*/ -void gf_term_connect_object(GF_Terminal *term, GF_ObjectManager *odm, char *serviceURL, GF_ClientService *ParentService) +void gf_term_connect_object(GF_Terminal *term, GF_ObjectManager *odm, char *serviceURL, char *parent_url) { GF_ClientService *ns; - u32 i; + u32 i, count; GF_Err e; + Bool reloc_result; + char relocated_url[GF_MAX_PATH], localized_url[GF_MAX_PATH]; gf_term_lock_net(term, 1); + /*try to relocate the url*/ + reloc_result = gf_term_relocate_url(term, serviceURL, parent_url, relocated_url, localized_url); + if (reloc_result) serviceURL = (char *) relocated_url; + + /*check cache*/ + if (parent_url) { + count = gf_cfg_get_section_count(term->user->config); + for (i=0; i<count; i++) { + u32 exp, sec, frac; + const char *opt, *service_cache; + const char *name = gf_cfg_get_section_name(term->user->config, i); + if (strncmp(name, "@cache=", 7)) continue; + opt = gf_cfg_get_key(term->user->config, name, "serviceURL"); + if (!opt || stricmp(opt, parent_url)) continue; + opt = gf_cfg_get_key(term->user->config, name, "cacheName"); + if (!opt || stricmp(opt, serviceURL)) continue; + + service_cache = (char*)gf_cfg_get_key(term->user->config, name, "cacheFile"); + opt = gf_cfg_get_key(term->user->config, name, "expireAfterNTP"); + if (opt) { + sscanf(opt, "%u", &exp); + gf_net_get_ntp(&sec, &frac); + if (exp && (exp<sec)) { + opt = gf_cfg_get_key(term->user->config, name, "cacheFile"); + if (opt) gf_delete_file((char*) opt); + gf_cfg_del_section(term->user->config, name); + i--; + count--; + service_cache = NULL; + } + } + if (service_cache) serviceURL = (char *)service_cache; + break; + } + } + /*for remoteODs/dynamic ODs, check if one of the running service cannot be used*/ i=0; while ( (ns = (GF_ClientService*)gf_list_enum(term->net_services, &i)) ) { @@ -958,7 +1205,7 @@ void gf_term_connect_object(GF_Terminal *term, GF_ObjectManager *odm, char *serv } } - odm->net_service = gf_term_service_new(term, odm, serviceURL, ParentService, &e); + odm->net_service = gf_term_service_new(term, odm, serviceURL, reloc_result ? NULL : parent_url, &e); if (!odm->net_service) { gf_term_lock_net(term, 0); gf_term_message(term, serviceURL, "Cannot open service", e); @@ -995,7 +1242,7 @@ GF_Err gf_term_connect_remote_channel(GF_Terminal *term, GF_Channel *ch, char *U } } /*use parent OD for parent service*/ - ns = gf_term_service_new(term, NULL, URL, ch->odm->net_service, &e); + ns = gf_term_service_new(term, NULL, URL, ch->odm->net_service->url, &e); if (!ns) return e; ch->service = ns; ns->ifce->ConnectService(ns->ifce, ns, ns->url); @@ -1005,14 +1252,22 @@ GF_Err gf_term_connect_remote_channel(GF_Terminal *term, GF_Channel *ch, char *U } GF_EXPORT -u32 gf_term_play_from_time(GF_Terminal *term, u64 from_time, Bool pause_at_first_frame) +u32 gf_term_play_from_time(GF_Terminal *term, u64 from_time, u32 pause_at_first_frame) { if (!term || !term->root_scene || !term->root_scene->root_od) return 0; if (term->root_scene->root_od->flags & GF_ODM_NO_TIME_CTRL) return 1; + if (pause_at_first_frame==2) { + if (gf_term_get_option(term, GF_OPT_PLAY_STATE) != GF_STATE_PLAYING) + pause_at_first_frame = 1; + else + pause_at_first_frame = 0; + } + /*for dynamic scene OD ressources are static and all object use the same clock, so don't restart the root OD, just act as a mediaControl on all playing streams*/ if (term->root_scene->is_dynamic_scene) { + /*exit pause mode*/ gf_term_set_play_state(term, GF_STATE_PLAYING, 1, 1); @@ -1020,7 +1275,7 @@ u32 gf_term_play_from_time(GF_Terminal *term, u64 from_time, Bool pause_at_first gf_term_set_play_state(term, GF_STATE_STEP_PAUSE, 0, 0); gf_sc_lock(term->compositor, 1); - gf_inline_restart_dynamic(term->root_scene, from_time); + gf_scene_restart_dynamic(term->root_scene, from_time); gf_sc_lock(term->compositor, 0); return 2; } @@ -1029,13 +1284,15 @@ u32 gf_term_play_from_time(GF_Terminal *term, u64 from_time, Bool pause_at_first gf_term_set_play_state(term, GF_STATE_PAUSED, 0, 1); /*stop root*/ gf_odm_stop(term->root_scene->root_od, 1); - gf_inline_disconnect(term->root_scene, 0); + gf_scene_disconnect(term->root_scene, 0); /*make sure we don't have OD queued*/ while (gf_list_count(term->media_queue)) gf_list_rem(term->media_queue, 0); term->root_scene->root_od->media_start_time = from_time; - gf_odm_start(term->root_scene->root_od); - gf_term_set_play_state(term, pause_at_first_frame ? GF_STATE_STEP_PAUSE : GF_STATE_PLAYING, 0, 1); + gf_odm_start(term->root_scene->root_od, 0); + gf_term_set_play_state(term, GF_STATE_PLAYING, 0, 1); + if (pause_at_first_frame) + gf_sc_set_option(term->compositor, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); return 2; } @@ -1075,11 +1332,13 @@ GF_EXPORT void gf_term_navigate_to(GF_Terminal *term, const char *toURL) { if (!toURL && !term->root_scene) return; - if (term->reload_url) free(term->reload_url); + if (term->reload_url) gf_free(term->reload_url); term->reload_url = NULL; - if (term->root_scene) - term->reload_url = gf_url_concatenate(term->root_scene->root_od->net_service->url, toURL); - if (!term->reload_url) term->reload_url = strdup(toURL); + if (toURL) { + if (term->root_scene && term->root_scene->root_od && term->root_scene->root_od->net_service) + term->reload_url = gf_url_concatenate(term->root_scene->root_od->net_service->url, toURL); + if (!term->reload_url) term->reload_url = gf_strdup(toURL); + } term->reload_state = 1; } @@ -1103,24 +1362,24 @@ GF_Err gf_term_add_object(GF_Terminal *term, const char *url, Bool auto_play) MFURL mfurl; if (!url || !term || !term->root_scene || !term->root_scene->is_dynamic_scene) return GF_BAD_PARAM; - sfurl.OD_ID = GF_ESM_DYNAMIC_OD_ID; + sfurl.OD_ID = GF_MEDIA_EXTERNAL_ID; sfurl.url = (char *) url; mfurl.count = 1; mfurl.vals = &sfurl; /*only text tracks are supported for now...*/ - mo = gf_inline_get_media_object(term->root_scene, &mfurl, GF_MEDIA_OBJECT_TEXT, 1); + mo = gf_scene_get_media_object(term->root_scene, &mfurl, GF_MEDIA_OBJECT_TEXT, 1); if (mo) { /*check if we must deactivate it*/ if (mo->odm) { if (mo->num_open && !auto_play) { - gf_inline_select_object(term->root_scene, mo->odm); + gf_scene_select_object(term->root_scene, mo->odm); } else { mo->odm->OD_PL = auto_play ? 1 : 0; } } else { - gf_list_del_item(term->root_scene->media_objects, mo); + gf_list_del_item(term->root_scene->scene_objects, mo); gf_sg_vrml_mf_reset(&mo->URLs, GF_SG_VRML_MFURL); - free(mo); + gf_free(mo); mo = NULL; } } @@ -1131,7 +1390,7 @@ GF_Err gf_term_add_object(GF_Terminal *term, const char *url, Bool auto_play) void gf_term_attach_service(GF_Terminal *term, GF_InputService *service_hdl) { Bool net_check_interface(GF_InputService *ifce); - GF_InlineScene *is; + GF_Scene *scene; GF_ObjectManager *odm; if (!net_check_interface(service_hdl)) return; @@ -1140,21 +1399,21 @@ void gf_term_attach_service(GF_Terminal *term, GF_InputService *service_hdl) gf_term_lock_net(term, 1); /*create a new scene*/ - is = gf_inline_new(NULL); + scene = gf_scene_new(NULL); odm = gf_odm_new(); - gf_sg_set_script_action(is->graph, term_script_action, term); + gf_sg_set_script_action(scene->graph, term_script_action, term); - is->root_od = odm; - term->root_scene = is; + scene->root_od = odm; + term->root_scene = scene; odm->parentscene = NULL; - odm->subscene = is; + odm->subscene = scene; odm->term = term; GF_SAFEALLOC(odm->net_service , GF_ClientService); odm->net_service->term = term; odm->net_service->owner = odm; odm->net_service->ifce = service_hdl; - odm->net_service->url = strdup("Internal Service Handler"); + odm->net_service->url = gf_strdup("Internal Service Handler"); odm->net_service->Clocks = gf_list_new(); gf_list_add(term->net_services, odm->net_service); @@ -1185,7 +1444,7 @@ GF_Err gf_term_scene_update(GF_Terminal *term, char *type, char *com) if (!term->root_scene) { gf_term_lock_net(term, 1); /*create a new scene*/ - term->root_scene = gf_inline_new(NULL); + term->root_scene = gf_scene_new(NULL); gf_sg_set_script_action(term->root_scene->graph, term_script_action, term); term->root_scene->root_od = gf_odm_new(); term->root_scene->root_od->parentscene = NULL; @@ -1218,16 +1477,16 @@ GF_Err gf_term_scene_update(GF_Terminal *term, char *type, char *com) if (com[i]=='<') is_xml = 1; load.type = is_xml ? GF_SM_LOAD_XMTA : GF_SM_LOAD_BT; - time = gf_inline_get_time(term->root_scene); + time = gf_scene_get_time(term->root_scene); if (type && (!stricmp(type, "application/x-laser+xml") || !stricmp(type, "laser"))) { load.type = GF_SM_LOAD_XSR; - time = gf_inline_get_time(term->root_scene); + time = gf_scene_get_time(term->root_scene); } else if (type && (!stricmp(type, "image/svg+xml") || !stricmp(type, "svg")) ) { load.type = GF_SM_LOAD_XSR; - time = gf_inline_get_time(term->root_scene); + time = gf_scene_get_time(term->root_scene); } else if (type && (!stricmp(type, "model/x3d+xml") || !stricmp(type, "x3d")) ) load.type = GF_SM_LOAD_X3D; else if (type && (!stricmp(type, "model/x3d+vrml") || !stricmp(type, "x3dv")) ) load.type = GF_SM_LOAD_X3DV; @@ -1238,12 +1497,12 @@ GF_Err gf_term_scene_update(GF_Terminal *term, char *type, char *com) tag = gf_node_get_tag(gf_sg_get_root_node(term->root_scene->graph)); if (tag >= GF_NODE_RANGE_FIRST_SVG) { load.type = GF_SM_LOAD_XSR; - time = gf_inline_get_time(term->root_scene); + time = gf_scene_get_time(term->root_scene); } else if (tag>=GF_NODE_RANGE_FIRST_X3D) { load.type = is_xml ? GF_SM_LOAD_X3D : GF_SM_LOAD_X3DV; } else { load.type = is_xml ? GF_SM_LOAD_XMTA : GF_SM_LOAD_BT; - time = gf_inline_get_time(term->root_scene); + time = gf_scene_get_time(term->root_scene); } } @@ -1267,7 +1526,7 @@ GF_Err gf_term_scene_update(GF_Terminal *term, char *type, char *com) // load.ctx->scene_height = term->compositor->height; } gf_sg_set_scene_size_info(term->root_scene->graph, load.ctx->scene_width, load.ctx->scene_height, load.ctx->is_pixel_metrics); - gf_inline_attach_to_compositor(term->root_scene); + gf_scene_attach_to_compositor(term->root_scene); } gf_sm_del(load.ctx); return e; @@ -1286,20 +1545,23 @@ GF_Err gf_term_release_screen_buffer(GF_Terminal *term, GF_VideoSurface *framebu } -static void gf_term_sample_scenetime(GF_InlineScene *scene) +static void gf_term_sample_scenetime(GF_Scene *scene) { u32 i, count; - gf_inline_sample_time(scene); - count = gf_list_count(scene->ODlist); + gf_term_lock_net(scene->root_od->term, 1); + gf_scene_sample_time(scene); + count = gf_list_count(scene->resources); for (i=0; i<count; i++) { - GF_ObjectManager *odm = gf_list_get(scene->ODlist, i); + GF_ObjectManager *odm = gf_list_get(scene->resources, i); if (odm->subscene) gf_term_sample_scenetime(odm->subscene); } + gf_term_lock_net(scene->root_od->term, 0); } -void gf_term_sample_clocks(GF_Terminal *term) +u32 gf_term_sample_clocks(GF_Terminal *term) { gf_term_sample_scenetime(term->root_scene); + return (u32) (1000*term->root_scene->simulation_time); } const char *gf_term_get_text_selection(GF_Terminal *term, Bool probe_only) @@ -1320,4 +1582,345 @@ GF_Err gf_term_paste_text(GF_Terminal *term, const char *txt, Bool probe_only) return gf_sc_paste_text(term->compositor, txt); } +Bool gf_term_forward_event(GF_Terminal *term, GF_Event *evt, Bool consumed) +{ + if (!term) return 0; + + if (term->event_filters) { + GF_TermExt *ext; + u32 i=0; + gf_mx_p(term->evt_mx); + while ((ext=gf_list_enum(term->event_filters, &i))) { + if (ext->process(ext, GF_TERM_EXT_EVENT, evt)) { + gf_mx_v(term->evt_mx); + return 0; + } + } + gf_mx_v(term->evt_mx); + } + + if (!consumed && term->user->EventProc) + return term->user->EventProc(term->user->opaque, evt); + + return 0; +} + +GF_EXPORT +Bool gf_term_send_event(GF_Terminal *term, GF_Event *evt) +{ + return gf_term_forward_event(term, evt, 0); +} + +void gf_term_register_event_filter(GF_Terminal *term, GF_TermExt *filter) +{ + if (!term || !filter) return; + if (!term->event_filters) { + term->event_filters = gf_list_new(); + } + gf_mx_p(term->evt_mx); + if (gf_list_find(term->event_filters, filter)<0) { + gf_list_add(term->event_filters, filter); + } + gf_mx_v(term->evt_mx); +} + +void gf_term_unregister_event_filter(GF_Terminal *term, GF_TermExt *filter) +{ + if (!term || !filter) return; + if (!term->event_filters) return; + + gf_mx_p(term->evt_mx); + gf_list_del_item(term->event_filters, filter); + if (!gf_list_count(term->event_filters)) { + gf_list_del(term->event_filters); + term->event_filters = NULL; + } + gf_mx_v(term->evt_mx); +} + +enum +{ + GF_ACTION_PLAY, + GF_ACTION_STOP, + GF_ACTION_STEP, + GF_ACTION_EXIT, + GF_ACTION_MUTE, + GF_ACTION_VOLUP, + GF_ACTION_VOLDOWN, + GF_ACTION_JUMP_FORWARD, + GF_ACTION_JUMP_BACKWARD, + GF_ACTION_JUMP_START, + GF_ACTION_JUMP_END, + GF_ACTION_VERY_FAST_FORWARD, + GF_ACTION_FAST_FORWARD, + GF_ACTION_SLOW_FORWARD, + GF_ACTION_VERY_FAST_REWIND, + GF_ACTION_FAST_REWIND, + GF_ACTION_SLOW_REWIND, + GF_ACTION_NEXT, + GF_ACTION_PREVIOUS, +}; + +static void set_clocks_speed(GF_Terminal *term, Fixed ratio) +{ + u32 i, j; + GF_ClientService *ns; + + /*pause all clocks on all services*/ + i=0; + while ( (ns = (GF_ClientService*)gf_list_enum(term->net_services, &i)) ) { + GF_Clock *ck; + j=0; + while ( (ck = (GF_Clock *)gf_list_enum(ns->Clocks, &j)) ) { + Fixed s = gf_mulfix(ck->speed, ratio); + gf_clock_set_speed(ck, s); + } + } +} + +void gf_term_set_speed(GF_Terminal *term, Fixed speed) +{ + Double fps; + u32 i, j; + const char *opt; + GF_ClientService *ns; + if (!speed) return; + + /*adjust all clocks on all services*/ + i=0; + while ( (ns = (GF_ClientService*)gf_list_enum(term->net_services, &i)) ) { + GF_Clock *ck; + j=0; + while ( (ck = (GF_Clock *)gf_list_enum(ns->Clocks, &j)) ) { + gf_clock_set_speed(ck, speed); + } + } + + opt = gf_cfg_get_key(term->user->config, "Compositor", "FrameRate"); + if (!opt) opt="30.0"; + + fps = atof(opt); + fps *= FIX2FLT(speed); + if (fps>100) fps = 1000; + term->frame_duration = (u32) (1000/fps); + gf_sc_set_fps(term->compositor, fps); +} + +void gf_term_process_shortcut(GF_Terminal *term, GF_Event *ev) +{ + GF_Event evt; + if (ev->type==GF_EVENT_KEYDOWN) { + u32 i; + u8 mod = 0; + if (ev->key.flags & GF_KEY_MOD_CTRL) mod |= GF_KEY_MOD_CTRL; + if (ev->key.flags & GF_KEY_MOD_ALT) mod |= GF_KEY_MOD_ALT; + + for (i=0; i<MAX_SHORTCUTS; i++) { + u32 val; + if (!term->shortcuts[i].code) break; + if (term->shortcuts[i].mods!=mod) continue; + if (term->shortcuts[i].code!=ev->key.key_code) continue; + + switch (term->shortcuts[i].action) { + case GF_ACTION_PLAY: + if (gf_term_get_option(term, GF_OPT_PLAY_STATE) == GF_STATE_PAUSED) { + gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_PLAYING); + } else if (term->speed_ratio != FIX_ONE) { + set_clocks_speed(term, gf_divfix(1, term->speed_ratio) ); + term->speed_ratio = FIX_ONE; + } else { + gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_PAUSED); + } + break; + case GF_ACTION_STOP: + gf_term_play_from_time(term, 0, 1); + break; + case GF_ACTION_NEXT: + evt.type = GF_EVENT_KEYDOWN; + evt.key.key_code = GF_KEY_MEDIANEXTTRACK; + gf_term_send_event(term, &evt); + break; + case GF_ACTION_PREVIOUS: + evt.type = GF_EVENT_KEYDOWN; + evt.key.key_code = GF_KEY_MEDIAPREVIOUSTRACK; + gf_term_send_event(term, &evt); + break; + + case GF_ACTION_STEP: + gf_term_set_option(term, GF_OPT_PLAY_STATE, GF_STATE_STEP_PAUSE); + break; + case GF_ACTION_EXIT: + evt.type = GF_EVENT_QUIT; + gf_term_send_event(term, &evt); + break; + case GF_ACTION_MUTE: + gf_term_set_option(term, GF_OPT_AUDIO_MUTE, gf_term_get_option(term, GF_OPT_AUDIO_MUTE) ? 0 : 1); + break; + case GF_ACTION_VOLUP: + val = gf_term_get_option(term, GF_OPT_AUDIO_VOLUME); + if (val<95) val += 5; + else val = 100; + gf_term_set_option(term, GF_OPT_AUDIO_VOLUME, val); + break; + case GF_ACTION_VOLDOWN: + val = gf_term_get_option(term, GF_OPT_AUDIO_VOLUME); + if (val>5) val -= 5; + else val = 0; + gf_term_set_option(term, GF_OPT_AUDIO_VOLUME, val); + break; + case GF_ACTION_JUMP_FORWARD: + case GF_ACTION_JUMP_BACKWARD: + case GF_ACTION_VERY_FAST_REWIND: + case GF_ACTION_FAST_REWIND: + case GF_ACTION_SLOW_REWIND: + if (term->root_scene && !(term->root_scene->root_od->flags & GF_ODM_NO_TIME_CTRL) ) { + s32 res; + u32 dur = (u32) term->root_scene->duration ; + val = gf_term_get_time_in_ms(term); + res = val; + switch (term->shortcuts[i].action) { + case GF_ACTION_JUMP_BACKWARD: + case GF_ACTION_FAST_REWIND: + res -= (s32) (5*dur/100); + if (res<0) res = 0; + break; + case GF_ACTION_VERY_FAST_REWIND: + res -= (s32) (10*dur/100); + if (res<0) res = 0; + break; + case GF_ACTION_SLOW_REWIND: + res -= (s32) (dur/100); + if (res<0) res = 0; + break; + default: + res += (s32) (5*dur/100); + if (res > (s32)dur) res = dur; + break; + } + gf_term_play_from_time(term, res, 2); + } + break; + case GF_ACTION_JUMP_START: + if (term->root_scene && !(term->root_scene->root_od->flags & GF_ODM_NO_TIME_CTRL) ) { + gf_term_play_from_time(term, 0, 2); + } + break; + case GF_ACTION_JUMP_END: + if (term->root_scene && !(term->root_scene->root_od->flags & GF_ODM_NO_TIME_CTRL) ) { + gf_term_play_from_time(term, term->root_scene->duration, 2); + } + break; + case GF_ACTION_VERY_FAST_FORWARD: + case GF_ACTION_FAST_FORWARD: + case GF_ACTION_SLOW_FORWARD: + if (term->speed_ratio != FIX_ONE) { + set_clocks_speed(term, gf_divfix(1, term->speed_ratio) ); + term->speed_ratio = FIX_ONE; + } + else { + switch (term->shortcuts[i].action) { + case GF_ACTION_VERY_FAST_FORWARD: + term->speed_ratio = INT2FIX(4); + break; + case GF_ACTION_FAST_FORWARD: + term->speed_ratio = INT2FIX(2); + break; + case GF_ACTION_SLOW_FORWARD: + term->speed_ratio = INT2FIX(1)/4; + break; + } + set_clocks_speed(term, term->speed_ratio); + } + break; + } + break; + } + } +} + +void gf_term_load_shortcuts(GF_Terminal *term) +{ + char szVal[51]; + u32 i, k, count; + + memset(term->shortcuts, 0, sizeof(GF_Shortcut)*MAX_SHORTCUTS); + count = gf_cfg_get_key_count(term->user->config, "Shortcuts"); + k = 0; + for (i=0; i<count; i++) { + char *name = (char*)gf_cfg_get_key_name(term->user->config, "Shortcuts", i); + char *val = (char*)gf_cfg_get_key(term->user->config, "Shortcuts", name); + if (!name || !val) continue; + + strncpy(szVal, val, 50); + strlwr(szVal); + val = szVal; + + while (strchr(val, '+')) { + if (!strnicmp(val, "ctrl+", 5)) { + val += 5; + term->shortcuts[k].mods |= GF_KEY_MOD_CTRL; + } + if (!strnicmp(val, "alt+", 4)) { + val += 4; + term->shortcuts[k].mods |= GF_KEY_MOD_ALT; + } + } +#ifndef GPAC_DISABLE_SVG + term->shortcuts[k].code = gf_dom_get_key_type((char *)val); +#endif + if (!term->shortcuts[k].code) continue; + + if (!stricmp(name, "Play") || !stricmp(name, "Pause")) term->shortcuts[k].action = GF_ACTION_PLAY; + else if (!stricmp(name, "Stop")) term->shortcuts[k].action = GF_ACTION_STOP; + else if (!stricmp(name, "Step")) term->shortcuts[k].action = GF_ACTION_STEP; + else if (!stricmp(name, "Exit")) term->shortcuts[k].action = GF_ACTION_EXIT; + else if (!stricmp(name, "Mute")) term->shortcuts[k].action = GF_ACTION_MUTE; + else if (!stricmp(name, "VolumeUp")) term->shortcuts[k].action = GF_ACTION_VOLUP; + else if (!stricmp(name, "VolumeDown")) term->shortcuts[k].action = GF_ACTION_VOLDOWN; + else if (!stricmp(name, "JumpForward")) term->shortcuts[k].action = GF_ACTION_JUMP_FORWARD; + else if (!stricmp(name, "JumpBackward")) term->shortcuts[k].action = GF_ACTION_JUMP_BACKWARD; + else if (!stricmp(name, "JumpStart")) term->shortcuts[k].action = GF_ACTION_JUMP_START; + else if (!stricmp(name, "JumpEnd")) term->shortcuts[k].action = GF_ACTION_JUMP_END; + else if (!stricmp(name, "VeryFastForward")) term->shortcuts[k].action = GF_ACTION_VERY_FAST_FORWARD; + else if (!stricmp(name, "FastForward")) term->shortcuts[k].action = GF_ACTION_FAST_FORWARD; + else if (!stricmp(name, "SlowForward")) term->shortcuts[k].action = GF_ACTION_SLOW_FORWARD; + else if (!stricmp(name, "VeryFastRewind")) term->shortcuts[k].action = GF_ACTION_VERY_FAST_REWIND; + else if (!stricmp(name, "FastRewind")) term->shortcuts[k].action = GF_ACTION_FAST_REWIND; + else if (!stricmp(name, "SlowRewind")) term->shortcuts[k].action = GF_ACTION_SLOW_REWIND; + else if (!stricmp(name, "Next")) term->shortcuts[k].action = GF_ACTION_NEXT; + else if (!stricmp(name, "Previous")) term->shortcuts[k].action = GF_ACTION_PREVIOUS; + else { + term->shortcuts[k].mods = 0; + term->shortcuts[k].code = 0; + continue; + } + k++; + if (k==MAX_SHORTCUTS) break; + } +} + +void gf_scene_switch_quality(GF_Scene *scene, Bool up) +{ + u32 i; + GF_ObjectManager *odm; + GF_CodecCapability caps; + if (!scene) return; + caps.CapCode = GF_CODEC_MEDIA_SWITCH_QUALITY; + caps.cap.valueInt = up ? 1 : 0; + if (scene->scene_codec) { + scene->scene_codec->decio->SetCapabilities(scene->scene_codec->decio, caps); + } + i=0; + while (odm = gf_list_enum(scene->resources, &i) ) { + if (odm->codec) + odm->codec->decio->SetCapabilities(odm->codec->decio, caps); + if (odm->subscene) + gf_scene_switch_quality(odm->subscene, up); + } +} + +void gf_term_switch_quality(GF_Terminal *term, Bool up) +{ + gf_scene_switch_quality(term->root_scene, up); +} \ No newline at end of file diff --git a/src/utils/bitstream.c b/src/utils/bitstream.c index a8a338a..09adea2 100644 --- a/src/utils/bitstream.c +++ b/src/utils/bitstream.c @@ -43,11 +43,11 @@ struct __tag_bitstream /*original data*/ char *original; - /*the size of our buffer*/ + /*the size of our buffer in bytes*/ u64 size; /*current position in BYTES*/ u64 position; - /*the byte readen/written */ + /*the byte readen/written*/ u32 current; /*the number of bits in the current byte*/ u32 nbBits; @@ -65,7 +65,7 @@ GF_BitStream *gf_bs_new(char *buffer, u64 BufferSize, u32 mode) GF_BitStream *tmp; if ( (buffer && ! BufferSize)) return NULL; - tmp = (GF_BitStream *)malloc(sizeof(GF_BitStream)); + tmp = (GF_BitStream *)gf_malloc(sizeof(GF_BitStream)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_BitStream)); @@ -92,9 +92,9 @@ GF_BitStream *gf_bs_new(char *buffer, u64 BufferSize, u32 mode) } else { tmp->size = BS_MEM_BLOCK_ALLOC_SIZE; } - tmp->original = (char *) malloc(sizeof(char) * ((u32) tmp->size)); + tmp->original = (char *) gf_malloc(sizeof(char) * ((u32) tmp->size)); if (! tmp->original) { - free(tmp); + gf_free(tmp); return NULL; } tmp->bsmode = GF_BITSTREAM_WRITE_DYN; @@ -105,7 +105,7 @@ GF_BitStream *gf_bs_new(char *buffer, u64 BufferSize, u32 mode) break; default: /*the stream constructor is not the same...*/ - free(tmp); + gf_free(tmp); return NULL; } return tmp; @@ -117,7 +117,7 @@ GF_BitStream *gf_bs_from_file(FILE *f, u32 mode) GF_BitStream *tmp; if (!f) return NULL; - tmp = (GF_BitStream *)malloc(sizeof(GF_BitStream)); + tmp = (GF_BitStream *)gf_malloc(sizeof(GF_BitStream)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_BitStream)); /*switch to internal mode*/ @@ -142,8 +142,8 @@ 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) free(bs->original); - free(bs); + if ((bs->bsmode == GF_BITSTREAM_WRITE_DYN) && bs->original) gf_free(bs->original); + gf_free(bs); } @@ -336,7 +336,7 @@ u32 gf_bs_read_data(GF_BitStream *bs, char *data, u32 nbBytes) return nbBytes; case GF_BITSTREAM_FILE_READ: case GF_BITSTREAM_FILE_WRITE: - fread(data, nbBytes, 1, bs->stream); + nbBytes = fread(data, 1, nbBytes, bs->stream); bs->position += nbBytes; return nbBytes; default: @@ -364,9 +364,9 @@ static void BS_WriteByte(GF_BitStream *bs, u8 val) if (bs->position == bs->size) { /*no more space...*/ if (bs->bsmode != GF_BITSTREAM_WRITE_DYN) return; - /*realloc if enough space...*/ + /*gf_realloc if enough space...*/ if (bs->size > 0xFFFFFFFF) return; - bs->original = (char*)realloc(bs->original, (u32) (bs->size + BS_MEM_BLOCK_ALLOC_SIZE)); + bs->original = (char*)gf_realloc(bs->original, (u32) (bs->size + BS_MEM_BLOCK_ALLOC_SIZE)); if (!bs->original) return; bs->size += BS_MEM_BLOCK_ALLOC_SIZE; } @@ -374,7 +374,7 @@ static void BS_WriteByte(GF_BitStream *bs, u8 val) bs->position++; return; } - /*we are in FILE mode, no pb for any realloc...*/ + /*we are in FILE mode, no pb for any gf_realloc...*/ fputc(val, bs->stream); /*check we didn't rewind the stream*/ if (bs->size == bs->position) bs->size++; @@ -490,7 +490,7 @@ void gf_bs_write_double (GF_BitStream *bs, Double value) GF_EXPORT -u32 gf_bs_write_data(GF_BitStream *bs, char *data, u32 nbBytes) +u32 gf_bs_write_data(GF_BitStream *bs, const char *data, u32 nbBytes) { /*we need some feedback for this guy...*/ u64 begin = bs->position; @@ -505,11 +505,11 @@ u32 gf_bs_write_data(GF_BitStream *bs, char *data, u32 nbBytes) bs->position += nbBytes; return nbBytes; case GF_BITSTREAM_WRITE_DYN: - /*need to realloc ...*/ + /*need to gf_realloc ...*/ if (bs->position+nbBytes > bs->size) { if (bs->size + nbBytes > 0xFFFFFFFF) return 0; - bs->original = (char*)realloc(bs->original, sizeof(u32)*((u32) bs->size + nbBytes)); + bs->original = (char*)gf_realloc(bs->original, sizeof(u32)*((u32) bs->size + nbBytes)); if (!bs->original) return 0; bs->size += nbBytes; @@ -569,7 +569,10 @@ u64 gf_bs_available(GF_BitStream *bs) /*we are in MEM mode*/ if (bs->bsmode == GF_BITSTREAM_READ) { - return (bs->size - bs->position); + if ((s64)bs->size - (s64)bs->position < 0) + return 0; + else + return (bs->size - bs->position); } /*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); @@ -583,7 +586,7 @@ u64 gf_bs_available(GF_BitStream *bs) /*call this funct to set the buffer size to the nb of bytes written Used only in WRITE mode, as we don't know the real size during allocation... -return -1 for bad param or malloc failed +return -1 for bad param or gf_malloc failed return nbBytes cut*/ static u32 BS_CutBuffer(GF_BitStream *bs) { @@ -594,7 +597,7 @@ static u32 BS_CutBuffer(GF_BitStream *bs) nbBytes = (u32) (bs->size - bs->position); if (!nbBytes || (nbBytes == 0xFFFFFFFF) || (bs->position >= 0xFFFFFFFF)) return 0; - bs->original = (char*)realloc(bs->original, (u32) bs->position); + bs->original = (char*)gf_realloc(bs->original, (u32) bs->position); if (! bs->original) return (u32) -1; /*just in case, re-adjust..*/ bs->size = bs->position; @@ -610,7 +613,7 @@ void gf_bs_get_content(GF_BitStream *bs, char **output, u32 *outSize) if (!bs->position && !bs->nbBits) { *output = NULL; *outSize = 0; - free(bs->original); + gf_free(bs->original); } else { BS_CutBuffer(bs); *output = bs->original; @@ -679,8 +682,8 @@ static GF_Err BS_SeekIntern(GF_BitStream *bs, u64 offset) /*0 for write, read will be done automatically*/ if (offset >= bs->size) { if ( (bs->bsmode == GF_BITSTREAM_READ) || (bs->bsmode == GF_BITSTREAM_WRITE) ) return GF_BAD_PARAM; - /*in DYN, realloc ...*/ - bs->original = (char*)realloc(bs->original, (u32) (offset + 1)); + /*in DYN, gf_realloc ...*/ + bs->original = (char*)gf_realloc(bs->original, (u32) (offset + 1)); for (i = 0; i < (u32) (offset + 1 - bs->size); i++) { bs->original[bs->size + i] = 0; } @@ -844,3 +847,9 @@ u32 gf_bs_read_vluimsbf5(GF_BitStream *bs) return gf_bs_read_int(bs, 4*nb_words); } +GF_EXPORT +void gf_bs_truncate(GF_BitStream *bs) +{ + bs->size = bs->position; + if (bs->stream) return; +} diff --git a/src/utils/color.c b/src/utils/color.c index 7d0e60f..8375b9f 100644 --- a/src/utils/color.c +++ b/src/utils/color.c @@ -41,8 +41,6 @@ * follows the usual GPL license terms ****************************************************************************/ - - #define col_clip(a) MAX(0, MIN(255, a)) static s32 RGB_Y[256]; @@ -54,27 +52,28 @@ 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 void yuv2rgb_init(void) { s32 i; - if (!is_init) { - 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); - G_U[i] = FIX_OUT(0.391) * (i - 128); - G_V[i] = FIX_OUT(0.813) * (i - 128); - R_V[i] = FIX_OUT(1.596) * (i - 128); - } + if (is_init) return; + + 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); + G_U[i] = FIX_OUT(0.391) * (i - 128); + G_V[i] = FIX_OUT(0.813) * (i - 128); + R_V[i] = FIX_OUT(1.596) * (i - 128); } } static void gf_yuv_load_lines(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char * v_src, s32 y_stride, s32 uv_stride, s32 width) { - u32 x, hw; + u32 hw, x; unsigned char *dst2 = (unsigned char *) dst + dststride; unsigned char *y_src2 = (unsigned char *) y_src + y_stride; @@ -128,7 +127,7 @@ static void gf_yuv_load_lines(unsigned char *dst, s32 dststride, unsigned char * static void gf_yuva_load_lines(unsigned char *dst, s32 dststride, unsigned char *y_src, unsigned char *u_src, unsigned char *v_src, unsigned char *a_src, s32 y_stride, s32 uv_stride, s32 width) { - u32 x, hw; + u32 hw, x; unsigned char *dst2 = dst + dststride; unsigned char *y_src2 = y_src + y_stride; unsigned char *a_src2 = a_src + y_stride; @@ -182,7 +181,6 @@ static void gf_yuva_load_lines(unsigned char *dst, s32 dststride, unsigned char dst += 8; dst2 += 8; } - } static s32 mul255(s32 a, s32 b) @@ -554,6 +552,33 @@ static void load_line_rgb_32(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pit } } +static void load_line_rgbd(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u8 *dst_bits) +{ + u32 i; + src_bits += x_offset*4 + y_offset*y_pitch; + for (i=0; i<width; i++) { + dst_bits[0] = *src_bits++; + dst_bits[1] = *src_bits++; + dst_bits[2] = *src_bits++; + dst_bits[3] = 0xFF; + src_bits++; + dst_bits += 4; + } +} + +static void load_line_rgbds(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u8 *dst_bits) +{ + u32 i; + src_bits += x_offset*4 + y_offset*y_pitch; + for (i=0; i<width; i++) { + dst_bits[0] = *src_bits++; + dst_bits[1] = *src_bits++; + dst_bits[2] = *src_bits++; + dst_bits[3] = ( *src_bits++) & 0x80 ? 255 : 0; + dst_bits += 4; + } +} + static void load_line_argb(u8 *src_bits, u32 x_offset, u32 y_offset, u32 y_pitch, u32 width, u8 *dst_bits) { u32 i; @@ -603,18 +628,21 @@ static void load_line_yuva(char *src_bits, u32 x_offset, u32 y_offset, u32 y_pit static void gf_cmx_apply_argb(GF_ColorMatrix *_this, u8 *a_, u8 *r_, u8 *g_, u8 *b_); GF_EXPORT -GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *dst_wnd, GF_Window *src_wnd, s32 dst_x_pitch, u8 alpha, Bool flip, GF_ColorKey *key, GF_ColorMatrix *cmat) +GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *dst_wnd, GF_Window *src_wnd, u8 alpha, Bool flip, GF_ColorKey *key, GF_ColorMatrix *cmat) { u8 *tmp, *rows; u8 ka, kr, kg, kb, kl, kh; s32 src_row; u32 i, yuv_type = 0; + Bool no_memcpy; Bool yuv_init = 0; Bool has_alpha = (alpha!=0xFF) ? 1 : 0; u32 dst_bpp, dst_w_size; s32 pos_y, inc_y, inc_x, prev_row, x_off; u32 src_w, src_h, dst_w, dst_h; u8 *src_bits = NULL, *dst_bits = NULL, *dst_bits_prev = NULL, *dst_temp_bits = NULL; + s32 dst_x_pitch = dst->pitch_x; + copy_row_proto copy_row = NULL; load_line_proto load_line = NULL; @@ -643,6 +671,13 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds case GF_PIXEL_RGB_32: load_line = load_line_rgb_32; break; + case GF_PIXEL_RGBDS: + load_line = load_line_rgbds; + has_alpha = 1; + break; + case GF_PIXEL_RGBD: + load_line = load_line_rgbd; + break; case GF_PIXEL_BGR_32: load_line = load_line_bgr_32; break; @@ -654,6 +689,7 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds break; case GF_PIXEL_YUVA: has_alpha = 1; + case GF_PIXEL_YUVD: yuv_type = 2; break; default: @@ -708,7 +744,7 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds if (yuv_type && (src_w%2)) src_w++; - tmp = (u8 *) malloc(sizeof(u8) * src_w * (yuv_type ? 8 : 4) ); + tmp = (u8 *) gf_malloc(sizeof(u8) * src_w * (yuv_type ? 8 : 4) ); rows = tmp; src_bits = (u8 *) src->video_buffer; @@ -723,14 +759,14 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds prev_row = -1; dst_bits = (u8 *) dst->video_buffer; - if (dst_wnd) dst_bits += ((s32)dst_wnd->x) * dst_x_pitch + ((s32)dst_wnd->y) * dst->pitch; + if (dst_wnd) dst_bits += ((s32)dst_wnd->x) * dst_x_pitch + ((s32)dst_wnd->y) * dst->pitch_y; dst_w_size = dst_bpp*dst_w; /*small opt here: if we need to fetch data from destination, and if destination is hardware memory, we work on a copy of the destination line*/ if (has_alpha && dst->is_hardware_memory) - dst_temp_bits = (u8 *) malloc(sizeof(u8) * dst_bpp * dst_w); + dst_temp_bits = (u8 *) gf_malloc(sizeof(u8) * dst_bpp * dst_w); /*for 2 and 4 bytes colors, precompute pitch for u16 and u32 type casting*/ @@ -747,6 +783,9 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds if (kh==kl) kh++; } + /*do NOT use memcpy if the target buffer is not in systems memory*/ + no_memcpy = (has_alpha || dst->is_hardware_memory || (dst_bpp!=dst_x_pitch)) ? 1 : 0; + while (dst_h) { while ( pos_y >= 0x10000L ) { src_row++; @@ -762,9 +801,9 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds the_row --; if (flip) the_row = src->height-2 - the_row; if (yuv_type==1) { - load_line_yv12(src->video_buffer, x_off, the_row, src->pitch, src_w, src->height, tmp); + load_line_yv12(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp); } else { - load_line_yuva(src->video_buffer, x_off, the_row, src->pitch, src_w, src->height, tmp); + load_line_yuva(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp); } the_row = src_row - 1; } @@ -772,9 +811,9 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds } else { if (flip) the_row = src->height-2 - the_row; if (yuv_type==1) { - load_line_yv12(src->video_buffer, x_off, the_row, src->pitch, src_w, src->height, tmp); + load_line_yv12(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp); } else { - load_line_yuva(src->video_buffer, x_off, the_row, src->pitch, src_w, src->height, tmp); + load_line_yuva(src->video_buffer, x_off, the_row, src->pitch_y, src_w, src->height, tmp); } yuv_init = 1; rows = flip ? tmp + src_w * 4 : tmp; @@ -805,7 +844,7 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds } } else { if (flip) the_row = src->height-1 - the_row; - load_line((u8*)src->video_buffer, x_off, the_row, src->pitch, src_w, tmp); + load_line((u8*)src->video_buffer, x_off, the_row, src->pitch_y, src_w, tmp); rows = tmp; if (cmat) { for (i=0; i<src_w; i++) { @@ -825,7 +864,8 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds } } } - if (dst_temp_bits) { + /*FIXME - this should be configurable, and tested against each graphics card*/ + if (0&&dst_temp_bits) { /*load from video memory*/ memcpy(dst_temp_bits, dst_bits, dst_w_size); /*merge*/ @@ -837,7 +877,7 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds } } /*do NOT use memcpy if the target buffer is not in systems memory*/ - else if (has_alpha || dst->is_hardware_memory) { + else if (no_memcpy) { copy_row(rows, src_w, dst_bits, dst_w, inc_x, dst_x_pitch, alpha); } else { memcpy(dst_bits, dst_bits_prev, dst_w_size); @@ -847,11 +887,11 @@ GF_Err gf_stretch_bits(GF_VideoSurface *dst, GF_VideoSurface *src, GF_Window *ds prev_row = src_row; dst_bits_prev = dst_bits; - dst_bits += dst->pitch; + dst_bits += dst->pitch_y; dst_h--; } - if (dst_temp_bits) free(dst_temp_bits); - free(tmp); + if (dst_temp_bits) gf_free(dst_temp_bits); + gf_free(tmp); return GF_OK; } diff --git a/src/utils/configfile.c b/src/utils/configfile.c index dff49d6..e8d8dde 100644 --- a/src/utils/configfile.c +++ b/src/utils/configfile.c @@ -25,7 +25,6 @@ #include <gpac/module.h> #include <gpac/list.h> -#define MAX_SECTION_NAME 500 #define MAX_INI_LINE 2046 typedef struct @@ -36,7 +35,7 @@ typedef struct typedef struct { - char section_name[MAX_SECTION_NAME]; + char *section_name; GF_List *keys; } IniSection; @@ -56,7 +55,8 @@ GF_Config *gf_cfg_new(const char *filePath, const char* file_name) FILE *file; char *ret; char fileName[GF_MAX_PATH]; - char line[MAX_INI_LINE]; + char *line; + u32 line_alloc = MAX_INI_LINE; GF_Config *tmp; if (filePath) { @@ -69,22 +69,31 @@ GF_Config *gf_cfg_new(const char *filePath, const char* file_name) } else { strcpy(fileName,file_name); } - file = fopen(fileName, "rt"); + file = gf_f64_open(fileName, "rt"); if (!file) return NULL; - tmp = (GF_Config *)malloc(sizeof(GF_Config)); + tmp = (GF_Config *)gf_malloc(sizeof(GF_Config)); memset((void *)tmp, 0, sizeof(GF_Config)); - tmp->filePath = strdup(filePath); - tmp->fileName = strdup(fileName); + tmp->filePath = gf_strdup(filePath); + tmp->fileName = gf_strdup(fileName); tmp->sections = gf_list_new(); //load the file p = NULL; + line = gf_malloc(sizeof(char)*line_alloc); + memset(line, 0, sizeof(char)*line_alloc); while (!feof(file)) { - ret = fgets(line, MAX_INI_LINE, file); - + u32 read; + ret = fgets(line, line_alloc, file); + read = strlen(line); + while (read + 1 == line_alloc) { + line_alloc += MAX_INI_LINE; + line = gf_realloc(line, sizeof(char)*line_alloc); + ret = fgets(line+read, MAX_INI_LINE, file); + read = strlen(line); + } if (!ret) continue; //get rid of the end of line stuff @@ -100,9 +109,9 @@ GF_Config *gf_cfg_new(const char *filePath, const char* file_name) //new section if (line[0] == '[') { - p = (IniSection *) malloc(sizeof(IniSection)); + p = (IniSection *) gf_malloc(sizeof(IniSection)); p->keys = gf_list_new(); - strcpy(p->section_name, line + 1); + p->section_name = gf_strdup(line + 1); p->section_name[strlen(line) - 2] = 0; while (p->section_name[strlen(p->section_name) - 1] == ']' || p->section_name[strlen(p->section_name) - 1] == ' ') p->section_name[strlen(p->section_name) - 1] = 0; gf_list_add(tmp->sections, p); @@ -110,29 +119,31 @@ GF_Config *gf_cfg_new(const char *filePath, const char* file_name) else if (strlen(line) && (strchr(line, '=') != NULL) ) { if (!p) { gf_list_del(tmp->sections); - free(tmp->fileName); - free(tmp->filePath); - free(tmp); + gf_free(tmp->fileName); + gf_free(tmp->filePath); + gf_free(tmp); fclose(file); + gf_free(line); return NULL; } // GF_SAFEALLOC(k, IniKey) - k = (IniKey *) malloc(sizeof(IniKey)); + k = (IniKey *) gf_malloc(sizeof(IniKey)); memset((void *)k, 0, sizeof(IniKey)); ret = strchr(line, '='); if (ret) { ret[0] = 0; - k->name = strdup(line); + k->name = gf_strdup(line); ret[0] = '='; ret += 1; while (ret[0] == ' ') ret++; - k->value = strdup(ret); + k->value = gf_strdup(ret); while (k->name[strlen(k->name) - 1] == ' ') k->name[strlen(k->name) - 1] = 0; while (k->value[strlen(k->value) - 1] == ' ') k->value[strlen(k->value) - 1] = 0; } gf_list_add(p->keys, k); } } + gf_free(line); fclose(file); return tmp; } @@ -144,14 +155,15 @@ static void DelSection(IniSection *ptr) if (ptr->keys) { while (gf_list_count(ptr->keys)) { k = (IniKey *) gf_list_get(ptr->keys, 0); - if (k->value) free(k->value); - if (k->name) free(k->name); - free(k); + if (k->value) gf_free(k->value); + if (k->name) gf_free(k->name); + gf_free(k); gf_list_rem(ptr->keys, 0); } gf_list_del(ptr->keys); } - free(ptr); + if (ptr->section_name) gf_free(ptr->section_name); + gf_free(ptr); } @@ -165,7 +177,7 @@ GF_Err gf_cfg_save(GF_Config *iniFile) if (!iniFile->hasChanged) return GF_OK; - file = fopen(iniFile->fileName, "wt"); + file = gf_f64_open(iniFile->fileName, "wt"); if (!file) return GF_IO_ERR; i=0; @@ -195,9 +207,9 @@ void gf_cfg_del(GF_Config *iniFile) gf_list_rem(iniFile->sections, 0); } gf_list_del(iniFile->sections); - free(iniFile->fileName); - free(iniFile->filePath); - free(iniFile); + gf_free(iniFile->fileName); + gf_free(iniFile->filePath); + gf_free(iniFile); } @@ -238,8 +250,8 @@ GF_Err gf_cfg_set_key(GF_Config *iniFile, const char *secName, const char *keyNa if (!strcmp(secName, sec->section_name)) goto get_key; } //need a new key - sec = (IniSection *) malloc(sizeof(IniSection)); - strcpy(sec->section_name, secName); + sec = (IniSection *) gf_malloc(sizeof(IniSection)); + sec->section_name = gf_strdup(secName); sec->keys = gf_list_new(); iniFile->hasChanged = 1; gf_list_add(iniFile->sections, sec); @@ -251,26 +263,26 @@ get_key: } if (!keyValue) return GF_OK; //need a new key - key = (IniKey *) malloc(sizeof(IniKey)); - key->name = strdup(keyName); - key->value = strdup(""); + key = (IniKey *) gf_malloc(sizeof(IniKey)); + key->name = gf_strdup(keyName); + key->value = gf_strdup(""); iniFile->hasChanged = 1; gf_list_add(sec->keys, key); set_value: if (!keyValue) { gf_list_del_item(sec->keys, key); - if (key->name) free(key->name); - if (key->value) free(key->value); - free(key); + if (key->name) gf_free(key->name); + if (key->value) gf_free(key->value); + gf_free(key); iniFile->hasChanged = 1; return GF_OK; } //same value, don't update if (!strcmp(key->value, keyValue)) return GF_OK; - if (key->value) free(key->value); - key->value = strdup(keyValue); + if (key->value) gf_free(key->value); + key->value = gf_strdup(keyValue); iniFile->hasChanged = 1; return GF_OK; } @@ -351,11 +363,38 @@ GF_Err gf_cfg_insert_key(GF_Config *iniFile, const char *secName, const char *ke if (!strcmp(key->name, keyName)) return GF_BAD_PARAM; } - key = (IniKey *) malloc(sizeof(IniKey)); - key->name = strdup(keyName); - key->value = strdup(keyValue); + key = (IniKey *) gf_malloc(sizeof(IniKey)); + key->name = gf_strdup(keyName); + key->value = gf_strdup(keyValue); gf_list_insert(sec->keys, key, index); iniFile->hasChanged = 1; return GF_OK; } +GF_EXPORT +const char *gf_cfg_get_sub_key(GF_Config *iniFile, const char *secName, const char *keyName, u32 sub_index) +{ + u32 j; + char *subKeyValue, *returnKey; + char *keyValue; + + + keyValue = gf_strdup(gf_cfg_get_key(iniFile, secName, keyName)); + if (!keyValue){ + return NULL; + } + + j = 0; + subKeyValue = strtok((char*)keyValue,";"); + while (subKeyValue!=NULL) { + if (j==sub_index) { + returnKey = gf_strdup(subKeyValue); + gf_free(keyValue); + return returnKey; + } + j++; + subKeyValue = strtok (NULL, ";"); + } + gf_free(keyValue); + return NULL; +} diff --git a/src/utils/dlmalloc.c b/src/utils/dlmalloc.c new file mode 100644 index 0000000..732f482 --- /dev/null +++ b/src/utils/dlmalloc.c @@ -0,0 +1,5712 @@ +#define USE_LOCK 1 + +/* + This is a version (aka dlmalloc) of malloc/free/realloc written by + Doug Lea and released to the public domain, as explained at + http://creativecommons.org/licenses/publicdomain. Send questions, + comments, complaints, performance data, etc to dl@cs.oswego.edu + +* Version 2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) + + Note: There may be an updated version of this malloc obtainable at + ftp://gee.cs.oswego.edu/pub/misc/malloc.c + Check before installing! + +* Quickstart + + This library is all in one file to simplify the most common usage: + ftp it, compile it (-O3), and link it into another program. All of + the compile-time options default to reasonable values for use on + most platforms. You might later want to step through various + compile-time and dynamic tuning options. + + For convenience, an include file for code using this malloc is at: + ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.4.h + You don't really need this .h file unless you call functions not + defined in your system include files. The .h file contains only the + excerpts from this file needed for using this malloc on ANSI C/C++ + systems, so long as you haven't changed compile-time options about + naming and tuning parameters. If you do, then you can create your + own malloc.h that does include all settings by cutting at the point + indicated below. Note that you may already by default be using a C + library containing a malloc that is based on some version of this + malloc (for example in linux). You might still want to use the one + in this file to customize settings or to avoid overheads associated + with library versions. + +* Vital statistics: + + Supported pointer/size_t representation: 4 or 8 bytes + size_t MUST be an unsigned type of the same width as + pointers. (If you are using an ancient system that declares + size_t as a signed type, or need it to be a different width + than pointers, you can use a previous release of this malloc + (e.g. 2.7.2) supporting these.) + + Alignment: 8 bytes (default) + This suffices for nearly all current machines and C compilers. + However, you can define MALLOC_ALIGNMENT to be wider than this + if necessary (up to 128bytes), at the expense of using more space. + + Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) + 8 or 16 bytes (if 8byte sizes) + Each malloced chunk has a hidden word of overhead holding size + and status information, and additional cross-check word + if FOOTERS is defined. + + Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) + 8-byte ptrs: 32 bytes (including overhead) + + Even a request for zero bytes (i.e., malloc(0)) returns a + pointer to something of the minimum allocatable size. + The maximum overhead wastage (i.e., number of extra bytes + allocated than were requested in malloc) is less than or equal + to the minimum size, except for requests >= mmap_threshold that + are serviced via mmap(), where the worst case wastage is about + 32 bytes plus the remainder from a system page (the minimal + mmap unit); typically 4096 or 8192 bytes. + + Security: static-safe; optionally more or less + The "security" of malloc refers to the ability of malicious + code to accentuate the effects of errors (for example, freeing + space that is not currently malloc'ed or overwriting past the + ends of chunks) in code that calls malloc. This malloc + guarantees not to modify any memory locations below the base of + heap, i.e., static variables, even in the presence of usage + errors. The routines additionally detect most improper frees + and reallocs. All this holds as long as the static bookkeeping + for malloc itself is not corrupted by some other means. This + is only one aspect of security -- these checks do not, and + cannot, detect all possible programming errors. + + If FOOTERS is defined nonzero, then each allocated chunk + carries an additional check word to verify that it was malloced + from its space. These check words are the same within each + execution of a program using malloc, but differ across + executions, so externally crafted fake chunks cannot be + freed. This improves security by rejecting frees/reallocs that + could corrupt heap memory, in addition to the checks preventing + writes to statics that are always on. This may further improve + security at the expense of time and space overhead. (Note that + FOOTERS may also be worth using with MSPACES.) + + By default detected errors cause the program to abort (calling + "abort()"). You can override this to instead proceed past + errors by defining PROCEED_ON_ERROR. In this case, a bad free + has no effect, and a malloc that encounters a bad address + caused by user overwrites will ignore the bad address by + dropping pointers and indices to all known memory. This may + be appropriate for programs that should continue if at all + possible in the face of programming errors, although they may + run out of memory because dropped memory is never reclaimed. + + If you don't like either of these options, you can define + CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything + else. And if if you are sure that your program using malloc has + no errors or vulnerabilities, you can define INSECURE to 1, + which might (or might not) provide a small performance improvement. + + Thread-safety: NOT thread-safe unless USE_LOCKS defined + When USE_LOCKS is defined, each public call to malloc, free, + etc is surrounded with either a pthread mutex or a win32 + spinlock (depending on WIN32). This is not especially fast, and + can be a major bottleneck. It is designed only to provide + minimal protection in concurrent environments, and to provide a + basis for extensions. If you are using malloc in a concurrent + program, consider instead using nedmalloc + (http://www.nedprod.com/programs/portable/nedmalloc/) or + ptmalloc (See http://www.malloc.de), which are derived + from versions of this malloc. + + System requirements: Any combination of MORECORE and/or MMAP/MUNMAP + This malloc can use unix sbrk or any emulation (invoked using + the CALL_MORECORE macro) and/or mmap/munmap or any emulation + (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system + memory. On most unix systems, it tends to work best if both + MORECORE and MMAP are enabled. On Win32, it uses emulations + based on VirtualAlloc. It also uses common C library functions + like memset. + + Compliance: I believe it is compliant with the Single Unix Specification + (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably + others as well. + +* Overview of algorithms + + This is not the fastest, most space-conserving, most portable, or + most tunable malloc ever written. However it is among the fastest + while also being among the most space-conserving, portable and + tunable. Consistent balance across these factors results in a good + general-purpose allocator for malloc-intensive programs. + + In most ways, this malloc is a best-fit allocator. Generally, it + chooses the best-fitting existing chunk for a request, with ties + broken in approximately least-recently-used order. (This strategy + normally maintains low fragmentation.) However, for requests less + than 256bytes, it deviates from best-fit when there is not an + exactly fitting available chunk by preferring to use space adjacent + to that used for the previous small request, as well as by breaking + ties in approximately most-recently-used order. (These enhance + locality of series of small allocations.) And for very large requests + (>= 256Kb by default), it relies on system memory mapping + facilities, if supported. (This helps avoid carrying around and + possibly fragmenting memory used only for large chunks.) + + All operations (except malloc_stats and mallinfo) have execution + times that are bounded by a constant factor of the number of bits in + a size_t, not counting any clearing in calloc or copying in realloc, + or actions surrounding MORECORE and MMAP that have times + proportional to the number of non-contiguous regions returned by + system allocation routines, which is often just 1. In real-time + applications, you can optionally suppress segment traversals using + NO_SEGMENT_TRAVERSAL, which assures bounded execution even when + system allocators return non-contiguous spaces, at the typical + expense of carrying around more memory and increased fragmentation. + + The implementation is not very modular and seriously overuses + macros. Perhaps someday all C compilers will do as good a job + inlining modular code as can now be done by brute-force expansion, + but now, enough of them seem not to. + + Some compilers issue a lot of warnings about code that is + dead/unreachable only on some platforms, and also about intentional + uses of negation on unsigned types. All known cases of each can be + ignored. + + For a longer but out of date high-level description, see + http://gee.cs.oswego.edu/dl/html/malloc.html + +* MSPACES + If MSPACES is defined, then in addition to malloc, free, etc., + this file also defines mspace_malloc, mspace_free, etc. These + are versions of malloc routines that take an "mspace" argument + obtained using create_mspace, to control all internal bookkeeping. + If ONLY_MSPACES is defined, only these versions are compiled. + So if you would like to use this allocator for only some allocations, + and your system malloc for others, you can compile with + ONLY_MSPACES and then do something like... + static mspace mymspace = create_mspace(0,0); // for example + #define mymalloc(bytes) mspace_malloc(mymspace, bytes) + + (Note: If you only need one instance of an mspace, you can instead + use "USE_DL_PREFIX" to relabel the global malloc.) + + You can similarly create thread-local allocators by storing + mspaces as thread-locals. For example: + static __thread mspace tlms = 0; + void* tlmalloc(size_t bytes) { + if (tlms == 0) tlms = create_mspace(0, 0); + return mspace_malloc(tlms, bytes); + } + void tlfree(void* mem) { mspace_free(tlms, mem); } + + Unless FOOTERS is defined, each mspace is completely independent. + You cannot allocate from one and free to another (although + conformance is only weakly checked, so usage errors are not always + caught). If FOOTERS is defined, then each chunk carries around a tag + indicating its originating mspace, and frees are directed to their + originating spaces. + + ------------------------- Compile-time options --------------------------- + +Be careful in setting #define values for numerical constants of type +size_t. On some systems, literal values are not automatically extended +to size_t precision unless they are explicitly casted. You can also +use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. + +WIN32 default: defined if _WIN32 defined + Defining WIN32 sets up defaults for MS environment and compilers. + Otherwise defaults are for unix. Beware that there seem to be some + cases where this malloc might not be a pure drop-in replacement for + Win32 malloc: Random-looking failures from Win32 GDI API's (eg; + SetDIBits()) may be due to bugs in some video driver implementations + when pixel buffers are malloc()ed, and the region spans more than + one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb) + default granularity, pixel buffers may straddle virtual allocation + regions more often than when using the Microsoft allocator. You can + avoid this by using VirtualAlloc() and VirtualFree() for all pixel + buffers rather than using malloc(). If this is not possible, + recompile this malloc with a larger DEFAULT_GRANULARITY. + +MALLOC_ALIGNMENT default: (size_t)8 + Controls the minimum alignment for malloc'ed chunks. It must be a + power of two and at least 8, even on machines for which smaller + alignments would suffice. It may be defined as larger than this + though. Note however that code and data structures are optimized for + the case of 8-byte alignment. + +MSPACES default: 0 (false) + If true, compile in support for independent allocation spaces. + This is only supported if HAVE_MMAP is true. + +ONLY_MSPACES default: 0 (false) + If true, only compile in mspace versions, not regular versions. + +USE_LOCKS default: 0 (false) + Causes each call to each public routine to be surrounded with + pthread or WIN32 mutex lock/unlock. (If set true, this can be + overridden on a per-mspace basis for mspace versions.) If set to a + non-zero value other than 1, locks are used, but their + implementation is left out, so lock functions must be supplied manually, + as described below. + +USE_SPIN_LOCKS default: 1 iff USE_LOCKS and on x86 using gcc or MSC + If true, uses custom spin locks for locking. This is currently + supported only for x86 platforms using gcc or recent MS compilers. + Otherwise, posix locks or win32 critical sections are used. + +FOOTERS default: 0 + If true, provide extra checking and dispatching by placing + information in the footers of allocated chunks. This adds + space and time overhead. + +INSECURE default: 0 + If true, omit checks for usage errors and heap space overwrites. + +USE_DL_PREFIX default: NOT defined + Causes compiler to prefix all public routines with the string 'dl'. + This can be useful when you only want to use this malloc in one part + of a program, using your regular system malloc elsewhere. + +ABORT default: defined as abort() + Defines how to abort on failed checks. On most systems, a failed + check cannot die with an "assert" or even print an informative + message, because the underlying print routines in turn call malloc, + which will fail again. Generally, the best policy is to simply call + abort(). It's not very useful to do more than this because many + errors due to overwriting will show up as address faults (null, odd + addresses etc) rather than malloc-triggered checks, so will also + abort. Also, most compilers know that abort() does not return, so + can better optimize code conditionally calling it. + +PROCEED_ON_ERROR default: defined as 0 (false) + Controls whether detected bad addresses cause them to bypassed + rather than aborting. If set, detected bad arguments to free and + realloc are ignored. And all bookkeeping information is zeroed out + upon a detected overwrite of freed heap space, thus losing the + ability to ever return it from malloc again, but enabling the + application to proceed. If PROCEED_ON_ERROR is defined, the + static variable malloc_corruption_error_count is compiled in + and can be examined to see if errors have occurred. This option + generates slower code than the default abort policy. + +DEBUG default: NOT defined + The DEBUG setting is mainly intended for people trying to modify + this code or diagnose problems when porting to new platforms. + However, it may also be able to better isolate user errors than just + using runtime checks. The assertions in the check routines spell + out in more detail the assumptions and invariants underlying the + algorithms. The checking is fairly extensive, and will slow down + execution noticeably. Calling malloc_stats or mallinfo with DEBUG + set will attempt to check every non-mmapped allocated and free chunk + in the course of computing the summaries. + +ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) + Debugging assertion failures can be nearly impossible if your + version of the assert macro causes malloc to be called, which will + lead to a cascade of further failures, blowing the runtime stack. + ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), + which will usually make debugging easier. + +MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 + The action to take before "return 0" when malloc fails to be able to + return memory because there is none available. + +HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES + True if this system supports sbrk or an emulation of it. + +MORECORE default: sbrk + The name of the sbrk-style system routine to call to obtain more + memory. See below for guidance on writing custom MORECORE + functions. The type of the argument to sbrk/MORECORE varies across + systems. It cannot be size_t, because it supports negative + arguments, so it is normally the signed type of the same width as + size_t (sometimes declared as "intptr_t"). It doesn't much matter + though. Internally, we only call it with arguments less than half + the max value of a size_t, which should work across all reasonable + possibilities, although sometimes generating compiler warnings. + +MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE + If true, take advantage of fact that consecutive calls to MORECORE + with positive arguments always return contiguous increasing + addresses. This is true of unix sbrk. It does not hurt too much to + set it true anyway, since malloc copes with non-contiguities. + Setting it false when definitely non-contiguous saves time + and possibly wasted space it would take to discover this though. + +MORECORE_CANNOT_TRIM default: NOT defined + True if MORECORE cannot release space back to the system when given + negative arguments. This is generally necessary only if you are + using a hand-crafted MORECORE function that cannot handle negative + arguments. + +NO_SEGMENT_TRAVERSAL default: 0 + If non-zero, suppresses traversals of memory segments + returned by either MORECORE or CALL_MMAP. This disables + merging of segments that are contiguous, and selectively + releasing them to the OS if unused, but bounds execution times. + +HAVE_MMAP default: 1 (true) + True if this system supports mmap or an emulation of it. If so, and + HAVE_MORECORE is not true, MMAP is used for all system + allocation. If set and HAVE_MORECORE is true as well, MMAP is + primarily used to directly allocate very large blocks. It is also + used as a backup strategy in cases where MORECORE fails to provide + space from system. Note: A single call to MUNMAP is assumed to be + able to unmap memory that may have be allocated using multiple calls + to MMAP, so long as they are adjacent. + +HAVE_MREMAP default: 1 on linux, else 0 + If true realloc() uses mremap() to re-allocate large blocks and + extend or shrink allocation spaces. + +MMAP_CLEARS default: 1 except on WINCE. + True if mmap clears memory so calloc doesn't need to. This is true + for standard unix mmap using /dev/zero and on WIN32 except for WINCE. + +USE_BUILTIN_FFS default: 0 (i.e., not used) + Causes malloc to use the builtin ffs() function to compute indices. + Some compilers may recognize and intrinsify ffs to be faster than the + supplied C version. Also, the case of x86 using gcc is special-cased + to an asm instruction, so is already as fast as it can be, and so + this setting has no effect. Similarly for Win32 under recent MS compilers. + (On most x86s, the asm version is only slightly faster than the C version.) + +malloc_getpagesize default: derive from system includes, or 4096. + The system page size. To the extent possible, this malloc manages + memory from the system in page-size units. This may be (and + usually is) a function rather than a constant. This is ignored + if WIN32, where page size is determined using getSystemInfo during + initialization. + +USE_DEV_RANDOM default: 0 (i.e., not used) + Causes malloc to use /dev/random to initialize secure magic seed for + stamping footers. Otherwise, the current time is used. + +NO_MALLINFO default: 0 + If defined, don't compile "mallinfo". This can be a simple way + of dealing with mismatches between system declarations and + those in this file. + +MALLINFO_FIELD_TYPE default: size_t + The type of the fields in the mallinfo struct. This was originally + defined as "int" in SVID etc, but is more usefully defined as + size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set + +REALLOC_ZERO_BYTES_FREES default: not defined + This should be set if a call to realloc with zero bytes should + be the same as a call to free. Some people think it should. Otherwise, + since this malloc returns a unique pointer for malloc(0), so does + realloc(p, 0). + +LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H +LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H +LACKS_STDLIB_H default: NOT defined unless on WIN32 + Define these if your system does not have these header files. + You might need to manually insert some of the declarations they provide. + +DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, + system_info.dwAllocationGranularity in WIN32, + otherwise 64K. + Also settable using mallopt(M_GRANULARITY, x) + The unit for allocating and deallocating memory from the system. On + most systems with contiguous MORECORE, there is no reason to + make this more than a page. However, systems with MMAP tend to + either require or encourage larger granularities. You can increase + this value to prevent system allocation functions to be called so + often, especially if they are slow. The value must be at least one + page and must be a power of two. Setting to 0 causes initialization + to either page size or win32 region size. (Note: In previous + versions of malloc, the equivalent of this option was called + "TOP_PAD") + +DEFAULT_TRIM_THRESHOLD default: 2MB + Also settable using mallopt(M_TRIM_THRESHOLD, x) + The maximum amount of unused top-most memory to keep before + releasing via malloc_trim in free(). Automatic trimming is mainly + useful in long-lived programs using contiguous MORECORE. Because + trimming via sbrk can be slow on some systems, and can sometimes be + wasteful (in cases where programs immediately afterward allocate + more large chunks) the value should be high enough so that your + overall system performance would improve by releasing this much + memory. As a rough guide, you might set to a value close to the + average size of a process (program) running on your system. + Releasing this much memory would allow such a process to run in + memory. Generally, it is worth tuning trim thresholds when a + program undergoes phases where several large chunks are allocated + and released in ways that can reuse each other's storage, perhaps + mixed with phases where there are no such chunks at all. The trim + value must be greater than page size to have any useful effect. To + disable trimming completely, you can set to MAX_SIZE_T. Note that the trick + some people use of mallocing a huge space and then freeing it at + program startup, in an attempt to reserve system memory, doesn't + have the intended effect under automatic trimming, since that memory + will immediately be returned to the system. + +DEFAULT_MMAP_THRESHOLD default: 256K + Also settable using mallopt(M_MMAP_THRESHOLD, x) + The request size threshold for using MMAP to directly service a + request. Requests of at least this size that cannot be allocated + using already-existing space will be serviced via mmap. (If enough + normal freed space already exists it is used instead.) Using mmap + segregates relatively large chunks of memory so that they can be + individually obtained and released from the host system. A request + serviced through mmap is never reused by any other request (at least + not directly; the system may just so happen to remap successive + requests to the same locations). Segregating space in this way has + the benefits that: Mmapped space can always be individually released + back to the system, which helps keep the system level memory demands + of a long-lived program low. Also, mapped memory doesn't become + `locked' between other chunks, as can happen with normally allocated + chunks, which means that even trimming via malloc_trim would not + release them. However, it has the disadvantage that the space + cannot be reclaimed, consolidated, and then used to service later + requests, as happens with normal chunks. The advantages of mmap + nearly always outweigh disadvantages for "large" chunks, but the + value of "large" may vary across systems. The default is an + empirically derived value that works well in most systems. You can + disable mmap by setting to MAX_SIZE_T. + +MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP + The number of consolidated frees between checks to release + unused segments when freeing. When using non-contiguous segments, + especially with multiple mspaces, checking only for topmost space + doesn't always suffice to trigger trimming. To compensate for this, + free() will, with a period of MAX_RELEASE_CHECK_RATE (or the + current number of segments, if greater) try to release unused + segments to the OS when freeing chunks that result in + consolidation. The best value for this parameter is a compromise + between slowing down frees with relatively costly checks that + rarely trigger versus holding on to unused memory. To effectively + disable, set to MAX_SIZE_T. This may lead to a very slight speed + improvement at the expense of carrying around more memory. +*/ + +#if 0 +#include <config.h> +#include <base/commandlineflags.h> +#include <google/malloc_extension.h> +#endif + +/* Version identifier to allow people to support multiple versions */ +#ifndef DLMALLOC_VERSION +#define DLMALLOC_VERSION 20804 +#endif /* DLMALLOC_VERSION */ + +#ifndef WIN32 +#ifdef _WIN32 +#define WIN32 1 +#endif /* _WIN32 */ +#ifdef _WIN32_WCE +#define LACKS_FCNTL_H +#define WIN32 1 +#endif /* _WIN32_WCE */ +#endif /* WIN32 */ +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#define HAVE_MMAP 1 +#define HAVE_MORECORE 0 +#define LACKS_UNISTD_H +#define LACKS_SYS_PARAM_H +#define LACKS_SYS_MMAN_H +#define LACKS_STRING_H +#define LACKS_STRINGS_H +#define LACKS_SYS_TYPES_H +#define LACKS_ERRNO_H +#ifndef MALLOC_FAILURE_ACTION +#define MALLOC_FAILURE_ACTION +#endif /* MALLOC_FAILURE_ACTION */ +#ifdef _WIN32_WCE /* WINCE reportedly does not clear */ +#define MMAP_CLEARS 0 +#else +#define MMAP_CLEARS 1 +#endif /* _WIN32_WCE */ +#endif /* WIN32 */ + +#if defined(DARWIN) || defined(_DARWIN) +/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ +#ifndef HAVE_MORECORE +#define HAVE_MORECORE 0 +#define HAVE_MMAP 1 +/* OSX allocators provide 16 byte alignment */ +#ifndef MALLOC_ALIGNMENT +#define MALLOC_ALIGNMENT ((size_t)16U) +#endif +#endif /* HAVE_MORECORE */ +#endif /* DARWIN */ + +#ifndef LACKS_SYS_TYPES_H +#include <sys/types.h> /* For size_t */ +#endif /* LACKS_SYS_TYPES_H */ + +#if (defined(__GNUC__) && ((defined(__i386__) || defined(__x86_64__)))) || (defined(_MSC_VER) && _MSC_VER>=1310) +#define SPIN_LOCKS_AVAILABLE 1 +#else +#define SPIN_LOCKS_AVAILABLE 0 +#endif + +/* The maximum possible size_t value has all bits set */ +#define MAX_SIZE_T (~(size_t)0) + +#ifndef ONLY_MSPACES +#define ONLY_MSPACES 0 /* define to a value */ +#else +#define ONLY_MSPACES 1 +#endif /* ONLY_MSPACES */ +#ifndef MSPACES +#if ONLY_MSPACES +#define MSPACES 1 +#else /* ONLY_MSPACES */ +#define MSPACES 0 +#endif /* ONLY_MSPACES */ +#endif /* MSPACES */ +#ifndef MALLOC_ALIGNMENT +#define MALLOC_ALIGNMENT ((size_t)8U) +#endif /* MALLOC_ALIGNMENT */ +#ifndef FOOTERS +#define FOOTERS 0 +#endif /* FOOTERS */ +#ifndef ABORT +#define ABORT abort() +#endif /* ABORT */ +#ifndef ABORT_ON_ASSERT_FAILURE +#define ABORT_ON_ASSERT_FAILURE 1 +#endif /* ABORT_ON_ASSERT_FAILURE */ +#ifndef PROCEED_ON_ERROR +#define PROCEED_ON_ERROR 0 +#endif /* PROCEED_ON_ERROR */ +#ifndef USE_LOCKS +#define USE_LOCKS 0 +#endif /* USE_LOCKS */ +#ifndef USE_SPIN_LOCKS +#if USE_LOCKS && SPIN_LOCKS_AVAILABLE +#define USE_SPIN_LOCKS 1 +#else +#define USE_SPIN_LOCKS 0 +#endif /* USE_LOCKS && SPIN_LOCKS_AVAILABLE. */ +#endif /* USE_SPIN_LOCKS */ +#ifndef INSECURE +#define INSECURE 0 +#endif /* INSECURE */ +#ifndef HAVE_MMAP +#define HAVE_MMAP 1 +#endif /* HAVE_MMAP */ +#ifndef MMAP_CLEARS +#define MMAP_CLEARS 1 +#endif /* MMAP_CLEARS */ +#ifndef HAVE_MREMAP +#ifdef linux +#define HAVE_MREMAP 1 +#else /* linux */ +#define HAVE_MREMAP 0 +#endif /* linux */ +#endif /* HAVE_MREMAP */ +#ifndef MALLOC_FAILURE_ACTION +#define MALLOC_FAILURE_ACTION errno = ENOMEM; +#endif /* MALLOC_FAILURE_ACTION */ +#ifndef HAVE_MORECORE +#if ONLY_MSPACES +#define HAVE_MORECORE 0 +#else /* ONLY_MSPACES */ +#define HAVE_MORECORE 1 +#endif /* ONLY_MSPACES */ +#endif /* HAVE_MORECORE */ +#if !HAVE_MORECORE +#define MORECORE_CONTIGUOUS 0 +#else /* !HAVE_MORECORE */ +#define MORECORE_DEFAULT sbrk +#ifndef MORECORE_CONTIGUOUS +#define MORECORE_CONTIGUOUS 1 +#endif /* MORECORE_CONTIGUOUS */ +#endif /* HAVE_MORECORE */ +#ifndef DEFAULT_GRANULARITY +#if (MORECORE_CONTIGUOUS || defined(WIN32)) +#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ +#else /* MORECORE_CONTIGUOUS */ +#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) +#endif /* MORECORE_CONTIGUOUS */ +#endif /* DEFAULT_GRANULARITY */ +#ifndef DEFAULT_TRIM_THRESHOLD +#ifndef MORECORE_CANNOT_TRIM +#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) +#else /* MORECORE_CANNOT_TRIM */ +#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T +#endif /* MORECORE_CANNOT_TRIM */ +#endif /* DEFAULT_TRIM_THRESHOLD */ +#ifndef DEFAULT_MMAP_THRESHOLD +#if HAVE_MMAP +#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) +#else /* HAVE_MMAP */ +#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T +#endif /* HAVE_MMAP */ +#endif /* DEFAULT_MMAP_THRESHOLD */ +#ifndef MAX_RELEASE_CHECK_RATE +#if HAVE_MMAP +#define MAX_RELEASE_CHECK_RATE 4095 +#else +#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T +#endif /* HAVE_MMAP */ +#endif /* MAX_RELEASE_CHECK_RATE */ +#ifndef USE_BUILTIN_FFS +#define USE_BUILTIN_FFS 0 +#endif /* USE_BUILTIN_FFS */ +#ifndef USE_DEV_RANDOM +#define USE_DEV_RANDOM 0 +#endif /* USE_DEV_RANDOM */ +#ifndef NO_MALLINFO +#define NO_MALLINFO 0 +#endif /* NO_MALLINFO */ +#ifndef MALLINFO_FIELD_TYPE +#define MALLINFO_FIELD_TYPE size_t +#endif /* MALLINFO_FIELD_TYPE */ +#ifndef NO_SEGMENT_TRAVERSAL +#define NO_SEGMENT_TRAVERSAL 0 +#endif /* NO_SEGMENT_TRAVERSAL */ + +/* + mallopt tuning options. SVID/XPG defines four standard parameter + numbers for mallopt, normally defined in malloc.h. None of these + are used in this malloc, so setting them has no effect. But this + malloc does support the following options. +*/ + +#define M_TRIM_THRESHOLD (-1) +#define M_GRANULARITY (-2) +#define M_MMAP_THRESHOLD (-3) + +/* ------------------------ Mallinfo declarations ------------------------ */ + +#if !NO_MALLINFO +/* + This version of malloc supports the standard SVID/XPG mallinfo + routine that returns a struct containing usage properties and + statistics. It should work on any system that has a + /usr/include/malloc.h defining struct mallinfo. The main + declaration needed is the mallinfo struct that is returned (by-copy) + by mallinfo(). The malloinfo struct contains a bunch of fields that + are not even meaningful in this version of malloc. These fields are + are instead filled by mallinfo() with other numbers that might be of + interest. + + HAVE_USR_INCLUDE_MALLOC_H should be set if you have a + /usr/include/malloc.h file that includes a declaration of struct + mallinfo. If so, it is included; else a compliant version is + declared below. These must be precisely the same for mallinfo() to + work. The original SVID version of this struct, defined on most + systems with mallinfo, declares all fields as ints. But some others + define as unsigned long. If your system defines the fields using a + type of different width than listed here, you MUST #include your + system version and #define HAVE_USR_INCLUDE_MALLOC_H. +*/ + +/* #define HAVE_USR_INCLUDE_MALLOC_H */ + +#ifdef HAVE_USR_INCLUDE_MALLOC_H +#include "/usr/include/malloc.h" +#else /* HAVE_USR_INCLUDE_MALLOC_H */ +#ifndef STRUCT_MALLINFO_DECLARED +#define STRUCT_MALLINFO_DECLARED 1 +struct mallinfo { + MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ + MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ + MALLINFO_FIELD_TYPE smblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblks; /* always 0 */ + MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ + MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ + MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ + MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ + MALLINFO_FIELD_TYPE fordblks; /* total free space */ + MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ +}; +#endif /* STRUCT_MALLINFO_DECLARED */ +#endif /* HAVE_USR_INCLUDE_MALLOC_H */ +#endif /* NO_MALLINFO */ + +/* + Try to persuade compilers to inline. The most critical functions for + inlining are defined as macros, so these aren't used for them. +*/ + +#ifdef WIN64 + #undef FORCEINLINE +#endif + +#ifndef FORCEINLINE + #if defined(__GNUC__) +#define FORCEINLINE __inline __attribute__ ((always_inline)) + #elif defined(_MSC_VER) + #define FORCEINLINE __forceinline + #endif +#endif +#ifndef NOINLINE + #if defined(__GNUC__) + #define NOINLINE __attribute__ ((noinline)) + #elif defined(_MSC_VER) + #define NOINLINE __declspec(noinline) + #else + #define NOINLINE + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#ifndef FORCEINLINE + #define FORCEINLINE inline +#endif +#endif /* __cplusplus */ +#ifndef FORCEINLINE + #define FORCEINLINE +#endif + + +#define USE_DL_PREFIX + +#if !ONLY_MSPACES + +/* ------------------- Declarations of public routines ------------------- */ + +#ifndef USE_DL_PREFIX +#define dlcalloc calloc +#define dlfree free +#define dlmalloc malloc +#define dlmemalign memalign +#define dlrealloc realloc +#define dlvalloc valloc +#define dlpvalloc pvalloc +#define dlmallinfo mallinfo +#define dlmallopt mallopt +#define dlmalloc_trim malloc_trim +#define dlmalloc_stats malloc_stats +#define dlmalloc_usable_size malloc_usable_size +#define dlmalloc_footprint malloc_footprint +#define dlmalloc_max_footprint malloc_max_footprint +#define dlindependent_calloc independent_calloc +#define dlindependent_comalloc independent_comalloc +#endif /* USE_DL_PREFIX */ + + +/* + malloc(size_t n) + Returns a pointer to a newly allocated chunk of at least n bytes, or + null if no space is available, in which case errno is set to ENOMEM + on ANSI C systems. + + If n is zero, malloc returns a minimum-sized chunk. (The minimum + size is 16 bytes on most 32bit systems, and 32 bytes on 64bit + systems.) Note that size_t is an unsigned type, so calls with + arguments that would be negative if signed are interpreted as + requests for huge amounts of space, which will often fail. The + maximum supported value of n differs across systems, but is in all + cases less than the maximum representable value of a size_t. +*/ +void* dlmalloc(size_t); + +/* + free(void* p) + Releases the chunk of memory pointed to by p, that had been previously + allocated using malloc or a related routine such as realloc. + It has no effect if p is null. If p was not malloced or already + freed, free(p) will by default cause the current program to abort. +*/ +void dlfree(void*); + +/* + calloc(size_t n_elements, size_t element_size); + Returns a pointer to n_elements * element_size bytes, with all locations + set to zero. +*/ +void* dlcalloc(size_t, size_t); + +/* + realloc(void* p, size_t n) + Returns a pointer to a chunk of size n that contains the same data + as does chunk p up to the minimum of (n, p's size) bytes, or null + if no space is available. + + The returned pointer may or may not be the same as p. The algorithm + prefers extending p in most cases when possible, otherwise it + employs the equivalent of a malloc-copy-free sequence. + + If p is null, realloc is equivalent to malloc. + + If space is not available, realloc returns null, errno is set (if on + ANSI) and p is NOT freed. + + if n is for fewer bytes than already held by p, the newly unused + space is lopped off and freed if possible. realloc with a size + argument of zero (re)allocates a minimum-sized chunk. + + The old unix realloc convention of allowing the last-free'd chunk + to be used as an argument to realloc is not supported. +*/ + +void* dlrealloc(void*, size_t); + +/* + memalign(size_t alignment, size_t n); + Returns a pointer to a newly allocated chunk of n bytes, aligned + in accord with the alignment argument. + + The alignment argument should be a power of two. If the argument is + not a power of two, the nearest greater power is used. + 8-byte alignment is guaranteed by normal malloc calls, so don't + bother calling memalign with an argument of 8 or less. + + Overreliance on memalign is a sure way to fragment space. +*/ +void* dlmemalign(size_t, size_t); + +/* + valloc(size_t n); + Equivalent to memalign(pagesize, n), where pagesize is the page + size of the system. If the pagesize is unknown, 4096 is used. +*/ +void* dlvalloc(size_t); + +/* + mallopt(int parameter_number, int parameter_value) + Sets tunable parameters The format is to provide a + (parameter-number, parameter-value) pair. mallopt then sets the + corresponding parameter to the argument value if it can (i.e., so + long as the value is meaningful), and returns 1 if successful else + 0. To workaround the fact that mallopt is specified to use int, + not size_t parameters, the value -1 is specially treated as the + maximum unsigned size_t value. + + SVID/XPG/ANSI defines four standard param numbers for mallopt, + normally defined in malloc.h. None of these are use in this malloc, + so setting them has no effect. But this malloc also supports other + options in mallopt. See below for details. Briefly, supported + parameters are as follows (listed defaults are for "typical" + configurations). + + Symbol param # default allowed param values + M_TRIM_THRESHOLD -1 2*1024*1024 any (-1 disables) + M_GRANULARITY -2 page size any power of 2 >= page size + M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) +*/ +int dlmallopt(int, int); + +/* + malloc_footprint(); + Returns the number of bytes obtained from the system. The total + number of bytes allocated by malloc, realloc etc., is less than this + value. Unlike mallinfo, this function returns only a precomputed + result, so can be called frequently to monitor memory consumption. + Even if locks are otherwise defined, this function does not use them, + so results might not be up to date. +*/ +size_t dlmalloc_footprint(void); + +/* + malloc_max_footprint(); + Returns the maximum number of bytes obtained from the system. This + value will be greater than current footprint if deallocated space + has been reclaimed by the system. The peak number of bytes allocated + by malloc, realloc etc., is less than this value. Unlike mallinfo, + this function returns only a precomputed result, so can be called + frequently to monitor memory consumption. Even if locks are + otherwise defined, this function does not use them, so results might + not be up to date. +*/ +size_t dlmalloc_max_footprint(void); + +#if !NO_MALLINFO +/* + mallinfo() + Returns (by copy) a struct containing various summary statistics: + + arena: current total non-mmapped bytes allocated from system + ordblks: the number of free chunks + smblks: always zero. + hblks: current number of mmapped regions + hblkhd: total bytes held in mmapped regions + usmblks: the maximum total allocated space. This will be greater + than current total if trimming has occurred. + fsmblks: always zero + uordblks: current total allocated space (normal or mmapped) + fordblks: total free space + keepcost: the maximum number of bytes that could ideally be released + back to system via malloc_trim. ("ideally" means that + it ignores page restrictions etc.) + + Because these fields are ints, but internal bookkeeping may + be kept as longs, the reported values may wrap around zero and + thus be inaccurate. +*/ +struct mallinfo dlmallinfo(void); +#endif /* NO_MALLINFO */ + +/* + independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); + + independent_calloc is similar to calloc, but instead of returning a + single cleared space, it returns an array of pointers to n_elements + independent elements that can hold contents of size elem_size, each + of which starts out cleared, and can be independently freed, + realloc'ed etc. The elements are guaranteed to be adjacently + allocated (this is not guaranteed to occur with multiple callocs or + mallocs), which may also improve cache locality in some + applications. + + The "chunks" argument is optional (i.e., may be null, which is + probably the most typical usage). If it is null, the returned array + is itself dynamically allocated and should also be freed when it is + no longer needed. Otherwise, the chunks array must be of at least + n_elements in length. It is filled in with the pointers to the + chunks. + + In either case, independent_calloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and "chunks" + is null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be individually freed when it is no longer + needed. If you'd like to instead be able to free all at once, you + should instead use regular calloc and assign pointers into this + space to represent elements. (In this case though, you cannot + independently free elements.) + + independent_calloc simplifies and speeds up implementations of many + kinds of pools. It may also be useful when constructing large data + structures that initially have a fixed number of fixed-sized nodes, + but the number is not known at compile time, and some of the nodes + may later need to be freed. For example: + + struct Node { int item; struct Node* next; }; + + struct Node* build_list() { + struct Node** pool; + int n = read_number_of_nodes_needed(); + if (n <= 0) return 0; + pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); + if (pool == 0) die(); + // organize into a linked list... + struct Node* first = pool[0]; + for (i = 0; i < n-1; ++i) + pool[i]->next = pool[i+1]; + free(pool); // Can now free the array (or not, if it is needed later) + return first; + } +*/ +void** dlindependent_calloc(size_t, size_t, void**); + +/* + independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); + + independent_comalloc allocates, all at once, a set of n_elements + chunks with sizes indicated in the "sizes" array. It returns + an array of pointers to these elements, each of which can be + independently freed, realloc'ed etc. The elements are guaranteed to + be adjacently allocated (this is not guaranteed to occur with + multiple callocs or mallocs), which may also improve cache locality + in some applications. + + The "chunks" argument is optional (i.e., may be null). If it is null + the returned array is itself dynamically allocated and should also + be freed when it is no longer needed. Otherwise, the chunks array + must be of at least n_elements in length. It is filled in with the + pointers to the chunks. + + In either case, independent_comalloc returns this pointer array, or + null if the allocation failed. If n_elements is zero and chunks is + null, it returns a chunk representing an array with zero elements + (which should be freed if not wanted). + + Each element must be individually freed when it is no longer + needed. If you'd like to instead be able to free all at once, you + should instead use a single regular malloc, and assign pointers at + particular offsets in the aggregate space. (In this case though, you + cannot independently free elements.) + + independent_comallac differs from independent_calloc in that each + element may have a different size, and also that it does not + automatically clear elements. + + independent_comalloc can be used to speed up allocation in cases + where several structs or objects must always be allocated at the + same time. For example: + + struct Head { ... } + struct Foot { ... } + + void send_message(char* msg) { + int msglen = strlen(msg); + size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; + void* chunks[3]; + if (independent_comalloc(3, sizes, chunks) == 0) + die(); + struct Head* head = (struct Head*)(chunks[0]); + char* body = (char*)(chunks[1]); + struct Foot* foot = (struct Foot*)(chunks[2]); + // ... + } + + In general though, independent_comalloc is worth using only for + larger values of n_elements. For small values, you probably won't + detect enough difference from series of malloc calls to bother. + + Overuse of independent_comalloc can increase overall memory usage, + since it cannot reuse existing noncontiguous small chunks that + might be available for some of the elements. +*/ +void** dlindependent_comalloc(size_t, size_t*, void**); + + +/* + pvalloc(size_t n); + Equivalent to valloc(minimum-page-that-holds(n)), that is, + round up n to nearest pagesize. + */ +void* dlpvalloc(size_t); + +/* + malloc_trim(size_t pad); + + If possible, gives memory back to the system (via negative arguments + to sbrk) if there is unused memory at the `high' end of the malloc + pool or in unused MMAP segments. You can call this after freeing + large blocks of memory to potentially reduce the system-level memory + requirements of a program. However, it cannot guarantee to reduce + memory. Under some allocation patterns, some large free blocks of + memory will be locked between two used chunks, so they cannot be + given back to the system. + + The `pad' argument to malloc_trim represents the amount of free + trailing space to leave untrimmed. If this argument is zero, only + the minimum amount of memory to maintain internal data structures + will be left. Non-zero arguments can be supplied to maintain enough + trailing space to service future expected allocations without having + to re-obtain memory from the system. + + Malloc_trim returns 1 if it actually released any memory, else 0. +*/ +int dlmalloc_trim(size_t); + +/* + malloc_stats(); + Prints on stderr the amount of space obtained from the system (both + via sbrk and mmap), the maximum amount (which may be more than + current if malloc_trim and/or munmap got called), and the current + number of bytes allocated via malloc (or realloc, etc) but not yet + freed. Note that this is the number of bytes allocated, not the + number requested. It will be larger than the number requested + because of alignment and bookkeeping overhead. Because it includes + alignment wastage as being in use, this figure may be greater than + zero even when no user-level chunks are allocated. + + The reported current and maximum system memory can be inaccurate if + a program makes other calls to system memory allocation functions + (normally sbrk) outside of malloc. + + malloc_stats prints only the most commonly interesting statistics. + More information can be obtained by calling mallinfo. +*/ +void dlmalloc_stats(void); + +#endif /* ONLY_MSPACES */ + +/* + malloc_usable_size(void* p); + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. malloc_usable_size can be more useful in + debugging and assertions, for example: + + p = malloc(n); + assert(malloc_usable_size(p) >= 256); +*/ +size_t dlmalloc_usable_size(void*); + + +#if MSPACES + +/* + mspace is an opaque type representing an independent + region of space that supports mspace_malloc, etc. +*/ +typedef void* mspace; + +/* + create_mspace creates and returns a new independent space with the + given initial capacity, or, if 0, the default granularity size. It + returns null if there is no system memory available to create the + space. If argument locked is non-zero, the space uses a separate + lock to control access. The capacity of the space will grow + dynamically as needed to service mspace_malloc requests. You can + control the sizes of incremental increases of this space by + compiling with a different DEFAULT_GRANULARITY or dynamically + setting with mallopt(M_GRANULARITY, value). +*/ +mspace create_mspace(size_t capacity, int locked); + +/* + destroy_mspace destroys the given space, and attempts to return all + of its memory back to the system, returning the total number of + bytes freed. After destruction, the results of access to all memory + used by the space become undefined. +*/ +size_t destroy_mspace(mspace msp); + +/* + create_mspace_with_base uses the memory supplied as the initial base + of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this + space is used for bookkeeping, so the capacity must be at least this + large. (Otherwise 0 is returned.) When this initial space is + exhausted, additional memory will be obtained from the system. + Destroying this space will deallocate all additionally allocated + space (if possible) but not the initial base. +*/ +mspace create_mspace_with_base(void* base, size_t capacity, int locked); + +/* + mspace_track_large_chunks controls whether requests for large chunks + are allocated in their own untracked mmapped regions, separate from + others in this mspace. By default large chunks are not tracked, + which reduces fragmentation. However, such chunks are not + necessarily released to the system upon destroy_mspace. Enabling + tracking by setting to true may increase fragmentation, but avoids + leakage when relying on destroy_mspace to release all memory + allocated using this space. The function returns the previous + setting. +*/ +int mspace_track_large_chunks(mspace msp, int enable); + + +/* + mspace_malloc behaves as malloc, but operates within + the given space. +*/ +void* mspace_malloc(mspace msp, size_t bytes); + +/* + mspace_free behaves as free, but operates within + the given space. + + If compiled with FOOTERS==1, mspace_free is not actually needed. + free may be called instead of mspace_free because freed chunks from + any space are handled by their originating spaces. +*/ +void mspace_free(mspace msp, void* mem); + +/* + mspace_realloc behaves as realloc, but operates within + the given space. + + If compiled with FOOTERS==1, mspace_realloc is not actually + needed. realloc may be called instead of mspace_realloc because + realloced chunks from any space are handled by their originating + spaces. +*/ +void* mspace_realloc(mspace msp, void* mem, size_t newsize); + +/* + mspace_calloc behaves as calloc, but operates within + the given space. +*/ +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); + +/* + mspace_memalign behaves as memalign, but operates within + the given space. +*/ +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); + +/* + mspace_independent_calloc behaves as independent_calloc, but + operates within the given space. +*/ +void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]); + +/* + mspace_independent_comalloc behaves as independent_comalloc, but + operates within the given space. +*/ +void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]); + +/* + mspace_footprint() returns the number of bytes obtained from the + system for this space. +*/ +size_t mspace_footprint(mspace msp); + +/* + mspace_max_footprint() returns the peak number of bytes obtained from the + system for this space. +*/ +size_t mspace_max_footprint(mspace msp); + + +#if !NO_MALLINFO +/* + mspace_mallinfo behaves as mallinfo, but reports properties of + the given space. +*/ +struct mallinfo mspace_mallinfo(mspace msp); +#endif /* NO_MALLINFO */ + +/* + malloc_usable_size(void* p) behaves the same as malloc_usable_size; +*/ + size_t mspace_usable_size(void* mem); + +/* + mspace_malloc_stats behaves as malloc_stats, but reports + properties of the given space. +*/ +void mspace_malloc_stats(mspace msp); + +/* + mspace_trim behaves as malloc_trim, but + operates within the given space. +*/ +int mspace_trim(mspace msp, size_t pad); + +/* + An alias for mallopt. +*/ +int mspace_mallopt(int, int); + +#endif /* MSPACES */ + +#ifdef __cplusplus +}; /* end of extern "C" */ +#endif /* __cplusplus */ + +/* + ======================================================================== + To make a fully customizable malloc.h header file, cut everything + above this line, put into file malloc.h, edit to suit, and #include it + on the next line, as well as in programs that use this malloc. + ======================================================================== +*/ + +/* #include "malloc.h" */ + +/*------------------------------ internal #includes ---------------------- */ + +#ifdef WIN32 +#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ +#endif /* WIN32 */ + +#include <stdio.h> /* for printing in malloc_stats */ + +#ifndef LACKS_ERRNO_H +#include <errno.h> /* for MALLOC_FAILURE_ACTION */ +#endif /* LACKS_ERRNO_H */ +#if FOOTERS || DEBUG +#include <time.h> /* for magic initialization */ +#endif /* FOOTERS */ +#ifndef LACKS_STDLIB_H +#include <stdlib.h> /* for abort() */ +#endif /* LACKS_STDLIB_H */ +#ifdef DEBUG +#if ABORT_ON_ASSERT_FAILURE +#undef assert +#define assert(x) if(!(x)) ABORT +#else /* ABORT_ON_ASSERT_FAILURE */ +#include <assert.h> +#endif /* ABORT_ON_ASSERT_FAILURE */ +#else /* DEBUG */ +#ifndef assert +#define assert(x) +#endif +#define DEBUG 0 +#endif /* DEBUG */ +#ifndef LACKS_STRING_H +#include <string.h> /* for memset etc */ +#endif /* LACKS_STRING_H */ +#if USE_BUILTIN_FFS +#ifndef LACKS_STRINGS_H +#include <strings.h> /* for ffs */ +#endif /* LACKS_STRINGS_H */ +#endif /* USE_BUILTIN_FFS */ +#if HAVE_MMAP +#ifndef LACKS_SYS_MMAN_H +/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */ +#if (defined(linux) && !defined(__USE_GNU)) +#define __USE_GNU 1 +#include <sys/mman.h> /* for mmap */ +#undef __USE_GNU +#else +#include <sys/mman.h> /* for mmap */ +#endif /* linux */ +#endif /* LACKS_SYS_MMAN_H */ +#ifndef LACKS_FCNTL_H +#include <fcntl.h> +#endif /* LACKS_FCNTL_H */ +#endif /* HAVE_MMAP */ +#ifndef LACKS_UNISTD_H +#include <unistd.h> /* for sbrk, sysconf */ +#else /* LACKS_UNISTD_H */ +#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) +//extern "C" { void* sbrk(ptrdiff_t); }; +#endif /* FreeBSD etc */ +#endif /* LACKS_UNISTD_H */ + +/* Declarations for locking */ +#if USE_LOCKS +#ifndef WIN32 +#include <pthread.h> +#if defined (__SVR4) && defined (__sun) /* solaris */ +#include <thread.h> +#endif /* solaris */ +#else +#ifndef _M_AMD64 +/* These are already defined on AMD64 builds */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp); +LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value); +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* _M_AMD64 */ +#pragma intrinsic (_InterlockedCompareExchange) +#pragma intrinsic (_InterlockedExchange) +#define interlockedcompareexchange _InterlockedCompareExchange +#define interlockedexchange _InterlockedExchange +#endif /* Win32 */ +#endif /* USE_LOCKS */ + +/* Declarations for bit scanning on win32 */ +#if defined(_MSC_VER) && _MSC_VER>=1300 +#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +unsigned char _BitScanForward(unsigned long *index, unsigned long mask); +unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#define BitScanForward _BitScanForward +#define BitScanReverse _BitScanReverse +#pragma intrinsic(_BitScanForward) +#pragma intrinsic(_BitScanReverse) +#endif /* BitScanForward */ +#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */ + +#ifndef WIN32 +#ifndef malloc_getpagesize +# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ +# ifndef _SC_PAGE_SIZE +# define _SC_PAGE_SIZE _SC_PAGESIZE +# endif +# endif +# ifdef _SC_PAGE_SIZE +# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) +# else +# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) + extern size_t getpagesize(); +# define malloc_getpagesize getpagesize() +# else +# ifdef WIN32 /* use supplied emulation of getpagesize */ +# define malloc_getpagesize getpagesize() +# else +# ifndef LACKS_SYS_PARAM_H +# include <sys/param.h> +# endif +# ifdef EXEC_PAGESIZE +# define malloc_getpagesize EXEC_PAGESIZE +# else +# ifdef NBPG +# ifndef CLSIZE +# define malloc_getpagesize NBPG +# else +# define malloc_getpagesize (NBPG * CLSIZE) +# endif +# else +# ifdef NBPC +# define malloc_getpagesize NBPC +# else +# ifdef PAGESIZE +# define malloc_getpagesize PAGESIZE +# else /* just guess */ +# define malloc_getpagesize ((size_t)4096U) +# endif +# endif +# endif +# endif +# endif +# endif +# endif +#endif +#endif + + + +/* ------------------- size_t and alignment properties -------------------- */ + +/* The byte and bit size of a size_t */ +#define SIZE_T_SIZE (sizeof(size_t)) +#define SIZE_T_BITSIZE (sizeof(size_t) << 3) + +/* Some constants coerced to size_t */ +/* Annoying but necessary to avoid errors on some platforms */ +#define SIZE_T_ZERO ((size_t)0) +#define SIZE_T_ONE ((size_t)1) +#define SIZE_T_TWO ((size_t)2) +#define SIZE_T_FOUR ((size_t)4) +#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) +#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) +#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) +#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) + +/* The bit mask value corresponding to MALLOC_ALIGNMENT */ +#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) + +/* True if address a has acceptable alignment */ +#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) + +/* the number of bytes to offset an address to align it */ +#define align_offset(A)\ + ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ + ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) + +/* -------------------------- MMAP preliminaries ------------------------- */ + +/* + If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and + checks to fail so compiler optimizer can delete code rather than + using so many "#if"s. +*/ + + +/* MORECORE and MMAP must return MFAIL on failure */ +#define MFAIL ((void*)(MAX_SIZE_T)) +#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ + +#if HAVE_MMAP + +#ifndef WIN32 +#define MUNMAP_DEFAULT(a, s) munmap((a), (s)) +#define MMAP_PROT (PROT_READ|PROT_WRITE) +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) +#define MAP_ANONYMOUS MAP_ANON +#endif /* MAP_ANON */ +#ifdef MAP_ANONYMOUS +#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) +#define MMAP_DEFAULT(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) +#else /* MAP_ANONYMOUS */ +/* + Nearly all versions of mmap support MAP_ANONYMOUS, so the following + is unlikely to be needed, but is supplied just in case. +*/ +#define MMAP_FLAGS (MAP_PRIVATE) +static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ +#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \ + (dev_zero_fd = open("/dev/zero", O_RDWR), \ + mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ + mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) +#endif /* MAP_ANONYMOUS */ + +#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s) + +#else /* WIN32 */ + +/* Win32 MMAP via VirtualAlloc */ +static FORCEINLINE void* win32mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); + return (ptr != 0)? ptr: MFAIL; +} + +/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ +static FORCEINLINE void* win32direct_mmap(size_t size) { + void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, + PAGE_READWRITE); + return (ptr != 0)? ptr: MFAIL; +} + +/* This function supports releasing coalesed segments */ +static FORCEINLINE int win32munmap(void* ptr, size_t size) { + MEMORY_BASIC_INFORMATION minfo; + char* cptr = (char*)ptr; + while (size) { + if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) + return -1; + if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || + minfo.State != MEM_COMMIT || minfo.RegionSize > size) + return -1; + if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) + return -1; + cptr += minfo.RegionSize; + size -= minfo.RegionSize; + } + return 0; +} + +#define MMAP_DEFAULT(s) win32mmap(s) +#define MUNMAP_DEFAULT(a, s) win32munmap((a), (s)) +#define DIRECT_MMAP_DEFAULT(s) win32direct_mmap(s) +#endif /* WIN32 */ +#endif /* HAVE_MMAP */ + +#if HAVE_MREMAP +#ifndef WIN32 +#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) +#endif /* WIN32 */ +#endif /* HAVE_MREMAP */ + + +/** + * Define CALL_MORECORE + */ +#if HAVE_MORECORE + #ifdef MORECORE + #define CALL_MORECORE(S) MORECORE(S) + #else /* MORECORE */ + #define CALL_MORECORE(S) MORECORE_DEFAULT(S) + #endif /* MORECORE */ +#else /* HAVE_MORECORE */ + #define CALL_MORECORE(S) MFAIL +#endif /* HAVE_MORECORE */ + +/** + * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP + */ +#if HAVE_MMAP + #define USE_MMAP_BIT (SIZE_T_ONE) + + #ifdef MMAP + #define CALL_MMAP(s) MMAP(s) + #else /* MMAP */ + #define CALL_MMAP(s) MMAP_DEFAULT(s) + #endif /* MMAP */ + #ifdef MUNMAP + #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) + #else /* MUNMAP */ + #define CALL_MUNMAP(a, s) MUNMAP_DEFAULT((a), (s)) + #endif /* MUNMAP */ + #ifdef DIRECT_MMAP + #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) + #else /* DIRECT_MMAP */ + #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s) + #endif /* DIRECT_MMAP */ +#else /* HAVE_MMAP */ + #define USE_MMAP_BIT (SIZE_T_ZERO) + + #define MMAP(s) MFAIL + #define MUNMAP(a, s) (-1) + #define DIRECT_MMAP(s) MFAIL + #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s) + #define CALL_MMAP(s) MMAP(s) + #define CALL_MUNMAP(a, s) MUNMAP((a), (s)) +#endif /* HAVE_MMAP */ + +/** + * Define CALL_MREMAP + */ +#if HAVE_MMAP && HAVE_MREMAP + #ifdef MREMAP + #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv)) + #else /* MREMAP */ + #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv)) + #endif /* MREMAP */ +#else /* HAVE_MMAP && HAVE_MREMAP */ + #define CALL_MREMAP(addr, osz, nsz, mv) MFAIL +#endif /* HAVE_MMAP && HAVE_MREMAP */ + +/* mstate bit set if continguous morecore disabled or failed */ +#define USE_NONCONTIGUOUS_BIT (4U) + +/* segment bit set in create_mspace_with_base */ +#define EXTERN_BIT (8U) + + +/* --------------------------- Lock preliminaries ------------------------ */ + +/* + When locks are defined, there is one global lock, plus + one per-mspace lock. + + The global lock_ensures that mparams.magic and other unique + mparams values are initialized only once. It also protects + sequences of calls to MORECORE. In many cases sys_alloc requires + two calls, that should not be interleaved with calls by other + threads. This does not protect against direct calls to MORECORE + by other threads not using this lock, so there is still code to + cope the best we can on interference. + + Per-mspace locks surround calls to malloc, free, etc. To enable use + in layered extensions, per-mspace locks are reentrant. + + Because lock-protected regions generally have bounded times, it is + OK to use the supplied simple spinlocks in the custom versions for + x86. Spinlocks are likely to improve performance for lightly + contended applications, but worsen performance under heavy + contention. + + If USE_LOCKS is > 1, the definitions of lock routines here are + bypassed, in which case you will need to define the type MLOCK_T, + and at least INITIAL_LOCK, ACQUIRE_LOCK, RELEASE_LOCK and possibly + TRY_LOCK (which is not used in this malloc, but commonly needed in + extensions.) You must also declare a + static MLOCK_T malloc_global_mutex = { initialization values };. + +*/ + +#if USE_LOCKS == 1 + +#if USE_SPIN_LOCKS && SPIN_LOCKS_AVAILABLE +#ifndef WIN32 + +/* Custom pthread-style spin locks on x86 and x64 for gcc */ +struct pthread_mlock_t { + volatile unsigned int l; + unsigned int c; + pthread_t threadid; +}; +#define MLOCK_T struct pthread_mlock_t +#define CURRENT_THREAD pthread_self() +#define INITIAL_LOCK(sl) ((sl)->threadid = 0, (sl)->l = (sl)->c = 0, 0) +#define ACQUIRE_LOCK(sl) pthread_acquire_lock(sl) +#define RELEASE_LOCK(sl) pthread_release_lock(sl) +#define TRY_LOCK(sl) pthread_try_lock(sl) +#define SPINS_PER_YIELD 63 + +static MLOCK_T malloc_global_mutex = { 0, 0, 0}; + +static FORCEINLINE int pthread_acquire_lock (MLOCK_T *sl) { + int spins = 0; + volatile unsigned int* lp = &sl->l; + for (;;) { + if (*lp != 0) { + if (sl->threadid == CURRENT_THREAD) { + ++sl->c; + return 0; + } + } + else { + /* place args to cmpxchgl in locals to evade oddities in some gccs */ + int cmp = 0; + int val = 1; + int ret; + __asm__ __volatile__ ("lock; cmpxchgl %1, %2" + : "=a" (ret) + : "r" (val), "m" (*(lp)), "0"(cmp) + : "memory", "cc"); + if (!ret) { + assert(!sl->threadid); + sl->threadid = CURRENT_THREAD; + sl->c = 1; + return 0; + } + } + if ((++spins & SPINS_PER_YIELD) == 0) { +#if defined (__SVR4) && defined (__sun) /* solaris */ + thr_yield(); +#else +#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) + sched_yield(); +#else /* no-op yield on unknown systems */ + ; +#endif /* __linux__ || __FreeBSD__ || __APPLE__ */ +#endif /* solaris */ + } + } +} + +static FORCEINLINE void pthread_release_lock (MLOCK_T *sl) { + volatile unsigned int* lp = &sl->l; + assert(*lp != 0); + assert(sl->threadid == CURRENT_THREAD); + if (--sl->c == 0) { + sl->threadid = 0; + int prev = 0; + int ret; + __asm__ __volatile__ ("lock; xchgl %0, %1" + : "=r" (ret) + : "m" (*(lp)), "0"(prev) + : "memory"); + } +} + +static FORCEINLINE int pthread_try_lock (MLOCK_T *sl) { + volatile unsigned int* lp = &sl->l; + if (*lp != 0) { + if (sl->threadid == CURRENT_THREAD) { + ++sl->c; + return 1; + } + } + else { + int cmp = 0; + int val = 1; + int ret; + __asm__ __volatile__ ("lock; cmpxchgl %1, %2" + : "=a" (ret) + : "r" (val), "m" (*(lp)), "0"(cmp) + : "memory", "cc"); + if (!ret) { + assert(!sl->threadid); + sl->threadid = CURRENT_THREAD; + sl->c = 1; + return 1; + } + } + return 0; +} + + +#else /* WIN32 */ +/* Custom win32-style spin locks on x86 and x64 for MSC */ +struct win32_mlock_t { + volatile long l; + unsigned int c; + long threadid; +}; + +#define MLOCK_T struct win32_mlock_t +#define CURRENT_THREAD GetCurrentThreadId() +#define INITIAL_LOCK(sl) ((sl)->threadid = 0, (sl)->l = (sl)->c = 0, 0) +#define ACQUIRE_LOCK(sl) win32_acquire_lock(sl) +#define RELEASE_LOCK(sl) win32_release_lock(sl) +#define TRY_LOCK(sl) win32_try_lock(sl) +#define SPINS_PER_YIELD 63 + +static MLOCK_T malloc_global_mutex = { 0, 0, 0}; + +static FORCEINLINE int win32_acquire_lock (MLOCK_T *sl) { + int spins = 0; + for (;;) { + if (sl->l != 0) { + if (sl->threadid == CURRENT_THREAD) { + ++sl->c; + return 0; + } + } + else { + if (!interlockedexchange(&sl->l, 1)) { + assert(!sl->threadid); + sl->threadid = CURRENT_THREAD; + sl->c = 1; + return 0; + } + } + if ((++spins & SPINS_PER_YIELD) == 0) + SleepEx(0, FALSE); + } +} + +static FORCEINLINE void win32_release_lock (MLOCK_T *sl) { + assert(sl->threadid == CURRENT_THREAD); + assert(sl->l != 0); + if (--sl->c == 0) { + sl->threadid = 0; + interlockedexchange (&sl->l, 0); + } +} + +static FORCEINLINE int win32_try_lock (MLOCK_T *sl) { + if (sl->l != 0) { + if (sl->threadid == CURRENT_THREAD) { + ++sl->c; + return 1; + } + } + else { + if (!interlockedexchange(&sl->l, 1)){ + assert(!sl->threadid); + sl->threadid = CURRENT_THREAD; + sl->c = 1; + return 1; + } + } + return 0; +} + +#endif /* WIN32 */ +#else /* USE_SPIN_LOCKS */ + +#ifndef WIN32 +/* pthreads-based locks */ + +#define MLOCK_T pthread_mutex_t +#define CURRENT_THREAD pthread_self() +#define INITIAL_LOCK(sl) pthread_init_lock(sl) +#define ACQUIRE_LOCK(sl) pthread_mutex_lock(sl) +#define RELEASE_LOCK(sl) pthread_mutex_unlock(sl) +#define TRY_LOCK(sl) (!pthread_mutex_trylock(sl)) + +static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER; + +/* Cope with old-style linux recursive lock initialization by adding */ +/* skipped internal declaration from pthread.h */ +#ifdef linux +#ifndef PTHREAD_MUTEX_RECURSIVE +extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr, + int __kind)); +#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP +#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y) +#endif +#endif + +static int pthread_init_lock (MLOCK_T *sl) { + pthread_mutexattr_t attr; + if (pthread_mutexattr_init(&attr)) return 1; + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1; + if (pthread_mutex_init(sl, &attr)) return 1; + if (pthread_mutexattr_destroy(&attr)) return 1; + return 0; +} + +#else /* WIN32 */ +/* Win32 critical sections */ +#define MLOCK_T CRITICAL_SECTION +#define CURRENT_THREAD GetCurrentThreadId() +#define INITIAL_LOCK(s) (!InitializeCriticalSectionAndSpinCount((s), 0x80000000|4000)) +#define ACQUIRE_LOCK(s) (EnterCriticalSection(sl), 0) +#define RELEASE_LOCK(s) LeaveCriticalSection(sl) +#define TRY_LOCK(s) TryEnterCriticalSection(sl) +#define NEED_GLOBAL_LOCK_INIT + +static MLOCK_T malloc_global_mutex; +static volatile long malloc_global_mutex_status; + +/* Use spin loop to initialize global lock */ +static void init_malloc_global_mutex() { + for (;;) { + long stat = malloc_global_mutex_status; + if (stat > 0) + return; + /* transition to < 0 while initializing, then to > 0) */ + if (stat == 0 && + interlockedcompareexchange(&malloc_global_mutex_status, -1, 0) == 0) { + InitializeCriticalSection(&malloc_global_mutex); + interlockedexchange(&malloc_global_mutex_status,1); + return; + } + SleepEx(0, FALSE); + } +} + +#endif /* WIN32 */ +#endif /* USE_SPIN_LOCKS */ +#endif /* USE_LOCKS == 1 */ + +/* ----------------------- User-defined locks ------------------------ */ + +#if USE_LOCKS > 1 +/* Define your own lock implementation here */ +/* #define INITIAL_LOCK(sl) ... */ +/* #define ACQUIRE_LOCK(sl) ... */ +/* #define RELEASE_LOCK(sl) ... */ +/* #define TRY_LOCK(sl) ... */ +/* static MLOCK_T malloc_global_mutex = ... */ +#endif /* USE_LOCKS > 1 */ + +/* ----------------------- Lock-based state ------------------------ */ + +#if USE_LOCKS +#define USE_LOCK_BIT (2U) +#else /* USE_LOCKS */ +#define USE_LOCK_BIT (0U) +#define INITIAL_LOCK(l) +#endif /* USE_LOCKS */ + +#if USE_LOCKS +#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK +#define ACQUIRE_MALLOC_GLOBAL_LOCK() ACQUIRE_LOCK(&malloc_global_mutex); +#endif +#ifndef RELEASE_MALLOC_GLOBAL_LOCK +#define RELEASE_MALLOC_GLOBAL_LOCK() RELEASE_LOCK(&malloc_global_mutex); +#endif +#else /* USE_LOCKS */ +#define ACQUIRE_MALLOC_GLOBAL_LOCK() +#define RELEASE_MALLOC_GLOBAL_LOCK() +#endif /* USE_LOCKS */ + + +/* ----------------------- Chunk representations ------------------------ */ + +/* + (The following includes lightly edited explanations by Colin Plumb.) + + The malloc_chunk declaration below is misleading (but accurate and + necessary). It declares a "view" into memory allowing access to + necessary fields at known offsets from a given base. + + Chunks of memory are maintained using a `boundary tag' method as + originally described by Knuth. (See the paper by Paul Wilson + ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such + techniques.) Sizes of free chunks are stored both in the front of + each chunk and at the end. This makes consolidating fragmented + chunks into bigger chunks fast. The head fields also hold bits + representing whether chunks are free or in use. + + Here are some pictures to make it clearer. They are "exploded" to + show that the state of a chunk can be thought of as extending from + the high 31 bits of the head field of its header through the + prev_foot and PINUSE_BIT bit of the following chunk header. + + A chunk that's in use looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk (if P = 0) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 1| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | | + +- -+ + | | + +- -+ + | : + +- size - sizeof(size_t) available payload bytes -+ + : | + chunk-> +- -+ + | | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| + | Size of next chunk (may or may not be in use) | +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + And if it's free, it looks like this: + + chunk-> +- -+ + | User payload (must be in use, or we would have merged!) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| + | Size of this chunk 0| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Next pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Prev pointer | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- size - sizeof(struct chunk) unused bytes -+ + : | + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| + | Size of next chunk (must be in use, or we would have merged)| +-+ + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | : + +- User payload -+ + : | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |0| + +-+ + Note that since we always merge adjacent free chunks, the chunks + adjacent to a free chunk must be in use. + + Given a pointer to a chunk (which can be derived trivially from the + payload pointer) we can, in O(1) time, find out whether the adjacent + chunks are free, and if so, unlink them from the lists that they + are on and merge them with the current chunk. + + Chunks always begin on even word boundaries, so the mem portion + (which is returned to the user) is also on an even word boundary, and + thus at least double-word aligned. + + The P (PINUSE_BIT) bit, stored in the unused low-order bit of the + chunk size (which is always a multiple of two words), is an in-use + bit for the *previous* chunk. If that bit is *clear*, then the + word before the current chunk size contains the previous chunk + size, and can be used to find the front of the previous chunk. + The very first chunk allocated always has this bit set, preventing + access to non-existent (or non-owned) memory. If pinuse is set for + any given chunk, then you CANNOT determine the size of the + previous chunk, and might even get a memory addressing fault when + trying to do so. + + The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of + the chunk size redundantly records whether the current chunk is + inuse (unless the chunk is mmapped). This redundancy enables usage + checks within free and realloc, and reduces indirection when freeing + and consolidating chunks. + + Each freshly allocated chunk must have both cinuse and pinuse set. + That is, each allocated chunk borders either a previously allocated + and still in-use chunk, or the base of its memory arena. This is + ensured by making all allocations from the the `lowest' part of any + found chunk. Further, no free chunk physically borders another one, + so each free chunk is known to be preceded and followed by either + inuse chunks or the ends of memory. + + Note that the `foot' of the current chunk is actually represented + as the prev_foot of the NEXT chunk. This makes it easier to + deal with alignments etc but can be very confusing when trying + to extend or adapt this code. + + The exceptions to all this are + + 1. The special chunk `top' is the top-most available chunk (i.e., + the one bordering the end of available memory). It is treated + specially. Top is never included in any bin, is used only if + no other chunk is available, and is released back to the + system if it is very large (see M_TRIM_THRESHOLD). In effect, + the top chunk is treated as larger (and thus less well + fitting) than any other available chunk. The top chunk + doesn't update its trailing size field since there is no next + contiguous chunk that would have to index off it. However, + space is still allocated for it (TOP_FOOT_SIZE) to enable + separation or merging when space is extended. + + 3. Chunks allocated via mmap, have both cinuse and pinuse bits + cleared in their head fields. Because they are allocated + one-by-one, each must carry its own prev_foot field, which is + also used to hold the offset this chunk has within its mmapped + region, which is needed to preserve alignment. Each mmapped + chunk is trailed by the first two fields of a fake next-chunk + for sake of usage checks. + +*/ + +struct malloc_chunk { + size_t prev_foot; /* Size of previous chunk (if free). */ + size_t head; /* Size and inuse bits. */ + struct malloc_chunk* fd; /* double links -- used only if free. */ + struct malloc_chunk* bk; +}; + +typedef struct malloc_chunk mchunk; +typedef struct malloc_chunk* mchunkptr; +typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ +typedef unsigned int bindex_t; /* Described below */ +typedef unsigned int binmap_t; /* Described below */ +typedef unsigned int flag_t; /* The type of various bit flag sets */ + +/* ------------------- Chunks sizes and alignments ----------------------- */ + +#define MCHUNK_SIZE (sizeof(mchunk)) + +#if FOOTERS +#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +#else /* FOOTERS */ +#define CHUNK_OVERHEAD (SIZE_T_SIZE) +#endif /* FOOTERS */ + +/* MMapped chunks need a second word of overhead ... */ +#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) +/* ... and additional padding for fake next-chunk at foot */ +#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) + +/* The smallest size we can malloc is an aligned minimal chunk */ +#define MIN_CHUNK_SIZE\ + ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* conversion from malloc headers to user pointers, and back */ +#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) +#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) +/* chunk associated with aligned address A */ +#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) + +/* Bounds on request (not chunk) sizes. */ +#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) +#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) + +/* pad request bytes into a usable size */ +#define pad_request(req) \ + (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) + +/* pad request, checking for minimum (but not maximum) */ +#define request2size(req) \ + (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) + + +/* ------------------ Operations on head and foot fields ----------------- */ + +/* + The head field of a chunk is or'ed with PINUSE_BIT when previous + adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in + use, unless mmapped, in which case both bits are cleared. + + FLAG4_BIT is not used by this malloc, but might be useful in extensions. +*/ + +#define PINUSE_BIT (SIZE_T_ONE) +#define CINUSE_BIT (SIZE_T_TWO) +#define FLAG4_BIT (SIZE_T_FOUR) +#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) +#define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT) + +/* Head value for fenceposts */ +#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) + +/* extraction of fields from head words */ +#define cinuse(p) ((p)->head & CINUSE_BIT) +#define pinuse(p) ((p)->head & PINUSE_BIT) +#define is_inuse(p) (((p)->head & INUSE_BITS) != PINUSE_BIT) +#define is_mmapped(p) (((p)->head & INUSE_BITS) == 0) + +#define chunksize(p) ((p)->head & ~(FLAG_BITS)) + +#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) + +/* Treat space at ptr +/- offset as a chunk */ +#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) +#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) + +/* Ptr to next or previous physical malloc_chunk. */ +#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS))) +#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) + +/* extract next chunk's pinuse bit */ +#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) + +/* Get/set size at footer */ +#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) +#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) + +/* Set size, pinuse bit, and foot */ +#define set_size_and_pinuse_of_free_chunk(p, s)\ + ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) + +/* Set size, pinuse bit, foot, and clear next pinuse */ +#define set_free_with_pinuse(p, s, n)\ + (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) + +/* Get the internal overhead associated with chunk p */ +#define overhead_for(p)\ + (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) + +/* Return true if malloced space is not necessarily cleared */ +#if MMAP_CLEARS +#define calloc_must_clear(p) (!is_mmapped(p)) +#else /* MMAP_CLEARS */ +#define calloc_must_clear(p) (1) +#endif /* MMAP_CLEARS */ + +/* ---------------------- Overlaid data structures ----------------------- */ + +/* + When chunks are not in use, they are treated as nodes of either + lists or trees. + + "Small" chunks are stored in circular doubly-linked lists, and look + like this: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk in list | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space (may be 0 bytes long) . + . . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Larger chunks are kept in a form of bitwise digital trees (aka + tries) keyed on chunksizes. Because malloc_tree_chunks are only for + free chunks greater than 256 bytes, their size doesn't impose any + constraints on user chunk sizes. Each node looks like: + + chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Size of previous chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `head:' | Size of chunk, in bytes |P| + mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Forward pointer to next chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Back pointer to previous chunk of same size | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to left child (child[0]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to right child (child[1]) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Pointer to parent | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | bin index of this chunk | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | Unused space . + . | +nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + `foot:' | Size of chunk, in bytes | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + Each tree holding treenodes is a tree of unique chunk sizes. Chunks + of the same size are arranged in a circularly-linked list, with only + the oldest chunk (the next to be used, in our FIFO ordering) + actually in the tree. (Tree members are distinguished by a non-null + parent pointer.) If a chunk with the same size an an existing node + is inserted, it is linked off the existing node using pointers that + work in the same way as fd/bk pointers of small chunks. + + Each tree contains a power of 2 sized range of chunk sizes (the + smallest is 0x100 <= x < 0x180), which is is divided in half at each + tree level, with the chunks in the smaller half of the range (0x100 + <= x < 0x140 for the top nose) in the left subtree and the larger + half (0x140 <= x < 0x180) in the right subtree. This is, of course, + done by inspecting individual bits. + + Using these rules, each node's left subtree contains all smaller + sizes than its right subtree. However, the node at the root of each + subtree has no particular ordering relationship to either. (The + dividing line between the subtree sizes is based on trie relation.) + If we remove the last chunk of a given size from the interior of the + tree, we need to replace it with a leaf node. The tree ordering + rules permit a node to be replaced by any leaf below it. + + The smallest chunk in a tree (a common operation in a best-fit + allocator) can be found by walking a path to the leftmost leaf in + the tree. Unlike a usual binary tree, where we follow left child + pointers until we reach a null, here we follow the right child + pointer any time the left one is null, until we reach a leaf with + both child pointers null. The smallest chunk in the tree will be + somewhere along that path. + + The worst case number of steps to add, find, or remove a node is + bounded by the number of bits differentiating chunks within + bins. Under current bin calculations, this ranges from 6 up to 21 + (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case + is of course much better. +*/ + +struct malloc_tree_chunk { + /* The first four fields must be compatible with malloc_chunk */ + size_t prev_foot; + size_t head; + struct malloc_tree_chunk* fd; + struct malloc_tree_chunk* bk; + + struct malloc_tree_chunk* child[2]; + struct malloc_tree_chunk* parent; + bindex_t index; +}; + +typedef struct malloc_tree_chunk tchunk; +typedef struct malloc_tree_chunk* tchunkptr; +typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ + +/* A little helper macro for trees */ +#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) + +/* ----------------------------- Segments -------------------------------- */ + +/* + Each malloc space may include non-contiguous segments, held in a + list headed by an embedded malloc_segment record representing the + top-most space. Segments also include flags holding properties of + the space. Large chunks that are directly allocated by mmap are not + included in this list. They are instead independently created and + destroyed without otherwise keeping track of them. + + Segment management mainly comes into play for spaces allocated by + MMAP. Any call to MMAP might or might not return memory that is + adjacent to an existing segment. MORECORE normally contiguously + extends the current space, so this space is almost always adjacent, + which is simpler and faster to deal with. (This is why MORECORE is + used preferentially to MMAP when both are available -- see + sys_alloc.) When allocating using MMAP, we don't use any of the + hinting mechanisms (inconsistently) supported in various + implementations of unix mmap, or distinguish reserving from + committing memory. Instead, we just ask for space, and exploit + contiguity when we get it. It is probably possible to do + better than this on some systems, but no general scheme seems + to be significantly better. + + Management entails a simpler variant of the consolidation scheme + used for chunks to reduce fragmentation -- new adjacent memory is + normally prepended or appended to an existing segment. However, + there are limitations compared to chunk consolidation that mostly + reflect the fact that segment processing is relatively infrequent + (occurring only when getting memory from system) and that we + don't expect to have huge numbers of segments: + + * Segments are not indexed, so traversal requires linear scans. (It + would be possible to index these, but is not worth the extra + overhead and complexity for most programs on most platforms.) + * New segments are only appended to old ones when holding top-most + memory; if they cannot be prepended to others, they are held in + different segments. + + Except for the top-most segment of an mstate, each segment record + is kept at the tail of its segment. Segments are added by pushing + segment records onto the list headed by &mstate.seg for the + containing mstate. + + Segment flags control allocation/merge/deallocation policies: + * If EXTERN_BIT set, then we did not allocate this segment, + and so should not try to deallocate or merge with others. + (This currently holds only for the initial segment passed + into create_mspace_with_base.) + * If USE_MMAP_BIT set, the segment may be merged with + other surrounding mmapped segments and trimmed/de-allocated + using munmap. + * If neither bit is set, then the segment was obtained using + MORECORE so can be merged with surrounding MORECORE'd segments + and deallocated/trimmed using MORECORE with negative arguments. +*/ + +struct malloc_segment { + char* base; /* base address */ + size_t size; /* allocated size */ + struct malloc_segment* next; /* ptr to next segment */ + flag_t sflags; /* mmap and extern flag */ +}; + +#define is_mmapped_segment(S) ((S)->sflags & USE_MMAP_BIT) +#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) + +typedef struct malloc_segment msegment; +typedef struct malloc_segment* msegmentptr; + +/* ---------------------------- malloc_state ----------------------------- */ + +/* + A malloc_state holds all of the bookkeeping for a space. + The main fields are: + + Top + The topmost chunk of the currently active segment. Its size is + cached in topsize. The actual size of topmost space is + topsize+TOP_FOOT_SIZE, which includes space reserved for adding + fenceposts and segment records if necessary when getting more + space from the system. The size at which to autotrim top is + cached from mparams in trim_check, except that it is disabled if + an autotrim fails. + + Designated victim (dv) + This is the preferred chunk for servicing small requests that + don't have exact fits. It is normally the chunk split off most + recently to service another small request. Its size is cached in + dvsize. The link fields of this chunk are not maintained since it + is not kept in a bin. + + SmallBins + An array of bin headers for free chunks. These bins hold chunks + with sizes less than MIN_LARGE_SIZE bytes. Each bin contains + chunks of all the same size, spaced 8 bytes apart. To simplify + use in double-linked lists, each bin header acts as a malloc_chunk + pointing to the real first node, if it exists (else pointing to + itself). This avoids special-casing for headers. But to avoid + waste, we allocate only the fd/bk pointers of bins, and then use + repositioning tricks to treat these as the fields of a chunk. + + TreeBins + Treebins are pointers to the roots of trees holding a range of + sizes. There are 2 equally spaced treebins for each power of two + from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything + larger. + + Bin maps + There is one bit map for small bins ("smallmap") and one for + treebins ("treemap). Each bin sets its bit when non-empty, and + clears the bit when empty. Bit operations are then used to avoid + bin-by-bin searching -- nearly all "search" is done without ever + looking at bins that won't be selected. The bit maps + conservatively use 32 bits per map word, even if on 64bit system. + For a good description of some of the bit-based techniques used + here, see Henry S. Warren Jr's book "Hacker's Delight" (and + supplement at http://hackersdelight.org/). Many of these are + intended to reduce the branchiness of paths through malloc etc, as + well as to reduce the number of memory locations read or written. + + Segments + A list of segments headed by an embedded malloc_segment record + representing the initial space. + + Address check support + The least_addr field is the least address ever obtained from + MORECORE or MMAP. Attempted frees and reallocs of any address less + than this are trapped (unless INSECURE is defined). + + Magic tag + A cross-check field that should always hold same value as mparams.magic. + + Flags + Bits recording whether to use MMAP, locks, or contiguous MORECORE + + Statistics + Each space keeps track of current and maximum system memory + obtained via MORECORE or MMAP. + + Trim support + Fields holding the amount of unused topmost memory that should trigger + timming, and a counter to force periodic scanning to release unused + non-topmost segments. + + Locking + If USE_LOCKS is defined, the "mutex" lock is acquired and released + around every public call using this mspace. + + Extension support + A void* pointer and a size_t field that can be used to help implement + extensions to this malloc. +*/ + +/* Bin types, widths and sizes */ +#define NSMALLBINS (32U) +#define NTREEBINS (32U) +#define SMALLBIN_SHIFT (3U) +#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) +#define TREEBIN_SHIFT (8U) +#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) +#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) +#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) + +struct malloc_state { + binmap_t smallmap; + binmap_t treemap; + size_t dvsize; + size_t topsize; + char* least_addr; + mchunkptr dv; + mchunkptr top; + size_t trim_check; + size_t release_checks; + size_t magic; + mchunkptr smallbins[(NSMALLBINS+1)*2]; + tbinptr treebins[NTREEBINS]; + size_t footprint; + size_t max_footprint; + flag_t mflags; +#if USE_LOCKS + MLOCK_T mutex; /* locate lock among fields that rarely change */ +#endif /* USE_LOCKS */ + msegment seg; + void* extp; /* Unused but available for extensions */ + size_t exts; +}; + +typedef struct malloc_state* mstate; + +/* ------------- Global malloc_state and malloc_params ------------------- */ + +/* + malloc_params holds global properties, including those that can be + dynamically set using mallopt. There is a single instance, mparams, + initialized in init_mparams. Note that the non-zeroness of "magic" + also serves as an initialization flag. +*/ + +struct malloc_params { + volatile size_t magic; + size_t page_size; + size_t granularity; + size_t mmap_threshold; + size_t trim_threshold; + flag_t default_mflags; +}; + +static struct malloc_params mparams; + +/* Ensure mparams initialized */ +#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams()) + +#if !ONLY_MSPACES + +/* The global malloc_state used for all non-"mspace" calls */ +static struct malloc_state _gm_; +#define gm (&_gm_) +#define is_global(M) ((M) == &_gm_) + +#endif /* !ONLY_MSPACES */ + +#define is_initialized(M) ((M)->top != 0) + +/* -------------------------- system alloc setup ------------------------- */ + +/* Operations on mflags */ + +#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) +#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) +#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) + +#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) +#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) +#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) + +#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) +#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) + +#define set_lock(M,L)\ + ((M)->mflags = (L)?\ + ((M)->mflags | USE_LOCK_BIT) :\ + ((M)->mflags & ~USE_LOCK_BIT)) + +/* page-align a size */ +#define page_align(S)\ + (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) + +/* granularity-align a size */ +#define granularity_align(S)\ + (((S) + (mparams.granularity - SIZE_T_ONE))\ + & ~(mparams.granularity - SIZE_T_ONE)) + + +/* For mmap, use granularity alignment on windows, else page-align */ +#ifdef WIN32 +#define mmap_align(S) granularity_align(S) +#else +#define mmap_align(S) page_align(S) +#endif + +/* For sys_alloc, enough padding to ensure can malloc request on success */ +#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT) + +#define is_page_aligned(S)\ + (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) +#define is_granularity_aligned(S)\ + (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) + +/* True if segment S holds address A */ +#define segment_holds(S, A)\ + ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) + +/* Return segment holding given address */ +static msegmentptr segment_holding(mstate m, char* addr) { + msegmentptr sp = &m->seg; + for (;;) { + if (addr >= sp->base && addr < sp->base + sp->size) + return sp; + if ((sp = sp->next) == 0) + return 0; + } +} + +/* Return true if segment contains a segment link */ +static int has_segment_link(mstate m, msegmentptr ss) { + msegmentptr sp = &m->seg; + for (;;) { + if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) + return 1; + if ((sp = sp->next) == 0) + return 0; + } +} + +#ifndef MORECORE_CANNOT_TRIM +#define should_trim(M,s) ((s) > (M)->trim_check) +#else /* MORECORE_CANNOT_TRIM */ +#define should_trim(M,s) (0) +#endif /* MORECORE_CANNOT_TRIM */ + +/* + TOP_FOOT_SIZE is padding at the end of a segment, including space + that may be needed to place segment records and fenceposts when new + noncontiguous segments are added. +*/ +#define TOP_FOOT_SIZE\ + (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) + + +/* ------------------------------- Hooks -------------------------------- */ + +/* + PREACTION should be defined to return 0 on success, and nonzero on + failure. If you are not using locking, you can redefine these to do + anything you like. +*/ + +#if USE_LOCKS + +#define PREACTION(M) ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) +#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } +#else /* USE_LOCKS */ + +#ifndef PREACTION +#define PREACTION(M) (0) +#endif /* PREACTION */ + +#ifndef POSTACTION +#define POSTACTION(M) +#endif /* POSTACTION */ + +#endif /* USE_LOCKS */ + +/* + CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. + USAGE_ERROR_ACTION is triggered on detected bad frees and + reallocs. The argument p is an address that might have triggered the + fault. It is ignored by the two predefined actions, but might be + useful in custom actions that try to help diagnose errors. +*/ + +#if PROCEED_ON_ERROR + +/* A count of the number of corruption errors causing resets */ +int malloc_corruption_error_count; + +/* default corruption action */ +static void reset_on_error(mstate m); + +#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) +#define USAGE_ERROR_ACTION(m, p) + +#else /* PROCEED_ON_ERROR */ + +#ifndef CORRUPTION_ERROR_ACTION +#define CORRUPTION_ERROR_ACTION(m) ABORT +#endif /* CORRUPTION_ERROR_ACTION */ + +#ifndef USAGE_ERROR_ACTION +#define USAGE_ERROR_ACTION(m,p) ABORT +#endif /* USAGE_ERROR_ACTION */ + +#endif /* PROCEED_ON_ERROR */ + +/* -------------------------- Debugging setup ---------------------------- */ + +#if ! DEBUG + +#define check_free_chunk(M,P) +#define check_inuse_chunk(M,P) +#define check_malloced_chunk(M,P,N) +#define check_mmapped_chunk(M,P) +#define check_malloc_state(M) +#define check_top_chunk(M,P) + +#else /* DEBUG */ +#define check_free_chunk(M,P) do_check_free_chunk(M,P) +#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) +#define check_top_chunk(M,P) do_check_top_chunk(M,P) +#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) +#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) +#define check_malloc_state(M) do_check_malloc_state(M) + +static void do_check_any_chunk(mstate m, mchunkptr p); +static void do_check_top_chunk(mstate m, mchunkptr p); +static void do_check_mmapped_chunk(mstate m, mchunkptr p); +static void do_check_inuse_chunk(mstate m, mchunkptr p); +static void do_check_free_chunk(mstate m, mchunkptr p); +static void do_check_malloced_chunk(mstate m, void* mem, size_t s); +static void do_check_tree(mstate m, tchunkptr t); +static void do_check_treebin(mstate m, bindex_t i); +static void do_check_smallbin(mstate m, bindex_t i); +static void do_check_malloc_state(mstate m); +static int bin_find(mstate m, mchunkptr x); +static size_t traverse_and_check(mstate m); +#endif /* DEBUG */ + +/* ---------------------------- Indexing Bins ---------------------------- */ + +#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) +#define small_index(s) ((s) >> SMALLBIN_SHIFT) +#define small_index2size(i) ((i) << SMALLBIN_SHIFT) +#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) + +/* addressing by index. See above about smallbin repositioning */ +#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) +#define treebin_at(M,i) (&((M)->treebins[i])) + +/* assign tree index for size S to variable I. Use x86 asm if possible */ +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#define compute_tree_index(S, I)\ +{\ + unsigned int X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K;\ + __asm__("bsrl\t%1, %0\n\t" : "=r" (K) : "g" (X));\ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} + +#elif defined (__INTEL_COMPILER) +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K = _bit_scan_reverse (X); \ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} + +#elif defined(_MSC_VER) && _MSC_VER>=1300 +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int K;\ + _BitScanReverse((DWORD *) &K, X);\ + I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ + }\ +} + +#else /* GNUC */ +#define compute_tree_index(S, I)\ +{\ + size_t X = S >> TREEBIN_SHIFT;\ + if (X == 0)\ + I = 0;\ + else if (X > 0xFFFF)\ + I = NTREEBINS-1;\ + else {\ + unsigned int Y = (unsigned int)X;\ + unsigned int N = ((Y - 0x100) >> 16) & 8;\ + unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ + N += K;\ + N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ + K = 14 - N + ((Y <<= K) >> 15);\ + I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ + }\ +} +#endif /* GNUC */ + +/* Bit representing maximum resolved size in a treebin at i */ +#define bit_for_tree_index(i) \ + (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) + +/* Shift placing maximum resolved bit in a treebin at i as sign bit */ +#define leftshift_for_tree_index(i) \ + ((i == NTREEBINS-1)? 0 : \ + ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) + +/* The size of the smallest chunk held in bin with index i */ +#define minsize_for_tree_index(i) \ + ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ + (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) + + +/* ------------------------ Operations on bin maps ----------------------- */ + +/* bit corresponding to given index */ +#define idx2bit(i) ((binmap_t)(1) << (i)) + +/* Mark/Clear bits with given index */ +#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) +#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) +#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) + +#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) +#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) +#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) + +/* isolate the least set bit of a bitmap */ +#define least_bit(x) ((x) & -(x)) + +/* mask with all bits to left of least bit of x on */ +#define left_bits(x) ((x<<1) | -(x<<1)) + +/* mask with all bits to left of or equal to least bit of x on */ +#define same_or_left_bits(x) ((x) | -(x)) + +/* index corresponding to given bit. Use x86 asm if possible */ + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + __asm__("bsfl\t%1, %0\n\t" : "=r" (J) : "g" (X));\ + I = (bindex_t)J;\ +} + +#elif defined (__INTEL_COMPILER) +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + J = _bit_scan_forward (X); \ + I = (bindex_t)J;\ +} + +#elif defined(_MSC_VER) && _MSC_VER>=1300 +#define compute_bit2idx(X, I)\ +{\ + unsigned int J;\ + _BitScanForward((DWORD *) &J, X);\ + I = (bindex_t)J;\ +} + +#elif USE_BUILTIN_FFS +#define compute_bit2idx(X, I) I = ffs(X)-1 + +#else +#define compute_bit2idx(X, I)\ +{\ + unsigned int Y = X - 1;\ + unsigned int K = Y >> (16-4) & 16;\ + unsigned int N = K; Y >>= K;\ + N += K = Y >> (8-3) & 8; Y >>= K;\ + N += K = Y >> (4-2) & 4; Y >>= K;\ + N += K = Y >> (2-1) & 2; Y >>= K;\ + N += K = Y >> (1-0) & 1; Y >>= K;\ + I = (bindex_t)(N + Y);\ +} +#endif /* GNUC */ + + +/* ----------------------- Runtime Check Support ------------------------- */ + +/* + For security, the main invariant is that malloc/free/etc never + writes to a static address other than malloc_state, unless static + malloc_state itself has been corrupted, which cannot occur via + malloc (because of these checks). In essence this means that we + believe all pointers, sizes, maps etc held in malloc_state, but + check all of those linked or offsetted from other embedded data + structures. These checks are interspersed with main code in a way + that tends to minimize their run-time cost. + + When FOOTERS is defined, in addition to range checking, we also + verify footer fields of inuse chunks, which can be used guarantee + that the mstate controlling malloc/free is intact. This is a + streamlined version of the approach described by William Robertson + et al in "Run-time Detection of Heap-based Overflows" LISA'03 + http://www.usenix.org/events/lisa03/tech/robertson.html The footer + of an inuse chunk holds the xor of its mstate and a random seed, + that is checked upon calls to free() and realloc(). This is + (probablistically) unguessable from outside the program, but can be + computed by any code successfully malloc'ing any chunk, so does not + itself provide protection against code that has already broken + security through some other means. Unlike Robertson et al, we + always dynamically check addresses of all offset chunks (previous, + next, etc). This turns out to be cheaper than relying on hashes. +*/ + +#if !INSECURE +/* Check if address a is at least as high as any from MORECORE or MMAP */ +#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) +/* Check if address of next chunk n is higher than base chunk p */ +#define ok_next(p, n) ((char*)(p) < (char*)(n)) +/* Check if p has inuse status */ +#define ok_inuse(p) is_inuse(p) +/* Check if p has its pinuse bit on */ +#define ok_pinuse(p) pinuse(p) + +#else /* !INSECURE */ +#define ok_address(M, a) (1) +#define ok_next(b, n) (1) +#define ok_inuse(p) (1) +#define ok_pinuse(p) (1) +#endif /* !INSECURE */ + +#if (FOOTERS && !INSECURE) +/* Check if (alleged) mstate m has expected magic field */ +#define ok_magic(M) ((M)->magic == mparams.magic) +#else /* (FOOTERS && !INSECURE) */ +#define ok_magic(M) (1) +#endif /* (FOOTERS && !INSECURE) */ + + +/* In gcc, use __builtin_expect to minimize impact of checks */ +#if !INSECURE +#if defined(__GNUC__) && __GNUC__ >= 3 +#define RTCHECK(e) __builtin_expect(e, 1) +#else /* GNUC */ +#define RTCHECK(e) (e) +#endif /* GNUC */ +#else /* !INSECURE */ +#define RTCHECK(e) (1) +#endif /* !INSECURE */ + +/* macros to set up inuse chunks with or without footers */ + +#if !FOOTERS + +#define mark_inuse_foot(M,p,s) + +/* Macros for setting head/foot of non-mmapped chunks */ + +/* Set cinuse bit and pinuse bit of next chunk */ +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) + +/* Set size, cinuse and pinuse bit of this chunk */ +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) + +#else /* FOOTERS */ + +/* Set foot of inuse chunk to be xor of mstate and seed */ +#define mark_inuse_foot(M,p,s)\ + (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) + +#define get_mstate_for(p)\ + ((mstate)(((mchunkptr)((char*)(p) +\ + (chunksize(p))))->prev_foot ^ mparams.magic)) + +#define set_inuse(M,p,s)\ + ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ + mark_inuse_foot(M,p,s)) + +#define set_inuse_and_pinuse(M,p,s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ + mark_inuse_foot(M,p,s)) + +#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ + ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ + mark_inuse_foot(M, p, s)) + +#endif /* !FOOTERS */ + +/* ---------------------------- setting mparams -------------------------- */ + +/* Initialize mparams */ +static int init_mparams(void) { +#ifdef NEED_GLOBAL_LOCK_INIT + if (malloc_global_mutex_status <= 0) + init_malloc_global_mutex(); +#endif + + ACQUIRE_MALLOC_GLOBAL_LOCK(); + if (mparams.magic == 0) { + size_t magic; + size_t psize; + size_t gsize; + +#ifndef WIN32 + psize = malloc_getpagesize; + gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize); +#else /* WIN32 */ + { + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + psize = system_info.dwPageSize; + gsize = ((DEFAULT_GRANULARITY != 0)? + DEFAULT_GRANULARITY : system_info.dwAllocationGranularity); + } +#endif /* WIN32 */ + + /* Sanity-check configuration: + size_t must be unsigned and as wide as pointer type. + ints must be at least 4 bytes. + alignment must be at least 8. + Alignment, min chunk size, and page size must all be powers of 2. + */ + if ((sizeof(size_t) != sizeof(char*)) || + (MAX_SIZE_T < MIN_CHUNK_SIZE) || + (sizeof(int) < 4) || + (MALLOC_ALIGNMENT < (size_t)8U) || + ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || + ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || + ((gsize & (gsize-SIZE_T_ONE)) != 0) || + ((psize & (psize-SIZE_T_ONE)) != 0)) + ABORT; + + mparams.granularity = gsize; + mparams.page_size = psize; + mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; + mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; +#if MORECORE_CONTIGUOUS + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; +#else /* MORECORE_CONTIGUOUS */ + mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; +#endif /* MORECORE_CONTIGUOUS */ + +#if !ONLY_MSPACES + /* Set up lock for main malloc area */ + gm->mflags = mparams.default_mflags; + INITIAL_LOCK(&gm->mutex); +#endif + + { +#if USE_DEV_RANDOM + int fd; + unsigned char buf[sizeof(size_t)]; + /* Try to use /dev/urandom, else fall back on using time */ + if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && + read(fd, buf, sizeof(buf)) == sizeof(buf)) { + magic = *((size_t *) buf); + close(fd); + } + else +#endif /* USE_DEV_RANDOM */ +#ifdef WIN32 + magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U); +#else + magic = (size_t)(time(0) ^ (size_t)0x55555555U); +#endif + magic |= (size_t)8U; /* ensure nonzero */ + magic &= ~(size_t)7U; /* improve chances of fault for bad values */ + mparams.magic = magic; + } + } + + RELEASE_MALLOC_GLOBAL_LOCK(); + return 1; +} + +/* support for mallopt */ +static int change_mparam(int param_number, int value) { + size_t val; + ensure_initialization(); + val = (value == -1)? MAX_SIZE_T : (size_t)value; + switch(param_number) { + case M_TRIM_THRESHOLD: + mparams.trim_threshold = val; + return 1; + case M_GRANULARITY: + if (val >= mparams.page_size && ((val & (val-1)) == 0)) { + mparams.granularity = val; + return 1; + } + else + return 0; + case M_MMAP_THRESHOLD: + mparams.mmap_threshold = val; + return 1; + default: + return 0; + } +} + +#if DEBUG +/* ------------------------- Debugging Support --------------------------- */ + +/* Check properties of any chunk, whether free, inuse, mmapped etc */ +static void do_check_any_chunk(mstate m, mchunkptr p) { + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); +} + +/* Check properties of top chunk */ +static void do_check_top_chunk(mstate m, mchunkptr p) { + msegmentptr sp = segment_holding(m, (char*)p); + size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ + assert(sp != 0); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(sz == m->topsize); + assert(sz > 0); + assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); + assert(pinuse(p)); + assert(!pinuse(chunk_plus_offset(p, sz))); +} + +/* Check properties of (inuse) mmapped chunks */ +static void do_check_mmapped_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD); + assert(is_mmapped(p)); + assert(use_mmap(m)); + assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); + assert(ok_address(m, p)); + assert(!is_small(sz)); + assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); + assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); + assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); +} + +/* Check properties of inuse chunks */ +static void do_check_inuse_chunk(mstate m, mchunkptr p) { + do_check_any_chunk(m, p); + assert(is_inuse(p)); + assert(next_pinuse(p)); + /* If not pinuse and not mmapped, previous chunk has OK offset */ + assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); + if (is_mmapped(p)) + do_check_mmapped_chunk(m, p); +} + +/* Check properties of free chunks */ +static void do_check_free_chunk(mstate m, mchunkptr p) { + size_t sz = chunksize(p); + mchunkptr next = chunk_plus_offset(p, sz); + do_check_any_chunk(m, p); + assert(!is_inuse(p)); + assert(!next_pinuse(p)); + assert (!is_mmapped(p)); + if (p != m->dv && p != m->top) { + if (sz >= MIN_CHUNK_SIZE) { + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(is_aligned(chunk2mem(p))); + assert(next->prev_foot == sz); + assert(pinuse(p)); + assert (next == m->top || is_inuse(next)); + assert(p->fd->bk == p); + assert(p->bk->fd == p); + } + else /* markers are always of size SIZE_T_SIZE */ + assert(sz == SIZE_T_SIZE); + } +} + +/* Check properties of malloced chunks at the point they are malloced */ +static void do_check_malloced_chunk(mstate m, void* mem, size_t s) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + size_t sz = p->head & ~INUSE_BITS; + do_check_inuse_chunk(m, p); + assert((sz & CHUNK_ALIGN_MASK) == 0); + assert(sz >= MIN_CHUNK_SIZE); + assert(sz >= s); + /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ + assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); + } +} + +/* Check a tree and its subtrees. */ +static void do_check_tree(mstate m, tchunkptr t) { + tchunkptr head = 0; + tchunkptr u = t; + bindex_t tindex = t->index; + size_t tsize = chunksize(t); + bindex_t idx; + compute_tree_index(tsize, idx); + assert(tindex == idx); + assert(tsize >= MIN_LARGE_SIZE); + assert(tsize >= minsize_for_tree_index(idx)); + assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); + + do { /* traverse through chain of same-sized nodes */ + do_check_any_chunk(m, ((mchunkptr)u)); + assert(u->index == tindex); + assert(chunksize(u) == tsize); + assert(!is_inuse(u)); + assert(!next_pinuse(u)); + assert(u->fd->bk == u); + assert(u->bk->fd == u); + if (u->parent == 0) { + assert(u->child[0] == 0); + assert(u->child[1] == 0); + } + else { + assert(head == 0); /* only one node on chain has parent */ + head = u; + assert(u->parent != u); + assert (u->parent->child[0] == u || + u->parent->child[1] == u || + *((tbinptr*)(u->parent)) == u); + if (u->child[0] != 0) { + assert(u->child[0]->parent == u); + assert(u->child[0] != u); + do_check_tree(m, u->child[0]); + } + if (u->child[1] != 0) { + assert(u->child[1]->parent == u); + assert(u->child[1] != u); + do_check_tree(m, u->child[1]); + } + if (u->child[0] != 0 && u->child[1] != 0) { + assert(chunksize(u->child[0]) < chunksize(u->child[1])); + } + } + u = u->fd; + } while (u != t); + assert(head != 0); +} + +/* Check all the chunks in a treebin. */ +static void do_check_treebin(mstate m, bindex_t i) { + tbinptr* tb = treebin_at(m, i); + tchunkptr t = *tb; + int empty = (m->treemap & (1U << i)) == 0; + if (t == 0) + assert(empty); + if (!empty) + do_check_tree(m, t); +} + +/* Check all the chunks in a smallbin. */ +static void do_check_smallbin(mstate m, bindex_t i) { + sbinptr b = smallbin_at(m, i); + mchunkptr p = b->bk; + unsigned int empty = (m->smallmap & (1U << i)) == 0; + if (p == b) + assert(empty); + if (!empty) { + for (; p != b; p = p->bk) { + size_t size = chunksize(p); + mchunkptr q; + /* each chunk claims to be free */ + do_check_free_chunk(m, p); + /* chunk belongs in bin */ + assert(small_index(size) == i); + assert(p->bk == b || chunksize(p->bk) == chunksize(p)); + /* chunk is followed by an inuse chunk */ + q = next_chunk(p); + if (q->head != FENCEPOST_HEAD) + do_check_inuse_chunk(m, q); + } + } +} + +/* Find x in a bin. Used in other check functions. */ +static int bin_find(mstate m, mchunkptr x) { + size_t size = chunksize(x); + if (is_small(size)) { + bindex_t sidx = small_index(size); + sbinptr b = smallbin_at(m, sidx); + if (smallmap_is_marked(m, sidx)) { + mchunkptr p = b; + do { + if (p == x) + return 1; + } while ((p = p->fd) != b); + } + } + else { + bindex_t tidx; + compute_tree_index(size, tidx); + if (treemap_is_marked(m, tidx)) { + tchunkptr t = *treebin_at(m, tidx); + size_t sizebits = size << leftshift_for_tree_index(tidx); + while (t != 0 && chunksize(t) != size) { + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + sizebits <<= 1; + } + if (t != 0) { + tchunkptr u = t; + do { + if (u == (tchunkptr)x) + return 1; + } while ((u = u->fd) != t); + } + } + } + return 0; +} + +/* Traverse each chunk and check it; return total */ +static size_t traverse_and_check(mstate m) { + size_t sum = 0; + if (is_initialized(m)) { + msegmentptr s = &m->seg; + sum += m->topsize + TOP_FOOT_SIZE; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + mchunkptr lastq = 0; + assert(pinuse(q)); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + sum += chunksize(q); + if (is_inuse(q)) { + assert(!bin_find(m, q)); + do_check_inuse_chunk(m, q); + } + else { + assert(q == m->dv || bin_find(m, q)); + assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */ + do_check_free_chunk(m, q); + } + lastq = q; + q = next_chunk(q); + } + s = s->next; + } + } + return sum; +} + +/* Check all properties of malloc_state. */ +static void do_check_malloc_state(mstate m) { + bindex_t i; + size_t total; + /* check bins */ + for (i = 0; i < NSMALLBINS; ++i) + do_check_smallbin(m, i); + for (i = 0; i < NTREEBINS; ++i) + do_check_treebin(m, i); + + if (m->dvsize != 0) { /* check dv chunk */ + do_check_any_chunk(m, m->dv); + assert(m->dvsize == chunksize(m->dv)); + assert(m->dvsize >= MIN_CHUNK_SIZE); + assert(bin_find(m, m->dv) == 0); + } + + if (m->top != 0) { /* check top chunk */ + do_check_top_chunk(m, m->top); + /*assert(m->topsize == chunksize(m->top)); redundant */ + assert(m->topsize > 0); + assert(bin_find(m, m->top) == 0); + } + + total = traverse_and_check(m); + assert(total <= m->footprint); + assert(m->footprint <= m->max_footprint); +} +#endif /* DEBUG */ + +/* ----------------------------- statistics ------------------------------ */ + +#if !NO_MALLINFO +static struct mallinfo internal_mallinfo(mstate m) { + struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + ensure_initialization(); + if (!PREACTION(m)) { + check_malloc_state(m); + if (is_initialized(m)) { + size_t nfree = SIZE_T_ONE; /* top always free */ + size_t mfree = m->topsize + TOP_FOOT_SIZE; + size_t sum = mfree; + msegmentptr s = &m->seg; + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + size_t sz = chunksize(q); + sum += sz; + if (!is_inuse(q)) { + mfree += sz; + ++nfree; + } + q = next_chunk(q); + } + s = s->next; + } + + nm.arena = sum; + nm.ordblks = nfree; + nm.hblkhd = m->footprint - sum; + nm.usmblks = m->max_footprint; + nm.uordblks = m->footprint - mfree; + nm.fordblks = mfree; + nm.keepcost = m->topsize; + } + + POSTACTION(m); + } + return nm; +} +#endif /* !NO_MALLINFO */ + +static void internal_malloc_stats(mstate m) { + ensure_initialization(); + if (!PREACTION(m)) { + size_t maxfp = 0; + size_t fp = 0; + size_t used = 0; + check_malloc_state(m); + if (is_initialized(m)) { + msegmentptr s = &m->seg; + maxfp = m->max_footprint; + fp = m->footprint; + used = fp - (m->topsize + TOP_FOOT_SIZE); + + while (s != 0) { + mchunkptr q = align_as_chunk(s->base); + while (segment_holds(s, q) && + q != m->top && q->head != FENCEPOST_HEAD) { + if (!is_inuse(q)) + used -= chunksize(q); + q = next_chunk(q); + } + s = s->next; + } + } + + fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); + fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); + fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); + + POSTACTION(m); + } +} + +/* ----------------------- Operations on smallbins ----------------------- */ + +/* + Various forms of linking and unlinking are defined as macros. Even + the ones for trees, which are very long but have very short typical + paths. This is ugly but reduces reliance on inlining support of + compilers. +*/ + +/* Link a free chunk into a smallbin */ +#define insert_small_chunk(M, P, S) {\ + bindex_t I = small_index(S);\ + mchunkptr B = smallbin_at(M, I);\ + mchunkptr F = B;\ + assert(S >= MIN_CHUNK_SIZE);\ + if (!smallmap_is_marked(M, I))\ + mark_smallmap(M, I);\ + else if (RTCHECK(ok_address(M, B->fd)))\ + F = B->fd;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + B->fd = P;\ + F->bk = P;\ + P->fd = F;\ + P->bk = B;\ +} + +/* Unlink a chunk from a smallbin */ +#define unlink_small_chunk(M, P, S) {\ + mchunkptr F = P->fd;\ + mchunkptr B = P->bk;\ + bindex_t I = small_index(S);\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (F == B)\ + clear_smallmap(M, I);\ + else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\ + (B == smallbin_at(M,I) || ok_address(M, B)))) {\ + F->bk = B;\ + B->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + +/* Unlink the first chunk from a smallbin */ +#define unlink_first_small_chunk(M, B, P, I) {\ + mchunkptr F = P->fd;\ + assert(P != B);\ + assert(P != F);\ + assert(chunksize(P) == small_index2size(I));\ + if (B == F)\ + clear_smallmap(M, I);\ + else if (RTCHECK(ok_address(M, F))) {\ + B->fd = F;\ + F->bk = B;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ +} + + + +/* Replace dv node, binning the old one */ +/* Used only when dvsize known to be small */ +#define replace_dv(M, P, S) {\ + size_t DVS = M->dvsize;\ + if (DVS != 0) {\ + mchunkptr DV = M->dv;\ + assert(is_small(DVS));\ + insert_small_chunk(M, DV, DVS);\ + }\ + M->dvsize = S;\ + M->dv = P;\ +} + +/* ------------------------- Operations on trees ------------------------- */ + +/* Insert chunk into tree */ +#define insert_large_chunk(M, X, S) {\ + tbinptr* H;\ + bindex_t I;\ + compute_tree_index(S, I);\ + H = treebin_at(M, I);\ + X->index = I;\ + X->child[0] = X->child[1] = 0;\ + if (!treemap_is_marked(M, I)) {\ + mark_treemap(M, I);\ + *H = X;\ + X->parent = (tchunkptr)H;\ + X->fd = X->bk = X;\ + }\ + else {\ + tchunkptr T = *H;\ + size_t K = S << leftshift_for_tree_index(I);\ + for (;;) {\ + if (chunksize(T) != S) {\ + tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ + K <<= 1;\ + if (*C != 0)\ + T = *C;\ + else if (RTCHECK(ok_address(M, C))) {\ + *C = X;\ + X->parent = T;\ + X->fd = X->bk = X;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + else {\ + tchunkptr F = T->fd;\ + if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ + T->fd = F->bk = X;\ + X->fd = F;\ + X->bk = T;\ + X->parent = 0;\ + break;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + break;\ + }\ + }\ + }\ + }\ +} + +/* + Unlink steps: + + 1. If x is a chained node, unlink it from its same-sized fd/bk links + and choose its bk node as its replacement. + 2. If x was the last node of its size, but not a leaf node, it must + be replaced with a leaf node (not merely one with an open left or + right), to make sure that lefts and rights of descendents + correspond properly to bit masks. We use the rightmost descendent + of x. We could use any other leaf, but this is easy to locate and + tends to counteract removal of leftmosts elsewhere, and so keeps + paths shorter than minimally guaranteed. This doesn't loop much + because on average a node in a tree is near the bottom. + 3. If x is the base of a chain (i.e., has parent links) relink + x's parent and children to x's replacement (or null if none). +*/ + +#define unlink_large_chunk(M, X) {\ + tchunkptr XP = X->parent;\ + tchunkptr R;\ + if (X->bk != X) {\ + tchunkptr F = X->fd;\ + R = X->bk;\ + if (RTCHECK(ok_address(M, F))) {\ + F->bk = R;\ + R->fd = F;\ + }\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else {\ + tchunkptr* RP;\ + if (((R = *(RP = &(X->child[1]))) != 0) ||\ + ((R = *(RP = &(X->child[0]))) != 0)) {\ + tchunkptr* CP;\ + while ((*(CP = &(R->child[1])) != 0) ||\ + (*(CP = &(R->child[0])) != 0)) {\ + R = *(RP = CP);\ + }\ + if (RTCHECK(ok_address(M, RP)))\ + *RP = 0;\ + else {\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + }\ + if (XP != 0) {\ + tbinptr* H = treebin_at(M, X->index);\ + if (X == *H) {\ + if ((*H = R) == 0) \ + clear_treemap(M, X->index);\ + }\ + else if (RTCHECK(ok_address(M, XP))) {\ + if (XP->child[0] == X) \ + XP->child[0] = R;\ + else \ + XP->child[1] = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + if (R != 0) {\ + if (RTCHECK(ok_address(M, R))) {\ + tchunkptr C0, C1;\ + R->parent = XP;\ + if ((C0 = X->child[0]) != 0) {\ + if (RTCHECK(ok_address(M, C0))) {\ + R->child[0] = C0;\ + C0->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + if ((C1 = X->child[1]) != 0) {\ + if (RTCHECK(ok_address(M, C1))) {\ + R->child[1] = C1;\ + C1->parent = R;\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ + else\ + CORRUPTION_ERROR_ACTION(M);\ + }\ + }\ +} + +/* Relays to large vs small bin operations */ + +#define insert_chunk(M, P, S)\ + if (is_small(S)) insert_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } + +#define unlink_chunk(M, P, S)\ + if (is_small(S)) unlink_small_chunk(M, P, S)\ + else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } + + +/* Relays to internal calls to malloc/free from realloc, memalign etc */ + +#if ONLY_MSPACES +#define internal_malloc(m, b) mspace_malloc(m, b) +#define internal_free(m, mem) mspace_free(m,mem); +#else /* ONLY_MSPACES */ +#if MSPACES +#define internal_malloc(m, b)\ + (m == gm)? dlmalloc(b) : mspace_malloc(m, b) +#define internal_free(m, mem)\ + if (m == gm) dlfree(mem); else mspace_free(m,mem); +#else /* MSPACES */ +#define internal_malloc(m, b) dlmalloc(b) +#define internal_free(m, mem) dlfree(mem) +#endif /* MSPACES */ +#endif /* ONLY_MSPACES */ + +/* ----------------------- Direct-mmapping chunks ----------------------- */ + +/* + Directly mmapped chunks are set up with an offset to the start of + the mmapped region stored in the prev_foot field of the chunk. This + allows reconstruction of the required argument to MUNMAP when freed, + and also allows adjustment of the returned chunk to meet alignment + requirements (especially in memalign). +*/ + +/* Malloc using mmap */ +static void* mmap_alloc(mstate m, size_t nb) { + size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + if (mmsize > nb) { /* Check for wrap around 0 */ + char* mm = (char*)(CALL_DIRECT_MMAP(mmsize)); + if (mm != CMFAIL) { + size_t offset = align_offset(chunk2mem(mm)); + size_t psize = mmsize - offset - MMAP_FOOT_PAD; + mchunkptr p = (mchunkptr)(mm + offset); + p->prev_foot = offset; + p->head = psize; + mark_inuse_foot(m, p, psize); + chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; + + if (m->least_addr == 0 || mm < m->least_addr) + m->least_addr = mm; + if ((m->footprint += mmsize) > m->max_footprint) + m->max_footprint = m->footprint; + assert(is_aligned(chunk2mem(p))); + check_mmapped_chunk(m, p); + return chunk2mem(p); + } + } + return 0; +} + +/* Realloc using mmap */ +static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) { + size_t oldsize = chunksize(oldp); + if (is_small(nb)) /* Can't shrink mmap regions below small size */ + return 0; + /* Keep old chunk if big enough but not too big */ + if (oldsize >= nb + SIZE_T_SIZE && + (oldsize - nb) <= (mparams.granularity << 1)) + return oldp; + else { + size_t offset = oldp->prev_foot; + size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; + size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + char* cp = (char*)CALL_MREMAP((char*)oldp - offset, + oldmmsize, newmmsize, 1); + if (cp != CMFAIL) { + mchunkptr newp = (mchunkptr)(cp + offset); + size_t psize = newmmsize - offset - MMAP_FOOT_PAD; + newp->head = psize; + mark_inuse_foot(m, newp, psize); + chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; + chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; + + if (cp < m->least_addr) + m->least_addr = cp; + if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) + m->max_footprint = m->footprint; + check_mmapped_chunk(m, newp); + return newp; + } + } + return 0; +} + +/* -------------------------- mspace management -------------------------- */ + +/* Initialize top chunk and its size */ +static void init_top(mstate m, mchunkptr p, size_t psize) { + /* Ensure alignment */ + size_t offset = align_offset(chunk2mem(p)); + p = (mchunkptr)((char*)p + offset); + psize -= offset; + + m->top = p; + m->topsize = psize; + p->head = psize | PINUSE_BIT; + /* set size of fake trailing chunk holding overhead space only once */ + chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; + m->trim_check = mparams.trim_threshold; /* reset on each update */ +} + +/* Initialize bins for a new mstate that is otherwise zeroed out */ +static void init_bins(mstate m) { + /* Establish circular links for smallbins */ + bindex_t i; + for (i = 0; i < NSMALLBINS; ++i) { + sbinptr bin = smallbin_at(m,i); + bin->fd = bin->bk = bin; + } +} + +#if PROCEED_ON_ERROR + +/* default corruption action */ +static void reset_on_error(mstate m) { + int i; + ++malloc_corruption_error_count; + /* Reinitialize fields to forget about all memory */ + m->smallbins = m->treebins = 0; + m->dvsize = m->topsize = 0; + m->seg.base = 0; + m->seg.size = 0; + m->seg.next = 0; + m->top = m->dv = 0; + for (i = 0; i < NTREEBINS; ++i) + *treebin_at(m, i) = 0; + init_bins(m); +} +#endif /* PROCEED_ON_ERROR */ + +/* Allocate chunk and prepend remainder with chunk in successor base. */ +static void* prepend_alloc(mstate m, char* newbase, char* oldbase, + size_t nb) { + mchunkptr p = align_as_chunk(newbase); + mchunkptr oldfirst = align_as_chunk(oldbase); + size_t psize = (char*)oldfirst - (char*)p; + mchunkptr q = chunk_plus_offset(p, nb); + size_t qsize = psize - nb; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + + assert((char*)oldfirst > (char*)q); + assert(pinuse(oldfirst)); + assert(qsize >= MIN_CHUNK_SIZE); + + /* consolidate remainder with first chunk of old base */ + if (oldfirst == m->top) { + size_t tsize = m->topsize += qsize; + m->top = q; + q->head = tsize | PINUSE_BIT; + check_top_chunk(m, q); + } + else if (oldfirst == m->dv) { + size_t dsize = m->dvsize += qsize; + m->dv = q; + set_size_and_pinuse_of_free_chunk(q, dsize); + } + else { + if (!is_inuse(oldfirst)) { + size_t nsize = chunksize(oldfirst); + unlink_chunk(m, oldfirst, nsize); + oldfirst = chunk_plus_offset(oldfirst, nsize); + qsize += nsize; + } + set_free_with_pinuse(q, qsize, oldfirst); + insert_chunk(m, q, qsize); + check_free_chunk(m, q); + } + + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); +} + +/* Add a segment to hold a new noncontiguous region */ +static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { + /* Determine locations and sizes of segment, fenceposts, old top */ + char* old_top = (char*)m->top; + msegmentptr oldsp = segment_holding(m, old_top); + char* old_end = oldsp->base + oldsp->size; + size_t ssize = pad_request(sizeof(struct malloc_segment)); + char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); + size_t offset = align_offset(chunk2mem(rawsp)); + char* asp = rawsp + offset; + char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; + mchunkptr sp = (mchunkptr)csp; + msegmentptr ss = (msegmentptr)(chunk2mem(sp)); + mchunkptr tnext = chunk_plus_offset(sp, ssize); + mchunkptr p = tnext; + int nfences = 0; + + /* reset top to new space */ + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + + /* Set up segment record */ + assert(is_aligned(ss)); + set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); + *ss = m->seg; /* Push current record */ + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmapped; + m->seg.next = ss; + + /* Insert trailing fenceposts */ + for (;;) { + mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); + p->head = FENCEPOST_HEAD; + ++nfences; + if ((char*)(&(nextp->head)) < old_end) + p = nextp; + else + break; + } + assert(nfences >= 2); + + /* Insert the rest of old top into a bin as an ordinary free chunk */ + if (csp != old_top) { + mchunkptr q = (mchunkptr)old_top; + size_t psize = csp - old_top; + mchunkptr tn = chunk_plus_offset(q, psize); + set_free_with_pinuse(q, psize, tn); + insert_chunk(m, q, psize); + } + + check_top_chunk(m, m->top); +} + +/* -------------------------- System allocation -------------------------- */ + +/* Get memory from system using MORECORE or MMAP */ +static void* sys_alloc(mstate m, size_t nb) { + char* tbase = CMFAIL; + size_t tsize = 0; + flag_t mmap_flag = 0; + + ensure_initialization(); + + /* Directly map large chunks, but only if already initialized */ + if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) { + void* mem = mmap_alloc(m, nb); + if (mem != 0) + return mem; + } + + /* + Try getting memory in any of three ways (in most-preferred to + least-preferred order): + 1. A call to MORECORE that can normally contiguously extend memory. + (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or + or main space is mmapped or a previous contiguous call failed) + 2. A call to MMAP new space (disabled if not HAVE_MMAP). + Note that under the default settings, if MORECORE is unable to + fulfill a request, and HAVE_MMAP is true, then mmap is + used as a noncontiguous system allocator. This is a useful backup + strategy for systems with holes in address spaces -- in this case + sbrk cannot contiguously expand the heap, but mmap may be able to + find space. + 3. A call to MORECORE that cannot usually contiguously extend memory. + (disabled if not HAVE_MORECORE) + + In all cases, we need to request enough bytes from system to ensure + we can malloc nb bytes upon success, so pad with enough space for + top_foot, plus alignment-pad to make sure we don't lose bytes if + not on boundary, and round this up to a granularity unit. + */ + + if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { + char* br = CMFAIL; + msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); + size_t asize = 0; + ACQUIRE_MALLOC_GLOBAL_LOCK(); + + if (ss == 0) { /* First time through or recovery */ + char* base = (char*)CALL_MORECORE(0); + if (base != CMFAIL) { + asize = granularity_align(nb + SYS_ALLOC_PADDING); + /* Adjust to end on a page boundary */ + if (!is_page_aligned(base)) + asize += (page_align((size_t)base) - (size_t)base); + /* Can't call MORECORE if size is negative when treated as signed */ + if (asize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(asize))) == base) { + tbase = base; + tsize = asize; + } + } + } + else { + /* Subtract out existing available top space from MORECORE request. */ + asize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING); + /* Use mem here only if it did continuously extend old space */ + if (asize < HALF_MAX_SIZE_T && + (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { + tbase = br; + tsize = asize; + } + } + + if (tbase == CMFAIL) { /* Cope with partial failure */ + if (br != CMFAIL) { /* Try to use/extend the space we did get */ + if (asize < HALF_MAX_SIZE_T && + asize < nb + SYS_ALLOC_PADDING) { + size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - asize); + if (esize < HALF_MAX_SIZE_T) { + char* end = (char*)CALL_MORECORE(esize); + if (end != CMFAIL) + asize += esize; + else { /* Can't use; try to release */ + (void) CALL_MORECORE(-asize); + br = CMFAIL; + } + } + } + } + if (br != CMFAIL) { /* Use the space we did get */ + tbase = br; + tsize = asize; + } + else + disable_contiguous(m); /* Don't try contiguous path in the future */ + } + + RELEASE_MALLOC_GLOBAL_LOCK(); + } + + if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ + size_t rsize = granularity_align(nb + SYS_ALLOC_PADDING); + if (rsize > nb) { /* Fail if wraps around zero */ + char* mp = (char*)(CALL_MMAP(rsize)); + if (mp != CMFAIL) { + tbase = mp; + tsize = rsize; + mmap_flag = USE_MMAP_BIT; + } + } + } + + if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ + size_t asize = granularity_align(nb + SYS_ALLOC_PADDING); + if (asize < HALF_MAX_SIZE_T) { + char* br = CMFAIL; + char* end = CMFAIL; + ACQUIRE_MALLOC_GLOBAL_LOCK(); + br = (char*)(CALL_MORECORE(asize)); + end = (char*)(CALL_MORECORE(0)); + RELEASE_MALLOC_GLOBAL_LOCK(); + if (br != CMFAIL && end != CMFAIL && br < end) { + size_t ssize = end - br; + if (ssize > nb + TOP_FOOT_SIZE) { + tbase = br; + tsize = ssize; + } + } + } + } + + if (tbase != CMFAIL) { + + if ((m->footprint += tsize) > m->max_footprint) + m->max_footprint = m->footprint; + + if (!is_initialized(m)) { /* first-time initialization */ + if (m->least_addr == 0 || tbase < m->least_addr) + m->least_addr = tbase; + m->seg.base = tbase; + m->seg.size = tsize; + m->seg.sflags = mmap_flag; + m->magic = mparams.magic; + m->release_checks = MAX_RELEASE_CHECK_RATE; + init_bins(m); +#if !ONLY_MSPACES + if (is_global(m)) + init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); + else +#endif + { + /* Offset top by embedded malloc_state */ + mchunkptr mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); + } + } + + else { + /* Try to merge with an existing segment */ + msegmentptr sp = &m->seg; + /* Only consider most recent segment if traversal suppressed */ + while (sp != 0 && tbase != sp->base + sp->size) + sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & USE_MMAP_BIT) == mmap_flag && + segment_holds(sp, m->top)) { /* append */ + sp->size += tsize; + init_top(m, m->top, m->topsize + tsize); + } + else { + if (tbase < m->least_addr) + m->least_addr = tbase; + sp = &m->seg; + while (sp != 0 && sp->base != tbase + tsize) + sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; + if (sp != 0 && + !is_extern_segment(sp) && + (sp->sflags & USE_MMAP_BIT) == mmap_flag) { + char* oldbase = sp->base; + sp->base = tbase; + sp->size += tsize; + return prepend_alloc(m, tbase, oldbase, nb); + } + else + add_segment(m, tbase, tsize, mmap_flag); + } + } + + if (nb < m->topsize) { /* Allocate from new or extended top space */ + size_t rsize = m->topsize -= nb; + mchunkptr p = m->top; + mchunkptr r = m->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(m, p, nb); + check_top_chunk(m, m->top); + check_malloced_chunk(m, chunk2mem(p), nb); + return chunk2mem(p); + } + } + + MALLOC_FAILURE_ACTION; + return 0; +} + +/* ----------------------- system deallocation -------------------------- */ + +/* Unmap and unlink any mmapped segments that don't contain used chunks */ +static size_t release_unused_segments(mstate m) { + size_t released = 0; + int nsegs = 0; + msegmentptr pred = &m->seg; + msegmentptr sp = pred->next; + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + msegmentptr next = sp->next; + ++nsegs; + if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { + mchunkptr p = align_as_chunk(base); + size_t psize = chunksize(p); + /* Can unmap if first chunk holds entire segment and not pinned */ + if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { + tchunkptr tp = (tchunkptr)p; + assert(segment_holds(sp, (char*)sp)); + if (p == m->dv) { + m->dv = 0; + m->dvsize = 0; + } + else { + unlink_large_chunk(m, tp); + } + if (CALL_MUNMAP(base, size) == 0) { + released += size; + m->footprint -= size; + /* unlink obsoleted record */ + sp = pred; + sp->next = next; + } + else { /* back out if cannot unmap */ + insert_large_chunk(m, tp, psize); + } + } + } + if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ + break; + pred = sp; + sp = next; + } + /* Reset check counter */ + m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE)? + nsegs : MAX_RELEASE_CHECK_RATE); + return released; +} + +static int sys_trim(mstate m, size_t pad) { + size_t released = 0; + ensure_initialization(); + if (pad < MAX_REQUEST && is_initialized(m)) { + pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ + + if (m->topsize > pad) { + /* Shrink top space in granularity-size units, keeping at least one */ + size_t unit = mparams.granularity; + size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - + SIZE_T_ONE) * unit; + msegmentptr sp = segment_holding(m, (char*)m->top); + + if (!is_extern_segment(sp)) { + if (is_mmapped_segment(sp)) { + if (HAVE_MMAP && + sp->size >= extra && + !has_segment_link(m, sp)) { /* can't shrink if pinned */ + size_t newsize = sp->size - extra; + /* Prefer mremap, fall back to munmap */ + if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || + (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { + released = extra; + } + } + } + else if (HAVE_MORECORE) { + if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ + extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; + ACQUIRE_MALLOC_GLOBAL_LOCK(); + { + /* Make sure end of memory is where we last set it. */ + char* old_br = (char*)(CALL_MORECORE(0)); + if (old_br == sp->base + sp->size) { + char* rel_br = (char*)(CALL_MORECORE(-extra)); + char* new_br = (char*)(CALL_MORECORE(0)); + if (rel_br != CMFAIL && new_br < old_br) + released = old_br - new_br; + } + } + RELEASE_MALLOC_GLOBAL_LOCK(); + } + } + + if (released != 0) { + sp->size -= released; + m->footprint -= released; + init_top(m, m->top, m->topsize - released); + check_top_chunk(m, m->top); + } + } + + /* Unmap any unused mmapped segments */ + if (HAVE_MMAP) + released += release_unused_segments(m); + + /* On failure, disable autotrim to avoid repeated failed future calls */ + if (released == 0 && m->topsize > m->trim_check) + m->trim_check = MAX_SIZE_T; + } + + return (released != 0)? 1 : 0; +} + + +/* ---------------------------- malloc support --------------------------- */ + +/* allocate a large request from the best fitting chunk in a treebin */ +static void* tmalloc_large(mstate m, size_t nb) { + tchunkptr v = 0; + size_t rsize = -nb; /* Unsigned negation */ + tchunkptr t; + bindex_t idx; + compute_tree_index(nb, idx); + if ((t = *treebin_at(m, idx)) != 0) { + /* Traverse tree for this bin looking for node with size == nb */ + size_t sizebits = nb << leftshift_for_tree_index(idx); + tchunkptr rst = 0; /* The deepest untaken right subtree */ + for (;;) { + tchunkptr rt; + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + v = t; + if ((rsize = trem) == 0) + break; + } + rt = t->child[1]; + t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; + if (rt != 0 && rt != t) + rst = rt; + if (t == 0) { + t = rst; /* set t to least subtree holding sizes > nb */ + break; + } + sizebits <<= 1; + } + } + if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ + binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; + if (leftbits != 0) { + bindex_t i; + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + t = *treebin_at(m, i); + } + } + + while (t != 0) { /* find smallest of tree or subtree */ + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + t = leftmost_child(t); + } + + /* If dv is a better fit, return 0 so malloc will use it */ + if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { + if (RTCHECK(ok_address(m, v))) { /* split */ + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + insert_chunk(m, r, rsize); + } + return chunk2mem(v); + } + } + CORRUPTION_ERROR_ACTION(m); + } + return 0; +} + +/* allocate a small request from the best fitting chunk in a treebin */ +static void* tmalloc_small(mstate m, size_t nb) { + tchunkptr t, v; + size_t rsize; + bindex_t i; + binmap_t leastbit = least_bit(m->treemap); + compute_bit2idx(leastbit, i); + v = t = *treebin_at(m, i); + rsize = chunksize(t) - nb; + + while ((t = leftmost_child(t)) != 0) { + size_t trem = chunksize(t) - nb; + if (trem < rsize) { + rsize = trem; + v = t; + } + } + + if (RTCHECK(ok_address(m, v))) { + mchunkptr r = chunk_plus_offset(v, nb); + assert(chunksize(v) == rsize + nb); + if (RTCHECK(ok_next(v, r))) { + unlink_large_chunk(m, v); + if (rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(m, v, (rsize + nb)); + else { + set_size_and_pinuse_of_inuse_chunk(m, v, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(m, r, rsize); + } + return chunk2mem(v); + } + } + + CORRUPTION_ERROR_ACTION(m); + return 0; +} + +/* --------------------------- realloc support --------------------------- */ + +static void* internal_realloc(mstate m, void* oldmem, size_t bytes) { + if (bytes >= MAX_REQUEST) { + MALLOC_FAILURE_ACTION; + return 0; + } + if (!PREACTION(m)) { + mchunkptr oldp = mem2chunk(oldmem); + size_t oldsize = chunksize(oldp); + mchunkptr next = chunk_plus_offset(oldp, oldsize); + mchunkptr newp = 0; + void* extra = 0; + + /* Try to either shrink or extend into top. Else malloc-copy-free */ + + if (RTCHECK(ok_address(m, oldp) && ok_inuse(oldp) && + ok_next(oldp, next) && ok_pinuse(next))) { + size_t nb = request2size(bytes); + if (is_mmapped(oldp)) + newp = mmap_resize(m, oldp, nb); + else if (oldsize >= nb) { /* already big enough */ + size_t rsize = oldsize - nb; + newp = oldp; + if (rsize >= MIN_CHUNK_SIZE) { + mchunkptr remainder = chunk_plus_offset(newp, nb); + set_inuse(m, newp, nb); + set_inuse_and_pinuse(m, remainder, rsize); + extra = chunk2mem(remainder); + } + } + else if (next == m->top && oldsize + m->topsize > nb) { + /* Expand into top */ + size_t newsize = oldsize + m->topsize; + size_t newtopsize = newsize - nb; + mchunkptr newtop = chunk_plus_offset(oldp, nb); + set_inuse(m, oldp, nb); + newtop->head = newtopsize |PINUSE_BIT; + m->top = newtop; + m->topsize = newtopsize; + newp = oldp; + } + } + else { + USAGE_ERROR_ACTION(m, oldmem); + POSTACTION(m); + return 0; + } +#if DEBUG + if (newp != 0) { + check_inuse_chunk(m, newp); /* Check requires lock */ + } +#endif + + POSTACTION(m); + + if (newp != 0) { + if (extra != 0) { + internal_free(m, extra); + } + return chunk2mem(newp); + } + else { + void* newmem = internal_malloc(m, bytes); + if (newmem != 0) { + size_t oc = oldsize - overhead_for(oldp); + memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); + internal_free(m, oldmem); + } + return newmem; + } + } + return 0; +} + +/* --------------------------- memalign support -------------------------- */ + +static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { + if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ + return internal_malloc(m, bytes); + if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ + alignment = MIN_CHUNK_SIZE; + if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ + size_t a = MALLOC_ALIGNMENT << 1; + while (a < alignment) a <<= 1; + alignment = a; + } + + if (bytes >= MAX_REQUEST - alignment) { + if (m != 0) { /* Test isn't needed but avoids compiler warning */ + MALLOC_FAILURE_ACTION; + } + } + else { + size_t nb = request2size(bytes); + size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; + char* mem = (char*)internal_malloc(m, req); + if (mem != 0) { + void* leader = 0; + void* trailer = 0; + mchunkptr p = mem2chunk(mem); + + if (PREACTION(m)) return 0; + if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */ + /* + Find an aligned spot inside chunk. Since we need to give + back leading space in a chunk of at least MIN_CHUNK_SIZE, if + the first calculation places us at a spot with less than + MIN_CHUNK_SIZE leader, we can move to the next aligned spot. + We've allocated enough total room so that this is always + possible. + */ + char* br = (char*)mem2chunk((size_t)(((size_t)(mem + + alignment - + SIZE_T_ONE)) & + -alignment)); + char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? + br : br+alignment; + mchunkptr newp = (mchunkptr)pos; + size_t leadsize = pos - (char*)(p); + size_t newsize = chunksize(p) - leadsize; + + if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ + newp->prev_foot = p->prev_foot + leadsize; + newp->head = newsize; + } + else { /* Otherwise, give back leader, use the rest */ + set_inuse(m, newp, newsize); + set_inuse(m, p, leadsize); + leader = chunk2mem(p); + } + p = newp; + } + + /* Give back spare room at the end */ + if (!is_mmapped(p)) { + size_t size = chunksize(p); + if (size > nb + MIN_CHUNK_SIZE) { + size_t remainder_size = size - nb; + mchunkptr remainder = chunk_plus_offset(p, nb); + set_inuse(m, p, nb); + set_inuse(m, remainder, remainder_size); + trailer = chunk2mem(remainder); + } + } + + assert (chunksize(p) >= nb); + assert((((size_t)(chunk2mem(p))) % alignment) == 0); + check_inuse_chunk(m, p); + POSTACTION(m); + if (leader != 0) { + internal_free(m, leader); + } + if (trailer != 0) { + internal_free(m, trailer); + } + return chunk2mem(p); + } + } + return 0; +} + +/* ------------------------ comalloc/coalloc support --------------------- */ + +static void** ialloc(mstate m, + size_t n_elements, + size_t* sizes, + int opts, + void* chunks[]) { + /* + This provides common support for independent_X routines, handling + all of the combinations that can result. + + The opts arg has: + bit 0 set if all elements are same size (using sizes[0]) + bit 1 set if elements should be zeroed + */ + + size_t element_size; /* chunksize of each element, if all same */ + size_t contents_size; /* total size of elements */ + size_t array_size; /* request size of pointer array */ + void* mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + size_t remainder_size; /* remaining bytes while splitting */ + void** marray; /* either "chunks" or malloced ptr array */ + mchunkptr array_chunk; /* chunk for malloced ptr array */ + flag_t was_enabled; /* to disable mmap */ + size_t size; + size_t i; + + ensure_initialization(); + /* compute array length, if needed */ + if (chunks != 0) { + if (n_elements == 0) + return chunks; /* nothing to do */ + marray = chunks; + array_size = 0; + } + else { + /* if empty req, must still return chunk representing empty array */ + if (n_elements == 0) + return (void**)internal_malloc(m, 0); + marray = 0; + array_size = request2size(n_elements * (sizeof(void*))); + } + + /* compute total element size */ + if (opts & 0x1) { /* all-same-size */ + element_size = request2size(*sizes); + contents_size = n_elements * element_size; + } + else { /* add up all the sizes */ + element_size = 0; + contents_size = 0; + for (i = 0; i != n_elements; ++i) + contents_size += request2size(sizes[i]); + } + + size = contents_size + array_size; + + /* + Allocate the aggregate chunk. First disable direct-mmapping so + malloc won't use it, since we would not be able to later + free/realloc space internal to a segregated mmap region. + */ + was_enabled = use_mmap(m); + disable_mmap(m); + mem = internal_malloc(m, size - CHUNK_OVERHEAD); + if (was_enabled) + enable_mmap(m); + if (mem == 0) + return 0; + + if (PREACTION(m)) return 0; + p = mem2chunk(mem); + remainder_size = chunksize(p); + + assert(!is_mmapped(p)); + + if (opts & 0x2) { /* optionally clear the elements */ + memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); + } + + /* If not provided, allocate the pointer array as final part of chunk */ + if (marray == 0) { + size_t array_chunk_size; + array_chunk = chunk_plus_offset(p, contents_size); + array_chunk_size = remainder_size - contents_size; + marray = (void**) (chunk2mem(array_chunk)); + set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); + remainder_size = contents_size; + } + + /* split out elements */ + for (i = 0; ; ++i) { + marray[i] = chunk2mem(p); + if (i != n_elements-1) { + if (element_size != 0) + size = element_size; + else + size = request2size(sizes[i]); + remainder_size -= size; + set_size_and_pinuse_of_inuse_chunk(m, p, size); + p = chunk_plus_offset(p, size); + } + else { /* the final element absorbs any overallocation slop */ + set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); + break; + } + } + +#if DEBUG + if (marray != chunks) { + /* final element must have exactly exhausted chunk */ + if (element_size != 0) { + assert(remainder_size == element_size); + } + else { + assert(remainder_size == request2size(sizes[i])); + } + check_inuse_chunk(m, mem2chunk(marray)); + } + for (i = 0; i != n_elements; ++i) + check_inuse_chunk(m, mem2chunk(marray[i])); + +#endif /* DEBUG */ + + POSTACTION(m); + return marray; +} + + +/* -------------------------- public routines ---------------------------- */ + +#if !ONLY_MSPACES + +void* dlmalloc(size_t bytes) { + /* + Basic algorithm: + If a small request (< 256 bytes minus per-chunk overhead): + 1. If one exists, use a remainderless chunk in associated smallbin. + (Remainderless means that there are too few excess bytes to + represent as a chunk.) + 2. If it is big enough, use the dv chunk, which is normally the + chunk adjacent to the one used for the most recent small request. + 3. If one exists, split the smallest available chunk in a bin, + saving remainder in dv. + 4. If it is big enough, use the top chunk. + 5. If available, get memory from system and use it + Otherwise, for a large request: + 1. Find the smallest available binned chunk that fits, and use it + if it is better fitting than dv chunk, splitting if necessary. + 2. If better fitting than any binned chunk, use the dv chunk. + 3. If it is big enough, use the top chunk. + 4. If request size >= mmap threshold, try to directly mmap this chunk. + 5. If available, get memory from system and use it + + The ugly goto's here ensure that postaction occurs along all paths. + */ + +#if USE_LOCKS + ensure_initialization(); /* initialize in sys_alloc if not using locks */ +#endif + + if (!PREACTION(gm)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = gm->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(gm, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(gm, b, p, idx); + set_inuse_and_pinuse(gm, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb > gm->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(gm, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(gm, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(gm, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(gm, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + } + + if (nb <= gm->dvsize) { + size_t rsize = gm->dvsize - nb; + mchunkptr p = gm->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = gm->dv = chunk_plus_offset(p, nb); + gm->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + } + else { /* exhaust dv */ + size_t dvs = gm->dvsize; + gm->dvsize = 0; + gm->dv = 0; + set_inuse_and_pinuse(gm, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + else if (nb < gm->topsize) { /* Split top */ + size_t rsize = gm->topsize -= nb; + mchunkptr p = gm->top; + mchunkptr r = gm->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(gm, p, nb); + mem = chunk2mem(p); + check_top_chunk(gm, gm->top); + check_malloced_chunk(gm, mem, nb); + goto postaction; + } + + mem = sys_alloc(gm, nb); + + postaction: + POSTACTION(gm); + return mem; + } + + return 0; +} + +void dlfree(void* mem) { + /* + Consolidate freed chunks with preceeding or succeeding bordering + free chunks, if they exist, and then place in a bin. Intermixed + with special cases for top, dv, mmapped chunks, and usage errors. + */ + + if (mem != 0) { + mchunkptr p = mem2chunk(mem); +#if FOOTERS + mstate fm = get_mstate_for(p); + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } +#else /* FOOTERS */ +#define fm gm +#endif /* FOOTERS */ + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + + if (is_small(psize)) { + insert_small_chunk(fm, p, psize); + check_free_chunk(fm, p); + } + else { + tchunkptr tp = (tchunkptr)p; + insert_large_chunk(fm, tp, psize); + check_free_chunk(fm, p); + if (--fm->release_checks == 0) + release_unused_segments(fm); + } + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +#if !FOOTERS +#undef fm +#endif /* FOOTERS */ +} + +void* dlcalloc(size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = dlmalloc(req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + memset(mem, 0, req); + return mem; +} + +void* dlrealloc(void* oldmem, size_t bytes) { + if (oldmem == 0) + return dlmalloc(bytes); +#ifdef REALLOC_ZERO_BYTES_FREES + if (bytes == 0) { + dlfree(oldmem); + return 0; + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { +#if ! FOOTERS + mstate m = gm; +#else /* FOOTERS */ + mstate m = get_mstate_for(mem2chunk(oldmem)); + if (!ok_magic(m)) { + USAGE_ERROR_ACTION(m, oldmem); + return 0; + } +#endif /* FOOTERS */ + return internal_realloc(m, oldmem, bytes); + } +} + +void* dlmemalign(size_t alignment, size_t bytes) { + return internal_memalign(gm, alignment, bytes); +} + +void** dlindependent_calloc(size_t n_elements, size_t elem_size, + void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + return ialloc(gm, n_elements, &sz, 3, chunks); +} + +void** dlindependent_comalloc(size_t n_elements, size_t sizes[], + void* chunks[]) { + return ialloc(gm, n_elements, sizes, 0, chunks); +} + +void* dlvalloc(size_t bytes) { + size_t pagesz; + ensure_initialization(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, bytes); +} + +void* dlpvalloc(size_t bytes) { + size_t pagesz; + ensure_initialization(); + pagesz = mparams.page_size; + return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); +} + +int dlmalloc_trim(size_t pad) { + int result = 0; + ensure_initialization(); + if (!PREACTION(gm)) { + result = sys_trim(gm, pad); + POSTACTION(gm); + } + return result; +} + +size_t dlmalloc_footprint(void) { + return gm->footprint; +} + +size_t dlmalloc_max_footprint(void) { + return gm->max_footprint; +} + +#if !NO_MALLINFO +struct mallinfo dlmallinfo(void) { + return internal_mallinfo(gm); +} +#endif /* NO_MALLINFO */ + +void dlmalloc_stats() { + internal_malloc_stats(gm); +} + +int dlmallopt(int param_number, int value) { + return change_mparam(param_number, value); +} + +#endif /* !ONLY_MSPACES */ + +size_t dlmalloc_usable_size(void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (is_inuse(p)) + return chunksize(p) - overhead_for(p); + } + return 0; +} + +/* ----------------------------- user mspaces ---------------------------- */ + +#if MSPACES + +static mstate init_user_mstate(char* tbase, size_t tsize) { + size_t msize = pad_request(sizeof(struct malloc_state)); + mchunkptr mn; + mchunkptr msp = align_as_chunk(tbase); + mstate m = (mstate)(chunk2mem(msp)); + memset(m, 0, msize); + INITIAL_LOCK(&m->mutex); + msp->head = (msize|INUSE_BITS); + m->seg.base = m->least_addr = tbase; + m->seg.size = m->footprint = m->max_footprint = tsize; + m->magic = mparams.magic; + m->release_checks = MAX_RELEASE_CHECK_RATE; + m->mflags = mparams.default_mflags; + m->extp = 0; + m->exts = 0; + disable_contiguous(m); + init_bins(m); + mn = next_chunk(mem2chunk(m)); + init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); + check_top_chunk(m, m->top); + return m; +} + +mspace create_mspace(size_t capacity, int locked) { + mstate m = 0; + size_t msize; + ensure_initialization(); + msize = pad_request(sizeof(struct malloc_state)); + if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + size_t rs = ((capacity == 0)? mparams.granularity : + (capacity + TOP_FOOT_SIZE + msize)); + size_t tsize = granularity_align(rs); + char* tbase = (char*)(CALL_MMAP(tsize)); + if (tbase != CMFAIL) { + m = init_user_mstate(tbase, tsize); + m->seg.sflags = USE_MMAP_BIT; + set_lock(m, locked); + } + } + return (mspace)m; +} + +mspace create_mspace_with_base(void* base, size_t capacity, int locked) { + mstate m = 0; + size_t msize; + ensure_initialization(); + msize = pad_request(sizeof(struct malloc_state)); + if (capacity > msize + TOP_FOOT_SIZE && + capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { + m = init_user_mstate((char*)base, capacity); + m->seg.sflags = EXTERN_BIT; + set_lock(m, locked); + } + return (mspace)m; +} + +int mspace_track_large_chunks(mspace msp, int enable) { + int ret = 0; + mstate ms = (mstate)msp; + if (!PREACTION(ms)) { + if (!use_mmap(ms)) + ret = 1; + if (!enable) + enable_mmap(ms); + else + disable_mmap(ms); + POSTACTION(ms); + } + return ret; +} + +size_t destroy_mspace(mspace msp) { + size_t freed = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + msegmentptr sp = &ms->seg; + while (sp != 0) { + char* base = sp->base; + size_t size = sp->size; + flag_t flag = sp->sflags; + sp = sp->next; + if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) && + CALL_MUNMAP(base, size) == 0) + freed += size; + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return freed; +} + +/* + mspace versions of routines are near-clones of the global + versions. This is not so nice but better than the alternatives. +*/ + + +void* mspace_malloc(mspace msp, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (!PREACTION(ms)) { + void* mem; + size_t nb; + if (bytes <= MAX_SMALL_REQUEST) { + bindex_t idx; + binmap_t smallbits; + nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); + idx = small_index(nb); + smallbits = ms->smallmap >> idx; + + if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ + mchunkptr b, p; + idx += ~smallbits & 1; /* Uses next bin if idx empty */ + b = smallbin_at(ms, idx); + p = b->fd; + assert(chunksize(p) == small_index2size(idx)); + unlink_first_small_chunk(ms, b, p, idx); + set_inuse_and_pinuse(ms, p, small_index2size(idx)); + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb > ms->dvsize) { + if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ + mchunkptr b, p, r; + size_t rsize; + bindex_t i; + binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); + binmap_t leastbit = least_bit(leftbits); + compute_bit2idx(leastbit, i); + b = smallbin_at(ms, i); + p = b->fd; + assert(chunksize(p) == small_index2size(i)); + unlink_first_small_chunk(ms, b, p, i); + rsize = small_index2size(i) - nb; + /* Fit here cannot be remainderless if 4byte sizes */ + if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) + set_inuse_and_pinuse(ms, p, small_index2size(i)); + else { + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + r = chunk_plus_offset(p, nb); + set_size_and_pinuse_of_free_chunk(r, rsize); + replace_dv(ms, r, rsize); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + } + } + else if (bytes >= MAX_REQUEST) + nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ + else { + nb = pad_request(bytes); + if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + } + + if (nb <= ms->dvsize) { + size_t rsize = ms->dvsize - nb; + mchunkptr p = ms->dv; + if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ + mchunkptr r = ms->dv = chunk_plus_offset(p, nb); + ms->dvsize = rsize; + set_size_and_pinuse_of_free_chunk(r, rsize); + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + } + else { /* exhaust dv */ + size_t dvs = ms->dvsize; + ms->dvsize = 0; + ms->dv = 0; + set_inuse_and_pinuse(ms, p, dvs); + } + mem = chunk2mem(p); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + else if (nb < ms->topsize) { /* Split top */ + size_t rsize = ms->topsize -= nb; + mchunkptr p = ms->top; + mchunkptr r = ms->top = chunk_plus_offset(p, nb); + r->head = rsize | PINUSE_BIT; + set_size_and_pinuse_of_inuse_chunk(ms, p, nb); + mem = chunk2mem(p); + check_top_chunk(ms, ms->top); + check_malloced_chunk(ms, mem, nb); + goto postaction; + } + + mem = sys_alloc(ms, nb); + + postaction: + POSTACTION(ms); + return mem; + } + + return 0; +} + +void mspace_free(mspace msp, void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); +#if FOOTERS + mstate fm = get_mstate_for(p); + msp = msp; /* placate people compiling -Wunused */ +#else /* FOOTERS */ + mstate fm = (mstate)msp; +#endif /* FOOTERS */ + if (!ok_magic(fm)) { + USAGE_ERROR_ACTION(fm, p); + return; + } + if (!PREACTION(fm)) { + check_inuse_chunk(fm, p); + if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) { + size_t psize = chunksize(p); + mchunkptr next = chunk_plus_offset(p, psize); + if (!pinuse(p)) { + size_t prevsize = p->prev_foot; + if (is_mmapped(p)) { + psize += prevsize + MMAP_FOOT_PAD; + if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) + fm->footprint -= psize; + goto postaction; + } + else { + mchunkptr prev = chunk_minus_offset(p, prevsize); + psize += prevsize; + p = prev; + if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ + if (p != fm->dv) { + unlink_chunk(fm, p, prevsize); + } + else if ((next->head & INUSE_BITS) == INUSE_BITS) { + fm->dvsize = psize; + set_free_with_pinuse(p, psize, next); + goto postaction; + } + } + else + goto erroraction; + } + } + + if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { + if (!cinuse(next)) { /* consolidate forward */ + if (next == fm->top) { + size_t tsize = fm->topsize += psize; + fm->top = p; + p->head = tsize | PINUSE_BIT; + if (p == fm->dv) { + fm->dv = 0; + fm->dvsize = 0; + } + if (should_trim(fm, tsize)) + sys_trim(fm, 0); + goto postaction; + } + else if (next == fm->dv) { + size_t dsize = fm->dvsize += psize; + fm->dv = p; + set_size_and_pinuse_of_free_chunk(p, dsize); + goto postaction; + } + else { + size_t nsize = chunksize(next); + psize += nsize; + unlink_chunk(fm, next, nsize); + set_size_and_pinuse_of_free_chunk(p, psize); + if (p == fm->dv) { + fm->dvsize = psize; + goto postaction; + } + } + } + else + set_free_with_pinuse(p, psize, next); + + if (is_small(psize)) { + insert_small_chunk(fm, p, psize); + check_free_chunk(fm, p); + } + else { + tchunkptr tp = (tchunkptr)p; + insert_large_chunk(fm, tp, psize); + check_free_chunk(fm, p); + if (--fm->release_checks == 0) + release_unused_segments(fm); + } + goto postaction; + } + } + erroraction: + USAGE_ERROR_ACTION(fm, p); + postaction: + POSTACTION(fm); + } + } +} + +void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { + void* mem; + size_t req = 0; + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + if (n_elements != 0) { + req = n_elements * elem_size; + if (((n_elements | elem_size) & ~(size_t)0xffff) && + (req / n_elements != elem_size)) + req = MAX_SIZE_T; /* force downstream failure on overflow */ + } + mem = internal_malloc(ms, req); + if (mem != 0 && calloc_must_clear(mem2chunk(mem))) + memset(mem, 0, req); + return mem; +} + +void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { + if (oldmem == 0) + return mspace_malloc(msp, bytes); +#ifdef REALLOC_ZERO_BYTES_FREES + if (bytes == 0) { + mspace_free(msp, oldmem); + return 0; + } +#endif /* REALLOC_ZERO_BYTES_FREES */ + else { +#if FOOTERS + mchunkptr p = mem2chunk(oldmem); + mstate ms = get_mstate_for(p); +#else /* FOOTERS */ + mstate ms = (mstate)msp; +#endif /* FOOTERS */ + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return internal_realloc(ms, oldmem, bytes); + } +} + +void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return internal_memalign(ms, alignment, bytes); +} + +void** mspace_independent_calloc(mspace msp, size_t n_elements, + size_t elem_size, void* chunks[]) { + size_t sz = elem_size; /* serves as 1-element array */ + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, &sz, 3, chunks); +} + +void** mspace_independent_comalloc(mspace msp, size_t n_elements, + size_t sizes[], void* chunks[]) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + return 0; + } + return ialloc(ms, n_elements, sizes, 0, chunks); +} + +int mspace_trim(mspace msp, size_t pad) { + int result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + if (!PREACTION(ms)) { + result = sys_trim(ms, pad); + POSTACTION(ms); + } + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + +void mspace_malloc_stats(mspace msp) { + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + internal_malloc_stats(ms); + } + else { + USAGE_ERROR_ACTION(ms,ms); + } +} + +size_t mspace_footprint(mspace msp) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->footprint; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + + +size_t mspace_max_footprint(mspace msp) { + size_t result = 0; + mstate ms = (mstate)msp; + if (ok_magic(ms)) { + result = ms->max_footprint; + } + else { + USAGE_ERROR_ACTION(ms,ms); + } + return result; +} + + +#if !NO_MALLINFO +struct mallinfo mspace_mallinfo(mspace msp) { + mstate ms = (mstate)msp; + if (!ok_magic(ms)) { + USAGE_ERROR_ACTION(ms,ms); + } + return internal_mallinfo(ms); +} +#endif /* NO_MALLINFO */ + +size_t mspace_usable_size(void* mem) { + if (mem != 0) { + mchunkptr p = mem2chunk(mem); + if (is_inuse(p)) + return chunksize(p) - overhead_for(p); + } + return 0; +} + +int mspace_mallopt(int param_number, int value) { + return change_mparam(param_number, value); +} + +#endif /* MSPACES */ + + +/* -------------------- Alternative MORECORE functions ------------------- */ + +/* + Guidelines for creating a custom version of MORECORE: + + * For best performance, MORECORE should allocate in multiples of pagesize. + * MORECORE may allocate more memory than requested. (Or even less, + but this will usually result in a malloc failure.) + * MORECORE must not allocate memory when given argument zero, but + instead return one past the end address of memory from previous + nonzero call. + * For best performance, consecutive calls to MORECORE with positive + arguments should return increasing addresses, indicating that + space has been contiguously extended. + * Even though consecutive calls to MORECORE need not return contiguous + addresses, it must be OK for malloc'ed chunks to span multiple + regions in those cases where they do happen to be contiguous. + * MORECORE need not handle negative arguments -- it may instead + just return MFAIL when given negative arguments. + Negative arguments are always multiples of pagesize. MORECORE + must not misinterpret negative args as large positive unsigned + args. You can suppress all such calls from even occurring by defining + MORECORE_CANNOT_TRIM, + + As an example alternative MORECORE, here is a custom allocator + kindly contributed for pre-OSX macOS. It uses virtually but not + necessarily physically contiguous non-paged memory (locked in, + present and won't get swapped out). You can use it by uncommenting + this section, adding some #includes, and setting up the appropriate + defines above: + + #define MORECORE osMoreCore + + There is also a shutdown routine that should somehow be called for + cleanup upon program exit. + + #define MAX_POOL_ENTRIES 100 + #define MINIMUM_MORECORE_SIZE (64 * 1024U) + static int next_os_pool; + void *our_os_pools[MAX_POOL_ENTRIES]; + + void *osMoreCore(int size) + { + void *ptr = 0; + static void *sbrk_top = 0; + + if (size > 0) + { + if (size < MINIMUM_MORECORE_SIZE) + size = MINIMUM_MORECORE_SIZE; + if (CurrentExecutionLevel() == kTaskLevel) + ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); + if (ptr == 0) + { + return (void *) MFAIL; + } + // save ptrs so they can be freed during cleanup + our_os_pools[next_os_pool] = ptr; + next_os_pool++; + ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); + sbrk_top = (char *) ptr + size; + return ptr; + } + else if (size < 0) + { + // we don't currently support shrink behavior + return (void *) MFAIL; + } + else + { + return sbrk_top; + } + } + + // cleanup any allocated memory pools + // called as last thing before shutting down driver + + void osCleanupMem(void) + { + void **ptr; + + for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) + if (*ptr) + { + PoolDeallocate(*ptr); + *ptr = 0; + } + } + +*/ + + +/* ----------------------------------------------------------------------- +History: + V2.8.4 Wed May 27 09:56:23 2009 Doug Lea (dl at gee) + * Use zeros instead of prev foot for is_mmapped + * Add mspace_track_large_chunks; thanks to Jean Brouwers + * Fix set_inuse in internal_realloc; thanks to Jean Brouwers + * Fix insufficient sys_alloc padding when using 16byte alignment + * Fix bad error check in mspace_footprint + * Adaptations for ptmalloc; thanks to Wolfram Gloger. + * Reentrant spin locks; thanks to Earl Chew and others + * Win32 improvements; thanks to Niall Douglas and Earl Chew + * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options + * Extension hook in malloc_state + * Various small adjustments to reduce warnings on some compilers + * Various configuration extensions/changes for more platforms. Thanks + to all who contributed these. + + V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) + * Add max_footprint functions + * Ensure all appropriate literals are size_t + * Fix conditional compilation problem for some #define settings + * Avoid concatenating segments with the one provided + in create_mspace_with_base + * Rename some variables to avoid compiler shadowing warnings + * Use explicit lock initialization. + * Better handling of sbrk interference. + * Simplify and fix segment insertion, trimming and mspace_destroy + * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x + * Thanks especially to Dennis Flanagan for help on these. + + V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) + * Fix memalign brace error. + + V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) + * Fix improper #endif nesting in C++ + * Add explicit casts needed for C++ + + V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) + * Use trees for large bins + * Support mspaces + * Use segments to unify sbrk-based and mmap-based system allocation, + removing need for emulation on most platforms without sbrk. + * Default safety checks + * Optional footer checks. Thanks to William Robertson for the idea. + * Internal code refactoring + * Incorporate suggestions and platform-specific changes. + Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, + Aaron Bachmann, Emery Berger, and others. + * Speed up non-fastbin processing enough to remove fastbins. + * Remove useless cfree() to avoid conflicts with other apps. + * Remove internal memcpy, memset. Compilers handle builtins better. + * Remove some options that no one ever used and rename others. + + V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) + * Fix malloc_state bitmap array misdeclaration + + V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) + * Allow tuning of FIRST_SORTED_BIN_SIZE + * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. + * Better detection and support for non-contiguousness of MORECORE. + Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger + * Bypass most of malloc if no frees. Thanks To Emery Berger. + * Fix freeing of old top non-contiguous chunk im sysmalloc. + * Raised default trim and map thresholds to 256K. + * Fix mmap-related #defines. Thanks to Lubos Lunak. + * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. + * Branch-free bin calculation + * Default trim and mmap thresholds now 256K. + + V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) + * Introduce independent_comalloc and independent_calloc. + Thanks to Michael Pachos for motivation and help. + * Make optional .h file available + * Allow > 2GB requests on 32bit systems. + * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>. + Thanks also to Andreas Mueller <a.mueller at paradatec.de>, + and Anonymous. + * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for + helping test this.) + * memalign: check alignment arg + * realloc: don't try to shift chunks backwards, since this + leads to more fragmentation in some programs and doesn't + seem to help in any others. + * Collect all cases in malloc requiring system memory into sysmalloc + * Use mmap as backup to sbrk + * Place all internal state in malloc_state + * Introduce fastbins (although similar to 2.5.1) + * Many minor tunings and cosmetic improvements + * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK + * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS + Thanks to Tony E. Bennett <tbennett@nvidia.com> and others. + * Include errno.h to support default failure action. + + V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) + * return null for negative arguments + * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com> + * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' + (e.g. WIN32 platforms) + * Cleanup header file inclusion for WIN32 platforms + * Cleanup code to avoid Microsoft Visual C++ compiler complaints + * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing + memory allocation routines + * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) + * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to + usage of 'assert' in non-WIN32 code + * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to + avoid infinite loop + * Always call 'fREe()' rather than 'free()' + + V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) + * Fixed ordering problem with boundary-stamping + + V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) + * Added pvalloc, as recommended by H.J. Liu + * Added 64bit pointer support mainly from Wolfram Gloger + * Added anonymously donated WIN32 sbrk emulation + * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen + * malloc_extend_top: fix mask error that caused wastage after + foreign sbrks + * Add linux mremap support code from HJ Liu + + V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) + * Integrated most documentation with the code. + * Add support for mmap, with help from + Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Use last_remainder in more cases. + * Pack bins using idea from colin@nyx10.cs.du.edu + * Use ordered bins instead of best-fit threshhold + * Eliminate block-local decls to simplify tracing and debugging. + * Support another case of realloc via move into top + * Fix error occuring when initial sbrk_base not word-aligned. + * Rely on page size for units instead of SBRK_UNIT to + avoid surprises about sbrk alignment conventions. + * Add mallinfo, mallopt. Thanks to Raymond Nijssen + (raymond@es.ele.tue.nl) for the suggestion. + * Add `pad' argument to malloc_trim and top_pad mallopt parameter. + * More precautions for cases where other routines call sbrk, + courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). + * Added macros etc., allowing use in linux libc from + H.J. Lu (hjl@gnu.ai.mit.edu) + * Inverted this history list + + V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) + * Re-tuned and fixed to behave more nicely with V2.6.0 changes. + * Removed all preallocation code since under current scheme + the work required to undo bad preallocations exceeds + the work saved in good cases for most test programs. + * No longer use return list or unconsolidated bins since + no scheme using them consistently outperforms those that don't + given above changes. + * Use best fit for very large chunks to prevent some worst-cases. + * Added some support for debugging + + V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) + * Removed footers when chunks are in use. Thanks to + Paul Wilson (wilson@cs.texas.edu) for the suggestion. + + V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) + * Added malloc_trim, with help from Wolfram Gloger + (wmglo@Dent.MED.Uni-Muenchen.DE). + + V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) + + V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) + * realloc: try to expand in both directions + * malloc: swap order of clean-bin strategy; + * realloc: only conditionally expand backwards + * Try not to scavenge used bins + * Use bin counts as a guide to preallocation + * Occasionally bin return list chunks in first scan + * Add a few optimizations from colin@nyx10.cs.du.edu + + V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) + * faster bin computation & slightly different binning + * merged all consolidations to one part of malloc proper + (eliminating old malloc_find_space & malloc_clean_bin) + * Scan 2 returns chunks (not just 1) + * Propagate failure in realloc if malloc returns 0 + * Add stuff to allow compilation on non-ANSI compilers + from kpv@research.att.com + + V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) + * removed potential for odd address access in prev_chunk + * removed dependency on getpagesize.h + * misc cosmetics and a bit more internal documentation + * anticosmetics: mangled names in macros to evade debugger strangeness + * tested on sparc, hp-700, dec-mips, rs6000 + with gcc & native cc (hp, dec only) allowing + Detlefs & Zorn comparison study (in SIGPLAN Notices.) + + Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) + * Based loosely on libg++-1.2X malloc. (It retains some of the overall + structure of old version, but most details differ.) + +*/ + diff --git a/src/utils/downloader.c b/src/utils/downloader.c index dcb8b13..e53b62c 100644 --- a/src/utils/downloader.c +++ b/src/utils/downloader.c @@ -11,15 +11,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -31,6 +31,7 @@ #include <gpac/list.h> #include <gpac/base_coding.h> #include <gpac/crypt.h> +#include <gpac/tools.h> #ifdef GPAC_HAS_SSL @@ -65,15 +66,20 @@ struct __gf_download_session GF_Mutex *mx; Bool in_callback, destroy; + u32 proxy_enabled; char *server_name; u16 port; + char *orig_url; char *remote_path; char *user; char *passwd; char cookie[GF_MAX_PATH]; + /* Used when a cache file is forced, when the download session is used standalone */ + Bool use_cache_extension; + FILE *cache; char *cache_name; /*cache size if existing*/ @@ -88,7 +94,11 @@ struct __gf_download_session u32 total_size, bytes_done, start_time, icy_metaint, icy_count, icy_bytes; u32 bytes_per_sec, window_start, bytes_in_wnd; u32 limit_data_rate; - + + /* Range information if needed for the download (cf flag) */ + Bool needs_range; + u32 range_start, range_end; + /*0: GET 1: HEAD 2: all the rest @@ -124,6 +134,8 @@ struct __gf_download_manager GF_Config *cfg; GF_List *sessions; + GF_List *skip_proxy_servers; + #ifdef GPAC_HAS_SSL SSL_CTX *ssl_ctx; #endif @@ -136,7 +148,7 @@ static void init_prng (void) { char namebuf[256]; const char *random_file; - + if (RAND_status ()) return; namebuf[0] = '\0'; @@ -144,7 +156,7 @@ static void init_prng (void) if (random_file && *random_file) RAND_load_file(random_file, 16384); - + if (RAND_status ()) return; #ifdef WIN32 @@ -157,7 +169,7 @@ static void init_prng (void) static int ssl_init(GF_DownloadManager *dm, u32 mode) { SSL_METHOD *meth; - + if (!dm) return 0; /* The SSL has already been initialized. */ if (dm->ssl_ctx) return 1; @@ -168,7 +180,7 @@ static int ssl_init(GF_DownloadManager *dm, u32 mode) SSL_load_error_strings(); SSLeay_add_all_algorithms(); SSLeay_add_ssl_algorithms(); - + switch (mode) { case 0: meth = SSLv23_client_method(); @@ -185,7 +197,7 @@ static int ssl_init(GF_DownloadManager *dm, u32 mode) default: goto error; } - + dm->ssl_ctx = SSL_CTX_new(meth); if (!dm->ssl_ctx) goto error; SSL_CTX_set_default_verify_paths(dm->ssl_ctx); @@ -196,7 +208,7 @@ static int ssl_init(GF_DownloadManager *dm, u32 mode) than examining the error stack after a failed SSL_connect. */ SSL_CTX_set_verify(dm->ssl_ctx, SSL_VERIFY_NONE, NULL); - /* Since fd_write unconditionally assumes partial writes (and handles them correctly), + /* Since fd_write unconditionally assumes partial writes (and handles them correctly), allow them in OpenSSL. */ SSL_CTX_set_mode(dm->ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE); return 1; @@ -234,17 +246,20 @@ void gf_dm_configure_cache(GF_DownloadSession *sess) u8 hash[20]; const char *opt; - if (!sess->dm->cache_directory) return; + if (sess->use_cache_extension) return; + if (!sess->dm->cache_directory) return; if (sess->flags & GF_NETIO_SESSION_NOT_CACHED) return; + if (sess->flags & GF_NETIO_SESSION_REUSE_APPEND) return; - len = strlen(sess->server_name) + strlen(sess->remote_path) + 1; + len = strlen(sess->server_name) + strlen(sess->remote_path) + 10; if (len<50) len = 50; - tmp = malloc(sizeof(char) * len); + tmp = gf_malloc(sizeof(char) * len); tmp[0] = 0; /*generate hash of the full url*/ strcpy(tmp, sess->server_name); strcat(tmp, sess->remote_path); + gf_sha1_csum(tmp, strlen(tmp), hash); tmp[0] = 0; for (i=0; i<20; i++) { @@ -255,7 +270,7 @@ void gf_dm_configure_cache(GF_DownloadSession *sess) } len += strlen(sess->dm->cache_directory) + 6; - sess->cache_name = malloc(sizeof(char)*len); + sess->cache_name = gf_malloc(sizeof(char)*len); sess->cache_name[0] = 0; strcpy(sess->cache_name, sess->dm->cache_directory); @@ -267,15 +282,15 @@ void gf_dm_configure_cache(GF_DownloadSession *sess) if (ext) ext[0] = 0; ext = strchr(tmp, '.'); if (ext && (strlen(ext)<6) ) strcat(sess->cache_name, ext); - free(tmp); + gf_free(tmp); /*first try, check cached file*/ - if (!sess->cache_start_size) { + if (!sess->cache_start_size && !(sess->flags&GF_NETIO_SESSION_FORCE_RESTART) ) { /*if file present figure out how much of the file is downloaded - we assume 2^31 byte file max*/ - FILE *the_cache = fopen(sess->cache_name, "rb"); + FILE *the_cache = gf_f64_open(sess->cache_name, "rb"); if (the_cache) { - fseek(the_cache, 0, SEEK_END); - sess->cache_start_size = ftell(the_cache); + gf_f64_seek(the_cache, 0, SEEK_END); + sess->cache_start_size = (u32) gf_f64_tell(the_cache); fclose(the_cache); } } @@ -286,12 +301,18 @@ void gf_dm_configure_cache(GF_DownloadSession *sess) GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP] Cache setup to %s\n", sess->cache_name)); /*are we using existing cached files ?*/ - opt = gf_cfg_get_key(sess->dm->cfg, "Downloader", "RestartFiles"); - if (opt && !stricmp(opt, "yes")) sess->cache_start_size = 0; + if (sess->dm) { + opt = gf_cfg_get_key(sess->dm->cfg, "Downloader", "RestartFiles"); + if (opt && !stricmp(opt, "yes")) sess->cache_start_size = 0; + } else { + sess->cache_start_size = 0; + } } static void gf_dm_disconnect(GF_DownloadSession *sess) { + if (sess->mx) + gf_mx_p(sess->mx); #ifdef GPAC_HAS_SSL if (sess->ssl) { SSL_shutdown(sess->ssl); @@ -307,6 +328,8 @@ static void gf_dm_disconnect(GF_DownloadSession *sess) sess->cache = NULL; sess->status = GF_NETIO_DISCONNECTED; if (sess->num_retry) sess->num_retry--; + if (sess->mx) + gf_mx_v(sess->mx); } void gf_dm_sess_del(GF_DownloadSession *sess) @@ -322,48 +345,56 @@ void gf_dm_sess_del(GF_DownloadSession *sess) /*if threaded wait for thread exit*/ if (sess->th) { - while (!(sess->flags & GF_DOWNLOAD_SESSION_THREAD_DEAD)) + while (!(sess->flags & GF_DOWNLOAD_SESSION_THREAD_DEAD)) gf_sleep(1); gf_th_del(sess->th); gf_mx_del(sess->mx); } - - gf_list_del_item(sess->dm->sessions, sess); - if (sess->cache_name) { - opt = gf_cfg_get_key(sess->dm->cfg, "Downloader", "CleanCache"); - if (opt && !stricmp(opt, "yes")) gf_delete_file(sess->cache_name); - free(sess->cache_name); + if (sess->dm) gf_list_del_item(sess->dm->sessions, sess); + + 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); } - - if (sess->server_name) free(sess->server_name); - if (sess->remote_path) free(sess->remote_path); - if (sess->user) free(sess->user); - if (sess->passwd) free(sess->passwd); - if (sess->mime_type) free(sess->mime_type); + + if (sess->orig_url) gf_free(sess->orig_url); + if (sess->server_name) gf_free(sess->server_name); + if (sess->remote_path) gf_free(sess->remote_path); + if (sess->user) gf_free(sess->user); + if (sess->passwd) gf_free(sess->passwd); + if (sess->mime_type) gf_free(sess->mime_type); if (sess->cache) fclose(sess->cache); - if (sess->init_data) free(sess->init_data); - free(sess); + if (sess->init_data) gf_free(sess->init_data); + gf_free(sess); } void http_do_requests(GF_DownloadSession *sess); static void gf_dm_sess_notify_state(GF_DownloadSession *sess, u32 dnload_status, GF_Err error) { - GF_NETIO_Parameter par; - sess->in_callback = 1; - memset(&par, 0, sizeof(GF_NETIO_Parameter)); - par.msg_type = dnload_status; - par.error = error; - sess->user_proc(sess->usr_cbk, &par); - sess->in_callback = 0; + if (sess->user_proc) { + GF_NETIO_Parameter par; + sess->in_callback = 1; + memset(&par, 0, sizeof(GF_NETIO_Parameter)); + par.msg_type = dnload_status; + par.error = error; + sess->user_proc(sess->usr_cbk, &par); + sess->in_callback = 0; + } } static void gf_dm_sess_user_io(GF_DownloadSession *sess, GF_NETIO_Parameter *par) { - sess->in_callback = 1; - sess->user_proc(sess->usr_cbk, par); - sess->in_callback = 0; + if (sess->user_proc) { + sess->in_callback = 1; + sess->user_proc(sess->usr_cbk, par); + sess->in_callback = 0; + } } GF_Err gf_dm_sess_last_error(GF_DownloadSession *sess) @@ -373,15 +404,17 @@ GF_Err gf_dm_sess_last_error(GF_DownloadSession *sess) } -static GF_Err gf_dm_setup_from_url(GF_DownloadSession *sess, char *url) +GF_Err gf_dm_setup_from_url(GF_DownloadSession *sess, char *url) { char *tmp, *tmp_url; const char *opt; + sess->orig_url = gf_strdup(url); + if (!strnicmp(url, "http://", 7)) { url += 7; sess->port = 80; sess->do_requests = http_do_requests; - } + } else if (!strnicmp(url, "https://", 8)) { url += 8; sess->port = 443; @@ -396,14 +429,16 @@ static GF_Err gf_dm_setup_from_url(GF_DownloadSession *sess, char *url) sess->port = 21; sess->do_requests = NULL; return GF_NOT_SUPPORTED; - } + } /*relative URL*/ else if (!strstr(url, "://")) { u32 i; if (!sess->remote_path) return GF_BAD_PARAM; tmp = gf_url_concatenate(sess->remote_path, url); - free(sess->remote_path); - sess->remote_path = tmp; + gf_free(sess->remote_path); + sess->remote_path = gf_url_percent_encode(tmp); + gf_free(tmp); + if (!sess->remote_path) sess->remote_path = gf_strdup(url); for (i=0; i<strlen(sess->remote_path); i++) if (sess->remote_path[i]=='\\') sess->remote_path[i]='/'; @@ -413,15 +448,15 @@ static GF_Err gf_dm_setup_from_url(GF_DownloadSession *sess, char *url) tmp = strchr(url, '/'); - sess->remote_path = strdup(tmp ? tmp : "/"); + sess->remote_path = gf_url_percent_encode(tmp ? tmp : "/"); if (tmp) { tmp[0] = 0; - tmp_url = strdup(url); + tmp_url = gf_strdup(url); tmp[0] = '/'; } else { - tmp_url = strdup(url); + tmp_url = gf_strdup(url); } - + tmp = strrchr(tmp_url, ':'); if (tmp) { sess->port = atoi(tmp+1); @@ -429,32 +464,33 @@ static GF_Err gf_dm_setup_from_url(GF_DownloadSession *sess, char *url) } tmp = strrchr(tmp_url, '@'); if (tmp) { - sess->server_name = strdup(tmp+1); + sess->server_name = gf_strdup(tmp+1); tmp[0] = 0; tmp = strchr(tmp_url, ':'); - if (sess->user) free(sess->user); + if (sess->user) gf_free(sess->user); sess->user = NULL; - if (sess->passwd) free(sess->passwd); + if (sess->passwd) gf_free(sess->passwd); sess->passwd = NULL; if (tmp) { - sess->passwd = strdup(tmp+1); + sess->passwd = gf_strdup(tmp+1); tmp[0] = 0; } - sess->user = strdup(tmp_url); + sess->user = gf_strdup(tmp_url); } else { - sess->server_name = strdup(tmp_url); + sess->server_name = gf_strdup(tmp_url); } - free(tmp_url); + gf_free(tmp_url); /*setup BW limiter*/ sess->limit_data_rate = 0; - opt = gf_cfg_get_key(sess->dm->cfg, "Downloader", "MaxRate"); - if (opt) { - /*use it in in BYTES per second*/ - sess->limit_data_rate = 1024 * atoi(opt) / 8; - } - + if (sess->dm) { + opt = gf_cfg_get_key(sess->dm->cfg, "Downloader", "MaxRate"); + if (opt) { + /*use it in in BYTES per second*/ + sess->limit_data_rate = 1024 * atoi(opt) / 8; + } + } return GF_OK; } @@ -493,33 +529,41 @@ static u32 gf_dm_session_thread(void *par) #define SESSION_RETRY_COUNT 20 -GF_DownloadSession *gf_dm_sess_new(GF_DownloadManager *dm, char *url, u32 dl_flags, +void gf_dm_sess_dash_reset(GF_DownloadSession *sess) +{ + sess->flags |= GF_NETIO_SESSION_REUSE_APPEND; + sess->status = GF_NETIO_SETUP; + sess->needs_range = 0; + sess->range_start = sess->range_end = 0; + +} + +GF_Err gf_dm_sess_set_range(GF_DownloadSession *sess, u32 start, u32 end) +{ + if (!sess) return GF_BAD_PARAM; + sess->needs_range = 1; + sess->range_start = start; + sess->range_end = end; + return GF_OK; +} + +GF_DownloadSession *gf_dm_sess_new_simple(char *url, u32 dl_flags, gf_dm_user_io user_io, void *usr_cbk, + char *cache_name, GF_Err *e) { GF_DownloadSession *sess; - - *e = GF_OK; - if (gf_dm_is_local(dm, url)) return NULL; - - if (!gf_dm_can_handle_url(dm, url)) { - *e = GF_NOT_SUPPORTED; - return NULL; - } - if (!user_io) { - *e = GF_BAD_PARAM; - return NULL; - } - - - sess = (GF_DownloadSession *)malloc(sizeof(GF_DownloadSession)); + sess = (GF_DownloadSession *)gf_malloc(sizeof(GF_DownloadSession)); memset((void *)sess, 0, sizeof(GF_DownloadSession)); sess->flags = dl_flags; sess->user_proc = user_io; sess->usr_cbk = usr_cbk; - sess->dm = dm; - gf_list_add(dm->sessions, sess); + if (cache_name) { + sess->cache_name = cache_name; + sess->use_cache_extension = 1; + } + *e = gf_dm_setup_from_url(sess, url); if (*e) { @@ -535,10 +579,32 @@ GF_DownloadSession *gf_dm_sess_new(GF_DownloadManager *dm, char *url, u32 dl_fla return sess; } +GF_DownloadSession *gf_dm_sess_new(GF_DownloadManager *dm, char *url, u32 dl_flags, + gf_dm_user_io user_io, + void *usr_cbk, + GF_Err *e) +{ + GF_DownloadSession *sess; + + *e = GF_OK; + if (gf_dm_is_local(dm, url)) return NULL; + + if (!gf_dm_can_handle_url(dm, url)) { + *e = GF_NOT_SUPPORTED; + return NULL; + } + sess = gf_dm_sess_new_simple(url, dl_flags, user_io, usr_cbk, NULL, e); + if (sess) { + sess->dm = dm; + gf_list_add(dm->sessions, sess); + } + return sess; +} + static GF_Err gf_dm_read_data(GF_DownloadSession *sess, char *data, u32 data_size, u32 *out_read) { GF_Err e; - + #ifdef GPAC_HAS_SSL if (sess->ssl) { u32 size = SSL_read(sess->ssl, data, data_size); @@ -546,10 +612,10 @@ static GF_Err gf_dm_read_data(GF_DownloadSession *sess, char *data, u32 data_siz data[size] = 0; if (!size) e = GF_IP_NETWORK_EMPTY; *out_read = size; - } else + } else #endif e = gf_sk_receive(sess->sock, data, data_size, 0, out_read); - + return e; } @@ -601,25 +667,47 @@ static void gf_dm_connect(GF_DownloadSession *sess) /*connect*/ sess->status = GF_NETIO_SETUP; gf_dm_sess_notify_state(sess, sess->status, GF_OK); - + /*PROXY setup*/ - proxy = gf_cfg_get_key(sess->dm->cfg, "HTTPProxy", "Enabled"); - if (proxy && !strcmp(proxy, "yes")) { - proxy = gf_cfg_get_key(sess->dm->cfg, "HTTPProxy", "Port"); - proxy_port = proxy ? atoi(proxy) : 80; - - proxy = gf_cfg_get_key(sess->dm->cfg, "HTTPProxy", "Name"); + if (sess->proxy_enabled!=2 && sess->dm) { + proxy = gf_cfg_get_key(sess->dm->cfg, "HTTPProxy", "Enabled"); + if (proxy && !strcmp(proxy, "yes")) { + u32 i; + Bool use_proxy=1; + for (i=0; i<gf_list_count(sess->dm->skip_proxy_servers); i++) { + char *skip = gf_list_get(sess->dm->skip_proxy_servers, i); + if (!strcmp(skip, sess->server_name)) { + use_proxy=0; + break; + } + } + if (use_proxy) { + proxy = gf_cfg_get_key(sess->dm->cfg, "HTTPProxy", "Port"); + proxy_port = proxy ? atoi(proxy) : 80; + proxy = gf_cfg_get_key(sess->dm->cfg, "HTTPProxy", "Name"); + sess->proxy_enabled = 1; + } else { + proxy = NULL; + } + } else { + proxy = NULL; + sess->proxy_enabled = 0; + } } else { proxy = NULL; } - ip = gf_cfg_get_key(sess->dm->cfg, "Network", "MobileIPEnabled"); - if (ip && !strcmp(ip, "yes")) { - ip = gf_cfg_get_key(sess->dm->cfg, "Network", "MobileIP"); - } else { - ip = NULL; - } + if (sess->dm) { + ip = gf_cfg_get_key(sess->dm->cfg, "Network", "MobileIPEnabled"); + if (ip && !strcmp(ip, "yes")) { + ip = gf_cfg_get_key(sess->dm->cfg, "Network", "MobileIP"); + } else { + ip = NULL; + } + } else { + ip = NULL; + } if (!proxy) { proxy = sess->server_name; @@ -642,8 +730,8 @@ static void gf_dm_connect(GF_DownloadSession *sess) sess->last_error = e; gf_dm_sess_notify_state(sess, sess->status, e); return; - } - + } + sess->status = GF_NETIO_CONNECTED; gf_dm_sess_notify_state(sess, GF_NETIO_CONNECTED, GF_OK); //gf_sk_set_block_mode(sess->sock, 1); @@ -665,7 +753,7 @@ static void gf_dm_connect(GF_DownloadSession *sess) ret = SSL_connect(sess->ssl); assert(ret>0); - cert = SSL_get_peer_certificate(sess->ssl); + cert = SSL_get_peer_certificate(sess->ssl); /*if we have a cert, check it*/ if (cert) { vresult = SSL_get_verify_result(sess->ssl); @@ -722,6 +810,35 @@ const char *gf_dm_sess_mime_type(GF_DownloadSession *sess) +GF_Err gf_dm_sess_process(GF_DownloadSession *sess) +{ + Bool go; + go = 1; + while (go) { + switch (sess->status) { + /*setup download*/ + case GF_NETIO_SETUP: + gf_dm_connect(sess); + if (sess->status == GF_NETIO_SETUP) + gf_sleep(200); + break; + case GF_NETIO_WAIT_FOR_REPLY: + gf_sleep(20); + case GF_NETIO_CONNECTED: + case GF_NETIO_DATA_EXCHANGE: + sess->do_requests(sess); + if (!sess->cache_name && !sess->th) + return sess->last_error; + break; + case GF_NETIO_DISCONNECTED: + case GF_NETIO_STATE_ERROR: + go = 0; + break; + } + } + return sess->last_error; +} + GF_DownloadManager *gf_dm_new(GF_Config *cfg) { @@ -730,15 +847,16 @@ GF_DownloadManager *gf_dm_new(GF_Config *cfg) if (!cfg) return NULL; GF_SAFEALLOC(dm, GF_DownloadManager); dm->sessions = gf_list_new(); + dm->skip_proxy_servers = gf_list_new(); dm->cfg = cfg; opt = gf_cfg_get_key(cfg, "General", "CacheDirectory"); if (opt) { if (opt[strlen(opt)-1] != GF_PATH_SEPARATOR) { - dm->cache_directory = (char *) malloc(sizeof(char)* (strlen(opt)+2)); + dm->cache_directory = (char *) gf_malloc(sizeof(char)* (strlen(opt)+2)); sprintf(dm->cache_directory, "%s%c", opt, GF_PATH_SEPARATOR); } else { - dm->cache_directory = strdup(opt); + dm->cache_directory = gf_strdup(opt); } } #ifdef GPAC_HAS_SSL @@ -748,7 +866,7 @@ GF_DownloadManager *gf_dm_new(GF_Config *cfg) } void gf_dm_set_auth_callback(GF_DownloadManager *dm, - Bool (*GetUserPassword)(void *usr_cbk, const char *site_url, char *usr_name, char *password), + Bool (*GetUserPassword)(void *usr_cbk, const char *site_url, char *usr_name, char *password), void *usr_cbk) { if (dm) { @@ -766,13 +884,20 @@ void gf_dm_del(GF_DownloadManager *dm) } gf_list_del(dm->sessions); - free(dm->cache_directory); + while (gf_list_count(dm->skip_proxy_servers)) { + char *serv = gf_list_get(dm->skip_proxy_servers, 0); + gf_list_rem(dm->skip_proxy_servers, 0); + gf_free(serv); + } + gf_list_del(dm->skip_proxy_servers); + + gf_free(dm->cache_directory); #ifdef GPAC_HAS_SSL if (dm->ssl_ctx) SSL_CTX_free(dm->ssl_ctx); #endif - free(dm); + gf_free(dm); } @@ -780,7 +905,7 @@ static GFINLINE void gf_dm_data_received(GF_DownloadSession *sess, char *data, u { GF_NETIO_Parameter par; u32 runtime, rcv; - + rcv = nbBytes; if (! (sess->flags & GF_NETIO_SESSION_NOT_CACHED)) { @@ -790,10 +915,11 @@ static GFINLINE void gf_dm_data_received(GF_DownloadSession *sess, char *data, u } sess->bytes_done += nbBytes; /*if not threaded don't signal data to user*/ - if (sess->th) { +// if (sess->th) + { par.msg_type = GF_NETIO_DATA_EXCHANGE; par.error = GF_OK; - par.data = NULL; + par.data = data; par.size = nbBytes; gf_dm_sess_user_io(sess, &par); } @@ -801,7 +927,7 @@ static GFINLINE void gf_dm_data_received(GF_DownloadSession *sess, char *data, u while (nbBytes) { if (sess->icy_bytes == sess->icy_metaint) { sess->icy_count = 1 + 16* (u8) data[0]; - + /*skip icy metadata*/ if (sess->icy_count >= nbBytes) { sess->icy_count -= nbBytes; @@ -812,7 +938,7 @@ static GFINLINE void gf_dm_data_received(GF_DownloadSession *sess, char *data, u char szData[4096]; memcpy(szData, data+1, sess->icy_count-1); szData[sess->icy_count] = 0; - + par.error = 0; par.msg_type = GF_NETIO_PARSE_HEADER; par.name = "icy-meta"; @@ -846,8 +972,8 @@ static GFINLINE void gf_dm_data_received(GF_DownloadSession *sess, char *data, u } } else { sess->bytes_done += nbBytes; - /*if not threaded don't signal data to user*/ - if (sess->th) { + /*if not threaded or cached, don't signal data to user*/ + if (sess->th || !sess->cache_name) { par.msg_type = GF_NETIO_DATA_EXCHANGE; par.error = GF_OK; par.data = data; @@ -906,7 +1032,7 @@ GF_Err gf_dm_sess_fetch_data(GF_DownloadSession *sess, char *buffer, u32 buffer_ if (sess->init_data_size<=buffer_size) { memcpy(buffer, sess->init_data, sizeof(char)*sess->init_data_size); *read_size = sess->init_data_size; - free(sess->init_data); + gf_free(sess->init_data); sess->init_data = NULL; sess->init_data_size = 0; } else { @@ -994,9 +1120,10 @@ void http_do_requests(GF_DownloadSession *sess) char comp[400]; char *new_location; char *hdr, *hdr_val; - u32 bytesRead, res; + u32 res; + s32 bytesRead; s32 LinePos, Pos; - u32 rsp_code, ContentLength, first_byte, last_byte, total_size, range, no_range; + u32 rsp_code, ContentLength, first_byte, last_byte, total_size, range, no_range, no_cache; s32 BodyStart; /*sent HTTP request*/ @@ -1004,10 +1131,11 @@ void http_do_requests(GF_DownloadSession *sess) char range_buf[1024]; char pass_buf[1024]; const char *user_agent; + const char *url; const char *user_profile; const char *param_string; u32 size; - Bool has_accept, has_connection, has_range, has_agent, send_profile; + Bool has_accept, has_connection, has_range, has_agent, has_language, send_profile; /*setup authentification*/ strcpy(pass_buf, ""); @@ -1021,7 +1149,7 @@ void http_do_requests(GF_DownloadSession *sess) sess->status = GF_NETIO_STATE_ERROR; return; } - sess->passwd = strdup(szPASS); + sess->passwd = gf_strdup(szPASS); } sprintf(pass_buf, "%s:%s", sess->user, sess->passwd); size = gf_base64_encode(pass_buf, strlen(pass_buf), range_buf, 1024); @@ -1040,12 +1168,15 @@ void http_do_requests(GF_DownloadSession *sess) if (!sPass) sPass = "mix"; sprintf(https_get_buffer, "%s&login=%s&password=%s", sess->remote_path, sLogin, sPass); } -#endif +#endif - user_agent = gf_cfg_get_key(sess->dm->cfg, "Downloader", "UserAgent"); + if (sess->dm) + user_agent = gf_cfg_get_key(sess->dm->cfg, "Downloader", "UserAgent"); + else + user_agent = NULL; if (!user_agent) user_agent = GF_DOWNLOAD_AGENT_NAME; - + par.error = 0; par.msg_type = GF_NETIO_GET_METHOD; par.name = NULL; @@ -1059,31 +1190,34 @@ void http_do_requests(GF_DownloadSession *sess) sess->http_read_type = 0; } - param_string = gf_cfg_get_key(sess->dm->cfg, "Downloader", "ParamString"); + url = (sess->proxy_enabled==1) ? sess->orig_url : sess->remote_path; + if (sess->dm) + param_string = gf_cfg_get_key(sess->dm->cfg, "Downloader", "ParamString"); + else + param_string = NULL; if (param_string) { if (strchr(sess->remote_path, '?')) { sprintf(sHTTP, "%s %s&%s HTTP/1.0\r\nHost: %s\r\n" , - par.name ? par.name : "GET", sess->remote_path, param_string, sess->server_name); + par.name ? par.name : "GET", url, param_string, sess->server_name); } else { sprintf(sHTTP, "%s %s?%s HTTP/1.0\r\nHost: %s\r\n" , - par.name ? par.name : "GET", sess->remote_path, param_string, sess->server_name); + par.name ? par.name : "GET", url, param_string, sess->server_name); } } else { sprintf(sHTTP, "%s %s HTTP/1.0\r\nHost: %s\r\n" , - par.name ? par.name : "GET", sess->remote_path, sess->server_name); + par.name ? par.name : "GET", url, sess->server_name); } /*signal we support title streaming*/ if (!strcmp(sess->remote_path, "/")) strcat(sHTTP, "icy-metadata:1\r\n"); /*get all headers*/ - has_agent = has_accept = has_connection = has_range = 0; + has_agent = has_accept = has_connection = has_range = has_language = 0; while (1) { par.msg_type = GF_NETIO_GET_HEADER; - par.name = NULL; par.value = NULL; gf_dm_sess_user_io(sess, &par); - if (!par.name) break; + if (!par.value) break; strcat(sHTTP, par.name); strcat(sHTTP, ": "); strcat(sHTTP, par.value); @@ -1092,6 +1226,8 @@ void http_do_requests(GF_DownloadSession *sess) else if (!strcmp(par.name, "Connection")) has_connection = 1; else if (!strcmp(par.name, "Range")) has_range = 1; else if (!strcmp(par.name, "User-Agent")) has_agent = 1; + else if (!strcmp(par.name, "Accept-Language")) has_language = 1; + if (!par.msg_type) break; } if (!has_agent) { strcat(sHTTP, "User-Agent: "); @@ -1099,11 +1235,30 @@ void http_do_requests(GF_DownloadSession *sess) strcat(sHTTP, "\r\n"); } if (!has_accept) strcat(sHTTP, "Accept: */*\r\n"); - if (!has_connection) strcat(sHTTP, "Connection: Keep-Alive\r\n"); + if (sess->proxy_enabled==1) strcat(sHTTP, "Proxy-Connection: Keep-alive\r\n"); + else if (!has_connection) strcat(sHTTP, "Connection: Keep-Alive\r\n"); if (!has_range && sess->cache_start_size) { sprintf(range_buf, "Range: bytes=%d-\r\n", sess->cache_start_size); strcat(sHTTP, range_buf); + } else if (!has_range && sess->needs_range) { + if (!sess->range_end) sprintf(range_buf, "Range: bytes=%d-\r\n", sess->range_start); + else sprintf(range_buf, "Range: bytes=%d-%d\r\n", sess->range_start, sess->range_end); + strcat(sHTTP, range_buf); + } + if (!has_language) { + const char *opt; + if (sess->dm) + opt = gf_cfg_get_key(sess->dm->cfg, "Systems", "Language2CC"); + else + opt = NULL; + if (opt) { + strcat(sHTTP, "Accept-Language: "); + strcat(sHTTP, opt); + strcat(sHTTP, "\r\n"); + } } + + if (strlen(pass_buf)) { strcat(sHTTP, pass_buf); strcat(sHTTP, "\r\n"); @@ -1116,18 +1271,24 @@ void http_do_requests(GF_DownloadSession *sess) /*check if we have personalization info*/ send_profile = 0; - user_profile = gf_cfg_get_key(sess->dm->cfg, "Downloader", "UserProfileID"); + if (sess->dm) + user_profile = gf_cfg_get_key(sess->dm->cfg, "Downloader", "UserProfileID"); + else + user_profile = NULL; if (user_profile) { strcat(sHTTP, "X-UserProfileID: "); strcat(sHTTP, user_profile); strcat(sHTTP, "\r\n"); } else { - user_profile = gf_cfg_get_key(sess->dm->cfg, "Downloader", "UserProfile"); + if (sess->dm) + user_profile = gf_cfg_get_key(sess->dm->cfg, "Downloader", "UserProfile"); + else + user_profile = NULL; if (user_profile) { - FILE *profile = fopen(user_profile, "rt"); + FILE *profile = gf_f64_open(user_profile, "rt"); if (profile) { - fseek(profile, 0, SEEK_END); - par.size = ftell(profile); + gf_f64_seek(profile, 0, SEEK_END); + par.size = (u32) gf_f64_tell(profile); fclose(profile); sprintf(range_buf, "Content-Length: %d\r\n", par.size); strcat(sHTTP, range_buf); @@ -1149,7 +1310,7 @@ void http_do_requests(GF_DownloadSession *sess) if (send_profile || par.data) { u32 len = strlen(sHTTP); - char *tmp_buf = malloc(sizeof(char)*(len+par.size)); + char *tmp_buf = gf_malloc(sizeof(char)*(len+par.size)); strcpy(tmp_buf, sHTTP); if (par.data) { memcpy(tmp_buf+len, par.data, par.size); @@ -1157,32 +1318,43 @@ void http_do_requests(GF_DownloadSession *sess) FILE *profile; user_profile = gf_cfg_get_key(sess->dm->cfg, "Downloader", "UserProfile"); assert (user_profile); - profile = fopen(user_profile, "rt"); - fread(tmp_buf+len, 1, par.size, profile); - fclose(profile); + profile = gf_f64_open(user_profile, "rt"); + if (profile){ + u32 readen = fread(tmp_buf+len, 1, par.size, profile); + if (readen<size){ + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, + ("Error while loading Downloader/UserProfile, size=%d, should be %d.", readen, par.size)); + for (; readen < size; readen++){ + tmp_buf[len + readen] = 0; + } + } + fclose(profile); + } else { + GF_LOG(GF_LOG_WARNING, GF_LOG_NETWORK, ("Error while loading Profile file %s.", user_profile)); + } } #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; - } else + } else #endif e = gf_sk_send(sess->sock, tmp_buf, len+par.size); - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] %s\n\n", tmp_buf)); - free(tmp_buf); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP] Sending request %s\n\n", tmp_buf)); + gf_free(tmp_buf); } else { #ifdef GPAC_HAS_SSL if (sess->ssl) { e = GF_IP_NETWORK_FAILURE; if (!SSL_write(sess->ssl, sHTTP, strlen(sHTTP))) e = GF_OK; - } else + } else #endif e = gf_sk_send(sess->sock, sHTTP, strlen(sHTTP)); - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] %s\n\n", sHTTP)); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP] Sending request %s\n\n", sHTTP)); } if (e) { @@ -1203,7 +1375,7 @@ void http_do_requests(GF_DownloadSession *sess) new_location = NULL; while (1) { e = gf_dm_read_data(sess, sHTTP + bytesRead, GF_DOWNLOAD_BUFFER_SIZE - bytesRead, &res); - + switch (e) { case GF_IP_NETWORK_EMPTY: if (!bytesRead) return; @@ -1239,23 +1411,23 @@ void http_do_requests(GF_DownloadSession *sess) e = GF_REMOTE_SERVICE_ERROR; goto exit; } - if (!BodyStart) + if (!BodyStart) BodyStart = bytesRead; sHTTP[BodyStart-1] = 0; - GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[HTTP] %s\n\n", sHTTP)); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[HTTP] %s\n\n", sHTTP)); LinePos = gf_token_get_line(sHTTP, 0, bytesRead, buf, 1024); Pos = gf_token_get(buf, 0, " \t\r\n", comp, 400); - if (sess->mime_type) free(sess->mime_type); + if (sess->mime_type) gf_free(sess->mime_type); sess->mime_type = NULL; is_ice = 0; if (!strncmp("ICY", comp, 4)) { is_ice = 1; /*be prepared not to receive any mime type from ShoutCast servers*/ - sess->mime_type = strdup("audio/mpeg"); + sess->mime_type = gf_strdup("audio/mpeg"); } else if ((strncmp("HTTP", comp, 4) != 0)) { e = GF_REMOTE_SERVICE_ERROR; goto exit; @@ -1268,7 +1440,7 @@ void http_do_requests(GF_DownloadSession *sess) rsp_code = (u32) atoi(comp); Pos = gf_token_get(buf, Pos, " \r\n", comp, 400); - no_range = range = ContentLength = first_byte = last_byte = total_size = 0; + no_range = range = ContentLength = first_byte = last_byte = total_size = no_cache = 0; //parse header while (1) { char *sep, *hdr_sep; @@ -1296,9 +1468,9 @@ void http_do_requests(GF_DownloadSession *sess) gf_dm_sess_user_io(sess, &par); if (!stricmp(hdr, "Content-Length") ) ContentLength = (u32) atoi(hdr_val); - else if (!stricmp(hdr, "Content-Type")) { - if (sess->mime_type) free(sess->mime_type); - sess->mime_type = strdup(hdr_val); + else if (!stricmp(hdr, "Content-Type")) { + if (sess->mime_type) gf_free(sess->mime_type); + sess->mime_type = gf_strdup(hdr_val); while (1) { u32 len = strlen(sess->mime_type); char c = len ? sess->mime_type[len-1] : 0; @@ -1311,7 +1483,7 @@ void http_do_requests(GF_DownloadSession *sess) hdr = strchr(sess->mime_type, ';'); if (hdr) hdr[0] = 0; } - else if (!stricmp(hdr, "Content-Range")) { + else if (!stricmp(hdr, "Content-Range")) { range = 1; if (!strncmp(hdr_val, "bytes", 5)) { hdr_val += 5; @@ -1327,15 +1499,20 @@ void http_do_requests(GF_DownloadSession *sess) else if (!stricmp(hdr, "Accept-Ranges")) { if (strstr(hdr_val, "none")) no_range = 1; } - else if (!stricmp(hdr, "Location")) - new_location = strdup(hdr_val); - else if (!stricmp(hdr, "icy-metaint")) + else if (!stricmp(hdr, "Location")) + new_location = gf_strdup(hdr_val); + else if (!stricmp(hdr, "icy-metaint")) sess->icy_metaint = atoi(hdr_val); - else if (!stricmp(hdr, "ice") || !stricmp(hdr, "icy") ) + else if (!stricmp(hdr, "ice") || !stricmp(hdr, "icy") ) { is_ice = 1; - else if (!stricmp(hdr, "X-UserProfileID") ) + no_cache = 1; + } + else if (!stricmp(hdr, "Cache-Control")) { + if (strstr(hdr_val, "no-cache")) no_cache = 1; + } + else if (!stricmp(hdr, "X-UserProfileID") ) gf_cfg_set_key(sess->dm->cfg, "Downloader", "UserProfileID", hdr_val); -/* else if (!stricmp(hdr, "Connection") ) +/* else if (!stricmp(hdr, "Connection") ) if (strstr(hdr_val, "close")) sess->http_read_type = 1; */ @@ -1344,13 +1521,16 @@ void http_do_requests(GF_DownloadSession *sess) } if (no_range) first_byte = 0; - if (sess->cache_start_size) { + /*check if this code was useful ? */ +#if 0 + if (sess->cache_start_size && (rsp_code == 200) ) { if (total_size && (sess->cache_start_size >= total_size) ) { rsp_code = 200; ContentLength = total_size; } if (ContentLength && (sess->cache_start_size == ContentLength) ) rsp_code = 200; - } + } +#endif par.msg_type = GF_NETIO_PARSE_REPLY; par.error = GF_OK; @@ -1364,6 +1544,11 @@ void http_do_requests(GF_DownloadSession *sess) case 206: gf_dm_sess_user_io(sess, &par); e = GF_OK; + if (sess->proxy_enabled==2) { + sess->proxy_enabled=0; + if (sess->dm) + gf_list_add(sess->dm->skip_proxy_servers, gf_strdup(sess->server_name)); + } break; /*redirection: extract the new location*/ case 301: @@ -1374,7 +1559,7 @@ void http_do_requests(GF_DownloadSession *sess) goto exit; } while ( - (new_location[strlen(new_location)-1] == '\n') + (new_location[strlen(new_location)-1] == '\n') || (new_location[strlen(new_location)-1] == '\r') ) new_location[strlen(new_location)-1] = 0; @@ -1406,6 +1591,13 @@ void http_do_requests(GF_DownloadSession *sess) e = GF_URL_ERROR; goto exit; case 503: + /*retry without proxy*/ + if (sess->proxy_enabled==1) { + sess->proxy_enabled=2; + gf_dm_disconnect(sess); + sess->status = GF_NETIO_SETUP; + return; + } default: gf_dm_sess_user_io(sess, &par); e = GF_REMOTE_SERVICE_ERROR; @@ -1429,17 +1621,30 @@ void http_do_requests(GF_DownloadSession *sess) // if (!is_ice && !ContentLength) e = GF_REMOTE_SERVICE_ERROR; if (e) goto exit; + if (is_ice && no_cache && !sess->use_cache_extension) { + sess->flags |= GF_NETIO_SESSION_NOT_CACHED; + no_range = 1; + first_byte = 0; + if (sess->cache) { + fclose(sess->cache); + sess->cache = NULL; + } + if (sess->cache_name) { + gf_delete_file(sess->cache_name); + sess->cache = gf_f64_open(sess->cache_name, "wb"); + } + sess->cache_start_size = 0; + } /*force disabling cache (no content length)*/ if (is_ice) { - sess->flags |= GF_NETIO_SESSION_NOT_CACHED; if (sess->mime_type && !stricmp(sess->mime_type, "video/nsv")) { - free(sess->mime_type); - sess->mime_type = strdup("audio/aac"); + gf_free(sess->mime_type); + sess->mime_type = gf_strdup("audio/aac"); } } /*done*/ - if (sess->cache_start_size + if (sess->cache_start_size && ( (total_size && sess->cache_start_size >= total_size) || (sess->cache_start_size == ContentLength)) ) { sess->total_size = sess->bytes_done = sess->cache_start_size; /*disconnect*/ @@ -1463,7 +1668,10 @@ void http_do_requests(GF_DownloadSession *sess) sess->cache_start_size = sess->bytes_done = 0; sess->total_size = ContentLength; if (! (sess->flags & GF_NETIO_SESSION_NOT_CACHED) ) { - sess->cache = fopen(sess->cache_name, "wb"); + if (sess->flags & GF_NETIO_SESSION_REUSE_APPEND) + sess->cache = gf_f64_open(sess->cache_name, "ab"); + else + sess->cache = gf_f64_open(sess->cache_name, "wb"); if (!sess->cache) { e = GF_IO_ERR; goto exit; @@ -1475,7 +1683,7 @@ void http_do_requests(GF_DownloadSession *sess) else { sess->total_size = ContentLength + sess->cache_start_size; if (! (sess->flags & GF_NETIO_SESSION_NOT_CACHED) ) { - sess->cache = fopen(sess->cache_name, "ab"); + sess->cache = gf_f64_open(sess->cache_name, "ab"); if (!sess->cache) { e = GF_IO_ERR; goto exit; @@ -1494,9 +1702,9 @@ void http_do_requests(GF_DownloadSession *sess) gf_dm_data_received(sess, sHTTP + BodyStart, bytesRead - BodyStart); /*store data if no callbacks or cache*/ // if (sess->flags & GF_NETIO_SESSION_NOT_CACHED) { - if (sess->init_data) free(sess->init_data); + if (sess->init_data) gf_free(sess->init_data); sess->init_data_size = bytesRead - BodyStart; - sess->init_data = (char *) malloc(sizeof(char) * sess->init_data_size); + sess->init_data = (char *) gf_malloc(sizeof(char) * sess->init_data_size); memcpy(sess->init_data, sHTTP+BodyStart, sess->init_data_size); // } } @@ -1513,6 +1721,10 @@ exit: /*fetch data*/ while (1) { u32 size; + + if (sess->status>=GF_NETIO_DISCONNECTED) + return; + #if 1 if (sess->limit_data_rate && sess->bytes_per_sec) { if (sess->bytes_per_sec>sess->limit_data_rate) { @@ -1524,10 +1736,11 @@ exit: } #endif e = gf_dm_read_data(sess, sHTTP, GF_DOWNLOAD_BUFFER_SIZE, &size); - if (!size || e == GF_IP_NETWORK_EMPTY) { - if (!sess->total_size && (gf_sys_clock() - sess->window_start > 1000)) { + if (!size || e == GF_IP_NETWORK_EMPTY) { + if (!sess->total_size && (gf_sys_clock() - sess->window_start > 2000)) { sess->total_size = sess->bytes_done; gf_dm_sess_notify_state(sess, GF_NETIO_DATA_TRANSFERED, GF_OK); + sess->status = GF_NETIO_DISCONNECTED; } return; } @@ -1544,3 +1757,40 @@ exit: } } +GF_Err gf_dm_wget(const char *url, const char *filename) +{ + GF_Err e; + GF_DownloadSession *dnload; + dnload = gf_dm_sess_new_simple((char *)url, GF_NETIO_SESSION_NOT_THREADED, NULL, NULL, (char *)filename, &e); + if (!dnload) return GF_BAD_PARAM; + + if (e == GF_OK) { + e = gf_dm_sess_process(dnload); + } + gf_dm_sess_del(dnload); + return e; +} + +const char *gf_dm_sess_get_resource_name(GF_DownloadSession *dnload) +{ + return dnload ? dnload->orig_url : NULL; +} + +GF_Err gf_dm_sess_reset(GF_DownloadSession *sess) +{ + if (!sess) return GF_BAD_PARAM; + sess->status = GF_NETIO_SETUP; + sess->needs_range = 0; + sess->range_start = sess->range_end = 0; + sess->bytes_done = sess->bytes_in_wnd = sess->bytes_per_sec = 0; + if (sess->init_data) free(sess->init_data); + sess->init_data = NULL; + sess->init_data_size = 0; + sess->last_error = GF_OK; + if (sess->mime_type) free(sess->mime_type); + sess->mime_type = NULL; + sess->total_size = 0; + sess->window_start = 0; + sess->start_time = 0; + return GF_OK; +} diff --git a/src/utils/error.c b/src/utils/error.c index 6f94278..2c15a03 100644 --- a/src/utils/error.c +++ b/src/utils/error.c @@ -22,66 +22,620 @@ * */ +#include <string.h> + +#define STD_MALLOC 0 +#define GOOGLE_MALLOC 1 +#define INTEL_MALLOC 2 +#define DL_MALLOC 3 + +#ifdef WIN32 +#define USE_MALLOC STD_MALLOC +#else +#define USE_MALLOC STD_MALLOC +#endif + + +#if defined(_WIN32_WCE) && !defined(strdup) +#define strdup _strdup +#endif + +/* + WARNING - you must enable C++ style compilation of this file (error.c) to be able to compile + with google malloc. This is not set by default in the project settings. +*/ +#if (USE_MALLOC==GOOGLE_MALLOC) +#include <config.h> +#include <base/commandlineflags.h> +#include <google/malloc_extension.h> + +#ifdef WIN32 +#pragma comment(lib, "libtcmalloc_minimal") +#endif + +#define MALLOC malloc +#define CALLOC calloc +#define REALLOC realloc +#define FREE free +#define STRDUP(a) return strdup(a); + +/*we must use c++ compiler for google malloc :( */ +#define CDECL extern "C" +#endif + +#if (USE_MALLOC==INTEL_MALLOC) +#define CDECL +CDECL void * scalable_malloc(size_t size); +CDECL void * scalable_realloc(void* ptr, size_t size); +CDECL void * scalable_calloc(size_t num, size_t size); +CDECL void scalable_free(void* ptr); + +#ifdef WIN32 +#pragma comment(lib, "tbbmalloc.lib") +#endif + +#define MALLOC scalable_malloc +#define CALLOC scalable_calloc +#define REALLOC scalable_realloc +#define FREE scalable_free +#define STRDUP(_a) if (_a) { unsigned int len = strlen(_a)+1; char *ptr = (char *) scalable_malloc(len); strcpy(ptr, _a); return ptr; } else { return NULL; } + +#endif + +#ifndef CDECL +#define CDECL +#endif + +#if (USE_MALLOC==DL_MALLOC) + +CDECL void * dlmalloc(size_t size); +CDECL void * dlrealloc(void* ptr, size_t size); +CDECL void * dlcalloc(size_t num, size_t size); +CDECL void dlfree(void* ptr); + +#define MALLOC dlmalloc +#define CALLOC dlcalloc +#define REALLOC dlrealloc +#define FREE dlfree +#define STRDUP(_a) if (_a) { unsigned int len = strlen(_a)+1; char *ptr = (char *) dlmalloc(len); strcpy(ptr, _a); return ptr; } else { return NULL; } + +#endif + +#if (USE_MALLOC==STD_MALLOC) #include <stdlib.h> -#include <string.h> + +#define MALLOC malloc +#define CALLOC calloc +#define REALLOC realloc +#define FREE free +#define STRDUP(a) return strdup(a); + +#endif + + + #ifndef _WIN32_WCE #include <assert.h> #endif +/*This is to handle cases where config.h is generated at the root of the gpac build tree (./configure) +This is only needed when building libgpac and modules when libgpac is not installed*/ +#ifdef GPAC_HAVE_CONFIG_H +# include "config.h" +#else +# include <gpac/configuration.h> +#endif + /*GPAC memory tracking*/ -size_t gpac_allocated_memory = 0; -size_t gpac_nb_alloc_blocs = 0; +#ifndef GPAC_MEMORY_TRACKING + +CDECL void *gf_malloc(size_t size) { - void *ptr; - size_t size_g = size + sizeof(size_t); - ptr = malloc(size_g); - *(size_t *)ptr = size; - gpac_allocated_memory += size; - gpac_nb_alloc_blocs++; - return (void *) ( (char *)ptr + sizeof(size_t) ); + return MALLOC(size); } +CDECL +void *gf_calloc(size_t num, size_t size_of) +{ + return CALLOC(num, size_of); +} +CDECL void *gf_realloc(void *ptr, size_t size) { - size_t prev_size; - char *ptr_g = (char *)ptr; - if (!ptr) return gf_malloc(size); - ptr_g -= sizeof(size_t); - prev_size = *(size_t *)ptr_g; -#ifndef _WIN32_WCE - assert(gpac_allocated_memory >= prev_size); -#endif - gpac_allocated_memory -= prev_size; - ptr_g = (char *) realloc(ptr_g, size+sizeof(size_t)); - *(size_t *)ptr_g = size; - gpac_allocated_memory += size; - return ptr_g + sizeof(size_t); + return REALLOC(ptr, size); } +CDECL void gf_free(void *ptr) { - if (ptr) { - char *ptr_g = (char *)ptr - sizeof(size_t); - size_t size_g = *(size_t *)ptr_g; -#ifndef _WIN32_WCE - assert(gpac_allocated_memory >= size_g); + FREE(ptr); +} +CDECL +char *gf_strdup(const char *str) +{ + STRDUP(str); +} + +#else + + +CDECL +size_t gpac_allocated_memory = 0; +size_t gpac_nb_alloc_blocs = 0; + +#ifdef _WIN32_WCE +#define assert(p) #endif - gpac_allocated_memory -= size_g; - gpac_nb_alloc_blocs--; - free(ptr_g); + +static void register_address(void *ptr, size_t size, char *filename, int line); +static int unregister_address(void *ptr, char *filename, int line); + +static void gf_memory_log(unsigned int level, const char *fmt, ...); +enum +{ + /*! Log message describes an error*/ + GF_MEMORY_ERROR = 1, + /*! Log message describes a warning*/ + GF_MEMORY_WARNING, + /*! Log message is informational (state, etc..)*/ + GF_MEMORY_INFO, + /*! Log message is a debug info*/ + GF_MEMORY_DEBUG, +}; + +static void *gf_mem_malloc_basic(size_t size, char *filename, int line) +{ + return MALLOC(size); +} +static void *gf_mem_calloc_basic(size_t num, size_t size_of, char *filename, int line) +{ + return CALLOC(num, size_of); +} +static void *gf_mem_realloc_basic(void *ptr, size_t size, char *filename, int line) +{ + return REALLOC(ptr, size); +} +static void gf_mem_free_basic(void *ptr, char *filename, int line) +{ + FREE(ptr); +} +static char *gf_mem_strdup_basic(const char *str, char *filename, int line) +{ + STRDUP(str); +} + +void *gf_mem_malloc_tracker(size_t size, char *filename, int line) +{ + void *ptr = MALLOC(size); + if (!ptr) { + gf_memory_log(GF_MEMORY_ERROR, "malloc() has returned a NULL pointer\n"); + assert(0); + } else { + register_address(ptr, size, filename, line); } + gf_memory_log(GF_MEMORY_DEBUG, "malloc %3d bytes at 0x%08X in file %s at line %d\n", size, ptr, filename, line); + return ptr; } -char *gf_strdup(const char *str) + +void *gf_mem_calloc_tracker(size_t num, size_t size_of, char *filename, int line) { - size_t len = strlen(str) + 1; - char *ptr = (char *) gf_malloc(len); - memcpy(ptr, str, len); + size_t size = num*size_of; + void *ptr = CALLOC(num, size_of); + if (!ptr) { + gf_memory_log(GF_MEMORY_ERROR, "calloc() has returned a NULL pointer\n"); + assert(0); + } else { + register_address(ptr, size, filename, line); + } + gf_memory_log(GF_MEMORY_DEBUG, "calloc %3d bytes at 0x%08X in file %s at line %d\n", size, ptr, filename, line); return ptr; } +void gf_mem_free_tracker(void *ptr, char *filename, int line) +{ + int size_prev; + if (ptr && (size_prev=unregister_address(ptr, filename, line))) { + gf_memory_log(GF_MEMORY_DEBUG, "free %3d bytes at 0x%08X in file %s at line %d\n", size_prev, ptr, filename, line); + FREE(ptr); + } +} + +void *gf_mem_realloc_tracker(void *ptr, size_t size, char *filename, int line) +{ + void *ptr_g; + int size_prev; + if (!ptr) { + gf_memory_log(GF_MEMORY_DEBUG, "realloc() from a null pointer: calling malloc() instead\n"); + return gf_mem_malloc_tracker(size, filename, line); + } + /*a) The return value is NULL if the size is zero and the buffer argument is not NULL. In this case, the original block is freed.*/ + if (!size) { + gf_memory_log(GF_MEMORY_DEBUG, "realloc() with a null size: calling free() instead\n"); + gf_mem_free_tracker(ptr, filename, line); + return NULL; + } + ptr_g = REALLOC(ptr, size); + if (!ptr_g) { + /*b) The return value is NULL if there is not enough available memory to expand the block to the given size. In this case, the original block is unchanged.*/ + gf_memory_log(GF_MEMORY_ERROR, "realloc() has returned a NULL pointer\n"); + assert(0); + } else { + size_prev = unregister_address(ptr, filename, line); + register_address(ptr_g, size, filename, line); + gf_memory_log(GF_MEMORY_DEBUG, "realloc %3d (instead of %3d) bytes at 0x%08X in file %s at line %d\n", size, size_prev, ptr, filename, line); + } + return ptr_g; +} + +char *gf_mem_strdup_tracker(const char *str, char *filename, int line) +{ + char *ptr; + if (!str) return NULL; + ptr = (char*)gf_mem_malloc_tracker(strlen(str)+1, filename, line); + strcpy(ptr, str); + return ptr; +} + +static void *(*gf_mem_malloc_proto)(size_t size, char *filename, int line) = gf_mem_malloc_basic; +static void *(*gf_mem_calloc_proto)(size_t num, size_t size_of, char *filename, int line) = gf_mem_calloc_basic; +static void *(*gf_mem_realloc_proto)(void *ptr, size_t size, char *filename, int line) = gf_mem_realloc_basic; +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; + +CDECL +void *gf_mem_malloc(size_t size, char *filename, int line) +{ + return gf_mem_malloc_proto(size, filename, line); +} +CDECL +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); +} +CDECL +void *gf_mem_realloc(void *ptr, size_t size, char *filename, int line) +{ + return gf_mem_realloc_proto(ptr, size, filename, line); +} +CDECL +void gf_mem_free(void *ptr, char *filename, int line) +{ + gf_mem_free_proto(ptr, filename, line); +} +CDECL +char *gf_mem_strdup(const char *str, char *filename, int line) +{ + return gf_mem_strdup_proto(str, filename, line); +} + +CDECL +void gf_mem_enable_tracker() +{ + gf_mem_malloc_proto = gf_mem_malloc_tracker; + gf_mem_calloc_proto = gf_mem_calloc_tracker; + gf_mem_realloc_proto = gf_mem_realloc_tracker; + gf_mem_free_proto = gf_mem_free_tracker; + gf_mem_strdup_proto = gf_mem_strdup_tracker; +} + + +#define GPAC_MEMORY_TRACKING_HASH_TABLE 1 +#if GPAC_MEMORY_TRACKING_HASH_TABLE + +#define HASH_ENTRIES 4096 + +typedef struct s_memory_element +{ + void *ptr; + int size; + struct s_memory_element *next; + int line; + char *filename; +} memory_element; + +/*pointer to the first element of the list*/ +typedef memory_element** memory_list; + +static unsigned int gf_memory_hash(void *ptr) +{ + return (((unsigned int)ptr>>4)+(unsigned int)ptr)%HASH_ENTRIES; +} + +#else + +typedef struct s_memory_element +{ + void *ptr; + int size; + struct s_memory_element *next; + int line; + char *filename; +} memory_element; + +/*pointer to the first element of the list*/ +typedef memory_element* memory_list; + +#endif + + +/*base functions (add, find, del_item, del) are implemented upon a stack model*/ +static void gf_memory_add_stack(memory_element **p, void *ptr, int size, char *filename, int line) +{ + memory_element *element = (memory_element*)MALLOC(sizeof(memory_element)+strlen(filename)); + element->ptr = ptr; + element->size = size; + element->line = line; + element->next = *p; + strcpy((char*)&element->filename, filename); + *p = element; +} +static int gf_memory_find_stack(memory_element *p, void *ptr) +{ + memory_element *element = p; + while (element) { + if (element->ptr == ptr) { + return 1; + } + element = element->next; + } + return 0; +} + +/*returns the size of the deleted item*/ +static int gf_memory_del_item_stack(memory_element **p, void *ptr) +{ + int size; + memory_element *curr_element=*p, *prev_element=NULL; + while (curr_element) { + if (curr_element->ptr == ptr) { + if (prev_element) prev_element->next = curr_element->next; + else *p = curr_element->next; + size = curr_element->size; + FREE(curr_element); + return size; + } + prev_element = curr_element; + curr_element = curr_element->next; + } + return 0; +} + +static void gf_memory_del_stack(memory_element **p) +{ + memory_element *curr_element=*p, *next_element; + while (curr_element) { + next_element = curr_element->next; + FREE(curr_element); + curr_element = next_element; + } + *p = NULL; +} + + +#if GPAC_MEMORY_TRACKING_HASH_TABLE + +/*this list is implemented as a stack to minimise the cost of freeing recent allocations*/ +static void gf_memory_add(memory_list *p, void *ptr, int size, char *filename, int line) +{ + unsigned int pos; + if (!*p) *p = (memory_list) CALLOC(HASH_ENTRIES, sizeof(memory_element*)); + assert(*p); + + pos = gf_memory_hash(ptr); + gf_memory_add_stack(&((*p)[pos]), ptr, size, filename, line); +} + + +static int gf_memory_find(memory_list p, void *ptr) +{ + unsigned int pos; + assert(p); + if (!p) return 0; + pos = gf_memory_hash(ptr); + return gf_memory_find_stack(p[pos], ptr); +} + +static int gf_memory_del_item(memory_list *p, void *ptr) +{ + unsigned int pos; + int ret; + memory_element **sub_list; + if (!*p) *p = (memory_list) CALLOC(HASH_ENTRIES, sizeof(memory_element*)); + assert(*p); + pos = gf_memory_hash(ptr); + sub_list = &((*p)[pos]); + if (!sub_list) return 0; + ret = gf_memory_del_item_stack(sub_list, ptr); + if (ret && !((*p)[pos])) { + /*check for deletion*/ + int i; + for (i=0; i<HASH_ENTRIES; i++) + if (&((*p)[i])) break; + if (i==HASH_ENTRIES) { + FREE(*p); + p = NULL; + } + } + return ret; +} + +static void gf_memory_del(memory_list *p) +{ + int i; + for (i=0; i<HASH_ENTRIES; i++) + gf_memory_del_stack(&((*p)[i])); + FREE(*p); + p = NULL; +} + +#else + +#define gf_memory_add gf_memory_add_stack +#define gf_memory_del gf_memory_del_stack +#define gf_memory_del_item gf_memory_del_item_stack +#define gf_memory_find gf_memory_find_stack + +#endif + + +#endif /*GPAC_MEMORY_TRACKING*/ + #include <gpac/tools.h> + +/*GPAC memory tracking*/ +#ifdef GPAC_MEMORY_TRACKING + +#include <gpac/thread.h> + +/*global lists of allocations and deallocations*/ +memory_list memory_add = NULL, memory_rem = NULL; +GF_Mutex *gpac_allocations_lock = NULL; + +static void register_address(void *ptr, size_t size, char *filename, int line) +{ + /*mutex initialization*/ + if (gpac_allocations_lock == 0) { + assert(!memory_add); + assert(!memory_rem); + gpac_allocations_lock = (GF_Mutex*)1; /*must be non-null to avoid a recursive infinite call*/ + gpac_allocations_lock = gf_mx_new("gpac_allocations_lock"); + } + else if (gpac_allocations_lock == (void*)1) { + /*we're initializing the mutex (ie called by the gf_mx_new() above)*/ + return; + } + + /*lock*/ + gf_mx_p(gpac_allocations_lock); + + gf_memory_add(&memory_add, ptr, size, filename, line); + gf_memory_del_item(&memory_rem, ptr); /*the same block can be reallocated, so remove it from the deallocation list*/ + + /*update stats*/ + gpac_allocated_memory += size; + gpac_nb_alloc_blocs++; + + //gf_memory_log(GF_MEMORY_DEBUG, "register %6d bytes at 0x%08X (%8d Bytes in %4d Blocks allocated)\n", size, ptr, gpac_allocated_memory, gpac_nb_alloc_blocs); + + /*unlock*/ + gf_mx_v(gpac_allocations_lock); +} + +/*returns the size of the unregistered block*/ +static int unregister_address(void *ptr, char *filename, int line) +{ + int size = 0; /*default: failure*/ + + /*lock*/ + gf_mx_p(gpac_allocations_lock); + + if (!memory_add) { + if (!memory_rem) { + /*assume we're rather destroying the mutex (ie calling the gf_mx_del() below) + than being called by free() before the first allocation occured*/ + return 1; + //gf_memory_log(GF_MEMORY_ERROR, "calling free() before the first allocation occured\n"); + //assert(0); + } + } else { + if (!gf_memory_find(memory_add, ptr)) { + if (!gf_memory_find(memory_rem, ptr)) { + gf_memory_log(GF_MEMORY_ERROR, "trying to free a never allocated block (0x%08X)\n", ptr); + //assert(0); /*don't assert since this is often due to allocations that occured out of gpac (fonts, etc.)*/ + } else { + gf_memory_log(GF_MEMORY_ERROR, "the block 0x%08X has already been freed line%5d from %s\n", line, filename); + assert(0); + } + } else { + size = gf_memory_del_item(&memory_add, ptr); + assert(size>=0); + + /*update stats*/ + gpac_allocated_memory -= size; + gpac_nb_alloc_blocs--; + + //gf_memory_log(GF_MEMORY_DEBUG, "unregister %6d bytes at 0x%08X (%8d bytes in %4d blocks remaining)\n", size, ptr, gpac_allocated_memory, gpac_nb_alloc_blocs); + + /*the allocation list is empty: free the lists to avoid a leak (we should be exiting)*/ + if (!memory_add) { + assert(!gpac_allocated_memory); + assert(!gpac_nb_alloc_blocs); + + /*we destroy the mutex we own, then we return*/ + gf_mx_del(gpac_allocations_lock); + gpac_allocations_lock = NULL; + + gf_memory_log(GF_MEMORY_DEBUG, "the allocated-blocks-list is empty: the freed-blocks-list will be emptied too.\n"); + gf_memory_del(&memory_rem); + + return size; + } else { + gf_memory_add(&memory_rem, ptr, size, filename, line); + } + } + } + + /*unlock*/ + gf_mx_v(gpac_allocations_lock); + + return size; +} + +static void gf_memory_log(unsigned int level, const char *fmt, ...) +{ + va_list vl; + char msg[255]; /*since we print*/ + assert(strlen(fmt) < 80); + va_start(vl, fmt); + vsprintf(msg, fmt, vl); + GF_LOG(level, GF_LOG_MEMORY, (msg)); + va_end(vl); +} + +/*prints allocations sum-up*/ +void gf_memory_size() +{ + gf_memory_log(GF_MEMORY_INFO, "Total: %d bytes allocated on %d blocks\n", gpac_allocated_memory, gpac_nb_alloc_blocs); +} + +/*prints the state of current allocations*/ +void gf_memory_print() +{ + /*if lists are empty, the mutex is also NULL*/ + if (!memory_add) { + assert(!gpac_allocations_lock); + gf_memory_log(GF_MEMORY_INFO, "gf_memory_print(): the memory tracker is not initialized.\n"); + } else { + int i=0; + assert(gpac_allocations_lock); + + /*lock*/ + gf_mx_p(gpac_allocations_lock); +#if GPAC_MEMORY_TRACKING_HASH_TABLE + for (i=0; i<HASH_ENTRIES; i++) { + memory_element *curr_element = memory_add[i], *next_element; +#else + { + memory_element *curr_element = memory_add, *next_element; +#endif + while (curr_element) { + next_element = curr_element->next; + gf_memory_log(GF_MEMORY_INFO, "Memory Block 0x%08X allocated line%5d from %s\n", curr_element->ptr, curr_element->line, &curr_element->filename); + curr_element = next_element; + } + } + gf_memory_size(); + + /*unlock*/ + gf_mx_v(gpac_allocations_lock); + } +} + +#endif + + static char szTYPE[5]; GF_EXPORT @@ -128,14 +682,14 @@ static const char *szProg[] = "====================", }; -static u32 prev_pos = 0; -static u32 prev_pc = 0; -static void gf_on_progress_stdout(char *_title, u32 done, u32 total) +static u64 prev_pos = 0; +static u64 prev_pc = 0; +static void gf_on_progress_stdout(char *_title, u64 done, u64 total) { Double prog; u32 pos; char *szT = _title ? (char *)_title : (char *) ""; - prog = done; + prog = (double) done; prog /= total; pos = MIN((u32) (20 * prog), 20); @@ -163,7 +717,7 @@ static gf_on_progress_cbk prog_cbk = NULL; static void *user_cbk; GF_EXPORT -void gf_set_progress(char *title, u32 done, u32 total) +void gf_set_progress(char *title, u64 done, u64 total) { if (prog_cbk) { prog_cbk(user_cbk, title, done, total); @@ -186,6 +740,54 @@ void gf_set_progress_callback(void *_user_cbk, gf_on_progress_cbk _prog_cbk) u32 global_log_level = 0; u32 global_log_tools = 0; +u32 gf_log_parse_level(const char *val) +{ +#ifndef GPAC_DISABLE_LOG + if (!stricmp(val, "error")) return GF_LOG_ERROR; + if (!stricmp(val, "warning")) return GF_LOG_WARNING; + if (!stricmp(val, "info")) return GF_LOG_INFO; + if (!stricmp(val, "debug")) return GF_LOG_DEBUG; +#endif + return 0; +} + +u32 gf_log_parse_tools(const char *val) +{ + u32 flags = 0; +#ifndef GPAC_DISABLE_LOG + char *sep; + while (val) { + sep = strchr(val, ':'); + if (sep) sep[0] = 0; + if (!stricmp(val, "core")) flags |= GF_LOG_CORE; + else if (!stricmp(val, "coding")) flags |= GF_LOG_CODING; + else if (!stricmp(val, "container")) flags |= GF_LOG_CONTAINER; + else if (!stricmp(val, "network")) flags |= GF_LOG_NETWORK; + else if (!stricmp(val, "rtp")) flags |= GF_LOG_RTP; + else if (!stricmp(val, "author")) flags |= GF_LOG_AUTHOR; + else if (!stricmp(val, "sync")) flags |= GF_LOG_SYNC; + else if (!stricmp(val, "codec")) flags |= GF_LOG_CODEC; + else if (!stricmp(val, "parser")) flags |= GF_LOG_PARSER; + else if (!stricmp(val, "media")) flags |= GF_LOG_MEDIA; + else if (!stricmp(val, "scene")) flags |= GF_LOG_SCENE; + else if (!stricmp(val, "script")) flags |= GF_LOG_SCRIPT; + else if (!stricmp(val, "interact")) flags |= GF_LOG_INTERACT; + else if (!stricmp(val, "smil")) flags |= GF_LOG_SMIL; + else if (!stricmp(val, "compose")) flags |= GF_LOG_COMPOSE; + else if (!stricmp(val, "mmio")) flags |= GF_LOG_MMIO; + else if (!stricmp(val, "none")) flags = 0; + else if (!stricmp(val, "all")) flags = 0xFFFFFFFF; + else if (!stricmp(val, "rti")) flags |= GF_LOG_RTI; + else if (!stricmp(val, "cache")) flags |= GF_LOG_CACHE; + else if (!stricmp(val, "audio")) flags |= GF_LOG_AUDIO; + else if (!stricmp(val, "mem")) flags |= GF_LOG_MEMORY; + if (!sep) break; + sep[0] = ':'; + val = sep+1; + } +#endif + return flags; +} #ifndef GPAC_DISABLE_LOG u32 call_lev = 0; @@ -432,3 +1034,129 @@ u32 gf_crc_32(char *data, u32 len) return crc; } +#define CHECK_MAC(_a) "#_a :" ? (_a) ? "yes":"no" + +GF_EXPORT +const char *gpac_features() +{ + const char *features = "" +#ifdef GPAC_FIXED_POINT + "GPAC_FIXED_POINT " +#endif +#ifdef GPAC_MEMORY_TRACKING + "GPAC_MEMORY_TRACKING " +#endif +#ifdef GPAC_BIG_ENDIAN + "GPAC_BIG_ENDIAN " +#endif +#ifdef GPAC_HAS_SSL + "GPAC_HAS_SSL " +#endif +#ifdef GPAC_HAS_SPIDERMONKEY + "GPAC_HAS_SPIDERMONKEY " +#endif +#ifdef GPAC_HAS_JPEG + "GPAC_HAS_JPEG " +#endif +#ifdef GPAC_HAS_PNG + "GPAC_HAS_PNG " +#endif +#ifdef GPAC_DISABLE_3D + "GPAC_DISABLE_3D " +#endif +#ifdef GPAC_USE_TINYGL + "GPAC_USE_TINYGL " +#endif +#ifdef GPAC_USE_OGL_ES + "GPAC_USE_OGL_ES " +#endif +#if defined(_WIN32_WCE) +#ifdef GPAC_USE_IGPP + "GPAC_USE_IGPP " +#endif +#ifdef GPAC_USE_IGPP_HP + "GPAC_USE_IGPP_HP " +#endif +#endif +#ifdef GPAC_DISABLE_SVG + "GPAC_DISABLE_SVG " +#endif +#ifdef GPAC_DISABLE_VRML + "GPAC_DISABLE_VRML " +#endif +#ifdef GPAC_MINIMAL_ODF + "GPAC_MINIMAL_ODF " +#endif +#ifdef GPAC_DISABLE_BIFS + "GPAC_DISABLE_BIFS " +#endif +#ifdef GPAC_DISABLE_QTVR + "GPAC_DISABLE_QTVR " +#endif +#ifdef GPAC_DISABLE_AVILIB + "GPAC_DISABLE_AVILIB " +#endif +#ifdef GPAC_DISABLE_OGG + "GPAC_DISABLE_OGG " +#endif +#ifdef GPAC_DISABLE_MPEG2PS + "GPAC_DISABLE_MPEG2PS " +#endif +#ifdef GPAC_DISABLE_MPEG2PS + "GPAC_DISABLE_MPEG2TS " +#endif +#ifdef GPAC_DISABLE_SENG + "GPAC_DISABLE_SENG " +#endif +#ifdef GPAC_DISABLE_MEDIA_IMPORT + "GPAC_DISABLE_MEDIA_IMPORT " +#endif +#ifdef GPAC_DISABLE_AV_PARSERS + "GPAC_DISABLE_AV_PARSERS " +#endif +#ifdef GPAC_DISABLE_MEDIA_EXPORT + "GPAC_DISABLE_MEDIA_EXPORT " +#endif +#ifdef GPAC_DISABLE_SWF_IMPORT + "GPAC_DISABLE_SWF_IMPORT " +#endif +#ifdef GPAC_DISABLE_SCENE_STATS + "GPAC_DISABLE_SCENE_STATS " +#endif +#ifdef GPAC_DISABLE_SCENE_DUMP + "GPAC_DISABLE_SCENE_DUMP " +#endif +#ifdef GPAC_DISABLE_SCENE_ENCODER + "GPAC_DISABLE_SCENE_ENCODER " +#endif +#ifdef GPAC_DISABLE_LOADER_ISOM + "GPAC_DISABLE_LOADER_ISOM " +#endif +#ifdef GPAC_DISABLE_OD_DUMP + "GPAC_DISABLE_OD_DUMP " +#endif +#ifdef GPAC_DISABLE_MCRYPT + "GPAC_DISABLE_MCRYPT " +#endif +#ifdef GPAC_DISABLE_ISOM + "GPAC_DISABLE_MCRYPT " +#endif +#ifdef GPAC_DISABLE_ISOM_HINTING + "GPAC_DISABLE_ISOM_HINTING " +#endif +#ifdef GPAC_DISABLE_ISOM_WRITE + "GPAC_DISABLE_ISOM_WRITE " +#endif +#ifdef GPAC_DISABLE_ISOM_FRAGMENTS + "GPAC_DISABLE_ISOM_FRAGMENTS " +#endif +#ifdef GPAC_DISABLE_LASER + "GPAC_DISABLE_LASER " +#endif +#ifdef GPAC_DISABLE_STREAMING + "GPAC_DISABLE_STREAMING " +#endif + + ; + return features; +} diff --git a/src/utils/gzio.cpp b/src/utils/gzio.cpp index 053f39f..3b71742 100644 --- a/src/utils/gzio.cpp +++ b/src/utils/gzio.cpp @@ -5,7 +5,7 @@ * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. */ -/* @(#) $Id: gzio.cpp,v 1.2 2007/05/23 15:51:18 jeanlf Exp $ */ +/* @(#) $Id: gzio.cpp,v 1.4 2010-02-23 16:24:20 jeanlf Exp $ */ #include <stdio.h> @@ -42,12 +42,12 @@ struct internal_state {int dummy;}; /* for buggy compilers */ #endif #ifndef STDC -//extern voidp malloc OF((uInt size)); +//extern voidp gf_malloc OF((uInt size)); //extern void free OF((voidpf ptr)); #endif -#define ALLOC(size) malloc(size) -#define TRYFREE(p) {if (p) free(p);} +#define ALLOC(size) gf_malloc(size) +#define TRYFREE(p) {if (p) gf_free(p);} static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ @@ -401,10 +401,7 @@ local int destroy (gz_stream *s) return err; } -/* =========================================================================== - Reads the given number of uncompressed bytes from the compressed file. - gzread returns the number of bytes actually read (0 for end of file). -*/ + GZ_EXPORT int gzread (gzFile file, voidp buf, unsigned len) { diff --git a/src/utils/list.c b/src/utils/list.c index c22cfb4..9043cab 100644 --- a/src/utils/list.c +++ b/src/utils/list.c @@ -35,7 +35,7 @@ single step memory array #define GF_LIST_ARRAY - multi-step memory array withou realloc on remove, using the GF_LIST_REALLOC macro + multi-step memory array withou gf_realloc on remove, using the GF_LIST_REALLOC macro GF_LIST_ARRAY_GROW */ @@ -46,8 +46,8 @@ #define GF_LIST_ARRAY_GROW #endif -//#define GF_LIST_REALLOC(a) (a ? (3*a/2) : 10) -#define GF_LIST_REALLOC(a) (a++) +#define GF_LIST_REALLOC(a) (a = a ? (3*a/2) : 10) +//#define GF_LIST_REALLOC(a) (a++) #if defined(GF_LIST_LINKED) @@ -71,7 +71,7 @@ struct _tag_array GF_EXPORT GF_List * gf_list_new() { - GF_List *nlist = (GF_List *) malloc(sizeof(GF_List)); + GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List)); if (! nlist) return NULL; nlist->head = nlist->foundEntry = NULL; nlist->tail = NULL; @@ -85,7 +85,7 @@ void gf_list_del(GF_List *ptr) { if (!ptr) return; while (ptr->entryCount) gf_list_rem(ptr, 0); - free(ptr); + gf_free(ptr); } GF_EXPORT @@ -99,7 +99,7 @@ GF_Err gf_list_add(GF_List *ptr, void* item) { ItemSlot *entry; if (! ptr) return GF_BAD_PARAM; - entry = (ItemSlot *) malloc(sizeof(ItemSlot)); + entry = (ItemSlot *) gf_malloc(sizeof(ItemSlot)); if (!entry) return GF_OUT_OF_MEM; entry->data = item; entry->next = NULL; @@ -171,7 +171,7 @@ GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber) ptr->entryCount --; ptr->foundEntry = ptr->head; ptr->foundEntryNumber = 0; - free(tmp); + gf_free(tmp); /*that was the last entry, reset the tail*/ if (!ptr->entryCount) { ptr->tail = ptr->head = ptr->foundEntry = NULL; @@ -194,7 +194,7 @@ GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber) tmp->next = NULL; } - free(tmp2); + gf_free(tmp2); ptr->entryCount --; ptr->foundEntry = ptr->head; ptr->foundEntryNumber = 0; @@ -218,7 +218,7 @@ GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position) /*if last entry or first of an empty array...*/ if (position >= ptr->entryCount) return gf_list_add(ptr, item); - tmp2 = (ItemSlot *) malloc(sizeof(ItemSlot)); + tmp2 = (ItemSlot *) gf_malloc(sizeof(ItemSlot)); tmp2->data = item; tmp2->next = NULL; /*special case for the head*/ @@ -267,7 +267,7 @@ struct _tag_array GF_EXPORT GF_List * gf_list_new() { - GF_List *nlist = (GF_List *) malloc(sizeof(GF_List)); + GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List)); if (! nlist) return NULL; nlist->head = nlist->foundEntry = NULL; nlist->tail = NULL; @@ -283,7 +283,7 @@ void gf_list_del(GF_List *ptr) while (ptr->entryCount) { gf_list_rem(ptr, 0); } - free(ptr); + gf_free(ptr); } GF_EXPORT @@ -297,7 +297,7 @@ GF_Err gf_list_add(GF_List *ptr, void* item) { ItemSlot *entry; if (! ptr) return GF_BAD_PARAM; - entry = (ItemSlot *) malloc(sizeof(ItemSlot)); + entry = (ItemSlot *) gf_malloc(sizeof(ItemSlot)); if (!entry) return GF_OUT_OF_MEM; entry->data = item; entry->next = entry->prev = NULL; @@ -378,7 +378,7 @@ GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber) ptr->entryCount --; ptr->foundEntry = ptr->head; ptr->foundEntryNumber = 0; - free(tmp); + gf_free(tmp); /*that was the last entry, reset the tail*/ if (!ptr->entryCount) { @@ -398,7 +398,7 @@ GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber) ptr->foundEntry = ptr->tail; ptr->foundEntryNumber = ptr->entryCount-1; } - free(tmp); + gf_free(tmp); return GF_OK; } @@ -415,7 +415,7 @@ GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber) tmp->prev->next = tmp->next; tmp->next->prev = tmp->prev; if (tmp==ptr->foundEntry) ptr->foundEntry = tmp->next; - free(tmp); + gf_free(tmp); ptr->entryCount--; return GF_OK; } @@ -435,7 +435,7 @@ GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position) if (!ptr || !item) return GF_BAD_PARAM; /*if last entry or first of an empty array...*/ if (position >= ptr->entryCount) return gf_list_add(ptr, item); - tmp2 = (ItemSlot *) malloc(sizeof(ItemSlot)); + tmp2 = (ItemSlot *) gf_malloc(sizeof(ItemSlot)); tmp2->data = item; tmp2->next = tmp2->prev = NULL; /*special case for the head*/ @@ -482,7 +482,7 @@ struct _tag_array GF_EXPORT GF_List * gf_list_new() { - GF_List *nlist = (GF_List *) malloc(sizeof(GF_List)); + GF_List *nlist = (GF_List *) gf_malloc(sizeof(GF_List)); if (! nlist) return NULL; nlist->slots = NULL; nlist->entryCount = 0; @@ -493,8 +493,8 @@ GF_EXPORT void gf_list_del(GF_List *ptr) { if (!ptr) return; - free(ptr->slots); - free(ptr); + gf_free(ptr->slots); + gf_free(ptr); } GF_EXPORT @@ -503,7 +503,7 @@ GF_Err gf_list_add(GF_List *ptr, void* item) if (! ptr) return GF_BAD_PARAM; ptr->entryCount ++; - ptr->slots = (void **) realloc(ptr->slots, ptr->entryCount*sizeof(void*)); + ptr->slots = (void **) gf_realloc(ptr->slots, ptr->entryCount*sizeof(void*)); if (!ptr->slots) { ptr->entryCount = 0; return GF_OUT_OF_MEM; @@ -543,7 +543,7 @@ GF_Err gf_list_rem(GF_List *ptr, u32 itemNumber) if (i) memmove(&ptr->slots[itemNumber], & ptr->slots[itemNumber +1], sizeof(void *)*i); ptr->slots[ptr->entryCount-1] = NULL; ptr->entryCount -= 1; - ptr->slots = (void **) realloc(ptr->slots, sizeof(void*)*ptr->entryCount); + ptr->slots = (void **) gf_realloc(ptr->slots, sizeof(void*)*ptr->entryCount); return GF_OK; } @@ -552,7 +552,7 @@ GF_Err gf_list_rem_last(GF_List *ptr) { if ( !ptr || !ptr->slots || !ptr->entryCount) return GF_BAD_PARAM; ptr->entryCount -= 1; - ptr->slots = (void **) realloc(ptr->slots, sizeof(void*)*ptr->entryCount); + ptr->slots = (void **) gf_realloc(ptr->slots, sizeof(void*)*ptr->entryCount); return GF_OK; } @@ -565,7 +565,7 @@ GF_Err gf_list_insert(GF_List *ptr, void *item, u32 position) if (!ptr || !item) return GF_BAD_PARAM; /*if last entry or first of an empty array...*/ if (position >= ptr->entryCount) return gf_list_add(ptr, item); - ptr->slots = (void **) realloc(ptr->slots, (ptr->entryCount+1)*sizeof(void*)); + ptr->slots = (void **) gf_realloc(ptr->slots, (ptr->entryCount+1)*sizeof(void*)); i = ptr->entryCount - position; memmove(&ptr->slots[position + 1], &ptr->slots[position], sizeof(void *)*i); ptr->entryCount++; @@ -578,7 +578,7 @@ void gf_list_reset(GF_List *ptr) { if (ptr) { ptr->entryCount = 0; - free(ptr->slots); + gf_free(ptr->slots); ptr->slots = NULL; } } @@ -598,7 +598,7 @@ GF_List * gf_list_new() { GF_List *nlist; - nlist = (GF_List *) malloc(sizeof(GF_List)); + nlist = (GF_List *) gf_malloc(sizeof(GF_List)); if (! nlist) return NULL; nlist->slots = NULL; @@ -611,14 +611,14 @@ GF_EXPORT void gf_list_del(GF_List *ptr) { if (!ptr) return; - free(ptr->slots); - free(ptr); + gf_free(ptr->slots); + gf_free(ptr); } static void realloc_chain(GF_List *ptr) { GF_LIST_REALLOC(ptr->allocSize); - ptr->slots = realloc(ptr->slots, ptr->allocSize*sizeof(void*)); + ptr->slots = gf_realloc(ptr->slots, ptr->allocSize*sizeof(void*)); } GF_EXPORT diff --git a/src/utils/math.c b/src/utils/math.c index baf05e9..d48f418 100644 --- a/src/utils/math.c +++ b/src/utils/math.c @@ -885,6 +885,7 @@ void gf_mx2d_apply_point(GF_Matrix2D *_this, GF_Point2D *pt) GF_EXPORT void gf_mx2d_apply_rect(GF_Matrix2D *_this, GF_Rect *rc) { + GF_Point2D c1, c2, c3, c4; c1.x = c2.x = rc->x; c3.x = c4.x = rc->x + rc->width; diff --git a/src/utils/module.c b/src/utils/module.c index ddb5648..90ede8f 100644 --- a/src/utils/module.c +++ b/src/utils/module.c @@ -10,20 +10,21 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include "module_wrap.h" #include <gpac/config_file.h> +#include <gpac/tools.h> GF_EXPORT GF_ModuleManager *gf_modules_new(const char *directory, GF_Config *config) @@ -40,7 +41,7 @@ GF_ModuleManager *gf_modules_new(const char *directory, GF_Config *config) tmp->plug_list = gf_list_new(); if (!tmp->plug_list) { - free(tmp); + gf_free(tmp); return NULL; } tmp->cfg = config; @@ -60,15 +61,15 @@ void gf_modules_del(GF_ModuleManager *pm) gf_list_rem(pm->plug_list, 0); } gf_list_del(pm->plug_list); - free(pm); + gf_free(pm); } -Bool gf_module_is_loaded(GF_ModuleManager *pm, char *filename) +Bool gf_module_is_loaded(GF_ModuleManager *pm, char *filename) { u32 i = 0; ModuleInstance *inst; while ( (inst = (ModuleInstance *) gf_list_enum(pm->plug_list, &i) ) ) { - if (!strcmp(inst->szName, filename)) return 1; + if (!strcmp(inst->name, filename)) return 1; } return 0; } @@ -84,13 +85,61 @@ u32 gf_modules_get_count(GF_ModuleManager *pm) GF_EXPORT GF_BaseInterface *gf_modules_load_interface(GF_ModuleManager *pm, u32 whichplug, u32 InterfaceFamily) { + const char *opt; + char szKey[10]; ModuleInstance *inst; GF_BaseInterface *ifce; if (!pm) return NULL; inst = (ModuleInstance *) gf_list_get(pm->plug_list, whichplug); if (!inst) return NULL; - if (!gf_modules_load_library(inst)) return NULL; + + /*look in cache*/ + opt = gf_cfg_get_key(pm->cfg, "PluginsCache", inst->name); + if (opt) { + sprintf(szKey, "%s:yes", gf_4cc_to_str(InterfaceFamily)); + if (!strstr(opt, szKey)) return NULL; + } + + if (!gf_modules_load_library(inst)) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load library %s\n", inst->name)); + gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "Invalid Plugin"); + return NULL; + } + + if (!inst->query_func) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Library %s missing GPAC export symbols\n", inst->name)); + gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "Invalid Plugin"); + goto err_exit; + } + + /*build cache*/ + if (!opt) { + u32 i; + Bool found = 0; + char *key; + const u32 *si = inst->query_func(); + if (!si) { + GF_LOG(GF_LOG_WARNING, GF_LOG_CORE, ("[Core] GPAC module %s has no supported interfaces - disabling\n", inst->name)); + gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, "Invalid Plugin"); + goto err_exit; + } + i=0; + while (si[i]) i++; + + key = gf_malloc(sizeof(char) * 10 * i); + key[0] = 0; + i=0; + while (si[i]) { + sprintf(szKey, "%s:yes ", gf_4cc_to_str(si[i])); + strcat(key, szKey); + if (InterfaceFamily==si[i]) found = 1; + i++; + } + gf_cfg_set_key(pm->cfg, "PluginsCache", inst->name, key); + gf_free(key); + if (!found) goto err_exit; + } if (!inst->query_func || !inst->query_func(InterfaceFamily) ) goto err_exit; @@ -103,15 +152,13 @@ GF_BaseInterface *gf_modules_load_interface(GF_ModuleManager *pm, u32 whichplug, goto err_exit; } gf_list_add(inst->interfaces, ifce); + /*keep track of parent*/ ifce->HPLUG = inst; return ifce; err_exit: - /*this slows down loading of GPAC on CE-based devices*/ -#ifndef _WIN32_WCE gf_modules_unload_library(inst); -#endif return NULL; } @@ -119,16 +166,31 @@ err_exit: GF_EXPORT GF_BaseInterface *gf_modules_load_interface_by_name(GF_ModuleManager *pm, const char *plug_name, u32 InterfaceFamily) { + const char *file_name; u32 i, count; GF_BaseInterface *ifce; count = gf_list_count(pm->plug_list); + + /*look for cache entry*/ + file_name = gf_cfg_get_key(pm->cfg, "PluginsCache", plug_name); + if (file_name) { + for (i=0; i<count; i++) { + ModuleInstance *inst = (ModuleInstance *) gf_list_get(pm->plug_list, i); + if (!strcmp(inst->name, file_name)) { + ifce = gf_modules_load_interface(pm, i, InterfaceFamily); + if (ifce) return ifce; + } + } + } + for (i=0; i<count; i++) { ifce = gf_modules_load_interface(pm, i, InterfaceFamily); if (!ifce) continue; - /*check by driver name*/ - if (ifce->module_name && !stricmp(ifce->module_name, plug_name)) return ifce; - /*check by file name*/ - if (!stricmp(((ModuleInstance *)ifce->HPLUG)->szName, plug_name)) return ifce; + if (ifce->module_name && !stricmp(ifce->module_name, plug_name)) { + /*update cache entry*/ + gf_cfg_set_key(pm->cfg, "PluginsCache", plug_name, ((ModuleInstance*)ifce->HPLUG)->name); + return ifce; + } gf_modules_close_interface(ifce); } return NULL; @@ -138,7 +200,7 @@ GF_EXPORT GF_Err gf_modules_close_interface(GF_BaseInterface *ifce) { ModuleInstance *par; - u32 i; + s32 i; if (!ifce) return GF_BAD_PARAM; par = (ModuleInstance *) ifce->HPLUG; @@ -188,6 +250,14 @@ const char *gf_modules_get_file_name(GF_ModuleManager *pm, u32 i) { ModuleInstance *inst = (ModuleInstance *) gf_list_get(pm->plug_list, i); if (!inst) return NULL; - return inst->szName; + return inst->name; +} + +GF_EXPORT +const char *gf_module_get_file_name(GF_BaseInterface *ifce) +{ + ModuleInstance *inst = (ModuleInstance *) ifce->HPLUG; + if (!inst) return NULL; + return inst->name; } diff --git a/src/utils/module_wrap.h b/src/utils/module_wrap.h index 01f19df..e9218ac 100644 --- a/src/utils/module_wrap.h +++ b/src/utils/module_wrap.h @@ -29,7 +29,7 @@ #define _GF_MODULE_WRAP_H_ /* interface api*/ -typedef Bool (*QueryInterface) (u32 InterfaceType); +typedef const u32 *(*QueryInterfaces) (); typedef void * (*LoadInterface) (u32 InterfaceType); typedef void (*ShutdownInterface) (void *interface_obj); @@ -37,12 +37,12 @@ typedef void (*ShutdownInterface) (void *interface_obj); typedef struct { struct __tag_mod_man *plugman; - char szName[GF_MAX_PATH]; + char *name; GF_List *interfaces; /*library is loaded only when an interface is attached*/ void *lib_handle; - QueryInterface query_func; + QueryInterfaces query_func; LoadInterface load_func; ShutdownInterface destroy_func; } ModuleInstance; diff --git a/src/utils/os_divers.c b/src/utils/os_divers.c index 167fbdc..8635dce 100644 --- a/src/utils/os_divers.c +++ b/src/utils/os_divers.c @@ -26,6 +26,7 @@ #if defined(_WIN32_WCE) +#include <winbase.h> #include <winsock.h> #include <tlhelp32.h> @@ -153,7 +154,7 @@ s32 gettimeofday(struct timeval *tp, void *tz) struct _timeb timebuffer; _ftime( &timebuffer ); - tp->tv_sec = timebuffer.time; + tp->tv_sec = (long) (timebuffer.time); tp->tv_usec = timebuffer.millitm * 1000; return 0; } @@ -190,6 +191,7 @@ void CE_CharToWide(char *str, unsigned short *w_str) void gf_delete_file(char *fileName) { + #if defined(_WIN32_WCE) TCHAR swzName[MAX_PATH]; CE_CharToWide(fileName, swzName); @@ -201,7 +203,20 @@ void gf_delete_file(char *fileName) #endif } - +void gf_move_file(char *fileName, char *newFileName) +{ +#if defined(_WIN32_WCE) + TCHAR swzName[MAX_PATH]; + TCHAR swzNewName[MAX_PATH]; + CE_CharToWide(fileName, swzName); + CE_CharToWide(newFileName, swzNewName); + MoveFile(swzName, swzNewName); +#elif defined(WIN32) + MoveFile(fileName, newFileName); +#else + rename(fileName, newFileName); +#endif +} void gf_rand_init(Bool Reset) { @@ -221,8 +236,38 @@ u32 gf_rand() return rand(); } +#ifndef _WIN32_WCE +#include <sys/stat.h> +#endif + +u64 gf_file_modification_time(const char *filename) +{ +#if defined(_WIN32_WCE) + WCHAR _file[GF_MAX_PATH]; + WIN32_FIND_DATA FindData; + HANDLE fh; + ULARGE_INTEGER uli; + ULONGLONG time_ms; + CE_CharToWide((char *) filename, _file); + fh = FindFirstFile(_file, &FindData); + if (fh == INVALID_HANDLE_VALUE) return 0; + uli.LowPart = FindData.ftLastWriteTime.dwLowDateTime; + uli.HighPart = FindData.ftLastWriteTime.dwHighDateTime; + FindClose(fh); + time_ms = uli.QuadPart/10000; + return time_ms; +#elif defined(WIN32) && !defined(__GNUC__) + struct _stat64 sb; + if (_stat64(filename, &sb) != 0) return 0; + return sb.st_mtime; +#else + struct stat sb; + if (stat(filename, &sb) != 0) return 0; + return sb.st_mtime; +#endif + return 0; +} -#ifndef GPAC_READ_ONLY FILE *gf_temp_file_new() { #if defined(_WIN32_WCE) @@ -244,12 +289,11 @@ FILE *gf_temp_file_new() if (!GetEnvironmentVariable("TEMP",tmp,MAX_PATH)) return NULL; sprintf(t_file, "\\gpac_%08x.tmp", (u32) tmp); strcat(tmp, t_file); - return fopen(tmp, "w+b"); + return gf_f64_open(tmp, "w+b"); #else return tmpfile(); #endif } -#endif void gf_utc_time_since_1970(u32 *sec, u32 *msec) @@ -257,7 +301,7 @@ void gf_utc_time_since_1970(u32 *sec, u32 *msec) #if defined (WIN32) && !defined(_WIN32_WCE) struct _timeb tb; _ftime( &tb ); - *sec = tb.time; + *sec = (u32) tb.time; *msec = tb.millitm; #else struct timeval tv; @@ -315,19 +359,68 @@ GF_Err gf_enum_directory(const char *dir, Bool enum_directory, gf_enum_dir_item #endif if (!dir || !enum_dir_fct) return GF_BAD_PARAM; + + if (filter && (!strcmp(filter, "*") || !filter[0])) filter=NULL; + + if (!strcmp(dir, "/")) { +#if defined(WIN32) && !defined(_WIN32_WCE) + u32 len; + char *drives, *volume; + len = GetLogicalDriveStrings(0, NULL); + drives = gf_malloc(sizeof(char)*(len+1)); + drives[0]=0; + GetLogicalDriveStrings(len, drives); + len = strlen(drives); + volume = drives; + while (len) { + enum_dir_fct(cbck, volume, ""); + volume += len+1; + len = strlen(volume); + } + gf_free(drives); + return GF_OK; +#elif defined(__SYMBIAN32__) + RFs iFs; + TDriveList aList; + iFs.Connect(); + iFs.DriveList(aList); + for (TInt i=0;i<KMaxDrives;i++) { + if (aList[i]) { + char szDrive[10]; + TChar aDrive; + iFs.DriveToChar(i, aDrive); + sprintf(szDrive, "%c:", (TUint)aDrive); + enum_dir_fct(cbck, szDrive, ""); + } + } + iFs.Close(); + FlushItemList(); + return GF_OK; +#endif + } + + #if defined (_WIN32_WCE) - if (dir[strlen(dir) - 1] == GF_PATH_SEPARATOR) { + switch (dir[strlen(dir) - 1]) { + case '/': + case '\\': sprintf(_path, "%s*", dir); - } else { + break; + default: sprintf(_path, "%s%c*", dir, GF_PATH_SEPARATOR); + break; } CE_CharToWide(_path, path); CE_CharToWide((char *)filter, w_filter); #elif defined(WIN32) - if (dir[strlen(dir) - 1] == GF_PATH_SEPARATOR) { + switch (dir[strlen(dir) - 1]) { + case '/': + case '\\': sprintf(path, "%s*", dir); - } else { + break; + default: sprintf(path, "%s%c*", dir, GF_PATH_SEPARATOR); + break; } #else strcpy(path, dir); @@ -464,16 +557,14 @@ u64 gf_f64_tell(FILE *fp) { #if defined(_WIN32_WCE) return (u64) ftell(fp); +#elif defined(GPAC_CONFIG_WIN32) //mingw or cygwin + return (u64) ftell(fp); #elif defined(WIN32) - fpos_t pos; - if (fgetpos(fp, &pos)) - return (u64) -1; - else - return ((u64) pos); -#elif defined(GPAC_CONFIG_LINUX) + return (u64) _ftelli64(fp); +#elif defined(GPAC_CONFIG_LINUX) && !defined(ANDROID) return (u64) ftello64(fp); #elif (defined(GPAC_CONFIG_FREEBSD) || defined(GPAC_CONFIG_DARWIN)) - return (u64) ftell(fp); + return (u64) ftello(fp); #else return (u64) ftell(fp); #endif @@ -483,21 +574,14 @@ u64 gf_f64_seek(FILE *fp, s64 offset, s32 whence) { #if defined(_WIN32_WCE) return (u64) fseek(fp, (s32) offset, whence); +#elif defined(GPAC_CONFIG_WIN32) //mingw or cygwin + return (u64) fseek(fp, (s32) offset, whence); #elif defined(WIN32) - fpos_t pos; - if (whence == SEEK_CUR) { - fgetpos(fp, &pos); - pos += (fpos_t) offset; - } - else if (whence == SEEK_END) - pos = (fpos_t) (_filelengthi64(fileno(fp)) + offset); - else if (whence == SEEK_SET) - pos = (fpos_t) offset; - return fsetpos(fp, &pos); -#elif defined(GPAC_CONFIG_LINUX) + return (u64) _fseeki64(fp, offset, whence); +#elif defined(GPAC_CONFIG_LINUX) && !defined(ANDROID) return fseeko64(fp, (off64_t) offset, whence); #elif (defined(GPAC_CONFIG_FREEBSD) || defined(GPAC_CONFIG_DARWIN)) - return fseek(fp, offset, whence); + return fseeko(fp, (off_t) offset, whence); #else return fseek(fp, (s32) offset, whence); #endif @@ -507,7 +591,7 @@ FILE *gf_f64_open(const char *file_name, const char *mode) { #if defined(WIN32) return fopen(file_name, mode); -#elif defined(GPAC_CONFIG_LINUX) +#elif defined(GPAC_CONFIG_LINUX) && !defined(ANDROID) return fopen64(file_name, mode); #elif (defined(GPAC_CONFIG_FREEBSD) || defined(GPAC_CONFIG_DARWIN)) return fopen(file_name, mode); @@ -613,7 +697,8 @@ char gf_prompt_get_char() close_keyboard(1); return ch; } - read(0,&ch,1); + if (0==read(0,&ch,1)) + ch = 0; close_keyboard(1); return ch; } @@ -699,7 +784,8 @@ u32 gf_sys_clock() #endif -#if defined(_WIN32_WCE) +#ifdef WIN32 + static u32 OS_GetSysClockHIGHRES() { LARGE_INTEGER now; @@ -708,31 +794,84 @@ static u32 OS_GetSysClockHIGHRES() return (u32) ((now.QuadPart * 1000) / frequency.QuadPart); } -static u32 OS_GetSysClockNORMAL() { return GetTickCount(); } +static u32 OS_GetSysClockNORMAL() +{ +#ifdef _WIN32_WCE + return GetTickCount(); +#else + return timeGetTime(); +#endif +} + +#endif //WIN32 -#elif defined(WIN32) +#if defined(__sh__) +/* Avoid exception for denormalized floating point values */ +static int +sh4_get_fpscr() +{ + int ret; + asm volatile ("sts fpscr,%0" : "=r" (ret)); + return ret; +} -static u32 OS_GetSysClockHIGHRES() +static void +sh4_put_fpscr(int nv) { - LARGE_INTEGER now; - QueryPerformanceCounter(&now); - now.QuadPart -= init_counter.QuadPart; - return (u32) (now.QuadPart * 1000 / frequency.QuadPart); + asm volatile ("lds %0,fpscr" : : "r" (nv)); } -u32 OS_GetSysClockNORMAL() { return timeGetTime(); } +#define SH4_FPSCR_FR 0x00200000 +#define SH4_FPSCR_SZ 0x00100000 +#define SH4_FPSCR_PR 0x00080000 +#define SH4_FPSCR_DN 0x00040000 +#define SH4_FPSCR_RN 0x00000003 +#define SH4_FPSCR_RN_N 0 +#define SH4_FPSCR_RN_Z 1 -#endif +extern int __fpscr_values[2]; + +void +sh4_change_fpscr(int off, int on) +{ + int b = sh4_get_fpscr(); + off = ~off; + off |= 0x00180000; + on &= ~ 0x00180000; + b &= off; + b |= on; + sh4_put_fpscr(b); + __fpscr_values[0] &= off; + __fpscr_values[0] |= on; + __fpscr_values[1] &= off; + __fpscr_values[1] |= on; +} +#endif -void gf_sys_init() +#ifdef GPAC_MEMORY_TRACKING +void gf_mem_enable_tracker(); +#endif + +void gf_sys_init(Bool enable_memory_tracker) { if (!sys_init) { -#if defined(WIN32) - #if defined(_WIN32_WCE) MEMORYSTATUS ms; #endif + + if (enable_memory_tracker) { +#ifdef GPAC_MEMORY_TRACKING + gf_mem_enable_tracker(); +#endif + } + +#if defined(__sh__) + /* Round all denormalized floatting point number to 0.0 */ + sh4_change_fpscr(0,SH4_FPSCR_DN) ; +#endif + +#if defined(WIN32) frequency.QuadPart = 0; /*clock setup*/ if (QueryPerformanceFrequency(&frequency)) { @@ -740,13 +879,14 @@ void gf_sys_init() OS_GetSysClock = OS_GetSysClockHIGHRES; GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[core] using WIN32 performance timer\n")); } else { -#ifndef _WIN32_WCE - timeBeginPeriod(1); -#endif OS_GetSysClock = OS_GetSysClockNORMAL; GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[core] using WIN32 regular timer\n")); } +#ifndef _WIN32_WCE + timeBeginPeriod(1); +#endif + GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[core] checking for run-time info tools")); #if defined(_WIN32_WCE) last_total_k_u_time = last_process_k_u_time = 0; @@ -805,7 +945,7 @@ void gf_sys_close() last_update_time = 0xFFFFFFFF; #if defined(WIN32) && !defined(_WIN32_WCE) - if (!frequency.QuadPart) timeEndPeriod(1); + timeEndPeriod(1); MyGetSystemTimes = NULL; MyGetProcessMemoryInfo = NULL; @@ -816,8 +956,10 @@ void gf_sys_close() } } +#ifdef GPAC_MEMORY_TRACKING extern size_t gpac_allocated_memory; extern size_t gpac_nb_alloc_blocs; +#endif /*CPU and Memory Usage*/ @@ -854,7 +996,9 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) GlobalMemoryStatus(&ms); rti->physical_memory = ms.dwTotalPhys; rti->physical_memory_avail = ms.dwAvailPhys; +#ifdef GPAC_MEMORY_TRACKING rti->gpac_memory = (u64) gpac_allocated_memory; +#endif return 1; } @@ -1047,7 +1191,9 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) GlobalMemoryStatus(&ms); the_rti.physical_memory = ms.dwTotalPhys; +#ifdef GPAC_MEMORY_TRACKING the_rti.gpac_memory = (u64) gpac_allocated_memory; +#endif the_rti.physical_memory_avail = ms.dwAvailPhys; #if defined(_WIN32_WCE) @@ -1087,7 +1233,7 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) } u_k_time = idle_time = 0; - f = fopen("/proc/stat", "r"); + f = gf_f64_open("/proc/stat", "r"); if (f) { u32 k_time, nice_time, u_time; if (fgets(line, 128, f) != NULL) { @@ -1105,7 +1251,7 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) the complete CPU usage of all therads of the process...*/ #if 0 sprintf(szProc, "/proc/%d/stat", the_rti.pid); - f = fopen(szProc, "r"); + f = gf_f64_open(szProc, "r"); if (f) { fflush(f); if (fgets(line, 2048, f) != NULL) { @@ -1142,11 +1288,11 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[RTI] cannot open %s\n", szProc)); } sprintf(szProc, "/proc/%d/status", the_rti.pid); - f = fopen(szProc, "r"); + f = gf_f64_open(szProc, "r"); if (f) { while (fgets(line, 1024, f) != NULL) { if (!strnicmp(line, "VmSize:", 7)) { - sscanf(line, "VmSize: %lld kB", &the_rti.process_memory); + sscanf(line, "VmSize: %"LLD" kB", &the_rti.process_memory); the_rti.process_memory *= 1024; } } @@ -1158,14 +1304,14 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) the_rti.physical_memory = the_rti.physical_memory_avail = 0; - f = fopen("/proc/meminfo", "r"); + f = gf_f64_open("/proc/meminfo", "r"); if (f) { while (fgets(line, 1024, f) != NULL) { if (!strnicmp(line, "MemTotal:", 9)) { - sscanf(line, "MemTotal: %lld kB", &the_rti.physical_memory); + sscanf(line, "MemTotal: %"LLD" kB", &the_rti.physical_memory); the_rti.physical_memory *= 1024; }else if (!strnicmp(line, "MemFree:", 8)) { - sscanf(line, "MemFree: %lld kB", &the_rti.physical_memory_avail); + sscanf(line, "MemFree: %"LLD" kB", &the_rti.physical_memory_avail); the_rti.physical_memory_avail *= 1024; break; } @@ -1213,7 +1359,9 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) mem_at_startup = the_rti.physical_memory_avail; } the_rti.process_memory = mem_at_startup - the_rti.physical_memory_avail; +#ifdef GPAC_MEMORY_TRACKING the_rti.gpac_memory = gpac_allocated_memory; +#endif last_process_k_u_time = process_u_k_time; last_cpu_idle_time = idle_time; @@ -1226,14 +1374,24 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) #endif -Bool gf_sys_get_battery_state(Bool *onBattery, u32 *onCharge, u32*level) +Bool gf_sys_get_battery_state(Bool *onBattery, u32 *onCharge, u32*level, u32 *batteryLifeTime, u32 *batteryFullLifeTime) { -#if defined(WIN32) && !defined(_WIN32_WCE) +#if defined(_WIN32_WCE) + SYSTEM_POWER_STATUS_EX sps; + GetSystemPowerStatusEx(&sps, 0); + if (onBattery) *onBattery = sps.ACLineStatus ? 0 : 1; + if (onCharge) *onCharge = (sps.BatteryFlag & BATTERY_FLAG_CHARGING) ? 1 : 0; + if (level) *level = sps.BatteryLifePercent; + if (batteryLifeTime) *batteryLifeTime = sps.BatteryLifeTime; + if (batteryFullLifeTime) *batteryFullLifeTime = sps.BatteryFullLifeTime; +#elif defined(WIN32) SYSTEM_POWER_STATUS sps; GetSystemPowerStatus(&sps); - if (onBattery) *onBattery = sps.ACLineStatus; + if (onBattery) *onBattery = sps.ACLineStatus ? 0 : 1; if (onCharge) *onCharge = (sps.BatteryFlag & BATTERY_FLAG_CHARGING) ? 1 : 0; if (level) *level = sps.BatteryLifePercent; + if (batteryLifeTime) *batteryLifeTime = sps.BatteryLifeTime; + if (batteryFullLifeTime) *batteryFullLifeTime = sps.BatteryFullLifeTime; #endif return 1; } diff --git a/src/utils/os_module.c b/src/utils/os_module.c index de8d9bd..b919cf9 100644 --- a/src/utils/os_module.c +++ b/src/utils/os_module.c @@ -49,48 +49,55 @@ void gf_modules_free_module(ModuleInstance *inst) if (inst->lib_handle) dlclose(inst->lib_handle); #endif gf_list_del(inst->interfaces); - free(inst); + gf_free(inst->name); + gf_free(inst); } Bool gf_modules_load_library(ModuleInstance *inst) { +#ifdef WIN32 + DWORD res; + #ifdef _WIN32_WCE char s_path[GF_MAX_PATH]; unsigned short path[GF_MAX_PATH]; #else char path[GF_MAX_PATH]; -#ifndef WIN32 - s32 _flags; #endif +#else + char path[GF_MAX_PATH]; + s32 _flags; #endif if (inst->lib_handle) return 1; + GF_LOG(GF_LOG_INFO, GF_LOG_CORE, ("[Core] Load module file %s\n", inst->name)); #ifdef _WIN32_WCE - sprintf(s_path, "%s%c%s", inst->plugman->dir, GF_PATH_SEPARATOR, inst->szName); + sprintf(s_path, "%s%c%s", inst->plugman->dir, GF_PATH_SEPARATOR, inst->name); CE_CharToWide(s_path, path); #else - sprintf(path, "%s%c%s", inst->plugman->dir, GF_PATH_SEPARATOR, inst->szName); + sprintf(path, "%s%c%s", inst->plugman->dir, GF_PATH_SEPARATOR, inst->name); #endif #ifdef WIN32 inst->lib_handle = LoadLibrary(path); if (!inst->lib_handle) { + res = GetLastError(); #ifdef _WIN32_WCE - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s\n", s_path)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s: error %d\n", s_path, res)); #else - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s\n", path)); + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s: error %d\n", path, res)); #endif return 0; } #if defined(_WIN32_WCE) - inst->query_func = (QueryInterface) GetProcAddress(inst->lib_handle, _T("QueryInterface")); + inst->query_func = (QueryInterfaces) GetProcAddress(inst->lib_handle, _T("QueryInterfaces")); inst->load_func = (LoadInterface) GetProcAddress(inst->lib_handle, _T("LoadInterface")); inst->destroy_func = (ShutdownInterface) GetProcAddress(inst->lib_handle, _T("ShutdownInterface")); #else - inst->query_func = (QueryInterface) GetProcAddress(inst->lib_handle, "QueryInterface"); + inst->query_func = (QueryInterfaces) GetProcAddress(inst->lib_handle, "QueryInterfaces"); inst->load_func = (LoadInterface) GetProcAddress(inst->lib_handle, "LoadInterface"); inst->destroy_func = (ShutdownInterface) GetProcAddress(inst->lib_handle, "ShutdownInterface"); #endif @@ -107,7 +114,7 @@ Bool gf_modules_load_library(ModuleInstance *inst) GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s, error is %s\n", path, dlerror())); return 0; } - inst->query_func = (QueryInterface) dlsym(inst->lib_handle, "QueryInterface"); + inst->query_func = (QueryInterfaces) dlsym(inst->lib_handle, "QueryInterfaces"); inst->load_func = (LoadInterface) dlsym(inst->lib_handle, "LoadInterface"); inst->destroy_func = (ShutdownInterface) dlsym(inst->lib_handle, "ShutdownInterface"); #endif @@ -155,7 +162,10 @@ Bool enum_modules(void *cbck, char *item_name, char *item_path) #ifdef WIN32 ModuleLib = LoadLibrary(item_path); - if (!ModuleLib) return 0; + if (!ModuleLib) { + GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[Core] Cannot load module file %s\n", item_name)); + return 0; + } #ifdef _WIN32_WCE query_func = (QueryInterface) GetProcAddress(ModuleLib, _T("QueryInterface")); @@ -192,7 +202,7 @@ Bool enum_modules(void *cbck, char *item_name, char *item_path) GF_SAFEALLOC(inst, ModuleInstance); inst->interfaces = gf_list_new(); inst->plugman = pm; - strcpy(inst->szName, item_name); + inst->name = gf_strdup(item_name); gf_list_add(pm->plug_list, inst); return 0; } diff --git a/src/utils/os_net.c b/src/utils/os_net.c index d8ce560..96aa0e6 100644 --- a/src/utils/os_net.c +++ b/src/utils/os_net.c @@ -10,15 +10,15 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ @@ -48,7 +48,7 @@ #if !defined(__GNUC__) -#if defined(IPV6_MULTICAST_IF___dis) +#if defined(IPV6_MULTICAST_IF) #define GPAC_HAS_IPV6 1 #pragma message("Using WinSock IPV6") #else @@ -72,8 +72,10 @@ /*the number of sockets used. This because the WinSock lib needs init*/ static int wsa_init = 0; + #include <gpac/network.h> + /*end-win32*/ #else @@ -81,7 +83,7 @@ static int wsa_init = 0; #include <unistd.h> #include <fcntl.h> #include <netdb.h> - + #ifndef __BEOS__ #include <errno.h> #endif @@ -115,10 +117,21 @@ static int wsa_init = 0; typedef s32 SOCKET; #define closesocket(v) close(v) +#endif /*WIN32||_WIN32_WCE*/ + + +#ifdef GPAC_HAS_IPV6 +# ifndef IPV6_ADD_MEMBERSHIP +# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +# endif +# ifndef IPV6_DROP_MEMBERSHIP +# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP +# endif #endif + #ifdef __SYMBIAN32__ -#define SSO_CAST +#define SSO_CAST #else #define SSO_CAST (const char *) #endif @@ -130,6 +143,13 @@ typedef s32 SOCKET; static u32 ipv6_check_state = 0; #endif +#ifdef __x86_64__ +#define NULL_SOCKET 0 +#else +#define NULL_SOCKET (SOCKET)NULL +#endif + + /*internal flags*/ enum { @@ -216,7 +236,7 @@ u32 gf_net_has_ipv6() #ifdef WIN32 if (!wsa_init) WSACleanup(); #endif - } + } return (ipv6_check_state==2); #else return 0; @@ -252,7 +272,7 @@ static struct addrinfo *gf_sk_get_ipv6_addr(char *PeerName, u16 PortNumber, int memset(&hints, 0, sizeof(hints)); hints.ai_socktype = sock_type; hints.ai_family = family; - hints.ai_flags = flags; + hints.ai_flags = flags; if (PortNumber) { sprintf (portstring, "%d", PortNumber); @@ -293,14 +313,14 @@ GF_Err gf_sk_get_local_ip(GF_Socket *sock, char *buffer) #ifdef GPAC_HAS_IPV6 char clienthost[NI_MAXHOST]; if (sock->flags & GF_SOCK_HAS_PEER) { - if (getnameinfo((struct sockaddr *)&sock->dest_addr, sock->dest_addr_len, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST)) + if (getnameinfo((struct sockaddr *)&sock->dest_addr, sock->dest_addr_len, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST)) return GF_IP_NETWORK_FAILURE; } else { struct sockaddr_storage clientaddr; socklen_t addrlen = sizeof(clientaddr); if (getsockname(sock->socket, (struct sockaddr *)&clientaddr, &addrlen)) return GF_IP_NETWORK_FAILURE; - if (getnameinfo((struct sockaddr *)&clientaddr, addrlen, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST)) + if (getnameinfo((struct sockaddr *)&clientaddr, addrlen, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST)) return GF_IP_NETWORK_FAILURE; } strcpy(buffer, clienthost); @@ -386,7 +406,7 @@ GF_Err gf_sk_set_block_mode(GF_Socket *sock, u32 NonBlockingOn) } -static void gf_sk_free(GF_Socket *sock) +static void gf_sk_gf_free(GF_Socket *sock) { /*leave multicast*/ if (sock->socket && (sock->flags & GF_SOCK_IS_MULTICAST) ) { @@ -394,7 +414,7 @@ static void gf_sk_free(GF_Socket *sock) #ifdef GPAC_HAS_IPV6 struct sockaddr *addr = (struct sockaddr *)&sock->dest_addr; if (addr->sa_family==AF_INET6) { - struct ipv6_mreq mreq6; + struct ipv6_mreq mreq6; memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); mreq6.ipv6mr_interface= 0; setsockopt(sock->socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &mreq6, sizeof(mreq6)); @@ -421,12 +441,12 @@ static void gf_sk_free(GF_Socket *sock) void gf_sk_del(GF_Socket *sock) { - gf_sk_free(sock); + gf_sk_gf_free(sock); #ifdef WIN32 wsa_init --; if (!wsa_init) WSACleanup(); #endif - free(sock); + gf_free(sock); } void gf_sk_reset(GF_Socket *sock) @@ -435,7 +455,7 @@ void gf_sk_reset(GF_Socket *sock) if (sock) setsockopt(sock->socket, SOL_SOCKET, SO_ERROR, (char *) &clear, sizeof(u32) ); } -s32 gf_sk_get_handle(GF_Socket *sock) +s32 gf_sk_get_handle(GF_Socket *sock) { return sock->socket; } @@ -450,7 +470,7 @@ GF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber, char *loca u32 type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM; struct addrinfo *res, *aip, *lip; - gf_sk_free(sock); + gf_sk_gf_free(sock); res = gf_sk_get_ipv6_addr(PeerName, PortNumber, AF_UNSPEC, AI_PASSIVE, type); if (!res) return GF_IP_CONNECTION_FAILURE; @@ -478,7 +498,7 @@ GF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber, char *loca if (type != (u32) aip->ai_socktype) continue; sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); if (sock->socket == INVALID_SOCKET) { - sock->socket = (SOCKET)NULL; + sock->socket = NULL_SOCKET; continue; } if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1); @@ -489,7 +509,7 @@ GF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber, char *loca ret = bind(sock->socket, lip->ai_addr, lip->ai_addrlen); if (ret == SOCKET_ERROR) { closesocket(sock->socket); - sock->socket = (SOCKET)NULL; + sock->socket = NULL_SOCKET; continue; } } @@ -497,7 +517,7 @@ GF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber, char *loca ret = connect(sock->socket, aip->ai_addr, aip->ai_addrlen); if (ret == SOCKET_ERROR) { closesocket(sock->socket); - sock->socket = (SOCKET)NULL; + sock->socket = NULL_SOCKET; continue; } @@ -511,9 +531,9 @@ GF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber, char *loca if (lip) freeaddrinfo(lip); return GF_IP_CONNECTION_FAILURE; -#else +#else struct hostent *Host; - + if (local_ip) { /*this will turn on MobileIP if needed*/ GF_Err e = gf_sk_bind(sock, local_ip, PortNumber, PeerName, PortNumber, GF_SOCK_REUSE_PORT); @@ -521,7 +541,7 @@ GF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber, char *loca } if (!sock->socket) { sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0); - if (sock->flags & GF_SOCK_NON_BLOCKING) + if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1); } @@ -548,12 +568,12 @@ GF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber, char *loca ret = connect(sock->socket, (struct sockaddr *) &sock->dest_addr, sizeof(struct sockaddr)); if (ret == SOCKET_ERROR) { u32 res = LASTSOCKERROR; - GF_LOG(GF_LOG_CORE, GF_LOG_ERROR, ("[Core] Couldn't connect socket - last sock error %d\n", res)); + GF_LOG(GF_LOG_NETWORK, GF_LOG_ERROR, ("[Core] Couldn't connect socket - last sock error %d\n", res)); switch (res) { case EAGAIN: return GF_IP_SOCK_WOULD_BLOCK; #ifdef WIN32 - case WSAEINVAL: - if (sock->flags & GF_SOCK_NON_BLOCKING) + case WSAEINVAL: + if (sock->flags & GF_SOCK_NON_BLOCKING) return GF_IP_SOCK_WOULD_BLOCK; #endif case EISCONN: return GF_OK; @@ -584,7 +604,10 @@ GF_Err gf_sk_bind(GF_Socket *sock, char *local_ip, u16 port, char *peer_name, u1 size_t addrlen; struct sockaddr_in LocalAdd; struct hostent *Host; +#if 0 char buf[GF_MAX_IP_NAME_LEN]; +#endif + #endif s32 ret; s32 optval; @@ -600,7 +623,7 @@ GF_Err gf_sk_bind(GF_Socket *sock, char *local_ip, u16 port, char *peer_name, u1 res = gf_sk_get_ipv6_addr(peer_name, peer_port, af, AI_PASSIVE, type); if (!res) return GF_IP_CONNECTION_FAILURE; #ifdef WIN32 - /*win32 has troubles redirecting IPV4 datagrams to IPV6 sockets, so override + /*win32 has troubles redirecting IPV4 datagrams to IPV6 sockets, so override local family type to avoid IPV4(S)->IPV6(C) UDP*/ af = res->ai_family; #endif @@ -608,7 +631,7 @@ GF_Err gf_sk_bind(GF_Socket *sock, char *local_ip, u16 port, char *peer_name, u1 sock->dest_addr_len = res->ai_addrlen; freeaddrinfo(res); } - + /*turn on MobileIP*/ if (local_ip && MobileIPAdd && !strcmp(MobileIPAdd, local_ip) ) { if (gf_net_mobileip_ctrl(1)==GF_OK) { @@ -635,7 +658,7 @@ GF_Err gf_sk_bind(GF_Socket *sock, char *local_ip, u16 port, char *peer_name, u1 sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); if (sock->socket == INVALID_SOCKET) { - sock->socket = (SOCKET)NULL; + sock->socket = NULL_SOCKET; continue; } if (options & GF_SOCK_REUSE_PORT) { @@ -646,21 +669,23 @@ GF_Err gf_sk_bind(GF_Socket *sock, char *local_ip, u16 port, char *peer_name, u1 setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval)); #endif } + if (sock->flags & GF_SOCK_NON_BLOCKING) gf_sk_set_block_mode(sock, 1); + if (peer_name && peer_port) + sock->flags |= GF_SOCK_HAS_PEER; + + ret = bind(sock->socket, aip->ai_addr, aip->ai_addrlen); if (ret == SOCKET_ERROR) { closesocket(sock->socket); - sock->socket = (SOCKET)NULL; + sock->socket = NULL_SOCKET; continue; } if (aip->ai_family==PF_INET6) sock->flags |= GF_SOCK_IS_IPV6; else sock->flags &= ~GF_SOCK_IS_IPV6; - if (peer_name && peer_port) - sock->flags |= GF_SOCK_HAS_PEER; - freeaddrinfo(res); return GF_OK; } @@ -674,17 +699,6 @@ GF_Err gf_sk_bind(GF_Socket *sock, char *local_ip, u16 port, char *peer_name, u1 sock->flags &= ~GF_SOCK_IS_IPV6; memset((void *) &LocalAdd, 0, sizeof(LocalAdd)); - ret = gethostname(buf, GF_MAX_IP_NAME_LEN); - if (ret == SOCKET_ERROR) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot get localhost name - socket error %x\n", LASTSOCKERROR)); - return GF_IP_ADDRESS_NOT_FOUND; - } - /*get the IP address*/ - Host = gethostbyname(buf); - if (Host == NULL) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot resolve localhost name - socket error %x\n", LASTSOCKERROR)); - return GF_IP_ADDRESS_NOT_FOUND; - } /*turn on MobileIP*/ if (local_ip && MobileIPAdd && !strcmp(MobileIPAdd, local_ip) ) { @@ -694,19 +708,41 @@ GF_Err gf_sk_bind(GF_Socket *sock, char *local_ip, u16 port, char *peer_name, u1 local_ip = NULL; } } - /*setup the address*/ ip_add = 0; if (local_ip) ip_add = inet_addr(local_ip); + if (!ip_add) { - ip_add = htonl(INADDR_ANY); - local_ip = NULL; +#if 0 + buf[0] = 0; + ret = gethostname(buf, GF_MAX_IP_NAME_LEN); + /*get the IP address*/ + Host = gethostbyname(buf); + if (Host != NULL) { + memcpy((char *) &LocalAdd.sin_addr, Host->h_addr_list[0], sizeof(LocalAdd.sin_addr)); + ip_add = LocalAdd.sin_addr.s_addr; + } else { + ip_add = INADDR_ANY; + } +#else + ip_add = INADDR_ANY; +#endif } - memcpy((char *) &LocalAdd.sin_addr, Host->h_addr_list[0], sizeof(LocalAdd.sin_addr)); + if (peer_name && peer_port) { +#ifdef WIN32 + if ((inet_addr(peer_name)== ip_add)) { + optval = 1; + setsockopt(sock->socket, SOL_SOCKET, SO_USELOOPBACK, SSO_CAST &optval, sizeof(optval)); + } +#endif + } + LocalAdd.sin_family = AF_INET; - LocalAdd.sin_addr.s_addr = ip_add; LocalAdd.sin_port = htons(port); + LocalAdd.sin_addr.s_addr = ip_add; addrlen = sizeof(struct sockaddr_in); + + if (options & GF_SOCK_REUSE_PORT) { optval = 1; setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, SSO_CAST &optval, sizeof(optval)); @@ -715,11 +751,12 @@ GF_Err gf_sk_bind(GF_Socket *sock, char *local_ip, u16 port, char *peer_name, u1 setsockopt(sock->socket, SOL_SOCKET, SO_REUSEPORT, SSO_CAST &optval, sizeof(optval)); #endif } + /*bind the socket*/ ret = bind(sock->socket, (struct sockaddr *) &LocalAdd, addrlen); if (ret == SOCKET_ERROR) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot bind socket - socket error %x\n", LASTSOCKERROR)); - return GF_IP_CONNECTION_FAILURE; + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] cannot bind socket - socket error %x\n", LASTSOCKERROR)); + ret = GF_IP_CONNECTION_FAILURE; } if (peer_name && peer_port) { @@ -728,27 +765,28 @@ GF_Err gf_sk_bind(GF_Socket *sock, char *local_ip, u16 port, char *peer_name, u1 sock->dest_addr.sin_addr.s_addr = inet_addr(peer_name); if (sock->dest_addr.sin_addr.s_addr == INADDR_NONE) { Host = gethostbyname(peer_name); - if (Host == NULL) return GF_IP_ADDRESS_NOT_FOUND; - memcpy((char *) &sock->dest_addr.sin_addr, Host->h_addr_list[0], sizeof(u32)); + if (Host == NULL) ret = GF_IP_ADDRESS_NOT_FOUND; + else memcpy((char *) &sock->dest_addr.sin_addr, Host->h_addr_list[0], sizeof(u32)); } sock->flags |= GF_SOCK_HAS_PEER; } -#endif if (sock->flags & GF_SOCK_HAS_PEER) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[socket] socket bound to port %d - remote peer: %s:%d\n", port, peer_name, peer_port)); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[socket] socket bound to %08X - port %d - remote peer: %s:%d\n", ip_add, port, peer_name, peer_port)); } else { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[socket] socket bound to port %d\n", port)); + GF_LOG(GF_LOG_INFO, GF_LOG_NETWORK, ("[socket] socket bound to %08X - port %d\n", ip_add, port)); } - return GF_OK; + return ret; +#endif } //send length bytes of a buffer GF_Err gf_sk_send(GF_Socket *sock, char *buffer, u32 length) { GF_Err e; - u32 Count, Res; + u32 count; + s32 res; #ifndef __SYMBIAN32__ - u32 ready; + s32 ready; struct timeval timeout; fd_set Group; #endif @@ -781,15 +819,15 @@ GF_Err gf_sk_send(GF_Socket *sock, char *buffer, u32 length) #endif //direct writing - Count = 0; - while (Count < length) { + count = 0; + while (count < length) { if (sock->flags & GF_SOCK_HAS_PEER) { - Res = sendto(sock->socket, (char *) &buffer[Count], length - Count, 0, (struct sockaddr *) &sock->dest_addr, sock->dest_addr_len); + res = sendto(sock->socket, (char *) buffer+count, length - count, 0, (struct sockaddr *) &sock->dest_addr, sock->dest_addr_len); } else { - Res = send(sock->socket, (char *) &buffer[Count], length - Count, 0); + res = send(sock->socket, (char *) buffer+count, length - count, 0); } - if (Res == SOCKET_ERROR) { - switch (Res = LASTSOCKERROR) { + if (res == SOCKET_ERROR) { + switch (res = LASTSOCKERROR) { case EAGAIN: return GF_IP_SOCK_WOULD_BLOCK; #ifndef __SYMBIAN32__ @@ -801,13 +839,13 @@ GF_Err gf_sk_send(GF_Socket *sock, char *buffer, u32 length) return GF_IP_NETWORK_FAILURE; } } - Count += Res; + count += res; } return GF_OK; } -u32 gf_sk_is_multicast_address(char *multi_IPAdd) +u32 gf_sk_is_multicast_address(const char *multi_IPAdd) { #ifdef GPAC_HAS_IPV6 u32 val; @@ -819,11 +857,11 @@ u32 gf_sk_is_multicast_address(char *multi_IPAdd) if (sep) sep = strchr(multi_IPAdd, ':'); if (sep && !strnicmp(multi_IPAdd, "ff", 2)) return 1; /*ipv4 multicast address*/ - res = gf_sk_get_ipv6_addr(multi_IPAdd, 7000, AF_UNSPEC, AI_PASSIVE, SOCK_DGRAM); + res = gf_sk_get_ipv6_addr((char*)multi_IPAdd, 7000, AF_UNSPEC, AI_PASSIVE, SOCK_DGRAM); if (!res) return 0; val = 0; if (res->ai_addr->sa_family == AF_INET) { - val = IN_MULTICAST(ntohl(((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr)); + val = IN_MULTICAST(ntohl(((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr)); } else if (res->ai_addr->sa_family == AF_INET6) { val = IN6_IS_ADDR_MULTICAST(& ((struct sockaddr_in6 *)res->ai_addr)->sin6_addr); } @@ -831,14 +869,14 @@ u32 gf_sk_is_multicast_address(char *multi_IPAdd) return val; #else if (!multi_IPAdd) return 0; - return ((htonl(inet_addr(multi_IPAdd)) >> 8) & 0x00f00000) == 0x00e00000; + return ((htonl(inet_addr(multi_IPAdd)) >> 8) & 0x00f00000) == 0x00e00000; #endif } GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNumber, u32 TTL, Bool NoBind, char *local_interface_ip) { s32 ret; - u32 flag; + u32 flag; struct ip_mreq M_req; u32 optval; #ifdef GPAC_HAS_IPV6 @@ -852,7 +890,7 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNu if (!sock || sock->socket) return GF_BAD_PARAM; if (TTL > 255) TTL = 255; - + /*check the address*/ if (!gf_sk_is_multicast_address(multi_IPAdd)) return GF_BAD_PARAM; @@ -882,7 +920,7 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNu if (type != (u32) aip->ai_socktype) continue; sock->socket = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); if (sock->socket == INVALID_SOCKET) { - sock->socket = (SOCKET)NULL; + sock->socket = NULL_SOCKET; continue; } @@ -906,7 +944,7 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNu ret = bind(sock->socket, aip->ai_addr, aip->ai_addrlen); if (ret == SOCKET_ERROR) { closesocket(sock->socket); - sock->socket = (SOCKET)NULL; + sock->socket = NULL_SOCKET; continue; } } @@ -917,8 +955,8 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNu freeaddrinfo(res); if (!sock->socket) return GF_IP_CONNECTION_FAILURE; - - if (!gf_sk_ipv6_set_remote_address(sock, multi_IPAdd, MultiPortNumber)) + + if (!gf_sk_ipv6_set_remote_address(sock, multi_IPAdd, MultiPortNumber)) return GF_IP_CONNECTION_FAILURE; addr = (struct sockaddr *)&sock->dest_addr; @@ -937,8 +975,8 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNu } if (addr->sa_family == AF_INET6) { struct ipv6_mreq M_reqV6; - - + + memcpy(&M_reqV6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); M_reqV6.ipv6mr_interface = 0; @@ -949,10 +987,10 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNu flag = 1; ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *) &flag, sizeof(flag)); if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE; - + ret = setsockopt(sock->socket, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *) &M_reqV6, sizeof(M_reqV6)); if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE; - } + } #else sock->socket = socket(AF_INET, (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM, 0); @@ -997,7 +1035,7 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNu ret = setsockopt(sock->socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &M_req, sizeof(M_req)); if (ret == SOCKET_ERROR) { - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[core] cannot join multicast: error %d\n", LASTSOCKERROR)); + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[core] cannot join multicast: error %d\n", LASTSOCKERROR)); return GF_IP_CONNECTION_FAILURE; } /*set the Time To Live*/ @@ -1006,7 +1044,7 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNu /*Disable loopback*/ flag = 1; ret = setsockopt(sock->socket, IPPROTO_IP, IP_MULTICAST_LOOP, (char *) &flag, sizeof(flag)); - if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE; +// if (ret == SOCKET_ERROR) return GF_IP_CONNECTION_FAILURE; sock->dest_addr.sin_family = AF_INET; sock->dest_addr.sin_addr.s_addr = M_req.imr_multiaddr.s_addr; @@ -1025,9 +1063,9 @@ GF_Err gf_sk_setup_multicast(GF_Socket *sock, char *multi_IPAdd, u16 MultiPortNu GF_Err gf_sk_receive(GF_Socket *sock, char *buffer, u32 length, u32 startFrom, u32 *BytesRead) { GF_Err e; - u32 res; + s32 res; #ifndef __SYMBIAN32__ - u32 ready; + s32 ready; struct timeval timeout; fd_set Group; #endif @@ -1052,12 +1090,12 @@ GF_Err gf_sk_receive(GF_Socket *sock, char *buffer, u32 length, u32 startFrom, u case EAGAIN: return GF_IP_SOCK_WOULD_BLOCK; default: - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] cannot select (error %d)\n", LASTSOCKERROR)); + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] cannot select (error %d)\n", LASTSOCKERROR)); return GF_IP_NETWORK_FAILURE; } } if (!FD_ISSET(sock->socket, &Group)) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[socket] nothing to be read\n")); + GF_LOG(GF_LOG_DEBUG, GF_LOG_NETWORK, ("[socket] nothing to be read\n")); return GF_IP_NETWORK_EMPTY; } #endif @@ -1069,7 +1107,7 @@ GF_Err gf_sk_receive(GF_Socket *sock, char *buffer, u32 length, u32 startFrom, u if (res == SOCKET_ERROR) { res = LASTSOCKERROR; - GF_LOG(GF_LOG_ERROR, GF_LOG_CORE, ("[socket] error reading - socket error %d\n", res)); + GF_LOG(GF_LOG_ERROR, GF_LOG_NETWORK, ("[socket] error reading - socket error %d\n", res)); switch (res) { case EAGAIN: return GF_IP_SOCK_WOULD_BLOCK; @@ -1104,10 +1142,11 @@ GF_Err gf_sk_listen(GF_Socket *sock, u32 MaxConnection) GF_Err gf_sk_accept(GF_Socket *sock, GF_Socket **newConnection) { - u32 client_address_size, res; + u32 client_address_size; + s32 res; SOCKET sk; #ifndef __SYMBIAN32__ - u32 ready; + s32 ready; struct timeval timeout; fd_set Group; #endif @@ -1149,10 +1188,10 @@ GF_Err gf_sk_accept(GF_Socket *sock, GF_Socket **newConnection) return GF_IP_SOCK_WOULD_BLOCK; default: return GF_IP_NETWORK_FAILURE; - } + } } - (*newConnection) = (GF_Socket *) malloc(sizeof(GF_Socket)); + (*newConnection) = (GF_Socket *) gf_malloc(sizeof(GF_Socket)); (*newConnection)->socket = sk; (*newConnection)->flags = sock->flags & ~GF_SOCK_IS_LISTENING; #ifdef GPAC_HAS_IPV6 @@ -1205,7 +1244,7 @@ GF_Err gf_sk_get_local_info(GF_Socket *sock, u16 *Port, u32 *Familly) return GF_OK; } -//we have to do this for the server sockets as we use only one thread +//we have to do this for the server sockets as we use only one thread GF_Err gf_sk_server_mode(GF_Socket *sock, Bool serverOn) { u32 one; @@ -1227,14 +1266,14 @@ GF_Err gf_sk_get_remote_address(GF_Socket *sock, char *buf) char clienthost[NI_MAXHOST]; struct sockaddr_in6 * addrptr = (struct sockaddr_in6 *)(&sock->dest_addr_len); if (!sock || sock->socket) return GF_BAD_PARAM; - if (getnameinfo((struct sockaddr *)addrptr, sock->dest_addr_len, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST)) + if (getnameinfo((struct sockaddr *)addrptr, sock->dest_addr_len, clienthost, sizeof(clienthost), NULL, 0, NI_NUMERICHOST)) return GF_IP_ADDRESS_NOT_FOUND; strcpy(buf, clienthost); #else if (!sock || !sock->socket) return GF_BAD_PARAM; strcpy(buf, inet_ntoa(sock->dest_addr.sin_addr)); #endif - return GF_OK; + return GF_OK; } @@ -1243,7 +1282,8 @@ GF_Err gf_sk_get_remote_address(GF_Socket *sock, char *buf) //send length bytes of a buffer GF_Err gf_sk_send_to(GF_Socket *sock, char *buffer, u32 length, char *remoteHost, u16 remotePort) { - u32 Count, Res, remote_add_len; + u32 count, remote_add_len; + s32 res; #ifdef GPAC_HAS_IPV6 struct sockaddr_storage remote_add; #else @@ -1251,7 +1291,7 @@ GF_Err gf_sk_send_to(GF_Socket *sock, char *buffer, u32 length, char *remoteHost struct hostent *Host; #endif #ifndef __SYMBIAN32__ - u32 ready; + s32 ready; struct timeval timeout; fd_set Group; #endif @@ -1313,11 +1353,11 @@ GF_Err gf_sk_send_to(GF_Socket *sock, char *buffer, u32 length, char *remoteHost remote_add.sin_port = sock->dest_addr.sin_port; remote_add.sin_addr.s_addr = sock->dest_addr.sin_addr.s_addr; } -#endif - Count = 0; - while (Count < length) { - Res = sendto(sock->socket, (char *) &buffer[Count], length - Count, 0, (struct sockaddr *) &remote_add, remote_add_len); - if (Res == SOCKET_ERROR) { +#endif + count = 0; + while (count < length) { + res = sendto(sock->socket, (char *) buffer+count, length - count, 0, (struct sockaddr *) &remote_add, remote_add_len); + if (res == SOCKET_ERROR) { switch (LASTSOCKERROR) { case EAGAIN: return GF_IP_SOCK_WOULD_BLOCK; @@ -1325,7 +1365,7 @@ GF_Err gf_sk_send_to(GF_Socket *sock, char *buffer, u32 length, char *remoteHost return GF_IP_NETWORK_FAILURE; } } - Count += Res; + count += res; } return GF_OK; } @@ -1336,9 +1376,9 @@ GF_Err gf_sk_send_to(GF_Socket *sock, char *buffer, u32 length, char *remoteHost GF_Err gf_sk_receive_wait(GF_Socket *sock, char *buffer, u32 length, u32 startFrom, u32 *BytesRead, u32 Second ) { GF_Err e; - u32 res; + s32 res; #ifndef __SYMBIAN32__ - u32 ready; + s32 ready; struct timeval timeout; fd_set Group; #endif @@ -1390,9 +1430,10 @@ GF_Err gf_sk_send_wait(GF_Socket *sock, char *buffer, u32 length, u32 Second ) { GF_Err e; - u32 Count, Res; + u32 count; + s32 res; #ifndef __SYMBIAN32__ - u32 ready; + s32 ready; struct timeval timeout; fd_set Group; #endif @@ -1424,22 +1465,22 @@ GF_Err gf_sk_send_wait(GF_Socket *sock, char *buffer, u32 length, u32 Second ) #endif //direct writing - Count = 0; - while (Count < length) { - Res = send(sock->socket, (char *) &buffer[Count], length - Count, 0); - if (Res == SOCKET_ERROR) { + count = 0; + while (count < length) { + res = send(sock->socket, (char *) buffer+count, length - count, 0); + if (res == SOCKET_ERROR) { switch (LASTSOCKERROR) { case EAGAIN: return GF_IP_SOCK_WOULD_BLOCK; #ifndef __SYMBIAN32__ - case ECONNRESET: + case ECONNRESET: return GF_IP_CONNECTION_CLOSED; #endif default: return GF_IP_NETWORK_FAILURE; } } - Count += Res; + count += res; } return GF_OK; } diff --git a/src/utils/os_thread.c b/src/utils/os_thread.c index dd69890..7e3f8f8 100644 --- a/src/utils/os_thread.c +++ b/src/utils/os_thread.c @@ -97,17 +97,17 @@ static const char *log_th_name(u32 id) GF_Thread *gf_th_new(const char *name) { - GF_Thread *tmp = malloc(sizeof(GF_Thread)); + GF_Thread *tmp = gf_malloc(sizeof(GF_Thread)); memset(tmp, 0, sizeof(GF_Thread)); tmp->status = GF_THREAD_STATUS_STOP; #ifndef GPAC_DISABLE_LOG if (name) { - tmp->log_name = strdup(name); + tmp->log_name = gf_strdup(name); } else { char szN[20]; - sprintf(szN, "0x%08x", (u32) tmp); - tmp->log_name = strdup(szN); + sprintf(szN, "0x%p", tmp); + tmp->log_name = gf_strdup(szN); } log_add_thread(tmp); #endif @@ -119,9 +119,9 @@ DWORD WINAPI RunThread(void *ptr) { DWORD ret = 0; #else -void *RunThread(void *ptr) +void * RunThread(void *ptr) { - u32 ret = 0; + long int ret = 0; #endif GF_Thread *t = (GF_Thread *)ptr; @@ -133,14 +133,18 @@ void *RunThread(void *ptr) #ifndef GPAC_DISABLE_LOG t->id = gf_th_id(); - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Thread %s] Entering thread proc - thread ID 0x%08x\n", t->log_name, t->id)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Thread %s] At %d Entering thread proc - thread ID 0x%08x\n", t->log_name, gf_sys_clock(), t->id)); #endif + + /* Each thread has its own seed */ + gf_rand_init(0); + /* Run our thread */ ret = t->Run(t->args); exit: #ifndef GPAC_DISABLE_LOG - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Thread %s] Exiting thread proc\n", t->log_name)); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Thread %s] At %d Exiting thread proc\n", t->log_name, gf_sys_clock())); #endif t->status = GF_THREAD_STATUS_DEAD; t->Run = NULL; @@ -201,7 +205,11 @@ void Thread_Stop(GF_Thread *t, Bool Destroy) } #else if (Destroy) { +#ifdef ANDROID + pthread_kill(t->threadH, SIGQUIT); +#else pthread_cancel(t->threadH); +#endif t->threadH = 0; } else { /*gracefully wait for Run to finish*/ @@ -225,10 +233,10 @@ void gf_th_del(GF_Thread *t) #endif #ifndef GPAC_DISABLE_LOG - free(t->log_name); + gf_free(t->log_name); log_del_thread(t); #endif - free(t); + gf_free(t); } @@ -298,7 +306,7 @@ GF_Mutex *gf_mx_new(const char *name) #ifndef WIN32 pthread_mutexattr_t attr; #endif - GF_Mutex *tmp = malloc(sizeof(GF_Mutex)); + GF_Mutex *tmp = gf_malloc(sizeof(GF_Mutex)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_Mutex)); @@ -309,17 +317,17 @@ GF_Mutex *gf_mx_new(const char *name) pthread_mutexattr_init(&attr); if ( pthread_mutex_init(&tmp->hMutex, &attr) != 0 ) { #endif - free(tmp); + gf_free(tmp); return NULL; } #ifndef GPAC_DISABLE_LOG if (name) { - tmp->log_name = strdup(name); + tmp->log_name = gf_strdup(name); } else { char szN[20]; - sprintf(szN, "0x%08x", (u32) tmp); - tmp->log_name = strdup(szN); + sprintf(szN, "0x%p", tmp); + tmp->log_name = gf_strdup(szN); } #endif @@ -334,9 +342,9 @@ void gf_mx_del(GF_Mutex *mx) pthread_mutex_destroy(&mx->hMutex); #endif #ifndef GPAC_DISABLE_LOG - free(mx->log_name); + gf_free(mx->log_name); #endif - free(mx); + gf_free(mx); } void gf_mx_v(GF_Mutex *mx) @@ -353,7 +361,7 @@ void gf_mx_v(GF_Mutex *mx) if (mx->HolderCount == 0) { #ifndef GPAC_DISABLE_LOG - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] Released by thread %s\n", mx->log_name, log_th_name(mx->Holder) )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] At %d Released by thread %s\n", mx->log_name, gf_sys_clock(), log_th_name(mx->Holder) )); #endif mx->Holder = 0; #ifdef WIN32 @@ -367,6 +375,7 @@ void gf_mx_v(GF_Mutex *mx) u32 gf_mx_p(GF_Mutex *mx) { u32 caller; + assert(mx); if (!mx) return 0; caller = gf_th_id(); if (caller == mx->Holder) { @@ -376,7 +385,7 @@ u32 gf_mx_p(GF_Mutex *mx) #ifndef GPAC_DISABLE_LOG if (mx->Holder) - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] Thread %s waiting a release from thread %s\n", mx->log_name, log_th_name(caller), log_th_name(mx->Holder) )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] At %d Thread %s waiting a release from thread %s\n", mx->log_name, gf_sys_clock(), log_th_name(caller), log_th_name(mx->Holder) )); #endif #ifdef WIN32 @@ -395,7 +404,7 @@ u32 gf_mx_p(GF_Mutex *mx) #endif mx->HolderCount = 1; mx->Holder = caller; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] Grabbed by thread %s\n", mx->log_name, log_th_name(mx->Holder) )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] At %d Grabbed by thread %s\n", mx->log_name, gf_sys_clock(), log_th_name(mx->Holder) )); return 1; } @@ -414,20 +423,20 @@ Bool gf_mx_try_lock(GF_Mutex *mx) switch (WaitForSingleObject(mx->hMutex, 1)) { case WAIT_ABANDONED: case WAIT_TIMEOUT: - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] Couldn't release it for thread %s (grabbed by thread %s)\n", mx->log_name, log_th_name(caller), log_th_name(mx->Holder) )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] At %d Couldn't be locked by thread %s (grabbed by thread %s)\n", mx->log_name, gf_sys_clock(), log_th_name(caller), log_th_name(mx->Holder) )); return 0; default: break; } #else if (pthread_mutex_trylock(&mx->hMutex) != 0 ) { - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] Couldn't release it for thread %s (grabbed by thread %s)\n", mx->log_name, log_th_name(caller), log_th_name(mx->Holder) )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] At %d Couldn't release it for thread %s (grabbed by thread %s)\n", mx->log_name, gf_sys_clock(), log_th_name(caller), log_th_name(mx->Holder) )); return 0; } #endif mx->Holder = caller; mx->HolderCount = 1; - GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] Grabbed by thread %s\n", mx->log_name, log_th_name(mx->Holder) )); + GF_LOG(GF_LOG_DEBUG, GF_LOG_CORE, ("[Mutex %s] At %d Grabbed by thread %s\n", mx->log_name, gf_sys_clock(), log_th_name(mx->Holder) )); return 1; } @@ -443,7 +452,7 @@ struct __tag_semaphore sem_t *hSemaphore; sem_t SemaData; #if defined(__DARWIN__) || defined(__APPLE__) - const char *SemName; + char *SemName; #endif #endif }; @@ -451,7 +460,7 @@ struct __tag_semaphore GF_Semaphore *gf_sema_new(u32 MaxCount, u32 InitCount) { - GF_Semaphore *tmp = malloc(sizeof(GF_Semaphore)); + GF_Semaphore *tmp = gf_malloc(sizeof(GF_Semaphore)); if (!tmp) return NULL; #if defined(WIN32) @@ -465,19 +474,19 @@ GF_Semaphore *gf_sema_new(u32 MaxCount, u32 InitCount) { char semaName[40]; sprintf(semaName,"GPAC_SEM%d", (u32) tmp); - tmp->SemName = strdup(semaName); + tmp->SemName = gf_strdup(semaName); } tmp->hSemaphore = sem_open(tmp->SemName, O_CREAT, S_IRUSR|S_IWUSR, InitCount); #else if (sem_init(&tmp->SemaData, 0, InitCount) < 0 ) { - free(tmp); + gf_free(tmp); return NULL; } tmp->hSemaphore = &tmp->SemaData; #endif if (!tmp->hSemaphore) { - free(tmp); + gf_free(tmp); return NULL; } return tmp; @@ -490,11 +499,11 @@ void gf_sema_del(GF_Semaphore *sm) #elif defined(__DARWIN__) || defined(__APPLE__) sem_t *sema = sem_open(sm->SemName, 0); sem_destroy(sema); - free(sm->SemName); + gf_free(sm->SemName); #else sem_destroy(sm->hSemaphore); #endif - free(sm); + gf_free(sm); } u32 gf_sema_notify(GF_Semaphore *sm, u32 NbRelease) diff --git a/src/utils/path2d.c b/src/utils/path2d.c index bc29d78..f934cdd 100644 --- a/src/utils/path2d.c +++ b/src/utils/path2d.c @@ -40,9 +40,9 @@ void gf_path_reset(GF_Path *gp) Fixed fineness; u32 flags; if (!gp) return; - if (gp->contours) free(gp->contours); - if (gp->tags) free(gp->tags); - if (gp->points) free(gp->points); + if (gp->contours) gf_free(gp->contours); + if (gp->tags) gf_free(gp->tags); + if (gp->points) gf_free(gp->points); fineness = gp->fineness ? gp->fineness : FIX_ONE; flags = gp->flags; memset(gp, 0, sizeof(GF_Path)); @@ -56,12 +56,12 @@ GF_Path *gf_path_clone(GF_Path *gp) GF_Path *dst; GF_SAFEALLOC(dst, GF_Path); if (!dst) return NULL; - dst->contours = (u32 *)malloc(sizeof(u32)*gp->n_contours); - if (!dst->contours) { free(dst); return NULL; } - dst->points = (GF_Point2D *) malloc(sizeof(GF_Point2D)*gp->n_points); - if (!dst->points) { free(dst->contours); free(dst); return NULL; } - dst->tags = (u8 *) malloc(sizeof(u8)*gp->n_points); - if (!dst->tags) { free(dst->points); free(dst->contours); free(dst); return NULL; } + dst->contours = (u32 *)gf_malloc(sizeof(u32)*gp->n_contours); + if (!dst->contours) { gf_free(dst); return NULL; } + dst->points = (GF_Point2D *) gf_malloc(sizeof(GF_Point2D)*gp->n_points); + if (!dst->points) { gf_free(dst->contours); gf_free(dst); return NULL; } + dst->tags = (u8 *) gf_malloc(sizeof(u8)*gp->n_points); + if (!dst->tags) { gf_free(dst->points); gf_free(dst->contours); gf_free(dst); return NULL; } memcpy(dst->contours, gp->contours, sizeof(u32)*gp->n_contours); dst->n_contours = gp->n_contours; memcpy(dst->points, gp->points, sizeof(GF_Point2D)*gp->n_points); @@ -77,17 +77,17 @@ GF_EXPORT void gf_path_del(GF_Path *gp) { if (!gp) return; - if (gp->contours) free(gp->contours); - if (gp->tags) free(gp->tags); - if (gp->points) free(gp->points); - free(gp); + if (gp->contours) gf_free(gp->contours); + if (gp->tags) gf_free(gp->tags); + if (gp->points) gf_free(gp->points); + gf_free(gp); } #define GF_2D_REALLOC(_gp) \ if (_gp->n_alloc_points < _gp->n_points+3) { \ _gp->n_alloc_points = (_gp->n_alloc_points<5) ? 10 : (_gp->n_alloc_points*3/2); \ - _gp->points = (GF_Point2D *)realloc(_gp->points, sizeof(GF_Point2D)*(_gp->n_alloc_points)); \ - _gp->tags = (u8 *) realloc(_gp->tags, sizeof(u8)*(_gp->n_alloc_points)); \ + _gp->points = (GF_Point2D *)gf_realloc(_gp->points, sizeof(GF_Point2D)*(_gp->n_alloc_points)); \ + _gp->tags = (u8 *) gf_realloc(_gp->tags, sizeof(u8)*(_gp->n_alloc_points)); \ } \ @@ -105,7 +105,7 @@ GF_Err gf_path_add_move_to(GF_Path *gp, Fixed x, Fixed y) } #endif - gp->contours = (u32 *) realloc(gp->contours, sizeof(u32)*(gp->n_contours+1)); + gp->contours = (u32 *) gf_realloc(gp->contours, sizeof(u32)*(gp->n_contours+1)); GF_2D_REALLOC(gp) gp->points[gp->n_points].x = x; @@ -275,16 +275,16 @@ GF_Err gf_path_add_subpath(GF_Path *gp, GF_Path *src, GF_Matrix2D *mx) { u32 i; if (!src) return GF_OK; - gp->contours = realloc(gp->contours, sizeof(u32) * (gp->n_contours + src->n_contours)); + gp->contours = gf_realloc(gp->contours, sizeof(u32) * (gp->n_contours + src->n_contours)); if (!gp->contours) return GF_OUT_OF_MEM; for (i=0; i<src->n_contours; i++) { gp->contours[i+gp->n_contours] = src->contours[i] + gp->n_points; } gp->n_contours += src->n_contours; gp->n_alloc_points += src->n_alloc_points; - gp->points = realloc(gp->points, sizeof(GF_Point2D)*gp->n_alloc_points); + gp->points = gf_realloc(gp->points, sizeof(GF_Point2D)*gp->n_alloc_points); if (!gp->points) return GF_OUT_OF_MEM; - gp->tags = realloc(gp->tags, sizeof(u8)*gp->n_alloc_points); + gp->tags = gf_realloc(gp->tags, sizeof(u8)*gp->n_alloc_points); if (!gp->tags) return GF_OUT_OF_MEM; memcpy(gp->points + gp->n_points, src->points, sizeof(GF_Point2D)*src->n_points); if (mx) { @@ -356,13 +356,13 @@ GF_Err gf_path_add_bezier(GF_Path *gp, GF_Point2D *pts, u32 nbPoints) GF_Point2D *newpts; if (!gp->n_points) return GF_BAD_PARAM; - newpts = (GF_Point2D *) malloc(sizeof(GF_Point2D) * (nbPoints+1)); + newpts = (GF_Point2D *) gf_malloc(sizeof(GF_Point2D) * (nbPoints+1)); newpts[0] = gp->points[gp->n_points-1]; memcpy(&newpts[1], pts, sizeof(GF_Point2D) * nbPoints); gf_add_n_bezier(gp, newpts, nbPoints + 1); - free(newpts); + gf_free(newpts); return GF_OK; } @@ -990,11 +990,11 @@ void gf_path_flatten(GF_Path *gp) if (gp->flags & GF_PATH_FLATTENED) return; if (!gp->n_points) return; res = gf_path_get_flatten(gp); - if (gp->contours) free(gp->contours); - if (gp->points) free(gp->points); - if (gp->tags) free(gp->tags); + if (gp->contours) gf_free(gp->contours); + if (gp->points) gf_free(gp->points); + if (gp->tags) gf_free(gp->tags); memcpy(gp, res, sizeof(GF_Path)); - free(res); + gf_free(res); } @@ -1164,10 +1164,10 @@ GF_PathIterator *gf_path_iterator_new(GF_Path *gp) if (!it) return NULL; flat = gf_path_get_flatten(gp); if (!flat) { - free(it); + gf_free(it); return NULL; } - it->seg = (IterInfo *) malloc(sizeof(IterInfo) * flat->n_points); + it->seg = (IterInfo *) gf_malloc(sizeof(IterInfo) * flat->n_points); it->num_seg = 0; it->length = 0; cur = 0; @@ -1274,8 +1274,8 @@ found: GF_EXPORT void gf_path_iterator_del(GF_PathIterator *it) { - if (it->seg) free(it->seg); - free(it); + if (it->seg) gf_free(it->seg); + gf_free(it); } diff --git a/src/utils/path2d_stroker.c b/src/utils/path2d_stroker.c index 91bbde8..05b95ef 100644 --- a/src/utils/path2d_stroker.c +++ b/src/utils/path2d_stroker.c @@ -182,8 +182,8 @@ static s32 ft_stroke_border_grow(FT_StrokeBorder border, u32 new_points) u32 new_max = border->num_points + new_points; if (new_max > border->max_points) { u32 cur_max = new_max*2; - border->points = (GF_Point2D *) realloc(border->points, sizeof(GF_Point2D)*cur_max); - border->tags = (u8 *) realloc(border->tags, sizeof(u8)*cur_max); + border->points = (GF_Point2D *) gf_realloc(border->points, sizeof(GF_Point2D)*cur_max); + border->tags = (u8 *) gf_realloc(border->tags, sizeof(u8)*cur_max); if (!border->points || !border->tags) return -1; border->max_points = cur_max; } @@ -1445,11 +1445,11 @@ static GF_Err gf_path_mergedashes(GF_Path *gp, u32 start_contour_index) gp->contours[i] = gp->contours[i+1] - dash_nb_pts; } gp->n_contours--; - gp->contours = (u32 *)realloc(gp->contours, sizeof(u32)*gp->n_contours); + gp->contours = (u32 *)gf_realloc(gp->contours, sizeof(u32)*gp->n_contours); /* - gp->points = realloc(gp->points, sizeof(GF_Point2D)*gp->n_points); - gp->tags = realloc(gp->tags, sizeof(u8)*gp->n_points); + gp->points = gf_realloc(gp->points, sizeof(GF_Point2D)*gp->n_points); + gp->tags = gf_realloc(gp->tags, sizeof(u8)*gp->n_points); gp->n_alloc_points = gp->n_points; */ return GF_OK; @@ -1472,7 +1472,7 @@ static GF_Err evg_dash_subpath(GF_Path *dashed, GF_Point2D *pts, u32 nb_pts, GF_ Fixed phase; s32 offset, toggle; - dists = (Fixed *)malloc(sizeof (Fixed) * nb_pts); + dists = (Fixed *)gf_malloc(sizeof (Fixed) * nb_pts); if (dists == NULL) return GF_OUT_OF_MEM; /* initial values */ @@ -1563,7 +1563,7 @@ static GF_Err evg_dash_subpath(GF_Path *dashed, GF_Point2D *pts, u32 nb_pts, GF_ gf_path_add_line_to_vec(dashed, &pts[i]); } } - free(dists); + gf_free(dists); return GF_OK; } @@ -1632,7 +1632,7 @@ static GF_Err evg_dash_subpath(GF_Path *dashed, GF_Point2D *pts, u32 nb_pts, GF_ err_exit: // pen->dash_offset = dist; - free(dists); + gf_free(dists); return GF_OK; } @@ -1746,9 +1746,9 @@ GF_Path *gf_path_get_outline(GF_Path *path, GF_PenSettings pen) FT_StrokeBorder sborder; outline = gf_path_new(); if (nb_pt) { - outline->points = (GF_Point2D *) malloc(sizeof(GF_Point2D)*nb_pt); - outline->tags = (u8 *) malloc(sizeof(u8)*nb_pt); - outline->contours = (u32 *) malloc(sizeof(u32)*nb_cnt); + outline->points = (GF_Point2D *) gf_malloc(sizeof(GF_Point2D)*nb_pt); + outline->tags = (u8 *) gf_malloc(sizeof(u8)*nb_pt); + outline->contours = (u32 *) gf_malloc(sizeof(u32)*nb_cnt); outline->n_alloc_points = nb_pt; sborder = &stroker.borders[0]; if (sborder->valid ) ft_stroke_border_export(sborder, outline); @@ -1771,10 +1771,10 @@ GF_Path *gf_path_get_outline(GF_Path *path, GF_PenSettings pen) } } - if (stroker.borders[0].points) free(stroker.borders[0].points); - if (stroker.borders[0].tags) free(stroker.borders[0].tags); - if (stroker.borders[1].points) free(stroker.borders[1].points); - if (stroker.borders[1].tags) free(stroker.borders[1].tags); + if (stroker.borders[0].points) gf_free(stroker.borders[0].points); + if (stroker.borders[0].tags) gf_free(stroker.borders[0].tags); + if (stroker.borders[1].points) gf_free(stroker.borders[1].points); + if (stroker.borders[1].tags) gf_free(stroker.borders[1].tags); if (dashed) gf_path_del(dashed); if (scaled) gf_path_del(scaled); diff --git a/src/utils/symbian_net.cpp b/src/utils/symbian_net.cpp index 2e456b4..7b18e9b 100644 --- a/src/utils/symbian_net.cpp +++ b/src/utils/symbian_net.cpp @@ -308,7 +308,7 @@ GF_Err gf_sk_set_block_mode(GF_Socket *sock, u32 NonBlockingOn) } -static void gf_sk_free(GF_Socket *sock) +static void gf_sk_gf_free(GF_Socket *sock) { /*leave multicast*/ if (sock->socket && (sock->flags & GF_SOCK_IS_MULTICAST) ) { @@ -337,12 +337,12 @@ static void gf_sk_free(GF_Socket *sock) void gf_sk_del(GF_Socket *sock) { - gf_sk_free(sock); + gf_sk_gf_free(sock); #ifdef WIN32 wsa_init --; if (!wsa_init) WSACleanup(); #endif - free(sock); + gf_free(sock); } void gf_sk_reset(GF_Socket *sock) @@ -366,7 +366,7 @@ GF_Err gf_sk_connect(GF_Socket *sock, char *PeerName, u16 PortNumber, char *loca u32 type = (sock->flags & GF_SOCK_IS_TCP) ? SOCK_STREAM : SOCK_DGRAM; struct addrinfo *res, *aip; - gf_sk_free(sock); + gf_sk_gf_free(sock); res = gf_sk_get_ipv6_addr(PeerName, PortNumber, AF_UNSPEC, AI_PASSIVE, type); if (!res) return GF_IP_CONNECTION_FAILURE; @@ -935,7 +935,7 @@ GF_Err gf_sk_accept(GF_Socket *sock, GF_Socket **newConnection) } } - (*newConnection) = (GF_Socket *) malloc(sizeof(GF_Socket)); + (*newConnection) = (GF_Socket *) gf_malloc(sizeof(GF_Socket)); (*newConnection)->socket = sk; (*newConnection)->flags = sock->flags & ~GF_SOCK_IS_LISTENING; #ifdef GPAC_HAS_IPV6 @@ -1242,7 +1242,7 @@ typedef struct __tag_sock_group GF_SocketGroup *NewSockGroup() { - GF_SocketGroup *tmp = (GF_SocketGroup*)malloc(sizeof(GF_SocketGroup)); + GF_SocketGroup *tmp = (GF_SocketGroup*)gf_malloc(sizeof(GF_SocketGroup)); if (!tmp) return NULL; FD_ZERO(&tmp->ReadGroup); FD_ZERO(&tmp->WriteGroup); @@ -1251,7 +1251,7 @@ GF_SocketGroup *NewSockGroup() void SKG_Delete(GF_SocketGroup *group) { - free(group); + gf_free(group); } void SKG_SetWatchTime(GF_SocketGroup *group, u32 DelayInS, u32 DelayInMicroS) diff --git a/src/utils/symbian_os.cpp b/src/utils/symbian_os.cpp index dda6dca..5adf6e4 100644 --- a/src/utils/symbian_os.cpp +++ b/src/utils/symbian_os.cpp @@ -277,16 +277,16 @@ struct __tag_thread GF_EXPORT GF_Thread *gf_th_new(const char *name) { - GF_Thread *tmp = (GF_Thread *) malloc(sizeof(GF_Thread)); + GF_Thread *tmp = (GF_Thread *) gf_malloc(sizeof(GF_Thread)); memset((void *)tmp, 0, sizeof(GF_Thread)); tmp->status = GF_THREAD_STATUS_STOP; #ifndef GPAC_DISABLE_LOG if (name) { - tmp->log_name = strdup(name); + tmp->log_name = gf_strdup(name); } else { char szN[20]; sprintf(szN, "0x%08x", (u32) tmp); - tmp->log_name = strdup(szN); + tmp->log_name = gf_strdup(szN); } #endif @@ -412,9 +412,9 @@ void gf_th_del(GF_Thread *t) { Thread_Stop(t, 0); #ifndef GPAC_DISABLE_LOG - free(t->log_name); + gf_free(t->log_name); #endif - free(t); + gf_free(t); } @@ -464,22 +464,22 @@ struct __tag_mutex GF_EXPORT GF_Mutex *gf_mx_new(const char *name) { - GF_Mutex *tmp = (GF_Mutex *)malloc(sizeof(GF_Mutex)); + GF_Mutex *tmp = (GF_Mutex *)gf_malloc(sizeof(GF_Mutex)); if (!tmp) return NULL; memset(tmp, 0, sizeof(GF_Mutex)); tmp->hMutex = new RMutex(); if( tmp->hMutex->CreateLocal() != KErrNone){ - free(tmp); + gf_free(tmp); return NULL; } #ifndef GPAC_DISABLE_LOG if (name) { - tmp->log_name = strdup(name); + tmp->log_name = gf_strdup(name); } else { char szN[20]; sprintf(szN, "0x%08x", (u32) tmp); - tmp->log_name = strdup(szN); + tmp->log_name = gf_strdup(szN); } #endif return tmp; @@ -489,7 +489,7 @@ GF_EXPORT void gf_mx_del(GF_Mutex *mx) { mx->hMutex->Close(); - free(mx); + gf_free(mx); } GF_EXPORT @@ -562,12 +562,12 @@ struct __tag_semaphore GF_EXPORT GF_Semaphore *gf_sema_new(u32 MaxCount, u32 InitCount) { - GF_Semaphore *tmp = (GF_Semaphore *) malloc(sizeof(GF_Semaphore)); + GF_Semaphore *tmp = (GF_Semaphore *) gf_malloc(sizeof(GF_Semaphore)); if (!tmp) return NULL; tmp->hSemaphore = new RSemaphore(); if (!tmp->hSemaphore) { - free(tmp); + gf_free(tmp); return NULL; } TBuf<32> semaName; @@ -581,7 +581,7 @@ GF_EXPORT void gf_sema_del(GF_Semaphore *sm) { sm->hSemaphore->Close(); - free(sm); + gf_free(sm); } GF_EXPORT @@ -637,7 +637,7 @@ void gf_sys_close() } } -#if GPAC_MEMORY_TRACKING +#ifdef GPAC_MEMORY_TRACKING extern size_t gpac_allocated_memory; #endif @@ -697,7 +697,7 @@ Bool gf_sys_get_rti(u32 refresh_time_ms, GF_SystemRTInfo *rti, u32 flags) HAL::Get(HALData::EMemoryRAMFree, ram_free); rti->physical_memory = ram; rti->physical_memory_avail = ram_free; -#if GPAC_MEMORY_TRACKING +#ifdef GPAC_MEMORY_TRACKING rti->gpac_memory = gpac_allocated_memory; #endif return 1; @@ -724,7 +724,7 @@ void gf_modules_free_module(ModuleInstance *inst) pLibrary->Close(); } gf_list_del(inst->interfaces); - free(inst); + gf_free(inst); } Bool gf_modules_load_library(ModuleInstance *inst) @@ -757,7 +757,7 @@ Bool gf_modules_load_library(ModuleInstance *inst) delete pLibrary; goto err_exit; } - inst->query_func = (QueryInterface) pLibrary->Lookup(1); + inst->query_func = (QueryInterfaces) pLibrary->Lookup(1); inst->load_func = (LoadInterface) pLibrary->Lookup(2); inst->destroy_func = (ShutdownInterface) pLibrary->Lookup(3); diff --git a/src/utils/uni_bidi.c b/src/utils/uni_bidi.c index 4cc5d68..5043c14 100644 --- a/src/utils/uni_bidi.c +++ b/src/utils/uni_bidi.c @@ -10,24 +10,24 @@ * 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. + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <gpac/utf.h> - + /*------------------------------------------------------------------------ Bidirectional Character Types - + as defined by the Unicode Bidirectional Algorithm Table 3-7. ------------------------------------------------------------------------*/ @@ -35,7 +35,7 @@ enum { // input types // ON MUST be zero, code relies on ON = N = 0 - ON = 0, // Other Neutral + ON = 0, // Other Neutral L, // Left Letter R, // Right Letter AN, // Arabic Number @@ -45,15 +45,15 @@ enum CS, // Common Separator ES, // European Separator ET, // European Terminator (post/prefix e.g. $ and %) - + // resolved types BN, // Boundary neutral (type of RLE etc after explicit levels) - + // input types, S, // Segment Separator (TAB) // used only in L1 WS, // White space // used only in L1 B, // Paragraph Separator (aka as PS) - + // types for explicit controls RLO, // these are used only in X1-X9 RLE, @@ -86,7 +86,7 @@ static int bidi_get_class(u32 val); GF_EXPORT -Bool gf_utf8_is_right_to_left(u16 *utf_string) +Bool gf_utf8_is_right_to_left(u16 *utf_string) { u32 i = 0; while (1) { @@ -133,12 +133,12 @@ Bool gf_utf8_reorder_bidi(u16 *utf_string, u32 len) Bool rtl = cur_dir; u32 c = bidi_get_class(utf_string[i]); switch (c) { - case R: + case R: case AN: case AL: rtl = 1; break; - case L: + case L: case EN: rtl = 0; break; @@ -151,7 +151,7 @@ Bool gf_utf8_reorder_bidi(u16 *utf_string, u32 len) continue; } if (cur_dir != rtl) { - if (!stop) + if (!stop) stop = i; if (is_start) { @@ -1253,7 +1253,7 @@ static int bidi_get_class(u32 val) if ((val>=0x1D200) && (val<=0x1D241)) return ON; //# So [66] GREEK VOCAL NOTATION SYMBOL-1..GREEK INSTRUMENTAL NOTATION SYMBOL-54 if (val==0x0001D245) return ON; //# So GREEK MUSICAL LEIMMA if ((val>=0x1D300) && (val<=0x1D356)) return ON; //# So [87] MONOGRAM FOR EARTH..TETRAGRAM FOR FOSTERING - if ((val>=0x0000) && (val<=0x0008)) return BN; //# Cc [9] <control-0000>..<control-0008> + if (/*(val>=0x0000) && */(val<=0x0008)) return BN; //# Cc [9] <control-0000>..<control-0008> if ((val>=0x000E) && (val<=0x001B)) return BN; //# Cc [14] <control-000E>..<control-001B> if ((val>=0x007F) && (val<=0x0084)) return BN; //# Cc [6] <control-007F>..<control-0084> if ((val>=0x0086) && (val<=0x009F)) return BN; //# Cc [26] <control-0086>..<control-009F> diff --git a/src/utils/url.c b/src/utils/url.c index a53b910..1ae6856 100644 --- a/src/utils/url.c +++ b/src/utils/url.c @@ -70,14 +70,14 @@ char *gf_url_get_absolute_path(const char *pathName, const char *parentPath) /*abs path name*/ if (prot_type == GF_URL_TYPE_FILE) { /*abs path*/ - if (!strstr(pathName, "://") && !strstr(pathName, "|//")) return strdup(pathName); + if (!strstr(pathName, "://") && !strstr(pathName, "|//")) return gf_strdup(pathName); pathName += 6; /*not sure if "file:///C:\..." is std, but let's handle it anyway*/ if ((pathName[0]=='/') && (pathName[2]==':')) pathName += 1; - return strdup(pathName); + return gf_strdup(pathName); } if (prot_type==GF_URL_TYPE_ANY) return NULL; - if (!parentPath) return strdup(pathName); + if (!parentPath) return gf_strdup(pathName); /*try with the parent URL*/ prot_type = URL_GetProtocolType(parentPath); @@ -85,15 +85,14 @@ char *gf_url_get_absolute_path(const char *pathName, const char *parentPath) if (prot_type == GF_URL_TYPE_FILE) return gf_url_concatenate(parentPath, pathName); if (prot_type != GF_URL_TYPE_RELATIVE) return NULL; /*if we are here, parentPath is also relative... return the original PathName*/ - return strdup(pathName); + return gf_strdup(pathName); } char *gf_url_concatenate(const char *parentName, const char *pathName) { u32 pathSepCount, i, prot_type; - char psep; - char *outPath, *name; + char *outPath, *name, *rad; char tmp[GF_MAX_PATH]; if (!pathName || !parentName) return NULL; @@ -102,10 +101,64 @@ char *gf_url_concatenate(const char *parentName, const char *pathName) prot_type = URL_GetProtocolType(pathName); if (prot_type != GF_URL_TYPE_RELATIVE) { - outPath = strdup(pathName); + outPath = gf_strdup(pathName); goto check_spaces; } + /*old upnp addressing a la Platinum*/ + rad = strstr(parentName, "%3fpath="); + if (!rad) rad = strstr(parentName, "%3Fpath="); + if (!rad) rad = strstr(parentName, "?path="); + if (rad) { + char *the_path; + rad = strchr(rad, '='); + rad[0] = 0; + the_path = gf_strdup(rad+1); + i=0; + while (1) { + if (the_path[i]==0) break; + if (!strnicmp(the_path+i, "%5c", 3) || !strnicmp(the_path+i, "%2f", 3) ) { + the_path[i] = '/'; + memmove(the_path+i+1, the_path+i+3, strlen(the_path+i+3)+1); + } + else if (!strnicmp(the_path+i, "%05c", 4) || !strnicmp(the_path+i, "%02f", 4) ) { + the_path[i] = '/'; + memmove(the_path+i+1, the_path+i+4, strlen(the_path+i+4)+1); + } + i++; + } + name = gf_url_concatenate(the_path, pathName); + outPath = gf_malloc(strlen(parentName) + strlen(name) + 2); + sprintf(outPath, "%s=%s", parentName, name); + rad[0] = '='; + gf_free(name); + gf_free(the_path); + return outPath; + } + + /*rewrite path to use / not % encoding*/ + rad = strchr(parentName, '%'); + if (rad && (!strnicmp(rad, "%5c", 3) || !strnicmp(rad, "%05c", 4) || !strnicmp(rad, "%2f", 3) || !strnicmp(rad, "%02f", 4))) { + char *the_path = gf_strdup(parentName); + i=0; + while (1) { + if (the_path[i]==0) break; + if (!strnicmp(the_path+i, "%5c", 3) || !strnicmp(the_path+i, "%2f", 3) ) { + the_path[i] = '/'; + memmove(the_path+i+1, the_path+i+3, strlen(the_path+i+3)+1); + } + else if (!strnicmp(the_path+i, "%05c", 4) || !strnicmp(the_path+i, "%02f", 4) ) { + the_path[i] = '/'; + memmove(the_path+i+1, the_path+i+4, strlen(the_path+i+4)+1); + } + i++; + } + name = gf_url_concatenate(the_path, pathName); + gf_free(the_path); + return name; + } + + pathSepCount = 0; name = NULL; if (pathName[0] == '.') { @@ -146,29 +199,41 @@ char *gf_url_concatenate(const char *parentName, const char *pathName) } //if i==0, the parent path was relative, just return the pathName if (!i) { - outPath = strdup(pathName); + tmp[i] = 0; + while (pathSepCount) { + strcat(tmp, "../"); + pathSepCount--; + } +/* outPath = gf_strdup(pathName); goto check_spaces; + */ + } else { + strcat(tmp, "/"); } - prot_type = URL_GetProtocolType(parentName); - psep = (prot_type == GF_URL_TYPE_FILE) ? GF_PATH_SEPARATOR : '/'; - - outPath = (char *) malloc(strlen(tmp) + strlen(name) + 2); - sprintf(outPath, "%s%c%s", tmp, psep, name); + i = strlen(tmp); + outPath = (char *) gf_malloc(i + strlen(name) + 1); + sprintf(outPath, "%s%s", tmp, name); /*cleanup paths sep for win32*/ -// if ((prot_type == GF_URL_TYPE_FILE) && (GF_PATH_SEPARATOR != '/')) { - for (i = 0; i<strlen(outPath); i++) -// if (outPath[i]=='/') outPath[i] = GF_PATH_SEPARATOR; - if (outPath[i]=='\\') outPath[i] = '/'; -// } + for (i = 0; i<strlen(outPath); i++) + if (outPath[i]=='\\') outPath[i] = '/'; check_spaces: - while (1) { - char *str = strstr(outPath, "%20"); - if (!str) break; - str[0] = ' '; - memmove(str+1, str+3, strlen(str)-2); + i=0; + while (outPath[i]) { + if (outPath[i] == '?') break; + + if (outPath[i] != '%') { + i++; + continue; + } + if (!strnicmp(outPath+i, "%3f", 3)) break; + if (!strnicmp(outPath+i, "%20", 3)) { + outPath[i]=' '; + memmove(outPath + i+1, outPath+i+3, strlen(outPath+i)-2); + } + i++; } return outPath; } @@ -193,3 +258,32 @@ void gf_url_to_fs_path(char *sURL) } } +char *gf_url_percent_encode(const char *path) +{ + char *outpath, *sep; + u32 count; + if (!path) return NULL; + + sep = strchr(path, ' '); + if (!sep) return gf_strdup(path); + count = 1; + sep ++; + while (1) { + sep = strchr(sep, ' '); + if (!sep) break; + sep ++; + count ++; + sep++; + } + outpath = gf_malloc(sizeof(char) * (strlen(path) + 2*count + 1)); + strcpy(outpath, path); + while (1) { + sep = strchr(outpath, ' '); + if (!sep) break; + memmove(sep+3, sep+1, strlen(sep+1)+1); + sep[0] = '%'; + sep[1] = '2'; + sep[2] = '0'; + } + return outpath; +} diff --git a/src/utils/xml_parser.c b/src/utils/xml_parser.c index e4b1a88..e4b3c5f 100644 --- a/src/utils/xml_parser.c +++ b/src/utils/xml_parser.c @@ -41,13 +41,13 @@ static char *xml_translate_xml_string(char *str) char *value; u32 size, i, j; if (!str || !strlen(str)) return NULL; - value = (char *)malloc(sizeof(char) * 500); + value = (char *)gf_malloc(sizeof(char) * 500); size = 500; i = j = 0; while (str[i]) { if (j+20 >= size) { size += 500; - value = (char *)realloc(value, sizeof(char)*size); + value = (char *)gf_realloc(value, sizeof(char)*size); } if (str[i] == '&') { if (str[i+1]=='#') { @@ -182,8 +182,8 @@ static GF_XMLSaxAttribute *xml_get_sax_attribute(GF_SAXParser *parser) { if (parser->nb_attrs==parser->nb_alloc_attrs) { parser->nb_alloc_attrs++; - parser->sax_attrs = (GF_XMLSaxAttribute *)realloc(parser->sax_attrs, sizeof(GF_XMLSaxAttribute)*parser->nb_alloc_attrs); - parser->attrs = (GF_XMLAttribute *)realloc(parser->attrs, sizeof(GF_XMLAttribute)*parser->nb_alloc_attrs); + parser->sax_attrs = (GF_XMLSaxAttribute *)gf_realloc(parser->sax_attrs, sizeof(GF_XMLSaxAttribute)*parser->nb_alloc_attrs); + parser->attrs = (GF_XMLAttribute *)gf_realloc(parser->attrs, sizeof(GF_XMLAttribute)*parser->nb_alloc_attrs); } return &parser->sax_attrs[parser->nb_attrs++]; } @@ -200,6 +200,24 @@ static void xml_sax_swap(GF_SAXParser *parser) } } +static void format_sax_error(GF_SAXParser *parser, u32 linepos, const char* fmt, ...) +{ + va_list args; + u32 len; + char szM[20]; + + va_start(args, fmt); + vsprintf(parser->err_msg, fmt, args); + va_end(args); + + sprintf(szM, " - Line %d: ", parser->line + 1); + strcat(parser->err_msg, szM); + len = strlen(parser->err_msg); + strncpy(parser->err_msg + len, parser->buffer+ (linepos ? linepos : parser->current_pos), 10); + parser->err_msg[len + 10] = 0; + parser->sax_state = SAX_STATE_SYNTAX_ERROR; +} + static void xml_sax_node_end(GF_SAXParser *parser, Bool had_children) { char *name, *sep, c; @@ -207,8 +225,7 @@ static void xml_sax_node_end(GF_SAXParser *parser, Bool had_children) assert(parser->elt_name_start); assert(parser->elt_name_end); if (!parser->node_depth) { - parser->sax_state = SAX_STATE_SYNTAX_ERROR; - sprintf(parser->err_msg, "Markup error"); + format_sax_error(parser, 0, "Markup error"); return; } c = parser->buffer[parser->elt_name_end - 1]; @@ -275,7 +292,7 @@ static void xml_sax_node_start(GF_SAXParser *parser) for (i=0;i<parser->nb_attrs; i++) { if (parser->sax_attrs[i].has_entities) { parser->sax_attrs[i].has_entities = 0; - free(parser->attrs[i].value); + gf_free(parser->attrs[i].value); } } } @@ -327,8 +344,7 @@ static Bool xml_sax_parse_attribute(GF_SAXParser *parser) } if (!parser->in_quote && (c=='/')) { if (!parser->init_state) { - parser->sax_state = SAX_STATE_SYNTAX_ERROR; - sprintf(parser->err_msg, "Markup error"); + format_sax_error(parser, 0, "Markup error"); return 1; } } @@ -336,8 +352,7 @@ static Bool xml_sax_parse_attribute(GF_SAXParser *parser) case '"': if (parser->sax_state==SAX_STATE_ATT_VALUE) break; if (parser->in_quote && (parser->in_quote!=c) ) { - parser->sax_state = SAX_STATE_SYNTAX_ERROR; - sprintf(parser->err_msg, "Markup error"); + format_sax_error(parser, 0, "Markup error"); return 1; } if (parser->in_quote) parser->in_quote = 0; @@ -348,8 +363,7 @@ static Bool xml_sax_parse_attribute(GF_SAXParser *parser) /*end of <!DOCTYPE>*/ if (parser->init_state) { if (parser->init_state==1) { - parser->sax_state = SAX_STATE_SYNTAX_ERROR; - sprintf(parser->err_msg, "Invalid DOCTYPE"); + format_sax_error(parser, 0, "Invalid DOCTYPE"); return 1; } parser->sax_state = SAX_STATE_ELEMENT; @@ -363,8 +377,7 @@ static Bool xml_sax_parse_attribute(GF_SAXParser *parser) if (parser->init_state) { parser->current_pos+=1; if (parser->init_state==1) { - parser->sax_state = SAX_STATE_SYNTAX_ERROR; - sprintf(parser->err_msg, "Invalid DOCTYPE"); + format_sax_error(parser, 0, "Invalid DOCTYPE"); return 1; } parser->sax_state = SAX_STATE_ELEMENT; @@ -372,8 +385,7 @@ static Bool xml_sax_parse_attribute(GF_SAXParser *parser) } break; case '<': - parser->sax_state = SAX_STATE_SYNTAX_ERROR; - sprintf(parser->err_msg, "Invalid character"); + format_sax_error(parser, 0, "Invalid character '<'"); return 0; /*first char of attr name*/ default: @@ -401,6 +413,7 @@ static Bool xml_sax_parse_attribute(GF_SAXParser *parser) /*looking for '"'*/ if (parser->att_name_start) { + u32 i, first=1; sep = strchr(parser->buffer + parser->att_name_start - 1, '='); /*not enough data*/ if (!sep) return 1; @@ -414,6 +427,23 @@ static Bool xml_sax_parse_attribute(GF_SAXParser *parser) att->name_end --; } att->has_entities = 0; + + for (i=att->name_start; i<att->name_end; i++) { + char c = parser->buffer[i-1]; + if ((c>='a') && (c<='z')) {} + else if ((c>='A') && (c<='Z')) {} + else if ((c==':') || (c=='_')) {} + + else if (!first && ((c=='-') || (c=='.') || ((c>='0') && (c<='9')) )) {} + + else { + format_sax_error(parser, att->name_start-1, "Invalid character \'%c\' for attribute name", c); + return 1; + } + + first=0; + } + parser->att_name_start = 0; parser->current_pos++; parser->sax_state = SAX_STATE_ATT_VALUE; @@ -492,43 +522,6 @@ static void xml_sax_flush_text(GF_SAXParser *parser) char *text, c; if (!parser->text_start || parser->init_state || !parser->sax_text_content) return; - /* This optimization should be done at the application level - generic XML parsing should not try to remove any character !!*/ -#if 0 - u32 offset; - offset = 0; - while (parser->text_start+offset<parser->text_end) { - c = parser->buffer[parser->text_start-1+offset]; - if (c=='\r') offset++; - else if (c==' ') offset++; - else if (c=='\n') { - parser->line++; - offset++; - } else { - break; - } - } - parser->text_start+=offset; - if (parser->text_start == parser->text_end) { - parser->text_start = parser->text_end = 0; - return; - } - - offset = 0; - while (offset<parser->text_end) { - c = parser->buffer[parser->text_end-2-offset]; - if (c=='\r') offset++; - else if (c==' ') offset++; - else if (c=='\n') { - parser->line++; - offset++; - } else { - break; - } - } - parser->text_end-=offset; -#endif - assert(parser->text_start < parser->text_end); c = parser->buffer[parser->text_end-1]; @@ -540,7 +533,7 @@ static void xml_sax_flush_text(GF_SAXParser *parser) char *xml_text = xml_translate_xml_string(text); if (xml_text) { parser->sax_text_content(parser->sax_cbck, xml_text, (parser->sax_state==SAX_STATE_CDATA) ? 1 : 0); - free(xml_text); + gf_free(xml_text); } } else { parser->sax_text_content(parser->sax_cbck, text, (parser->sax_state==SAX_STATE_CDATA) ? 1 : 0); @@ -583,7 +576,7 @@ static char *xml_get_current_text(GF_SAXParser *parser) c = parser->buffer[parser->text_end-1]; parser->buffer[parser->text_end-1] = 0; - text = strdup(parser->buffer + parser->text_start-1); + text = gf_strdup(parser->buffer + parser->text_start-1); parser->buffer[parser->text_end-1] = c; parser->text_start = parser->text_end = 0; return text; @@ -641,7 +634,7 @@ static void xml_sax_parse_entity(GF_SAXParser *parser) else if (!ent && ((c=='\"') || (c=='\'')) ) { szName[i] = 0; GF_SAFEALLOC(ent, XML_Entity); - ent->name = strdup(szName); + ent->name = gf_strdup(szName); ent->namelen = strlen(ent->name); ent->sep = c; parser->current_pos += 1+i; @@ -654,7 +647,7 @@ static void xml_sax_parse_entity(GF_SAXParser *parser) xml_sax_store_text(parser, i); ent->value = xml_get_current_text(parser); - if (!ent->value) ent->value = strdup(""); + if (!ent->value) ent->value = gf_strdup(""); parser->current_pos += 1; assert(parser->current_pos < parser->line_size); @@ -712,6 +705,7 @@ static GF_Err xml_sax_parse(GF_SAXParser *parser, Bool force_parse) Bool is_text, is_end; u8 c; char *elt, sep; + u32 cdata_sep; is_text = 0; while (parser->current_pos<parser->line_size) { @@ -733,7 +727,7 @@ restart: goto restart; } i++; - if (!is_text && (c=='\n')) parser->line++; + if (c=='\n') parser->line++; if (parser->current_pos+i==parser->line_size) goto exit; } if (is_text && i) { @@ -746,8 +740,14 @@ restart: } is_end = 0; i = 0; + cdata_sep = 0; while (1) { char c = parser->buffer[parser->current_pos+1+i]; + if (!strncmp(parser->buffer+parser->current_pos+1+i, "!--", 3)) { + parser->sax_state = SAX_STATE_COMMENT; + i += 3; + break; + } if (!c) { i = 0; goto exit; @@ -763,9 +763,21 @@ restart: } else if (c=='>') break; else if (c=='=') break; + else if (c=='[') { + i++; + if (!cdata_sep) cdata_sep = 1; + else { + break; + } + } else if (c=='/') { is_end = !i ? 1 : 2; i++; + } else if (c=='<') { + if (parser->sax_state != SAX_STATE_COMMENT) { + parser->sax_state = SAX_STATE_SYNTAX_ERROR; + return GF_CORRUPTED_DATA; + } } else { i++; } @@ -828,13 +840,13 @@ restart: char *orig_buf; GF_Err e; parser->buffer[parser->elt_name_end-1] = sep; - orig_buf = strdup(parser->buffer + parser->current_pos); + orig_buf = gf_strdup(parser->buffer + parser->current_pos); parser->current_pos = 0; parser->line_size = 0; parser->elt_start_pos = 0; parser->sax_state = SAX_STATE_TEXT_CONTENT; e = gf_xml_sax_parse_intern(parser, orig_buf); - free(orig_buf); + gf_free(orig_buf); return e; } } @@ -845,7 +857,7 @@ restart: case SAX_STATE_COMMENT: if (!xml_sax_parse_comments(parser)) { xml_sax_swap(parser); - return GF_OK; + goto exit; } break; case SAX_STATE_ATT_NAME: @@ -879,7 +891,11 @@ exit: } #endif xml_sax_swap(parser); - return GF_OK; + + if (parser->sax_state==SAX_STATE_SYNTAX_ERROR) + return GF_CORRUPTED_DATA; + else + return GF_OK; } static GF_Err xml_sax_append_string(GF_SAXParser *parser, char *string) @@ -890,11 +906,13 @@ static GF_Err xml_sax_append_string(GF_SAXParser *parser, char *string) if (!nl_size) return GF_OK; if ( (parser->alloc_size < size+nl_size+1) - || (parser->alloc_size / 2 ) > size+nl_size+1) +// || (parser->alloc_size / 2 ) > size+nl_size+1 + ) { - parser->buffer = realloc(parser->buffer, sizeof(char) * (size+nl_size+1) ); - if (!parser->buffer ) return GF_OUT_OF_MEM; parser->alloc_size = size+nl_size+1; + parser->alloc_size = 3 * parser->alloc_size / 2; + parser->buffer = gf_realloc(parser->buffer, sizeof(char) * parser->alloc_size); + if (!parser->buffer ) return GF_OUT_OF_MEM; } memcpy(parser->buffer+size, string, sizeof(char)*nl_size); parser->buffer[size+nl_size] = 0; @@ -946,11 +964,11 @@ static GF_Err gf_xml_sax_parse_intern(GF_SAXParser *parser, char *current) entityEnd[0] = 0; len = strlen(entityStart) + strlen(current) + 1; - name = malloc(sizeof(char)*len); + name = gf_malloc(sizeof(char)*len); sprintf(name, "%s%s;", entityStart+1, current); ent = gf_xml_locate_entity(parser, name, &needs_text); - free(name); + gf_free(name); if (!ent && !needs_text) { xml_sax_append_string(parser, current); @@ -1015,11 +1033,11 @@ GF_Err gf_xml_sax_parse(GF_SAXParser *parser, void *string) if (parser->unicode_type>1) { const u16 *sptr = (const u16 *)string; u32 len = 2*gf_utf8_wcslen(sptr); - utf_conv = (char *)malloc(sizeof(char)*(len+1)); + utf_conv = (char *)gf_malloc(sizeof(char)*(len+1)); len = gf_utf8_wcstombs(utf_conv, len, &sptr); if (len==(u32) -1) { parser->sax_state = SAX_STATE_SYNTAX_ERROR; - free(utf_conv); + gf_free(utf_conv); return GF_CORRUPTED_DATA; } utf_conv[len] = 0; @@ -1029,7 +1047,7 @@ GF_Err gf_xml_sax_parse(GF_SAXParser *parser, void *string) } e = gf_xml_sax_parse_intern(parser, current); - if (utf_conv) free(utf_conv); + if (utf_conv) gf_free(utf_conv); return e; } @@ -1073,16 +1091,16 @@ static void xml_sax_reset(GF_SAXParser *parser) XML_Entity *ent = (XML_Entity *)gf_list_last(parser->entities); if (!ent) break; gf_list_rem_last(parser->entities); - if (ent->name) free(ent->name); - if (ent->value) free(ent->value); - free(ent); + if (ent->name) gf_free(ent->name); + if (ent->value) gf_free(ent->value); + gf_free(ent); } - if (parser->buffer) free(parser->buffer); + if (parser->buffer) gf_free(parser->buffer); parser->buffer = NULL; parser->current_pos = 0; - free(parser->attrs); + gf_free(parser->attrs); parser->attrs = NULL; - free(parser->sax_attrs); + gf_free(parser->sax_attrs); parser->sax_attrs = NULL; parser->nb_alloc_attrs = parser->nb_attrs = 0; } @@ -1107,7 +1125,7 @@ static GF_Err xml_sax_read_file(GF_SAXParser *parser) #else s32 read = gzread(parser->gz_in, szLine, XML_INPUT_SIZE); #endif - if ((read<=0) && !parser->node_depth) break; + if ((read<=0) /*&& !parser->node_depth*/) break; szLine[read] = 0; szLine[read+1] = 0; e = gf_xml_sax_parse(parser, szLine); @@ -1131,6 +1149,16 @@ static GF_Err xml_sax_read_file(GF_SAXParser *parser) gzclose(parser->gz_in); parser->gz_in = 0; #endif + + parser->elt_start_pos = parser->elt_end_pos = 0; + parser->elt_name_start = parser->elt_name_end = 0; + parser->att_name_start = 0; + parser->current_pos = 0; + parser->line_size = 0; + parser->att_sep = 0; + parser->file_pos = 0; + parser->file_size = 0; + parser->line_size = 0; } return e; } @@ -1146,16 +1174,17 @@ GF_Err gf_xml_sax_parse_file(GF_SAXParser *parser, const char *fileName, gf_xml_ unsigned char szLine[6]; /*check file exists and gets its size (zlib doesn't support SEEK_END)*/ - test = fopen(fileName, "rb"); + test = gf_f64_open(fileName, "rb"); if (!test) return GF_URL_ERROR; - fseek(test, 0, SEEK_END); - parser->file_size = ftell(test); + gf_f64_seek(test, 0, SEEK_END); + assert(gf_f64_tell(test) < 1<<31); + parser->file_size = (u32) gf_f64_tell(test); fclose(test); parser->on_progress = OnProgress; #ifdef NO_GZIP - parser->f_in = fopen(fileName, "rt"); + parser->f_in = gf_f64_open(fileName, "rt"); fread(szLine, 1, 4, parser->f_in); #else gzInput = gzopen(fileName, "rb"); @@ -1211,7 +1240,7 @@ void gf_xml_sax_del(GF_SAXParser *parser) #else if (parser->gz_in) gzclose(parser->gz_in); #endif - free(parser); + gf_free(parser); } GF_EXPORT @@ -1257,65 +1286,97 @@ char *gf_xml_sax_peek_node(GF_SAXParser *parser, char *att_name, char *att_value { u32 state, att_len, alloc_size; z_off_t pos; + Bool from_buffer; + Bool dobreak=0; char szLine1[XML_INPUT_SIZE+2], szLine2[XML_INPUT_SIZE+2], *szLine, *cur_line, *sep, *start, first_c, *result; -#ifdef NO_GZIP - if (!parser->f_in) return NULL; -#else - if (!parser->gz_in) return NULL; -#endif + #define CPYCAT_ALLOC(__str, __is_copy) if ( strlen(__str) + (__is_copy ? 0 : strlen(szLine))>=alloc_size) {\ alloc_size = 1+strlen(__str); \ if (!__is_copy) alloc_size += strlen(szLine); \ - szLine = realloc(szLine, alloc_size); \ + szLine = gf_realloc(szLine, alloc_size); \ }\ if (__is_copy) strcpy(szLine, __str); \ else strcat(szLine, __str); \ + from_buffer=0; +#ifdef NO_GZIP + if (!parser->f_in) from_buffer=1; +#else + if (!parser->gz_in) from_buffer=1; +#endif + result = NULL; szLine1[0] = szLine2[0] = 0; + pos=0; + if (!from_buffer) { #ifdef NO_GZIP - pos = ftell(parser->f_in); + pos = gf_f64_tell(parser->f_in); #else - pos = gztell(parser->gz_in); + pos = gztell(parser->gz_in); #endif + } att_len = strlen(parser->buffer + parser->att_name_start); if (att_len<2*XML_INPUT_SIZE) att_len = 2*XML_INPUT_SIZE; alloc_size = att_len; - szLine = (char *) malloc(sizeof(char)*alloc_size); + szLine = (char *) gf_malloc(sizeof(char)*alloc_size); strcpy(szLine, parser->buffer + parser->att_name_start); cur_line = szLine; att_len = strlen(att_value); state = 0; goto retry; + while (1) { + u32 read; + u8 sep_char; + if (!from_buffer) { #ifdef NO_GZIP - while (!feof(parser->f_in)) { + if (!feof(parser->f_in)) break; #else - while (!gzeof(parser->gz_in)) { + if (!gzeof(parser->gz_in)) break; #endif - u32 read; + } + + if (dobreak) break; + if (cur_line == szLine2) { cur_line = szLine1; } else { cur_line = szLine2; } + if (from_buffer) { + dobreak=1; + } else { #ifdef NO_GZIP - read = fread(cur_line, 1, XML_INPUT_SIZE, parser->f_in); + read = fread(cur_line, 1, XML_INPUT_SIZE, parser->f_in); #else - read = gzread(parser->gz_in, cur_line, XML_INPUT_SIZE); + read = gzread(parser->gz_in, cur_line, XML_INPUT_SIZE); #endif - cur_line[read] = cur_line[read+1] = 0; + cur_line[read] = cur_line[read+1] = 0; + + CPYCAT_ALLOC(cur_line, 0); + } + + if (end_pattern) { + start = strstr(szLine, end_pattern); + if (start) { + start[0] = 0; + dobreak = 1; + } + } - CPYCAT_ALLOC(cur_line, 0); retry: if (state == 2) goto fetch_attr; sep = strstr(szLine, att_name); if (!sep && !state) { state = 0; - CPYCAT_ALLOC(cur_line, 1); - if (end_pattern && strstr(szLine, end_pattern)) goto exit; + start = strrchr(szLine, '<'); + if (start) { + CPYCAT_ALLOC(start, 1); + } else { + CPYCAT_ALLOC(cur_line, 1); + } continue; } if (!state) { @@ -1324,7 +1385,8 @@ retry: first_c = sep[0]; sep[0] = 0; start = strrchr(szLine, '<'); - if (!start) goto exit; + if (!start) + goto exit; sep[0] = first_c; CPYCAT_ALLOC(start, 1); sep = strstr(szLine, att_name); @@ -1335,11 +1397,14 @@ retry: CPYCAT_ALLOC(cur_line, 1); continue; } - while (sep[0] && (sep[0] != '\"') ) sep++; + while (sep[0] && (sep[0] != '\"') && (sep[0] != '\'') ) sep++; if (!sep[0]) continue; + sep_char = sep[0]; sep++; while (sep[0] && strchr(" \n\r\t", sep[0]) ) sep++; if (!sep[0]) continue; + if (!strchr(sep, sep_char)) + continue; /*found*/ if (!strncmp(sep, att_value, att_len)) { @@ -1353,7 +1418,7 @@ retry: state = 2; if (!substitute || !get_attr || strcmp(sep, substitute) ) { if (is_substitute) *is_substitute = 0; - result = strdup(sep); + result = gf_strdup(sep); goto exit; } sep[pos] = first_c; @@ -1369,7 +1434,7 @@ fetch_attr: pos = 0; while (!strchr(" \t\r\n/>", sep[pos])) pos++; sep[pos-1] = 0; - result = strdup(sep); + result = gf_strdup(sep); if (is_substitute) *is_substitute = 1; goto exit; } @@ -1378,13 +1443,16 @@ fetch_attr: goto retry; } exit: - free(szLine); + gf_free(szLine); + + if (!from_buffer) { #ifdef NO_GZIP - fseek(parser->f_in, pos, SEEK_SET); + gf_f64_seek(parser->f_in, pos, SEEK_SET); #else - gzrewind(parser->gz_in); - gzseek(parser->gz_in, pos, SEEK_SET); + gzrewind(parser->gz_in); + gzseek(parser->gz_in, pos, SEEK_SET); #endif + } return result; } @@ -1404,7 +1472,7 @@ struct _peek_type static void on_peek_node_start(void *cbk, const char *name, const char *ns, const GF_XMLAttribute *attributes, u32 nb_attributes) { struct _peek_type *pt = (struct _peek_type*)cbk; - pt->res = strdup(name); + pt->res = gf_strdup(name); pt->parser->suspended = 1; } @@ -1441,7 +1509,7 @@ struct _tag_dom_parser GF_XMLNode *root; u32 depth; - void (*OnProgress)(void *cbck, u32 done, u32 tot); + void (*OnProgress)(void *cbck, u64 done, u64 tot); void *cbk; }; @@ -1453,9 +1521,9 @@ void gf_xml_dom_node_del(GF_XMLNode *node) while (gf_list_count(node->attributes)) { GF_XMLAttribute *att = (GF_XMLAttribute *)gf_list_last(node->attributes); gf_list_rem_last(node->attributes); - if (att->name) free(att->name); - if (att->value) free(att->value); - free(att); + if (att->name) gf_free(att->name); + if (att->value) gf_free(att->value); + gf_free(att); } gf_list_del(node->attributes); } @@ -1467,9 +1535,9 @@ void gf_xml_dom_node_del(GF_XMLNode *node) } gf_list_del(node->content); } - if (node->ns) free(node->ns); - if (node->name) free(node->name); - free(node); + if (node->ns) gf_free(node->ns); + if (node->name) gf_free(node->name); + gf_free(node); } static void on_dom_node_start(void *cbk, const char *name, const char *ns, const GF_XMLAttribute *attributes, u32 nb_attributes) @@ -1488,13 +1556,13 @@ static void on_dom_node_start(void *cbk, const char *name, const char *ns, const for (i=0; i<nb_attributes; i++) { GF_XMLAttribute *att; GF_SAFEALLOC(att, GF_XMLAttribute); - att->name = strdup(attributes[i].name); - att->value = strdup(attributes[i].value); + att->name = gf_strdup(attributes[i].name); + att->value = gf_strdup(attributes[i].value); gf_list_add(node->attributes, att); } node->content = gf_list_new(); - node->name = strdup(name); - if (ns) node->ns = strdup(ns); + node->name = gf_strdup(name); + if (ns) node->ns = gf_strdup(ns); gf_list_add(par->stack, node); if (!par->root) par->root = node; } @@ -1507,6 +1575,7 @@ static void on_dom_node_end(void *cbk, const char *name, const char *ns) if (!last || strcmp(last->name, name) || (!ns && last->ns) || (ns && !last->ns) || (ns && strcmp(last->ns, ns) ) ) { par->parser->suspended = 1; gf_xml_dom_node_del(last); + if (last==par->root) par->root=NULL; return; } @@ -1528,7 +1597,7 @@ static void on_dom_text_content(void *cbk, const char *content, Bool is_cdata) GF_SAFEALLOC(node, GF_XMLNode); node->type = is_cdata ? GF_XML_CDATA_TYPE : GF_XML_TEXT_TYPE; - node->name = strdup(content); + node->name = gf_strdup(content); gf_list_add(last->content, node); } @@ -1567,7 +1636,7 @@ GF_EXPORT void gf_xml_dom_del(GF_DOMParser *parser) { gf_xml_dom_reset(parser, 1); - free(parser); + gf_free(parser); } GF_EXPORT @@ -1578,7 +1647,7 @@ GF_XMLNode *gf_xml_dom_detach_root(GF_DOMParser *parser) return root; } -static void dom_on_progress(void *cbck, u32 done, u32 tot) +static void dom_on_progress(void *cbck, u64 done, u64 tot) { GF_DOMParser *dom = (GF_DOMParser *)cbck; dom->OnProgress(dom->cbk, done, tot); @@ -1624,7 +1693,7 @@ static void gf_xml_dom_node_serialize(GF_XMLNode *node, Bool content_only, char vlen = strlen(v); \ if (vlen+ (*size) >= (*alloc_size)) { \ (*alloc_size) += 1024; \ - (*str) = realloc((*str), (*alloc_size)); \ + (*str) = gf_realloc((*str), (*alloc_size)); \ (*str)[(*size)] = 0; \ } \ strcat((*str), v); \ diff --git a/src/utils/zutil.c b/src/utils/zutil.c index 884630f..93d7317 100644 --- a/src/utils/zutil.c +++ b/src/utils/zutil.c @@ -3,7 +3,7 @@ * For conditions of distribution and use, see copyright notice in zlib.h */ -/* @(#) $Id: zutil.c,v 1.1 2006/12/13 15:51:06 jeanlf Exp $ */ +/* @(#) $Id: zutil.c,v 1.2 2010-02-23 16:24:20 jeanlf Exp $ */ #include "zutil.h" @@ -189,10 +189,10 @@ void zmemzero(dest, len) # define MY_ZCALLOC -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes +/* Turbo C gf_malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). + * original form in order to free it, use zcgf_free(). */ #define MAX_PTR 10 @@ -237,18 +237,18 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) return buf; } -void zcfree (voidpf opaque, voidpf ptr) +void zcgf_free(voidpf opaque, voidpf ptr) { int n; if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); + fargf_free(ptr); return; } /* Find the original pointer */ for (n = 0; n < next_ptr; n++) { if (ptr != table[n].new_ptr) continue; - farfree(table[n].org_ptr); + fargf_free(table[n].org_ptr); while (++n < next_ptr) { table[n-1] = table[n]; } @@ -278,10 +278,10 @@ voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) return _halloc((long)items, size); } -void zcfree (voidpf opaque, voidpf ptr) +void zcgf_free(voidpf opaque, voidpf ptr) { if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); + _hgf_free(ptr); } #endif /* M_I86 */ @@ -292,8 +292,8 @@ void zcfree (voidpf opaque, voidpf ptr) #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); +extern voidp gf_malloc OF((uInt size)); +extern voidp gf_calloc OF((uInt items, uInt size)); extern void free OF((voidpf ptr)); #endif @@ -303,15 +303,15 @@ voidpf zcalloc (opaque, items, size) unsigned size; { if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); + return sizeof(uInt) > 2 ? (voidpf)gf_malloc(items * size) : + (voidpf)gf_calloc(items, size); } -void zcfree (opaque, ptr) +void zcgf_free(opaque, ptr) voidpf opaque; voidpf ptr; { - free(ptr); + gf_free(ptr); if (opaque) return; /* make compiler happy */ } diff --git a/src/utils/zutil.h b/src/utils/zutil.h index 4b61258..ba95f4f 100644 --- a/src/utils/zutil.h +++ b/src/utils/zutil.h @@ -8,7 +8,7 @@ subject to change. Applications should only use zlib.h. */ -/* @(#) $Id: zutil.h,v 1.1 2006/12/13 15:51:06 jeanlf Exp $ */ +/* @(#) $Id: zutil.h,v 1.2 2010-02-23 16:24:20 jeanlf Exp $ */ #ifndef ZUTIL_H #define ZUTIL_H @@ -95,13 +95,13 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ # if defined(__TURBOC__) || defined(__BORLANDC__) # if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); + void _Cdecl fargf_free( void *block ); void *_Cdecl farmalloc( unsigned long nbytes ); # else # include <alloc.h> # endif # else /* MSC or DJGPP */ -# include <malloc.h> +# include <gf_malloc.h> # endif #endif @@ -122,7 +122,7 @@ extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #ifdef OS2 # define OS_CODE 0x06 # ifdef M_I86 - #include <malloc.h> + #include <gf_malloc.h> # endif #endif -- 2.30.2

    kLD((Pmu$p3xLPaC9#g! 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

x(iRmCjEYhEK+JvOS!@3Y(aC!>eW% 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,!|EuI6I-ZM}rU#2mWJ0i9ia@0U-mVQ-5;^A#Z)L zmaQTlo@AXAVVSWIgy_6l$zl5M0V1-|c`#aPsdWxc(SnxX#cm)(-YwR01TotLg!t$) zi-1N|KuAO`j}luxW1S@;9Sf%wAjI|uj5AM^Fi}5g6BkAo3^5Sm9mk@hHwcMp$D*S> z2(gEAX;p>%?H>+M!rz|4%%#|;t5(!H!0!FzNghWDtbx9Y)<$Mq_82+$^%W-Vj6G2F**QjPD zb+l0lg!pKIB?lz^ZZ#_{=5s6`-U1=oI+mJ`fsklwVo3@)?gAm&HnIo|+iO8cyfugt z?Ldew&Uk}LhZ2}3-k34hTi<*HJXO32t}=x`hj1fG97mW_K#0K{N0@^_NO-)cRu3E( z6qd+@-9U)JW>^HYYyv_I=7{?$AS8esv)h&rSr-W)#~@z;LX2)7ltPXtL3Gh`xx*eY z5bZVLut#qYGV*MDVC~T!gjmeB2WI=DKu8ce?D6LZtgYD8VUM*SWOlLbfnMfyhDAM>2SVb*J~o0)F9spnI&^6YLUgeYh0w-9AjJE(SSwTz->As2?n|QWdhSA7-q}_6H|Dq1S7bzv)>(Jh`}7rZvjFA$Z>jfFbFY+ zVGGD2nis^=}})0VsyvWvona6I(^vA$B=6P zLc*iS3NfUQGIlRc*J5g4^R8tUJ4(>m91z{KICeaPm;$1`ChT~IID?5u6F@A989*Hs zo+^L@4+7{=^e^FYvO4UgHhIJ$fVcmfwG@M;zDD^rK#8N&*C=NIlzik_2h8a6P7pHw z%14Q-Ku9P!orI=Z5SYe%GN4rK`sEd#%6x(c=KJ^^HcngZKF5aqWe^gPjt%)eAY=?X zHsrU05EnQ$GDUk11X!&R8d2V7V{Y zRvkql=HCZUqVG%>Sc|~{0L21rTp%7a>;y1<5aMw5NPrSz_VkUZX4l)SMfwm!9#}2A!e@;kVCqGkU7y_BY#f|v_J?D1@rxDP}+d*p#gXOD|PNPL5Sh1-)&|hxcF)iVitSq1ajykCp;YmCXcKLGC|JxUnN%ug=Gq3JzKP zF*ecKA{g|0fe^(IxxWzLTwNd$d#-%VD#N@vZUe`dx8M5286g} zk97(TIp%;6x9qS8$T0^KILC9d(Xc6e88whdj5=&dO(FBC#2uG+_v57I~ zA_xP&V3ymm#PXb@jTIooFLSIjbXe?35MuS&7J*)3AjGE2tqa5;dV`Sk;n-@l2O&0f zY$T2XAvSf)Lw~-(+KNpdwuV0BSPMep;}q+p7k-%wLUcJfO56uR;^Vj|k!Q={9Ja@D z$e&AKnqkX~xlO38@KnQA@L<^fu-F<5_LPck$~z!LSx0z0145K_OsNSF;#$X)dLsyN ztz$~<2qK+p>w{2=k;P_2r{#UGTh4bZLe_(j1ap#=Z;_-HfRON5XPu@tV2|AoLM&#l z*)d#(fe?GxDG0M%cMwhW;?S|XXaPb7rDJz-FbJ`jy}Lj!Kb0c3GOqiV6KAaZ<5nVq zMo-v;<20fWgjlwh@(zzDJwaRtLXt?2C~+nTv8>}nqYenMtRv0*v50jMt2olkXCNew z9G8Y)10hMok%;aE(MtQzv40!_Lj31QRTqH}i>*;fgw3rjb}|UD*s3T|6@)~qL(;7a z*&brkx2!hc+qXf8O&xdZJq1E+>bP4k4ni#E@Z9wvT55~sS|g9c#6Js!jEQ~L$ivvI z3qq{!$W?n5u(r~MBThdDA%2;8vU$5a>@g37SUtE}68HrfU@8c)dT_NQARuWz2(h{| z{bPup2T+Xf2U-meTov~{Gj&2!lv60VLT++`rd9**Jr zI0(@tbwJ-vV4C#|2fewTIZxrK)-!@DJNtDYh75+LR*t}c`r|e9pYf$Q9}!p5Q3A~| zU%d$8JRQ!v)VUg`D$39GIb;13L?=yrA0-BWXsd}$QQ}-%j!mw94iDIcbC5jLIU1#clo0rB;XxkG#Z2iiDNdp8iZuupDq8fY5g`JB;Xwzydyw} zw%=N9AkF;#Dr+m**Rh8C7=#3T>Kg!O0~D2;G`O?`H|_7ygcG-V%-za2tSPeCJJIxWB$SK=FY+hnY8l`7a?dZ&n88J#cZy zhJlR{l4_v%ZzwL~&0_Z}F5}H&w-Hy;Q3OnVk)R7eiIvnB3F-oriR?&g2NQnea{Bml>is+T~dANe>?C?YV;$Y;hJ`8^e$YUB$ZjQkTJhJ@$oY9LXYvP-B0 zLV~ZkHPiyDU~1g(0$WA3O9F4Q&dy-BQV^oEW5x0ih%S1>IqvEl2|`A#$Wpi@DJ(%Y;JDW={-L5R|hLy7JGVr^x_^{}Q1?#y2WLITu2@o+bhm%^a)wfgq~sXmPCO&jTS5=UC03077EH z;m2GMVn5rDQ0d#}Sa-3G!;ecrh;_A~Mcc!%d~Hhv zjm?b9*F({g%$@~S%wP;{pUpbUNF5R-R)LUl*v}$V{DTnN_l^=1>^6R}&V7TZs>8;) z9-z3uv5Gwlgt%atbwU7@>VlBSTx1a#YB_R51Iqc0cu5&d5ag`<?JdWd|BM1rT2P^`?SRX_u-Ns~# z!26ZL;5L}T4XS8I*}F~}BY zd{p2IY&ph6iNBceoQ5Hf6TjS`!mwgyGtD6tHLg#7jN^Elz9Ot|N95LL9cS6Xer zVq=J)%$4!5xhGnZP_P3Z>y%a?B;f48hh=MkklbbmKHAvv6zeRx%@Oz?f{@&12R_<( z0fa<}W9GRVgv5Y7^I(0@AB1?vG4pfGKkZcYEA|o&NqYR$4|zHP^oTNVf2s0F{R+ z7E*7gA0Uu`15`_FH~P_KvLMTaeVz(9e=r)9QQ)}Cpc@D=mE#_QCLqLAj(Z5IfDltT zE;VkM$rcb(68Adk9e^;5q4@M`MVwg z_pr(Fc^4}KPK_4-1I68Ka{S&2Hk=v8&nRw`$?<@f_SDGn?;@_GqgXOe@zfam9PxWC z2(e^8i@*qL2SO~_%OcRmks!p9-7Nxb?0T5x5KB5D>r)Vtn$EP^V1fNtK}g&@Z_Or{ zD<*@G(fWi%K+@Ylh&`r9i3>r9J?@DTCxH-c3oN2OOL`y((Pdzi@TapqRB%xIToWah zgJ`J7Vt0#xE>D1{r-^f;L?H+jTGUJHC~+N#n!1f9QQ}MxGFjD%5_LdS(`{6Z5`R3z z+E&rTpK7V3;+7)$>E zag`>PMu}rUh`r}UiE>1cudGvk&W;Vp^JaGZ`~h%1)x4*&sOxIL%Zkf*HK15=8LtLh zPh3gI{#r*z&N&N&*y$Q2A&JkC%WC*_LG;pXIA)?f_j4~jG~u{p^f`z;O*k$)%>yw= z6OQ~j6@-jr$L*o{AY`06mUfqbka6l*+BE|qqp+EE1cBQ_JrEMBj@xB_n8x;yAidOT zgH7wd1EQ(c*4`*%K6wU2V@-6i+CX+pfRGH^I!fFKqM>eMvU*`^kd^oZ+wTZMGOWFj zMKAS1NQQMRsP|2^ykBC;fe2a;LbB56D6s&9WTpO5;(id4b9z|>{4xxLBpb*2usaBe zqr}i5JCAq+cS%=rvOj27vp&VvqUbs^j{_1 zxMgTmRKm$1WHgS561RbnESVoAE(B3tYnl3h=2!wr+0)b$ziQIrr8-}#G|+V4E7g5BK}MoxbNm+p%|#dL^`Fbs%dPoa>YP9P34mUqf9jSN zSP(L3UqCMy(90Ht0p9`8Yy+AVh3Wu$+JGLlAo?Q5-#Ll3d)$DgSP*3T2+#}z8fQWD zMUMYGpoa|TP76XyMS!Lm&@c;vb~gZ;VnBnU(3yZH8c<&gqAzm%T7V`P(3KVhnSQ;8 zO)$=YF18@Zv0p)U*z~>8R~e44uR$t0fBA+Fd)>iH;2OaswNx3SP7 zAjeP;GI_mV5s>3j5Hfi^Wf730IS84&9*z>#K*;1Z*&-mvkN;$Q$mCUM5s>5GAY}3y zY7vm*SrDDHw*8{SI1ueM(bFOzM;{O}d7WbskfRd_S*W$Khzit*e>4c0cutBEIUr=> zsbdk4ECeA*d#`$51XrdA!sWmRK&XUEIeA-@7!E?sBt&em2*`06 z2ub{FqC`t33VV?Uw6II83=P+KfUYv2`B7*~3Afb4fL@A1Zvnd0fS!#)GXQlnpqWwV zc0lJD&;wEEGC*AnXi^kv2B?z(jgLZA0JSxs(F$U3lFM+`_}v6HK~n?Dvmp3&37|#> z)X#!&7C0SHJp;PNf)J_00o631ODza{-b(;gGoUUOgoShyKvfK=tp)KM>{kNBCu}-Y znphAHLccC%6YL;fL-i~ums@%r(Dw#(m<2Up=m9{R4XCmOVHo8D+F(HY)S4u4OMPys z8=!Rtw8Mf(BYOW6pw$NCTM(|!RsgiZfWELGUMKk*$Fm8R8qjJBqAzm%g#^)@&eG!BbFSZJ0N#x(H=*1?@YoQ=lfPR|(hRyw6ik@TAk1JZAr54Is!*8zW*(S}4 z3~HOB3~kF&!7s1q$4r{n2t@0(ZD9=6XesA^QUoohnRJ1o8v>#qPgQfZKTDw{2HG)? zS}m_RH6QzhiYqX={=_xXoSISnD-}1y-b-dgUa1at`%_{iQt+lCoNFixhB_`I1WZ|YJTx2EAA|l<8vgAM{u=O zd$$lrznfXOnSPqMC;vOV0nvH3hI?C2B@i_l*){B6mB2_lP@{VinH#S{!ug*Oh{oTs zYoxvj{3%`Ie$^j|}m(vI7I!};6QRfP~ zj%`6$y=_n@-UO&D#2nA39IVlDKqV?u--GvMEKp*bR$>K}828KB0&z<6XX!d8={i$T zM+C8U44g9H#SHdK zfjMpZUls=XpGwuy#|kPjhQX7SB5zlm71W7O2b!+=0*wv^Dnb8kbfeZiKw}+sXqmcG7j{t%#&TADtKEX3I`$ou|pV**9TYh!*%C5ECi)g_&v4%N)@mjrdnSv+f7Zd z9@&7myMmB$Y0s2%18(b;z+98!Vr#Y@grBhDaydJewG#&TWH$;}3r-2nk91{wz2(A4CdcA~9S- z1XcYyVy645^~T}v2QmC_N&oZpRNoh3XRw+g-mBArzpv)f4hRK&=P zP4xhg!Z;B4)QoK$nyw9)W&0hO9K8yJ$dPZ2n&5Wn8tm_<0E)lu2R&$p$?@ZMQ;xxN zJ&0rHhGK}aw5^Z$st%@1j)k zZ_9DKI^g23NZY`)HCgHN0E%f_HaG8;J&1`D?51qf9>+v32r=!^R%Zmz?>~;T%wo6E zh>4{jWL9<Hk1iK%DHHr2Z2sHD-K%)7#j4-2oPK?_`=Lc;n=QWj zO{(L?emR=J-Q~R4C;X2sW$-(^`S%BWPK5s#jUq3xfWnGkFFs%&{SK^Zd)l((whsh5 zBoHO<*c|%(>5v~B;ZFqryJ{Q1Hyp1T@@GW&LP}#^;;X}zs%U@xUXkbFx02;K675$q z<#{gT$4B^L@F&wdCfSr|e^kgFL1{Ag~L{B_CFNW#%drJI17xH@}^G8Qo_<4zEs==7S{1@_rUQ3q$ z59G(GhZy|%A>S>+*JZI;{<0!}osi!fwWpT9x5)p)Z=&z_5q>IXYHoj|O4($eMIrxE zWPJamT5^8+)~IV$A8j__^Z|BZBUMe@!0 zA)gcR&ykc*y+kF`esw~AY-GK0CTD8)=g}%LB^+gnU6HA6>|i!umE>A;bRPF8baO;S<~}^EXTTi$ea+i2axA z@$syTkCKq@6X6SKS?VP|KG3kw)ggaqBz}K^eO@&4=}95KBa#vx(fW=NefRt<`c|>x zms7~+6y{!HvT6T!Lw<84A3TWo{HBs2|MZZ5Iug$bov&|}d_5rK$3*ydpzn94Jnce$ z!<^*#W2zqCBV~M74f&-Jz9ZTnWsa})+r&PxNId^j%RgA;e=g*2i0}(&8t@XYn(dDY z`Mr_&AExE+De|8m@}ETb7HI!hGk)rX{B|pzIX~ruU(T?;Wan4c!TYP~T+P?-{v`Hj zY5AYqdm;StDCGr?N1N+rjhY{t4&)y-odWpK`c&Hlk z)g$~ZkpE>m%@_Z!|6c4N^7x;frY3i&f4d>iD)pUN2a+_OdW zeLONBB(!~Q7W=##^5Y}C$C|QzwyPmY_M9H_QzHKQNw@!@v_Bx^$42-BH_PqcEbX@o z`DGD(&(!T7E$vqg`KKfNFSP%o{aKD-pY^`jXKo}vJV?XVOFU-9f5^|U`7&PY5hiIa zh$lj7X=I}K85C)`I%t^Aq2t}d8jssG2pooeYk4nza!9STdnf8`O;rl1g|-igxM>gSm@(JTjzeL_GACZtK@?#S-%)ZPnFsy&qBq zcJ`tkKf`K*dVD6N9=Ff*i5jBYDh#Qn_R5~9cDk*rL+Sl1<*wa=jQ*H$+Cqky@_ekh<8Ofk>`zG<9Q0ZI9TiqW1QgA+;=$CqC0U9uZPg zB5h5^nuB!wWs_Lq>xk`-(Q>^TQWYXG@g24})YelW)iPqQpLJVzh1BLqTSK&5SBBI> zk+#}l#Ya7!5>mfKGQg);mk{NJ)WeZ6)J)6eZxl;3iTLq$E!UeNRVxx-1GHSzL#llw zzC7LIu#hSrk!zRk@gjqY$kjmicw$IBAEA!Xk#j&u%{F5qxc2;S(}qFWDl=MxvQkIc zG*i!jyW3G#>geMkN7)ini=e%i9A!OBF9h5LjM<3TX%I2Ce z9>_PvQTCprY?-5Mp~I$6JIczN*J*-&cbeHED63{>@1QK#QTC(5R$ClpI~+1^ag-h9 zsJq({2jd-e2RX{dI&44EQP$1OCV{?f9c5D-^4;VpTj#LpN=I2O^EzA5?+%BL?r@Y1 zca+U`ludJ#O>&ftbCmUQl%4G;Yj3W{0zDR+^Kno%!Qso{j}JQ<>g6bV(qV c3%cy=I_qsiW*$$Jko!DBI~M+vX_i<0!kvQMSP$^S>QsTO2X8 z$x(K(!&aRfWnCP$Kf_U0*3rjK2Up9%RdE296pLUV*Fc&d}ADSw>jc|n?v8`4*4E%^fA-bhr^~d9P{}$ zM;}Ky+RJm;?SSEN5Blg^>^t>fKgQ4!*%U@L7`Oszb&hF0DmgRWGoog=7*|%@>zT(cc z@sH7S>5^v7)o)UxbfKseCrJKli|GR74xpQpz?ec=2;Jt$Hj6niWj$ zvDxCn-POHB9pXuc+^1QGa(yOxu^-#2=SJRWZtCI1f9B^ASdQ|LgZ@u)NXvBaex~Sh zpqF@)XlnOTv|EjePlp%Y>AJr}7!k!gu!9VxT(H)m`__J_lB`-0EDo_l@l&i#!v!POX z`FogBQU4u3UH79jRsDSKy}cL_LI2SG#6R@nRWw`{LRGPavaET4m-vDnNgyZBhD7Rl zAurbK6vR*AIZfD@S;b2wFIEY$-;wH&o%s2s_+9+G1J@@ZXzZjDg&fmKJEp6yrqoRx z4<#M;6z(J?j(`&JrBH%g^g>gXLE<#Ni=RsfJ$+DMl7iQhM-&{~TGjUAOR}#LP>nlg85y;uljyWr_ z(7?Odu2vbeE2VNc;~9(4cd3H`sl>CJPMtd`+k3G+C$UB((HeemA?$<eFR6WY$i=%3cT`hH-BXlp-w3#ejqXJ{_1DZU&#AU~GSLK6sOZ;HnggG9| zhT}0vc-DBV;3d}5V+j-$!(qMhG|!hinVS_m#@<3s598w*evX0dXNoElZqgJJ+Xj1( zTLEeeXaDsBG7w@2}neMC>QO~kB z4a4u?y^1sq;vbZ!cky!vVZ19lWoU>3`E|-I2;_No{nYD5HrNCWXEGR4aDnclyRN2` zO|#D4QjQnChj@vGRE6Sp1tR1CirXVeVH&TAlW0G{!$LoIvx}cYVExUE>W){kUmr@{ z^xy{hoyH~BG4phN(-Cxk9Q}y}bitWeNaW;ZtWZ`Z&2kOOtt$AtmmEOGyblV-YHmZY)u?QrM2F{li$kZ5Q> z*8=}IKy71Goq6+16W<&TcG~~(BL|@oQp?W)uvEi#l8-K$8NP-do-tacf2)D< zdUS(Iw(Ja~z{^gtR}hUV8RbXQc5)*HDph{$p6^mpc1VRfP{SM(Ad(UcNuK1&N6 zGJ2r*E`AOn)LR*lZp%p$GpAs5r=V-rsY$&+C)IQ6Xr`^cm$;Yupq^WC&vd-Nc|UO% zm0|tS!; z)%@@R8%e8-73n;44Ian zFifWH3825OrN6E_<%XmPGWPU_+f%Pu42X0zQ)zNbD$l204xpv1ASJlUF|OsSDM9B{n81WmPDg)p zqEg*uFlJWSO!;pAM(O`sc}Dps_2$BeK0?#wK4psx+GQ0Ee>0R-^eLG#Xs1k&`ih8Q zOhVIbJyc8og?P(i2AzBFqB3mC^kNz_0~ASla#=ci-|a^{Wza6TXqG-yRAgot!G9gJ zA9+#B6dd`weHYnA$yV02#QCe}8PMV5F;m(}#drog{TH&Xjs1UW%&g++uY*+3 zsT7^T;)JGKTB(-)X6V0y2gi7SoA3SyT3n45wZx%UQ>ip83)Y;Ro%+sv=w-#!y@(`1cR z)+PSb>v_CUfKcKxKyv5|_|$g$I@W!zF)Mpw%migd5jZ|JR(7hm~r zhqW?DOWkhN-HzAwGe;8NZU-lkl9%XeL2%1mKm<)g+XOYyP^Pwx^#q~jd7FE3$O=+{ zllIO@qu&fy@f{a=mF5}hWy%zW1nLkmLvGEWx$2H2`-^Otp*wSgr;RzN`F~NkinJt2 zHp<=((d*@@)2`vDte~tc_t!zGvy36Qf+zzm#?3lLDl#CI<}-w0>WR|ubXImsatrnA zxHm`*<+L{e8XEj3wCkoD`;1n_dRBupgLPC(O3KWmX8-7{&VN%Tv#dOp6_g<@Dy1?& z6p6GF$|@eIy>v$|`)9-doOZ1;+FK|6X4{#kCTGS>9wN$2gr>8AX-k?@BR5GJ!#0C0 zDT$C*{LYPB++F~ zAz3wJIUe*ZFuMcz&FJo9}7+xpDqozJ+uzuA=91V!yi2 z#5aTchUd~NAiQg$thZ1 z^yV*5dQ+EplNL97yVa8X>P0JxYd0(=vY5!C@9CNLdF-XqPe+`QQ}pF8PtN1*jH=LT zN!|zZs_>WB#;7U&l0}j)Ur}G)qQ7K)YJ^Qm44bZ3Cx8ki{UI%kK8?v<*Oj4}1PO=wES(?``&^pOpyi6$lLo1YIFPMXW;1t?M z?N!j`*8C$2ZZ9)1|FDAF%jV2ugW>srSPxRM&qQVLcMDVlQEOCWYn()A=J9-I9Pxwx-w%MO#j=i{|JrN+ z#v6iS4ck4N{KSiq(hb^;N%2MR2hJ(oroT*zFMPRIf9Z;^D)E%#Z65lqqX9>Jq4|?E z;D|2(Z8X495+<-iIDsL?&(Q#zB?Pw9dnx95tX@wIaJ+`V2Mo~LcXLYnX@Da>1YQte zs0Mgu2!Vex05uCWz{xEH1~P!zWU>ah!w}$~GF6HEVGXd-A<$TWr!>Gig}{LfAf>*b z0hTBPw$O_x=FzL?b4nL#fXx;HZ!V7!2rFRKc{q$ z26$=-fj$ht4u_2m0){&bfzAvdoz&An4GU-}!0{Sjox&E%F#tO>*8oct0-NaV6iS9O zG(bNAU;uA002$8F0R8rp0n8BKVhzxbX&At01|Y+g8lYc0F@S5Ng}xe~$CnI%f67!% zM1wRyzgJ@bwFMZa0eTwC0REs?QOrZ;zEcDBEMP4I5OSOb>RZ4(1~4wBXy9lIm?m93 zs(}U;FpL2tsaYDJ$1e>bFB9Np4IEPhpaZiC_dIYQT|C)%ekXBcB2| zUIUJNiix@C3%wKp$GYhX!Q4NFosI6XhVlT$iek$N=>OTSOxMA|PU z+ZXfZ!>n31>jOk(s{ISAUHX#VWF*-a23VxOOtLS6ZMpt3m3?Px2RQ7D*?o=%QrTB_ zKvDa`X{BS%Ra>)YxK`qD-NNCDCzNIXnQYI{LfP1pC(qL5TI{6!0G&S5UnbcT`>`$h zOP4)GS%*ClF?)4whdtr01IDQg6SW35IE{I`r(W2Qdi-MOB-pjt*aK^@$vO~{>;a*% zRdVc)5kkNJ(N3jAmpzKKx(<6_^v@gVmu-@y z__2+dWG^IzdRp86r|ktLo3N9Qg~2tRWh3`Z2w;B$TR)}&#zO%6 z8)z|G102dBfc*`CIT~>6ZvZUTfMb6HV5J5e`x^kOHQ?CaK+P{S;Mm^)@HODr-vHR5 z0muFZz&;J6+TT?z*xvw{q=EVtfc*`C z2Q+ZB1z>*zV5SBdSU|YHc~%1rEg;vQCUi}@rp zoBWHAdQVH4lz%xbmagWbP{;g^nv?Vlos@qeM5q3#&%aT7re0S#@-JHWO!w``zp(G@ zlqbGf&+k}BWPSdPq`paum1HlB@SpUTuK8+@{xZp4s98}T);Z=Y^m~{F9QJ}a)@nyO z?1kL0Ndu|otM4_y?S*qicpkSa0HQ0ZEccIaESAFA#3!VdT}qO@(Uj~`lI(3qSdzWb z?AiCEjL(8L`S}fKa1PF|LxZ#bMBeGqxMaHrwK#BDl0UH-t);(o_!Fa}i3S}0MBlA7kSd>?s{w~UF*>_zz~N6E zzF(sOhd;3yAE*I`KOtm+1|0r`n)hgc{|X(B^)J%qbPcdgLm)ige?kMCr$Yee`w0B! zHQ-qP0+^?PRO{cR8epBmE^xjNSHB+s(WpFxqjClvq4#l}C&2`N&3+#ql`Xv;kDM`& zN5-VQS+;*LK7zc-(TTj7H$km))cKs`bvr-Ud14tKNj}ETf+X32u z0WKV^Ec3nY!Vb`le2fQRrv~f*UCaPnTYf??2JHZSgaKI0(|{eIcQSx% zQ8NIdu0_J>PGIVM^EdfdonRlQRY}S>u=UCMOWU2e-vRUFDH^cdiTfR3DLLM@-HH1h z0LT%V?M_@zgdtj|G-bBuh3My6ZYG=j4f-anS5p4QxV=q(X^)rSGLQZ;$)1?%#_2B| z_C&wigVk@!^KHGti3V2I=Y<8W@{8WgJ6Q$lbS;soXnyPHeKiHcY3cM%!SJ&E^WSRr zcERv+!F@k@tJV15`mZ1lVBtGkH*1;b88y7#(qCF8nxIx*a=2}q=oTK{NbRe1Z9C+; zGJu#|qX9eQj+YkXaNQ2MT*)BogBGGjM#z0hqqpd{)aS7Xk{`3(uOaI-EeSG?>4v-y z3fkO)D-t*6^A(8^>i(FEiJ^5W^2}+vo@L7Wm8H(sU)rV|&UzvoFVKK(%F7u*IR2r- z(Kh9&3_!~sx&_;mhcN)fT(yc;z|7RZ^$NAT2M7wGMuPQ|1* zZ$Q+%*BTuCg{#B)M^T-=ee^jFJ0P$d&*PlWRXuRMg=0Si+y;uUkn>_EsP+T7;g!Ku zPo3X#_y_f#rh1`%;8+gDam)lfTk{)Jzp?ti$2)MZx=f%cT{-Sz;|B~e34SrCsK-Dw3P!7JL6L3AETqp-0 zdjwq5C>Pp^kGldcmpJ2meHY!Lg*Ym!;wY~4p|d|8(G+iM2=bx=I<1O9_{ZU+U zZY1sn#nsnb+3OIO@fF~xJ&axYtrW$*s5lxVfn4p$FUB~DZ6=Ps)#E0{ab7e; z2ZUjG@G$4`)=0Jg41FlQ0y%gcgDlDi62#>w?jkByTn^St(%%NUXN&Z{joZn5{b2#8 zx}^P6-U+-wZAZayWBzF*;|S^}zX@dEbu9GGKT3_)$c`eABWa;YV^HRyym!<(wm>ft z*?Jcx6D^%6xH&AU)WHb7SB1^X+BOWWGmUqMEFzgW_49{Ve- z&m?$lYh!<9tskQCiK}5%$#20pGS*MO(}?%m@>lNt%ik2Q!Fu6rtQXdkQL$dgJCAc5 z|L(^mDx%aeLazhH;BU&em}|WlkJ3I9w+>X_6FHpq$s5T3;ylQH3hQH@r}F4Jsu9`& zN%g^v5DvK=c|1nHUrGJRdh2J&o9H)x94w4EL-DH!p!_+24UKgQI4{oqAz@>!;UTXR zcd+JyeSEwmnDUMpbkv*#V+UbP^qp5 zXUaDPZTjGPTR&WH%hP@_)?dN(HbkRbH?{`?Ki{JUqFgt&(@qrzI9^IqUpK~?%~xbx z%twy(Gc44MGepw-=6t>k`DCNMN}gm-i1NMu(wfX(QHt!)Us@Susydn8qrbE>N_gHX zu1b}^C*KlW0ksVo=I_=z6WWFh&s)1_z>&X^)nrS^cGI!s#c;h2&b(B&z%dd6xL(I% zm9EhfI@>Y?aJ>#K9IR&{{woA5J)lKRiYG+kv--=VctRw;s=su^ z6QX{R1|0E(=9g)}5l=9a+`-_8Cpf#ScD5s)(8UM33r9R5;MQrt5l>L_!lA)6BS$>p zi13%-no-o3SzP}u?wnhEHT`@tJpnsAXJ}na5Pc@5TF=stEYowby`I<4#g_6xFqW!( z%S~P{T5@=?zAb4K@Y(`7fxqzLFHjjW@Ycua%9|G-P1|9bv-Zoy{*3YujF}TXin+4QPd54LUq%QikrRd^9S-_DKAp6#o79W&E~yQ zI)RQ>4G{}iM2=8@FQrpFB#9Yh>*KhsKkNlh#FpMcK^>OG`InQoE>^4d;lY`$8kzho zuNUK!Aay3ZQ718TG9m?|@VbacMvKDcbTpc+Vuz+JDSAM&FdK zpDp%cwYW75z?<|5vn|gqN&%|7md%3zwB=dD0LGcV$`uVj$n!4(19^(p;BjVps#!hJ z>=&;iQ}b#UUBQX5!%4K#%g<@2?q5-5*K=7e-CBUHk1Cr@?Uo*5mBoj&ASZIN@c9Rn zBi+qjOI60-YckQ>h|0M1yNuoF-d|?H%vFiN;F5?*sPE%#IxQriS#r{i` z4Ww8s<>yw7P}|m=q~xsSPv-sU(42^%AFXjnf5u0S!d)LkW&4;~EoHYER^^>N553rP z%_zpY(?y_A$oK(N!C%UnpUq!z-ciyQb4wR+87C`M_9>O2rT4g{e&3Kaxx&_0C~qYD z_m7PfB$(82NuP6pJm5}0Q^*fi;Zl$DmVGal#{go?c^Th}T_P=%23K=Z1mOt;>U|GZ zmr0^j=7um^y%IEJ?WVk#k9#2VajH2O=R*DE9E%4=a1OGB?|($zPQ7NssJNd&sOA#q zcK#N2yV5OAPXVs4<{X}*#@!F!96| z(if#Sa~U_IhBND3+Vt5V|Di1YEB&gle;&g<84kz(?Oew4LlZxT>PE(VVzHyJ!|RU1 z^H)%7{O$`woFll0q+EL=m+{3`Lz3r7M7)v0P_Hb7bSYmk#aWoa| zHeEpP{FQ)ox%X2B5RT=^P%IZ_-f-~FVE_^DX}}KXd!>aVHDG6$JOX&HeGIJ?Z_TgE z7ex@)!F2}CHbLI)%1uF?Gj&sTsyUtkq`M0=V5gc~1~B}3XuwW2-|f&quKsNo%v5=Af5SZNDC><|LZSWhGVr!>;%7>0d#S4N|WF$ zZx(?x&eZxCcaJ2^zvBtu153V(`9_?o;JjU3PvVtn;OE{VlAK=J%hIzLz$Q5Loe`LT zYZ4f)?EM8?530CE%U1g3;P-(<+$uEE(;UbXVmpT{KY{5=y%t+#@0Xp^bDc_Pi7Y?gR^VtLE$ z#Sh27%F_DPiyw%8hx_b5XyT(CG=HdgZyOxmnCtfS^6j~_Gu| zAI<6}%^f2dKz3`d0eduDAu=@7=Zf~+!9Sp^TDVYDNZv2wI+#bG-Y+8~yHwutqc%ti zmEUF{oyt!OkV54I1L;)mBQm5=xwEv8LFL*6ay+T-4hRfrx_CDwiX?UH^MTJ8z|y^% zw!fW-=Q4ndc(?}agf~@MkRuV>#X|`wXmfr3aTK=K=hvs%e^}tBVE$)^>-nD>gZIQX z?2K?Ray$dbo-MRE_5vZ70i1}OsR4U|@ZI+Wz{3}6fYl4TSjGSx*j)qmUgQY|V3J-M zU_5LgCN1>S0E-*~*Gmg|0T5k-9K>6I)&$ai7t-MEa!K=TEp7( z{ZzYjv@Y}Ol8cZZN?)Evby;S`y}}$X^NrO^4!6fEdzAUV(8L&-;@dt?YNYh#vd#3Z z?JC=sPcVQSp$(pg>|2Cx@ALj(4h`tw@?km}`u9D7WC&Hx*>blrEs zD?@BQ%x3_zNf+IP?T7mrK(M4fD8%w)kaVS=9#Fng*A*`2Z*58Km}|xWbd|@KY+b7{ z09!8C4?Jta|#rs4j<{L3l_^Y2Q6lsd9|w)K5R0KI!oio0jE+%IAKxuUcnH!RpO{Vg9Tp#`~N!S?Z63}h424-ts{3|~k#Y*L#< zDCNt=M%hhV#@AU9FaDL3Bb1)5eR@ZhAl>4kQoTOdB?7K<-zt z&Gb40m?Y#z3foK%GXOKm%@p=@I*I}KQtp|shr(3?$jt=YUYNw&NEdR?8#^upYB7Lo z+;?j=Is8Ll7hk!79dz1(P9d;{0hszh-GaSVeT@Ow;aLrEhhYo%3GiwFLbs#igX<89?x+aC|NUP+0tGJN~;3S|2$svmL*T06wkc{mQM_uk=m1UwMEV zgZ1RR(vE=<3?Ogo^UA1ku(a()VDkLCn#+>r-+H89^8DM6xulDjizqTmSwr|v<;V+Z zP?Yi+AS~$5(fJVPEsxM*q15MVgq*!qg_pVE-CRc3?SryEzofEibaC5A$lbUzUa6pA zRd*AY$wgZK9O^8x9w@hhtb-Ba$^z}Er?gq1HUsH`;g2r}NEZxi8NfoUjt*`+80Ikm z2^(s_&H~c}Xqqzmu>iQ0Kz%-e9+w0+ov4wd)&X6)H9P6p^TY8B*h$BpA95LhO`Lae zd9m--YmFo;*(xt%z&4t#@)Ha|2FXfx(8n0SYDVs&vJ>C+B7;tR(NTdlKx+bNAHl~@ zXi$aLLMknNn|98SLY1-Jr5|t^FV|GrMa=Qi(g@2ZIDC1n7S@fwOUqKfImNp657sZE zWNRMYZ}BXVYCU*&@NLqXw1@$W_lGrL`{yPBp4Nb!pZ>uB9Qcw3Z2uffK(^;8yFaJK z5N!)|W45b4V*v4;;yh(81DIj%(k<9?)KuwWi3V8uaDEsnUC5Hgo};=mfNZDbE|U%%-=; z^Lt#>^$+%Qu+Hwy%|PYy?yCf62_Rb+dl1%R0D&eO0^76uKGTxQhQJ<#Uoe1SEElS6 z&n{vB$td-OYTOP#g+QD`rnKu|ZYte^?ji=#*|jMH(DxK=F?-y23?S6c)POy1eq2L< zt*>p;cNxf_FH-sA1g6(_3^$cd-|HAir*C@(kcAs)b!>g>GJp_jqybysy`K^QgEY~A zt?zmUY=hV#w2*-e2EpQGGJ$+PmfHW^QaXEF#6UWGG-Uwl*3sJ7_V5_6wXyB-<0k}U z&<6KiyhWg~PSx8ebDo~bZNWRTthVRryBL7DGQjP5pce!7__g&plL1&n#;>iwfFU3IvE8&R9zsz{uglN=!(0>U@j=`;db> z3|kn(Kn8OnbzVVW@Ep&U;Jn1NXKQW;y2$;*wmpv!Nq&*)$unO$-h6GNE5E7z_91@@ zzsYoC_wynH>HId40Xtl6zuigzhilsNr>@+JZCKlP$4fV<;}khMhryKjXw!%EZMuB) z1_Mw>qRfud84RF(ogb1eeU4@T7Sr!T!M&nkj9f!Nw&SP zkM5B5bY$Om<%14+KAGw$d~~s+@S!)f_gvR_E0Ao;w<)giezS^z>LhpR&3aE~`*tY< z7!7jW`+u?bKJal?Ro;01Oxv-HPLKeB4Qtfs28`Nh)z%hBlT1>fg+Q88pec35T33`V z%+M}U4NRu=;W2DhftOWaQQ2Kqa4jy|EeJGiYNv%NwXl+*4Fv3JXOnfa(uDwB`+mRY z-upcF&P@Nn`+I-ypU+z*^W6KKd+)jDoO{l>=l*$IS^ji1-Anrmh@+ zmH?uIf`xH57)nPo0YpNBl~7j)y@vpzqypF8)j_|1+B9L7kp-i$i4g+G9-FTmaq22N zp&kaH_&b76DVl$iRms~U(ELvcAc6GDO4GcP04`Hpntzl4E>m2ZzbgO;nBvm>-+qo7 zgkr&3w@dR~1aP_L()kVoDSpvB1rLG78 znhD^tm-U4J?+Ka+*h_U30{s4Gs6jMTFtu|7cOwD7GQ$%}Ls-LO1aQ~ViE;?=9RdhX zf{7WyLxAfEa10T9H_g*U030Zae<8Cd{)KLb@vr0oSSa*C2_S?&#{RkC zr$B^nGQ>ymQiNG5IN*@MB(k31^;;sU>g6F8;N4kv{Etj|)UD)Y<^?-|^PhorD5B3R zKNh;NtMSaAqhd^#|16%#$WvumyzgVc1oTZJ1M~%)z8|4$Okjg^My-+#_>%cJ(%k>_ zByb=B1lRm8ffDP8XRZY{oSMfoUz8`5#5j&;E=LOGhEPr#d-#K(0P=ZUneb|TC!YC@ zq=WYQZUKV8lgDj=XJ`c#eE!QYp-z1*f(hH_2hw?JSK9CUD>RIH-j7VDzpr4jXSe?= zNr&x!L6zHuY^PkkZpYwVZCX?3v-&=&%KaBc0`dMsv)xXy`aK*VXPLbGIywSDlsCT` zNmXz0c~zW8%M8Z*z65RHr=l_rH>VHHDMM(-Hnpjfi;t**4=h4GvbpwpDPkLfaA@8l7GRs)U%sg)mvBpUws&#PdBwMR1mHKSg0YW>NhV@ z5U$nzkcObT-@IHwxT^mh8bYxAqJnUBKcy?^M@m7s%KxVtLg=t@M5yFy|LXEAh9C_#->D#618_DW64Cg^n)I73*zdarD<-Gn0=_k=6M6lf zaFOTWPqu6ND^(NS{LoUo@?WaYg3aG32)Y9y1dnQwD&*PbAAf2tg^4>LLI@sFBLvHB z-k|E>7Kjj{Uqi6m=B*0Cy>|agHpD+G2rhnvb$muc2>%W!2>0UsKhhACz0C&|gnRS; z6b&K#>rwo3uipRFA=MY*-|MOl_wIdue2l$i+nc9;Rb;@ueE+XB1Z&=WhJtW!-(RaC zM4qq23=%YTuiw91Lx?t8c7_A-@*9dILe_67 zh$aVOP(uh=zo#HR=0MzI*YOVu;^Pj)4R#${6~s&jf=ARSW}*b1Q4pVSAZ7s~{pNzy zdlgwPOw~XGw85Tex_*+-eec%wh^W1w>iLvY&&2DhC4u<0f|%t%{9Ho_E}#2?sDRlH z#Df|_sJ2FN@6!&%EjGk&RV#BGh?N>bME)ThO$LAGIuPv|Ld5mIR2^qK5cL{D_#3@J z>Nv-NsIc)kSwWoZK#WdWl&@D1%?`v98bZ|BhZMv-2jVUbA$XjlAX*%V>oo)w)aLUQ zM5_a_#IECW3Zl({_@ssqmAFblBpirp4I#t#1_jaXK>Y4C)mx$IEefK;f!M7fgfF)% zi1`i#Pm@trrH*?P#Ah6cZ)gZA{mp-;AkK3j{zOBFT75!6obN!)*AQZ6{#ijRa3DUY zA;gLKje=O{KtwbIP0Qxj6vPD%#LKU$zKA+|r;@@89f&~2PzL3BD0_h<+iFMoHX zNZ~~e#0?rkG*uL5P$BCVI}n%I5Z_l2T@J)74I$(9EQQA+2jUbPkB=#cZU^Gvf2!V! zoX%DdiyeqP8bavNt{^UPAU0?S>FxE(WG-XY4Iz5@%L-zt12I)Yh@37_c=R|B`wyyCWJG;VK`e71wrU8WM^d$N zg#&S~UB}g`j^z%-*EEETsIMxB&pHrG?N<5}#2-5lpVko4+glaH=NyO{yNwL&%8A zD~PKdhy@x#_;N@=ta2dE(h#CyqF)pF_)`ZWsv!i^GZe%%4#cm2XZ7}@3gTJ^Vw(+d zwt`4H5Z}`fg6a7RBIQ8zY6ux~mnewq9EfFh9ak!d)egj5yN*=~VvPfFx?RUw1@UJN z#3YV7k+9t9GFn_5G{48g804zv0Xz5 z9`8{Q_c;*vX$a9UA5jp0?LgdQ*D+f`{EY*#Ttf)e=PQW&9f)%@gy@gU6vW>-5VbbM z=M=;b9EdmmUG-Kly-Gnm;6My(2(hNC6~u!M#702C-$dl*K|Jw$6kX}@YQHDySE?Iv z-kIK3eR% z*_f$L1by;bV}4iF5uyFoI=_p!h5cx4L{ibiskgR7rr%oacd?gN@mjyD&dsU!yBh2q zh2qT8%?J-H!WCBMmByp6m&b#d!ed5hJdW9SRXV^_CE0UDyV7VDldG8i4Sp9{V3Bl| z-$khmavX*ibGW$g1qF(+C}fe}+UR$YGC`YuYoV|nv(iG=`K`rWo8fm+5UgejM?gU{ zRTyY?fkHOed^;Y}_^pL#7BpBi(2II;i~41%~>P;|uRg!wfQcx_dR1Wk_ z@OX?~unv&JYom&*!cSCJQ78)q*cOu8QfdW|g(7r>fm-8t)dClb;e~SL7b(FbRCPSk zbkw0!(1XIhIyJvTNg8P^`2HF4d`GDi`6{wbF0BlASOu`>m_O$2ES} z4R#0o^j&Z#{BPZhzi$2}$$zXU|5?c&F3KO3{QX7wS zC}JHS=<)THfW}*REetd| zp~a*uK)%ohmn4&FH1v&K+o|4ihM-!Lw_)R@9O+|JSgJ^Y;yC75h!o843i@66x_J7h zaHOwebt|Aju|fA+3ys_VhE28>`be1ULBMSbb_{k3cLRfu8F-N&Qe@Fv-?G(5}_4uP5NDH?3`n8+<9Gc zq?MY_7Y@-9f_8)fQ!oUIW!#z#keY@#wg#t8E}dUAgo=f$m~BOqFTb@|UOJB%GAU+; zLtAv5`oeM|l~jja5$Op16-ge&e|KtsTM20)FrdYT$EmdVb+NuXrd>L=H*m}<3Rzr$ z?M!H<`fJ(%P$mXv^9$%z}_Glu}9lPp~t`rdvVRj!p(aGc+TmhN@HFQ4*!f zf~EyCa;Ji~CrPEOTVqi`saW;Dohhi_y2$TZauh9E*uP@rj-X153l`#cgo1@0SaIO% z2nB5oVzg!{m0n28BUD#k7&9m>0G3uMj7Ap7LM>N|ufe z98;~>WIA@Vxm2g^@1tIV1%s+XO?$JEdTwoyzGVizt;s8z2EFIhk@#m`c_52^bLqjW zRxSWu!bD*H(HhIPa($vK+sb)5ernWDt;(!ZKlQjTzu9YT$hJ1(>0GaMMtWP7H+=aO zSewAc$MAb9T}^wjf&px*QBY%(oReiOW!_M>Il_l*Gna_)6H`A50iehg7DME0D}m1S zhV>E%n!);r)!(^z9rkyz^p^`u9{P)Zvddi45s;=mh=}xV_7J_qf89)#t?_yedZ|fo?V&?WucC%orUoIqLW8Tl-Y;Ky;3xP! zSL4DpDuv6Sw=Ci90NHjR)&N zMfe;>Z8J?fg3pCQ7Os>w?S18eC#2TrG)DIsNN;t-yCUjf(orjzbkun>vK`<)P`IMO zyQ0yXEQLr3{*$$uJISWf{0FDWBrXvOBv}N}61g;7R~wnb`qSe!{n_97rnvO?^U`0g z{58EQ^hb@Rzg+Q@hP>4=?~1Byhm!F~J>^ecWIO6A@a%Qedoz6eSry^mB~kes%XTPU zte#mwg#o=jXZWFngJTk-#ZUob@(kJFLkuaS>^qlf&6vb4^R7u2 zoKgi5m|M_u-SMOGXAKGp7Q&w|3BKHjS&Z+1f%G)KB6lvL4GPglBHAd3HVUHn3oJPn z1kL9Ku_{yBJk;|*?PL!ZOb!>?L9BGeR5KMdAv=O!!K?)X1 z+EWcxnTBedh6=``qpw|-e_EOpmP21R?L}i8m)uSwczMfeAb@OGlG%2p7u)N+nnIm? z9mi{6|EOD}NYkFoVDi1$2uE94dTS*8M(s8K0aJ)plE^XUF0gYl^7}Uv8ueYW7zRG3 zEX`HO3Wyc&`z1?1*EIOZAMin08;GUq0C(=_4v4K;7W0->dCRJ^?KOB)<}IuBmeqO7 z>fO#UFkj}iV{{=u(BQB^m6AUbqpp1>M;-stU|2A-6wKU_DT7(uh5^XA0*SxTk!1@; zrtCoW$g)KvQ+CV4(vc~{1YFiUvh2!ids|uA^{v@1{D@;__v5E=ubEBaNqX zLuP9Ix{7!QK2NrlD;AI-E?>aZ$2`pMl{0`aP-~qnLv(A7%+H3B{N$D^!%w3nv>}u8 zPiFi&^0)|vEUw=S-!z$z|cYP_L8uZ#DUVAj#PF=K_ylt=c+H1V_+HAWFM3=EM z6l1|aH-DDOpNo8w{s-W|g0iw5ErqhJ*kJGv>F?@`4;AT)mF$G3f9|&?$Co9l|?x}v$RSgz*)dL1=z z&|8ZAb-BcW5tkrZw@ev@_M*FsGS|0_Ts{NZ?Pt4oos-@M84;(~*k^lu7I5+*6c&OQ zP6pa#g+b-fpY2+3&L;dh*IOL%7T1BJ$}7Z3h31h_TJJ4ufFtNFo8husJ=8ek{>SZ&l!InnvL5e%}6kst(5(BY3Za*?#hExD$>&syzKcF*Y4i4*&0cCgyBbP_03#vyhueBQ!`3UT1ovB&u=h?Qtt)u^v01i-5y$eCN3yw%}n?O;;WKIu1AtE3dUN+d4zE zIrdkz&hoIWv9&qdD%vaC3OluFSFh*-FOf z|A1eCc_}4NAVoJ@3V08P64f3}o?QNa%9elOzn1^N<}?igdo==7R7b)&rinm5Sp0Ko zqx6#*yPAJp0sr1~X^ zi!HL5&XgQ~)dp42f94U!b5XqMq7tM!=^MITYzJ4;n3k`l;gATRcKJbHZO zLeny+U)Fq#_=v^d$4og+yyJb-pnOICKT0gaF?xXk+jRKw*AG96KVKJKTkdfq;(cCg z8%kS)RZJ(wXVs*zXpKV>hagc4L*@DqrVvOG)HKqFq`mObZNq+->rH1qXo}@tfHoo`ol=pW9@9)JE-)GbJ={zs} zAfCK$ZIIlDb#5S*$Fy&qC=uE><)2W}j16DN=Rki1{z)*eFuta(IvoF`Kwr&r+WVOB z%eL3lxux6F@mt%VmY8qXJM|aGAI`Vxx2p>DM*+SK1@&?6PNWTe&O26pCC9^2?D1z< z;qlmGdwdB@@=cG>cBj)h;A3oceXuYs~dM?F>$$17=nUH*Nth=1B&;b~(T zA!^oZy!8TaIE>#}@`xc~>EeYVk0v&$$KPB7BDKrxS}k%xAp@SH(Fh~XdB_|N&Ze`P zrOfqXe}tMSp9S;`8W8zu6&#GuL=RvNN`?9vb4b!qSp(@JeMyNlVVQ{wOz@^G(_oK> z8Waru|4-ZWwEe$N2VjGN^$Az>Lr4{fi9wL|#;UOu|80hknedUqUz8)@BhJ zOD?SVSb;p=;MA{lH1Du5I=acJUr(UKIm@;(qyQIeIsW43DwR?Wnbo$k{KfujHA-pE zDA{tn{`L$MGThgL!vt82lopIX6JO&>-&J9gbZGwo7zgohuJ(D){X_&_%{>FvjKwSI zTZc?ZvK=Zwwz?TL2JQ=E2b;4UZBvL~2jXKs{%{!#f3XZU-|LLY-zxcAEq@hEEuWXv z$=~{H2ctFxYimMouVWFH6c@>o;v%UO&oSTtrK<>;?O=EZ%`av1OVNC`W4W#_&<5F# zE7c0vN>;a0s>5I4h`+#brMCn);<=iUyh#b7+xptlr}It2BAb_rF5|+fk)8MPS^Kt| ziY#;0p9<`vls z8LK7wH&VauoN$0pIE!NtZoDjz5b>YdY<(WYi@59>4!?+E80D{7(b7aagSmtX{Mhsi z{1torANT%_GaLliau5X3>n#QJ3kI>sNAY~6mKAFH*^2*2^Oa-OCrfEZt1syPaoW4n ztsWb@S(2W|S>I{LTc6FJPAoT~90qH1ME#KTCHCJ?h%5n7gWd>;5|=9en4TQdzBT|@ zTM60!P&hv%mPh5^Tcx)IAdli-1og33#(ove51|TVrlTt|k+q}6>#D5!jy@hhVCtHn z0CZ~*)`6xmh7e%_+aI*$1xxq`ua;unb5x6iG6?77IF?ep;qkR>xb%|Gnz3E;jj)CGYjs zl>V4G1DP-t?~VLv9mp9^)yU<}hJupw5m&dD+@%%lpv{$Gjt-h06&SCIUSx#v31p35^I!ML zbjDG?0Y8lY#+`D@?aJeQud!Y(=!y_v|AIEcyhK5f#3oO>m@6)j4xuXYO<=rAzdh=g zWy`t}7k_32^jmuw*2IN?PHCmKutr`~x|*e15*izz&H4l*+a%Pt(S)eO9)tbHTizcJV%~Rn`K3SL~m&KY(Ho zuq591k4OsDc<%)F2WYCDYryQG15&768CBH(z32GYZ`d5cO7^+(1RdCXZnj-k3S?sl zX8*QB+FmQZCN{f}YJo75=5?gnCG!@Xza1vUUsi|rfha@e5TH4dEt_}2rJxG6O3@ZZ zCC|2eIKmh2+s;Ci4-vqyryoZC|2p}Awg#2LZ9otThus*yHoF@sOcuM?VGW$+rQtS zX!dNIbv>*Ln79T5o2`wZYE}Xs>}Lws$7h+!#2)lWdnPue+xu$+V%oFC%*58=iUW)@ z5s@>At1yhk{vcC^WFb01e8=klN`Qy-Un%&A`xe@#?->w-PpSUP0w&hLJY3LX7B8`S z;^8=Y>jJN}lglD7U#&~MuH{$`2~aDgj~h&bLL;S*3+61}H6R8jLl@g72l}|czdo9M z)I7Mhxc(Xn^%3-a$lv9rpx}OesOm#{USmKE?pm%j;bf0rSKY|vSpE*xiwTglwrRdQ z@3?sa1{S1NZ$~cg3@8kL%Hp>xe_Y*qu5fQr&;^5^;kVjWfPl6N?Q<{wsj zOHF5m9%_F+H}2B5YFb}mK#tg+ido{06|Bg~;+u!tRa%>iSV#WLo;sLS}d>s4@=LbP&MTQl= z1v>j9rs3nlw}2jQ{VHBkQ2!}~^&_y(Z7NWE>PK;3>3v&CmC~<)L6!cf_>(wR;h1E& z)}eo4dkx}ZS=!dNuLb>c`CU?_TG3m5tPTE-Qg!8L{{hy6`Z@m2ReSXGHWW@#8nBDg zmWI;tCU?AlywrFnIi2<(529Ms-ch@a;`O8Bu(#3T`jzTC9(uX_Q2X%;_%W@xelsa` zC%vV{i;MpUgg*9sTILHTeim2^O9>YGzXkkuoqS3g{z+3^o^%6jCsy&ilQfw%7I)cIGN`>d*!F5S$>+Utac;hW8@+As4m zn~?Cf_OE*uY239CWi;`R_^kaYzn>8O>qe2sckfm2yand+I;nwg-p@B}_0j%y;|fNw z^KVz>8TKL+JqO~Crqp{~KLcBQPtC^n#r1zMsGoKuz)#oDcofTjps@bC*?u-boXRqL z<9*veK!0JhX-_);Uax-xUJf9c*%|NqCqSehXU_E1Nk78}XuyUYbIQzioXExg?Ls}e zN?S%Na_i`gSGGikqr>YK;W2mjE|kix8N%dlm-=s4&r*X_?%%N=82O3uoD|7b-{jvh zft=jq|B6!af6DOZ;n)fEFTV5G$?Tn%fzs7Hy3n$*P+1Ue#QXfm%`C23d4dRKrA3Xv=6MS6fk#v9v;= zVgQy_M5PL*b3!H*OCK)JEv<;f`!0-ttA{J%eRs%1WxVfkJSe#S%p^K8vb4UAqI2ir zIml<%ki+Bcs`p4#DYD{839Xg~{|<&6*>>!v%+BPAUQA5^gZ%#5oBD5O6Y%kr8Lk9$ zW-tW?3k&bwjhCv;+}+R0v&hQb!}2W5zIz{@`#Z~Li==zqt z&G+Q)*asHIZy$_*d+R%Pg97o5gWkGr%qx%p&Hg(MP)0-oM(&{Zm%Ha6b28HWJ(Kb* zXx(#2o(0`|7}!^h=kD2I!SAx*cgr&o%-uo1OxJlwJ)d{x?&0hvcMpSFxr}OI7M|mM z&0x;RurTb9Vc4$`CeLNqw#%?;3{6!!U>Ffs3=`S}43p@czm5@gjIZDZgn&E!J>$Y4 zttdQ!^ry-V3C%T7lv*89zn%>ZGG|pRHHvST=q4E8--+*-3GduqAi5=%Hd962yV?kN}Upk%9b4 z(4Lwe-fpcn!B82}|Kn;?2r)nA(Bg4?;Y9H0kNh(lD$|Y9mw#)DI;42crge|0KfN{z zeL|5^dLfWXv7Xl_n;asKo!PcjJ^98O0ph;`HbO%+(R_gZw|?G9%d*j1{8m2@kfT0o(gCs9D3ER z?Kc)(6jerZQ%Hp2*Nd@NxaX#j0K=~znFMdK^ZQoKDa-#J-{=BoWOU|x&=I9F1Jp$< z-URAe@7rSWK6Ijhr#%p{|8scyS@2X1(#+uS3AS3wDQD_@<4oNy26CM^Q|A{rQ=%2l zceFzCV~PmSUt-$%OVf+rBluEd6(hrN|I-Jiq$j7w*L@FSloclzgQQIP&0>kO;;kXC zEdMyZut70p%+OM}eV3yM^9f|~b9aw(RAuC^FdOFZ$=p-;X zvK`x&{{X&Z1V?od;4DPhsB*q7M5~Et*cqzEBA5w$9>ap6t6K!K3ou&V{uhmw`#?mH zHp;MBA&EQpM(WesB5EjU>c&8%VE-w0#K{aV5v@n@p8ol3@^|7h871Cxx`Ovt=GT;d z&*?@_|9Zsg%JSU;0z23p*3U@`-rvRdpD6MEz4CtkjC@V$`rohKx8?bfjuQBBss{XO z^TW>jowDN_QtWqjdfgL#=OVBBpx?Q~>z?#GmtsL8igI4}q5kfP1NWfh&LL-iY*Sc% z;C_Le@CP20hlBpW20UaFbO^b$0iOajO|qs%QWN5BcKHE$kMg%Ec=&RFKL`?aAJXM& z6$aM@>pNEYPOh18w2BJK4$MJ- zgqIli5(hXQT;DI%2nj_r*#heCJ^++S9%_mMccK+s3vl@|#2Z-NRb@%p>IJw^jrHu$ zCHCjK50J{;6F`6LhsPR^HgK;MaACY_63X8|p>re?JrAXt9~JF0V+9@S=uXqAHiD7N$1j619-ST%s=5b1;{v&-F~g z%s(~qs~1N{_TCd;w-~+3O_{(=4NZGS#$FtKbz35S+g5<=t*#u-L zmpC~5B<_9~UN|wl1@;Ujls|XV1E5nbF){pkylWgz0Goruzv3gxOb&m3Tyn?X@l5iJ zkzxK11pM4c4(|Ynax_O{(G>$D`=~sJ_XGTeZMiAKKry##WItTS)ouFWx)bo`sj+v+ zIE1(LRPNGPZl|{+cPXavxl1Ft(`4`M)<_xVLlkfz^CaFpmD@S?H!ti*(VwpvV3VUZ zvPcE!@{L9qrAA>W+hFdL-#lfKDD7<8Ybf>KhVs9L8)f`l_5LZ)RTKNaZO!w;ti|g= zf&5K8Df~XYl>GTEF>hXjkpL+Aa6LLGzkKK0E01_%b97?pWFy~_-r%NVy>2?%S&*&^ z(jt#NQR8&rDkD5{T=%{(M=cAu=k?R$QJ*3oL2x2!v<>^)B5vmz_!cIHv2zIHiSR_R zibIn1W(c7@bd*;LFQiY&`kMyR*T>4@w+(tN;^qH^(+UJ8EU)|HpC3V>1)E|Rc#(F$ z&oX+Bi|b-B#ky^fVGk^%s1E-S05Tz09i|#LJJNynop$lANYfyO!cWHjss#SLF9KgQ z@=}Mgtw33D5$@AhpvA#EA?0L=jin>KSurFZxvVudlm54@XJd?cSv+N*PwRAu*E*93RFy#dO#y%FP*{23Wm z-U#K2w%cs27<*WIDb@X4iONMz3UuVPa}dydy;4{~ z(%9A~{XuC4b@ zJYuyP_X<>&ue`nSeFr2p;dpG&~}$6)wJUWQm-vrviIJ=a_`{IX-r*U>nOy$?+J zVBcWsG7BixbN%JYGOK&xb`Gi3*a>=kFbRo^?SuNlZ@3<7sNn^c&>@ zwE8_5!JABdW7Bnib0fL*Q2FfVue&|h_Lql5DX@=czIe~-XL6Ch%snYAy7svoVkmG% zmeymHq5i-p_>uI*HQpqa54_xK!&_cLz_ub6nLhl|@RRVbmeuCkDk8bI=@FArhm0sP zq9&sr88KwUhF^L?iZtX;1x2-91z|40etcB_+OS_8^%mFqi=wDGddY;X-J#>gnxo7q6T;w6cl4o6(d=Glwzp%#p-IkXl z{XN5YS?@=tBkou2gAMqt!7sl)Qj1@HegvNue>R{mu8tQ1W35pryr@1VB$oS=tHder z6T_rSVqbbZ;(;`YQCynpC-!?C4f%fq8}xW14k6zzQGB~Z@$C}DHxzh`e1rXx@zdbw z+yYu(@jV zA>soPq5X9IVj7tSys6TSlAK%te`g|_(Z6l>GxFk8mPl>nJ^v5pm zukJ@9W&M{O%(Yb=%th84#Q@b&1JzMwtBx9|jw+}Qr77z39~P1+|0nVpEH780&d!5= z^TGTiCCm1Q3+??|kgwT_O)^+5I@pFSzmXsF>ZhkH==Oomjm^0yrF>t`^%Eq3x7gpTjit9&=~|ag7v%d!hVz-wJ+tM>dnP@;z(Y(l z5%m_1`qL>^i1}u5dR+1(!!W&Vfx5Doe)`x{rALw3G^nygullKdm=ZtT z^lH;ys8PRrKSm>bC;z;Nk3+4I)4j-Pe%tAA&`yis7Y^EK(ex0;;=a|-NF!r^sp|E6 z_91+IbJO9bS6NTbs5c3|qP`C$_ElE0x~>Q|4)xb&(1$WVa+4Qn^4m^A#Z9RABvjlK zO>YNh_O0HUKik+(SFYqE>I?Ug9n~UN`_SCZ{>a6!u-^9muEP|rq4!fZ6a%Axt#AMKHY+GV~XaAv+#m;%U**+{tDA z^Q-$iV^lYK72!Kr>=L?R1_%0E@we!V=SskTsRX>`e=UpjUr^n@IM$C-Dwy}24QMD< z3G~_Fme4mlj(9^X+a9eN7XAKCzuhR(Z1N<8e+tz5farJJ@C?c4`k2x0nZwCFB2WDh zvD#32-WC|{$_wgdzo@MDiQc@(>d~0V1@^{~wPG5*|f^Fgc# zWw2@VLi$S8;(KAiXm|WaLonM=&7zQ%U4e6jB_PfSpe}J{R*je)oF-tbq=)F}LJ9ke z)tjYHM$%i#F$0OtetPv*jD}bA#HoOvG0b=UDH>q%l-wH0H(3hZ>j1TDwc0XN(YlM zzdPo2HXw59bv9z*NsFCZzM*9K?r0CBrN3pyX?tGV^WNR=`l_rx2ldaD`kRkb|J>sG zWqlbdVC5^)v&vJI{zVaQch8WmPk?`qU#44yzL0ctM6Z`h+K0oVb|s~za??NJl+94z zGeDIIzd1HmIe>jzooxshzt*GdiwWzqK2k3zS0Q-(jLpBpN-VJE39W7$66nu3KCwPXE|J3`{^0MTM{`pWg zDR@~id|_`+Me67MiD#)_e4J{8a`Rgo4XXUqp-?F~8&-}3_wlcX3l|Ut+3JyX^5U7V zV(5wT%qKVqrSgbbhsie~Pw))v0Typg9%~%%vEQ?7MS8M4^#NJYNuI_A*)zDf1|yzC zO8qlQHxU1)!JWc4Bi~9sx*2vo$wTL`!wT}GmI%P#;DAUtUiJEp>f$uLF7Gdl`Q<_g zL;$seiYi~)-ds@*j@k1st-ljd(B5AaF^qVa_MuGi!Kwo0y6s5?Br0Ip)jCUkaJCp?YNLlW56aXln z#`=)E7Z}&%YEpidB@q1c{K_KI;Vz5w;~SgHabiBcu>w~q z`7L$k;xTA4+-t`rJX~i&IX6p97}p7M@#FUBK_%dbq*K!soj))H}MTmJtV(sLUCA-y0YZ2{pMPnCo}q9@{_*+PhC5p@*nY=>k9Lu!Z$3|8T_=o z^i;uR=ub^(qNm@4#C#3B#U$gr^qbhU`z<8ABvf+;)VifnlC9}CD^urSh|KP+NsXv_ z(J<7BR{@bdlloEK)+JY!sv!09iUAo<#)$)81im)8sWkl9Zh2q5Vjy`(Nr=(0zt?yq zssZYOo@3wD{=Z&7M8DpRS6sGEsht+G?zyd6P`R8g1@TT;T0i*`>*_*~y9y?twIR6} zItj7?4O(qX3)VB4V%!{R&;D9&f?gNO1{HeLa2k{!$fSwZk@Y&2>{khRuCD~&!+R7MLoY`CO7R-1;4{D#!m5k7{zt4d%t;I;7l!60lEO0kV3>|2X8_1f zPk)pfJoDEPDH}49`n8e|OcNJ@c!I^FaHZiOdx;J4K5mrpvhoFE z*Y2)Ne$h{i!_=+rKqvgQ8@!Gxe5{O&yacURc^%+ChSCOczPyeFrW2xBI~G{(khe8I zf+lG(FJeWyw?e}F5ZyzpREw75ad;UkN^a$?x7^i%*`u zkG~dzzrnj66siKl{k1XgvPSRv8U73@p86?z9y2}1XM>0|JWPu753X@p+A4nbr4K?Lk@D}47`cdm2Y?)Y#vt-FH z`yH|V9(XdfLb2vL!%wZ4c&@}45(-9g&Fsk}_CU;;mOKTjNpv&}d0@U$KNp!DnA0ix^Bytzm!GM#tX2VqorB$>rQrL(36j zno`0y#@BhyQ%3bVjF$X;CWVV0=^QpVd?1D%NtLnu~;>{Z-Z(qIOSeCSm|0OD#3 zj{4wO{#Fbn(`j!lu8a%efPd_cooXY%hcMq|f2J@UsjtJ2qJ~;dw&RuQaom<%Uk5}4 zBAXb+W0{wQLdLAW6~0zxs2~9oQQi^B~5YKQ)JB zpl2EK@I78fHQWwEB)X6oby05(N>^#oC5gX{_VPR^HUM-vjHNM*n(fJVIzuzQv2y)X z`ts}B<>Z@YFTOBV=(5g%>|!5}2sBhi=+?;E7|_~RtJAN`}PE7dh&G1AeOjCj;)77Lr$!P z;|}|aWzt-T-u8IrD=vC;6hixq^+oUyk|cUl+6Y;Nxm%$<=YHfWTHHO!)AS_cL{V9| zzen~IiyxATLfk*ow0BJTZwT{~-;(*~a%=n1qSztu|)EgfA>jD3o zNQQCa03Y1`1dQ5gJNjipDnf(=@ql`~qVPUrFQV`-cDrGDdmPqOwdglxoqB;#6}8-GvHAm9Y%r@+ff67?Wyw2(p3 zVxjej5}_TiINCYa8v;E*sb+vo5qeOX=T47j7EmI&*(=`nCwMds7#ifektuT23fDE> z*N!A56Ka9f6SW{g5ep6J@7O049ZZFOd!Um{mN#T)@(V;{M*s!_Z^c!E1{2J9ZHoBq zGyKIf@iKIN!=j;ah5yc>pyiOl61WBVUm^x?$M4eP4WU0uS2R@xU;hu`cmtJ>QoSbO zUOL_Mxu|#M8UoQZ#2JB!{^PheO)yKI!AcmU!xYue9__c-j;hSxV(d6^E3QTVBdGVD8 zI5WoT(E1jr?F7P5>9w)xxNHGM@N`x@lfx6%NxE)-yI*gAz^9Ng$vK=*iO0TUdPxf4M4Sq4LCUxZ%^VE+9z5xN_%0}cO@8Q$+Rd*T_ML1#4V8WRT`J5|Q9bcP2- z0_V(F-%xQ>R|M9*&9H;c!iSpF9*>X!2^~~6<{=(gy zifVzCv6E~IJcr!~znOR5cB?{Ylh6duMzHb`C=|}P4wOqBsmIXsY;!GLDU1uVRG@R$ZULL zXE}5VLVkt5&e-2*y{_~g=Hz!3Lki@b@TLt2TegBH?0V%DoL{)SCvr*Frhyj3O3L#2^JozrU z3vm}Qj!&6WZ^h zR;0EXr(?x{!4JWp>^vC^W+W)Q9Re|yp!=6zQ(qC!#6U3xmw$@y5N|_Ih*w8ow>iI{ zsDQw(okNYgvQ>&64`5 z^^T+N*?8ZVQ9E4hQy~`!pnbZfJasR(5A{47Uw1KH6&OPgu`HU$a18qkhjHQM#_~^B zB%jFtF^F8y#J+gnbk#(i=7(-4o;eN3N?ZHl>wb;rqP9kh+8Q-&J(}N(rCrhU@Za6_ zB$-L<98&S%-}&cZxdrQPzco}XvHqw0f%wLPfN(DZ!rV*Jw>NoFF9X7~(rR8%5D-4E z7Xje}rUi34Yji(Tzf|&8A}&0q^R2~&=X4%DE3-m)ZVq)tPPwN1u2(Y&882^d*#=Wz9_9d4a4UwLd;N?D}IntA{ zWNY{`maN;v$mIY6P=cMX(Q!?kNM|IqTfxEK3gVewVw>N+Z4(CgVN4sg`fInr@#0;U zjAw3B@yzkcF@)G)7gtx(d2*f{|4lnMyar{Bx;-?VQiue6Hja^SQgS>M_p+4fpw5_=xeBFCv5Vq;r=S=uPrNUNr)(x^Di=VlgxTT$RPIX4Kzi~l+y(}u z5Fw`=#QQ#m1R8}Kv`h73L(n3;I`}qH7iL!Rbw4uhO(ND0A%Npzf%bRbFFAATS&eYb zPdqj!F&xkAq$ibla86=JJo6Hs)03DHlLwsBbkj>y>mE0tLYN?60Or8qLS|Y6 z76B6n*t3T*eEi!_Gi zfN_72*_+y$KM~c4o=C6Vq2wa-draGP;IuzA${11-B{7F9+A$G}XsbM4P<eC_qG@Mi>R%WJ}zX&fO51hJk1c;O?)qonx@}qPT69-r% z|7AKd+6pRq<)@=Lj$?+iMO1<@?qvlYe2QhYgLx-vB;T}yIp2ijZJ57wVO9k&iBaMJ z*%~_w@naBz=&3llEwe-d6BbJgiW~+x^vhF&ino3B97v)Kh`bu-I_{I;IFI*L5aMpp z7vSna(8?X}`Ind#281(vy~F`5=8;lbGHEM;;dY^Hf7{f6Yr;{{J^{K=a3MNo!DAjP z;{pP1AlLoMzn6GHL^$UPMFc=dIUAbyBC{!6(f$MG44KtEy=6mnZ}f_?0H@t>XZX9&B)C1G^_e1n?VClf|BAtXb| zKk!=_Kif|-Sq=>K)c|e~#v*vnL9-5yS;jc+Bid8=#^Axc53?|YF#bRfULXEefMl{t z^rzhw2?C(Oa0CSc#07tJ=a-uP*iB~Wxz%rO14gfT*kIPu5UlN6{)masBkXQ9pVa;( zh{s`Nz2pF87UoxB32#EddqI1gDWO3#&V*FOn1?k0$#16B3J3`muCGvME(Bkbr@~$Z z^+UGdOw5_rxjG_o;(46~JyiGv^oGq?V3!v`3-Oa=tG!w;mM7W7t)E;Z$BHxlzK?KW zpJMVB&PB+!52Bszl_8$0oq)1RDzVS3wXm$oQGV#yrT~An-#w6PwXeNM=8`WPBrwGb z_X}zH4)$v>_W(r`#!mWyuZv1;LHXrn!3;oSqPKX$wx)B}K@GX^J`%M^Lc)NOB#rxh3^WtAJbN23d-`4>OErV}y*3b{6hP47K z*~G9|qD$t}qvRDfDx!9HkKe%nX}s@mnU}yHnYy~I8%*ypdVWe6o` z+3(&5VV2btmU|L=au?y+K~yE>^H0;~(<&2`@bN{{Sr7uew=3fyW`00xcS)l)mAM==Ra2RZgyJ)7$Cb3g)+~^J zvNE1o!@@=MR8pf^l<5Hs`9e4x-dWv9hkQN@;!;J~{xXLU-Nu}G-FCks0%hw7&gI^L z5_7JNaSP?>oYtz;Gjw?a`APz9;~`+&Z0v7U91k~2k9`k%pQv^TAt@pTP&!H+t*7EaB1pl`K*BZ_v7zG*yp zwdG4tjzsMh?YsR9wyR>j_Y}l?^}bsu(%G%p-q+h@mJ4jRy;u87 zLu{W;%AXs5V2kz#{CQ$O*&jNura$vSi+xJ|61*s0&ky<++@j6^1pNEV;F@=#H9Z~} zXAe7FvcK`Zp8}|NPFb=!@YC$2n(64tb~O%VXt2K*p#P9VrLwR;S+8rT-MY{pqL5%q zjeINel$bGYuPh()1~h%*eV3!JsMjk&AFel)q|YC*%)_$p-q73dKPHAY-uEmzm~Nke z%^Lw>!Hw0%hqAIw7Tu~4c5m{h{#P4Ao+mewTn}lco4MB5y#>OkJkzKlf+=q~Y`|iU zY0}CzSq08rI1a{cSMz#vK1j|6c>iMUf9`@iOJiN-&u@TtJLU48!!He({k5PEU&Ei< zBl}r*az87_UbvqX%P!@-&kj5Gai1NWNZe<~-B7T^$r@N-oRhsA4L@1*1jqoALdf%wPDdc45b${6V2DWxK?d^Rd!f}*3iQmYK08K4# z|5~1$)3g`U6l4tcO=+f zRW&59&p>X!v{;g3vSy9 z%zur6;Bf}5IwOHdtR2sGR6&rjZq8*QteZ#mLOSY)b8;I>UYo@BLx1f!c>$NGC0d@H zhHQoyar6$J9nVT!#`A^T1EZCFbC#H&s${g&GQAv#@-{=AaT{T=ljadzmn4N^h<7+Hrdh zuG7IBe9{|t_k+uQ8MxmerfzY=bfEJ*f{o?#B!43vUAb1S{)aF7WLw!>9v7gd1MWi3(pW+|iqTY{8Eh*Kj> zr$%V!4EQc80zPHiMG@fKgHq5TeIXCnxH1ljfKEUVzY3>iF7mIb^4`$0prja@BH0sP zC#N7L=T^r1P6X@v^>XgiP)w2wA&K7W2$=T19_e3n(qRv-*c8Cd>5iqI#-@Jm&c%Aj zguk#_Uh{C#?9Nzne~HRc&!Hag4d_QoSbXDF@mCN%qM&Krlm8(q^xo+G*Yecq17qz< zj#z&})nA2%lQ);D{Q0r(7U5AH?_0tlQ{1uCGx@9eM)+4$4xOyyTfP2n5d`Hv6_m5b z1BYda_>GKDYzmV7;FuxF79i~Rt@7LJF+zJVz_1U{ZeR)g-XQIzplRi>suDNFZc4>h zLA)SPbtH=z)PtseV60zQyUBq)3?TikT3D~Y$CLynDRnzt8>79(?lgWD=Yb{?ihk#B zAW67?MV+fPSGvMJsrB1jMXn{1Yl-HzsB12wBhTZytu6R($lSAYW6 z-^{jiEQY5bl{=kRv0fI*UB;^#aSy}uD7}T00M@$GH~%|~3GQs&l0Se4O`k2pzaIXN zT+gB07F^o;ANa__uV46G?#cYcWE1)&;Qvf;B~QG{b!6W?sdIJu`WEy6c%mKL&&s=K zN1jI~xLzK=CCwhUStH04RJ>X2rnphv#1%V89u=!T&qCDSYz+K0~AN zdkAj_x(od|p8t031N0`w%IVNzUgr`FTYSQ)`KeQIZsf{|np3dEyA)1Q@p;wn?w@vU z8CQ0Dmt)=1=rXz}$!45Om)CS+xzX7Hp>J>l;tafz%miAoPecw39qz1}{le-Y<9wr8 zwD+GPeibV4)Fcx^F01nQG{PPlIqZ@*71#CeHU-(uBMC7cpt|1+GCs_{0!j}bVK0twbUv~!5RLG zgK7@7_o#dN#G(|(PjRor2^}>!CVYi#UEr5d4EYd0tw7RVXe$$oUZ<#Kj|S`zeka4V zWpl9aU@l8>i*U^E?IRHq`?5Fjfif%+LVTK@Y-kUvupTiYv9bd#0uUVd2td4^aa@Gu zUsC&yC-u5{2gHrvD&_)gKUmsUkF$v5_^ATzV$v9Ps);`uRwIb*^9G2I+Axep3egFo zxI#6}7kEn(P_M$5g19S~(g~(0hH!VD@Ut{d6pi^9y(*Ap6G1K&q&)HF9iA7R(-OtS zTvYgihdNq{_lv9ZoaPnj6WQB}eg!c{n`%0z$Bk>*&3rsEo zij-gh_bKKK<250G(`~SJOMLf=;8bi zS*MQk(Voc-HDv|%4E3xx^w zpAb7VE6w3I#^yzGBuwt?lECSRHx7*AZp5)0l|GTe;Ex=JAj6FPkgusQasWk)TTHR3 zG^I99%~b1GuMU+b+irYQ(3tBz|BE+p^-uD&G$z};KIbf0@0`R-VyYdcnq{oK-T5>GiQK4)os-e>SRbKq->ffD+cY)`*Y$zO9$ z#BCM#038Xxv1dsZc^?~lLF4sH^zku1myJCodS2##a)0{&LG=2trq>5ZFU6jZVXc>Eyc~or>xhOT?8D@-2vg z^vjb*Z+nSN1V<=a!>4vTZ*g!4Z+RK1)Ry|O^LDU5u?e)2Z%<&!N)-D^Xbp^EAIg9k zNhxCRD39Dh5;8nIpZ@~>*!~6m1x!Ss<}jt{spkAb>pJwR+{<1U^G`BJBv0L>x^&Q* zyO5s_ZV%%sM^hs8bL&+$@tEM2*raT}T*_due>Yy0!XB)-1v_W)a~9>xAm?r6bs{(< zh3?>5lk}4juSyhZei?E$@gUgP)9SvZ26Ut{h)KuST?pZa(D)ViL+V?Q5UUdJ`xNtA zBFyFFS#pDMaJsyV@@3q-57+7@hr_LU_4pNKYcr7l;RO8)W%*`5p z^)2hGaffC3?59@$n}lX@!7l7MCcNZ;c07dIW9FU;$A5I?t41!ML6n=L1B6PxL+&D@ z+!*o*$tWqH+LQ*+7Y#{!fs>PbipmYm6APUyOeBGr9qv&S#MC|`wSI=n2e?=gB7gw9 zaum+^cTXZLU%n^(WVv@@dRu+Cpcm*j#AlCXpX;?f zM9``F7jIG#qbYXj1FIJ=&MmKPPTx^esvSa!%io1Q*yEZqGF2QySkIvdrqf`{IX zGYLr;IN>xl>!N^p77tG6ixa7z>$(=T+8oGJNj+2A}cIV0B~mPNYJ_6UW!v23d^foO zNek^O_1h5bRmic>W-=9`%`I0fqKUAE&tdWgH`&W%h;|>6178ZzUhe{b!%Ysj$=i^$ z(0)+A4bi5av(RR8c8K<4NV14Vdyvmza+{mnf#j<91$gd4a`zX5nbHN;kREP4e*V zjM|{fefn*P_5gA$w3+;-p?9|THY6>y@6^RL+IP9hd)?%HZt{LN`JkKJ;3gkN(n5Qe zejB1)hg}^O+D!gsh;}`a7TOI+T2j&ICTF`Af?!q<4O6J-*aF^1 zDZ=SNnV(x=*m@>&m*Zf=mc znEoM#eKs?Tu;&qx!fLtTi9NGyA8U$*Z-HP9<3{+cW?T4`IUjywIzRdkXyL7uWK;_^ zL?0WyxmKPnV;Ave@uM$+CvJg~&!ZTTBmjqL;B^TyZO@uC`>WM3v1IFvNeH zjKCJx`RL9o5A+MUy%!bPw*g*}eH0U;Y^DvMyCjciH#SJ#B0N1Oc|80)`e%f@5>LO8 zyp?!bE_q2jy(xJ-FtYr5!u8>4+EZ*}J)UM@|4TM=8=k5q?@m0ex{!JI;pq&?yB|-> z7clQ(Je?_do0#`C=551MljQBdQ}16h?^!&xOWrV^?tPMZ`|+ei>HwZ7QrXNwJar4) zB%YT45%VGtz$+v#${@)Hna8a}UzEHWJT>3Xym~xcD|tK~)VqOsGx2nTjN$bw4;VSz`t!4c zhC~RT{fD{8n2(mrw`V>>1RiRzg_o3^WVbS;Wb=*eS!O97(K#XMA$duX_WoF2@+t?u zBuOiGu_Q^_e3rZ zLcpM=nlqB6h{{W+k2m=cAvQB%XxQ za?-5%aVc4*xbt!(pL6Y*swXA}qtORG7Z#c-2#X-`7l4_9LyIFApndBk$&Ux~Z zqA~ceytD_2W(i)_-6Ai8L2@yRCDw1~1Jx3@T_&kJ2hSu>LJg8Xmc0AR))V4kH3T-5 z90ErCjVb|!M3ppe1^F3&qUeJKG8T&UNiYPoT?1cLzhAuV98g9EgX-(|4hyN+duI^T zeVeMs9t2AGR|;)rfu?1@knU6XE2(DAVIC;hEWdne!_(CQPv+G@ssYCFAjRNLp0g@HXpXl&4gEy>GKV2D?ht*ZDTHPu|=Al77M z15jeWtkO#6WRQ8lWTFQV5W0*@xQX%p#D1t|eW?z=9F^WSllr<0Yq9dZ9kt)Ra6MPy z7pW(HT)mbvd8!t)8z3edhOknc#&=$HrTqo{$M??)m$&~vTVGd11o=S3N!gf-&#N3N zx!{ct%;96G2e_Z5dz_H~5PJc(5~@2EumXP&wD%Kwt^QCzGj`Qk(zlkzWq%a*JKZ=w zj=e4DW&h)izyJMfyWhL@#+Q5XFPVRBYi}>s*rsmz*Q)fEin2ZF zT;-XsugFH?b!9l3hy6w2W(2jTYm4mQ_nVhs$G}YZRumL(?Iv78+!@syT_Hc>Em4l} z7F$kar|ZQ_q=p-}v9D%-Q_~(dZT2%1?GGTuL)m^S@^j-jLubkWaR(6gJ<4vNwTH}H zl5;`&AL@!Oy*UUws@`4rjlJtQWeRrafC4XU&qNP_Rlu(QZa(?5)XwnWa2Zaf@I$~! z+_RFrm^&Oum9?<%7zKu%>et%W=C%^=qn$Tf>tvYZ=_Sa%B>D7%RGP6W9s9d*|3Z3v zKK2L6`3gB*kvyreTiB;!wyvapb)+35oOcV2!W}FBq;_y&$4lzLw@|E?0*lk3vh7QM zyrCs#l2@>=C3c+Pvxc}uum%<$#AXdRd$0pTws>!ff_xI{L?CzIW*~f?dsn4nt0#U1l2fA8Yx2tjw=waAPaYcVMq28D9u_n;+LYX1APCTy?2kZs;c|P zhnW!u96h6wVp5`_l2Sri4~Q6oM@*$KouqWqvL-7nADsiFqTrcvI3C9)FNtMFX+}y) zY6@yNTx3Ae@RH34C@Se}XPz3<5Yb1z@ArFM&fe$j!yGTq>-&4YuOEMKX7Bx3x6f^T z)@OazXI0)B!au$@1wdHKr2YgM#6MHdIDv3YAj%hNWSx=R)$T3Jem$;kdt8y#!elX zdUouzQK=_g2gQMwzk<6>9uZW90jg0-i06?+(@y}9#dVL#b-^KIS`&w5>Og$*1^R5d zdkIQf8E0o}`Kj)i;6xO|2&-#w;*i+a>X6m5e1zA)Fjt-ys zXK(i580$LF3Y$CwrxoEIr(jSaYeEaPtW)#BYhXSy)KJTG^+gzpdZccHYZTQvSySL9 z-t(}5^fM~RC2izo5iQ3R6<`hkXQftaA^?7TrDIVpILXLNOKnF65{xzl7Q)@31mM?o z!4iW;KaTGe8AoouV7|Fwnl2IGhUt=6Ani0;l2~fZQi2iKsX^(L!#JTM&qw$h^>FHQ z{JiMOwC?U&E>9EXWi_%XZ8>j%dP(`|v4FXzJ0( zO9l#zK^!=a)FZ(qnGDs15}ixcx^w4wQ-3SsVOu7yPjB66ddek#mH7<~K6<^V!lYx# zO_cdLs2kk|Eo9!Ao`8^>*r0*6G43Ydom7r?cx+wAj6WL#hI!;*Uv3}XwCFG6a35B( zm-3MpCtpx{`ttOw4b?NA#PJ-nOhEb7ERXSu%P{cVNzdb|OeQnaVg*{{IjTyAPCIn- zv;xx7HFy3)Domp?{p`1EwL8Y#3=sZVH})fSEV)7UE5tf5V1xY9YAO zzuAOJ_=etMQ;MN^d~+qM z+0&}BUxrOL4jH_gcESsUg1y{$6Q#Qh9P*+`HKS1|yWZj@vp z5)yT3fT4RDCL`^#UspMJq<}>QNL6d3*qp0LBG=?#JAK1!&=Fu)AQ+0ajb3l z7DM!$K=4~uY53c;o7&a2nP{4;xfpBX4pEC#x7INRhsHJz2|{_w3dm1j-So} zH2G=xhv%n?;0QFpuGikn<0I?bnsY00fx{WKi?hjlTLy1LQ)QXjn=;Q5dq>~R-kHz7X=6UoFByXhzUWn|?!6K`tDA`O z!d4$**fxjO2WWz-;ZpY-*)gZjpPJ z>5otVs<`0ij*D<`>uUTxXB%G6PBdQ5_miuh+y(`j89dJ{v^~>9L44ByEZbILA*P0E zIuL_!HI2c0uFk-6PK)I<7|K$K4ebba3l(3A8O9ZVo8rFX;+;e11y2D?^T}q+Cqyg! zpGeaIWgp7j-MBu{bReeH*cq|VLxt;owi1>3YTm3#%29dO`c;s`ParwEs`SDKHLV@Q z7?!*r$E-O603<8|m}xyT=4Q6w#J6qLC=#jNiMFeQgg=8-M|+zu)uF1t>#B~_TSR>O z#rK+mt1Kn47~O=g#6Y-@i?_t~k+P_Sq=k4aB49saMTK~jXx#(hv-5p~cEK+(W}UB% z7KD*`IKIH{1joOJ3GYPEy?wIQDZy$CT?yJ8*IGNPzzlIB^;h()-QK!EMx=al`nPHn zZJ4Rhnp5YXewtHTGPU!9S-=ChaC zc7wNoJgd)eIoVhswlz31C&i8%f_*TH<=}P`+|zg$%S+sw&Eut}f4>D`4qx_%8i$FRKZ5B<;^Ax`sVi&|%7k(_ybztml@u>&G zr3(ic@B7V|gvhj`khp1QEC!9G)o_lM;@$UgeP~{#78u{p){5ybLvHlId?L>Ry_Ghf z2rytiq`yEU(v_EhSktgh*in_kVL zy>y$;Cn!G~{gbqdL5iF^{WECFS+MD@e&~Oqu@!~sf2Ws`-aoAua27l4xG^1N3KjSx zIj8C_CRGnn)L1b2{nmDi!)Led;0A;5b)spJER=O@47-DEa%P6R*Z57!IQN$VJQA9f+@{Gbiqie29U_@w!OuM=drz#VI zw)nVA$CF!UPC!;5&0Cj!9w{fp4@W{0aE|`!i|`xHJMk4gySx((N1OKZgbeqTSTT7; zXjRgo6H!v5LH*qpk4S8g-Gdu(OC{U+>xfuaM8h@6Kx>u}7@$KZ4QhlHOs)n8da`BD zM4F3z6Zi3)eTQGW;UGQInwBGb7cM-n;F*5<7aH~%y$1Q;SOxMV6sBg?!#7) z{Ni8`&qGEq-UiD$e-WIary*g$*yXsO8F^d5xTb6Od5$vIPos{2T*i5#wuVElN-iDed-{ClBR;Axzew$18%;N}$ms;dQ>jGmk3Iv-4 zsNSiKC(^tb@)lH&DiV$V!XHRkedxwyS7+UZ?3b!KlN&nwZ48j{vvcpnb!~}XEZ=Wk zx)+xwwh>8`S5X1?QllS^{}PH@c04$JqeEK5(;o;|p8_3)??|tXsWjdCT4l6f!Px*e z@QdWI(>o@Mw>zvh`Nw)yox}MQGTcSQ7ns+vbkx$Gk)zn0}-K z^~cpmQBQyujDN@E<4C{b^oB{%uaOI%-PagAIl850dzw8*dV0F8{XldZ{l4f%la_N( z-$d&K(V`@)wj`^LlC1jk9BgK?(UbmCepE@ zN|<*o_ASXTK-Ad5us)r}{Tb|crkH}s+EdPK&a80T9+M*JSYYzS#wq3Q83M%fFfh{F z4oWnB8aA?-zndQb`qJAD^!oBCJdfVaJif`EC*K~sEHh!+tvL_A|Epek`<6(Se zQgXC=4BAWE4V6XcAvaXGkCNVYu*QL$$J<6w|2Hu=q-?sD#dH}3^uyMhe9SG2Y0U=A z^KK#7R>0dLkWL-<_Tq|R_~(|rTArssRVQo`>z&E>vWX9YaU@p5Z>A19+<*Oc|WrE!Ttc zK6)@28Jjgg4q+WD(ACGF2d*c;V#uUSQg0Zr$u*euilf-n%6>o%?z^ux{S6FZfD&da zLnPyrmDqEyyfWC!A~N@W*;Xu6t_kwQ6A>*!)t6qg8CYxM|?Y$Y_sc#J?f#Tp3xU29-ndIS+hEIUkTc&h@FU|fKmqe4i zF>fMzv2ky<8>3C&EiVCvmzp;K|DAP$WyPs8e$L&#C&#h9a2x=`wuAtajV+Vh95euP z;$!lL_S-FQXuo}PaH{)m_uc(hL>zApK98?felae277ySns1*iB)Hu)b2Ip(aTkfDY z-n}Lspjw>*yal(Tg!*OWWfM7vH>6s`%?IsiSJNTp1=}MIK*1^iWBloD!y3*`Z#y8- z*o`XE+xGMNh6gXw+xGX*yMQj~ZNvR@wVp@1=cYfgb*@+4W>kN?2!6$8I9_tJzQAMO z12?rT7hI}hE7{W!X{nHss|#fSo|rMnPB;vV!=<%htJi-3;MDD*iUDeC)|jK;X|;RUrh}S zukd^KL%9)RQ*sc#tG?i7{3SA2)^OwQ#<=6&pG<@)zdXX1zKwYK&I)8E>zq`D8xS7l z9=?4Om;l~VkfqklM8gULvry3+zHX~ct}~GtrwOa^t=D^vSbERmoA?RA^V%PSpz!=YLe7#Z#a}SGnjs7iQe>6~0!8V)OxuAPx-xg3p3l&^7w-`af9j1QX%hHz~` z<Ma*OX$S_n(BhH7LDuD!pZh^W*M!Xwn1aUUmWM z0P@JN`6(r^F2DaOT7Z9ZW&rP7?nV4sT`xifJ}EvJf!YRUaVz)C^0L%dnfKB1LzK9h zCqsikP*Iq(+~}B@zhQout-7zV_ie(PHp4W@W6(IGGQzdgov~yThUky(kd*_*h4Y6N zi$NXP))zwO88Pmk>5T;RsbLp&w@ZZR_#-c$|Js~@J&acTeHll=QHMC~^J{por*?Exq=dJXbXmtibnl7#AlwQOn{UQpA>_DRF@YkKyV zMQcjq_EvWkQ@?4XDIBX1AHygq+q8>+h!ynI19geucRdy{WdH3LoIm@DM9Arw^ zelazDUC;EHmW_>PKN8$ZX|e%2sV5nnGuWuB_9WL!h@)8G{HX?;%(&mMpk>Met;VLz z2aYOtBOr`m+)e^KGuM8@71q99d9GDb=3ar=23pVtBbHTJ6)R(W=yLK^R9z-YQ^qfVCTzq0a(f9g{{f+CNp2NVSU<>xd?@wHn9)1fGyU6 zxs?>B!u+r^p_lA>E40tUd^zVUga{S8KAQ&2&qh`?Ao8g{ft=M=f=C{f9H4+JLbpRpX2=_<7wi@>jzsJ ze=(#Y#9w^O<1g?F%%48F%;6jD`^_;-+aG|xTueyc`~@y5!e7Wt40T!pf7!+?e;rqq zX$OCu&C=kns?OsoJI<~Yr}ghRfSA9*a@rWfX*{+Rl`s0UQewGT?_z`df93e$2+55f zD#9U)(33mch!#|sTWk5sBxyfRBCWa4|BeN9=%jJPH z{IF!4MHf!zgzC<^d7WjQbvNN=g3h}6N>7c6Anfr`QW~1`a3&z*cqKO`ar~Hv5*B2V z*Ma)IZ``pML2_S!vjMh22C<6C1^kFT`_ANiprX1nd6Re}Igf~O{b;ELSQmJflem$n zn7+~>R;c76OvuAMy_x5zVT~IG!rz5fFz&9sxyqhpv|MK2Kz9U%?`y+y=2SC(=lBl! zzO!}ju31r3pU2=CXQ9w|G~c&DTJBIe*6KVM9VdVWbhGfQyzZE(xC8wDC6e(KKq*kN z83=)&miwAGE=2bf!mfMq1N88e4EnnjKW5(L!IS53caV9%!9aCbBtAn&Lr!_pE3Nh6 z2b!Nr%#i-%W32uJvZjJ{`uSjTWaScCN`VAiUb7lk)$Wtsv9G&gE%sjLp3~O zYT()gHIT-xhWRMCQM>_8xfMcc^TvZ=XtWK@A|w}?MY737_yPOeiy!o5F@8|fL-=tu zp)Xhu741ulslj%<+Atg{^dt7tj+%`Q+Z|njw5db%OBH z1#j*^7l1p!R~y7B;IV2t2*75dKgMai%_13aKyh{yfL2}&dJ(lOvX(?kt|QHmzRWI6 zMSKu&6Uw1DSu0e0u`NzrP4-!&irQ2K9J-{sIb%rf@Qn#N(i*k9pL5Vm75h|zh2bbJ zE+MVobhM`SLbo}1;DEJL$EWDM&C&XEptaEoZoPKNyPyj~>8cY~=)PUtgN)N)+Y{F( ze+m!4eaW9Du1j9CfAX5S$!imhcX62yW&U*>xWfH;cyedF>v}C;aB0gabh1Ak$0#Ob z7T^-J!G81Wc`c2Bn3}PZhvHrt*zyC$m8TxW!JTmvD^vGqlyIIvFD07y$5jZ~DMRc% zjH!Xy(~ijWV$m_lK_!}3VCfV(Ky(`(v6FBKJes(lsZx3w&x`boV{fob%9d@aNU!dn zUU`X@p@{26A8`3@na!q=o#^{&VQ^%R{yrX?n^d*Yz;V3A;4p79wAYl@^*Xv=&a`7g zevyP?QepW@wPVWHV4&Y_se2SWqHVAxp&S50Ij9opD)v7#q8xG#Nl^Er*Vtv*DZTaJ z>D9O?O=lJ9mjzxnTRe$_B3^zRVRmB7y+t-26y7aAluYub!peAbZsyR; zs@b!CTGsF}aV>M6hL`%;x`obPs_!_SNv@8fxvO8I=}1`2O*mcFi+Qaq(YP-*S!d6> z20p8vO!BHk)9=A_3Y3N)?wy}N60rPOk(oInGj(Xogb|opv;DCQX3~TV0@P}-H}Sa} z;Pr>Co~>KtIoS^fvj{@a&=m-*5jWeh9PxRCV)r!8m?9HI?ZQN33-*7dt9eof0?K}x zEhD&iG^hxoH9aiM&aBK1z{TnqATQ6$ez^v_x*DtVL}35pP<}ZLd|~7{wKKkfFGcUJ zT}vA5@jtVJoz+Gom;}zz&ImE)fkQZROd95#apAGHQDuchJzIyXTZJPWV9Uc%wDP)z z*?okj^_e=LiHF_|n(Fe<1QWTC_B_T2F3h2c@m0Y;xSB#U;PHurvlr*AV?SSR1%Ifv z+%RKVlxL%BGRF-SiwwmbtZT~}PGE8o6yYr6MJ|Z|Rzv1(8e9k|0NnBHjd6Y*ocMgoDk4erUey%_~1t-CW+Ghj)IsS{Qj0 zd>stg^_>q_5pypFyRo97AFd)wXRw+GdOGu=5JXQ-a2YD18Ul-+j!>jqaet>%{$vP< z%Qlr)Os?#NFQo1|`9S7nvF3qu1beFw<$0Qub8)P<-QJ`tS2NFhX)emv&TXGq$;ZsZ zs?5YunIWC0O$d5tGG zcQ^^zb6;_o`LL7Fd1xG%!Bua`t4v%0CWlI+y(7~C>?$+qU^3dVX$9e(+AmYvJ9dv5 zcL%%J!4)UFJ+TotxDO!+3C1C|;*{a&r&{W|Xm=ozuCmo$Q`$w#MWSyF=;%=W2= zIye!P?3i)wF}{y@1QO*ZaBfi}z@v9Pf!rTC&;$3%dI=Q%Cb{|CK)ZL4W9#F#VlaElZdxH!90UHeF%XZ+Neu+fm zp?HHK6yP7|UI}y?H1`LP^rtJEXk7PS@#V}a1{eqVu$3X{Oo z{F)?wEETB7(I~8BF?U z`}L+V++_{`gXmYGW_Ul`5W?V%sQM$M^$7(%wR8LXLf|7o`A6HWdl;Q-?I|Fz_>}$r zS#X*O{B`kkHs0wZYdV%^_rgKs^tSTE74(b4dv~&l)=9Tjd}_I5+8;fpv%>G{V2^9# zH|R$}4m)xk*YqNKZt+fU#Yw1i&a7ViKReO*1^l30XvG@*#b6;5r3EJ*CpqUkZK+*} zgm1VPpc2bu1c$fbNXXC&UZ>}Vdmq@8+0>p~&2PBO1sV#uDAqm9T&MZ7| z)U5Vo7hWQ-E$v8Z>#WBl+>-}or;dPg{MGgeBM8L|vp64)`NB=h-D|0DLk@P$6X}&F z$vC?0y$U#Z6FzFX{`$i>Y4Z(DAH;(Larx?5@6+DIJJVn~Kn@_DZrvj^Kb9 zJiI-*;Sjt8N07e!?)V13a!e!A%vddmu+5ZrA0@mc-^6DVi)QC2|E%q&{Fex8fk;Eu zFipAsgsrnA^k`yT_9nh$fws8)Y2=SKHVcD(m?-7HM6GSVc0!lgUS>(hw7GM8 z5s>k81dJwVPJKI+pSGpW#P>;*3NObp|_)`6Oo1LK%?s4`%KRW}*=k^PSV!zNcAa!3EVuhWk z!4zH5uy?l1x|3NK2I@1A=R1vh8+Hvjji@cAjcA{s{TMtTE;HRW0!||Yo}wnhq3Esg zp3#LUfymuImYs#L=*(p5QtW^-t|!+~Zh<0cqzERt&y6SZEJ{u3apb^&Ce+xT!gX#* zf+a-6!v#KJIxZN+voMoTp8Ra;MgCYOX9oWk!u| z!|v<#Py|Emz9jm4O12KVts2cK46z!49PP;($#h-S>2(3mx@WfJ=BIdgrc2BSp4kuj zh9B)Zzv7igzMIdLoAS7F6IhZ{ ziXZO!x zqA_u)Cif`IL&$VZ7uj2N&=Uj>MWA?k6&;1xN2$WnGCMI6-prdDCT90!%8pwkI+#%a zh#|Ph?p$Dx>oX0G3&~AbJ$C=f_@$T+vpR#x1x^Gq=14JS3_i)0(KzH}97+!qN`)~l zn1LAAIwRjF4yOY+MvxI~kKH0j98pY>vy%+MBza=t5mNj45I)V2S3yp5>tGilXOu*> zuVU7w7Q}+1H^3t57jo?qAgA+)&u>|LmL6d zTON=wd}|cJ8KM1Sa7mbNH<7u$O#BbE$v^EZ~EP^1mCCw7Z$z2F!lk z&CP~h2(mJ{`XW{a4YP+ReBORKgQ=sH?|v}O2iA5qZQoeCX=7bS>QWx#u3NM*iKoR# zl(4Z5X8ewib8u5lG74uM|2DCr8$H_;StJvej zk=sseb3OwSXr3|_o>iwqGNXk1fH|gGaSEm5bu`xT1sw40zA8MQVm%bW7cxtvaHmFb ze1&jNJ5jr_uFkdOXVxr1JBMGtzlA1Cy0 zOs>noyL8+rYKGN9ypA1*g#uD&5RZj74$k%_*P&Z}@7Ig1{?|5-ya1ESj8;3FEV2q(-O zXF*aYk=tn*tT9OxJu@X52hst78Hk~MCnp-2mk;<7H;vxH#X6mN0)VRP-p$S{mmNz( zYad$URN_=6c4dKSDC`SHkr>pA9ciTD5z zb9yr0!zY4k0e~-2!vWb!kY)Ex0FnQS53njUK*U21>9C7`VD9dL8_>8jqxK&74Y3!H4^9D2MzGL2KjP2x9Ei;;PTIiU~ptenb0Y@ctxz`jq(zTZ+D zKOtj*_G$_CeH1_M&%U2^(Zyl=zII(HCceiQk{?53h)eTLeBjSUGHQ0V6A(|`SVR9^ zOhuiOt7zx1i`e_YC1Lzoe`Hbn7M3j(4lG+xy>H7lf~rExwm>(AMoQfn9%+|R8jRWO zz5qE!AAzCJ7QF zWIFQag3x$7BI9L%D)l3mhvwurZ7#YSUH?c~I6!mOduY70FQo5T$Q6LT2iiiWTdcm1 z3=iDc6$*G)67&?X5dx}5zqr-wFA zZb=F&-mFj7(}htB@5Q=?QCJRS_oB(v#5|YQl7gF{6;DbNoQ9D*x(z`v#!j%D+3E;| zxy?_ov#yn?5RDBD%3lJ4v$X-a)`~S1T1T+8zcRQcPZ^*=>c8vQ>^wDl zQ)hB+XWhzda%E@oD$a*E-^;^~tKq94Rd^m2WD;>Y>lzt%Uf0GLbR_43mkj6c>mE`8 zp4A0(n}_b0(#Qh;=u9@s-b^(83+$J;vIqYgyK`gh{EpR~UC6K2*12utCfKAG^>5g7 zV@G#6rkbJtJQnl=-gItE&PSkS)kZf%V9rBkgt~>D$%Pv+9U&$bL+O};0bSKGW#03F zNes}6zxDn)y@6iB*XuA!K;jK5YhAW|yEt7}swMwyOUhkQL3#g%l*zi`ZKA0XJ6Xy`}m&PbM~d>7vg@a zU1wiffjsyPpEr2G4$IgxE9+aQe;hiu@-wU*Yu(CuP8tzFaO<3vY*qVNi1V$&0&r{B zT4cAwx6RoBILyxF-Eb%jleg`YElr%a(IYN?xgDTz3zxbrdp*Ch$VRT`b!2jIPCsBW z!g1K;_|&dy&@!%_2usIJ~=ATH zI9P=${Qk!ooTQ*^#|+Hwn?1j>VFuE=d>`EI2WK^F`r=AB*sexRI;QMCD}89chW$Vj zGk@Z1m@cPyx=hN^>_|9eIM<^MfroET6g; zQN~0m(FSySv~u9M>Y)&g-OVvW40!w^vOj?Q&2rBm1%VTFI4+n$EH6fCHzurb83{~0 z*GoQe7qdIC6WP4fgT@$;bS=-zKe!h=ZpBJq-SfM5X$}8#_UyTISe7U5ud1K(_BrJZ zW2PU3KZaH|48+f&&@(B-PkS$-%WejKsZYOsa>F3^0_V(UGMUXkvtJ$wkA4^C0nC{Q zV|%`RGLyB50o4-65y{_1&E5Nyr z@e*3c&Jg@p$p1T|3H(-WCJ`-bP>`NL+vycMXX=opViAB7xFKp>s_lZ`+hl02OO74U zjmb5*DuB8X!wz`|IhBX3B4ZkDtw=QAjvym!!l6r0@@9*l7{xeUrRFQ5WW19Yj!C{m z?vB%tZf~*gMe-q;F9qrLRyBMPGl$lt#=gPK#;x|*XTe5x&0zeBu|m8%=0{kLi)rNZ z6q*?Z^X)x9<6-r@CABs)d8iFU4DFZUoVKfu3NF$3G!=LS^UyY4NnB#Yjid1gJuTTu zLr4f>#%fsC1^h~eh(ohVU{};KJ`JI!#4mL}f7NT$q*Tj7qX`(z;VbwCHJio{cu(!# zD771Rr@9J#e>d;@zo`50oqfY^W!2+RZg~OU(<^X;&7$CO>Nx6mb-Jkyeo@{F8a_u+ zW@>YB{6LBU<}C3S7stOI=7#F|$PgAhic!`xUh{(yARv|;`@-Mb{0a2Dee&>Omtdlr zJYwoCdt$E=vXW@L7#|#9qWLp;!j+3HSgPBFET*_2Kw}{plZ%WrEjfZ#EBpN4! zG~|N(yRtyP37&rY1IU*lKO`F087_+}caAT2heI;kGUXmFQV!TgldUL9X;NdswScAY zSWI(%{wYskq66Xe>jLl`*00#NFQv^~96-~;X zOV*A>qrBLri&`(56(QD(p%2*B>#V!CGkI@k?Mkc&-QU>ggM-SvUmHm+{Tv37OD)|$ z(fA@>gwjOMW18r>omyFTYFQ~9jehDYowM#nw&=T+EqYPsd5hL#>2coO*(nRd$)e{m zS@hgavxIExc&Srs$YLp@6IZ0sx=UIOytlyQ2U*Cg3Q4e&3!bInoWYDj-WoMal?+IT z@`)>lL3b(dbnV*CS}fvL;wl#9lg{POE=Shsx|KE^_S)_&z9VyW<5T0%6MkTp?6tvv zvLdFNel!HEi`4-I9Qg`@$qv$&{T$ygC3OgjJ0W@g@HssT_koz(?Zcd6$7Il+XyoQ{ z%k^_NquBMA;Qv)k{2O~t-t^*}`*lFU2tPz<1Vb=bjk(o)lSFM?Ir>9jZ z<4yk=x1)dSO#cvg%S>c;B4#_bMYs5Ic({VM3fH%Ou<@8W`>n2TFB>^*)r9i0;C8Y( z)Dqfn`Q=tehRYy8HA$=O4Beo%L&3L9KM-U_GsP9pBQS#m;9_85j1^H^|UZgcw zPO9x^Mw(*;qd&rwdr_@bdUS;lz0Z#E^gEPf+mTkys4#W<=5tJ_@tPi>Z*F=G{sz7U zk^Ok{d*E31F%Z@+qOg8~9=A*^|#1yY9mB%(~1m=hUqT>uVSYSYhp{wMO>%vyg#*P~G+y zE#J8KYnN8P7I|U*o}N{;Z(ZVNZ7Y-?5ACP7j-I~L=r-h~2M;yk*hK4MdMfJbTV1)u z9836_(_Z+Qu7~h5je9=Fj+gE2viP$EvG+!z-IJbSyU2zXt_Pix{`UQV_6~nv3aX#p2*OXfLgM8V-u$16;GXYW+AwYNTFSyz1}cflxEw;r&?i{)xq- z@P~UprF!vus12+0`xbA(AEEcd3BM+F^Wwd7@P@w)y`Ir)(+|*V@Lx%6Nq5Zwt{@wrLmJ>e@zKyw5uM-+-1ahd(Dc7# zzk>Tjm-SnhslcAos_1$E@(in-`KXyz1<_yCP)OQNs;OIES!Nr^tsl}osI@A)TjKum z`td)-%7*b;(~qtnKfZkW%=+=)DrfZ#-!ODfH0wUr@n0^t{CHgb_|wbbmp*!Q8~v%S z|MlsuC$il1OYzq?@%@vo{G%Lo*HpZwe|E-d^Im4pnw-9=AAgkEz3`R#@w=e@MDxed ztNQVSY`YgeQ9u3~`omY%kN*XJQ?rSyY8i&IG*n^tAJEJR7ybtS4|VO|j`s1qk9ofE z3U-9?PA{1EgDqU+_dyawbsdZ!^fRvZHPD|ZeQ~1kXaLoZZ{*i7AJ_kYYqoIXcNe}A zjm&pkKmOysKHkR)xHI*WzNorv4Q_;llDJoP1>~FbH_kuw?iXmO7dmzN4@v(-V>P%` z?O*W}@iYExU++tRV*h_Gx}4+RzoX~ecwW}?cm4MXd~OA|MD#jFCVqi`$<}+fp~uB; zyf3L-;)<8lkDpq7h&VOXkK~BbkBP<=dTzDPsh?qX2Oe`gk=HJ`%i!15|1Z^_!=Lzt z+-U3P?ZNfLws~&ieR7%Fsx{^g9gJgWqVXGmG2f?ugES+5aovHxPjL0TX2y4ntLHTk zC{hn%Dep2c-%K?A!TdEf(X>1tZg9hF)VoijiF*^i21{Q`XQGk*c1m&s2#u#&ixwB z!2c&V97H*97*;>NT=<1weS8J??LHILmx=q9WuU-ZYpwau{)_EL-gnrz)#qY1$8XgX zm^id~H(^GDN9jl3woXXNo8)~=DA*yzU{@Y7BfS}t`y2eiTlDF~6?7{JpWu(61rPXz zV>r2CT>sQ%*uQW~xNO}9-a@pg;VB$Y+ttvE`;&DWrnk9N*MMejq>zKi9Hxh9Yrce> z>Ly7szVyJL$1=ayHH4Mi@9g-wQIfmAiuWniz$DoKlf<;Ygm&K>xAF4Z``WsnZbf|I zfX+20ymG}w%Mf;mh$Z*p?)uh??(96S3c*a~RekHt%yRJaAfG<_KYQ+l+=jvO^PiD^oO^(m{!+`S}uHMmCJZ z|DT54bpn2e)FBM2ovW&{?w@D-XTM5M51B&{-5UyDttotUU)Wwo z>`e|gzz2KfarOVeGu8vRxd6+6o$WGUFqQ#$aR|0i!}dRN5IjF;R?UPHPbynXZ_kXs zV%mWooKiD(P{SI4;xQ~vP>JA>gA#Y)REl+1!_LnfqchcbR zKkf%&_xzkOV-Le45&f(FzM9|PXJuHT7w2HX0?EH{Tyk)t`Chb(#FmM>RzULEW3dK% zkGuou;d6<*cEfBTZy)=JWsdc{m?7f zqmg^2mt*MuoYjLk*gmDIUoSk+*^{w`Qvr;%-?n})NQL^5R*fAs{rs`1!Kt;`DP3I3 z4GQDL-Mx$I+4Jt-nYMb^77Gn%Pxfd?NPAjhd*eo3@CXNu5&KSTCOwX+H256^T?~0k z_t4(KX`#Wx(``&1jp!(Dcw@q@_S9Ts{W^fxde``v211pa`(rCy9uLq;RJ*Iwx4;&2@chfoG_>;#{I6V!{tb_bhKIuYm zUmqYbAxJOq1AQ6(1078Gu!qUM>=!-N1~V?*VvEr)cB8NDt=sOKhmA!KMu4Xe_}t<=i@&PvL7$7AL&@~ABWkG zjFMu9=za1Z_p={q*YG1__^q{Kx(6$M>MuS&~jJ|M39(@kRTQo-qG$ zxc#`&ex%#Xf8+|EZT`-Fq%X~XJkWl;(te}^&wm_cKb~hl(#z*RjV!<$be&@<>ue#(B_U_a7*=ssexwf9pv;FVtf+2A33 zH~P$D>C5>~dF5blwj9^bY~{hehWzL3&B^CL3_r#k&y&xwcB%89Az)$j`q5ild(4M2 zrPmnSYZ{(L+y^_G3u?elP_DOiy)!n2o0VeA*`v07*nl|YXhQ@TwzOGixM76+OSErjoz!WY;UJK-l!6 zTF-rmGyaD8L6ML!jw^>7sv7N!s#d~EGDf^vUm$qWP0Zo1%BhA*I58onkkgc^=zh@D zmsK81RsowbS1H={o>xo_SWghHDFr2E$^|p|C*Dso_pd1JJD$U%ySm8exXwZ(-zgEx zSdK=-&lSAq;xF#~TTmqRt?DutoH_bhbYtR%g;qO^At7}`$v~K;XCV%82%`9z4ZR<) z;%N8`m)Ui=b^$kT4$1P;O?nY@;gK53T;2QmSAJ819w-<2#5-(Rzy_>j? z2h8Xzndy8bCpV0em*kLo?9n$Io49WU79ts(H^DN57qTNbuF7@6t!H-#gLsP_eJ7C? zSQaeD#2R8j?=7+I*#2vaZXj61xcOK?o2`I}0b?r=UpjdoiLe}cS@uP9AOvzDS;G(- zU=qluK5Qw;NO7ViQHmcL;pJc(mEnT~LLKwSAfAa!FaQkzMK?#C^^BT1sK z2koK}EDw^nJUW#S+&2vzUV#>BIadPbh#8{UuvbBk5^|S=Wl$)!0?IbOf96xe-;33& zo<67OW+J!4BKPGea&I_tyfLw&>l0^rVqK7K^Lk(n=Y=+>P{Z^G2Xtl`p@ODntkGwpK22rBxJBN1JEm4T;xZCfB*s)LtJM_iE| z_I~O1E8<1(?>h(z-`8hv?@`LZByVjZIm%8uy!6&oPzVe+uyn z+M`~_;S%sF;qW>=EZNjlcGjYyFA027|eIx84mE$6Ea%Fd>m5}>n5G)EZ zxR`q|l8Xm6)44N3;6(08G@gtJ4;tjXLlRA^fETN`kn3ngKk8W_#~x>J(Zpk6@@x!- zpkT~+vd16;M0K!D^Q8it8MKd@aLfTe#vU*o!7&jtvdn-)(;UtWlht1EXA~A6JF>H# z-7-%n?&=t~SHn;`DlHxWb{gX1I~iLUZ5Wrc zu7Nwkos4*BOcV&ouMWnbKdyb^D>ERt2^PKV8uLtvLr1URTg`(GZ=;_Yy#~f+a&zhw zhU6(B9U0scVq9JC1y2Q2P|)fP3>^Gubl@Ju?1_~bctg;WDb>N97@Qe&@NpCwyYKXY z*(sY7cRj}IrjlKwpBg)4`VHCI&G0#>tgfPwhP`~~kA@S%uB1Jz(}$DNs($@mfTQS;v8ft_3&2?G zJroMxdX{=9Y5lf^{Yu@BY9ZrU6-4kZo=^2tYT&Q~h_1EvV~osEN0kL-q&*CZF#gU# zPiSl^{usIl9sUBQSp1Ahzf*0t)-Bp+d_Mh7CB~cjWO~-%YVM0(0~Lb5D-B*?NT40) zxsaI9yiLC|9GdK%k*QbG?~EqCv>*NOXVE3$5jE_~ZY8d`2=&o%2h5EgJ1Wt{ePqT% z*qN(oOD4InVSf4@sF&9P3QaR>F#diFV5pb(U_#FrrybOd(bkthdBG}ylLt_S7jcH- z=>Ug|EPrbRY`KCJ~O; zuy#nb19kme8Ln>2gY!|}!}QYxKjU9?=d=b{{wbywe+L)ynZ77P$KVHiW-yd}KAq1J z3Il&4pXqC{-+9*UVPe}pAIfK{Gy6=x$;0$P+2@`4Ot+JLeh1?JFd5Z8ck`K^F8j<( z`ws)_?)fo3lR)ftW5`VkvFjI{fP&y#li`#V zi+s*rnu56cURt*Jpde;_wG%stMF+3tGTK9!*c=Ul*WuE@y2}L_28@$zZK+#I7T|#%&t$LUbd-|KKp!rF3!;j!!L`u{@|n zh3&}&8dQEwsS~;2^IL+cL%_SW3)yRqkb`CDwX^(^3sB{P8B0v&eBgJ=f^mZ`T#G0t zvg#_5pmxEy-7dT%ao6$+%%`v{=j-L7vAZR%I0@3>KLkhPDH5Og=?YLjz4fx`Rf~^* zMKN+v@MmorSGM?9vlw=^_-gahXnvM$(95ok`nl6Q%`-m@=H=N2a)WuAW}eP7Ps_~D zSIy5|=I3v-j%Gs_U8FjHV_yEu{2Vt+FUOjn&zhfGYE+=g{QMrf_$a=Y`F7<-J-vE~ zewLb_-E;cW}WS+iYem-x0K4E_Po1eE0alUT~)R`8h+2ZEs zO#^b(dJScfdAj>Qjv{exGf#+*;M2M0<>$@Q2=lX-`59<_t~LekGYw5LPw$zkx0;`k z=4JX_)(O3Y^&MxnG6tD|s}W*y+4P+mxohXw#Qkk#?U!5}L_vHkRc0vObTL(C_?ap* z{7e-ce&!L&@H16%_?f=-@bj*D&zvH{->LG$&s6#0=RNYC^W$r&P($#*4?G&s71h~_ zFpd&3-0EAgwIX}L;%PIEot47^gB`N>>56+w|L$v;6JWkhr0FxU`pWCE9Gqwlw@uXi z-~C|v$o@0#%9az+uZ$~8A33nTb;hrnTvhC%C~K28uw&q5D< zz^oSOBdZe4)9{C?z136;dMBDExtFW;vdYX?iRMGy`(Cw2Gm`d4<6&Pn<2a#~EmVK^ zd9}xx4=w~Wi9e7ZaEKdXz_<~$&HzKTKKNA*YLMxF^9uKRj9&M5?cd?ve;etL7P74f&(##4ktcd3?6$O)7)fWV4`36%0x=Z^dk_;cRuo z0pFi&$Fn>-o;#sfbA0+~*3+iqLjJEo+(f$aE0Lz(xFTGHilcpE4fRcM1?`R_D-+Gr zT@QwLfoTS%-|px1R^u+VAAgGWWB=|9+m{@8bA;g+2g&q2BK*c*IBE?cQ%T^*DGQQ5BMh z1?-Po*EC=3-XEd&J308X-TUM5J|suSSUKJs_$Wn=_eVWYOo`^*U4>`)3c0?#1^NJd zmmY;*C;X^4O6QTpZwHQ;LjDuYtMP}1a*6FS_0c`<20r90 z5zJP-0~5{XyDHjj6_kfL(eiU)LFD*PdUAq_(L`;I!p?r70Cuoo#jC3^;6!?tD6ck{ z?pZZ#d6hrGb8mC>xLNv9{GrizY4na!9&oR#ULy7~%qz+|)0t7bkXxvZ-Hi=$eVERWz6)+O#LJ0a4G zD0dx31Rbn)#q6(uUWxP{qjSrRHx$ghZ*H+Nz8QZA9mCOQNWIg?&5yYcQ}w~)^&a>B z5)Lv)$JRcPHCt^uWL@CuX^qx@ihF-+wEp(vBWQRdGCx@)euCK8TNO}EToc9IUYCc} zge@|ZMP9)ro9QEsYELwG;7KT1tR4uj*OH91uhM5m`SqZP?m=Z`!90~$v9qCd66u9e zxrzu3RORqx%re71kTSnqeS z^`Ge9uhaW#`~GnMzUsd;&)WC<`1eQYz3Wefe?JxPtwH!3%8C3@iS+eRRNpgCcE44Q zT-5|^Z%Eh^&5Q7duyn4fGWOiRlM()mDvQx9KU?KF|GDzBS)Rm$9dM+;BK)R;i6@nP-Al@-%wq+0D>DPkrJ>9b=taSI| zXfFc7sSPhIbVRo z`v#mLz#`ZtGJ;w`6v4J|dAJ~Ugzen`QOfv&f9`nj=mGPRNP;3C2d-I=`g=VlP2>iFok`VN+cA{WtCv4lM#^Mp_ZX(}F00n70ei zBd0if%n{&-zS(11sZAdyz#@F4CC4t&&PAnGny?!;BDWye%W`*&)UM%$%OyzduT@i# z-q5WTTqX#Qs%UStPN?g%H{(j|%^o}I4V`Ym>pdKKk=~3T#9sulBi#G}5T)RzNi~gh zST4>aX9&g*tx+Cm=dAgvLX9VH@6ldWe3E|0V-K;ON@0;XgPEBjs;~6nx!)7h5Of+i!=e8zoG&l^Z6h$^jlVo zFRU4WewGCf3Bq&V9||FUE(p(k^9mtm0s>>`(=$6&HF>mMR>;Sn5rh}vR0P7>S$neE zJ4HM7o5RA!?S6!Kxho~f+&H3=0yRc#*~!qbV2xjM-`zUP8Ed5VvJh; zEFelzJ%dzJ30(T(tHeMF^V4Dhdb$)Bke>+94|7)k@H`BZ!u}P6XQ!CC{6s-`M8w&@ zg4oe)KR^&(x?*gKzrVtb;2>#Bo`|d;?3s#8aSZEWV@70&5 zhkIoKxjh!#AVA-_*9?+u=Pcmf1pJ`@OF(;4fFA9;niWj6#>ZIWPyvqYd!l`VnbjtF zvA88-BT6GYDG1*=J4vDuzb3j%5PqD+we}SNd>>l-Gy`6$)*hj5lpwgtAYcZ^+Z@yws#K|y#*ydHtjTy~=%Jex$lJ+cF52*TrSQ=|^HQY#3rYh%>k z;eg0je?!7+Nz=t(X9IVk;TW^#tg%Z8nH`4lgO^`YeYM{gPI7Bgq9wdGeGqUhlRSe( zmAee18wKGxE2`WNAP#2;VpQKu`XvD#(Kq0Mr2@YDBD-Hg(@zVq$T*3V;E#eRGR|Ry z_=zBPM8)#}Q3@542Ch#ke!{@@NyUF}A{xBNbQ%NLDrpiwcv=u1Q89}CkI_2*VjTD3 zI({MuFHMgWLYyZEFHLsS$jY0f=|n;J=_F<<_>>^LG)0Yh)iFR2o(@rWxNMuhzd(HW zew-7TP6V++5Id6UUkk$b<6DtBB-NJ*!t+#g0yzX&haXrI$X5mES?jYAyH4FXLJ*!j z#chzC0SFHJO4#Q#G%Wu{!3QrtAHl$rk!6*7zf2IG5^Ew5n%I9O2#nt?gx6B1hl?9&_ghyuass={ejPaqrx{+h|{Bhh*!}EgB{fHp^T=<*FjIOcY zA_zbB;&b6e0DK>F;fV&k)VXk|y5aHm-;tHA$hd7ogwX$tKxlgE5QJy-mkJ^76NDdZ z%mj9wAUuD5EV8Soeq103&k6$~5bDQNL6kt@g9YfdS&XjQNe~__FGbi%`tIfR5gyoJ zAjoMD7HhK!@BsmOR)|qZ^913sQ=Aok1i<&f3KI-?sjRS@x-q8j$+PP@4&Br0%ZA=| z=$f!s3BprixDkB|!Jpt(L3nCTD6HdhL3k2e65%R~;A&R&H352QjA{`J$e&;o0D-;} zO-;sRp$Wt;hdnA)2JWaZ9CuzloFP@Psgrmp0b%zG(3>SO`{>sT!lN|C(!5X*9$_~` z*k7~O$%60*i?Kxy6NI0&qL`8h?IH*-%GttJx;r>%&#W<`yhadb^vy@}1$e9je9z2U zVV!-cAf`HqsCQ3;K0^=_97JMn*fS@$<&lE$$dCH}RL2lOc+^Jyf2w24-y(x9E}@SL z&6IlRS8Q00Q~n2mwh^enOB>nPsX{Q~sd z{kU1bSVD^g*9*e)?n4m>k>El>cqxz3*(VF4+6}4ls_?9=It~+r=k6F)yo(?_cV8b_ zX+cet1>Jw;pnXrjT&UXC2*UUD3xyEB6NKlI81>jB2rsF_3hOvq5H)VJ(O3nm^%Sdc zqyRlyYD`s}Qgaj4J{;L@0`%A^u5i1aiAY0Kjf55M!vZWpLHJcM$H(6aAs!IKj_@&05T`m;Zi$RmSf4J4sScvJrkNtZ;~ikk8uL&=OmGk}Ys`Uy z@XYu}GY4A4NsqkxB+=rv?EDCXI{b(rJc(n-bBiE6iDTGgjvzdFV%EB63c{l{X0{nG zh@;$SW0pnx2;v9_5wo&?dmTsX@nI(d5T6P}?D{uBczhfi3EdVx{v-&`jMqezkZ^jf zApB^biI{tAEcj1BcxHSe6Q1g|MEEiwFtn8|LiGh(igvA#gKBcqMciGLA< zA8m|I{DUC;Xp8H_MgjUke=4GOr0TvU2tVlJT63%bOVEim0`y2Kt`lEfLri!^jltC; zg7Dak!Ne_s@VrwT6Bh~4BenQAPZprZ?cotF5H}ts2ru=;XNUd*^w=+siH)nJ1C|@J z&$v|LTqS=3TuH8ys|4sJ{GmIvXG$Kn4w&Hkg7CUFMoSzoh#isVAVGNY#ISOuAUt_u z2>4Pvhvex}oPbLN=;>0NfUN>7fjr+8Ucq6GQ+ngBf=i_6z20eW&4SAPQpSb}^# zzoInxx({$6^*7cqlGSSb39b`_XZh$3p7p87MezdxdT#ktAy0l$5T09x6+#>=2v5Kv zg%CRl!V@r22=VfA4#^X6Kq163L3nh>$oa1X;qe?J=d%Rir6)$tPZxye{27I7@v(yN z_=xd7?j;D1kC@f^zn5{eo*ARQMXiFK7K9(|4QWd5EERRF#|ll)L!i?Krc%%oblfeN4Px3FTGw6o-<;2XNe%Zev0yrW}+Je;d$qt zh}T&VDM5HixxEnL6hV0Iis7Bng7Dlmzp##kAa=xE|Fx9(@ED63?PG%Qvb4^uJ+1dl zuH4@X!fTG0{q<%+c#O42)~~ALJA&}|_;Vq|Btdw5RGR(S$oww|kB_?}bx0|1|1(GH z@e#vn8wGKOW5$^E{DXox)j`}6>BqrT{Wl82i`ma35c?5gh9JC9TpNKHNr+lOc&VRk z>~T9kCmQ8s#*#H$4HZ3hwKQ@K?TXE})C3gKb_ z`d(dGIQFmQb*B*GKLjz-HTL5|h>rIu^AwIke#YoxXg7EWPjFjCW2roRv8UJzt`VPko=`2B<>V^~pakL;# zau6{?8Y+lm9Yjorw=L$Ny#U4xxnLU0W2tU7^Wo9vw z80$Jw`ip|_d_AoY;$T5|S&o^3c*;1m@{8g8m+vQp=h_&~UnU4Yzr=W9eAxYMi8DCqA^%fPye_t!V58z*;+w(630wt zw+q6nuIf!;=d@kvD5!Cc06i~Qf0m`RG}xJf@VpSS%p5NW&kHeboP7l0c_DiCQG_g*5xQ!ZxR|AZhs2Q@@m5y=(`!mH5lMIh9V zD+S@zaB-IZrU1`%=q?U8Mu47?w!ct};}Qb&{Padqz*p`eCOlicQWWsd0vzW0*ijVl zIstk%Tw4_I2Lkj=7Gq_6Q4rOx%@`}=U_g{&Wo*Bj!~C|ZY1xHgXY7GwnvH@u%R$62 z&4YsQ8q9`YS=Q9its4d5Cpx<~Y#~Oll^KFK$+faP!ZZX7Y6amLZ%zb4tsE{0&v-G~ zWH&*0A$l-Uhg$jPABhhyL^0araY1+?y1THBI{*RPFEC$>NRNU@6P*%i!+t^9z}*~% z8xA-QMsS8#g3}G$)nPaWH4<^*pvJ=u+^jGhRf(^!Qs@nK23*Ue28Zh(nq4mrAHWCT zCkPf1;(P}YL-Te)T;d>#OXkf2^dcOiQ7#dLXTfh2cIWGYILkE_L)bBb@GKY;uezro zPIYy}kp9iPIB3tLF;mS`g7A7PCZctbAUu=Cu+PV_=sCCeob=kAV&Lx^O5_-ryb)&L3{T9IfvOGO9wjf|sR z(dS*!14}Jh;fg-uioW)H4zYw*R|8N(TwH32pV<HrljVTgZUfFZt(o5Fw3R^P6$n)3;~E=dRc)|LM=oA%|eR(Y=x?vFSr zwK_PL1;IXz4Q{xns7wic9_@;L7JdQ^cSxy4xBSjh^cDP3lBlm_2_k4gWPpEAc|XA7 zO0vGJ~gvq$v6qMRIqqY&@KrRG&qyY5>f5-_{akGdub z@v%q<4_$P@?*!p7(^Q!9q$yg*PYnb;2(TdWe_3$0ApDT#nSSsSAmnN|CJIs9^c^BV zkM9_l;+9)DXy4(Pkq%2QJtGL;otU&6cSq}Z#bDTWm_I>lw2o;JAAk_|LqT|gpA>;O zfOVWC2(JxeoS%n8TPco~e$mEas(Rr!5t+CvqOLWhKMTU6C1yy!5QHDnsN2K4CSuJW z_gTkjJE}uy`P_~mK10OqAqcYwhMtT);>Db+!E3+fpm#K+)qp@1#S%ENmhj5_MpfuB z&{@bBGoldx5h1&Hy*ApZTO*XfOo{!EXdN+`6L*V3tc}zmCjaOBh#15O%Hx38!O*!{ z3=jQgRk&lMvrLc@pvO^^ONJBT6hZ8WETf|kpNU{m<4f$Ql|#@9&f6;umnN{^9V5alRI)A?cE?-byeB?XbjC`9*2IFD|-OX(C=8kR~J9JLNF0H&w zZ~62`@Q`{_*S4Nsr*bQnOn3_=EfM~ReThF zzRbsYd=%47;NyJ%IGT^Q`p5nGc&~rlgO3~hVsfJ5Ba#*e?60r zv;Ehpd>q1Vs8`3}u@&^kMZvsUkr&ooGQ8^DC3N5~WyocwJ+tDC+Y&b{Ph8VBdd-;S zsogWHvqOhxdBY$eaYN~f)+I1~%9hgGl6m2c+m;Zorofox4Nsbn)X@6K(fW_~E}>X2 zrRPT<*?<4>h9#Vp zk3-{BP^i9jNrDy8-KC1y+gwGTCJ}k3(^7iw1i((^0ICU~5z!z@r4vU}(7#AaO%m;+o|n)+Lso`??LuNT!vLeeJef|rDE z-j}nKDLmAvJbdrUkIVp~k9qi(-eUq0eaz#3m1NEieT>1k+U1tB0E*$exDpsZWQ+vf z?ZjFfAFO*R_u5Oshm;fd?$xh6d}zqr`q#%ie2Bb^9MH!oK4y+i2x`WIe=yYNO>|oMF4!t0o40GFvNubg>%5JBtLKa z>E6ZOIVOKnuk+|HK4b1EeT>rIOx}$0*2frm5Lub=NdW(o z@}NQR%xp>ckXGYqK=mt59(b5gAM@}Lm83j;2w6PJSPUPU*LWJT7(RqB#=Qt2DhJZX z8mChrB0!GCq>nY#@N}nYh{{1uA2V=<0EIkQqCOS|8M$2&zBMe(mNE9Bq=tdy>Tw>v z^^tMt`k04r*&_@^*2ftBizt4-CWN^TGR@AJr$G^HHDj_+KpUjrlx!NC)zagG%Pn zL+Iua34JW2$Lw)GO6`LQ- zFoT2uJ_!FZXX{d?vtSK{C@)c8sG~gjQWCzST$ab5Q7+5Fw}`=WJQ{BvzEzUPfb_AD zKaCl}lSBfD!MAGQVI%=W88nA)o@Ww348Fy9e$I^17t*XeT%{V=V4l8EABxLBY5L+L z)ZZGB*TQ-9P-neamPZfqKaZnms4?`2s^?<#aJbMKJclgNBdUFi(WAKb9Y~Er`_XvH zS{?>H;?{#7q5c)~^O&Zvl84Wza?Zo22FpXD#qgPvLe9f6_>2l(G5+={z7U^O@$kYx z#n(v1lfiM%&sIOtdF>wMYVq9xmZLKI^Pg{VCJqK^zojKjY^GO$q} z^YE|rA;Tk!;a}@R23iUr2LGy_A)5k-!M|!?@TUL@@o!c!j7JtgjD8WO7}6|&C>3On z2!K)10w71^WNH!V7+vL3ljHz?LIBm^OiZncascv9N=th)m-XcUruZ71To+C{2}_q@E{GcYhevRP=^`57jR6{X-aH!5(7mFX%Nx$rk;Rnqne&HO$58~<~>tgYPM$yN* zI7xEfdk}~br+;%4EM+~sJ4wp4XF^Jz{0ryInx>C=^p-`&q-**ZM{iGz76q6t3(-c4qJ~d9JpSWcA?@1Oq&@f}5J9=;7R90x}A0e3s-A3aW zqI@j>Xmmp)%E$7LYP^1bD$2(>|7ah4{L=q@d}=OXq9ieQ6raYf_+PRg_#ydM#owPj z%UpuOTAsd;1;A8T zW=21DvQR;n=%0{~m+TM9SsR?v;_&UAMS1!{#*}y1#PPRx*2Lgj==26gR8Me!)ljUs zl$X4}goux9U3IoBaerC;rz^_q(_1f_z8_B68hu+30buR2#Qkju5gGaVID5bBQeOJ0 z-jAZrifB#4MwFGwvhKc>`h4jM@SNC*pHo$%*K}W{_YA$# zHjF8DE~?^tQ6Q*i?-b9nl=sle8=!XEmJ%bO<_-sB_oGYy4{`4TA60S1k8hGCEVy!` zMny$U6%`dLu|9Z234st)f=CQd6_H1RR0uTe0;1H=-KE}Kqp8(uTVJ)-s`WvurAQUR zqlu_(DO$}6QEF|QYpBH+LQwgCzh~~;y?1vb{QCQSK7ag}yLaZynKNh3IdkUB<8mr0 z(bukavt2ecU|)mU(_jz#&w&H$KEW;~nNUe}@hFO|jv4Wt zr=zXh3*|Dwh;#qRI&PekG+8H8==Y;&Iyw_+FHlPC+wd!c%0>T05qeKTk=+ldGhhy& zC2GpX-jJ%?%^XI&7--QgvMOH_<*NKm7^ezl9|h&wS;y;3Iz;-|b422s2pMtvO905E ziyy}k0IzTx@s|l87K3i*Ks0q`sK9R%=e zzTc3}cL924twhGh08sQrteuX;co}laA)pez?%NNdWMt8n&WmO{a}Uzlg66jb6zAp^ zcU4sHG&16MGgnx{-L=9RudOxWiw>clJc_|(E~YtI>KV*j;R*NXW~t|}L#^k%ZeS9& z@M}cG1`4!SHRu{R% z^ei`ccEsX_bmb(3cb$&(4kkr zHAP-}8;Q(Mj$aezW|HIQ@3=!CCrDK}ndGQAiz1(2@=NDm_vfHT%$~ct@24k80CCOu zX+dF+pPn@Y5Yx+#6lUSyy)FPh{3if@313WrgD^OsEvf{djAKdwC907o4`;cRWsPDO z@jh;4Jq!e$dq9l{xDLL^xUD*oLslCBM8J7+AxnE60|2+woFQ9kzQHXuPCq!~G4g?AbWfZtLzxmA2$1NaBPc`gRttRxtyD=FSzP5@CKUOOcKBsm3emW!c> z$ao(YpohqK=ck$vZd}_R32h^Qugiq-DH~uDkdE9>t}xgNVjE;ZX5B>Khf>!A;SG801j22pCmFd7w#S} ze;1o>ZSM5P-^Dk$0D3qRsZ6oAf&kJWH4Ai~#!M2vL-dhT%X08Rv;vM=I_E_D{@z4oOW6HjGOdDjp*mu6p*1P}wn&pQi% z-@dGIG4RXG0^pa=dkNsPmp#a59RPcf&r|;b9HR4blp$^KyMQ%_4b)T2v_=%V0B$Va z--u5>1O^#bvWDD^_%;GaBYFs1{ssVPyW-vXH`(Wm_l?Bkj}rUs<6Hvxqr`suIF10) zST{=S9|F&C0eU#akWYYvbck#|=|IFm$&XN6;)EW(^0Ssf3CZP^8Cm4#Cj{{Kji2>P zT>!Ul{PHt}0AkL0i-}a>_a85GX>d=5kmD(Pf3%B%x2*^UKhr-b?3K>C+=kq9k*e%wF+S=Z#HCIaB+M+E`=9QE_#bQi$osGlFb2;i4?KR@2@ z0)SuI{X)120BNftj7K>BE#=XX_n#7zzw?MU)i*a0Kp5tBo`0~ON&q327vTs${DbvH zZWV6ta%@jkaSQ=uxOdOP_;)IN_JIcAjXqKZC)_CvZxFz*lq5L?@Eif8Ph6!WcnaVy z0>~_$cNj?(^pa8l-zC67l=3LL9OD2;Z;bmd>t+Atyyj>>#`$WoKj){&t!-Y%E&Ad% zu_hz_C{ovPSH7g#)nG{aXg`A>X`}sorn#fNeUjS~{9=b-_5>hT*=T_DG{5*EE%eVM z?<9asF!<3B0q{$H9RY*|{O*VV_$9xR0Me2Cbcq1?C4VphWU$h~EO|?D`7oCTen3Sq z_$B`Xj@{Cc{055v_$7afJGk>RE&|{;zmF5(ARQ@d8MgvZ&(EbsJ$NZ{9si%$glYU@ zu~g^h>M#O`X!4`S0^sLrf0rITZ%mude*SM=g*)N#bM;LE_*#_4)!(@QJx_RK5_>xU zQ*p~voZYP6_I`(`M2dK7I7@pkC4ex52fVYicaV#L7j_UJ)7=p7=)k{H{FfOEZzEIi zsmSHq08;Gbon~3+d4T}pnecM7EcD#x0`QhK0q{%p5&{T&c|n^1`1wB>05rCYC(Md6 zp0K3Hc*0pk=C_u90q;WqzcKU+c;`O>ApRontrK$m0^UXdse)JE2>_{2DcNHLkSch4 zo&fkwdV&BV^6r)oze%6%0=VXs_)=Ajb^&+|pj6>E>8B9DC$pJSAe+zjy$>HpNgOY> zBr2~wzK!g(!Pc*TFAzYu;d+jK{kx9BlrVt7on-RgVH` zQWfDN_x4TW#uP-;al<>O(!g0U8RJZ{AG=Tv4_2qN|h)TMf z+0*=A7lRvv@+-;vJApy^%H7oNH@OmEZwPQ!R*jyvy@0X9>)z#_c#5DQZN&xY#+(3Z8U!Da( z!-z<<2=cWcdOYN7p)(&~_vraAvH19s*(#B<831hdFQIwcQzn(&D7OaG$gKf4L5?%m zyN`G4bC=ir;=t-N$^1JJ>^APd1y5U@uy)}f-A`L$@q94eX< zTr}FOdK>j6!iI;`s5bzZ5&K)PB}?L2uVc!zc03}HR7K%pJRd}?d*obS+L26)V!Ntn zy@K1sDCVvHw3i9T4iq{CE^#s7?B8N;)|@_xyPp`+CUK85&7H)ln!e4nu?Q!N1?swc z9hZXTx5~eY`MgX^((JeKn$i4;TLF_6_8q`-+~=F3Ha>`H^z%e26#nFPq;a#Z!hgg8 zw1xA6bv&RfMn=KCMmVmr3770iMD-YBxSa4PkS7Sjp+p81mG(QPt=1u9l~&8NjZEX{ zq|$CAJ`Mpwu3e4EVGr@g(Jg?a|E3`8fGmR{CvOBy(M}C>SvHs(5ogaR*!otM#BU_C zBtG?rEQx1qM!nD72l1lXNy`%Z5%4VDVh?yb8$3ibgNE5G6#lcszCuHywx;uI>@AIUV{T&BYDoA9azmu%ZDs=*6k{JI{tTbxe- zpUq7hyp95ZY`55mQBR?A?W*5-u-k#kZ&&@!!^;FX$ao-=-G>0^j0duZ>@_egO_k$^ zfv$DDi%%MFui)$H6jFK$n$Oyk8{FC5LDNT8VL4+j+^F$cLAeQz=n z)8tnk{JTf+tG3x5j|axdb-c1l#6`)wJ(~PMJjtQgNEnikJI_e;l3#hUKhH>f4g?Ua zO%Pch{Hai3)HzS#GZIJ1J4(quJ|mHbca*bGZXGw435)Ii`vnbX-Un4wH2+tA;r1U6 z!BoqYw+mH$R*-qLEBQfMFRZiDaB=1gX#KVqP<@z8wjrWN?&_%`e&+tq5mw6ry z`zI4EM*JuUmlX|(a;%Tx(j~axd2l4uXoAa>j?Ual3Hn%sGn@5;mr0SJr%2>a%%#e% z-@9FMdwFx8b<2LGa`U~pKV&Wq+4|86b8kabA4H`CAvo?(IQsY? z&UPTE3+wyr5FCAd5Pcj7T7&h+Du}~;5dQ|-Nr&JVq#(jRh(9_IoU*RJP(d8-gZKp@ z%0tHL{;~aKhb(%hv{qhTpJx*wtAygG|DQ8Cw-D?Ek|&ovH&wD>XA;sPJU zFb6{VeW=j%^Y5GVK`HaQT|a~CRz0X~SII}joxBNfDnK8RZ# z2x-d%1#yxOVwwX%uWbFzssB<8s z>sBgKFYrN(cOZn+A1R0neGq4PA)ZqZ7x^GU4#Y8J>JL?Ohx#D?)vemXsq*??DTrY{ z2yUfhYx@&ot%4ZtgLuS&kgj`O(J{gY(cnNx_is};N_-I4IS|s?e<+BHeGnxMgmC?1 z1#yWF;&?BPrK(>>`XKi1Q*Ghky?(8twA2UjCLm(_$45_A-G2p+STD^T)9mzr8DZnU zb+Cv+{ARiI|7ahUW(PuA^M#^yj1QvDfe>LnOi4(&4`RFnK~H-9aSCFr58^Bbfh>^KcL0s;GXmB7z z4sTEp<9!ga=i~? zu$PYSDW1;oLG*PX=z^|)Le(`W>h&vFX4O5p3KbH6)W;zhUu^kG>QXfRA7h;yeagz_? zBnLwJC8BUF^Fe%p9dD#mEX;jMqi*p*yzM{;9nUC;CF3*wi#Cv~4yRcu$G zH7#W2c~6}6j%_Z)EyT^vxw20XU%VFA&f;UX!GWFdst%~vkpDHTU#-yvR#hS1%&P_l zJ@EZCfGR#%zc!oGLQ zvxEY3OW9YW(Y4J$OD3RIx_lZs_3F~1UelUAK$o>f53#Dw$D2#1f*+~@?DsK$IW+p# z0v`{?S#Wm9XnQcuF*oHM&&)w66p}b7m)4qYJGnHq>p4HF|(m zRpd=kbq#b;pIr${4GPvgJt`Z&gk7r(9)KP4%Xz_FRu7C9%g!J6wK&yH*uB;38E8Qd;&ePFFIl zNKY!_%8dPtlyfUmXx&b???kprO9KgMQdO>NSk!A;-?{iyuB+4b5EuQmEP=B-Z$XmMkIy+{$>@hnUn)!cMh~*8*ykRKGBtLh zRdtmg=HOH-8t1t*R*}a4J0~cUd{qhUi(0{cQKn2sK9AsCUVd_8G?8Yk6jS~pPEh0iM2 z<<9>$m?)y?{{vlM1DC%zln@IhmMEbcz2B&P`?U z7OINSqRdWk8JRg3vFGsQ*4Iw^GV4+BDOm~%H3wtKmprN^HI=ySu-!CQs;$wf>{pPT zS$$6$XI~6;R5iFGjQs;akxfVJdwa~vtTVmIL;f$yeu@KN3SX+PweQf5JX!DTZ%+Hv zjP5m;fAIyP(zqmspTE0x@lnMGn$5k|v`?+*UTgUm@_iUy3iBDhR~{TV1RhU~w=Zijc?P1P$a5)>d6f~bK$eig7>Xu^(G5)sGAn{+MaZlOw^bBy z51d(1Xjb$$D+btyE4&lEc#Zg{m<$L?60T7)q>@6}RuOJDE*y-Z54w9fud1n#Tc_XlYgXfdYjDHSqi5YOIwAn$x{{1>%GJp@sS!Q*Of>oa8ZsJv=h#ljz|`_ ztX17a32-~hoHE#~7-CL2-<&ekoKj*|l(OHZu;0vziDt!BX2n$d9n4A5no@twe?+Qq zh@GH0#AsrwHR_9i52@lL(CI7eSNH)-Z)*#R;Kw!wW8MAhKSIBObjB>*E}E$dUz;jy zZshr&3SB#6?z(oyLsPYf*)hq^j_JYVhaFQ2JEjcim{Qs?eVpA-;T-72X~a2GkoIsj z!NW<0VTEp&gN|C6Qwq!}TBX*aGOmlt-lMT>HzUGQ5%4f#t-7xw z*cPaoIIg@FmSa+RYiWMKo}lXT3I9b0tqV0UD(!NXi<+p($5|u(UrwmsDsGXrjN~G%%{KzcQncQ@8Gt&IBP^4vn zv3N~!TLncZU|*4e0`kDiVY1+GSj(WlVyB}Gzy%w4z|K>+V8K*=qDAXJW}JR}12j!s zV@S~?GTv4ZViWD>Q3|a~ldPW+7l#ckS?q1D+-O;~Z&Br3wkBGfeLnH&%we-LWe7;P z?BXGX3NG_#&`^pZ(qs->M*LV!gVt8ZPH<^Qz>2rMz~XDfc25bKQ$pqyVe<+R@hSby zDcWXSG041PusLN&Tg6am@&?QBxu z%ux?xn^`fqtzroHw4NrjVyIa`li5}w0^U|JE)aOR%zhT@h2V%sri}P~Nb@(t6(=rg z>1JqSZQrPH0AZ>Vu?~UD3W$iZ#MLHk_qevEWvRHOt->plYW!EGpT^2AP^brcQR8w9 zOi%?c*OxS2u5xO;b~_;a9ZmkOXDW&Sum>B5uI75GZlc|s70;4G!NZkX7tgq?c+Nc( zJX|Ao@dOl}>(K;{zWf`GukeE+srkVbTg?w-YX1r%qkJpJWwD<|VX(^QSKx9mjneB< zaG6-6w4GujC)oS+w4#ibnj$NEL=^ zMI^Oc@Yk(pUF#vO;AW-_JHxE2B~ImmXLR9&nS_>nOZ#>g+*=F{OPsvBiG{3C2HO-mQbv( zHh)u!)Epar2&QdzxvGhF-Q_uJI!D)}Ejz2>Wtym!aBMKtY>G#%1xaqtg5lO3PD3U3qQbBD$>{@ z#*?em<9dL@pv_Zn3x%N%0#`P1S}EyS#ECmtwK%~-D_j!8u_q~9 zbS|APS4uiO4VUX)p6kKox|d;vCBr1~ei#`$v`Ip1DLdSjtH%!4iaUNLWtG;STgqJP zAEJ$}DxY*Ir>$eb5Y>oaY7FqikTOaavUFK_g_NEU5IgAjR>}kLRfmvMVB+{u4zQND zGtm@)(arVg#t}%Dj`cdam-sqX+-JKJw}52pwXKq#rPnU@a2gGk`QSy71|6V-;HB-S)(zf9wavJhXGG~ zM5*y`EpkASPV35d8La-c?8!wh_$Z+mr#Ll07%tr9zz$ z7yINMkoE2X*+7j<4|X1yC;QL{-5;ROaK&P^63QO4WPFoj-8QcU1TkT?gEBg-+)0 zZB77ZNhydPq}#_(;rh0UG4$vd#YJpqoWyqUH^ko)!}7O4{uat#1v7xZrxwZIfo&Dz zr7BN&pshmeB_oSNEc{srPw*;1ir-<-;Bf(`vanfkEvvs4)wfk#@1UdjDtlDHIT?U% zAi5g_9sYtw`~{6Sm{UO`eiz!j9|ri@11{f;crH_s1ROo+6Z(e-TeKqCTXF9S@MIX4 zHAv4eEIc%$M-2PNs-%ws9p_obyo1rfLpm-U;}o_bDCD+>gZ~gsN1BfC43JMp-~^DJ zHt&Z)g9z>-!u{w>%}x+FVt6Qlyi(5W-zz*m<6y*p-ZLKG;)kOO{WO(OK0SZMq|m-v zA%=v81y` zWZ$VuW>|*kSsXC+mKd3fCU+(Jd>^D@!pcRtCD_A;5o;5J#*NbU#E}9c^Oig1(y*&>rn9Y z_u|=$n^e#mA5BL5J*FOvo@2duR%ONW(?h{?j2F)h3QvZZOqBF2Vsf;nwCm}eqOfG> zP2V&uZd8>=^t7-!nk|#ZK&f`()M}#rGOk(4g zC*D^hU8IqxAGAMSL_CgK!CoLZ;hW#W6(l98@RW=m6+@Yb$ZcCisrog>{sI@Jpw@AC z_tpA7(xp~!wDm+!t=>qL^=0Cc6puK9s%V-0pu(QflPe`XOHVSY;^_lLHuxibpxPwLbDs)8uPk*RcsF0l(M;VOsGvC&DM*2A8y^IQ9VzC~{b8CvmX~Sael- z9UG7?EaLGP-7&pAEE1otVI+eM1szlRcT5@DF}>7oROm9~vR=|tJQ2Bc#)f=NHt29? zA@I-O{$E;733?k*d#5@~FF;SgK1J1&HYkOWdZ^xNFMnsKIz(8dD%7#=U18087n%8yHxAJQ^ylk#lb@6TF1U>-T<;!SAq62l7q@&1!ooq}33B&|NkKdl#baK#rB=F_nqa-L$STpiw|G(#&)t!(T#m14M&y)n%9&JBc*Hhf5p5tpQ*?E zYcJv3St^gGZSeMv%G;(MOYj{`B)*D6+IVbIiR+${#Je7o$8#$2ljj8F5%u;H^_cy* zfbfhrivLh0{{2g-=x-`7sor>W8X$Qy<*`*I-tmT%`<^N{Up=O)$9VM^t{&&AN0E9I zs7J1PJgpvk70$2J!&Zs^QE&I(Ce^M`ZxQvFtsaxrW1MciJao(?_ z(cgPo9#5*o`_#iykEay}XQ{^)5uP=FP>-k8<6-saRv`5X*+UL8mDi{qx2ne?^|(Pj zc%B*jyjs1LsmGP-5mZ=qtGAu%@uqt8J0Rt9)Z^k>c7VudY!^f^kSq@+%fm+EXAtIw z;kXy#r}&X94Yt41niEKt;rY&nX{i0xWEuY8_1mH3EA8XL$t}e#?U#j_5Vood z65AqICR>u7$yYkwdw1u9i|2K;^FJhfJD405!gEW<-}`)24MOy6i~4x2frUar^FfARAoSniaL@H8Y?FurK8=xR32{X zX)1MqO8vlr<=3A9`(Hf79zwsX%uP7)WvmVi&sCieJtfxJw97d@2Q>f?t!6U}7*xb0C* z!6q5B{K5KCE6>cq4q|guFgZHZ{t6|C0tE@$f(?A;s4(}UkHY#~`{jjb_GN|4EX>~C z-cEa2pG#*~4|JaIZ{O2hhc|owf!@jHo6-dZR%syy67RlT|7(HoHGjj-TA7J-5-M$ezjYb zI7tv3F)A1-j_s|C436!+B63D-?*#TwYcft#!Hk94@u#4@FJ$OAzKsj=^|D~`Hqjz`5ZeXvQ3%YtjO753#C}&w?SO%u z7h><5xzP>~uDmd|G&spfT!-aM6aoZGOk_*?o4O%y(r|lzL@+yt^zY(E>O)d|;Z9{>LM(%7d65qz(rsxh# zPJ)ce2VyO7Y~V>-)rI2mo8`OA@*Q+{Iw!>T291?}1R9}*>wVuu1!?xhh#%JjeJ~3! zyZ3`c2z*d*h&0&WLFY8H`@j?MO&HP^psgm)FLnAFteeX2Y`@g$1Sa4o62c-49IvM0 zClU%Ip+LH6YJuGc6;RHv30al>t)<}hQPy`u!;du*A3z)_>J>pF!M%$RU08wJj&T)z zLNKw#92<%ZEQVQQZ4j;Y@NHIw5D~r&bq;8ZZO9ohAz1%T@izNGB19#S#7jeF<=xie zkQrTNEecu7S3%>Yq9`j0tL?v5`Q7HnofX(%XI&ReY>$jC-fmUj-4yJQ&e)X08d37H zu(>gBN;qdj-q`Th3F(OIg7xcxz$zOQdpS3@bH75bchfn638$b z8}Sz$Q-YEB9^SCepi#~$x|#@Kg;E6|(#KJ7p_t42)0?0YT33WHmf4T66;jJY+@1<7 zj+{9AuT*F_y<;tq$@@?-99vIskYOf3# zzpvi5I$Ud3Z-xHO-@1L;YsvZBCRx*7o2Wqw++-{ITGK5j<>-KlRr$PGexH?t-RA0e zX!(7fO7o`Ohgu`Z@|=#fD(`C@Gwc8^$?9)ihXdoj@oD*en1hV42RPHoW48pMT7mdUh*xuK5L9;dOeqlc3%u_1rCW0yXy0AVc zX)V9s>a7zop!~sF{$k>Q5f5@_G3549*;w!L(gF?W46`jo1`GfOfq>cSh(_da6#;VA zfgtU%O*!ob)wds1i^jSA3NZi^=rCc=X!L$sj}&dgroFf%0TDk9&4Nf$&2J5v%U>4e zJT7c`%G1E=$IbGVRChaUX)zN2gsfPVFQ-VgqAiI%Mtl&Yws?;WtF8`tJE&fJvNJga=OnKZl6x>#$DXLOQtR@E>2xi>7@vg9^2Y&;1=tI#$XqpWEI zpl=i^;PD{g{v-(di3EqR12&3DaNh7-sEU#JE}9YB5X7#GrqMzBT>xR=Z7wXq2q@YE z_ibDV*u<1#cva}zL+1GdS%n=T8QWkJ|CNa!d$L*^*>FyaM{ zr59+8Ei^|J+AFZ1Fjb!qch@65Wtgdq9_X@XaagaEc8n6|ARG1e#ejk58DT|v>(JUCe0ROHHKRuQ^pFTrWyq?cxZ*78>hy&H!{b#m8etA z57gfJf5vuER&iV?gh(5T7Fy*zHeO(r^ALF$F#0lTH-XeX)+U9h(5&rU&$+)2+Y%LEZ4n#^DMlOh4 zzK#K&;_Y3B10MKW!?FG2BBw#=N_^P=(G|_$O%F`GPlyqGeW95VP9Xy{ENg zbHv>nyYznQ)kk&x2=rUkyWx~bNNB|9Q1r#FhgH0$cw6k|V8B3uJ5@ree`33C5a$~s zj`qJV4~`fYj2wlan)mP!{b{%ci9L~<;FW;FcVqjijn&5(t9vh=F0zNFEq+D#Ca+KA zVjioiQ}bHB!|Z&$I1V`1<8s+cp$6i2H$4jVZx-iYMW>`5xrW2aAJN-LOrTmRpGBfs z_DCjNXd<9C(pBc@=W4m(@ zv$MaAe1SF+aZy8EE~lH-zN5tMOhOYq~;M&m~Og(?nv*H|eB9bl8K%J*HqahPqj$~#kh zJ7#!+k+>bDx_;#}=2pCv^f7*L9;#&>y8WtO9;6KXY~we!k_D3iYE=YBj14Nuu*;F) zpc#sv-s1L)WD;8a8e6?J)#|PORtHdyt$q%Uees^=t^ulEqw(JynkW?_f5ytY0HEaJ zHMe~nY9SX}b^DTe$$-;)k(caW0s|>{krcF~C}{ChK*yF86bl8K?-_D=q+5SWdi^iz z`pvgHzXh)nW~t4=V;2Ft*=_FjYPj8xt|utlLCSWfDBJ0$?0w<_W%t5xf;Y4aT?Kx9 zS^Pc4lO5?a?R07KIFhh&t@a(PJl{IjnMbb21TV1-`-hS2HGG)JDfPY{8BQlx;b%#% z5q|@XQgldU9P()oN7m4-PLXr)lFU!`)|!+!o;Vr{nd}iU`##|D!F}9KxLx?`g?rFQ zB$34S8;yUF%uo_jEv@n|GV^%}cNmS&N`5$5fq12367Kir-zoV8$%+Cu{}yll0?98- zRvf|>QgA}$I{!~4L8-WUL;#p zJM2!R&@Q?5=`AFrF=aDLHLjBkA47i4!VVn|Nw$w4w=-Mw>sHD4@nfDhpXY~?V--If ze)2{{xBN)S@1Lyb4}P5vr5Ap6D-iB=ktu^6q5cmPS(ln^EG zGq|5wCGZ_&IQ6L^=v5@J@b}V;4!U3!vW!NaA4-n(@#J14asGOzWcm1U3zFRSERg&Z zKkR+z$Y!SjlaR><^kM_93yzqM0Kp|lOK5v-#3gpHIE28!ln}Z+S4&yrF@TF4ZX0-z zj^218LNM%A$G-iRG7-EZ8EkY)M7G=ifP3lmqhjDTB*azx=lg)ixI;F)h*WC|To-H} z!OyHb{3&4^if`xdW6bJRmND!Vv+{W(u?#5~uj1=rX{-rhYf3nolOjEF4YG~KYWz(i zuv_MgLT%+w0X%@9(Fo*3#@grOq5G-)sbp|NGPqGUKXI(!I0Any!QWW$*aAL!p&70)6&l!hqqGtBjT9%ne#2f{l?~!hd_I z!kf~!IY=l$-0fM|eRlbgDAF{guxV@|?T|f~s_y8gkr)o(H03-4Nk-#0B*Q0&{gA}| zmzoEh)CjErjDAn~VlC+s5y{t*X)V=&=4NKQ{&ZcW?a#@`BWtwO zKu38aqN{HQFhO-ldltoowCc@hvUrh-(w9N06C6n9n;TPu{KIw&ibL=dYw+YabR%#W ztH%b1R|I9eNIZm$G*fUpl8nZcl9B2F5VnX&9J@J3vXvdMCjhI;Ncr-WO0lB*N6^wpIhVd4Jx!LrZT|ixf44_F`1>*b-W~lbmc$>%Pw#|I)1;aY zZ=(Qx5;n&V3~}On9F`e%WXo7RC1>~)sLBNxHI3C*zD69UQv)T3VgA8qII=uBI@p1T09)~M*6c_ef+Hn4kz48J z{GO0`%09<8@+F7}CZD~GcwgFud?S7epS_JZCh&ohkP$zR?|q^dLRmnE2ys&|zqT!~ za8@g}LU)}g_}X%3L?a8@%7W+A*DP);3)R#ws%b4_yJSM%tW~WR0r=AbU7dhr3)^zp zTnC8q-C7nzB5~LrzpT zc5?v)k+&d_;wo{j8t^8LfwR9|D=k>i`XQw{C7N3|*wA zwW4ppe$mNCc?<^2S0-C960DSwAfB8bfA^)OU~6*zN-H5hTFgyzTMBSIto`r^J{dE2 zdtk#K*_zOeEhUqRw>hg5@7Pjwp;NSpKag9c)-G<`Qu2;H=}PtDfck0yz5*-3LgY#X z`6XT9u#C%UO<3jc?&K94j#}AoAXUO^Mx5Vd7`D|JXX7jIrfo0#=DP$;g-y2*(r|Cr#nJ&VQQ8U5h8Ec1jZM(j}~h ztEUH*;DJLtalx*9?l!4yUa^@qb7ujfxzg?+OxYX9l)%ry7+3_y=L6OoeG{Z%tgEkC zgvFbh`o%S^xTvVBg-``23sm$utFoXiXHjIq!q!p2K-Z%U-LrB1#;Nq3@~~f8e&jfE zW5lZlG9y>NC+fi#K`^ssF$RE9!Fd7uI;63NXH^YGqLM%)WY&y@5fBosuL;;g9jFQo zbq1lT3)*rQ*3@Gt2`;FgAFz*fpu&WrS2sZj$kFn84&n?T)TQS=SO`I~VCKBJK=R!v zs`?WWMehZ}*i%sC1K8|uflmSp((72^?AZbP=YSO!^aU7OaUHqYog?Lqc%{_mX+P^@ z(-wUcL{%>2fvFYnvOo;o8ADuV4aS{z9z8vh+1xIk>f%IcmgWw2catEm#_`-{IU?=1rvk0Cp=2iw6t+4nKaP6x`+WF+zWe-gbFU(KlAwy9mQ(X~6<`u15y!N&t)gke=A_4n5DPE*E|# z?<>l|To0GVHy@WrmJST>$`eE$n*3tIX%s%fT&L4&Z?30nD@viPoXFC8^m4N9}P)SKH z`qzk02U9?QQ$?`zz<*tM`yXfwSd{#*cu%sW6(BhMaL*eE4 zM0mFx=iiOk4E*KbYE^`ruH7BNbhN2(cdRuReqvEmq7xFF%){^gh@6OD%nX^W#_25R zeJYg&P4^I1e0#lnsG^{uWJoVyOy(Jho77mCe1KO7B_FsAf8Em61@NPCmj#ju$xJX4 zVcfAO(l9cx=26rX!BreV`afu;E@%G-a9EBct8T#kX`GK#L$VnsV~EmP5=^M|3M0M| z?}!Qgjzo5y08v4(M;7!PVuvAyy7B=QLPS4!pKhc~$(_k6Hb5cb;qvxMX8w*&T9h}EU^=oBT1 zM%)tAj(vMPt=`RP@;S#}Pke$HN7uf^8y#b><@fLM?v9J`4@I6+_WxsfckOe0x!Bjk zv>eAvQrJ)5rzzx7kht)!qm zA3(~#8VS{0i{);tKTu1kiWOlkL{E7%#U6$-Sl!f6y)_W$n66+K0*FHO83=~1!aiLj zqep5SE%5hq;yuI(mAovR#~~9eUm#8F;I#_M zW_IYKM~aI<~0hI;_>RqwbySy^?r+$3GDPW)rUjRN*1Ogk9?{=`c-hlXfekQ%$` z7}3~xF66l+PwUUqdMmQY@OKSoAA`^yZ}RcbKwbMGjq3$dJ;EsS2{{&f*u ztBEPtJ-R7kdD!FFv=ITD^Bb(3Ix!V2u0-((8-%9umz=;+i;lM+T;}RwybN-a+|q@0 zCNK;8|H#CGWUn1{BLeNW3U_`+t`!b!KYZ$f5fXD!I&>ze#40Djh390p!21*;4^UKy zFQH>Hc-;vV_Q+r2J=`3G5u)h<8h9%1kituxV4Jh=9hRF549-Hm^{b*2 zDWvG->CAMU$} zYZIF7*ZGbXb4}LY;unzPw)h*4z0S`6JBZ{SLBV$Gz*BWW=Ri~f`d>yl-7TQTaff~j z7mC*OQJAcBk8K1|s_cI;J2)^k4zo-E!iIdUrHVg9qKw5CxbFuZp%MQCKj;v8%eRTQ zO4gf+t!Ovo*Sd#4%)~Aj1?+xIY%>#|;wSd`pgg==WNKcRiAV9)b*9i`HSqS@%d`k1#+9hTn|1CiGu5Dmiuk@Xo;fsC#vD3Pl&sz1Y9 z{mF{XtoGn5)MOj>j#0sd zXa@oXSl12M4nyf95Mzjg=2(#DB>5EnRuZEzR^}nwqGKT5Oin>vF^m1S(O+hDI-? zGDEl9G0LR^0R;>MT(z6t*pR01?qr@SiPu3Y5>S+6B%nWb;^0w`%)wuA+kWVAj=|{c zVS!tQcLje`WuumtEs{gUD8QX_h%6nWl;r?(VekqQsrI`a@ z_Y8a-O?^wEls|pn0oFrNeuQs5G!0wklIWi?;c)t+aG>TZIi?0M-&n5LN*b_K$`MdY z^$&rhnN>MlmKl{OQ>n9RSjtsH2DxilpUh9xy5URzB6F~GnBWht9wy#r%G3P&?n~|R zn^{&uejn;GA{Py_Ao(4UIE#sY_AMr2cni~Ja?vnLL8%==<7kW9C)uRgUV)j3$WyHv zSe7Ar$^}Phx6wEUzdMqO>zd^^QIs`531Bo1CK#e{Uf~z9k9x&kK6y?XK7YoXI*c)M zYi|nJyx)kX$3ZClfnYMa0F#DSk*TI-=rSr4n@xwAwCFChe@Q6Bz1-PeVg+mu$F;^= z@Pkugo~?(~VlwSlV?BNe!3cBk2t0O5Gn|n{o@t2cFZ3^dedb*{yxhvnDi_#uK z4m9syBR|Ev)2+9}@k=w_UB}_z|Iw*)zkMA!W}vjZ02de-iG{d%NQHZbs94V+HH|G& z0RzMhq@A9)LB9Z&H1+(m7{%e~qFdM{dVN+CWgm%br`Z(+&0T#v-bRap{EN#DcH*)F z=ZJseDp(n#aT2HN&XhG-I8YfWQEPOnimJY%2auIVvyXc1#?;*1F=5=>!syEL7}Q)T z;4X@rB_a}R{|Ie+=i}t7YWCiK0q6C}S5?o)Prw)}^kFZwLnF35yTa7?yhz3xzhv|i zIf~!M9(xUP@tQ)7ejq>Y=l%r*3#20S-5|6WQ5pO%@iq3Qw9c-R^+s7A$EFl46bzHV zi|aqHN0R0_hxG3wZ~|-W7m$-o`q(i{K0&Ebot904=nuQF@&X|Ser%N=XYn}#cFmDyd zYA`Ha%_2{0IG%u@uiniU1wzFEWvgL4R>oEIJRg{wiDI zT}(`8)$(jOZ^#B&rE%8Q*T^#1GOX632S#WNOK!l@dugyLGNT@S7O8>!xCR2I_y%yi}JVsqjs)iW>XL%I(EF+Wa7X<7&Rj@6$cE-F#T);ygUyU?uyHNvP=WFdkZfXLhM=AR{4)f&i z%xEMc>&`_eDdxWy1BC5YXw&G#v0PK&DE>zsLZ&C+CBC0FuiKbS{5Q;~YC(_A7~#us85kkJd@ zA{p$O`kGoU=hw`FAfBXXYYRl`p@JN~!#YJeiz(eCD7{brsi#g8C)2 z0rj)509AGK;Iw>8qh3%~#ho!T>e+sksLi!_GD|DxQcu2(huDBq5ONbL>#$9R>OMoM z`+M7+%8IdH!+t}(>8{e4W-Cmy1yeg>Sb}N(T&`5Z&IIiHS&ogHUo#u4DA;BZuy50t zr&f*+*vt4vE-l7VKMKjZdd=5XrwE_R>O|ld%)=r(y7F9&xE@;>D5A3i_6bb$#J@lb zMhw|O7WVJU`si(kR3Stb_$Oi_J7aEL1cZlcX19()pT9~d);e!)9U93_5H)yCmsV^< zL+6Qo`k97zgS=)65hUwBmcbQ_~K%K}{aiRqI z+=mcmI=Stb%Lxl2qd3Gx<}OB$g<)?#fXR{`bIn;hQ`ls&@ny=!Z_;31!~YBu(=FXk zG^A=Bu9*qgiEMxiT|jKvU;{zTwHnaX{>yYq{ep<>lj2y0mYv6RQaQJdi&145_Khe|KSut8X6&~m^fe) zIFLTgvP_>ZMiRS}6mj<`oY-uHxQH~ZUZi8WPFF@1RMbg&jm9&xrdEPq&StPm4L=hy z@4<6{PFIqTT|5E%8#-+P)^5Sg`E!?H%nDr@#eSGk;kgkQjj!Hv$W7_qSnidfH}oF! zggu2{EOLn9@+yLJsDoVc@RU z5Q}EX7MGS5!xdEJx)WEEi>qO~1jGnWLhXM~beVnDTda!xQQhk$C1-5M_ zgo16mF<^iErqedKJ!n*L-rR)&yF({N>Su6s$)b5P(0v#P0`^9oB`qpbEh-C*ubG40 zg5jBSMF8L;mGFfLxf%+@oxN<4vg?N?hLGjogmGp6wz6sS`>6-EW8V*RL! z)lstM&0R$MevY!SA?$1%$}I2BS|i>XJfv8NJz9;kZ8<5MhxzZ{=r`cTHC`IC_yn6b zC()1SD&Su=Z_^V?@2n&QI3v-Q!Ly9{D$bUIq~t4@m%QSem%ObU0M{8wn~m($t9jXb?K(!QO;)Oi6l6oF0>Me2MEUuG6JrS9-Kn@4z1rc*zE9f`g60zCz3&*pL*BDOo(GP0YyOW2>#q@@59hSPGRU+QYk ziE!YBC(t@79I&VA{0rEM%hX%;E^yjCK|B5zu|$8CAXyjktuNm+1tj1cxbkJ88MEo= zh0mEo<5N};T_}3nvCSzen_*yQ&Z%DjGqVI>uv!bE3$g!=AjBsl6y1==k%A7*mv}1s z6Cs9I?0oPDsUaus;iSK2PXR=)Fi6_ylc$IG3qid}P|C1r$IaPI@63Umi3TdnjEvj8fyhq^nlwt9B%<}@R$aT7 zAuCrpU0|QU@)RAn|2Y#Blxl7 zX`$Hu>cuBW6o#>!`=H##EfQBePs!J)%7y#13cE5eDJHX!$TCM*bk-MD95^`1*#qd zI1gY2*CEZGgBS1%aM%yxha2yKbDH4Lz^d$1i9@YB01x(|C_M7n=OcKRo>Ufd z?$XOhSQEen9Cj`3H68=i$9 zxSEL>(DT&geop;`xU&faOxE}a9)NF4XJ(!KO_rb_z^ox|sS2usD3iHseKLb?SHBjT%{r5a_@SRyKN(RigP|H^P z5u`{-oOm(fSL2O}=B&`C+ToA`nx}ftx)itAGf+h6lJh}J)qOqAWtqH@CwlA}^f52X zOkI^J@VL`QuFNsZACK(7ft;$;`9R5E?Cc+NsKepv*RhOL+YBud{&hX2o-ktqkHamR{#LC#-UdGB# zfL*5?ciR(sz_b3JZbu<9#KM(_) z#5Y#w0Ou%@>bW!3njGBlUM>lr_BgJzl=c1KK(1^Fc_{vjw>YjudxfVIN+YT^4M58&Xa{wscVmom7_gb zxcb@n%k3NL0QPZHD}d^~8;IP312#2;Nlg9`i>%=dm95Mn7m^TjU$X+i@Nk z`vR)DyW}6K0%WWUg3{$r8SyiL5}R6-9c0fCm3#Xil#T>B_d=n_hVMt{dIPi&AJ8K z&)RZQEyFDU_-y2DNAa#+;htvQu;r_kJPWd0=_Ei2Mx#%U65+k=82dNkc|4B$$&^s$ zK-=Y#v%b2xxzU_VUHkzd^Pw7rI>%8B-tqXj5@6j~6rm}EcQhTZ<5WfHE=Na|E+FTd z%mIc=tP^lqWY;%koTc4lKb0t56FaKj%}q-Cv{82;aOu%2R{5ivHVVVTMtlHp7w^G7 z6x;%d+nTul!O>m_!ayQa*sP=Q$%3jNKUq)}!Y2!?sxUthRaIb4M0%k)vCyjOZ%*uQ zRShsF4zQ|<%!x&^ROHk?Ec)=0pP?-?yHkxOdopbatt4!oEDXu#-ZjstPhw|q(=0B} z1P#}O8b)BII+ZwCMz#;g{TaFp`dK#^mH%^}GvL4-K=U}-3#&Z7DQMQW0j3Q-kE5`2 zd%3aFLRsEeZu1N9nW>L^Q~8xnfqfdOJd}BSNuY^$E~b5r4UBb0c-+c}dj-Q5nus9< zXPr5|kg!~`6s8s~illPPFU(}W<^4_5l5$MO2JNM=p15NM_S)PUYr%6T4K{#bzT3)ooXsNTE%MN&-4RA0o(;qzak!jP z`4hN>6|EKRRYK`jhKe7B2nx9P2KMPFjp0mRcYhta9aq>_%fn4QQl<9sr}E?QfE7s* ze}?xp#C8qD%t3bDM2$6&%>%K`19{T|{CMpzMgEPMBv=Kr)ES+cg-sUhXvC?9%6YT45p2S0=b=O#Xp}p+%8h#_E%BbzFRVKyGaF zV0D(;8K(iq(_SyA!TFQNa10fq(y;$joczEKa{B_{v8s3I)^RV@zn!epfE|@KP1~*8 z#sY(wDg~U&d%z%B&8uE=NuX(I>PqD5oxI!;N~<{(Lbx;-w{k?FX0w0IkKP?;}p=nTbn z8WVwCZJJ8_ptG_pcy{giv2%A4RFBm*9vyXy+Xj@D<6Few-0sjRw8MAaG-~v zsc@5m9lWIo{m7rZr0892w8bs-JJEWi;w`p0_|8Y@wdB=ddk|?U??e|AG~t4JsI8|% z`u_==`BSt*;6#S7DP$KU$tv&Ul(sBv{{wE|knLSZD*K6c;2vEg{wKPe&Rx10jd+{X z@lq#Xye-%MIbdb}I1Ww_Zk^r4yKLXWEHZkWSV75P+28wq|&Nkw2fn(psf7nNz9n;#$eHwi|m4>$^UobhxpY{-n6-9YlcEgCG$X?ZF-cm;VF_eH*x>?TX zL2c$I!Cd~mulPqcia?KKxXSVQVtaFqJBGlt&8^CO(Y1pl-r#GWkvPXOI1@b7 zPz>J(9O2J{$EK-d`p=y7MLs-{IZfqkpEPWWA60xRC`y*U-*K#6Lb3!9f<&N18wz&L#l>zfTr^ALB5p5BJ_Cqxy)s=aM_5G+I{KgDfLQ5~LSJTQ;W1#m*RLfDipLWYMs zDx*PNFU$9prc5s01D|KS34g8n4YLwg=5h!=*}elPtm^ir?_peq;9q-QPR`yqE?eA5 zG+!C(HbJt2aL2Ae|A?Oh<^D@?OT+%Nu@aJl`+HF+JOs`k>uuNvvycyr4f`e-@xM`H zM{VW(y_c$5k{{-L%((Bm4VY`iI)}6$J_aH*(O7*MKG>E6SS6$-ecsuy_-*s^_?GBw zt8zzTOC&dmLAX6s^3T+kLfM0v>PZeyl12+(zl^|aHLm5 z_lRgeWA(%wOom}sa1r-EVw=aCd&RrJ_m{e!VYfBx`zDTxf_{`YKhN3C=tMO}qui33 zNT{S7*DpiYkOw5j>H$O9_V{!(u6R$wel++ZwsSNrOi7<5XIL;R+j91aTr~ynGS?gVLXN2hI++e}}@jt>A!t6n-G5cn=va_u4moFAv!N0|e&h__32e zrtQS9ku-$LQS|EHAdYU1{?U0fD|ef3Di5-Hm$?bfX8+be-?a!nQnS3D7sB^|cCDWY zc^8!hpwSvQY%R@6*WZ-ih5R|pr{9YFzO8{UPvQo;eun{@mYyzW%6vqsXo2*!9JdAR zYN`qrZ|R)PaXY#@v8SnUs1aX`cJR!F4&g2C=Y;RB3EEdPPkmKv@hS4PFdIa&rk8KT z$miHEhF@Cqa=Y$!CrXPqV#WJKhp1D3E8dEu#gR~JUY=bG#15tiEpQ4GvV(R7vsIHW zz7Karx#KZQ_fp?5QgodD6J+~J=i7Z!rK@t%>+WrHbam=ZJ1Pm}A^TNktGbtvG+*6) z?5B_olU$7WyZt17d+l%W7T%!6&y>L0GPDC5X}*mpEU$1D-s6hF&VS+s78O8%Fn3ME z$03y%Rjcy-AwKwE0W7$+JWOf&7@Hwi5yNEkp1G+h*t_%RcvUu;S6dC}FPHjnGTSLq z!03!uSZPpSEEtbX#Qv3*4<+nTd_a~~5T-zsw3)8QS7_yBy zB}I{sO9rb8t((s8jlqOg3ricAgGJ8-nx@G)Ie*26>twuyQDE@(RrAfJOIh^4MEbE= z-C|X?n4eRM9{Ij3;E8AqYsa~A$S*RPwT!%XPIWNrUJ&MF#nZBGp_NyqthB6~FrYbE zKTON|1~kjb8c7GqQPaQE-uT5P{2GO8Tznq5YOT7L!~`)M%01KK+JEew#ktCrpm3* zTn3Poa{M2w!pRs6v)Vbk7l%oI6QD#b)SGPd&;0*~{^zjKH;bXPWOu7Rn$KJkEZGBbf-$j!!5q z&T3B>qSQ1dN6B9224pqe(mU7w07BVTPA@ZHuVjZ{jPU~ArvX<$i!t6oVaj*eH=z_X z&%TJmB&_l#QSGfz?Hd43^R~kk+R4OF{YLSY9DFqc&FCzbgq^8`^Ch7@m2j#gyq`)q zk_p%5<=B4!72f+PG50B?FQC_j9A^Szg(NQff=RAw^eH2Yb3`dG;78F%~Vz8KN#^R*@uW7@oHcH*Nt9hv@&G_c0>0WtD?=3waV@pcRq@|hVD~V zeOLM6kLdJ|CB10X0+rslY9Z;p_4^IoKVS76t}CJGTnug3)U4ZxU$K@6B(0(Qnl(Iz zYs4o4?A9d>-50O2)OZrV1S!zJJO3^CN31fPbRKS9)o9##5}pm+!&lvA#E-(yVr6f- z?rZ2id(BOP^9yv4aVLXG4c%w1TH=)d7gHZw@op$^73nim;)g4CsYyp+>HiIDz z-RG>iS>X9eOSe(W>|DvbWz8zd{1h6}(7k-sZ;ZH&pQwy`1{^_3&1dkvs};Mhg~|T{ z_XGj1DIpV}SIv7`@Mb2~5X~?c7RaJR*P8ATfP0uhH*N%K)6$QCMuKvS8_jp4|89+6z}mQ8 zG!XSTGYm7qO)%Ij(I(qqid#PUwe=E{xH^qXiTKOWLu0j&tE3&=KRa>__!pV1h*^Ix zT*em;17?K&6Nl3Q6+ErIgVsxI2){UR7@f}t_-0At$cUvm@Ua-`Qd}_-ALDn|$JRZh z0wGoP1D6fpHMVg;=Ra`u047mS;$|eIq}CF!W#}?85flWh-$|Zh1@HwU`4X)gEONnK z5-?{4ShEuxjIK`O61O99n~<{|i2)`bZ>)RR;Z|<#ilIjZaZL`|iK*F&&6EaldRgTo z;E-yEW+}sT{A`kHW7E{Wt+_dbyb4u$1fexD$c?Jfxsj;!fPqc_A9Y^?A7ydvosWe? zj6P9QjG9_(sbWPXN);q(Aa24{XiC$Dl%>xIl#ZO~#<{yQa22$gh6pU0?p{^rE>oLdQ_I2^2P(9ZoJNcf z>XWTRn3Xo~NJqO#q~@yj*JpT}QkN8xegVlk+J5%7)_ zQu4G_qz1*%>;kp!cZpjNNg2*)PnN|gr{KZvH z9ir0MX9*3v^d=OdSAEAuWo#;VFkvOuQg(w9G`a(#Kp7AsgzqOV=ljSqMA78M7%yi5 z5^d>!=g4B_I*G97qpv-3B6=Ttq8CtLxj9o%NfcujV{oDRgneUY@ky+Rr<7)7Gs!NN z#6OHhd*ouGQV))592R4p#p8fklnm;FH3BrIIVy%W$R_@QFit#G{eVjJ$TA$>*taW{ z1PsBJC7&bAb^BsB?SpE)AbKDGfi%S9-@j{)It|a1M-LeUoh>~;Ql(kJb1H;J;7!%^k0Q6=@eitD?8p~8`kOb5a;)QGzDRz zFW;lRi7GTRJV%f_*m9dmFsnOp))@Y zlj{Mu8Z5h>I6Bbahz64yJ67^ol+VME)p7_cRakOH;2Q#nUp~MC@_6kf1*O2u-MMih zhfqUc=9vG5LNoThbbzv@l}hP03_|RzFy*>F&fvre;WYb!Vp66ZQJ0A;l^!1YI! zQ}p!#1j+PsExe&nk@oU`6s>(9=Gf3%y*(=$$` zV3?kB>OUffIj0uw3rv2o#gp`YBJ6;`Bf^)&Rsh9D&`FLN7xU#b|d zIYrB!y5d^Mda|tGHR)(MCBE+hYA~8y3&KymUW9bYOQ`kj`|Y`SD7XYx@kn>Bz!+j* zDpeq>{gqOwh*iv1RVWK%)H1+YMEBpwS}sN{mAaOrSqrkb7AF8zXSqPKT;aUOSscjX z!ZJg$6gl0@0$5l}9xR0d%N26i!5(`Jxjo*dVY!{PU}Rv1v`E$@Sr014%7~CEti%;n z=sd9D!(>V4$Z>Xw;;h!v8%86wNp5xc89!H#b{=;c4$%rUb~;dHxx4?Aki@C5tS6(4Swd_ivTf8b^PNaiTq0;2(a(O+$++dB1bHY1ATT0 z^hH4n{4KB|SQ|E#(>9cgJ*=M%(Ljtl1L@U!a-TNy^C6K^H6=`b$69&>GJwBONH)dV zBl`LS48?H#@ls)b-@R}|QrH=N$}A|FUpU(-4*|lbNkkl5g8u?|F=stwn}R}T9kUEQ zKRVzNhD5YN*Fu+<>h#>DkP`(Jh0gWNf=jWS zj;=F!cD7S~K^Hx{2g4x}v4cPb#PtnUat*R!j~=y>KbNnfYZN_N$-5<7to=}fX&{X0 zZs_YK1W8|CCVd6D`0cRxA@R&*7SPwXkVW$jW+Wl51tBua7n!B8OqA>Z35!5_c4^;p zJFx+ST|;?czc_SS16M?t^u@5HaEf)MLooGGy3$@8)u8LDQm}1Y=qTv>D)jMACsT&x ziHSvEv;Z=8R>VsF1leLY7k0;^X_o2Ms~IwecE_ zkLfy#x7fH$<8btl`1t&wEbe^!14fNmiX;n;L(0LK+?AuQ)NybeLkPY=2!gBgz33dv zcIqq*%pwfmK#*7lwhm&CO$Jf?1leNWB~h%9ucB+%fBE$FA7Ow05oGJ$isV-PMO8J< zKjQ;)aXApY1+~w#lBcWMXTWSrSB`c*8?5&**4tEucRDeWblTnb?|;KczK`J?W(Hq| z=GfURvkcAN@IWB46gq2FEvQ^!^QFEyJNE4>)_%nP3*%-B(cPx2+KPn|o%BmJN9d}) zjVzEeeO zqOzaHr6;{|Wa>Ds1y8+p`dNx&XX*f<&^9ODLmJ%mERW$Df)-DaECtRFRTeV#v#QZ$ z=(0dnEaa{Rtnoky6UsWu`G%AjQkptnS9%V!fbGK=fLgYC7jEYZ8lp}LBLvxqE31N_d;a9&$5U@WE;wyM+5jj#5 zMatQw)}2pVx3^7t+Pb62xu2P^W`|38NnmDq->0&mwN@!wrUd~|it<7xdKQCr2!eIM z(32P*=@{(Vi+x6F&J5P!E+;sKF70~&?uVR-s>PvXR62kq9UmgiW2MA6@JTN`po1fp z>>Hr3>h0Oaj^E5gm$Hp*Sy*8;c4ZrPWE;D)jq9?FYqE`xWSdr5YbREwaI!eYO7v5M zC+G9Acj1!%6$E4N;vJ}N`51+D%}Q*>cVd&3xSQuV^-tAI7W^(46WcrU$r)%VQWo2L z&68L2s|eN%^-n>eS~GcJFAfY~F~9QDGDAFdF*>a!_XBl*rlMkuznanYrF~nr0}taF zNz8L{QMBoMrrVo|7h+0lYeJ`pIm4Q}b(AzsKjUwsUc>WiYz3(!X|2fNZaLZ&nJI$laR;0+(R&A zX`S8Jfg|G-tn^{M`4+7>!(F-WWno~)TD#j&f4Z@)`$`DHXT(_awa{OP0UdrNu1Aen|cP)3I!@y+D3qi8O&1$OiLf&;f;3VX0ciT`nI7TF7Uu6;1_HIN z)`$opu&-N*?~?D3`Zo&opMfOI9AuYCfqssYm^N=(A1%@1U*U>h%R&tvp7C1lAiRILRAWqu65+v4H ze2{aCPIQ%otoAV}S>#-)6W=DZM%^?Ek!*9iPP}%74%^A`v*}P6ksR$ab>eYMq)5s(|BS|I zbvs5U9_sJyfl{*2Db|Uu;4Y&|*4?y{*!UBjS^^vQ__5KV0q)d^fq}hG15A08B?AMy zK##z3o#?6)*z9)%;6mp+I?>(xG4VxR@&cXcDhil*CL#jraI+1p@?x-ClZ5BH%I`KL`Zm-uR zzoioc)9q2r0or)a)QNmC#?aWEZPx7@#&zM`28#Y8+Ty)M%Zi<`I%5F1YxVGz=)?e? zOQeZH=XIRRrp2bc^$(D#wlgSPQk2%GgrI}dM=#csh;Ilv>)aBTvcv-j#s}(L{SSgb zFu2!j@GI>95suwlG~1-#C}D5E^(}-!+GfA?RRl$jFGAe{S7AS8?YB3hsk4xX?UfHc zx&5Tgjxi48?@;!PmO6Prt#R4zli$*Y>;ow~3ubl!jah zxeyW}#2~y<(6kZqVR&6P1gNIXeY<`S>;$B&t%wm(v>R&|c6H3!fo-0XqE?`h4@^Q} zcda~~w{S3v{M{5pRK<`*b~yh9y@^BzD_J_=%k9V$WYP7p#iI)sSjjGs7e0%=VI_Y@ zN(-+~UtbKZdU-Jw?T4mAhgoZUbzsL7cI7kH^vuKu`t?l1lFEM50EMg#GJ%0Im= zne-qI0ncZobqL8Wg&l+#4N9=)Bc$d*qqXAiz#X{REpczfP1Is$a|WJurIjoLpqPr+ zTFD~$D!RhV!?)mrGIp~!4_`$XEXT~l=joynHUGB9<2=dHnrE!liI$(Cy@(SBUOf4s zPCSE&W?g(=5{sP0I`ImB;x`aUCVH7p477QQZgZMWJdLXxc3!gdHA`ZN^Ld?kD7iY~ zBrzt52RNlVaS{{3%q8)2l33*Apa5q-uVA%2a^^BKPbWUhM2d2~een+22`}iuRc-AE zzbE_S>#ykfD$d?Q&V9O?YF`_Pvr!F-$0lJQ;>ZAnIR@gp@>O(&$Z=NkTN3of;bMe= z3^NYrA=uN+2+_YdQxGP+Z~GcbZh_i@;=$2U7PcX`pb)0z$mm6dOgPsi$yEOiE zsIROO6^=aKN$3iXB$~|_oD8nWRqh))@j2h(ndpV=rnmkLI{iKpjge*dO5u?61)Uf` z$iIW@0xstuomlM0)?JcVsQm2%1IIEE+iB_KcDSr$$>+7}O6*D5e|DP4@Et5AA7K`C zVkG#`%aB6GbsQ3C&1Qo8 z;$#%Z1GFR+oF^3&J9W$hzqCmAGrQ#1H5q))OXme9m+>ejfb$=nu1?d(Q><~17Oli< zI61-zU!k)DA3TQy%xa(Ydql9&(WE^C)S1#~q4QtNt?n%$%lkg^O@5y>qT@ERD7b4` zg`xc$B)!=Awo0e$f;GA>)OYTB%-Tl8vemsrg`xObU1X9@e3G*{1pHpxb;dRF?5{|c* z0^DL82s^=*BIiN;()j2MId2jm_XL2n5);4*6rdvrXi`^qG_tu18U5{(6<$Jk0PJH- zG-KPK6VKL(NBbs7Vj&O)(!oh~e4yG&jzJLT922bMA;^t$4t$l!7nT^x<9net_sQEi z1lgc(KNLNtvv{PlRVUoSUaRTMgpl*NPMF06H6v8QDxI)`35uUGVT9A76MlIW60jzM zV56Vs$X=@xR(Wk$$*&-i0GzKApJJjWp9F73pto|Q^9OvZBb|2n;yrw*6y)1mPk)B6 zZ#{kQCGJ*EiJpg1$7$jO&3EwLDiUJfEt+8DqpcG5>e+y>uO9l_?<_8J9>i~a;8fgp zmpzYH-|Z}avsd3O687r5UMeu}@+p7&7>Bv+trBmdmvt78a?X`}Bb;gYjSo!J@J27E zV6n&t|7ThMBCoweCG53VB=xxR-P<^!;?+ zBUzd7&n4`&bGOuC-tTj41lbO+j=Ga)f#ezCT+2kixX|+iChT0s!s#vM`#w%3z2;zT zx)yV?K;|TQA*&5@DyVr9jgUHzLgDzpX;yMELDyqUx~IQ=|M2{2+QAr_N{;jt@+VHfthb`$cTeM;~wD zXoo&4-2NlnSzKb;e;z^2bdL-ymXYfeFT)W{x%0T@NSFFB@Lkm6(BFQ1V6v68S&yb5 ztgBY?Mnw4O=UWo?;Gn;KXtN9)=drvZhR+cWml&)>4I0N-93Z$jSwnI)AyG^^DtFOG zu>w%al}x}fE13@x4shPYNe&aPXM&RanJ~)f)(N*TL32JN9Oyiy6IKKh%AEUk!fGaH zYD9^HoU~5(Ww6A-PDCgCjtL%Amh)Aeu$2j#iK414rD)`~wtQLRa}Zo}rBWYcKI_S1NSygL zu7Ac7n{HM&Iw)zn;}S6zj#55)8g9frhf|$p6~*z68g! znPs_WL{5d>YNU-bFy9s&ZJP!u<^sI;mHI^ay3X1D`-2x%@4ImJZ};I}e0Lf2>#$i~ zfEThOUlJSWinHKoBmz^vXn(5vovzf=h3`gQg{^tIsx)17G#qL|^RTS(ZLF98l5&M< z82x&C88jOeXQkdl>0ib>%2e-^BEo0i{S?~<2w0g5;=3_271r9W6i&8qA_VJV+&RY~ z*G7N^yrgfEM~bCk5iy9zsT@o-uA`Oc9*;%0*}Y&ycd zk;ynr!(`*3M*5sHAW`zD8CTuK(VxkR3+?V;GABh_d$q3P9#!Dnz z*FHMFds3=tz*^f>k&3<#d|GSU(Y8Sg0og@&E@YkV;HKrk#g9H-sILz#JDN_rqwk9g zhgSRp{Q~MGd&fh}jGVD#?;Q*ch z@#-hi*AdzH4%BynuJ2r3-!xx+r>XiPC#mWp$EI(2>pk+Y!Uaby**l5NA6AXFPFIZ@ z{}8$zKfPTDV}2N_lm_knv<_9MnG}z!rFs5Nbq*Z2Ka+y1t&VcsdQlU{_t%hGUlt-Mc{G zGx38i-~npDE@dV+^)Gxr)eJQFAV&WHuks%cJ*tpjDc<4!0yL_S4&14kf}XBv0R2^z zrMkQ3SfCxJ9fsT#R!#qB&?u_OeXSLH44jn1)kAK2v57<(+ z304Jt*`{9XEG9?07yi&V$!JAE#JR&7?Y3IJ3lhog)O;R?zDVzGW4ovb{ph|Dz`_wx zFU<;2XP@*+VCf|+IF$x0y#S(|C&sWL7#cFbVYM8Dww&+akG~z$2u@8+Bip=2(BX6g ze4i8n3bIhMeH#jbN(DiMf&lOkH-Lxc4FIwWKQ6}-c$)tKcwWXI=`RqIhw2aA@`va< z?*cnF;E&8R;5Waq{f(>hITi%{b6oP^>=z7Wn|L%msM2&pQ9M)pKfqnT!rkscxSRUl z=+C|QlgD4+eJAZLbDOjy9B(~CI#{$_WIa|e@5E7|dGUdh7JkNhj88=9}3(Jj^0Y`!>q@OOalunUUU!9$*Y>js=aZin)b|Cm|tX; zy2TX$`JyHa^J^a_$@aPB$xYG!MCCV@72sNQ?rvSb$!C6@#bm@7KV465t?H)HNAhUq?~+8Ph;6HWO9bF>-ca;p z_!s%NJ<^_4iKY&*&n<=HwNYjfut(zl@i8GQaU4|zI#a!UK?r%zMyBfRGDfnDoM`%w znI?YP?b=E>wZ=UJE#OUl*)G84QS#D-FWDol$IA6$eT`mRuhffclU`gE+>tNo^|fBF zuV;Dd>#2HuJwdImk&trpKUjaNGY1fX=i}e*k zhTBb0_<1g_=@)1!*ZpL1*Ex!EjpbkO1O5V+G?!9zu@d(JK?qQOfiD9Upb%pvQYt`6 zW?pOLW@MruqwyZO7GcUWCVVN_^N9x|f|AJjNEA_IIzA|gM9#)X6+W!Qt*91)Fh#EF zJ!U|8`5h6EH#+eO6+iHJ41aR^eHE0bL{R6CR1Wg)ZRnw$hV=pbx}(!gFIsrHLcP7B z@P~TGdiAC@co*gQqQ>*^MEt1Wd&u>CT5L*DicP_8RD5K6wS#;rV0>IMqD| zt44(qwVX>B$NrZv+nEeWJx(1z!Cy{S;oRrdFCda}kp7X-hZRbd|2*+iO?bKf=|NTLi>dE_2yaT)Q^KLt_fGNaoT}pKKgL!#wAM0@ zAj0_+QU!iVFX6Kh{s1CrZ0d59=Dw1%~BtHipKN1b}gXt$i zU>lhvJFsYCO+jZeg|CuK@(%pmA`y4ttFSZqL&iT^`SydEB#WewmPwZ4tKd;|OyJ2R zD-gb0QY!J)wxhCOUM5+E&q8D#i{GC~;y8Sb*;$FWiTHY0;wIs1)^;gSgU=!)o`c_Y zk~ke-kGzC-q{nFmL2?m58oGae45X!VspR4hm0RJ8uP>;fBWevB^w(+zYQOnq@b#e2 zEwdLgpeGmk^6n3_2A(Si^<;mg3`Ezm6dl&+vEN@AGlmO4LK!oLv5!!O3T=*i z%SR|f?KsQa@e#_3z=>XeV`w`0Ep1qXm_y}ci$z96)A+L=6 z1o@WBuN9|`JTt{`YQ4Y+zs{npX4HdM8pVrl<%*GBA?wwgv6c3xC=H;06y^ClM*qTZ z0X8HXW%&^G9G_eZxV*d} ziCkWE;!1oL6+Bv#N#2LAcO`kXm;4YuS#}M6OHO0O>%7GEI0Qc%z!?beBZ!|zl{9Pkp~*NGtrix)~_DZX^cGJJ9otHAFyl33{_ zR^d~YMEtf$B441;CCBT;iTM4gBu?@YYjol{`2DRUPWKXL=)^hr-6n~1y~Im&;uZLP zQxdQ860gQ5p^e~ouOu$=5*OpM7>Nn|jyPRL)Jt5BPnNs`zlTZUU0&i!op>L9KP!o= zy~Kxf;u`#(EQ#y9#PvF{1HUzrxY0}8tP{84ccvtE>%>fQ7rq)LuFsA88@~Qk;s)Hf z5H~Pt=FTJ~K*)_p;0N*~g};B5cnW_-oyp@>JO#iTB%T6bac6R}il^*%tHe|G3w0*{ zMa9p-&pi@97hfYflV9OaM)u1;m-wp?F|srHO%)%(&pL@;gs+m$B$eqUnQ-FRCE%gq zWu=|r6oPkbVxI6_2XuyiI06?jFWt%1)uR-9?F>JFJZoN%JnIhZ3_p%w$7>SYSk@Wd zgy6Ql66`*xGn_5?aO}4#y&?o?z+;DJ#KL*`I+$X_A~k*h1D2C+&49o5D-H!^`VmG( zC+q#TMBhdJr4|fekUV#x#FOV@gdV`p2qSSP5J0TSb7eeO5eNk7zTk$45}_d8{g09`%)(R;(4W>N?Cop6QuI^^`9y*!)q!e^m`vNvtB5r_5lp%slq5{94L6%3WGBTrkvxD|@ z=Wd>YjGWf`3t6Y zGomw@<&POGnZdY}sJEH>nIbZkN1Ox8QVg4!$orid9InU5V6f<(Rqea$1U($C-ros& z`~&qRNvuTT{O2XH3ZGn@$$c-CL=IEibCNh-Cr-rgm69mq^{gb;=tT12t0j@+)wWp@ zIbI<>UN=Z0$E)@kNxTG~BawIoes7Y*tMD~p6G$U5f@}o+Q5W#XT>n?Ylo-DRnYI4m z<0AKcH77m{a*bkU*gf`-044^i^mc#+-5aIdLFyZ+L=05+vswS4uIO%5^f9Yw(N+BP z<5zL7uHwOuU&XI=6~7w33L*@-h&VZn7~Ef<=1SJFLAoim1(O2SpMwTTQt++-506=V0Mvx@fkX9>Fw%-SBCcI`0h-TE-rUcU?z47Mq!stu( z%nJLEJsS!mT}$?&qF7|(mc3KTZ`gnnvsg{}$c2yNp^I`HEKE8BV+&1U5pk5e7Y{dP z3W)LCUG~h%Od-cFmzE5qhTJWZffVLYKv9}a*Zu?NqwgqtD{huCb!9 zExxfZRg{BYebHyb3xIN_;qP9g3`+J*4hIPJZqny8?YV=DDqMc^^}iT#cdRLX3?6F@ z`@v8o%ZO8#3_pn)ZYKyg4zm6T&Hk1FoW?~?z;ktx(V&(N(m~;t0d(PUbAF^_rj_RI zm-84C4&{E3H=Y4~^*l8E~9N$3P+sZRvZ(zQk zci#EWo=+g%od6WT{m};V7e}wYTatLhxh~WhDjylgYi+;Q=v#jr=7;#}Ol6ddf1IH8 z+Y@j?IG#_sZxVZ>Sk0&r3qOTvI11Bn4yK_VADp@1`G(1FUXOPBaYOOx-eTe54eqgG zs)5IGJX^R7c4YDPqTI8fyLfwXu9E}mohQb3&;2Cu0S+@V+6`ktyBr+GO56zQ)m&x+ z>1}FgHDVVdmfnbCk%uL+l#&1DMuNW}XIU^ZE|KMoyv5{%UkpqvNvL4L5-;I=&bV+t zwirBWbgjfd9{TY@Jm2R(!9gX;moqLD1rCg*1WggCKOa=0OA??s@*M_AiH)j6g+Jjp zRE?&(`^2B+?9!fae|mahwrT_XGWF1|Y6GA9j<*%{z_6+68Hw%AUh)iMdtgSSGj5cO z#lsU^5eUvX9~;_MJeu5F!sjWI(-3rSVjRi9#EwS2LZcM1LVa{S|>C2GbwknjS=dC2pjT{=CTe zCreGgfe207cm?L0GT!}WygkAw6v9yC0>S{f?1u_Mqyj!^hH>@i;5Uenm;C~CKsAfd zfws@_=-^hQV7znq35+)f6!BD>pnh5ZCVfKVS>zwj+kvIQ<9P>S^>}`iQTh!=oH)N` z@6b5k4|WTQ-7~>s)Oou*&%S^t=j$e3q0EvEr{MQea;5+8@pb0A9~oZ-|5SXHDjRNB zM&kZcxV-P+Xh?b3mrmIacL;VEndy09+x^0}i*Wjc4`s@rC8rS!AEm7z7Gv=3?4=dC zpUQ73$2Io@`7Y1hCcmNFQu!@&Zo+u;^JsDR?UzR=Kh2jJLmN1syeFmwgJgS8-kbj+ zN#cP(W@>_~b@;33l?#{)IjE%-wdlf6KeEnxc_b3;7W)gB0x> zyJ97>!`?afA`EwPTk!U$uOryx#WxnEiky>>KmKm9)$)1yD72RHQNMKPzwx)AxUMw* zZc$_mY@~BfORjxb9#R{(^x@%3h^kC~r7#Nn?c7h}?~YjTTC1}Y8RG92S}iZ&!>a~n zI={&lIHWXWv|1ih*;*GIn?C;^sV;wouNFqXhpb;hR$^kGa}>T%(*Sw|8C z+1m14FEA-|nR_u?TLwDLJqx32@|#ZG5l^1??Z;?==ozkc?J_bAw@=jB)TOWVz%cdDP- zJ{i3fJ2UJ;n`o&fRDpO0VYOFV|}3lXyQAYcDreVl7& z07|ILZSl(o@!h`l<`blMtT!dmXX3qFR%C%QodO!&eqqIMaSc8Px6l2=GDt$NbCG3C z5738meLla%DDhEazHTfX!ceux|1=Q!nq6cNk?NGi655bS{+S~DN!w&_L#@qy$vq88 zHddyJ)ItlJZtu-{#qZIl5LLG(cXeA%d!lvqlg7RpI!+p>;Z{|0d(?t1MT=Wdr_5`W z^_e~OsW1)byoeAzMDwkT`sH2CCre-)`oetp=0`ar7W~;jf>NF7s*>nIxzAxb!MSk! zjlxK!^<*9W-{zO)ZleqVPy)*TRAUERV}bO`>{*vU zO5QhX?xuFtp9%$j)6n4ixDrO|AgHiSujjR5G6`kK+WVSbdqEG8?3U(oVo8G=g;_*z!3A#PNg==2|ngJ1G>JswgX!(LmI445CWL&VN_Q-XZ#!sZ)wV|^N zrCay?;~)Qcr|XyvOJ0rPU&MK5Lo8NM5FPpS>*evMiwd^Jv&F~1J1-Nm#^Bu@-M+no z;HJZCV5lIvv*vYZ$UR;podIB+z>Asq1#_2lu*cqvZPoS2`ij@p--n8xS4MfJQcjRP zNj-AHp7z4Xu}j_~awA7?$&pT@qmcpQAQ&K(>3v1siGkAp&-K?ItQ?x+kwWaF^Gce2 zirilkeT5_(1nb#Uc%5A^FTSX#AhLlwwRNd1uMA;-#uLH5N4r4I4-7s}!1_T>i~fSy zg6l?A#V!L7fQlnS%SYOrU2`jJyDBooGp^wXzO`LDN4^OAk&#$*@ly|TZI|@Tv;ny= zsZ^$hm{PERilXr99jQrzw=m~wc8r+m0_ zkZ`pRa)q>EQLFcTAp&`6#eQcT&Ek~6;>q(%cCQ9D{3s^N%;zFN-4yc8(=^{aDb>wW z#t~NHP4Lmy1*gRaMuLB;bD;RZ0h-@g39e!DT7^^d5}qfp$$k&>7?;g)hNKnOq38>^ z^|>Yf>Hzqjp}b6_&12tIqLw*m~magU*aN;fV~y@|o?Xegx1woFZQ?d zo&C3y^|eD|{l3%PcFq{w&fS4_D*Ww~=yuo_-=>mude36;{%lhIHZG^fN_pZoy7WZRW76T(#289E*24=d%uTvaIYb*P!)d@+Jo9MtTqL~$_-!><@E*^R4) zu#s$BnQX&#{1xp)tl8UX+KzWD)<@V1E4)f1j%dvE$MV9S=I0Zz>{-}dK4PCc7rO29 z(&0xiY4A?NO7{9lb_$)-0^=48&+&Hj5y+{ZWwIZwK(F3rCbwJ3{{UfCZ}*xTa=pg_ zsU@xE_rbwnSK?!AdOg8Hg8tg;Xb42=w`1e^rTee$?`H6}EkyMOJQ4YQHC$yJ4ZK~e zUE|md%Fu*Wc}2Zj3k@RMGFKj6#RCEgW#md9>MT%~C6ag-@IM(UQcdH)_-srJ7uzFv zqk{h&n%Z$6tosq0=z|_Ghx@I>2xP%?)fVOt>=kek)LQx$=Re%~V8gEZA1H?r3E`f$ z2kzu>X|w|aBGgJE^rht^(5;WrT6CW3^n3kUg{1F65kg zL@-mY2BqGmeNyGBh=u17;5xlv3ams%vy|9s;aQ{n>}+frn&R8zp8^bcXaEc#@gCve z72+{CQAkiN0p|^7da-WaT2=;?zIdo8;5A2eXaML`F5q!6w+o{yVhJM22gHwYt9hW3$HxOA{b>Os0EBOv5Hqm7zcjHr?IN}+}l{BIuqpep&?%{-k z_*Xz~=qu5SfEf*}Dv+2t^Yow^46_t%747gURc-#TsdWOyaL+;1HsRHmfJcBbX2CDa zeJC`%)&NMsQdXz zH!9K5>aYy{6%I{qWq)y^h~edqCcF{=7r+AxuEf8B!Nf}Wl5+z}s{S;WCn-loj)t>G zkiMT_QknQ)2Atm^E7pmd%bnk{IS4UxU4l%*T>y4ZAn&1=V~AtrBS7?}pH&PuAC##3 zHnIR9Z~qeCJspcN^&fItgpCa8%FGGO?@rNx6h#gjyqi~gUNPPXMSFn`^gatU`3tFx zY`4%s;9ea$VYV2Zf!jf3|GA$@B7CdPFX?+#7<^sP@ z=+i2tA>j|~op$>6O`;^mM2eaA14xPf3U3U>2WqXvb0FyWz*N0oi~dOZZ8!Crev|gd zR9uyg5l1lrh#1fN_lBXBN7)hmmrW_i)|FQ#KDrXxVGJUT%6ed(Bov zJ5g^K}}1%lI>m!(o=o+>=9&$3Kl9f){3m z&quZf=8tB2X6`6oC*Xb$v2);*(mC+ncJRY+B^Mk0-iWLL6I_ZH+^8$&6uE+o zN%TZk^2>~#*;~D}v#_vpY6vgbUQoSt*309^#yd(Ci`nrmo;dsphA8BvbibMX3Y^Q7 zUXa>5E7h-Z??haA-vyXb&R+b{l@41WMn11XzD=87VOd`xD|`Td6vXa%z$!>mvH z;qMixj9RfW7^QYO*zF1q5}2Ew2T)gZxkQI?y2Ebl;>H)`X@;uPO3;W+d1F2f{Zv%SVH-ovOu9Gb%{QY2)4JT-n1i7I!>$Nb=N}z=Tsee70`_Gc+#Hdc~ zpR`roX1{(_lea4=<#Q*z#Uz~GC%Hk}lL9HhdHVHB;sa;kIeVUo#0P3L8;+F42hM_c zY9%j2$L!{9X5E~qxPsx|w(HBw#9$-n#u?$&i$S{`7&}U0dcLaq^4`krEP%~wUv@4< z>yTHP9qI489LBtkC{F!$;#e$q98c|)ScXv32y`vj64Fr@rZ>s%_nfD+H;>zZq@m$l!M>PIxA*ov{EksSQ-Yy^|pYgQfSMgqcAlZ3>5Qx=4&>F!|;D9Q?^UKbOu7-i!=)z8&CC z+kN1=vn-95hUbW4f>-aTtjJeT_%?6RyTD&K+gdT((EkO;#s|*DZxs03)l)E}>8gxp z<1W59(l@FGmaDuWl${o0=G>M+^3sys(;-s1`dsNbe1~%a1xP&E1vVZTgUep(RE4Cv zHA_ssClhF1Z#PtMAqsDUKiKd(YG{CRBj1D{iX5EE z$ZJKskZy+`!mCg)jiEKnb`DK*g?+eOW#h?=K4?ljjc;vGvqk#5gX3}ZugM- z(2npUJr`HmuwBvmVQL?uRk@R(XLzWmwyI}Zl|JZNcoa3}I~Q-bJ^4$VjRAv=che)va=LLnR%4=Po5SNqneUa{ z<>4rY(-C#!EijTlj#8-7lTivzhE453`$bb8#Xm-Q+B47M)d(nR11l{qvzCY{LgbKm z$1F_*W*-#pWotNNm|kjsWiD0TXIyJ1dmk)O}4yc5Z3+H5;>Yd2$o5 z6GhW7dZ|_u$S?0)-O7R0* zUZsxrTn~UK;F@d}s86)!;;m#X&kx{9x-=~bENEz-QwU&s7I%RYb6+3SXd|_$8x^U; z*rU?nR#pa7dfE(Sy0^t{ltt=Z;FsDJEJJ9?@Ms*x+=>J?{-@lT?x_~WxQc+403fD4 zdwIaZ^|PtH5N{vt#ZsjC?jZOw;a2GlPWW4^H}NzTW_6s)eHT9fktp1XCN=~GZ0Ify z3K%?5H-9RiCC`>&uRZt(f}?l^b~dQSkPH}q9R$a#fo`*=s`c|?HT}_)-!4fc%*c_| zZT1Svnn45o9M)S?iAqQ9)5@&G!LVa8$GVYk$dry36sEdWrquUI)qSIWj{ZsgZfCl7 z!&MFm-zhie7V)~$LVF|*+gqK=0_PZ>MhKta5b0$ml@T!!kS_=IyCZflPmCkh`#}Ni(L-?-cro1KDc)0C3h2zYh`~BuED7{?MO)<&CQs$% zyDH7M9B=77V^EEW=X!6x$N9c%`E3hiSQ#@jd?3v@7?VI(HOmLm9AELdzVAyWyzGK; zxi9_--}hC%@2h>^^S$rbGJfNqfoe(S4um|wVhqw%qJk}U7lIymv6Tq&pH5vR0XKLb zf~|1bt5a78Qy&TjDVOq}&b&s2OmJN=*rkIW*mPUr1DnBz;Q3A0MjG^iO}5H^I+a^G zUywEiv5hX+lMw96xIsS6=*wIi44xAVPDilSD|@+4^}wcL%m+4utsdC(5o8e!XN2Eg za8WQwCkGP_F@ze6A=tXr1v?SUyet@89t^g!tOxdLo$7(T1~ERc8GOD1vG7O!QfR1@s**LA@&nqA^9>Yq{4-*6Jb zmVj=@U+D&WWM4&A{1%Nt{BJ3L7sDs#V?tOVVYZbHflY+WE7sVm%v58hCSTw`vL_Chvtbz~4z+9S_` zfPlpbkPPh`$71IK;gGusF(M>7X^d^m^lT(Sqr8r4WVycnnQU=T$D^*CI#G&I)KBo9 zIz6;y>q5B~w0?c){*l9fGX3L8U(K-n<9mxk_HRAa`I(`i#RFSF}& zuWw7|%7(-O&%{(d9IxkgKu#nYw&54luFLZ>bhbG6lnR3%@IKby>4UM_pzRF&_q3o2 z*i%q~7yfE_@dNj(ybX7j7p*vsdc#e*&Fsx`>-GK%eIZI|!Z58rNPzwP!~ ziC0)WuU*+?Yi14bq}|^mU!YyO$@#eL?t;#Jh<5)14qz~5+KuP8d;R~Q-F_<(XB&C_ z{pJwuPRVcg3;%<5`(TSZM7udmk^KI?jeG$-zsiEc($)UQcQ+`QZ3Oxoxh~M=r`5jq z!Tfgb{+R8;R{Li-Ugm6B$|~AZO}qIlO=F*ps}tdV-dJwjh0_6C)aThj$9TWpBoqW( za{#orgSC?1M1`4fFJt{hu)YkHKT>X{AAm?It2f*$_qWzMR5>d_b%4L@J3J@92$93& zrxxCypLYP_l#IGlaA-$|l~9GwlX;aX|*;94Psqh0Y;F<5+2eAW_f@10R8B^M(en}xpJN}u* zoxT=uUekr4l>Piz|pSD{(0j)wWK{p}=7&TL)n3B_^Oj1_4?q3IOi2NNe~k(mFniG}^wP z6b~Z-VM>BEqlPn$N{9aVWSrbPS2@J^;i0tFSFhoD7Ky{cLwSW_5T@U%Llf|S;NBkM|qMa+>Lyl7Cs+A_$S4049$$3 zgnN{QGzfuZ3=BeG83Th5SjONE0xV--5HhvGo>rNfTFEyvah_O=+|V^5H>~ZD8;Wb> zh87#SVLO7{btbnEvd3R=N{iWAlZhF{RVGHA6-a(xCf0^8=#-wy#5(Y+;?_$Xa2eaE zzj&y$=2!;UpC!8|LI|QYah00!>0~dFz$vI>Kz>v~8YO658Sa&C&4efd0!ICmkKkH(%wu+RYc=#(ci#6Y0 zVnm;j+=F#LG7+UFK(BFGCA1nBp&5iHQ5wKy4)=Z*-cK{HH7b4xr(HyH{=HNgS?ZfVEQpciFd2=#~ZxU#5B-7PyaHmLyp zzm3{m9&O!%-|W&h{x!EPtsk_}?s_RFj)$V%)Qf1!j`V3dlJEls(0M63jXbB8H@IgH zQRAzo0-@G&J)&c{9^o>`+>eFMq#o>U7oKHbR0<0X>`lNVTs99|GW8gIx_*XR)6zE7 zk4b#Ch)Sw`51z{}UEl zfOq3XIbu&6=e<^&#cmIcXrq7yI2`LuNrk8fwa8Y_pP#Lc11rbF*dx1Nfgu{G2Fw@Y zZdaAKy62N*s@2$!^Mx$Zi7pbzg&Q+h7fgUI;~?qGOPur#n|hID530 z9MFykJ!K(SvUOadL}#SiEj&X&YpXal-ngo9wh{|4nnR8-UfrhQS5H&7p%eh% z`A6msKn-^6ETO~lo^UtDyuuszqc}AcpX|xn;ccA6v9nzSCI13(B-^yk0B9|x6FVP- zz>B(KFeH2)C_%Uyw|StI6SO&Ft1wMqLa;6f9$oJuD==$300$AiEnAdq%NA$bBB7pc zPy{wW+q(a>^BMg2bhgr=L)YvZ&hr!^JpNO?i5z1Rh>j=7FzO@U$iis5`Tf3qm^t=R zMIMn8HM0o!%gt#CTEHy|vbZta)_q$yKJ82AZB z1U?CD*Uz6a4H7DyZeoGU!Y*@Gxw{mwK2x{Ui#ox5)v`d=?bhym4i(V&i_=*33HSUH z2O*S^C5_-Y{~+r9e8o!8wI!MWy~yf?-$APv>{)$_25m9XMKnI?Y+)s$jg>AsudseF z0&jg^vU?n=#C%F+D5pHe`9xiNZCP?p^gO$Ej5|8}km6ro1>c_qdrUXXAdT8308>am z-ZsWCIWxf)Lg@0{I``KjbR6j&s*mYp8HLc~`?TBRgeYOvY|CR;=`{0v$lJbf=5#`u zwJmw~FA!v{rSw#amdn=HtBczwAeNBKWjHkUJNS_<;fPs0Rj)0k*Eiamm|Hy^*e z0q@F5fwe)84oyrVm{Mx_+5wvLSc&-5@YAzdC;7nKQ2iXPEnWNcT7T_vR3iKkcN?4- zFgF;VbBDp_2ei`~=mix=98g0f<--sO<^3hQD>C&affE3hmS%osT38t}xl7rCUwBxE+&dJG&8+(5Xz4M) z^G~NGK9@J_yrHY0q5Ap(<9t_up1!Zg`FYI@ZXITv{q}j-PjdeozbP~|f~{W&dt;o_ z>Ww#eC$zm~P%eDHZ4)XN>MB+7Ab%G5e#vec(Ae{_xl$&>ci@W4IU_m{sT@O9UEhzS z>h0EAn8S9Y8aJlGtGN!qEEoQ>A#THec6b|Iwqe79bFnZqz-=gDt@Wwg;SZkF_PtfC z70!vPCFoq-W1AR*VCO5MuH5+KXI$#BannJ82Z{__smim zHYFe@D}i|HR`Qqh)PG>SfLmnOd3QP(K8GjO!e2cw5)KNe=I{Z1kk>7U72asQj?^JX zi|EA=0@;SC8EpIN!afh1gn6w1=zMhxlE7Dt&EB&JAW19PBtNrl-LJ|E0v7yLck`~0&s%c8lR~UK`M>;+^B0wKJB^k1Pj>k%0a{);YelqlUtR6HT zH**4LJ_-3p?A2!kIQJ-oGD+UOQ8W)#rhawER5FKraRPpl|OBgATqmA?l1NU{rQt%4+;)PlItpWLqZAtrDta1cn4h2Ibm5eBTA*Y{_2O zu-Jx1R5no~pks>u7%gOyJ2d!q!(#TAEHr&-;gov_h?ly!A~#>-6}N9xYV$>0t$fhI z<4w6eeLUSLQJ};H->HP|*~~43j{gvW;sPL^gDM+KV&8ZExVS)}t6ltny>KxUUY{}( z%dF=u-(wAT#_$)~@Jjo##gqX0h{!a1f!mLlVZOv=L<-flt;rIwZutfX!_;TBaD10^ zkTBFDsPx%tz-J<-y@G>^L8Ejl#bCjG8WNQHju!9|oBO`}2vKAIeEBfDV?`9J^ss zs$niq8Ayu_i|~U-=Ulv@jM7TTT>z3T*nsTT$qs4}_GPA2)NqCK3OCj*33ioR4%X{+ z%;Db7j74FA@H;DU1R}LQ{sfuwh4jhjA9=5cmH0F8Kz=Q8Dar4UtN>EkU$hWzk$V8d zK|6Ak6MmEGgbcnIN+w8E*%7_hPAQ;Zx~F3VCWN(iz*RL(Qz}9w{)oOAhjf@Lhj3z+ zO@5LBo0T{msL8krnLIyM*&nnalRXn!OEpS)ej4gpXHON;*Jcjs4cScO8`-A21gFr^WW#q^Ex$$MJfwi0QhOfc z{XDI`6r~t2oDJVcX%vHwQ@nuxF6-7U7*~ZBAi#C+)zb})R`SP)F|8@Mtrp6EUW2A3 zw66_vV`nSZrT#`!G6ZhZT*nm(tt53O@$ZfW8V_Jkr;ZUcjukYH6Euz&G)@pSP82jw zqD05@e@%~~ui6V(_XihraC{|8&%5j!xWmW}V{q~6IKP}DQ6qO$Av~m^kPNjpaGa#N z(>~alJxqGy5+w9=+ap~e;t{h%F-{8+ZXBv~zJL-kui$2!ZNti0K;X<%a(O*E4Ba0( z+-29J!=S$!BBH*Qh^Rk@h^U`VL_7-7NS%`j>$DPkPzmSN{`87NXpAfB{5uvWGo_ zJ2;zt1MC|gMoSs{V3wMPQUuV`r(SfS@T05kMP-T^kt@k=&2XeP?#&x`-g{Wy_WM6U zL7DJF9Ao7gHnWFeO;>D=I2+f$SnK{oC^F3oC^F3oC^F3oC^F3oC^GEm+-4T&94+U z`ZSAP1UqUgaf&pFgVS}wuh#4KZen}Q>yrDT6BT#7z_hkTS_5B0YwM-8HfgOxTH7eC zZMOfV28YDSD7jkWZeSSaM0l5QY+vqGPR`xxa0i!?$vt`QDMKa<;C$)nYGq$Xe{2-l5UCM(i%^hDwYRYLbK1S)g@6>qAah%?ImNPIf=PRK=l# zA&RZ!^GH_w?08ugz|VkY@H3zp{0wLYKLeUEy@6&-Z=e~|yU)2B1^xW&Ex-V%wJu{f z8LVP&&||DYD3lgfrTVWs0eQJ;9pyOM&M7FKCsxQ+fqp;%^aBc@A5Z}OfCA_T6hJ?q z*zC|hvygqb%Xu2#Qhi|l{}8cec0P5BQl^8|sDS|0f_O(fwZg)M&fyNIcuJ#G$}`UK zvz)VsY>zv4(;g%#x2bG+cTdx*;Tq`)ugc>ItI?M9#<`z0DxRMScLVeS=Q;8S_S=Td zziSa}B^H4h!5cHKIOpvz>7gL7zx)z%a(@Y3oLe4YD|rj*$KugRegge~V)U8tdbSIH zCv;oLa^&~m^cV_odJF~TFZew;eXVf%b4V!U_kGTFgjMpdk^Ji{zW^VUFcu z6ZZm+z)oz+{PD1Zys$RjQRU}@x+MoKp@~=H;oidBohooYZ36t;kM`UO)4%b`!U_7_ z@lqSaU>jy(vT?2D)PZ?tbH59_l{f*B7%v0XlyI-L^gw2mjp{5s9Bn0EKqspApeVW^ zwlnOBHyd;}bKl{(*TD&bdEEkrHv6$$vc+;~)5ow}(xM-aMPb?FA+#OdOWd%r`13Fj znWpeJg~)WoPv-@~`o}I>~9n*@4=Ll%B;lg_%tvmq}5hx z1gJ-Wjr|$)4Wz$t8O3hVUsK;M1Z5>cYHX^-T=N|gjpE;?=E)f=-iv6_(W^4alToI6 zk0COZUtM3%LrY{akTAKf6n;p<{Zt@w{9Hr@4aeq4qR+rAF2e)^;9$NFVPK|*$!iIO ze4N(-_~8=TF2fs7P6b6-%u_Q9yh6IbFtlgaFG|&q8=_JYhe4hph1@ODBHK}}D+8H2 z9gz_g9*urzIdD#Y26SffB3FJKYg`J!Vwrs*o*hqc{2+2HmqQL=z45kCe1L}>cnZNv zTm$wl_q43U&siF0)ooVt7x+}lg5_$b>+XGFstF{)#sC05j$BwEb^rq5^Sp2p6IUyz zBTBhiiKXV3reL(txGXiR+@6_8ZHRBEOiiz#UokA#*#8im%In{>n`yiWvk>mdD^nLu z$}~)ziFBT_V0RAJK^M)Ey)>>c?ULPjU#j5}3MdVigJ`hFHfjw|gRgYG7`T0zmNqs< zd(f5+{Hi!v5)i_cAMnWWA2ZprDc&-X1p>f^O&ab%%#5Y} z{XR*ZI7Di5EOqBxYB-i^rI>2BuEJj!ZJz`(Mhl|j`m9Yu3iUl2%pcztP%re6 zJOt_hZTDLivJwY!_`=IMd@q*Bz$`-WrW$G@U ziu6=n4RH=j#F;x%=fQZaH#Hmg)OMxna30o|0{aBc>)`pNKQ((%s;Gdp7GKRuw`Ec9cZRjOe^JU+#|D(fYOKaTrIz9{;Qdqco@-2j%r@c5tspM6$q~E zF~@+vIQ&Li!mz{-m4}kt_(04-~3>$by9WmDqq>$|Ehb0hEa~4QI0&Jbi-! ztl{#oDAUy#Dw`{@QzyOZ`$(oWYiT9w)AD$r9ZuE{XlG2Io#(LNwWeWyKSv=0fC)16 zZ)gEN498`s9|x9j)Qf41t;aGMCEjopmqdci{0bt75V-A`9YE9(TaS4r)!54AXMxKd zlkGQ-Wha3gg=jORIb1{)Ds1xt!IaUjaHrf=j0y<3F+@jSz62!K*}L zuUaK=Kv3j-2N!8DuRB{rvE(#R=BXQl{wCf4w6aFgl&G_y5OV+XILbj2W&1G-{5Khq z7&HoE3OgQDO36|kiV=;RPquOdM8{zumjoJP>-M>PXZwKIdr1K??B4!g8MxiTxS|Nnyrz-%ZNoxe? zK;20ml47q%AI*HHNk`onrx%+?J?nJ4R$>VVWGMdgO+`3{&v70|Q7iz!nIU`NKVbIm zoWi3+b3Ps9kjT3c97}3(=pzyrr#KtW9KfeHas4YET;$Ini8L;ECGsPgySB7?JIC=L z1O(3pp2^+T(t&r7W9D+coq_#TbUe05^<$=lyRpyk)w7kk)ag+MpE%*l{RVP{h`xUa zz|g6RN1v8?91Cu5oVx)668!o*+^DGmr@{M#>Et$m?_Y|5gerr|6ds1bn<#%{mSQ`( zi@$X|jXlT9Q4T>XNnKECT9uuoF#@fm0@-fa%R?5c&J6R(irFL?@e2lk~=g3EeU4na6T(79t%S@XHfbcU({nVJdjuTq+-AepGVzE}J_c~>hZzW=g zH5>gE%&2JrS^%|cPHsjdGI7&?p-Tx8dqchLFJdMCifpb1U|y>XW?=JgB~~GetrP&g zPyh&h;i(vms7NA8j+h_f*5h}`YWgU5CcRDXhRE;j;!Yxn_u-0V`v&EKJ9F$}=l8(1 z*}o>~k~B4KqMf{2J|@}8%jKiiPF^J+HBKvjP5wZy5>1>A< z@d;%5*uYD9_6@ZQXW<^}eW*g68;JUp#$NVPvN&wjIMO@O6mWJMfF%qcXGeQPnaXKoX3t zk^Al22ot$KkK`3VPd+D*d;_;Lhzd+sb;tgK z+J36_@bzAOZ=)uAsniEy;NKV;TwgDur9Lgo0M-epPkG?=RVK28TNxkiQYbc_m96ym-GCE7RP^Q>6=$`Sr=h1AkDs#GqRPT1IjU~MYgp!H zrR$F$`H>643d01*4i;+x5K4)J_B)6g0IDeqT(L$2CfpKUkG7L4IW4PyW32 zpb1LN8rQ`4q)}g!UEtmSWVokxl6vpK)tA1HXt?X?0cYV$kiFnVW6e-f^H@Q$AP zDmbq-o@=kB=h~MS%%n^}#|v68OLamHtSO4Z(W)*Wb^!~v=zO@*7XLqmG@LO7^agSA z%L~^)&f6g?f>&SeNYV`oL-#<3(Xdf(zUz_vQ4v?$Gt&J?zQR{smXsjpeeGX|Q9Hic{^;mt`4=%%%R7 zT1wHcc_^(5McS|tG!10xN(pT40bHkt1jd(|MW8q=6d7MF^P{?LN^?JGHr`RD^x?B{ zb06n%=l~5+{x5Ui17CGj{=bb244izfI&JE-naie;u|xv_z3dO03W^H26oiTv6&C8} z0wLJOy%)HCT+MHg*jLTUlFIsOU({)$6V@&$86wrDOv%Xham%Li#fc=p_xm~LeE!@G z6TjbHuiupWInVijp7WgNJm)#*Jf|`uk0oby`ewTTPe4=`icRCUegP}LR~NVEVG$c8 zzD(g_pUT|p20ih;Xu0==8!Er&vHF>P!Z2hu;uf5Nh<|JK74Qk}kL6{-KS#s-@Fmv< znX*dwEqYVe}Leo(YfAlsF9<<{q zajt^i74QEcp7rptLcO?it5V?z{WWkUF*Gj5SKq~jexSOS5!`D0DtR=%7xHN8Xyi^2 zW+=Y6;tIP;`HF6EY^0{BD;DXxW^`BO=&mbEyDAGYesFvC?j@h>e7fruT%&#AZfoT} zWVri_1u9@zdM@;W($v|D4Opa9(hmonPMCFg}7|>|9j}8EQns`B*W04q1rC z_olAO(!d?v8&2+;9MNZhZ}9vrk3`P%WnVt9)C- zYq{9Qp@%)994|4*wjmTWh=9i&aPXXfs%ib&5|&(2x00~x~$I92D- zR*%5IevCP|NtU@$&KVpvZLfWf>iW)Yx>nNZ5%g^yu{GMINsz8i_WCuY?rEyN&`KXw z-D@ScGps{lZ?yXqE2Al&JeO0&(hJ_@5aE zng*M#m0tzAnN(_JD!*zsi>ky6IalBYiMa}~&97!kR7qJ4qGKB_d%yH&AgHzL zHIC^EQ8nr3v+?>9E<9K7(?#j-vu;^U`jOF$kj~dx4bU0-y0vFJ#!)9M=%E{NLP}jU z?(B9iQ!O?=2A%ekKxOD8Z%8oG?A8{nmr&X}!*h-gNt;M+0TpotfE3 zy5KtnyFHazvynTo$w_jV4=`36pg))h*_sqvof7cP~HL8Lrg z^ILR}%GO+axbdsHz{OuSl^4-e3sHOs;b|n1p@uRb81{AFOik}JxM0?!yPR68wqlte z)RqYP$GYX?s#l;L62!?fRN~~0RadM~Rof8vean6#a~?z$Y1a}M5L9JOFF@1$R{ImS z-8I-WADB`HPOo*r>9yys!TO)#Jy#S~vK+%xYkJOr(^OC4(OP{AN7T*5T{Wgp<<3}= z+GfZ*`Yi7M01~6h)iv{?8c5ctpk0q9Ns&ZQ-Ix~dPutlI`BgS`@}pA81h-w;;$ zDR5Sov4~DxwJp{ye707T=3JjNFA0$*r2X?jo2Ou0<53P^(j&^xD59Lxx47hRRJmP9 z5_#WT>{4j!QqCqg#r~+=*PwQcOEx31;q8P}2P&)`x#a(ojYTdN_#&>x(8>iqI z6DE&DG3jg)aJZ9NiX!k>xRc^(F(^x&REapC(<~JS^qynI0gb4rGHama949`|a+Zk$ zxsDbGRH9?Vfw_7nd|8WgGs#&{-kQV zXf&5XCm3qQx&aAclA?(jVWyvzpT0EGb?vzJDMe6Tib^Llr7U_CEa*=uL}o06OK8b} z+#@}u7+ckf8KRV%!F~k7ItP4_T+QQ(RxbJ5P)7b5eIWzmn7_-_mqMMHN{HG6n6`mG_OS;ZKb_wEag)0w!x zI1nKv_6Q##Q;N%XVgQ3vs}cNb@PN$RNIm z(n&3PMNRu*m&@i6wDX|)SQNSo_nU~k?3O@oQePntQElPWuFh`2d25fs4YJbN72-G4 zYe~Ks#O@6k4MEPTcxmc&#IbJa#xEHpwgJXLsGp0tSTD>ia48X@p}u@4)}~NTwVQyrBkXhvy8SYge*s6OrjYIJ1a{78U8F9gdaiG;hcbBp6lc(WTk!& zzT(K+%Ex`s5h=rfm3rFO;#;!^%j52(ALYC z$E;$xs*LflyP{MD-)-H(dy?vYw~`v2Tx4}O&8nw6Qi2AVe#D5xB*Dd&cA=Mo+g7~`!MMsvOJsjdz!yJZj^%Pp0!%X1c8 zFQD4T%daKBBls(PtF!f`HzB=Xp>!8_v;-|!D{bPgm-R@BAFi0>d7sW-P6zn%rds@V z{*po10>$rP7Emc>7+6DDt7ibAXgN`5t)4*azR`Kt4CW@U33Xl@b=JvvySdbX5f^>J zCD}Yoh%ka_AAJ?*x^Ey0XBIRiR&pxhq&IOKXEB0|uqtj5D|WOyR;sucB`NR&pMb~> zTw35Do%yt_<>q7&LXMceTP_aL_aAT~LesZ%ZH(h<3VcMS7~%^E17M6oFzGNg+D>VWE)-6Nu3&oQVzH@15x=C<%QzX4QBpz7^$E)S-EgjYWje+1pt2gdPd5?72m*^EdoNNvHw?N zmKlb|>|H`9dd%L8@i%bHnm$TVsKF?6*0G-_OpjOz%GEwep2c}QI8T@FeCro#fXbT~ zmttD;R4}_QD&9T0fFl%>V#-F2{2Js&+;qX_I0O`qn8`^=cj%K5$>go{o@MrjD$&rRX)FSAJ`9p1p z&W1{vIA;Tq{{K)Gz#<*9o09Uk{~cX4=sJDC{4XrZE*rp(DDel`m0?f8j%`{;!OL`R zSODWzoHuKO0V(-;O1>M%Ftcu1hhI*Qm>^$w@8X>9@naeH=YgbDud|=HEEp+dHyR8b zmo}p6z-8pntTOivU!JgT`Aol`FV69OhljnOpTo4TL{n>ZBlEeo*!??>TtO-xnBRXg zjgn6wj|>6fp)MYMOFgYsUqhrI|G5V65z|G%MM3^krmFvw3qB0K_XhFdbA5LvWOaSj zR*1hJO;=0`w0g+hzmJ_S^T*Y|7r=hXv|%dLCF~IioxLwqoB5-53X1N%$QJ% z4uhHbTK<9wRlGTgP*n%;CQlQ>kVOcAhR9m|WjMOz8O5N;+jZACmIZxDiVm$Wu~v^q zY@saabqBpZc$bP|Rj=2)3i!;`bEOWYx7d86SI!Zbm^eR^HIBw_v2Qk^{^$x2%g_H2 zBzZh|idw4#VOyA~LoLr@ZD;43GE@Vx)|2xN&`lMh3#4>;kfN)j{6+VjAR4{8XV-er zdL4^;aU9HqQjr#K@LmoMNpN2|%^{<98q4=LH&v_qi6NB})GJ%;>-;;5I9=^6N)!F> z*;jn4B+>s*p}+VOiR=1!w8O}0zfycK(XZ&!9)){n>g-T%d(UmnjNNk!4zI1)lLOOZ z=DK1ta!AK_r{$I!E)=g0b|eVwS+5f$#D65(_~X)ED9u1UT2T8Uf=>Kg_q)J_s;|uI zAtd~7^>)rMsF64&8@&uB;s6%^X^$XgQpbQ`64kqNabQRI*1H(Kn8$8vRrTs=)`$)1 z!_<93UQfe8fIcgEDazq-(JA8 zJ4%X(!*{v9_a`T<0;w#N_qQ6o7U7){<^tV`l3)FYzdelvwpHt2IO_j?v#L{f+7GQvIE%zf<+McFRoJ{=^|d z>d^Vl-qBcYCAx3f-=$~|19Rup`}B28OHK*)vJO0m0PrRI*~Ec!Ti}yp zw2(K+;9}-FoMk7UYlkpS6->B<6U;%tg$P2~>#}(ndXJy*nse8C>%Hr!&n-H@`L0Nf>ECki~@r& z1(hHSFcN}Mp%C1l;DP6D<$aks1w6*}breczt{z`!@^T7jl~BVpj2qcmITjZ>;Z9eM zK}aV~NBOTIShsHmB>Gz%m2sg2p)v;g1a*MQTKy`$I=Sz$Ph8xE>3m(zPj$Yut@E0( zP9qRX$x&@0@Zs&ppb^V)8hL~s{`rul?IF0h>P()`YL!a0(5;_DRnwKVj$Dpo$O|Ze zf_L&cIMS7ioJMjZhQtsRr%SCQ_hG4&l@Pg3GL#K&BwJ#{`y?V%cy~+0BByb^4!KK0 zaI9{vge-R&c>srLzH5r53Ep(&45x9A4!OhR)+}l2oW{L643jaNV)F0-$yGXi`(Gf8!i$eS$r8jPUAf~BE!Xd4I?HR z;O#Wts{`jtAo9OP0+SNBK?mM0f%9>0O9IzO;Qc!At0wUC5=feH8XwSslOzz?j+H>p zdrl*NiFZCqEO;NzK-|!7q%M~svrNb|Nk)Qo8u#hIckmU0?t>#;X*-Q{Fd6LxNl3ed zEOaI>4fI@<)7Yvb4g(S;;?dx)=>(}6?bQL;{#02v`PLhnIFSgDWsC;t? zPEGINb4qI3@%Cj#Dt?M_y$$0$S&TI+A{hzI9ko^h{-k1jt(_#Zx8Lio2n93{Nohw}-4O~Hw$OH}*nRC^Ln#}xbp z1+)AH#=l?1Z+KSYuT6zFJe#ZH*Bdyh;NNN3!^b=zP`4E-rz?m~;G^N$26qbF3Lozv zk&c7A_dS3bo{hP@6`iRZgO1H{kAoUUr&HyeuKES>6ud*1`>bx)Tn#Uc0vRc@v-s^HHXxJ=Wx7&;L`-5**0P)8h>CSpQ{^$F7+>NAQHFfFkKc5wOs+U7Uq< zJ|)g5oezt%fX-itGoQ|T#2KM;oj7yoyhWS`!3W&s7Ihw6pc#b57-%{n zzMm+0P9?Lj4$85*8!$nt>(~+HIh5gq}6fSVFA^8bj#U1{zK1UIUd8 z`ksMG39T_u387^MDkdblR~c%At~FtWgr*xPN~pp>1%$>LD4)<728s~kPPw!%htNm^ z9mL%1@}(CE>nHTOfp|^ArLkoR;|&3Kr-67g!zDYHFrMjmA2txLb+{W0w1?354YZrk ztp@5KbhCkW5n5!R9fUZcND12s%`nhbLfod8ur@;D4Ae^KECW4GsMtVUw7H`Uw2@Gb zfgT|ACK#sVc|W1O2HHS~_QEBMyWZ|r1KmUDF$3L6=zasOCv>-g))HzqP&1*G2D+7y zZJ;%T>J5}6RA-0mBQ)DUV+mbq zpfQAE1{zK1GX^RnRBE77LMIrggiyYLiU}RSzKFE1h)}PA3JJYrpeUgo1}Y%5*+BV( zHX0~G=%)tCA++8=2Qde`w-~6O&~gJ&`gXr=AWGcsJOgnp=3Zf-ZbDTC+Dqs>1MMMH zW+1K=U9l%Yj>4smTVTR=5qb|B+|u?Pg!&A$ozN==+Dd4bf!YYQ8>p2~i-8^|^m7BX z5W3Sq8wq{eKo1aVFwp&kZZOaWLh}uDFQHimx`z;V_NCT$5<1^NTxGbU4YZcfsRn8$ z6gAMTgz^luhR{Cjut}atLa!RAfl!BrDwn&zGtQ;%X5+NoM~rikd%tlmbbn}^3*7G+ z=X}>O&UtQwan5$*##!fn)i`IkbB%MlJHt4qx)&K|t$TrXCaOqhV@yDm`*GupxhEOt zMAtITac;yo$GY!eFON;H9OJ%joTJ^p7-yN=VVtGz?~Jp=-E5r2?jy!o3WRKCt-y>56Z2fHdJ6dA(6=Lf4!1ExeGj|yp$Ij# zVNkRoUh*3CTaIU;N88Eye7?GEH)cq9zAwgA!qVkbkXcHTFm1FEE zSBD6QVQ7J%E5|^=<6Jog92}M#$r{EY4SU9<$)tzi?!pN8h&@Qyfysq27$iqL4jvP) za-2Pkc~y=>jO?&l9af9$0oh@Tbl4)5E?hQl;|B__jIeb4s^UXUD;m(WBB>56rJ|_~ z7iJf`To=1s6&uQH#(=zLu;82U3@Ww5rpuU-^7JidYB>TpZ4!eCh_|Qzvz* zlRCvFXV+=AuG8#6&@^9%%~$mep?;nYo7bLmbatK-b=br~+PPpr{T8(69F^UQ(F0mZs!Lqjp2IO5s%cDz#Z+ywI=dj$*#*RTWx-&bT|A&l#ZskWze-tIM?+cT znhLUx4wiMvfUHX->ypD}ogd0NUt;I$tP6Z<(H1RF3JpMG$2ie|h)9`*d$EaW9~VmE zh$l-Chg3@v1`(ZDgZ%6f5{piibtndTp^iakd(M#T!pR#46i!dcmJWrJSXRQy(g8Ru zWs=HLABVwlk|2*AP!K((AUgbn!8TOdnw)G!PNA@cI&7h8StzVZhgA(sCt5s>7cy@Z zBa4~}LtS2|up4YrW!V4}lnDyT4%3pUx<*qm^b>7SDB}i^M`(n&I=^S6$Ul^Clzrp) zKI|%b`>2qMC<|eie@VCXNGsHPbyvc){LCnK_p$rTZ>|1vH<~bar}^b>HNV`w=9jzK z{Bn1jU+#AE%iV8&xf{+ecgOjS=r4EA33E3c-<1tOq;@8KCka#gk^;4pbful_dF9Mg zpNerhggv9ZcyfSc73(ig77$*bzft`y(O;fSV0fMW&eq@g`a4g57wWIQC3t>_DHqFQ{Ky0VNJgz_yhTg_nKrkGhNHbo(a|i2!NZKRn+{POD zF-n{}ST8?Do^u;(=f{XScd&{qs8KRyeCIY+6_Jb|1>-wdXFpy8QaQJ=?tyryrE_@| zJkCgOdHeb1bjRr{S<$ro9wiM?Zs!WbioeXQAlbPI+JBnkG%yj~6_xWWw7&!yUwi84 zkADKi(;h#>Axc|OKt@d2VxJu1rkVj~Vg*ctl?RV`4M$Za0k3u+hZ|w(4oF`E>%+rt zQJjrJ8HJ%TKK4Fkm{UutsG(j_!yJxg6ecChDI~miUKtgz2}UJx`Wuxam+_=taEf$? zws(N`{(oGb|3x2oh@m+poRvo>VRQC_p=AL5K(s!UB*S$U41q=P8HIDBFx;i?#xI7L ztIkC!`ocx}f$zOD)oX!N!jCn*@i-4RU!pYH3Bsg~3ek_nDYbldAuOpK!UC=}ewws^ zW|}vi!9HEA?~RE!4qwMd3C($YUCti@jUYCRI7OeC>U?|VL|mZOJaVftKN;=0F~(UM1Wd!0Ft%Q6M{F~)%Q_l&CN z`ONY0$E{UK1kiRldpu;o>m_H}R@^k6kQ?8H1;3R{AY!8bR7=hQIkdhd^|p^?yvcYG z5O?fUY?`w|VN0Jkq)m)xofT~~oz8=}%Y7qXXm6tWas1nx zt0`iLwd!qb*$5;D0;N58CK8@P1<>xJCEy&IOHFGNB}Lcd;;uO`uePi3`UyGl;c%>p zV&<>r`&^QlGgB_%ZczZ+R zque)<3=u$R9-l)b3>b;${t>|g^hGd6@6j|~5KhBvVDMdn;v3$8fhppH&xYXmS}X!$ zD+lI)Ky(v`zdPO0&HMg|wo-EV;C*ng_Yai6pjqWlTGrVkcbz@opV8Te#;4-fb6`ia z0CQ(dO<%a-Bi!j^#hnU0T#$Ka!+Uz3VhMs9(DIgeJLN{&zES-Few64fO3&#BJ4(lS zqa97=>>(-Ab&>QKXHI__x7>$02qv#0M!*Vb%M&#=7j8oOxv|I%bv+4a2Uk0e6J!)y z%BMx_V|BSLNQu^t1u~tBqb zNfTh)6sApq3oV7<@OyQiQ&)u65=peUer)Xof==T$E-7Qd89FD z4^HNXiR{C8p+2Z@(5?IGH1t*oovHn_K2JHYX~izEv5>uPshsIIO{!#?k0KyDE(f32 z$HkgI;q@k1*94(}B6g?Iw5$S5q7#^*pNLPC946-R!I-eI!EDt$Y)n{Gvtx!j)kW!| z%oHUB_9faTD%OVKiX=`njg=Sd9#lu&vB075V_*m}pfkG-GvG=69|Ku<><3SqErF}Pxo4T; zFF1En45U29pG+mU!g88$R34)cZISkaRcbyDUoDQdtCtWMM-5KlMk4cOrv55t(NPDTkBrND{T3}uM(C8svRqoJ2D!j;j)ffJQA`^15hac+%F!~+Y@DEH$xGh76x5ElH6P=TY2+8t-P-@xCmGL6kXp_INk9I&*!Z8L{K3h2UTFoA zxz=FpwBLdEA$vnE4>m$xTF{q21a399@`yYKQ42FIE1=PljG>nsq!^N8)iWeW{ zU>e+pansQ~11B&NZ86SFs=uoDieW+t{44@{ej)y9zJdi*6w84^?x2Pvs-vFrjeu2| zp|EWb{fO{0G10nOrZPjLko5ZOiM)e^@yzk$NI36<=qS8c5(&>Orq!?{yW|;_K(23y zmDj_}kH95`j6^T04{VLt|5U_EUC9M&VgqLAL-9_hG=yKA}PMFXWjDF zo}(2149a^!VN8uCa33?qdVZ}LuBV@A>>Y>pLwJP{wS`7$R~)oQh@qz9h;6~NJj5zk z$=6aC-n0r#Qo&lo>Pw*3@pdP^$GKT{ZT|tfzzxiI?O%(8R~(7|Y>;FvaF=eUq5L_@K4_8B#b8jq_{IgP?dSQEE>&YcB^DP3@OR8HN7}LwZz@XsTJp zCh6QI@~B^mG`>ImmX$ns=xFvpptJHf}QR zXe1cO56R!j4TTpTOs|_r!fQ`A3CYre9oDE>cG=bYj-K!yYn@GU3!e|()K9{I6Z@w1lW0VbuTIrZ8i7Ih4b-q{ z9i?&H|NfJ<0hbZ$R4`zt9-)-W_huS!CozS#Cj>pGy(&Bo^7_0zXm~MQd{9h`_)rM$_}Tqj?w&%U_u%ORrao-3Ozx$lX~L2BxKd+ zkeP@bS!r=~UeR!Tr*Bi$=(L=5d^iM>*~54fiY`dAa>?pHksF?e^1O25k%r464Ne|x zB`z7(UNao#3daw(Qa7;^#a7`6(L#QWu+$*2`c^b5H*w*y>8o(V~392^G7r9JX-A>4jpU=WBeJ`Kz9?~LvwCX$IYL()3_?!s zZ_sf8Odb#3csLAfWG=?o?w}k^7?c_-EiE1QHX1lFKPm0}SIs)JbZOPhb;zKt`w2P` zmAC_~`=y#6*!c0+m&R9NcaF?7eLz>CNv`y|HzEb7jGkSVXV3Du@4N}Hv=>qdteZIKk^egJ|exw9#5~Kr!6cRGYw>w{G$d~?~3EqHwZA$ zlUm6WSQl=aTFIlNS_QC>0yC-AJg1ch?G12o9MzecWYaKao11w4kT6+!CEhN=)0Auu zI7DG77O34{kl7aY532D1)X*F&b(<7l0G{)h)FxoQ1?%3n(Rz3(>J>zZv8oO;YO-Ys zC~ti;8SSWw8EU8oNl6P9P=RUTq6EXp7cO{vtG*fS810D zRGgi^3SaE3u^mlwdd=oR^*-qh3}Zng8allVX2LPzOWN^`lrGwOqM~f-tD%VVaN+CW zkk%td@7XB4(ek48gH~)*Vah$NgBw@am{H?xPJat}0gGMPtO@RKBzp6m9J`TkT_9^)I4AT%U6U4cv{9@jH->mxRJNNSg%tDt=GHuG(6NuMDl!j{8+aK z839kuv6M1tTNIC+%1U8)B>tLnlNb>9aS;Egb0uFNgsPT2;F#vdHr7-G1?eYjvw0?| zP`{>4eAY>kOC^lasD|T=G8l@iBGMhOCH)X1Wm5e8IC5)GeFd&uXA|q0Ua^-Xges)p zR{3;z%MT_f3nY++rNP?+n<;?`a(tG*$SR;_);i4(I8mvRv;w4jr>a?9LDO9<0V}hY z(>vb!Mfzn`#gf5F3~cI%y{$lha(`BKX4Nh&mYY6_@ob;y?gCx~pnFZ`*r&vsAqoua z*oNtMK>h&|{s8$`{j2<7Cv^`dKls#~ zm0E*bbwees`w38i$xp5G&LUk%%0j>Al(LWflbR&*LuACaAcbyGDrVS~V^C*|oDp30 z3BZX8yJm@2k1Rxuq07_tDBth?NaiOcPc-&Ej+_s2euey{87Ud|Oi1lcoxD=KhK!!0 z6!U62)1%KF5wBKqA;YeWU>763PBd^81vJ`ja&p8I>$nOI^3myclG|{ckIfBgI5?dE znVa`nej%1hj^5>4GqULAJR;X{qgZ4Yt?sK#O>dZ6rBi^p034=Uc5ef+n52sPzR^ zr6!{vL(zyI^)4cCl8@0K1nc(!$WP&Li#h&-i2;HawwulY8by8rD3labdN?bh95P{* zC$JJ44r-<()tapiX_U+nfx)I|iG+7JvUPvR#T)1W0_J20w57Vzc)_C}H~=snz-87w zg>`pLH2o}z54&wC8oJ_`dsUW&G6E)Z*TzQ!9w0V6LZSSPA^;@ zJ08s+EWl4D@-jUbci zSmy3_ajm&g&X=0?X7NFAo2dxY=%Fk-DxG=sIC#kwF9_h6I7vdSTa@tLpoRC}YvElE zHO182wW2RwQzg!HO>Mf}qdd%Az>-rF^Kby-_W-A+%JVlAjs?bx>VVTytRT6r>_~sc zpXZHC3m=|&#svx8F#mj-UQf>~qIir$xGM^=+=mK-eJo5SR_m3D^+&OuexZ!Ob05`v zIZZx8EbQ0onV!#5{^h&0UOH#S+Yz#OqnbrFx{rml_FAjb$iWbm6M5SNqhlZX@NC}C zhdjOtbug5Lb7Iwf$b11hg%o#n{`mOb^qf9x^%4+)RNhDR7U>he&OCJpT?tPa1)fsJ zK^~;zv9^jTIr1=?=vGG_fDa_E!-}xa9f<-k4h26>Z7ELqffM$ors~MHx73G1M5{ukL?qzj^vOZ zD!NZ4S4#zC$(dGUM1GO0kb2~NT`Rq$U=^Nag;52D8682^o^-an&G&hoc+@Kz$D_Ul zlj-Q6rOqlP;Kgs2Iy$o6rtrC%)fiiPXeaAJ6--tYS%vR>UXJK;u_L&HpAsSQ{&%TI z3${LDt|O)I=JtB_`=O*;G(^U7OkoV_Zff%WNGpnh=svx(cvCX zq)305^*{j#<)Cx4s6lYr?z&TQa-0-Ih2IEHsqdc>SC(bO9etG)2-1KfNjc{oK^h(o zVVf>Gf;4;sk7?!}K^jY^x$y|n9HY~G=LphpzGvO;I)XGjP0KX@bp&ZXqSI_Sf;1=U zG=DgPG$-pcdyXIt#)7oxog+x|QJrRZ-3O=9({!4Xjv&qHI?b6T4RsMRd>042OH4FZYdu`C&5(#w_rldC2{vdy)a`yaS+|Y&?vTJ1xEemm658N;N&L3L#Y~W3JDeW2$D-fNMN`PGH__3%O z%0~Bp5s}(cC&D#6lPbk$p?H+RmD`@;F`=O-3ZKQ|KMtVwz(b+YP@y(H_aL;Xa%y{ODS%<^sc)*F zBtAcv4A;=3J(X7eYw>wZ{MW;k-=4Zd`QM9AyZCQ_YeakMXUcygKF^7N3tS`HQ;#bD zHhf+d|E+Kx)t=g>{CDBgEB+mD6||>1@c}~i;`5gHcf)mbd&LG9H375I^ttK{&0$<3U9>W52irvI`Jm)y*p z69!H02ok~W<^iMF8+co>x{DB5iCl`|wO;5kJPybz42`Q01*!@?loglzI{Y3S4Sgqk zr_UR}=T=CP1v&|s%0f7qpN+30flK|s;1qx;bgY= z;`_7&Ztw%|*MS@H-6Mf5a78CbZ6DWxZTS9=1a5^(vxe<(vdmrh=3K+pcfh4lvs(x5 z#WyN}-EirYy*h9oz8{moenwMe9@K$kfyNG1%BW{ILT0Le4mxT zrGDUY6iZE=!ZBN8U zb75Qj%isZSd#3Uqi%&xQ$H4_|J6`!$;qzVbuZ0WT_9Ep!1D_v?e;r)lv!7G`^YQtm z_%DD9O!g}bMicS*jrcEx3rzN#%0G!uyZEnx3rsex{MX|1g7~k83rzM7<$o_euZsT$ zxWHt8CjM21*+tVSayP7Yz-Nk~@&JP=VMh(d=!7u}ZxcPP@Fsl|D#6|KZsepmUL5i| zpVQXE-3;+UMCe0pGJ@skCxrB9x>~3U-+xMA8C>&Dlfcn%=H)yHt?pR3M$TqhV!ZEE z37!Zi(-Q3`NnkBpI^(HuavaUT_e=>S?sdkq;Uq1w1I9_<0=RUx3*lr+8{dm1kiF0c zsRi`A98Q+WuDD79*Z6_A!YTX$Up4C49}kR|ly}0(lSis6(`O56 zY=G*En#39p6#~L9{s)c1kZBho9n6APyD5U<^G^h|%X9^1agq4z!4?=<#c+p2i1!;= zJh#F=QzPpySaExkDf3WgITQyY7S-6I3#$sLZJ-$|cT0?7WXBk2Lnc+C0oAnYYbT-p z<4|$kE-)ju>qnoae=S^IyJW#pFo*4}gFl!c5BLHP^YQtF_%DD9Oz|3UGvlG2k} zxB)NuY4tERWwT{0FKdQuV;DHS0S@G|Nt0W|b|55z=;eT3441Y=d$yPq5#Bk(8j`COWCr3FQ z_{WF%$LB5aCo?IoGt$36X#$iR{lwR&J+JNaE--Gto+yFGfDi{!*woZV?K9%CX z0j~3af91aspBduc0@r7Of92nX&ph$p3fDN`U-|FCr|WzYW(Qp3fq&({7oUs2!uEE< zH4*q%{`>Ix^VjI#57#8%U-?Hs{x;KTmG zXQkAu2(Am!KjJ@da1U4~k;#GaskM^P#wU2}jufNV+ghkk|K&o5s#Ipw%<4BV17wXI zAMdp@wb+{ZzKboRRlUd0B(OpHL6&P~z4dcHha*|8QJKV6Jo@318zk)daLG;cU;A*$ zP1|$ldR-7`JI#$y56*3fM1Kj)jfj5Z;@pXl3e^O)Ctm~`&O|t{v5rD$&_qee4L!OG zcxVQj#A88aoP&nSseW0ZWByeW??BocFu{6sx7^>s_Nk8VC3%x-G3xElCnutTYCch= z>FIDZyw!AwnLwub2aDC(^s^Ge2@!KaU_z`Ce@=*)3)F-t>rpk9m%<-I?VI>uj3x1z zF7emEg}ES2e>0yeWL|@Ch02DLJycS#Dg`R%NnjaV)AJ;7G@K%J;d{LVj)N;FhkCdw zxE``(a)fKl@${Pk*J6oR2Uo*EPNMVSx>fuZ!1cfZtfin`4Xhv3J|)-N2+x&UPQbgU zRfcW^xdSL6RbXuq>Yx&2H5ha7JLqUi1lYcwUdO$`eaI`lxv6?%rh22~7ho(XBT@uU zr(!m?tPWjK=gis2<0P#}<5XhL(Mmo9Co~Zyj3ozQ({J--=t5L_%+D`Cw{pfGs^~$X z^KP`dJw3wNDiAI$l~#k}b>yIwD6vbV%O`?nC=pZkIUs?xaJ7z=z^QOT(AK@6*QCf5QortaR7nT>fFwE%efjN2IKDQ(@TqFzIT&be}+^taR4C!=@|o z(!GXvg0s@C=sRq>e(akIBHTJe%1U=-&tcQ;^3t7+NLlITf}#%7zP(;O`B;mjL+|ja znA8GW%9$Ti32j@C-j42*^EQ*{fs@}EJb(4*vG9HC7cwC{cx)y%^&1!!0%c;;NhaDo z15V?v3%F&ztvo&pkg7XFZLph|T-Gz%_+C;mHS}o7b`N#N|1l+<$b^Nk`e~fNZrN+!!Kz^+n2+ldz zRIFh=K)-GccLL;}%C_Mi0X*HcK4!u7NJ`e^shQStq0Zi`Dp?;)LZ9+nR60~qyNu`e9CKMWoWgDf;q?IP9ze}1(o zB?qcauzczyQ}iN$OrmRI)9r&x!{Bm&(~t71-4G5hHVtMHI}ke5bVw@L~A-1KzyQf=K$hkY~?C+1pD$kDK+l zjMT0q1^WUyjqEg#KyVcP6V6Iru)>kBb8!Ok&<@-w>rD4~H#^+1FRJrbO19{E1tI0U z_#~F-a1N<)GZ|ga({kP^WZzGfhckT>!zF&)EAgB`OWgbd&++N<_8z9Z?NZ(#hM3Th zNJDL;fi#ILRN42huvC>5t9Niu$B!Lh{E`nIA18r%HR>o_5XWKm(>AAfY*Y4vc^_<$ z`otp)=bPg^=M^7S-ntFv$;|OmST`IV0c>|~llk2Ed-y;fel;dOsOg&%T{W@qr>VCMR)oL7ug08FVJ? zseSZwrr;qFE4c?@4#tp`{3BdV>lpSM)IBG?t{2XpGti$?ik+&WgTZ}edPRy7Tjahi zN0GCR1wk11G_SyJXTv5bs!2ZfBk6aX+{9CnrshNMz4sn2CvR?ir2&7o`}XFBhMb)E zu%}*&CZ5X6*_r4Z^2sI^-z0U--CCc?8C}vI%gb@aO2$Sxhs|Z($y5Tp(r=KFmiD?9 zeCwNa>2V8pU@~Nw4em0^l0cx!H;6`Dn@Vhrr1RXX5M{9Q(2c#tki=A9&7qbk+*fjv z5l6N4=}fdf+StYvLSC}|kSP8gbdXl6?;lX8{VB1uAaC(==odh^6D<8g8H0pxC0~cD zT=hxQLyXe%EyXUK$T*z(WFv$S(r`TxLi>)YjKV$lf+2a1A>91@Is&+#afP3%W zU4Cbp^jxlcD|-%nNBBt@Z?oZSElsut4iZ=QnVyrL)Tgk#5vNDg;Cw+x)^Y6JZ?}_C z+a-JnxZKvn)?DV3=Y9b`3J)Y3Yn8n5IlVUB-@W#E#FaP~ z2tHLfaqGlJgCOt5`F1@HPJw4L?$#i>WQ}}z23^w??H)GM+vnz4?yf<(S4^1Tt zDmE<0J}V(+-HF_P=+o*|Kn^E=eOldqdV*eL2jWZ##~HQ!0u@J9#J`V_=v}J%%kNQ| zp8Z$s{rG_#7xRzwqc;bnx7eM)RBrrvCsu}bZ&w%kWZ3bpN*;ORpHa{B=EN(*?O!Gi zMB*C~d-}~t$9e9)?oNY z-BXF~@h>akigxgZZ{=uZ!n6?ere>s|yYU=eeq#E^Xr?_Z<7k&b1J;M6{yn|`vOzLrm@4DrYPf5feRFeaO^vdN0Fc` z>XjbS^P3?u5HIH`T(Th{_nPZ0=udgp3>IkEV&0s#QeTAAl*ZHK=88u~Uc?ptFz(+* zPZ>i`xCJfmRL8e*cFs?4RkO1VTdnbj=>4dCbhXENb}M zZe-K!kMLVr6anVDs!8PQ|x3X(rECDOAABhdh9hl z#N~!yb5O3S-s>KOU*gaGrYPKv!+QhH4@O zA}Fw_Fh!ZADUuTTjy7rfXhsGbcBUffnnJ!5u*Ebr9XZFDw%3_ki0h)bue;YP9Ah+c z9LUg_)|ZJeJ3M`R5XaqE0B?QuvOrw^Vo=ZbLC2rZnV8eFNq5h(ENt%eyT@TrfFif~ z-Sd$zfb0Sk`76JBMlvYSJ>T^+yge&J?waT>x{pDD4CnY6KAlC8Vu(@9=|_H@mEkA+ z44=r#u)xpoC;t_u$Txff+LD#w9~q>^%pbBc6cbQt%)G>)K$GR=XjQ{EvocKi8RCd{ zsL5Xy+L2LRKspX&c$r_r6G9|zCCB<1p2eU54o~zmyy{EgPI(Um0y@R@AMhrVMiEuI zT{u%y)vzHZ0IUA$y_`TvWf3uLcP`5k@l@L&kPwpq@zP`0yPrFN$xAH|{Q1k=hYK0; zN8X@LZ+9?jZD1e!s5(;`ia!CA=m!vB&lYoez-VIg~^0~!4qDxJ?6Os z<995Eky?bE$FLwz*bD(@!Rze1qI6!*cVM!=XA7(EiRp5I4BonZo?(a({&AlSwq~9Y zeGV*B?2L~KnnR#G!_EjTXn195tP(NNO3z-0iOX3Elb%O@JsIn+){G(}1V$T6I(q@y`~wl2b(`?^PS3X?zaVUCSfJDqnjl8a zC@sKlSAGyLoT#sqiMlW7jqKcs@NO8owAnoazS;CPPFW(N)s#7Wc_~=2 z{aZj+jqeKej7-14HO+;KkHLEmp^?yx^-YPaZ(^`q;!%00BYPfb)bA7Hux2Tw6@>mo z>nPC9CNJ#2L1ckM_j&=}?~LVZI-=buum5KjCbs5bnX-fp*Ckj<8nLk+;X1~YFNUN# zW3@d`b;hRlJl+|rYwmftGd3G|?)g>Nid!geF8!%YaMmZ$aWu7XG@O1iqA-(3WV_!7 zWIZ96d8+@Ti9NU+Jq)EJB;VquIXyUnykD)Vh9WgYIS@Wdj?`W? zv`YVwl#sumq!cVg_4H9*Zgimze!M8Iu zzjMW_h-y7j{p!X7RAF!Db$ef&v#0aAS21syEPuzDAXaSHGm+==Oahi!fnx5HSfc|z z>%<54%)Bm5zy}uRU`Cojcy*$$dqW#sSVHHy^(JtR1V#|(c!3wekMEn&{8R}HdV^&M z&kwQ?_Jdhu;ESNc?meG(KPGX^OY(Y_Y9}&OD2GzQ$-omb@R?}OEFCEq% z8IsfU6Zn+BC>6td6}JyIAIel1<@k>m?%y&zBWG`TA2~G06`wCi{KZ@E8WhT`CrV1M zsu=UF8QL$*>1oO4H=@i02?ScE_0a4erSBJIjaW$wjQrs2D(lFx85lEVr>TL!FAauh z8N^9&uL(6dS{W%55L)cO{E@~o*5KWROmb-8{dtfJRKrr|;!;wspc2Jzwqe)^3UT{b zC_I#E&oiGOvqHC?6~J%o-JBQt6a7am5q&rwkSu|2q}lYA&~G3cr=k==UTG5CvmWa? zatrc@9!J*ef-ma3jdF{s5YsKbT5D{nIrpTbCFnMehCamCbZ22UWB*yLBt@Sab*`rQ z`w8`lWqCRFSY%I$-kWPZG@leebNp!2G^wY0)W<7NQ0?WT1x<68-`4raeR|}hXF!#Y zrf!%GL5+TfM~iAAw5*ipEaHIKQ=eFhDt7k#Sd+P?CsK9+ha5&qfa-*XJ}FYr$0dmG zHE~1Iqo5%w-{F#P{1~5fbpBo&Oue){0{agN7pe_g)7*j3Qj4^G5PN0+zt&F~FO6d6 z!bq|VW-?PsNCV0YL%_FGd}kFy>vaM3W%ilBA+eZbYO}zDW1H6`^=^!(u zSY=X(OeRYvqa_oJBQNC?ECh-?Xcp`<4U!L4T&N;cdBKX8DPQW@0u>*ve5rm7_)b*5 zv^5d%RgIhy3;V`Y+^Vo|mGZ5H?^%Xgf;?(UZDIr2RIW3n)@c@owbLG#nNrJinJHt` z2b%|k)PyyqNI_%OXByKZh_0J5#X}ui)a?>Z_eTm zTkMxGb!RFCm1vpA_VF|g&l&eT86JP2eJbC{&w&GJMTj|>YG~Ff<(u7EvAZy^{O-?l zj>irzShGxFuXMtR4 zNA0ToOickv7YWL>))jSE9iiI*iChe>aV{HfP%nHc#9TqQPA)k9bZ~r)7aF&MiK~i; zb9q^M@>sVXQ;*EAXiZoH%+1Rw6EjnUK0SI63P`nPrby=pX;V=w8^AGmi431})bPPN zz*JIfcX8j&^FVDb4~)h?hH#_?Bx*7%A4JH77I&jQ!b*!_Bfh6M5Hqm6NX!f~Ww=xh z>U{;a3M0@;?xYxqqvJL7Ffr3L1@5B=z_{%4JxcP8L44fetPmm z&iGe?ItqABn&qFx#P8EsSo>jPJ)MQibMmM^%8{;)K}EOAxdM-#?Es>g;|`2H=Oi93 z<>nDocIY4I>$FNRJ!g+ouoCLwUTE(~htS+{;24!%yd#Zg*RUmQRJkBpDC=rqWqOC# z6zK1unwwkftk^{(fZt<@({>r1nu9!`)B~-|-0jp9XCl&t7$_~GL(4dqM<1oJjr1Si z`Y9}ralBO*JW5j6aL`h#8}+7R9*9@C!gdhHQ5n*4h=Z9Fy@5RHrMe z#F?(F%`^x%L?P}Y5Xek_VSMsw6f5~7YK~@cDVDsQPSpOg7*vuUcjk`aQtkV!FnYo? z5@}MuVwKSo)A6Pt$ZSkgRi4^&2vFRV(V)U1Q^q(~6*!lXpK);e$gL@GW{pO0ddiq~ zXd2v;SvT5k%J1&zhe@_=IOz%aQFf8m+-Isg*l(HY-CTRS(?LMZ!J4_B=lIzu``36@ zlv+{uT2dM4K*ndx>&I#NnaMF^0=q*6*w=8+Maq_`=zvF=b^4`r2ECA^KAclb&3g2V zw+ygSUx0thOvc8&CoeXS@VYZlZF1ziFX8krB>10&%}UKfBI%fbywcdahPjx-3*4bf@71K^cUsA-#OIzTze*Hw zF-?;GIX!3IQ_h?Fnl?*VJ|BXyQZ_@;_r0%RvMYdGUV&*J{cn#*Zx*B8@xMD4*Eu)9 zewTf+-u;7wNyJ2u)EqB=PImslzS(w-r*vhhb7LvDch({%9;#z}?jPA#vqcs8PxTLh zaA~b=wI0U)UKBw?>A;LV=jwaX)$3h8_7T#J$q^32=kIy)BiM>E-Ituq$SdxgZhygv-}B^)uTIK&ly^=z zOwK?MJ-=bb4?T~8r%Sbg%8yu}Eq}G|qU(Y7xZJ72=@(5ArSe9DYUIrLI=_AKbi>ji zcpuVA@>UkwB?iEt-`i>0D;*=JRfspqkNHzKLl0kHs`p#LzUIKfs+Bwwy(CkOuNS~@ z;p3DRLe#QtDEk%@%RfnK;p0GGWe^DC6$ELU>WOzTOnL$5sP{*(5yXOiCW-r;s8g43 zJ(5>HDL-N*e*@3@N!<0lMO@cKtkw5P#NJdZ+j|o$p{#a+Rz0Gob^tc*Fo6cu$<=#% zY@r*@PJG}5`?r(?_59a@d@VaM3t;gx)` zHLOmKgTaUDluik4nu-uoCK?|N;c;uY=#Cy5%y|8FYgJ9uv zOwY2Wo7iAg(=0Q$l~L1TQ9d^N{Z0B-)a3Oyc5Pjn!IyCo+5(0NHA~*f5gul;q!s{H z1l1!sM_~#Gjt1n#olP%z`9`&1L(W z1Iex3o-fPhYlSh_Ima2!W6yzVySAJ>XGn`oe`2VCRZ?<}Q#i!LwUVELD2e!!mDy3q ztE0kJejD3Z5x)n4Py5Hgz0ge0_oScqZ_c%kX*__wZ4lT>T@Ar4(VwU1SNps~|1jV= zzV4|5Lt6G^Ca~C{E%Odd$Z5KZCL&~F)^r8S19$Q9qMnJ(q*lyLcya&{@^w_RP6eue zhzu~*sz<(+ZpEY~q0r(*64OO7z6}?C!%EI4ji2C+rgPDLHJT2fSL!EmH1)B6#E2~4 zah--{Xq=$9K(998{dsvI3RM*Gn{>^2mtR&^=9ICDQ*p{#&wRy_vm@!eIa=+av8BR= z5-WC8S;=nH%xR+84LqCN*Io50*yAkZVC1nY{qqV!tXDAiA($=oEQZ`En&fEXy{voi zp%jd2)@de6A;q50n1-uvZedDt;2q@0%W?&Fw*Wx@!)i1f0U7}FlU89uba~xP`oG~@ zxnH+Z|G^5^czh$#KPfHdL#!lsevM*@8PJ4?{ne)G?a;)EU0dDG;JP!6Hq$^>pK>$s z7lk-%77^9EFmOgW>u9ZHLexq=jBb&~oLJJ54UW{q|QgQjRmCIJEFAMW2~lVnlHzK=|@OV{aYk&zHxAZHuJv zdsV+Ijb~~rPFCV=G6X7NVFO$g7Ve=B#7IxVwvt~0)p9B#9l^F5k7VMH@#LNjVcb{ZUxVZ~KmH{MMLF@gjudN%isHqenG9k-nrK99n1$z2$6$} z)Ij6$8hOcZ8a&7~n&Yoi3KHa^@2De}kpr&r2Q8Rk6=ZtVYZ0%Gs{C4HReL<)yE=%t z+2M(a{I%zCgA#l_KB)EwLsa7~W`~yHuSk!Nxr5Z=ay|=0~Z$`CR)`i353dG|);#e`en(5J0id zbe$9vI7iJbc5H(OV~ZXZ`c)s_69!ZcM?24O^0DSEF&SgH<>V|bN!*l={r@6=|38>B z>LKSxxb2wbuk^WKY5L?gk4zurpnMB)2Pxi4zJLH{9EGnPaB&&El|JD`&?)Ew^0i+g z2(s#XSpP6~j+H!}A%|dJ`Z$kmv>-qUY0rv_LRuSKPJBmdzwSOO8AC#<-q>G0|KK%q zzOX!yTTr{iRlk-wF`{k+f--rdSO)mq4y;j*ac1r?yit$O0sL>kd~PMV9@F)5IG*hj zWh}G5I) zxCEI|#+8$uET2u5Gv^#5a0eGJc-Q+elo!xHsryEl9L^fh|9Gna*Cgy?5=$dtYLgX2 z=)Mxt55g`s+m?{8dM_I@#c-XHe1iD1|6zE=Mv-gmm-W7Go^3OH$=OiNU|iyDg9@lC zo9%CAPjPx=_54)EC9cZZpTsqt`0dUW`BE0@f3)dyIaa_`U!Kdu|Hv13SN-MkTr=pz zPxYrzs-CUj8pNkeIYuhgh07@*DPP7{8OIm5kPB(%TaB;(MmG$=Z@L|NclHkzX~|}| z$SSQ>tLWz~0rh)kJL5OVGB6Jha5KCT?*vnIg=aq3;;;hWL-6KGv9^yFx{?@^lwgxD z+UH^vmP4{q^r$30{eq!xjm#xuOZB4x663J)0q0j93J*{+s-Bn5r~~5ILN<$1dm>hb zE#;Kg0`+w-QTR{37{4>Q(_W96O7JJ8qF=Jdjr~NRBs>T7pdMeqw|Y-OcBU{`px2%g z#o=AG9X8XulESHWDDQd#P5C%o?5nfm$KkO)e@U#z>wepn9qbi*j5G=g|Dz0t9X!Kz zs-7oKQ1isFC67t{ac--D=MZ?J9-9TI3iioyTV`fH3h^E&Q14SN`!;N~_%(4>$i0-| z?sY&7bPE}*m>qTreHo4WS`e8*AVPaJW2Z&kJ4i3TR(+X_{IqK?vH(v z%W_YF$4kV*z2eWHq|9(KDVH}Hq~4IRF}p)^^O@gJr`_zV*y}984F~)9CuwXW-HCih zIy3hQ^TEMQ99+H#^HO@+-uSMTBt&VUZ68^vzq({|4@C@&Gn4;LB>fFHK{UU-UKK*S z9a)9^GFZr;dhSs5tmO&+@yUnm1)rA{ z0QE1)3)F{Qch%%Kt>e6fHLL&3Ha*Iad3)+haOI}sdxCPk=rJ;}8AQL!V}2|@yk-u{ zu|0QZ^+%#Nbl+sfL2lf|`v>*~L}Py}#|OW^ghBN;(NSpSiHN*^kbd|*7+mCt?wj`KAi3s6+m>&2OvC;qp#aOI<$U&>b)Vjue6^JpkY-^T`!sd@+u^% z;03G5y`(Y++B8kuLX3t2@n!zh1exPXYPkUq99Bjuq6Cqo1`rw3MQTeK?^OiueOC9m z)Vj#{3tW<*>QpY;xF1DmfFJYyZr*7djW$i&Z6zl`<%U_<+Zq>A)b+&(Js;H+DaD9x ze8YC|m*#e}!mwdwS}Ti?p%H7<3)HTui&A^6UyBV>1F9yDTQSK-3#yBf7uxm!0n;WN+r5=*(d&+%YGCjp%Kt)CAnb?+R$Y;0s42g`%`||*fjYl zAepap>C|xiJ4^oo@|Ot@S_e1{Kfjje*_QwN3SL|y=(bPP^AI$8c-nb)_q*h;eEjk6 z&UxIszY$}D!T=;Z?kT1I0tUyf5x5r`TYcQApcO9$YIm{WLqpKv8m`T8W{6J3V&kkUF}RfIVj zw<7TTIiDP~hwdLT9M7>2z$N7XAoErBfYE5lD6*d?LEFD`hCm{++q1$m_C^WDQHDOl zqeW|C-${-S-@pul`KMS8lkUq@7jUu+AE}l5<(Mp?hE#Lpkn(N3LyI@W`yKN}oeAz{Fg*KWF%0=b3>Ep%c7rfV=}eg9dJ~e=iL{Nl-?ziBAq7Li>JM zSO0YU7T{JLU1*B@mNI=v$>g8U$KE53z_;2rhp~lod{i$jz@n*qC%D!(P#w7l&1J3` zmr{D*HBn`xZwsHhw$BV(aknwq&z!0Bgs#2iUZ2YKUVwaui1H@Z8%>me(cc{8WCp540O@c0sa zgHkrU50(bwS26;_{7TfXySSXUl2oy#cEbKb8(LMq->5{iFe@TpFLf6`=g@&PidD85 zbMQ_*1n>Hm{K%6WD?)i%J%>lB`;)D91y-0Ba6p+eK~vDtedv)h@$twnuw%zPcYtO* zrl&+HA!{2(r^`~p*f6q^6b%$XDa3y3KQv;c3@iC}nR`7Z;ZilH(TlSg5Z%{qPX9md z-Uhs?;@TTOCpm-w(Vf=RQX7@F*n)tPLaQlQL*hwLiBd62D^XF1+WJ*I2dIio*ykkK z-90weqTbst+iP2Iuf3&L3aAtlNOPj4Ek&;e0g0Asc9Uxny%4Z(d4In(Gkfoo1WKRx z-sky0e|Vmpy=TwInl)?IthHv%nwPyeCO7o&5_fLQKW2_O11~sa2jFD~eF2_#RFYZw zo#YIrdqE--(%pbHkG?QM|7NpGFIM z7f@>n>XO|M^Hd2O53^uH-nvTNMvkYGL_9BzSt+h>K||utl{g3Z1n2ogX3Y`+FIR<9 zX=LP2CNRVxhuIXP;hDh*Rhxcabx)c)iIDL8S9huBstd~KB zMe1E2dJ^mba=$AVgyC~MoA{}swGqE=O?=%fpt2IGNCzZ^oZH;3 z)*A@@v5CYv;_QD4S&sH4XeHtDBwXF2FY?adW^rl|; zlka?vrC2aLps(|k5%cXY%HBuEQ(y_O#(Vu+-K{iZuJPjbXUK4@^eDVS$T%PJEK_ky z_Aa$PBqqrS7|9xOn79tSrV#7<93km<=;b&pu_^IijQ3&{_%P&f@7rjAcCA2EPqlKY zX>Bv{h7f;YEV+laP#DhYg3IS|WjL~iZk~UMB?+dL{uliPc3V6J`yt}r04jkEoaB{g zhJ`MDGu>%n<){lA!`@3xQx4H1}+IS6* z>%-HO3(qDp&tzZvpn(V8XlyBYhVZqxuhOLG4n$wIW56*Gf`k4mA-q(Z;j_|ogX0$~ zEq<24K2ZuEWGn>^Pu$93zv!HrD-T>%EF?j>wI8(0xs~HUqekA3SkA?3E$kK=HYw}< z2aSR2WS_#N++d{^aS0FwAw)BlT*Tm2;2Zovi-}CEp^EOT6yvo^>){*0M`*n=XkBXX zcA@n)-7dX4M`-s}Bzp@-Zg=X5wVUbz&ULTL4tfXKWy)!)zo`-1P2GlMw|)SF@6+RZ zEJ%7BQ1l3^1mocIeJCCHGsC?nMq;G%dx!`Y;}yjC8GQM;{sIRuJf#o9KT@JTLtoK) zN#cGv$<~%o8`OodM6G*a|7)Rfz)S`lColr3y=WuA1UVk;8Ue6(39z$}3DOY$YVtfA zj~d)Ve&T=O2}Wf~4JjzVfcK!GhkDKqT3`Wk9!#wOd93^C{#Vs^vjSn}W4y5{6ypba z#gO22R(cv;Vm{sflQ4Y({|G%d;*g~oJVtf`RXfA!l*frr1WV7OYXO!Ppj3!n3emX{ z==5)Fd;otqE*g8v?hNb13ALNNNw=v>i+2P2t9V-3E^id{VbF(uKj?i2@A^&6rw;>T zISJn!n$V0P*EzJn>wT2{%UzG;{IfD?U`+~zucMI9(Gro%cVbBvg>@isX0hs;{zSk{_$ zdbxv?j9`TYTq00HaF9R(9tpB7Z0E(HY_`|`L*O^8+jPKJ)aYk8CBweM#6=6pE@d0$ z8Y6DazPP4^P4qIGNQnG_co-oOXXSNnZ67*vGx$WNB8tvb3;ERexpeqYYRNNPZYu@i zejg}NiTln@NccL6mFG00KbdOWXK^(7A4tqy7p~^a^Pswv9R>2*lb`GVgwXF7jJH`L z&)Hl4yHy{62SoaNoW@vQ6X)6;(ek&GJK^*E7g=|})MUZO7PsWT? zcWzF1XstfniBhAY>~{_unEx|Pn8|mIesB(K_S6shU(QWG1LKJFozNUO*;F(A-_`o_ zPt~up)9WYU8v9|edByWDt1w^)mPWn>p);f(V3^|I+v15qjVJYK^Iesr1WA-Ap)= z16Z;EtCi9(YD=@euoccm9QTi=1lh-SJ1 zoe#hj8Ki&A!U%wfn3Y!QMP0TK_Xv1D1}-$Mbg`r0HtO8SC48Gt6K>!4S!J>WsQeQ| z3CW#UDKik{8u7Lxk>vm!8CCfu6LFeJw}BsjK)h=JtV~S~gZED?mK+F3(BsK$)M5sZ z^T*5MSfS=94i|Z^F+&pEm=oYW^yORanTsN$(bstbgV4YuqycR!0+1Zcs5h10;{m%2 zktQ~)P6x7uF?)`XMq%H*_pv2*`GCk;4lUKAdy`&8C$cg|KOA<$pEN5}yK;nwzmILa~8 zE(d-gL(DC~HZ`EL($^C4@!iaMmE_#boUo#u73A!tN%#*|T4KM_9$=;ZTh!EE5Croc zMrTkfJHC&@{JfPekb3tq@3)v2-ZQG+->STXpidy!4Gd#ro;i7z1=5ht`7c4v0m=Cv z%(-fSGeXPcbjvw$Y;&#L8d7_{#vk2;=;R zLHHaU2?@x3-aYPx9D|k2p(-3CNH~>*`oO+tRf4d-gQWf)ocv;(8Gu)>B9?6`FNtM8 zAyr_$g!${m`3d6>4<}FuEaE;bJRB4n2nzjxh5jt_avv24dUK(WAvGRa)@0ci6ynWL zp36dYy$ZHo7V6bhH!UbcTGrs5$3na}6dT?OyxlBhCJXPi(=BnbpwL{PAdiKV_fd}m zuZM-qT;ypaU1)dE(r>|zyf31pSa`fCc+vwC*u%NMSX)dxWN3>q{T#&&hJqf@`-@M5 z{3)(E+XJ&JgW!b_CE63;fF9x;Q6|$l zeZ=wrA{yigED~9P7} ziQl&LQCqCFSpO7T1f5u^pYy2z3Si>tq51YFej>`~4{$~$IU45H$44h_EZY^5TGTSv zgq}HrU@v_~aMcp~Zl&(Pl)zNFL-agZFAb*#1RX1{1-4L6-{d!mmp+8G(0DnI<=PYf zq)pjI7(k(|$!3pJ82*#-B4TW$Fi3*!{vRR-C3Ta!j%e5m zn=o67)7*F|G1YCQaBUYDQa4sJdR`vYnZ`Rz zP}z7pb7te)_`?Vo@l6J|Jd_8w587?HvVH`O8xc(la4H@stGx^z6BGnzPMCZRl3BKt zWi{89oxQE*ZO9&h8*gX1a{*lj>oE)uDDJN&oOrB`TPbFqVU^8bxjr9a^oV&+&CQF0 zXl`vcwu`18r~VJ*mcfWQ^KsJj`0!{w1MoQKyLD7wKZqYg5WpPqqxb$rYo{MAsB<(z znV>ym7^U~38}B9--iJqGi|y-Wi|b-1zjXlAbIdtS!h5`0<;s~go&j?Wx}M*jDUkK#++VeN!ElEZzp%b5d#^|G-Y1d zfaH9mq#E%iB8l>*o|`ln=sJLtFS?%&h|@`K17UhMumI(+jTm|#mty>5J=v-Wtk;ci zbGCFGIn${c?<_#X%k9pB67Lr%YOsuUs){9sqt>H7P5;*9c6;e|?uN=(JUmWIewT1*EzuotsVC zyq=Ed=^?n8a%4D}p@I{~A>%XVLIDf;fC*%`6 z;bb6XL`ZDS;@%47bn><{*tCVLw(mcdu}h4a`;^dE=#G}eM_3JJPtM^mD6ZEQ_HR(* zgn7Q}7`VL%fgr=q;=N*M&?hXy;UG^+?_xm6?MuIjeH~ z^%9p8Cm|Hd%JUgnYG>-ZFQ%%yFBH59+WAcV>MD$A;%->h5~nM^aV$F&Ot+!CYt{fK zBX7vU#D;GQ{xH`gCiwwr(zpIK(w?mPNr#qUzxsrnqQtQ1v$-c3N>sUwTK1esDh|Ru z^z>Z-yODTLk=}U%M~#Uer^NTo$lQxj(ejHp>vS2SpQ+#iwJ+?#CATB@&MZ5}>luxW zzr>U?d8MD;zl2gauAA{r#udyLEl*&l8zyjw6kz?P<1(t_7}PS~O8o#>bn8p0ihU0Y ztoTiVX@1pYX2N(R+>ZQCd>dFIUKT@;h*_ysC|lP43`ar>7-9Y|j<2wle>78irV%3Y zeWovNFkt%WwU`mIM!`ZG?>5cmu0cRh(^i>Z;C)A(`fYMh3hP&BU83C&t#xTgWKEK5 zjlwXcZ$){IDtCYNnpAqGza|CXr5Uw}YZ8CKnc-yQuP9C&>7t+2Z898z@=d(cN{Rkm zw=FoW3uHs?`7mlJ+r_b*hweH!=y0Z!T&O2Lz7%{s6N33f%Nch)alqtTIH?1Q&rtlzi4kL^8SIC{1qlL+un>{= zNq_|X4HU+m*&%$xx2a|pfp2KmCB~t6cg7r=@TUNH$23T5vQnPIC6V?ASxybnaUxr( zKVVLHyiGVH+UZH)9Yiw93BUix*UvWduMR#?f2z+}PnDx&z;DQADsaTDPFj{4UY|rh)Mg zQ2pqbGFqtfbf|&_T=5pha$++p@Fmy5&S+w1MuZJ)aTjNPIf$rZ9CWNfl0p91??pef znj_*L$VZkfOe6V>!31p?wgLuSh}CWy!b12J%PBkZhq{d* zwWAVLT2^e4U?9yfKwjcP`@TsVUKG3Yi};OAoc^WL z^m;yntL?RFp#<1gGf!ViX`o!@qm?=zNd{{uj1@{1#`DEMmE`tLK_`{%4ql z@IS+P&m%_T9hlGR_923#Tj}=&+uwpvbOdf;23_R*mvL#L00;|lUMO%r&t&oYXYrjT zk-V_H0%ydbQI2#e>Oj^#Wg!bn%KLj?9Q(3L?YlA+e@BWL~w zb+6Mf%+OB(GF^7Pf91L-`;XF?=?2ge@%HhX8pp;}??hnfiTBwRJlfvt#`k68#rLos z?Rp#ZG2(2~%-^MxYs473aj1+##P?^CnLYT1-C{P*+*&;rO*Kbwx zys}v8Eo)cH5cF0TQfCOpqp#OaVGr+B2KGcE4N8E9U`%vDUJgI*w$5mdC zdIdi6J^7Y)2;GSF6WYGe(Y{zX_+K28UQ zqlq(lzTsd3YcIm4^8EA3&;A<2qBj;3xG%M-lcmI9*Opn++Ye&+CI1S?TC;H%p0tkQ z{IVNwi0Q(=c{T#!%Hy!hHTS5?H4%4>#J0oDuoC;bES5hxBc-LL#!a8vi-yik6nCXQ z#U{_i?`!x4ozwgkI~T=+`2~eHk)N3#rLdy_HGpL@EX@+Y!d*r%XZo5g2jyGU}UI*q`=w2JkRE=`dYtav{ zk-${X{+VR~$1GGQ^ISzv?Q*s<`r}lzf}P!WH~<{dcYd5rx1%&3Bi6%PtZ%lTzXcbq zAeSp>BICFQvlB#)F?kOcsYauSkEBaDzg&kWMUQKksCy~^AwN>+k#)Fkfy@-19R5)chEfI$uv7a$p8S7;hJ3uOR9ioapy-Uco?;B)HsU7Y7=RC)s6 zg{1Pl&iBAGw)%#p%*=3`(n8{HQ=b|W3?|+8FjC?PqA~PbWNM!hKo^Y5dNeyn=8*RQ^2>bH>qR4vtOqI! z5EAG!Biv8oHcNg@pis{sl9@ZI6n*i!SIMM53=`CX`bAzt#BN!X&a*ZYsKBdRFqGDY z?x$rjZ14Yos#n(6B73mLN-<&!R@nc_#46k(SrcU~#^EpA0~uO}t<+bU^R#3?*W!|N zG1g)obG-cd#ATdMblLJdgL_VHaP0_}bqpZs?DoT;Gg1}(0`2ydCa-$$EX9(AR9T0y zI@Fp)cy9`5#OZg@Oc<%oC`ar>9B>T#K)TspUmGg^!%@i zbw#2|j$wUGhZ*}n*#{}UE0PzaV}b9AEa^vm6ZpLq-$hJpywLj!dVx65tcQOgJgTVv z!e5#WpNstPv}ac(j}+^!)cX~ZmM?L=wH$+b#(Lbx58h+m2h4lZ;mJ}T9feRm8zkePsNyw{hkJ`z4JRI+Z2hj2=&l`T4sdj*s zSnv|mw`X{L{p-#BL(rflCJyA$*r$$^rm;->5d&=)CPWHe+Aoh~Pay1WDoT1`+CGN|_ zz71ldmSb=#{0DKoW-yKy)M}_Nun>MEmUuDTTJoF7A8f&Ez0Tw=k6Cg8u>Vm#?{qDn zMEYFJ@&49Ox+q6eF$ZapRq4x5ZMfh(;Grq@%3$OMokv=7n9CIdiRuBpA75W`e+C&S6KuV;<*FOGf6kkPQsWBV{ULU z8j-t^vw^KOI5P~9PzMgGH1iR0B!t7`Y7vBZ#nn1c0#5G#6#3kCQLPi7P+IqXr$996 zYSE;tVP-LGT;rc%fVjVUlIY(Cbn(*;M8_?-y{v|I${EfA-m&9UBYr*f^J+wq&(oJE zA;@fP35){IC7yOiV?y4af7xw=qB!4LTSt*(o)~ol`;U2HGCt9J>65y`3 z7-w|jICua$)ks!%q2R0w%uYLjS+XQ*Z^ThMwrvOcPf_#Nc~yHHQ;HK#{$J#7cd1y- z6r6pz9`TytJ6TthiJd%zbv^CYmWty&1Vu#4pA!R#J9A);=wCoZNF1G~Xg;#4gfnq0 zU?EF|;CxhAs`HA5gYj9c4X2cEPY%Gb$UzX@Dx94yg>=A5D^aP>lSwyl+?7gTLU|M9 zlVcn{5z}x(wkmH@q#>IhCH0XAm6kwq@;MYt$1?g>`di2#tW(>GtkfA`^dVc(shVE= zb<0YfiX2!WAs-u?kyBNK#a84Z=LNaHvkfQVh*Ws?1&l8=VXV}2a3~PFIYhrpg5;cq zL^+2I$3ExMBJOO_uM_+C!eoFo5FkdR5(Ef$I$%x_F_ei0uoU&4TSqd~4 z<O5}kZYaRADHcB(KjND*@M1GEZiD^VaaM}=Zn(<{NtzB7Zn79iLu?3{ z#t^$rx0oV(4r+{y+UwTiz&9>k1}@~#=~Vb(N#s~mOL~{XJr_ao0(@eAQN<<7$A4mD z+!>TfOuo8RcteOM!pKF4$QP}YL();a5y#QV8{@ml8{_-%0g7*rcNFx1dWZmhzW~3W z|8l>8!2@?fLjCZbLn)yv;0|06<3d40>eK^TzLh4=UTswOeowNyy0FdrGJylmG5_Wl zdeq|GN?ZyCbGuIqPEDcrQ+@z?V1%zJc54FGfD6NT_803j@C2#*v!mn7d10Jru`UtfhEOF9)t4yj`H*+NBK6q<(6j( z|4I2o96v!>enZ*oSythX*vu`@6#i4~ryH3UW#r)a!4Q9OvR64TEuajt$f<3&S0-q? zBn4yfi&$&6l0^9^?2_p~Bq`l6SV;$4+l6B({5%SuIq&@?87{Vrmct^?@ta<%`7Q?p zjM1*;3H8-y8tPh+7Ipcl2V*sncy)hfibhP~SP_x+|TYDH4Sm zUVYA%DGzt!8x0~)5)kDciLLn%lx_>NL|fYN*ZF=Y{!aP6JYxmH7N~U6jd$iW-SQ$c z&z#uN7xQ6uAMQn>Y^M}i8(PRvWv1n{Rddl~`ewF=Ym*ib@7QWN7ckO|X9CI!!&3WU zgbxMGFu*w~cy~_(cR-^oho&=qxvw}aH>Kv@E6R4<(%uJ4{(S7FO=)RFBYUS#v^xv& zp`)*4zFTv%dVjU!iupaCs`%t={e9=ES6_V&oaI%y=6d(e+jj3=wSDJpufl~hzh-4l zQ!Ob4dVsW+)*&eyOOXI1=>CHN+|L6P9j_NU+u>MxXjM0Ss=Qf-{sk$I7h9=Lq_{1; zC_JjMsqS7UzAqEsXQ;>jRab`)+0754fG!Pwjtx`1lQN4@1w<_pxqJo@fH7|a$R+f) z;$|kOfs2h$fg*uIH4Z3uJ-DLZJsC-lQR%23srg0=L*qu&Zh*4e^PLX+wfsy;2C0#9 z$QBgII{L63Oi@_;vT&wxa(72>KEx_2n=}1+N|60Ys?$;0pQox1DnBPE^YeQsJ;tN| zrmz0&9Zp%Q_Mo)e67ELMK!0Dplq#Cl26|vc8|(!d;Udy1#5P?u;2`o;HtbI;Q92V_ zQ-}{@H|_Xy9*%-IFPL-uf5E7c4+6i49~<^ZXx#ibt4n-9-64)ZHt#Ag0*O~94bQ5c z>ug=N7br1{w*ZBAwnr-9kAm@`ZahMfMqq5#>sBYoRjA)Em`-0Q;Xpr7lw1o))<=Ui zphl80zwT8Cr;Q-!C?Wz2L;@+Lh5^dl{%G?iwiB>GEX-$Qo3|s8|FX^7)B~Of8vg-{ zQr;T}iqrD@P66*EW5@Rx3=s5=l^lx(fkRs3G@^%-P8It-NlHNdyJ zFJ4_-8>YCC&22cZ>>(&JEDBq)Zy-N`!9S2ZTk@3`#CVD$g1w%;`k(5}xj zDcST|P~1UOvf_QNJU4ano3Kq3g)E4E7fDA@r}P9+0%n0ED~Htut5R6LXMN0T@pv{u zwInbld<^PzzRO|{5jXuP;84B8n>vz0(N}R=Sic&a^mvGiiyvSEp>H(?$H(KsZ z{?uB(%lU3Qa$(mHf8nFrp19cB@Jn{mek+Q*^H>j<^eo9`*&pW~x@i?!`RpwpM)-TMLl$f7lQdq;mBCkF^dk)TFHrYhS1gy6}*7a&mZ z`#7p_)BG#=y_$FcN)4U;L%*}W%X*gm%G!|OL*}B3|4+32P){aNaHN5%@d2nuAw0ho zO&)+fU^kU=Gir6%L{Rw0Ifm67I!fF)o0^Vdl%UTyKE*{LqT(3|bks^KFY;@^xHt78 zho6AYtM`Qyn4>S0U~+2ANTv2$qeOP;K|dtn@nTJvS^&b0d^j1rT3RZas3oEO3SC-~ zcG8cT(oz>s7Mr>#2i=QzPVi#D5|)E#R+6F^&=Pkwc_f~S-PHr?smNU|;A5y2icq*I zEDTA^ovtQ9lrg2ifa0trKD{iO)w97ngw?=wUrh}p9Q8`T07CX=iSJ8m<}7zU7t@)U z_+JSTfET_;21;OHCkxpGK-ut`|Lb$w52>vEIibU?#&K8wQeTG2vK_$>!AUFT0mO(i zf4;8|8~;*brB?3Y{u*+SsXUimO?`y_oXUmN^eeCDOLlb+fAFtsHE|GiDz8iwIA3G$ zv#Yt*^Iutec6FzEL~6VLwB3K&=0A1&PaF*X%gSKz$p2Ch!sQXGUj%=R7yBeyfk4lim3R?S};Y zDR5Ump+-b{;>SOv@vxO+jV7kMjqP|+1EbL2bJF9^?8p_L^9Q46RMG9Tu#qpd$hZuv zuikAWAz>VdAHW}nD*Cyz8ywn)@iY}rdORsF!+%!-IM)x74|*smVxg6KRXwU`E$*qb z!cd}u@d`7d*u9Kc88hp$LVd;USejWFXLMS$7`eU>yWr?v{9YX6rc%RMkqMbA$48^x z4dq)BxF;Hdro_=cT0$zO_h&NBHpwFO^c{G~7imiDIfFhQG*!&`#B*^gV<`2clxc zSd<1?XnfHfcfT_~rfADq7>ZxUTX->=>?kB(-%!taa(=dAJgSg=q9}kQ+r1>_ULDIc z9mVZ=LT?}1b?AkLrawj|%&IF<_c6mLQIeUNpNXB)P~NrTvzgd9{4RqTdB5`+)M{6N zNQ%w4SS^h67Hr?B?%_5XRF}BZ`Mryn{#J_ISJk(CAHJ!_yLPk6vCao|rKZZ|ztF=1 z|C%3%upCfN9X*T-TQQzyTLOkUv5;evE3oi}v<70;F;fzk=}ttKU*ykA&{yKqp*8|)A+(BEYDg?kfW~ON zfEXdwgywDYKM$c-<1a%JLD2v=u<*ww_JpYwxVe^uN4P-%jN2pk8({y4?=X#^7fv3s zori3)4!M_LMNaN3kC)ta&6IeFJvi2SxScl-^HNC+7cNsJrck{9Sv^=*>JVhVP&WgR zWVjLpDKuQ%zQH!%Pz~9bu27 z(q(UJc@7hUQ(=CI-HB+`fgQf=xgiNd<{yM2-w0xDKn=LH>|kO_gMGofqc3Ev@&;@% zk9xZC!(gV)2bfld{hQPI&|u$pb_D0f!iQVv&*P7>lNH}Uxc!{kzf;3$52`qJ$x!mA(v&(Q7wi9+rRxr+R9p3LZh%p55>-3NjU1LrdWs zUjofaR73Dr;1}yxCN5`^Dfk&Xas037_L1jc8jfzKBfY_ojK@Tbhf?-oTlP=QL+^Gk zz1giBobn(=G`kaa-P5d}cUV9F!!`9CeFdnf&B%N9z+8qWsW&&m?Mj}MgD?!5wK?ys zcGS}`SO8a<)_mNRNAb1)Wqh!ECv*&sYORXOb8*LDthFl7T90(AwJP7*Tp8`?JF~Sa zX02Zqwcq$^<30Hi=k3-@M|ino@T(x_Uc)2v{qt)Vwl(#iy{*n~jp< z;lD#yxtc}bMs#J?S)x`8?Oz*T)cn`mjBiF>Ab;IV+=v(-RZ13iu`(A$-*rUeG7T+% zSe_m)PTbE~HH>$H8yXF5qOYM%P?n`qcQvtuJ@gXnn-(hr_IUamVXks?WYHHb7qh>S z3kRBz_Po9b|Wzq_5MU2-Grxzpig20YH+Po9%=}I>@yc2OYiYe z8Mid^1A;UpDbMDV}a;TxEs|$X3tCU&in2U#IHFoChztIv?GlyyZ{-?IZ$L zEj758Rd|2JXolBs`qqWzO&$Oa4XD3ZVgT8u)Pv`J;lY%PeB=uZ7^1~ksfD@qVEU=D zW`#fuK)^|;D8Lx3qU4VC}WP9KFw=SD>p-f5K5U`)XE8HHG zCXi!a$ccYXS0%=+CXvypM$Xe(DLCdZRslvSU{X~xb6;sk2)-6L`B0?j5C(5@a0#3> zt&*dY@Zza1ajKvqjYs?xx4P7+Ds`(TI8_r|+znJU(XF23R84ZLr#e+r-RkL1)pWOd zrc*Ujsb%8~1xU?=Ae1uG9S7+(-HfiP+OkP^@1C;p9Sj#HT0gSC34Ke>%leTe z&_w^YQAb<Lh?V*@mg`TW9O~Rkobn|QSRG$+rGW4dUoFS1|k4NJIKc8&NUVx zUq26vQX)p-JSSBT?wnYu8GO9zR;tF6Bo!eaaBg2^u-4DbZ#;}>xhL_xzSLUZkq?of ze!qL)otca5BA%c*T0UsC902vCo_mJ!fx1k9Qx7UDnH4@!d@96`nhB6C_>L+g*oIo4 zhneAXW*nj8HqJJ*tW@b1u!?IWAm-npLi)0y1epZ_a@c97|p21+BJ^9s)+zNG( zn{1u;|uK_QZbGH&bSSJEPMo_Yw?CM0+>>Khf9|0iS+=^cFU$!}= z9wJ@MWFpj_qVm<2FF1fIemT`EGtG_o%r-LB_nJ2PM>n*|W)IKJ5800tdY=Slg+M!7 zA;E*-;8RE5GMx-ZZh!eKy(AB^+0n=d$D|b3Cx*Dgsbzh9mnM+-KIQMFzVzWzC`lbi zRI8Nzh>VMr#Hc<*)W&jt3{8_U?!qc);EREy%Ha=vrh_~@9RA?%zw=;j_(N|{0tc;q zZo=SQMvf1iOE*^d;P8zZnh+=Q_vgauOOE^>ws(ny5aP+zvw@EQj%zFAJSyU>14)a) z(DdQftUA}4t)jpc$zo#%)?6WlXu#`?e8T-voOfcRxzq%&sohNXOKSjr>AQob`R<V=Rx z(m04YhAX@$ z*;kG)q5Ebo`J_5f8PmU)o1X4vOOFv&`eSgo;dpN!&4W7~LABOH>I+i@Kpz6@+bHb) znK}^&Y!c;rp)Uw<)sv22qZ%|p254-y=?m%hVuG~>m9jr#bV0pdiV5O3A|i?`qW!>_36Y%&+z%fr#NzIkVh1N@^r|lXLjEC*YF>>L@PG!2ibH zl}~LfXE{%tlFcvsV*t3iEO9WKnN^E)HgnXTp=0uK}^Gh40JwF0Jv z7Bt4M(ENE3xV{`Ynm^Y*5>1SUE-P#~aWbMZ;G1I1pc6P7udiIl(cMV0C%xdbpcbiU zQ4t#lc6Sjij%<)j^;|5d5XSA5bKx@nJlPN>KE&E4IIGCM#6i1k7tWKw#=kyx8pKC7 z(ep_JGe8rW^g32IXlMOkVCD7WSM2CYUBC|!oMy)l1*#aDQn@qVeeo9{157m3RQN{# z%NqY2nyW%v5Hx+?8CD`FN)|o49~pIM1S?e_FzXH+Mz`GWN`qKi{*8T07OK{)_04^# zfDI1n247SS5)NTw(rDoM+qk)%Ehf%r>f*z*OL%TndSe<-|A37LVCKh*8?upE6S^w$ z*ig}8S9(_XPY)lXhoRw#7dCDjL^Dw5zAd#Dx?kImSL%=lR7c#0sA5C?Nk71Z=D+d{ zV>m3+qx^FUZ`GnEv+?Su=F+e|fwZ}-R>S46&@&bQ4p&12Bh&w@zZ z`^WPQ04(O)LvnExTF>WO^8{V)M`*oq^F+Kw689dgu8mpg*V$;$x9EN!D?+2InVAFe z-q#dfh7H8bkRNceuyONQtQ~RVQE%gBS_JU&TfmFv5FVTRq?q4oHU#S%e6&b;Am-J` zs;GdYg51*jE4gG4kU#*rnky{e?ISZ*vpccv?zL_MgW73K6aWV$hc=B;-G>qTdLNb6{am@a5CbPEeacT<<4)Hhcc>N`x zV12(h@%nxS7>@}bxe)97=M%5*^5fM<9>@CJ6R+=WIP)G8K5|gjckhYU_u%pBBY$Rn zUpn#nK6SkM$o*O0bthim%ZNmO%>Ht1VSQJgczs`CeZdqA&o}P|zD%tpqtm_-EM&-#- z8?V6+knW#XkTyIwW##1! z5SY)8sI!1-y%?dNb84@M$RROR->~-ZeHto?U0vB#T@dkj4-C%x49C~!s^asQZ+^tP zA9-@{`py#<;BYYU+V~7tyGIkFHlF%3i9(Z$82g!(pfBt`(nHs9V`wu4)77P`-V9ca zczbz?r7IJHx30<2g*MXJ`8u2G_Pt$7$_`4`uK$T1?2LLmt-Lw<{+`e?#Ed=1ki1&#w+>7tL z^HyN^mKzr*vXzCm+;MxvTbA=3^sR=#`vTIl1;E2qrtWF+1re_Y>r=L1>Fqa8TN`DE zsSZ{bs%DFHv&Cq3E%N2;Kk>d0WebMNRm96t>I-ooi1r-Zt_WFD{PdoD1S6Y1=p^?g zU^8&ZpAgQn{JD32oH);|n%B`c&fXujd!vrs$WO_A)PME?5tw_-3~InUf+>W-;q|^B zEWGi784rFPpJ&*u_&a6`0`uXjDwi*~F4%dJ->mgdl5IKrQ-}*olZc(-=NuEPq8F!o zirvPn#%S`kwf+y~Tkd+EH)1`>FYcUkDsktGcPhubb8u+B)SWZIshr@>ndnqbbmvTRDkr&fraF~V z-8s{p%IWYyU~JE?abwe6HNkm$9UtNooz)xpfC~V>wn;vfI$xOUJiS)FLRqXFA0;!v zg3*-+@8o&d-H>A{sO+heBoi(y>En}z8kf9-Ou8D+1MtzV#*6SXp})!4za{X-yuUtG zs_F;rVtYi9Z)@E|Z!v4j|(_ZhR8&9E(qN;@jQ$be#8d<1?Lj zw;Mm-!70x;ZX|2Z*zKs6w_>c?RMswVv@TfaRL!^6*X?V4kZX#yKHl4ElPkJ)yPXFI z_z>@Ns;-nV z%xd~DVm&Tal@$Y$2J)Y;JY?7;&6{r%KOSM{Woy%6^|Qh~*_r8}N| zl=b#S4<&K7ew|#&4PV=MU)hdBhsxvYtd2do#~!Sj2TMR71d7IINE(nf?m`aN zWOtj$JA)EL+ivP)b zvi8k*=0A@?F^OmAB}DUKa57B~_G^coOXqPQvoes(Zw5x>hM>!Jo3ISs>USBPLFd_J z^~A1#v?3D8qD?iOQ=4!*q8!5@DF5`eKzR_5pMCvrd=e^oQORRjX&wT|e1-98%Wqgl z8zvE|Fn=sCa0@nWe|eDVCdSa?buH`<_%UbX>5g z+4wrfvXlwuJqXflXge6+SONPTKH}!Pas<3cy$eVA_Q`hA`M<@qS+xE1%7M~BQPym4!s8%IFh>w-h+na;yN(cD(sW1l(r)K8Q5oi{OX$AXWzq-c^`57`zGi zqz3OLsB6kjr3mP3)Zr7*>39hU$ikZfkpdX#9+P(#o%>&i!6 zO-nca6So=aHez+bBFl@4D6r0U{RHkx` zhVBnxjBdQO;~@*Lub)6~i}eTr4~Y!!BeEi!CYc=$y{r|DC_es~j6Z0o$hu*$*NQ$^dAmWa?Gt!peJHequ zwf|-hOl3rNI7eVdX)@ObkaG1zI-!ZbGA`q*UQ~7z@-%`v%6cE&TfVB;YCc`2Z&7p* z;kGBy&SW_%{%iD;G@y570_L2OJl&F-vW*>>kxn3*vC#2a&Mr|A= z-(JRFgpoONvX$z@W8>l2iWc{wdr=<#R&Z9eT7HdWw)ZA}-G``;@Qn-(yUB7c+m&z! zn7BuGI6cw5`OPfu$ls>;?nhBVDq4nAw>g2oJg3r3+1HU*E6qDC$VDJb29-TT?ItVL z-~mr8%6~*li$``Lc(OaEn#~${-$+qP^vBX)PecG_kKU$uKk)|O%+z34-w^GpzCPkq zFBx8t>RBfK4sSG|nT|kFIwO2T`XFkXU`_ReS%5z|e{PD>i(~SXwUTwS{>Yq`HAVc7f_cB|~^>@2Ts+pB}^qNT3v4OhI zOwHfeLBh)XW}UzQV75dD%eO<7go_1)c}QjPZ3sNba`B@4_-=gzQ#QU`O2)B90&5~y zUNt{+(P$h_uv%!B%+&C)xe8yg&}F_LJ9`wwQ3FBB#$RL&9D68L?e?nnsP$0%m5$f* zTkCeYLXH%-B?w#HMr-p}n6Rw$HK?v})hn27pJT;_%lG*-x6h4FWU*eK3Zr}Zb(Lz>Dsf~fO&6c*4{FhhA?DdYIWd-Ea1VY>{NEevYk zA*!^M<|)7E_efz_*fHnn+S-k@$%s++Q=~?r$orlC1<4WU6co1nif`)L(fufa&TMnu zYpuQ>h{Uk?h>X7y>5A_f@7I$0wUpa*TvAr}B5G4VVs=5O97lltW+(MX{g?(~_fdSr8JrT|UA}eM$wt5HkCtz}>oAxBI>Z5hWyAXu1T13@ zSPx0&z1FMHU!fSkgXtB3*m=(oQv8)D`XBLr$D-78MuZ<|4S1ahKmOq5OUOByaAXxj z@FslXTtR7fdAxY}C$NObI_6~{HZ$OnQGw#Sg)^?q^JM#2k17JD2Def|P&2&r@9>&_ z9KK)oabSi1Fv2fpV{y|=f|r7*`)_fi0zQE@!chDL0r`5Z)N)`_n8J48hggL=!)Yfs zt_j?nd6@B2R`tTHq^1T0&s^rHrpAHL)QHL4HH^b_8SkUm21?^60{>k7MO~7vICkko z)-IGlDxrSq7tpSR#-%V554WlOxpN^47(R@QixgW2ci)}c0nEOkT_O=9c=hLzHyZEJ z#8bYi*IM0=!39#H&Z^yI@EOCK;E9B(7avrPHoyi)T15IEH0$JSGq!5rhVXj;%aG;P z`s4)au(hMf5_lxeT7O9tr%c9l*oX5FZO&?W9XQR#I~BL=A!2c4ICJ%)DfQ4AHn}ab z{@1M~o4gu$cWWj#*fm&AaUjg8S>o2NWpG=!g_cZ84G(iP-G_w-q4?!s*Qbra@vi1i zpfDH9BcR*N=MR?Gw}ZWtW|p6pxpK^aeu=&Uiy6`PgFrnXpBxfnsi7psN`!5Ko`_kWf)?6P+tk-Wh1}XrxtTW#A=Rx5XTr1Tkgy;sNWI##z}%a2nU@qob@6j1jD%l%V<>QWN1iI zD?yo<#u&x5Lq?zMOJ=!Sw^rmBe`IBPXN4+|2b&l#Mr(WB`rh*TO;+>QFjj7TdwG4Y zd-Z&`wigB}YyEz^D?fA5*u$8wR?DZjwAF8#Qs3*;zvxZFn-Nzp8b4-M4K$P~=*j=; zFr#vsX#FWkV>gFdmSP!d=Kxf3V#Ev(!wKii!*;$J%209UaGqJ_kSSw+*%!goKRnYY zj3uVK{)Cg0PPLu9nF%NqzeImnFuBoPC`*^J@G+8}H8ho0TqsnXd8f ze3;M2;>q^70)Y3E1!3hTR=lJ1Wmq1;F2w&cX>^xkeQ7SG;DTk~^9Q}J(y2o&S6n{a z`n9>ecvxgVpSZm51@f6eBPJ;pM{*qqQbVX#gs0WoZtA1`MdU&e&W&Rf*$W6y2%bw> zw}M}-i(GWpkcexPF6WPj^aL85-xm`}bNG76K8F_72p831h>=D0^7%o1-c#@p!8i?> zokI|KIWif{kI{1pH+ZVS!LcsXcOc}G z@=TS&x$S3=&f5f=|FTj&pX|?6k5QzCE1*u#C0 zz}PbgNO3UX$S9gBtki3GrHSWT%ES}hE`}KwMQGFcBfi?3X_tvEpJw`NZ5}P7)O;(_ zO{WivIu=ciwnd4E($br`C#sZBj16n6MSg32&&Woi_mq*yR`nQL(ZHjCKtP&}!b;~; zh9XN&Tp$4BH$ZVjQ_D`yA#MLDHB3v{e<<;T&f#SK>rQBX(6?bOkexd%HxJ}mcluNZ z4N-{R?MiGO!p3JL4%B=Gw2d-uDAof-%(UgLdYi9Z{;o z`Std$$v@6miH7QX*aIly89B`NF_a~q3340qZYHdH-L0Ca zt0LwE)j;y_wSYvT;E=iaGxk~ZzrfxJOj6IzMX0PY-jCU!@E`XXSq5?9<%dY~$?ks! zSI0q=_yLlt8}-EBg?`}OOytRCA`gx47uauPK7*V_flYBHSIPba?<-XkPxdD~u27UC zDD#5J;*cH8Ys%2?KFGd{b@s)~MS0O#@ak!qfh4X7FW|T74IaPYoWqMi$6vL?8ivT} zm07{lK}vnf6$$FLo6;~%Fup0=5x?ll&<4~@v4!Sjt@;7-LNB4DD5eRY zn0Dwn0%a&)x;AUUd`I=MvJ~hZ7anR7;+=bK(D?c(9i6ck5#)lDxSj`hO74axC2%iK#B?g%?7eKjI zV;vT3j*ZX#A$$%P_<>09gONC0*#7Z%mWKeJKJB!00%p6@x7R7Y5*K3zF{IipijLH> zcQMKmz{vf|>U{?a5J^MV|8SnmbMyFXzUvAv!xqr(T#}SR>ht#hZOjel(YXt2fH}Ez zC5Zp3_pg$2Wght1?=Tg0Q1?s{cEcVb5pnrdPl}vD&iu(eGB4sq(H_HzaP8?w=^oIN zA0KEs@+8O!mj|IPyFJ!)B!X9n@yQK5N>g8yUyqmz^KD!!fjz4A3!={U_CeeZV6D%$ zUmM;2=YsaWf>wlg*qq;5yS26Ujjs5ck&fQHFqkd5^fgo9sQE~MGZ(#eXdjfvJ zGO;ZgYpi_(TYmBjdsSfuH^W~kn|MViOwv#rb*JGE0A;eI#>wkQJ^Z@ZIiYpfC#jSb+64>wE_>I=1mon6|R>7J)5ftp! zZW~woqLuEJa^17w$y(oMJqY^~#%#Z}nvOtj?e0unU#2RCwtTb(F{D-^RAir^ryK*l z`VEwDw)Q{Y&_+LQY-(&H%B=K5_={$p_m=0o_1%;AB3hu@nk+l0ZTost)T5N3Wj5{wuMNsKJ#fS;Mf1|Snq7WvA@DVgXjYMWpK%yLIx$wi< zT$SI^JE}GQrn9B-o>*k%C+x%dR@wrqg6D1wGX-Jv3gd5j{|C)!9D3Yew4X0-t$VZo z4@6K%zjj`}N^A~O-9|DY%B#cLdY`E;WuX?gqS*HOF=p@G@H)j2q*%F z5^|-{;b0R{VK-@Vc>XgU1Deb0zF@gE{n2=2-V?&3T%Bd^OXS@t&==`qg>X~2vjw#T zJEpX6JS_vH?&C-wZOF!P;se`Z+-{DQZ@=qi2Y&a>OOUDTsI{T~031BO6zq2Ygw+ZE zP&DZ4#NZzTQMJ{HsY8CzV6Qq5NfsQeo|l&#Q?>(Y@K0s6HC6=s&$$1s{s2A7q`Ap2 z!>GE(AU#)i7h|N+^%V(dXAc6(e}Q%nc`p5V@*uT}0vlLpD2X-SiM$~s`{1TNhwN<) z(f9#_n+PD4Tm3MPGqKTPE8ztIoE{Q~U7h!b|56E^_C>-4^b>|tLGDTlA_TG7oh7h( z1^c;bykKpCgB@xa(})Y=Q@=*1lx<=oy9mbrG3@!nn5Ft+nEVj$9rPA8+-rPU{CHf} z=0f|mGws7gD^8Z`Ug-VTyfYB&bZoZyI~s$k4Cw%SaG--=&~MNqOk@%0bk*V$=%QPB$%|LzQ; zdTv;>Lmwvw;=P$UdF5CHdI&pWgyFCAn`il=nLhAftuLmFf3MwL3S$Hx&$L(dL}{i< zakVP{jg{)fuik6MlXMbobJ`6x_XOBr-?`Ulme61dd~DTjXApyA3>E&Dp@UTSqUdQL zsAxTw`|5>aC~K`=toQYYxoDA>KnmdCu;W(q$y{T;@Hd3t#7T%3;j3e$J#Cv55@hRKCY1`kHq*53hR+<(Y!4!a!(G zze=vN=9#gBRSbmi6!N-qvIUa}HeoraK+xWLCT=G1uV6qIwti5^X!Yx;+{75EO!h=l;s!Dw7? zE=bR*y78XTkg_URy?7B*wH%AL#(N5ozMTz;e>&Hi8K9X^h4~{^==at?Op>||<%lzc z$s0c$g8U~5q4ybN5`KW8Dzs9(Rz=aL@@R%XzV3=EC+s#;#T{N5Gr{3PC;~qKo^p*@ z6uhG#Fx5}O18zN~s&sfI`A-%TB06+~-}?0E@SB$*F!jRenG++Y`FuGv zNa^}K-j?R zx*Z#x=4C>$R)FshMh}29ehI)p-%C^?T^Q zdo?cObuXXfz^}h{w|gB_K$!k_m%UQ9AJXWW_{;7FnL`H?6WkV=TkXkHtqnEfowuj7 z(0Kj=b)ob|jAD@9_~dE8T346j$-r%eU0GGVz-6F z$&Ww7MjJJmo*U5`UfT&L7}C+2Q3wI|hpFok#O!Yc$#| zoBr$36Aakz8^1a>;z$W=O-&w*(lyv5-tN{ck#%tPL=cGz@*C`mKS;3S#Z#aMo3+y4 zh22rMBl>-=0nzWb;_v$&{yP4q4|dh$MY_OnQs3av+BHQOy_)e^LB7laL3`t>m%w|z zfIibEKY(VS5jI|kG=|ISioYCjzai8FS)v?s1{4DNLuhZTv+$2{E?=T*M3eNgh_==& z#)RNd`+R|unhl2a0;lCxWI2(X?!z}Tr@zIVZ6T`p4=%ex=vG>sYP5@@j~4OaAic8_ z-YS`2W@fb8Ua1uVnD+?EMwie$NtG}uBw_;wE7c-l3Atz?)OWeC#gg@fGk-ilfNt2|Tp>)aGwDrMj zAQPAMoHTj~%Bxu$g+gVe=gK=LDrYTI79a(DE8^ARLG6dskUL$CgT6QdMD8@X=R*ga zc>6}8*MZ^U8{`5n^x8)t0rNfvIL=x2TX^thqWf(!^+!kAaBU4S#A~H zBEa6z#<4f84aqPK8QL0G{XUWy-8CA1j!`HZ#*wy7O)@rW8b3xY&Fr9v*q91^3c@f2 z%jqs~6z_-37``7t?448LH9(`n6EYhM4^~p4$ydDY>88fUMk?R+#fM(k3RU%dgkbCV z^XN>;DU-V)$F+Qzd3n9Jl}hrlwosd>#QfN^QR=8IJhZgfdD;Ek{EolC%W@WlesSV* z$Tg`Y(Th>?W|kd2^twEumB}x`j)~3LuFC5phY-BEaB{LZ8{a21^RnBQX#n z`^SMHN5`B?A9cDC$wNJMZ+`h8woC`hc5sgOl662HiJf{BG=(b%{=0lIahY>?a)e*Nm1f-)lgi_wK>;PtGe%(NMyf0CbiJeONLS0=E z`TX*VcXX%sA6mK_oxnY|y@ivvV^?SLmewmzKB`3)#U5ZOk)TRO2mPkv4ls%CkG8UZ zraLt8%5?_p?WggjFA$L?q2BtF?07d%t;<{c_xZDbRb2u1+6+#YmisDasA7VwMq z#K(qbT8o-NSb^dcR472EuK}(B%fSkg}ems#Bnc~7_BYMuUt|dFSSaTC2b0^Uh>YdDf2Q77HU%tx-rdDT$*c%6P9`VdZ^uG32w=cZ56 z>0fyuH+_Omzkf(QCjTQt(oOw89+Eyy*Yk~;x%HcR-W$@dkLmos7*fyKI{imKMCb;Xcf2w> zy=MqK+EN+YlM7FJ4+(Bp=2uHN)s+BJ%vlPO71F` z$?IvzDLOyDA|_2ZqL1*k@b|p_y}9`d`+pbyURl(?nF|R}FuepQmXL4|>Tp6uogX?arcnRhhjR5-QG zdz(lOBWJqz>d>T_-fxB`o$t}6qe1!dgCKBXp(1GOpN5v0EqL~tkPgfhf+mEB{+LS? zX^BoB6Nyv!pp%6u&5UIFV75jCTW55l7>0LT38F!Fc-LDYnVMU9y~*yC3&n3V_7kE3a!l5cB|*`fdd!XZ@X#%4haw3i$GK0cvSA&lN3C^iM*M63d&ctSkP?{{dC{J1 zWX_E@BAQ%9?9N12MM0!Ii43QmE*YYOhzt7}iIxjC?!u^&m}w?)CRR`$N7kD@s#?b! zgV%&PnSxe*gh#tF*XEViBky~-VGWQ5$`^u9z?&A& zRutZT;~h(~6-Bq)ev<}dd(8#* zd&dBF9)MkZ`%OszyZEN13fN@|@nO6YSR7p+4(z`l6Ig%E3xHjWt)1bRt-#ihm7-{v zx#uLo?E6$cgV|)_W?=S?Ww+c-U=z380XitUUBPSgB7u*)2i;^ zlu9gK#wtK}e`rJsEgcEa9z}E`09tB>A^`NR5dob)fm1&W=*NZv zdOHEVF@e~J2*7l^59qj&0i7@spjRIg&&WV%ke|(T|oZzIYm(1Z+AahrNfZ1Q7 zxW5Lra6IshtBJvR+ z(yf2g-Wrod>~@tkb5~w|{LyTrdf6SfbydU^Mc!cWoU?8&oI27#Z!VS2jzE!9%>aNR zt9=mfABHyJe$xq}DE0*L6ajIT%4$HIzwC~cK;>7a&B0<+n7H|lWn4h-M(oatV#e+i z+}|-W=+j36UDN#tpidtW^c!{E3^O0X?o5LIxWVp80(!B^It=tHmICxICvRB>qA1d< zX{p9YPcF7+js)@~wMvfw^2`xIUi*GUibFug#X45%6@t97m>y%lH_(q0=ucCVR|w+@ zEdHEmpP2xzP~WrtxngMp#w50E=`uw?KUSZmCM`2^*_b`jXslMFJi=)Bx31*S z{-1T-IisS+uQrSy9?BUEb~->d$MBAG8PMNTzsn<3&9KUUs-X2L+}^j z-Nzk*=++P?c~kTH5JHKDxs2QJ?OcSGD8bzzbivZQ?gEhhjJ!>K4kHxO@fxP!r&O07L*Qh~L2)%PD2Y-ncZ-~%&Cy3C`{(}hJ9Gc}J=HYAR zj4k^uE7eti9wi^OyOh|tR+SQ9uUxj63-euflJONL0CP6}1coAF>{0P2Ff~OY3>1EM z;s0gsUBIggpj1!{Gqc@z-PUd7TlZ2An! zNo>~DQ`sHJ3w0vY%XRQctVWibuj}n!esr~HJs~UO(Z5NwYu#NB>g8^;YYX8xo{<_? zD3rq*?APE6)s4=(28&0*+-Wl|V602~I-Gc{3AVLHwDnEh)|y~j?xqFx*cNZCjZMuf z5{u8VeN;o%LG|{{Yj%t}Pu_ z+b?!yYF@6O;@47Wpql$ZHP@Cxf%}`(n-pKudN)ujYoY=SY#x;A)xz6DpuL%io8eb) z`jiSrOW#MS>VA};Nb@|<4CyPlO-SE=eA4G%QIzz3l$w;^7YClFgD5|Z(xdEawLq>> zw@M))fx9{*&|9PEUbpL3fDz}OjVO|}{rye&y6<1%R6{S~8V@1V&dpD{=3nkMFygCV z1TT+k2}nr-#nhQLdzKKD*cFff=!2M)01)!kYzUDqj}n2HweUtn71+7PbqSlA}9hu(cJ`WLk5MnYhQU#s z*dphO99D1tP(K}__LWS_X}esrGe(j#t;BM@#dcjkD=)Eqp^iKNcR5%^<@`PbL9+`U zaPbI+UY404|N zH&AxdE{r$lQlj+1nc9Wn<=mYC7aCW}$xzX#)k13;rRg++Sn6zYpUx!u@z}c6|8@&E4QSZNzsOTK zU6ti{%=OxpyO$n^VOnNvVR)URe!6o4*J|YZRhykqyWA;p-!afx2dQ@V9i76}JD0ti z1>8x_yjQqC(e0YXO;A|id;q}i;f6aCAvG>sr}T|-8Zet&xK7(Gbk2G;8@M9pp{(Hg zISr7S?%OSOav`nV!<9LU{cxT3caZZtteP&qPT>YPCu7y@9FF^x)53bl#6RpX(>Y;B zzH=_B>+ufJLHys!a^63erG7mShBLN%C=6%nmoo>Fm@%J?aPchRev#$6I3`PcbF+l2 z-;-TGzT@G8ccXEu&>}dD^trYH=p^B{HtE&zqc5E@W{4M~6e_ zzUtg<&MQ>eG0#t6Z2u==y>5iNAWOJEVdixy$km?X$Gbn+xWAqk&HX7c@g?E$8v%R7 z+J$sGyrn90^}uff?OZtt4!YzE*wi5PU0u=UV{s-R?rI}k-X&LBt$XnX*S7oFj}T__ z$@=xd`y$CEdg4U+1~^)CHrL=~I=KsQ{N<~4F>As7iLyxYlssK)<2ATEy#c=A9P5Aa zritGd;bw;_NmN$nCMrk4t5#%RGRbOX`_@Z@dx0403e(9wC~5%ih8ue4#(K-=8}Mvz zBH6r@^)f-@g?5q!_Dwu3;eAedml7vK7xD9(Q*6;q`k}NxiKj;VdeVM`6;pTbXZ1}a z0iLH~UTCKWDv7pmswHFBsLRZ_DerN~ov<#;A1gMpkkN=DolP5=21P%SFlco0%) z*N$c9-bRtg4U7H=JV<*WMk#S9FS6wOWF7dnh